@smthrs/plan 1.0.0-rc.4 → 1.0.0-rc.6

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.
Files changed (47) hide show
  1. package/CHANGELOG.md +2 -0
  2. package/README.md +5 -5
  3. package/THIRD_PARTY_NOTICES.md +48 -0
  4. package/dist/cjs/KeyMaterial.d.ts +1 -1
  5. package/dist/cjs/KeyMaterial.js.map +1 -1
  6. package/dist/cjs/Node.d.ts +71 -0
  7. package/dist/cjs/Node.d.ts.map +1 -1
  8. package/dist/cjs/Node.js +7 -0
  9. package/dist/cjs/Node.js.map +2 -2
  10. package/dist/cjs/StepKey.d.ts +1 -1
  11. package/dist/cjs/StepKey.js.map +1 -1
  12. package/dist/cjs/internal/SchemaIdentity.d.ts +140 -0
  13. package/dist/cjs/internal/SchemaIdentity.d.ts.map +1 -0
  14. package/dist/cjs/internal/SchemaIdentity.js +718 -0
  15. package/dist/cjs/internal/SchemaIdentity.js.map +7 -0
  16. package/dist/cjs/internal/node.d.ts +1 -1
  17. package/dist/cjs/internal/node.d.ts.map +1 -1
  18. package/dist/cjs/internal/node.js +2 -1
  19. package/dist/cjs/internal/node.js.map +2 -2
  20. package/dist/esm/KeyMaterial.d.ts +1 -1
  21. package/dist/esm/KeyMaterial.js +1 -1
  22. package/dist/esm/KeyMaterial.js.map +1 -1
  23. package/dist/esm/Node.d.ts +71 -0
  24. package/dist/esm/Node.d.ts.map +1 -1
  25. package/dist/esm/Node.js +46 -0
  26. package/dist/esm/Node.js.map +1 -1
  27. package/dist/esm/StepKey.d.ts +1 -1
  28. package/dist/esm/StepKey.js +1 -1
  29. package/dist/esm/StepKey.js.map +1 -1
  30. package/dist/esm/internal/SchemaIdentity.d.ts +140 -0
  31. package/dist/esm/internal/SchemaIdentity.d.ts.map +1 -0
  32. package/dist/esm/internal/SchemaIdentity.js +1002 -0
  33. package/dist/esm/internal/SchemaIdentity.js.map +1 -0
  34. package/dist/esm/internal/node.d.ts +1 -1
  35. package/dist/esm/internal/node.d.ts.map +1 -1
  36. package/dist/esm/internal/node.js +3 -2
  37. package/dist/esm/internal/node.js.map +1 -1
  38. package/docs/README.md +1 -1
  39. package/docs/api.md +11 -1
  40. package/docs/concepts/authoring-ast.md +2 -1
  41. package/docs/installation.md +3 -3
  42. package/package.json +9 -8
  43. package/src/KeyMaterial.ts +1 -1
  44. package/src/Node.ts +79 -0
  45. package/src/StepKey.ts +1 -1
  46. package/src/internal/SchemaIdentity.ts +1096 -0
  47. package/src/internal/node.ts +3 -2
package/dist/esm/Node.js CHANGED
@@ -30,6 +30,7 @@
30
30
  import { dual } from "effect/Function";
31
31
  import { GraphBuildError } from "./GraphBuildError.js";
32
32
  import * as internal from "./internal/node.js";
33
+ import * as internalSchemaIdentity from "./internal/SchemaIdentity.js";
33
34
  import * as Planned from "./Planned.js";
34
35
  /**
35
36
  * The runtime type identifier carried by every node.
@@ -495,6 +496,51 @@ export const catchFilter = (ast) => ast._tag === "Catch" ? internal.filter(ast)
495
496
  * @slop
496
497
  */
497
498
  export const functionIdentity = (operation) => internal.functionIdentity(operation);
