@particle-academy/fancy-flow 0.29.0 → 0.30.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,45 @@
1
+ import { N as NodeKindDefinition } from './types-DEmDSByY.cjs';
2
+
3
+ /**
4
+ * registerNodeKind — install a node kind in the global registry. Returns
5
+ * an `unregister` function. Calling with the same name replaces the prior
6
+ * registration (handy for HMR).
7
+ *
8
+ * A kind's `name` is its CANONICAL id and is what gets written into saved
9
+ * documents. Publish namespaced (`@fancy/llm_branch`, `@acme/salesforce_upsert`)
10
+ * and list any previous bare names in `aliases`, so graphs saved before the
11
+ * rename keep resolving.
12
+ */
13
+ declare function registerNodeKind<TC = any, TI = any, TO = any>(definition: NodeKindDefinition<TC, TI, TO>): () => void;
14
+ /**
15
+ * Resolve any id — canonical or alias — to the canonical one, or null.
16
+ *
17
+ * `kind` is persisted inside every saved graph, so a bare name that two
18
+ * packages could both claim is unfixable after the fact: the ambiguous string
19
+ * is already in the document. Canonical ids are namespaced; aliases exist so
20
+ * documents written before namespacing keep opening.
21
+ */
22
+ declare function resolveKindId(id: string): string | null;
23
+ /** Get a single kind by canonical id or alias, or null. */
24
+ declare function getNodeKind(name: string): NodeKindDefinition | null;
25
+ /** Every id a kind answers to — canonical first. Used to key node-type maps. */
26
+ declare function kindIds(kind: NodeKindDefinition): string[];
27
+ /** List every registered kind, optionally filtered by category. */
28
+ declare function listNodeKinds(category?: string): NodeKindDefinition[];
29
+ /** Subscribe to registry changes. Returns an unsubscribe function. */
30
+ declare function onNodeKindsChanged(listener: () => void): () => void;
31
+ /** Fill in defaults from a kind's configSchema for newly-created nodes. */
32
+ declare function defaultConfigFor(kind: NodeKindDefinition): Record<string, unknown>;
33
+ /**
34
+ * Validate a config object against a kind's schema. Returns an array of
35
+ * issues (empty = valid). Validation is intentionally light — type
36
+ * coercion + required-field checks. Hosts can layer Zod / Ajv on top.
37
+ */
38
+ declare function validateConfig(kind: NodeKindDefinition, config: Record<string, unknown>): Array<{
39
+ key: string;
40
+ message: string;
41
+ }>;
42
+ /** Default accents per category. */
43
+ declare function categoryAccent(category: string): string;
44
+
45
+ export { resolveKindId as a, categoryAccent as c, defaultConfigFor as d, getNodeKind as g, kindIds as k, listNodeKinds as l, onNodeKindsChanged as o, registerNodeKind as r, validateConfig as v };
@@ -1,7 +1,101 @@
1
1
  import { ReactNode, ComponentType } from 'react';
2
2
  import { NodeProps } from '@xyflow/react';
3
3
  import { P as PortDescriptor, N as NodeExecutor, a as FlowNode } from './types-CMSrWVYM.js';
