@flowdrop/flowdrop 1.15.0 → 2.0.0-beta.2

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 (235) hide show
  1. package/CHANGELOG.md +508 -0
  2. package/MIGRATION-2.0.md +629 -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/api/enhanced-client.js +6 -11
  8. package/dist/chat/batchFeedback.d.ts +39 -0
  9. package/dist/chat/batchFeedback.js +51 -0
  10. package/dist/commands/executor.js +15 -1
  11. package/dist/commands/storeIntegration.svelte.d.ts +4 -1
  12. package/dist/commands/storeIntegration.svelte.js +26 -21
  13. package/dist/commands/types.d.ts +2 -0
  14. package/dist/components/App.svelte +163 -192
  15. package/dist/components/App.svelte.d.ts +47 -8
  16. package/dist/components/ConfigForm.svelte +77 -49
  17. package/dist/components/ConfigModal.svelte +7 -2
  18. package/dist/components/ConnectionLine.svelte +4 -2
  19. package/dist/components/Navbar.svelte +61 -1
  20. package/dist/components/NodeSidebar.svelte +27 -45
  21. package/dist/components/NodeStatusOverlay.svelte +94 -6
  22. package/dist/components/NodeSwapPicker.svelte +10 -8
  23. package/dist/components/PipelineStatus.svelte +22 -68
  24. package/dist/components/PipelineStatus.svelte.d.ts +3 -0
  25. package/dist/components/PortCoordinateTracker.svelte +5 -6
  26. package/dist/components/SchemaForm.stories.svelte +1 -3
  27. package/dist/components/SchemaForm.svelte +22 -27
  28. package/dist/components/SchemaForm.svelte.d.ts +0 -8
  29. package/dist/components/SettingsModal.svelte +8 -3
  30. package/dist/components/SettingsPanel.svelte +20 -4
  31. package/dist/components/SwapMappingEditor.svelte +67 -49
  32. package/dist/components/SwapMappingEditor.svelte.d.ts +0 -2
  33. package/dist/components/UniversalNode.svelte +9 -7
  34. package/dist/components/WorkflowEditor.svelte +121 -111
  35. package/dist/components/WorkflowEditor.svelte.d.ts +21 -10
  36. package/dist/components/chat/AIChatPanel.svelte +98 -89
  37. package/dist/components/chat/AIChatPanel.svelte.d.ts +0 -4
  38. package/dist/components/chat/CommandPreview.svelte +2 -1
  39. package/dist/components/console/CommandConsole.svelte +7 -5
  40. package/dist/components/console/ConsoleAutocomplete.svelte +10 -11
  41. package/dist/components/console/ConsoleAutocomplete.svelte.d.ts +6 -0
  42. package/dist/components/console/ConsoleInput.svelte +15 -6
  43. package/dist/components/console/ConsoleOutput.svelte +2 -1
  44. package/dist/components/form/FormArray.svelte +5 -9
  45. package/dist/components/form/FormArray.svelte.d.ts +2 -1
  46. package/dist/components/form/FormAutocomplete.svelte +16 -15
  47. package/dist/components/form/FormField.svelte +4 -2
  48. package/dist/components/form/FormFieldLight.svelte +34 -3
  49. package/dist/components/form/FormFieldLight.svelte.d.ts +12 -0
  50. package/dist/components/form/FormMarkdownEditor.svelte +9 -4
  51. package/dist/components/form/FormRangeField.svelte +1 -0
  52. package/dist/components/form/FormTemplateEditor.svelte +11 -3
  53. package/dist/components/form/FormToggle.svelte +5 -12
  54. package/dist/components/form/FormToggle.svelte.d.ts +4 -2
  55. package/dist/components/form/FormUISchemaRenderer.svelte +3 -1
  56. package/dist/components/form/templateAutocomplete.js +1 -5
  57. package/dist/components/form/types.d.ts +1 -14
  58. package/dist/components/interrupt/FormPrompt.svelte +3 -2
  59. package/dist/components/interrupt/InterruptBubble.svelte +25 -17
  60. package/dist/components/interrupt/ReviewPrompt.svelte +10 -3
  61. package/dist/components/interrupt/TextInputPrompt.svelte +2 -1
  62. package/dist/components/layouts/MainLayout.svelte +20 -13
  63. package/dist/components/layouts/MainLayout.svelte.d.ts +4 -0
  64. package/dist/components/nodes/AtomNode.svelte +17 -5
  65. package/dist/components/nodes/GatewayNode.svelte +19 -10
  66. package/dist/components/nodes/IdeaNode.svelte +7 -0
  67. package/dist/components/nodes/SimpleNode.svelte +11 -6
  68. package/dist/components/nodes/SquareNode.svelte +15 -8
  69. package/dist/components/nodes/TerminalNode.svelte +9 -4
  70. package/dist/components/nodes/ToolNode.svelte +7 -1
  71. package/dist/components/nodes/WorkflowNode.svelte +16 -7
  72. package/dist/components/playground/ChatInput.svelte +11 -14
  73. package/dist/components/playground/ChatPanel.svelte +6 -49
  74. package/dist/components/playground/ChatPanel.svelte.d.ts +0 -14
  75. package/dist/components/playground/ControlPanel.svelte +134 -123
  76. package/dist/components/playground/ControlPanel.svelte.d.ts +3 -0
  77. package/dist/components/playground/ExecutionLogs.svelte +11 -9
  78. package/dist/components/playground/InputCollector.svelte +11 -9
  79. package/dist/components/playground/MessageStream.svelte +17 -23
  80. package/dist/components/playground/PipelineKanbanView.svelte +69 -8
  81. package/dist/components/playground/PipelineKanbanView.svelte.d.ts +2 -0
  82. package/dist/components/playground/PipelinePanel.svelte +31 -8
  83. package/dist/components/playground/PipelinePanel.svelte.d.ts +2 -0
  84. package/dist/components/playground/PipelineTableView.svelte +188 -44
  85. package/dist/components/playground/PipelineTableView.svelte.d.ts +2 -0
  86. package/dist/components/playground/Playground.svelte +154 -105
  87. package/dist/components/playground/Playground.svelte.d.ts +5 -0
  88. package/dist/components/playground/PlaygroundApp.svelte +11 -1
  89. package/dist/components/playground/PlaygroundApp.svelte.d.ts +6 -0
  90. package/dist/components/playground/PlaygroundModal.svelte +18 -3
  91. package/dist/components/playground/PlaygroundModal.svelte.d.ts +6 -0
  92. package/dist/components/playground/PlaygroundStudio.svelte +40 -32
  93. package/dist/components/playground/PlaygroundStudio.svelte.d.ts +6 -0
  94. package/dist/components/playground/SessionManager.svelte +9 -12
  95. package/dist/components/playground/pipelineViewUtils.svelte.d.ts +30 -1
  96. package/dist/components/playground/pipelineViewUtils.svelte.js +40 -3
  97. package/dist/config/endpoints.d.ts +23 -7
  98. package/dist/config/endpoints.js +30 -10
  99. package/dist/core/index.d.ts +5 -6
  100. package/dist/core/index.js +8 -12
  101. package/dist/display/index.d.ts +6 -3
  102. package/dist/display/index.js +7 -5
  103. package/dist/editor/index.d.ts +20 -21
  104. package/dist/editor/index.js +26 -36
  105. package/dist/form/code.d.ts +25 -15
  106. package/dist/form/code.js +44 -41
  107. package/dist/form/fieldRegistry.d.ts +17 -13
  108. package/dist/form/fieldRegistry.js +32 -12
  109. package/dist/form/full.d.ts +19 -14
  110. package/dist/form/full.js +26 -28
  111. package/dist/form/index.d.ts +3 -4
  112. package/dist/form/index.js +6 -5
  113. package/dist/form/markdown.d.ts +13 -8
  114. package/dist/form/markdown.js +22 -23
  115. package/dist/helpers/proximityConnect.d.ts +3 -2
  116. package/dist/helpers/proximityConnect.js +2 -5
  117. package/dist/helpers/workflowEditorHelper.d.ts +14 -5
  118. package/dist/helpers/workflowEditorHelper.js +28 -25
  119. package/dist/index.d.ts +28 -24
  120. package/dist/index.js +27 -50
  121. package/dist/messages/defaults.d.ts +2 -5
  122. package/dist/messages/defaults.js +3 -6
  123. package/dist/messages/index.d.ts +0 -1
  124. package/dist/messages/index.js +0 -1
  125. package/dist/mocks/app-forms.d.ts +6 -2
  126. package/dist/mocks/app-forms.js +11 -4
  127. package/dist/openapi/v1/openapi.yaml +3 -3
  128. package/dist/playground/index.d.ts +4 -5
  129. package/dist/playground/index.js +4 -32
  130. package/dist/playground/mount.d.ts +25 -0
  131. package/dist/playground/mount.js +50 -20
  132. package/dist/registry/{BaseRegistry.d.ts → BaseRegistry.svelte.d.ts} +22 -1
  133. package/dist/registry/{BaseRegistry.js → BaseRegistry.svelte.js} +37 -1
  134. package/dist/registry/builtinFormats.d.ts +9 -18
  135. package/dist/registry/builtinFormats.js +9 -39
  136. package/dist/registry/builtinNodeTypes.d.ts +53 -0
  137. package/dist/registry/builtinNodeTypes.js +67 -0
  138. package/dist/registry/builtinNodes.d.ts +2 -64
  139. package/dist/registry/builtinNodes.js +7 -103
  140. package/dist/registry/index.d.ts +3 -4
  141. package/dist/registry/index.js +4 -6
  142. package/dist/registry/nodeComponentRegistry.d.ts +182 -15
  143. package/dist/registry/nodeComponentRegistry.js +235 -17
  144. package/dist/registry/workflowFormatRegistry.d.ts +14 -9
  145. package/dist/registry/workflowFormatRegistry.js +24 -8
  146. package/dist/{schema → schemas}/index.d.ts +2 -2
  147. package/dist/{schema → schemas}/index.js +2 -2
  148. package/dist/schemas/v1/workflow.schema.json +3 -3
  149. package/dist/services/agentSpecExecutionService.d.ts +0 -2
  150. package/dist/services/agentSpecExecutionService.js +0 -3
  151. package/dist/services/apiVariableService.d.ts +2 -1
  152. package/dist/services/apiVariableService.js +16 -47
  153. package/dist/services/autoSaveService.d.ts +7 -0
  154. package/dist/services/autoSaveService.js +6 -4
  155. package/dist/services/categoriesApi.js +3 -6
  156. package/dist/services/chatService.d.ts +9 -4
  157. package/dist/services/chatService.js +23 -28
  158. package/dist/services/draftStorage.d.ts +129 -13
  159. package/dist/services/draftStorage.js +185 -37
  160. package/dist/services/dynamicSchemaService.d.ts +2 -1
  161. package/dist/services/dynamicSchemaService.js +5 -22
  162. package/dist/services/globalSave.d.ts +13 -12
  163. package/dist/services/globalSave.js +29 -51
  164. package/dist/services/historyService.d.ts +9 -3
  165. package/dist/services/historyService.js +9 -3
  166. package/dist/services/interruptService.d.ts +15 -9
  167. package/dist/services/interruptService.js +35 -37
  168. package/dist/services/nodeExecutionService.d.ts +18 -3
  169. package/dist/services/nodeExecutionService.js +71 -45
  170. package/dist/services/playgroundService.d.ts +16 -10
  171. package/dist/services/playgroundService.js +42 -43
  172. package/dist/services/portConfigApi.js +3 -6
  173. package/dist/services/settingsService.d.ts +9 -4
  174. package/dist/services/settingsService.js +23 -12
  175. package/dist/services/variableService.d.ts +2 -1
  176. package/dist/services/variableService.js +2 -2
  177. package/dist/services/workflowStorage.js +6 -6
  178. package/dist/stores/apiContext.d.ts +56 -0
  179. package/dist/stores/apiContext.js +80 -0
  180. package/dist/stores/categoriesStore.svelte.d.ts +28 -23
  181. package/dist/stores/categoriesStore.svelte.js +69 -64
  182. package/dist/stores/getInstance.svelte.d.ts +39 -0
  183. package/dist/stores/getInstance.svelte.js +65 -0
  184. package/dist/stores/historyStore.svelte.d.ts +77 -93
  185. package/dist/stores/historyStore.svelte.js +134 -160
  186. package/dist/stores/instanceContainer.svelte.d.ts +111 -0
  187. package/dist/stores/instanceContainer.svelte.js +114 -0
  188. package/dist/stores/interruptStore.svelte.d.ts +112 -82
  189. package/dist/stores/interruptStore.svelte.js +253 -226
  190. package/dist/stores/pipelinePanelStore.svelte.d.ts +27 -3
  191. package/dist/stores/pipelinePanelStore.svelte.js +61 -14
  192. package/dist/stores/playgroundStore.svelte.d.ts +169 -222
  193. package/dist/stores/playgroundStore.svelte.js +513 -580
  194. package/dist/stores/portCoordinateStore.svelte.d.ts +57 -51
  195. package/dist/stores/portCoordinateStore.svelte.js +109 -98
  196. package/dist/stores/settingsStore.svelte.d.ts +4 -1
  197. package/dist/stores/settingsStore.svelte.js +47 -12
  198. package/dist/stores/workflowStore.svelte.d.ts +178 -213
  199. package/dist/stores/workflowStore.svelte.js +449 -501
  200. package/dist/stories/EdgeDecorator.svelte +5 -2
  201. package/dist/stories/NodeDecorator.svelte +5 -3
  202. package/dist/svelte-app.d.ts +60 -10
  203. package/dist/svelte-app.js +159 -54
  204. package/dist/types/auth.d.ts +9 -51
  205. package/dist/types/auth.js +4 -54
  206. package/dist/types/events.d.ts +6 -3
  207. package/dist/types/index.d.ts +37 -5
  208. package/dist/types/index.js +0 -1
  209. package/dist/types/navbar.d.ts +7 -0
  210. package/dist/types/playground.d.ts +18 -3
  211. package/dist/types/settings.d.ts +13 -0
  212. package/dist/types/settings.js +1 -0
  213. package/dist/utils/colors.d.ts +47 -21
  214. package/dist/utils/colors.js +69 -68
  215. package/dist/utils/connections.d.ts +9 -15
  216. package/dist/utils/connections.js +13 -32
  217. package/dist/utils/duration.d.ts +13 -0
  218. package/dist/utils/duration.js +45 -0
  219. package/dist/utils/edgeStyling.js +9 -5
  220. package/dist/utils/fetchWithAuth.d.ts +36 -15
  221. package/dist/utils/fetchWithAuth.js +53 -23
  222. package/dist/utils/icons.d.ts +5 -2
  223. package/dist/utils/icons.js +6 -5
  224. package/dist/utils/nodeSwap.d.ts +6 -2
  225. package/dist/utils/nodeSwap.js +62 -126
  226. package/dist/utils/nodeTypes.d.ts +17 -8
  227. package/dist/utils/nodeTypes.js +27 -20
  228. package/dist/utils/performanceUtils.js +7 -0
  229. package/package.json +7 -5
  230. package/dist/messages/deprecation.d.ts +0 -20
  231. package/dist/messages/deprecation.js +0 -33
  232. package/dist/registry/plugin.d.ts +0 -215
  233. package/dist/registry/plugin.js +0 -249
  234. package/dist/services/api.d.ts +0 -129
  235. package/dist/services/api.js +0 -217
