feat(spacetimedb): typed SpacetimeDB provider - #1044
Conversation
Adds a typed SpacetimeDB provider to Alchemy with Database, Generate, Project, SpacetimeAuthProject resources; Connect binding service; in-Worker DbConnection runtime; browser-side token persistence; per-database Connection tags. Local mode spawns 'spacetime dev --server-only'. 69 unit tests cover CLI helpers, HTTP client, runtime, naming, browsers, and the live provider.
Adds website/src/content/docs/spacetimedb/{index,getting-started}.mdx walking through Database → Generate → Worker → Vite SPA flow, auth setup, removal policy, and browser token persistence. Each step is one concept per heading (per AGENTS.md tutorial standard). Generated provider markdown under website/src/content/docs/providers/SpacetimeDB/ is gitignored and regenerated by 'bun docs:gen' from resource JSDoc.
Adds examples/cloudflare-spacetimedb-todo — an end-to-end todo app that wires SpacetimeDB.Database + Generate + Cloudflare Worker + Vite SPA in a single Alchemy Stack. Includes an activity table, ownership checks on reducers, and on_connect lifecycle. Gitignore keeps node_modules / .alchemy / generated module_bindings / spacetime config out of the working tree.
There was a problem hiding this comment.
Pull request overview
Adds a first-class SpacetimeDB provider to Alchemy, including typed resources/bindings, local-dev support, and a Cloudflare + SpacetimeDB todo example plus docs.
Changes:
- Introduce a new
packages/alchemy/src/SpacetimeDB/surface (resources, bindings, runtime helpers, auth provider, local provider sidecar entry). - Add extensive unit tests for the SpacetimeDB provider modules.
- Add new docs pages under
website/src/content/docs/spacetimedb/and a full example app underexamples/cloudflare-spacetimedb-todo/.
Reviewed changes
Copilot reviewed 51 out of 52 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| website/src/content/docs/spacetimedb/index.mdx | SpacetimeDB docs landing page introducing resources, local dev, auth, and removal policy. |
| website/src/content/docs/spacetimedb/getting-started.mdx | Step-by-step walkthrough for the Cloudflare + SpacetimeDB todo example. |
| packages/alchemy/test/SpacetimeDB/SpacetimeAuthProject.test.ts | Unit tests for the config-only SpacetimeAuth project resource/provider behavior. |
| packages/alchemy/test/SpacetimeDB/Runtime.test.ts | Tests for scoped connection lifecycle + timeout behavior in the runtime helper layer. |
| packages/alchemy/test/SpacetimeDB/Providers.test.ts | Tests for provider-layer composition and credential resolution helpers. |
| packages/alchemy/test/SpacetimeDB/Project.test.ts | Tests for generating spacetime.json and spacetime.local.json. |
| packages/alchemy/test/SpacetimeDB/LocalDatabase.test.ts | Tests for shell-quoting used by the local dev server runner. |
| packages/alchemy/test/SpacetimeDB/Host.test.ts | Tests for host normalization, websocket URI conversion, and env resolution. |
| packages/alchemy/test/SpacetimeDB/Database.test.ts | Tests covering the live HTTP provider behavior via an in-memory mock backend. |
| packages/alchemy/test/SpacetimeDB/ConnectBinding.test.ts | Tests for Connect binding tag identity and env key naming. |
| packages/alchemy/test/SpacetimeDB/Connect.test.ts | Tests for env key stability/disambiguation and database-name regex behavior. |
| packages/alchemy/test/SpacetimeDB/Client.test.ts | Tests for token decoding and client HTTP envelope/error mapping. |
| packages/alchemy/test/SpacetimeDB/Client.ops.test.ts | Tests for reducer calls, SQL calls, log retrieval, and log parsing behavior. |
| packages/alchemy/test/SpacetimeDB/Cli.test.ts | Tests for CLI argument shaping and CLI output parsing. |
| packages/alchemy/test/SpacetimeDB/Browser.test.ts | Tests for browser token persistence helper behavior. |
| packages/alchemy/src/Util/EnvName.ts | New shared env-key mangling helpers (also reused by Prisma). |
| packages/alchemy/src/SpacetimeDB/SpacetimeAuth.ts | New config-only SpacetimeAuth resource/provider with typed outputs for apps. |
| packages/alchemy/src/SpacetimeDB/Runtime.ts | Connection layer + Connection<C>(name) tag helper for runtime connection lookups. |
| packages/alchemy/src/SpacetimeDB/Providers.ts | Provider collection and layer wiring for SpacetimeDB resources + auth provider. |
| packages/alchemy/src/SpacetimeDB/Project.ts | Project resource/provider to materialize spacetime.json + local overrides. |
| packages/alchemy/src/SpacetimeDB/LocalDatabase.ts | Local (dev-mode) provider implementation that spawns spacetime dev --server-only. |
| packages/alchemy/src/SpacetimeDB/Local.ts | Sidecar entrypoint to host the long-running local dev process via RPC server. |
| packages/alchemy/src/SpacetimeDB/index.ts | SpacetimeDB package barrel exports. |
| packages/alchemy/src/SpacetimeDB/Host.ts | Host normalization + env resolution + websocket/dashboard URL helpers. |
| packages/alchemy/src/SpacetimeDB/Generate.ts | Generate resource/provider and module hashing utilities. |
| packages/alchemy/src/SpacetimeDB/DatabaseHttp.ts | Effect-native HTTP management client layer for a single database. |
| packages/alchemy/src/SpacetimeDB/Credentials.ts | Credential service + helpers to resolve token/host from env/profile/literal token. |
| packages/alchemy/src/SpacetimeDB/ConnectBinding.ts | Binding implementation that wires DB coordinates into Worker/Lambda bindings. |
| packages/alchemy/src/SpacetimeDB/Connect.ts | Connect binding contract + env-key derivation + Vite env helpers. |
| packages/alchemy/src/SpacetimeDB/Cli.ts | CLI runner + helpers for build/publish/generate/delete/lock/unlock + hashing utilities. |
| packages/alchemy/src/SpacetimeDB/Browser.ts | Browser-side helper for persisting identity tokens (no Effect dependency). |
| packages/alchemy/src/SpacetimeDB/AuthProvider.ts | AuthProvider integration for alchemy login and token/host configuration. |
| packages/alchemy/src/Prisma/Internal/EnvName.ts | Refactor Prisma env-name logic to reuse Util/EnvName.ts. |
| packages/alchemy/package.json | Export-map updates to add SpacetimeDB package entrypoints. |
| examples/cloudflare-spacetimedb-todo/worker/api.ts | Worker for upload + file serving (R2-backed) used by the todo example. |
| examples/cloudflare-spacetimedb-todo/vite.config.ts | Vite config for the example SPA. |
| examples/cloudflare-spacetimedb-todo/tsconfig.json | TypeScript config for the example project. |
| examples/cloudflare-spacetimedb-todo/src/styles.css | Styling for the example SPA. |
| examples/cloudflare-spacetimedb-todo/src/main.tsx | SPA bootstrap using SpacetimeDB React provider and generated bindings. |
| examples/cloudflare-spacetimedb-todo/src/App.tsx | Todo SPA UI wired to reducers/tables and optional attachment uploads. |
| examples/cloudflare-spacetimedb-todo/spacetimedb/tsconfig.json | TS config for the SpacetimeDB module sources in the example. |
| examples/cloudflare-spacetimedb-todo/spacetimedb/src/index.ts | SpacetimeDB module schema + reducers used by the todo example. |
| examples/cloudflare-spacetimedb-todo/spacetimedb/package.json | Module package manifest pinning spacetimedb dependency. |
| examples/cloudflare-spacetimedb-todo/spacetimedb/.gitignore | Ignores module build artifacts and deps. |
| examples/cloudflare-spacetimedb-todo/README.md | Example documentation and commands. |
| examples/cloudflare-spacetimedb-todo/package.json | Example app manifest and scripts. |
| examples/cloudflare-spacetimedb-todo/index.html | SPA HTML entrypoint. |
| examples/cloudflare-spacetimedb-todo/alchemy.run.ts | The example stack wiring SpacetimeDB + Cloudflare resources. |
| examples/cloudflare-spacetimedb-todo/.gitignore | Ignores local state, generated configs, and generated bindings. |
Suppressed comments (4)
packages/alchemy/src/SpacetimeDB/Cli.ts:304
Effect.genblocks are returningyield* new SpacetimeCliError(...)on non-zero exit. This should fail the effect viaEffect.fail(...), otherwise the error isn't propagated through the Effect error channel.
return yield* new SpacetimeCliError({
command: args.join(" "),
...result,
});
}
packages/alchemy/src/SpacetimeDB/Cli.ts:342
Effect.genblocks are returningyield* new SpacetimeCliError(...)on non-zero exit. Return anEffect.fail(...)so this path actually fails withSpacetimeCliError.
return yield* new SpacetimeCliError({
command: args.join(" "),
...result,
});
}
packages/alchemy/src/SpacetimeDB/Cli.ts:379
- On non-zero exit, this path also does
return yield* new SpacetimeCliError(...)which isn't an Effect. This should fail viaEffect.fail(...)so downstream code can catch/handleSpacetimeCliError.
return yield* new SpacetimeCliError({
command: args.join(" "),
...result,
});
}
packages/alchemy/src/SpacetimeDB/Cli.ts:449
renameViaClireturnsyield* new SpacetimeCliError(...)on failure; this should be anEffect.fail(...)so the function's effect fails correctly.
return yield* new SpacetimeCliError({
command: args.join(" "),
...result,
});
}
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
This needs to be in https://github.com/alchemy-run/distilled
cc @Mkassabov
|
Requested distilled SDK from this review comment. SpacetimeDB has no first-party OpenAPI; the HTTP management API is documented at https://spacetimedb.com/docs/http/ (and |
|
Distilled PR is up: alchemy-run/distilled#533 ( |
PR in case it's useful to the devs, close as "not planned" if needed. Code mirror lives in https://github.com/Cyberistic/alchemy-spacetimedb-provider
tested most functionalities in a real app, and fixed regressions found.
here's your ai slop summary:
SpacetimeDB provider — typed modules, bindings, and realtime connections as Alchemy resources.
A new
packages/alchemy/src/SpacetimeDB/package ships four resources, four binding services, and a runtime tag parameterized by name:SpacetimeDB.Databasepublishes a module to Maincloud (or a configured host). Defaults to retain so data is not deleted onalchemy destroy; opt in viadestroy().SpacetimeDB.Generaterunsspacetime generateto emit typed client bindings; module-content-hash aware so subsequent deploys detect stale clients.SpacetimeDB.Projectwritesspacetime.json+spacetime.local.jsonfor multi-database projects.SpacetimeDB.SpacetimeAuthProjecttracks an OIDC client config (config-only — the SpacetimeAuth dashboard is the source of truth for client provisioning).SpacetimeDB.Connectis aBinding.Servicethat hands a Worker env-var bundle (SPACETIMEDB_*_URI,_DATABASE_NAME,_TOKEN,_HOST,_DASHBOARD_URL) — the token makes in-WorkerDbConnections authenticated.Connection<C>("name")is aContext.Tagparameterized by name so two connections in one app don't collide.alchemy devboots a sidecar that runsspacetime dev --server-onlyon127.0.0.1:3000, watchingmodulePathfor hot-reload.SpacetimeDB.viteEnv(db)inlines coordinates into a Vite SPA bundle.69 unit tests cover CLI helpers, HTTP client, runtime, naming, browser token persistence, and the live provider (mocked HTTP).
Notable design choices
Databasedefaults toretain(same asGitHub.Repository); user-visible breaking change vs. adestroydefault — call it out in the release notes.envName/fnv1a64implementation inpackages/alchemy/src/Util/EnvName.tsis now shared bySpacetimeDB.ConnectandPrisma.Connect/Prisma.Connection(was duplicated).connect/refreshergonomics flow through aConnectbinding so a Worker gets a typed client without env-var gymnastics.Database.tswas shaping (HTTP + CLI); local mode spawns the dev server.Outstanding:
plans/014-local-and-live-test-suites.md, deferred — requires a live SpacetimeDB CLI + Maincloud token).website/src/content/docs/providers/SpacetimeDB/are gitignored per repo convention; CI regenerates them from resource JSDoc viabun docs:gen.SpacetimeAuthis config-as-code only — there is no public create API yet (beta).Run locally: