TanStack

Content temporarily unavailable

State-stack mutation round: test gaps

Reviewed executable revision: f1a40e58d (base ef1e6a4aa). No production code changes.

How the gaps were found

A planned code-weight refactor of state.ts, sync.ts, and lifecycle.ts has nine prototype commits. Before porting them, 22 plausible porting mistakes were applied to unchanged main as source mutants. Each survivor of the db suite was then classified with a probe that passes on main and fails on the mutant, or with evidence that the mutant changes no public observation. Two survivors exposed bugs on main, which have separate repairs: a direct mutation confirmed inside its handler (#1986) and an update sent for an absent key (#1995). This change closes five survivors that were test gaps.

MutantWrong behavior that passed the suiteNew witness
B4A sync insert did not clear the key's pending local layers. After a confirmed insert, the next remote update reported $origin: 'local'.Optimistic-history grammar: source rows are written as insert for a key the source lacks.
B2A sync delete did not clear the key's pending local layers. A later source reinsert reported $origin: 'local'.Optimistic-history grammar: source deletes. Pinned replay of the random-campaign counterexample.
F2A sync write() after commit(), while the batch waited for persistence, joined the queued batch.Retention oracle: a write to a committed, waiting batch throws SyncTransactionAlreadyCommittedWriteError.
G4Cleanup with a pending subset load emitted a start transition.Cleanup/restart oracle: one end transition at cleanup.
H3Idle cleanup that rescheduled itself could not be canceled by a returning subscriber, so the Collection cleaned up early.New collection-idle-cleanup.test.ts, with a controllable browser idle scheduler.

Grammar change

Every optimistic-history source batch wrote update messages, which act as upserts. The production insert and delete apply paths never ran in those histories. The driver now tracks which keys the source holds, including queued batches, in write order:

  • A row for an absent key is written as insert. Later copies are updates.
  • A batch may carry deletes. Only keys the source holds apply.
  • The model receives the same resolved batch and removes deleted keys from its base. A source delete acknowledges no request.

A runtime witness requires 40 fixed-campaign histories to write source inserts and deletes. The extended grammar passes on main.

RunResult
Retention owner, B4 applied3 of 97 fail
Retention owner, B2 appliedthe pinned replay fails; the fixed campaign does not reach it
Retention owner, F2 applied1 of 97 fail
Cleanup/restart owner, G4 applied1 of 41 fail
Idle-cleanup owner, H3 applied1 of 1 fail

Survivors that change no observation

These were classified with evidence and need no witness. The port can delete the code under the last two.

  • A2 to A4: the truncate reapply search and filter are dead.
  • G1, G3, H2, I3: stale state that every reader ignores, or a cancellation that is a no-op on every reached history.
  • D1, D3: the recompute delete filter's inner branch ran 0 times in 7,871 tests and in targeted histories. Recompute keeps optimistic layers for keys with pending sync operations, so no such delete forms.

Limits

  • H3 depends on a browser idle scheduler. The suite's Node polyfill always reports a timed-out deadline.
  • Source deletes run only after a batch's rows. A delete before an insert of the same key in one batch is outside the grammar.
  • The driver drops a source delete for a key the source lacks, so the grammar never sends one. On a plain Collection, such a delete is a silent no-op. Its effect on an optimistic layer for the same key is unverified. The optimistic-history oracle owns that open cell; it needs the contract for the absent-key delete and a witness with an active and an accepted request on the key.
  • The idle-cleanup test needs per-file module isolation, the Vitest default. Without it, the binding check fails with an explicit error.
  • The fallback that derives previous $synced/$origin from completed request keys still has a survivor (see the absent-key insert review).

Verification

packages/db Vitest, typecheck off: 201 files, 7,862 tests. tsc --noEmit reports only the tests/conformance errors that need a built dist.