4
- import { P as PauseAwaiting } from './pause-9iT4tCEV.js';
4
+
5
+ /**
6
+ * The human-pause contract.
7
+ *
8
+ * A workflow that waits for a person is not an error, but it travels the same
9
+ * channel as one: the executor aborts, the engine records a reason string, and
10
+ * the durable runner decides whether that string meant "failed" or "waiting".
11
+ *
12
+ * That seam existed before this module, as two `str_starts_with` checks in the
13
+ * Laravel run job against constants owned by two BUILTIN executors. It worked,
14
+ * and it was invisible: a third-party human-input node had no way to announce
15
+ * that it pauses, and nothing stopped a refactor from removing the mechanism
16
+ * out from under published packages. Reported by the MOIC Suite consumer, who
17
+ * needed exactly that and had to reach for a private constant to get it.
18
+ *
19
+ * So the encoding is now public, typed, and versioned by prefix rather than
20
+ * implied. The wire format stays a plain string on purpose — it survives the
21
+ * existing abort → `RunResult.error` path unchanged, crosses a queue boundary,
22
+ * and decodes identically in PHP, none of which a thrown class would do.
23
+ *
24
+ * @see decodePause — the one function a durable runner needs.
25
+ */
26
+ /**
27
+ * What the run is waiting for.
28
+ *
29
+ * `approval` and `input` are the shapes both runtimes ship. The type stays open
30
+ * because the whole point is that a marketplace node can define its own —
31
+ * a signature step, a payment confirmation, a review queue — and a runner that
32
+ * does not recognise one should report it rather than guess.
33
+ */
34
+ type PauseAwaiting = "approval" | "input" | (string & {});
35
+ /** A run halted, waiting for a person. */
36
+ type PauseSignal = {
37
+ /** The node that paused — where a submission gets injected on resume. */
38
+ nodeId: string;
39
+ awaiting: PauseAwaiting;
40
+ /**
41
+ * Kind-supplied context for whoever renders the wait — a form schema, the
42
+ * question being asked, a diff to approve. Must be JSON-serializable: it
43
+ * crosses a queue boundary and, for durable runs, a database column.
44
+ */
45
+ detail?: unknown;
46
+ };
47
+ /** Marks a reason string as a pause rather than a failure. */
48
+ declare const PAUSE_PREFIX = "fancy-flow:pause:";
49
+ /**
50
+ * Reason prefixes shipped before this contract, kept decodable forever.
51
+ *
52
+ * These are what `DurableApprovalExecutor` and `DurableUserInputExecutor`
53
+ * emitted, and they are written into the `error` column of every run that
54
+ * paused under an older version. Dropping them would strand those runs
55
+ * mid-flight — a resume path that only works for new runs is not a resume path.
56
+ */
57
+ declare const LEGACY_PAUSE_PREFIXES: ReadonlyArray<readonly [string, PauseAwaiting]>;
58
+ /**
59
+ * Encode a pause as the reason string an executor aborts with.
60
+ *
61
+ * The payload is JSON rather than delimited fields because a node id may
62
+ * contain a colon, and a positional encoding that breaks on user data is the
63
+ * kind of bug that only shows up in someone else's graph.
64
+ */
65
+ declare function encodePause(signal: PauseSignal): string;
66
+ /**
67
+ * Decode a run's error reason into a pause, or null if it was a real failure.
68
+ *
69
+ * This is the whole contract from a runner's side: call it on `result.error`,
70
+ * and if it returns non-null, persist the run as waiting on `signal.nodeId`
71
+ * instead of failing it. Accepts the legacy prefixes, so a runner written
72
+ * against this handles runs that paused under an older version.
73
+ */
74
+ declare function decodePause(reason: string | null | undefined): PauseSignal | null;
75
+ /** True when a run's error reason is actually a pause. */
76
+ declare function isPause(reason: string | null | undefined): boolean;
77
+ /**
78
+ * Abort the current node as a pause.
79
+ *
80
+ * Called from inside an executor with its own context. Node authors should
81
+ * reach for this rather than hand-encoding a reason, so the format stays ours
82
+ * to change:
83
+ *
84
+ * ```ts
85
+ * const values = ctx.inputs.values;
86
+ * if (values === undefined) pauseForHuman(ctx, "input", { fields });
87
+ * return values;
88
+ * ```
89
+ *
90
+ * Note the `undefined` check — an empty submission (`{}`) is a real answer and
91
+ * must resume. Truthiness here pauses forever on an empty form.
92
+ */
93
+ declare function pauseForHuman(ctx: {
94
+ node: {
95
+ id: string;
96
+ };
97
+ abort: (reason?: string) => never;
98
+ }, awaiting: PauseAwaiting, detail?: unknown): never;
5
99
 
