alchemy 2.0.0-beta.43 → 2.0.0-beta.44

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 (207) hide show
  1. package/bin/cli.js +18 -5
  2. package/bin/exec.js +315 -233
  3. package/bin/exec.js.map +1 -1
  4. package/lib/Auth/Lock.js +2 -2
  5. package/lib/Auth/Lock.js.map +1 -1
  6. package/lib/Bundle/Bundle.d.ts +11 -0
  7. package/lib/Bundle/Bundle.d.ts.map +1 -1
  8. package/lib/Bundle/Bundle.js +19 -12
  9. package/lib/Bundle/Bundle.js.map +1 -1
  10. package/lib/Bundle/BundleAnalyzerPlugin.d.ts +25 -0
  11. package/lib/Bundle/BundleAnalyzerPlugin.d.ts.map +1 -0
  12. package/lib/Bundle/BundleAnalyzerPlugin.js +16 -0
  13. package/lib/Bundle/BundleAnalyzerPlugin.js.map +1 -0
  14. package/lib/Bundle/RawPlugin.d.ts +36 -0
  15. package/lib/Bundle/RawPlugin.d.ts.map +1 -0
  16. package/lib/Bundle/RawPlugin.js +80 -0
  17. package/lib/Bundle/RawPlugin.js.map +1 -0
  18. package/lib/Bundle/index.d.ts +2 -0
  19. package/lib/Bundle/index.d.ts.map +1 -1
  20. package/lib/Bundle/index.js +2 -0
  21. package/lib/Bundle/index.js.map +1 -1
  22. package/lib/Cli/commands/dev.d.ts +3 -2
  23. package/lib/Cli/commands/dev.d.ts.map +1 -1
  24. package/lib/Cli/commands/dev.js +9 -1
  25. package/lib/Cli/commands/dev.js.map +1 -1
  26. package/lib/Cli/exec.d.ts.map +1 -1
  27. package/lib/Cli/exec.js +2 -1
  28. package/lib/Cli/exec.js.map +1 -1
  29. package/lib/Cloudflare/Local.d.ts +2 -0
  30. package/lib/Cloudflare/Local.d.ts.map +1 -0
  31. package/lib/Cloudflare/Local.js +9 -0
  32. package/lib/Cloudflare/Local.js.map +1 -0
  33. package/lib/Cloudflare/Providers.d.ts.map +1 -1
  34. package/lib/Cloudflare/Providers.js +3 -1
  35. package/lib/Cloudflare/Providers.js.map +1 -1
  36. package/lib/Cloudflare/Workers/DurableObjectBridge.d.ts.map +1 -1
  37. package/lib/Cloudflare/Workers/DurableObjectBridge.js +0 -1
  38. package/lib/Cloudflare/Workers/DurableObjectBridge.js.map +1 -1
  39. package/lib/Cloudflare/Workers/LocalWorkerProvider.d.ts +22 -3
  40. package/lib/Cloudflare/Workers/LocalWorkerProvider.d.ts.map +1 -1
  41. package/lib/Cloudflare/Workers/LocalWorkerProvider.js +413 -21
  42. package/lib/Cloudflare/Workers/LocalWorkerProvider.js.map +1 -1
  43. package/lib/Cloudflare/Workers/Worker.d.ts +6 -19
  44. package/lib/Cloudflare/Workers/Worker.d.ts.map +1 -1
  45. package/lib/Cloudflare/Workers/Worker.js +3 -4
  46. package/lib/Cloudflare/Workers/Worker.js.map +1 -1
  47. package/lib/Cloudflare/Workers/WorkerBridge.d.ts.map +1 -1
  48. package/lib/Cloudflare/Workers/WorkerBridge.js +3 -5
  49. package/lib/Cloudflare/Workers/WorkerBridge.js.map +1 -1
  50. package/lib/Cloudflare/Workers/WorkerBundle.d.ts +1 -2
  51. package/lib/Cloudflare/Workers/WorkerBundle.d.ts.map +1 -1
  52. package/lib/Cloudflare/Workers/WorkerBundle.js +3 -6
  53. package/lib/Cloudflare/Workers/WorkerBundle.js.map +1 -1
  54. package/lib/Cloudflare/Zaraz/ZarazConfig.d.ts +184 -0
  55. package/lib/Cloudflare/Zaraz/ZarazConfig.d.ts.map +1 -0
  56. package/lib/Cloudflare/Zaraz/ZarazConfig.js +216 -0
  57. package/lib/Cloudflare/Zaraz/ZarazConfig.js.map +1 -0
  58. package/lib/Cloudflare/Zaraz/ZarazEventTypes.d.ts +188 -0
  59. package/lib/Cloudflare/Zaraz/ZarazEventTypes.d.ts.map +1 -0
  60. package/lib/Cloudflare/Zaraz/ZarazEventTypes.js +4 -0
  61. package/lib/Cloudflare/Zaraz/ZarazEventTypes.js.map +1 -0
  62. package/lib/Cloudflare/Zaraz/index.d.ts +3 -0
  63. package/lib/Cloudflare/Zaraz/index.d.ts.map +1 -0
  64. package/lib/Cloudflare/Zaraz/index.js +2 -0
  65. package/lib/Cloudflare/Zaraz/index.js.map +1 -0
  66. package/lib/Cloudflare/index.d.ts +1 -0
  67. package/lib/Cloudflare/index.d.ts.map +1 -1
  68. package/lib/Cloudflare/index.js +1 -0
  69. package/lib/Cloudflare/index.js.map +1 -1
  70. package/lib/Local/RpcProvider.d.ts +54 -0
  71. package/lib/Local/RpcProvider.d.ts.map +1 -0
  72. package/lib/Local/RpcProvider.js +57 -0
  73. package/lib/Local/RpcProvider.js.map +1 -0
  74. package/lib/Local/RpcProviderProxy.d.ts +19 -0
  75. package/lib/Local/RpcProviderProxy.d.ts.map +1 -0
  76. package/lib/Local/RpcProviderProxy.js +48 -0
  77. package/lib/Local/RpcProviderProxy.js.map +1 -0
  78. package/lib/Local/RpcSerialization.d.ts +34 -0
  79. package/lib/Local/RpcSerialization.d.ts.map +1 -0
  80. package/lib/Local/RpcSerialization.js +120 -0
  81. package/lib/Local/RpcSerialization.js.map +1 -0
  82. package/lib/Local/RpcServer.d.ts +63 -0
  83. package/lib/Local/RpcServer.d.ts.map +1 -0
  84. package/lib/Local/RpcServer.js +72 -0
  85. package/lib/Local/RpcServer.js.map +1 -0
  86. package/lib/Local/RpcServerBun.d.ts +3 -0
  87. package/lib/Local/RpcServerBun.d.ts.map +1 -0
  88. package/lib/Local/RpcServerBun.js +47 -0
  89. package/lib/Local/RpcServerBun.js.map +1 -0
  90. package/lib/Local/RpcServerEnvironment.d.ts +20 -0
  91. package/lib/Local/RpcServerEnvironment.d.ts.map +1 -0
  92. package/lib/Local/RpcServerEnvironment.js +22 -0
  93. package/lib/Local/RpcServerEnvironment.js.map +1 -0
  94. package/lib/Local/RpcServerNode.d.ts +3 -0
  95. package/lib/Local/RpcServerNode.d.ts.map +1 -0
  96. package/lib/Local/RpcServerNode.js +43 -0
  97. package/lib/Local/RpcServerNode.js.map +1 -0
  98. package/lib/Local/RpcServerSession.d.ts +27 -0
  99. package/lib/Local/RpcServerSession.d.ts.map +1 -0
  100. package/lib/Local/RpcServerSession.js +68 -0
  101. package/lib/Local/RpcServerSession.js.map +1 -0
  102. package/lib/Local/RpcSpawner.d.ts +21 -0
  103. package/lib/Local/RpcSpawner.d.ts.map +1 -0
  104. package/lib/Local/RpcSpawner.js +132 -0
  105. package/lib/Local/RpcSpawner.js.map +1 -0
  106. package/lib/Util/PlatformServices.d.ts +7 -0
  107. package/lib/Util/PlatformServices.d.ts.map +1 -1
  108. package/lib/Util/PlatformServices.js +22 -11
  109. package/lib/Util/PlatformServices.js.map +1 -1
  110. package/lib/Util/camel.d.ts.map +1 -1
  111. package/lib/Util/camel.js +2 -3
  112. package/lib/Util/camel.js.map +1 -1
  113. package/lib/Util/data.d.ts +5 -0
  114. package/lib/Util/data.d.ts.map +1 -1
  115. package/lib/Util/data.js +29 -0
  116. package/lib/Util/data.js.map +1 -1
  117. package/lib/Util/stable.d.ts.map +1 -1
  118. package/lib/Util/stable.js +3 -6
  119. package/lib/Util/stable.js.map +1 -1
  120. package/lib/tsconfig.test.tsbuildinfo +1 -1
  121. package/package.json +12 -14
  122. package/src/Auth/Lock.ts +2 -2
  123. package/src/Bundle/Bundle.ts +35 -13
  124. package/src/Bundle/BundleAnalyzerPlugin.ts +33 -0
  125. package/src/Bundle/RawPlugin.ts +82 -0
  126. package/src/Bundle/index.ts +2 -0
  127. package/src/Cli/commands/dev.ts +51 -37
  128. package/src/Cli/exec.ts +12 -7
  129. package/src/Cloudflare/Local.ts +23 -0
  130. package/src/Cloudflare/Providers.ts +3 -0
  131. package/src/Cloudflare/Workers/DurableObjectBridge.ts +0 -1
  132. package/src/Cloudflare/Workers/LocalWorkerProvider.ts +547 -21
  133. package/src/Cloudflare/Workers/Worker.ts +11 -22
  134. package/src/Cloudflare/Workers/WorkerBridge.ts +3 -5
  135. package/src/Cloudflare/Workers/WorkerBundle.ts +4 -8
  136. package/src/Cloudflare/Zaraz/ZarazConfig.ts +403 -0
  137. package/src/Cloudflare/Zaraz/ZarazEventTypes.ts +257 -0
  138. package/src/Cloudflare/Zaraz/index.ts +25 -0
  139. package/src/Cloudflare/index.ts +1 -0
  140. package/src/Local/RpcProvider.ts +102 -0
  141. package/src/Local/RpcProviderProxy.ts +86 -0
  142. package/src/Local/RpcSerialization.ts +225 -0
  143. package/src/Local/RpcServer.ts +138 -0
  144. package/src/Local/RpcServerBun.ts +59 -0
  145. package/src/Local/RpcServerEnvironment.ts +55 -0
  146. package/src/Local/RpcServerNode.ts +58 -0
  147. package/src/Local/RpcServerSession.ts +87 -0
  148. package/src/Local/RpcSpawner.ts +196 -0
  149. package/src/Util/PlatformServices.ts +41 -27
  150. package/src/Util/camel.ts +3 -5
  151. package/src/Util/data.ts +38 -0
  152. package/src/Util/stable.ts +4 -10
  153. package/lib/Cloudflare/Local/Sidecar.d.ts +0 -63
  154. package/lib/Cloudflare/Local/Sidecar.d.ts.map +0 -1
  155. package/lib/Cloudflare/Local/Sidecar.js +0 -50
  156. package/lib/Cloudflare/Local/Sidecar.js.map +0 -1
  157. package/lib/Cloudflare/Local/SidecarHandlers.d.ts +0 -8
  158. package/lib/Cloudflare/Local/SidecarHandlers.d.ts.map +0 -1
  159. package/lib/Cloudflare/Local/SidecarHandlers.js +0 -381
  160. package/lib/Cloudflare/Local/SidecarHandlers.js.map +0 -1
  161. package/lib/Cloudflare/Local/SidecarServer.d.ts +0 -2
  162. package/lib/Cloudflare/Local/SidecarServer.d.ts.map +0 -1
  163. package/lib/Cloudflare/Local/SidecarServer.js +0 -34
  164. package/lib/Cloudflare/Local/SidecarServer.js.map +0 -1
  165. package/lib/Sidecar/Lock.d.ts +0 -23
  166. package/lib/Sidecar/Lock.d.ts.map +0 -1
  167. package/lib/Sidecar/Lock.js +0 -39
  168. package/lib/Sidecar/Lock.js.map +0 -1
  169. package/lib/Sidecar/RpcClient.d.ts +0 -15
  170. package/lib/Sidecar/RpcClient.d.ts.map +0 -1
  171. package/lib/Sidecar/RpcClient.js +0 -78
  172. package/lib/Sidecar/RpcClient.js.map +0 -1
  173. package/lib/Sidecar/RpcHandler.d.ts +0 -51
  174. package/lib/Sidecar/RpcHandler.d.ts.map +0 -1
  175. package/lib/Sidecar/RpcHandler.js +0 -87
  176. package/lib/Sidecar/RpcHandler.js.map +0 -1
  177. package/lib/Sidecar/RpcPaths.d.ts +0 -19
  178. package/lib/Sidecar/RpcPaths.d.ts.map +0 -1
  179. package/lib/Sidecar/RpcPaths.js +0 -31
  180. package/lib/Sidecar/RpcPaths.js.map +0 -1
  181. package/lib/Sidecar/RpcServer.d.ts +0 -30
  182. package/lib/Sidecar/RpcServer.d.ts.map +0 -1
  183. package/lib/Sidecar/RpcServer.js +0 -105
  184. package/lib/Sidecar/RpcServer.js.map +0 -1
  185. package/lib/Sidecar/RpcServerBun.d.ts +0 -4
  186. package/lib/Sidecar/RpcServerBun.d.ts.map +0 -1
  187. package/lib/Sidecar/RpcServerBun.js +0 -28
  188. package/lib/Sidecar/RpcServerBun.js.map +0 -1
  189. package/lib/Sidecar/RpcServerNode.d.ts +0 -4
  190. package/lib/Sidecar/RpcServerNode.d.ts.map +0 -1
  191. package/lib/Sidecar/RpcServerNode.js +0 -39
  192. package/lib/Sidecar/RpcServerNode.js.map +0 -1
  193. package/lib/Sidecar/RpcServices.d.ts +0 -6
  194. package/lib/Sidecar/RpcServices.d.ts.map +0 -1
  195. package/lib/Sidecar/RpcServices.js +0 -29
  196. package/lib/Sidecar/RpcServices.js.map +0 -1
  197. package/src/Cloudflare/Local/Sidecar.ts +0 -81
  198. package/src/Cloudflare/Local/SidecarHandlers.ts +0 -491
  199. package/src/Cloudflare/Local/SidecarServer.ts +0 -70
  200. package/src/Sidecar/Lock.ts +0 -66
  201. package/src/Sidecar/RpcClient.ts +0 -142
  202. package/src/Sidecar/RpcHandler.ts +0 -205
  203. package/src/Sidecar/RpcPaths.ts +0 -39
  204. package/src/Sidecar/RpcServer.ts +0 -153
  205. package/src/Sidecar/RpcServerBun.ts +0 -41
  206. package/src/Sidecar/RpcServerNode.ts +0 -51
  207. package/src/Sidecar/RpcServices.ts +0 -48
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "alchemy",
3
- "version": "2.0.0-beta.43",
3
+ "version": "2.0.0-beta.44",
4
4
  "homepage": "https://alchemy.run",
