alchemy 2.0.0-beta.2 → 2.0.0-beta.test-export-fix-3

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 (65) hide show
  1. package/bin/{alchemy-effect.js → alchemy.js} +173 -173
  2. package/bin/alchemy.js.map +1 -0
  3. package/bin/{alchemy-effect.sh → alchemy.sh} +2 -2
  4. package/lib/cli/index.js +169 -169
  5. package/lib/cli/index.js.map +1 -1
  6. package/package.json +75 -67
  7. package/src/AWS/AGENTS.md +10 -10
  8. package/src/AWS/Assets.ts +1 -1
  9. package/src/AWS/Credentials.ts +0 -1
  10. package/src/AWS/DynamoDB/Table.ts +63 -10
  11. package/src/AWS/EC2/hosted.ts +1 -1
  12. package/src/AWS/ECS/Task.ts +1 -1
  13. package/src/AWS/Kinesis/Stream.ts +44 -8
  14. package/src/AWS/Lambda/Function.ts +218 -10
  15. package/src/AWS/S3/Bucket.ts +26 -19
  16. package/src/AWS/S3/BucketNotifications.ts +1 -1
  17. package/src/AWS/SNS/Topic.ts +47 -10
  18. package/src/AWS/SQS/Queue.ts +66 -0
  19. package/src/Cloudflare/Container/Container.ts +122 -0
  20. package/src/Cloudflare/Container/ContainerApplication.ts +6 -3
  21. package/src/Cloudflare/Container/ContainerBinding.ts +2 -4
  22. package/src/Cloudflare/Container/StartContainer.ts +1 -1
  23. package/src/Cloudflare/D1/D1Database.ts +23 -4
  24. package/src/Cloudflare/KV/KVNamespace.ts +25 -0
  25. package/src/Cloudflare/Providers.ts +1 -6
  26. package/src/Cloudflare/R2/R2Bucket.ts +45 -2
  27. package/src/Cloudflare/Website/StaticSite.ts +79 -6
  28. package/src/Cloudflare/Website/Vite.ts +67 -13
  29. package/src/Cloudflare/Workers/Assets.ts +170 -207
  30. package/src/Cloudflare/Workers/DurableObjectNamespace.ts +629 -0
  31. package/src/Cloudflare/Workers/DurableObjectState.ts +63 -0
  32. package/src/Cloudflare/Workers/DurableObjectStorage.ts +256 -0
  33. package/src/Cloudflare/Workers/DynamicWorkerLoader.ts +66 -7
  34. package/src/Cloudflare/Workers/InferEnv.ts +11 -7
  35. package/src/Cloudflare/Workers/Rpc.ts +13 -2
  36. package/src/Cloudflare/Workers/ScheduledEvents.ts +185 -0
  37. package/src/Cloudflare/Workers/WebSocket.ts +1 -1
  38. package/src/Cloudflare/Workers/Worker.ts +406 -49
  39. package/src/Cloudflare/Workers/Workflow.ts +53 -11
  40. package/src/Cloudflare/Workers/index.ts +4 -1
  41. package/src/Construct.ts +2 -2
  42. package/src/GitHub/Comment.ts +224 -0
  43. package/src/GitHub/Secret.ts +257 -0
  44. package/src/GitHub/Variable.ts +166 -0
  45. package/src/GitHub/index.ts +3 -0
  46. package/src/Kubernetes/client.ts +2 -2
  47. package/src/Output.ts +1 -1
  48. package/src/Platform.ts +1 -1
  49. package/src/Provider.ts +1 -1
  50. package/src/Test/Vitest.ts +4 -3
  51. package/src/Util/PlatformServices.ts +21 -0
  52. package/src/Util/dedent.ts +59 -0
  53. package/src/Util/index.ts +1 -0
  54. package/bin/alchemy-effect.js.map +0 -1
  55. package/src/Cloudflare/Workers/DurableObject.ts +0 -527
  56. package/src/Daemon/Client.ts +0 -116
  57. package/src/Daemon/Config.ts +0 -28
  58. package/src/Daemon/Errors.ts +0 -48
  59. package/src/Daemon/Lock.ts +0 -162
  60. package/src/Daemon/ProcessRegistry.ts +0 -284
  61. package/src/Daemon/RpcSchema.ts +0 -43
  62. package/src/Daemon/RpcServer.ts +0 -231
  63. package/src/Daemon/index.ts +0 -27
  64. package/src/Spawn.ts +0 -23
  65. /package/bin/{alchemy-effect.ts → alchemy.ts} +0 -0
