コンテンツにスキップ

Migrations

plasma の schema 変更は deploy 前に生成します。Worker runtime は request path で table を作ったり照合したりしません。CLI で生成・レビュー・適用した artifact に対して sync traffic を処理します。

6 つの command があります:

Command 目的
plasma generate 次の SQL migration / snapshot / journal / manifest / schema version を生成する。
plasma generate --check artifact を再生成し、commit 済み artifact と byte-for-byte 比較する。
plasma generate --watch schema.ts を監視し、変更ごとに子 process で generate する。
plasma migrate deploy 未適用 SQL artifact を crash-safe lock と tracking table 付きで適用する。
plasma migrate status 適用済み row、現在の lock、artifact と DB の差分を表示する。
plasma migrate baseline 既存 DB を drift check 後に 0000_baseline として採用する。
plasma.config.ts
import { defineConfig } from "@sh1n4ps/plasma-cli/config"
export default defineConfig({
schema: "./src/shared/schema.ts",
out: "./plasma",
localDbPath: "./local.sqlite",
d1: {
accountId: process.env.CLOUDFLARE_ACCOUNT_ID,
databaseId: process.env.CLOUDFLARE_D1_DATABASE_ID,
apiToken: process.env.CLOUDFLARE_API_TOKEN,
},
})
src/shared/schema.ts
import { defineMutators, defineSchema, id, table, text } from "@sh1n4ps/plasma-core"
export const todos = table("todos", { id: id(), title: text() })
export const schema = defineSchema({ todos })
export const mutators = defineMutators<typeof schema, { userId: string }>()({})

初回生成:

Terminal window
plasma generate --name baseline

生成される構成:

plasma/
migrations/
0000_baseline.sql
meta/
0000_snapshot.json
_journal.json
_manifest.json
schema-version.ts

この directory 全体を commit します。生成された schema-version.ts が client と Worker の両方で使う SCHEMA_VERSION を export します。手動編集や手動 bump はしません。

Terminal window
plasma generate --schema ./src/shared/schema.ts --out ./plasma --name add-priority

初回 schema では baseline SQL を出します。2 回目以降は plasma/meta/_journal.json から最新 snapshot を読み、宣言 schema と mutator manifest から新 snapshot を構築し、diff / unsafe validation / size estimate を通したうえで artifact directory を atomic に差し替えます。

Terminal window
plasma generate --check --schema ./src/shared/schema.ts --out ./plasma

CI 用です。静的 validation と artifact drift 検出だけを行い、D1 credential は不要です。exit code は stable で、0 は一致、1 は validation/error、2 は drift です。

--check --probe は D1 に接続して batch limit を実測したい環境向けの opt-in です。

Terminal window
plasma generate --watch

watch mode は各 generate を子 process で実行するため、前回の schema import による TypeScript module cache が次回に漏れません。

Terminal window
# local smoke test
plasma migrate deploy --local --local-db ./local.sqlite
# production D1 REST API
plasma migrate deploy --wait 30

deploy は _plasma_migrations_plasma_migrations_lock を bootstrap し、lease を取得し、SQL batch の前に running row を記録します。その後 SQL と完了 update を別 batch で適用し、verifier がある場合は検証して、lease を解放します。失敗や crash は tracking table に残ります。

Terminal window
plasma migrate status --local --local-db ./local.sqlite
plasma migrate status --json

status は artifact journal と _plasma_migrations を比較し、現在の lock holder を表示します。JSON output は常に次の envelope です:

{ "version": "1", "exitCode": 0, "results": {}, "warnings": [], "errors": [] }
Terminal window
plasma migrate baseline --local --local-db ./existing.sqlite
plasma migrate baseline --force

baseline は既存 DB を introspect し、宣言 schema と比較して、drift があれば --force なしでは拒否します。0000_baseline.sql / snapshot / journal / manifest と、将来の deploy が baseline 適用済みと判断できる self-recording _plasma_migrations insert を生成します。

生成は、データ損失、IndexedDB semantic の破壊、sync protocol の曖昧化につながる変更を拒否します。table / column drop、kind 変更、nullable から NOT NULL、unique 追加、mutator 必須 arg 追加、mutator manifest 未宣言、暗号化 key 変更、ref().onDelete semantic 変更が対象です。--force は、別途データ移行済みの場合に限って使い、refuse を warning に降格します。

D1 は送信済み batch を abort できないため、deploy runner は 2 batch model です:

  1. tracking / lock table を毎回 bootstrap。
  2. _plasma_migrations_lock を compare-and-swap lease で取得。
  3. migration SQL batch の外で running row を insert。
  4. migration statements と applied update を 1 batch で適用。
  5. post-apply verification 後に verified または verified_mismatch へ更新。
  6. 次回起動時、古い running row は failed にする。--force なら idempotent retry を試みる。

heartbeat が lock loss を検出したら次の migration は発行しません。ただし in-flight D1 batch は完了を待つため、2 つの runner が同時に進む状態を避けます。

各 snapshot は shape / mutators / auth / protocol / conflict の 5 つの独立 SHA-256 hash を持ちます。その JCS canonical composite hash の先頭 16 hex が SCHEMA_VERSION です。journal には内訳も保存されるため、drift report はどの次元が変わったかを示せます。

server は minClientVersion を設定できます。新規 project は、generated schema version、"keep" mismatch handling、hash breakdown、IDB migration diagnostics を理解する最初の client line として、少なくとも 1.0.0 を要求することを推奨します。

pull した schema version が local IndexedDB metadata と違う場合、client は次の 4 分岐で判断します:

分岐 結果
outbox 空 + local cache 互換 metadata を migrate して続行。
outbox 空 + local cache 非互換 local state を自動 reset。
pending outbox + app が "reset" を返す local state を捨て server truth から再開。
pending outbox + app が "keep" を返す IDB を保持し、user action required として mismatch を表面化。
createPlasmaClient({
schema,
mutators,
endpoint: "/sync",
schemaVersion: SCHEMA_VERSION,
onSchemaMismatch: async (info) => {
if (info.outboxCount === 0) return "reset"
return "keep"
},
})
  • plasma artifacts are missingplasma generate を実行し、plasma/ directory を commit します。
  • generated artifacts differ from committed artifactsplasma generate を実行し、SQL / snapshot diff を review して commit します。
  • migration generation refused — JSON の errors[].details を確認し、schema を additive にするか、手動 data migration 後に --force を使います。
  • previous migration deploy crashed_plasma_migrations.logs を確認し、SQL が idempotent と判断できる場合のみ --force で再実行します。
  • D1 credentials requiredgenerate --check は credential 不要です。migrate deploy--local でない限り必要です。