@kevisual/api 0.0.41 → 0.0.42
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
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kevisual/api",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.42",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "mod.ts",
|
|
6
6
|
"scripts": {
|
|
@@ -25,10 +25,10 @@
|
|
|
25
25
|
"@kevisual/query": "^0.0.39",
|
|
26
26
|
"@kevisual/router": "^0.0.66",
|
|
27
27
|
"@kevisual/types": "^0.0.12",
|
|
28
|
-
"@kevisual/use-config": "^1.0.
|
|
28
|
+
"@kevisual/use-config": "^1.0.30",
|
|
29
29
|
"@types/bun": "^1.3.8",
|
|
30
30
|
"@types/crypto-js": "^4.2.2",
|
|
31
|
-
"@types/node": "^25.
|
|
31
|
+
"@types/node": "^25.2.0",
|
|
32
32
|
"crypto-js": "^4.2.0",
|
|
33
33
|
"dotenv": "^17.2.3",
|
|
34
34
|
"fast-glob": "^3.3.3"
|
|
@@ -2,15 +2,18 @@ import { adapter, DataOpts, Result } from '@kevisual/query';
|
|
|
2
2
|
import path from 'path-browserify-esm';
|
|
3
3
|
import { hashContent } from './utils';
|
|
4
4
|
|
|
5
|
+
type Process = {}
|
|
5
6
|
type QueryResourcesOptions = {
|
|
6
7
|
prefix?: string;
|
|
7
8
|
storage?: Storage;
|
|
8
9
|
username?: string;
|
|
10
|
+
onProcess?: (opts?: Process) => void;
|
|
9
11
|
[key: string]: any;
|
|
10
12
|
};
|
|
11
13
|
export class QueryResources {
|
|
12
14
|
prefix: string; // root/resources
|
|
13
15
|
storage: Storage;
|
|
16
|
+
onProcess?: (opts?: Process) => void;
|
|
14
17
|
constructor(opts: QueryResourcesOptions) {
|
|
15
18
|
if (opts.username) {
|
|
16
19
|
this.prefix = `/${opts.username}/resources/`;
|
|
@@ -18,6 +21,7 @@ export class QueryResources {
|
|
|
18
21
|
this.prefix = opts.prefix || '';
|
|
19
22
|
}
|
|
20
23
|
this.storage = opts.storage || localStorage;
|
|
24
|
+
this.onProcess = opts.onProcess || (() => { });
|
|
21
25
|
}
|
|
22
26
|
setUsername(username: string) {
|
|
23
27
|
this.prefix = `/${username}/resources/`;
|
|
@@ -81,6 +85,7 @@ export class QueryResources {
|
|
|
81
85
|
// 使用分块上传
|
|
82
86
|
return this.uploadChunkedFile(filepath, content, hash, { chunkSize, ...restOpts });
|
|
83
87
|
}
|
|
88
|
+
this.onProcess?.({ type: 'uploadBegin', filename, size: fileSize, process: 0 });
|
|
84
89
|
|
|
85
90
|
const formData = new FormData();
|
|
86
91
|
if (isBlob) {
|
|
@@ -88,7 +93,7 @@ export class QueryResources {
|
|
|
88
93
|
} else {
|
|
89
94
|
formData.append('file', new Blob([content], { type }));
|
|
90
95
|
}
|
|
91
|
-
|
|
96
|
+
const res = await adapter({
|
|
92
97
|
url: url.toString(),
|
|
93
98
|
isPostFile: true,
|
|
94
99
|
method: 'POST',
|
|
@@ -101,6 +106,8 @@ export class QueryResources {
|
|
|
101
106
|
...restOpts?.params,
|
|
102
107
|
},
|
|
103
108
|
});
|
|
109
|
+
this.onProcess?.({ type: 'uploadFinish', filename, size: fileSize, process: 100 });
|
|
110
|
+
return res;
|
|
104
111
|
}
|
|
105
112
|
async uploadChunkedFile(filepath: string, file: Blob, hash: string, opts?: DataOpts & { chunkSize?: number }): Promise<Result<any>> {
|
|
106
113
|
const pathname = `${this.prefix}${filepath}`;
|
|
@@ -114,8 +121,10 @@ export class QueryResources {
|
|
|
114
121
|
const { chunkSize: _chunkSize, ...restOpts } = opts || {};
|
|
115
122
|
const chunkSize = _chunkSize ?? 5 * 1024 * 1024; // 5MB
|
|
116
123
|
const totalChunks = Math.ceil(file.size / chunkSize);
|
|
124
|
+
this.onProcess?.({ type: 'uploadBegin', filename, size: file.size, process: 0 });
|
|
117
125
|
|
|
118
126
|
for (let currentChunk = 0; currentChunk < totalChunks; currentChunk++) {
|
|
127
|
+
this.onProcess?.({ type: 'uploadChunkedFile', filename, size: file.size, process: 0, totalChunks, currentChunk: currentChunk + 1 });
|
|
119
128
|
const start = currentChunk * chunkSize;
|
|
120
129
|
const end = Math.min(start + chunkSize, file.size);
|
|
121
130
|
const chunkBlob = file.slice(start, end);
|
|
@@ -145,15 +154,16 @@ export class QueryResources {
|
|
|
145
154
|
},
|
|
146
155
|
});
|
|
147
156
|
if (res.code !== 200) {
|
|
148
|
-
throw new Error(`Chunk
|
|
157
|
+
throw new Error(`Chunk 上传失败 code ${res!.code}, 错误信息是: ${res!.message}`);
|
|
149
158
|
}
|
|
150
159
|
console.log(`Chunk ${currentChunk + 1}/${totalChunks} uploaded`, res);
|
|
160
|
+
this.onProcess?.({ type: 'uploadChunkedFile', filename, size: file.size, process: Math.round(((currentChunk + 1) / totalChunks) * 100), totalChunks, currentChunk: currentChunk + 1 });
|
|
151
161
|
} catch (error) {
|
|
152
162
|
console.error(`Error uploading chunk ${currentChunk + 1}/${totalChunks}`, error);
|
|
153
163
|
return { code: 500, message: `分块上传失败: ${(error as Error).message}` };
|
|
154
164
|
}
|
|
155
165
|
}
|
|
156
|
-
|
|
166
|
+
this.onProcess?.({ type: 'uploadFinish', filename, size: file.size, process: 100 });
|
|
157
167
|
return { code: 200, message: '上传成功' };
|
|
158
168
|
}
|
|
159
169
|
|