@connecttomahdi/rxdb 17.0.0-beta.17 → 17.1.1
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 +0 -7
- 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 +5 -23
- 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 +1 -8
- 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 +5 -23
- 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/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/dist/types/types/rx-error.d.ts +3 -0
- package/dist/types/types/rx-schema.d.ts +5 -0
- package/eslint.config.mjs +2 -1
- package/package.json +38 -35
- package/scripts/check-code-block-line-length.js +91 -0
- package/scripts/check-em-dashes.js +53 -0
- package/scripts/copy-path.mjs +20 -0
- package/scripts/docs-fetch-git-history.mjs +36 -0
- package/scripts/fix-types.mjs +15 -8
- 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
|
@@ -1,18 +1,19 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
2
|
+
* Optimized binary search functions for the memory storage.
|
|
3
|
+
* Based on https://github.com/mikolalysenko/binary-search-bounds
|
|
4
|
+
* but with performance improvements:
|
|
5
|
+
* - Removed unnecessary undefined checks for comparator
|
|
6
|
+
* - Inlined the norm() wrapper to avoid extra function calls
|
|
7
|
+
* - Added string-specialized variants to avoid temporary array allocations
|
|
7
8
|
*/
|
|
8
9
|
|
|
9
|
-
function
|
|
10
|
+
export function boundGE(a, y, c, lo, hi) {
|
|
11
|
+
var l = lo === undefined ? 0 : lo | 0;
|
|
12
|
+
var h = hi === undefined ? a.length - 1 : hi | 0;
|
|
10
13
|
var i = h + 1;
|
|
11
14
|
while (l <= h) {
|
|
12
15
|
var m = l + h >>> 1;
|
|
13
|
-
|
|
14
|
-
var p = c !== undefined ? c(x, y) : x - y;
|
|
15
|
-
if (p >= 0) {
|
|
16
|
+
if (c(a[m], y) >= 0) {
|
|
16
17
|
i = m;
|
|
17
18
|
h = m - 1;
|
|
18
19
|
} else {
|
|
@@ -21,13 +22,13 @@ function ge(a, y, c, l, h) {
|
|
|
21
22
|
}
|
|
22
23
|
return i;
|
|
23
24
|
}
|
|
24
|
-
function
|
|
25
|
+
export function boundGT(a, y, c, lo, hi) {
|
|
26
|
+
var l = lo === undefined ? 0 : lo | 0;
|
|
27
|
+
var h = hi === undefined ? a.length - 1 : hi | 0;
|
|
25
28
|
var i = h + 1;
|
|
26
29
|
while (l <= h) {
|
|
27
30
|
var m = l + h >>> 1;
|
|
28
|
-
|
|
29
|
-
var p = c !== undefined ? c(x, y) : x - y;
|
|
30
|
-
if (p > 0) {
|
|
31
|
+
if (c(a[m], y) > 0) {
|
|
31
32
|
i = m;
|
|
32
33
|
h = m - 1;
|
|
33
34
|
} else {
|
|
@@ -36,13 +37,13 @@ function gt(a, y, c, l, h) {
|
|
|
36
37
|
}
|
|
37
38
|
return i;
|
|
38
39
|
}
|
|
39
|
-
function
|
|
40
|
+
export function boundLT(a, y, c, lo, hi) {
|
|
41
|
+
var l = lo === undefined ? 0 : lo | 0;
|
|
42
|
+
var h = hi === undefined ? a.length - 1 : hi | 0;
|
|
40
43
|
var i = l - 1;
|
|
41
44
|
while (l <= h) {
|
|
42
|
-
var m = l + h >>> 1
|
|
43
|
-
|
|
44
|
-
var p = c !== undefined ? c(x, y) : x - y;
|
|
45
|
-
if (p < 0) {
|
|
45
|
+
var m = l + h >>> 1;
|
|
46
|
+
if (c(a[m], y) < 0) {
|
|
46
47
|
i = m;
|
|
47
48
|
l = m + 1;
|
|
48
49
|
} else {
|
|
@@ -51,13 +52,13 @@ function lt(a, y, c, l, h) {
|
|
|
51
52
|
}
|
|
52
53
|
return i;
|
|
53
54
|
}
|
|
54
|
-
function
|
|
55
|
+
export function boundLE(a, y, c, lo, hi) {
|
|
56
|
+
var l = lo === undefined ? 0 : lo | 0;
|
|
57
|
+
var h = hi === undefined ? a.length - 1 : hi | 0;
|
|
55
58
|
var i = l - 1;
|
|
56
59
|
while (l <= h) {
|
|
57
|
-
var m = l + h >>> 1
|
|
58
|
-
|
|
59
|
-
var p = c !== undefined ? c(x, y) : x - y;
|
|
60
|
-
if (p <= 0) {
|
|
60
|
+
var m = l + h >>> 1;
|
|
61
|
+
if (c(a[m], y) <= 0) {
|
|
61
62
|
i = m;
|
|
62
63
|
l = m + 1;
|
|
63
64
|
} else {
|
|
@@ -66,11 +67,12 @@ function le(a, y, c, l, h) {
|
|
|
66
67
|
}
|
|
67
68
|
return i;
|
|
68
69
|
}
|
|
69
|
-
function
|
|
70
|
+
export function boundEQ(a, y, c, lo, hi) {
|
|
71
|
+
var l = lo === undefined ? 0 : lo | 0;
|
|
72
|
+
var h = hi === undefined ? a.length - 1 : hi | 0;
|
|
70
73
|
while (l <= h) {
|
|
71
|
-
var m = l + h >>> 1
|
|
72
|
-
|
|
73
|
-
var p = c !== undefined ? c(x, y) : x - y;
|
|
74
|
+
var m = l + h >>> 1;
|
|
75
|
+
var p = c(a[m], y);
|
|
74
76
|
if (p === 0) {
|
|
75
77
|
return m;
|
|
76
78
|
}
|
|
@@ -82,22 +84,87 @@ function eq(a, y, c, l, h) {
|
|
|
82
84
|
}
|
|
83
85
|
return -1;
|
|
84
86
|
}
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Specialized binary search functions that compare DocWithIndexString
|
|
90
|
+
* entries directly against an index string, avoiding temporary array allocations.
|
|
91
|
+
* Used in query() and count() hot paths.
|
|
92
|
+
*/
|
|
93
|
+
export function boundGEByIndexString(a, indexString) {
|
|
94
|
+
var l = 0;
|
|
95
|
+
var h = a.length - 1;
|
|
96
|
+
var i = h + 1;
|
|
97
|
+
while (l <= h) {
|
|
98
|
+
var m = l + h >>> 1;
|
|
99
|
+
if (a[m][0] >= indexString) {
|
|
100
|
+
i = m;
|
|
101
|
+
h = m - 1;
|
|
102
|
+
} else {
|
|
103
|
+
l = m + 1;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
return i;
|
|
90
107
|
}
|
|
91
|
-
export function
|
|
92
|
-
|
|
108
|
+
export function boundGTByIndexString(a, indexString) {
|
|
109
|
+
var l = 0;
|
|
110
|
+
var h = a.length - 1;
|
|
111
|
+
var i = h + 1;
|
|
112
|
+
while (l <= h) {
|
|
113
|
+
var m = l + h >>> 1;
|
|
114
|
+
if (a[m][0] > indexString) {
|
|
115
|
+
i = m;
|
|
116
|
+
h = m - 1;
|
|
117
|
+
} else {
|
|
118
|
+
l = m + 1;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
return i;
|
|
93
122
|
}
|
|
94
|
-
export function
|
|
95
|
-
|
|
123
|
+
export function boundEQByIndexString(a, indexString) {
|
|
124
|
+
var l = 0;
|
|
125
|
+
var h = a.length - 1;
|
|
126
|
+
while (l <= h) {
|
|
127
|
+
var m = l + h >>> 1;
|
|
128
|
+
var s = a[m][0];
|
|
129
|
+
if (s === indexString) {
|
|
130
|
+
return m;
|
|
131
|
+
}
|
|
132
|
+
if (s < indexString) {
|
|
133
|
+
l = m + 1;
|
|
134
|
+
} else {
|
|
135
|
+
h = m - 1;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
return -1;
|
|
96
139
|
}
|
|
97
|
-
export function
|
|
98
|
-
|
|
140
|
+
export function boundLTByIndexString(a, indexString) {
|
|
141
|
+
var l = 0;
|
|
142
|
+
var h = a.length - 1;
|
|
143
|
+
var i = l - 1;
|
|
144
|
+
while (l <= h) {
|
|
145
|
+
var m = l + h >>> 1;
|
|
146
|
+
if (a[m][0] < indexString) {
|
|
147
|
+
i = m;
|
|
148
|
+
l = m + 1;
|
|
149
|
+
} else {
|
|
150
|
+
h = m - 1;
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
return i;
|
|
99
154
|
}
|
|
100
|
-
export function
|
|
101
|
-
|
|
155
|
+
export function boundLEByIndexString(a, indexString) {
|
|
156
|
+
var l = 0;
|
|
157
|
+
var h = a.length - 1;
|
|
158
|
+
var i = l - 1;
|
|
159
|
+
while (l <= h) {
|
|
160
|
+
var m = l + h >>> 1;
|
|
161
|
+
if (a[m][0] <= indexString) {
|
|
162
|
+
i = m;
|
|
163
|
+
l = m + 1;
|
|
164
|
+
} else {
|
|
165
|
+
h = m - 1;
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
return i;
|
|
102
169
|
}
|
|
103
170
|
//# sourceMappingURL=binary-search-bounds.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"binary-search-bounds.js","names":["ge","a","y","c","l","h","i","m","x","p","undefined","gt","lt","le","eq","norm","f","length","boundGE","boundGT","boundLT","boundLE","boundEQ"],"sources":["../../../../src/plugins/storage-memory/binary-search-bounds.ts"],"sourcesContent":["/**\r\n * Everything in this file was copied and adapted from\r\n * @link https://github.com/mikolalysenko/binary-search-bounds\r\n *\r\n * We should use the original npm module instead when this bug is fixed:\r\n * @link https://github.com/mikolalysenko/binary-search-bounds/pull/14\r\n */\r\n\r\n\r\n\r\ntype Compare<T> = ((a: T, b: T) => number | null | undefined);\r\n\r\nfunction ge<T>(a: T[], y: T, c: Compare<T>, l?: any, h?: any): number {\r\n let i: number = h + 1;\r\n while (l <= h) {\r\n const m = (l + h) >>> 1;\r\n const x: any = a[m];\r\n const p: any = (c !== undefined) ? c(x, y) : (x - (y as any));\r\n if (p >= 0) {\r\n i = m; h = m - 1;\r\n } else {\r\n l = m + 1;\r\n }\r\n }\r\n return i;\r\n}\r\n\r\nfunction gt<T>(a: T[], y: T, c: Compare<T>, l?: any, h?: any): number {\r\n let i = h + 1;\r\n while (l <= h) {\r\n const m = (l + h) >>> 1;\r\n const x = a[m];\r\n const p: any = (c !== undefined) ? c(x, y) : ((x as any) - (y as any));\r\n if (p > 0) {\r\n i = m; h = m - 1;\r\n } else {\r\n l = m + 1;\r\n }\r\n }\r\n return i;\r\n}\r\n\r\nfunction lt<T>(a: T[], y: T, c: Compare<T>, l?: any, h?: any): number {\r\n let i = l - 1;\r\n while (l <= h) {\r\n const m = (l + h) >>> 1, x = a[m];\r\n const p: any = (c !== undefined) ? c(x, y) : ((x as any) - (y as any));\r\n if (p < 0) {\r\n i = m; l = m + 1;\r\n } else {\r\n h = m - 1;\r\n }\r\n }\r\n return i;\r\n}\r\n\r\nfunction le<T>(a: T[], y: T, c: Compare<T>, l?: any, h?: any): number {\r\n let i = l - 1;\r\n while (l <= h) {\r\n const m = (l + h) >>> 1, x = a[m];\r\n const p: any = (c !== undefined) ? c(x, y) : ((x as any) - (y as any));\r\n if (p <= 0) {\r\n i = m; l = m + 1;\r\n } else {\r\n h = m - 1;\r\n }\r\n }\r\n return i;\r\n}\r\n\r\nfunction eq<T>(a: T[], y: T, c: Compare<T>, l?: any, h?: any): number {\r\n while (l <= h) {\r\n const m = (l + h) >>> 1, x = a[m];\r\n const p: any = (c !== undefined) ? c(x, y) : ((x as any) - (y as any));\r\n if (p === 0) {\r\n return m;\r\n }\r\n if (p <= 0) {\r\n l = m + 1;\r\n } else {\r\n h = m - 1;\r\n }\r\n }\r\n return -1;\r\n}\r\n\r\nfunction norm<T>(a: T[], y: T, c: Compare<T>, l: any, h: any, f: any) {\r\n return f(a, y, c, (l === undefined) ? 0 : l | 0, (h === undefined) ? a.length - 1 : h | 0);\r\n}\r\n\r\n\r\nexport function boundGE<T>(a: T[], y: T, c: Compare<T>, l?: any, h?: any) {\r\n return norm(a, y, c, l, h, ge);\r\n}\r\nexport function boundGT<T>(a: T[], y: T, c: Compare<T>, l?: any, h?: any) {\r\n return norm(a, y, c, l, h, gt);\r\n}\r\nexport function boundLT<T>(a: T[], y: T, c: Compare<T>, l?: any, h?: any) {\r\n return norm(a, y, c, l, h, lt);\r\n}\r\nexport function boundLE<T>(a: T[], y: T, c: Compare<T>, l?: any, h?: any) {\r\n return norm(a, y, c, l, h, le);\r\n}\r\nexport function boundEQ<T>(a: T[], y: T, c: Compare<T>, l?: any, h?: any) {\r\n return norm(a, y, c, l, h, eq);\r\n}\r\n"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{"version":3,"file":"binary-search-bounds.js","names":["boundGE","a","y","c","lo","hi","l","undefined","h","length","i","m","boundGT","boundLT","boundLE","boundEQ","p","boundGEByIndexString","indexString","boundGTByIndexString","boundEQByIndexString","s","boundLTByIndexString","boundLEByIndexString"],"sources":["../../../../src/plugins/storage-memory/binary-search-bounds.ts"],"sourcesContent":["/**\r\n * Optimized binary search functions for the memory storage.\r\n * Based on https://github.com/mikolalysenko/binary-search-bounds\r\n * but with performance improvements:\r\n * - Removed unnecessary undefined checks for comparator\r\n * - Inlined the norm() wrapper to avoid extra function calls\r\n * - Added string-specialized variants to avoid temporary array allocations\r\n */\r\n\r\ntype Compare<T> = ((a: T, b: T) => number | null | undefined);\r\n\r\nexport function boundGE<T>(a: T[], y: T, c: Compare<T>, lo?: any, hi?: any): number {\r\n let l: number = lo === undefined ? 0 : lo | 0;\r\n let h: number = hi === undefined ? a.length - 1 : hi | 0;\r\n let i: number = h + 1;\r\n while (l <= h) {\r\n const m = (l + h) >>> 1;\r\n if ((c(a[m], y) as number) >= 0) {\r\n i = m; h = m - 1;\r\n } else {\r\n l = m + 1;\r\n }\r\n }\r\n return i;\r\n}\r\n\r\nexport function boundGT<T>(a: T[], y: T, c: Compare<T>, lo?: any, hi?: any): number {\r\n let l: number = lo === undefined ? 0 : lo | 0;\r\n let h: number = hi === undefined ? a.length - 1 : hi | 0;\r\n let i = h + 1;\r\n while (l <= h) {\r\n const m = (l + h) >>> 1;\r\n if ((c(a[m], y) as number) > 0) {\r\n i = m; h = m - 1;\r\n } else {\r\n l = m + 1;\r\n }\r\n }\r\n return i;\r\n}\r\n\r\nexport function boundLT<T>(a: T[], y: T, c: Compare<T>, lo?: any, hi?: any): number {\r\n let l: number = lo === undefined ? 0 : lo | 0;\r\n let h: number = hi === undefined ? a.length - 1 : hi | 0;\r\n let i = l - 1;\r\n while (l <= h) {\r\n const m = (l + h) >>> 1;\r\n if ((c(a[m], y) as number) < 0) {\r\n i = m; l = m + 1;\r\n } else {\r\n h = m - 1;\r\n }\r\n }\r\n return i;\r\n}\r\n\r\nexport function boundLE<T>(a: T[], y: T, c: Compare<T>, lo?: any, hi?: any): number {\r\n let l: number = lo === undefined ? 0 : lo | 0;\r\n let h: number = hi === undefined ? a.length - 1 : hi | 0;\r\n let i = l - 1;\r\n while (l <= h) {\r\n const m = (l + h) >>> 1;\r\n if ((c(a[m], y) as number) <= 0) {\r\n i = m; l = m + 1;\r\n } else {\r\n h = m - 1;\r\n }\r\n }\r\n return i;\r\n}\r\n\r\nexport function boundEQ<T>(a: T[], y: T, c: Compare<T>, lo?: any, hi?: any): number {\r\n let l: number = lo === undefined ? 0 : lo | 0;\r\n let h: number = hi === undefined ? a.length - 1 : hi | 0;\r\n while (l <= h) {\r\n const m = (l + h) >>> 1;\r\n const p = c(a[m], y) as number;\r\n if (p === 0) {\r\n return m;\r\n }\r\n if (p <= 0) {\r\n l = m + 1;\r\n } else {\r\n h = m - 1;\r\n }\r\n }\r\n return -1;\r\n}\r\n\r\n/**\r\n * Specialized binary search functions that compare DocWithIndexString\r\n * entries directly against an index string, avoiding temporary array allocations.\r\n * Used in query() and count() hot paths.\r\n */\r\nexport function boundGEByIndexString<T extends [string, ...any[]]>(a: T[], indexString: string): number {\r\n let l = 0;\r\n let h = a.length - 1;\r\n let i: number = h + 1;\r\n while (l <= h) {\r\n const m = (l + h) >>> 1;\r\n if (a[m][0] >= indexString) {\r\n i = m; h = m - 1;\r\n } else {\r\n l = m + 1;\r\n }\r\n }\r\n return i;\r\n}\r\n\r\nexport function boundGTByIndexString<T extends [string, ...any[]]>(a: T[], indexString: string): number {\r\n let l = 0;\r\n let h = a.length - 1;\r\n let i = h + 1;\r\n while (l <= h) {\r\n const m = (l + h) >>> 1;\r\n if (a[m][0] > indexString) {\r\n i = m; h = m - 1;\r\n } else {\r\n l = m + 1;\r\n }\r\n }\r\n return i;\r\n}\r\n\r\nexport function boundEQByIndexString<T extends [string, ...any[]]>(a: T[], indexString: string): number {\r\n let l = 0;\r\n let h = a.length - 1;\r\n while (l <= h) {\r\n const m = (l + h) >>> 1;\r\n const s = a[m][0];\r\n if (s === indexString) {\r\n return m;\r\n }\r\n if (s < indexString) {\r\n l = m + 1;\r\n } else {\r\n h = m - 1;\r\n }\r\n }\r\n return -1;\r\n}\r\n\r\nexport function boundLTByIndexString<T extends [string, ...any[]]>(a: T[], indexString: string): number {\r\n let l = 0;\r\n let h = a.length - 1;\r\n let i = l - 1;\r\n while (l <= h) {\r\n const m = (l + h) >>> 1;\r\n if (a[m][0] < indexString) {\r\n i = m; l = m + 1;\r\n } else {\r\n h = m - 1;\r\n }\r\n }\r\n return i;\r\n}\r\n\r\nexport function boundLEByIndexString<T extends [string, ...any[]]>(a: T[], indexString: string): number {\r\n let l = 0;\r\n let h = a.length - 1;\r\n let i = l - 1;\r\n while (l <= h) {\r\n const m = (l + h) >>> 1;\r\n if (a[m][0] <= indexString) {\r\n i = m; l = m + 1;\r\n } else {\r\n h = m - 1;\r\n }\r\n }\r\n return i;\r\n}\r\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { pushAtSortPosition } from 'array-push-at-sort-position';
|
|
2
2
|
import { newRxError } from "../../rx-error.js";
|
|
3
|
-
import {
|
|
3
|
+
import { boundEQByIndexString } from "./binary-search-bounds.js";
|
|
4
4
|
export function getMemoryCollectionKey(databaseName, collectionName, schemaVersion) {
|
|
5
5
|
return [databaseName, collectionName, schemaVersion].join('--memory--');
|
|
6
6
|
}
|
|
@@ -12,6 +12,14 @@ export function ensureNotRemoved(instance) {
|
|
|
12
12
|
export function attachmentMapKey(documentId, attachmentId) {
|
|
13
13
|
return documentId + '||' + attachmentId;
|
|
14
14
|
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* @performance
|
|
18
|
+
* Threshold for using in-place splice vs. full merge-sort when inserting
|
|
19
|
+
* documents into indexes. Below this batch size, in-place binary search + splice
|
|
20
|
+
* is faster because it avoids allocating a new full-size array and copying all elements.
|
|
21
|
+
*/
|
|
22
|
+
var IN_PLACE_INSERT_THRESHOLD = 64;
|
|
15
23
|
function sortByIndexStringComparator(a, b) {
|
|
16
24
|
if (a[0] < b[0]) {
|
|
17
25
|
return -1;
|
|
@@ -25,29 +33,57 @@ function sortByIndexStringComparator(a, b) {
|
|
|
25
33
|
*/
|
|
26
34
|
export function putWriteRowToState(docId, state, stateByIndex, document, docInState) {
|
|
27
35
|
state.documents.set(docId, document);
|
|
28
|
-
|
|
36
|
+
var stateByIndexLength = stateByIndex.length;
|
|
37
|
+
for (var i = 0; i < stateByIndexLength; ++i) {
|
|
29
38
|
var byIndex = stateByIndex[i];
|
|
30
39
|
var docsWithIndex = byIndex.docsWithIndex;
|
|
31
40
|
var getIndexableString = byIndex.getIndexableString;
|
|
32
41
|
var newIndexString = getIndexableString(document);
|
|
33
|
-
var insertPosition = pushAtSortPosition(docsWithIndex, [newIndexString, document, docId], sortByIndexStringComparator, 0);
|
|
34
42
|
|
|
35
43
|
/**
|
|
36
|
-
*
|
|
44
|
+
* @performance
|
|
45
|
+
* When updating a document, first compute whether the index changed.
|
|
46
|
+
* If it did not change, we only need to update the document reference
|
|
47
|
+
* in-place without any splice operations.
|
|
37
48
|
*/
|
|
38
49
|
if (docInState) {
|
|
39
50
|
var previousIndexString = getIndexableString(docInState);
|
|
40
51
|
if (previousIndexString === newIndexString) {
|
|
41
52
|
/**
|
|
42
53
|
* Performance shortcut.
|
|
43
|
-
*
|
|
54
|
+
* Index did not change, so the old entry is at the same position.
|
|
55
|
+
* We can find it by string-specialized binary search and update in-place.
|
|
44
56
|
*/
|
|
45
|
-
var
|
|
46
|
-
if (
|
|
57
|
+
var eqPos = boundEQByIndexString(docsWithIndex, previousIndexString);
|
|
58
|
+
if (eqPos !== -1) {
|
|
59
|
+
/**
|
|
60
|
+
* There might be multiple entries with the same index string
|
|
61
|
+
* (e.g. different documents). Search around eqPos for ours.
|
|
62
|
+
*/
|
|
63
|
+
if (docsWithIndex[eqPos][2] === docId) {
|
|
64
|
+
docsWithIndex[eqPos][1] = document;
|
|
65
|
+
continue;
|
|
66
|
+
}
|
|
67
|
+
// Check neighbors
|
|
68
|
+
var prev = docsWithIndex[eqPos - 1];
|
|
69
|
+
if (prev && prev[0] === previousIndexString && prev[2] === docId) {
|
|
70
|
+
docsWithIndex[eqPos - 1][1] = document;
|
|
71
|
+
continue;
|
|
72
|
+
}
|
|
73
|
+
var next = docsWithIndex[eqPos + 1];
|
|
74
|
+
if (next && next[0] === previousIndexString && next[2] === docId) {
|
|
75
|
+
docsWithIndex[eqPos + 1][1] = document;
|
|
76
|
+
continue;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
// Fallback: use the old insert+remove approach
|
|
80
|
+
var insertPosition = pushAtSortPosition(docsWithIndex, [newIndexString, document, docId], sortByIndexStringComparator, 0);
|
|
81
|
+
var prevEntry = docsWithIndex[insertPosition - 1];
|
|
82
|
+
if (prevEntry && prevEntry[2] === docId) {
|
|
47
83
|
docsWithIndex.splice(insertPosition - 1, 1);
|
|
48
84
|
} else {
|
|
49
|
-
var
|
|
50
|
-
if (
|
|
85
|
+
var nextEntry = docsWithIndex[insertPosition + 1];
|
|
86
|
+
if (nextEntry[2] === docId) {
|
|
51
87
|
docsWithIndex.splice(insertPosition + 1, 1);
|
|
52
88
|
} else {
|
|
53
89
|
throw newRxError('SNH', {
|
|
@@ -58,26 +94,35 @@ export function putWriteRowToState(docId, state, stateByIndex, document, docInSt
|
|
|
58
94
|
});
|
|
59
95
|
}
|
|
60
96
|
}
|
|
97
|
+
continue;
|
|
61
98
|
} else {
|
|
62
99
|
/**
|
|
63
|
-
* Index changed, we must
|
|
100
|
+
* Index changed, we must remove the old entry and insert the new one.
|
|
64
101
|
*/
|
|
65
|
-
var indexBefore =
|
|
66
|
-
|
|
102
|
+
var indexBefore = boundEQByIndexString(docsWithIndex, previousIndexString);
|
|
103
|
+
if (indexBefore !== -1) {
|
|
104
|
+
docsWithIndex.splice(indexBefore, 1);
|
|
105
|
+
}
|
|
67
106
|
}
|
|
68
107
|
}
|
|
108
|
+
pushAtSortPosition(docsWithIndex, [newIndexString, document, docId], sortByIndexStringComparator, 0);
|
|
69
109
|
}
|
|
70
110
|
}
|
|
71
111
|
|
|
72
112
|
/**
|
|
73
113
|
* @hotPath
|
|
74
114
|
* Efficiently inserts multiple documents into the state at once.
|
|
75
|
-
*
|
|
76
|
-
*
|
|
77
|
-
*
|
|
115
|
+
*
|
|
116
|
+
* Uses two strategies based on batch size:
|
|
117
|
+
* - For small batches (relative to existing index size), uses in-place
|
|
118
|
+
* binary search + splice per document. This avoids allocating a new
|
|
119
|
+
* full-size array and copying all elements, reducing GC pressure.
|
|
120
|
+
* - For large batches (or empty indexes), pre-computes all index entries,
|
|
121
|
+
* sorts them, and merges into the existing sorted arrays in a single pass.
|
|
78
122
|
*/
|
|
79
123
|
export function bulkInsertToState(primaryPath, state, stateByIndex, docs) {
|
|
80
124
|
var docsLength = docs.length;
|
|
125
|
+
var stateByIndexLength = stateByIndex.length;
|
|
81
126
|
|
|
82
127
|
// Extract documents and docIds once, store in Map
|
|
83
128
|
var documents = new Array(docsLength);
|
|
@@ -90,36 +135,74 @@ export function bulkInsertToState(primaryPath, state, stateByIndex, docs) {
|
|
|
90
135
|
state.documents.set(docId, doc);
|
|
91
136
|
}
|
|
92
137
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
138
|
+
/**
|
|
139
|
+
* @performance
|
|
140
|
+
* For small batch sizes, use in-place binary search + splice
|
|
141
|
+
* instead of creating a full merged array copy. This is faster
|
|
142
|
+
* for serial inserts and small bulk inserts because it avoids:
|
|
143
|
+
* - Allocating a new array of size n+m
|
|
144
|
+
* - Copying all n existing elements
|
|
145
|
+
* - GC pressure from discarding the old array
|
|
146
|
+
*
|
|
147
|
+
* The threshold is based on when the merge approach becomes more
|
|
148
|
+
* efficient than individual splices.
|
|
149
|
+
*/
|
|
150
|
+
var useInPlaceInsert = docsLength < IN_PLACE_INSERT_THRESHOLD;
|
|
151
|
+
if (useInPlaceInsert) {
|
|
152
|
+
for (var indexI = 0; indexI < stateByIndexLength; ++indexI) {
|
|
153
|
+
var byIndex = stateByIndex[indexI];
|
|
154
|
+
var docsWithIndex = byIndex.docsWithIndex;
|
|
155
|
+
var getIndexableString = byIndex.getIndexableString;
|
|
156
|
+
if (docsWithIndex.length === 0) {
|
|
157
|
+
for (var _i = 0; _i < docsLength; ++_i) {
|
|
158
|
+
var _doc = documents[_i];
|
|
159
|
+
var indexString = getIndexableString(_doc);
|
|
160
|
+
docsWithIndex.push([indexString, _doc, docIds[_i]]);
|
|
161
|
+
}
|
|
162
|
+
docsWithIndex.sort(sortByIndexStringComparator);
|
|
163
|
+
} else {
|
|
164
|
+
for (var _i2 = 0; _i2 < docsLength; ++_i2) {
|
|
165
|
+
var _doc2 = documents[_i2];
|
|
166
|
+
var _indexString = getIndexableString(_doc2);
|
|
167
|
+
var newEntry = [_indexString, _doc2, docIds[_i2]];
|
|
168
|
+
pushAtSortPosition(docsWithIndex, newEntry, sortByIndexStringComparator, 0);
|
|
169
|
+
}
|
|
170
|
+
}
|
|
104
171
|
}
|
|
172
|
+
} else {
|
|
173
|
+
// For each index, batch-compute entries, sort, and merge
|
|
174
|
+
for (var _indexI = 0; _indexI < stateByIndexLength; ++_indexI) {
|
|
175
|
+
var _byIndex = stateByIndex[_indexI];
|
|
176
|
+
var _docsWithIndex = _byIndex.docsWithIndex;
|
|
177
|
+
var _getIndexableString = _byIndex.getIndexableString;
|
|
105
178
|
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
179
|
+
// Build new entries
|
|
180
|
+
var newEntries = new Array(docsLength);
|
|
181
|
+
for (var _i3 = 0; _i3 < docsLength; ++_i3) {
|
|
182
|
+
var _doc3 = documents[_i3];
|
|
183
|
+
newEntries[_i3] = [_getIndexableString(_doc3), _doc3, docIds[_i3]];
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
// Sort by index string
|
|
187
|
+
newEntries.sort(sortByIndexStringComparator);
|
|
188
|
+
if (_docsWithIndex.length === 0) {
|
|
189
|
+
// Index is empty, just assign sorted entries
|
|
190
|
+
_byIndex.docsWithIndex = newEntries;
|
|
191
|
+
} else {
|
|
192
|
+
// Merge sorted arrays
|
|
193
|
+
_byIndex.docsWithIndex = mergeSortedArrays(_docsWithIndex, newEntries);
|
|
194
|
+
}
|
|
114
195
|
}
|
|
115
196
|
}
|
|
116
197
|
}
|
|
117
198
|
|
|
118
199
|
/**
|
|
119
|
-
* Merges two sorted arrays into a single sorted array.
|
|
200
|
+
* Merges two sorted DocWithIndexString arrays into a single sorted array.
|
|
120
201
|
* Runs in O(n + m) where n and m are the lengths of the input arrays.
|
|
202
|
+
* @performance Comparator is inlined to avoid function call overhead
|
|
203
|
+
* per comparison, which is significant for large arrays.
|
|
121
204
|
*/
|
|
122
|
-
function mergeSortedArrays(a, b
|
|
205
|
+
function mergeSortedArrays(a, b) {
|
|
123
206
|
var aLen = a.length;
|
|
124
207
|
var bLen = b.length;
|
|
125
208
|
var result = new Array(aLen + bLen);
|
|
@@ -127,7 +210,7 @@ function mergeSortedArrays(a, b, comparator) {
|
|
|
127
210
|
var bi = 0;
|
|
128
211
|
var ri = 0;
|
|
129
212
|
while (ai < aLen && bi < bLen) {
|
|
130
|
-
if (
|
|
213
|
+
if (a[ai][0] <= b[bi][0]) {
|
|
131
214
|
result[ri++] = a[ai++];
|
|
132
215
|
} else {
|
|
133
216
|
result[ri++] = b[bi++];
|
|
@@ -144,12 +227,16 @@ function mergeSortedArrays(a, b, comparator) {
|
|
|
144
227
|
export function removeDocFromState(primaryPath, schema, state, doc) {
|
|
145
228
|
var docId = doc[primaryPath];
|
|
146
229
|
state.documents.delete(docId);
|
|
147
|
-
|
|
230
|
+
var stateByIndex = state.byIndexArray;
|
|
231
|
+
for (var i = 0; i < stateByIndex.length; ++i) {
|
|
232
|
+
var byIndex = stateByIndex[i];
|
|
148
233
|
var docsWithIndex = byIndex.docsWithIndex;
|
|
149
234
|
var indexString = byIndex.getIndexableString(doc);
|
|
150
|
-
var positionInIndex =
|
|
151
|
-
|
|
152
|
-
|
|
235
|
+
var positionInIndex = boundEQByIndexString(docsWithIndex, indexString);
|
|
236
|
+
if (positionInIndex !== -1) {
|
|
237
|
+
docsWithIndex.splice(positionInIndex, 1);
|
|
238
|
+
}
|
|
239
|
+
}
|
|
153
240
|
}
|
|
154
241
|
export function compareDocsWithIndex(a, b) {
|
|
155
242
|
var indexStringA = a[0];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"memory-helper.js","names":["pushAtSortPosition","newRxError","boundEQ","getMemoryCollectionKey","databaseName","collectionName","schemaVersion","join","ensureNotRemoved","instance","internals","removed","Error","schema","version","attachmentMapKey","documentId","attachmentId","sortByIndexStringComparator","a","b","putWriteRowToState","docId","state","stateByIndex","document","docInState","documents","set","i","length","byIndex","docsWithIndex","getIndexableString","newIndexString","insertPosition","previousIndexString","prev","splice","next","args","indexBefore","compareDocsWithIndex","bulkInsertToState","primaryPath","docs","docsLength","Array","docIds","doc","indexI","newEntries","sort","mergeSortedArrays","comparator","aLen","bLen","result","ai","bi","ri","removeDocFromState","delete","Object","values","forEach","indexString","positionInIndex","indexStringA","indexStringB"],"sources":["../../../../src/plugins/storage-memory/memory-helper.ts"],"sourcesContent":["import type {\r\n BulkWriteRow,\r\n RxDocumentData,\r\n RxJsonSchema\r\n} from '../../types/index.d.ts';\r\nimport type {\r\n DocWithIndexString,\r\n MemoryStorageInternals,\r\n MemoryStorageInternalsByIndex\r\n} from './memory-types.ts';\r\nimport type { RxStorageInstanceMemory } from './rx-storage-instance-memory.ts';\r\nimport {\r\n pushAtSortPosition\r\n} from 'array-push-at-sort-position';\r\nimport { newRxError } from '../../rx-error.ts';\r\nimport { boundEQ } from './binary-search-bounds.ts';\r\n\r\n\r\nexport function getMemoryCollectionKey(\r\n databaseName: string,\r\n collectionName: string,\r\n schemaVersion: number\r\n): string {\r\n return [\r\n databaseName,\r\n collectionName,\r\n schemaVersion\r\n ].join('--memory--');\r\n}\r\n\r\n\r\nexport function ensureNotRemoved(\r\n instance: RxStorageInstanceMemory<any>\r\n) {\r\n if (instance.internals.removed) {\r\n throw new Error(\r\n 'removed already ' +\r\n instance.databaseName + ' - ' + instance.collectionName +\r\n ' - ' + instance.schema.version\r\n );\r\n }\r\n}\r\n\r\nexport function attachmentMapKey(documentId: string, attachmentId: string): string {\r\n return documentId + '||' + attachmentId;\r\n}\r\n\r\n\r\nfunction sortByIndexStringComparator<RxDocType>(a: DocWithIndexString<RxDocType>, b: DocWithIndexString<RxDocType>) {\r\n if (a[0] < b[0]) {\r\n return -1;\r\n } else {\r\n return 1;\r\n }\r\n}\r\n\r\n\r\n\r\n/**\r\n * @hotPath\r\n */\r\nexport function putWriteRowToState<RxDocType>(\r\n docId: string,\r\n state: MemoryStorageInternals<RxDocType>,\r\n stateByIndex: MemoryStorageInternalsByIndex<RxDocType>[],\r\n document: RxDocumentData<RxDocType>,\r\n docInState?: RxDocumentData<RxDocType>\r\n) {\r\n state.documents.set(docId, document as any);\r\n for (let i = 0; i < stateByIndex.length; ++i) {\r\n const byIndex = stateByIndex[i];\r\n const docsWithIndex = byIndex.docsWithIndex;\r\n const getIndexableString = byIndex.getIndexableString;\r\n const newIndexString = getIndexableString(document as any);\r\n const insertPosition = pushAtSortPosition(\r\n docsWithIndex,\r\n [\r\n newIndexString,\r\n document,\r\n docId,\r\n ],\r\n sortByIndexStringComparator,\r\n 0\r\n );\r\n\r\n /**\r\n * Remove previous if it was in the state\r\n */\r\n if (docInState) {\r\n const previousIndexString = getIndexableString(docInState);\r\n if (previousIndexString === newIndexString) {\r\n /**\r\n * Performance shortcut.\r\n * If index was not changed -> The old doc must be before or after the new one.\r\n */\r\n const prev = docsWithIndex[insertPosition - 1];\r\n if (prev && prev[2] === docId) {\r\n docsWithIndex.splice(insertPosition - 1, 1);\r\n } else {\r\n const next = docsWithIndex[insertPosition + 1];\r\n if (next[2] === docId) {\r\n docsWithIndex.splice(insertPosition + 1, 1);\r\n } else {\r\n throw newRxError('SNH', {\r\n document,\r\n args: {\r\n byIndex\r\n }\r\n });\r\n }\r\n }\r\n } else {\r\n /**\r\n * Index changed, we must search for the old one and remove it.\r\n */\r\n const indexBefore = boundEQ(\r\n docsWithIndex,\r\n [\r\n previousIndexString\r\n ] as any,\r\n compareDocsWithIndex\r\n );\r\n docsWithIndex.splice(indexBefore, 1);\r\n }\r\n }\r\n }\r\n}\r\n\r\n\r\n/**\r\n * @hotPath\r\n * Efficiently inserts multiple documents into the state at once.\r\n * Instead of inserting one-by-one with Array.splice() (O(n) per insert),\r\n * this pre-computes all index entries, sorts them, and merges them into\r\n * the existing sorted arrays in a single pass (O(n log n + n + m)).\r\n */\r\nexport function bulkInsertToState<RxDocType>(\r\n primaryPath: string,\r\n state: MemoryStorageInternals<RxDocType>,\r\n stateByIndex: MemoryStorageInternalsByIndex<RxDocType>[],\r\n docs: { document: RxDocumentData<RxDocType> }[]\r\n) {\r\n const docsLength = docs.length;\r\n\r\n // Extract documents and docIds once, store in Map\r\n const documents: RxDocumentData<RxDocType>[] = new Array(docsLength);\r\n const docIds: string[] = new Array(docsLength);\r\n for (let i = 0; i < docsLength; ++i) {\r\n const doc = docs[i].document;\r\n const docId: string = (doc as any)[primaryPath];\r\n documents[i] = doc;\r\n docIds[i] = docId;\r\n state.documents.set(docId, doc as any);\r\n }\r\n\r\n // For each index, batch-compute entries, sort, and merge\r\n for (let indexI = 0; indexI < stateByIndex.length; ++indexI) {\r\n const byIndex = stateByIndex[indexI];\r\n const docsWithIndex = byIndex.docsWithIndex;\r\n const getIndexableString = byIndex.getIndexableString;\r\n\r\n // Build new entries\r\n const newEntries: DocWithIndexString<RxDocType>[] = new Array(docsLength);\r\n for (let i = 0; i < docsLength; ++i) {\r\n const doc = documents[i];\r\n newEntries[i] = [\r\n getIndexableString(doc as any),\r\n doc,\r\n docIds[i]\r\n ];\r\n }\r\n\r\n // Sort by index string\r\n newEntries.sort(sortByIndexStringComparator);\r\n\r\n if (docsWithIndex.length === 0) {\r\n // Index is empty, just assign sorted entries\r\n byIndex.docsWithIndex = newEntries;\r\n } else {\r\n // Merge sorted arrays\r\n byIndex.docsWithIndex = mergeSortedArrays(docsWithIndex, newEntries, sortByIndexStringComparator);\r\n }\r\n }\r\n}\r\n\r\n\r\n/**\r\n * Merges two sorted arrays into a single sorted array.\r\n * Runs in O(n + m) where n and m are the lengths of the input arrays.\r\n */\r\nfunction mergeSortedArrays<T>(\r\n a: T[],\r\n b: T[],\r\n comparator: (x: T, y: T) => number\r\n): T[] {\r\n const aLen = a.length;\r\n const bLen = b.length;\r\n const result: T[] = new Array(aLen + bLen);\r\n let ai = 0;\r\n let bi = 0;\r\n let ri = 0;\r\n\r\n while (ai < aLen && bi < bLen) {\r\n if (comparator(a[ai], b[bi]) <= 0) {\r\n result[ri++] = a[ai++];\r\n } else {\r\n result[ri++] = b[bi++];\r\n }\r\n }\r\n\r\n while (ai < aLen) {\r\n result[ri++] = a[ai++];\r\n }\r\n while (bi < bLen) {\r\n result[ri++] = b[bi++];\r\n }\r\n\r\n return result;\r\n}\r\n\r\nexport function removeDocFromState<RxDocType>(\r\n primaryPath: string,\r\n schema: RxJsonSchema<RxDocumentData<RxDocType>>,\r\n state: MemoryStorageInternals<RxDocType>,\r\n doc: RxDocumentData<RxDocType>\r\n) {\r\n const docId: string = (doc as any)[primaryPath];\r\n state.documents.delete(docId);\r\n\r\n Object.values(state.byIndex).forEach(byIndex => {\r\n const docsWithIndex = byIndex.docsWithIndex;\r\n const indexString = byIndex.getIndexableString(doc);\r\n\r\n const positionInIndex = boundEQ(\r\n docsWithIndex,\r\n [\r\n indexString\r\n ] as any,\r\n compareDocsWithIndex\r\n );\r\n docsWithIndex.splice(positionInIndex, 1);\r\n });\r\n}\r\n\r\n\r\nexport function compareDocsWithIndex<RxDocType>(\r\n a: DocWithIndexString<RxDocType>,\r\n b: DocWithIndexString<RxDocType>\r\n): 1 | 0 | -1 {\r\n const indexStringA = a[0];\r\n const indexStringB = b[0];\r\n if (indexStringA < indexStringB) {\r\n return -1;\r\n } else if (indexStringA === indexStringB) {\r\n return 0;\r\n } else {\r\n return 1;\r\n }\r\n}\r\n"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{"version":3,"file":"memory-helper.js","names":["pushAtSortPosition","newRxError","boundEQByIndexString","getMemoryCollectionKey","databaseName","collectionName","schemaVersion","join","ensureNotRemoved","instance","internals","removed","Error","schema","version","attachmentMapKey","documentId","attachmentId","IN_PLACE_INSERT_THRESHOLD","sortByIndexStringComparator","a","b","putWriteRowToState","docId","state","stateByIndex","document","docInState","documents","set","stateByIndexLength","length","i","byIndex","docsWithIndex","getIndexableString","newIndexString","previousIndexString","eqPos","prev","next","insertPosition","prevEntry","splice","nextEntry","args","indexBefore","bulkInsertToState","primaryPath","docs","docsLength","Array","docIds","doc","useInPlaceInsert","indexI","indexString","push","sort","newEntry","newEntries","mergeSortedArrays","aLen","bLen","result","ai","bi","ri","removeDocFromState","delete","byIndexArray","positionInIndex","compareDocsWithIndex","indexStringA","indexStringB"],"sources":["../../../../src/plugins/storage-memory/memory-helper.ts"],"sourcesContent":["import type {\r\n RxDocumentData,\r\n RxJsonSchema\r\n} from '../../types/index.d.ts';\r\nimport type {\r\n DocWithIndexString,\r\n MemoryStorageInternals,\r\n MemoryStorageInternalsByIndex\r\n} from './memory-types.ts';\r\nimport type { RxStorageInstanceMemory } from './rx-storage-instance-memory.ts';\r\nimport {\r\n pushAtSortPosition\r\n} from 'array-push-at-sort-position';\r\nimport { newRxError } from '../../rx-error.ts';\r\nimport { boundEQByIndexString } from './binary-search-bounds.ts';\r\n\r\n\r\nexport function getMemoryCollectionKey(\r\n databaseName: string,\r\n collectionName: string,\r\n schemaVersion: number\r\n): string {\r\n return [\r\n databaseName,\r\n collectionName,\r\n schemaVersion\r\n ].join('--memory--');\r\n}\r\n\r\n\r\nexport function ensureNotRemoved(\r\n instance: RxStorageInstanceMemory<any>\r\n) {\r\n if (instance.internals.removed) {\r\n throw new Error(\r\n 'removed already ' +\r\n instance.databaseName + ' - ' + instance.collectionName +\r\n ' - ' + instance.schema.version\r\n );\r\n }\r\n}\r\n\r\nexport function attachmentMapKey(documentId: string, attachmentId: string): string {\r\n return documentId + '||' + attachmentId;\r\n}\r\n\r\n\r\n/**\r\n * @performance\r\n * Threshold for using in-place splice vs. full merge-sort when inserting\r\n * documents into indexes. Below this batch size, in-place binary search + splice\r\n * is faster because it avoids allocating a new full-size array and copying all elements.\r\n */\r\nconst IN_PLACE_INSERT_THRESHOLD = 64;\r\n\r\nfunction sortByIndexStringComparator<RxDocType>(a: DocWithIndexString<RxDocType>, b: DocWithIndexString<RxDocType>) {\r\n if (a[0] < b[0]) {\r\n return -1;\r\n } else {\r\n return 1;\r\n }\r\n}\r\n\r\n\r\n\r\n/**\r\n * @hotPath\r\n */\r\nexport function putWriteRowToState<RxDocType>(\r\n docId: string,\r\n state: MemoryStorageInternals<RxDocType>,\r\n stateByIndex: MemoryStorageInternalsByIndex<RxDocType>[],\r\n document: RxDocumentData<RxDocType>,\r\n docInState?: RxDocumentData<RxDocType>\r\n) {\r\n state.documents.set(docId, document as any);\r\n const stateByIndexLength = stateByIndex.length;\r\n for (let i = 0; i < stateByIndexLength; ++i) {\r\n const byIndex = stateByIndex[i];\r\n const docsWithIndex = byIndex.docsWithIndex;\r\n const getIndexableString = byIndex.getIndexableString;\r\n const newIndexString = getIndexableString(document as any);\r\n\r\n /**\r\n * @performance\r\n * When updating a document, first compute whether the index changed.\r\n * If it did not change, we only need to update the document reference\r\n * in-place without any splice operations.\r\n */\r\n if (docInState) {\r\n const previousIndexString = getIndexableString(docInState);\r\n if (previousIndexString === newIndexString) {\r\n /**\r\n * Performance shortcut.\r\n * Index did not change, so the old entry is at the same position.\r\n * We can find it by string-specialized binary search and update in-place.\r\n */\r\n const eqPos = boundEQByIndexString(\r\n docsWithIndex,\r\n previousIndexString\r\n );\r\n if (eqPos !== -1) {\r\n /**\r\n * There might be multiple entries with the same index string\r\n * (e.g. different documents). Search around eqPos for ours.\r\n */\r\n if (docsWithIndex[eqPos][2] === docId) {\r\n docsWithIndex[eqPos][1] = document;\r\n continue;\r\n }\r\n // Check neighbors\r\n const prev = docsWithIndex[eqPos - 1];\r\n if (prev && prev[0] === previousIndexString && prev[2] === docId) {\r\n docsWithIndex[eqPos - 1][1] = document;\r\n continue;\r\n }\r\n const next = docsWithIndex[eqPos + 1];\r\n if (next && next[0] === previousIndexString && next[2] === docId) {\r\n docsWithIndex[eqPos + 1][1] = document;\r\n continue;\r\n }\r\n }\r\n // Fallback: use the old insert+remove approach\r\n const insertPosition = pushAtSortPosition(\r\n docsWithIndex,\r\n [newIndexString, document, docId],\r\n sortByIndexStringComparator,\r\n 0\r\n );\r\n const prevEntry = docsWithIndex[insertPosition - 1];\r\n if (prevEntry && prevEntry[2] === docId) {\r\n docsWithIndex.splice(insertPosition - 1, 1);\r\n } else {\r\n const nextEntry = docsWithIndex[insertPosition + 1];\r\n if (nextEntry[2] === docId) {\r\n docsWithIndex.splice(insertPosition + 1, 1);\r\n } else {\r\n throw newRxError('SNH', {\r\n document,\r\n args: {\r\n byIndex\r\n }\r\n });\r\n }\r\n }\r\n continue;\r\n } else {\r\n /**\r\n * Index changed, we must remove the old entry and insert the new one.\r\n */\r\n const indexBefore = boundEQByIndexString(\r\n docsWithIndex,\r\n previousIndexString\r\n );\r\n if (indexBefore !== -1) {\r\n docsWithIndex.splice(indexBefore, 1);\r\n }\r\n }\r\n }\r\n\r\n pushAtSortPosition(\r\n docsWithIndex,\r\n [newIndexString, document, docId],\r\n sortByIndexStringComparator,\r\n 0\r\n );\r\n }\r\n}\r\n\r\n\r\n/**\r\n * @hotPath\r\n * Efficiently inserts multiple documents into the state at once.\r\n *\r\n * Uses two strategies based on batch size:\r\n * - For small batches (relative to existing index size), uses in-place\r\n * binary search + splice per document. This avoids allocating a new\r\n * full-size array and copying all elements, reducing GC pressure.\r\n * - For large batches (or empty indexes), pre-computes all index entries,\r\n * sorts them, and merges into the existing sorted arrays in a single pass.\r\n */\r\nexport function bulkInsertToState<RxDocType>(\r\n primaryPath: string,\r\n state: MemoryStorageInternals<RxDocType>,\r\n stateByIndex: MemoryStorageInternalsByIndex<RxDocType>[],\r\n docs: { document: RxDocumentData<RxDocType> }[]\r\n) {\r\n const docsLength = docs.length;\r\n const stateByIndexLength = stateByIndex.length;\r\n\r\n // Extract documents and docIds once, store in Map\r\n const documents: RxDocumentData<RxDocType>[] = new Array(docsLength);\r\n const docIds: string[] = new Array(docsLength);\r\n for (let i = 0; i < docsLength; ++i) {\r\n const doc = docs[i].document;\r\n const docId: string = (doc as any)[primaryPath];\r\n documents[i] = doc;\r\n docIds[i] = docId;\r\n state.documents.set(docId, doc as any);\r\n }\r\n\r\n /**\r\n * @performance\r\n * For small batch sizes, use in-place binary search + splice\r\n * instead of creating a full merged array copy. This is faster\r\n * for serial inserts and small bulk inserts because it avoids:\r\n * - Allocating a new array of size n+m\r\n * - Copying all n existing elements\r\n * - GC pressure from discarding the old array\r\n *\r\n * The threshold is based on when the merge approach becomes more\r\n * efficient than individual splices.\r\n */\r\n const useInPlaceInsert = docsLength < IN_PLACE_INSERT_THRESHOLD;\r\n\r\n if (useInPlaceInsert) {\r\n for (let indexI = 0; indexI < stateByIndexLength; ++indexI) {\r\n const byIndex = stateByIndex[indexI];\r\n const docsWithIndex = byIndex.docsWithIndex;\r\n const getIndexableString = byIndex.getIndexableString;\r\n\r\n if (docsWithIndex.length === 0) {\r\n for (let i = 0; i < docsLength; ++i) {\r\n const doc = documents[i];\r\n const indexString = getIndexableString(doc as any);\r\n docsWithIndex.push([indexString, doc, docIds[i]]);\r\n }\r\n docsWithIndex.sort(sortByIndexStringComparator);\r\n } else {\r\n for (let i = 0; i < docsLength; ++i) {\r\n const doc = documents[i];\r\n const indexString = getIndexableString(doc as any);\r\n const newEntry: DocWithIndexString<RxDocType> = [indexString, doc, docIds[i]];\r\n pushAtSortPosition(\r\n docsWithIndex,\r\n newEntry,\r\n sortByIndexStringComparator,\r\n 0\r\n );\r\n }\r\n }\r\n }\r\n } else {\r\n // For each index, batch-compute entries, sort, and merge\r\n for (let indexI = 0; indexI < stateByIndexLength; ++indexI) {\r\n const byIndex = stateByIndex[indexI];\r\n const docsWithIndex = byIndex.docsWithIndex;\r\n const getIndexableString = byIndex.getIndexableString;\r\n\r\n // Build new entries\r\n const newEntries: DocWithIndexString<RxDocType>[] = new Array(docsLength);\r\n for (let i = 0; i < docsLength; ++i) {\r\n const doc = documents[i];\r\n newEntries[i] = [\r\n getIndexableString(doc as any),\r\n doc,\r\n docIds[i]\r\n ];\r\n }\r\n\r\n // Sort by index string\r\n newEntries.sort(sortByIndexStringComparator);\r\n\r\n if (docsWithIndex.length === 0) {\r\n // Index is empty, just assign sorted entries\r\n byIndex.docsWithIndex = newEntries;\r\n } else {\r\n // Merge sorted arrays\r\n byIndex.docsWithIndex = mergeSortedArrays(docsWithIndex, newEntries);\r\n }\r\n }\r\n }\r\n}\r\n\r\n\r\n/**\r\n * Merges two sorted DocWithIndexString arrays into a single sorted array.\r\n * Runs in O(n + m) where n and m are the lengths of the input arrays.\r\n * @performance Comparator is inlined to avoid function call overhead\r\n * per comparison, which is significant for large arrays.\r\n */\r\nfunction mergeSortedArrays<RxDocType>(\r\n a: DocWithIndexString<RxDocType>[],\r\n b: DocWithIndexString<RxDocType>[]\r\n): DocWithIndexString<RxDocType>[] {\r\n const aLen = a.length;\r\n const bLen = b.length;\r\n const result: DocWithIndexString<RxDocType>[] = new Array(aLen + bLen);\r\n let ai = 0;\r\n let bi = 0;\r\n let ri = 0;\r\n\r\n while (ai < aLen && bi < bLen) {\r\n if (a[ai][0] <= b[bi][0]) {\r\n result[ri++] = a[ai++];\r\n } else {\r\n result[ri++] = b[bi++];\r\n }\r\n }\r\n\r\n while (ai < aLen) {\r\n result[ri++] = a[ai++];\r\n }\r\n while (bi < bLen) {\r\n result[ri++] = b[bi++];\r\n }\r\n\r\n return result;\r\n}\r\n\r\nexport function removeDocFromState<RxDocType>(\r\n primaryPath: string,\r\n schema: RxJsonSchema<RxDocumentData<RxDocType>>,\r\n state: MemoryStorageInternals<RxDocType>,\r\n doc: RxDocumentData<RxDocType>\r\n) {\r\n const docId: string = (doc as any)[primaryPath];\r\n state.documents.delete(docId);\r\n\r\n const stateByIndex = state.byIndexArray;\r\n for (let i = 0; i < stateByIndex.length; ++i) {\r\n const byIndex = stateByIndex[i];\r\n const docsWithIndex = byIndex.docsWithIndex;\r\n const indexString = byIndex.getIndexableString(doc);\r\n\r\n const positionInIndex = boundEQByIndexString(\r\n docsWithIndex,\r\n indexString\r\n );\r\n if (positionInIndex !== -1) {\r\n docsWithIndex.splice(positionInIndex, 1);\r\n }\r\n }\r\n}\r\n\r\n\r\nexport function compareDocsWithIndex<RxDocType>(\r\n a: DocWithIndexString<RxDocType>,\r\n b: DocWithIndexString<RxDocType>\r\n): 1 | 0 | -1 {\r\n const indexStringA = a[0];\r\n const indexStringB = b[0];\r\n if (indexStringA < indexStringB) {\r\n return -1;\r\n } else if (indexStringA === indexStringB) {\r\n return 0;\r\n } else {\r\n return 1;\r\n }\r\n}\r\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -14,6 +14,7 @@ export function addIndexesToInternalsState(state, schema) {
|
|
|
14
14
|
getIndexableString: getIndexableStringMonad(schema, indexAr)
|
|
15
15
|
};
|
|
16
16
|
});
|
|
17
|
+
state.byIndexArray = Object.values(state.byIndex);
|
|
17
18
|
}
|
|
18
19
|
export function getMemoryIndexName(index) {
|
|
19
20
|
return index.join(',');
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"memory-indexes.js","names":["getIndexableStringMonad","getPrimaryFieldOfPrimaryKey","toArray","addIndexesToInternalsState","state","schema","primaryPath","primaryKey","useIndexes","indexes","map","row","push","forEach","indexAr","byIndex","getMemoryIndexName","index","docsWithIndex","getIndexableString","join"],"sources":["../../../../src/plugins/storage-memory/memory-indexes.ts"],"sourcesContent":["import { getIndexableStringMonad } from '../../custom-index.ts';\r\nimport { getPrimaryFieldOfPrimaryKey } from '../../rx-schema-helper.ts';\r\nimport type { RxDocumentData, RxJsonSchema } from '../../types/index.d.ts';\r\nimport { toArray } from '../../plugins/utils/index.ts';\r\nimport type { MemoryStorageInternals } from './memory-types.ts';\r\n\r\nexport function addIndexesToInternalsState<RxDocType>(\r\n state: MemoryStorageInternals<RxDocType>,\r\n schema: RxJsonSchema<RxDocumentData<RxDocType>>\r\n) {\r\n const primaryPath = getPrimaryFieldOfPrimaryKey(schema.primaryKey);\r\n const useIndexes: string[][] = !schema.indexes ? [] : schema.indexes.map(row => toArray(row)) as any;\r\n\r\n // we need this index for running cleanup()\r\n useIndexes.push([\r\n '_deleted',\r\n '_meta.lwt',\r\n primaryPath\r\n ]);\r\n\r\n\r\n useIndexes.forEach(indexAr => {\r\n state.byIndex[getMemoryIndexName(indexAr)] = {\r\n index: indexAr,\r\n docsWithIndex: [],\r\n getIndexableString: getIndexableStringMonad(schema, indexAr)\r\n };\r\n });\r\n}\r\n\r\n\r\nexport function getMemoryIndexName(index: string[]): string {\r\n return index.join(',');\r\n}\r\n"],"mappings":"AAAA,SAASA,uBAAuB,QAAQ,uBAAuB;AAC/D,SAASC,2BAA2B,QAAQ,2BAA2B;AAEvE,SAASC,OAAO,QAAQ,8BAA8B;AAGtD,OAAO,SAASC,0BAA0BA,CACtCC,KAAwC,EACxCC,MAA+C,EACjD;EACE,IAAMC,WAAW,GAAGL,2BAA2B,CAACI,MAAM,CAACE,UAAU,CAAC;EAClE,IAAMC,UAAsB,GAAG,CAACH,MAAM,CAACI,OAAO,GAAG,EAAE,GAAGJ,MAAM,CAACI,OAAO,CAACC,GAAG,CAACC,GAAG,IAAIT,OAAO,CAACS,GAAG,CAAC,CAAQ;;EAEpG;EACAH,UAAU,CAACI,IAAI,CAAC,CACZ,UAAU,EACV,WAAW,EACXN,WAAW,CACd,CAAC;EAGFE,UAAU,CAACK,OAAO,CAACC,OAAO,IAAI;IAC1BV,KAAK,CAACW,OAAO,CAACC,kBAAkB,CAACF,OAAO,CAAC,CAAC,GAAG;MACzCG,KAAK,EAAEH,OAAO;MACdI,aAAa,EAAE,EAAE;MACjBC,kBAAkB,EAAEnB,uBAAuB,CAACK,MAAM,EAAES,OAAO;IAC/D,CAAC;EACL,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"memory-indexes.js","names":["getIndexableStringMonad","getPrimaryFieldOfPrimaryKey","toArray","addIndexesToInternalsState","state","schema","primaryPath","primaryKey","useIndexes","indexes","map","row","push","forEach","indexAr","byIndex","getMemoryIndexName","index","docsWithIndex","getIndexableString","byIndexArray","Object","values","join"],"sources":["../../../../src/plugins/storage-memory/memory-indexes.ts"],"sourcesContent":["import { getIndexableStringMonad } from '../../custom-index.ts';\r\nimport { getPrimaryFieldOfPrimaryKey } from '../../rx-schema-helper.ts';\r\nimport type { RxDocumentData, RxJsonSchema } from '../../types/index.d.ts';\r\nimport { toArray } from '../../plugins/utils/index.ts';\r\nimport type { MemoryStorageInternals } from './memory-types.ts';\r\n\r\nexport function addIndexesToInternalsState<RxDocType>(\r\n state: MemoryStorageInternals<RxDocType>,\r\n schema: RxJsonSchema<RxDocumentData<RxDocType>>\r\n) {\r\n const primaryPath = getPrimaryFieldOfPrimaryKey(schema.primaryKey);\r\n const useIndexes: string[][] = !schema.indexes ? [] : schema.indexes.map(row => toArray(row)) as any;\r\n\r\n // we need this index for running cleanup()\r\n useIndexes.push([\r\n '_deleted',\r\n '_meta.lwt',\r\n primaryPath\r\n ]);\r\n\r\n\r\n useIndexes.forEach(indexAr => {\r\n state.byIndex[getMemoryIndexName(indexAr)] = {\r\n index: indexAr,\r\n docsWithIndex: [],\r\n getIndexableString: getIndexableStringMonad(schema, indexAr)\r\n };\r\n });\r\n state.byIndexArray = Object.values(state.byIndex);\r\n}\r\n\r\n\r\nexport function getMemoryIndexName(index: string[]): string {\r\n return index.join(',');\r\n}\r\n"],"mappings":"AAAA,SAASA,uBAAuB,QAAQ,uBAAuB;AAC/D,SAASC,2BAA2B,QAAQ,2BAA2B;AAEvE,SAASC,OAAO,QAAQ,8BAA8B;AAGtD,OAAO,SAASC,0BAA0BA,CACtCC,KAAwC,EACxCC,MAA+C,EACjD;EACE,IAAMC,WAAW,GAAGL,2BAA2B,CAACI,MAAM,CAACE,UAAU,CAAC;EAClE,IAAMC,UAAsB,GAAG,CAACH,MAAM,CAACI,OAAO,GAAG,EAAE,GAAGJ,MAAM,CAACI,OAAO,CAACC,GAAG,CAACC,GAAG,IAAIT,OAAO,CAACS,GAAG,CAAC,CAAQ;;EAEpG;EACAH,UAAU,CAACI,IAAI,CAAC,CACZ,UAAU,EACV,WAAW,EACXN,WAAW,CACd,CAAC;EAGFE,UAAU,CAACK,OAAO,CAACC,OAAO,IAAI;IAC1BV,KAAK,CAACW,OAAO,CAACC,kBAAkB,CAACF,OAAO,CAAC,CAAC,GAAG;MACzCG,KAAK,EAAEH,OAAO;MACdI,aAAa,EAAE,EAAE;MACjBC,kBAAkB,EAAEnB,uBAAuB,CAACK,MAAM,EAAES,OAAO;IAC/D,CAAC;EACL,CAAC,CAAC;EACFV,KAAK,CAACgB,YAAY,GAAGC,MAAM,CAACC,MAAM,CAAClB,KAAK,CAACW,OAAO,CAAC;AACrD;AAGA,OAAO,SAASC,kBAAkBA,CAACC,KAAe,EAAU;EACxD,OAAOA,KAAK,CAACM,IAAI,CAAC,GAAG,CAAC;AAC1B","ignoreList":[]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"memory-types.js","names":[],"sources":["../../../../src/plugins/storage-memory/memory-types.ts"],"sourcesContent":["import { Subject } from 'rxjs';\r\nimport type {\r\n CategorizeBulkWriteRowsOutput,\r\n EventBulk,\r\n RxAttachmentWriteData,\r\n RxDocumentData,\r\n RxJsonSchema,\r\n RxStorage,\r\n RxStorageChangeEvent,\r\n RxStorageDefaultCheckpoint\r\n} from '../../types/index.d.ts';\r\n\r\nexport type RxStorageMemorySettings = {};\r\nexport type RxStorageMemoryInstanceCreationOptions = {};\r\nexport type RxStorageMemory = RxStorage<MemoryStorageInternals<any>, RxStorageMemoryInstanceCreationOptions> & {\r\n /**\r\n * State by collectionKey\r\n */\r\n collectionStates: Map<string, MemoryStorageInternals<any>>;\r\n};\r\n\r\nexport type MemoryStorageInternalsByIndex<RxDocType> = {\r\n index: string[];\r\n docsWithIndex: DocWithIndexString<RxDocType>[];\r\n getIndexableString: (docData: RxDocumentData<RxDocType>) => string;\r\n};\r\n\r\n/**\r\n * The internals are shared between multiple storage instances\r\n * that have been created with the same [databaseName+collectionName] combination.\r\n */\r\nexport type MemoryStorageInternals<RxDocType> = {\r\n // used to debug stuff and identify instances\r\n id: string;\r\n\r\n /**\r\n * Schema of the first instance created with the given settings.\r\n * Used to ensure that the same storage is not re-created with\r\n * a different schema.\r\n */\r\n schema: RxJsonSchema<RxDocumentData<RxDocType>>;\r\n\r\n /**\r\n * We reuse the memory state when multiple instances\r\n * are created with the same params.\r\n * If refCount becomes 0, we can delete the state.\r\n */\r\n refCount: number;\r\n /**\r\n * If this becomes true,\r\n * it means that an instance has called remove()\r\n * so all other instances should also not work anymore.\r\n */\r\n removed: boolean;\r\n documents: Map<string, RxDocumentData<RxDocType>>;\r\n /**\r\n * Attachments data, indexed by a combined string\r\n * consisting of [documentId + '||' + attachmentId]\r\n */\r\n attachments: Map<string, {\r\n writeData: RxAttachmentWriteData;\r\n digest: string;\r\n }>;\r\n byIndex: {\r\n /**\r\n * Because RxDB requires a deterministic sorting\r\n * on all indexes, we can be sure that the composed index key\r\n * of each document is unique, because it contains the primaryKey\r\n * as last index part.\r\n * So we do not have to store the index-position when we want to do fast\r\n * writes. Instead we can do a binary search over the existing array\r\n * because RxDB also knows the previous state of the document when we do a bulkWrite().\r\n */\r\n [indexName: string]: MemoryStorageInternalsByIndex<RxDocType>;\r\n };\r\n\r\n /**\r\n * We need these to do lazy writes.\r\n */\r\n ensurePersistenceTask?: CategorizeBulkWriteRowsOutput<RxDocType>;\r\n ensurePersistenceIdlePromise?: Promise<void>;\r\n\r\n changes$: Subject<EventBulk<RxStorageChangeEvent<RxDocumentData<RxDocType>>, RxStorageDefaultCheckpoint>>;\r\n};\r\n\r\nexport type DocWithIndexString<RxDocType> = [\r\n string, // indexString, must be first because often we only need that one.\r\n RxDocumentData<RxDocType>, // document\r\n string, // id\r\n];\r\n"],"mappings":"","ignoreList":[]}
|
|
1
|
+
{"version":3,"file":"memory-types.js","names":[],"sources":["../../../../src/plugins/storage-memory/memory-types.ts"],"sourcesContent":["import { Subject } from 'rxjs';\r\nimport type {\r\n CategorizeBulkWriteRowsOutput,\r\n EventBulk,\r\n RxAttachmentWriteData,\r\n RxDocumentData,\r\n RxJsonSchema,\r\n RxStorage,\r\n RxStorageChangeEvent,\r\n RxStorageDefaultCheckpoint\r\n} from '../../types/index.d.ts';\r\n\r\nexport type RxStorageMemorySettings = {};\r\nexport type RxStorageMemoryInstanceCreationOptions = {};\r\nexport type RxStorageMemory = RxStorage<MemoryStorageInternals<any>, RxStorageMemoryInstanceCreationOptions> & {\r\n /**\r\n * State by collectionKey\r\n */\r\n collectionStates: Map<string, MemoryStorageInternals<any>>;\r\n};\r\n\r\nexport type MemoryStorageInternalsByIndex<RxDocType> = {\r\n index: string[];\r\n docsWithIndex: DocWithIndexString<RxDocType>[];\r\n getIndexableString: (docData: RxDocumentData<RxDocType>) => string;\r\n};\r\n\r\n/**\r\n * The internals are shared between multiple storage instances\r\n * that have been created with the same [databaseName+collectionName] combination.\r\n */\r\nexport type MemoryStorageInternals<RxDocType> = {\r\n // used to debug stuff and identify instances\r\n id: string;\r\n\r\n /**\r\n * Schema of the first instance created with the given settings.\r\n * Used to ensure that the same storage is not re-created with\r\n * a different schema.\r\n */\r\n schema: RxJsonSchema<RxDocumentData<RxDocType>>;\r\n\r\n /**\r\n * We reuse the memory state when multiple instances\r\n * are created with the same params.\r\n * If refCount becomes 0, we can delete the state.\r\n */\r\n refCount: number;\r\n /**\r\n * If this becomes true,\r\n * it means that an instance has called remove()\r\n * so all other instances should also not work anymore.\r\n */\r\n removed: boolean;\r\n documents: Map<string, RxDocumentData<RxDocType>>;\r\n /**\r\n * Attachments data, indexed by a combined string\r\n * consisting of [documentId + '||' + attachmentId]\r\n */\r\n attachments: Map<string, {\r\n writeData: RxAttachmentWriteData;\r\n digest: string;\r\n }>;\r\n byIndex: {\r\n /**\r\n * Because RxDB requires a deterministic sorting\r\n * on all indexes, we can be sure that the composed index key\r\n * of each document is unique, because it contains the primaryKey\r\n * as last index part.\r\n * So we do not have to store the index-position when we want to do fast\r\n * writes. Instead we can do a binary search over the existing array\r\n * because RxDB also knows the previous state of the document when we do a bulkWrite().\r\n */\r\n [indexName: string]: MemoryStorageInternalsByIndex<RxDocType>;\r\n };\r\n /**\r\n * Cached array of all MemoryStorageInternalsByIndex values.\r\n * Avoids calling Object.values(byIndex) on every write operation.\r\n */\r\n byIndexArray: MemoryStorageInternalsByIndex<RxDocType>[];\r\n\r\n /**\r\n * We need these to do lazy writes.\r\n */\r\n ensurePersistenceTask?: CategorizeBulkWriteRowsOutput<RxDocType>;\r\n ensurePersistenceIdlePromise?: Promise<void>;\r\n\r\n changes$: Subject<EventBulk<RxStorageChangeEvent<RxDocumentData<RxDocType>>, RxStorageDefaultCheckpoint>>;\r\n};\r\n\r\nexport type DocWithIndexString<RxDocType> = [\r\n string, // indexString, must be first because often we only need that one.\r\n RxDocumentData<RxDocType>, // document\r\n string, // id\r\n];\r\n"],"mappings":"","ignoreList":[]}
|