From 36628c8279e871befb56210020dc0b28ca435c3e Mon Sep 17 00:00:00 2001 From: xiongxiao Date: Sun, 21 Dec 2025 04:20:25 +0800 Subject: [PATCH] feat: update WebSocket connection and add system version sending functionality - Changed WebSocket connection URL to localhost for testing. - Added a function to send system version to the server upon connection and after a delay. - Improved logging for received messages. chore: update package dependencies - Bump versions for several dependencies including @kevisual/query, lucide-react, vue, and others. - Update package manager version to pnpm@10.26.1. fix: adjust app initialization to use sessionStorage - Modified the app initialization to use a custom sessionStorage implementation backed by an LRU cache. feat: implement sessionStorage with LRU cache - Added a new module for sessionStorage that utilizes LRUCache for efficient caching. --- assistant/package.json | 8 +- assistant/src/app.ts | 6 +- .../src/module/assistant/proxy/http-proxy.ts | 6 +- assistant/src/module/assistant/proxy/index.ts | 3 +- assistant/src/module/assistant/proxy/pipe.ts | 19 ++ assistant/src/module/assistant/proxy/utils.ts | 6 + .../module/assistant/proxy/ws-proxy-base.ts | 0 .../src/module/assistant/proxy/ws-proxy.ts | 13 +- assistant/src/server.ts | 8 +- .../src/services/proxy/proxy-page-index.ts | 67 ++++- assistant/src/test/ws-app.ts | 15 +- cli-center/package.json | 8 +- package.json | 6 +- pnpm-lock.yaml | 243 ++++++++++++------ src/ai/ai.ts | 6 +- src/module/cache.ts | 21 ++ 16 files changed, 323 insertions(+), 112 deletions(-) create mode 100644 assistant/src/module/assistant/proxy/pipe.ts create mode 100644 assistant/src/module/assistant/proxy/utils.ts create mode 100644 assistant/src/module/assistant/proxy/ws-proxy-base.ts create mode 100644 src/module/cache.ts diff --git a/assistant/package.json b/assistant/package.json index cd7150d..29b540a 100644 --- a/assistant/package.json +++ b/assistant/package.json @@ -10,7 +10,7 @@ ], "author": "abearxiong (https://www.xiongxiao.me)", "license": "MIT", - "packageManager": "pnpm@10.26.0", + "packageManager": "pnpm@10.26.1", "type": "module", "files": [ "dist", @@ -46,12 +46,12 @@ "@kevisual/load": "^0.0.6", "@kevisual/local-app-manager": "^0.1.32", "@kevisual/logger": "^0.0.4", - "@kevisual/query": "0.0.32", + "@kevisual/query": "0.0.33", "@kevisual/query-login": "0.0.7", - "@kevisual/router": "^0.0.39", + "@kevisual/router": "^0.0.47", "@kevisual/types": "^0.0.10", "@kevisual/use-config": "^1.0.21", - "@types/bun": "^1.3.4", + "@types/bun": "^1.3.5", "@types/lodash-es": "^4.17.12", "@types/node": "^25.0.3", "@types/send": "^1.2.1", diff --git a/assistant/src/app.ts b/assistant/src/app.ts index 7ff5886..4f47588 100644 --- a/assistant/src/app.ts +++ b/assistant/src/app.ts @@ -41,7 +41,8 @@ export const app: App = useContextKey('app', () => { httpType: 'http', cors: { origin: '*', - } + }, + io: true }, }); } @@ -54,7 +55,8 @@ export const app: App = useContextKey('app', () => { httpsKey: httpsPem.key, cors: { origin: '*', - } + }, + io: true }, }); }); diff --git a/assistant/src/module/assistant/proxy/http-proxy.ts b/assistant/src/module/assistant/proxy/http-proxy.ts index 57d4101..a68b244 100644 --- a/assistant/src/module/assistant/proxy/http-proxy.ts +++ b/assistant/src/module/assistant/proxy/http-proxy.ts @@ -2,6 +2,7 @@ import http from 'node:http'; import https from 'node:https'; import { rewriteCookieDomain } from '../https/cookie-rewrite.ts'; import { ProxyInfo } from './proxy.ts'; +import { pipeStream } from './pipe.ts'; export const defaultApiProxy = [ { path: '/api/router', @@ -109,5 +110,6 @@ export const httpProxy = (req: http.IncomingMessage, res: http.ServerResponse, p }); // 处理 POST 请求的请求体(传递数据到目标服务器),end:true 表示当请求体结束时,关闭请求 req.pipe(proxyReq, { end: true }); - return; -}; + // @ts-ignore + // pipeStream(proxyReq, res); +} \ No newline at end of file diff --git a/assistant/src/module/assistant/proxy/index.ts b/assistant/src/module/assistant/proxy/index.ts index 58afd2f..8754341 100644 --- a/assistant/src/module/assistant/proxy/index.ts +++ b/assistant/src/module/assistant/proxy/index.ts @@ -1,5 +1,4 @@ export * from './proxy.ts'; export * from './file-proxy.ts'; export { default as send } from 'send'; -export * from './http-proxy.ts'; -export * from './ws-proxy.ts'; \ No newline at end of file +export * from './http-proxy.ts'; \ No newline at end of file diff --git a/assistant/src/module/assistant/proxy/pipe.ts b/assistant/src/module/assistant/proxy/pipe.ts new file mode 100644 index 0000000..35b69c7 --- /dev/null +++ b/assistant/src/module/assistant/proxy/pipe.ts @@ -0,0 +1,19 @@ +import * as http from 'http'; +import * as fs from 'fs'; +import { isBun } from './utils.ts'; + +export const pipeFileStream = (filePath: string, res: http.ServerResponse) => { + const readStream = fs.createReadStream(filePath); + if (isBun) { + res.pipe(readStream as any); + } else { + readStream.pipe(res, { end: true }); + } +} +export const pipeStream = (readStream: fs.ReadStream, res: http.ServerResponse) => { + if (isBun) { + res.pipe(readStream as any); + } else { + readStream.pipe(res, { end: true }); + } +} \ No newline at end of file diff --git a/assistant/src/module/assistant/proxy/utils.ts b/assistant/src/module/assistant/proxy/utils.ts new file mode 100644 index 0000000..df6c945 --- /dev/null +++ b/assistant/src/module/assistant/proxy/utils.ts @@ -0,0 +1,6 @@ +export const isBun = typeof Bun !== 'undefined' && Bun?.version != null; + +export const isNode = typeof process !== 'undefined' && process?.versions != null && process.versions?.node != null; + +// @ts-ignore +export const isDeno = typeof Deno !== 'undefined' && Deno?.version != null && Deno?.version?.deno != null; \ No newline at end of file diff --git a/assistant/src/module/assistant/proxy/ws-proxy-base.ts b/assistant/src/module/assistant/proxy/ws-proxy-base.ts new file mode 100644 index 0000000..e69de29 diff --git a/assistant/src/module/assistant/proxy/ws-proxy.ts b/assistant/src/module/assistant/proxy/ws-proxy.ts index 67f3a5a..277eac4 100644 --- a/assistant/src/module/assistant/proxy/ws-proxy.ts +++ b/assistant/src/module/assistant/proxy/ws-proxy.ts @@ -4,6 +4,7 @@ import type { Http2Server } from 'node:http2'; import { WebSocket } from 'ws'; import { ProxyInfo } from './proxy.ts'; import { WebSocketServer } from 'ws'; +import { isBun, isNode } from './utils.ts'; export const wss = new WebSocketServer({ noServer: true, @@ -97,7 +98,13 @@ export const wsProxy = (server: HttpServer | HttpsServer | Http2Server, config: await wssApp.handleConnection(ws, req); }); // 处理升级请求 - server.on('upgrade', (request, socket, head) => { - wssApp.upgrade(request, socket, head); - }); + if (!isBun) { + server.on('upgrade', (request, socket, head) => { + wssApp.upgrade(request, socket, head); + }); + } else if (isBun) { + // @ts-ignore + console.warn('Bun WebSocket proxy is not implemented yet.'); + console.log('server', server) + } }; diff --git a/assistant/src/server.ts b/assistant/src/server.ts index b8f9d8d..3248da8 100644 --- a/assistant/src/server.ts +++ b/assistant/src/server.ts @@ -38,8 +38,12 @@ export const runServer = async (port: number = 51015, listenPath = '127.0.0.1') console.log(`Server is running on ${protocol}://${listenPath}:${_port}`); }); } - app.server.on(proxyRoute); - proxyWs(); + app.server.on([{ + id: 'all', + func: proxyRoute as any + }, + ...proxyWs() + ]); const manager = new AssistantApp(assistantConfig, app); setTimeout(() => { manager.load({ runtime: 'client' }).then(() => { diff --git a/assistant/src/services/proxy/proxy-page-index.ts b/assistant/src/services/proxy/proxy-page-index.ts index 287d417..106398d 100644 --- a/assistant/src/services/proxy/proxy-page-index.ts +++ b/assistant/src/services/proxy/proxy-page-index.ts @@ -1,10 +1,12 @@ -import { fileProxy, httpProxy, createApiProxy, wsProxy } from '@/module/assistant/index.ts'; +import { fileProxy, httpProxy, createApiProxy, ProxyInfo } from '@/module/assistant/index.ts'; import http from 'node:http'; import { LocalProxy } from './local-proxy.ts'; import { assistantConfig, app } from '@/app.ts'; import { log, logger } from '@/module/logger.ts'; import { getToken } from '@/module/http-token.ts'; import { getTokenUserCache } from '@/routes/index.ts'; +import type { WebSocketListenerFun } from "@kevisual/router"; +import WebSocket from 'ws'; const localProxy = new LocalProxy({}); localProxy.initFromAssistantConfig(assistantConfig); @@ -175,8 +177,63 @@ export const proxyWs = () => { const apiProxy = assistantConfig.getCacheAssistantConfig()?.api?.proxy || []; const proxy = assistantConfig.getCacheAssistantConfig()?.proxy || []; const proxyApi = [...apiProxy, ...proxy].filter((item) => item.ws); - log.debug('proxyApi ', proxyApi); - wsProxy(app.server.server, { - apiList: proxyApi, - }); + + const demoProxy = [ + { + path: '/api/ws/demo', + target: 'https://kevisual.xiongxiao.me', + pathname: '/api/router', + ws: true, + } + ] + return proxyApi.map(createProxyInfo); }; +export const createProxyInfo = (proxyApiItem: ProxyInfo) => { + const func: WebSocketListenerFun = async (req, res) => { + const { ws, emitter, id, data } = req; + if (!id) { + ws.send(JSON.stringify({ type: 'error', message: 'not found id' })); + ws.close(); + return; + } + // @ts-ignore + let _proxySocket = ws.data.proxySocket; + if (!_proxySocket) { + const _u = new URL(proxyApiItem.path, `${proxyApiItem.target}`); + if (proxyApiItem.pathname) { + _u.pathname = proxyApiItem.pathname; + } + const isHttps = _u.protocol === 'https:'; + const wsProtocol = isHttps ? 'wss' : 'ws'; + const wsUrl = `${wsProtocol}://${_u.host}${_u.pathname}`; + console.log('WebSocket proxy URL', { wsUrl }); + const proxySocket = new WebSocket(wsUrl); + proxySocket.on('open', () => { + proxySocket.on('message', (message) => { + ws.send(message); + }); + }); + + proxySocket.on('error', (err) => { + console.error(`WebSocket proxy error: ${err.message}`); + }); + proxySocket.on('close', () => { + console.log('WebSocket proxy closed'); + }); + emitter.once('close--' + id, () => { + console.log('WebSocket client closed'); + proxySocket?.close?.(); + }); + // @ts-ignore + ws.data.proxySocket = proxySocket; + return; + } + console.log('ws.data', data); + _proxySocket.send(JSON.stringify(data)) + } + return { + path: proxyApiItem.path, + io: true, + func: func + } +} diff --git a/assistant/src/test/ws-app.ts b/assistant/src/test/ws-app.ts index ab25e88..e5474ef 100644 --- a/assistant/src/test/ws-app.ts +++ b/assistant/src/test/ws-app.ts @@ -5,11 +5,20 @@ const testRouter = () => { // const ws = new WebSocket('wss://kevisual.xiongxiao.me/ws/proxy'); // const ws = new WebSocket('wss://kevisual.xiongxiao.me/api/router'); - const ws = new WebSocket('ws://118.196.32.29:3005/api/router'); + // const ws = new WebSocket('ws://118.196.32.29:3005/api/router'); // const ws = new WebSocket('wss://kevisual.cn/api/router'); + + const ws = new WebSocket('ws://localhost:51015/api/ws/demo?id=12345'); console.log('Connecting to WebSocket server...'); ws.on('open', () => { console.log('WebSocket connection opened'); + sendSystemVersion(); + setTimeout(() => { + sendSystemVersion(); + console.log('第二次发送'); + }, 3000); + }); + const sendSystemVersion = () => { ws.send( JSON.stringify({ "type": "router", @@ -19,10 +28,10 @@ const testRouter = () => { } }), ); - }); + } ws.on('message', (data) => { - console.log('Received message from server:', data.toString()); + console.log('Received message from server e:', data.toString()); }); ws.on('close', () => { console.log('WebSocket connection closed'); diff --git a/cli-center/package.json b/cli-center/package.json index aa11fce..3dd5d50 100644 --- a/cli-center/package.json +++ b/cli-center/package.json @@ -26,7 +26,7 @@ "@kevisual/api": "^0.0.5", "@kevisual/context": "^0.0.4", "@kevisual/kv-code": "^0.0.4", - "@kevisual/query": "^0.0.32", + "@kevisual/query": "^0.0.33", "@kevisual/query-login": "^0.0.7", "@kevisual/registry": "^0.0.1", "@radix-ui/react-slot": "^1.2.4", @@ -40,7 +40,7 @@ "es-toolkit": "^1.43.0", "github-markdown-css": "^5.8.1", "highlight.js": "^11.11.1", - "lucide-react": "^0.561.0", + "lucide-react": "^0.562.0", "marked": "^17.0.1", "marked-highlight": "^2.2.3", "nanoid": "^5.1.6", @@ -48,7 +48,7 @@ "react-dom": "^19.2.3", "react-toastify": "^11.0.5", "tailwind-merge": "^3.4.0", - "vue": "^3.5.25", + "vue": "^3.5.26", "zustand": "^5.0.9" }, "publishConfig": { @@ -62,7 +62,7 @@ "tailwindcss": "^4.1.18", "tw-animate-css": "^1.4.0" }, - "packageManager": "pnpm@10.26.0", + "packageManager": "pnpm@10.26.1", "onlyBuiltDependencies": [ "@tailwindcss/oxide", "esbuild", diff --git a/package.json b/package.json index 7baffba..e80e9c3 100644 --- a/package.json +++ b/package.json @@ -41,7 +41,7 @@ ], "author": "abearxiong", "dependencies": { - "@kevisual/app": "^0.0.1", + "@kevisual/app": "^0.0.2", "@kevisual/context": "^0.0.4", "@kevisual/hot-api": "^0.0.3", "@nut-tree-fork/nut-js": "^4.2.6", @@ -57,9 +57,9 @@ "@kevisual/dts": "^0.0.3", "@kevisual/load": "^0.0.6", "@kevisual/logger": "^0.0.4", - "@kevisual/query": "0.0.32", + "@kevisual/query": "0.0.33", "@kevisual/query-login": "0.0.7", - "@types/bun": "^1.3.4", + "@types/bun": "^1.3.5", "@types/crypto-js": "^4.2.2", "@types/jsonwebtoken": "^9.0.10", "@types/micromatch": "^4.0.10", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 694bd8d..1c49e0d 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -9,8 +9,8 @@ importers: .: dependencies: '@kevisual/app': - specifier: ^0.0.1 - version: 0.0.1(dotenv@17.2.3) + specifier: ^0.0.2 + version: 0.0.2(dotenv@17.2.3) '@kevisual/context': specifier: ^0.0.4 version: 0.0.4 @@ -52,14 +52,14 @@ importers: specifier: ^0.0.4 version: 0.0.4 '@kevisual/query': - specifier: 0.0.32 - version: 0.0.32 + specifier: 0.0.33 + version: 0.0.33 '@kevisual/query-login': specifier: 0.0.7 - version: 0.0.7(@kevisual/query@0.0.32) + version: 0.0.7(@kevisual/query@0.0.33) '@types/bun': - specifier: ^1.3.4 - version: 1.3.4 + specifier: ^1.3.5 + version: 1.3.5 '@types/crypto-js': specifier: ^4.2.2 version: 4.2.2 @@ -140,14 +140,14 @@ importers: specifier: ^0.0.4 version: 0.0.4 '@kevisual/query': - specifier: 0.0.32 - version: 0.0.32 + specifier: 0.0.33 + version: 0.0.33 '@kevisual/query-login': specifier: 0.0.7 - version: 0.0.7(@kevisual/query@0.0.32) + version: 0.0.7(@kevisual/query@0.0.33) '@kevisual/router': - specifier: ^0.0.39 - version: 0.0.39(supports-color@10.2.2) + specifier: ^0.0.47 + version: 0.0.47(supports-color@10.2.2) '@kevisual/types': specifier: ^0.0.10 version: 0.0.10 @@ -155,8 +155,8 @@ importers: specifier: ^1.0.21 version: 1.0.21(dotenv@17.2.3) '@types/bun': - specifier: ^1.3.4 - version: 1.3.4 + specifier: ^1.3.5 + version: 1.3.5 '@types/lodash-es': specifier: ^4.17.12 version: 4.17.12 @@ -219,7 +219,7 @@ importers: version: 3.6.0 '@astrojs/vue': specifier: ^5.1.3 - version: 5.1.3(@types/node@25.0.3)(astro@5.16.6(@types/node@25.0.3)(idb-keyval@6.2.1)(jiti@2.6.1)(lightningcss@1.30.2)(rollup@4.43.0)(typescript@5.8.2))(jiti@2.6.1)(lightningcss@1.30.2)(rollup@4.43.0)(vue@3.5.25(typescript@5.8.2)) + version: 5.1.3(@types/node@25.0.3)(astro@5.16.6(@types/node@25.0.3)(idb-keyval@6.2.1)(jiti@2.6.1)(lightningcss@1.30.2)(rollup@4.43.0)(typescript@5.8.2))(jiti@2.6.1)(lightningcss@1.30.2)(rollup@4.43.0)(vue@3.5.26(typescript@5.8.2)) '@kevisual/api': specifier: ^0.0.5 version: 0.0.5 @@ -230,11 +230,11 @@ importers: specifier: ^0.0.4 version: 0.0.4(@types/react@19.2.7)(dotenv@17.2.3) '@kevisual/query': - specifier: ^0.0.32 - version: 0.0.32 + specifier: ^0.0.33 + version: 0.0.33 '@kevisual/query-login': specifier: ^0.0.7 - version: 0.0.7(@kevisual/query@0.0.32) + version: 0.0.7(@kevisual/query@0.0.33) '@kevisual/registry': specifier: ^0.0.1 version: 0.0.1(typescript@5.8.2) @@ -272,8 +272,8 @@ importers: specifier: ^11.11.1 version: 11.11.1 lucide-react: - specifier: ^0.561.0 - version: 0.561.0(react@19.2.3) + specifier: ^0.562.0 + version: 0.562.0(react@19.2.3) marked: specifier: ^17.0.1 version: 17.0.1 @@ -296,8 +296,8 @@ importers: specifier: ^3.4.0 version: 3.4.0 vue: - specifier: ^3.5.25 - version: 3.5.25(typescript@5.8.2) + specifier: ^3.5.26 + version: 3.5.26(typescript@5.8.2) zustand: specifier: ^5.0.9 version: 5.0.9(@types/react@19.2.7)(react@19.2.3) @@ -1250,6 +1250,9 @@ packages: '@kevisual/app@0.0.1': resolution: {integrity: sha512-PEx8P3l0iNSqrz9Ib9kVCYfqNMX6/LfNu+cEafmY6ECP1cV5Vmv+TH2fuasMosKjtbH2fAdDi97sbd29tdEK+g==} + '@kevisual/app@0.0.2': + resolution: {integrity: sha512-DdUkrsLxHO31y5nYl1qAoBPbvTrunztN3z84ow73Of3kZADJRKmjZtrSOMX53vGVgg74AoLOxbYggoWvil9Ifg==} + '@kevisual/cache@0.0.3': resolution: {integrity: sha512-BWEck69KYL96/ywjYVkML974RHjDJTj2ITQND1zFPR+hlBV1H1p55QZgSYRJCObg3EAV1S9Zic/fR2T4pfe8yg==} @@ -1292,6 +1295,9 @@ packages: '@kevisual/query@0.0.32': resolution: {integrity: sha512-9WN9cjmwSW8I5A0SqITdts9oxlLBGdPP7kJ8vwrxkaQteHS9FzxKuMBJxZzGKZdyte/zJDvdrE+lMf254BGbbg==} + '@kevisual/query@0.0.33': + resolution: {integrity: sha512-3w74bcLpwV3z483eg8n0DgkftfjWC6iLONXBvfyjW6IZf6jMOuouFaM4Rk+uEsTgElU6XGMKseNTp6dlQdWYkg==} + '@kevisual/registry@0.0.1': resolution: {integrity: sha512-//OHu9m4JDrMjgP8o8dcjZd3D3IAUkRVlkTSviouZEH7r5m7mccA3Hvzw0XJ/lelx6exC6LWsyv6c4uV0Dp+gw==} @@ -1304,6 +1310,9 @@ packages: '@kevisual/router@0.0.39': resolution: {integrity: sha512-jE7/csRkMUuuSWl5RZHbOY44xL/2RI/vAJzCsqt150taW5CAri3efdaQJOQlzghlOqqA+1ZyGajxUAYv/HaQxA==} + '@kevisual/router@0.0.47': + resolution: {integrity: sha512-j6/IHQ7hjyJxoSjNbygfrBXi1w7tmGvcNqcLRJwpmSaks65uN6NC9H7Wxna2+/TRtLnRUghHUMIL1pm1uhHeOg==} + '@kevisual/types@0.0.10': resolution: {integrity: sha512-Q73uzzjk9UidumnmCvOpgzqDDvQxsblz22bIFuoiioUFJWwaparx8bpd8ArRyFojicYL1YJoFDzDZ9j9NN8grA==} @@ -2064,8 +2073,8 @@ packages: '@types/braces@3.0.5': resolution: {integrity: sha512-SQFof9H+LXeWNz8wDe7oN5zu7ket0qwMu5vZubW4GCJ8Kkeh6nBWUz87+KTz/G3Kqsrp0j/W253XJb3KMEeg3w==} - '@types/bun@1.3.4': - resolution: {integrity: sha512-EEPTKXHP+zKGPkhRLv+HI0UEX8/o+65hqARxLy8Ov5rIxMBPNTjeZww00CIihrIQGEQBYg+0roO5qOnS/7boGA==} + '@types/bun@1.3.5': + resolution: {integrity: sha512-RnygCqNrd3srIPEWBd5LFeUYG7plCoH2Yw9WaZGyNmdTEei+gWaHqydbaIRkIkcbXwhBT94q78QljxN0Sk838w==} '@types/crypto-js@4.2.2': resolution: {integrity: sha512-sDOLlVbHhXpAUAL0YHDUUwDZf3iN4Bwi4W6a0W0b+QcAezUbRtH4FVb+9J4h+XFPW7l/gQ9F8qC7P+Ec4k8QVQ==} @@ -2213,15 +2222,27 @@ packages: '@vue/compiler-core@3.5.25': resolution: {integrity: sha512-vay5/oQJdsNHmliWoZfHPoVZZRmnSWhug0BYT34njkYTPqClh3DNWLkZNJBVSjsNMrg0CCrBfoKkjZQPM/QVUw==} + '@vue/compiler-core@3.5.26': + resolution: {integrity: sha512-vXyI5GMfuoBCnv5ucIT7jhHKl55Y477yxP6fc4eUswjP8FG3FFVFd41eNDArR+Uk3QKn2Z85NavjaxLxOC19/w==} + '@vue/compiler-dom@3.5.25': resolution: {integrity: sha512-4We0OAcMZsKgYoGlMjzYvaoErltdFI2/25wqanuTu+S4gismOTRTBPi4IASOjxWdzIwrYSjnqONfKvuqkXzE2Q==} + '@vue/compiler-dom@3.5.26': + resolution: {integrity: sha512-y1Tcd3eXs834QjswshSilCBnKGeQjQXB6PqFn/1nxcQw4pmG42G8lwz+FZPAZAby6gZeHSt/8LMPfZ4Rb+Bd/A==} + '@vue/compiler-sfc@3.5.25': resolution: {integrity: sha512-PUgKp2rn8fFsI++lF2sO7gwO2d9Yj57Utr5yEsDf3GNaQcowCLKL7sf+LvVFvtJDXUp/03+dC6f2+LCv5aK1ag==} + '@vue/compiler-sfc@3.5.26': + resolution: {integrity: sha512-egp69qDTSEZcf4bGOSsprUr4xI73wfrY5oRs6GSgXFTiHrWj4Y3X5Ydtip9QMqiCMCPVwLglB9GBxXtTadJ3mA==} + '@vue/compiler-ssr@3.5.25': resolution: {integrity: sha512-ritPSKLBcParnsKYi+GNtbdbrIE1mtuFEJ4U1sWeuOMlIziK5GtOL85t5RhsNy4uWIXPgk+OUdpnXiTdzn8o3A==} + '@vue/compiler-ssr@3.5.26': + resolution: {integrity: sha512-lZT9/Y0nSIRUPVvapFJEVDbEXruZh2IYHMk2zTtEgJSlP5gVOqeWXH54xDKAaFS4rTnDeDBQUYDtxKyoW9FwDw==} + '@vue/devtools-core@7.7.9': resolution: {integrity: sha512-48jrBSwG4GVQRvVeeXn9p9+dlx+ISgasM7SxZZKczseohB0cBz+ITKr4YbLWjmJdy45UHL7UMPlR4Y0CWTRcSQ==} peerDependencies: @@ -2233,23 +2254,26 @@ packages: '@vue/devtools-shared@7.7.9': resolution: {integrity: sha512-iWAb0v2WYf0QWmxCGy0seZNDPdO3Sp5+u78ORnyeonS6MT4PC7VPrryX2BpMJrwlDeaZ6BD4vP4XKjK0SZqaeA==} - '@vue/reactivity@3.5.25': - resolution: {integrity: sha512-5xfAypCQepv4Jog1U4zn8cZIcbKKFka3AgWHEFQeK65OW+Ys4XybP6z2kKgws4YB43KGpqp5D/K3go2UPPunLA==} + '@vue/reactivity@3.5.26': + resolution: {integrity: sha512-9EnYB1/DIiUYYnzlnUBgwU32NNvLp/nhxLXeWRhHUEeWNTn1ECxX8aGO7RTXeX6PPcxe3LLuNBFoJbV4QZ+CFQ==} - '@vue/runtime-core@3.5.25': - resolution: {integrity: sha512-Z751v203YWwYzy460bzsYQISDfPjHTl+6Zzwo/a3CsAf+0ccEjQ8c+0CdX1WsumRTHeywvyUFtW6KvNukT/smA==} + '@vue/runtime-core@3.5.26': + resolution: {integrity: sha512-xJWM9KH1kd201w5DvMDOwDHYhrdPTrAatn56oB/LRG4plEQeZRQLw0Bpwih9KYoqmzaxF0OKSn6swzYi84e1/Q==} - '@vue/runtime-dom@3.5.25': - resolution: {integrity: sha512-a4WrkYFbb19i9pjkz38zJBg8wa/rboNERq3+hRRb0dHiJh13c+6kAbgqCPfMaJ2gg4weWD3APZswASOfmKwamA==} + '@vue/runtime-dom@3.5.26': + resolution: {integrity: sha512-XLLd/+4sPC2ZkN/6+V4O4gjJu6kSDbHAChvsyWgm1oGbdSO3efvGYnm25yCjtFm/K7rrSDvSfPDgN1pHgS4VNQ==} - '@vue/server-renderer@3.5.25': - resolution: {integrity: sha512-UJaXR54vMG61i8XNIzTSf2Q7MOqZHpp8+x3XLGtE3+fL+nQd+k7O5+X3D/uWrnQXOdMw5VPih+Uremcw+u1woQ==} + '@vue/server-renderer@3.5.26': + resolution: {integrity: sha512-TYKLXmrwWKSodyVuO1WAubucd+1XlLg4set0YoV+Hu8Lo79mp/YMwWV5mC5FgtsDxX3qo1ONrxFaTP1OQgy1uA==} peerDependencies: - vue: 3.5.25 + vue: 3.5.26 '@vue/shared@3.5.25': resolution: {integrity: sha512-AbOPdQQnAnzs58H2FrrDxYj/TJfmeS2jdfEEhgiKINy+bnOANmVizIEgq1r+C5zsbs6l1CCQxtcj71rwNQ4jWg==} + '@vue/shared@3.5.26': + resolution: {integrity: sha512-7Z6/y3uFI5PRoKeorTOSXKcDj0MSasfNNltcslbFrPpcw6aXRUALq4IfJlaTRspiWIUOEZbrpM+iQGmCOiWe4A==} + abort-controller@3.0.0: resolution: {integrity: sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==} engines: {node: '>=6.5'} @@ -2465,8 +2489,8 @@ packages: buffer@6.0.3: resolution: {integrity: sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==} - bun-types@1.3.4: - resolution: {integrity: sha512-5ua817+BZPZOlNaRgGBpZJOSAQ9RQ17pkwPD0yR7CfJg+r8DgIILByFifDTa+IPDDxzf5VNhtNlcKqFzDgJvlQ==} + bun-types@1.3.5: + resolution: {integrity: sha512-inmAYe2PFLs0SUbFOWSVD24sg1jFlMPxOjOSSCYqUgn4Hsc3rDc7dFvfVYjFPNHtov6kgUeulV4SxbuIV/stPw==} bundle-name@4.1.0: resolution: {integrity: sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q==} @@ -2885,6 +2909,10 @@ packages: resolution: {integrity: sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==} engines: {node: '>=0.12'} + entities@7.0.0: + resolution: {integrity: sha512-FDWG5cmEYf2Z00IkYRhbFrwIwvdFKH07uV8dvNy0omp/Qb1xcyCWp2UDtcwJF4QZZvk0sLudP6/hAu42TaqVhQ==} + engines: {node: '>=0.12'} + error-stack-parser-es@0.1.5: resolution: {integrity: sha512-xHku1X40RO+fO8yJ8Wh2f2rZWVjqyhb1zgq1yZ8aZRQkv6OOKhKWRUaht3eSCUbAOBaKIgM+ykwFLE+QUxgGeg==} @@ -3665,8 +3693,8 @@ packages: peerDependencies: react: ^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0 - lucide-react@0.561.0: - resolution: {integrity: sha512-Y59gMY38tl4/i0qewcqohPdEbieBy7SovpBL9IFebhc2mDd8x4PZSOsiFRkpPcOq6bj1r/mjH/Rk73gSlIJP2A==} + lucide-react@0.562.0: + resolution: {integrity: sha512-82hOAu7y0dbVuFfmO4bYF1XEwYk/mEbM5E+b1jgci/udUBEE/R7LF5Ip0CCEmXe8AybRM8L+04eP+LGZeDvkiw==} peerDependencies: react: ^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0 @@ -5063,8 +5091,8 @@ packages: resolution: {integrity: sha512-Dhxzh5HZuiHQhbvTW9AMetFfBHDMYpo23Uo9btPXgdYP+3T5S+p+jgNy7spra+veYhBP2dCSgxR/i2Y02h5/6w==} engines: {node: '>=0.10.0'} - vue@3.5.25: - resolution: {integrity: sha512-YLVdgv2K13WJ6n+kD5owehKtEXwdwXuj2TTyJMsO7pSeKw2bfRNZGjhB7YzrpbMYj5b5QsUebHpOqR3R3ziy/g==} + vue@3.5.26: + resolution: {integrity: sha512-SJ/NTccVyAoNUJmkM9KUqPcYlY+u8OVL1X5EW9RIs3ch5H2uERxyyIUI4MRxVCSOiEcupX9xNGde1tL9ZKpimA==} peerDependencies: typescript: '*' peerDependenciesMeta: @@ -5364,15 +5392,15 @@ snapshots: transitivePeerDependencies: - supports-color - '@astrojs/vue@5.1.3(@types/node@25.0.3)(astro@5.16.6(@types/node@25.0.3)(idb-keyval@6.2.1)(jiti@2.6.1)(lightningcss@1.30.2)(rollup@4.43.0)(typescript@5.8.2))(jiti@2.6.1)(lightningcss@1.30.2)(rollup@4.43.0)(vue@3.5.25(typescript@5.8.2))': + '@astrojs/vue@5.1.3(@types/node@25.0.3)(astro@5.16.6(@types/node@25.0.3)(idb-keyval@6.2.1)(jiti@2.6.1)(lightningcss@1.30.2)(rollup@4.43.0)(typescript@5.8.2))(jiti@2.6.1)(lightningcss@1.30.2)(rollup@4.43.0)(vue@3.5.26(typescript@5.8.2))': dependencies: - '@vitejs/plugin-vue': 5.2.1(vite@6.4.1(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2))(vue@3.5.25(typescript@5.8.2)) - '@vitejs/plugin-vue-jsx': 4.2.0(vite@6.4.1(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2))(vue@3.5.25(typescript@5.8.2)) + '@vitejs/plugin-vue': 5.2.1(vite@6.4.1(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2))(vue@3.5.26(typescript@5.8.2)) + '@vitejs/plugin-vue-jsx': 4.2.0(vite@6.4.1(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2))(vue@3.5.26(typescript@5.8.2)) '@vue/compiler-sfc': 3.5.25 astro: 5.16.6(@types/node@25.0.3)(idb-keyval@6.2.1)(jiti@2.6.1)(lightningcss@1.30.2)(rollup@4.43.0)(typescript@5.8.2) vite: 6.4.1(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2) - vite-plugin-vue-devtools: 7.7.9(rollup@4.43.0)(vite@6.4.1(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2))(vue@3.5.25(typescript@5.8.2)) - vue: 3.5.25(typescript@5.8.2) + vite-plugin-vue-devtools: 7.7.9(rollup@4.43.0)(vite@6.4.1(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2))(vue@3.5.26(typescript@5.8.2)) + vue: 3.5.26(typescript@5.8.2) transitivePeerDependencies: - '@nuxt/kit' - '@types/node' @@ -6281,6 +6309,19 @@ snapshots: - dotenv - supports-color + '@kevisual/app@0.0.2(dotenv@17.2.3)': + dependencies: + '@kevisual/ai': 0.0.19 + '@kevisual/context': 0.0.4 + '@kevisual/query': 0.0.32 + '@kevisual/router': 0.0.39 + '@kevisual/use-config': 1.0.21(dotenv@17.2.3) + mitt: 3.0.1 + nanoid: 5.1.6 + transitivePeerDependencies: + - dotenv + - supports-color + '@kevisual/cache@0.0.3': dependencies: idb-keyval: 6.2.1 @@ -6362,10 +6403,10 @@ snapshots: '@kevisual/permission@0.0.3': {} - '@kevisual/query-login@0.0.7(@kevisual/query@0.0.32)': + '@kevisual/query-login@0.0.7(@kevisual/query@0.0.33)': dependencies: '@kevisual/cache': 0.0.3 - '@kevisual/query': 0.0.32 + '@kevisual/query': 0.0.33 dotenv: 17.2.3 '@kevisual/query@0.0.30': {} @@ -6374,6 +6415,8 @@ snapshots: '@kevisual/query@0.0.32': {} + '@kevisual/query@0.0.33': {} + '@kevisual/registry@0.0.1(typescript@5.8.2)': dependencies: class-variance-authority: 0.7.1 @@ -6408,7 +6451,15 @@ snapshots: transitivePeerDependencies: - supports-color - '@kevisual/router@0.0.39(supports-color@10.2.2)': + '@kevisual/router@0.0.39': + dependencies: + path-to-regexp: 8.3.0 + selfsigned: 5.2.0 + send: 1.2.1(supports-color@10.2.2) + transitivePeerDependencies: + - supports-color + + '@kevisual/router@0.0.47(supports-color@10.2.2)': dependencies: path-to-regexp: 8.3.0 selfsigned: 5.2.0 @@ -7338,9 +7389,9 @@ snapshots: '@types/braces@3.0.5': {} - '@types/bun@1.3.4': + '@types/bun@1.3.5': dependencies: - bun-types: 1.3.4 + bun-types: 1.3.5 '@types/crypto-js@4.2.2': {} @@ -7482,21 +7533,21 @@ snapshots: transitivePeerDependencies: - supports-color - '@vitejs/plugin-vue-jsx@4.2.0(vite@6.4.1(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2))(vue@3.5.25(typescript@5.8.2))': + '@vitejs/plugin-vue-jsx@4.2.0(vite@6.4.1(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2))(vue@3.5.26(typescript@5.8.2))': dependencies: '@babel/core': 7.28.5 '@babel/plugin-transform-typescript': 7.28.5(@babel/core@7.28.5) '@rolldown/pluginutils': 1.0.0-beta.55 '@vue/babel-plugin-jsx': 1.5.0(@babel/core@7.28.5) vite: 6.4.1(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2) - vue: 3.5.25(typescript@5.8.2) + vue: 3.5.26(typescript@5.8.2) transitivePeerDependencies: - supports-color - '@vitejs/plugin-vue@5.2.1(vite@6.4.1(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2))(vue@3.5.25(typescript@5.8.2))': + '@vitejs/plugin-vue@5.2.1(vite@6.4.1(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2))(vue@3.5.26(typescript@5.8.2))': dependencies: vite: 6.4.1(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2) - vue: 3.5.25(typescript@5.8.2) + vue: 3.5.26(typescript@5.8.2) '@vue/babel-helper-vue-transform-on@1.5.0': {} @@ -7535,11 +7586,24 @@ snapshots: estree-walker: 2.0.2 source-map-js: 1.2.1 + '@vue/compiler-core@3.5.26': + dependencies: + '@babel/parser': 7.28.5 + '@vue/shared': 3.5.26 + entities: 7.0.0 + estree-walker: 2.0.2 + source-map-js: 1.2.1 + '@vue/compiler-dom@3.5.25': dependencies: '@vue/compiler-core': 3.5.25 '@vue/shared': 3.5.25 + '@vue/compiler-dom@3.5.26': + dependencies: + '@vue/compiler-core': 3.5.26 + '@vue/shared': 3.5.26 + '@vue/compiler-sfc@3.5.25': dependencies: '@babel/parser': 7.28.5 @@ -7552,12 +7616,29 @@ snapshots: postcss: 8.5.6 source-map-js: 1.2.1 + '@vue/compiler-sfc@3.5.26': + dependencies: + '@babel/parser': 7.28.5 + '@vue/compiler-core': 3.5.26 + '@vue/compiler-dom': 3.5.26 + '@vue/compiler-ssr': 3.5.26 + '@vue/shared': 3.5.26 + estree-walker: 2.0.2 + magic-string: 0.30.21 + postcss: 8.5.6 + source-map-js: 1.2.1 + '@vue/compiler-ssr@3.5.25': dependencies: '@vue/compiler-dom': 3.5.25 '@vue/shared': 3.5.25 - '@vue/devtools-core@7.7.9(vite@6.4.1(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2))(vue@3.5.25(typescript@5.8.2))': + '@vue/compiler-ssr@3.5.26': + dependencies: + '@vue/compiler-dom': 3.5.26 + '@vue/shared': 3.5.26 + + '@vue/devtools-core@7.7.9(vite@6.4.1(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2))(vue@3.5.26(typescript@5.8.2))': dependencies: '@vue/devtools-kit': 7.7.9 '@vue/devtools-shared': 7.7.9 @@ -7565,7 +7646,7 @@ snapshots: nanoid: 5.1.6 pathe: 2.0.3 vite-hot-client: 2.1.0(vite@6.4.1(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)) - vue: 3.5.25(typescript@5.8.2) + vue: 3.5.26(typescript@5.8.2) transitivePeerDependencies: - vite @@ -7583,30 +7664,32 @@ snapshots: dependencies: rfdc: 1.4.1 - '@vue/reactivity@3.5.25': + '@vue/reactivity@3.5.26': dependencies: - '@vue/shared': 3.5.25 + '@vue/shared': 3.5.26 - '@vue/runtime-core@3.5.25': + '@vue/runtime-core@3.5.26': dependencies: - '@vue/reactivity': 3.5.25 - '@vue/shared': 3.5.25 + '@vue/reactivity': 3.5.26 + '@vue/shared': 3.5.26 - '@vue/runtime-dom@3.5.25': + '@vue/runtime-dom@3.5.26': dependencies: - '@vue/reactivity': 3.5.25 - '@vue/runtime-core': 3.5.25 - '@vue/shared': 3.5.25 - csstype: 3.1.3 + '@vue/reactivity': 3.5.26 + '@vue/runtime-core': 3.5.26 + '@vue/shared': 3.5.26 + csstype: 3.2.3 - '@vue/server-renderer@3.5.25(vue@3.5.25(typescript@5.8.2))': + '@vue/server-renderer@3.5.26(vue@3.5.26(typescript@5.8.2))': dependencies: - '@vue/compiler-ssr': 3.5.25 - '@vue/shared': 3.5.25 - vue: 3.5.25(typescript@5.8.2) + '@vue/compiler-ssr': 3.5.26 + '@vue/shared': 3.5.26 + vue: 3.5.26(typescript@5.8.2) '@vue/shared@3.5.25': {} + '@vue/shared@3.5.26': {} + abort-controller@3.0.0: dependencies: event-target-shim: 5.0.1 @@ -7945,7 +8028,7 @@ snapshots: base64-js: 1.5.1 ieee754: 1.2.1 - bun-types@1.3.4: + bun-types@1.3.5: dependencies: '@types/node': 25.0.3 @@ -8313,6 +8396,8 @@ snapshots: entities@6.0.1: {} + entities@7.0.0: {} + error-stack-parser-es@0.1.5: {} es-define-property@1.0.1: {} @@ -9239,7 +9324,7 @@ snapshots: dependencies: react: 19.2.3 - lucide-react@0.561.0(react@19.2.3): + lucide-react@0.562.0(react@19.2.3): dependencies: react: 19.2.3 @@ -11025,9 +11110,9 @@ snapshots: - rollup - supports-color - vite-plugin-vue-devtools@7.7.9(rollup@4.43.0)(vite@6.4.1(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2))(vue@3.5.25(typescript@5.8.2)): + vite-plugin-vue-devtools@7.7.9(rollup@4.43.0)(vite@6.4.1(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2))(vue@3.5.26(typescript@5.8.2)): dependencies: - '@vue/devtools-core': 7.7.9(vite@6.4.1(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2))(vue@3.5.25(typescript@5.8.2)) + '@vue/devtools-core': 7.7.9(vite@6.4.1(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2))(vue@3.5.26(typescript@5.8.2)) '@vue/devtools-kit': 7.7.9 '@vue/devtools-shared': 7.7.9 execa: 9.6.1 @@ -11083,13 +11168,13 @@ snapshots: void-elements@3.1.0: {} - vue@3.5.25(typescript@5.8.2): + vue@3.5.26(typescript@5.8.2): dependencies: - '@vue/compiler-dom': 3.5.25 - '@vue/compiler-sfc': 3.5.25 - '@vue/runtime-dom': 3.5.25 - '@vue/server-renderer': 3.5.25(vue@3.5.25(typescript@5.8.2)) - '@vue/shared': 3.5.25 + '@vue/compiler-dom': 3.5.26 + '@vue/compiler-sfc': 3.5.26 + '@vue/runtime-dom': 3.5.26 + '@vue/server-renderer': 3.5.26(vue@3.5.26(typescript@5.8.2)) + '@vue/shared': 3.5.26 optionalDependencies: typescript: 5.8.2 diff --git a/src/ai/ai.ts b/src/ai/ai.ts index 53f902c..ac5371a 100644 --- a/src/ai/ai.ts +++ b/src/ai/ai.ts @@ -1,4 +1,4 @@ -import { App } from '@kevisual/app/src/app.ts'; +import { App } from '@kevisual/app'; import { storage } from '../module/query.ts'; - -export const app = new App({ token: storage.getItem('token') || '', storage }); \ No newline at end of file +import { sessionStorage } from '../module/cache.ts'; +export const app = new App({ token: storage.getItem('token') || '', storage: sessionStorage }); \ No newline at end of file diff --git a/src/module/cache.ts b/src/module/cache.ts new file mode 100644 index 0000000..bf81bce --- /dev/null +++ b/src/module/cache.ts @@ -0,0 +1,21 @@ +import { LRUCache } from 'lru-cache' + +export const cache = new LRUCache({ + max: 10000, // 最大缓存数量 + ttl: 1000 * 60 * 60 * 24 * 7, // 缓存过期时间,单位为毫秒,这里设置为7天 +}); + +export const sessionStorage = { + setItem: (key: string, value: any) => { + cache.set(key, value); + }, + getItem: (key: string) => { + return cache.get(key); + }, + removeItem: (key: string) => { + cache.delete(key); + }, + clear: () => { + cache.clear(); + } +} \ No newline at end of file