Storage
Copy page
import { postgresStorage, buildPostgresProvisionPlan } from "@nizhal/server/adapters";
const storage = postgresStorage({ connectionString: process.env.DATABASE_URL! });await storage.provision({ schema, syncRules });StorageAdapter interface
Section titled “StorageAdapter interface”getChanges— cursor pull with bucket scope, tombstones,removedBucketstransaction— atomic mutator executionclaimMutation/recordApplied— idempotent push + client-id reconciliationprovision— DDL from schema + sync rules
buildPostgresProvisionPlan returns raw SQL statements for inspection or CI diffing.
What provision creates
Section titled “What provision creates”updated_at/deleted_aton synced tables_nizhal_sync_controlloop-gate + per-table change log_nizhal_mutations— idempotency + client→server ID map_nizhal_tombstones— delete propagation_nizhal_client_buckets— scope tracking- Indexes for cursor scans
No logical replication. Runs on managed Postgres (Neon, RDS, Supabase) without superuser WAL settings.
nizhal migrate --config nizhal.config.jsSee CLI reference.
Custom adapters
Section titled “Custom adapters”StorageAdapter is the seam for alternate backends (D1/SQLite backlog). Phase 0 ships Postgres only; the interface exists so a second backend is a new adapter, not a rewrite.