@flowdrop/flowdrop 1.6.0 → 1.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +10 -0
- package/dist/components/App.svelte +153 -84
- package/dist/components/App.svelte.d.ts +16 -1
- package/dist/components/ConfigModal.svelte +2 -1
- package/dist/components/ConfigPanel.svelte +3 -2
- package/dist/components/FlowDropZone.svelte +2 -1
- package/dist/components/LogsSidebar.svelte +3 -2
- package/dist/components/Navbar.svelte +10 -6
- package/dist/components/NodeSidebar.svelte +4 -3
- package/dist/components/NodeStatusOverlay.svelte +14 -7
- package/dist/components/NodeSwapPicker.svelte +2 -1
- package/dist/components/PipelineStatus.svelte +10 -7
- package/dist/components/ReadOnlyDetails.svelte +4 -2
- package/dist/components/SchemaForm.svelte +20 -9
- package/dist/components/SchemaForm.svelte.d.ts +2 -4
- package/dist/components/SettingsModal.svelte +4 -3
- package/dist/components/SettingsPanel.svelte +3 -2
- package/dist/components/SwapMappingEditor.svelte +2 -1
- package/dist/components/WorkflowEditor.svelte +3 -2
- package/dist/components/chat/AIChatPanel.svelte +22 -7
- package/dist/components/chat/AIChatPanel.svelte.d.ts +3 -0
- package/dist/components/chat/CommandPreview.svelte +10 -6
- package/dist/components/console/CommandConsole.svelte +4 -3
- package/dist/components/form/FormArray.svelte +33 -20
- package/dist/components/form/FormArray.svelte.d.ts +3 -1
- package/dist/components/form/FormAutocomplete.svelte +18 -7
- package/dist/components/form/FormCodeEditor.svelte +6 -4
- package/dist/components/form/FormFieldWrapper.svelte +2 -1
- package/dist/components/form/FormMarkdownEditor.svelte +152 -108
- package/dist/components/form/FormMarkdownEditor.svelte.d.ts +1 -1
- package/dist/components/form/FormTemplateEditor.svelte +2 -1
- package/dist/components/form/FormToggle.svelte +23 -5
- package/dist/components/form/FormToggle.svelte.d.ts +6 -2
- package/dist/components/interrupt/ChoicePrompt.svelte +14 -5
- package/dist/components/interrupt/ConfirmationPrompt.svelte +8 -5
- package/dist/components/interrupt/FormPrompt.svelte +28 -7
- package/dist/components/interrupt/InterruptBubble.svelte +27 -18
- package/dist/components/interrupt/ReviewPrompt.svelte +32 -22
- package/dist/components/interrupt/TextInputPrompt.svelte +12 -5
- package/dist/components/layouts/MainLayout.svelte +4 -3
- package/dist/components/nodes/GatewayNode.svelte +8 -3
- package/dist/components/nodes/IdeaNode.svelte +2 -1
- package/dist/components/nodes/NotesNode.svelte +18 -12
- package/dist/components/nodes/SimpleNode.svelte +8 -8
- package/dist/components/nodes/WorkflowNode.svelte +8 -3
- package/dist/components/playground/ChatPanel.svelte +36 -24
- package/dist/components/playground/MessageBubble.svelte +15 -7
- package/dist/components/playground/Playground.svelte +2 -1
- package/dist/components/playground/PlaygroundModal.svelte +2 -1
- package/dist/components/playground/SessionManager.svelte +14 -10
- package/dist/core/index.d.ts +2 -0
- package/dist/core/index.js +9 -0
- package/dist/editor/index.d.ts +1 -1
- package/dist/editor/index.js +1 -1
- package/dist/messages/context.d.ts +29 -0
- package/dist/messages/context.js +38 -0
- package/dist/messages/defaults.d.ts +396 -0
- package/dist/messages/defaults.js +356 -0
- package/dist/messages/deprecation.d.ts +20 -0
- package/dist/messages/deprecation.js +33 -0
- package/dist/messages/index.d.ts +11 -0
- package/dist/messages/index.js +10 -0
- package/dist/messages/merge.d.ts +28 -0
- package/dist/messages/merge.js +53 -0
- package/dist/messages/types.d.ts +29 -0
- package/dist/messages/types.js +13 -0
- package/dist/schemas/v1/workflow.schema.json +5 -0
- package/dist/services/draftStorage.d.ts +13 -0
- package/dist/services/draftStorage.js +36 -0
- package/dist/stores/workflowStore.svelte.d.ts +1 -0
- package/dist/stores/workflowStore.svelte.js +1 -0
- package/dist/styles/base.css +13 -4
- package/dist/svelte-app.d.ts +11 -0
- package/dist/svelte-app.js +11 -2
- package/dist/types/index.d.ts +2 -0
- package/dist/utils/connections.d.ts +4 -0
- package/dist/utils/connections.js +6 -0
- package/package.json +1 -1
|
@@ -24,6 +24,7 @@
|
|
|
24
24
|
} from '../../utils/colors.js';
|
|
25
25
|
import { getConnectedHandles } from '../../stores/workflowStore.svelte.js';
|
|
26
26
|
import { applyPortOrder } from '../../utils/portUtils.js';
|
|
27
|
+
import { m } from '../../messages/index.js';
|
|
27
28
|
|
|
28
29
|
interface Props {
|
|
29
30
|
data: WorkflowNode['data'] & {
|
|
@@ -36,6 +37,10 @@
|
|
|
36
37
|
let props: Props = $props();
|
|
37
38
|
let isHandleInteraction = $state(false);
|
|
38
39
|
|
|
40
|
+
// Hoist the graph branch — three reads in the template, two of them inside
|
|
41
|
+
// {#each port} loops where N×M reads add up. One getter walk per render.
|
|
42
|
+
const graph = $derived(m().nodes.graph);
|
|
43
|
+
|
|
39
44
|
/**
|
|
40
45
|
* Instance-specific title override from config.
|
|
41
46
|
* Falls back to the original label if not set.
|
|
@@ -205,7 +210,7 @@
|
|
|
205
210
|
handleDoubleClick();
|
|
206
211
|
}
|
|
207
212
|
}}
|
|
208
|
-
aria-label=
|
|
213
|
+
aria-label={graph.workflowNode({ name: props.data.metadata.name })}
|
|
209
214
|
aria-describedby="node-description-{props.data.nodeId || 'unknown'}"
|
|
210
215
|
>
|
|
211
216
|
<!-- Default Node Header: expands in multiples of 10 (title row 40px + gap 10px + description 20px per line) -->
|
|
@@ -261,7 +266,7 @@
|
|
|
261
266
|
)}); --fd-handle-border-color: var(--fd-handle-border);"
|
|
262
267
|
role="button"
|
|
263
268
|
tabindex={0}
|
|
264
|
-
aria-label=
|
|
269
|
+
aria-label={graph.connectInputPort({ name: port.name })}
|
|
265
270
|
/>
|
|
266
271
|
|
|
267
272
|
<!-- Port Info: padding lives here so handle position is simple -->
|
|
@@ -339,7 +344,7 @@
|
|
|
339
344
|
)}); --fd-handle-border-color: var(--fd-handle-border);"
|
|
340
345
|
role="button"
|
|
341
346
|
tabindex={0}
|
|
342
|
-
aria-label=
|
|
347
|
+
aria-label={graph.connectOutputPort({ name: port.name })}
|
|
343
348
|
/>
|
|
344
349
|
</div>
|
|
345
350
|
{/each}
|
|
@@ -30,6 +30,7 @@
|
|
|
30
30
|
interruptActions,
|
|
31
31
|
getInterruptByMessageId
|
|
32
32
|
} from '../../stores/interruptStore.svelte.js';
|
|
33
|
+
import { m } from '../../messages/index.js';
|
|
33
34
|
|
|
34
35
|
/**
|
|
35
36
|
* Component props
|
|
@@ -78,7 +79,7 @@
|
|
|
78
79
|
let {
|
|
79
80
|
showTimestamps = true,
|
|
80
81
|
autoScroll = true,
|
|
81
|
-
placeholder
|
|
82
|
+
placeholder,
|
|
82
83
|
onSendMessage,
|
|
83
84
|
onStopExecution,
|
|
84
85
|
showLogsInline = false,
|
|
@@ -86,10 +87,21 @@
|
|
|
86
87
|
onInterruptResolved,
|
|
87
88
|
showChatInput = true,
|
|
88
89
|
showRunButton = true,
|
|
89
|
-
predefinedMessage
|
|
90
|
+
predefinedMessage,
|
|
90
91
|
compactSystemMessages = true
|
|
91
92
|
}: Props = $props();
|
|
92
93
|
|
|
94
|
+
// Hoist playground branches — states/actions are read 8+ times each in the
|
|
95
|
+
// template. Single getter walk per render instead of per-string.
|
|
96
|
+
const states = $derived(m().playground.states);
|
|
97
|
+
const actions = $derived(m().playground.actions);
|
|
98
|
+
const chat = $derived(m().playground.chat);
|
|
99
|
+
|
|
100
|
+
// Playground placeholders/labels are configurable per-instance (workflow
|
|
101
|
+
// author) but fall back to the localized messages tree when not provided.
|
|
102
|
+
const resolvedPlaceholder = $derived(placeholder ?? chat.placeholder);
|
|
103
|
+
const resolvedPredefinedMessage = $derived(predefinedMessage ?? chat.predefinedRun);
|
|
104
|
+
|
|
93
105
|
/**
|
|
94
106
|
* Tracks whether the Run button is enabled.
|
|
95
107
|
* Starts as true, becomes false after Run is clicked,
|
|
@@ -283,7 +295,7 @@
|
|
|
283
295
|
}
|
|
284
296
|
// Disable the Run button after clicking
|
|
285
297
|
runEnabled = false;
|
|
286
|
-
onSendMessage?.(
|
|
298
|
+
onSendMessage?.(resolvedPredefinedMessage);
|
|
287
299
|
}
|
|
288
300
|
|
|
289
301
|
/**
|
|
@@ -468,16 +480,16 @@
|
|
|
468
480
|
</svg>
|
|
469
481
|
</div>
|
|
470
482
|
{#if noInputsAvailable}
|
|
471
|
-
<h2 class="chat-panel__welcome-title">
|
|
483
|
+
<h2 class="chat-panel__welcome-title">{states.viewOnlyTitle}</h2>
|
|
472
484
|
<p class="chat-panel__welcome-text">
|
|
473
|
-
|
|
485
|
+
{states.viewOnlyText}
|
|
474
486
|
</p>
|
|
475
487
|
{:else if showChatInput}
|
|
476
|
-
<h2 class="chat-panel__welcome-title">
|
|
477
|
-
<p class="chat-panel__welcome-text">
|
|
488
|
+
<h2 class="chat-panel__welcome-title">{states.newSessionTitle}</h2>
|
|
489
|
+
<p class="chat-panel__welcome-text">{states.newSessionText}</p>
|
|
478
490
|
{:else}
|
|
479
|
-
<h2 class="chat-panel__welcome-title">
|
|
480
|
-
<p class="chat-panel__welcome-text">
|
|
491
|
+
<h2 class="chat-panel__welcome-title">{states.readyTitle}</h2>
|
|
492
|
+
<p class="chat-panel__welcome-text">{states.readyText}</p>
|
|
481
493
|
{/if}
|
|
482
494
|
</div>
|
|
483
495
|
{:else if showEmptyChat}
|
|
@@ -509,16 +521,16 @@
|
|
|
509
521
|
</svg>
|
|
510
522
|
</div>
|
|
511
523
|
{#if noInputsAvailable}
|
|
512
|
-
<h2 class="chat-panel__welcome-title">
|
|
524
|
+
<h2 class="chat-panel__welcome-title">{states.viewOnlyTitle}</h2>
|
|
513
525
|
<p class="chat-panel__welcome-text">
|
|
514
|
-
|
|
526
|
+
{states.viewOnlyText}
|
|
515
527
|
</p>
|
|
516
528
|
{:else if showChatInput}
|
|
517
|
-
<h2 class="chat-panel__welcome-title">
|
|
518
|
-
<p class="chat-panel__welcome-text">
|
|
529
|
+
<h2 class="chat-panel__welcome-title">{states.newSessionTitle}</h2>
|
|
530
|
+
<p class="chat-panel__welcome-text">{states.newSessionText}</p>
|
|
519
531
|
{:else}
|
|
520
|
-
<h2 class="chat-panel__welcome-title">
|
|
521
|
-
<p class="chat-panel__welcome-text">
|
|
532
|
+
<h2 class="chat-panel__welcome-title">{states.readyTitle}</h2>
|
|
533
|
+
<p class="chat-panel__welcome-text">{states.readyText}</p>
|
|
522
534
|
{/if}
|
|
523
535
|
</div>
|
|
524
536
|
{:else}
|
|
@@ -552,7 +564,7 @@
|
|
|
552
564
|
<span></span>
|
|
553
565
|
<span></span>
|
|
554
566
|
</div>
|
|
555
|
-
<span class="chat-panel__typing-text">
|
|
567
|
+
<span class="chat-panel__typing-text">{states.processing}</span>
|
|
556
568
|
</div>
|
|
557
569
|
{/if}
|
|
558
570
|
{/if}
|
|
@@ -564,7 +576,7 @@
|
|
|
564
576
|
<!-- No inputs available - show informational message -->
|
|
565
577
|
<div class="chat-panel__no-inputs">
|
|
566
578
|
<Icon icon="mdi:information-outline" />
|
|
567
|
-
<span>
|
|
579
|
+
<span>{states.viewOnlyHelp}</span>
|
|
568
580
|
</div>
|
|
569
581
|
{:else}
|
|
570
582
|
<div
|
|
@@ -577,7 +589,7 @@
|
|
|
577
589
|
bind:this={inputField}
|
|
578
590
|
bind:value={inputValue}
|
|
579
591
|
class="chat-panel__input"
|
|
580
|
-
{
|
|
592
|
+
placeholder={resolvedPlaceholder}
|
|
581
593
|
rows="1"
|
|
582
594
|
disabled={getIsExecuting()}
|
|
583
595
|
onkeydown={handleKeydown}
|
|
@@ -591,10 +603,10 @@
|
|
|
591
603
|
type="button"
|
|
592
604
|
class="chat-panel__stop-btn"
|
|
593
605
|
onclick={handleStop}
|
|
594
|
-
title=
|
|
606
|
+
title={actions.stopTitle}
|
|
595
607
|
>
|
|
596
608
|
<Icon icon="mdi:stop" />
|
|
597
|
-
|
|
609
|
+
{actions.stop}
|
|
598
610
|
</button>
|
|
599
611
|
{:else if showChatInput}
|
|
600
612
|
<button
|
|
@@ -602,9 +614,9 @@
|
|
|
602
614
|
class="chat-panel__send-btn"
|
|
603
615
|
onclick={handleSend}
|
|
604
616
|
disabled={!inputValue.trim()}
|
|
605
|
-
title=
|
|
617
|
+
title={actions.sendTitle}
|
|
606
618
|
>
|
|
607
|
-
|
|
619
|
+
{actions.send}
|
|
608
620
|
</button>
|
|
609
621
|
{:else if showRunButton}
|
|
610
622
|
<button
|
|
@@ -612,10 +624,10 @@
|
|
|
612
624
|
class="chat-panel__run-btn"
|
|
613
625
|
onclick={handleRun}
|
|
614
626
|
disabled={!runEnabled}
|
|
615
|
-
title={runEnabled ?
|
|
627
|
+
title={runEnabled ? actions.runTitle : actions.runWaitingTitle}
|
|
616
628
|
>
|
|
617
629
|
<Icon icon="mdi:play" />
|
|
618
|
-
|
|
630
|
+
{actions.run}
|
|
619
631
|
</button>
|
|
620
632
|
{/if}
|
|
621
633
|
</div>
|
|
@@ -17,6 +17,7 @@
|
|
|
17
17
|
PlaygroundMessageMetadata,
|
|
18
18
|
PlaygroundMessageRole
|
|
19
19
|
} from '../../types/playground.js';
|
|
20
|
+
import { m } from '../../messages/index.js';
|
|
20
21
|
|
|
21
22
|
/**
|
|
22
23
|
* Component props
|
|
@@ -91,17 +92,18 @@
|
|
|
91
92
|
* @returns Display label
|
|
92
93
|
*/
|
|
93
94
|
function getRoleLabel(role: PlaygroundMessageRole, metadata?: PlaygroundMessageMetadata): string {
|
|
95
|
+
const roles = m().playground.roles;
|
|
94
96
|
switch (role) {
|
|
95
97
|
case 'user':
|
|
96
|
-
return metadata?.userName ??
|
|
98
|
+
return metadata?.userName ?? roles.you;
|
|
97
99
|
case 'assistant':
|
|
98
|
-
return
|
|
100
|
+
return roles.assistant;
|
|
99
101
|
case 'system':
|
|
100
|
-
return
|
|
102
|
+
return roles.system;
|
|
101
103
|
case 'log':
|
|
102
|
-
return metadata?.nodeLabel ??
|
|
104
|
+
return metadata?.nodeLabel ?? roles.log;
|
|
103
105
|
default:
|
|
104
|
-
return
|
|
106
|
+
return roles.message;
|
|
105
107
|
}
|
|
106
108
|
}
|
|
107
109
|
|
|
@@ -208,13 +210,19 @@
|
|
|
208
210
|
{#if message.metadata?.duration !== undefined || message.nodeId}
|
|
209
211
|
<div class="message-bubble__footer">
|
|
210
212
|
{#if message.nodeId}
|
|
211
|
-
<span
|
|
213
|
+
<span
|
|
214
|
+
class="message-bubble__node"
|
|
215
|
+
title={m().playground.messageTooltips.nodeId({ id: message.nodeId })}
|
|
216
|
+
>
|
|
212
217
|
<Icon icon="mdi:graph" />
|
|
213
218
|
{message.metadata?.nodeLabel ?? message.nodeId}
|
|
214
219
|
</span>
|
|
215
220
|
{/if}
|
|
216
221
|
{#if message.metadata?.duration !== undefined}
|
|
217
|
-
<span
|
|
222
|
+
<span
|
|
223
|
+
class="message-bubble__duration"
|
|
224
|
+
title={m().playground.messageTooltips.executionDuration}
|
|
225
|
+
>
|
|
218
226
|
<Icon icon="mdi:timer-outline" />
|
|
219
227
|
{formatDuration(message.metadata.duration)}
|
|
220
228
|
</span>
|
|
@@ -29,6 +29,7 @@
|
|
|
29
29
|
} from '../../stores/playgroundStore.svelte.js';
|
|
30
30
|
import { interruptActions } from '../../stores/interruptStore.svelte.js';
|
|
31
31
|
import { logger } from '../../utils/logger.js';
|
|
32
|
+
import { m } from '../../messages/index.js';
|
|
32
33
|
|
|
33
34
|
/**
|
|
34
35
|
* Component props
|
|
@@ -545,7 +546,7 @@
|
|
|
545
546
|
role="button"
|
|
546
547
|
tabindex="0"
|
|
547
548
|
title="Click to load this session"
|
|
548
|
-
aria-label=
|
|
549
|
+
aria-label={m().layout.loadSession({ name: session.name })}
|
|
549
550
|
onclick={() => handleSelectSession(session.id)}
|
|
550
551
|
onkeydown={(e) => e.key === 'Enter' && handleSelectSession(session.id)}
|
|
551
552
|
>
|
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
import type { Workflow } from '../../types/index.js';
|
|
13
13
|
import type { EndpointConfig } from '../../config/endpoints.js';
|
|
14
14
|
import type { PlaygroundConfig } from '../../types/playground.js';
|
|
15
|
+
import { m } from '../../messages/index.js';
|
|
15
16
|
|
|
16
17
|
/**
|
|
17
18
|
* Component props
|
|
@@ -86,7 +87,7 @@
|
|
|
86
87
|
type="button"
|
|
87
88
|
class="playground-modal__close-btn"
|
|
88
89
|
onclick={onClose}
|
|
89
|
-
aria-label=
|
|
90
|
+
aria-label={m().layout.closePlaygroundModal}
|
|
90
91
|
>
|
|
91
92
|
<Icon icon="mdi:close" />
|
|
92
93
|
</button>
|
|
@@ -16,6 +16,7 @@
|
|
|
16
16
|
getIsLoading,
|
|
17
17
|
getSessionCount
|
|
18
18
|
} from '../../stores/playgroundStore.svelte.js';
|
|
19
|
+
import { m } from '../../messages/index.js';
|
|
19
20
|
|
|
20
21
|
/**
|
|
21
22
|
* Component props
|
|
@@ -44,6 +45,9 @@
|
|
|
44
45
|
mode = 'sidebar'
|
|
45
46
|
}: Props = $props();
|
|
46
47
|
|
|
48
|
+
// Hoist the sessions branch — used in formatDate plus several template reads.
|
|
49
|
+
const t = $derived(m().playground.sessions);
|
|
50
|
+
|
|
47
51
|
/** Session pending deletion (for confirmation) */
|
|
48
52
|
let pendingDeleteId = $state<string | null>(null);
|
|
49
53
|
|
|
@@ -105,16 +109,16 @@
|
|
|
105
109
|
const diffDays = Math.floor(diffMs / 86400000);
|
|
106
110
|
|
|
107
111
|
if (diffMins < 1) {
|
|
108
|
-
return
|
|
112
|
+
return t.justNow;
|
|
109
113
|
}
|
|
110
114
|
if (diffMins < 60) {
|
|
111
|
-
return
|
|
115
|
+
return t.minutesAgo({ n: diffMins });
|
|
112
116
|
}
|
|
113
117
|
if (diffHours < 24) {
|
|
114
|
-
return
|
|
118
|
+
return t.hoursAgo({ n: diffHours });
|
|
115
119
|
}
|
|
116
120
|
if (diffDays < 7) {
|
|
117
|
-
return
|
|
121
|
+
return t.daysAgo({ n: diffDays });
|
|
118
122
|
}
|
|
119
123
|
return date.toLocaleDateString('en-US', {
|
|
120
124
|
month: 'short',
|
|
@@ -170,7 +174,7 @@
|
|
|
170
174
|
>
|
|
171
175
|
<div class="session-manager__title">
|
|
172
176
|
<Icon icon="mdi:history" />
|
|
173
|
-
<span>
|
|
177
|
+
<span>{t.header}</span>
|
|
174
178
|
{#if getSessionCount() > 0}
|
|
175
179
|
<span class="session-manager__count">{getSessionCount()}</span>
|
|
176
180
|
{/if}
|
|
@@ -192,7 +196,7 @@
|
|
|
192
196
|
disabled={getIsLoading()}
|
|
193
197
|
>
|
|
194
198
|
<Icon icon="mdi:plus" />
|
|
195
|
-
|
|
199
|
+
{t.newSession}
|
|
196
200
|
</button>
|
|
197
201
|
|
|
198
202
|
<!-- Sessions List -->
|
|
@@ -200,7 +204,7 @@
|
|
|
200
204
|
{#if getSessions().length === 0}
|
|
201
205
|
<div class="session-manager__empty">
|
|
202
206
|
<Icon icon="mdi:chat-outline" />
|
|
203
|
-
<span>
|
|
207
|
+
<span>{t.empty}</span>
|
|
204
208
|
</div>
|
|
205
209
|
{:else}
|
|
206
210
|
{#each getSessions() as session (session.id)}
|
|
@@ -236,7 +240,7 @@
|
|
|
236
240
|
type="button"
|
|
237
241
|
class="session-manager__delete-btn session-manager__delete-btn--confirm"
|
|
238
242
|
onclick={(e) => handleDeleteClick(e, session.id)}
|
|
239
|
-
title=
|
|
243
|
+
title={t.clickAgainToConfirm}
|
|
240
244
|
>
|
|
241
245
|
<Icon icon="mdi:check" />
|
|
242
246
|
</button>
|
|
@@ -244,7 +248,7 @@
|
|
|
244
248
|
type="button"
|
|
245
249
|
class="session-manager__delete-btn session-manager__delete-btn--cancel"
|
|
246
250
|
onclick={cancelDelete}
|
|
247
|
-
title=
|
|
251
|
+
title={t.cancel}
|
|
248
252
|
>
|
|
249
253
|
<Icon icon="mdi:close" />
|
|
250
254
|
</button>
|
|
@@ -253,7 +257,7 @@
|
|
|
253
257
|
type="button"
|
|
254
258
|
class="session-manager__delete-btn"
|
|
255
259
|
onclick={(e) => handleDeleteClick(e, session.id)}
|
|
256
|
-
title=
|
|
260
|
+
title={t.deleteSession}
|
|
257
261
|
>
|
|
258
262
|
<Icon icon="mdi:delete-outline" />
|
|
259
263
|
</button>
|
package/dist/core/index.d.ts
CHANGED
|
@@ -82,3 +82,5 @@ export { logger, setLogLevel, getLogLevel } from '../utils/logger.js';
|
|
|
82
82
|
export type { LogLevel } from '../utils/logger.js';
|
|
83
83
|
export { computeSwapPreview, computeSwapPreviewWithOptions, executeSwap, mapConfig, getVersionUpgrade, compareSemver, performSwap, validateSwapResult, SwapValidationError } from '../utils/nodeSwap.js';
|
|
84
84
|
export type { SwapPreview, SwapResult, PortMapping, DroppedEdge, MatchQuality, PortMappingOverride, ConfigMappingOverride, SwapOptions, SwapStrategy, SwapStrategyContext, SwapEventContext } from '../utils/nodeSwap.js';
|
|
85
|
+
export { defaultMessages, mergeMessages, setMessages } from '../messages/index.js';
|
|
86
|
+
export type { Messages, MessagesOverride } from '../messages/index.js';
|
package/dist/core/index.js
CHANGED
|
@@ -101,3 +101,12 @@ export { logger, setLogLevel, getLogLevel } from '../utils/logger.js';
|
|
|
101
101
|
// Node Swap
|
|
102
102
|
// ============================================================================
|
|
103
103
|
export { computeSwapPreview, computeSwapPreviewWithOptions, executeSwap, mapConfig, getVersionUpgrade, compareSemver, performSwap, validateSwapResult, SwapValidationError } from '../utils/nodeSwap.js';
|
|
104
|
+
// ============================================================================
|
|
105
|
+
// Messages (typed, overridable, translation-ready user-facing strings)
|
|
106
|
+
//
|
|
107
|
+
// Consumers pass `messages={partial}` (or a getter) to <FlowDrop>; type the
|
|
108
|
+
// partial as `MessagesOverride`. `setMessages` + `mergeMessages` are exported
|
|
109
|
+
// for ad-hoc mounts that render flowdrop components outside the root provider
|
|
110
|
+
// (Storybook stories, standalone <SchemaForm>, etc.) — see the i18n guide.
|
|
111
|
+
// ============================================================================
|
|
112
|
+
export { defaultMessages, mergeMessages, setMessages } from '../messages/index.js';
|
package/dist/editor/index.d.ts
CHANGED
|
@@ -82,7 +82,7 @@ export { globalSaveWorkflow, globalExportWorkflow } from '../services/globalSave
|
|
|
82
82
|
export { fetchPortConfig, validatePortConfig } from '../services/portConfigApi.js';
|
|
83
83
|
export { fetchCategories, validateCategories } from '../services/categoriesApi.js';
|
|
84
84
|
export { fetchDynamicSchema, resolveExternalEditUrl, getEffectiveConfigEditOptions, clearSchemaCache, invalidateSchemaCache, hasConfigEditOptions, shouldShowExternalEdit, shouldUseDynamicSchema } from '../services/dynamicSchemaService.js';
|
|
85
|
-
export { getDraftStorageKey, saveDraft, loadDraft, deleteDraft, hasDraft, getDraftMetadata, DraftAutoSaveManager } from '../services/draftStorage.js';
|
|
85
|
+
export { getDraftStorageKey, saveDraft, loadDraft, deleteDraft, hasDraft, getDraftMetadata, clearAllDrafts, DraftAutoSaveManager } from '../services/draftStorage.js';
|
|
86
86
|
export { EnhancedFlowDropApiClient, ApiError } from '../api/enhanced-client.js';
|
|
87
87
|
export { isLoopbackEdge, isValidLoopbackCycle, PortCompatibilityChecker, initializePortCompatibility, getPortCompatibilityChecker, getPossibleConnections, validateConnection, getConnectionSuggestions, hasCycles, hasInvalidCycles, getExecutionOrder } from '../utils/connections.js';
|
|
88
88
|
export { fetchRuntimeConfig, getRuntimeConfig, clearRuntimeConfigCache, initRuntimeConfig } from '../config/runtimeConfig.js';
|
package/dist/editor/index.js
CHANGED
|
@@ -125,7 +125,7 @@ export { globalSaveWorkflow, globalExportWorkflow } from '../services/globalSave
|
|
|
125
125
|
export { fetchPortConfig, validatePortConfig } from '../services/portConfigApi.js';
|
|
126
126
|
export { fetchCategories, validateCategories } from '../services/categoriesApi.js';
|
|
127
127
|
export { fetchDynamicSchema, resolveExternalEditUrl, getEffectiveConfigEditOptions, clearSchemaCache, invalidateSchemaCache, hasConfigEditOptions, shouldShowExternalEdit, shouldUseDynamicSchema } from '../services/dynamicSchemaService.js';
|
|
128
|
-
export { getDraftStorageKey, saveDraft, loadDraft, deleteDraft, hasDraft, getDraftMetadata, DraftAutoSaveManager } from '../services/draftStorage.js';
|
|
128
|
+
export { getDraftStorageKey, saveDraft, loadDraft, deleteDraft, hasDraft, getDraftMetadata, clearAllDrafts, DraftAutoSaveManager } from '../services/draftStorage.js';
|
|
129
129
|
// ============================================================================
|
|
130
130
|
// API Clients
|
|
131
131
|
// ============================================================================
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Svelte context plumbing for the messages system.
|
|
3
|
+
*
|
|
4
|
+
* The context value is a **getter** `() => Messages`, not a snapshot. Storing
|
|
5
|
+
* a getter lets the consumer's i18n library drive reactivity transparently:
|
|
6
|
+
* they pass `messages={() => somethingReactive()}` to `<FlowDrop>`, the root
|
|
7
|
+
* `$derived`s the merged tree, and `m()` re-reads it on every access. No
|
|
8
|
+
* subscription, no store, no flowdrop-owned reactive primitive.
|
|
9
|
+
*
|
|
10
|
+
* Components rendered outside the root provider (Storybook stories, ad-hoc
|
|
11
|
+
* mounts) silently fall back to `defaultMessages` rather than throwing — see
|
|
12
|
+
* `getMessages()` below. Trade-off: a missing provider produces English
|
|
13
|
+
* regardless of the consumer's locale, by design.
|
|
14
|
+
*/
|
|
15
|
+
import type { Messages } from './types.js';
|
|
16
|
+
export declare function setMessages(getter: () => Messages): void;
|
|
17
|
+
/**
|
|
18
|
+
* Returns the current messages getter. Components should call the result on
|
|
19
|
+
* every read so locale switches in the consumer's i18n library propagate
|
|
20
|
+
* without a subscription.
|
|
21
|
+
*
|
|
22
|
+
* Outside a provider, returns a getter that always yields `defaultMessages`.
|
|
23
|
+
*/
|
|
24
|
+
export declare function getMessages(): () => Messages;
|
|
25
|
+
/**
|
|
26
|
+
* Shorthand for the common pattern `getMessages()()` — read the current
|
|
27
|
+
* merged messages tree once. Use inside templates: `m().form.array.moveUp`.
|
|
28
|
+
*/
|
|
29
|
+
export declare function m(): Messages;
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Svelte context plumbing for the messages system.
|
|
3
|
+
*
|
|
4
|
+
* The context value is a **getter** `() => Messages`, not a snapshot. Storing
|
|
5
|
+
* a getter lets the consumer's i18n library drive reactivity transparently:
|
|
6
|
+
* they pass `messages={() => somethingReactive()}` to `<FlowDrop>`, the root
|
|
7
|
+
* `$derived`s the merged tree, and `m()` re-reads it on every access. No
|
|
8
|
+
* subscription, no store, no flowdrop-owned reactive primitive.
|
|
9
|
+
*
|
|
10
|
+
* Components rendered outside the root provider (Storybook stories, ad-hoc
|
|
11
|
+
* mounts) silently fall back to `defaultMessages` rather than throwing — see
|
|
12
|
+
* `getMessages()` below. Trade-off: a missing provider produces English
|
|
13
|
+
* regardless of the consumer's locale, by design.
|
|
14
|
+
*/
|
|
15
|
+
import { getContext, setContext } from 'svelte';
|
|
16
|
+
import { defaultMessages } from './defaults.js';
|
|
17
|
+
const KEY = Symbol('flowdrop.messages');
|
|
18
|
+
const defaultGetter = () => defaultMessages;
|
|
19
|
+
export function setMessages(getter) {
|
|
20
|
+
setContext(KEY, getter);
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Returns the current messages getter. Components should call the result on
|
|
24
|
+
* every read so locale switches in the consumer's i18n library propagate
|
|
25
|
+
* without a subscription.
|
|
26
|
+
*
|
|
27
|
+
* Outside a provider, returns a getter that always yields `defaultMessages`.
|
|
28
|
+
*/
|
|
29
|
+
export function getMessages() {
|
|
30
|
+
return getContext(KEY) ?? defaultGetter;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Shorthand for the common pattern `getMessages()()` — read the current
|
|
34
|
+
* merged messages tree once. Use inside templates: `m().form.array.moveUp`.
|
|
35
|
+
*/
|
|
36
|
+
export function m() {
|
|
37
|
+
return getMessages()();
|
|
38
|
+
}
|