@@ -1,136 +1,120 @@
1
1
  /**
2
2
  * History Store for FlowDrop (Svelte 5 Runes)
3
3
  *
4
- * Provides reactive Svelte 5 rune-based bindings for the history service.
4
+ * Provides reactive Svelte 5 rune-based bindings for a history service.
5
5
  * Exposes undo/redo state and actions for the workflow editor.
6
6
  *
7
+ * The reactive state lives in the {@link HistoryStore} class — one per
8
+ * FlowDrop instance, created by `createFlowDropInstance()` and resolved in
9
+ * components via `getInstance().historyBindings`.
10
+ *
7
11
  * @module stores/historyStore
8
12
  */
9
- import { type HistoryState, type PushOptions } from '../services/historyService.js';
13
+ import { HistoryService, type HistoryState, type PushOptions } from '../services/historyService.js';
10
14
  import type { Workflow } from '../types/index.js';
11
15
  /**
12
- * Clean up the historyService subscription created at module initialisation.
13
- * Call this when tearing down the history store (e.g., in tests or on app
14
- * unmount) to prevent memory leaks.
15
- */
16
- export declare function cleanupHistorySubscription(): void;
17
- /**
18
- * Get the current history state snapshot.
19
- *
20
- * Use this for binding to UI elements like undo/redo buttons.
16
+ * Undo/redo actions for a {@link HistoryStore}.
21
17
  *
22
- * @example
23
- * ```svelte
24
- * <script>
25
- * import { getHistoryState } from "./historyStore.svelte.js";
26
- *
27
- * const state = $derived(getHistoryState());
28
- * </script>
29
- *
30
- * <button disabled={!state.canUndo} onclick={historyActions.undo}>
31
- * Undo
32
- * </button>
33
- * ```
18
+ * Bound facade — safe to detach (`onclick={fd.historyBindings.actions.undo}`)
19
+ * because every entry is bound to its store in the constructor.
34
20
  */
