@kevisual/api 0.0.15 → 0.0.17

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kevisual/api",
3
- "version": "0.0.15",
3
+ "version": "0.0.17",
4
4
  "description": "",
5
5
  "main": "mod.ts",
6
6
  "scripts": {
@@ -21,8 +21,8 @@
21
21
  "packageManager": "pnpm@10.27.0",
22
22
  "type": "module",
23
23
  "devDependencies": {
24
- "@kevisual/cache": "^0.0.4",
25
- "@kevisual/query": "^0.0.33",
24
+ "@kevisual/cache": "^0.0.5",
25
+ "@kevisual/query": "^0.0.34",
26
26
  "@kevisual/router": "^0.0.52",
27
27
  "@kevisual/types": "^0.0.10",
28
28
  "@kevisual/use-config": "^1.0.21",
@@ -1,16 +1,29 @@
1
- import { Query, Result } from '@kevisual/query/query';
1
+ import { QueryClient as Query, Result } from '@kevisual/query';
2
2
  import { QueryRouterServer, Route } from '@kevisual/router/src/route.ts';
3
3
  import { filter } from '@kevisual/js-filter'
4
4
  import { EventEmitter } from 'eventemitter3';
5
5
 
6
6
  export const RouteTypeList = ['api', 'context', 'worker', 'page'] as const;
7
- export type RouterViewItem = RouterViewApi | RouterViewContext | RouterViewWorker | RouteViewPage;
7
+ export type RouterViewItemInfo = RouterViewApi | RouterViewContext | RouterViewWorker | RouteViewPage;
8
+ export type RouterViewItem<T = {}> = RouterViewItemInfo & T;
8
9
 
9
10
  type RouteViewBase = {
11
+ /**
12
+ * _id 用于纯本地存储标识
13
+ */
14
+ _id: string;
10
15
  id: string;
11
16
  title: string;
12
17
  description: string;
13
18
  enabled?: boolean;
19
+ /**
20
+ * 响应数据
21
+ */
22
+ response?: any;
23
+ /**
24
+ * 默认动作配置
25
+ */
26
+ action?: { path?: string; key?: string; id?: string; payload?: any;[key: string]: any };
14
27
  }
15
28
  export type RouterViewApi = {
16
29
  type: 'api',
@@ -46,6 +59,30 @@ export type RouterViewWorker = {
46
59
  }
47
60
  } & RouteViewBase;
48
61
 
62
+ /**
63
+ * 去掉不需要保存都服务器的数据
64
+ * @param item
65
+ * @returns
66
+ */
67
+ export const pickRouterViewData = (item: RouterViewItem) => {
68
+ const { action, response, _id, ...rest } = item;
69
+ if (rest.type === 'api') {
70
+ if (rest.api) {
71
+ delete rest.api.query;
72
+ }
73
+ }
74
+ if (rest.type === 'worker') {
75
+ if (rest.worker) {
76
+ delete rest.worker.worker;
77
+ }
78
+ }
79
+ if (rest.type === 'context') {
80
+ if (rest.context) {
81
+ delete rest.context.router;
82
+ }
83
+ }
84
+ return rest
85
+ }
49
86
  /**
50
87
  * 注入 js 的url地址,使用importScripts加载
51
88
  */
@@ -91,56 +128,62 @@ export class QueryProxy {
91
128
  return undefined;
92
129
  }
93
130
  }
94
- async initRouterViewQuery() {
131
+ initRouterViewQuery() {
95
132
  this.routerViewItems = this.routerViewItems.map(item => {
96
- if (item.type === 'api' && item.api?.url) {
97
- const url = item.api.url;
98
- if (item?.api?.query) return item;
99
- item['api'] = { url: url, query: new Query({ url: url }) };
133
+ return this.initRouterView(item);
134
+ }).filter(item => {
135
+ const enabled = item.enabled ?? true;
136
+ return enabled;
137
+ });
138
+ }
139
+
140
+ initRouterView(item: RouterViewItem) {
141
+ if (item.type === 'api' && item.api?.url) {
142
+ const url = item.api.url;
143
+ if (item?.api?.query) return item;
144
+ const query = new Query({ url: url });
145
+ item['api'] = { url: url, query: query };
146
+ }
147
+ if (item.type === 'worker' && item.worker?.url) {
148
+ let viewItem = item as RouterViewWorker;
149
+ if (!item.worker?.workerOptions?.type) {
150
+ item.worker.workerOptions = { ...item.worker.workerOptions, type: 'module' };
100
151
  }
101
- if (item.type === 'worker' && item.worker?.url) {
102
- let viewItem = item as RouterViewWorker;
103
- if (!item.worker?.workerOptions?.type) {
104
- item.worker.workerOptions = { ...item.worker.workerOptions, type: 'module' };
105
- }
106
- if (item.worker.worker) {
107
- return item;
108
- }
109
- let worker: Worker | SharedWorker | ServiceWorker | undefined = undefined;
110
- if (item.worker.type === 'SharedWorker') {
111
- worker = new SharedWorker(item.worker.url, item.worker.workerOptions);
112
- worker.port.start();
113
- } else if (viewItem.worker.type === 'serviceWorker') {
114
- if ('serviceWorker' in navigator) {
115
- navigator.serviceWorker.register(viewItem.worker.url, item.worker.workerOptions).then(function (registration) {
116
- console.debug('注册serviceWorker成功 ', registration.scope);
117
- }, function (err) {
118
- console.debug('注册 serviceWorker 失败: ', err);
119
- });
120
- } else {
121
- console.warn('当前浏览器不支持serviceWorker');
122
- }
152
+ if (item.worker.worker) {
153
+ return item;
154
+ }
155
+ let worker: Worker | SharedWorker | ServiceWorker | undefined = undefined;
156
+ if (item.worker.type === 'SharedWorker') {
157
+ worker = new SharedWorker(item.worker.url, item.worker.workerOptions);
158
+ worker.port.start();
159
+ } else if (viewItem.worker.type === 'serviceWorker') {
160
+ if ('serviceWorker' in navigator) {
161
+ navigator.serviceWorker.register(viewItem.worker.url, item.worker.workerOptions).then(function (registration) {
162
+ console.debug('注册serviceWorker成功 ', registration.scope);
163
+ }, function (err) {
164
+ console.debug('注册 serviceWorker 失败: ', err);
165
+ });
123
166
  } else {
124
- worker = new Worker(viewItem.worker.url, item.worker.workerOptions);
167
+ console.warn('当前浏览器不支持serviceWorker');
125
168
  }
126
- viewItem['worker']['worker'] = worker;
169
+ } else {
170
+ worker = new Worker(viewItem.worker.url, item.worker.workerOptions);
127
171
  }
128
- if (item.type === 'context' && item.context?.key) {
129
- if (item.context?.router) {
130
- return item;
131
- }
132
- // @ts-ignore
133
- const context = globalThis['context'] || {}
134
- const router = context[item.context.key] as QueryRouterServer;
135
- if (router) {
136
- item['context']['router'] = router;
137
- }
172
+ viewItem['worker']['worker'] = worker;
173
+ }
174
+ if (item.type === 'context' && item.context?.key) {
175
+ if (item.context?.router) {
176
+ return item;
138
177
  }
139
- return item;
140
- }).filter(item => {
141
- const enabled = item.enabled ?? true;
142
- return enabled;
143
- });
178
+ // @ts-ignore
179
+ const context = globalThis['context'] || {}
180
+ const router = context[item.context.key] as QueryRouterServer;
181
+ if (router) {
182
+ item['context']['router'] = router;
183
+ }
184
+ }
185
+ return item;
186
+
144
187
  }
145
188
 
146
189
  /**
@@ -248,7 +291,35 @@ export class QueryProxy {
248
291
  generateId() {
249
292
  return 'route_' + Math.random().toString(36).substring(2, 9);
250
293
  }
251
- async initWorker(item?: RouterViewWorker) {
294
+ async callWorker(msg: any, viewItem: RouterViewWorker['worker']): Promise<Result> {
295
+ const that = this;
296
+ const requestId = this.generateId();
297
+ const worker = viewItem?.worker;
298
+ if (!worker) {
299
+ return { code: 500, message: 'Worker未初始化' };
300
+ }
301
+ let port: MessagePort | Worker | ServiceWorker;
302
+ if (viewItem.type === 'SharedWorker') {
303
+ port = (worker as SharedWorker).port;
304
+ } else {
305
+ port = worker as Worker | ServiceWorker;
306
+ }
307
+ port.postMessage({
308
+ ...msg,
309
+ requestId: requestId,
310
+ })
311
+ return new Promise((resolve) => {
312
+ const timer = setTimeout(() => {
313
+ that.emitter.removeAllListeners(requestId);
314
+ resolve({ code: 500, message: '请求超时' });
315
+ }, 3 * 60 * 1000); // 3分钟超时
316
+ that.emitter.once(requestId, (res: any) => {
317
+ clearTimeout(timer);
318
+ resolve(res);
319
+ });
320
+ });
321
+ }
322
+ async initWorker(item?: RouterViewWorker, initRoutes: boolean = true) {
252
323
  const that = this;
253
324
  if (!item?.worker?.url) {
254
325
  console.warn('Worker URL not provided');
@@ -278,33 +349,10 @@ export class QueryProxy {
278
349
  } else {
279
350
  (worker as Worker).onmessage = callResponse;
280
351
  }
281
- const callWorker = async (msg: any, viewItem: RouterViewWorker['worker']): Promise<Result> => {
282
- const requestId = this.generateId();
283
- const worker = viewItem?.worker;
284
- if (!worker) {
285
- return { code: 500, message: 'Worker未初始化' };
286
- }
287
- let port: MessagePort | Worker | ServiceWorker;
288
- if (viewItem.type === 'SharedWorker') {
289
- port = (worker as SharedWorker).port;
290
- } else {
291
- port = worker as Worker | ServiceWorker;
292
- }
293
- port.postMessage({
294
- ...msg,
295
- requestId: requestId,
296
- })
297
- return new Promise((resolve) => {
298
- const timer = setTimeout(() => {
299
- that.emitter.removeAllListeners(requestId);
300
- resolve({ code: 500, message: '请求超时' });
301
- }, 3 * 60 * 1000); // 3分钟超时
302
- that.emitter.once(requestId, (res: any) => {
303
- clearTimeout(timer);
304
- resolve(res);
305
- });
306
- });
352
+ if (!initRoutes) {
353
+ return;
307
354
  }
355
+ const callWorker = this.callWorker.bind(this);
308
356
 
309
357
  const res = await callWorker({
310
358
  path: "router",
@@ -393,6 +441,43 @@ export class QueryProxy {
393
441
  async run(msg: { id?: string, path?: string, key?: string }) {
394
442
  return await this.router.run(msg);
395
443
  }
444
+
445
+ async runByRouteView(routeView: RouterViewItem) {
446
+ if (routeView.response) {
447
+ return routeView;
448
+ }
449
+ const item = this.initRouterView(routeView);
450
+ if (item.type === 'api' && item.api?.url) {
451
+ const query = item.api.query!;
452
+ const res = await query.post<any>(item.action || {});
453
+ item.response = res;
454
+ return item;
455
+ } else if (item.type === 'api') {
456
+ item.response = { code: 500, message: 'API URL未配置' };
457
+ return item;
458
+ }
459
+ if (item.type === 'context' && item.context?.router) {
460
+ const router = item.context.router;
461
+ const res = await router.run(item.action || {});
462
+ item.response = res;
463
+ return item;
464
+ }
465
+ if (item.type === 'page') {
466
+ await this.initPage(item);
467
+ const res = await this.router.run(item.action || {});
468
+ item.response = res;
469
+ return item;
470
+ }
471
+ if (item.type === 'worker' && item.worker?.worker) {
472
+ await this.initWorker(item, false);
473
+ const callWorker = this.callWorker.bind(this);
474
+ const res = await callWorker(item.action || {}, item.worker);
475
+ item.response = res;
476
+ return item;
477
+ }
478
+ item.response = { code: 500, message: '无法处理的路由类型' };
479
+ return item;
480
+ }
396
481
  }
397
482
 
398
483
  type RouterItem = {