6
100
  /** Categories used by the palette for grouping. */
7
101
  type NodeCategory = "trigger" | "logic" | "data" | "ai" | "io" | "human" | "output" | "layout" | "annotation" | "custom";
@@ -280,4 +374,4 @@ type NodeKindDefinition<TConfig = Record<string, unknown>, TIn = any, TOut = any
280
374
  reactive?: boolean;
281
375
  };
282
376
 
283
- export type { ConfigField as C, DocumentConfigField as D, ExpressionConfigField as E, JsonConfigField as J, KeyValueConfigField as K, NodeCategory as N, PortSpec as P, RenderBodyContext as R, SelectConfigField as S, TextConfigField as T, NodeKindDefinition as a, CredentialConfigField as b, NumberConfigField as c, RepeaterConfigField as d, RepeaterRowField as e, SwitchConfigField as f, TextareaConfigField as g };
377
+ export { type ConfigField as C, type DocumentConfigField as D, type ExpressionConfigField as E, type JsonConfigField as J, type KeyValueConfigField as K, LEGACY_PAUSE_PREFIXES as L, type NodeKindDefinition as N, type PauseAwaiting as P, type RenderBodyContext as R, type SelectConfigField as S, type TextConfigField as T, type NodeCategory as a, PAUSE_PREFIX as b, type PauseSignal as c, type PortSpec as d, decodePause as e, encodePause as f, type CredentialConfigField as g, type NumberConfigField as h, isPause as i, type RepeaterConfigField as j, type RepeaterRowField as k, type SwitchConfigField as l, type TextareaConfigField as m, pauseForHuman as p };
@@ -1,7 +1,101 @@
1
1
  import { ReactNode, ComponentType } from 'react';
2
2
  import { NodeProps } from '@xyflow/react';
3
3
  import { P as PortDescriptor, N as NodeExecutor, a as FlowNode } from './types-CMSrWVYM.cjs';
