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,51 +1,36 @@
|
|
|
1
1
|
import * as workers from "@distilled.cloud/cloudflare/workers";
|
|
2
2
|
import * as zones from "@distilled.cloud/cloudflare/zones";
|
|
3
|
-
import * as Cause from "effect/Cause";
|
|
4
3
|
import * as Context from "effect/Context";
|
|
5
4
|
import * as Data from "effect/Data";
|
|
6
5
|
import * as Effect from "effect/Effect";
|
|
7
|
-
import * as Exit from "effect/Exit";
|
|
8
6
|
import * as Layer from "effect/Layer";
|
|
9
|
-
import * as Option from "effect/Option";
|
|
10
7
|
import * as Path from "effect/Path";
|
|
11
8
|
import * as Redacted from "effect/Redacted";
|
|
12
9
|
import * as Schedule from "effect/Schedule";
|
|
13
|
-
import * as Scope from "effect/Scope";
|
|
14
|
-
import * as Stream from "effect/Stream";
|
|
15
10
|
import { Unowned } from "../../AdoptPolicy.js";
|
|
16
11
|
import { AlchemyContext } from "../../AlchemyContext.js";
|
|
17
12
|
import * as Artifacts from "../../Artifacts.js";
|
|
18
|
-
import * as Binding from "../../Binding.js";
|
|
19
13
|
import { hashDirectory } from "../../Build/Memo.js";
|
|
20
14
|
import * as Bundle from "../../Bundle/Bundle.js";
|
|
21
15
|
import { isResolved } from "../../Diff.js";
|
|
22
|
-
import {
|
|
23
|
-
import * as Output from "../../Output.js";
|
|
24
|
-
import { Platform, } from "../../Platform.js";
|
|
16
|
+
import { Platform } from "../../Platform.js";
|
|
25
17
|
import * as Provider from "../../Provider.js";
|
|
26
18
|
import { Resource } from "../../Resource.js";
|
|
27
|
-
import * as Serverless from "../../Serverless/index.js";
|
|
28
19
|
import { Stack } from "../../Stack.js";
|
|
29
|
-
import { isYieldableEffectLike } from "../../Util/effect.js";
|
|
30
|
-
import { isAnalyticsEngineDataset, } from "../AnalyticsEngine/AnalyticsEngineDataset.js";
|
|
31
|
-
import { isArtifacts as isArtifactsBinding, } from "../Artifacts/Artifacts.js";
|
|
32
20
|
import { CloudflareEnvironment } from "../CloudflareEnvironment.js";
|
|
33
|
-
import { D1Database } from "../D1/D1Database.js";
|
|
34
|
-
import { isSendEmail } from "../Email/SendEmail.js";
|
|
35
|
-
import { isImages as isImagesBinding, } from "../Images/Images.js";
|
|
36
21
|
import { SidecarLive } from "../Local/Sidecar.js";
|
|
37
22
|
import { CloudflareLogs } from "../Logs.js";
|
|
38
|
-
import {
|
|
23
|
+
import { readAssets, uploadAssets, } from "./Assets.js";
|
|
39
24
|
import { getCompatibility } from "./Compatibility.js";
|
|
40
|
-
import { isDurableObjectExport
|
|
41
|
-
import { workersHttpHandler } from "./HttpServer.js";
|
|
25
|
+
import { isDurableObjectExport } from "./DurableObjectNamespace.js";
|
|
42
26
|
import { LocalWorkerProvider } from "./LocalWorkerProvider.js";
|
|
43
27
|
import { Request } from "./Request.js";
|
|
44
|
-
import { encodeRpcError, ErrorTag, makeRpcStub, toRpcStream, } from "./Rpc.js";
|
|
45
28
|
import * as Vite from "./Vite.js";
|
|
29
|
+
import { bindWorkerAsyncBindings, getCronBindings, } from "./WorkerAsyncBindings.js";
|
|
46
30
|
import { WorkerBundle } from "./WorkerBundle.js";
|
|
47
31
|
import { createWorkerName } from "./WorkerName.js";
|
|
48
|
-
|
|
32
|
+
import { makeWorkerRuntimeContext, } from "./WorkerRuntimeContext.js";
|
|
33
|
+
export const WorkerTypeId = "Cloudflare.Worker";
|
|
49
34
|
export const isWorker = (value) => typeof value === "object" &&
|
|
50
35
|
value !== null &&
|
|
51
36
|
"Type" in value &&
|
|
@@ -423,342 +408,11 @@ export const ExportedHandlerMethods = [
|
|
|
423
408
|
* ```
|
|
424
409
|
*/
|
|
425
410
|
export const Worker = Platform(WorkerTypeId, {
|
|
426
|
-
onCreate:
|
|
427
|
-
|
|
428
|
-
for (const bindingName in props.bindings) {
|
|
429
|
-
// @ts-expect-error
|
|
430
|
-
const bindingEff = props.bindings?.[bindingName];
|
|
431
|
-
// Bindings can be passed as a plain resource value, an Effect that
|
|
432
|
-
// yields a resource, or an effect-class (e.g. a `Cloudflare.Worker`
|
|
433
|
-
// class). Resolve the yieldable forms before deriving binding metadata.
|
|
434
|
-
const binding = isYieldableEffectLike(bindingEff)
|
|
435
|
-
? (yield* bindingEff)
|
|
436
|
-
: bindingEff;
|
|
437
|
-
const bindingMeta = isAssets(binding)
|
|
438
|
-
? {
|
|
439
|
-
type: "assets",
|
|
440
|
-
name: bindingName,
|
|
441
|
-
}
|
|
442
|
-
: isArtifactsBinding(binding)
|
|
443
|
-
? {
|
|
444
|
-
type: "artifacts",
|
|
445
|
-
name: bindingName,
|
|
446
|
-
namespace: binding.namespace,
|
|
447
|
-
}
|
|
448
|
-
: isImagesBinding(binding)
|
|
449
|
-
? {
|
|
450
|
-
type: "images",
|
|
451
|
-
name: bindingName,
|
|
452
|
-
}
|
|
453
|
-
: isAnalyticsEngineDataset(binding)
|
|
454
|
-
? {
|
|
455
|
-
type: "analytics_engine",
|
|
456
|
-
name: bindingName,
|
|
457
|
-
dataset: binding.dataset,
|
|
458
|
-
}
|
|
459
|
-
: isSendEmail(binding)
|
|
460
|
-
? {
|
|
461
|
-
type: "send_email",
|
|
462
|
-
name: bindingName,
|
|
463
|
-
destinationAddress: binding.destinationAddress,
|
|
464
|
-
allowedDestinationAddresses: binding.allowedDestinationAddresses,
|
|
465
|
-
allowedSenderAddresses: binding.allowedSenderAddresses,
|
|
466
|
-
}
|
|
467
|
-
: isDurableObjectNamespaceLike(binding)
|
|
468
|
-
? {
|
|
469
|
-
type: "durable_object_namespace",
|
|
470
|
-
name: bindingName,
|
|
471
|
-
className: binding.className ?? binding.name,
|
|
472
|
-
}
|
|
473
|
-
: binding.Type === "Cloudflare.D1Database"
|
|
474
|
-
? {
|
|
475
|
-
type: "d1",
|
|
476
|
-
id: binding.databaseId,
|
|
477
|
-
name: bindingName,
|
|
478
|
-
}
|
|
479
|
-
: binding.Type === "Cloudflare.R2Bucket"
|
|
480
|
-
? {
|
|
481
|
-
type: "r2_bucket",
|
|
482
|
-
name: bindingName,
|
|
483
|
-
bucketName: binding.bucketName,
|
|
484
|
-
jurisdiction: binding.jurisdiction.pipe(Output.map((jurisdiction) => jurisdiction === "default"
|
|
485
|
-
? undefined
|
|
486
|
-
: jurisdiction)),
|
|
487
|
-
}
|
|
488
|
-
: binding.Type === "Cloudflare.KVNamespace"
|
|
489
|
-
? {
|
|
490
|
-
type: "kv_namespace",
|
|
491
|
-
name: bindingName,
|
|
492
|
-
namespaceId: binding.namespaceId,
|
|
493
|
-
}
|
|
494
|
-
: binding.Type === "Cloudflare.Queue"
|
|
495
|
-
? {
|
|
496
|
-
type: "queue",
|
|
497
|
-
name: bindingName,
|
|
498
|
-
queueName: binding.queueName,
|
|
499
|
-
}
|
|
500
|
-
: binding.Type === "Cloudflare.AiGateway"
|
|
501
|
-
? {
|
|
502
|
-
type: "ai",
|
|
503
|
-
name: bindingName,
|
|
504
|
-
}
|
|
505
|
-
: binding.Type === "Cloudflare.Hyperdrive"
|
|
506
|
-
? {
|
|
507
|
-
type: "hyperdrive",
|
|
508
|
-
name: bindingName,
|
|
509
|
-
id: binding.hyperdriveId,
|
|
510
|
-
}
|
|
511
|
-
: isWorker(binding)
|
|
512
|
-
? {
|
|
513
|
-
type: "service",
|
|
514
|
-
name: bindingName,
|
|
515
|
-
service: binding.workerName,
|
|
516
|
-
}
|
|
517
|
-
: // TODO(sam): handle others
|
|
518
|
-
undefined;
|
|
519
|
-
if (bindingMeta) {
|
|
520
|
-
yield* resource.bind `${bindingName}`({
|
|
521
|
-
bindings: [bindingMeta],
|
|
522
|
-
});
|
|
523
|
-
}
|
|
524
|
-
else {
|
|
525
|
-
return yield* Effect.die(`Unknown binding type: ${bindingName}`);
|
|
526
|
-
}
|
|
527
|
-
}
|
|
528
|
-
}
|
|
529
|
-
}),
|
|
530
|
-
createRuntimeContext: (id) => {
|
|
531
|
-
const listeners = [];
|
|
532
|
-
const exports = {};
|
|
533
|
-
const env = {};
|
|
534
|
-
let userShape;
|
|
535
|
-
const ctx = {
|
|
536
|
-
Type: WorkerTypeId,
|
|
537
|
-
id,
|
|
538
|
-
env,
|
|
539
|
-
get: (key) => Effect.serviceOption(WorkerEnvironment).pipe(Effect.map(Option.getOrUndefined), Effect.flatMap((env) => env
|
|
540
|
-
? Effect.succeed(env[key])
|
|
541
|
-
: Effect.die("WorkerEnvironment not found")), Effect.flatMap((value) => value
|
|
542
|
-
? Effect.succeed(value)
|
|
543
|
-
: Effect.die(`Environment variable '${key}' not found`)), Effect.map((json) => {
|
|
544
|
-
try {
|
|
545
|
-
const value = JSON.parse(json);
|
|
546
|
-
// The `set` path serializes Redacted values as
|
|
547
|
-
// `{_tag: "Redacted", value: ...}`. After JSON.parse the
|
|
548
|
-
// result is a plain object — `Redacted.isRedacted` would
|
|
549
|
-
// always return `false` on it — so detect the marker shape
|
|
550
|
-
// and rebuild the Redacted wrapper. Plain values pass
|
|
551
|
-
// through unchanged.
|
|
552
|
-
if (value !== null &&
|
|
553
|
-
typeof value === "object" &&
|
|
554
|
-
value._tag === "Redacted" &&
|
|
555
|
-
"value" in value) {
|
|
556
|
-
return Redacted.make(value.value);
|
|
557
|
-
}
|
|
558
|
-
return value;
|
|
559
|
-
}
|
|
560
|
-
catch {
|
|
561
|
-
return json;
|
|
562
|
-
}
|
|
563
|
-
})),
|
|
564
|
-
set: (id, output) => Effect.sync(() => {
|
|
565
|
-
const key = id.replaceAll(/[^a-zA-Z0-9]/g, "_");
|
|
566
|
-
// Preserve `Redacted`-ness across the Output → env → Cloudflare
|
|
567
|
-
// binding boundary so the put-worker loop can deploy secrets via
|
|
568
|
-
// `secret_text` instead of leaking them as `plain_text`. The JSON
|
|
569
|
-
// payload still carries the `{_tag: "Redacted", …}` marker so the
|
|
570
|
-
// runtime `get` accessor can rebuild the wrapper after Cloudflare
|
|
571
|
-
// hands the binding back as a plain string.
|
|
572
|
-
env[key] = output.pipe(Output.map((value) => Redacted.isRedacted(value)
|
|
573
|
-
? Redacted.make(JSON.stringify({
|
|
574
|
-
_tag: "Redacted",
|
|
575
|
-
value: Redacted.value(value),
|
|
576
|
-
}))
|
|
577
|
-
: JSON.stringify(value)));
|
|
578
|
-
return key;
|
|
579
|
-
}),
|
|
580
|
-
serve: (handler, options) => {
|
|
581
|
-
// Capture the user's full default-export shape so `exports` can
|
|
582
|
-
// expose any non-handler methods on it as RPC methods on the
|
|
583
|
-
// deployed `WorkerEntrypoint` subclass — see `__rpc__` below.
|
|
584
|
-
if (options?.shape)
|
|
585
|
-
userShape = options.shape;
|
|
586
|
-
return ctx.listen(workersHttpHandler(handler));
|
|
587
|
-
},
|
|
588
|
-
listen: ((handler) => Effect.sync(() => Effect.isEffect(handler)
|
|
589
|
-
? listeners.push(handler)
|
|
590
|
-
: listeners.push(Effect.succeed(handler)))),
|
|
591
|
-
export: (name, value) => Effect.sync(() => {
|
|
592
|
-
exports[name] = value;
|
|
593
|
-
}),
|
|
594
|
-
exports: Effect.gen(function* () {
|
|
595
|
-
const handlers = yield* Effect.all(listeners, {
|
|
596
|
-
concurrency: "unbounded",
|
|
597
|
-
});
|
|
598
|
-
const services = yield* Effect.context();
|
|
599
|
-
// Provide the per-request runtime layer (services + `WorkerExecutionContext`
|
|
600
|
-
// + a fresh `ExecutionContext`/`Scope`) to a user effect, then run it.
|
|
601
|
-
// This is the bridge between Cloudflare's request-time callback and
|
|
602
|
-
// the user's Effect-native handler. Used by both the standard
|
|
603
|
-
// `handle()` dispatch (fetch/scheduled/…) and the per-RPC dispatchers
|
|
604
|
-
// below — keeping them on a single layer-provision path.
|
|
605
|
-
const runUserEffect = (eff, context) => {
|
|
606
|
-
const scope = Scope.makeUnsafe();
|
|
607
|
-
return eff
|
|
608
|
-
.pipe(Effect.provideContext(services), Scope.provide(scope), Effect.provide(Layer.succeed(WorkerExecutionContext, context)), Effect.provide(Layer.succeed(ExecutionContext, { scope, cache: {} })), Effect.runPromiseExit)
|
|
609
|
-
.finally(() => context.waitUntil(Effect.runPromise(Scope.close(scope, Exit.void))));
|
|
610
|
-
};
|
|
611
|
-
const handle = (type) => (request, env, context) => {
|
|
612
|
-
const event = {
|
|
613
|
-
kind: "Cloudflare.Workers.WorkerEvent",
|
|
614
|
-
type,
|
|
615
|
-
input: request,
|
|
616
|
-
env,
|
|
617
|
-
context,
|
|
618
|
-
};
|
|
619
|
-
for (const handler of handlers) {
|
|
620
|
-
const eff = handler(event);
|
|
621
|
-
if (Effect.isEffect(eff)) {
|
|
622
|
-
return runUserEffect(eff, context).then((exit) => {
|
|
623
|
-
if (exit._tag === "Success")
|
|
624
|
-
return exit.value;
|
|
625
|
-
throw Cause.squash(exit.cause);
|
|
626
|
-
});
|
|
627
|
-
}
|
|
628
|
-
}
|
|
629
|
-
return Promise.reject(new Error("No event handler found"));
|
|
630
|
-
};
|
|
631
|
-
// RPC method dispatchers — one per non-handler method on the user's
|
|
632
|
-
// shape. Each dispatcher is invoked by the WorkerEntrypoint bridge
|
|
633
|
-
// as `dispatcher(args, ctx)`: `args` are the user-facing call args,
|
|
634
|
-
// `ctx` is the `this.ctx` that Cloudflare hands the bridge per RPC
|
|
635
|
-
// request. The dispatcher runs the user effect with the same runtime
|
|
636
|
-
// layer the fetch path uses, then envelope-encodes the result so
|
|
637
|
-
// `Effect.fail` round-trips as `RpcErrorEnvelope` and `Stream` as
|
|
638
|
-
// `RpcStreamEnvelope` (consumers wrap the binding with
|
|
639
|
-
// `toPromiseApi`/`bindWorker` to decode).
|
|
640
|
-
const exportedHandlerSet = new Set(ExportedHandlerMethods);
|
|
641
|
-
const rpcDispatchers = {};
|
|
642
|
-
if (userShape) {
|
|
643
|
-
for (const [name, value] of Object.entries(userShape)) {
|
|
644
|
-
if (exportedHandlerSet.has(name))
|
|
645
|
-
continue;
|
|
646
|
-
if (typeof value !== "function")
|
|
647
|
-
continue;
|
|
648
|
-
rpcDispatchers[name] = async (args, context) => {
|
|
649
|
-
const result = value(...args);
|
|
650
|
-
if (!Effect.isEffect(result))
|
|
651
|
-
return result;
|
|
652
|
-
const exit = await runUserEffect(result, context);
|
|
653
|
-
if (exit._tag === "Success") {
|
|
654
|
-
if (Stream.isStream(exit.value)) {
|
|
655
|
-
return await Effect.runPromise(toRpcStream(exit.value));
|
|
656
|
-
}
|
|
657
|
-
return exit.value;
|
|
658
|
-
}
|
|
659
|
-
const failReason = exit.cause.reasons.find(Cause.isFailReason);
|
|
660
|
-
if (failReason) {
|
|
661
|
-
return {
|
|
662
|
-
_tag: ErrorTag,
|
|
663
|
-
error: encodeRpcError(failReason.error),
|
|
664
|
-
};
|
|
665
|
-
}
|
|
666
|
-
const dieReason = exit.cause.reasons.find(Cause.isDieReason);
|
|
667
|
-
throw (dieReason?.defect ??
|
|
668
|
-
new Error("RPC method failed with an unexpected cause"));
|
|
669
|
-
};
|
|
670
|
-
}
|
|
671
|
-
}
|
|
672
|
-
return {
|
|
673
|
-
...exports,
|
|
674
|
-
default: Object.fromEntries(ExportedHandlerMethods.map((method) => [method, handle(method)])),
|
|
675
|
-
__rpc__: rpcDispatchers,
|
|
676
|
-
};
|
|
677
|
-
}),
|
|
678
|
-
};
|
|
679
|
-
return ctx;
|
|
680
|
-
},
|
|
681
|
-
});
|
|
682
|
-
export const bindWorker = Effect.fnUntraced(function* (workerEff) {
|
|
683
|
-
// Worker classes and regular Effects are both yieldable here.
|
|
684
|
-
const worker = isYieldableEffectLike(workerEff)
|
|
685
|
-
? yield* workerEff
|
|
686
|
-
: workerEff;
|
|
687
|
-
const self = yield* Worker;
|
|
688
|
-
yield* self.bind `${worker}`({
|
|
689
|
-
bindings: [
|
|
690
|
-
{
|
|
691
|
-
type: "service",
|
|
692
|
-
name: worker.LogicalId,
|
|
693
|
-
service: worker.workerName,
|
|
694
|
-
},
|
|
695
|
-
],
|
|
696
|
-
});
|
|
697
|
-
// `bindWorker` runs at *init* phase (both at plantime and at runtime
|
|
698
|
-
// cold-start). `WorkerEnvironment` only exists at exec phase on the
|
|
699
|
-
// deployed worker, so we hand `makeRpcStub` an `Effect<stub>` that
|
|
700
|
-
// resolves the binding lazily on each method call.
|
|
701
|
-
const stubEff = WorkerEnvironment.pipe(Effect.map((env) => env[worker.LogicalId]));
|
|
702
|
-
return makeRpcStub(stubEff);
|
|
411
|
+
onCreate: bindWorkerAsyncBindings,
|
|
412
|
+
createRuntimeContext: makeWorkerRuntimeContext,
|
|
703
413
|
});
|
|
704
|
-
export class BindWorkerPolicy extends Binding.Policy()("Cloudflare.Worker.Bind") {
|
|
705
|
-
}
|
|
706
|
-
export const BindWorkerPolicyLive = BindWorkerPolicy.layer.succeed(Effect.fn(function* (host, worker) {
|
|
707
|
-
if (isWorker(host)) {
|
|
708
|
-
yield* host.bind `${worker}`({
|
|
709
|
-
bindings: [
|
|
710
|
-
{
|
|
711
|
-
type: "service",
|
|
712
|
-
name: worker.LogicalId,
|
|
713
|
-
service: worker.workerName,
|
|
714
|
-
},
|
|
715
|
-
],
|
|
716
|
-
});
|
|
717
|
-
}
|
|
718
|
-
else {
|
|
719
|
-
return yield* Effect.die(new Error(`BindWorkerPolicy does not support runtime '${host.Type}'`));
|
|
720
|
-
}
|
|
721
|
-
}));
|
|
722
414
|
class MissingDurableObjectNamespaces extends Data.TaggedError("MissingDurableObjectNamespaces") {
|
|
723
415
|
}
|
|
724
|
-
function bumpMigrationTagVersion(oldTag) {
|
|
725
|
-
if (!oldTag)
|
|
726
|
-
return undefined;
|
|
727
|
-
const version = oldTag.match(/^(alchemy:)?v(\d+)$/)?.[2];
|
|
728
|
-
if (!version)
|
|
729
|
-
return "alchemy:v1";
|
|
730
|
-
return `alchemy:v${parseInt(version, 10) + 1}`;
|
|
731
|
-
}
|
|
732
|
-
function getDurableObjectBindings(bindings, workerName) {
|
|
733
|
-
return bindings.flatMap((binding) => (binding.data.bindings ?? []).flatMap((item) => item.type === "durable_object_namespace" &&
|
|
734
|
-
"className" in item &&
|
|
735
|
-
item.className &&
|
|
736
|
-
(!("scriptName" in item) ||
|
|
737
|
-
!item.scriptName ||
|
|
738
|
-
item.scriptName === workerName)
|
|
739
|
-
? [
|
|
740
|
-
{
|
|
741
|
-
logicalId: binding.sid,
|
|
742
|
-
bindingName: item.name,
|
|
743
|
-
className: item.className,
|
|
744
|
-
},
|
|
745
|
-
]
|
|
746
|
-
: []));
|
|
747
|
-
}
|
|
748
|
-
export function getCronBindings(bindings) {
|
|
749
|
-
return Array.from(new Set(bindings.flatMap((b) => b.data.crons ?? [])));
|
|
750
|
-
}
|
|
751
|
-
function getDurableObjectTagMap(tags) {
|
|
752
|
-
return Object.fromEntries(tags.flatMap((tag) => {
|
|
753
|
-
if (!tag.startsWith("alchemy:do:")) {
|
|
754
|
-
return [];
|
|
755
|
-
}
|
|
756
|
-
const parts = tag.split(":");
|
|
757
|
-
const logicalId = parts[2];
|
|
758
|
-
const className = parts.slice(3).join(":");
|
|
759
|
-
return logicalId && className ? [[logicalId, className]] : [];
|
|
760
|
-
}));
|
|
761
|
-
}
|
|
762
416
|
const selectLayer = (input) => Layer.unwrap(AlchemyContext.useSync((context) => context.dev ? input.dev() : input.live()));
|
|
763
417
|
export const WorkerProvider = () => selectLayer({
|
|
764
418
|
live: LiveWorkerProvider,
|
|
@@ -1677,6 +1331,12 @@ export const LiveWorkerProvider = () => Provider.effect(Worker, Effect.gen(funct
|
|
|
1677
1331
|
yield* deleteScript({
|
|
1678
1332
|
accountId: output.accountId,
|
|
1679
1333
|
scriptName: output.workerName,
|
|
1334
|
+
// Force teardown of queue consumers, durable object classes, and
|
|
1335
|
+
// service bindings hanging off this worker. Without `force`, those
|
|
1336
|
+
// conditions raise QueueConsumerConflict / ServiceBindingConflict
|
|
1337
|
+
// and leave the script in CF. Alchemy is the source of truth for
|
|
1338
|
+
// the worker, so we want a hard delete on teardown.
|
|
1339
|
+
force: true,
|
|
1680
1340
|
}).pipe(Effect.catchTag("WorkerNotFound", () => Effect.void));
|
|
1681
1341
|
}),
|
|
1682
1342
|
tail: ({ output }) => telemetry.tailScript({
|
|
@@ -1719,4 +1379,39 @@ const contentTypeFromExtension = (extension) => {
|
|
|
1719
1379
|
return "application/octet-stream";
|
|
1720
1380
|
}
|
|
1721
1381
|
};
|
|
1382
|
+
function bumpMigrationTagVersion(oldTag) {
|
|
1383
|
+
if (!oldTag)
|
|
1384
|
+
return undefined;
|
|
1385
|
+
const version = oldTag.match(/^(alchemy:)?v(\d+)$/)?.[2];
|
|
1386
|
+
if (!version)
|
|
1387
|
+
return "alchemy:v1";
|
|
1388
|
+
return `alchemy:v${parseInt(version, 10) + 1}`;
|
|
1389
|
+
}
|
|
1390
|
+
function getDurableObjectBindings(bindings, workerName) {
|
|
1391
|
+
return bindings.flatMap((binding) => (binding.data.bindings ?? []).flatMap((item) => item.type === "durable_object_namespace" &&
|
|
1392
|
+
"className" in item &&
|
|
1393
|
+
item.className &&
|
|
1394
|
+
(!("scriptName" in item) ||
|
|
1395
|
+
!item.scriptName ||
|
|
1396
|
+
item.scriptName === workerName)
|
|
1397
|
+
? [
|
|
1398
|
+
{
|
|
1399
|
+
logicalId: binding.sid,
|
|
1400
|
+
bindingName: item.name,
|
|
1401
|
+
className: item.className,
|
|
1402
|
+
},
|
|
1403
|
+
]
|
|
1404
|
+
: []));
|
|
1405
|
+
}
|
|
1406
|
+
function getDurableObjectTagMap(tags) {
|
|
1407
|
+
return Object.fromEntries(tags.flatMap((tag) => {
|
|
1408
|
+
if (!tag.startsWith("alchemy:do:")) {
|
|
1409
|
+
return [];
|
|
1410
|
+
}
|
|
1411
|
+
const parts = tag.split(":");
|
|
1412
|
+
const logicalId = parts[2];
|
|
1413
|
+
const className = parts.slice(3).join(":");
|
|
1414
|
+
return logicalId && className ? [[logicalId, className]] : [];
|
|
1415
|
+
}));
|
|
1416
|
+
}
|
|
1722
1417
|
//# sourceMappingURL=Worker.js.map
|