35
- export declare function getHistoryState(): HistoryState;
36
- /**
37
- * Convenience getter for canUndo state.
38
- *
39
- * @returns Whether undo is currently available
40
- */
41
- export declare function getCanUndo(): boolean;
42
- /**
43
- * Convenience getter for canRedo state.
44
- *
45
- * @returns Whether redo is currently available
46
- */
47
- export declare function getCanRedo(): boolean;
48
- /**
49
- * Set the callback for restoring workflow state
50
- *
51
- * This callback is invoked when undo/redo operations return a workflow.
52
- * Use this to update the workflow store or other state management.
53
- *
54
- * @param callback - Function to call with restored workflow
55
- */
56
- export declare function setOnRestoreCallback(callback: ((workflow: Workflow) => void) | null): void;
21
+ export interface HistoryStoreActions {
22
+ initialize: (workflow: Workflow) => void;
23
+ pushState: (workflow: Workflow, options?: PushOptions) => void;
24
+ undo: () => boolean;
25
+ redo: () => boolean;
26
+ startTransaction: (workflow: Workflow, description?: string) => void;
27
+ commitTransaction: () => void;
28
+ cancelTransaction: () => void;
29
+ clear: (currentWorkflow?: Workflow) => void;
30
+ canUndo: () => boolean;
31
+ canRedo: () => boolean;
32
+ getState: () => HistoryState;
33
+ }
57
34
  /**
58
- * History actions for undo/redo operations
35
+ * Reactive rune bindings around a {@link HistoryService}.
59
36
  *
60
- * Use these functions to interact with the history service.
61
- * They handle the coordination between history and workflow state.
37
+ * Subscribes to the service on construction; call {@link cleanup} when the
38
+ * owning instance is destroyed to release the subscription.
62
39
  */
