@kevisual/api 0.0.11 → 0.0.14
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 +4 -4
- package/query/query-proxy/index.ts +78 -34
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kevisual/api",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.14",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "mod.ts",
|
|
6
6
|
"scripts": {
|
|
@@ -18,12 +18,12 @@
|
|
|
18
18
|
"keywords": [],
|
|
19
19
|
"author": "abearxiong <xiongxiao@xiongxiao.me> (https://www.xiongxiao.me)",
|
|
20
20
|
"license": "MIT",
|
|
21
|
-
"packageManager": "pnpm@10.
|
|
21
|
+
"packageManager": "pnpm@10.27.0",
|
|
22
22
|
"type": "module",
|
|
23
23
|
"devDependencies": {
|
|
24
24
|
"@kevisual/cache": "^0.0.4",
|
|
25
25
|
"@kevisual/query": "^0.0.33",
|
|
26
|
-
"@kevisual/router": "^0.0.
|
|
26
|
+
"@kevisual/router": "^0.0.52",
|
|
27
27
|
"@kevisual/types": "^0.0.10",
|
|
28
28
|
"@kevisual/use-config": "^1.0.21",
|
|
29
29
|
"@types/bun": "^1.3.5",
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
"fast-glob": "^3.3.3"
|
|
33
33
|
},
|
|
34
34
|
"dependencies": {
|
|
35
|
-
"@kevisual/js-filter": "^0.0.
|
|
35
|
+
"@kevisual/js-filter": "^0.0.3",
|
|
36
36
|
"@kevisual/load": "^0.0.6",
|
|
37
37
|
"es-toolkit": "^1.43.0",
|
|
38
38
|
"eventemitter3": "^5.0.1",
|
|
@@ -4,38 +4,46 @@ import { filter } from '@kevisual/js-filter'
|
|
|
4
4
|
import { EventEmitter } from 'eventemitter3';
|
|
5
5
|
|
|
6
6
|
export type RouterViewItem = RouterViewApi | RouterViewContext | RouterViewWorker;
|
|
7
|
-
|
|
7
|
+
type RouteViewBase = {
|
|
8
|
+
id: string;
|
|
8
9
|
title: string;
|
|
9
10
|
description: string;
|
|
11
|
+
enabled?: boolean;
|
|
12
|
+
}
|
|
13
|
+
export type RouterViewApi = {
|
|
10
14
|
type: 'api',
|
|
11
15
|
api: {
|
|
12
16
|
url: string,
|
|
13
|
-
// 已初始化的query
|
|
17
|
+
// 已初始化的query实例,不需要编辑配置
|
|
14
18
|
query?: Query
|
|
15
19
|
}
|
|
16
|
-
}
|
|
20
|
+
} & RouteViewBase;
|
|
17
21
|
|
|
18
22
|
export type RouterViewContext = {
|
|
19
|
-
title: string;
|
|
20
|
-
description: string;
|
|
21
23
|
type: 'context',
|
|
22
24
|
context: {
|
|
23
25
|
key: string,
|
|
24
|
-
// 从context中获取router
|
|
26
|
+
// 从context中获取router,不需要编辑配置
|
|
25
27
|
router?: QueryRouterServer
|
|
26
28
|
}
|
|
27
|
-
}
|
|
29
|
+
} & RouteViewBase;
|
|
28
30
|
export type RouterViewWorker = {
|
|
29
|
-
title: string;
|
|
30
|
-
description: string;
|
|
31
31
|
type: 'worker',
|
|
32
32
|
worker: {
|
|
33
33
|
type: 'Worker' | 'SharedWorker' | 'serviceWorker',
|
|
34
34
|
url: string,
|
|
35
|
-
// 已初始化的worker
|
|
36
|
-
worker?: Worker | SharedWorker | ServiceWorker
|
|
35
|
+
// 已初始化的worker实例,不需要编辑配置
|
|
36
|
+
worker?: Worker | SharedWorker | ServiceWorker,
|
|
37
|
+
/**
|
|
38
|
+
* worker选项
|
|
39
|
+
* default: { type: 'module' }
|
|
40
|
+
*/
|
|
41
|
+
workerOptions?: {
|
|
42
|
+
type: 'module' | 'classic'
|
|
43
|
+
}
|
|
37
44
|
}
|
|
38
|
-
}
|
|
45
|
+
} & RouteViewBase;
|
|
46
|
+
|
|
39
47
|
export type RouterViewQuery = {
|
|
40
48
|
id: string,
|
|
41
49
|
query: string,
|
|
@@ -51,15 +59,15 @@ export type RouterViewData = {
|
|
|
51
59
|
export class QueryProxy {
|
|
52
60
|
router: QueryRouterServer;
|
|
53
61
|
token?: string;
|
|
54
|
-
|
|
62
|
+
routerViewItems: RouterViewItem[];
|
|
55
63
|
views: RouterViewQuery[];
|
|
56
64
|
emitter: EventEmitter;
|
|
57
|
-
constructor(opts?: {
|
|
65
|
+
constructor(opts?: { router?: QueryRouterServer, token?: string, routerViewData?: RouterViewData }) {
|
|
58
66
|
this.router = opts?.router || new QueryRouterServer();
|
|
59
67
|
this.token = opts?.token || this.getDefulatToken();
|
|
60
|
-
this.
|
|
61
|
-
this.views = opts?.
|
|
62
|
-
this.
|
|
68
|
+
this.routerViewItems = opts?.routerViewData?.data?.items || [];
|
|
69
|
+
this.views = opts?.routerViewData?.views || [];
|
|
70
|
+
this.initRouterViewQuery();
|
|
63
71
|
this.emitter = new EventEmitter();
|
|
64
72
|
}
|
|
65
73
|
getDefulatToken() {
|
|
@@ -71,21 +79,28 @@ export class QueryProxy {
|
|
|
71
79
|
return undefined;
|
|
72
80
|
}
|
|
73
81
|
}
|
|
74
|
-
async
|
|
75
|
-
this.
|
|
82
|
+
async initRouterViewQuery() {
|
|
83
|
+
this.routerViewItems = this.routerViewItems.map(item => {
|
|
76
84
|
if (item.type === 'api' && item.api?.url) {
|
|
77
85
|
const url = item.api.url;
|
|
86
|
+
if (item?.api?.query) return item;
|
|
78
87
|
item['api'] = { url: url, query: new Query({ url: url }) };
|
|
79
88
|
}
|
|
80
89
|
if (item.type === 'worker' && item.worker?.url) {
|
|
81
90
|
let viewItem = item as RouterViewWorker;
|
|
91
|
+
if (!item.worker?.workerOptions?.type) {
|
|
92
|
+
item.worker.workerOptions = { ...item.worker.workerOptions, type: 'module' };
|
|
93
|
+
}
|
|
94
|
+
if (item.worker.worker) {
|
|
95
|
+
return item;
|
|
96
|
+
}
|
|
82
97
|
let worker: Worker | SharedWorker | ServiceWorker | undefined = undefined;
|
|
83
98
|
if (item.worker.type === 'SharedWorker') {
|
|
84
|
-
worker = new SharedWorker(item.worker.url);
|
|
99
|
+
worker = new SharedWorker(item.worker.url, item.worker.workerOptions);
|
|
85
100
|
worker.port.start();
|
|
86
101
|
} else if (viewItem.worker.type === 'serviceWorker') {
|
|
87
102
|
if ('serviceWorker' in navigator) {
|
|
88
|
-
navigator.serviceWorker.register(viewItem.worker.url).then(function (registration) {
|
|
103
|
+
navigator.serviceWorker.register(viewItem.worker.url, item.worker.workerOptions).then(function (registration) {
|
|
89
104
|
console.debug('注册serviceWorker成功 ', registration.scope);
|
|
90
105
|
}, function (err) {
|
|
91
106
|
console.debug('注册 serviceWorker 失败: ', err);
|
|
@@ -94,11 +109,14 @@ export class QueryProxy {
|
|
|
94
109
|
console.warn('当前浏览器不支持serviceWorker');
|
|
95
110
|
}
|
|
96
111
|
} else {
|
|
97
|
-
worker = new Worker(viewItem.worker.url);
|
|
112
|
+
worker = new Worker(viewItem.worker.url, item.worker.workerOptions);
|
|
98
113
|
}
|
|
99
114
|
viewItem['worker']['worker'] = worker;
|
|
100
115
|
}
|
|
101
116
|
if (item.type === 'context' && item.context?.key) {
|
|
117
|
+
if (item.context?.router) {
|
|
118
|
+
return item;
|
|
119
|
+
}
|
|
102
120
|
// @ts-ignore
|
|
103
121
|
const context = globalThis['context'] || {}
|
|
104
122
|
const router = context[item.context.key] as QueryRouterServer;
|
|
@@ -107,6 +125,9 @@ export class QueryProxy {
|
|
|
107
125
|
}
|
|
108
126
|
}
|
|
109
127
|
return item;
|
|
128
|
+
}).filter(item => {
|
|
129
|
+
const enabled = item.enabled ?? true;
|
|
130
|
+
return enabled;
|
|
110
131
|
});
|
|
111
132
|
}
|
|
112
133
|
|
|
@@ -114,13 +135,13 @@ export class QueryProxy {
|
|
|
114
135
|
* 初始化路由
|
|
115
136
|
* @returns
|
|
116
137
|
*/
|
|
117
|
-
async init(
|
|
118
|
-
const
|
|
119
|
-
if (
|
|
138
|
+
async init() {
|
|
139
|
+
const routerViewItems = this.routerViewItems || [];
|
|
140
|
+
if (routerViewItems.length === 0) {
|
|
120
141
|
await this.initApi();
|
|
121
142
|
return;
|
|
122
143
|
}
|
|
123
|
-
for (const item of
|
|
144
|
+
for (const item of routerViewItems) {
|
|
124
145
|
switch (item.type) {
|
|
125
146
|
case 'api':
|
|
126
147
|
this.initApi(item);
|
|
@@ -145,12 +166,14 @@ export class QueryProxy {
|
|
|
145
166
|
for (const r of _list) {
|
|
146
167
|
if (r.path || r.id) {
|
|
147
168
|
console.debug(`注册路由: [${r.path}] ${r?.key}`, 'API');
|
|
169
|
+
let metadata = r.metadata || {};
|
|
170
|
+
metadata.viewItem = item;
|
|
148
171
|
this.router.route({
|
|
149
172
|
path: r.path,
|
|
150
173
|
key: r.key || '',
|
|
151
174
|
id: r.id,
|
|
152
175
|
description: r.description,
|
|
153
|
-
metadata:
|
|
176
|
+
metadata: metadata,
|
|
154
177
|
}).define(async (ctx) => {
|
|
155
178
|
const msg = { ...ctx.query };
|
|
156
179
|
if (msg.token === undefined && that.token !== undefined) {
|
|
@@ -173,12 +196,14 @@ export class QueryProxy {
|
|
|
173
196
|
const routes = router.getList();
|
|
174
197
|
for (const r of routes) {
|
|
175
198
|
console.debug(`注册路由: [${r.path}] ${r?.key}`, 'Context');
|
|
199
|
+
let metadata = r.metadata || {};
|
|
200
|
+
metadata.viewItem = item;
|
|
176
201
|
this.router.route({
|
|
177
202
|
path: r.path,
|
|
178
203
|
key: r.key || '',
|
|
179
204
|
id: r.id,
|
|
180
205
|
description: r.description,
|
|
181
|
-
metadata:
|
|
206
|
+
metadata: metadata,
|
|
182
207
|
}).define(async (ctx) => {
|
|
183
208
|
const res = await router.run({ path: r.path, key: r.key, ...ctx.query });
|
|
184
209
|
ctx.forward(res)
|
|
@@ -200,14 +225,23 @@ export class QueryProxy {
|
|
|
200
225
|
console.warn('Worker not initialized');
|
|
201
226
|
return;
|
|
202
227
|
}
|
|
203
|
-
|
|
204
|
-
const
|
|
205
|
-
|
|
206
|
-
const msg = e.data;
|
|
228
|
+
const callResponse = (e: MessageEvent) => {
|
|
229
|
+
const msg = e.data;
|
|
230
|
+
if (msg.requestId) {
|
|
207
231
|
const requestId = msg.requestId;
|
|
208
232
|
that.emitter.emit(requestId, msg);
|
|
209
|
-
}
|
|
233
|
+
} else {
|
|
234
|
+
that.router.run(msg);
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
if (item.worker.type === 'SharedWorker') {
|
|
238
|
+
const port = (worker as SharedWorker).port;
|
|
239
|
+
port.onmessage = callResponse;
|
|
210
240
|
port.start();
|
|
241
|
+
} else if (item.worker.type === 'serviceWorker') {
|
|
242
|
+
navigator.serviceWorker.addEventListener('message', callResponse);
|
|
243
|
+
} else {
|
|
244
|
+
(worker as Worker).onmessage = callResponse;
|
|
211
245
|
}
|
|
212
246
|
const callWorker = async (msg: any, viewItem: RouterViewWorker['worker']): Promise<Result> => {
|
|
213
247
|
const requestId = this.generateId();
|
|
@@ -236,6 +270,7 @@ export class QueryProxy {
|
|
|
236
270
|
});
|
|
237
271
|
});
|
|
238
272
|
}
|
|
273
|
+
|
|
239
274
|
const res = await callWorker({
|
|
240
275
|
path: "router",
|
|
241
276
|
key: 'list',
|
|
@@ -250,12 +285,14 @@ export class QueryProxy {
|
|
|
250
285
|
for (const r of _list) {
|
|
251
286
|
if (r.path || r.id) {
|
|
252
287
|
console.debug(`注册路由: [${r.path}] ${r?.key}`, 'API');
|
|
288
|
+
let metadata = r.metadata || {};
|
|
289
|
+
metadata.viewItem = item;
|
|
253
290
|
this.router.route({
|
|
254
291
|
path: r.path,
|
|
255
292
|
key: r.key || '',
|
|
256
293
|
id: r.id,
|
|
257
294
|
description: r.description,
|
|
258
|
-
metadata:
|
|
295
|
+
metadata: metadata,
|
|
259
296
|
}).define(async (ctx) => {
|
|
260
297
|
const msg = { ...ctx.query };
|
|
261
298
|
if (msg.token === undefined && that.token !== undefined) {
|
|
@@ -289,6 +326,13 @@ export class QueryProxy {
|
|
|
289
326
|
}
|
|
290
327
|
return routes;
|
|
291
328
|
}
|
|
329
|
+
async getViewQuery(viewId: string) {
|
|
330
|
+
const view = this.views.find(v => v.id === viewId);
|
|
331
|
+
if (view) {
|
|
332
|
+
return view.query;
|
|
333
|
+
}
|
|
334
|
+
return undefined;
|
|
335
|
+
}
|
|
292
336
|
/**
|
|
293
337
|
* 运行路由
|
|
294
338
|
* @param msg
|