web-dc-api 0.0.66 → 0.0.68
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 +1 -1
- package/dist/index.cjs.js +1 -1
- package/dist/index.esm.js +1 -1
- package/lib/common/dcutil.ts +8 -1
- package/lib/common/service-worker.ts +42 -45
- package/lib/implements/threaddb/net/grpcClient.ts +1 -1
- package/lib/implements/threaddb/net/net.ts +14 -6
- package/package.json +1 -1
package/lib/common/dcutil.ts
CHANGED
|
@@ -439,8 +439,9 @@ export class DcUtil {
|
|
|
439
439
|
const nodeConn = await libp2p.dial(nodeAddr, {
|
|
440
440
|
signal: AbortSignal.timeout(dial_timeout)
|
|
441
441
|
});
|
|
442
|
-
|
|
442
|
+
//判断是否有现成的stream,如果已经存在就直接使用
|
|
443
443
|
const stream = await nodeConn.newStream("/dc/transfer/1.0.0")
|
|
444
|
+
try{
|
|
444
445
|
const writer = new StreamWriter(stream.sink)
|
|
445
446
|
const mParts: Uint8Array[] = [];
|
|
446
447
|
let parsedMessage: { type: number; version: number; payload: Uint8Array } | null = null;
|
|
@@ -508,9 +509,15 @@ export class DcUtil {
|
|
|
508
509
|
}
|
|
509
510
|
}
|
|
510
511
|
}
|
|
512
|
+
}catch(err){
|
|
513
|
+
console.error("createTransferStream error:", err);
|
|
514
|
+
throw err
|
|
515
|
+
}finally{
|
|
511
516
|
stream.close()
|
|
512
517
|
}
|
|
513
518
|
|
|
519
|
+
}
|
|
520
|
+
|
|
514
521
|
|
|
515
522
|
private async *chunkGenerator(stream: Stream): AsyncGenerator<Uint8Array> {
|
|
516
523
|
const iterator = stream.source[Symbol.asyncIterator]();
|
|
@@ -6,60 +6,57 @@ import { createLogger } from "../util/logger";
|
|
|
6
6
|
|
|
7
7
|
const logger = createLogger('ServiceWorker');
|
|
8
8
|
|
|
9
|
+
|
|
10
|
+
let swMessageHandler: ((event: MessageEvent) => void) | null = null;
|
|
11
|
+
|
|
9
12
|
/**
|
|
10
13
|
* 注册 Service Worker 并设置消息监听器
|
|
11
14
|
* @param fileOps 文件操作对象,用于处理IPFS请求
|
|
12
15
|
* @returns Promise<ServiceWorkerRegistration | null>
|
|
13
16
|
*/
|
|
14
17
|
export async function registerServiceWorker(fileOps?: IFileOperations, swUrl: string = ''): Promise<ServiceWorkerRegistration | null> {
|
|
15
|
-
if ('serviceWorker' in navigator)
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
registration.addEventListener('updatefound', () => {
|
|
37
|
-
const nw = registration.installing;
|
|
38
|
-
if (!nw) return;
|
|
39
|
-
nw.addEventListener('statechange', () => {
|
|
40
|
-
if (nw.state === 'installed' && navigator.serviceWorker.controller) {
|
|
41
|
-
nw.postMessage({ type: 'SKIP_WAITING' });
|
|
42
|
-
}
|
|
43
|
-
});
|
|
44
|
-
});
|
|
45
|
-
// 设置消息监听器处理IPFS资源请求
|
|
46
|
-
navigator.serviceWorker.addEventListener('message', async (event) => {
|
|
47
|
-
if (event.data && event.data.type === 'ipfs-fetch') {
|
|
48
|
-
await handleIpfsRequest(event.data, event.ports[0]!, fileOps);
|
|
18
|
+
if (!('serviceWorker' in navigator)) return Promise.reject('Service Worker not supported');
|
|
19
|
+
if (location.protocol !== 'https:' && location.hostname !== 'localhost') {
|
|
20
|
+
logger.error('ServiceWorker 仅支持 https 或 localhost');
|
|
21
|
+
return null;
|
|
22
|
+
}
|
|
23
|
+
if (window.location.protocol != 'https:' && window.location.hostname != 'localhost') {
|
|
24
|
+
logger.error('ServiceWorker 仅支持https协议');
|
|
25
|
+
return null;
|
|
26
|
+
}
|
|
27
|
+
const swPath = new URL(swUrl || '/sw.js', location.origin).href;
|
|
28
|
+
const registration = await navigator.serviceWorker.register(swPath);
|
|
29
|
+
// 只保留一个监听器,避免重复处理同一请求
|
|
30
|
+
if (swMessageHandler) {
|
|
31
|
+
navigator.serviceWorker.removeEventListener('message', swMessageHandler);
|
|
32
|
+
}
|
|
33
|
+
swMessageHandler = async (event: MessageEvent) => {
|
|
34
|
+
if (event.data && event.data.type === 'ipfs-fetch') {
|
|
35
|
+
const port = event.ports?.[0];
|
|
36
|
+
if (!port) {
|
|
37
|
+
logger.warn('SW 未提供 MessagePort');
|
|
38
|
+
return;
|
|
49
39
|
}
|
|
40
|
+
//里面回一个消息,通知已经收到请求
|
|
41
|
+
port.postMessage({ success: true, message: 'Request received' ,status: 999 });
|
|
42
|
+
try {
|
|
43
|
+
await handleIpfsRequest(event.data, port, fileOps);
|
|
44
|
+
} catch (e) {
|
|
45
|
+
logger.error('handleIpfsRequest 处理异常:', e);
|
|
46
|
+
port.postMessage({ success: false, error: String(e) });
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
};
|
|
50
|
+
navigator.serviceWorker.addEventListener('message', swMessageHandler);
|
|
51
|
+
// 确保 SW 已 active
|
|
52
|
+
await navigator.serviceWorker.ready;
|
|
53
|
+
// 确保当前页已被控制,否则等待接管
|
|
54
|
+
if (!navigator.serviceWorker.controller) {
|
|
55
|
+
await new Promise<void>((resolve) => {
|
|
56
|
+
navigator.serviceWorker.addEventListener('controllerchange', () => resolve(), { once: true });
|
|
50
57
|
});
|
|
51
|
-
// 控制器变化(新 SW 接管)
|
|
52
|
-
navigator.serviceWorker.addEventListener('controllerchange', () => {
|
|
53
|
-
location.reload();
|
|
54
|
-
});
|
|
55
|
-
|
|
56
|
-
return registration;
|
|
57
|
-
} catch (error) {
|
|
58
|
-
logger.error('ServiceWorker 注册失败:', error);
|
|
59
|
-
return null;
|
|
60
58
|
}
|
|
61
|
-
|
|
62
|
-
return Promise.reject('Service Worker not supported');
|
|
59
|
+
return registration;
|
|
63
60
|
}
|
|
64
61
|
|
|
65
62
|
/**
|
|
@@ -1333,31 +1333,39 @@ export class Network implements Net {
|
|
|
1333
1333
|
|
|
1334
1334
|
// 创建记录收集器
|
|
1335
1335
|
const recordCollector = new RecordCollector();
|
|
1336
|
+
// 设置超时
|
|
1337
|
+
let timeout : NodeJS.Timeout | null = null;
|
|
1336
1338
|
//遍历节点,按顺序处理
|
|
1337
1339
|
for (const peerId of peers) {
|
|
1338
1340
|
try {
|
|
1339
|
-
|
|
1340
|
-
const timeout = setTimeout(() => {
|
|
1341
|
+
timeout = setTimeout(() => {
|
|
1341
1342
|
throw new Error(`Timeout getting records from peer ${peerId}`);
|
|
1342
|
-
},
|
|
1343
|
-
|
|
1343
|
+
}, 900000);
|
|
1344
1344
|
//连接到指定peerId,返回一个Client
|
|
1345
1345
|
const [client,err] = await this.getClient(peerId);
|
|
1346
1346
|
if (!client) {
|
|
1347
|
-
clearTimeout(timeout);
|
|
1348
1347
|
throw new Error(`Error getting records from peer ${peerId},no client,errinfo: ${err}`);
|
|
1349
1348
|
}
|
|
1349
|
+
console.log(`时间:${new Date().toLocaleString()} ,开始从 ${peerId.toString()} 获取记录...`);
|
|
1350
1350
|
const dbClient = new DBClient(client,this.dc,this,this.logstore);
|
|
1351
1351
|
const records = await dbClient.getRecordsFromPeer( req, serviceKey);
|
|
1352
|
+
console.log(`时间:${new Date().toLocaleString()} ,从 ${peerId.toString()} 获取记录完成,记录数为:`,Object.keys(records).length);
|
|
1353
|
+
console.log(`开始处理从 ${peerId.toString()} 获取的记录,记录数为:`,Object.keys(records).length);
|
|
1352
1354
|
for (const [logId, rs] of Object.entries(records)) {
|
|
1353
1355
|
await recordCollector.batchUpdate(logId, rs);
|
|
1354
1356
|
}
|
|
1355
|
-
|
|
1357
|
+
console.log(`处理从 ${peerId.toString()} 获取的记录完成,记录数为:`,Object.keys(records).length);
|
|
1358
|
+
|
|
1356
1359
|
if(!multiPeersFlag){
|
|
1357
1360
|
break;
|
|
1358
1361
|
}
|
|
1359
1362
|
} catch (err) {
|
|
1360
1363
|
continue;
|
|
1364
|
+
}finally{
|
|
1365
|
+
// 清除超时
|
|
1366
|
+
if (timeout) {
|
|
1367
|
+
clearTimeout(timeout);
|
|
1368
|
+
}
|
|
1361
1369
|
}
|
|
1362
1370
|
}
|
|
1363
1371
|
|