63
- export declare const historyActions: {
40
+ export declare class HistoryStore {
41
+ #private;
42
+ /** Bound action facade — see {@link HistoryStoreActions}. */
43
+ readonly actions: HistoryStoreActions;
44
+ constructor(service: HistoryService);
64
45
  /**
65
- * Initialize history with the current workflow
46
+ * The current history state snapshot.
47
+ *
48
+ * Use this for binding to UI elements like undo/redo buttons.
66
49
  *
67
- * Call this when loading a new workflow to reset history.
50
+ * @example
51
+ * ```svelte
52
+ * <script>
53
+ * const fd = getInstance();
54
+ * const state = $derived(fd.historyBindings.state);
55
+ * </script>
68
56
  *
69
- * @param workflow - The initial workflow state
57
+ * <button disabled={!state.canUndo} onclick={fd.historyBindings.actions.undo}>
58
+ * Undo
59
+ * </button>
60
+ * ```
70
61
  */
71
- initialize: (workflow: Workflow) => void;
62
+ get state(): HistoryState;
63
+ /** Whether undo is currently available (reactive). */
64
+ get canUndo(): boolean;
65
+ /** Whether redo is currently available (reactive). */
66
+ get canRedo(): boolean;
72
67
  /**
73
- * Push the current state to history before making changes
68
+ * Set the callback for restoring workflow state.
74
69
  *
75
- * Call this BEFORE modifying the workflow to capture the "before" state.
70
+ * This callback is invoked when undo/redo operations return a workflow.
71
+ * Use this to update the workflow store or other state management.
72
+ */
73
+ setOnRestoreCallback(callback: ((workflow: Workflow) => void) | null): void;
74
+ /**
75
+ * Release the history service subscription.
76
+ * Called by the owning instance's destroy(); safe to call repeatedly.
77
+ */
78
+ cleanup(): void;
79
+ /** Initialize history with the current workflow (resets history). */
80
+ initialize(workflow: Workflow): void;
81
+ /**
82
+ * Push the current state to history before making changes.
76
83
  *
77
- * @param workflow - The current workflow state (before changes)
78
- * @param options - Options for this history entry
84
+ * Call this BEFORE modifying the workflow to capture the "before" state.
79
85
  */
80
- pushState: (workflow: Workflow, options?: PushOptions) => void;
86
+ pushState(workflow: Workflow, options?: PushOptions): void;
81
87
  /**
82
- * Undo the last change
88
+ * Undo the last change.
83
89
  *
84
90
  * Restores the previous workflow state and invokes the restore callback.
85
91
  *
86
92
  * @returns true if undo was successful, false if at beginning of history
87
93
  */
88
- undo: () => boolean;
94
+ undo(): boolean;
89
95
  /**
90
- * Redo the last undone change
96
+ * Redo the last undone change.
91
97
  *
92
98
  * Restores the next workflow state and invokes the restore callback.
93
99
  *
94
100
  * @returns true if redo was successful, false if at end of history
95
101
  */
96
- redo: () => boolean;
102
+ redo(): boolean;
97
103
  /**
98
- * Start a transaction for grouping multiple changes
104
+ * Start a transaction for grouping multiple changes.
99
105
  *
100
106
  * All changes during a transaction are combined into a single undo entry.
101
- *
102
- * @param workflow - The current workflow state (before changes)
103
- * @param description - Description for the combined change
104
- */
105
- startTransaction: (workflow: Workflow, description?: string) => void;
106
- /**
107
- * Commit the current transaction
108
- */
109
- commitTransaction: () => void;
110
- /**
111
- * Cancel the current transaction without committing
112
107
  */
113
- cancelTransaction: () => void;
108
+ startTransaction(workflow: Workflow, description?: string): void;
109
+ /** Commit the current transaction. */
110
+ commitTransaction(): void;
111
+ /** Cancel the current transaction without committing. */
112
+ cancelTransaction(): void;
114
113
  /**
115
- * Clear all history
114
+ * Clear all history.
116
115
  *
117
116
  * @param currentWorkflow - If provided, keeps this as the initial state
118
117
  */
119
- clear: (currentWorkflow?: Workflow) => void;
120
- /**
121
- * Check if undo is available
122
- */
123
- canUndo: () => boolean;
124
- /**
125
- * Check if redo is available
126
- */
127
- canRedo: () => boolean;
128
- /**
129
- * Get the current history state synchronously
130
- *
131
- * @returns The current history state
132
- */
133
- getState: () => HistoryState;
134
- };
118
+ clear(currentWorkflow?: Workflow): void;
119
+ }
135
120
  export type { HistoryEntry, HistoryState, PushOptions } from '../services/historyService.js';
