@burdenoff/fluidgrids-fe-sdk 2026.1022.5 → 2026.1022.7

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.
@@ -0,0 +1,476 @@
1
+ import { REPLAY_WORKFLOW_RUN, RETRY_WORKFLOW_RUNS } from './chunk-QBFAJNUC.js';
2
+ import { useExecutionsStore } from './chunk-UZG3ZIQM.js';
3
+ import { ExecutionsListDocument, ExecutionDetailDocument, ExecutionStatsDocument, PauseExecutionDocument, ResumeExecutionDocument, CancelExecutionDocument, RetryNodeDocument, TriggerWorkflowDocument, TerminateExecutionDocument } from './chunk-SAZVBFMO.js';
4
+ import { throwIfResultError, openRunQuotaUpgradePrompt } from './chunk-4UAWCWS7.js';
5
+ import { useTr } from './chunk-UULVIT25.js';
6
+ import { getFluidGridsClient } from './chunk-NTWG3CJX.js';
7
+ import { useState, useRef, useCallback, useEffect, useMemo } from 'react';
8
+ import { gql } from '@apollo/client';
9
+
10
+ gql`
11
+ subscription NodeStateUpdated($runId: String!) {
12
+ _empty
13
+ }
14
+ `;
15
+ gql`
16
+ subscription WorkflowCompleted($runId: String!) {
17
+ _empty
18
+ }
19
+ `;
20
+ gql`
21
+ subscription WorkflowError($runId: String!) {
22
+ _empty
23
+ }
24
+ `;
25
+ gql`
26
+ subscription ExecutionUpdated($runId: String!) {
27
+ _empty
28
+ }
29
+ `;
30
+ gql`
31
+ subscription ExecutionNodeStateUpdated($runId: String!) {
32
+ _empty
33
+ }
34
+ `;
35
+ gql`
36
+ subscription ExecutionCompleted($runId: String!) {
37
+ _empty
38
+ }
39
+ `;
40
+ gql`
41
+ subscription ExecutionError($runId: String!) {
42
+ _empty
43
+ }
44
+ `;
45
+
46
+ // src/modules/executions/utils/date-range.ts
47
+ function toDate(value) {
48
+ if (value === null || value === void 0 || value === "") return null;
49
+ const date = value instanceof Date ? value : new Date(value);
50
+ return Number.isNaN(date.getTime()) ? null : date;
51
+ }
52
+ function validateDateRange(start, end, preset) {
53
+ const startDate = toDate(start);
54
+ const endDate = toDate(end);
55
+ if (startDate && endDate && startDate.getTime() > endDate.getTime()) {
56
+ return { valid: false, start: null, end: null, preset: preset ?? "all" };
57
+ }
58
+ return {
59
+ valid: true,
60
+ start: startDate,
61
+ end: endDate,
62
+ preset: preset ?? "all"
63
+ };
64
+ }
65
+ function dateRangeToInput(start, end) {
66
+ const {
67
+ valid,
68
+ start: validatedStart,
69
+ end: validatedEnd
70
+ } = validateDateRange(start, end);
71
+ if (!valid) return {};
72
+ const input = {};
73
+ if (validatedStart) input.startDate = validatedStart.toISOString();
74
+ if (validatedEnd) input.endDate = validatedEnd.toISOString();
75
+ return input;
76
+ }
77
+
78
+ // src/modules/executions/utils/retry.ts
79
+ var NON_REPLAYABLE_CONTEXT_KEYS = ["isScheduled", "workspaceId"];
80
+ function buildRetryTriggerInput(run) {
81
+ if (!run.workflowKey || !run.version || !run.triggerNodeId) return null;
82
+ const context = {};
83
+ const original = run.context;
84
+ if (original && typeof original === "object" && !Array.isArray(original)) {
85
+ for (const [key, value] of Object.entries(
86
+ original
87
+ )) {
88
+ if (NON_REPLAYABLE_CONTEXT_KEYS.includes(key)) {
89
+ continue;
90
+ }
91
+ context[key] = value;
92
+ }
93
+ }
94
+ context.retryOfRunId = run.id;
95
+ return {
96
+ workflowKey: run.workflowKey,
97
+ version: run.version,
98
+ triggerNodeId: run.triggerNodeId,
99
+ triggerData: run.triggerData ?? void 0,
100
+ context
101
+ };
102
+ }
103
+
104
+ // src/modules/executions/hooks/useExecutions.ts
105
+ function useExecutions(input = {}) {
106
+ const [executions, setExecutions] = useState([]);
107
+ const [total, setTotal] = useState(0);
108
+ const [hasMore, setHasMore] = useState(false);
109
+ const [loading, setLoading] = useState(true);
110
+ const [error, setError] = useState(null);
111
+ const inputKey = JSON.stringify(input);
112
+ const reqIdRef = useRef(0);
113
+ const fetchData = useCallback(async () => {
114
+ const reqId = ++reqIdRef.current;
115
+ setLoading(true);
116
+ setError(null);
117
+ try {
118
+ const client = getFluidGridsClient();
119
+ const result = await client.query({
120
+ query: ExecutionsListDocument,
121
+ variables: { input: JSON.parse(inputKey) },
122
+ fetchPolicy: "network-only"
123
+ });
124
+ if (reqId !== reqIdRef.current) return;
125
+ setExecutions(result.data?.workflowRuns?.items ?? []);
126
+ setTotal(result.data?.workflowRuns?.total ?? 0);
127
+ setHasMore(result.data?.workflowRuns?.hasMore ?? false);
128
+ } catch (err) {
129
+ if (reqId !== reqIdRef.current) return;
130
+ setError(err);
131
+ } finally {
132
+ if (reqId === reqIdRef.current) setLoading(false);
133
+ }
134
+ }, [inputKey]);
135
+ useEffect(() => {
136
+ fetchData();
137
+ }, [fetchData]);
138
+ return {
139
+ executions,
140
+ total,
141
+ hasMore,
142
+ loading,
143
+ error,
144
+ refetch: fetchData
145
+ };
146
+ }
147
+ function useExecution(id) {
148
+ const [execution, setExecution] = useState(null);
149
+ const [loading, setLoading] = useState(true);
150
+ const [error, setError] = useState(null);
151
+ const fetchData = useCallback(async () => {
152
+ if (!id) {
153
+ setLoading(false);
154
+ return;
155
+ }
156
+ setLoading(true);
157
+ setError(null);
158
+ try {
159
+ const client = getFluidGridsClient();
160
+ const result = await client.query({
161
+ query: ExecutionDetailDocument,
162
+ variables: { id },
163
+ fetchPolicy: "network-only"
164
+ });
165
+ setExecution(result.data?.workflowRun ?? null);
166
+ } catch (err) {
167
+ setError(err);
168
+ } finally {
169
+ setLoading(false);
170
+ }
171
+ }, [id]);
172
+ useEffect(() => {
173
+ fetchData();
174
+ }, [fetchData]);
175
+ return {
176
+ execution,
177
+ loading,
178
+ error,
179
+ refetch: fetchData
180
+ };
181
+ }
182
+ function useExecutionStats(options = {}) {
183
+ const [stats, setStats] = useState(null);
184
+ const [loading, setLoading] = useState(true);
185
+ const [error, setError] = useState(null);
186
+ const optionsKey = JSON.stringify(options);
187
+ const fetchData = useCallback(async () => {
188
+ setLoading(true);
189
+ setError(null);
190
+ try {
191
+ const client = getFluidGridsClient();
192
+ const result = await client.query({
193
+ query: ExecutionStatsDocument,
194
+ variables: JSON.parse(optionsKey),
195
+ fetchPolicy: "network-only"
196
+ });
197
+ setStats(result.data?.dashboardSummary ?? null);
198
+ } catch (err) {
199
+ setError(err);
200
+ } finally {
201
+ setLoading(false);
202
+ }
203
+ }, [optionsKey]);
204
+ useEffect(() => {
205
+ fetchData();
206
+ }, [fetchData]);
207
+ return {
208
+ stats,
209
+ loading,
210
+ error,
211
+ refetch: fetchData
212
+ };
213
+ }
214
+ function useExecutionActions() {
215
+ const tr = useTr();
216
+ const [loading, setLoading] = useState(false);
217
+ const [error, setError] = useState(null);
218
+ const pauseExecution = useCallback(async (id) => {
219
+ setLoading(true);
220
+ setError(null);
221
+ try {
222
+ const client = getFluidGridsClient();
223
+ const result = throwIfResultError(
224
+ await client.mutate({
225
+ mutation: PauseExecutionDocument,
226
+ variables: { id }
227
+ })
228
+ );
229
+ return result.data?.pauseWorkflowRun ?? null;
230
+ } catch (err) {
231
+ setError(err);
232
+ return null;
233
+ } finally {
234
+ setLoading(false);
235
+ }
236
+ }, []);
237
+ const resumeExecution = useCallback(async (id) => {
238
+ setLoading(true);
239
+ setError(null);
240
+ try {
241
+ const client = getFluidGridsClient();
242
+ const result = throwIfResultError(
243
+ await client.mutate({
244
+ mutation: ResumeExecutionDocument,
245
+ variables: { id }
246
+ })
247
+ );
248
+ return result.data?.resumeWorkflowRun ?? null;
249
+ } catch (err) {
250
+ setError(err);
251
+ return null;
252
+ } finally {
253
+ setLoading(false);
254
+ }
255
+ }, []);
256
+ const cancelExecution = useCallback(async (id) => {
257
+ setLoading(true);
258
+ setError(null);
259
+ try {
260
+ const client = getFluidGridsClient();
261
+ const result = throwIfResultError(
262
+ await client.mutate({
263
+ mutation: CancelExecutionDocument,
264
+ variables: { id }
265
+ })
266
+ );
267
+ return result.data?.cancelWorkflowRun ?? null;
268
+ } catch (err) {
269
+ setError(err);
270
+ return null;
271
+ } finally {
272
+ setLoading(false);
273
+ }
274
+ }, []);
275
+ const retryNode = useCallback(async (runId, nodeId) => {
276
+ setLoading(true);
277
+ setError(null);
278
+ try {
279
+ const client = getFluidGridsClient();
280
+ const result = throwIfResultError(
281
+ await client.mutate({
282
+ mutation: RetryNodeDocument,
283
+ variables: { id: runId, nodeId }
284
+ })
285
+ );
286
+ return result.data?.retryNode ?? null;
287
+ } catch (err) {
288
+ setError(err);
289
+ return null;
290
+ } finally {
291
+ setLoading(false);
292
+ }
293
+ }, []);
294
+ const retryExecution = useCallback(
295
+ async (execution) => {
296
+ const input = buildRetryTriggerInput(execution);
297
+ if (!input) {
298
+ const message = "This run has no trigger node, so it cannot be re-run.";
299
+ setError(new Error(message));
300
+ return { ok: false, message };
301
+ }
302
+ setLoading(true);
303
+ setError(null);
304
+ try {
305
+ const client = getFluidGridsClient();
306
+ const result = throwIfResultError(
307
+ await client.mutate({
308
+ mutation: TriggerWorkflowDocument,
309
+ variables: { input }
310
+ })
311
+ );
312
+ const run = result.data?.triggerWorkflow;
313
+ if (!run) {
314
+ const message = "The workflow did not start.";
315
+ setError(new Error(message));
316
+ return { ok: false, message };
317
+ }
318
+ return { ok: true, run };
319
+ } catch (err) {
320
+ const error2 = err;
321
+ setError(error2);
322
+ openRunQuotaUpgradePrompt(err, tr);
323
+ return { ok: false, message: error2.message };
324
+ } finally {
325
+ setLoading(false);
326
+ }
327
+ },
328
+ [tr]
329
+ );
330
+ const replayExecution = useCallback(
331
+ async (runId) => {
332
+ setLoading(true);
333
+ setError(null);
334
+ try {
335
+ const client = getFluidGridsClient();
336
+ const result = throwIfResultError(
337
+ await client.mutate({
338
+ mutation: REPLAY_WORKFLOW_RUN,
339
+ variables: { runId }
340
+ })
341
+ );
342
+ return result.data?.replayWorkflowRun ?? null;
343
+ } catch (err) {
344
+ setError(err);
345
+ openRunQuotaUpgradePrompt(err, tr);
346
+ return null;
347
+ } finally {
348
+ setLoading(false);
349
+ }
350
+ },
351
+ [tr]
352
+ );
353
+ const retryExecutions = useCallback(
354
+ async (runIds) => {
355
+ setLoading(true);
356
+ setError(null);
357
+ try {
358
+ const client = getFluidGridsClient();
359
+ const result = throwIfResultError(
360
+ await client.mutate({
361
+ mutation: RETRY_WORKFLOW_RUNS,
362
+ variables: { runIds }
363
+ })
364
+ );
365
+ return result.data?.retryWorkflowRuns ?? [];
366
+ } catch (err) {
367
+ setError(err);
368
+ openRunQuotaUpgradePrompt(err, tr);
369
+ return [];
370
+ } finally {
371
+ setLoading(false);
372
+ }
373
+ },
374
+ [tr]
375
+ );
376
+ const terminateExecution = useCallback(
377
+ async (runId, reason) => {
378
+ setLoading(true);
379
+ setError(null);
380
+ try {
381
+ const client = getFluidGridsClient();
382
+ const result = throwIfResultError(
383
+ await client.mutate({
384
+ mutation: TerminateExecutionDocument,
385
+ variables: { runId, reason }
386
+ })
387
+ );
388
+ return result.data?.terminateWorkflow ?? null;
389
+ } catch (err) {
390
+ setError(err);
391
+ return null;
392
+ } finally {
393
+ setLoading(false);
394
+ }
395
+ },
396
+ []
397
+ );
398
+ return {
399
+ pauseExecution,
400
+ resumeExecution,
401
+ cancelExecution,
402
+ retryNode,
403
+ retryExecution,
404
+ replayExecution,
405
+ retryExecutions,
406
+ terminateExecution,
407
+ loading,
408
+ error
409
+ };
410
+ }
411
+ var EXECUTIONS_SEARCH_DEBOUNCE_MS = 350;
412
+ function useExecutionsWithStore() {
413
+ const { filter, pagination, setTotal } = useExecutionsStore();
414
+ const [debouncedSearch, setDebouncedSearch] = useState(filter.search);
415
+ useEffect(() => {
416
+ const timer = setTimeout(
417
+ () => setDebouncedSearch(filter.search),
418
+ EXECUTIONS_SEARCH_DEBOUNCE_MS
419
+ );
420
+ return () => clearTimeout(timer);
421
+ }, [filter.search]);
422
+ const input = useMemo(() => {
423
+ const baseInput = {
424
+ limit: pagination.pageSize,
425
+ offset: (pagination.page - 1) * pagination.pageSize
426
+ };
427
+ if (filter.status !== "all") {
428
+ baseInput.status = filter.status;
429
+ }
430
+ if (filter.workflowKey) {
431
+ baseInput.workflowKey = filter.workflowKey;
432
+ }
433
+ Object.assign(
434
+ baseInput,
435
+ dateRangeToInput(filter.dateRange.start, filter.dateRange.end)
436
+ );
437
+ const term = debouncedSearch.trim();
438
+ if (term) {
439
+ baseInput.search = term;
440
+ }
441
+ if (filter.triggerType !== "all") {
442
+ baseInput.triggerType = filter.triggerType;
443
+ }
444
+ if (filter.durationMinSeconds !== null) {
445
+ baseInput.durationMinSeconds = filter.durationMinSeconds;
446
+ }
447
+ if (filter.durationMaxSeconds !== null) {
448
+ baseInput.durationMaxSeconds = filter.durationMaxSeconds;
449
+ }
450
+ if (filter.errorType !== "all") {
451
+ baseInput.errorType = filter.errorType;
452
+ }
453
+ if (filter.nodeId.trim()) {
454
+ baseInput.nodeId = filter.nodeId.trim();
455
+ }
456
+ return baseInput;
457
+ }, [filter, debouncedSearch, pagination.page, pagination.pageSize]);
458
+ const result = useExecutions(input);
459
+ useEffect(() => {
460
+ if (result.total !== pagination.total) {
461
+ setTotal(result.total);
462
+ }
463
+ }, [result.total, pagination.total, setTotal]);
464
+ return result;
465
+ }
466
+ function useAutoRefresh(refetchFn, enabled = true, interval = 5e3) {
467
+ useEffect(() => {
468
+ if (!enabled) return;
469
+ const timer = setInterval(() => {
470
+ refetchFn();
471
+ }, interval);
472
+ return () => clearInterval(timer);
473
+ }, [enabled, interval, refetchFn]);
474
+ }
475
+
476
+ export { useAutoRefresh, useExecution, useExecutionActions, useExecutionStats, useExecutions, useExecutionsWithStore, validateDateRange };
@@ -1,4 +1,5 @@
1
- import { useExecution, buildNodeDisplayMap, useExecutionActions, useAutoRefresh, ExecutionStatusBadge, formatRunVersion, NodeTimeline, RunLogViewer } from './chunk-HIXQIM22.js';
1
+ import { buildNodeDisplayMap, ExecutionStatusBadge, formatRunVersion, NodeTimeline, RunLogViewer } from './chunk-CV56O5R4.js';
2
+ import { useExecution, useExecutionActions, useAutoRefresh } from './chunk-VGIH3SOT.js';
2
3
  import { useFluidGridsPermission, FLUIDGRIDS_PERMISSIONS } from './chunk-ONVGFVNH.js';
