Skip to content

Validation & testing

Copy page

Nizhal validates sync with adversarial emulation — not only happy-path unit tests.

apps/emulation runs 19 scenarios against a real createNizhalServer + N createNizhalClient instances with failure injectors:

  • Network partition / delayed push
  • Server restart mid-outbox
  • Dropped realtime (SYNC-5 — pull.intervalMs converges)
  • Garbage cursor (cursorReset)
  • Poison mutation dead-letter + cascade-cancel
  • Revoked membership eviction
  • Concurrent POS inventory races
  • Credit-ledger balance fold invariants

Default DB: PGlite. Set NEON_URL for managed Postgres.

Current status: 19/19 PASS on PGlite (see rfcs/RFC-004-findings.md).

research/phase2/offline-first-testing-and-transports.md defines a 30-scenario matrix covering transports (web↔mobile), persistence drivers, and tenancy edge cases. Scenarios map to TS harness rows in apps/emulation.

  • ConvergenceassertInvariants diffs all clients vs server row sets (strips TanStack metadata + timestamp columns)
  • Exactly-once — replay entire outbox twice → byte-identical server state
  • No poison wedge — queue drains after deterministic failure
AreaEvidence
Multi-device weblive-e2e, emulation harness
op-sqlite on deviceapps/op-sqlite-probe iOS simulator
Managed PostgresNEON_URL chaos + neon-smoke
CF realtimepackages/server/examples/cf-e2e-smoke.ts
RN native WS + fetch@nizhal/react-native README path

op-sqlite JSI — native only. Emulation uses wa-sqlite WASM / node:sqlite for the same persistence code paths; literal op-sqlite binary requires simulator/device (RFC-004 scope split).

Terminal window
pnpm install && pnpm build && pnpm test && pnpm chaos

Unit tests (~64+) stay in pnpm test; chaos is heavier and separate.