136
- export { HistoryService, historyService } from '../services/historyService.js';
@@ -1,207 +1,181 @@
1
1
  /**
2
2
  * History Store for FlowDrop (Svelte 5 Runes)
3
3
  *
4
- * Provides reactive Svelte 5 rune-based bindings for the history service.
4
+ * Provides reactive Svelte 5 rune-based bindings for a history service.
5
5
  * Exposes undo/redo state and actions for the workflow editor.
6
6
  *
7
- * @module stores/historyStore
8
- */
9
- import { historyService } from '../services/historyService.js';
10
- // =========================================================================
11
- // Reactive State (Runes)
12
- // =========================================================================
13
- /**
14
- * Internal reactive state for history, powered by $state.
15
- */
16
- let historyState = $state({
17
- canUndo: false,
18
- canRedo: false,
19
- currentIndex: 0,
20
- historyLength: 0,
21
- isInTransaction: false
22
- });
23
- // Subscribe to history service changes and update the rune state.
24
- // The unsubscribe function is stored so it can be called via
25
- // cleanupHistorySubscription() when the store is torn down.
26
- const _unsubscribeHistoryService = historyService.subscribe((state) => {
27
- historyState = state;
28
- });
29
- /**
30
- * Clean up the historyService subscription created at module initialisation.
31
- * Call this when tearing down the history store (e.g., in tests or on app
32
- * unmount) to prevent memory leaks.
33
- */
34
- export function cleanupHistorySubscription() {
35
- _unsubscribeHistoryService();
36
- }
37
- // =========================================================================
38
- // Reactive Getters
39
- // =========================================================================
40
- /**
41
- * Get the current history state snapshot.
42
- *
43
- * Use this for binding to UI elements like undo/redo buttons.
44
- *
45
- * @example
46
- * ```svelte
47
- * <script>
48
- * import { getHistoryState } from "./historyStore.svelte.js";
49
- *
50
- * const state = $derived(getHistoryState());
51
- * </script>
52
- *
53
- * <button disabled={!state.canUndo} onclick={historyActions.undo}>
54
- * Undo
55
- * </button>
56
- * ```
57
- */
58
- export function getHistoryState() {
59
- return historyState;
60
- }
61
- /**
62
- * Convenience getter for canUndo state.
7
+ * The reactive state lives in the {@link HistoryStore} class — one per
8
+ * FlowDrop instance, created by `createFlowDropInstance()` and resolved in
9
+ * components via `getInstance().historyBindings`.
63
10
  *
64
- * @returns Whether undo is currently available
65
- */
66
- export function getCanUndo() {
67
- return historyState.canUndo;
68
- }
69
- /**
70
- * Convenience getter for canRedo state.
71
- *
72
- * @returns Whether redo is currently available
11
+ * @module stores/historyStore
73
12
  */
