@mblaney/holster 2.2.1 → 2.2.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 +1 -1
- package/build/holster.js.map +2 -2
- package/dist/holster.js +1 -1
- package/dist/holster.js.map +2 -2
- package/package.json +1 -1
- package/src/holster.js +30 -29
- package/ts/src/holster.ts +3 -1
- package/utils/user-storage.js +4 -4
package/package.json
CHANGED
package/src/holster.js
CHANGED
|
@@ -167,7 +167,7 @@ const Holster = opt => {
|
|
|
167
167
|
const node = msg.put && msg.put[soul]
|
|
168
168
|
const id = utils.rel.is(node && node[item])
|
|
169
169
|
if (!id) {
|
|
170
|
-
// If it's a plain value (not a rel) and
|
|
170
|
+
// If it's a plain value (not a rel) and using get, deliver it.
|
|
171
171
|
// node._ guards against timeout null-acks which lack metadata.
|
|
172
172
|
if (!on && node && node._ && typeof node[item] !== "undefined") {
|
|
173
173
|
if (timer) clearTimeout(timer)
|
|
@@ -189,7 +189,9 @@ const Holster = opt => {
|
|
|
189
189
|
{...request._opt, secure: !!(ctx.user || opt.secure)},
|
|
190
190
|
)
|
|
191
191
|
}
|
|
192
|
-
|
|
192
|
+
// The get parameter is set to true to call handler immediately for
|
|
193
|
+
// listeners set on nested properties.
|
|
194
|
+
wire.on({"#": soul, ".": item}, handler, true, request._opt)
|
|
193
195
|
// Time out after the same total duration as the on() retry loop
|
|
194
196
|
// (1+2+4+8+16 = 31s) so callers are not blocked forever if the node
|
|
195
197
|
// genuinely doesn't exist.
|
|
@@ -325,7 +327,7 @@ const Holster = opt => {
|
|
|
325
327
|
api(ctxid).put(request.put, cb)
|
|
326
328
|
})
|
|
327
329
|
} else if (on) {
|
|
328
|
-
// Item is not a rel yet
|
|
330
|
+
// Item is not a rel yet - watch the parent soul for when it
|
|
329
331
|
// becomes one, then retry chain resolution.
|
|
330
332
|
watchForRel(soul, item, ctx, i, request, cb)
|
|
331
333
|
if (request._get) cb(null)
|
|
@@ -346,7 +348,7 @@ const Holster = opt => {
|
|
|
346
348
|
})
|
|
347
349
|
} else {
|
|
348
350
|
if (on) {
|
|
349
|
-
// Node doesn't exist yet
|
|
351
|
+
// Node doesn't exist yet - watch for it to appear.
|
|
350
352
|
watchForRel(soul, item, ctx, i, request, cb)
|
|
351
353
|
if (request._get) cb(null)
|
|
352
354
|
} else if (get && node) {
|
|
@@ -356,14 +358,14 @@ const Holster = opt => {
|
|
|
356
358
|
Object.keys(sv).length > 0 &&
|
|
357
359
|
typeof sv[item] === "undefined"
|
|
358
360
|
) {
|
|
359
|
-
// State vector has other properties but not this one
|
|
361
|
+
// State vector has other properties but not this one.
|
|
360
362
|
if (cb) cb(null)
|
|
361
363
|
} else {
|
|
362
|
-
// Empty state vector or item is tracked
|
|
364
|
+
// Empty state vector or item is tracked, may arrive via push.
|
|
363
365
|
watchForRel(soul, item, ctx, i, request, cb, false)
|
|
364
366
|
}
|
|
365
367
|
} else {
|
|
366
|
-
// Soul doesn't exist or no get
|
|
368
|
+
// Soul doesn't exist or no get - return null.
|
|
367
369
|
if (cb) cb(null)
|
|
368
370
|
}
|
|
369
371
|
}
|
|
@@ -698,7 +700,7 @@ const Holster = opt => {
|
|
|
698
700
|
if (_opt && _opt.nested) {
|
|
699
701
|
// attachNested calls this once for the top level and again for
|
|
700
702
|
// every discovered child, each needing its own independent
|
|
701
|
-
// context
|
|
703
|
+
// context. A single shared _ctxid would accumulate .next()
|
|
702
704
|
// calls onto the same path instead of giving sibling paths.
|
|
703
705
|
const factory = () => {
|
|
704
706
|
const _ctxid = utils.text.random()
|
|
@@ -724,37 +726,36 @@ const Holster = opt => {
|
|
|
724
726
|
const maxRetries = 5
|
|
725
727
|
const retryDelay = 1000 // Start with 1 second
|
|
726
728
|
let retryTimer = null
|
|
727
|
-
// Which soul the persistent wire listener is currently attached to
|
|
728
|
-
//
|
|
729
|
-
//
|
|
730
|
-
//
|
|
731
|
-
//
|
|
732
|
-
//
|
|
733
|
-
//
|
|
734
|
-
//
|
|
735
|
-
// same key) each track their own independently.
|
|
729
|
+
// Which soul the persistent wire listener is currently attached to.
|
|
730
|
+
// Starts on the parent (soul/item), and moves to a rel's target soul
|
|
731
|
+
// once item is created, since further updates land on the target's own
|
|
732
|
+
// soul, not the parent's. Tracked rather than switching unconditionally
|
|
733
|
+
// so that the two places that can discover a rel - the initial check
|
|
734
|
+
// below and a later resolveValue retry - don't both re-register the
|
|
735
|
+
// same listener. Scoped to this one on() call's closure, so concurrent
|
|
736
|
+
// subscriptions (even on the same key) can each track their own.
|
|
736
737
|
let listenedSoul = soul
|
|
737
738
|
|
|
738
739
|
map.set(cb, () => {
|
|
739
|
-
// Bail out if off() has already cleaned up this context
|
|
740
|
+
// Bail out if off() has already cleaned up this context. The mapped
|
|
740
741
|
// callback can fire twice (once from wire.on and once from the _get
|
|
741
742
|
// immediate-read path) and the second call after async context
|
|
742
743
|
// cleanup would crash in resolve(). Matches the guard in watchForRel.
|
|
743
744
|
if (!allctx.has(ctxid)) return
|
|
744
|
-
|
|
745
|
+
|
|
746
|
+
// Cancel any pending retry. The persistent listener firing means we
|
|
745
747
|
// have an update and should not call cb twice.
|
|
746
748
|
clearTimeout(retryTimer)
|
|
747
749
|
retryTimer = null
|
|
748
750
|
|
|
749
751
|
// Resolves {soul, item} to a genuine value, following a rel to its
|
|
750
|
-
// target if the property turns out to be one
|
|
751
|
-
// every attempt,
|
|
752
|
-
//
|
|
753
|
-
//
|
|
754
|
-
//
|
|
755
|
-
//
|
|
756
|
-
//
|
|
757
|
-
// "genuinely null" apart from "hasn't landed yet" either - its
|
|
752
|
+
// target if the property turns out to be one. This is checked on
|
|
753
|
+
// every attempt, since a property can still be a plain undefined/null
|
|
754
|
+
// on an early check and only become a rel once a later retry catches
|
|
755
|
+
// up (e.g. a nested rel-creating put both adds "item" as a rel on
|
|
756
|
+
// this node AND populates its target, and either half can still be
|
|
757
|
+
// mid-flight when the listener first fires). Also wire.get() can't
|
|
758
|
+
// reliably tell "genuinely null" apart from "hasn't landed yet", its
|
|
758
759
|
// own internal timeout fallback explicitly answers null when
|
|
759
760
|
// nothing comes back in time - so a null/missing value is
|
|
760
761
|
// retried a few times before being trusted as final, the same
|
|
@@ -848,7 +849,7 @@ const Holster = opt => {
|
|
|
848
849
|
const current = msg.put && msg.put[soul] && msg.put[soul][item]
|
|
849
850
|
const id = utils.rel.is(current)
|
|
850
851
|
if (id) {
|
|
851
|
-
// It's a rel, need to switch listener to the related node
|
|
852
|
+
// It's a rel, need to switch listener to the related node,
|
|
852
853
|
// unless resolveValue (triggered by the initial listener
|
|
853
854
|
// firing) already beat this check to it.
|
|
854
855
|
if (listenedSoul !== id) {
|
|
@@ -878,7 +879,7 @@ const Holster = opt => {
|
|
|
878
879
|
return
|
|
879
880
|
}
|
|
880
881
|
|
|
881
|
-
// Resolve the current context before removing event listener.
|
|
882
|
+
// Resolve the current context before removing the event listener.
|
|
882
883
|
const {item, soul} = resolve({off: true}, cb)
|
|
883
884
|
if (!soul) return
|
|
884
885
|
|
package/ts/src/holster.ts
CHANGED
|
@@ -291,7 +291,9 @@ const Holster = (opt?: HolsterOptions | string | string[]): HolsterAPI => {
|
|
|
291
291
|
},
|
|
292
292
|
)
|
|
293
293
|
}
|
|
294
|
-
|
|
294
|
+
// The get parameter is set to true to call handler immediately for
|
|
295
|
+
// listeners set on nested properties.
|
|
296
|
+
wire.on({"#": soul, ".": item}, handler, true, request._opt)
|
|
295
297
|
// Time out after the same total duration as the on() retry loop
|
|
296
298
|
// (1+2+4+8+16 = 31s) so callers are not blocked forever if the node
|
|
297
299
|
// genuinely doesn't exist.
|
package/utils/user-storage.js
CHANGED
|
@@ -69,7 +69,7 @@ const page = users.slice(offset, offset + limit)
|
|
|
69
69
|
console.log(` Total users: ${users.length}`)
|
|
70
70
|
if (page.length > 0) {
|
|
71
71
|
console.log(
|
|
72
|
-
` Showing
|
|
72
|
+
` Showing public keys for ${page.length} user${page.length !== 1 ? "s" : ""} (query: --offset ${offset} --limit ${limit})`,
|
|
73
73
|
)
|
|
74
74
|
}
|
|
75
75
|
|
|
@@ -78,10 +78,10 @@ for (const {pub, total} of page) {
|
|
|
78
78
|
const pubLimit = data[pub]
|
|
79
79
|
const limitStr =
|
|
80
80
|
typeof pubLimit !== "number"
|
|
81
|
-
? "
|
|
81
|
+
? "server default"
|
|
82
82
|
: pubLimit === 0
|
|
83
|
-
? "
|
|
83
|
+
? "blocked"
|
|
84
84
|
: formatBytes(pubLimit * 1048576)
|
|
85
85
|
console.log(` ${pub}`)
|
|
86
|
-
console.log(` used: ${formatBytes(total)} /
|
|
86
|
+
console.log(` used: ${formatBytes(total)} / ${limitStr}`)
|
|
87
87
|
}
|