5
5
  "license": "Apache-2.0",
6
6
  "author": "Sam Goodwin <sam@alchemy.run>",
@@ -288,18 +288,18 @@
288
288
  "access": "public"
289
289
  },
290
290
  "dependencies": {
291
- "@alchemy.run/node-utils": "0.0.2",
291
+ "@alchemy.run/node-utils": "0.0.4",
292
292
  "@aws-sdk/credential-providers": "^3.0.0",
293
293
  "@clack/prompts": "^0.11.0",
294
- "@distilled.cloud/aws": "^0.21.3",
295
- "@distilled.cloud/axiom": "^0.21.3",
296
- "@distilled.cloud/cloudflare": "^0.21.3",
297
- "@distilled.cloud/cloudflare-rolldown-plugin": "0.5.4",
298
- "@distilled.cloud/cloudflare-runtime": "0.5.4",
299
- "@distilled.cloud/cloudflare-vite-plugin": "0.5.4",
300
- "@distilled.cloud/core": "^0.21.3",
301
- "@distilled.cloud/planetscale": "^0.21.3",
302
- "@distilled.cloud/neon": "^0.21.3",
294
+ "@distilled.cloud/aws": "^0.21.5",
295
+ "@distilled.cloud/axiom": "^0.21.5",
296
+ "@distilled.cloud/cloudflare": "^0.21.5",
297
+ "@distilled.cloud/cloudflare-rolldown-plugin": "0.6.3",
298
+ "@distilled.cloud/cloudflare-runtime": "0.6.3",
299
+ "@distilled.cloud/cloudflare-vite-plugin": "0.6.3",
300
+ "@distilled.cloud/core": "^0.21.5",
301
+ "@distilled.cloud/neon": "^0.21.5",
302
+ "@distilled.cloud/planetscale": "^0.21.5",
303
303
  "@effect/vitest": ">=4.0.0-beta.66 || >=4.0.0",
304
304
  "@libsql/client": "^0.17.0",
305
305
  "@octokit/rest": "^22.0.1",
@@ -311,7 +311,6 @@
311
311
  "capnweb": "^0.6.1",
312
312
  "fast-glob": "^3.3.2",
313
313
  "fast-xml-parser": "^5.3.4",
314
- "foreground-child": "^4.0.3",
315
314
  "ink": "^6.3.1",
316
315
  "jszip": "^3.10.1",
317
316
  "libsodium-wrappers": "^0.8.3",
@@ -321,8 +320,7 @@
321
320
  "pg": "^8.13.0",
322
321
  "picomatch": "^4.0.4",
323
322
  "react": "^19.2.0",
324
- "rolldown": "1.0.0-rc.17",
325
- "sonda": "^0.11.1",
323
+ "rolldown": "1.0.1",
326
324
  "undici": "^7.16.0",
327
325
  "yaml": "^2.0.0"
328
326
  },