74
- export function getCanRedo() {
75
- return historyState.canRedo;
76
- }
13
+ import { HistoryService } from '../services/historyService.js';
77
14
  // =========================================================================
78
- // History Actions
15
+ // HistoryStore (per-instance reactive bindings)
79
16
  // =========================================================================
80
17
  /**
81
- * Callback for when workflow state is restored from history
18
+ * Reactive rune bindings around a {@link HistoryService}.
82
19
  *
83
- * Set this to handle the restored workflow state (e.g., update the workflow store)
20
+ * Subscribes to the service on construction; call {@link cleanup} when the
21
+ * owning instance is destroyed to release the subscription.
84
22
  */
85
- let onRestoreCallback = null;
86
- /**
87
- * Set the callback for restoring workflow state
88
- *
89
- * This callback is invoked when undo/redo operations return a workflow.
90
- * Use this to update the workflow store or other state management.
91
- *
92
- * @param callback - Function to call with restored workflow
93
- */
94
- export function setOnRestoreCallback(callback) {
95
- onRestoreCallback = callback;
96
- }
97
- /**
98
- * History actions for undo/redo operations
99
- *
100
- * Use these functions to interact with the history service.
101
- * They handle the coordination between history and workflow state.
102
- */
103
- export const historyActions = {
23
+ export class HistoryStore {
24
+ /** Reactive snapshot of the history service state. */
25
+ #state = $state({
26
+ canUndo: false,
27
+ canRedo: false,
28
+ currentIndex: 0,
29
+ historyLength: 0,
30
+ isInTransaction: false
31
+ });
32
+ /**
33
+ * Callback for when workflow state is restored from history.
34
+ * Invoked when undo/redo operations return a workflow.
35
+ */
36
+ #onRestore = null;
37
+ /** Unsubscribe handle for the service subscription. */
38
+ #unsubscribe;
39
+ /** The underlying (non-reactive) history service. */
40
+ #service;
41
+ /** Bound action facade — see {@link HistoryStoreActions}. */
42
+ actions;
43
+ constructor(service) {
44
+ this.#service = service;
45
+ this.#unsubscribe = service.subscribe((state) => {
46
+ this.#state = state;
47
+ });
48
+ this.actions = Object.freeze({
49
+ initialize: this.initialize.bind(this),
50
+ pushState: this.pushState.bind(this),
51
+ undo: this.undo.bind(this),
52
+ redo: this.redo.bind(this),
53
+ startTransaction: this.startTransaction.bind(this),
54
+ commitTransaction: this.commitTransaction.bind(this),
55
+ cancelTransaction: this.cancelTransaction.bind(this),
56
+ clear: this.clear.bind(this),
57
+ canUndo: () => this.#service.canUndo(),
58
+ canRedo: () => this.#service.canRedo(),
59
+ getState: () => this.#state
60
+ });
61
+ }
62
+ // -----------------------------------------------------------------------
63
+ // Reactive getters
64
+ // -----------------------------------------------------------------------
104
65
  /**
105
- * Initialize history with the current workflow
66
+ * The current history state snapshot.
67
+ *
68
+ * Use this for binding to UI elements like undo/redo buttons.
106
69
  *
107
- * Call this when loading a new workflow to reset history.
70
+ * @example
71
+ * ```svelte
72
+ * <script>
73
+ * const fd = getInstance();
74
+ * const state = $derived(fd.historyBindings.state);
75
+ * </script>
108
76
  *
109
- * @param workflow - The initial workflow state
77
+ * <button disabled={!state.canUndo} onclick={fd.historyBindings.actions.undo}>
78
+ * Undo
79
+ * </button>
80
+ * ```
110
81
  */
111
- initialize: (workflow) => {
112
- historyService.initialize(workflow);
113
- },
82
+ get state() {
83
+ return this.#state;
84
+ }
85
+ /** Whether undo is currently available (reactive). */
86
+ get canUndo() {
87
+ return this.#state.canUndo;
88
+ }
89
+ /** Whether redo is currently available (reactive). */
90
+ get canRedo() {
91
+ return this.#state.canRedo;
92
+ }
93
+ // -----------------------------------------------------------------------
94
+ // Wiring & lifecycle
95
+ // -----------------------------------------------------------------------
114
96
  /**
115
- * Push the current state to history before making changes
97
+ * Set the callback for restoring workflow state.
116
98
  *
117
- * Call this BEFORE modifying the workflow to capture the "before" state.
99
+ * This callback is invoked when undo/redo operations return a workflow.
100
+ * Use this to update the workflow store or other state management.
101
+ */
102
+ setOnRestoreCallback(callback) {
103
+ this.#onRestore = callback;
104
+ }
105
+ /**
106
+ * Release the history service subscription.
107
+ * Called by the owning instance's destroy(); safe to call repeatedly.
108
+ */
109
+ cleanup() {
110
+ this.#unsubscribe();
111
+ }
112
+ // -----------------------------------------------------------------------
113
+ // Actions
114
+ // -----------------------------------------------------------------------
115
+ /** Initialize history with the current workflow (resets history). */
116
+ initialize(workflow) {
117
+ this.#service.initialize(workflow);
118
+ }
119
+ /**
120
+ * Push the current state to history before making changes.
118
121
  *
119
- * @param workflow - The current workflow state (before changes)
120
- * @param options - Options for this history entry
122
+ * Call this BEFORE modifying the workflow to capture the "before" state.
121
123
  */
122
- pushState: (workflow, options) => {
123
- historyService.push(workflow, options);
124
- },
124
+ pushState(workflow, options) {
125
+ this.#service.push(workflow, options);
126
+ }
125
127
  /**
126
- * Undo the last change
128
+ * Undo the last change.
127
129
  *
128
130
  * Restores the previous workflow state and invokes the restore callback.
129
131
  *
130
132
  * @returns true if undo was successful, false if at beginning of history
131
133
  */
