← Public packages
@kentcdodds/package-storage-migrations
Ordered idempotent packageStorage schema migrations + isolate-memoized runner. Caller always passes storage.
src/smoke.ts
86 lines · 2.2 KB · TypeScriptimport { packageStorage } from 'kody:runtime'
import {
createMigrationRunner,
runPackageStorageMigrations,
} from './index.ts'
/**
* Post-publish smoke against **this** package's `packageStorage()` bucket only.
*
* Application / product code must pass the **caller's** storage into
* `runPackageStorageMigrations` / `createMigrationRunner` — never rely on this
* smoke path for product data.
*
* @returns Projection asserting first-run applies, second-run is idempotent,
* and the isolate runner shares one promise.
*
* @example
* import smoke from 'kody:@kentcdodds/package-storage-migrations/smoke'
* const result = await smoke()
*/
export default async function smoke() {
const storage = packageStorage()
const versionKey = '__psm_smoke:schema-version'
const legacyKey = '__psm_smoke:notes-v1'
const notesKey = '__psm_smoke:notes'
await storage.delete?.(versionKey)
await storage.delete?.(notesKey)
await storage.set(legacyKey, [
{ id: 'a', text: 'hi', createdAt: '2026-01-01T00:00:00.000Z' },
])
const migrations = [
{
version: 1,
name: 'notes-to-document',
async up(s: {
get(key: string): Promise<unknown>
set(key: string, value: unknown): Promise<void>
delete?(key: string): Promise<void>
}) {
const legacy = await s.get(legacyKey)
if (Array.isArray(legacy)) {
await s.set(notesKey, { items: legacy })
await s.delete?.(legacyKey)
}
},
},
]
const first = await runPackageStorageMigrations({
storage,
versionKey,
migrations,
})
const second = await runPackageStorageMigrations({
storage,
versionKey,
migrations,
})
const ensure = createMigrationRunner({ storage, versionKey, migrations })
const third = await ensure()
const fourth = await ensure()
const notes = (await storage.get(notesKey)) as { items?: unknown } | undefined
const legacyGone = (await storage.get(legacyKey)) == null
const ok =
first.fromVersion === 0 &&
first.toVersion === 1 &&
first.applied.length === 1 &&
second.applied.length === 0 &&
second.toVersion === 1 &&
third.applied.length === 0 &&
fourth === third &&
Array.isArray(notes?.items) &&
legacyGone
return {
ok,
first,
secondApplied: second.applied.length,
sharedEnsure: third === fourth,
legacyGone,
}
}