@particle-academy/fancy-flow 0.7.0 → 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +93 -0
- package/dist/{chunk-BCXECQUC.js → chunk-6GGFEZH7.js} +3 -3
- package/dist/{chunk-BCXECQUC.js.map → chunk-6GGFEZH7.js.map} +1 -1
- package/dist/{chunk-M2XKGQQL.js → chunk-6RHAQ2LP.js} +228 -17
- package/dist/chunk-6RHAQ2LP.js.map +1 -0
- package/dist/{chunk-WNVBXXOL.js → chunk-CPSOC27D.js} +43 -2
- package/dist/chunk-CPSOC27D.js.map +1 -0
- package/dist/{chunk-NVULCEDX.js → chunk-HNBO4HP3.js} +8 -4
- package/dist/chunk-HNBO4HP3.js.map +1 -0
- package/dist/chunk-TITD5W4Y.js +26 -0
- package/dist/chunk-TITD5W4Y.js.map +1 -0
- package/dist/{chunk-QSSQRQN4.js → chunk-VEI743ZX.js} +3 -3
- package/dist/{chunk-QSSQRQN4.js.map → chunk-VEI743ZX.js.map} +1 -1
- package/dist/engine.cjs +32 -2
- package/dist/engine.cjs.map +1 -1
- package/dist/engine.js +3 -1
- package/dist/index.cjs +717 -40
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +45 -6
- package/dist/index.d.ts +45 -6
- package/dist/index.js +415 -23
- package/dist/index.js.map +1 -1
- package/dist/registry/index.d.cts +111 -4
- package/dist/registry/index.d.ts +111 -4
- package/dist/registry.cjs +313 -31
- package/dist/registry.cjs.map +1 -1
- package/dist/registry.js +3 -2
- package/dist/runtime.cjs +32 -2
- package/dist/runtime.cjs.map +1 -1
- package/dist/runtime.js +4 -2
- package/dist/schema.cjs +41 -0
- package/dist/schema.cjs.map +1 -1
- package/dist/schema.js +2 -2
- package/dist/styles.css +191 -0
- package/dist/styles.css.map +1 -1
- package/dist/types-BocBFh6l.d.ts +221 -0
- package/dist/types-DKqaUjF_.d.cts +221 -0
- package/dist/ux.cjs.map +1 -1
- package/dist/ux.d.cts +1 -1
- package/dist/ux.d.ts +1 -1
- package/dist/ux.js +1 -1
- package/package.json +4 -4
- package/dist/chunk-M2XKGQQL.js.map +0 -1
- package/dist/chunk-NVULCEDX.js.map +0 -1
- package/dist/chunk-WNVBXXOL.js.map +0 -1
- package/dist/types-C0wdN6QX.d.cts +0 -121
- package/dist/types-DnMe9Vsf.d.ts +0 -121
|
@@ -1,8 +1,115 @@
|
|
|
1
|
-
import { a as NodeKindDefinition } from '../types-
|
|
2
|
-
export { C as ConfigField, b as CredentialConfigField, E as ExpressionConfigField, J as JsonConfigField, N as NodeCategory, c as NumberConfigField, R as RenderBodyContext, S as SelectConfigField,
|
|
1
|
+
import { a as NodeKindDefinition, P as PortSpec } from '../types-DKqaUjF_.cjs';
|
|
2
|
+
export { C as ConfigField, b as CredentialConfigField, D as DocumentConfigField, E as ExpressionConfigField, J as JsonConfigField, K as KeyValueConfigField, N as NodeCategory, c as NumberConfigField, R as RenderBodyContext, d as RepeaterConfigField, e as RepeaterRowField, S as SelectConfigField, f as SwitchConfigField, T as TextConfigField, g as TextareaConfigField } from '../types-DKqaUjF_.cjs';
|
|
3
|
+
import { F as FlowNode, P as PortDescriptor } from '../types-BS3Gwnkq.cjs';
|
|
3
4
|
import * as react from 'react';
|
|
5
|
+
import { ReactNode } from 'react';
|
|
4
6
|
import { NodeProps, NodeTypes } from '@xyflow/react';
|
|
5
|
-
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Port resolution — the single place a node's ports are derived, shared by
|
|
10
|
+
* the canvas renderer and the headless runtime.
|
|
11
|
+
*
|
|
12
|
+
* This module is deliberately React-free: `runFlow` (the `/engine` entry)
|
|
13
|
+
* imports it, and the engine bundle must stay free of React.
|
|
14
|
+
*
|
|
15
|
+
* ## Why this is centralized
|
|
16
|
+
*
|
|
17
|
+
* Ports used to be read in two places that disagreed — the canvas consulted
|
|
18
|
+
* `data.outputs ?? kind.outputs`, while the runtime consulted `data.outputs`
|
|
19
|
+
* ONLY and fell back to a single `out` port. A kind that declared branch ports
|
|
20
|
+
* therefore drew correctly and then routed as if it had one output, unless the
|
|
21
|
+
* host remembered to mirror the ports onto every node's `data`. Both callers
|
|
22
|
+
* now go through `resolveNodePorts`, so declared ports and executed ports
|
|
23
|
+
* cannot drift apart.
|
|
24
|
+
*/
|
|
25
|
+
/**
|
|
26
|
+
* Resolve a `PortSpec` against a config object.
|
|
27
|
+
*
|
|
28
|
+
* A config-driven spec is author-supplied and runs on every render, so a throw
|
|
29
|
+
* is contained: it degrades to "undeclared" (letting the caller fall back)
|
|
30
|
+
* rather than taking out the canvas or aborting a run mid-flight.
|
|
31
|
+
*/
|
|
32
|
+
declare function resolvePortSpec<TConfig>(spec: PortSpec<TConfig> | undefined, config: TConfig): PortDescriptor[] | undefined;
|
|
33
|
+
/** Read the config bag off a node, tolerating the FlowNodeData union. */
|
|
34
|
+
declare function nodeConfig(node: Pick<FlowNode, "data">): Record<string, unknown>;
|
|
35
|
+
/**
|
|
36
|
+
* Resolve a node's effective ports.
|
|
37
|
+
*
|
|
38
|
+
* Precedence: explicit `data.inputs`/`data.outputs` (a per-node host override)
|
|
39
|
+
* beats the kind's declaration. `undefined` means "nothing declared" — the
|
|
40
|
+
* caller applies its own category default.
|
|
41
|
+
*/
|
|
42
|
+
declare function resolveNodePorts(node: Pick<FlowNode, "data">, kind?: Pick<NodeKindDefinition<any>, "inputs" | "outputs">): {
|
|
43
|
+
inputs?: PortDescriptor[];
|
|
44
|
+
outputs?: PortDescriptor[];
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Rich user input — the adapter seam.
|
|
49
|
+
*
|
|
50
|
+
* `rich_user_input` pauses a run on a fully authored page (long-form content,
|
|
51
|
+
* required reading + confirmation, multi-section forms) rather than a flat
|
|
52
|
+
* field list. Authoring and rendering that document needs a document model
|
|
53
|
+
* (fancy-cms Stages) and a device frame for the preview (react-fancy's
|
|
54
|
+
* FauxClient) — neither of which fancy-flow depends on.
|
|
55
|
+
*
|
|
56
|
+
* So the host registers them once, and the node lights up:
|
|
57
|
+
*
|
|
58
|
+
* ```tsx
|
|
59
|
+
* import { FauxClient } from "@particle-academy/react-fancy";
|
|
60
|
+
* import { StagesViewer } from "@particle-academy/fancy-cms-ui";
|
|
61
|
+
* import { registerRichInputAdapter } from "@particle-academy/fancy-flow";
|
|
62
|
+
*
|
|
63
|
+
* registerRichInputAdapter({
|
|
64
|
+
* FauxClient,
|
|
65
|
+
* renderDocument: (doc) => <StagesViewer doc={doc} />,
|
|
66
|
+
* });
|
|
67
|
+
* ```
|
|
68
|
+
*
|
|
69
|
+
* Until then the node still registers and still round-trips its config — it
|
|
70
|
+
* just renders an "unavailable" body explaining what to install. Keeping the
|
|
71
|
+
* dependency optional is deliberate: fancy-cms is an early-release beta, and a
|
|
72
|
+
* workflow editor should not hard-require a CMS to draw a canvas.
|
|
73
|
+
*/
|
|
74
|
+
type RichInputAdapter = {
|
|
75
|
+
/**
|
|
76
|
+
* react-fancy's `FauxClient` (or any component with the same shape) — a
|
|
77
|
+
* frame that mimics a browser window or device and scales its content down
|
|
78
|
+
* to fit. Used to preview the authored page inside the node card.
|
|
79
|
+
*/
|
|
80
|
+
FauxClient?: (props: {
|
|
81
|
+
variant?: "browser" | "device" | "bare";
|
|
82
|
+
children?: ReactNode;
|
|
83
|
+
[key: string]: unknown;
|
|
84
|
+
}) => ReactNode;
|
|
85
|
+
/** Render the stored document read-only, for the in-node preview. */
|
|
86
|
+
renderDocument?: (doc: unknown) => ReactNode;
|
|
87
|
+
/** Editor mounted in the config panel via `renderDocumentField`. */
|
|
88
|
+
renderEditor?: (props: {
|
|
89
|
+
value: unknown;
|
|
90
|
+
onChange: (next: unknown) => void;
|
|
91
|
+
}) => ReactNode;
|
|
92
|
+
};
|
|
93
|
+
/** Install the host's document editor + preview frame. Returns an unregister fn. */
|
|
94
|
+
declare function registerRichInputAdapter(next: RichInputAdapter): () => void;
|
|
95
|
+
/** The registered adapter, or null when the host hasn't wired one. */
|
|
96
|
+
declare function getRichInputAdapter(): RichInputAdapter | null;
|
|
97
|
+
/** True once a host has wired an adapter — i.e. the node is usable. */
|
|
98
|
+
declare function isRichInputEnabled(): boolean;
|
|
99
|
+
/** Subscribe to adapter changes (so nodes re-render when it lands). */
|
|
100
|
+
declare function onRichInputAdapterChanged(fn: () => void): () => void;
|
|
101
|
+
/**
|
|
102
|
+
* RichInputPreview — the node card body. Shows the authored page inside a
|
|
103
|
+
* FauxClient frame so an author can see, at a glance on the canvas, what the
|
|
104
|
+
* person hitting this step will be looking at.
|
|
105
|
+
*
|
|
106
|
+
* Degrades in two steps rather than one: no adapter at all → install hint;
|
|
107
|
+
* adapter but nothing authored yet → an empty frame with the step title. A
|
|
108
|
+
* blank node body would read as "broken" in both cases.
|
|
109
|
+
*/
|
|
110
|
+
declare function RichInputPreview({ config }: {
|
|
111
|
+
config: Record<string, unknown>;
|
|
112
|
+
}): react.JSX.Element;
|
|
6
113
|
|
|
7
114
|
/**
|
|
8
115
|
* registerNodeKind — install a node kind in the global registry. Returns
|
|
@@ -50,4 +157,4 @@ declare const BUILTIN_KINDS: NodeKindDefinition[];
|
|
|
50
157
|
*/
|
|
51
158
|
declare function buildNodeTypes(): NodeTypes;
|
|
52
159
|
|
|
53
|
-
export { BUILTIN_KINDS, NodeKindDefinition, RegistryNode, buildNodeTypes, categoryAccent, defaultConfigFor, getNodeKind, listNodeKinds, onNodeKindsChanged, registerBuiltinKinds, registerNodeKind, validateConfig };
|
|
160
|
+
export { BUILTIN_KINDS, NodeKindDefinition, PortSpec, RegistryNode, type RichInputAdapter, RichInputPreview, buildNodeTypes, categoryAccent, defaultConfigFor, getNodeKind, getRichInputAdapter, isRichInputEnabled, listNodeKinds, nodeConfig, onNodeKindsChanged, onRichInputAdapterChanged, registerBuiltinKinds, registerNodeKind, registerRichInputAdapter, resolveNodePorts, resolvePortSpec, validateConfig };
|
package/dist/registry/index.d.ts
CHANGED
|
@@ -1,8 +1,115 @@
|
|
|
1
|
-
import { a as NodeKindDefinition } from '../types-
|
|
2
|
-
export { C as ConfigField, b as CredentialConfigField, E as ExpressionConfigField, J as JsonConfigField, N as NodeCategory, c as NumberConfigField, R as RenderBodyContext, S as SelectConfigField,
|
|
1
|
+
import { a as NodeKindDefinition, P as PortSpec } from '../types-BocBFh6l.js';
|
|
2
|
+
export { C as ConfigField, b as CredentialConfigField, D as DocumentConfigField, E as ExpressionConfigField, J as JsonConfigField, K as KeyValueConfigField, N as NodeCategory, c as NumberConfigField, R as RenderBodyContext, d as RepeaterConfigField, e as RepeaterRowField, S as SelectConfigField, f as SwitchConfigField, T as TextConfigField, g as TextareaConfigField } from '../types-BocBFh6l.js';
|
|
3
|
+
import { F as FlowNode, P as PortDescriptor } from '../types-BS3Gwnkq.js';
|
|
3
4
|
import * as react from 'react';
|
|
5
|
+
import { ReactNode } from 'react';
|
|
4
6
|
import { NodeProps, NodeTypes } from '@xyflow/react';
|
|
5
|
-
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Port resolution — the single place a node's ports are derived, shared by
|
|
10
|
+
* the canvas renderer and the headless runtime.
|
|
11
|
+
*
|
|
12
|
+
* This module is deliberately React-free: `runFlow` (the `/engine` entry)
|
|
13
|
+
* imports it, and the engine bundle must stay free of React.
|
|
14
|
+
*
|
|
15
|
+
* ## Why this is centralized
|
|
16
|
+
*
|
|
17
|
+
* Ports used to be read in two places that disagreed — the canvas consulted
|
|
18
|
+
* `data.outputs ?? kind.outputs`, while the runtime consulted `data.outputs`
|
|
19
|
+
* ONLY and fell back to a single `out` port. A kind that declared branch ports
|
|
20
|
+
* therefore drew correctly and then routed as if it had one output, unless the
|
|
21
|
+
* host remembered to mirror the ports onto every node's `data`. Both callers
|
|
22
|
+
* now go through `resolveNodePorts`, so declared ports and executed ports
|
|
23
|
+
* cannot drift apart.
|
|
24
|
+
*/
|
|
25
|
+
/**
|
|
26
|
+
* Resolve a `PortSpec` against a config object.
|
|
27
|
+
*
|
|
28
|
+
* A config-driven spec is author-supplied and runs on every render, so a throw
|
|
29
|
+
* is contained: it degrades to "undeclared" (letting the caller fall back)
|
|
30
|
+
* rather than taking out the canvas or aborting a run mid-flight.
|
|
31
|
+
*/
|
|
32
|
+
declare function resolvePortSpec<TConfig>(spec: PortSpec<TConfig> | undefined, config: TConfig): PortDescriptor[] | undefined;
|
|
33
|
+
/** Read the config bag off a node, tolerating the FlowNodeData union. */
|
|
34
|
+
declare function nodeConfig(node: Pick<FlowNode, "data">): Record<string, unknown>;
|
|
35
|
+
/**
|
|
36
|
+
* Resolve a node's effective ports.
|
|
37
|
+
*
|
|
38
|
+
* Precedence: explicit `data.inputs`/`data.outputs` (a per-node host override)
|
|
39
|
+
* beats the kind's declaration. `undefined` means "nothing declared" — the
|
|
40
|
+
* caller applies its own category default.
|
|
41
|
+
*/
|
|
42
|
+
declare function resolveNodePorts(node: Pick<FlowNode, "data">, kind?: Pick<NodeKindDefinition<any>, "inputs" | "outputs">): {
|
|
43
|
+
inputs?: PortDescriptor[];
|
|
44
|
+
outputs?: PortDescriptor[];
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Rich user input — the adapter seam.
|
|
49
|
+
*
|
|
50
|
+
* `rich_user_input` pauses a run on a fully authored page (long-form content,
|
|
51
|
+
* required reading + confirmation, multi-section forms) rather than a flat
|
|
52
|
+
* field list. Authoring and rendering that document needs a document model
|
|
53
|
+
* (fancy-cms Stages) and a device frame for the preview (react-fancy's
|
|
54
|
+
* FauxClient) — neither of which fancy-flow depends on.
|
|
55
|
+
*
|
|
56
|
+
* So the host registers them once, and the node lights up:
|
|
57
|
+
*
|
|
58
|
+
* ```tsx
|
|
59
|
+
* import { FauxClient } from "@particle-academy/react-fancy";
|
|
60
|
+
* import { StagesViewer } from "@particle-academy/fancy-cms-ui";
|
|
61
|
+
* import { registerRichInputAdapter } from "@particle-academy/fancy-flow";
|
|
62
|
+
*
|
|
63
|
+
* registerRichInputAdapter({
|
|
64
|
+
* FauxClient,
|
|
65
|
+
* renderDocument: (doc) => <StagesViewer doc={doc} />,
|
|
66
|
+
* });
|
|
67
|
+
* ```
|
|
68
|
+
*
|
|
69
|
+
* Until then the node still registers and still round-trips its config — it
|
|
70
|
+
* just renders an "unavailable" body explaining what to install. Keeping the
|
|
71
|
+
* dependency optional is deliberate: fancy-cms is an early-release beta, and a
|
|
72
|
+
* workflow editor should not hard-require a CMS to draw a canvas.
|
|
73
|
+
*/
|
|
74
|
+
type RichInputAdapter = {
|
|
75
|
+
/**
|
|
76
|
+
* react-fancy's `FauxClient` (or any component with the same shape) — a
|
|
77
|
+
* frame that mimics a browser window or device and scales its content down
|
|
78
|
+
* to fit. Used to preview the authored page inside the node card.
|
|
79
|
+
*/
|
|
80
|
+
FauxClient?: (props: {
|
|
81
|
+
variant?: "browser" | "device" | "bare";
|
|
82
|
+
children?: ReactNode;
|
|
83
|
+
[key: string]: unknown;
|
|
84
|
+
}) => ReactNode;
|
|
85
|
+
/** Render the stored document read-only, for the in-node preview. */
|
|
86
|
+
renderDocument?: (doc: unknown) => ReactNode;
|
|
87
|
+
/** Editor mounted in the config panel via `renderDocumentField`. */
|
|
88
|
+
renderEditor?: (props: {
|
|
89
|
+
value: unknown;
|
|
90
|
+
onChange: (next: unknown) => void;
|
|
91
|
+
}) => ReactNode;
|
|
92
|
+
};
|
|
93
|
+
/** Install the host's document editor + preview frame. Returns an unregister fn. */
|
|
94
|
+
declare function registerRichInputAdapter(next: RichInputAdapter): () => void;
|
|
95
|
+
/** The registered adapter, or null when the host hasn't wired one. */
|
|
96
|
+
declare function getRichInputAdapter(): RichInputAdapter | null;
|
|
97
|
+
/** True once a host has wired an adapter — i.e. the node is usable. */
|
|
98
|
+
declare function isRichInputEnabled(): boolean;
|
|
99
|
+
/** Subscribe to adapter changes (so nodes re-render when it lands). */
|
|
100
|
+
declare function onRichInputAdapterChanged(fn: () => void): () => void;
|
|
101
|
+
/**
|
|
102
|
+
* RichInputPreview — the node card body. Shows the authored page inside a
|
|
103
|
+
* FauxClient frame so an author can see, at a glance on the canvas, what the
|
|
104
|
+
* person hitting this step will be looking at.
|
|
105
|
+
*
|
|
106
|
+
* Degrades in two steps rather than one: no adapter at all → install hint;
|
|
107
|
+
* adapter but nothing authored yet → an empty frame with the step title. A
|
|
108
|
+
* blank node body would read as "broken" in both cases.
|
|
109
|
+
*/
|
|
110
|
+
declare function RichInputPreview({ config }: {
|
|
111
|
+
config: Record<string, unknown>;
|
|
112
|
+
}): react.JSX.Element;
|
|
6
113
|
|
|
7
114
|
/**
|
|
8
115
|
* registerNodeKind — install a node kind in the global registry. Returns
|
|
@@ -50,4 +157,4 @@ declare const BUILTIN_KINDS: NodeKindDefinition[];
|
|
|
50
157
|
*/
|
|
51
158
|
declare function buildNodeTypes(): NodeTypes;
|
|
52
159
|
|
|
53
|
-
export { BUILTIN_KINDS, NodeKindDefinition, RegistryNode, buildNodeTypes, categoryAccent, defaultConfigFor, getNodeKind, listNodeKinds, onNodeKindsChanged, registerBuiltinKinds, registerNodeKind, validateConfig };
|
|
160
|
+
export { BUILTIN_KINDS, NodeKindDefinition, PortSpec, RegistryNode, type RichInputAdapter, RichInputPreview, buildNodeTypes, categoryAccent, defaultConfigFor, getNodeKind, getRichInputAdapter, isRichInputEnabled, listNodeKinds, nodeConfig, onNodeKindsChanged, onRichInputAdapterChanged, registerBuiltinKinds, registerNodeKind, registerRichInputAdapter, resolveNodePorts, resolvePortSpec, validateConfig };
|