@flowdrop/flowdrop 1.14.0 → 1.15.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.
@@ -202,7 +202,7 @@ export declare function dynamicPortToNodePort(port: DynamicPort, portType: 'inpu
202
202
  * Built-in node types for explicit component rendering.
203
203
  * These are the node types that ship with FlowDrop.
204
204
  */
205
- export type BuiltinNodeType = 'note' | 'simple' | 'square' | 'tool' | 'gateway' | 'terminal' | 'default';
205
+ export type BuiltinNodeType = 'note' | 'simple' | 'square' | 'atom' | 'tool' | 'gateway' | 'terminal' | 'default';
206
206
  /**
207
207
  * Node type for component rendering.
208
208
  * Includes built-in types and allows custom registered types.
@@ -306,8 +306,13 @@ export interface AutocompleteConfig {
306
306
  * If the "account" field currently holds "my-jira", the URL becomes:
307
307
  * /api/jira/issue-types?account=my-jira&q=...
308
308
  *
309
- * When any dependency field changes, the autocomplete clears its
310
- * current value and invalidates the suggestion cache.
309
+ * When a dependency field changes, the component invalidates its cached
310
+ * suggestions and aborts any in-flight fetch. The dependent field's own
311
+ * value is cleared by the parent form (`ConfigForm` / `SchemaForm`) on
312
+ * user-driven edits only — undo/redo, programmatic value replacement, and
313
+ * collaborative edits flow in via props and preserve dependent values.
314
+ * Standalone consumers of `FormAutocomplete` outside a FlowDrop form
315
+ * therefore need to clear dependents themselves.
311
316
  */
312
317
  params?: Record<string, string>;
313
318
  }
