@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 +3 -3
- package/query/query-proxy/index.ts +158 -73
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kevisual/api",
|
|
3
|
-
"version": "0.0.
|
|
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.
|
|
25
|
-
"@kevisual/query": "^0.0.
|
|
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
|
|
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
|
|
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
|
-
|
|
131
|
+
initRouterViewQuery() {
|
|
95
132
|
this.routerViewItems = this.routerViewItems.map(item => {
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
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.
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
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
|
-
|
|
167
|
+
console.warn('当前浏览器不支持serviceWorker');
|
|
125
168
|
}
|
|
126
|
-
|
|
169
|
+
} else {
|
|
170
|
+
worker = new Worker(viewItem.worker.url, item.worker.workerOptions);
|
|
127
171
|
}
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
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
|
-
|
|
140
|
-
|
|
141
|
-
const
|
|
142
|
-
|
|
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
|
|
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
|
-
|
|
282
|
-
|
|
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 = {
|