@milaboratories/pl-tree 1.3.18 → 1.4.0
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/dist/index.js +4 -3
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +55 -48
- package/dist/index.mjs.map +1 -1
- package/dist/state.d.ts +7 -0
- package/dist/state.d.ts.map +1 -1
- package/dist/sync.d.ts +1 -0
- package/dist/sync.d.ts.map +1 -1
- package/dist/synchronized_tree.d.ts.map +1 -1
- package/package.json +3 -3
- package/src/state.ts +11 -0
- package/src/sync.ts +4 -0
- package/src/synchronized_tree.ts +8 -1
package/dist/index.mjs
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
var J = Object.defineProperty;
|
|
2
2
|
var q = (n, e, t) => e in n ? J(n, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : n[e] = t;
|
|
3
3
|
var d = (n, e, t) => q(n, typeof e != "symbol" ? e + "" : e, t);
|
|
4
|
-
import { resourceIdToString as C, resourceTypeToString as
|
|
5
|
-
import { ChangeSource as m, PollingComputableHooks as
|
|
6
|
-
import { notEmpty as y, msToHumanReadable as
|
|
4
|
+
import { resourceIdToString as C, resourceTypeToString as A, resourceTypesEqual as $, isNotNullResourceId as g, NullResourceId as F, isNullResourceId as b, stringifyWithResourceId as L, isTimeoutOrCancelError as B } from "@milaboratories/pl-client";
|
|
5
|
+
import { ChangeSource as m, PollingComputableHooks as M } from "@milaboratories/computable";
|
|
6
|
+
import { notEmpty as y, msToHumanReadable as z } from "@milaboratories/ts-helpers";
|
|
7
7
|
import H from "denque";
|
|
8
8
|
import * as j from "node:timers/promises";
|
|
9
9
|
function se(n, e) {
|
|
@@ -46,7 +46,7 @@ class R {
|
|
|
46
46
|
return `[ENTRY:${C(this.rid)}]`;
|
|
47
47
|
}
|
|
48
48
|
}
|
|
49
|
-
function
|
|
49
|
+
function K(n, e, t, r, s) {
|
|
50
50
|
const a = new Y(
|
|
51
51
|
n,
|
|
52
52
|
e,
|
|
@@ -57,12 +57,12 @@ function W(n, e, t, r, s) {
|
|
|
57
57
|
const o = a.getError();
|
|
58
58
|
if (o !== void 0)
|
|
59
59
|
throw new N(
|
|
60
|
-
`error encountered on resource ${C(a.id)} (${
|
|
60
|
+
`error encountered on resource ${C(a.id)} (${A(a.resourceType)}): ${o.getDataAsString()}`
|
|
61
61
|
);
|
|
62
62
|
}
|
|
63
|
-
if (s.assertResourceType !== void 0 && (Array.isArray(s.assertResourceType) ? s.assertResourceType.findIndex((o) =>
|
|
63
|
+
if (s.assertResourceType !== void 0 && (Array.isArray(s.assertResourceType) ? s.assertResourceType.findIndex((o) => $(o, a.resourceType)) === -1 : !$(s.assertResourceType, a.resourceType)))
|
|
64
64
|
throw new Error(
|
|
65
|
-
`wrong resource type ${
|
|
65
|
+
`wrong resource type ${A(a.resourceType)} but expected ${s.assertResourceType}`
|
|
66
66
|
);
|
|
67
67
|
return a;
|
|
68
68
|
}
|
|
@@ -72,7 +72,7 @@ class E {
|
|
|
72
72
|
this.accessorData = e, this.tree = t, this.rid = r, this.instanceData = s;
|
|
73
73
|
}
|
|
74
74
|
node(e = {}) {
|
|
75
|
-
return this.instanceData.guard(), this.accessorData.hooks !== void 0 && this.instanceData.ctx.attacheHooks(this.accessorData.hooks),
|
|
75
|
+
return this.instanceData.guard(), this.accessorData.hooks !== void 0 && this.instanceData.ctx.attacheHooks(this.accessorData.hooks), K(this.accessorData, this.tree, this.instanceData, this.rid, e);
|
|
76
76
|
}
|
|
77
77
|
}
|
|
78
78
|
function ue(n, e) {
|
|
@@ -99,7 +99,7 @@ class Y {
|
|
|
99
99
|
return { id: this.id, type: this.resourceType };
|
|
100
100
|
}
|
|
101
101
|
getResourceFromTree(e, t) {
|
|
102
|
-
return
|
|
102
|
+
return K(this.accessorData, this.tree, this.instanceData, e, t);
|
|
103
103
|
}
|
|
104
104
|
traverse(...e) {
|
|
105
105
|
return this.traverseWithCommon({}, ...e);
|
|
@@ -223,26 +223,26 @@ class Y {
|
|
|
223
223
|
return new R(this.accessorData, this.resource.id);
|
|
224
224
|
}
|
|
225
225
|
}
|
|
226
|
-
class
|
|
226
|
+
class S extends Error {
|
|
227
227
|
constructor(e) {
|
|
228
228
|
super(e);
|
|
229
229
|
}
|
|
230
230
|
}
|
|
231
|
-
class
|
|
231
|
+
class x {
|
|
232
232
|
constructor(e, t, r, s) {
|
|
233
233
|
d(this, "change", new m());
|
|
234
234
|
this.type = e, this.value = t, this.error = r, this.resourceVersion = s;
|
|
235
235
|
}
|
|
236
236
|
}
|
|
237
|
-
const
|
|
237
|
+
const T = 0, O = new TextDecoder();
|
|
238
238
|
class G {
|
|
239
239
|
constructor(e, t) {
|
|
240
240
|
/** Tracks number of other resources referencing this resource. Used to perform garbage collection in tree patching procedure */
|
|
241
241
|
d(this, "refCount", 0);
|
|
242
242
|
/** Increments each time resource is checked for difference with new state */
|
|
243
|
-
d(this, "version",
|
|
243
|
+
d(this, "version", T);
|
|
244
244
|
/** Set to resource version when resource state, or it's fields have changed */
|
|
245
|
-
d(this, "dataVersion",
|
|
245
|
+
d(this, "dataVersion", T);
|
|
246
246
|
d(this, "fields", /* @__PURE__ */ new Map());
|
|
247
247
|
d(this, "kv", /* @__PURE__ */ new Map());
|
|
248
248
|
d(this, "resourceRemoved", new m());
|
|
@@ -322,7 +322,7 @@ class G {
|
|
|
322
322
|
return this.outputsLocked || (t = this.resourceStateChange) == null || t.attachWatcher(e), this.outputsLocked;
|
|
323
323
|
}
|
|
324
324
|
get isReadyOrError() {
|
|
325
|
-
return this.error !==
|
|
325
|
+
return this.error !== F || this.resourceReady || this.originalResourceId !== F;
|
|
326
326
|
}
|
|
327
327
|
getIsFinal(e) {
|
|
328
328
|
var t;
|
|
@@ -334,7 +334,7 @@ class G {
|
|
|
334
334
|
}
|
|
335
335
|
getError(e) {
|
|
336
336
|
var t;
|
|
337
|
-
if (
|
|
337
|
+
if (b(this.error)) {
|
|
338
338
|
(t = this.resourceStateChange) == null || t.attachWatcher(e);
|
|
339
339
|
return;
|
|
340
340
|
} else
|
|
@@ -368,11 +368,11 @@ class G {
|
|
|
368
368
|
getKeyValueString(e, t) {
|
|
369
369
|
const r = this.getKeyValue(e, t);
|
|
370
370
|
if (r !== void 0)
|
|
371
|
-
return
|
|
371
|
+
return O.decode(r);
|
|
372
372
|
}
|
|
373
373
|
getDataAsString() {
|
|
374
374
|
if (this.data !== void 0)
|
|
375
|
-
return this.dataAsString === void 0 && (this.dataAsString =
|
|
375
|
+
return this.dataAsString === void 0 && (this.dataAsString = O.decode(this.data)), this.dataAsString;
|
|
376
376
|
}
|
|
377
377
|
getDataAsJson() {
|
|
378
378
|
if (this.data !== void 0)
|
|
@@ -405,7 +405,7 @@ class G {
|
|
|
405
405
|
this.fields.forEach((l) => l.change.markChanged()), (e = this.finalChanged) == null || e.markChanged(), (t = this.resourceStateChange) == null || t.markChanged(), (r = this.lockedChange) == null || r.markChanged(), (s = this.inputAndServiceFieldListChanged) == null || s.markChanged(), (a = this.outputFieldListChanged) == null || a.markChanged(), (o = this.dynamicFieldListChanged) == null || o.markChanged(), (i = this.kvChanged) == null || i.markChanged(), this.resourceRemoved.markChanged();
|
|
406
406
|
}
|
|
407
407
|
}
|
|
408
|
-
class
|
|
408
|
+
class V {
|
|
409
409
|
constructor(e, t = (r) => !1) {
|
|
410
410
|
/** resource heap */
|
|
411
411
|
d(this, "resources", /* @__PURE__ */ new Map());
|
|
@@ -436,7 +436,7 @@ class O {
|
|
|
436
436
|
let i = this.resources.get(o.id);
|
|
437
437
|
const l = i == null ? void 0 : i.state, c = (f) => {
|
|
438
438
|
const { fields: k, ...u } = o;
|
|
439
|
-
throw this.invalidateTree(), new
|
|
439
|
+
throw this.invalidateTree(), new S(
|
|
440
440
|
`Unexpected resource state transition (${f}): ${L(
|
|
441
441
|
u
|
|
442
442
|
)} -> ${L(l)}`
|
|
@@ -445,14 +445,14 @@ class O {
|
|
|
445
445
|
if (i !== void 0) {
|
|
446
446
|
i.final && c("resource state can be updated after it is marked as final");
|
|
447
447
|
let f = !1;
|
|
448
|
-
i.version += 1, i.originalResourceId !== o.originalResourceId && (i.originalResourceId !==
|
|
448
|
+
i.version += 1, i.originalResourceId !== o.originalResourceId && (i.originalResourceId !== F && c("originalResourceId can't change after it is set"), i.originalResourceId = o.originalResourceId, y(i.resourceStateChange).markChanged(), f = !0), i.error !== o.error && (g(i.error) && c("resource can't change attached error after it is set"), i.error = o.error, r.push(i.error), y(i.resourceStateChange).markChanged(), f = !0);
|
|
449
449
|
for (const u of o.fields) {
|
|
450
450
|
let h = i.fields.get(u.name);
|
|
451
451
|
h ? (h.type !== u.type && (h.type !== "Dynamic" && c(`field changed type ${h.type} -> ${u.type}`), y(i.dynamicFieldListChanged).markChanged(), (h.type === "Input" || h.type === "Service") && (i.inputsLocked && c(
|
|
452
452
|
`adding input field "${u.name}", while corresponding list is locked`
|
|
453
453
|
), y(i.inputAndServiceFieldListChanged).markChanged()), h.type === "Output" && (i.outputsLocked && c(
|
|
454
454
|
`adding output field "${u.name}", while corresponding list is locked`
|
|
455
|
-
), y(i.outputFieldListChanged).markChanged()), h.type = u.type, h.change.markChanged(), f = !0), h.value !== u.value && (g(h.value) && s.push(h.value), h.value = u.value, g(u.value) && r.push(u.value), h.change.markChanged(), f = !0), h.error !== u.error && (g(h.error) && s.push(h.error), h.error = u.error, g(u.error) && r.push(u.error), h.change.markChanged(), f = !0), h.resourceVersion = i.version) : (h = new
|
|
455
|
+
), y(i.outputFieldListChanged).markChanged()), h.type = u.type, h.change.markChanged(), f = !0), h.value !== u.value && (g(h.value) && s.push(h.value), h.value = u.value, g(u.value) && r.push(u.value), h.change.markChanged(), f = !0), h.error !== u.error && (g(h.error) && s.push(h.error), h.error = u.error, g(u.error) && r.push(u.error), h.change.markChanged(), f = !0), h.resourceVersion = i.version) : (h = new x(u.type, u.value, u.error, i.version), g(u.value) && r.push(u.value), g(u.error) && r.push(u.error), u.type === "Input" || u.type === "Service" ? (i.inputsLocked && c(
|
|
456
456
|
`adding ${u.type} (${u.name}) field while inputs locked`
|
|
457
457
|
), y(i.inputAndServiceFieldListChanged).markChanged()) : u.type === "Output" ? (i.outputsLocked && c(
|
|
458
458
|
`adding ${u.type} (${u.name}) field while outputs locked`
|
|
@@ -481,17 +481,17 @@ class O {
|
|
|
481
481
|
} else {
|
|
482
482
|
i = new G(o), i.verifyReadyState(), g(i.error) && r.push(i.error);
|
|
483
483
|
for (const f of o.fields) {
|
|
484
|
-
const k = new
|
|
484
|
+
const k = new x(f.type, f.value, f.error, T);
|
|
485
485
|
g(f.value) && r.push(f.value), g(f.error) && r.push(f.error), i.fields.set(f.name, k);
|
|
486
486
|
}
|
|
487
487
|
for (const f of o.kv) i.kv.set(f.key, f.value);
|
|
488
|
-
this.resources.set(i.id, i), this.resourcesAdded.markChanged();
|
|
488
|
+
this.isFinalPredicate(i) && i.markFinal(), this.resources.set(i.id, i), this.resourcesAdded.markChanged();
|
|
489
489
|
}
|
|
490
490
|
}
|
|
491
491
|
for (const o of r) {
|
|
492
492
|
const i = this.resources.get(o);
|
|
493
493
|
if (!i)
|
|
494
|
-
throw this.invalidateTree(), new
|
|
494
|
+
throw this.invalidateTree(), new S(`orphan resource ${o}`);
|
|
495
495
|
i.refCount++;
|
|
496
496
|
}
|
|
497
497
|
let a = s;
|
|
@@ -500,7 +500,7 @@ class O {
|
|
|
500
500
|
for (const i of a) {
|
|
501
501
|
const l = this.resources.get(i);
|
|
502
502
|
if (!l)
|
|
503
|
-
throw this.invalidateTree(), new
|
|
503
|
+
throw this.invalidateTree(), new S(`orphan resource ${i}`);
|
|
504
504
|
l.refCount--, l.refCount === 0 && l.id !== this.root && (l.fields.forEach((c) => {
|
|
505
505
|
g(c.value) && o.push(c.value), g(c.error) && o.push(c.error), c.change.markChanged();
|
|
506
506
|
}), g(l.error) && o.push(l.error), l.resourceRemoved.markChanged(), this.resources.delete(i));
|
|
@@ -510,7 +510,7 @@ class O {
|
|
|
510
510
|
if (!t) {
|
|
511
511
|
for (const o of e)
|
|
512
512
|
if (!this.resources.has(o.id))
|
|
513
|
-
throw this.invalidateTree(), new
|
|
513
|
+
throw this.invalidateTree(), new S(`orphan input resource ${o.id}`);
|
|
514
514
|
}
|
|
515
515
|
}
|
|
516
516
|
/** @deprecated use "entry" instead */
|
|
@@ -532,7 +532,7 @@ function Q(n, e) {
|
|
|
532
532
|
s.final ? r.add(s.id) : t.push(s.id);
|
|
533
533
|
}), t.length === 0 && r.size === 0 && t.push(n.root), { seedResources: t, finalResources: r, pruningFunction: e };
|
|
534
534
|
}
|
|
535
|
-
function
|
|
535
|
+
function D() {
|
|
536
536
|
return {
|
|
537
537
|
requests: 0,
|
|
538
538
|
roundtrips: 0,
|
|
@@ -540,6 +540,7 @@ function b() {
|
|
|
540
540
|
retrievedFields: 0,
|
|
541
541
|
retrievedKeyValues: 0,
|
|
542
542
|
retrievedResourceDataBytes: 0,
|
|
543
|
+
retrievedKeyValueBytes: 0,
|
|
543
544
|
prunnedFields: 0,
|
|
544
545
|
finalResourcesSkipped: 0,
|
|
545
546
|
millisSpent: 0
|
|
@@ -548,12 +549,13 @@ function b() {
|
|
|
548
549
|
function de(n) {
|
|
549
550
|
let e = `Requests: ${n.requests}
|
|
550
551
|
`;
|
|
551
|
-
return e += `Total time: ${
|
|
552
|
+
return e += `Total time: ${z(n.millisSpent)}
|
|
552
553
|
`, e += `Roundtrips: ${n.roundtrips}
|
|
553
554
|
`, e += `Resources: ${n.retrievedResources}
|
|
554
555
|
`, e += `Fields: ${n.retrievedFields}
|
|
555
556
|
`, e += `KV: ${n.retrievedKeyValues}
|
|
556
557
|
`, e += `Data Bytes: ${n.retrievedResourceDataBytes}
|
|
558
|
+
`, e += `KV Bytes: ${n.retrievedKeyValueBytes}
|
|
557
559
|
`, e += `Pruned fields: ${n.prunnedFields}
|
|
558
560
|
`, e += `Final resources skipped: ${n.finalResourcesSkipped}`, e;
|
|
559
561
|
}
|
|
@@ -564,7 +566,7 @@ async function X(n, e, t) {
|
|
|
564
566
|
const { seedResources: s, finalResources: a, pruningFunction: o } = e, i = new H();
|
|
565
567
|
let l = !0, c = 0;
|
|
566
568
|
const f = /* @__PURE__ */ new Set(), k = (p) => {
|
|
567
|
-
if (
|
|
569
|
+
if (b(p) || f.has(p)) return;
|
|
568
570
|
if (a.has(p)) {
|
|
569
571
|
t && t.finalResourcesSkipped++;
|
|
570
572
|
return;
|
|
@@ -573,10 +575,10 @@ async function X(n, e, t) {
|
|
|
573
575
|
const v = n.getResourceDataIfExists(p, !0), w = n.listKeyValuesIfResourceExists(p), U = l;
|
|
574
576
|
l && (l = !1), i.push(
|
|
575
577
|
(async () => {
|
|
576
|
-
const [
|
|
577
|
-
if (U && (c++, l = !0),
|
|
578
|
-
if (
|
|
579
|
-
return { ...
|
|
578
|
+
const [_, I] = await Promise.all([v, w]);
|
|
579
|
+
if (U && (c++, l = !0), _ !== void 0) {
|
|
580
|
+
if (I === void 0) throw new Error("Inconsistent replies");
|
|
581
|
+
return { ..._, kv: I };
|
|
580
582
|
}
|
|
581
583
|
})()
|
|
582
584
|
);
|
|
@@ -596,7 +598,11 @@ async function X(n, e, t) {
|
|
|
596
598
|
k(v.error);
|
|
597
599
|
for (const w of v.fields)
|
|
598
600
|
k(w.value), k(w.error);
|
|
599
|
-
|
|
601
|
+
if (t) {
|
|
602
|
+
t.retrievedResources++, t.retrievedFields += v.fields.length, t.retrievedKeyValues += v.kv.length, t.retrievedResourceDataBytes += ((h = v.data) == null ? void 0 : h.length) ?? 0;
|
|
603
|
+
for (const w of v.kv) t.retrievedKeyValueBytes += w.value.length;
|
|
604
|
+
}
|
|
605
|
+
u.push(v);
|
|
600
606
|
}
|
|
601
607
|
}
|
|
602
608
|
return t && (t.millisSpent += Date.now() - r, t.roundtrips += c), u;
|
|
@@ -654,7 +660,7 @@ function fe(n, e, t) {
|
|
|
654
660
|
metadata: Object.fromEntries(a)
|
|
655
661
|
};
|
|
656
662
|
}
|
|
657
|
-
class
|
|
663
|
+
class W {
|
|
658
664
|
constructor(e, t, r, s) {
|
|
659
665
|
d(this, "finalPredicate");
|
|
660
666
|
d(this, "state");
|
|
@@ -672,7 +678,7 @@ class K {
|
|
|
672
678
|
d(this, "terminated", !1);
|
|
673
679
|
this.pl = e, this.root = t, this.logger = s;
|
|
674
680
|
const { finalPredicate: a, pruning: o, pollingInterval: i, stopPollingDelay: l, logStat: c } = r;
|
|
675
|
-
this.pruning = o, this.pollingInterval = i, this.finalPredicate = a, this.logStat = c, this.state = new
|
|
681
|
+
this.pruning = o, this.pollingInterval = i, this.finalPredicate = a, this.logStat = c, this.state = new V(t, a), this.hooks = new M(
|
|
676
682
|
() => this.startUpdating(),
|
|
677
683
|
() => this.stopUpdating(),
|
|
678
684
|
{ stopDebounce: l },
|
|
@@ -713,16 +719,16 @@ class K {
|
|
|
713
719
|
}
|
|
714
720
|
async mainLoop() {
|
|
715
721
|
var t, r;
|
|
716
|
-
let e = this.logStat ?
|
|
722
|
+
let e = this.logStat ? D() : void 0;
|
|
717
723
|
for (; this.keepRunning; ) {
|
|
718
724
|
let s;
|
|
719
725
|
this.scheduledOnNextState.length > 0 && (s = this.scheduledOnNextState, this.scheduledOnNextState = []);
|
|
720
726
|
try {
|
|
721
|
-
if (this.logStat === "per-request" && (e =
|
|
727
|
+
if (this.logStat === "per-request" && (e = D()), await this.refresh(e), e && this.logger && this.logger.info(`Tree stat (success): ${JSON.stringify(e)}`), s !== void 0) for (const a of s) a.resolve();
|
|
722
728
|
} catch (a) {
|
|
723
729
|
if (e && this.logger && this.logger.info(`Tree stat (error): ${JSON.stringify(e)}`), s !== void 0) for (const o of s) o.reject(a);
|
|
724
|
-
if (a instanceof
|
|
725
|
-
(t = this.logger) == null || t.error(a), this.state.invalidateTree("stat update error"), this.state = new
|
|
730
|
+
if (a instanceof S) {
|
|
731
|
+
(t = this.logger) == null || t.error(a), this.state.invalidateTree("stat update error"), this.state = new V(this.root, this.finalPredicate);
|
|
726
732
|
continue;
|
|
727
733
|
} else (r = this.logger) == null || r.warn(a);
|
|
728
734
|
}
|
|
@@ -730,7 +736,7 @@ class K {
|
|
|
730
736
|
try {
|
|
731
737
|
await j.setTimeout(this.pollingInterval, this.abortController.signal);
|
|
732
738
|
} catch (a) {
|
|
733
|
-
if (!
|
|
739
|
+
if (!B(a)) throw new Error("Unexpected error", { cause: a });
|
|
734
740
|
break;
|
|
735
741
|
}
|
|
736
742
|
}
|
|
@@ -748,8 +754,9 @@ class K {
|
|
|
748
754
|
this.currentLoop !== void 0 && await this.currentLoop;
|
|
749
755
|
}
|
|
750
756
|
static async init(e, t, r, s) {
|
|
751
|
-
const a = new
|
|
752
|
-
|
|
757
|
+
const a = new W(e, t, r, s);
|
|
758
|
+
let o = r.logStat ? D() : void 0;
|
|
759
|
+
return await a.refresh(o), o && s && s.info(`Tree stat (initial load): ${JSON.stringify(o)}`), a;
|
|
753
760
|
}
|
|
754
761
|
}
|
|
755
762
|
export {
|
|
@@ -758,12 +765,12 @@ export {
|
|
|
758
765
|
E as PlTreeEntryAccessor,
|
|
759
766
|
Y as PlTreeNodeAccessor,
|
|
760
767
|
G as PlTreeResource,
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
768
|
+
V as PlTreeState,
|
|
769
|
+
W as SynchronizedTreeState,
|
|
770
|
+
S as TreeStateUpdateError,
|
|
764
771
|
Q as constructTreeLoadingRequest,
|
|
765
772
|
de as formatTreeLoadingStat,
|
|
766
|
-
|
|
773
|
+
D as initialTreeLoadingStat,
|
|
767
774
|
ne as isPlTreeEntry,
|
|
768
775
|
oe as isPlTreeEntryAccessor,
|
|
769
776
|
ae as isPlTreeNodeAccessor,
|