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

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 +218 -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 +366 -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,12 @@
1
+ import { Stack } from "alchemy/Stack";
2
+ import * as Effect from "effect/Effect";
3
+ /** The resource types a pool hosts. */
4
+ export declare const HOSTED_TYPES: Set<string>;
5
+ /**
6
+ * `${stack}-${stage}-${id}` as a lowercase DNS label of at most `max`
7
+ * characters. A longer one keeps its start and ends in a hash of the whole.
8
+ */
9
+ export declare const stackDnsLabel: (id: string, max?: any) => Effect.Effect<string, never, Stack>;
10
+ /** `id` as a lowercase label of at most `max` characters, ending in a hash when shortened. */
11
+ export declare const shortLabel: (id: string, max: number) => Effect.Effect<string, never, never>;
12
+ //# sourceMappingURL=Naming.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Naming.d.ts","sources":["../../src/internal/Naming.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AACtC,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AAGxC,uCAAuC;AACvC,eAAO,MAAM,YAAY,aAKvB,CAAC;AAeH;;;GAGG;AACH,eAAO,MAAM,aAAa,gEAGxB,CAAC;AAEH,8FAA8F;AAC9F,eAAO,MAAM,UAAU,OAAQ,MAAM,OAAO,MAAM,wCAAqB,CAAC"}
@@ -0,0 +1,40 @@
1
+ /**
2
+ * Names every pool Layer shares, kept apart from the bundling in
3
+ * `PoolHost.ts` so a runtime that bundles a pool Layer (a Worker) never
4
+ * pulls in the bundler.
5
+ *
6
+ * @internal
7
+ */
8
+ import { createHash } from "node:crypto";
9
+ import { Stack } from "alchemy/Stack";
10
+ import * as Effect from "effect/Effect";
11
+ import { EntityTypeId } from "../Entity.js";
12
+ /** The resource types a pool hosts. */
13
+ export const HOSTED_TYPES = new Set([
14
+ EntityTypeId,
15
+ "Cluster.Workflow",
16
+ "Cluster.Singleton",
17
+ "Cluster.Cron",
18
+ ]);
19
+ /** `label` as a lowercase name of at most `max` characters, ending in a hash when shortened. */
20
+ const shorten = Effect.fn(function* (label, max) {
21
+ const clean = label
22
+ .toLowerCase()
23
+ .replace(/[^a-z0-9-]+/g, "-")
24
+ .replace(/^-+|-+$/g, "");
25
+ if (clean.length <= max)
26
+ return clean;
27
+ const hash = yield* Effect.sync(() => createHash("sha256").update(clean).digest("hex").slice(0, 8));
28
+ return `${clean.slice(0, max - 9).replace(/-+$/, "")}-${hash}`;
29
+ });
30
+ /**
31
+ * `${stack}-${stage}-${id}` as a lowercase DNS label of at most `max`
32
+ * characters. A longer one keeps its start and ends in a hash of the whole.
33
+ */
34
+ export const stackDnsLabel = Effect.fn(function* (id, max = 63) {
35
+ const stack = yield* Stack;
36
+ return yield* shorten(`${stack.name}-${stack.stage}-${id}`, max);
37
+ });
38
+ /** `id` as a lowercase label of at most `max` characters, ending in a hash when shortened. */
39
+ export const shortLabel = (id, max) => shorten(id, max);
40
+ //# sourceMappingURL=Naming.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Naming.js","sources":["../../src/internal/Naming.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AACtC,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AACxC,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAE5C,uCAAuC;AACvC,MAAM,CAAC,MAAM,YAAY,GAAG,IAAI,GAAG,CAAS;IAC1C,YAAY;IACZ,kBAAkB;IAClB,mBAAmB;IACnB,cAAc;CACf,CAAC,CAAC;AAEH,gGAAgG;AAChG,MAAM,OAAO,GAAG,MAAM,CAAC,EAAE,CAAC,QAAQ,CAAC,EAAE,KAAa,EAAE,GAAW;IAC7D,MAAM,KAAK,GAAG,KAAK;SAChB,WAAW,EAAE;SACb,OAAO,CAAC,cAAc,EAAE,GAAG,CAAC;SAC5B,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;IAC3B,IAAI,KAAK,CAAC,MAAM,IAAI,GAAG;QAAE,OAAO,KAAK,CAAC;IACtC,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,CACnC,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAC7D,CAAC;IACF,OAAO,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,IAAI,IAAI,EAAE,CAAC;AACjE,CAAC,CAAC,CAAC;AAEH;;;GAGG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG,MAAM,CAAC,EAAE,CAAC,QAAQ,CAAC,EAAE,EAAU,EAAE,GAAG,GAAG,EAAE;IACpE,MAAM,KAAK,GAAG,KAAK,CAAC,CAAC,KAAK,CAAC;IAC3B,OAAO,KAAK,CAAC,CAAC,OAAO,CAAC,GAAG,KAAK,CAAC,IAAI,IAAI,KAAK,CAAC,KAAK,IAAI,EAAE,EAAE,EAAE,GAAG,CAAC,CAAC;AACnE,CAAC,CAAC,CAAC;AAEH,8FAA8F;AAC9F,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,EAAU,EAAE,GAAW,EAAE,EAAE,CAAC,OAAO,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC"}
@@ -0,0 +1,141 @@
1
+ import type { RuntimeContext } from "alchemy/RuntimeContext";
2
+ import type { ObjectImpl } from "alchemy/Workers/DurableObjectEngine";
3
+ import * as Cause from "effect/Cause";
4
+ import { type Entity as EffectEntity, Sharding } from "effect/cluster";
5
+ import * as Context from "effect/Context";
6
+ import * as Effect from "effect/Effect";
7
+ import * as Layer from "effect/Layer";
8
+ import { type Rpc } from "effect/rpc";
9
+ import type * as Scope from "effect/Scope";
10
+ import * as Stream from "effect/Stream";
11
+ import type { WorkflowEngine } from "effect/workflow";
12
+ import type { HostedCron } from "../Cron.ts";
13
+ import { type HostedEntity } from "../Entity.ts";
14
+ import type { HostedSingleton } from "../Singleton.ts";
15
+ import type { HostedWorkflow } from "../Workflow.ts";
16
+ import { type EntityStorage } from "./EntityRuntime.ts";
17
+ type AnyEntity = EffectEntity.Entity<string, Rpc.Any>;
18
+ declare const NotHosted_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]; }>) => Cause.YieldableError & {
19
+ readonly _tag: "Cluster.NotHosted";
20
+ } & Readonly<A>;
21
+ /** A class this pool hosts was asked for, but nothing registered it. */
22
+ export declare class NotHosted extends NotHosted_base<{
23
+ readonly message: string;
24
+ }> {
25
+ }
26
+ /**
27
+ * What a pool's process registers, for its objects to run: each object reads
28
+ * the class it runs from here when it is constructed.
29
+ */
30
+ export declare const registry: {
31
+ entities: Map<string, HostedEntity>;
32
+ scheduled: Map<string, HostedCron | HostedSingleton>;
33
+ workflows: Map<string, ObjectImpl<unknown>>;
34
+ sharding: Sharding.Sharding["Service"] | undefined;
35
+ };
36
+ /** The object a workflow execution runs in: `${class}:${executionId}`. */
37
+ export declare const workflowObjectName: (className: string, executionId: string) => string;
38
+ /** The workflow class an object named by {@link workflowObjectName} runs. */
39
+ export declare const workflowClassOf: (objectName: string) => string;
40
+ /** The object a singleton or cron runs in: `singleton:${name}` or `cron:${name}`. */
41
+ export declare const scheduledObjectName: (kind: "singleton" | "cron", name: string) => string;
42
+ /** Answer a defect as data, since an object's caller can't be sent a cause. */
43
+ export declare const reportDefects: <A, E, R>(effect: Effect.Effect<A, E, R>) => Effect.Effect<A, never, R>;
44
+ /** What an entity's object answers: calls and replies as JSON text. */
45
+ export interface EntityObjectStub {
46
+ readonly ask: (call: string) => Effect.Effect<string, unknown>;
47
+ readonly tell: (call: string) => Effect.Effect<string, unknown>;
48
+ readonly stream: (call: string) => Stream.Stream<string, unknown>;
49
+ readonly interrupt: (requestId: string) => Effect.Effect<void, unknown>;
50
+ }
51
+ /** What a singleton's or cron's object answers. */
52
+ export interface ScheduledObjectStub {
53
+ readonly ensure: () => Effect.Effect<void, unknown>;
54
+ }
55
+ export interface Namespace<Stub> {
56
+ readonly getByName: (name: string) => Stub;
57
+ }
58
+ /** What differs between the hosts whose objects back a cluster. */
59
+ export interface ObjectHost {
60
+ /** The shard group every address on this host is in: the host's name. */
61
+ readonly group: string;
62
+ /**
63
+ * Whether a failed call to an object can be sent again: the host knows a
64
+ * transient failure from one the object answered with.
65
+ */
66
+ readonly isRetryable: (error: unknown) => boolean;
67
+ }
68
+ /**
69
+ * A client for one entity instance: each RPC is sent to the entity's object
70
+ * and answered by it, with the caller's headers, as Effect Cluster's own
71
+ * client sends it to the runner that owns the entity.
72
+ *
73
+ * A call the object never answered fails with `PersistenceError`; a
74
+ * persisted one is sent again first, to a fresh stub, since the object
75
+ * stores it under the same request id and runs it once. Interrupting a call
76
+ * interrupts its handler.
77
+ */
78
+ export declare const clientOf: (entity: AnyEntity, entityId: string, objects: () => Namespace<EntityObjectStub>, host: ObjectHost,
79
+ /** Whether the pool hosts the entity: checked before any object is woken. */
80
+ hosts?: (type: string) => boolean) => Record<string, unknown>;
81
+ /** `Sharding` for a process whose entities are durable objects. */
82
+ export declare const makeObjectSharding: (objects: () => Namespace<EntityObjectStub>, host: ObjectHost) => Sharding.Sharding["Service"];
83
+ /**
84
+ * One entity instance, in the object named `name`: the instance runs as
85
+ * Effect Cluster's runners run it (see `EntityRuntime.ts`), and answers its
86
+ * callers in JSON text.
87
+ */
88
+ export declare const makeEntityObject: (options: {
89
+ readonly name: string;
90
+ readonly host: ObjectHost;
91
+ readonly storage: EntityStorage;
92
+ /** The object's own services, which its handlers run with. */
93
+ readonly runtime: Context.Context<RuntimeContext>;
94
+ readonly maxEncodedBytes?: number;
95
+ readonly waitUntil: (effect: Effect.Effect<unknown>) => Effect.Effect<void>;
96
+ }) => Effect.Effect<{
97
+ ask: (message: string) => Effect.Effect<string, never, never>;
98
+ tell: (message: string) => Effect.Effect<string, never, never>;
99
+ stream: (message: string) => Stream.Stream<string, never, never>;
100
+ interrupt: (requestId: string) => Effect.Effect<void, never, never>;
101
+ alarm: () => Effect.Effect<void, never, never>;
102
+ }, never, never>;
103
+ /**
104
+ * One singleton or cron, in the object named `name`, kept awake by its
105
+ * alarm. A singleton's object runs its fiber and checks on it every few
106
+ * seconds, restarting it if its object was restarted; a cron's object wakes
107
+ * at each scheduled time and runs the job once.
108
+ */
109
+ export declare const makeScheduledObject: (options: {
110
+ readonly name: string;
111
+ readonly storage: Pick<EntityStorage, "exec" | "setAlarm">;
112
+ readonly runtime: Context.Context<RuntimeContext>;
113
+ }) => Effect.Effect<{
114
+ ensure: () => Effect.Effect<void, never, never>;
115
+ alarm: () => Effect.Effect<void, never, never>;
116
+ }, never, never>;
117
+ /** Wake every singleton and cron, so their objects start their alarms. */
118
+ export declare const wakeScheduled: (objects: Namespace<ScheduledObjectStub>) => Effect.Effect<void, never, never>;
119
+ /** A class the pool hosts: its name, and its module's export. */
120
+ export interface HostedDefinition {
121
+ readonly name: string;
122
+ readonly value: unknown;
123
+ }
124
+ /**
125
+ * Build every class a pool hosts and register it for the pool's objects:
126
+ * entities, singletons and crons by name, and each workflow on `engine`,
127
+ * whose executions are objects too. Runs once per process, in `scope`.
128
+ */
129
+ export declare const hostClasses: (options: {
130
+ readonly definitions: ReadonlyArray<HostedDefinition>;
131
+ readonly scope: Scope.Scope;
132
+ readonly sharding: Sharding.Sharding["Service"];
133
+ /** The workflow engine, which registers each workflow's class in {@link registry}. */
134
+ readonly engine: Layer.Layer<WorkflowEngine.WorkflowEngine>;
135
+ }) => Effect.Effect<{
136
+ entities: HostedEntity[];
137
+ workflows: HostedWorkflow[];
138
+ services: Context.Context<Sharding.Sharding | WorkflowEngine.WorkflowEngine>;
139
+ }, import("effect/Config").ConfigError, any>;
140
+ export {};
141
+ //# sourceMappingURL=ObjectSharding.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ObjectSharding.d.ts","sources":["../../src/internal/ObjectSharding.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,337 @@
1
+ /**
2
+ * Effect Cluster on durable objects, in Effect's shape: there are no shards
3
+ * or runners to place an instance on, because a durable object (a Cloudflare
4
+ * Durable Object, a Rivet actor) already is one instance per name. Every
5
+ * entity instance is the object named by its `(type, id)`, every workflow
6
+ * execution the object named by its `(workflow, execution)`, every singleton
7
+ * and cron the object named after it.
8
+ *
9
+ * `Sharding` is the seam: Effect Cluster's own client (`Entity.client`), the
10
+ * gateway and one entity calling another all ask it for a client, and this
11
+ * one sends each call to the entity's object. A host supplies the objects:
12
+ * their storage and alarm, and stubs to call them by name.
13
+ *
14
+ * @internal
15
+ */
16
+ import { makeEntrypointLayer } from "alchemy/Runtime";
17
+ import { stackFromEnv } from "alchemy/Runtime/Bootstrap";
18
+ import { Self } from "alchemy/Self";
19
+ import * as Cause from "effect/Cause";
20
+ import * as Clock from "effect/Clock";
21
+ import { ClusterCron, ClusterSchema, EntityAddress, EntityId, EntityType, RunnerAddress, Sharding, ShardId, Snowflake, } from "effect/cluster";
22
+ import { AlreadyProcessingMessage, MailboxFull, PersistenceError, } from "effect/cluster/ClusterError";
23
+ import * as Context from "effect/Context";
24
+ import * as Cron from "effect/Cron";
25
+ import * as SecureRandom from "effect/crypto/SecureRandom";
26
+ import * as Data from "effect/Data";
27
+ import * as DateTime from "effect/DateTime";
28
+ import * as Duration from "effect/Duration";
29
+ import * as Effect from "effect/Effect";
30
+ import * as Exit from "effect/Exit";
31
+ import * as FetchHttpClient from "effect/http/FetchHttpClient";
32
+ import * as Headers from "effect/http/Headers";
33
+ import * as Layer from "effect/Layer";
34
+ import * as Option from "effect/Option";
35
+ import { RpcClient, RpcSchema } from "effect/rpc";
36
+ import * as Schedule from "effect/Schedule";
37
+ import * as Stream from "effect/Stream";
38
+ import { PlatformDeclaration } from "../Entity.js";
39
+ import { RunnerHost } from "../Host.js";
40
+ import { makeEntityRuntime } from "./EntityRuntime.js";
41
+ import { HasNoPool } from "./HostedRuntime.js";
42
+ import { chunkCodec, DEFECT, decode, encode, entityObjectName, exitCodec, parseEntityObjectName, payloadCodec, } from "./Wire.js";
43
+ /** A class this pool hosts was asked for, but nothing registered it. */
44
+ export class NotHosted extends Data.TaggedError("Cluster.NotHosted") {
45
+ }
46
+ /**
47
+ * What a pool's process registers, for its objects to run: each object reads
48
+ * the class it runs from here when it is constructed.
49
+ */
50
+ export const registry = {
51
+ entities: new Map(),
52
+ scheduled: new Map(),
53
+ workflows: new Map(),
54
+ sharding: undefined,
55
+ };
56
+ // ---------------------------------------------------------------- names
57
+ /** The object a workflow execution runs in: `${class}:${executionId}`. */
58
+ export const workflowObjectName = (className, executionId) => `${className}:${executionId}`;
59
+ /** The workflow class an object named by {@link workflowObjectName} runs. */
60
+ export const workflowClassOf = (objectName) => objectName.slice(0, objectName.indexOf(":"));
61
+ /** The object a singleton or cron runs in: `singleton:${name}` or `cron:${name}`. */
62
+ export const scheduledObjectName = (kind, name) => `${kind}:${name}`;
63
+ // ---------------------------------------------------------------- wire
64
+ /** Call an object, turning a defect it returned as data back into a defect. */
65
+ const call = (effect) => effect.pipe(Effect.orDie, Effect.flatMap((value) => value !== null && typeof value === "object" && DEFECT in value
66
+ ? Effect.die(new Error(String(value[DEFECT])))
67
+ : Effect.succeed(value)));
68
+ /** Answer a defect as data, since an object's caller can't be sent a cause. */
69
+ export const reportDefects = (effect) => effect.pipe(Effect.catchCause((cause) => Effect.succeed({ [DEFECT]: Cause.pretty(cause) })));
70
+ /** The address of an entity instance on `host`: its one shard is the host itself. */
71
+ const addressOf = (host, type, id) => EntityAddress.make({
72
+ shardId: ShardId.make(host.group, 1),
73
+ entityType: EntityType.make(type),
74
+ entityId: EntityId.make(id),
75
+ });
76
+ /** A rejection the object answered with, as Effect Cluster's error. */
77
+ const rejectionError = (address, rejection) => {
78
+ switch (rejection._tag) {
79
+ case "MailboxFull":
80
+ return MailboxFull.make({ address });
81
+ case "AlreadyProcessingMessage":
82
+ return AlreadyProcessingMessage.make({ address, envelopeId: Snowflake.Snowflake(0n) });
83
+ case "PersistenceError":
84
+ return PersistenceError.make({ cause: rejection.message });
85
+ }
86
+ };
87
+ /**
88
+ * A client for one entity instance: each RPC is sent to the entity's object
89
+ * and answered by it, with the caller's headers, as Effect Cluster's own
90
+ * client sends it to the runner that owns the entity.
91
+ *
92
+ * A call the object never answered fails with `PersistenceError`; a
93
+ * persisted one is sent again first, to a fresh stub, since the object
94
+ * stores it under the same request id and runs it once. Interrupting a call
95
+ * interrupts its handler.
96
+ */
97
+ export const clientOf = (entity, entityId, objects, host,
98
+ /** Whether the pool hosts the entity: checked before any object is woken. */
99
+ hosts = () => true) => {
100
+ const address = addressOf(host, entity.type, entityId);
101
+ const stub = () => objects().getByName(entityObjectName(entity.type, entityId));
102
+ const hosted = Effect.suspend(() => hosts(entity.type)
103
+ ? Effect.void
104
+ : Effect.die(new NotHosted({ message: `This pool hosts no Cluster.Entity '${entity.type}'.` })));
105
+ const methods = {};
106
+ for (const [tag, rpc_] of entity.protocol.requests) {
107
+ const rpc = rpc_;
108
+ const persisted = Context.get(rpc.annotations, ClusterSchema.Persisted);
109
+ const message = Effect.fn(function* (payload, options) {
110
+ yield* hosted;
111
+ const headers = Headers.merge(yield* RpcClient.CurrentHeaders, Headers.fromInput(options?.headers ?? {}));
112
+ const sent = {
113
+ requestId: SecureRandom.uuidV4Unsafe(),
114
+ tag,
115
+ payload: yield* encode(payloadCodec(rpc), payload),
116
+ headers: Object.fromEntries(Object.entries(headers)),
117
+ };
118
+ return sent;
119
+ });
120
+ /** Send `sent`, again on a fresh stub while a persisted call's failure is transient. */
121
+ const send = (method) => Effect.suspend(() => method(stub())).pipe(Effect.retry({
122
+ while: (error) => persisted && host.isRetryable(error),
123
+ schedule: Schedule.exponential("100 millis"),
124
+ times: 3,
125
+ }), Effect.mapError((cause) => PersistenceError.make({ cause })));
126
+ /** Interrupting the caller interrupts the handler. */
127
+ const interruptible = (sent, effect) => Effect.onInterrupt(effect, () => Effect.ignore(stub().interrupt(sent.requestId)));
128
+ const answer = (reply) => Effect.gen(function* () {
129
+ if (DEFECT in reply)
130
+ return yield* Effect.die(new Error(reply[DEFECT]));
131
+ if ("rejected" in reply)
132
+ return yield* rejectionError(address, reply.rejected);
133
+ const exit = (yield* decode(exitCodec(rpc), reply.exit));
134
+ return yield* exit;
135
+ });
136
+ methods[tag] = RpcSchema.isStreamSchema(rpc.successSchema)
137
+ ? (payload, options) => Stream.unwrap(Effect.map(message(payload, options), (sent) => stub()
138
+ .stream(JSON.stringify(sent))
139
+ .pipe(Stream.mapError((cause) => PersistenceError.make({ cause })), Stream.mapEffect((frame) => Effect.gen(function* () {
140
+ const parsed = JSON.parse(frame);
141
+ if ("chunk" in parsed) {
142
+ return yield* Effect.forEach(parsed.chunk, (value) => decode(chunkCodec(rpc), value));
143
+ }
144
+ yield* answer(parsed);
145
+ return [];
146
+ })), Stream.flatMap((values) => Stream.fromIterable(values)), Stream.onExit((exit) => Exit.hasInterrupts(exit)
147
+ ? Effect.ignore(stub().interrupt(sent.requestId))
148
+ : Effect.void))))
149
+ : (payload, options) => Effect.gen(function* () {
150
+ const sent = yield* message(payload, options);
151
+ const text = JSON.stringify(sent);
152
+ if (options?.discard === true) {
153
+ const reply = yield* send((target) => call(target.tell(text)));
154
+ const parsed = JSON.parse(reply);
155
+ if (parsed.rejected !== undefined) {
156
+ return yield* rejectionError(address, parsed.rejected);
157
+ }
158
+ return;
159
+ }
160
+ const reply = yield* interruptible(sent, send((target) => call(target.ask(text))));
161
+ return yield* answer(JSON.parse(reply));
162
+ });
163
+ }
164
+ return methods;
165
+ };
166
+ const unused = (operation) => Effect.die(new NotHosted({ message: `Sharding.${operation} is not used on durable objects.` }));
167
+ /** `Sharding` for a process whose entities are durable objects. */
168
+ export const makeObjectSharding = (objects, host) => ({
169
+ getShardId: (_entityId, group) => ShardId.make(group, 1),
170
+ hasShardId: () => true,
171
+ getSnowflake: Effect.map(Clock.currentTimeMillis, (now) => Snowflake.Snowflake(BigInt(now) << 22n)),
172
+ isShutdown: Effect.succeed(false),
173
+ makeClient: (entity) => Effect.succeed((entityId) => clientOf(entity, entityId, objects, host, (type) => registry.entities.has(type))),
174
+ getRegistrationEvents: Stream.empty,
175
+ registerEntity: () => unused("registerEntity"),
176
+ registerSingleton: () => unused("registerSingleton"),
177
+ send: () => unused("send"),
178
+ sendOutgoing: () => unused("sendOutgoing"),
179
+ notify: () => unused("notify"),
180
+ reset: () => Effect.succeed(false),
181
+ pollStorage: Effect.void,
182
+ activeEntityCount: Effect.sync(() => registry.entities.size),
183
+ });
184
+ /** The services everything hosted runs with, beyond its own: the cluster's `Sharding`. */
185
+ const withSharding = (context) => registry.sharding === undefined
186
+ ? context
187
+ : Context.add(context, Sharding.Sharding, registry.sharding);
188
+ // ---------------------------------------------------------------- entities
189
+ /**
190
+ * One entity instance, in the object named `name`: the instance runs as
191
+ * Effect Cluster's runners run it (see `EntityRuntime.ts`), and answers its
192
+ * callers in JSON text.
193
+ */
194
+ export const makeEntityObject = Effect.fn(function* (options) {
195
+ const { type, id } = parseEntityObjectName(options.name);
196
+ const hosted = registry.entities.get(type);
197
+ if (hosted === undefined) {
198
+ return yield* Effect.die(new NotHosted({ message: `This pool hosts no Cluster.Entity '${type}'.` }));
199
+ }
200
+ const entity = yield* makeEntityRuntime({
201
+ hosted,
202
+ address: addressOf(options.host, type, id),
203
+ runnerAddress: RunnerAddress.make(options.name, 0),
204
+ context: Context.merge(withSharding(hosted.context), options.runtime),
205
+ storage: options.storage,
206
+ maxEncodedBytes: options.maxEncodedBytes,
207
+ waitUntil: options.waitUntil,
208
+ });
209
+ return {
210
+ ask: (message) => reportDefects(entity.ask(JSON.parse(message))),
211
+ tell: (message) => reportDefects(entity.tell(JSON.parse(message))),
212
+ stream: (message) => entity.stream(JSON.parse(message)),
213
+ interrupt: (requestId) => entity.interrupt(requestId),
214
+ alarm: () => entity.alarm,
215
+ };
216
+ });
217
+ // ---------------------------------------------------------------- singletons and crons
218
+ /** How often a singleton's object checks that it is still running. */
219
+ const SINGLETON_HEARTBEAT = 10_000;
220
+ /**
221
+ * One singleton or cron, in the object named `name`, kept awake by its
222
+ * alarm. A singleton's object runs its fiber and checks on it every few
223
+ * seconds, restarting it if its object was restarted; a cron's object wakes
224
+ * at each scheduled time and runs the job once.
225
+ */
226
+ export const makeScheduledObject = Effect.fn(function* (options) {
227
+ const { exec, setAlarm } = options.storage;
228
+ const hosted = registry.scheduled.get(options.name.slice(options.name.indexOf(":") + 1));
229
+ if (hosted === undefined) {
230
+ return yield* Effect.die(new NotHosted({ message: `This pool hosts no singleton or cron '${options.name}'.` }));
231
+ }
232
+ yield* exec("CREATE TABLE IF NOT EXISTS cluster_schedule (key TEXT PRIMARY KEY, value INTEGER NOT NULL)");
233
+ const context = Context.merge(withSharding(hosted.context), options.runtime);
234
+ if (hosted.kind === "singleton") {
235
+ let fiber;
236
+ const beat = Effect.gen(function* () {
237
+ if (fiber === undefined || fiber.pollUnsafe() !== undefined) {
238
+ fiber = Effect.runForkWith(context)(hosted.run.pipe(Effect.andThen(Effect.never), Effect.scoped, Effect.tapCause((cause) => Effect.logError("Singleton failed", cause)),
239
+ // The object's next heartbeat starts it again.
240
+ Effect.ignore));
241
+ }
242
+ yield* setAlarm((yield* Clock.currentTimeMillis) + SINGLETON_HEARTBEAT);
243
+ });
244
+ return { ensure: () => reportDefects(beat), alarm: () => beat };
245
+ }
246
+ const nextAfter = (time) => Cron.next(hosted.cron, new Date(time)).getTime();
247
+ const readNext = Effect.map(exec("SELECT value FROM cluster_schedule WHERE key = 'next'"), ([row]) => row?.value);
248
+ const writeNext = (next) => Effect.andThen(exec("INSERT OR REPLACE INTO cluster_schedule (key, value) VALUES ('next', ?)", next), setAlarm(next));
249
+ const fire = Effect.gen(function* () {
250
+ const due = yield* readNext;
251
+ const now = yield* Clock.currentTimeMillis;
252
+ if (due === undefined)
253
+ return yield* writeNext(nextAfter(now));
254
+ if (due > now)
255
+ return yield* setAlarm(due);
256
+ // A run due longer ago than `skipIfOlderThan` (after an outage) is skipped.
257
+ const skipAfter = hosted.options.skipIfOlderThan;
258
+ const stale = skipAfter !== undefined && now - due > Duration.toMillis(Duration.fromInputUnsafe(skipAfter));
259
+ if (!stale) {
260
+ yield* hosted.run.pipe(Effect.scoped, Effect.provideService(ClusterCron.CurrentScheduledTime, DateTime.makeUnsafe(due)), Effect.provideContext(context), Effect.tapCause((cause) => Effect.logError("Cron run failed", cause)), Effect.ignore);
261
+ }
262
+ yield* writeNext(nextAfter(hosted.options.calculateNextRunFromPrevious ? due : Math.max(now, due)));
263
+ });
264
+ // Its alarm is set again even when its next time is known: the alarm may
265
+ // be what was lost.
266
+ const ensure = Effect.gen(function* () {
267
+ const due = yield* readNext;
268
+ yield* due === undefined
269
+ ? writeNext(nextAfter(yield* Clock.currentTimeMillis))
270
+ : setAlarm(Math.max(due, yield* Clock.currentTimeMillis));
271
+ });
272
+ return { ensure: () => reportDefects(ensure), alarm: () => fire };
273
+ });
274
+ /** Wake every singleton and cron, so their objects start their alarms. */
275
+ export const wakeScheduled = (objects) => Effect.forEach(registry.scheduled.values(), (hosted) => objects.getByName(scheduledObjectName(hosted.kind, hosted.name)).ensure().pipe(Effect.ignore), { concurrency: "unbounded", discard: true });
276
+ // oxlint-disable-next-line effecttsgo/service-not-as-class
277
+ const entrypointTag = Context.Service(Self.key);
278
+ /**
279
+ * Build each class's Construction phase, keeping what its runtime context
280
+ * hosts. A Layer that hosts its entities itself (a Domain model's) provides
281
+ * no class: it hands them to `RunnerHost`, with a Layer to launch beside
282
+ * them once the workflow engine and Sharding are up.
283
+ */
284
+ const buildHosted = (definitions, scope) => Effect.gen(function* () {
285
+ const hosted = [];
286
+ const launched = [];
287
+ const runner = RunnerHost.of({
288
+ host: (entity, layer) => Effect.sync(() => {
289
+ if (!hosted.some((h) => h.kind === "entity" && h.entity.type === entity.entity.type))
290
+ hosted.push(entity);
291
+ launched.push(layer);
292
+ }),
293
+ });
294
+ for (const { value } of definitions) {
295
+ const declaration = value?.[PlatformDeclaration] ?? value;
296
+ const context = yield* Layer.buildWithScope(makeEntrypointLayer(entrypointTag, declaration), scope).pipe(Effect.provideService(RunnerHost, runner));
297
+ const self = Context.getOption(context, entrypointTag);
298
+ if (Option.isNone(self))
299
+ continue;
300
+ const runtime = self.value.RuntimeContext;
301
+ const built = runtime.hosted();
302
+ if (built === undefined) {
303
+ return yield* Effect.die(new HasNoPool({
304
+ message: `${runtime.Type} '${runtime.id}' did not finish its Construction phase.`,
305
+ }));
306
+ }
307
+ hosted.push(built);
308
+ }
309
+ return { hosted, launched };
310
+ });
311
+ /**
312
+ * Build every class a pool hosts and register it for the pool's objects:
313
+ * entities, singletons and crons by name, and each workflow on `engine`,
314
+ * whose executions are objects too. Runs once per process, in `scope`.
315
+ */
316
+ export const hostClasses = Effect.fn(function* (options) {
317
+ registry.sharding = options.sharding;
318
+ const { hosted, launched } = yield* buildHosted(options.definitions, options.scope).pipe(Effect.provide(Layer.mergeAll(FetchHttpClient.layer, stackFromEnv)));
319
+ const entities = hosted.filter((entry) => entry.kind === "entity");
320
+ const workflows = hosted.filter((entry) => entry.kind === "workflow");
321
+ for (const entry of entities)
322
+ registry.entities.set(entry.entity.type, entry);
323
+ for (const entry of hosted) {
324
+ if (entry.kind === "singleton" || entry.kind === "cron") {
325
+ registry.scheduled.set(entry.name, entry);
326
+ }
327
+ }
328
+ // Each handler runs with the services its Construction phase had, and the
329
+ // cluster's Sharding.
330
+ const sharding = Layer.succeed(Sharding.Sharding, options.sharding);
331
+ const workflowLayers = workflows.map((entry) => entry.workflow.toLayer((payload, executionId) => entry
332
+ .execute(payload, executionId)
333
+ .pipe(Effect.provideContext(Context.add(entry.context, Sharding.Sharding, options.sharding)))));
334
+ const services = yield* Layer.buildWithScope(Layer.mergeAll(...workflowLayers, ...launched).pipe(Layer.provideMerge(options.engine), Layer.provideMerge(sharding)), options.scope);
335
+ return { entities, workflows, services };
336
+ });
337
+ //# sourceMappingURL=ObjectSharding.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ObjectSharding.js","sources":["../../src/internal/ObjectSharding.ts"],"names":[],"mappings":"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"}