@flowdrop/flowdrop 1.15.0 → 2.0.0-beta.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 (215) hide show
  1. package/CHANGELOG.md +475 -0
  2. package/MIGRATION-2.0.md +472 -0
  3. package/README.md +23 -23
  4. package/dist/adapters/WorkflowAdapter.d.ts +1 -1
  5. package/dist/adapters/WorkflowAdapter.js +14 -8
  6. package/dist/adapters/agentspec/AgentSpecAdapter.js +7 -7
  7. package/dist/chat/batchFeedback.d.ts +39 -0
  8. package/dist/chat/batchFeedback.js +51 -0
  9. package/dist/commands/executor.js +15 -1
  10. package/dist/commands/storeIntegration.svelte.d.ts +4 -1
  11. package/dist/commands/storeIntegration.svelte.js +26 -21
  12. package/dist/commands/types.d.ts +2 -0
  13. package/dist/components/App.svelte +162 -192
  14. package/dist/components/App.svelte.d.ts +47 -8
  15. package/dist/components/ConfigForm.svelte +71 -47
  16. package/dist/components/ConfigModal.svelte +7 -2
  17. package/dist/components/ConnectionLine.svelte +4 -2
  18. package/dist/components/Navbar.svelte +61 -1
  19. package/dist/components/NodeSidebar.svelte +27 -45
  20. package/dist/components/NodeStatusOverlay.svelte +94 -6
  21. package/dist/components/NodeSwapPicker.svelte +10 -8
  22. package/dist/components/PipelineStatus.svelte +16 -67
  23. package/dist/components/PortCoordinateTracker.svelte +5 -6
  24. package/dist/components/SchemaForm.stories.svelte +1 -3
  25. package/dist/components/SchemaForm.svelte +18 -25
  26. package/dist/components/SchemaForm.svelte.d.ts +0 -8
  27. package/dist/components/SettingsModal.svelte +8 -3
  28. package/dist/components/SettingsPanel.svelte +20 -4
  29. package/dist/components/SwapMappingEditor.svelte +67 -49
  30. package/dist/components/SwapMappingEditor.svelte.d.ts +0 -2
  31. package/dist/components/UniversalNode.svelte +9 -7
  32. package/dist/components/WorkflowEditor.svelte +118 -111
  33. package/dist/components/WorkflowEditor.svelte.d.ts +18 -10
  34. package/dist/components/chat/AIChatPanel.svelte +93 -89
  35. package/dist/components/chat/AIChatPanel.svelte.d.ts +0 -4
  36. package/dist/components/chat/CommandPreview.svelte +2 -1
  37. package/dist/components/console/CommandConsole.svelte +7 -5
  38. package/dist/components/console/ConsoleAutocomplete.svelte +10 -11
  39. package/dist/components/console/ConsoleAutocomplete.svelte.d.ts +6 -0
  40. package/dist/components/console/ConsoleInput.svelte +15 -6
  41. package/dist/components/console/ConsoleOutput.svelte +2 -1
  42. package/dist/components/form/FormArray.svelte +5 -9
  43. package/dist/components/form/FormArray.svelte.d.ts +2 -1
  44. package/dist/components/form/FormAutocomplete.svelte +8 -6
  45. package/dist/components/form/FormField.svelte +4 -2
  46. package/dist/components/form/FormFieldLight.svelte +4 -2
  47. package/dist/components/form/FormMarkdownEditor.svelte +9 -4
  48. package/dist/components/form/FormRangeField.svelte +1 -0
  49. package/dist/components/form/FormTemplateEditor.svelte +11 -3
  50. package/dist/components/form/FormToggle.svelte +5 -12
  51. package/dist/components/form/FormToggle.svelte.d.ts +4 -2
  52. package/dist/components/form/templateAutocomplete.js +1 -5
  53. package/dist/components/form/types.d.ts +1 -14
  54. package/dist/components/interrupt/FormPrompt.svelte +3 -2
  55. package/dist/components/interrupt/InterruptBubble.svelte +16 -17
  56. package/dist/components/interrupt/ReviewPrompt.svelte +10 -3
  57. package/dist/components/interrupt/TextInputPrompt.svelte +2 -1
  58. package/dist/components/layouts/MainLayout.svelte +20 -13
  59. package/dist/components/layouts/MainLayout.svelte.d.ts +4 -0
  60. package/dist/components/nodes/AtomNode.svelte +17 -5
  61. package/dist/components/nodes/GatewayNode.svelte +19 -10
  62. package/dist/components/nodes/IdeaNode.svelte +7 -0
  63. package/dist/components/nodes/SimpleNode.svelte +11 -6
  64. package/dist/components/nodes/SquareNode.svelte +15 -8
  65. package/dist/components/nodes/TerminalNode.svelte +9 -4
  66. package/dist/components/nodes/ToolNode.svelte +7 -1
  67. package/dist/components/nodes/WorkflowNode.svelte +16 -7
  68. package/dist/components/playground/ChatInput.svelte +11 -14
  69. package/dist/components/playground/ChatPanel.svelte +6 -49
  70. package/dist/components/playground/ChatPanel.svelte.d.ts +0 -14
  71. package/dist/components/playground/ControlPanel.svelte +134 -123
  72. package/dist/components/playground/ControlPanel.svelte.d.ts +3 -0
  73. package/dist/components/playground/ExecutionLogs.svelte +11 -9
  74. package/dist/components/playground/InputCollector.svelte +11 -9
  75. package/dist/components/playground/MessageStream.svelte +17 -23
  76. package/dist/components/playground/PipelineKanbanView.svelte +65 -6
  77. package/dist/components/playground/PipelinePanel.svelte +11 -5
  78. package/dist/components/playground/PipelineTableView.svelte +186 -44
  79. package/dist/components/playground/Playground.svelte +90 -92
  80. package/dist/components/playground/Playground.svelte.d.ts +2 -0
  81. package/dist/components/playground/PlaygroundApp.svelte +6 -1
  82. package/dist/components/playground/PlaygroundApp.svelte.d.ts +3 -0
  83. package/dist/components/playground/PlaygroundModal.svelte +13 -3
  84. package/dist/components/playground/PlaygroundModal.svelte.d.ts +3 -0
  85. package/dist/components/playground/PlaygroundStudio.svelte +34 -32
  86. package/dist/components/playground/PlaygroundStudio.svelte.d.ts +3 -0
  87. package/dist/components/playground/SessionManager.svelte +9 -12
  88. package/dist/components/playground/pipelineViewUtils.svelte.d.ts +28 -0
  89. package/dist/components/playground/pipelineViewUtils.svelte.js +38 -1
  90. package/dist/config/endpoints.d.ts +0 -7
  91. package/dist/config/endpoints.js +2 -10
  92. package/dist/core/index.d.ts +4 -4
  93. package/dist/core/index.js +6 -6
  94. package/dist/display/index.d.ts +0 -2
  95. package/dist/display/index.js +0 -6
  96. package/dist/editor/index.d.ts +19 -20
  97. package/dist/editor/index.js +25 -35
  98. package/dist/form/code.d.ts +25 -15
  99. package/dist/form/code.js +44 -41
  100. package/dist/form/fieldRegistry.d.ts +17 -13
  101. package/dist/form/fieldRegistry.js +32 -12
  102. package/dist/form/full.d.ts +17 -13
  103. package/dist/form/full.js +22 -27
  104. package/dist/form/index.d.ts +3 -3
  105. package/dist/form/index.js +3 -3
  106. package/dist/form/markdown.d.ts +13 -8
  107. package/dist/form/markdown.js +22 -23
  108. package/dist/helpers/proximityConnect.d.ts +3 -2
  109. package/dist/helpers/proximityConnect.js +2 -5
  110. package/dist/helpers/workflowEditorHelper.d.ts +12 -5
  111. package/dist/helpers/workflowEditorHelper.js +27 -25
  112. package/dist/index.d.ts +28 -24
  113. package/dist/index.js +27 -50
  114. package/dist/messages/defaults.d.ts +2 -5
  115. package/dist/messages/defaults.js +3 -6
  116. package/dist/messages/index.d.ts +0 -1
  117. package/dist/messages/index.js +0 -1
  118. package/dist/mocks/app-forms.d.ts +6 -2
  119. package/dist/mocks/app-forms.js +11 -4
  120. package/dist/openapi/v1/openapi.yaml +3 -3
  121. package/dist/playground/index.d.ts +2 -3
  122. package/dist/playground/index.js +2 -30
  123. package/dist/playground/mount.d.ts +15 -0
  124. package/dist/playground/mount.js +46 -20
  125. package/dist/registry/{BaseRegistry.d.ts → BaseRegistry.svelte.d.ts} +22 -1
  126. package/dist/registry/{BaseRegistry.js → BaseRegistry.svelte.js} +37 -1
  127. package/dist/registry/builtinFormats.d.ts +9 -18
  128. package/dist/registry/builtinFormats.js +9 -39
  129. package/dist/registry/builtinNodes.d.ts +0 -25
  130. package/dist/registry/builtinNodes.js +1 -50
  131. package/dist/registry/index.d.ts +3 -4
  132. package/dist/registry/index.js +4 -6
  133. package/dist/registry/nodeComponentRegistry.d.ts +182 -15
  134. package/dist/registry/nodeComponentRegistry.js +235 -17
  135. package/dist/registry/workflowFormatRegistry.d.ts +14 -9
  136. package/dist/registry/workflowFormatRegistry.js +24 -8
  137. package/dist/{schema → schemas}/index.d.ts +2 -2
  138. package/dist/{schema → schemas}/index.js +2 -2
  139. package/dist/schemas/v1/workflow.schema.json +3 -3
  140. package/dist/services/agentSpecExecutionService.js +0 -1
  141. package/dist/services/apiVariableService.d.ts +2 -1
  142. package/dist/services/apiVariableService.js +5 -22
  143. package/dist/services/autoSaveService.d.ts +7 -0
  144. package/dist/services/autoSaveService.js +6 -4
  145. package/dist/services/chatService.d.ts +8 -4
  146. package/dist/services/chatService.js +15 -15
  147. package/dist/services/draftStorage.d.ts +129 -13
  148. package/dist/services/draftStorage.js +185 -37
  149. package/dist/services/dynamicSchemaService.d.ts +2 -1
  150. package/dist/services/dynamicSchemaService.js +5 -22
  151. package/dist/services/globalSave.d.ts +13 -12
  152. package/dist/services/globalSave.js +29 -51
  153. package/dist/services/historyService.d.ts +9 -3
  154. package/dist/services/historyService.js +9 -3
  155. package/dist/services/interruptService.d.ts +14 -9
  156. package/dist/services/interruptService.js +27 -27
  157. package/dist/services/nodeExecutionService.d.ts +18 -3
  158. package/dist/services/nodeExecutionService.js +71 -45
  159. package/dist/services/playgroundService.d.ts +14 -9
  160. package/dist/services/playgroundService.js +31 -30
  161. package/dist/services/variableService.d.ts +2 -1
  162. package/dist/services/variableService.js +2 -2
  163. package/dist/services/workflowStorage.js +6 -6
  164. package/dist/stores/apiContext.d.ts +45 -0
  165. package/dist/stores/apiContext.js +65 -0
  166. package/dist/stores/categoriesStore.svelte.d.ts +28 -23
  167. package/dist/stores/categoriesStore.svelte.js +70 -64
  168. package/dist/stores/getInstance.svelte.d.ts +39 -0
  169. package/dist/stores/getInstance.svelte.js +65 -0
  170. package/dist/stores/historyStore.svelte.d.ts +77 -93
  171. package/dist/stores/historyStore.svelte.js +134 -160
  172. package/dist/stores/instanceContainer.svelte.d.ts +111 -0
  173. package/dist/stores/instanceContainer.svelte.js +114 -0
  174. package/dist/stores/interruptStore.svelte.d.ts +112 -82
  175. package/dist/stores/interruptStore.svelte.js +253 -226
  176. package/dist/stores/pipelinePanelStore.svelte.d.ts +27 -3
  177. package/dist/stores/pipelinePanelStore.svelte.js +61 -14
  178. package/dist/stores/playgroundStore.svelte.d.ts +169 -222
  179. package/dist/stores/playgroundStore.svelte.js +515 -580
  180. package/dist/stores/portCoordinateStore.svelte.d.ts +57 -51
  181. package/dist/stores/portCoordinateStore.svelte.js +109 -98
  182. package/dist/stores/settingsStore.svelte.d.ts +4 -1
  183. package/dist/stores/settingsStore.svelte.js +47 -12
  184. package/dist/stores/workflowStore.svelte.d.ts +178 -213
  185. package/dist/stores/workflowStore.svelte.js +449 -501
  186. package/dist/stories/EdgeDecorator.svelte +5 -2
  187. package/dist/stories/NodeDecorator.svelte +5 -3
  188. package/dist/svelte-app.d.ts +60 -10
  189. package/dist/svelte-app.js +157 -53
  190. package/dist/types/events.d.ts +6 -3
  191. package/dist/types/index.d.ts +33 -3
  192. package/dist/types/navbar.d.ts +7 -0
  193. package/dist/types/playground.d.ts +18 -3
  194. package/dist/types/settings.d.ts +13 -0
  195. package/dist/types/settings.js +1 -0
  196. package/dist/utils/colors.d.ts +47 -21
  197. package/dist/utils/colors.js +69 -68
  198. package/dist/utils/connections.d.ts +9 -15
  199. package/dist/utils/connections.js +13 -32
  200. package/dist/utils/duration.d.ts +13 -0
  201. package/dist/utils/duration.js +45 -0
  202. package/dist/utils/icons.d.ts +5 -2
  203. package/dist/utils/icons.js +6 -5
  204. package/dist/utils/nodeSwap.d.ts +6 -2
  205. package/dist/utils/nodeSwap.js +62 -126
  206. package/dist/utils/nodeTypes.d.ts +17 -8
  207. package/dist/utils/nodeTypes.js +26 -19
  208. package/dist/utils/performanceUtils.js +7 -0
  209. package/package.json +6 -5
  210. package/dist/messages/deprecation.d.ts +0 -20
  211. package/dist/messages/deprecation.js +0 -33
  212. package/dist/registry/plugin.d.ts +0 -215
  213. package/dist/registry/plugin.js +0 -249
  214. package/dist/services/api.d.ts +0 -129
  215. package/dist/services/api.js +0 -217
