winche_database 4.2.0
winche_database: ^4.2.0 copied to clipboard
Type-safe Dart client for Winche Database — an offline-first, real-time document store over a single WebSocket connection.
Changelog #
4.2.0 #
- Deletion reconciliation: server-side deletes are now tombstoned locally, so a
deleted document disappears from every listener,
get, and cache read and never resurfaces — online or offline. Adds thedeletedlisten-delta change kind and bumps the wire protocol to v2;listen/doc.listenframes now advertiseprotocol: 2, and the server only emitsdeletedto clients on v2. - Membership-based offline reads: each live query records the exact ordered set
of documents the server last reported for it (
TargetCache). Offline reads and a listener's cache-first emission serve that set against the cache + pending overlay, solimit/offset/ filter queries stay correct offline instead of re-deriving over the whole collection (which could resurface out-of-window or stale-but-locally-matching documents). - Resume across restarts: with durable persistence, listeners persist their
resume token (
ResumeTokenStore) and query membership. On relaunch a listener emits its last-known results immediately and resumes the server subscription with the stored token — going live without re-downloading when nothing changed, or taking a fresh snapshot when the token is stale. Newlisten.currentserver frame signals a covered resume (live and up to date, no documents). WithinMemory: true, resume state lasts only for the session. - Optional bounded cache: new
WincheDatabaseConfig.maxCachedDocumentsandcacheSizeBytescaps (both default null = unbounded). When a cap is exceeded the least-recently-used documents not referenced by an active listener or a pending write are evicted; an evicted document is re-fetched on next read (eviction is not deletion). Caps are also enforced against already-persisted documents on startup. See the README's "Cache management" section. - Conflict handling: under the automatic policies (
clientWins/serverWins), a write that can never be resolved — e.g. anupdateto a since-deleted document that always fails withNOT_FOUND— is now reported asWriteFailedand removed from the queue instead of being retried forever.
4.1.0 #
- Query parity with the server (PROTOCOL §4.1): added
QueryReference.offset(n)andQueryReference.limitToLast(n).offsetskips leading results and composes withlimit;limitToLastreturns the last N of the result window in ascending order, requires at least oneorderBy, and cannot be combined withlimitoroffset(validated locally, mirroring the server'sINVALID_ARGUMENT). Both are honoured for one-shot reads and livesnapshots()alike, since results are evaluated by the local query engine. - Write parity (PROTOCOL §3.2):
DocumentReference.set,WriteBatch.set, andTransaction.setnow acceptmergeFields— a dotted-path field mask. Only the masked paths are written; a masked path absent from the data deletes it. Mutually exclusive withmerge. The pending-write overlay applies the same mask semantics, so offline optimistic state matches the server. - Internal: the query and single-document live listeners now share a common
base, split by layer —
_LiveListener(facade: snapshots + cache overlay) and_LiveFeed(server-subscription lifecycle: reconnect/resume/teardown). The concrete types are_QueryListener/_DocumentListenerover_QueryFeed/_DocumentFeed, inlive_listener.dartandlive_feed.dart. No public API or behavior change.
4.0.0 #
- Breaking: the durable persistence backend is now sembast instead of
Hive.
HiveLocalStoreis removed and replaced bySembastLocalStore; thehive_cedependency is dropped in favour ofsembast/sembast_web. This removes Hive's 255-character key limit, so long/deeply-nested document paths are stored as-is. Persistence remains on by default, with the samedirectoryResolvercontract (required on native, ignored on web/IndexedDB). No data migration is provided.
3.0.0 #
- Breaking:
WriteBatch.setandTransaction.setnow accept typedT dataand convert it through the reference's converter, mirroringDocumentReference.set. Untyped references use the identity converter, so map-based call sites are unchanged; typed-converter call sites must now pass aTinstead of a pre-builtMap.
2.0.0 #
- Breaking:
WincheDatabasenow takes a singleWincheDatabaseConfig— connection options + local-store selection + conflict policy in one object, mirroringwinche_storage'sWincheStorageConfig. Replaces the previousWincheDatabase(ConnectionConfig, {store, inMemory, ...})constructor. - Breaking: persistence is now on by default (Hive). On native platforms a
directoryResolveris required; the Hive directory is resolved lazily on first store access (web uses IndexedDB, no path needed). SetinMemory: truefor the previous non-persistent behavior. directoryResolverlets the Hive directory be resolved lazily, so apps no longer need toawait HiveLocalStore.open(...)before constructing the database.- Added
LazyLocalStore, aLocalStoredecorator that opens its underlying store on first use (memoized; safe under concurrent first-callers). WincheDatabase.close()now also closes the database-owned local store.- Custom store injection moved to
WincheDatabase.withStore(connectionConfig, store).
1.1.0 #
ConnectionConfig.tokenProvidernow accepts an async callback (FutureOr<String> Function()), so auth tokens can be fetched or refreshed asynchronously on each (re)dial. Synchronous providers continue to work unchanged.
1.0.0 #
Initial release.
- Offline-first document store over a single WebSocket connection.
- Typed values: null, bool, int, double (incl.
NaN/Infinity), string, bytes, timestamp, reference, geo-point, arrays, and nested maps. - Writes: set / merge-set / update / delete with field transforms (increment, server timestamp, array union/remove, min/max) and preconditions.
- Queries: filters, ordering, limits, cursors, client-side projection (
select), andcount. - Real-time document and query listeners.
- Optimistic transactions with automatic retry.
- Local cache + pending-write overlay + background sync, backed by an in-memory or durable (Hive) store.
- Authentication at the WebSocket upgrade via an
?access_token=query parameter; token rotation by reconnect.