From 171847a46ce9097eac6b8042c6dac4d5de7c7d8d Mon Sep 17 00:00:00 2001 From: abearxiong Date: Mon, 2 Feb 2026 16:57:30 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E7=89=88=E6=9C=AC=E8=87=B3?= =?UTF-8?q?=200.0.42=EF=BC=8C=E4=BF=AE=E6=94=B9=E4=BE=9D=E8=B5=96=E9=A1=B9?= =?UTF-8?q?=E7=89=88=E6=9C=AC=E5=B9=B6=E5=9C=A8=20QueryResources=20?= =?UTF-8?q?=E7=B1=BB=E4=B8=AD=E6=96=B0=E5=A2=9E=20onProcess=20=E5=9B=9E?= =?UTF-8?q?=E8=B0=83=E4=BB=A5=E6=94=AF=E6=8C=81=E4=B8=8A=E4=BC=A0=E8=BF=9B?= =?UTF-8?q?=E5=BA=A6=E9=80=9A=E7=9F=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package.json | 6 +++--- pnpm-lock.yaml | 22 +++++++++++----------- query/query-resources/index.ts | 16 +++++++++++++--- 3 files changed, 27 insertions(+), 17 deletions(-) diff --git a/package.json b/package.json index d69ad15..8d25ca8 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@kevisual/api", - "version": "0.0.41", + "version": "0.0.42", "description": "", "main": "mod.ts", "scripts": { @@ -25,10 +25,10 @@ "@kevisual/query": "^0.0.39", "@kevisual/router": "^0.0.66", "@kevisual/types": "^0.0.12", - "@kevisual/use-config": "^1.0.28", + "@kevisual/use-config": "^1.0.30", "@types/bun": "^1.3.8", "@types/crypto-js": "^4.2.2", - "@types/node": "^25.1.0", + "@types/node": "^25.2.0", "crypto-js": "^4.2.0", "dotenv": "^17.2.3", "fast-glob": "^3.3.3" diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index fb72413..56e00e8 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -49,8 +49,8 @@ importers: specifier: ^0.0.12 version: 0.0.12 '@kevisual/use-config': - specifier: ^1.0.28 - version: 1.0.28(dotenv@17.2.3) + specifier: ^1.0.30 + version: 1.0.30(dotenv@17.2.3) '@types/bun': specifier: ^1.3.8 version: 1.3.8 @@ -58,8 +58,8 @@ importers: specifier: ^4.2.2 version: 4.2.2 '@types/node': - specifier: ^25.1.0 - version: 25.1.0 + specifier: ^25.2.0 + version: 25.2.0 crypto-js: specifier: ^4.2.0 version: 4.2.0 @@ -134,8 +134,8 @@ packages: '@kevisual/types@0.0.12': resolution: {integrity: sha512-zJXH2dosir3jVrQ6QG4i0+iLQeT9gJ3H+cKXs8ReWboxBSYzUZO78XssVeVrFPsJ33iaAqo4q3DWbSS1dWGn7Q==} - '@kevisual/use-config@1.0.28': - resolution: {integrity: sha512-ngF+LDbjxpXWrZNmnShIKF/jPpAa+ezV+DcgoZIIzHlRnIjE+rr9sLkN/B7WJbiH9C/j1tQXOILY8ujBqILrow==} + '@kevisual/use-config@1.0.30': + resolution: {integrity: sha512-kPdna0FW/X7D600aMdiZ5UTjbCo6d8d4jjauSc8RMmBwUU6WliFDSPUNKVpzm2BsDX5Nth1IXFPYMqH+wxqAmw==} peerDependencies: dotenv: ^17 @@ -350,8 +350,8 @@ packages: '@types/node@22.15.27': resolution: {integrity: sha512-5fF+eu5mwihV2BeVtX5vijhdaZOfkQTATrePEaXTcKqI16LhJ7gi2/Vhd9OZM0UojcdmiOCVg5rrax+i1MdoQQ==} - '@types/node@25.1.0': - resolution: {integrity: sha512-t7frlewr6+cbx+9Ohpl0NOTKXZNV9xHRmNOvql47BFJKcEG1CxtxlPEEe+gR9uhVWM4DwhnvTF110mIL4yP9RA==} + '@types/node@25.2.0': + resolution: {integrity: sha512-DZ8VwRFUNzuqJ5khrvwMXHmvPe+zGayJhr2CDNiKB1WBE1ST8Djl00D0IC4vvNmHMdj6DlbYRIaFE7WHjlDl5w==} '@types/resolve@1.20.2': resolution: {integrity: sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==} @@ -765,7 +765,7 @@ snapshots: '@kevisual/types@0.0.12': {} - '@kevisual/use-config@1.0.28(dotenv@17.2.3)': + '@kevisual/use-config@1.0.30(dotenv@17.2.3)': dependencies: '@kevisual/load': 0.0.6 dotenv: 17.2.3 @@ -921,7 +921,7 @@ snapshots: dependencies: undici-types: 6.21.0 - '@types/node@25.1.0': + '@types/node@25.2.0': dependencies: undici-types: 7.16.0 @@ -945,7 +945,7 @@ snapshots: bun-types@1.3.8: dependencies: - '@types/node': 25.1.0 + '@types/node': 25.2.0 call-bind-apply-helpers@1.0.2: dependencies: diff --git a/query/query-resources/index.ts b/query/query-resources/index.ts index 672cd6d..7ba7ae6 100644 --- a/query/query-resources/index.ts +++ b/query/query-resources/index.ts @@ -2,15 +2,18 @@ import { adapter, DataOpts, Result } from '@kevisual/query'; import path from 'path-browserify-esm'; import { hashContent } from './utils'; +type Process = {} type QueryResourcesOptions = { prefix?: string; storage?: Storage; username?: string; + onProcess?: (opts?: Process) => void; [key: string]: any; }; export class QueryResources { prefix: string; // root/resources storage: Storage; + onProcess?: (opts?: Process) => void; constructor(opts: QueryResourcesOptions) { if (opts.username) { this.prefix = `/${opts.username}/resources/`; @@ -18,6 +21,7 @@ export class QueryResources { this.prefix = opts.prefix || ''; } this.storage = opts.storage || localStorage; + this.onProcess = opts.onProcess || (() => { }); } setUsername(username: string) { this.prefix = `/${username}/resources/`; @@ -81,6 +85,7 @@ export class QueryResources { // 使用分块上传 return this.uploadChunkedFile(filepath, content, hash, { chunkSize, ...restOpts }); } + this.onProcess?.({ type: 'uploadBegin', filename, size: fileSize, process: 0 }); const formData = new FormData(); if (isBlob) { @@ -88,7 +93,7 @@ export class QueryResources { } else { formData.append('file', new Blob([content], { type })); } - return adapter({ + const res = await adapter({ url: url.toString(), isPostFile: true, method: 'POST', @@ -101,6 +106,8 @@ export class QueryResources { ...restOpts?.params, }, }); + this.onProcess?.({ type: 'uploadFinish', filename, size: fileSize, process: 100 }); + return res; } async uploadChunkedFile(filepath: string, file: Blob, hash: string, opts?: DataOpts & { chunkSize?: number }): Promise> { const pathname = `${this.prefix}${filepath}`; @@ -114,8 +121,10 @@ export class QueryResources { const { chunkSize: _chunkSize, ...restOpts } = opts || {}; const chunkSize = _chunkSize ?? 5 * 1024 * 1024; // 5MB const totalChunks = Math.ceil(file.size / chunkSize); + this.onProcess?.({ type: 'uploadBegin', filename, size: file.size, process: 0 }); for (let currentChunk = 0; currentChunk < totalChunks; currentChunk++) { + this.onProcess?.({ type: 'uploadChunkedFile', filename, size: file.size, process: 0, totalChunks, currentChunk: currentChunk + 1 }); const start = currentChunk * chunkSize; const end = Math.min(start + chunkSize, file.size); const chunkBlob = file.slice(start, end); @@ -145,15 +154,16 @@ export class QueryResources { }, }); if (res.code !== 200) { - throw new Error(`Chunk upload failed with code ${res!.code}, message: ${res!.message}`); + throw new Error(`Chunk 上传失败 code ${res!.code}, 错误信息是: ${res!.message}`); } console.log(`Chunk ${currentChunk + 1}/${totalChunks} uploaded`, res); + this.onProcess?.({ type: 'uploadChunkedFile', filename, size: file.size, process: Math.round(((currentChunk + 1) / totalChunks) * 100), totalChunks, currentChunk: currentChunk + 1 }); } catch (error) { console.error(`Error uploading chunk ${currentChunk + 1}/${totalChunks}`, error); return { code: 500, message: `分块上传失败: ${(error as Error).message}` }; } } - + this.onProcess?.({ type: 'uploadFinish', filename, size: file.size, process: 100 }); return { code: 200, message: '上传成功' }; }