@@ -495,9 +500,39 @@ export interface ConfigEditOptions {
495
500
  * UI-related extension settings for nodes
496
501
  * Used to control visual behavior in the workflow editor
497
502
  */
503
+ /**
504
+ * Display/behavior config for minimalist "atom" nodes (Constant, Cast, …).
505
+ * Lives under `extensions.ui.atom`. The atom renderer reads it to decide what to
506
+ * show, and `getAllPorts` reads `valueTypeKey` to drive the bound output port's
507
+ * dataType from config so connection validation stays correct.
508
+ */
509
+ export interface AtomUIConfig {
510
+ /** Config key whose value becomes the node body. Falls back to `data.label`. */
511
+ valueKey?: string;
512
+ /**
513
+ * Config key holding the selected value's type (a port dataType id).
514
+ * The bound output port adopts this dataType.
515
+ */
516
+ valueTypeKey?: string;
517
+ /** Output port id driven by `valueTypeKey`. Defaults to the first output port. */
518
+ outputPortId?: string;
519
+ /** Body shape. `'pill'` (default) is fully rounded; `'rectangle'` is lightly rounded. */
520
+ shape?: 'pill' | 'rectangle';
521
+ /**
522
+ * Dimmed affordance rendered before the body (e.g. `'→ '` to mark a transform).
523
+ * Stays visible while the body value ellipsizes. Hidden in the empty state.
524
+ */
525
+ prefix?: string;
526
+ /** Text shown (dimmed) when the resolved body value is empty/unset. */
527
+ placeholder?: string;
528
+ /** Max body width in px before the label ellipsizes. */
529
+ maxWidth?: number;
530
+ }
498
531
  export interface NodeUIExtensions {
499
532
  /** Show/hide unconnected handles (ports) to reduce visual noise */
500
533
  hideUnconnectedHandles?: boolean;
534
+ /** Display/behavior config for minimalist atom nodes (Constant, Cast, …) */
535
+ atom?: AtomUIConfig;
501
536
  /**
502
537
  * Visual-only port display order (no effect on execution).
503
538
  * Arrays of port IDs in the desired render order.
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Form value merge — shared by `SchemaForm` and `ConfigForm`.
3
+ *
4
+ * Produces the view of form values that children read via context. Precedence
5
+ * per key:
6
+ *
7
+ * 1. `key in edits` → use the user's local edit
8
+ * 2. `source[key] !== undefined` → use the prop value (including null/0/false/'')
9
+ * 3. otherwise → use the schema field's `default`
10
+ *
11
+ * Keeping this separate from the host components means the test pins the same
12
+ * function the components run, not a parallel implementation.
13
+ */
14
+ export declare function mergeWithDefaults(schema: {
15
+ properties?: Record<string, unknown>;
16
+ } | undefined, source: Record<string, unknown>, edits: Record<string, unknown>): Record<string, unknown>;
17
+ /**
18
+ * Compute the cascade-clear set when a single field changes — shared by
19
+ * `SchemaForm` and `ConfigForm`.
20
+ *
21
+ * When `changedKey` changes, any property whose `autocomplete.params` references
22
+ * `changedKey` (directly or transitively) should have its value cleared: the
23
+ * old dependent value was computed against the old parent value and is now
24
+ * stale.
25
+ *
26
+ * Returns a map of `{ dependentKey -> clearValue }` to apply on top of the
27
+ * caller's edits buffer. Single-value autocompletes clear to `''`; ones with
28
+ * `multiple: true` clear to `[]`.
29
+ *
30
+ * This logic lives in the parent form (not in `FormAutocomplete`) so it only
31
+ * runs on user-driven changes via `handleFieldChange`, not on undo/redo,
32
+ * programmatic resets, or collaborative edits (#33).
33
+ */
34
+ export declare function cascadeClearAutocompleteDependents(schema: {
35
+ properties?: Record<string, unknown>;
36
+ } | undefined, changedKey: string): Record<string, unknown>;
@@ -0,0 +1,70 @@
1
+ /**
2
+ * Form value merge — shared by `SchemaForm` and `ConfigForm`.
3
+ *
4
+ * Produces the view of form values that children read via context. Precedence
5
+ * per key:
6
+ *
7
+ * 1. `key in edits` → use the user's local edit
8
+ * 2. `source[key] !== undefined` → use the prop value (including null/0/false/'')
9
+ * 3. otherwise → use the schema field's `default`
10
+ *
11
+ * Keeping this separate from the host components means the test pins the same
12
+ * function the components run, not a parallel implementation.
13
+ */
14
+ export function mergeWithDefaults(schema, source, edits) {
15
+ if (!schema?.properties)
16
+ return {};
17
+ const merged = {};
18
+ for (const [key, field] of Object.entries(schema.properties)) {
19
+ if (key in edits) {
20
+ merged[key] = edits[key];
21
+ }
22
+ else {
23
+ const fieldConfig = field;
24
+ merged[key] = source[key] !== undefined ? source[key] : fieldConfig.default;
25
+ }
26
+ }
27
+ return merged;
28
+ }
29
+ /**
30
+ * Compute the cascade-clear set when a single field changes — shared by
31
+ * `SchemaForm` and `ConfigForm`.
32
+ *
33
+ * When `changedKey` changes, any property whose `autocomplete.params` references
34
+ * `changedKey` (directly or transitively) should have its value cleared: the
35
+ * old dependent value was computed against the old parent value and is now
36
+ * stale.
37
+ *
38
+ * Returns a map of `{ dependentKey -> clearValue }` to apply on top of the
39
+ * caller's edits buffer. Single-value autocompletes clear to `''`; ones with
40
+ * `multiple: true` clear to `[]`.
41
+ *
42
+ * This logic lives in the parent form (not in `FormAutocomplete`) so it only
43
+ * runs on user-driven changes via `handleFieldChange`, not on undo/redo,
44
+ * programmatic resets, or collaborative edits (#33).
45
+ */
46
+ export function cascadeClearAutocompleteDependents(schema, changedKey) {
47
+ if (!schema?.properties)
48
+ return {};
49
+ const cleared = new Set([changedKey]);
50
+ const result = {};
51
+ let added = true;
52
+ while (added) {
53
+ added = false;
54
+ for (const [depKey, depField] of Object.entries(schema.properties)) {
55
+ if (cleared.has(depKey))
56
+ continue;
57
+ const field = depField;
58
+ const params = field.autocomplete?.params;
59
+ if (!params)
60
+ continue;
61
+ const dependsOnCleared = Object.values(params).some((fieldName) => cleared.has(fieldName));
62
+ if (dependsOnCleared) {
63
+ result[depKey] = field.autocomplete?.multiple ? [] : '';
64
+ cleared.add(depKey);
65
+ added = true;
66
+ }
67
+ }
68
+ }
69
+ return result;
70
+ }
@@ -18,6 +18,7 @@ const TYPE_DISPLAY_NAMES = {
18
18
  note: 'Note (sticky note style)',
19
19
  simple: 'Simple (compact layout)',
20
20
  square: 'Square (geometric layout)',
21
+ atom: 'Atom (minimal value/transform)',
21
22
  tool: 'Tool (specialized for agent tools)',
22
23
  gateway: 'Gateway (branching control flow)',
23
24
  terminal: 'Terminal (start/end/exit)',
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "description": "A drop-in visual workflow editor for any web application. You own the backend. You own the data. You own the orchestration.",
4
4
  "license": "MIT",
5
5
  "private": false,
6
- "version": "1.14.0",
6
+ "version": "1.15.0",
7
7
  "author": "Shibin Das (D34dMan)",
8
8
  "bugs": {
9
9
  "url": "https://github.com/flowdrop-io/flowdrop/issues"