package/dist/form/full.js CHANGED
@@ -14,8 +14,8 @@
14
14
  * // Single import that sets up everything
15
15
  * import { SchemaForm, initializeAllFieldTypes } from "@flowdrop/flowdrop/form/full";
16
16
  *
17
- * // Call once at app startup
18
- * initializeAllFieldTypes();
17
+ * // Call once at app startup, against an instance's field registry
18
+ * initializeAllFieldTypes(fd.fields);
19
19
  *
20
20
  * // Now all field types are available
21
21
  * ```
@@ -26,7 +26,7 @@ export { SchemaForm, FormField, FormFieldFull, FormFieldWrapper, FormTextField,
26
26
  // Utility functions
27
27
  export { isFieldOptionArray, isOneOfArray, normalizeOptions, oneOfToOptions, getSchemaOptions } from './index.js';
28
28
  // Field Registry
29
- export { fieldComponentRegistry, hiddenFieldMatcher, checkboxGroupMatcher, enumSelectMatcher, textareaMatcher, rangeMatcher, textFieldMatcher, numberFieldMatcher, toggleMatcher, selectOptionsMatcher, arrayMatcher } from './index.js';
29
+ export { FieldComponentRegistry, hiddenFieldMatcher, checkboxGroupMatcher, enumSelectMatcher, textareaMatcher, rangeMatcher, textFieldMatcher, numberFieldMatcher, toggleMatcher, selectOptionsMatcher, arrayMatcher } from './index.js';
30
30
  // Import registration functions
31
31
  import { registerCodeEditorField, registerTemplateEditorField } from './code.js';
32
32
  import { registerMarkdownEditorField } from './markdown.js';
@@ -36,45 +36,40 @@ export { FormMarkdownEditor } from './markdown.js';
36
36
  // Re-export registration functions
37
37
  export { registerCodeEditorField, registerTemplateEditorField, registerAllCodeEditors, isCodeEditorRegistered, isTemplateEditorRegistered, codeEditorFieldMatcher, templateEditorFieldMatcher } from './code.js';
38
38
  export { registerMarkdownEditorField, isMarkdownEditorRegistered, markdownEditorFieldMatcher } from './markdown.js';
39
- /**
40
- * Track if all field types have been initialized
41
- */
42
- let allFieldTypesInitialized = false;
43
39
  /**
44
40
  * Initialize all form field types including heavy editors
45
41
  *
46
- * Call this once at application startup to enable all field types.
47
- * This includes:
42
+ * Call this once at application startup to enable all field types in the
43
+ * given instance's field registry. This includes:
48
44
  * - Code/JSON editor (CodeMirror)
49
45
  * - Template editor (CodeMirror with Twig/Liquid syntax)
50
46
  * - Markdown editor (CodeMirror 6)
51
47
  *
48
+ * Registration is idempotent per registry — each `register*Field` is a no-op
49
+ * if its field type is already present (see `FieldComponentRegistry.has`).
50
+ *
51
+ * @param registry - The instance's field registry (e.g. `fd.fields`)
52
+ *
52
53
  * @example
53
54
  * ```typescript
