npm rxdb 17.2.0

6 hours ago

JavaScript Database

  • ADD React useRxDocument(collection, primaryKey) hook for subscribing to a single document by primary key with live updates
  • ADD React useReplicationStatus(replicationState) hook that exposes syncing, error, lastSyncedAt, and canceled from replication observables
  • DOCS Mark liveQueryUpdateThrottleTime as a beta feature in the documentation
  • DOCS Move the main liveQueryUpdateThrottleTime documentation to rx-query.md; rx-database.md and rx-collection.md now only list the option with a short description and a link
  • FIX allAttachments$ observable emitting a new value on every document revision even when the set of attachments is unchanged, by filtering emissions with distinctUntilChanged based on attachment ids and digests
  • FIX RxAttachment.remove() not cleaning up binary attachment data from storage, because categorizeBulkWriteRows() only iterated over the new document's _attachments and never detected attachments removed between revisions
  • FIX attachments-compression isCompressibleType() not stripping RFC 2045 parameters (e.g. ; charset=utf-8) from MIME types, causing attachments with a charset-qualified type like application/json; charset=utf-8 to silently bypass compression when matched against exact patterns like application/json
  • FIX backup plugin not removing the folder of a deleted document when the change batch only contained deletions, because findByIds() returned an empty map and the loop exited early before running the deletion handler
  • FIX RxCollection.cleanup() returning undefined instead of boolean as declared by its TypeScript return type, because the cleanup plugin implementation did not return the result from cleanupRxCollection()
  • FIX CRDT plugin bulkInsert hook not including the composite primary key in CRDT operations, causing the primary key field to be lost during conflict resolution rebuild for schemas that use a composite primary key
  • ADD dev-mode check (SC43) to prevent encrypted fields from being nested inside other encrypted fields. When a parent path is encrypted, the entire object is encrypted so child paths must not be listed separately in the encrypted array.
  • FIX findByIds() query operations modify(), patch(), incrementalModify(), incrementalPatch(), and incrementalRemove() returning an Array instead of a Map. Also fix findByIds().remove() crashing with TypeError: docs.remove is not a function because it did not handle the Map return type from findByIds().
  • FIX getJsonSchemaWithoutMeta() not removing internal meta field references (_deleted, _meta.lwt) from indexes, while correctly removing them from properties and required, causing the returned schema to be internally inconsistent
  • FIX getLocal() returning a deleted local document from the document cache instead of null, causing inconsistent behavior between cache hits and storage lookups after a local document is removed
  • FIX replication-google-drive plugin requesting etag in the Google Drive v3 list API fields parameter, which is rejected by the real API; etag is now fetched separately via the v2 API
  • FIX RxLocalDocument.get$() on nested object/array paths emitting spurious values when unrelated document fields changed, because distinctUntilChanged() used reference equality which always fails for non-primitive values across document revisions
  • FIX database-level RxLocalDocument.$ observable emitting events from a collection-level local document that shares the same id, because the filter on the database event stream only checked isLocal and did not exclude events that originated from a collection
  • FIX localstorage storage remove() not deleting attachment data from localStorage, causing orphaned attachment entries to remain after the storage instance is removed
  • FIX schema migration not forwarding _attachments across chained migration strategies, so later strategies received the document with _attachments as undefined when an earlier strategy returned a new object without forwarding them, breaking the WithAttachments<DocData> contract and preventing strategies from reading or mutating attachment metadata as described in the docs
  • FIX schema migration losing attachments when the migration strategy returns a new object, because migrateDocumentData() never restored _attachments after running the strategies while _meta and _deleted were restored
  • FIX RxMigrationState.migratePromise() returning count.percent: 0 instead of 100 when the migration status is DONE and no migration was needed, which is inconsistent with the updateStatus() logic that correctly sets percent to 100 when total is 0
  • FIX ORM attachment-method names conflicting with built-in RxAttachment methods (getData, getStringData, getDataBase64, remove) not being validated, silently shadowing the built-in method on every attachment instance and preventing users from retrieving their attachment data. Dev-mode now throws a clear RxError (COL17) during collection creation.
  • FIX ORM document method names conflicting with schema-generated suffixed getters (field$, field$$, field_) not being validated, causing a TypeError crash at runtime instead of a clear RxError (COL18) during collection creation
  • FIX RxDatabase.password being an enumerable property, which could leak the plaintext password through Object.keys(), object spreading, Object.assign(), or JSON.stringify() in logging and error reporting contexts
  • FIX RxPipeline error state blocking unrelated reads on the destination collection, because the pipeline's waitBeforeWriteFn hook always called awaitIdle() which re-throws the stored handler error forever. After a handler throws, reads on the destination collection now proceed normally instead of re-throwing the pipeline error.
  • FIX RxPipeline deadlock when multiple pipelines share the same destination collection and their handlers read from the destination, because each pipeline's waitBeforeWriteFn only recognized its own flagged function name in the stack instead of any pipeline's flagged function prefix
  • FIX RxDocument.populate() throwing DOC6 for array fields when ref is defined on items instead of on the array field itself, even though createRxSchema accepts both patterns
  • FIX RxDocument.populate() silently returning null for invalid schema paths and non-ref fields when the value at that path was falsy. The documented DOC5 / DOC6 errors are now thrown consistently, regardless of whether the document has a value at the given path.
  • FIX populate() on array ref fields returning documents in wrong order when two documents reference the same set of IDs in different order, because findByIds query cache deduplication reused a cached query whose Map iteration order matched the first caller instead of preserving each document's own ref array order
  • FIX query-builder operators (gt, lt, ne, in, etc.) silently dropping the implicit $eq condition when a selector shorthand value (e.g. { age: 5 }) was used and then another operator was chained on the same field via the query-builder API
  • FIX default cache replacement policy not evicting executed unsubscribed queries when subscribed queries caused the total cache size to exceed tryToKeepMax, because the eviction count was calculated from only the unsubscribed query count instead of the total cache size
  • FIX React hooks useRxQuery and useLiveRxQuery initializing loading state as false instead of true, causing components to briefly render with empty results before the query resolved #8292
  • FIX remote storage remove() not unsubscribing from internal subscriptions and not completing the changeStream() observable, unlike close() which correctly performs both cleanup steps
  • FIX replication upstream marking documents as successfully pushed when the replication is paused during a push retry, because masterWrite() returns an empty conflicts array on pause and the upstream updates the meta instance and checkpoint without verifying the push actually succeeded, causing those documents to never be retried on resume
  • FIX replication sent$ observable emitting documents in the master format (with the user-defined deletedField) instead of the typed WithDeleted<RxDocType> format (with _deleted: boolean), because the deletedField swap mutated the same row object that was later forwarded to subscribers
  • FIX replication sent$ observable emitting null for documents that were filtered out by a push.modifier returning null, violating its Observable<WithDeleted<RxDocType>> type and falsely reporting filtered documents as sent to the endpoint
  • FIX RxState _cleanup() not returning true on completion, causing the cleanup plugin loop to never terminate and run indefinitely
  • FIX RxState $ observable emitting duplicate and stale values on each write because both _ownEmits$ and collection.eventBulks$ triggered emissions for own-instance events
  • FIX RxState.get$() (and the field$ proxy accessor) emitting a stale value when subscribed after the state was modified, because startWith() eagerly captured the current value at observable creation time instead of at subscription time
  • FIX(types) RxDocument.collection losing the Reactivity generic because it was passed as the third type argument to RxCollection (which is StaticMethods) instead of the fifth, causing doc.collection.find().$$ and similar calls to be typed as the default reactivity instead of the user's custom reactivity type
  • FIX RxDocument.$ observable emitting stale document state when subscribed after the document was modified, because startWith() eagerly captured the latest data at observable creation time instead of at subscription time
  • FIX RxState.set() permanently breaking the write queue when a user-supplied modifier throws, causing all subsequent set() calls to reject with an unrelated SNH error instead of performing the write
  • FIX storage query() returning all matching documents when the caller passes limit: 0 in the mango query, because the truthy check query.limit ? query.limit : Infinity treated 0 as "no limit was set" (affects memory, dexie, localstorage, foundationdb, denokv, sqlite-trial, mongodb storages and the query-builder plugin).
  • FIX getStartIndexStringFromLowerBound() and getStartIndexStringFromUpperBound() using space character (\x20) as the minimum boundary for string index fields, causing documents with string values containing control characters (codepoints below 32, e.g. \t, \n) to fall below the index scan range and be silently excluded from query results and counts
  • FIX WebMCP changes tool returning documents with internal meta fields (_meta, _rev, _attachments, _deleted) instead of stripping them like the query, insert, upsert, and delete tools do via toJSON()

