@mblaney/holster 1.0.27 → 1.0.29
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/build/holster.js +3 -3
- package/build/holster.js.map +3 -3
- package/package.json +1 -1
- package/src/get.js +14 -0
- package/src/ham.js +0 -3
- package/src/holster.js +151 -129
- package/src/sea.js +0 -1
- package/src/store.js +4 -2
- package/src/wire.js +44 -78
package/package.json
CHANGED
package/src/get.js
CHANGED
|
@@ -32,6 +32,20 @@ const Get = (lex, graph) => {
|
|
|
32
32
|
signatures[key] = graph[soul]._["s"][key]
|
|
33
33
|
}
|
|
34
34
|
}
|
|
35
|
+
|
|
36
|
+
// Always include userPublicKey for verification, regardless of filter
|
|
37
|
+
if (userPublicKey && typeof graph[soul][userPublicKey] !== "undefined") {
|
|
38
|
+
node[userPublicKey] = graph[soul][userPublicKey]
|
|
39
|
+
node._[">"][userPublicKey] = graph[soul]._[">"][userPublicKey]
|
|
40
|
+
const pkState = graph[soul]._[">"][userPublicKey]
|
|
41
|
+
if (graph[soul]._["s"]) {
|
|
42
|
+
if (graph[soul]._["s"][pkState]) {
|
|
43
|
+
signatures[pkState] = graph[soul]._["s"][pkState]
|
|
44
|
+
} else if (graph[soul]._["s"][userPublicKey]) {
|
|
45
|
+
signatures[userPublicKey] = graph[soul]._["s"][userPublicKey]
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
35
49
|
} else {
|
|
36
50
|
for (const key of Object.keys(graph[soul])) {
|
|
37
51
|
// Always include userPublicKey for verification, regardless of filter
|
package/src/ham.js
CHANGED
|
@@ -130,9 +130,6 @@ Ham.mix = async (change, graph, secure, listen) => {
|
|
|
130
130
|
for (const key of Object.keys(node)) {
|
|
131
131
|
if (key === "_") continue
|
|
132
132
|
|
|
133
|
-
// Skip metadata fields (including userSignature for old data)
|
|
134
|
-
if (key === utils.userSignature || key === utils.userPublicKey) continue
|
|
135
|
-
|
|
136
133
|
// Properties without signatures in this update are left unchanged
|
|
137
134
|
if (validProperties.has(soul) && !validProperties.get(soul).has(key)) {
|
|
138
135
|
continue
|
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.
|
|
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
|
-
|
|
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(
|
|
386
|
-
|
|
387
|
-
|
|
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 ${
|
|
388
|
+
_ack(`error getting ${soul}: ${msg.err}`)
|
|
408
389
|
return
|
|
409
390
|
}
|
|
410
391
|
|
|
411
|
-
|
|
412
|
-
|
|
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
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
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
|
-
|
|
427
|
-
|
|
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
|
-
|
|
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(
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
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
|
-
|
|
459
|
-
|
|
463
|
+
let node = msg.put && msg.put[soul]
|
|
464
|
+
const current = node && node[item]
|
|
460
465
|
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
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
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
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
|
-
|
|
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(
|
|
478
|
-
|
|
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
|
-
|
|
490
|
-
|
|
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
|
-
|
|
511
|
-
|
|
512
|
-
|
|
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
|
|
526
|
+
// updates 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
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
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
|
-
|
|
524
|
-
if (!node) node = {}
|
|
525
|
-
update.forEach(key => {
|
|
526
|
-
node[key] = data[key]
|
|
541
|
+
wire.put(g, _ack)
|
|
527
542
|
})
|
|
528
|
-
|
|
529
|
-
|
|
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, {
|
|
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, {
|
|
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
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
|
@@ -197,46 +197,6 @@ const Wire = opt => {
|
|
|
197
197
|
const rateLimiter = createRateLimiter(isTestEnv)
|
|
198
198
|
const connectionManager = createConnectionManager(opt.maxConnections || 1000)
|
|
199
199
|
|
|
200
|
-
// The check function is required because user data must provide a public key
|
|
201
|
-
// so that it can be verified. The public key might verify the provided
|
|
202
|
-
// signature but not actually match the user under which the data is being
|
|
203
|
-
// stored. To avoid this, the current data on a soul needs to be checked to
|
|
204
|
-
// make sure the stored public key matches the one provided with the update.
|
|
205
|
-
const check = async (data, send, cb) => {
|
|
206
|
-
for (const soul of Object.keys(data)) {
|
|
207
|
-
const msg = await new Promise(res => {
|
|
208
|
-
getWithCallback({"#": soul}, res, send)
|
|
209
|
-
})
|
|
210
|
-
if (msg.err) {
|
|
211
|
-
if (cb) cb(msg.err)
|
|
212
|
-
return false
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
const node = data[soul]
|
|
216
|
-
const key = utils.userPublicKey
|
|
217
|
-
// If there is no current node then the data is ok to write without
|
|
218
|
-
// matching public keys, as the provided soul also needs a rel on the
|
|
219
|
-
// parent node which then also requires checking. Otherwise publc keys
|
|
220
|
-
// need to match for existing data.
|
|
221
|
-
if (!msg.put || !msg.put[soul] || msg.put[soul][key] === node[key]) {
|
|
222
|
-
continue
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
// If a soul exists but does not have a public key, then one should not be
|
|
226
|
-
// added because the node is not user data. The above check fails in this
|
|
227
|
-
// case if a public key is provided. Note that this is only an error case
|
|
228
|
-
// if called via the API, which is when a callback is provided here.
|
|
229
|
-
// (The wire spec can fetch and put data on the wire without a signature
|
|
230
|
-
// or public key and this can be ignored.)
|
|
231
|
-
if (cb) {
|
|
232
|
-
cb(`error in wire check public key does not match for soul: ${soul}`)
|
|
233
|
-
}
|
|
234
|
-
return false
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
return true
|
|
238
|
-
}
|
|
239
|
-
|
|
240
200
|
const get = (msg, send) => {
|
|
241
201
|
const ack = Get(msg.get, graph)
|
|
242
202
|
if (ack) {
|
|
@@ -248,16 +208,22 @@ const Wire = opt => {
|
|
|
248
208
|
}),
|
|
249
209
|
)
|
|
250
210
|
} else {
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
211
|
+
// Always pass secure to ensure public key is fetched. User data may be
|
|
212
|
+
// requested that requires the public key for verification.
|
|
213
|
+
store.get(
|
|
214
|
+
msg.get,
|
|
215
|
+
(err, ack) => {
|
|
216
|
+
send(
|
|
217
|
+
JSON.stringify({
|
|
218
|
+
"#": dup.track(utils.text.random(9)),
|
|
219
|
+
"@": msg["#"],
|
|
220
|
+
put: ack,
|
|
221
|
+
err: err,
|
|
222
|
+
}),
|
|
223
|
+
)
|
|
224
|
+
},
|
|
225
|
+
{secure: true},
|
|
226
|
+
)
|
|
261
227
|
}
|
|
262
228
|
}
|
|
263
229
|
|
|
@@ -275,8 +241,6 @@ const Wire = opt => {
|
|
|
275
241
|
return
|
|
276
242
|
}
|
|
277
243
|
|
|
278
|
-
if (!(await check(update.now, send))) return
|
|
279
|
-
|
|
280
244
|
store.put(update.now, err => {
|
|
281
245
|
send(
|
|
282
246
|
JSON.stringify({
|
|
@@ -318,36 +282,40 @@ const Wire = opt => {
|
|
|
318
282
|
return
|
|
319
283
|
}
|
|
320
284
|
|
|
321
|
-
store.get(
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
285
|
+
store.get(
|
|
286
|
+
lex,
|
|
287
|
+
(err, ack) => {
|
|
288
|
+
if (ack) {
|
|
289
|
+
// Also send request on the wire to check for updates.
|
|
290
|
+
const sendResult = send(request)
|
|
291
|
+
if (sendResult && sendResult.err) {
|
|
292
|
+
cb({err: sendResult.err})
|
|
293
|
+
return
|
|
294
|
+
}
|
|
295
|
+
cb({put: ack, err: err})
|
|
327
296
|
return
|
|
328
297
|
}
|
|
329
|
-
cb({put: ack, err: err})
|
|
330
|
-
return
|
|
331
|
-
}
|
|
332
298
|
|
|
333
|
-
|
|
299
|
+
if (err) console.log(err)
|
|
334
300
|
|
|
335
|
-
|
|
301
|
+
queue[track] = cb
|
|
336
302
|
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
303
|
+
// Store timeout config to start after message is sent from queue
|
|
304
|
+
pendingTimeouts.set(track, {
|
|
305
|
+
lex: lex,
|
|
306
|
+
wait: _opt.wait || 100,
|
|
307
|
+
})
|
|
342
308
|
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
309
|
+
const sendResult = send(request)
|
|
310
|
+
if (sendResult && sendResult.err) {
|
|
311
|
+
cb({err: sendResult.err})
|
|
312
|
+
delete queue[track]
|
|
313
|
+
pendingTimeouts.delete(track)
|
|
314
|
+
return
|
|
315
|
+
}
|
|
316
|
+
},
|
|
317
|
+
_opt,
|
|
318
|
+
)
|
|
351
319
|
}
|
|
352
320
|
|
|
353
321
|
const api = send => {
|
|
@@ -374,8 +342,6 @@ const Wire = opt => {
|
|
|
374
342
|
return
|
|
375
343
|
}
|
|
376
344
|
|
|
377
|
-
if (!(await check(update.now, send, cb))) return
|
|
378
|
-
|
|
379
345
|
// Seed pendingReferences with any new references from API calls
|
|
380
346
|
for (const [soul, node] of Object.entries(update.now)) {
|
|
381
347
|
if (node && typeof node === "object") {
|