@d34dman/flowdrop 0.0.30 → 0.0.32

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. package/dist/components/App.svelte +54 -6
  2. package/dist/components/NodeSidebar.svelte +1 -1
  3. package/dist/components/SchemaForm.svelte +14 -14
  4. package/dist/components/SchemaForm.svelte.d.ts +1 -1
  5. package/dist/components/form/FormFieldLight.svelte +66 -66
  6. package/dist/components/form/FormFieldLight.svelte.d.ts +1 -1
  7. package/dist/components/form/types.d.ts +1 -1
  8. package/dist/components/playground/ChatPanel.svelte +523 -0
  9. package/dist/components/playground/ChatPanel.svelte.d.ts +20 -0
  10. package/dist/components/playground/ExecutionLogs.svelte +486 -0
  11. package/dist/components/playground/ExecutionLogs.svelte.d.ts +14 -0
  12. package/dist/components/playground/InputCollector.svelte +444 -0
  13. package/dist/components/playground/InputCollector.svelte.d.ts +16 -0
  14. package/dist/components/playground/MessageBubble.svelte +398 -0
  15. package/dist/components/playground/MessageBubble.svelte.d.ts +15 -0
  16. package/dist/components/playground/Playground.svelte +861 -0
  17. package/dist/components/playground/Playground.svelte.d.ts +25 -0
  18. package/dist/components/playground/PlaygroundModal.svelte +220 -0
  19. package/dist/components/playground/PlaygroundModal.svelte.d.ts +25 -0
  20. package/dist/components/playground/SessionManager.svelte +537 -0
  21. package/dist/components/playground/SessionManager.svelte.d.ts +20 -0
  22. package/dist/config/endpoints.d.ts +16 -0
  23. package/dist/config/endpoints.js +9 -0
  24. package/dist/core/index.d.ts +25 -23
  25. package/dist/core/index.js +13 -12
  26. package/dist/display/index.d.ts +2 -2
  27. package/dist/display/index.js +2 -2
  28. package/dist/editor/index.d.ts +58 -49
  29. package/dist/editor/index.js +53 -42
  30. package/dist/form/code.d.ts +4 -4
  31. package/dist/form/code.js +11 -11
  32. package/dist/form/fieldRegistry.d.ts +2 -2
  33. package/dist/form/fieldRegistry.js +8 -10
  34. package/dist/form/full.d.ts +5 -5
  35. package/dist/form/full.js +7 -7
  36. package/dist/form/index.d.ts +16 -16
  37. package/dist/form/index.js +14 -14
  38. package/dist/form/markdown.d.ts +3 -3
  39. package/dist/form/markdown.js +6 -6
  40. package/dist/index.d.ts +6 -4
  41. package/dist/index.js +9 -4
  42. package/dist/playground/index.d.ts +125 -0
  43. package/dist/playground/index.js +147 -0
  44. package/dist/playground/mount.d.ts +184 -0
  45. package/dist/playground/mount.js +209 -0
  46. package/dist/services/playgroundService.d.ts +129 -0
  47. package/dist/services/playgroundService.js +317 -0
  48. package/dist/stores/playgroundStore.d.ts +199 -0
  49. package/dist/stores/playgroundStore.js +350 -0
  50. package/dist/types/playground.d.ts +230 -0
  51. package/dist/types/playground.js +28 -0
  52. package/dist/utils/colors.js +4 -4
  53. package/package.json +6 -1
