web-dc-api 0.0.40 → 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/dist/dc.min.js +2 -2
- package/dist/index.cjs.js +1 -1
- package/dist/index.d.ts +132 -24
- package/dist/index.esm.js +1 -1
- package/lib/common/define.ts +32 -22
- package/lib/common/module-system.ts +1 -0
- package/lib/common/service-worker.ts +2 -1
- package/lib/common/types/types.ts +7 -1
- package/lib/dc.ts +74 -17
- package/lib/implements/aiproxy/client.ts +18 -14
- package/lib/implements/file/client.ts +8 -8
- package/lib/implements/file/manager.ts +6 -2
- package/lib/implements/threaddb/core/logstore.ts +4 -4
- package/lib/implements/threaddb/lsstoreds/metadata.ts +23 -22
- package/lib/implements/threaddb/net/net.ts +0 -1
- package/lib/implements/wallet/manager.ts +287 -160
- package/lib/index.ts +15 -3
- package/lib/interfaces/file-interface.ts +1 -1
- package/lib/interfaces/util-interface.ts +1 -1
- package/lib/modules/aiproxy-module.ts +40 -15
- package/lib/modules/auth-module.ts +6 -6
- package/lib/modules/database-module.ts +51 -3
- package/lib/modules/file-module.ts +12 -7
- package/package.json +1 -1
package/lib/common/define.ts
CHANGED
|
@@ -1,27 +1,37 @@
|
|
|
1
|
-
|
|
2
1
|
// 只考虑浏览器环境
|
|
3
2
|
declare const __IS_PROD__: boolean | undefined;
|
|
4
3
|
|
|
5
4
|
let isProd = false;
|
|
6
|
-
|
|
7
5
|
// 打包后用 __IS_PROD__,源码直用时用 window.IS_PROD
|
|
8
|
-
if (typeof __IS_PROD__ !==
|
|
6
|
+
if (typeof __IS_PROD__ !== "undefined") {
|
|
9
7
|
isProd = __IS_PROD__;
|
|
10
|
-
} else if (
|
|
8
|
+
} else if (
|
|
9
|
+
typeof window !== "undefined" &&
|
|
10
|
+
typeof (window as any).IS_PROD !== "undefined"
|
|
11
|
+
) {
|
|
11
12
|
isProd = (window as any).IS_PROD;
|
|
12
13
|
}
|
|
14
|
+
const walletOpenType =
|
|
15
|
+
typeof globalThis !== "undefined" ? (globalThis as any).walletOpenType : ""; // 用于判断是否是直接打开;
|
|
16
|
+
|
|
17
|
+
const walletOpenOrgin =
|
|
18
|
+
typeof globalThis !== "undefined" ? (globalThis as any).walletOpenOrgin : ""; // 用户传入的打开钱包的源;
|
|
13
19
|
|
|
14
|
-
|
|
15
|
-
let
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
20
|
+
|
|
21
|
+
let _baseUrl = "";
|
|
22
|
+
let _walletOrigin = "";
|
|
23
|
+
if (isProd) {
|
|
24
|
+
_baseUrl = "/v0_0_9";
|
|
25
|
+
_walletOrigin = "https://wallet.dcnetio.com";
|
|
26
|
+
if(walletOpenType === "iframe") {
|
|
27
|
+
_walletOrigin = walletOpenOrgin || "https://wallet.dcnetio.com";
|
|
28
|
+
}
|
|
19
29
|
} else {
|
|
20
|
-
|
|
21
|
-
|
|
30
|
+
_baseUrl = "";
|
|
31
|
+
_walletOrigin = "http://localhost:3000";
|
|
22
32
|
}
|
|
23
33
|
export const walletOrigin = _walletOrigin;
|
|
24
|
-
export const
|
|
34
|
+
export const walletUrl = _walletOrigin + _baseUrl; // 钱包地址后面统一改成origin+version
|
|
25
35
|
export const walletWindowName = "walletWindow"; // 窗口名称
|
|
26
36
|
export const dc_protocol = "/dc/thread/0.0.1";
|
|
27
37
|
export const dial_timeout = 1000;
|
|
@@ -29,23 +39,23 @@ export const keyExpire = 60 * 60 * 24; // setcachekey 过期时间默认一天
|
|
|
29
39
|
export const OffChainOpTimes = 2000; // 链下操作次数
|
|
30
40
|
export const OffChainSpaceLimit = 1024 * 1024 * 10; // 评论空间下限10m
|
|
31
41
|
export const OffChainOpTimesLimit = 100; // 链下操作次数下限
|
|
32
|
-
export enum Direction {
|
|
33
|
-
Forward = 0,
|
|
34
|
-
Reverse = 1
|
|
35
|
-
}
|
|
42
|
+
export enum Direction {
|
|
43
|
+
Forward = 0,
|
|
44
|
+
Reverse = 1,
|
|
45
|
+
}
|
|
36
46
|
export enum CommentType {
|
|
37
47
|
/** 普通评论 */
|
|
38
48
|
Comment = 0,
|
|
39
|
-
|
|
49
|
+
|
|
40
50
|
/** 赞 */
|
|
41
51
|
Up = 1,
|
|
42
|
-
|
|
52
|
+
|
|
43
53
|
/** 踩 */
|
|
44
54
|
Down = 2,
|
|
45
|
-
|
|
55
|
+
|
|
46
56
|
/** 推荐或转发 */
|
|
47
57
|
Transfer = 3,
|
|
48
|
-
|
|
58
|
+
|
|
49
59
|
/** keyvalue形式的数据 */
|
|
50
|
-
KeyValue = 4
|
|
51
|
-
}
|
|
60
|
+
KeyValue = 4,
|
|
61
|
+
}
|
|
@@ -114,8 +114,9 @@ async function handleIpfsRequest(
|
|
|
114
114
|
return;
|
|
115
115
|
}
|
|
116
116
|
} else {
|
|
117
|
+
const [fileContent, error] = await fileOps.getFile(ipfsPath, decryptKey);
|
|
118
|
+
fileData = fileContent;
|
|
117
119
|
// 普通文件请求
|
|
118
|
-
fileData = (await fileOps.getFile(ipfsPath, decryptKey)) ?? null;
|
|
119
120
|
fileSize = fileData ? fileData.length : 0;
|
|
120
121
|
// 非范围请求的文件读取完成后,清理缓存
|
|
121
122
|
fileOps.clearFileCache(pathname);
|
|
@@ -123,7 +123,7 @@ export interface AIProxyConfig {
|
|
|
123
123
|
apiType: number; // 当type 为0时起作用,表示模型的接口类型,如0:anthropic,1:openai 2:ollama 3:googleai 4:azureopenai
|
|
124
124
|
authorization: string;
|
|
125
125
|
endpoint: string;
|
|
126
|
-
organization: string; // 组织名称或ID
|
|
126
|
+
organization: string; // 组织名称或ID
|
|
127
127
|
apiVersion: string; // api版本号
|
|
128
128
|
modelConfig: ModelConfig; // 模型配置
|
|
129
129
|
remark: string;
|
|
@@ -191,6 +191,8 @@ export enum AIStreamResponseFlag {
|
|
|
191
191
|
/** Token数超限,需要继续请求 */
|
|
192
192
|
TOKEN_LIMIT_EXCEEDED = 5,
|
|
193
193
|
TOOLCALL = 6,
|
|
194
|
+
// 外部退出
|
|
195
|
+
EXTERNAL_EXIT = 7,
|
|
194
196
|
/** 卡住了 */
|
|
195
197
|
STREAM_HANG = 88,
|
|
196
198
|
/** 其他错误 */
|
|
@@ -226,6 +228,10 @@ export enum UploadStatus {
|
|
|
226
228
|
UPLOADING=2, // 上传中
|
|
227
229
|
ERROR=3,
|
|
228
230
|
ABNORMAL=4,
|
|
231
|
+
PULLERROR=5,
|
|
232
|
+
FILESIZEERROR=6, // 文件大小错误
|
|
233
|
+
FILECOUNTERROR=7, // 文件总数错误
|
|
234
|
+
NOSPACE=8, // 存储空间不足
|
|
229
235
|
};
|
|
230
236
|
|
|
231
237
|
export type ConnectReqMessage = {
|
package/lib/dc.ts
CHANGED
|
@@ -80,7 +80,7 @@ export class DC implements DCContext {
|
|
|
80
80
|
this.dcChain = new ChainUtil();
|
|
81
81
|
this.dcutil = new DcUtil(this.dcChain);
|
|
82
82
|
// //todo 发布注释 remove
|
|
83
|
-
|
|
83
|
+
// this.dcutil.defaultPeerId= "12D3KooWEGzh4AcbJrfZMfQb63wncBUpscMEEyiMemSWzEnjVCPf";
|
|
84
84
|
// //todo remove end
|
|
85
85
|
this.appInfo = options.appInfo || ({} as APPInfo);
|
|
86
86
|
|
|
@@ -205,7 +205,9 @@ export class DC implements DCContext {
|
|
|
205
205
|
backStep && (await backStep(3));
|
|
206
206
|
|
|
207
207
|
// 定时维系token
|
|
208
|
-
this.auth
|
|
208
|
+
if(this.auth){
|
|
209
|
+
this.auth.startDcPeerTokenKeepValidTask();
|
|
210
|
+
}
|
|
209
211
|
|
|
210
212
|
return true;
|
|
211
213
|
} catch (error) {
|
|
@@ -222,6 +224,7 @@ export class DC implements DCContext {
|
|
|
222
224
|
}
|
|
223
225
|
};
|
|
224
226
|
|
|
227
|
+
|
|
225
228
|
setAppInfo(appInfo: APPInfo): void {
|
|
226
229
|
this.appInfo = appInfo;
|
|
227
230
|
}
|
|
@@ -241,6 +244,9 @@ export class DC implements DCContext {
|
|
|
241
244
|
let userInfo: User | null = null;
|
|
242
245
|
try {
|
|
243
246
|
this.assertInitialized();
|
|
247
|
+
if(!this.auth) {
|
|
248
|
+
return [null, new Error("用户模块不存在")];
|
|
249
|
+
}
|
|
244
250
|
const [user, err] = await this.auth.refreshUserInfo();
|
|
245
251
|
if (err) {
|
|
246
252
|
return [null, err];
|
|
@@ -269,12 +275,41 @@ export class DC implements DCContext {
|
|
|
269
275
|
const fid = threadDBInfos[3] || ""; //预加载记录文件ID
|
|
270
276
|
const preCount = threadDBInfos[4] || 0; //预加载记录条数
|
|
271
277
|
//判断本地是否存在数据库
|
|
278
|
+
if(!this.db) {
|
|
279
|
+
return [null, new Error("数据库模块不存在")]
|
|
280
|
+
}
|
|
272
281
|
const [dbinfo, error] = await this.db.getDBInfo(threadid);
|
|
273
282
|
if (dbinfo != null && !error) {
|
|
283
|
+
//本地数据库存在,检查是否需要表结构升级
|
|
284
|
+
if (verno) {
|
|
285
|
+
//获取本地localVersion
|
|
286
|
+
const localVersion = await this.db.loadVerno(threadid);
|
|
287
|
+
if (localVersion != verno) {
|
|
288
|
+
//版本号不一致,需要升级表结构
|
|
289
|
+
const err = await this.db.upgradeCollections(
|
|
290
|
+
threadid,
|
|
291
|
+
collections
|
|
292
|
+
);
|
|
293
|
+
if (err) {
|
|
294
|
+
console.error("升级表结构失败", err);
|
|
295
|
+
return [null, err];
|
|
296
|
+
}
|
|
297
|
+
// 更新本地版本号
|
|
298
|
+
await this.db.saveVerno(threadid, verno);
|
|
299
|
+
}
|
|
300
|
+
// 需要升级表结构
|
|
301
|
+
await this.db.upgradeCollections(
|
|
302
|
+
threadid,
|
|
303
|
+
collections
|
|
304
|
+
);
|
|
305
|
+
}
|
|
306
|
+
|
|
274
307
|
this.db.refreshDBFromDC(threadid);
|
|
275
308
|
//3秒后将本地数据库同步到DC
|
|
276
309
|
setTimeout(() => {
|
|
277
|
-
this.db
|
|
310
|
+
if(this.db){
|
|
311
|
+
this.db.syncDBToDC(threadid);
|
|
312
|
+
}
|
|
278
313
|
}, 5000);
|
|
279
314
|
this.dbThreadId = dbinfo.id;
|
|
280
315
|
return [dbinfo, null];
|
|
@@ -304,6 +339,12 @@ export class DC implements DCContext {
|
|
|
304
339
|
return [null, error];
|
|
305
340
|
}
|
|
306
341
|
}
|
|
342
|
+
if(!this.util) {
|
|
343
|
+
return [null, new Error("util模块不存在")];
|
|
344
|
+
}
|
|
345
|
+
if(!this.db) {
|
|
346
|
+
return [null, new Error("数据库模块不存在")]
|
|
347
|
+
}
|
|
307
348
|
//数据库不存在,创建应用数据库
|
|
308
349
|
const rk = this.util.createSymmetricKey();
|
|
309
350
|
const sk = this.util.createSymmetricKey();
|
|
@@ -333,6 +374,9 @@ export class DC implements DCContext {
|
|
|
333
374
|
return [null, new Error("设置用户去中心DB失败")];
|
|
334
375
|
}
|
|
335
376
|
}
|
|
377
|
+
if(!this.db) {
|
|
378
|
+
return [null, new Error("数据库模块不存在")]
|
|
379
|
+
}
|
|
336
380
|
const [dbinfo, error] = await this.db.getDBInfo(threadId);
|
|
337
381
|
if (dbinfo != null && !error) {
|
|
338
382
|
this.dbThreadId = dbinfo.id;
|
|
@@ -359,6 +403,9 @@ export class DC implements DCContext {
|
|
|
359
403
|
): Promise<boolean> {
|
|
360
404
|
// 加到用户信息上
|
|
361
405
|
try {
|
|
406
|
+
if(!dc.auth) {
|
|
407
|
+
return false;
|
|
408
|
+
}
|
|
362
409
|
await dc.auth.setUserDefaultDB(DBthreadid, rk, sk, remark || "");
|
|
363
410
|
} catch (error) {
|
|
364
411
|
console.error("设置用户默认DB失败", error);
|
|
@@ -376,19 +423,22 @@ export class DC implements DCContext {
|
|
|
376
423
|
// 初始化定时器
|
|
377
424
|
let interval = setInterval(async () => {
|
|
378
425
|
intervalNum++;
|
|
379
|
-
|
|
380
|
-
const [user, err] = await dc.auth.refreshUserInfo();
|
|
381
|
-
if (!err && user && user.dbConfig) {
|
|
382
|
-
// 绑定成功停止定时任务
|
|
383
|
-
interval ? clearInterval(interval) : "";
|
|
384
|
-
intervalNum = 0;
|
|
385
|
-
resolve(true);
|
|
386
|
-
} else if (intervalNum > 20) {
|
|
426
|
+
if (intervalNum > 20) {
|
|
387
427
|
// 超时停止定时任务
|
|
388
428
|
interval ? clearInterval(interval) : "";
|
|
389
429
|
intervalNum = 0;
|
|
390
430
|
resolve(false);
|
|
391
431
|
}
|
|
432
|
+
// 获取用户信息,判断空间有效期是否延长
|
|
433
|
+
if(dc.auth){
|
|
434
|
+
const [user, err] = await dc.auth.refreshUserInfo();
|
|
435
|
+
if (!err && user && user.dbConfig) {
|
|
436
|
+
// 绑定成功停止定时任务
|
|
437
|
+
interval ? clearInterval(interval) : "";
|
|
438
|
+
intervalNum = 0;
|
|
439
|
+
resolve(true);
|
|
440
|
+
}
|
|
441
|
+
}
|
|
392
442
|
}, 1000);
|
|
393
443
|
});
|
|
394
444
|
}
|
|
@@ -440,6 +490,9 @@ export class DC implements DCContext {
|
|
|
440
490
|
* @returns 签名结果
|
|
441
491
|
*/
|
|
442
492
|
sign = async (payload: Uint8Array): Promise<Uint8Array> => {
|
|
493
|
+
if (!this.auth) {
|
|
494
|
+
return new Uint8Array();
|
|
495
|
+
}
|
|
443
496
|
const signature = this.auth.signWithWallet(payload);
|
|
444
497
|
return signature;
|
|
445
498
|
};
|
|
@@ -513,13 +566,17 @@ export class DC implements DCContext {
|
|
|
513
566
|
* @param moduleName 模块名称
|
|
514
567
|
* @returns 模块实例
|
|
515
568
|
*/
|
|
516
|
-
getModule<T extends DCModule>(moduleName: string): T {
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
569
|
+
getModule<T extends DCModule>(moduleName: string): T | null {
|
|
570
|
+
try {
|
|
571
|
+
this.assertInitialized();
|
|
572
|
+
const module = this.moduleSystem.getModule<T>(moduleName);
|
|
573
|
+
if (!module) {
|
|
574
|
+
throw new Error(`模块 ${moduleName} 不存在或未注册`);
|
|
575
|
+
}
|
|
576
|
+
return module;
|
|
577
|
+
} catch (error) {
|
|
578
|
+
return null;
|
|
521
579
|
}
|
|
522
|
-
return module;
|
|
523
580
|
}
|
|
524
581
|
|
|
525
582
|
/**
|
|
@@ -220,7 +220,7 @@ export class AIProxyClient {
|
|
|
220
220
|
onStreamResponse(AIStreamResponseFlag.STREAM_HANG, "", "数据流超时:超过30秒未收到响应数据");
|
|
221
221
|
}
|
|
222
222
|
}
|
|
223
|
-
},
|
|
223
|
+
}, 60000); // 60秒超时
|
|
224
224
|
};
|
|
225
225
|
|
|
226
226
|
// 检查是否已经被中止
|
|
@@ -244,6 +244,11 @@ export class AIProxyClient {
|
|
|
244
244
|
|
|
245
245
|
try {
|
|
246
246
|
const decodedPayload = dcnet.pb.DoAIProxyCallReply.decode(payload);
|
|
247
|
+
if (decodedPayload.flag == AIStreamResponseFlag.CONNECTION_CLOSED) {
|
|
248
|
+
isCompleted = true; // 如果不是流式响应,标记为完成
|
|
249
|
+
clearTimeoutTimer();
|
|
250
|
+
console.log('*********** CONNECTION_CLOSED ***********222');
|
|
251
|
+
}
|
|
247
252
|
if (onStreamResponse) {
|
|
248
253
|
onStreamResponse(
|
|
249
254
|
decodedPayload.flag,
|
|
@@ -260,22 +265,20 @@ export class AIProxyClient {
|
|
|
260
265
|
};
|
|
261
266
|
|
|
262
267
|
const onEndCallback = async () => {
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
+
clearTimeoutTimer();
|
|
269
|
+
if (isAborted || checkAborted() || isCompleted) return;
|
|
270
|
+
console.log('*********** onEndCallback ***********1111');
|
|
271
|
+
isCompleted = true;
|
|
268
272
|
if (onStreamResponse) {
|
|
269
273
|
onStreamResponse(AIStreamResponseFlag.CONNECTION_CLOSED, "", "");
|
|
270
274
|
}
|
|
271
275
|
};
|
|
272
276
|
|
|
273
277
|
const onErrorCallback = async (error: unknown) => {
|
|
274
|
-
if (isAborted || checkAborted()) return;
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
278
|
+
if (isAborted || checkAborted() || isCompleted) return;
|
|
279
|
+
//不要标记完成,和清理定时器,统一由onEndCallback处理
|
|
280
|
+
// isCompleted = true; //
|
|
281
|
+
// clearTimeoutTimer();
|
|
279
282
|
if (onStreamResponse) {
|
|
280
283
|
onStreamResponse(AIStreamResponseFlag.OTHER_ERROR, "", error instanceof Error ? error.message : String(error));
|
|
281
284
|
}
|
|
@@ -289,7 +292,7 @@ export class AIProxyClient {
|
|
|
289
292
|
isAborted = true;
|
|
290
293
|
clearTimeoutTimer();
|
|
291
294
|
console.log('DoAIProxyCall 调用前已被中止');
|
|
292
|
-
return AIStreamResponseFlag.
|
|
295
|
+
return AIStreamResponseFlag.EXTERNAL_EXIT;
|
|
293
296
|
}
|
|
294
297
|
|
|
295
298
|
abortListener = () => {
|
|
@@ -299,7 +302,7 @@ export class AIProxyClient {
|
|
|
299
302
|
|
|
300
303
|
// 通知调用者已被中止
|
|
301
304
|
if (onStreamResponse) {
|
|
302
|
-
onStreamResponse(AIStreamResponseFlag.
|
|
305
|
+
onStreamResponse(AIStreamResponseFlag.EXTERNAL_EXIT, "", "调用被用户中止");
|
|
303
306
|
}
|
|
304
307
|
};
|
|
305
308
|
|
|
@@ -337,7 +340,7 @@ export class AIProxyClient {
|
|
|
337
340
|
|
|
338
341
|
// 检查是否是中止导致的错误
|
|
339
342
|
if (context.signal?.aborted) {
|
|
340
|
-
return AIStreamResponseFlag.
|
|
343
|
+
return AIStreamResponseFlag.EXTERNAL_EXIT;
|
|
341
344
|
}
|
|
342
345
|
|
|
343
346
|
throw error;
|
|
@@ -349,6 +352,7 @@ export class AIProxyClient {
|
|
|
349
352
|
if (abortListener && context.signal) {
|
|
350
353
|
context.signal.removeEventListener('abort', abortListener);
|
|
351
354
|
}
|
|
355
|
+
// 无需关闭 gRPC 客户端连接,因为 Libp2pGrpcClient 没有 close 方法
|
|
352
356
|
}
|
|
353
357
|
}
|
|
354
358
|
}
|
|
@@ -83,7 +83,7 @@ export class FileClient {
|
|
|
83
83
|
resStatus = UploadStatus.UPLOADING;
|
|
84
84
|
break;
|
|
85
85
|
case uploadRespondStatus.PullFail:
|
|
86
|
-
resStatus = UploadStatus.
|
|
86
|
+
resStatus = UploadStatus.PULLERROR;
|
|
87
87
|
break;
|
|
88
88
|
case uploadRespondStatus.PullSuccess:
|
|
89
89
|
resStatus = UploadStatus.OK;
|
|
@@ -95,13 +95,13 @@ export class FileClient {
|
|
|
95
95
|
resStatus = UploadStatus.ABNORMAL;
|
|
96
96
|
break;
|
|
97
97
|
case uploadRespondStatus.FaultSize:
|
|
98
|
-
resStatus = UploadStatus.
|
|
98
|
+
resStatus = UploadStatus.FILESIZEERROR;
|
|
99
99
|
break;
|
|
100
100
|
case uploadRespondStatus.FaultCount:
|
|
101
|
-
resStatus = UploadStatus.
|
|
101
|
+
resStatus = UploadStatus.FILECOUNTERROR;
|
|
102
102
|
break;
|
|
103
103
|
case uploadRespondStatus.NoUserSpace:
|
|
104
|
-
resStatus = UploadStatus.
|
|
104
|
+
resStatus = UploadStatus.NOSPACE;
|
|
105
105
|
break;
|
|
106
106
|
}
|
|
107
107
|
if(onUpdateTransmitSize ) {
|
|
@@ -194,7 +194,7 @@ async storeFolder(
|
|
|
194
194
|
resStatus = UploadStatus.UPLOADING;
|
|
195
195
|
break;
|
|
196
196
|
case uploadRespondStatus.PullFail:
|
|
197
|
-
resStatus = UploadStatus.
|
|
197
|
+
resStatus = UploadStatus.PULLERROR;
|
|
198
198
|
break;
|
|
199
199
|
case uploadRespondStatus.PullSuccess:
|
|
200
200
|
resStatus = UploadStatus.OK;
|
|
@@ -206,13 +206,13 @@ async storeFolder(
|
|
|
206
206
|
resStatus = UploadStatus.ABNORMAL;
|
|
207
207
|
break;
|
|
208
208
|
case uploadRespondStatus.FaultSize:
|
|
209
|
-
resStatus = UploadStatus.
|
|
209
|
+
resStatus = UploadStatus.FILESIZEERROR;
|
|
210
210
|
break;
|
|
211
211
|
case uploadRespondStatus.FaultCount:
|
|
212
|
-
resStatus = UploadStatus.
|
|
212
|
+
resStatus = UploadStatus.FILECOUNTERROR;
|
|
213
213
|
break;
|
|
214
214
|
case uploadRespondStatus.NoUserSpace:
|
|
215
|
-
resStatus = UploadStatus.
|
|
215
|
+
resStatus = UploadStatus.NOSPACE;
|
|
216
216
|
break;
|
|
217
217
|
}
|
|
218
218
|
if (updateTransmitCount !== null) {
|
|
@@ -302,7 +302,9 @@ export class FileManager {
|
|
|
302
302
|
if (resError) {
|
|
303
303
|
return [null, resError];
|
|
304
304
|
}
|
|
305
|
-
if (resStatus === UploadStatus.ERROR || resStatus === UploadStatus.ABNORMAL
|
|
305
|
+
if (resStatus === UploadStatus.ERROR || resStatus === UploadStatus.ABNORMAL
|
|
306
|
+
|| resStatus === UploadStatus.NOSPACE || resStatus === UploadStatus.FILECOUNTERROR
|
|
307
|
+
|| resStatus === UploadStatus.FILESIZEERROR || resStatus === UploadStatus.PULLERROR) {
|
|
306
308
|
//上传失败,不需要操作
|
|
307
309
|
return [null, Errors.ErrNoNeedUpload];
|
|
308
310
|
}
|
|
@@ -520,7 +522,9 @@ export class FileManager {
|
|
|
520
522
|
updateTransmitCount(UploadStatus.ERROR, 0, 0);
|
|
521
523
|
return [null, resError];
|
|
522
524
|
}
|
|
523
|
-
if (resStatus === UploadStatus.ERROR || resStatus === UploadStatus.ABNORMAL
|
|
525
|
+
if (resStatus === UploadStatus.ERROR || resStatus === UploadStatus.ABNORMAL
|
|
526
|
+
|| resStatus === UploadStatus.NOSPACE || resStatus === UploadStatus.FILECOUNTERROR
|
|
527
|
+
|| resStatus === UploadStatus.FILESIZEERROR || resStatus === UploadStatus.PULLERROR) {
|
|
524
528
|
//上传失败的时候,不需要操作
|
|
525
529
|
return [null, Errors.ErrNoNeedUpload];
|
|
526
530
|
}
|
|
@@ -129,9 +129,9 @@ export interface MetadataKey {
|
|
|
129
129
|
|
|
130
130
|
export interface DumpMetadata {
|
|
131
131
|
data: {
|
|
132
|
-
int64: Record<string, number
|
|
133
|
-
bool: Record<string, boolean
|
|
134
|
-
string: Record<string, string
|
|
135
|
-
bytes: Record<string, Uint8Array
|
|
132
|
+
int64: Record<string, Record<string, number>>;
|
|
133
|
+
bool: Record<string, Record<string, boolean>>;
|
|
134
|
+
string: Record<string, Record<string, string>>;
|
|
135
|
+
bytes: Record<string, Record<string, Uint8Array>>;
|
|
136
136
|
};
|
|
137
137
|
}
|
|
@@ -46,10 +46,10 @@ export class DsThreadMetadata implements IThreadMetadata {
|
|
|
46
46
|
try {
|
|
47
47
|
const value = await this.ds.get(k)
|
|
48
48
|
return value
|
|
49
|
-
} catch (err) {
|
|
50
|
-
if (err.code === 'ERR_NOT_FOUND') return null
|
|
51
|
-
throw new Error(`Error getting metadata: ${err.message}`)
|
|
52
|
-
}
|
|
49
|
+
} catch (err:any) {
|
|
50
|
+
if (err.code === 'ERR_NOT_FOUND') return null
|
|
51
|
+
throw new Error(`Error getting metadata: ${err.message}`)
|
|
52
|
+
}
|
|
53
53
|
}
|
|
54
54
|
|
|
55
55
|
|
|
@@ -57,7 +57,7 @@ export class DsThreadMetadata implements IThreadMetadata {
|
|
|
57
57
|
const k = this.keyMeta(t, key)
|
|
58
58
|
try {
|
|
59
59
|
await this.ds.put(k, val)
|
|
60
|
-
} catch (err) {
|
|
60
|
+
} catch (err:any) {
|
|
61
61
|
throw new Error(`Error setting metadata: ${err.message}`)
|
|
62
62
|
}
|
|
63
63
|
}
|
|
@@ -73,7 +73,7 @@ export class DsThreadMetadata implements IThreadMetadata {
|
|
|
73
73
|
const value = await this.ds.get(k)
|
|
74
74
|
// For Uint8Array we'll handle it in getBytes method
|
|
75
75
|
return this.decodeValue<T>(value)
|
|
76
|
-
} catch (err) {
|
|
76
|
+
} catch (err:any) {
|
|
77
77
|
if (err.code === 'ERR_NOT_FOUND') return null
|
|
78
78
|
throw new Error(`Error getting metadata: ${err.message}`)
|
|
79
79
|
}
|
|
@@ -84,7 +84,7 @@ export class DsThreadMetadata implements IThreadMetadata {
|
|
|
84
84
|
const value = this.encodeValue(val)
|
|
85
85
|
try {
|
|
86
86
|
await this.ds.put(k, value)
|
|
87
|
-
} catch (err) {
|
|
87
|
+
} catch (err:any) {
|
|
88
88
|
throw new Error(`Error setting metadata: ${err.message}`)
|
|
89
89
|
}
|
|
90
90
|
}
|
|
@@ -112,13 +112,13 @@ export class DsThreadMetadata implements IThreadMetadata {
|
|
|
112
112
|
throw new Error(`Bad metabook key: ${entry.key}`)
|
|
113
113
|
}
|
|
114
114
|
const [,, ts, key] = kns
|
|
115
|
-
const tid = this.parseThreadID(ts)
|
|
116
|
-
const mk: MetadataKey = { t: tid, k: key }
|
|
115
|
+
const tid = this.parseThreadID(ts!)
|
|
116
|
+
const mk: MetadataKey = { t: tid, k: key! }
|
|
117
117
|
|
|
118
118
|
const value = await this.decodeAnyValue(entry.value)
|
|
119
119
|
this.storeDecodedValue(dump, mk, value)
|
|
120
120
|
}
|
|
121
|
-
} catch (err) {
|
|
121
|
+
} catch (err:any) {
|
|
122
122
|
throw new Error(`Error dumping metadata: ${err.message}`)
|
|
123
123
|
}
|
|
124
124
|
return dump
|
|
@@ -152,7 +152,7 @@ export class DsThreadMetadata implements IThreadMetadata {
|
|
|
152
152
|
for await (const key of results) {
|
|
153
153
|
await this.ds.delete(key)
|
|
154
154
|
}
|
|
155
|
-
} catch (err) {
|
|
155
|
+
} catch (err:any) {
|
|
156
156
|
throw new Error(`Error clearing keys: ${err.message}`)
|
|
157
157
|
}
|
|
158
158
|
}
|
|
@@ -161,7 +161,7 @@ export class DsThreadMetadata implements IThreadMetadata {
|
|
|
161
161
|
try {
|
|
162
162
|
const decoder = new TextDecoder()
|
|
163
163
|
return JSON.parse(decoder.decode(buf)) as T
|
|
164
|
-
} catch (err) {
|
|
164
|
+
} catch (err:any) {
|
|
165
165
|
throw new Error(`Value decoding failed: ${err.message}`)
|
|
166
166
|
}
|
|
167
167
|
}
|
|
@@ -170,7 +170,7 @@ export class DsThreadMetadata implements IThreadMetadata {
|
|
|
170
170
|
try {
|
|
171
171
|
const encoder = new TextEncoder()
|
|
172
172
|
return encoder.encode(JSON.stringify(val))
|
|
173
|
-
} catch (err) {
|
|
173
|
+
} catch (err:any) {
|
|
174
174
|
throw new Error(`Value encoding failed: ${err.message}`)
|
|
175
175
|
}
|
|
176
176
|
}
|
|
@@ -178,7 +178,7 @@ export class DsThreadMetadata implements IThreadMetadata {
|
|
|
178
178
|
private parseThreadID(ts: string): ThreadID {
|
|
179
179
|
try {
|
|
180
180
|
return ThreadID.fromString(ts)
|
|
181
|
-
} catch (err) {
|
|
181
|
+
} catch (err:any) {
|
|
182
182
|
throw new Error(`Invalid thread ID: ${ts}`)
|
|
183
183
|
}
|
|
184
184
|
}
|
|
@@ -190,21 +190,22 @@ export class DsThreadMetadata implements IThreadMetadata {
|
|
|
190
190
|
) {
|
|
191
191
|
switch (typeof value) {
|
|
192
192
|
case 'boolean':
|
|
193
|
-
dump.data.bool[mk.t.toString()] = dump.data.bool[mk.t.toString()] ||
|
|
194
|
-
dump.data.bool[mk.t.toString()][mk.k] = value;
|
|
193
|
+
dump.data.bool[mk.t.toString()] = dump.data.bool[mk.t.toString()] || {};
|
|
194
|
+
dump.data.bool[mk.t.toString()]![mk.k] = value;
|
|
195
195
|
break
|
|
196
196
|
case 'number':
|
|
197
|
-
dump.data.int64[mk.t.toString()] = dump.data.int64[mk.t.toString()] ||
|
|
198
|
-
dump.data.int64[mk.t.toString()][mk.k] = value;
|
|
197
|
+
dump.data.int64[mk.t.toString()] = dump.data.int64[mk.t.toString()] || {};
|
|
198
|
+
dump.data.int64[mk.t.toString()]![mk.k] = value;
|
|
199
199
|
break
|
|
200
200
|
case 'string':
|
|
201
|
-
dump.data.string[mk.t.toString()] = dump.data.string[mk.t.toString()] ||
|
|
202
|
-
dump.data.string[mk.t.toString()][mk.k] = value;
|
|
201
|
+
dump.data.string[mk.t.toString()] = dump.data.string[mk.t.toString()] || {};
|
|
202
|
+
dump.data.string[mk.t.toString()]![mk.k] = value;
|
|
203
203
|
break
|
|
204
204
|
default:
|
|
205
205
|
if (value instanceof Uint8Array) {
|
|
206
|
-
|
|
207
|
-
dump.data.bytes[mk.t.toString()][mk.
|
|
206
|
+
// dump.data.bytes[mk.t.toString()] = dump.data.bytes[mk.t.toString()] || '';
|
|
207
|
+
dump.data.bytes[mk.t.toString()] = dump.data.bytes[mk.t.toString()] || {};
|
|
208
|
+
dump.data.bytes[mk.t.toString()]![mk.k] = value;
|
|
208
209
|
} else {
|
|
209
210
|
throw new Error(`Unsupported value type for key: ${mk.k}`)
|
|
210
211
|
}
|