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
|
@@ -1,69 +1,31 @@
|
|
|
1
1
|
import type * as cf from "@cloudflare/workers-types";
|
|
2
2
|
import * as workers from "@distilled.cloud/cloudflare/workers";
|
|
3
3
|
import * as zones from "@distilled.cloud/cloudflare/zones";
|
|
4
|
-
import * as Cause from "effect/Cause";
|
|
5
4
|
import * as Context from "effect/Context";
|
|
6
5
|
import * as Data from "effect/Data";
|
|
7
6
|
import * as Effect from "effect/Effect";
|
|
8
|
-
import * as Exit from "effect/Exit";
|
|
9
7
|
import * as Layer from "effect/Layer";
|
|
10
|
-
import * as Option from "effect/Option";
|
|
11
8
|
import * as Path from "effect/Path";
|
|
12
9
|
import * as Redacted from "effect/Redacted";
|
|
13
10
|
import * as Schedule from "effect/Schedule";
|
|
14
|
-
import * as Scope from "effect/Scope";
|
|
15
|
-
import * as Stream from "effect/Stream";
|
|
16
11
|
import { Unowned } from "../../AdoptPolicy.ts";
|
|
17
12
|
import { AlchemyContext } from "../../AlchemyContext.ts";
|
|
18
13
|
import * as Artifacts from "../../Artifacts.ts";
|
|
19
|
-
import * as Binding from "../../Binding.ts";
|
|
20
14
|
import { hashDirectory, type MemoOptions } from "../../Build/Memo.ts";
|
|
21
15
|
import * as Bundle from "../../Bundle/Bundle.ts";
|
|
22
16
|
import type { ScopedPlanStatusSession } from "../../Cli/Cli.ts";
|
|
23
17
|
import { isResolved } from "../../Diff.ts";
|
|
24
|
-
import { ExecutionContext } from "../../ExecutionContext.ts";
|
|
25
|
-
import type { HttpEffect } from "../../Http.ts";
|
|
26
18
|
import type { InputProps } from "../../Input.ts";
|
|
27
|
-
import
|
|
28
|
-
import {
|
|
29
|
-
Platform,
|
|
30
|
-
type Main,
|
|
31
|
-
type PlatformProps,
|
|
32
|
-
type Rpc,
|
|
33
|
-
} from "../../Platform.ts";
|
|
19
|
+
import { Platform, type Main, type PlatformProps } from "../../Platform.ts";
|
|
34
20
|
import * as Provider from "../../Provider.ts";
|
|
35
21
|
import { Resource, type ResourceBinding } from "../../Resource.ts";
|
|
36
|
-
import * as Serverless from "../../Serverless/index.ts";
|
|
37
22
|
import { Stack } from "../../Stack.ts";
|
|
38
|
-
import { isYieldableEffectLike } from "../../Util/effect.ts";
|
|
39
|
-
import type { AiGateway } from "../AiGateway/AiGateway.ts";
|
|
40
|
-
import {
|
|
41
|
-
isAnalyticsEngineDataset,
|
|
42
|
-
type AnalyticsEngineDataset,
|
|
43
|
-
} from "../AnalyticsEngine/AnalyticsEngineDataset.ts";
|
|
44
|
-
import {
|
|
45
|
-
isArtifacts as isArtifactsBinding,
|
|
46
|
-
type Artifacts as ArtifactsBinding,
|
|
47
|
-
} from "../Artifacts/Artifacts.ts";
|
|
48
23
|
import { CloudflareEnvironment } from "../CloudflareEnvironment.ts";
|
|
49
|
-
import {
|
|
50
|
-
import { isSendEmail, type SendEmail } from "../Email/SendEmail.ts";
|
|
51
|
-
import type {
|
|
52
|
-
Hyperdrive,
|
|
53
|
-
HyperdriveDevOrigin,
|
|
54
|
-
} from "../Hyperdrive/Hyperdrive.ts";
|
|
55
|
-
import {
|
|
56
|
-
isImages as isImagesBinding,
|
|
57
|
-
type Images as ImagesBinding,
|
|
58
|
-
} from "../Images/Images.ts";
|
|
59
|
-
import type { KVNamespace } from "../KV/KVNamespace.ts";
|
|
24
|
+
import type { HyperdriveDevOrigin } from "../Hyperdrive/Hyperdrive.ts";
|
|
60
25
|
import { SidecarLive } from "../Local/Sidecar.ts";
|
|
61
26
|
import { CloudflareLogs } from "../Logs.ts";
|
|
62
27
|
import type { Providers } from "../Providers.ts";
|
|
63
|
-
import type { Queue as CloudflareQueue } from "../Queue/Queue.ts";
|
|
64
|
-
import type { R2Bucket } from "../R2/R2Bucket.ts";
|
|
65
28
|
import {
|
|
66
|
-
isAssets,
|
|
67
29
|
readAssets,
|
|
68
30
|
uploadAssets,
|
|
69
31
|
type Assets,
|
|
@@ -71,28 +33,29 @@ import {
|
|
|
71
33
|
type AssetsProps,
|
|
72
34
|
} from "./Assets.ts";
|
|
73
35
|
import { getCompatibility } from "./Compatibility.ts";
|
|
74
|
-
import {
|
|
75
|
-
isDurableObjectExport,
|
|
76
|
-
isDurableObjectNamespaceLike,
|
|
77
|
-
type DurableObjectNamespaceLike,
|
|
78
|
-
} from "./DurableObjectNamespace.ts";
|
|
79
|
-
import { workersHttpHandler } from "./HttpServer.ts";
|
|
36
|
+
import { isDurableObjectExport } from "./DurableObjectNamespace.ts";
|
|
80
37
|
import { LocalWorkerProvider } from "./LocalWorkerProvider.ts";
|
|
81
38
|
import { Request } from "./Request.ts";
|
|
82
|
-
import {
|
|
83
|
-
encodeRpcError,
|
|
84
|
-
ErrorTag,
|
|
85
|
-
makeRpcStub,
|
|
86
|
-
toRpcStream,
|
|
87
|
-
type RpcErrorEnvelope,
|
|
88
|
-
type RpcStreamEnvelope,
|
|
89
|
-
} from "./Rpc.ts";
|
|
90
39
|
import * as Vite from "./Vite.ts";
|
|
40
|
+
import {
|
|
41
|
+
bindWorkerAsyncBindings,
|
|
42
|
+
getCronBindings,
|
|
43
|
+
} from "./WorkerAsyncBindings.ts";
|
|
44
|
+
import type {
|
|
45
|
+
WorkerBinding,
|
|
46
|
+
WorkerBindingResource,
|
|
47
|
+
WorkerBindings,
|
|
48
|
+
WorkerSettingsBinding,
|
|
49
|
+
} from "./WorkerBinding.ts";
|
|
91
50
|
import { WorkerBundle } from "./WorkerBundle.ts";
|
|
92
51
|
import { createWorkerName } from "./WorkerName.ts";
|
|
52
|
+
import {
|
|
53
|
+
makeWorkerRuntimeContext,
|
|
54
|
+
type WorkerRuntimeContext,
|
|
55
|
+
} from "./WorkerRuntimeContext.ts";
|
|
93
56
|
|
|
94
|
-
const WorkerTypeId = "Cloudflare.Worker";
|
|
95
|
-
type WorkerTypeId = typeof WorkerTypeId;
|
|
57
|
+
export const WorkerTypeId = "Cloudflare.Worker";
|
|
58
|
+
export type WorkerTypeId = typeof WorkerTypeId;
|
|
96
59
|
|
|
97
60
|
export const isWorker = <T>(value: T): value is T & Worker =>
|
|
98
61
|
typeof value === "object" &&
|
|
@@ -162,16 +125,6 @@ export type WorkerPlacement = Exclude<
|
|
|
162
125
|
undefined
|
|
163
126
|
>;
|
|
164
127
|
|
|
165
|
-
export type WorkerBinding = Exclude<
|
|
166
|
-
workers.PutScriptRequest["metadata"]["bindings"],
|
|
167
|
-
undefined
|
|
168
|
-
>[number];
|
|
169
|
-
|
|
170
|
-
type WorkerSettingsBinding = Exclude<
|
|
171
|
-
workers.GetScriptScriptAndVersionSettingResponse["bindings"],
|
|
172
|
-
null | undefined
|
|
173
|
-
>[number];
|
|
174
|
-
|
|
175
128
|
export const ExportedHandlerMethods = [
|
|
176
129
|
"fetch",
|
|
177
130
|
"tail",
|
|
@@ -183,32 +136,20 @@ export const ExportedHandlerMethods = [
|
|
|
183
136
|
"queue",
|
|
184
137
|
] as const satisfies (keyof cf.ExportedHandler)[];
|
|
185
138
|
|
|
186
|
-
export
|
|
187
|
-
export(name: string, value: any): Effect.Effect<void>;
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
export type WorkerServices = Worker | Request;
|
|
139
|
+
export type WorkerServices = Worker | Request | WorkerExecutionContext;
|
|
191
140
|
|
|
192
141
|
export type WorkerShape = Main<WorkerServices | WorkerEnvironment>;
|
|
193
142
|
|
|
194
|
-
export type
|
|
195
|
-
|
|
196
|
-
|
|
|
197
|
-
|
|
|
198
|
-
|
|
|
199
|
-
|
|
|
200
|
-
|
|
|
201
|
-
|
|
|
202
|
-
|
|
|
203
|
-
|
|
204
|
-
| ImagesBinding
|
|
205
|
-
| Hyperdrive
|
|
206
|
-
| Worker
|
|
207
|
-
| DurableObjectNamespaceLike<any>;
|
|
208
|
-
|
|
209
|
-
export type WorkerBindings = {
|
|
210
|
-
[bindingName in string]: WorkerBindingResource;
|
|
211
|
-
};
|
|
143
|
+
export type WorkerEnv = Record<
|
|
144
|
+
string,
|
|
145
|
+
| string
|
|
146
|
+
| number
|
|
147
|
+
| boolean
|
|
148
|
+
| null
|
|
149
|
+
| readonly unknown[]
|
|
150
|
+
| { readonly [key: string]: unknown }
|
|
151
|
+
| Redacted.Redacted<string>
|
|
152
|
+
>;
|
|
212
153
|
|
|
213
154
|
export type WorkerBindingProps = {
|
|
214
155
|
[bindingName in string]:
|
|
@@ -233,6 +174,7 @@ export type WorkerAssetsConfig = string | AssetsProps | AssetsWithHash;
|
|
|
233
174
|
|
|
234
175
|
export interface WorkerProps<
|
|
235
176
|
Bindings extends WorkerBindingProps = any,
|
|
177
|
+
Env extends WorkerEnv = WorkerEnv,
|
|
236
178
|
Assets extends WorkerAssetsConfig | undefined =
|
|
237
179
|
| WorkerAssetsConfig
|
|
238
180
|
| undefined,
|
|
@@ -282,16 +224,7 @@ export interface WorkerProps<
|
|
|
282
224
|
};
|
|
283
225
|
limits?: WorkerLimits;
|
|
284
226
|
placement?: WorkerPlacement;
|
|
285
|
-
env?:
|
|
286
|
-
string,
|
|
287
|
-
| string
|
|
288
|
-
| number
|
|
289
|
-
| boolean
|
|
290
|
-
| null
|
|
291
|
-
| readonly unknown[]
|
|
292
|
-
| { readonly [key: string]: unknown }
|
|
293
|
-
| Redacted.Redacted<string>
|
|
294
|
-
>;
|
|
227
|
+
env?: Env;
|
|
295
228
|
exports?: string[];
|
|
296
229
|
bindings?: Bindings;
|
|
297
230
|
/**
|
|
@@ -718,414 +651,40 @@ export const Worker: Platform<
|
|
|
718
651
|
WorkerRuntimeContext
|
|
719
652
|
> & {
|
|
720
653
|
<
|
|
721
|
-
const Bindings extends WorkerBindingProps,
|
|
654
|
+
const Bindings extends WorkerBindingProps = {},
|
|
655
|
+
const Env extends WorkerEnv = {},
|
|
722
656
|
const Assets extends WorkerAssetsConfig | undefined = undefined,
|
|
723
657
|
Req = never,
|
|
724
658
|
>(
|
|
725
659
|
id: string,
|
|
726
660
|
props:
|
|
727
|
-
|
|
|
728
|
-
| Effect.Effect<
|
|
661
|
+
| WorkerProps<Bindings, Env, Assets>
|
|
662
|
+
| Effect.Effect<
|
|
663
|
+
InputProps<WorkerProps<Bindings, Env, Assets>>,
|
|
664
|
+
never,
|
|
665
|
+
Req
|
|
666
|
+
>,
|
|
729
667
|
): Effect.Effect<
|
|
730
|
-
Worker<
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
668
|
+
Worker<
|
|
669
|
+
{
|
|
670
|
+
[binding in keyof NormalizedBindings<
|
|
671
|
+
Bindings,
|
|
672
|
+
Assets
|
|
673
|
+
>]: NormalizedBindings<Bindings, Assets>[binding];
|
|
674
|
+
} & {
|
|
675
|
+
[K in keyof Env]: Env[K] extends Redacted.Redacted<infer T>
|
|
676
|
+
? T
|
|
677
|
+
: Env[K];
|
|
678
|
+
}
|
|
679
|
+
>,
|
|
736
680
|
never,
|
|
737
681
|
Req | Providers
|
|
738
682
|
>;
|
|
739
683
|
} = Platform(WorkerTypeId, {
|
|
740
|
-
onCreate:
|
|
741
|
-
|
|
742
|
-
props: InputProps<WorkerProps<WorkerBindingProps>>,
|
|
743
|
-
) {
|
|
744
|
-
if (props.bindings) {
|
|
745
|
-
for (const bindingName in props.bindings) {
|
|
746
|
-
// @ts-expect-error
|
|
747
|
-
const bindingEff = props.bindings?.[bindingName] as
|
|
748
|
-
| WorkerBindingResource
|
|
749
|
-
| Effect.Effect<WorkerBindingResource>;
|
|
750
|
-
// Bindings can be passed as a plain resource value, an Effect that
|
|
751
|
-
// yields a resource, or an effect-class (e.g. a `Cloudflare.Worker`
|
|
752
|
-
// class). Resolve the yieldable forms before deriving binding metadata.
|
|
753
|
-
const binding = isYieldableEffectLike(bindingEff)
|
|
754
|
-
? ((yield* bindingEff as Effect.Effect<unknown>) as WorkerBindingResource)
|
|
755
|
-
: bindingEff;
|
|
756
|
-
|
|
757
|
-
const bindingMeta: InputProps<WorkerBinding> | undefined = isAssets(
|
|
758
|
-
binding,
|
|
759
|
-
)
|
|
760
|
-
? {
|
|
761
|
-
type: "assets",
|
|
762
|
-
name: bindingName,
|
|
763
|
-
}
|
|
764
|
-
: isArtifactsBinding(binding)
|
|
765
|
-
? ({
|
|
766
|
-
type: "artifacts",
|
|
767
|
-
name: bindingName,
|
|
768
|
-
namespace: binding.namespace,
|
|
769
|
-
} as any)
|
|
770
|
-
: isImagesBinding(binding)
|
|
771
|
-
? {
|
|
772
|
-
type: "images",
|
|
773
|
-
name: bindingName,
|
|
774
|
-
}
|
|
775
|
-
: isAnalyticsEngineDataset(binding)
|
|
776
|
-
? {
|
|
777
|
-
type: "analytics_engine",
|
|
778
|
-
name: bindingName,
|
|
779
|
-
dataset: binding.dataset,
|
|
780
|
-
}
|
|
781
|
-
: isSendEmail(binding)
|
|
782
|
-
? {
|
|
783
|
-
type: "send_email",
|
|
784
|
-
name: bindingName,
|
|
785
|
-
destinationAddress: binding.destinationAddress,
|
|
786
|
-
allowedDestinationAddresses:
|
|
787
|
-
binding.allowedDestinationAddresses,
|
|
788
|
-
allowedSenderAddresses: binding.allowedSenderAddresses,
|
|
789
|
-
}
|
|
790
|
-
: isDurableObjectNamespaceLike(binding)
|
|
791
|
-
? {
|
|
792
|
-
type: "durable_object_namespace",
|
|
793
|
-
name: bindingName,
|
|
794
|
-
className: binding.className ?? binding.name,
|
|
795
|
-
}
|
|
796
|
-
: binding.Type === "Cloudflare.D1Database"
|
|
797
|
-
? {
|
|
798
|
-
type: "d1",
|
|
799
|
-
id: binding.databaseId,
|
|
800
|
-
name: bindingName,
|
|
801
|
-
}
|
|
802
|
-
: binding.Type === "Cloudflare.R2Bucket"
|
|
803
|
-
? {
|
|
804
|
-
type: "r2_bucket",
|
|
805
|
-
name: bindingName,
|
|
806
|
-
bucketName: binding.bucketName,
|
|
807
|
-
jurisdiction: binding.jurisdiction.pipe(
|
|
808
|
-
Output.map((jurisdiction) =>
|
|
809
|
-
jurisdiction === "default"
|
|
810
|
-
? undefined
|
|
811
|
-
: jurisdiction,
|
|
812
|
-
),
|
|
813
|
-
),
|
|
814
|
-
}
|
|
815
|
-
: binding.Type === "Cloudflare.KVNamespace"
|
|
816
|
-
? {
|
|
817
|
-
type: "kv_namespace",
|
|
818
|
-
name: bindingName,
|
|
819
|
-
namespaceId: binding.namespaceId,
|
|
820
|
-
}
|
|
821
|
-
: binding.Type === "Cloudflare.Queue"
|
|
822
|
-
? {
|
|
823
|
-
type: "queue",
|
|
824
|
-
name: bindingName,
|
|
825
|
-
queueName: binding.queueName,
|
|
826
|
-
}
|
|
827
|
-
: binding.Type === "Cloudflare.AiGateway"
|
|
828
|
-
? {
|
|
829
|
-
type: "ai",
|
|
830
|
-
name: bindingName,
|
|
831
|
-
}
|
|
832
|
-
: binding.Type === "Cloudflare.Hyperdrive"
|
|
833
|
-
? {
|
|
834
|
-
type: "hyperdrive",
|
|
835
|
-
name: bindingName,
|
|
836
|
-
id: binding.hyperdriveId,
|
|
837
|
-
}
|
|
838
|
-
: isWorker(binding)
|
|
839
|
-
? {
|
|
840
|
-
type: "service",
|
|
841
|
-
name: bindingName,
|
|
842
|
-
service: binding.workerName,
|
|
843
|
-
}
|
|
844
|
-
: // TODO(sam): handle others
|
|
845
|
-
undefined;
|
|
846
|
-
|
|
847
|
-
if (bindingMeta) {
|
|
848
|
-
yield* resource.bind`${bindingName}`({
|
|
849
|
-
bindings: [bindingMeta],
|
|
850
|
-
});
|
|
851
|
-
} else {
|
|
852
|
-
return yield* Effect.die(`Unknown binding type: ${bindingName}`);
|
|
853
|
-
}
|
|
854
|
-
}
|
|
855
|
-
}
|
|
856
|
-
}),
|
|
857
|
-
createRuntimeContext: (id: string): WorkerRuntimeContext => {
|
|
858
|
-
const listeners: Effect.Effect<Serverless.FunctionListener>[] = [];
|
|
859
|
-
const exports: Record<string, any> = {};
|
|
860
|
-
const env: Record<string, any> = {};
|
|
861
|
-
let userShape: Record<string, unknown> | undefined;
|
|
862
|
-
|
|
863
|
-
const ctx = {
|
|
864
|
-
Type: WorkerTypeId,
|
|
865
|
-
id,
|
|
866
|
-
env,
|
|
867
|
-
get: (key: string) =>
|
|
868
|
-
Effect.serviceOption(WorkerEnvironment).pipe(
|
|
869
|
-
Effect.map(Option.getOrUndefined),
|
|
870
|
-
Effect.flatMap((env) =>
|
|
871
|
-
env
|
|
872
|
-
? Effect.succeed(env[key])
|
|
873
|
-
: Effect.die("WorkerEnvironment not found"),
|
|
874
|
-
),
|
|
875
|
-
Effect.flatMap((value) =>
|
|
876
|
-
value
|
|
877
|
-
? Effect.succeed(value)
|
|
878
|
-
: Effect.die(`Environment variable '${key}' not found`),
|
|
879
|
-
),
|
|
880
|
-
Effect.map((json) => {
|
|
881
|
-
try {
|
|
882
|
-
const value = JSON.parse(json);
|
|
883
|
-
// The `set` path serializes Redacted values as
|
|
884
|
-
// `{_tag: "Redacted", value: ...}`. After JSON.parse the
|
|
885
|
-
// result is a plain object — `Redacted.isRedacted` would
|
|
886
|
-
// always return `false` on it — so detect the marker shape
|
|
887
|
-
// and rebuild the Redacted wrapper. Plain values pass
|
|
888
|
-
// through unchanged.
|
|
889
|
-
if (
|
|
890
|
-
value !== null &&
|
|
891
|
-
typeof value === "object" &&
|
|
892
|
-
(value as { _tag?: unknown })._tag === "Redacted" &&
|
|
893
|
-
"value" in (value as object)
|
|
894
|
-
) {
|
|
895
|
-
return Redacted.make((value as { value: unknown }).value);
|
|
896
|
-
}
|
|
897
|
-
return value;
|
|
898
|
-
} catch {
|
|
899
|
-
return json;
|
|
900
|
-
}
|
|
901
|
-
}),
|
|
902
|
-
) as any,
|
|
903
|
-
set: (id: string, output: Output.Output) =>
|
|
904
|
-
Effect.sync(() => {
|
|
905
|
-
const key = id.replaceAll(/[^a-zA-Z0-9]/g, "_");
|
|
906
|
-
// Preserve `Redacted`-ness across the Output → env → Cloudflare
|
|
907
|
-
// binding boundary so the put-worker loop can deploy secrets via
|
|
908
|
-
// `secret_text` instead of leaking them as `plain_text`. The JSON
|
|
909
|
-
// payload still carries the `{_tag: "Redacted", …}` marker so the
|
|
910
|
-
// runtime `get` accessor can rebuild the wrapper after Cloudflare
|
|
911
|
-
// hands the binding back as a plain string.
|
|
912
|
-
env[key] = output.pipe(
|
|
913
|
-
Output.map((value) =>
|
|
914
|
-
Redacted.isRedacted(value)
|
|
915
|
-
? Redacted.make(
|
|
916
|
-
JSON.stringify({
|
|
917
|
-
_tag: "Redacted",
|
|
918
|
-
value: Redacted.value(value),
|
|
919
|
-
}),
|
|
920
|
-
)
|
|
921
|
-
: JSON.stringify(value),
|
|
922
|
-
),
|
|
923
|
-
);
|
|
924
|
-
return key;
|
|
925
|
-
}),
|
|
926
|
-
serve: <Req = never>(
|
|
927
|
-
handler: HttpEffect<Req> | Effect.Effect<HttpEffect<Req>>,
|
|
928
|
-
options?: { shape?: Record<string, unknown> },
|
|
929
|
-
) => {
|
|
930
|
-
// Capture the user's full default-export shape so `exports` can
|
|
931
|
-
// expose any non-handler methods on it as RPC methods on the
|
|
932
|
-
// deployed `WorkerEntrypoint` subclass — see `__rpc__` below.
|
|
933
|
-
if (options?.shape) userShape = options.shape;
|
|
934
|
-
return ctx.listen(workersHttpHandler(handler));
|
|
935
|
-
},
|
|
936
|
-
listen: ((
|
|
937
|
-
handler:
|
|
938
|
-
| Serverless.FunctionListener
|
|
939
|
-
| Effect.Effect<Serverless.FunctionListener>,
|
|
940
|
-
) =>
|
|
941
|
-
Effect.sync(() =>
|
|
942
|
-
Effect.isEffect(handler)
|
|
943
|
-
? listeners.push(handler)
|
|
944
|
-
: listeners.push(Effect.succeed(handler)),
|
|
945
|
-
)) as any as Serverless.FunctionContext["listen"],
|
|
946
|
-
export: (name: string, value: any) =>
|
|
947
|
-
Effect.sync(() => {
|
|
948
|
-
exports[name] = value;
|
|
949
|
-
}),
|
|
950
|
-
exports: Effect.gen(function* () {
|
|
951
|
-
const handlers = yield* Effect.all(listeners, {
|
|
952
|
-
concurrency: "unbounded",
|
|
953
|
-
});
|
|
954
|
-
const services = yield* Effect.context();
|
|
955
|
-
|
|
956
|
-
// Provide the per-request runtime layer (services + `WorkerExecutionContext`
|
|
957
|
-
// + a fresh `ExecutionContext`/`Scope`) to a user effect, then run it.
|
|
958
|
-
// This is the bridge between Cloudflare's request-time callback and
|
|
959
|
-
// the user's Effect-native handler. Used by both the standard
|
|
960
|
-
// `handle()` dispatch (fetch/scheduled/…) and the per-RPC dispatchers
|
|
961
|
-
// below — keeping them on a single layer-provision path.
|
|
962
|
-
const runUserEffect = <A, E>(
|
|
963
|
-
eff: Effect.Effect<A, E>,
|
|
964
|
-
context: cf.ExecutionContext,
|
|
965
|
-
): Promise<Exit.Exit<A, E>> => {
|
|
966
|
-
const scope = Scope.makeUnsafe();
|
|
967
|
-
return eff
|
|
968
|
-
.pipe(
|
|
969
|
-
Effect.provideContext(services),
|
|
970
|
-
Scope.provide(scope),
|
|
971
|
-
Effect.provide(Layer.succeed(WorkerExecutionContext, context)),
|
|
972
|
-
Effect.provide(
|
|
973
|
-
Layer.succeed(ExecutionContext, { scope, cache: {} }),
|
|
974
|
-
),
|
|
975
|
-
Effect.runPromiseExit,
|
|
976
|
-
)
|
|
977
|
-
.finally(() =>
|
|
978
|
-
context.waitUntil(
|
|
979
|
-
Effect.runPromise(Scope.close(scope, Exit.void)),
|
|
980
|
-
),
|
|
981
|
-
);
|
|
982
|
-
};
|
|
983
|
-
|
|
984
|
-
const handle =
|
|
985
|
-
(type: WorkerEvent["type"]) =>
|
|
986
|
-
(request: any, env: unknown, context: cf.ExecutionContext) => {
|
|
987
|
-
const event: WorkerEvent = {
|
|
988
|
-
kind: "Cloudflare.Workers.WorkerEvent",
|
|
989
|
-
type,
|
|
990
|
-
input: request,
|
|
991
|
-
env,
|
|
992
|
-
context,
|
|
993
|
-
};
|
|
994
|
-
for (const handler of handlers) {
|
|
995
|
-
const eff = handler(event);
|
|
996
|
-
if (Effect.isEffect(eff)) {
|
|
997
|
-
return runUserEffect(
|
|
998
|
-
eff as Effect.Effect<unknown, unknown>,
|
|
999
|
-
context,
|
|
1000
|
-
).then((exit) => {
|
|
1001
|
-
if (exit._tag === "Success") return exit.value;
|
|
1002
|
-
throw Cause.squash(exit.cause);
|
|
1003
|
-
});
|
|
1004
|
-
}
|
|
1005
|
-
}
|
|
1006
|
-
return Promise.reject(new Error("No event handler found"));
|
|
1007
|
-
};
|
|
1008
|
-
|
|
1009
|
-
// RPC method dispatchers — one per non-handler method on the user's
|
|
1010
|
-
// shape. Each dispatcher is invoked by the WorkerEntrypoint bridge
|
|
1011
|
-
// as `dispatcher(args, ctx)`: `args` are the user-facing call args,
|
|
1012
|
-
// `ctx` is the `this.ctx` that Cloudflare hands the bridge per RPC
|
|
1013
|
-
// request. The dispatcher runs the user effect with the same runtime
|
|
1014
|
-
// layer the fetch path uses, then envelope-encodes the result so
|
|
1015
|
-
// `Effect.fail` round-trips as `RpcErrorEnvelope` and `Stream` as
|
|
1016
|
-
// `RpcStreamEnvelope` (consumers wrap the binding with
|
|
1017
|
-
// `toPromiseApi`/`bindWorker` to decode).
|
|
1018
|
-
const exportedHandlerSet = new Set<string>(ExportedHandlerMethods);
|
|
1019
|
-
const rpcDispatchers: Record<
|
|
1020
|
-
string,
|
|
1021
|
-
(args: unknown[], ctx: cf.ExecutionContext) => Promise<unknown>
|
|
1022
|
-
> = {};
|
|
1023
|
-
if (userShape) {
|
|
1024
|
-
for (const [name, value] of Object.entries(userShape)) {
|
|
1025
|
-
if (exportedHandlerSet.has(name)) continue;
|
|
1026
|
-
if (typeof value !== "function") continue;
|
|
1027
|
-
rpcDispatchers[name] = async (
|
|
1028
|
-
args: unknown[],
|
|
1029
|
-
context: cf.ExecutionContext,
|
|
1030
|
-
) => {
|
|
1031
|
-
const result = (value as (...a: unknown[]) => unknown)(...args);
|
|
1032
|
-
if (!Effect.isEffect(result)) return result;
|
|
1033
|
-
const exit = await runUserEffect(
|
|
1034
|
-
result as Effect.Effect<unknown, unknown>,
|
|
1035
|
-
context,
|
|
1036
|
-
);
|
|
1037
|
-
if (exit._tag === "Success") {
|
|
1038
|
-
if (Stream.isStream(exit.value)) {
|
|
1039
|
-
return await Effect.runPromise(
|
|
1040
|
-
toRpcStream(exit.value) as Effect.Effect<RpcStreamEnvelope>,
|
|
1041
|
-
);
|
|
1042
|
-
}
|
|
1043
|
-
return exit.value;
|
|
1044
|
-
}
|
|
1045
|
-
const failReason = exit.cause.reasons.find(Cause.isFailReason);
|
|
1046
|
-
if (failReason) {
|
|
1047
|
-
return {
|
|
1048
|
-
_tag: ErrorTag,
|
|
1049
|
-
error: encodeRpcError(failReason.error),
|
|
1050
|
-
} satisfies RpcErrorEnvelope;
|
|
1051
|
-
}
|
|
1052
|
-
const dieReason = exit.cause.reasons.find(Cause.isDieReason);
|
|
1053
|
-
throw (
|
|
1054
|
-
dieReason?.defect ??
|
|
1055
|
-
new Error("RPC method failed with an unexpected cause")
|
|
1056
|
-
);
|
|
1057
|
-
};
|
|
1058
|
-
}
|
|
1059
|
-
}
|
|
1060
|
-
|
|
1061
|
-
return {
|
|
1062
|
-
...exports,
|
|
1063
|
-
default: Object.fromEntries(
|
|
1064
|
-
ExportedHandlerMethods.map((method) => [method, handle(method)]),
|
|
1065
|
-
),
|
|
1066
|
-
__rpc__: rpcDispatchers,
|
|
1067
|
-
};
|
|
1068
|
-
}),
|
|
1069
|
-
};
|
|
1070
|
-
return ctx;
|
|
1071
|
-
},
|
|
1072
|
-
});
|
|
1073
|
-
|
|
1074
|
-
export const bindWorker = Effect.fnUntraced(function* <Shape, Req = never>(
|
|
1075
|
-
workerEff:
|
|
1076
|
-
| (Worker & Rpc<Shape>)
|
|
1077
|
-
| Effect.Effect<Worker & Rpc<Shape>, never, Req>,
|
|
1078
|
-
) {
|
|
1079
|
-
// Worker classes and regular Effects are both yieldable here.
|
|
1080
|
-
const worker = isYieldableEffectLike(workerEff)
|
|
1081
|
-
? yield* workerEff as Effect.Effect<Worker & Rpc<Shape>, never, Req>
|
|
1082
|
-
: workerEff;
|
|
1083
|
-
const self = yield* Worker;
|
|
1084
|
-
yield* self.bind`${worker}`({
|
|
1085
|
-
bindings: [
|
|
1086
|
-
{
|
|
1087
|
-
type: "service",
|
|
1088
|
-
name: worker.LogicalId,
|
|
1089
|
-
service: worker.workerName,
|
|
1090
|
-
},
|
|
1091
|
-
],
|
|
1092
|
-
});
|
|
1093
|
-
|
|
1094
|
-
// `bindWorker` runs at *init* phase (both at plantime and at runtime
|
|
1095
|
-
// cold-start). `WorkerEnvironment` only exists at exec phase on the
|
|
1096
|
-
// deployed worker, so we hand `makeRpcStub` an `Effect<stub>` that
|
|
1097
|
-
// resolves the binding lazily on each method call.
|
|
1098
|
-
const stubEff = WorkerEnvironment.pipe(
|
|
1099
|
-
Effect.map((env) => (env as Record<string, unknown>)[worker.LogicalId]),
|
|
1100
|
-
);
|
|
1101
|
-
return makeRpcStub<Shape>(stubEff);
|
|
684
|
+
onCreate: bindWorkerAsyncBindings,
|
|
685
|
+
createRuntimeContext: makeWorkerRuntimeContext,
|
|
1102
686
|
});
|
|
1103
687
|
|
|
1104
|
-
export class BindWorkerPolicy extends Binding.Policy<
|
|
1105
|
-
BindWorkerPolicy,
|
|
1106
|
-
(worker: Worker) => Effect.Effect<void>
|
|
1107
|
-
>()("Cloudflare.Worker.Bind") {}
|
|
1108
|
-
|
|
1109
|
-
export const BindWorkerPolicyLive = BindWorkerPolicy.layer.succeed(
|
|
1110
|
-
Effect.fn(function* (host, worker: Worker) {
|
|
1111
|
-
if (isWorker(host)) {
|
|
1112
|
-
yield* host.bind`${worker}`({
|
|
1113
|
-
bindings: [
|
|
1114
|
-
{
|
|
1115
|
-
type: "service",
|
|
1116
|
-
name: worker.LogicalId,
|
|
1117
|
-
service: worker.workerName,
|
|
1118
|
-
},
|
|
1119
|
-
],
|
|
1120
|
-
});
|
|
1121
|
-
} else {
|
|
1122
|
-
return yield* Effect.die(
|
|
1123
|
-
new Error(`BindWorkerPolicy does not support runtime '${host.Type}'`),
|
|
1124
|
-
);
|
|
1125
|
-
}
|
|
1126
|
-
}),
|
|
1127
|
-
);
|
|
1128
|
-
|
|
1129
688
|
class MissingDurableObjectNamespaces extends Data.TaggedError(
|
|
1130
689
|
"MissingDurableObjectNamespaces",
|
|
1131
690
|
)<{
|
|
@@ -1133,59 +692,6 @@ class MissingDurableObjectNamespaces extends Data.TaggedError(
|
|
|
1133
692
|
expected: string[];
|
|
1134
693
|
}> {}
|
|
1135
694
|
|
|
1136
|
-
function bumpMigrationTagVersion(
|
|
1137
|
-
oldTag: string | undefined,
|
|
1138
|
-
): string | undefined {
|
|
1139
|
-
if (!oldTag) return undefined;
|
|
1140
|
-
const version = oldTag.match(/^(alchemy:)?v(\d+)$/)?.[2];
|
|
1141
|
-
if (!version) return "alchemy:v1";
|
|
1142
|
-
return `alchemy:v${parseInt(version, 10) + 1}`;
|
|
1143
|
-
}
|
|
1144
|
-
|
|
1145
|
-
function getDurableObjectBindings(
|
|
1146
|
-
bindings: ReadonlyArray<ResourceBinding>,
|
|
1147
|
-
workerName: string,
|
|
1148
|
-
) {
|
|
1149
|
-
return bindings.flatMap((binding) =>
|
|
1150
|
-
(binding.data.bindings ?? []).flatMap((item: WorkerBinding) =>
|
|
1151
|
-
item.type === "durable_object_namespace" &&
|
|
1152
|
-
"className" in item &&
|
|
1153
|
-
item.className &&
|
|
1154
|
-
(!("scriptName" in item) ||
|
|
1155
|
-
!item.scriptName ||
|
|
1156
|
-
item.scriptName === workerName)
|
|
1157
|
-
? [
|
|
1158
|
-
{
|
|
1159
|
-
logicalId: binding.sid,
|
|
1160
|
-
bindingName: item.name,
|
|
1161
|
-
className: item.className,
|
|
1162
|
-
},
|
|
1163
|
-
]
|
|
1164
|
-
: [],
|
|
1165
|
-
),
|
|
1166
|
-
);
|
|
1167
|
-
}
|
|
1168
|
-
|
|
1169
|
-
export function getCronBindings(
|
|
1170
|
-
bindings: ReadonlyArray<ResourceBinding<Worker["Binding"]>>,
|
|
1171
|
-
) {
|
|
1172
|
-
return Array.from(new Set(bindings.flatMap((b) => b.data.crons ?? [])));
|
|
1173
|
-
}
|
|
1174
|
-
|
|
1175
|
-
function getDurableObjectTagMap(tags: ReadonlyArray<string>) {
|
|
1176
|
-
return Object.fromEntries(
|
|
1177
|
-
tags.flatMap((tag) => {
|
|
1178
|
-
if (!tag.startsWith("alchemy:do:")) {
|
|
1179
|
-
return [];
|
|
1180
|
-
}
|
|
1181
|
-
const parts = tag.split(":");
|
|
1182
|
-
const logicalId = parts[2];
|
|
1183
|
-
const className = parts.slice(3).join(":");
|
|
1184
|
-
return logicalId && className ? [[logicalId, className]] : [];
|
|
1185
|
-
}),
|
|
1186
|
-
);
|
|
1187
|
-
}
|
|
1188
|
-
|
|
1189
695
|
const selectLayer = <
|
|
1190
696
|
LayerLive extends Layer.Layer<any, any, any>,
|
|
1191
697
|
LayerDev extends Layer.Layer<any, any, any>,
|
|
@@ -2517,6 +2023,12 @@ export const LiveWorkerProvider = () =>
|
|
|
2517
2023
|
yield* deleteScript({
|
|
2518
2024
|
accountId: output.accountId,
|
|
2519
2025
|
scriptName: output.workerName,
|
|
2026
|
+
// Force teardown of queue consumers, durable object classes, and
|
|
2027
|
+
// service bindings hanging off this worker. Without `force`, those
|
|
2028
|
+
// conditions raise QueueConsumerConflict / ServiceBindingConflict
|
|
2029
|
+
// and leave the script in CF. Alchemy is the source of truth for
|
|
2030
|
+
// the worker, so we want a hard delete on teardown.
|
|
2031
|
+
force: true,
|
|
2520
2032
|
}).pipe(Effect.catchTag("WorkerNotFound", () => Effect.void));
|
|
2521
2033
|
}),
|
|
2522
2034
|
tail: ({ output }) =>
|
|
@@ -2563,3 +2075,50 @@ const contentTypeFromExtension = (extension: string) => {
|
|
|
2563
2075
|
return "application/octet-stream";
|
|
2564
2076
|
}
|
|
2565
2077
|
};
|
|
2078
|
+
|
|
2079
|
+
function bumpMigrationTagVersion(
|
|
2080
|
+
oldTag: string | undefined,
|
|
2081
|
+
): string | undefined {
|
|
2082
|
+
if (!oldTag) return undefined;
|
|
2083
|
+
const version = oldTag.match(/^(alchemy:)?v(\d+)$/)?.[2];
|
|
2084
|
+
if (!version) return "alchemy:v1";
|
|
2085
|
+
return `alchemy:v${parseInt(version, 10) + 1}`;
|
|
2086
|
+
}
|
|
2087
|
+
|
|
2088
|
+
function getDurableObjectBindings(
|
|
2089
|
+
bindings: ReadonlyArray<ResourceBinding>,
|
|
2090
|
+
workerName: string,
|
|
2091
|
+
) {
|
|
2092
|
+
return bindings.flatMap((binding) =>
|
|
2093
|
+
(binding.data.bindings ?? []).flatMap((item: WorkerBinding) =>
|
|
2094
|
+
item.type === "durable_object_namespace" &&
|
|
2095
|
+
"className" in item &&
|
|
2096
|
+
item.className &&
|
|
2097
|
+
(!("scriptName" in item) ||
|
|
2098
|
+
!item.scriptName ||
|
|
2099
|
+
item.scriptName === workerName)
|
|
2100
|
+
? [
|
|
2101
|
+
{
|
|
2102
|
+
logicalId: binding.sid,
|
|
2103
|
+
bindingName: item.name,
|
|
2104
|
+
className: item.className,
|
|
2105
|
+
},
|
|
2106
|
+
]
|
|
2107
|
+
: [],
|
|
2108
|
+
),
|
|
2109
|
+
);
|
|
2110
|
+
}
|
|
2111
|
+
|
|
2112
|
+
function getDurableObjectTagMap(tags: ReadonlyArray<string>) {
|
|
2113
|
+
return Object.fromEntries(
|
|
2114
|
+
tags.flatMap((tag) => {
|
|
2115
|
+
if (!tag.startsWith("alchemy:do:")) {
|
|
2116
|
+
return [];
|
|
2117
|
+
}
|
|
2118
|
+
const parts = tag.split(":");
|
|
2119
|
+
const logicalId = parts[2];
|
|
2120
|
+
const className = parts.slice(3).join(":");
|
|
2121
|
+
return logicalId && className ? [[logicalId, className]] : [];
|
|
2122
|
+
}),
|
|
2123
|
+
);
|
|
2124
|
+
}
|