alchemy 2.0.0-beta.70 → 2.0.0-beta.71
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +201 -0
- package/NOTICE +5 -0
- package/README.md +3 -1
- package/THIRD_PARTY_LICENSES.md +127 -0
- package/bin/exec.js +25 -9
- package/bin/exec.js.map +1 -1
- package/lib/AWS/DataZone/Domain.d.ts.map +1 -1
- package/lib/AWS/DataZone/Domain.js +7 -7
- package/lib/AWS/DataZone/Domain.js.map +1 -1
- package/lib/AWS/EC2/InternetGateway.d.ts.map +1 -1
- package/lib/AWS/EC2/InternetGateway.js +14 -16
- package/lib/AWS/EC2/InternetGateway.js.map +1 -1
- package/lib/AWS/EC2/LingeringEnis.d.ts +2 -2
- package/lib/AWS/EC2/LingeringEnis.d.ts.map +1 -1
- package/lib/AWS/EC2/LingeringEnis.js +9 -7
- package/lib/AWS/EC2/LingeringEnis.js.map +1 -1
- package/lib/AWS/RDSData/Marshall.d.ts +23 -0
- package/lib/AWS/RDSData/Marshall.d.ts.map +1 -0
- package/lib/AWS/RDSData/Marshall.js +87 -0
- package/lib/AWS/RDSData/Marshall.js.map +1 -0
- package/lib/AWS/RDSData/index.d.ts +1 -0
- package/lib/AWS/RDSData/index.d.ts.map +1 -1
- package/lib/AWS/RDSData/index.js +1 -0
- package/lib/AWS/RDSData/index.js.map +1 -1
- package/lib/AWS/ResourceGroups/Group.d.ts.map +1 -1
- package/lib/AWS/ResourceGroups/Group.js +3 -1
- package/lib/AWS/ResourceGroups/Group.js.map +1 -1
- package/lib/AWS/S3Tables/Namespace.d.ts.map +1 -1
- package/lib/AWS/S3Tables/Namespace.js +3 -1
- package/lib/AWS/S3Tables/Namespace.js.map +1 -1
- package/lib/AWS/S3Tables/TableBucket.d.ts.map +1 -1
- package/lib/AWS/S3Tables/TableBucket.js +8 -2
- package/lib/AWS/S3Tables/TableBucket.js.map +1 -1
- package/lib/AWS/S3Vectors/VectorBucket.d.ts.map +1 -1
- package/lib/AWS/S3Vectors/VectorBucket.js +6 -1
- package/lib/AWS/S3Vectors/VectorBucket.js.map +1 -1
- package/lib/AWS/Website/cfcode.d.ts.map +1 -1
- package/lib/AWS/Website/cfcode.js +2 -0
- package/lib/AWS/Website/cfcode.js.map +1 -1
- package/lib/Apply.d.ts.map +1 -1
- package/lib/Apply.js +22 -8
- package/lib/Apply.js.map +1 -1
- package/lib/Auth/AuthProvider.d.ts.map +1 -1
- package/lib/Auth/AuthProvider.js +1 -1
- package/lib/Auth/AuthProvider.js.map +1 -1
- package/lib/Bundle/Bundle.js +2 -2
- package/lib/Bundle/Bundle.js.map +1 -1
- package/lib/Cli/commands/cloudflare.js +1 -1
- package/lib/Cli/commands/cloudflare.js.map +1 -1
- package/lib/Cli/commands/logs.d.ts.map +1 -1
- package/lib/Cli/commands/logs.js +2 -1
- package/lib/Cli/commands/logs.js.map +1 -1
- package/lib/Cli/commands/nuke.js +1 -1
- package/lib/Cli/commands/nuke.js.map +1 -1
- package/lib/Cli/commands/tail.d.ts.map +1 -1
- package/lib/Cli/commands/tail.js +2 -1
- package/lib/Cli/commands/tail.js.map +1 -1
- package/lib/Cloudflare/AI/LanguageModel.js +1 -1
- package/lib/Cloudflare/AI/LanguageModel.js.map +1 -1
- package/lib/Cloudflare/Access.js +1 -1
- package/lib/Cloudflare/Access.js.map +1 -1
- package/lib/Cloudflare/Containers/ContainerBundle.d.ts +1 -1
- package/lib/Cloudflare/Containers/ContainerBundle.js +1 -1
- package/lib/Cloudflare/Containers/ContainerProvider.d.ts.map +1 -1
- package/lib/Cloudflare/Containers/ContainerProvider.js +24 -2
- package/lib/Cloudflare/Containers/ContainerProvider.js.map +1 -1
- package/lib/Cloudflare/Containers/LocalContainerProvider.d.ts +1 -1
- package/lib/Cloudflare/Containers/LocalContainerProvider.js +1 -1
- package/lib/Cloudflare/D1/Database.d.ts +2 -2
- package/lib/Cloudflare/D1/Database.d.ts.map +1 -1
- package/lib/Cloudflare/D1/LocalD1Gateway.d.ts +3 -3
- package/lib/Cloudflare/D1/LocalD1Gateway.d.ts.map +1 -1
- package/lib/Cloudflare/D1/LocalD1Gateway.js +3 -3
- package/lib/Cloudflare/D1/LocalD1Gateway.js.map +1 -1
- package/lib/Cloudflare/KV/LocalKVGateway.js +2 -2
- package/lib/Cloudflare/KV/LocalKVGateway.js.map +1 -1
- package/lib/Cloudflare/LocalGateway.d.ts +1 -1
- package/lib/Cloudflare/LocalGateway.d.ts.map +1 -1
- package/lib/Cloudflare/LocalGateway.js +1 -1
- package/lib/Cloudflare/LocalGateway.js.map +1 -1
- package/lib/Cloudflare/LocalRuntime.d.ts +1 -1
- package/lib/Cloudflare/LocalRuntime.d.ts.map +1 -1
- package/lib/Cloudflare/LocalRuntime.js +5 -4
- package/lib/Cloudflare/LocalRuntime.js.map +1 -1
- package/lib/Cloudflare/Queues/Consumer.d.ts +22 -5
- package/lib/Cloudflare/Queues/Consumer.d.ts.map +1 -1
- package/lib/Cloudflare/Queues/Consumer.js +129 -38
- package/lib/Cloudflare/Queues/Consumer.js.map +1 -1
- package/lib/Cloudflare/Queues/Queue.d.ts +4 -3
- package/lib/Cloudflare/Queues/Queue.d.ts.map +1 -1
- package/lib/Cloudflare/Queues/Queue.js +115 -6
- package/lib/Cloudflare/Queues/Queue.js.map +1 -1
- package/lib/Cloudflare/R2/LocalR2Gateway.js +2 -2
- package/lib/Cloudflare/R2/LocalR2Gateway.js.map +1 -1
- package/lib/Cloudflare/SecretsStore/LocalSecretsStoreGateway.d.ts +4 -4
- package/lib/Cloudflare/SecretsStore/LocalSecretsStoreGateway.d.ts.map +1 -1
- package/lib/Cloudflare/SecretsStore/LocalSecretsStoreGateway.js +2 -2
- package/lib/Cloudflare/SecretsStore/LocalSecretsStoreGateway.js.map +1 -1
- package/lib/Cloudflare/SecretsStore/Secret.d.ts +2 -2
- package/lib/Cloudflare/SecretsStore/Secret.d.ts.map +1 -1
- package/lib/Cloudflare/StateStore/Api.js +7 -0
- package/lib/Cloudflare/StateStore/Api.js.map +1 -1
- package/lib/Cloudflare/Website/Astro.d.ts +19 -11
- package/lib/Cloudflare/Website/Astro.d.ts.map +1 -1
- package/lib/Cloudflare/Website/Astro.js +16 -9
- package/lib/Cloudflare/Website/Astro.js.map +1 -1
- package/lib/Cloudflare/Website/Nextjs.d.ts +7 -4
- package/lib/Cloudflare/Website/Nextjs.d.ts.map +1 -1
- package/lib/Cloudflare/Website/Nextjs.js +10 -8
- package/lib/Cloudflare/Website/Nextjs.js.map +1 -1
- package/lib/Cloudflare/Website/Nuxt.d.ts +5 -4
- package/lib/Cloudflare/Website/Nuxt.d.ts.map +1 -1
- package/lib/Cloudflare/Website/Nuxt.js +4 -3
- package/lib/Cloudflare/Website/Nuxt.js.map +1 -1
- package/lib/Cloudflare/Website/Octane.d.ts +4 -3
- package/lib/Cloudflare/Website/Octane.d.ts.map +1 -1
- package/lib/Cloudflare/Website/Octane.js +5 -4
- package/lib/Cloudflare/Website/Octane.js.map +1 -1
- package/lib/Cloudflare/Website/SvelteKit.d.ts +17 -10
- package/lib/Cloudflare/Website/SvelteKit.d.ts.map +1 -1
- package/lib/Cloudflare/Website/SvelteKit.js +9 -5
- package/lib/Cloudflare/Website/SvelteKit.js.map +1 -1
- package/lib/Cloudflare/Website/Waku.d.ts +20 -9
- package/lib/Cloudflare/Website/Waku.d.ts.map +1 -1
- package/lib/Cloudflare/Website/Waku.js +10 -4
- package/lib/Cloudflare/Website/Waku.js.map +1 -1
- package/lib/Cloudflare/Workers/Assets.d.ts +54 -1
- package/lib/Cloudflare/Workers/Assets.d.ts.map +1 -1
- package/lib/Cloudflare/Workers/Assets.js +60 -26
- package/lib/Cloudflare/Workers/Assets.js.map +1 -1
- package/lib/Cloudflare/Workers/LocalWorkerProvider.d.ts +2 -2
- package/lib/Cloudflare/Workers/LocalWorkerProvider.d.ts.map +1 -1
- package/lib/Cloudflare/Workers/LocalWorkerProvider.js +153 -49
- package/lib/Cloudflare/Workers/LocalWorkerProvider.js.map +1 -1
- package/lib/Cloudflare/Workers/RuntimeBindings.d.ts +3 -3
- package/lib/Cloudflare/Workers/RuntimeBindings.d.ts.map +1 -1
- package/lib/Cloudflare/Workers/RuntimeBindings.js +2 -2
- package/lib/Cloudflare/Workers/RuntimeBindings.js.map +1 -1
- package/lib/Cloudflare/Workers/Source.d.ts +1 -1
- package/lib/Cloudflare/Workers/Source.d.ts.map +1 -1
- package/lib/Cloudflare/Workers/Source.js +1 -1
- package/lib/Cloudflare/Workers/Source.js.map +1 -1
- package/lib/Cloudflare/Workers/Sources/Rolldown.d.ts.map +1 -1
- package/lib/Cloudflare/Workers/Sources/Rolldown.js +3 -4
- package/lib/Cloudflare/Workers/Sources/Rolldown.js.map +1 -1
- package/lib/Cloudflare/Workers/Sources/Vite.d.ts +1 -1
- package/lib/Cloudflare/Workers/Sources/Vite.d.ts.map +1 -1
- package/lib/Cloudflare/Workers/Sources/Vite.js +36 -17
- package/lib/Cloudflare/Workers/Sources/Vite.js.map +1 -1
- package/lib/Cloudflare/Workers/ViteChild.d.ts.map +1 -1
- package/lib/Cloudflare/Workers/ViteChild.js +6 -0
- package/lib/Cloudflare/Workers/ViteChild.js.map +1 -1
- package/lib/Cloudflare/Workers/ViteChild.shared.d.ts +1 -1
- package/lib/Cloudflare/Workers/ViteChild.shared.d.ts.map +1 -1
- package/lib/Cloudflare/Workers/ViteChildRunner.js +5 -10
- package/lib/Cloudflare/Workers/ViteChildRunner.js.map +1 -1
- package/lib/Cloudflare/Workers/Worker.d.ts +11 -4
- package/lib/Cloudflare/Workers/Worker.d.ts.map +1 -1
- package/lib/Cloudflare/Workers/Worker.js.map +1 -1
- package/lib/Cloudflare/Workers/WorkerProvider.d.ts +1 -1
- package/lib/Cloudflare/Workers/WorkerProvider.d.ts.map +1 -1
- package/lib/Cloudflare/Workers/WorkerProvider.js +12 -2
- package/lib/Cloudflare/Workers/WorkerProvider.js.map +1 -1
- package/lib/Docker/Docker.d.ts.map +1 -1
- package/lib/Docker/Docker.js +6 -2
- package/lib/Docker/Docker.js.map +1 -1
- package/lib/Drizzle/{DurableObject.d.ts → Cloudflare.d.ts} +2 -1
- package/lib/Drizzle/Cloudflare.d.ts.map +1 -0
- package/lib/Drizzle/{DurableObject.js → Cloudflare.js} +2 -1
- package/lib/Drizzle/Cloudflare.js.map +1 -0
- package/lib/Drizzle/MySQL.d.ts +2 -2
- package/lib/Drizzle/MySQL.d.ts.map +1 -1
- package/lib/Drizzle/MySQL.js +5 -3
- package/lib/Drizzle/MySQL.js.map +1 -1
- package/lib/Drizzle/Postgres.d.ts +1 -1
- package/lib/Drizzle/Postgres.d.ts.map +1 -1
- package/lib/Drizzle/Postgres.js +4 -2
- package/lib/Drizzle/Postgres.js.map +1 -1
- package/lib/Drizzle/index.d.ts +0 -3
- package/lib/Drizzle/index.d.ts.map +1 -1
- package/lib/Drizzle/index.js +5 -3
- package/lib/Drizzle/index.js.map +1 -1
- package/lib/Neon/Migrations.d.ts.map +1 -1
- package/lib/Neon/Migrations.js +1 -5
- package/lib/Neon/Migrations.js.map +1 -1
- package/lib/PhysicalName.d.ts +8 -0
- package/lib/PhysicalName.d.ts.map +1 -1
- package/lib/PhysicalName.js +5 -2
- package/lib/PhysicalName.js.map +1 -1
- package/lib/Plan.d.ts.map +1 -1
- package/lib/Plan.js +16 -9
- package/lib/Plan.js.map +1 -1
- package/lib/ProviderMode.d.ts +45 -0
- package/lib/ProviderMode.d.ts.map +1 -1
- package/lib/ProviderMode.js +51 -0
- package/lib/ProviderMode.js.map +1 -1
- package/lib/SQL/ConnectionSource.d.ts +45 -0
- package/lib/SQL/ConnectionSource.d.ts.map +1 -0
- package/lib/SQL/ConnectionSource.js +51 -0
- package/lib/SQL/ConnectionSource.js.map +1 -0
- package/lib/SQL/MySQLDriver.d.ts +21 -0
- package/lib/SQL/MySQLDriver.d.ts.map +1 -0
- package/lib/SQL/MySQLDriver.js +31 -0
- package/lib/SQL/MySQLDriver.js.map +1 -0
- package/lib/SQL/PostgresDriver.d.ts +21 -0
- package/lib/SQL/PostgresDriver.d.ts.map +1 -0
- package/lib/SQL/PostgresDriver.js +29 -0
- package/lib/SQL/PostgresDriver.js.map +1 -0
- package/lib/State/HttpStateApi.d.ts +11 -11
- package/lib/State/LocalState.d.ts.map +1 -1
- package/lib/State/LocalState.js +17 -1
- package/lib/State/LocalState.js.map +1 -1
- package/lib/State/ResourceState.d.ts +6 -2
- package/lib/State/ResourceState.d.ts.map +1 -1
- package/lib/State/StateEncoding.d.ts +8 -0
- package/lib/State/StateEncoding.d.ts.map +1 -1
- package/lib/State/StateEncoding.js +38 -0
- package/lib/State/StateEncoding.js.map +1 -1
- package/lib/Sync.d.ts.map +1 -1
- package/lib/Sync.js +4 -2
- package/lib/Sync.js.map +1 -1
- package/lib/Test/Alchemy.d.ts.map +1 -1
- package/lib/Test/Alchemy.js +24 -14
- package/lib/Test/Alchemy.js.map +1 -1
- package/lib/Test/Core.d.ts +25 -8
- package/lib/Test/Core.d.ts.map +1 -1
- package/lib/Test/Core.js +24 -7
- package/lib/Test/Core.js.map +1 -1
- package/package.json +49 -40
- package/src/AWS/DataZone/Domain.ts +15 -13
- package/src/AWS/EC2/InternetGateway.ts +28 -32
- package/src/AWS/EC2/LingeringEnis.ts +11 -9
- package/src/AWS/RDSData/Marshall.ts +106 -0
- package/src/AWS/RDSData/index.ts +1 -0
- package/src/AWS/ResourceGroups/Group.ts +5 -1
- package/src/AWS/S3Tables/Namespace.ts +3 -1
- package/src/AWS/S3Tables/TableBucket.ts +8 -2
- package/src/AWS/S3Vectors/VectorBucket.ts +6 -1
- package/src/AWS/Website/cfcode.ts +2 -0
- package/src/Apply.ts +22 -9
- package/src/Auth/AuthProvider.ts +4 -7
- package/src/Bundle/Bundle.ts +2 -2
- package/src/Cli/commands/cloudflare.ts +1 -1
- package/src/Cli/commands/logs.ts +2 -1
- package/src/Cli/commands/nuke.ts +1 -1
- package/src/Cli/commands/tail.ts +2 -1
- package/src/Cloudflare/AI/LanguageModel.ts +3 -0
- package/src/Cloudflare/Access.ts +1 -1
- package/src/Cloudflare/Containers/ContainerBundle.ts +1 -1
- package/src/Cloudflare/Containers/ContainerProvider.ts +35 -5
- package/src/Cloudflare/Containers/LocalContainerProvider.ts +1 -1
- package/src/Cloudflare/D1/Database.ts +1 -1
- package/src/Cloudflare/D1/LocalD1Gateway.ts +4 -4
- package/src/Cloudflare/KV/LocalKVGateway.ts +2 -2
- package/src/Cloudflare/LocalGateway.ts +1 -1
- package/src/Cloudflare/LocalRuntime.ts +6 -4
- package/src/Cloudflare/Queues/Consumer.ts +183 -45
- package/src/Cloudflare/Queues/Queue.ts +157 -5
- package/src/Cloudflare/R2/LocalR2Gateway.ts +2 -2
- package/src/Cloudflare/SecretsStore/LocalSecretsStoreGateway.ts +2 -2
- package/src/Cloudflare/SecretsStore/Secret.ts +1 -1
- package/src/Cloudflare/StateStore/Api.ts +7 -0
- package/src/Cloudflare/Website/Astro.ts +20 -12
- package/src/Cloudflare/Website/Nextjs.ts +13 -8
- package/src/Cloudflare/Website/Nuxt.ts +6 -5
- package/src/Cloudflare/Website/Octane.ts +6 -4
- package/src/Cloudflare/Website/SvelteKit.ts +18 -11
- package/src/Cloudflare/Website/Waku.ts +21 -10
- package/src/Cloudflare/Workers/Assets.ts +122 -20
- package/src/Cloudflare/Workers/LocalWorkerProvider.ts +228 -81
- package/src/Cloudflare/Workers/RuntimeBindings.ts +3 -3
- package/src/Cloudflare/Workers/Source.ts +2 -2
- package/src/Cloudflare/Workers/Sources/Rolldown.ts +3 -4
- package/src/Cloudflare/Workers/Sources/Vite.ts +46 -24
- package/src/Cloudflare/Workers/ViteChild.shared.ts +1 -1
- package/src/Cloudflare/Workers/ViteChild.ts +6 -0
- package/src/Cloudflare/Workers/ViteChildRunner.ts +5 -10
- package/src/Cloudflare/Workers/Worker.ts +26 -6
- package/src/Cloudflare/Workers/WorkerProvider.ts +19 -2
- package/src/Docker/Docker.ts +17 -11
- package/src/Drizzle/{DurableObject.ts → Cloudflare.ts} +1 -0
- package/src/Drizzle/MySQL.ts +13 -3
- package/src/Drizzle/Postgres.ts +10 -2
- package/src/Drizzle/index.ts +6 -3
- package/src/Neon/Migrations.ts +1 -10
- package/src/PhysicalName.ts +17 -1
- package/src/Plan.ts +20 -9
- package/src/ProviderMode.ts +56 -0
- package/src/SQL/ConnectionSource.ts +101 -0
- package/src/SQL/MySQLDriver.ts +49 -0
- package/src/SQL/PostgresDriver.ts +45 -0
- package/src/State/LocalState.ts +24 -0
- package/src/State/ResourceState.ts +6 -2
- package/src/State/StateEncoding.ts +37 -0
- package/src/Sync.ts +4 -2
- package/src/Test/Alchemy.ts +17 -6
- package/src/Test/Core.ts +42 -15
- package/lib/Drizzle/DurableObject.d.ts.map +0 -1
- package/lib/Drizzle/DurableObject.js.map +0 -1
|
@@ -20,10 +20,65 @@ export interface Assets {
|
|
|
20
20
|
export const isAssets = (value: any): value is Assets =>
|
|
21
21
|
value?.kind === "Cloudflare.Workers.Assets";
|
|
22
22
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
23
|
+
/**
|
|
24
|
+
* Routing configuration for a Worker's static assets — sent to Cloudflare
|
|
25
|
+
* as `metadata.assets.config` on script upload. Declared explicitly (not
|
|
26
|
+
* derived from the distilled API schema) so alchemy owns and documents its
|
|
27
|
+
* public surface.
|
|
28
|
+
*/
|
|
29
|
+
export interface AssetsConfig {
|
|
30
|
+
/**
|
|
31
|
+
* Determines the redirects and rewrites of requests for HTML content:
|
|
32
|
+
* whether `/page` serves `page.html`, and whether trailing slashes are
|
|
33
|
+
* added or dropped.
|
|
34
|
+
*
|
|
35
|
+
* @default "auto-trailing-slash"
|
|
36
|
+
*/
|
|
37
|
+
htmlHandling?:
|
|
38
|
+
| "auto-trailing-slash"
|
|
39
|
+
| "force-trailing-slash"
|
|
40
|
+
| "drop-trailing-slash"
|
|
41
|
+
| "none";
|
|
42
|
+
/**
|
|
43
|
+
* Determines the response when a request does not match a static asset:
|
|
44
|
+
* `"404-page"` serves the nearest `404.html`, and
|
|
45
|
+
* `"single-page-application"` serves `index.html` for client-side
|
|
46
|
+
* routing. When the Worker has a script, an unmatched request falls
|
|
47
|
+
* through to the Worker instead.
|
|
48
|
+
*
|
|
49
|
+
* @default "none"
|
|
50
|
+
*/
|
|
51
|
+
notFoundHandling?: "none" | "404-page" | "single-page-application";
|
|
52
|
+
/**
|
|
53
|
+
* Routes requests through the Worker *before* static-asset matching.
|
|
54
|
+
*
|
|
55
|
+
* Assets-first by default: a request matching a file is served directly
|
|
56
|
+
* and never invokes the Worker. `true` routes every request through the
|
|
57
|
+
* Worker ahead of the asset layer — serve files yourself via the
|
|
58
|
+
* `ASSETS` binding. A path-rule array routes only matching paths
|
|
59
|
+
* worker-first (e.g. `["/api/*"]`): glob (`*`) and negative (`!`) rules
|
|
60
|
+
* are supported, rules must start with `/` or `!/`, and negative rules
|
|
61
|
+
* take precedence. The same routing applies under `alchemy dev`.
|
|
62
|
+
*
|
|
63
|
+
* @default false
|
|
64
|
+
*/
|
|
65
|
+
runWorkerFirst?: boolean | string[];
|
|
66
|
+
/**
|
|
67
|
+
* Legacy routing flag predating `runWorkerFirst`.
|
|
68
|
+
*/
|
|
69
|
+
serveDirectly?: boolean;
|
|
70
|
+
/**
|
|
71
|
+
* Raw contents of a `_headers` file — header rules applied by the asset
|
|
72
|
+
* layer. Overrides a `_headers` file read from the assets directory.
|
|
73
|
+
*/
|
|
74
|
+
headers?: string;
|
|
75
|
+
/**
|
|
76
|
+
* Raw contents of a `_redirects` file — redirect rules applied by the
|
|
77
|
+
* asset layer. Overrides a `_redirects` file read from the assets
|
|
78
|
+
* directory.
|
|
79
|
+
*/
|
|
80
|
+
redirects?: string;
|
|
81
|
+
}
|
|
27
82
|
|
|
28
83
|
export interface AssetReadResult {
|
|
29
84
|
directory: string;
|
|
@@ -117,23 +172,56 @@ export class AssetUploadSessionError extends Data.TaggedError(
|
|
|
117
172
|
workerName: string;
|
|
118
173
|
}> {}
|
|
119
174
|
|
|
175
|
+
const contentTypesByExtension: Record<string, string> = {
|
|
176
|
+
html: "text/html",
|
|
177
|
+
htm: "text/html",
|
|
178
|
+
txt: "text/plain",
|
|
179
|
+
md: "text/markdown",
|
|
180
|
+
sql: "text/sql",
|
|
181
|
+
json: "application/json",
|
|
182
|
+
// Source maps are JSON; serving them as such lets devtools consume them.
|
|
183
|
+
map: "application/json",
|
|
184
|
+
jsonld: "application/ld+json",
|
|
185
|
+
xml: "application/xml",
|
|
186
|
+
csv: "text/csv",
|
|
187
|
+
// Browsers only accept JavaScript module scripts when the MIME type is a
|
|
188
|
+
// "JavaScript MIME type" (e.g. text/javascript). application/javascript+module
|
|
189
|
+
// is not valid and causes strict module loading to fail.
|
|
190
|
+
js: "text/javascript; charset=utf-8",
|
|
191
|
+
mjs: "text/javascript; charset=utf-8",
|
|
192
|
+
css: "text/css",
|
|
193
|
+
wasm: "application/wasm",
|
|
194
|
+
pdf: "application/pdf",
|
|
195
|
+
// images
|
|
196
|
+
png: "image/png",
|
|
197
|
+
jpg: "image/jpeg",
|
|
198
|
+
jpeg: "image/jpeg",
|
|
199
|
+
gif: "image/gif",
|
|
200
|
+
webp: "image/webp",
|
|
201
|
+
avif: "image/avif",
|
|
202
|
+
svg: "image/svg+xml",
|
|
203
|
+
ico: "image/x-icon",
|
|
204
|
+
bmp: "image/bmp",
|
|
205
|
+
// fonts
|
|
206
|
+
woff: "font/woff",
|
|
207
|
+
woff2: "font/woff2",
|
|
208
|
+
ttf: "font/ttf",
|
|
209
|
+
otf: "font/otf",
|
|
210
|
+
eot: "application/vnd.ms-fontobject",
|
|
211
|
+
// media
|
|
212
|
+
mp3: "audio/mpeg",
|
|
213
|
+
wav: "audio/wav",
|
|
214
|
+
ogg: "audio/ogg",
|
|
215
|
+
mp4: "video/mp4",
|
|
216
|
+
webm: "video/webm",
|
|
217
|
+
// app manifests
|
|
218
|
+
webmanifest: "application/manifest+json",
|
|
219
|
+
};
|
|
220
|
+
|
|
120
221
|
const getContentType = (name: string) => {
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
if (name.endsWith(".json")) return "application/json";
|
|
125
|
-
if (name.endsWith(".js") || name.endsWith(".mjs")) {
|
|
126
|
-
// Browsers only accept JavaScript module scripts when the MIME type is a
|
|
127
|
-
// "JavaScript MIME type" (e.g. text/javascript). application/javascript+module
|
|
128
|
-
// is not valid and causes strict module loading to fail.
|
|
129
|
-
return "text/javascript; charset=utf-8";
|
|
130
|
-
}
|
|
131
|
-
if (name.endsWith(".css")) return "text/css";
|
|
132
|
-
if (name.endsWith(".wasm")) return "application/wasm";
|
|
133
|
-
if (name.endsWith(".png")) return "image/png";
|
|
134
|
-
if (name.endsWith(".svg")) return "image/svg+xml";
|
|
135
|
-
if (name.endsWith(".ico")) return "image/x-icon";
|
|
136
|
-
return "application/octet-stream";
|
|
222
|
+
const dot = name.lastIndexOf(".");
|
|
223
|
+
const ext = dot === -1 ? "" : name.slice(dot + 1).toLowerCase();
|
|
224
|
+
return contentTypesByExtension[ext] ?? "application/octet-stream";
|
|
137
225
|
};
|
|
138
226
|
|
|
139
227
|
const maybeReadString = Effect.fn(function* (file: string) {
|
|
@@ -254,7 +342,21 @@ export const readAssets = Effect.fn(function* ({
|
|
|
254
342
|
size,
|
|
255
343
|
});
|
|
256
344
|
}
|
|
345
|
+
// Hash content + extension (matching wrangler): the upload API stores
|
|
346
|
+
// one blob + content type per hash, so two identical bodies under
|
|
347
|
+
// different extensions must not collapse into a single entry — the
|
|
348
|
+
// second file would serve with the first file's content type.
|
|
349
|
+
const extension = name.slice(name.lastIndexOf(".") + 1).toLowerCase();
|
|
257
350
|
const hash = yield* fs.readFile(file).pipe(
|
|
351
|
+
Effect.flatMap((content) =>
|
|
352
|
+
Effect.sync(() => {
|
|
353
|
+
const extBytes = new TextEncoder().encode(extension);
|
|
354
|
+
const hashed = new Uint8Array(content.length + extBytes.length);
|
|
355
|
+
hashed.set(content);
|
|
356
|
+
hashed.set(extBytes, content.length);
|
|
357
|
+
return hashed;
|
|
358
|
+
}),
|
|
359
|
+
),
|
|
258
360
|
Effect.flatMap(sha256),
|
|
259
361
|
Effect.map((hash) => hash.slice(0, 32)),
|
|
260
362
|
);
|
|
@@ -8,9 +8,9 @@ import {
|
|
|
8
8
|
type DurableObjectNamespace as RuntimeDurableObject,
|
|
9
9
|
type QueueConsumer as RuntimeQueueConsumer,
|
|
10
10
|
type Workflow as RuntimeWorkflow,
|
|
11
|
-
} from "@
|
|
12
|
-
import type { ContainerImage } from "@
|
|
13
|
-
import * as WorkerProxy from "@
|
|
11
|
+
} from "@alchemy.run/cloudflare-runtime/core";
|
|
12
|
+
import type { ContainerImage } from "@alchemy.run/cloudflare-runtime/core/Docker";
|
|
13
|
+
import * as WorkerProxy from "@alchemy.run/cloudflare-runtime/core/proxy/WorkerProxy";
|
|
14
14
|
import * as Cause from "effect/Cause";
|
|
15
15
|
import * as Effect from "effect/Effect";
|
|
16
16
|
import * as Equal from "effect/Equal";
|
|
@@ -36,6 +36,7 @@ import {
|
|
|
36
36
|
LocalRuntimeState,
|
|
37
37
|
localStorageDirectory,
|
|
38
38
|
} from "../LocalRuntime.ts";
|
|
39
|
+
import type { ConsumerSettings } from "../Queues/Consumer.ts";
|
|
39
40
|
import type { WorkerAssetsConfig, WorkerProps } from "../Workers/Worker.ts";
|
|
40
41
|
import { readAssetsConfigFiles } from "./Assets.ts";
|
|
41
42
|
import { getCompatibility } from "./Compatibility.ts";
|
|
@@ -126,6 +127,25 @@ export const LocalWorkerProvider = () =>
|
|
|
126
127
|
}
|
|
127
128
|
>();
|
|
128
129
|
|
|
130
|
+
// ConsumerSettings speaks the Cloudflare API's dialect (batchSize,
|
|
131
|
+
// maxWaitTimeMs in milliseconds); the runtime's QueueConsumer speaks
|
|
132
|
+
// wrangler's (maxBatchSize, maxBatchTimeout in seconds). Map
|
|
133
|
+
// explicitly — a spread silently drops the mismatched fields.
|
|
134
|
+
const toRuntimeConsumerSettings = (
|
|
135
|
+
settings: ConsumerSettings | undefined,
|
|
136
|
+
): Pick<
|
|
137
|
+
RuntimeQueueConsumer,
|
|
138
|
+
"maxBatchSize" | "maxBatchTimeout" | "maxRetries" | "retryDelay"
|
|
139
|
+
> => ({
|
|
140
|
+
maxBatchSize: settings?.batchSize,
|
|
141
|
+
maxBatchTimeout:
|
|
142
|
+
settings?.maxWaitTimeMs !== undefined
|
|
143
|
+
? settings.maxWaitTimeMs / 1000
|
|
144
|
+
: undefined,
|
|
145
|
+
maxRetries: settings?.maxRetries,
|
|
146
|
+
retryDelay: settings?.retryDelay,
|
|
147
|
+
});
|
|
148
|
+
|
|
129
149
|
const getQueueConsumers = Effect.fn(function* (scriptName: string) {
|
|
130
150
|
const consumers: RuntimeQueueConsumer[] = [];
|
|
131
151
|
for (const consumer of MutableHashMap.values(
|
|
@@ -146,7 +166,7 @@ export const LocalWorkerProvider = () =>
|
|
|
146
166
|
consumers.push({
|
|
147
167
|
queueName: consumer.queueName,
|
|
148
168
|
deadLetterQueue: consumer.deadLetterQueue,
|
|
149
|
-
...consumer.settings,
|
|
169
|
+
...toRuntimeConsumerSettings(consumer.settings),
|
|
150
170
|
pull: {
|
|
151
171
|
queueId: consumer.queueId,
|
|
152
172
|
accountId: consumer.accountId,
|
|
@@ -162,7 +182,7 @@ export const LocalWorkerProvider = () =>
|
|
|
162
182
|
consumers.push({
|
|
163
183
|
queueName: queue.queueName,
|
|
164
184
|
deadLetterQueue: consumer.deadLetterQueue,
|
|
165
|
-
...consumer.settings,
|
|
185
|
+
...toRuntimeConsumerSettings(consumer.settings),
|
|
166
186
|
});
|
|
167
187
|
} else {
|
|
168
188
|
return yield* Effect.die(`Queue ${consumer.queueId} not found`);
|
|
@@ -675,24 +695,41 @@ export const LocalWorkerProvider = () =>
|
|
|
675
695
|
);
|
|
676
696
|
|
|
677
697
|
/**
|
|
678
|
-
* Restart a running worker with its latest bundle
|
|
679
|
-
* runtime wiring (queue consumers) is
|
|
680
|
-
* {@link LocalRuntimeState}. No-op if the worker hasn't
|
|
681
|
-
* the pending first serve will already observe the
|
|
698
|
+
* Restart a running worker with its latest bundle (or its latest Vite
|
|
699
|
+
* dev-server child) so start-time runtime wiring (queue consumers) is
|
|
700
|
+
* re-read from {@link LocalRuntimeState}. No-op if the worker hasn't
|
|
701
|
+
* served yet — the pending first serve will already observe the
|
|
702
|
+
* updated state.
|
|
682
703
|
*/
|
|
704
|
+
const logRestartFailure = (id: string) =>
|
|
705
|
+
Effect.catchCause((cause: Cause.Cause<unknown>) =>
|
|
706
|
+
Effect.logWarning(
|
|
707
|
+
`[${id}] Failed to restart local worker`,
|
|
708
|
+
Cause.squash(cause),
|
|
709
|
+
),
|
|
710
|
+
);
|
|
711
|
+
|
|
683
712
|
const restartWorker = (id: string) =>
|
|
684
713
|
Effect.suspend(() => {
|
|
685
714
|
const latest = latestServes.get(id);
|
|
686
|
-
if (
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
715
|
+
if (latest) {
|
|
716
|
+
return serveWith(latest.worker, latest.bundle, latest.proxy).pipe(
|
|
717
|
+
Effect.asVoid,
|
|
718
|
+
logRestartFailure(id),
|
|
719
|
+
);
|
|
720
|
+
}
|
|
721
|
+
const vite = latestViteServes.get(id);
|
|
722
|
+
if (vite) {
|
|
723
|
+
// A Vite boot is expensive, so skip the restart if the running
|
|
724
|
+
// child already serves the current wiring (the in-flight serve's
|
|
725
|
+
// re-check loop may have picked it up while this restart waited
|
|
726
|
+
// on the serve lock).
|
|
727
|
+
return serveVite(vite, { onlyIfConsumersChanged: true }).pipe(
|
|
728
|
+
Effect.asVoid,
|
|
729
|
+
logRestartFailure(id),
|
|
730
|
+
);
|
|
731
|
+
}
|
|
732
|
+
return Effect.void;
|
|
696
733
|
});
|
|
697
734
|
|
|
698
735
|
// Tear down the running workerd for a worker id, if any. Used when the
|
|
@@ -711,13 +748,15 @@ export const LocalWorkerProvider = () =>
|
|
|
711
748
|
// in-flight restart may still hold the semaphore when the instance
|
|
712
749
|
// is torn down, and a same-id re-create must serialize against it.
|
|
713
750
|
const dropServeState = (id: string) => {
|
|
714
|
-
const latest = latestServes.get(id);
|
|
751
|
+
const latest = latestServes.get(id) ?? latestViteServes.get(id);
|
|
715
752
|
if (latest) {
|
|
716
753
|
MutableHashMap.remove(
|
|
717
754
|
localRuntimeState.workerRestarts,
|
|
718
755
|
latest.worker.name,
|
|
719
756
|
);
|
|
720
757
|
latestServes.delete(id);
|
|
758
|
+
latestViteServes.delete(id);
|
|
759
|
+
servedViteConsumers.delete(id);
|
|
721
760
|
}
|
|
722
761
|
};
|
|
723
762
|
|
|
@@ -863,6 +902,165 @@ export const LocalWorkerProvider = () =>
|
|
|
863
902
|
return proxy.url;
|
|
864
903
|
});
|
|
865
904
|
|
|
905
|
+
/** Everything needed to serve (or re-serve) a Vite dev-server child. */
|
|
906
|
+
interface ViteServeArgs {
|
|
907
|
+
worker: RunnableWorkerConfig;
|
|
908
|
+
rootDir: string | undefined;
|
|
909
|
+
invalidate: Effect.Effect<void>;
|
|
910
|
+
source: NonNullable<ViteChildConfig["source"]> | undefined;
|
|
911
|
+
proxy: WorkerProxy.WorkerProxyInstance;
|
|
912
|
+
}
|
|
913
|
+
|
|
914
|
+
/** The Vite analogue of `latestServes`: everything needed to restart
|
|
915
|
+
* the dev-server child when a sibling `Consumer` reconcile changes the
|
|
916
|
+
* queue-consumer wiring (see `workerRestarts`). */
|
|
917
|
+
const latestViteServes = new Map<string, ViteServeArgs>();
|
|
918
|
+
|
|
919
|
+
/** The queue-consumer wiring (canonical JSON) each running Vite child
|
|
920
|
+
* was started with, for the restart path's changed-wiring check. */
|
|
921
|
+
const servedViteConsumers = new Map<string, string>();
|
|
922
|
+
|
|
923
|
+
// Serve a Vite dev-server child with the same two guarantees
|
|
924
|
+
// `serveWith` gives a plain worker: a `workerRestarts` hook so sibling
|
|
925
|
+
// `Consumer` reconciles can restart the child with fresh queue-consumer
|
|
926
|
+
// wiring, and a post-start re-check so wiring that lands while the
|
|
927
|
+
// child is starting is not lost. Unlike `serveWith` this is
|
|
928
|
+
// break-before-make — two Vite dev servers rooted at the same app
|
|
929
|
+
// would race file watchers and Durable Object storage — so the proxy
|
|
930
|
+
// queues requests across the gap. The child's scope is forked from
|
|
931
|
+
// `rootScope` and tracked in `workerdScopes`, so it survives instance
|
|
932
|
+
// restarts and is reclaimed by `stop`/handoff/`serveWith` like any
|
|
933
|
+
// other running instance.
|
|
934
|
+
const serveVite = (
|
|
935
|
+
args: ViteServeArgs,
|
|
936
|
+
options?: { onlyIfConsumersChanged?: boolean },
|
|
937
|
+
) =>
|
|
938
|
+
Semaphore.withPermits(
|
|
939
|
+
serveLock(args.worker.id),
|
|
940
|
+
1,
|
|
941
|
+
)(
|
|
942
|
+
// The bookkeeping around `startViteChild` must not be torn in half
|
|
943
|
+
// by an interrupt: once a replacement child is up it must be
|
|
944
|
+
// recorded in `workerdScopes`, or it would leak until provider
|
|
945
|
+
// shutdown while holding the worker's registry key.
|
|
946
|
+
Effect.uninterruptibleMask((restore) =>
|
|
947
|
+
Effect.gen(function* () {
|
|
948
|
+
const { worker, rootDir, invalidate, source, proxy } = args;
|
|
949
|
+
if (options?.onlyIfConsumersChanged) {
|
|
950
|
+
const current = yield* getQueueConsumers(worker.name);
|
|
951
|
+
if (
|
|
952
|
+
workerdScopes.has(worker.id) &&
|
|
953
|
+
JSON.stringify(current) === servedViteConsumers.get(worker.id)
|
|
954
|
+
) {
|
|
955
|
+
return;
|
|
956
|
+
}
|
|
957
|
+
}
|
|
958
|
+
// Queue requests while the child is (re)starting.
|
|
959
|
+
yield* proxy.unset().pipe(Effect.forkChild);
|
|
960
|
+
// The dev server and its workerd run in a child process rooted
|
|
961
|
+
// at the app.
|
|
962
|
+
const root = path.resolve(rootDir ?? process.cwd());
|
|
963
|
+
const { accountId } = yield* cloudflareEnv;
|
|
964
|
+
// Queue-consumer wiring can change while the child is starting
|
|
965
|
+
// (a sibling `Consumer` reconcile), before the restart hook
|
|
966
|
+
// below exists to pick it up. We hold the serve lock, so a
|
|
967
|
+
// restart would deadlock — instead, loop and serve again until
|
|
968
|
+
// the wiring is stable across a start.
|
|
969
|
+
while (true) {
|
|
970
|
+
const queueConsumers = yield* getQueueConsumers(worker.name);
|
|
971
|
+
// Break-before-make: tear the previous child down before
|
|
972
|
+
// starting its replacement (also covers a superseded child
|
|
973
|
+
// from the previous loop iteration).
|
|
974
|
+
yield* closeWorkerd(worker.id);
|
|
975
|
+
const scope = yield* Scope.fork(rootScope);
|
|
976
|
+
const child = yield* restore(
|
|
977
|
+
startViteChild(
|
|
978
|
+
{
|
|
979
|
+
rootDir: root,
|
|
980
|
+
publicUrl: proxy.url.toString().replace(/\/$/, ""),
|
|
981
|
+
accountId,
|
|
982
|
+
storageDirectory,
|
|
983
|
+
stack: { name: stack.name, stage: stack.stage },
|
|
984
|
+
// Already resolved to plain values by `start`
|
|
985
|
+
// (`Worker.URL` sentinels substituted); Redacted
|
|
986
|
+
// unwraps at the process boundary inside
|
|
987
|
+
// `startViteChild`.
|
|
988
|
+
env: worker.env ?? {},
|
|
989
|
+
source,
|
|
990
|
+
worker: {
|
|
991
|
+
name: worker.name,
|
|
992
|
+
compatibility: worker.compatibility,
|
|
993
|
+
main: worker.viteMain,
|
|
994
|
+
viteEnvironments: worker.viteEnvironments,
|
|
995
|
+
hasAssets: worker.hasAssets,
|
|
996
|
+
bindingDescriptors: worker.bindingDescriptors,
|
|
997
|
+
devRemote: worker.devRemote,
|
|
998
|
+
durableObjectNamespaces: worker.durableObjectNamespaces,
|
|
999
|
+
workflows: worker.workflows,
|
|
1000
|
+
hyperdrives: worker.hyperdrives,
|
|
1001
|
+
queueConsumers,
|
|
1002
|
+
assets: yield* toRuntimeAssets(worker.assets),
|
|
1003
|
+
},
|
|
1004
|
+
},
|
|
1005
|
+
(channel, line) => {
|
|
1006
|
+
process[channel].write(`${worker.id} | ${line}\n`);
|
|
1007
|
+
},
|
|
1008
|
+
).pipe(Scope.provide(scope)),
|
|
1009
|
+
).pipe(
|
|
1010
|
+
// The scope hangs off `rootScope`, so a failed or
|
|
1011
|
+
// interrupted start must close it here — nothing else owns
|
|
1012
|
+
// it yet.
|
|
1013
|
+
Effect.onExit((exit) =>
|
|
1014
|
+
exit._tag === "Failure"
|
|
1015
|
+
? Scope.close(scope, exit)
|
|
1016
|
+
: Effect.void,
|
|
1017
|
+
),
|
|
1018
|
+
);
|
|
1019
|
+
workerdScopes.set(worker.id, scope);
|
|
1020
|
+
latestViteServes.set(worker.id, args);
|
|
1021
|
+
// Unexpected child death: log, park the proxy, and mark the
|
|
1022
|
+
// instance for update on the next plan. Forked into the
|
|
1023
|
+
// child's scope so a deliberate restart or teardown
|
|
1024
|
+
// interrupts the watcher before the process is killed.
|
|
1025
|
+
yield* child.exitCode.pipe(
|
|
1026
|
+
Effect.flatMap((exitCode) =>
|
|
1027
|
+
Effect.logWarning(
|
|
1028
|
+
`[${worker.id}] Dev server child exited unexpectedly with code ${exitCode}`,
|
|
1029
|
+
),
|
|
1030
|
+
),
|
|
1031
|
+
Effect.andThen(proxy.unset().pipe(Effect.ignore)),
|
|
1032
|
+
Effect.andThen(invalidate),
|
|
1033
|
+
Effect.forkIn(scope),
|
|
1034
|
+
);
|
|
1035
|
+
// Register the restart hook before the re-check below:
|
|
1036
|
+
// changes landing after the re-check find the hook; changes
|
|
1037
|
+
// before it are caught by the re-check. Nothing falls in
|
|
1038
|
+
// between.
|
|
1039
|
+
MutableHashMap.set(
|
|
1040
|
+
localRuntimeState.workerRestarts,
|
|
1041
|
+
worker.name,
|
|
1042
|
+
restartWorker(worker.id),
|
|
1043
|
+
);
|
|
1044
|
+
const currentConsumers = yield* getQueueConsumers(worker.name);
|
|
1045
|
+
if (
|
|
1046
|
+
JSON.stringify(currentConsumers) !==
|
|
1047
|
+
JSON.stringify(queueConsumers)
|
|
1048
|
+
) {
|
|
1049
|
+
// Wiring changed while the child was starting — serve
|
|
1050
|
+
// again with the fresh consumers before exposing it.
|
|
1051
|
+
continue;
|
|
1052
|
+
}
|
|
1053
|
+
servedViteConsumers.set(
|
|
1054
|
+
worker.id,
|
|
1055
|
+
JSON.stringify(queueConsumers),
|
|
1056
|
+
);
|
|
1057
|
+
yield* proxy.set(child.url);
|
|
1058
|
+
return;
|
|
1059
|
+
}
|
|
1060
|
+
}),
|
|
1061
|
+
),
|
|
1062
|
+
);
|
|
1063
|
+
|
|
866
1064
|
const runVite = Effect.fn(function* (
|
|
867
1065
|
worker: RunnableWorkerConfig,
|
|
868
1066
|
rootDir: string | undefined,
|
|
@@ -870,53 +1068,7 @@ export const LocalWorkerProvider = () =>
|
|
|
870
1068
|
source?: NonNullable<ViteChildConfig["source"]>,
|
|
871
1069
|
) {
|
|
872
1070
|
const proxy = yield* maybeStartProxy(worker.id, worker.dev);
|
|
873
|
-
yield* proxy
|
|
874
|
-
// The dev server and its workerd run in a child process rooted at
|
|
875
|
-
// the app.
|
|
876
|
-
const root = path.resolve(rootDir ?? process.cwd());
|
|
877
|
-
const { accountId } = yield* cloudflareEnv;
|
|
878
|
-
const child = yield* startViteChild(
|
|
879
|
-
{
|
|
880
|
-
rootDir: root,
|
|
881
|
-
publicUrl: proxy.url.toString().replace(/\/$/, ""),
|
|
882
|
-
accountId,
|
|
883
|
-
storageDirectory,
|
|
884
|
-
stack: { name: stack.name, stage: stack.stage },
|
|
885
|
-
// Already resolved to plain values by `start` (`Worker.URL`
|
|
886
|
-
// sentinels substituted); Redacted unwraps at the process
|
|
887
|
-
// boundary inside `startViteChild`.
|
|
888
|
-
env: worker.env ?? {},
|
|
889
|
-
source,
|
|
890
|
-
worker: {
|
|
891
|
-
name: worker.name,
|
|
892
|
-
compatibility: worker.compatibility,
|
|
893
|
-
main: worker.viteMain,
|
|
894
|
-
viteEnvironments: worker.viteEnvironments,
|
|
895
|
-
hasAssets: worker.hasAssets,
|
|
896
|
-
bindingDescriptors: worker.bindingDescriptors,
|
|
897
|
-
devRemote: worker.devRemote,
|
|
898
|
-
durableObjectNamespaces: worker.durableObjectNamespaces,
|
|
899
|
-
workflows: worker.workflows,
|
|
900
|
-
hyperdrives: worker.hyperdrives,
|
|
901
|
-
queueConsumers: yield* getQueueConsumers(worker.name),
|
|
902
|
-
assets: yield* toRuntimeAssets(worker.assets),
|
|
903
|
-
},
|
|
904
|
-
},
|
|
905
|
-
(channel, line) => {
|
|
906
|
-
process[channel].write(`${worker.id} | ${line}\n`);
|
|
907
|
-
},
|
|
908
|
-
);
|
|
909
|
-
yield* proxy.set(child.url);
|
|
910
|
-
yield* child.exitCode.pipe(
|
|
911
|
-
Effect.flatMap((exitCode) =>
|
|
912
|
-
Effect.logWarning(
|
|
913
|
-
`[${worker.id}] Dev server child exited unexpectedly with code ${exitCode}`,
|
|
914
|
-
),
|
|
915
|
-
),
|
|
916
|
-
Effect.andThen(proxy.unset().pipe(Effect.ignore)),
|
|
917
|
-
Effect.andThen(invalidate),
|
|
918
|
-
Effect.forkScoped,
|
|
919
|
-
);
|
|
1071
|
+
yield* serveVite({ worker, rootDir, invalidate, source, proxy });
|
|
920
1072
|
return proxy.url;
|
|
921
1073
|
});
|
|
922
1074
|
|
|
@@ -1192,20 +1344,15 @@ const toRuntimeAssets = Effect.fn(function* (
|
|
|
1192
1344
|
directory: assets.directory,
|
|
1193
1345
|
headers: assets.headers ?? files._headers,
|
|
1194
1346
|
redirects: assets.redirects ?? files._redirects,
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
| "none"
|
|
1205
|
-
| "404-page"
|
|
1206
|
-
| "single-page-application"
|
|
1207
|
-
| undefined,
|
|
1208
|
-
runWorkerFirst: assets.runWorkerFirst,
|
|
1347
|
+
htmlHandling: assets.htmlHandling,
|
|
1348
|
+
notFoundHandling: assets.notFoundHandling,
|
|
1349
|
+
// The deployed default is assets-first (`run_worker_first` omitted =
|
|
1350
|
+
// false on the cloud API), but the runtime's router inverts it — it
|
|
1351
|
+
// treats anything `!== false` (including `undefined`) as worker-first.
|
|
1352
|
+
// Pin the cloud default explicitly so a Worker with an assets directory
|
|
1353
|
+
// and a `main` serves asset paths from the asset layer locally exactly
|
|
1354
|
+
// like it does deployed.
|
|
1355
|
+
runWorkerFirst: assets.runWorkerFirst ?? false,
|
|
1209
1356
|
serveDirectly: assets.serveDirectly,
|
|
1210
1357
|
};
|
|
1211
1358
|
});
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type {
|
|
2
2
|
BindingHook,
|
|
3
3
|
BindingServices,
|
|
4
|
-
} from "@
|
|
4
|
+
} from "@alchemy.run/cloudflare-runtime/core";
|
|
5
5
|
import {
|
|
6
6
|
Ai,
|
|
7
7
|
AiSearch,
|
|
@@ -35,14 +35,14 @@ import {
|
|
|
35
35
|
WasmModule,
|
|
36
36
|
WorkerLoader,
|
|
37
37
|
Workflows,
|
|
38
|
-
} from "@
|
|
38
|
+
} from "@alchemy.run/cloudflare-runtime/core/bindings";
|
|
39
39
|
import * as Effect from "effect/Effect";
|
|
40
40
|
import * as Redacted from "effect/Redacted";
|
|
41
41
|
import * as Schema from "effect/Schema";
|
|
42
42
|
import { isLocalId } from "../LocalRuntime.ts";
|
|
43
43
|
import type { WorkerBinding } from "./WorkerBinding.ts";
|
|
44
44
|
|
|
45
|
-
export class WorkerValidationError extends Schema.
|
|
45
|
+
export class WorkerValidationError extends Schema.TaggedError<WorkerValidationError>()(
|
|
46
46
|
"WorkerValidationError",
|
|
47
47
|
{
|
|
48
48
|
message: Schema.String,
|
|
@@ -6,7 +6,7 @@ import type {
|
|
|
6
6
|
DurableObjectNamespace as RuntimeDurableObject,
|
|
7
7
|
QueueConsumer as RuntimeQueueConsumer,
|
|
8
8
|
RuntimeServices,
|
|
9
|
-
} from "@
|
|
9
|
+
} from "@alchemy.run/cloudflare-runtime/core";
|
|
10
10
|
import type * as Context from "effect/Context";
|
|
11
11
|
import * as Data from "effect/Data";
|
|
12
12
|
import * as Effect from "effect/Effect";
|
|
@@ -360,7 +360,7 @@ export const resolveSource = (
|
|
|
360
360
|
}
|
|
361
361
|
if (props.vite) {
|
|
362
362
|
// Loaded lazily: `./Sources/Vite.ts` pulls in
|
|
363
|
-
// `@
|
|
363
|
+
// `@alchemy.run/cloudflare-runtime/vite` (~0.5s), which is only
|
|
364
364
|
// needed for vite-based workers — not for every Worker resolution.
|
|
365
365
|
const vite = props.vite;
|
|
366
366
|
return Effect.promise(() => import("./Sources/Vite.ts")).pipe(
|
|
@@ -61,10 +61,9 @@ export interface WorkerBundleOptions {
|
|
|
61
61
|
* Rebuild any `builtin:esm-external-require` plugin instance with OUR copy of
|
|
62
62
|
* rolldown.
|
|
63
63
|
*
|
|
64
|
-
*
|
|
65
|
-
* under bun's `bun` export condition `@distilled.cloud/cloudflare-rolldown-plugin`
|
|
64
|
+
* A separately installed or bundled `@alchemy.run/cloudflare-runtime/rolldown`
|
|
66
65
|
* can resolve a physically different copy of rolldown than the one Alchemy
|
|
67
|
-
*
|
|
66
|
+
* invokes. Builtin plugins — here `builtin:esm-external-require`, which
|
|
68
67
|
* rewrites CJS `require`s of Node builtins into ESM imports under
|
|
69
68
|
* `nodejs_compat` — are `BuiltinPlugin` class instances that rolldown
|
|
70
69
|
* recognizes with an `instanceof` check. An instance constructed by the
|
|
@@ -105,7 +104,7 @@ export const WorkerBundle = Effect.gen(function* () {
|
|
|
105
104
|
const [{ default: cloudflareRolldown }, { esmExternalRequirePlugin }] =
|
|
106
105
|
yield* Effect.promise(() =>
|
|
107
106
|
Promise.all([
|
|
108
|
-
import("@
|
|
107
|
+
import("@alchemy.run/cloudflare-runtime/rolldown"),
|
|
109
108
|
import("rolldown/plugins"),
|
|
110
109
|
]),
|
|
111
110
|
);
|