@kevisual/api 0.0.15 → 0.0.16

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.16",
4
4
  "description": "",
5
5
  "main": "mod.ts",
6
6
  "scripts": {
@@ -4,13 +4,26 @@ 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 = {
10
11
  id: string;
11
12
  title: string;
12
13
  description: string;
13
14
  enabled?: boolean;
15
+ /**
16
+ * 提示问题
17
+ */
18
+ question?: string;
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 { question, action, response, ...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,61 @@ 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
+ item['api'] = { url: url, query: new Query({ url: url }) };
145
+ }
146
+ if (item.type === 'worker' && item.worker?.url) {
147
+ let viewItem = item as RouterViewWorker;
148
+ if (!item.worker?.workerOptions?.type) {
149
+ item.worker.workerOptions = { ...item.worker.workerOptions, type: 'module' };
100
150
  }
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
- }
151
+ if (item.worker.worker) {
152
+ return item;
153
+ }
154
+ let worker: Worker | SharedWorker | ServiceWorker | undefined = undefined;
155
+ if (item.worker.type === 'SharedWorker') {
156
+ worker = new SharedWorker(item.worker.url, item.worker.workerOptions);
157
+ worker.port.start();
158
+ } else if (viewItem.worker.type === 'serviceWorker') {
159
+ if ('serviceWorker' in navigator) {
160
+ navigator.serviceWorker.register(viewItem.worker.url, item.worker.workerOptions).then(function (registration) {
161
+ console.debug('注册serviceWorker成功 ', registration.scope);
162
+ }, function (err) {
163
+ console.debug('注册 serviceWorker 失败: ', err);
164
+ });
123
165
  } else {
124
- worker = new Worker(viewItem.worker.url, item.worker.workerOptions);
166
+ console.warn('当前浏览器不支持serviceWorker');
125
167
  }
126
- viewItem['worker']['worker'] = worker;
168
+ } else {
169
+ worker = new Worker(viewItem.worker.url, item.worker.workerOptions);
127
170
  }
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
- }
171
+ viewItem['worker']['worker'] = worker;
172
+ }
173
+ if (item.type === 'context' && item.context?.key) {
174
+ if (item.context?.router) {
175
+ return item;
138
176
  }
139
- return item;
140
- }).filter(item => {
141
- const enabled = item.enabled ?? true;
142
- return enabled;
143
- });
177
+ // @ts-ignore
178
+ const context = globalThis['context'] || {}
179
+ const router = context[item.context.key] as QueryRouterServer;
180
+ if (router) {
181
+ item['context']['router'] = router;
182
+ }
183
+ }
184
+ return item;
185
+
144
186
  }
145
187
 
146
188
  /**
@@ -248,7 +290,35 @@ export class QueryProxy {
248
290
  generateId() {
249
291
  return 'route_' + Math.random().toString(36).substring(2, 9);
250
292
  }
251
- async initWorker(item?: RouterViewWorker) {
293
+ async callWorker(msg: any, viewItem: RouterViewWorker['worker']): Promise<Result> {
294
+ const that = this;
295
+ const requestId = this.generateId();
296
+ const worker = viewItem?.worker;
297
+ if (!worker) {
298
+ return { code: 500, message: 'Worker未初始化' };
299
+ }
300
+ let port: MessagePort | Worker | ServiceWorker;
301
+ if (viewItem.type === 'SharedWorker') {
302
+ port = (worker as SharedWorker).port;
303
+ } else {
304
+ port = worker as Worker | ServiceWorker;
305
+ }
306
+ port.postMessage({
307
+ ...msg,
308
+ requestId: requestId,
309
+ })
310
+ return new Promise((resolve) => {
311
+ const timer = setTimeout(() => {
312
+ that.emitter.removeAllListeners(requestId);
313
+ resolve({ code: 500, message: '请求超时' });
314
+ }, 3 * 60 * 1000); // 3分钟超时
315
+ that.emitter.once(requestId, (res: any) => {
316
+ clearTimeout(timer);
317
+ resolve(res);
318
+ });
319
+ });
320
+ }
321
+ async initWorker(item?: RouterViewWorker, initRoutes: boolean = true) {
252
322
  const that = this;
253
323
  if (!item?.worker?.url) {
254
324
  console.warn('Worker URL not provided');
@@ -278,33 +348,10 @@ export class QueryProxy {
278
348
  } else {
279
349
  (worker as Worker).onmessage = callResponse;
280
350
  }
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
- });
351
+ if (!initRoutes) {
352
+ return;
307
353
  }
354
+ const callWorker = this.callWorker.bind(this);
308
355
 
309
356
  const res = await callWorker({
310
357
  path: "router",
@@ -393,6 +440,43 @@ export class QueryProxy {
393
440
  async run(msg: { id?: string, path?: string, key?: string }) {
394
441
  return await this.router.run(msg);
395
442
  }
443
+
444
+ async runByRouteView(routeView: RouterViewItem) {
445
+ if (routeView.response) {
446
+ return routeView;
447
+ }
448
+ const item = this.initRouterView(routeView);
449
+ if (item.type === 'api' && item.api?.url) {
450
+ const query = item.api.query!;
451
+ const res = await query.post<any>(item.action || {});
452
+ item.response = res;
453
+ return item;
454
+ } else if (item.type === 'api') {
455
+ item.response = { code: 500, message: 'API URL未配置' };
456
+ return item;
457
+ }
458
+ if (item.type === 'context' && item.context?.router) {
459
+ const router = item.context.router;
460
+ const res = await router.run(item.action || {});
461
+ item.response = res;
462
+ return item;
463
+ }
464
+ if (item.type === 'page') {
465
+ await this.initPage(item);
466
+ const res = await this.router.run(item.action || {});
467
+ item.response = res;
468
+ return item;
469
+ }
470
+ if (item.type === 'worker' && item.worker?.worker) {
471
+ await this.initWorker(item, false);
472
+ const callWorker = this.callWorker.bind(this);
473
+ const res = await callWorker(item.action || {}, item.worker);
474
+ item.response = res;
475
+ return item;
476
+ }
477
+ item.response = { code: 500, message: '无法处理的路由类型' };
478
+ return item;
479
+ }
396
480
  }
397
481
 
398
482
  type RouterItem = {