@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.
- package/CHANGELOG.md +508 -0
- package/MIGRATION-2.0.md +629 -0
- package/README.md +23 -23
- package/dist/adapters/WorkflowAdapter.d.ts +1 -1
- package/dist/adapters/WorkflowAdapter.js +14 -8
- package/dist/adapters/agentspec/AgentSpecAdapter.js +7 -7
- package/dist/api/enhanced-client.js +6 -11
- package/dist/chat/batchFeedback.d.ts +39 -0
- package/dist/chat/batchFeedback.js +51 -0
- package/dist/commands/executor.js +15 -1
- package/dist/commands/storeIntegration.svelte.d.ts +4 -1
- package/dist/commands/storeIntegration.svelte.js +26 -21
- package/dist/commands/types.d.ts +2 -0
- package/dist/components/App.svelte +163 -192
- package/dist/components/App.svelte.d.ts +47 -8
- package/dist/components/ConfigForm.svelte +77 -49
- package/dist/components/ConfigModal.svelte +7 -2
- package/dist/components/ConnectionLine.svelte +4 -2
- package/dist/components/Navbar.svelte +61 -1
- package/dist/components/NodeSidebar.svelte +27 -45
- package/dist/components/NodeStatusOverlay.svelte +94 -6
- package/dist/components/NodeSwapPicker.svelte +10 -8
- package/dist/components/PipelineStatus.svelte +22 -68
- package/dist/components/PipelineStatus.svelte.d.ts +3 -0
- package/dist/components/PortCoordinateTracker.svelte +5 -6
- package/dist/components/SchemaForm.stories.svelte +1 -3
- package/dist/components/SchemaForm.svelte +22 -27
- package/dist/components/SchemaForm.svelte.d.ts +0 -8
- package/dist/components/SettingsModal.svelte +8 -3
- package/dist/components/SettingsPanel.svelte +20 -4
- package/dist/components/SwapMappingEditor.svelte +67 -49
- package/dist/components/SwapMappingEditor.svelte.d.ts +0 -2
- package/dist/components/UniversalNode.svelte +9 -7
- package/dist/components/WorkflowEditor.svelte +121 -111
- package/dist/components/WorkflowEditor.svelte.d.ts +21 -10
- package/dist/components/chat/AIChatPanel.svelte +98 -89
- package/dist/components/chat/AIChatPanel.svelte.d.ts +0 -4
- package/dist/components/chat/CommandPreview.svelte +2 -1
- package/dist/components/console/CommandConsole.svelte +7 -5
- package/dist/components/console/ConsoleAutocomplete.svelte +10 -11
- package/dist/components/console/ConsoleAutocomplete.svelte.d.ts +6 -0
- package/dist/components/console/ConsoleInput.svelte +15 -6
- package/dist/components/console/ConsoleOutput.svelte +2 -1
- package/dist/components/form/FormArray.svelte +5 -9
- package/dist/components/form/FormArray.svelte.d.ts +2 -1
- package/dist/components/form/FormAutocomplete.svelte +16 -15
- package/dist/components/form/FormField.svelte +4 -2
- package/dist/components/form/FormFieldLight.svelte +34 -3
- package/dist/components/form/FormFieldLight.svelte.d.ts +12 -0
- package/dist/components/form/FormMarkdownEditor.svelte +9 -4
- package/dist/components/form/FormRangeField.svelte +1 -0
- package/dist/components/form/FormTemplateEditor.svelte +11 -3
- package/dist/components/form/FormToggle.svelte +5 -12
- package/dist/components/form/FormToggle.svelte.d.ts +4 -2
- package/dist/components/form/FormUISchemaRenderer.svelte +3 -1
- package/dist/components/form/templateAutocomplete.js +1 -5
- package/dist/components/form/types.d.ts +1 -14
- package/dist/components/interrupt/FormPrompt.svelte +3 -2
- package/dist/components/interrupt/InterruptBubble.svelte +25 -17
- package/dist/components/interrupt/ReviewPrompt.svelte +10 -3
- package/dist/components/interrupt/TextInputPrompt.svelte +2 -1
- package/dist/components/layouts/MainLayout.svelte +20 -13
- package/dist/components/layouts/MainLayout.svelte.d.ts +4 -0
- package/dist/components/nodes/AtomNode.svelte +17 -5
- package/dist/components/nodes/GatewayNode.svelte +19 -10
- package/dist/components/nodes/IdeaNode.svelte +7 -0
- package/dist/components/nodes/SimpleNode.svelte +11 -6
- package/dist/components/nodes/SquareNode.svelte +15 -8
- package/dist/components/nodes/TerminalNode.svelte +9 -4
- package/dist/components/nodes/ToolNode.svelte +7 -1
- package/dist/components/nodes/WorkflowNode.svelte +16 -7
- package/dist/components/playground/ChatInput.svelte +11 -14
- package/dist/components/playground/ChatPanel.svelte +6 -49
- package/dist/components/playground/ChatPanel.svelte.d.ts +0 -14
- package/dist/components/playground/ControlPanel.svelte +134 -123
- package/dist/components/playground/ControlPanel.svelte.d.ts +3 -0
- package/dist/components/playground/ExecutionLogs.svelte +11 -9
- package/dist/components/playground/InputCollector.svelte +11 -9
- package/dist/components/playground/MessageStream.svelte +17 -23
- package/dist/components/playground/PipelineKanbanView.svelte +69 -8
- package/dist/components/playground/PipelineKanbanView.svelte.d.ts +2 -0
- package/dist/components/playground/PipelinePanel.svelte +31 -8
- package/dist/components/playground/PipelinePanel.svelte.d.ts +2 -0
- package/dist/components/playground/PipelineTableView.svelte +188 -44
- package/dist/components/playground/PipelineTableView.svelte.d.ts +2 -0
- package/dist/components/playground/Playground.svelte +154 -105
- package/dist/components/playground/Playground.svelte.d.ts +5 -0
- package/dist/components/playground/PlaygroundApp.svelte +11 -1
- package/dist/components/playground/PlaygroundApp.svelte.d.ts +6 -0
- package/dist/components/playground/PlaygroundModal.svelte +18 -3
- package/dist/components/playground/PlaygroundModal.svelte.d.ts +6 -0
- package/dist/components/playground/PlaygroundStudio.svelte +40 -32
- package/dist/components/playground/PlaygroundStudio.svelte.d.ts +6 -0
- package/dist/components/playground/SessionManager.svelte +9 -12
- package/dist/components/playground/pipelineViewUtils.svelte.d.ts +30 -1
- package/dist/components/playground/pipelineViewUtils.svelte.js +40 -3
- package/dist/config/endpoints.d.ts +23 -7
- package/dist/config/endpoints.js +30 -10
- package/dist/core/index.d.ts +5 -6
- package/dist/core/index.js +8 -12
- package/dist/display/index.d.ts +6 -3
- package/dist/display/index.js +7 -5
- package/dist/editor/index.d.ts +20 -21
- package/dist/editor/index.js +26 -36
- package/dist/form/code.d.ts +25 -15
- package/dist/form/code.js +44 -41
- package/dist/form/fieldRegistry.d.ts +17 -13
- package/dist/form/fieldRegistry.js +32 -12
- package/dist/form/full.d.ts +19 -14
- package/dist/form/full.js +26 -28
- package/dist/form/index.d.ts +3 -4
- package/dist/form/index.js +6 -5
- package/dist/form/markdown.d.ts +13 -8
- package/dist/form/markdown.js +22 -23
- package/dist/helpers/proximityConnect.d.ts +3 -2
- package/dist/helpers/proximityConnect.js +2 -5
- package/dist/helpers/workflowEditorHelper.d.ts +14 -5
- package/dist/helpers/workflowEditorHelper.js +28 -25
- package/dist/index.d.ts +28 -24
- package/dist/index.js +27 -50
- package/dist/messages/defaults.d.ts +2 -5
- package/dist/messages/defaults.js +3 -6
- package/dist/messages/index.d.ts +0 -1
- package/dist/messages/index.js +0 -1
- package/dist/mocks/app-forms.d.ts +6 -2
- package/dist/mocks/app-forms.js +11 -4
- package/dist/openapi/v1/openapi.yaml +3 -3
- package/dist/playground/index.d.ts +4 -5
- package/dist/playground/index.js +4 -32
- package/dist/playground/mount.d.ts +25 -0
- package/dist/playground/mount.js +50 -20
- package/dist/registry/{BaseRegistry.d.ts → BaseRegistry.svelte.d.ts} +22 -1
- package/dist/registry/{BaseRegistry.js → BaseRegistry.svelte.js} +37 -1
- package/dist/registry/builtinFormats.d.ts +9 -18
- package/dist/registry/builtinFormats.js +9 -39
- package/dist/registry/builtinNodeTypes.d.ts +53 -0
- package/dist/registry/builtinNodeTypes.js +67 -0
- package/dist/registry/builtinNodes.d.ts +2 -64
- package/dist/registry/builtinNodes.js +7 -103
- package/dist/registry/index.d.ts +3 -4
- package/dist/registry/index.js +4 -6
- package/dist/registry/nodeComponentRegistry.d.ts +182 -15
- package/dist/registry/nodeComponentRegistry.js +235 -17
- package/dist/registry/workflowFormatRegistry.d.ts +14 -9
- package/dist/registry/workflowFormatRegistry.js +24 -8
- package/dist/{schema → schemas}/index.d.ts +2 -2
- package/dist/{schema → schemas}/index.js +2 -2
- package/dist/schemas/v1/workflow.schema.json +3 -3
- package/dist/services/agentSpecExecutionService.d.ts +0 -2
- package/dist/services/agentSpecExecutionService.js +0 -3
- package/dist/services/apiVariableService.d.ts +2 -1
- package/dist/services/apiVariableService.js +16 -47
- package/dist/services/autoSaveService.d.ts +7 -0
- package/dist/services/autoSaveService.js +6 -4
- package/dist/services/categoriesApi.js +3 -6
- package/dist/services/chatService.d.ts +9 -4
- package/dist/services/chatService.js +23 -28
- package/dist/services/draftStorage.d.ts +129 -13
- package/dist/services/draftStorage.js +185 -37
- package/dist/services/dynamicSchemaService.d.ts +2 -1
- package/dist/services/dynamicSchemaService.js +5 -22
- package/dist/services/globalSave.d.ts +13 -12
- package/dist/services/globalSave.js +29 -51
- package/dist/services/historyService.d.ts +9 -3
- package/dist/services/historyService.js +9 -3
- package/dist/services/interruptService.d.ts +15 -9
- package/dist/services/interruptService.js +35 -37
- package/dist/services/nodeExecutionService.d.ts +18 -3
- package/dist/services/nodeExecutionService.js +71 -45
- package/dist/services/playgroundService.d.ts +16 -10
- package/dist/services/playgroundService.js +42 -43
- package/dist/services/portConfigApi.js +3 -6
- package/dist/services/settingsService.d.ts +9 -4
- package/dist/services/settingsService.js +23 -12
- package/dist/services/variableService.d.ts +2 -1
- package/dist/services/variableService.js +2 -2
- package/dist/services/workflowStorage.js +6 -6
- package/dist/stores/apiContext.d.ts +56 -0
- package/dist/stores/apiContext.js +80 -0
- package/dist/stores/categoriesStore.svelte.d.ts +28 -23
- package/dist/stores/categoriesStore.svelte.js +69 -64
- package/dist/stores/getInstance.svelte.d.ts +39 -0
- package/dist/stores/getInstance.svelte.js +65 -0
- package/dist/stores/historyStore.svelte.d.ts +77 -93
- package/dist/stores/historyStore.svelte.js +134 -160
- package/dist/stores/instanceContainer.svelte.d.ts +111 -0
- package/dist/stores/instanceContainer.svelte.js +114 -0
- package/dist/stores/interruptStore.svelte.d.ts +112 -82
- package/dist/stores/interruptStore.svelte.js +253 -226
- package/dist/stores/pipelinePanelStore.svelte.d.ts +27 -3
- package/dist/stores/pipelinePanelStore.svelte.js +61 -14
- package/dist/stores/playgroundStore.svelte.d.ts +169 -222
- package/dist/stores/playgroundStore.svelte.js +513 -580
- package/dist/stores/portCoordinateStore.svelte.d.ts +57 -51
- package/dist/stores/portCoordinateStore.svelte.js +109 -98
- package/dist/stores/settingsStore.svelte.d.ts +4 -1
- package/dist/stores/settingsStore.svelte.js +47 -12
- package/dist/stores/workflowStore.svelte.d.ts +178 -213
- package/dist/stores/workflowStore.svelte.js +449 -501
- package/dist/stories/EdgeDecorator.svelte +5 -2
- package/dist/stories/NodeDecorator.svelte +5 -3
- package/dist/svelte-app.d.ts +60 -10
- package/dist/svelte-app.js +159 -54
- package/dist/types/auth.d.ts +9 -51
- package/dist/types/auth.js +4 -54
- package/dist/types/events.d.ts +6 -3
- package/dist/types/index.d.ts +37 -5
- package/dist/types/index.js +0 -1
- package/dist/types/navbar.d.ts +7 -0
- package/dist/types/playground.d.ts +18 -3
- package/dist/types/settings.d.ts +13 -0
- package/dist/types/settings.js +1 -0
- package/dist/utils/colors.d.ts +47 -21
- package/dist/utils/colors.js +69 -68
- package/dist/utils/connections.d.ts +9 -15
- package/dist/utils/connections.js +13 -32
- package/dist/utils/duration.d.ts +13 -0
- package/dist/utils/duration.js +45 -0
- package/dist/utils/edgeStyling.js +9 -5
- package/dist/utils/fetchWithAuth.d.ts +36 -15
- package/dist/utils/fetchWithAuth.js +53 -23
- package/dist/utils/icons.d.ts +5 -2
- package/dist/utils/icons.js +6 -5
- package/dist/utils/nodeSwap.d.ts +6 -2
- package/dist/utils/nodeSwap.js +62 -126
- package/dist/utils/nodeTypes.d.ts +17 -8
- package/dist/utils/nodeTypes.js +27 -20
- package/dist/utils/performanceUtils.js +7 -0
- package/package.json +7 -5
- package/dist/messages/deprecation.d.ts +0 -20
- package/dist/messages/deprecation.js +0 -33
- package/dist/registry/plugin.d.ts +0 -215
- package/dist/registry/plugin.js +0 -249
- package/dist/services/api.d.ts +0 -129
- package/dist/services/api.js +0 -217
package/MIGRATION-2.0.md
ADDED
|
@@ -0,0 +1,629 @@
|
|
|
1
|
+
# Migrating to FlowDrop 2.0
|
|
2
|
+
|
|
3
|
+
2.0's theme is **the explicit-instance era**: every compatibility shim the 1.x
|
|
4
|
+
multi-instance refactor and the 1.8 message migration carried is gone. If your
|
|
5
|
+
1.x code ran without deprecation warnings in the console, most of this guide
|
|
6
|
+
does not apply to you.
|
|
7
|
+
|
|
8
|
+
The sections are ordered by the shape of the change, from the deepest
|
|
9
|
+
architectural moves (instances, the API client, registries) outward to module
|
|
10
|
+
layout, data formats, component props, and storage. Each has a 1.x → 2.0 code
|
|
11
|
+
example.
|
|
12
|
+
|
|
13
|
+
## 1. Module-level store APIs are removed (the big one)
|
|
14
|
+
|
|
15
|
+
All ~95 module-level functions that operated on "the" editor are gone:
|
|
16
|
+
`getWorkflowStore()`, `workflowActions`, `historyService`, `getMessages()`,
|
|
17
|
+
`playgroundActions`, `getCategories()`, `getHistoryState()`, and the rest of
|
|
18
|
+
the get*/set*/actions surface from `@flowdrop/flowdrop/editor` and
|
|
19
|
+
`@flowdrop/flowdrop/playground`.
|
|
20
|
+
|
|
21
|
+
**Replacement:** every mount handle exposes its state container.
|
|
22
|
+
|
|
23
|
+
```js
|
|
24
|
+
// 1.x
|
|
25
|
+
import { workflowActions, historyService, getMessages } from '@flowdrop/flowdrop/editor';
|
|
26
|
+
const app = await mountFlowDropApp(el, options);
|
|
27
|
+
workflowActions.addNode(node);
|
|
28
|
+
historyService.undo();
|
|
29
|
+
const messages = getMessages();
|
|
30
|
+
|
|
31
|
+
// 2.0
|
|
32
|
+
const app = await mountFlowDropApp(el, options);
|
|
33
|
+
app.instance.workflow.actions.addNode(node);
|
|
34
|
+
app.instance.history.undo();
|
|
35
|
+
const messages = app.instance.playground.messages;
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
Inside Svelte components rendered under `<App>`/`<WorkflowEditor>`, resolve the
|
|
39
|
+
owning instance with `getInstance()` (unchanged — including the browser
|
|
40
|
+
fallback to the page-default instance for single-editor embeds):
|
|
41
|
+
|
|
42
|
+
```svelte
|
|
43
|
+
<script>
|
|
44
|
+
import { getInstance } from '@flowdrop/flowdrop/editor';
|
|
45
|
+
const fd = getInstance();
|
|
46
|
+
// fd.workflow, fd.history, fd.playground, fd.interrupts, fd.categories, …
|
|
47
|
+
</script>
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
For hosts that construct state manually, the store classes are now exported:
|
|
51
|
+
`WorkflowStore`, `HistoryStore`, `HistoryService`, `PlaygroundStore`,
|
|
52
|
+
`InterruptStore`, `PortCoordinateStore`, plus `createFlowDropInstance()`.
|
|
53
|
+
|
|
54
|
+
Settings remain page-global by design — `getSettings()` etc. are unchanged.
|
|
55
|
+
|
|
56
|
+
## 2. API access is instance-scoped (`fd.api`)
|
|
57
|
+
|
|
58
|
+
The module-level API singleton in `services/api.js` is gone:
|
|
59
|
+
`setEndpointConfig()`, `getEndpointConfig()`, `nodeApi`, `workflowApi`, and the
|
|
60
|
+
`api` aggregate are removed. Each instance now owns an `ApiContext` at
|
|
61
|
+
`fd.api`, which holds the endpoint config + auth provider and lazily builds an
|
|
62
|
+
`EnhancedFlowDropApiClient`.
|
|
63
|
+
|
|
64
|
+
```js
|
|
65
|
+
// 1.x
|
|
66
|
+
import { setEndpointConfig, workflowApi, nodeApi } from '@flowdrop/flowdrop/editor';
|
|
67
|
+
setEndpointConfig(createEndpointConfig('/api/flowdrop'));
|
|
68
|
+
const nodes = await nodeApi.getNodes();
|
|
69
|
+
const wf = await workflowApi.getWorkflow(id);
|
|
70
|
+
|
|
71
|
+
// 2.0 — mount configures fd.api automatically; inside components resolve it:
|
|
72
|
+
import { getInstance } from '@flowdrop/flowdrop/editor';
|
|
73
|
+
const fd = getInstance();
|
|
74
|
+
const nodes = await fd.api.client.getAvailableNodes();
|
|
75
|
+
const wf = await fd.api.client.loadWorkflow(id);
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
`mountFlowDropApp` / `mountPlayground` / `<App>` call `fd.api.configure(config,
|
|
79
|
+
authProvider)` for you. Services that previously read the singleton (playground,
|
|
80
|
+
interrupt, chat, node-execution, dynamic-schema, variable) now take the endpoint
|
|
81
|
+
config as their first argument — pass `fd.api.config`.
|
|
82
|
+
|
|
83
|
+
These services also accept the instance's `AuthProvider` as an **optional
|
|
84
|
+
trailing argument** so every request they make is authenticated consistently
|
|
85
|
+
with `fd.api.client` (the typed workflow/node API). The built-in components and
|
|
86
|
+
mount helpers pass `fd.api.authProvider` for you — no action is needed for the
|
|
87
|
+
normal mounted flow. Only direct callers of the service singletons need to
|
|
88
|
+
forward it:
|
|
89
|
+
|
|
90
|
+
```js
|
|
91
|
+
import { playgroundService } from '@flowdrop/flowdrop/playground';
|
|
92
|
+
|
|
93
|
+
// 2.0 — authenticate playground requests by forwarding the provider
|
|
94
|
+
await playgroundService.listSessions(fd.api.config, workflowId, undefined, fd.api.authProvider);
|
|
95
|
+
await playgroundService.sendMessage(fd.api.config, sessionId, text, undefined, fd.api.authProvider);
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
The settings-sync entry points gained the same optional provider:
|
|
99
|
+
`setSettingsEndpointConfig(config, authProvider?)` and
|
|
100
|
+
`createSettingsService(config, authProvider?)` — pass an `AuthProvider` if your
|
|
101
|
+
backend's preferences endpoint requires auth.
|
|
102
|
+
|
|
103
|
+
The standalone playground mounts — `mountPlayground`, `mountPlaygroundStudio`,
|
|
104
|
+
and `mountPlaygroundApp` — accept an `authProvider` option that they wire into
|
|
105
|
+
`fd.api` for you (the editor's built-in playground already inherits the
|
|
106
|
+
provider from `mountFlowDropApp`). Pass it so playground requests (sessions,
|
|
107
|
+
messages, polling, interrupts) carry your auth/CSRF headers:
|
|
108
|
+
|
|
109
|
+
```js
|
|
110
|
+
mountPlayground(el, {
|
|
111
|
+
workflowId,
|
|
112
|
+
endpointConfig: createEndpointConfig('/api/flowdrop'),
|
|
113
|
+
authProvider: new CallbackAuthProvider({ getToken: () => session.getCsrfToken() })
|
|
114
|
+
});
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
The same plumbing was extended to the editor and pipeline surfaces, which
|
|
118
|
+
previously built unauthenticated API clients from `endpointConfig` alone:
|
|
119
|
+
|
|
120
|
+
- The exported `<WorkflowEditor>` component accepts an `authProvider` prop
|
|
121
|
+
(threaded for you by `mountFlowDropApp` / `mountWorkflowEditor` / `<App>`).
|
|
122
|
+
Pass it when using `<WorkflowEditor>` directly.
|
|
123
|
+
- `<PipelineStatus>` accepts an `authProvider` prop (used when it builds its own
|
|
124
|
+
client from `endpointConfig` / `baseUrl`; ignored when you pass `apiClient`).
|
|
125
|
+
- `PipelineViewProps` — the contract for custom pipeline views registered via
|
|
126
|
+
`pipelineViews` — gained an optional `authProvider`, so custom views can build
|
|
127
|
+
authenticated clients the same way the built-in graph/kanban/table views do.
|
|
128
|
+
|
|
129
|
+
### `EndpointConfig.auth` is removed — use an `AuthProvider`
|
|
130
|
+
|
|
131
|
+
The `auth` block on `EndpointConfig` (and its header-injection branch) is gone.
|
|
132
|
+
Authentication is supplied exclusively through an `AuthProvider`, passed to the
|
|
133
|
+
mount/`<App>` `authProvider` option (or `fd.api.configure(config, provider)`).
|
|
134
|
+
`StaticAuthProvider` covers the former static-token cases one-to-one:
|
|
135
|
+
|
|
136
|
+
```js
|
|
137
|
+
// 1.x
|
|
138
|
+
createEndpointConfig('/api/flowdrop', {
|
|
139
|
+
auth: { type: 'bearer', token: TOKEN }
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
// 2.0
|
|
143
|
+
import { StaticAuthProvider } from '@flowdrop/flowdrop';
|
|
144
|
+
mountFlowDropApp(el, {
|
|
145
|
+
endpointConfig: createEndpointConfig('/api/flowdrop'),
|
|
146
|
+
authProvider: new StaticAuthProvider({ type: 'bearer', token: TOKEN })
|
|
147
|
+
});
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
| 1.x `auth` | 2.0 `AuthProvider` |
|
|
151
|
+
| ----------------------------- | ----------------------------------------------------- |
|
|
152
|
+
| `{ type: 'none' }` | `new NoAuthProvider()` (or omit `authProvider`) |
|
|
153
|
+
| `{ type: 'bearer', token }` | `new StaticAuthProvider({ type: 'bearer', token })` |
|
|
154
|
+
| `{ type: 'api_key', apiKey }` | `new StaticAuthProvider({ type: 'api_key', apiKey })` |
|
|
155
|
+
| `{ type: 'custom', headers }` | `new StaticAuthProvider({ type: 'custom', headers })` |
|
|
156
|
+
|
|
157
|
+
`StaticAuthProvider`'s `api_key` type now accepts an optional `apiKeyHeader` to
|
|
158
|
+
override the header name (defaults to `X-API-Key`):
|
|
159
|
+
|
|
160
|
+
```js
|
|
161
|
+
new StaticAuthProvider({ type: 'api_key', apiKey: KEY, apiKeyHeader: 'X-Tenant-Key' });
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
### `AuthProvider.isAuthenticated()` is removed
|
|
165
|
+
|
|
166
|
+
The `isAuthenticated()` method has been dropped from the `AuthProvider`
|
|
167
|
+
interface and all built-in providers. It was never consulted by the library —
|
|
168
|
+
request authentication is driven entirely by `getAuthHeaders()` and the optional
|
|
169
|
+
`onUnauthorized()` / `onForbidden()` hooks. If you implemented a **custom**
|
|
170
|
+
`AuthProvider`, you can delete the method; no replacement is needed.
|
|
171
|
+
|
|
172
|
+
```ts
|
|
173
|
+
// 1.x — required
|
|
174
|
+
const provider: AuthProvider = {
|
|
175
|
+
getAuthHeaders: async () => ({ Authorization: `Bearer ${token}` }),
|
|
176
|
+
isAuthenticated: () => Boolean(token) // ← remove this
|
|
177
|
+
};
|
|
178
|
+
|
|
179
|
+
// 2.0
|
|
180
|
+
const provider: AuthProvider = {
|
|
181
|
+
getAuthHeaders: async () => ({ Authorization: `Bearer ${token}` })
|
|
182
|
+
};
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
### Auth refresh (`401`) now applies to every request
|
|
186
|
+
|
|
187
|
+
Previously only the typed workflow/node API (`fd.api.client`) refreshed and
|
|
188
|
+
retried on `401`. The per-instance services (playground, chat, interrupt,
|
|
189
|
+
settings, port config, categories) and form autocomplete attached auth headers
|
|
190
|
+
but did **not** invoke `onUnauthorized()`. They now all route through one
|
|
191
|
+
authenticated-fetch path, so a configured `onUnauthorized()` fires — and the
|
|
192
|
+
request retries once with a refreshed token — uniformly across the library.
|
|
193
|
+
|
|
194
|
+
This is not a source change for consumers, but if your `onUnauthorized()` had
|
|
195
|
+
side effects (analytics, redirects) it may now be called from request paths
|
|
196
|
+
where it previously was not. Make it idempotent.
|
|
197
|
+
|
|
198
|
+
### Swap the auth provider at runtime — `fd.api.setAuthProvider()`
|
|
199
|
+
|
|
200
|
+
The `AuthProvider` is still supplied at mount time, but you no longer have to
|
|
201
|
+
remount to change it (e.g. on login/logout). `ApiContext` gained
|
|
202
|
+
`setAuthProvider()`, which updates the live client and is picked up by services
|
|
203
|
+
on their next request:
|
|
204
|
+
|
|
205
|
+
```js
|
|
206
|
+
import { getInstance } from '@flowdrop/flowdrop/editor';
|
|
207
|
+
const fd = getInstance();
|
|
208
|
+
|
|
209
|
+
// after the user logs in / refreshes their session
|
|
210
|
+
fd.api.setAuthProvider(new StaticAuthProvider({ type: 'bearer', token: newToken }));
|
|
211
|
+
|
|
212
|
+
// on logout
|
|
213
|
+
fd.api.setAuthProvider(new NoAuthProvider());
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
### Instance-scoped port compatibility
|
|
217
|
+
|
|
218
|
+
`initializePortCompatibility()`, `getPortCompatibilityChecker()`, and
|
|
219
|
+
`isPortCompatibilityInitialized()` are removed. Each instance owns a
|
|
220
|
+
`PortCompatibilityChecker` at `fd.portCompatibility`, seeded with
|
|
221
|
+
`DEFAULT_PORT_CONFIG` and re-initialized by mount from the backend's port
|
|
222
|
+
config. The standalone connection helpers (`validateConnection`,
|
|
223
|
+
`getPossibleConnections`, `getConnectionSuggestions`) now take the checker as
|
|
224
|
+
their first argument.
|
|
225
|
+
|
|
226
|
+
```js
|
|
227
|
+
// 1.x
|
|
228
|
+
import { initializePortCompatibility, validateConnection } from '@flowdrop/flowdrop/editor';
|
|
229
|
+
initializePortCompatibility(portConfig);
|
|
230
|
+
const ok = validateConnection(source, target);
|
|
231
|
+
|
|
232
|
+
// 2.0
|
|
233
|
+
import { getInstance } from '@flowdrop/flowdrop/editor';
|
|
234
|
+
const fd = getInstance();
|
|
235
|
+
const ok = validateConnection(fd.portCompatibility, source, target);
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
## 3. Registries are instance-scoped — importing the editor registers nothing
|
|
239
|
+
|
|
240
|
+
In 1.x the node, field, and format registries were module singletons, and the
|
|
241
|
+
editor barrel ran a side-effecting import that registered every builtin node the
|
|
242
|
+
moment you imported it. In 2.0 each registry lives on the instance —
|
|
243
|
+
`fd.nodes`, `fd.fields`, `fd.formats` — seeded in the constructor from read-only
|
|
244
|
+
builtin definitions. There is no longer any import-time registration, and
|
|
245
|
+
`package.json` `sideEffects` is now CSS-only (`["**/*.css"]`).
|
|
246
|
+
|
|
247
|
+
The module-level registration functions and the singleton registry constants are
|
|
248
|
+
removed:
|
|
249
|
+
|
|
250
|
+
- `registerCustomNode()`, `createFlowDropPlugin()` / `registerFlowDropPlugin()`,
|
|
251
|
+
and `plugin.ts` are gone. Registration is now a registry method:
|
|
252
|
+
`fd.nodes.registerCustom(...)`, `fd.nodes.registerPlugin(...)`,
|
|
253
|
+
`fd.nodes.unregisterPlugin(...)`. `createPlugin().register(fd.nodes)` replaces
|
|
254
|
+
the module plugin functions.
|
|
255
|
+
- The exported singleton consts `nodeComponentRegistry`, `fieldComponentRegistry`,
|
|
256
|
+
and `workflowFormatRegistry` are removed. Resolve the instance registry instead.
|
|
257
|
+
|
|
258
|
+
```js
|
|
259
|
+
// 1.x — module singletons + import-time side effects
|
|
260
|
+
import { registerCustomNode, fieldComponentRegistry } from '@flowdrop/flowdrop/editor';
|
|
261
|
+
registerCustomNode('myapp:color', 'Color Node', ColorNode);
|
|
262
|
+
fieldComponentRegistry.register('color', {
|
|
263
|
+
component: MyColorField,
|
|
264
|
+
matcher: (schema) => schema.format === 'color'
|
|
265
|
+
});
|
|
266
|
+
|
|
267
|
+
// 2.0 — register against the instance after mount
|
|
268
|
+
import { getInstance } from '@flowdrop/flowdrop/editor';
|
|
269
|
+
const fd = getInstance();
|
|
270
|
+
fd.nodes.registerCustom('myapp:color', 'Color Node', ColorNode);
|
|
271
|
+
fd.fields.register('color', {
|
|
272
|
+
component: MyColorField,
|
|
273
|
+
matcher: (schema) => schema.format === 'color'
|
|
274
|
+
});
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
Because registration is now post-mount by construction, late registrations have
|
|
278
|
+
to invalidate `$derived` reads that already ran. `BaseRegistry` carries a
|
|
279
|
+
`$state` version counter (the `editVersion` pattern) so dependent reads
|
|
280
|
+
re-run when you register after the first paint — no host action required.
|
|
281
|
+
|
|
282
|
+
The heavy form-field installers (`registerCodeEditorField`,
|
|
283
|
+
`registerMarkdownEditorField`, and the template field) now take the **target
|
|
284
|
+
registry explicitly** and re-check registration after their dynamic import
|
|
285
|
+
resolves:
|
|
286
|
+
|
|
287
|
+
```js
|
|
288
|
+
// 1.x
|
|
289
|
+
import { registerCodeEditorField } from '@flowdrop/flowdrop/form/code';
|
|
290
|
+
registerCodeEditorField();
|
|
291
|
+
|
|
292
|
+
// 2.0
|
|
293
|
+
import { registerCodeEditorField } from '@flowdrop/flowdrop/form/code';
|
|
294
|
+
import { getInstance } from '@flowdrop/flowdrop/editor';
|
|
295
|
+
registerCodeEditorField(getInstance().fields);
|
|
296
|
+
```
|
|
297
|
+
|
|
298
|
+
Category color/icon helpers likewise take a `CategoriesStore` as an explicit
|
|
299
|
+
parameter — the last global-instance fallback in `utils` is gone.
|
|
300
|
+
|
|
301
|
+
`fd.fields.register()` warns in dev when it overwrites an existing field type.
|
|
302
|
+
Overwriting still works (replacing a built-in field is legitimate); the warning
|
|
303
|
+
flags accidental duplicates.
|
|
304
|
+
|
|
305
|
+
## 4. Barrel de-duplication and the slim main entry
|
|
306
|
+
|
|
307
|
+
### Each export keeps a single canonical home
|
|
308
|
+
|
|
309
|
+
The editor barrel no longer re-exports playground internals, and the display
|
|
310
|
+
barrel no longer re-exports `marked`.
|
|
311
|
+
|
|
312
|
+
- **Playground exports** (`Playground`, `PlaygroundModal`, `ChatPanel`,
|
|
313
|
+
`SessionManager`, `InputCollector`, `ExecutionLogs`, `MessageBubble`,
|
|
314
|
+
`PlaygroundService`, `PlaygroundStore`) are removed from
|
|
315
|
+
`@flowdrop/flowdrop/editor`. Import them from `@flowdrop/flowdrop/playground`
|
|
316
|
+
instead.
|
|
317
|
+
|
|
318
|
+
```js
|
|
319
|
+
// 1.x
|
|
320
|
+
import { Playground, PlaygroundStore } from '@flowdrop/flowdrop/editor';
|
|
321
|
+
|
|
322
|
+
// 2.0
|
|
323
|
+
import { Playground, PlaygroundStore } from '@flowdrop/flowdrop/playground';
|
|
324
|
+
```
|
|
325
|
+
|
|
326
|
+
- **`marked`** is no longer re-exported from `@flowdrop/flowdrop/display`. If you
|
|
327
|
+
need `marked` directly, install it as a dependency and import it from the
|
|
328
|
+
package:
|
|
329
|
+
|
|
330
|
+
```js
|
|
331
|
+
// 1.x
|
|
332
|
+
import { marked } from '@flowdrop/flowdrop/display';
|
|
333
|
+
|
|
334
|
+
// 2.0 — `npm install marked`
|
|
335
|
+
import { marked } from 'marked';
|
|
336
|
+
```
|
|
337
|
+
|
|
338
|
+
### The main entry is now a minimal front door
|
|
339
|
+
|
|
340
|
+
`@flowdrop/flowdrop` (the main entry) no longer re-exports the entire library.
|
|
341
|
+
In 1.x it bundled every sub-module via `export *`; in 2.0 it exposes only the
|
|
342
|
+
small surface most apps need to bootstrap:
|
|
343
|
+
|
|
344
|
+
- **Values:** `App`, `mountFlowDropApp`, `unmountFlowDropApp`,
|
|
345
|
+
`createFlowDropInstance`, `getInstance`, `provideInstance`,
|
|
346
|
+
`createEndpointConfig`, `defaultEndpointConfig`, `NoAuthProvider`,
|
|
347
|
+
`StaticAuthProvider`, `CallbackAuthProvider`.
|
|
348
|
+
- **Types:** `Workflow`, `WorkflowNode`, `WorkflowEdge`, `NodeMetadata`,
|
|
349
|
+
`ConfigSchema`, `EndpointConfig`, `AuthProvider`, `FlowDropInstance`,
|
|
350
|
+
`FlowDropMountOptions`, `MountedFlowDropApp`, `FlowDropEventHandlers`,
|
|
351
|
+
`Messages`, `MessagesOverride`.
|
|
352
|
+
|
|
353
|
+
Everything else moves to a sub-module. If you imported a name from
|
|
354
|
+
`@flowdrop/flowdrop` that is not in the list above, switch to the sub-module
|
|
355
|
+
that owns it:
|
|
356
|
+
|
|
357
|
+
| Name (1.x main entry) | 2.0 sub-module |
|
|
358
|
+
| -------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------- |
|
|
359
|
+
| `WorkflowEditor`, `ConfigForm`, `ConfigModal`, `ConfigPanel`, `Navbar`, `NodeSidebar`, node components | `@flowdrop/flowdrop/editor` |
|
|
360
|
+
| `mountWorkflowEditor`, editor helper classes, `EnhancedFlowDropApiClient`, `ApiContext` | `@flowdrop/flowdrop/editor` |
|
|
361
|
+
| `WorkflowStore`, `HistoryStore`, `HistoryService`, `PortCoordinateStore` | `@flowdrop/flowdrop/editor` |
|
|
362
|
+
| `globalSaveWorkflow`, `globalExportWorkflow`, `saveWorkflow`, `getWorkflow`, draft-storage helpers | `@flowdrop/flowdrop/editor` |
|
|
363
|
+
| `fetchPortConfig`, `fetchCategories`, dynamic-schema helpers | `@flowdrop/flowdrop/editor` |
|
|
364
|
+
| `NodeExecutionService`, connection utilities, `PortCompatibilityChecker` | `@flowdrop/flowdrop/editor` |
|
|
365
|
+
| Toast functions (`showSuccess`, `showError`, `showWarning`, `showInfo`, `showLoading`, `dismissToast`, `showPromise`, `showConfirmation`, …) | `@flowdrop/flowdrop/editor` |
|
|
366
|
+
| `SchemaForm`, `FormField`, `FormSelect`, `FormToggle`, `FormArray`, …, `AutocompleteConfig` | `@flowdrop/flowdrop/form` |
|
|
367
|
+
| `FormAutocomplete` | `@flowdrop/flowdrop/form/autocomplete` |
|
|
368
|
+
| `registerCodeEditorField` | `@flowdrop/flowdrop/form/code` |
|
|
369
|
+
| `registerMarkdownEditorField` | `@flowdrop/flowdrop/form/markdown` |
|
|
370
|
+
| `Playground`, `PlaygroundModal`, `ChatPanel`, `mountPlayground`, `PlaygroundService` | `@flowdrop/flowdrop/playground` |
|
|
371
|
+
| `MarkdownDisplay` | `@flowdrop/flowdrop/display` |
|
|
372
|
+
| `setMessages`, `mergeMessages`, `defaultMessages` | `@flowdrop/flowdrop/core` |
|
|
373
|
+
| Theme/skin exports (`defaultTheme`, `minimalTheme`, `resolveTheme`, `defaultSkin`, `slateSkin`) | `@flowdrop/flowdrop/core` |
|
|
374
|
+
| Color-preference helpers (`theme`, `resolvedTheme`, `setTheme`, `toggleTheme`, …) | `@flowdrop/flowdrop/core` |
|
|
375
|
+
| `WorkflowAdapter`, `AgentSpecAdapter`, command DSL, color/icon utilities, all remaining types | `@flowdrop/flowdrop/core` |
|
|
376
|
+
| Settings stores/services/components | `@flowdrop/flowdrop/settings` |
|
|
377
|
+
|
|
378
|
+
```js
|
|
379
|
+
// 1.x — everything from the main entry
|
|
380
|
+
import { WorkflowEditor, SchemaForm, showSuccess, defaultTheme } from '@flowdrop/flowdrop';
|
|
381
|
+
|
|
382
|
+
// 2.0 — import from the owning sub-module
|
|
383
|
+
import { WorkflowEditor, showSuccess } from '@flowdrop/flowdrop/editor';
|
|
384
|
+
import { SchemaForm } from '@flowdrop/flowdrop/form';
|
|
385
|
+
import { defaultTheme } from '@flowdrop/flowdrop/core';
|
|
386
|
+
```
|
|
387
|
+
|
|
388
|
+
This also tightens tree-shaking: importing `App` and a couple of types from the
|
|
389
|
+
main entry no longer pulls the form, display, playground, and settings barrels
|
|
390
|
+
into your bundle.
|
|
391
|
+
|
|
392
|
+
### Keeping heavy dependencies out of the light entries
|
|
393
|
+
|
|
394
|
+
A few more exports moved so that the lightweight entries (`/core`, the light
|
|
395
|
+
`/form`) never statically pull a heavy dependency (CodeMirror, `marked`,
|
|
396
|
+
DOMPurify, `@xyflow/svelte`). These are enforced by a bundle guard in CI, so
|
|
397
|
+
they cannot silently regress.
|
|
398
|
+
|
|
399
|
+
- **`sanitizeHtml` moved from `@flowdrop/flowdrop/core` to
|
|
400
|
+
`@flowdrop/flowdrop/display`.** It is DOMPurify-backed, and `/core` is the
|
|
401
|
+
"zero heavy dependencies" entry, so it now lives alongside `MarkdownDisplay`.
|
|
402
|
+
|
|
403
|
+
```js
|
|
404
|
+
// before
|
|
405
|
+
import { sanitizeHtml } from '@flowdrop/flowdrop/core';
|
|
406
|
+
// 2.0
|
|
407
|
+
import { sanitizeHtml } from '@flowdrop/flowdrop/display';
|
|
408
|
+
```
|
|
409
|
+
|
|
410
|
+
- **`FormFieldFull` moved from `@flowdrop/flowdrop/form` to
|
|
411
|
+
`@flowdrop/flowdrop/form/full`.** `FormFieldFull` statically bundles every
|
|
412
|
+
editor (including CodeMirror); keeping it in the light `/form` entry pulled
|
|
413
|
+
CodeMirror into every `SchemaForm` import. The default `FormField` exported
|
|
414
|
+
from `/form` is the registry-based light field factory — register heavy
|
|
415
|
+
editors via `/form/code` / `/form/markdown` (unchanged). Use `/form/full`
|
|
416
|
+
only if you specifically want every editor statically bundled.
|
|
417
|
+
|
|
418
|
+
```js
|
|
419
|
+
// before
|
|
420
|
+
import { FormFieldFull } from '@flowdrop/flowdrop/form';
|
|
421
|
+
// 2.0
|
|
422
|
+
import { FormFieldFull } from '@flowdrop/flowdrop/form/full';
|
|
423
|
+
```
|
|
424
|
+
|
|
425
|
+
- **Service singleton _instances_ are no longer exported.**
|
|
426
|
+
`playgroundService` and `interruptService` (`@flowdrop/flowdrop/playground`),
|
|
427
|
+
`nodeExecutionService` (`@flowdrop/flowdrop/editor`), and
|
|
428
|
+
`agentSpecExecutionService` (`@flowdrop/flowdrop/core`) are removed. They were
|
|
429
|
+
module-level instances constructed at import time, which forced the service
|
|
430
|
+
(and its dependencies) to be built the moment the entry was imported. The
|
|
431
|
+
**classes** remain exported (`PlaygroundService`, `InterruptService`,
|
|
432
|
+
`NodeExecutionService`, `AgentSpecExecutionService`). Most apps never touched
|
|
433
|
+
these directly (use `fd.playground` / `fd.interrupts`); if you did, call
|
|
434
|
+
`getInstance()` to obtain the shared instance:
|
|
435
|
+
|
|
436
|
+
```js
|
|
437
|
+
// before
|
|
438
|
+
import { playgroundService } from '@flowdrop/flowdrop/playground';
|
|
439
|
+
// 2.0
|
|
440
|
+
import { PlaygroundService } from '@flowdrop/flowdrop/playground';
|
|
441
|
+
const playgroundService = PlaygroundService.getInstance();
|
|
442
|
+
```
|
|
443
|
+
|
|
444
|
+
## 5. Workflow `metadata` is required and `version` → `schemaVersion`
|
|
445
|
+
|
|
446
|
+
The workflow document's `metadata` object is now **required** on the `Workflow`
|
|
447
|
+
type, and its `version` field has been renamed to `schemaVersion`. The rename
|
|
448
|
+
disambiguates the document's _format_ version from any per-workflow revision
|
|
449
|
+
number you may track yourself (and from `NodeMetadata.version`, the node-type
|
|
450
|
+
version, which is **unchanged**).
|
|
451
|
+
|
|
452
|
+
```ts
|
|
453
|
+
// 1.x
|
|
454
|
+
interface Workflow {
|
|
455
|
+
/* … */
|
|
456
|
+
metadata?: {
|
|
457
|
+
version: string; // ambiguous
|
|
458
|
+
createdAt: string;
|
|
459
|
+
updatedAt: string;
|
|
460
|
+
/* … */
|
|
461
|
+
};
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
// 2.0
|
|
465
|
+
interface Workflow {
|
|
466
|
+
/* … */
|
|
467
|
+
metadata: {
|
|
468
|
+
schemaVersion: string; // the workflow schema format version
|
|
469
|
+
createdAt: string;
|
|
470
|
+
updatedAt: string;
|
|
471
|
+
/* … */
|
|
472
|
+
};
|
|
473
|
+
}
|
|
474
|
+
```
|
|
475
|
+
|
|
476
|
+
### Load-time healing (automatic)
|
|
477
|
+
|
|
478
|
+
You do **not** need to migrate stored workflow JSON by hand. Every workflow
|
|
479
|
+
entry point — `WorkflowStore.initialize` (which backs `mountFlowDropApp`'s
|
|
480
|
+
`workflow` option, drag-and-drop file import, and draft load) and
|
|
481
|
+
`WorkflowAdapter.importWorkflow` — normalizes metadata on the way in:
|
|
482
|
+
|
|
483
|
+
- **Missing `metadata`** → populated with required defaults (`schemaVersion`
|
|
484
|
+
from `WORKFLOW_SCHEMA_VERSION`, fresh `createdAt`/`updatedAt`).
|
|
485
|
+
- **Legacy `metadata.version`** → copied into `schemaVersion` (when
|
|
486
|
+
`schemaVersion` is absent), then the legacy `version` key is dropped.
|
|
487
|
+
|
|
488
|
+
Healing is idempotent: re-running it on an already-healed workflow is a no-op
|
|
489
|
+
(round-trip stable). This mirrors the localStorage key migration in §8 — the
|
|
490
|
+
runtime heals 1.x data on first read so existing documents keep loading.
|
|
491
|
+
|
|
492
|
+
### What hosts reading workflow JSON need to know
|
|
493
|
+
|
|
494
|
+
If your application reads or writes FlowDrop workflow JSON directly (outside the
|
|
495
|
+
editor), update your code to read `metadata.schemaVersion` instead of
|
|
496
|
+
`metadata.version`. Documents still on disk with the old `version` key continue
|
|
497
|
+
to load through the editor unchanged, but newly serialized workflows will carry
|
|
498
|
+
`schemaVersion`. The Agent Spec export still uses the namespaced
|
|
499
|
+
`flowdrop:version` key (its source is now `metadata.schemaVersion`); that
|
|
500
|
+
external key name is unchanged.
|
|
501
|
+
|
|
502
|
+
The JSON Schema published at `@flowdrop/flowdrop/schema` reflects the rename —
|
|
503
|
+
`WorkflowMetadata.required` is now `[schemaVersion, createdAt, updatedAt]`.
|
|
504
|
+
|
|
505
|
+
## 6. Removed component props
|
|
506
|
+
|
|
507
|
+
| Component | Removed | Use instead |
|
|
508
|
+
| ------------------------ | ------------------------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------- |
|
|
509
|
+
| `SchemaForm` | `saveLabel`, `cancelLabel` | `messages.form.schema.save` / `.cancel` |
|
|
510
|
+
| `AIChatPanel` | `placeholder` | `messages.chat.placeholder` |
|
|
511
|
+
| `ChatPanel` | `showChatInput`, `showRunButton` | `MessageStream` directly, or `ControlPanel` (keeps both flags) |
|
|
512
|
+
| `ChatPanel` | `showLogs` | `fd.playground.setShowLogs(...)` |
|
|
513
|
+
| `WorkflowEditor` | `nodes`, `height`, `width`, `isConfigSidebarOpen`, `selectedNodeForConfig`, `closeConfigSidebar` | These never did anything in 1.x. Size via `App`'s `height`/`width` (working since 1.16); node metadata flows through the instance. |
|
|
514
|
+
| `App` / `WorkflowEditor` | `readOnly`, `lockWorkflow` | A single `mode` prop — see [section 6.2](#62-mode-prop-replaces-readonly--lockworkflow). |
|
|
515
|
+
| `App` | `eventHandlers` (object) | Flat `on*` props — see [section 6.3](#63-app-event-handlers-are-flat-props). |
|
|
516
|
+
|
|
517
|
+
`FormToggle.onLabel`/`offLabel` and `FormArray.addLabel` were _un_-deprecated:
|
|
518
|
+
they express per-instance labels the global messages system cannot, and are
|
|
519
|
+
now documented overrides.
|
|
520
|
+
|
|
521
|
+
Removed message keys (only the removed ChatPanel branches read them):
|
|
522
|
+
`playground.states.viewOnlyTitle`, `.viewOnlyText`, `.readyTitle`, `.readyText`.
|
|
523
|
+
|
|
524
|
+
### 6.1 `mountWorkflowEditor` option changes
|
|
525
|
+
|
|
526
|
+
- `workflow` now actually loads the workflow (1.x accepted and ignored it).
|
|
527
|
+
- `nodes` is removed (it fed a prop the editor never read). Use
|
|
528
|
+
`mountFlowDropApp` if you need to pre-seed node metadata.
|
|
529
|
+
- `readOnly` / `lockWorkflow` mount options become a single `mode` option
|
|
530
|
+
(`'edit' | 'readonly' | 'locked'`) — see
|
|
531
|
+
[section 6.2](#62-mode-prop-replaces-readonly--lockworkflow). The grouped
|
|
532
|
+
`eventHandlers` mount option is **unchanged** (an options bag is fine in a JS
|
|
533
|
+
mount API); only the `<App>` _component_ prop is flattened.
|
|
534
|
+
|
|
535
|
+
### 6.2 `mode` prop replaces `readOnly` + `lockWorkflow`
|
|
536
|
+
|
|
537
|
+
`<App>`, `<WorkflowEditor>`, and the `mountFlowDropApp` options bag no longer
|
|
538
|
+
take the `readOnly` and `lockWorkflow` booleans. They are replaced by a single
|
|
539
|
+
`mode` prop/option:
|
|
540
|
+
|
|
541
|
+
```ts
|
|
542
|
+
mode?: 'edit' | 'readonly' | 'locked'; // default: 'edit'
|
|
543
|
+
```
|
|
544
|
+
|
|
545
|
+
**Behavior matrix** (what each mode gates):
|
|
546
|
+
|
|
547
|
+
| mode | node drag / connect / select | proximity-connect | node swap | bottom console panel + toggle |
|
|
548
|
+
| ------------ | ---------------------------- | ----------------- | --------- | ----------------------------- |
|
|
549
|
+
| `'edit'` | enabled | enabled | enabled | available |
|
|
550
|
+
| `'readonly'` | disabled | disabled | disabled | hidden |
|
|
551
|
+
| `'locked'` | disabled | disabled | disabled | hidden |
|
|
552
|
+
|
|
553
|
+
In 1.x, `readOnly` and `lockWorkflow` gated the **exact same** interactions and
|
|
554
|
+
were always combined as `!readOnly && !lockWorkflow`. Any combination of the two
|
|
555
|
+
booleans therefore collapsed to either "edit" (both `false`) or "fully disabled"
|
|
556
|
+
(either `true`) — there was no orthogonal behavior to lose. `'readonly'` and
|
|
557
|
+
`'locked'` behave identically today; the two names are preserved as distinct
|
|
558
|
+
intents so a future release can differentiate them without another breaking
|
|
559
|
+
change.
|
|
560
|
+
|
|
561
|
+
**Old → new mapping** (component prop and mount option are identical):
|
|
562
|
+
|
|
563
|
+
| 1.x | 2.0 |
|
|
564
|
+
| ---------------------------------------------------------- | ------------------------------------------------------ |
|
|
565
|
+
| `readOnly` unset / `false`, `lockWorkflow` unset / `false` | `mode="edit"` (or omit) |
|
|
566
|
+
| `readOnly={true}` | `mode="readonly"` |
|
|
567
|
+
| `lockWorkflow={true}` | `mode="locked"` |
|
|
568
|
+
| both `true` | `mode="readonly"` _or_ `mode="locked"` (same behavior) |
|
|
569
|
+
|
|
570
|
+
```svelte
|
|
571
|
+
<!-- 1.x -->
|
|
572
|
+
<App readOnly={true} />
|
|
573
|
+
<App lockWorkflow={true} />
|
|
574
|
+
|
|
575
|
+
<!-- 2.0 -->
|
|
576
|
+
<App mode="readonly" />
|
|
577
|
+
<App mode="locked" />
|
|
578
|
+
```
|
|
579
|
+
|
|
580
|
+
```js
|
|
581
|
+
// 1.x
|
|
582
|
+
mountFlowDropApp(el, { readOnly: true });
|
|
583
|
+
// 2.0
|
|
584
|
+
mountFlowDropApp(el, { mode: 'readonly' });
|
|
585
|
+
```
|
|
586
|
+
|
|
587
|
+
### 6.3 `<App>` event handlers are flat props
|
|
588
|
+
|
|
589
|
+
The `<App>` component no longer takes a grouped `eventHandlers={{ … }}` object.
|
|
590
|
+
The handlers `<App>` consumes are now individual `on*` props, consistent with
|
|
591
|
+
every other component:
|
|
592
|
+
|
|
593
|
+
```svelte
|
|
594
|
+
<!-- 1.x -->
|
|
595
|
+
<App eventHandlers={{ onApiError, onAfterSave, onWorkflowLoad, onBeforeSwap }} />
|
|
596
|
+
|
|
597
|
+
<!-- 2.0 -->
|
|
598
|
+
<App {onApiError} {onAfterSave} {onWorkflowLoad} {onBeforeSwap} />
|
|
599
|
+
```
|
|
600
|
+
|
|
601
|
+
Available `<App>` callback props: `onBeforeSave`, `onAfterSave`, `onSaveError`,
|
|
602
|
+
`onApiError`, `onWorkflowLoad`, `onBeforeSwap`, `onAfterSwap`.
|
|
603
|
+
|
|
604
|
+
The **`mountFlowDropApp` / `mountPlayground` options bag is unchanged** — keep
|
|
605
|
+
passing the grouped `eventHandlers` object there. The mount functions wire
|
|
606
|
+
`onDirtyStateChange` / `onWorkflowChange` into the instance store, call
|
|
607
|
+
`onBeforeUnmount` on teardown, and forward the remaining handlers to `<App>`'s
|
|
608
|
+
flat props for you. The `FlowDropEventHandlers` type is still exported for use
|
|
609
|
+
with the mount option.
|
|
610
|
+
|
|
611
|
+
## 7. localStorage keys are instance-scoped
|
|
612
|
+
|
|
613
|
+
The page-default instance no longer writes bare keys:
|
|
614
|
+
|
|
615
|
+
| 1.x | 2.0 |
|
|
616
|
+
| ----------------------------- | ------------------------------------- |
|
|
617
|
+
| `flowdrop:draft:<workflowId>` | `flowdrop:draft:default:<workflowId>` |
|
|
618
|
+
| `fd-pipeline-panel-open` | `fd-pipeline-panel-open:default` |
|
|
619
|
+
|
|
620
|
+
Existing user data migrates automatically on first read (copy to the scoped
|
|
621
|
+
key, remove the legacy key). Only hosts reading these keys directly need to
|
|
622
|
+
update. `clearAllDrafts()` still removes everything under `flowdrop:draft:`.
|
|
623
|
+
|
|
624
|
+
## 8. Behavioral notes
|
|
625
|
+
|
|
626
|
+
- `fd.fields.register()` warns in dev when overwriting an existing field type.
|
|
627
|
+
Overwriting still works; the warning flags accidents.
|
|
628
|
+
- Internal `DEV` gates use `esm-env` instead of `import.meta.env`, so the
|
|
629
|
+
package no longer assumes a Vite host.
|