132
- undo: () => {
133
- const previousState = historyService.undo();
134
- if (previousState && onRestoreCallback) {
135
- onRestoreCallback(previousState);
134
+ undo() {
135
+ const previousState = this.#service.undo();
136
+ if (previousState && this.#onRestore) {
137
+ this.#onRestore(previousState);
136
138
  return true;
137
139
  }
138
140
  return previousState !== null;
139
- },
141
+ }
140
142
  /**
141
- * Redo the last undone change
143
+ * Redo the last undone change.
142
144
  *
143
145
  * Restores the next workflow state and invokes the restore callback.
144
146
  *
145
147
  * @returns true if redo was successful, false if at end of history
146
148
  */
147
- redo: () => {
148
- const nextState = historyService.redo();
149
- if (nextState && onRestoreCallback) {
150
- onRestoreCallback(nextState);
149
+ redo() {
150
+ const nextState = this.#service.redo();
151
+ if (nextState && this.#onRestore) {
152
+ this.#onRestore(nextState);
151
153
  return true;
152
154
  }
153
155
  return false;
154
- },
156
+ }
155
157
  /**
156
- * Start a transaction for grouping multiple changes
158
+ * Start a transaction for grouping multiple changes.
157
159
  *
158
160
  * All changes during a transaction are combined into a single undo entry.
159
- *
160
- * @param workflow - The current workflow state (before changes)
161
- * @param description - Description for the combined change
162
161
  */
163
- startTransaction: (workflow, description) => {
164
- historyService.startTransaction(workflow, description);
165
- },
166
- /**
167
- * Commit the current transaction
168
- */
169
- commitTransaction: () => {
170
- historyService.commitTransaction();
171
- },
172
- /**
173
- * Cancel the current transaction without committing
174
- */
175
- cancelTransaction: () => {
176
- historyService.cancelTransaction();
177
- },
162
+ startTransaction(workflow, description) {
163
+ this.#service.startTransaction(workflow, description);
164
+ }
165
+ /** Commit the current transaction. */
166
+ commitTransaction() {
167
+ this.#service.commitTransaction();
168
+ }
169
+ /** Cancel the current transaction without committing. */
170
+ cancelTransaction() {
171
+ this.#service.cancelTransaction();
172
+ }
178
173
  /**
179
- * Clear all history
174
+ * Clear all history.
180
175
  *
181
176
  * @param currentWorkflow - If provided, keeps this as the initial state
182
177
  */
183
- clear: (currentWorkflow) => {
184
- historyService.clear(currentWorkflow);
185
- },
186
- /**
187
- * Check if undo is available
188
- */
189
- canUndo: () => {
190
- return historyService.canUndo();
191
- },
192
- /**
193
- * Check if redo is available
194
- */
195
- canRedo: () => {
196
- return historyService.canRedo();
197
- },
198
- /**
199
- * Get the current history state synchronously
200
- *
201
- * @returns The current history state
202
- */
203
- getState: () => {
204
- return historyState;
178
+ clear(currentWorkflow) {
179
+ this.#service.clear(currentWorkflow);
205
180
  }
206
- };
207
- export { HistoryService, historyService } from '../services/historyService.js';
181
+ }
@@ -0,0 +1,111 @@
1
+ /**
2
+ * FlowDrop Instance Container
3
+ *
4
+ * Holds all per-instance state for one FlowDrop editor: workflow state,
5
+ * undo/redo history, playground sessions, interrupts, port coordinates,
6
+ * categories, and pipeline panel state. Creating one container per mount is
7
+ * what allows multiple FlowDrop editors to coexist on a single page.
8
+ *
9
+ * The container is provided to the component tree via Svelte context (see
10
+ * `getInstance.svelte.ts`). A lazily-created, browser-only default instance
11
+ * backs the legacy module-level store APIs so existing single-instance
12
+ * consumers keep working unchanged.
13
+ *
14
+ * @module stores/instanceContainer
15
+ */
16
+ import { HistoryService } from '../services/historyService.js';
17
+ import { WorkflowStore } from './workflowStore.svelte.js';
18
+ import { HistoryStore } from './historyStore.svelte.js';
19
+ import { PlaygroundStore } from './playgroundStore.svelte.js';
20
+ import { InterruptStore } from './interruptStore.svelte.js';
21
+ import { CategoriesStore } from './categoriesStore.svelte.js';
22
+ import { PortCoordinateStore } from './portCoordinateStore.svelte.js';
23
+ import { PipelinePanelStore } from './pipelinePanelStore.svelte.js';
24
+ import { ApiContext } from './apiContext.js';
25
+ import { PortCompatibilityChecker } from '../utils/connections.js';
26
+ import { NodeComponentRegistry } from '../registry/nodeComponentRegistry.js';
27
+ import { FieldComponentRegistry } from '../form/fieldRegistry.js';
28
+ import { WorkflowFormatRegistry } from '../registry/workflowFormatRegistry.js';
29
+ /** Storage key prefix shared by the default instance and legacy consumers. */
30
+ export declare const DEFAULT_DRAFT_PREFIX = "flowdrop:draft";
31
+ /**
32
+ * All per-instance FlowDrop state.
33
+ *
34
+ * Store fields are added phase-by-phase as the module-level stores are
35
+ * converted to classes (workflow, history bindings, playground, interrupts,
36
+ * categories, port coordinates, pipeline panel).
37
+ */
38
+ export interface FlowDropInstance {
39
+ /** Unique id for this instance (used to scope storage keys). */
40
+ readonly id: string;
41
+ /** Prefix for draft localStorage keys — legacy bare prefix for the default instance. */
42
+ readonly storagePrefix: string;
43
+ /** Whether this is the page-default instance (legacy storage keys, module-API reachable). */
44
+ readonly isDefault: boolean;
45
+ /** Undo/redo engine for this instance. */
46
+ readonly history: HistoryService;
47
+ /** Workflow state with dirty tracking and history integration. */
48
+ readonly workflow: WorkflowStore;
49
+ /** Reactive rune bindings around `history` (undo/redo button state). */
50
+ readonly historyBindings: HistoryStore;
51
+ /** Playground sessions, messages, and execution state. */
52
+ readonly playground: PlaygroundStore;
53
+ /** Pending interrupt/confirmation dialogs. */
54
+ readonly interrupts: InterruptStore;
55
+ /** Endpoint configuration, auth provider, and API client for this instance. */
56
+ readonly api: ApiContext;
57
+ /** Node component registry, seeded with the built-in node components. */
58
+ readonly nodes: NodeComponentRegistry;
59
+ /**
60
+ * Form field component registry. Starts empty (built-in light fields are
61
+ * resolved inline); heavy editors are registered on demand via
62
+ * `registerCodeEditorField(fd.fields)` etc.
63
+ */
64
+ readonly fields: FieldComponentRegistry;
65
+ /** Workflow format registry, seeded with the flowdrop + agentspec adapters. */
66
+ readonly formats: WorkflowFormatRegistry;
67
+ /** Node category definitions. */
68
+ readonly categories: CategoriesStore;
69
+ /**
70
+ * Port-to-port data-type compatibility checker for this instance.
71
+ * Seeded with `DEFAULT_PORT_CONFIG`; re-initialized by mount after the
72
+ * backend's port config is fetched.
73
+ */
74
+ readonly portCompatibility: PortCompatibilityChecker;
75
+ /** Canvas port coordinates. */
76
+ readonly portCoordinates: PortCoordinateStore;
77
+ /** Pipeline panel open/close state (instance-scoped persistence). */
78
+ readonly pipelinePanel: PipelinePanelStore;
79
+ /**
80
+ * Dispose all per-instance resources (subscriptions, effect roots,
81
+ * external callbacks). Safe to call more than once. Must not touch
82
+ * sibling instances.
83
+ */
84
+ destroy(): void;
85
+ }
86
+ export interface CreateInstanceOptions {
87
+ /** Explicit instance id; auto-generated (`fd-<n>`) when omitted. */
88
+ id?: string;
89
+ /**
90
+ * Marks the page-default instance: it keeps the legacy (unscoped) storage
91
+ * keys and reuses the exported `historyService` singleton so legacy
92
+ * imports keep operating on the same history stack.
93
+ */
94
+ isDefault?: boolean;
95
+ }
96
+ /**
97
+ * Create a fully wired FlowDrop instance.
98
+ *
99
+ * Creation order matters: history first, then stores that depend on it
100
+ * (constructor injection — no module-singleton imports).
101
+ */
102
+ export declare function createFlowDropInstance(options?: CreateInstanceOptions): FlowDropInstance;
103
+ /**
104
+ * Get the page-default FlowDrop instance, creating it on first access.
105
+ *
106
+ * **Browser-only.** Reactive per-user state must never live at module scope
107
+ * on the server — a module-level default would leak between SvelteKit
108
+ * requests. Server renders must provide an instance via context instead
109
+ * (`<App>` and `<WorkflowEditor>` do this automatically).
110
+ */
111
+ export declare function getDefaultInstance(): FlowDropInstance;