@flowdrop/flowdrop 1.8.1 → 1.10.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/PipelineStatus.svelte +31 -8
- package/dist/components/PipelineStatus.svelte.d.ts +5 -0
- package/dist/components/WorkflowEditor.svelte +26 -0
- package/dist/components/chat/AIChatPanel.svelte +16 -5
- package/dist/components/playground/ChatPanel.svelte +31 -108
- package/dist/components/playground/ChatPanel.svelte.d.ts +3 -1
- package/dist/components/playground/ExecutionList.svelte +138 -0
- package/dist/components/playground/ExecutionList.svelte.d.ts +10 -0
- package/dist/components/playground/MessageBubble.svelte +281 -156
- package/dist/components/playground/PipelinePanel.svelte +382 -0
- package/dist/components/playground/PipelinePanel.svelte.d.ts +20 -0
- package/dist/components/playground/Playground.svelte +707 -174
- package/dist/components/playground/Playground.svelte.d.ts +6 -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 +7 -3
- package/dist/playground/index.js +14 -5
- package/dist/playground/mount.d.ts +7 -0
- package/dist/playground/mount.js +78 -81
- package/dist/services/globalSave.d.ts +7 -0
- package/dist/services/globalSave.js +5 -1
- 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/pipelinePanelStore.svelte.d.ts +6 -0
- package/dist/stores/pipelinePanelStore.svelte.js +24 -0
- package/dist/stores/playgroundStore.svelte.d.ts +26 -21
- package/dist/stores/playgroundStore.svelte.js +134 -55
- package/dist/svelte-app.js +25 -2
- package/dist/types/playground.d.ts +15 -5
- package/package.json +1 -1
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
*
|
|
7
7
|
* @module stores/playgroundStore
|
|
8
8
|
*/
|
|
9
|
-
import { isChatInputNode
|
|
9
|
+
import { isChatInputNode } from '../types/playground.js';
|
|
10
10
|
import { logger } from '../utils/logger.js';
|
|
11
11
|
// =========================================================================
|
|
12
12
|
// Core State
|
|
@@ -23,10 +23,6 @@ let _sessions = $state([]);
|
|
|
23
23
|
* Messages in the current session
|
|
24
24
|
*/
|
|
25
25
|
let _messages = $state([]);
|
|
26
|
-
/**
|
|
27
|
-
* Whether an execution is currently running
|
|
28
|
-
*/
|
|
29
|
-
let _isExecuting = $state(false);
|
|
30
26
|
/**
|
|
31
27
|
* Whether we are currently loading data
|
|
32
28
|
*/
|
|
@@ -42,7 +38,19 @@ let _currentWorkflow = $state(null);
|
|
|
42
38
|
/**
|
|
43
39
|
* Last polling timestamp for incremental message fetching
|
|
44
40
|
*/
|
|
45
|
-
let
|
|
41
|
+
let _lastPollSequenceNumber = $state(null);
|
|
42
|
+
/** Execution ID explicitly pinned by the user (null = follow latest) */
|
|
43
|
+
let _pinnedExecutionId = $state(null);
|
|
44
|
+
/** Incremented on every message batch that should trigger a pipeline re-fetch */
|
|
45
|
+
let _pipelineRefreshTrigger = $state(0);
|
|
46
|
+
/** Latest execution ID derived from current session's executions list */
|
|
47
|
+
const _latestExecutionId = $derived(_currentSession?.executions?.at(-1)?.id ?? null);
|
|
48
|
+
/** Active execution: pinned if set, otherwise latest */
|
|
49
|
+
const _activeExecutionId = $derived(_pinnedExecutionId ?? _latestExecutionId);
|
|
50
|
+
// Derived from server status — never manually set.
|
|
51
|
+
// Exception: updateSessionStatus('running') in handleSendMessage is an
|
|
52
|
+
// acknowledged optimistic write, overwritten by the next server response.
|
|
53
|
+
const _isExecuting = $derived(_currentSession?.status === 'running');
|
|
46
54
|
// =========================================================================
|
|
47
55
|
// Getter Functions (for reactive access in components)
|
|
48
56
|
// =========================================================================
|
|
@@ -89,10 +97,10 @@ export function getCurrentWorkflow() {
|
|
|
89
97
|
return _currentWorkflow;
|
|
90
98
|
}
|
|
91
99
|
/**
|
|
92
|
-
* Get the last poll
|
|
100
|
+
* Get the last poll sequence number cursor
|
|
93
101
|
*/
|
|
94
|
-
export function
|
|
95
|
-
return
|
|
102
|
+
export function getLastPollSequenceNumber() {
|
|
103
|
+
return _lastPollSequenceNumber;
|
|
96
104
|
}
|
|
97
105
|
// =========================================================================
|
|
98
106
|
// Derived Getters
|
|
@@ -103,6 +111,14 @@ export function getLastPollTimestamp() {
|
|
|
103
111
|
export function getSessionStatus() {
|
|
104
112
|
return _currentSession?.status ?? 'idle';
|
|
105
113
|
}
|
|
114
|
+
/**
|
|
115
|
+
* Whether the user can currently send a message.
|
|
116
|
+
* False when executing, when awaiting input, or when no session exists.
|
|
117
|
+
*/
|
|
118
|
+
export function getCanSendMessage() {
|
|
119
|
+
const status = _currentSession?.status ?? 'idle';
|
|
120
|
+
return _currentSession !== null && !_isExecuting && status !== 'awaiting_input';
|
|
121
|
+
}
|
|
106
122
|
/**
|
|
107
123
|
* Get message count
|
|
108
124
|
*/
|
|
@@ -204,6 +220,23 @@ export function getHasChatInput() {
|
|
|
204
220
|
export function getSessionCount() {
|
|
205
221
|
return _sessions.length;
|
|
206
222
|
}
|
|
223
|
+
export function getPinnedExecutionId() {
|
|
224
|
+
return _pinnedExecutionId;
|
|
225
|
+
}
|
|
226
|
+
export function getLatestExecutionId() {
|
|
227
|
+
return _latestExecutionId;
|
|
228
|
+
}
|
|
229
|
+
export function getActiveExecutionId() {
|
|
230
|
+
return _activeExecutionId;
|
|
231
|
+
}
|
|
232
|
+
/**
|
|
233
|
+
* Counter that increments whenever new messages arrive and the pipeline display
|
|
234
|
+
* should re-fetch — i.e. when following latest or pinned to the latest execution.
|
|
235
|
+
* Pass to PipelinePanel's refreshTrigger prop.
|
|
236
|
+
*/
|
|
237
|
+
export function getPipelineRefreshTrigger() {
|
|
238
|
+
return _pipelineRefreshTrigger;
|
|
239
|
+
}
|
|
207
240
|
// =========================================================================
|
|
208
241
|
// Helper Functions
|
|
209
242
|
// =========================================================================
|
|
@@ -238,6 +271,34 @@ function sortMessagesChronologically(messageList) {
|
|
|
238
271
|
return a.id.localeCompare(b.id);
|
|
239
272
|
});
|
|
240
273
|
}
|
|
274
|
+
/**
|
|
275
|
+
* Syncs the current session's executions list from incoming messages.
|
|
276
|
+
* When a message has a new executionId not yet tracked, adds it as a new execution entry.
|
|
277
|
+
*/
|
|
278
|
+
function syncExecutionsFromMessages(messages) {
|
|
279
|
+
if (!_currentSession)
|
|
280
|
+
return;
|
|
281
|
+
const existingIds = new Set((_currentSession.executions ?? []).map((e) => e.id));
|
|
282
|
+
const newExecutions = [];
|
|
283
|
+
for (const msg of messages) {
|
|
284
|
+
if (msg.executionId && !existingIds.has(msg.executionId)) {
|
|
285
|
+
existingIds.add(msg.executionId);
|
|
286
|
+
newExecutions.push({
|
|
287
|
+
id: msg.executionId,
|
|
288
|
+
startedAt: msg.timestamp,
|
|
289
|
+
status: 'running'
|
|
290
|
+
});
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
if (newExecutions.length > 0) {
|
|
294
|
+
_currentSession = {
|
|
295
|
+
..._currentSession,
|
|
296
|
+
executions: [...(_currentSession.executions ?? []), ...newExecutions]
|
|
297
|
+
};
|
|
298
|
+
// Clear any manual pin so the panel automatically follows the new run.
|
|
299
|
+
_pinnedExecutionId = null;
|
|
300
|
+
}
|
|
301
|
+
}
|
|
241
302
|
// =========================================================================
|
|
242
303
|
// Actions
|
|
243
304
|
// =========================================================================
|
|
@@ -259,6 +320,7 @@ export const playgroundActions = {
|
|
|
259
320
|
* @param session - The session to set as active
|
|
260
321
|
*/
|
|
261
322
|
setCurrentSession: (session) => {
|
|
323
|
+
_pinnedExecutionId = null;
|
|
262
324
|
_currentSession = session;
|
|
263
325
|
if (session) {
|
|
264
326
|
// Update session in the list
|
|
@@ -278,6 +340,20 @@ export const playgroundActions = {
|
|
|
278
340
|
updatedAt: new Date().toISOString()
|
|
279
341
|
};
|
|
280
342
|
}
|
|
343
|
+
// Update the latest execution status when the session reaches a terminal state.
|
|
344
|
+
// Only the last execution can be running at any time (sessions are single-pipeline),
|
|
345
|
+
// so we only need to check and update the tail entry.
|
|
346
|
+
// 'idle' means the run finished normally (server returns 'idle' post-completion,
|
|
347
|
+
// not 'completed'), so map it to 'completed' for the execution entry.
|
|
348
|
+
const terminalExecutionStatus = status === 'failed' ? 'failed' : status === 'completed' || status === 'idle' ? 'completed' : null;
|
|
349
|
+
if (terminalExecutionStatus && _currentSession?.executions?.length) {
|
|
350
|
+
const execs = [..._currentSession.executions];
|
|
351
|
+
const last = execs[execs.length - 1];
|
|
352
|
+
if (last.status === 'running') {
|
|
353
|
+
execs[execs.length - 1] = { ...last, status: terminalExecutionStatus };
|
|
354
|
+
_currentSession = { ..._currentSession, executions: execs };
|
|
355
|
+
}
|
|
356
|
+
}
|
|
281
357
|
// Also update in sessions list
|
|
282
358
|
const session = _currentSession;
|
|
283
359
|
if (session) {
|
|
@@ -349,26 +425,27 @@ export const playgroundActions = {
|
|
|
349
425
|
addMessages: (newMessages) => {
|
|
350
426
|
if (newMessages.length === 0)
|
|
351
427
|
return;
|
|
352
|
-
// Deduplicate
|
|
428
|
+
// Deduplicate against existing messages AND within the incoming batch itself.
|
|
429
|
+
// The latter matters when the backend returns the same page twice (e.g. broken
|
|
430
|
+
// offset pagination), which would otherwise create duplicate IDs in _messages
|
|
431
|
+
// and trigger Svelte's each_key_duplicate error.
|
|
353
432
|
const existingIds = new Set(_messages.map((m) => m.id));
|
|
354
|
-
const
|
|
355
|
-
|
|
433
|
+
const seenInBatch = new Set();
|
|
434
|
+
const uniqueNewMessages = newMessages.filter((m) => {
|
|
435
|
+
if (existingIds.has(m.id) || seenInBatch.has(m.id))
|
|
436
|
+
return false;
|
|
437
|
+
seenInBatch.add(m.id);
|
|
438
|
+
return true;
|
|
439
|
+
});
|
|
356
440
|
_messages = sortMessagesChronologically([..._messages, ...uniqueNewMessages]);
|
|
441
|
+
syncExecutionsFromMessages(uniqueNewMessages);
|
|
357
442
|
},
|
|
358
443
|
/**
|
|
359
444
|
* Clear all messages
|
|
360
445
|
*/
|
|
361
446
|
clearMessages: () => {
|
|
362
447
|
_messages = [];
|
|
363
|
-
|
|
364
|
-
},
|
|
365
|
-
/**
|
|
366
|
-
* Set the executing state
|
|
367
|
-
*
|
|
368
|
-
* @param executing - Whether execution is in progress
|
|
369
|
-
*/
|
|
370
|
-
setExecuting: (executing) => {
|
|
371
|
-
_isExecuting = executing;
|
|
448
|
+
_lastPollSequenceNumber = null;
|
|
372
449
|
},
|
|
373
450
|
/**
|
|
374
451
|
* Set the loading state
|
|
@@ -391,8 +468,8 @@ export const playgroundActions = {
|
|
|
391
468
|
*
|
|
392
469
|
* @param timestamp - ISO 8601 timestamp
|
|
393
470
|
*/
|
|
394
|
-
|
|
395
|
-
|
|
471
|
+
updateLastPollSequenceNumber: (seq) => {
|
|
472
|
+
_lastPollSequenceNumber = seq;
|
|
396
473
|
},
|
|
397
474
|
/**
|
|
398
475
|
* Reset all playground state
|
|
@@ -401,11 +478,11 @@ export const playgroundActions = {
|
|
|
401
478
|
_currentSession = null;
|
|
402
479
|
_sessions = [];
|
|
403
480
|
_messages = [];
|
|
404
|
-
_isExecuting = false;
|
|
405
481
|
_isLoading = false;
|
|
406
482
|
_error = null;
|
|
407
483
|
_currentWorkflow = null;
|
|
408
|
-
|
|
484
|
+
_lastPollSequenceNumber = null;
|
|
485
|
+
_pipelineRefreshTrigger = 0;
|
|
409
486
|
},
|
|
410
487
|
/**
|
|
411
488
|
* Switch to a different session
|
|
@@ -413,37 +490,38 @@ export const playgroundActions = {
|
|
|
413
490
|
* @param sessionId - The session ID to switch to
|
|
414
491
|
*/
|
|
415
492
|
switchSession: (sessionId) => {
|
|
493
|
+
_pinnedExecutionId = null;
|
|
416
494
|
const session = _sessions.find((s) => s.id === sessionId);
|
|
417
495
|
if (session) {
|
|
418
496
|
_currentSession = session;
|
|
419
497
|
_messages = [];
|
|
420
|
-
|
|
498
|
+
_lastPollSequenceNumber = null;
|
|
421
499
|
}
|
|
500
|
+
},
|
|
501
|
+
pinExecution(executionId) {
|
|
502
|
+
_pinnedExecutionId = executionId;
|
|
422
503
|
}
|
|
423
504
|
};
|
|
424
505
|
// =========================================================================
|
|
425
|
-
//
|
|
506
|
+
// Server Response Application
|
|
426
507
|
// =========================================================================
|
|
427
508
|
/**
|
|
428
|
-
*
|
|
429
|
-
*
|
|
430
|
-
*
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
if (
|
|
438
|
-
|
|
439
|
-
}
|
|
440
|
-
if (response.sessionStatus) {
|
|
441
|
-
playgroundActions.updateSessionStatus(response.sessionStatus);
|
|
442
|
-
if (isTerminalStatus(response.sessionStatus)) {
|
|
443
|
-
playgroundActions.setExecuting(false);
|
|
444
|
-
}
|
|
509
|
+
* Apply a server response to the store. All message and status updates from
|
|
510
|
+
* the server flow through here — polling callback, manual fetches, interrupt
|
|
511
|
+
* resolution. Nothing updates messages or session status except this function.
|
|
512
|
+
*/
|
|
513
|
+
export function applyServerResponse(response) {
|
|
514
|
+
if (response.data && response.data.length > 0) {
|
|
515
|
+
playgroundActions.addMessages(response.data);
|
|
516
|
+
// Refresh pipeline when following latest or pinned to the latest execution.
|
|
517
|
+
// Skip only when the user is viewing a historical run.
|
|
518
|
+
if (_pinnedExecutionId === null || _pinnedExecutionId === _latestExecutionId) {
|
|
519
|
+
_pipelineRefreshTrigger++;
|
|
445
520
|
}
|
|
446
|
-
}
|
|
521
|
+
}
|
|
522
|
+
if (response.sessionStatus) {
|
|
523
|
+
playgroundActions.updateSessionStatus(response.sessionStatus);
|
|
524
|
+
}
|
|
447
525
|
}
|
|
448
526
|
// =========================================================================
|
|
449
527
|
// Utilities
|
|
@@ -474,14 +552,17 @@ export function getMessagesSnapshot() {
|
|
|
474
552
|
return _messages;
|
|
475
553
|
}
|
|
476
554
|
/**
|
|
477
|
-
* Get the latest message
|
|
555
|
+
* Get the sequence number of the latest message, used to seed incremental polling.
|
|
478
556
|
*
|
|
479
|
-
* @returns
|
|
557
|
+
* @returns Sequence number of the last message, or null
|
|
480
558
|
*/
|
|
481
|
-
export function
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
559
|
+
export function getLatestSequenceNumber() {
|
|
560
|
+
for (let i = _messages.length - 1; i >= 0; i--) {
|
|
561
|
+
if (_messages[i].sequenceNumber !== undefined) {
|
|
562
|
+
return _messages[i].sequenceNumber;
|
|
563
|
+
}
|
|
564
|
+
}
|
|
565
|
+
return null;
|
|
485
566
|
}
|
|
486
567
|
/**
|
|
487
568
|
* Subscribe to session status changes using $effect.root.
|
|
@@ -510,17 +591,15 @@ export function subscribeToSessionStatus(callback) {
|
|
|
510
591
|
* has stopped but new messages may exist on the server.
|
|
511
592
|
*
|
|
512
593
|
* @param fetchMessages - Async function to fetch messages from the API
|
|
513
|
-
* @param isTerminalStatus - Optional override for terminal status check
|
|
514
594
|
* @returns Promise that resolves when messages are refreshed
|
|
515
595
|
*/
|
|
516
|
-
export async function refreshSessionMessages(fetchMessages
|
|
596
|
+
export async function refreshSessionMessages(fetchMessages) {
|
|
517
597
|
const session = _currentSession;
|
|
518
598
|
if (!session)
|
|
519
599
|
return;
|
|
520
600
|
try {
|
|
521
601
|
const response = await fetchMessages(session.id);
|
|
522
|
-
|
|
523
|
-
callback(response);
|
|
602
|
+
applyServerResponse(response);
|
|
524
603
|
}
|
|
525
604
|
catch (err) {
|
|
526
605
|
logger.error('[playgroundStore] Failed to refresh messages:', err);
|
package/dist/svelte-app.js
CHANGED
|
@@ -188,14 +188,37 @@ export async function mountFlowDropApp(container, options = {}) {
|
|
|
188
188
|
isDirty: () => isDirty(),
|
|
189
189
|
markAsSaved: () => {
|
|
190
190
|
markAsSaved();
|
|
191
|
-
// Also update draft manager
|
|
192
191
|
if (state.draftManager) {
|
|
192
|
+
// Migrate the draft key when the host confirms a save. New workflows start
|
|
193
|
+
// on 'flowdrop:draft:new', a key shared across all tabs. If the host has
|
|
194
|
+
// written the server-assigned ID back into the store before calling
|
|
195
|
+
// markAsSaved(), we can move to a unique per-workflow key and stop
|
|
196
|
+
// competing with other tabs that may also have unsaved new workflows.
|
|
197
|
+
// Skip when customDraftKey is set — the host manages that key explicitly.
|
|
198
|
+
if (!customDraftKey) {
|
|
199
|
+
const currentWorkflow = getWorkflowFromStore();
|
|
200
|
+
if (currentWorkflow?.id) {
|
|
201
|
+
state.draftManager.updateStorageKey(getDraftStorageKey(currentWorkflow.id));
|
|
202
|
+
}
|
|
203
|
+
}
|
|
193
204
|
state.draftManager.markAsSaved();
|
|
194
205
|
}
|
|
195
206
|
},
|
|
196
207
|
getWorkflow: () => getWorkflowFromStore(),
|
|
197
208
|
save: async () => {
|
|
198
|
-
await globalSaveWorkflow(
|
|
209
|
+
await globalSaveWorkflow({
|
|
210
|
+
onSaved: (saved) => {
|
|
211
|
+
// globalSaveWorkflow does not write the server-assigned ID back to the
|
|
212
|
+
// workflow store, so we cannot read it from getWorkflowFromStore() here.
|
|
213
|
+
// Instead we use the savedWorkflow returned by the API directly.
|
|
214
|
+
// This migrates 'flowdrop:draft:new' to a unique per-workflow key
|
|
215
|
+
// immediately after the first save, preventing cross-tab collisions
|
|
216
|
+
// when multiple new workflows are open simultaneously.
|
|
217
|
+
if (state.draftManager && !customDraftKey && saved.id) {
|
|
218
|
+
state.draftManager.updateStorageKey(getDraftStorageKey(saved.id));
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
});
|
|
199
222
|
},
|
|
200
223
|
export: () => {
|
|
201
224
|
globalExportWorkflow();
|
|
@@ -52,6 +52,14 @@ export type PlaygroundMessageLevel = 'info' | 'warning' | 'error' | 'debug';
|
|
|
52
52
|
* Status of a playground message
|
|
53
53
|
*/
|
|
54
54
|
export type PlaygroundMessageStatus = 'pending' | 'processing' | 'completed' | 'failed';
|
|
55
|
+
/**
|
|
56
|
+
* A single pipeline execution associated with a playground session
|
|
57
|
+
*/
|
|
58
|
+
export interface PlaygroundExecution {
|
|
59
|
+
id: string;
|
|
60
|
+
startedAt: string;
|
|
61
|
+
status: 'running' | 'completed' | 'failed';
|
|
62
|
+
}
|
|
55
63
|
/**
|
|
56
64
|
* Playground session representing a test conversation
|
|
57
65
|
*
|
|
@@ -83,6 +91,8 @@ export interface PlaygroundSession {
|
|
|
83
91
|
createdAt: string;
|
|
84
92
|
/** Last activity timestamp (ISO 8601) */
|
|
85
93
|
updatedAt: string;
|
|
94
|
+
/** Pipeline executions triggered within this session, ordered oldest-first */
|
|
95
|
+
executions?: PlaygroundExecution[];
|
|
86
96
|
/** Custom session metadata */
|
|
87
97
|
metadata?: Record<string, unknown>;
|
|
88
98
|
}
|
|
@@ -100,6 +110,8 @@ export interface PlaygroundMessageMetadata {
|
|
|
100
110
|
outputs?: Record<string, unknown>;
|
|
101
111
|
/** User's display name for user-role messages (from backend) */
|
|
102
112
|
userName?: string;
|
|
113
|
+
/** Subsystem that produced this message (e.g. 'pipeline', 'job', 'queue', 'cron') */
|
|
114
|
+
source?: string;
|
|
103
115
|
/** Allow additional properties */
|
|
104
116
|
[key: string]: unknown;
|
|
105
117
|
}
|
|
@@ -136,14 +148,12 @@ export interface PlaygroundMessage {
|
|
|
136
148
|
timestamp: string;
|
|
137
149
|
/** Message status */
|
|
138
150
|
status?: PlaygroundMessageStatus;
|
|
139
|
-
/**
|
|
140
|
-
* Sequence number for ordering messages
|
|
141
|
-
* - User messages: incrementing numbers (1, 2, 3, ...)
|
|
142
|
-
* - Assistant/system responses: 0 (sorted after parent via parentMessageId)
|
|
143
|
-
*/
|
|
151
|
+
/** Incrementing sequence number for chronological ordering. All message roles receive unique incrementing numbers (1, 2, 3, ...). Primary sort key. */
|
|
144
152
|
sequenceNumber?: number;
|
|
145
153
|
/** Parent message ID (for assistant responses linked to user messages) */
|
|
146
154
|
parentMessageId?: string;
|
|
155
|
+
/** Pipeline/execution ID that generated this message */
|
|
156
|
+
executionId?: string | null;
|
|
147
157
|
/** Associated node ID (for log/assistant messages) */
|
|
148
158
|
nodeId?: string | null;
|
|
149
159
|
/** Additional message metadata */
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"description": "A drop-in visual workflow editor for any web application. You own the backend. You own the data. You own the orchestration.",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"private": false,
|
|
6
|
-
"version": "1.
|
|
6
|
+
"version": "1.10.0",
|
|
7
7
|
"author": "Shibin Das (D34dMan)",
|
|
8
8
|
"bugs": {
|
|
9
9
|
"url": "https://github.com/flowdrop-io/flowdrop/issues"
|