@loomwork/plugin-content 0.0.0-stage → 0.1.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/LICENSE +202 -0
- package/NOTICE +8 -0
- package/README.md +92 -2
- package/dist/CachingContentStore.d.ts +54 -0
- package/dist/CachingContentStore.d.ts.map +1 -0
- package/dist/CachingContentStore.js +171 -0
- package/dist/CachingContentStore.js.map +1 -0
- package/dist/ContentResolvingEventStore.d.ts +70 -0
- package/dist/ContentResolvingEventStore.d.ts.map +1 -0
- package/dist/ContentResolvingEventStore.js +245 -0
- package/dist/ContentResolvingEventStore.js.map +1 -0
- package/dist/ContentStore.d.ts +186 -0
- package/dist/ContentStore.d.ts.map +1 -0
- package/dist/ContentStore.js +177 -0
- package/dist/ContentStore.js.map +1 -0
- package/dist/ContentTouchingSnapshotStore.d.ts +56 -0
- package/dist/ContentTouchingSnapshotStore.d.ts.map +1 -0
- package/dist/ContentTouchingSnapshotStore.js +85 -0
- package/dist/ContentTouchingSnapshotStore.js.map +1 -0
- package/dist/citations.d.ts +40 -0
- package/dist/citations.d.ts.map +1 -0
- package/dist/citations.js +118 -0
- package/dist/citations.js.map +1 -0
- package/dist/content.bench.d.ts +2 -0
- package/dist/content.bench.d.ts.map +1 -0
- package/dist/content.bench.js +75 -0
- package/dist/content.bench.js.map +1 -0
- package/dist/content.d.ts +40 -0
- package/dist/content.d.ts.map +1 -0
- package/dist/content.js +177 -0
- package/dist/content.js.map +1 -0
- package/dist/derive.d.ts +9 -0
- package/dist/derive.d.ts.map +1 -0
- package/dist/derive.js +40 -0
- package/dist/derive.js.map +1 -0
- package/dist/errors.d.ts +6 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +20 -0
- package/dist/errors.js.map +1 -0
- package/dist/executionEnd.d.ts +22 -0
- package/dist/executionEnd.d.ts.map +1 -0
- package/dist/executionEnd.js +66 -0
- package/dist/executionEnd.js.map +1 -0
- package/dist/gc.d.ts +470 -0
- package/dist/gc.d.ts.map +1 -0
- package/dist/gc.js +819 -0
- package/dist/gc.js.map +1 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +42 -0
- package/dist/index.js.map +1 -0
- package/dist/touchAround.d.ts +46 -0
- package/dist/touchAround.d.ts.map +1 -0
- package/dist/touchAround.js +98 -0
- package/dist/touchAround.js.map +1 -0
- package/package.json +58 -3
- package/src/CachingContentStore.ts +184 -0
- package/src/ContentResolvingEventStore.ts +325 -0
- package/src/ContentStore.ts +317 -0
- package/src/ContentTouchingSnapshotStore.ts +109 -0
- package/src/citations.ts +117 -0
- package/src/content.bench.ts +84 -0
- package/src/content.ts +191 -0
- package/src/derive.ts +40 -0
- package/src/errors.ts +19 -0
- package/src/executionEnd.ts +64 -0
- package/src/gc.ts +1213 -0
- package/src/index.ts +54 -0
- package/src/touchAround.ts +131 -0
package/dist/derive.d.ts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { StepDefinition } from "@loomwork/core";
|
|
2
|
+
/**
|
|
3
|
+
* Build the {@link ContentResolvingEventStore} `externalize` map from step definitions: every
|
|
4
|
+
* field marked `externalized()` in a step's `outputSchema` becomes a `STEP_COMPLETED` dot-path
|
|
5
|
+
* `output.<path>`. Paths are unioned + O(n) de-duplicated across steps; an empty map when
|
|
6
|
+
* nothing is marked (zero-overhead unwired path, G2).
|
|
7
|
+
*/
|
|
8
|
+
export declare function externalizePathsFromSteps(steps: readonly Pick<StepDefinition, "outputSchema">[]): Record<string, string[]>;
|
|
9
|
+
//# sourceMappingURL=derive.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"derive.d.ts","sourceRoot":"","sources":["../src/derive.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAarD;;;;;GAKG;AACH,wBAAgB,yBAAyB,CAGvC,KAAK,EAAE,SAAS,IAAI,CAAC,cAAc,EAAE,cAAc,CAAC,EAAE,GACrD,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAe1B"}
|
package/dist/derive.js
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.externalizePathsFromSteps = externalizePathsFromSteps;
|
|
4
|
+
const classify_1 = require("@loomwork/classify");
|
|
5
|
+
// ── ADR 0046 — derive the externalize map from `externalized()` marks ──────────
|
|
6
|
+
//
|
|
7
|
+
// Mark a field once — `doc: externalized(z.object({...}))` — and derive the
|
|
8
|
+
// ContentResolvingEventStore `externalize` map, instead of hand-authoring
|
|
9
|
+
// `{ STEP_COMPLETED: ["output.doc"] }`. Mirrors `sensitivePathsFromSteps` (crypto): a step's
|
|
10
|
+
// output is stored under `output.*` in STEP_COMPLETED, so an externalized output field
|
|
11
|
+
// contributes `STEP_COMPLETED → "output.<path>"`.
|
|
12
|
+
/** The STEP_COMPLETED payload nests a step's output under this key. */
|
|
13
|
+
const OUTPUT_PREFIX = "output";
|
|
14
|
+
/**
|
|
15
|
+
* Build the {@link ContentResolvingEventStore} `externalize` map from step definitions: every
|
|
16
|
+
* field marked `externalized()` in a step's `outputSchema` becomes a `STEP_COMPLETED` dot-path
|
|
17
|
+
* `output.<path>`. Paths are unioned + O(n) de-duplicated across steps; an empty map when
|
|
18
|
+
* nothing is marked (zero-overhead unwired path, G2).
|
|
19
|
+
*/
|
|
20
|
+
function externalizePathsFromSteps(
|
|
21
|
+
// Only the output schema is read; Pick drops the invariant handler field so concrete
|
|
22
|
+
// `StepDefinition<In, Out>` values pass without a cast.
|
|
23
|
+
steps) {
|
|
24
|
+
const seen = new Set();
|
|
25
|
+
const stepCompleted = [];
|
|
26
|
+
for (const step of steps) {
|
|
27
|
+
const schema = step.outputSchema;
|
|
28
|
+
if (schema === undefined)
|
|
29
|
+
continue;
|
|
30
|
+
for (const path of (0, classify_1.externalizedPaths)(schema)) {
|
|
31
|
+
const dotted = `${OUTPUT_PREFIX}.${path}`;
|
|
32
|
+
if (!seen.has(dotted)) {
|
|
33
|
+
seen.add(dotted);
|
|
34
|
+
stepCompleted.push(dotted);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
return stepCompleted.length > 0 ? { STEP_COMPLETED: stepCompleted } : {};
|
|
39
|
+
}
|
|
40
|
+
//# sourceMappingURL=derive.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"derive.js","sourceRoot":"","sources":["../src/derive.ts"],"names":[],"mappings":";;AAoBA,8DAmBC;AAvCD,iDAAuD;AAGvD,kFAAkF;AAClF,EAAE;AACF,4EAA4E;AAC5E,0EAA0E;AAC1E,6FAA6F;AAC7F,uFAAuF;AACvF,kDAAkD;AAElD,uEAAuE;AACvE,MAAM,aAAa,GAAG,QAAQ,CAAC;AAE/B;;;;;GAKG;AACH,SAAgB,yBAAyB;AACvC,qFAAqF;AACrF,wDAAwD;AACxD,KAAsD;IAEtD,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAC/B,MAAM,aAAa,GAAa,EAAE,CAAC;IACnC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,MAAM,GAAG,IAAI,CAAC,YAAY,CAAC;QACjC,IAAI,MAAM,KAAK,SAAS;YAAE,SAAS;QACnC,KAAK,MAAM,IAAI,IAAI,IAAA,4BAAiB,EAAC,MAAM,CAAC,EAAE,CAAC;YAC7C,MAAM,MAAM,GAAG,GAAG,aAAa,IAAI,IAAI,EAAE,CAAC;YAC1C,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;gBACtB,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;gBACjB,aAAa,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YAC7B,CAAC;QACH,CAAC;IACH,CAAC;IACD,OAAO,aAAa,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,cAAc,EAAE,aAAa,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;AAC3E,CAAC"}
|
package/dist/errors.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAMA,qBAAa,mBAAoB,SAAQ,KAAK;IAE1C,QAAQ,CAAC,cAAc,EAAE,MAAM;IAC/B,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM;gBADpB,cAAc,EAAE,MAAM,EACtB,WAAW,CAAC,EAAE,MAAM,YAAA;CAShC"}
|
package/dist/errors.js
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// ── ADR 0046 — loud on absence (the generalized PAYLOAD_SHREDDED contract) ─────
|
|
3
|
+
//
|
|
4
|
+
// A fold that needs an externalized value whose bytes were erased (or never stored) must fail
|
|
5
|
+
// LOUDLY — never silently substitute a default and diverge (G1). This mirrors the crypto
|
|
6
|
+
// plugin's `PayloadShreddedError`: the value is gone, so replay of it cannot proceed.
|
|
7
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
+
exports.ContentMissingError = void 0;
|
|
9
|
+
class ContentMissingError extends Error {
|
|
10
|
+
contentAddress;
|
|
11
|
+
executionId;
|
|
12
|
+
constructor(contentAddress, executionId) {
|
|
13
|
+
super(`externalized content "${contentAddress}"${executionId ? ` (execution "${executionId}")` : ""} is missing: the bytes were erased or never stored, so replay cannot restore this value`);
|
|
14
|
+
this.contentAddress = contentAddress;
|
|
15
|
+
this.executionId = executionId;
|
|
16
|
+
this.name = "ContentMissingError";
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
exports.ContentMissingError = ContentMissingError;
|
|
20
|
+
//# sourceMappingURL=errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":";AAAA,kFAAkF;AAClF,EAAE;AACF,8FAA8F;AAC9F,yFAAyF;AACzF,sFAAsF;;;AAEtF,MAAa,mBAAoB,SAAQ,KAAK;IAEjC;IACA;IAFX,YACW,cAAsB,EACtB,WAAoB;QAE7B,KAAK,CACH,yBAAyB,cAAc,IACrC,WAAW,CAAC,CAAC,CAAC,gBAAgB,WAAW,IAAI,CAAC,CAAC,CAAC,EAClD,yFAAyF,CAC1F,CAAC;QAPO,mBAAc,GAAd,cAAc,CAAQ;QACtB,gBAAW,GAAX,WAAW,CAAS;QAO7B,IAAI,CAAC,IAAI,GAAG,qBAAqB,CAAC;IACpC,CAAC;CACF;AAZD,kDAYC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { EventEnvelope } from "@loomwork/core";
|
|
2
|
+
/**
|
|
3
|
+
* ADR 0146 - when did this execution END, as far as the live log can tell? The `at` of its newest
|
|
4
|
+
* kernel terminal event, or `undefined` when it has not ended: no terminal event, or it was RE-OPENED
|
|
5
|
+
* after its newest one (`resumeAs` appends EXECUTION_RESUMED to a terminal execution; a later
|
|
6
|
+
* EXECUTION_SUSPENDED / EXECUTION_STARTED likewise means live). `undefined` makes the sweep fall back
|
|
7
|
+
* to the citation clock, so every uncertainty can only age a ref LATER or equal, never earlier.
|
|
8
|
+
*
|
|
9
|
+
* The terminal set is the one `@loomwork/workflow-runtime`'s `terminalEndedAt` uses (and the replay VM's
|
|
10
|
+
* `isKernelWritten` check for EXECUTION_CONTINUED); it is duplicated, not imported, so this package
|
|
11
|
+
* takes no dependency on workflow-runtime. `gc.endClock.test.ts` (l) pins it against the ReplayVM.
|
|
12
|
+
* Scans from the tail in sequence order (not timestamp order), usually stopping within a few events.
|
|
13
|
+
*/
|
|
14
|
+
export declare function terminalEndOf(events: readonly EventEnvelope[]): number | undefined;
|
|
15
|
+
/**
|
|
16
|
+
* ADR 0146 - was this execution RE-OPENED after a terminal event? True iff its tail is live
|
|
17
|
+
* (`terminalEndOf` returns `undefined` because a RESUMED / SUSPENDED / STARTED follows) AND a terminal
|
|
18
|
+
* event (the same set as `terminalEndOf`) precedes that live tail. A run that never ended is false.
|
|
19
|
+
* A terminal event with a non-finite timestamp still counts as an end here (the log shows it ended).
|
|
20
|
+
*/
|
|
21
|
+
export declare function wasReopened(events: readonly EventEnvelope[]): boolean;
|
|
22
|
+
//# sourceMappingURL=executionEnd.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"executionEnd.d.ts","sourceRoot":"","sources":["../src/executionEnd.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAOpD;;;;;;;;;;;GAWG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,SAAS,aAAa,EAAE,GAAG,MAAM,GAAG,SAAS,CAiBlF;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,MAAM,EAAE,SAAS,aAAa,EAAE,GAAG,OAAO,CAmBrE"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.terminalEndOf = terminalEndOf;
|
|
4
|
+
exports.wasReopened = wasReopened;
|
|
5
|
+
// A terminal timestamp that is not a finite number (NaN, a string from an imported log or a 3P store,
|
|
6
|
+
// +-Infinity, null) is not comparable: treat the execution as not ended so the citation clock applies.
|
|
7
|
+
const finiteOrUndefined = (t) => typeof t === "number" && Number.isFinite(t) ? t : undefined;
|
|
8
|
+
/**
|
|
9
|
+
* ADR 0146 - when did this execution END, as far as the live log can tell? The `at` of its newest
|
|
10
|
+
* kernel terminal event, or `undefined` when it has not ended: no terminal event, or it was RE-OPENED
|
|
11
|
+
* after its newest one (`resumeAs` appends EXECUTION_RESUMED to a terminal execution; a later
|
|
12
|
+
* EXECUTION_SUSPENDED / EXECUTION_STARTED likewise means live). `undefined` makes the sweep fall back
|
|
13
|
+
* to the citation clock, so every uncertainty can only age a ref LATER or equal, never earlier.
|
|
14
|
+
*
|
|
15
|
+
* The terminal set is the one `@loomwork/workflow-runtime`'s `terminalEndedAt` uses (and the replay VM's
|
|
16
|
+
* `isKernelWritten` check for EXECUTION_CONTINUED); it is duplicated, not imported, so this package
|
|
17
|
+
* takes no dependency on workflow-runtime. `gc.endClock.test.ts` (l) pins it against the ReplayVM.
|
|
18
|
+
* Scans from the tail in sequence order (not timestamp order), usually stopping within a few events.
|
|
19
|
+
*/
|
|
20
|
+
function terminalEndOf(events) {
|
|
21
|
+
for (let i = events.length - 1; i >= 0; i--) {
|
|
22
|
+
const e = events[i];
|
|
23
|
+
switch (e.eventType) {
|
|
24
|
+
case "EXECUTION_RESUMED":
|
|
25
|
+
case "EXECUTION_SUSPENDED":
|
|
26
|
+
case "EXECUTION_STARTED":
|
|
27
|
+
return undefined;
|
|
28
|
+
case "EXECUTION_COMPLETED":
|
|
29
|
+
case "EXECUTION_FAILED":
|
|
30
|
+
case "EXECUTION_CANCELLED":
|
|
31
|
+
return finiteOrUndefined(e.timestamp);
|
|
32
|
+
case "EXECUTION_CONTINUED":
|
|
33
|
+
if (e.metadata?.kernel === true)
|
|
34
|
+
return finiteOrUndefined(e.timestamp);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
return undefined;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* ADR 0146 - was this execution RE-OPENED after a terminal event? True iff its tail is live
|
|
41
|
+
* (`terminalEndOf` returns `undefined` because a RESUMED / SUSPENDED / STARTED follows) AND a terminal
|
|
42
|
+
* event (the same set as `terminalEndOf`) precedes that live tail. A run that never ended is false.
|
|
43
|
+
* A terminal event with a non-finite timestamp still counts as an end here (the log shows it ended).
|
|
44
|
+
*/
|
|
45
|
+
function wasReopened(events) {
|
|
46
|
+
let live = false;
|
|
47
|
+
for (let i = events.length - 1; i >= 0; i--) {
|
|
48
|
+
const e = events[i];
|
|
49
|
+
switch (e.eventType) {
|
|
50
|
+
case "EXECUTION_RESUMED":
|
|
51
|
+
case "EXECUTION_SUSPENDED":
|
|
52
|
+
case "EXECUTION_STARTED":
|
|
53
|
+
live = true;
|
|
54
|
+
break;
|
|
55
|
+
case "EXECUTION_COMPLETED":
|
|
56
|
+
case "EXECUTION_FAILED":
|
|
57
|
+
case "EXECUTION_CANCELLED":
|
|
58
|
+
return live;
|
|
59
|
+
case "EXECUTION_CONTINUED":
|
|
60
|
+
if (e.metadata?.kernel === true)
|
|
61
|
+
return live;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
return false;
|
|
65
|
+
}
|
|
66
|
+
//# sourceMappingURL=executionEnd.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"executionEnd.js","sourceRoot":"","sources":["../src/executionEnd.ts"],"names":[],"mappings":";;AAmBA,sCAiBC;AAQD,kCAmBC;AA7DD,sGAAsG;AACtG,uGAAuG;AACvG,MAAM,iBAAiB,GAAG,CAAC,CAAU,EAAsB,EAAE,CAC3D,OAAO,CAAC,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;AAE9D;;;;;;;;;;;GAWG;AACH,SAAgB,aAAa,CAAC,MAAgC;IAC5D,KAAK,IAAI,CAAC,GAAG,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QAC5C,MAAM,CAAC,GAAG,MAAM,CAAC,CAAC,CAAkB,CAAC;QACrC,QAAQ,CAAC,CAAC,SAAS,EAAE,CAAC;YACpB,KAAK,mBAAmB,CAAC;YACzB,KAAK,qBAAqB,CAAC;YAC3B,KAAK,mBAAmB;gBACtB,OAAO,SAAS,CAAC;YACnB,KAAK,qBAAqB,CAAC;YAC3B,KAAK,kBAAkB,CAAC;YACxB,KAAK,qBAAqB;gBACxB,OAAO,iBAAiB,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;YACxC,KAAK,qBAAqB;gBACxB,IAAI,CAAC,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI;oBAAE,OAAO,iBAAiB,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;QAC3E,CAAC;IACH,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED;;;;;GAKG;AACH,SAAgB,WAAW,CAAC,MAAgC;IAC1D,IAAI,IAAI,GAAG,KAAK,CAAC;IACjB,KAAK,IAAI,CAAC,GAAG,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QAC5C,MAAM,CAAC,GAAG,MAAM,CAAC,CAAC,CAAkB,CAAC;QACrC,QAAQ,CAAC,CAAC,SAAS,EAAE,CAAC;YACpB,KAAK,mBAAmB,CAAC;YACzB,KAAK,qBAAqB,CAAC;YAC3B,KAAK,mBAAmB;gBACtB,IAAI,GAAG,IAAI,CAAC;gBACZ,MAAM;YACR,KAAK,qBAAqB,CAAC;YAC3B,KAAK,kBAAkB,CAAC;YACxB,KAAK,qBAAqB;gBACxB,OAAO,IAAI,CAAC;YACd,KAAK,qBAAqB;gBACxB,IAAI,CAAC,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI;oBAAE,OAAO,IAAI,CAAC;QACjD,CAAC;IACH,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC"}
|