@astrale-os/adapter-cloudflare 0.5.0-beta.18 → 0.5.0-beta.181

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.
Files changed (248) hide show
  1. package/README.md +230 -2
  2. package/dist/adapter.d.ts +11 -0
  3. package/dist/adapter.js +54 -0
  4. package/dist/build/bundle/admit.d.ts +3 -0
  5. package/dist/build/bundle/admit.js +46 -0
  6. package/dist/build/bundle/compiled-wasm-loader.d.ts +8 -0
  7. package/dist/build/bundle/compiled-wasm-loader.js +21 -0
  8. package/dist/build/bundler.d.ts +21 -0
  9. package/dist/build/bundler.js +96 -0
  10. package/dist/build/closure.d.ts +2 -0
  11. package/dist/build/closure.js +22 -0
  12. package/dist/build/codegen/execution.d.ts +3 -0
  13. package/dist/build/codegen/execution.js +2 -0
  14. package/dist/build/codegen/merge.d.ts +0 -1
  15. package/dist/build/codegen/merge.js +0 -1
  16. package/dist/build/codegen/wrangler.d.ts +32 -6
  17. package/dist/build/codegen/wrangler.js +77 -21
  18. package/dist/build/configuration/invocation-timeout.d.ts +2 -0
  19. package/dist/build/configuration/invocation-timeout.js +9 -0
  20. package/dist/build/configuration/request-limit.d.ts +2 -0
  21. package/dist/build/configuration/request-limit.js +9 -0
  22. package/dist/build/configuration/router.d.ts +7 -0
  23. package/dist/build/configuration/router.js +17 -0
  24. package/dist/build/configuration/settings.d.ts +6 -0
  25. package/dist/build/configuration/settings.js +40 -0
  26. package/dist/build/configuration.d.ts +4 -0
  27. package/dist/build/configuration.js +4 -0
  28. package/dist/build/frontend/files.d.ts +19 -0
  29. package/dist/build/frontend/files.js +99 -0
  30. package/dist/build/frontend/readiness.d.ts +16 -0
  31. package/dist/build/frontend/readiness.js +21 -0
  32. package/dist/build/frontend/revision.d.ts +5 -0
  33. package/dist/build/frontend/revision.js +14 -0
  34. package/dist/build/frontend/vite.d.ts +14 -0
  35. package/dist/build/frontend/vite.js +42 -0
  36. package/dist/build/frontend/vite.process.d.ts +7 -0
  37. package/dist/build/frontend/vite.process.js +65 -0
  38. package/dist/build/frontend/vite.runner.d.ts +1 -0
  39. package/dist/build/frontend/vite.runner.js +155 -0
  40. package/dist/build/index.d.ts +12 -16
  41. package/dist/build/index.js +12 -16
  42. package/dist/build/material.d.ts +10 -0
  43. package/dist/build/material.js +25 -0
  44. package/dist/build/metafile.d.ts +5 -0
  45. package/dist/build/metafile.js +14 -0
  46. package/dist/build/qualification.d.ts +5 -0
  47. package/dist/build/qualification.js +7 -0
  48. package/dist/build/roots.d.ts +2 -0
  49. package/dist/build/roots.js +34 -0
  50. package/dist/build/worker/codegen/entry.d.ts +10 -0
  51. package/dist/build/worker/codegen/entry.js +65 -0
  52. package/dist/build/worker/codegen/literal.d.ts +28 -0
  53. package/dist/build/worker/codegen/literal.js +136 -0
  54. package/dist/build/worker/codegen/service.d.ts +14 -0
  55. package/dist/build/worker/codegen/service.js +56 -0
  56. package/dist/build/worker/execution.prepare.d.ts +20 -0
  57. package/dist/build/worker/execution.prepare.js +129 -0
  58. package/dist/build/worker/media-type.d.ts +1 -0
  59. package/dist/build/worker/media-type.js +20 -0
  60. package/dist/build/worker/modules.d.ts +20 -0
  61. package/dist/build/worker/modules.js +32 -0
  62. package/dist/build/worker/specifier.d.ts +5 -0
  63. package/dist/build/worker/specifier.js +15 -0
  64. package/dist/build/worker/upload.d.ts +23 -0
  65. package/dist/build/worker/upload.js +42 -0
  66. package/dist/cloudflare.d.ts +1 -45
  67. package/dist/cloudflare.js +1 -202
  68. package/dist/hosting/activation.d.ts +38 -0
  69. package/dist/hosting/activation.js +109 -0
  70. package/dist/hosting/assets.d.ts +14 -0
  71. package/dist/hosting/assets.js +53 -0
  72. package/dist/hosting/bounded.d.ts +10 -0
  73. package/dist/hosting/bounded.js +32 -0
  74. package/dist/hosting/bytes.d.ts +6 -0
  75. package/dist/hosting/bytes.js +25 -0
  76. package/dist/hosting/client.d.ts +144 -0
  77. package/dist/hosting/client.js +491 -0
  78. package/dist/hosting/dispatcher/cron.d.mts +10 -0
  79. package/dist/hosting/dispatcher/cron.mjs +135 -0
  80. package/dist/hosting/dispatcher/deployments.d.mts +26 -0
  81. package/dist/hosting/dispatcher/deployments.mjs +158 -0
  82. package/dist/hosting/dispatcher/dispatcher.d.mts +17 -0
  83. package/dist/hosting/dispatcher/dispatcher.mjs +76 -0
  84. package/dist/hosting/dispatcher/env.d.mts +51 -0
  85. package/dist/hosting/dispatcher/failure.d.mts +4 -0
  86. package/dist/hosting/dispatcher/failure.mjs +15 -0
  87. package/dist/hosting/dispatcher/index.d.mts +4 -0
  88. package/dist/hosting/dispatcher/index.mjs +8 -0
  89. package/dist/hosting/dispatcher/modules.d.ts +24 -0
  90. package/dist/hosting/dispatcher/modules.js +55 -0
  91. package/dist/hosting/dispatcher/services.d.mts +23 -0
  92. package/dist/hosting/dispatcher/services.mjs +202 -0
  93. package/dist/hosting/identity.d.ts +15 -0
  94. package/dist/hosting/identity.js +36 -0
  95. package/dist/hosting/index.d.ts +34 -0
  96. package/dist/hosting/index.js +32 -0
  97. package/dist/hosting/kv.d.ts +90 -0
  98. package/dist/hosting/kv.js +207 -0
  99. package/dist/hosting/listing.d.ts +34 -0
  100. package/dist/hosting/listing.js +50 -0
  101. package/dist/hosting/names.d.ts +16 -0
  102. package/dist/hosting/names.js +28 -0
  103. package/dist/hosting/provision/account.d.ts +11 -0
  104. package/dist/hosting/provision/account.js +86 -0
  105. package/dist/hosting/provision/dispatcher.d.ts +42 -0
  106. package/dist/hosting/provision/dispatcher.js +99 -0
  107. package/dist/hosting/provision/ingress.d.ts +12 -0
  108. package/dist/hosting/provision/ingress.js +31 -0
  109. package/dist/hosting/provision/plan.d.ts +143 -0
  110. package/dist/hosting/provision/plan.js +246 -0
  111. package/dist/hosting/provision/routing.d.ts +82 -0
  112. package/dist/hosting/provision/routing.js +226 -0
  113. package/dist/hosting/readiness.d.ts +53 -0
  114. package/dist/hosting/readiness.js +82 -0
  115. package/dist/hosting/refusal.d.ts +28 -0
  116. package/dist/hosting/refusal.js +13 -0
  117. package/dist/hosting/retirement.d.ts +70 -0
  118. package/dist/hosting/retirement.js +107 -0
  119. package/dist/hosting/retry-after.d.ts +6 -0
  120. package/dist/hosting/retry-after.js +55 -0
  121. package/dist/hosting/script.d.ts +186 -0
  122. package/dist/hosting/script.js +324 -0
  123. package/dist/hosting/testing/fake-cloudflare.d.ts +212 -0
  124. package/dist/hosting/testing/fake-cloudflare.js +757 -0
  125. package/dist/hosting/testing/index.d.ts +6 -0
  126. package/dist/hosting/testing/index.js +6 -0
  127. package/dist/hosting/time.d.ts +4 -0
  128. package/dist/hosting/time.js +20 -0
  129. package/dist/identity/binding.d.ts +2 -0
  130. package/dist/identity/binding.js +2 -0
  131. package/dist/identity/material.d.ts +6 -0
  132. package/dist/identity/material.js +29 -0
  133. package/dist/index.d.ts +14 -13
  134. package/dist/index.js +13 -12
  135. package/dist/namespace/configure.d.ts +22 -0
  136. package/dist/namespace/configure.js +199 -0
  137. package/dist/namespace/coordinates.d.ts +15 -0
  138. package/dist/namespace/coordinates.js +49 -0
  139. package/dist/namespace/deploy-release.d.ts +53 -0
  140. package/dist/namespace/deploy-release.js +389 -0
  141. package/dist/namespace/hosting.d.ts +29 -0
  142. package/dist/namespace/hosting.js +120 -0
  143. package/dist/namespace/index.d.ts +12 -0
  144. package/dist/namespace/index.js +12 -0
  145. package/dist/namespace/list.d.ts +18 -0
  146. package/dist/namespace/list.js +63 -0
  147. package/dist/namespace/readiness.d.ts +30 -0
  148. package/dist/namespace/readiness.js +31 -0
  149. package/dist/namespace/record.d.ts +21 -0
  150. package/dist/namespace/record.js +53 -0
  151. package/dist/params.d.ts +59 -66
  152. package/dist/params.js +0 -1
  153. package/dist/release/build.d.ts +35 -0
  154. package/dist/release/build.js +44 -0
  155. package/dist/release/deployment.d.ts +44 -0
  156. package/dist/release/deployment.js +141 -0
  157. package/dist/release/index.d.ts +2 -0
  158. package/dist/release/index.js +2 -0
  159. package/dist/worker/build-digest.d.ts +10 -0
  160. package/dist/worker/build-digest.js +22 -0
  161. package/dist/worker/durable.d.ts +3 -0
  162. package/dist/worker/durable.js +5 -0
  163. package/dist/worker/entry.d.ts +41 -0
  164. package/dist/worker/entry.js +128 -0
  165. package/dist/worker/fetch.d.ts +0 -1
  166. package/dist/worker/fetch.js +0 -1
  167. package/dist/worker/front.d.ts +55 -0
  168. package/dist/worker/front.js +59 -0
  169. package/dist/worker/frontend.d.ts +4 -0
  170. package/dist/worker/frontend.js +83 -0
  171. package/dist/worker/identity.d.ts +7 -0
  172. package/dist/worker/identity.js +23 -0
  173. package/dist/worker/index.d.ts +5 -61
  174. package/dist/worker/index.js +5 -221
  175. package/dist/worker/restate.d.ts +6 -0
  176. package/dist/worker/restate.js +6 -0
  177. package/dist/worker/settings.d.ts +47 -0
  178. package/dist/worker/settings.js +161 -0
  179. package/dist/wrangler/bundle.d.ts +10 -0
  180. package/dist/wrangler/bundle.js +27 -0
  181. package/dist/wrangler/index.d.ts +3 -0
  182. package/dist/wrangler/index.js +3 -0
  183. package/dist/wrangler/process.d.ts +15 -0
  184. package/dist/wrangler/process.js +102 -0
  185. package/dist/wrangler/type-generation.d.ts +6 -0
  186. package/dist/wrangler/type-generation.js +19 -0
  187. package/package.json +45 -20
  188. package/template/astrale.config.ts +43 -29
  189. package/dist/build/codegen/identity.d.ts +0 -10
  190. package/dist/build/codegen/identity.d.ts.map +0 -1
  191. package/dist/build/codegen/identity.js +0 -32
  192. package/dist/build/codegen/identity.js.map +0 -1
  193. package/dist/build/codegen/merge.d.ts.map +0 -1
  194. package/dist/build/codegen/merge.js.map +0 -1
  195. package/dist/build/codegen/worker.d.ts +0 -12
  196. package/dist/build/codegen/worker.d.ts.map +0 -1
  197. package/dist/build/codegen/worker.js +0 -40
  198. package/dist/build/codegen/worker.js.map +0 -1
  199. package/dist/build/codegen/wrangler.d.ts.map +0 -1
  200. package/dist/build/codegen/wrangler.js.map +0 -1
  201. package/dist/build/frontend.d.ts +0 -27
  202. package/dist/build/frontend.d.ts.map +0 -1
  203. package/dist/build/frontend.js +0 -252
  204. package/dist/build/frontend.js.map +0 -1
  205. package/dist/build/index.d.ts.map +0 -1
  206. package/dist/build/index.js.map +0 -1
  207. package/dist/build/parse-output.d.ts +0 -27
  208. package/dist/build/parse-output.d.ts.map +0 -1
  209. package/dist/build/parse-output.js +0 -58
  210. package/dist/build/parse-output.js.map +0 -1
  211. package/dist/build/prepare.d.ts +0 -18
  212. package/dist/build/prepare.d.ts.map +0 -1
  213. package/dist/build/prepare.js +0 -138
  214. package/dist/build/prepare.js.map +0 -1
  215. package/dist/build/worker.d.ts +0 -15
  216. package/dist/build/worker.d.ts.map +0 -1
  217. package/dist/build/worker.js +0 -21
  218. package/dist/build/worker.js.map +0 -1
  219. package/dist/build/wrangler-cli.d.ts +0 -88
  220. package/dist/build/wrangler-cli.d.ts.map +0 -1
  221. package/dist/build/wrangler-cli.js +0 -283
  222. package/dist/build/wrangler-cli.js.map +0 -1
  223. package/dist/cloudflare.d.ts.map +0 -1
  224. package/dist/cloudflare.js.map +0 -1
  225. package/dist/index.d.ts.map +0 -1
  226. package/dist/index.js.map +0 -1
  227. package/dist/params.d.ts.map +0 -1
  228. package/dist/params.js.map +0 -1
  229. package/dist/worker/fetch.d.ts.map +0 -1
  230. package/dist/worker/fetch.js.map +0 -1
  231. package/dist/worker/index.d.ts.map +0 -1
  232. package/dist/worker/index.js.map +0 -1
  233. package/src/build/codegen/identity.ts +0 -40
  234. package/src/build/codegen/merge.ts +0 -92
  235. package/src/build/codegen/worker.ts +0 -53
  236. package/src/build/codegen/wrangler.ts +0 -128
  237. package/src/build/frontend.ts +0 -298
  238. package/src/build/index.ts +0 -29
  239. package/src/build/parse-output.ts +0 -60
  240. package/src/build/prepare.ts +0 -189
  241. package/src/build/worker.ts +0 -37
  242. package/src/build/wrangler-cli.ts +0 -372
  243. package/src/cloudflare.ts +0 -275
  244. package/src/index.ts +0 -21
  245. package/src/params.ts +0 -92
  246. package/src/worker/fetch.ts +0 -46
  247. package/src/worker/index.ts +0 -335
  248. package/src/worker/tsconfig.json +0 -10
