@alchemy.run/effect-cluster 0.0.0 → 2.0.0-beta.87

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 (233) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +101 -4
  3. package/lib/AWS/Database.d.ts +54 -0
  4. package/lib/AWS/Database.d.ts.map +1 -0
  5. package/lib/AWS/Database.js +96 -0
  6. package/lib/AWS/Database.js.map +1 -0
  7. package/lib/AWS/EcsPool.d.ts +56 -0
  8. package/lib/AWS/EcsPool.d.ts.map +1 -0
  9. package/lib/AWS/EcsPool.js +87 -0
  10. package/lib/AWS/EcsPool.js.map +1 -0
  11. package/lib/AWS/index.d.ts +7 -0
  12. package/lib/AWS/index.d.ts.map +1 -0
  13. package/lib/AWS/index.js +7 -0
  14. package/lib/AWS/index.js.map +1 -0
  15. package/lib/AWS/internal/Gateway.d.ts +23 -0
  16. package/lib/AWS/internal/Gateway.d.ts.map +1 -0
  17. package/lib/AWS/internal/Gateway.js +70 -0
  18. package/lib/AWS/internal/Gateway.js.map +1 -0
  19. package/lib/Cloudflare/DurableObjectPool.d.ts +42 -0
  20. package/lib/Cloudflare/DurableObjectPool.d.ts.map +1 -0
  21. package/lib/Cloudflare/DurableObjectPool.js +136 -0
  22. package/lib/Cloudflare/DurableObjectPool.js.map +1 -0
  23. package/lib/Cloudflare/PoolWorker.d.ts +186 -0
  24. package/lib/Cloudflare/PoolWorker.d.ts.map +1 -0
  25. package/lib/Cloudflare/PoolWorker.js +75 -0
  26. package/lib/Cloudflare/PoolWorker.js.map +1 -0
  27. package/lib/Cloudflare/index.d.ts +7 -0
  28. package/lib/Cloudflare/index.d.ts.map +1 -0
  29. package/lib/Cloudflare/index.js +7 -0
  30. package/lib/Cloudflare/index.js.map +1 -0
  31. package/lib/Cloudflare/internal/Objects.d.ts +38 -0
  32. package/lib/Cloudflare/internal/Objects.d.ts.map +1 -0
  33. package/lib/Cloudflare/internal/Objects.js +102 -0
  34. package/lib/Cloudflare/internal/Objects.js.map +1 -0
  35. package/lib/Cron.d.ts +143 -0
  36. package/lib/Cron.d.ts.map +1 -0
  37. package/lib/Cron.js +83 -0
  38. package/lib/Cron.js.map +1 -0
  39. package/lib/Database.d.ts +95 -0
  40. package/lib/Database.d.ts.map +1 -0
  41. package/lib/Database.js +38 -0
  42. package/lib/Database.js.map +1 -0
  43. package/lib/Docker/Database.d.ts +42 -0
  44. package/lib/Docker/Database.d.ts.map +1 -0
  45. package/lib/Docker/Database.js +53 -0
  46. package/lib/Docker/Database.js.map +1 -0
  47. package/lib/Docker/SwarmPool.d.ts +44 -0
  48. package/lib/Docker/SwarmPool.d.ts.map +1 -0
  49. package/lib/Docker/SwarmPool.js +56 -0
  50. package/lib/Docker/SwarmPool.js.map +1 -0
  51. package/lib/Docker/index.d.ts +7 -0
  52. package/lib/Docker/index.d.ts.map +1 -0
  53. package/lib/Docker/index.js +7 -0
  54. package/lib/Docker/index.js.map +1 -0
  55. package/lib/Entity.d.ts +348 -0
  56. package/lib/Entity.d.ts.map +1 -0
  57. package/lib/Entity.js +308 -0
  58. package/lib/Entity.js.map +1 -0
  59. package/lib/Fly/Database.d.ts +50 -0
  60. package/lib/Fly/Database.d.ts.map +1 -0
  61. package/lib/Fly/Database.js +56 -0
  62. package/lib/Fly/Database.js.map +1 -0
  63. package/lib/Fly/MachinePool.d.ts +39 -0
  64. package/lib/Fly/MachinePool.d.ts.map +1 -0
  65. package/lib/Fly/MachinePool.js +51 -0
  66. package/lib/Fly/MachinePool.js.map +1 -0
  67. package/lib/Fly/index.d.ts +7 -0
  68. package/lib/Fly/index.d.ts.map +1 -0
  69. package/lib/Fly/index.js +7 -0
  70. package/lib/Fly/index.js.map +1 -0
  71. package/lib/GCP/ComputeEnginePool.d.ts +41 -0
  72. package/lib/GCP/ComputeEnginePool.d.ts.map +1 -0
  73. package/lib/GCP/ComputeEnginePool.js +172 -0
  74. package/lib/GCP/ComputeEnginePool.js.map +1 -0
  75. package/lib/GCP/Database.d.ts +48 -0
  76. package/lib/GCP/Database.d.ts.map +1 -0
  77. package/lib/GCP/Database.js +115 -0
  78. package/lib/GCP/Database.js.map +1 -0
  79. package/lib/GCP/index.d.ts +7 -0
  80. package/lib/GCP/index.d.ts.map +1 -0
  81. package/lib/GCP/index.js +7 -0
  82. package/lib/GCP/index.js.map +1 -0
  83. package/lib/Hetzner/Database.d.ts +48 -0
  84. package/lib/Hetzner/Database.d.ts.map +1 -0
  85. package/lib/Hetzner/Database.js +91 -0
  86. package/lib/Hetzner/Database.js.map +1 -0
  87. package/lib/Hetzner/ServerPool.d.ts +35 -0
  88. package/lib/Hetzner/ServerPool.d.ts.map +1 -0
  89. package/lib/Hetzner/ServerPool.js +98 -0
  90. package/lib/Hetzner/ServerPool.js.map +1 -0
  91. package/lib/Hetzner/index.d.ts +7 -0
  92. package/lib/Hetzner/index.d.ts.map +1 -0
  93. package/lib/Hetzner/index.js +7 -0
  94. package/lib/Hetzner/index.js.map +1 -0
  95. package/lib/Host.d.ts +60 -0
  96. package/lib/Host.d.ts.map +1 -0
  97. package/lib/Host.js +31 -0
  98. package/lib/Host.js.map +1 -0
  99. package/lib/Kubernetes/Database.d.ts +40 -0
  100. package/lib/Kubernetes/Database.d.ts.map +1 -0
  101. package/lib/Kubernetes/Database.js +56 -0
  102. package/lib/Kubernetes/Database.js.map +1 -0
  103. package/lib/Kubernetes/DeploymentPool.d.ts +54 -0
  104. package/lib/Kubernetes/DeploymentPool.d.ts.map +1 -0
  105. package/lib/Kubernetes/DeploymentPool.js +49 -0
  106. package/lib/Kubernetes/DeploymentPool.js.map +1 -0
  107. package/lib/Kubernetes/index.d.ts +7 -0
  108. package/lib/Kubernetes/index.d.ts.map +1 -0
  109. package/lib/Kubernetes/index.js +7 -0
  110. package/lib/Kubernetes/index.js.map +1 -0
  111. package/lib/Pool.d.ts +66 -0
  112. package/lib/Pool.d.ts.map +1 -0
  113. package/lib/Pool.js +47 -0
  114. package/lib/Pool.js.map +1 -0
  115. package/lib/Providers.d.ts +19 -0
  116. package/lib/Providers.d.ts.map +1 -0
  117. package/lib/Providers.js +31 -0
  118. package/lib/Providers.js.map +1 -0
  119. package/lib/ShardGroups.d.ts +24 -0
  120. package/lib/ShardGroups.d.ts.map +1 -0
  121. package/lib/ShardGroups.js +19 -0
  122. package/lib/ShardGroups.js.map +1 -0
  123. package/lib/Singleton.d.ts +110 -0
  124. package/lib/Singleton.d.ts.map +1 -0
  125. package/lib/Singleton.js +60 -0
  126. package/lib/Singleton.js.map +1 -0
  127. package/lib/Workflow.d.ts +251 -0
  128. package/lib/Workflow.d.ts.map +1 -0
  129. package/lib/Workflow.js +288 -0
  130. package/lib/Workflow.js.map +1 -0
  131. package/lib/index.d.ts +12 -0
  132. package/lib/index.d.ts.map +1 -0
  133. package/lib/index.js +12 -0
  134. package/lib/index.js.map +1 -0
  135. package/lib/internal/Bootstrap.d.ts +28 -0
  136. package/lib/internal/Bootstrap.d.ts.map +1 -0
  137. package/lib/internal/Bootstrap.js +257 -0
  138. package/lib/internal/Bootstrap.js.map +1 -0
  139. package/lib/internal/EntityRuntime.d.ts +40 -0
  140. package/lib/internal/EntityRuntime.d.ts.map +1 -0
  141. package/lib/internal/EntityRuntime.js +698 -0
  142. package/lib/internal/EntityRuntime.js.map +1 -0
  143. package/lib/internal/Gateway.d.ts +82 -0
  144. package/lib/internal/Gateway.d.ts.map +1 -0
  145. package/lib/internal/Gateway.js +219 -0
  146. package/lib/internal/Gateway.js.map +1 -0
  147. package/lib/internal/HostedPlatform.d.ts +36 -0
  148. package/lib/internal/HostedPlatform.d.ts.map +1 -0
  149. package/lib/internal/HostedPlatform.js +36 -0
  150. package/lib/internal/HostedPlatform.js.map +1 -0
  151. package/lib/internal/HostedRuntime.d.ts +58 -0
  152. package/lib/internal/HostedRuntime.d.ts.map +1 -0
  153. package/lib/internal/HostedRuntime.js +72 -0
  154. package/lib/internal/HostedRuntime.js.map +1 -0
  155. package/lib/internal/Naming.d.ts +12 -0
  156. package/lib/internal/Naming.d.ts.map +1 -0
  157. package/lib/internal/Naming.js +40 -0
  158. package/lib/internal/Naming.js.map +1 -0
  159. package/lib/internal/ObjectSharding.d.ts +141 -0
  160. package/lib/internal/ObjectSharding.d.ts.map +1 -0
  161. package/lib/internal/ObjectSharding.js +337 -0
  162. package/lib/internal/ObjectSharding.js.map +1 -0
  163. package/lib/internal/PoolHost.d.ts +80 -0
  164. package/lib/internal/PoolHost.d.ts.map +1 -0
  165. package/lib/internal/PoolHost.js +203 -0
  166. package/lib/internal/PoolHost.js.map +1 -0
  167. package/lib/internal/PoolHostService.d.ts +25 -0
  168. package/lib/internal/PoolHostService.d.ts.map +1 -0
  169. package/lib/internal/PoolHostService.js +10 -0
  170. package/lib/internal/PoolHostService.js.map +1 -0
  171. package/lib/internal/Wire.d.ts +60 -0
  172. package/lib/internal/Wire.d.ts.map +1 -0
  173. package/lib/internal/Wire.js +36 -0
  174. package/lib/internal/Wire.js.map +1 -0
  175. package/lib/internal/WorkflowGateway.d.ts +36 -0
  176. package/lib/internal/WorkflowGateway.d.ts.map +1 -0
  177. package/lib/internal/WorkflowGateway.js +124 -0
  178. package/lib/internal/WorkflowGateway.js.map +1 -0
  179. package/lib/internal/external-runner.d.ts +2 -0
  180. package/lib/internal/external-runner.d.ts.map +1 -0
  181. package/lib/internal/external-runner.js +7 -0
  182. package/lib/internal/external-runner.js.map +1 -0
  183. package/lib/internal/runner.d.ts +2 -0
  184. package/lib/internal/runner.d.ts.map +1 -0
  185. package/lib/internal/runner.js +5 -0
  186. package/lib/internal/runner.js.map +1 -0
  187. package/package.json +128 -3
  188. package/src/AWS/Database.ts +139 -0
  189. package/src/AWS/EcsPool.ts +118 -0
  190. package/src/AWS/index.ts +6 -0
  191. package/src/AWS/internal/Gateway.ts +82 -0
  192. package/src/Cloudflare/DurableObjectPool.ts +198 -0
  193. package/src/Cloudflare/PoolWorker.ts +124 -0
  194. package/src/Cloudflare/index.ts +6 -0
  195. package/src/Cloudflare/internal/Objects.ts +160 -0
  196. package/src/Cron.ts +202 -0
  197. package/src/Database.ts +116 -0
  198. package/src/Docker/Database.ts +94 -0
  199. package/src/Docker/SwarmPool.ts +83 -0
  200. package/src/Docker/index.ts +6 -0
  201. package/src/Entity.ts +621 -0
  202. package/src/Fly/Database.ts +102 -0
  203. package/src/Fly/MachinePool.ts +72 -0
  204. package/src/Fly/index.ts +6 -0
  205. package/src/GCP/ComputeEnginePool.ts +203 -0
  206. package/src/GCP/Database.ts +168 -0
  207. package/src/GCP/index.ts +6 -0
  208. package/src/Hetzner/Database.ts +142 -0
  209. package/src/Hetzner/ServerPool.ts +116 -0
  210. package/src/Hetzner/index.ts +6 -0
  211. package/src/Host.ts +68 -0
  212. package/src/Kubernetes/Database.ts +89 -0
  213. package/src/Kubernetes/DeploymentPool.ts +77 -0
  214. package/src/Kubernetes/index.ts +6 -0
  215. package/src/Pool.ts +104 -0
  216. package/src/Providers.ts +49 -0
  217. package/src/ShardGroups.ts +41 -0
  218. package/src/Singleton.ts +153 -0
  219. package/src/Workflow.ts +556 -0
  220. package/src/index.ts +11 -0
  221. package/src/internal/Bootstrap.ts +368 -0
  222. package/src/internal/EntityRuntime.ts +996 -0
  223. package/src/internal/Gateway.ts +367 -0
  224. package/src/internal/HostedPlatform.ts +83 -0
  225. package/src/internal/HostedRuntime.ts +118 -0
  226. package/src/internal/Naming.ts +44 -0
  227. package/src/internal/ObjectSharding.ts +578 -0
  228. package/src/internal/PoolHost.ts +330 -0
  229. package/src/internal/PoolHostService.ts +25 -0
  230. package/src/internal/Wire.ts +83 -0
  231. package/src/internal/WorkflowGateway.ts +188 -0
  232. package/src/internal/external-runner.ts +10 -0
  233. package/src/internal/runner.ts +5 -0
