@mblaney/holster 1.0.17 → 1.0.18

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mblaney/holster",
3
- "version": "1.0.17",
3
+ "version": "1.0.18",
4
4
  "description": "Holster is a service that allows synchronising data between devices using Node, Deno, Bun or the browser.",
5
5
  "type": "module",
6
6
  "main": "index.js",
package/src/holster.js CHANGED
@@ -568,25 +568,19 @@ const Holster = opt => {
568
568
  if (id) {
569
569
  // It's a rel, read the related node. It might not be in the graph
570
570
  // yet when the listener fires, so we retry with delays.
571
- const attemptRead = (retries = 0) => {
572
- wire.get(
573
- {"#": id},
574
- relMsg => {
575
- if (relMsg.put && relMsg.put[id]) {
576
- delete relMsg.put[id]._
577
- delete relMsg.put[id][utils.userPublicKey]
578
- delete relMsg.put[id][utils.userSignature]
579
- cb(relMsg.put[id])
580
- } else if (retries < 5) {
581
- // Data not ready yet, retry after a delay
582
- setTimeout(() => attemptRead(retries + 1), 50)
583
- } else {
584
- // Give up after retries
585
- cb(null)
586
- }
587
- },
588
- _opt,
589
- )
571
+ const attemptRead = async (retries = 0) => {
572
+ const data = await new Promise(res => {
573
+ const _ctxid = utils.text.random()
574
+ allctx.set(_ctxid, {chain: [{item: null, soul: id}]})
575
+ api(_ctxid).next(null, res, _opt)
576
+ })
577
+ if (data !== null || retries >= 5) {
578
+ cb(data)
579
+ } else {
580
+ // Data not ready, retry after delay
581
+ await new Promise(resolve => setTimeout(resolve, 50))
582
+ attemptRead(retries + 1)
583
+ }
590
584
  }
591
585
  attemptRead()
592
586
  } else {
package/src/wire.js CHANGED
@@ -353,30 +353,30 @@ const Wire = opt => {
353
353
  // used whereas wire spec needs to handle clock skew for updates
354
354
  // across the network.
355
355
  const update = await Ham.mix(data, graph, opt.secure, listen)
356
- const none = Object.keys(update.now).length === 0
357
- if (none) {
358
- // Nothing to do.
359
- cb(null)
360
- return
361
- }
362
356
 
363
- if (!(await check(update.now, send, cb))) return
364
-
365
- // Seed pendingReferences with any new references from API calls
366
- for (const [soul, node] of Object.entries(update.now)) {
367
- if (node && typeof node === "object") {
368
- for (const [key, value] of Object.entries(node)) {
369
- const soulId = utils.rel.is(value)
370
- if (soulId) {
371
- // Add referenced soul to pending list
372
- pendingReferences.add(soulId)
357
+ if (Object.keys(update.now).length !== 0) {
358
+ if (!(await check(update.now, send, cb))) return
359
+
360
+ // Seed pendingReferences with any new references from API calls
361
+ for (const [soul, node] of Object.entries(update.now)) {
362
+ if (node && typeof node === "object") {
363
+ for (const [key, value] of Object.entries(node)) {
364
+ const soulId = utils.rel.is(value)
365
+ if (soulId) {
366
+ // Add referenced soul to pending list
367
+ pendingReferences.add(soulId)
368
+ }
373
369
  }
374
370
  }
375
371
  }
372
+
373
+ store.put(update.now, cb)
374
+ } else {
375
+ // No local update needed, but still callback
376
+ if (cb) cb(null)
376
377
  }
377
378
 
378
- store.put(update.now, cb)
379
- // Also put data on the wire spec.
379
+ // Always put data on the wire spec even if no local update needed
380
380
  const sendResult = send(
381
381
  JSON.stringify({
382
382
  "#": dup.track(utils.text.random(9)),
@@ -608,29 +608,34 @@ const Wire = opt => {
608
608
  }
609
609
 
610
610
  // Process next message in queue
611
- const data = messageQueue.shift()
612
- sendToPeers(data)
613
-
614
- // Start timeout for this message now that it's been sent
615
- const msg = JSON.parse(data)
616
- const trackId = msg["#"]
617
- if (trackId && pendingTimeouts.has(trackId)) {
618
- const timeoutConfig = pendingTimeouts.get(trackId)
619
- pendingTimeouts.delete(trackId)
620
-
621
- // Respond to callback with null if no response.
622
- timeoutConfig.timeoutId = setTimeout(() => {
623
- const cb = queue[trackId]
624
- if (cb) {
625
- const id = timeoutConfig.lex["#"]
626
- const ack = {[id]: null}
627
- if (typeof timeoutConfig.lex["."] === "string") {
628
- ack[id] = {[timeoutConfig.lex["."]]: null}
611
+ const data = messageQueue[0]
612
+ const sent = sendToPeers(data)
613
+
614
+ if (sent) {
615
+ // Only remove from queue if successfully sent
616
+ messageQueue.shift()
617
+
618
+ // Start timeout for this message now that it's been sent
619
+ const msg = JSON.parse(data)
620
+ const trackId = msg["#"]
621
+ if (trackId && pendingTimeouts.has(trackId)) {
622
+ const timeoutConfig = pendingTimeouts.get(trackId)
623
+ pendingTimeouts.delete(trackId)
624
+
625
+ // Respond to callback with null if no response.
626
+ timeoutConfig.timeoutId = setTimeout(() => {
627
+ const cb = queue[trackId]
628
+ if (cb) {
629
+ const id = timeoutConfig.lex["#"]
630
+ const ack = {[id]: null}
631
+ if (typeof timeoutConfig.lex["."] === "string") {
632
+ ack[id] = {[timeoutConfig.lex["."]]: null}
633
+ }
634
+ cb({put: ack})
635
+ delete queue[trackId]
629
636
  }
630
- cb({put: ack})
631
- delete queue[trackId]
632
- }
633
- }, timeoutConfig.wait)
637
+ }, timeoutConfig.wait)
638
+ }
634
639
  }
635
640
 
636
641
  // Schedule processing of next message if queue not empty
@@ -643,9 +648,11 @@ const Wire = opt => {
643
648
  }
644
649
 
645
650
  const sendToPeers = data => {
651
+ let sentToAtLeastOne = false
646
652
  peers.forEach(peer => {
647
653
  if (peer && peer.readyState === WebSocket.OPEN) {
648
654
  peer.send(data)
655
+ sentToAtLeastOne = true
649
656
  } else {
650
657
  const retryHandler = peer._retryHandler || createRetryHandler()
651
658
  peer._retryHandler = retryHandler
@@ -663,6 +670,7 @@ const Wire = opt => {
663
670
  }
664
671
  }
665
672
  })
673
+ return sentToAtLeastOne
666
674
  }
667
675
 
668
676
  const send = data => {