@mblaney/holster 1.0.0 → 1.0.1
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/ham.js +4 -5
- package/src/holster.js +63 -42
- package/test/holster.get.test.js +5 -1
- package/test/holster.put.test.js +5 -1
- package/test/holster.user.get.test.js +5 -1
- package/test/holster.user.on.test.js +5 -1
- package/test/holster.user.put.test.js +5 -1
package/package.json
CHANGED
package/src/ham.js
CHANGED
|
@@ -63,11 +63,10 @@ Ham.mix = async (change, graph, secure, listen) => {
|
|
|
63
63
|
}
|
|
64
64
|
}
|
|
65
65
|
if (verify) {
|
|
66
|
-
// Partial nodes can be read from disk,
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
if (!(await SEA.verify({m: node, s: sig}, {pub: pub}))) {
|
|
70
|
-
console.log(`error could not verify soul: ${soul}`)
|
|
66
|
+
// Partial nodes can be read from disk, which are ignored. This could be
|
|
67
|
+
// a missing signature or public key, or missing properties on the node
|
|
68
|
+
// which means verify won't work either.
|
|
69
|
+
if (!sig || !pub || !(await SEA.verify({m: node, s: sig}, {pub: pub}))) {
|
|
71
70
|
continue
|
|
72
71
|
}
|
|
73
72
|
}
|
package/src/holster.js
CHANGED
|
@@ -100,17 +100,21 @@ const Holster = opt => {
|
|
|
100
100
|
return utils.graph(soul, data)
|
|
101
101
|
}
|
|
102
102
|
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
103
|
+
// done takes a context id and returns a new callback function so that the
|
|
104
|
+
// callback is not overwritten by simultaneous requests.
|
|
105
|
+
const done = ctxid => {
|
|
106
|
+
return data => {
|
|
107
|
+
const ctx = allctx.get(ctxid)
|
|
108
|
+
if (ctx && typeof ctx.cb !== "undefined") {
|
|
109
|
+
// Use a timeout so that the context can be removed before data is
|
|
110
|
+
// returned to the callback (allows nested get calls).
|
|
111
|
+
setTimeout(() => ctx.cb(data), 1)
|
|
112
|
+
} else if (data) {
|
|
113
|
+
console.log("error no callback for data", data, "ctx", ctx)
|
|
114
|
+
}
|
|
115
|
+
// A context updated by "on" should only be removed by "off".
|
|
116
|
+
if (ctx && !ctx.on) allctx.delete(ctxid)
|
|
111
117
|
}
|
|
112
|
-
// A context updated by "on" should only be removed by "off".
|
|
113
|
-
if (ctx && !ctx.on) allctx.delete(ctxid)
|
|
114
118
|
}
|
|
115
119
|
|
|
116
120
|
const resolve = (request, cb) => {
|
|
@@ -258,13 +262,22 @@ const Holster = opt => {
|
|
|
258
262
|
allctx.set(ctxid, {chain: [{item: key, soul: "root"}], cb: cb})
|
|
259
263
|
if (!cb) return api(ctxid)
|
|
260
264
|
|
|
265
|
+
const _done = done(ctxid)
|
|
261
266
|
// When there's a callback need to resolve the context first.
|
|
262
|
-
const {soul} = resolve({get: lex, _opt: _opt},
|
|
263
|
-
if (soul) get(lex, soul,
|
|
267
|
+
const {soul} = resolve({get: lex, _opt: _opt}, _done)
|
|
268
|
+
if (soul) get(lex, soul, _done, _opt)
|
|
264
269
|
},
|
|
265
270
|
next: (key, lex, cb, _opt) => {
|
|
266
|
-
|
|
267
|
-
|
|
271
|
+
// ack needs to work the same as done, pass it the context id and then
|
|
272
|
+
// return a new function for the actual callback.
|
|
273
|
+
const ack = ctxid => {
|
|
274
|
+
return data => {
|
|
275
|
+
if (cb) {
|
|
276
|
+
cb(data)
|
|
277
|
+
} else {
|
|
278
|
+
done(ctxid)(data)
|
|
279
|
+
}
|
|
280
|
+
}
|
|
268
281
|
}
|
|
269
282
|
if (typeof lex === "function") {
|
|
270
283
|
_opt = cb
|
|
@@ -273,12 +286,13 @@ const Holster = opt => {
|
|
|
273
286
|
}
|
|
274
287
|
if (!ctxid) {
|
|
275
288
|
console.log("error please provide a key using get(key)")
|
|
276
|
-
|
|
289
|
+
if (cb) cb(null)
|
|
277
290
|
return
|
|
278
291
|
}
|
|
279
292
|
|
|
293
|
+
const _ack = ack(ctxid)
|
|
280
294
|
if (key === "" || key === "_") {
|
|
281
|
-
|
|
295
|
+
_ack(null)
|
|
282
296
|
return
|
|
283
297
|
}
|
|
284
298
|
|
|
@@ -304,20 +318,25 @@ const Holster = opt => {
|
|
|
304
318
|
if (!ctx.cb) return api(ctxid)
|
|
305
319
|
|
|
306
320
|
// When there's a callback need to resolve the context first.
|
|
307
|
-
const {soul} = resolve({get: lex, _opt: _opt},
|
|
308
|
-
if (soul) get(lex, soul,
|
|
321
|
+
const {soul} = resolve({get: lex, _opt: _opt}, _ack)
|
|
322
|
+
if (soul) get(lex, soul, _ack, _opt)
|
|
309
323
|
},
|
|
310
324
|
put: (data, set, cb) => {
|
|
311
325
|
if (typeof set === "function") {
|
|
312
326
|
cb = set
|
|
313
327
|
set = false
|
|
314
328
|
}
|
|
315
|
-
const ack =
|
|
316
|
-
|
|
329
|
+
const ack = ctxid => {
|
|
330
|
+
return data => {
|
|
331
|
+
if (cb) {
|
|
332
|
+
cb(data)
|
|
333
|
+
} else {
|
|
334
|
+
done(ctxid)(data)
|
|
335
|
+
}
|
|
336
|
+
}
|
|
317
337
|
}
|
|
318
|
-
|
|
319
338
|
if (!ctxid) {
|
|
320
|
-
|
|
339
|
+
if (cb) cb("error please provide a key using get(key)")
|
|
321
340
|
return
|
|
322
341
|
}
|
|
323
342
|
|
|
@@ -334,15 +353,16 @@ const Holster = opt => {
|
|
|
334
353
|
}
|
|
335
354
|
if (set) data = {[utils.text.random()]: data}
|
|
336
355
|
|
|
356
|
+
const _ack = ack(ctxid)
|
|
337
357
|
const result = check(data)
|
|
338
358
|
if (typeof result === "string") {
|
|
339
359
|
// All strings returned from check are errors, cannot continue.
|
|
340
|
-
|
|
360
|
+
_ack(result)
|
|
341
361
|
return
|
|
342
362
|
}
|
|
343
363
|
|
|
344
364
|
// Resolve the current context before putting data.
|
|
345
|
-
const {item, soul} = resolve({put: data},
|
|
365
|
+
const {item, soul} = resolve({put: data}, _ack)
|
|
346
366
|
if (!soul) return
|
|
347
367
|
|
|
348
368
|
if (result === true) {
|
|
@@ -354,7 +374,7 @@ const Holster = opt => {
|
|
|
354
374
|
ctx.user || opt.secure ? {"#": soul} : {"#": soul, ".": item}
|
|
355
375
|
wire.get(lex, async msg => {
|
|
356
376
|
if (msg.err) {
|
|
357
|
-
|
|
377
|
+
_ack(`error getting ${soul}: ${msg.err}`)
|
|
358
378
|
return
|
|
359
379
|
}
|
|
360
380
|
|
|
@@ -365,21 +385,21 @@ const Holster = opt => {
|
|
|
365
385
|
// Not a rel, can just put the data.
|
|
366
386
|
if (!node) node = {}
|
|
367
387
|
node[item] = data
|
|
368
|
-
const g = await graph(soul, node, ctx.user,
|
|
388
|
+
const g = await graph(soul, node, ctx.user, _ack)
|
|
369
389
|
if (g === null) return
|
|
370
390
|
|
|
371
|
-
wire.put(g,
|
|
391
|
+
wire.put(g, _ack)
|
|
372
392
|
return
|
|
373
393
|
}
|
|
374
394
|
|
|
375
395
|
wire.get({"#": id}, async msg => {
|
|
376
396
|
if (msg.err) {
|
|
377
|
-
|
|
397
|
+
_ack(`error getting ${id}: ${msg.err}`)
|
|
378
398
|
return
|
|
379
399
|
}
|
|
380
400
|
|
|
381
401
|
if (!msg.put || !msg.put[id]) {
|
|
382
|
-
|
|
402
|
+
_ack(`error ${id} not found`)
|
|
383
403
|
return
|
|
384
404
|
}
|
|
385
405
|
|
|
@@ -400,16 +420,16 @@ const Holster = opt => {
|
|
|
400
420
|
api(_ctxid).put(null, res)
|
|
401
421
|
})
|
|
402
422
|
if (err) {
|
|
403
|
-
|
|
423
|
+
_ack(err)
|
|
404
424
|
return
|
|
405
425
|
}
|
|
406
426
|
}
|
|
407
427
|
if (!node) node = {}
|
|
408
428
|
node[item] = data
|
|
409
|
-
const g = await graph(soul, node, ctx.user,
|
|
429
|
+
const g = await graph(soul, node, ctx.user, _ack)
|
|
410
430
|
if (g === null) return
|
|
411
431
|
|
|
412
|
-
wire.put(g,
|
|
432
|
+
wire.put(g, _ack)
|
|
413
433
|
})
|
|
414
434
|
})
|
|
415
435
|
return
|
|
@@ -422,7 +442,7 @@ const Holster = opt => {
|
|
|
422
442
|
ctx.user || opt.secure ? {"#": soul} : {"#": soul, ".": item}
|
|
423
443
|
wire.get(lex, async msg => {
|
|
424
444
|
if (msg.err) {
|
|
425
|
-
|
|
445
|
+
_ack(`error getting ${soul}.${item}: ${msg.err}`)
|
|
426
446
|
return
|
|
427
447
|
}
|
|
428
448
|
|
|
@@ -433,12 +453,12 @@ const Holster = opt => {
|
|
|
433
453
|
// The current rel doesn't exist, so add it first.
|
|
434
454
|
if (!node) node = {}
|
|
435
455
|
node[item] = utils.rel.ify(utils.text.random())
|
|
436
|
-
const g = await graph(soul, node, ctx.user,
|
|
456
|
+
const g = await graph(soul, node, ctx.user, _ack)
|
|
437
457
|
if (g === null) return
|
|
438
458
|
|
|
439
459
|
wire.put(g, err => {
|
|
440
460
|
if (err) {
|
|
441
|
-
|
|
461
|
+
_ack(`error putting ${item} on ${soul}: ${err}`)
|
|
442
462
|
} else {
|
|
443
463
|
const _ctxid = utils.text.random()
|
|
444
464
|
const chain = [{item: item, soul: soul}]
|
|
@@ -466,13 +486,13 @@ const Holster = opt => {
|
|
|
466
486
|
}
|
|
467
487
|
})
|
|
468
488
|
if (err) {
|
|
469
|
-
|
|
489
|
+
_ack(err, ctxid)
|
|
470
490
|
return
|
|
471
491
|
}
|
|
472
492
|
}
|
|
473
493
|
|
|
474
494
|
if (update.length === 0) {
|
|
475
|
-
|
|
495
|
+
_ack(null)
|
|
476
496
|
return
|
|
477
497
|
}
|
|
478
498
|
|
|
@@ -480,7 +500,7 @@ const Holster = opt => {
|
|
|
480
500
|
// object, so fetch the node so the rest of the updates can be added.
|
|
481
501
|
wire.get({"#": id}, async msg => {
|
|
482
502
|
if (msg.err) {
|
|
483
|
-
|
|
503
|
+
_ack(`error getting ${id}: ${msg.err}`)
|
|
484
504
|
return
|
|
485
505
|
}
|
|
486
506
|
|
|
@@ -489,10 +509,10 @@ const Holster = opt => {
|
|
|
489
509
|
update.forEach(key => {
|
|
490
510
|
node[key] = data[key]
|
|
491
511
|
})
|
|
492
|
-
const g = await graph(id, node, ctx.user,
|
|
512
|
+
const g = await graph(id, node, ctx.user, _ack)
|
|
493
513
|
if (g === null) return
|
|
494
514
|
|
|
495
|
-
wire.put(g,
|
|
515
|
+
wire.put(g, _ack)
|
|
496
516
|
})
|
|
497
517
|
})
|
|
498
518
|
},
|
|
@@ -618,8 +638,9 @@ const Holster = opt => {
|
|
|
618
638
|
if (!cb) return api(ctxid)
|
|
619
639
|
|
|
620
640
|
// When there's a callback need to resolve the context first.
|
|
621
|
-
const
|
|
622
|
-
|
|
641
|
+
const _done = done(ctxid)
|
|
642
|
+
const {soul} = resolve({get: lex}, _done)
|
|
643
|
+
if (soul) get(lex, soul, _done, _opt)
|
|
623
644
|
}
|
|
624
645
|
}
|
|
625
646
|
return user
|
package/test/holster.get.test.js
CHANGED
|
@@ -37,12 +37,16 @@ describe("holster.get", () => {
|
|
|
37
37
|
})
|
|
38
38
|
|
|
39
39
|
test("get unknown keys in for loop callbacks null", (t, done) => {
|
|
40
|
+
let count = 0
|
|
40
41
|
for (let i = 0; i < 5; i++) {
|
|
41
42
|
holster.get("unknown" + i, data => {
|
|
42
43
|
assert.equal(data, null)
|
|
43
|
-
|
|
44
|
+
count++
|
|
44
45
|
})
|
|
45
46
|
}
|
|
47
|
+
setTimeout(() => {
|
|
48
|
+
if (count === 5) done()
|
|
49
|
+
}, 200)
|
|
46
50
|
})
|
|
47
51
|
|
|
48
52
|
test("nested unknown keys both callbacks null", (t, done) => {
|
package/test/holster.put.test.js
CHANGED
|
@@ -71,12 +71,16 @@ describe("holster.put", () => {
|
|
|
71
71
|
}
|
|
72
72
|
|
|
73
73
|
setTimeout(() => {
|
|
74
|
+
let count = 0
|
|
74
75
|
for (let i = 0; i < 5; i++) {
|
|
75
76
|
holster.get("for" + i, data => {
|
|
76
77
|
assert.equal(data, i)
|
|
77
|
-
|
|
78
|
+
count++
|
|
78
79
|
})
|
|
79
80
|
}
|
|
81
|
+
setTimeout(() => {
|
|
82
|
+
if (count === 5) done()
|
|
83
|
+
}, 200)
|
|
80
84
|
}, 200)
|
|
81
85
|
})
|
|
82
86
|
|
|
@@ -63,12 +63,16 @@ describe("holster.user.get", () => {
|
|
|
63
63
|
})
|
|
64
64
|
|
|
65
65
|
test("get unknown keys in for loop callbacks null", (t, done) => {
|
|
66
|
+
let count = 0
|
|
66
67
|
for (let i = 0; i < 5; i++) {
|
|
67
68
|
user.get("unknown" + i, data => {
|
|
68
69
|
assert.equal(data, null)
|
|
69
|
-
|
|
70
|
+
count++
|
|
70
71
|
})
|
|
71
72
|
}
|
|
73
|
+
setTimeout(() => {
|
|
74
|
+
if (count === 5) done()
|
|
75
|
+
}, 200)
|
|
72
76
|
})
|
|
73
77
|
|
|
74
78
|
test("nested get unknown key callback null", (t, done) => {
|
|
@@ -101,11 +101,12 @@ describe("holster.user.on", () => {
|
|
|
101
101
|
|
|
102
102
|
// Need to wait until after all initial puts are done to set on listeners.
|
|
103
103
|
setTimeout(async () => {
|
|
104
|
+
let count = 0
|
|
104
105
|
for (let i = 0; i < 5; i++) {
|
|
105
106
|
user.get("for" + i).on(data => {
|
|
106
107
|
assert.equal(data, "update" + i)
|
|
107
108
|
user.get("for" + i).off()
|
|
108
|
-
|
|
109
|
+
count++
|
|
109
110
|
})
|
|
110
111
|
}
|
|
111
112
|
|
|
@@ -117,6 +118,9 @@ describe("holster.user.on", () => {
|
|
|
117
118
|
})
|
|
118
119
|
assert.equal(err, null)
|
|
119
120
|
}
|
|
121
|
+
setTimeout(() => {
|
|
122
|
+
if (count === 5) done()
|
|
123
|
+
}, 500)
|
|
120
124
|
}, 500)
|
|
121
125
|
}, 1000)
|
|
122
126
|
})
|
|
@@ -98,12 +98,16 @@ describe("holster.user.put", () => {
|
|
|
98
98
|
})()
|
|
99
99
|
|
|
100
100
|
setTimeout(async () => {
|
|
101
|
+
let count = 0
|
|
101
102
|
for (let i = 0; i < 5; i++) {
|
|
102
103
|
user.get("for" + i, data => {
|
|
103
104
|
assert.equal(data, i)
|
|
104
|
-
|
|
105
|
+
count++
|
|
105
106
|
})
|
|
106
107
|
}
|
|
108
|
+
setTimeout(() => {
|
|
109
|
+
if (count === 5) done()
|
|
110
|
+
}, 200)
|
|
107
111
|
}, 500)
|
|
108
112
|
})
|
|
109
113
|
|