@@ -57,18 +57,37 @@ export type D1Database = Resource<
57
57
  /**
58
58
  * A Cloudflare D1 serverless SQL database built on SQLite.
59
59
  *
60
+ * D1 is a serverless relational database that runs at the edge. Create a
61
+ * database as a resource, then bind it to a Worker to run SQL queries.
62
+ *
60
63
  * @section Creating a Database
61
- * @example Basic Database
64
+ * @example Basic database
62
65
  * ```typescript
63
- * const db = yield* Database("my-db", {});
66
+ * const db = yield* Cloudflare.D1Database("my-db");
64
67
  * ```
65
68
  *
66
- * @example Database with Location Hint
69
+ * @example Database with location hint
67
70
  * ```typescript
68
- * const db = yield* Database("my-db", {
71
+ * const db = yield* Cloudflare.D1Database("my-db", {
69
72
  * primaryLocationHint: "wnam",
70
73
  * });
71
74
  * ```
75
+ *
76
+ * @section Binding to a Worker
77
+ * @example Using D1 inside a Worker
78
+ * ```typescript
79
+ * const db = yield* Cloudflare.D1Connection.bind(MyDB);
80
+ *
81
+ * // Run a query
82
+ * const results = yield* db.prepare("SELECT * FROM users WHERE id = ?")
83
+ * .bind(userId)
84
+ * .all();
85
+ *
86
+ * // Execute a mutation
87
+ * yield* db.prepare("INSERT INTO users (id, name) VALUES (?, ?)")
88
+ * .bind(newId, name)
89
+ * .run();
90
+ * ```
72
91
  */
73
92
  export const D1Database = Resource<D1Database>("Cloudflare.D1Database");
74
93
 
@@ -30,6 +30,31 @@ export type KVNamespace = Resource<
30
30
  Providers
31
31
  >;
32
32
 
33
+ /**
34
+ * A Cloudflare Workers KV namespace for key-value storage at the edge.
35
+ *
36
+ * KV provides eventually-consistent, low-latency reads with global
37
+ * replication. Create a namespace as a resource, then bind it to a Worker
38
+ * to get/put values at runtime.
39
+ *
40
+ * @section Creating a Namespace
41
+ * @example Basic KV namespace
42
+ * ```typescript
43
+ * const kv = yield* Cloudflare.KVNamespace("MyKV");
44
+ * ```
45
+ *
46
+ * @section Binding to a Worker
47
+ * @example Using KV inside a Worker
48
+ * ```typescript
49
+ * const kv = yield* Cloudflare.KVNamespace.bind(MyKV);
50
+ *
51
+ * // Read a value
52
+ * const value = yield* kv.get("my-key");
53
+ *
54
+ * // Write a value
55
+ * yield* kv.put("my-key", "hello world");
56
+ * ```
57
+ */
33
58
  export const KVNamespace = Resource<KVNamespace>("Cloudflare.KVNamespace")({
34
59
  bind: KVNamespaceBinding.bind,
35
60
  });
@@ -10,7 +10,6 @@ import * as Containers from "./Container/index.ts";
10
10
  import * as D1 from "./D1/index.ts";
11
11
  import * as KV from "./KV/index.ts";
12
12
  import * as R2 from "./R2/index.ts";
13
- import * as Assets from "./Workers/Assets.ts";
14
13
  import * as Workers from "./Workers/index.ts";
15
14
  import * as Workflows from "./Workers/Workflow.ts";
16
15
 
@@ -60,11 +59,7 @@ export const providers = () =>
60
59
  ),
61
60
  ),
62
61
  Layer.provideMerge(
63
- Layer.mergeAll(
64
- Assets.AssetsProvider(),
65
- Build.CommandProvider(),
66
- RandomProvider(),
67
- ),
62
+ Layer.mergeAll(Build.CommandProvider(), RandomProvider()),
68
63
  ),
