@kevisual/query 0.0.19 → 0.0.21

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,11 +1,12 @@
1
1
  declare const methods: readonly ["GET", "POST"];
2
2
  type Method = (typeof methods)[number];
3
3
  type AdapterOpts = {
4
- url: string;
4
+ url?: string;
5
5
  headers?: Record<string, string>;
6
6
  body?: Record<string, any>;
7
7
  timeout?: number;
8
8
  method?: Method;
9
+ isBlob?: boolean;
9
10
  };
10
11
  /**
11
12
  *
@@ -8,6 +8,7 @@ const methods = ['GET', 'POST'];
8
8
  const adapter = async (opts, overloadOpts) => {
9
9
  const controller = new AbortController();
10
10
  const signal = controller.signal;
11
+ const isBlob = opts.isBlob || false; // 是否返回 Blob 对象
11
12
  const timeout = opts.timeout || 60000 * 3; // 默认超时时间为 60s * 3
12
13
  const timer = setTimeout(() => {
13
14
  controller.abort();
@@ -39,8 +40,12 @@ const adapter = async (opts, overloadOpts) => {
39
40
  .then((response) => {
40
41
  // 获取 Content-Type 头部信息
41
42
  const contentType = response.headers.get('Content-Type');
43
+ if (isBlob) {
44
+ return response.blob(); // 直接返回 Blob 对象
45
+ }
46
+ const isJson = contentType && contentType.includes('application/json');
42
47
  // 判断返回的数据类型
43
- if (contentType && contentType.includes('application/json')) {
48
+ if (isJson) {
44
49
  return response.json(); // 解析为 JSON
45
50
  }
46
51
  else {
@@ -3,11 +3,12 @@ import { StoreApi } from 'zustand/vanilla';
3
3
  declare const methods: readonly ["GET", "POST"];
4
4
  type Method = (typeof methods)[number];
5
5
  type AdapterOpts = {
6
- url: string;
6
+ url?: string;
7
7
  headers?: Record<string, string>;
8
8
  body?: Record<string, any>;
9
9
  timeout?: number;
10
10
  method?: Method;
11
+ isBlob?: boolean;
11
12
  };
12
13
  /**
13
14
  *
@@ -92,10 +93,12 @@ type Fn = (opts: {
92
93
  }) => Promise<Record<string, any> | false>;
93
94
  type QueryOpts$1 = {
94
95
  url?: string;
95
- adapter?: typeof adapter;
96
96
  headers?: Record<string, string>;
97
+ body?: Record<string, any>;
97
98
  timeout?: number;
98
99
  method?: Method;
100
+ isBlob?: boolean;
101
+ adapter?: typeof adapter;
99
102
  [key: string]: any;
100
103
  };
101
104
  type Data = {
@@ -159,7 +162,9 @@ declare class Query {
159
162
  * 需要突然停止请求,比如401的时候
160
163
  */
161
164
  stop?: boolean;
165
+ qws: QueryWs;
162
166
  constructor(opts?: QueryOpts$1);
167
+ setQueryWs(qws: QueryWs): void;
163
168
  /**
164
169
  * 突然停止请求
165
170
  */
@@ -192,6 +197,7 @@ declare class Query {
192
197
  * @param fn 处理函数
193
198
  */
194
199
  after(fn: DataOpts['afterResponse']): void;
200
+ fetchText(url: string, options?: RequestInit): Promise<Result<any>>;
195
201
  }
196
202
 
