libp2r2p 0.5.0 → 0.7.0
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/README.md +58 -11
- package/idb-queue/index.js +60 -11
- package/package.json +1 -1
- package/private-channel/index.js +49 -31
- package/private-channel/services/received-chunks.js +453 -245
- package/private-message/index.js +62 -17
- package/private-messenger/index.js +383 -76
- package/private-messenger/recovery/index.js +3 -1
- package/private-messenger/services/channel-state.js +132 -0
- package/private-messenger/services/storage-maintenance.js +324 -0
package/private-message/index.js
CHANGED
|
@@ -12,6 +12,7 @@ const HEX_PUBKEY = /^[0-9a-f]{64}$/i
|
|
|
12
12
|
|
|
13
13
|
const watchesByChannel = new Map()
|
|
14
14
|
const subsByRelay = new Map()
|
|
15
|
+
let nextWatchRevision = 1
|
|
15
16
|
|
|
16
17
|
function nowSeconds () {
|
|
17
18
|
return Math.floor(Date.now() / 1000)
|
|
@@ -254,6 +255,27 @@ function maxWatchNumber (channels, field) {
|
|
|
254
255
|
return values.length ? Math.max(...values) : undefined
|
|
255
256
|
}
|
|
256
257
|
|
|
258
|
+
function watchNumbersForChannels (channels, field) {
|
|
259
|
+
const out = {}
|
|
260
|
+
for (const channel of channels) {
|
|
261
|
+
const value = watchesByChannel.get(channel)?.[field]
|
|
262
|
+
if (Number.isFinite(value)) out[channel] = value
|
|
263
|
+
}
|
|
264
|
+
return out
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
function watchRevisionsForChannels (channels) {
|
|
268
|
+
return Object.fromEntries(channels.map(channel => [channel, watchesByChannel.get(channel)?.revision || 0]))
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
function subscriptionMatches (current, channels) {
|
|
272
|
+
if (!current || !setEquals(current.channels, channels)) return false
|
|
273
|
+
for (const channel of channels) {
|
|
274
|
+
if (current.revisions?.[channel] !== watchesByChannel.get(channel)?.revision) return false
|
|
275
|
+
}
|
|
276
|
+
return true
|
|
277
|
+
}
|
|
278
|
+
|
|
257
279
|
function firstWatchValue (channels, field) {
|
|
258
280
|
for (const channel of channels) {
|
|
259
281
|
const value = watchesByChannel.get(channel)?.[field]
|
|
@@ -263,25 +285,34 @@ function firstWatchValue (channels, field) {
|
|
|
263
285
|
}
|
|
264
286
|
|
|
265
287
|
function closeSubscription (sub, gracefulClose) {
|
|
266
|
-
if (gracefulClose)
|
|
267
|
-
|
|
288
|
+
if (gracefulClose) {
|
|
289
|
+
setTimeout(() => Promise.resolve().then(() => sub.close()).catch(() => {}), RESUBSCRIBE_GRACE_MS)
|
|
290
|
+
return null
|
|
291
|
+
}
|
|
292
|
+
try {
|
|
293
|
+
return Promise.resolve(sub.close())
|
|
294
|
+
} catch (err) {
|
|
295
|
+
return Promise.reject(err)
|
|
296
|
+
}
|
|
268
297
|
}
|
|
269
298
|
|
|
270
299
|
function rebuildSubscriptions ({ _subscribe = privateChannel.subscribe, gracefulClose = true } = {}) {
|
|
271
300
|
const desired = desiredRelayState()
|
|
301
|
+
const closing = []
|
|
272
302
|
|
|
273
303
|
for (const [relay, current] of subsByRelay) {
|
|
274
304
|
const nextChannels = desired.get(relay)
|
|
275
|
-
if (nextChannels &&
|
|
305
|
+
if (nextChannels && subscriptionMatches(current, nextChannels)) continue
|
|
276
306
|
if (!nextChannels) {
|
|
277
|
-
closeSubscription(current.sub, gracefulClose)
|
|
307
|
+
const close = closeSubscription(current.sub, gracefulClose)
|
|
308
|
+
if (close) closing.push(close)
|
|
278
309
|
subsByRelay.delete(relay)
|
|
279
310
|
}
|
|
280
311
|
}
|
|
281
312
|
|
|
282
313
|
for (const [relay, channels] of desired) {
|
|
283
314
|
const current = subsByRelay.get(relay)
|
|
284
|
-
if (
|
|
315
|
+
if (subscriptionMatches(current, channels)) continue
|
|
285
316
|
|
|
286
317
|
const channelList = [...channels]
|
|
287
318
|
const firstWatch = watchesByChannel.get(channelList[0])
|
|
@@ -300,8 +331,9 @@ function rebuildSubscriptions ({ _subscribe = privateChannel.subscribe, graceful
|
|
|
300
331
|
mode: firstWatch.mode,
|
|
301
332
|
modeByPubkey: modesForChannels(channelList),
|
|
302
333
|
receivedChunkTtlMs: maxWatchNumber(channelList, 'receivedChunkTtlMs'),
|
|
334
|
+
receivedChunkTtlMsByPubkey: watchNumbersForChannels(channelList, 'receivedChunkTtlMs'),
|
|
303
335
|
receivedChunkMaxBytes: maxWatchNumber(channelList, 'receivedChunkMaxBytes'),
|
|
304
|
-
|
|
336
|
+
receivedChunkIndexedDB: firstWatchValue(channelList, 'receivedChunkIndexedDB'),
|
|
305
337
|
ignoredGroupTtlMs: maxWatchNumber(channelList, 'ignoredGroupTtlMs'),
|
|
306
338
|
ignoredGroupMaxEntries: maxWatchNumber(channelList, 'ignoredGroupMaxEntries'),
|
|
307
339
|
limit: 0,
|
|
@@ -321,9 +353,17 @@ function rebuildSubscriptions ({ _subscribe = privateChannel.subscribe, graceful
|
|
|
321
353
|
onError: err => firstWatch.callbacks.onError?.(err)
|
|
322
354
|
})
|
|
323
355
|
|
|
324
|
-
subsByRelay.set(relay, {
|
|
325
|
-
|
|
356
|
+
subsByRelay.set(relay, {
|
|
357
|
+
channels: new Set(channels),
|
|
358
|
+
revisions: watchRevisionsForChannels(channelList),
|
|
359
|
+
sub
|
|
360
|
+
})
|
|
361
|
+
if (current) {
|
|
362
|
+
const close = closeSubscription(current.sub, gracefulClose)
|
|
363
|
+
if (close) closing.push(close)
|
|
364
|
+
}
|
|
326
365
|
}
|
|
366
|
+
return Promise.allSettled(closing)
|
|
327
367
|
}
|
|
328
368
|
|
|
329
369
|
export async function watch ({
|
|
@@ -348,7 +388,7 @@ export async function watch ({
|
|
|
348
388
|
onError,
|
|
349
389
|
receivedChunkTtlMs,
|
|
350
390
|
receivedChunkMaxBytes,
|
|
351
|
-
|
|
391
|
+
receivedChunkIndexedDB,
|
|
352
392
|
ignoredGroupTtlMs,
|
|
353
393
|
ignoredGroupMaxEntries,
|
|
354
394
|
since = nowSeconds(),
|
|
@@ -372,26 +412,30 @@ export async function watch ({
|
|
|
372
412
|
mode,
|
|
373
413
|
receivedChunkTtlMs,
|
|
374
414
|
receivedChunkMaxBytes,
|
|
375
|
-
|
|
415
|
+
receivedChunkIndexedDB,
|
|
376
416
|
ignoredGroupTtlMs,
|
|
377
417
|
ignoredGroupMaxEntries,
|
|
378
418
|
callbacks,
|
|
379
419
|
since
|
|
380
420
|
}
|
|
381
421
|
const current = watchesByChannel.get(channel)
|
|
382
|
-
|
|
422
|
+
const sameSettings = Boolean(
|
|
383
423
|
current &&
|
|
384
|
-
|
|
424
|
+
current.receiverSigner === next.receiverSigner &&
|
|
425
|
+
current.iykcSigner === next.iykcSigner &&
|
|
385
426
|
current.privateChannelSigner === next.privateChannelSigner &&
|
|
386
427
|
current.privateChannelReaderSigner === next.privateChannelReaderSigner &&
|
|
387
428
|
current.privateChannelReaderPubkey === next.privateChannelReaderPubkey &&
|
|
429
|
+
current.receiverPubkey === next.receiverPubkey &&
|
|
388
430
|
current.mode === next.mode &&
|
|
389
431
|
current.receivedChunkTtlMs === next.receivedChunkTtlMs &&
|
|
390
432
|
current.receivedChunkMaxBytes === next.receivedChunkMaxBytes &&
|
|
391
|
-
current.
|
|
433
|
+
current.receivedChunkIndexedDB === next.receivedChunkIndexedDB &&
|
|
392
434
|
current.ignoredGroupTtlMs === next.ignoredGroupTtlMs &&
|
|
393
435
|
current.ignoredGroupMaxEntries === next.ignoredGroupMaxEntries
|
|
394
|
-
)
|
|
436
|
+
)
|
|
437
|
+
next.revision = sameSettings ? current.revision : nextWatchRevision++
|
|
438
|
+
if (sameSettings && setEquals(new Set(current.relays), new Set(next.relays))) {
|
|
395
439
|
current.callbacks = callbacks
|
|
396
440
|
continue
|
|
397
441
|
}
|
|
@@ -399,18 +443,19 @@ export async function watch ({
|
|
|
399
443
|
changed = true
|
|
400
444
|
}
|
|
401
445
|
|
|
402
|
-
if (changed) rebuildSubscriptions({ _subscribe })
|
|
446
|
+
if (changed) await rebuildSubscriptions({ _subscribe })
|
|
403
447
|
return () => unwatch(channelList)
|
|
404
448
|
}
|
|
405
449
|
|
|
406
450
|
export function unwatch (channels) {
|
|
407
451
|
const channelList = channels ? uniq(Array.isArray(channels) ? channels : [channels]) : [...watchesByChannel.keys()]
|
|
408
452
|
for (const channel of channelList) watchesByChannel.delete(channel)
|
|
409
|
-
rebuildSubscriptions({ gracefulClose: false })
|
|
453
|
+
return rebuildSubscriptions({ gracefulClose: false })
|
|
410
454
|
}
|
|
411
455
|
|
|
412
456
|
export function clearChannelState (channelPubkey) {
|
|
413
|
-
if (watchesByChannel.has(channelPubkey)) unwatch(channelPubkey)
|
|
457
|
+
if (watchesByChannel.has(channelPubkey)) return unwatch(channelPubkey)
|
|
458
|
+
return Promise.resolve([])
|
|
414
459
|
}
|
|
415
460
|
|
|
416
461
|
async function sendPrivateMessage ({
|