Skip to content
← Public packages

@kentcdodds/package-storage-migrations

Ordered idempotent packageStorage schema migrations + isolate-memoized runner. Caller always passes storage.

README.md

83 lines · 2.4 KB · Markdown

@kentcdodds/package-storage-migrations

Ordered, idempotent packageStorage schema migrations with an isolate-memoized runner for Worker boot / first request.

Intent

Package apps evolve KV-shaped documents in packageStorage(). This package gives a tiny, reusable contract: store an integer under a versionKey, run each up with version > current exactly once (ascending), and optionally wrap the work in createMigrationRunner so one isolate only pays the cost once.

Success looks like: pass the caller's packageStorage(), apply pending steps, re-run as a no-op, and keep product data out of this package's own bucket.

Prerequisites

  • A saved Kody package (so packageStorage() has provenance on the caller).
  • Callers always inject storage — this library never calls packageStorage() on the public API path.

Setup

import {
	runPackageStorageMigrations,
	createMigrationRunner,
} from 'kody:@kentcdodds/package-storage-migrations'
import { packageStorage } from 'kody:runtime'

const ensureSchema = createMigrationRunner({
	storage: packageStorage(),
	versionKey: 'my-app:schema-version',
	migrations: [
		{
			version: 1,
			name: 'notes-to-document',
			async up(storage) {
				const legacy = await storage.get('notes-v1')
				if (Array.isArray(legacy)) {
					await storage.set('notes', { items: legacy })
					await storage.delete?.('notes-v1')
				}
			},
		},
	],
})

await ensureSchema() // idempotent; safe on every request

Or one-shot without memoization:

await runPackageStorageMigrations({
	storage: packageStorage(),
	versionKey: 'my-app:schema-version',
	migrations: [/* ... */],
})

Critical: always pass the caller's packageStorage(). If this package called packageStorage() itself, writes would land in @kentcdodds/package-storage-migrations's bucket instead of yours. Only the optional ./smoke export may use this package's storage for self-test.

Exports

SpecifierUse
kody:@kentcdodds/package-storage-migrationsrunPackageStorageMigrations, createMigrationRunner, types, default
kody:@kentcdodds/package-storage-migrations/smokePost-publish self-test only

Done when

  • Callers import the runner, pass their storage, and see pending versions apply once.
  • Re-runs return applied: [] with the same toVersion.
  • Post-publish ./smoke returns { ok: true }.

License

MIT