@effect/platform-cloudflare 0.0.0 → 4.1.3

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 (237) hide show
  1. package/AGENTS.md +434 -0
  2. package/CLAUDE.md +434 -0
  3. package/LICENSE +21 -0
  4. package/README.md +506 -0
  5. package/ai-docs/README.md +44 -0
  6. package/ai-docs/package.json +36 -0
  7. package/ai-docs/src/01_effect/01_basics/01_effect-gen.ts +30 -0
  8. package/ai-docs/src/01_effect/01_basics/02_effect-fn.ts +52 -0
  9. package/ai-docs/src/01_effect/01_basics/10_creating-effects.ts +74 -0
  10. package/ai-docs/src/01_effect/01_basics/index.md +7 -0
  11. package/ai-docs/src/01_effect/02_schema/10_schema-basics.ts +43 -0
  12. package/ai-docs/src/01_effect/02_schema/index.md +7 -0
  13. package/ai-docs/src/01_effect/03_services/01_service.ts +45 -0
  14. package/ai-docs/src/01_effect/03_services/10_reference.ts +10 -0
  15. package/ai-docs/src/01_effect/03_services/20_layer-composition.ts +70 -0
  16. package/ai-docs/src/01_effect/03_services/20_layer-unwrap.ts +66 -0
  17. package/ai-docs/src/01_effect/03_services/index.md +5 -0
  18. package/ai-docs/src/01_effect/04_errors/01_error-handling.ts +30 -0
  19. package/ai-docs/src/01_effect/04_errors/10_catch-tags.ts +24 -0
  20. package/ai-docs/src/01_effect/04_errors/20_reason-errors.ts +64 -0
  21. package/ai-docs/src/01_effect/04_errors/index.md +1 -0
  22. package/ai-docs/src/01_effect/05_resources/10_acquire-release.ts +105 -0
  23. package/ai-docs/src/01_effect/05_resources/20_layer-side-effects.ts +31 -0
  24. package/ai-docs/src/01_effect/05_resources/30_layer-map.ts +86 -0
  25. package/ai-docs/src/01_effect/05_resources/index.md +3 -0
  26. package/ai-docs/src/01_effect/06_running/10_run-main.ts +30 -0
  27. package/ai-docs/src/01_effect/06_running/20_layer-launch.ts +27 -0
  28. package/ai-docs/src/01_effect/06_running/index.md +1 -0
  29. package/ai-docs/src/01_effect/07_pubsub/10_pubsub.ts +56 -0
  30. package/ai-docs/src/01_effect/07_pubsub/index.md +3 -0
  31. package/ai-docs/src/03_stream/10_creating-streams.ts +103 -0
  32. package/ai-docs/src/03_stream/20_consuming-streams.ts +137 -0
  33. package/ai-docs/src/03_stream/30_encoding.ts +163 -0
  34. package/ai-docs/src/03_stream/index.md +4 -0
  35. package/ai-docs/src/04_integration/10_managed-runtime.ts +129 -0
  36. package/ai-docs/src/04_integration/index.md +5 -0
  37. package/ai-docs/src/05_batching/10_request-resolver.ts +89 -0
  38. package/ai-docs/src/05_batching/index.md +3 -0
  39. package/ai-docs/src/06_schedule/10_schedules.ts +111 -0
  40. package/ai-docs/src/06_schedule/index.md +3 -0
  41. package/ai-docs/src/07_datetime/10_creating-and-formatting.ts +30 -0
  42. package/ai-docs/src/07_datetime/20_time-zones.ts +44 -0
  43. package/ai-docs/src/07_datetime/index.md +5 -0
  44. package/ai-docs/src/08_observability/10_logging.ts +66 -0
  45. package/ai-docs/src/08_observability/20_otlp-tracing.ts +95 -0
  46. package/ai-docs/src/08_observability/index.md +7 -0
  47. package/ai-docs/src/09_testing/10_effect-tests.ts +55 -0
  48. package/ai-docs/src/09_testing/20_layer-tests.ts +138 -0
  49. package/ai-docs/src/09_testing/index.md +1 -0
  50. package/ai-docs/src/10_predicate/01_basics.ts +14 -0
  51. package/ai-docs/src/10_predicate/index.md +9 -0
  52. package/ai-docs/src/40_sql/10_basics.ts +175 -0
  53. package/ai-docs/src/40_sql/index.md +6 -0
  54. package/ai-docs/src/50_http-client/10_basics.ts +102 -0
  55. package/ai-docs/src/50_http-client/index.md +3 -0
  56. package/ai-docs/src/51_http-server/10_basics.ts +118 -0
  57. package/ai-docs/src/51_http-server/20_testing.ts +100 -0
  58. package/ai-docs/src/51_http-server/fixtures/api/Api.ts +14 -0
  59. package/ai-docs/src/51_http-server/fixtures/api/Authorization.ts +36 -0
  60. package/ai-docs/src/51_http-server/fixtures/api/System.ts +10 -0
  61. package/ai-docs/src/51_http-server/fixtures/api/Users.ts +107 -0
  62. package/ai-docs/src/51_http-server/fixtures/domain/User.ts +21 -0
  63. package/ai-docs/src/51_http-server/fixtures/domain/UserErrors.ts +22 -0
  64. package/ai-docs/src/51_http-server/fixtures/server/Authorization.ts +37 -0
  65. package/ai-docs/src/51_http-server/fixtures/server/Users/http.ts +80 -0
  66. package/ai-docs/src/51_http-server/fixtures/server/Users.ts +183 -0
  67. package/ai-docs/src/51_http-server/index.md +3 -0
  68. package/ai-docs/src/52_graphql/10_basics.ts +117 -0
  69. package/ai-docs/src/52_graphql/20_testing.ts +45 -0
  70. package/ai-docs/src/52_graphql/30_batching.ts +118 -0
  71. package/ai-docs/src/52_graphql/40_aliased-batching.ts +124 -0
  72. package/ai-docs/src/52_graphql/50_errors-and-retries.ts +74 -0
  73. package/ai-docs/src/52_graphql/index.md +6 -0
  74. package/ai-docs/src/60_child-process/10_working-with-child-processes.ts +117 -0
  75. package/ai-docs/src/60_child-process/index.md +3 -0
  76. package/ai-docs/src/70_cli/10_basics.ts +162 -0
  77. package/ai-docs/src/70_cli/index.md +5 -0
  78. package/ai-docs/src/71_ai/10_language-model.ts +156 -0
  79. package/ai-docs/src/71_ai/20_tools.ts +226 -0
  80. package/ai-docs/src/71_ai/30_chat.ts +158 -0
  81. package/ai-docs/src/71_ai/fixtures/domain/LaunchPlan.ts +9 -0
  82. package/ai-docs/src/71_ai/index.md +5 -0
  83. package/ai-docs/src/80_cluster/10_entities.ts +97 -0
  84. package/ai-docs/src/80_cluster/index.md +4 -0
  85. package/ai-docs/src/index.md +10 -0
  86. package/ai-docs/tsconfig.json +28 -0
  87. package/dist/AlchemyCloudflareCluster.d.ts +134 -0
  88. package/dist/AlchemyCloudflareCluster.d.ts.map +1 -0
  89. package/dist/AlchemyCloudflareCluster.js +111 -0
  90. package/dist/AlchemyCloudflareCluster.js.map +1 -0
  91. package/dist/CloudflareCluster.d.ts +196 -0
  92. package/dist/CloudflareCluster.d.ts.map +1 -0
  93. package/dist/CloudflareCluster.js +533 -0
  94. package/dist/CloudflareCluster.js.map +1 -0
  95. package/dist/CloudflareDurableObjectPrograms.d.ts +279 -0
  96. package/dist/CloudflareDurableObjectPrograms.d.ts.map +1 -0
  97. package/dist/CloudflareDurableObjectPrograms.js +295 -0
  98. package/dist/CloudflareDurableObjectPrograms.js.map +1 -0
  99. package/dist/CloudflareDurableObjects.d.ts +149 -0
  100. package/dist/CloudflareDurableObjects.d.ts.map +1 -0
  101. package/dist/CloudflareDurableObjects.js +337 -0
  102. package/dist/CloudflareDurableObjects.js.map +1 -0
  103. package/dist/CloudflarePersistedQueue.d.ts +36 -0
  104. package/dist/CloudflarePersistedQueue.d.ts.map +1 -0
  105. package/dist/CloudflarePersistedQueue.js +122 -0
  106. package/dist/CloudflarePersistedQueue.js.map +1 -0
  107. package/dist/CloudflareWorkflowEngine.d.ts +72 -0
  108. package/dist/CloudflareWorkflowEngine.d.ts.map +1 -0
  109. package/dist/CloudflareWorkflowEngine.js +187 -0
  110. package/dist/CloudflareWorkflowEngine.js.map +1 -0
  111. package/dist/index.d.ts +29 -0
  112. package/dist/index.d.ts.map +1 -0
  113. package/dist/index.js +33 -0
  114. package/dist/index.js.map +1 -0
  115. package/dist/internal/alchemyCluster.d.ts +2 -0
  116. package/dist/internal/alchemyCluster.d.ts.map +1 -0
  117. package/dist/internal/alchemyCluster.js +75 -0
  118. package/dist/internal/alchemyCluster.js.map +1 -0
  119. package/dist/internal/boundedMap.d.ts +3 -0
  120. package/dist/internal/boundedMap.d.ts.map +1 -0
  121. package/dist/internal/boundedMap.js +15 -0
  122. package/dist/internal/boundedMap.js.map +1 -0
  123. package/dist/internal/cluster.d.ts +57 -0
  124. package/dist/internal/cluster.d.ts.map +1 -0
  125. package/dist/internal/cluster.js +2 -0
  126. package/dist/internal/cluster.js.map +1 -0
  127. package/dist/internal/clusterName.d.ts +2 -0
  128. package/dist/internal/clusterName.d.ts.map +1 -0
  129. package/dist/internal/clusterName.js +16 -0
  130. package/dist/internal/clusterName.js.map +1 -0
  131. package/dist/internal/entityKeepAlive.d.ts +2 -0
  132. package/dist/internal/entityKeepAlive.d.ts.map +1 -0
  133. package/dist/internal/entityKeepAlive.js +73 -0
  134. package/dist/internal/entityKeepAlive.js.map +1 -0
  135. package/dist/internal/entityMailbox.d.ts +2 -0
  136. package/dist/internal/entityMailbox.d.ts.map +1 -0
  137. package/dist/internal/entityMailbox.js +160 -0
  138. package/dist/internal/entityMailbox.js.map +1 -0
  139. package/dist/internal/entityRegistry.d.ts +16 -0
  140. package/dist/internal/entityRegistry.d.ts.map +1 -0
  141. package/dist/internal/entityRegistry.js +22 -0
  142. package/dist/internal/entityRegistry.js.map +1 -0
  143. package/dist/internal/entityReply.d.ts +2 -0
  144. package/dist/internal/entityReply.d.ts.map +1 -0
  145. package/dist/internal/entityReply.js +35 -0
  146. package/dist/internal/entityReply.js.map +1 -0
  147. package/dist/internal/entityRuntime.d.ts +2 -0
  148. package/dist/internal/entityRuntime.d.ts.map +1 -0
  149. package/dist/internal/entityRuntime.js +823 -0
  150. package/dist/internal/entityRuntime.js.map +1 -0
  151. package/dist/internal/entitySql.d.ts +2 -0
  152. package/dist/internal/entitySql.d.ts.map +1 -0
  153. package/dist/internal/entitySql.js +29 -0
  154. package/dist/internal/entitySql.js.map +1 -0
  155. package/dist/internal/entityStorage.d.ts +2 -0
  156. package/dist/internal/entityStorage.d.ts.map +1 -0
  157. package/dist/internal/entityStorage.js +98 -0
  158. package/dist/internal/entityStorage.js.map +1 -0
  159. package/dist/internal/entityWire.d.ts +2 -0
  160. package/dist/internal/entityWire.d.ts.map +1 -0
  161. package/dist/internal/entityWire.js +146 -0
  162. package/dist/internal/entityWire.js.map +1 -0
  163. package/dist/internal/queueRuntime.d.ts +2 -0
  164. package/dist/internal/queueRuntime.d.ts.map +1 -0
  165. package/dist/internal/queueRuntime.js +88 -0
  166. package/dist/internal/queueRuntime.js.map +1 -0
  167. package/dist/internal/queueStorage.d.ts +2 -0
  168. package/dist/internal/queueStorage.d.ts.map +1 -0
  169. package/dist/internal/queueStorage.js +129 -0
  170. package/dist/internal/queueStorage.js.map +1 -0
  171. package/dist/internal/registry.d.ts +10 -0
  172. package/dist/internal/registry.d.ts.map +1 -0
  173. package/dist/internal/registry.js +24 -0
  174. package/dist/internal/registry.js.map +1 -0
  175. package/dist/internal/singletonRegistry.d.ts +2 -0
  176. package/dist/internal/singletonRegistry.d.ts.map +1 -0
  177. package/dist/internal/singletonRegistry.js +9 -0
  178. package/dist/internal/singletonRegistry.js.map +1 -0
  179. package/dist/internal/singletonRuntime.d.ts +2 -0
  180. package/dist/internal/singletonRuntime.d.ts.map +1 -0
  181. package/dist/internal/singletonRuntime.js +42 -0
  182. package/dist/internal/singletonRuntime.js.map +1 -0
  183. package/dist/internal/singletonStorage.d.ts +2 -0
  184. package/dist/internal/singletonStorage.d.ts.map +1 -0
  185. package/dist/internal/singletonStorage.js +34 -0
  186. package/dist/internal/singletonStorage.js.map +1 -0
  187. package/dist/internal/transport.d.ts +2 -0
  188. package/dist/internal/transport.d.ts.map +1 -0
  189. package/dist/internal/transport.js +49 -0
  190. package/dist/internal/transport.js.map +1 -0
  191. package/dist/internal/workflowRegistry.d.ts +2 -0
  192. package/dist/internal/workflowRegistry.d.ts.map +1 -0
  193. package/dist/internal/workflowRegistry.js +29 -0
  194. package/dist/internal/workflowRegistry.js.map +1 -0
  195. package/dist/internal/workflowRuntime.d.ts +2 -0
  196. package/dist/internal/workflowRuntime.d.ts.map +1 -0
  197. package/dist/internal/workflowRuntime.js +322 -0
  198. package/dist/internal/workflowRuntime.js.map +1 -0
  199. package/dist/internal/workflowStorage.d.ts +2 -0
  200. package/dist/internal/workflowStorage.d.ts.map +1 -0
  201. package/dist/internal/workflowStorage.js +113 -0
  202. package/dist/internal/workflowStorage.js.map +1 -0
  203. package/dist/internal/workflowWire.d.ts +2 -0
  204. package/dist/internal/workflowWire.d.ts.map +1 -0
  205. package/dist/internal/workflowWire.js +52 -0
  206. package/dist/internal/workflowWire.js.map +1 -0
  207. package/package.json +77 -1
  208. package/src/AlchemyCloudflareCluster.ts +200 -0
  209. package/src/CloudflareCluster.ts +704 -0
  210. package/src/CloudflareDurableObjectPrograms.ts +543 -0
  211. package/src/CloudflareDurableObjects.ts +430 -0
  212. package/src/CloudflarePersistedQueue.ts +189 -0
  213. package/src/CloudflareWorkflowEngine.ts +220 -0
  214. package/src/index.ts +38 -0
  215. package/src/internal/alchemyCluster.ts +120 -0
  216. package/src/internal/boundedMap.ts +15 -0
  217. package/src/internal/cluster.ts +57 -0
  218. package/src/internal/clusterName.ts +19 -0
  219. package/src/internal/entityKeepAlive.ts +121 -0
  220. package/src/internal/entityMailbox.ts +324 -0
  221. package/src/internal/entityRegistry.ts +46 -0
  222. package/src/internal/entityReply.ts +54 -0
  223. package/src/internal/entityRuntime.ts +1318 -0
  224. package/src/internal/entitySql.ts +60 -0
  225. package/src/internal/entityStorage.ts +168 -0
  226. package/src/internal/entityWire.ts +204 -0
  227. package/src/internal/queueRuntime.ts +174 -0
  228. package/src/internal/queueStorage.ts +255 -0
  229. package/src/internal/registry.ts +31 -0
  230. package/src/internal/singletonRegistry.ts +21 -0
  231. package/src/internal/singletonRuntime.ts +88 -0
  232. package/src/internal/singletonStorage.ts +64 -0
  233. package/src/internal/transport.ts +67 -0
  234. package/src/internal/workflowRegistry.ts +78 -0
  235. package/src/internal/workflowRuntime.ts +443 -0
  236. package/src/internal/workflowStorage.ts +234 -0
  237. package/src/internal/workflowWire.ts +123 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"queueStorage.js","names":[],"sources":["../../src/internal/queueStorage.ts"],"sourcesContent":[null],"mappings":"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","ignoreList":[]}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * A module-level registration map shared between the Worker layer and the