package/src/Auth/Lock.ts CHANGED
@@ -1,4 +1,4 @@
1
- import * as lockfile from "@alchemy.run/node-utils";
1
+ import { lock } from "@alchemy.run/node-utils/lockfile";
2
2
  import * as Effect from "effect/Effect";
3
3
  import * as fs from "node:fs/promises";
4
4
  import * as path from "pathe";
@@ -24,7 +24,7 @@ export const withLock = <A, E, R>(
24
24
  return Effect.acquireUseRelease(
25
25
  Effect.promise(async () => {
26
26
  await fs.mkdir(lockDir, { recursive: true });
27
- return await lockfile.lock(lockPath, {
27
+ return await lock(lockPath, {
28
28
  retries: { retries: 600, minTimeout: 50, maxTimeout: 50 },
29
29
  stale: 5_000,
30
30
  realpath: false,
@@ -6,7 +6,12 @@ import * as Stream from "effect/Stream";
6
6
  import assert from "node:assert";
7
7
  import * as rolldown from "rolldown";
8
8
  import { sha256, sha256Object } from "../Util/sha256.ts";
9
+ import {
10
+ bundleAnalyzerPlugin,
11
+ type BundleAnalyzerPluginOptions,
12
+ } from "./BundleAnalyzerPlugin.ts";
9
13
  import { purePlugin, type PurePluginOptions } from "./PurePlugin.ts";
14
+ import { rawPlugin } from "./RawPlugin.ts";
10
15
 
11
16
  /**
12
17
  * Extra options accepted by {@link build} / {@link watch} on top of the
@@ -24,6 +29,16 @@ export interface BundleExtraOptions {
24
29
  * - `false`: plugin is disabled.
25
30
  */
26
31
  readonly pure?: PurePluginOptions | false;
32
+ /**
33
+ * Configures the {@link bundleAnalyzerPlugin} which emits a bundle analysis
34
+ * report alongside the bundle output, describing chunks, modules, and the
35
+ * import graph reachable from each entry point.
36
+ *
37
+ * - `undefined` / `false` (default): plugin is disabled.
38
+ * - `true`: plugin is enabled with default options.
39
+ * - `BundleAnalyzerPluginOptions`: plugin is enabled with the provided options.
40
+ */
41
+ readonly bundleAnalyzer?: BundleAnalyzerPluginOptions | boolean;
27
42
  }
28
43
 
29
44
  export interface BundleOutput {
@@ -86,7 +101,7 @@ export const build = (
86
101
  try: async () => {
87
102
  const bundle = await rolldown.rolldown({
88
103
  ...inputOptions,
89
- plugins: withPurePlugin(inputOptions.plugins, extra?.pure),
104
+ plugins: [inputOptions.plugins, builtInPlugins(extra)],
90
105
  optimization: inputOptions.optimization ?? {
91
106
  inlineConst: {
92
107
  mode: "smart",
@@ -94,7 +109,7 @@ export const build = (
94
109
  },
95
110
  },
96
111
  });
97
- const result = await bundle.generate(outputOptions);
112
+ const result = await bundle.write(outputOptions);
98
113
  await bundle.close();
99
114
  return result.output;
100
115
  },
@@ -128,7 +143,8 @@ export const watch = (
128
143
  const watcher = rolldown.watch({
129
144
  ...inputOptions,
130
145
  plugins: [
131
- withPurePlugin(inputOptions.plugins, extra?.pure),
146
+ inputOptions.plugins,
147
+ builtInPlugins(extra),
132
148
  // The watcher event listener does not receive the bundle output, so we grab it using a plugin.
133
149
  {
134
150
  name: "alchemy:watch-bundle",
@@ -266,19 +282,25 @@ export function bundleOutputFromRolldownOutputBundle(
266
282
  }
267
283
 
268
284
  /**
269
- * Composes the user-provided plugin chain with the default
270
- * {@link purePlugin} according to the `pure` option.
285
+ * Returns the built-in plugins appended after the user-provided plugin chain,
286
+ * configured by {@link BundleExtraOptions}.
271
287
  *
272
- * The pure plugin is appended LAST so it sees module ids that have already
273
- * been resolved into `node_modules/<pkg>/...` by upstream resolver plugins
274
- * such as `@distilled.cloud/cloudflare-rolldown-plugin`.
288
+ * These run LAST so they see module ids that have already been resolved into
289
+ * `node_modules/<pkg>/...` by upstream resolver plugins such as
290
+ * `@distilled.cloud/cloudflare-rolldown-plugin`.
275
291
  */
276
- function withPurePlugin(
277
- plugins: rolldown.RolldownPluginOption,
278
- pure: PurePluginOptions | false | undefined,
292
+ function builtInPlugins(
293
+ extra?: BundleExtraOptions,
279
294
  ): rolldown.RolldownPluginOption {
280
- if (pure === false) return plugins;
281
- return [plugins, purePlugin(pure ?? {})];
295
+ return [
296
+ extra?.bundleAnalyzer
297
+ ? bundleAnalyzerPlugin(
298
+ extra.bundleAnalyzer === true ? {} : extra.bundleAnalyzer,
299
+ )
300
+ : undefined,
301
+ extra?.pure !== false ? purePlugin(extra?.pure ?? {}) : undefined,
302
+ rawPlugin(),
303
+ ];
282
304
  }
283
305
 
284
306
  function bundleErrorFromUnknown(error: unknown): BundleError {
@@ -0,0 +1,33 @@
1
+ import type { Plugin } from "rolldown";
2
+ import { bundleAnalyzerPlugin as rolldownBundleAnalyzerPlugin } from "rolldown/experimental";
3
+
4
+ export interface BundleAnalyzerPluginOptions {
5
+ /**
6
+ * The filename of the bundle analysis data.
7
+ * @default "analyze-data.md"
8
+ */
9
+ readonly fileName?: string;
10
+ /**
11
+ * The format of the bundle analysis data.
12
+ * @default "md"
13
+ */
14
+ readonly format?: "json" | "md";
15
+ }
16
+
17
+ /**
18
+ * Wraps rolldown's experimental bundle analyzer plugin, which emits a report
19
+ * describing the composition of the bundle.
20
+ *
21
+ * The report includes:
22
+ * - all chunks and their relationships
23
+ * - the modules bundled into each chunk
24
+ * - import dependencies between chunks
25
+ * - the modules reachable from each entry point
26
+ */
27
+ export const bundleAnalyzerPlugin = (
28
+ options: BundleAnalyzerPluginOptions = {},
29
+ ): Plugin =>
30
+ rolldownBundleAnalyzerPlugin({
31
+ fileName: options.fileName,
32
+ format: options.format ?? "md",
33
+ });
@@ -0,0 +1,82 @@
1
+ import type * as rolldown from "rolldown";
2
+
3
+ /**
4
+ * Matches `?raw` or `&raw` query suffixes, mirroring Vite's `rawRE`
5
+ * (see `vite/src/node/utils.ts`). Used to gate both `resolveId` and
6
+ * `load` so the plugin only inspects ids that opt in.
7
+ */
8
+ export const RAW_RE: RegExp = /(\?|&)raw(?:&|$)/;
9
+
10
+ /**
11
+ * Rolldown plugin that adds Vite-style `?raw` import support to the
12
+ * Alchemy bundler.
13
+ *
14
+ * Importing a file with the `?raw` suffix inlines its contents as the
15
+ * default export of a JS module:
16
+ *
17
+ * ```ts
18
+ * import sql from "./schema.sql?raw";
19
+ * // ^ string — the file contents read as UTF-8
20
+ * ```
21
+ *
22
+ * This plugin only implements `?raw`. Vite's `?url` and `?inline`
23
+ * variants both rely on a browser asset pipeline (URL serving / `data:`
24
+ * fallback) that has no analogue in the server-side bundles produced
25
+ * here (Cloudflare Workers, AWS Lambda), so they are intentionally
26
+ * omitted.
27
+ */
28
+ export const rawPlugin = (): rolldown.Plugin => ({
29
+ name: "alchemy:raw",
30
+ resolveId: {
31
+ filter: { id: RAW_RE },
32
+ async handler(source, importer) {
33
+ const [base, query] = splitFileAndPostfix(source);
34
+ const resolved = await this.resolve(base, importer, { skipSelf: true });
35
+ if (!resolved || resolved.external) return null;
36
+ return { id: resolved.id + query, moduleSideEffects: false };
37
+ },
38
+ },
39
+ load: {
40
+ filter: { id: RAW_RE },
41
+ async handler(id) {
42
+ const file = id.replace(/[?#].*$/, "");
43
+ const contents = await this.fs.readFile(file, { encoding: "utf8" });
44
+ return {
45
+ code: `export default ${JSON.stringify(contents)};`,
46
+ // Empty mappings = "this module has no meaningful source map".
47
+ // The generated code is a synthetic `export default "..."` that
48
+ // doesn't correspond line-for-line to any source file (the
49
+ // underlying file isn't JS), so there's nothing to map. Supplying
50
+ // `{ mappings: "" }` (rather than omitting `map`) opts the module
51
+ // out of source-map generation without making rolldown synthesize
52
+ // a default one from the loaded code.
53
+ map: { mappings: "" },
54
+ // NOTE: matches Vite — avoids a double `export default` if the
55
+ // file extension would otherwise be picked up by another loader
56
+ // (e.g. `?raw&.json`).
57
+ moduleType: "js",
58
+ };
59
+ },
60
+ },
61
+ });
62
+
63
+ /**
64
+ * Splits an id into its file portion and the query/hash postfix (kept
65
+ * with the leading `?` / `#`). Matches Vite's `splitFileAndPostfix`.
66
+ *
67
+ * @example
68
+ * splitFileAndPostfix("./foo.txt?raw") // => ["./foo.txt", "?raw"]
69
+ * splitFileAndPostfix("./foo.txt") // => ["./foo.txt", ""]
70
+ */
71
+ export function splitFileAndPostfix(id: string): [string, string] {
72
+ const queryIdx = id.indexOf("?");
73
+ const hashIdx = id.indexOf("#");
74
+ const idx =
75
+ queryIdx === -1
76
+ ? hashIdx
77
+ : hashIdx === -1
78
+ ? queryIdx
79
+ : Math.min(queryIdx, hashIdx);
80
+ if (idx === -1) return [id, ""];
81
+ return [id.slice(0, idx), id.slice(idx)];
82
+ }
@@ -1,4 +1,6 @@
1
1
  export * from "./Bundle.ts";
2
+ export * from "./BundleAnalyzerPlugin.ts";
2
3
  export * from "./Docker.ts";
3
4
  export * from "./PurePlugin.ts";
5
+ export * from "./RawPlugin.ts";
4
6
  export * from "./TempRoot.ts";
@@ -1,8 +1,11 @@
1
1
  import * as Effect from "effect/Effect";
2
+ import * as Option from "effect/Option";
2
3
  import * as Schema from "effect/Schema";
3
4
  import * as Command from "effect/unstable/cli/Command";
4
5
  import * as ChildProcess from "effect/unstable/process/ChildProcess";
5
6
  import { fileURLToPath } from "node:url";
7
+ import { SPAWNER_URL_ENV_KEY } from "../../Local/RpcProviderProxy.ts";
8
+ import * as RpcSpawner from "../../Local/RpcSpawner.ts";
6
9
  import { envFile, force, profile, script, stage } from "./_shared.ts";
7
10
  import { ExecStackOptions } from "./deploy.ts";
8
11
 
@@ -15,41 +18,52 @@ export const devCommand = Command.make(
15
18
  stage,
16
19
  profile,
17
20
  },
18
- Effect.fn(function* (args) {
19
- const options = yield* Schema.encodeEffect(ExecStackOptions)({
20
- ...args,
21
- yes: true,
22
- dev: true,
23
- });
24
- // We no longer force Bun in development because this prevents us from testing in Node.
25
- const command =
26
- typeof globalThis.Bun !== "undefined"
27
- ? [
28
- "bun",
29
- "run",
30
- ...process.execArgv,
31
- "--watch",
32
- "--no-clear-screen",
33
- fileURLToPath(import.meta.resolve("alchemy/bin/exec.ts")),
34
- ]
35
- : [
36
- "node",
37
- ...process.execArgv,
38
- "--experimental-transform-types",
39
- "--watch",
40
- "--watch-preserve-output",
41
- fileURLToPath(import.meta.resolve("alchemy/bin/exec.js")),
42
- ];
43
- const child = yield* ChildProcess.make(command[0], command.slice(1), {
44
- stdin: "inherit",
45
- stdout: "inherit",
46
- stderr: "inherit",
47
- env: {
48
- ALCHEMY_EXEC_OPTIONS: JSON.stringify(options),
49
- },
50
- extendEnv: true,
51
- detached: false,
52
- });
53
- yield* child.exitCode;
54
- }),
21
+ Effect.fn(
22
+ function* (args) {
23
+ const options = yield* Schema.encodeEffect(ExecStackOptions)({
24
+ ...args,
25
+ yes: true,
26
+ dev: true,
27
+ });
28
+ const spawner = yield* RpcSpawner.RpcSpawner;
29
+ // We no longer force Bun in development because this prevents us from testing in Node.
30
+ const command =
31
+ typeof globalThis.Bun !== "undefined"
32
+ ? [
33
+ "bun",
34
+ "run",
35
+ ...process.execArgv,
36
+ "--watch",
37
+ "--no-clear-screen",
38
+ fileURLToPath(import.meta.resolve("alchemy/bin/exec.ts")),
39
+ ]
40
+ : [
41
+ "node",
42
+ ...process.execArgv,
43
+ "--experimental-transform-types",
44
+ "--watch",
45
+ "--watch-preserve-output",
46
+ fileURLToPath(import.meta.resolve("alchemy/bin/exec.js")),
47
+ ];
48
+ const child = yield* ChildProcess.make(command[0], command.slice(1), {
49
+ stdin: "inherit",
50
+ stdout: "inherit",
51
+ stderr: "inherit",
52
+ env: {
53
+ ALCHEMY_EXEC_OPTIONS: JSON.stringify(options),
54
+ [SPAWNER_URL_ENV_KEY]: spawner.url,
55
+ },
56
+ extendEnv: true,
57
+ detached: false,
58
+ });
59
+ yield* child.exitCode;
60
+ },
61
+ (effect, args) =>
62
+ Effect.provide(
63
+ RpcSpawner.layerServer({
64
+ profile: args.profile,
65
+ envFile: Option.getOrUndefined(args.envFile),
66
+ }),
67
+ )(effect),
68
+ ),
55
69
  );
package/src/Cli/exec.ts CHANGED
@@ -7,17 +7,22 @@ import * as FetchHttpClient from "effect/unstable/http/FetchHttpClient";
7
7
  import { AlchemyContextLive } from "../AlchemyContext.ts";
8
8
  import { CredentialsStoreLive } from "../Auth/Credentials.ts";
9
9
  import { ProfileLive } from "../Auth/Profile.ts";
10
+ import * as RpcProviderProxy from "../Local/RpcProviderProxy.ts";
10
11
  import { PlatformServices } from "../Util/PlatformServices.ts";
11
12
  import { execStack, ExecStackOptions } from "./commands/deploy.ts";
12
13
  import { selectCli } from "./selectCli.ts";
13
14
 
14
- const services = Layer.mergeAll(
15
- Layer.provideMerge(AlchemyContextLive, PlatformServices),
16
- Layer.provide(ProfileLive, PlatformServices),
17
- Layer.provide(CredentialsStoreLive, PlatformServices),
18
- FetchHttpClient.layer,
19
- ConfigProvider.layer(ConfigProvider.fromEnv()),
20
- selectCli(),
15
+ const services = Layer.merge(selectCli(), RpcProviderProxy.fromEnv()).pipe(
16
+ Layer.provideMerge(
17
+ Layer.mergeAll(AlchemyContextLive, ProfileLive, CredentialsStoreLive),
18
+ ),
19
+ Layer.provideMerge(
20
+ Layer.mergeAll(
21
+ PlatformServices,
22
+ FetchHttpClient.layer,
23
+ ConfigProvider.layer(ConfigProvider.fromEnv()),
24
+ ),
25
+ ),
21
26
  );
22
27
 
23
28
  export const exec = () =>
@@ -0,0 +1,23 @@
1
+ import * as Layer from "effect/Layer";
2
+ import * as RpcServer from "../Local/RpcServer.ts";
3
+ import { CloudflareAuth } from "./Auth/AuthProvider.ts";
4
+ import * as CloudflareEnvironment from "./CloudflareEnvironment.ts";
5
+ import * as Credentials from "./Credentials.ts";
6
+ import {
7
+ LocalWorkerProvider,
8
+ localRuntimeServices,
9
+ } from "./Workers/LocalWorkerProvider.ts";
10
+
11
+ const cloudflareServices = Layer.provide(
12
+ Layer.merge(
13
+ Credentials.fromAuthProvider(),
14
+ CloudflareEnvironment.fromProfile(),
15
+ ),
16
+ CloudflareAuth,
17
+ );
18
+
19
+ LocalWorkerProvider().pipe(
20
+ Layer.provide(localRuntimeServices({ port: 1337 })),
21
+ Layer.provide(cloudflareServices),
22
+ RpcServer.launch,
23
+ );
@@ -32,6 +32,7 @@ import * as Tunnel from "./Tunnel/index.ts";
32
32
  import * as VpcService from "./VpcService/index.ts";
33
33
  import * as Workers from "./Workers/index.ts";
34
34
  import * as Workflows from "./Workers/Workflow.ts";
35
+ import * as Zaraz from "./Zaraz/index.ts";
35
36
 
36
37
  export { Credentials } from "@distilled.cloud/cloudflare/Credentials";
37
38
 
@@ -84,6 +85,7 @@ export const providers = () =>
84
85
  Workers.FetchPolicy,
85
86
  Workers.Worker,
86
87
  Workflows.WorkflowResource,
88
+ Zaraz.ZarazConfig,
87
89
  ]),
88
90
  ).pipe(
89
91
  Layer.provide(
@@ -122,6 +124,7 @@ export const providers = () =>
122
124
  Workers.FetchPolicyLive,
123
125
  Workers.WorkerProvider(),
124
126
  Workflows.WorkflowProvider(),
127
+ Zaraz.ZarazConfigProvider(),
125
128
  ),
126
129
  ),
127
130
  Layer.provideMerge(
@@ -81,7 +81,6 @@ export const makeDurableObjectBridge =
81
81
 
82
82
  return new Proxy(this, {
83
83
  get: (target, prop) => {
84
- console.log(target, prop, prop in target);
85
84
  const bind = (f: any) =>
86
85
  typeof f === "function" ? f.bind(target) : f;
87
86
  if (typeof prop !== "string") return bind((target as any)[prop]);