alchemy 2.0.0-beta.40 → 2.0.0-beta.41
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/bin/exec.js +16 -3
- package/bin/exec.js.map +1 -1
- package/lib/AWS/EC2/hosted.js +1 -1
- package/lib/AWS/EC2/hosted.js.map +1 -1
- package/lib/AWS/ECS/Task.js +1 -1
- package/lib/AWS/ECS/Task.js.map +1 -1
- package/lib/AWS/Lambda/BucketEventSource.d.ts +1 -1
- package/lib/AWS/Lambda/BucketEventSource.d.ts.map +1 -1
- package/lib/AWS/Lambda/EventBridgeEventSource.d.ts +1 -1
- package/lib/AWS/Lambda/EventBridgeEventSource.d.ts.map +1 -1
- package/lib/AWS/Lambda/Function.js +1 -1
- package/lib/AWS/Lambda/Function.js.map +1 -1
- package/lib/AWS/Lambda/QueueEventSource.d.ts +1 -1
- package/lib/AWS/Lambda/QueueEventSource.d.ts.map +1 -1
- package/lib/AWS/Lambda/StreamEventSource.d.ts +1 -1
- package/lib/AWS/Lambda/StreamEventSource.d.ts.map +1 -1
- package/lib/AWS/Lambda/TableEventSource.d.ts +1 -1
- package/lib/AWS/Lambda/TableEventSource.d.ts.map +1 -1
- package/lib/AWS/Lambda/TopicEventSource.d.ts +1 -1
- package/lib/AWS/Lambda/TopicEventSource.d.ts.map +1 -1
- package/lib/Apply.d.ts.map +1 -1
- package/lib/Apply.js +41 -7
- package/lib/Apply.js.map +1 -1
- package/lib/Cloudflare/Bridge.d.ts +1 -0
- package/lib/Cloudflare/Bridge.d.ts.map +1 -1
- package/lib/Cloudflare/Bridge.js +1 -0
- package/lib/Cloudflare/Bridge.js.map +1 -1
- package/lib/Cloudflare/Container/ContainerApplication.js +1 -1
- package/lib/Cloudflare/Container/ContainerApplication.js.map +1 -1
- package/lib/Cloudflare/Container/ContainerBinding.d.ts +1 -1
- package/lib/Cloudflare/Container/ContainerBinding.d.ts.map +1 -1
- package/lib/Cloudflare/Container/ContainerBinding.js +1 -1
- package/lib/Cloudflare/Container/ContainerBinding.js.map +1 -1
- package/lib/Cloudflare/Fetcher.d.ts +9 -0
- package/lib/Cloudflare/Fetcher.d.ts.map +1 -1
- package/lib/Cloudflare/Fetcher.js +20 -1
- package/lib/Cloudflare/Fetcher.js.map +1 -1
- package/lib/Cloudflare/Local/SidecarHandlers.d.ts.map +1 -1
- package/lib/Cloudflare/Local/SidecarHandlers.js +1 -1
- package/lib/Cloudflare/Local/SidecarHandlers.js.map +1 -1
- package/lib/Cloudflare/StateStore/Api.d.ts +2 -2
- package/lib/Cloudflare/Website/StaticSite.d.ts +5 -4
- package/lib/Cloudflare/Website/StaticSite.d.ts.map +1 -1
- package/lib/Cloudflare/Website/StaticSite.js.map +1 -1
- package/lib/Cloudflare/Website/Vite.d.ts +4 -4
- package/lib/Cloudflare/Website/Vite.d.ts.map +1 -1
- package/lib/Cloudflare/Website/Vite.js.map +1 -1
- package/lib/Cloudflare/Workers/DurableObjectBridge.d.ts +17 -0
- package/lib/Cloudflare/Workers/DurableObjectBridge.d.ts.map +1 -0
- package/lib/Cloudflare/Workers/DurableObjectBridge.js +86 -0
- package/lib/Cloudflare/Workers/DurableObjectBridge.js.map +1 -0
- package/lib/Cloudflare/Workers/DurableObjectNamespace.d.ts +2 -1
- package/lib/Cloudflare/Workers/DurableObjectNamespace.d.ts.map +1 -1
- package/lib/Cloudflare/Workers/DurableObjectNamespace.js +10 -39
- package/lib/Cloudflare/Workers/DurableObjectNamespace.js.map +1 -1
- package/lib/Cloudflare/Workers/HttpServer.d.ts +2 -8
- package/lib/Cloudflare/Workers/HttpServer.d.ts.map +1 -1
- package/lib/Cloudflare/Workers/HttpServer.js +29 -33
- package/lib/Cloudflare/Workers/HttpServer.js.map +1 -1
- package/lib/Cloudflare/Workers/InferEnv.d.ts +5 -24
- package/lib/Cloudflare/Workers/InferEnv.d.ts.map +1 -1
- package/lib/Cloudflare/Workers/Rpc.d.ts +0 -101
- package/lib/Cloudflare/Workers/Rpc.d.ts.map +1 -1
- package/lib/Cloudflare/Workers/Rpc.js +9 -286
- package/lib/Cloudflare/Workers/Rpc.js.map +1 -1
- package/lib/Cloudflare/Workers/RpcAsync.d.ts +8 -0
- package/lib/Cloudflare/Workers/RpcAsync.d.ts.map +1 -0
- package/lib/Cloudflare/Workers/RpcAsync.js +45 -0
- package/lib/Cloudflare/Workers/RpcAsync.js.map +1 -0
- package/lib/Cloudflare/Workers/Worker.d.ts +16 -162
- package/lib/Cloudflare/Workers/Worker.d.ts.map +1 -1
- package/lib/Cloudflare/Workers/Worker.js +49 -354
- package/lib/Cloudflare/Workers/Worker.js.map +1 -1
- package/lib/Cloudflare/Workers/WorkerAsyncBindings.d.ts +8 -0
- package/lib/Cloudflare/Workers/WorkerAsyncBindings.d.ts.map +1 -0
- package/lib/Cloudflare/Workers/WorkerAsyncBindings.js +129 -0
- package/lib/Cloudflare/Workers/WorkerAsyncBindings.js.map +1 -0
- package/lib/Cloudflare/Workers/WorkerBinding.d.ts +154 -0
- package/lib/Cloudflare/Workers/WorkerBinding.d.ts.map +1 -0
- package/lib/Cloudflare/Workers/WorkerBinding.js +51 -0
- package/lib/Cloudflare/Workers/WorkerBinding.js.map +1 -0
- package/lib/Cloudflare/Workers/WorkerBridge.d.ts +35 -0
- package/lib/Cloudflare/Workers/WorkerBridge.d.ts.map +1 -0
- package/lib/Cloudflare/Workers/WorkerBridge.js +149 -0
- package/lib/Cloudflare/Workers/WorkerBridge.js.map +1 -0
- package/lib/Cloudflare/Workers/WorkerBundle.d.ts.map +1 -1
- package/lib/Cloudflare/Workers/WorkerBundle.js +18 -84
- package/lib/Cloudflare/Workers/WorkerBundle.js.map +1 -1
- package/lib/Cloudflare/Workers/WorkerRuntimeContext.d.ts +8 -0
- package/lib/Cloudflare/Workers/WorkerRuntimeContext.d.ts.map +1 -0
- package/lib/Cloudflare/Workers/WorkerRuntimeContext.js +113 -0
- package/lib/Cloudflare/Workers/WorkerRuntimeContext.js.map +1 -0
- package/lib/Cloudflare/Workers/WorkflowBridge.d.ts +26 -0
- package/lib/Cloudflare/Workers/WorkflowBridge.d.ts.map +1 -0
- package/lib/Cloudflare/Workers/WorkflowBridge.js +41 -0
- package/lib/Cloudflare/Workers/WorkflowBridge.js.map +1 -0
- package/lib/Cloudflare/Workers/index.d.ts +4 -0
- package/lib/Cloudflare/Workers/index.d.ts.map +1 -1
- package/lib/Cloudflare/Workers/index.js +4 -0
- package/lib/Cloudflare/Workers/index.js.map +1 -1
- package/lib/Cloudflare/index.d.ts +4 -2
- package/lib/Cloudflare/index.d.ts.map +1 -1
- package/lib/Cloudflare/index.js +4 -2
- package/lib/Cloudflare/index.js.map +1 -1
- package/lib/Neon/Project.d.ts.map +1 -1
- package/lib/Neon/Project.js +2 -1
- package/lib/Neon/Project.js.map +1 -1
- package/lib/Platform.d.ts +3 -4
- package/lib/Platform.d.ts.map +1 -1
- package/lib/Platform.js.map +1 -1
- package/lib/Rpc.d.ts +17 -0
- package/lib/Rpc.d.ts.map +1 -0
- package/lib/Rpc.js +1 -0
- package/lib/Rpc.js.map +1 -0
- package/lib/RuntimeContext.d.ts +1 -0
- package/lib/RuntimeContext.d.ts.map +1 -1
- package/lib/RuntimeContext.js.map +1 -1
- package/lib/Sidecar/RpcHandler.d.ts.map +1 -1
- package/lib/Sidecar/RpcHandler.js +13 -9
- package/lib/Sidecar/RpcHandler.js.map +1 -1
- package/lib/State/HttpStateApi.d.ts +10 -0
- package/lib/State/HttpStateApi.d.ts.map +1 -1
- package/lib/State/HttpStateApi.js +10 -0
- package/lib/State/HttpStateApi.js.map +1 -1
- package/lib/State/HttpStateStore.d.ts.map +1 -1
- package/lib/State/HttpStateStore.js +2 -1
- package/lib/State/HttpStateStore.js.map +1 -1
- package/lib/State/InMemoryState.d.ts.map +1 -1
- package/lib/State/InMemoryState.js +2 -0
- package/lib/State/InMemoryState.js.map +1 -1
- package/lib/State/LocalState.d.ts.map +1 -1
- package/lib/State/LocalState.js +2 -0
- package/lib/State/LocalState.js.map +1 -1
- package/lib/State/State.d.ts +8 -0
- package/lib/State/State.d.ts.map +1 -1
- package/lib/State/StateEncoding.d.ts.map +1 -1
- package/lib/State/StateEncoding.js +5 -1
- package/lib/State/StateEncoding.js.map +1 -1
- package/lib/index.d.ts +2 -1
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +1 -1
- package/lib/index.js.map +1 -1
- package/lib/tsconfig.test.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/src/Apply.ts +44 -10
- package/src/Cli/Event.ts +1 -1
- package/src/Cloudflare/Bridge.ts +1 -0
- package/src/Cloudflare/Container/ContainerBinding.ts +1 -1
- package/src/Cloudflare/Fetcher.ts +38 -1
- package/src/Cloudflare/Local/SidecarHandlers.ts +3 -6
- package/src/Cloudflare/Website/StaticSite.ts +10 -5
- package/src/Cloudflare/Website/Vite.ts +7 -4
- package/src/Cloudflare/Workers/DurableObjectBridge.ts +180 -0
- package/src/Cloudflare/Workers/DurableObjectNamespace.ts +22 -70
- package/src/Cloudflare/Workers/HttpServer.ts +25 -39
- package/src/Cloudflare/Workers/InferEnv.ts +42 -78
- package/src/Cloudflare/Workers/Rpc.ts +18 -417
- package/src/Cloudflare/Workers/RpcAsync.ts +63 -0
- package/src/Cloudflare/Workers/Worker.ts +107 -548
- package/src/Cloudflare/Workers/WorkerAsyncBindings.ts +149 -0
- package/src/Cloudflare/Workers/WorkerBinding.ts +103 -0
- package/src/Cloudflare/Workers/WorkerBridge.ts +304 -0
- package/src/Cloudflare/Workers/WorkerBundle.ts +17 -83
- package/src/Cloudflare/Workers/WorkerRuntimeContext.ts +164 -0
- package/src/Cloudflare/Workers/WorkflowBridge.ts +92 -0
- package/src/Cloudflare/Workers/index.ts +4 -0
- package/src/Cloudflare/index.ts +4 -2
- package/src/Neon/Project.ts +3 -1
- package/src/Platform.ts +3 -4
- package/src/Rpc.ts +25 -0
- package/src/RuntimeContext.ts +1 -0
- package/src/Sidecar/RpcHandler.ts +18 -9
- package/src/State/HttpStateApi.ts +11 -0
- package/src/State/HttpStateStore.ts +7 -2
- package/src/State/InMemoryState.ts +2 -0
- package/src/State/LocalState.ts +2 -0
- package/src/State/State.ts +8 -0
- package/src/State/StateEncoding.ts +8 -1
- package/src/index.ts +7 -6
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
import * as Effect from "effect/Effect";
|
|
2
|
+
import * as Redacted from "effect/Redacted";
|
|
3
|
+
import type { InputProps } from "../../Input.ts";
|
|
4
|
+
import * as Output from "../../Output.ts";
|
|
5
|
+
import type { ResourceBinding } from "../../Resource.ts";
|
|
6
|
+
import { isYieldableEffectLike } from "../../Util/effect.ts";
|
|
7
|
+
import { isAnalyticsEngineDataset } from "../AnalyticsEngine/AnalyticsEngineDataset.ts";
|
|
8
|
+
import { isArtifacts } from "../Artifacts/Artifacts.ts";
|
|
9
|
+
import { isSendEmail } from "../Email/SendEmail.ts";
|
|
10
|
+
import { isImages } from "../Images/Images.ts";
|
|
11
|
+
import { isAssets } from "./Assets.ts";
|
|
12
|
+
import { isDurableObjectNamespaceLike } from "./DurableObjectNamespace.ts";
|
|
13
|
+
import type { WorkerBindingProps } from "./Worker.ts";
|
|
14
|
+
import { isWorker, type Worker, type WorkerProps } from "./Worker.ts";
|
|
15
|
+
import type { WorkerBinding, WorkerBindingResource } from "./WorkerBinding.ts";
|
|
16
|
+
|
|
17
|
+
export const bindWorkerAsyncBindings = Effect.fnUntraced(function* (
|
|
18
|
+
resource: Worker,
|
|
19
|
+
props: InputProps<WorkerProps<WorkerBindingProps>>,
|
|
20
|
+
) {
|
|
21
|
+
if (props.bindings) {
|
|
22
|
+
for (const bindingName in props.bindings) {
|
|
23
|
+
// @ts-expect-error
|
|
24
|
+
const bindingEff = props.bindings?.[bindingName] as
|
|
25
|
+
| WorkerBindingResource
|
|
26
|
+
| Effect.Effect<WorkerBindingResource>;
|
|
27
|
+
// Bindings can be passed as a plain resource value, an Effect that
|
|
28
|
+
// yields a resource, or an effect-class (e.g. a `Cloudflare.Worker`
|
|
29
|
+
// class). Resolve the yieldable forms before deriving binding metadata.
|
|
30
|
+
const binding = isYieldableEffectLike(bindingEff)
|
|
31
|
+
? ((yield* bindingEff as Effect.Effect<unknown>) as WorkerBindingResource)
|
|
32
|
+
: bindingEff;
|
|
33
|
+
|
|
34
|
+
const bindingMeta: InputProps<WorkerBinding> | undefined =
|
|
35
|
+
typeof binding === "string"
|
|
36
|
+
? {
|
|
37
|
+
type: "plain_text",
|
|
38
|
+
name: bindingName,
|
|
39
|
+
value: binding,
|
|
40
|
+
}
|
|
41
|
+
: Redacted.isRedacted(binding)
|
|
42
|
+
? {
|
|
43
|
+
type: "secret_text",
|
|
44
|
+
name: bindingName,
|
|
45
|
+
value: Redacted.value(binding),
|
|
46
|
+
}
|
|
47
|
+
: isAssets(binding)
|
|
48
|
+
? {
|
|
49
|
+
type: "assets",
|
|
50
|
+
name: bindingName,
|
|
51
|
+
}
|
|
52
|
+
: isArtifacts(binding)
|
|
53
|
+
? ({
|
|
54
|
+
type: "artifacts",
|
|
55
|
+
name: bindingName,
|
|
56
|
+
namespace: binding.namespace,
|
|
57
|
+
} as any)
|
|
58
|
+
: isImages(binding)
|
|
59
|
+
? {
|
|
60
|
+
type: "images",
|
|
61
|
+
name: bindingName,
|
|
62
|
+
}
|
|
63
|
+
: isAnalyticsEngineDataset(binding)
|
|
64
|
+
? {
|
|
65
|
+
type: "analytics_engine",
|
|
66
|
+
name: bindingName,
|
|
67
|
+
dataset: binding.dataset,
|
|
68
|
+
}
|
|
69
|
+
: isSendEmail(binding)
|
|
70
|
+
? {
|
|
71
|
+
type: "send_email",
|
|
72
|
+
name: bindingName,
|
|
73
|
+
destinationAddress: binding.destinationAddress,
|
|
74
|
+
allowedDestinationAddresses:
|
|
75
|
+
binding.allowedDestinationAddresses,
|
|
76
|
+
allowedSenderAddresses:
|
|
77
|
+
binding.allowedSenderAddresses,
|
|
78
|
+
}
|
|
79
|
+
: isDurableObjectNamespaceLike(binding)
|
|
80
|
+
? {
|
|
81
|
+
type: "durable_object_namespace",
|
|
82
|
+
name: bindingName,
|
|
83
|
+
className: binding.className ?? binding.name,
|
|
84
|
+
}
|
|
85
|
+
: binding.Type === "Cloudflare.D1Database"
|
|
86
|
+
? {
|
|
87
|
+
type: "d1",
|
|
88
|
+
id: binding.databaseId,
|
|
89
|
+
name: bindingName,
|
|
90
|
+
}
|
|
91
|
+
: binding.Type === "Cloudflare.R2Bucket"
|
|
92
|
+
? {
|
|
93
|
+
type: "r2_bucket",
|
|
94
|
+
name: bindingName,
|
|
95
|
+
bucketName: binding.bucketName,
|
|
96
|
+
jurisdiction: binding.jurisdiction.pipe(
|
|
97
|
+
Output.map((jurisdiction) =>
|
|
98
|
+
jurisdiction === "default"
|
|
99
|
+
? undefined
|
|
100
|
+
: jurisdiction,
|
|
101
|
+
),
|
|
102
|
+
),
|
|
103
|
+
}
|
|
104
|
+
: binding.Type === "Cloudflare.KVNamespace"
|
|
105
|
+
? {
|
|
106
|
+
type: "kv_namespace",
|
|
107
|
+
name: bindingName,
|
|
108
|
+
namespaceId: binding.namespaceId,
|
|
109
|
+
}
|
|
110
|
+
: binding.Type === "Cloudflare.Queue"
|
|
111
|
+
? {
|
|
112
|
+
type: "queue",
|
|
113
|
+
name: bindingName,
|
|
114
|
+
queueName: binding.queueName,
|
|
115
|
+
}
|
|
116
|
+
: binding.Type === "Cloudflare.AiGateway"
|
|
117
|
+
? {
|
|
118
|
+
type: "ai",
|
|
119
|
+
name: bindingName,
|
|
120
|
+
}
|
|
121
|
+
: binding.Type === "Cloudflare.Hyperdrive"
|
|
122
|
+
? {
|
|
123
|
+
type: "hyperdrive",
|
|
124
|
+
name: bindingName,
|
|
125
|
+
id: binding.hyperdriveId,
|
|
126
|
+
}
|
|
127
|
+
: isWorker(binding)
|
|
128
|
+
? {
|
|
129
|
+
type: "service",
|
|
130
|
+
name: bindingName,
|
|
131
|
+
service: binding.workerName,
|
|
132
|
+
}
|
|
133
|
+
: // TODO(sam): handle others
|
|
134
|
+
undefined;
|
|
135
|
+
|
|
136
|
+
if (bindingMeta) {
|
|
137
|
+
yield* resource.bind`${bindingName}`({
|
|
138
|
+
bindings: [bindingMeta],
|
|
139
|
+
});
|
|
140
|
+
} else {
|
|
141
|
+
return yield* Effect.die(`Unknown binding type: ${bindingName}`);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
export const getCronBindings = (
|
|
148
|
+
bindings: ReadonlyArray<ResourceBinding<Worker["Binding"]>>,
|
|
149
|
+
) => Array.from(new Set(bindings.flatMap((b) => b.data.crons ?? [])));
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import type * as workers from "@distilled.cloud/cloudflare/workers";
|
|
2
|
+
import * as Effect from "effect/Effect";
|
|
3
|
+
import * as Binding from "../../Binding.ts";
|
|
4
|
+
import type { Rpc } from "../../Rpc.ts";
|
|
5
|
+
import { isYieldableEffectLike } from "../../Util/effect.ts";
|
|
6
|
+
import type { AiGateway } from "../AiGateway/AiGateway.ts";
|
|
7
|
+
import { AnalyticsEngineDataset } from "../AnalyticsEngine/AnalyticsEngineDataset.ts";
|
|
8
|
+
import { Artifacts } from "../Artifacts/Artifacts.ts";
|
|
9
|
+
import type { D1Database } from "../D1/D1Database.ts";
|
|
10
|
+
import { SendEmail } from "../Email/SendEmail.ts";
|
|
11
|
+
import { Hyperdrive } from "../Hyperdrive/Hyperdrive.ts";
|
|
12
|
+
import { Images } from "../Images/Images.ts";
|
|
13
|
+
import type { KVNamespace } from "../KV/KVNamespace.ts";
|
|
14
|
+
import type { Queue } from "../Queue/Queue.ts";
|
|
15
|
+
import type { R2Bucket } from "../R2/R2Bucket.ts";
|
|
16
|
+
import type { Assets } from "./Assets.ts";
|
|
17
|
+
import type { DurableObjectNamespaceLike } from "./DurableObjectNamespace.ts";
|
|
18
|
+
import { makeRpcStub } from "./Rpc.ts";
|
|
19
|
+
import { isWorker, Worker, WorkerEnvironment } from "./Worker.ts";
|
|
20
|
+
|
|
21
|
+
export type WorkerBinding = Exclude<
|
|
22
|
+
workers.PutScriptRequest["metadata"]["bindings"],
|
|
23
|
+
undefined
|
|
24
|
+
>[number];
|
|
25
|
+
|
|
26
|
+
export type WorkerSettingsBinding = Exclude<
|
|
27
|
+
workers.GetScriptScriptAndVersionSettingResponse["bindings"],
|
|
28
|
+
null | undefined
|
|
29
|
+
>[number];
|
|
30
|
+
|
|
31
|
+
export type WorkerBindingResource =
|
|
32
|
+
| Assets
|
|
33
|
+
| R2Bucket
|
|
34
|
+
| D1Database
|
|
35
|
+
| KVNamespace
|
|
36
|
+
| Queue
|
|
37
|
+
| AiGateway
|
|
38
|
+
| AnalyticsEngineDataset
|
|
39
|
+
| SendEmail
|
|
40
|
+
| Artifacts
|
|
41
|
+
| Images
|
|
42
|
+
| Hyperdrive
|
|
43
|
+
| Worker
|
|
44
|
+
| DurableObjectNamespaceLike<any>;
|
|
45
|
+
|
|
46
|
+
export type WorkerBindings = {
|
|
47
|
+
[bindingName in string]: WorkerBindingResource;
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
export const bindWorker = Effect.fnUntraced(function* <Shape, Req = never>(
|
|
51
|
+
workerEff:
|
|
52
|
+
| (Worker & Rpc<Shape>)
|
|
53
|
+
| Effect.Effect<Worker & Rpc<Shape>, never, Req>,
|
|
54
|
+
) {
|
|
55
|
+
// Worker classes and regular Effects are both yieldable here.
|
|
56
|
+
const worker = isYieldableEffectLike(workerEff)
|
|
57
|
+
? yield* workerEff as Effect.Effect<Worker & Rpc<Shape>, never, Req>
|
|
58
|
+
: workerEff;
|
|
59
|
+
const self = yield* Worker;
|
|
60
|
+
yield* self.bind`${worker}`({
|
|
61
|
+
bindings: [
|
|
62
|
+
{
|
|
63
|
+
type: "service",
|
|
64
|
+
name: worker.LogicalId,
|
|
65
|
+
service: worker.workerName,
|
|
66
|
+
},
|
|
67
|
+
],
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
// `bindWorker` runs at *init* phase (both at plantime and at runtime
|
|
71
|
+
// cold-start). `WorkerEnvironment` only exists at exec phase on the
|
|
72
|
+
// deployed worker, so we hand `makeRpcStub` an `Effect<stub>` that
|
|
73
|
+
// resolves the binding lazily on each method call.
|
|
74
|
+
const stubEff = WorkerEnvironment.pipe(
|
|
75
|
+
Effect.map((env) => (env as Record<string, unknown>)[worker.LogicalId]),
|
|
76
|
+
);
|
|
77
|
+
return makeRpcStub<Shape>(stubEff);
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
export class BindWorkerPolicy extends Binding.Policy<
|
|
81
|
+
BindWorkerPolicy,
|
|
82
|
+
(worker: Worker) => Effect.Effect<void>
|
|
83
|
+
>()("Cloudflare.Worker.Bind") {}
|
|
84
|
+
|
|
85
|
+
export const BindWorkerPolicyLive = BindWorkerPolicy.layer.succeed(
|
|
86
|
+
Effect.fn(function* (host, worker: Worker) {
|
|
87
|
+
if (isWorker(host)) {
|
|
88
|
+
yield* host.bind`${worker}`({
|
|
89
|
+
bindings: [
|
|
90
|
+
{
|
|
91
|
+
type: "service",
|
|
92
|
+
name: worker.LogicalId,
|
|
93
|
+
service: worker.workerName,
|
|
94
|
+
},
|
|
95
|
+
],
|
|
96
|
+
});
|
|
97
|
+
} else {
|
|
98
|
+
return yield* Effect.die(
|
|
99
|
+
new Error(`BindWorkerPolicy does not support runtime '${host.Type}'`),
|
|
100
|
+
);
|
|
101
|
+
}
|
|
102
|
+
}),
|
|
103
|
+
);
|
|
@@ -0,0 +1,304 @@
|
|
|
1
|
+
import type * as cf from "@cloudflare/workers-types";
|
|
2
|
+
import { NodeServices } from "@effect/platform-node";
|
|
3
|
+
import type { DurableObject, WorkerEntrypoint } from "cloudflare:workers";
|
|
4
|
+
import { Stream } from "effect";
|
|
5
|
+
import * as Cause from "effect/Cause";
|
|
6
|
+
import * as ConfigProvider from "effect/ConfigProvider";
|
|
7
|
+
import * as Context from "effect/Context";
|
|
8
|
+
import * as Effect from "effect/Effect";
|
|
9
|
+
import * as Exit from "effect/Exit";
|
|
10
|
+
import { pipe } from "effect/Function";
|
|
11
|
+
import * as Layer from "effect/Layer";
|
|
12
|
+
import * as Logger from "effect/Logger";
|
|
13
|
+
import { MinimumLogLevel } from "effect/References";
|
|
14
|
+
import * as Scope from "effect/Scope";
|
|
15
|
+
import { FetchHttpClient } from "effect/unstable/http";
|
|
16
|
+
import { ExecutionContext } from "../../ExecutionContext.ts";
|
|
17
|
+
import { makeEntrypointLayer } from "../../Runtime.ts";
|
|
18
|
+
import { Self } from "../../Self.ts";
|
|
19
|
+
import { Stack } from "../../Stack.ts";
|
|
20
|
+
import {
|
|
21
|
+
ErrorTag,
|
|
22
|
+
type RpcErrorEnvelope,
|
|
23
|
+
type RpcStreamEnvelope,
|
|
24
|
+
encodeRpcError,
|
|
25
|
+
toRpcStream,
|
|
26
|
+
} from "./Rpc.ts";
|
|
27
|
+
import {
|
|
28
|
+
ExportedHandlerMethods,
|
|
29
|
+
Worker,
|
|
30
|
+
WorkerEnvironment,
|
|
31
|
+
WorkerExecutionContext,
|
|
32
|
+
} from "./Worker.ts";
|
|
33
|
+
import type { WorkerRuntimeContext } from "./WorkerRuntimeContext.ts";
|
|
34
|
+
import cloudflare_workers from "./cloudflare_workers.ts";
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Makes the WorkerEntrypoint class and bridges to Effect fetch and RPC calls.
|
|
38
|
+
*/
|
|
39
|
+
export const makeWorkerBridge = (
|
|
40
|
+
Base: typeof WorkerEntrypoint | typeof DurableObject,
|
|
41
|
+
{
|
|
42
|
+
stack,
|
|
43
|
+
entrypoint,
|
|
44
|
+
}: {
|
|
45
|
+
stack: {
|
|
46
|
+
name: string;
|
|
47
|
+
stage: string;
|
|
48
|
+
};
|
|
49
|
+
entrypoint: any;
|
|
50
|
+
},
|
|
51
|
+
) => {
|
|
52
|
+
const { globalContext, exported, shape } = getWorkerExport({
|
|
53
|
+
entrypoint,
|
|
54
|
+
stack,
|
|
55
|
+
exportName: "default",
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
const processEvent = (
|
|
59
|
+
eff: Effect.Effect<
|
|
60
|
+
readonly [Effect.Effect<any, any, any>, Context.Context<never>],
|
|
61
|
+
any,
|
|
62
|
+
any
|
|
63
|
+
>,
|
|
64
|
+
ctx: cf.ExecutionContext,
|
|
65
|
+
) => {
|
|
66
|
+
const scope = Scope.makeUnsafe();
|
|
67
|
+
return eff
|
|
68
|
+
.pipe(
|
|
69
|
+
Effect.flatMap(([eff, context]) =>
|
|
70
|
+
Effect.provide(
|
|
71
|
+
eff,
|
|
72
|
+
pipe(
|
|
73
|
+
Layer.succeedContext(context),
|
|
74
|
+
Layer.provideMerge(Layer.succeedContext(context)),
|
|
75
|
+
Layer.provideMerge(Layer.succeed(WorkerExecutionContext, ctx)),
|
|
76
|
+
Layer.provideMerge(
|
|
77
|
+
Layer.succeed(ExecutionContext, {
|
|
78
|
+
scope,
|
|
79
|
+
cache: {},
|
|
80
|
+
}),
|
|
81
|
+
),
|
|
82
|
+
),
|
|
83
|
+
),
|
|
84
|
+
),
|
|
85
|
+
Effect.provide(
|
|
86
|
+
Layer.provideMerge(globalContext, Layer.succeed(Scope.Scope, scope)),
|
|
87
|
+
),
|
|
88
|
+
Effect.runPromiseExit,
|
|
89
|
+
)
|
|
90
|
+
.finally(() =>
|
|
91
|
+
Scope.close(scope, Exit.void).pipe(Effect.runPromise, (promise) =>
|
|
92
|
+
ctx.waitUntil(promise),
|
|
93
|
+
),
|
|
94
|
+
);
|
|
95
|
+
};
|
|
96
|
+
class WorkerBridge extends Base {
|
|
97
|
+
constructor(
|
|
98
|
+
public readonly ctx: any,
|
|
99
|
+
public readonly env: any,
|
|
100
|
+
) {
|
|
101
|
+
super(ctx, env);
|
|
102
|
+
|
|
103
|
+
for (const methodName of ExportedHandlerMethods) {
|
|
104
|
+
(this as any)[methodName] = async (input: any) =>
|
|
105
|
+
exported
|
|
106
|
+
.pipe(
|
|
107
|
+
Effect.map((_default) => _default[methodName]),
|
|
108
|
+
Effect.map(
|
|
109
|
+
(f) =>
|
|
110
|
+
f(input, this.env, this.ctx) as [
|
|
111
|
+
Effect.Effect<any>,
|
|
112
|
+
Context.Context<never>,
|
|
113
|
+
],
|
|
114
|
+
),
|
|
115
|
+
(eff) => processEvent(eff, this.ctx),
|
|
116
|
+
)
|
|
117
|
+
.then((exit) =>
|
|
118
|
+
exit._tag === "Success"
|
|
119
|
+
? Promise.resolve(exit.value)
|
|
120
|
+
: Promise.reject(Cause.squash(exit.cause)),
|
|
121
|
+
);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
return new Proxy(this, {
|
|
125
|
+
get: (target, prop) => {
|
|
126
|
+
if (typeof prop !== "string") return (target as any)[prop];
|
|
127
|
+
if (prop in target) return (target as any)[prop];
|
|
128
|
+
return (...args: unknown[]) =>
|
|
129
|
+
shape
|
|
130
|
+
.pipe(
|
|
131
|
+
Effect.map((shape: any) => shape[prop]),
|
|
132
|
+
Effect.flatMap((dispatcher) => {
|
|
133
|
+
if (typeof dispatcher !== "function") {
|
|
134
|
+
return Effect.die(
|
|
135
|
+
new Error(
|
|
136
|
+
`Method "${prop}" not found on worker. ` +
|
|
137
|
+
`Make sure it's returned from the worker's default export.`,
|
|
138
|
+
),
|
|
139
|
+
);
|
|
140
|
+
}
|
|
141
|
+
console.log("dispatcher", dispatcher.toString());
|
|
142
|
+
return Effect.succeed([
|
|
143
|
+
dispatcher(...args) as Effect.Effect<any>,
|
|
144
|
+
Context.empty(),
|
|
145
|
+
] as const);
|
|
146
|
+
}),
|
|
147
|
+
(eff) => processEvent(eff, this.ctx),
|
|
148
|
+
)
|
|
149
|
+
.then(handleRpcExit);
|
|
150
|
+
},
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
// Stub prototype methods so Cloudflare's script-validate detects the
|
|
156
|
+
// standard handler set; per-instance overrides above are what actually
|
|
157
|
+
// run.
|
|
158
|
+
for (const method of ExportedHandlerMethods) {
|
|
159
|
+
Object.defineProperty(WorkerBridge.prototype, method, {
|
|
160
|
+
value: function () {
|
|
161
|
+
throw new Error(
|
|
162
|
+
`Bridge method '${method}' was called before instance setup`,
|
|
163
|
+
);
|
|
164
|
+
},
|
|
165
|
+
writable: true,
|
|
166
|
+
configurable: true,
|
|
167
|
+
});
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
return WorkerBridge;
|
|
171
|
+
};
|
|
172
|
+
|
|
173
|
+
export const getWorkerExport = <Export = any>({
|
|
174
|
+
entrypoint,
|
|
175
|
+
stack,
|
|
176
|
+
exportName,
|
|
177
|
+
}: {
|
|
178
|
+
entrypoint: any;
|
|
179
|
+
stack: { name: string; stage: string };
|
|
180
|
+
exportName: string;
|
|
181
|
+
}) => {
|
|
182
|
+
const tag = Self as any as Context.Service<
|
|
183
|
+
never,
|
|
184
|
+
Worker & {
|
|
185
|
+
RuntimeContext: WorkerRuntimeContext;
|
|
186
|
+
}
|
|
187
|
+
>;
|
|
188
|
+
|
|
189
|
+
const runtimeContext = tag.pipe(Effect.map((func) => func.RuntimeContext));
|
|
190
|
+
const shape = runtimeContext.pipe(Effect.map((context) => context.shape()));
|
|
191
|
+
const exported = runtimeContext.pipe(
|
|
192
|
+
Effect.flatMap((context) => context.exports),
|
|
193
|
+
Effect.flatMap((exports) =>
|
|
194
|
+
Effect.isEffect(exports[exportName])
|
|
195
|
+
? exports[exportName]
|
|
196
|
+
: Effect.succeed(exports[exportName]),
|
|
197
|
+
),
|
|
198
|
+
) as Effect.Effect<Export>;
|
|
199
|
+
|
|
200
|
+
const layer = makeEntrypointLayer(tag, entrypoint);
|
|
201
|
+
|
|
202
|
+
const platform = Layer.mergeAll(
|
|
203
|
+
NodeServices.layer,
|
|
204
|
+
FetchHttpClient.layer,
|
|
205
|
+
// TODO(sam): wire this up to telemetry more directly
|
|
206
|
+
Logger.layer([Logger.consolePretty()]),
|
|
207
|
+
);
|
|
208
|
+
|
|
209
|
+
const globalContext = Layer.unwrap(
|
|
210
|
+
cloudflare_workers.pipe(
|
|
211
|
+
Effect.map(({ env }) =>
|
|
212
|
+
layer.pipe(
|
|
213
|
+
Layer.provideMerge(
|
|
214
|
+
Layer.succeed(Stack, {
|
|
215
|
+
name: stack.name,
|
|
216
|
+
stage: stack.stage,
|
|
217
|
+
bindings: {},
|
|
218
|
+
resources: {},
|
|
219
|
+
actions: {},
|
|
220
|
+
}),
|
|
221
|
+
),
|
|
222
|
+
Layer.provideMerge(platform),
|
|
223
|
+
Layer.provideMerge(
|
|
224
|
+
Layer.succeed(
|
|
225
|
+
ConfigProvider.ConfigProvider,
|
|
226
|
+
ConfigProvider.orElse(
|
|
227
|
+
ConfigProvider.fromUnknown({ ALCHEMY_PHASE: "runtime" }),
|
|
228
|
+
ConfigProvider.fromUnknown(env),
|
|
229
|
+
),
|
|
230
|
+
),
|
|
231
|
+
),
|
|
232
|
+
Layer.provideMerge(Layer.succeed(WorkerEnvironment, env)),
|
|
233
|
+
Layer.provideMerge(
|
|
234
|
+
Layer.succeed(
|
|
235
|
+
MinimumLogLevel,
|
|
236
|
+
(env as any).DEBUG ? "Debug" : "Info",
|
|
237
|
+
),
|
|
238
|
+
),
|
|
239
|
+
),
|
|
240
|
+
),
|
|
241
|
+
),
|
|
242
|
+
);
|
|
243
|
+
|
|
244
|
+
return {
|
|
245
|
+
globalContext,
|
|
246
|
+
exported,
|
|
247
|
+
shape,
|
|
248
|
+
};
|
|
249
|
+
};
|
|
250
|
+
|
|
251
|
+
export const makeRpcProxy = (
|
|
252
|
+
self: any,
|
|
253
|
+
userShape: Effect.Effect<any>,
|
|
254
|
+
processEvent: (
|
|
255
|
+
eff: Effect.Effect<[Effect.Effect<any>, Context.Context<never>]>,
|
|
256
|
+
) => Promise<any>,
|
|
257
|
+
) =>
|
|
258
|
+
new Proxy(self, {
|
|
259
|
+
get: (target, prop) => {
|
|
260
|
+
if (typeof prop !== "string") return (target as any)[prop];
|
|
261
|
+
if (prop in target) return (target as any)[prop];
|
|
262
|
+
return (...args: unknown[]) =>
|
|
263
|
+
userShape
|
|
264
|
+
.pipe(
|
|
265
|
+
Effect.map((shape) => shape[prop]),
|
|
266
|
+
Effect.flatMap((dispatcher) => {
|
|
267
|
+
if (typeof dispatcher !== "function") {
|
|
268
|
+
return Effect.die(
|
|
269
|
+
new Error(
|
|
270
|
+
`Method "${prop}" not found on worker. ` +
|
|
271
|
+
`Make sure it's returned from the worker's default export.`,
|
|
272
|
+
),
|
|
273
|
+
);
|
|
274
|
+
}
|
|
275
|
+
console.log("dispatcher", dispatcher.toString());
|
|
276
|
+
return dispatcher(...args) as Effect.Effect<any>;
|
|
277
|
+
}),
|
|
278
|
+
processEvent,
|
|
279
|
+
)
|
|
280
|
+
.then(handleRpcExit);
|
|
281
|
+
},
|
|
282
|
+
});
|
|
283
|
+
|
|
284
|
+
export const handleRpcExit = async (exit: Exit.Exit<any, any>) => {
|
|
285
|
+
if (exit._tag === "Success") {
|
|
286
|
+
if (Stream.isStream(exit.value)) {
|
|
287
|
+
return await Effect.runPromise(
|
|
288
|
+
toRpcStream(exit.value) as Effect.Effect<RpcStreamEnvelope>,
|
|
289
|
+
);
|
|
290
|
+
}
|
|
291
|
+
return exit.value;
|
|
292
|
+
}
|
|
293
|
+
const failReason = exit.cause.reasons.find(Cause.isFailReason);
|
|
294
|
+
if (failReason) {
|
|
295
|
+
return {
|
|
296
|
+
_tag: ErrorTag,
|
|
297
|
+
error: encodeRpcError(failReason.error),
|
|
298
|
+
} satisfies RpcErrorEnvelope;
|
|
299
|
+
}
|
|
300
|
+
const dieReason = exit.cause.reasons.find(Cause.isDieReason);
|
|
301
|
+
throw (
|
|
302
|
+
dieReason?.defect ?? new Error("RPC method failed with an unexpected cause")
|
|
303
|
+
);
|
|
304
|
+
};
|
|
@@ -9,7 +9,6 @@ import type * as rolldown from "rolldown";
|
|
|
9
9
|
import Sonda from "sonda/rolldown";
|
|
10
10
|
import * as Bundle from "../../Bundle/Bundle.ts";
|
|
11
11
|
import { findCwdForBundle } from "../../Bundle/TempRoot.ts";
|
|
12
|
-
import { Self } from "../../Self.ts";
|
|
13
12
|
import {
|
|
14
13
|
isDurableObjectExport,
|
|
15
14
|
type DurableObjectExport,
|
|
@@ -47,6 +46,12 @@ export const WorkerBundle = Effect.gen(function* () {
|
|
|
47
46
|
const realMain = yield* sanitizeMain(options.main);
|
|
48
47
|
const inputOptions: rolldown.InputOptions = {
|
|
49
48
|
input: realMain,
|
|
49
|
+
// Forever-devtool native modules that vite/chokidar reference behind
|
|
50
|
+
// runtime guards. Rolldown resolves before tree-shaking, so the dead
|
|
51
|
+
// `require('../pkg')` (lightningcss < 1.32) and `require('fsevents')`
|
|
52
|
+
// (darwin-only) trip [UNRESOLVED_IMPORT] before DCE can prune them.
|
|
53
|
+
// See rolldown/tsdown#212.
|
|
54
|
+
external: ["lightningcss", "fsevents"],
|
|
50
55
|
cwd: yield* findCwdForBundle(realMain).pipe(
|
|
51
56
|
Effect.mapError(
|
|
52
57
|
(cause) =>
|
|
@@ -148,100 +153,29 @@ export const makeEffectVirtualEntry = (
|
|
|
148
153
|
const hasDoClasses = doClasses.length > 0;
|
|
149
154
|
const hasWfClasses = wfClasses.length > 0;
|
|
150
155
|
return (importPath: string) => `
|
|
151
|
-
import * as Config from "effect/Config";
|
|
152
|
-
import * as ConfigProvider from "effect/ConfigProvider";
|
|
153
|
-
import * as Console from "effect/Console";
|
|
154
156
|
import * as Effect from "effect/Effect";
|
|
155
|
-
import * as FetchHttpClient from "effect/unstable/http/FetchHttpClient";
|
|
156
|
-
import * as Layer from "effect/Layer";
|
|
157
|
-
import * as Logger from "effect/Logger";
|
|
158
|
-
import * as Context from "effect/Context";
|
|
159
|
-
import * as Stream from "effect/Stream";
|
|
160
157
|
|
|
161
158
|
import { env, DurableObject, WorkerEntrypoint${hasWfClasses ? ", WorkflowEntrypoint" : ""} } from "cloudflare:workers";
|
|
162
|
-
import {
|
|
163
|
-
import * as NodeServices from "@effect/platform-node/NodeServices";
|
|
164
|
-
import { Stack } from "alchemy/Stack";
|
|
165
|
-
import { WorkerEnvironment, makeDurableObjectBridge, makeWorkerBridge${hasWfClasses ? ", makeWorkflowBridge" : ""}, ExportedHandlerMethods } from "alchemy/Cloudflare";
|
|
159
|
+
import { makeDurableObjectBridge, makeWorkerBridge${hasWfClasses ? ", makeWorkflowBridge" : ""} } from "alchemy/Cloudflare";
|
|
166
160
|
import { makeEntrypointLayer } from "alchemy/Runtime";
|
|
167
161
|
|
|
168
162
|
import entrypoint from ${JSON.stringify(importPath)};
|
|
169
163
|
|
|
170
|
-
const
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
Logger.layer([Logger.consolePretty()]),
|
|
178
|
-
);
|
|
179
|
-
|
|
180
|
-
const stack = Layer.succeed(
|
|
181
|
-
Stack,
|
|
182
|
-
{
|
|
183
|
-
name: "${stack.name}",
|
|
184
|
-
stage: "${stack.stage}",
|
|
185
|
-
bindings: {},
|
|
186
|
-
resources: {}
|
|
187
|
-
}
|
|
188
|
-
);
|
|
189
|
-
|
|
190
|
-
const exportsEffect = tag.pipe(
|
|
191
|
-
Effect.flatMap(func => func.RuntimeContext.exports),
|
|
192
|
-
Effect.provide(
|
|
193
|
-
layer.pipe(
|
|
194
|
-
Layer.provideMerge(stack),
|
|
195
|
-
Layer.provideMerge(platform),
|
|
196
|
-
Layer.provideMerge(
|
|
197
|
-
Layer.succeed(
|
|
198
|
-
ConfigProvider.ConfigProvider,
|
|
199
|
-
ConfigProvider.orElse(
|
|
200
|
-
ConfigProvider.fromUnknown({ ALCHEMY_PHASE: "runtime" }),
|
|
201
|
-
ConfigProvider.fromUnknown(env),
|
|
202
|
-
),
|
|
203
|
-
),
|
|
204
|
-
),
|
|
205
|
-
Layer.provideMerge(Layer.succeed(WorkerEnvironment, env)),
|
|
206
|
-
Layer.provideMerge(
|
|
207
|
-
Layer.succeed(MinimumLogLevel, env.DEBUG ? "Debug" : "Info"),
|
|
208
|
-
),
|
|
209
|
-
),
|
|
210
|
-
),
|
|
211
|
-
Effect.scoped,
|
|
212
|
-
);
|
|
213
|
-
|
|
214
|
-
// TODO(sam): we could kick this off during module init, but any I/O will break deploy
|
|
215
|
-
// let exportsPromise = Effect.runPromise(exportsEffect);
|
|
216
|
-
|
|
217
|
-
// for now, we delay initializing the worker until the first request
|
|
218
|
-
let exportsPromise;
|
|
219
|
-
|
|
220
|
-
// don't initialize the workerEffect during module init because Cloudflare does not allow I/O during module init
|
|
221
|
-
// we cache it synchronously (??=) to guarnatee only one initialization ever happens
|
|
222
|
-
const getExports = () => (exportsPromise ??= Effect.runPromise(exportsEffect))
|
|
223
|
-
const getExport = (name) => getExports().then(exports => exports[name]?.make)
|
|
224
|
-
const getDefault = () => getExports().then(exports => exports.default)
|
|
225
|
-
const getRpc = () => getExports().then(exports => exports.__rpc__ ?? {})
|
|
164
|
+
const meta = {
|
|
165
|
+
entrypoint,
|
|
166
|
+
stack: {
|
|
167
|
+
name: ${JSON.stringify(stack.name)},
|
|
168
|
+
stage: ${JSON.stringify(stack.stage)},
|
|
169
|
+
},
|
|
170
|
+
};
|
|
226
171
|
|
|
227
|
-
|
|
228
|
-
// subclass so Cloudflare service bindings can dispatch both the standard
|
|
229
|
-
// handler methods (fetch, scheduled, …) and any user-defined RPC methods.
|
|
230
|
-
// RPC method results are wire-encoded by \`runtimeContext.exports\`;
|
|
231
|
-
// consumers unwrap them with \`Cloudflare.toPromiseApi(env.X)\` (Promise
|
|
232
|
-
// API) or \`bindWorker(WorkerClass)\` (Effect API).
|
|
233
|
-
export default makeWorkerBridge(
|
|
234
|
-
WorkerEntrypoint,
|
|
235
|
-
ExportedHandlerMethods,
|
|
236
|
-
getDefault,
|
|
237
|
-
getRpc,
|
|
238
|
-
);
|
|
172
|
+
export default makeWorkerBridge(WorkerEntrypoint, meta);
|
|
239
173
|
|
|
240
174
|
// export class proxy stubs for Durable Objects and Workflows
|
|
241
175
|
${[
|
|
242
176
|
...(hasDoClasses
|
|
243
177
|
? [
|
|
244
|
-
"const DurableObjectBridge = makeDurableObjectBridge(DurableObject,
|
|
178
|
+
"const DurableObjectBridge = makeDurableObjectBridge(DurableObject, meta);",
|
|
245
179
|
...doClasses.map(
|
|
246
180
|
(id) => `export class ${id} extends DurableObjectBridge("${id}") {}`,
|
|
247
181
|
),
|
|
@@ -249,7 +183,7 @@ ${[
|
|
|
249
183
|
: []),
|
|
250
184
|
...(hasWfClasses
|
|
251
185
|
? [
|
|
252
|
-
"const WorkflowBridgeFn = makeWorkflowBridge(WorkflowEntrypoint,
|
|
186
|
+
"const WorkflowBridgeFn = makeWorkflowBridge(WorkflowEntrypoint, meta);",
|
|
253
187
|
...wfClasses.map(
|
|
254
188
|
(id) => `export class ${id} extends WorkflowBridgeFn("${id}") {}`,
|
|
255
189
|
),
|