import { StoreBuilder, StoreUpdater } from "./builder.store" import type { ExtantKey, MigrationDef, MigrationFn, RowConstraint, SchemaConstraint, Simplify, StoreDef, UnusedKey, VersionDef } from "./schema" export class VersionBuilder { #stores: Map> #migrations: MigrationDef[] constructor(previousStores: Map> = new Map()) { this.#stores = new Map(previousStores) this.#migrations = [] } create(name: UnusedKey) { if (this.#stores.has(name)) throw new Error(`cannot create store ${name} - already exists`) return (callback: (b: StoreBuilder) => StoreBuilder) => { const builder = callback(new StoreBuilder()) const created = builder.build(name) this.#stores.set(name, created) this.#migrations.push(['create', name, created]) return this as unknown as VersionBuilder> } } update(name: ExtantKey) { const extant = this.#stores.get(name) if (extant == null) throw new Error(`cannot update store ${name} - does not exist`) return (callback: (u: StoreUpdater) => StoreUpdater) => { const updater = new StoreUpdater(extant as any) const updated = callback(updater).build() this.#stores.set(name, updated) this.#migrations.push(['update', name, updated]) return this as unknown as VersionBuilder & {[K in Name]: NewRow}>> } } drop(name: Name): VersionBuilder> { this.#stores.delete(name) this.#migrations.push(['drop', name]) return this as unknown as VersionBuilder>> } migrate< WriteOverrides extends SchemaConstraint, OverriddenSchema extends SchemaConstraint = Simplify & WriteOverrides> >(cb: MigrationFn): VersionBuilder { this.#migrations.push(cb) return this as unknown as VersionBuilder } build(): VersionDef> { return { stores: this.#stores, migrations: this.#migrations, __schema: undefined as unknown as Schema, } } }