RxDB Server

  • FIX invalid CORS response when the server is configured with the default cors: '*'. The express adapter always sends Access-Control-Allow-Credentials: true, but combining that with Access-Control-Allow-Origin: * is rejected by browsers per the CORS spec, so credentialed (cookie/auth-header) requests from any cross-origin client would fail. The adapter now reflects the request Origin back when cors is '*', keeping the "allow from anywhere" semantics while staying compatible with credentials.
  • FIX false conflicts during replication push when a serverOnlyField is absent from the stored server document (e.g. because the field is optional and was never set). mergeServerDocumentFieldsMonad previously wrote a null value for the missing field onto the merged assumedMasterState, so the extra key caused masterWrite's isEqual check to report a conflict that did not actually exist, silently reverting the client's update. The helper now deletes the property in that case so the merged row matches the stored master state.
  • FIX replication pull URL not URL-encoding the checkpoint id. When a document's primary key contained URL-reserved characters (for example &, #, =), the URL was parsed incorrectly on the server, causing the checkpoint to be truncated. With batchSize: 1 this could make the pull loop never advance past such a document. The client now encodes the id with encodeURIComponent.
  • FIX replication /push endpoint allowing clients to populate serverOnlyFields when inserting NEW documents. mergeServerDocumentFieldsMonad returned the client document unchanged when no server-side document existed yet, so a client-supplied value for a server-only field was passed through to replicationHandler.masterWrite() and persisted on the server. The merge now strips server-only fields from the client document when the server has no prior state for it, matching the documented contract that clients cannot do writes where one of the serverOnlyFields is set. The REST /set endpoint already stripped these fields explicitly, so it was unaffected.
  • FIX conflict handling for new documents pushed via replication when serverOnlyFields are configured. mergeServerDocumentFieldsMonad incorrectly transformed a falsy assumedMasterState (used for new document inserts) into an object and set server-only fields to null on newDocumentState, causing schema validation failures and false conflicts.
  • FIX replication /push endpoint allowing clients to populate serverOnlyFields when inserting NEW documents. Updates of existing documents already preserved the stored server value via mergeServerDocumentFields, but inserts (no assumedMasterState / no existing serverDoc) passed the client document straight into masterWrite, so any value the client sent for a server-only field was persisted. The handler now strips server-only fields from the new document state on insert, matching the behavior of the REST /set endpoint and the documented contract that clients cannot do writes where one of the serverOnlyFields is set.
  • FIX missing await in RxRestClient.get(), RxRestClient.set(), and RxRestClient.delete() methods. The postRequest() call was not awaited before calling handleError(), which caused server errors (e.g. 403 Forbidden from changeValidator) to be silently swallowed instead of thrown to the caller.
  • FIX REST client observeQuery not URL-encoding the base64 query string. Standard base64 contains + and /; in a URL query parameter + is decoded by the server as a space, so the server's atob rejected the corrupted string with Invalid character and the SSE handler crashed silently after the response headers were already sent. Any query whose base64 contained + or / (for example, queries that filtered by a unicode value such as firstName: { $eq: 'ûÿþ' }) would never deliver a document and the client just hung. The base64 is now passed through encodeURIComponent before being appended to the URL.
  • FIX REST /delete endpoint returning 403 Forbidden when serverOnlyFields is configured. The delete handler passed full documents (including server-only fields) to the changeValidator, which always rejected them because the wrapper checks for the presence of server-only fields. Now the server-only fields are stripped before validation, consistent with the /set endpoint behavior.
  • FIX REST /query/observe endpoint not rejecting $regex queries with a proper 400 response. The queryModifier wrapper throws on $regex selectors to prevent DOS attacks (matching the /query behavior), but the observe handler called the wrapped modifier AFTER setSSEHeaders had already committed a 200 OK SSE response, and without a try/catch. A client that sent a $regex query therefore observed a successful 200 status with an empty stream that the server then dropped, instead of the same 400 Bad Request that /query returns. The handler now runs the queryModifier (and the JSON/base64 query parsing) inside a try/catch BEFORE setting the SSE headers, so a bad request is answered with a proper 400 response.
  • FIX REST /set endpoint not running the changeValidator for inserts of NEW documents. The handler only invoked the validator on the update path (when an existing document was found by primary key), so a changeValidator that returned false had no effect when the client sent a document whose primary key did not yet exist on the server. The handler now runs the validator for inserts as well, with assumedMasterState set to undefined, matching the behavior of the replication /push endpoint and the documented contract that the validator gates all writes.
  • FIX REST /set endpoint allowing a client to overwrite documents they do not own. When a queryModifier was configured, the handler only validated that the client-provided (new) document state matched the modifier but never checked the existing server document. An authenticated user could therefore take over a foreign document by sending a write whose new state matched the modifier while targeting another user's primary key. The handler now also runs the query matcher against the existing server document and rejects the request with 403 Forbidden if it does not match, aligning the behavior with the replication /push endpoint.
  • FIX REST endpoint /set allowing clients to populate serverOnlyFields when inserting NEW documents. Updates to existing documents already stripped client-supplied values for these fields, but the insert path passed the client document straight to RxCollection.insert(), so a client could persist arbitrary values into fields that are documented as server-only. The handler now strips server-only fields from the client document before inserting, matching the documented contract that clients cannot do writes where one of the serverOnlyFields is set.
  • FIX REST endpoint /set not protecting serverOnlyFields from client overwrites. Clients could include server-only fields in write requests to /set, and those values would be stored directly instead of being ignored. The handler now uses mergeServerDocumentFields (consistent with the replication endpoint) to ensure server-only field values are always preserved from the server-side document, not taken from client input.

NOTICE: An overview about all releases can be found at the changelog

Join RxDB:

Don't miss a new rxdb release

NewReleases is sending notifications on new releases.