Collection conformance oracle suite: shared adapter laws for settlement, cancellation, readiness, reset, and ownership
Les mainteneurs répondent en général sous 1 jour
Personne n'a encore pris cette issue.
Évaluation
- Difficulté
- 5/5
- Temps estimé
- Plus d'une semaine
- Accessibilité débutants
- 38/100
- Type d'issue
- Fonctionnalité
- Clarté
- Plutôt claire
- Activité
- Active
- Stack technique
- typescript
- Domaine
- backend-api-design, testing
Piste de recherche
Start with docs/contributing/oracle-tests.md and the existing conformance suites in packages/db-collection-e2e and packages/db/tests/conformance/. For the first milestone, trace the Electric and query-db harnesses and the applied-settlement and cancellation observations through a live query and skipInitial Effect. Done means the three #2115 hostile fixtures fail at their intended checkpoints and both laws run against the two adapters.
Rédigé par le modèle d'indexation à partir du texte de l'issue.
Description
Summary
Add a shared conformance oracle suite that tests the contract between core and a collection adapter. The adapters in scope are Electric, query-db, TrailBase, PowerSync, RxDB, and any third-party sync implementation. Each adapter supplies a small harness. The suite then runs the same laws, histories, and checks against every adapter. It uses controlled transports in CI and can also run against real backends.
Why
Core decides when a live query is ready, when an Effect stops suppressing initial rows, and when a window may publish. It decides from signals the adapter gives it: loadSubset settlement, markReady(), applied receipts, aborts, truncates, and unloads. If an adapter sends a wrong signal, core shows a wrong result, even though core and the adapter's own tests both pass.
#2115 showed this directly. Its readiness fix made settled subset demand the readiness evidence for on-demand sources. Several adapter paths then turned out to break the settlement contract (ARCHITECTURE.md law 7: a successful load settles only after its rows are visible):
- Electric progressive: during a must-refetch before the first ready,
loadSubsetresolved at once without loading rows. A query became ready and empty. Only a code review found this. #2115 fixes it. - TrailBase on-demand:
loadcan finish before the change subscription starts, so a change between the fetch and the subscription can be lost. Only reading the code found this. - Electric resume: a resumed progressive stream settles loads at once because its local rows are complete by contract. A plausible "fix" broke that contract, and only Electric's own oracles caught it.
Every adapter now re-derives these rules in its own tests, in its own words. Nothing shows that each adapter keeps them.
Proposed design
Adapter harness
Each adapter provides a harness that:
- creates a Collection over a controlled transport, for example a scripted Electric
ShapeStream, a fake TanStack Query fetcher, or a TrailBase record API stub; - runs backend actions: insert, update, and delete rows; send a must-refetch or reset; resume from an offset; fail a request; delay a request;
- declares its capabilities: sync modes, cancellation support, resume, progressive buffering, ordered loading, txid confirmation, and persistence composition.
The suite uses the declared capabilities to choose which laws apply. A missing capability is an explicit, reviewed exclusion, not a silent skip. This also makes the concept from #2115 explicit: an adapter declares whether a source serves subset demand in each phase, instead of core inferring it from syncMode.
Laws (first set)
Each law needs an independent model, a legal history grammar, and public observations at named checkpoints, following docs/contributing/oracle-tests.md.
- Applied settlement. When
loadSubsetfulfills, every row that the request establishes is visible, or the source is ready and owns the authoritative absence. Histories: the buffered initial sync, a reset before and during a fetch, resume, retry after failure, and concurrent loads with overlapping predicates. - Cancellation. An aborted load rejects with
AbortError. A source that can cancel installs no request-scoped rows after it sees the abort. A source that cannot cancel declares that and settles its work. - Readiness meaning. For each sync mode, state what
markReady()promises. Examples: an eager source has applied its whole dataset, and a progressive source has completed its full sync. Check the promise at thereadytransition. - Freshness. After a load settles, the source delivers later changes to its rows. Any declared buffering window is a capability with a pinned observation, for example progressive buffering until the atomic swap.
- Reset and truncate. A must-refetch or truncate replaces state atomically behind the replay barrier. A failed reset keeps the last complete public state.
- Unload ownership.
unloadSubsetdoes not remove rows that another active demand still owns. Each physical acquisition gets one release. - Cleanup and restart. Cleanup aborts in-flight loads and runs no first-ready callbacks. A restart acquires its demand again through a fresh barrier.
- Mutation confirmation. For adapters with write handlers, confirmation helpers (
awaitTxId,awaitMatch, and others) resolve only after the confirming sync transaction applies.
Observation through core
Run every history through a real live query and a real skipInitial Effect, not only through the adapter's API. The law that matters to users is the composed one: when core reports ready, the rows are right. Use the Model D shapes from #2115 as the consumer side: direct, single result, ordered window, lazy join, and include.
Calibration
For each law, keep at least one hostile adapter fixture that breaks it. Each fixture must fail the suite at the intended checkpoint, not at setup or by timing out. The #2115 failures make good first fixtures:
- a load that resolves without rows during a reset;
- a load that resolves before its change subscription starts;
- a resume path that waits for the network although its local rows are complete.
Real-provider runs
The same laws should register in packages/db-collection-e2e for real backends where possible. That gives each controlled premise a receiving witness (ORC-014). It also gives the existing progressive registrations the phase and capability evidence that the coverage map says they lack.
Existing pieces to build on
packages/db-collection-e2e(shared real-backend suites)- The persisted conformance manifest (
packages/db-collection-e2e/src/fixtures/persisted-conformance-manifest.ts) - The framework conformance contract (
packages/db/tests/conformance/) - Model D (
packages/db/tests/query/includes-temporal-oracle.test.ts) and the Electric phase matrix (packages/electric-db-collection/tests/electric-live-query.test.ts)
Out of scope for the first version
- Performance and work budgets.
- Multi-process persistence (the SQLite owners cover it).
- Framework render timing (the framework conformance suite covers it).
First milestone
Implement law 1 (applied settlement) and law 2 (cancellation) with harnesses for Electric and query-db. Use the three #2115 hostile fixtures as calibration. Then add TrailBase and PowerSync, and record the TrailBase subscription gap as RED or as a declared capability.
- Langage dominant
- TypeScript
- Étoiles
- 3.9k
- Forks
- 272
- Merge moyen
- 1 j 1 h
- PR mergées (30 j)
- 235
Préparer son environnement
- Aucun Dockerfile ni fichier Docker Compose
- Propose un modèle de pull request
- Lire le guide de contribution
Par où commencer
- Lisez l'issue en entier, puis le guide de contribution du projet.
- Signalez en commentaire que vous la prenez — cela évite que deux personnes fassent le même travail.
- Forkez le dépôt et travaillez sur une branche.
- Ouvrez une pull request qui référence le numéro de l'issue.
Autres issues de TanStack/db
-
Difficulté 3/5 Une demi-journée Accessibilité débutants 62/100
Les mainteneurs répondent en général sous 1 jour
-
Difficulté 5/5 Plus d'une semaine Accessibilité débutants 8/100
Les mainteneurs répondent en général sous 1 jour
-
Difficulté 3/5 Une demi-journée Accessibilité débutants 58/100
Les mainteneurs répondent en général sous 1 jour
-
Difficulté 5/5 Plus d'une semaine Accessibilité débutants 5/100
TanStack/db#2139 · 1 commentaire ·
Les mainteneurs répondent en général sous 1 jour
-
Difficulté 4/5 3-5 jours Accessibilité débutants 25/100
Les mainteneurs répondent en général sous 1 jour
Toutes les issues de TanStack/db
Issues similaires
-
Difficulté 2/5 1-3 heures Accessibilité débutants 82/100
Les mainteneurs répondent en général sous 1 jour
-
high priority
Difficulté 2/5 1-3 heures Accessibilité débutants 62/100
CI-CMG/deep-sea-corals-exb#84 · 1 commentaire ·
-
Create/import wallet form shows raw "password must be at least 1 characters" instead of the translated messagePeut-être pris @CapThunder19 l’a pris aujourd’hui. Ouvertebug
Difficulté 2/5 1-3 heures Accessibilité débutants 82/100
joinmarket-webui/jam#1538 ·
Les mainteneurs répondent en général sous 1 jour
-
t0ggles
Difficulté 2/5 1-3 heures Accessibilité débutants 70/100
nolimits4web/swiper#8240 · 1 commentaire ·
-
Difficulté 2/5 1-3 heures Accessibilité débutants 82/100
Les mainteneurs répondent en général sous 1 jour