@flowdrop/flowdrop 1.9.0 → 1.11.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/dist/api/enhanced-client.js +5 -1
- package/dist/components/Navbar.svelte +1 -10
- package/dist/components/Navbar.svelte.d.ts +1 -9
- package/dist/components/PipelineStatus.svelte +17 -1
- package/dist/components/PipelineStatus.svelte.d.ts +2 -0
- package/dist/components/WorkflowEditor.svelte +26 -0
- package/dist/components/playground/ChatPanel.svelte +33 -235
- package/dist/components/playground/ExecutionList.svelte +2 -6
- package/dist/components/playground/MessageBubble.svelte +61 -4
- package/dist/components/playground/PipelinePanel.svelte +17 -7
- package/dist/components/playground/PipelinePanel.svelte.d.ts +2 -1
- package/dist/components/playground/Playground.svelte +123 -73
- package/dist/components/playground/PlaygroundApp.svelte +110 -0
- package/dist/components/playground/PlaygroundApp.svelte.d.ts +28 -0
- package/dist/components/playground/PlaygroundStudio.svelte +404 -0
- package/dist/components/playground/PlaygroundStudio.svelte.d.ts +30 -0
- package/dist/editor/index.d.ts +1 -1
- package/dist/editor/index.js +1 -1
- package/dist/playground/index.d.ts +8 -3
- package/dist/playground/index.js +15 -5
- package/dist/playground/mount.d.ts +63 -4
- package/dist/playground/mount.js +173 -84
- package/dist/services/nodeExecutionService.js +4 -2
- package/dist/services/playgroundService.d.ts +11 -4
- package/dist/services/playgroundService.js +22 -12
- package/dist/stores/playgroundStore.svelte.d.ts +22 -21
- package/dist/stores/playgroundStore.svelte.js +79 -58
- package/dist/svelte-app.d.ts +2 -10
- package/dist/types/navbar.d.ts +14 -0
- package/dist/types/navbar.js +1 -0
- package/dist/types/playground.d.ts +3 -5
- package/package.json +1 -1
|
@@ -0,0 +1,404 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
PlaygroundStudio Component
|
|
3
|
+
|
|
4
|
+
Drop-in embeddable split-pane layout: PipelinePanel (left, resizable) + Playground
|
|
5
|
+
chat (right). Provides the same integrated experience as the FlowDrop demo app with a
|
|
6
|
+
single import and zero layout glue code.
|
|
7
|
+
|
|
8
|
+
@example Basic usage — workflow fetched automatically
|
|
9
|
+
```svelte
|
|
10
|
+
<script>
|
|
11
|
+
import { PlaygroundStudio, createEndpointConfig } from '@flowdrop/flowdrop/playground';
|
|
12
|
+
import '@flowdrop/flowdrop/styles';
|
|
13
|
+
</script>
|
|
14
|
+
|
|
15
|
+
<PlaygroundStudio
|
|
16
|
+
workflowId="wf-123"
|
|
17
|
+
endpointConfig={createEndpointConfig('/api/flowdrop')}
|
|
18
|
+
/>
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
@example With pre-loaded workflow and URL-based session routing
|
|
22
|
+
```svelte
|
|
23
|
+
<script>
|
|
24
|
+
import { PlaygroundStudio, createEndpointConfig } from '@flowdrop/flowdrop/playground';
|
|
25
|
+
|
|
26
|
+
let { data } = $props(); // workflow from server load
|
|
27
|
+
let sessionId = $derived($page.params.sessionId);
|
|
28
|
+
|
|
29
|
+
function handleSessionNavigate(id) {
|
|
30
|
+
goto(`/playground/${id}`);
|
|
31
|
+
}
|
|
32
|
+
</script>
|
|
33
|
+
|
|
34
|
+
<PlaygroundStudio
|
|
35
|
+
workflowId={data.workflow.id}
|
|
36
|
+
workflow={data.workflow}
|
|
37
|
+
endpointConfig={createEndpointConfig('/api/flowdrop')}
|
|
38
|
+
initialSessionId={sessionId}
|
|
39
|
+
onSessionNavigate={handleSessionNavigate}
|
|
40
|
+
/>
|
|
41
|
+
```
|
|
42
|
+
-->
|
|
43
|
+
|
|
44
|
+
<script lang="ts">
|
|
45
|
+
import { onMount } from 'svelte';
|
|
46
|
+
import Icon from '@iconify/svelte';
|
|
47
|
+
import Playground from './Playground.svelte';
|
|
48
|
+
import PipelinePanel from './PipelinePanel.svelte';
|
|
49
|
+
import { getPipelinePanelOpen, pipelinePanelActions } from '../../stores/pipelinePanelStore.svelte.js';
|
|
50
|
+
import {
|
|
51
|
+
getActiveExecutionId,
|
|
52
|
+
getPinnedExecutionId,
|
|
53
|
+
getLatestExecutionId,
|
|
54
|
+
getPipelineRefreshTrigger,
|
|
55
|
+
getCurrentSession,
|
|
56
|
+
playgroundActions,
|
|
57
|
+
} from '../../stores/playgroundStore.svelte.js';
|
|
58
|
+
import { setEndpointConfig, workflowApi } from '../../services/api.js';
|
|
59
|
+
import { logger } from '../../utils/logger.js';
|
|
60
|
+
import type { Workflow } from '../../types/index.js';
|
|
61
|
+
import type { EndpointConfig } from '../../config/endpoints.js';
|
|
62
|
+
import type { PlaygroundConfig, PlaygroundMode } from '../../types/playground.js';
|
|
63
|
+
|
|
64
|
+
interface Props {
|
|
65
|
+
/** Target workflow ID */
|
|
66
|
+
workflowId: string;
|
|
67
|
+
/** Pre-loaded workflow — skips internal fetch when provided */
|
|
68
|
+
workflow?: Workflow;
|
|
69
|
+
/** API endpoint configuration */
|
|
70
|
+
endpointConfig?: EndpointConfig;
|
|
71
|
+
/** Display mode (default: standalone) */
|
|
72
|
+
mode?: PlaygroundMode;
|
|
73
|
+
/** Session ID to activate on mount. Changing this prop remounts the Playground. */
|
|
74
|
+
initialSessionId?: string;
|
|
75
|
+
/** Playground configuration options */
|
|
76
|
+
config?: PlaygroundConfig;
|
|
77
|
+
/** Whether the pipeline panel starts open. When omitted the stored preference is used. */
|
|
78
|
+
initialPipelineOpen?: boolean;
|
|
79
|
+
/** Minimum chat panel width in px (default: 760) */
|
|
80
|
+
minChatWidth?: number;
|
|
81
|
+
/** Initial pipeline panel width in px (default: 500) */
|
|
82
|
+
initialPipelineWidth?: number;
|
|
83
|
+
/** Called when session navigation is requested — use for URL-based routing */
|
|
84
|
+
onSessionNavigate?: (sessionId: string) => void;
|
|
85
|
+
/** Called when the playground is closed (embedded / modal mode) */
|
|
86
|
+
onClose?: () => void;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
let {
|
|
90
|
+
workflowId,
|
|
91
|
+
workflow: workflowProp,
|
|
92
|
+
endpointConfig,
|
|
93
|
+
mode = 'standalone',
|
|
94
|
+
initialSessionId,
|
|
95
|
+
config = {},
|
|
96
|
+
initialPipelineOpen,
|
|
97
|
+
minChatWidth = 760,
|
|
98
|
+
initialPipelineWidth = 500,
|
|
99
|
+
onSessionNavigate,
|
|
100
|
+
onClose,
|
|
101
|
+
}: Props = $props();
|
|
102
|
+
|
|
103
|
+
// svelte-ignore state_referenced_locally
|
|
104
|
+
let resolvedWorkflow = $state<Workflow | null>(workflowProp ?? null);
|
|
105
|
+
// svelte-ignore state_referenced_locally
|
|
106
|
+
let workflowLoading = $state(workflowProp === undefined);
|
|
107
|
+
let workflowError = $state<string | null>(null);
|
|
108
|
+
|
|
109
|
+
let splitEl = $state<HTMLElement | null>(null);
|
|
110
|
+
// svelte-ignore state_referenced_locally
|
|
111
|
+
let pipelineWidth = $state(initialPipelineWidth);
|
|
112
|
+
let isResizing = $state(false);
|
|
113
|
+
let containerWidth = $state(0);
|
|
114
|
+
|
|
115
|
+
$effect(() => {
|
|
116
|
+
if (!splitEl) return;
|
|
117
|
+
const observer = new ResizeObserver(([entry]) => {
|
|
118
|
+
containerWidth = entry.contentRect.width;
|
|
119
|
+
});
|
|
120
|
+
observer.observe(splitEl);
|
|
121
|
+
return () => observer.disconnect();
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
onMount(() => {
|
|
125
|
+
pipelinePanelActions.init();
|
|
126
|
+
if (initialPipelineOpen !== undefined) {
|
|
127
|
+
pipelinePanelActions.setOpen(initialPipelineOpen);
|
|
128
|
+
}
|
|
129
|
+
if (endpointConfig) {
|
|
130
|
+
setEndpointConfig(endpointConfig);
|
|
131
|
+
}
|
|
132
|
+
if (!workflowProp) {
|
|
133
|
+
void loadWorkflow();
|
|
134
|
+
}
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
async function loadWorkflow(): Promise<void> {
|
|
138
|
+
if (!endpointConfig) {
|
|
139
|
+
workflowError = 'Provide a workflow prop or an endpointConfig so the workflow can be fetched.';
|
|
140
|
+
workflowLoading = false;
|
|
141
|
+
return;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
try {
|
|
145
|
+
workflowLoading = true;
|
|
146
|
+
workflowError = null;
|
|
147
|
+
resolvedWorkflow = await workflowApi.getWorkflow(workflowId);
|
|
148
|
+
} catch (err) {
|
|
149
|
+
workflowError = err instanceof Error ? err.message : 'Failed to load workflow';
|
|
150
|
+
logger.error('[PlaygroundStudio] Workflow load failed:', err);
|
|
151
|
+
} finally {
|
|
152
|
+
workflowLoading = false;
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
function handleResizerPointerDown(e: PointerEvent) {
|
|
157
|
+
isResizing = true;
|
|
158
|
+
(e.currentTarget as HTMLElement).setPointerCapture(e.pointerId);
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
function handleResizerPointerMove(e: PointerEvent) {
|
|
162
|
+
if (!isResizing || !splitEl) return;
|
|
163
|
+
const rect = splitEl.getBoundingClientRect();
|
|
164
|
+
pipelineWidth = Math.min(
|
|
165
|
+
Math.max(e.clientX - rect.left, rect.width - minChatWidth),
|
|
166
|
+
rect.width * 0.75
|
|
167
|
+
);
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
function handleResizerPointerUp() {
|
|
171
|
+
isResizing = false;
|
|
172
|
+
}
|
|
173
|
+
</script>
|
|
174
|
+
|
|
175
|
+
<div class="playground-studio" class:playground-studio--resizing={isResizing} style="--playground-studio-min-chat-width: {minChatWidth}px">
|
|
176
|
+
<div class="playground-studio__panes" bind:this={splitEl}>
|
|
177
|
+
{#if getPipelinePanelOpen() && resolvedWorkflow && endpointConfig}
|
|
178
|
+
{@const activeId = getActiveExecutionId()}
|
|
179
|
+
{@const executions = getCurrentSession()?.executions ?? []}
|
|
180
|
+
|
|
181
|
+
<div class="playground-studio__pipeline" style="width: {pipelineWidth}px;">
|
|
182
|
+
<PipelinePanel
|
|
183
|
+
pipelineId={activeId}
|
|
184
|
+
workflow={resolvedWorkflow}
|
|
185
|
+
{endpointConfig}
|
|
186
|
+
isPinned={getPinnedExecutionId() !== null}
|
|
187
|
+
{executions}
|
|
188
|
+
latestExecutionId={getLatestExecutionId()}
|
|
189
|
+
onSelectExecution={(id) => playgroundActions.pinExecution(id)}
|
|
190
|
+
refreshTrigger={getPipelineRefreshTrigger()}
|
|
191
|
+
/>
|
|
192
|
+
</div>
|
|
193
|
+
|
|
194
|
+
<!-- svelte-ignore a11y_no_noninteractive_tabindex -->
|
|
195
|
+
<div
|
|
196
|
+
class="playground-studio__resizer"
|
|
197
|
+
class:playground-studio__resizer--active={isResizing}
|
|
198
|
+
role="separator"
|
|
199
|
+
aria-orientation="vertical"
|
|
200
|
+
aria-valuenow={Math.round(pipelineWidth)}
|
|
201
|
+
aria-valuemin={0}
|
|
202
|
+
aria-valuemax={Math.round(containerWidth * 0.75)}
|
|
203
|
+
tabindex="0"
|
|
204
|
+
onpointerdown={handleResizerPointerDown}
|
|
205
|
+
onpointermove={handleResizerPointerMove}
|
|
206
|
+
onpointerup={handleResizerPointerUp}
|
|
207
|
+
onpointercancel={handleResizerPointerUp}
|
|
208
|
+
>
|
|
209
|
+
<div class="playground-studio__resizer-handle"></div>
|
|
210
|
+
</div>
|
|
211
|
+
{/if}
|
|
212
|
+
|
|
213
|
+
<div
|
|
214
|
+
class="playground-studio__chat"
|
|
215
|
+
class:playground-studio__chat--solo={!getPipelinePanelOpen()}
|
|
216
|
+
>
|
|
217
|
+
{#if workflowLoading}
|
|
218
|
+
<div class="playground-studio__loading">
|
|
219
|
+
<Icon icon="mdi:loading" class="playground-studio__loading-icon" />
|
|
220
|
+
<p>Loading workflow...</p>
|
|
221
|
+
</div>
|
|
222
|
+
{:else if workflowError}
|
|
223
|
+
<div class="playground-studio__error">
|
|
224
|
+
<Icon icon="mdi:alert-circle" class="playground-studio__error-icon" />
|
|
225
|
+
<p class="playground-studio__error-text">{workflowError}</p>
|
|
226
|
+
<button type="button" class="playground-studio__retry-btn" onclick={loadWorkflow}>
|
|
227
|
+
<Icon icon="mdi:refresh" />
|
|
228
|
+
Retry
|
|
229
|
+
</button>
|
|
230
|
+
</div>
|
|
231
|
+
{:else if resolvedWorkflow}
|
|
232
|
+
{#key initialSessionId}
|
|
233
|
+
<Playground
|
|
234
|
+
{workflowId}
|
|
235
|
+
workflow={resolvedWorkflow}
|
|
236
|
+
{endpointConfig}
|
|
237
|
+
{mode}
|
|
238
|
+
{initialSessionId}
|
|
239
|
+
{config}
|
|
240
|
+
{onClose}
|
|
241
|
+
{onSessionNavigate}
|
|
242
|
+
onTogglePanel={pipelinePanelActions.toggle}
|
|
243
|
+
isPipelinePanelOpen={getPipelinePanelOpen()}
|
|
244
|
+
/>
|
|
245
|
+
{/key}
|
|
246
|
+
{/if}
|
|
247
|
+
</div>
|
|
248
|
+
</div>
|
|
249
|
+
</div>
|
|
250
|
+
|
|
251
|
+
<style>
|
|
252
|
+
.playground-studio {
|
|
253
|
+
display: flex;
|
|
254
|
+
flex-direction: column;
|
|
255
|
+
height: 100%;
|
|
256
|
+
min-height: 0;
|
|
257
|
+
overflow: hidden;
|
|
258
|
+
background-color: var(--fd-background);
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
.playground-studio--resizing {
|
|
262
|
+
cursor: col-resize;
|
|
263
|
+
user-select: none;
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
.playground-studio__panes {
|
|
267
|
+
display: flex;
|
|
268
|
+
flex-direction: row;
|
|
269
|
+
flex: 1;
|
|
270
|
+
min-height: 0;
|
|
271
|
+
overflow: hidden;
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
/* Pipeline pane — explicit width set via inline style */
|
|
275
|
+
.playground-studio__pipeline {
|
|
276
|
+
min-width: calc(100% - var(--playground-studio-min-chat-width));
|
|
277
|
+
max-width: 75%;
|
|
278
|
+
overflow: hidden;
|
|
279
|
+
flex-shrink: 0;
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
/* Drag handle between the two panes */
|
|
283
|
+
.playground-studio__resizer {
|
|
284
|
+
width: 8px;
|
|
285
|
+
flex-shrink: 0;
|
|
286
|
+
cursor: col-resize;
|
|
287
|
+
background-color: var(--fd-background);
|
|
288
|
+
border-right: 1px solid var(--fd-border);
|
|
289
|
+
border-left: 1px solid var(--fd-border);
|
|
290
|
+
display: flex;
|
|
291
|
+
align-items: center;
|
|
292
|
+
justify-content: center;
|
|
293
|
+
touch-action: none;
|
|
294
|
+
z-index: 1;
|
|
295
|
+
transition: background-color var(--fd-transition-normal);
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
.playground-studio__resizer:hover,
|
|
299
|
+
.playground-studio__resizer--active {
|
|
300
|
+
background-color: var(--fd-primary-muted);
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
.playground-studio__resizer-handle {
|
|
304
|
+
width: 4px;
|
|
305
|
+
height: 48px;
|
|
306
|
+
background-color: var(--fd-border-strong);
|
|
307
|
+
border-radius: var(--fd-radius-sm);
|
|
308
|
+
transition:
|
|
309
|
+
background-color var(--fd-transition-normal),
|
|
310
|
+
transform var(--fd-transition-normal);
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
.playground-studio__resizer:hover .playground-studio__resizer-handle {
|
|
314
|
+
background-color: var(--fd-primary);
|
|
315
|
+
transform: scaleY(1.2);
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
.playground-studio__resizer--active .playground-studio__resizer-handle {
|
|
319
|
+
background-color: var(--fd-primary-hover);
|
|
320
|
+
transform: scaleY(1.4);
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
/* Chat pane — fills remaining space */
|
|
324
|
+
.playground-studio__chat {
|
|
325
|
+
flex: 1;
|
|
326
|
+
min-width: 0;
|
|
327
|
+
overflow: hidden;
|
|
328
|
+
display: flex;
|
|
329
|
+
flex-direction: column;
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
.playground-studio__chat--solo {
|
|
333
|
+
border-left: 1px solid var(--fd-border);
|
|
334
|
+
border-right: 1px solid var(--fd-border);
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
/* Loading state */
|
|
338
|
+
.playground-studio__loading {
|
|
339
|
+
display: flex;
|
|
340
|
+
flex-direction: column;
|
|
341
|
+
align-items: center;
|
|
342
|
+
justify-content: center;
|
|
343
|
+
height: 100%;
|
|
344
|
+
color: var(--fd-muted-foreground);
|
|
345
|
+
gap: var(--fd-space-md);
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
:global(.playground-studio__loading-icon) {
|
|
349
|
+
font-size: var(--fd-space-6xl);
|
|
350
|
+
animation: studio-spin 1s linear infinite;
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
@keyframes studio-spin {
|
|
354
|
+
from {
|
|
355
|
+
transform: rotate(0deg);
|
|
356
|
+
}
|
|
357
|
+
to {
|
|
358
|
+
transform: rotate(360deg);
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
/* Error state */
|
|
363
|
+
.playground-studio__error {
|
|
364
|
+
display: flex;
|
|
365
|
+
flex-direction: column;
|
|
366
|
+
align-items: center;
|
|
367
|
+
justify-content: center;
|
|
368
|
+
height: 100%;
|
|
369
|
+
padding: var(--fd-space-4xl);
|
|
370
|
+
text-align: center;
|
|
371
|
+
gap: var(--fd-space-md);
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
:global(.playground-studio__error-icon) {
|
|
375
|
+
font-size: var(--fd-space-7xl);
|
|
376
|
+
color: var(--fd-error);
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
.playground-studio__error-text {
|
|
380
|
+
font-size: var(--fd-text-base);
|
|
381
|
+
color: var(--fd-muted-foreground);
|
|
382
|
+
margin: 0;
|
|
383
|
+
max-width: 400px;
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
.playground-studio__retry-btn {
|
|
387
|
+
display: inline-flex;
|
|
388
|
+
align-items: center;
|
|
389
|
+
gap: var(--fd-space-xs);
|
|
390
|
+
padding: var(--fd-space-md) var(--fd-space-3xl);
|
|
391
|
+
border: none;
|
|
392
|
+
border-radius: var(--fd-radius-lg);
|
|
393
|
+
background-color: var(--fd-primary);
|
|
394
|
+
color: var(--fd-primary-foreground);
|
|
395
|
+
font-size: var(--fd-text-base);
|
|
396
|
+
font-weight: 500;
|
|
397
|
+
cursor: pointer;
|
|
398
|
+
transition: background-color var(--fd-transition-normal);
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
.playground-studio__retry-btn:hover {
|
|
402
|
+
background-color: var(--fd-primary-hover);
|
|
403
|
+
}
|
|
404
|
+
</style>
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { Workflow } from '../../types/index.js';
|
|
2
|
+
import type { EndpointConfig } from '../../config/endpoints.js';
|
|
3
|
+
import type { PlaygroundConfig, PlaygroundMode } from '../../types/playground.js';
|
|
4
|
+
interface Props {
|
|
5
|
+
/** Target workflow ID */
|
|
6
|
+
workflowId: string;
|
|
7
|
+
/** Pre-loaded workflow — skips internal fetch when provided */
|
|
8
|
+
workflow?: Workflow;
|
|
9
|
+
/** API endpoint configuration */
|
|
10
|
+
endpointConfig?: EndpointConfig;
|
|
11
|
+
/** Display mode (default: standalone) */
|
|
12
|
+
mode?: PlaygroundMode;
|
|
13
|
+
/** Session ID to activate on mount. Changing this prop remounts the Playground. */
|
|
14
|
+
initialSessionId?: string;
|
|
15
|
+
/** Playground configuration options */
|
|
16
|
+
config?: PlaygroundConfig;
|
|
17
|
+
/** Whether the pipeline panel starts open. When omitted the stored preference is used. */
|
|
18
|
+
initialPipelineOpen?: boolean;
|
|
19
|
+
/** Minimum chat panel width in px (default: 760) */
|
|
20
|
+
minChatWidth?: number;
|
|
21
|
+
/** Initial pipeline panel width in px (default: 500) */
|
|
22
|
+
initialPipelineWidth?: number;
|
|
23
|
+
/** Called when session navigation is requested — use for URL-based routing */
|
|
24
|
+
onSessionNavigate?: (sessionId: string) => void;
|
|
25
|
+
/** Called when the playground is closed (embedded / modal mode) */
|
|
26
|
+
onClose?: () => void;
|
|
27
|
+
}
|
|
28
|
+
declare const PlaygroundStudio: import("svelte").Component<Props, {}, "">;
|
|
29
|
+
type PlaygroundStudio = ReturnType<typeof PlaygroundStudio>;
|
|
30
|
+
export default PlaygroundStudio;
|
package/dist/editor/index.d.ts
CHANGED
|
@@ -76,7 +76,7 @@ export { setEndpointConfig, getEndpointConfig, nodeApi, workflowApi, api } from
|
|
|
76
76
|
export { showSuccess, showError, showWarning, showInfo, showLoading, dismissToast, dismissAllToasts, showPromise, showConfirmation, apiToasts, workflowToasts, pipelineToasts } from '../services/toastService.js';
|
|
77
77
|
export { NodeExecutionService, nodeExecutionService } from '../services/nodeExecutionService.js';
|
|
78
78
|
export { PlaygroundService, playgroundService } from '../services/playgroundService.js';
|
|
79
|
-
export { getCurrentSession, getSessions, getMessages, getIsExecuting, getIsLoading, getError as getPlaygroundError, getCurrentWorkflow,
|
|
79
|
+
export { getCurrentSession, getSessions, getMessages, getIsExecuting, getCanSendMessage, getIsLoading, getError as getPlaygroundError, getCurrentWorkflow, getLastPollSequenceNumber, getSessionStatus, getMessageCount, getChatMessages, getLogMessages, getLatestMessage, getInputFields, getHasChatInput, getSessionCount, playgroundActions, applyServerResponse, subscribeToSessionStatus, getCurrentSessionId, isSessionSelected, getMessagesSnapshot, getLatestSequenceNumber } from '../stores/playgroundStore.svelte.js';
|
|
80
80
|
export { saveWorkflow, updateWorkflow, getWorkflow, getWorkflows, deleteWorkflow, getWorkflowCount, initializeSampleWorkflows } from '../services/workflowStorage.js';
|
|
81
81
|
export { globalSaveWorkflow, globalExportWorkflow } from '../services/globalSave.js';
|
|
82
82
|
export { fetchPortConfig, validatePortConfig } from '../services/portConfigApi.js';
|
package/dist/editor/index.js
CHANGED
|
@@ -119,7 +119,7 @@ export { showSuccess, showError, showWarning, showInfo, showLoading, dismissToas
|
|
|
119
119
|
export { NodeExecutionService, nodeExecutionService } from '../services/nodeExecutionService.js';
|
|
120
120
|
// Playground Service and Store
|
|
121
121
|
export { PlaygroundService, playgroundService } from '../services/playgroundService.js';
|
|
122
|
-
export { getCurrentSession, getSessions, getMessages, getIsExecuting, getIsLoading, getError as getPlaygroundError, getCurrentWorkflow,
|
|
122
|
+
export { getCurrentSession, getSessions, getMessages, getIsExecuting, getCanSendMessage, getIsLoading, getError as getPlaygroundError, getCurrentWorkflow, getLastPollSequenceNumber, getSessionStatus, getMessageCount, getChatMessages, getLogMessages, getLatestMessage, getInputFields, getHasChatInput, getSessionCount, playgroundActions, applyServerResponse, subscribeToSessionStatus, getCurrentSessionId, isSessionSelected, getMessagesSnapshot, getLatestSequenceNumber } from '../stores/playgroundStore.svelte.js';
|
|
123
123
|
export { saveWorkflow, updateWorkflow, getWorkflow, getWorkflows, deleteWorkflow, getWorkflowCount, initializeSampleWorkflows } from '../services/workflowStorage.js';
|
|
124
124
|
export { globalSaveWorkflow, globalExportWorkflow } from '../services/globalSave.js';
|
|
125
125
|
export { fetchPortConfig, validatePortConfig } from '../services/portConfigApi.js';
|
|
@@ -111,8 +111,12 @@
|
|
|
111
111
|
* ```
|
|
112
112
|
*/
|
|
113
113
|
export { default as Playground } from '../components/playground/Playground.svelte';
|
|
114
|
+
export { default as PlaygroundStudio } from '../components/playground/PlaygroundStudio.svelte';
|
|
115
|
+
export { default as PlaygroundApp } from '../components/playground/PlaygroundApp.svelte';
|
|
114
116
|
export { default as PlaygroundModal } from '../components/playground/PlaygroundModal.svelte';
|
|
115
117
|
export { default as ChatPanel } from '../components/playground/ChatPanel.svelte';
|
|
118
|
+
export { default as PipelinePanel } from '../components/playground/PipelinePanel.svelte';
|
|
119
|
+
export { default as ExecutionList } from '../components/playground/ExecutionList.svelte';
|
|
116
120
|
export { default as SessionManager } from '../components/playground/SessionManager.svelte';
|
|
117
121
|
export { default as InputCollector } from '../components/playground/InputCollector.svelte';
|
|
118
122
|
export { default as ExecutionLogs } from '../components/playground/ExecutionLogs.svelte';
|
|
@@ -120,12 +124,13 @@ export { default as MessageBubble } from '../components/playground/MessageBubble
|
|
|
120
124
|
export { InterruptBubble, ConfirmationPrompt, ChoicePrompt, TextInputPrompt, FormPrompt, ReviewPrompt } from '../components/interrupt/index.js';
|
|
121
125
|
export { PlaygroundService, playgroundService } from '../services/playgroundService.js';
|
|
122
126
|
export { InterruptService, interruptService } from '../services/interruptService.js';
|
|
123
|
-
export { getCurrentSession, getSessions, getMessages, getIsExecuting, getIsLoading, getError as getPlaygroundError, getCurrentWorkflow,
|
|
124
|
-
export
|
|
127
|
+
export { getCurrentSession, getSessions, getMessages, getIsExecuting, getCanSendMessage, getIsLoading, getError as getPlaygroundError, getCurrentWorkflow, getLastPollSequenceNumber, getSessionStatus, getMessageCount, getChatMessages, getLogMessages, getLatestMessage, getInputFields, getHasChatInput, getSessionCount, getActiveExecutionId, getPinnedExecutionId, getLatestExecutionId, playgroundActions, applyServerResponse, subscribeToSessionStatus, getCurrentSessionId, isSessionSelected, getMessagesSnapshot, getLatestSequenceNumber } from '../stores/playgroundStore.svelte.js';
|
|
128
|
+
export { getPipelinePanelOpen, pipelinePanelActions } from '../stores/pipelinePanelStore.svelte.js';
|
|
129
|
+
export type { PlaygroundSession, PlaygroundMessage, PlaygroundInputField, PlaygroundMessageRequest, PlaygroundMessagesResult, PlaygroundConfig, PlaygroundMode, PlaygroundSessionStatus, PlaygroundMessageRole, PlaygroundMessageLevel, PlaygroundMessageMetadata, PlaygroundApiResponse, PlaygroundSessionsResponse, PlaygroundSessionResponse, PlaygroundMessageResponse, PlaygroundMessagesApiResponse, PlaygroundExecution } from '../types/playground.js';
|
|
125
130
|
export { isChatInputNode, CHAT_INPUT_PATTERNS, defaultShouldStopPolling, defaultIsTerminalStatus, DEFAULT_STOP_POLLING_STATUSES, DEFAULT_TERMINAL_STATUSES } from '../types/playground.js';
|
|
126
131
|
export type { InterruptType, InterruptStatus, Interrupt, InterruptChoice, InterruptConfig, ConfirmationConfig, ChoiceConfig, TextConfig, FormConfig, ReviewConfig, ReviewChange, ReviewFieldDecision, ReviewResolution, InterruptResolution, InterruptApiResponse, InterruptListResponse, InterruptResponse, InterruptMessageMetadata, InterruptPollingConfig } from '../types/interrupt.js';
|
|
127
132
|
export { isInterruptMetadata, extractInterruptMetadata, metadataToInterrupt, defaultInterruptPollingConfig } from '../types/interrupt.js';
|
|
128
133
|
export { getInterruptsMap, getPendingInterruptIds, getPendingInterrupts, getPendingInterruptCount, getResolvedInterrupts, getIsAnySubmitting, interruptActions, getInterrupt, isInterruptPending, isInterruptSubmitting, getInterruptError, getInterruptByMessageId, interruptHasError } from '../stores/interruptStore.svelte.js';
|
|
129
134
|
export type { InterruptWithState } from '../stores/interruptStore.svelte.js';
|
|
130
|
-
export { mountPlayground, unmountPlayground, type PlaygroundMountOptions, type MountedPlayground } from './mount.js';
|
|
135
|
+
export { mountPlayground, unmountPlayground, mountPlaygroundStudio, mountPlaygroundApp, type PlaygroundMountOptions, type PlaygroundStudioMountOptions, type PlaygroundAppMountOptions, type MountedPlayground } from './mount.js';
|
|
131
136
|
export { createEndpointConfig, defaultEndpointConfig, buildEndpointUrl, type EndpointConfig } from '../config/endpoints.js';
|
package/dist/playground/index.js
CHANGED
|
@@ -114,8 +114,12 @@
|
|
|
114
114
|
// Playground Components
|
|
115
115
|
// ============================================================================
|
|
116
116
|
export { default as Playground } from '../components/playground/Playground.svelte';
|
|
117
|
+
export { default as PlaygroundStudio } from '../components/playground/PlaygroundStudio.svelte';
|
|
118
|
+
export { default as PlaygroundApp } from '../components/playground/PlaygroundApp.svelte';
|
|
117
119
|
export { default as PlaygroundModal } from '../components/playground/PlaygroundModal.svelte';
|
|
118
120
|
export { default as ChatPanel } from '../components/playground/ChatPanel.svelte';
|
|
121
|
+
export { default as PipelinePanel } from '../components/playground/PipelinePanel.svelte';
|
|
122
|
+
export { default as ExecutionList } from '../components/playground/ExecutionList.svelte';
|
|
119
123
|
export { default as SessionManager } from '../components/playground/SessionManager.svelte';
|
|
120
124
|
export { default as InputCollector } from '../components/playground/InputCollector.svelte';
|
|
121
125
|
export { default as ExecutionLogs } from '../components/playground/ExecutionLogs.svelte';
|
|
@@ -137,17 +141,23 @@ export { InterruptService, interruptService } from '../services/interruptService
|
|
|
137
141
|
// ============================================================================
|
|
138
142
|
export {
|
|
139
143
|
// Core state getters
|
|
140
|
-
getCurrentSession, getSessions, getMessages, getIsExecuting, getIsLoading, getError as getPlaygroundError, getCurrentWorkflow,
|
|
144
|
+
getCurrentSession, getSessions, getMessages, getIsExecuting, getCanSendMessage, getIsLoading, getError as getPlaygroundError, getCurrentWorkflow, getLastPollSequenceNumber,
|
|
141
145
|
// Derived getters
|
|
142
146
|
getSessionStatus, getMessageCount, getChatMessages, getLogMessages, getLatestMessage, getInputFields, getHasChatInput, getSessionCount,
|
|
147
|
+
// Execution getters (used with PipelinePanel / PlaygroundSplit)
|
|
148
|
+
getActiveExecutionId, getPinnedExecutionId, getLatestExecutionId,
|
|
143
149
|
// Actions
|
|
144
150
|
playgroundActions,
|
|
145
|
-
//
|
|
146
|
-
|
|
151
|
+
// Server response application (single update path)
|
|
152
|
+
applyServerResponse,
|
|
147
153
|
// Subscription utility
|
|
148
154
|
subscribeToSessionStatus,
|
|
149
155
|
// Utilities
|
|
150
|
-
getCurrentSessionId, isSessionSelected, getMessagesSnapshot,
|
|
156
|
+
getCurrentSessionId, isSessionSelected, getMessagesSnapshot, getLatestSequenceNumber } from '../stores/playgroundStore.svelte.js';
|
|
157
|
+
// ============================================================================
|
|
158
|
+
// Pipeline Panel Store (open/close state, persisted to localStorage)
|
|
159
|
+
// ============================================================================
|
|
160
|
+
export { getPipelinePanelOpen, pipelinePanelActions } from '../stores/pipelinePanelStore.svelte.js';
|
|
151
161
|
export { isChatInputNode, CHAT_INPUT_PATTERNS, defaultShouldStopPolling, defaultIsTerminalStatus, DEFAULT_STOP_POLLING_STATUSES, DEFAULT_TERMINAL_STATUSES } from '../types/playground.js';
|
|
152
162
|
export { isInterruptMetadata, extractInterruptMetadata, metadataToInterrupt, defaultInterruptPollingConfig } from '../types/interrupt.js';
|
|
153
163
|
// ============================================================================
|
|
@@ -165,7 +175,7 @@ getInterrupt, isInterruptPending, isInterruptSubmitting, getInterruptError, getI
|
|
|
165
175
|
// ============================================================================
|
|
166
176
|
// Playground Mount Functions (for vanilla JS / Drupal / IIFE integration)
|
|
167
177
|
// ============================================================================
|
|
168
|
-
export { mountPlayground, unmountPlayground } from './mount.js';
|
|
178
|
+
export { mountPlayground, unmountPlayground, mountPlaygroundStudio, mountPlaygroundApp } from './mount.js';
|
|
169
179
|
// ============================================================================
|
|
170
180
|
// Endpoint Configuration (re-exported for convenience)
|
|
171
181
|
// ============================================================================
|
|
@@ -46,6 +46,8 @@
|
|
|
46
46
|
import type { Workflow } from '../types/index.js';
|
|
47
47
|
import type { EndpointConfig } from '../config/endpoints.js';
|
|
48
48
|
import type { PlaygroundMode, PlaygroundConfig, PlaygroundSession, PlaygroundMessagesApiResponse, PlaygroundSessionStatus } from '../types/playground.js';
|
|
49
|
+
import type { PartialSettings, SettingsCategory } from '../types/settings.js';
|
|
50
|
+
import type { NavbarAction } from '../types/navbar.js';
|
|
49
51
|
/**
|
|
50
52
|
* Mount options for Playground component
|
|
51
53
|
*/
|
|
@@ -83,13 +85,15 @@ export interface PlaygroundMountOptions {
|
|
|
83
85
|
*/
|
|
84
86
|
config?: PlaygroundConfig;
|
|
85
87
|
/**
|
|
86
|
-
* Container height (CSS value)
|
|
87
|
-
*
|
|
88
|
+
* Container height (CSS value). If omitted, the library does NOT set an
|
|
89
|
+
* inline height — the host's own CSS owns sizing. Pass a definite value
|
|
90
|
+
* (e.g. `"100dvh"`, `"600px"`) only when mounting into an unsized
|
|
91
|
+
* container.
|
|
88
92
|
*/
|
|
89
93
|
height?: string;
|
|
90
94
|
/**
|
|
91
|
-
* Container width (CSS value)
|
|
92
|
-
*
|
|
95
|
+
* Container width (CSS value). If omitted, the library does NOT set an
|
|
96
|
+
* inline width. See `height` for rationale.
|
|
93
97
|
*/
|
|
94
98
|
width?: string;
|
|
95
99
|
/**
|
|
@@ -103,6 +107,12 @@ export interface PlaygroundMountOptions {
|
|
|
103
107
|
* @param previousStatus - The previous session status
|
|
104
108
|
*/
|
|
105
109
|
onSessionStatusChange?: (status: PlaygroundSessionStatus, previousStatus: PlaygroundSessionStatus) => void;
|
|
110
|
+
/**
|
|
111
|
+
* Optional setting overrides deep-merged over current settings before mount.
|
|
112
|
+
* Theme is re-initialized on every mount regardless. Mirrors mountFlowDropApp's
|
|
113
|
+
* `settings` option.
|
|
114
|
+
*/
|
|
115
|
+
settings?: PartialSettings;
|
|
106
116
|
}
|
|
107
117
|
/**
|
|
108
118
|
* Return type for mounted Playground instance
|
|
@@ -201,3 +211,52 @@ export declare function mountPlayground(container: HTMLElement, options: Playgro
|
|
|
201
211
|
* ```
|
|
202
212
|
*/
|
|
203
213
|
export declare function unmountPlayground(app: MountedPlayground): void;
|
|
214
|
+
export interface PlaygroundStudioMountOptions extends PlaygroundMountOptions {
|
|
215
|
+
initialPipelineOpen?: boolean;
|
|
216
|
+
minChatWidth?: number;
|
|
217
|
+
initialPipelineWidth?: number;
|
|
218
|
+
onSessionNavigate?: (sessionId: string) => void;
|
|
219
|
+
}
|
|
220
|
+
export declare function mountPlaygroundStudio(container: HTMLElement, options: PlaygroundStudioMountOptions): Promise<MountedPlayground>;
|
|
221
|
+
export interface PlaygroundAppMountOptions extends Omit<PlaygroundStudioMountOptions, 'mode'> {
|
|
222
|
+
/**
|
|
223
|
+
* Display mode. Modal is unsupported — use mountPlayground() for that.
|
|
224
|
+
* @default "standalone"
|
|
225
|
+
*/
|
|
226
|
+
mode?: 'standalone' | 'embedded';
|
|
227
|
+
/** Render the FlowDrop Navbar above the playground (default: true). */
|
|
228
|
+
showNavbar?: boolean;
|
|
229
|
+
/** Title shown in the navbar. Falls back to the workflow name, then "Playground". */
|
|
230
|
+
navbarTitle?: string;
|
|
231
|
+
/** Action buttons rendered in the navbar. Passed straight through to <Navbar primaryActions>. */
|
|
232
|
+
primaryActions?: NavbarAction[];
|
|
233
|
+
/** Show the settings gear icon in the navbar (default: true). */
|
|
234
|
+
showSettings?: boolean;
|
|
235
|
+
/** Restrict which settings categories are exposed in the settings modal. */
|
|
236
|
+
settingsCategories?: SettingsCategory[];
|
|
237
|
+
/** Show the "Sync to Cloud" button in the settings modal. */
|
|
238
|
+
showSettingsSyncButton?: boolean;
|
|
239
|
+
/** Show the reset buttons in the settings modal. */
|
|
240
|
+
showSettingsResetButton?: boolean;
|
|
241
|
+
}
|
|
242
|
+
/**
|
|
243
|
+
* Mount the full-page PlaygroundApp (Navbar + PlaygroundStudio) into a container.
|
|
244
|
+
*
|
|
245
|
+
* Use this when you want the same chrome as the FlowDrop editor — logo,
|
|
246
|
+
* branding, and settings modal — wrapped around the playground. For an
|
|
247
|
+
* embeddable split-pane without the navbar, use mountPlaygroundStudio().
|
|
248
|
+
*
|
|
249
|
+
* @example
|
|
250
|
+
* ```typescript
|
|
251
|
+
* const app = await mountPlaygroundApp(container, {
|
|
252
|
+
* workflowId: 'wf-123',
|
|
253
|
+
* endpointConfig: createEndpointConfig('/api/flowdrop'),
|
|
254
|
+
* navbarTitle: 'My Workflow',
|
|
255
|
+
* primaryActions: [
|
|
256
|
+
* { label: 'Edit', href: '/workflows/wf-123/edit', icon: 'mdi:pencil-outline', variant: 'secondary' },
|
|
257
|
+
* { label: 'Workflows', href: '/workflows', icon: 'mdi:arrow-left', variant: 'outline' }
|
|
258
|
+
* ]
|
|
259
|
+
* });
|
|
260
|
+
* ```
|
|
261
|
+
*/
|
|
262
|
+
export declare function mountPlaygroundApp(container: HTMLElement, options: PlaygroundAppMountOptions): Promise<MountedPlayground>;
|