@molecule/api-project-archive-external-state-d1
Provider bond · project-archive-external-state · API (Node) · v1.0.4 · Apache-2.0
Captures and restores a project's Cloudflare D1 databases via wrangler, so archiving a Workers project does not silently drop its data.
npm install @molecule/api-project-archive-external-state-d1npm · Source on GitHub · Implements @molecule/api-project-archive
How it works
@molecule/api-project-archive-external-state-d1 is a provider bond on the API (Node) side: it implements the project-archive-external-state core interface (@molecule/api-project-archive) with a concrete vendor or library behind it.
Your code calls the core; you wire this provider once at startup. Swapping vendors later is one line in that wiring, not a rewrite.
import { setExternalStateProvider } from '@molecule/api-project-archive'
import { createD1ExternalStateProvider } from '@molecule/api-project-archive-external-state-d1'
setExternalStateProvider(
createD1ExternalStateProvider({
// A DECLARATION of what the project owns — never a lookup.
databaseNames: (projectId) => [`mol_${projectId}`],
}),
)Works with: @molecule/api-project-archive
Reference
@molecule/api-project-archive-external-state-d1 — captures and restores a
project's Cloudflare D1 databases so archiving a Workers project does not
silently drop its data.
@molecule/api-project-archive destroys the original once result.verified
is true. State whose provider was never written is captured by nobody,
verifies clean, and is then permanently deleted — so every state-owning
provider bond needs one of these. This is D1's.
Capture shells out to wrangler d1 export, for the same reason the Postgres
bond shells out to pg_dump: only the engine that owns the data can produce a
consistent snapshot with schema, indexes and constraints intact.
Auto-generated, AI-first package reference for the molecule.dev ecosystem. It is written to be read by coding agents as much as by people, and is generated from this package's source — edit
src/index.tsJSDoc, not this file.
Quick Start
import { setExternalStateProvider } from '@molecule/api-project-archive'
import { createD1ExternalStateProvider } from '@molecule/api-project-archive-external-state-d1'
setExternalStateProvider(
createD1ExternalStateProvider({
// A DECLARATION of what the project owns — never a lookup.
databaseNames: (projectId) => [`mol_${projectId}`],
}),
)
Type
provider
Installation
npm install @molecule/api-project-archive-external-state-d1 @molecule/api-project-archive
API
Interfaces
D1ExternalStateConfig
How this deployment finds a project's D1 databases.
interface D1ExternalStateConfig {
/**
* The D1 database NAMES belonging to `projectId`, as `wrangler` knows them.
*
* **This is a DECLARATION, not a search.** An empty array means the project
* genuinely owns none — and it is the ONLY way to say that. Asking Cloudflare
* "which databases does this project have?" cannot distinguish "none" from
* "this API token cannot see them", and the caller DESTROYS the project on a
* successful capture, so an inferred absence deletes live data. A name that is
* listed but does not exist is an ERROR, never an absence.
*
* @param projectId - The project being archived or restored.
* @returns Its D1 database names; `[]` when it owns none.
*/
databaseNames: (projectId: string) => readonly string[] | Promise<readonly string[]>
/**
* The `wrangler` executable. Defaults to `wrangler`.
*
* Capture needs D1's own tooling for the same reason `pg_dump` cannot dump
* MySQL: the export has to come from the engine that owns the data.
*/
wranglerPath?: string
/**
* Extra arguments appended to every `wrangler` invocation — typically
* `['--config', 'wrangler.toml']` or an account selector.
*
* Credentials are NOT passed here. `wrangler` reads `CLOUDFLARE_API_TOKEN` /
* `CLOUDFLARE_ACCOUNT_ID` from the environment, and a token in argv is visible
* in `ps` to every user on the host.
*/
wranglerArgs?: readonly string[]
/**
* Operate on the deployed (remote) database rather than the local emulator.
* Defaults to `true`.
*
* The default is deliberate: `wrangler d1 export` without `--remote` dumps the
* LOCAL miniflare database, which in production is empty. Defaulting to local
* would produce a clean, successful, zero-row capture — and then the caller
* would destroy the real one.
*/
remote?: boolean
}
Functions
createD1ExternalStateProvider(config)
Create the provider.
function createD1ExternalStateProvider(config: D1ExternalStateConfig): ProjectExternalStateProvider
config— How to find a project's D1 databases.
Returns: A provider ready to bond with setExternalStateProvider.
Constants
KIND
Recorded on every record this provider produces; routes restores back here.
const KIND: 'd1'
Core Interface
Implements @molecule/api-project-archive interface.
Injection Notes
Requirements
Peer dependencies:
@molecule/api-project-archive^1.0.1
Runtime Dependencies
-
@molecule/api-project-archive -
databaseNamesdeclares; it must never search. Asking Cloudflare which databases a project has cannot distinguish "none" from "this token cannot see them", and the caller destroys the project on a successful capture. An empty array is the only way to say "owns nothing"; a listed name that does not exist is an error. -
remotedefaults totrue, deliberately.wrangler d1 exportwithout--remotedumps the LOCAL miniflare database, which in production is empty. Defaulting to local would yield a clean, successful, zero-row capture — and then the caller would destroy the real database. -
A zero-byte export is treated as a failure, not an empty database.
d1 exportalways emits at least schema statements, so zero bytes means the export did not happen (wrong name, wrong account, silent auth failure). -
Credentials come from the environment, never argv.
wranglerreadsCLOUDFLARE_API_TOKEN/CLOUDFLARE_ACCOUNT_ID; a token in argv is visible inpsto every user on the host.wranglerArgsis for--configand similar, not secrets.