@mblaney/holster 1.0.27 → 1.0.28

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.27",
3
+ "version": "1.0.28",
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
@@ -67,12 +67,15 @@ const Holster = opt => {
67
67
  for (const key of Object.keys(msg.put[soul])) {
68
68
  const id = utils.rel.is(msg.put[soul][key])
69
69
  if (id) {
70
- // Due to message queuing, the related node might not be available yet
71
70
  // Retry with delays if we get null
72
71
  const attemptRead = async (retries = 0) => {
73
72
  const data = await new Promise(res => {
74
73
  const _ctxid = utils.text.random()
75
- allctx.set(_ctxid, {chain: [{item: null, soul: id}]})
74
+ const ctx = allctx.get(ctxid)
75
+ allctx.set(_ctxid, {
76
+ chain: [{item: null, soul: id}],
77
+ user: ctx ? ctx.user : null,
78
+ })
76
79
  api(_ctxid).next(null, res, _opt)
77
80
  })
78
81
  if (data !== null || retries >= 5) {
@@ -157,11 +160,7 @@ const Holster = opt => {
157
160
  {"#": soul, ".": item},
158
161
  async msg => {
159
162
  if (msg.err) {
160
- if (ctx.user || opt.secure) {
161
- console.log(`error getting ${soul}: ${msg.err}`)
162
- } else {
163
- console.log(`error getting ${item} on ${soul}: ${msg.err}`)
164
- }
163
+ console.log(`error getting ${item} on ${soul}: ${msg.err}`)
165
164
  if (cb) cb(null)
166
165
  return
167
166
  }
@@ -230,7 +229,7 @@ const Holster = opt => {
230
229
  if (cb) cb(null)
231
230
  }
232
231
  },
233
- request._opt,
232
+ {...request._opt, secure: ctx.user || opt.secure},
234
233
  )
235
234
  // Callback has been passed to next soul lookup or called above, so
236
235
  // return false as the calling code should not continue.
@@ -382,66 +381,70 @@ const Holster = opt => {
382
381
  // When result is true data is a property to put on the current soul.
383
382
  // Need to check if item is a rel and also set the node to null. (This
384
383
  // applies for any update from a rel to a property, not just null.)
385
- wire.get({"#": soul, ".": item}, async msg => {
386
- if (msg.err) {
387
- _ack(`error getting ${soul}: ${msg.err}`)
388
- return
389
- }
390
-
391
- let node = msg.put && msg.put[soul]
392
- const current = node && node[item]
393
- const id = utils.rel.is(current)
394
- if (!id) {
395
- // Not a rel, can just put the data.
396
- if (!node) node = {}
397
- node[item] = data
398
- const g = await graph(soul, node, ctx.user, _ack)
399
- if (g === null) return
400
-
401
- wire.put(g, _ack)
402
- return
403
- }
404
-
405
- wire.get({"#": id}, async msg => {
384
+ wire.get(
385
+ {"#": soul, ".": item},
386
+ async msg => {
406
387
  if (msg.err) {
407
- _ack(`error getting ${id}: ${msg.err}`)
388
+ _ack(`error getting ${soul}: ${msg.err}`)
408
389
  return
409
390
  }
410
391
 
411
- if (!msg.put || !msg.put[id]) {
412
- _ack(`error ${id} not found`)
392
+ let node = msg.put && msg.put[soul]
393
+ const current = node && node[item]
394
+ const id = utils.rel.is(current)
395
+ if (!id) {
396
+ // Not a rel, can just put the data.
397
+ if (!node) node = {}
398
+ node[item] = data
399
+ const g = await graph(soul, node, ctx.user, _ack)
400
+ if (g === null) return
401
+
402
+ wire.put(g, _ack)
413
403
  return
414
404
  }
415
405
 
416
- // null each of the properties on the node before putting data.
417
- for (const key of Object.keys(msg.put[id])) {
418
- if (
419
- key === "_" ||
420
- key === utils.userPublicKey ||
421
- key === utils.userSignature
422
- ) {
423
- continue
406
+ wire.get({"#": id}, async msg => {
407
+ if (msg.err) {
408
+ _ack(`error getting ${id}: ${msg.err}`)
409
+ return
424
410
  }
425
411
 
426
- const err = await new Promise(res => {
427
- const _ctxid = utils.text.random()
428
- const chain = [{item: key, soul: id}]
429
- allctx.set(_ctxid, {chain: chain, user: ctx.user})
430
- api(_ctxid).put(null, res)
431
- })
432
- if (err) {
433
- _ack(err)
412
+ if (!msg.put || !msg.put[id]) {
413
+ _ack(`error ${id} not found`)
434
414
  return
435
415
  }
436
- }
437
- if (!node) node = {}
438
- node[item] = data
439
- const g = await graph(soul, node, ctx.user, _ack)
440
- if (g === null) return
441
416
 
442
- wire.put(g, _ack)
443
- })
444
- })
417
+ // null each of the properties on the node before putting data.
418
+ for (const key of Object.keys(msg.put[id])) {
419
+ if (
420
+ key === "_" ||
421
+ key === utils.userPublicKey ||
422
+ key === utils.userSignature
423
+ ) {
424
+ continue
425
+ }
426
+
427
+ const err = await new Promise(res => {
428
+ const _ctxid = utils.text.random()
429
+ const chain = [{item: key, soul: id}]
430
+ allctx.set(_ctxid, {chain: chain, user: ctx.user})
431
+ api(_ctxid).put(null, res)
432
+ })
433
+ if (err) {
434
+ _ack(err)
435
+ return
436
+ }
437
+ }
438
+ if (!node) node = {}
439
+ node[item] = data
440
+ const g = await graph(soul, node, ctx.user, _ack)
441
+ if (g === null) return
442
+
443
+ wire.put(g, _ack)
444
+ })
445
+ },
446
+ {secure: ctx.user || opt.secure},
447
+ )
445
448
  return
446
449
  }
447
450
 
@@ -449,88 +452,97 @@ const Holster = opt => {
449
452
  // Need to check if a rel has already been added on the current node.
450
453
  // Use attemptRead to retry if data hasn't propagated yet.
451
454
  const attemptRead = (retries = 0) => {
452
- wire.get({"#": soul, ".": item}, async msg => {
453
- if (msg.err) {
454
- _ack(`error getting ${soul}.${item}: ${msg.err}`)
455
- return
456
- }
455
+ wire.get(
456
+ {"#": soul, ".": item},
457
+ async msg => {
458
+ if (msg.err) {
459
+ _ack(`error getting ${soul}.${item}: ${msg.err}`)
460
+ return
461
+ }
457
462
 
458
- let node = msg.put && msg.put[soul]
459
- const current = node && node[item]
463
+ let node = msg.put && msg.put[soul]
464
+ const current = node && node[item]
460
465
 
461
- // If we didn't find the item but still have retries, retry
462
- if (!current && retries < 5) {
463
- await new Promise(r => setTimeout(r, 50))
464
- return attemptRead(retries + 1)
465
- }
466
+ // If we didn't find the item but still have retries, retry
467
+ if (!current && retries < 5) {
468
+ await new Promise(r => setTimeout(r, 50))
469
+ return attemptRead(retries + 1)
470
+ }
466
471
 
467
- const id = utils.rel.is(current)
468
- if (!id) {
469
- // The current rel doesn't exist, so add it first.
470
- if (!node) node = {}
471
- node[item] = utils.rel.ify(utils.text.random())
472
- const g = await graph(soul, node, ctx.user, _ack)
473
- if (g === null) return
472
+ const id = utils.rel.is(current)
473
+ if (!id) {
474
+ // The current rel doesn't exist, so add it first.
475
+ if (!node) node = {}
476
+ node[item] = utils.rel.ify(utils.text.random())
477
+ const g = await graph(soul, node, ctx.user, _ack)
478
+ if (g === null) return
474
479
 
475
- wire.put(g, err => {
480
+ wire.put(g, err => {
481
+ if (err) {
482
+ _ack(`error putting ${item} on ${soul}: ${err}`)
483
+ } else {
484
+ const _ctxid = utils.text.random()
485
+ const chain = [{item: item, soul: soul}]
486
+ // Pass on the previous context's callback and user flag here.
487
+ allctx.set(_ctxid, {
488
+ chain: chain,
489
+ user: ctx.user,
490
+ cb: ctx.cb,
491
+ })
492
+ api(_ctxid).put(data)
493
+ }
494
+ })
495
+ return
496
+ }
497
+
498
+ const update = []
499
+ for (const key of result) {
500
+ const err = await new Promise(res => {
501
+ if (utils.obj.is(data[key]) && !utils.rel.is(data[key])) {
502
+ // Use the current rel as the context for nested objects.
503
+ const _ctxid = utils.text.random()
504
+ const chain = [{item: key, soul: id}]
505
+ allctx.set(_ctxid, {chain: chain, user: ctx.user})
506
+ api(_ctxid).put(data[key], res)
507
+ } else {
508
+ // Group the rest of the updates for put below.
509
+ update.push(key)
510
+ res(null)
511
+ }
512
+ })
476
513
  if (err) {
477
- _ack(`error putting ${item} on ${soul}: ${err}`)
478
- } else {
479
- const _ctxid = utils.text.random()
480
- const chain = [{item: item, soul: soul}]
481
- // Pass on the previous context's callback and user flag here.
482
- allctx.set(_ctxid, {chain: chain, user: ctx.user, cb: ctx.cb})
483
- api(_ctxid).put(data)
514
+ _ack(err, ctxid)
515
+ return
484
516
  }
485
- })
486
- return
487
- }
517
+ }
488
518
 
489
- const update = []
490
- for (const key of result) {
491
- const err = await new Promise(res => {
492
- if (utils.obj.is(data[key]) && !utils.rel.is(data[key])) {
493
- // Use the current rel as the context for nested objects.
494
- const _ctxid = utils.text.random()
495
- const chain = [{item: key, soul: id}]
496
- allctx.set(_ctxid, {chain: chain, user: ctx.user})
497
- api(_ctxid).put(data[key], res)
498
- } else {
499
- // Group the rest of the updates for put below.
500
- update.push(key)
501
- res(null)
502
- }
503
- })
504
- if (err) {
505
- _ack(err, ctxid)
519
+ if (update.length === 0) {
520
+ _ack(null)
506
521
  return
507
522
  }
508
- }
509
523
 
510
- if (update.length === 0) {
511
- _ack(null)
512
- return
513
- }
524
+ // The nested objects created above will also have rels on the
525
+ // parent object, so fetch the node so that the rest of the updates
526
+ // can be added.
527
+ wire.get({"#": id}, async msg => {
528
+ if (msg.err) {
529
+ _ack(`error getting ${id}: ${msg.err}`)
530
+ return
531
+ }
514
532
 
515
- // The nested objects created above will also have rels on the parent
516
- // object, so fetch the node so the rest of the updates can be added.
517
- wire.get({"#": id}, async msg => {
518
- if (msg.err) {
519
- _ack(`error getting ${id}: ${msg.err}`)
520
- return
521
- }
533
+ let node = msg.put && msg.put[id]
534
+ if (!node) node = {}
535
+ update.forEach(key => {
536
+ node[key] = data[key]
537
+ })
538
+ const g = await graph(id, node, ctx.user, _ack)
539
+ if (g === null) return
522
540
 
523
- let node = msg.put && msg.put[id]
524
- if (!node) node = {}
525
- update.forEach(key => {
526
- node[key] = data[key]
541
+ wire.put(g, _ack)
527
542
  })
528
- const g = await graph(id, node, ctx.user, _ack)
529
- if (g === null) return
530
-
531
- wire.put(g, _ack)
532
- })
533
- })
543
+ },
544
+ {secure: ctx.user || opt.secure},
545
+ )
534
546
  }
535
547
  attemptRead()
536
548
  },
@@ -556,8 +568,15 @@ const Holster = opt => {
556
568
  const {item, soul} = resolve({on: lex, _get: _get, _opt: _opt}, cb)
557
569
  if (!soul) return
558
570
 
571
+ // Get the context to check if it has user info
572
+ const ctx = allctx.get(ctxid)
573
+
559
574
  // Flag that this context is set from on and shouldn't be removed.
560
- allctx.set(ctxid, {chain: [{item: item, soul: soul}], on: true})
575
+ allctx.set(ctxid, {
576
+ chain: [{item: item, soul: soul}],
577
+ on: true,
578
+ user: ctx ? ctx.user : null,
579
+ })
561
580
  // Map the user's callback because it can also be passed to off,
562
581
  // so need a reference to it to compare them.
563
582
  // Create a new context for each listener invocation to avoid mutation
@@ -574,7 +593,10 @@ const Holster = opt => {
574
593
  const attemptRead = async (retries = 0) => {
575
594
  const data = await new Promise(res => {
576
595
  const _ctxid = utils.text.random()
577
- allctx.set(_ctxid, {chain: [{item: null, soul: id}]})
596
+ allctx.set(_ctxid, {
597
+ chain: [{item: null, soul: id}],
598
+ user: ctx ? ctx.user : null,
599
+ })
578
600
  api(_ctxid).next(null, res, _opt)
579
601
  })
580
602
  if (data !== null || retries >= 5) {
@@ -591,7 +613,7 @@ const Holster = opt => {
591
613
  cb(current !== undefined ? current : null)
592
614
  }
593
615
  },
594
- _opt,
616
+ {..._opt, secure: ctx.user || opt.secure},
595
617
  )
596
618
  })
597
619
 
@@ -637,7 +659,7 @@ const Holster = opt => {
637
659
  map.get(cb)()
638
660
  }
639
661
  },
640
- _opt,
662
+ {..._opt, secure: ctx.user || opt.secure},
641
663
  )
642
664
  },
643
665
  off: cb => {
package/src/sea.js CHANGED
@@ -264,7 +264,6 @@ const SEA = {
264
264
 
265
265
  const propSig = propertySignatures[k]
266
266
  if (!propSig) {
267
- console.log(`warning: property '${k}' missing signature`)
268
267
  continue
269
268
  }
270
269
 
package/src/store.js CHANGED
@@ -211,7 +211,7 @@ const Store = opt => {
211
211
  const radisk = Radisk(opt)
212
212
 
213
213
  return {
214
- get: (lex, cb) => {
214
+ get: (lex, cb, _opt) => {
215
215
  if (!lex || !utils.obj.is(lex)) {
216
216
  cb("lex required")
217
217
  return
@@ -221,8 +221,10 @@ const Store = opt => {
221
221
  return
222
222
  }
223
223
 
224
+ if (!_opt) _opt = {}
225
+
224
226
  var soul = lex["#"]
225
- var key = typeof lex["."] === "string" ? lex["."] : ""
227
+ var key = !_opt.secure && typeof lex["."] === "string" ? lex["."] : ""
226
228
  var node
227
229
  var signatures = {}
228
230
  const each = (value, key) => {
package/src/wire.js CHANGED
@@ -318,36 +318,40 @@ const Wire = opt => {
318
318
  return
319
319
  }
320
320
 
321
- store.get(lex, (err, ack) => {
322
- if (ack) {
323
- // Also send request on the wire to check for updates.
324
- const sendResult = send(request)
325
- if (sendResult && sendResult.err) {
326
- cb({err: sendResult.err})
321
+ store.get(
322
+ lex,
323
+ (err, ack) => {
324
+ if (ack) {
325
+ // Also send request on the wire to check for updates.
326
+ const sendResult = send(request)
327
+ if (sendResult && sendResult.err) {
328
+ cb({err: sendResult.err})
329
+ return
330
+ }
331
+ cb({put: ack, err: err})
327
332
  return
328
333
  }
329
- cb({put: ack, err: err})
330
- return
331
- }
332
334
 
333
- if (err) console.log(err)
335
+ if (err) console.log(err)
334
336
 
335
- queue[track] = cb
337
+ queue[track] = cb
336
338
 
337
- // Store timeout config to start after message is sent from queue
338
- pendingTimeouts.set(track, {
339
- lex: lex,
340
- wait: _opt.wait || 100,
341
- })
339
+ // Store timeout config to start after message is sent from queue
340
+ pendingTimeouts.set(track, {
341
+ lex: lex,
342
+ wait: _opt.wait || 100,
343
+ })
342
344
 
343
- const sendResult = send(request)
344
- if (sendResult && sendResult.err) {
345
- cb({err: sendResult.err})
346
- delete queue[track]
347
- pendingTimeouts.delete(track)
348
- return
349
- }
350
- })
345
+ const sendResult = send(request)
346
+ if (sendResult && sendResult.err) {
347
+ cb({err: sendResult.err})
348
+ delete queue[track]
349
+ pendingTimeouts.delete(track)
350
+ return
351
+ }
352
+ },
353
+ _opt,
354
+ )
351
355
  }
352
356
 
353
357
  const api = send => {