54
55
  * import { initializeAllFieldTypes } from "@flowdrop/flowdrop/form/full";
55
56
  *
56
57
  * // In your app's entry point
57
- * initializeAllFieldTypes();
58
+ * initializeAllFieldTypes(fd.fields);
58
59
  * ```
59
60
  */
60
- export function initializeAllFieldTypes() {
61
- if (allFieldTypesInitialized) {
62
- return;
63
- }
64
- registerCodeEditorField();
65
- registerTemplateEditorField();
66
- registerMarkdownEditorField();
67
- allFieldTypesInitialized = true;
61
+ export function initializeAllFieldTypes(registry) {
62
+ registerCodeEditorField(registry);
63
+ registerTemplateEditorField(registry);
64
+ registerMarkdownEditorField(registry);
68
65
  }
69
66
  /**
70
- * Check if all field types have been initialized
71
- */
72
- export function areAllFieldTypesInitialized() {
73
- return allFieldTypesInitialized;
74
- }
75
- /**
76
- * Reset initialization state (useful for testing)
67
+ * Check if all heavy field types are registered in the given registry.
68
+ *
69
+ * @param registry - The instance's field registry (e.g. `fd.fields`)
77
70
  */
78
- export function resetFieldTypeInitialization() {
79
- allFieldTypesInitialized = false;
71
+ export function areAllFieldTypesInitialized(registry) {
72
+ return (registry.has('code-editor') &&
73
+ registry.has('template-editor') &&
74
+ registry.has('markdown-editor'));
80
75
  }
@@ -71,13 +71,13 @@ export { default as FormCheckboxGroup } from '../components/form/FormCheckboxGro
71
71
  export { default as FormArray } from '../components/form/FormArray.svelte';
72
72
  export { default as FormFieldset } from '../components/form/FormFieldset.svelte';
73
73
  export { default as FormUISchemaRenderer } from '../components/form/FormUISchemaRenderer.svelte';
74
- export type { FieldSchema, FieldType, FieldFormat, FieldOption, OneOfItem, SchemaFormProps, BaseFieldProps, TextFieldProps, TextareaFieldProps, NumberFieldProps, ToggleFieldProps, RangeFieldProps, SelectFieldProps, CheckboxGroupFieldProps, ArrayFieldProps, FormFieldFactoryProps, FormFieldWrapperProps } from '../components/form/types.js';
74
+ export type { FieldSchema, FieldType, FieldFormat, FieldOption, OneOfItem, SchemaFormProps, BaseFieldProps, TextFieldProps, TextareaFieldProps, NumberFieldProps, ToggleFieldProps, RangeFieldProps, SelectFieldProps, CheckboxGroupFieldProps, ArrayFieldProps, FormFieldFactoryProps, FormFieldWrapperProps, AutocompleteConfig } from '../components/form/types.js';
75
75
  export { isFieldOptionArray, isOneOfArray, normalizeOptions, oneOfToOptions, getSchemaOptions } from '../components/form/types.js';
76
- export { fieldComponentRegistry, hiddenFieldMatcher, checkboxGroupMatcher, enumSelectMatcher, textareaMatcher, rangeMatcher, textFieldMatcher, numberFieldMatcher, toggleMatcher, selectOptionsMatcher, arrayMatcher } from './fieldRegistry.js';
76
+ export { FieldComponentRegistry, hiddenFieldMatcher, checkboxGroupMatcher, enumSelectMatcher, textareaMatcher, rangeMatcher, textFieldMatcher, numberFieldMatcher, toggleMatcher, selectOptionsMatcher, arrayMatcher } from './fieldRegistry.js';
77
77
  export type { FieldComponentProps, FieldMatcher, FieldMatcherRegistration, FieldComponent, FieldComponentRegistration } from './fieldRegistry.js';
78
78
  /**
79
79
  * Use with Svelte's `getContext` inside custom field components registered
80
- * via `fieldComponentRegistry` to read sibling form field values.
80
+ * via `fd.fields` to read sibling form field values.
81
81
  *
82
82
  * @example
83
83
  * ```svelte
