alchemy 2.0.0-beta.35 → 2.0.0-beta.37
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 +176 -26
- package/bin/exec.js.map +1 -1
- package/lib/AWS/Lambda/Function.d.ts.map +1 -1
- package/lib/AWS/Lambda/Function.js +22 -2
- package/lib/AWS/Lambda/Function.js.map +1 -1
- package/lib/Apply.d.ts.map +1 -1
- package/lib/Apply.js +6 -1
- package/lib/Apply.js.map +1 -1
- package/lib/Cli/main.d.ts.map +1 -1
- package/lib/Cli/main.js +2 -0
- package/lib/Cli/main.js.map +1 -1
- package/lib/Cloudflare/AnalyticsEngine/AnalyticsEngineDataset.d.ts +54 -0
- package/lib/Cloudflare/AnalyticsEngine/AnalyticsEngineDataset.d.ts.map +1 -0
- package/lib/Cloudflare/AnalyticsEngine/AnalyticsEngineDataset.js +17 -0
- package/lib/Cloudflare/AnalyticsEngine/AnalyticsEngineDataset.js.map +1 -0
- package/lib/Cloudflare/AnalyticsEngine/AnalyticsEngineDatasetBinding.d.ts +37 -0
- package/lib/Cloudflare/AnalyticsEngine/AnalyticsEngineDatasetBinding.d.ts.map +1 -0
- package/lib/Cloudflare/AnalyticsEngine/AnalyticsEngineDatasetBinding.js +45 -0
- package/lib/Cloudflare/AnalyticsEngine/AnalyticsEngineDatasetBinding.js.map +1 -0
- package/lib/Cloudflare/AnalyticsEngine/index.d.ts +3 -0
- package/lib/Cloudflare/AnalyticsEngine/index.d.ts.map +1 -0
- package/lib/Cloudflare/AnalyticsEngine/index.js +3 -0
- package/lib/Cloudflare/AnalyticsEngine/index.js.map +1 -0
- package/lib/Cloudflare/D1/D1Connection.d.ts +47 -3
- package/lib/Cloudflare/D1/D1Connection.d.ts.map +1 -1
- package/lib/Cloudflare/D1/D1Connection.js +62 -5
- package/lib/Cloudflare/D1/D1Connection.js.map +1 -1
- package/lib/Cloudflare/Images/Images.d.ts +103 -0
- package/lib/Cloudflare/Images/Images.d.ts.map +1 -0
- package/lib/Cloudflare/Images/Images.js +82 -0
- package/lib/Cloudflare/Images/Images.js.map +1 -0
- package/lib/Cloudflare/Images/ImagesBinding.d.ts +73 -0
- package/lib/Cloudflare/Images/ImagesBinding.d.ts.map +1 -0
- package/lib/Cloudflare/Images/ImagesBinding.js +83 -0
- package/lib/Cloudflare/Images/ImagesBinding.js.map +1 -0
- package/lib/Cloudflare/Images/index.d.ts +3 -0
- package/lib/Cloudflare/Images/index.d.ts.map +1 -0
- package/lib/Cloudflare/Images/index.js +3 -0
- package/lib/Cloudflare/Images/index.js.map +1 -0
- package/lib/Cloudflare/Local/SidecarHandlers.js +9 -1
- package/lib/Cloudflare/Local/SidecarHandlers.js.map +1 -1
- package/lib/Cloudflare/Providers.d.ts.map +1 -1
- package/lib/Cloudflare/Providers.js +6 -1
- package/lib/Cloudflare/Providers.js.map +1 -1
- package/lib/Cloudflare/R2/R2Bucket.d.ts +135 -0
- package/lib/Cloudflare/R2/R2Bucket.d.ts.map +1 -1
- package/lib/Cloudflare/R2/R2Bucket.js +146 -7
- package/lib/Cloudflare/R2/R2Bucket.js.map +1 -1
- package/lib/Cloudflare/StateStore/Api.d.ts +6 -1
- package/lib/Cloudflare/StateStore/Api.d.ts.map +1 -1
- package/lib/Cloudflare/StateStore/Api.js +23 -1
- package/lib/Cloudflare/StateStore/Api.js.map +1 -1
- package/lib/Cloudflare/StateStore/Store.d.ts +16 -1
- package/lib/Cloudflare/StateStore/Store.d.ts.map +1 -1
- package/lib/Cloudflare/StateStore/Store.js +22 -5
- package/lib/Cloudflare/StateStore/Store.js.map +1 -1
- package/lib/Cloudflare/Workers/CronEventSource.d.ts +35 -0
- package/lib/Cloudflare/Workers/CronEventSource.d.ts.map +1 -0
- package/lib/Cloudflare/Workers/CronEventSource.js +55 -0
- package/lib/Cloudflare/Workers/CronEventSource.js.map +1 -0
- package/lib/Cloudflare/Workers/InferEnv.d.ts +37 -2
- package/lib/Cloudflare/Workers/InferEnv.d.ts.map +1 -1
- package/lib/Cloudflare/Workers/LocalWorkerProvider.d.ts.map +1 -1
- package/lib/Cloudflare/Workers/LocalWorkerProvider.js +2 -1
- package/lib/Cloudflare/Workers/LocalWorkerProvider.js.map +1 -1
- package/lib/Cloudflare/Workers/Rpc.d.ts +76 -3
- package/lib/Cloudflare/Workers/Rpc.d.ts.map +1 -1
- package/lib/Cloudflare/Workers/Rpc.js +197 -13
- package/lib/Cloudflare/Workers/Rpc.js.map +1 -1
- package/lib/Cloudflare/Workers/Worker.d.ts +26 -6
- package/lib/Cloudflare/Workers/Worker.d.ts.map +1 -1
- package/lib/Cloudflare/Workers/Worker.js +183 -41
- package/lib/Cloudflare/Workers/Worker.js.map +1 -1
- package/lib/Cloudflare/Workers/WorkerBundle.d.ts.map +1 -1
- package/lib/Cloudflare/Workers/WorkerBundle.js +15 -5
- package/lib/Cloudflare/Workers/WorkerBundle.js.map +1 -1
- package/lib/Cloudflare/Workers/Workflow.d.ts +50 -47
- package/lib/Cloudflare/Workers/Workflow.d.ts.map +1 -1
- package/lib/Cloudflare/Workers/Workflow.js +41 -35
- package/lib/Cloudflare/Workers/Workflow.js.map +1 -1
- package/lib/Cloudflare/Workers/index.d.ts +1 -0
- package/lib/Cloudflare/Workers/index.d.ts.map +1 -1
- package/lib/Cloudflare/Workers/index.js +1 -0
- package/lib/Cloudflare/Workers/index.js.map +1 -1
- package/lib/Cloudflare/index.d.ts +2 -0
- package/lib/Cloudflare/index.d.ts.map +1 -1
- package/lib/Cloudflare/index.js +2 -0
- package/lib/Cloudflare/index.js.map +1 -1
- package/lib/Deploy.d.ts +4 -1
- package/lib/Deploy.d.ts.map +1 -1
- package/lib/Deploy.js +2 -2
- package/lib/Deploy.js.map +1 -1
- package/lib/Destroy.d.ts +4 -1
- package/lib/Destroy.d.ts.map +1 -1
- package/lib/Destroy.js +2 -2
- package/lib/Destroy.js.map +1 -1
- package/lib/Output.d.ts +45 -5
- package/lib/Output.d.ts.map +1 -1
- package/lib/Output.js +100 -4
- package/lib/Output.js.map +1 -1
- package/lib/Plan.d.ts.map +1 -1
- package/lib/Plan.js +93 -12
- package/lib/Plan.js.map +1 -1
- package/lib/Platform.d.ts.map +1 -1
- package/lib/Platform.js +16 -3
- package/lib/Platform.js.map +1 -1
- package/lib/Ref.d.ts +4 -1
- package/lib/Ref.d.ts.map +1 -1
- package/lib/Ref.js +1 -1
- package/lib/Ref.js.map +1 -1
- package/lib/Resource.d.ts +8 -0
- package/lib/Resource.d.ts.map +1 -1
- package/lib/Resource.js +10 -0
- package/lib/Resource.js.map +1 -1
- package/lib/RuntimeContext.d.ts +3 -1
- package/lib/RuntimeContext.d.ts.map +1 -1
- package/lib/RuntimeContext.js.map +1 -1
- package/lib/Secret.d.ts +50 -0
- package/lib/Secret.d.ts.map +1 -0
- package/lib/Secret.js +23 -0
- package/lib/Secret.js.map +1 -0
- package/lib/Serverless/Function.d.ts +9 -1
- package/lib/Serverless/Function.d.ts.map +1 -1
- package/lib/Stack.d.ts +14 -5
- package/lib/Stack.d.ts.map +1 -1
- package/lib/Stack.js +31 -19
- package/lib/Stack.js.map +1 -1
- package/lib/State/HttpStateApi.d.ts +15 -1
- package/lib/State/HttpStateApi.d.ts.map +1 -1
- package/lib/State/HttpStateApi.js +11 -0
- package/lib/State/HttpStateApi.js.map +1 -1
- package/lib/State/HttpStateStore.d.ts.map +1 -1
- package/lib/State/HttpStateStore.js +11 -0
- package/lib/State/HttpStateStore.js.map +1 -1
- package/lib/State/InMemoryState.d.ts +2 -2
- package/lib/State/InMemoryState.d.ts.map +1 -1
- package/lib/State/InMemoryState.js +12 -6
- package/lib/State/InMemoryState.js.map +1 -1
- package/lib/State/LocalState.d.ts.map +1 -1
- package/lib/State/LocalState.js +11 -2
- package/lib/State/LocalState.js.map +1 -1
- package/lib/State/State.d.ts +21 -0
- package/lib/State/State.d.ts.map +1 -1
- package/lib/Test/Bun.d.ts.map +1 -1
- package/lib/Test/Bun.js +30 -7
- package/lib/Test/Bun.js.map +1 -1
- package/lib/Test/Core.d.ts +17 -2
- package/lib/Test/Core.d.ts.map +1 -1
- package/lib/Test/Core.js +29 -11
- package/lib/Test/Core.js.map +1 -1
- package/lib/Test/Vitest.d.ts.map +1 -1
- package/lib/Test/Vitest.js +26 -5
- package/lib/Test/Vitest.js.map +1 -1
- package/lib/Util/LocalhostDns.d.ts +23 -0
- package/lib/Util/LocalhostDns.d.ts.map +1 -0
- package/lib/Util/LocalhostDns.js +46 -0
- package/lib/Util/LocalhostDns.js.map +1 -0
- package/lib/Util/PlatformServices.d.ts.map +1 -1
- package/lib/Util/PlatformServices.js +2 -0
- package/lib/Util/PlatformServices.js.map +1 -1
- package/lib/Util/effect.d.ts +7 -0
- package/lib/Util/effect.d.ts.map +1 -1
- package/lib/Util/effect.js +6 -0
- package/lib/Util/effect.js.map +1 -1
- package/lib/Variable.d.ts +29 -0
- package/lib/Variable.d.ts.map +1 -0
- package/lib/Variable.js +9 -0
- package/lib/Variable.js.map +1 -0
- package/lib/index.d.ts +3 -0
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +3 -0
- package/lib/index.js.map +1 -1
- package/lib/tsconfig.test.tsbuildinfo +1 -1
- package/package.json +7 -7
- package/src/AWS/Lambda/Function.ts +30 -2
- package/src/Apply.ts +8 -1
- package/src/Cli/main.ts +3 -0
- package/src/Cloudflare/AnalyticsEngine/AnalyticsEngineDataset.ts +82 -0
- package/src/Cloudflare/AnalyticsEngine/AnalyticsEngineDatasetBinding.ts +106 -0
- package/src/Cloudflare/AnalyticsEngine/index.ts +2 -0
- package/src/Cloudflare/D1/D1Connection.ts +95 -12
- package/src/Cloudflare/Images/Images.ts +121 -0
- package/src/Cloudflare/Images/ImagesBinding.ts +192 -0
- package/src/Cloudflare/Images/index.ts +2 -0
- package/src/Cloudflare/Local/SidecarHandlers.ts +9 -1
- package/src/Cloudflare/Providers.ts +8 -0
- package/src/Cloudflare/R2/R2Bucket.ts +271 -7
- package/src/Cloudflare/StateStore/Api.ts +34 -1
- package/src/Cloudflare/StateStore/Store.ts +40 -10
- package/src/Cloudflare/Workers/CronEventSource.ts +89 -0
- package/src/Cloudflare/Workers/InferEnv.ts +94 -16
- package/src/Cloudflare/Workers/LocalWorkerProvider.ts +9 -1
- package/src/Cloudflare/Workers/Rpc.ts +227 -18
- package/src/Cloudflare/Workers/Worker.ts +295 -62
- package/src/Cloudflare/Workers/WorkerBundle.ts +15 -5
- package/src/Cloudflare/Workers/Workflow.ts +74 -70
- package/src/Cloudflare/Workers/index.ts +1 -0
- package/src/Cloudflare/index.ts +2 -0
- package/src/Deploy.ts +5 -1
- package/src/Destroy.ts +5 -1
- package/src/Output.ts +121 -12
- package/src/Plan.ts +101 -12
- package/src/Platform.ts +19 -4
- package/src/Ref.ts +10 -5
- package/src/Resource.ts +22 -0
- package/src/RuntimeContext.ts +1 -0
- package/src/Secret.ts +87 -0
- package/src/Serverless/Function.ts +10 -1
- package/src/Stack.ts +52 -29
- package/src/State/HttpStateApi.ts +21 -0
- package/src/State/HttpStateStore.ts +21 -0
- package/src/State/InMemoryState.ts +29 -8
- package/src/State/LocalState.ts +28 -4
- package/src/State/State.ts +21 -0
- package/src/Test/Bun.ts +43 -7
- package/src/Test/Core.ts +29 -8
- package/src/Test/Vitest.ts +36 -4
- package/src/Util/LocalhostDns.ts +52 -0
- package/src/Util/PlatformServices.ts +2 -0
- package/src/Util/effect.ts +25 -0
- package/src/Variable.ts +44 -0
- package/src/index.ts +3 -0
|
@@ -2,17 +2,18 @@ import type * as cf from "@cloudflare/workers-types";
|
|
|
2
2
|
import cloudflareVite from "@distilled.cloud/cloudflare-vite-plugin";
|
|
3
3
|
import * as workers from "@distilled.cloud/cloudflare/workers";
|
|
4
4
|
import * as zones from "@distilled.cloud/cloudflare/zones";
|
|
5
|
+
import * as Cause from "effect/Cause";
|
|
5
6
|
import * as Context from "effect/Context";
|
|
6
7
|
import * as Data from "effect/Data";
|
|
7
8
|
import * as Effect from "effect/Effect";
|
|
8
9
|
import * as Exit from "effect/Exit";
|
|
9
|
-
import * as FileSystem from "effect/FileSystem";
|
|
10
10
|
import * as Layer from "effect/Layer";
|
|
11
11
|
import * as Option from "effect/Option";
|
|
12
12
|
import * as Path from "effect/Path";
|
|
13
13
|
import * as Redacted from "effect/Redacted";
|
|
14
14
|
import * as Schedule from "effect/Schedule";
|
|
15
15
|
import * as Scope from "effect/Scope";
|
|
16
|
+
import * as Stream from "effect/Stream";
|
|
16
17
|
import { createRequire } from "node:module";
|
|
17
18
|
import path from "node:path";
|
|
18
19
|
import { pathToFileURL } from "node:url";
|
|
@@ -34,11 +35,16 @@ import {
|
|
|
34
35
|
type PlatformProps,
|
|
35
36
|
type Rpc,
|
|
36
37
|
} from "../../Platform.ts";
|
|
38
|
+
import { isYieldableEffectLike } from "../../Util/effect.ts";
|
|
37
39
|
import * as Provider from "../../Provider.ts";
|
|
38
40
|
import { Resource, type ResourceBinding } from "../../Resource.ts";
|
|
39
41
|
import * as Serverless from "../../Serverless/index.ts";
|
|
40
42
|
import { Stack } from "../../Stack.ts";
|
|
41
43
|
import type { AiGateway } from "../AiGateway/AiGateway.ts";
|
|
44
|
+
import {
|
|
45
|
+
isAnalyticsEngineDataset,
|
|
46
|
+
type AnalyticsEngineDataset,
|
|
47
|
+
} from "../AnalyticsEngine/AnalyticsEngineDataset.ts";
|
|
42
48
|
import {
|
|
43
49
|
isArtifacts as isArtifactsBinding,
|
|
44
50
|
type Artifacts as ArtifactsBinding,
|
|
@@ -46,7 +52,14 @@ import {
|
|
|
46
52
|
import { CloudflareEnvironment } from "../CloudflareEnvironment.ts";
|
|
47
53
|
import { D1Database } from "../D1/D1Database.ts";
|
|
48
54
|
import { fromCloudflareFetcher } from "../Fetcher.ts";
|
|
49
|
-
import type {
|
|
55
|
+
import type {
|
|
56
|
+
Hyperdrive,
|
|
57
|
+
HyperdriveDevOrigin,
|
|
58
|
+
} from "../Hyperdrive/Hyperdrive.ts";
|
|
59
|
+
import {
|
|
60
|
+
isImages as isImagesBinding,
|
|
61
|
+
type Images as ImagesBinding,
|
|
62
|
+
} from "../Images/Images.ts";
|
|
50
63
|
import type { KVNamespace } from "../KV/KVNamespace.ts";
|
|
51
64
|
import { SidecarLive } from "../Local/Sidecar.ts";
|
|
52
65
|
import { CloudflareLogs } from "../Logs.ts";
|
|
@@ -70,7 +83,14 @@ import {
|
|
|
70
83
|
import { workersHttpHandler } from "./HttpServer.ts";
|
|
71
84
|
import { LocalWorkerProvider } from "./LocalWorkerProvider.ts";
|
|
72
85
|
import { Request } from "./Request.ts";
|
|
73
|
-
import {
|
|
86
|
+
import {
|
|
87
|
+
encodeRpcError,
|
|
88
|
+
ErrorTag,
|
|
89
|
+
makeRpcStub,
|
|
90
|
+
toRpcStream,
|
|
91
|
+
type RpcErrorEnvelope,
|
|
92
|
+
type RpcStreamEnvelope,
|
|
93
|
+
} from "./Rpc.ts";
|
|
74
94
|
import { WorkerBundle } from "./WorkerBundle.ts";
|
|
75
95
|
import { createWorkerName } from "./WorkerName.ts";
|
|
76
96
|
|
|
@@ -181,7 +201,11 @@ export type WorkerBindingResource =
|
|
|
181
201
|
| KVNamespace
|
|
182
202
|
| CloudflareQueue
|
|
183
203
|
| AiGateway
|
|
204
|
+
| AnalyticsEngineDataset
|
|
184
205
|
| ArtifactsBinding
|
|
206
|
+
| ImagesBinding
|
|
207
|
+
| Hyperdrive
|
|
208
|
+
| Worker
|
|
185
209
|
| DurableObjectNamespaceLike<any>;
|
|
186
210
|
|
|
187
211
|
export type WorkerBindings = {
|
|
@@ -272,6 +296,12 @@ export interface WorkerProps<
|
|
|
272
296
|
>;
|
|
273
297
|
exports?: string[];
|
|
274
298
|
bindings?: Bindings;
|
|
299
|
+
/**
|
|
300
|
+
* Cron expressions that trigger the Worker's scheduled handler.
|
|
301
|
+
*
|
|
302
|
+
* Pass an empty array to remove all Cron Triggers.
|
|
303
|
+
*/
|
|
304
|
+
crons?: string[];
|
|
275
305
|
/**
|
|
276
306
|
* One or more custom hostnames (e.g. `"app.example.com"`) to bind to this
|
|
277
307
|
* Worker. The Cloudflare Zone is inferred from the hostname — the zone must
|
|
@@ -310,6 +340,7 @@ export type Worker<Bindings extends WorkerBindings = any> = Resource<
|
|
|
310
340
|
durableObjectNamespaces: Record<string, string>;
|
|
311
341
|
accountId: string;
|
|
312
342
|
domains: { hostname: string; id: string; zoneId: string }[];
|
|
343
|
+
crons: string[];
|
|
313
344
|
hash?: {
|
|
314
345
|
assets: string | undefined;
|
|
315
346
|
bundle: string | undefined;
|
|
@@ -319,6 +350,7 @@ export type Worker<Bindings extends WorkerBindings = any> = Resource<
|
|
|
319
350
|
{
|
|
320
351
|
bindings?: WorkerBinding[];
|
|
321
352
|
containers?: { className: string }[];
|
|
353
|
+
crons?: string[];
|
|
322
354
|
hyperdrives?: Record<string, Required<HyperdriveDevOrigin>>;
|
|
323
355
|
},
|
|
324
356
|
Providers
|
|
@@ -717,8 +749,11 @@ export const Worker: Platform<
|
|
|
717
749
|
const bindingEff = props.bindings?.[bindingName] as
|
|
718
750
|
| WorkerBindingResource
|
|
719
751
|
| Effect.Effect<WorkerBindingResource>;
|
|
720
|
-
|
|
721
|
-
|
|
752
|
+
// Bindings can be passed as a plain resource value, an Effect that
|
|
753
|
+
// yields a resource, or an effect-class (e.g. a `Cloudflare.Worker`
|
|
754
|
+
// class). Resolve the yieldable forms before deriving binding metadata.
|
|
755
|
+
const binding = isYieldableEffectLike(bindingEff)
|
|
756
|
+
? ((yield* bindingEff as Effect.Effect<unknown>) as WorkerBindingResource)
|
|
722
757
|
: bindingEff;
|
|
723
758
|
|
|
724
759
|
const bindingMeta: InputProps<WorkerBinding> | undefined = isAssets(
|
|
@@ -734,48 +769,73 @@ export const Worker: Platform<
|
|
|
734
769
|
name: bindingName,
|
|
735
770
|
namespace: binding.namespace,
|
|
736
771
|
} as any)
|
|
737
|
-
:
|
|
772
|
+
: isImagesBinding(binding)
|
|
738
773
|
? {
|
|
739
|
-
type: "
|
|
774
|
+
type: "images",
|
|
740
775
|
name: bindingName,
|
|
741
|
-
className: binding.className ?? binding.name,
|
|
742
776
|
}
|
|
743
|
-
: binding
|
|
777
|
+
: isAnalyticsEngineDataset(binding)
|
|
744
778
|
? {
|
|
745
|
-
type: "
|
|
746
|
-
id: binding.databaseId,
|
|
779
|
+
type: "analytics_engine",
|
|
747
780
|
name: bindingName,
|
|
781
|
+
dataset: binding.dataset,
|
|
748
782
|
}
|
|
749
|
-
: binding
|
|
783
|
+
: isDurableObjectNamespaceLike(binding)
|
|
750
784
|
? {
|
|
751
|
-
type: "
|
|
785
|
+
type: "durable_object_namespace",
|
|
752
786
|
name: bindingName,
|
|
753
|
-
|
|
754
|
-
jurisdiction: binding.jurisdiction.pipe(
|
|
755
|
-
Output.map((jurisdiction) =>
|
|
756
|
-
jurisdiction === "default" ? undefined : jurisdiction,
|
|
757
|
-
),
|
|
758
|
-
),
|
|
787
|
+
className: binding.className ?? binding.name,
|
|
759
788
|
}
|
|
760
|
-
: binding.Type === "Cloudflare.
|
|
789
|
+
: binding.Type === "Cloudflare.D1Database"
|
|
761
790
|
? {
|
|
762
|
-
type: "
|
|
791
|
+
type: "d1",
|
|
792
|
+
id: binding.databaseId,
|
|
763
793
|
name: bindingName,
|
|
764
|
-
namespaceId: binding.namespaceId,
|
|
765
794
|
}
|
|
766
|
-
: binding.Type === "Cloudflare.
|
|
795
|
+
: binding.Type === "Cloudflare.R2Bucket"
|
|
767
796
|
? {
|
|
768
|
-
type: "
|
|
797
|
+
type: "r2_bucket",
|
|
769
798
|
name: bindingName,
|
|
770
|
-
|
|
799
|
+
bucketName: binding.bucketName,
|
|
800
|
+
jurisdiction: binding.jurisdiction.pipe(
|
|
801
|
+
Output.map((jurisdiction) =>
|
|
802
|
+
jurisdiction === "default"
|
|
803
|
+
? undefined
|
|
804
|
+
: jurisdiction,
|
|
805
|
+
),
|
|
806
|
+
),
|
|
771
807
|
}
|
|
772
|
-
: binding.Type === "Cloudflare.
|
|
808
|
+
: binding.Type === "Cloudflare.KVNamespace"
|
|
773
809
|
? {
|
|
774
|
-
type: "
|
|
810
|
+
type: "kv_namespace",
|
|
775
811
|
name: bindingName,
|
|
812
|
+
namespaceId: binding.namespaceId,
|
|
776
813
|
}
|
|
777
|
-
:
|
|
778
|
-
|
|
814
|
+
: binding.Type === "Cloudflare.Queue"
|
|
815
|
+
? {
|
|
816
|
+
type: "queue",
|
|
817
|
+
name: bindingName,
|
|
818
|
+
queueName: binding.queueName,
|
|
819
|
+
}
|
|
820
|
+
: binding.Type === "Cloudflare.AiGateway"
|
|
821
|
+
? {
|
|
822
|
+
type: "ai",
|
|
823
|
+
name: bindingName,
|
|
824
|
+
}
|
|
825
|
+
: binding.Type === "Cloudflare.Hyperdrive"
|
|
826
|
+
? {
|
|
827
|
+
type: "hyperdrive",
|
|
828
|
+
name: bindingName,
|
|
829
|
+
id: binding.hyperdriveId,
|
|
830
|
+
}
|
|
831
|
+
: isWorker(binding)
|
|
832
|
+
? {
|
|
833
|
+
type: "service",
|
|
834
|
+
name: bindingName,
|
|
835
|
+
service: binding.workerName,
|
|
836
|
+
}
|
|
837
|
+
: // TODO(sam): handle others
|
|
838
|
+
undefined;
|
|
779
839
|
|
|
780
840
|
if (bindingMeta) {
|
|
781
841
|
yield* resource.bind`${bindingName}`({
|
|
@@ -791,6 +851,7 @@ export const Worker: Platform<
|
|
|
791
851
|
const listeners: Effect.Effect<Serverless.FunctionListener>[] = [];
|
|
792
852
|
const exports: Record<string, any> = {};
|
|
793
853
|
const env: Record<string, any> = {};
|
|
854
|
+
let userShape: Record<string, unknown> | undefined;
|
|
794
855
|
|
|
795
856
|
const ctx = {
|
|
796
857
|
Type: WorkerTypeId,
|
|
@@ -857,7 +918,14 @@ export const Worker: Platform<
|
|
|
857
918
|
}),
|
|
858
919
|
serve: <Req = never>(
|
|
859
920
|
handler: HttpEffect<Req> | Effect.Effect<HttpEffect<Req>>,
|
|
860
|
-
|
|
921
|
+
options?: { shape?: Record<string, unknown> },
|
|
922
|
+
) => {
|
|
923
|
+
// Capture the user's full default-export shape so `exports` can
|
|
924
|
+
// expose any non-handler methods on it as RPC methods on the
|
|
925
|
+
// deployed `WorkerEntrypoint` subclass — see `__rpc__` below.
|
|
926
|
+
if (options?.shape) userShape = options.shape;
|
|
927
|
+
return ctx.listen(workersHttpHandler(handler));
|
|
928
|
+
},
|
|
861
929
|
listen: ((
|
|
862
930
|
handler:
|
|
863
931
|
| Serverless.FunctionListener
|
|
@@ -877,6 +945,35 @@ export const Worker: Platform<
|
|
|
877
945
|
concurrency: "unbounded",
|
|
878
946
|
});
|
|
879
947
|
const services = yield* Effect.context();
|
|
948
|
+
|
|
949
|
+
// Provide the per-request runtime layer (services + `WorkerExecutionContext`
|
|
950
|
+
// + a fresh `ExecutionContext`/`Scope`) to a user effect, then run it.
|
|
951
|
+
// This is the bridge between Cloudflare's request-time callback and
|
|
952
|
+
// the user's Effect-native handler. Used by both the standard
|
|
953
|
+
// `handle()` dispatch (fetch/scheduled/…) and the per-RPC dispatchers
|
|
954
|
+
// below — keeping them on a single layer-provision path.
|
|
955
|
+
const runUserEffect = <A, E>(
|
|
956
|
+
eff: Effect.Effect<A, E>,
|
|
957
|
+
context: cf.ExecutionContext,
|
|
958
|
+
): Promise<Exit.Exit<A, E>> => {
|
|
959
|
+
const scope = Scope.makeUnsafe();
|
|
960
|
+
return eff
|
|
961
|
+
.pipe(
|
|
962
|
+
Effect.provideContext(services),
|
|
963
|
+
Scope.provide(scope),
|
|
964
|
+
Effect.provide(Layer.succeed(WorkerExecutionContext, context)),
|
|
965
|
+
Effect.provide(
|
|
966
|
+
Layer.succeed(ExecutionContext, { scope, cache: {} }),
|
|
967
|
+
),
|
|
968
|
+
Effect.runPromiseExit,
|
|
969
|
+
)
|
|
970
|
+
.finally(() =>
|
|
971
|
+
context.waitUntil(
|
|
972
|
+
Effect.runPromise(Scope.close(scope, Exit.void)),
|
|
973
|
+
),
|
|
974
|
+
);
|
|
975
|
+
};
|
|
976
|
+
|
|
880
977
|
const handle =
|
|
881
978
|
(type: WorkerEvent["type"]) =>
|
|
882
979
|
(request: any, env: unknown, context: cf.ExecutionContext) => {
|
|
@@ -890,36 +987,76 @@ export const Worker: Platform<
|
|
|
890
987
|
for (const handler of handlers) {
|
|
891
988
|
const eff = handler(event);
|
|
892
989
|
if (Effect.isEffect(eff)) {
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
),
|
|
901
|
-
Effect.provide(
|
|
902
|
-
Layer.succeed(ExecutionContext, {
|
|
903
|
-
scope,
|
|
904
|
-
cache: {},
|
|
905
|
-
}),
|
|
906
|
-
),
|
|
907
|
-
Effect.runPromise,
|
|
908
|
-
)
|
|
909
|
-
.finally(() =>
|
|
910
|
-
context.waitUntil(
|
|
911
|
-
Effect.runPromise(Scope.close(scope, Exit.void)),
|
|
912
|
-
),
|
|
913
|
-
);
|
|
990
|
+
return runUserEffect(
|
|
991
|
+
eff as Effect.Effect<unknown, unknown>,
|
|
992
|
+
context,
|
|
993
|
+
).then((exit) => {
|
|
994
|
+
if (exit._tag === "Success") return exit.value;
|
|
995
|
+
throw Cause.squash(exit.cause);
|
|
996
|
+
});
|
|
914
997
|
}
|
|
915
998
|
}
|
|
916
999
|
return Promise.reject(new Error("No event handler found"));
|
|
917
1000
|
};
|
|
1001
|
+
|
|
1002
|
+
// RPC method dispatchers — one per non-handler method on the user's
|
|
1003
|
+
// shape. Each dispatcher is invoked by the WorkerEntrypoint bridge
|
|
1004
|
+
// as `dispatcher(args, ctx)`: `args` are the user-facing call args,
|
|
1005
|
+
// `ctx` is the `this.ctx` that Cloudflare hands the bridge per RPC
|
|
1006
|
+
// request. The dispatcher runs the user effect with the same runtime
|
|
1007
|
+
// layer the fetch path uses, then envelope-encodes the result so
|
|
1008
|
+
// `Effect.fail` round-trips as `RpcErrorEnvelope` and `Stream` as
|
|
1009
|
+
// `RpcStreamEnvelope` (consumers wrap the binding with
|
|
1010
|
+
// `toPromiseApi`/`bindWorker` to decode).
|
|
1011
|
+
const exportedHandlerSet = new Set<string>(ExportedHandlerMethods);
|
|
1012
|
+
const rpcDispatchers: Record<
|
|
1013
|
+
string,
|
|
1014
|
+
(args: unknown[], ctx: cf.ExecutionContext) => Promise<unknown>
|
|
1015
|
+
> = {};
|
|
1016
|
+
if (userShape) {
|
|
1017
|
+
for (const [name, value] of Object.entries(userShape)) {
|
|
1018
|
+
if (exportedHandlerSet.has(name)) continue;
|
|
1019
|
+
if (typeof value !== "function") continue;
|
|
1020
|
+
rpcDispatchers[name] = async (
|
|
1021
|
+
args: unknown[],
|
|
1022
|
+
context: cf.ExecutionContext,
|
|
1023
|
+
) => {
|
|
1024
|
+
const result = (value as (...a: unknown[]) => unknown)(...args);
|
|
1025
|
+
if (!Effect.isEffect(result)) return result;
|
|
1026
|
+
const exit = await runUserEffect(
|
|
1027
|
+
result as Effect.Effect<unknown, unknown>,
|
|
1028
|
+
context,
|
|
1029
|
+
);
|
|
1030
|
+
if (exit._tag === "Success") {
|
|
1031
|
+
if (Stream.isStream(exit.value)) {
|
|
1032
|
+
return await Effect.runPromise(
|
|
1033
|
+
toRpcStream(exit.value) as Effect.Effect<RpcStreamEnvelope>,
|
|
1034
|
+
);
|
|
1035
|
+
}
|
|
1036
|
+
return exit.value;
|
|
1037
|
+
}
|
|
1038
|
+
const failReason = exit.cause.reasons.find(Cause.isFailReason);
|
|
1039
|
+
if (failReason) {
|
|
1040
|
+
return {
|
|
1041
|
+
_tag: ErrorTag,
|
|
1042
|
+
error: encodeRpcError(failReason.error),
|
|
1043
|
+
} satisfies RpcErrorEnvelope;
|
|
1044
|
+
}
|
|
1045
|
+
const dieReason = exit.cause.reasons.find(Cause.isDieReason);
|
|
1046
|
+
throw (
|
|
1047
|
+
dieReason?.defect ??
|
|
1048
|
+
new Error("RPC method failed with an unexpected cause")
|
|
1049
|
+
);
|
|
1050
|
+
};
|
|
1051
|
+
}
|
|
1052
|
+
}
|
|
1053
|
+
|
|
918
1054
|
return {
|
|
919
1055
|
...exports,
|
|
920
1056
|
default: Object.fromEntries(
|
|
921
1057
|
ExportedHandlerMethods.map((method) => [method, handle(method)]),
|
|
922
1058
|
),
|
|
1059
|
+
__rpc__: rpcDispatchers,
|
|
923
1060
|
};
|
|
924
1061
|
}),
|
|
925
1062
|
};
|
|
@@ -932,7 +1069,10 @@ export const bindWorker = Effect.fnUntraced(function* <Shape, Req = never>(
|
|
|
932
1069
|
| (Worker & Rpc<Shape>)
|
|
933
1070
|
| Effect.Effect<Worker & Rpc<Shape>, never, Req>,
|
|
934
1071
|
) {
|
|
935
|
-
|
|
1072
|
+
// Worker classes and regular Effects are both yieldable here.
|
|
1073
|
+
const worker = isYieldableEffectLike(workerEff)
|
|
1074
|
+
? yield* workerEff as Effect.Effect<Worker & Rpc<Shape>, never, Req>
|
|
1075
|
+
: workerEff;
|
|
936
1076
|
const self = yield* Worker;
|
|
937
1077
|
yield* self.bind`${worker}`({
|
|
938
1078
|
bindings: [
|
|
@@ -944,13 +1084,14 @@ export const bindWorker = Effect.fnUntraced(function* <Shape, Req = never>(
|
|
|
944
1084
|
],
|
|
945
1085
|
});
|
|
946
1086
|
|
|
947
|
-
|
|
948
|
-
|
|
1087
|
+
// `bindWorker` runs at *init* phase (both at plantime and at runtime
|
|
1088
|
+
// cold-start). `WorkerEnvironment` only exists at exec phase on the
|
|
1089
|
+
// deployed worker, so we hand `makeRpcStub` an `Effect<stub>` that
|
|
1090
|
+
// resolves the binding lazily on each method call.
|
|
1091
|
+
const stubEff = WorkerEnvironment.asEffect().pipe(
|
|
1092
|
+
Effect.map((env) => (env as Record<string, unknown>)[worker.LogicalId]),
|
|
949
1093
|
);
|
|
950
|
-
|
|
951
|
-
const fetcher = workerBinding.pipe(Effect.map(fromCloudflareFetcher));
|
|
952
|
-
// TODO(sam): update makeRpcStub to support lazily evaluating the Effect<Fetcher>
|
|
953
|
-
return makeRpcStub<Shape>(fetcher);
|
|
1094
|
+
return makeRpcStub<Shape>(stubEff);
|
|
954
1095
|
});
|
|
955
1096
|
|
|
956
1097
|
export class BindWorkerPolicy extends Binding.Policy<
|
|
@@ -1018,6 +1159,12 @@ function getDurableObjectBindings(
|
|
|
1018
1159
|
);
|
|
1019
1160
|
}
|
|
1020
1161
|
|
|
1162
|
+
export function getCronBindings(
|
|
1163
|
+
bindings: ReadonlyArray<ResourceBinding<Worker["Binding"]>>,
|
|
1164
|
+
) {
|
|
1165
|
+
return Array.from(new Set(bindings.flatMap((b) => b.data.crons ?? [])));
|
|
1166
|
+
}
|
|
1167
|
+
|
|
1021
1168
|
function getDurableObjectTagMap(tags: ReadonlyArray<string>) {
|
|
1022
1169
|
return Object.fromEntries(
|
|
1023
1170
|
tags.flatMap((tag) => {
|
|
@@ -1059,20 +1206,20 @@ export const LiveWorkerProvider = () =>
|
|
|
1059
1206
|
Provider.effect(
|
|
1060
1207
|
Worker,
|
|
1061
1208
|
Effect.gen(function* () {
|
|
1062
|
-
const fs = yield* FileSystem.FileSystem;
|
|
1063
1209
|
const path = yield* Path.Path;
|
|
1064
1210
|
|
|
1065
1211
|
const { accountId } = yield* CloudflareEnvironment;
|
|
1066
|
-
const virtualEntryPlugin = yield* Bundle.virtualEntryPlugin;
|
|
1067
1212
|
const bundler = yield* WorkerBundle;
|
|
1068
1213
|
const stack = yield* Stack;
|
|
1069
1214
|
|
|
1070
1215
|
const createScriptSubdomain = yield* workers.createScriptSubdomain;
|
|
1071
1216
|
const deleteScript = yield* workers.deleteScript;
|
|
1072
1217
|
const getScriptSubdomain = yield* workers.getScriptSubdomain;
|
|
1218
|
+
const getScriptSchedule = yield* workers.getScriptSchedule;
|
|
1073
1219
|
const getScriptSettings = yield* workers.getScriptScriptAndVersionSetting;
|
|
1074
1220
|
const getSubdomain = yield* workers.getSubdomain;
|
|
1075
1221
|
const putScript = yield* workers.putScript;
|
|
1222
|
+
const putScriptSchedule = yield* workers.putScriptSchedule;
|
|
1076
1223
|
const putDomain = yield* workers.putDomain;
|
|
1077
1224
|
const listDomains = yield* workers.listDomains;
|
|
1078
1225
|
const deleteDomain = yield* workers.deleteDomain;
|
|
@@ -1120,6 +1267,60 @@ export const LiveWorkerProvider = () =>
|
|
|
1120
1267
|
),
|
|
1121
1268
|
);
|
|
1122
1269
|
|
|
1270
|
+
const normalizeCrons = (crons: string[] | undefined): string[] =>
|
|
1271
|
+
Array.from(new Set(crons ?? []));
|
|
1272
|
+
|
|
1273
|
+
const getWorkerCrons = (scriptName: string) =>
|
|
1274
|
+
getScriptSchedule({
|
|
1275
|
+
accountId,
|
|
1276
|
+
scriptName,
|
|
1277
|
+
}).pipe(
|
|
1278
|
+
Effect.map((response) =>
|
|
1279
|
+
normalizeCrons(response.schedules.map((schedule) => schedule.cron)),
|
|
1280
|
+
),
|
|
1281
|
+
Effect.catchTag("WorkerNotFound", () => Effect.succeed([])),
|
|
1282
|
+
);
|
|
1283
|
+
|
|
1284
|
+
const reconcileCrons = (
|
|
1285
|
+
scriptName: string,
|
|
1286
|
+
desired: string[],
|
|
1287
|
+
previous: string[],
|
|
1288
|
+
session: ScopedPlanStatusSession,
|
|
1289
|
+
) =>
|
|
1290
|
+
Effect.gen(function* () {
|
|
1291
|
+
const live = yield* getWorkerCrons(scriptName);
|
|
1292
|
+
const desiredSorted = [...desired].sort();
|
|
1293
|
+
const liveSorted = [...live].sort();
|
|
1294
|
+
const changed =
|
|
1295
|
+
desiredSorted.length !== liveSorted.length ||
|
|
1296
|
+
desiredSorted.some((cron, index) => cron !== liveSorted[index]);
|
|
1297
|
+
|
|
1298
|
+
if (!changed) return live;
|
|
1299
|
+
|
|
1300
|
+
if (desired.length > 0 || previous.length > 0 || live.length > 0) {
|
|
1301
|
+
yield* session.note(
|
|
1302
|
+
`Reconciling Cron Triggers (${desired.length}) ...`,
|
|
1303
|
+
);
|
|
1304
|
+
}
|
|
1305
|
+
|
|
1306
|
+
const result = yield* putScriptSchedule({
|
|
1307
|
+
accountId,
|
|
1308
|
+
scriptName,
|
|
1309
|
+
body: desired.map((cron) => ({ cron })),
|
|
1310
|
+
}).pipe(
|
|
1311
|
+
Effect.retry({
|
|
1312
|
+
while: (error: { _tag?: string }) =>
|
|
1313
|
+
error?._tag === "WorkerNotFound",
|
|
1314
|
+
schedule: Schedule.exponential(200).pipe(
|
|
1315
|
+
Schedule.both(Schedule.recurs(15)),
|
|
1316
|
+
),
|
|
1317
|
+
}),
|
|
1318
|
+
);
|
|
1319
|
+
return normalizeCrons(
|
|
1320
|
+
result.schedules.map((schedule) => schedule.cron),
|
|
1321
|
+
);
|
|
1322
|
+
});
|
|
1323
|
+
|
|
1123
1324
|
/**
|
|
1124
1325
|
* Infer the Cloudflare Zone ID for a given hostname by listing the
|
|
1125
1326
|
* account's zones and matching the hostname against each zone's name —
|
|
@@ -1939,6 +2140,12 @@ export const LiveWorkerProvider = () =>
|
|
|
1939
2140
|
desiredDomains,
|
|
1940
2141
|
previousDomains,
|
|
1941
2142
|
);
|
|
2143
|
+
const crons = yield* reconcileCrons(
|
|
2144
|
+
name,
|
|
2145
|
+
normalizeCrons([...getCronBindings(bindings), ...(news.crons ?? [])]),
|
|
2146
|
+
output?.crons ?? [],
|
|
2147
|
+
session,
|
|
2148
|
+
);
|
|
1942
2149
|
return {
|
|
1943
2150
|
workerId: worker.id ?? name,
|
|
1944
2151
|
workerName: name,
|
|
@@ -1951,6 +2158,7 @@ export const LiveWorkerProvider = () =>
|
|
|
1951
2158
|
durableObjectNamespaces,
|
|
1952
2159
|
accountId,
|
|
1953
2160
|
domains,
|
|
2161
|
+
crons,
|
|
1954
2162
|
hash,
|
|
1955
2163
|
} satisfies Worker["Attributes"];
|
|
1956
2164
|
});
|
|
@@ -2006,7 +2214,13 @@ export const LiveWorkerProvider = () =>
|
|
|
2006
2214
|
|
|
2007
2215
|
return Worker.Provider.of({
|
|
2008
2216
|
stables: ["workerId", "workerName"],
|
|
2009
|
-
diff: Effect.fnUntraced(function* ({
|
|
2217
|
+
diff: Effect.fnUntraced(function* ({
|
|
2218
|
+
id,
|
|
2219
|
+
news,
|
|
2220
|
+
olds,
|
|
2221
|
+
output,
|
|
2222
|
+
newBindings,
|
|
2223
|
+
}) {
|
|
2010
2224
|
if (!isResolved(news)) return undefined;
|
|
2011
2225
|
if ((output?.accountId ?? accountId) !== accountId) {
|
|
2012
2226
|
return { action: "replace" };
|
|
@@ -2028,7 +2242,23 @@ export const LiveWorkerProvider = () =>
|
|
|
2028
2242
|
const domainsChanged =
|
|
2029
2243
|
newDomains.length !== oldDomains.length ||
|
|
2030
2244
|
newDomains.some((d, i) => d !== oldDomains[i]);
|
|
2031
|
-
|
|
2245
|
+
const newCrons = normalizeCrons([
|
|
2246
|
+
...(Array.isArray(newBindings)
|
|
2247
|
+
? getCronBindings(
|
|
2248
|
+
newBindings as ResourceBinding<Worker["Binding"]>[],
|
|
2249
|
+
)
|
|
2250
|
+
: []),
|
|
2251
|
+
...(news.crons ?? []),
|
|
2252
|
+
]).sort();
|
|
2253
|
+
const oldCrons = [...(output?.crons ?? [])].sort();
|
|
2254
|
+
const cronsChanged =
|
|
2255
|
+
newCrons.length !== oldCrons.length ||
|
|
2256
|
+
newCrons.some((cron, index) => cron !== oldCrons[index]);
|
|
2257
|
+
if (
|
|
2258
|
+
domainsChanged ||
|
|
2259
|
+
cronsChanged ||
|
|
2260
|
+
(yield* hasChanged(id, news, output))
|
|
2261
|
+
) {
|
|
2032
2262
|
return {
|
|
2033
2263
|
action: "update",
|
|
2034
2264
|
stables:
|
|
@@ -2154,6 +2384,7 @@ export const LiveWorkerProvider = () =>
|
|
|
2154
2384
|
durableObjectNamespaces,
|
|
2155
2385
|
accountId,
|
|
2156
2386
|
domains: [],
|
|
2387
|
+
crons: [],
|
|
2157
2388
|
} satisfies Worker["Attributes"];
|
|
2158
2389
|
}),
|
|
2159
2390
|
read: Effect.fnUntraced(
|
|
@@ -2185,6 +2416,7 @@ export const LiveWorkerProvider = () =>
|
|
|
2185
2416
|
service: workerName,
|
|
2186
2417
|
}).pipe(Effect.map((r) => r.result ?? [])),
|
|
2187
2418
|
]);
|
|
2419
|
+
const crons = yield* getWorkerCrons(workerName);
|
|
2188
2420
|
yield* Effect.logInfo(
|
|
2189
2421
|
`Cloudflare Worker read: found ${workerName}`,
|
|
2190
2422
|
);
|
|
@@ -2205,6 +2437,7 @@ export const LiveWorkerProvider = () =>
|
|
|
2205
2437
|
? [{ id: d.id, hostname: d.hostname, zoneId: d.zoneId }]
|
|
2206
2438
|
: [],
|
|
2207
2439
|
),
|
|
2440
|
+
crons,
|
|
2208
2441
|
} satisfies Worker["Attributes"];
|
|
2209
2442
|
|
|
2210
2443
|
// Centralized ownership decision: the engine routes `read`'s
|
|
@@ -158,11 +158,11 @@ import * as Logger from "effect/Logger";
|
|
|
158
158
|
import * as Context from "effect/Context";
|
|
159
159
|
import * as Stream from "effect/Stream";
|
|
160
160
|
|
|
161
|
-
import { env, DurableObject${hasWfClasses ? ", WorkflowEntrypoint" : ""} } from "cloudflare:workers";
|
|
161
|
+
import { env, DurableObject, WorkerEntrypoint${hasWfClasses ? ", WorkflowEntrypoint" : ""} } from "cloudflare:workers";
|
|
162
162
|
import { MinimumLogLevel } from "effect/References";
|
|
163
163
|
import { NodeServices } from "@effect/platform-node";
|
|
164
164
|
import { Stack } from "alchemy/Stack";
|
|
165
|
-
import { WorkerEnvironment, makeDurableObjectBridge${hasWfClasses ? ", makeWorkflowBridge" : ""}, ExportedHandlerMethods } from "alchemy/Cloudflare";
|
|
165
|
+
import { WorkerEnvironment, makeDurableObjectBridge, makeWorkerBridge${hasWfClasses ? ", makeWorkflowBridge" : ""}, ExportedHandlerMethods } from "alchemy/Cloudflare";
|
|
166
166
|
|
|
167
167
|
import entry from "${importPath}";
|
|
168
168
|
|
|
@@ -223,10 +223,20 @@ let exportsPromise;
|
|
|
223
223
|
// we cache it synchronously (??=) to guarnatee only one initialization ever happens
|
|
224
224
|
const getExports = () => (exportsPromise ??= Effect.runPromise(exportsEffect))
|
|
225
225
|
const getExport = (name) => getExports().then(exports => exports[name]?.make)
|
|
226
|
-
const
|
|
226
|
+
const getDefault = () => getExports().then(exports => exports.default)
|
|
227
|
+
const getRpc = () => getExports().then(exports => exports.__rpc__ ?? {})
|
|
227
228
|
|
|
228
|
-
|
|
229
|
-
|
|
229
|
+
// Bridge the user's default-export shape onto a real \`WorkerEntrypoint\`
|
|
230
|
+
// subclass so Cloudflare service bindings can dispatch both the standard
|
|
231
|
+
// handler methods (fetch, scheduled, …) and any user-defined RPC methods.
|
|
232
|
+
// RPC method results are wire-encoded by \`runtimeContext.exports\`;
|
|
233
|
+
// consumers unwrap them with \`Cloudflare.toPromiseApi(env.X)\` (Promise
|
|
234
|
+
// API) or \`bindWorker(WorkerClass)\` (Effect API).
|
|
235
|
+
export default makeWorkerBridge(
|
|
236
|
+
WorkerEntrypoint,
|
|
237
|
+
ExportedHandlerMethods,
|
|
238
|
+
getDefault,
|
|
239
|
+
getRpc,
|
|
230
240
|
);
|
|
231
241
|
|
|
232
242
|
// export class proxy stubs for Durable Objects and Workflows
|