69
64
  Layer.provideMerge(
70
65
  Layer.mergeAll(
@@ -6,7 +6,7 @@ import { createPhysicalName } from "../../PhysicalName.ts";
6
6
  import * as Provider from "../../Provider.ts";
7
7
  import { Resource } from "../../Resource.ts";
8
8
  import { Account } from "../Account.ts";
9
- import type { Providers } from "../Providers.ts";
9
+ import type * as Cloudflare from "../Providers.ts";
10
10
  import { R2BucketBinding } from "./R2BucketBinding.ts";
11
11
 
12
12
  export type R2BucketName = string;
@@ -44,9 +44,52 @@ export type R2Bucket = Resource<
44
44
  accountId: string;
45
45
  },
46
46
  never,
47
- Providers
47
+ Cloudflare.Providers
48
48
  >;
49
49
 
50
+ /**
51
+ * A Cloudflare R2 object storage bucket with S3-compatible API.
52
+ *
53
+ * R2 provides zero-egress-fee object storage. Create a bucket as a resource,
54
+ * then bind it to a Worker to read and write objects at runtime.
55
+ *
56
+ * @section Creating a Bucket
57
+ * @example Basic R2 bucket
58
+ * ```typescript
59
+ * const bucket = yield* Cloudflare.R2Bucket("MyBucket");
60
+ * ```
61
+ *
62
+ * @example Bucket with location hint
63
+ * ```typescript
64
+ * const bucket = yield* Cloudflare.R2Bucket("MyBucket", {
65
+ * locationHint: "wnam",
66
+ * });
67
+ * ```
68
+ *
69
+ * @section Binding to a Worker
70
+ * @example Reading and writing objects
71
+ * ```typescript
72
+ * const bucket = yield* Cloudflare.R2Bucket.bind(MyBucket);
73
+ *
74
+ * // Write an object
75
+ * yield* bucket.put("hello.txt", "Hello, World!");
76
+ *
77
+ * // Read an object
78
+ * const object = yield* bucket.get("hello.txt");
79
+ * if (object) {
80
+ * const text = yield* object.text();
81
+ * }
82
+ * ```
83
+ *
84
+ * @example Streaming upload with content length
85
+ * ```typescript
86
+ * const bucket = yield* Cloudflare.R2Bucket.bind(MyBucket);
87
+ *
88
+ * yield* bucket.put("upload.bin", request.stream, {
89
+ * contentLength: Number(request.headers["content-length"] ?? 0),
90
+ * });
91
+ * ```
92
+ */
50
93
  export const R2Bucket = Resource<R2Bucket>("Cloudflare.R2Bucket")({
51
94
  bind: R2BucketBinding.bind,
52
95
  });
@@ -3,10 +3,17 @@ import { Command, type CommandProps } from "../../Build/Command.ts";
3
3
  import type { InputProps } from "../../Input.ts";
4
4
  import * as Namespace from "../../Namespace.ts";
5
5
  import type { AssetsConfig } from "../Workers/Assets.ts";
6
- import { Worker, type WorkerProps } from "../Workers/Worker.ts";
6
+ import {
7
+ Worker,
8
+ type WorkerAssetsConfig,
9
+ type WorkerBindingProps,
10
+ type WorkerProps,
11
+ } from "../Workers/Worker.ts";
7
12
 
8
- export interface StaticSiteProps
9
- extends Omit<WorkerProps, "assets">, Omit<CommandProps, "env"> {
13
+ export interface StaticSiteProps<Bindings extends WorkerBindingProps = {}>
14
+ extends
15
+ Omit<WorkerProps<Bindings, WorkerAssetsConfig>, "assets">,
16
+ Omit<CommandProps, "env"> {
10
17
  /**
11
18
  * Optional configuration for static asset routing behavior.
12
19
  * Supports `runWorkerFirst`, `htmlHandling`, `notFoundHandling`, etc.
@@ -19,12 +26,78 @@ export interface StaticSiteProps
19
26
 
20
27
  export type StaticSite = ReturnType<typeof StaticSite>;
21
28
 
22
- export const StaticSite = (id: string, props: InputProps<StaticSiteProps>) =>
29
+ /**
30
+ * A Cloudflare Worker that serves static assets built by a shell command.
31
+ *
32
+ * `StaticSite` runs a build command (e.g. `npm run build`), content-hashes
33
+ * the output directory, and deploys the result as a Cloudflare Worker with
34
+ * static assets. Use this when your site has its own build step that
35
+ * produces a directory of files — Hugo, Zola, Eleventy, or any custom
36
+ * pipeline.
37
+ *
38
+ * For Vite-based projects, prefer `Cloudflare.Vite` which handles
39
+ * building automatically.
40
+ *
41
+ * @resource
42
+ *
43
+ * @section Basic Usage
44
+ * Point `command` at your build script and `outdir` at where it writes
45
+ * output. Alchemy runs the command, hashes the output, and deploys it.
46
+ *
47
+ * @example Deploying a Hugo site
48
+ * ```typescript
49
+ * const site = yield* Cloudflare.StaticSite("Blog", {
50
+ * command: "hugo --minify",
51
+ * outdir: "public",
52
+ * });
53
+ * ```
54
+ *
55
+ * @section Asset Configuration
56
+ * Use `assetsConfig` to control how Cloudflare handles routing for
57
+ * your static files — HTML handling, not-found behavior, etc.
58
+ *
59
+ * @example SPA-style routing
60
+ * ```typescript
61
+ * const site = yield* Cloudflare.StaticSite("App", {
62
+ * command: "npm run build",
63
+ * outdir: "dist",
64
+ * assetsConfig: {
65
+ * htmlHandling: "auto-trailing-slash",
66
+ * notFoundHandling: "single-page-application",
67
+ * },
68
+ * });
69
+ * ```
70
+ *
71
+ * @section Custom Rebuild Scope
72
+ * By default, all non-gitignored files are hashed to decide whether
73
+ * the build should re-run. Use `memo` to narrow the scope.
74
+ *
75
+ * @example Narrowing the memo scope
76
+ * ```typescript
77
+ * const site = yield* Cloudflare.StaticSite("Docs", {
78
+ * command: "npm run build",
79
+ * outdir: "dist",
80
+ * memo: {
81
+ * include: ["content/**", "templates/**", "config.toml"],
82
+ * },
83
+ * });
84
+ * ```
85
+ */
86
+ export const StaticSite = <const Bindings extends WorkerBindingProps = {}>(
87
+ id: string,
88
+ props: InputProps<StaticSiteProps<Bindings>>,
89
+ ) =>
23
90
  Effect.gen(function* () {
24
91
  // TODO(sam): local dev/hmr support?
25
- const build = yield* Command("Build", props);
92
+ const build = yield* Command("Build", {
93
+ command: props.command,
94
+ cwd: props.cwd,
95
+ memo: props.memo,
96
+ outdir: props.outdir,
97
+ env: props.env,
98
+ });
26
99
 
27
- const worker = yield* Worker("Worker", {
100
+ const worker = yield* Worker<Bindings, WorkerAssetsConfig>("Worker", {
28
101
  ...props,
29
102
  assets: {
30
103
  path: build.outdir,
@@ -1,8 +1,15 @@
1
- import type { InputProps } from "../../Input.ts";
2
1
  import type { MemoOptions } from "../../Build/Memo.ts";
3
- import { Worker, type WorkerProps } from "../Workers/Worker.ts";
2
+ import type { InputProps } from "../../Input.ts";
3
+ import {
4
+ Worker,
5
+ type WorkerAssetsConfig,
6
+ type WorkerBindingProps,
7
+ type WorkerProps,
8
+ } from "../Workers/Worker.ts";
4
9
 
5
- export interface ViteProps extends Omit<WorkerProps, "vite" | "main"> {
10
+ export interface ViteProps<
11
+ Bindings extends WorkerBindingProps = {},
12
+ > extends Omit<WorkerProps<Bindings>, "vite" | "main"> {
6
13
  /**
7
14
  * Root directory passed to Vite's `root` option.
8
15
  * Defaults to the current working directory (`process.cwd()`).
@@ -21,22 +28,31 @@ export interface ViteProps extends Omit<WorkerProps, "vite" | "main"> {
21
28
  /**
22
29
  * A Cloudflare Worker deployed from a Vite project.
23
30
  *
24
- * `Vite` uses the Cloudflare Vite plugin to build both the server bundle and
25
- * client assets in a single `vite build` invocation — no manual `main`
26
- * entrypoint, build command, output directory, or Wrangler configuration
27
- * required.
31
+ * `Vite` uses the Cloudflare Vite plugin to build both the server bundle
32
+ * and client assets in a single `vite build` invocation — no manual
33
+ * `main` entrypoint, build command, output directory, or Wrangler
34
+ * configuration required.
28
35
  *
29
36
  * Input files are content-hashed (respecting `.gitignore` by default) so
30
37
  * unchanged projects skip the build and deploy entirely.
31
38
  *
39
+ * @resource
40
+ *
32
41
  * @section Deploying a Static Site
33
- * @example Basic Static Site
42
+ * For a pure static site (no SSR), a single call is all you need.
43
+ * Vite builds the project and Alchemy deploys the output as a
44
+ * Cloudflare Worker with static assets.
45
+ *
46
+ * @example Static Vite site
34
47
  * ```typescript
35
48
  * const site = yield* Cloudflare.Vite("Website");
36
49
  * ```
37
50
  *
38
- * @section Deploying a TanStack Start App
39
- * @example TanStack Start with SSR
51
+ * @section SSR Frameworks
52
+ * For SSR frameworks like TanStack Start, SolidStart, or Nuxt, enable
53
+ * `nodejs_compat` so the server bundle can use Node.js APIs.
54
+ *
55
+ * @example TanStack Start
40
56
  * ```typescript
41
57
  * const app = yield* Cloudflare.Vite("TanStackStart", {
42
58
  * compatibility: {
@@ -45,8 +61,43 @@ export interface ViteProps extends Omit<WorkerProps, "vite" | "main"> {
45
61
  * });
46
62
  * ```
47
63
  *
64
+ * @example SolidStart with worker-first routing
65
+ * ```typescript
66
+ * const app = yield* Cloudflare.Vite("SolidStart", {
67
+ * compatibility: {
68
+ * flags: ["nodejs_compat"],
69
+ * },
70
+ * assets: {
71
+ * config: { runWorkerFirst: true },
72
+ * },
73
+ * });
74
+ * ```
75
+ *
76
+ * @section Single-Page Applications
77
+ * For SPAs (React, Vue, etc.), configure asset handling so all
78
+ * routes fall back to `index.html`.
79
+ *
80
+ * @example Vue SPA
81
+ * ```typescript
82
+ * const app = yield* Cloudflare.Vite("Vue", {
83
+ * compatibility: {
84
+ * flags: ["nodejs_compat"],
85
+ * },
86
+ * assets: {
87
+ * config: {
88
+ * htmlHandling: "auto-trailing-slash",
89
+ * notFoundHandling: "single-page-application",
90
+ * },
91
+ * },
92
+ * });
93
+ * ```
94
+ *
48
95
  * @section Custom Rebuild Scope
49
- * @example Narrow the Memo Scope
96
+ * By default, every non-gitignored file is hashed to decide whether
97
+ * a rebuild is needed. Use `memo` to narrow the scope when your
98
+ * project has large directories that don't affect the build output.
99
+ *
100
+ * @example Narrowing the memo scope
50
101
  * ```typescript
51
102
  * const site = yield* Cloudflare.Vite("Docs", {
52
103
  * memo: {
@@ -55,8 +106,11 @@ export interface ViteProps extends Omit<WorkerProps, "vite" | "main"> {
55
106
  * });
56
107
  * ```
57
108
  */
58
- export const Vite = (id: string, props: InputProps<ViteProps> = {}) =>
59
- Worker(id, {
109
+ export const Vite = <const Bindings extends WorkerBindingProps = {}>(
110
+ id: string,
111
+ props: InputProps<ViteProps<Bindings>> = {},
112
+ ) =>
113
+ Worker<Bindings, WorkerAssetsConfig>(id, {
60
114
  ...props,
61
115
  main: undefined!,
62
116
  vite: {