197
203
  declare class BaseQuery<T extends Query = Query, R extends {
@@ -204,14 +210,17 @@ declare class BaseQuery<T extends Query = Query, R extends {
204
210
  query: T;
205
211
  queryDefine: R;
206
212
  constructor(opts?: {
207
- query: T;
213
+ query?: T;
208
214
  queryDefine?: R;
209
215
  clientQuery?: T;
210
216
  });
211
- get chain(): any;
217
+ get chain(): R['queryChain'];
212
218
  post<R = any, P = any>(data: P, options?: DataOpts): Promise<Result<R>>;
213
219
  get<R = any, P = any>(data: P, options?: DataOpts): Promise<Result<R>>;
214
220
  }
221
+ declare class ClientQuery extends Query {
222
+ constructor(opts?: QueryOpts$1);
223
+ }
215
224
 
216
225
  type QueryOpts = {
217
226
  url?: string;
@@ -220,13 +229,12 @@ type QueryOpts = {
220
229
  timeout?: number;
221
230
  };
222
231
  /**
223
- * 前端调用后端QueryRouter
232
+ * 前端调用后端QueryRouter, 封装 beforeRequest 和 wss
224
233
  */
225
234
  declare class QueryClient extends Query {
226
235
  tokenName: string;
227
236
  storage: Storage;
228
237
  token: string;
229
- qws: QueryWs;
230
238
  constructor(opts?: QueryOpts & {
231
239
  tokenName?: string;
232
240
  storage?: Storage;
@@ -238,5 +246,5 @@ declare class QueryClient extends Query {
238
246
  removeToken(): void;
239
247
  }
240
248
 
241
- export { BaseQuery, Query, QueryClient, QueryWs, adapter, wrapperError };
249
+ export { BaseQuery, ClientQuery, Query, QueryClient, QueryWs, adapter, wrapperError };
242
250
  export type { Data, DataOpts, QueryOpts, QueryWsOpts, Result };
@@ -7,6 +7,7 @@
7
7
  const adapter = async (opts, overloadOpts) => {
8
8
  const controller = new AbortController();
9
9
  const signal = controller.signal;
10
+ const isBlob = opts.isBlob || false; // 是否返回 Blob 对象
10
11
  const timeout = opts.timeout || 60000 * 3; // 默认超时时间为 60s * 3
11
12
  const timer = setTimeout(() => {
12
13
  controller.abort();
@@ -38,8 +39,12 @@ const adapter = async (opts, overloadOpts) => {
38
39
  .then((response) => {
39
40
  // 获取 Content-Type 头部信息
40
41
  const contentType = response.headers.get('Content-Type');
42
+ if (isBlob) {
43
+ return response.blob(); // 直接返回 Blob 对象
44
+ }
45
+ const isJson = contentType && contentType.includes('application/json');
41
46
  // 判断返回的数据类型
42
- if (contentType && contentType.includes('application/json')) {
47
+ if (isJson) {
43
48
  return response.json(); // 解析为 JSON
44
49
  }
45
50
  else {
@@ -293,6 +298,7 @@ const setBaseResponse = (res) => {
293
298
  fn?.();
294
299
  }
295
300
  };
301
+ return res;
296
302
  };
297
303
  const wrapperError = ({ code, message }) => {
298
304
  const result = {
@@ -326,6 +332,8 @@ class Query {
326
332
  * 需要突然停止请求,比如401的时候
327
333
  */
328
334
  stop;
335
+ // 默认不使用ws
336
+ qws;
329
337
  constructor(opts) {
330
338
  this.adapter = opts?.adapter || adapter;
331
339
  this.url = opts?.url || '/api/router';
@@ -334,6 +342,9 @@ class Query {
334
342
  };
335
343
  this.timeout = opts?.timeout || 60000 * 3; // 默认超时时间为 60s * 3
336
344
  }
345
+ setQueryWs(qws) {
346
+ this.qws = qws;
347
+ }
337
348
  /**
338
349
  * 突然停止请求
339
350
  */
@@ -443,6 +454,62 @@ class Query {
443
454
  after(fn) {
444
455
  this.afterResponse = fn;
445
456
  }
457
+ async fetchText(url, options) {
458
+ const res = await fetch(url, {
459
+ method: 'GET',
460
+ ...options,
461
+ headers: {
462
+ ...this.headers,
463
+ ...(options?.headers || {}),
464
+ },
465
+ });
466
+ if (!res.ok) {
467
+ return wrapperError({
468
+ code: res.status,
469
+ message: `fetch error: ${res.statusText}`,
470
+ });
471
+ }
472
+ const contentType = res.headers.get('Content-Type');
473
+ if (contentType && contentType.includes('application/json')) {
474
+ const data = await res.json();
475
+ const result = { code: res.status, data, success: res.ok };
476
+ return setBaseResponse(result);
477
+ }
478
+ if (contentType && contentType.includes('text/html')) {
479
+ const text = await res.text();
480
+ const result = {
481
+ code: res.status,
482
+ data: text,
483
+ success: res.ok,
484
+ };
485
+ return setBaseResponse(result);
486
+ }
487
+ if (contentType && contentType.includes('text/plain')) {
488
+ let text = await res.text();
489
+ // 处理特殊情况,比如返回的是纯文本
490
+ if (text.startsWith('{')) {
491
+ try {
492
+ text = JSON.parse(text);
493
+ }
494
+ catch (e) {
495
+ // 如果解析失败,保持原样
496
+ }
497
+ }
498
+ const result = {
499
+ code: res.status,
500
+ data: text,
501
+ success: res.ok,
502
+ };
503
+ return setBaseResponse(result);
504
+ }
505
+ const blob = await res.blob();
506
+ const result = {
507
+ code: res.status,
508
+ data: blob,
509
+ success: res.ok,
510
+ };
511
+ return setBaseResponse(result);
512
+ }
446
513
  }
447
514
  class BaseQuery {
448
515
  query;
@@ -469,16 +536,19 @@ class BaseQuery {
469
536
  return this.query.get(data, options);
470
537
  }
471
538
  }
539
+ class ClientQuery extends Query {
540
+ constructor(opts) {
541
+ super({ ...opts, url: opts?.url || '/client/router' });
542
+ }
543
+ }
472
544
 
473
545
  /**
474
- * 前端调用后端QueryRouter
546
+ * 前端调用后端QueryRouter, 封装 beforeRequest 和 wss
475
547
  */
476
548
  class QueryClient extends Query {
477
549
  tokenName;
478
550
  storage;
479
551
  token;
480
- // 默认不使用ws
481
- qws;
482
552
  constructor(opts) {
483
553
  super(opts);
484
554
  this.tokenName = opts?.tokenName || 'token';
@@ -513,4 +583,4 @@ class QueryClient extends Query {
513
583
  // 移除默认生成的实例
514
584
  // export const client = new QueryClient();
515
585
 
516
- export { BaseQuery, Query, QueryClient, QueryWs, adapter, wrapperError };
586
+ export { BaseQuery, ClientQuery, Query, QueryClient, QueryWs, adapter, wrapperError };
package/dist/query.d.ts CHANGED
@@ -1,11 +1,14 @@
1
+ import { StoreApi } from 'zustand/vanilla';
2
+
1
3
  declare const methods: readonly ["GET", "POST"];
2
4
  type Method = (typeof methods)[number];
3
5
  type AdapterOpts = {
4
- url: string;
6
+ url?: string;
5
7
  headers?: Record<string, string>;
6
8
  body?: Record<string, any>;
7
9
  timeout?: number;
8
10
  method?: Method;
11
+ isBlob?: boolean;
9
12
  };
10
13
  /**
11
14
  *
@@ -15,6 +18,67 @@ type AdapterOpts = {
15
18
  */
16
19
  declare const adapter: (opts: AdapterOpts, overloadOpts?: RequestInit) => Promise<any>;
17
20
 
21
+ type QueryWsStore = {
22
+ connected: boolean;
23
+ status: 'connecting' | 'connected' | 'disconnected';
24
+ setConnected: (connected: boolean) => void;
25
+ setStatus: (status: QuerySelectState) => void;
26
+ };
27
+ type QuerySelectState = 'connecting' | 'connected' | 'disconnected';
28
+ type QueryWsOpts = {
29
+ url?: string;
30
+ store?: StoreApi<QueryWsStore>;
31
+ ws?: WebSocket;
32
+ };
33
+ declare class QueryWs {
34
+ url: string;
35
+ store: StoreApi<QueryWsStore>;
36
+ ws: WebSocket;
37
+ constructor(opts?: QueryWsOpts);
38
+ /**
39
+ * 连接 WebSocket
40
+ */
41
+ connect(opts?: {
42
+ timeout?: number;
43
+ }): Promise<unknown>;
44
+ /**
45
+ * ws.onopen 必须用这个去获取,否者会丢失链接信息
46
+ * @param callback
47
+ * @returns
48
+ */
49
+ listenConnect(callback: () => void): () => void;
50
+ listenClose(callback: () => void): () => void;
51
+ onMessage<T = any, U = any>(fn: (data: U, event: MessageEvent) => void, opts?: {
52
+ /**
53
+ * 是否将数据转换为 JSON
54
+ */
55
+ isJson?: boolean;
56
+ /**
57
+ * 选择器
58
+ */
59
+ selector?: (data: T) => U;
60
+ }): () => void;
61
+ close(): void;
62
+ /**
63
+ * 发送消息
64
+ *
65
+ * @param data
66
+ * @param opts
67
+ * @returns
68
+ */
69
+ send<T = any, U = any>(data: T, opts?: {
70
+ /**
71
+ * 是否将数据转换为 JSON
72
+ */
73
+ isJson?: boolean;
74
+ /**
75
+ * 包装数据
76
+ */
77
+ wrapper?: (data: T) => U;
78
+ }): void;
79
+ getOpen(): boolean;
80
+ }
81
+
18
82
  /**
19
83
  * 请求前处理函数
20
84
  * @param opts 请求配置
@@ -29,10 +93,12 @@ type Fn = (opts: {
29
93
  }) => Promise<Record<string, any> | false>;
30
94
  type QueryOpts = {
31
95
  url?: string;
32
- adapter?: typeof adapter;
33
96
  headers?: Record<string, string>;
97
+ body?: Record<string, any>;
34
98
  timeout?: number;
35
99
  method?: Method;
100
+ isBlob?: boolean;
101
+ adapter?: typeof adapter;
36
102
  [key: string]: any;
37
103
  };
38
104
  type Data = {
@@ -72,7 +138,7 @@ type DataOpts = Partial<QueryOpts> & {
72
138
  * showError 是 如果 success 为 false 且 noMsg 为 false, 则调用 showError
73
139
  * @param res 响应
74
140
  */
75
- declare const setBaseResponse: (res: Result) => void;
141
+ declare const setBaseResponse: (res: Partial<Result>) => Result;
76
142
  declare const wrapperError: ({ code, message }: {
77
143
  code?: number;
78
144
  message?: string;
@@ -103,7 +169,9 @@ declare class Query {
103
169
  * 需要突然停止请求,比如401的时候
104
170
  */
105
171
  stop?: boolean;
172
+ qws: QueryWs;
106
173
  constructor(opts?: QueryOpts);
174
+ setQueryWs(qws: QueryWs): void;
107
175
  /**
108
176
  * 突然停止请求
109
177
  */
@@ -136,6 +204,7 @@ declare class Query {
136
204
  * @param fn 处理函数
137
205
  */
138
206
  after(fn: DataOpts['afterResponse']): void;
207
+ fetchText(url: string, options?: RequestInit): Promise<Result<any>>;
139
208
  }
140
209
 
141
210
  declare class BaseQuery<T extends Query = Query, R extends {
@@ -148,11 +217,11 @@ declare class BaseQuery<T extends Query = Query, R extends {
148
217
  query: T;
149
218
  queryDefine: R;
150
219
  constructor(opts?: {
151
- query: T;
220
+ query?: T;
152
221
  queryDefine?: R;
153
222
  clientQuery?: T;
154
223
  });
155
- get chain(): any;
224
+ get chain(): R['queryChain'];
156
225
  post<R = any, P = any>(data: P, options?: DataOpts): Promise<Result<R>>;
157
226
  get<R = any, P = any>(data: P, options?: DataOpts): Promise<Result<R>>;
158
227
  }
package/dist/query.js CHANGED
@@ -7,6 +7,7 @@
7
7
  const adapter = async (opts, overloadOpts) => {
8
8
  const controller = new AbortController();
9
9
  const signal = controller.signal;
10
+ const isBlob = opts.isBlob || false; // 是否返回 Blob 对象
10
11
  const timeout = opts.timeout || 60000 * 3; // 默认超时时间为 60s * 3
11
12
  const timer = setTimeout(() => {
12
13
  controller.abort();
@@ -38,8 +39,12 @@ const adapter = async (opts, overloadOpts) => {
38
39
  .then((response) => {
39
40
  // 获取 Content-Type 头部信息
40
41
  const contentType = response.headers.get('Content-Type');
42
+ if (isBlob) {
43
+ return response.blob(); // 直接返回 Blob 对象
44
+ }
45
+ const isJson = contentType && contentType.includes('application/json');
41
46
  // 判断返回的数据类型
42
- if (contentType && contentType.includes('application/json')) {
47
+ if (isJson) {
43
48
  return response.json(); // 解析为 JSON
44
49
  }
45
50
  else {
@@ -77,6 +82,7 @@ const setBaseResponse = (res) => {
77
82
  fn?.();
78
83
  }
79
84
  };
85
+ return res;
80
86
  };
81
87
  const wrapperError = ({ code, message }) => {
82
88
  const result = {
@@ -110,6 +116,8 @@ class Query {
110
116
  * 需要突然停止请求,比如401的时候
111
117
  */
112
118
  stop;
119
+ // 默认不使用ws
120
+ qws;
113
121
  constructor(opts) {
114
122
  this.adapter = opts?.adapter || adapter;
115
123
  this.url = opts?.url || '/api/router';
@@ -118,6 +126,9 @@ class Query {
118
126
  };
119
127
  this.timeout = opts?.timeout || 60000 * 3; // 默认超时时间为 60s * 3
120
128
  }
129
+ setQueryWs(qws) {
130
+ this.qws = qws;
131
+ }
121
132
  /**
122
133
  * 突然停止请求
123
134
  */
@@ -227,6 +238,62 @@ class Query {
227
238
  after(fn) {
228
239
  this.afterResponse = fn;
229
240
  }
241
+ async fetchText(url, options) {
242
+ const res = await fetch(url, {
243
+ method: 'GET',
244
+ ...options,
245
+ headers: {
246
+ ...this.headers,
247
+ ...(options?.headers || {}),
248
+ },
249
+ });
250
+ if (!res.ok) {
251
+ return wrapperError({
252
+ code: res.status,
253
+ message: `fetch error: ${res.statusText}`,
254
+ });
255
+ }
256
+ const contentType = res.headers.get('Content-Type');
257
+ if (contentType && contentType.includes('application/json')) {
258
+ const data = await res.json();
259
+ const result = { code: res.status, data, success: res.ok };
260
+ return setBaseResponse(result);
261
+ }
262
+ if (contentType && contentType.includes('text/html')) {
263
+ const text = await res.text();
264
+ const result = {
265
+ code: res.status,
266
+ data: text,
267
+ success: res.ok,
268
+ };
269
+ return setBaseResponse(result);
270
+ }
271
+ if (contentType && contentType.includes('text/plain')) {
272
+ let text = await res.text();
273
+ // 处理特殊情况,比如返回的是纯文本
274
+ if (text.startsWith('{')) {
275
+ try {
276
+ text = JSON.parse(text);
277
+ }
278
+ catch (e) {
279
+ // 如果解析失败,保持原样
280
+ }
281
+ }
282
+ const result = {
283
+ code: res.status,
284
+ data: text,
285
+ success: res.ok,
286
+ };
287
+ return setBaseResponse(result);
288
+ }
289
+ const blob = await res.blob();
290
+ const result = {
291
+ code: res.status,
292
+ data: blob,
293
+ success: res.ok,
294
+ };
295
+ return setBaseResponse(result);
296
+ }
230
297
  }
231
298
  class BaseQuery {
232
299
  query;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kevisual/query",
3
- "version": "0.0.19",
3
+ "version": "0.0.21",
4
4
  "main": "dist/index.js",
5
5
  "module": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -25,12 +25,12 @@
25
25
  "devDependencies": {
26
26
  "@rollup/plugin-node-resolve": "^16.0.1",
27
27
  "@rollup/plugin-typescript": "^12.1.2",
28
- "rollup": "^4.40.2",
28
+ "rollup": "^4.41.1",
29
29
  "rollup-plugin-dts": "^6.2.1",
30
30
  "ts-node": "^10.9.2",
31
31
  "tslib": "^2.8.1",
32
32
  "typescript": "^5.8.3",
33
- "zustand": "^5.0.4"
33
+ "zustand": "^5.0.5"
34
34
  },
35
35
  "packageManager": "yarn@1.22.22",
36
36
  "publishConfig": {
@@ -59,6 +59,6 @@
59
59
  }
60
60
  },
61
61
  "dependencies": {
62
- "openai": "^4.98.0"
62
+ "openai": "^5.0.1"
63
63
  }
64
64
  }