499
+ /**
500
+ * The refusal `schemaIdentity` and `representationIdentity` raise for a schema
501
+ * a step key cannot be derived from. Its message is the one
502
+ * `effect@4.0.0-rc.115` gave for the same schema, where it gave one.
503
+ *
504
+ * @since 1.0.0
505
+ * @category errors
506
+ */
507
+ export const SchemaIdentityError = internalSchemaIdentity.SchemaIdentityError;
508
+ /**
509
+ * Identifies a schema by the constraints it documents, so a call re-keys when
510
+ * what its callee accepts or produces changes, and a catch re-keys when its
511
+ * filter does.
512
+ *
513
+ * The document is what `Schema.toJsonSchemaDocument(schema, options)`
514
+ * returned under `effect@4.0.0-rc.115`. It is printed by this package, not by
515
+ * the installed `effect`, because a later release prints a different document
516
+ * for the same schema and a moved identity re-keys every recorded step. Use
517
+ * it wherever the document is hashed, compared or pinned; a JSON Schema shown
518
+ * to a model or a person comes from `Schema.toJsonSchemaDocument`.
519
+ *
520
+ * Reserved for the packages that derive identities. Authors never call it; it
521
+ * throws for a schema that has no JSON Schema form.
522
+ *
523
+ * @since 1.0.0
524
+ * @category engine
525
+ */
526
+ export const schemaIdentity = (schema, options) => internalSchemaIdentity.schemaIdentity(schema, options);
527
+ /**
528
+ * Identifies a schema AST by its encoded representation, the material a
529
+ * sealed action's step key folds in for its success and error schemas.
530
+ *
531
+ * The value is what `SchemaRepresentation.toJson(SchemaRepresentation.toRepresentation(ast))`
532
+ * returned under `effect@4.0.0-rc.115`, so a later `effect` release does not
533
+ * re-key recorded steps. The one exception is `Schema.brand`: from
534
+ * `effect@4.0.4` on a brand is not part of the AST, so a declaration with a
535
+ * brand re-keys once.
536
+ *
537
+ * Reserved for the packages that derive step keys. Authors never call it; it
538
+ * throws for an AST that has no representation.
539
+ *
540
+ * @since 1.0.0
541
+ * @category engine
542
+ */
543
+ export const representationIdentity = (ast) => internalSchemaIdentity.representationIdentity(ast);
498
544
  /**
499
545
  * Binds a frozen plain copy of inert captures as the callback's this receiver.
500
546
  *
@@ -1 +1 @@
1
- {"version":3,"file":"Node.js","sourceRoot":"","sources":["../../src/Node.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Pure, pipeable nodes: the shape a flow body describes and nothing more.\n *\n * Building a node records an inspectable AST and executes nothing — the same\n * split as Bazel's `ctx.actions.run`, which declares an action rather than\n * running one. A plan is\n * always a DAG, so there is no loop node here and never will be: repetition\n * lives one level up, in what a flow settles with.\n *\n * A node also carries Effect's requirement channel, `R`, and carries it as a\n * PHANTOM: building a plan demands nothing, and every combinator here unions\n * `R` without ever reading it. What fills the channel is a call to something\n * whose code lives elsewhere — an action — so the type of a plan states which\n * implementations executing it will need, and the place that executes it is\n * where the compiler asks for them.\n *\n * Control flow is structure. {@link branch} takes both arms and evaluates each\n * ONCE, symbolically, so the exit condition and the handoff site are visible\n * topology before anything runs; its predicate is digested and runs later on\n * the real value. {@link map} is transformation only. The rule the authoring\n * note states, and this module encodes: **map transforms; branch decides.**\n *\n * Adapted from `@smthrs/core` (`packages/smithers/flows/core`) `Node.ts`.\n * `Dynamic` is gone — a model call is an ordinary action, and nothing\n * model-shaped belongs in this package — and node annotations are gone with\n * it, because the AST has to stay JSON serializable.\n *\n * @since 0.1.0\n */\n\nimport { dual } from \"effect/Function\"\nimport type * as Pipeable from \"effect/Pipeable\"\nimport type * as Schema from \"effect/Schema\"\nimport type * as Types from \"effect/Types\"\nimport { GraphBuildError } from \"./GraphBuildError.ts\"\nimport * as internal from \"./internal/node.ts\"\nimport * as Planned from \"./Planned.ts\"\n\n/**\n * The runtime type identifier carried by every node.\n *\n * @since 0.1.0\n * @category type ids\n * @slop\n */\nexport const TypeId: TypeId = internal.TypeId\n\n/**\n * The type-level form of {@link TypeId}.\n *\n * @since 0.1.0\n * @category type ids\n * @slop\n */\nexport type TypeId = \"~@smthrs/plan/Node\"\n\n/**\n * The inspectable AST a node stores: closure-free, and JSON serializable for\n * every JSON payload an author puts in it.\n *\n * @since 0.1.0\n * @category models\n * @slop\n */\nexport type Ast = internal.NodeAst\n\n/**\n * How a flow call joins the caller's plan: `inline` splices the callee's body\n * in, `boundary` makes it one child execution, and `handoff` names the next\n * trampoline round.\n *\n * This is the ONE call-mode vocabulary. {@link flowCall} takes it and\n * `@smthrs/flow`'s graph builder switches on it, so a second spelling in\n * either package would fork the moment one gained a mode.\n *\n * @since 0.1.0\n * @category models\n * @slop\n */\nexport const CallMode = internal.CallMode\n\n/**\n * The value form of {@link CallMode}.\n *\n * @since 0.1.0\n * @category models\n * @slop\n */\nexport type CallMode = internal.CallMode\n\n/**\n * The serializable stand-in an AST keeps for a plan-time function: a digest of\n * its normalized source, hashed in place of a closure that could not be\n * shipped, stored, or compared.\n *\n * @since 0.1.0\n * @category models\n * @slop\n */\nexport type FunctionIdentity = Extract<Ast, { readonly _tag: \"Map\" }>[\"mapper\"]\n\n/**\n * Reads the inert AST reference created for a planned value.\n *\n * Structural lookalikes remain ordinary payload data. This accessor is the\n * only recognition path because the marker itself is deliberately private to\n * the AST cloner.\n *\n * @since 1.0.0\n * @category accessors\n */\nexport const plannedReference = internal.plannedReference\n\n/**\n * A pure graph-building value, covariant in what it will succeed and fail\n * with and in what it will need to run. It is a description: holding one has\n * run nothing.\n *\n * `R` is Effect's requirement channel, and it is PHANTOM here. Nothing at plan\n * time reads it: the AST, the graph built from it, its key material, and every\n * digest are identical whatever `R` says. It exists so a value that names an\n * implementation it does not carry — an action call — can say so in its type,\n * and so the place that finally has to run that implementation can demand it.\n * Building a plan therefore stays requirement-free; only executing one is not.\n *\n * @since 0.1.0\n * @category models\n * @slop\n */\nexport interface Node<out A, out E = never, out R = never> extends Pipeable.Pipeable {\n readonly [TypeId]: {\n readonly _A: Types.Covariant<A>\n readonly _E: Types.Covariant<E>\n readonly _R: Types.Covariant<R>\n }\n readonly ast: Ast\n}\n\n/**\n * Any node, whatever it succeeds or fails with and whatever it requires.\n *\n * @since 0.1.0\n * @category models\n * @slop\n */\nexport type Any = Node<unknown, unknown, any>\n\n/**\n * The success type of a node.\n *\n * @since 0.1.0\n * @category models\n * @slop\n */\nexport type Success<N> = N extends Node<infer A, infer _E, infer _R> ? A : never\n\n/**\n * The error type of a node.\n *\n * @since 0.1.0\n * @category models\n * @slop\n */\nexport type Error<N> = N extends Node<infer _A, infer E, infer _R> ? E : never\n\n/**\n * The requirements of a node: what has to be provided wherever it is finally\n * executed, and nothing that has to be provided to build it.\n *\n * @since 0.1.0\n * @category models\n * @slop\n */\nexport type Services<N> = N extends Node<infer _A, infer _E, infer R> ? R : never\n\n/**\n * The node reference a branch arm's symbolic subject carries. Arms are built\n * before the graph assigns ids, so every reference an arm records names this\n * placeholder, and graph building rewrites it to the branch's own upstream\n * node — which is `first`, structurally, and therefore not a guess.\n *\n * @since 0.1.0\n * @category constants\n * @slop\n */\nexport const branchSubject = \"branch/subject\"\n\n/** @private */\nconst subjectsKey = Symbol.for(\"@smthrs/plan/Node/subjects/v1\")\nconst globals = globalThis as typeof globalThis & { [subjectsKey]?: { branch: number; catch: number } }\nconst subjects = globals[subjectsKey] ??= { branch: 0, catch: 0 }\n\n/**\n * The prefix of the node reference a catch failure arm's symbolic error\n * carries. Each {@link catch_} mints its own token under this prefix, so an\n * outer error captured inside a nested failure arm keeps naming the outer\n * catch, and graph building rewrites each token to the node that catch\n * protects.\n *\n * @since 0.1.0\n * @category constants\n * @slop\n */\nexport const catchSubject = \"catch/subject\"\n\n/**\n * The two arms of a decision plus the predicate that chooses between them.\n *\n * `if` runs at RUN time on the real value. `then` and `else` run at PLAN time,\n * once each, against a {@link module:Planned.Planned} placeholder — they\n * describe topology, so they may pass the value on but never compute on it.\n *\n * @since 0.1.0\n * @category models\n * @slop\n */\nexport interface BranchOptions<A, B1, E1, R1, B2, E2, R2> {\n readonly if: (value: A) => boolean\n readonly then: (value: Planned.Planned<A>) => Node<B1, E1, R1>\n readonly else: (value: Planned.Planned<A>) => Node<B2, E2, R2>\n}\n\n/**\n * The statically planned recovery arm and optional schema selecting which\n * typed failures it handles.\n *\n * @since 0.1.0\n * @category models\n * @slop\n */\nexport interface CatchOptions<E, B, E2, R2 = never, Handled = E> {\n readonly error?: Schema.Schema<Handled> | undefined\n readonly onFailure: (error: Planned.Planned<Handled>) => Node<B, E2, R2>\n}\n\n/**\n * Checks whether a value is a node.\n *\n * A node this package built is recognized by registration at construction. A\n * node that crossed a serialization boundary, an object sharing the node\n * prototype whose own `ast` is a well-formed AST, is recognized by that shape,\n * because `@smthrs/flow` hands a rehydrated AST back as a node and its side\n * tables are all a round trip loses. The {@link TypeId} marker is a public\n * string any object can carry, so it counts for nothing on its own: every\n * combinator that admits a node reads its `ast` as trusted topology, and an\n * object carrying the marker on any other prototype, one inheriting it from a\n * node, and one whose `ast` is missing, malformed, cyclic, or an accessor are\n * all refused with the same `GraphBuildError` as any other non-node. A proxy\n * is judged by the shape it forwards: one that forwards a node unchanged\n * passes, and one that diverges from it does not.\n *\n * @since 0.1.0\n * @category guards\n * @slop\n */\nexport const isNode = (value: unknown): value is Any => internal.isNode(value)\n\n/**\n * The inert value delivered by {@link succeed}. Planned references resolve to\n * their result type; other values follow the payload's JSON projection.\n * Invalid dates serialize to null. Members without a JSON representation are\n * omitted from objects and replaced with null in arrays.\n *\n * @since 1.0.0\n * @category models\n */\nexport type Succeed<A> = A extends Planned.Planned<infer Value> ? Value\n : A extends Date ? string | null\n : A extends { toJSON: (...args: any) => infer Value } ? Succeed<Value>\n : A extends (...args: any) => any ? undefined\n : A extends symbol ? undefined\n : A extends ReadonlyArray<unknown> ? { [K in keyof A]: SucceedArrayMember<A[K]> }\n : A extends object ? {\n [K in keyof A as K extends string | number ? [Succeed<A[K]>] extends [undefined] ? never : K : never]: Succeed<\n A[K]\n >\n }\n : A\n\n/** @private */\ntype SucceedArrayMember<A> = A extends Planned.Planned<infer Value> ? Value\n : A extends unknown ? Succeed<A> extends infer Value ? Value extends undefined ? null : Value\n : never\n : never\n\n/**\n * A node that succeeds with the constant's inert JSON projection.\n *\n * Dates produce strings (or null for invalid dates), URLs produce strings,\n * and callable object members are omitted. Use {@link map} to reconstruct a\n * domain value explicitly after this serialization boundary.\n *\n * @since 0.1.0\n * @category constructors\n */\nexport const succeed = <A>(value: A): Node<Succeed<A>> => internal.makeNode<Succeed<A>>(internal.succeed(value))\n\n/**\n * The inert error delivered by {@link fail}: the same JSON projection\n * {@link Succeed} describes, because a plan stores an error exactly as it\n * stores a value.\n *\n * @since 1.0.0\n * @category models\n */\nexport type Fail<E> = Succeed<E>\n\n/**\n * A node that fails with the constant's inert JSON projection, in the typed\n * error channel.\n *\n * It is how a plan states a refusal it already knows about — an unsupported\n * input, an exhausted budget, a compensation that has nothing left to undo —\n * without an action that exists only to fail. {@link catch} recovers it exactly\n * as it recovers an action's failure, and an uncaught one is the flow's typed\n * failure.\n *\n * @since 1.0.0\n * @category constructors\n */\nexport const fail = <E>(error: E): Node<never, Fail<E>> => internal.makeNode<never, Fail<E>>(internal.fail(error))\n\n/**\n * Combines independent children into one node, keyed by name.\n *\n * Width is fixed here, at plan time. Fanning out over something a step\n * discovered is not this: end the round and carry the list in the next flow's\n * payload, where it is real data.\n *\n * @since 0.1.0\n * @category constructors\n * @slop\n */\nexport const all = <const Nodes extends Readonly<Record<string, Any>>>(\n nodes: Nodes\n): Node<\n Types.Simplify<{ readonly [K in keyof Nodes]: Success<Nodes[K]> }>,\n Error<Nodes[keyof Nodes]>,\n Services<Nodes[keyof Nodes]>\n> => internal.makeNode(internal.all(memberAsts(nodes, \"all\", \"invalid_all_member\")))\n\n/**\n * The member ASTs of a combination, keyed by name, refusing a non-node member.\n *\n * @private\n */\nconst memberAsts = (\n nodes: Readonly<Record<string, unknown>>,\n combinator: string,\n code: \"invalid_all_member\" | \"invalid_join\"\n): Record<string, Ast> => {\n const asts: Record<string, Ast> = Object.create(null) as Record<string, Ast>\n for (const [member, node] of Object.entries(nodes)) {\n if (!isNode(node)) {\n throw new GraphBuildError({\n code,\n node: member,\n path: [],\n message: `Node.${combinator} expected a Node at member \"${member}\"`\n })\n }\n Object.defineProperty(asts, member, {\n configurable: true,\n enumerable: true,\n value: node.ast,\n writable: true\n })\n }\n return asts\n}\n\n/**\n * Builds a join that settles early, refusing a member set it could never\n * decide on.\n *\n * @private\n */\nconst join = (mode: internal.RaceMode, count: number, nodes: Readonly<Record<string, unknown>>): Ast => {\n const asts = memberAsts(nodes, mode, \"invalid_join\")\n const width = Object.keys(asts).length\n if (!internal.isRaceCount(mode, count, width)) {\n throw new GraphBuildError({\n code: \"invalid_join\",\n node: mode,\n path: [],\n message: mode === \"quorum\"\n ? `Node.quorum needs a whole number of successes between 1 and its ${width} members, got ${String(count)}`\n : `Node.${mode} needs at least one member`\n })\n }\n return internal.race(mode, count, asts)\n}\n\n/**\n * The members of an early-settling join, keyed by name.\n *\n * @since 1.0.0\n * @category models\n */\nexport type Members = Readonly<Record<string, Any>>\n\n/**\n * Settles with the first member to settle, success or typed failure.\n *\n * The other members are interrupted. The winner is journaled, so a resumed run\n * settles the same member and never starts the others again.\n *\n * @since 1.0.0\n * @category constructors\n */\nexport const race = <const Nodes extends Members>(\n nodes: Nodes\n): Node<Success<Nodes[keyof Nodes]>, Error<Nodes[keyof Nodes]>, Services<Nodes[keyof Nodes]>> =>\n internal.makeNode(join(\"race\", 1, nodes))\n\n/**\n * Settles with the first member to succeed, ignoring typed failures while a\n * member is still running.\n *\n * It fails with the last failure when every member fails. The other members\n * are interrupted, and the winner is journaled as {@link race} journals it.\n *\n * @since 1.0.0\n * @category constructors\n */\nexport const any = <const Nodes extends Members>(\n nodes: Nodes\n): Node<Success<Nodes[keyof Nodes]>, Error<Nodes[keyof Nodes]>, Services<Nodes[keyof Nodes]>> =>\n internal.makeNode(join(\"any\", 1, nodes))\n\n/**\n * Succeeds once `count` members succeed, with exactly those members' values\n * keyed by name.\n *\n * It fails with the failure that leaves fewer than `count` members able to\n * succeed. Either way the members still running are interrupted, and the\n * members that decided are journaled as {@link race} journals its winner.\n *\n * @since 1.0.0\n * @category constructors\n */\nexport const quorum = <const Nodes extends Members>(\n count: number,\n nodes: Nodes\n): Node<\n Types.Simplify<{ readonly [K in keyof Nodes]?: Success<Nodes[K]> }>,\n Error<Nodes[keyof Nodes]>,\n Services<Nodes[keyof Nodes]>\n> => internal.makeNode(join(\"quorum\", count, nodes))\n\n/**\n * Transforms an eventual success value with a deferred pure function.\n *\n * The function is digested, not run: it executes later, on the real value.\n * This is where computation on a step result belongs — and only computation. A\n * `map` that decides what happens next is a `branch` written wrongly.\n *\n * @since 0.1.0\n * @category mapping\n * @slop\n */\nexport const map: {\n <A, B>(f: (a: A) => B): <E, R>(self: Node<A, E, R>) => Node<B, E, R>\n <A, E, R, B>(self: Node<A, E, R>, f: (a: A) => B): Node<B, E, R>\n} = dual(\n 2,\n <A, E, R, B>(self: Node<A, E, R>, f: (a: A) => B): Node<B, E, R> =>\n internal.makeNode<B, E, R>(internal.map(self.ast, (value) => f(value as A), f))\n)\n\n/**\n * Starts the entire next subtree only after this node succeeds, without\n * consuming its result. Failure or interruption prevents that subtree from\n * starting, including actions nested inside combinations or inline flows.\n *\n * Use {@link bindPlanned} to build a dependency from a symbolic result, or\n * {@link map} to compute on the eventual value.\n *\n * @since 0.1.0\n * @category sequencing\n * @slop\n */\nexport const andThen: {\n <B, E2, R2>(next: Node<B, E2, R2>): <A, E, R>(self: Node<A, E, R>) => Node<B, E | E2, R | R2>\n <A, E, R, B, E2, R2>(self: Node<A, E, R>, next: Node<B, E2, R2>): Node<B, E | E2, R | R2>\n} = dual(\n 2,\n <A, E, R, B, E2, R2>(\n self: Node<A, E, R>,\n next: Node<B, E2, R2>\n ): Node<B, E | E2, R | R2> => {\n if (!isNode(next)) {\n throw new GraphBuildError({\n code: \"invalid_continuation\",\n node: \"andThen/next\",\n path: [],\n message:\n \"Node.andThen expects a Node; use Node.bindPlanned for a symbolic builder or Node.map for value computation\"\n })\n }\n return internal.makeNode<B, E | E2, R | R2>(internal.andThenNode(self.ast, next.ast))\n }\n)\n\n/**\n * Builds a dependency using a symbolic reference to this node's future result.\n *\n * The builder runs during planning. Its argument is a {@link module:Planned.Planned}\n * reference, not the value the node will eventually produce. Pass references\n * into action payloads; use {@link branch} for decisions and {@link map} for\n * computation on real results. JavaScript truthiness and reference equality\n * cannot inspect a planned result. Enable type-aware ESLint's\n * `@typescript-eslint/strict-boolean-expressions` to reject planned conditions.\n * Independent descendants of the built subtree can start while this producer\n * is running; consumers of its reference wait for its value. Use\n * {@link andThen} when the whole next subtree must wait for success.\n *\n * @since 1.0.0\n * @category sequencing\n */\nexport const bindPlanned: {\n <A, B, E2, R2>(\n build: (reference: Planned.Planned<A>) => Node<B, E2, R2>\n ): <E, R>(self: Node<A, E, R>) => Node<B, E | E2, R | R2>\n <A, E, R, B, E2, R2>(\n self: Node<A, E, R>,\n build: (reference: Planned.Planned<A>) => Node<B, E2, R2>\n ): Node<B, E | E2, R | R2>\n} = dual(\n 2,\n <A, E, R, B, E2, R2>(\n self: Node<A, E, R>,\n build: (reference: Planned.Planned<A>) => Node<B, E2, R2>\n ): Node<B, E | E2, R | R2> =>\n internal.makeNode<B, E | E2, R | R2>(\n internal.andThen(self.ast, (value) => build(value as Planned.Planned<A>), build)\n )\n)\n\n/**\n * Builds one arm, once, against the symbolic subject.\n *\n * @private\n */\nconst arm = <A, B, E, R>(\n build: (value: Planned.Planned<A>) => Node<B, E, R>,\n subject: Planned.Planned<A>,\n side: string\n): Ast => {\n const node = build(subject)\n if (!isNode(node)) {\n throw new GraphBuildError({\n code: \"invalid_continuation\",\n node: `${branchSubject}/${side}`,\n path: [],\n message: `Node.branch expected its \"${side}\" arm to return a Node`\n })\n }\n return node.ast\n}\n\n/**\n * Decides between two arms, both of them static topology.\n *\n * Each arm builder is evaluated exactly once, here, against a\n * {@link module:Planned.Planned} placeholder, and the resulting ASTs are what\n * the node stores — so a plan shows the exit condition and both continuations\n * before it runs. The predicate is digested and evaluated at run time on the\n * real value, which is why none of the plan-time placeholder machinery leaks\n * into control flow.\n *\n * Both arms contribute their requirements, because both arms are topology the\n * plan carries. A run takes one of them, but which one is not known until the\n * predicate sees the real value, so an execution has to be able to take either.\n *\n * @since 0.1.0\n * @category sequencing\n * @slop\n */\nexport const branch: {\n <A, B1, E1, R1, B2, E2, R2>(\n options: BranchOptions<A, B1, E1, R1, B2, E2, R2>\n ): <E, R>(self: Node<A, E, R>) => Node<B1 | B2, E | E1 | E2, R | R1 | R2>\n <A, E, R, B1, E1, R1, B2, E2, R2>(\n self: Node<A, E, R>,\n options: BranchOptions<A, B1, E1, R1, B2, E2, R2>\n ): Node<B1 | B2, E | E1 | E2, R | R1 | R2>\n} = dual(\n 2,\n <A, E, R, B1, E1, R1, B2, E2, R2>(\n self: Node<A, E, R>,\n options: BranchOptions<A, B1, E1, R1, B2, E2, R2>\n ): Node<B1 | B2, E | E1 | E2, R | R1 | R2> => {\n const predicate = options.if\n const subjectToken = `${branchSubject}/${subjects.branch++}`\n const subject = Planned.make<A>(subjectToken)\n return internal.makeNode<B1 | B2, E | E1 | E2, R | R1 | R2>(\n internal.branch(\n subjectToken,\n self.ast,\n (value) => predicate(value as A),\n predicate,\n arm(options.then, subject, \"then\"),\n arm(options.else, subject, \"else\")\n )\n )\n }\n)\n\n/**\n * Recovers from matching typed failures with static failure topology.\n *\n * The protected graph and failure arm are both stored in the AST. The arm is\n * built once at plan time against a strict planned error placeholder. With no\n * schema the whole typed error channel is handled. A schema handles only the\n * values it accepts, so its overloads retain E: a refinement can reject values\n * without narrowing its TypeScript type. Runtime schema callbacks enter the\n * filter identity along with its JSON Schema. Uncaptured callbacks are local\n * to this process, just like uncaptured mappers.\n *\n * The failure arm contributes its requirements to the node's, for the same\n * reason a branch's arms do: it is topology the plan carries, and a run reaches\n * it whenever the protected graph fails.\n *\n * @since 0.1.0\n * @category sequencing\n * @slop\n */\nconst catch_: {\n <Handled, B, E2, R2>(\n options: CatchOptions<unknown, B, E2, R2, Handled> & {\n readonly error: Schema.Schema<Handled>\n }\n ): <A, E, R>(self: Node<A, E, R>) => Node<A | B, E | E2, R | R2>\n <E, B, E2, R2>(\n options: CatchOptions<E, B, E2, R2> & {\n readonly error?: undefined\n }\n ): <A, R>(self: Node<A, E, R>) => Node<A | B, E2, R | R2>\n <A, E, R, Handled, B, E2, R2>(\n self: Node<A, E, R>,\n options: CatchOptions<E, B, E2, R2, Handled> & {\n readonly error: Schema.Schema<Handled>\n }\n ): Node<A | B, E | E2, R | R2>\n <A, E, R, B, E2, R2>(\n self: Node<A, E, R>,\n options: CatchOptions<E, B, E2, R2> & {\n readonly error?: undefined\n }\n ): Node<A | B, E2, R | R2>\n} = dual(\n 2,\n <A, E, R, Handled, B, E2, R2>(\n self: Node<A, E, R>,\n options: CatchOptions<E, B, E2, R2, Handled>\n ): Node<A | B, E | E2, R | R2> => {\n const subjectToken = `${catchSubject}/${subjects.catch++}`\n const failure = options.onFailure(Planned.make<Handled>(subjectToken))\n if (!isNode(failure)) {\n throw new GraphBuildError({\n code: \"invalid_continuation\",\n node: catchSubject,\n path: [],\n message: \"Node.catch expected its failure arm to return a Node\"\n })\n }\n return internal.makeNode(internal.catch_(subjectToken, self.ast, failure.ast, options.error))\n }\n)\n\nexport { catch_ as catch }\n\n/**\n * Attaches a scheduling priority to a node, leaving the original unchanged.\n *\n * The scheduler runs ready work with a higher number first, so a priority\n * changes LATENCY and nothing else. It never enters key material: a node\n * ordered ahead of another still computes the same result, so re-keying it\n * would throw away a legitimate cache hit. Children inherit the value\n * lexically when the graph is built, and a child that states its own keeps it.\n *\n * @since 0.1.0\n * @category annotations\n * @slop\n */\nexport const priority: {\n (value: number): <A, E, R>(self: Node<A, E, R>) => Node<A, E, R>\n <A, E, R>(self: Node<A, E, R>, value: number): Node<A, E, R>\n} = dual(\n 2,\n <A, E, R>(self: Node<A, E, R>, value: number): Node<A, E, R> => {\n if (!Number.isSafeInteger(value)) {\n throw new GraphBuildError({\n code: \"invalid_priority\",\n node: self.ast._tag,\n path: [],\n message: `Node.priority expects a safe integer, received ${value}`\n })\n }\n return internal.makeNode<A, E, R>(internal.withPriority(self.ast, value))\n }\n)\n\n/**\n * Reads the scheduling priority a node carries, or `undefined` when it states\n * none and inherits from whatever encloses it.\n *\n * @since 0.1.0\n * @category accessors\n * @slop\n */\nexport const declaredPriority = (ast: Ast): number | undefined => ast.priority\n\n/**\n * Constructs the flow-call node used by `@smthrs/flow` without making flow\n * calls part of the public authoring surface of this package.\n *\n * Reserved for `@smthrs/flow`, which owns flow authoring. It is not part\n * of this package's authoring surface, and it validates nothing: an unknown\n * flow tag becomes a call node the graph keeps as a leaf.\n *\n * @since 0.1.0\n * @category engine\n * @slop\n */\nexport const flowCall = <A = unknown, E = never, R = never>(\n declaration: unknown,\n flow: string,\n mode: CallMode,\n payload: unknown\n): Node<A, E, R> => internal.makeNode<A, E, R>(internal.flowCall(declaration, flow, mode, payload))\n\n/**\n * Constructs the action-call node used by `@smthrs/flow` without making\n * action calls part of the public authoring surface of this package.\n *\n * Reserved for `@smthrs/flow`, which owns action authoring. It is not part\n * of this package's authoring surface, and an unknown action tag becomes a\n * call node the graph keeps as a leaf.\n *\n * @since 0.1.0\n * @category engine\n * @slop\n */\nexport const actionCall = <A = unknown, E = never, R = never>(\n declaration: unknown,\n action: string,\n payload: unknown\n): Node<A, E, R> => internal.makeNode<A, E, R>(internal.actionCall(declaration, action, payload))\n\n/**\n * Reads the flow or action declaration a call node names, so `@smthrs/flow`\n * can expand a call it recorded. It is `undefined` for an AST that was\n * rehydrated from JSON, because the declaration lives beside the AST rather\n * than inside it — a graph built from such an AST keeps the call as a leaf.\n *\n * Reserved for `@smthrs/flow`, which files the declaration when it builds\n * the call. Authors never call it.\n *\n * @since 0.1.0\n * @category engine\n * @slop\n */\nexport const declaration = (\n ast: Extract<Ast, { readonly _tag: \"ActionCall\" | \"FlowCall\" }>\n): unknown => internal.declaration(ast)\n\n/**\n * Reads the continuation builder of a sequenced node, which graph building\n * evaluates once against a placeholder. It is `undefined` when the author\n * supplied a node directly — the topology is already in `next` — and for a\n * rehydrated AST, whose side table did not survive serialization.\n *\n * Reserved for `@smthrs/flow`'s graph walk. Authors never call it.\n *\n * @since 0.1.0\n * @category engine\n * @slop\n */\nexport const continuation = (\n ast: Extract<Ast, { readonly _tag: \"AndThen\" }>\n): ((value: Planned.Planned<unknown>) => unknown) | undefined => internal.operation(ast)\n\n/**\n * Reads the deferred mapper of a {@link map} node, which a driver applies to\n * the real upstream value once it has one. It is `undefined` for every other\n * variant, and for a rehydrated AST whose side table did not survive\n * serialization.\n *\n * Reserved for `@smthrs/flow`'s interpreter. Authors never call it.\n *\n * @since 0.1.0\n * @category engine\n * @slop\n */\nexport const mapper = (ast: Ast): ((value: unknown) => unknown) | undefined =>\n ast._tag === \"Map\" ? internal.operation(ast) : undefined\n\n/**\n * Reads the run-time predicate of a {@link branch} node, which a driver\n * evaluates on the real subject value to choose an arm. It is `undefined` for\n * every other variant, and for a rehydrated AST whose side table did not\n * survive serialization.\n *\n * Reserved for `@smthrs/flow`'s interpreter. Authors never call it.\n *\n * @since 0.1.0\n * @category engine\n * @slop\n */\nexport const predicate = (ast: Ast): ((value: unknown) => boolean) | undefined =>\n ast._tag === \"Branch\" ? internal.predicate(ast) : undefined\n\n/**\n * Reads the optional schema selecting failures handled by a {@link catch_}.\n *\n * Reserved for `@smthrs/flow`'s interpreter. It is `undefined` for every\n * variant but `catch_`, and for a rehydrated AST whose side table did not\n * survive serialization.\n *\n * @since 0.1.0\n * @category engine\n * @slop\n */\nexport const catchFilter = (ast: Ast): Schema.Top | undefined => ast._tag === \"Catch\" ? internal.filter(ast) : undefined\n\n/**\n * Identifies a plan-time function the AST does NOT store, a flow's `body`,\n * exactly as the AST identifies the mapper and continuation it does store.\n * A call that keeps its callee as a leaf still has to re-key when that\n * callee's body is edited, and this is the identity it folds in. Unannotated\n * functions fail closed with process-local identity; use {@link capture} to\n * declare inert captures and obtain deterministic identity.\n *\n * Reserved for `@smthrs/flow`, which folds a callee body's identity into a\n * call it keeps as a leaf. Authors never call it; it throws a `TypeError`\n * when handed anything but a function.\n *\n * @since 0.1.0\n * @category engine\n * @slop\n */\nexport const functionIdentity = (operation: unknown): FunctionIdentity => internal.functionIdentity(operation)\n\n/**\n * Binds a frozen plain copy of inert captures as the callback's this receiver.\n *\n * Use a function expression to read the snapshot while keeping the ordinary\n * callback arguments: Node.capture({ factor: 3 }, function(value: number) {\n * return value * this.factor\n * }). Caller objects remain unchanged; lexical aliases still name originals\n * and must not be used as mutable semantic inputs. Nested captures retain the\n * inner callback's snapshot and compose the two identities.\n *\n * Admission walks original descriptors once, rejects built-in brands and\n * non-plain prototypes without evaluating getters, then uses structuredClone\n * to refuse Proxies. Hosts without that API refuse object capture. Only the\n * owned frozen copy enters identity and the wrapper. Sealed, non-extensible,\n * frozen and Immer ordinary data are supported equally. Unsupported values\n * raise a TypeError naming the path. See core docs/api.md#nodecapture for the\n * complete algorithm and the migration from original-object locking.\n *\n * @category constructors\n * @since 0.1.0\n * @slop\n */\nexport const capture = <C extends Readonly<Record<string, unknown>>, Args extends ReadonlyArray<unknown>, A>(\n captures: C,\n operation: (this: Readonly<C>, ...args: Args) => A\n): (...args: Args) => A => internal.capture(captures, operation)\n"]}
1
+ {"version":3,"file":"Node.js","sourceRoot":"","sources":["../../src/Node.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Pure, pipeable nodes: the shape a flow body describes and nothing more.\n *\n * Building a node records an inspectable AST and executes nothing — the same\n * split as Bazel's `ctx.actions.run`, which declares an action rather than\n * running one. A plan is\n * always a DAG, so there is no loop node here and never will be: repetition\n * lives one level up, in what a flow settles with.\n *\n * A node also carries Effect's requirement channel, `R`, and carries it as a\n * PHANTOM: building a plan demands nothing, and every combinator here unions\n * `R` without ever reading it. What fills the channel is a call to something\n * whose code lives elsewhere — an action — so the type of a plan states which\n * implementations executing it will need, and the place that executes it is\n * where the compiler asks for them.\n *\n * Control flow is structure. {@link branch} takes both arms and evaluates each\n * ONCE, symbolically, so the exit condition and the handoff site are visible\n * topology before anything runs; its predicate is digested and runs later on\n * the real value. {@link map} is transformation only. The rule the authoring\n * note states, and this module encodes: **map transforms; branch decides.**\n *\n * Adapted from `@smthrs/core` (`packages/smithers/flows/core`) `Node.ts`.\n * `Dynamic` is gone — a model call is an ordinary action, and nothing\n * model-shaped belongs in this package — and node annotations are gone with\n * it, because the AST has to stay JSON serializable.\n *\n * @since 0.1.0\n */\n\nimport { dual } from \"effect/Function\"\nimport type * as Pipeable from \"effect/Pipeable\"\nimport type * as Schema from \"effect/Schema\"\nimport type * as SchemaAST from \"effect/SchemaAST\"\nimport type * as Types from \"effect/Types\"\nimport { GraphBuildError } from \"./GraphBuildError.ts\"\nimport * as internal from \"./internal/node.ts\"\nimport * as internalSchemaIdentity from \"./internal/SchemaIdentity.ts\"\nimport * as Planned from \"./Planned.ts\"\n\n/**\n * The runtime type identifier carried by every node.\n *\n * @since 0.1.0\n * @category type ids\n * @slop\n */\nexport const TypeId: TypeId = internal.TypeId\n\n/**\n * The type-level form of {@link TypeId}.\n *\n * @since 0.1.0\n * @category type ids\n * @slop\n */\nexport type TypeId = \"~@smthrs/plan/Node\"\n\n/**\n * The inspectable AST a node stores: closure-free, and JSON serializable for\n * every JSON payload an author puts in it.\n *\n * @since 0.1.0\n * @category models\n * @slop\n */\nexport type Ast = internal.NodeAst\n\n/**\n * How a flow call joins the caller's plan: `inline` splices the callee's body\n * in, `boundary` makes it one child execution, and `handoff` names the next\n * trampoline round.\n *\n * This is the ONE call-mode vocabulary. {@link flowCall} takes it and\n * `@smthrs/flow`'s graph builder switches on it, so a second spelling in\n * either package would fork the moment one gained a mode.\n *\n * @since 0.1.0\n * @category models\n * @slop\n */\nexport const CallMode = internal.CallMode\n\n/**\n * The value form of {@link CallMode}.\n *\n * @since 0.1.0\n * @category models\n * @slop\n */\nexport type CallMode = internal.CallMode\n\n/**\n * The serializable stand-in an AST keeps for a plan-time function: a digest of\n * its normalized source, hashed in place of a closure that could not be\n * shipped, stored, or compared.\n *\n * @since 0.1.0\n * @category models\n * @slop\n */\nexport type FunctionIdentity = Extract<Ast, { readonly _tag: \"Map\" }>[\"mapper\"]\n\n/**\n * Reads the inert AST reference created for a planned value.\n *\n * Structural lookalikes remain ordinary payload data. This accessor is the\n * only recognition path because the marker itself is deliberately private to\n * the AST cloner.\n *\n * @since 1.0.0\n * @category accessors\n */\nexport const plannedReference = internal.plannedReference\n\n/**\n * A pure graph-building value, covariant in what it will succeed and fail\n * with and in what it will need to run. It is a description: holding one has\n * run nothing.\n *\n * `R` is Effect's requirement channel, and it is PHANTOM here. Nothing at plan\n * time reads it: the AST, the graph built from it, its key material, and every\n * digest are identical whatever `R` says. It exists so a value that names an\n * implementation it does not carry — an action call — can say so in its type,\n * and so the place that finally has to run that implementation can demand it.\n * Building a plan therefore stays requirement-free; only executing one is not.\n *\n * @since 0.1.0\n * @category models\n * @slop\n */\nexport interface Node<out A, out E = never, out R = never> extends Pipeable.Pipeable {\n readonly [TypeId]: {\n readonly _A: Types.Covariant<A>\n readonly _E: Types.Covariant<E>\n readonly _R: Types.Covariant<R>\n }\n readonly ast: Ast\n}\n\n/**\n * Any node, whatever it succeeds or fails with and whatever it requires.\n *\n * @since 0.1.0\n * @category models\n * @slop\n */\nexport type Any = Node<unknown, unknown, any>\n\n/**\n * The success type of a node.\n *\n * @since 0.1.0\n * @category models\n * @slop\n */\nexport type Success<N> = N extends Node<infer A, infer _E, infer _R> ? A : never\n\n/**\n * The error type of a node.\n *\n * @since 0.1.0\n * @category models\n * @slop\n */\nexport type Error<N> = N extends Node<infer _A, infer E, infer _R> ? E : never\n\n/**\n * The requirements of a node: what has to be provided wherever it is finally\n * executed, and nothing that has to be provided to build it.\n *\n * @since 0.1.0\n * @category models\n * @slop\n */\nexport type Services<N> = N extends Node<infer _A, infer _E, infer R> ? R : never\n\n/**\n * The node reference a branch arm's symbolic subject carries. Arms are built\n * before the graph assigns ids, so every reference an arm records names this\n * placeholder, and graph building rewrites it to the branch's own upstream\n * node — which is `first`, structurally, and therefore not a guess.\n *\n * @since 0.1.0\n * @category constants\n * @slop\n */\nexport const branchSubject = \"branch/subject\"\n\n/** @private */\nconst subjectsKey = Symbol.for(\"@smthrs/plan/Node/subjects/v1\")\nconst globals = globalThis as typeof globalThis & { [subjectsKey]?: { branch: number; catch: number } }\nconst subjects = globals[subjectsKey] ??= { branch: 0, catch: 0 }\n\n/**\n * The prefix of the node reference a catch failure arm's symbolic error\n * carries. Each {@link catch_} mints its own token under this prefix, so an\n * outer error captured inside a nested failure arm keeps naming the outer\n * catch, and graph building rewrites each token to the node that catch\n * protects.\n *\n * @since 0.1.0\n * @category constants\n * @slop\n */\nexport const catchSubject = \"catch/subject\"\n\n/**\n * The two arms of a decision plus the predicate that chooses between them.\n *\n * `if` runs at RUN time on the real value. `then` and `else` run at PLAN time,\n * once each, against a {@link module:Planned.Planned} placeholder — they\n * describe topology, so they may pass the value on but never compute on it.\n *\n * @since 0.1.0\n * @category models\n * @slop\n */\nexport interface BranchOptions<A, B1, E1, R1, B2, E2, R2> {\n readonly if: (value: A) => boolean\n readonly then: (value: Planned.Planned<A>) => Node<B1, E1, R1>\n readonly else: (value: Planned.Planned<A>) => Node<B2, E2, R2>\n}\n\n/**\n * The statically planned recovery arm and optional schema selecting which\n * typed failures it handles.\n *\n * @since 0.1.0\n * @category models\n * @slop\n */\nexport interface CatchOptions<E, B, E2, R2 = never, Handled = E> {\n readonly error?: Schema.Schema<Handled> | undefined\n readonly onFailure: (error: Planned.Planned<Handled>) => Node<B, E2, R2>\n}\n\n/**\n * Checks whether a value is a node.\n *\n * A node this package built is recognized by registration at construction. A\n * node that crossed a serialization boundary, an object sharing the node\n * prototype whose own `ast` is a well-formed AST, is recognized by that shape,\n * because `@smthrs/flow` hands a rehydrated AST back as a node and its side\n * tables are all a round trip loses. The {@link TypeId} marker is a public\n * string any object can carry, so it counts for nothing on its own: every\n * combinator that admits a node reads its `ast` as trusted topology, and an\n * object carrying the marker on any other prototype, one inheriting it from a\n * node, and one whose `ast` is missing, malformed, cyclic, or an accessor are\n * all refused with the same `GraphBuildError` as any other non-node. A proxy\n * is judged by the shape it forwards: one that forwards a node unchanged\n * passes, and one that diverges from it does not.\n *\n * @since 0.1.0\n * @category guards\n * @slop\n */\nexport const isNode = (value: unknown): value is Any => internal.isNode(value)\n\n/**\n * The inert value delivered by {@link succeed}. Planned references resolve to\n * their result type; other values follow the payload's JSON projection.\n * Invalid dates serialize to null. Members without a JSON representation are\n * omitted from objects and replaced with null in arrays.\n *\n * @since 1.0.0\n * @category models\n */\nexport type Succeed<A> = A extends Planned.Planned<infer Value> ? Value\n : A extends Date ? string | null\n : A extends { toJSON: (...args: any) => infer Value } ? Succeed<Value>\n : A extends (...args: any) => any ? undefined\n : A extends symbol ? undefined\n : A extends ReadonlyArray<unknown> ? { [K in keyof A]: SucceedArrayMember<A[K]> }\n : A extends object ? {\n [K in keyof A as K extends string | number ? [Succeed<A[K]>] extends [undefined] ? never : K : never]: Succeed<\n A[K]\n >\n }\n : A\n\n/** @private */\ntype SucceedArrayMember<A> = A extends Planned.Planned<infer Value> ? Value\n : A extends unknown ? Succeed<A> extends infer Value ? Value extends undefined ? null : Value\n : never\n : never\n\n/**\n * A node that succeeds with the constant's inert JSON projection.\n *\n * Dates produce strings (or null for invalid dates), URLs produce strings,\n * and callable object members are omitted. Use {@link map} to reconstruct a\n * domain value explicitly after this serialization boundary.\n *\n * @since 0.1.0\n * @category constructors\n */\nexport const succeed = <A>(value: A): Node<Succeed<A>> => internal.makeNode<Succeed<A>>(internal.succeed(value))\n\n/**\n * The inert error delivered by {@link fail}: the same JSON projection\n * {@link Succeed} describes, because a plan stores an error exactly as it\n * stores a value.\n *\n * @since 1.0.0\n * @category models\n */\nexport type Fail<E> = Succeed<E>\n\n/**\n * A node that fails with the constant's inert JSON projection, in the typed\n * error channel.\n *\n * It is how a plan states a refusal it already knows about — an unsupported\n * input, an exhausted budget, a compensation that has nothing left to undo —\n * without an action that exists only to fail. {@link catch} recovers it exactly\n * as it recovers an action's failure, and an uncaught one is the flow's typed\n * failure.\n *\n * @since 1.0.0\n * @category constructors\n */\nexport const fail = <E>(error: E): Node<never, Fail<E>> => internal.makeNode<never, Fail<E>>(internal.fail(error))\n\n/**\n * Combines independent children into one node, keyed by name.\n *\n * Width is fixed here, at plan time. Fanning out over something a step\n * discovered is not this: end the round and carry the list in the next flow's\n * payload, where it is real data.\n *\n * @since 0.1.0\n * @category constructors\n * @slop\n */\nexport const all = <const Nodes extends Readonly<Record<string, Any>>>(\n nodes: Nodes\n): Node<\n Types.Simplify<{ readonly [K in keyof Nodes]: Success<Nodes[K]> }>,\n Error<Nodes[keyof Nodes]>,\n Services<Nodes[keyof Nodes]>\n> => internal.makeNode(internal.all(memberAsts(nodes, \"all\", \"invalid_all_member\")))\n\n/**\n * The member ASTs of a combination, keyed by name, refusing a non-node member.\n *\n * @private\n */\nconst memberAsts = (\n nodes: Readonly<Record<string, unknown>>,\n combinator: string,\n code: \"invalid_all_member\" | \"invalid_join\"\n): Record<string, Ast> => {\n const asts: Record<string, Ast> = Object.create(null) as Record<string, Ast>\n for (const [member, node] of Object.entries(nodes)) {\n if (!isNode(node)) {\n throw new GraphBuildError({\n code,\n node: member,\n path: [],\n message: `Node.${combinator} expected a Node at member \"${member}\"`\n })\n }\n Object.defineProperty(asts, member, {\n configurable: true,\n enumerable: true,\n value: node.ast,\n writable: true\n })\n }\n return asts\n}\n\n/**\n * Builds a join that settles early, refusing a member set it could never\n * decide on.\n *\n * @private\n */\nconst join = (mode: internal.RaceMode, count: number, nodes: Readonly<Record<string, unknown>>): Ast => {\n const asts = memberAsts(nodes, mode, \"invalid_join\")\n const width = Object.keys(asts).length\n if (!internal.isRaceCount(mode, count, width)) {\n throw new GraphBuildError({\n code: \"invalid_join\",\n node: mode,\n path: [],\n message: mode === \"quorum\"\n ? `Node.quorum needs a whole number of successes between 1 and its ${width} members, got ${String(count)}`\n : `Node.${mode} needs at least one member`\n })\n }\n return internal.race(mode, count, asts)\n}\n\n/**\n * The members of an early-settling join, keyed by name.\n *\n * @since 1.0.0\n * @category models\n */\nexport type Members = Readonly<Record<string, Any>>\n\n/**\n * Settles with the first member to settle, success or typed failure.\n *\n * The other members are interrupted. The winner is journaled, so a resumed run\n * settles the same member and never starts the others again.\n *\n * @since 1.0.0\n * @category constructors\n */\nexport const race = <const Nodes extends Members>(\n nodes: Nodes\n): Node<Success<Nodes[keyof Nodes]>, Error<Nodes[keyof Nodes]>, Services<Nodes[keyof Nodes]>> =>\n internal.makeNode(join(\"race\", 1, nodes))\n\n/**\n * Settles with the first member to succeed, ignoring typed failures while a\n * member is still running.\n *\n * It fails with the last failure when every member fails. The other members\n * are interrupted, and the winner is journaled as {@link race} journals it.\n *\n * @since 1.0.0\n * @category constructors\n */\nexport const any = <const Nodes extends Members>(\n nodes: Nodes\n): Node<Success<Nodes[keyof Nodes]>, Error<Nodes[keyof Nodes]>, Services<Nodes[keyof Nodes]>> =>\n internal.makeNode(join(\"any\", 1, nodes))\n\n/**\n * Succeeds once `count` members succeed, with exactly those members' values\n * keyed by name.\n *\n * It fails with the failure that leaves fewer than `count` members able to\n * succeed. Either way the members still running are interrupted, and the\n * members that decided are journaled as {@link race} journals its winner.\n *\n * @since 1.0.0\n * @category constructors\n */\nexport const quorum = <const Nodes extends Members>(\n count: number,\n nodes: Nodes\n): Node<\n Types.Simplify<{ readonly [K in keyof Nodes]?: Success<Nodes[K]> }>,\n Error<Nodes[keyof Nodes]>,\n Services<Nodes[keyof Nodes]>\n> => internal.makeNode(join(\"quorum\", count, nodes))\n\n/**\n * Transforms an eventual success value with a deferred pure function.\n *\n * The function is digested, not run: it executes later, on the real value.\n * This is where computation on a step result belongs — and only computation. A\n * `map` that decides what happens next is a `branch` written wrongly.\n *\n * @since 0.1.0\n * @category mapping\n * @slop\n */\nexport const map: {\n <A, B>(f: (a: A) => B): <E, R>(self: Node<A, E, R>) => Node<B, E, R>\n <A, E, R, B>(self: Node<A, E, R>, f: (a: A) => B): Node<B, E, R>\n} = dual(\n 2,\n <A, E, R, B>(self: Node<A, E, R>, f: (a: A) => B): Node<B, E, R> =>\n internal.makeNode<B, E, R>(internal.map(self.ast, (value) => f(value as A), f))\n)\n\n/**\n * Starts the entire next subtree only after this node succeeds, without\n * consuming its result. Failure or interruption prevents that subtree from\n * starting, including actions nested inside combinations or inline flows.\n *\n * Use {@link bindPlanned} to build a dependency from a symbolic result, or\n * {@link map} to compute on the eventual value.\n *\n * @since 0.1.0\n * @category sequencing\n * @slop\n */\nexport const andThen: {\n <B, E2, R2>(next: Node<B, E2, R2>): <A, E, R>(self: Node<A, E, R>) => Node<B, E | E2, R | R2>\n <A, E, R, B, E2, R2>(self: Node<A, E, R>, next: Node<B, E2, R2>): Node<B, E | E2, R | R2>\n} = dual(\n 2,\n <A, E, R, B, E2, R2>(\n self: Node<A, E, R>,\n next: Node<B, E2, R2>\n ): Node<B, E | E2, R | R2> => {\n if (!isNode(next)) {\n throw new GraphBuildError({\n code: \"invalid_continuation\",\n node: \"andThen/next\",\n path: [],\n message:\n \"Node.andThen expects a Node; use Node.bindPlanned for a symbolic builder or Node.map for value computation\"\n })\n }\n return internal.makeNode<B, E | E2, R | R2>(internal.andThenNode(self.ast, next.ast))\n }\n)\n\n/**\n * Builds a dependency using a symbolic reference to this node's future result.\n *\n * The builder runs during planning. Its argument is a {@link module:Planned.Planned}\n * reference, not the value the node will eventually produce. Pass references\n * into action payloads; use {@link branch} for decisions and {@link map} for\n * computation on real results. JavaScript truthiness and reference equality\n * cannot inspect a planned result. Enable type-aware ESLint's\n * `@typescript-eslint/strict-boolean-expressions` to reject planned conditions.\n * Independent descendants of the built subtree can start while this producer\n * is running; consumers of its reference wait for its value. Use\n * {@link andThen} when the whole next subtree must wait for success.\n *\n * @since 1.0.0\n * @category sequencing\n */\nexport const bindPlanned: {\n <A, B, E2, R2>(\n build: (reference: Planned.Planned<A>) => Node<B, E2, R2>\n ): <E, R>(self: Node<A, E, R>) => Node<B, E | E2, R | R2>\n <A, E, R, B, E2, R2>(\n self: Node<A, E, R>,\n build: (reference: Planned.Planned<A>) => Node<B, E2, R2>\n ): Node<B, E | E2, R | R2>\n} = dual(\n 2,\n <A, E, R, B, E2, R2>(\n self: Node<A, E, R>,\n build: (reference: Planned.Planned<A>) => Node<B, E2, R2>\n ): Node<B, E | E2, R | R2> =>\n internal.makeNode<B, E | E2, R | R2>(\n internal.andThen(self.ast, (value) => build(value as Planned.Planned<A>), build)\n )\n)\n\n/**\n * Builds one arm, once, against the symbolic subject.\n *\n * @private\n */\nconst arm = <A, B, E, R>(\n build: (value: Planned.Planned<A>) => Node<B, E, R>,\n subject: Planned.Planned<A>,\n side: string\n): Ast => {\n const node = build(subject)\n if (!isNode(node)) {\n throw new GraphBuildError({\n code: \"invalid_continuation\",\n node: `${branchSubject}/${side}`,\n path: [],\n message: `Node.branch expected its \"${side}\" arm to return a Node`\n })\n }\n return node.ast\n}\n\n/**\n * Decides between two arms, both of them static topology.\n *\n * Each arm builder is evaluated exactly once, here, against a\n * {@link module:Planned.Planned} placeholder, and the resulting ASTs are what\n * the node stores — so a plan shows the exit condition and both continuations\n * before it runs. The predicate is digested and evaluated at run time on the\n * real value, which is why none of the plan-time placeholder machinery leaks\n * into control flow.\n *\n * Both arms contribute their requirements, because both arms are topology the\n * plan carries. A run takes one of them, but which one is not known until the\n * predicate sees the real value, so an execution has to be able to take either.\n *\n * @since 0.1.0\n * @category sequencing\n * @slop\n */\nexport const branch: {\n <A, B1, E1, R1, B2, E2, R2>(\n options: BranchOptions<A, B1, E1, R1, B2, E2, R2>\n ): <E, R>(self: Node<A, E, R>) => Node<B1 | B2, E | E1 | E2, R | R1 | R2>\n <A, E, R, B1, E1, R1, B2, E2, R2>(\n self: Node<A, E, R>,\n options: BranchOptions<A, B1, E1, R1, B2, E2, R2>\n ): Node<B1 | B2, E | E1 | E2, R | R1 | R2>\n} = dual(\n 2,\n <A, E, R, B1, E1, R1, B2, E2, R2>(\n self: Node<A, E, R>,\n options: BranchOptions<A, B1, E1, R1, B2, E2, R2>\n ): Node<B1 | B2, E | E1 | E2, R | R1 | R2> => {\n const predicate = options.if\n const subjectToken = `${branchSubject}/${subjects.branch++}`\n const subject = Planned.make<A>(subjectToken)\n return internal.makeNode<B1 | B2, E | E1 | E2, R | R1 | R2>(\n internal.branch(\n subjectToken,\n self.ast,\n (value) => predicate(value as A),\n predicate,\n arm(options.then, subject, \"then\"),\n arm(options.else, subject, \"else\")\n )\n )\n }\n)\n\n/**\n * Recovers from matching typed failures with static failure topology.\n *\n * The protected graph and failure arm are both stored in the AST. The arm is\n * built once at plan time against a strict planned error placeholder. With no\n * schema the whole typed error channel is handled. A schema handles only the\n * values it accepts, so its overloads retain E: a refinement can reject values\n * without narrowing its TypeScript type. Runtime schema callbacks enter the\n * filter identity along with its JSON Schema. Uncaptured callbacks are local\n * to this process, just like uncaptured mappers.\n *\n * The failure arm contributes its requirements to the node's, for the same\n * reason a branch's arms do: it is topology the plan carries, and a run reaches\n * it whenever the protected graph fails.\n *\n * @since 0.1.0\n * @category sequencing\n * @slop\n */\nconst catch_: {\n <Handled, B, E2, R2>(\n options: CatchOptions<unknown, B, E2, R2, Handled> & {\n readonly error: Schema.Schema<Handled>\n }\n ): <A, E, R>(self: Node<A, E, R>) => Node<A | B, E | E2, R | R2>\n <E, B, E2, R2>(\n options: CatchOptions<E, B, E2, R2> & {\n readonly error?: undefined\n }\n ): <A, R>(self: Node<A, E, R>) => Node<A | B, E2, R | R2>\n <A, E, R, Handled, B, E2, R2>(\n self: Node<A, E, R>,\n options: CatchOptions<E, B, E2, R2, Handled> & {\n readonly error: Schema.Schema<Handled>\n }\n ): Node<A | B, E | E2, R | R2>\n <A, E, R, B, E2, R2>(\n self: Node<A, E, R>,\n options: CatchOptions<E, B, E2, R2> & {\n readonly error?: undefined\n }\n ): Node<A | B, E2, R | R2>\n} = dual(\n 2,\n <A, E, R, Handled, B, E2, R2>(\n self: Node<A, E, R>,\n options: CatchOptions<E, B, E2, R2, Handled>\n ): Node<A | B, E | E2, R | R2> => {\n const subjectToken = `${catchSubject}/${subjects.catch++}`\n const failure = options.onFailure(Planned.make<Handled>(subjectToken))\n if (!isNode(failure)) {\n throw new GraphBuildError({\n code: \"invalid_continuation\",\n node: catchSubject,\n path: [],\n message: \"Node.catch expected its failure arm to return a Node\"\n })\n }\n return internal.makeNode(internal.catch_(subjectToken, self.ast, failure.ast, options.error))\n }\n)\n\nexport { catch_ as catch }\n\n/**\n * Attaches a scheduling priority to a node, leaving the original unchanged.\n *\n * The scheduler runs ready work with a higher number first, so a priority\n * changes LATENCY and nothing else. It never enters key material: a node\n * ordered ahead of another still computes the same result, so re-keying it\n * would throw away a legitimate cache hit. Children inherit the value\n * lexically when the graph is built, and a child that states its own keeps it.\n *\n * @since 0.1.0\n * @category annotations\n * @slop\n */\nexport const priority: {\n (value: number): <A, E, R>(self: Node<A, E, R>) => Node<A, E, R>\n <A, E, R>(self: Node<A, E, R>, value: number): Node<A, E, R>\n} = dual(\n 2,\n <A, E, R>(self: Node<A, E, R>, value: number): Node<A, E, R> => {\n if (!Number.isSafeInteger(value)) {\n throw new GraphBuildError({\n code: \"invalid_priority\",\n node: self.ast._tag,\n path: [],\n message: `Node.priority expects a safe integer, received ${value}`\n })\n }\n return internal.makeNode<A, E, R>(internal.withPriority(self.ast, value))\n }\n)\n\n/**\n * Reads the scheduling priority a node carries, or `undefined` when it states\n * none and inherits from whatever encloses it.\n *\n * @since 0.1.0\n * @category accessors\n * @slop\n */\nexport const declaredPriority = (ast: Ast): number | undefined => ast.priority\n\n/**\n * Constructs the flow-call node used by `@smthrs/flow` without making flow\n * calls part of the public authoring surface of this package.\n *\n * Reserved for `@smthrs/flow`, which owns flow authoring. It is not part\n * of this package's authoring surface, and it validates nothing: an unknown\n * flow tag becomes a call node the graph keeps as a leaf.\n *\n * @since 0.1.0\n * @category engine\n * @slop\n */\nexport const flowCall = <A = unknown, E = never, R = never>(\n declaration: unknown,\n flow: string,\n mode: CallMode,\n payload: unknown\n): Node<A, E, R> => internal.makeNode<A, E, R>(internal.flowCall(declaration, flow, mode, payload))\n\n/**\n * Constructs the action-call node used by `@smthrs/flow` without making\n * action calls part of the public authoring surface of this package.\n *\n * Reserved for `@smthrs/flow`, which owns action authoring. It is not part\n * of this package's authoring surface, and an unknown action tag becomes a\n * call node the graph keeps as a leaf.\n *\n * @since 0.1.0\n * @category engine\n * @slop\n */\nexport const actionCall = <A = unknown, E = never, R = never>(\n declaration: unknown,\n action: string,\n payload: unknown\n): Node<A, E, R> => internal.makeNode<A, E, R>(internal.actionCall(declaration, action, payload))\n\n/**\n * Reads the flow or action declaration a call node names, so `@smthrs/flow`\n * can expand a call it recorded. It is `undefined` for an AST that was\n * rehydrated from JSON, because the declaration lives beside the AST rather\n * than inside it — a graph built from such an AST keeps the call as a leaf.\n *\n * Reserved for `@smthrs/flow`, which files the declaration when it builds\n * the call. Authors never call it.\n *\n * @since 0.1.0\n * @category engine\n * @slop\n */\nexport const declaration = (\n ast: Extract<Ast, { readonly _tag: \"ActionCall\" | \"FlowCall\" }>\n): unknown => internal.declaration(ast)\n\n/**\n * Reads the continuation builder of a sequenced node, which graph building\n * evaluates once against a placeholder. It is `undefined` when the author\n * supplied a node directly — the topology is already in `next` — and for a\n * rehydrated AST, whose side table did not survive serialization.\n *\n * Reserved for `@smthrs/flow`'s graph walk. Authors never call it.\n *\n * @since 0.1.0\n * @category engine\n * @slop\n */\nexport const continuation = (\n ast: Extract<Ast, { readonly _tag: \"AndThen\" }>\n): ((value: Planned.Planned<unknown>) => unknown) | undefined => internal.operation(ast)\n\n/**\n * Reads the deferred mapper of a {@link map} node, which a driver applies to\n * the real upstream value once it has one. It is `undefined` for every other\n * variant, and for a rehydrated AST whose side table did not survive\n * serialization.\n *\n * Reserved for `@smthrs/flow`'s interpreter. Authors never call it.\n *\n * @since 0.1.0\n * @category engine\n * @slop\n */\nexport const mapper = (ast: Ast): ((value: unknown) => unknown) | undefined =>\n ast._tag === \"Map\" ? internal.operation(ast) : undefined\n\n/**\n * Reads the run-time predicate of a {@link branch} node, which a driver\n * evaluates on the real subject value to choose an arm. It is `undefined` for\n * every other variant, and for a rehydrated AST whose side table did not\n * survive serialization.\n *\n * Reserved for `@smthrs/flow`'s interpreter. Authors never call it.\n *\n * @since 0.1.0\n * @category engine\n * @slop\n */\nexport const predicate = (ast: Ast): ((value: unknown) => boolean) | undefined =>\n ast._tag === \"Branch\" ? internal.predicate(ast) : undefined\n\n/**\n * Reads the optional schema selecting failures handled by a {@link catch_}.\n *\n * Reserved for `@smthrs/flow`'s interpreter. It is `undefined` for every\n * variant but `catch_`, and for a rehydrated AST whose side table did not\n * survive serialization.\n *\n * @since 0.1.0\n * @category engine\n * @slop\n */\nexport const catchFilter = (ast: Ast): Schema.Top | undefined => ast._tag === \"Catch\" ? internal.filter(ast) : undefined\n\n/**\n * Identifies a plan-time function the AST does NOT store, a flow's `body`,\n * exactly as the AST identifies the mapper and continuation it does store.\n * A call that keeps its callee as a leaf still has to re-key when that\n * callee's body is edited, and this is the identity it folds in. Unannotated\n * functions fail closed with process-local identity; use {@link capture} to\n * declare inert captures and obtain deterministic identity.\n *\n * Reserved for `@smthrs/flow`, which folds a callee body's identity into a\n * call it keeps as a leaf. Authors never call it; it throws a `TypeError`\n * when handed anything but a function.\n *\n * @since 0.1.0\n * @category engine\n * @slop\n */\nexport const functionIdentity = (operation: unknown): FunctionIdentity => internal.functionIdentity(operation)\n\n/**\n * The document a schema's identity is: JSON-Schema-shaped, and the same bytes\n * under every `effect` release this package supports.\n *\n * @since 1.0.0\n * @category engine\n */\nexport type SchemaIdentity = internalSchemaIdentity.Document\n\n/**\n * The one option a schema's identity is taken under: whether an object closes\n * over the keys it declares (`\"error\"`) or leaves others open (`\"ignore\"`,\n * the default). It has the meaning it has in `Schema.toJsonSchemaDocument`.\n *\n * @since 1.0.0\n * @category engine\n */\nexport type SchemaIdentityOptions = internalSchemaIdentity.Options\n\n/**\n * The refusal `schemaIdentity` and `representationIdentity` raise for a schema\n * a step key cannot be derived from. Its message is the one\n * `effect@4.0.0-rc.115` gave for the same schema, where it gave one.\n *\n * @since 1.0.0\n * @category errors\n */\nexport const SchemaIdentityError = internalSchemaIdentity.SchemaIdentityError\n\n/**\n * The type of {@link SchemaIdentityError}.\n *\n * @since 1.0.0\n * @category errors\n */\nexport type SchemaIdentityError = internalSchemaIdentity.SchemaIdentityError\n\n/**\n * Identifies a schema by the constraints it documents, so a call re-keys when\n * what its callee accepts or produces changes, and a catch re-keys when its\n * filter does.\n *\n * The document is what `Schema.toJsonSchemaDocument(schema, options)`\n * returned under `effect@4.0.0-rc.115`. It is printed by this package, not by\n * the installed `effect`, because a later release prints a different document\n * for the same schema and a moved identity re-keys every recorded step. Use\n * it wherever the document is hashed, compared or pinned; a JSON Schema shown\n * to a model or a person comes from `Schema.toJsonSchemaDocument`.\n *\n * Reserved for the packages that derive identities. Authors never call it; it\n * throws for a schema that has no JSON Schema form.\n *\n * @since 1.0.0\n * @category engine\n */\nexport const schemaIdentity = (schema: Schema.Top, options?: SchemaIdentityOptions): SchemaIdentity =>\n internalSchemaIdentity.schemaIdentity(schema, options)\n\n/**\n * Identifies a schema AST by its encoded representation, the material a\n * sealed action's step key folds in for its success and error schemas.\n *\n * The value is what `SchemaRepresentation.toJson(SchemaRepresentation.toRepresentation(ast))`\n * returned under `effect@4.0.0-rc.115`, so a later `effect` release does not\n * re-key recorded steps. The one exception is `Schema.brand`: from\n * `effect@4.0.4` on a brand is not part of the AST, so a declaration with a\n * brand re-keys once.\n *\n * Reserved for the packages that derive step keys. Authors never call it; it\n * throws for an AST that has no representation.\n *\n * @since 1.0.0\n * @category engine\n */\nexport const representationIdentity = (ast: SchemaAST.AST): Schema.Json =>\n internalSchemaIdentity.representationIdentity(ast)\n\n/**\n * Binds a frozen plain copy of inert captures as the callback's this receiver.\n *\n * Use a function expression to read the snapshot while keeping the ordinary\n * callback arguments: Node.capture({ factor: 3 }, function(value: number) {\n * return value * this.factor\n * }). Caller objects remain unchanged; lexical aliases still name originals\n * and must not be used as mutable semantic inputs. Nested captures retain the\n * inner callback's snapshot and compose the two identities.\n *\n * Admission walks original descriptors once, rejects built-in brands and\n * non-plain prototypes without evaluating getters, then uses structuredClone\n * to refuse Proxies. Hosts without that API refuse object capture. Only the\n * owned frozen copy enters identity and the wrapper. Sealed, non-extensible,\n * frozen and Immer ordinary data are supported equally. Unsupported values\n * raise a TypeError naming the path. See core docs/api.md#nodecapture for the\n * complete algorithm and the migration from original-object locking.\n *\n * @category constructors\n * @since 0.1.0\n * @slop\n */\nexport const capture = <C extends Readonly<Record<string, unknown>>, Args extends ReadonlyArray<unknown>, A>(\n captures: C,\n operation: (this: Readonly<C>, ...args: Args) => A\n): (...args: Args) => A => internal.capture(captures, operation)\n"]}
@@ -22,7 +22,7 @@
22
22
  * resolved references, and the hashed `version`.