3
+ * Durable Object instances of the same isolate. Unregistering only removes
4
+ * the exact registration that was added, so a finalizer racing a re-register
5
+ * cannot drop the replacement.
6
+ *
7
+ * @internal
8
+ */
9
+ export {};
10
+ //# sourceMappingURL=registry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/internal/registry.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG"}
@@ -0,0 +1,24 @@
1
+ /**
2
+ * A module-level registration map shared between the Worker layer and the
3
+ * Durable Object instances of the same isolate. Unregistering only removes
4
+ * the exact registration that was added, so a finalizer racing a re-register
5
+ * cannot drop the replacement.
6
+ *
7
+ * @internal
8
+ */
9
+ /** @internal */
10
+ export const makeRegistry = () => {
11
+ const registrations = new Map();
12
+ return {
13
+ get: key => registrations.get(key),
14
+ register: (key, value) => {
15
+ if (registrations.has(key)) return false;
16
+ registrations.set(key, value);
17
+ return true;
18
+ },
19
+ unregister: (key, value) => {
20
+ if (registrations.get(key) === value) registrations.delete(key);
21
+ }
22
+ };
23
+ };
24
+ //# sourceMappingURL=registry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.js","names":[],"sources":["../../src/internal/registry.ts"],"sourcesContent":[null],"mappings":"AAAA;;;;;;;;AAgBA;AACA,OAAO,MAAM,YAAY,GAAG,MAAqB;EAC/C,MAAM,aAAa,GAAG,IAAI,GAAG,EAAa;EAC1C,OAAO;IACL,GAAG,EAAG,GAAG,IAAK,aAAa,CAAC,GAAG,CAAC,GAAG,CAAC;IACpC,QAAQ,EAAE,CAAC,GAAG,EAAE,KAAK,KAAI;MACvB,IAAI,aAAa,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,OAAO,KAAK;MACxC,aAAa,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC;MAC7B,OAAO,IAAI;IACb,CAAC;IACD,UAAU,EAAE,CAAC,GAAG,EAAE,KAAK,KAAI;MACzB,IAAI,aAAa,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,KAAK,EAAE,aAAa,CAAC,MAAM,CAAC,GAAG,CAAC;IACjE;GACD;AACH,CAAC","ignoreList":[]}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=singletonRegistry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"singletonRegistry.d.ts","sourceRoot":"","sources":["../../src/internal/singletonRegistry.ts"],"names":[],"mappings":""}
@@ -0,0 +1,9 @@
1
+ import { makeRegistry } from "./registry.js";
2
+ const registry = /*#__PURE__*/makeRegistry();
3
+ /** @internal */
4
+ export const getSingletonRegistration = registry.get;
5
+ /** @internal */
6
+ export const registerSingleton = registry.register;
7
+ /** @internal */
8
+ export const unregisterSingleton = registry.unregister;
9
+ //# sourceMappingURL=singletonRegistry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"singletonRegistry.js","names":[],"sources":["../../src/internal/singletonRegistry.ts"],"sourcesContent":[null],"mappings":"AAGA,SAAS,YAAY,QAAQ,eAAe;AAQ5C,MAAM,QAAQ,gBAAG,YAAY,EAAyB;AAEtD;AACA,OAAO,MAAM,wBAAwB,GAAwD,QAAQ,CAAC,GAAG;AAEzG;AACA,OAAO,MAAM,iBAAiB,GAAmE,QAAQ,CAAC,QAAQ;AAElH;AACA,OAAO,MAAM,mBAAmB,GAAgE,QAAQ,CAAC,UAAU","ignoreList":[]}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=singletonRuntime.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"singletonRuntime.d.ts","sourceRoot":"","sources":["../../src/internal/singletonRuntime.ts"],"names":[],"mappings":""}
@@ -0,0 +1,42 @@
1
+ import * as Effect from "effect/Effect";
2
+ import { armAlarm } from "./entityStorage.js";
3
+ import { beginSingletonWake, completeSingletonWake, ensureSingletonStorage, loadSingletonState } from "./singletonStorage.js";
4
+ /**
5
+ * How far ahead the watchdog alarm is armed while a wake is running.
6
+ */
7
+ const watchdogMillis = 60_000;
8
+ /** @internal */
9
+ export const makeSingletonRuntime = options => {
10
+ ensureSingletonStorage(options.sql);
11
+ let inFlight;
12
+ const armWatchdog = () => Effect.suspend(() => armAlarm(options.alarm, options.now() + watchdogMillis));
13
+ const runPending = arm => {
14
+ const run = options.run.pipe(Effect.ensuring(Effect.promise(() => options.alarm.deleteAlarm()).pipe(Effect.ensuring(Effect.sync(() => completeSingletonWake(options.sql))))));
15
+ const operation = Effect.runPromise(arm ? Effect.andThen(armWatchdog(), run) : run);
16
+ inFlight = operation;
17
+ void operation.then(() => {
18
+ inFlight = undefined;
19
+ }, () => {
20
+ inFlight = undefined;
21
+ });
22
+ return operation;
23
+ };
24
+ return {
25
+ wake: () => {
26
+ if (inFlight !== undefined) return Promise.resolve();
27
+ const pending = loadSingletonState(options.sql).wakeAt;
28
+ if (pending !== undefined) return runPending(false);
29
+ const now = options.now();
30
+ if (!beginSingletonWake(options.sql, now)) return Promise.resolve();
31
+ return runPending(true);
32
+ },
33
+ // Cloudflare consumes the alarm before invoking this handler, so an alarm
34
+ // that fires during a run must arm the next watchdog before returning.
35
+ runAlarm: () => {
36
+ if (loadSingletonState(options.sql).wakeAt === undefined) return Promise.resolve();
37
+ if (inFlight !== undefined) return Effect.runPromise(armWatchdog());
38
+ return runPending(false);
39
+ }
40
+ };
41
+ };
42
+ //# sourceMappingURL=singletonRuntime.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"singletonRuntime.js","names":[],"sources":["../../src/internal/singletonRuntime.ts"],"sourcesContent":[null],"mappings":"AAYA,OAAO,KAAK,MAAM,MAAM,eAAe;AACvC,SAAS,QAAQ,QAAQ,oBAAoB;AAC7C,SACE,kBAAkB,EAClB,qBAAqB,EACrB,sBAAsB,EACtB,kBAAkB,QACb,uBAAuB;AAE9B;;;AAGA,MAAM,cAAc,GAAG,MAAM;AAgB7B;AACA,OAAO,MAAM,oBAAoB,GAAI,OAAgC,IAAsB;EACzF,sBAAsB,CAAC,OAAO,CAAC,GAAG,CAAC;EACnC,IAAI,QAAmC;EAEvC,MAAM,WAAW,GAAG,MAClB,MAAM,CAAC,OAAO,CAAC,MAAM,QAAQ,CAAC,OAAO,CAAC,KAAK,EAAE,OAAO,CAAC,GAAG,EAAE,GAAG,cAAc,CAAC,CAAC;EAE/E,MAAM,UAAU,GAAI,GAAY,IAAmB;IACjD,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,CAC1B,MAAM,CAAC,QAAQ,CACb,MAAM,CAAC,OAAO,CAAC,MAAM,OAAO,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC,CAAC,IAAI,CACpD,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,qBAAqB,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CACvE,CACF,CACF;IACD,MAAM,SAAS,GAAG,MAAM,CAAC,UAAU,CAAC,GAAG,GAAG,MAAM,CAAC,OAAO,CAAC,WAAW,EAAE,EAAE,GAAG,CAAC,GAAG,GAAG,CAAC;IACnF,QAAQ,GAAG,SAAS;IACpB,KAAK,SAAS,CAAC,IAAI,CACjB,MAAK;MACH,QAAQ,GAAG,SAAS;IACtB,CAAC,EACD,MAAK;MACH,QAAQ,GAAG,SAAS;IACtB,CAAC,CACF;IACD,OAAO,SAAS;EAClB,CAAC;EAED,OAAO;IACL,IAAI,EAAE,MAAK;MACT,IAAI,QAAQ,KAAK,SAAS,EAAE,OAAO,OAAO,CAAC,OAAO,EAAE;MACpD,MAAM,OAAO,GAAG,kBAAkB,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM;MACtD,IAAI,OAAO,KAAK,SAAS,EAAE,OAAO,UAAU,CAAC,KAAK,CAAC;MACnD,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,EAAE;MACzB,IAAI,CAAC,kBAAkB,CAAC,OAAO,CAAC,GAAG,EAAE,GAAG,CAAC,EAAE,OAAO,OAAO,CAAC,OAAO,EAAE;MACnE,OAAO,UAAU,CAAC,IAAI,CAAC;IACzB,CAAC;IAED;IACA;IACA,QAAQ,EAAE,MAAK;MACb,IAAI,kBAAkB,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,KAAK,SAAS,EAAE,OAAO,OAAO,CAAC,OAAO,EAAE;MAClF,IAAI,QAAQ,KAAK,SAAS,EAAE,OAAO,MAAM,CAAC,UAAU,CAAC,WAAW,EAAE,CAAC;MACnE,OAAO,UAAU,CAAC,KAAK,CAAC;IAC1B;GACD;AACH,CAAC","ignoreList":[]}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=singletonStorage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"singletonStorage.d.ts","sourceRoot":"","sources":["../../src/internal/singletonStorage.ts"],"names":[],"mappings":""}
@@ -0,0 +1,34 @@
1
+ const ddl = `CREATE TABLE IF NOT EXISTS singleton_state (
2
+ id INTEGER PRIMARY KEY CHECK (id = 1),
3
+ name TEXT,
4
+ wake_at INTEGER
5
+ )`;
6
+ /** @internal */
7
+ export const ensureSingletonStorage = sql => {
8
+ sql.exec(ddl);
9
+ };
10
+ /** @internal */
11
+ export const loadSingletonState = sql => {
12
+ const row = sql.exec("SELECT name, wake_at FROM singleton_state WHERE id = 1").toArray()[0];
13
+ return {
14
+ name: row?.name ?? undefined,
15
+ wakeAt: row?.wake_at ?? undefined
16
+ };
17
+ };
18
+ /** @internal */
19
+ export const rememberSingletonName = (sql, name) => {
20
+ sql.exec(`INSERT INTO singleton_state (id, name) VALUES (1, ?)
21
+ ON CONFLICT(id) DO UPDATE SET name = excluded.name`, name);
22
+ };
23
+ /** @internal */
24
+ export const beginSingletonWake = (sql, wakeAt) => {
25
+ if (loadSingletonState(sql).wakeAt !== undefined) return false;
26
+ sql.exec(`INSERT INTO singleton_state (id, wake_at) VALUES (1, ?)
27
+ ON CONFLICT(id) DO UPDATE SET wake_at = excluded.wake_at`, wakeAt);
28
+ return true;
29
+ };
30
+ /** @internal */
31
+ export const completeSingletonWake = sql => {
32
+ sql.exec("UPDATE singleton_state SET wake_at = NULL WHERE id = 1");
33
+ };
34
+ //# sourceMappingURL=singletonStorage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"singletonStorage.js","names":[],"sources":["../../src/internal/singletonStorage.ts"],"sourcesContent":[null],"mappings":"AASA,MAAM,GAAG,GAAG;;;;EAIV;AAEF;AACA,OAAO,MAAM,sBAAsB,GAAI,GAAe,IAAU;EAC9D,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC;AACf,CAAC;AAaD;AACA,OAAO,MAAM,kBAAkB,GAAI,GAAe,IAAoB;EACpE,MAAM,GAAG,GAAG,GAAG,CAAC,IAAI,CAAoB,wDAAwD,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;EAC9G,OAAO;IACL,IAAI,EAAE,GAAG,EAAE,IAAI,IAAI,SAAS;IAC5B,MAAM,EAAE,GAAG,EAAE,OAAO,IAAI;GACzB;AACH,CAAC;AAED;AACA,OAAO,MAAM,qBAAqB,GAAG,CAAC,GAAe,EAAE,IAAY,KAAU;EAC3E,GAAG,CAAC,IAAI,CACN;wDACoD,EACpD,IAAI,CACL;AACH,CAAC;AAED;AACA,OAAO,MAAM,kBAAkB,GAAG,CAAC,GAAe,EAAE,MAAc,KAAa;EAC7E,IAAI,kBAAkB,CAAC,GAAG,CAAC,CAAC,MAAM,KAAK,SAAS,EAAE,OAAO,KAAK;EAC9D,GAAG,CAAC,IAAI,CACN;8DAC0D,EAC1D,MAAM,CACP;EACD,OAAO,IAAI;AACb,CAAC;AAED;AACA,OAAO,MAAM,qBAAqB,GAAI,GAAe,IAAU;EAC7D,GAAG,CAAC,IAAI,CAAC,wDAAwD,CAAC;AACpE,CAAC","ignoreList":[]}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=transport.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transport.d.ts","sourceRoot":"","sources":["../../src/internal/transport.ts"],"names":[],"mappings":""}
@@ -0,0 +1,49 @@
1
+ /** @internal */
2
+ import { PersistenceError } from "effect/cluster/ClusterError";
3
+ import * as Effect from "effect/Effect";
4
+ import * as Schedule from "effect/Schedule";
5
+ /**
6
+ * Whether a failed Durable Object call may be retried. Cloudflare marks
7
+ * transient failures `retryable`, and an `overloaded` object must not be
8
+ * retried, as retrying only adds load.
9
+ *
10
+ * @internal
11
+ */
12
+ export const isRetryable = error => {
13
+ const cause = error.cause;
14
+ return typeof cause === "object" && cause !== null && cause.retryable === true && cause.overloaded !== true;
15
+ };
16
+ /**
17
+ * The bounded retry policy for idempotent calls outside a workflow: a few
18
+ * quick attempts, then the caller sees the typed error.
19
+ *
20
+ * @internal
21
+ */
22
+ export const boundedRetry = /*#__PURE__*/Schedule.max([/*#__PURE__*/Schedule.exponential(100, 2), /*#__PURE__*/Schedule.recurs(4)]);
23
+ /**
24
+ * Makes one Worker-to-Durable Object stub call.
25
+ *
26
+ * **Details**
27
+ *
28
+ * A rejection becomes a `PersistenceError` whose `cause` is the rejected
29
+ * value, so Cloudflare's `retryable`, `overloaded` and `remote` flags stay
30
+ * readable. Each attempt resolves a fresh stub with `resolve`, because
31
+ * Cloudflare advises against reusing a stub after it throws. With `retry`, the
32
+ * call is retried on that schedule while the error is retryable; only pass it
33
+ * for idempotent calls.
34
+ *
35
+ * @internal
36
+ */
37
+ export const callDurableObject = options => {
38
+ const attempt = Effect.tryPromise({
39
+ try: () => options.call(options.resolve()),
40
+ catch: cause => new PersistenceError({
41
+ cause
42
+ })
43
+ });
44
+ return options.retry === undefined ? attempt : Effect.retry(attempt, {
45
+ schedule: options.retry,
46
+ while: isRetryable
47
+ });
48
+ };
49
+ //# sourceMappingURL=transport.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transport.js","names":[],"sources":["../../src/internal/transport.ts"],"sourcesContent":[null],"mappings":"AAAA;AACA,SAAS,gBAAgB,QAAQ,6BAA6B;AAC9D,OAAO,KAAK,MAAM,MAAM,eAAe;AACvC,OAAO,KAAK,QAAQ,MAAM,iBAAiB;AAc3C;;;;;;;AAOA,OAAO,MAAM,WAAW,GAAI,KAAuB,IAAa;EAC9D,MAAM,KAAK,GAAG,KAAK,CAAC,KAA+C;EACnE,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,CAAC,SAAS,KAAK,IAAI,IAAI,KAAK,CAAC,UAAU,KAAK,IAAI;AAC7G,CAAC;AAED;;;;;;AAMA,OAAO,MAAM,YAAY,gBAA+B,QAAQ,CAAC,GAAG,CAAC,cACnE,QAAQ,CAAC,WAAW,CAAC,GAAG,EAAE,CAAC,CAAC,eAC5B,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CACnB,CAAC;AAEF;;;;;;;;;;;;;;AAcA,OAAO,MAAM,iBAAiB,GAAa,OAI1C,IAAwC;EACvC,MAAM,OAAO,GAAG,MAAM,CAAC,UAAU,CAAC;IAChC,GAAG,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC;IAC1C,KAAK,EAAG,KAAK,IAAK,IAAI,gBAAgB,CAAC;MAAE;IAAK,CAAE;GACjD,CAAC;EACF,OAAO,OAAO,CAAC,KAAK,KAAK,SAAS,GAC9B,OAAO,GACP,MAAM,CAAC,KAAK,CAAC,OAAO,EAAE;IAAE,QAAQ,EAAE,OAAO,CAAC,KAAK;IAAE,KAAK,EAAE;EAAW,CAAE,CAAC;AAC5E,CAAC","ignoreList":[]}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=workflowRegistry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workflowRegistry.d.ts","sourceRoot":"","sources":["../../src/internal/workflowRegistry.ts"],"names":[],"mappings":""}
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Module-level workflow state shared between the Worker layer and the workflow
3
+ * Durable Object instances of the same isolate. Registrations are recorded at
4
+ * Worker init; a running execution provides its own handle through
5
+ * `CurrentExecutionHandle` so engine operations inside the run hit local
6
+ * SQLite instead of a self-RPC.
7
+ *
8
+ * @internal
9
+ */
10
+ import * as Context from "effect/Context";
11
+ import * as WorkflowEngine from "effect/workflow/WorkflowEngine";
12
+ import { makeRegistry } from "./registry.js";
13
+ const registry = /*#__PURE__*/makeRegistry();
14
+ /** @internal */
15
+ export const getWorkflowRegistration = registry.get;
16
+ /** @internal */
17
+ export const registerWorkflow = registry.register;
18
+ /** @internal */
19
+ export const unregisterWorkflow = registry.unregister;
20
+ /**
21
+ * The handle of the workflow execution currently running in this fiber,
22
+ * provided by the workflow Durable Object runtime around each run attempt.
23
+ *
24
+ * @internal
25
+ */
26
+ export class CurrentExecutionHandle extends /*#__PURE__*/Context.Service()("@effect/platform-cloudflare/CloudflareWorkflowEngine/CurrentExecutionHandle") {}
27
+ /** @internal */
28
+ export const deferredState = /*#__PURE__*/WorkflowEngine.makeDeferredState();
29
+ //# sourceMappingURL=workflowRegistry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workflowRegistry.js","names":[],"sources":["../../src/internal/workflowRegistry.ts"],"sourcesContent":[null],"mappings":"AAAA;;;;;;;;;AASA,OAAO,KAAK,OAAO,MAAM,gBAAgB;AAGzC,OAAO,KAAK,cAAc,MAAM,gCAAgC;AAEhE,SAAS,YAAY,QAAQ,eAAe;AAY5C,MAAM,QAAQ,gBAAG,YAAY,EAAwB;AAErD;AACA,OAAO,MAAM,uBAAuB,GAAuD,QAAQ,CAAC,GAAG;AAEvG;AACA,OAAO,MAAM,gBAAgB,GAAkE,QAAQ,CAAC,QAAQ;AAEhH;AACA,OAAO,MAAM,kBAAkB,GAA+D,QAAQ,CAAC,UAAU;AA+BjH;;;;;;AAMA,OAAM,MAAO,sBAAuB,sBAAQ,OAAO,CAAC,OAAO,EAAmD,CAC5G,6EAA6E,CAC9E;AAED;AACA,OAAO,MAAM,aAAa,gBAAG,cAAc,CAAC,iBAAiB,EAAE","ignoreList":[]}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=workflowRuntime.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workflowRuntime.d.ts","sourceRoot":"","sources":["../../src/internal/workflowRuntime.ts"],"names":[],"mappings":""}
@@ -0,0 +1,322 @@
1
+ import * as Cause from "effect/Cause";
2
+ import * as Context from "effect/Context";
3
+ import * as Duration from "effect/Duration";
4
+ import * as Effect from "effect/Effect";
5
+ import * as Exit from "effect/Exit";
6
+ import * as Fiber from "effect/Fiber";
7
+ import * as Schedule from "effect/Schedule";
8
+ import * as Scope from "effect/Scope";
9
+ import * as DurableClock from "effect/workflow/DurableClock";
10
+ import * as Workflow from "effect/workflow/Workflow";
11
+ import * as WorkflowEngine from "effect/workflow/WorkflowEngine";
12
+ import { decodeName, encodeName } from "./clusterName.js";
13
+ import { armAlarm } from "./entityStorage.js";
14
+ import { CurrentExecutionHandle, deferredState, getWorkflowRegistration } from "./workflowRegistry.js";
15
+ import * as WorkflowStorage from "./workflowStorage.js";
16
+ import { decodePayload, encodeDefectResult, encodeExit, encodeResult } from "./workflowWire.js";
17
+ /** @internal */
18
+ export const InterruptSignalName = "Workflow/InterruptSignal";
19
+ const resumeGuardMillis = 60_000;
20
+ let voidExitCache;
21
+ const voidExitText = () => voidExitCache ??= Effect.runPromise(encodeExit(Exit.void, Context.empty()));
22
+ const mergeWake = (current, mode) => current === "explicit" ? current : mode;
23
+ /** @internal */
24
+ export const makeWorkflowRuntime = options => {
25
+ const name = decodeName(options.name);
26
+ if (name === undefined) {
27
+ throw new Error("ClusterWorkflow requires a canonical workflow Durable Object name");
28
+ }
29
+ const workflowName = name.type;
30
+ const executionId = name.id;
31
+ const sql = options.sql;
32
+ WorkflowStorage.ensureWorkflowStorage(sql);
33
+ let inflight;
34
+ let resumeRequested;
35
+ // Parent of every attempt's scope. As in the memory engine, scopes of
36
+ // attempts that suspended stay open under it, so their finalizers and
37
+ // resources last until the execution completes or an attempt defects.
38
+ let executionScope = Scope.makeUnsafe();
39
+ // The final attempt's scope has already closed with the real exit. Closing
40
+ // the parent closes earlier attempts' scopes in reverse order with
41
+ // `Exit.void`, so their superseded compensations are skipped. A fresh
42
+ // parent is swapped in first: a later replay must not fork from a closed
43
+ // scope, which would run its finalizers as soon as they are registered.
44
+ const closeExecutionScope = Effect.suspend(() => {
45
+ const closing = executionScope;
46
+ executionScope = Scope.makeUnsafe();
47
+ return Scope.close(closing, Exit.void);
48
+ });
49
+ const detach = promise => {
50
+ options.waitUntil(promise.then(() => undefined, () => undefined));
51
+ };
52
+ const parseResult = result => JSON.parse(result);
53
+ const isComplete = result => result !== undefined && parseResult(result)._tag === "Complete";
54
+ // As in the memory engine, only an explicit wake replays a failure suspension.
55
+ const isUnwakeable = (result, mode) => {
56
+ if (result === undefined) return false;
57
+ const parsed = parseResult(result);
58
+ return parsed._tag === "Complete" || mode === "automatic" && parsed.failed === true;
59
+ };
60
+ /**
61
+ * Records a wake durably. A running attempt queues it and decides when it
62
+ * settles, since its result may still become a failure suspension. Returns
63
+ * whether a replay is now pending.
64
+ */
65
+ const requestWake = mode => {
66
+ const row = WorkflowStorage.loadExecution(sql);
67
+ if (row === undefined || isComplete(row.result)) return false;
68
+ if (inflight === undefined && isUnwakeable(row.result, mode)) return false;
69
+ const pending = mergeWake(row.resumePending, mode);
70
+ if (pending !== row.resumePending) WorkflowStorage.setResumePending(sql, pending);
71
+ if (inflight !== undefined) resumeRequested = mergeWake(resumeRequested, mode);
72
+ return true;
73
+ };
74
+ const armResumeGuard = Effect.suspend(() => armAlarm(options.alarm, options.now() + resumeGuardMillis));
75
+ const resumeParent = parent => Effect.promise(() => options.getStub(encodeName(parent.workflowName, parent.executionId)).resume("automatic")).pipe(Effect.sandbox, Effect.retry({
76
+ times: 5,
77
+ schedule: Schedule.exponential(200)
78
+ }));
79
+ const logResumeParentFailure = cause => Effect.logError("Workflow parent resume failed", cause);
80
+ const deliverParentWake = Effect.suspend(() => {
81
+ const row = WorkflowStorage.loadExecution(sql);
82
+ if (row === undefined || row.resumePending === undefined || !isComplete(row.result) || row.parent === undefined) {
83
+ return Effect.void;
84
+ }
85
+ // Re-arm before sending so a crash or exhausted retries leave another attempt.
86
+ return armResumeGuard.pipe(Effect.andThen(resumeParent(row.parent).pipe(Effect.tap(() => Effect.sync(() => WorkflowStorage.setResumePending(sql, undefined))), Effect.catchCause(logResumeParentFailure))));
87
+ });
88
+ // An attempt the machinery cannot finish (a defect with `CaptureDefects`
89
+ // off, a payload that no longer decodes, a result that fails to encode, a
90
+ // dying finalizer, a missing registration) completes the execution with the
91
+ // defect, as `ClusterWorkflowEngine` stores an exhausted defect retry. The
92
+ // object never rejects `run` for such a reason, so a caller can tell the
93
+ // child's own defect from a transport failure, and a parent replaying a
94
+ // discarded child finds the result instead of restarting it.
95
+ const failAttempt = cause => Effect.runPromise(Effect.gen(function* () {
96
+ yield* Effect.logError("Workflow execution failed", cause);
97
+ const text = yield* encodeDefectResult(Cause.squash(cause));
98
+ const parent = WorkflowStorage.loadExecution(sql)?.parent;
99
+ if (parent !== undefined) yield* armResumeGuard;
100
+ WorkflowStorage.saveCompletion(sql, text, parent !== undefined);
101
+ inflight = undefined;
102
+ resumeRequested = undefined;
103
+ if (parent !== undefined) options.waitUntil(Effect.runPromise(deliverParentWake));
104
+ return text;
105
+ }));
106
+ const startAttempt = row => {
107
+ const registration = getWorkflowRegistration(workflowName);
108
+ if (registration === undefined) {
109
+ return failAttempt(Cause.die(new Error(`No workflow registered for name: ${workflowName}`)));
110
+ }
111
+ const workflow = registration.workflow;
112
+ const instance = WorkflowEngine.WorkflowInstance.initial(workflow, executionId, {
113
+ scope: Scope.forkUnsafe(executionScope)
114
+ });
115
+ const execute = decodePayload(workflow, row.payload, registration.context).pipe(Effect.flatMap(payload => registration.execute(payload, executionId)), Effect.onExit(exit => {
116
+ const suspendOnFailure = Context.get(workflow.annotations, Workflow.SuspendOnFailure);
117
+ if (!instance.suspended && !(suspendOnFailure && exit._tag === "Failure")) {
118
+ return Effect.void;
119
+ }
120
+ if (WorkflowStorage.loadDeferred(sql, InterruptSignalName) === undefined) {
121
+ return Effect.void;
122
+ }
123
+ instance.suspended = false;
124
+ instance.interrupted = true;
125
+ return Effect.withFiber(fiber => Effect.interruptible(Fiber.interrupt(fiber)));
126
+ }), Workflow.intoResult, effect => deferredState.trackRun(instance, effect), Effect.flatMap(result => Effect.map(encodeResult(workflow, result, registration.context), text => ({
127
+ result,
128
+ text
129
+ }))), Effect.provideService(DurableClock.InMemoryThreshold, Duration.zero), Effect.provideService(CurrentExecutionHandle, runtime));
130
+ const persist = ({
131
+ result,
132
+ text
133
+ }) => Effect.runPromise(Effect.gen(function* () {
134
+ const parent = WorkflowStorage.loadExecution(sql)?.parent;
135
+ if (result._tag === "Complete" && parent !== undefined) {
136
+ // Arm before the atomic result/pending save so a persisted
137
+ // completion always has a delivery wake.
138
+ yield* armResumeGuard;
139
+ }
140
+ // Stay in flight until the result is saved so a concurrent resume
141
+ // queues behind this attempt instead of replaying alongside it.
142
+ if (result._tag === "Complete") {
143
+ WorkflowStorage.saveCompletion(sql, text, parent !== undefined);
144
+ inflight = undefined;
145
+ resumeRequested = undefined;
146
+ if (parent !== undefined) options.waitUntil(Effect.runPromise(deliverParentWake));
147
+ return text;
148
+ }
149
+ const replay = resumeRequested !== undefined && !isUnwakeable(text, resumeRequested) ? resumeRequested : undefined;
150
+ WorkflowStorage.saveSuspension(sql, text, replay);
151
+ inflight = undefined;
152
+ resumeRequested = undefined;
153
+ if (replay !== undefined) detach(startAttempt(row));
154
+ return text;
155
+ }).pipe(Effect.tapCause(() => Effect.sync(() => {
156
+ inflight = undefined;
157
+ }))));
158
+ const finish = attempt => {
159
+ if (attempt.result._tag !== "Complete") return persist(attempt);
160
+ // Close retained scopes before saving, so a durable completion never
161
+ // has unrun finalizers. A dying finalizer fails the attempt instead.
162
+ return Effect.runPromise(Effect.exit(closeExecutionScope)).then(closed => Exit.isSuccess(closed) ? persist(attempt) : failAttempt(closed.cause));
163
+ };
164
+ const fiber = Effect.runFork(execute);
165
+ const promise = Effect.runPromise(Fiber.await(fiber)).then(exit => {
166
+ if (Exit.isSuccess(exit)) return finish(exit.value);
167
+ if (Cause.hasInterruptsOnly(exit.cause) && (instance.interrupted || instance.suspended)) {
168
+ // A hard interrupt (or a completion preempting the fiber after it
169
+ // already produced its result) kills the fiber before it can encode;
170
+ // synthesize the result from the instance state so it still persists.
171
+ const result = instance.interrupted ? new Workflow.Complete({
172
+ exit: exit
173
+ }) : new Workflow.Suspended({});
174
+ return Effect.runPromise(encodeResult(workflow, result, registration.context)).then(text => finish({
175
+ result,
176
+ text
177
+ }));
178
+ }
179
+ // A defect ends every retained attempt; a replay starts in fresh scopes.
180
+ // Stay in flight while closing so cleanup precedes any replay.
181
+ return Effect.runPromise(Effect.exit(closeExecutionScope)).then(closed => failAttempt(Exit.isSuccess(closed) ? exit.cause : Cause.combine(exit.cause, closed.cause)));
182
+ });
183
+ inflight = {
184
+ instance,
185
+ fiber,
186
+ promise
187
+ };
188
+ return promise;
189
+ };
190
+ const run = (payload, opts) => {
191
+ let row = WorkflowStorage.loadExecution(sql);
192
+ if (row === undefined) {
193
+ WorkflowStorage.createExecution(sql, workflowName, executionId, payload, opts.parent);
194
+ row = {
195
+ workflowName,
196
+ executionId,
197
+ payload,
198
+ parent: opts.parent,
199
+ result: undefined,
200
+ resumePending: undefined
201
+ };
202
+ } else if (opts.parent !== undefined && row.parent === undefined) {
203
+ // An execution started standalone can gain a parent later; keep the
204
+ // first parent so its completion still wakes that parent.
205
+ WorkflowStorage.setParent(sql, opts.parent);
206
+ row = {
207
+ ...row,
208
+ parent: opts.parent
209
+ };
210
+ }
211
+ if (inflight !== undefined) return opts.discard ? Promise.resolve("") : inflight.promise;
212
+ if (row.result !== undefined) return Promise.resolve(opts.discard ? "" : row.result);
213
+ // The attempt stays pending under the guard alarm until it persists a
214
+ // result, so an attempt lost with this object is replayed even when no
215
+ // caller awaits it.
216
+ WorkflowStorage.setResumePending(sql, mergeWake(row.resumePending, "automatic"));
217
+ const attempt = startAttempt(row);
218
+ const armed = Effect.runPromise(armResumeGuard);
219
+ if (opts.discard) {
220
+ detach(attempt);
221
+ return armed.then(() => "");
222
+ }
223
+ return Promise.all([attempt, armed]).then(([text]) => text);
224
+ };
225
+ const startPending = () => {
226
+ const row = WorkflowStorage.loadExecution(sql);
227
+ if (row === undefined || row.resumePending === undefined || inflight !== undefined) return;
228
+ if (isUnwakeable(row.result, row.resumePending)) return;
229
+ detach(startAttempt(row));
230
+ };
231
+ const resume = (mode = "explicit") => {
232
+ if (!requestWake(mode)) return Promise.resolve();
233
+ // Persist and guard the resume before acknowledging it, so an abort after
234
+ // the RPC returns is still recovered.
235
+ return Effect.runPromise(armResumeGuard).then(startPending);
236
+ };
237
+ const completeDeferred = (deferredName, exitText, mode) => {
238
+ if (!WorkflowStorage.saveDeferred(sql, deferredName, exitText)) return Promise.resolve();
239
+ // Persisted with the exit in the same write batch: if this wake is lost
240
+ // before the replay finishes, the next wake (or the guard alarm) replays
241
+ // the execution. The in-flight request is set synchronously so a settling
242
+ // attempt cannot clear the pending resume without a restart.
243
+ if (!requestWake(mode)) return Promise.resolve();
244
+ return Effect.runPromise(armResumeGuard.pipe(Effect.andThen(deferredState.deferredDone(executionId, deferredName)))).then(() => resume(mode));
245
+ };
246
+ const deferredDone = (deferredName, exitText) => completeDeferred(deferredName, exitText, "automatic");
247
+ // The caller belongs to the run this wake interrupts, so awaiting that run
248
+ // would wait on the caller's own cleanup. As in the memory engine, the wake
249
+ // starts on a separate fiber after the caller continues.
250
+ const completeOwnDeferred = (deferredName, exitText) => Effect.suspend(() => {
251
+ if (!WorkflowStorage.saveDeferred(sql, deferredName, exitText) || !requestWake("automatic")) {
252
+ return Effect.void;
253
+ }
254
+ const wake = deferredState.deferredDone(executionId, deferredName).pipe(Effect.andThen(Effect.suspend(() => inflight === undefined ? Effect.promise(() => resume("automatic")) : Effect.void)));
255
+ return armResumeGuard.pipe(Effect.andThen(Effect.forkDetach(wake)), Effect.flatMap(fiber => Effect.sync(() => detach(Effect.runPromise(Fiber.await(fiber))))));
256
+ });
257
+ const interrupt = () => {
258
+ const row = WorkflowStorage.loadExecution(sql);
259
+ if (row === undefined || isComplete(row.result)) return Promise.resolve();
260
+ return voidExitText().then(exitText => completeDeferred(InterruptSignalName, exitText, "explicit"));
261
+ };
262
+ const interruptUnsafe = () => {
263
+ const current = inflight;
264
+ const signalled = interrupt();
265
+ if (current === undefined) return signalled;
266
+ current.instance.interrupted = true;
267
+ return signalled.then(() => Effect.runPromise(Fiber.interrupt(current.fiber))).then(() => undefined);
268
+ };
269
+ const scheduleClock = (clockName, deferredName, wakeUp) => {
270
+ WorkflowStorage.saveClock(sql, clockName, deferredName, wakeUp);
271
+ const earliest = WorkflowStorage.earliestClockWakeUp(sql);
272
+ return earliest === undefined ? Promise.resolve() : Effect.runPromise(armAlarm(options.alarm, earliest));
273
+ };
274
+ const runAlarm = () => voidExitText().then(voidExit => {
275
+ const completed = WorkflowStorage.dueClocks(sql, options.now()).filter(clock => {
276
+ WorkflowStorage.markClockFired(sql, clock.name);
277
+ return WorkflowStorage.saveDeferred(sql, clock.deferredName, voidExit);
278
+ });
279
+ if (completed.length > 0) requestWake("automatic");
280
+ return Effect.runPromise(Effect.forEach(completed, clock => deferredState.deferredDone(executionId, clock.deferredName), {
281
+ discard: true
282
+ })).then(() => {
283
+ const row = WorkflowStorage.loadExecution(sql);
284
+ const mode = row?.resumePending;
285
+ const pending = mode !== undefined && !isUnwakeable(row?.result, mode);
286
+ // A live attempt is not lost: only re-arm the guard. Requesting a wake
287
+ // would replay the attempt once it suspends, for no reason.
288
+ return (pending && inflight === undefined ? resume(mode) : Promise.resolve()).then(() => {
289
+ // While a resume is pending a guard alarm stays armed, so a replay
290
+ // lost with this isolate is retried instead of sleeping forever.
291
+ const targets = [WorkflowStorage.earliestClockWakeUp(sql), pending ? options.now() + resumeGuardMillis : undefined].filter(target => target !== undefined);
292
+ if (targets.length === 0) return undefined;
293
+ // The alarm that fired is spent, so set the next one outright:
294
+ // `armAlarm` only ever moves an alarm earlier.
295
+ return options.alarm.setAlarm(Math.min(...targets));
296
+ });
297
+ });
298
+ }).then(() => Effect.runPromise(deliverParentWake)).then(() => undefined);
299
+ const runtime = {
300
+ executionId,
301
+ run,
302
+ poll: () => Promise.resolve(WorkflowStorage.loadExecution(sql)?.result),
303
+ resume,
304
+ interrupt,
305
+ interruptUnsafe,
306
+ deferredDone,
307
+ scheduleClock,
308
+ runAlarm,
309
+ loadActivity: key => WorkflowStorage.loadActivity(sql, key),
310
+ saveActivity: (key, exit) => WorkflowStorage.saveActivity(sql, key, exit),
311
+ loadDeferred: deferredName => WorkflowStorage.loadDeferred(sql, deferredName),
312
+ completeOwnDeferred
313
+ };
314
+ // Self-heal on wake: a resume recorded by deferredDone but lost with the
315
+ // previous isolate replays now instead of waiting for external contact.
316
+ const pending = WorkflowStorage.loadExecution(sql)?.resumePending;
317
+ if (pending !== undefined) {
318
+ void resume(pending);
319
+ }
320
+ return runtime;
321
+ };
322
+ //# sourceMappingURL=workflowRuntime.js.map