4
- import { P as PauseAwaiting } from './pause-9iT4tCEV.cjs';
4
+
5
+ /**
6
+ * The human-pause contract.
7
+ *
8
+ * A workflow that waits for a person is not an error, but it travels the same
9
+ * channel as one: the executor aborts, the engine records a reason string, and
10
+ * the durable runner decides whether that string meant "failed" or "waiting".
11
+ *
12
+ * That seam existed before this module, as two `str_starts_with` checks in the
13
+ * Laravel run job against constants owned by two BUILTIN executors. It worked,
14
+ * and it was invisible: a third-party human-input node had no way to announce
15
+ * that it pauses, and nothing stopped a refactor from removing the mechanism
16
+ * out from under published packages. Reported by the MOIC Suite consumer, who
17
+ * needed exactly that and had to reach for a private constant to get it.
18
+ *
19
+ * So the encoding is now public, typed, and versioned by prefix rather than
20
+ * implied. The wire format stays a plain string on purpose — it survives the
21
+ * existing abort → `RunResult.error` path unchanged, crosses a queue boundary,
22
+ * and decodes identically in PHP, none of which a thrown class would do.
23
+ *
24
+ * @see decodePause — the one function a durable runner needs.
25
+ */
26
+ /**
27
+ * What the run is waiting for.
28
+ *
29
+ * `approval` and `input` are the shapes both runtimes ship. The type stays open
30
+ * because the whole point is that a marketplace node can define its own —
31
+ * a signature step, a payment confirmation, a review queue — and a runner that
32
+ * does not recognise one should report it rather than guess.
33
+ */
34
+ type PauseAwaiting = "approval" | "input" | (string & {});
35
+ /** A run halted, waiting for a person. */
36
+ type PauseSignal = {
37
+ /** The node that paused — where a submission gets injected on resume. */
38
+ nodeId: string;
39
+ awaiting: PauseAwaiting;
40
+ /**
41
+ * Kind-supplied context for whoever renders the wait — a form schema, the
42
+ * question being asked, a diff to approve. Must be JSON-serializable: it
43
+ * crosses a queue boundary and, for durable runs, a database column.
44
+ */
45
+ detail?: unknown;
46
+ };
47
+ /** Marks a reason string as a pause rather than a failure. */
48
+ declare const PAUSE_PREFIX = "fancy-flow:pause:";
49
+ /**
50
+ * Reason prefixes shipped before this contract, kept decodable forever.
51
+ *
52
+ * These are what `DurableApprovalExecutor` and `DurableUserInputExecutor`
53
+ * emitted, and they are written into the `error` column of every run that
54
+ * paused under an older version. Dropping them would strand those runs
55
+ * mid-flight — a resume path that only works for new runs is not a resume path.
56
+ */
57
+ declare const LEGACY_PAUSE_PREFIXES: ReadonlyArray<readonly [string, PauseAwaiting]>;
58
+ /**
59
+ * Encode a pause as the reason string an executor aborts with.
60
+ *
61
+ * The payload is JSON rather than delimited fields because a node id may
62
+ * contain a colon, and a positional encoding that breaks on user data is the
63
+ * kind of bug that only shows up in someone else's graph.
64
+ */
65
+ declare function encodePause(signal: PauseSignal): string;
66
+ /**
67
+ * Decode a run's error reason into a pause, or null if it was a real failure.
68
+ *
69
+ * This is the whole contract from a runner's side: call it on `result.error`,
70
+ * and if it returns non-null, persist the run as waiting on `signal.nodeId`
71
+ * instead of failing it. Accepts the legacy prefixes, so a runner written
72
+ * against this handles runs that paused under an older version.
73
+ */
74
+ declare function decodePause(reason: string | null | undefined): PauseSignal | null;
75
+ /** True when a run's error reason is actually a pause. */
76
+ declare function isPause(reason: string | null | undefined): boolean;
77
+ /**
78
+ * Abort the current node as a pause.
79
+ *
80
+ * Called from inside an executor with its own context. Node authors should
81
+ * reach for this rather than hand-encoding a reason, so the format stays ours
82
+ * to change:
83
+ *
84
+ * ```ts
85
+ * const values = ctx.inputs.values;
86
+ * if (values === undefined) pauseForHuman(ctx, "input", { fields });
87
+ * return values;
88
+ * ```
89
+ *
90
+ * Note the `undefined` check — an empty submission (`{}`) is a real answer and
91
+ * must resume. Truthiness here pauses forever on an empty form.
92
+ */
93
+ declare function pauseForHuman(ctx: {
94
+ node: {
95
+ id: string;
96
+ };
97
+ abort: (reason?: string) => never;
98
+ }, awaiting: PauseAwaiting, detail?: unknown): never;
5
99
 
6
100
  /** Categories used by the palette for grouping. */
7
101
  type NodeCategory = "trigger" | "logic" | "data" | "ai" | "io" | "human" | "output" | "layout" | "annotation" | "custom";
@@ -280,4 +374,4 @@ type NodeKindDefinition<TConfig = Record<string, unknown>, TIn = any, TOut = any
280
374
  reactive?: boolean;
281
375
  };
282
376
 
283
- export type { ConfigField as C, DocumentConfigField as D, ExpressionConfigField as E, JsonConfigField as J, KeyValueConfigField as K, NodeCategory as N, PortSpec as P, RenderBodyContext as R, SelectConfigField as S, TextConfigField as T, NodeKindDefinition as a, CredentialConfigField as b, NumberConfigField as c, RepeaterConfigField as d, RepeaterRowField as e, SwitchConfigField as f, TextareaConfigField as g };
377
+ export { type ConfigField as C, type DocumentConfigField as D, type ExpressionConfigField as E, type JsonConfigField as J, type KeyValueConfigField as K, LEGACY_PAUSE_PREFIXES as L, type NodeKindDefinition as N, type PauseAwaiting as P, type RenderBodyContext as R, type SelectConfigField as S, type TextConfigField as T, type NodeCategory as a, PAUSE_PREFIX as b, type PauseSignal as c, type PortSpec as d, decodePause as e, encodePause as f, type CredentialConfigField as g, type NumberConfigField as h, isPause as i, type RepeaterConfigField as j, type RepeaterRowField as k, type SwitchConfigField as l, type TextareaConfigField as m, pauseForHuman as p };
package/dist/ux.d.cts CHANGED
@@ -1,10 +1,9 @@
1
1
  import { EffectRegistry, DispatchActor } from '@particle-academy/fancy-auto-common';
