@smthrs/plan 0.0.0-stage → 1.0.0-rc.13
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/CHANGELOG.md +189 -0
- package/LICENSE +21 -0
- package/README.md +230 -2
- package/THIRD_PARTY_NOTICES.md +48 -0
- package/dist/cjs/CachePolicy.d.ts +131 -0
- package/dist/cjs/CachePolicy.d.ts.map +1 -0
- package/dist/cjs/CachePolicy.js +50 -0
- package/dist/cjs/CachePolicy.js.map +7 -0
- package/dist/cjs/Effects.d.ts +258 -0
- package/dist/cjs/Effects.d.ts.map +1 -0
- package/dist/cjs/Effects.js +76 -0
- package/dist/cjs/Effects.js.map +7 -0
- package/dist/cjs/FileSet.d.ts +366 -0
- package/dist/cjs/FileSet.d.ts.map +1 -0
- package/dist/cjs/FileSet.js +196 -0
- package/dist/cjs/FileSet.js.map +7 -0
- package/dist/cjs/GraphBuildError.d.ts +120 -0
- package/dist/cjs/GraphBuildError.d.ts.map +1 -0
- package/dist/cjs/GraphBuildError.js +71 -0
- package/dist/cjs/GraphBuildError.js.map +7 -0
- package/dist/cjs/KeyMaterial.d.ts +107 -0
- package/dist/cjs/KeyMaterial.d.ts.map +1 -0
- package/dist/cjs/KeyMaterial.js +64 -0
- package/dist/cjs/KeyMaterial.js.map +7 -0
- package/dist/cjs/Node.d.ts +685 -0
- package/dist/cjs/Node.d.ts.map +1 -0
- package/dist/cjs/Node.js +230 -0
- package/dist/cjs/Node.js.map +7 -0
- package/dist/cjs/Placement.d.ts +117 -0
- package/dist/cjs/Placement.d.ts.map +1 -0
- package/dist/cjs/Placement.js +46 -0
- package/dist/cjs/Placement.js.map +7 -0
- package/dist/cjs/Plan.d.ts +489 -0
- package/dist/cjs/Plan.d.ts.map +1 -0
- package/dist/cjs/Plan.js +511 -0
- package/dist/cjs/Plan.js.map +7 -0
- package/dist/cjs/PlanDiff.d.ts +77 -0
- package/dist/cjs/PlanDiff.d.ts.map +1 -0
- package/dist/cjs/PlanDiff.js +149 -0
- package/dist/cjs/PlanDiff.js.map +7 -0
- package/dist/cjs/Planned.d.ts +121 -0
- package/dist/cjs/Planned.d.ts.map +1 -0
- package/dist/cjs/Planned.js +72 -0
- package/dist/cjs/Planned.js.map +7 -0
- package/dist/cjs/Repetition.d.ts +31 -0
- package/dist/cjs/Repetition.d.ts.map +1 -0
- package/dist/cjs/Repetition.js +36 -0
- package/dist/cjs/Repetition.js.map +7 -0
- package/dist/cjs/Scheduling.d.ts +89 -0
- package/dist/cjs/Scheduling.d.ts.map +1 -0
- package/dist/cjs/Scheduling.js +76 -0
- package/dist/cjs/Scheduling.js.map +7 -0
- package/dist/cjs/StepKey.d.ts +354 -0
- package/dist/cjs/StepKey.d.ts.map +1 -0
- package/dist/cjs/StepKey.js +313 -0
- package/dist/cjs/StepKey.js.map +7 -0
- package/dist/cjs/index.d.ts +91 -0
- package/dist/cjs/index.d.ts.map +1 -0
- package/dist/cjs/index.js +59 -0
- package/dist/cjs/index.js.map +7 -0
- package/dist/cjs/internal/ConflictAnnotation.d.ts +59 -0
- package/dist/cjs/internal/ConflictAnnotation.d.ts.map +1 -0
- package/dist/cjs/internal/ConflictAnnotation.js +247 -0
- package/dist/cjs/internal/ConflictAnnotation.js.map +7 -0
- package/dist/cjs/internal/EffectCandidates.d.ts +19 -0
- package/dist/cjs/internal/EffectCandidates.d.ts.map +1 -0
- package/dist/cjs/internal/EffectCandidates.js +92 -0
- package/dist/cjs/internal/EffectCandidates.js.map +7 -0
- package/dist/cjs/internal/JsonMirror.d.ts +34 -0
- package/dist/cjs/internal/JsonMirror.d.ts.map +1 -0
- package/dist/cjs/internal/JsonMirror.js +195 -0
- package/dist/cjs/internal/JsonMirror.js.map +7 -0
- package/dist/cjs/internal/SchemaIdentity.d.ts +140 -0
- package/dist/cjs/internal/SchemaIdentity.d.ts.map +1 -0
- package/dist/cjs/internal/SchemaIdentity.js +718 -0
- package/dist/cjs/internal/SchemaIdentity.js.map +7 -0
- package/dist/cjs/internal/effects.d.ts +245 -0
- package/dist/cjs/internal/effects.d.ts.map +1 -0
- package/dist/cjs/internal/effects.js +290 -0
- package/dist/cjs/internal/effects.js.map +7 -0
- package/dist/cjs/internal/node.d.ts +526 -0
- package/dist/cjs/internal/node.d.ts.map +1 -0
- package/dist/cjs/internal/node.js +313 -0
- package/dist/cjs/internal/node.js.map +7 -0
- package/dist/cjs/package.json +1 -0
- package/dist/cjs/test/PlanFixtures.d.ts +127 -0
- package/dist/cjs/test/PlanFixtures.d.ts.map +1 -0
- package/dist/cjs/test/PlanFixtures.js +59 -0
- package/dist/cjs/test/PlanFixtures.js.map +7 -0
- package/dist/esm/CachePolicy.d.ts +131 -0
- package/dist/esm/CachePolicy.d.ts.map +1 -0
- package/dist/esm/CachePolicy.js +117 -0
- package/dist/esm/CachePolicy.js.map +1 -0
- package/dist/esm/Effects.d.ts +258 -0
- package/dist/esm/Effects.d.ts.map +1 -0
- package/dist/esm/Effects.js +178 -0
- package/dist/esm/Effects.js.map +1 -0
- package/dist/esm/FileSet.d.ts +366 -0
- package/dist/esm/FileSet.d.ts.map +1 -0
- package/dist/esm/FileSet.js +398 -0
- package/dist/esm/FileSet.js.map +1 -0
- package/dist/esm/GraphBuildError.d.ts +120 -0
- package/dist/esm/GraphBuildError.d.ts.map +1 -0
- package/dist/esm/GraphBuildError.js +145 -0
- package/dist/esm/GraphBuildError.js.map +1 -0
- package/dist/esm/KeyMaterial.d.ts +107 -0
- package/dist/esm/KeyMaterial.d.ts.map +1 -0
- package/dist/esm/KeyMaterial.js +92 -0
- package/dist/esm/KeyMaterial.js.map +1 -0
- package/dist/esm/Node.d.ts +685 -0
- package/dist/esm/Node.d.ts.map +1 -0
- package/dist/esm/Node.js +591 -0
- package/dist/esm/Node.js.map +1 -0
- package/dist/esm/Placement.d.ts +117 -0
- package/dist/esm/Placement.d.ts.map +1 -0
- package/dist/esm/Placement.js +65 -0
- package/dist/esm/Placement.js.map +1 -0
- package/dist/esm/Plan.d.ts +489 -0
- package/dist/esm/Plan.d.ts.map +1 -0
- package/dist/esm/Plan.js +718 -0
- package/dist/esm/Plan.js.map +1 -0
- package/dist/esm/PlanDiff.d.ts +77 -0
- package/dist/esm/PlanDiff.d.ts.map +1 -0
- package/dist/esm/PlanDiff.js +205 -0
- package/dist/esm/PlanDiff.js.map +1 -0
- package/dist/esm/Planned.d.ts +121 -0
- package/dist/esm/Planned.d.ts.map +1 -0
- package/dist/esm/Planned.js +147 -0
- package/dist/esm/Planned.js.map +1 -0
- package/dist/esm/Repetition.d.ts +31 -0
- package/dist/esm/Repetition.d.ts.map +1 -0
- package/dist/esm/Repetition.js +24 -0
- package/dist/esm/Repetition.js.map +1 -0
- package/dist/esm/Scheduling.d.ts +89 -0
- package/dist/esm/Scheduling.d.ts.map +1 -0
- package/dist/esm/Scheduling.js +82 -0
- package/dist/esm/Scheduling.js.map +1 -0
- package/dist/esm/StepKey.d.ts +354 -0
- package/dist/esm/StepKey.d.ts.map +1 -0
- package/dist/esm/StepKey.js +503 -0
- package/dist/esm/StepKey.js.map +1 -0
- package/dist/esm/index.d.ts +91 -0
- package/dist/esm/index.d.ts.map +1 -0
- package/dist/esm/index.js +91 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/internal/ConflictAnnotation.d.ts +59 -0
- package/dist/esm/internal/ConflictAnnotation.d.ts.map +1 -0
- package/dist/esm/internal/ConflictAnnotation.js +332 -0
- package/dist/esm/internal/ConflictAnnotation.js.map +1 -0
- package/dist/esm/internal/EffectCandidates.d.ts +19 -0
- package/dist/esm/internal/EffectCandidates.d.ts.map +1 -0
- package/dist/esm/internal/EffectCandidates.js +86 -0
- package/dist/esm/internal/EffectCandidates.js.map +1 -0
- package/dist/esm/internal/JsonMirror.d.ts +34 -0
- package/dist/esm/internal/JsonMirror.d.ts.map +1 -0
- package/dist/esm/internal/JsonMirror.js +204 -0
- package/dist/esm/internal/JsonMirror.js.map +1 -0
- package/dist/esm/internal/SchemaIdentity.d.ts +140 -0
- package/dist/esm/internal/SchemaIdentity.d.ts.map +1 -0
- package/dist/esm/internal/SchemaIdentity.js +1002 -0
- package/dist/esm/internal/SchemaIdentity.js.map +1 -0
- package/dist/esm/internal/effects.d.ts +245 -0
- package/dist/esm/internal/effects.d.ts.map +1 -0
- package/dist/esm/internal/effects.js +459 -0
- package/dist/esm/internal/effects.js.map +1 -0
- package/dist/esm/internal/node.d.ts +526 -0
- package/dist/esm/internal/node.d.ts.map +1 -0
- package/dist/esm/internal/node.js +565 -0
- package/dist/esm/internal/node.js.map +1 -0
- package/dist/esm/test/PlanFixtures.d.ts +127 -0
- package/dist/esm/test/PlanFixtures.d.ts.map +1 -0
- package/dist/esm/test/PlanFixtures.js +60 -0
- package/dist/esm/test/PlanFixtures.js.map +1 -0
- package/docs/README.md +167 -0
- package/docs/api.md +1485 -0
- package/docs/concepts/authoring-ast.md +204 -0
- package/docs/concepts/effects-and-conflicts.md +135 -0
- package/docs/concepts/plan-value.md +168 -0
- package/docs/concepts/step-keys.md +179 -0
- package/docs/guides/author-a-node-graph.md +182 -0
- package/docs/guides/compile-a-plan.md +146 -0
- package/docs/guides/declare-file-effects.md +143 -0
- package/docs/guides/diff-two-plans.md +310 -0
- package/docs/installation.md +75 -0
- package/docs/quickstart.md +128 -0
- package/docs/testing.md +73 -0
- package/docs/troubleshooting.md +314 -0
- package/package.json +255 -3
- package/src/CachePolicy.ts +143 -0
- package/src/Effects.ts +302 -0
- package/src/FileSet.ts +493 -0
- package/src/GraphBuildError.ts +156 -0
- package/src/KeyMaterial.ts +111 -0
- package/src/Node.ts +974 -0
- package/src/Placement.ts +99 -0
- package/src/Plan.ts +911 -0
- package/src/PlanDiff.ts +244 -0
- package/src/Planned.ts +208 -0
- package/src/Repetition.ts +33 -0
- package/src/Scheduling.ts +154 -0
- package/src/StepKey.ts +736 -0
- package/src/index.ts +103 -0
- package/src/internal/ConflictAnnotation.ts +374 -0
- package/src/internal/EffectCandidates.ts +89 -0
- package/src/internal/JsonMirror.ts +255 -0
- package/src/internal/SchemaIdentity.ts +1096 -0
- package/src/internal/effects.ts +543 -0
- package/src/internal/node.ts +859 -0
- package/src/test/PlanFixtures.ts +76 -0
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A plan comparison, as a value.
|
|
3
|
+
*
|
|
4
|
+
* A plan diff answers "which steps changed key (and _which input_
|
|
5
|
+
* changed them), what entered the envelope, what joined the release set —
|
|
6
|
+
* 'what is different about this run' is a set comparison, not archaeology."
|
|
7
|
+
* This module is the set comparison.
|
|
8
|
+
*
|
|
9
|
+
* The **verdict** is the key: two nodes with the same key are the same step,
|
|
10
|
+
* under the same id or a moved one, and nothing else needs saying. The
|
|
11
|
+
* **attribution** — `changed: ["input[1]"]` — is a report for a human, derived
|
|
12
|
+
* by comparing the declarations field by field. It is deliberately not part of any digest.
|
|
13
|
+
*
|
|
14
|
+
* @since 0.1.0
|
|
15
|
+
*/
|
|
16
|
+
import type * as Plan from "./Plan.ts";
|
|
17
|
+
/**
|
|
18
|
+
* A node whose key moved, with the fields that moved it.
|
|
19
|
+
*
|
|
20
|
+
* @since 0.1.0
|
|
21
|
+
* @category models
|
|
22
|
+
*/
|
|
23
|
+
export interface Rekeyed {
|
|
24
|
+
/** The node's id in the newer plan. */
|
|
25
|
+
readonly id: string;
|
|
26
|
+
/** The step key the paired node carried in the older plan. */
|
|
27
|
+
readonly from: string;
|
|
28
|
+
/** The step key the node carries in the newer plan. */
|
|
29
|
+
readonly to: string;
|
|
30
|
+
/**
|
|
31
|
+
* Field labels such as `"kind"`, `"body"`, `"layers"`, `"capabilities"`,
|
|
32
|
+
* `"effects"`, and `"input[0]"` whose declaration differs. `"kind"` is the
|
|
33
|
+
* effect tier (`sealed`, `compensable`, or `irreversible`). A
|
|
34
|
+
* `Pending`-referenced upstream re-key is attributed to that input position
|
|
35
|
+
* too. `changed` is empty only when none of the compared fields moved.
|
|
36
|
+
*/
|
|
37
|
+
readonly changed: ReadonlyArray<string>;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* What changed between two plans of the same flow.
|
|
41
|
+
*
|
|
42
|
+
* @since 0.1.0
|
|
43
|
+
* @category models
|
|
44
|
+
*/
|
|
45
|
+
export interface PlanDiff {
|
|
46
|
+
/** Ids, in the newer plan, of nodes with no counterpart in the older plan. */
|
|
47
|
+
readonly added: ReadonlyArray<string>;
|
|
48
|
+
/** Ids, in the older plan, of nodes with no counterpart in the newer plan. */
|
|
49
|
+
readonly removed: ReadonlyArray<string>;
|
|
50
|
+
/** Nodes paired by id whose step key changed, with the fields that changed it. */
|
|
51
|
+
readonly rekeyed: ReadonlyArray<Rekeyed>;
|
|
52
|
+
/** Ids, in the newer plan, of nodes whose step key is unchanged, including nodes whose id moved. */
|
|
53
|
+
readonly unchanged: ReadonlyArray<string>;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Compares a plan against the last plan for the same flow.
|
|
57
|
+
*
|
|
58
|
+
* Nodes pair in three passes, each over the nodes no earlier pass paired:
|
|
59
|
+
* the same id with the same key, then the same key under any id, then the
|
|
60
|
+
* same id with a different key. The second pass exists because flow node ids
|
|
61
|
+
* can be positional: inserting a step shifts the ids after it while their
|
|
62
|
+
* keys stay equal, and that is one added step, not a re-key of every later
|
|
63
|
+
* one (#3905).
|
|
64
|
+
*
|
|
65
|
+
* `added`, `rekeyed`, and `unchanged` name nodes by their id in `next`;
|
|
66
|
+
* `removed` names nodes by their id in `previous`. A moved id can therefore
|
|
67
|
+
* appear once in `removed` or `added` and once in `unchanged`.
|
|
68
|
+
*
|
|
69
|
+
* @param previous - The last plan recorded for the flow.
|
|
70
|
+
* @param next - The plan to compare against it.
|
|
71
|
+
* @returns The added, removed, re-keyed, and unchanged node ids, each in its
|
|
72
|
+
* plan's node order.
|
|
73
|
+
* @since 0.1.0
|
|
74
|
+
* @category constructors
|
|
75
|
+
*/
|
|
76
|
+
export declare const diff: (previous: Plan.Plan, next: Plan.Plan) => PlanDiff;
|
|
77
|
+
//# sourceMappingURL=PlanDiff.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PlanDiff.d.ts","sourceRoot":"","sources":["../../src/PlanDiff.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAGH,OAAO,KAAK,KAAK,IAAI,MAAM,WAAW,CAAA;AAGtC;;;;;GAKG;AACH,MAAM,WAAW,OAAO;IACtB,uCAAuC;IACvC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;IACnB,8DAA8D;IAC9D,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,uDAAuD;IACvD,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;IACnB;;;;;;OAMG;IACH,QAAQ,CAAC,OAAO,EAAE,aAAa,CAAC,MAAM,CAAC,CAAA;CACxC;AAED;;;;;GAKG;AACH,MAAM,WAAW,QAAQ;IACvB,8EAA8E;IAC9E,QAAQ,CAAC,KAAK,EAAE,aAAa,CAAC,MAAM,CAAC,CAAA;IACrC,8EAA8E;IAC9E,QAAQ,CAAC,OAAO,EAAE,aAAa,CAAC,MAAM,CAAC,CAAA;IACvC,kFAAkF;IAClF,QAAQ,CAAC,OAAO,EAAE,aAAa,CAAC,OAAO,CAAC,CAAA;IACxC,oGAAoG;IACpG,QAAQ,CAAC,SAAS,EAAE,aAAa,CAAC,MAAM,CAAC,CAAA;CAC1C;AAuGD;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,eAAO,MAAM,IAAI,GAAI,UAAU,IAAI,CAAC,IAAI,EAAE,MAAM,IAAI,CAAC,IAAI,KAAG,QA6D3D,CAAA"}
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
var PlanDiff_exports = {};
|
|
20
|
+
__export(PlanDiff_exports, {
|
|
21
|
+
diff: () => diff
|
|
22
|
+
});
|
|
23
|
+
module.exports = __toCommonJS(PlanDiff_exports);
|
|
24
|
+
var import_JsonMirror = require("./internal/JsonMirror.js");
|
|
25
|
+
const stable = (value) => {
|
|
26
|
+
if (typeof value === "bigint") return `${value}n`;
|
|
27
|
+
if (value === null || typeof value !== "object") return JSON.stringify(value) ?? "undefined";
|
|
28
|
+
if (Array.isArray(value)) return `[${value.map(stable).join(",")}]`;
|
|
29
|
+
const entries = Object.entries(value).sort(([left], [right]) => left < right ? -1 : 1);
|
|
30
|
+
return `{${entries.map(([name, entry]) => `${JSON.stringify(name)}:${stable(entry)}`).join(",")}}`;
|
|
31
|
+
};
|
|
32
|
+
const plannedReference = (_value, reference) => ({
|
|
33
|
+
_tag: "PlannedReference",
|
|
34
|
+
node: reference.node,
|
|
35
|
+
path: reference.path
|
|
36
|
+
});
|
|
37
|
+
const fieldComparison = () => {
|
|
38
|
+
const refused = /* @__PURE__ */ new Map();
|
|
39
|
+
const token = (input, nodeId, field) => {
|
|
40
|
+
try {
|
|
41
|
+
return stable((0, import_JsonMirror.jsonMirror)(input, plannedReference));
|
|
42
|
+
} catch {
|
|
43
|
+
const address = JSON.stringify([nodeId, field]);
|
|
44
|
+
let fields = refused.get(input);
|
|
45
|
+
if (fields === void 0) {
|
|
46
|
+
fields = /* @__PURE__ */ new Map();
|
|
47
|
+
refused.set(input, fields);
|
|
48
|
+
}
|
|
49
|
+
let sentinel = fields.get(address);
|
|
50
|
+
if (sentinel === void 0) {
|
|
51
|
+
sentinel = Symbol(address);
|
|
52
|
+
fields.set(address, sentinel);
|
|
53
|
+
}
|
|
54
|
+
return sentinel;
|
|
55
|
+
}
|
|
56
|
+
};
|
|
57
|
+
return (previous, next, nodeId, field) => token(previous, nodeId, field) === token(next, nodeId, field);
|
|
58
|
+
};
|
|
59
|
+
const changedFields = (previous, next, rekeyedDependencies, sameField) => {
|
|
60
|
+
const changed = [];
|
|
61
|
+
if (!sameField(previous.material.version, next.material.version, next.id, "version")) changed.push("version");
|
|
62
|
+
if (previous.material.kind !== next.material.kind) changed.push("kind");
|
|
63
|
+
if (!sameField(previous.material.body, next.material.body, next.id, "body")) changed.push("body");
|
|
64
|
+
if (!sameField(previous.material.nondeterministic, next.material.nondeterministic, next.id, "nondeterministic")) {
|
|
65
|
+
changed.push("nondeterministic");
|
|
66
|
+
}
|
|
67
|
+
if (!sameField(previous.material.effects, next.material.effects, next.id, "effects")) changed.push("effects");
|
|
68
|
+
if (!sameField(previous.material.placement, next.material.placement, next.id, "placement")) {
|
|
69
|
+
changed.push("placement");
|
|
70
|
+
}
|
|
71
|
+
const width = Math.max(previous.material.inputs.length, next.material.inputs.length);
|
|
72
|
+
for (let index = 0; index < width; index++) {
|
|
73
|
+
const before = previous.material.inputs[index];
|
|
74
|
+
const after = next.material.inputs[index];
|
|
75
|
+
const field = `input[${index}]`;
|
|
76
|
+
if (before === void 0 || after === void 0 || !sameField(before, after, next.id, field)) {
|
|
77
|
+
changed.push(field);
|
|
78
|
+
continue;
|
|
79
|
+
}
|
|
80
|
+
if (after._tag !== "Literal" && rekeyedDependencies.has(after.from)) changed.push(field);
|
|
81
|
+
}
|
|
82
|
+
if (!sameField(previous.material.layers, next.material.layers, next.id, "layers")) changed.push("layers");
|
|
83
|
+
if (!sameField(previous.material.capabilities, next.material.capabilities, next.id, "capabilities")) {
|
|
84
|
+
changed.push("capabilities");
|
|
85
|
+
}
|
|
86
|
+
return changed;
|
|
87
|
+
};
|
|
88
|
+
const diff = (previous, next) => {
|
|
89
|
+
const pairs = /* @__PURE__ */ new Map();
|
|
90
|
+
const paired = /* @__PURE__ */ new Set();
|
|
91
|
+
const pair = (node, original) => {
|
|
92
|
+
pairs.set(node, original);
|
|
93
|
+
paired.add(original);
|
|
94
|
+
};
|
|
95
|
+
const before = new Map(previous.nodes.map((node) => [node.id, node]));
|
|
96
|
+
for (const node of next.nodes) {
|
|
97
|
+
const original = before.get(node.id);
|
|
98
|
+
if (original !== void 0 && original.key === node.key) pair(node, original);
|
|
99
|
+
}
|
|
100
|
+
const byKey = /* @__PURE__ */ new Map();
|
|
101
|
+
for (const node of previous.nodes) {
|
|
102
|
+
if (paired.has(node)) continue;
|
|
103
|
+
const same = byKey.get(node.key);
|
|
104
|
+
if (same === void 0) byKey.set(node.key, [node]);
|
|
105
|
+
else same.push(node);
|
|
106
|
+
}
|
|
107
|
+
for (const node of next.nodes) {
|
|
108
|
+
if (pairs.has(node)) continue;
|
|
109
|
+
const original = byKey.get(node.key)?.shift();
|
|
110
|
+
if (original !== void 0) pair(node, original);
|
|
111
|
+
}
|
|
112
|
+
const rekeyedIds = /* @__PURE__ */ new Set();
|
|
113
|
+
for (const node of next.nodes) {
|
|
114
|
+
if (pairs.has(node)) continue;
|
|
115
|
+
const original = before.get(node.id);
|
|
116
|
+
if (original !== void 0 && !paired.has(original)) {
|
|
117
|
+
pair(node, original);
|
|
118
|
+
rekeyedIds.add(node.id);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
const added = [];
|
|
122
|
+
const rekeyed = [];
|
|
123
|
+
const unchanged = [];
|
|
124
|
+
const sameField = fieldComparison();
|
|
125
|
+
for (const node of next.nodes) {
|
|
126
|
+
const original = pairs.get(node);
|
|
127
|
+
if (original === void 0) {
|
|
128
|
+
added.push(node.id);
|
|
129
|
+
continue;
|
|
130
|
+
}
|
|
131
|
+
if (original.key === node.key) {
|
|
132
|
+
unchanged.push(node.id);
|
|
133
|
+
continue;
|
|
134
|
+
}
|
|
135
|
+
rekeyed.push({
|
|
136
|
+
id: node.id,
|
|
137
|
+
from: original.key,
|
|
138
|
+
to: node.key,
|
|
139
|
+
changed: changedFields(original, node, rekeyedIds, sameField)
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
return {
|
|
143
|
+
added,
|
|
144
|
+
removed: previous.nodes.filter((node) => !paired.has(node)).map((node) => node.id),
|
|
145
|
+
rekeyed,
|
|
146
|
+
unchanged
|
|
147
|
+
};
|
|
148
|
+
};
|
|
149
|
+
//# sourceMappingURL=PlanDiff.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/PlanDiff.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * A plan comparison, as a value.\n *\n * A plan diff answers \"which steps changed key (and _which input_\n * changed them), what entered the envelope, what joined the release set \u2014\n * 'what is different about this run' is a set comparison, not archaeology.\"\n * This module is the set comparison.\n *\n * The **verdict** is the key: two nodes with the same key are the same step,\n * under the same id or a moved one, and nothing else needs saying. The\n * **attribution** \u2014 `changed: [\"input[1]\"]` \u2014 is a report for a human, derived\n * by comparing the declarations field by field. It is deliberately not part of any digest.\n *\n * @since 0.1.0\n */\n\nimport { jsonMirror } from \"./internal/JsonMirror.ts\"\nimport type * as Plan from \"./Plan.ts\"\nimport type * as Planned from \"./Planned.ts\"\n\n/**\n * A node whose key moved, with the fields that moved it.\n *\n * @since 0.1.0\n * @category models\n */\nexport interface Rekeyed {\n /** The node's id in the newer plan. */\n readonly id: string\n /** The step key the paired node carried in the older plan. */\n readonly from: string\n /** The step key the node carries in the newer plan. */\n readonly to: string\n /**\n * Field labels such as `\"kind\"`, `\"body\"`, `\"layers\"`, `\"capabilities\"`,\n * `\"effects\"`, and `\"input[0]\"` whose declaration differs. `\"kind\"` is the\n * effect tier (`sealed`, `compensable`, or `irreversible`). A\n * `Pending`-referenced upstream re-key is attributed to that input position\n * too. `changed` is empty only when none of the compared fields moved.\n */\n readonly changed: ReadonlyArray<string>\n}\n\n/**\n * What changed between two plans of the same flow.\n *\n * @since 0.1.0\n * @category models\n */\nexport interface PlanDiff {\n /** Ids, in the newer plan, of nodes with no counterpart in the older plan. */\n readonly added: ReadonlyArray<string>\n /** Ids, in the older plan, of nodes with no counterpart in the newer plan. */\n readonly removed: ReadonlyArray<string>\n /** Nodes paired by id whose step key changed, with the fields that changed it. */\n readonly rekeyed: ReadonlyArray<Rekeyed>\n /** Ids, in the newer plan, of nodes whose step key is unchanged, including nodes whose id moved. */\n readonly unchanged: ReadonlyArray<string>\n}\n\n/**\n * Order-insensitive structural comparison for the attribution report only.\n * Digests go through RFC 8785 canonical JSON; this does not have to, and\n * saying so keeps the two from being confused.\n *\n * @private\n */\nconst stable = (value: unknown): string => {\n if (typeof value === \"bigint\") return `${value}n`\n if (value === null || typeof value !== \"object\") return JSON.stringify(value) ?? \"undefined\"\n if (Array.isArray(value)) return `[${value.map(stable).join(\",\")}]`\n const entries = Object.entries(value as Record<string, unknown>).sort(([left], [right]) => left < right ? -1 : 1)\n return `{${entries.map(([name, entry]) => `${JSON.stringify(name)}:${stable(entry)}`).join(\",\")}}`\n}\n\n/**\n * A planned value compares as the reference an AST stores for it, so the same\n * reference at the same place is unchanged.\n *\n * @private\n */\nconst plannedReference = (_value: unknown, reference: Planned.Reference) => ({\n _tag: \"PlannedReference\",\n node: reference.node,\n path: reference.path\n})\n\n/** @private */\ntype ComparisonToken = string | symbol\n\n/**\n * Projects compared fields through the key's JSON semantics. A refused value\n * receives an identity token scoped to its node and field, so the same value\n * remains equal to itself without equating two distinct refused values.\n *\n * @private\n */\nconst fieldComparison = () => {\n const refused = new Map<unknown, Map<string, symbol>>()\n const token = (input: unknown, nodeId: string, field: string): ComparisonToken => {\n try {\n return stable(jsonMirror(input, plannedReference))\n } catch {\n const address = JSON.stringify([nodeId, field])\n let fields = refused.get(input)\n if (fields === undefined) {\n fields = new Map()\n refused.set(input, fields)\n }\n let sentinel = fields.get(address)\n if (sentinel === undefined) {\n sentinel = Symbol(address)\n fields.set(address, sentinel)\n }\n return sentinel\n }\n }\n return (previous: unknown, next: unknown, nodeId: string, field: string): boolean =>\n token(previous, nodeId, field) === token(next, nodeId, field)\n}\n\n/** @private */\nconst changedFields = (\n previous: Plan.PlanNode,\n next: Plan.PlanNode,\n rekeyedDependencies: ReadonlySet<string>,\n sameField: ReturnType<typeof fieldComparison>\n): ReadonlyArray<string> => {\n const changed: Array<string> = []\n // StepKey.materialBody is the identity list this attribution must mirror.\n // Inputs, layers, and capabilities complete fromKeyMaterial's hashed value,\n // and material.kind selects the key namespace (content versus tier-bearing\n // plan declaration), so a tier-only move still re-keys and is blamed here.\n if (!sameField(previous.material.version, next.material.version, next.id, \"version\")) changed.push(\"version\")\n if (previous.material.kind !== next.material.kind) changed.push(\"kind\")\n if (!sameField(previous.material.body, next.material.body, next.id, \"body\")) changed.push(\"body\")\n if (!sameField(previous.material.nondeterministic, next.material.nondeterministic, next.id, \"nondeterministic\")) {\n changed.push(\"nondeterministic\")\n }\n if (!sameField(previous.material.effects, next.material.effects, next.id, \"effects\")) changed.push(\"effects\")\n if (!sameField(previous.material.placement, next.material.placement, next.id, \"placement\")) {\n changed.push(\"placement\")\n }\n const width = Math.max(previous.material.inputs.length, next.material.inputs.length)\n for (let index = 0; index < width; index++) {\n const before = previous.material.inputs[index]\n const after = next.material.inputs[index]\n const field = `input[${index}]`\n if (before === undefined || after === undefined || !sameField(before, after, next.id, field)) {\n changed.push(field)\n continue\n }\n if (after._tag !== \"Literal\" && rekeyedDependencies.has(after.from)) changed.push(field)\n }\n if (!sameField(previous.material.layers, next.material.layers, next.id, \"layers\")) changed.push(\"layers\")\n if (!sameField(previous.material.capabilities, next.material.capabilities, next.id, \"capabilities\")) {\n changed.push(\"capabilities\")\n }\n return changed\n}\n\n/**\n * Compares a plan against the last plan for the same flow.\n *\n * Nodes pair in three passes, each over the nodes no earlier pass paired:\n * the same id with the same key, then the same key under any id, then the\n * same id with a different key. The second pass exists because flow node ids\n * can be positional: inserting a step shifts the ids after it while their\n * keys stay equal, and that is one added step, not a re-key of every later\n * one (#3905).\n *\n * `added`, `rekeyed`, and `unchanged` name nodes by their id in `next`;\n * `removed` names nodes by their id in `previous`. A moved id can therefore\n * appear once in `removed` or `added` and once in `unchanged`.\n *\n * @param previous - The last plan recorded for the flow.\n * @param next - The plan to compare against it.\n * @returns The added, removed, re-keyed, and unchanged node ids, each in its\n * plan's node order.\n * @since 0.1.0\n * @category constructors\n */\nexport const diff = (previous: Plan.Plan, next: Plan.Plan): PlanDiff => {\n // pairs maps a next node to the previous node it is the same step as.\n const pairs = new Map<Plan.PlanNode, Plan.PlanNode>()\n const paired = new Set<Plan.PlanNode>()\n const pair = (node: Plan.PlanNode, original: Plan.PlanNode) => {\n pairs.set(node, original)\n paired.add(original)\n }\n const before = new Map(previous.nodes.map((node) => [node.id, node]))\n for (const node of next.nodes) {\n const original = before.get(node.id)\n if (original !== undefined && original.key === node.key) pair(node, original)\n }\n const byKey = new Map<string, Array<Plan.PlanNode>>()\n for (const node of previous.nodes) {\n if (paired.has(node)) continue\n const same = byKey.get(node.key)\n if (same === undefined) byKey.set(node.key, [node])\n else same.push(node)\n }\n for (const node of next.nodes) {\n if (pairs.has(node)) continue\n const original = byKey.get(node.key)?.shift()\n if (original !== undefined) pair(node, original)\n }\n const rekeyedIds = new Set<string>()\n for (const node of next.nodes) {\n if (pairs.has(node)) continue\n const original = before.get(node.id)\n if (original !== undefined && !paired.has(original)) {\n pair(node, original)\n rekeyedIds.add(node.id)\n }\n }\n const added: Array<string> = []\n const rekeyed: Array<Rekeyed> = []\n const unchanged: Array<string> = []\n const sameField = fieldComparison()\n for (const node of next.nodes) {\n const original = pairs.get(node)\n if (original === undefined) {\n added.push(node.id)\n continue\n }\n if (original.key === node.key) {\n unchanged.push(node.id)\n continue\n }\n rekeyed.push({\n id: node.id,\n from: original.key,\n to: node.key,\n changed: changedFields(original, node, rekeyedIds, sameField)\n })\n }\n return {\n added,\n removed: previous.nodes.filter((node) => !paired.has(node)).map((node) => node.id),\n rekeyed,\n unchanged\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The placeholder a body sees where a step result will be.
|
|
3
|
+
*
|
|
4
|
+
* A flow body runs at PLAN time, so its
|
|
5
|
+
* own payload is real data while every step result is a value that does not
|
|
6
|
+
* exist yet. That value has a name and one rule: a planned value may be **passed** — into a payload field,
|
|
7
|
+
* into a branch, into a map — and field access is allowed, because it records a
|
|
8
|
+
* reference path. It may never be **computed on**.
|
|
9
|
+
*
|
|
10
|
+
* {@link Planned} is branded, so arithmetic is a compile error.
|
|
11
|
+
* {@link make} returns a strict proxy
|
|
12
|
+
* whose `Symbol.toPrimitive`, `valueOf`, `toString`, `toJSON`, and call traps
|
|
13
|
+
* throw {@link module:GraphBuildError.GraphBuildError} rather than let a plan be
|
|
14
|
+
* built around `NaN` or `"[object Object]"`. The lenient proxy this adapts
|
|
15
|
+
* (`@smthrs/core`'s `Graph.plannedValue`) answered `toPrimitive` with a
|
|
16
|
+
* readable string, which is exactly the silent-wrong-plan path this module
|
|
17
|
+
* exists to close.
|
|
18
|
+
*
|
|
19
|
+
* JavaScript does not expose traps for `Boolean(value)` or strict identity
|
|
20
|
+
* (`value === other`), so those operations cannot be refused at run time.
|
|
21
|
+
* They reveal only proxy truthiness or identity and never the planned result;
|
|
22
|
+
* authors must use {@link module:Node.branch} for decisions on real values.
|
|
23
|
+
* Type-aware ESLint `@typescript-eslint/strict-boolean-expressions` rejects
|
|
24
|
+
* planned conditions, but does not reject explicit Boolean coercion or all
|
|
25
|
+
* reference comparisons. Those still require review.
|
|
26
|
+
*
|
|
27
|
+
* @since 0.1.0
|
|
28
|
+
*/
|
|
29
|
+
import type * as Types from "effect/Types";
|
|
30
|
+
/**
|
|
31
|
+
* The brand carried by every planned value, and the key its reference is read
|
|
32
|
+
* from. Interned with `Symbol.for` so a value that crossed a module boundary is
|
|
33
|
+
* still recognised. The interned symbol is a recognition aid, not a
|
|
34
|
+
* capability, so {@link reference} validates the value stored under it.
|
|
35
|
+
*
|
|
36
|
+
* @since 0.1.0
|
|
37
|
+
* @category symbols
|
|
38
|
+
* @slop
|
|
39
|
+
*/
|
|
40
|
+
export declare const TypeId: unique symbol;
|
|
41
|
+
/**
|
|
42
|
+
* The type-level form of {@link TypeId}.
|
|
43
|
+
*
|
|
44
|
+
* @since 0.1.0
|
|
45
|
+
* @category symbols
|
|
46
|
+
* @slop
|
|
47
|
+
*/
|
|
48
|
+
export type TypeId = typeof TypeId;
|
|
49
|
+
/**
|
|
50
|
+
* What a planned value points at: the node that will produce the result, and
|
|
51
|
+
* the property path read from it. `path` is empty for the result itself.
|
|
52
|
+
*
|
|
53
|
+
* @since 0.1.0
|
|
54
|
+
* @category models
|
|
55
|
+
* @slop
|
|
56
|
+
*/
|
|
57
|
+
export interface Reference {
|
|
58
|
+
readonly node: string;
|
|
59
|
+
readonly path: ReadonlyArray<string>;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* A {@link Reference} plus the phantom type of the value it stands for, so
|
|
63
|
+
* `Planned<string>` and `Planned<number>` are not interchangeable.
|
|
64
|
+
*
|
|
65
|
+
* @since 0.1.0
|
|
66
|
+
* @category models
|
|
67
|
+
* @slop
|
|
68
|
+
*/
|
|
69
|
+
export interface Identity<out T> extends Reference {
|
|
70
|
+
readonly _T: Types.Covariant<T>;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* A step result that has not been produced yet.
|
|
74
|
+
*
|
|
75
|
+
* The brand rejects arithmetic and ordinary value arguments. The mapped half keeps field
|
|
76
|
+
* access typed — `result.files` is a `Planned` of the field, which is what
|
|
77
|
+
* makes "pass it on, never compute on it" expressible rather than merely
|
|
78
|
+
* documented.
|
|
79
|
+
*
|
|
80
|
+
* @since 0.1.0
|
|
81
|
+
* @category models
|
|
82
|
+
* @slop
|
|
83
|
+
*/
|
|
84
|
+
export type Planned<T> = {
|
|
85
|
+
readonly [TypeId]: Identity<T>;
|
|
86
|
+
} & ([T] extends [object] ? {
|
|
87
|
+
readonly [K in keyof T]: Planned<T[K]>;
|
|
88
|
+
} : unknown);
|
|
89
|
+
/**
|
|
90
|
+
* Creates the strict placeholder standing for a node's result.
|
|
91
|
+
*
|
|
92
|
+
* Planning hands one of these to every builder that consumes an upstream
|
|
93
|
+
* value — a branch arm, a continuation — and reads the {@link Reference} back
|
|
94
|
+
* off whatever the builder passed it into.
|
|
95
|
+
*
|
|
96
|
+
* @since 0.1.0
|
|
97
|
+
* @category constructors
|
|
98
|
+
* @slop
|
|
99
|
+
*/
|
|
100
|
+
export declare const make: <T>(node: string) => Planned<T>;
|
|
101
|
+
/**
|
|
102
|
+
* Reads the reference a planned value records, or `undefined` for anything
|
|
103
|
+
* else. An interned symbol is a recognition aid rather than a capability, so a
|
|
104
|
+
* forged carrier is accepted only when its node and path have the complete
|
|
105
|
+
* reference shape. This is how a payload is scanned for the upstream results
|
|
106
|
+
* it consumes.
|
|
107
|
+
*
|
|
108
|
+
* @since 0.1.0
|
|
109
|
+
* @category accessors
|
|
110
|
+
* @slop
|
|
111
|
+
*/
|
|
112
|
+
export declare const reference: (value: unknown) => Reference | undefined;
|
|
113
|
+
/**
|
|
114
|
+
* Checks whether a value is a planned placeholder.
|
|
115
|
+
*
|
|
116
|
+
* @since 0.1.0
|
|
117
|
+
* @category guards
|
|
118
|
+
* @slop
|
|
119
|
+
*/
|
|
120
|
+
export declare const isPlanned: (value: unknown) => value is Planned<unknown>;
|
|
121
|
+
//# sourceMappingURL=Planned.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Planned.d.ts","sourceRoot":"","sources":["../../src/Planned.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAEH,OAAO,KAAK,KAAK,KAAK,MAAM,cAAc,CAAA;AAG1C;;;;;;;;;GASG;AACH,eAAO,MAAM,MAAM,EAAE,OAAO,MAA2C,CAAA;AAEvE;;;;;;GAMG;AACH,MAAM,MAAM,MAAM,GAAG,OAAO,MAAM,CAAA;AAElC;;;;;;;GAOG;AACH,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC,MAAM,CAAC,CAAA;CACrC;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAE,SAAQ,SAAS;IAChD,QAAQ,CAAC,EAAE,EAAE,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,CAAA;CAChC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,MAAM,OAAO,CAAC,CAAC,IACjB;IAAE,QAAQ,CAAC,CAAC,MAAM,CAAC,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAA;CAAE,GAClC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,GAAG;IAAE,QAAQ,EAAE,CAAC,IAAI,MAAM,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;CAAE,GAAG,OAAO,CAAC,CAAA;AAmEjF;;;;;;;;;;GAUG;AACH,eAAO,MAAM,IAAI,GAAI,CAAC,EAAE,MAAM,MAAM,KAAG,OAAO,CAAC,CAAC,CAAkD,CAAA;AAalG;;;;;;;;;;GAUG;AACH,eAAO,MAAM,SAAS,GAAI,OAAO,OAAO,KAAG,SAAS,GAAG,SAItD,CAAA;AAED;;;;;;GAMG;AACH,eAAO,MAAM,SAAS,GAAI,OAAO,OAAO,KAAG,KAAK,IAAI,OAAO,CAAC,OAAO,CAAmC,CAAA"}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
var Planned_exports = {};
|
|
20
|
+
__export(Planned_exports, {
|
|
21
|
+
TypeId: () => TypeId,
|
|
22
|
+
isPlanned: () => isPlanned,
|
|
23
|
+
make: () => make,
|
|
24
|
+
reference: () => reference
|
|
25
|
+
});
|
|
26
|
+
module.exports = __toCommonJS(Planned_exports);
|
|
27
|
+
var import_GraphBuildError = require("./GraphBuildError.js");
|
|
28
|
+
const TypeId = /* @__PURE__ */ Symbol.for("@smthrs/plan/Planned");
|
|
29
|
+
const refusals = /* @__PURE__ */ new Map([
|
|
30
|
+
[Symbol.toPrimitive, "Symbol.toPrimitive"],
|
|
31
|
+
["valueOf", "valueOf"],
|
|
32
|
+
["toString", "toString"],
|
|
33
|
+
["toJSON", "toJSON"]
|
|
34
|
+
]);
|
|
35
|
+
const describe = (reference2) => reference2.path.length === 0 ? reference2.node : `${reference2.node}.${reference2.path.join(".")}`;
|
|
36
|
+
const refuse = (reference2, operation) => new import_GraphBuildError.GraphBuildError({
|
|
37
|
+
code: "planned_value_computed",
|
|
38
|
+
node: reference2.node,
|
|
39
|
+
path: reference2.path,
|
|
40
|
+
message: `Planned value ${describe(reference2)} was computed at plan time by ${operation}. Use Node.map to compute, Node.branch to decide, or pass the value into a payload.`
|
|
41
|
+
});
|
|
42
|
+
const placeholder = (reference2) => {
|
|
43
|
+
const target = () => void 0;
|
|
44
|
+
return new Proxy(target, {
|
|
45
|
+
get: (_target, key) => {
|
|
46
|
+
if (key === TypeId) return reference2;
|
|
47
|
+
const refusal = refusals.get(key);
|
|
48
|
+
if (refusal !== void 0) throw refuse(reference2, refusal);
|
|
49
|
+
if (key === "then") return void 0;
|
|
50
|
+
return placeholder({ node: reference2.node, path: [...reference2.path, String(key)] });
|
|
51
|
+
},
|
|
52
|
+
apply: () => {
|
|
53
|
+
throw refuse(reference2, "function application");
|
|
54
|
+
},
|
|
55
|
+
has: () => {
|
|
56
|
+
throw refuse(reference2, "property existence (`in`)");
|
|
57
|
+
},
|
|
58
|
+
ownKeys: () => {
|
|
59
|
+
throw refuse(reference2, "property enumeration");
|
|
60
|
+
}
|
|
61
|
+
});
|
|
62
|
+
};
|
|
63
|
+
const make = (node) => placeholder({ node, path: [] });
|
|
64
|
+
const carrier = (value) => typeof value === "object" && value !== null || typeof value === "function";
|
|
65
|
+
const validReference = (value) => typeof value === "object" && value !== null && typeof value.node === "string" && value.node.length > 0 && Array.isArray(value.path) && Array.from(value.path).every((segment) => typeof segment === "string");
|
|
66
|
+
const reference = (value) => {
|
|
67
|
+
if (!carrier(value)) return void 0;
|
|
68
|
+
const candidate = value[TypeId];
|
|
69
|
+
return validReference(candidate) ? candidate : void 0;
|
|
70
|
+
};
|
|
71
|
+
const isPlanned = (value) => reference(value) !== void 0;
|
|
72
|
+
//# sourceMappingURL=Planned.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/Planned.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * The placeholder a body sees where a step result will be.\n *\n * A flow body runs at PLAN time, so its\n * own payload is real data while every step result is a value that does not\n * exist yet. That value has a name and one rule: a planned value may be **passed** \u2014 into a payload field,\n * into a branch, into a map \u2014 and field access is allowed, because it records a\n * reference path. It may never be **computed on**.\n *\n * {@link Planned} is branded, so arithmetic is a compile error.\n * {@link make} returns a strict proxy\n * whose `Symbol.toPrimitive`, `valueOf`, `toString`, `toJSON`, and call traps\n * throw {@link module:GraphBuildError.GraphBuildError} rather than let a plan be\n * built around `NaN` or `\"[object Object]\"`. The lenient proxy this adapts\n * (`@smthrs/core`'s `Graph.plannedValue`) answered `toPrimitive` with a\n * readable string, which is exactly the silent-wrong-plan path this module\n * exists to close.\n *\n * JavaScript does not expose traps for `Boolean(value)` or strict identity\n * (`value === other`), so those operations cannot be refused at run time.\n * They reveal only proxy truthiness or identity and never the planned result;\n * authors must use {@link module:Node.branch} for decisions on real values.\n * Type-aware ESLint `@typescript-eslint/strict-boolean-expressions` rejects\n * planned conditions, but does not reject explicit Boolean coercion or all\n * reference comparisons. Those still require review.\n *\n * @since 0.1.0\n */\n\nimport type * as Types from \"effect/Types\"\nimport { GraphBuildError } from \"./GraphBuildError.ts\"\n\n/**\n * The brand carried by every planned value, and the key its reference is read\n * from. Interned with `Symbol.for` so a value that crossed a module boundary is\n * still recognised. The interned symbol is a recognition aid, not a\n * capability, so {@link reference} validates the value stored under it.\n *\n * @since 0.1.0\n * @category symbols\n * @slop\n */\nexport const TypeId: unique symbol = Symbol.for(\"@smthrs/plan/Planned\")\n\n/**\n * The type-level form of {@link TypeId}.\n *\n * @since 0.1.0\n * @category symbols\n * @slop\n */\nexport type TypeId = typeof TypeId\n\n/**\n * What a planned value points at: the node that will produce the result, and\n * the property path read from it. `path` is empty for the result itself.\n *\n * @since 0.1.0\n * @category models\n * @slop\n */\nexport interface Reference {\n readonly node: string\n readonly path: ReadonlyArray<string>\n}\n\n/**\n * A {@link Reference} plus the phantom type of the value it stands for, so\n * `Planned<string>` and `Planned<number>` are not interchangeable.\n *\n * @since 0.1.0\n * @category models\n * @slop\n */\nexport interface Identity<out T> extends Reference {\n readonly _T: Types.Covariant<T>\n}\n\n/**\n * A step result that has not been produced yet.\n *\n * The brand rejects arithmetic and ordinary value arguments. The mapped half keeps field\n * access typed \u2014 `result.files` is a `Planned` of the field, which is what\n * makes \"pass it on, never compute on it\" expressible rather than merely\n * documented.\n *\n * @since 0.1.0\n * @category models\n * @slop\n */\nexport type Planned<T> =\n & { readonly [TypeId]: Identity<T> }\n & ([T] extends [object] ? { readonly [K in keyof T]: Planned<T[K]> } : unknown)\n\n/**\n * The operations that are computation rather than reference, keyed by the\n * property that performs them. `toJSON` is here because `JSON.stringify` reads\n * it, and a plan that serialized a placeholder would look correct.\n *\n * @private\n */\nconst refusals = new Map<PropertyKey, string>([\n [Symbol.toPrimitive, \"Symbol.toPrimitive\"],\n [\"valueOf\", \"valueOf\"],\n [\"toString\", \"toString\"],\n [\"toJSON\", \"toJSON\"]\n])\n\n/** @private */\nconst describe = (reference: Reference): string =>\n reference.path.length === 0 ? reference.node : `${reference.node}.${reference.path.join(\".\")}`\n\n/**\n * The one refusal this module raises. The guidance is spelled out rather than\n * linked because the author reading it is inside a body and needs the\n * correction on the spot.\n *\n * @private\n */\nconst refuse = (reference: Reference, operation: string): GraphBuildError =>\n new GraphBuildError({\n code: \"planned_value_computed\",\n node: reference.node,\n path: reference.path,\n message: `Planned value ${describe(reference)} was computed at plan time by ${operation}. ` +\n \"Use Node.map to compute, Node.branch to decide, or pass the value into a payload.\"\n })\n\n/**\n * The proxy itself. `_T` of {@link Identity} is a phantom and never exists at\n * run time, so the trap carries the plain {@link Reference}.\n *\n * @private\n */\nconst placeholder = (reference: Reference): unknown => {\n /* v8 ignore next -- a Proxy application always enters the `apply` trap below, so the callable target is unreachable by construction */\n const target = (): undefined => undefined\n return new Proxy(target, {\n get: (_target, key) => {\n if (key === TypeId) return reference\n const refusal = refusals.get(key)\n if (refusal !== undefined) throw refuse(reference, refusal)\n // Not a thenable: a body that returns a planned value inside a promise\n // must resolve to the placeholder, not hang awaiting a proxy.\n if (key === \"then\") return undefined\n return placeholder({ node: reference.node, path: [...reference.path, String(key)] })\n },\n apply: () => {\n throw refuse(reference, \"function application\")\n },\n has: () => {\n throw refuse(reference, \"property existence (`in`)\")\n },\n ownKeys: () => {\n throw refuse(reference, \"property enumeration\")\n }\n })\n}\n\n/**\n * Creates the strict placeholder standing for a node's result.\n *\n * Planning hands one of these to every builder that consumes an upstream\n * value \u2014 a branch arm, a continuation \u2014 and reads the {@link Reference} back\n * off whatever the builder passed it into.\n *\n * @since 0.1.0\n * @category constructors\n * @slop\n */\nexport const make = <T>(node: string): Planned<T> => placeholder({ node, path: [] }) as Planned<T>\n\n/** @private */\nconst carrier = (value: unknown): value is { readonly [TypeId]?: Reference } =>\n (typeof value === \"object\" && value !== null) || typeof value === \"function\"\n\n/** @private */\nconst validReference = (value: unknown): value is Reference =>\n typeof value === \"object\" && value !== null &&\n typeof (value as Reference).node === \"string\" && (value as Reference).node.length > 0 &&\n Array.isArray((value as Reference).path) &&\n Array.from((value as Reference).path).every((segment) => typeof segment === \"string\")\n\n/**\n * Reads the reference a planned value records, or `undefined` for anything\n * else. An interned symbol is a recognition aid rather than a capability, so a\n * forged carrier is accepted only when its node and path have the complete\n * reference shape. This is how a payload is scanned for the upstream results\n * it consumes.\n *\n * @since 0.1.0\n * @category accessors\n * @slop\n */\nexport const reference = (value: unknown): Reference | undefined => {\n if (!carrier(value)) return undefined\n const candidate = value[TypeId]\n return validReference(candidate) ? candidate : undefined\n}\n\n/**\n * Checks whether a value is a planned placeholder.\n *\n * @since 0.1.0\n * @category guards\n * @slop\n */\nexport const isPlanned = (value: unknown): value is Planned<unknown> => reference(value) !== undefined\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA8BA,6BAAgC;AAYzB,MAAM,SAAwB,uBAAO,IAAI,sBAAsB;AA2DtE,MAAM,WAAW,oBAAI,IAAyB;AAAA,EAC5C,CAAC,OAAO,aAAa,oBAAoB;AAAA,EACzC,CAAC,WAAW,SAAS;AAAA,EACrB,CAAC,YAAY,UAAU;AAAA,EACvB,CAAC,UAAU,QAAQ;AACrB,CAAC;AAGD,MAAM,WAAW,CAACA,eAChBA,WAAU,KAAK,WAAW,IAAIA,WAAU,OAAO,GAAGA,WAAU,IAAI,IAAIA,WAAU,KAAK,KAAK,GAAG,CAAC;AAS9F,MAAM,SAAS,CAACA,YAAsB,cACpC,IAAI,uCAAgB;AAAA,EAClB,MAAM;AAAA,EACN,MAAMA,WAAU;AAAA,EAChB,MAAMA,WAAU;AAAA,EAChB,SAAS,iBAAiB,SAASA,UAAS,CAAC,iCAAiC,SAAS;AAEzF,CAAC;AAQH,MAAM,cAAc,CAACA,eAAkC;AAErD,QAAM,SAAS,MAAiB;AAChC,SAAO,IAAI,MAAM,QAAQ;AAAA,IACvB,KAAK,CAAC,SAAS,QAAQ;AACrB,UAAI,QAAQ,OAAQ,QAAOA;AAC3B,YAAM,UAAU,SAAS,IAAI,GAAG;AAChC,UAAI,YAAY,OAAW,OAAM,OAAOA,YAAW,OAAO;AAG1D,UAAI,QAAQ,OAAQ,QAAO;AAC3B,aAAO,YAAY,EAAE,MAAMA,WAAU,MAAM,MAAM,CAAC,GAAGA,WAAU,MAAM,OAAO,GAAG,CAAC,EAAE,CAAC;AAAA,IACrF;AAAA,IACA,OAAO,MAAM;AACX,YAAM,OAAOA,YAAW,sBAAsB;AAAA,IAChD;AAAA,IACA,KAAK,MAAM;AACT,YAAM,OAAOA,YAAW,2BAA2B;AAAA,IACrD;AAAA,IACA,SAAS,MAAM;AACb,YAAM,OAAOA,YAAW,sBAAsB;AAAA,IAChD;AAAA,EACF,CAAC;AACH;AAaO,MAAM,OAAO,CAAI,SAA6B,YAAY,EAAE,MAAM,MAAM,CAAC,EAAE,CAAC;AAGnF,MAAM,UAAU,CAAC,UACd,OAAO,UAAU,YAAY,UAAU,QAAS,OAAO,UAAU;AAGpE,MAAM,iBAAiB,CAAC,UACtB,OAAO,UAAU,YAAY,UAAU,QACvC,OAAQ,MAAoB,SAAS,YAAa,MAAoB,KAAK,SAAS,KACpF,MAAM,QAAS,MAAoB,IAAI,KACvC,MAAM,KAAM,MAAoB,IAAI,EAAE,MAAM,CAAC,YAAY,OAAO,YAAY,QAAQ;AAa/E,MAAM,YAAY,CAAC,UAA0C;AAClE,MAAI,CAAC,QAAQ,KAAK,EAAG,QAAO;AAC5B,QAAM,YAAY,MAAM,MAAM;AAC9B,SAAO,eAAe,SAAS,IAAI,YAAY;AACjD;AASO,MAAM,YAAY,CAAC,UAA8C,UAAU,KAAK,MAAM;",
|
|
6
|
+
"names": ["reference"]
|
|
7
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What a bounded repetition does when it reaches its ceiling.
|
|
3
|
+
*
|
|
4
|
+
* This is the ONE ceiling vocabulary. `@smthrs/flow`'s `Poll.make` takes it as
|
|
5
|
+
* `onTimeout`, for the attempt a poll gives up on, and `@smthrs/patterns`'
|
|
6
|
+
* `Loop` takes it as `onMaxReached`, for the iteration a loop gives up on. It
|
|
7
|
+
* was the same two words written out in both packages, with no edge between
|
|
8
|
+
* them, so a third member added on one side would have been invisible to the
|
|
9
|
+
* other. It lives here because `@smthrs/plan` is the package both already
|
|
10
|
+
* depend on.
|
|
11
|
+
*
|
|
12
|
+
* @since 1.0.0-rc.0
|
|
13
|
+
*/
|
|
14
|
+
import * as Schema from "effect/Schema";
|
|
15
|
+
/**
|
|
16
|
+
* What a bounded repetition answers with at its ceiling: `fail` raises the
|
|
17
|
+
* repetition's own typed failure, and `return-last` settles with the last
|
|
18
|
+
* value it produced.
|
|
19
|
+
*
|
|
20
|
+
* @category models
|
|
21
|
+
* @since 1.0.0-rc.0
|
|
22
|
+
*/
|
|
23
|
+
export declare const AtCeiling: Schema.Literals<readonly ["fail", "return-last"]>;
|
|
24
|
+
/**
|
|
25
|
+
* The value form of {@link AtCeiling}.
|
|
26
|
+
*
|
|
27
|
+
* @category models
|
|
28
|
+
* @since 1.0.0-rc.0
|
|
29
|
+
*/
|
|
30
|
+
export type AtCeiling = typeof AtCeiling.Type;
|
|
31
|
+
//# sourceMappingURL=Repetition.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Repetition.d.ts","sourceRoot":"","sources":["../../src/Repetition.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AAEvC;;;;;;;GAOG;AACH,eAAO,MAAM,SAAS,mDAA2C,CAAA;AAEjE;;;;;GAKG;AACH,MAAM,MAAM,SAAS,GAAG,OAAO,SAAS,CAAC,IAAI,CAAA"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
28
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
+
var Repetition_exports = {};
|
|
30
|
+
__export(Repetition_exports, {
|
|
31
|
+
AtCeiling: () => AtCeiling
|
|
32
|
+
});
|
|
33
|
+
module.exports = __toCommonJS(Repetition_exports);
|
|
34
|
+
var Schema = __toESM(require("effect/Schema"), 1);
|
|
35
|
+
const AtCeiling = Schema.Literals(["fail", "return-last"]);
|
|
36
|
+
//# sourceMappingURL=Repetition.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/Repetition.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * What a bounded repetition does when it reaches its ceiling.\n *\n * This is the ONE ceiling vocabulary. `@smthrs/flow`'s `Poll.make` takes it as\n * `onTimeout`, for the attempt a poll gives up on, and `@smthrs/patterns`'\n * `Loop` takes it as `onMaxReached`, for the iteration a loop gives up on. It\n * was the same two words written out in both packages, with no edge between\n * them, so a third member added on one side would have been invisible to the\n * other. It lives here because `@smthrs/plan` is the package both already\n * depend on.\n *\n * @since 1.0.0-rc.0\n */\n\nimport * as Schema from \"effect/Schema\"\n\n/**\n * What a bounded repetition answers with at its ceiling: `fail` raises the\n * repetition's own typed failure, and `return-last` settles with the last\n * value it produced.\n *\n * @category models\n * @since 1.0.0-rc.0\n */\nexport const AtCeiling = Schema.Literals([\"fail\", \"return-last\"])\n\n/**\n * The value form of {@link AtCeiling}.\n *\n * @category models\n * @since 1.0.0-rc.0\n */\nexport type AtCeiling = typeof AtCeiling.Type\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAcA,aAAwB;AAUjB,MAAM,YAAY,OAAO,SAAS,CAAC,QAAQ,aAAa,CAAC;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|