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.
@@ -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) setTimeout(() => sub.close(), RESUBSCRIBE_GRACE_MS)
267
- else sub.close()
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 && setEquals(current.channels, nextChannels)) continue
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 (current && setEquals(current.channels, channels)) continue
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
- receivedChunkStorageArea: firstWatchValue(channelList, 'receivedChunkStorageArea'),
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, { channels: new Set(channels), sub })
325
- if (current) closeSubscription(current.sub, gracefulClose)
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
- receivedChunkStorageArea,
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
- receivedChunkStorageArea,
415
+ receivedChunkIndexedDB,
376
416
  ignoredGroupTtlMs,
377
417
  ignoredGroupMaxEntries,
378
418
  callbacks,
379
419
  since
380
420
  }
381
421
  const current = watchesByChannel.get(channel)
382
- if (
422
+ const sameSettings = Boolean(
383
423
  current &&
384
- setEquals(new Set(current.relays), new Set(next.relays)) &&
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.receivedChunkStorageArea === next.receivedChunkStorageArea &&
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 ({