@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.
- package/CHANGELOG.md +475 -0
- package/MIGRATION-2.0.md +472 -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/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 +162 -192
- package/dist/components/App.svelte.d.ts +47 -8
- package/dist/components/ConfigForm.svelte +71 -47
- 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 +16 -67
- package/dist/components/PortCoordinateTracker.svelte +5 -6
- package/dist/components/SchemaForm.stories.svelte +1 -3
- package/dist/components/SchemaForm.svelte +18 -25
- 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 +118 -111
- package/dist/components/WorkflowEditor.svelte.d.ts +18 -10
- package/dist/components/chat/AIChatPanel.svelte +93 -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 +8 -6
- package/dist/components/form/FormField.svelte +4 -2
- package/dist/components/form/FormFieldLight.svelte +4 -2
- 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/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 +16 -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 +65 -6
- package/dist/components/playground/PipelinePanel.svelte +11 -5
- package/dist/components/playground/PipelineTableView.svelte +186 -44
- package/dist/components/playground/Playground.svelte +90 -92
- package/dist/components/playground/Playground.svelte.d.ts +2 -0
- package/dist/components/playground/PlaygroundApp.svelte +6 -1
- package/dist/components/playground/PlaygroundApp.svelte.d.ts +3 -0
- package/dist/components/playground/PlaygroundModal.svelte +13 -3
- package/dist/components/playground/PlaygroundModal.svelte.d.ts +3 -0
- package/dist/components/playground/PlaygroundStudio.svelte +34 -32
- package/dist/components/playground/PlaygroundStudio.svelte.d.ts +3 -0
- package/dist/components/playground/SessionManager.svelte +9 -12
- package/dist/components/playground/pipelineViewUtils.svelte.d.ts +28 -0
- package/dist/components/playground/pipelineViewUtils.svelte.js +38 -1
- package/dist/config/endpoints.d.ts +0 -7
- package/dist/config/endpoints.js +2 -10
- package/dist/core/index.d.ts +4 -4
- package/dist/core/index.js +6 -6
- package/dist/display/index.d.ts +0 -2
- package/dist/display/index.js +0 -6
- package/dist/editor/index.d.ts +19 -20
- package/dist/editor/index.js +25 -35
- 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 +17 -13
- package/dist/form/full.js +22 -27
- package/dist/form/index.d.ts +3 -3
- package/dist/form/index.js +3 -3
- 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 +12 -5
- package/dist/helpers/workflowEditorHelper.js +27 -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 +2 -3
- package/dist/playground/index.js +2 -30
- package/dist/playground/mount.d.ts +15 -0
- package/dist/playground/mount.js +46 -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/builtinNodes.d.ts +0 -25
- package/dist/registry/builtinNodes.js +1 -50
- 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.js +0 -1
- package/dist/services/apiVariableService.d.ts +2 -1
- package/dist/services/apiVariableService.js +5 -22
- package/dist/services/autoSaveService.d.ts +7 -0
- package/dist/services/autoSaveService.js +6 -4
- package/dist/services/chatService.d.ts +8 -4
- package/dist/services/chatService.js +15 -15
- 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 +14 -9
- package/dist/services/interruptService.js +27 -27
- package/dist/services/nodeExecutionService.d.ts +18 -3
- package/dist/services/nodeExecutionService.js +71 -45
- package/dist/services/playgroundService.d.ts +14 -9
- package/dist/services/playgroundService.js +31 -30
- 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 +45 -0
- package/dist/stores/apiContext.js +65 -0
- package/dist/stores/categoriesStore.svelte.d.ts +28 -23
- package/dist/stores/categoriesStore.svelte.js +70 -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 +515 -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 +157 -53
- package/dist/types/events.d.ts +6 -3
- package/dist/types/index.d.ts +33 -3
- 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/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 +26 -19
- package/dist/utils/performanceUtils.js +7 -0
- package/package.json +6 -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
|
@@ -4,171 +4,198 @@
|
|
|
4
4
|
* Rune-based reactive state for managing interrupt state using a lightweight state machine.
|
|
5
5
|
* Ensures valid state transitions and prevents deadlocks.
|
|
6
6
|
*
|
|
7
|
+
* The reactive state lives in the {@link InterruptStore} class — one per
|
|
8
|
+
* FlowDrop instance, resolved in components via `getInstance().interrupts`.
|
|
9
|
+
*
|
|
7
10
|
* @module stores/interruptStore
|
|
8
11
|
*/
|
|
9
12
|
import { SvelteMap } from 'svelte/reactivity';
|
|
10
13
|
import { initialState, transition, isTerminalState, isSubmitting as checkIsSubmitting, hasError as checkHasError, getErrorMessage, getResolvedValue, toLegacyStatus } from '../types/interruptState.js';
|
|
11
14
|
import { logger } from '../utils/logger.js';
|
|
12
15
|
// =========================================================================
|
|
13
|
-
//
|
|
14
|
-
// =========================================================================
|
|
15
|
-
/**
|
|
16
|
-
* Reactive map of all interrupts by ID.
|
|
17
|
-
* Uses SvelteMap for deep reactivity with Svelte 5 runes.
|
|
18
|
-
* Key: interrupt ID, Value: Interrupt object with state
|
|
19
|
-
*/
|
|
20
|
-
let interrupts = $state(new SvelteMap());
|
|
21
|
-
// =========================================================================
|
|
22
|
-
// Getter Functions (replace derived stores)
|
|
16
|
+
// InterruptStore (per-instance reactive state)
|
|
23
17
|
// =========================================================================
|
|
24
18
|
/**
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
}
|
|
31
|
-
/**
|
|
32
|
-
* Get pending interrupt IDs (interrupts not in a terminal state)
|
|
33
|
-
*/
|
|
34
|
-
export function getPendingInterruptIds() {
|
|
35
|
-
const pending = [];
|
|
36
|
-
interrupts.forEach((interrupt, id) => {
|
|
37
|
-
if (!isTerminalState(interrupt.machineState)) {
|
|
38
|
-
pending.push(id);
|
|
39
|
-
}
|
|
40
|
-
});
|
|
41
|
-
return pending;
|
|
42
|
-
}
|
|
43
|
-
/**
|
|
44
|
-
* Get pending interrupts array (interrupts not in a terminal state)
|
|
45
|
-
*/
|
|
46
|
-
export function getPendingInterrupts() {
|
|
47
|
-
const pending = [];
|
|
48
|
-
interrupts.forEach((interrupt) => {
|
|
49
|
-
if (!isTerminalState(interrupt.machineState)) {
|
|
50
|
-
pending.push(interrupt);
|
|
51
|
-
}
|
|
52
|
-
});
|
|
53
|
-
return pending;
|
|
54
|
-
}
|
|
55
|
-
/**
|
|
56
|
-
* Get count of pending interrupts
|
|
19
|
+
* Per-instance interrupt state, managed via a lightweight state machine.
|
|
20
|
+
*
|
|
21
|
+
* Reads go through getter methods backed by a {@link SvelteMap}, so reading
|
|
22
|
+
* them inside a component template or `$derived` tracks reactively, exactly
|
|
23
|
+
* like the legacy module-level functions did.
|
|
57
24
|
*/
|
|
58
|
-
export
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
25
|
+
export class InterruptStore {
|
|
26
|
+
/**
|
|
27
|
+
* Reactive map of all interrupts by ID.
|
|
28
|
+
* Uses SvelteMap for deep reactivity with Svelte 5 runes.
|
|
29
|
+
* Key: interrupt ID, Value: Interrupt object with state
|
|
30
|
+
*/
|
|
31
|
+
#interrupts = new SvelteMap();
|
|
32
|
+
/** Bound mutation facade — see {@link InterruptStoreActions}. */
|
|
33
|
+
actions;
|
|
34
|
+
constructor() {
|
|
35
|
+
this.actions = Object.freeze({
|
|
36
|
+
addInterrupt: this.addInterrupt.bind(this),
|
|
37
|
+
addInterrupts: this.addInterrupts.bind(this),
|
|
38
|
+
startSubmit: this.startSubmit.bind(this),
|
|
39
|
+
startCancel: this.startCancel.bind(this),
|
|
40
|
+
submitSuccess: this.submitSuccess.bind(this),
|
|
41
|
+
submitFailure: this.submitFailure.bind(this),
|
|
42
|
+
retry: this.retry.bind(this),
|
|
43
|
+
resetInterrupt: this.resetInterrupt.bind(this),
|
|
44
|
+
resolveInterrupt: this.resolveInterrupt.bind(this),
|
|
45
|
+
cancelInterrupt: this.cancelInterrupt.bind(this),
|
|
46
|
+
removeInterrupt: this.removeInterrupt.bind(this),
|
|
47
|
+
clearSessionInterrupts: this.clearSessionInterrupts.bind(this),
|
|
48
|
+
clearInterrupts: this.clearInterrupts.bind(this),
|
|
49
|
+
reset: this.reset.bind(this)
|
|
50
|
+
});
|
|
63
51
|
}
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
52
|
+
// -----------------------------------------------------------------------
|
|
53
|
+
// Reactive getters (replace derived stores)
|
|
54
|
+
// -----------------------------------------------------------------------
|
|
55
|
+
/**
|
|
56
|
+
* Get the reactive interrupts map.
|
|
57
|
+
* Use this in components within $derived() for reactivity.
|
|
58
|
+
*/
|
|
59
|
+
getMap() {
|
|
60
|
+
return this.#interrupts;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Get pending interrupt IDs (interrupts not in a terminal state)
|
|
64
|
+
*/
|
|
65
|
+
getPendingIds() {
|
|
66
|
+
const pending = [];
|
|
67
|
+
this.#interrupts.forEach((interrupt, id) => {
|
|
68
|
+
if (!isTerminalState(interrupt.machineState)) {
|
|
69
|
+
pending.push(id);
|
|
70
|
+
}
|
|
71
|
+
});
|
|
72
|
+
return pending;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Get pending interrupts array (interrupts not in a terminal state)
|
|
76
|
+
*/
|
|
77
|
+
getPending() {
|
|
78
|
+
const pending = [];
|
|
79
|
+
this.#interrupts.forEach((interrupt) => {
|
|
80
|
+
if (!isTerminalState(interrupt.machineState)) {
|
|
81
|
+
pending.push(interrupt);
|
|
82
|
+
}
|
|
83
|
+
});
|
|
84
|
+
return pending;
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Get count of pending interrupts
|
|
88
|
+
*/
|
|
89
|
+
getPendingCount() {
|
|
90
|
+
let count = 0;
|
|
91
|
+
for (const interrupt of this.#interrupts.values()) {
|
|
92
|
+
if (!isTerminalState(interrupt.machineState))
|
|
93
|
+
count++;
|
|
85
94
|
}
|
|
95
|
+
return count;
|
|
86
96
|
}
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
*/
|
|
99
|
-
function applyAction(interruptId, action) {
|
|
100
|
-
const interrupt = interrupts.get(interruptId);
|
|
101
|
-
if (!interrupt) {
|
|
102
|
-
return {
|
|
103
|
-
state: initialState,
|
|
104
|
-
valid: false,
|
|
105
|
-
error: `Interrupt not found: ${interruptId}`
|
|
106
|
-
};
|
|
97
|
+
/**
|
|
98
|
+
* Get resolved interrupts array
|
|
99
|
+
*/
|
|
100
|
+
getResolved() {
|
|
101
|
+
const resolved = [];
|
|
102
|
+
this.#interrupts.forEach((interrupt) => {
|
|
103
|
+
if (interrupt.machineState.status === 'resolved') {
|
|
104
|
+
resolved.push(interrupt);
|
|
105
|
+
}
|
|
106
|
+
});
|
|
107
|
+
return resolved;
|
|
107
108
|
}
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
status: toLegacyStatus(result.state),
|
|
117
|
-
responseValue: getResolvedValue(result.state) ?? current.responseValue,
|
|
118
|
-
resolvedAt: result.state.status === 'resolved'
|
|
119
|
-
? result.state.resolvedAt
|
|
120
|
-
: result.state.status === 'cancelled'
|
|
121
|
-
? result.state.cancelledAt
|
|
122
|
-
: current.resolvedAt
|
|
123
|
-
};
|
|
124
|
-
interrupts.set(interruptId, newInterrupt);
|
|
109
|
+
/**
|
|
110
|
+
* Check if any interrupt is currently submitting
|
|
111
|
+
*/
|
|
112
|
+
getIsAnySubmitting() {
|
|
113
|
+
for (const interrupt of this.#interrupts.values()) {
|
|
114
|
+
if (checkIsSubmitting(interrupt.machineState)) {
|
|
115
|
+
return true;
|
|
116
|
+
}
|
|
125
117
|
}
|
|
118
|
+
return false;
|
|
126
119
|
}
|
|
127
|
-
|
|
128
|
-
|
|
120
|
+
// -----------------------------------------------------------------------
|
|
121
|
+
// State machine internals
|
|
122
|
+
// -----------------------------------------------------------------------
|
|
123
|
+
/**
|
|
124
|
+
* Apply a state machine action to an interrupt
|
|
125
|
+
*
|
|
126
|
+
* @param interruptId - The interrupt ID
|
|
127
|
+
* @param action - The action to apply
|
|
128
|
+
* @returns Transition result with validity and any errors
|
|
129
|
+
*/
|
|
130
|
+
#applyAction(interruptId, action) {
|
|
131
|
+
const interrupt = this.#interrupts.get(interruptId);
|
|
132
|
+
if (!interrupt) {
|
|
133
|
+
return {
|
|
134
|
+
state: initialState,
|
|
135
|
+
valid: false,
|
|
136
|
+
error: `Interrupt not found: ${interruptId}`
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
const result = transition(interrupt.machineState, action);
|
|
140
|
+
if (result.valid) {
|
|
141
|
+
const current = this.#interrupts.get(interruptId);
|
|
142
|
+
if (current) {
|
|
143
|
+
// Update machine state and sync legacy fields
|
|
144
|
+
const newInterrupt = {
|
|
145
|
+
...current,
|
|
146
|
+
machineState: result.state,
|
|
147
|
+
status: toLegacyStatus(result.state),
|
|
148
|
+
responseValue: getResolvedValue(result.state) ?? current.responseValue,
|
|
149
|
+
resolvedAt: result.state.status === 'resolved'
|
|
150
|
+
? result.state.resolvedAt
|
|
151
|
+
: result.state.status === 'cancelled'
|
|
152
|
+
? result.state.cancelledAt
|
|
153
|
+
: current.resolvedAt
|
|
154
|
+
};
|
|
155
|
+
this.#interrupts.set(interruptId, newInterrupt);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
else {
|
|
159
|
+
logger.warn(`[InterruptStore] Invalid transition: ${result.error}`);
|
|
160
|
+
}
|
|
161
|
+
return result;
|
|
129
162
|
}
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
//
|
|
133
|
-
// Public Actions
|
|
134
|
-
// =========================================================================
|
|
135
|
-
/**
|
|
136
|
-
* Interrupt store actions for modifying state
|
|
137
|
-
*/
|
|
138
|
-
export const interruptActions = {
|
|
163
|
+
// -----------------------------------------------------------------------
|
|
164
|
+
// Public actions
|
|
165
|
+
// -----------------------------------------------------------------------
|
|
139
166
|
/**
|
|
140
167
|
* Add or update an interrupt in the store
|
|
141
168
|
*
|
|
142
169
|
* @param interrupt - The interrupt to add or update
|
|
143
170
|
*/
|
|
144
|
-
addInterrupt
|
|
145
|
-
const existing = interrupts.get(interrupt.id);
|
|
171
|
+
addInterrupt(interrupt) {
|
|
172
|
+
const existing = this.#interrupts.get(interrupt.id);
|
|
146
173
|
// Preserve existing machine state if interrupt already exists
|
|
147
174
|
const machineState = existing?.machineState ?? initialState;
|
|
148
175
|
const interruptWithState = {
|
|
149
176
|
...interrupt,
|
|
150
177
|
machineState
|
|
151
178
|
};
|
|
152
|
-
interrupts.set(interrupt.id, interruptWithState);
|
|
153
|
-
}
|
|
179
|
+
this.#interrupts.set(interrupt.id, interruptWithState);
|
|
180
|
+
}
|
|
154
181
|
/**
|
|
155
182
|
* Add multiple interrupts to the store
|
|
156
183
|
*
|
|
157
184
|
* @param interruptList - Array of interrupts to add
|
|
158
185
|
*/
|
|
159
|
-
addInterrupts
|
|
186
|
+
addInterrupts(interruptList) {
|
|
160
187
|
if (interruptList.length === 0)
|
|
161
188
|
return;
|
|
162
189
|
interruptList.forEach((interrupt) => {
|
|
163
|
-
const existing = interrupts.get(interrupt.id);
|
|
190
|
+
const existing = this.#interrupts.get(interrupt.id);
|
|
164
191
|
const machineState = existing?.machineState ?? initialState;
|
|
165
192
|
const interruptWithState = {
|
|
166
193
|
...interrupt,
|
|
167
194
|
machineState
|
|
168
195
|
};
|
|
169
|
-
interrupts.set(interrupt.id, interruptWithState);
|
|
196
|
+
this.#interrupts.set(interrupt.id, interruptWithState);
|
|
170
197
|
});
|
|
171
|
-
}
|
|
198
|
+
}
|
|
172
199
|
/**
|
|
173
200
|
* Start submitting an interrupt (user clicked submit)
|
|
174
201
|
*
|
|
@@ -176,27 +203,27 @@ export const interruptActions = {
|
|
|
176
203
|
* @param value - The value being submitted
|
|
177
204
|
* @returns Transition result
|
|
178
205
|
*/
|
|
179
|
-
startSubmit
|
|
180
|
-
return applyAction(interruptId, { type: 'SUBMIT', value });
|
|
181
|
-
}
|
|
206
|
+
startSubmit(interruptId, value) {
|
|
207
|
+
return this.#applyAction(interruptId, { type: 'SUBMIT', value });
|
|
208
|
+
}
|
|
182
209
|
/**
|
|
183
210
|
* Start cancelling an interrupt (user clicked cancel)
|
|
184
211
|
*
|
|
185
212
|
* @param interruptId - The interrupt ID
|
|
186
213
|
* @returns Transition result
|
|
187
214
|
*/
|
|
188
|
-
startCancel
|
|
189
|
-
return applyAction(interruptId, { type: 'CANCEL' });
|
|
190
|
-
}
|
|
215
|
+
startCancel(interruptId) {
|
|
216
|
+
return this.#applyAction(interruptId, { type: 'CANCEL' });
|
|
217
|
+
}
|
|
191
218
|
/**
|
|
192
219
|
* Mark submission as successful
|
|
193
220
|
*
|
|
194
221
|
* @param interruptId - The interrupt ID
|
|
195
222
|
* @returns Transition result
|
|
196
223
|
*/
|
|
197
|
-
submitSuccess
|
|
198
|
-
return applyAction(interruptId, { type: 'SUCCESS' });
|
|
199
|
-
}
|
|
224
|
+
submitSuccess(interruptId) {
|
|
225
|
+
return this.#applyAction(interruptId, { type: 'SUCCESS' });
|
|
226
|
+
}
|
|
200
227
|
/**
|
|
201
228
|
* Mark submission as failed
|
|
202
229
|
*
|
|
@@ -204,148 +231,148 @@ export const interruptActions = {
|
|
|
204
231
|
* @param error - Error message
|
|
205
232
|
* @returns Transition result
|
|
206
233
|
*/
|
|
207
|
-
submitFailure
|
|
208
|
-
return applyAction(interruptId, { type: 'FAILURE', error });
|
|
209
|
-
}
|
|
234
|
+
submitFailure(interruptId, error) {
|
|
235
|
+
return this.#applyAction(interruptId, { type: 'FAILURE', error });
|
|
236
|
+
}
|
|
210
237
|
/**
|
|
211
238
|
* Retry a failed submission
|
|
212
239
|
*
|
|
213
240
|
* @param interruptId - The interrupt ID
|
|
214
241
|
* @returns Transition result
|
|
215
242
|
*/
|
|
216
|
-
retry
|
|
217
|
-
return applyAction(interruptId, { type: 'RETRY' });
|
|
218
|
-
}
|
|
243
|
+
retry(interruptId) {
|
|
244
|
+
return this.#applyAction(interruptId, { type: 'RETRY' });
|
|
245
|
+
}
|
|
219
246
|
/**
|
|
220
247
|
* Reset an interrupt to idle state
|
|
221
248
|
*
|
|
222
249
|
* @param interruptId - The interrupt ID
|
|
223
250
|
* @returns Transition result
|
|
224
251
|
*/
|
|
225
|
-
resetInterrupt
|
|
226
|
-
return applyAction(interruptId, { type: 'RESET' });
|
|
227
|
-
}
|
|
252
|
+
resetInterrupt(interruptId) {
|
|
253
|
+
return this.#applyAction(interruptId, { type: 'RESET' });
|
|
254
|
+
}
|
|
228
255
|
/**
|
|
229
256
|
* Mark an interrupt as resolved with the user's response
|
|
230
257
|
*
|
|
231
258
|
* @param interruptId - The interrupt ID
|
|
232
259
|
* @param value - The resolved value
|
|
233
260
|
*/
|
|
234
|
-
resolveInterrupt
|
|
235
|
-
const submitResult = applyAction(interruptId, { type: 'SUBMIT', value });
|
|
261
|
+
resolveInterrupt(interruptId, value) {
|
|
262
|
+
const submitResult = this.#applyAction(interruptId, { type: 'SUBMIT', value });
|
|
236
263
|
if (submitResult.valid) {
|
|
237
|
-
applyAction(interruptId, { type: 'SUCCESS' });
|
|
264
|
+
this.#applyAction(interruptId, { type: 'SUCCESS' });
|
|
238
265
|
}
|
|
239
|
-
}
|
|
266
|
+
}
|
|
240
267
|
/**
|
|
241
268
|
* Mark an interrupt as cancelled
|
|
242
269
|
*
|
|
243
270
|
* @param interruptId - The interrupt ID
|
|
244
271
|
*/
|
|
245
|
-
cancelInterrupt
|
|
246
|
-
const cancelResult = applyAction(interruptId, { type: 'CANCEL' });
|
|
272
|
+
cancelInterrupt(interruptId) {
|
|
273
|
+
const cancelResult = this.#applyAction(interruptId, { type: 'CANCEL' });
|
|
247
274
|
if (cancelResult.valid) {
|
|
248
|
-
applyAction(interruptId, { type: 'SUCCESS' });
|
|
275
|
+
this.#applyAction(interruptId, { type: 'SUCCESS' });
|
|
249
276
|
}
|
|
250
|
-
}
|
|
277
|
+
}
|
|
251
278
|
/**
|
|
252
279
|
* Remove an interrupt from the store
|
|
253
280
|
*
|
|
254
281
|
* @param interruptId - The interrupt ID to remove
|
|
255
282
|
*/
|
|
256
|
-
removeInterrupt
|
|
257
|
-
interrupts.delete(interruptId);
|
|
258
|
-
}
|
|
283
|
+
removeInterrupt(interruptId) {
|
|
284
|
+
this.#interrupts.delete(interruptId);
|
|
285
|
+
}
|
|
259
286
|
/**
|
|
260
287
|
* Clear all interrupts for a specific session
|
|
261
288
|
*
|
|
262
289
|
* @param sessionId - The session ID to clear interrupts for
|
|
263
290
|
*/
|
|
264
|
-
clearSessionInterrupts
|
|
291
|
+
clearSessionInterrupts(sessionId) {
|
|
265
292
|
const toDelete = [];
|
|
266
|
-
interrupts.forEach((interrupt, id) => {
|
|
293
|
+
this.#interrupts.forEach((interrupt, id) => {
|
|
267
294
|
if (interrupt.sessionId === sessionId) {
|
|
268
295
|
toDelete.push(id);
|
|
269
296
|
}
|
|
270
297
|
});
|
|
271
|
-
toDelete.forEach((id) => interrupts.delete(id));
|
|
272
|
-
}
|
|
298
|
+
toDelete.forEach((id) => this.#interrupts.delete(id));
|
|
299
|
+
}
|
|
273
300
|
/**
|
|
274
301
|
* Alias for clearSessionInterrupts
|
|
275
302
|
*/
|
|
276
|
-
clearInterrupts
|
|
277
|
-
interrupts.clear();
|
|
278
|
-
}
|
|
303
|
+
clearInterrupts() {
|
|
304
|
+
this.#interrupts.clear();
|
|
305
|
+
}
|
|
279
306
|
/**
|
|
280
307
|
* Reset all interrupt state
|
|
281
308
|
*/
|
|
282
|
-
reset
|
|
283
|
-
interrupts.clear();
|
|
309
|
+
reset() {
|
|
310
|
+
this.#interrupts.clear();
|
|
284
311
|
}
|
|
285
|
-
|
|
286
|
-
//
|
|
287
|
-
//
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
312
|
+
// -----------------------------------------------------------------------
|
|
313
|
+
// Utilities
|
|
314
|
+
// -----------------------------------------------------------------------
|
|
315
|
+
/**
|
|
316
|
+
* Get an interrupt by ID
|
|
317
|
+
*
|
|
318
|
+
* @param interruptId - The interrupt ID
|
|
319
|
+
* @returns The interrupt or undefined
|
|
320
|
+
*/
|
|
321
|
+
getInterrupt(interruptId) {
|
|
322
|
+
return this.#interrupts.get(interruptId);
|
|
323
|
+
}
|
|
324
|
+
/**
|
|
325
|
+
* Check if an interrupt is pending (not resolved or cancelled)
|
|
326
|
+
*
|
|
327
|
+
* @param interruptId - The interrupt ID
|
|
328
|
+
* @returns True if the interrupt exists and is pending
|
|
329
|
+
*/
|
|
330
|
+
isPending(interruptId) {
|
|
331
|
+
const interrupt = this.#interrupts.get(interruptId);
|
|
332
|
+
return interrupt ? !isTerminalState(interrupt.machineState) : false;
|
|
333
|
+
}
|
|
334
|
+
/**
|
|
335
|
+
* Check if an interrupt is currently submitting
|
|
336
|
+
*
|
|
337
|
+
* @param interruptId - The interrupt ID
|
|
338
|
+
* @returns True if the interrupt is being submitted
|
|
339
|
+
*/
|
|
340
|
+
isSubmitting(interruptId) {
|
|
341
|
+
const interrupt = this.#interrupts.get(interruptId);
|
|
342
|
+
return interrupt ? checkIsSubmitting(interrupt.machineState) : false;
|
|
343
|
+
}
|
|
344
|
+
/**
|
|
345
|
+
* Get the error for an interrupt
|
|
346
|
+
*
|
|
347
|
+
* @param interruptId - The interrupt ID
|
|
348
|
+
* @returns The error message or undefined
|
|
349
|
+
*/
|
|
350
|
+
getError(interruptId) {
|
|
351
|
+
const interrupt = this.#interrupts.get(interruptId);
|
|
352
|
+
return interrupt ? getErrorMessage(interrupt.machineState) : undefined;
|
|
353
|
+
}
|
|
354
|
+
/**
|
|
355
|
+
* Get an interrupt by its associated message ID
|
|
356
|
+
*
|
|
357
|
+
* @param messageId - The message ID
|
|
358
|
+
* @returns The interrupt or undefined
|
|
359
|
+
*/
|
|
360
|
+
getByMessageId(messageId) {
|
|
361
|
+
for (const interrupt of this.#interrupts.values()) {
|
|
362
|
+
if (interrupt.messageId === messageId) {
|
|
363
|
+
return interrupt;
|
|
364
|
+
}
|
|
338
365
|
}
|
|
366
|
+
return undefined;
|
|
367
|
+
}
|
|
368
|
+
/**
|
|
369
|
+
* Check if an interrupt has an error
|
|
370
|
+
*
|
|
371
|
+
* @param interruptId - The interrupt ID
|
|
372
|
+
* @returns True if the interrupt has an error
|
|
373
|
+
*/
|
|
374
|
+
hasError(interruptId) {
|
|
375
|
+
const interrupt = this.#interrupts.get(interruptId);
|
|
376
|
+
return interrupt ? checkHasError(interrupt.machineState) : false;
|
|
339
377
|
}
|
|
340
|
-
return undefined;
|
|
341
|
-
}
|
|
342
|
-
/**
|
|
343
|
-
* Check if an interrupt has an error
|
|
344
|
-
*
|
|
345
|
-
* @param interruptId - The interrupt ID
|
|
346
|
-
* @returns True if the interrupt has an error
|
|
347
|
-
*/
|
|
348
|
-
export function interruptHasError(interruptId) {
|
|
349
|
-
const interrupt = interrupts.get(interruptId);
|
|
350
|
-
return interrupt ? checkHasError(interrupt.machineState) : false;
|
|
351
378
|
}
|
|
@@ -1,6 +1,30 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Pipeline Panel Store for FlowDrop (Svelte 5 Runes)
|
|
3
|
+
*
|
|
4
|
+
* Tracks whether the pipeline panel is open, persisting the choice to
|
|
5
|
+
* localStorage so it survives reloads.
|
|
6
|
+
*
|
|
7
|
+
* The reactive state lives in the {@link PipelinePanelStore} class — one per
|
|
8
|
+
* FlowDrop instance, resolved in components via `getInstance().pipelinePanel`.
|
|
9
|
+
*
|
|
10
|
+
* @module stores/pipelinePanelStore
|
|
11
|
+
*/
|
|
12
|
+
/**
|
|
13
|
+
* Per-instance pipeline panel open state.
|
|
14
|
+
*
|
|
15
|
+
* Reads go through the {@link isOpen} getter backed by `$state`, so they track
|
|
16
|
+
* reactively in templates and `$derived`.
|
|
17
|
+
*/
|
|
18
|
+
export declare class PipelinePanelStore {
|
|
19
|
+
#private;
|
|
20
|
+
/** @param instanceId - Instance id used to scope the localStorage key. */
|
|
21
|
+
constructor(instanceId: string);
|
|
22
|
+
/** Whether the pipeline panel is currently open (reactive). */
|
|
23
|
+
get isOpen(): boolean;
|
|
24
|
+
/** Initialize open state from localStorage. */
|
|
3
25
|
init(): void;
|
|
26
|
+
/** Toggle the panel open/closed, persisting the new state. */
|
|
4
27
|
toggle(): void;
|
|
28
|
+
/** Set the panel open state explicitly, persisting it. */
|
|
5
29
|
setOpen(value: boolean): void;
|
|
6
|
-
}
|
|
30
|
+
}
|