2
2
  export { AutoActivityEvent } from '@particle-academy/fancy-auto-common';
3
- import { N as NodeCategory, C as ConfigField } from './types-B_pxRqfw.cjs';
3
+ import { a as NodeCategory, C as ConfigField } from './types-DEmDSByY.cjs';
4
4
  import { E as ExecutorRegistry } from './types-CMSrWVYM.cjs';
5
5
  import 'react';
6
6
  import '@xyflow/react';
7
- import './pause-9iT4tCEV.cjs';
8
7
 
9
8
  /** Per-effect presentation for the palette node kind that drives it. */
10
9
  type UxEffectMeta = {
package/dist/ux.d.ts CHANGED
@@ -1,10 +1,9 @@
1
1
  import { EffectRegistry, DispatchActor } from '@particle-academy/fancy-auto-common';
2
2
  export { AutoActivityEvent } from '@particle-academy/fancy-auto-common';
3
- import { N as NodeCategory, C as ConfigField } from './types-BGtR3k9J.js';
3
+ import { a as NodeCategory, C as ConfigField } from './types-Bj_ZHwqG.js';
4
4
  import { E as ExecutorRegistry } from './types-CMSrWVYM.js';
5
5
  import 'react';
6
6
  import '@xyflow/react';
7
- import './pause-9iT4tCEV.js';
8
7
 
9
8
  /** Per-effect presentation for the palette node kind that drives it. */
10
9
  type UxEffectMeta = {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@particle-academy/fancy-flow",
3
- "version": "0.29.0",
3
+ "version": "0.30.0",
4
4
  "description": "Workflow editor + runner. Six built-in node kits (trigger / action / decision / output / note / subgraph), tokenized theme, topological execution with per-node status. React-flow bundled; consumers npm install fancy-flow and get nothing extra.",
5
5
  "repository": {
6
6
  "type": "git",
@@ -1,96 +0,0 @@
1
- /**
2
- * The human-pause contract.
3
- *
4
- * A workflow that waits for a person is not an error, but it travels the same
5
- * channel as one: the executor aborts, the engine records a reason string, and
6
- * the durable runner decides whether that string meant "failed" or "waiting".
7
- *
8
- * That seam existed before this module, as two `str_starts_with` checks in the
9
- * Laravel run job against constants owned by two BUILTIN executors. It worked,
10
- * and it was invisible: a third-party human-input node had no way to announce
11
- * that it pauses, and nothing stopped a refactor from removing the mechanism
12
- * out from under published packages. Reported by the MOIC Suite consumer, who
13
- * needed exactly that and had to reach for a private constant to get it.
14
- *
15
- * So the encoding is now public, typed, and versioned by prefix rather than
16
- * implied. The wire format stays a plain string on purpose — it survives the
17
- * existing abort → `RunResult.error` path unchanged, crosses a queue boundary,
18
- * and decodes identically in PHP, none of which a thrown class would do.
19
- *
20
- * @see decodePause — the one function a durable runner needs.
21
- */
22
- /**
23
- * What the run is waiting for.
24
- *
25
- * `approval` and `input` are the shapes both runtimes ship. The type stays open
26
- * because the whole point is that a marketplace node can define its own —
27
- * a signature step, a payment confirmation, a review queue — and a runner that
28
- * does not recognise one should report it rather than guess.
29
- */
30
- type PauseAwaiting = "approval" | "input" | (string & {});
31
- /** A run halted, waiting for a person. */
32
- type PauseSignal = {
33
- /** The node that paused — where a submission gets injected on resume. */
34
- nodeId: string;
35
- awaiting: PauseAwaiting;
36
- /**
37
- * Kind-supplied context for whoever renders the wait — a form schema, the
38
- * question being asked, a diff to approve. Must be JSON-serializable: it
39
- * crosses a queue boundary and, for durable runs, a database column.
40
- */
41
- detail?: unknown;
42
- };
43
- /** Marks a reason string as a pause rather than a failure. */
44
- declare const PAUSE_PREFIX = "fancy-flow:pause:";
45
- /**
46
- * Reason prefixes shipped before this contract, kept decodable forever.
47
- *
48
- * These are what `DurableApprovalExecutor` and `DurableUserInputExecutor`
49
- * emitted, and they are written into the `error` column of every run that
50
- * paused under an older version. Dropping them would strand those runs
51
- * mid-flight — a resume path that only works for new runs is not a resume path.
52
- */
53
- declare const LEGACY_PAUSE_PREFIXES: ReadonlyArray<readonly [string, PauseAwaiting]>;
54
- /**
55
- * Encode a pause as the reason string an executor aborts with.
56
- *
57
- * The payload is JSON rather than delimited fields because a node id may
58
- * contain a colon, and a positional encoding that breaks on user data is the
59
- * kind of bug that only shows up in someone else's graph.
60
- */
61
- declare function encodePause(signal: PauseSignal): string;
62
- /**
63
- * Decode a run's error reason into a pause, or null if it was a real failure.
64
- *
65
- * This is the whole contract from a runner's side: call it on `result.error`,
66
- * and if it returns non-null, persist the run as waiting on `signal.nodeId`
67
- * instead of failing it. Accepts the legacy prefixes, so a runner written
68
- * against this handles runs that paused under an older version.
69
- */
70
- declare function decodePause(reason: string | null | undefined): PauseSignal | null;
71
- /** True when a run's error reason is actually a pause. */
72
- declare function isPause(reason: string | null | undefined): boolean;
73
- /**
74
- * Abort the current node as a pause.
75
- *
76
- * Called from inside an executor with its own context. Node authors should
77
- * reach for this rather than hand-encoding a reason, so the format stays ours
78
- * to change:
79
- *
80
- * ```ts
81
- * const values = ctx.inputs.values;
82
- * if (values === undefined) pauseForHuman(ctx, "input", { fields });
83
- * return values;
84
- * ```
85
- *
86
- * Note the `undefined` check — an empty submission (`{}`) is a real answer and
87
- * must resume. Truthiness here pauses forever on an empty form.
88
- */
89
- declare function pauseForHuman(ctx: {
90
- node: {
91
- id: string;
92
- };
93
- abort: (reason?: string) => never;
94
- }, awaiting: PauseAwaiting, detail?: unknown): never;
95
-
96
- export { LEGACY_PAUSE_PREFIXES as L, type PauseAwaiting as P, PAUSE_PREFIX as a, type PauseSignal as b, decodePause as d, encodePause as e, isPause as i, pauseForHuman as p };
@@ -1,96 +0,0 @@
1
- /**
2
- * The human-pause contract.
3
- *
4
- * A workflow that waits for a person is not an error, but it travels the same
5
- * channel as one: the executor aborts, the engine records a reason string, and
6
- * the durable runner decides whether that string meant "failed" or "waiting".
7
- *
8
- * That seam existed before this module, as two `str_starts_with` checks in the
9
- * Laravel run job against constants owned by two BUILTIN executors. It worked,
10
- * and it was invisible: a third-party human-input node had no way to announce
11
- * that it pauses, and nothing stopped a refactor from removing the mechanism
12
- * out from under published packages. Reported by the MOIC Suite consumer, who
13
- * needed exactly that and had to reach for a private constant to get it.
14
- *
15
- * So the encoding is now public, typed, and versioned by prefix rather than
16
- * implied. The wire format stays a plain string on purpose — it survives the
17
- * existing abort → `RunResult.error` path unchanged, crosses a queue boundary,
18
- * and decodes identically in PHP, none of which a thrown class would do.
19
- *
20
- * @see decodePause — the one function a durable runner needs.
21
- */
22
- /**
23
- * What the run is waiting for.
24
- *
25
- * `approval` and `input` are the shapes both runtimes ship. The type stays open
26
- * because the whole point is that a marketplace node can define its own —
27
- * a signature step, a payment confirmation, a review queue — and a runner that
28
- * does not recognise one should report it rather than guess.
29
- */
30
- type PauseAwaiting = "approval" | "input" | (string & {});
31
- /** A run halted, waiting for a person. */
32
- type PauseSignal = {
33
- /** The node that paused — where a submission gets injected on resume. */
34
- nodeId: string;
35
- awaiting: PauseAwaiting;
36
- /**
37
- * Kind-supplied context for whoever renders the wait — a form schema, the
38
- * question being asked, a diff to approve. Must be JSON-serializable: it
39
- * crosses a queue boundary and, for durable runs, a database column.
40
- */
41
- detail?: unknown;
42
- };
43
- /** Marks a reason string as a pause rather than a failure. */
44
- declare const PAUSE_PREFIX = "fancy-flow:pause:";
45
- /**
46
- * Reason prefixes shipped before this contract, kept decodable forever.
47
- *
48
- * These are what `DurableApprovalExecutor` and `DurableUserInputExecutor`
49
- * emitted, and they are written into the `error` column of every run that
50
- * paused under an older version. Dropping them would strand those runs
51
- * mid-flight — a resume path that only works for new runs is not a resume path.
52
- */
53
- declare const LEGACY_PAUSE_PREFIXES: ReadonlyArray<readonly [string, PauseAwaiting]>;
54
- /**
55
- * Encode a pause as the reason string an executor aborts with.
56
- *
57
- * The payload is JSON rather than delimited fields because a node id may
58
- * contain a colon, and a positional encoding that breaks on user data is the
59
- * kind of bug that only shows up in someone else's graph.
60
- */
61
- declare function encodePause(signal: PauseSignal): string;
62
- /**
63
- * Decode a run's error reason into a pause, or null if it was a real failure.
64
- *
65
- * This is the whole contract from a runner's side: call it on `result.error`,
66
- * and if it returns non-null, persist the run as waiting on `signal.nodeId`
67
- * instead of failing it. Accepts the legacy prefixes, so a runner written
68
- * against this handles runs that paused under an older version.
69
- */
70
- declare function decodePause(reason: string | null | undefined): PauseSignal | null;
71
- /** True when a run's error reason is actually a pause. */
72
- declare function isPause(reason: string | null | undefined): boolean;
73
- /**
74
- * Abort the current node as a pause.
75
- *
76
- * Called from inside an executor with its own context. Node authors should
77
- * reach for this rather than hand-encoding a reason, so the format stays ours
78
- * to change:
79
- *
80
- * ```ts
81
- * const values = ctx.inputs.values;
82
- * if (values === undefined) pauseForHuman(ctx, "input", { fields });
83
- * return values;
84
- * ```
85
- *
86
- * Note the `undefined` check — an empty submission (`{}`) is a real answer and
87
- * must resume. Truthiness here pauses forever on an empty form.
88
- */
89
- declare function pauseForHuman(ctx: {
90
- node: {
91
- id: string;
92
- };
93
- abort: (reason?: string) => never;
94
- }, awaiting: PauseAwaiting, detail?: unknown): never;
95
-
96
- export { LEGACY_PAUSE_PREFIXES as L, type PauseAwaiting as P, PAUSE_PREFIX as a, type PauseSignal as b, decodePause as d, encodePause as e, isPause as i, pauseForHuman as p };