@pgflow/client 0.0.0-test-snapshot-releases-8d5d9bc1-20250922101013 → 0.0.0-update-supabase-868977e5-20251119071021

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/index.js ADDED
@@ -0,0 +1,928 @@
1
+ var Q = (s) => {
2
+ throw TypeError(s);
3
+ };
4
+ var O = (s, t, r) => t.has(s) || Q("Cannot " + r);
5
+ var e = (s, t, r) => (O(s, t, "read from private field"), r ? r.call(s) : t.get(s)), d = (s, t, r) => t.has(s) ? Q("Cannot add the same private member more than once") : t instanceof WeakSet ? t.add(s) : t.set(s, r), f = (s, t, r, i) => (O(s, t, "write to private field"), i ? i.call(s, r) : t.set(s, r), r), m = (s, t, r) => (O(s, t, "access private method"), r);
6
+ var H = (s, t, r, i) => ({
7
+ set _(n) {
8
+ f(s, t, n, r);
9
+ },
10
+ get _() {
11
+ return e(s, t, i);
12
+ }
13
+ });
14
+ import { v4 as st } from "uuid";
15
+ import { createNanoEvents as L } from "nanoevents";
16
+ var p = /* @__PURE__ */ ((s) => (s.Started = "started", s.Completed = "completed", s.Failed = "failed", s))(p || {});
17
+ function dt(s) {
18
+ return !!s && typeof s == "object" && "run_id" in s && "flow_slug" in s && !("step_slug" in s) && "status" in s && (s.status === "started" || s.status === "completed" || s.status === "failed");
19
+ }
20
+ function ct(s) {
21
+ return s.status === "started";
22
+ }
23
+ function pt(s) {
24
+ return s.status === "completed";
25
+ }
26
+ function ht(s) {
27
+ return s.status === "failed";
28
+ }
29
+ var h = /* @__PURE__ */ ((s) => (s.Created = "created", s.Started = "started", s.Completed = "completed", s.Failed = "failed", s))(h || {});
30
+ function N(s) {
31
+ return !!s && typeof s == "object" && "run_id" in s && "step_slug" in s && "status" in s && (s.status === "started" || s.status === "completed" || s.status === "failed");
32
+ }
33
+ function ft(s) {
34
+ return N(s) && s.status === "started" && "event_type" in s && s.event_type === "step:started";
35
+ }
36
+ function _t(s) {
37
+ return N(s) && s.status === "completed" && "event_type" in s && s.event_type === "step:completed";
38
+ }
39
+ function mt(s) {
40
+ return N(s) && s.status === "failed" && "event_type" in s && s.event_type === "step:failed";
41
+ }
42
+ var S, C, F, I, W, M, _, j, X, G, Y, Z, v, k, K;
43
+ class rt {
44
+ /**
45
+ * Creates a new instance of SupabaseBroadcastAdapter
46
+ *
47
+ * @param supabase - Supabase client instance
48
+ */
49
+ constructor(t, r = {}) {
50
+ d(this, _);
51
+ d(this, S);
52
+ d(this, C, /* @__PURE__ */ new Map());
53
+ d(this, F, L());
54
+ d(this, I);
55
+ d(this, W);
56
+ d(this, M);
57
+ // Store unsubscribe functions per run ID for reference equality
58
+ d(this, k, /* @__PURE__ */ new Map());
59
+ f(this, S, t), f(this, I, r.reconnectDelayMs ?? 2e3), f(this, W, r.stabilizationDelayMs ?? 300), f(this, M, r.schedule ?? setTimeout);
60
+ }
61
+ /**
62
+ * Fetches flow definition metadata from the database
63
+ *
64
+ * @param flow_slug - Flow slug to fetch
65
+ */
66
+ async fetchFlowDefinition(t) {
67
+ const [r, i] = await Promise.all([
68
+ e(this, S).schema("pgflow").from("flows").select("*").eq("flow_slug", t).single(),
69
+ e(this, S).schema("pgflow").from("steps").select("*").eq("flow_slug", t).order("step_index", { ascending: !0 })
70
+ ]);
71
+ if (r.error) throw r.error;
72
+ if (!r.data) throw new Error(`Flow "${t}" not found`);
73
+ if (i.error) throw i.error;
74
+ const n = Array.isArray(i.data) ? i.data : [];
75
+ return {
76
+ flow: r.data,
77
+ steps: n
78
+ };
79
+ }
80
+ /**
81
+ * Registers a callback for run events
82
+ *
83
+ * @param callback - Function to call when run events are received
84
+ * @returns Function to unsubscribe from the event
85
+ */
86
+ onRunEvent(t) {
87
+ const r = e(this, F).on("runEvent", t);
88
+ return () => {
89
+ try {
90
+ r();
91
+ } catch (i) {
92
+ console.warn("Could not unsubscribe from run event - emitter may have been disposed", i);
93
+ }
94
+ };
95
+ }
96
+ /**
97
+ * Registers a callback for step events
98
+ *
99
+ * @param callback - Function to call when step events are received
100
+ * @returns Function to unsubscribe from the event
101
+ */
102
+ onStepEvent(t) {
103
+ const r = e(this, F).on("stepEvent", t);
104
+ return () => {
105
+ try {
106
+ r();
107
+ } catch (i) {
108
+ console.warn("Could not unsubscribe from step event - emitter may have been disposed", i);
109
+ }
110
+ };
111
+ }
112
+ /**
113
+ * Subscribes to a flow run's events
114
+ *
115
+ * @param run_id - Run ID to subscribe to
116
+ * @returns Function to unsubscribe
117
+ */
118
+ async subscribeToRun(t) {
119
+ const r = `pgflow:run:${t}`;
120
+ if (e(this, C).has(t)) {
121
+ const c = e(this, k).get(t);
122
+ if (c)
123
+ return c;
124
+ m(this, _, K).call(this, t);
125
+ }
126
+ const i = e(this, S).channel(r);
127
+ i.on("broadcast", { event: "*" }, m(this, _, j).bind(this)), i.on("system", { event: "closed" }, () => {
128
+ console.log(`Channel ${r} closed`);
129
+ }), i.on("system", { event: "error" }, (c) => {
130
+ console.log(`Channel ${r} error:`, c), m(this, _, G).call(this, t, r, i, c.error);
131
+ }), console.log(`Subscribing to channel ${r}...`), await new Promise((c, u) => {
132
+ const l = setTimeout(() => {
133
+ u(new Error(`Subscription timeout for channel ${r}`));
134
+ }, 2e4);
135
+ i.subscribe((b) => {
136
+ console.log(`Channel ${r} subscription status:`, b), b === "SUBSCRIBED" && (clearTimeout(l), c());
137
+ });
138
+ }), await new Promise((c) => e(this, M).call(this, c, e(this, W))), e(this, C).set(t, i);
139
+ const g = () => this.unsubscribe(t);
140
+ return e(this, k).set(t, g), g;
141
+ }
142
+ /**
143
+ * Unsubscribes from a run's events
144
+ *
145
+ * @param run_id - Run ID to unsubscribe from
146
+ */
147
+ unsubscribe(t) {
148
+ m(this, _, K).call(this, t);
149
+ }
150
+ /**
151
+ * Fetches current state of a run and its steps
152
+ *
153
+ * @param run_id - Run ID to fetch
154
+ */
155
+ async getRunWithStates(t) {
156
+ const { data: r, error: i } = await e(this, S).schema("pgflow").rpc("get_run_with_states", { run_id: t });
157
+ if (i) throw i;
158
+ if (!r) throw new Error(`No data returned for run ${t}`);
159
+ return r;
160
+ }
161
+ }
162
+ S = new WeakMap(), C = new WeakMap(), F = new WeakMap(), I = new WeakMap(), W = new WeakMap(), M = new WeakMap(), _ = new WeakSet(), /**
163
+ * Handle broadcast messages from Supabase
164
+ * @param payload - The message payload
165
+ */
166
+ j = function(t) {
167
+ const { event: r, payload: i } = t, n = i;
168
+ m(this, _, X).call(this, n), r.startsWith("run:") ? e(this, F).emit("runEvent", n) : r.startsWith("step:") && e(this, F).emit("stepEvent", n);
169
+ }, /**
170
+ * Parse JSON string fields in broadcast event data
171
+ * @param eventData - The event data object to parse
172
+ */
173
+ X = function(t) {
174
+ if ("output" in t && typeof t.output == "string")
175
+ try {
176
+ t.output = JSON.parse(t.output);
177
+ } catch {
178
+ }
179
+ if ("input" in t && typeof t.input == "string")
180
+ try {
181
+ t.input = JSON.parse(t.input);
182
+ } catch {
183
+ }
184
+ }, G = async function(t, r, i, n) {
185
+ console.error(`Channel ${r} error:`, n), e(this, M).call(this, async () => {
186
+ e(this, C).has(t) && await m(this, _, Z).call(this, t, r);
187
+ }, e(this, I));
188
+ }, /**
189
+ * Creates and configures a channel for a run
190
+ * @param run_id - The run ID
191
+ * @param channelName - The channel name
192
+ * @returns The configured RealtimeChannel
193
+ */
194
+ Y = function(t, r) {
195
+ const i = e(this, S).channel(r);
196
+ return i.on("broadcast", { event: "*" }, m(this, _, j).bind(this)), i;
197
+ }, Z = async function(t, r) {
198
+ console.log(`Attempting to reconnect to ${r}`);
199
+ try {
200
+ const i = await this.getRunWithStates(t);
201
+ m(this, _, v).call(this, t, i);
202
+ const n = m(this, _, Y).call(this, t, r);
203
+ n.on("system", { event: "subscribed" }, () => {
204
+ console.log(`Reconnected and subscribed to channel ${r}`);
205
+ }), n.on("system", { event: "closed" }, () => {
206
+ console.log(`Reconnected channel ${r} closed`);
207
+ }), n.on(
208
+ "system",
209
+ { event: "error" },
210
+ (g) => m(this, _, G).call(this, t, r, n, g.error)
211
+ ), n.subscribe(), e(this, C).set(t, n);
212
+ } catch (i) {
213
+ console.error(`Failed to reconnect to ${r}:`, i);
214
+ }
215
+ }, /**
216
+ * Refresh client state from a state snapshot
217
+ * @param run_id - The run ID
218
+ * @param state - The state snapshot
219
+ */
220
+ v = function(t, r) {
221
+ if (!r || !r.run) return;
222
+ const i = {
223
+ event_type: `run:${r.run.status}`,
224
+ ...r.run
225
+ };
226
+ if (e(this, F).emit("runEvent", i), r.steps && Array.isArray(r.steps))
227
+ for (const n of r.steps) {
228
+ const g = {
229
+ event_type: `step:${n.status}`,
230
+ ...n
231
+ };
232
+ e(this, F).emit("stepEvent", g);
233
+ }
234
+ }, k = new WeakMap(), /**
235
+ * Unsubscribes from a run's events
236
+ *
237
+ * @param run_id - Run ID to unsubscribe from
238
+ */
239
+ K = function(t) {
240
+ const r = e(this, C).get(t);
241
+ r && (r.unsubscribe(), e(this, C).delete(t), e(this, k).delete(t));
242
+ };
243
+ var o, $, x, J, tt;
244
+ class it {
245
+ /**
246
+ * Creates a new FlowStep instance
247
+ *
248
+ * @param initialState - Initial state for the step
249
+ */
250
+ constructor(t) {
251
+ d(this, J);
252
+ d(this, o);
253
+ d(this, $, L());
254
+ d(this, x, {
255
+ [h.Created]: 0,
256
+ [h.Started]: 1,
257
+ [h.Completed]: 2,
258
+ [h.Failed]: 3
259
+ });
260
+ f(this, o, t);
261
+ }
262
+ /**
263
+ * Get the run ID this step belongs to
264
+ */
265
+ get run_id() {
266
+ return e(this, o).run_id;
267
+ }
268
+ /**
269
+ * Get the step slug
270
+ */
271
+ get step_slug() {
272
+ return e(this, o).step_slug;
273
+ }
274
+ /**
275
+ * Get the current status
276
+ */
277
+ get status() {
278
+ return e(this, o).status;
279
+ }
280
+ /**
281
+ * Get the started_at timestamp
282
+ */
283
+ get started_at() {
284
+ return e(this, o).started_at;
285
+ }
286
+ /**
287
+ * Get the completed_at timestamp
288
+ */
289
+ get completed_at() {
290
+ return e(this, o).completed_at;
291
+ }
292
+ /**
293
+ * Get the failed_at timestamp
294
+ */
295
+ get failed_at() {
296
+ return e(this, o).failed_at;
297
+ }
298
+ /**
299
+ * Get the step output
300
+ */
301
+ get output() {
302
+ return e(this, o).output;
303
+ }
304
+ /**
305
+ * Get the error object
306
+ */
307
+ get error() {
308
+ return e(this, o).error;
309
+ }
310
+ /**
311
+ * Get the error message
312
+ */
313
+ get error_message() {
314
+ return e(this, o).error_message;
315
+ }
316
+ /**
317
+ * Register an event handler for a step event
318
+ *
319
+ * @param event - Event type to listen for
320
+ * @param callback - Callback function to execute when event is emitted
321
+ * @returns Function to unsubscribe from the event
322
+ */
323
+ on(t, r) {
324
+ return e(this, $).on(t, r);
325
+ }
326
+ /**
327
+ * Wait for the step to reach a specific status
328
+ *
329
+ * @param targetStatus - The status to wait for
330
+ * @param options - Optional timeout and abort signal
331
+ * @returns Promise that resolves with the step instance when the status is reached
332
+ */
333
+ waitForStatus(t, r) {
334
+ const i = (r == null ? void 0 : r.timeoutMs) ?? 3e5, { signal: n } = r || {};
335
+ return this.status === t ? Promise.resolve(this) : new Promise((g, c) => {
336
+ let u, l = !1;
337
+ i > 0 && (u = setTimeout(() => {
338
+ l || (l = !0, P(), c(new Error(`Timeout waiting for step ${this.step_slug} to reach status '${t}'`)));
339
+ }, i));
340
+ let b;
341
+ if (n) {
342
+ const E = () => {
343
+ l || (l = !0, u && clearTimeout(u), P(), c(new Error(`Aborted waiting for step ${this.step_slug} to reach status '${t}'`)));
344
+ };
345
+ n.addEventListener("abort", E), b = () => {
346
+ n.removeEventListener("abort", E);
347
+ };
348
+ }
349
+ const P = this.on("*", (E) => {
350
+ if (E.status === t) {
351
+ if (l) return;
352
+ l = !0, u && clearTimeout(u), b && b(), P(), g(this);
353
+ }
354
+ });
355
+ });
356
+ }
357
+ /**
358
+ * Apply state from database snapshot (no events emitted)
359
+ * Used when initializing state from start_flow_with_states() or get_run_with_states()
360
+ *
361
+ * @internal This method is only intended for use by PgflowClient.
362
+ * Applications should not call this directly.
363
+ */
364
+ applySnapshot(t) {
365
+ e(this, o).status = t.status, e(this, o).started_at = t.started_at ? new Date(t.started_at) : null, e(this, o).completed_at = t.completed_at ? new Date(t.completed_at) : null, e(this, o).failed_at = t.failed_at ? new Date(t.failed_at) : null, e(this, o).error_message = t.error_message, e(this, o).error = t.error_message ? new Error(t.error_message) : null;
366
+ }
367
+ /**
368
+ * Updates the step state based on an event
369
+ *
370
+ * @internal This method is only intended for use by FlowRun and tests.
371
+ * Applications should not call this directly - state updates should come from
372
+ * database events through the PgflowClient.
373
+ *
374
+ * TODO: After v1.0, make this method private and refactor tests to use PgflowClient
375
+ * with event emission instead of direct state manipulation.
376
+ */
377
+ updateState(t) {
378
+ if (t.step_slug !== e(this, o).step_slug || t.run_id !== e(this, o).run_id || !m(this, J, tt).call(this, e(this, o).status, t.status))
379
+ return !1;
380
+ switch (t.status) {
381
+ case h.Started:
382
+ f(this, o, {
383
+ ...e(this, o),
384
+ status: h.Started,
385
+ started_at: typeof t.started_at == "string" ? new Date(t.started_at) : /* @__PURE__ */ new Date()
386
+ }), e(this, $).emit("started", t);
387
+ break;
388
+ case h.Completed:
389
+ f(this, o, {
390
+ ...e(this, o),
391
+ status: h.Completed,
392
+ completed_at: typeof t.completed_at == "string" ? new Date(t.completed_at) : /* @__PURE__ */ new Date(),
393
+ output: t.output
394
+ }), e(this, $).emit("completed", t);
395
+ break;
396
+ case h.Failed:
397
+ f(this, o, {
398
+ ...e(this, o),
399
+ status: h.Failed,
400
+ failed_at: typeof t.failed_at == "string" ? new Date(t.failed_at) : /* @__PURE__ */ new Date(),
401
+ error_message: typeof t.error_message == "string" ? t.error_message : "Unknown error",
402
+ error: new Error(typeof t.error_message == "string" ? t.error_message : "Unknown error")
403
+ }), e(this, $).emit("failed", t);
404
+ break;
405
+ default:
406
+ return !1;
407
+ }
408
+ return e(this, $).emit("*", t), !0;
409
+ }
410
+ }
411
+ o = new WeakMap(), $ = new WeakMap(), x = new WeakMap(), J = new WeakSet(), /**
412
+ * Determines if a status should be updated based on precedence
413
+ *
414
+ * @param currentStatus - Current status
415
+ * @param newStatus - New status
416
+ * @returns true if the status should be updated, false otherwise
417
+ */
418
+ tt = function(t, r) {
419
+ if (t === h.Completed || t === h.Failed)
420
+ return !1;
421
+ const i = e(this, x)[t];
422
+ return e(this, x)[r] > i;
423
+ };
424
+ var a, R, T, q, U, A, D, B, et;
425
+ class V {
426
+ /**
427
+ * Creates a new FlowRun instance
428
+ *
429
+ * @param initialState - Initial state for the run
430
+ */
431
+ constructor(t) {
432
+ d(this, D);
433
+ d(this, a);
434
+ d(this, R, L());
435
+ d(this, T, /* @__PURE__ */ new Map());
436
+ d(this, q, {
437
+ [p.Started]: 0,
438
+ [p.Completed]: 1,
439
+ [p.Failed]: 2
440
+ });
441
+ d(this, U, !1);
442
+ // Track number of listeners
443
+ d(this, A, 0);
444
+ f(this, a, t);
445
+ }
446
+ /**
447
+ * Get the run ID
448
+ */
449
+ get run_id() {
450
+ return e(this, a).run_id;
451
+ }
452
+ /**
453
+ * Get the flow slug
454
+ */
455
+ get flow_slug() {
456
+ return e(this, a).flow_slug;
457
+ }
458
+ /**
459
+ * Get the current status
460
+ */
461
+ get status() {
462
+ return e(this, a).status;
463
+ }
464
+ /**
465
+ * Get the started_at timestamp
466
+ */
467
+ get started_at() {
468
+ return e(this, a).started_at;
469
+ }
470
+ /**
471
+ * Get the completed_at timestamp
472
+ */
473
+ get completed_at() {
474
+ return e(this, a).completed_at;
475
+ }
476
+ /**
477
+ * Get the failed_at timestamp
478
+ */
479
+ get failed_at() {
480
+ return e(this, a).failed_at;
481
+ }
482
+ /**
483
+ * Get the flow input
484
+ */
485
+ get input() {
486
+ return e(this, a).input;
487
+ }
488
+ /**
489
+ * Get the flow output
490
+ */
491
+ get output() {
492
+ return e(this, a).output;
493
+ }
494
+ /**
495
+ * Get the error object
496
+ */
497
+ get error() {
498
+ return e(this, a).error;
499
+ }
500
+ /**
501
+ * Get the error message
502
+ */
503
+ get error_message() {
504
+ return e(this, a).error_message;
505
+ }
506
+ /**
507
+ * Get the number of remaining steps
508
+ */
509
+ get remaining_steps() {
510
+ return e(this, a).remaining_steps;
511
+ }
512
+ /**
513
+ * Register an event handler for a run event
514
+ *
515
+ * @param event - Event type to listen for
516
+ * @param callback - Callback function to execute when event is emitted
517
+ * @returns Function to unsubscribe from the event
518
+ */
519
+ on(t, r) {
520
+ H(this, A)._++;
521
+ const i = e(this, R).on(t, r);
522
+ return () => {
523
+ i(), H(this, A)._--, m(this, D, B).call(this);
524
+ };
525
+ }
526
+ /**
527
+ * Get a FlowStep instance for a specific step
528
+ *
529
+ * @param stepSlug - Step slug to get
530
+ * @returns FlowStep instance for the specified step
531
+ */
532
+ step(t) {
533
+ const r = e(this, T).get(t);
534
+ if (r)
535
+ return r;
536
+ const i = new it({
537
+ run_id: this.run_id,
538
+ step_slug: t,
539
+ status: h.Created,
540
+ output: null,
541
+ error: null,
542
+ error_message: null,
543
+ started_at: null,
544
+ completed_at: null,
545
+ failed_at: null
546
+ });
547
+ return e(this, T).set(
548
+ t,
549
+ i
550
+ ), i;
551
+ }
552
+ /**
553
+ * Check if this run has a specific step
554
+ *
555
+ * @param stepSlug - Step slug to check
556
+ * @returns true if the step exists, false otherwise
557
+ */
558
+ hasStep(t) {
559
+ return e(this, T).has(t);
560
+ }
561
+ /**
562
+ * Wait for the run to reach a specific status
563
+ *
564
+ * @param targetStatus - The status to wait for
565
+ * @param options - Optional timeout and abort signal
566
+ * @returns Promise that resolves with the run instance when the status is reached
567
+ */
568
+ waitForStatus(t, r) {
569
+ const i = (r == null ? void 0 : r.timeoutMs) ?? 3e5, { signal: n } = r || {};
570
+ return this.status === t ? Promise.resolve(this) : new Promise((g, c) => {
571
+ let u, l = !1;
572
+ i > 0 && (u = setTimeout(() => {
573
+ l || (l = !0, P(), c(
574
+ new Error(
575
+ `Timeout waiting for run ${this.run_id} to reach status '${t}'`
576
+ )
577
+ ));
578
+ }, i));
579
+ let b;
580
+ if (n) {
581
+ const E = () => {
582
+ l || (l = !0, u && clearTimeout(u), P(), c(
583
+ new Error(
584
+ `Aborted waiting for run ${this.run_id} to reach status '${t}'`
585
+ )
586
+ ));
587
+ };
588
+ n.addEventListener("abort", E), b = () => {
589
+ n.removeEventListener("abort", E);
590
+ };
591
+ }
592
+ const P = this.on("*", (E) => {
593
+ if (E.status === t) {
594
+ if (l) return;
595
+ l = !0, u && clearTimeout(u), b && b(), P(), g(this);
596
+ }
597
+ });
598
+ });
599
+ }
600
+ /**
601
+ * Apply state from database snapshot (no events emitted)
602
+ * Used when initializing state from start_flow_with_states() or get_run_with_states()
603
+ *
604
+ * @internal This method is only intended for use by PgflowClient.
605
+ * Applications should not call this directly.
606
+ */
607
+ applySnapshot(t) {
608
+ e(this, a).status = t.status, e(this, a).input = t.input, e(this, a).output = t.output, e(this, a).started_at = t.started_at ? new Date(t.started_at) : null, e(this, a).completed_at = t.completed_at ? new Date(t.completed_at) : null, e(this, a).failed_at = t.failed_at ? new Date(t.failed_at) : null, e(this, a).remaining_steps = t.remaining_steps, e(this, a).error_message = null, e(this, a).error = null;
609
+ }
610
+ /**
611
+ * Updates the run state based on an event
612
+ *
613
+ * @internal This method is only intended for use by PgflowClient and tests.
614
+ * Applications should not call this directly - state updates should come from
615
+ * database events through the PgflowClient.
616
+ *
617
+ * TODO: After v1.0, make this method private and refactor tests to use PgflowClient
618
+ * with event emission instead of direct state manipulation.
619
+ */
620
+ updateState(t) {
621
+ if (t.run_id !== e(this, a).run_id || !m(this, D, et).call(this, e(this, a).status, t.status))
622
+ return !1;
623
+ switch (t.status) {
624
+ case p.Started:
625
+ f(this, a, {
626
+ ...e(this, a),
627
+ status: p.Started,
628
+ started_at: typeof t.started_at == "string" ? new Date(t.started_at) : /* @__PURE__ */ new Date(),
629
+ remaining_steps: "remaining_steps" in t ? Number(t.remaining_steps) : e(this, a).remaining_steps
630
+ }), e(this, R).emit("started", t);
631
+ break;
632
+ case p.Completed:
633
+ f(this, a, {
634
+ ...e(this, a),
635
+ status: p.Completed,
636
+ completed_at: typeof t.completed_at == "string" ? new Date(t.completed_at) : /* @__PURE__ */ new Date(),
637
+ output: t.output,
638
+ remaining_steps: 0
639
+ }), e(this, R).emit("completed", t), m(this, D, B).call(this);
640
+ break;
641
+ case p.Failed:
642
+ f(this, a, {
643
+ ...e(this, a),
644
+ status: p.Failed,
645
+ failed_at: typeof t.failed_at == "string" ? new Date(t.failed_at) : /* @__PURE__ */ new Date(),
646
+ error_message: typeof t.error_message == "string" ? t.error_message : "Unknown error",
647
+ error: new Error(
648
+ typeof t.error_message == "string" ? t.error_message : "Unknown error"
649
+ )
650
+ }), e(this, R).emit("failed", t), m(this, D, B).call(this);
651
+ break;
652
+ default:
653
+ return !1;
654
+ }
655
+ return e(this, R).emit("*", t), !0;
656
+ }
657
+ /**
658
+ * Updates a step state based on an event
659
+ *
660
+ * @param stepSlug - Step slug to update
661
+ * @param event - Event data to update the step with
662
+ * @returns true if the state was updated, false otherwise
663
+ */
664
+ updateStepState(t, r) {
665
+ return this.step(t).updateState(r);
666
+ }
667
+ /**
668
+ * Clean up all resources held by this run
669
+ */
670
+ dispose() {
671
+ e(this, U) || (e(this, T).clear(), f(this, R, L()), f(this, A, 0), f(this, U, !0));
672
+ }
673
+ }
674
+ a = new WeakMap(), R = new WeakMap(), T = new WeakMap(), q = new WeakMap(), U = new WeakMap(), A = new WeakMap(), D = new WeakSet(), /**
675
+ * Checks if auto-dispose should be triggered (when in terminal state with no listeners)
676
+ */
677
+ B = function() {
678
+ e(this, U) || this.status !== p.Completed && this.status !== p.Failed || e(this, A) === 0 && this.dispose();
679
+ }, /**
680
+ * Determines if a status should be updated based on precedence
681
+ *
682
+ * @param currentStatus - Current status
683
+ * @param newStatus - New status
684
+ * @returns true if the status should be updated, false otherwise
685
+ */
686
+ et = function(t, r) {
687
+ if (t === p.Completed || t === p.Failed)
688
+ return !1;
689
+ const i = e(this, q)[t];
690
+ return e(this, q)[r] > i;
691
+ };
692
+ function nt(s) {
693
+ switch (s.status) {
694
+ case p.Started:
695
+ return {
696
+ event_type: "run:started",
697
+ run_id: s.run_id,
698
+ flow_slug: s.flow_slug,
699
+ status: p.Started,
700
+ started_at: s.started_at,
701
+ remaining_steps: s.remaining_steps,
702
+ input: s.input
703
+ };
704
+ case p.Completed:
705
+ return {
706
+ event_type: "run:completed",
707
+ run_id: s.run_id,
708
+ flow_slug: s.flow_slug,
709
+ status: p.Completed,
710
+ completed_at: s.completed_at,
711
+ output: s.output
712
+ };
713
+ case p.Failed:
714
+ return {
715
+ event_type: "run:failed",
716
+ run_id: s.run_id,
717
+ flow_slug: s.flow_slug,
718
+ status: p.Failed,
719
+ failed_at: s.failed_at,
720
+ error_message: s.error_message
721
+ };
722
+ }
723
+ }
724
+ function at(s) {
725
+ switch (s.status) {
726
+ case h.Started:
727
+ return {
728
+ event_type: "step:started",
729
+ run_id: s.run_id,
730
+ step_slug: s.step_slug,
731
+ status: h.Started,
732
+ started_at: s.started_at
733
+ };
734
+ case h.Completed:
735
+ return {
736
+ event_type: "step:completed",
737
+ run_id: s.run_id,
738
+ step_slug: s.step_slug,
739
+ status: h.Completed,
740
+ completed_at: s.completed_at,
741
+ output: s.output
742
+ };
743
+ case h.Failed:
744
+ return {
745
+ event_type: "step:failed",
746
+ run_id: s.run_id,
747
+ step_slug: s.step_slug,
748
+ status: h.Failed,
749
+ failed_at: s.failed_at,
750
+ error_message: s.error_message
751
+ };
752
+ }
753
+ }
754
+ var z, w, y;
755
+ class gt {
756
+ /**
757
+ * Creates a new PgflowClient instance
758
+ *
759
+ * @param supabaseClient - Supabase client instance
760
+ * @param opts - Optional configuration
761
+ */
762
+ constructor(t, r = {}) {
763
+ d(this, z);
764
+ d(this, w);
765
+ // Use the widest event type - keeps the compiler happy but
766
+ // still provides the structural API we need (updateState/step/...)
767
+ d(this, y, /* @__PURE__ */ new Map());
768
+ f(this, z, t), f(this, w, new rt(t, {
769
+ stabilizationDelayMs: r.realtimeStabilizationDelayMs,
770
+ schedule: r.schedule
771
+ })), e(this, w).onRunEvent((i) => {
772
+ const n = e(this, y).get(i.run_id);
773
+ n && n.updateState(nt(i));
774
+ }), e(this, w).onStepEvent((i) => {
775
+ const n = e(this, y).get(i.run_id);
776
+ if (n) {
777
+ const g = i.step_slug;
778
+ n.step(g).updateState(at(i));
779
+ }
780
+ });
781
+ }
782
+ /**
783
+ * Start a flow with optional run_id
784
+ *
785
+ * @param flow_slug - Flow slug to start
786
+ * @param input - Input data for the flow
787
+ * @param run_id - Optional run ID (will be generated if not provided)
788
+ * @returns Promise that resolves with the FlowRun instance
789
+ */
790
+ async startFlow(t, r, i) {
791
+ const n = i || st(), g = {
792
+ run_id: n,
793
+ flow_slug: t,
794
+ status: p.Started,
795
+ input: r,
796
+ output: null,
797
+ error: null,
798
+ error_message: null,
799
+ started_at: null,
800
+ completed_at: null,
801
+ failed_at: null,
802
+ remaining_steps: -1
803
+ // Use -1 to indicate unknown until first snapshot arrives
804
+ }, c = new V(g);
805
+ e(this, y).set(n, c), await e(this, w).subscribeToRun(n);
806
+ const { data: u, error: l } = await e(this, z).schema("pgflow").rpc("start_flow_with_states", {
807
+ flow_slug: t,
808
+ input: r,
809
+ run_id: n
810
+ });
811
+ if (l)
812
+ throw this.dispose(n), l;
813
+ if (u.run && c.applySnapshot(u.run), u.steps && Array.isArray(u.steps))
814
+ for (const b of u.steps)
815
+ c.step(b.step_slug).applySnapshot(b);
816
+ return c;
817
+ }
818
+ /**
819
+ * Dispose a specific flow run
820
+ *
821
+ * @param runId - Run ID to dispose
822
+ */
823
+ dispose(t) {
824
+ const r = e(this, y).get(t);
825
+ r && (e(this, w).unsubscribe(t), r.dispose(), e(this, y).delete(t));
826
+ }
827
+ /**
828
+ * Dispose all flow runs
829
+ */
830
+ disposeAll() {
831
+ for (const t of e(this, y).keys())
832
+ this.dispose(t);
833
+ }
834
+ // Delegate IFlowRealtime methods to the adapter
835
+ /**
836
+ * Fetch flow definition metadata
837
+ */
838
+ async fetchFlowDefinition(t) {
839
+ return e(this, w).fetchFlowDefinition(t);
840
+ }
841
+ /**
842
+ * Register a callback for run events
843
+ * @returns Function to unsubscribe from the event
844
+ */
845
+ onRunEvent(t) {
846
+ return e(this, w).onRunEvent(t);
847
+ }
848
+ /**
849
+ * Register a callback for step events
850
+ * @returns Function to unsubscribe from the event
851
+ */
852
+ onStepEvent(t) {
853
+ return e(this, w).onStepEvent(t);
854
+ }
855
+ /**
856
+ * Subscribe to a flow run's events
857
+ */
858
+ async subscribeToRun(t) {
859
+ return await e(this, w).subscribeToRun(t);
860
+ }
861
+ /**
862
+ * Fetch current state of a run and its steps
863
+ */
864
+ async getRunWithStates(t) {
865
+ return e(this, w).getRunWithStates(t);
866
+ }
867
+ /**
868
+ * Get a flow run by ID
869
+ *
870
+ * @param run_id - ID of the run to get
871
+ * @returns Promise that resolves with the FlowRun instance or null if not found
872
+ */
873
+ async getRun(t) {
874
+ const r = e(this, y).get(t);
875
+ if (r)
876
+ return r;
877
+ try {
878
+ const { run: i, steps: n } = await this.getRunWithStates(t);
879
+ if (!i)
880
+ return null;
881
+ if (!i.run_id || !i.flow_slug || !i.status)
882
+ throw new Error("Invalid run data: missing required fields");
883
+ if (!Object.values(p).includes(i.status))
884
+ throw new Error(`Invalid run data: invalid status '${i.status}'`);
885
+ const c = {
886
+ run_id: i.run_id,
887
+ flow_slug: i.flow_slug,
888
+ status: i.status,
889
+ input: i.input,
890
+ output: null,
891
+ error: null,
892
+ error_message: null,
893
+ started_at: null,
894
+ completed_at: null,
895
+ failed_at: null,
896
+ remaining_steps: 0
897
+ }, u = new V(c);
898
+ if (u.applySnapshot(i), e(this, y).set(t, u), await e(this, w).subscribeToRun(t), n && Array.isArray(n))
899
+ for (const l of n) {
900
+ if (!l.step_slug || !l.status)
901
+ throw new Error("Invalid step data: missing required fields");
902
+ u.step(l.step_slug).applySnapshot(l);
903
+ }
904
+ return u;
905
+ } catch (i) {
906
+ if (console.error("Error getting run:", i), i instanceof Error && (i.message.includes("Invalid run data") || i.message.includes("Invalid step data")))
907
+ throw i;
908
+ return null;
909
+ }
910
+ }
911
+ }
912
+ z = new WeakMap(), w = new WeakMap(), y = new WeakMap();
913
+ export {
914
+ V as FlowRun,
915
+ p as FlowRunStatus,
916
+ it as FlowStep,
917
+ h as FlowStepStatus,
918
+ gt as PgflowClient,
919
+ pt as isFlowRunCompletedEvent,
920
+ dt as isFlowRunEvent,
921
+ ht as isFlowRunFailedEvent,
922
+ ct as isFlowRunStartedEvent,
923
+ _t as isStepCompletedEvent,
924
+ N as isStepEvent,
925
+ mt as isStepFailedEvent,
926
+ ft as isStepStartedEvent
927
+ };
928
+ //# sourceMappingURL=index.js.map