@steve02081504/fount-p2p 0.0.7 → 0.0.9
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/discovery/bt/index.mjs +8 -6
- package/discovery/index.mjs +15 -21
- package/files/chunk_responder.mjs +4 -8
- package/link/rtc.mjs +1 -1
- package/package.json +1 -1
- package/transport/link_registry.mjs +2 -8
package/discovery/bt/index.mjs
CHANGED
|
@@ -252,14 +252,15 @@ export function createBluetoothDiscoveryProvider() {
|
|
|
252
252
|
|
|
253
253
|
/**
|
|
254
254
|
* Central:按 peer hint 连接并对端 signal characteristic 写短包。
|
|
255
|
+
* 无 hint 时返回 false(正常降级,不算错误)。
|
|
255
256
|
* @param {string} topic 信令 topic
|
|
256
257
|
* @param {string} to 目标 nodeHash
|
|
257
258
|
* @param {Uint8Array} bytes 载荷
|
|
258
|
-
* @returns {Promise<
|
|
259
|
+
* @returns {Promise<boolean>} 是否投递
|
|
259
260
|
*/
|
|
260
261
|
async function sendSignalViaGatt(topic, to, bytes) {
|
|
261
262
|
const hint = getBtPeerHint(to)
|
|
262
|
-
if (!hint)
|
|
263
|
+
if (!hint) return false
|
|
263
264
|
const blob = Buffer.from(JSON.stringify({
|
|
264
265
|
topic: String(topic),
|
|
265
266
|
to: String(to),
|
|
@@ -324,6 +325,7 @@ export function createBluetoothDiscoveryProvider() {
|
|
|
324
325
|
finally {
|
|
325
326
|
try { await peripheral.disconnectAsync() } catch { /* ignore */ }
|
|
326
327
|
}
|
|
328
|
+
return true
|
|
327
329
|
}
|
|
328
330
|
|
|
329
331
|
return {
|
|
@@ -356,14 +358,14 @@ export function createBluetoothDiscoveryProvider() {
|
|
|
356
358
|
return addListener(advertListeners, String(topic), onAdvert)
|
|
357
359
|
},
|
|
358
360
|
/**
|
|
359
|
-
* 经 GATT 向近场 peer
|
|
361
|
+
* 经 GATT 向近场 peer 发送信令;无 peer hint 时返回 false。
|
|
360
362
|
* @param {string} topic 信令 topic
|
|
361
363
|
* @param {string} to 目标 nodeHash
|
|
362
364
|
* @param {Uint8Array} bytes 载荷
|
|
363
|
-
* @returns {Promise<
|
|
365
|
+
* @returns {Promise<boolean>} 是否投递
|
|
364
366
|
*/
|
|
365
|
-
|
|
366
|
-
|
|
367
|
+
sendSignal(topic, to, bytes) {
|
|
368
|
+
return sendSignalViaGatt(topic, to, bytes)
|
|
367
369
|
},
|
|
368
370
|
/**
|
|
369
371
|
* 监听经本机 peripheral signal characteristic 写入的信令。
|
package/discovery/index.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/** @typedef {{ id: string, priority: number, caps: { canDiscover?: boolean, canSignal?: boolean, canRelay?: boolean }, advertise?: (topic: string, bytes: Uint8Array) => (() => void) | Promise<() => void>, subscribe?: (topic: string, onAdvert: (bytes: Uint8Array, meta?: object) => void) => (() => void) | Promise<() => void>, sendSignal?: (topic: string, to: string, bytes: Uint8Array) => void | Promise<void>, onSignal?: (topic: string, onSignal: (bytes: Uint8Array, meta?: object) => void) => (() => void) | Promise<() => void> }} DiscoveryProvider */
|
|
1
|
+
/** @typedef {{ id: string, priority: number, caps: { canDiscover?: boolean, canSignal?: boolean, canRelay?: boolean }, advertise?: (topic: string, bytes: Uint8Array) => (() => void) | Promise<() => void>, subscribe?: (topic: string, onAdvert: (bytes: Uint8Array, meta?: object) => void) => (() => void) | Promise<() => void>, sendSignal?: (topic: string, to: string, bytes: Uint8Array) => boolean | void | Promise<boolean | void>, onSignal?: (topic: string, onSignal: (bytes: Uint8Array, meta?: object) => void) => (() => void) | Promise<() => void> }} DiscoveryProvider */
|
|
2
2
|
|
|
3
3
|
/** @type {Map<string, DiscoveryProvider>} */
|
|
4
4
|
const providers = new Map()
|
|
@@ -33,6 +33,7 @@ export function listDiscoveryProviders() {
|
|
|
33
33
|
|
|
34
34
|
/**
|
|
35
35
|
* 通过所有可用 provider 广播 topic advert。
|
|
36
|
+
* 单路失败静默(正常降级);其它 provider 仍可成功。
|
|
36
37
|
* @param {string} topic advert 主题
|
|
37
38
|
* @param {Uint8Array} bytes advert 载荷
|
|
38
39
|
* @returns {Promise<() => void>} 统一取消函数
|
|
@@ -45,10 +46,7 @@ export async function advertiseTopic(topic, bytes) {
|
|
|
45
46
|
try {
|
|
46
47
|
cleanup = await provider.advertise(topic, bytes)
|
|
47
48
|
}
|
|
48
|
-
catch
|
|
49
|
-
console.warn(`p2p: discovery advertise failed for ${provider.id}`, error)
|
|
50
|
-
continue
|
|
51
|
-
}
|
|
49
|
+
catch { continue }
|
|
52
50
|
if (typeof cleanup === 'function') cleanups.push(cleanup)
|
|
53
51
|
}
|
|
54
52
|
return () => {
|
|
@@ -59,6 +57,7 @@ export async function advertiseTopic(topic, bytes) {
|
|
|
59
57
|
|
|
60
58
|
/**
|
|
61
59
|
* 通过所有可用 provider 订阅 topic advert。
|
|
60
|
+
* 单路失败静默(正常降级)。
|
|
62
61
|
* @param {string} topic advert 主题
|
|
63
62
|
* @param {(bytes: Uint8Array, meta?: object) => void} onAdvert advert 回调
|
|
64
63
|
* @returns {Promise<() => void>} 统一取消函数
|
|
@@ -71,10 +70,7 @@ export async function subscribeTopic(topic, onAdvert) {
|
|
|
71
70
|
try {
|
|
72
71
|
cleanup = await provider.subscribe(topic, onAdvert)
|
|
73
72
|
}
|
|
74
|
-
catch
|
|
75
|
-
console.warn(`p2p: discovery subscribe failed for ${provider.id}`, error)
|
|
76
|
-
continue
|
|
77
|
-
}
|
|
73
|
+
catch { continue }
|
|
78
74
|
if (typeof cleanup === 'function') cleanups.push(cleanup)
|
|
79
75
|
}
|
|
80
76
|
return () => {
|
|
@@ -85,6 +81,8 @@ export async function subscribeTopic(topic, onAdvert) {
|
|
|
85
81
|
|
|
86
82
|
/**
|
|
87
83
|
* 通过 discovery provider 发送信令。
|
|
84
|
+
* provider 返回 `false` = 本路不可达(正常降级,不计成功);其它返回值 / void = 已投递。
|
|
85
|
+
* 单路 throw 静默;全部未投递才 throw。
|
|
88
86
|
* @param {string} topic 信令 topic
|
|
89
87
|
* @param {string} to 目标节点标识
|
|
90
88
|
* @param {Uint8Array} bytes 信令载荷
|
|
@@ -95,20 +93,19 @@ export async function sendSignal(topic, to, bytes) {
|
|
|
95
93
|
if (!capable.length) throw new Error('p2p: no discovery provider can signal')
|
|
96
94
|
let sent = false
|
|
97
95
|
let lastError = null
|
|
98
|
-
for (const provider of capable)
|
|
99
|
-
|
|
100
|
-
await Promise.resolve(provider.sendSignal(topic, to, bytes))
|
|
96
|
+
for (const provider of capable) try {
|
|
97
|
+
if (await Promise.resolve(provider.sendSignal(topic, to, bytes)) !== false)
|
|
101
98
|
sent = true
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
}
|
|
99
|
+
}
|
|
100
|
+
catch (error) {
|
|
101
|
+
lastError = error
|
|
102
|
+
}
|
|
107
103
|
if (!sent) throw lastError || new Error('p2p: no discovery provider delivered signal')
|
|
108
104
|
}
|
|
109
105
|
|
|
110
106
|
/**
|
|
111
107
|
* 通过所有可用 provider 监听信令。
|
|
108
|
+
* 单路失败静默(正常降级)。
|
|
112
109
|
* @param {string} topic 信令 topic
|
|
113
110
|
* @param {(bytes: Uint8Array, meta?: object) => void} onSignal 信令回调
|
|
114
111
|
* @returns {Promise<() => void>} 统一取消函数
|
|
@@ -121,10 +118,7 @@ export async function listenSignals(topic, onSignal) {
|
|
|
121
118
|
try {
|
|
122
119
|
cleanup = await provider.onSignal(topic, onSignal)
|
|
123
120
|
}
|
|
124
|
-
catch
|
|
125
|
-
console.warn(`p2p: discovery signal listener failed for ${provider.id}`, error)
|
|
126
|
-
continue
|
|
127
|
-
}
|
|
121
|
+
catch { continue }
|
|
128
122
|
if (typeof cleanup === 'function') cleanups.push(cleanup)
|
|
129
123
|
}
|
|
130
124
|
return () => {
|
|
@@ -94,14 +94,12 @@ export function attachTrustGraphFedChunkResponder(username, room, fedOut, guardG
|
|
|
94
94
|
*/
|
|
95
95
|
const send = () => {
|
|
96
96
|
try { sendChunkData(resp, pid) }
|
|
97
|
-
catch
|
|
98
|
-
console.warn('federation: trust-graph chunk response failed', error)
|
|
99
|
-
}
|
|
97
|
+
catch { /* peer gone — normal */ }
|
|
100
98
|
}
|
|
101
99
|
if (fedOut) fedOut.enqueue(6, send)
|
|
102
100
|
else send()
|
|
103
101
|
})
|
|
104
|
-
})().catch(
|
|
102
|
+
})().catch(() => { /* peer/handler race — normal degrade */ })
|
|
105
103
|
})
|
|
106
104
|
|
|
107
105
|
getChunkData(data => {
|
|
@@ -120,14 +118,12 @@ export function attachTrustGraphFedChunkResponder(username, room, fedOut, guardG
|
|
|
120
118
|
*/
|
|
121
119
|
const send = () => {
|
|
122
120
|
try { sendManifestData(resp, pid) }
|
|
123
|
-
catch
|
|
124
|
-
console.warn('federation: trust-graph manifest response failed', error)
|
|
125
|
-
}
|
|
121
|
+
catch { /* peer gone — normal */ }
|
|
126
122
|
}
|
|
127
123
|
if (fedOut) fedOut.enqueue(6, send)
|
|
128
124
|
else send()
|
|
129
125
|
})
|
|
130
|
-
})().catch(
|
|
126
|
+
})().catch(() => { /* peer/handler race — normal degrade */ })
|
|
131
127
|
})
|
|
132
128
|
|
|
133
129
|
getManifestData(data => {
|
package/link/rtc.mjs
CHANGED
|
@@ -8,7 +8,7 @@ import { wrapRtcPeerConnectionForMdns } from '../transport/rtc_mdns_filter.mjs'
|
|
|
8
8
|
* libdatachannel 的原生线程在 pc.close() 后仍需时间回收;进程退出时若原生资源未同步销毁,
|
|
9
9
|
* Windows 上会触发堆损坏(退出码 0xC0000374)。
|
|
10
10
|
*/
|
|
11
|
-
const { cleanup = undefined } = await import('node-datachannel').catch(
|
|
11
|
+
const { cleanup = undefined } = await import('node-datachannel').catch(() => ({}))
|
|
12
12
|
process.on('exit', () => {
|
|
13
13
|
try { cleanup?.() } catch { /* already torn down */ }
|
|
14
14
|
})
|
package/package.json
CHANGED
|
@@ -347,9 +347,7 @@ export function createLinkRegistry(options = {}) {
|
|
|
347
347
|
})
|
|
348
348
|
if (typeof stop === 'function') stopLinkListeners.push(stop)
|
|
349
349
|
}
|
|
350
|
-
catch
|
|
351
|
-
console.warn(`p2p: link provider listening failed for ${provider.id}`, error)
|
|
352
|
-
}
|
|
350
|
+
catch { /* provider listen unavailable — normal degrade */ }
|
|
353
351
|
|
|
354
352
|
if (listDiscoveryProviders().length) {
|
|
355
353
|
stopSignalListener = await listenSignals(selfTopic, bytes => {
|
|
@@ -591,16 +589,12 @@ export function createLinkRegistry(options = {}) {
|
|
|
591
589
|
// soft-fail 返回 null(不 throw);必须 continue 才能落到更低 level。
|
|
592
590
|
const link = await dialOfferAnswer(provider, normalized)
|
|
593
591
|
if (link) return link
|
|
594
|
-
console.warn(`p2p: link dial failed for ${provider.id}: soft-fail`)
|
|
595
592
|
continue
|
|
596
593
|
}
|
|
597
594
|
const link = await dialProvider(provider, normalized)
|
|
598
595
|
if (link) return link
|
|
599
|
-
console.warn(`p2p: link dial failed for ${provider.id}: soft-fail`)
|
|
600
|
-
}
|
|
601
|
-
catch (error) {
|
|
602
|
-
console.warn(`p2p: link dial failed for ${provider.id}: ${error?.message ?? error}`)
|
|
603
596
|
}
|
|
597
|
+
catch { /* dial failed — try next provider */ }
|
|
604
598
|
|
|
605
599
|
return null
|
|
606
600
|
})().finally(() => inflights.delete(normalized))
|