@@ -85,8 +85,8 @@ export { isFieldOptionArray, isOneOfArray, normalizeOptions, oneOfToOptions, get
85
85
  // Field Registry (for dynamic field registration)
86
86
  // ============================================================================
87
87
  export {
88
- // Registry singleton
89
- fieldComponentRegistry,
88
+ // Registry class (instances live on `fd.fields`)
89
+ FieldComponentRegistry,
90
90
  // Built-in matchers for custom components
91
91
  hiddenFieldMatcher, checkboxGroupMatcher, enumSelectMatcher, textareaMatcher, rangeMatcher, textFieldMatcher, numberFieldMatcher, toggleMatcher, selectOptionsMatcher, arrayMatcher } from './fieldRegistry.js';
92
92
  // ============================================================================
@@ -94,7 +94,7 @@ hiddenFieldMatcher, checkboxGroupMatcher, enumSelectMatcher, textareaMatcher, ra
94
94
  // ============================================================================
95
95
  /**
96
96
  * Use with Svelte's `getContext` inside custom field components registered
97
- * via `fieldComponentRegistry` to read sibling form field values.
97
+ * via `fd.fields` to read sibling form field values.
98
98
  *
99
99
  * @example
100
100
  * ```svelte
@@ -12,7 +12,7 @@
12
12
  * import { registerMarkdownEditorField } from "@flowdrop/flowdrop/form/markdown";
13
13
  *
14
14
  * // Register markdown editor support (call once at app startup)
15
- * registerMarkdownEditorField();
15
+ * registerMarkdownEditorField(fd.fields);
16
16
  *
17
17
  * // Now SchemaForm will render markdown editors for format: "markdown"
18
18
  * const schema = {
@@ -23,7 +23,7 @@
23
23
  * };
24
24
  * ```
25
25
  */
26
- import type { FieldComponent } from './fieldRegistry.js';
26
+ import type { FieldComponent, FieldComponentRegistry } from './fieldRegistry.js';
27
27
  import type { FieldSchema } from '../components/form/types.js';
28
28
  export { default as FormMarkdownEditor } from '../components/form/FormMarkdownEditor.svelte';
29
29
  export type { MarkdownEditorFieldProps } from '../components/form/types.js';
@@ -38,6 +38,7 @@ export declare function markdownEditorFieldMatcher(schema: FieldSchema): boolean
38
38
  * Call this function once at application startup to enable
39
39
  * markdown editor fields in SchemaForm.
40
40
  *
41
+ * @param registry - The instance's field registry (e.g. `fd.fields`)
41
42
  * @param priority - Priority for field matching (default: 100)
42
43
  *
43
44
  * @example
@@ -45,25 +46,29 @@ export declare function markdownEditorFieldMatcher(schema: FieldSchema): boolean
45
46
  * // In your app's entry point:
46
47
  * import { registerMarkdownEditorField } from "@flowdrop/flowdrop/form/markdown";
47
48
  *
48
- * registerMarkdownEditorField();
49
+ * registerMarkdownEditorField(fd.fields);
49
50
  * ```
50
51
  */
51
- export declare function registerMarkdownEditorField(priority?: number): void;
52
+ export declare function registerMarkdownEditorField(registry: FieldComponentRegistry, priority?: number): void;
52
53
  /**
53
54
  * Synchronously register markdown editor field using the imported component
54
55
  *
55
56
  * Use this when you've already imported the component and want immediate registration.
56
57
  *
58
+ * @param registry - The instance's field registry (e.g. `fd.fields`)
59
+ * @param component - The pre-imported markdown editor component
57
60
  * @param priority - Priority for field matching (default: 100)
58
61
  *
59
62
  * @example
60
63
  * ```typescript
61
64
  * import { registerMarkdownEditorFieldWithComponent, FormMarkdownEditor } from "@flowdrop/flowdrop/form/markdown";
62
- * registerMarkdownEditorFieldWithComponent(FormMarkdownEditor);
65
+ * registerMarkdownEditorFieldWithComponent(fd.fields, FormMarkdownEditor);
63
66
  * ```
64
67
  */
65
- export declare function registerMarkdownEditorFieldWithComponent(component: FieldComponent, priority?: number): void;
68
+ export declare function registerMarkdownEditorFieldWithComponent(registry: FieldComponentRegistry, component: FieldComponent, priority?: number): void;
66
69
  /**
67
- * Check if markdown editor field is registered
70
+ * Check if markdown editor field is registered in the given registry.
71
+ *
72
+ * @param registry - The instance's field registry (e.g. `fd.fields`)
68
73
  */
69
- export declare function isMarkdownEditorRegistered(): boolean;
74
+ export declare function isMarkdownEditorRegistered(registry: FieldComponentRegistry): boolean;
@@ -12,7 +12,7 @@
12
12
  * import { registerMarkdownEditorField } from "@flowdrop/flowdrop/form/markdown";
13
13
  *
14
14
  * // Register markdown editor support (call once at app startup)
15
- * registerMarkdownEditorField();
15
+ * registerMarkdownEditorField(fd.fields);
16
16
  *
17
17
  * // Now SchemaForm will render markdown editors for format: "markdown"
18
18
  * const schema = {
@@ -23,7 +23,6 @@
23
23
  * };
24
24
  * ```
25
25
  */
26
- import { fieldComponentRegistry } from './fieldRegistry.js';
27
26
  // Re-export the component for direct usage if needed
28
27
  export { default as FormMarkdownEditor } from '../components/form/FormMarkdownEditor.svelte';
29
28
  /**
@@ -33,20 +32,13 @@ export { default as FormMarkdownEditor } from '../components/form/FormMarkdownEd
33
32
  export function markdownEditorFieldMatcher(schema) {
34
33
  return schema.format === 'markdown';
35
34
  }
36
- /**
37
- * Track if markdown editor is registered
38
- */
39
- let markdownEditorRegistered = false;
40
- // Sync registration flag with registry.clear() for test isolation
41
- fieldComponentRegistry.onClear(() => {
42
- markdownEditorRegistered = false;
43
- });
44
35
  /**
45
36
  * Register the markdown editor field component
46
37
  *
47
38
  * Call this function once at application startup to enable
48
39
  * markdown editor fields in SchemaForm.
49
40
  *
41
+ * @param registry - The instance's field registry (e.g. `fd.fields`)
50
42
  * @param priority - Priority for field matching (default: 100)
51
43
  *
52
44
  * @example
@@ -54,21 +46,25 @@ fieldComponentRegistry.onClear(() => {
54
46
  * // In your app's entry point:
55
47
  * import { registerMarkdownEditorField } from "@flowdrop/flowdrop/form/markdown";
56
48
  *
57
- * registerMarkdownEditorField();
49
+ * registerMarkdownEditorField(fd.fields);
58
50
  * ```
59
51
  */
60
- export function registerMarkdownEditorField(priority = 100) {
61
- if (markdownEditorRegistered) {
52
+ export function registerMarkdownEditorField(registry, priority = 100) {
53
+ if (registry.has('markdown-editor')) {
62
54
  return;
63
55
  }
64
56
  // Dynamic import to ensure proper code splitting
65
57
  import('../components/form/FormMarkdownEditor.svelte').then((module) => {
66
- fieldComponentRegistry.register('markdown-editor', {
58
+ // Re-check inside the async callback: two rapid synchronous calls both pass
59
+ // the guard above before either import resolves, so guard again here.
60
+ if (registry.has('markdown-editor')) {
61
+ return;
62
+ }
63
+ registry.register('markdown-editor', {
67
64
  component: module.default,
68
65
  matcher: markdownEditorFieldMatcher,
69
66
  priority
70
67
  });
71
- markdownEditorRegistered = true;
72
68
  });
73
69
  }
74
70
  /**
@@ -76,28 +72,31 @@ export function registerMarkdownEditorField(priority = 100) {
76
72
  *
77
73
  * Use this when you've already imported the component and want immediate registration.
78
74
  *
75
+ * @param registry - The instance's field registry (e.g. `fd.fields`)
76
+ * @param component - The pre-imported markdown editor component
79
77
  * @param priority - Priority for field matching (default: 100)
80
78
  *
81
79
  * @example
82
80
  * ```typescript
83
81
  * import { registerMarkdownEditorFieldWithComponent, FormMarkdownEditor } from "@flowdrop/flowdrop/form/markdown";
84
- * registerMarkdownEditorFieldWithComponent(FormMarkdownEditor);
82
+ * registerMarkdownEditorFieldWithComponent(fd.fields, FormMarkdownEditor);
85
83
  * ```
86
84
  */
87
- export function registerMarkdownEditorFieldWithComponent(component, priority = 100) {
88
- if (markdownEditorRegistered) {
85
+ export function registerMarkdownEditorFieldWithComponent(registry, component, priority = 100) {
86
+ if (registry.has('markdown-editor')) {
89
87
  return;
90
88
  }
91
- fieldComponentRegistry.register('markdown-editor', {
89
+ registry.register('markdown-editor', {
92
90
  component,
93
91
  matcher: markdownEditorFieldMatcher,
94
92
  priority
95
93
  });
96
- markdownEditorRegistered = true;
97
94
  }
98
95
  /**
99
- * Check if markdown editor field is registered
96
+ * Check if markdown editor field is registered in the given registry.
97
+ *
98
+ * @param registry - The instance's field registry (e.g. `fd.fields`)
100
99
  */
101
- export function isMarkdownEditorRegistered() {
102
- return markdownEditorRegistered;
100
+ export function isMarkdownEditorRegistered(registry) {
101
+ return registry.has('markdown-editor');
103
102
  }
@@ -6,6 +6,7 @@
6
6
  * compatible port pair and creates a preview/permanent edge.
7
7
  */
8
8
  import type { WorkflowNode as WorkflowNodeType, WorkflowEdge, NodePort, PortCoordinateMap } from '../types/index.js';
9
+ import type { PortCompatibilityChecker } from '../utils/connections.js';
9
10
  /** A candidate proximity edge before it is finalized */
10
11
  export interface ProximityEdgeCandidate {
11
12
  id: string;
@@ -61,7 +62,7 @@ export declare class ProximityConnectHelper {
61
62
  *
62
63
  * @returns Array with at most ONE ProximityEdgeCandidate
63
64
  */
64
- static findCompatibleEdges(draggedNode: WorkflowNodeType, allNodes: WorkflowNodeType[], existingEdges: WorkflowEdge[], minDistance: number): ProximityEdgeCandidate[];
65
+ static findCompatibleEdges(checker: PortCompatibilityChecker, draggedNode: WorkflowNodeType, allNodes: WorkflowNodeType[], existingEdges: WorkflowEdge[], minDistance: number): ProximityEdgeCandidate[];
65
66
  /**
66
67
  * Find the single best compatible edge using port-to-port distance.
67
68
  *
@@ -77,7 +78,7 @@ export declare class ProximityConnectHelper {
77
78
  *
78
79
  * @returns Array with at most ONE ProximityEdgeCandidate
79
80
  */
80
- static findCompatibleEdgesByPortCoordinates(draggedNodeId: string, portCoordinates: PortCoordinateMap, existingEdges: WorkflowEdge[], maxDistance: number): ProximityEdgeCandidate[];
81
+ static findCompatibleEdgesByPortCoordinates(checker: PortCompatibilityChecker, draggedNodeId: string, portCoordinates: PortCoordinateMap, existingEdges: WorkflowEdge[], maxDistance: number): ProximityEdgeCandidate[];
81
82
  /**
82
83
  * Convert candidates to temporary (preview) WorkflowEdge objects with dashed styling.
83
84
  */
@@ -6,7 +6,6 @@
6
6
  * compatible port pair and creates a preview/permanent edge.
7
7
  */
8
8
  import { dynamicPortToNodePort } from '../types/index.js';
9
- import { getPortCompatibilityChecker } from '../utils/connections.js';
10
9
  import { v4 as uuidv4 } from 'uuid';
11
10
  /** CSS class applied to proximity preview edges */
12
11
  const PROXIMITY_EDGE_CLASS = 'flowdrop--edge--proximity-preview';
@@ -86,8 +85,7 @@ export class ProximityConnectHelper {
86
85
  *
87
86
  * @returns Array with at most ONE ProximityEdgeCandidate
88
87
  */
89
- static findCompatibleEdges(draggedNode, allNodes, existingEdges, minDistance) {
90
- const checker = getPortCompatibilityChecker();
88
+ static findCompatibleEdges(checker, draggedNode, allNodes, existingEdges, minDistance) {
91
89
  // Build lookup set for O(1) duplicate checks
92
90
  const existingEdgeSet = new Set(existingEdges.map((e) => `${e.source}:${e.sourceHandle}->${e.target}:${e.targetHandle}`));
93
91
  // Find the closest node within distance
@@ -198,8 +196,7 @@ export class ProximityConnectHelper {
198
196
  *
199
197
  * @returns Array with at most ONE ProximityEdgeCandidate
200
198
  */
201
- static findCompatibleEdgesByPortCoordinates(draggedNodeId, portCoordinates, existingEdges, maxDistance) {
202
- const checker = getPortCompatibilityChecker();
199
+ static findCompatibleEdgesByPortCoordinates(checker, draggedNodeId, portCoordinates, existingEdges, maxDistance) {
203
200
  // Build lookup set for O(1) duplicate checks
204
201
  const existingEdgeSet = new Set(existingEdges.map((e) => `${e.source}:${e.sourceHandle}->${e.target}:${e.targetHandle}`));
205
202
  // Partition ports by owner and direction, group other-node ports by dataType
@@ -3,6 +3,8 @@
3
3
  * Contains business logic for workflow operations
4
4
  */
5
5
  import type { WorkflowNode as WorkflowNodeType, NodeMetadata, Workflow, WorkflowEdge, NodeExecutionInfo } from '../types/index.js';
6
+ import { type FlowDropInstance } from '../stores/instanceContainer.svelte.js';
7
+ import type { ApiContext } from '../stores/apiContext.js';
6
8
  import type { EndpointConfig } from '../config/endpoints.js';
7
9
  export { generateNodeId, extractConfigDefaults } from '../utils/nodeIds.js';
8
10
  /**
@@ -33,11 +35,11 @@ export declare class NodeOperationsHelper {
33
35
  /**
34
36
  * Load nodes from API
35
37
  */
36
- static loadNodesFromApi(providedNodes?: NodeMetadata[]): Promise<NodeMetadata[]>;
38
+ static loadNodesFromApi(api: ApiContext, providedNodes?: NodeMetadata[]): Promise<NodeMetadata[]>;
37
39
  /**
38
40
  * Load node execution information for all nodes in the workflow
39
41
  */
40
- static loadNodeExecutionInfo(workflow: Workflow | null, pipelineId?: string): Promise<Record<string, NodeExecutionInfo>>;
42
+ static loadNodeExecutionInfo(api: ApiContext, workflow: Workflow | null, pipelineId?: string): Promise<Record<string, NodeExecutionInfo>>;
41
43
  /**
42
44
  * Create a new node from dropped data
43
45
  */
@@ -72,8 +74,13 @@ export declare class WorkflowOperationsHelper {
72
74
  static addNode(workflow: Workflow, node: WorkflowNodeType): Workflow;
73
75
  /**
74
76
  * Save workflow to backend
77
+ *
78
+ * @param api - The instance's API context (endpoints + client)
79
+ * @param workflow - The workflow to save
80
+ * @param instance - The FlowDrop instance whose store should be synced when
81
+ * the server assigns a new ID; defaults to the page-default instance
75
82
  */
76
- static saveWorkflow(workflow: Workflow | null): Promise<Workflow | null>;
83
+ static saveWorkflow(api: ApiContext, workflow: Workflow | null, instance?: FlowDropInstance): Promise<Workflow | null>;
77
84
  /**
78
85
  * Export workflow as JSON file
79
86
  */
@@ -127,7 +134,7 @@ export declare class WorkflowOperationsHelper {
127
134
  */
128
135
  export declare class ConfigurationHelper {
129
136
  /**
130
- * Configure API endpoints
137
+ * Configure API endpoints on the given instance's API context.
131
138
  */
132
- static configureEndpoints(config: EndpointConfig): void;
139
+ static configureEndpoints(api: ApiContext, config: EndpointConfig): void;
133
140
  }
@@ -3,9 +3,8 @@
3
3
  * Contains business logic for workflow operations
4
4
  */
5
5
  import { hasCycles, hasInvalidCycles } from '../utils/connections.js';
6
- import { workflowApi, nodeApi, setEndpointConfig } from '../services/api.js';
7
6
  import { v4 as uuidv4 } from 'uuid';
8
- import { workflowActions } from '../stores/workflowStore.svelte.js';
7
+ import { getDefaultInstance } from '../stores/instanceContainer.svelte.js';
9
8
  import { nodeExecutionService } from '../services/nodeExecutionService.js';
10
9
  import { WorkflowAdapter } from '../adapters/WorkflowAdapter.js';
11
10
  import { AgentSpecAdapter } from '../adapters/agentspec/AgentSpecAdapter.js';
@@ -49,14 +48,14 @@ export class NodeOperationsHelper {
49
48
  /**
50
49
  * Load nodes from API
51
50
  */
52
- static async loadNodesFromApi(providedNodes) {
51
+ static async loadNodesFromApi(api, providedNodes) {
53
52
  // If nodes are provided via props, use them
54
53
  if (providedNodes && providedNodes.length > 0) {
55
54
  return providedNodes;
56
55
  }
57
56
  // Otherwise, load from API
58
57
  try {
59
- const fetchedNodes = await nodeApi.getNodes();
58
+ const fetchedNodes = await api.client.getAvailableNodes();
60
59
  return fetchedNodes;
61
60
  }
62
61
  catch (error) {
@@ -89,7 +88,7 @@ export class NodeOperationsHelper {
89
88
  /**
90
89
  * Load node execution information for all nodes in the workflow
91
90
  */
92
- static async loadNodeExecutionInfo(workflow, pipelineId) {
91
+ static async loadNodeExecutionInfo(api, workflow, pipelineId) {
93
92
  if (!workflow?.nodes)
94
93
  return {};
95
94
  // Only load execution info if we have a pipelineId (for pipeline status mode)
@@ -97,7 +96,7 @@ export class NodeOperationsHelper {
97
96
  return {};
98
97
  try {
99
98
  const nodeIds = workflow.nodes.map((node) => node.id);
100
- const executionInfo = await nodeExecutionService.getMultipleNodeExecutionInfo(nodeIds, pipelineId);
99
+ const executionInfo = await nodeExecutionService.getMultipleNodeExecutionInfo(api.config, nodeIds, pipelineId);
101
100
  return executionInfo;
102
101
  }
103
102
  catch (error) {
@@ -160,7 +159,7 @@ export class WorkflowOperationsHelper {
160
159
  static generateMetadata(existingMetadata) {
161
160
  const now = new Date().toISOString();
162
161
  return {
163
- version: '1.0.0',
162
+ schemaVersion: '1.0.0',
164
163
  createdAt: now,
165
164
  ...(existingMetadata ?? {}),
166
165
  updatedAt: now,
@@ -217,38 +216,41 @@ export class WorkflowOperationsHelper {
217
216
  }
218
217
  /**
219
218
  * Save workflow to backend
219
+ *
220
+ * @param api - The instance's API context (endpoints + client)
221
+ * @param workflow - The workflow to save
222
+ * @param instance - The FlowDrop instance whose store should be synced when
223
+ * the server assigns a new ID; defaults to the page-default instance
220
224
  */
221
- static async saveWorkflow(workflow) {
225
+ static async saveWorkflow(api, workflow, instance) {
222
226
  if (!workflow) {
223
227
  logger.warn('No workflow data available to save');
224
228
  return null;
225
229
  }
226
230
  try {
227
- // Determine the workflow ID based on whether we have an existing workflow
228
- let workflowId;
229
- if (workflow.id) {
230
- // Use the existing workflow ID
231
- workflowId = workflow.id;
232
- }
233
- else {
234
- // Generate a new UUID for a new workflow
235
- workflowId = uuidv4();
236
- }
231
+ // Determine new vs existing BEFORE the uuidv4() fallback: a present id (any
232
+ // format) means the workflow came from a backend and must be updated. Only
233
+ // a missing id means "truly new".
234
+ const isExistingWorkflow = !!workflow.id;
235
+ const workflowId = workflow.id || uuidv4();
237
236
  const workflowToSave = {
238
237
  id: workflowId,
239
238
  name: workflow.name || 'Untitled Workflow',
240
239
  nodes: workflow.nodes || [],
241
240
  edges: workflow.edges || [],
242
241
  metadata: {
243
- version: '1.0.0',
242
+ schemaVersion: workflow.metadata?.schemaVersion || '1.0.0',
244
243
  createdAt: workflow.metadata?.createdAt || new Date().toISOString(),
245
244
  updatedAt: new Date().toISOString()
246
245
  }
247
246
  };
248
- const savedWorkflow = await workflowApi.saveWorkflow(workflowToSave);
247
+ const savedWorkflow = isExistingWorkflow
248
+ ? await api.client.updateWorkflow(workflowToSave.id, workflowToSave)
249
+ : await api.client.saveWorkflow(workflowToSave);
249
250
  // Update the workflow ID if it changed (new workflow)
250
251
  if (savedWorkflow.id && savedWorkflow.id !== workflowToSave.id) {
251
- workflowActions.batchUpdate({
252
+ const fd = instance ?? getDefaultInstance();
253
+ fd.workflow.batchUpdate({
252
254
  nodes: workflowToSave.nodes,
253
255
  edges: workflowToSave.edges,
254
256
  name: workflowToSave.name,
@@ -281,7 +283,7 @@ export class WorkflowOperationsHelper {
281
283
  nodes: workflow.nodes || [],
282
284
  edges: workflow.edges || [],
283
285
  metadata: {
284
- version: '1.0.0',
286
+ schemaVersion: workflow.metadata?.schemaVersion || '1.0.0',
285
287
  createdAt: workflow.metadata?.createdAt || new Date().toISOString(),
286
288
  updatedAt: new Date().toISOString()
287
289
  }
@@ -380,9 +382,9 @@ export class WorkflowOperationsHelper {
380
382
  */
381
383
  export class ConfigurationHelper {
382
384
  /**
383
- * Configure API endpoints
385
+ * Configure API endpoints on the given instance's API context.
384
386
  */
385
- static configureEndpoints(config) {
386
- setEndpointConfig(config);
387
+ static configureEndpoints(api, config) {
388
+ api.configure(config);
387
389
  }
388
390
  }
package/dist/index.d.ts CHANGED
@@ -1,37 +1,41 @@
1
1
  /**
2
2
  * FlowDrop - Visual Workflow Editor Library
3
3
  *
4
- * A Svelte 5 component library built on @xyflow/svelte for creating node-based workflow editors.
4
+ * A Svelte 5 component library built on @xyflow/svelte for creating node-based
5
+ * workflow editors.
5
6
  *
6
- * ## Module Structure (Tree-Shakable)
7
+ * ## The main entry is a minimal front door
7
8
  *
8
- * For optimal bundle size, import from specific sub-modules:
9
+ * This entry point intentionally exposes only the small surface most apps need
10
+ * to get started: the `App` component, the `mountFlowDropApp` / `unmountFlowDropApp`
11
+ * mount helpers, instance plumbing (`createFlowDropInstance` / `getInstance` /
12
+ * `provideInstance`), endpoint + auth helpers, and the core public types. It does
13
+ * NOT re-export the entire library.
9
14
  *
10
- * - `@flowdrop/flowdrop/core` - Types and utilities only (no heavy deps)
11
- * - `@flowdrop/flowdrop/editor` - WorkflowEditor with @xyflow/svelte
15
+ * Everything else lives in focused sub-modules import from the one you need:
16
+ *
17
+ * - `@flowdrop/flowdrop/core` - Types, utilities, theme/skin, messages helpers (no heavy deps)
18
+ * - `@flowdrop/flowdrop/editor` - WorkflowEditor, registries, stores, services (adds @xyflow/svelte)
12
19
  * - `@flowdrop/flowdrop/form` - SchemaForm with basic fields
13
- * - `@flowdrop/flowdrop/form/code` - Code editor support (adds CodeMirror)
14
- * - `@flowdrop/flowdrop/form/markdown` - Markdown editor support (CodeMirror 6)
20
+ * - `@flowdrop/flowdrop/form/code` - Code editor field (adds CodeMirror)
21
+ * - `@flowdrop/flowdrop/form/markdown` - Markdown editor field (CodeMirror 6)
15
22
  * - `@flowdrop/flowdrop/display` - MarkdownDisplay (adds marked)
16
23
  * - `@flowdrop/flowdrop/playground` - Playground for interactive workflow testing
24
+ * - `@flowdrop/flowdrop/settings` - Settings stores, services, components
17
25
  * - `@flowdrop/flowdrop/styles` - CSS styles
18
26
  *
19
- * ## Legacy Import (Full Bundle)
20
- *
21
- * Importing from the main entry point includes everything:
22
- *
23
- * ```typescript
24
- * import { WorkflowEditor, SchemaForm } from "@flowdrop/flowdrop";
25
- * ```
26
- *
27
- * **Note**: This will bundle ALL dependencies including @xyflow/svelte,
28
- * CodeMirror and marked. For smaller bundles, use sub-modules.
29
- *
30
27
  * @module flowdrop
31
28
  */
32
- export * from './core/index.js';
33
- export * from './form/index.js';
34
- export * from './display/index.js';
35
- export * from './playground/index.js';
36
- export * from './editor/index.js';
37
- export * from './settings/index.js';
29
+ export { default as App } from './components/App.svelte';
30
+ export { mountFlowDropApp, unmountFlowDropApp } from './svelte-app.js';
31
+ export { createFlowDropInstance } from './stores/instanceContainer.svelte.js';
32
+ export { getInstance, provideInstance } from './stores/getInstance.svelte.js';
33
+ export { createEndpointConfig, defaultEndpointConfig } from './config/endpoints.js';
34
+ export { NoAuthProvider, StaticAuthProvider, CallbackAuthProvider } from './types/auth.js';
35
+ export type { Workflow, WorkflowNode, WorkflowEdge, NodeMetadata, ConfigSchema } from './types/index.js';
36
+ export type { EndpointConfig } from './config/endpoints.js';
37
+ export type { AuthProvider } from './types/auth.js';
38
+ export type { FlowDropInstance } from './stores/instanceContainer.svelte.js';
39
+ export type { FlowDropMountOptions, MountedFlowDropApp } from './svelte-app.js';
40
+ export type { FlowDropEventHandlers } from './types/events.js';
41
+ export type { Messages, MessagesOverride } from './messages/index.js';