@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.41",
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",
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.1.0",
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
- return adapter({
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 upload failed with code ${res!.code}, message: ${res!.message}`);
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