3
4
  import { getFluidGridsConfig } from './chunk-UZG3ZIQM.js';
4
5
  import { RunLogsDocument, RunLogAppendedDocument } from './chunk-SAZVBFMO.js';
@@ -0,0 +1,64 @@
1
+ // src/utils/workflow-open.ts
2
+ var NEW_WORKFLOW_STATE = { createWorkflow: true };
3
+ var NEW_WORKFLOW_NAV = { state: NEW_WORKFLOW_STATE };
4
+ function isCreateIntent(state) {
5
+ return typeof state === "object" && state !== null && state.createWorkflow === true;
6
+ }
7
+ function decideMissingWorkflow(input) {
8
+ if (input.otherVersionExists) return "open-newest";
9
+ return input.createIntent ? "create" : "not-found";
10
+ }
11
+
12
+ // src/onboarding/firstWorkflow.ts
13
+ var GUIDED_FIRST_WORKFLOW_STATE = {
14
+ ...NEW_WORKFLOW_STATE,
15
+ guidedTour: true
16
+ };
17
+ var GUIDED_FIRST_WORKFLOW_NAV = {
18
+ state: GUIDED_FIRST_WORKFLOW_STATE
19
+ };
20
+ function isGuidedTourIntent(state) {
21
+ return typeof state === "object" && state !== null && state.guidedTour === true;
22
+ }
23
+ function withoutGuidedTourIntent(state) {
24
+ if (typeof state !== "object" || state === null) return state;
25
+ if (!("guidedTour" in state)) return state;
26
+ const rest = {};
27
+ for (const [key, value] of Object.entries(state)) {
28
+ if (key !== "guidedTour") rest[key] = value;
29
+ }
30
+ return Object.keys(rest).length > 0 ? rest : null;
31
+ }
32
+ function byMostRecent(a, b) {
33
+ const at = a.updatedAt ? Date.parse(a.updatedAt) : 0;
34
+ const bt = b.updatedAt ? Date.parse(b.updatedAt) : 0;
35
+ return (Number.isNaN(bt) ? 0 : bt) - (Number.isNaN(at) ? 0 : at);
36
+ }
37
+ function firstWorkflowProgress(workflows, runsTotal) {
38
+ const created = workflows.length > 0;
39
+ const ran = runsTotal !== null && runsTotal > 0;
40
+ const activated = workflows.some((w) => w.status === "ACTIVE");
41
+ const ordered = [...workflows].sort(byMostRecent);
42
+ const runTarget = ordered[0] ?? null;
43
+ const activateTarget = ordered.find((w) => (w.status ?? "DRAFT") === "DRAFT") ?? runTarget;
44
+ const remaining = [created, ran, activated].filter((done) => !done).length;
45
+ return {
46
+ created,
47
+ ran,
48
+ activated,
49
+ complete: remaining === 0,
50
+ remaining,
51
+ runTarget,
52
+ activateTarget
53
+ };
54
+ }
55
+ function builderPathFor(workflow) {
56
+ return `../workflow/${encodeURIComponent(workflow.workflowKey)}/${encodeURIComponent(workflow.version)}`;
57
+ }
58
+ function pickGuidedTour(pageTours, pageId) {
59
+ const playable = pageTours.filter((tour) => (tour.steps?.length ?? 0) > 0).sort((a, b) => (b.priority ?? 0) - (a.priority ?? 0));
60
+ if (!pageId) return null;
61
+ return playable.find((tour) => tour.pageId === pageId) ?? null;
62
+ }
63
+
64
+ export { GUIDED_FIRST_WORKFLOW_NAV, GUIDED_FIRST_WORKFLOW_STATE, NEW_WORKFLOW_NAV, builderPathFor, decideMissingWorkflow, firstWorkflowProgress, isCreateIntent, isGuidedTourIntent, pickGuidedTour, withoutGuidedTourIntent };
@@ -1,7 +1,8 @@
1
1
  import './chunk-AD3BXTJS.js';
2
- export { ExecutionsListPage } from './chunk-PG2JFX63.js';
3
- export { ExecutionDetailPage } from './chunk-P3R3RFAC.js';
4
- import './chunk-HIXQIM22.js';
2
+ export { ExecutionsListPage } from './chunk-QMZGUJI3.js';
3
+ export { ExecutionDetailPage } from './chunk-WFZD44CK.js';
4
+ import './chunk-CV56O5R4.js';
5
+ import './chunk-VGIH3SOT.js';
5
6
  import './chunk-QBFAJNUC.js';
6
7
  import './chunk-ONVGFVNH.js';
7
8
  import './chunk-JL7CASN5.js';