web-dc-api 0.0.47 → 0.0.49
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 +7 -1
- package/dist/index.d.ts +33 -2
- package/dist/index.esm.js +7 -1
- package/lib/common/chain.ts +6 -5
- package/lib/common/dcutil.ts +4 -4
- package/lib/common/define.ts +1 -1
- package/lib/common/service-worker.ts +1 -1
- package/lib/common/types/types.ts +10 -0
- package/lib/dc.ts +1 -1
- package/lib/implements/threaddb/dbmanager.ts +28 -1
- package/lib/implements/threaddb/net/net.ts +144 -85
- package/lib/interfaces/util-interface.ts +13 -0
- package/lib/modules/util-module.ts +24 -1
- package/package.json +13 -11
package/lib/common/chain.ts
CHANGED
|
@@ -6,7 +6,7 @@ import { Multiaddr, multiaddr } from "@multiformats/multiaddr";
|
|
|
6
6
|
import { ApiPromise, WsProvider } from "@polkadot/api";
|
|
7
7
|
|
|
8
8
|
import { isUser, sha256,hexToAscii } from "../util/utils";
|
|
9
|
-
import { IAppInfo, User } from "./types/types";
|
|
9
|
+
import { IAppInfo, User,PeerStatus } from "./types/types";
|
|
10
10
|
|
|
11
11
|
import { hexToBytes } from "@noble/curves/abstract/utils";
|
|
12
12
|
import { base32 } from "multiformats/bases/base32";
|
|
@@ -263,7 +263,7 @@ export class ChainUtil {
|
|
|
263
263
|
// 链上查询节点webrtc direct的地址信息,
|
|
264
264
|
// peerid: 节点的peerid
|
|
265
265
|
// 直接连接节点的地址
|
|
266
|
-
getDcNodeWebrtcDirectAddr = async (peerid: string): Promise<Multiaddr | null> => {
|
|
266
|
+
getDcNodeWebrtcDirectAddr = async (peerid: string): Promise<[Multiaddr | null, PeerStatus]> => {
|
|
267
267
|
const peerInfo = await (this.dcchainapi?.query as any).dcNode.peers(peerid);
|
|
268
268
|
const peerInfoJson = peerInfo?.toJSON();
|
|
269
269
|
if (
|
|
@@ -272,7 +272,7 @@ export class ChainUtil {
|
|
|
272
272
|
(peerInfoJson as { ipAddress: string }).ipAddress == ""
|
|
273
273
|
) {
|
|
274
274
|
console.error("no ip address found for peer: ", peerid);
|
|
275
|
-
return null;
|
|
275
|
+
return [null, PeerStatus.PeerStatusOffline];
|
|
276
276
|
}
|
|
277
277
|
let nodeAddr = Buffer.from(
|
|
278
278
|
(peerInfoJson as { ipAddress: string }).ipAddress.slice(2),
|
|
@@ -280,10 +280,11 @@ export class ChainUtil {
|
|
|
280
280
|
).toString("utf8");
|
|
281
281
|
let addrParts = nodeAddr.split(",");
|
|
282
282
|
if (addrParts.length < 2) {
|
|
283
|
-
return null;
|
|
283
|
+
return [null, PeerStatus.PeerStatusOffline];
|
|
284
284
|
}
|
|
285
285
|
const addr = multiaddr(addrParts[1]);
|
|
286
|
-
|
|
286
|
+
const peerStatus = (peerInfoJson as { status: number }).status || PeerStatus.PeerStatusOffline;
|
|
287
|
+
return [addr, peerStatus];
|
|
287
288
|
};
|
|
288
289
|
|
|
289
290
|
// 链上查询节点列表
|
package/lib/common/dcutil.ts
CHANGED
|
@@ -92,7 +92,7 @@ export class DcUtil {
|
|
|
92
92
|
if (!peerListJson[i]) {
|
|
93
93
|
return;
|
|
94
94
|
}
|
|
95
|
-
const nodeAddr = await _this.dcChain.getDcNodeWebrtcDirectAddr(
|
|
95
|
+
const [nodeAddr,_] = await _this.dcChain.getDcNodeWebrtcDirectAddr(
|
|
96
96
|
peerListJson[i]
|
|
97
97
|
);
|
|
98
98
|
if (!nodeAddr) {
|
|
@@ -343,16 +343,16 @@ export class DcUtil {
|
|
|
343
343
|
}
|
|
344
344
|
};
|
|
345
345
|
_getNodeAddr = async (peerId: string): Promise<Multiaddr | undefined> => {
|
|
346
|
-
let nodeAddr = await this.dcChain.getDcNodeWebrtcDirectAddr(peerId)
|
|
346
|
+
let [nodeAddr, _] = await this.dcChain.getDcNodeWebrtcDirectAddr(peerId);
|
|
347
347
|
if (!nodeAddr) {
|
|
348
348
|
console.error("no node address found for peer: ", peerId);
|
|
349
349
|
return;
|
|
350
350
|
}
|
|
351
351
|
if (isName(nodeAddr)) {
|
|
352
352
|
const addrs = await nodeAddr.resolve();
|
|
353
|
-
nodeAddr = addrs[0] ;
|
|
353
|
+
nodeAddr = addrs[0] ? addrs[0] : null;
|
|
354
354
|
}
|
|
355
|
-
return nodeAddr;
|
|
355
|
+
return nodeAddr ? nodeAddr : undefined;
|
|
356
356
|
};
|
|
357
357
|
|
|
358
358
|
getDefaultDcNodeAddr = async (): Promise<Multiaddr | undefined> => {
|
package/lib/common/define.ts
CHANGED
|
@@ -68,7 +68,7 @@ export async function registerServiceWorker(fileOps?: IFileOperations, swUrl: st
|
|
|
68
68
|
* @param port 消息端口
|
|
69
69
|
* @param fileOps 文件操作对象
|
|
70
70
|
*/
|
|
71
|
-
async function handleIpfsRequest(
|
|
71
|
+
export async function handleIpfsRequest(
|
|
72
72
|
data: { id: string, pathname: string, range?: string },
|
|
73
73
|
port: MessagePort,
|
|
74
74
|
fileOps?: IFileOperations
|
|
@@ -235,6 +235,16 @@ export enum UploadStatus {
|
|
|
235
235
|
NOSPACE=8, // 存储空间不足
|
|
236
236
|
};
|
|
237
237
|
|
|
238
|
+
export enum PeerStatus {
|
|
239
|
+
PeerStatusOffline = 1,
|
|
240
|
+
PeerStatusJoining = 2, //Joining the network
|
|
241
|
+
PeerStatusOnline = 3,
|
|
242
|
+
PeerStatusStaked = 4,
|
|
243
|
+
PeerStatusErr = 5,
|
|
244
|
+
PeerStatusClose = 6,
|
|
245
|
+
PeerStatusDiscard = 7
|
|
246
|
+
}
|
|
247
|
+
|
|
238
248
|
export type SignReqMessageData = {
|
|
239
249
|
appUrl: string,
|
|
240
250
|
ethAccount: string,
|
package/lib/dc.ts
CHANGED
|
@@ -82,7 +82,7 @@ export class DC implements DCContext {
|
|
|
82
82
|
this.dcChain = new ChainUtil();
|
|
83
83
|
this.dcutil = new DcUtil(this.dcChain);
|
|
84
84
|
// //todo 发布注释 remove
|
|
85
|
-
|
|
85
|
+
// this.dcutil.defaultPeerId= "12D3KooWEGzh4AcbJrfZMfQb63wncBUpscMEEyiMemSWzEnjVCPf";
|
|
86
86
|
// //todo remove end
|
|
87
87
|
this.appInfo = options.appInfo || ({} as APPInfo);
|
|
88
88
|
this.accountInfo = {} as AccountInfo;
|
|
@@ -1516,7 +1516,21 @@ async create(threadId: string, collectionName: string, jsonInstance: string): P
|
|
|
1516
1516
|
// if (jsonInstance.length > 100 * 1024) { // 100 KB
|
|
1517
1517
|
// throw new Error("instance too big");
|
|
1518
1518
|
// }
|
|
1519
|
+
|
|
1520
|
+
// 判断instance里面是否有_mod字段,存在则删除
|
|
1521
|
+
try {
|
|
1522
|
+
const instanceObj = JSON.parse(jsonInstance);
|
|
1523
|
+
if (instanceObj && typeof instanceObj === 'object' && '_mod' in instanceObj) {
|
|
1524
|
+
delete instanceObj._mod;
|
|
1525
|
+
jsonInstance = JSON.stringify(instanceObj);
|
|
1526
|
+
}
|
|
1527
|
+
} catch (err) {
|
|
1528
|
+
// JSON解析失败,保持原字符串不变
|
|
1529
|
+
console.warn('Failed to parse instance JSON, keeping original:', err);
|
|
1530
|
+
throw new Error("Invalid instance JSON format");
|
|
1531
|
+
}
|
|
1519
1532
|
try {
|
|
1533
|
+
|
|
1520
1534
|
// 解码threaddbID
|
|
1521
1535
|
const tID = ThreadID.fromString(threadId);
|
|
1522
1536
|
|
|
@@ -1587,7 +1601,20 @@ async save(threadId: string, collectionName: string, instance: string): Promise<
|
|
|
1587
1601
|
// 解码线程ID
|
|
1588
1602
|
const tID = ThreadID.fromString(threadId);
|
|
1589
1603
|
|
|
1590
|
-
|
|
1604
|
+
// 判断instance里面是否有_mod字段,存在则删除
|
|
1605
|
+
try {
|
|
1606
|
+
const instanceObj = JSON.parse(instance);
|
|
1607
|
+
if (instanceObj && typeof instanceObj === 'object' && '_mod' in instanceObj) {
|
|
1608
|
+
delete instanceObj._mod;
|
|
1609
|
+
instance = JSON.stringify(instanceObj);
|
|
1610
|
+
}
|
|
1611
|
+
} catch (err) {
|
|
1612
|
+
// JSON解析失败,保持原字符串不变
|
|
1613
|
+
console.warn('Failed to parse instance JSON, keeping original:', err);
|
|
1614
|
+
throw new Error("Invalid instance JSON format");
|
|
1615
|
+
}
|
|
1616
|
+
|
|
1617
|
+
|
|
1591
1618
|
|
|
1592
1619
|
// 获取线程数据库
|
|
1593
1620
|
const threadDB = await this.getDB(tID);
|
|
@@ -38,6 +38,7 @@ import {CreateEvent} from '../cbor/event';
|
|
|
38
38
|
import {Errors} from '../core/db';
|
|
39
39
|
import {net as net_pb} from "../pb/net_pb";
|
|
40
40
|
import {PermanentAddrTTL} from "../common/logstore";
|
|
41
|
+
import {PeerStatus} from '../../../common/types/types';
|
|
41
42
|
import {
|
|
42
43
|
PeerIDConverter,
|
|
43
44
|
MultiaddrConverter,
|
|
@@ -101,50 +102,58 @@ export class Network implements Net {
|
|
|
101
102
|
return signature;
|
|
102
103
|
}
|
|
103
104
|
|
|
104
|
-
async getClient(peerId: PeerId):Promise<Client>{
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
105
|
+
async getClient(peerId: PeerId):Promise<[Client | null, Error | null]>{
|
|
106
|
+
try{
|
|
107
|
+
let cachedFlag = true;
|
|
108
|
+
const cacheAddr = this.cachePeers[peerId.toString()];
|
|
109
|
+
let peerAddr: TMultiaddr | null = cacheAddr || null;
|
|
110
|
+
let peerStatus: PeerStatus | null = null;
|
|
111
|
+
if (!cacheAddr) {
|
|
112
|
+
cachedFlag = false;
|
|
113
|
+
[peerAddr, peerStatus] = await this.dcChain.getDcNodeWebrtcDirectAddr(peerId.toString());
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
if (!peerAddr) {
|
|
117
|
+
throw new Error("peerAddr is null");
|
|
118
|
+
}
|
|
119
|
+
if (peerStatus !== PeerStatus.PeerStatusOnline) {
|
|
120
|
+
throw new Error("peerStatus is not online");
|
|
121
|
+
}
|
|
122
|
+
if (!this.context.publicKey){
|
|
123
|
+
throw new Error("publicKey is null");
|
|
124
|
+
}
|
|
119
125
|
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
126
|
+
const addr = multiaddr(peerAddr);
|
|
127
|
+
const client = new Client(this.libp2p,this.bstore,addr, dc_protocol);
|
|
128
|
+
//获取token
|
|
129
|
+
const token = await client.GetToken(this.context.appInfo.appId||"", this.context.publicKey.string(),(payload: Uint8Array):Promise<Uint8Array> => {
|
|
130
|
+
return this.sign(payload);
|
|
131
|
+
});
|
|
132
|
+
if (!token) {
|
|
133
|
+
if (cachedFlag) {
|
|
134
|
+
[peerAddr,_] = await this.dcChain.getDcNodeWebrtcDirectAddr(peerId.toString());
|
|
135
|
+
delete this.cachePeers[peerId.toString()];
|
|
136
|
+
if (!peerAddr) {
|
|
137
|
+
throw new Error("peerAddr is null");
|
|
138
|
+
}
|
|
139
|
+
const addr = multiaddr(peerAddr);
|
|
140
|
+
const client = new Client(this.libp2p,this.bstore,addr, dc_protocol);
|
|
141
|
+
const token = await client.GetToken(this.context.appInfo.appId||"",this.context.publicKey.string(),(payload: Uint8Array) => {
|
|
142
|
+
return this.sign(payload);
|
|
143
|
+
});
|
|
144
|
+
if (token) {
|
|
145
|
+
this.cachePeers[peerId.toString()] = peerAddr;
|
|
146
|
+
return [client, null];
|
|
147
|
+
}
|
|
141
148
|
}
|
|
149
|
+
throw new Error("get token is null");
|
|
150
|
+
|
|
142
151
|
}
|
|
143
|
-
|
|
144
|
-
|
|
152
|
+
this.cachePeers[peerId.toString()] = peerAddr;
|
|
153
|
+
return [client, null];
|
|
154
|
+
}catch(err){
|
|
155
|
+
return [null,err as Error];
|
|
145
156
|
}
|
|
146
|
-
this.cachePeers[peerId.toString()] = peerAddr;
|
|
147
|
-
return client;
|
|
148
157
|
}
|
|
149
158
|
|
|
150
159
|
|
|
@@ -315,7 +324,7 @@ async getThreadFromPeer(
|
|
|
315
324
|
options: { token?: ThreadToken } = {}
|
|
316
325
|
): Promise<ThreadInfo> {
|
|
317
326
|
try {
|
|
318
|
-
const client = await this.getClient(peerId);
|
|
327
|
+
const [client, _] = await this.getClient(peerId);
|
|
319
328
|
if (!client) {
|
|
320
329
|
throw new Error("Failed to get client");
|
|
321
330
|
}
|
|
@@ -484,10 +493,14 @@ async ensureUniqueLog(id: ThreadID, key?: Ed25519PrivKey | Ed25519PubKey, identi
|
|
|
484
493
|
*/
|
|
485
494
|
async pullThread(id: ThreadID): Promise<void> {
|
|
486
495
|
try {
|
|
496
|
+
let recs: Record<string, PeerRecords> = {};
|
|
487
497
|
const mutex = this.getMutexForThread(id.toString());
|
|
488
498
|
await mutex.acquire();
|
|
489
|
-
|
|
490
|
-
|
|
499
|
+
try {
|
|
500
|
+
recs = await this.pullThreadDeal(id);
|
|
501
|
+
} finally {
|
|
502
|
+
mutex.release();
|
|
503
|
+
}
|
|
491
504
|
|
|
492
505
|
const [connector, appConnected] = this.getConnector(id);
|
|
493
506
|
|
|
@@ -719,7 +732,7 @@ async ensureUniqueLog(id: ThreadID, key?: Ed25519PrivKey | Ed25519PubKey, identi
|
|
|
719
732
|
|
|
720
733
|
async updateLogsFromPeer(tid: ThreadID,peerId: PeerId): Promise<void> {
|
|
721
734
|
try {
|
|
722
|
-
const client = await this.getClient(peerId);
|
|
735
|
+
const [client,_] = await this.getClient(peerId);
|
|
723
736
|
if (!client) {
|
|
724
737
|
return ;
|
|
725
738
|
}
|
|
@@ -804,7 +817,7 @@ async getRecordsFromPeer(
|
|
|
804
817
|
): Promise<Record<string, PeerRecords>> {
|
|
805
818
|
try {
|
|
806
819
|
|
|
807
|
-
const client = await this.getClient(peerId);
|
|
820
|
+
const [client,_] = await this.getClient(peerId);
|
|
808
821
|
if (!client) {
|
|
809
822
|
return {};
|
|
810
823
|
}
|
|
@@ -1147,67 +1160,113 @@ async getRecord( id: ThreadID, rid: CID): Promise<IRecord> {
|
|
|
1147
1160
|
const recordCollector = new RecordCollector();
|
|
1148
1161
|
|
|
1149
1162
|
// 确定需要获取的对等点数量
|
|
1150
|
-
const needFetched = Math.min(
|
|
1151
|
-
let
|
|
1163
|
+
const needFetched = Math.min(1, peers.length);
|
|
1164
|
+
let resolved = false; // 防止重复调用 resolve
|
|
1165
|
+
// 使用对象来保证引用一致性
|
|
1166
|
+
const fetchState = {
|
|
1167
|
+
fetchedPeers: 0
|
|
1168
|
+
};
|
|
1169
|
+
let mainTimeoutId: NodeJS.Timeout | undefined;
|
|
1170
|
+
// 设置主超时
|
|
1171
|
+
const timeoutPromise = new Promise<void>((resolve) => {
|
|
1172
|
+
mainTimeoutId = setTimeout(() => {
|
|
1173
|
+
resolve(); // 超时时总是resolve,在外部判断是否有足够的数据
|
|
1174
|
+
}, 30000);
|
|
1175
|
+
});
|
|
1152
1176
|
|
|
1153
1177
|
// 创建一个 Promise 在足够的对等点响应时解析
|
|
1154
1178
|
const fetchPromise = new Promise<void>((resolve) => {
|
|
1155
|
-
//
|
|
1179
|
+
// 立即检查是否满足条件
|
|
1156
1180
|
const checkComplete = () => {
|
|
1157
|
-
if (fetchedPeers >= needFetched) {
|
|
1181
|
+
if (!resolved && fetchState.fetchedPeers >= needFetched) {
|
|
1182
|
+
resolved = true;
|
|
1158
1183
|
resolve();
|
|
1159
1184
|
}
|
|
1160
1185
|
};
|
|
1161
1186
|
|
|
1162
1187
|
// 从每个对等点查询记录
|
|
1163
1188
|
const fetchPromises = peers.map(async (peerId) => {
|
|
1189
|
+
let timeoutId: NodeJS.Timeout | undefined;
|
|
1190
|
+
// 为每个peer设置独立的超时
|
|
1191
|
+
const peerTimeout = new Promise<never>((_, reject) => {
|
|
1192
|
+
timeoutId = setTimeout(() => reject(new Error(`Peer ${peerId} timeout after 30s`)), 30000);
|
|
1193
|
+
});
|
|
1194
|
+
|
|
1164
1195
|
try {
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
// 更新收集器
|
|
1176
|
-
Object.entries(records).forEach(([logId, rs]) => {
|
|
1177
|
-
recordCollector.updateHeadCounter(logId, rs.counter);
|
|
1178
|
-
rs.records.forEach(record => {
|
|
1179
|
-
recordCollector.store(logId, record);
|
|
1180
|
-
});
|
|
1181
|
-
});
|
|
1182
|
-
|
|
1183
|
-
fetchedPeers++;
|
|
1196
|
+
// 使用 Promise.race 为每个peer设置超时
|
|
1197
|
+
await Promise.race([
|
|
1198
|
+
(async () => {
|
|
1199
|
+
//连接到指定peerId,返回一个Client
|
|
1200
|
+
const [client,_] = await this.getClient(peerId);
|
|
1201
|
+
if (!client) {
|
|
1202
|
+
return;
|
|
1203
|
+
}
|
|
1204
|
+
const dbClient = new DBClient(client,this.dc,this,this.logstore);
|
|
1184
1205
|
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1206
|
+
const records = await dbClient.getRecordsFromPeer( req, serviceKey);
|
|
1207
|
+
|
|
1208
|
+
// 更新收集器
|
|
1209
|
+
Object.entries(records).forEach(([logId, rs]) => {
|
|
1210
|
+
recordCollector.updateHeadCounter(logId, rs.counter);
|
|
1211
|
+
rs.records.forEach(record => {
|
|
1212
|
+
recordCollector.store(logId, record);
|
|
1213
|
+
});
|
|
1214
|
+
});
|
|
1215
|
+
|
|
1216
|
+
fetchState.fetchedPeers++;
|
|
1217
|
+
|
|
1218
|
+
// 每次成功获取记录后立即检查是否满足条件
|
|
1219
|
+
checkComplete();
|
|
1220
|
+
})(),
|
|
1221
|
+
peerTimeout
|
|
1222
|
+
]);
|
|
1192
1223
|
} catch (err) {
|
|
1193
1224
|
console.error(`Error getting records from peer ${peerId}:`, err);
|
|
1225
|
+
// 错误不影响其他peer的执行
|
|
1226
|
+
} finally {
|
|
1227
|
+
// 清除定时器,防止内存泄漏
|
|
1228
|
+
if (timeoutId) {
|
|
1229
|
+
clearTimeout(timeoutId);
|
|
1230
|
+
}
|
|
1231
|
+
}
|
|
1232
|
+
});
|
|
1233
|
+
|
|
1234
|
+
// 使用 Promise.allSettled 替代 Promise.all,避免被单个失败阻塞
|
|
1235
|
+
// 同时设置额外的兜底检查机制
|
|
1236
|
+
Promise.allSettled(fetchPromises).then(() => {
|
|
1237
|
+
if (!resolved) {
|
|
1238
|
+
checkComplete();
|
|
1194
1239
|
}
|
|
1195
1240
|
});
|
|
1196
1241
|
|
|
1197
|
-
//
|
|
1198
|
-
|
|
1199
|
-
|
|
1242
|
+
// 添加定期检查机制,防止被某些未知问题阻塞
|
|
1243
|
+
const checkInterval = setInterval(() => {
|
|
1244
|
+
if (resolved) {
|
|
1245
|
+
clearInterval(checkInterval);
|
|
1246
|
+
} else {
|
|
1247
|
+
checkComplete();
|
|
1248
|
+
}
|
|
1249
|
+
}, 5000); // 每5秒检查一次
|
|
1250
|
+
|
|
1251
|
+
// 确保interval最终被清理
|
|
1252
|
+
setTimeout(() => clearInterval(checkInterval), 35000);
|
|
1200
1253
|
});
|
|
1201
1254
|
|
|
1202
|
-
|
|
1203
|
-
const timeoutPromise = new Promise<void>((_, reject) => {
|
|
1204
|
-
setTimeout(() => reject(new Error("Fetch records timeout")), 30000);
|
|
1205
|
-
});
|
|
1255
|
+
|
|
1206
1256
|
|
|
1207
1257
|
// 等待获取足够的记录或超时
|
|
1208
1258
|
await Promise.race([fetchPromise, timeoutPromise]);
|
|
1259
|
+
// 清除超时定时器
|
|
1260
|
+
if (mainTimeoutId) {
|
|
1261
|
+
clearTimeout(mainTimeoutId);
|
|
1262
|
+
}
|
|
1263
|
+
// 检查是否获取到足够的数据
|
|
1264
|
+
if (fetchState.fetchedPeers === 0) {
|
|
1265
|
+
throw new Error("Fetch records timeout: no peers responded");
|
|
1266
|
+
}
|
|
1209
1267
|
|
|
1210
|
-
//
|
|
1268
|
+
// 如果有数据就返回(不管是1个还是2个节点)
|
|
1269
|
+
console.log(`获取记录完成: ${fetchState.fetchedPeers}/${needFetched} 个节点响应`);
|
|
1211
1270
|
return recordCollector.list();
|
|
1212
1271
|
} catch (err) {
|
|
1213
1272
|
console.error("getRecords error:", err);
|
|
@@ -1588,7 +1647,7 @@ async pushRecord(tid: ThreadID, lid: PeerId, rec: IRecord, counter: number): Pro
|
|
|
1588
1647
|
continue;
|
|
1589
1648
|
}
|
|
1590
1649
|
try {
|
|
1591
|
-
const client = await this.getClient(p);
|
|
1650
|
+
const [client,_] = await this.getClient(p);
|
|
1592
1651
|
if (!client) {
|
|
1593
1652
|
continue
|
|
1594
1653
|
}
|
|
@@ -1649,7 +1708,7 @@ async exchange(tid: ThreadID): Promise<void> {
|
|
|
1649
1708
|
private async exchangeWithPeer(pid: PeerId, tid: ThreadID): Promise<void> {
|
|
1650
1709
|
try {
|
|
1651
1710
|
// 获取客户端连接
|
|
1652
|
-
const client = await this.getClient(pid);
|
|
1711
|
+
const [client,_] = await this.getClient(pid);
|
|
1653
1712
|
if (!client) {
|
|
1654
1713
|
return;
|
|
1655
1714
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { IAppInfo } from '../../lib/common/types/types';
|
|
2
2
|
import { SymmetricKey, Key as ThreadKey } from '../implements/threaddb/common/key';
|
|
3
|
+
import { IFileOperations } from './file-interface';
|
|
3
4
|
|
|
4
5
|
|
|
5
6
|
export interface IUtilOperations {
|
|
@@ -15,4 +16,16 @@ export interface IUtilOperations {
|
|
|
15
16
|
*/
|
|
16
17
|
setAppInfo(appId: string,fid:string,domain:string,owner?: string,rewarder?: string): Promise<[boolean|null, Error | null]>;
|
|
17
18
|
getAppInfo(appId: string): Promise<[IAppInfo|null, Error | null]>;
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* 处理IPFS请求
|
|
22
|
+
* @param data 请求数据
|
|
23
|
+
* @param port 消息端口
|
|
24
|
+
* @param fileOps 文件操作对象
|
|
25
|
+
*/
|
|
26
|
+
handleIpfsRequest(
|
|
27
|
+
data: { id: string, pathname: string, range?: string },
|
|
28
|
+
port: MessagePort,
|
|
29
|
+
fileOps?: IFileOperations
|
|
30
|
+
): Promise<void>
|
|
18
31
|
}
|
|
@@ -2,11 +2,12 @@
|
|
|
2
2
|
import { IUtilOperations } from '../interfaces/util-interface';
|
|
3
3
|
import { SymmetricKey,Key as ThreadKey } from '../implements/threaddb/common/key';
|
|
4
4
|
import { CoreModuleName } from '../common/module-system';
|
|
5
|
-
import { DCContext } from '../interfaces';
|
|
5
|
+
import { DCContext, IFileOperations } from '../interfaces';
|
|
6
6
|
import { createLogger } from '../util/logger';
|
|
7
7
|
import { UtilManager } from '../../lib/implements/util/manager';
|
|
8
8
|
import { IAppInfo } from '../../lib/common/types/types';
|
|
9
9
|
import { Errors } from '../../lib/common/error';
|
|
10
|
+
import { handleIpfsRequest } from '../common/service-worker';
|
|
10
11
|
const logger = createLogger("UtilModule");
|
|
11
12
|
export class UtilModule implements IUtilOperations {
|
|
12
13
|
readonly moduleName = CoreModuleName.UTIL;
|
|
@@ -121,5 +122,27 @@ export class UtilModule implements IUtilOperations {
|
|
|
121
122
|
async shutdown(): Promise<void> {
|
|
122
123
|
this.initialized = false;
|
|
123
124
|
}
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* 处理IPFS请求
|
|
129
|
+
* @param data 请求数据
|
|
130
|
+
* @param port 消息端口
|
|
131
|
+
* @param fileOps 文件操作对象
|
|
132
|
+
*/
|
|
133
|
+
async handleIpfsRequest(
|
|
134
|
+
data: { id: string, pathname: string, range?: string },
|
|
135
|
+
port: MessagePort,
|
|
136
|
+
fileOps?: IFileOperations
|
|
137
|
+
): Promise<void>{
|
|
138
|
+
if (!this.initialized) {
|
|
139
|
+
return;
|
|
140
|
+
}
|
|
141
|
+
try {
|
|
142
|
+
await handleIpfsRequest(data, port, fileOps);
|
|
143
|
+
} catch (error) {
|
|
144
|
+
logger.error("页面处理IPFS请求失败:", error);
|
|
145
|
+
}
|
|
146
|
+
}
|
|
124
147
|
|
|
125
148
|
}
|
package/package.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "web-dc-api",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.49",
|
|
4
4
|
"description": "web相关的dcapi",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"browser": "dist/dc.min.js",
|
|
7
|
-
"main": "
|
|
8
|
-
"module": "
|
|
9
|
-
"types": "
|
|
7
|
+
"main": "dist/index.cjs.js",
|
|
8
|
+
"module": "dist/index.esm.js",
|
|
9
|
+
"types": "dist/index.d.ts",
|
|
10
10
|
"exports": {
|
|
11
11
|
".": {
|
|
12
12
|
"types": "./dist/index.d.ts",
|
|
@@ -52,14 +52,10 @@
|
|
|
52
52
|
"ajv": "^8.17.1",
|
|
53
53
|
"async-mutex": "^0.5.0",
|
|
54
54
|
"blockstore-idb": "^2.0.1",
|
|
55
|
-
"cbor-x": "^1.6.0",
|
|
56
55
|
"cids": "^1.1.9",
|
|
57
|
-
"crypto-js": "^4.2.0",
|
|
58
56
|
"datastore-idb": "^3.0.1",
|
|
59
57
|
"datastore-level": "^11.0.1",
|
|
60
|
-
"ethers": "^6.14.1",
|
|
61
58
|
"google-protobuf": "~3.21.2",
|
|
62
|
-
"grpc-libp2p-client": "^0.0.10",
|
|
63
59
|
"helia": "5.3.0",
|
|
64
60
|
"interface-ipld-format": "^1.0.1",
|
|
65
61
|
"it-to-buffer": "^4.0.7",
|
|
@@ -68,9 +64,7 @@
|
|
|
68
64
|
"jscrypto": "^1.0.3",
|
|
69
65
|
"jwt-decode": "^4.0.0",
|
|
70
66
|
"libp2p": "^2.8.1",
|
|
71
|
-
"lodash": "~4.17.0",
|
|
72
67
|
"lru-cache": "^11.1.0",
|
|
73
|
-
"mp4box": "^0.5.4",
|
|
74
68
|
"multiaddr": "^10.0.1",
|
|
75
69
|
"multiformats": "^13.3.2",
|
|
76
70
|
"protobufjs": "^7.5.0",
|
|
@@ -82,6 +76,12 @@
|
|
|
82
76
|
"lib": "lib"
|
|
83
77
|
},
|
|
84
78
|
"devDependencies": {
|
|
79
|
+
"grpc-libp2p-client": "^0.0.10",
|
|
80
|
+
"cbor-x": "^1.6.0",
|
|
81
|
+
"crypto-js": "^4.2.0",
|
|
82
|
+
"ethers": "^6.14.1",
|
|
83
|
+
"lodash": "~4.17.0",
|
|
84
|
+
"mp4box": "^0.5.4",
|
|
85
85
|
"@babel/core": "^7.27.4",
|
|
86
86
|
"@babel/preset-env": "^7.27.2",
|
|
87
87
|
"@rollup/plugin-babel": "^6.0.4",
|
|
@@ -97,6 +97,8 @@
|
|
|
97
97
|
"nodemon": "^3.1.9",
|
|
98
98
|
"rollup-plugin-dts": "^6.2.1",
|
|
99
99
|
"typescript": "^5.8.3",
|
|
100
|
-
"webpack-bundle-analyzer": "^4.10.2"
|
|
100
|
+
"webpack-bundle-analyzer": "^4.10.2",
|
|
101
|
+
"vite": "^7.1.2",
|
|
102
|
+
"vite-plugin-dts": "^4.5.4"
|
|
101
103
|
}
|
|
102
104
|
}
|