23
23
  *
24
24
  * Governing contract: the step-key rules at
25
- * https://smithers.sh/docs/concepts/content-addressing.
25
+ * https://github.com/smithersai/smithers/blob/main/packages/smithers/flows/plan/docs/concepts/step-keys.md.
26
26
  *
27
27
  * @since 0.1.0
28
28
  */
@@ -22,7 +22,7 @@
22
22
  * resolved references, and the hashed `version`.
23
23
  *
24
24
  * Governing contract: the step-key rules at
25
- * https://smithers.sh/docs/concepts/content-addressing.
25
+ * https://github.com/smithersai/smithers/blob/main/packages/smithers/flows/plan/docs/concepts/step-keys.md.
26
26
  *
27
27
  * @since 0.1.0
28
28
  */
@@ -1 +1 @@
1
- {"version":3,"file":"StepKey.js","sourceRoot":"","sources":["../../src/StepKey.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * The KeyMaterial → step-key compiler.\n *\n * Revived from the deleted `packages/smithers/flows/keys/src/StepKey.ts`. Two\n * deliberate deviations from the original:\n *\n * 1. **It lives here, not in `@smthrs/keys`.** That package owns generic\n * derivation and stored-key validation; a compiler that understands plan\n * material belongs above it.\n * 2. **It produces `@smthrs/keys` `StoredKey` values, not a second `sk1_` digest\n * format.** The original minted its own prefix over a private `Digest`\n * module. The engine dispatches under `StoredKey` (`FlowEngine/ActionKey.ts`),\n * so a plan whose node keys were a *different* string format could never be\n * the thing the cache is consulted against, and that is the whole point of\n * a `Plan`. One key format, one hashing\n * chokepoint (canonical JSON + injected `Crypto`), one namespace field\n * (`kind`) distinguishing content keys from ordinal ones.\n *\n * Everything the original earned is kept: nominally branded digest inputs (a\n * literal that merely *looks* like `{digest}` hashes as a literal), set\n * normalization, the separate environment namespace, per-variant tagging of\n * resolved references, and the hashed `version`.\n *\n * Governing contract: the step-key rules at\n * https://smithers.sh/docs/concepts/content-addressing.\n *\n * @since 0.1.0\n */\n\nimport { DerivedKey, type StoredKey } from \"@smthrs/keys\"\nimport * as Cause from \"effect/Cause\"\nimport type * as Crypto from \"effect/Crypto\"\nimport * as Deferred from \"effect/Deferred\"\nimport * as Effect from \"effect/Effect\"\nimport * as Exit from \"effect/Exit\"\nimport * as Schema from \"effect/Schema\"\nimport type * as FileSet from \"./FileSet.ts\"\nimport type * as KeyMaterial from \"./KeyMaterial.ts\"\n\n/**\n * A computed step key. Identical in representation to any other flow key —\n * `key1_` plus a SHA-256 digest of the canonical serialization of the material.\n *\n * @since 0.1.0\n * @category models\n * @slop\n */\nexport type StepKey = StoredKey\n\n/**\n * The nominal brand carried by every {@link DigestInput}. Kept private: the\n * only way to produce a value bearing it is {@link digestInput}, so a plain\n * value that merely happens to look like `{ digest: \"...\" }` — actions pass\n * content hashes around as ordinary data — can never be mistaken for a genuine\n * upstream-result digest reference. This closes a step-key collision where\n * shape-sniffing (`\"digest\" in value`) hashed the two identically.\n *\n * @since 0.1.0\n * @category symbols\n */\nconst DigestInputTypeId: unique symbol = Symbol.for(\"@smthrs/plan/StepKey/DigestInput\")\n\n/**\n * Which kind of graph reference a {@link DigestInput} stands for. Declared\n * once here so the field on `DigestInput` and the parameter of\n * {@link digestInput} name one set and cannot drift apart.\n */\ntype GraphReference = \"ref\" | \"pending\" | \"ref-projected\"\n\n/**\n * A precomputed digest supplied as a step input rather than a literal value.\n *\n * @since 0.1.0\n * @category models\n * @slop\n */\nexport interface DigestInput {\n readonly [DigestInputTypeId]: typeof DigestInputTypeId\n readonly digest: string\n /**\n * Which kind of graph reference resolved to this digest.\n *\n * Carrying the discriminator on the digest input keeps `normalizeInputs` the\n * single normalizer: it wraps every variant once, and the variants stay\n * mutually distinct because they differ in this field rather than in a\n * hand-built object a second wrap would hide.\n */\n readonly reference?: GraphReference\n /** The projection applied to the referenced result, for `ref-projected`. */\n readonly path?: ReadonlyArray<string>\n}\n\n/**\n * Nominally tags a precomputed digest so it is hashed as a digest reference\n * rather than a literal value.\n *\n * @since 0.1.0\n * @category constructors\n * @slop\n */\nexport const digestInput = (\n digest: string,\n reference?: {\n readonly reference: GraphReference\n readonly path?: ReadonlyArray<string>\n }\n): DigestInput => ({\n [DigestInputTypeId]: DigestInputTypeId,\n digest,\n ...(reference === undefined ? {} : { reference: reference.reference }),\n ...(reference?.path === undefined ? {} : { path: reference.path })\n})\n\n/**\n * Type guard for values produced by {@link digestInput}.\n *\n * @since 0.1.0\n * @category guards\n * @slop\n */\nexport const isDigestInput = (value: unknown): value is DigestInput =>\n typeof value === \"object\" && value !== null && DigestInputTypeId in value &&\n (value as Record<PropertyKey, unknown>)[DigestInputTypeId] === DigestInputTypeId\n\n/**\n * The engine-resolved execution environment a content key is computed under,\n * hashed in its OWN namespace rather than merged into the caller's `layers`\n * and `capabilities`.\n *\n * Three properties matter and none survives a merge:\n *\n * 1. **Non-aliasing.** Concatenating environment material onto the caller's\n * made `caller{fs:[\"a\"]} + env{fs:[\"b\"]}` hash identically to\n * `caller{fs:[\"a\",\"b\"]} + env{}` — a cross-run collision in the very\n * material whose purpose is preventing one.\n * 2. **Declared vs undeclared.** `declared: false` is not the same value as\n * `declared: true` with empty sets.\n * 3. **Composition order.** Environment layers retain declaration order,\n * because plugin and service composition order can change behavior. The\n * caller-owned `ContentIdentity.layers` stays set-normalized.\n *\n * `runScope` is set only when `declared` is `false`: it pins the key to one\n * run, so a step whose environment identity is unknown can never serve a\n * cross-run hit. The union enforces this for typed callers; both\n * {@link content} and {@link dispatchIdentity} validate it at run time.\n *\n * @since 0.1.0\n * @category models\n * @slop\n */\nexport type EnvironmentIdentity = typeof EnvironmentIdentity.Type\n\n/**\n * Validated, copyable runtime environment identity. Layer order matters;\n * capability patterns are set-like. Unknown fields are not identity material.\n * @since 1.0.0\n * @category schemas\n */\nexport const EnvironmentIdentity = Schema.Union([\n Schema.Struct({\n declared: Schema.Literal(true),\n layers: Schema.Array(Schema.String),\n capabilities: Schema.Record(Schema.String, Schema.Array(Schema.String)),\n runScope: Schema.optionalKey(Schema.Undefined)\n }),\n Schema.Struct({\n declared: Schema.Literal(false),\n layers: Schema.Array(Schema.String),\n capabilities: Schema.Record(Schema.String, Schema.Array(Schema.String)),\n runScope: Schema.NonEmptyString\n })\n])\n\n/**\n * Caller-owned memoization context for projected dependency-value digests.\n *\n * This is the flows counterpart of Bazel's `ActionKeyContext`: one context is\n * passed through related key computations so shared input material is hashed\n * once. Concurrent requests for the same projection share the in-flight\n * digest. Entries are sound only while each settled `from` value is immutable;\n * callers must create a fresh memo when those values can change.\n *\n * @since 0.1.0\n * @category models\n * @slop\n */\nexport interface DigestMemo {\n readonly digest: (\n from: string,\n path: ReadonlyArray<string>,\n compute: Effect.Effect<StepKey, Schema.SchemaError, Crypto.Crypto>\n ) => Effect.Effect<StepKey, Schema.SchemaError, Crypto.Crypto>\n}\n\n/**\n * Creates an empty projected-value digest memo. Projection addresses are\n * JSON-encoded `[from, path]` tuples so segment boundaries are unambiguous.\n *\n * @since 0.1.0\n * @category constructors\n * @slop\n */\nexport const makeDigestMemo = (): DigestMemo => {\n const entries = new Map<string, Deferred.Deferred<StepKey, Schema.SchemaError>>()\n const digest: DigestMemo[\"digest\"] = (from, path, compute) =>\n Effect.suspend(() => {\n const address = JSON.stringify([from, path])\n const existing = entries.get(address)\n if (existing !== undefined) {\n return Effect.flatMap(Effect.exit(Deferred.await(existing)), (exit) => {\n if (Exit.isSuccess(exit)) return Effect.succeed(exit.value)\n // A waiter did not request the leader's cancellation. It competes to\n // become the replacement leader instead of inheriting that interrupt.\n return Cause.hasInterrupts(exit.cause) ? digest(from, path, compute) : Effect.failCause(exit.cause)\n })\n }\n const pending = Deferred.makeUnsafe<StepKey, Schema.SchemaError>()\n entries.set(address, pending)\n return compute.pipe(\n Effect.onExit((exit) =>\n Effect.gen(function*() {\n if (Exit.isFailure(exit) && entries.get(address) === pending) {\n entries.delete(address)\n }\n yield* Deferred.done(pending, exit)\n })\n )\n )\n })\n return { digest }\n}\n\n/**\n * Material describing a sealed or hermetic content-addressed step.\n *\n * @since 0.1.0\n * @category models\n * @slop\n */\nexport interface ContentIdentity {\n readonly body: unknown\n readonly inputs: Readonly<Record<string, unknown | DigestInput>>\n readonly layers: ReadonlyArray<string>\n readonly capabilities: Readonly<Record<string, ReadonlyArray<string>>>\n readonly environment?: EnvironmentIdentity | undefined\n readonly hermetic?: {\n readonly readSet: ReadonlyArray<{ readonly path: string; readonly digest: string }>\n readonly writeSet: ReadonlyArray<FileSet.Entry>\n readonly removes?: ReadonlyArray<string> | undefined\n readonly boundaryMode: FileSet.BoundaryMode\n } | undefined\n}\n\n/**\n * Material describing the run-local identity of a non-cacheable step.\n *\n * @since 0.1.0\n * @category models\n * @slop\n */\nexport interface OrdinalIdentity {\n readonly runId: string\n readonly parentScope?: string | undefined\n readonly ordinal: number\n readonly tier: \"compensable\" | \"irreversible\" | \"unsealed\"\n}\n\n/**\n * Stable failures while resolving graph-local dependency references.\n *\n * @since 0.1.0\n * @category errors\n * @slop\n */\nexport class KeyMaterialError extends Schema.TaggedError<KeyMaterialError>()(\"@smthrs/plan/KeyMaterialError\", {\n code: Schema.Literals([\"invalid_environment\", \"missing_dependency\", \"non_content_material\"]),\n message: Schema.String\n}) {}\n\nconst validateEnvironment = (environment: EnvironmentIdentity): KeyMaterialError | undefined => {\n const candidate = environment as { readonly declared?: unknown; readonly runScope?: unknown }\n if (candidate.declared === false) {\n if (typeof candidate.runScope !== \"string\" || candidate.runScope.length === 0) {\n return new KeyMaterialError({\n code: \"invalid_environment\",\n message: \"Undeclared environment identity requires a non-empty runScope\"\n })\n }\n return undefined\n }\n if (candidate.declared === true) {\n return candidate.runScope === undefined\n ? undefined\n : new KeyMaterialError({\n code: \"invalid_environment\",\n message: \"Declared environment identity must not include runScope\"\n })\n }\n return new KeyMaterialError({\n code: \"invalid_environment\",\n message: \"Environment identity requires a boolean declared field\"\n })\n}\n\nconst decodeEnvironment = (environment: EnvironmentIdentity) =>\n Effect.try({\n try: () => {\n const invalid = validateEnvironment(environment)\n if (invalid !== undefined) throw invalid\n return Schema.decodeUnknownSync(EnvironmentIdentity)(environment, { onExcessProperty: \"error\" })\n },\n catch: (cause) =>\n cause instanceof KeyMaterialError ? cause : new KeyMaterialError({\n code: \"invalid_environment\",\n message:\n \"Environment identity must contain only its declared fields, string layers, and string capability patterns\"\n })\n })\n\nconst sortStrings = (values: ReadonlyArray<string>): Array<string> =>\n [...new Set(values.map((value) => value.normalize(\"NFC\")))].sort()\n\nconst normalizeInputs = (inputs: ContentIdentity[\"inputs\"]): Record<string, unknown> =>\n Object.fromEntries(\n Object.entries(inputs).map(([name, value]) => [\n name,\n isDigestInput(value)\n ? {\n kind: \"digest\",\n digest: value.digest,\n ...(value.reference === undefined ? {} : { reference: value.reference }),\n ...(value.path === undefined ? {} : { path: value.path })\n }\n : { kind: \"literal\", value }\n ])\n )\n\nconst normalizeCapabilities = (capabilities: ContentIdentity[\"capabilities\"]): Record<string, Array<string>> =>\n Object.fromEntries(Object.entries(capabilities).map(([group, patterns]) => [group, sortStrings(patterns)]))\n\nconst normalizeEnvironment = (environment: EnvironmentIdentity) => ({\n declared: environment.declared,\n layers: environment.layers.map((layer) => layer.normalize(\"NFC\")),\n capabilities: normalizeCapabilities(environment.capabilities),\n ...(environment.runScope === undefined ? {} : { runScope: environment.runScope })\n})\n\nconst compareCodeUnits = (left: string, right: string): number => left < right ? -1 : 1\n\ntype NormalizedWriteEntry =\n | string\n | { readonly _tag: \"TreeArtifact\"; readonly path: string }\n | {\n readonly _tag: \"Glob\"\n readonly include: ReadonlyArray<string>\n readonly exclude?: ReadonlyArray<string> | undefined\n }\n\nconst writeEntryKey = (entry: NormalizedWriteEntry): string =>\n typeof entry === \"string\"\n ? JSON.stringify([\"Path\", entry])\n : entry._tag === \"TreeArtifact\"\n ? JSON.stringify([entry._tag, entry.path])\n : JSON.stringify([entry._tag, entry.include, entry.exclude ?? null])\n\nconst normalizeHermetic = (hermetic: NonNullable<ContentIdentity[\"hermetic\"]>) => {\n const readSet = [...hermetic.readSet]\n .map((entry) => ({ path: entry.path.normalize(\"NFC\"), digest: entry.digest }))\n .sort((left, right) => {\n if (left.path !== right.path) return left.path < right.path ? -1 : 1\n return left.digest < right.digest ? -1 : left.digest > right.digest ? 1 : 0\n })\n .filter((entry, index, entries) =>\n index === 0 || entry.path !== entries[index - 1]!.path || entry.digest !== entries[index - 1]!.digest\n )\n const normalizedWrites = [...hermetic.writeSet].map((entry) => {\n if (typeof entry === \"string\") return entry.normalize(\"NFC\")\n if (entry._tag === \"TreeArtifact\") return { ...entry, path: entry.path.normalize(\"NFC\") }\n return {\n ...entry,\n include: sortStrings(entry.include),\n ...(entry.exclude === undefined ? {} : { exclude: sortStrings(entry.exclude) })\n }\n })\n const writeSet = [...new Map(normalizedWrites.map((entry) => [writeEntryKey(entry), entry])).entries()]\n .sort(([left], [right]) => compareCodeUnits(left, right))\n .map(([, entry]) => entry)\n return {\n readSet,\n writeSet,\n ...(hermetic.removes === undefined ? {} : { removes: sortStrings(hermetic.removes) }),\n boundaryMode: hermetic.boundaryMode\n }\n}\n\nconst decodeKey = Schema.decodeUnknownEffect(DerivedKey)\n\n/**\n * Fingerprint for binding one execution to its runtime environment, not an\n * action dispatch key. Uses the same normalization as content/dispatch keys.\n * An omitted environment is distinct from declared-empty and run-scoped ones.\n * @since 1.0.0\n * @category constructors\n */\nexport const environmentIdentity = (\n environment?: EnvironmentIdentity\n): Effect.Effect<StoredKey, KeyMaterialError | Schema.SchemaError, Crypto.Crypto> =>\n Effect.gen(function*() {\n const captured = environment === undefined ? undefined : yield* decodeEnvironment(environment)\n return yield* decodeKey({\n kind: \"execution-environment/v1\",\n environment: captured === undefined ? null : normalizeEnvironment(captured)\n })\n })\n\n/**\n * Produces a cross-run reusable key for a sealed or hermetic step. Set-like\n * declarations are normalized before serialization; write declarations remain\n * part of the identity even when the step writes nothing.\n *\n * @since 0.1.0\n * @category constructors\n * @slop\n */\nexport const content = (\n identity: ContentIdentity\n): Effect.Effect<StepKey, KeyMaterialError | Schema.SchemaError, Crypto.Crypto> =>\n Effect.gen(function*() {\n const environment = identity.environment === undefined ? undefined : yield* decodeEnvironment(identity.environment)\n return yield* decodeKey({\n kind: \"content\",\n body: identity.body,\n inputs: normalizeInputs(identity.inputs),\n layers: sortStrings(identity.layers),\n capabilities: normalizeCapabilities(identity.capabilities),\n ...(environment === undefined ? {} : { environment: normalizeEnvironment(environment) }),\n ...(identity.hermetic === undefined ? {} : { hermetic: normalizeHermetic(identity.hermetic) })\n })\n })\n\n/**\n * Produces a run-local ordinal key for compensable, irreversible, or unsealed\n * work. These keys intentionally cannot be reused across runs.\n *\n * @since 0.1.0\n * @category constructors\n * @slop\n */\nexport const ordinal = (\n identity: OrdinalIdentity\n): Effect.Effect<StepKey, Schema.SchemaError, Crypto.Crypto> => decodeKey({ kind: \"ordinal\", ...identity })\n\n/**\n * Resolves graph-local references to dependency digests and constructs a\n * sealed content key. Use {@link planIdentity} to compile any effect tier.\n *\n * This is the handoff the Flow Builder Brief describes: the planner hands over\n * a topologically ordered sequence of `{ nodeId, material }`, and for each one\n * the compiler substitutes every `Ref`/`Pending` with the *already computed\n * key of the referenced node*. Structural node ids are lookup addresses only\n * and never enter the hashed value — rename a node and nothing re-keys; change\n * what a node consumes and everything downstream of it does.\n *\n * @since 0.1.0\n * @category constructors\n * @slop\n */\nexport const fromKeyMaterial = (\n material: KeyMaterial.KeyMaterial,\n dependencyDigests: Readonly<Record<string, string>>\n): Effect.Effect<StepKey, KeyMaterialError | Schema.SchemaError, Crypto.Crypto> => {\n if (material.kind !== \"sealed\") {\n return Effect.fail(\n new KeyMaterialError({\n code: \"non_content_material\",\n message: `Cannot create a content key for ${material.kind} material`\n })\n )\n }\n return materialIdentity(material, dependencyDigests).pipe(Effect.flatMap(content))\n}\n\n/**\n * Identifies a declaration in a plan, independently of whether its execution\n * can be cached. Sealed material retains its existing content-key format;\n * compensable and irreversible material use a distinct, tier-bearing plan\n * namespace. These fingerprints bind approvals, not cross-run result reuse.\n * Dispatch non-cacheable work under a run-local {@link ordinal} instead.\n *\n * @since 1.0.0\n * @category constructors\n */\nexport const planIdentity = (\n material: KeyMaterial.KeyMaterial,\n dependencyDigests: Readonly<Record<string, string>>\n): Effect.Effect<StepKey, KeyMaterialError | Schema.SchemaError, Crypto.Crypto> =>\n material.kind === \"sealed\" ?\n fromKeyMaterial(material, dependencyDigests) :\n materialIdentity(material, dependencyDigests).pipe(Effect.flatMap((identity) =>\n decodeKey({\n kind: \"plan-declaration\",\n tier: material.kind,\n body: identity.body,\n inputs: normalizeInputs(identity.inputs),\n layers: sortStrings(identity.layers),\n capabilities: normalizeCapabilities(identity.capabilities)\n })\n ))\n\n/**\n * Reads the entry a graph reference names. Only an own data property counts:\n * an absent name or an accessor is a missing dependency, and no getter runs.\n * `label` names what the record holds, as each refusal says it.\n *\n * @private\n */\nconst ownDataProperty = (\n record: Readonly<Record<string, unknown>>,\n from: string,\n label: \"Digest\" | \"Settled result\"\n): Effect.Effect<unknown, KeyMaterialError> => {\n const descriptor = Object.getOwnPropertyDescriptor(record, from)\n if (descriptor === undefined) {\n return Effect.fail(\n new KeyMaterialError({\n code: \"missing_dependency\",\n message: `Missing ${label.toLowerCase()} for graph dependency ${from}`\n })\n )\n }\n if (!(\"value\" in descriptor)) {\n return Effect.fail(\n new KeyMaterialError({\n code: \"missing_dependency\",\n message: `${label} for graph dependency ${from} must be a data property`\n })\n )\n }\n return Effect.succeed(descriptor.value)\n}\n\n/**\n * The positional inputs both identities hash. A `Literal` contributes its raw\n * value, so `normalizeInputs` applies the one literal wrap; `resolve` supplies\n * the digest for each `Ref` and `Pending`, tagged with the reference variant.\n *\n * @private\n */\nconst resolveInputs = <E, R>(\n material: KeyMaterial.KeyMaterial,\n resolve: (reference: Exclude<KeyMaterial.InputRef, { readonly _tag: \"Literal\" }>) => Effect.Effect<string, E, R>\n): Effect.Effect<Record<string, unknown>, E, R> =>\n Effect.gen(function*() {\n const inputs: Record<string, unknown> = {}\n for (let index = 0; index < material.inputs.length; index++) {\n const input = material.inputs[index]!\n if (input._tag === \"Literal\") {\n inputs[String(index)] = input.value\n continue\n }\n const digest = yield* resolve(input)\n inputs[String(index)] = input._tag === \"Pending\"\n ? digestInput(digest, { reference: \"pending\" })\n : input.path.length > 0\n ? digestInput(digest, { reference: \"ref-projected\", path: input.path })\n : digestInput(digest, { reference: \"ref\" })\n }\n return inputs\n })\n\n/** Resolves plan references once for both content and non-cacheable declarations. */\nconst materialIdentity = (\n material: KeyMaterial.KeyMaterial,\n dependencyDigests: Readonly<Record<string, string>>\n): Effect.Effect<ContentIdentity, KeyMaterialError> =>\n resolveInputs(\n material,\n (reference) =>\n Effect.flatMap(ownDataProperty(dependencyDigests, reference.from, \"Digest\"), (digest) =>\n typeof digest === \"string\" ? Effect.succeed(digest) : Effect.fail(\n new KeyMaterialError({\n code: \"missing_dependency\",\n message: `Digest for graph dependency ${reference.from} must be a string`\n })\n ))\n ).pipe(Effect.map((inputs) => ({\n body: materialBody(material),\n inputs,\n layers: material.layers,\n capabilities: { declared: material.capabilities }\n })))\n\n/**\n * The node's own declaration, hashed. Shared by {@link planIdentity},\n * {@link fromKeyMaterial}, and {@link dispatchIdentity} so derivations cannot drift about what\n * \"the node itself\" means.\n *\n * @private\n */\nconst materialBody = (material: KeyMaterial.KeyMaterial) => ({\n version: material.version,\n declaration: material.body,\n ...(material.nondeterministic === undefined ? {} : { nondeterministic: material.nondeterministic }),\n ...(material.effects === undefined ? {} : { effects: material.effects }),\n ...(material.placement === undefined ? {} : { placement: material.placement })\n})\n\n/**\n * The digest a `Pending` input contributes to a dispatch key. It is a\n * constant, and that is the point: `Pending` is an ordering reference, and\n * ordering does not change what a node consumes, so it must not change what\n * the node caches under. The string is self-describing, so a reader of a\n * hashed payload can see that no upstream value was folded.\n *\n * @private\n */\nconst orderingOnly = \"ordering-only\"\n\n/**\n * Projects a settled result along a `Ref` path. Only own data properties\n * resolve, so a missing, inherited, or accessor segment yields `undefined`\n * without invoking a getter. This is a stable, distinct value: a projection that\n * walks off the end of a result is a fact about the graph, not a failure.\n * `undefined` drops out of the canonical form, so it hashes distinctly from\n * every JSON value including `null`.\n *\n * Exported because it is the ONE projection semantics for the value channel:\n * {@link dispatchIdentity} digests what this returns, so every consumer that\n * resolves a `Ref` at execution time must resolve it the same way, or two\n * inputs that key identically could be consumed differently — a stale-hit\n * vector.\n *\n * @since 0.1.0\n * @category utilities\n * @slop\n */\nexport const project = (value: unknown, path: ReadonlyArray<string>): unknown => {\n let current = value\n for (const segment of path) {\n if (typeof current !== \"object\" || current === null) return undefined\n const descriptor = Object.getOwnPropertyDescriptor(current, segment)\n if (descriptor === undefined || !(\"value\" in descriptor)) return undefined\n current = descriptor.value\n }\n return current\n}\n\n/**\n * The key a dispatch is *cached* under, as distinct from the plan key a node\n * is *identified* by.\n *\n * A plan key folds the resolved keys of every upstream node, transitively, so\n * an edit anywhere upstream re-keys everything below it — even when the edited\n * node's output value is byte for byte what it was before. Bazel does not work\n * that way: `ActionCacheChecker` keys an action by the *content* of its\n * inputs, so an unchanged output stops invalidation dead. The file channel in\n * flows already had that property through the measured boundary digests; the\n * JSON value channel did not, and this is what gives it one.\n *\n * The derivation folds the node's OWN material — body, version, effects,\n * placement, layers, capabilities — and never an upstream key. Each material\n * input contributes content instead: a `Literal` its value, a `Ref` the digest\n * of the settled result of `from` projected along `path`, and a `Pending`\n * nothing beyond its tag. The measured hermetic boundary is folded unchanged.\n *\n * `results` must hold every dependency the material names. The scheduler's\n * halt rule guarantees it: a dependent of failed or skipped work never\n * dispatches, so a `Ref` always resolves against a success.\n *\n * @since 0.1.0\n * @category constructors\n * @slop\n */\nexport const dispatchIdentity = (options: {\n readonly material: KeyMaterial.KeyMaterial\n /** The settled output value of each dependency, by node id. */\n readonly results: Readonly<Record<string, unknown>>\n readonly hermetic: NonNullable<ContentIdentity[\"hermetic\"]>\n /** The engine-resolved execution environment this dispatch runs under. */\n readonly environment?: EnvironmentIdentity | undefined\n /** Reuses projected-value digests while the corresponding settled values remain immutable. */\n readonly digestMemo?: DigestMemo | undefined\n}): Effect.Effect<StepKey, KeyMaterialError | Schema.SchemaError, Crypto.Crypto> =>\n Effect.gen(function*() {\n const material = options.material\n if (material.kind !== \"sealed\") {\n return yield* new KeyMaterialError({\n code: \"non_content_material\",\n message: `Cannot create a dispatch key for ${material.kind} material`\n })\n }\n const environment = options.environment === undefined ? undefined : yield* decodeEnvironment(options.environment)\n const inputs = yield* resolveInputs(material, (reference) =>\n reference._tag === \"Pending\"\n ? Effect.succeed(orderingOnly)\n : Effect.flatMap(ownDataProperty(options.results, reference.from, \"Settled result\"), (settled) => {\n const compute = decodeKey({ kind: \"input-value\", value: project(settled, reference.path) })\n return options.digestMemo === undefined\n ? compute\n : options.digestMemo.digest(reference.from, reference.path, compute)\n }))\n return yield* content({\n body: materialBody(material),\n inputs,\n layers: material.layers,\n capabilities: { declared: material.capabilities },\n environment,\n hermetic: options.hermetic\n })\n })\n"]}
1
+ {"version":3,"file":"StepKey.js","sourceRoot":"","sources":["../../src/StepKey.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * The KeyMaterial → step-key compiler.\n *\n * Revived from the deleted `packages/smithers/flows/keys/src/StepKey.ts`. Two\n * deliberate deviations from the original:\n *\n * 1. **It lives here, not in `@smthrs/keys`.** That package owns generic\n * derivation and stored-key validation; a compiler that understands plan\n * material belongs above it.\n * 2. **It produces `@smthrs/keys` `StoredKey` values, not a second `sk1_` digest\n * format.** The original minted its own prefix over a private `Digest`\n * module. The engine dispatches under `StoredKey` (`FlowEngine/ActionKey.ts`),\n * so a plan whose node keys were a *different* string format could never be\n * the thing the cache is consulted against, and that is the whole point of\n * a `Plan`. One key format, one hashing\n * chokepoint (canonical JSON + injected `Crypto`), one namespace field\n * (`kind`) distinguishing content keys from ordinal ones.\n *\n * Everything the original earned is kept: nominally branded digest inputs (a\n * literal that merely *looks* like `{digest}` hashes as a literal), set\n * normalization, the separate environment namespace, per-variant tagging of\n * resolved references, and the hashed `version`.\n *\n * Governing contract: the step-key rules at\n * https://github.com/smithersai/smithers/blob/main/packages/smithers/flows/plan/docs/concepts/step-keys.md.\n *\n * @since 0.1.0\n */\n\nimport { DerivedKey, type StoredKey } from \"@smthrs/keys\"\nimport * as Cause from \"effect/Cause\"\nimport type * as Crypto from \"effect/Crypto\"\nimport * as Deferred from \"effect/Deferred\"\nimport * as Effect from \"effect/Effect\"\nimport * as Exit from \"effect/Exit\"\nimport * as Schema from \"effect/Schema\"\nimport type * as FileSet from \"./FileSet.ts\"\nimport type * as KeyMaterial from \"./KeyMaterial.ts\"\n\n/**\n * A computed step key. Identical in representation to any other flow key —\n * `key1_` plus a SHA-256 digest of the canonical serialization of the material.\n *\n * @since 0.1.0\n * @category models\n * @slop\n */\nexport type StepKey = StoredKey\n\n/**\n * The nominal brand carried by every {@link DigestInput}. Kept private: the\n * only way to produce a value bearing it is {@link digestInput}, so a plain\n * value that merely happens to look like `{ digest: \"...\" }` — actions pass\n * content hashes around as ordinary data — can never be mistaken for a genuine\n * upstream-result digest reference. This closes a step-key collision where\n * shape-sniffing (`\"digest\" in value`) hashed the two identically.\n *\n * @since 0.1.0\n * @category symbols\n */\nconst DigestInputTypeId: unique symbol = Symbol.for(\"@smthrs/plan/StepKey/DigestInput\")\n\n/**\n * Which kind of graph reference a {@link DigestInput} stands for. Declared\n * once here so the field on `DigestInput` and the parameter of\n * {@link digestInput} name one set and cannot drift apart.\n */\ntype GraphReference = \"ref\" | \"pending\" | \"ref-projected\"\n\n/**\n * A precomputed digest supplied as a step input rather than a literal value.\n *\n * @since 0.1.0\n * @category models\n * @slop\n */\nexport interface DigestInput {\n readonly [DigestInputTypeId]: typeof DigestInputTypeId\n readonly digest: string\n /**\n * Which kind of graph reference resolved to this digest.\n *\n * Carrying the discriminator on the digest input keeps `normalizeInputs` the\n * single normalizer: it wraps every variant once, and the variants stay\n * mutually distinct because they differ in this field rather than in a\n * hand-built object a second wrap would hide.\n */\n readonly reference?: GraphReference\n /** The projection applied to the referenced result, for `ref-projected`. */\n readonly path?: ReadonlyArray<string>\n}\n\n/**\n * Nominally tags a precomputed digest so it is hashed as a digest reference\n * rather than a literal value.\n *\n * @since 0.1.0\n * @category constructors\n * @slop\n */\nexport const digestInput = (\n digest: string,\n reference?: {\n readonly reference: GraphReference\n readonly path?: ReadonlyArray<string>\n }\n): DigestInput => ({\n [DigestInputTypeId]: DigestInputTypeId,\n digest,\n ...(reference === undefined ? {} : { reference: reference.reference }),\n ...(reference?.path === undefined ? {} : { path: reference.path })\n})\n\n/**\n * Type guard for values produced by {@link digestInput}.\n *\n * @since 0.1.0\n * @category guards\n * @slop\n */\nexport const isDigestInput = (value: unknown): value is DigestInput =>\n typeof value === \"object\" && value !== null && DigestInputTypeId in value &&\n (value as Record<PropertyKey, unknown>)[DigestInputTypeId] === DigestInputTypeId\n\n/**\n * The engine-resolved execution environment a content key is computed under,\n * hashed in its OWN namespace rather than merged into the caller's `layers`\n * and `capabilities`.\n *\n * Three properties matter and none survives a merge:\n *\n * 1. **Non-aliasing.** Concatenating environment material onto the caller's\n * made `caller{fs:[\"a\"]} + env{fs:[\"b\"]}` hash identically to\n * `caller{fs:[\"a\",\"b\"]} + env{}` — a cross-run collision in the very\n * material whose purpose is preventing one.\n * 2. **Declared vs undeclared.** `declared: false` is not the same value as\n * `declared: true` with empty sets.\n * 3. **Composition order.** Environment layers retain declaration order,\n * because plugin and service composition order can change behavior. The\n * caller-owned `ContentIdentity.layers` stays set-normalized.\n *\n * `runScope` is set only when `declared` is `false`: it pins the key to one\n * run, so a step whose environment identity is unknown can never serve a\n * cross-run hit. The union enforces this for typed callers; both\n * {@link content} and {@link dispatchIdentity} validate it at run time.\n *\n * @since 0.1.0\n * @category models\n * @slop\n */\nexport type EnvironmentIdentity = typeof EnvironmentIdentity.Type\n\n/**\n * Validated, copyable runtime environment identity. Layer order matters;\n * capability patterns are set-like. Unknown fields are not identity material.\n * @since 1.0.0\n * @category schemas\n */\nexport const EnvironmentIdentity = Schema.Union([\n Schema.Struct({\n declared: Schema.Literal(true),\n layers: Schema.Array(Schema.String),\n capabilities: Schema.Record(Schema.String, Schema.Array(Schema.String)),\n runScope: Schema.optionalKey(Schema.Undefined)\n }),\n Schema.Struct({\n declared: Schema.Literal(false),\n layers: Schema.Array(Schema.String),\n capabilities: Schema.Record(Schema.String, Schema.Array(Schema.String)),\n runScope: Schema.NonEmptyString\n })\n])\n\n/**\n * Caller-owned memoization context for projected dependency-value digests.\n *\n * This is the flows counterpart of Bazel's `ActionKeyContext`: one context is\n * passed through related key computations so shared input material is hashed\n * once. Concurrent requests for the same projection share the in-flight\n * digest. Entries are sound only while each settled `from` value is immutable;\n * callers must create a fresh memo when those values can change.\n *\n * @since 0.1.0\n * @category models\n * @slop\n */\nexport interface DigestMemo {\n readonly digest: (\n from: string,\n path: ReadonlyArray<string>,\n compute: Effect.Effect<StepKey, Schema.SchemaError, Crypto.Crypto>\n ) => Effect.Effect<StepKey, Schema.SchemaError, Crypto.Crypto>\n}\n\n/**\n * Creates an empty projected-value digest memo. Projection addresses are\n * JSON-encoded `[from, path]` tuples so segment boundaries are unambiguous.\n *\n * @since 0.1.0\n * @category constructors\n * @slop\n */\nexport const makeDigestMemo = (): DigestMemo => {\n const entries = new Map<string, Deferred.Deferred<StepKey, Schema.SchemaError>>()\n const digest: DigestMemo[\"digest\"] = (from, path, compute) =>\n Effect.suspend(() => {\n const address = JSON.stringify([from, path])\n const existing = entries.get(address)\n if (existing !== undefined) {\n return Effect.flatMap(Effect.exit(Deferred.await(existing)), (exit) => {\n if (Exit.isSuccess(exit)) return Effect.succeed(exit.value)\n // A waiter did not request the leader's cancellation. It competes to\n // become the replacement leader instead of inheriting that interrupt.\n return Cause.hasInterrupts(exit.cause) ? digest(from, path, compute) : Effect.failCause(exit.cause)\n })\n }\n const pending = Deferred.makeUnsafe<StepKey, Schema.SchemaError>()\n entries.set(address, pending)\n return compute.pipe(\n Effect.onExit((exit) =>\n Effect.gen(function*() {\n if (Exit.isFailure(exit) && entries.get(address) === pending) {\n entries.delete(address)\n }\n yield* Deferred.done(pending, exit)\n })\n )\n )\n })\n return { digest }\n}\n\n/**\n * Material describing a sealed or hermetic content-addressed step.\n *\n * @since 0.1.0\n * @category models\n * @slop\n */\nexport interface ContentIdentity {\n readonly body: unknown\n readonly inputs: Readonly<Record<string, unknown | DigestInput>>\n readonly layers: ReadonlyArray<string>\n readonly capabilities: Readonly<Record<string, ReadonlyArray<string>>>\n readonly environment?: EnvironmentIdentity | undefined\n readonly hermetic?: {\n readonly readSet: ReadonlyArray<{ readonly path: string; readonly digest: string }>\n readonly writeSet: ReadonlyArray<FileSet.Entry>\n readonly removes?: ReadonlyArray<string> | undefined\n readonly boundaryMode: FileSet.BoundaryMode\n } | undefined\n}\n\n/**\n * Material describing the run-local identity of a non-cacheable step.\n *\n * @since 0.1.0\n * @category models\n * @slop\n */\nexport interface OrdinalIdentity {\n readonly runId: string\n readonly parentScope?: string | undefined\n readonly ordinal: number\n readonly tier: \"compensable\" | \"irreversible\" | \"unsealed\"\n}\n\n/**\n * Stable failures while resolving graph-local dependency references.\n *\n * @since 0.1.0\n * @category errors\n * @slop\n */\nexport class KeyMaterialError extends Schema.TaggedError<KeyMaterialError>()(\"@smthrs/plan/KeyMaterialError\", {\n code: Schema.Literals([\"invalid_environment\", \"missing_dependency\", \"non_content_material\"]),\n message: Schema.String\n}) {}\n\nconst validateEnvironment = (environment: EnvironmentIdentity): KeyMaterialError | undefined => {\n const candidate = environment as { readonly declared?: unknown; readonly runScope?: unknown }\n if (candidate.declared === false) {\n if (typeof candidate.runScope !== \"string\" || candidate.runScope.length === 0) {\n return new KeyMaterialError({\n code: \"invalid_environment\",\n message: \"Undeclared environment identity requires a non-empty runScope\"\n })\n }\n return undefined\n }\n if (candidate.declared === true) {\n return candidate.runScope === undefined\n ? undefined\n : new KeyMaterialError({\n code: \"invalid_environment\",\n message: \"Declared environment identity must not include runScope\"\n })\n }\n return new KeyMaterialError({\n code: \"invalid_environment\",\n message: \"Environment identity requires a boolean declared field\"\n })\n}\n\nconst decodeEnvironment = (environment: EnvironmentIdentity) =>\n Effect.try({\n try: () => {\n const invalid = validateEnvironment(environment)\n if (invalid !== undefined) throw invalid\n return Schema.decodeUnknownSync(EnvironmentIdentity)(environment, { onExcessProperty: \"error\" })\n },\n catch: (cause) =>\n cause instanceof KeyMaterialError ? cause : new KeyMaterialError({\n code: \"invalid_environment\",\n message:\n \"Environment identity must contain only its declared fields, string layers, and string capability patterns\"\n })\n })\n\nconst sortStrings = (values: ReadonlyArray<string>): Array<string> =>\n [...new Set(values.map((value) => value.normalize(\"NFC\")))].sort()\n\nconst normalizeInputs = (inputs: ContentIdentity[\"inputs\"]): Record<string, unknown> =>\n Object.fromEntries(\n Object.entries(inputs).map(([name, value]) => [\n name,\n isDigestInput(value)\n ? {\n kind: \"digest\",\n digest: value.digest,\n ...(value.reference === undefined ? {} : { reference: value.reference }),\n ...(value.path === undefined ? {} : { path: value.path })\n }\n : { kind: \"literal\", value }\n ])\n )\n\nconst normalizeCapabilities = (capabilities: ContentIdentity[\"capabilities\"]): Record<string, Array<string>> =>\n Object.fromEntries(Object.entries(capabilities).map(([group, patterns]) => [group, sortStrings(patterns)]))\n\nconst normalizeEnvironment = (environment: EnvironmentIdentity) => ({\n declared: environment.declared,\n layers: environment.layers.map((layer) => layer.normalize(\"NFC\")),\n capabilities: normalizeCapabilities(environment.capabilities),\n ...(environment.runScope === undefined ? {} : { runScope: environment.runScope })\n})\n\nconst compareCodeUnits = (left: string, right: string): number => left < right ? -1 : 1\n\ntype NormalizedWriteEntry =\n | string\n | { readonly _tag: \"TreeArtifact\"; readonly path: string }\n | {\n readonly _tag: \"Glob\"\n readonly include: ReadonlyArray<string>\n readonly exclude?: ReadonlyArray<string> | undefined\n }\n\nconst writeEntryKey = (entry: NormalizedWriteEntry): string =>\n typeof entry === \"string\"\n ? JSON.stringify([\"Path\", entry])\n : entry._tag === \"TreeArtifact\"\n ? JSON.stringify([entry._tag, entry.path])\n : JSON.stringify([entry._tag, entry.include, entry.exclude ?? null])\n\nconst normalizeHermetic = (hermetic: NonNullable<ContentIdentity[\"hermetic\"]>) => {\n const readSet = [...hermetic.readSet]\n .map((entry) => ({ path: entry.path.normalize(\"NFC\"), digest: entry.digest }))\n .sort((left, right) => {\n if (left.path !== right.path) return left.path < right.path ? -1 : 1\n return left.digest < right.digest ? -1 : left.digest > right.digest ? 1 : 0\n })\n .filter((entry, index, entries) =>\n index === 0 || entry.path !== entries[index - 1]!.path || entry.digest !== entries[index - 1]!.digest\n )\n const normalizedWrites = [...hermetic.writeSet].map((entry) => {\n if (typeof entry === \"string\") return entry.normalize(\"NFC\")\n if (entry._tag === \"TreeArtifact\") return { ...entry, path: entry.path.normalize(\"NFC\") }\n return {\n ...entry,\n include: sortStrings(entry.include),\n ...(entry.exclude === undefined ? {} : { exclude: sortStrings(entry.exclude) })\n }\n })\n const writeSet = [...new Map(normalizedWrites.map((entry) => [writeEntryKey(entry), entry])).entries()]\n .sort(([left], [right]) => compareCodeUnits(left, right))\n .map(([, entry]) => entry)\n return {\n readSet,\n writeSet,\n ...(hermetic.removes === undefined ? {} : { removes: sortStrings(hermetic.removes) }),\n boundaryMode: hermetic.boundaryMode\n }\n}\n\nconst decodeKey = Schema.decodeUnknownEffect(DerivedKey)\n\n/**\n * Fingerprint for binding one execution to its runtime environment, not an\n * action dispatch key. Uses the same normalization as content/dispatch keys.\n * An omitted environment is distinct from declared-empty and run-scoped ones.\n * @since 1.0.0\n * @category constructors\n */\nexport const environmentIdentity = (\n environment?: EnvironmentIdentity\n): Effect.Effect<StoredKey, KeyMaterialError | Schema.SchemaError, Crypto.Crypto> =>\n Effect.gen(function*() {\n const captured = environment === undefined ? undefined : yield* decodeEnvironment(environment)\n return yield* decodeKey({\n kind: \"execution-environment/v1\",\n environment: captured === undefined ? null : normalizeEnvironment(captured)\n })\n })\n\n/**\n * Produces a cross-run reusable key for a sealed or hermetic step. Set-like\n * declarations are normalized before serialization; write declarations remain\n * part of the identity even when the step writes nothing.\n *\n * @since 0.1.0\n * @category constructors\n * @slop\n */\nexport const content = (\n identity: ContentIdentity\n): Effect.Effect<StepKey, KeyMaterialError | Schema.SchemaError, Crypto.Crypto> =>\n Effect.gen(function*() {\n const environment = identity.environment === undefined ? undefined : yield* decodeEnvironment(identity.environment)\n return yield* decodeKey({\n kind: \"content\",\n body: identity.body,\n inputs: normalizeInputs(identity.inputs),\n layers: sortStrings(identity.layers),\n capabilities: normalizeCapabilities(identity.capabilities),\n ...(environment === undefined ? {} : { environment: normalizeEnvironment(environment) }),\n ...(identity.hermetic === undefined ? {} : { hermetic: normalizeHermetic(identity.hermetic) })\n })\n })\n\n/**\n * Produces a run-local ordinal key for compensable, irreversible, or unsealed\n * work. These keys intentionally cannot be reused across runs.\n *\n * @since 0.1.0\n * @category constructors\n * @slop\n */\nexport const ordinal = (\n identity: OrdinalIdentity\n): Effect.Effect<StepKey, Schema.SchemaError, Crypto.Crypto> => decodeKey({ kind: \"ordinal\", ...identity })\n\n/**\n * Resolves graph-local references to dependency digests and constructs a\n * sealed content key. Use {@link planIdentity} to compile any effect tier.\n *\n * This is the handoff the Flow Builder Brief describes: the planner hands over\n * a topologically ordered sequence of `{ nodeId, material }`, and for each one\n * the compiler substitutes every `Ref`/`Pending` with the *already computed\n * key of the referenced node*. Structural node ids are lookup addresses only\n * and never enter the hashed value — rename a node and nothing re-keys; change\n * what a node consumes and everything downstream of it does.\n *\n * @since 0.1.0\n * @category constructors\n * @slop\n */\nexport const fromKeyMaterial = (\n material: KeyMaterial.KeyMaterial,\n dependencyDigests: Readonly<Record<string, string>>\n): Effect.Effect<StepKey, KeyMaterialError | Schema.SchemaError, Crypto.Crypto> => {\n if (material.kind !== \"sealed\") {\n return Effect.fail(\n new KeyMaterialError({\n code: \"non_content_material\",\n message: `Cannot create a content key for ${material.kind} material`\n })\n )\n }\n return materialIdentity(material, dependencyDigests).pipe(Effect.flatMap(content))\n}\n\n/**\n * Identifies a declaration in a plan, independently of whether its execution\n * can be cached. Sealed material retains its existing content-key format;\n * compensable and irreversible material use a distinct, tier-bearing plan\n * namespace. These fingerprints bind approvals, not cross-run result reuse.\n * Dispatch non-cacheable work under a run-local {@link ordinal} instead.\n *\n * @since 1.0.0\n * @category constructors\n */\nexport const planIdentity = (\n material: KeyMaterial.KeyMaterial,\n dependencyDigests: Readonly<Record<string, string>>\n): Effect.Effect<StepKey, KeyMaterialError | Schema.SchemaError, Crypto.Crypto> =>\n material.kind === \"sealed\" ?\n fromKeyMaterial(material, dependencyDigests) :\n materialIdentity(material, dependencyDigests).pipe(Effect.flatMap((identity) =>\n decodeKey({\n kind: \"plan-declaration\",\n tier: material.kind,\n body: identity.body,\n inputs: normalizeInputs(identity.inputs),\n layers: sortStrings(identity.layers),\n capabilities: normalizeCapabilities(identity.capabilities)\n })\n ))\n\n/**\n * Reads the entry a graph reference names. Only an own data property counts:\n * an absent name or an accessor is a missing dependency, and no getter runs.\n * `label` names what the record holds, as each refusal says it.\n *\n * @private\n */\nconst ownDataProperty = (\n record: Readonly<Record<string, unknown>>,\n from: string,\n label: \"Digest\" | \"Settled result\"\n): Effect.Effect<unknown, KeyMaterialError> => {\n const descriptor = Object.getOwnPropertyDescriptor(record, from)\n if (descriptor === undefined) {\n return Effect.fail(\n new KeyMaterialError({\n code: \"missing_dependency\",\n message: `Missing ${label.toLowerCase()} for graph dependency ${from}`\n })\n )\n }\n if (!(\"value\" in descriptor)) {\n return Effect.fail(\n new KeyMaterialError({\n code: \"missing_dependency\",\n message: `${label} for graph dependency ${from} must be a data property`\n })\n )\n }\n return Effect.succeed(descriptor.value)\n}\n\n/**\n * The positional inputs both identities hash. A `Literal` contributes its raw\n * value, so `normalizeInputs` applies the one literal wrap; `resolve` supplies\n * the digest for each `Ref` and `Pending`, tagged with the reference variant.\n *\n * @private\n */\nconst resolveInputs = <E, R>(\n material: KeyMaterial.KeyMaterial,\n resolve: (reference: Exclude<KeyMaterial.InputRef, { readonly _tag: \"Literal\" }>) => Effect.Effect<string, E, R>\n): Effect.Effect<Record<string, unknown>, E, R> =>\n Effect.gen(function*() {\n const inputs: Record<string, unknown> = {}\n for (let index = 0; index < material.inputs.length; index++) {\n const input = material.inputs[index]!\n if (input._tag === \"Literal\") {\n inputs[String(index)] = input.value\n continue\n }\n const digest = yield* resolve(input)\n inputs[String(index)] = input._tag === \"Pending\"\n ? digestInput(digest, { reference: \"pending\" })\n : input.path.length > 0\n ? digestInput(digest, { reference: \"ref-projected\", path: input.path })\n : digestInput(digest, { reference: \"ref\" })\n }\n return inputs\n })\n\n/** Resolves plan references once for both content and non-cacheable declarations. */\nconst materialIdentity = (\n material: KeyMaterial.KeyMaterial,\n dependencyDigests: Readonly<Record<string, string>>\n): Effect.Effect<ContentIdentity, KeyMaterialError> =>\n resolveInputs(\n material,\n (reference) =>\n Effect.flatMap(ownDataProperty(dependencyDigests, reference.from, \"Digest\"), (digest) =>\n typeof digest === \"string\" ? Effect.succeed(digest) : Effect.fail(\n new KeyMaterialError({\n code: \"missing_dependency\",\n message: `Digest for graph dependency ${reference.from} must be a string`\n })\n ))\n ).pipe(Effect.map((inputs) => ({\n body: materialBody(material),\n inputs,\n layers: material.layers,\n capabilities: { declared: material.capabilities }\n })))\n\n/**\n * The node's own declaration, hashed. Shared by {@link planIdentity},\n * {@link fromKeyMaterial}, and {@link dispatchIdentity} so derivations cannot drift about what\n * \"the node itself\" means.\n *\n * @private\n */\nconst materialBody = (material: KeyMaterial.KeyMaterial) => ({\n version: material.version,\n declaration: material.body,\n ...(material.nondeterministic === undefined ? {} : { nondeterministic: material.nondeterministic }),\n ...(material.effects === undefined ? {} : { effects: material.effects }),\n ...(material.placement === undefined ? {} : { placement: material.placement })\n})\n\n/**\n * The digest a `Pending` input contributes to a dispatch key. It is a\n * constant, and that is the point: `Pending` is an ordering reference, and\n * ordering does not change what a node consumes, so it must not change what\n * the node caches under. The string is self-describing, so a reader of a\n * hashed payload can see that no upstream value was folded.\n *\n * @private\n */\nconst orderingOnly = \"ordering-only\"\n\n/**\n * Projects a settled result along a `Ref` path. Only own data properties\n * resolve, so a missing, inherited, or accessor segment yields `undefined`\n * without invoking a getter. This is a stable, distinct value: a projection that\n * walks off the end of a result is a fact about the graph, not a failure.\n * `undefined` drops out of the canonical form, so it hashes distinctly from\n * every JSON value including `null`.\n *\n * Exported because it is the ONE projection semantics for the value channel:\n * {@link dispatchIdentity} digests what this returns, so every consumer that\n * resolves a `Ref` at execution time must resolve it the same way, or two\n * inputs that key identically could be consumed differently — a stale-hit\n * vector.\n *\n * @since 0.1.0\n * @category utilities\n * @slop\n */\nexport const project = (value: unknown, path: ReadonlyArray<string>): unknown => {\n let current = value\n for (const segment of path) {\n if (typeof current !== \"object\" || current === null) return undefined\n const descriptor = Object.getOwnPropertyDescriptor(current, segment)\n if (descriptor === undefined || !(\"value\" in descriptor)) return undefined\n current = descriptor.value\n }\n return current\n}\n\n/**\n * The key a dispatch is *cached* under, as distinct from the plan key a node\n * is *identified* by.\n *\n * A plan key folds the resolved keys of every upstream node, transitively, so\n * an edit anywhere upstream re-keys everything below it — even when the edited\n * node's output value is byte for byte what it was before. Bazel does not work\n * that way: `ActionCacheChecker` keys an action by the *content* of its\n * inputs, so an unchanged output stops invalidation dead. The file channel in\n * flows already had that property through the measured boundary digests; the\n * JSON value channel did not, and this is what gives it one.\n *\n * The derivation folds the node's OWN material — body, version, effects,\n * placement, layers, capabilities — and never an upstream key. Each material\n * input contributes content instead: a `Literal` its value, a `Ref` the digest\n * of the settled result of `from` projected along `path`, and a `Pending`\n * nothing beyond its tag. The measured hermetic boundary is folded unchanged.\n *\n * `results` must hold every dependency the material names. The scheduler's\n * halt rule guarantees it: a dependent of failed or skipped work never\n * dispatches, so a `Ref` always resolves against a success.\n *\n * @since 0.1.0\n * @category constructors\n * @slop\n */\nexport const dispatchIdentity = (options: {\n readonly material: KeyMaterial.KeyMaterial\n /** The settled output value of each dependency, by node id. */\n readonly results: Readonly<Record<string, unknown>>\n readonly hermetic: NonNullable<ContentIdentity[\"hermetic\"]>\n /** The engine-resolved execution environment this dispatch runs under. */\n readonly environment?: EnvironmentIdentity | undefined\n /** Reuses projected-value digests while the corresponding settled values remain immutable. */\n readonly digestMemo?: DigestMemo | undefined\n}): Effect.Effect<StepKey, KeyMaterialError | Schema.SchemaError, Crypto.Crypto> =>\n Effect.gen(function*() {\n const material = options.material\n if (material.kind !== \"sealed\") {\n return yield* new KeyMaterialError({\n code: \"non_content_material\",\n message: `Cannot create a dispatch key for ${material.kind} material`\n })\n }\n const environment = options.environment === undefined ? undefined : yield* decodeEnvironment(options.environment)\n const inputs = yield* resolveInputs(material, (reference) =>\n reference._tag === \"Pending\"\n ? Effect.succeed(orderingOnly)\n : Effect.flatMap(ownDataProperty(options.results, reference.from, \"Settled result\"), (settled) => {\n const compute = decodeKey({ kind: \"input-value\", value: project(settled, reference.path) })\n return options.digestMemo === undefined\n ? compute\n : options.digestMemo.digest(reference.from, reference.path, compute)\n }))\n return yield* content({\n body: materialBody(material),\n inputs,\n layers: material.layers,\n capabilities: { declared: material.capabilities },\n environment,\n hermetic: options.hermetic\n })\n })\n"]}