2025-03-21 21:34:26 +08:00

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