358 lines
10 KiB
JavaScript
358 lines
10 KiB
JavaScript
import {
|
|
__publicField
|
|
} from "./chunk-V6TY7KAL.js";
|
|
|
|
// ../../node_modules/.pnpm/@kevisual+query@0.0.12_ws@8.18.1/node_modules/@kevisual/query/dist/query-browser.js
|
|
var adapter = async (opts, overloadOpts) => {
|
|
const controller = new AbortController();
|
|
const signal = controller.signal;
|
|
const timeout = opts.timeout || 6e4 * 3;
|
|
const timer = setTimeout(() => {
|
|
controller.abort();
|
|
}, timeout);
|
|
return fetch(opts.url, {
|
|
method: "POST",
|
|
headers: {
|
|
"Content-Type": "application/json",
|
|
...opts.headers
|
|
},
|
|
body: JSON.stringify(opts.body),
|
|
signal,
|
|
...overloadOpts
|
|
}).then((response) => {
|
|
const contentType = response.headers.get("Content-Type");
|
|
if (contentType && contentType.includes("application/json")) {
|
|
return response.json();
|
|
} else {
|
|
return response.text();
|
|
}
|
|
}).catch((err) => {
|
|
if (err.name === "AbortError") {
|
|
console.log("Request timed out and was aborted");
|
|
}
|
|
console.error(err);
|
|
return {
|
|
code: 500
|
|
};
|
|
}).finally(() => {
|
|
clearTimeout(timer);
|
|
});
|
|
};
|
|
var createStoreImpl = (createState) => {
|
|
let state;
|
|
const listeners = /* @__PURE__ */ new Set();
|
|
const setState = (partial, replace) => {
|
|
const nextState = typeof partial === "function" ? partial(state) : partial;
|
|
if (!Object.is(nextState, state)) {
|
|
const previousState = state;
|
|
state = (replace != null ? replace : typeof nextState !== "object" || nextState === null) ? nextState : Object.assign({}, state, nextState);
|
|
listeners.forEach((listener) => listener(state, previousState));
|
|
}
|
|
};
|
|
const getState = () => state;
|
|
const getInitialState = () => initialState;
|
|
const subscribe = (listener) => {
|
|
listeners.add(listener);
|
|
return () => listeners.delete(listener);
|
|
};
|
|
const api = { setState, getState, getInitialState, subscribe };
|
|
const initialState = state = createState(setState, getState, api);
|
|
return api;
|
|
};
|
|
var createStore = (createState) => createState ? createStoreImpl(createState) : createStoreImpl;
|
|
var parseWsUrl = (url) => {
|
|
try {
|
|
new URL(url);
|
|
return url;
|
|
} catch (e) {
|
|
const _url = new URL(url, location.origin);
|
|
if (_url.protocol === "http:") {
|
|
_url.protocol = "ws:";
|
|
}
|
|
if (_url.protocol === "https:") {
|
|
_url.protocol = "wss:";
|
|
}
|
|
return _url.href;
|
|
}
|
|
};
|
|
var QueryWs = class {
|
|
constructor(opts) {
|
|
__publicField(this, "url");
|
|
__publicField(this, "store");
|
|
__publicField(this, "ws");
|
|
const url = (opts == null ? void 0 : opts.url) || "/api/router";
|
|
if (opts == null ? void 0 : opts.store) {
|
|
this.store = opts.store;
|
|
} else {
|
|
const store = createStore((set) => ({
|
|
connected: false,
|
|
status: "connecting",
|
|
setConnected: (connected) => set({ connected }),
|
|
setStatus: (status) => set({ status })
|
|
}));
|
|
this.store = store;
|
|
}
|
|
const wsUrl = parseWsUrl(url);
|
|
if ((opts == null ? void 0 : opts.ws) && opts.ws instanceof WebSocket) {
|
|
this.ws = opts.ws;
|
|
} else {
|
|
this.ws = new WebSocket(wsUrl);
|
|
}
|
|
this.connect();
|
|
}
|
|
/**
|
|
* 连接 WebSocket
|
|
*/
|
|
async connect(opts) {
|
|
const store = this.store;
|
|
const connected = store.getState().connected;
|
|
if (connected) {
|
|
return Promise.resolve(true);
|
|
}
|
|
return new Promise((resolve, reject) => {
|
|
const ws = this.ws || new WebSocket(this.url);
|
|
const timeout = (opts == null ? void 0 : opts.timeout) || 5 * 60 * 1e3;
|
|
let timer = setTimeout(() => {
|
|
console.error("WebSocket 连接超时");
|
|
reject("timeout");
|
|
}, timeout);
|
|
ws.onopen = () => {
|
|
store.getState().setConnected(true);
|
|
store.getState().setStatus("connected");
|
|
resolve(true);
|
|
clearTimeout(timer);
|
|
};
|
|
ws.onclose = () => {
|
|
store.getState().setConnected(false);
|
|
store.getState().setStatus("disconnected");
|
|
this.ws = null;
|
|
};
|
|
});
|
|
}
|
|
listenConnect(callback) {
|
|
const store = this.store;
|
|
const { connected } = store.getState();
|
|
if (connected) {
|
|
callback();
|
|
return;
|
|
}
|
|
const subscriptionOne = (selector, listener) => {
|
|
const unsubscribe = store.subscribe((newState, oldState) => {
|
|
if (selector(newState) !== selector(oldState)) {
|
|
listener(newState, oldState);
|
|
unsubscribe();
|
|
}
|
|
});
|
|
return unsubscribe;
|
|
};
|
|
const cancel = subscriptionOne((state) => state.connected, () => {
|
|
callback();
|
|
});
|
|
return cancel;
|
|
}
|
|
onMessage(fn, opts) {
|
|
const ws = this.ws;
|
|
const isJson = (opts == null ? void 0 : opts.isJson) ?? true;
|
|
const selector = opts == null ? void 0 : opts.selector;
|
|
const parseIfJson = (data) => {
|
|
try {
|
|
return JSON.parse(data);
|
|
} catch (e) {
|
|
return data;
|
|
}
|
|
};
|
|
const listener = (event) => {
|
|
const received = parseIfJson(event.data);
|
|
if (typeof received === "string" && !isJson) {
|
|
fn(received, event);
|
|
} else if (typeof received === "object" && isJson) {
|
|
fn(selector ? selector(received) : received, event);
|
|
} else ;
|
|
};
|
|
ws.addEventListener("message", listener);
|
|
return () => {
|
|
ws.removeEventListener("message", listener);
|
|
};
|
|
}
|
|
close() {
|
|
var _a;
|
|
const ws = this.ws;
|
|
const store = this.store;
|
|
(_a = ws == null ? void 0 : ws.close) == null ? void 0 : _a.call(ws);
|
|
this.ws = null;
|
|
store.getState().setConnected(false);
|
|
store.getState().setStatus("disconnected");
|
|
}
|
|
send(data, opts) {
|
|
const ws = this.ws;
|
|
const isJson = (opts == null ? void 0 : opts.isJson) ?? true;
|
|
const wrapper = opts == null ? void 0 : opts.wrapper;
|
|
if (!ws || ws.readyState !== WebSocket.OPEN) {
|
|
console.error("WebSocket is not open");
|
|
return;
|
|
}
|
|
if (isJson) {
|
|
ws.send(JSON.stringify(wrapper ? wrapper(data) : data));
|
|
} else {
|
|
ws.send(data);
|
|
}
|
|
}
|
|
getOpen() {
|
|
if (!this.ws) {
|
|
return false;
|
|
}
|
|
return this.ws.readyState === WebSocket.OPEN;
|
|
}
|
|
};
|
|
var setBaseResponse = (res) => {
|
|
res.success = res.code === 200;
|
|
res.showError = (fn) => {
|
|
if (!res.success && !res.noMsg) {
|
|
fn == null ? void 0 : fn();
|
|
}
|
|
};
|
|
};
|
|
var Query = class {
|
|
constructor(opts) {
|
|
__publicField(this, "adapter");
|
|
__publicField(this, "url");
|
|
__publicField(this, "beforeRequest");
|
|
__publicField(this, "afterResponse");
|
|
__publicField(this, "headers");
|
|
__publicField(this, "timeout");
|
|
this.adapter = (opts == null ? void 0 : opts.adapter) || adapter;
|
|
this.url = (opts == null ? void 0 : opts.url) || "/api/router";
|
|
this.headers = (opts == null ? void 0 : opts.headers) || {
|
|
"Content-Type": "application/json"
|
|
};
|
|
this.timeout = (opts == null ? void 0 : opts.timeout) || 6e4 * 3;
|
|
}
|
|
/**
|
|
* 发送 get 请求,转到 post 请求
|
|
* T是请求类型自定义
|
|
* S是返回类型自定义
|
|
* @param params 请求参数
|
|
* @param options 请求配置
|
|
* @returns 请求结果
|
|
*/
|
|
async get(params, options) {
|
|
return this.post(params, options);
|
|
}
|
|
/**
|
|
* 发送 post 请求
|
|
* T是请求类型自定义
|
|
* S是返回类型自定义
|
|
* @param body 请求体
|
|
* @param options 请求配置
|
|
* @returns 请求结果
|
|
*/
|
|
async post(body, options) {
|
|
const url = (options == null ? void 0 : options.url) || this.url;
|
|
const headers = { ...this.headers, ...options == null ? void 0 : options.headers };
|
|
const adapter2 = (options == null ? void 0 : options.adapter) || this.adapter;
|
|
const beforeRequest = (options == null ? void 0 : options.beforeRequest) || this.beforeRequest;
|
|
const afterResponse = (options == null ? void 0 : options.afterResponse) || this.afterResponse;
|
|
const timeout = (options == null ? void 0 : options.timeout) || this.timeout;
|
|
const req = {
|
|
url,
|
|
headers,
|
|
body,
|
|
timeout
|
|
};
|
|
try {
|
|
if (beforeRequest) {
|
|
await beforeRequest(req);
|
|
}
|
|
} catch (e) {
|
|
console.error("request beforeFn error", e, req);
|
|
return {
|
|
code: 500,
|
|
success: false,
|
|
message: "api request beforeFn error",
|
|
showError: () => {
|
|
}
|
|
};
|
|
}
|
|
return adapter2(req).then(async (res) => {
|
|
try {
|
|
setBaseResponse(res);
|
|
if (afterResponse) {
|
|
return await afterResponse(res, {
|
|
req,
|
|
res,
|
|
fetch: adapter2
|
|
});
|
|
}
|
|
return res;
|
|
} catch (e) {
|
|
console.error("request error", e, req);
|
|
return {
|
|
code: 500,
|
|
success: false,
|
|
message: "api request afterFn error",
|
|
showError: () => {
|
|
}
|
|
};
|
|
}
|
|
});
|
|
}
|
|
/**
|
|
* 请求前处理,设置请求前处理函数
|
|
* @param fn 处理函数
|
|
*/
|
|
before(fn) {
|
|
this.beforeRequest = fn;
|
|
}
|
|
/**
|
|
* 请求后处理,设置请求后处理函数
|
|
* @param fn 处理函数
|
|
*/
|
|
after(fn) {
|
|
this.afterResponse = fn;
|
|
}
|
|
};
|
|
var QueryClient = class extends Query {
|
|
constructor(opts) {
|
|
super(opts);
|
|
__publicField(this, "tokenName");
|
|
__publicField(this, "storage");
|
|
__publicField(this, "token");
|
|
// 默认不使用ws
|
|
__publicField(this, "qws");
|
|
this.tokenName = (opts == null ? void 0 : opts.tokenName) || "token";
|
|
this.storage = (opts == null ? void 0 : opts.storage) || localStorage;
|
|
this.beforeRequest = async (opts2) => {
|
|
const token = this.token || this.getToken();
|
|
if (token) {
|
|
opts2.headers = {
|
|
...opts2.headers,
|
|
Authorization: `Bearer ${token}`
|
|
};
|
|
}
|
|
return opts2;
|
|
};
|
|
if (opts == null ? void 0 : opts.io) {
|
|
this.createWs();
|
|
}
|
|
}
|
|
createWs(opts) {
|
|
this.qws = new QueryWs({ url: this.url, ...opts });
|
|
}
|
|
getToken() {
|
|
return this.storage.getItem(this.tokenName);
|
|
}
|
|
saveToken(token) {
|
|
this.storage.setItem(this.tokenName, token);
|
|
}
|
|
removeToken() {
|
|
this.storage.removeItem(this.tokenName);
|
|
}
|
|
};
|
|
export {
|
|
Query,
|
|
QueryClient,
|
|
QueryWs,
|
|
adapter
|
|
};
|
|
//# sourceMappingURL=@kevisual_query.js.map
|