@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 +1 @@
|
|
|
1
|
-
{"version":3,"file":"query-planner.js","names":["countUntilNotMatching","newRxError","getSchemaByObjectPath","INDEX_MAX","String","fromCharCode","INDEX_MIN","Number","MIN_SAFE_INTEGER","getQueryPlan","schema","query","selector","indexes","slice","index","hasDescSorting","sort","find","sortField","Object","values","sortIrrelevevantFields","Set","keys","forEach","fieldName","schemaPart","type","enum","prototype","hasOwnProperty","call","add","optimalSortIndex","map","optimalSortIndexCompareString","filter","f","has","join","currentBestQuality","currentBestQueryPlan","inclusiveEnd","inclusiveStart","opts","indexField","matcher","operators","matcherOpts","length","startKey","endKey","operator","LOGICAL_OPERATORS","operatorValue","partialOpts","getMatcherQueryOpts","assign","startKeys","opt","endKeys","indexCompareString","size","queryPlan","sortSatisfiedByIndex","selectorSatisfiedByIndex","isSelectorSatisfiedByIndex","quality","rateQueryPlan","LOWER_BOUND_LOGICAL_OPERATORS","UPPER_BOUND_LOGICAL_OPERATORS","$and","$or","selectorEntries","entries","lowerOperatorFieldNames","upperOperatorFieldNames","hasNonEqLowerBound","hasNonEqUpperBound","operation","includes","operationKeys","lowerLogicOpCount","lastLowerLogicOp","upperLogicOpCount","lastUpperLogicOp","op","i","set","delete","Error","addQuality","value","pointsPerMatchingKey","nonMinKeyCount","keyValue","nonMaxKeyCount","equalKeyCount","idx","pointsIfNoReSortMustBeDone"],"sources":["../../src/query-planner.ts"],"sourcesContent":["import { countUntilNotMatching } from './plugins/utils/index.ts';\r\nimport { newRxError } from './rx-error.ts';\r\nimport { getSchemaByObjectPath } from './rx-schema-helper.ts';\r\nimport type {\r\n FilledMangoQuery,\r\n MangoQuerySelector,\r\n RxDocumentData,\r\n RxJsonSchema,\r\n RxQueryPlan,\r\n RxQueryPlanKey,\r\n RxQueryPlanerOpts\r\n} from './types/index.d.ts';\r\n\r\nexport const INDEX_MAX = String.fromCharCode(65535);\r\n\r\n/**\r\n * Do not use -Infinity here because it would be\r\n * transformed to null on JSON.stringify() which can break things\r\n * when the query plan is sent to the storage as json.\r\n * @link https://stackoverflow.com/a/16644751\r\n * Notice that for IndexedDB IDBKeyRange we have\r\n * to transform the value back to -Infinity\r\n * before we can use it in IDBKeyRange.bound.\r\n */\r\nexport const INDEX_MIN = Number.MIN_SAFE_INTEGER;\r\n\r\n/**\r\n * Returns the query plan which contains\r\n * information about how to run the query\r\n * and which indexes to use.\r\n *\r\n * This is used in some storage like Memory, dexie.js and IndexedDB.\r\n */\r\nexport function getQueryPlan<RxDocType>(\r\n schema: RxJsonSchema<RxDocumentData<RxDocType>>,\r\n query: FilledMangoQuery<RxDocType>\r\n): RxQueryPlan {\r\n const selector = query.selector;\r\n let indexes: string[][] = schema.indexes ? schema.indexes.slice(0) as any : [];\r\n if (query.index) {\r\n indexes = [query.index];\r\n }\r\n\r\n /**\r\n * Most storages do not support descending indexes\r\n * so having a 'desc' in the sorting, means we always have to re-sort the results.\r\n */\r\n const hasDescSorting = !!query.sort.find(sortField => Object.values(sortField)[0] === 'desc');\r\n\r\n /**\r\n * Some fields can be part of the selector while not being relevant for sorting\r\n * because their selector operators specify that in all cases all matching docs\r\n * would have the same value.\r\n * For example the boolean field _deleted or enum fields.\r\n */\r\n const sortIrrelevevantFields = new Set();\r\n Object.keys(selector).forEach(fieldName => {\r\n const schemaPart = getSchemaByObjectPath(schema, fieldName);\r\n if (\r\n schemaPart &&\r\n (\r\n schemaPart.type === 'boolean' ||\r\n schemaPart.enum\r\n ) &&\r\n Object.prototype.hasOwnProperty.call((selector as any)[fieldName], '$eq')\r\n ) {\r\n sortIrrelevevantFields.add(fieldName);\r\n }\r\n });\r\n\r\n\r\n const optimalSortIndex = query.sort.map(sortField => Object.keys(sortField)[0]);\r\n const optimalSortIndexCompareString = optimalSortIndex\r\n .filter(f => !sortIrrelevevantFields.has(f))\r\n .join(',');\r\n\r\n let currentBestQuality = -1;\r\n let currentBestQueryPlan: RxQueryPlan | undefined;\r\n\r\n /**\r\n * Calculate one query plan for each index\r\n * and then test which of the plans is best.\r\n */\r\n indexes.forEach((index) => {\r\n let inclusiveEnd = true;\r\n let inclusiveStart = true;\r\n const opts: RxQueryPlanerOpts[] = index.map(indexField => {\r\n const matcher = (selector as any)[indexField];\r\n const operators = matcher ? Object.keys(matcher) : [];\r\n\r\n let matcherOpts: RxQueryPlanerOpts = {} as any;\r\n if (\r\n !matcher ||\r\n !operators.length\r\n ) {\r\n const startKey = inclusiveStart ? INDEX_MIN : INDEX_MAX;\r\n matcherOpts = {\r\n startKey,\r\n endKey: inclusiveEnd ? INDEX_MAX : INDEX_MIN,\r\n inclusiveStart: true,\r\n inclusiveEnd: true\r\n };\r\n } else {\r\n operators.forEach(operator => {\r\n if (LOGICAL_OPERATORS.has(operator)) {\r\n const operatorValue = matcher[operator];\r\n const partialOpts = getMatcherQueryOpts(operator, operatorValue);\r\n matcherOpts = Object.assign(matcherOpts, partialOpts);\r\n }\r\n });\r\n }\r\n\r\n // fill missing attributes\r\n if (typeof matcherOpts.startKey === 'undefined') {\r\n matcherOpts.startKey = INDEX_MIN;\r\n }\r\n if (typeof matcherOpts.endKey === 'undefined') {\r\n matcherOpts.endKey = INDEX_MAX;\r\n }\r\n if (typeof matcherOpts.inclusiveStart === 'undefined') {\r\n matcherOpts.inclusiveStart = true;\r\n }\r\n if (typeof matcherOpts.inclusiveEnd === 'undefined') {\r\n matcherOpts.inclusiveEnd = true;\r\n }\r\n\r\n if (inclusiveStart && !matcherOpts.inclusiveStart) {\r\n inclusiveStart = false;\r\n }\r\n if (inclusiveEnd && !matcherOpts.inclusiveEnd) {\r\n inclusiveEnd = false;\r\n }\r\n\r\n return matcherOpts;\r\n });\r\n\r\n\r\n const startKeys = opts.map(opt => opt.startKey);\r\n const endKeys = opts.map(opt => opt.endKey);\r\n\r\n /**\r\n * Compute the index compare string once per index,\r\n * not inside the queryPlan object literal, to avoid\r\n * creating a filtered array and joining on every iteration.\r\n */\r\n let indexCompareString: string;\r\n if (sortIrrelevevantFields.size === 0) {\r\n indexCompareString = index.join(',');\r\n } else {\r\n indexCompareString = index.filter(f => !sortIrrelevevantFields.has(f)).join(',');\r\n }\r\n\r\n const queryPlan: RxQueryPlan = {\r\n index,\r\n startKeys,\r\n endKeys,\r\n inclusiveEnd,\r\n inclusiveStart,\r\n sortSatisfiedByIndex: !hasDescSorting && optimalSortIndexCompareString === indexCompareString,\r\n selectorSatisfiedByIndex: isSelectorSatisfiedByIndex(index, query.selector, startKeys, endKeys)\r\n };\r\n const quality = rateQueryPlan(\r\n schema,\r\n query,\r\n queryPlan\r\n );\r\n if (\r\n (\r\n quality >= currentBestQuality\r\n ) ||\r\n query.index\r\n ) {\r\n currentBestQuality = quality;\r\n currentBestQueryPlan = queryPlan;\r\n }\r\n });\r\n\r\n /**\r\n * In all cases and index must be found\r\n */\r\n if (!currentBestQueryPlan) {\r\n throw newRxError('SNH', {\r\n query\r\n });\r\n }\r\n\r\n return currentBestQueryPlan;\r\n}\r\n\r\nexport const LOGICAL_OPERATORS = new Set(['$eq', '$gt', '$gte', '$lt', '$lte']);\r\nexport const LOWER_BOUND_LOGICAL_OPERATORS = new Set(['$eq', '$gt', '$gte']);\r\nexport const UPPER_BOUND_LOGICAL_OPERATORS = new Set(['$eq', '$lt', '$lte']);\r\n\r\n\r\nexport function isSelectorSatisfiedByIndex(\r\n index: string[],\r\n selector: MangoQuerySelector<any>,\r\n startKeys: RxQueryPlanKey[],\r\n endKeys: RxQueryPlanKey[]\r\n): boolean {\r\n\r\n /**\r\n * Not satisfied if contains $and or $or operations.\r\n */\r\n if (selector.$and || selector.$or) {\r\n return false;\r\n }\r\n\r\n /**\r\n * Check all selector entries in a single pass:\r\n * - Ensure all fields are in the index\r\n * - Ensure all operators are logical\r\n * - Track lower/upper bound operators\r\n */\r\n const selectorEntries = Object.entries(selector);\r\n const lowerOperatorFieldNames = new Set<string>();\r\n const upperOperatorFieldNames = new Set<string>();\r\n let hasNonEqLowerBound = false;\r\n let hasNonEqUpperBound = false;\r\n\r\n for (const [fieldName, operation] of selectorEntries) {\r\n if (!index.includes(fieldName)) {\r\n return false;\r\n }\r\n\r\n const operationKeys = Object.keys(operation as any);\r\n\r\n let lowerLogicOpCount = 0;\r\n let lastLowerLogicOp: string | undefined;\r\n let upperLogicOpCount = 0;\r\n let lastUpperLogicOp: string | undefined;\r\n\r\n for (const op of operationKeys) {\r\n if (!LOGICAL_OPERATORS.has(op)) {\r\n return false;\r\n }\r\n if (LOWER_BOUND_LOGICAL_OPERATORS.has(op)) {\r\n lowerLogicOpCount++;\r\n lastLowerLogicOp = op;\r\n }\r\n if (UPPER_BOUND_LOGICAL_OPERATORS.has(op)) {\r\n upperLogicOpCount++;\r\n lastUpperLogicOp = op;\r\n }\r\n }\r\n\r\n // If more than one logic op on the same field per bound direction, we have to selector-match.\r\n if (lowerLogicOpCount > 1 || upperLogicOpCount > 1) {\r\n return false;\r\n }\r\n\r\n if (lastLowerLogicOp) {\r\n lowerOperatorFieldNames.add(fieldName);\r\n }\r\n if (lastLowerLogicOp !== '$eq') {\r\n if (hasNonEqLowerBound) {\r\n return false;\r\n }\r\n hasNonEqLowerBound = true;\r\n }\r\n\r\n if (lastUpperLogicOp) {\r\n upperOperatorFieldNames.add(fieldName);\r\n }\r\n if (lastUpperLogicOp !== '$eq') {\r\n if (hasNonEqUpperBound) {\r\n return false;\r\n }\r\n hasNonEqUpperBound = true;\r\n }\r\n }\r\n\r\n\r\n /**\r\n * If the index contains a non-relevant field between\r\n * the relevant fields, then the index is not satisfying.\r\n */\r\n let i = 0;\r\n for (const fieldName of index) {\r\n for (const set of [\r\n lowerOperatorFieldNames,\r\n upperOperatorFieldNames\r\n ]) {\r\n if (\r\n !set.has(fieldName) &&\r\n set.size > 0\r\n ) {\r\n return false;\r\n }\r\n set.delete(fieldName);\r\n }\r\n\r\n const startKey = startKeys[i];\r\n const endKey = endKeys[i];\r\n\r\n if (\r\n startKey !== endKey && (\r\n lowerOperatorFieldNames.size > 0 &&\r\n upperOperatorFieldNames.size > 0\r\n )\r\n ) {\r\n return false;\r\n }\r\n\r\n i++;\r\n }\r\n\r\n return true;\r\n}\r\n\r\nexport function getMatcherQueryOpts(\r\n operator: string,\r\n operatorValue: any\r\n): Partial<RxQueryPlanerOpts> {\r\n switch (operator) {\r\n case '$eq':\r\n return {\r\n startKey: operatorValue,\r\n endKey: operatorValue,\r\n inclusiveEnd: true,\r\n inclusiveStart: true\r\n };\r\n case '$lte':\r\n return {\r\n endKey: operatorValue,\r\n inclusiveEnd: true\r\n };\r\n case '$gte':\r\n return {\r\n startKey: operatorValue,\r\n inclusiveStart: true\r\n };\r\n case '$lt':\r\n return {\r\n endKey: operatorValue,\r\n inclusiveEnd: false\r\n };\r\n case '$gt':\r\n return {\r\n startKey: operatorValue,\r\n inclusiveStart: false\r\n };\r\n default:\r\n throw new Error('SNH');\r\n }\r\n}\r\n\r\n\r\n/**\r\n * Returns a number that determines the quality of the query plan.\r\n * Higher number means better query plan.\r\n */\r\nexport function rateQueryPlan<RxDocType>(\r\n schema: RxJsonSchema<RxDocumentData<RxDocType>>,\r\n query: FilledMangoQuery<RxDocType>,\r\n queryPlan: RxQueryPlan\r\n): number {\r\n let quality: number = 0;\r\n const addQuality = (value: number) => {\r\n if (value > 0) {\r\n quality = quality + value;\r\n }\r\n };\r\n\r\n const pointsPerMatchingKey = 10;\r\n\r\n const nonMinKeyCount = countUntilNotMatching(queryPlan.startKeys, keyValue => keyValue !== INDEX_MIN && keyValue !== INDEX_MAX);\r\n addQuality(nonMinKeyCount * pointsPerMatchingKey);\r\n\r\n const nonMaxKeyCount = countUntilNotMatching(queryPlan.startKeys, keyValue => keyValue !== INDEX_MAX && keyValue !== INDEX_MIN);\r\n addQuality(nonMaxKeyCount * pointsPerMatchingKey);\r\n\r\n const equalKeyCount = countUntilNotMatching(queryPlan.startKeys, (keyValue, idx) => {\r\n if (keyValue === queryPlan.endKeys[idx]) {\r\n return true;\r\n } else {\r\n return false;\r\n }\r\n });\r\n addQuality(equalKeyCount * pointsPerMatchingKey * 1.5);\r\n\r\n const pointsIfNoReSortMustBeDone = queryPlan.sortSatisfiedByIndex ? 5 : 0;\r\n addQuality(pointsIfNoReSortMustBeDone);\r\n\r\n return quality;\r\n}\r\n"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{"version":3,"file":"query-planner.js","names":["countUntilNotMatching","newRxError","getSchemaByObjectPath","INDEX_MAX","String","fromCharCode","INDEX_MIN","Number","MIN_SAFE_INTEGER","getQueryPlan","schema","query","selector","indexes","slice","index","hasDescSorting","sort","find","sortField","Object","values","sortIrrelevevantFields","Set","keys","forEach","fieldName","schemaPart","type","enum","prototype","hasOwnProperty","call","add","optimalSortIndex","map","optimalSortIndexCompareString","filter","f","has","join","currentBestQuality","currentBestQueryPlan","inclusiveEnd","inclusiveStart","opts","indexField","matcher","operators","matcherOpts","length","startKey","endKey","operator","LOGICAL_OPERATORS","operatorValue","partialOpts","getMatcherQueryOpts","assign","startKeys","opt","endKeys","indexCompareString","size","queryPlan","sortSatisfiedByIndex","selectorSatisfiedByIndex","isSelectorSatisfiedByIndex","quality","rateQueryPlan","LOWER_BOUND_LOGICAL_OPERATORS","UPPER_BOUND_LOGICAL_OPERATORS","$and","$or","selectorEntries","entries","lowerOperatorFieldNames","upperOperatorFieldNames","hasNonEqLowerBound","hasNonEqUpperBound","operation","includes","operationKeys","lowerLogicOpCount","lastLowerLogicOp","upperLogicOpCount","lastUpperLogicOp","op","i","set","delete","addQuality","value","pointsPerMatchingKey","nonMinKeyCount","keyValue","nonMaxKeyCount","equalKeyCount","idx","pointsIfNoReSortMustBeDone"],"sources":["../../src/query-planner.ts"],"sourcesContent":["import { countUntilNotMatching } from './plugins/utils/index.ts';\r\nimport { newRxError } from './rx-error.ts';\r\nimport { getSchemaByObjectPath } from './rx-schema-helper.ts';\r\nimport type {\r\n FilledMangoQuery,\r\n MangoQuerySelector,\r\n RxDocumentData,\r\n RxJsonSchema,\r\n RxQueryPlan,\r\n RxQueryPlanKey,\r\n RxQueryPlanerOpts\r\n} from './types/index.d.ts';\r\n\r\nexport const INDEX_MAX = String.fromCharCode(65535);\r\n\r\n/**\r\n * Do not use -Infinity here because it would be\r\n * transformed to null on JSON.stringify() which can break things\r\n * when the query plan is sent to the storage as json.\r\n * @link https://stackoverflow.com/a/16644751\r\n * Notice that for IndexedDB IDBKeyRange we have\r\n * to transform the value back to -Infinity\r\n * before we can use it in IDBKeyRange.bound.\r\n */\r\nexport const INDEX_MIN = Number.MIN_SAFE_INTEGER;\r\n\r\n/**\r\n * Returns the query plan which contains\r\n * information about how to run the query\r\n * and which indexes to use.\r\n *\r\n * This is used in some storage like Memory, dexie.js and IndexedDB.\r\n */\r\nexport function getQueryPlan<RxDocType>(\r\n schema: RxJsonSchema<RxDocumentData<RxDocType>>,\r\n query: FilledMangoQuery<RxDocType>\r\n): RxQueryPlan {\r\n const selector = query.selector;\r\n let indexes: string[][] = schema.indexes ? schema.indexes.slice(0) as any : [];\r\n if (query.index) {\r\n indexes = [query.index];\r\n }\r\n\r\n /**\r\n * Most storages do not support descending indexes\r\n * so having a 'desc' in the sorting, means we always have to re-sort the results.\r\n */\r\n const hasDescSorting = !!query.sort.find(sortField => Object.values(sortField)[0] === 'desc');\r\n\r\n /**\r\n * Some fields can be part of the selector while not being relevant for sorting\r\n * because their selector operators specify that in all cases all matching docs\r\n * would have the same value.\r\n * For example the boolean field _deleted or enum fields.\r\n */\r\n const sortIrrelevevantFields = new Set();\r\n Object.keys(selector).forEach(fieldName => {\r\n const schemaPart = getSchemaByObjectPath(schema, fieldName);\r\n if (\r\n schemaPart &&\r\n (\r\n schemaPart.type === 'boolean' ||\r\n schemaPart.enum\r\n ) &&\r\n Object.prototype.hasOwnProperty.call((selector as any)[fieldName], '$eq')\r\n ) {\r\n sortIrrelevevantFields.add(fieldName);\r\n }\r\n });\r\n\r\n\r\n const optimalSortIndex = query.sort.map(sortField => Object.keys(sortField)[0]);\r\n const optimalSortIndexCompareString = optimalSortIndex\r\n .filter(f => !sortIrrelevevantFields.has(f))\r\n .join(',');\r\n\r\n let currentBestQuality = -1;\r\n let currentBestQueryPlan: RxQueryPlan | undefined;\r\n\r\n /**\r\n * Calculate one query plan for each index\r\n * and then test which of the plans is best.\r\n */\r\n indexes.forEach((index) => {\r\n let inclusiveEnd = true;\r\n let inclusiveStart = true;\r\n const opts: RxQueryPlanerOpts[] = index.map(indexField => {\r\n const matcher = (selector as any)[indexField];\r\n const operators = matcher ? Object.keys(matcher) : [];\r\n\r\n let matcherOpts: RxQueryPlanerOpts = {} as any;\r\n if (\r\n !matcher ||\r\n !operators.length\r\n ) {\r\n const startKey = inclusiveStart ? INDEX_MIN : INDEX_MAX;\r\n matcherOpts = {\r\n startKey,\r\n endKey: inclusiveEnd ? INDEX_MAX : INDEX_MIN,\r\n inclusiveStart: true,\r\n inclusiveEnd: true\r\n };\r\n } else {\r\n operators.forEach(operator => {\r\n if (LOGICAL_OPERATORS.has(operator)) {\r\n const operatorValue = matcher[operator];\r\n const partialOpts = getMatcherQueryOpts(operator, operatorValue);\r\n matcherOpts = Object.assign(matcherOpts, partialOpts);\r\n }\r\n });\r\n }\r\n\r\n // fill missing attributes\r\n if (typeof matcherOpts.startKey === 'undefined') {\r\n matcherOpts.startKey = INDEX_MIN;\r\n }\r\n if (typeof matcherOpts.endKey === 'undefined') {\r\n matcherOpts.endKey = INDEX_MAX;\r\n }\r\n if (typeof matcherOpts.inclusiveStart === 'undefined') {\r\n matcherOpts.inclusiveStart = true;\r\n }\r\n if (typeof matcherOpts.inclusiveEnd === 'undefined') {\r\n matcherOpts.inclusiveEnd = true;\r\n }\r\n\r\n if (inclusiveStart && !matcherOpts.inclusiveStart) {\r\n inclusiveStart = false;\r\n }\r\n if (inclusiveEnd && !matcherOpts.inclusiveEnd) {\r\n inclusiveEnd = false;\r\n }\r\n\r\n return matcherOpts;\r\n });\r\n\r\n\r\n const startKeys = opts.map(opt => opt.startKey);\r\n const endKeys = opts.map(opt => opt.endKey);\r\n\r\n /**\r\n * Compute the index compare string once per index,\r\n * not inside the queryPlan object literal, to avoid\r\n * creating a filtered array and joining on every iteration.\r\n */\r\n let indexCompareString: string;\r\n if (sortIrrelevevantFields.size === 0) {\r\n indexCompareString = index.join(',');\r\n } else {\r\n indexCompareString = index.filter(f => !sortIrrelevevantFields.has(f)).join(',');\r\n }\r\n\r\n const queryPlan: RxQueryPlan = {\r\n index,\r\n startKeys,\r\n endKeys,\r\n inclusiveEnd,\r\n inclusiveStart,\r\n sortSatisfiedByIndex: !hasDescSorting && optimalSortIndexCompareString === indexCompareString,\r\n selectorSatisfiedByIndex: isSelectorSatisfiedByIndex(index, query.selector, startKeys, endKeys)\r\n };\r\n const quality = rateQueryPlan(\r\n schema,\r\n query,\r\n queryPlan\r\n );\r\n if (\r\n (\r\n quality >= currentBestQuality\r\n ) ||\r\n query.index\r\n ) {\r\n currentBestQuality = quality;\r\n currentBestQueryPlan = queryPlan;\r\n }\r\n });\r\n\r\n /**\r\n * In all cases and index must be found\r\n */\r\n if (!currentBestQueryPlan) {\r\n throw newRxError('SNH', {\r\n query\r\n });\r\n }\r\n\r\n return currentBestQueryPlan;\r\n}\r\n\r\nexport const LOGICAL_OPERATORS = new Set(['$eq', '$gt', '$gte', '$lt', '$lte']);\r\nexport const LOWER_BOUND_LOGICAL_OPERATORS = new Set(['$eq', '$gt', '$gte']);\r\nexport const UPPER_BOUND_LOGICAL_OPERATORS = new Set(['$eq', '$lt', '$lte']);\r\n\r\n\r\nexport function isSelectorSatisfiedByIndex(\r\n index: string[],\r\n selector: MangoQuerySelector<any>,\r\n startKeys: RxQueryPlanKey[],\r\n endKeys: RxQueryPlanKey[]\r\n): boolean {\r\n\r\n /**\r\n * Not satisfied if contains $and or $or operations.\r\n */\r\n if (selector.$and || selector.$or) {\r\n return false;\r\n }\r\n\r\n /**\r\n * Check all selector entries in a single pass:\r\n * - Ensure all fields are in the index\r\n * - Ensure all operators are logical\r\n * - Track lower/upper bound operators\r\n */\r\n const selectorEntries = Object.entries(selector);\r\n const lowerOperatorFieldNames = new Set<string>();\r\n const upperOperatorFieldNames = new Set<string>();\r\n let hasNonEqLowerBound = false;\r\n let hasNonEqUpperBound = false;\r\n\r\n for (const [fieldName, operation] of selectorEntries) {\r\n if (!index.includes(fieldName)) {\r\n return false;\r\n }\r\n\r\n const operationKeys = Object.keys(operation as any);\r\n\r\n let lowerLogicOpCount = 0;\r\n let lastLowerLogicOp: string | undefined;\r\n let upperLogicOpCount = 0;\r\n let lastUpperLogicOp: string | undefined;\r\n\r\n for (const op of operationKeys) {\r\n if (!LOGICAL_OPERATORS.has(op)) {\r\n return false;\r\n }\r\n if (LOWER_BOUND_LOGICAL_OPERATORS.has(op)) {\r\n lowerLogicOpCount++;\r\n lastLowerLogicOp = op;\r\n }\r\n if (UPPER_BOUND_LOGICAL_OPERATORS.has(op)) {\r\n upperLogicOpCount++;\r\n lastUpperLogicOp = op;\r\n }\r\n }\r\n\r\n // If more than one logic op on the same field per bound direction, we have to selector-match.\r\n if (lowerLogicOpCount > 1 || upperLogicOpCount > 1) {\r\n return false;\r\n }\r\n\r\n if (lastLowerLogicOp) {\r\n lowerOperatorFieldNames.add(fieldName);\r\n }\r\n if (lastLowerLogicOp !== '$eq') {\r\n if (hasNonEqLowerBound) {\r\n return false;\r\n }\r\n hasNonEqLowerBound = true;\r\n }\r\n\r\n if (lastUpperLogicOp) {\r\n upperOperatorFieldNames.add(fieldName);\r\n }\r\n if (lastUpperLogicOp !== '$eq') {\r\n if (hasNonEqUpperBound) {\r\n return false;\r\n }\r\n hasNonEqUpperBound = true;\r\n }\r\n }\r\n\r\n\r\n /**\r\n * If the index contains a non-relevant field between\r\n * the relevant fields, then the index is not satisfying.\r\n */\r\n let i = 0;\r\n for (const fieldName of index) {\r\n for (const set of [\r\n lowerOperatorFieldNames,\r\n upperOperatorFieldNames\r\n ]) {\r\n if (\r\n !set.has(fieldName) &&\r\n set.size > 0\r\n ) {\r\n return false;\r\n }\r\n set.delete(fieldName);\r\n }\r\n\r\n const startKey = startKeys[i];\r\n const endKey = endKeys[i];\r\n\r\n if (\r\n startKey !== endKey && (\r\n lowerOperatorFieldNames.size > 0 &&\r\n upperOperatorFieldNames.size > 0\r\n )\r\n ) {\r\n return false;\r\n }\r\n\r\n i++;\r\n }\r\n\r\n return true;\r\n}\r\n\r\nexport function getMatcherQueryOpts(\r\n operator: string,\r\n operatorValue: any\r\n): Partial<RxQueryPlanerOpts> {\r\n switch (operator) {\r\n case '$eq':\r\n return {\r\n startKey: operatorValue,\r\n endKey: operatorValue,\r\n inclusiveEnd: true,\r\n inclusiveStart: true\r\n };\r\n case '$lte':\r\n return {\r\n endKey: operatorValue,\r\n inclusiveEnd: true\r\n };\r\n case '$gte':\r\n return {\r\n startKey: operatorValue,\r\n inclusiveStart: true\r\n };\r\n case '$lt':\r\n return {\r\n endKey: operatorValue,\r\n inclusiveEnd: false\r\n };\r\n case '$gt':\r\n return {\r\n startKey: operatorValue,\r\n inclusiveStart: false\r\n };\r\n default:\r\n throw newRxError('SNH');\r\n }\r\n}\r\n\r\n\r\n/**\r\n * Returns a number that determines the quality of the query plan.\r\n * Higher number means better query plan.\r\n */\r\nexport function rateQueryPlan<RxDocType>(\r\n schema: RxJsonSchema<RxDocumentData<RxDocType>>,\r\n query: FilledMangoQuery<RxDocType>,\r\n queryPlan: RxQueryPlan\r\n): number {\r\n let quality: number = 0;\r\n const addQuality = (value: number) => {\r\n if (value > 0) {\r\n quality = quality + value;\r\n }\r\n };\r\n\r\n const pointsPerMatchingKey = 10;\r\n\r\n const nonMinKeyCount = countUntilNotMatching(queryPlan.startKeys, keyValue => keyValue !== INDEX_MIN && keyValue !== INDEX_MAX);\r\n addQuality(nonMinKeyCount * pointsPerMatchingKey);\r\n\r\n const nonMaxKeyCount = countUntilNotMatching(queryPlan.endKeys, keyValue => keyValue !== INDEX_MAX && keyValue !== INDEX_MIN);\r\n addQuality(nonMaxKeyCount * pointsPerMatchingKey);\r\n\r\n const equalKeyCount = countUntilNotMatching(queryPlan.startKeys, (keyValue, idx) => {\r\n if (keyValue === queryPlan.endKeys[idx]) {\r\n return true;\r\n } else {\r\n return false;\r\n }\r\n });\r\n addQuality(equalKeyCount * pointsPerMatchingKey * 1.5);\r\n\r\n const pointsIfNoReSortMustBeDone = queryPlan.sortSatisfiedByIndex ? 5 : 0;\r\n addQuality(pointsIfNoReSortMustBeDone);\r\n\r\n return quality;\r\n}\r\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -134,7 +134,7 @@ export async function startReplicationDownstream(state) {
|
|
|
134
134
|
var lastCheckpoint = null;
|
|
135
135
|
tasks.forEach(task => {
|
|
136
136
|
if (task === 'RESYNC') {
|
|
137
|
-
throw
|
|
137
|
+
throw newRxError('SNH');
|
|
138
138
|
}
|
|
139
139
|
docsOfAllTasks = docsOfAllTasks.concat(task.documents);
|
|
140
140
|
lastCheckpoint = stackCheckpoints([lastCheckpoint, task.checkpoint]);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"downstream.js","names":["firstValueFrom","filter","mergeMap","newRxError","getWrittenDocumentsFromBulkWriteResponse","stackCheckpoints","createRevision","ensureNotFalsy","flatClone","getDefaultRevision","getHeightOfRevision","now","PROMISE_RESOLVE_VOID","getLastCheckpointDoc","setCheckpoint","stripAttachmentsDataFromMetaWriteRows","writeDocToDocState","getAssumedMasterState","getMetaWriteRow","startReplicationDownstream","state","input","initialCheckpoint","downstream","checkpointDoc","identifierHash","hashFunction","identifier","replicationHandler","timer","openTasks","addNewTask","task","stats","down","taskWithTime","time","push","streamQueue","then","useTasks","length","events","active","next","innerTaskWithTime","shift","lastTimeMasterChangesRequested","downstreamResyncOnce","downstreamProcessChanges","firstSyncDone","getValue","canceled","sub","masterChangeStream$","pipe","ev","up","s","subscribe","masterChangeStreamEmit","unsubscribe","checkpointQueue","lastCheckpoint","promises","downResult","masterChangesSince","pullBatchSize","documents","checkpoint","persistFromMaster","Promise","all","tasks","docsOfAllTasks","forEach","Error","concat","persistenceQueue","nonPersistedFromMaster","docs","primaryPath","docData","docId","downDocsById","useCheckpoint","docIds","Object","keys","writeRowsToFork","writeRowsToForkById","writeRowsToMeta","useMetaWriteRows","forkInstance","findDocumentsById","currentForkStateList","assumedMasterState","currentForkState","Map","doc","set","map","forkStateFullDoc","get","forkStateDocData","hasAttachments","undefined","masterState","assumedMaster","metaDocument","isResolvedConflict","_rev","isAssumedMasterEqualToForkState","conflictHandler","isEqual","_meta","skipStoringPullMeta","o","hash","areStatesExactlyEqual","newForkState","assign","_attachments","lwt","nextRevisionHeight","keepMeta","forkWriteRow","previous","document","bulkWrite","downstreamBulkWriteFlag","forkWriteResult","success","processed","mustThrow","error","status","throwMe","writeError","metaInstance","metaWriteResult","id","documentId","catch","unhandledError"],"sources":["../../../src/replication-protocol/downstream.ts"],"sourcesContent":["import {\r\n firstValueFrom,\r\n filter,\r\n mergeMap\r\n} from 'rxjs';\r\nimport { newRxError } from '../rx-error.ts';\r\nimport { getWrittenDocumentsFromBulkWriteResponse, stackCheckpoints } from '../rx-storage-helper.ts';\r\nimport type {\r\n RxStorageInstanceReplicationState,\r\n BulkWriteRow,\r\n BulkWriteRowById,\r\n RxStorageReplicationMeta,\r\n RxDocumentData,\r\n ById,\r\n WithDeleted,\r\n DocumentsWithCheckpoint,\r\n WithDeletedAndAttachments,\r\n RxError\r\n} from '../types/index.d.ts';\r\nimport {\r\n createRevision,\r\n ensureNotFalsy,\r\n flatClone,\r\n getDefaultRevision,\r\n getHeightOfRevision,\r\n now,\r\n PROMISE_RESOLVE_VOID\r\n} from '../plugins/utils/index.ts';\r\nimport {\r\n getLastCheckpointDoc,\r\n setCheckpoint\r\n} from './checkpoint.ts';\r\nimport {\r\n stripAttachmentsDataFromMetaWriteRows,\r\n writeDocToDocState\r\n} from './helper.ts';\r\nimport {\r\n getAssumedMasterState,\r\n getMetaWriteRow\r\n} from './meta-instance.ts';\r\n\r\n/**\r\n * Writes all documents from the master to the fork.\r\n * The downstream has two operation modes\r\n * - Sync by iterating over the checkpoints via downstreamResyncOnce()\r\n * - Sync by listening to the changestream via downstreamProcessChanges()\r\n * We need this to be able to do initial syncs\r\n * and still can have fast event based sync when the client is not offline.\r\n */\r\nexport async function startReplicationDownstream<RxDocType, CheckpointType = any>(\r\n state: RxStorageInstanceReplicationState<RxDocType>\r\n) {\r\n if (\r\n state.input.initialCheckpoint &&\r\n state.input.initialCheckpoint.downstream\r\n ) {\r\n const checkpointDoc = await getLastCheckpointDoc(state, 'down');\r\n if (!checkpointDoc) {\r\n await setCheckpoint(\r\n state,\r\n 'down',\r\n state.input.initialCheckpoint.downstream\r\n );\r\n }\r\n }\r\n\r\n const identifierHash = await state.input.hashFunction(state.input.identifier);\r\n const replicationHandler = state.input.replicationHandler;\r\n\r\n // used to detect which tasks etc can in it at which order.\r\n let timer = 0;\r\n\r\n\r\n type Task = DocumentsWithCheckpoint<RxDocType, any> | 'RESYNC';\r\n type TaskWithTime = {\r\n time: number;\r\n task: Task;\r\n };\r\n const openTasks: TaskWithTime[] = [];\r\n\r\n\r\n function addNewTask(task: Task): void {\r\n state.stats.down.addNewTask = state.stats.down.addNewTask + 1;\r\n const taskWithTime = {\r\n time: timer++,\r\n task\r\n };\r\n openTasks.push(taskWithTime);\r\n state.streamQueue.down = state.streamQueue.down\r\n .then(() => {\r\n const useTasks: Task[] = [];\r\n while (openTasks.length > 0) {\r\n state.events.active.down.next(true);\r\n const innerTaskWithTime = ensureNotFalsy(openTasks.shift());\r\n\r\n /**\r\n * If the task came in before the last time we started the pull\r\n * from the master, then we can drop the task.\r\n */\r\n if (innerTaskWithTime.time < lastTimeMasterChangesRequested) {\r\n continue;\r\n }\r\n\r\n if (innerTaskWithTime.task === 'RESYNC') {\r\n if (useTasks.length === 0) {\r\n useTasks.push(innerTaskWithTime.task);\r\n break;\r\n } else {\r\n break;\r\n }\r\n }\r\n\r\n useTasks.push(innerTaskWithTime.task);\r\n }\r\n if (useTasks.length === 0) {\r\n return;\r\n }\r\n\r\n if (useTasks[0] === 'RESYNC') {\r\n return downstreamResyncOnce();\r\n } else {\r\n return downstreamProcessChanges(useTasks);\r\n }\r\n }).then(() => {\r\n state.events.active.down.next(false);\r\n if (\r\n !state.firstSyncDone.down.getValue() &&\r\n !state.events.canceled.getValue()\r\n ) {\r\n state.firstSyncDone.down.next(true);\r\n }\r\n });\r\n }\r\n addNewTask('RESYNC');\r\n\r\n /**\r\n * If a write on the master happens, we have to trigger the downstream.\r\n * Only do this if not canceled yet, otherwise firstValueFrom errors\r\n * when running on a completed observable.\r\n */\r\n if (!state.events.canceled.getValue()) {\r\n const sub = replicationHandler\r\n .masterChangeStream$\r\n .pipe(\r\n mergeMap(async (ev: any) => {\r\n /**\r\n * While a push is running, we have to delay all incoming\r\n * events from the server to not mix up the replication state.\r\n */\r\n await firstValueFrom(\r\n state.events.active.up.pipe(filter((s: boolean) => !s))\r\n );\r\n return ev;\r\n })\r\n )\r\n .subscribe((task: Task) => {\r\n state.stats.down.masterChangeStreamEmit = state.stats.down.masterChangeStreamEmit + 1;\r\n addNewTask(task);\r\n });\r\n // unsubscribe when replication is canceled\r\n firstValueFrom(\r\n state.events.canceled.pipe(\r\n filter((canceled: boolean) => !!canceled)\r\n )\r\n ).then(() => sub.unsubscribe());\r\n }\r\n\r\n\r\n /**\r\n * For faster performance, we directly start each write\r\n * and then await all writes at the end.\r\n */\r\n let lastTimeMasterChangesRequested: number = -1;\r\n async function downstreamResyncOnce() {\r\n state.stats.down.downstreamResyncOnce = state.stats.down.downstreamResyncOnce + 1;\r\n if (state.events.canceled.getValue()) {\r\n return;\r\n }\r\n\r\n state.checkpointQueue = state.checkpointQueue.then(() => getLastCheckpointDoc(state, 'down'));\r\n let lastCheckpoint: CheckpointType = await state.checkpointQueue;\r\n\r\n\r\n const promises: Promise<any>[] = [];\r\n while (!state.events.canceled.getValue()) {\r\n lastTimeMasterChangesRequested = timer++;\r\n const downResult = await replicationHandler.masterChangesSince(\r\n lastCheckpoint,\r\n state.input.pullBatchSize\r\n );\r\n\r\n if (downResult.documents.length === 0) {\r\n break;\r\n }\r\n\r\n lastCheckpoint = stackCheckpoints([lastCheckpoint, downResult.checkpoint]);\r\n\r\n promises.push(\r\n persistFromMaster(\r\n downResult.documents,\r\n lastCheckpoint\r\n )\r\n );\r\n\r\n /**\r\n * By definition we stop pull when the pulled documents\r\n * do not fill up the pullBatchSize because we\r\n * can assume that the remote has no more documents.\r\n */\r\n if (downResult.documents.length < state.input.pullBatchSize) {\r\n break;\r\n }\r\n\r\n }\r\n await Promise.all(promises);\r\n }\r\n\r\n\r\n function downstreamProcessChanges(tasks: Task[]) {\r\n state.stats.down.downstreamProcessChanges = state.stats.down.downstreamProcessChanges + 1;\r\n let docsOfAllTasks: WithDeleted<RxDocType>[] = [];\r\n let lastCheckpoint: CheckpointType | undefined = null as any;\r\n\r\n tasks.forEach(task => {\r\n if (task === 'RESYNC') {\r\n throw new Error('SNH');\r\n }\r\n docsOfAllTasks = docsOfAllTasks.concat(task.documents);\r\n lastCheckpoint = stackCheckpoints([lastCheckpoint, task.checkpoint]);\r\n });\r\n return persistFromMaster(\r\n docsOfAllTasks,\r\n ensureNotFalsy(lastCheckpoint)\r\n );\r\n }\r\n\r\n\r\n /**\r\n * It can happen that the calls to masterChangesSince() or the changeStream()\r\n * are way faster than how fast the documents can be persisted.\r\n * Therefore we merge all incoming downResults into the nonPersistedFromMaster object\r\n * and process them together if possible.\r\n * This often bundles up single writes and improves performance\r\n * by processing the documents in bulks.\r\n */\r\n let persistenceQueue = PROMISE_RESOLVE_VOID;\r\n const nonPersistedFromMaster: {\r\n checkpoint?: CheckpointType;\r\n docs: ById<WithDeleted<RxDocType>>;\r\n } = {\r\n docs: {}\r\n };\r\n\r\n function persistFromMaster(\r\n docs: WithDeleted<RxDocType>[],\r\n checkpoint: CheckpointType\r\n ): Promise<void> {\r\n const primaryPath = state.primaryPath;\r\n state.stats.down.persistFromMaster = state.stats.down.persistFromMaster + 1;\r\n\r\n /**\r\n * Add the new docs to the non-persistent list\r\n */\r\n docs.forEach(docData => {\r\n const docId: string = (docData as any)[primaryPath];\r\n nonPersistedFromMaster.docs[docId] = docData;\r\n });\r\n nonPersistedFromMaster.checkpoint = checkpoint;\r\n\r\n /**\r\n * Run in the queue\r\n * with all open documents from nonPersistedFromMaster.\r\n */\r\n persistenceQueue = persistenceQueue.then(() => {\r\n const downDocsById: ById<WithDeletedAndAttachments<RxDocType>> = nonPersistedFromMaster.docs;\r\n nonPersistedFromMaster.docs = {};\r\n const useCheckpoint = nonPersistedFromMaster.checkpoint;\r\n const docIds = Object.keys(downDocsById);\r\n\r\n if (\r\n state.events.canceled.getValue() ||\r\n docIds.length === 0\r\n ) {\r\n return PROMISE_RESOLVE_VOID;\r\n }\r\n\r\n const writeRowsToFork: BulkWriteRow<RxDocType>[] = [];\r\n const writeRowsToForkById: ById<BulkWriteRow<RxDocType>> = {};\r\n const writeRowsToMeta: BulkWriteRowById<RxStorageReplicationMeta<RxDocType, CheckpointType>> = {};\r\n const useMetaWriteRows: BulkWriteRow<RxStorageReplicationMeta<RxDocType, CheckpointType>>[] = [];\r\n\r\n return Promise.all([\r\n state.input.forkInstance.findDocumentsById(docIds, true),\r\n getAssumedMasterState(\r\n state,\r\n docIds\r\n )\r\n ]).then(([\r\n currentForkStateList,\r\n assumedMasterState\r\n ]) => {\r\n const currentForkState = new Map<string, RxDocumentData<RxDocType>>();\r\n currentForkStateList.forEach(doc => currentForkState.set((doc as any)[primaryPath], doc));\r\n return Promise.all(\r\n docIds.map(async (docId) => {\r\n const forkStateFullDoc: RxDocumentData<RxDocType> | undefined = currentForkState.get(docId);\r\n const forkStateDocData: WithDeletedAndAttachments<RxDocType> | undefined = forkStateFullDoc\r\n ? writeDocToDocState(forkStateFullDoc, state.hasAttachments, false)\r\n : undefined\r\n ;\r\n const masterState = downDocsById[docId];\r\n const assumedMaster = assumedMasterState[docId];\r\n\r\n if (\r\n assumedMaster &&\r\n forkStateFullDoc &&\r\n assumedMaster.metaDocument.isResolvedConflict === forkStateFullDoc._rev\r\n ) {\r\n /**\r\n * The current fork state represents a resolved conflict\r\n * that first must be sent to the master in the upstream.\r\n * All conflicts are resolved by the upstream.\r\n */\r\n // return PROMISE_RESOLVE_VOID;\r\n await state.streamQueue.up;\r\n }\r\n\r\n let isAssumedMasterEqualToForkState = !assumedMaster || !forkStateDocData ?\r\n false :\r\n state.input.conflictHandler.isEqual(\r\n assumedMaster.docData,\r\n forkStateDocData,\r\n 'downstream-check-if-equal-0'\r\n );\r\n if (\r\n !isAssumedMasterEqualToForkState &&\r\n (\r\n assumedMaster &&\r\n (assumedMaster.docData as any)._rev &&\r\n forkStateFullDoc &&\r\n forkStateFullDoc._meta[state.input.identifier] &&\r\n getHeightOfRevision(forkStateFullDoc._rev) === forkStateFullDoc._meta[state.input.identifier]\r\n )\r\n ) {\r\n isAssumedMasterEqualToForkState = true;\r\n }\r\n\r\n if (\r\n (\r\n (\r\n forkStateFullDoc &&\r\n assumedMaster &&\r\n isAssumedMasterEqualToForkState === false\r\n )\r\n ||\r\n (\r\n forkStateFullDoc && !assumedMaster\r\n )\r\n ) && !state.skipStoringPullMeta\r\n &&\r\n !(\r\n forkStateFullDoc._meta.o &&\r\n (\r\n forkStateFullDoc._meta.o.hash === identifierHash &&\r\n forkStateFullDoc._meta.o._rev === getHeightOfRevision(forkStateFullDoc._rev)\r\n )\r\n )\r\n ) {\r\n\r\n /**\r\n * We have a non-upstream-replicated\r\n * local write to the fork.\r\n * This means either we have to upstream the local\r\n * doc data first, or it means that the fork state was\r\n * synced from the master but the process exited before\r\n * the metadata was written.\r\n * @link https://github.com/pubkey/rxdb/pull/7804\r\n */\r\n return PROMISE_RESOLVE_VOID;\r\n }\r\n\r\n const areStatesExactlyEqual = !forkStateDocData\r\n ? false\r\n : state.input.conflictHandler.isEqual(\r\n masterState,\r\n forkStateDocData,\r\n 'downstream-check-if-equal-1'\r\n );\r\n if (\r\n forkStateDocData &&\r\n areStatesExactlyEqual\r\n ) {\r\n /**\r\n * Document states are exactly equal.\r\n * This can happen when the replication is shut down\r\n * unexpected like when the user goes offline.\r\n *\r\n * Only when the assumedMaster is different from the forkState,\r\n * we have to patch the document in the meta instance.\r\n */\r\n if (\r\n !assumedMaster ||\r\n isAssumedMasterEqualToForkState === false\r\n ) {\r\n useMetaWriteRows.push(\r\n await getMetaWriteRow(\r\n state,\r\n forkStateDocData,\r\n assumedMaster ? assumedMaster.metaDocument : undefined\r\n )\r\n );\r\n }\r\n return PROMISE_RESOLVE_VOID;\r\n }\r\n\r\n /**\r\n * All other master states need to be written to the forkInstance\r\n * and metaInstance.\r\n */\r\n const newForkState = Object.assign(\r\n {},\r\n masterState,\r\n forkStateFullDoc ? {\r\n _meta: flatClone(forkStateFullDoc._meta),\r\n _attachments: state.hasAttachments && masterState._attachments ? masterState._attachments : {},\r\n _rev: getDefaultRevision()\r\n } : {\r\n _meta: {\r\n lwt: now()\r\n },\r\n _rev: getDefaultRevision(),\r\n _attachments: state.hasAttachments && masterState._attachments ? masterState._attachments : {}\r\n }\r\n );\r\n /**\r\n * If the remote works with revisions,\r\n * we store the height of the next fork-state revision\r\n * inside of the documents meta data.\r\n * By doing so we can filter it out in the upstream\r\n * and detect the document as being equal to master or not.\r\n * This is used for example in the CouchDB replication plugin.\r\n */\r\n if ((masterState as any)._rev) {\r\n const nextRevisionHeight = !forkStateFullDoc ? 1 : getHeightOfRevision(forkStateFullDoc._rev) + 1;\r\n newForkState._meta[state.input.identifier] = nextRevisionHeight;\r\n if (state.input.keepMeta) {\r\n newForkState._rev = (masterState as any)._rev;\r\n }\r\n }\r\n if (\r\n state.input.keepMeta &&\r\n (masterState as any)._meta\r\n ) {\r\n newForkState._meta = (masterState as any)._meta;\r\n }\r\n\r\n\r\n\r\n newForkState._meta.o = {\r\n _rev: !forkStateFullDoc ? 1 : getHeightOfRevision(forkStateFullDoc._rev) + 1,\r\n hash: identifierHash\r\n };\r\n\r\n const forkWriteRow = {\r\n previous: forkStateFullDoc,\r\n document: newForkState\r\n };\r\n\r\n forkWriteRow.document._rev = forkWriteRow.document._rev ? forkWriteRow.document._rev : createRevision(\r\n identifierHash,\r\n forkWriteRow.previous\r\n );\r\n\r\n writeRowsToFork.push(forkWriteRow);\r\n writeRowsToForkById[docId] = forkWriteRow;\r\n writeRowsToMeta[docId] = await getMetaWriteRow(\r\n state,\r\n masterState,\r\n assumedMaster ? assumedMaster.metaDocument : undefined\r\n );\r\n })\r\n );\r\n }).then(async () => {\r\n if (writeRowsToFork.length > 0) {\r\n return state.input.forkInstance.bulkWrite(\r\n writeRowsToFork,\r\n await state.downstreamBulkWriteFlag\r\n ).then((forkWriteResult) => {\r\n const success = getWrittenDocumentsFromBulkWriteResponse(\r\n state.primaryPath,\r\n writeRowsToFork,\r\n forkWriteResult\r\n );\r\n success.forEach(doc => {\r\n const docId = (doc as any)[primaryPath];\r\n state.events.processed.down.next(writeRowsToForkById[docId]);\r\n useMetaWriteRows.push(writeRowsToMeta[docId]);\r\n });\r\n let mustThrow: RxError | undefined;\r\n forkWriteResult.error.forEach(error => {\r\n /**\r\n * We do not have to care about downstream conflict errors here\r\n * because on conflict, it will be solved locally and result in another write.\r\n */\r\n if (error.status === 409) {\r\n return;\r\n }\r\n // other non-conflict errors must be handled\r\n const throwMe = newRxError('RC_PULL', {\r\n writeError: error\r\n });\r\n state.events.error.next(throwMe);\r\n mustThrow = throwMe;\r\n });\r\n if (mustThrow) {\r\n throw mustThrow;\r\n }\r\n });\r\n }\r\n }).then(() => {\r\n if (!state.skipStoringPullMeta && useMetaWriteRows.length > 0) {\r\n return state.input.metaInstance.bulkWrite(\r\n stripAttachmentsDataFromMetaWriteRows(state, useMetaWriteRows),\r\n 'replication-down-write-meta'\r\n ).then(metaWriteResult => {\r\n metaWriteResult.error\r\n .forEach(writeError => {\r\n state.events.error.next(newRxError('RC_PULL', {\r\n id: writeError.documentId,\r\n writeError\r\n }));\r\n });\r\n });\r\n }\r\n }).then(() => {\r\n /**\r\n * For better performance we do not await checkpoint writes,\r\n * but to ensure order on parallel checkpoint writes,\r\n * we have to use a queue.\r\n */\r\n setCheckpoint(\r\n state,\r\n 'down',\r\n useCheckpoint\r\n );\r\n });\r\n }).catch(unhandledError => state.events.error.next(unhandledError));\r\n return persistenceQueue;\r\n }\r\n}\r\n"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{"version":3,"file":"downstream.js","names":["firstValueFrom","filter","mergeMap","newRxError","getWrittenDocumentsFromBulkWriteResponse","stackCheckpoints","createRevision","ensureNotFalsy","flatClone","getDefaultRevision","getHeightOfRevision","now","PROMISE_RESOLVE_VOID","getLastCheckpointDoc","setCheckpoint","stripAttachmentsDataFromMetaWriteRows","writeDocToDocState","getAssumedMasterState","getMetaWriteRow","startReplicationDownstream","state","input","initialCheckpoint","downstream","checkpointDoc","identifierHash","hashFunction","identifier","replicationHandler","timer","openTasks","addNewTask","task","stats","down","taskWithTime","time","push","streamQueue","then","useTasks","length","events","active","next","innerTaskWithTime","shift","lastTimeMasterChangesRequested","downstreamResyncOnce","downstreamProcessChanges","firstSyncDone","getValue","canceled","sub","masterChangeStream$","pipe","ev","up","s","subscribe","masterChangeStreamEmit","unsubscribe","checkpointQueue","lastCheckpoint","promises","downResult","masterChangesSince","pullBatchSize","documents","checkpoint","persistFromMaster","Promise","all","tasks","docsOfAllTasks","forEach","concat","persistenceQueue","nonPersistedFromMaster","docs","primaryPath","docData","docId","downDocsById","useCheckpoint","docIds","Object","keys","writeRowsToFork","writeRowsToForkById","writeRowsToMeta","useMetaWriteRows","forkInstance","findDocumentsById","currentForkStateList","assumedMasterState","currentForkState","Map","doc","set","map","forkStateFullDoc","get","forkStateDocData","hasAttachments","undefined","masterState","assumedMaster","metaDocument","isResolvedConflict","_rev","isAssumedMasterEqualToForkState","conflictHandler","isEqual","_meta","skipStoringPullMeta","o","hash","areStatesExactlyEqual","newForkState","assign","_attachments","lwt","nextRevisionHeight","keepMeta","forkWriteRow","previous","document","bulkWrite","downstreamBulkWriteFlag","forkWriteResult","success","processed","mustThrow","error","status","throwMe","writeError","metaInstance","metaWriteResult","id","documentId","catch","unhandledError"],"sources":["../../../src/replication-protocol/downstream.ts"],"sourcesContent":["import {\r\n firstValueFrom,\r\n filter,\r\n mergeMap\r\n} from 'rxjs';\r\nimport { newRxError } from '../rx-error.ts';\r\nimport { getWrittenDocumentsFromBulkWriteResponse, stackCheckpoints } from '../rx-storage-helper.ts';\r\nimport type {\r\n RxStorageInstanceReplicationState,\r\n BulkWriteRow,\r\n BulkWriteRowById,\r\n RxStorageReplicationMeta,\r\n RxDocumentData,\r\n ById,\r\n WithDeleted,\r\n DocumentsWithCheckpoint,\r\n WithDeletedAndAttachments,\r\n RxError\r\n} from '../types/index.d.ts';\r\nimport {\r\n createRevision,\r\n ensureNotFalsy,\r\n flatClone,\r\n getDefaultRevision,\r\n getHeightOfRevision,\r\n now,\r\n PROMISE_RESOLVE_VOID\r\n} from '../plugins/utils/index.ts';\r\nimport {\r\n getLastCheckpointDoc,\r\n setCheckpoint\r\n} from './checkpoint.ts';\r\nimport {\r\n stripAttachmentsDataFromMetaWriteRows,\r\n writeDocToDocState\r\n} from './helper.ts';\r\nimport {\r\n getAssumedMasterState,\r\n getMetaWriteRow\r\n} from './meta-instance.ts';\r\n\r\n/**\r\n * Writes all documents from the master to the fork.\r\n * The downstream has two operation modes\r\n * - Sync by iterating over the checkpoints via downstreamResyncOnce()\r\n * - Sync by listening to the changestream via downstreamProcessChanges()\r\n * We need this to be able to do initial syncs\r\n * and still can have fast event based sync when the client is not offline.\r\n */\r\nexport async function startReplicationDownstream<RxDocType, CheckpointType = any>(\r\n state: RxStorageInstanceReplicationState<RxDocType>\r\n) {\r\n if (\r\n state.input.initialCheckpoint &&\r\n state.input.initialCheckpoint.downstream\r\n ) {\r\n const checkpointDoc = await getLastCheckpointDoc(state, 'down');\r\n if (!checkpointDoc) {\r\n await setCheckpoint(\r\n state,\r\n 'down',\r\n state.input.initialCheckpoint.downstream\r\n );\r\n }\r\n }\r\n\r\n const identifierHash = await state.input.hashFunction(state.input.identifier);\r\n const replicationHandler = state.input.replicationHandler;\r\n\r\n // used to detect which tasks etc can in it at which order.\r\n let timer = 0;\r\n\r\n\r\n type Task = DocumentsWithCheckpoint<RxDocType, any> | 'RESYNC';\r\n type TaskWithTime = {\r\n time: number;\r\n task: Task;\r\n };\r\n const openTasks: TaskWithTime[] = [];\r\n\r\n\r\n function addNewTask(task: Task): void {\r\n state.stats.down.addNewTask = state.stats.down.addNewTask + 1;\r\n const taskWithTime = {\r\n time: timer++,\r\n task\r\n };\r\n openTasks.push(taskWithTime);\r\n state.streamQueue.down = state.streamQueue.down\r\n .then(() => {\r\n const useTasks: Task[] = [];\r\n while (openTasks.length > 0) {\r\n state.events.active.down.next(true);\r\n const innerTaskWithTime = ensureNotFalsy(openTasks.shift());\r\n\r\n /**\r\n * If the task came in before the last time we started the pull\r\n * from the master, then we can drop the task.\r\n */\r\n if (innerTaskWithTime.time < lastTimeMasterChangesRequested) {\r\n continue;\r\n }\r\n\r\n if (innerTaskWithTime.task === 'RESYNC') {\r\n if (useTasks.length === 0) {\r\n useTasks.push(innerTaskWithTime.task);\r\n break;\r\n } else {\r\n break;\r\n }\r\n }\r\n\r\n useTasks.push(innerTaskWithTime.task);\r\n }\r\n if (useTasks.length === 0) {\r\n return;\r\n }\r\n\r\n if (useTasks[0] === 'RESYNC') {\r\n return downstreamResyncOnce();\r\n } else {\r\n return downstreamProcessChanges(useTasks);\r\n }\r\n }).then(() => {\r\n state.events.active.down.next(false);\r\n if (\r\n !state.firstSyncDone.down.getValue() &&\r\n !state.events.canceled.getValue()\r\n ) {\r\n state.firstSyncDone.down.next(true);\r\n }\r\n });\r\n }\r\n addNewTask('RESYNC');\r\n\r\n /**\r\n * If a write on the master happens, we have to trigger the downstream.\r\n * Only do this if not canceled yet, otherwise firstValueFrom errors\r\n * when running on a completed observable.\r\n */\r\n if (!state.events.canceled.getValue()) {\r\n const sub = replicationHandler\r\n .masterChangeStream$\r\n .pipe(\r\n mergeMap(async (ev: any) => {\r\n /**\r\n * While a push is running, we have to delay all incoming\r\n * events from the server to not mix up the replication state.\r\n */\r\n await firstValueFrom(\r\n state.events.active.up.pipe(filter((s: boolean) => !s))\r\n );\r\n return ev;\r\n })\r\n )\r\n .subscribe((task: Task) => {\r\n state.stats.down.masterChangeStreamEmit = state.stats.down.masterChangeStreamEmit + 1;\r\n addNewTask(task);\r\n });\r\n // unsubscribe when replication is canceled\r\n firstValueFrom(\r\n state.events.canceled.pipe(\r\n filter((canceled: boolean) => !!canceled)\r\n )\r\n ).then(() => sub.unsubscribe());\r\n }\r\n\r\n\r\n /**\r\n * For faster performance, we directly start each write\r\n * and then await all writes at the end.\r\n */\r\n let lastTimeMasterChangesRequested: number = -1;\r\n async function downstreamResyncOnce() {\r\n state.stats.down.downstreamResyncOnce = state.stats.down.downstreamResyncOnce + 1;\r\n if (state.events.canceled.getValue()) {\r\n return;\r\n }\r\n\r\n state.checkpointQueue = state.checkpointQueue.then(() => getLastCheckpointDoc(state, 'down'));\r\n let lastCheckpoint: CheckpointType = await state.checkpointQueue;\r\n\r\n\r\n const promises: Promise<any>[] = [];\r\n while (!state.events.canceled.getValue()) {\r\n lastTimeMasterChangesRequested = timer++;\r\n const downResult = await replicationHandler.masterChangesSince(\r\n lastCheckpoint,\r\n state.input.pullBatchSize\r\n );\r\n\r\n if (downResult.documents.length === 0) {\r\n break;\r\n }\r\n\r\n lastCheckpoint = stackCheckpoints([lastCheckpoint, downResult.checkpoint]);\r\n\r\n promises.push(\r\n persistFromMaster(\r\n downResult.documents,\r\n lastCheckpoint\r\n )\r\n );\r\n\r\n /**\r\n * By definition we stop pull when the pulled documents\r\n * do not fill up the pullBatchSize because we\r\n * can assume that the remote has no more documents.\r\n */\r\n if (downResult.documents.length < state.input.pullBatchSize) {\r\n break;\r\n }\r\n\r\n }\r\n await Promise.all(promises);\r\n }\r\n\r\n\r\n function downstreamProcessChanges(tasks: Task[]) {\r\n state.stats.down.downstreamProcessChanges = state.stats.down.downstreamProcessChanges + 1;\r\n let docsOfAllTasks: WithDeleted<RxDocType>[] = [];\r\n let lastCheckpoint: CheckpointType | undefined = null as any;\r\n\r\n tasks.forEach(task => {\r\n if (task === 'RESYNC') {\r\n throw newRxError('SNH');\r\n }\r\n docsOfAllTasks = docsOfAllTasks.concat(task.documents);\r\n lastCheckpoint = stackCheckpoints([lastCheckpoint, task.checkpoint]);\r\n });\r\n return persistFromMaster(\r\n docsOfAllTasks,\r\n ensureNotFalsy(lastCheckpoint)\r\n );\r\n }\r\n\r\n\r\n /**\r\n * It can happen that the calls to masterChangesSince() or the changeStream()\r\n * are way faster than how fast the documents can be persisted.\r\n * Therefore we merge all incoming downResults into the nonPersistedFromMaster object\r\n * and process them together if possible.\r\n * This often bundles up single writes and improves performance\r\n * by processing the documents in bulks.\r\n */\r\n let persistenceQueue = PROMISE_RESOLVE_VOID;\r\n const nonPersistedFromMaster: {\r\n checkpoint?: CheckpointType;\r\n docs: ById<WithDeleted<RxDocType>>;\r\n } = {\r\n docs: {}\r\n };\r\n\r\n function persistFromMaster(\r\n docs: WithDeleted<RxDocType>[],\r\n checkpoint: CheckpointType\r\n ): Promise<void> {\r\n const primaryPath = state.primaryPath;\r\n state.stats.down.persistFromMaster = state.stats.down.persistFromMaster + 1;\r\n\r\n /**\r\n * Add the new docs to the non-persistent list\r\n */\r\n docs.forEach(docData => {\r\n const docId: string = (docData as any)[primaryPath];\r\n nonPersistedFromMaster.docs[docId] = docData;\r\n });\r\n nonPersistedFromMaster.checkpoint = checkpoint;\r\n\r\n /**\r\n * Run in the queue\r\n * with all open documents from nonPersistedFromMaster.\r\n */\r\n persistenceQueue = persistenceQueue.then(() => {\r\n const downDocsById: ById<WithDeletedAndAttachments<RxDocType>> = nonPersistedFromMaster.docs;\r\n nonPersistedFromMaster.docs = {};\r\n const useCheckpoint = nonPersistedFromMaster.checkpoint;\r\n const docIds = Object.keys(downDocsById);\r\n\r\n if (\r\n state.events.canceled.getValue() ||\r\n docIds.length === 0\r\n ) {\r\n return PROMISE_RESOLVE_VOID;\r\n }\r\n\r\n const writeRowsToFork: BulkWriteRow<RxDocType>[] = [];\r\n const writeRowsToForkById: ById<BulkWriteRow<RxDocType>> = {};\r\n const writeRowsToMeta: BulkWriteRowById<RxStorageReplicationMeta<RxDocType, CheckpointType>> = {};\r\n const useMetaWriteRows: BulkWriteRow<RxStorageReplicationMeta<RxDocType, CheckpointType>>[] = [];\r\n\r\n return Promise.all([\r\n state.input.forkInstance.findDocumentsById(docIds, true),\r\n getAssumedMasterState(\r\n state,\r\n docIds\r\n )\r\n ]).then(([\r\n currentForkStateList,\r\n assumedMasterState\r\n ]) => {\r\n const currentForkState = new Map<string, RxDocumentData<RxDocType>>();\r\n currentForkStateList.forEach(doc => currentForkState.set((doc as any)[primaryPath], doc));\r\n return Promise.all(\r\n docIds.map(async (docId) => {\r\n const forkStateFullDoc: RxDocumentData<RxDocType> | undefined = currentForkState.get(docId);\r\n const forkStateDocData: WithDeletedAndAttachments<RxDocType> | undefined = forkStateFullDoc\r\n ? writeDocToDocState(forkStateFullDoc, state.hasAttachments, false)\r\n : undefined\r\n ;\r\n const masterState = downDocsById[docId];\r\n const assumedMaster = assumedMasterState[docId];\r\n\r\n if (\r\n assumedMaster &&\r\n forkStateFullDoc &&\r\n assumedMaster.metaDocument.isResolvedConflict === forkStateFullDoc._rev\r\n ) {\r\n /**\r\n * The current fork state represents a resolved conflict\r\n * that first must be sent to the master in the upstream.\r\n * All conflicts are resolved by the upstream.\r\n */\r\n // return PROMISE_RESOLVE_VOID;\r\n await state.streamQueue.up;\r\n }\r\n\r\n let isAssumedMasterEqualToForkState = !assumedMaster || !forkStateDocData ?\r\n false :\r\n state.input.conflictHandler.isEqual(\r\n assumedMaster.docData,\r\n forkStateDocData,\r\n 'downstream-check-if-equal-0'\r\n );\r\n if (\r\n !isAssumedMasterEqualToForkState &&\r\n (\r\n assumedMaster &&\r\n (assumedMaster.docData as any)._rev &&\r\n forkStateFullDoc &&\r\n forkStateFullDoc._meta[state.input.identifier] &&\r\n getHeightOfRevision(forkStateFullDoc._rev) === forkStateFullDoc._meta[state.input.identifier]\r\n )\r\n ) {\r\n isAssumedMasterEqualToForkState = true;\r\n }\r\n\r\n if (\r\n (\r\n (\r\n forkStateFullDoc &&\r\n assumedMaster &&\r\n isAssumedMasterEqualToForkState === false\r\n )\r\n ||\r\n (\r\n forkStateFullDoc && !assumedMaster\r\n )\r\n ) && !state.skipStoringPullMeta\r\n &&\r\n !(\r\n forkStateFullDoc._meta.o &&\r\n (\r\n forkStateFullDoc._meta.o.hash === identifierHash &&\r\n forkStateFullDoc._meta.o._rev === getHeightOfRevision(forkStateFullDoc._rev)\r\n )\r\n )\r\n ) {\r\n\r\n /**\r\n * We have a non-upstream-replicated\r\n * local write to the fork.\r\n * This means either we have to upstream the local\r\n * doc data first, or it means that the fork state was\r\n * synced from the master but the process exited before\r\n * the metadata was written.\r\n * @link https://github.com/pubkey/rxdb/pull/7804\r\n */\r\n return PROMISE_RESOLVE_VOID;\r\n }\r\n\r\n const areStatesExactlyEqual = !forkStateDocData\r\n ? false\r\n : state.input.conflictHandler.isEqual(\r\n masterState,\r\n forkStateDocData,\r\n 'downstream-check-if-equal-1'\r\n );\r\n if (\r\n forkStateDocData &&\r\n areStatesExactlyEqual\r\n ) {\r\n /**\r\n * Document states are exactly equal.\r\n * This can happen when the replication is shut down\r\n * unexpected like when the user goes offline.\r\n *\r\n * Only when the assumedMaster is different from the forkState,\r\n * we have to patch the document in the meta instance.\r\n */\r\n if (\r\n !assumedMaster ||\r\n isAssumedMasterEqualToForkState === false\r\n ) {\r\n useMetaWriteRows.push(\r\n await getMetaWriteRow(\r\n state,\r\n forkStateDocData,\r\n assumedMaster ? assumedMaster.metaDocument : undefined\r\n )\r\n );\r\n }\r\n return PROMISE_RESOLVE_VOID;\r\n }\r\n\r\n /**\r\n * All other master states need to be written to the forkInstance\r\n * and metaInstance.\r\n */\r\n const newForkState = Object.assign(\r\n {},\r\n masterState,\r\n forkStateFullDoc ? {\r\n _meta: flatClone(forkStateFullDoc._meta),\r\n _attachments: state.hasAttachments && masterState._attachments ? masterState._attachments : {},\r\n _rev: getDefaultRevision()\r\n } : {\r\n _meta: {\r\n lwt: now()\r\n },\r\n _rev: getDefaultRevision(),\r\n _attachments: state.hasAttachments && masterState._attachments ? masterState._attachments : {}\r\n }\r\n );\r\n /**\r\n * If the remote works with revisions,\r\n * we store the height of the next fork-state revision\r\n * inside of the documents meta data.\r\n * By doing so we can filter it out in the upstream\r\n * and detect the document as being equal to master or not.\r\n * This is used for example in the CouchDB replication plugin.\r\n */\r\n if ((masterState as any)._rev) {\r\n const nextRevisionHeight = !forkStateFullDoc ? 1 : getHeightOfRevision(forkStateFullDoc._rev) + 1;\r\n newForkState._meta[state.input.identifier] = nextRevisionHeight;\r\n if (state.input.keepMeta) {\r\n newForkState._rev = (masterState as any)._rev;\r\n }\r\n }\r\n if (\r\n state.input.keepMeta &&\r\n (masterState as any)._meta\r\n ) {\r\n newForkState._meta = (masterState as any)._meta;\r\n }\r\n\r\n\r\n\r\n newForkState._meta.o = {\r\n _rev: !forkStateFullDoc ? 1 : getHeightOfRevision(forkStateFullDoc._rev) + 1,\r\n hash: identifierHash\r\n };\r\n\r\n const forkWriteRow = {\r\n previous: forkStateFullDoc,\r\n document: newForkState\r\n };\r\n\r\n forkWriteRow.document._rev = forkWriteRow.document._rev ? forkWriteRow.document._rev : createRevision(\r\n identifierHash,\r\n forkWriteRow.previous\r\n );\r\n\r\n writeRowsToFork.push(forkWriteRow);\r\n writeRowsToForkById[docId] = forkWriteRow;\r\n writeRowsToMeta[docId] = await getMetaWriteRow(\r\n state,\r\n masterState,\r\n assumedMaster ? assumedMaster.metaDocument : undefined\r\n );\r\n })\r\n );\r\n }).then(async () => {\r\n if (writeRowsToFork.length > 0) {\r\n return state.input.forkInstance.bulkWrite(\r\n writeRowsToFork,\r\n await state.downstreamBulkWriteFlag\r\n ).then((forkWriteResult) => {\r\n const success = getWrittenDocumentsFromBulkWriteResponse(\r\n state.primaryPath,\r\n writeRowsToFork,\r\n forkWriteResult\r\n );\r\n success.forEach(doc => {\r\n const docId = (doc as any)[primaryPath];\r\n state.events.processed.down.next(writeRowsToForkById[docId]);\r\n useMetaWriteRows.push(writeRowsToMeta[docId]);\r\n });\r\n let mustThrow: RxError | undefined;\r\n forkWriteResult.error.forEach(error => {\r\n /**\r\n * We do not have to care about downstream conflict errors here\r\n * because on conflict, it will be solved locally and result in another write.\r\n */\r\n if (error.status === 409) {\r\n return;\r\n }\r\n // other non-conflict errors must be handled\r\n const throwMe = newRxError('RC_PULL', {\r\n writeError: error\r\n });\r\n state.events.error.next(throwMe);\r\n mustThrow = throwMe;\r\n });\r\n if (mustThrow) {\r\n throw mustThrow;\r\n }\r\n });\r\n }\r\n }).then(() => {\r\n if (!state.skipStoringPullMeta && useMetaWriteRows.length > 0) {\r\n return state.input.metaInstance.bulkWrite(\r\n stripAttachmentsDataFromMetaWriteRows(state, useMetaWriteRows),\r\n 'replication-down-write-meta'\r\n ).then(metaWriteResult => {\r\n metaWriteResult.error\r\n .forEach(writeError => {\r\n state.events.error.next(newRxError('RC_PULL', {\r\n id: writeError.documentId,\r\n writeError\r\n }));\r\n });\r\n });\r\n }\r\n }).then(() => {\r\n /**\r\n * For better performance we do not await checkpoint writes,\r\n * but to ensure order on parallel checkpoint writes,\r\n * we have to use a queue.\r\n */\r\n setCheckpoint(\r\n state,\r\n 'down',\r\n useCheckpoint\r\n );\r\n });\r\n }).catch(unhandledError => state.events.error.next(unhandledError));\r\n return persistenceQueue;\r\n }\r\n}\r\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { createRevision, flatClone, now
|
|
1
|
+
import { createRevision, flatClone, now } from "./plugins/utils/index.js";
|
|
2
2
|
import { fillObjectWithDefaults, fillPrimaryKey } from "./rx-schema-helper.js";
|
|
3
3
|
import { runAsyncPluginHooks } from "./hooks.js";
|
|
4
4
|
import { getAllCollectionDocuments } from "./rx-database-internal-store.js";
|
|
@@ -16,18 +16,23 @@ export function fillObjectDataBeforeInsert(schema, data) {
|
|
|
16
16
|
if (typeof schema.jsonSchema.primaryKey !== 'string') {
|
|
17
17
|
data = fillPrimaryKey(schema.primaryPath, schema.jsonSchema, data);
|
|
18
18
|
}
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
19
|
+
/**
|
|
20
|
+
* _meta and _rev are not set here because
|
|
21
|
+
* they are always overwritten by the wrapped storage instance
|
|
22
|
+
* in getWrappedStorageInstance() before the actual write.
|
|
23
|
+
* Skipping them here avoids unnecessary object allocations on the hot path.
|
|
24
|
+
*
|
|
25
|
+
* _deleted and _attachments still need to be initialized here because
|
|
26
|
+
* the wrapped storage does NOT set them, and they are required
|
|
27
|
+
* for the document to be valid before the storage write
|
|
28
|
+
* (e.g. _attachments is checked during attachment normalization in bulkInsert).
|
|
29
|
+
*/
|
|
22
30
|
if (!('_deleted' in data)) {
|
|
23
31
|
data._deleted = false;
|
|
24
32
|
}
|
|
25
33
|
if (!('_attachments' in data)) {
|
|
26
34
|
data._attachments = {};
|
|
27
35
|
}
|
|
28
|
-
if (!('_rev' in data)) {
|
|
29
|
-
data._rev = '';
|
|
30
|
-
}
|
|
31
36
|
return data;
|
|
32
37
|
}
|
|
33
38
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rx-collection-helper.js","names":["createRevision","flatClone","now","RX_META_LWT_MINIMUM","fillObjectWithDefaults","fillPrimaryKey","runAsyncPluginHooks","getAllCollectionDocuments","flatCloneDocWithMeta","overwritable","newRxError","fillObjectDataBeforeInsert","schema","data","jsonSchema","primaryKey","primaryPath","_meta","lwt","_deleted","_attachments","_rev","normalizeInlineAttachments","hashFunction","attachments","entries","Array","isArray","attachmentMap","att","id","length","type","Blob","obj","Object","prototype","hasOwnProperty","call","Promise","all","map","digest","size","keys","allNormalized","every","createRxCollectionStorageInstance","rxDatabase","storageInstanceCreationParams","multiInstance","storageInstance","storage","createStorageInstance","removeCollectionStorages","databaseInternalStorage","databaseInstanceToken","databaseName","collectionName","password","allCollectionMetaDocs","relevantCollectionMetaDocs","filter","metaDoc","name","removeStorages","forEach","push","isCollection","connectedStorages","row","alreadyAdded","Set","key","version","has","add","options","devMode","isDevMode","remove","writeRows","doc","writeDoc","previous","document","bulkWrite","ensureRxCollectionIsNotClosed","collection","closed"],"sources":["../../src/rx-collection-helper.ts"],"sourcesContent":["import type {\r\n HashFunction,\r\n InternalStoreDocType,\r\n RxAttachmentWriteData,\r\n RxCollection,\r\n RxDatabase,\r\n RxDocumentData,\r\n RxJsonSchema,\r\n RxStorage,\r\n RxStorageInstance,\r\n RxStorageInstanceCreationParams\r\n} from './types/index.d.ts';\r\nimport {\r\n createRevision,\r\n flatClone,\r\n now,\r\n RX_META_LWT_MINIMUM\r\n} from './plugins/utils/index.ts';\r\nimport {\r\n fillObjectWithDefaults,\r\n fillPrimaryKey\r\n} from './rx-schema-helper.ts';\r\nimport type { RxSchema } from './rx-schema.ts';\r\nimport { runAsyncPluginHooks } from './hooks.ts';\r\nimport { getAllCollectionDocuments } from './rx-database-internal-store.ts';\r\nimport { flatCloneDocWithMeta } from './rx-storage-helper.ts';\r\nimport { overwritable } from './overwritable.ts';\r\nimport type { RxCollectionBase } from './rx-collection.ts';\r\nimport { newRxError } from './rx-error.ts';\r\n\r\n/**\r\n * fills in the default data.\r\n * This also clones the data.\r\n */\r\nexport function fillObjectDataBeforeInsert<RxDocType>(\r\n schema: RxSchema<RxDocType>,\r\n data: Partial<RxDocumentData<RxDocType>> | any\r\n): RxDocumentData<RxDocType> {\r\n data = flatClone(data);\r\n data = fillObjectWithDefaults(schema, data);\r\n if (typeof schema.jsonSchema.primaryKey !== 'string') {\r\n data = fillPrimaryKey(\r\n schema.primaryPath,\r\n schema.jsonSchema,\r\n data\r\n );\r\n }\r\n data._meta = { lwt: RX_META_LWT_MINIMUM };\r\n if (!('_deleted' in data)) {\r\n data._deleted = false;\r\n }\r\n if (!('_attachments' in data)) {\r\n data._attachments = {};\r\n }\r\n if (!('_rev' in data)) {\r\n data._rev = '';\r\n }\r\n return data;\r\n}\r\n\r\n/**\r\n * Normalizes inline attachment inputs on a document's _attachments.\r\n * Accepts an array of { id, type, data } objects (aligned with putAttachment API)\r\n * and converts to the internal map format { [id]: { type, data, digest, length } }.\r\n * For each entry where data is a Blob and digest is missing,\r\n * computes digest via hashFunction and sets length from Blob.size.\r\n * Already-complete RxAttachmentWriteData entries are left untouched.\r\n */\r\nexport async function normalizeInlineAttachments(\r\n hashFunction: HashFunction,\r\n attachments: Array<{ id: string; type: string; data: Blob; }> | { [attachmentId: string]: any; }\r\n): Promise<{ [attachmentId: string]: RxAttachmentWriteData; }> {\r\n // Guard against null/undefined/non-object values\r\n if (attachments == null || typeof attachments !== 'object') {\r\n throw newRxError('COL24', { data: attachments });\r\n }\r\n\r\n let entries: [string, any][];\r\n // Only accept array format for inline attachments.\r\n // An empty object {} (set by fillObjectDataBeforeInsert) is also valid.\r\n if (Array.isArray(attachments)) {\r\n const attachmentMap: { [attachmentId: string]: any; } = {};\r\n for (const att of attachments) {\r\n if (\r\n !att ||\r\n typeof att.id !== 'string' || att.id.length === 0 ||\r\n typeof att.type !== 'string' || att.type.length === 0 ||\r\n !(att.data instanceof Blob)\r\n ) {\r\n throw newRxError('AT2', { obj: att });\r\n }\r\n if (Object.prototype.hasOwnProperty.call(attachmentMap, att.id)) {\r\n throw newRxError('AT3', { obj: att });\r\n }\r\n attachmentMap[att.id] = {\r\n type: att.type,\r\n data: att.data\r\n };\r\n }\r\n entries = Object.entries(attachmentMap);\r\n await Promise.all(\r\n entries.map(async ([, att]) => {\r\n if (att.data instanceof Blob && !att.digest) {\r\n att.digest = await hashFunction(att.data);\r\n att.length = att.data.size;\r\n }\r\n })\r\n );\r\n return attachmentMap;\r\n }\r\n\r\n // Empty object from fillObjectDataBeforeInsert — pass through\r\n if (typeof attachments === 'object' && Object.keys(attachments).length === 0) {\r\n return attachments;\r\n }\r\n\r\n // Already-normalized map (from internal paths like bulkUpsert's 409 handler)\r\n // where entries already have digest/length — pass through\r\n entries = Object.entries(attachments);\r\n const allNormalized = entries.every(([, att]) => att.digest);\r\n if (allNormalized) {\r\n return attachments;\r\n }\r\n\r\n throw newRxError('COL24', { data: attachments });\r\n}\r\n\r\n/**\r\n * Creates the storage instances that are used internally in the collection\r\n */\r\nexport async function createRxCollectionStorageInstance<RxDocumentType, Internals, InstanceCreationOptions>(\r\n rxDatabase: RxDatabase<{}, Internals, InstanceCreationOptions>,\r\n storageInstanceCreationParams: RxStorageInstanceCreationParams<RxDocumentType, InstanceCreationOptions>\r\n): Promise<RxStorageInstance<RxDocumentType, Internals, InstanceCreationOptions>> {\r\n storageInstanceCreationParams.multiInstance = rxDatabase.multiInstance;\r\n const storageInstance = await rxDatabase.storage.createStorageInstance<RxDocumentType>(\r\n storageInstanceCreationParams\r\n );\r\n return storageInstance;\r\n}\r\n\r\n/**\r\n * Removes the main storage of the collection\r\n * and all connected storages like the ones from the replication meta etc.\r\n */\r\nexport async function removeCollectionStorages(\r\n storage: RxStorage<any, any>,\r\n databaseInternalStorage: RxStorageInstance<InternalStoreDocType<any>, any, any>,\r\n databaseInstanceToken: string,\r\n databaseName: string,\r\n collectionName: string,\r\n multiInstance: boolean,\r\n password?: string,\r\n /**\r\n * If no hash function is provided,\r\n * we assume that the whole internal store is removed anyway\r\n * so we do not have to delete the meta documents.\r\n */\r\n hashFunction?: HashFunction,\r\n) {\r\n const allCollectionMetaDocs = await getAllCollectionDocuments(\r\n databaseInternalStorage\r\n );\r\n const relevantCollectionMetaDocs = allCollectionMetaDocs\r\n .filter(metaDoc => metaDoc.data.name === collectionName);\r\n let removeStorages: {\r\n collectionName: string;\r\n schema: RxJsonSchema<any>;\r\n isCollection: boolean;\r\n }[] = [];\r\n relevantCollectionMetaDocs.forEach(metaDoc => {\r\n removeStorages.push({\r\n collectionName: metaDoc.data.name,\r\n schema: metaDoc.data.schema,\r\n isCollection: true\r\n });\r\n metaDoc.data.connectedStorages.forEach(row => removeStorages.push({\r\n collectionName: row.collectionName,\r\n isCollection: false,\r\n schema: row.schema\r\n }));\r\n });\r\n\r\n // ensure uniqueness\r\n const alreadyAdded = new Set<string>();\r\n removeStorages = removeStorages.filter(row => {\r\n const key = row.collectionName + '||' + row.schema.version;\r\n if (alreadyAdded.has(key)) {\r\n return false;\r\n } else {\r\n alreadyAdded.add(key);\r\n return true;\r\n }\r\n });\r\n\r\n // remove all the storages\r\n await Promise.all(\r\n removeStorages\r\n .map(async (row) => {\r\n const storageInstance = await storage.createStorageInstance<any>({\r\n collectionName: row.collectionName,\r\n databaseInstanceToken,\r\n databaseName,\r\n /**\r\n * multiInstance must be set to true if multiInstance\r\n * was true on the database\r\n * so that the storageInstance can inform other\r\n * instances about being removed.\r\n */\r\n multiInstance,\r\n options: {},\r\n schema: row.schema,\r\n password,\r\n devMode: overwritable.isDevMode()\r\n });\r\n await storageInstance.remove();\r\n if (row.isCollection) {\r\n await runAsyncPluginHooks('postRemoveRxCollection', {\r\n storage,\r\n databaseName: databaseName,\r\n collectionName\r\n });\r\n }\r\n })\r\n );\r\n\r\n // remove the meta documents\r\n if (hashFunction) {\r\n const writeRows = relevantCollectionMetaDocs.map(doc => {\r\n const writeDoc = flatCloneDocWithMeta(doc);\r\n writeDoc._deleted = true;\r\n writeDoc._meta.lwt = now();\r\n writeDoc._rev = createRevision(\r\n databaseInstanceToken,\r\n doc\r\n );\r\n return {\r\n previous: doc,\r\n document: writeDoc\r\n };\r\n });\r\n await databaseInternalStorage.bulkWrite(\r\n writeRows,\r\n 'rx-database-remove-collection-all'\r\n );\r\n }\r\n}\r\n\r\n\r\nexport function ensureRxCollectionIsNotClosed(\r\n collection: RxCollection | RxCollectionBase<any, any, any, any, any>\r\n) {\r\n if (collection.closed) {\r\n throw newRxError(\r\n 'COL21',\r\n {\r\n collection: collection.name,\r\n version: collection.schema.version\r\n }\r\n );\r\n }\r\n}\r\n"],"mappings":"AAYA,SACIA,cAAc,EACdC,SAAS,EACTC,GAAG,EACHC,mBAAmB,QAChB,0BAA0B;AACjC,SACIC,sBAAsB,EACtBC,cAAc,QACX,uBAAuB;AAE9B,SAASC,mBAAmB,QAAQ,YAAY;AAChD,SAASC,yBAAyB,QAAQ,iCAAiC;AAC3E,SAASC,oBAAoB,QAAQ,wBAAwB;AAC7D,SAASC,YAAY,QAAQ,mBAAmB;AAEhD,SAASC,UAAU,QAAQ,eAAe;;AAE1C;AACA;AACA;AACA;AACA,OAAO,SAASC,0BAA0BA,CACtCC,MAA2B,EAC3BC,IAA8C,EACrB;EACzBA,IAAI,GAAGZ,SAAS,CAACY,IAAI,CAAC;EACtBA,IAAI,GAAGT,sBAAsB,CAACQ,MAAM,EAAEC,IAAI,CAAC;EAC3C,IAAI,OAAOD,MAAM,CAACE,UAAU,CAACC,UAAU,KAAK,QAAQ,EAAE;IAClDF,IAAI,GAAGR,cAAc,CACjBO,MAAM,CAACI,WAAW,EAClBJ,MAAM,CAACE,UAAU,EACjBD,IACJ,CAAC;EACL;EACAA,IAAI,CAACI,KAAK,GAAG;IAAEC,GAAG,EAAEf;EAAoB,CAAC;EACzC,IAAI,EAAE,UAAU,IAAIU,IAAI,CAAC,EAAE;IACvBA,IAAI,CAACM,QAAQ,GAAG,KAAK;EACzB;EACA,IAAI,EAAE,cAAc,IAAIN,IAAI,CAAC,EAAE;IAC3BA,IAAI,CAACO,YAAY,GAAG,CAAC,CAAC;EAC1B;EACA,IAAI,EAAE,MAAM,IAAIP,IAAI,CAAC,EAAE;IACnBA,IAAI,CAACQ,IAAI,GAAG,EAAE;EAClB;EACA,OAAOR,IAAI;AACf;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,eAAeS,0BAA0BA,CAC5CC,YAA0B,EAC1BC,WAAgG,EACrC;EAC3D;EACA,IAAIA,WAAW,IAAI,IAAI,IAAI,OAAOA,WAAW,KAAK,QAAQ,EAAE;IACxD,MAAMd,UAAU,CAAC,OAAO,EAAE;MAAEG,IAAI,EAAEW;IAAY,CAAC,CAAC;EACpD;EAEA,IAAIC,OAAwB;EAC5B;EACA;EACA,IAAIC,KAAK,CAACC,OAAO,CAACH,WAAW,CAAC,EAAE;IAC5B,IAAMI,aAA+C,GAAG,CAAC,CAAC;IAC1D,KAAK,IAAMC,GAAG,IAAIL,WAAW,EAAE;MAC3B,IACI,CAACK,GAAG,IACJ,OAAOA,GAAG,CAACC,EAAE,KAAK,QAAQ,IAAID,GAAG,CAACC,EAAE,CAACC,MAAM,KAAK,CAAC,IACjD,OAAOF,GAAG,CAACG,IAAI,KAAK,QAAQ,IAAIH,GAAG,CAACG,IAAI,CAACD,MAAM,KAAK,CAAC,IACrD,EAAEF,GAAG,CAAChB,IAAI,YAAYoB,IAAI,CAAC,EAC7B;QACE,MAAMvB,UAAU,CAAC,KAAK,EAAE;UAAEwB,GAAG,EAAEL;QAAI,CAAC,CAAC;MACzC;MACA,IAAIM,MAAM,CAACC,SAAS,CAACC,cAAc,CAACC,IAAI,CAACV,aAAa,EAAEC,GAAG,CAACC,EAAE,CAAC,EAAE;QAC7D,MAAMpB,UAAU,CAAC,KAAK,EAAE;UAAEwB,GAAG,EAAEL;QAAI,CAAC,CAAC;MACzC;MACAD,aAAa,CAACC,GAAG,CAACC,EAAE,CAAC,GAAG;QACpBE,IAAI,EAAEH,GAAG,CAACG,IAAI;QACdnB,IAAI,EAAEgB,GAAG,CAAChB;MACd,CAAC;IACL;IACAY,OAAO,GAAGU,MAAM,CAACV,OAAO,CAACG,aAAa,CAAC;IACvC,MAAMW,OAAO,CAACC,GAAG,CACbf,OAAO,CAACgB,GAAG,CAAC,OAAO,GAAGZ,GAAG,CAAC,KAAK;MAC3B,IAAIA,GAAG,CAAChB,IAAI,YAAYoB,IAAI,IAAI,CAACJ,GAAG,CAACa,MAAM,EAAE;QACzCb,GAAG,CAACa,MAAM,GAAG,MAAMnB,YAAY,CAACM,GAAG,CAAChB,IAAI,CAAC;QACzCgB,GAAG,CAACE,MAAM,GAAGF,GAAG,CAAChB,IAAI,CAAC8B,IAAI;MAC9B;IACJ,CAAC,CACL,CAAC;IACD,OAAOf,aAAa;EACxB;;EAEA;EACA,IAAI,OAAOJ,WAAW,KAAK,QAAQ,IAAIW,MAAM,CAACS,IAAI,CAACpB,WAAW,CAAC,CAACO,MAAM,KAAK,CAAC,EAAE;IAC1E,OAAOP,WAAW;EACtB;;EAEA;EACA;EACAC,OAAO,GAAGU,MAAM,CAACV,OAAO,CAACD,WAAW,CAAC;EACrC,IAAMqB,aAAa,GAAGpB,OAAO,CAACqB,KAAK,CAAC,CAAC,GAAGjB,GAAG,CAAC,KAAKA,GAAG,CAACa,MAAM,CAAC;EAC5D,IAAIG,aAAa,EAAE;IACf,OAAOrB,WAAW;EACtB;EAEA,MAAMd,UAAU,CAAC,OAAO,EAAE;IAAEG,IAAI,EAAEW;EAAY,CAAC,CAAC;AACpD;;AAEA;AACA;AACA;AACA,OAAO,eAAeuB,iCAAiCA,CACnDC,UAA8D,EAC9DC,6BAAuG,EACzB;EAC9EA,6BAA6B,CAACC,aAAa,GAAGF,UAAU,CAACE,aAAa;EACtE,IAAMC,eAAe,GAAG,MAAMH,UAAU,CAACI,OAAO,CAACC,qBAAqB,CAClEJ,6BACJ,CAAC;EACD,OAAOE,eAAe;AAC1B;;AAEA;AACA;AACA;AACA;AACA,OAAO,eAAeG,wBAAwBA,CAC1CF,OAA4B,EAC5BG,uBAA+E,EAC/EC,qBAA6B,EAC7BC,YAAoB,EACpBC,cAAsB,EACtBR,aAAsB,EACtBS,QAAiB;AACjB;AACJ;AACA;AACA;AACA;AACIpC,YAA2B,EAC7B;EACE,IAAMqC,qBAAqB,GAAG,MAAMrD,yBAAyB,CACzDgD,uBACJ,CAAC;EACD,IAAMM,0BAA0B,GAAGD,qBAAqB,CACnDE,MAAM,CAACC,OAAO,IAAIA,OAAO,CAAClD,IAAI,CAACmD,IAAI,KAAKN,cAAc,CAAC;EAC5D,IAAIO,cAID,GAAG,EAAE;EACRJ,0BAA0B,CAACK,OAAO,CAACH,OAAO,IAAI;IAC1CE,cAAc,CAACE,IAAI,CAAC;MAChBT,cAAc,EAAEK,OAAO,CAAClD,IAAI,CAACmD,IAAI;MACjCpD,MAAM,EAAEmD,OAAO,CAAClD,IAAI,CAACD,MAAM;MAC3BwD,YAAY,EAAE;IAClB,CAAC,CAAC;IACFL,OAAO,CAAClD,IAAI,CAACwD,iBAAiB,CAACH,OAAO,CAACI,GAAG,IAAIL,cAAc,CAACE,IAAI,CAAC;MAC9DT,cAAc,EAAEY,GAAG,CAACZ,cAAc;MAClCU,YAAY,EAAE,KAAK;MACnBxD,MAAM,EAAE0D,GAAG,CAAC1D;IAChB,CAAC,CAAC,CAAC;EACP,CAAC,CAAC;;EAEF;EACA,IAAM2D,YAAY,GAAG,IAAIC,GAAG,CAAS,CAAC;EACtCP,cAAc,GAAGA,cAAc,CAACH,MAAM,CAACQ,GAAG,IAAI;IAC1C,IAAMG,GAAG,GAAGH,GAAG,CAACZ,cAAc,GAAG,IAAI,GAAGY,GAAG,CAAC1D,MAAM,CAAC8D,OAAO;IAC1D,IAAIH,YAAY,CAACI,GAAG,CAACF,GAAG,CAAC,EAAE;MACvB,OAAO,KAAK;IAChB,CAAC,MAAM;MACHF,YAAY,CAACK,GAAG,CAACH,GAAG,CAAC;MACrB,OAAO,IAAI;IACf;EACJ,CAAC,CAAC;;EAEF;EACA,MAAMlC,OAAO,CAACC,GAAG,CACbyB,cAAc,CACTxB,GAAG,CAAC,MAAO6B,GAAG,IAAK;IAChB,IAAMnB,eAAe,GAAG,MAAMC,OAAO,CAACC,qBAAqB,CAAM;MAC7DK,cAAc,EAAEY,GAAG,CAACZ,cAAc;MAClCF,qBAAqB;MACrBC,YAAY;MACZ;AACpB;AACA;AACA;AACA;AACA;MACoBP,aAAa;MACb2B,OAAO,EAAE,CAAC,CAAC;MACXjE,MAAM,EAAE0D,GAAG,CAAC1D,MAAM;MAClB+C,QAAQ;MACRmB,OAAO,EAAErE,YAAY,CAACsE,SAAS,CAAC;IACpC,CAAC,CAAC;IACF,MAAM5B,eAAe,CAAC6B,MAAM,CAAC,CAAC;IAC9B,IAAIV,GAAG,CAACF,YAAY,EAAE;MAClB,MAAM9D,mBAAmB,CAAC,wBAAwB,EAAE;QAChD8C,OAAO;QACPK,YAAY,EAAEA,YAAY;QAC1BC;MACJ,CAAC,CAAC;IACN;EACJ,CAAC,CACT,CAAC;;EAED;EACA,IAAInC,YAAY,EAAE;IACd,IAAM0D,SAAS,GAAGpB,0BAA0B,CAACpB,GAAG,CAACyC,GAAG,IAAI;MACpD,IAAMC,QAAQ,GAAG3E,oBAAoB,CAAC0E,GAAG,CAAC;MAC1CC,QAAQ,CAAChE,QAAQ,GAAG,IAAI;MACxBgE,QAAQ,CAAClE,KAAK,CAACC,GAAG,GAAGhB,GAAG,CAAC,CAAC;MAC1BiF,QAAQ,CAAC9D,IAAI,GAAGrB,cAAc,CAC1BwD,qBAAqB,EACrB0B,GACJ,CAAC;MACD,OAAO;QACHE,QAAQ,EAAEF,GAAG;QACbG,QAAQ,EAAEF;MACd,CAAC;IACL,CAAC,CAAC;IACF,MAAM5B,uBAAuB,CAAC+B,SAAS,CACnCL,SAAS,EACT,mCACJ,CAAC;EACL;AACJ;AAGA,OAAO,SAASM,6BAA6BA,CACzCC,UAAoE,EACtE;EACE,IAAIA,UAAU,CAACC,MAAM,EAAE;IACnB,MAAM/E,UAAU,CACZ,OAAO,EACP;MACI8E,UAAU,EAAEA,UAAU,CAACxB,IAAI;MAC3BU,OAAO,EAAEc,UAAU,CAAC5E,MAAM,CAAC8D;IAC/B,CACJ,CAAC;EACL;AACJ","ignoreList":[]}
|
|
1
|
+
{"version":3,"file":"rx-collection-helper.js","names":["createRevision","flatClone","now","fillObjectWithDefaults","fillPrimaryKey","runAsyncPluginHooks","getAllCollectionDocuments","flatCloneDocWithMeta","overwritable","newRxError","fillObjectDataBeforeInsert","schema","data","jsonSchema","primaryKey","primaryPath","_deleted","_attachments","normalizeInlineAttachments","hashFunction","attachments","entries","Array","isArray","attachmentMap","att","id","length","type","Blob","obj","Object","prototype","hasOwnProperty","call","Promise","all","map","digest","size","keys","allNormalized","every","createRxCollectionStorageInstance","rxDatabase","storageInstanceCreationParams","multiInstance","storageInstance","storage","createStorageInstance","removeCollectionStorages","databaseInternalStorage","databaseInstanceToken","databaseName","collectionName","password","allCollectionMetaDocs","relevantCollectionMetaDocs","filter","metaDoc","name","removeStorages","forEach","push","isCollection","connectedStorages","row","alreadyAdded","Set","key","version","has","add","options","devMode","isDevMode","remove","writeRows","doc","writeDoc","_meta","lwt","_rev","previous","document","bulkWrite","ensureRxCollectionIsNotClosed","collection","closed"],"sources":["../../src/rx-collection-helper.ts"],"sourcesContent":["import type {\r\n HashFunction,\r\n InternalStoreDocType,\r\n RxAttachmentWriteData,\r\n RxCollection,\r\n RxDatabase,\r\n RxDocumentData,\r\n RxJsonSchema,\r\n RxStorage,\r\n RxStorageInstance,\r\n RxStorageInstanceCreationParams\r\n} from './types/index.d.ts';\r\nimport {\r\n createRevision,\r\n flatClone,\r\n now\r\n} from './plugins/utils/index.ts';\r\nimport {\r\n fillObjectWithDefaults,\r\n fillPrimaryKey\r\n} from './rx-schema-helper.ts';\r\nimport type { RxSchema } from './rx-schema.ts';\r\nimport { runAsyncPluginHooks } from './hooks.ts';\r\nimport { getAllCollectionDocuments } from './rx-database-internal-store.ts';\r\nimport { flatCloneDocWithMeta } from './rx-storage-helper.ts';\r\nimport { overwritable } from './overwritable.ts';\r\nimport type { RxCollectionBase } from './rx-collection.ts';\r\nimport { newRxError } from './rx-error.ts';\r\n\r\n/**\r\n * fills in the default data.\r\n * This also clones the data.\r\n */\r\nexport function fillObjectDataBeforeInsert<RxDocType>(\r\n schema: RxSchema<RxDocType>,\r\n data: Partial<RxDocumentData<RxDocType>> | any\r\n): RxDocumentData<RxDocType> {\r\n data = flatClone(data);\r\n data = fillObjectWithDefaults(schema, data);\r\n if (typeof schema.jsonSchema.primaryKey !== 'string') {\r\n data = fillPrimaryKey(\r\n schema.primaryPath,\r\n schema.jsonSchema,\r\n data\r\n );\r\n }\r\n /**\r\n * _meta and _rev are not set here because\r\n * they are always overwritten by the wrapped storage instance\r\n * in getWrappedStorageInstance() before the actual write.\r\n * Skipping them here avoids unnecessary object allocations on the hot path.\r\n *\r\n * _deleted and _attachments still need to be initialized here because\r\n * the wrapped storage does NOT set them, and they are required\r\n * for the document to be valid before the storage write\r\n * (e.g. _attachments is checked during attachment normalization in bulkInsert).\r\n */\r\n if (!('_deleted' in data)) {\r\n data._deleted = false;\r\n }\r\n if (!('_attachments' in data)) {\r\n data._attachments = {};\r\n }\r\n return data;\r\n}\r\n\r\n/**\r\n * Normalizes inline attachment inputs on a document's _attachments.\r\n * Accepts an array of { id, type, data } objects (aligned with putAttachment API)\r\n * and converts to the internal map format { [id]: { type, data, digest, length } }.\r\n * For each entry where data is a Blob and digest is missing,\r\n * computes digest via hashFunction and sets length from Blob.size.\r\n * Already-complete RxAttachmentWriteData entries are left untouched.\r\n */\r\nexport async function normalizeInlineAttachments(\r\n hashFunction: HashFunction,\r\n attachments: Array<{ id: string; type: string; data: Blob; }> | { [attachmentId: string]: any; }\r\n): Promise<{ [attachmentId: string]: RxAttachmentWriteData; }> {\r\n // Guard against null/undefined/non-object values\r\n if (attachments == null || typeof attachments !== 'object') {\r\n throw newRxError('COL24', { data: attachments });\r\n }\r\n\r\n let entries: [string, any][];\r\n // Only accept array format for inline attachments.\r\n // An empty object {} (set by fillObjectDataBeforeInsert) is also valid.\r\n if (Array.isArray(attachments)) {\r\n const attachmentMap: { [attachmentId: string]: any; } = {};\r\n for (const att of attachments) {\r\n if (\r\n !att ||\r\n typeof att.id !== 'string' || att.id.length === 0 ||\r\n typeof att.type !== 'string' || att.type.length === 0 ||\r\n !(att.data instanceof Blob)\r\n ) {\r\n throw newRxError('AT2', { obj: att });\r\n }\r\n if (Object.prototype.hasOwnProperty.call(attachmentMap, att.id)) {\r\n throw newRxError('AT3', { obj: att });\r\n }\r\n attachmentMap[att.id] = {\r\n type: att.type,\r\n data: att.data\r\n };\r\n }\r\n entries = Object.entries(attachmentMap);\r\n await Promise.all(\r\n entries.map(async ([, att]) => {\r\n if (att.data instanceof Blob && !att.digest) {\r\n att.digest = await hashFunction(att.data);\r\n att.length = att.data.size;\r\n }\r\n })\r\n );\r\n return attachmentMap;\r\n }\r\n\r\n // Empty object from fillObjectDataBeforeInsert — pass through\r\n if (typeof attachments === 'object' && Object.keys(attachments).length === 0) {\r\n return attachments;\r\n }\r\n\r\n // Already-normalized map (from internal paths like bulkUpsert's 409 handler)\r\n // where entries already have digest/length — pass through\r\n entries = Object.entries(attachments);\r\n const allNormalized = entries.every(([, att]) => att.digest);\r\n if (allNormalized) {\r\n return attachments;\r\n }\r\n\r\n throw newRxError('COL24', { data: attachments });\r\n}\r\n\r\n/**\r\n * Creates the storage instances that are used internally in the collection\r\n */\r\nexport async function createRxCollectionStorageInstance<RxDocumentType, Internals, InstanceCreationOptions>(\r\n rxDatabase: RxDatabase<{}, Internals, InstanceCreationOptions>,\r\n storageInstanceCreationParams: RxStorageInstanceCreationParams<RxDocumentType, InstanceCreationOptions>\r\n): Promise<RxStorageInstance<RxDocumentType, Internals, InstanceCreationOptions>> {\r\n storageInstanceCreationParams.multiInstance = rxDatabase.multiInstance;\r\n const storageInstance = await rxDatabase.storage.createStorageInstance<RxDocumentType>(\r\n storageInstanceCreationParams\r\n );\r\n return storageInstance;\r\n}\r\n\r\n/**\r\n * Removes the main storage of the collection\r\n * and all connected storages like the ones from the replication meta etc.\r\n */\r\nexport async function removeCollectionStorages(\r\n storage: RxStorage<any, any>,\r\n databaseInternalStorage: RxStorageInstance<InternalStoreDocType<any>, any, any>,\r\n databaseInstanceToken: string,\r\n databaseName: string,\r\n collectionName: string,\r\n multiInstance: boolean,\r\n password?: string,\r\n /**\r\n * If no hash function is provided,\r\n * we assume that the whole internal store is removed anyway\r\n * so we do not have to delete the meta documents.\r\n */\r\n hashFunction?: HashFunction,\r\n) {\r\n const allCollectionMetaDocs = await getAllCollectionDocuments(\r\n databaseInternalStorage\r\n );\r\n const relevantCollectionMetaDocs = allCollectionMetaDocs\r\n .filter(metaDoc => metaDoc.data.name === collectionName);\r\n let removeStorages: {\r\n collectionName: string;\r\n schema: RxJsonSchema<any>;\r\n isCollection: boolean;\r\n }[] = [];\r\n relevantCollectionMetaDocs.forEach(metaDoc => {\r\n removeStorages.push({\r\n collectionName: metaDoc.data.name,\r\n schema: metaDoc.data.schema,\r\n isCollection: true\r\n });\r\n metaDoc.data.connectedStorages.forEach(row => removeStorages.push({\r\n collectionName: row.collectionName,\r\n isCollection: false,\r\n schema: row.schema\r\n }));\r\n });\r\n\r\n // ensure uniqueness\r\n const alreadyAdded = new Set<string>();\r\n removeStorages = removeStorages.filter(row => {\r\n const key = row.collectionName + '||' + row.schema.version;\r\n if (alreadyAdded.has(key)) {\r\n return false;\r\n } else {\r\n alreadyAdded.add(key);\r\n return true;\r\n }\r\n });\r\n\r\n // remove all the storages\r\n await Promise.all(\r\n removeStorages\r\n .map(async (row) => {\r\n const storageInstance = await storage.createStorageInstance<any>({\r\n collectionName: row.collectionName,\r\n databaseInstanceToken,\r\n databaseName,\r\n /**\r\n * multiInstance must be set to true if multiInstance\r\n * was true on the database\r\n * so that the storageInstance can inform other\r\n * instances about being removed.\r\n */\r\n multiInstance,\r\n options: {},\r\n schema: row.schema,\r\n password,\r\n devMode: overwritable.isDevMode()\r\n });\r\n await storageInstance.remove();\r\n if (row.isCollection) {\r\n await runAsyncPluginHooks('postRemoveRxCollection', {\r\n storage,\r\n databaseName: databaseName,\r\n collectionName\r\n });\r\n }\r\n })\r\n );\r\n\r\n // remove the meta documents\r\n if (hashFunction) {\r\n const writeRows = relevantCollectionMetaDocs.map(doc => {\r\n const writeDoc = flatCloneDocWithMeta(doc);\r\n writeDoc._deleted = true;\r\n writeDoc._meta.lwt = now();\r\n writeDoc._rev = createRevision(\r\n databaseInstanceToken,\r\n doc\r\n );\r\n return {\r\n previous: doc,\r\n document: writeDoc\r\n };\r\n });\r\n await databaseInternalStorage.bulkWrite(\r\n writeRows,\r\n 'rx-database-remove-collection-all'\r\n );\r\n }\r\n}\r\n\r\n\r\nexport function ensureRxCollectionIsNotClosed(\r\n collection: RxCollection | RxCollectionBase<any, any, any, any, any>\r\n) {\r\n if (collection.closed) {\r\n throw newRxError(\r\n 'COL21',\r\n {\r\n collection: collection.name,\r\n version: collection.schema.version\r\n }\r\n );\r\n }\r\n}\r\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -9,7 +9,7 @@ import { createQueryCache, defaultCacheReplacementPolicy } from "./query-cache.j
|
|
|
9
9
|
import { createChangeEventBuffer } from "./change-event-buffer.js";
|
|
10
10
|
import { runAsyncPluginHooks, runPluginHooks } from "./hooks.js";
|
|
11
11
|
import { createNewRxDocument, getRxDocumentConstructor } from "./rx-document-prototype-merge.js";
|
|
12
|
-
import { getWrappedStorageInstance, getWrittenDocumentsFromBulkWriteResponse, throwIfIsStorageWriteError } from "./rx-storage-helper.js";
|
|
12
|
+
import { getWrappedStorageInstance, getWrittenDocumentsFromBulkWriteResponse, throwIfIsStorageWriteError, RX_COLLECTION_BULK_INSERT_CONTEXT } from "./rx-storage-helper.js";
|
|
13
13
|
import { IncrementalWriteQueue } from "./incremental-write.js";
|
|
14
14
|
import { beforeDocumentUpdateWrite } from "./rx-document.js";
|
|
15
15
|
import { overwritable } from "./overwritable.js";
|
|
@@ -75,15 +75,19 @@ export var RxCollectionBase = /*#__PURE__*/function () {
|
|
|
75
75
|
* we retry after some times to account for this.
|
|
76
76
|
*/
|
|
77
77
|
var count = 0;
|
|
78
|
-
|
|
78
|
+
var startTime = 0;
|
|
79
|
+
while (count < 35 && OPEN_COLLECTIONS.size >= NON_PREMIUM_COLLECTION_LIMIT) {
|
|
80
|
+
startTime = Date.now();
|
|
79
81
|
await this.promiseWait(30);
|
|
80
82
|
count++;
|
|
81
83
|
}
|
|
82
84
|
if (OPEN_COLLECTIONS.size > NON_PREMIUM_COLLECTION_LIMIT) {
|
|
85
|
+
var timeInRetry = Date.now() - startTime;
|
|
83
86
|
throw newRxError('COL23', {
|
|
84
87
|
database: this.database.name,
|
|
85
88
|
collection: this.name,
|
|
86
89
|
args: {
|
|
90
|
+
timeInRetry,
|
|
87
91
|
existing: Array.from(OPEN_COLLECTIONS.values()).map(c => ({
|
|
88
92
|
db: c.database ? c.database.name : '',
|
|
89
93
|
c: c.name
|
|
@@ -103,7 +107,7 @@ export var RxCollectionBase = /*#__PURE__*/function () {
|
|
|
103
107
|
OPEN_COLLECTIONS.add(this);
|
|
104
108
|
}
|
|
105
109
|
this.storageInstance = getWrappedStorageInstance(this.database, this.internalStorageInstance, this.schema.jsonSchema);
|
|
106
|
-
this.incrementalWriteQueue = new IncrementalWriteQueue(this.storageInstance, this.schema.primaryPath, (newData, oldData) => beforeDocumentUpdateWrite(this, newData, oldData), result => this._runHooks('post', 'save', result));
|
|
110
|
+
this.incrementalWriteQueue = new IncrementalWriteQueue(this.storageInstance, this.schema.primaryPath, (newData, oldData) => beforeDocumentUpdateWrite(this, newData, oldData), result => this._runHooks('post', 'save', result, this._docCache.getCachedRxDocument(result)));
|
|
107
111
|
this.$ = this.eventBulks$.pipe(mergeMap(changeEventBulk => rxChangeEventBulkToRxChangeEvents(changeEventBulk)));
|
|
108
112
|
this.checkpoint$ = this.eventBulks$.pipe(map(changeEventBulk => changeEventBulk.checkpoint));
|
|
109
113
|
this._changeEventBuffer = createChangeEventBuffer(this.asRxCollection);
|
|
@@ -234,8 +238,19 @@ export var RxCollectionBase = /*#__PURE__*/function () {
|
|
|
234
238
|
}
|
|
235
239
|
}
|
|
236
240
|
if (ids.size !== docsData.length) {
|
|
241
|
+
var duplicateIdSet = new Set();
|
|
242
|
+
var seenIds = new Set();
|
|
243
|
+
for (var row of insertRows) {
|
|
244
|
+
var id = row.document[primaryPath];
|
|
245
|
+
if (seenIds.has(id)) {
|
|
246
|
+
duplicateIdSet.add(id);
|
|
247
|
+
} else {
|
|
248
|
+
seenIds.add(id);
|
|
249
|
+
}
|
|
250
|
+
}
|
|
237
251
|
throw newRxError('COL22', {
|
|
238
252
|
collection: this.name,
|
|
253
|
+
duplicateIds: Array.from(duplicateIdSet),
|
|
239
254
|
args: {
|
|
240
255
|
documents: docsData
|
|
241
256
|
}
|
|
@@ -249,7 +264,7 @@ export var RxCollectionBase = /*#__PURE__*/function () {
|
|
|
249
264
|
if (this.schema.jsonSchema.attachments) {
|
|
250
265
|
var normalizePromises = [];
|
|
251
266
|
var _loop = async function () {
|
|
252
|
-
var doc =
|
|
267
|
+
var doc = _row.document;
|
|
253
268
|
var atts = doc._attachments;
|
|
254
269
|
if (atts == null || Object.keys(atts).length === 0) {
|
|
255
270
|
doc._attachments = {};
|
|
@@ -259,14 +274,14 @@ export var RxCollectionBase = /*#__PURE__*/function () {
|
|
|
259
274
|
}));
|
|
260
275
|
}
|
|
261
276
|
};
|
|
262
|
-
for (var
|
|
277
|
+
for (var _row of insertRows) {
|
|
263
278
|
await _loop();
|
|
264
279
|
}
|
|
265
280
|
if (normalizePromises.length > 0) {
|
|
266
281
|
await Promise.all(normalizePromises);
|
|
267
282
|
}
|
|
268
283
|
}
|
|
269
|
-
var results = await this.storageInstance.bulkWrite(insertRows,
|
|
284
|
+
var results = await this.storageInstance.bulkWrite(insertRows, RX_COLLECTION_BULK_INSERT_CONTEXT);
|
|
270
285
|
|
|
271
286
|
/**
|
|
272
287
|
* Often the user does not need to access the RxDocuments of the bulkInsert() call.
|
|
@@ -828,7 +843,20 @@ function _incrementalUpsertEnsureRxDocumentExists(rxCollection, primary, json) {
|
|
|
828
843
|
return rxCollection.insert(json).then(newDoc => ({
|
|
829
844
|
doc: newDoc,
|
|
830
845
|
inserted: true
|
|
831
|
-
}))
|
|
846
|
+
})).catch(err => {
|
|
847
|
+
/**
|
|
848
|
+
* If the insert fails with a conflict error,
|
|
849
|
+
* it means another concurrent operation already
|
|
850
|
+
* inserted a document with the same primary key
|
|
851
|
+
* between our findOne() and insert() calls.
|
|
852
|
+
* Re-run the whole function which will now find the
|
|
853
|
+
* existing document via cache or query.
|
|
854
|
+
*/
|
|
855
|
+
if (err.code === 'CONFLICT') {
|
|
856
|
+
return _incrementalUpsertEnsureRxDocumentExists(rxCollection, primary, json);
|
|
857
|
+
}
|
|
858
|
+
throw err;
|
|
859
|
+
});
|
|
832
860
|
} else {
|
|
833
861
|
return {
|
|
834
862
|
doc,
|