@connecttomahdi/rxdb 17.0.0-beta.17 → 17.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +4 -0
- package/CHANGELOG.md +47 -4
- package/CLAUDE.md +2 -0
- package/dist/cjs/change-event-buffer.js +2 -1
- package/dist/cjs/change-event-buffer.js.map +1 -1
- package/dist/cjs/custom-index.js +85 -12
- package/dist/cjs/custom-index.js.map +1 -1
- package/dist/cjs/doc-cache.js +117 -35
- package/dist/cjs/doc-cache.js.map +1 -1
- package/dist/cjs/event-reduce.js +10 -1
- package/dist/cjs/event-reduce.js.map +1 -1
- package/dist/cjs/plugin-helpers.js +16 -0
- package/dist/cjs/plugin-helpers.js.map +1 -1
- package/dist/cjs/plugins/attachments/index.js +3 -3
- package/dist/cjs/plugins/attachments/index.js.map +1 -1
- package/dist/cjs/plugins/cleanup/cleanup.js +5 -3
- package/dist/cjs/plugins/cleanup/cleanup.js.map +1 -1
- package/dist/cjs/plugins/crdt/index.js +52 -0
- package/dist/cjs/plugins/crdt/index.js.map +1 -1
- package/dist/cjs/plugins/dev-mode/check-query.js +7 -1
- package/dist/cjs/plugins/dev-mode/check-query.js.map +1 -1
- package/dist/cjs/plugins/dev-mode/check-schema.js +2 -1
- package/dist/cjs/plugins/dev-mode/check-schema.js.map +1 -1
- package/dist/cjs/plugins/dev-mode/error-messages.js +43 -5
- package/dist/cjs/plugins/dev-mode/error-messages.js.map +1 -1
- package/dist/cjs/plugins/encryption-crypto-js/index.js +22 -6
- package/dist/cjs/plugins/encryption-crypto-js/index.js.map +1 -1
- package/dist/cjs/plugins/leader-election/index.js +5 -5
- package/dist/cjs/plugins/leader-election/index.js.map +1 -1
- package/dist/cjs/plugins/local-documents/local-documents.js +20 -13
- package/dist/cjs/plugins/local-documents/local-documents.js.map +1 -1
- package/dist/cjs/plugins/migration-schema/migration-helpers.js +3 -0
- package/dist/cjs/plugins/migration-schema/migration-helpers.js.map +1 -1
- package/dist/cjs/plugins/migration-schema/rx-migration-state.js +1 -1
- package/dist/cjs/plugins/migration-schema/rx-migration-state.js.map +1 -1
- package/dist/cjs/plugins/pipeline/rx-pipeline.js +5 -1
- package/dist/cjs/plugins/pipeline/rx-pipeline.js.map +1 -1
- package/dist/cjs/plugins/query-builder/mquery/nosql-query-builder.js +4 -2
- package/dist/cjs/plugins/query-builder/mquery/nosql-query-builder.js.map +1 -1
- package/dist/cjs/plugins/replication/index.js +40 -2
- package/dist/cjs/plugins/replication/index.js.map +1 -1
- package/dist/cjs/plugins/replication-google-drive/document-handling.js +17 -6
- package/dist/cjs/plugins/replication-google-drive/document-handling.js.map +1 -1
- package/dist/cjs/plugins/replication-google-drive/google-drive-helper.js +1 -1
- package/dist/cjs/plugins/replication-google-drive/google-drive-helper.js.map +1 -1
- package/dist/cjs/plugins/replication-google-drive/google-drive-types.js.map +1 -1
- package/dist/cjs/plugins/replication-google-drive/signaling.js +4 -1
- package/dist/cjs/plugins/replication-google-drive/signaling.js.map +1 -1
- package/dist/cjs/plugins/replication-google-drive/upstream.js +7 -4
- package/dist/cjs/plugins/replication-google-drive/upstream.js.map +1 -1
- package/dist/cjs/plugins/replication-microsoft-onedrive/signaling.js +4 -1
- package/dist/cjs/plugins/replication-microsoft-onedrive/signaling.js.map +1 -1
- package/dist/cjs/plugins/state/rx-state.js +14 -3
- package/dist/cjs/plugins/state/rx-state.js.map +1 -1
- package/dist/cjs/plugins/storage-dexie/rx-storage-instance-dexie.js +10 -17
- package/dist/cjs/plugins/storage-dexie/rx-storage-instance-dexie.js.map +1 -1
- package/dist/cjs/plugins/storage-memory/binary-search-bounds.js +112 -40
- package/dist/cjs/plugins/storage-memory/binary-search-bounds.js.map +1 -1
- package/dist/cjs/plugins/storage-memory/memory-helper.js +127 -40
- package/dist/cjs/plugins/storage-memory/memory-helper.js.map +1 -1
- package/dist/cjs/plugins/storage-memory/memory-indexes.js +1 -0
- package/dist/cjs/plugins/storage-memory/memory-indexes.js.map +1 -1
- package/dist/cjs/plugins/storage-memory/memory-types.js.map +1 -1
- package/dist/cjs/plugins/storage-memory/rx-storage-instance-memory.js +97 -37
- package/dist/cjs/plugins/storage-memory/rx-storage-instance-memory.js.map +1 -1
- package/dist/cjs/plugins/storage-mongodb/mongodb-helper.js +42 -1
- package/dist/cjs/plugins/storage-mongodb/mongodb-helper.js.map +1 -1
- package/dist/cjs/plugins/storage-mongodb/rx-storage-instance-mongodb.js +7 -7
- package/dist/cjs/plugins/storage-mongodb/rx-storage-instance-mongodb.js.map +1 -1
- package/dist/cjs/plugins/test-utils/config.js +1 -1
- package/dist/cjs/plugins/test-utils/config.js.map +1 -1
- package/dist/cjs/plugins/test-utils/performance.js +122 -92
- package/dist/cjs/plugins/test-utils/performance.js.map +1 -1
- package/dist/cjs/plugins/test-utils/schema-objects.js +1 -1
- package/dist/cjs/plugins/test-utils/schema-objects.js.map +1 -1
- package/dist/cjs/plugins/test-utils/test-util.js +62 -0
- package/dist/cjs/plugins/test-utils/test-util.js.map +1 -1
- package/dist/cjs/plugins/utils/utils-map.js +2 -2
- package/dist/cjs/plugins/utils/utils-map.js.map +1 -1
- package/dist/cjs/plugins/utils/utils-object-deep-equal.js +3 -2
- package/dist/cjs/plugins/utils/utils-object-deep-equal.js.map +1 -1
- package/dist/cjs/plugins/utils/utils-object-dot-prop.js +25 -0
- package/dist/cjs/plugins/utils/utils-object-dot-prop.js.map +1 -1
- package/dist/cjs/plugins/utils/utils-object.js +102 -27
- package/dist/cjs/plugins/utils/utils-object.js.map +1 -1
- package/dist/cjs/plugins/utils/utils-other.js +9 -4
- package/dist/cjs/plugins/utils/utils-other.js.map +1 -1
- package/dist/cjs/plugins/utils/utils-premium.js +1 -19
- package/dist/cjs/plugins/utils/utils-premium.js.map +1 -1
- package/dist/cjs/plugins/utils/utils-revision.js +20 -10
- package/dist/cjs/plugins/utils/utils-revision.js.map +1 -1
- package/dist/cjs/plugins/utils/utils-rxdb-version.js +1 -1
- package/dist/cjs/plugins/utils/utils-rxdb-version.js.map +1 -1
- package/dist/cjs/plugins/utils/utils-string.js +11 -8
- package/dist/cjs/plugins/utils/utils-string.js.map +1 -1
- package/dist/cjs/plugins/utils/utils-time.js +21 -16
- package/dist/cjs/plugins/utils/utils-time.js.map +1 -1
- package/dist/cjs/query-cache.js +6 -4
- package/dist/cjs/query-cache.js.map +1 -1
- package/dist/cjs/query-planner.js +2 -2
- package/dist/cjs/query-planner.js.map +1 -1
- package/dist/cjs/replication-protocol/downstream.js +1 -1
- package/dist/cjs/replication-protocol/downstream.js.map +1 -1
- package/dist/cjs/rx-collection-helper.js +11 -6
- package/dist/cjs/rx-collection-helper.js.map +1 -1
- package/dist/cjs/rx-collection.js +34 -6
- package/dist/cjs/rx-collection.js.map +1 -1
- package/dist/cjs/rx-database.js +40 -7
- package/dist/cjs/rx-database.js.map +1 -1
- package/dist/cjs/rx-document.js +10 -3
- package/dist/cjs/rx-document.js.map +1 -1
- package/dist/cjs/rx-query-helper.js +35 -12
- package/dist/cjs/rx-query-helper.js.map +1 -1
- package/dist/cjs/rx-query-single-result.js +9 -2
- package/dist/cjs/rx-query-single-result.js.map +1 -1
- package/dist/cjs/rx-query.js +72 -29
- package/dist/cjs/rx-query.js.map +1 -1
- package/dist/cjs/rx-schema-helper.js +9 -3
- package/dist/cjs/rx-schema-helper.js.map +1 -1
- package/dist/cjs/rx-schema.js +1 -0
- package/dist/cjs/rx-schema.js.map +1 -1
- package/dist/cjs/rx-storage-helper.js +212 -129
- package/dist/cjs/rx-storage-helper.js.map +1 -1
- package/dist/cjs/types/rx-error.d.js.map +1 -1
- package/dist/cjs/types/rx-schema.d.js.map +1 -1
- package/dist/esm/change-event-buffer.js +2 -1
- package/dist/esm/change-event-buffer.js.map +1 -1
- package/dist/esm/custom-index.js +85 -12
- package/dist/esm/custom-index.js.map +1 -1
- package/dist/esm/doc-cache.js +118 -36
- package/dist/esm/doc-cache.js.map +1 -1
- package/dist/esm/event-reduce.js +10 -1
- package/dist/esm/event-reduce.js.map +1 -1
- package/dist/esm/plugin-helpers.js +16 -0
- package/dist/esm/plugin-helpers.js.map +1 -1
- package/dist/esm/plugins/attachments/index.js +3 -3
- package/dist/esm/plugins/attachments/index.js.map +1 -1
- package/dist/esm/plugins/cleanup/cleanup.js +5 -3
- package/dist/esm/plugins/cleanup/cleanup.js.map +1 -1
- package/dist/esm/plugins/crdt/index.js +52 -0
- package/dist/esm/plugins/crdt/index.js.map +1 -1
- package/dist/esm/plugins/dev-mode/check-query.js +7 -1
- package/dist/esm/plugins/dev-mode/check-query.js.map +1 -1
- package/dist/esm/plugins/dev-mode/check-schema.js +2 -1
- package/dist/esm/plugins/dev-mode/check-schema.js.map +1 -1
- package/dist/esm/plugins/dev-mode/error-messages.js +43 -5
- package/dist/esm/plugins/dev-mode/error-messages.js.map +1 -1
- package/dist/esm/plugins/encryption-crypto-js/index.js +22 -6
- package/dist/esm/plugins/encryption-crypto-js/index.js.map +1 -1
- package/dist/esm/plugins/leader-election/index.js +4 -4
- package/dist/esm/plugins/leader-election/index.js.map +1 -1
- package/dist/esm/plugins/local-documents/local-documents.js +20 -13
- package/dist/esm/plugins/local-documents/local-documents.js.map +1 -1
- package/dist/esm/plugins/migration-schema/migration-helpers.js +3 -0
- package/dist/esm/plugins/migration-schema/migration-helpers.js.map +1 -1
- package/dist/esm/plugins/migration-schema/rx-migration-state.js +1 -1
- package/dist/esm/plugins/migration-schema/rx-migration-state.js.map +1 -1
- package/dist/esm/plugins/pipeline/rx-pipeline.js +5 -1
- package/dist/esm/plugins/pipeline/rx-pipeline.js.map +1 -1
- package/dist/esm/plugins/query-builder/mquery/nosql-query-builder.js +4 -2
- package/dist/esm/plugins/query-builder/mquery/nosql-query-builder.js.map +1 -1
- package/dist/esm/plugins/replication/index.js +40 -2
- package/dist/esm/plugins/replication/index.js.map +1 -1
- package/dist/esm/plugins/replication-google-drive/document-handling.js +17 -6
- package/dist/esm/plugins/replication-google-drive/document-handling.js.map +1 -1
- package/dist/esm/plugins/replication-google-drive/google-drive-helper.js +1 -1
- package/dist/esm/plugins/replication-google-drive/google-drive-helper.js.map +1 -1
- package/dist/esm/plugins/replication-google-drive/google-drive-types.js.map +1 -1
- package/dist/esm/plugins/replication-google-drive/signaling.js +4 -1
- package/dist/esm/plugins/replication-google-drive/signaling.js.map +1 -1
- package/dist/esm/plugins/replication-google-drive/upstream.js +7 -4
- package/dist/esm/plugins/replication-google-drive/upstream.js.map +1 -1
- package/dist/esm/plugins/replication-microsoft-onedrive/signaling.js +4 -1
- package/dist/esm/plugins/replication-microsoft-onedrive/signaling.js.map +1 -1
- package/dist/esm/plugins/state/rx-state.js +15 -4
- package/dist/esm/plugins/state/rx-state.js.map +1 -1
- package/dist/esm/plugins/storage-dexie/rx-storage-instance-dexie.js +11 -18
- package/dist/esm/plugins/storage-dexie/rx-storage-instance-dexie.js.map +1 -1
- package/dist/esm/plugins/storage-memory/binary-search-bounds.js +107 -40
- package/dist/esm/plugins/storage-memory/binary-search-bounds.js.map +1 -1
- package/dist/esm/plugins/storage-memory/memory-helper.js +128 -41
- package/dist/esm/plugins/storage-memory/memory-helper.js.map +1 -1
- package/dist/esm/plugins/storage-memory/memory-indexes.js +1 -0
- package/dist/esm/plugins/storage-memory/memory-indexes.js.map +1 -1
- package/dist/esm/plugins/storage-memory/memory-types.js.map +1 -1
- package/dist/esm/plugins/storage-memory/rx-storage-instance-memory.js +90 -30
- package/dist/esm/plugins/storage-memory/rx-storage-instance-memory.js.map +1 -1
- package/dist/esm/plugins/storage-mongodb/mongodb-helper.js +39 -0
- package/dist/esm/plugins/storage-mongodb/mongodb-helper.js.map +1 -1
- package/dist/esm/plugins/storage-mongodb/rx-storage-instance-mongodb.js +8 -8
- package/dist/esm/plugins/storage-mongodb/rx-storage-instance-mongodb.js.map +1 -1
- package/dist/esm/plugins/test-utils/config.js +1 -1
- package/dist/esm/plugins/test-utils/config.js.map +1 -1
- package/dist/esm/plugins/test-utils/performance.js +122 -92
- package/dist/esm/plugins/test-utils/performance.js.map +1 -1
- package/dist/esm/plugins/test-utils/schema-objects.js +1 -1
- package/dist/esm/plugins/test-utils/schema-objects.js.map +1 -1
- package/dist/esm/plugins/test-utils/test-util.js +59 -0
- package/dist/esm/plugins/test-utils/test-util.js.map +1 -1
- package/dist/esm/plugins/utils/utils-map.js +2 -2
- package/dist/esm/plugins/utils/utils-map.js.map +1 -1
- package/dist/esm/plugins/utils/utils-object-deep-equal.js +3 -2
- package/dist/esm/plugins/utils/utils-object-deep-equal.js.map +1 -1
- package/dist/esm/plugins/utils/utils-object-dot-prop.js +25 -0
- package/dist/esm/plugins/utils/utils-object-dot-prop.js.map +1 -1
- package/dist/esm/plugins/utils/utils-object.js +102 -27
- package/dist/esm/plugins/utils/utils-object.js.map +1 -1
- package/dist/esm/plugins/utils/utils-other.js +9 -4
- package/dist/esm/plugins/utils/utils-other.js.map +1 -1
- package/dist/esm/plugins/utils/utils-premium.js +1 -19
- package/dist/esm/plugins/utils/utils-premium.js.map +1 -1
- package/dist/esm/plugins/utils/utils-revision.js +20 -10
- package/dist/esm/plugins/utils/utils-revision.js.map +1 -1
- package/dist/esm/plugins/utils/utils-rxdb-version.js +1 -1
- package/dist/esm/plugins/utils/utils-rxdb-version.js.map +1 -1
- package/dist/esm/plugins/utils/utils-string.js +11 -8
- package/dist/esm/plugins/utils/utils-string.js.map +1 -1
- package/dist/esm/plugins/utils/utils-time.js +21 -16
- package/dist/esm/plugins/utils/utils-time.js.map +1 -1
- package/dist/esm/query-cache.js +7 -5
- package/dist/esm/query-cache.js.map +1 -1
- package/dist/esm/query-planner.js +2 -2
- package/dist/esm/query-planner.js.map +1 -1
- package/dist/esm/replication-protocol/downstream.js +1 -1
- package/dist/esm/replication-protocol/downstream.js.map +1 -1
- package/dist/esm/rx-collection-helper.js +12 -7
- package/dist/esm/rx-collection-helper.js.map +1 -1
- package/dist/esm/rx-collection.js +35 -7
- package/dist/esm/rx-collection.js.map +1 -1
- package/dist/esm/rx-database.js +40 -7
- package/dist/esm/rx-database.js.map +1 -1
- package/dist/esm/rx-document.js +11 -4
- package/dist/esm/rx-document.js.map +1 -1
- package/dist/esm/rx-query-helper.js +35 -12
- package/dist/esm/rx-query-helper.js.map +1 -1
- package/dist/esm/rx-query-single-result.js +10 -3
- package/dist/esm/rx-query-single-result.js.map +1 -1
- package/dist/esm/rx-query.js +72 -29
- package/dist/esm/rx-query.js.map +1 -1
- package/dist/esm/rx-schema-helper.js +9 -3
- package/dist/esm/rx-schema-helper.js.map +1 -1
- package/dist/esm/rx-schema.js +1 -0
- package/dist/esm/rx-schema.js.map +1 -1
- package/dist/esm/rx-storage-helper.js +176 -94
- package/dist/esm/rx-storage-helper.js.map +1 -1
- package/dist/esm/types/rx-error.d.js.map +1 -1
- package/dist/esm/types/rx-schema.d.js.map +1 -1
- package/dist/types/custom-index.d.ts +5 -0
- package/dist/types/doc-cache.d.ts +1 -1
- package/dist/types/index.d.ts +25 -26
- package/dist/types/plugins/dev-mode/error-messages.d.ts +36 -0
- package/dist/types/plugins/leader-election/index.d.ts +1 -0
- package/dist/types/plugins/replication-google-drive/document-handling.d.ts +4 -1
- package/dist/types/plugins/replication-google-drive/google-drive-types.d.ts +1 -0
- package/dist/types/plugins/state/rx-state.d.ts +1 -1
- package/dist/types/plugins/storage-denokv/index.d.ts +1 -1
- package/dist/types/plugins/storage-dexie/rx-storage-dexie.d.ts +1 -1
- package/dist/types/plugins/storage-localstorage/index.d.ts +1 -1
- package/dist/types/plugins/storage-memory/binary-search-bounds.d.ts +21 -10
- package/dist/types/plugins/storage-memory/memory-helper.d.ts +7 -3
- package/dist/types/plugins/storage-memory/memory-types.d.ts +5 -0
- package/dist/types/plugins/storage-mongodb/mongodb-helper.d.ts +9 -1
- package/dist/types/plugins/storage-mongodb/rx-storage-instance-mongodb.d.ts +2 -2
- package/dist/types/plugins/storage-mongodb/rx-storage-mongodb.d.ts +1 -1
- package/dist/types/plugins/storage-remote/rx-storage-remote.d.ts +1 -1
- package/dist/types/plugins/storage-sqlite/index.d.ts +1 -1
- package/dist/types/plugins/test-utils/performance.d.ts +36 -0
- package/dist/types/plugins/test-utils/test-util.d.ts +17 -0
- package/dist/types/plugins/utils/utils-object.d.ts +8 -3
- package/dist/types/plugins/utils/utils-premium.d.ts +0 -2
- package/dist/types/plugins/utils/utils-rxdb-version.d.ts +1 -1
- package/dist/types/rx-database.d.ts +1 -1
- package/dist/types/rx-query-single-result.d.ts +1 -1
- package/dist/types/rx-query.d.ts +3 -2
- package/dist/types/rx-storage-helper.d.ts +15 -0
- package/eslint.config.mjs +2 -1
- package/package.json +732 -729
- package/scripts/check-code-block-line-length.js +91 -0
- package/scripts/check-em-dashes.js +53 -0
- package/scripts/docs-fetch-git-history.mjs +36 -0
- package/scripts/install-foundationdb.sh +0 -6
- package/scripts/notify-indexnow.mjs +171 -0
- package/scripts/start-foundationdb-docker.sh +73 -0
- package/src/change-event-buffer.ts +4 -1
- package/src/custom-index.ts +93 -16
- package/src/doc-cache.ts +117 -41
- package/src/event-reduce.ts +10 -1
- package/src/plugin-helpers.ts +10 -0
- package/src/plugins/attachments/index.ts +10 -12
- package/src/plugins/cleanup/cleanup.ts +5 -3
- package/src/plugins/crdt/index.ts +55 -0
- package/src/plugins/dev-mode/check-query.ts +7 -1
- package/src/plugins/dev-mode/check-schema.ts +2 -1
- package/src/plugins/dev-mode/error-messages.ts +45 -5
- package/src/plugins/encryption-crypto-js/index.ts +18 -6
- package/src/plugins/leader-election/index.ts +9 -8
- package/src/plugins/local-documents/local-documents.ts +21 -12
- package/src/plugins/migration-schema/migration-helpers.ts +3 -0
- package/src/plugins/migration-schema/rx-migration-state.ts +1 -1
- package/src/plugins/pipeline/rx-pipeline.ts +5 -1
- package/src/plugins/query-builder/mquery/nosql-query-builder.ts +8 -2
- package/src/plugins/replication/index.ts +41 -3
- package/src/plugins/replication-google-drive/document-handling.ts +17 -5
- package/src/plugins/replication-google-drive/google-drive-helper.ts +1 -1
- package/src/plugins/replication-google-drive/google-drive-types.ts +1 -0
- package/src/plugins/replication-google-drive/signaling.ts +4 -1
- package/src/plugins/replication-google-drive/upstream.ts +7 -4
- package/src/plugins/replication-microsoft-onedrive/signaling.ts +4 -1
- package/src/plugins/state/rx-state.ts +17 -5
- package/src/plugins/storage-dexie/rx-storage-instance-dexie.ts +0 -27
- package/src/plugins/storage-memory/binary-search-bounds.ts +105 -40
- package/src/plugins/storage-memory/memory-helper.ts +158 -67
- package/src/plugins/storage-memory/memory-indexes.ts +1 -0
- package/src/plugins/storage-memory/memory-types.ts +5 -0
- package/src/plugins/storage-memory/rx-storage-instance-memory.ts +104 -53
- package/src/plugins/storage-mongodb/mongodb-helper.ts +43 -1
- package/src/plugins/storage-mongodb/rx-storage-instance-mongodb.ts +11 -9
- package/src/plugins/test-utils/config.ts +2 -1
- package/src/plugins/test-utils/performance.ts +159 -85
- package/src/plugins/test-utils/schema-objects.ts +1 -1
- package/src/plugins/test-utils/test-util.ts +71 -0
- package/src/plugins/utils/utils-map.ts +2 -2
- package/src/plugins/utils/utils-object-deep-equal.ts +2 -4
- package/src/plugins/utils/utils-object-dot-prop.ts +25 -0
- package/src/plugins/utils/utils-object.ts +103 -28
- package/src/plugins/utils/utils-other.ts +9 -4
- package/src/plugins/utils/utils-premium.ts +11 -37
- package/src/plugins/utils/utils-revision.ts +20 -9
- package/src/plugins/utils/utils-rxdb-version.ts +1 -1
- package/src/plugins/utils/utils-string.ts +11 -9
- package/src/plugins/utils/utils-time.ts +21 -17
- package/src/query-cache.ts +6 -5
- package/src/query-planner.ts +2 -2
- package/src/replication-protocol/downstream.ts +1 -1
- package/src/rx-collection-helper.ts +12 -6
- package/src/rx-collection.ts +39 -8
- package/src/rx-database.ts +49 -17
- package/src/rx-document.ts +12 -3
- package/src/rx-query-helper.ts +36 -15
- package/src/rx-query-single-result.ts +10 -3
- package/src/rx-query.ts +48 -8
- package/src/rx-schema-helper.ts +7 -4
- package/src/rx-schema.ts +1 -0
- package/src/rx-storage-helper.ts +210 -139
- package/src/types/rx-error.d.ts +3 -0
- package/src/types/rx-schema.d.ts +5 -0
- package/dist/esm/package.json +0 -1
- package/dist/types/types/conflict-handling.d.ts +0 -48
- package/dist/types/types/couchdb.d.ts +0 -293
- package/dist/types/types/index.d.ts +0 -32
- package/dist/types/types/modules/index.d.ts +0 -0
- package/dist/types/types/modules/mocha.parallel.d.ts +0 -1
- package/dist/types/types/plugins/backup.d.ts +0 -35
- package/dist/types/types/plugins/cleanup.d.ts +0 -38
- package/dist/types/types/plugins/crdt.d.ts +0 -76
- package/dist/types/types/plugins/dexie.d.ts +0 -30
- package/dist/types/types/plugins/local-documents.d.ts +0 -49
- package/dist/types/types/plugins/migration.d.ts +0 -14
- package/dist/types/types/plugins/reactivity.d.ts +0 -40
- package/dist/types/types/plugins/replication-graphql.d.ts +0 -98
- package/dist/types/types/plugins/replication.d.ts +0 -175
- package/dist/types/types/plugins/state.d.ts +0 -4
- package/dist/types/types/plugins/update.d.ts +0 -23
- package/dist/types/types/plugins/webmcp.d.ts +0 -40
- package/dist/types/types/query-planner.d.ts +0 -47
- package/dist/types/types/replication-protocol.d.ts +0 -296
- package/dist/types/types/rx-attachment.d.ts +0 -46
- package/dist/types/types/rx-change-event.d.ts +0 -85
- package/dist/types/types/rx-collection.d.ts +0 -117
- package/dist/types/types/rx-database-internal-store.d.ts +0 -54
- package/dist/types/types/rx-database.d.ts +0 -124
- package/dist/types/types/rx-document.d.ts +0 -160
- package/dist/types/types/rx-error.d.ts +0 -222
- package/dist/types/types/rx-plugin.d.ts +0 -167
- package/dist/types/types/rx-query.d.ts +0 -144
- package/dist/types/types/rx-schema.d.ts +0 -209
- package/dist/types/types/rx-storage.d.ts +0 -347
- package/dist/types/types/rx-storage.interface.d.ts +0 -312
- package/dist/types/types/util.d.ts +0 -180
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import type {
|
|
2
|
-
BulkWriteRow,
|
|
3
2
|
RxDocumentData,
|
|
4
3
|
RxJsonSchema
|
|
5
4
|
} from '../../types/index.d.ts';
|
|
@@ -13,7 +12,7 @@ import {
|
|
|
13
12
|
pushAtSortPosition
|
|
14
13
|
} from 'array-push-at-sort-position';
|
|
15
14
|
import { newRxError } from '../../rx-error.ts';
|
|
16
|
-
import {
|
|
15
|
+
import { boundEQByIndexString } from './binary-search-bounds.ts';
|
|
17
16
|
|
|
18
17
|
|
|
19
18
|
export function getMemoryCollectionKey(
|
|
@@ -46,6 +45,14 @@ export function attachmentMapKey(documentId: string, attachmentId: string): stri
|
|
|
46
45
|
}
|
|
47
46
|
|
|
48
47
|
|
|
48
|
+
/**
|
|
49
|
+
* @performance
|
|
50
|
+
* Threshold for using in-place splice vs. full merge-sort when inserting
|
|
51
|
+
* documents into indexes. Below this batch size, in-place binary search + splice
|
|
52
|
+
* is faster because it avoids allocating a new full-size array and copying all elements.
|
|
53
|
+
*/
|
|
54
|
+
const IN_PLACE_INSERT_THRESHOLD = 64;
|
|
55
|
+
|
|
49
56
|
function sortByIndexStringComparator<RxDocType>(a: DocWithIndexString<RxDocType>, b: DocWithIndexString<RxDocType>) {
|
|
50
57
|
if (a[0] < b[0]) {
|
|
51
58
|
return -1;
|
|
@@ -67,38 +74,65 @@ export function putWriteRowToState<RxDocType>(
|
|
|
67
74
|
docInState?: RxDocumentData<RxDocType>
|
|
68
75
|
) {
|
|
69
76
|
state.documents.set(docId, document as any);
|
|
70
|
-
|
|
77
|
+
const stateByIndexLength = stateByIndex.length;
|
|
78
|
+
for (let i = 0; i < stateByIndexLength; ++i) {
|
|
71
79
|
const byIndex = stateByIndex[i];
|
|
72
80
|
const docsWithIndex = byIndex.docsWithIndex;
|
|
73
81
|
const getIndexableString = byIndex.getIndexableString;
|
|
74
82
|
const newIndexString = getIndexableString(document as any);
|
|
75
|
-
const insertPosition = pushAtSortPosition(
|
|
76
|
-
docsWithIndex,
|
|
77
|
-
[
|
|
78
|
-
newIndexString,
|
|
79
|
-
document,
|
|
80
|
-
docId,
|
|
81
|
-
],
|
|
82
|
-
sortByIndexStringComparator,
|
|
83
|
-
0
|
|
84
|
-
);
|
|
85
83
|
|
|
86
84
|
/**
|
|
87
|
-
*
|
|
85
|
+
* @performance
|
|
86
|
+
* When updating a document, first compute whether the index changed.
|
|
87
|
+
* If it did not change, we only need to update the document reference
|
|
88
|
+
* in-place without any splice operations.
|
|
88
89
|
*/
|
|
89
90
|
if (docInState) {
|
|
90
91
|
const previousIndexString = getIndexableString(docInState);
|
|
91
92
|
if (previousIndexString === newIndexString) {
|
|
92
93
|
/**
|
|
93
94
|
* Performance shortcut.
|
|
94
|
-
*
|
|
95
|
+
* Index did not change, so the old entry is at the same position.
|
|
96
|
+
* We can find it by string-specialized binary search and update in-place.
|
|
95
97
|
*/
|
|
96
|
-
const
|
|
97
|
-
|
|
98
|
+
const eqPos = boundEQByIndexString(
|
|
99
|
+
docsWithIndex,
|
|
100
|
+
previousIndexString
|
|
101
|
+
);
|
|
102
|
+
if (eqPos !== -1) {
|
|
103
|
+
/**
|
|
104
|
+
* There might be multiple entries with the same index string
|
|
105
|
+
* (e.g. different documents). Search around eqPos for ours.
|
|
106
|
+
*/
|
|
107
|
+
if (docsWithIndex[eqPos][2] === docId) {
|
|
108
|
+
docsWithIndex[eqPos][1] = document;
|
|
109
|
+
continue;
|
|
110
|
+
}
|
|
111
|
+
// Check neighbors
|
|
112
|
+
const prev = docsWithIndex[eqPos - 1];
|
|
113
|
+
if (prev && prev[0] === previousIndexString && prev[2] === docId) {
|
|
114
|
+
docsWithIndex[eqPos - 1][1] = document;
|
|
115
|
+
continue;
|
|
116
|
+
}
|
|
117
|
+
const next = docsWithIndex[eqPos + 1];
|
|
118
|
+
if (next && next[0] === previousIndexString && next[2] === docId) {
|
|
119
|
+
docsWithIndex[eqPos + 1][1] = document;
|
|
120
|
+
continue;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
// Fallback: use the old insert+remove approach
|
|
124
|
+
const insertPosition = pushAtSortPosition(
|
|
125
|
+
docsWithIndex,
|
|
126
|
+
[newIndexString, document, docId],
|
|
127
|
+
sortByIndexStringComparator,
|
|
128
|
+
0
|
|
129
|
+
);
|
|
130
|
+
const prevEntry = docsWithIndex[insertPosition - 1];
|
|
131
|
+
if (prevEntry && prevEntry[2] === docId) {
|
|
98
132
|
docsWithIndex.splice(insertPosition - 1, 1);
|
|
99
133
|
} else {
|
|
100
|
-
const
|
|
101
|
-
if (
|
|
134
|
+
const nextEntry = docsWithIndex[insertPosition + 1];
|
|
135
|
+
if (nextEntry[2] === docId) {
|
|
102
136
|
docsWithIndex.splice(insertPosition + 1, 1);
|
|
103
137
|
} else {
|
|
104
138
|
throw newRxError('SNH', {
|
|
@@ -109,20 +143,27 @@ export function putWriteRowToState<RxDocType>(
|
|
|
109
143
|
});
|
|
110
144
|
}
|
|
111
145
|
}
|
|
146
|
+
continue;
|
|
112
147
|
} else {
|
|
113
148
|
/**
|
|
114
|
-
* Index changed, we must
|
|
149
|
+
* Index changed, we must remove the old entry and insert the new one.
|
|
115
150
|
*/
|
|
116
|
-
const indexBefore =
|
|
151
|
+
const indexBefore = boundEQByIndexString(
|
|
117
152
|
docsWithIndex,
|
|
118
|
-
|
|
119
|
-
previousIndexString
|
|
120
|
-
] as any,
|
|
121
|
-
compareDocsWithIndex
|
|
153
|
+
previousIndexString
|
|
122
154
|
);
|
|
123
|
-
|
|
155
|
+
if (indexBefore !== -1) {
|
|
156
|
+
docsWithIndex.splice(indexBefore, 1);
|
|
157
|
+
}
|
|
124
158
|
}
|
|
125
159
|
}
|
|
160
|
+
|
|
161
|
+
pushAtSortPosition(
|
|
162
|
+
docsWithIndex,
|
|
163
|
+
[newIndexString, document, docId],
|
|
164
|
+
sortByIndexStringComparator,
|
|
165
|
+
0
|
|
166
|
+
);
|
|
126
167
|
}
|
|
127
168
|
}
|
|
128
169
|
|
|
@@ -130,9 +171,13 @@ export function putWriteRowToState<RxDocType>(
|
|
|
130
171
|
/**
|
|
131
172
|
* @hotPath
|
|
132
173
|
* Efficiently inserts multiple documents into the state at once.
|
|
133
|
-
*
|
|
134
|
-
*
|
|
135
|
-
*
|
|
174
|
+
*
|
|
175
|
+
* Uses two strategies based on batch size:
|
|
176
|
+
* - For small batches (relative to existing index size), uses in-place
|
|
177
|
+
* binary search + splice per document. This avoids allocating a new
|
|
178
|
+
* full-size array and copying all elements, reducing GC pressure.
|
|
179
|
+
* - For large batches (or empty indexes), pre-computes all index entries,
|
|
180
|
+
* sorts them, and merges into the existing sorted arrays in a single pass.
|
|
136
181
|
*/
|
|
137
182
|
export function bulkInsertToState<RxDocType>(
|
|
138
183
|
primaryPath: string,
|
|
@@ -141,6 +186,7 @@ export function bulkInsertToState<RxDocType>(
|
|
|
141
186
|
docs: { document: RxDocumentData<RxDocType> }[]
|
|
142
187
|
) {
|
|
143
188
|
const docsLength = docs.length;
|
|
189
|
+
const stateByIndexLength = stateByIndex.length;
|
|
144
190
|
|
|
145
191
|
// Extract documents and docIds once, store in Map
|
|
146
192
|
const documents: RxDocumentData<RxDocType>[] = new Array(docsLength);
|
|
@@ -153,55 +199,99 @@ export function bulkInsertToState<RxDocType>(
|
|
|
153
199
|
state.documents.set(docId, doc as any);
|
|
154
200
|
}
|
|
155
201
|
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
202
|
+
/**
|
|
203
|
+
* @performance
|
|
204
|
+
* For small batch sizes, use in-place binary search + splice
|
|
205
|
+
* instead of creating a full merged array copy. This is faster
|
|
206
|
+
* for serial inserts and small bulk inserts because it avoids:
|
|
207
|
+
* - Allocating a new array of size n+m
|
|
208
|
+
* - Copying all n existing elements
|
|
209
|
+
* - GC pressure from discarding the old array
|
|
210
|
+
*
|
|
211
|
+
* The threshold is based on when the merge approach becomes more
|
|
212
|
+
* efficient than individual splices.
|
|
213
|
+
*/
|
|
214
|
+
const useInPlaceInsert = docsLength < IN_PLACE_INSERT_THRESHOLD;
|
|
215
|
+
|
|
216
|
+
if (useInPlaceInsert) {
|
|
217
|
+
for (let indexI = 0; indexI < stateByIndexLength; ++indexI) {
|
|
218
|
+
const byIndex = stateByIndex[indexI];
|
|
219
|
+
const docsWithIndex = byIndex.docsWithIndex;
|
|
220
|
+
const getIndexableString = byIndex.getIndexableString;
|
|
161
221
|
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
222
|
+
if (docsWithIndex.length === 0) {
|
|
223
|
+
for (let i = 0; i < docsLength; ++i) {
|
|
224
|
+
const doc = documents[i];
|
|
225
|
+
const indexString = getIndexableString(doc as any);
|
|
226
|
+
docsWithIndex.push([indexString, doc, docIds[i]]);
|
|
227
|
+
}
|
|
228
|
+
docsWithIndex.sort(sortByIndexStringComparator);
|
|
229
|
+
} else {
|
|
230
|
+
for (let i = 0; i < docsLength; ++i) {
|
|
231
|
+
const doc = documents[i];
|
|
232
|
+
const indexString = getIndexableString(doc as any);
|
|
233
|
+
const newEntry: DocWithIndexString<RxDocType> = [indexString, doc, docIds[i]];
|
|
234
|
+
pushAtSortPosition(
|
|
235
|
+
docsWithIndex,
|
|
236
|
+
newEntry,
|
|
237
|
+
sortByIndexStringComparator,
|
|
238
|
+
0
|
|
239
|
+
);
|
|
240
|
+
}
|
|
241
|
+
}
|
|
171
242
|
}
|
|
243
|
+
} else {
|
|
244
|
+
// For each index, batch-compute entries, sort, and merge
|
|
245
|
+
for (let indexI = 0; indexI < stateByIndexLength; ++indexI) {
|
|
246
|
+
const byIndex = stateByIndex[indexI];
|
|
247
|
+
const docsWithIndex = byIndex.docsWithIndex;
|
|
248
|
+
const getIndexableString = byIndex.getIndexableString;
|
|
172
249
|
|
|
173
|
-
|
|
174
|
-
|
|
250
|
+
// Build new entries
|
|
251
|
+
const newEntries: DocWithIndexString<RxDocType>[] = new Array(docsLength);
|
|
252
|
+
for (let i = 0; i < docsLength; ++i) {
|
|
253
|
+
const doc = documents[i];
|
|
254
|
+
newEntries[i] = [
|
|
255
|
+
getIndexableString(doc as any),
|
|
256
|
+
doc,
|
|
257
|
+
docIds[i]
|
|
258
|
+
];
|
|
259
|
+
}
|
|
175
260
|
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
261
|
+
// Sort by index string
|
|
262
|
+
newEntries.sort(sortByIndexStringComparator);
|
|
263
|
+
|
|
264
|
+
if (docsWithIndex.length === 0) {
|
|
265
|
+
// Index is empty, just assign sorted entries
|
|
266
|
+
byIndex.docsWithIndex = newEntries;
|
|
267
|
+
} else {
|
|
268
|
+
// Merge sorted arrays
|
|
269
|
+
byIndex.docsWithIndex = mergeSortedArrays(docsWithIndex, newEntries);
|
|
270
|
+
}
|
|
182
271
|
}
|
|
183
272
|
}
|
|
184
273
|
}
|
|
185
274
|
|
|
186
275
|
|
|
187
276
|
/**
|
|
188
|
-
* Merges two sorted arrays into a single sorted array.
|
|
277
|
+
* Merges two sorted DocWithIndexString arrays into a single sorted array.
|
|
189
278
|
* Runs in O(n + m) where n and m are the lengths of the input arrays.
|
|
279
|
+
* @performance Comparator is inlined to avoid function call overhead
|
|
280
|
+
* per comparison, which is significant for large arrays.
|
|
190
281
|
*/
|
|
191
|
-
function mergeSortedArrays<
|
|
192
|
-
a:
|
|
193
|
-
b:
|
|
194
|
-
|
|
195
|
-
): T[] {
|
|
282
|
+
function mergeSortedArrays<RxDocType>(
|
|
283
|
+
a: DocWithIndexString<RxDocType>[],
|
|
284
|
+
b: DocWithIndexString<RxDocType>[]
|
|
285
|
+
): DocWithIndexString<RxDocType>[] {
|
|
196
286
|
const aLen = a.length;
|
|
197
287
|
const bLen = b.length;
|
|
198
|
-
const result:
|
|
288
|
+
const result: DocWithIndexString<RxDocType>[] = new Array(aLen + bLen);
|
|
199
289
|
let ai = 0;
|
|
200
290
|
let bi = 0;
|
|
201
291
|
let ri = 0;
|
|
202
292
|
|
|
203
293
|
while (ai < aLen && bi < bLen) {
|
|
204
|
-
if (
|
|
294
|
+
if (a[ai][0] <= b[bi][0]) {
|
|
205
295
|
result[ri++] = a[ai++];
|
|
206
296
|
} else {
|
|
207
297
|
result[ri++] = b[bi++];
|
|
@@ -227,19 +317,20 @@ export function removeDocFromState<RxDocType>(
|
|
|
227
317
|
const docId: string = (doc as any)[primaryPath];
|
|
228
318
|
state.documents.delete(docId);
|
|
229
319
|
|
|
230
|
-
|
|
320
|
+
const stateByIndex = state.byIndexArray;
|
|
321
|
+
for (let i = 0; i < stateByIndex.length; ++i) {
|
|
322
|
+
const byIndex = stateByIndex[i];
|
|
231
323
|
const docsWithIndex = byIndex.docsWithIndex;
|
|
232
324
|
const indexString = byIndex.getIndexableString(doc);
|
|
233
325
|
|
|
234
|
-
const positionInIndex =
|
|
326
|
+
const positionInIndex = boundEQByIndexString(
|
|
235
327
|
docsWithIndex,
|
|
236
|
-
|
|
237
|
-
indexString
|
|
238
|
-
] as any,
|
|
239
|
-
compareDocsWithIndex
|
|
328
|
+
indexString
|
|
240
329
|
);
|
|
241
|
-
|
|
242
|
-
|
|
330
|
+
if (positionInIndex !== -1) {
|
|
331
|
+
docsWithIndex.splice(positionInIndex, 1);
|
|
332
|
+
}
|
|
333
|
+
}
|
|
243
334
|
}
|
|
244
335
|
|
|
245
336
|
|
|
@@ -73,6 +73,11 @@ export type MemoryStorageInternals<RxDocType> = {
|
|
|
73
73
|
*/
|
|
74
74
|
[indexName: string]: MemoryStorageInternalsByIndex<RxDocType>;
|
|
75
75
|
};
|
|
76
|
+
/**
|
|
77
|
+
* Cached array of all MemoryStorageInternalsByIndex values.
|
|
78
|
+
* Avoids calling Object.values(byIndex) on every write operation.
|
|
79
|
+
*/
|
|
80
|
+
byIndexArray: MemoryStorageInternalsByIndex<RxDocType>[];
|
|
76
81
|
|
|
77
82
|
/**
|
|
78
83
|
* We need these to do lazy writes.
|
|
@@ -37,15 +37,14 @@ import {
|
|
|
37
37
|
requestIdlePromiseNoQueue
|
|
38
38
|
} from '../../plugins/utils/index.ts';
|
|
39
39
|
import {
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
40
|
+
boundGEByIndexString,
|
|
41
|
+
boundGTByIndexString,
|
|
42
|
+
boundLEByIndexString,
|
|
43
|
+
boundLTByIndexString
|
|
44
44
|
} from './binary-search-bounds.ts';
|
|
45
45
|
import {
|
|
46
46
|
attachmentMapKey,
|
|
47
47
|
bulkInsertToState,
|
|
48
|
-
compareDocsWithIndex,
|
|
49
48
|
ensureNotRemoved,
|
|
50
49
|
getMemoryCollectionKey,
|
|
51
50
|
putWriteRowToState,
|
|
@@ -170,7 +169,6 @@ export class RxStorageInstanceMemory<RxDocType> implements RxStorageInstance<
|
|
|
170
169
|
return;
|
|
171
170
|
}
|
|
172
171
|
const internals = this.internals;
|
|
173
|
-
const documentsById = this.internals.documents;
|
|
174
172
|
const primaryPath = this.primaryPath;
|
|
175
173
|
|
|
176
174
|
const categorized = this.internals.ensurePersistenceTask;
|
|
@@ -178,8 +176,9 @@ export class RxStorageInstanceMemory<RxDocType> implements RxStorageInstance<
|
|
|
178
176
|
|
|
179
177
|
/**
|
|
180
178
|
* Do inserts/updates
|
|
179
|
+
* @performance Use cached byIndexArray instead of Object.values()
|
|
181
180
|
*/
|
|
182
|
-
const stateByIndex =
|
|
181
|
+
const stateByIndex = internals.byIndexArray;
|
|
183
182
|
|
|
184
183
|
/**
|
|
185
184
|
* @performance Use batch insert for bulk inserts to avoid
|
|
@@ -202,12 +201,19 @@ export class RxStorageInstanceMemory<RxDocType> implements RxStorageInstance<
|
|
|
202
201
|
const writeRow = bulkUpdateDocs[i];
|
|
203
202
|
const doc = writeRow.document;
|
|
204
203
|
const docId = doc[primaryPath];
|
|
204
|
+
/**
|
|
205
|
+
* @performance
|
|
206
|
+
* Pass writeRow.previous directly as the old document state
|
|
207
|
+
* instead of re-looking it up from the documents Map.
|
|
208
|
+
* This is safe because categorizeBulkWriteRows already verified
|
|
209
|
+
* that previous._rev matches the document in the Map (conflict check).
|
|
210
|
+
*/
|
|
205
211
|
putWriteRowToState(
|
|
206
212
|
docId as any,
|
|
207
213
|
internals,
|
|
208
214
|
stateByIndex,
|
|
209
215
|
doc,
|
|
210
|
-
|
|
216
|
+
writeRow.previous
|
|
211
217
|
);
|
|
212
218
|
}
|
|
213
219
|
|
|
@@ -254,17 +260,23 @@ export class RxStorageInstanceMemory<RxDocType> implements RxStorageInstance<
|
|
|
254
260
|
if (documentsById.size === 0) {
|
|
255
261
|
return Promise.resolve(ret);
|
|
256
262
|
}
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
263
|
+
/**
|
|
264
|
+
* @performance
|
|
265
|
+
* Split into two paths to avoid checking withDeleted on every iteration.
|
|
266
|
+
*/
|
|
267
|
+
if (withDeleted) {
|
|
268
|
+
for (let i = 0; i < docIds.length; ++i) {
|
|
269
|
+
const docInDb = documentsById.get(docIds[i]);
|
|
270
|
+
if (docInDb) {
|
|
271
|
+
ret.push(docInDb);
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
} else {
|
|
275
|
+
for (let i = 0; i < docIds.length; ++i) {
|
|
276
|
+
const docInDb = documentsById.get(docIds[i]);
|
|
277
|
+
if (docInDb && !docInDb._deleted) {
|
|
278
|
+
ret.push(docInDb);
|
|
279
|
+
}
|
|
268
280
|
}
|
|
269
281
|
}
|
|
270
282
|
return Promise.resolve(ret);
|
|
@@ -314,22 +326,17 @@ export class RxStorageInstanceMemory<RxDocType> implements RxStorageInstance<
|
|
|
314
326
|
const docsWithIndex = this.internals.byIndex[indexName].docsWithIndex;
|
|
315
327
|
|
|
316
328
|
|
|
329
|
+
/**
|
|
330
|
+
* @performance Use string-specialized binary search to avoid
|
|
331
|
+
* temporary array allocations on every query.
|
|
332
|
+
*/
|
|
333
|
+
let indexOfLower = queryPlan.inclusiveStart
|
|
334
|
+
? boundGEByIndexString(docsWithIndex, lowerBoundString)
|
|
335
|
+
: boundGTByIndexString(docsWithIndex, lowerBoundString);
|
|
317
336
|
|
|
318
|
-
|
|
319
|
-
docsWithIndex,
|
|
320
|
-
|
|
321
|
-
lowerBoundString
|
|
322
|
-
] as any,
|
|
323
|
-
compareDocsWithIndex
|
|
324
|
-
);
|
|
325
|
-
|
|
326
|
-
const indexOfUpper = (queryPlan.inclusiveEnd ? boundLE : boundLT)(
|
|
327
|
-
docsWithIndex,
|
|
328
|
-
[
|
|
329
|
-
upperBoundString
|
|
330
|
-
] as any,
|
|
331
|
-
compareDocsWithIndex
|
|
332
|
-
);
|
|
337
|
+
const indexOfUpper = queryPlan.inclusiveEnd
|
|
338
|
+
? boundLEByIndexString(docsWithIndex, upperBoundString)
|
|
339
|
+
: boundLTByIndexString(docsWithIndex, upperBoundString);
|
|
333
340
|
|
|
334
341
|
let rows: RxDocumentData<RxDocType>[] = [];
|
|
335
342
|
|
|
@@ -405,6 +412,7 @@ export class RxStorageInstanceMemory<RxDocType> implements RxStorageInstance<
|
|
|
405
412
|
* If the selector is satisfied by the index,
|
|
406
413
|
* we can compute the count directly from the index range
|
|
407
414
|
* without extracting document data into an array.
|
|
415
|
+
* Uses string-specialized binary search to avoid allocations.
|
|
408
416
|
*/
|
|
409
417
|
if (queryPlan.selectorSatisfiedByIndex) {
|
|
410
418
|
const queryPlanFields: string[] = queryPlan.index;
|
|
@@ -428,17 +436,13 @@ export class RxStorageInstanceMemory<RxDocType> implements RxStorageInstance<
|
|
|
428
436
|
}
|
|
429
437
|
const docsWithIndex = this.internals.byIndex[indexName].docsWithIndex;
|
|
430
438
|
|
|
431
|
-
const indexOfLower =
|
|
432
|
-
docsWithIndex,
|
|
433
|
-
|
|
434
|
-
compareDocsWithIndex
|
|
435
|
-
);
|
|
439
|
+
const indexOfLower = queryPlan.inclusiveStart
|
|
440
|
+
? boundGEByIndexString(docsWithIndex, lowerBoundString)
|
|
441
|
+
: boundGTByIndexString(docsWithIndex, lowerBoundString);
|
|
436
442
|
|
|
437
|
-
const indexOfUpper =
|
|
438
|
-
docsWithIndex,
|
|
439
|
-
|
|
440
|
-
compareDocsWithIndex
|
|
441
|
-
);
|
|
443
|
+
const indexOfUpper = queryPlan.inclusiveEnd
|
|
444
|
+
? boundLEByIndexString(docsWithIndex, upperBoundString)
|
|
445
|
+
: boundLTByIndexString(docsWithIndex, upperBoundString);
|
|
442
446
|
|
|
443
447
|
const count = Math.max(0, indexOfUpper - indexOfLower + 1);
|
|
444
448
|
return Promise.resolve({
|
|
@@ -447,10 +451,54 @@ export class RxStorageInstanceMemory<RxDocType> implements RxStorageInstance<
|
|
|
447
451
|
});
|
|
448
452
|
}
|
|
449
453
|
|
|
450
|
-
|
|
451
|
-
|
|
454
|
+
const queryMatcher = getQueryMatcher(
|
|
455
|
+
this.schema,
|
|
456
|
+
preparedQuery.query
|
|
457
|
+
);
|
|
458
|
+
const queryPlanFields: string[] = queryPlan.index;
|
|
459
|
+
const index: string[] = queryPlanFields;
|
|
460
|
+
const lowerBound: any[] = queryPlan.startKeys;
|
|
461
|
+
const lowerBoundString = getStartIndexStringFromLowerBound(
|
|
462
|
+
this.schema,
|
|
463
|
+
index,
|
|
464
|
+
lowerBound
|
|
465
|
+
);
|
|
466
|
+
const upperBound: any[] = queryPlan.endKeys;
|
|
467
|
+
const upperBoundString = getStartIndexStringFromUpperBound(
|
|
468
|
+
this.schema,
|
|
469
|
+
index,
|
|
470
|
+
upperBound
|
|
471
|
+
);
|
|
472
|
+
const indexName = getMemoryIndexName(index);
|
|
473
|
+
if (!this.internals.byIndex[indexName]) {
|
|
474
|
+
throw newRxError('SNH', { args: { indexName } });
|
|
475
|
+
}
|
|
476
|
+
const docsWithIndex = this.internals.byIndex[indexName].docsWithIndex;
|
|
477
|
+
|
|
478
|
+
let indexOfLower = queryPlan.inclusiveStart
|
|
479
|
+
? boundGEByIndexString(docsWithIndex, lowerBoundString)
|
|
480
|
+
: boundGTByIndexString(docsWithIndex, lowerBoundString);
|
|
481
|
+
|
|
482
|
+
const indexOfUpper = queryPlan.inclusiveEnd
|
|
483
|
+
? boundLEByIndexString(docsWithIndex, upperBoundString)
|
|
484
|
+
: boundLTByIndexString(docsWithIndex, upperBoundString);
|
|
485
|
+
|
|
486
|
+
let count = 0;
|
|
487
|
+
while (indexOfLower <= indexOfUpper) {
|
|
488
|
+
const currentRow = docsWithIndex[indexOfLower];
|
|
489
|
+
if (!currentRow) {
|
|
490
|
+
break;
|
|
491
|
+
}
|
|
492
|
+
if (queryMatcher(currentRow[1])) {
|
|
493
|
+
count++;
|
|
494
|
+
}
|
|
495
|
+
indexOfLower++;
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
return Promise.resolve({
|
|
499
|
+
count,
|
|
452
500
|
mode: 'fast' as const
|
|
453
|
-
})
|
|
501
|
+
});
|
|
454
502
|
}
|
|
455
503
|
|
|
456
504
|
cleanup(minimumDeletedTime: number): Promise<boolean> {
|
|
@@ -470,12 +518,9 @@ export class RxStorageInstanceMemory<RxDocType> implements RxStorageInstance<
|
|
|
470
518
|
]
|
|
471
519
|
);
|
|
472
520
|
|
|
473
|
-
let indexOfLower =
|
|
521
|
+
let indexOfLower = boundGTByIndexString(
|
|
474
522
|
docsWithIndex,
|
|
475
|
-
|
|
476
|
-
lowerBoundString
|
|
477
|
-
] as any,
|
|
478
|
-
compareDocsWithIndex
|
|
523
|
+
lowerBoundString
|
|
479
524
|
);
|
|
480
525
|
|
|
481
526
|
let done = false;
|
|
@@ -490,7 +535,12 @@ export class RxStorageInstanceMemory<RxDocType> implements RxStorageInstance<
|
|
|
490
535
|
this.internals,
|
|
491
536
|
currentDoc[1]
|
|
492
537
|
);
|
|
493
|
-
|
|
538
|
+
/**
|
|
539
|
+
* Do NOT increment indexOfLower after removal.
|
|
540
|
+
* removeDocFromState() splices the element out of the array,
|
|
541
|
+
* so the next element shifts into the current position.
|
|
542
|
+
* Incrementing would skip it.
|
|
543
|
+
*/
|
|
494
544
|
}
|
|
495
545
|
}
|
|
496
546
|
return PROMISE_RESOLVE_TRUE;
|
|
@@ -574,6 +624,7 @@ export function createMemoryStorageInstance<RxDocType>(
|
|
|
574
624
|
documents: new Map(),
|
|
575
625
|
attachments: params.schema.attachments ? new Map() : undefined as any,
|
|
576
626
|
byIndex: {},
|
|
627
|
+
byIndexArray: [],
|
|
577
628
|
changes$: new Subject()
|
|
578
629
|
};
|
|
579
630
|
addIndexesToInternalsState(internals, params.schema);
|
|
@@ -6,7 +6,8 @@ import type {
|
|
|
6
6
|
RxJsonSchema
|
|
7
7
|
} from '../../types/index.d.ts';
|
|
8
8
|
import {
|
|
9
|
-
Sort as MongoSort
|
|
9
|
+
Sort as MongoSort,
|
|
10
|
+
MongoClient
|
|
10
11
|
} from 'mongodb';
|
|
11
12
|
import { RXDB_VERSION, flatClone } from '../utils/index.ts';
|
|
12
13
|
import { MongoDBPreparedQuery, MongoQuerySelector } from './mongodb-types.ts';
|
|
@@ -117,3 +118,44 @@ export function swapToMongoSort<RxDocType>(
|
|
|
117
118
|
export function getMongoDBIndexName(index: string[]): string {
|
|
118
119
|
return index.join('|');
|
|
119
120
|
}
|
|
121
|
+
|
|
122
|
+
export const MONGO_CLIENT_CACHE = new Map<string, { client: MongoClient, refCount: number, promise: Promise<MongoClient>, closeTimeout?: ReturnType<typeof setTimeout> }>();
|
|
123
|
+
|
|
124
|
+
export async function getMongoDBClient(connection: string): Promise<MongoClient> {
|
|
125
|
+
let cached = MONGO_CLIENT_CACHE.get(connection);
|
|
126
|
+
if (!cached) {
|
|
127
|
+
const client = new MongoClient(connection, MONGO_OPTIONS_DRIVER_INFO);
|
|
128
|
+
cached = {
|
|
129
|
+
client,
|
|
130
|
+
refCount: 1,
|
|
131
|
+
promise: client.connect().then(() => client)
|
|
132
|
+
};
|
|
133
|
+
MONGO_CLIENT_CACHE.set(connection, cached);
|
|
134
|
+
return cached.promise;
|
|
135
|
+
}
|
|
136
|
+
cached.refCount++;
|
|
137
|
+
if (cached.closeTimeout) {
|
|
138
|
+
clearTimeout(cached.closeTimeout);
|
|
139
|
+
cached.closeTimeout = undefined;
|
|
140
|
+
}
|
|
141
|
+
return cached.promise;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
export async function closeMongoDBClient(connection: string): Promise<void> {
|
|
145
|
+
const cached = MONGO_CLIENT_CACHE.get(connection);
|
|
146
|
+
if (cached) {
|
|
147
|
+
cached.refCount--;
|
|
148
|
+
if (cached.refCount === 0) {
|
|
149
|
+
if (cached.closeTimeout) {
|
|
150
|
+
clearTimeout(cached.closeTimeout);
|
|
151
|
+
}
|
|
152
|
+
cached.closeTimeout = setTimeout(() => {
|
|
153
|
+
const innerCached = MONGO_CLIENT_CACHE.get(connection);
|
|
154
|
+
if (innerCached && innerCached.refCount === 0) {
|
|
155
|
+
MONGO_CLIENT_CACHE.delete(connection);
|
|
156
|
+
innerCached.client.close().catch(() => { });
|
|
157
|
+
}
|
|
158
|
+
}, 2000); // 2 second delay to allow reuse
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
}
|