package/README.md CHANGED
@@ -2,10 +2,238 @@
2
2
 
3
3
  Cloudflare Worker deployment adapter for Astrale Domains.
4
4
 
5
- During the SDK beta program, install the beta cohort explicitly:
5
+ During the SDK beta program, install the beta package set explicitly:
6
6
 
7
7
  ```bash
8
8
  npm install @astrale-os/sdk@beta @astrale-os/adapter-cloudflare@beta
9
9
  ```
10
10
 
11
- Bare installs return to stable releases when the cohort is promoted and npm `latest` advances.
11
+ Bare installs return to stable releases when the package set is promoted and npm `latest` advances.
12
+
13
+ One `cloudflare()` value configures one Project Environment in a Workers for Platforms dispatch
14
+ namespace. Each release becomes one immutable deployment on your own Cloudflare account or on a
15
+ platform's. A deploy never installs: install the URL it prints with
16
+ `astrale domain install <url> -i <instance>`.
17
+
18
+ Generated Worker modules are minified by default, including separately loaded runtime modules.
19
+ The Environment's `wrangler` overlay cannot change minification: every Environment of one source
20
+ must emit the same JavaScript bytes. `cloudflare({ wrangler: { minify: false } })` is rejected.
21
+
22
+ ## Host it yourself
23
+
24
+ Anyone with a Cloudflare account, Workers for Platforms and a domain of their own can host
25
+ immutable deployments, with no Astrale infrastructure:
26
+
27
+ 1. **A domain.** Add a zone to Cloudflare and pick a routing domain under it dedicated to the
28
+ deployments, such as `deploy.example.dev`: every deployment answers at
29
+ `https://<label>.deploy.example.dev`. Nothing else may serve a host at, under or above it, and
30
+ its wildcard name needs an edge certificate (Advanced Certificate Manager, or Total TLS).
31
+ 2. **A token.** Create an API token with Workers Scripts Edit, Workers KV Storage Edit, Workers
32
+ Routes Edit and Zone DNS Edit on that zone. Export it as `CLOUDFLARE_API_TOKEN`, with
33
+ `CLOUDFLARE_ACCOUNT_ID` (and `CLOUDFLARE_ZONE_ID` when the zone cannot be found from the domain).
34
+ 3. **The Environment.**
35
+
36
+ ```ts
37
+ production: {
38
+ deployment: cloudflare({
39
+ namespace: { name: 'my-deployments', routingDomain: 'deploy.example.dev' },
40
+ secrets: '.env.production',
41
+ }),
42
+ },
43
+ ```
44
+
45
+ 4. **Provision once.** `astrale-domain cloudflare plan production` reads the account and prints
46
+ what provisioning does and what blocks it; `astrale-domain cloudflare init production`
47
+ provisions it (both are commands this adapter declares; `--json` prints the result):
48
+ the dispatch namespace, its routing KV, the dispatcher Worker (`<name>-dispatcher`, or
49
+ `--dispatcher <worker>`), a proxied `AAAA 100::` record `*.<domain>` and the route
50
+ `*.<domain>/*` to the dispatcher, then checks that a never-deployed host reaches it over HTTPS.
51
+ It is idempotent: a rerun adopts what exists and uploads the dispatcher again.
52
+ 5. **Deploy.** `astrale-domain deploy production` prints the deployment URL, which
53
+ `astrale domain install` takes.
54
+
55
+ ## Namespace mode
56
+
57
+ `astrale-domain deploy <environment>` uploads one script named by the deployment label, create-only
58
+ (`If-None-Match: *`), which answers at `https://<label>.<routingDomain>` through the namespace's
59
+ dispatcher. Nothing is ever replaced in place: another build or configuration is another label.
60
+ Every line is readable. Namespace mode is a thin layer over the hosting kit below.
61
+
62
+ - **Credentials.** `CLOUDFLARE_API_TOKEN` must edit the namespace's scripts and the values of its
63
+ routing KV; the account is `namespace.account`, else `CLOUDFLARE_ACCOUNT_ID`. Neither is ever
64
+ written to the configuration.
65
+ - **Routing KV.** The deploy finds the namespace's routing KV by its title,
66
+ `astrale-deployment-routing-<first 16 bytes of sha256(name), in hexadecimal>`, which
67
+ provisioning creates. A namespace without it is refused before any effect. The names of
68
+ Services' deployments namespaces (`astrale-deployments-<hex>`) are refused: Services manages
69
+ their scripts.
70
+ - **Bindings.** Each new deployment binds `WORKER_URL`, `ASTRALE_BUILD_DIGEST`, `ASTRALE_SETTINGS`
71
+ (the router as `ROUTER`), the author's `vars`, the service and dispatch namespace bindings of
72
+ `wrangler`, the router, its version metadata, and as `secret_text` exactly the Environment's
73
+ secrets and `ASTRALE_SIGNING_IDENTITY`, a key generated for that deployment and kept nowhere
74
+ else. Its tags name its artifact (build digest), line and key; never `astrale-service`, which is
75
+ Services'.
76
+ - **Activation.** The deploy writes `record:<label>` with its media type metadata, whose presence
77
+ makes the dispatcher route the label: the canonical `DeploymentRecordV1`, published through the
78
+ kit's opaque record, which the dispatcher serves at `/.well-known/astrale/deployment.json`. It
79
+ never holds a provider version or a secret digest. Readiness then waits, bounded, until the URL serves the
80
+ sealed release from the provider version the upload created.
81
+ - **Reuse.** A redeploy of the same release finds the script under its label. It is reused only
82
+ when its artifact and line tags and its record name this build and configuration (only the
83
+ record's commit may differ: the deployment keeps the record it was first activated with), or,
84
+ when an interrupted deploy left it unactivated, when it binds exactly this configuration. Then only that
85
+ script's declared secrets are rewritten in place, and readiness waits for the version the
86
+ rewrite minted. Anything else is a `deployment-conflict`, refused with nothing written; no other
87
+ deployment is ever touched. A `summary:<label>` an older adapter wrote is ignored.
88
+ - **Retirement.** A label whose `retirement:<label>` the kit's `markRetired` wrote answers
89
+ `DEPLOYMENT_RETIRED` at the dispatcher and is refused by every later deploy. The namespace keeps
90
+ every deployment until then: there is no retention, preview expiry or `retain`.
91
+ - **Listing.** `astrale-domain list` lists the Environment's deployments from the routing KV and
92
+ the namespace, and writes nothing: one row per label of the Environment's line that
93
+ `record:<label>` activated or `retirement:<label>` withdrew, with its record as stored (a record
94
+ the SDK refuses is listed with `record: null` and the refusal), its script's creation instant and
95
+ key while the script exists, and the call target `{ kind: 'namespace', namespace, script }`. Its
96
+ state is `active`, `retiring` (tombstoned, script not deleted yet), `retired` (script deleted) or
97
+ `failed` (activated, script gone).
98
+ - **Refused.** A direct-mode parameter beside `namespace` (`route`, `workerName`, `identityIssuer`,
99
+ `addressing`, `signingIdentity`), a `router.binding` other than `ROUTER`, and any `wrangler` key
100
+ but `services`, `dispatch_namespaces` and `compatibility_flags`, `triggers` first: an immutable
101
+ deployment runs no cron of its own. A `dispatch_namespaces` entry is exactly
102
+ `{ binding, namespace }`; it is frozen into the configuration (`bindings.dispatchNamespaces`), so
103
+ into the label, bound at the create-only upload, and never names the namespace the deployment
104
+ lives in (AM-174). Which namespaces a deployment may bind is its host's to decide.
105
+ `durable` is frozen into the configuration (`settings.durableOptions`, AM-175), so into the
106
+ label, and bound in `ASTRALE_SETTINGS`: a durable run stays on the deployment that started it.
107
+
108
+ ## Hosting kit
109
+
110
+ `@astrale-os/adapter-cloudflare/hosting` is the one implementation of this hosting, for namespace
111
+ mode and for any other host that keeps its own routing beside it. Everything but provisioning runs in
112
+ Node and inside a Worker (`fetch` and WebCrypto only).
113
+
114
+ - **Client.** `CloudflareClient`: bounded bodies, `Retry-After`/429 waits by policy
115
+ (`DEFAULT_RATE_LIMIT`, `OPERATOR_RATE_LIMIT` or none), timeouts and a deadline, typed
116
+ `CloudflareApiError`s (`kind`, `status`, `codes`), cursor and numbered pagination, multipart
117
+ forms, raw KV text and bytes.
118
+ - **Routing KV.** `RoutingKv` (by title or id) and the contract: `record:<label>` (the deployment's
119
+ record, opaque bytes with their media type in the value's metadata, `{"contentType":...}`, or
120
+ `-` with `{"contentType":null}` for a deployment that publishes none; written once and kept only
121
+ for the same bytes and media type), `retirement:<label>` (`withdrawn`), `current:<name>` (one of
122
+ the name's labels), `cron:<name>` (canonical UTC crons). The record's metadata is mandatory: a
123
+ `record:<label>` without it activates nothing at the dispatcher (every path of the label answers
124
+ as not active yet, and no cron fires on it) and the kit refuses it (`record-invalid`) instead of
125
+ reading it as any record. Every write is read back before it counts.
126
+ - **Scripts.** `deploymentBindings`, `deploymentTags` (with a host's extra tags),
127
+ `uploadDeploymentScript` (create-only, every module kind, assets in parallel),
128
+ `observeScript`, `scriptSettings`, `scriptSecretNames`, `putScriptSecret`, `deleteScript`, and
129
+ `createSigningIdentity` (WebCrypto Ed25519).
130
+ - **Lifecycle.** `activateDeployment` (a label and its record, `WorkerRecord` of
131
+ `@astrale-os/sdk/deployment/worker`, or `null`), `readRecord`, `promoteDeployment`,
132
+ `replaceSchedules`, two-phase retirement
133
+ (`markRetired`, then `completeRetirement` once `retirementVisible` sees the dispatcher answer
134
+ `DEPLOYMENT_RETIRED`), `waitForReadiness` through the public URL or a dispatch binding, and
135
+ `listLineDeployments`.
136
+ - **Dispatcher.** Plain ES modules shipped with the package (`dispatcherModules()`), routing a label
137
+ to its script, a name to `current:<name>`, and firing `cron:<name>` on schedule. It serves a
138
+ label's record at `/.well-known/astrale/deployment.json`, its bytes and media type as published
139
+ (immutable, `405` but for `GET` and `HEAD`), and hands that path to a deployment that publishes
140
+ none. `createDispatcher()` owns routing and schedule admission. The public never reaches
141
+ `/__scheduled`; cron targets serve that internal POST endpoint.
142
+ - **Provisioning.** `planHosting` reads; `applyHosting` refuses any blocker before its first write;
143
+ `provisionHosting` does both.
144
+ - **Testing.** `@astrale-os/adapter-cloudflare/hosting/testing` exports `FakeCloudflare`, one fake
145
+ account that serves public requests with the real dispatcher.
146
+
147
+ ## Frontend files
148
+
149
+ The Worker runs before Workers Static Assets on every request and owns frontend response headers
150
+ and routing, for `cloudflare()` and `astrale()` deployments alike. Frontend preparation therefore
151
+ refuses a built frontend whose root contains `_headers`, `_redirects`, or `.assetsignore`, in any
152
+ letter case, as a file or a directory. Wrangler and managed deployments would otherwise interpret these files differently. The refusal happens while
153
+ the artifact is prepared, before any provider change. Vite copies its public directory (`public/`
154
+ by default) to that root: remove them there, or stop the plugin that emits them. The same names
155
+ below the root, such as `docs/_headers`, remain ordinary files.
156
+
157
+ The Worker is also the only server-side code, so preparation likewise refuses a root name starting
158
+ with `_worker.js`, the name of a Cloudflare Pages worker script: a `_worker.js` file or directory,
159
+ or a sibling such as `_worker.js.map`. Wrangler refuses to upload these as assets, since they may
160
+ hold server-side code, so a direct deployment would fail at upload, while a managed deployment would
161
+ publish them. Unlike the names above, the match is case-sensitive, as Wrangler's is: `_Worker.js`
162
+ and a nested `docs/_worker.js` remain ordinary files. Remove such a file from the public directory,
163
+ or rename it if it is a browser script.
164
+
165
+ ## Deployment bindings
166
+
167
+ The bundled Worker carries no Environment value, so every Environment of one source bundles the
168
+ same bytes. Each deployment binds its own values as plain Worker bindings:
169
+
170
+ | Binding | Value |
171
+ | --- | --- |
172
+ | `WORKER_URL` | serving origin of the deployment |
173
+ | `ASTRALE_SETTINGS` | canonical JSON of `{ invocationTimeoutMs, maximumRequestBytes, router, tokenExchange }`, defaults resolved, with optional `durableOptions` |
174
+ | `ASTRALE_BUILD_DIGEST` | required build digest the host recomputed from the uploaded bytes |
175
+
176
+ These names are adapter-owned: preparation refuses an author var, or a `wrangler.vars` entry, that
177
+ takes one, and deployment refuses a secret that does. A host that deploys the Worker itself encodes
178
+ the settings with `encodeWorkerSettings` from `@astrale-os/adapter-cloudflare/worker`. A generated
179
+ Worker refuses execution without `ASTRALE_SETTINGS`.
180
+
181
+ Every Worker requires `WORKER_URL` and `ASTRALE_BUILD_DIGEST`. It seals the `DomainRelease` v4
182
+ of its code at that serving URL, which is also its issuer, and serves it at
183
+ `/.well-known/astrale/release.json`. Routing must name that exact Release. The Worker refuses
184
+ execution when either binding is missing or invalid; a foreign request origin is refused before
185
+ loading the Service. `domain.json` serves no compatibility projection.
186
+
187
+ The `wrangler` overlay reaches the deployment configuration, never the bundle. Preparation refuses
188
+ an overlay key the bundler reads (`alias`, `build`, `define`, `jsx_factory`, `jsx_fragment`,
189
+ `keep_names`, `minify`, `no_bundle`, `node_compat`, `preserve_file_names`, `rules`, `tsconfig`,
190
+ `upload_source_maps`) and a compatibility flag it reads (Node.js, `navigator`, fetch iterable
191
+ typing, Python) beyond the adapter's own `nodejs_compat`.
192
+
193
+ ## Build digest
194
+
195
+ `cloudflare()` and `astrale()` bundle through one bundler, `cloudflare-worker` version `1`, so
196
+ every Environment of either adapter shares one build: `astrale-domain build` prints its build
197
+ digest, and `deploy` places that same Bundle. Two installed versions of this package are two
198
+ copies of the bundler: when their code differs, `build` prints one build digest per copy and warns
199
+ until the adapter versions are aligned.
200
+
201
+ Services and namespace deployments upload the placed modules unchanged, so the digest names the
202
+ bytes the deployment runs. A host with its own Worker entrypoint describes its final upload with
203
+ `workerBuildManifest` and `WorkerUpload` from `@astrale-os/adapter-cloudflare/build`, then computes
204
+ its digest with `buildDigest` from `@astrale-os/sdk/deployment/build/manifest`. Modules retain
205
+ their uploaded names and an asset `/<path>` becomes the file `assets/<path>`. The host binds that
206
+ digest as `ASTRALE_BUILD_DIGEST` and uploads those exact bytes without bundling them again.
207
+ The bundler version names this layout, not a package release.
208
+
209
+ ## Material for a custom Worker entrypoint
210
+
211
+ Workers with provider-specific routes or environment initialization can reuse the adapter's
212
+ material emission without adopting the entire generated entrypoint:
213
+
214
+ ```ts
215
+ import { generateBuildMaterialModule } from '@astrale-os/adapter-cloudflare/build'
216
+ import { writeFile } from 'node:fs/promises'
217
+
218
+ // build is an admitted Build returned by compile(domain).
219
+ await writeFile('src/build-material.gen.ts', generateBuildMaterialModule(build))
220
+ ```
221
+
222
+ The generated TypeScript module exports `loadBuildMaterial()`. Call it from the
223
+ `load` callback of `generatedCloudflareWorkerEntry` alongside the Domain's Runtime.
224
+ That callback loads deterministic local modules once per entrypoint. Concurrent execution and
225
+ `prepare()` calls share the same result, including a rejection; subsequent calls do not retry it.
226
+ A newly constructed entrypoint starts independently. Keep remote preparation that may recover
227
+ from transient failures in its own lifecycle, rather than putting it in `load`.
228
+ Such an entrypoint states its execution settings (`invocationTimeoutMs`, `maximumRequestBytes`,
229
+ `tokenExchange`, `routeSubrequest`) in its configuration, or reads them from its
230
+ deployment bindings with `settings: deploymentSettings`; one Worker never takes both.
231
+ It constructs the same verified, deduplicated material as the adapter's generated Service;
232
+ allocation is deferred until the factory is called and the SDK deep-freezes it before use.
233
+ The generated file needs only a type import from the SDK. Keep its compiler and runtime SDK
234
+ versions aligned, and regenerate it when either the Domain or that SDK version changes.
235
+
236
+ Such an entrypoint can keep the same fast frontend path by answering from
237
+ `cloudflareFrontDoor()` (`@astrale-os/adapter-cloudflare/worker/front`, which reaches no SDK
238
+ runtime module) before importing its Service, and calling that Service's `prepare()` through
239
+ `waitUntil` when the front door served a frontend file.
@@ -0,0 +1,11 @@
1
+ import type { Deployment } from '@astrale-os/sdk/deployment';
2
+ import type { Adapter } from '@astrale-os/sdk/deployment/adapter';
3
+ import type { NamespaceDependencies } from './namespace/index.js';
4
+ import type { CloudflareParams } from './params.js';
5
+ export type { NamespaceDependencies } from './namespace/index.js';
6
+ export interface CloudflareDependencies {
7
+ readonly namespace: NamespaceDependencies;
8
+ }
9
+ /** Deploy each release as one immutable deployment in a Cloudflare dispatch namespace. */
10
+ export declare function cloudflare(parameters: CloudflareParams): Deployment<CloudflareParams, Adapter<CloudflareParams>>;
11
+ export declare function cloudflareWithDependencies(parameters: CloudflareParams, dependencies: CloudflareDependencies): Deployment<CloudflareParams, Adapter<CloudflareParams>>;
@@ -0,0 +1,54 @@
1
+ import { defineAdapter, defineDeployment } from '@astrale-os/sdk/deployment/adapter';
2
+ import { createRequire } from 'node:module';
3
+ import { cloudflareWorkerBundler } from './build/bundler.js';
4
+ import { workerSettings } from './build/configuration.js';
5
+ import { createSigningIdentity } from './hosting/identity.js';
6
+ import { configureNamespace, deployNamespaceRelease, listNamespaceDeployments, hostingCommands, namespaceCoordinates, placeNamespace, } from './namespace/index.js';
7
+ const packageVersion = createRequire(import.meta.url)('../package.json')
8
+ .version;
9
+ /** Deploy each release as one immutable deployment in a Cloudflare dispatch namespace. */
10
+ export function cloudflare(parameters) {
11
+ return cloudflareWithDependencies(parameters, { namespace: platformNamespaceDependencies() });
12
+ }
13
+ export function cloudflareWithDependencies(parameters, dependencies) {
14
+ const namespace = dependencies.namespace;
15
+ const adapter = defineAdapter({
16
+ name: 'cloudflare',
17
+ version: packageVersion,
18
+ bundler: cloudflareWorkerBundler,
19
+ admit: admitCloudflare,
20
+ configure: configureNamespace,
21
+ placement: async (parameters) => placeNamespace(parameters),
22
+ deployRelease: (parameters, context) => deployNamespaceRelease(parameters, context, namespace),
23
+ list: (parameters, context) => listNamespaceDeployments(parameters, context, namespace),
24
+ commands: hostingCommands(namespace),
25
+ secretsFile: (parameters) => parameters.secrets,
26
+ });
27
+ return defineDeployment(adapter, parameters);
28
+ }
29
+ /** Validate the deployment contract when the Project loads, before any build or provider effect. */
30
+ function admitCloudflare(parameters) {
31
+ const allowed = [
32
+ 'namespace',
33
+ 'secrets',
34
+ 'vars',
35
+ 'maximumRequestBytes',
36
+ 'invocationTimeoutMs',
37
+ 'tokenExchange',
38
+ 'durable',
39
+ 'wrangler',
40
+ 'router',
41
+ ];
42
+ if (Reflect.ownKeys(parameters).some((key) => !allowed.includes(key))) {
43
+ throw new TypeError('Cloudflare deployment parameters contain unknown fields.');
44
+ }
45
+ namespaceCoordinates(parameters);
46
+ workerSettings(parameters);
47
+ }
48
+ function platformNamespaceDependencies() {
49
+ return Object.freeze({
50
+ fetch: (input, init) => fetch(input, init),
51
+ environment: process.env,
52
+ createSigningIdentity,
53
+ });
54
+ }
@@ -0,0 +1,3 @@
1
+ export declare function admitWorkerBundle(path: string): Promise<void>;
2
+ /** Admit the separately emitted engine's actual platform exports, including its compiled WASM. */
3
+ export declare function admitDurableEngineBundle(path: string): Promise<void>;
@@ -0,0 +1,46 @@
1
+ import * as nodeModule from 'node:module';
2
+ import { pathToFileURL } from 'node:url';
3
+ import { compiledWasmLoader, compiledWasmSource } from './compiled-wasm-loader.js';
4
+ let compiledWasm = false;
5
+ /**
6
+ * Import a WebAssembly module as Workers do for `CompiledWasm`: its default export is the compiled
7
+ * `WebAssembly.Module`, instantiated by the importing code. The CLI admits bundles under Bun; Node
8
+ * serves programmatic builds.
9
+ */
10
+ function admitCompiledWasm() {
11
+ if (compiledWasm)
12
+ return;
13
+ if (process.versions.bun !== undefined) {
14
+ ;
15
+ Reflect.get(globalThis, 'Bun').plugin({
16
+ name: 'astrale-compiled-wasm',
17
+ setup(build) {
18
+ build.onLoad({ filter: /\.wasm$/ }, ({ path }) => ({
19
+ loader: 'js',
20
+ contents: compiledWasmSource(JSON.stringify(path)),
21
+ }));
22
+ },
23
+ });
24
+ compiledWasm = true;
25
+ return;
26
+ }
27
+ nodeModule.register(compiledWasmLoader);
28
+ compiledWasm = true;
29
+ }
30
+ export async function admitWorkerBundle(path) {
31
+ admitCompiledWasm();
32
+ const loaded = (await import(`${pathToFileURL(path).href}?admit=${Date.now()}`));
33
+ if (loaded.default === null ||
34
+ typeof loaded.default !== 'object' ||
35
+ typeof Reflect.get(loaded.default, 'fetch') !== 'function') {
36
+ throw new TypeError('Generated Worker bundle does not export a Fetch handler.');
37
+ }
38
+ }
39
+ /** Admit the separately emitted engine's actual platform exports, including its compiled WASM. */
40
+ export async function admitDurableEngineBundle(path) {
41
+ admitCompiledWasm();
42
+ const engine = (await import(`${pathToFileURL(path).href}?admit=${Date.now()}`));
43
+ if (['createEndpointHandler', 'workflow', 'TerminalError', 'CancelledError'].some((key) => typeof engine[key] !== 'function')) {
44
+ throw new TypeError('Generated durable engine bundle does not export the platform Fetch entrypoint.');
45
+ }
46
+ }
@@ -0,0 +1,8 @@
1
+ /** Workers expose CompiledWasm imports as modules, rather than instantiated exports. */
2
+ export declare function compiledWasmSource(file: string): string;
3
+ /**
4
+ * Async hooks run in a separate Node thread. A self-contained ESM hook admits both emitted JS and
5
+ * source builds under tsx without requiring that thread to resolve or transpile our source files.
6
+ * The emitted import source is shared with Bun.
7
+ */
8
+ export declare const compiledWasmLoader: string;
@@ -0,0 +1,21 @@
1
+ const SOURCE_PREFIX = "import { readFileSync } from 'node:fs'\nexport default new WebAssembly.Module(readFileSync(";
2
+ const SOURCE_SUFFIX = '))\n';
3
+ /** Workers expose CompiledWasm imports as modules, rather than instantiated exports. */
4
+ export function compiledWasmSource(file) {
5
+ return `${SOURCE_PREFIX}${file}${SOURCE_SUFFIX}`;
6
+ }
7
+ /**
8
+ * Async hooks run in a separate Node thread. A self-contained ESM hook admits both emitted JS and
9
+ * source builds under tsx without requiring that thread to resolve or transpile our source files.
10
+ * The emitted import source is shared with Bun.
11
+ */
12
+ export const compiledWasmLoader = `data:text/javascript,${encodeURIComponent(`
13
+ export function load(url, context, nextLoad) {
14
+ if (!url.startsWith('file:') || !url.endsWith('.wasm')) return nextLoad(url, context);
15
+ return {
16
+ format: 'module',
17
+ shortCircuit: true,
18
+ source: ${JSON.stringify(SOURCE_PREFIX)} + 'new URL(' + JSON.stringify(url) + ')' + ${JSON.stringify(SOURCE_SUFFIX)},
19
+ };
20
+ }
21
+ `)}`;
@@ -0,0 +1,21 @@
1
+ import type { Bundle, BundleContext, Bundler } from '@astrale-os/sdk/deployment/adapter';
2
+ import type { frontend as frontendBuild } from '@astrale-os/sdk/deployment/build';
3
+ import type { ReleaseModule } from './worker/execution.prepare.js';
4
+ /**
5
+ * Environment-free bytes of one generated Worker: its entry, the modules it loads (the execution
6
+ * Service, the deferred workflow engine and their WASM) and its frontend.
7
+ */
8
+ export interface WorkerBytes {
9
+ readonly entry: Uint8Array;
10
+ readonly modules: readonly ReleaseModule[];
11
+ readonly frontend: readonly frontendBuild.FrontendFile[];
12
+ }
13
+ /**
14
+ * Bundles every generated Cloudflare Worker, for adapter-cloudflare and adapter-astrale alike. It
15
+ * reads no Environment: settings, address, issuer and key are bound at deploy.
16
+ */
17
+ export declare const cloudflareWorkerBundler: Bundler;
18
+ /** Bundle the Worker modules and build the frontend they serve, in one scratch directory. */
19
+ export declare function bundleWorker(context: BundleContext): Promise<WorkerBytes>;
20
+ /** Read back the Worker bytes of a Bundle this bundler produced for the same Build. */
21
+ export declare function bundledWorker(bundle: Bundle, build: Bundle['build']): WorkerBytes;
@@ -0,0 +1,96 @@
1
+ import { mkdir, mkdtemp, rm } from 'node:fs/promises';
2
+ import { join } from 'node:path';
3
+ import { CLOUDFLARE_WORKER_BUNDLER, workerAssetFile } from '../release/build.js';
4
+ import { frontendFiles } from './frontend/files.js';
5
+ import { frontendRevision } from './frontend/revision.js';
6
+ import { prepareExecution, RELEASE_ENTRY, RELEASE_SERVICE } from './worker/execution.prepare.js';
7
+ /** Worker modules live beside the entry; WASM is the only non-ESM kind preparation emits. */
8
+ const MODULE_DIRECTORY = 'bundle/';
9
+ /**
10
+ * Bundles every generated Cloudflare Worker, for adapter-cloudflare and adapter-astrale alike. It
11
+ * reads no Environment: settings, address, issuer and key are bound at deploy.
12
+ */
13
+ export const cloudflareWorkerBundler = Object.freeze({
14
+ id: CLOUDFLARE_WORKER_BUNDLER.id,
15
+ version: CLOUDFLARE_WORKER_BUNDLER.version,
16
+ async bundle(context) {
17
+ const worker = await bundleWorker(context);
18
+ return Object.freeze({
19
+ entrypoint: RELEASE_ENTRY,
20
+ files: Object.freeze([
21
+ { path: RELEASE_ENTRY, content: worker.entry },
22
+ ...worker.modules.map(({ path, content }) => ({ path, content })),
23
+ ...worker.frontend.map((file) => ({
24
+ path: workerAssetFile(`/${file.path}`),
25
+ content: file.bytes(),
26
+ })),
27
+ ]),
28
+ });
29
+ },
30
+ });
31
+ /** Bundle the Worker modules and build the frontend they serve, in one scratch directory. */
32
+ export async function bundleWorker(context) {
33
+ const stateDirectory = join(context.projectDir, '.astrale');
34
+ await mkdir(stateDirectory, { recursive: true });
35
+ const directory = await mkdtemp(join(stateDirectory, 'prepare-'));
36
+ try {
37
+ // `frontend` is the served file list; `addressed` rides alongside it into the Worker, where it
38
+ // decides which of those files a browser may retain.
39
+ const { files: frontend, addressed } = await frontendFiles({
40
+ frontend: context.build.frontend,
41
+ projectDir: context.projectDir,
42
+ output: join(directory, 'frontend'),
43
+ recordSource: context.recordSource,
44
+ signal: context.signal,
45
+ });
46
+ const modules = await prepareExecution({
47
+ context,
48
+ directory,
49
+ ...(frontend.length === 0 ? {} : { frontendRevision: frontendRevision(frontend) }),
50
+ ...(addressed.length === 0 ? {} : { frontendAddressed: addressed }),
51
+ });
52
+ return Object.freeze({ entry: modules.entry, modules: modules.modules, frontend });
53
+ }
54
+ finally {
55
+ await rm(directory, { recursive: true, force: true });
56
+ }
57
+ }
58
+ /** Read back the Worker bytes of a Bundle this bundler produced for the same Build. */
59
+ export function bundledWorker(bundle, build) {
60
+ const { id, version } = bundle.manifest.bundler;
61
+ if (bundle.build !== build ||
62
+ id !== CLOUDFLARE_WORKER_BUNDLER.id ||
63
+ version !== CLOUDFLARE_WORKER_BUNDLER.version ||
64
+ bundle.entrypoint !== RELEASE_ENTRY) {
65
+ throw new TypeError('Cloudflare preparation requires the Bundle of its Worker bundler.');
66
+ }
67
+ let entry;
68
+ const modules = [];
69
+ const frontend = [];
70
+ for (const file of bundle.files) {
71
+ if (file.path === RELEASE_ENTRY)
72
+ entry = file.bytes();
73
+ else if (file.path.startsWith(MODULE_DIRECTORY) && /\.(?:mjs|wasm)$/u.test(file.path)) {
74
+ modules.push(Object.freeze({
75
+ path: file.path,
76
+ kind: file.path.endsWith('.wasm') ? 'wasm' : 'esm',
77
+ content: file.bytes(),
78
+ }));
79
+ }
80
+ else if (file.path.startsWith('assets/')) {
81
+ const content = file.bytes();
82
+ frontend.push(Object.freeze({ path: file.path.slice('assets/'.length), bytes: () => content.slice() }));
83
+ }
84
+ else {
85
+ throw new TypeError(`Cloudflare Worker Bundle file ${file.path} is not a Worker file.`);
86
+ }
87
+ }
88
+ if (entry === undefined || !modules.some((module) => module.path === RELEASE_SERVICE)) {
89
+ throw new TypeError('Cloudflare Worker Bundle lacks its execution modules.');
90
+ }
91
+ return Object.freeze({
92
+ entry,
93
+ modules: Object.freeze(modules),
94
+ frontend: Object.freeze(frontend),
95
+ });
96
+ }
@@ -0,0 +1,2 @@
1
+ /** Prove emitted Worker reachability excludes authoring, compilation, and broad Core Schema owners. */
2
+ export declare function assertRuntimeClosure(metafilePath: string): Promise<void>;
@@ -0,0 +1,22 @@
1
+ import { readWranglerMetafile } from './metafile.js';
2
+ const FORBIDDEN_RUNTIME_INPUTS = [
3
+ '/v1/builder/',
4
+ '/v1/compiled/compiler/',
5
+ '/node_modules/ajv/',
6
+ '/node_modules/re2js/',
7
+ '/kernel-core/domain/',
8
+ '/core/domain/',
9
+ '/kernel-core/schema/index.',
10
+ '/core/schema/index.',
11
+ ];
12
+ /** Prove emitted Worker reachability excludes authoring, compilation, and broad Core Schema owners. */
13
+ export async function assertRuntimeClosure(metafilePath) {
14
+ const metafile = await readWranglerMetafile(metafilePath);
15
+ const forbidden = Object.keys(metafile.inputs).filter((input) => {
16
+ const normalized = `/${input.replaceAll('\\', '/')}`.replace(/(\/node_modules\/@astrale-os\/kernel-[^/]+)\/dist\//gu, '$1/');
17
+ return FORBIDDEN_RUNTIME_INPUTS.some((fragment) => normalized.includes(fragment));
18
+ });
19
+ if (forbidden.length > 0) {
20
+ throw new Error(`Cloudflare Worker reaches build-side modules: ${forbidden.sort().join(', ')}.`);
21
+ }
22
+ }
@@ -0,0 +1,3 @@
1
+ export { generateExecutionEntry } from '../worker/codegen/entry.js';
2
+ export { generateExecutionService } from '../worker/codegen/service.js';
3
+ export type { ExecutionCodegenOptions } from '../worker/codegen/service.js';
@@ -0,0 +1,2 @@
1
+ export { generateExecutionEntry } from '../worker/codegen/entry.js';
2
+ export { generateExecutionService } from '../worker/codegen/service.js';
@@ -17,4 +17,3 @@
17
17
  * the caller (`generateWranglerConfig`), not here — this stays a generic merge.
18
18
  */
19
19
  export declare function deepMergeConfig(base: Record<string, unknown>, overlay: Record<string, unknown>): Record<string, unknown>;
20
- //# sourceMappingURL=merge.d.ts.map
@@ -88,4 +88,3 @@ function isPlainObject(v) {
88
88
  function isPrimitive(v) {
89
89
  return v === null || (typeof v !== 'object' && typeof v !== 'function');
90
90
  }
91
- //# sourceMappingURL=merge.js.map
@@ -13,22 +13,32 @@
13
13
  */
14
14
  export interface WranglerCodegenOptions {
15
15
  workerName: string;
16
+ /** Provider-ready entrypoint relative to the generated config. */
17
+ main?: string;
16
18
  /** Full custom hostname for a routed deploy (e.g. 'crm.acme.dev'). */
17
19
  route?: string;
18
20
  /** Exact materialized local frontend; absence means no ASSETS binding. */
19
21
  frontend?: {
20
22
  readonly directory: string;
21
- readonly routes: readonly string[];
22
- readonly dev: boolean;
23
23
  };
24
24
  /** Plain (non-secret) vars to bake in. */
25
25
  vars?: Record<string, string>;
26
+ /** Secret binding names required by generated Worker code. */
27
+ secretBindings?: readonly string[];
28
+ /** Modules retained outside the startup entry and loaded on demand. */
29
+ modules?: {
30
+ readonly baseDir: string;
31
+ readonly rules: readonly {
32
+ readonly type: 'ESModule' | 'CompiledWasm' | 'Text' | 'Data';
33
+ readonly globs: readonly string[];
34
+ }[];
35
+ };
26
36
  /** Add the SELF service binding (autobinding). */
27
37
  selfBinding: boolean;
28
38
  /**
29
39
  * Add a service binding to a router Worker for instance-host subrequest
30
- * routing (see `CloudflareParams.router`). Pairs with the worker
31
- * entry's `routeSubrequest`.
40
+ * routing (see `CloudflareParams.router`). Pairs with the router rule bound
41
+ * in `ASTRALE_SETTINGS`.
32
42
  */
33
43
  router?: {
34
44
  binding: string;
@@ -39,9 +49,25 @@ export interface WranglerCodegenOptions {
39
49
  * hatch for extra bindings (KV, R2, D1, queues, service bindings, extra
40
50
  * `compatibility_flags`, cron `triggers`, …). Arrays concat; new keys are
41
51
  * added as-is. The adapter-owned keys `name`, `main`, `assets`, `routes` are
42
- * rejected (throws) — use `workerName` / `route` instead.
52
+ * rejected (throws) — use `workerName` / `route` instead — and so are the keys
53
+ * and compatibility flags Wrangler's bundler reads.
43
54
  */
44
55
  wrangler?: Record<string, unknown>;
45
56
  }
57
+ /**
58
+ * The Workers runtime every generated Worker runs on, wherever it is deployed: its compatibility
59
+ * date, kept on the runtime baseline qualified with Wrangler 4.123.0, and its compatibility flags.
60
+ * Domain execution calls its Kernel through the invocation's public issuer, so Cloudflare must route
61
+ * same-zone callbacks through the public front door instead of bypassing Worker routes
62
+ * (`global_fetch_strictly_public`). An immutable deployment freezes it into its configuration.
63
+ */
64
+ export declare const GENERATED_WORKER_RUNTIME: Readonly<{
65
+ compatibilityDate: "2026-08-11";
66
+ compatibilityFlags: readonly string[];
67
+ }>;
46
68
  export declare function generateWranglerConfig(opts: WranglerCodegenOptions): string;
47
- //# sourceMappingURL=wrangler.d.ts.map
69
+ /**
70
+ * Whether a compatibility flag shapes the bundle (Wrangler's bundler reads it), so that no
71
+ * Environment may add it: bundling takes no Environment.
72
+ */
73
+ export declare function isBundlingCompatibilityFlag(flag: string): boolean;