@entifix/workflow 0.0.0-stage → 0.12.1

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 (39) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +24 -2
  3. package/dist/engine/make-flow-engine.d.ts +23 -0
  4. package/dist/engine/make-flow-engine.d.ts.map +1 -0
  5. package/dist/engine/make-flow-engine.js +97 -0
  6. package/dist/engine/make-flow-engine.js.map +1 -0
  7. package/dist/index.d.ts +4 -0
  8. package/dist/index.d.ts.map +1 -0
  9. package/dist/index.js +5 -0
  10. package/dist/index.js.map +1 -0
  11. package/dist/interpreter/slip-workflow.d.ts +114 -0
  12. package/dist/interpreter/slip-workflow.d.ts.map +1 -0
  13. package/dist/interpreter/slip-workflow.js +316 -0
  14. package/dist/interpreter/slip-workflow.js.map +1 -0
  15. package/dist/postgres/index.d.ts +9 -0
  16. package/dist/postgres/index.d.ts.map +1 -0
  17. package/dist/postgres/index.js +9 -0
  18. package/dist/postgres/index.js.map +1 -0
  19. package/dist/postgres/single-runner.d.ts +9 -0
  20. package/dist/postgres/single-runner.d.ts.map +1 -0
  21. package/dist/postgres/single-runner.js +13 -0
  22. package/dist/postgres/single-runner.js.map +1 -0
  23. package/dist/postgres/sql-flow-status-store.d.ts +14 -0
  24. package/dist/postgres/sql-flow-status-store.d.ts.map +1 -0
  25. package/dist/postgres/sql-flow-status-store.js +68 -0
  26. package/dist/postgres/sql-flow-status-store.js.map +1 -0
  27. package/dist/socket-runner/index.d.ts +2 -0
  28. package/dist/socket-runner/index.d.ts.map +1 -0
  29. package/dist/socket-runner/index.js +3 -0
  30. package/dist/socket-runner/index.js.map +1 -0
  31. package/dist/socket-runner/socket-runner.d.ts +24 -0
  32. package/dist/socket-runner/socket-runner.d.ts.map +1 -0
  33. package/dist/socket-runner/socket-runner.js +20 -0
  34. package/dist/socket-runner/socket-runner.js.map +1 -0
  35. package/dist/status/flow-status-store.d.ts +59 -0
  36. package/dist/status/flow-status-store.d.ts.map +1 -0
  37. package/dist/status/flow-status-store.js +50 -0
  38. package/dist/status/flow-status-store.js.map +1 -0
  39. package/package.json +109 -3
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 r10c Technologies
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,3 +1,25 @@
1
- # Temporary Holding Version
1
+ # @entifix/workflow
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ Durable flows. A flow is a pinned routing slip, and this package interprets it on Effect Workflow behind the `FlowEngineTag` port from `@entifix/transactions`: each step an Activity keyed `<flowId>:<step>`, a refusal before the commit point compensated in reverse, a failure after it suspended and resumed, and a `wait` step parked on a durable deferred its signal completes.
4
+
5
+ `effect/workflow` and `effect/cluster` are imported here and nowhere else in entifix — their APIs are unstable, and the chaos suite pins what this package relies on.
6
+
7
+ ## Install
8
+
9
+ ```sh
10
+ pnpm add @entifix/workflow effect
11
+ # a deployment of several runners:
12
+ pnpm add @effect/platform-node
13
+ ```
14
+
15
+ ## Entry points
16
+
17
+ | Import | What it holds |
18
+ | --------------------------------- | ---------------------------------------------------------------------------------------------------------------------- |
19
+ | `@entifix/workflow` | `FlowEngineLayer`, `makeFlowEngine`, `SlipWorkflow`, `interpretSlip`, `FlowStatusStoreTag`, the in-memory status store |
20
+ | `@entifix/workflow/postgres` | `SingleRunnerFlowEngineLayer` and the SQL status store, over the host's `SqlClient` |
21
+ | `@entifix/workflow/socket-runner` | `SocketRunnerFlowEngineLayer`, one runner among several; needs `@effect/platform-node` |
22
+
23
+ ---
24
+
25
+ Tier 2 (adapters) of entifix — a package depends only on its own tier or below. See [the tiers](https://github.com/r10c-technologies/entifix#the-tiers-and-what-you-are-allowed-to-install). MIT licensed.
@@ -0,0 +1,23 @@
1
+ import { type FlowEngine, FlowEngineTag } from '@entifix/transactions';
2
+ import { Effect, Layer } from 'effect';
3
+ import { WorkflowEngine } from 'effect/workflow';
4
+ import { type InterpreterOptions } from '../interpreter/slip-workflow.js';
5
+ import { FlowStatusStoreTag } from '../status/flow-status-store.js';
6
+ /**
7
+ * The flow engine port over Effect Workflow
8
+ * ([ADR 0016](../../../../../docs/adr/0016-a-flow-engine-port-and-a-durable-workflow-adapter.md)).
9
+ * A start records the flow under its key and executes the slip detached — it
10
+ * answers the flow id, never the outcome, which arrives as `flow.*` events and
11
+ * in the status record. A signal is accepted only by a flow parked on exactly
12
+ * that wait.
13
+ */
14
+ export declare const makeFlowEngine: Effect.Effect<FlowEngine, never, FlowStatusStoreTag | WorkflowEngine.WorkflowEngine>;
15
+ /**
16
+ * The flow engine with the interpreter registered. Needs a workflow engine —
17
+ * the in-memory one, or the cluster engine over Postgres from
18
+ * `@entifix/workflow/postgres` — a status store, a participant client, the
19
+ * outbox its events go through, and the breaker, bulkhead and retry budget
20
+ * every call runs under.
21
+ */
22
+ export declare const FlowEngineLayer: (options: InterpreterOptions) => Layer.Layer<FlowEngineTag, never, import("@entifix/transactions").OutboxTag | import("@entifix/transactions").BulkheadTag | import("@entifix/transactions").CircuitBreakerTag | import("@entifix/transactions").ParticipantClientTag | import("@entifix/transactions").RetryBudgetTag | FlowStatusStoreTag | WorkflowEngine.WorkflowEngine>;
23
+ //# sourceMappingURL=make-flow-engine.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"make-flow-engine.d.ts","sourceRoot":"","sources":["../../src/engine/make-flow-engine.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,UAAU,EACf,aAAa,EAGd,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAW,MAAM,EAAE,KAAK,EAAU,MAAM,QAAQ,CAAC;AACxD,OAAO,EAAmB,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAElE,OAAO,EACL,KAAK,kBAAkB,EAIxB,MAAM,iCAAiC,CAAC;AAEzC,OAAO,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAC;AAEpE;;;;;;;GAOG;AACH,eAAO,MAAM,cAAc,sFAmFzB,CAAC;AAEH;;;;;;GAMG;AACH,eAAO,MAAM,eAAe,GAAI,SAAS,kBAAkB,gVAGxD,CAAC"}
@@ -0,0 +1,97 @@
1
+ import { _ as _extends } from "@swc/helpers/_/_extends";
2
+ import { FlowEngineTag, FlowNotFound, FlowSignalRejected } from '@entifix/transactions';
3
+ import { Context, Effect, Layer, Option } from 'effect';
4
+ import { DurableDeferred } from 'effect/workflow';
5
+ import { SlipWorkflow, SlipWorkflowLayer, waitFor } from '../interpreter/slip-workflow.js';
6
+ import { FlowStatusStoreTag } from '../status/flow-status-store.js';
7
+ /**
8
+ * The flow engine port over Effect Workflow
9
+ * ([ADR 0016](../../../../../docs/adr/0016-a-flow-engine-port-and-a-durable-workflow-adapter.md)).
10
+ * A start records the flow under its key and executes the slip detached — it
11
+ * answers the flow id, never the outcome, which arrives as `flow.*` events and
12
+ * in the status record. A signal is accepted only by a flow parked on exactly
13
+ * that wait.
14
+ */ export const makeFlowEngine = Effect.gen(function*() {
15
+ const context = yield* Effect.context();
16
+ const store = Context.get(context, FlowStatusStoreTag);
17
+ const within = (effect)=>Effect.provideContext(effect, context);
18
+ const known = (flowId)=>Effect.flatMap(store.find(flowId), (found)=>Option.match(found, {
19
+ onNone: ()=>Effect.fail(new FlowNotFound({
20
+ flowId
21
+ })),
22
+ onSome: Effect.succeed
23
+ }));
24
+ /** Completes the wait `record` is parked on, if `token` names it. */ const complete = (token, outcome)=>(record)=>Effect.gen(function*() {
25
+ if (record.state !== 'waiting' || record.waitingFor !== token) return yield* Effect.fail(new FlowSignalRejected({
26
+ flowId: record.flowId,
27
+ token
28
+ }));
29
+ const deferred = waitFor(token);
30
+ yield* within(DurableDeferred.succeed(deferred, {
31
+ token: DurableDeferred.tokenFromExecutionId(deferred, {
32
+ workflow: SlipWorkflow,
33
+ executionId: record.executionId
34
+ }),
35
+ value: outcome
36
+ }));
37
+ // Recorded here as well as by the flow, so a second signal racing the
38
+ // resume is refused rather than completing the wait twice.
39
+ yield* store.update(record.flowId, {
40
+ state: 'running',
41
+ step: token
42
+ });
43
+ });
44
+ const engine = {
45
+ start: (slip, idempotencyKey)=>Effect.gen(function*() {
46
+ const payload = {
47
+ key: idempotencyKey,
48
+ slip
49
+ };
50
+ const executionId = yield* SlipWorkflow.executionId(payload);
51
+ const record = yield* store.register(idempotencyKey, {
52
+ flowId: slip.flowId,
53
+ executionId,
54
+ state: 'running'
55
+ });
56
+ if (record.executionId === executionId && record.flowId === slip.flowId) yield* within(SlipWorkflow.execute(payload, {
57
+ discard: true
58
+ }));
59
+ return {
60
+ flowId: record.flowId
61
+ };
62
+ }),
63
+ status: (flowId)=>Effect.map(known(flowId), (record)=>_extends({
64
+ flowId: record.flowId,
65
+ state: record.state
66
+ }, record.step === undefined ? {} : {
67
+ step: record.step
68
+ })),
69
+ signal: (flowId, token, outcome)=>Effect.flatMap(known(flowId), complete(token, outcome)),
70
+ signalCorrelated: (correlation, token, outcome)=>Effect.gen(function*() {
71
+ const found = yield* store.findByCorrelation(correlation);
72
+ if (Option.isNone(found)) return yield* Effect.fail(new FlowNotFound({
73
+ flowId: correlation
74
+ }));
75
+ return yield* complete(token, outcome)(found.value);
76
+ }),
77
+ interrupt: (flowId)=>Effect.gen(function*() {
78
+ const record = yield* known(flowId);
79
+ yield* within(SlipWorkflow.interrupt(record.executionId));
80
+ yield* store.update(flowId, _extends({
81
+ state: 'interrupted'
82
+ }, record.step === undefined ? {} : {
83
+ step: record.step
84
+ }));
85
+ })
86
+ };
87
+ return engine;
88
+ });
89
+ /**
90
+ * The flow engine with the interpreter registered. Needs a workflow engine —
91
+ * the in-memory one, or the cluster engine over Postgres from
92
+ * `@entifix/workflow/postgres` — a status store, a participant client, the
93
+ * outbox its events go through, and the breaker, bulkhead and retry budget
94
+ * every call runs under.
95
+ */ export const FlowEngineLayer = (options)=>Layer.effect(FlowEngineTag, makeFlowEngine).pipe(Layer.provideMerge(SlipWorkflowLayer(options)));
96
+
97
+ //# sourceMappingURL=make-flow-engine.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/engine/make-flow-engine.ts"],"sourcesContent":["import {\n type FlowEngine,\n FlowEngineTag,\n FlowNotFound,\n FlowSignalRejected,\n} from '@entifix/transactions';\nimport { Context, Effect, Layer, Option } from 'effect';\nimport { DurableDeferred, WorkflowEngine } from 'effect/workflow';\n\nimport {\n type InterpreterOptions,\n SlipWorkflow,\n SlipWorkflowLayer,\n waitFor,\n} from '../interpreter/slip-workflow.js';\nimport type { FlowRecord } from '../status/flow-status-store.js';\nimport { FlowStatusStoreTag } from '../status/flow-status-store.js';\n\n/**\n * The flow engine port over Effect Workflow\n * ([ADR 0016](../../../../../docs/adr/0016-a-flow-engine-port-and-a-durable-workflow-adapter.md)).\n * A start records the flow under its key and executes the slip detached — it\n * answers the flow id, never the outcome, which arrives as `flow.*` events and\n * in the status record. A signal is accepted only by a flow parked on exactly\n * that wait.\n */\nexport const makeFlowEngine = Effect.gen(function* () {\n const context = yield* Effect.context<\n WorkflowEngine.WorkflowEngine | FlowStatusStoreTag\n >();\n const store = Context.get(context, FlowStatusStoreTag);\n const within = <A, E>(\n effect: Effect.Effect<A, E, WorkflowEngine.WorkflowEngine>,\n ) => Effect.provideContext(effect, context);\n\n const known = (flowId: string) =>\n Effect.flatMap(store.find(flowId), found =>\n Option.match(found, {\n onNone: () => Effect.fail(new FlowNotFound({ flowId })),\n onSome: Effect.succeed,\n }),\n );\n\n /** Completes the wait `record` is parked on, if `token` names it. */\n const complete = (token: string, outcome: unknown) => (record: FlowRecord) =>\n Effect.gen(function* () {\n if (record.state !== 'waiting' || record.waitingFor !== token)\n return yield* Effect.fail(\n new FlowSignalRejected({ flowId: record.flowId, token }),\n );\n const deferred = waitFor(token);\n yield* within(\n DurableDeferred.succeed(deferred, {\n token: DurableDeferred.tokenFromExecutionId(deferred, {\n workflow: SlipWorkflow,\n executionId: record.executionId,\n }),\n value: outcome,\n }),\n );\n // Recorded here as well as by the flow, so a second signal racing the\n // resume is refused rather than completing the wait twice.\n yield* store.update(record.flowId, { state: 'running', step: token });\n });\n\n const engine: FlowEngine = {\n start: (slip, idempotencyKey) =>\n Effect.gen(function* () {\n const payload = { key: idempotencyKey, slip };\n const executionId = yield* SlipWorkflow.executionId(payload);\n const record = yield* store.register(idempotencyKey, {\n flowId: slip.flowId,\n executionId,\n state: 'running',\n });\n if (record.executionId === executionId && record.flowId === slip.flowId)\n yield* within(SlipWorkflow.execute(payload, { discard: true }));\n return { flowId: record.flowId };\n }),\n\n status: flowId =>\n Effect.map(known(flowId), record => ({\n flowId: record.flowId,\n state: record.state,\n ...(record.step === undefined ? {} : { step: record.step }),\n })),\n\n signal: (flowId, token, outcome) =>\n Effect.flatMap(known(flowId), complete(token, outcome)),\n\n signalCorrelated: (correlation, token, outcome) =>\n Effect.gen(function* () {\n const found = yield* store.findByCorrelation(correlation);\n if (Option.isNone(found))\n return yield* Effect.fail(new FlowNotFound({ flowId: correlation }));\n return yield* complete(token, outcome)(found.value);\n }),\n\n interrupt: flowId =>\n Effect.gen(function* () {\n const record = yield* known(flowId);\n yield* within(SlipWorkflow.interrupt(record.executionId));\n yield* store.update(flowId, {\n state: 'interrupted',\n ...(record.step === undefined ? {} : { step: record.step }),\n });\n }),\n };\n return engine;\n});\n\n/**\n * The flow engine with the interpreter registered. Needs a workflow engine —\n * the in-memory one, or the cluster engine over Postgres from\n * `@entifix/workflow/postgres` — a status store, a participant client, the\n * outbox its events go through, and the breaker, bulkhead and retry budget\n * every call runs under.\n */\nexport const FlowEngineLayer = (options: InterpreterOptions) =>\n Layer.effect(FlowEngineTag, makeFlowEngine).pipe(\n Layer.provideMerge(SlipWorkflowLayer(options)),\n );\n"],"names":["FlowEngineTag","FlowNotFound","FlowSignalRejected","Context","Effect","Layer","Option","DurableDeferred","SlipWorkflow","SlipWorkflowLayer","waitFor","FlowStatusStoreTag","makeFlowEngine","gen","context","store","get","within","effect","provideContext","known","flowId","flatMap","find","found","match","onNone","fail","onSome","succeed","complete","token","outcome","record","state","waitingFor","deferred","tokenFromExecutionId","workflow","executionId","value","update","step","engine","start","slip","idempotencyKey","payload","key","register","execute","discard","status","map","undefined","signal","signalCorrelated","correlation","findByCorrelation","isNone","interrupt","FlowEngineLayer","options","pipe","provideMerge"],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ export * from './engine/make-flow-engine.js';
2
+ export * from './interpreter/slip-workflow.js';
3
+ export * from './status/flow-status-store.js';
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,8BAA8B,CAAC;AAC7C,cAAc,gCAAgC,CAAC;AAC/C,cAAc,+BAA+B,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,5 @@
1
+ export * from './engine/make-flow-engine.js';
2
+ export * from './interpreter/slip-workflow.js';
3
+ export * from './status/flow-status-store.js';
4
+
5
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts"],"sourcesContent":["export * from './engine/make-flow-engine.js';\nexport * from './interpreter/slip-workflow.js';\nexport * from './status/flow-status-store.js';\n"],"names":[],"mappings":"AAAA,cAAc,+BAA+B;AAC7C,cAAc,iCAAiC;AAC/C,cAAc,gCAAgC"}
@@ -0,0 +1,114 @@
1
+ import { type FragmentCatalog, Slip } from '@entifix/business/flow';
2
+ import { type EntifixFailure } from '@entifix/core';
3
+ import { BulkheadTag, CircuitBreakerTag, OutboxTag, ParticipantClientTag } from '@entifix/transactions';
4
+ import { Context, Effect, Schema } from 'effect';
5
+ import { DurableDeferred, Workflow } from 'effect/workflow';
6
+ import { FlowStatusStoreTag } from '../status/flow-status-store.js';
7
+ /**
8
+ * A failure as an Activity journals it: the problem body on the way in, the
9
+ * failure its code names on the way out, so a resumed flow sees the typed
10
+ * refusal a participant sent rather than a cast.
11
+ */
12
+ export declare const JournaledFailure: Schema.Codec<EntifixFailure, unknown>;
13
+ /**
14
+ * How a flow ended, as the workflow's own result: every step ran, or a
15
+ * refusal before the commit point was undone, or an undoing itself failed and
16
+ * the flow stopped where it was — which a person has to look at.
17
+ */
18
+ export declare const FlowOutcome: Schema.Literals<readonly ["completed", "compensated", "failed"]>;
19
+ declare const FlowWaitTimedOut_base: Schema.Class<FlowWaitTimedOut, Schema.TaggedStruct<"FlowWaitTimedOut", {
20
+ readonly step: Schema.String;
21
+ }>, import("effect/Cause").YieldableError & import("@entifix/core").FailureFacts<"flowWaitTimedOut", "timeout">>;
22
+ /** A durable wait that outlived its timeout before its signal came. */
23
+ export declare class FlowWaitTimedOut extends FlowWaitTimedOut_base {
24
+ }
25
+ /** How long a flow gives each participant call, and each step as a whole. */
26
+ export interface FlowDials {
27
+ /** One attempt at a call. */
28
+ readonly attemptTimeoutMs: number;
29
+ /** Every attempt at a step together, retries included. */
30
+ readonly stepTimeoutMs: number;
31
+ /** Segments of one stage run at once. */
32
+ readonly concurrency: number;
33
+ }
34
+ export declare const DEFAULT_FLOW_DIALS: FlowDials;
35
+ /** What the interpreter runs a slip with: the catalog, who announces, the dials. */
36
+ export interface InterpreterOptions {
37
+ readonly catalog: FragmentCatalog;
38
+ /** The slice the `flow.*` events are announced from. */
39
+ readonly source: string;
40
+ readonly dials?: Partial<FlowDials>;
41
+ /**
42
+ * One participant's own attempt and step bounds, over `dials` — the same
43
+ * shape the breaker's `dialsFor` and the bulkhead's `permitsFor` take, so a
44
+ * participant's dials are one row set however many guards read them.
45
+ */
46
+ readonly dialsFor?: (participant: string) => Partial<Omit<FlowDials, 'concurrency'>> | undefined;
47
+ }
48
+ declare const InterpreterOptionsTag_base: Context.ServiceClass<InterpreterOptionsTag, "@entifix/workflow/InterpreterOptions", InterpreterOptions>;
49
+ /**
50
+ * The interpreter's options, provided to the workflow it is registered with —
51
+ * the payload is the slip; the catalog and dials are the deployment's.
52
+ */
53
+ export declare class InterpreterOptionsTag extends InterpreterOptionsTag_base {
54
+ }
55
+ /**
56
+ * The one workflow every flow runs as: its payload is the pinned slip and the
57
+ * idempotency key that started it
58
+ * ([ADR 0016](../../../../../docs/adr/0016-a-flow-engine-port-and-a-durable-workflow-adapter.md)).
59
+ * The execution id derives from the key, so the same key is the same flow.
60
+ *
61
+ * A flow suspended past its commit point is resumed on the retry schedule:
62
+ * a participant that comes back gets the step again, idempotently.
63
+ */
64
+ export declare const SlipWorkflow: Workflow.Workflow<"entifix/slip", Schema.Struct<{
65
+ key: Schema.String;
66
+ slip: Schema.Struct<{
67
+ readonly slipVersion: Schema.Literal<1>;
68
+ readonly flowId: Schema.String;
69
+ readonly recipe: Schema.String;
70
+ readonly requiresCommitPoint: Schema.optionalKey<Schema.Boolean>;
71
+ readonly stages: Schema.$Array<Schema.Struct<{
72
+ readonly name: Schema.String;
73
+ readonly steps: Schema.$Array<Schema.Struct<{
74
+ readonly ref: Schema.String;
75
+ readonly step: Schema.String;
76
+ readonly cardinality: Schema.Literals<readonly ["one", "perVendor", "perLine"]>;
77
+ readonly segment: Schema.optionalKey<Schema.Struct<{
78
+ readonly vendor: Schema.optionalKey<Schema.String>;
79
+ readonly paymentMethod: Schema.optionalKey<Schema.String>;
80
+ }>>;
81
+ readonly participant: Schema.optionalKey<Schema.String>;
82
+ readonly call: Schema.optionalKey<Schema.Struct<{
83
+ readonly method: Schema.Literals<readonly ["GET", "POST", "PUT", "PATCH", "DELETE"]>;
84
+ readonly path: Schema.String;
85
+ }>>;
86
+ readonly compensation: Schema.optionalKey<Schema.Struct<{
87
+ readonly method: Schema.Literals<readonly ["GET", "POST", "PUT", "PATCH", "DELETE"]>;
88
+ readonly path: Schema.String;
89
+ }>>;
90
+ readonly parameters: Schema.optionalKey<Schema.$Record<Schema.String, Schema.Unknown>>;
91
+ }>>;
92
+ }>>;
93
+ readonly resolution: Schema.$Array<Schema.Struct<{
94
+ readonly useCase: Schema.String;
95
+ readonly variant: Schema.String;
96
+ readonly rule: Schema.Number;
97
+ }>>;
98
+ readonly composedAt: Schema.String;
99
+ readonly audience: Schema.optionalKey<Schema.$Array<Schema.Struct<{
100
+ readonly kind: Schema.Literals<readonly ["organization", "party", "flow"]>;
101
+ readonly id: Schema.String;
102
+ readonly digest: Schema.optionalKey<Schema.String>;
103
+ }>>>;
104
+ }>;
105
+ }>, Schema.Literals<readonly ["completed", "compensated", "failed"]>, Schema.Codec<EntifixFailure<string, string, import("@entifix/core").FailureCategory>, unknown, never, never>>;
106
+ /** The durable wait a `wait` step parks on, addressed by the step's name. */
107
+ export declare const waitFor: (step: string) => DurableDeferred.DurableDeferred<Schema.Unknown, Schema.Never>;
108
+ /** Every `slipVersion` the interpreter walks — each must have a journal. */
109
+ export declare const interpretedSlipVersions: readonly number[];
110
+ export declare const interpretSlip: (slip: Slip) => Effect.Effect<"completed" | "failed" | "compensated", EntifixFailure<string, string, import("@entifix/core").FailureCategory>, OutboxTag | BulkheadTag | CircuitBreakerTag | ParticipantClientTag | import("@entifix/transactions").RetryBudgetTag | FlowStatusStoreTag | InterpreterOptionsTag | import("effect/workflow/WorkflowEngine").WorkflowInstance | import("effect/workflow/WorkflowEngine").WorkflowEngine>;
111
+ /** The interpreter registered with the workflow engine, with its options. */
112
+ export declare const SlipWorkflowLayer: (options: InterpreterOptions) => import("effect/Layer").Layer<never, never, OutboxTag | BulkheadTag | CircuitBreakerTag | ParticipantClientTag | import("@entifix/transactions").RetryBudgetTag | FlowStatusStoreTag | import("effect/workflow/WorkflowEngine").WorkflowEngine>;
113
+ export {};
114
+ //# sourceMappingURL=slip-workflow.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"slip-workflow.d.ts","sourceRoot":"","sources":["../../src/interpreter/slip-workflow.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,eAAe,EACpB,IAAI,EAGL,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAEL,KAAK,cAAc,EAMpB,MAAM,eAAe,CAAC;AACvB,OAAO,EACL,WAAW,EACX,iBAAiB,EAIjB,SAAS,EACT,oBAAoB,EACrB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EACL,OAAO,EACP,MAAM,EAIN,MAAM,EAEP,MAAM,QAAQ,CAAC;AAChB,OAAO,EAGL,eAAe,EACf,QAAQ,EACT,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EAGL,kBAAkB,EACnB,MAAM,gCAAgC,CAAC;AAExC;;;;GAIG;AACH,eAAO,MAAM,gBAAgB,EAAE,MAAM,CAAC,KAAK,CAAC,cAAc,EAAE,OAAO,CAShE,CAAC;AAEJ;;;;GAIG;AACH,eAAO,MAAM,WAAW,kEAItB,CAAC;;;;AAEH,uEAAuE;AACvE,qBAAa,gBAAiB,SAAQ,qBAKrC;CAAG;AAEJ,6EAA6E;AAC7E,MAAM,WAAW,SAAS;IACxB,6BAA6B;IAC7B,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;IAClC,0DAA0D;IAC1D,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,yCAAyC;IACzC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;CAC9B;AAED,eAAO,MAAM,kBAAkB,EAAE,SAIhC,CAAC;AAEF,oFAAoF;AACpF,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,OAAO,EAAE,eAAe,CAAC;IAClC,wDAAwD;IACxD,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC,SAAS,CAAC,CAAC;IACpC;;;;OAIG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAClB,WAAW,EAAE,MAAM,KAChB,OAAO,CAAC,IAAI,CAAC,SAAS,EAAE,aAAa,CAAC,CAAC,GAAG,SAAS,CAAC;CAC1D;;AAED;;;GAGG;AACH,qBAAa,qBAAsB,SAAQ,0BAGA;CAAG;AAE9C;;;;;;;;GAQG;AACH,eAAO,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;mLAYvB,CAAC;AAEH,6EAA6E;AAC7E,eAAO,MAAM,OAAO,GAAI,MAAM,MAAM,kEAC+B,CAAC;AA0TpE,4EAA4E;AAC5E,eAAO,MAAM,uBAAuB,EAAE,SAAS,MAAM,EACd,CAAC;AAExC,eAAO,MAAM,aAAa,GAAI,MAAM,IAAI,2ZACF,CAAC;AAEvC,6EAA6E;AAC7E,eAAO,MAAM,iBAAiB,GAAI,SAAS,kBAAkB,mPAK1D,CAAC"}