@@ -0,0 +1,288 @@
1
+ import * as Output from "alchemy/Output";
2
+ import { Platform, } from "alchemy/Platform";
3
+ import * as Provider from "alchemy/Provider";
4
+ import { RuntimeContext, sanitizeKey } from "alchemy/RuntimeContext";
5
+ import { implemented, makeRun, } from "alchemy/Workflows";
6
+ import { ClusterSchema } from "effect/cluster";
7
+ import * as Context from "effect/Context";
8
+ import * as Data from "effect/Data";
9
+ import * as Effect from "effect/Effect";
10
+ import * as Effectable from "effect/Effectable";
11
+ import * as Layer from "effect/Layer";
12
+ import * as Option from "effect/Option";
13
+ import * as Redacted from "effect/Redacted";
14
+ import { Workflow as EffectWorkflow, WorkflowEngine as EffectWorkflowEngine, } from "effect/workflow";
15
+ import { PlatformDeclaration, shardGroupKey } from "./Entity.js";
16
+ import { bindRoute } from "./internal/Gateway.js";
17
+ import { makeHostedRuntimeContext } from "./internal/HostedRuntime.js";
18
+ import { makeRemoteEngine } from "./internal/WorkflowGateway.js";
19
+ export const WorkflowTypeId = "Cluster.Workflow";
20
+ /** The workflow behind each declared resource id, for the runtime context. */
21
+ const workflows = new Map();
22
+ /** Every `Cluster.Workflow` declared, by workflow name, for the engine. */
23
+ const declarations = new Map();
24
+ const platform = Platform(WorkflowTypeId, {
25
+ createRuntimeContext: makeHostedRuntimeContext(WorkflowTypeId, (id, execute, context) => ({
26
+ kind: "workflow",
27
+ workflow: workflows.get(id),
28
+ execute: execute,
29
+ context,
30
+ })),
31
+ });
32
+ /** The resource type behind every workflow, which the providers register. @internal */
33
+ export const WorkflowResource = platform;
34
+ /** The resource id of a workflow: kept apart from an entity of the same name. */
35
+ const resourceId = (name) => `${name}Workflow`;
36
+ /**
37
+ * A durable **Workflow** on an Effect Cluster: each run is a workflow
38
+ * entity, so its activities are persisted, `DurableClock.sleep` is a
39
+ * delayed message, and a run continues on another runner if its runner
40
+ * dies.
41
+ *
42
+ * Declare it like Effect's `Workflow.make`, from a name and its schemas,
43
+ * with its implementation: an Effect that resolves bindings once per runner
44
+ * and returns the handler. Providing a pool Layer to the implementation is
45
+ * what deploys it. Or declare it bare and implement it with
46
+ * `.make(props, impl)`, as a Layer: callers import the bare declaration
47
+ * without bundling the implementation or its pool.
48
+ *
49
+ * `yield* PlaceOrder` from any runtime returns its client: `start` a run,
50
+ * then read, signal or interrupt it.
51
+ *
52
+ * ### Declaring a workflow
53
+ * **Example:** A workflow, with its implementation
54
+ * ```typescript
55
+ * // src/PlaceOrder.ts
56
+ * export default class PlaceOrder extends Cluster.Workflow<PlaceOrder>()(
57
+ * "PlaceOrder",
58
+ * {
59
+ * payload: { orderId: Schema.String },
60
+ * success: Schema.String,
61
+ * idempotencyKey: ({ orderId }) => orderId,
62
+ * },
63
+ * { main: import.meta.url },
64
+ * Effect.gen(function* () {
65
+ * const counters = yield* Counter;
66
+ * return Effect.fn(function* ({ orderId }) {
67
+ * const n = yield* Activity.make({
68
+ * name: "count",
69
+ * success: Schema.Int,
70
+ * execute: Effect.flatMap(counters.getByName("orders"), (counter) =>
71
+ * counter.Increment({ amount: 1 }),
72
+ * ),
73
+ * });
74
+ * return `order ${orderId} is #${n}`;
75
+ * });
76
+ * }).pipe(Effect.provide(Default)),
77
+ * ) {}
78
+ * ```
79
+ *
80
+ * ### Keeping its code out of its callers
81
+ * **Example:** A bare declaration, which callers import
82
+ * ```typescript
83
+ * // src/PlaceOrder.ts
84
+ * export class PlaceOrder extends Cluster.Workflow<PlaceOrder>()("PlaceOrder", {
85
+ * payload: { orderId: Schema.String },
86
+ * success: Schema.String,
87
+ * idempotencyKey: ({ orderId }) => orderId,
88
+ * }) {}
89
+ * ```
90
+ *
91
+ * **Example:** Its implementation, as a Layer, deployed to a pool
92
+ * ```typescript
93
+ * // src/PlaceOrderLive.ts
94
+ * export default PlaceOrder.make(
95
+ * { main: import.meta.url },
96
+ * Effect.gen(function* () {
97
+ * const counters = yield* Counter;
98
+ * return PlaceOrder.of(
99
+ * Effect.fn(function* ({ orderId }) {
100
+ * const n = yield* Activity.make({
101
+ * name: "count",
102
+ * success: Schema.Int,
103
+ * execute: Effect.flatMap(counters.getByName("orders"), (counter) =>
104
+ * counter.Increment({ amount: 1 }),
105
+ * ),
106
+ * });
107
+ * return `order ${orderId} is #${n}`;
108
+ * }),
109
+ * );
110
+ * }).pipe(Effect.provide(Default)),
111
+ * );
112
+ * ```
113
+ *
114
+ * ### Running a workflow
115
+ * **Example:** Start a run from any runtime
116
+ * ```typescript
117
+ * const placeOrder = yield* PlaceOrder;
118
+ * const run = yield* placeOrder.start({ orderId: "o-1" });
119
+ * const status = yield* run.status;
120
+ * ```
121
+ *
122
+ * **Example:** A child workflow, inside another workflow
123
+ * ```typescript
124
+ * const receipt = yield* PlaceOrder.execute({ orderId: "o-1" });
125
+ * ```
126
+ *
127
+ * @resource
128
+ */
129
+ export const Workflow = (() => (name, options, props, impl) => {
130
+ const workflow = EffectWorkflow.make(name, options);
131
+ const id = resourceId(name);
132
+ placeInShardGroup(workflow, id);
133
+ workflows.set(id, workflow);
134
+ const members = {
135
+ LogicalId: name,
136
+ workflow,
137
+ execute: workflow.execute.bind(workflow),
138
+ withCompensation: workflow.withCompensation,
139
+ of: (handler) => handler,
140
+ };
141
+ // With an implementation, the class deploys it, and a runner builds it.
142
+ if (impl !== undefined) {
143
+ const declaration = platform()(id, props, impl);
144
+ declarations.set(name, declaration);
145
+ return Object.assign(class {
146
+ }, members, { [PlatformDeclaration]: declaration }, Effectable.Prototype({
147
+ label: `${WorkflowTypeId}<${name}>`,
148
+ evaluate: () => clientOf(workflow, declaration),
149
+ }));
150
+ }
151
+ const tag = platform()(id);
152
+ declarations.set(name, tag);
153
+ return Object.assign(class {
154
+ }, members, {
155
+ make: (props, impl) => {
156
+ const live = tag.make(props, impl);
157
+ // A runner builds the Platform declaration; the Stack, both.
158
+ return Object.assign(Layer.merge(live, implemented([name])), {
159
+ [PlatformDeclaration]: live,
160
+ });
161
+ },
162
+ }, Effectable.Prototype({
163
+ label: `${WorkflowTypeId}<${name}>`,
164
+ evaluate: () => clientOf(workflow, tag),
165
+ }));
166
+ });
167
+ /**
168
+ * Bind the gateway of the pool that hosts `name` into the current
169
+ * runtime: from its resource while deploying, from the environment at
170
+ * runtime. Undefined outside any runtime.
171
+ */
172
+ const routeOf = (name, declaration) => Effect.gen(function* () {
173
+ const ctx = Option.getOrUndefined(yield* Effect.serviceOption(RuntimeContext));
174
+ if (ctx === undefined)
175
+ return undefined;
176
+ if (!globalThis.__ALCHEMY_RUNTIME__ && declaration === undefined) {
177
+ return yield* Effect.die(new WorkflowNotHosted({ workflow: name }));
178
+ }
179
+ // Built on a memo map of its own, as an entity's client is.
180
+ const resource = globalThis.__ALCHEMY_RUNTIME__
181
+ ? undefined
182
+ : yield* declaration.pipe(Effect.provideServiceEffect(Layer.CurrentMemoMap, Layer.makeMemoMap));
183
+ const bind = (key, value) => ctx
184
+ .set(sanitizeKey(key), Output.isOutput(value) ? value : Output.literal(value))
185
+ .pipe(Effect.flatMap((bound) => ctx.get(bound)));
186
+ const url = yield* bind(`CLUSTER_WORKFLOW_${name}_GATEWAY`, resource?.gateway);
187
+ const token = yield* bind(`CLUSTER_WORKFLOW_${name}_TOKEN`, resource?.token);
188
+ // A Worker calling a gateway Worker reaches it through a service binding.
189
+ const service = sanitizeKey(`CLUSTER_WORKFLOW_${name}_SERVICE`);
190
+ if (!globalThis.__ALCHEMY_RUNTIME__)
191
+ yield* bindRoute(resourceId(name), service);
192
+ return {
193
+ url: url ?? "",
194
+ token: token === undefined ? "" : Redacted.isRedacted(token) ? Redacted.value(token) : token,
195
+ service,
196
+ };
197
+ });
198
+ const unrouted = (name, inRuntime) => Effect.die(inRuntime
199
+ ? new WorkflowNotHosted({ workflow: name })
200
+ : new WorkflowEngineOutsideRuntime({
201
+ message: `Cluster.Workflow '${name}' can only be started inside a runtime.`,
202
+ }));
203
+ /** `yield* PlaceOrder`: its client, over the gateway of the pool that hosts it. */
204
+ const clientOf = (workflow, declaration) => Effect.gen(function* () {
205
+ const target = yield* routeOf(workflow._tag, declaration);
206
+ const engine = makeRemoteEngine(() => target === undefined ? unrouted(workflow._tag, false) : Effect.succeed(target));
207
+ const run = (executionId) => makeRun(engine, workflow, executionId);
208
+ return {
209
+ start: (payload) => workflow
210
+ .execute(payload, { discard: true })
211
+ .pipe(Effect.provideService(EffectWorkflowEngine.WorkflowEngine, engine), Effect.map(run)),
212
+ get: run,
213
+ };
214
+ });
215
+ /**
216
+ * Place a workflow in its pool's shard group, read when a run is routed:
217
+ * the pool that hosts it has the group in their environment, so a child
218
+ * run started on any of them reaches them.
219
+ */
220
+ const placeInShardGroup = (workflow, id) => {
221
+ const key = shardGroupKey(id);
222
+ const self = workflow;
223
+ self.annotations = Context.add(self.annotations, ClusterSchema.ShardGroup, () =>
224
+ // A synchronous lookup at routing time; workerd has no `process`.
225
+ globalThis.process?.env[key] ??
226
+ "default");
227
+ };
228
+ /** A workflow started outside any runtime. */
229
+ export class WorkflowEngineOutsideRuntime extends Data.TaggedError("Cluster.WorkflowEngineOutsideRuntime") {
230
+ }
231
+ /** No `Cluster.Workflow` in the Stack hosts the workflow. */
232
+ export class WorkflowNotHosted extends Data.TaggedError("Cluster.WorkflowNotHosted") {
233
+ }
234
+ /**
235
+ * Run `Cluster.Workflow`s through Alchemy's engine-neutral
236
+ * `Workflows.RunWorkflow`: a `WorkflowEngine` that reaches each workflow
237
+ * through the gateway of the pool that hosts it. Use it for code that
238
+ * runs the same workflow on any engine; otherwise `yield*` the workflow.
239
+ *
240
+ * ### Running workflows on any engine
241
+ * **Example:** `Workflows.RunWorkflow` on the cluster
242
+ * ```typescript
243
+ * Effect.gen(function* () {
244
+ * const placeOrder = yield* Workflows.RunWorkflow(PlaceOrder.workflow);
245
+ * return {
246
+ * fetch: Effect.gen(function* () {
247
+ * const run = yield* placeOrder.start({ orderId: "o-1" });
248
+ * return yield* HttpServerResponse.json(yield* run.status);
249
+ * }),
250
+ * };
251
+ * }).pipe(Effect.provide(Cluster.WorkflowEngine(PlaceOrder)));
252
+ * ```
253
+ *
254
+ * @layer
255
+ * @provides WorkflowEngine
256
+ */
257
+ export const WorkflowEngine = (...runs) => Layer.merge(Layer.effect(EffectWorkflowEngine.WorkflowEngine, Effect.gen(function* () {
258
+ const inRuntime = Option.isSome(yield* Effect.serviceOption(RuntimeContext));
259
+ const routes = new Map();
260
+ for (const { workflow } of runs) {
261
+ const target = yield* routeOf(workflow._tag, declarations.get(workflow._tag));
262
+ if (target !== undefined)
263
+ routes.set(workflow._tag, target);
264
+ }
265
+ return makeRemoteEngine((name) => {
266
+ const target = routes.get(name);
267
+ return target === undefined ? unrouted(name, inRuntime) : Effect.succeed(target);
268
+ });
269
+ })), implemented(runs.map(({ workflow }) => workflow._tag)));
270
+ export const WorkflowProvider = () => Provider.succeed(platform, {
271
+ stables: ["workflow"],
272
+ reconcile: ({ id, bindings }) => Effect.sync(() => {
273
+ const attrs = {
274
+ workflow: id.replace(/Workflow$/, ""),
275
+ pool: undefined,
276
+ gateway: undefined,
277
+ token: undefined,
278
+ };
279
+ for (const { data } of bindings) {
280
+ attrs.pool = data.pool ?? attrs.pool;
281
+ attrs.gateway = data.gateway ?? attrs.gateway;
282
+ attrs.token = data.token ?? attrs.token;
283
+ }
284
+ return attrs;
285
+ }),
286
+ delete: () => Effect.void,
287
+ });
288
+ //# sourceMappingURL=Workflow.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Workflow.js","sources":["../src/Workflow.ts"],"names":[],"mappings":"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"}
package/lib/index.d.ts ADDED
@@ -0,0 +1,12 @@
1
+ /**
2
+ * @alchemy.run/effect-cluster — Effect Cluster entities, with the database
3
+ * they coordinate through and the pool that hosts them on any cloud.
4
+ */
5
+ export * as Database from "./Database.ts";
6
+ export * from "./Entity.ts";
7
+ export * from "./Providers.ts";
8
+ export * from "./Pool.ts";
9
+ export * from "./Workflow.ts";
10
+ export * from "./Singleton.ts";
11
+ export * from "./Cron.ts";
12
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,KAAK,QAAQ,MAAM,eAAe,CAAC;AAC1C,cAAc,aAAa,CAAC;AAC5B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,WAAW,CAAC;AAC1B,cAAc,eAAe,CAAC;AAC9B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,WAAW,CAAC"}
package/lib/index.js ADDED
@@ -0,0 +1,12 @@
1
+ /**
2
+ * @alchemy.run/effect-cluster — Effect Cluster entities, with the database
3
+ * they coordinate through and the pool that hosts them on any cloud.
4
+ */
5
+ export * as Database from "./Database.js";
6
+ export * from "./Entity.js";
7
+ export * from "./Providers.js";
8
+ export * from "./Pool.js";
9
+ export * from "./Workflow.js";
10
+ export * from "./Singleton.js";
11
+ export * from "./Cron.js";
12
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,KAAK,QAAQ,MAAM,eAAe,CAAC;AAC1C,cAAc,aAAa,CAAC;AAC5B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,WAAW,CAAC;AAC1B,cAAc,eAAe,CAAC;AAC9B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,WAAW,CAAC"}
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Run an existing Effect Cluster program as it is, as its own process, with
3
+ * the gateway beside it. The program reads its settings the way Effect
4
+ * Cluster programs do, from its environment, when it loads: `HOST` and
5
+ * `PORT` for the runner's address, `ASSIGNED_SHARD_GROUPS` and
6
+ * `AVAILABLE_SHARD_GROUPS` (`ShardingConfig.layerFromEnv`), and
7
+ * `DATABASE_URL`. The gateway joins the cluster as a client and routes
8
+ * callers to the program's entities.
9
+ */
10
+ export declare const runExternal: (definitions: ReadonlyArray<{
11
+ readonly name: string;
12
+ readonly value: unknown;
13
+ }>, programSource: string) => Promise<void>;
14
+ declare const ExternalProgramExited_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) => import("effect/Cause").YieldableError & {
15
+ readonly _tag: "Cluster.ExternalProgramExited";
16
+ } & Readonly<A>;
17
+ /** The external program a runner runs stopped, so the runner stops too. */
18
+ export declare class ExternalProgramExited extends ExternalProgramExited_base<{
19
+ readonly code: number | null;
20
+ }> {
21
+ }
22
+ /** Build each class's Construction phase, then run the runner until it is stopped. */
23
+ export declare const bootstrap: (definitions: ReadonlyArray<{
24
+ readonly name: string;
25
+ readonly value: unknown;
26
+ }>) => Promise<void>;
27
+ export {};
28
+ //# sourceMappingURL=Bootstrap.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Bootstrap.d.ts","sources":["../../src/internal/Bootstrap.ts"],"names":[],"mappings":"AAmHA;;;;;;;;GAQG;AACH,eAAO,MAAM,WAAW,gBACT,aAAa,CAAC;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAA;CAAE,CAAC,iBAC/D,MAAM,KACpB,OAAO,CAAC,IAAI,CAmDZ,CAAC;;;;AAEJ,2EAA2E;AAC3E,qBAAa,qBAAsB,SAAQ,2BAAkD;IAC3F,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;CAC9B,CAAC;CAAG;AAiBL,sFAAsF;AACtF,eAAO,MAAM,SAAS,gBACP,aAAa,CAAC;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAA;CAAE,CAAC,KAC7E,OAAO,CAAC,IAAI,CAoKd,CAAC"}
@@ -0,0 +1,257 @@
1
+ /**
2
+ * A runner's program: build each entity class's Construction phase, then
3
+ * run every class's instances on Effect Cluster's HTTP runner, with runner
4
+ * registration, shard locks and persisted messages in the cluster's
5
+ * database, and serve the gateway callers reach the entities through.
6
+ *
7
+ * @internal
8
+ */
9
+ import { spawn } from "node:child_process";
10
+ import { lookup } from "node:dns/promises";
11
+ import { createServer } from "node:http";
12
+ import { networkInterfaces } from "node:os";
13
+ import { NodeClusterHttp, NodeHttpServer, NodeServices } from "@effect/platform-node";
14
+ import { PgClient } from "@effect/sql-pg";
15
+ import { reifyBoundConfigProvider } from "alchemy/Runtime";
16
+ import { entrypointLayer, entrypointTag, runProcess, stackFromEnv, } from "alchemy/Runtime/Bootstrap";
17
+ import { ClusterCron, ClusterSchema, ClusterWorkflowEngine, Entity as EffectEntity, RunnerAddress, Singleton, } from "effect/cluster";
18
+ import * as ConfigProvider from "effect/ConfigProvider";
19
+ import * as Context from "effect/Context";
20
+ import * as Data from "effect/Data";
21
+ import * as Effect from "effect/Effect";
22
+ import * as FileSystem from "effect/FileSystem";
23
+ import * as FetchHttpClient from "effect/http/FetchHttpClient";
24
+ import * as HttpClient from "effect/http/HttpClient";
25
+ import * as Layer from "effect/Layer";
26
+ import * as Logger from "effect/Logger";
27
+ import * as Option from "effect/Option";
28
+ import * as Path from "effect/Path";
29
+ import * as Redacted from "effect/Redacted";
30
+ import * as Ref from "effect/Ref";
31
+ import { PlatformDeclaration } from "../Entity.js";
32
+ import { RunnerHost } from "../Host.js";
33
+ import { GATEWAY_PORT, RUNNER_PORT, gatewayLayer } from "./Gateway.js";
34
+ import { HasNoPool } from "./HostedRuntime.js";
35
+ const env = (name) => process.env[name];
36
+ /** Whether an IPv4 address is in a CIDR range (`10.46.0.0/16`). */
37
+ const inIpv4Range = (address, range) => {
38
+ const [base, bits] = range.split("/");
39
+ const toNumber = (ip) => ip.split(".").reduce((total, part) => total * 256 + Number(part), 0);
40
+ if (!/^\d+\.\d+\.\d+\.\d+$/.test(address) || base === undefined)
41
+ return false;
42
+ const size = 2 ** (32 - Number(bits ?? 32));
43
+ return Math.floor(toNumber(address) / size) === Math.floor(toNumber(base) / size);
44
+ };
45
+ /**
46
+ * The address other runners reach this one at: an explicit
47
+ * `CLUSTER_RUNNER_HOST`, else the local address that
48
+ * `CLUSTER_PEERS` (a DNS name every runner resolves to) lists,
49
+ * else the first non-internal IPv4 address.
50
+ */
51
+ const runnerHost = Effect.gen(function* () {
52
+ const explicit = env("CLUSTER_RUNNER_HOST");
53
+ if (explicit)
54
+ return explicit;
55
+ const local = Object.values(networkInterfaces())
56
+ .flat()
57
+ .filter((iface) => iface !== undefined && !iface.internal)
58
+ .map((iface) => iface.address)
59
+ // Link-local addresses (an agent's, a metadata endpoint's) aren't reachable.
60
+ .filter((address) => !address.startsWith("169.254.") && !address.startsWith("fe80:"));
61
+ // On a private network with a known range, the address in it.
62
+ const range = env("CLUSTER_RUNNER_NETWORK");
63
+ if (range) {
64
+ const inRange = local.find((address) => inIpv4Range(address, range));
65
+ if (inRange)
66
+ return inRange;
67
+ }
68
+ // On Fly, the Machine's name on the App's private network.
69
+ const flyMachine = env("FLY_MACHINE_ID");
70
+ const flyApp = env("FLY_APP_NAME");
71
+ if (flyMachine && flyApp)
72
+ return `${flyMachine}.vm.${flyApp}.internal`;
73
+ // On ECS, the task's own address in its VPC.
74
+ const ecsMetadata = env("ECS_CONTAINER_METADATA_URI_V4");
75
+ if (ecsMetadata) {
76
+ const address = yield* HttpClient.get(ecsMetadata).pipe(Effect.flatMap((response) => response.json), Effect.map((metadata) => metadata.Networks?.[0]
77
+ ?.IPv4Addresses?.[0]), Effect.orElseSucceed(() => undefined));
78
+ if (address)
79
+ return address;
80
+ }
81
+ const peers = env("CLUSTER_PEERS");
82
+ if (peers) {
83
+ const resolved = yield* Effect.tryPromise(() => lookup(peers, { all: true })).pipe(Effect.map((addresses) => addresses.map((address) => address.address)), Effect.orElseSucceed(() => []));
84
+ const mine = resolved.find((address) => local.includes(address));
85
+ if (mine)
86
+ return mine;
87
+ }
88
+ return local.find((address) => !address.includes(":")) ?? "127.0.0.1";
89
+ });
90
+ /**
91
+ * Run an existing Effect Cluster program as it is, as its own process, with
92
+ * the gateway beside it. The program reads its settings the way Effect
93
+ * Cluster programs do, from its environment, when it loads: `HOST` and
94
+ * `PORT` for the runner's address, `ASSIGNED_SHARD_GROUPS` and
95
+ * `AVAILABLE_SHARD_GROUPS` (`ShardingConfig.layerFromEnv`), and
96
+ * `DATABASE_URL`. The gateway joins the cluster as a client and routes
97
+ * callers to the program's entities.
98
+ */
99
+ export const runExternal = (definitions, programSource) => runProcess("Effect Cluster runner", Effect.gen(function* () {
100
+ const host = yield* runnerHost;
101
+ const fs = yield* FileSystem.FileSystem;
102
+ const path = yield* Path.Path;
103
+ // The program ships inside the runner; write it out to run it.
104
+ const programDir = yield* fs.makeTempDirectoryScoped({ prefix: "cluster-program-" });
105
+ const programFile = path.join(programDir, "program.mjs");
106
+ yield* fs.writeFileString(programFile, programSource);
107
+ const programEnv = {
108
+ ...process.env,
109
+ HOST: host,
110
+ PORT: String(RUNNER_PORT),
111
+ LISTEN_HOST: env("CLUSTER_LISTEN_HOST") ?? "0.0.0.0",
112
+ DATABASE_URL: env("DATABASE_URL") ?? env("CLUSTER_DATABASE_URL"),
113
+ ASSIGNED_SHARD_GROUPS: env("CLUSTER_SHARD_GROUPS"),
114
+ AVAILABLE_SHARD_GROUPS: env("CLUSTER_AVAILABLE_SHARD_GROUPS"),
115
+ };
116
+ yield* Effect.logInfo(`Effect Cluster runner ${host}:${RUNNER_PORT}: external program`);
117
+ // The program owns this runner: if it stops, so does the runner.
118
+ const child = yield* Effect.sync(() => spawn(process.execPath, [programFile], { env: programEnv, stdio: "inherit" }));
119
+ yield* Effect.addFinalizer(() => Effect.sync(() => child.kill("SIGTERM")));
120
+ const exited = Effect.callback((resume) => {
121
+ child.once("exit", (code) => resume(Effect.fail(new ExternalProgramExited({ code }))));
122
+ });
123
+ // Each definition is the entity's schema (an `RpcGroup`) or an Effect
124
+ // Cluster entity, as the external declaration's `main` exports it.
125
+ const entities = definitions.map(({ name, value }) => EffectEntity.isEntity(value)
126
+ ? value
127
+ : EffectEntity.fromRpcGroup(name, value));
128
+ const cluster = NodeClusterHttp.layer({
129
+ transport: "http",
130
+ storage: "sql",
131
+ clientOnly: true,
132
+ shardingConfig: shardGroupsConfig(),
133
+ }).pipe(Layer.provide(PgClient.layer({ url: Redacted.make(env("CLUSTER_DATABASE_URL")) })));
134
+ const gateway = gatewayLayer(entities, env("CLUSTER_GATEWAY_TOKEN") ?? "").pipe(Layer.provide(NodeHttpServer.layer(createServer, { port: GATEWAY_PORT })));
135
+ return yield* Effect.raceFirst(Layer.launch(gateway.pipe(Layer.provide(cluster))), exited);
136
+ }).pipe(Effect.scoped, Effect.provide(Layer.merge(NodeServices.layer, FetchHttpClient.layer))));
137
+ /** The external program a runner runs stopped, so the runner stops too. */
138
+ export class ExternalProgramExited extends Data.TaggedError("Cluster.ExternalProgramExited") {
139
+ }
140
+ /** The shard groups this pool serves, and every group in the cluster. */
141
+ const shardGroupsConfig = () => {
142
+ const list = (name) => (env(name) ?? "")
143
+ .split(",")
144
+ .map((group) => group.trim())
145
+ .filter((group) => group.length > 0);
146
+ const assigned = list("CLUSTER_SHARD_GROUPS");
147
+ const available = list("CLUSTER_AVAILABLE_SHARD_GROUPS");
148
+ return {
149
+ ...(assigned.length > 0 ? { assignedShardGroups: assigned } : {}),
150
+ ...(available.length > 0 ? { availableShardGroups: available } : {}),
151
+ };
152
+ };
153
+ /** Build each class's Construction phase, then run the runner until it is stopped. */
154
+ export const bootstrap = (definitions) => {
155
+ const entrypoints = definitions.map((definition) => definition.value);
156
+ const platform = Layer.mergeAll(NodeServices.layer, FetchHttpClient.layer, Logger.layer([Logger.consolePretty()])).pipe(Layer.provideMerge(stackFromEnv), Layer.provideMerge(Layer.succeed(ConfigProvider.ConfigProvider, reifyBoundConfigProvider(ConfigProvider.fromEnv(), process.env))));
157
+ const program = Effect.gen(function* () {
158
+ // Every class this runner hosts, and the Layers to launch beside them:
159
+ // its exported classes, and the entities Layers host themselves.
160
+ const hostedRef = yield* Ref.make([]);
161
+ const launchedRef = yield* Ref.make([]);
162
+ const add = (built) => Ref.update(hostedRef, (all) => built.kind === "entity" &&
163
+ all.some((other) => other.kind === "entity" && other.entity.type === built.entity.type)
164
+ ? all
165
+ : [...all, built]);
166
+ const runner = RunnerHost.of({
167
+ host: (entity, layer) => Effect.andThen(add(entity), Ref.update(launchedRef, (all) => [...all, layer])),
168
+ });
169
+ for (const entrypoint of entrypoints) {
170
+ const declaration = entrypoint?.[PlatformDeclaration] ??
171
+ entrypoint;
172
+ const context = yield* Layer.build(entrypointLayer(declaration)).pipe(Effect.provideService(RunnerHost, runner));
173
+ // A Layer that hosts its entities itself (a Domain model's) provides
174
+ // none: it handed them to `RunnerHost`.
175
+ const self = Context.getOption(context, entrypointTag);
176
+ if (Option.isNone(self))
177
+ continue;
178
+ const runtime = self.value.RuntimeContext;
179
+ const built = runtime.hosted();
180
+ if (built === undefined) {
181
+ return yield* Effect.die(new HasNoPool({
182
+ message: `${runtime.Type} '${runtime.id}' did not finish its Construction phase.`,
183
+ }));
184
+ }
185
+ yield* add(built);
186
+ }
187
+ const hosted = yield* Ref.get(hostedRef);
188
+ const launched = yield* Ref.get(launchedRef);
189
+ const host = yield* runnerHost;
190
+ const group = env("CLUSTER_SHARD_GROUPS") ?? "default";
191
+ // Every hosted entity lives in this pool's own shard group.
192
+ const placed = hosted
193
+ .filter((entry) => entry.kind === "entity")
194
+ .map((entry) => ({
195
+ ...entry,
196
+ entity: entry.entity.annotate(ClusterSchema.ShardGroup, () => group),
197
+ }));
198
+ const workflows = hosted.filter((entry) => entry.kind === "workflow");
199
+ // Each workflow runs its handler with the services its Construction phase had.
200
+ const workflowLayers = workflows.map((entry) => entry.workflow.toLayer((payload, executionId) => Effect.provide(entry.execute(payload, executionId), entry.context)));
201
+ const entityLayers = placed.map((entry) => entry.entity
202
+ .toLayer(
203
+ // The instance phase runs with the services its Construction phase had.
204
+ Effect.provide(entry.instance, entry.context), {
205
+ maxIdleTime: entry.options.maxIdleTime,
206
+ concurrency: entry.options.concurrency,
207
+ mailboxCapacity: entry.options.mailboxCapacity,
208
+ disableFatalDefects: entry.options.disableFatalDefects,
209
+ })
210
+ // So does the entity itself: its RPCs' middleware is provided to its Layer.
211
+ .pipe(Layer.provide(Layer.succeedContext(entry.context))));
212
+ const cluster = NodeClusterHttp.layer({
213
+ transport: "http",
214
+ storage: "sql",
215
+ shardingConfig: {
216
+ runnerAddress: Option.some(RunnerAddress.make(host, RUNNER_PORT)),
217
+ // Fly's private network is IPv6 only.
218
+ runnerListenAddress: Option.some(RunnerAddress.make(env("CLUSTER_LISTEN_HOST") ?? "0.0.0.0", RUNNER_PORT)),
219
+ ...shardGroupsConfig(),
220
+ },
221
+ }).pipe(Layer.provide(PgClient.layer({ url: Redacted.make(env("CLUSTER_DATABASE_URL")) })));
222
+ // Singletons and crons run in this pool's shard group too, each with
223
+ // the services its Construction phase had.
224
+ const scheduled = hosted.flatMap((entry) => entry.kind === "singleton"
225
+ ? [
226
+ Singleton.make(entry.name, Effect.provide(entry.run, entry.context), {
227
+ shardGroup: group,
228
+ }),
229
+ ]
230
+ : entry.kind === "cron"
231
+ ? [
232
+ ClusterCron.make({
233
+ name: entry.name,
234
+ cron: entry.cron,
235
+ execute: Effect.provide(entry.run, entry.context),
236
+ shardGroup: group,
237
+ ...entry.options,
238
+ }),
239
+ ]
240
+ : []);
241
+ const gateway = gatewayLayer(placed.map((entry) => entry.entity), env("CLUSTER_GATEWAY_TOKEN") ?? "", new Map(workflows.map((entry) => [entry.workflow._tag, entry.workflow]))).pipe(Layer.provide(NodeHttpServer.layer(createServer, { port: GATEWAY_PORT })));
242
+ yield* Effect.logInfo(`Effect Cluster runner ${host}:${RUNNER_PORT}: ${hosted
243
+ .map((entry) => entry.kind === "entity"
244
+ ? entry.entity.type
245
+ : entry.kind === "workflow"
246
+ ? entry.workflow._tag
247
+ : `${entry.kind} ${entry.name}`)
248
+ .join(", ")}`);
249
+ return yield* Layer.launch(Layer.mergeAll(...entityLayers, ...workflowLayers, ...scheduled,
250
+ // What the classes' Construction phases handed the runner.
251
+ ...launched, gateway).pipe(
252
+ // Workflows run on Effect Cluster's own engine, over the cluster.
253
+ Layer.provide(ClusterWorkflowEngine.layer), Layer.provide(cluster)));
254
+ }).pipe(Effect.provide(platform), Effect.scoped);
255
+ return runProcess("Effect Cluster runner", program);
256
+ };
257
+ //# sourceMappingURL=Bootstrap.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Bootstrap.js","sources":["../../src/internal/Bootstrap.ts"],"names":[],"mappings":"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"}