@@ -0,0 +1,486 @@
1
+ <!--
2
+ ExecutionLogs Component
3
+
4
+ Collapsible panel for displaying execution logs in the playground.
5
+ Shows real-time log entries with filtering and export capabilities.
6
+ Styled with BEM syntax.
7
+ -->
8
+
9
+ <script lang="ts">
10
+ import Icon from '@iconify/svelte';
11
+ import { slide } from 'svelte/transition';
12
+ import type { PlaygroundMessage, PlaygroundMessageLevel } from '../../types/playground.js';
13
+ import { logMessages } from '../../stores/playgroundStore.js';
14
+
15
+ /**
16
+ * Component props
17
+ */
18
+ interface Props {
19
+ /** Whether the logs panel is expanded */
20
+ isExpanded?: boolean;
21
+ /** Maximum height of the logs panel */
22
+ maxHeight?: string;
23
+ /** Callback when expansion state changes */
24
+ onToggle?: (expanded: boolean) => void;
25
+ }
26
+
27
+ let { isExpanded = $bindable(false), maxHeight = '300px', onToggle }: Props = $props();
28
+
29
+ /** Current log level filter */
30
+ let levelFilter = $state<PlaygroundMessageLevel | 'all'>('all');
31
+
32
+ /** Reference to logs container for auto-scroll */
33
+ let logsContainer = $state<HTMLDivElement>();
34
+
35
+ /**
36
+ * Filter logs based on selected level
37
+ */
38
+ const filteredLogs = $derived(
39
+ levelFilter === 'all'
40
+ ? $logMessages
41
+ : $logMessages.filter((log) => log.metadata?.level === levelFilter)
42
+ );
43
+
44
+ /**
45
+ * Count of logs by level
46
+ */
47
+ const logCounts = $derived({
48
+ all: $logMessages.length,
49
+ info: $logMessages.filter((l) => l.metadata?.level === 'info').length,
50
+ warning: $logMessages.filter((l) => l.metadata?.level === 'warning').length,
51
+ error: $logMessages.filter((l) => l.metadata?.level === 'error').length,
52
+ debug: $logMessages.filter((l) => l.metadata?.level === 'debug').length
53
+ });
54
+
55
+ /**
56
+ * Toggle expansion
57
+ */
58
+ function toggleExpanded(): void {
59
+ isExpanded = !isExpanded;
60
+ onToggle?.(isExpanded);
61
+ }
62
+
63
+ /**
64
+ * Format timestamp for display
65
+ */
66
+ function formatTimestamp(timestamp: string): string {
67
+ const date = new Date(timestamp);
68
+ return date.toLocaleTimeString('en-US', {
69
+ hour12: false,
70
+ hour: '2-digit',
71
+ minute: '2-digit',
72
+ second: '2-digit',
73
+ fractionalSecondDigits: 3
74
+ });
75
+ }
76
+
77
+ /**
78
+ * Get icon for log level
79
+ */
80
+ function getLevelIcon(level: PlaygroundMessageLevel | undefined): string {
81
+ switch (level) {
82
+ case 'error':
83
+ return 'mdi:alert-circle';
84
+ case 'warning':
85
+ return 'mdi:alert';
86
+ case 'debug':
87
+ return 'mdi:bug';
88
+ default:
89
+ return 'mdi:information';
90
+ }
91
+ }
92
+
93
+ /**
94
+ * Export logs to file
95
+ */
96
+ function exportLogs(): void {
97
+ const logText = filteredLogs
98
+ .map(
99
+ (log) =>
100
+ `[${formatTimestamp(log.timestamp)}] [${(log.metadata?.level ?? 'info').toUpperCase()}] ${log.content}${log.nodeId ? ` (Node: ${log.nodeId})` : ''}`
101
+ )
102
+ .join('\n');
103
+
104
+ const blob = new Blob([logText], { type: 'text/plain' });
105
+ const url = URL.createObjectURL(blob);
106
+ const link = document.createElement('a');
107
+ link.href = url;
108
+ link.download = `playground-logs-${new Date().toISOString().split('T')[0]}.txt`;
109
+ link.click();
110
+ URL.revokeObjectURL(url);
111
+ }
112
+
113
+ /**
114
+ * Auto-scroll to bottom when new logs arrive
115
+ */
116
+ $effect(() => {
117
+ if (isExpanded && logsContainer && filteredLogs.length > 0) {
118
+ logsContainer.scrollTop = logsContainer.scrollHeight;
119
+ }
120
+ });
121
+ </script>
122
+
123
+ <div class="execution-logs" class:execution-logs--expanded={isExpanded}>
124
+ <!-- Header -->
125
+ <button
126
+ type="button"
127
+ class="execution-logs__header"
128
+ onclick={toggleExpanded}
129
+ aria-expanded={isExpanded}
130
+ >
131
+ <div class="execution-logs__title">
132
+ <Icon icon="mdi:console" />
133
+ <span>Execution Logs</span>
134
+ {#if logCounts.all > 0}
135
+ <span class="execution-logs__badge">{logCounts.all}</span>
136
+ {/if}
137
+ {#if logCounts.error > 0}
138
+ <span class="execution-logs__badge execution-logs__badge--error">{logCounts.error}</span>
139
+ {/if}
140
+ {#if logCounts.warning > 0}
141
+ <span class="execution-logs__badge execution-logs__badge--warning">{logCounts.warning}</span
142
+ >
143
+ {/if}
144
+ </div>
145
+ <Icon
146
+ icon="mdi:chevron-down"
147
+ class="execution-logs__chevron {isExpanded ? 'execution-logs__chevron--expanded' : ''}"
148
+ />
149
+ </button>
150
+
151
+ <!-- Content -->
152
+ {#if isExpanded}
153
+ <div class="execution-logs__content" transition:slide={{ duration: 200 }}>
154
+ <!-- Toolbar -->
155
+ <div class="execution-logs__toolbar">
156
+ <div class="execution-logs__filters">
157
+ <button
158
+ type="button"
159
+ class="execution-logs__filter"
160
+ class:execution-logs__filter--active={levelFilter === 'all'}
161
+ onclick={() => (levelFilter = 'all')}
162
+ >
163
+ All ({logCounts.all})
164
+ </button>
165
+ <button
166
+ type="button"
167
+ class="execution-logs__filter execution-logs__filter--info"
168
+ class:execution-logs__filter--active={levelFilter === 'info'}
169
+ onclick={() => (levelFilter = 'info')}
170
+ >
171
+ Info ({logCounts.info})
172
+ </button>
173
+ <button
174
+ type="button"
175
+ class="execution-logs__filter execution-logs__filter--warning"
176
+ class:execution-logs__filter--active={levelFilter === 'warning'}
177
+ onclick={() => (levelFilter = 'warning')}
178
+ >
179
+ Warning ({logCounts.warning})
180
+ </button>
181
+ <button
182
+ type="button"
183
+ class="execution-logs__filter execution-logs__filter--error"
184
+ class:execution-logs__filter--active={levelFilter === 'error'}
185
+ onclick={() => (levelFilter = 'error')}
186
+ >
187
+ Error ({logCounts.error})
188
+ </button>
189
+ </div>
190
+ <button
191
+ type="button"
192
+ class="execution-logs__export"
193
+ onclick={exportLogs}
194
+ disabled={filteredLogs.length === 0}
195
+ title="Export logs"
196
+ >
197
+ <Icon icon="mdi:download" />
198
+ </button>
199
+ </div>
200
+
201
+ <!-- Logs List -->
202
+ <div class="execution-logs__list" bind:this={logsContainer} style="max-height: {maxHeight}">
203
+ {#if filteredLogs.length === 0}
204
+ <div class="execution-logs__empty">
205
+ <Icon icon="mdi:file-document-outline" />
206
+ <span>No logs to display</span>
207
+ </div>
208
+ {:else}
209
+ {#each filteredLogs as log (log.id)}
210
+ <div
211
+ class="execution-logs__entry"
212
+ class:execution-logs__entry--error={log.metadata?.level === 'error'}
213
+ class:execution-logs__entry--warning={log.metadata?.level === 'warning'}
214
+ class:execution-logs__entry--debug={log.metadata?.level === 'debug'}
215
+ >
216
+ <span class="execution-logs__entry-time">
217
+ {formatTimestamp(log.timestamp)}
218
+ </span>
219
+ <span class="execution-logs__entry-level">
220
+ <Icon icon={getLevelIcon(log.metadata?.level)} />
221
+ </span>
222
+ <span class="execution-logs__entry-content">
223
+ {log.content}
224
+ </span>
225
+ {#if log.nodeId}
226
+ <span class="execution-logs__entry-node" title="Node: {log.nodeId}">
227
+ {log.metadata?.nodeLabel ?? log.nodeId}
228
+ </span>
229
+ {/if}
230
+ </div>
231
+ {/each}
232
+ {/if}
233
+ </div>
234
+ </div>
235
+ {/if}
236
+ </div>
237
+
238
+ <style>
239
+ .execution-logs {
240
+ border-top: 1px solid #e2e8f0;
241
+ background-color: #f8fafc;
242
+ }
243
+
244
+ /* Header */
245
+ .execution-logs__header {
246
+ display: flex;
247
+ align-items: center;
248
+ justify-content: space-between;
249
+ width: 100%;
250
+ padding: 0.75rem 1rem;
251
+ border: none;
252
+ background: transparent;
253
+ cursor: pointer;
254
+ transition: background-color 0.2s ease-in-out;
255
+ }
256
+
257
+ .execution-logs__header:hover {
258
+ background-color: #f1f5f9;
259
+ }
260
+
261
+ .execution-logs__title {
262
+ display: flex;
263
+ align-items: center;
264
+ gap: 0.5rem;
265
+ font-size: 0.875rem;
266
+ font-weight: 500;
267
+ color: #475569;
268
+ }
269
+
270
+ .execution-logs__badge {
271
+ display: inline-flex;
272
+ align-items: center;
273
+ justify-content: center;
274
+ min-width: 1.25rem;
275
+ height: 1.25rem;
276
+ padding: 0 0.375rem;
277
+ border-radius: 0.625rem;
278
+ font-size: 0.6875rem;
279
+ font-weight: 600;
280
+ background-color: #e2e8f0;
281
+ color: #475569;
282
+ }
283
+
284
+ .execution-logs__badge--error {
285
+ background-color: #fee2e2;
286
+ color: #dc2626;
287
+ }
288
+
289
+ .execution-logs__badge--warning {
290
+ background-color: #fef3c7;
291
+ color: #d97706;
292
+ }
293
+
294
+ :global(.execution-logs__chevron) {
295
+ transition: transform 0.2s ease-in-out;
296
+ color: #94a3b8;
297
+ }
298
+
299
+ :global(.execution-logs__chevron--expanded) {
300
+ transform: rotate(180deg);
301
+ }
302
+
303
+ /* Content */
304
+ .execution-logs__content {
305
+ border-top: 1px solid #e2e8f0;
306
+ }
307
+
308
+ /* Toolbar */
309
+ .execution-logs__toolbar {
310
+ display: flex;
311
+ align-items: center;
312
+ justify-content: space-between;
313
+ padding: 0.5rem 1rem;
314
+ background-color: #ffffff;
315
+ border-bottom: 1px solid #e2e8f0;
316
+ }
317
+
318
+ .execution-logs__filters {
319
+ display: flex;
320
+ gap: 0.25rem;
321
+ }
322
+
323
+ .execution-logs__filter {
324
+ padding: 0.25rem 0.5rem;
325
+ border: 1px solid transparent;
326
+ border-radius: 0.375rem;
327
+ background: transparent;
328
+ font-size: 0.75rem;
329
+ color: #64748b;
330
+ cursor: pointer;
331
+ transition: all 0.2s ease-in-out;
332
+ }
333
+
334
+ .execution-logs__filter:hover {
335
+ background-color: #f1f5f9;
336
+ }
337
+
338
+ .execution-logs__filter--active {
339
+ background-color: #e2e8f0;
340
+ color: #1e293b;
341
+ font-weight: 500;
342
+ }
343
+
344
+ .execution-logs__filter--info.execution-logs__filter--active {
345
+ background-color: #dbeafe;
346
+ color: #1d4ed8;
347
+ }
348
+
349
+ .execution-logs__filter--warning.execution-logs__filter--active {
350
+ background-color: #fef3c7;
351
+ color: #b45309;
352
+ }
353
+
354
+ .execution-logs__filter--error.execution-logs__filter--active {
355
+ background-color: #fee2e2;
356
+ color: #dc2626;
357
+ }
358
+
359
+ .execution-logs__export {
360
+ display: flex;
361
+ align-items: center;
362
+ justify-content: center;
363
+ width: 1.75rem;
364
+ height: 1.75rem;
365
+ border: 1px solid #e2e8f0;
366
+ border-radius: 0.375rem;
367
+ background: #ffffff;
368
+ color: #64748b;
369
+ cursor: pointer;
370
+ transition: all 0.2s ease-in-out;
371
+ }
372
+
373
+ .execution-logs__export:hover:not(:disabled) {
374
+ background-color: #f1f5f9;
375
+ color: #1e293b;
376
+ }
377
+
378
+ .execution-logs__export:disabled {
379
+ opacity: 0.5;
380
+ cursor: not-allowed;
381
+ }
382
+
383
+ /* Logs List */
384
+ .execution-logs__list {
385
+ overflow-y: auto;
386
+ font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;
387
+ font-size: 0.75rem;
388
+ line-height: 1.5;
389
+ }
390
+
391
+ .execution-logs__empty {
392
+ display: flex;
393
+ align-items: center;
394
+ justify-content: center;
395
+ gap: 0.5rem;
396
+ padding: 2rem;
397
+ color: #94a3b8;
398
+ }
399
+
400
+ .execution-logs__entry {
401
+ display: flex;
402
+ align-items: flex-start;
403
+ gap: 0.5rem;
404
+ padding: 0.375rem 1rem;
405
+ border-bottom: 1px solid #f1f5f9;
406
+ background-color: #ffffff;
407
+ }
408
+
409
+ .execution-logs__entry:hover {
410
+ background-color: #f8fafc;
411
+ }
412
+
413
+ .execution-logs__entry--error {
414
+ background-color: #fef2f2;
415
+ }
416
+
417
+ .execution-logs__entry--error:hover {
418
+ background-color: #fee2e2;
419
+ }
420
+
421
+ .execution-logs__entry--warning {
422
+ background-color: #fffbeb;
423
+ }
424
+
425
+ .execution-logs__entry--warning:hover {
426
+ background-color: #fef3c7;
427
+ }
428
+
429
+ .execution-logs__entry--debug {
430
+ color: #7c3aed;
431
+ }
432
+
433
+ .execution-logs__entry-time {
434
+ flex-shrink: 0;
435
+ color: #94a3b8;
436
+ }
437
+
438
+ .execution-logs__entry-level {
439
+ flex-shrink: 0;
440
+ display: flex;
441
+ align-items: center;
442
+ }
443
+
444
+ .execution-logs__entry--error .execution-logs__entry-level {
445
+ color: #dc2626;
446
+ }
447
+
448
+ .execution-logs__entry--warning .execution-logs__entry-level {
449
+ color: #d97706;
450
+ }
451
+
452
+ .execution-logs__entry--debug .execution-logs__entry-level {
453
+ color: #7c3aed;
454
+ }
455
+
456
+ .execution-logs__entry-content {
457
+ flex: 1;
458
+ min-width: 0;
459
+ word-break: break-word;
460
+ color: #334155;
461
+ }
462
+
463
+ .execution-logs__entry-node {
464
+ flex-shrink: 0;
465
+ padding: 0.125rem 0.375rem;
466
+ background-color: #f1f5f9;
467
+ border-radius: 0.25rem;
468
+ color: #64748b;
469
+ font-size: 0.6875rem;
470
+ }
471
+
472
+ /* Responsive */
473
+ @media (max-width: 640px) {
474
+ .execution-logs__filters {
475
+ flex-wrap: wrap;
476
+ }
477
+
478
+ .execution-logs__entry {
479
+ flex-wrap: wrap;
480
+ }
481
+
482
+ .execution-logs__entry-node {
483
+ margin-left: auto;
484
+ }
485
+ }
486
+ </style>
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Component props
3
+ */
4
+ interface Props {
5
+ /** Whether the logs panel is expanded */
6
+ isExpanded?: boolean;
7
+ /** Maximum height of the logs panel */
8
+ maxHeight?: string;
9
+ /** Callback when expansion state changes */
10
+ onToggle?: (expanded: boolean) => void;
11
+ }
12
+ declare const ExecutionLogs: import("svelte").Component<Props, {}, "isExpanded">;
13
+ type ExecutionLogs = ReturnType<typeof ExecutionLogs>;
14
+ export default ExecutionLogs;