更新 @kevisual/api 版本至 0.0.16,增强 RouterViewItem 类型,添加 question、response 和 action 属性,重构 initRouterViewQuery 和 callWorker 方法以优化路由视图初始化和工作线程调用

This commit is contained in:
2026-01-03 01:54:55 +08:00
parent 31e8c0346f
commit cb8723c172
2 changed files with 158 additions and 74 deletions

View File

@@ -1,6 +1,6 @@
{ {
"name": "@kevisual/api", "name": "@kevisual/api",
"version": "0.0.15", "version": "0.0.16",
"description": "", "description": "",
"main": "mod.ts", "main": "mod.ts",
"scripts": { "scripts": {

View File

@@ -4,13 +4,26 @@ import { filter } from '@kevisual/js-filter'
import { EventEmitter } from 'eventemitter3'; import { EventEmitter } from 'eventemitter3';
export const RouteTypeList = ['api', 'context', 'worker', 'page'] as const; export const RouteTypeList = ['api', 'context', 'worker', 'page'] as const;
export type RouterViewItem = RouterViewApi | RouterViewContext | RouterViewWorker | RouteViewPage; export type RouterViewItemInfo = RouterViewApi | RouterViewContext | RouterViewWorker | RouteViewPage;
export type RouterViewItem<T = {}> = RouterViewItemInfo & T;
type RouteViewBase = { type RouteViewBase = {
id: string; id: string;
title: string; title: string;
description: string; description: string;
enabled?: boolean; enabled?: boolean;
/**
* 提示问题
*/
question?: string;
/**
* 响应数据
*/
response?: any;
/**
* 默认动作配置
*/
action?: { path?: string; key?: string; id?: string; payload?: any;[key: string]: any };
} }
export type RouterViewApi = { export type RouterViewApi = {
type: 'api', type: 'api',
@@ -46,6 +59,30 @@ export type RouterViewWorker = {
} }
} & RouteViewBase; } & RouteViewBase;
/**
* 去掉不需要保存都服务器的数据
* @param item
* @returns
*/
export const pickRouterViewData = (item: RouterViewItem) => {
const { question, action, response, ...rest } = item;
if (rest.type === 'api') {
if (rest.api) {
delete rest.api.query;
}
}
if (rest.type === 'worker') {
if (rest.worker) {
delete rest.worker.worker;
}
}
if (rest.type === 'context') {
if (rest.context) {
delete rest.context.router;
}
}
return rest
}
/** /**
* 注入 js 的url地址使用importScripts加载 * 注入 js 的url地址使用importScripts加载
*/ */
@@ -91,8 +128,16 @@ export class QueryProxy {
return undefined; return undefined;
} }
} }
async initRouterViewQuery() { initRouterViewQuery() {
this.routerViewItems = this.routerViewItems.map(item => { this.routerViewItems = this.routerViewItems.map(item => {
return this.initRouterView(item);
}).filter(item => {
const enabled = item.enabled ?? true;
return enabled;
});
}
initRouterView(item: RouterViewItem) {
if (item.type === 'api' && item.api?.url) { if (item.type === 'api' && item.api?.url) {
const url = item.api.url; const url = item.api.url;
if (item?.api?.query) return item; if (item?.api?.query) return item;
@@ -137,10 +182,7 @@ export class QueryProxy {
} }
} }
return item; return item;
}).filter(item => {
const enabled = item.enabled ?? true;
return enabled;
});
} }
/** /**
@@ -248,7 +290,35 @@ export class QueryProxy {
generateId() { generateId() {
return 'route_' + Math.random().toString(36).substring(2, 9); return 'route_' + Math.random().toString(36).substring(2, 9);
} }
async initWorker(item?: RouterViewWorker) { async callWorker(msg: any, viewItem: RouterViewWorker['worker']): Promise<Result> {
const that = this;
const requestId = this.generateId();
const worker = viewItem?.worker;
if (!worker) {
return { code: 500, message: 'Worker未初始化' };
}
let port: MessagePort | Worker | ServiceWorker;
if (viewItem.type === 'SharedWorker') {
port = (worker as SharedWorker).port;
} else {
port = worker as Worker | ServiceWorker;
}
port.postMessage({
...msg,
requestId: requestId,
})
return new Promise((resolve) => {
const timer = setTimeout(() => {
that.emitter.removeAllListeners(requestId);
resolve({ code: 500, message: '请求超时' });
}, 3 * 60 * 1000); // 3分钟超时
that.emitter.once(requestId, (res: any) => {
clearTimeout(timer);
resolve(res);
});
});
}
async initWorker(item?: RouterViewWorker, initRoutes: boolean = true) {
const that = this; const that = this;
if (!item?.worker?.url) { if (!item?.worker?.url) {
console.warn('Worker URL not provided'); console.warn('Worker URL not provided');
@@ -278,33 +348,10 @@ export class QueryProxy {
} else { } else {
(worker as Worker).onmessage = callResponse; (worker as Worker).onmessage = callResponse;
} }
const callWorker = async (msg: any, viewItem: RouterViewWorker['worker']): Promise<Result> => { if (!initRoutes) {
const requestId = this.generateId(); return;
const worker = viewItem?.worker;
if (!worker) {
return { code: 500, message: 'Worker未初始化' };
}
let port: MessagePort | Worker | ServiceWorker;
if (viewItem.type === 'SharedWorker') {
port = (worker as SharedWorker).port;
} else {
port = worker as Worker | ServiceWorker;
}
port.postMessage({
...msg,
requestId: requestId,
})
return new Promise((resolve) => {
const timer = setTimeout(() => {
that.emitter.removeAllListeners(requestId);
resolve({ code: 500, message: '请求超时' });
}, 3 * 60 * 1000); // 3分钟超时
that.emitter.once(requestId, (res: any) => {
clearTimeout(timer);
resolve(res);
});
});
} }
const callWorker = this.callWorker.bind(this);
const res = await callWorker({ const res = await callWorker({
path: "router", path: "router",
@@ -393,6 +440,43 @@ export class QueryProxy {
async run(msg: { id?: string, path?: string, key?: string }) { async run(msg: { id?: string, path?: string, key?: string }) {
return await this.router.run(msg); return await this.router.run(msg);
} }
async runByRouteView(routeView: RouterViewItem) {
if (routeView.response) {
return routeView;
}
const item = this.initRouterView(routeView);
if (item.type === 'api' && item.api?.url) {
const query = item.api.query!;
const res = await query.post<any>(item.action || {});
item.response = res;
return item;
} else if (item.type === 'api') {
item.response = { code: 500, message: 'API URL未配置' };
return item;
}
if (item.type === 'context' && item.context?.router) {
const router = item.context.router;
const res = await router.run(item.action || {});
item.response = res;
return item;
}
if (item.type === 'page') {
await this.initPage(item);
const res = await this.router.run(item.action || {});
item.response = res;
return item;
}
if (item.type === 'worker' && item.worker?.worker) {
await this.initWorker(item, false);
const callWorker = this.callWorker.bind(this);
const res = await callWorker(item.action || {}, item.worker);
item.response = res;
return item;
}
item.response = { code: 500, message: '无法处理的路由类型' };
return item;
}
} }
type RouterItem = { type RouterItem = {