@mblaney/holster 1.0.0 → 1.0.2
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 +66 -44
- package/src/user.js +102 -90
- 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) => {
|
|
@@ -225,7 +229,7 @@ const Holster = opt => {
|
|
|
225
229
|
// The context has been resolved but it does not include the requested
|
|
226
230
|
// node, which requires one more lookup.
|
|
227
231
|
ctx.chain.push({item: null, soul: null})
|
|
228
|
-
api(ctxid).next(null, request.get, cb)
|
|
232
|
+
api(ctxid).next(null, request.get, cb, request._opt)
|
|
229
233
|
return false
|
|
230
234
|
}
|
|
231
235
|
|
|
@@ -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,17 @@ 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
|
-
// Resolve the current context before putting data.
|
|
345
|
-
|
|
364
|
+
// Resolve the current context before putting data. (Note that set is
|
|
365
|
+
// not passed to resolve because it's already been applied above.)
|
|
366
|
+
const {item, soul} = resolve({put: data}, _ack)
|
|
346
367
|
if (!soul) return
|
|
347
368
|
|
|
348
369
|
if (result === true) {
|
|
@@ -354,7 +375,7 @@ const Holster = opt => {
|
|
|
354
375
|
ctx.user || opt.secure ? {"#": soul} : {"#": soul, ".": item}
|
|
355
376
|
wire.get(lex, async msg => {
|
|
356
377
|
if (msg.err) {
|
|
357
|
-
|
|
378
|
+
_ack(`error getting ${soul}: ${msg.err}`)
|
|
358
379
|
return
|
|
359
380
|
}
|
|
360
381
|
|
|
@@ -365,21 +386,21 @@ const Holster = opt => {
|
|
|
365
386
|
// Not a rel, can just put the data.
|
|
366
387
|
if (!node) node = {}
|
|
367
388
|
node[item] = data
|
|
368
|
-
const g = await graph(soul, node, ctx.user,
|
|
389
|
+
const g = await graph(soul, node, ctx.user, _ack)
|
|
369
390
|
if (g === null) return
|
|
370
391
|
|
|
371
|
-
wire.put(g,
|
|
392
|
+
wire.put(g, _ack)
|
|
372
393
|
return
|
|
373
394
|
}
|
|
374
395
|
|
|
375
396
|
wire.get({"#": id}, async msg => {
|
|
376
397
|
if (msg.err) {
|
|
377
|
-
|
|
398
|
+
_ack(`error getting ${id}: ${msg.err}`)
|
|
378
399
|
return
|
|
379
400
|
}
|
|
380
401
|
|
|
381
402
|
if (!msg.put || !msg.put[id]) {
|
|
382
|
-
|
|
403
|
+
_ack(`error ${id} not found`)
|
|
383
404
|
return
|
|
384
405
|
}
|
|
385
406
|
|
|
@@ -400,16 +421,16 @@ const Holster = opt => {
|
|
|
400
421
|
api(_ctxid).put(null, res)
|
|
401
422
|
})
|
|
402
423
|
if (err) {
|
|
403
|
-
|
|
424
|
+
_ack(err)
|
|
404
425
|
return
|
|
405
426
|
}
|
|
406
427
|
}
|
|
407
428
|
if (!node) node = {}
|
|
408
429
|
node[item] = data
|
|
409
|
-
const g = await graph(soul, node, ctx.user,
|
|
430
|
+
const g = await graph(soul, node, ctx.user, _ack)
|
|
410
431
|
if (g === null) return
|
|
411
432
|
|
|
412
|
-
wire.put(g,
|
|
433
|
+
wire.put(g, _ack)
|
|
413
434
|
})
|
|
414
435
|
})
|
|
415
436
|
return
|
|
@@ -422,7 +443,7 @@ const Holster = opt => {
|
|
|
422
443
|
ctx.user || opt.secure ? {"#": soul} : {"#": soul, ".": item}
|
|
423
444
|
wire.get(lex, async msg => {
|
|
424
445
|
if (msg.err) {
|
|
425
|
-
|
|
446
|
+
_ack(`error getting ${soul}.${item}: ${msg.err}`)
|
|
426
447
|
return
|
|
427
448
|
}
|
|
428
449
|
|
|
@@ -433,12 +454,12 @@ const Holster = opt => {
|
|
|
433
454
|
// The current rel doesn't exist, so add it first.
|
|
434
455
|
if (!node) node = {}
|
|
435
456
|
node[item] = utils.rel.ify(utils.text.random())
|
|
436
|
-
const g = await graph(soul, node, ctx.user,
|
|
457
|
+
const g = await graph(soul, node, ctx.user, _ack)
|
|
437
458
|
if (g === null) return
|
|
438
459
|
|
|
439
460
|
wire.put(g, err => {
|
|
440
461
|
if (err) {
|
|
441
|
-
|
|
462
|
+
_ack(`error putting ${item} on ${soul}: ${err}`)
|
|
442
463
|
} else {
|
|
443
464
|
const _ctxid = utils.text.random()
|
|
444
465
|
const chain = [{item: item, soul: soul}]
|
|
@@ -466,13 +487,13 @@ const Holster = opt => {
|
|
|
466
487
|
}
|
|
467
488
|
})
|
|
468
489
|
if (err) {
|
|
469
|
-
|
|
490
|
+
_ack(err, ctxid)
|
|
470
491
|
return
|
|
471
492
|
}
|
|
472
493
|
}
|
|
473
494
|
|
|
474
495
|
if (update.length === 0) {
|
|
475
|
-
|
|
496
|
+
_ack(null)
|
|
476
497
|
return
|
|
477
498
|
}
|
|
478
499
|
|
|
@@ -480,7 +501,7 @@ const Holster = opt => {
|
|
|
480
501
|
// object, so fetch the node so the rest of the updates can be added.
|
|
481
502
|
wire.get({"#": id}, async msg => {
|
|
482
503
|
if (msg.err) {
|
|
483
|
-
|
|
504
|
+
_ack(`error getting ${id}: ${msg.err}`)
|
|
484
505
|
return
|
|
485
506
|
}
|
|
486
507
|
|
|
@@ -489,10 +510,10 @@ const Holster = opt => {
|
|
|
489
510
|
update.forEach(key => {
|
|
490
511
|
node[key] = data[key]
|
|
491
512
|
})
|
|
492
|
-
const g = await graph(id, node, ctx.user,
|
|
513
|
+
const g = await graph(id, node, ctx.user, _ack)
|
|
493
514
|
if (g === null) return
|
|
494
515
|
|
|
495
|
-
wire.put(g,
|
|
516
|
+
wire.put(g, _ack)
|
|
496
517
|
})
|
|
497
518
|
})
|
|
498
519
|
},
|
|
@@ -618,8 +639,9 @@ const Holster = opt => {
|
|
|
618
639
|
if (!cb) return api(ctxid)
|
|
619
640
|
|
|
620
641
|
// When there's a callback need to resolve the context first.
|
|
621
|
-
const
|
|
622
|
-
|
|
642
|
+
const _done = done(ctxid)
|
|
643
|
+
const {soul} = resolve({get: lex, _opt: _opt}, _done)
|
|
644
|
+
if (soul) get(lex, soul, _done, _opt)
|
|
623
645
|
}
|
|
624
646
|
}
|
|
625
647
|
return user
|
package/src/user.js
CHANGED
|
@@ -27,53 +27,57 @@ const User = (opt, wire) => {
|
|
|
27
27
|
}
|
|
28
28
|
|
|
29
29
|
const pub = pubs.shift()
|
|
30
|
-
wire.get(
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
30
|
+
wire.get(
|
|
31
|
+
{"#": pub},
|
|
32
|
+
async msg => {
|
|
33
|
+
if (msg.err) {
|
|
34
|
+
done(`error getting ${pub}: ${msg.err}`)
|
|
35
|
+
return
|
|
36
|
+
}
|
|
35
37
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
+
const data = msg.put && msg.put[pub]
|
|
39
|
+
if (!data || !data.auth) return next()
|
|
38
40
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
41
|
+
const auth = JSON.parse(data.auth)
|
|
42
|
+
const work = await SEA.work(password, auth.salt)
|
|
43
|
+
const dec = await SEA.decrypt(auth.enc, work)
|
|
44
|
+
if (!dec) return next()
|
|
43
45
|
|
|
44
|
-
|
|
45
|
-
username: username,
|
|
46
|
-
pub: data.pub,
|
|
47
|
-
epub: data.epub,
|
|
48
|
-
priv: dec.priv,
|
|
49
|
-
epriv: dec.epriv,
|
|
50
|
-
}
|
|
51
|
-
if (newPassword !== "") {
|
|
52
|
-
// Encrypt private key using new password and a new salt.
|
|
53
|
-
const salt = utils.text.random(64)
|
|
54
|
-
const work = await SEA.work(newPassword, salt)
|
|
55
|
-
const enc = await SEA.encrypt(dec, work)
|
|
56
|
-
// Put all fields so that verification applies to the whole node.
|
|
57
|
-
const update = {
|
|
46
|
+
user.is = {
|
|
58
47
|
username: username,
|
|
59
48
|
pub: data.pub,
|
|
60
49
|
epub: data.epub,
|
|
61
|
-
|
|
50
|
+
priv: dec.priv,
|
|
51
|
+
epriv: dec.epriv,
|
|
62
52
|
}
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
53
|
+
if (newPassword !== "") {
|
|
54
|
+
// Encrypt private key using new password and a new salt.
|
|
55
|
+
const salt = utils.text.random(64)
|
|
56
|
+
const work = await SEA.work(newPassword, salt)
|
|
57
|
+
const enc = await SEA.encrypt(dec, work)
|
|
58
|
+
// Put all fields so that verification applies to the whole node.
|
|
59
|
+
const update = {
|
|
60
|
+
username: username,
|
|
61
|
+
pub: data.pub,
|
|
62
|
+
epub: data.epub,
|
|
63
|
+
auth: JSON.stringify({enc: enc, salt: salt}),
|
|
70
64
|
}
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
65
|
+
const signed = await SEA.sign(update, user.is)
|
|
66
|
+
const graph = utils.graph(pub, signed.m, signed.s, data.pub)
|
|
67
|
+
wire.put(graph, err => {
|
|
68
|
+
if (err) {
|
|
69
|
+
done(`error putting ${update} on ${pub}: ${err}`)
|
|
70
|
+
} else {
|
|
71
|
+
done(null)
|
|
72
|
+
}
|
|
73
|
+
})
|
|
74
|
+
return
|
|
75
|
+
}
|
|
74
76
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
+
return done(null)
|
|
78
|
+
},
|
|
79
|
+
{wait: 1000},
|
|
80
|
+
)
|
|
77
81
|
}
|
|
78
82
|
|
|
79
83
|
if (retries > 9) {
|
|
@@ -82,21 +86,25 @@ const User = (opt, wire) => {
|
|
|
82
86
|
}
|
|
83
87
|
|
|
84
88
|
const soul = "~@" + username
|
|
85
|
-
wire.get(
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
if (!data) return retry(username)
|
|
89
|
+
wire.get(
|
|
90
|
+
{"#": soul},
|
|
91
|
+
async msg => {
|
|
92
|
+
if (msg.err) {
|
|
93
|
+
done(`error getting ${soul}: ${msg.err}`)
|
|
94
|
+
return
|
|
95
|
+
}
|
|
93
96
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
97
|
+
const data = msg.put && msg.put[soul]
|
|
98
|
+
if (!data) return retry(username)
|
|
99
|
+
|
|
100
|
+
delete msg.put[soul]._
|
|
101
|
+
// Usernames aren't guaranteed to be unique, so store the list and then
|
|
102
|
+
// try each of them until one is successful with the given password.
|
|
103
|
+
pubs = Object.keys(data)
|
|
104
|
+
next()
|
|
105
|
+
},
|
|
106
|
+
{wait: 1000},
|
|
107
|
+
)
|
|
100
108
|
}
|
|
101
109
|
|
|
102
110
|
const user = {
|
|
@@ -124,53 +132,57 @@ const User = (opt, wire) => {
|
|
|
124
132
|
creating = true
|
|
125
133
|
|
|
126
134
|
const soul = "~@" + username
|
|
127
|
-
wire.get(
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
creating = false
|
|
136
|
-
ack("Username already exists")
|
|
137
|
-
return
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
const salt = utils.text.random(64)
|
|
141
|
-
const work = await SEA.work(password, salt)
|
|
142
|
-
const pair = await SEA.pair()
|
|
143
|
-
const priv = {priv: pair.priv, epriv: pair.epriv}
|
|
144
|
-
const enc = await SEA.encrypt(priv, work)
|
|
145
|
-
const data = {
|
|
146
|
-
username: username,
|
|
147
|
-
pub: pair.pub,
|
|
148
|
-
epub: pair.epub,
|
|
149
|
-
auth: JSON.stringify({enc: enc, salt: salt}),
|
|
150
|
-
}
|
|
135
|
+
wire.get(
|
|
136
|
+
{"#": soul},
|
|
137
|
+
async msg => {
|
|
138
|
+
if (msg.err) {
|
|
139
|
+
creating = false
|
|
140
|
+
ack(`error getting ${soul}: ${msg.err}`)
|
|
141
|
+
return
|
|
142
|
+
}
|
|
151
143
|
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
wire.put(graph, err => {
|
|
156
|
-
creating = false
|
|
157
|
-
if (err) {
|
|
158
|
-
ack(`error putting ${data} on ${pub}: ${err}`)
|
|
144
|
+
if (msg.put && msg.put[soul]) {
|
|
145
|
+
creating = false
|
|
146
|
+
ack("Username already exists")
|
|
159
147
|
return
|
|
160
148
|
}
|
|
161
149
|
|
|
162
|
-
const
|
|
163
|
-
|
|
150
|
+
const salt = utils.text.random(64)
|
|
151
|
+
const work = await SEA.work(password, salt)
|
|
152
|
+
const pair = await SEA.pair()
|
|
153
|
+
const priv = {priv: pair.priv, epriv: pair.epriv}
|
|
154
|
+
const enc = await SEA.encrypt(priv, work)
|
|
155
|
+
const data = {
|
|
156
|
+
username: username,
|
|
157
|
+
pub: pair.pub,
|
|
158
|
+
epub: pair.epub,
|
|
159
|
+
auth: JSON.stringify({enc: enc, salt: salt}),
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
const pub = "~" + pair.pub
|
|
163
|
+
const signed = await SEA.sign(data, pair)
|
|
164
|
+
const graph = utils.graph(pub, signed.m, signed.s, pair.pub)
|
|
165
|
+
wire.put(graph, err => {
|
|
166
|
+
creating = false
|
|
164
167
|
if (err) {
|
|
165
|
-
ack(`error putting ${
|
|
168
|
+
ack(`error putting ${data} on ${pub}: ${err}`)
|
|
166
169
|
return
|
|
167
170
|
}
|
|
168
171
|
|
|
169
|
-
|
|
170
|
-
|
|
172
|
+
const rel = {[pub]: {"#": pub}}
|
|
173
|
+
wire.put(utils.graph(soul, rel), err => {
|
|
174
|
+
if (err) {
|
|
175
|
+
ack(`error putting ${rel} on ${soul}: ${err}`)
|
|
176
|
+
return
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
// Return null on success.
|
|
180
|
+
if (cb) cb(null)
|
|
181
|
+
})
|
|
171
182
|
})
|
|
172
|
-
}
|
|
173
|
-
|
|
183
|
+
},
|
|
184
|
+
{wait: 1000},
|
|
185
|
+
)
|
|
174
186
|
},
|
|
175
187
|
auth: (username, password, cb) => {
|
|
176
188
|
const ack = err => {
|
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
|
|