@voltro/workflow 0.33.0 → 0.35.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.
@@ -1,62 +1,71 @@
1
1
  import { Context as e, Duration as t, Effect as n, Layer as r, Option as i } from "effect";
2
2
  import { ClusterCron as a, ClusterSchema as o, ClusterWorkflowEngine as s, EntityAddress as c, EntityId as l, EntityType as u, MessageStorage as d, RunnerAddress as f, Sharding as p, ShardingConfig as m, SingleRunner as h, SqlMessageStorage as g, SqlRunnerStorage as _ } from "@effect/cluster";
3
3
  import { SqlClient as v } from "@effect/sql";
4
+ import { fnv1a64 as y, resolveMigrationLockSchema as b } from "@voltro/database/sql";
4
5
  //#region src/clusterMigrationGate.ts
5
- var y = 6322741009312601n, b = `voltro_cluster_migration_${y.toString(36)}`, x = () => {
6
+ var x = 6322741009312601n, S = () => {
7
+ let e = b();
8
+ return e === void 0 ? x : y(`voltro_cluster_migration_lock:${e}`) & 9223372036854775807n;
9
+ }, C = () => {
10
+ let e = `voltro_cluster_migration_${x.toString(36)}`, t = b();
11
+ if (t === void 0) return e;
12
+ let n = `${e}_${t}`;
13
+ return /^[A-Za-z0-9_]+$/.test(t) && n.length <= 64 ? n : `${e}_h${y(`voltro_cluster_migration_lock:${t}`).toString(16)}`;
14
+ }, w = () => {
6
15
  let e = Number(process.env.VOLTRO_CLUSTER_MIGRATION_LOCK_TIMEOUT_MS);
7
16
  return Number.isFinite(e) && e > 0 ? e : 6e4;
8
- }, S = 250, C = (e) => e[0]?.[0], w = (e, t) => e.onDialectOrElse({
17
+ }, T = 250, E = (e) => e[0]?.[0], D = (e, t) => e.onDialectOrElse({
9
18
  sqlite: () => n.void,
10
- mysql: () => t.executeValues(`SELECT GET_LOCK('${b}', ${Math.ceil(x() / 1e3)})`, []).pipe(n.flatMap((e) => C(e) === 1 || C(e) === "1" ? n.void : n.die(/* @__PURE__ */ Error(`could not acquire cluster migration lock '${b}' (GET_LOCK timed out)`)))),
11
- mssql: () => t.executeValues(`DECLARE @res int; EXEC @res = sp_getapplock @Resource = '${b}', @LockMode = 'Exclusive', @LockOwner = 'Session', @LockTimeout = ${x()}; SELECT @res`, []).pipe(n.flatMap((e) => Number(C(e) ?? -999) >= 0 ? n.void : n.die(/* @__PURE__ */ Error(`could not acquire cluster migration lock '${b}' (sp_getapplock ${String(C(e))})`)))),
19
+ mysql: () => t.executeValues(`SELECT GET_LOCK('${C()}', ${Math.ceil(w() / 1e3)})`, []).pipe(n.flatMap((e) => E(e) === 1 || E(e) === "1" ? n.void : n.die(/* @__PURE__ */ Error(`could not acquire cluster migration lock '${C()}' (GET_LOCK timed out)`)))),
20
+ mssql: () => t.executeValues(`DECLARE @res int; EXEC @res = sp_getapplock @Resource = '${C()}', @LockMode = 'Exclusive', @LockOwner = 'Session', @LockTimeout = ${w()}; SELECT @res`, []).pipe(n.flatMap((e) => Number(E(e) ?? -999) >= 0 ? n.void : n.die(/* @__PURE__ */ Error(`could not acquire cluster migration lock '${C()}' (sp_getapplock ${String(E(e))})`)))),
12
21
  orElse: () => {
13
- let e = y.toString(), r = Date.now(), i = t.executeValues(`SELECT pg_try_advisory_lock(${e}::bigint)`, []).pipe(n.flatMap((e) => {
14
- let t = C(e);
15
- return t === !0 || t === "t" || t === 1 ? n.void : Date.now() - r >= x() ? n.die(/* @__PURE__ */ Error(`could not acquire the cluster migration advisory lock within ${Math.round(x() / 1e3)}s. Another runner is migrating the cluster schema, or a prior boot wedged while holding it. (Raise VOLTRO_CLUSTER_MIGRATION_LOCK_TIMEOUT_MS, or inspect pg_locks for the holder.)`)) : n.sleep(`${S} millis`).pipe(n.zipRight(i));
22
+ let e = S().toString(), r = Date.now(), i = t.executeValues(`SELECT pg_try_advisory_lock(${e}::bigint)`, []).pipe(n.flatMap((e) => {
23
+ let t = E(e);
24
+ return t === !0 || t === "t" || t === 1 ? n.void : Date.now() - r >= w() ? n.die(/* @__PURE__ */ Error(`could not acquire the cluster migration advisory lock within ${Math.round(w() / 1e3)}s. Another runner is migrating the cluster schema, or a prior boot wedged while holding it. (Raise VOLTRO_CLUSTER_MIGRATION_LOCK_TIMEOUT_MS, or inspect pg_locks for the holder.)`)) : n.sleep(`${T} millis`).pipe(n.zipRight(i));
16
25
  }));
17
26
  return i;
18
27
  }
19
- }), T = (e, t) => e.onDialectOrElse({
28
+ }), O = (e, t) => e.onDialectOrElse({
20
29
  sqlite: () => n.void,
21
- mysql: () => n.asVoid(t.executeValues(`SELECT RELEASE_LOCK('${b}')`, [])),
22
- mssql: () => n.asVoid(t.executeValues(`EXEC sp_releaseapplock @Resource = '${b}', @LockOwner = 'Session'`, [])),
23
- orElse: () => n.asVoid(t.executeValues(`SELECT pg_advisory_unlock(${y.toString()}::bigint)`, []))
24
- }), E = (e, t) => e.onDialectOrElse({
30
+ mysql: () => n.asVoid(t.executeValues(`SELECT RELEASE_LOCK('${C()}')`, [])),
31
+ mssql: () => n.asVoid(t.executeValues(`EXEC sp_releaseapplock @Resource = '${C()}', @LockOwner = 'Session'`, [])),
32
+ orElse: () => n.asVoid(t.executeValues(`SELECT pg_advisory_unlock(${S().toString()}::bigint)`, []))
33
+ }), k = (e, t) => e.onDialectOrElse({
25
34
  sqlite: () => !0,
26
35
  orElse: () => !1
27
36
  }) ? t : n.scoped(n.gen(function* () {
28
37
  let r = yield* e.reserve;
29
- return yield* n.acquireRelease(w(e, r), () => T(e, r).pipe(n.orDie)), yield* t;
30
- })), D = (e) => e === "sql" ? ["cluster_messages", "cluster_runners"] : ["cluster_messages"], O = (e, t) => n.forEach(D(t), (t) => e`SELECT 1 FROM ${e(t)}`.pipe(n.as(!0), n.catchAll(() => n.succeed(!1))), { concurrency: 1 }).pipe(n.map((e) => e.every(Boolean))), k = (e, t) => n.scoped(n.asVoid(r.build(t.pipe(r.provide(m.layerDefaults), r.provide(r.succeed(v.SqlClient, e)))))), A = (e, t) => k(e, g.layer).pipe(n.zipRight(t === "sql" ? k(e, _.layer) : n.void)), j = (e) => r.effect(v.SqlClient, n.gen(function* () {
38
+ return yield* n.acquireRelease(D(e, r), () => O(e, r).pipe(n.orDie)), yield* t;
39
+ })), A = (e) => e === "sql" ? ["cluster_messages", "cluster_runners"] : ["cluster_messages"], j = (e, t) => n.forEach(A(t), (t) => e`SELECT 1 FROM ${e(t)}`.pipe(n.as(!0), n.catchAll(() => n.succeed(!1))), { concurrency: 1 }).pipe(n.map((e) => e.every(Boolean))), M = (e, t) => n.scoped(n.asVoid(r.build(t.pipe(r.provide(m.layerDefaults), r.provide(r.succeed(v.SqlClient, e)))))), N = (e, t) => M(e, g.layer).pipe(n.zipRight(t === "sql" ? M(e, _.layer) : n.void)), P = (e) => r.effect(v.SqlClient, n.gen(function* () {
31
40
  let t = yield* v.SqlClient;
32
- return (yield* O(t, e.runnerStorage)) || (yield* E(t, A(t, e.runnerStorage))), t;
33
- })), M = 34e3, N = (e) => {
41
+ return (yield* j(t, e.runnerStorage)) || (yield* k(t, N(t, e.runnerStorage))), t;
42
+ })), F = 34e3, I = (e) => {
34
43
  let t = e.runnerListenHost ?? process.env.POD_IP ?? process.env.VOLTRO_WORKFLOW_RUNNER_HOST ?? "localhost";
35
44
  return {
36
45
  host: t,
37
46
  port: e.runnerListenPort ?? 34e3,
38
47
  localhostRisk: e.runnerStorage === "sql" && (t === "localhost" || t === "127.0.0.1")
39
48
  };
40
- }, P = (e) => {
49
+ }, L = (e) => {
41
50
  let t = e.sqliteFamily ? "memory" : "sql", n = e.override ?? process.env.VOLTRO_WORKFLOW_RUNNER_STORAGE;
42
51
  if (n === void 0 || n.trim() === "") return t;
43
52
  let r = n.trim().toLowerCase();
44
53
  if (r !== "memory" && r !== "sql") throw Error(`VOLTRO_WORKFLOW_RUNNER_STORAGE must be 'memory' or 'sql', got '${n}'.`);
45
54
  if (r === "sql" && e.sqliteFamily) throw Error("VOLTRO_WORKFLOW_RUNNER_STORAGE='sql' is unsupported on sqlite / turso — @effect/cluster has no sqlite advisory-lock branch. Use 'memory'.");
46
55
  return r;
47
- }, F = (e = process.env.VOLTRO_WORKFLOW_SHARD_LOCK) => {
56
+ }, R = (e = process.env.VOLTRO_WORKFLOW_SHARD_LOCK) => {
48
57
  if (e === void 0 || e.trim() === "") return "auto";
49
58
  let t = e.trim().toLowerCase();
50
59
  if (t === "auto" || t === "row" || t === "advisory") return t;
51
60
  throw Error(`VOLTRO_WORKFLOW_SHARD_LOCK must be 'auto', 'row', or 'advisory', got '${e}'.`);
52
- }, I = n.gen(function* () {
61
+ }, z = n.gen(function* () {
53
62
  let e = yield* (yield* v.SqlClient)`SELECT @@wsrep_on AS wsrep`.pipe(n.catchAll(() => n.succeed([])));
54
63
  if (e.length === 0) return !1;
55
64
  let t = e[0].wsrep;
56
65
  return t === 1 || t === "1" || t === !0 || t === "ON" || t === "on";
57
- }), L = (e) => n.gen(function* () {
58
- return e.runnerStorage === "memory" ? !1 : e.mode === "row" ? !0 : e.mode === "advisory" || e.dialectId !== "mysql" && e.dialectId !== "mariadb" ? !1 : yield* I;
59
- }), R = () => {
66
+ }), B = (e) => n.gen(function* () {
67
+ return e.runnerStorage === "memory" ? !1 : e.mode === "row" ? !0 : e.mode === "advisory" || e.dialectId !== "mysql" && e.dialectId !== "mariadb" ? !1 : yield* z;
68
+ }), V = () => {
60
69
  let e = (e) => {
61
70
  if (e === void 0) return;
62
71
  let t = Number(e);
@@ -67,15 +76,15 @@ var y = 6322741009312601n, b = `voltro_cluster_migration_${y.toString(36)}`, x =
67
76
  ...n === void 0 ? {} : { failoverHeartbeatSeconds: n },
68
77
  ...r === void 0 ? {} : { messagePollSeconds: r }
69
78
  };
70
- }, z = n.flatMap(p.Sharding, (e) => e.pollStorage), B = /* @__PURE__ */ new Set(), V = (e) => {
71
- let a = N({
79
+ }, H = n.flatMap(p.Sharding, (e) => e.pollStorage), U = /* @__PURE__ */ new Set(), W = (e) => {
80
+ let a = I({
72
81
  runnerStorage: e.runnerStorage,
73
82
  runnerListenHost: e.runnerListenHost,
74
83
  runnerListenPort: e.runnerListenPort
75
84
  }), o = a.host, c = a.port;
76
- a.localhostRisk && !B.has(o) && (B.add(o), process.stderr.write(`[voltro:workflow] runner host is '${o}' with SQL cluster storage — other pods cannot reach this runner, so a workflow cannot resume on another pod after a reschedule. Inject POD_IP via the K8s downward API (fieldRef: status.podIP) or set runnerListenHost / VOLTRO_WORKFLOW_RUNNER_HOST.
85
+ a.localhostRisk && !U.has(o) && (U.add(o), process.stderr.write(`[voltro:workflow] runner host is '${o}' with SQL cluster storage — other pods cannot reach this runner, so a workflow cannot resume on another pod after a reschedule. Inject POD_IP via the K8s downward API (fieldRef: status.podIP) or set runnerListenHost / VOLTRO_WORKFLOW_RUNNER_HOST.
77
86
  `));
78
- let l = j({ runnerStorage: e.runnerStorage }).pipe(r.provide(e.sqlClientLayer)), u = e.shardLockMode ?? F(), d = r.unwrapEffect(L({
87
+ let l = P({ runnerStorage: e.runnerStorage }).pipe(r.provide(e.sqlClientLayer)), u = e.shardLockMode ?? R(), d = r.unwrapEffect(B({
79
88
  dialectId: e.dialectId,
80
89
  runnerStorage: e.runnerStorage,
81
90
  mode: u
@@ -91,19 +100,19 @@ var y = 6322741009312601n, b = `voltro_cluster_migration_${y.toString(36)}`, x =
91
100
  }
92
101
  }))))).pipe(r.provide(l)), p = e.extraShardingLayers ?? [];
93
102
  return (p.length === 0 ? s.layer : r.mergeAll(s.layer, ...p)).pipe(r.provideMerge(d));
94
- }, H = (e) => a.make({
103
+ }, G = (e) => a.make({
95
104
  name: e.name,
96
105
  cron: e.cron,
97
106
  execute: n.promise(() => e.execute()),
98
107
  skipIfOlderThan: e.skipIfOlderThan ?? t.days(1)
99
- }), U = (e, t) => `${e}/${t}`, W = (t, n, r) => {
108
+ }), K = (e, t) => `${e}/${t}`, q = (t, n, r) => {
100
109
  let i = l.make(n), a = e.get(t.annotations, o.ShardGroup)(i);
101
110
  return new c.EntityAddress({
102
111
  entityType: u.EntityType.make(`Workflow/${t.name}`),
103
112
  entityId: i,
104
113
  shardId: r.getShardId(i, a)
105
114
  });
106
- }, G = (e) => {
115
+ }, J = (e) => {
107
116
  let t = (e) => e && typeof e == "object" && "_tag" in e ? String(e._tag) : void 0, n = t(e);
108
117
  if (n === "Failure" || n !== "Success") return "failed";
109
118
  let r = e.value, i = t(r);
@@ -113,8 +122,8 @@ var y = 6322741009312601n, b = `voltro_cluster_migration_${y.toString(36)}`, x =
113
122
  return t(e) === "Success" ? "succeeded" : "failed";
114
123
  }
115
124
  return "failed";
116
- }, K = (e) => J(e.workflow, e.executionId, e.failedActivities), q = (e) => J(e.workflow, e.executionId, e.resetActivities), J = (e, t, r) => n.gen(function* () {
117
- let a = yield* p.Sharding, o = yield* d.MessageStorage, s = W(e, t, a), c = yield* o.requestIdForPrimaryKey({
125
+ }, Y = (e) => Z(e.workflow, e.executionId, e.failedActivities), X = (e) => Z(e.workflow, e.executionId, e.resetActivities), Z = (e, t, r) => n.gen(function* () {
126
+ let a = yield* p.Sharding, o = yield* d.MessageStorage, s = q(e, t, a), c = yield* o.requestIdForPrimaryKey({
118
127
  address: s,
119
128
  tag: "run",
120
129
  id: ""
@@ -132,7 +141,7 @@ var y = 6322741009312601n, b = `voltro_cluster_migration_${y.toString(36)}`, x =
132
141
  activitiesReset: 0,
133
142
  reason: "no-reply"
134
143
  };
135
- if (G(l.exit) === "succeeded") return {
144
+ if (J(l.exit) === "succeeded") return {
136
145
  redriven: !1,
137
146
  runReplyCleared: !1,
138
147
  activitiesReset: 0,
@@ -143,7 +152,7 @@ var y = 6322741009312601n, b = `voltro_cluster_migration_${y.toString(36)}`, x =
143
152
  let t = yield* o.requestIdForPrimaryKey({
144
153
  address: s,
145
154
  tag: "activity",
146
- id: U(e.name, e.attempt)
155
+ id: K(e.name, e.attempt)
147
156
  }).pipe(n.orElseSucceed(() => i.none()));
148
157
  i.isSome(t) && (yield* a.reset(t.value)) && (u += 1);
149
158
  }
@@ -156,4 +165,4 @@ var y = 6322741009312601n, b = `voltro_cluster_migration_${y.toString(36)}`, x =
156
165
  };
157
166
  });
158
167
  //#endregion
159
- export { M as a, z as c, P as d, L as f, H as i, R as l, K as n, I as o, V as p, q as r, F as s, U as t, N as u };
168
+ export { F as a, H as c, L as d, B as f, G as i, V as l, Y as n, z as o, W as p, X as r, R as s, K as t, I as u };
package/dist/cluster.js CHANGED
@@ -1,2 +1,2 @@
1
- import { a as e, c as t, d as n, f as r, i, l as a, n as o, o as s, p as c, r as l, s as u, t as d, u as f } from "./cluster-CyIyBO39.js";
1
+ import { a as e, c as t, d as n, f as r, i, l as a, n as o, o as s, p as c, r as l, s as u, t as d, u as f } from "./cluster-CVyPUB9X.js";
2
2
  export { e as DEFAULT_RUNNER_LISTEN_PORT, d as activityPrimaryKey, s as detectWsrepCluster, i as makeClusterCronLayer, u as parseShardLockMode, t as pollWorkflowStorage, o as redriveFailedRun, a as resolveFailoverTuning, f as resolveRunnerIdentity, n as resolveRunnerStorage, r as resolveShardLockDisableAdvisory, l as resumeRunFromStep, c as workflowEngineLayer };
@@ -1,6 +1,6 @@
1
- import { E as e, _ as t, h as n, w as r, x as i } from "./primitives-Bp98_F5L.js";
2
- import { i as a } from "./src-CP61KZ9V.js";
3
- import { i as o, p as s } from "./cluster-CyIyBO39.js";
1
+ import { I as e, P as t, S as n, g as r, v as i } from "./primitives-CyQZeT1t.js";
2
+ import { o as a } from "./src-DPkbBZDD.js";
3
+ import { i as o, p as s } from "./cluster-CVyPUB9X.js";
4
4
  import { Cron as c, Deferred as l, Effect as u, Fiber as d, Layer as f, Schema as p } from "effect";
5
5
  import { SqlClient as m } from "@effect/sql";
6
6
  import { beforeAll as h, describe as g, expect as _, test as v } from "vitest";
@@ -59,39 +59,39 @@ var y = async (e, t, n = 750) => {
59
59
  await x(m);
60
60
  }, 3e4), v("a two-step workflow runs end-to-end", async () => {
61
61
  if (!s) return;
62
- let e = `clusterTwoStep_${y}`, n = i({
62
+ let e = `clusterTwoStep_${y}`, t = n({
63
63
  name: e,
64
64
  payload: { id: p.String },
65
65
  success: p.Number,
66
66
  idempotencyKey: ({ id: t }) => `${e}:${t}`
67
- }), r = n.toLayer(() => u.gen(function* () {
68
- let e = yield* t({
67
+ }), r = t.toLayer(() => u.gen(function* () {
68
+ let e = yield* i({
69
69
  name: "first",
70
70
  success: p.Number,
71
71
  execute: u.succeed(40)
72
72
  });
73
- return yield* t({
73
+ return yield* i({
74
74
  name: "second",
75
75
  success: p.Number,
76
76
  execute: u.succeed(e + 2)
77
77
  });
78
78
  }));
79
- _(await u.runPromise(u.scoped(n.execute({ id: `e2e-${y}` }).pipe(u.provide(r.pipe(f.provideMerge(b(m.runnerPort)))))))).toBe(42);
79
+ _(await u.runPromise(u.scoped(t.execute({ id: `e2e-${y}` }).pipe(u.provide(r.pipe(f.provideMerge(b(m.runnerPort)))))))).toBe(42);
80
80
  }, 3e4), v("idempotency-key journal — same payload returns same result", async () => {
81
81
  if (!s) return;
82
- let e = `clusterIdempotency_${y}`, n = 0, r = i({
82
+ let e = `clusterIdempotency_${y}`, t = 0, r = n({
83
83
  name: e,
84
84
  payload: { id: p.String },
85
85
  success: p.Number,
86
86
  idempotencyKey: ({ id: t }) => `${e}:${t}`
87
- }), a = r.toLayer(() => t({
87
+ }), a = r.toLayer(() => i({
88
88
  name: "compute",
89
89
  success: p.Number,
90
- execute: u.sync(() => (n++, n * 100))
90
+ execute: u.sync(() => (t++, t * 100))
91
91
  })).pipe(f.provideMerge(b(m.runnerPort))), [o, c] = await u.runPromise(u.scoped(u.gen(function* () {
92
92
  return [yield* r.execute({ id: `same-${y}` }), yield* r.execute({ id: `same-${y}` })];
93
93
  }).pipe(u.provide(a))));
94
- _(o).toBe(c), _(n).toBe(1);
94
+ _(o).toBe(c), _(t).toBe(1);
95
95
  }, 3e4), v("ClusterCron fires its execute on the shard owner", async () => {
96
96
  if (!s) return;
97
97
  let e = await u.runPromise(l.make()), t = 0, n = o({
@@ -108,32 +108,32 @@ var y = async (e, t, n = 750) => {
108
108
  let g = m.clusterResume ? v : (() => {});
109
109
  g("a sleeping workflow resumes on a fresh runner after the first is torn down", async () => {
110
110
  if (!s) return;
111
- let e = `dormancyResume_${y}`, r = [], a = [], o = [], c = () => i({
111
+ let e = `dormancyResume_${y}`, t = [], a = [], o = [], c = () => n({
112
112
  name: e,
113
113
  payload: { id: p.String },
114
114
  success: p.String,
115
115
  idempotencyKey: ({ id: t }) => `${e}:${t}`
116
- }), l = (e, i) => e.toLayer(() => u.gen(function* () {
117
- return yield* t({
116
+ }), l = (e, n) => e.toLayer(() => u.gen(function* () {
117
+ return yield* i({
118
118
  name: "step1",
119
119
  success: p.Void,
120
120
  execute: u.sync(() => {
121
- r.push(i);
121
+ t.push(n);
122
122
  })
123
- }), yield* t({
123
+ }), yield* i({
124
124
  name: "armed",
125
125
  success: p.Void,
126
126
  execute: u.sync(() => {
127
- o.push(i);
127
+ o.push(n);
128
128
  })
129
- }), yield* n({
129
+ }), yield* r({
130
130
  name: "nap",
131
131
  duration: S
132
- }), yield* t({
132
+ }), yield* i({
133
133
  name: "step2",
134
134
  success: p.Void,
135
135
  execute: u.sync(() => {
136
- a.push(i);
136
+ a.push(n);
137
137
  })
138
138
  }), "done";
139
139
  })), h = m.runnerPort + 2, g = (e) => {
@@ -146,10 +146,10 @@ var y = async (e, t, n = 750) => {
146
146
  let { wf: e, layer: t } = g("A"), n = yield* f.build(t), r = yield* u.forkDaemon(e.execute(v).pipe(u.provide(n), u.ignore));
147
147
  return (yield* w(() => o.length > 0, 6e4)) ? r : yield* u.die(/* @__PURE__ */ Error("runner A never journaled step1"));
148
148
  })));
149
- await u.runPromise(d.interrupt(x).pipe(u.ignore)), _(r).toEqual(["A"]), _(a).toEqual([]), _(await u.runPromise(u.scoped(u.gen(function* () {
149
+ await u.runPromise(d.interrupt(x).pipe(u.ignore)), _(t).toEqual(["A"]), _(a).toEqual([]), _(await u.runPromise(u.scoped(u.gen(function* () {
150
150
  let { wf: e, layer: t } = g("B"), n = yield* f.build(t);
151
151
  return yield* e.execute(v).pipe(u.provide(n), u.timeout("240 seconds"), u.orElseSucceed(() => "TIMEOUT"));
152
- })))).toBe("done"), _(r).toEqual(["A"]), _(a).toEqual(["B"]);
152
+ })))).toBe("done"), _(t).toEqual(["A"]), _(a).toEqual(["B"]);
153
153
  }, 48e4), g("dormancy loop: a wake signal survives teardown and is cleared on resume", async () => {
154
154
  if (!s) return;
155
155
  let o = `dormancyLoop_${y}`, c = `wr_${o}`, l = [], h = /* @__PURE__ */ new Map(), g = a({
@@ -166,27 +166,27 @@ var y = async (e, t, n = 750) => {
166
166
  h.delete(e);
167
167
  }
168
168
  }
169
- }), v = () => i({
169
+ }), v = () => n({
170
170
  name: o,
171
171
  payload: { id: p.String },
172
172
  success: p.String,
173
173
  idempotencyKey: ({ id: e }) => `${o}:${e}`
174
- }), x = (i, a) => i.toLayer(() => u.gen(function* () {
175
- return yield* t({
174
+ }), x = (n, a) => n.toLayer(() => u.gen(function* () {
175
+ return yield* i({
176
176
  name: "step1",
177
177
  success: p.Void,
178
178
  execute: u.void
179
- }), yield* n({
179
+ }), yield* r({
180
180
  name: "nap",
181
181
  duration: C
182
- }), yield* t({
182
+ }), yield* i({
183
183
  name: "step2",
184
184
  success: p.Void,
185
185
  execute: u.sync(() => {
186
186
  l.push(a);
187
187
  })
188
188
  }), "done";
189
- }).pipe(u.locally(r, c), u.provideService(e, g))), S = m.runnerPort + 2, T = (e) => {
189
+ }).pipe(u.locally(t, c), u.provideService(e, g))), S = m.runnerPort + 2, T = (e) => {
190
190
  let t = v();
191
191
  return {
192
192
  wf: t,