@alchemy.run/effect-cluster 0.0.0-stage → 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.
- package/LICENSE +201 -0
- package/README.md +105 -2
- package/lib/AWS/Database.d.ts +54 -0
- package/lib/AWS/Database.d.ts.map +1 -0
- package/lib/AWS/Database.js +96 -0
- package/lib/AWS/Database.js.map +1 -0
- package/lib/AWS/EcsPool.d.ts +56 -0
- package/lib/AWS/EcsPool.d.ts.map +1 -0
- package/lib/AWS/EcsPool.js +87 -0
- package/lib/AWS/EcsPool.js.map +1 -0
- package/lib/AWS/index.d.ts +7 -0
- package/lib/AWS/index.d.ts.map +1 -0
- package/lib/AWS/index.js +7 -0
- package/lib/AWS/index.js.map +1 -0
- package/lib/AWS/internal/Gateway.d.ts +23 -0
- package/lib/AWS/internal/Gateway.d.ts.map +1 -0
- package/lib/AWS/internal/Gateway.js +70 -0
- package/lib/AWS/internal/Gateway.js.map +1 -0
- package/lib/Cloudflare/DurableObjectPool.d.ts +42 -0
- package/lib/Cloudflare/DurableObjectPool.d.ts.map +1 -0
- package/lib/Cloudflare/DurableObjectPool.js +136 -0
- package/lib/Cloudflare/DurableObjectPool.js.map +1 -0
- package/lib/Cloudflare/PoolWorker.d.ts +186 -0
- package/lib/Cloudflare/PoolWorker.d.ts.map +1 -0
- package/lib/Cloudflare/PoolWorker.js +75 -0
- package/lib/Cloudflare/PoolWorker.js.map +1 -0
- package/lib/Cloudflare/index.d.ts +7 -0
- package/lib/Cloudflare/index.d.ts.map +1 -0
- package/lib/Cloudflare/index.js +7 -0
- package/lib/Cloudflare/index.js.map +1 -0
- package/lib/Cloudflare/internal/Objects.d.ts +38 -0
- package/lib/Cloudflare/internal/Objects.d.ts.map +1 -0
- package/lib/Cloudflare/internal/Objects.js +102 -0
- package/lib/Cloudflare/internal/Objects.js.map +1 -0
- package/lib/Cron.d.ts +143 -0
- package/lib/Cron.d.ts.map +1 -0
- package/lib/Cron.js +83 -0
- package/lib/Cron.js.map +1 -0
- package/lib/Database.d.ts +95 -0
- package/lib/Database.d.ts.map +1 -0
- package/lib/Database.js +38 -0
- package/lib/Database.js.map +1 -0
- package/lib/Docker/Database.d.ts +42 -0
- package/lib/Docker/Database.d.ts.map +1 -0
- package/lib/Docker/Database.js +53 -0
- package/lib/Docker/Database.js.map +1 -0
- package/lib/Docker/SwarmPool.d.ts +44 -0
- package/lib/Docker/SwarmPool.d.ts.map +1 -0
- package/lib/Docker/SwarmPool.js +56 -0
- package/lib/Docker/SwarmPool.js.map +1 -0
- package/lib/Docker/index.d.ts +7 -0
- package/lib/Docker/index.d.ts.map +1 -0
- package/lib/Docker/index.js +7 -0
- package/lib/Docker/index.js.map +1 -0
- package/lib/Entity.d.ts +348 -0
- package/lib/Entity.d.ts.map +1 -0
- package/lib/Entity.js +308 -0
- package/lib/Entity.js.map +1 -0
- package/lib/Fly/Database.d.ts +50 -0
- package/lib/Fly/Database.d.ts.map +1 -0
- package/lib/Fly/Database.js +56 -0
- package/lib/Fly/Database.js.map +1 -0
- package/lib/Fly/MachinePool.d.ts +39 -0
- package/lib/Fly/MachinePool.d.ts.map +1 -0
- package/lib/Fly/MachinePool.js +51 -0
- package/lib/Fly/MachinePool.js.map +1 -0
- package/lib/Fly/index.d.ts +7 -0
- package/lib/Fly/index.d.ts.map +1 -0
- package/lib/Fly/index.js +7 -0
- package/lib/Fly/index.js.map +1 -0
- package/lib/GCP/ComputeEnginePool.d.ts +41 -0
- package/lib/GCP/ComputeEnginePool.d.ts.map +1 -0
- package/lib/GCP/ComputeEnginePool.js +172 -0
- package/lib/GCP/ComputeEnginePool.js.map +1 -0
- package/lib/GCP/Database.d.ts +48 -0
- package/lib/GCP/Database.d.ts.map +1 -0
- package/lib/GCP/Database.js +115 -0
- package/lib/GCP/Database.js.map +1 -0
- package/lib/GCP/index.d.ts +7 -0
- package/lib/GCP/index.d.ts.map +1 -0
- package/lib/GCP/index.js +7 -0
- package/lib/GCP/index.js.map +1 -0
- package/lib/Hetzner/Database.d.ts +48 -0
- package/lib/Hetzner/Database.d.ts.map +1 -0
- package/lib/Hetzner/Database.js +91 -0
- package/lib/Hetzner/Database.js.map +1 -0
- package/lib/Hetzner/ServerPool.d.ts +35 -0
- package/lib/Hetzner/ServerPool.d.ts.map +1 -0
- package/lib/Hetzner/ServerPool.js +98 -0
- package/lib/Hetzner/ServerPool.js.map +1 -0
- package/lib/Hetzner/index.d.ts +7 -0
- package/lib/Hetzner/index.d.ts.map +1 -0
- package/lib/Hetzner/index.js +7 -0
- package/lib/Hetzner/index.js.map +1 -0
- package/lib/Host.d.ts +60 -0
- package/lib/Host.d.ts.map +1 -0
- package/lib/Host.js +31 -0
- package/lib/Host.js.map +1 -0
- package/lib/Kubernetes/Database.d.ts +40 -0
- package/lib/Kubernetes/Database.d.ts.map +1 -0
- package/lib/Kubernetes/Database.js +56 -0
- package/lib/Kubernetes/Database.js.map +1 -0
- package/lib/Kubernetes/DeploymentPool.d.ts +54 -0
- package/lib/Kubernetes/DeploymentPool.d.ts.map +1 -0
- package/lib/Kubernetes/DeploymentPool.js +49 -0
- package/lib/Kubernetes/DeploymentPool.js.map +1 -0
- package/lib/Kubernetes/index.d.ts +7 -0
- package/lib/Kubernetes/index.d.ts.map +1 -0
- package/lib/Kubernetes/index.js +7 -0
- package/lib/Kubernetes/index.js.map +1 -0
- package/lib/Pool.d.ts +66 -0
- package/lib/Pool.d.ts.map +1 -0
- package/lib/Pool.js +47 -0
- package/lib/Pool.js.map +1 -0
- package/lib/Providers.d.ts +19 -0
- package/lib/Providers.d.ts.map +1 -0
- package/lib/Providers.js +31 -0
- package/lib/Providers.js.map +1 -0
- package/lib/ShardGroups.d.ts +24 -0
- package/lib/ShardGroups.d.ts.map +1 -0
- package/lib/ShardGroups.js +19 -0
- package/lib/ShardGroups.js.map +1 -0
- package/lib/Singleton.d.ts +110 -0
- package/lib/Singleton.d.ts.map +1 -0
- package/lib/Singleton.js +60 -0
- package/lib/Singleton.js.map +1 -0
- package/lib/Workflow.d.ts +251 -0
- package/lib/Workflow.d.ts.map +1 -0
- package/lib/Workflow.js +288 -0
- package/lib/Workflow.js.map +1 -0
- package/lib/index.d.ts +12 -0
- package/lib/index.d.ts.map +1 -0
- package/lib/index.js +12 -0
- package/lib/index.js.map +1 -0
- package/lib/internal/Bootstrap.d.ts +28 -0
- package/lib/internal/Bootstrap.d.ts.map +1 -0
- package/lib/internal/Bootstrap.js +257 -0
- package/lib/internal/Bootstrap.js.map +1 -0
- package/lib/internal/EntityRuntime.d.ts +40 -0
- package/lib/internal/EntityRuntime.d.ts.map +1 -0
- package/lib/internal/EntityRuntime.js +698 -0
- package/lib/internal/EntityRuntime.js.map +1 -0
- package/lib/internal/Gateway.d.ts +82 -0
- package/lib/internal/Gateway.d.ts.map +1 -0
- package/lib/internal/Gateway.js +218 -0
- package/lib/internal/Gateway.js.map +1 -0
- package/lib/internal/HostedPlatform.d.ts +36 -0
- package/lib/internal/HostedPlatform.d.ts.map +1 -0
- package/lib/internal/HostedPlatform.js +36 -0
- package/lib/internal/HostedPlatform.js.map +1 -0
- package/lib/internal/HostedRuntime.d.ts +58 -0
- package/lib/internal/HostedRuntime.d.ts.map +1 -0
- package/lib/internal/HostedRuntime.js +72 -0
- package/lib/internal/HostedRuntime.js.map +1 -0
- package/lib/internal/Naming.d.ts +12 -0
- package/lib/internal/Naming.d.ts.map +1 -0
- package/lib/internal/Naming.js +40 -0
- package/lib/internal/Naming.js.map +1 -0
- package/lib/internal/ObjectSharding.d.ts +141 -0
- package/lib/internal/ObjectSharding.d.ts.map +1 -0
- package/lib/internal/ObjectSharding.js +337 -0
- package/lib/internal/ObjectSharding.js.map +1 -0
- package/lib/internal/PoolHost.d.ts +80 -0
- package/lib/internal/PoolHost.d.ts.map +1 -0
- package/lib/internal/PoolHost.js +203 -0
- package/lib/internal/PoolHost.js.map +1 -0
- package/lib/internal/PoolHostService.d.ts +25 -0
- package/lib/internal/PoolHostService.d.ts.map +1 -0
- package/lib/internal/PoolHostService.js +10 -0
- package/lib/internal/PoolHostService.js.map +1 -0
- package/lib/internal/Wire.d.ts +60 -0
- package/lib/internal/Wire.d.ts.map +1 -0
- package/lib/internal/Wire.js +36 -0
- package/lib/internal/Wire.js.map +1 -0
- package/lib/internal/WorkflowGateway.d.ts +36 -0
- package/lib/internal/WorkflowGateway.d.ts.map +1 -0
- package/lib/internal/WorkflowGateway.js +124 -0
- package/lib/internal/WorkflowGateway.js.map +1 -0
- package/lib/internal/external-runner.d.ts +2 -0
- package/lib/internal/external-runner.d.ts.map +1 -0
- package/lib/internal/external-runner.js +7 -0
- package/lib/internal/external-runner.js.map +1 -0
- package/lib/internal/runner.d.ts +2 -0
- package/lib/internal/runner.d.ts.map +1 -0
- package/lib/internal/runner.js +5 -0
- package/lib/internal/runner.js.map +1 -0
- package/package.json +143 -3
- package/src/AWS/Database.ts +139 -0
- package/src/AWS/EcsPool.ts +118 -0
- package/src/AWS/index.ts +6 -0
- package/src/AWS/internal/Gateway.ts +82 -0
- package/src/Cloudflare/DurableObjectPool.ts +198 -0
- package/src/Cloudflare/PoolWorker.ts +124 -0
- package/src/Cloudflare/index.ts +6 -0
- package/src/Cloudflare/internal/Objects.ts +160 -0
- package/src/Cron.ts +202 -0
- package/src/Database.ts +116 -0
- package/src/Docker/Database.ts +94 -0
- package/src/Docker/SwarmPool.ts +83 -0
- package/src/Docker/index.ts +6 -0
- package/src/Entity.ts +621 -0
- package/src/Fly/Database.ts +102 -0
- package/src/Fly/MachinePool.ts +72 -0
- package/src/Fly/index.ts +6 -0
- package/src/GCP/ComputeEnginePool.ts +203 -0
- package/src/GCP/Database.ts +168 -0
- package/src/GCP/index.ts +6 -0
- package/src/Hetzner/Database.ts +142 -0
- package/src/Hetzner/ServerPool.ts +116 -0
- package/src/Hetzner/index.ts +6 -0
- package/src/Host.ts +68 -0
- package/src/Kubernetes/Database.ts +89 -0
- package/src/Kubernetes/DeploymentPool.ts +77 -0
- package/src/Kubernetes/index.ts +6 -0
- package/src/Pool.ts +104 -0
- package/src/Providers.ts +49 -0
- package/src/ShardGroups.ts +41 -0
- package/src/Singleton.ts +153 -0
- package/src/Workflow.ts +556 -0
- package/src/index.ts +11 -0
- package/src/internal/Bootstrap.ts +368 -0
- package/src/internal/EntityRuntime.ts +996 -0
- package/src/internal/Gateway.ts +366 -0
- package/src/internal/HostedPlatform.ts +83 -0
- package/src/internal/HostedRuntime.ts +118 -0
- package/src/internal/Naming.ts +44 -0
- package/src/internal/ObjectSharding.ts +578 -0
- package/src/internal/PoolHost.ts +330 -0
- package/src/internal/PoolHostService.ts +25 -0
- package/src/internal/Wire.ts +83 -0
- package/src/internal/WorkflowGateway.ts +188 -0
- package/src/internal/external-runner.ts +10 -0
- package/src/internal/runner.ts +5 -0
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { Input } from "alchemy/Input";
|
|
2
|
+
import * as Output from "alchemy/Output";
|
|
3
|
+
import * as Effect from "effect/Effect";
|
|
4
|
+
import type { ClusterNetwork, DatabaseShape } from "../../Database.ts";
|
|
5
|
+
export type AwsNetwork = Extract<ClusterNetwork, {
|
|
6
|
+
kind: "aws";
|
|
7
|
+
}>;
|
|
8
|
+
export declare const awsNetworkOf: (database: DatabaseShape) => AwsNetwork | undefined;
|
|
9
|
+
/**
|
|
10
|
+
* An internet-facing load balancer in front of the pool's gateway. It is
|
|
11
|
+
* declared before the pool, so the gateway's URL never depends on it.
|
|
12
|
+
*/
|
|
13
|
+
export declare const makeAwsGateway: (id: string, network: {
|
|
14
|
+
readonly kind: "aws";
|
|
15
|
+
readonly vpcId: Input<string>;
|
|
16
|
+
readonly subnetIds: Input<string>[];
|
|
17
|
+
readonly securityGroupId: Input<string>;
|
|
18
|
+
}, targetType: "instance" | "ip") => Effect.Effect<{
|
|
19
|
+
url: Output.Output<string, never>;
|
|
20
|
+
targetGroupArn: Output.Output<`arn:aws:elasticloadbalancing:${string}:${string}:targetgroup/${string}`, never>;
|
|
21
|
+
securityGroupId: Output.Output<`sg-${string}`, never>;
|
|
22
|
+
}, never, import("@alchemy.run/aws/Providers").Providers>;
|
|
23
|
+
//# sourceMappingURL=Gateway.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Gateway.d.ts","sources":["../../../src/AWS/internal/Gateway.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AAC3C,OAAO,KAAK,MAAM,MAAM,gBAAgB,CAAC;AACzC,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AACxC,OAAO,KAAK,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAGvE,MAAM,MAAM,UAAU,GAAG,OAAO,CAAC,cAAc,EAAE;IAAE,IAAI,EAAE,KAAK,CAAA;CAAE,CAAC,CAAC;AAElE,eAAO,MAAM,YAAY,aAAc,aAAa,KAAG,UAAU,GAAG,SACH,CAAC;AAElE;;;GAGG;AACH,eAAO,MAAM,cAAc;;;;;;;;;yDA0DzB,CAAC"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What the AWS runners share: the database's VPC, and a load balancer that
|
|
3
|
+
* serves each pool's gateway to callers anywhere.
|
|
4
|
+
*
|
|
5
|
+
* @internal
|
|
6
|
+
*/
|
|
7
|
+
import * as EC2 from "@alchemy.run/aws/EC2";
|
|
8
|
+
import * as ELBv2 from "@alchemy.run/aws/ELBv2";
|
|
9
|
+
import * as Output from "alchemy/Output";
|
|
10
|
+
import * as Effect from "effect/Effect";
|
|
11
|
+
import { GATEWAY_PORT } from "../../internal/Gateway.js";
|
|
12
|
+
export const awsNetworkOf = (database) => database.network?.kind === "aws" ? database.network : undefined;
|
|
13
|
+
/**
|
|
14
|
+
* An internet-facing load balancer in front of the pool's gateway. It is
|
|
15
|
+
* declared before the pool, so the gateway's URL never depends on it.
|
|
16
|
+
*/
|
|
17
|
+
export const makeAwsGateway = Effect.fn(function* (id, network, targetType) {
|
|
18
|
+
// The database's network, as the EC2 identifiers it holds.
|
|
19
|
+
const vpcId = network.vpcId;
|
|
20
|
+
const subnetIds = network.subnetIds;
|
|
21
|
+
const balancerGroup = yield* EC2.SecurityGroup(`${id}GatewayBalancerGroup`, {
|
|
22
|
+
vpcId,
|
|
23
|
+
description: "Effect Cluster gateway load balancer",
|
|
24
|
+
ingress: [{ ipProtocol: "tcp", fromPort: 80, toPort: 80, cidrIpv4: "0.0.0.0/0" }],
|
|
25
|
+
egress: [{ ipProtocol: "-1", cidrIpv4: "0.0.0.0/0" }],
|
|
26
|
+
});
|
|
27
|
+
// Runners take gateway traffic only from their load balancer.
|
|
28
|
+
const gatewayGroup = yield* EC2.SecurityGroup(`${id}GatewayGroup`, {
|
|
29
|
+
vpcId,
|
|
30
|
+
description: "Effect Cluster gateway",
|
|
31
|
+
ingress: [
|
|
32
|
+
{
|
|
33
|
+
ipProtocol: "tcp",
|
|
34
|
+
fromPort: GATEWAY_PORT,
|
|
35
|
+
toPort: GATEWAY_PORT,
|
|
36
|
+
referencedGroupId: balancerGroup.groupId,
|
|
37
|
+
},
|
|
38
|
+
],
|
|
39
|
+
egress: [{ ipProtocol: "-1", cidrIpv4: "0.0.0.0/0" }],
|
|
40
|
+
});
|
|
41
|
+
const targets = yield* ELBv2.TargetGroup(`${id}Gateway`, {
|
|
42
|
+
vpcId,
|
|
43
|
+
port: GATEWAY_PORT,
|
|
44
|
+
protocol: "HTTP",
|
|
45
|
+
targetType,
|
|
46
|
+
healthCheckPath: "/health",
|
|
47
|
+
matcher: { HttpCode: "200" },
|
|
48
|
+
});
|
|
49
|
+
const balancer = yield* ELBv2.LoadBalancer(`${id}GatewayBalancer`, {
|
|
50
|
+
type: "application",
|
|
51
|
+
scheme: "internet-facing",
|
|
52
|
+
subnets: subnetIds,
|
|
53
|
+
securityGroups: [balancerGroup.groupId],
|
|
54
|
+
// Streaming calls stay open.
|
|
55
|
+
attributes: { "idle_timeout.timeout_seconds": "3600" },
|
|
56
|
+
});
|
|
57
|
+
const listener = yield* ELBv2.Listener(`${id}GatewayListener`, {
|
|
58
|
+
loadBalancerArn: balancer.loadBalancerArn,
|
|
59
|
+
port: 80,
|
|
60
|
+
protocol: "HTTP",
|
|
61
|
+
targetGroupArn: targets.targetGroupArn,
|
|
62
|
+
});
|
|
63
|
+
return {
|
|
64
|
+
// Ordered after the listener, so callers use it once it serves.
|
|
65
|
+
url: Output.all(balancer.dnsName, listener.listenerArn).pipe(Output.map(([dns]) => `http://${dns}`)),
|
|
66
|
+
targetGroupArn: targets.targetGroupArn,
|
|
67
|
+
securityGroupId: gatewayGroup.groupId,
|
|
68
|
+
};
|
|
69
|
+
});
|
|
70
|
+
//# sourceMappingURL=Gateway.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Gateway.js","sources":["../../../src/AWS/internal/Gateway.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import type * as Cloudflare from "@alchemy.run/cloudflare";
|
|
2
|
+
import type { Stack } from "alchemy/Stack";
|
|
3
|
+
import * as Layer from "effect/Layer";
|
|
4
|
+
import { PoolHost } from "../internal/PoolHostService.ts";
|
|
5
|
+
import type { Providers } from "../Providers.ts";
|
|
6
|
+
export interface DurableObjectPoolOptions {
|
|
7
|
+
/**
|
|
8
|
+
* The name the pool is known by, used for its Worker's entry.
|
|
9
|
+
* @default ${stack}-${stage}-${id}
|
|
10
|
+
*/
|
|
11
|
+
name?: string;
|
|
12
|
+
}
|
|
13
|
+
declare const ExternalProgramOnWorkers_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 & {
|
|
14
|
+
readonly _tag: "Cluster.ExternalProgramOnWorkers";
|
|
15
|
+
} & Readonly<A>;
|
|
16
|
+
/** An external program needs runners that run Node, which Workers don't. */
|
|
17
|
+
export declare class ExternalProgramOnWorkers extends ExternalProgramOnWorkers_base<{
|
|
18
|
+
readonly message: string;
|
|
19
|
+
}> {
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Run an Effect Cluster on Cloudflare: one Worker that hosts every class
|
|
23
|
+
* given this pool on Durable Objects. Each entity instance is a Durable
|
|
24
|
+
* Object named by its type and id, so there are no shards, no runners to
|
|
25
|
+
* place it on, and no database: the object's own SQLite holds its persisted
|
|
26
|
+
* messages. Each workflow execution is a Durable Object too, and each
|
|
27
|
+
* singleton and cron one that its alarm keeps awake.
|
|
28
|
+
*
|
|
29
|
+
* Callers anywhere reach the entities through the Worker's gateway; inside
|
|
30
|
+
* the Worker, one entity calls another's object directly.
|
|
31
|
+
*
|
|
32
|
+
* ### Running entities on Cloudflare
|
|
33
|
+
* **Example:** Runners on Durable Objects
|
|
34
|
+
* ```typescript
|
|
35
|
+
* export const Default = ClusterCloudflare.DurableObjectPool("Default");
|
|
36
|
+
* ```
|
|
37
|
+
*
|
|
38
|
+
* @primitive
|
|
39
|
+
*/
|
|
40
|
+
export declare const DurableObjectPool: (id: string, options?: DurableObjectPoolOptions) => Layer.Layer<PoolHost, never, Stack | Providers | Cloudflare.Providers>;
|
|
41
|
+
export {};
|
|
42
|
+
//# sourceMappingURL=DurableObjectPool.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DurableObjectPool.d.ts","sources":["../../src/Cloudflare/DurableObjectPool.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,UAAU,MAAM,yBAAyB,CAAC;AAM3D,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AAK3C,OAAO,KAAK,KAAK,MAAM,cAAc,CAAC;AAQtC,OAAO,EAAE,QAAQ,EAAE,MAAM,gCAAgC,CAAC;AAE1D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAqBjD,MAAM,WAAW,wBAAwB;IACvC;;;OAGG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;;;;AAED,4EAA4E;AAC5E,qBAAa,wBAAyB,SAAQ,8BAAqD;IACjG,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B,CAAC;CAAG;AAkCL;;;;;;;;;;;;;;;;;;GAkBG;AACH,eAAO,MAAM,iBAAiB,OACxB,MAAM,YACD,wBAAwB,KAChC,KAAK,CAAC,KAAK,CAAC,QAAQ,EAAE,KAAK,EAAE,KAAK,GAAG,SAAS,GAAG,UAAU,CAAC,SAAS,CAwFrE,CAAC"}
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import { Worker as CloudflareWorker } from "@alchemy.run/cloudflare/Workers";
|
|
2
|
+
import { dotAlchemyDirectory } from "alchemy/AlchemyContext";
|
|
3
|
+
import * as Output from "alchemy/Output";
|
|
4
|
+
import { Random } from "alchemy/Random";
|
|
5
|
+
import { Self } from "alchemy/Self";
|
|
6
|
+
import * as Data from "effect/Data";
|
|
7
|
+
import * as Effect from "effect/Effect";
|
|
8
|
+
import * as FileSystem from "effect/FileSystem";
|
|
9
|
+
import * as Layer from "effect/Layer";
|
|
10
|
+
import * as Option from "effect/Option";
|
|
11
|
+
import * as Path from "effect/Path";
|
|
12
|
+
import * as Redacted from "effect/Redacted";
|
|
13
|
+
import { registerRouteBinder, routeType } from "../internal/Gateway.js";
|
|
14
|
+
import { HOSTED_TYPES, stackDnsLabel } from "../internal/Naming.js";
|
|
15
|
+
import { PoolHost } from "../internal/PoolHostService.js";
|
|
16
|
+
import { Pool as PoolResource } from "../Pool.js";
|
|
17
|
+
import { poolWorker } from "./PoolWorker.js";
|
|
18
|
+
// A Worker that calls a class this pool hosts gets a service binding to
|
|
19
|
+
// the pool's Worker: Workers can't fetch another Worker's workers.dev URL.
|
|
20
|
+
registerRouteBinder((key, worker) => Effect.gen(function* () {
|
|
21
|
+
if (globalThis.__ALCHEMY_RUNTIME__)
|
|
22
|
+
return;
|
|
23
|
+
const caller = Option.getOrUndefined(yield* Effect.serviceOption(CloudflareWorker
|
|
24
|
+
.Self));
|
|
25
|
+
if (caller === undefined)
|
|
26
|
+
return;
|
|
27
|
+
yield* caller.bind `${key}`({
|
|
28
|
+
bindings: [{ type: "service", name: key, service: worker }],
|
|
29
|
+
});
|
|
30
|
+
}));
|
|
31
|
+
/** An external program needs runners that run Node, which Workers don't. */
|
|
32
|
+
export class ExternalProgramOnWorkers extends Data.TaggedError("Cluster.ExternalProgramOnWorkers") {
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Write the Worker's entry module: it imports every class the pool hosts
|
|
36
|
+
* and default-exports the pool Worker with them, so the Worker's own
|
|
37
|
+
* bundler bundles them all.
|
|
38
|
+
*/
|
|
39
|
+
const writeEntry = Effect.fn(function* (id, workerId, pool) {
|
|
40
|
+
const fs = yield* FileSystem.FileSystem;
|
|
41
|
+
const path = yield* Path.Path;
|
|
42
|
+
const dir = path.resolve(yield* dotAlchemyDirectory, "cluster", yield* stackDnsLabel(id));
|
|
43
|
+
return Output.mapEffect((entities) => Effect.gen(function* () {
|
|
44
|
+
yield* fs.makeDirectory(dir, { recursive: true });
|
|
45
|
+
const file = path.join(dir, "worker.ts");
|
|
46
|
+
const source = [
|
|
47
|
+
`import { poolWorker } from "@alchemy.run/effect-cluster/Cloudflare/PoolWorker";`,
|
|
48
|
+
...entities.map((entity, i) => `import { ${entity.handler} as e${i} } from ${JSON.stringify(entity.module.startsWith("file:") ? new URL(entity.module).pathname : entity.module)};`),
|
|
49
|
+
`export default poolWorker(${JSON.stringify(workerId)}, undefined, [${entities
|
|
50
|
+
.map((entity, i) => `{ name: ${JSON.stringify(entity.name)}, value: e${i} }`)
|
|
51
|
+
.join(", ")}]);`,
|
|
52
|
+
"",
|
|
53
|
+
].join("\n");
|
|
54
|
+
yield* fs.writeFileString(file, source);
|
|
55
|
+
return file;
|
|
56
|
+
}).pipe(Effect.orDie))(pool.entities);
|
|
57
|
+
});
|
|
58
|
+
/**
|
|
59
|
+
* Run an Effect Cluster on Cloudflare: one Worker that hosts every class
|
|
60
|
+
* given this pool on Durable Objects. Each entity instance is a Durable
|
|
61
|
+
* Object named by its type and id, so there are no shards, no runners to
|
|
62
|
+
* place it on, and no database: the object's own SQLite holds its persisted
|
|
63
|
+
* messages. Each workflow execution is a Durable Object too, and each
|
|
64
|
+
* singleton and cron one that its alarm keeps awake.
|
|
65
|
+
*
|
|
66
|
+
* Callers anywhere reach the entities through the Worker's gateway; inside
|
|
67
|
+
* the Worker, one entity calls another's object directly.
|
|
68
|
+
*
|
|
69
|
+
* ### Running entities on Cloudflare
|
|
70
|
+
* **Example:** Runners on Durable Objects
|
|
71
|
+
* ```typescript
|
|
72
|
+
* export const Default = ClusterCloudflare.DurableObjectPool("Default");
|
|
73
|
+
* ```
|
|
74
|
+
*
|
|
75
|
+
* @primitive
|
|
76
|
+
*/
|
|
77
|
+
export const DurableObjectPool = (id, options = {}) => Layer.effect(PoolHost, Effect.gen(function* () {
|
|
78
|
+
// What was provided to the pool, like an entity's RPC middleware,
|
|
79
|
+
// goes with every class they host.
|
|
80
|
+
const services = yield* Effect.context();
|
|
81
|
+
const self = Option.getOrUndefined(yield* Effect.serviceOption(Self));
|
|
82
|
+
const hostsSelf = self !== undefined && HOSTED_TYPES.has(self.Type);
|
|
83
|
+
if (globalThis.__ALCHEMY_RUNTIME__) {
|
|
84
|
+
if (hostsSelf)
|
|
85
|
+
yield* self.provideServices(services);
|
|
86
|
+
return {
|
|
87
|
+
host: (hosted) => hosted.provideServices(services),
|
|
88
|
+
deployExternal: () => Effect.void,
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
const name = options.name ?? (yield* stackDnsLabel(id));
|
|
92
|
+
const workerId = `${id}Pool`;
|
|
93
|
+
const context = yield* Effect.context();
|
|
94
|
+
/** Put `hosted` on the pool, and bind the gateway onto `resource`. */
|
|
95
|
+
const deploy = Effect.fn(function* (hosted, env, resource) {
|
|
96
|
+
const pool = yield* PoolResource(id, { name });
|
|
97
|
+
const token = yield* Random(`${id}GatewayToken`, {
|
|
98
|
+
bytes: 32,
|
|
99
|
+
});
|
|
100
|
+
yield* pool.bind `${hosted.name}`({ entities: [hosted], env });
|
|
101
|
+
const worker = yield* poolWorker(workerId, {
|
|
102
|
+
main: (yield* writeEntry(id, workerId, pool)),
|
|
103
|
+
compatibility: { flags: ["nodejs_compat"] },
|
|
104
|
+
env: {
|
|
105
|
+
// The classes' own environment, which only the deploy knows
|
|
106
|
+
// the keys of: one secret, unpacked when the Worker starts.
|
|
107
|
+
CLUSTER_ENV: pool.env.pipe(Output.map((values) => Redacted.make(JSON.stringify(values)))),
|
|
108
|
+
CLUSTER_POOL: name,
|
|
109
|
+
CLUSTER_GATEWAY_TOKEN: token.text,
|
|
110
|
+
},
|
|
111
|
+
}, []);
|
|
112
|
+
// Callers that are Workers reach the gateway through a service binding.
|
|
113
|
+
routeType(hosted.name, worker.workerName);
|
|
114
|
+
// What callers need to reach the entity through the gateway.
|
|
115
|
+
yield* resource.bind `Pool`({
|
|
116
|
+
pool: name,
|
|
117
|
+
gateway: worker.url,
|
|
118
|
+
token: token.text,
|
|
119
|
+
});
|
|
120
|
+
}, Effect.provide(context));
|
|
121
|
+
const host = (hosted) => Effect.andThen(hosted.provideServices(services), hosted.registerPool((env) => deploy({
|
|
122
|
+
name: hosted.LogicalId,
|
|
123
|
+
module: hosted.Props.main,
|
|
124
|
+
handler: hosted.Props.handler ?? "default",
|
|
125
|
+
}, env, hosted)));
|
|
126
|
+
if (hostsSelf)
|
|
127
|
+
yield* host(self);
|
|
128
|
+
return {
|
|
129
|
+
host,
|
|
130
|
+
deployExternal: ({ type }) => Effect.die(new ExternalProgramOnWorkers({
|
|
131
|
+
message: `Cluster.Entity '${type}' runs an existing Effect Cluster program, which needs Node: ` +
|
|
132
|
+
`give it a pool on another host, like ClusterDocker.SwarmPool or ClusterAWS.EcsPool.`,
|
|
133
|
+
})),
|
|
134
|
+
};
|
|
135
|
+
}));
|
|
136
|
+
//# sourceMappingURL=DurableObjectPool.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DurableObjectPool.js","sources":["../../src/Cloudflare/DurableObjectPool.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The Worker a `ClusterCloudflare.DurableObjectPool` Layer deploys. While deploying it
|
|
3
|
+
* declares the Durable Object classes every cluster uses; inside the
|
|
4
|
+
* deployed Worker it also builds each class the pool hosts, registers
|
|
5
|
+
* them for those objects, and serves the gateway callers reach them through.
|
|
6
|
+
*
|
|
7
|
+
* The pool Layer declares it, and the entry module it generates for the
|
|
8
|
+
* Worker's bundle default-exports it with the hosted classes imported.
|
|
9
|
+
*
|
|
10
|
+
* @internal
|
|
11
|
+
*/
|
|
12
|
+
import * as Cloudflare from "@alchemy.run/cloudflare/Workers";
|
|
13
|
+
import type { InputProps } from "alchemy/Input";
|
|
14
|
+
import * as Effect from "effect/Effect";
|
|
15
|
+
import * as HttpServerResponse from "effect/http/HttpServerResponse";
|
|
16
|
+
import * as Scope from "effect/Scope";
|
|
17
|
+
import { type HostedDefinition } from "../internal/ObjectSharding.ts";
|
|
18
|
+
export type { HostedDefinition } from "../internal/ObjectSharding.ts";
|
|
19
|
+
/**
|
|
20
|
+
* The pool's Worker `id`. `definitions` are the classes it hosts, which
|
|
21
|
+
* only the deployed Worker builds; `props` are its props, which only the
|
|
22
|
+
* deploy reads.
|
|
23
|
+
*/
|
|
24
|
+
export declare const poolWorker: (id: string, props: InputProps<Cloudflare.WorkerProps> | undefined, definitions: ReadonlyArray<HostedDefinition>) => Effect.Effect<import("effect/Pipeable").Pipeable & import("alchemy").ResourceLike<"Cloudflare.Worker", Cloudflare.WorkerProps<any, Cloudflare.WorkerAssetsConfig | undefined>, {
|
|
25
|
+
workerId: string;
|
|
26
|
+
workerName: string;
|
|
27
|
+
namespace: string | undefined;
|
|
28
|
+
logpush: boolean | undefined;
|
|
29
|
+
url: string | undefined;
|
|
30
|
+
urls: string[];
|
|
31
|
+
domain: {
|
|
32
|
+
name: string;
|
|
33
|
+
aliases: string[];
|
|
34
|
+
redirects: string[];
|
|
35
|
+
zone?: import("@alchemy.run/cloudflare/Zone").Reference;
|
|
36
|
+
previews?: boolean;
|
|
37
|
+
} | undefined;
|
|
38
|
+
tags: string[] | undefined;
|
|
39
|
+
durableObjectNamespaces: Record<string, string>;
|
|
40
|
+
accountId: string;
|
|
41
|
+
routes: {
|
|
42
|
+
id: string;
|
|
43
|
+
pattern: string;
|
|
44
|
+
zoneId: string;
|
|
45
|
+
url?: string;
|
|
46
|
+
}[];
|
|
47
|
+
crons: string[];
|
|
48
|
+
tailConsumers?: {
|
|
49
|
+
service: string;
|
|
50
|
+
}[] | undefined;
|
|
51
|
+
streamingTailConsumers?: {
|
|
52
|
+
service: string;
|
|
53
|
+
}[] | undefined;
|
|
54
|
+
versionOf?: string | undefined;
|
|
55
|
+
previewOf?: string | undefined;
|
|
56
|
+
previewId?: string | undefined;
|
|
57
|
+
previewName?: string | undefined;
|
|
58
|
+
previewSlug?: string | undefined;
|
|
59
|
+
previewDoClasses?: string[] | undefined;
|
|
60
|
+
versionId?: string | undefined;
|
|
61
|
+
versionAlias?: string | undefined;
|
|
62
|
+
deploymentId?: string | undefined;
|
|
63
|
+
affinityZoneIds?: string[] | undefined;
|
|
64
|
+
secretNames?: string[] | undefined;
|
|
65
|
+
hash?: {
|
|
66
|
+
assets: string | undefined;
|
|
67
|
+
bundle: string | undefined;
|
|
68
|
+
input: string | undefined;
|
|
69
|
+
additionalWorkspaces: string[] | undefined;
|
|
70
|
+
metadata?: string | undefined;
|
|
71
|
+
};
|
|
72
|
+
}, {
|
|
73
|
+
bindings?: Cloudflare.WorkerBinding[];
|
|
74
|
+
env?: Record<string, any>;
|
|
75
|
+
cache?: Cloudflare.WorkerCache;
|
|
76
|
+
observability?: {
|
|
77
|
+
traces?: Partial<NonNullable<Cloudflare.WorkerObservability["traces"]>>;
|
|
78
|
+
logs?: Partial<NonNullable<Cloudflare.WorkerObservability["logs"]>>;
|
|
79
|
+
};
|
|
80
|
+
containers?: {
|
|
81
|
+
className: string;
|
|
82
|
+
attachedBy?: "binding";
|
|
83
|
+
name?: string;
|
|
84
|
+
images?: Record<string, string>;
|
|
85
|
+
devImages?: Record<string, import("@alchemy.run/cloudflare").DevContainerImage>;
|
|
86
|
+
dev: import("@alchemy.run/cloudflare").DevContainerImage | undefined;
|
|
87
|
+
hash: string | undefined;
|
|
88
|
+
}[];
|
|
89
|
+
crons?: string[];
|
|
90
|
+
hyperdrives?: Record<string, Required<import("@alchemy.run/cloudflare/Hyperdrive").DevOrigin>>;
|
|
91
|
+
devRemote?: Record<string, boolean>;
|
|
92
|
+
}, import("@alchemy.run/cloudflare").Providers, Cloudflare.WorkerLookup> & {
|
|
93
|
+
bind(sid: import("alchemy").Input<string>, binding: import("alchemy").Input<{
|
|
94
|
+
bindings?: Cloudflare.WorkerBinding[];
|
|
95
|
+
env?: Record<string, any>;
|
|
96
|
+
cache?: Cloudflare.WorkerCache;
|
|
97
|
+
observability?: {
|
|
98
|
+
traces?: Partial<NonNullable<Cloudflare.WorkerObservability["traces"]>>;
|
|
99
|
+
logs?: Partial<NonNullable<Cloudflare.WorkerObservability["logs"]>>;
|
|
100
|
+
};
|
|
101
|
+
containers?: {
|
|
102
|
+
className: string;
|
|
103
|
+
attachedBy?: "binding";
|
|
104
|
+
name?: string;
|
|
105
|
+
images?: Record<string, string>;
|
|
106
|
+
devImages?: Record<string, import("@alchemy.run/cloudflare").DevContainerImage>;
|
|
107
|
+
dev: import("@alchemy.run/cloudflare").DevContainerImage | undefined;
|
|
108
|
+
hash: string | undefined;
|
|
109
|
+
}[];
|
|
110
|
+
crons?: string[];
|
|
111
|
+
hyperdrives?: Record<string, Required<import("@alchemy.run/cloudflare/Hyperdrive").DevOrigin>>;
|
|
112
|
+
devRemote?: Record<string, boolean>;
|
|
113
|
+
}>): Effect.Effect<void>;
|
|
114
|
+
bind(template: TemplateStringsArray, ...args: any[]): (binding: import("alchemy").Input<{
|
|
115
|
+
bindings?: Cloudflare.WorkerBinding[];
|
|
116
|
+
env?: Record<string, any>;
|
|
117
|
+
cache?: Cloudflare.WorkerCache;
|
|
118
|
+
observability?: {
|
|
119
|
+
traces?: Partial<NonNullable<Cloudflare.WorkerObservability["traces"]>>;
|
|
120
|
+
logs?: Partial<NonNullable<Cloudflare.WorkerObservability["logs"]>>;
|
|
121
|
+
};
|
|
122
|
+
containers?: {
|
|
123
|
+
className: string;
|
|
124
|
+
attachedBy?: "binding";
|
|
125
|
+
name?: string;
|
|
126
|
+
images?: Record<string, string>;
|
|
127
|
+
devImages?: Record<string, import("@alchemy.run/cloudflare").DevContainerImage>;
|
|
128
|
+
dev: import("@alchemy.run/cloudflare").DevContainerImage | undefined;
|
|
129
|
+
hash: string | undefined;
|
|
130
|
+
}[];
|
|
131
|
+
crons?: string[];
|
|
132
|
+
hyperdrives?: Record<string, Required<import("@alchemy.run/cloudflare/Hyperdrive").DevOrigin>>;
|
|
133
|
+
devRemote?: Record<string, boolean>;
|
|
134
|
+
}>) => Effect.Effect<void>;
|
|
135
|
+
} & {
|
|
136
|
+
workerId: import("alchemy").Output<string, never>;
|
|
137
|
+
workerName: import("alchemy").Output<string, never>;
|
|
138
|
+
namespace: import("alchemy").Output<string | undefined, never>;
|
|
139
|
+
logpush: import("alchemy").Output<boolean | undefined, never>;
|
|
140
|
+
url: import("alchemy").Output<string | undefined, never>;
|
|
141
|
+
urls: import("alchemy").Output<string[], never>;
|
|
142
|
+
domain: import("alchemy").Output<{
|
|
143
|
+
name: string;
|
|
144
|
+
aliases: string[];
|
|
145
|
+
redirects: string[];
|
|
146
|
+
zone?: import("@alchemy.run/cloudflare/Zone").Reference;
|
|
147
|
+
previews?: boolean;
|
|
148
|
+
} | undefined, never>;
|
|
149
|
+
tags: import("alchemy").Output<string[] | undefined, never>;
|
|
150
|
+
durableObjectNamespaces: import("alchemy/Output").ObjectExpr<Record<string, string>, never>;
|
|
151
|
+
accountId: import("alchemy").Output<string, never>;
|
|
152
|
+
routes: import("alchemy").Output<{
|
|
153
|
+
id: string;
|
|
154
|
+
pattern: string;
|
|
155
|
+
zoneId: string;
|
|
156
|
+
url?: string;
|
|
157
|
+
}[], never>;
|
|
158
|
+
crons: import("alchemy").Output<string[], never>;
|
|
159
|
+
tailConsumers: import("alchemy").Output<{
|
|
160
|
+
service: string;
|
|
161
|
+
}[] | undefined, never>;
|
|
162
|
+
streamingTailConsumers: import("alchemy").Output<{
|
|
163
|
+
service: string;
|
|
164
|
+
}[] | undefined, never>;
|
|
165
|
+
versionOf: import("alchemy").Output<string | undefined, never>;
|
|
166
|
+
previewOf: import("alchemy").Output<string | undefined, never>;
|
|
167
|
+
previewId: import("alchemy").Output<string | undefined, never>;
|
|
168
|
+
previewName: import("alchemy").Output<string | undefined, never>;
|
|
169
|
+
previewSlug: import("alchemy").Output<string | undefined, never>;
|
|
170
|
+
previewDoClasses: import("alchemy").Output<string[] | undefined, never>;
|
|
171
|
+
versionId: import("alchemy").Output<string | undefined, never>;
|
|
172
|
+
versionAlias: import("alchemy").Output<string | undefined, never>;
|
|
173
|
+
deploymentId: import("alchemy").Output<string | undefined, never>;
|
|
174
|
+
affinityZoneIds: import("alchemy").Output<string[] | undefined, never>;
|
|
175
|
+
secretNames: import("alchemy").Output<string[] | undefined, never>;
|
|
176
|
+
hash: import("alchemy").Output<{
|
|
177
|
+
assets: string | undefined;
|
|
178
|
+
bundle: string | undefined;
|
|
179
|
+
input: string | undefined;
|
|
180
|
+
additionalWorkspaces: string[] | undefined;
|
|
181
|
+
metadata?: string | undefined;
|
|
182
|
+
} | undefined, never>;
|
|
183
|
+
} & Cloudflare.Rpc<{
|
|
184
|
+
fetch: Effect.Effect<HttpServerResponse.HttpServerResponse, never, import("effect/http/HttpServerRequest").HttpServerRequest | Scope.Scope>;
|
|
185
|
+
}>, never, any> & import("alchemy").Named<string> & import("alchemy").PlatformIdentity<string>;
|
|
186
|
+
//# sourceMappingURL=PoolWorker.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PoolWorker.d.ts","sources":["../../src/Cloudflare/PoolWorker.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,OAAO,KAAK,UAAU,MAAM,iCAAiC,CAAC;AAC9D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAEhD,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AACxC,OAAO,KAAK,kBAAkB,MAAM,gCAAgC,CAAC;AAIrE,OAAO,KAAK,KAAK,MAAM,cAAc,CAAC;AAEtC,OAAO,EACL,KAAK,gBAAgB,EAMtB,MAAM,+BAA+B,CAAC;AASvC,YAAY,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AAEtE;;;;GAIG;AACH,eAAO,MAAM,UAAU,OACjB,MAAM,SACH,UAAU,CAAC,UAAU,CAAC,WAAW,CAAC,GAAG,SAAS,eACxC,aAAa,CAAC,gBAAgB,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8FAiC3C,CAAC"}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The Worker a `ClusterCloudflare.DurableObjectPool` Layer deploys. While deploying it
|
|
3
|
+
* declares the Durable Object classes every cluster uses; inside the
|
|
4
|
+
* deployed Worker it also builds each class the pool hosts, registers
|
|
5
|
+
* them for those objects, and serves the gateway callers reach them through.
|
|
6
|
+
*
|
|
7
|
+
* The pool Layer declares it, and the entry module it generates for the
|
|
8
|
+
* Worker's bundle default-exports it with the hosted classes imported.
|
|
9
|
+
*
|
|
10
|
+
* @internal
|
|
11
|
+
*/
|
|
12
|
+
import * as Cloudflare from "@alchemy.run/cloudflare/Workers";
|
|
13
|
+
import * as Config from "effect/Config";
|
|
14
|
+
import * as Effect from "effect/Effect";
|
|
15
|
+
import * as HttpServerResponse from "effect/http/HttpServerResponse";
|
|
16
|
+
import * as Layer from "effect/Layer";
|
|
17
|
+
import * as Redacted from "effect/Redacted";
|
|
18
|
+
import { RpcSerialization, RpcServer } from "effect/rpc";
|
|
19
|
+
import * as Scope from "effect/Scope";
|
|
20
|
+
import { authorized, gatewayServer } from "../internal/Gateway.js";
|
|
21
|
+
import { hostClasses, makeObjectSharding, wakeScheduled, } from "../internal/ObjectSharding.js";
|
|
22
|
+
import { EntityObject, host, ScheduledObject, WorkflowObject, workflowEngine, } from "./internal/Objects.js";
|
|
23
|
+
/**
|
|
24
|
+
* The pool's Worker `id`. `definitions` are the classes it hosts, which
|
|
25
|
+
* only the deployed Worker builds; `props` are its props, which only the
|
|
26
|
+
* deploy reads.
|
|
27
|
+
*/
|
|
28
|
+
export const poolWorker = (id, props, definitions) => Cloudflare.Worker(id, props ?? {}, Effect.gen(function* () {
|
|
29
|
+
const entities = yield* EntityObject;
|
|
30
|
+
const scheduled = yield* ScheduledObject;
|
|
31
|
+
const workflows = yield* WorkflowObject;
|
|
32
|
+
// A Cron Trigger wakes every singleton and cron each minute, in case
|
|
33
|
+
// their alarms stopped.
|
|
34
|
+
yield* Cloudflare.cron("* * * * *", () => wakeScheduled(scheduled));
|
|
35
|
+
if (!globalThis.__ALCHEMY_RUNTIME__) {
|
|
36
|
+
return { fetch: Effect.succeed(HttpServerResponse.empty({ status: 404 })) };
|
|
37
|
+
}
|
|
38
|
+
// A class that fails to build fails every call, with its cause in the
|
|
39
|
+
// Worker's logs rather than in a response anyone can read.
|
|
40
|
+
return yield* serve(definitions, entities, scheduled, workflows).pipe(Effect.tapCause((cause) => Effect.logError("Effect Cluster pool failed to start", cause)), Effect.catchCause(() => Effect.succeed({
|
|
41
|
+
fetch: Effect.succeed(HttpServerResponse.text("Effect Cluster pool failed to start; see the Worker's logs.", {
|
|
42
|
+
status: 503,
|
|
43
|
+
})),
|
|
44
|
+
})));
|
|
45
|
+
}).pipe(Effect.provide(Cloudflare.CronEventSourceLive)));
|
|
46
|
+
const serve = Effect.fn(function* (definitions, entities, scheduled, workflows) {
|
|
47
|
+
// The classes' own environment, which the deploy packs into one secret.
|
|
48
|
+
const packed = yield* Config.String("CLUSTER_ENV").pipe(Config.withDefault(""));
|
|
49
|
+
if (packed)
|
|
50
|
+
yield* Effect.sync(() => Object.assign(globalThis.process.env, JSON.parse(packed)));
|
|
51
|
+
// Built in the isolate's own scope: once, and never closed (workerd has
|
|
52
|
+
// no teardown hook). Workflows run on the Durable Object engine.
|
|
53
|
+
const hosted = yield* hostClasses({
|
|
54
|
+
definitions,
|
|
55
|
+
scope: Scope.makeUnsafe(),
|
|
56
|
+
sharding: makeObjectSharding(() => entities, host),
|
|
57
|
+
engine: workflowEngine(() => workflows),
|
|
58
|
+
});
|
|
59
|
+
const token = Redacted.value(yield* Config.Redacted("CLUSTER_GATEWAY_TOKEN"));
|
|
60
|
+
const { group, handlers } = gatewayServer(hosted.entities.map((entry) => entry.entity), new Map(hosted.workflows.map((entry) => [entry.workflow._tag, entry.workflow])));
|
|
61
|
+
let woken = false;
|
|
62
|
+
return {
|
|
63
|
+
fetch: authorized(token)(Effect.gen(function* () {
|
|
64
|
+
// The first call this isolate serves starts the singletons and
|
|
65
|
+
// crons, so they run without waiting for the Cron Trigger.
|
|
66
|
+
if (!woken) {
|
|
67
|
+
woken = true;
|
|
68
|
+
yield* wakeScheduled(scheduled);
|
|
69
|
+
}
|
|
70
|
+
const app = yield* RpcServer.toHttpEffect(group).pipe(Effect.provide(Layer.mergeAll(handlers, RpcSerialization.layerJson)), Effect.provideContext(hosted.services));
|
|
71
|
+
return yield* app;
|
|
72
|
+
})),
|
|
73
|
+
};
|
|
74
|
+
});
|
|
75
|
+
//# sourceMappingURL=PoolWorker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PoolWorker.js","sources":["../../src/Cloudflare/PoolWorker.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,OAAO,KAAK,UAAU,MAAM,iCAAiC,CAAC;AAE9D,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AACxC,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AACxC,OAAO,KAAK,kBAAkB,MAAM,gCAAgC,CAAC;AACrE,OAAO,KAAK,KAAK,MAAM,cAAc,CAAC;AACtC,OAAO,KAAK,QAAQ,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,gBAAgB,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AACzD,OAAO,KAAK,KAAK,MAAM,cAAc,CAAC;AACtC,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AACnE,OAAO,EAEL,WAAW,EACX,kBAAkB,EAGlB,aAAa,GACd,MAAM,+BAA+B,CAAC;AACvC,OAAO,EACL,YAAY,EACZ,IAAI,EACJ,eAAe,EACf,cAAc,EACd,cAAc,GACf,MAAM,uBAAuB,CAAC;AAI/B;;;;GAIG;AACH,MAAM,CAAC,MAAM,UAAU,GAAG,CACxB,EAAU,EACV,KAAqD,EACrD,WAA4C,EAC5C,EAAE,CACF,UAAU,CAAC,MAAM,CACf,EAAE,EACF,KAAK,IAAI,EAAE,EACX,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;IAClB,MAAM,QAAQ,GAAG,KAAK,CAAC,CAAC,YAAY,CAAC;IACrC,MAAM,SAAS,GAAG,KAAK,CAAC,CAAC,eAAe,CAAC;IACzC,MAAM,SAAS,GAAG,KAAK,CAAC,CAAC,cAAc,CAAC;IACxC,qEAAqE;IACrE,wBAAwB;IACxB,KAAK,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,WAAW,EAAE,GAAG,EAAE,CAAC,aAAa,CAAC,SAAS,CAAC,CAAC,CAAC;IACpE,IAAI,CAAC,UAAU,CAAC,mBAAmB,EAAE,CAAC;QACpC,OAAO,EAAE,KAAK,EAAE,MAAM,CAAC,OAAO,CAAC,kBAAkB,CAAC,KAAK,CAAC,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC;IAC9E,CAAC;IACD,sEAAsE;IACtE,2DAA2D;IAC3D,OAAO,KAAK,CAAC,CAAC,KAAK,CAAC,WAAW,EAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,CAAC,CAAC,IAAI,CACnE,MAAM,CAAC,QAAQ,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,qCAAqC,EAAE,KAAK,CAAC,CAAC,EACzF,MAAM,CAAC,UAAU,CAAC,GAAG,EAAE,CACrB,MAAM,CAAC,OAAO,CAAC;QACb,KAAK,EAAE,MAAM,CAAC,OAAO,CACnB,kBAAkB,CAAC,IAAI,CACrB,6DAA6D,EAC7D;YACE,MAAM,EAAE,GAAG;SACZ,CACF,CACF;KACF,CAAC,CACH,CACF,CAAC;AACJ,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,mBAAmB,CAAC,CAAC,CACxD,CAAC;AAEJ,MAAM,KAAK,GAAG,MAAM,CAAC,EAAE,CAAC,QAAQ,CAAC,EAC/B,WAA4C,EAC5C,QAAiB,EACjB,SAAyC,EACzC,SAAkB;IAElB,wEAAwE;IACxE,MAAM,MAAM,GAAG,KAAK,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC,CAAC;IAChF,IAAI,MAAM;QAAE,KAAK,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,OAAO,CAAC,GAAG,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;IAChG,wEAAwE;IACxE,iEAAiE;IACjE,MAAM,MAAM,GAAG,KAAK,CAAC,CAAC,WAAW,CAAC;QAChC,WAAW;QACX,KAAK,EAAE,KAAK,CAAC,UAAU,EAAE;QACzB,QAAQ,EAAE,kBAAkB,CAAC,GAAG,EAAE,CAAC,QAAiB,EAAE,IAAI,CAAC;QAC3D,MAAM,EAAE,cAAc,CAAC,GAAG,EAAE,CAAC,SAAkB,CAAC;KACjD,CAAC,CAAC;IAEH,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,uBAAuB,CAAC,CAAC,CAAC;IAC9E,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,GAAG,aAAa,CACvC,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,EAC5C,IAAI,GAAG,CAAC,MAAM,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,EAAE,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,CAChF,CAAC;IACF,IAAI,KAAK,GAAG,KAAK,CAAC;IAClB,OAAO;QACL,KAAK,EAAE,UAAU,CAAC,KAAK,CAAC,CACtB,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;YAClB,+DAA+D;YAC/D,2DAA2D;YAC3D,IAAI,CAAC,KAAK,EAAE,CAAC;gBACX,KAAK,GAAG,IAAI,CAAC;gBACb,KAAK,CAAC,CAAC,aAAa,CAAC,SAAS,CAAC,CAAC;YAClC,CAAC;YACD,MAAM,GAAG,GAAG,KAAK,CAAC,CAAC,SAAS,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC,IAAI,CACnD,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC,QAAQ,EAAE,gBAAgB,CAAC,SAAS,CAAC,CAAC,EACpE,MAAM,CAAC,cAAc,CAAC,MAAM,CAAC,QAAQ,CAAC,CACvC,CAAC;YACF,OAAO,KAAK,CAAC,CAAC,GAAG,CAAC;QACpB,CAAC,CAAC,CACH;KACF,CAAC;AACJ,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @alchemy.run/effect-cluster/Cloudflare — run an Effect Cluster's entities,
|
|
3
|
+
* workflows, singletons and crons on Cloudflare Durable Objects. Requires
|
|
4
|
+
* `@alchemy.run/cloudflare`.
|
|
5
|
+
*/
|
|
6
|
+
export * from "./DurableObjectPool.ts";
|
|
7
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sources":["../../src/Cloudflare/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,cAAc,wBAAwB,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @alchemy.run/effect-cluster/Cloudflare — run an Effect Cluster's entities,
|
|
3
|
+
* workflows, singletons and crons on Cloudflare Durable Objects. Requires
|
|
4
|
+
* `@alchemy.run/cloudflare`.
|
|
5
|
+
*/
|
|
6
|
+
export * from "./DurableObjectPool.js";
|
|
7
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../../src/Cloudflare/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,cAAc,wBAAwB,CAAC"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The Durable Object classes a `ClusterCloudflare.DurableObjectPool` Worker
|
|
3
|
+
* exports. Every entity type shares one class, `ClusterEntity`, whose objects
|
|
4
|
+
* are named by `(type, id)`; every workflow shares `ClusterWorkflow`, one
|
|
5
|
+
* object per execution; every singleton and cron shares `ClusterScheduled`,
|
|
6
|
+
* one object per name. What each object runs is host-neutral (see
|
|
7
|
+
* `internal/ObjectSharding.ts`); this module gives it workerd's storage.
|
|
8
|
+
*
|
|
9
|
+
* @internal
|
|
10
|
+
*/
|
|
11
|
+
import * as Cloudflare from "@alchemy.run/cloudflare/Workers";
|
|
12
|
+
import * as Effect from "effect/Effect";
|
|
13
|
+
import { type EntityObjectStub, type Namespace, type ObjectHost, type ScheduledObjectStub } from "../../internal/ObjectSharding.ts";
|
|
14
|
+
/** Cloudflare, as a host of the cluster's objects. */
|
|
15
|
+
export declare const host: ObjectHost;
|
|
16
|
+
/** Every entity instance: one object per `(type, id)`. */
|
|
17
|
+
export declare const EntityObject: Effect.Effect<Cloudflare.DurableObject<EntityObjectStub>, never, Cloudflare.Worker> & (new (_: never) => {
|
|
18
|
+
ask: (message: string) => Effect.Effect<string, never, never>;
|
|
19
|
+
tell: (message: string) => Effect.Effect<string, never, never>;
|
|
20
|
+
stream: (message: string) => import("effect/Stream").Stream<string, never, never>;
|
|
21
|
+
interrupt: (requestId: string) => Effect.Effect<void, never, never>;
|
|
22
|
+
alarm: () => Effect.Effect<void, never, never>;
|
|
23
|
+
});
|
|
24
|
+
/** Every singleton and cron: one object per name. */
|
|
25
|
+
export declare const ScheduledObject: Effect.Effect<Cloudflare.DurableObject<ScheduledObjectStub>, never, Cloudflare.Worker> & (new (_: never) => {
|
|
26
|
+
ensure: () => Effect.Effect<void, never, never>;
|
|
27
|
+
alarm: () => Effect.Effect<void, never, never>;
|
|
28
|
+
});
|
|
29
|
+
/**
|
|
30
|
+
* Every workflow execution: one object per `(workflow, execution)`, running
|
|
31
|
+
* Alchemy's Durable Object workflow engine. The engine declares a class per
|
|
32
|
+
* workflow; here each of those is a view onto this one class, so the Worker
|
|
33
|
+
* exports the same classes whatever workflows it hosts.
|
|
34
|
+
*/
|
|
35
|
+
export declare const WorkflowObject: Effect.Effect<Cloudflare.DurableObject<Record<string, never>>, never, Cloudflare.Worker> & (new (_: never) => Record<string, never>);
|
|
36
|
+
/** The workflow engine, its executions on {@link WorkflowObject}. */
|
|
37
|
+
export declare const workflowEngine: (objects: () => Namespace<unknown>) => import("effect/Layer").Layer<import("effect/workflow/WorkflowEngine").WorkflowEngine, never, never>;
|
|
38
|
+
//# sourceMappingURL=Objects.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Objects.d.ts","sources":["../../../src/Cloudflare/internal/Objects.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,KAAK,UAAU,MAAM,iCAAiC,CAAC;AAI9D,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AAIxC,OAAO,EACL,KAAK,gBAAgB,EAGrB,KAAK,SAAS,EAEd,KAAK,UAAU,EAEf,KAAK,mBAAmB,EAGzB,MAAM,kCAAkC,CAAC;AAE1C,sDAAsD;AACtD,eAAO,MAAM,IAAI,EAAE,UASlB,CAAC;AAqCF,0DAA0D;AAC1D,eAAO,MAAM,YAAY;;;;;;EAsBxB,CAAC;AAEF,qDAAqD;AACrD,eAAO,MAAM,eAAe;;;EAa3B,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,cAAc,sIAoB1B,CAAC;AAEF,qEAAqE;AACrE,eAAO,MAAM,cAAc,YAAa,MAAM,SAAS,CAAC,OAAO,CAAC,wGAW5D,CAAC"}
|