@particle-academy/fancy-flow 0.8.0 → 0.10.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 +104 -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-WNVBXXOL.js → chunk-CPSOC27D.js} +43 -2
- package/dist/chunk-CPSOC27D.js.map +1 -0
- package/dist/chunk-F5RPRB7A.js +56 -0
- package/dist/chunk-F5RPRB7A.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-M2XKGQQL.js → chunk-NCPQDVUE.js} +178 -16
- package/dist/chunk-NCPQDVUE.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 +716 -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 +417 -23
- package/dist/index.js.map +1 -1
- package/dist/registry/index.d.cts +112 -4
- package/dist/registry/index.d.ts +112 -4
- package/dist/registry.cjs +312 -31
- package/dist/registry.cjs.map +1 -1
- package/dist/registry.js +4 -2
- package/dist/rich-input.cjs +56 -0
- package/dist/rich-input.cjs.map +1 -0
- package/dist/rich-input.d.cts +27 -0
- package/dist/rich-input.d.ts +27 -0
- package/dist/rich-input.js +37 -0
- package/dist/rich-input.js.map +1 -0
- 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 +24 -2
- 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,116 @@
|
|
|
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 { ComponentType, 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 injection point.
|
|
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. That page IS a fancy-cms document — fancy-flow defines no
|
|
53
|
+
* document schema of its own and never re-implements one.
|
|
54
|
+
*
|
|
55
|
+
* The wiring ships in the box. Import the subpath once and the node lights up:
|
|
56
|
+
*
|
|
57
|
+
* ```ts
|
|
58
|
+
* import "@particle-academy/fancy-flow/rich-input";
|
|
59
|
+
* ```
|
|
60
|
+
*
|
|
61
|
+
* That module registers fancy-cms's `PageDoc` + `CmsPage` renderer + `Editor`
|
|
62
|
+
* against this seam. It lives on a separate entry so `@particle-academy/
|
|
63
|
+
* fancy-cms-ui` and `@particle-academy/react-fancy` stay OPTIONAL peers — most
|
|
64
|
+
* flows never use a rich input, and a workflow editor should not drag a CMS
|
|
65
|
+
* into every install.
|
|
66
|
+
*
|
|
67
|
+
* The seam stays public so a host can substitute a different document engine,
|
|
68
|
+
* but that is the escape hatch, not the expected path.
|
|
69
|
+
*
|
|
70
|
+
* Until something registers, the node still registers and still round-trips
|
|
71
|
+
* its config — it renders a "how to enable" body rather than an empty card.
|
|
72
|
+
*/
|
|
73
|
+
type RichInputAdapter = {
|
|
74
|
+
/**
|
|
75
|
+
* react-fancy's `FauxClient` (or any component with the same shape) — a
|
|
76
|
+
* frame that mimics a browser window or device and scales its content down
|
|
77
|
+
* to fit. Used to preview the authored page inside the node card.
|
|
78
|
+
*/
|
|
79
|
+
FauxClient?: ComponentType<any>;
|
|
80
|
+
/**
|
|
81
|
+
* Props for the frame — e.g. `{ variant: "browser", width: 1280, scale: "fit" }`
|
|
82
|
+
* so a full-width page renders at its real width and scales down into the
|
|
83
|
+
* node card instead of reflowing to a cramped layout that misrepresents it.
|
|
84
|
+
*/
|
|
85
|
+
frameProps?: Record<string, unknown>;
|
|
86
|
+
/** Render the stored document read-only, for the in-node preview. */
|
|
87
|
+
renderDocument?: (doc: unknown) => ReactNode;
|
|
88
|
+
/** Editor mounted in the config panel via `renderDocumentField`. */
|
|
89
|
+
renderEditor?: (props: {
|
|
90
|
+
value: unknown;
|
|
91
|
+
onChange: (next: unknown) => void;
|
|
92
|
+
}) => ReactNode;
|
|
93
|
+
};
|
|
94
|
+
/** Install the host's document editor + preview frame. Returns an unregister fn. */
|
|
95
|
+
declare function registerRichInputAdapter(next: RichInputAdapter): () => void;
|
|
96
|
+
/** The registered adapter, or null when the host hasn't wired one. */
|
|
97
|
+
declare function getRichInputAdapter(): RichInputAdapter | null;
|
|
98
|
+
/** True once a host has wired an adapter — i.e. the node is usable. */
|
|
99
|
+
declare function isRichInputEnabled(): boolean;
|
|
100
|
+
/** Subscribe to adapter changes (so nodes re-render when it lands). */
|
|
101
|
+
declare function onRichInputAdapterChanged(fn: () => void): () => void;
|
|
102
|
+
/**
|
|
103
|
+
* RichInputPreview — the node card body. Shows the authored page inside a
|
|
104
|
+
* FauxClient frame so an author can see, at a glance on the canvas, what the
|
|
105
|
+
* person hitting this step will be looking at.
|
|
106
|
+
*
|
|
107
|
+
* Degrades in two steps rather than one: no adapter at all → install hint;
|
|
108
|
+
* adapter but nothing authored yet → an empty frame with the step title. A
|
|
109
|
+
* blank node body would read as "broken" in both cases.
|
|
110
|
+
*/
|
|
111
|
+
declare function RichInputPreview({ config }: {
|
|
112
|
+
config: Record<string, unknown>;
|
|
113
|
+
}): react.JSX.Element;
|
|
6
114
|
|
|
7
115
|
/**
|
|
8
116
|
* registerNodeKind — install a node kind in the global registry. Returns
|
|
@@ -50,4 +158,4 @@ declare const BUILTIN_KINDS: NodeKindDefinition[];
|
|
|
50
158
|
*/
|
|
51
159
|
declare function buildNodeTypes(): NodeTypes;
|
|
52
160
|
|
|
53
|
-
export { BUILTIN_KINDS, NodeKindDefinition, RegistryNode, buildNodeTypes, categoryAccent, defaultConfigFor, getNodeKind, listNodeKinds, onNodeKindsChanged, registerBuiltinKinds, registerNodeKind, validateConfig };
|
|
161
|
+
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,116 @@
|
|
|
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 { ComponentType, 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 injection point.
|
|
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. That page IS a fancy-cms document — fancy-flow defines no
|
|
53
|
+
* document schema of its own and never re-implements one.
|
|
54
|
+
*
|
|
55
|
+
* The wiring ships in the box. Import the subpath once and the node lights up:
|
|
56
|
+
*
|
|
57
|
+
* ```ts
|
|
58
|
+
* import "@particle-academy/fancy-flow/rich-input";
|
|
59
|
+
* ```
|
|
60
|
+
*
|
|
61
|
+
* That module registers fancy-cms's `PageDoc` + `CmsPage` renderer + `Editor`
|
|
62
|
+
* against this seam. It lives on a separate entry so `@particle-academy/
|
|
63
|
+
* fancy-cms-ui` and `@particle-academy/react-fancy` stay OPTIONAL peers — most
|
|
64
|
+
* flows never use a rich input, and a workflow editor should not drag a CMS
|
|
65
|
+
* into every install.
|
|
66
|
+
*
|
|
67
|
+
* The seam stays public so a host can substitute a different document engine,
|
|
68
|
+
* but that is the escape hatch, not the expected path.
|
|
69
|
+
*
|
|
70
|
+
* Until something registers, the node still registers and still round-trips
|
|
71
|
+
* its config — it renders a "how to enable" body rather than an empty card.
|
|
72
|
+
*/
|
|
73
|
+
type RichInputAdapter = {
|
|
74
|
+
/**
|
|
75
|
+
* react-fancy's `FauxClient` (or any component with the same shape) — a
|
|
76
|
+
* frame that mimics a browser window or device and scales its content down
|
|
77
|
+
* to fit. Used to preview the authored page inside the node card.
|
|
78
|
+
*/
|
|
79
|
+
FauxClient?: ComponentType<any>;
|
|
80
|
+
/**
|
|
81
|
+
* Props for the frame — e.g. `{ variant: "browser", width: 1280, scale: "fit" }`
|
|
82
|
+
* so a full-width page renders at its real width and scales down into the
|
|
83
|
+
* node card instead of reflowing to a cramped layout that misrepresents it.
|
|
84
|
+
*/
|
|
85
|
+
frameProps?: Record<string, unknown>;
|
|
86
|
+
/** Render the stored document read-only, for the in-node preview. */
|
|
87
|
+
renderDocument?: (doc: unknown) => ReactNode;
|
|
88
|
+
/** Editor mounted in the config panel via `renderDocumentField`. */
|
|
89
|
+
renderEditor?: (props: {
|
|
90
|
+
value: unknown;
|
|
91
|
+
onChange: (next: unknown) => void;
|
|
92
|
+
}) => ReactNode;
|
|
93
|
+
};
|
|
94
|
+
/** Install the host's document editor + preview frame. Returns an unregister fn. */
|
|
95
|
+
declare function registerRichInputAdapter(next: RichInputAdapter): () => void;
|
|
96
|
+
/** The registered adapter, or null when the host hasn't wired one. */
|
|
97
|
+
declare function getRichInputAdapter(): RichInputAdapter | null;
|
|
98
|
+
/** True once a host has wired an adapter — i.e. the node is usable. */
|
|
99
|
+
declare function isRichInputEnabled(): boolean;
|
|
100
|
+
/** Subscribe to adapter changes (so nodes re-render when it lands). */
|
|
101
|
+
declare function onRichInputAdapterChanged(fn: () => void): () => void;
|
|
102
|
+
/**
|
|
103
|
+
* RichInputPreview — the node card body. Shows the authored page inside a
|
|
104
|
+
* FauxClient frame so an author can see, at a glance on the canvas, what the
|
|
105
|
+
* person hitting this step will be looking at.
|
|
106
|
+
*
|
|
107
|
+
* Degrades in two steps rather than one: no adapter at all → install hint;
|
|
108
|
+
* adapter but nothing authored yet → an empty frame with the step title. A
|
|
109
|
+
* blank node body would read as "broken" in both cases.
|
|
110
|
+
*/
|
|
111
|
+
declare function RichInputPreview({ config }: {
|
|
112
|
+
config: Record<string, unknown>;
|
|
113
|
+
}): react.JSX.Element;
|
|
6
114
|
|
|
7
115
|
/**
|
|
8
116
|
* registerNodeKind — install a node kind in the global registry. Returns
|
|
@@ -50,4 +158,4 @@ declare const BUILTIN_KINDS: NodeKindDefinition[];
|
|
|
50
158
|
*/
|
|
51
159
|
declare function buildNodeTypes(): NodeTypes;
|
|
52
160
|
|
|
53
|
-
export { BUILTIN_KINDS, NodeKindDefinition, RegistryNode, buildNodeTypes, categoryAccent, defaultConfigFor, getNodeKind, listNodeKinds, onNodeKindsChanged, registerBuiltinKinds, registerNodeKind, validateConfig };
|
|
161
|
+
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 };
|