@enbox/dwn-sdk-js 0.0.1 → 0.0.3
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/README.md +52 -301
- package/dist/bundles/dwn.js +19 -21
- package/dist/esm/generated/precompiled-validators.js +2764 -1773
- package/dist/esm/generated/precompiled-validators.js.map +1 -1
- package/dist/esm/src/core/dwn-error.js +27 -3
- package/dist/esm/src/core/dwn-error.js.map +1 -1
- package/dist/esm/src/core/message.js.map +1 -1
- package/dist/esm/src/core/messages-grant-authorization.js +17 -6
- package/dist/esm/src/core/messages-grant-authorization.js.map +1 -1
- package/dist/esm/src/core/protocol-authorization.js +245 -69
- package/dist/esm/src/core/protocol-authorization.js.map +1 -1
- package/dist/esm/src/core/resumable-task-manager.js +4 -4
- package/dist/esm/src/core/resumable-task-manager.js.map +1 -1
- package/dist/esm/src/dwn.js +10 -8
- package/dist/esm/src/dwn.js.map +1 -1
- package/dist/esm/src/enums/dwn-interface-method.js +4 -2
- package/dist/esm/src/enums/dwn-interface-method.js.map +1 -1
- package/dist/esm/src/event-stream/event-emitter-stream.js.map +1 -0
- package/dist/esm/src/handlers/messages-subscribe.js +1 -1
- package/dist/esm/src/handlers/messages-subscribe.js.map +1 -1
- package/dist/esm/src/handlers/messages-sync.js +116 -0
- package/dist/esm/src/handlers/messages-sync.js.map +1 -0
- package/dist/esm/src/handlers/protocols-configure.js +149 -16
- package/dist/esm/src/handlers/protocols-configure.js.map +1 -1
- package/dist/esm/src/handlers/protocols-query.js +2 -2
- package/dist/esm/src/handlers/protocols-query.js.map +1 -1
- package/dist/esm/src/handlers/records-count.js +143 -0
- package/dist/esm/src/handlers/records-count.js.map +1 -0
- package/dist/esm/src/handlers/records-query.js +4 -0
- package/dist/esm/src/handlers/records-query.js.map +1 -1
- package/dist/esm/src/handlers/records-read.js +4 -6
- package/dist/esm/src/handlers/records-read.js.map +1 -1
- package/dist/esm/src/handlers/records-write.js +17 -18
- package/dist/esm/src/handlers/records-write.js.map +1 -1
- package/dist/esm/src/index.js +9 -5
- package/dist/esm/src/index.js.map +1 -1
- package/dist/esm/src/interfaces/messages-read.js +2 -7
- package/dist/esm/src/interfaces/messages-read.js.map +1 -1
- package/dist/esm/src/interfaces/messages-subscribe.js +1 -0
- package/dist/esm/src/interfaces/messages-subscribe.js.map +1 -1
- package/dist/esm/src/interfaces/{messages-query.js → messages-sync.js} +11 -12
- package/dist/esm/src/interfaces/messages-sync.js.map +1 -0
- package/dist/esm/src/interfaces/protocols-configure.js +153 -30
- package/dist/esm/src/interfaces/protocols-configure.js.map +1 -1
- package/dist/esm/src/interfaces/protocols-query.js +1 -0
- package/dist/esm/src/interfaces/protocols-query.js.map +1 -1
- package/dist/esm/src/interfaces/records-count.js +91 -0
- package/dist/esm/src/interfaces/records-count.js.map +1 -0
- package/dist/esm/src/interfaces/records-read.js +15 -1
- package/dist/esm/src/interfaces/records-read.js.map +1 -1
- package/dist/esm/src/interfaces/records-write.js +64 -15
- package/dist/esm/src/interfaces/records-write.js.map +1 -1
- package/dist/esm/src/jose/algorithms/signing/ed25519.js.map +1 -1
- package/dist/esm/src/jose/algorithms/signing/signature-algorithms.js.map +1 -1
- package/dist/esm/src/jose/jws/general/builder.js.map +1 -1
- package/dist/esm/src/jose/jws/general/verifier.js.map +1 -1
- package/dist/esm/src/protocols/permission-grant.js +30 -0
- package/dist/esm/src/protocols/permission-grant.js.map +1 -1
- package/dist/esm/src/protocols/permission-request.js +24 -0
- package/dist/esm/src/protocols/permission-request.js.map +1 -1
- package/dist/esm/src/protocols/permissions.js +1 -1
- package/dist/esm/src/protocols/permissions.js.map +1 -1
- package/dist/esm/src/schema-validator.js +0 -1
- package/dist/esm/src/schema-validator.js.map +1 -1
- package/dist/esm/src/smt/smt-store-level.js +125 -0
- package/dist/esm/src/smt/smt-store-level.js.map +1 -0
- package/dist/esm/src/smt/smt-store-memory.js +67 -0
- package/dist/esm/src/smt/smt-store-memory.js.map +1 -0
- package/dist/esm/src/smt/smt-utils.js +146 -0
- package/dist/esm/src/smt/smt-utils.js.map +1 -0
- package/dist/esm/src/smt/sparse-merkle-tree.js +622 -0
- package/dist/esm/src/smt/sparse-merkle-tree.js.map +1 -0
- package/dist/esm/src/state-index/state-index-level.js +228 -0
- package/dist/esm/src/state-index/state-index-level.js.map +1 -0
- package/dist/esm/src/store/data-store-level.js +6 -6
- package/dist/esm/src/store/data-store-level.js.map +1 -1
- package/dist/esm/src/store/index-level.js +375 -17
- package/dist/esm/src/store/index-level.js.map +1 -1
- package/dist/esm/src/store/message-store-level.js +56 -0
- package/dist/esm/src/store/message-store-level.js.map +1 -1
- package/dist/esm/src/store/storage-controller.js +19 -16
- package/dist/esm/src/store/storage-controller.js.map +1 -1
- package/dist/esm/src/types/encryption-types.js +2 -0
- package/dist/esm/src/types/encryption-types.js.map +1 -0
- package/dist/esm/src/types/message-types.js.map +1 -1
- package/dist/esm/src/types/protocols-types.js +0 -2
- package/dist/esm/src/types/protocols-types.js.map +1 -1
- package/dist/esm/src/types/records-types.js +2 -0
- package/dist/esm/src/types/records-types.js.map +1 -1
- package/dist/esm/src/types/smt-types.js +5 -0
- package/dist/esm/src/types/smt-types.js.map +1 -0
- package/dist/esm/src/types/state-index.js +2 -0
- package/dist/esm/src/types/state-index.js.map +1 -0
- package/dist/esm/src/utils/cid.js +2 -1
- package/dist/esm/src/utils/cid.js.map +1 -1
- package/dist/esm/src/utils/data-stream.js +84 -29
- package/dist/esm/src/utils/data-stream.js.map +1 -1
- package/dist/esm/src/utils/encryption.js +22 -31
- package/dist/esm/src/utils/encryption.js.map +1 -1
- package/dist/esm/src/utils/hd-key.js +3 -3
- package/dist/esm/src/utils/hd-key.js.map +1 -1
- package/dist/esm/src/utils/jws.js +4 -4
- package/dist/esm/src/utils/jws.js.map +1 -1
- package/dist/esm/src/utils/private-key-signer.js +4 -3
- package/dist/esm/src/utils/private-key-signer.js.map +1 -1
- package/dist/esm/src/utils/protocols.js +82 -9
- package/dist/esm/src/utils/protocols.js.map +1 -1
- package/dist/esm/src/utils/records.js +82 -26
- package/dist/esm/src/utils/records.js.map +1 -1
- package/dist/esm/src/utils/secp256k1.js +4 -3
- package/dist/esm/src/utils/secp256k1.js.map +1 -1
- package/dist/esm/src/utils/secp256r1.js +3 -2
- package/dist/esm/src/utils/secp256r1.js.map +1 -1
- package/dist/esm/src/utils/time.js +1 -1
- package/dist/esm/src/utils/url.js +1 -1
- package/dist/esm/src/utils/url.js.map +1 -1
- package/dist/esm/tests/core/auth.spec.js +2 -2
- package/dist/esm/tests/core/auth.spec.js.map +1 -1
- package/dist/esm/tests/core/message-reply.spec.js +3 -3
- package/dist/esm/tests/core/message-reply.spec.js.map +1 -1
- package/dist/esm/tests/core/message.spec.js +13 -13
- package/dist/esm/tests/core/message.spec.js.map +1 -1
- package/dist/esm/tests/core/protocol-authorization.spec.js +3 -3
- package/dist/esm/tests/core/protocol-authorization.spec.js.map +1 -1
- package/dist/esm/tests/dwn.spec.js +27 -37
- package/dist/esm/tests/dwn.spec.js.map +1 -1
- package/dist/esm/tests/{event-log → event-stream}/event-emitter-stream.spec.js +14 -15
- package/dist/esm/tests/event-stream/event-emitter-stream.spec.js.map +1 -0
- package/dist/esm/tests/{event-log → event-stream}/event-stream.spec.js +13 -15
- package/dist/esm/tests/event-stream/event-stream.spec.js.map +1 -0
- package/dist/esm/tests/features/author-delegated-grant.spec.js +281 -135
- package/dist/esm/tests/features/author-delegated-grant.spec.js.map +1 -1
- package/dist/esm/tests/features/owner-delegated-grant.spec.js +57 -59
- package/dist/esm/tests/features/owner-delegated-grant.spec.js.map +1 -1
- package/dist/esm/tests/features/owner-signature.spec.js +32 -34
- package/dist/esm/tests/features/owner-signature.spec.js.map +1 -1
- package/dist/esm/tests/features/permissions.spec.js +73 -95
- package/dist/esm/tests/features/permissions.spec.js.map +1 -1
- package/dist/esm/tests/features/protocol-composition.spec.js +1645 -0
- package/dist/esm/tests/features/protocol-composition.spec.js.map +1 -0
- package/dist/esm/tests/features/protocol-create-action.spec.js +25 -27
- package/dist/esm/tests/features/protocol-create-action.spec.js.map +1 -1
- package/dist/esm/tests/features/protocol-delete-action.spec.js +42 -44
- package/dist/esm/tests/features/protocol-delete-action.spec.js.map +1 -1
- package/dist/esm/tests/features/protocol-update-action.spec.js +53 -55
- package/dist/esm/tests/features/protocol-update-action.spec.js.map +1 -1
- package/dist/esm/tests/features/records-prune.spec.js +126 -100
- package/dist/esm/tests/features/records-prune.spec.js.map +1 -1
- package/dist/esm/tests/features/records-tags.spec.js +272 -272
- package/dist/esm/tests/features/records-tags.spec.js.map +1 -1
- package/dist/esm/tests/features/resumable-tasks.spec.js +35 -37
- package/dist/esm/tests/features/resumable-tasks.spec.js.map +1 -1
- package/dist/esm/tests/handlers/messages-read.spec.js +112 -112
- package/dist/esm/tests/handlers/messages-read.spec.js.map +1 -1
- package/dist/esm/tests/handlers/messages-subscribe.spec.js +78 -76
- package/dist/esm/tests/handlers/messages-subscribe.spec.js.map +1 -1
- package/dist/esm/tests/handlers/messages-sync.spec.js +528 -0
- package/dist/esm/tests/handlers/messages-sync.spec.js.map +1 -0
- package/dist/esm/tests/handlers/protocols-configure.spec.js +545 -152
- package/dist/esm/tests/handlers/protocols-configure.spec.js.map +1 -1
- package/dist/esm/tests/handlers/protocols-query.spec.js +70 -72
- package/dist/esm/tests/handlers/protocols-query.spec.js.map +1 -1
- package/dist/esm/tests/handlers/records-count.spec.js +313 -0
- package/dist/esm/tests/handlers/records-count.spec.js.map +1 -0
- package/dist/esm/tests/handlers/records-delete.spec.js +106 -109
- package/dist/esm/tests/handlers/records-delete.spec.js.map +1 -1
- package/dist/esm/tests/handlers/records-query.spec.js +863 -463
- package/dist/esm/tests/handlers/records-query.spec.js.map +1 -1
- package/dist/esm/tests/handlers/records-read.spec.js +439 -209
- package/dist/esm/tests/handlers/records-read.spec.js.map +1 -1
- package/dist/esm/tests/handlers/records-subscribe.spec.js +292 -97
- package/dist/esm/tests/handlers/records-subscribe.spec.js.map +1 -1
- package/dist/esm/tests/handlers/records-write.spec.js +481 -483
- package/dist/esm/tests/handlers/records-write.spec.js.map +1 -1
- package/dist/esm/tests/interfaces/messages-get.spec.js +31 -11
- package/dist/esm/tests/interfaces/messages-get.spec.js.map +1 -1
- package/dist/esm/tests/interfaces/messages-subscribe.spec.js +5 -5
- package/dist/esm/tests/interfaces/messages-subscribe.spec.js.map +1 -1
- package/dist/esm/tests/interfaces/protocols-configure.spec.js +64 -134
- package/dist/esm/tests/interfaces/protocols-configure.spec.js.map +1 -1
- package/dist/esm/tests/interfaces/protocols-query.spec.js +4 -6
- package/dist/esm/tests/interfaces/protocols-query.spec.js.map +1 -1
- package/dist/esm/tests/interfaces/records-delete.spec.js +3 -5
- package/dist/esm/tests/interfaces/records-delete.spec.js.map +1 -1
- package/dist/esm/tests/interfaces/records-query.spec.js +9 -11
- package/dist/esm/tests/interfaces/records-query.spec.js.map +1 -1
- package/dist/esm/tests/interfaces/records-read.spec.js +76 -7
- package/dist/esm/tests/interfaces/records-read.spec.js.map +1 -1
- package/dist/esm/tests/interfaces/records-subscribe.spec.js +7 -9
- package/dist/esm/tests/interfaces/records-subscribe.spec.js.map +1 -1
- package/dist/esm/tests/interfaces/records-write.spec.js +244 -48
- package/dist/esm/tests/interfaces/records-write.spec.js.map +1 -1
- package/dist/esm/tests/jose/jws/general.spec.js +15 -18
- package/dist/esm/tests/jose/jws/general.spec.js.map +1 -1
- package/dist/esm/tests/protocols/permission-grant.spec.js +114 -0
- package/dist/esm/tests/protocols/permission-grant.spec.js.map +1 -0
- package/dist/esm/tests/protocols/permission-request.spec.js +43 -7
- package/dist/esm/tests/protocols/permission-request.spec.js.map +1 -1
- package/dist/esm/tests/protocols/permissions.spec.js +9 -11
- package/dist/esm/tests/protocols/permissions.spec.js.map +1 -1
- package/dist/esm/tests/scenarios/aggregator.spec.js +90 -92
- package/dist/esm/tests/scenarios/aggregator.spec.js.map +1 -1
- package/dist/esm/tests/scenarios/deleted-record.spec.js +17 -19
- package/dist/esm/tests/scenarios/deleted-record.spec.js.map +1 -1
- package/dist/esm/tests/scenarios/end-to-end-tests.spec.js +27 -29
- package/dist/esm/tests/scenarios/end-to-end-tests.spec.js.map +1 -1
- package/dist/esm/tests/scenarios/nested-roles.spec.js +37 -39
- package/dist/esm/tests/scenarios/nested-roles.spec.js.map +1 -1
- package/dist/esm/tests/scenarios/subscriptions.spec.js +163 -163
- package/dist/esm/tests/scenarios/subscriptions.spec.js.map +1 -1
- package/dist/esm/tests/smt/smt-store-level.spec.js +143 -0
- package/dist/esm/tests/smt/smt-store-level.spec.js.map +1 -0
- package/dist/esm/tests/smt/sparse-merkle-tree.spec.js +741 -0
- package/dist/esm/tests/smt/sparse-merkle-tree.spec.js.map +1 -0
- package/dist/esm/tests/state-index/state-index-level.spec.js +254 -0
- package/dist/esm/tests/state-index/state-index-level.spec.js.map +1 -0
- package/dist/esm/tests/store/blockstore-level.spec.js +136 -0
- package/dist/esm/tests/store/blockstore-level.spec.js.map +1 -0
- package/dist/esm/tests/store/blockstore-mock.spec.js +29 -28
- package/dist/esm/tests/store/blockstore-mock.spec.js.map +1 -1
- package/dist/esm/tests/store/data-store-level.spec.js +23 -25
- package/dist/esm/tests/store/data-store-level.spec.js.map +1 -1
- package/dist/esm/tests/store/index-level.spec.js +544 -194
- package/dist/esm/tests/store/index-level.spec.js.map +1 -1
- package/dist/esm/tests/store/message-store-level.spec.js +4 -4
- package/dist/esm/tests/store/message-store-level.spec.js.map +1 -1
- package/dist/esm/tests/store/message-store.spec.js +147 -73
- package/dist/esm/tests/store/message-store.spec.js.map +1 -1
- package/dist/esm/tests/store-dependent-tests.spec.js +1 -0
- package/dist/esm/tests/store-dependent-tests.spec.js.map +1 -1
- package/dist/esm/tests/test-stores.js +5 -5
- package/dist/esm/tests/test-stores.js.map +1 -1
- package/dist/esm/tests/test-suite.js +9 -8
- package/dist/esm/tests/test-suite.js.map +1 -1
- package/dist/esm/tests/utils/cid.spec.js +8 -11
- package/dist/esm/tests/utils/cid.spec.js.map +1 -1
- package/dist/esm/tests/utils/data-stream.spec.js +167 -13
- package/dist/esm/tests/utils/data-stream.spec.js.map +1 -1
- package/dist/esm/tests/utils/encryption-callbacks.spec.js +233 -0
- package/dist/esm/tests/utils/encryption-callbacks.spec.js.map +1 -0
- package/dist/esm/tests/utils/encryption.spec.js +34 -85
- package/dist/esm/tests/utils/encryption.spec.js.map +1 -1
- package/dist/esm/tests/utils/filters.spec.js +67 -69
- package/dist/esm/tests/utils/filters.spec.js.map +1 -1
- package/dist/esm/tests/utils/hd-key.spec.js +3 -3
- package/dist/esm/tests/utils/hd-key.spec.js.map +1 -1
- package/dist/esm/tests/utils/jws.spec.js +54 -3
- package/dist/esm/tests/utils/jws.spec.js.map +1 -1
- package/dist/esm/tests/utils/memory-cache.spec.js +6 -9
- package/dist/esm/tests/utils/memory-cache.spec.js.map +1 -1
- package/dist/esm/tests/utils/messages.spec.js +63 -29
- package/dist/esm/tests/utils/messages.spec.js.map +1 -1
- package/dist/esm/tests/utils/object.spec.js +3 -3
- package/dist/esm/tests/utils/object.spec.js.map +1 -1
- package/dist/esm/tests/utils/poller.js +1 -1
- package/dist/esm/tests/utils/poller.js.map +1 -1
- package/dist/esm/tests/utils/private-key-signer.spec.js +6 -6
- package/dist/esm/tests/utils/private-key-signer.spec.js.map +1 -1
- package/dist/esm/tests/utils/records.spec.js +37 -5
- package/dist/esm/tests/utils/records.spec.js.map +1 -1
- package/dist/esm/tests/utils/secp256k1.spec.js +7 -7
- package/dist/esm/tests/utils/secp256k1.spec.js.map +1 -1
- package/dist/esm/tests/utils/secp256r1.spec.js +7 -7
- package/dist/esm/tests/utils/secp256r1.spec.js.map +1 -1
- package/dist/esm/tests/utils/test-data-generator.js +47 -28
- package/dist/esm/tests/utils/test-data-generator.js.map +1 -1
- package/dist/esm/tests/utils/time.spec.js +7 -7
- package/dist/esm/tests/utils/time.spec.js.map +1 -1
- package/dist/esm/tests/utils/url.spec.js +25 -27
- package/dist/esm/tests/utils/url.spec.js.map +1 -1
- package/dist/esm/tests/validation/json-schemas/definitions.spec.js +4 -4
- package/dist/esm/tests/validation/json-schemas/definitions.spec.js.map +1 -1
- package/dist/esm/tests/validation/json-schemas/jwk/general-jwk.spec.js +15 -3
- package/dist/esm/tests/validation/json-schemas/jwk/general-jwk.spec.js.map +1 -1
- package/dist/esm/tests/validation/json-schemas/jwk/public-jwk.spec.js +8 -8
- package/dist/esm/tests/validation/json-schemas/jwk/public-jwk.spec.js.map +1 -1
- package/dist/esm/tests/validation/json-schemas/jwk-verification-method.spec.js +8 -18
- package/dist/esm/tests/validation/json-schemas/jwk-verification-method.spec.js.map +1 -1
- package/dist/esm/tests/validation/json-schemas/protocols/protocols-configure.spec.js +3 -3
- package/dist/esm/tests/validation/json-schemas/protocols/protocols-configure.spec.js.map +1 -1
- package/dist/esm/tests/validation/json-schemas/records/records-query.spec.js +9 -9
- package/dist/esm/tests/validation/json-schemas/records/records-query.spec.js.map +1 -1
- package/dist/esm/tests/validation/json-schemas/records/records-read.spec.js +106 -0
- package/dist/esm/tests/validation/json-schemas/records/records-read.spec.js.map +1 -0
- package/dist/esm/tests/validation/json-schemas/records/records-write.spec.js +18 -18
- package/dist/esm/tests/validation/json-schemas/records/records-write.spec.js.map +1 -1
- package/dist/esm/tests/vectors/protocol-definitions/email.json +1 -1
- package/dist/esm/tests/vectors/protocol-definitions/friend-role.json +2 -4
- package/dist/esm/tests/vectors/protocol-definitions/slack.json +2 -6
- package/dist/esm/tests/vectors/protocol-definitions/thread-role.json +2 -6
- package/dist/types/generated/precompiled-validators.d.ts +82 -64
- package/dist/types/generated/precompiled-validators.d.ts.map +1 -1
- package/dist/types/src/core/dwn-error.d.ts +27 -3
- package/dist/types/src/core/dwn-error.d.ts.map +1 -1
- package/dist/types/src/core/message-reply.d.ts +1 -1
- package/dist/types/src/core/message.d.ts +3 -3
- package/dist/types/src/core/message.d.ts.map +1 -1
- package/dist/types/src/core/messages-grant-authorization.d.ts +4 -4
- package/dist/types/src/core/messages-grant-authorization.d.ts.map +1 -1
- package/dist/types/src/core/protocol-authorization.d.ts +43 -2
- package/dist/types/src/core/protocol-authorization.d.ts.map +1 -1
- package/dist/types/src/core/records-grant-authorization.d.ts +2 -2
- package/dist/types/src/core/records-grant-authorization.d.ts.map +1 -1
- package/dist/types/src/core/resumable-task-manager.d.ts +1 -0
- package/dist/types/src/core/resumable-task-manager.d.ts.map +1 -1
- package/dist/types/src/dwn.d.ts +8 -8
- package/dist/types/src/dwn.d.ts.map +1 -1
- package/dist/types/src/enums/dwn-interface-method.d.ts +5 -3
- package/dist/types/src/enums/dwn-interface-method.d.ts.map +1 -1
- package/dist/types/src/event-stream/event-emitter-stream.d.ts.map +1 -0
- package/dist/types/src/handlers/messages-sync.d.ts +21 -0
- package/dist/types/src/handlers/messages-sync.d.ts.map +1 -0
- package/dist/types/src/handlers/protocols-configure.d.ts +24 -4
- package/dist/types/src/handlers/protocols-configure.d.ts.map +1 -1
- package/dist/types/src/handlers/protocols-query.d.ts.map +1 -1
- package/dist/types/src/handlers/records-count.d.ts +43 -0
- package/dist/types/src/handlers/records-count.d.ts.map +1 -0
- package/dist/types/src/handlers/records-query.d.ts.map +1 -1
- package/dist/types/src/handlers/records-read.d.ts.map +1 -1
- package/dist/types/src/handlers/records-write.d.ts +5 -5
- package/dist/types/src/handlers/records-write.d.ts.map +1 -1
- package/dist/types/src/index.d.ts +72 -37
- package/dist/types/src/index.d.ts.map +1 -1
- package/dist/types/src/interfaces/messages-read.d.ts +2 -2
- package/dist/types/src/interfaces/messages-read.d.ts.map +1 -1
- package/dist/types/src/interfaces/messages-subscribe.d.ts +2 -2
- package/dist/types/src/interfaces/messages-subscribe.d.ts.map +1 -1
- package/dist/types/src/interfaces/messages-sync.d.ts +16 -0
- package/dist/types/src/interfaces/messages-sync.d.ts.map +1 -0
- package/dist/types/src/interfaces/protocols-configure.d.ts +22 -2
- package/dist/types/src/interfaces/protocols-configure.d.ts.map +1 -1
- package/dist/types/src/interfaces/protocols-query.d.ts +2 -2
- package/dist/types/src/interfaces/protocols-query.d.ts.map +1 -1
- package/dist/types/src/interfaces/records-count.d.ts +27 -0
- package/dist/types/src/interfaces/records-count.d.ts.map +1 -0
- package/dist/types/src/interfaces/records-delete.d.ts +2 -2
- package/dist/types/src/interfaces/records-delete.d.ts.map +1 -1
- package/dist/types/src/interfaces/records-query.d.ts +2 -2
- package/dist/types/src/interfaces/records-query.d.ts.map +1 -1
- package/dist/types/src/interfaces/records-read.d.ts +4 -2
- package/dist/types/src/interfaces/records-read.d.ts.map +1 -1
- package/dist/types/src/interfaces/records-subscribe.d.ts +2 -2
- package/dist/types/src/interfaces/records-subscribe.d.ts.map +1 -1
- package/dist/types/src/interfaces/records-write.d.ts +37 -15
- package/dist/types/src/interfaces/records-write.d.ts.map +1 -1
- package/dist/types/src/jose/algorithms/signing/ed25519.d.ts.map +1 -1
- package/dist/types/src/jose/algorithms/signing/signature-algorithms.d.ts +5 -1
- package/dist/types/src/jose/algorithms/signing/signature-algorithms.d.ts.map +1 -1
- package/dist/types/src/jose/jws/general/builder.d.ts +3 -3
- package/dist/types/src/jose/jws/general/builder.d.ts.map +1 -1
- package/dist/types/src/protocols/permission-grant.d.ts +11 -0
- package/dist/types/src/protocols/permission-grant.d.ts.map +1 -1
- package/dist/types/src/protocols/permission-request.d.ts +11 -0
- package/dist/types/src/protocols/permission-request.d.ts.map +1 -1
- package/dist/types/src/protocols/permissions.d.ts +4 -4
- package/dist/types/src/protocols/permissions.d.ts.map +1 -1
- package/dist/types/src/schema-validator.d.ts +1 -1
- package/dist/types/src/schema-validator.d.ts.map +1 -1
- package/dist/types/src/smt/smt-store-level.d.ts +32 -0
- package/dist/types/src/smt/smt-store-level.d.ts.map +1 -0
- package/dist/types/src/smt/smt-store-memory.d.ts +22 -0
- package/dist/types/src/smt/smt-store-memory.d.ts.map +1 -0
- package/dist/types/src/smt/smt-utils.d.ts +58 -0
- package/dist/types/src/smt/smt-utils.d.ts.map +1 -0
- package/dist/types/src/smt/sparse-merkle-tree.d.ts +124 -0
- package/dist/types/src/smt/sparse-merkle-tree.d.ts.map +1 -0
- package/dist/types/src/state-index/state-index-level.d.ts +83 -0
- package/dist/types/src/state-index/state-index-level.d.ts.map +1 -0
- package/dist/types/src/store/data-store-level.d.ts +1 -2
- package/dist/types/src/store/data-store-level.d.ts.map +1 -1
- package/dist/types/src/store/index-level.d.ts +98 -2
- package/dist/types/src/store/index-level.d.ts.map +1 -1
- package/dist/types/src/store/level-wrapper.d.ts.map +1 -1
- package/dist/types/src/store/message-store-level.d.ts +5 -0
- package/dist/types/src/store/message-store-level.d.ts.map +1 -1
- package/dist/types/src/store/storage-controller.d.ts +7 -7
- package/dist/types/src/store/storage-controller.d.ts.map +1 -1
- package/dist/types/src/types/data-store.d.ts +2 -3
- package/dist/types/src/types/data-store.d.ts.map +1 -1
- package/dist/types/src/types/encryption-types.d.ts +48 -0
- package/dist/types/src/types/encryption-types.d.ts.map +1 -0
- package/dist/types/src/types/jose-types.d.ts +9 -40
- package/dist/types/src/types/jose-types.d.ts.map +1 -1
- package/dist/types/src/types/message-store.d.ts +5 -0
- package/dist/types/src/types/message-store.d.ts.map +1 -1
- package/dist/types/src/types/message-types.d.ts +19 -0
- package/dist/types/src/types/message-types.d.ts.map +1 -1
- package/dist/types/src/types/messages-types.d.ts +16 -11
- package/dist/types/src/types/messages-types.d.ts.map +1 -1
- package/dist/types/src/types/method-handler.d.ts +1 -2
- package/dist/types/src/types/method-handler.d.ts.map +1 -1
- package/dist/types/src/types/permission-types.d.ts +2 -2
- package/dist/types/src/types/permission-types.d.ts.map +1 -1
- package/dist/types/src/types/protocols-types.d.ts +49 -5
- package/dist/types/src/types/protocols-types.d.ts.map +1 -1
- package/dist/types/src/types/records-types.d.ts +23 -7
- package/dist/types/src/types/records-types.d.ts.map +1 -1
- package/dist/types/src/types/signer.d.ts +1 -1
- package/dist/types/src/types/signer.d.ts.map +1 -1
- package/dist/types/src/types/smt-types.d.ts +81 -0
- package/dist/types/src/types/smt-types.d.ts.map +1 -0
- package/dist/types/src/types/state-index.d.ts +90 -0
- package/dist/types/src/types/state-index.d.ts.map +1 -0
- package/dist/types/src/utils/cid.d.ts +1 -2
- package/dist/types/src/utils/cid.d.ts.map +1 -1
- package/dist/types/src/utils/data-stream.d.ts +14 -7
- package/dist/types/src/utils/data-stream.d.ts.map +1 -1
- package/dist/types/src/utils/encryption.d.ts +2 -3
- package/dist/types/src/utils/encryption.d.ts.map +1 -1
- package/dist/types/src/utils/hd-key.d.ts +4 -4
- package/dist/types/src/utils/hd-key.d.ts.map +1 -1
- package/dist/types/src/utils/jws.d.ts +7 -7
- package/dist/types/src/utils/jws.d.ts.map +1 -1
- package/dist/types/src/utils/private-key-signer.d.ts +4 -4
- package/dist/types/src/utils/private-key-signer.d.ts.map +1 -1
- package/dist/types/src/utils/protocols.d.ts +46 -3
- package/dist/types/src/utils/protocols.d.ts.map +1 -1
- package/dist/types/src/utils/records.d.ts +33 -6
- package/dist/types/src/utils/records.d.ts.map +1 -1
- package/dist/types/src/utils/secp256k1.d.ts +11 -11
- package/dist/types/src/utils/secp256k1.d.ts.map +1 -1
- package/dist/types/src/utils/secp256r1.d.ts +8 -8
- package/dist/types/src/utils/secp256r1.d.ts.map +1 -1
- package/dist/types/src/utils/time.d.ts +1 -1
- package/dist/types/tests/dwn.spec.d.ts.map +1 -1
- package/dist/types/tests/event-stream/event-emitter-stream.spec.d.ts.map +1 -0
- package/dist/types/tests/event-stream/event-stream.spec.d.ts.map +1 -0
- package/dist/types/tests/features/author-delegated-grant.spec.d.ts.map +1 -1
- package/dist/types/tests/features/owner-delegated-grant.spec.d.ts.map +1 -1
- package/dist/types/tests/features/owner-signature.spec.d.ts.map +1 -1
- package/dist/types/tests/features/permissions.spec.d.ts.map +1 -1
- package/dist/types/tests/features/protocol-composition.spec.d.ts +5 -0
- package/dist/types/tests/features/protocol-composition.spec.d.ts.map +1 -0
- package/dist/types/tests/features/protocol-create-action.spec.d.ts.map +1 -1
- package/dist/types/tests/features/protocol-delete-action.spec.d.ts.map +1 -1
- package/dist/types/tests/features/protocol-update-action.spec.d.ts.map +1 -1
- package/dist/types/tests/features/records-prune.spec.d.ts.map +1 -1
- package/dist/types/tests/features/records-tags.spec.d.ts.map +1 -1
- package/dist/types/tests/features/resumable-tasks.spec.d.ts.map +1 -1
- package/dist/types/tests/handlers/messages-read.spec.d.ts.map +1 -1
- package/dist/types/tests/handlers/messages-subscribe.spec.d.ts.map +1 -1
- package/dist/types/tests/handlers/messages-sync.spec.d.ts +2 -0
- package/dist/types/tests/handlers/messages-sync.spec.d.ts.map +1 -0
- package/dist/types/tests/handlers/protocols-configure.spec.d.ts.map +1 -1
- package/dist/types/tests/handlers/protocols-query.spec.d.ts.map +1 -1
- package/dist/types/tests/handlers/records-count.spec.d.ts +2 -0
- package/dist/types/tests/handlers/records-count.spec.d.ts.map +1 -0
- package/dist/types/tests/handlers/records-delete.spec.d.ts.map +1 -1
- package/dist/types/tests/handlers/records-query.spec.d.ts.map +1 -1
- package/dist/types/tests/handlers/records-read.spec.d.ts.map +1 -1
- package/dist/types/tests/handlers/records-subscribe.spec.d.ts.map +1 -1
- package/dist/types/tests/handlers/records-write.spec.d.ts.map +1 -1
- package/dist/types/tests/protocols/permission-grant.spec.d.ts +2 -0
- package/dist/types/tests/protocols/permission-grant.spec.d.ts.map +1 -0
- package/dist/types/tests/scenarios/deleted-record.spec.d.ts.map +1 -1
- package/dist/types/tests/scenarios/end-to-end-tests.spec.d.ts.map +1 -1
- package/dist/types/tests/scenarios/nested-roles.spec.d.ts.map +1 -1
- package/dist/types/tests/smt/smt-store-level.spec.d.ts +2 -0
- package/dist/types/tests/smt/smt-store-level.spec.d.ts.map +1 -0
- package/dist/types/tests/smt/sparse-merkle-tree.spec.d.ts +2 -0
- package/dist/types/tests/smt/sparse-merkle-tree.spec.d.ts.map +1 -0
- package/dist/types/tests/state-index/state-index-level.spec.d.ts +2 -0
- package/dist/types/tests/state-index/state-index-level.spec.d.ts.map +1 -0
- package/dist/types/tests/store/blockstore-level.spec.d.ts +2 -0
- package/dist/types/tests/store/blockstore-level.spec.d.ts.map +1 -0
- package/dist/types/tests/store/message-store.spec.d.ts.map +1 -1
- package/dist/types/tests/test-stores.d.ts +4 -4
- package/dist/types/tests/test-stores.d.ts.map +1 -1
- package/dist/types/tests/test-suite.d.ts +2 -2
- package/dist/types/tests/test-suite.d.ts.map +1 -1
- package/dist/types/tests/utils/encryption-callbacks.spec.d.ts +2 -0
- package/dist/types/tests/utils/encryption-callbacks.spec.d.ts.map +1 -0
- package/dist/types/tests/utils/test-data-generator.d.ts +31 -28
- package/dist/types/tests/utils/test-data-generator.d.ts.map +1 -1
- package/dist/types/tests/validation/json-schemas/records/records-read.spec.d.ts +2 -0
- package/dist/types/tests/validation/json-schemas/records/records-read.spec.d.ts.map +1 -0
- package/package.json +26 -45
- package/src/core/dwn-error.ts +27 -3
- package/src/core/message-reply.ts +1 -1
- package/src/core/message.ts +5 -5
- package/src/core/messages-grant-authorization.ts +22 -8
- package/src/core/protocol-authorization.ts +345 -68
- package/src/core/records-grant-authorization.ts +2 -2
- package/src/core/resumable-task-manager.ts +4 -5
- package/src/dwn.ts +25 -20
- package/src/enums/dwn-interface-method.ts +5 -3
- package/src/handlers/messages-subscribe.ts +1 -1
- package/src/handlers/messages-sync.ts +129 -0
- package/src/handlers/protocols-configure.ts +195 -17
- package/src/handlers/protocols-query.ts +7 -5
- package/src/handlers/records-count.ts +184 -0
- package/src/handlers/records-query.ts +4 -0
- package/src/handlers/records-read.ts +4 -8
- package/src/handlers/records-write.ts +20 -21
- package/src/index.ts +74 -37
- package/src/interfaces/messages-read.ts +6 -5
- package/src/interfaces/messages-subscribe.ts +7 -6
- package/src/interfaces/messages-sync.ts +59 -0
- package/src/interfaces/protocols-configure.ts +211 -33
- package/src/interfaces/protocols-query.ts +7 -6
- package/src/interfaces/records-count.ts +106 -0
- package/src/interfaces/records-delete.ts +2 -2
- package/src/interfaces/records-query.ts +2 -2
- package/src/interfaces/records-read.ts +26 -3
- package/src/interfaces/records-subscribe.ts +2 -2
- package/src/interfaces/records-write.ts +115 -46
- package/src/jose/algorithms/signing/ed25519.ts +13 -12
- package/src/jose/algorithms/signing/signature-algorithms.ts +6 -1
- package/src/jose/jws/general/builder.ts +3 -3
- package/src/jose/jws/general/verifier.ts +3 -3
- package/src/protocols/permission-grant.ts +51 -0
- package/src/protocols/permission-request.ts +37 -0
- package/src/protocols/permissions.ts +5 -5
- package/src/schema-validator.ts +11 -3
- package/src/smt/smt-store-level.ts +143 -0
- package/src/smt/smt-store-memory.ts +53 -0
- package/src/smt/smt-utils.ts +149 -0
- package/src/smt/sparse-merkle-tree.ts +698 -0
- package/src/state-index/state-index-level.ts +241 -0
- package/src/store/data-store-level.ts +8 -7
- package/src/store/index-level.ts +415 -19
- package/src/store/level-wrapper.ts +1 -1
- package/src/store/message-store-level.ts +62 -0
- package/src/store/storage-controller.ts +21 -19
- package/src/types/data-store.ts +2 -4
- package/src/types/encryption-types.ts +52 -0
- package/src/types/jose-types.ts +10 -42
- package/src/types/message-store.ts +11 -0
- package/src/types/message-types.ts +21 -0
- package/src/types/messages-types.ts +21 -15
- package/src/types/method-handler.ts +1 -2
- package/src/types/permission-types.ts +2 -2
- package/src/types/protocols-types.ts +55 -6
- package/src/types/records-types.ts +26 -7
- package/src/types/signer.ts +1 -1
- package/src/types/smt-types.ts +95 -0
- package/src/types/state-index.ts +100 -0
- package/src/utils/cid.ts +3 -4
- package/src/utils/data-stream.ts +75 -38
- package/src/utils/encryption.ts +24 -39
- package/src/utils/hd-key.ts +6 -6
- package/src/utils/jws.ts +9 -9
- package/src/utils/private-key-signer.ts +9 -8
- package/src/utils/protocols.ts +132 -6
- package/src/utils/records.ts +118 -29
- package/src/utils/secp256k1.ts +23 -21
- package/src/utils/secp256r1.ts +17 -15
- package/src/utils/time.ts +1 -1
- package/src/utils/url.ts +1 -1
- package/dist/cjs/index.js +0 -36749
- package/dist/cjs/package.json +0 -1
- package/dist/esm/src/event-log/event-emitter-stream.js.map +0 -1
- package/dist/esm/src/event-log/event-log-level.js +0 -63
- package/dist/esm/src/event-log/event-log-level.js.map +0 -1
- package/dist/esm/src/handlers/messages-query.js +0 -71
- package/dist/esm/src/handlers/messages-query.js.map +0 -1
- package/dist/esm/src/interfaces/messages-query.js.map +0 -1
- package/dist/esm/src/types/event-log.js +0 -2
- package/dist/esm/src/types/event-log.js.map +0 -1
- package/dist/esm/tests/event-log/event-emitter-stream.spec.js.map +0 -1
- package/dist/esm/tests/event-log/event-log-level.spec.js +0 -44
- package/dist/esm/tests/event-log/event-log-level.spec.js.map +0 -1
- package/dist/esm/tests/event-log/event-log.spec.js +0 -236
- package/dist/esm/tests/event-log/event-log.spec.js.map +0 -1
- package/dist/esm/tests/event-log/event-stream.spec.js.map +0 -1
- package/dist/esm/tests/handlers/messages-query.spec.js +0 -349
- package/dist/esm/tests/handlers/messages-query.spec.js.map +0 -1
- package/dist/esm/tests/interfaces/messagess-query.spec.js +0 -127
- package/dist/esm/tests/interfaces/messagess-query.spec.js.map +0 -1
- package/dist/esm/tests/scenarios/messages-query.spec.js +0 -395
- package/dist/esm/tests/scenarios/messages-query.spec.js.map +0 -1
- package/dist/types/src/event-log/event-emitter-stream.d.ts.map +0 -1
- package/dist/types/src/event-log/event-log-level.d.ts +0 -35
- package/dist/types/src/event-log/event-log-level.d.ts.map +0 -1
- package/dist/types/src/handlers/messages-query.d.ts +0 -17
- package/dist/types/src/handlers/messages-query.d.ts.map +0 -1
- package/dist/types/src/interfaces/messages-query.d.ts +0 -16
- package/dist/types/src/interfaces/messages-query.d.ts.map +0 -1
- package/dist/types/src/types/event-log.d.ts +0 -52
- package/dist/types/src/types/event-log.d.ts.map +0 -1
- package/dist/types/tests/event-log/event-emitter-stream.spec.d.ts.map +0 -1
- package/dist/types/tests/event-log/event-log-level.spec.d.ts +0 -2
- package/dist/types/tests/event-log/event-log-level.spec.d.ts.map +0 -1
- package/dist/types/tests/event-log/event-log.spec.d.ts +0 -2
- package/dist/types/tests/event-log/event-log.spec.d.ts.map +0 -1
- package/dist/types/tests/event-log/event-stream.spec.d.ts.map +0 -1
- package/dist/types/tests/handlers/messages-query.spec.d.ts +0 -2
- package/dist/types/tests/handlers/messages-query.spec.d.ts.map +0 -1
- package/dist/types/tests/interfaces/messagess-query.spec.d.ts +0 -2
- package/dist/types/tests/interfaces/messagess-query.spec.d.ts.map +0 -1
- package/dist/types/tests/scenarios/messages-query.spec.d.ts +0 -2
- package/dist/types/tests/scenarios/messages-query.spec.d.ts.map +0 -1
- package/src/event-log/event-log-level.ts +0 -72
- package/src/handlers/messages-query.ts +0 -67
- package/src/interfaces/messages-query.ts +0 -60
- package/src/types/event-log.ts +0 -52
- /package/dist/esm/src/{event-log → event-stream}/event-emitter-stream.js +0 -0
- /package/dist/types/src/{event-log → event-stream}/event-emitter-stream.d.ts +0 -0
- /package/dist/types/tests/{event-log → event-stream}/event-emitter-stream.spec.d.ts +0 -0
- /package/dist/types/tests/{event-log → event-stream}/event-stream.spec.d.ts +0 -0
- /package/src/{event-log → event-stream}/event-emitter-stream.ts +0 -0
|
@@ -16,14 +16,12 @@ import { SortDirection } from '../../src/types/query-types.js';
|
|
|
16
16
|
import { Temporal } from '@js-temporal/polyfill';
|
|
17
17
|
import { TestDataGenerator } from '../utils/test-data-generator.js';
|
|
18
18
|
import { v4 as uuid } from 'uuid';
|
|
19
|
-
import
|
|
20
|
-
import chai, { expect } from 'chai';
|
|
21
|
-
chai.use(chaiAsPromised);
|
|
19
|
+
import { afterAll, beforeAll, beforeEach, describe, expect, it } from 'bun:test';
|
|
22
20
|
describe('IndexLevel', () => {
|
|
23
21
|
let testIndex;
|
|
24
22
|
const tenant = 'did:alice:index-test';
|
|
25
23
|
describe('put', () => {
|
|
26
|
-
|
|
24
|
+
beforeAll(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
27
25
|
testIndex = new IndexLevel({
|
|
28
26
|
createLevelDatabase,
|
|
29
27
|
location: 'TEST-INDEX',
|
|
@@ -33,28 +31,27 @@ describe('IndexLevel', () => {
|
|
|
33
31
|
beforeEach(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
34
32
|
yield testIndex.clear();
|
|
35
33
|
}));
|
|
36
|
-
|
|
34
|
+
afterAll(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
37
35
|
yield testIndex.close();
|
|
38
36
|
}));
|
|
39
37
|
describe('fails to index with no indexable properties', () => {
|
|
40
38
|
it('fails on empty indexes', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
41
39
|
const id = uuid();
|
|
42
40
|
const failedIndexPromise = testIndex.put(tenant, id, {});
|
|
43
|
-
yield expect(failedIndexPromise).
|
|
41
|
+
yield expect(failedIndexPromise).rejects.toThrow(DwnErrorCode.IndexMissingIndexableProperty);
|
|
44
42
|
}));
|
|
45
43
|
});
|
|
46
44
|
it('successfully indexes', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
47
45
|
const id = uuid();
|
|
48
|
-
|
|
46
|
+
yield testIndex.put(tenant, id, {
|
|
49
47
|
id,
|
|
50
48
|
foo: 'foo',
|
|
51
49
|
digit: 12,
|
|
52
50
|
toggle: false,
|
|
53
51
|
tag: ['bar', 'baz']
|
|
54
52
|
});
|
|
55
|
-
yield expect(successfulIndex).to.eventually.not.be.rejected;
|
|
56
53
|
const results = yield testIndex.query(tenant, [{ id: id }], { sortProperty: 'id' });
|
|
57
|
-
expect(results[0].messageCid).
|
|
54
|
+
expect(results[0].messageCid).toBe(id);
|
|
58
55
|
}));
|
|
59
56
|
it('adds one index key per property value, aside from id', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
60
57
|
const id = uuid(); // 1 key for reverse lookup
|
|
@@ -65,7 +62,7 @@ describe('IndexLevel', () => {
|
|
|
65
62
|
dateCreated, // 1 key
|
|
66
63
|
});
|
|
67
64
|
let keys = yield ArrayUtility.fromAsyncGenerator(testIndex.db.keys());
|
|
68
|
-
expect(keys.length).
|
|
65
|
+
expect(keys.length).toBe(5);
|
|
69
66
|
yield testIndex.clear();
|
|
70
67
|
yield testIndex.put(tenant, id, {
|
|
71
68
|
'a': 'b', // 1 key
|
|
@@ -74,7 +71,7 @@ describe('IndexLevel', () => {
|
|
|
74
71
|
dateCreated, // 1 key
|
|
75
72
|
});
|
|
76
73
|
keys = yield ArrayUtility.fromAsyncGenerator(testIndex.db.keys());
|
|
77
|
-
expect(keys.length).
|
|
74
|
+
expect(keys.length).toBe(6);
|
|
78
75
|
}));
|
|
79
76
|
it('should not put anything if aborted beforehand', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
80
77
|
const controller = new AbortController();
|
|
@@ -85,13 +82,13 @@ describe('IndexLevel', () => {
|
|
|
85
82
|
foo: 'bar'
|
|
86
83
|
};
|
|
87
84
|
const indexPromise = testIndex.put(tenant, id, index, { signal: controller.signal });
|
|
88
|
-
yield expect(indexPromise).
|
|
85
|
+
yield expect(indexPromise).rejects.toThrow('reason');
|
|
89
86
|
const entries = yield testIndex.query(tenant, [{ foo: 'bar' }], { sortProperty: 'id' });
|
|
90
|
-
expect(entries.length).
|
|
87
|
+
expect(entries.length).toBe(0);
|
|
91
88
|
}));
|
|
92
89
|
});
|
|
93
90
|
describe('query', () => {
|
|
94
|
-
|
|
91
|
+
beforeAll(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
95
92
|
testIndex = new IndexLevel({
|
|
96
93
|
createLevelDatabase,
|
|
97
94
|
location: 'TEST-INDEX',
|
|
@@ -101,7 +98,7 @@ describe('IndexLevel', () => {
|
|
|
101
98
|
beforeEach(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
102
99
|
yield testIndex.clear();
|
|
103
100
|
}));
|
|
104
|
-
|
|
101
|
+
afterAll(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
105
102
|
yield testIndex.close();
|
|
106
103
|
}));
|
|
107
104
|
it('works', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
@@ -130,8 +127,8 @@ describe('IndexLevel', () => {
|
|
|
130
127
|
'a': 'b',
|
|
131
128
|
'c': 'e'
|
|
132
129
|
}], { sortProperty: 'id' });
|
|
133
|
-
expect(entries.length).
|
|
134
|
-
expect(entries[0].messageCid).
|
|
130
|
+
expect(entries.length).toBe(1);
|
|
131
|
+
expect(entries[0].messageCid).toBe(id3);
|
|
135
132
|
}));
|
|
136
133
|
it('should return all records if an empty filter array is passed', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
137
134
|
const items = ['b', 'a', 'd', 'c'];
|
|
@@ -140,10 +137,10 @@ describe('IndexLevel', () => {
|
|
|
140
137
|
}
|
|
141
138
|
// empty array
|
|
142
139
|
let allResults = yield testIndex.query(tenant, [], { sortProperty: 'letter' });
|
|
143
|
-
expect(allResults.map(({ messageCid }) => messageCid)).
|
|
140
|
+
expect(allResults.map(({ messageCid }) => messageCid)).toEqual(['a', 'b', 'c', 'd']);
|
|
144
141
|
// empty filter
|
|
145
142
|
allResults = yield testIndex.query(tenant, [{}], { sortProperty: 'letter' });
|
|
146
|
-
expect(allResults.map(({ messageCid }) => messageCid)).
|
|
143
|
+
expect(allResults.map(({ messageCid }) => messageCid)).toEqual(['a', 'b', 'c', 'd']);
|
|
147
144
|
}));
|
|
148
145
|
describe('queryWithIteratorPaging()', () => {
|
|
149
146
|
it('paginates using cursor', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
@@ -159,28 +156,28 @@ describe('IndexLevel', () => {
|
|
|
159
156
|
const filters = [{ schema: 'schema', published: true }];
|
|
160
157
|
// query with limit, default (ascending)
|
|
161
158
|
const results = yield testIndex.queryWithIteratorPaging(tenant, filters, { sortProperty: 'val', limit: 2 });
|
|
162
|
-
expect(results.length).
|
|
163
|
-
expect(results.map(({ messageCid }) => messageCid)).
|
|
159
|
+
expect(results.length).toBe(2);
|
|
160
|
+
expect(results.map(({ messageCid }) => messageCid)).toEqual(['a', 'b']);
|
|
164
161
|
// query with cursor, default (ascending)
|
|
165
162
|
const resultsAfterCursor = yield testIndex.queryWithIteratorPaging(tenant, filters, { sortProperty: 'val', cursor: IndexLevel.createCursorFromLastArrayItem(results, 'val') });
|
|
166
|
-
expect(resultsAfterCursor.length).
|
|
167
|
-
expect(resultsAfterCursor.map(({ messageCid }) => messageCid)).
|
|
163
|
+
expect(resultsAfterCursor.length).toBe(2);
|
|
164
|
+
expect(resultsAfterCursor.map(({ messageCid }) => messageCid)).toEqual(['c', 'd']);
|
|
168
165
|
// query with limit, explicit ascending
|
|
169
166
|
const ascResults = yield testIndex.queryWithIteratorPaging(tenant, filters, { sortProperty: 'val', limit: 2 });
|
|
170
|
-
expect(ascResults.length).
|
|
171
|
-
expect(ascResults.map(({ messageCid }) => messageCid)).
|
|
167
|
+
expect(ascResults.length).toBe(2);
|
|
168
|
+
expect(ascResults.map(({ messageCid }) => messageCid)).toEqual(['a', 'b']);
|
|
172
169
|
// query with cursor, explicit ascending
|
|
173
170
|
const ascResultsAfterCursor = yield testIndex.queryWithIteratorPaging(tenant, filters, { sortProperty: 'val', cursor: IndexLevel.createCursorFromLastArrayItem(ascResults, 'val') });
|
|
174
|
-
expect(ascResultsAfterCursor.length).
|
|
175
|
-
expect(ascResultsAfterCursor.map(({ messageCid }) => messageCid)).
|
|
171
|
+
expect(ascResultsAfterCursor.length).toBe(2);
|
|
172
|
+
expect(ascResultsAfterCursor.map(({ messageCid }) => messageCid)).toEqual(['c', 'd']);
|
|
176
173
|
// query with limit, descending
|
|
177
174
|
const descResults = yield testIndex.queryWithIteratorPaging(tenant, filters, { sortDirection: SortDirection.Descending, sortProperty: 'val', limit: 2 });
|
|
178
|
-
expect(descResults.length).
|
|
179
|
-
expect(descResults.map(({ messageCid }) => messageCid)).
|
|
175
|
+
expect(descResults.length).toBe(2);
|
|
176
|
+
expect(descResults.map(({ messageCid }) => messageCid)).toEqual(['d', 'c']);
|
|
180
177
|
// query with cursor, descending
|
|
181
178
|
const descResultsAfterCursor = yield testIndex.queryWithIteratorPaging(tenant, filters, { sortDirection: SortDirection.Descending, sortProperty: 'val', cursor: IndexLevel.createCursorFromLastArrayItem(descResults, 'val') });
|
|
182
|
-
expect(descResultsAfterCursor.length).
|
|
183
|
-
expect(descResultsAfterCursor.map(({ messageCid }) => messageCid)).
|
|
179
|
+
expect(descResultsAfterCursor.length).toBe(2);
|
|
180
|
+
expect(descResultsAfterCursor.map(({ messageCid }) => messageCid)).toEqual(['b', 'a']);
|
|
184
181
|
}));
|
|
185
182
|
it('returns empty array if sort property is invalid', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
186
183
|
const testVals = ['b', 'd', 'c', 'a'];
|
|
@@ -195,10 +192,10 @@ describe('IndexLevel', () => {
|
|
|
195
192
|
const filters = [{ schema: 'schema', published: true }];
|
|
196
193
|
// control test: return all results
|
|
197
194
|
const validResults = yield testIndex.queryWithIteratorPaging(tenant, filters, { sortProperty: 'val' });
|
|
198
|
-
expect(validResults.length).
|
|
195
|
+
expect(validResults.length).toBe(4);
|
|
199
196
|
// sort by invalid property returns no results
|
|
200
197
|
const invalidResults = yield testIndex.queryWithIteratorPaging(tenant, filters, { sortProperty: 'invalid' });
|
|
201
|
-
expect(invalidResults.length).
|
|
198
|
+
expect(invalidResults.length).toBe(0);
|
|
202
199
|
}));
|
|
203
200
|
it('cursor is valid but out of range of matched results', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
204
201
|
const testVals = ['b', 'd', 'c']; // a is missing
|
|
@@ -214,11 +211,11 @@ describe('IndexLevel', () => {
|
|
|
214
211
|
// cursor `a-id` doesn't actually exist, but the value `a` is sorted prior to the result set.
|
|
215
212
|
const cursorA = { messageCid: 'a-id', value: 'a' };
|
|
216
213
|
const allResults = yield testIndex.queryWithIteratorPaging(tenant, filters, { sortProperty: 'val', cursor: cursorA });
|
|
217
|
-
expect(allResults.map(({ messageCid }) => messageCid)).
|
|
214
|
+
expect(allResults.map(({ messageCid }) => messageCid)).toEqual(['b-id', 'c-id', 'd-id']);
|
|
218
215
|
// cursor `e-id` doesn't actually exist, but the value `e` is sorted after to the result set.
|
|
219
216
|
const cursorE = { messageCid: 'e-id', value: 'e' };
|
|
220
217
|
const noResults = yield testIndex.queryWithIteratorPaging(tenant, filters, { sortProperty: 'val', cursor: cursorE });
|
|
221
|
-
expect(noResults.length).
|
|
218
|
+
expect(noResults.length).toEqual(0);
|
|
222
219
|
}));
|
|
223
220
|
});
|
|
224
221
|
describe('array values', () => {
|
|
@@ -241,12 +238,12 @@ describe('IndexLevel', () => {
|
|
|
241
238
|
}
|
|
242
239
|
const filterForItemTag = [{ tag: 'item' }];
|
|
243
240
|
const allResults = yield testIndex.queryWithIteratorPaging(tenant, filterForItemTag, { sortProperty: 'id' });
|
|
244
|
-
expect(allResults.length).
|
|
245
|
-
expect(allResults.map(item => item.messageCid)).
|
|
241
|
+
expect(allResults.length).toBe(4);
|
|
242
|
+
expect(allResults.map(item => item.messageCid)).toEqual(expect.arrayContaining(items.map(item => item.id)));
|
|
246
243
|
const filterForItem3 = [{ tag: 'item3' }];
|
|
247
244
|
const item3Results = yield testIndex.queryWithIteratorPaging(tenant, filterForItem3, { sortProperty: 'id' });
|
|
248
|
-
expect(item3Results.length).
|
|
249
|
-
expect(item3Results.map(item => item.messageCid)).
|
|
245
|
+
expect(item3Results.length).toBe(1);
|
|
246
|
+
expect(item3Results.map(item => item.messageCid)).toEqual(expect.arrayContaining([items[2].id]));
|
|
250
247
|
}));
|
|
251
248
|
it('query items with number array values', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
252
249
|
const items = [{
|
|
@@ -267,16 +264,16 @@ describe('IndexLevel', () => {
|
|
|
267
264
|
}
|
|
268
265
|
const filterForItemTag = [{ tag: 1 }];
|
|
269
266
|
const allResults = yield testIndex.queryWithIteratorPaging(tenant, filterForItemTag, { sortProperty: 'id' });
|
|
270
|
-
expect(allResults.length).
|
|
271
|
-
expect(allResults.map(item => item.messageCid)).
|
|
267
|
+
expect(allResults.length).toBe(4);
|
|
268
|
+
expect(allResults.map(item => item.messageCid)).toEqual(expect.arrayContaining(items.map(item => item.id)));
|
|
272
269
|
const filterForItem3 = [{ tag: 3 }];
|
|
273
270
|
const item3Results = yield testIndex.queryWithIteratorPaging(tenant, filterForItem3, { sortProperty: 'id' });
|
|
274
|
-
expect(item3Results.length).
|
|
275
|
-
expect(item3Results.map(item => item.messageCid)).
|
|
271
|
+
expect(item3Results.length).toBe(1);
|
|
272
|
+
expect(item3Results.map(item => item.messageCid)).toEqual(expect.arrayContaining([items[2].id]));
|
|
276
273
|
const filterForRange = [{ tag: { gt: 1, lt: 4 } }];
|
|
277
274
|
const rangeItems = yield testIndex.queryWithIteratorPaging(tenant, filterForRange, { sortProperty: 'id' });
|
|
278
|
-
expect(rangeItems.length).
|
|
279
|
-
expect(rangeItems.map(item => item.messageCid)).
|
|
275
|
+
expect(rangeItems.length).toBe(2);
|
|
276
|
+
expect(rangeItems.map(item => item.messageCid)).toEqual(expect.arrayContaining([items[1].id, items[2].id]));
|
|
280
277
|
}));
|
|
281
278
|
});
|
|
282
279
|
describe('queryWithInMemoryPaging()', () => {
|
|
@@ -293,28 +290,28 @@ describe('IndexLevel', () => {
|
|
|
293
290
|
const filters = [{ schema: 'schema', published: true }];
|
|
294
291
|
// query with limit, default (ascending)
|
|
295
292
|
const results = yield testIndex.queryWithInMemoryPaging(tenant, filters, { sortProperty: 'val', limit: 2 });
|
|
296
|
-
expect(results.length).
|
|
297
|
-
expect(results.map(({ messageCid }) => messageCid)).
|
|
293
|
+
expect(results.length).toBe(2);
|
|
294
|
+
expect(results.map(({ messageCid }) => messageCid)).toEqual(['a', 'b']);
|
|
298
295
|
// query with cursor, default (ascending)
|
|
299
296
|
const resultsAfterCursor = yield testIndex.queryWithInMemoryPaging(tenant, filters, { sortProperty: 'val', cursor: IndexLevel.createCursorFromLastArrayItem(results, 'val') });
|
|
300
|
-
expect(resultsAfterCursor.length).
|
|
301
|
-
expect(resultsAfterCursor.map(({ messageCid }) => messageCid)).
|
|
297
|
+
expect(resultsAfterCursor.length).toBe(2);
|
|
298
|
+
expect(resultsAfterCursor.map(({ messageCid }) => messageCid)).toEqual(['c', 'd']);
|
|
302
299
|
// query with limit, explicit ascending
|
|
303
300
|
const ascResults = yield testIndex.queryWithInMemoryPaging(tenant, filters, { sortProperty: 'val', limit: 2 });
|
|
304
|
-
expect(ascResults.length).
|
|
305
|
-
expect(ascResults.map(({ messageCid }) => messageCid)).
|
|
301
|
+
expect(ascResults.length).toBe(2);
|
|
302
|
+
expect(ascResults.map(({ messageCid }) => messageCid)).toEqual(['a', 'b']);
|
|
306
303
|
// query with cursor, explicit ascending
|
|
307
304
|
const ascResultsAfterCursor = yield testIndex.queryWithInMemoryPaging(tenant, filters, { sortProperty: 'val', cursor: IndexLevel.createCursorFromLastArrayItem(ascResults, 'val') });
|
|
308
|
-
expect(ascResultsAfterCursor.length).
|
|
309
|
-
expect(ascResultsAfterCursor.map(({ messageCid }) => messageCid)).
|
|
305
|
+
expect(ascResultsAfterCursor.length).toBe(2);
|
|
306
|
+
expect(ascResultsAfterCursor.map(({ messageCid }) => messageCid)).toEqual(['c', 'd']);
|
|
310
307
|
// query with limit, descending
|
|
311
308
|
const descResults = yield testIndex.queryWithInMemoryPaging(tenant, filters, { sortDirection: SortDirection.Descending, sortProperty: 'val', limit: 2 });
|
|
312
|
-
expect(descResults.length).
|
|
313
|
-
expect(descResults.map(({ messageCid }) => messageCid)).
|
|
309
|
+
expect(descResults.length).toBe(2);
|
|
310
|
+
expect(descResults.map(({ messageCid }) => messageCid)).toEqual(['d', 'c']);
|
|
314
311
|
// query with cursor, descending
|
|
315
312
|
const descResultsAfterCursor = yield testIndex.queryWithInMemoryPaging(tenant, filters, { sortDirection: SortDirection.Descending, sortProperty: 'val', cursor: IndexLevel.createCursorFromLastArrayItem(descResults, 'val') });
|
|
316
|
-
expect(descResultsAfterCursor.length).
|
|
317
|
-
expect(descResultsAfterCursor.map(({ messageCid }) => messageCid)).
|
|
313
|
+
expect(descResultsAfterCursor.length).toBe(2);
|
|
314
|
+
expect(descResultsAfterCursor.map(({ messageCid }) => messageCid)).toEqual(['b', 'a']);
|
|
318
315
|
}));
|
|
319
316
|
it('returns empty array if sort property is invalid', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
320
317
|
const testVals = ['b', 'd', 'c', 'a'];
|
|
@@ -329,10 +326,10 @@ describe('IndexLevel', () => {
|
|
|
329
326
|
const filters = [{ schema: 'schema', published: true }];
|
|
330
327
|
// control test: return all results
|
|
331
328
|
const validResults = yield testIndex.queryWithInMemoryPaging(tenant, filters, { sortProperty: 'val', limit: 3 });
|
|
332
|
-
expect(validResults.length).
|
|
329
|
+
expect(validResults.length).toBe(3);
|
|
333
330
|
// sort by invalid property returns no results
|
|
334
331
|
const invalidResults = yield testIndex.queryWithInMemoryPaging(tenant, filters, { sortProperty: 'invalid' });
|
|
335
|
-
expect(invalidResults.length).
|
|
332
|
+
expect(invalidResults.length).toBe(0);
|
|
336
333
|
}));
|
|
337
334
|
it('cursor is valid but out of range of matched results', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
338
335
|
const testVals = ['b', 'd', 'c', 'a'];
|
|
@@ -347,10 +344,10 @@ describe('IndexLevel', () => {
|
|
|
347
344
|
const filters = [{ schema: 'schema', published: true }];
|
|
348
345
|
const cursorA = { messageCid: 'a', value: 'a' }; // before results
|
|
349
346
|
const allResults = yield testIndex.queryWithInMemoryPaging(tenant, filters, { sortProperty: 'val', cursor: cursorA });
|
|
350
|
-
expect(allResults.map(({ messageCid }) => messageCid)).
|
|
347
|
+
expect(allResults.map(({ messageCid }) => messageCid)).toEqual(['b', 'c', 'd']);
|
|
351
348
|
const cursorE = { messageCid: 'e', value: 'e' }; // after results
|
|
352
349
|
const noResults = yield testIndex.queryWithInMemoryPaging(tenant, filters, { sortProperty: 'val', cursor: cursorE });
|
|
353
|
-
expect(noResults.length).
|
|
350
|
+
expect(noResults.length).toEqual(0);
|
|
354
351
|
}));
|
|
355
352
|
it('supports range queries', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
356
353
|
const id = uuid();
|
|
@@ -378,8 +375,8 @@ describe('IndexLevel', () => {
|
|
|
378
375
|
}
|
|
379
376
|
}];
|
|
380
377
|
const entries = yield testIndex.queryWithInMemoryPaging(tenant, filters, { sortProperty: 'id' });
|
|
381
|
-
expect(entries.length).
|
|
382
|
-
expect(entries.map(({ messageCid }) => messageCid)).
|
|
378
|
+
expect(entries.length).toBe(2);
|
|
379
|
+
expect(entries.map(({ messageCid }) => messageCid)).toEqual(expect.arrayContaining([id2, id3]));
|
|
383
380
|
// only upper bounds
|
|
384
381
|
const lteFilter = [{
|
|
385
382
|
value: {
|
|
@@ -387,8 +384,8 @@ describe('IndexLevel', () => {
|
|
|
387
384
|
}
|
|
388
385
|
}];
|
|
389
386
|
const lteReply = yield testIndex.queryWithInMemoryPaging(tenant, lteFilter, { sortProperty: 'id' });
|
|
390
|
-
expect(lteReply.length).
|
|
391
|
-
expect(lteReply.map(({ messageCid }) => messageCid)).
|
|
387
|
+
expect(lteReply.length).toBe(3);
|
|
388
|
+
expect(lteReply.map(({ messageCid }) => messageCid)).toEqual(expect.arrayContaining([id, id2, id3]));
|
|
392
389
|
}));
|
|
393
390
|
describe('array values', () => {
|
|
394
391
|
it('query items with string array values', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
@@ -410,12 +407,12 @@ describe('IndexLevel', () => {
|
|
|
410
407
|
}
|
|
411
408
|
const filterForItemTag = [{ tag: 'item' }];
|
|
412
409
|
const allResults = yield testIndex.queryWithInMemoryPaging(tenant, filterForItemTag, { sortProperty: 'id' });
|
|
413
|
-
expect(allResults.length).
|
|
414
|
-
expect(allResults.map(item => item.messageCid)).
|
|
410
|
+
expect(allResults.length).toBe(4);
|
|
411
|
+
expect(allResults.map(item => item.messageCid)).toEqual(expect.arrayContaining(items.map(item => item.id)));
|
|
415
412
|
const filterForItem3 = [{ tag: 'item3' }];
|
|
416
413
|
const item3Results = yield testIndex.queryWithInMemoryPaging(tenant, filterForItem3, { sortProperty: 'id' });
|
|
417
|
-
expect(item3Results.length).
|
|
418
|
-
expect(item3Results.map(item => item.messageCid)).
|
|
414
|
+
expect(item3Results.length).toBe(1);
|
|
415
|
+
expect(item3Results.map(item => item.messageCid)).toEqual(expect.arrayContaining([items[2].id]));
|
|
419
416
|
}));
|
|
420
417
|
it('query items with number array values', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
421
418
|
const items = [{
|
|
@@ -436,16 +433,16 @@ describe('IndexLevel', () => {
|
|
|
436
433
|
}
|
|
437
434
|
const filterForItemTag = [{ tag: 1 }];
|
|
438
435
|
const allResults = yield testIndex.queryWithInMemoryPaging(tenant, filterForItemTag, { sortProperty: 'id' });
|
|
439
|
-
expect(allResults.length).
|
|
440
|
-
expect(allResults.map(item => item.messageCid)).
|
|
436
|
+
expect(allResults.length).toBe(4);
|
|
437
|
+
expect(allResults.map(item => item.messageCid)).toEqual(expect.arrayContaining(items.map(item => item.id)));
|
|
441
438
|
const filterForItem3 = [{ tag: 3 }];
|
|
442
439
|
const item3Results = yield testIndex.queryWithInMemoryPaging(tenant, filterForItem3, { sortProperty: 'id' });
|
|
443
|
-
expect(item3Results.length).
|
|
444
|
-
expect(item3Results.map(item => item.messageCid)).
|
|
440
|
+
expect(item3Results.length).toBe(1);
|
|
441
|
+
expect(item3Results.map(item => item.messageCid)).toEqual(expect.arrayContaining([items[2].id]));
|
|
445
442
|
const filterForRange = [{ tag: { gt: 1, lt: 4 } }];
|
|
446
443
|
const rangeItems = yield testIndex.queryWithInMemoryPaging(tenant, filterForRange, { sortProperty: 'id' });
|
|
447
|
-
expect(rangeItems.length).
|
|
448
|
-
expect(rangeItems.map(item => item.messageCid)).
|
|
444
|
+
expect(rangeItems.length).toBe(2);
|
|
445
|
+
expect(rangeItems.map(item => item.messageCid)).toEqual(expect.arrayContaining([items[1].id, items[2].id]));
|
|
449
446
|
}));
|
|
450
447
|
});
|
|
451
448
|
});
|
|
@@ -459,7 +456,7 @@ describe('IndexLevel', () => {
|
|
|
459
456
|
yield testIndex.put(tenant, id, doc);
|
|
460
457
|
const filters = [{ value: 'foo' }];
|
|
461
458
|
const entries = yield testIndex.query(tenant, filters, { sortProperty: 'id' });
|
|
462
|
-
expect(entries.length).
|
|
459
|
+
expect(entries.length).toBe(0);
|
|
463
460
|
}));
|
|
464
461
|
it('supports OR queries', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
465
462
|
const id1 = uuid();
|
|
@@ -484,9 +481,9 @@ describe('IndexLevel', () => {
|
|
|
484
481
|
a: ['a', 'b']
|
|
485
482
|
}];
|
|
486
483
|
const entries = yield testIndex.query(tenant, filters, { sortProperty: 'id' });
|
|
487
|
-
expect(entries.length).
|
|
488
|
-
expect(entries.map(({ messageCid }) => messageCid)).
|
|
489
|
-
expect(entries.map(({ messageCid }) => messageCid)).
|
|
484
|
+
expect(entries.length).toBe(2);
|
|
485
|
+
expect(entries.map(({ messageCid }) => messageCid)).toContain(id1);
|
|
486
|
+
expect(entries.map(({ messageCid }) => messageCid)).toContain(id2);
|
|
490
487
|
}));
|
|
491
488
|
it('supports range queries', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
492
489
|
for (let i = -5; i < 5; ++i) {
|
|
@@ -503,7 +500,7 @@ describe('IndexLevel', () => {
|
|
|
503
500
|
}
|
|
504
501
|
}];
|
|
505
502
|
const entries = yield testIndex.query(tenant, filters, { sortProperty: 'id' });
|
|
506
|
-
expect(entries.length).
|
|
503
|
+
expect(entries.length).toBe(5);
|
|
507
504
|
}));
|
|
508
505
|
it('supports prefixed range queries', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
509
506
|
const id = uuid();
|
|
@@ -518,8 +515,8 @@ describe('IndexLevel', () => {
|
|
|
518
515
|
}
|
|
519
516
|
}];
|
|
520
517
|
const entries = yield testIndex.query(tenant, filters, { sortProperty: 'id' });
|
|
521
|
-
expect(entries.length).
|
|
522
|
-
expect(entries.map(({ messageCid }) => messageCid)).
|
|
518
|
+
expect(entries.length).toBe(1);
|
|
519
|
+
expect(entries.map(({ messageCid }) => messageCid)).toContain(id);
|
|
523
520
|
}));
|
|
524
521
|
it('supports suffixed range queries', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
525
522
|
const id1 = uuid();
|
|
@@ -540,8 +537,8 @@ describe('IndexLevel', () => {
|
|
|
540
537
|
}
|
|
541
538
|
}];
|
|
542
539
|
const entries = yield testIndex.query(tenant, filters, { sortProperty: 'id' });
|
|
543
|
-
expect(entries.length).
|
|
544
|
-
expect(entries.map(({ messageCid }) => messageCid)).
|
|
540
|
+
expect(entries.length).toBe(1);
|
|
541
|
+
expect(entries.map(({ messageCid }) => messageCid)).toContain(id1);
|
|
545
542
|
}));
|
|
546
543
|
it('treats strings differently', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
547
544
|
const id1 = uuid();
|
|
@@ -560,8 +557,8 @@ describe('IndexLevel', () => {
|
|
|
560
557
|
foo: true
|
|
561
558
|
}];
|
|
562
559
|
const entries = yield testIndex.query(tenant, filters, { sortProperty: 'id' });
|
|
563
|
-
expect(entries.length).
|
|
564
|
-
expect(entries.map(({ messageCid }) => messageCid)).
|
|
560
|
+
expect(entries.length).toBe(1);
|
|
561
|
+
expect(entries.map(({ messageCid }) => messageCid)).toContain(id1);
|
|
565
562
|
}));
|
|
566
563
|
describe('numbers', () => {
|
|
567
564
|
const positiveDigits = Array(10).fill({}).map(_ => TestDataGenerator.randomInt(0, Number.MAX_SAFE_INTEGER)).sort((a, b) => a - b);
|
|
@@ -577,8 +574,8 @@ describe('IndexLevel', () => {
|
|
|
577
574
|
digit: testNumbers.at(index)
|
|
578
575
|
}];
|
|
579
576
|
const entries = yield testIndex.query(tenant, filters, { sortProperty: 'digit' });
|
|
580
|
-
expect(entries.length).
|
|
581
|
-
expect((_a = entries.at(0)) === null || _a === void 0 ? void 0 : _a.messageCid).
|
|
577
|
+
expect(entries.length).toBe(1);
|
|
578
|
+
expect((_a = entries.at(0)) === null || _a === void 0 ? void 0 : _a.messageCid).toBe(testNumbers.at(index).toString());
|
|
582
579
|
}));
|
|
583
580
|
it('should not return records that do not match provided number equality filter', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
584
581
|
// remove the potential (but unlikely) negative test result
|
|
@@ -587,7 +584,7 @@ describe('IndexLevel', () => {
|
|
|
587
584
|
}
|
|
588
585
|
const filters = [{ digit: 1 }];
|
|
589
586
|
const entries = yield testIndex.query(tenant, filters, { sortProperty: 'digit' });
|
|
590
|
-
expect(entries.length).
|
|
587
|
+
expect(entries.length).toBe(0);
|
|
591
588
|
}));
|
|
592
589
|
it('supports range queries with positive numbers inclusive', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
593
590
|
for (const digit of testNumbers) {
|
|
@@ -603,7 +600,7 @@ describe('IndexLevel', () => {
|
|
|
603
600
|
}];
|
|
604
601
|
const entries = yield testIndex.query(tenant, filters, { sortProperty: 'digit' });
|
|
605
602
|
const testResults = testNumbers.filter(n => n >= lowerBound && n <= upperBound).map(n => n.toString());
|
|
606
|
-
expect(entries.map(({ messageCid }) => messageCid)).
|
|
603
|
+
expect(entries.map(({ messageCid }) => messageCid)).toEqual(testResults);
|
|
607
604
|
}));
|
|
608
605
|
it('supports range queries with negative numbers inclusive', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
609
606
|
for (const digit of testNumbers) {
|
|
@@ -619,7 +616,7 @@ describe('IndexLevel', () => {
|
|
|
619
616
|
}];
|
|
620
617
|
const entries = yield testIndex.query(tenant, filters, { sortProperty: 'digit' });
|
|
621
618
|
const testResults = testNumbers.filter(n => n >= lowerBound && n <= upperBound).map(n => n.toString());
|
|
622
|
-
expect(entries.map(({ messageCid }) => messageCid)).
|
|
619
|
+
expect(entries.map(({ messageCid }) => messageCid)).toEqual(testResults);
|
|
623
620
|
}));
|
|
624
621
|
it('should return numbers gt a negative digit', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
625
622
|
for (const digit of testNumbers) {
|
|
@@ -633,7 +630,7 @@ describe('IndexLevel', () => {
|
|
|
633
630
|
}];
|
|
634
631
|
const entries = yield testIndex.query(tenant, filters, { sortProperty: 'digit' });
|
|
635
632
|
const testResults = testNumbers.filter(n => n > lowerBound).map(n => n.toString());
|
|
636
|
-
expect(entries.map(({ messageCid }) => messageCid)).
|
|
633
|
+
expect(entries.map(({ messageCid }) => messageCid)).toEqual(testResults);
|
|
637
634
|
}));
|
|
638
635
|
it('should return numbers gt a digit', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
639
636
|
for (const digit of testNumbers) {
|
|
@@ -647,7 +644,7 @@ describe('IndexLevel', () => {
|
|
|
647
644
|
}];
|
|
648
645
|
const entries = yield testIndex.query(tenant, filters, { sortProperty: 'digit' });
|
|
649
646
|
const testResults = testNumbers.filter(n => n > lowerBound).map(n => n.toString());
|
|
650
|
-
expect(entries.map(({ messageCid }) => messageCid)).
|
|
647
|
+
expect(entries.map(({ messageCid }) => messageCid)).toEqual(testResults);
|
|
651
648
|
}));
|
|
652
649
|
it('should return numbers lt a negative digit', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
653
650
|
for (const digit of testNumbers) {
|
|
@@ -661,7 +658,7 @@ describe('IndexLevel', () => {
|
|
|
661
658
|
}];
|
|
662
659
|
const entries = yield testIndex.query(tenant, filters, { sortProperty: 'digit' });
|
|
663
660
|
const testResults = testNumbers.filter(n => n < upperBound).map(n => n.toString());
|
|
664
|
-
expect(entries.map(({ messageCid }) => messageCid)).
|
|
661
|
+
expect(entries.map(({ messageCid }) => messageCid)).toEqual(testResults);
|
|
665
662
|
}));
|
|
666
663
|
it('should return numbers lt a digit', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
667
664
|
for (const digit of testNumbers) {
|
|
@@ -675,7 +672,7 @@ describe('IndexLevel', () => {
|
|
|
675
672
|
}];
|
|
676
673
|
const entries = yield testIndex.query(tenant, filters, { sortProperty: 'digit' });
|
|
677
674
|
const testResults = testNumbers.filter(n => n < upperBound).map(n => n.toString());
|
|
678
|
-
expect(entries.map(({ messageCid }) => messageCid)).
|
|
675
|
+
expect(entries.map(({ messageCid }) => messageCid)).toEqual(testResults);
|
|
679
676
|
}));
|
|
680
677
|
});
|
|
681
678
|
describe('booleans', () => {
|
|
@@ -697,18 +694,18 @@ describe('IndexLevel', () => {
|
|
|
697
694
|
const bothFilter = [{ schema: 'schema' }];
|
|
698
695
|
// control
|
|
699
696
|
const entries = yield testIndex.query(tenant, bothFilter, { sortProperty: 'id' });
|
|
700
|
-
expect(entries.length).
|
|
701
|
-
expect(entries.map(({ messageCid }) => messageCid)).
|
|
697
|
+
expect(entries.length).toBe(2);
|
|
698
|
+
expect(entries.map(({ messageCid }) => messageCid)).toEqual(expect.arrayContaining([itemTrueId, itemFalseId]));
|
|
702
699
|
const trueFilter = [{ published: true, schema: 'schema' }];
|
|
703
700
|
// equality true
|
|
704
701
|
const respTrue = yield testIndex.query(tenant, trueFilter, { sortProperty: 'id' });
|
|
705
|
-
expect(respTrue.length).
|
|
706
|
-
expect(respTrue.map(({ messageCid }) => messageCid)).
|
|
702
|
+
expect(respTrue.length).toBe(1);
|
|
703
|
+
expect(respTrue.map(({ messageCid }) => messageCid)).toEqual(expect.arrayContaining([itemTrueId]));
|
|
707
704
|
const falseFilter = [{ published: false, schema: 'schema' }];
|
|
708
705
|
// equality false
|
|
709
706
|
const respFalse = yield testIndex.query(tenant, falseFilter, { sortProperty: 'id' });
|
|
710
|
-
expect(respFalse.length).
|
|
711
|
-
expect(respFalse.map(({ messageCid }) => messageCid)).
|
|
707
|
+
expect(respFalse.length).toBe(1);
|
|
708
|
+
expect(respFalse.map(({ messageCid }) => messageCid)).toEqual(expect.arrayContaining([itemFalseId]));
|
|
712
709
|
}));
|
|
713
710
|
});
|
|
714
711
|
describe('sort, limit and cursor', () => {
|
|
@@ -720,12 +717,12 @@ describe('IndexLevel', () => {
|
|
|
720
717
|
const filters = [{ schema: 'schema' }];
|
|
721
718
|
// limit results without cursor
|
|
722
719
|
let ascResults = yield testIndex.query(tenant, filters, { sortProperty: 'val', limit: 2 });
|
|
723
|
-
expect(ascResults.length).
|
|
724
|
-
expect(ascResults.map(({ messageCid }) => messageCid)).
|
|
720
|
+
expect(ascResults.length).toBe(2);
|
|
721
|
+
expect(ascResults.map(({ messageCid }) => messageCid)).toEqual(['a', 'b']);
|
|
725
722
|
// limit results with a cursor
|
|
726
723
|
ascResults = yield testIndex.query(tenant, filters, { sortProperty: 'val', limit: 2, cursor: IndexLevel.createCursorFromLastArrayItem(ascResults, 'val') });
|
|
727
|
-
expect(ascResults.length).
|
|
728
|
-
expect(ascResults.map(({ messageCid }) => messageCid)).
|
|
724
|
+
expect(ascResults.length).toBe(2);
|
|
725
|
+
expect(ascResults.map(({ messageCid }) => messageCid)).toEqual(['c', 'd']);
|
|
729
726
|
}));
|
|
730
727
|
it('can sort by any indexed property', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
731
728
|
const testVals = ['b', 'd', 'c', 'a'];
|
|
@@ -735,20 +732,20 @@ describe('IndexLevel', () => {
|
|
|
735
732
|
const filters = [{ schema: 'schema' }];
|
|
736
733
|
// sort by value ascending
|
|
737
734
|
const ascResults = yield testIndex.query(tenant, filters, { sortProperty: 'val' });
|
|
738
|
-
expect(ascResults.length).
|
|
739
|
-
expect(ascResults.map(({ messageCid }) => messageCid)).
|
|
735
|
+
expect(ascResults.length).toBe(testVals.length);
|
|
736
|
+
expect(ascResults.map(({ messageCid }) => messageCid)).toEqual(['a', 'b', 'c', 'd']);
|
|
740
737
|
// sort by index ascending
|
|
741
738
|
const ascIndexResults = yield testIndex.query(tenant, filters, { sortProperty: 'index' });
|
|
742
|
-
expect(ascIndexResults.length).
|
|
743
|
-
expect(ascIndexResults.map(({ messageCid }) => messageCid)).
|
|
739
|
+
expect(ascIndexResults.length).toBe(testVals.length);
|
|
740
|
+
expect(ascIndexResults.map(({ messageCid }) => messageCid)).toEqual(testVals);
|
|
744
741
|
// sort by value descending
|
|
745
742
|
const descResults = yield testIndex.query(tenant, filters, { sortProperty: 'val', sortDirection: SortDirection.Descending });
|
|
746
|
-
expect(descResults.length).
|
|
747
|
-
expect(descResults.map(({ messageCid }) => messageCid)).
|
|
743
|
+
expect(descResults.length).toBe(testVals.length);
|
|
744
|
+
expect(descResults.map(({ messageCid }) => messageCid)).toEqual(['d', 'c', 'b', 'a']);
|
|
748
745
|
// sort by index descending
|
|
749
746
|
const descIndexResults = yield testIndex.query(tenant, filters, { sortProperty: 'index', sortDirection: SortDirection.Descending });
|
|
750
|
-
expect(descIndexResults.length).
|
|
751
|
-
expect(descIndexResults.map(({ messageCid }) => messageCid)).
|
|
747
|
+
expect(descIndexResults.length).toBe(testVals.length);
|
|
748
|
+
expect(descIndexResults.map(({ messageCid }) => messageCid)).toEqual([...testVals].reverse());
|
|
752
749
|
}));
|
|
753
750
|
it('sorts lexicographic', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
754
751
|
const testVals = ['b', 'a', 'd', 'c'];
|
|
@@ -758,12 +755,12 @@ describe('IndexLevel', () => {
|
|
|
758
755
|
const filters = [{ schema: 'schema' }];
|
|
759
756
|
// sort ascending
|
|
760
757
|
const ascResults = yield testIndex.query(tenant, filters, { sortProperty: 'val' });
|
|
761
|
-
expect(ascResults.length).
|
|
762
|
-
expect(ascResults.map(({ messageCid }) => messageCid)).
|
|
758
|
+
expect(ascResults.length).toBe(4);
|
|
759
|
+
expect(ascResults.map(({ messageCid }) => messageCid)).toEqual(['a', 'b', 'c', 'd']);
|
|
763
760
|
// sort descending
|
|
764
761
|
const descResults = yield testIndex.query(tenant, filters, { sortProperty: 'val', sortDirection: SortDirection.Descending });
|
|
765
|
-
expect(descResults.length).
|
|
766
|
-
expect(descResults.map(({ messageCid }) => messageCid)).
|
|
762
|
+
expect(descResults.length).toBe(4);
|
|
763
|
+
expect(descResults.map(({ messageCid }) => messageCid)).toEqual(['d', 'c', 'b', 'a']);
|
|
767
764
|
}));
|
|
768
765
|
it('sorts numeric with and without a cursor', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
769
766
|
const testVals = [-2, -1, 0, 1, 2, 3, 4];
|
|
@@ -773,12 +770,12 @@ describe('IndexLevel', () => {
|
|
|
773
770
|
const filters = [{ schema: 'schema' }];
|
|
774
771
|
// sort ascending
|
|
775
772
|
const ascResults = yield testIndex.query(tenant, filters, { sortProperty: 'val' });
|
|
776
|
-
expect(ascResults.length).
|
|
777
|
-
expect(ascResults.map(({ messageCid }) => messageCid)).
|
|
773
|
+
expect(ascResults.length).toBe(testVals.length);
|
|
774
|
+
expect(ascResults.map(({ messageCid }) => messageCid)).toEqual(['-2', '-1', '0', '1', '2', '3', '4']);
|
|
778
775
|
// sort descending
|
|
779
776
|
const descResults = yield testIndex.query(tenant, filters, { sortProperty: 'val', sortDirection: SortDirection.Descending });
|
|
780
|
-
expect(descResults.length).
|
|
781
|
-
expect(descResults.map(({ messageCid }) => messageCid)).
|
|
777
|
+
expect(descResults.length).toEqual(testVals.length);
|
|
778
|
+
expect(descResults.map(({ messageCid }) => messageCid)).toEqual(['4', '3', '2', '1', '0', '-1', '-2']);
|
|
782
779
|
}));
|
|
783
780
|
it('sorts range queries with or without a cursor', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
784
781
|
const testItems = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'];
|
|
@@ -796,16 +793,16 @@ describe('IndexLevel', () => {
|
|
|
796
793
|
}];
|
|
797
794
|
// ascending without a cursor
|
|
798
795
|
let response = yield testIndex.query(tenant, bothBoundsFilters, { sortProperty: 'letter', limit: 4 });
|
|
799
|
-
expect(response.map(({ messageCid }) => messageCid)).
|
|
796
|
+
expect(response.map(({ messageCid }) => messageCid)).toEqual(['b', 'c', 'd', 'e']);
|
|
800
797
|
// ascending with a cursor
|
|
801
798
|
response = yield testIndex.query(tenant, bothBoundsFilters, { sortProperty: 'letter', cursor: IndexLevel.createCursorFromLastArrayItem(response, 'letter') });
|
|
802
|
-
expect(response.map(({ messageCid }) => messageCid)).
|
|
799
|
+
expect(response.map(({ messageCid }) => messageCid)).toEqual(['f', 'g']); // should only return greater than e
|
|
803
800
|
// descending without a cursor
|
|
804
801
|
response = yield testIndex.query(tenant, bothBoundsFilters, { sortProperty: 'letter', sortDirection: SortDirection.Descending, limit: 4 });
|
|
805
|
-
expect(response.map(({ messageCid }) => messageCid)).
|
|
802
|
+
expect(response.map(({ messageCid }) => messageCid)).toEqual(['g', 'f', 'e', 'd']);
|
|
806
803
|
// descending with a cursor
|
|
807
804
|
response = yield testIndex.query(tenant, bothBoundsFilters, { sortProperty: 'letter', sortDirection: SortDirection.Descending, cursor: IndexLevel.createCursorFromLastArrayItem(response, 'letter') });
|
|
808
|
-
expect(response.map(({ messageCid }) => messageCid)).
|
|
805
|
+
expect(response.map(({ messageCid }) => messageCid)).toEqual(['c', 'b']); // should only return less than d
|
|
809
806
|
// test only upper bounds
|
|
810
807
|
const upperBoundsFilters = [{
|
|
811
808
|
letter: {
|
|
@@ -814,16 +811,16 @@ describe('IndexLevel', () => {
|
|
|
814
811
|
}];
|
|
815
812
|
// ascending without a cursor
|
|
816
813
|
response = yield testIndex.query(tenant, upperBoundsFilters, { sortProperty: 'letter', limit: 4 });
|
|
817
|
-
expect(response.map(({ messageCid }) => messageCid)).
|
|
814
|
+
expect(response.map(({ messageCid }) => messageCid)).toEqual(['a', 'b', 'c', 'd']);
|
|
818
815
|
// ascending with a cursor
|
|
819
816
|
response = yield testIndex.query(tenant, upperBoundsFilters, { sortProperty: 'letter', cursor: IndexLevel.createCursorFromLastArrayItem(response, 'letter') });
|
|
820
|
-
expect(response.map(({ messageCid }) => messageCid)).
|
|
817
|
+
expect(response.map(({ messageCid }) => messageCid)).toEqual(['e', 'f', 'g']); // should only return items greater than d
|
|
821
818
|
// descending without a cursor
|
|
822
819
|
response = yield testIndex.query(tenant, upperBoundsFilters, { sortProperty: 'letter', sortDirection: SortDirection.Descending, limit: 4 });
|
|
823
|
-
expect(response.map(({ messageCid }) => messageCid)).
|
|
820
|
+
expect(response.map(({ messageCid }) => messageCid)).toEqual(['g', 'f', 'e', 'd']);
|
|
824
821
|
// descending with a cursor
|
|
825
822
|
response = yield testIndex.query(tenant, upperBoundsFilters, { sortProperty: 'letter', sortDirection: SortDirection.Descending, cursor: IndexLevel.createCursorFromLastArrayItem(response, 'letter') });
|
|
826
|
-
expect(response.map(({ messageCid }) => messageCid)).
|
|
823
|
+
expect(response.map(({ messageCid }) => messageCid)).toEqual(['c', 'b', 'a']); // should only return items less than c
|
|
827
824
|
// test only lower bounds
|
|
828
825
|
const lowerBoundsFilters = [{
|
|
829
826
|
letter: {
|
|
@@ -832,16 +829,16 @@ describe('IndexLevel', () => {
|
|
|
832
829
|
}];
|
|
833
830
|
// ascending without a cursor
|
|
834
831
|
response = yield testIndex.query(tenant, lowerBoundsFilters, { sortProperty: 'letter', limit: 4 });
|
|
835
|
-
expect(response.map(({ messageCid }) => messageCid)).
|
|
832
|
+
expect(response.map(({ messageCid }) => messageCid)).toEqual(['b', 'c', 'd', 'e']);
|
|
836
833
|
// ascending with a cursor
|
|
837
834
|
response = yield testIndex.query(tenant, lowerBoundsFilters, { sortProperty: 'letter', cursor: IndexLevel.createCursorFromLastArrayItem(response, 'letter') });
|
|
838
|
-
expect(response.map(({ messageCid }) => messageCid)).
|
|
835
|
+
expect(response.map(({ messageCid }) => messageCid)).toEqual(['f', 'g', 'h']); // should only return items greater than e
|
|
839
836
|
// descending without a cursor
|
|
840
837
|
response = yield testIndex.query(tenant, lowerBoundsFilters, { sortProperty: 'letter', sortDirection: SortDirection.Descending, limit: 4 });
|
|
841
|
-
expect(response.map(({ messageCid }) => messageCid)).
|
|
838
|
+
expect(response.map(({ messageCid }) => messageCid)).toEqual(['h', 'g', 'f', 'e']);
|
|
842
839
|
// descending with a cursor
|
|
843
840
|
response = yield testIndex.query(tenant, lowerBoundsFilters, { sortProperty: 'letter', sortDirection: SortDirection.Descending, cursor: IndexLevel.createCursorFromLastArrayItem(response, 'letter') });
|
|
844
|
-
expect(response.map(({ messageCid }) => messageCid)).
|
|
841
|
+
expect(response.map(({ messageCid }) => messageCid)).toEqual(['d', 'c', 'b']); // should only return items less than e
|
|
845
842
|
}));
|
|
846
843
|
it('sorts range queries negative integers with or without a cursor', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
847
844
|
const testNumbers = [-5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5];
|
|
@@ -857,11 +854,11 @@ describe('IndexLevel', () => {
|
|
|
857
854
|
}
|
|
858
855
|
}];
|
|
859
856
|
let results = yield testIndex.query(tenant, filters, { sortProperty: 'digit', limit: 4 });
|
|
860
|
-
expect(results.map(({ messageCid }) => messageCid)).
|
|
857
|
+
expect(results.map(({ messageCid }) => messageCid)).toEqual(['-2', '-1', '0', '1']);
|
|
861
858
|
const cursor = IndexLevel.createCursorFromLastArrayItem(results, 'digit');
|
|
862
|
-
expect(typeof (cursor === null || cursor === void 0 ? void 0 : cursor.value)).
|
|
859
|
+
expect(typeof (cursor === null || cursor === void 0 ? void 0 : cursor.value)).toBe('number'); // the cursor value is a number, as it was indexed
|
|
863
860
|
results = yield testIndex.query(tenant, filters, { sortProperty: 'digit', cursor });
|
|
864
|
-
expect(results.map(({ messageCid }) => messageCid)).
|
|
861
|
+
expect(results.map(({ messageCid }) => messageCid)).toEqual(['2', '3']);
|
|
865
862
|
}));
|
|
866
863
|
it('sorts range queries with remaining results in lte after cursor', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
867
864
|
// create an array with unique IDs but multiple items representing the same digit.
|
|
@@ -903,7 +900,7 @@ describe('IndexLevel', () => {
|
|
|
903
900
|
lte: upperBound
|
|
904
901
|
},
|
|
905
902
|
}], { sortProperty: 'id', limit: 3 });
|
|
906
|
-
expect(response.map(({ messageCid }) => messageCid)).
|
|
903
|
+
expect(response.map(({ messageCid }) => messageCid)).toEqual(['b', 'c', 'd']);
|
|
907
904
|
// this cursor should ony return results from the 'lte' part of the filter
|
|
908
905
|
response = yield testIndex.query(tenant, [{
|
|
909
906
|
digit: {
|
|
@@ -911,14 +908,14 @@ describe('IndexLevel', () => {
|
|
|
911
908
|
lte: upperBound
|
|
912
909
|
},
|
|
913
910
|
}], { sortProperty: 'id', cursor: IndexLevel.createCursorFromLastArrayItem(response, 'id') });
|
|
914
|
-
expect(response.map(({ messageCid }) => messageCid)).
|
|
911
|
+
expect(response.map(({ messageCid }) => messageCid)).toEqual(['e', 'f', 'g']);
|
|
915
912
|
// issue a range with no lower bounds but a limit
|
|
916
913
|
response = yield testIndex.query(tenant, [{
|
|
917
914
|
digit: {
|
|
918
915
|
lte: upperBound
|
|
919
916
|
},
|
|
920
917
|
}], { sortProperty: 'id', limit: 4 });
|
|
921
|
-
expect(response.map(({ messageCid }) => messageCid)).
|
|
918
|
+
expect(response.map(({ messageCid }) => messageCid)).toEqual(['a', 'b', 'c', 'd']);
|
|
922
919
|
// with no lower bounds
|
|
923
920
|
// ascending with a cursor
|
|
924
921
|
// this cursor should ony return results from the 'lte' part of the filter
|
|
@@ -927,7 +924,7 @@ describe('IndexLevel', () => {
|
|
|
927
924
|
lte: upperBound
|
|
928
925
|
},
|
|
929
926
|
}], { sortProperty: 'id', cursor: IndexLevel.createCursorFromLastArrayItem(response, 'id') });
|
|
930
|
-
expect(response.map(({ messageCid }) => messageCid)).
|
|
927
|
+
expect(response.map(({ messageCid }) => messageCid)).toEqual(['e', 'f', 'g']); // should only return three matching items
|
|
931
928
|
}));
|
|
932
929
|
it('sorts OR queries with or without a cursor', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
933
930
|
const testValsSchema1 = ['a1', 'b1', 'c1', 'd1'];
|
|
@@ -943,10 +940,10 @@ describe('IndexLevel', () => {
|
|
|
943
940
|
}];
|
|
944
941
|
// sort ascending without cursor
|
|
945
942
|
let results = yield testIndex.query(tenant, filters, { sortProperty: 'val', limit: 4 });
|
|
946
|
-
expect(results.map(({ messageCid }) => messageCid)).
|
|
943
|
+
expect(results.map(({ messageCid }) => messageCid)).toEqual(['a1', 'a2', 'b1', 'b2']);
|
|
947
944
|
// sort ascending from b2 onwards
|
|
948
945
|
results = yield testIndex.query(tenant, filters, { sortProperty: 'val', cursor: IndexLevel.createCursorFromLastArrayItem(results, 'val') });
|
|
949
|
-
expect(results.map(({ messageCid }) => messageCid)).
|
|
946
|
+
expect(results.map(({ messageCid }) => messageCid)).toEqual(['c1', 'c2', 'd1', 'd2']);
|
|
950
947
|
}));
|
|
951
948
|
it('supports multiple filtered queries', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
952
949
|
const items = [];
|
|
@@ -978,22 +975,22 @@ describe('IndexLevel', () => {
|
|
|
978
975
|
];
|
|
979
976
|
// query in ascending order.
|
|
980
977
|
const results = yield testIndex.query(tenant, filters, { sortProperty: 'val', limit: 10 });
|
|
981
|
-
expect(results.length).
|
|
982
|
-
expect(results.map(({ messageCid }) => messageCid)).
|
|
978
|
+
expect(results.length).toBeLessThanOrEqual(10);
|
|
979
|
+
expect(results.map(({ messageCid }) => messageCid)).toEqual([...compareResults].slice(0, 10));
|
|
983
980
|
// query in ascending order with cursor.
|
|
984
981
|
const resultsWithCursor = yield testIndex.query(tenant, filters, { sortProperty: 'val', cursor: IndexLevel.createCursorFromLastArrayItem(results, 'val') });
|
|
985
|
-
expect(resultsWithCursor.map(({ messageCid }) => messageCid)).
|
|
982
|
+
expect(resultsWithCursor.map(({ messageCid }) => messageCid)).toEqual([...compareResults].slice(10));
|
|
986
983
|
const descResults = yield testIndex.query(tenant, filters, { sortProperty: 'val', sortDirection: SortDirection.Descending, limit: 10 });
|
|
987
|
-
expect(descResults.length).
|
|
988
|
-
expect(descResults.map(({ messageCid }) => messageCid)).
|
|
984
|
+
expect(descResults.length).toBeLessThanOrEqual(10);
|
|
985
|
+
expect(descResults.map(({ messageCid }) => messageCid)).toEqual([...compareResults].reverse().slice(0, 10));
|
|
989
986
|
const descResultsAfterCursor = yield testIndex.query(tenant, filters, { sortProperty: 'val', sortDirection: SortDirection.Descending, cursor: IndexLevel.createCursorFromLastArrayItem(descResults, 'val') });
|
|
990
|
-
expect(descResultsAfterCursor.map(({ messageCid }) => messageCid)).
|
|
987
|
+
expect(descResultsAfterCursor.map(({ messageCid }) => messageCid)).toEqual([...compareResults].reverse().slice(10));
|
|
991
988
|
}));
|
|
992
989
|
});
|
|
993
990
|
});
|
|
994
991
|
});
|
|
995
992
|
describe('delete', () => {
|
|
996
|
-
|
|
993
|
+
beforeAll(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
997
994
|
testIndex = new IndexLevel({
|
|
998
995
|
createLevelDatabase,
|
|
999
996
|
location: 'TEST-INDEX',
|
|
@@ -1003,7 +1000,7 @@ describe('IndexLevel', () => {
|
|
|
1003
1000
|
beforeEach(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
1004
1001
|
yield testIndex.clear();
|
|
1005
1002
|
}));
|
|
1006
|
-
|
|
1003
|
+
afterAll(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
1007
1004
|
yield testIndex.close();
|
|
1008
1005
|
}));
|
|
1009
1006
|
it('purges indexes', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
@@ -1022,14 +1019,14 @@ describe('IndexLevel', () => {
|
|
|
1022
1019
|
yield testIndex.put(tenant, id1, doc1);
|
|
1023
1020
|
yield testIndex.put(tenant, id2, doc2);
|
|
1024
1021
|
let result = yield testIndex.query(tenant, [{ 'a': 'b', 'c': 'e' }], { sortProperty: 'id' });
|
|
1025
|
-
expect(result.length).
|
|
1026
|
-
expect(result.map(({ messageCid }) => messageCid)).
|
|
1022
|
+
expect(result.length).toBe(2);
|
|
1023
|
+
expect(result.map(({ messageCid }) => messageCid)).toContain(id1);
|
|
1027
1024
|
yield testIndex.delete(tenant, id1);
|
|
1028
1025
|
result = yield testIndex.query(tenant, [{ 'a': 'b', 'c': 'e' }], { sortProperty: 'id' });
|
|
1029
|
-
expect(result.length).
|
|
1026
|
+
expect(result.length).toBe(1);
|
|
1030
1027
|
yield testIndex.delete(tenant, id2);
|
|
1031
1028
|
const allKeys = yield ArrayUtility.fromAsyncGenerator(testIndex.db.keys());
|
|
1032
|
-
expect(allKeys.length).
|
|
1029
|
+
expect(allKeys.length).toBe(0);
|
|
1033
1030
|
}));
|
|
1034
1031
|
it('should not delete anything if aborted beforehand', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
1035
1032
|
const controller = new AbortController();
|
|
@@ -1044,11 +1041,11 @@ describe('IndexLevel', () => {
|
|
|
1044
1041
|
yield testIndex.delete(tenant, id, { signal: controller.signal });
|
|
1045
1042
|
}
|
|
1046
1043
|
catch (e) {
|
|
1047
|
-
expect(e).
|
|
1044
|
+
expect(e).toBe('reason');
|
|
1048
1045
|
}
|
|
1049
1046
|
const result = yield testIndex.query(tenant, [{ foo: 'bar' }], { sortProperty: 'id' });
|
|
1050
|
-
expect(result.length).
|
|
1051
|
-
expect(result.map(({ messageCid }) => messageCid)).
|
|
1047
|
+
expect(result.length).toBe(1);
|
|
1048
|
+
expect(result.map(({ messageCid }) => messageCid)).toContain(id);
|
|
1052
1049
|
}));
|
|
1053
1050
|
it('does nothing when attempting to purge key that does not exist', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
1054
1051
|
const controller = new AbortController();
|
|
@@ -1062,8 +1059,8 @@ describe('IndexLevel', () => {
|
|
|
1062
1059
|
// attempt purge an invalid id
|
|
1063
1060
|
yield testIndex.delete(tenant, 'invalidCid');
|
|
1064
1061
|
const result = yield testIndex.query(tenant, [{ foo: 'bar' }], { sortProperty: 'id' });
|
|
1065
|
-
expect(result.length).
|
|
1066
|
-
expect(result.map(({ messageCid }) => messageCid)).
|
|
1062
|
+
expect(result.length).toBe(1);
|
|
1063
|
+
expect(result.map(({ messageCid }) => messageCid)).toContain(id);
|
|
1067
1064
|
}));
|
|
1068
1065
|
});
|
|
1069
1066
|
describe('createCursorFromItem', () => {
|
|
@@ -1076,8 +1073,8 @@ describe('IndexLevel', () => {
|
|
|
1076
1073
|
sortPropertyArray: [1, 2, 3],
|
|
1077
1074
|
}
|
|
1078
1075
|
};
|
|
1079
|
-
expect(() => IndexLevel.createCursorFromItem(item, 'sortPropertyBool')).
|
|
1080
|
-
expect(() => IndexLevel.createCursorFromItem(item, 'sortPropertyArray')).
|
|
1076
|
+
expect(() => IndexLevel.createCursorFromItem(item, 'sortPropertyBool')).toThrow(DwnErrorCode.IndexInvalidCursorValueType);
|
|
1077
|
+
expect(() => IndexLevel.createCursorFromItem(item, 'sortPropertyArray')).toThrow(DwnErrorCode.IndexInvalidCursorValueType);
|
|
1081
1078
|
}));
|
|
1082
1079
|
it('throws if sort property is not defined within the IndexedItem', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
1083
1080
|
const item = {
|
|
@@ -1086,7 +1083,7 @@ describe('IndexLevel', () => {
|
|
|
1086
1083
|
sortProperty: 1234,
|
|
1087
1084
|
}
|
|
1088
1085
|
};
|
|
1089
|
-
expect(() => IndexLevel.createCursorFromItem(item, 'unknownProperty')).
|
|
1086
|
+
expect(() => IndexLevel.createCursorFromItem(item, 'unknownProperty')).toThrow(DwnErrorCode.IndexInvalidCursorSortProperty);
|
|
1090
1087
|
}));
|
|
1091
1088
|
it('returns numeric type cursor value', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
1092
1089
|
const item = {
|
|
@@ -1096,7 +1093,7 @@ describe('IndexLevel', () => {
|
|
|
1096
1093
|
}
|
|
1097
1094
|
};
|
|
1098
1095
|
const cursor = IndexLevel.createCursorFromItem(item, 'sortProperty');
|
|
1099
|
-
expect(cursor.value).
|
|
1096
|
+
expect(cursor.value).toBe(1234);
|
|
1100
1097
|
}));
|
|
1101
1098
|
it('returns string type cursor value', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
1102
1099
|
const item = {
|
|
@@ -1106,13 +1103,13 @@ describe('IndexLevel', () => {
|
|
|
1106
1103
|
}
|
|
1107
1104
|
};
|
|
1108
1105
|
const cursor = IndexLevel.createCursorFromItem(item, 'sortProperty');
|
|
1109
|
-
expect(cursor.value).
|
|
1106
|
+
expect(cursor.value).toBe('1234');
|
|
1110
1107
|
}));
|
|
1111
1108
|
});
|
|
1112
1109
|
describe('createCursorFromLastArrayItem', () => {
|
|
1113
1110
|
it('returns undefined if an empty array is provided', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
1114
1111
|
const cursor = IndexLevel.createCursorFromLastArrayItem([], 'someProperty');
|
|
1115
|
-
expect(cursor).
|
|
1112
|
+
expect(cursor).toBe(undefined);
|
|
1116
1113
|
}));
|
|
1117
1114
|
it('returns a PaginationCursor for the last item given a valid sort property', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
1118
1115
|
const items = [{
|
|
@@ -1131,78 +1128,431 @@ describe('IndexLevel', () => {
|
|
|
1131
1128
|
}
|
|
1132
1129
|
}];
|
|
1133
1130
|
const cursor = IndexLevel.createCursorFromLastArrayItem(items, 'date');
|
|
1134
|
-
expect(cursor === null || cursor === void 0 ? void 0 : cursor.messageCid).
|
|
1135
|
-
expect(cursor === null || cursor === void 0 ? void 0 : cursor.value).
|
|
1131
|
+
expect(cursor === null || cursor === void 0 ? void 0 : cursor.messageCid).toBe('cid-2'); // expect the cursor to equal the messageCid
|
|
1132
|
+
expect(cursor === null || cursor === void 0 ? void 0 : cursor.value).toBe('2023-12-14T11:22:33.000000Z');
|
|
1136
1133
|
}));
|
|
1137
1134
|
});
|
|
1138
1135
|
describe('encodeValue', () => {
|
|
1139
1136
|
it('should wrap string in quotes', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
1140
|
-
expect(IndexLevel.encodeValue('test')).
|
|
1137
|
+
expect(IndexLevel.encodeValue('test')).toBe(`"test"`);
|
|
1141
1138
|
}));
|
|
1142
1139
|
it('should return string encoded number using encodeNumberValue()', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
1143
|
-
expect(IndexLevel.encodeValue(10)).
|
|
1140
|
+
expect(IndexLevel.encodeValue(10)).toBe(IndexLevel.encodeNumberValue(10));
|
|
1144
1141
|
}));
|
|
1145
1142
|
it('should return stringified boolean', () => {
|
|
1146
|
-
expect(IndexLevel.encodeValue(true)).
|
|
1147
|
-
expect(IndexLevel.encodeValue(false)).
|
|
1143
|
+
expect(IndexLevel.encodeValue(true)).toBe('true');
|
|
1144
|
+
expect(IndexLevel.encodeValue(false)).toBe('false');
|
|
1148
1145
|
});
|
|
1149
1146
|
});
|
|
1150
1147
|
describe('encodeNumberValue', () => {
|
|
1151
1148
|
it('should encode positive digits and pad with leading zeros', () => {
|
|
1152
1149
|
const expectedLength = String(Number.MAX_SAFE_INTEGER).length; //16
|
|
1153
1150
|
const encoded = IndexLevel.encodeNumberValue(100);
|
|
1154
|
-
expect(encoded.length).
|
|
1155
|
-
expect(encoded).
|
|
1151
|
+
expect(encoded.length).toBe(expectedLength);
|
|
1152
|
+
expect(encoded).toBe('0000000000000100');
|
|
1156
1153
|
});
|
|
1157
1154
|
it('should encode negative digits as an offset with a prefix', () => {
|
|
1158
1155
|
const expectedPrefix = '!';
|
|
1159
1156
|
// expected length is maximum padding + the prefix.
|
|
1160
1157
|
const expectedLength = (expectedPrefix + String(Number.MAX_SAFE_INTEGER)).length; //17
|
|
1161
1158
|
const encoded = IndexLevel.encodeNumberValue(-100);
|
|
1162
|
-
expect(encoded.length).
|
|
1163
|
-
expect(encoded.length).
|
|
1164
|
-
expect(encoded).
|
|
1159
|
+
expect(encoded.length).toBe(String(Number.MIN_SAFE_INTEGER).length);
|
|
1160
|
+
expect(encoded.length).toBe(expectedLength);
|
|
1161
|
+
expect(encoded).toBe('!9007199254740891');
|
|
1165
1162
|
});
|
|
1166
1163
|
it('should encode digits to sort using lexicographical comparison', () => {
|
|
1167
1164
|
const digits = [-1000, -100, -10, 10, 100, 1000].sort((a, b) => a - b);
|
|
1168
1165
|
const encodedDigits = digits.map(d => IndexLevel.encodeNumberValue(d))
|
|
1169
1166
|
.sort((a, b) => lexicographicalCompare(a, b));
|
|
1170
|
-
digits.forEach((n, i) => expect(encodedDigits.at(i)).
|
|
1167
|
+
digits.forEach((n, i) => expect(encodedDigits.at(i)).toBe(IndexLevel.encodeNumberValue(n)));
|
|
1171
1168
|
});
|
|
1172
1169
|
});
|
|
1173
1170
|
describe('isFilterConcise', () => {
|
|
1174
1171
|
const queryOptionsWithCursor = { sortProperty: 'sort', cursor: { messageCid: 'messageCid', value: 'value' } };
|
|
1175
1172
|
const queryOptionsWithoutCursor = { sortProperty: 'sort' };
|
|
1176
1173
|
it('recordId is always concise', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
1177
|
-
expect(IndexLevel.isFilterConcise({ recordId: 'record-id' }, queryOptionsWithCursor)).
|
|
1178
|
-
expect(IndexLevel.isFilterConcise({ recordId: 'record-id' }, queryOptionsWithoutCursor)).
|
|
1174
|
+
expect(IndexLevel.isFilterConcise({ recordId: 'record-id' }, queryOptionsWithCursor)).toBe(true);
|
|
1175
|
+
expect(IndexLevel.isFilterConcise({ recordId: 'record-id' }, queryOptionsWithoutCursor)).toBe(true);
|
|
1179
1176
|
}));
|
|
1180
1177
|
it('other than if `recordId` exists, if a cursor exists it is never concise', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
1181
|
-
expect(IndexLevel.isFilterConcise({ schema: 'schema', contextId: 'contextId', parentId: 'parentId' }, queryOptionsWithCursor)).
|
|
1178
|
+
expect(IndexLevel.isFilterConcise({ schema: 'schema', contextId: 'contextId', parentId: 'parentId' }, queryOptionsWithCursor)).toBe(false);
|
|
1182
1179
|
// control
|
|
1183
|
-
expect(IndexLevel.isFilterConcise({ schema: 'schema', contextId: 'contextId', parentId: 'parentId' }, queryOptionsWithoutCursor)).
|
|
1184
|
-
expect(IndexLevel.isFilterConcise({ recordId: 'record-id' }, queryOptionsWithCursor)).
|
|
1180
|
+
expect(IndexLevel.isFilterConcise({ schema: 'schema', contextId: 'contextId', parentId: 'parentId' }, queryOptionsWithoutCursor)).toBe(true);
|
|
1181
|
+
expect(IndexLevel.isFilterConcise({ recordId: 'record-id' }, queryOptionsWithCursor)).toBe(true);
|
|
1185
1182
|
}));
|
|
1186
1183
|
it('if there is no cursor - protocolPath, contextId, parentId, or schema return a concise filter', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
1187
|
-
expect(IndexLevel.isFilterConcise({ protocolPath: 'protocolPath' }, queryOptionsWithoutCursor)).
|
|
1188
|
-
expect(IndexLevel.isFilterConcise({ protocolPath: 'protocolPath' }, queryOptionsWithCursor)).
|
|
1189
|
-
expect(IndexLevel.isFilterConcise({ contextId: 'contextId' }, queryOptionsWithoutCursor)).
|
|
1190
|
-
expect(IndexLevel.isFilterConcise({ contextId: 'contextId' }, queryOptionsWithCursor)).
|
|
1191
|
-
expect(IndexLevel.isFilterConcise({ contextId: 'parentId' }, queryOptionsWithoutCursor)).
|
|
1192
|
-
expect(IndexLevel.isFilterConcise({ contextId: 'parentId' }, queryOptionsWithCursor)).
|
|
1193
|
-
expect(IndexLevel.isFilterConcise({ contextId: 'schema' }, queryOptionsWithoutCursor)).
|
|
1194
|
-
expect(IndexLevel.isFilterConcise({ contextId: 'schema' }, queryOptionsWithCursor)).
|
|
1184
|
+
expect(IndexLevel.isFilterConcise({ protocolPath: 'protocolPath' }, queryOptionsWithoutCursor)).toBe(true);
|
|
1185
|
+
expect(IndexLevel.isFilterConcise({ protocolPath: 'protocolPath' }, queryOptionsWithCursor)).toBe(false); // control
|
|
1186
|
+
expect(IndexLevel.isFilterConcise({ contextId: 'contextId' }, queryOptionsWithoutCursor)).toBe(true);
|
|
1187
|
+
expect(IndexLevel.isFilterConcise({ contextId: 'contextId' }, queryOptionsWithCursor)).toBe(false); // control
|
|
1188
|
+
expect(IndexLevel.isFilterConcise({ contextId: 'parentId' }, queryOptionsWithoutCursor)).toBe(true);
|
|
1189
|
+
expect(IndexLevel.isFilterConcise({ contextId: 'parentId' }, queryOptionsWithCursor)).toBe(false); // control
|
|
1190
|
+
expect(IndexLevel.isFilterConcise({ contextId: 'schema' }, queryOptionsWithoutCursor)).toBe(true);
|
|
1191
|
+
expect(IndexLevel.isFilterConcise({ contextId: 'schema' }, queryOptionsWithCursor)).toBe(false); // control
|
|
1195
1192
|
}));
|
|
1196
1193
|
it('if there is no cursor, and it is not one of the conditions, return not concise', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
1197
|
-
expect(IndexLevel.isFilterConcise({ dataSize: { gt: 123 } }, queryOptionsWithoutCursor)).
|
|
1194
|
+
expect(IndexLevel.isFilterConcise({ dataSize: { gt: 123 } }, queryOptionsWithoutCursor)).toBe(false);
|
|
1198
1195
|
// control
|
|
1199
|
-
expect(IndexLevel.isFilterConcise({ schema: 'schema', contextId: 'contextId', parentId: 'parentId' }, queryOptionsWithoutCursor)).
|
|
1196
|
+
expect(IndexLevel.isFilterConcise({ schema: 'schema', contextId: 'contextId', parentId: 'parentId' }, queryOptionsWithoutCursor)).toBe(true);
|
|
1200
1197
|
}));
|
|
1201
1198
|
it('if protocol filter exists by itself it is not a concise filter', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
1202
|
-
expect(IndexLevel.isFilterConcise({ protocol: 'protocol' }, queryOptionsWithoutCursor)).
|
|
1199
|
+
expect(IndexLevel.isFilterConcise({ protocol: 'protocol' }, queryOptionsWithoutCursor)).toBe(false);
|
|
1203
1200
|
// control
|
|
1204
|
-
expect(IndexLevel.isFilterConcise({ protocol: 'protocol', protocolPath: 'path/to' }, queryOptionsWithoutCursor)).
|
|
1201
|
+
expect(IndexLevel.isFilterConcise({ protocol: 'protocol', protocolPath: 'path/to' }, queryOptionsWithoutCursor)).toBe(true);
|
|
1202
|
+
}));
|
|
1203
|
+
});
|
|
1204
|
+
describe('compound indexes', () => {
|
|
1205
|
+
const compoundIndexes = [
|
|
1206
|
+
{
|
|
1207
|
+
name: 'protocol-protocolPath-messageTimestamp',
|
|
1208
|
+
properties: ['protocol', 'protocolPath'],
|
|
1209
|
+
sortProperty: 'messageTimestamp',
|
|
1210
|
+
},
|
|
1211
|
+
{
|
|
1212
|
+
name: 'schema-dateCreated',
|
|
1213
|
+
properties: ['schema'],
|
|
1214
|
+
sortProperty: 'dateCreated',
|
|
1215
|
+
},
|
|
1216
|
+
];
|
|
1217
|
+
let compoundIndex;
|
|
1218
|
+
const compoundTenant = 'did:alice:compound-test';
|
|
1219
|
+
beforeAll(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
1220
|
+
compoundIndex = new IndexLevel({
|
|
1221
|
+
createLevelDatabase,
|
|
1222
|
+
location: 'TEST-COMPOUND-INDEX',
|
|
1223
|
+
compoundIndexes: compoundIndexes,
|
|
1224
|
+
});
|
|
1225
|
+
yield compoundIndex.open();
|
|
1226
|
+
}));
|
|
1227
|
+
beforeEach(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
1228
|
+
yield compoundIndex.clear();
|
|
1229
|
+
}));
|
|
1230
|
+
afterAll(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
1231
|
+
yield compoundIndex.close();
|
|
1205
1232
|
}));
|
|
1233
|
+
describe('put and delete lifecycle', () => {
|
|
1234
|
+
it('should create compound index entries during put', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
1235
|
+
const id = uuid();
|
|
1236
|
+
yield compoundIndex.put(compoundTenant, id, {
|
|
1237
|
+
protocol: 'https://protocol.xyz',
|
|
1238
|
+
protocolPath: 'chat/message',
|
|
1239
|
+
messageTimestamp: '2024-01-15T10:00:00.000000Z',
|
|
1240
|
+
schema: 'https://schema.org/Message',
|
|
1241
|
+
dateCreated: '2024-01-15T10:00:00.000000Z',
|
|
1242
|
+
});
|
|
1243
|
+
// query using compound index (protocol + protocolPath sorted by messageTimestamp)
|
|
1244
|
+
const results = yield compoundIndex.query(compoundTenant, [{ protocol: 'https://protocol.xyz', protocolPath: 'chat/message' }], { sortProperty: 'messageTimestamp' });
|
|
1245
|
+
expect(results.length).toBe(1);
|
|
1246
|
+
expect(results[0].messageCid).toBe(id);
|
|
1247
|
+
}));
|
|
1248
|
+
it('should delete compound index entries during delete', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
1249
|
+
const id = uuid();
|
|
1250
|
+
yield compoundIndex.put(compoundTenant, id, {
|
|
1251
|
+
protocol: 'https://protocol.xyz',
|
|
1252
|
+
protocolPath: 'chat/message',
|
|
1253
|
+
messageTimestamp: '2024-01-15T10:00:00.000000Z',
|
|
1254
|
+
schema: 'https://schema.org/Message',
|
|
1255
|
+
dateCreated: '2024-01-15T10:00:00.000000Z',
|
|
1256
|
+
});
|
|
1257
|
+
// verify it exists
|
|
1258
|
+
let results = yield compoundIndex.query(compoundTenant, [{ protocol: 'https://protocol.xyz', protocolPath: 'chat/message' }], { sortProperty: 'messageTimestamp' });
|
|
1259
|
+
expect(results.length).toBe(1);
|
|
1260
|
+
// delete
|
|
1261
|
+
yield compoundIndex.delete(compoundTenant, id);
|
|
1262
|
+
// verify compound index entries are removed
|
|
1263
|
+
results = yield compoundIndex.query(compoundTenant, [{ protocol: 'https://protocol.xyz', protocolPath: 'chat/message' }], { sortProperty: 'messageTimestamp' });
|
|
1264
|
+
expect(results.length).toBe(0);
|
|
1265
|
+
}));
|
|
1266
|
+
it('should skip compound index entries when required properties are missing', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
1267
|
+
const id = uuid();
|
|
1268
|
+
// only has schema, not protocol+protocolPath
|
|
1269
|
+
yield compoundIndex.put(compoundTenant, id, {
|
|
1270
|
+
schema: 'https://schema.org/Message',
|
|
1271
|
+
dateCreated: '2024-01-15T10:00:00.000000Z',
|
|
1272
|
+
});
|
|
1273
|
+
// the protocol+protocolPath compound index should not have entries
|
|
1274
|
+
// query via the schema compound index should still work
|
|
1275
|
+
const schemaResults = yield compoundIndex.query(compoundTenant, [{ schema: 'https://schema.org/Message' }], { sortProperty: 'dateCreated' });
|
|
1276
|
+
expect(schemaResults.length).toBe(1);
|
|
1277
|
+
expect(schemaResults[0].messageCid).toBe(id);
|
|
1278
|
+
}));
|
|
1279
|
+
});
|
|
1280
|
+
describe('queryWithCompoundIndex()', () => {
|
|
1281
|
+
it('should return results sorted ascending by the sort property', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
1282
|
+
const ids = ['msg-c', 'msg-a', 'msg-b'];
|
|
1283
|
+
const timestamps = [
|
|
1284
|
+
'2024-01-15T12:00:00.000000Z',
|
|
1285
|
+
'2024-01-15T10:00:00.000000Z',
|
|
1286
|
+
'2024-01-15T11:00:00.000000Z',
|
|
1287
|
+
];
|
|
1288
|
+
for (let i = 0; i < ids.length; i++) {
|
|
1289
|
+
yield compoundIndex.put(compoundTenant, ids[i], {
|
|
1290
|
+
protocol: 'https://proto.xyz',
|
|
1291
|
+
protocolPath: 'thread/post',
|
|
1292
|
+
messageTimestamp: timestamps[i],
|
|
1293
|
+
});
|
|
1294
|
+
}
|
|
1295
|
+
const results = yield compoundIndex.query(compoundTenant, [{ protocol: 'https://proto.xyz', protocolPath: 'thread/post' }], { sortProperty: 'messageTimestamp' });
|
|
1296
|
+
expect(results.length).toBe(3);
|
|
1297
|
+
expect(results.map(r => r.messageCid)).toEqual(['msg-a', 'msg-b', 'msg-c']);
|
|
1298
|
+
}));
|
|
1299
|
+
it('should return results sorted descending by the sort property', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
1300
|
+
const ids = ['msg-c', 'msg-a', 'msg-b'];
|
|
1301
|
+
const timestamps = [
|
|
1302
|
+
'2024-01-15T12:00:00.000000Z',
|
|
1303
|
+
'2024-01-15T10:00:00.000000Z',
|
|
1304
|
+
'2024-01-15T11:00:00.000000Z',
|
|
1305
|
+
];
|
|
1306
|
+
for (let i = 0; i < ids.length; i++) {
|
|
1307
|
+
yield compoundIndex.put(compoundTenant, ids[i], {
|
|
1308
|
+
protocol: 'https://proto.xyz',
|
|
1309
|
+
protocolPath: 'thread/post',
|
|
1310
|
+
messageTimestamp: timestamps[i],
|
|
1311
|
+
});
|
|
1312
|
+
}
|
|
1313
|
+
const results = yield compoundIndex.query(compoundTenant, [{ protocol: 'https://proto.xyz', protocolPath: 'thread/post' }], { sortProperty: 'messageTimestamp', sortDirection: SortDirection.Descending });
|
|
1314
|
+
expect(results.length).toBe(3);
|
|
1315
|
+
expect(results.map(r => r.messageCid)).toEqual(['msg-c', 'msg-b', 'msg-a']);
|
|
1316
|
+
}));
|
|
1317
|
+
it('should support limit', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
1318
|
+
for (let i = 0; i < 5; i++) {
|
|
1319
|
+
yield compoundIndex.put(compoundTenant, `msg-${i}`, {
|
|
1320
|
+
protocol: 'https://proto.xyz',
|
|
1321
|
+
protocolPath: 'items',
|
|
1322
|
+
messageTimestamp: `2024-01-15T1${i}:00:00.000000Z`,
|
|
1323
|
+
});
|
|
1324
|
+
}
|
|
1325
|
+
const results = yield compoundIndex.query(compoundTenant, [{ protocol: 'https://proto.xyz', protocolPath: 'items' }], { sortProperty: 'messageTimestamp', limit: 3 });
|
|
1326
|
+
expect(results.length).toBe(3);
|
|
1327
|
+
expect(results.map(r => r.messageCid)).toEqual(['msg-0', 'msg-1', 'msg-2']);
|
|
1328
|
+
}));
|
|
1329
|
+
it('should support cursor pagination ascending', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
1330
|
+
for (let i = 0; i < 6; i++) {
|
|
1331
|
+
yield compoundIndex.put(compoundTenant, `msg-${i}`, {
|
|
1332
|
+
protocol: 'https://proto.xyz',
|
|
1333
|
+
protocolPath: 'items',
|
|
1334
|
+
messageTimestamp: `2024-01-15T1${i}:00:00.000000Z`,
|
|
1335
|
+
});
|
|
1336
|
+
}
|
|
1337
|
+
// first page
|
|
1338
|
+
const page1 = yield compoundIndex.query(compoundTenant, [{ protocol: 'https://proto.xyz', protocolPath: 'items' }], { sortProperty: 'messageTimestamp', limit: 3 });
|
|
1339
|
+
expect(page1.length).toBe(3);
|
|
1340
|
+
expect(page1.map(r => r.messageCid)).toEqual(['msg-0', 'msg-1', 'msg-2']);
|
|
1341
|
+
// second page using cursor
|
|
1342
|
+
const cursor = IndexLevel.createCursorFromLastArrayItem(page1, 'messageTimestamp');
|
|
1343
|
+
const page2 = yield compoundIndex.query(compoundTenant, [{ protocol: 'https://proto.xyz', protocolPath: 'items' }], { sortProperty: 'messageTimestamp', cursor });
|
|
1344
|
+
expect(page2.length).toBe(3);
|
|
1345
|
+
expect(page2.map(r => r.messageCid)).toEqual(['msg-3', 'msg-4', 'msg-5']);
|
|
1346
|
+
}));
|
|
1347
|
+
it('should support cursor pagination descending', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
1348
|
+
for (let i = 0; i < 6; i++) {
|
|
1349
|
+
yield compoundIndex.put(compoundTenant, `msg-${i}`, {
|
|
1350
|
+
protocol: 'https://proto.xyz',
|
|
1351
|
+
protocolPath: 'items',
|
|
1352
|
+
messageTimestamp: `2024-01-15T1${i}:00:00.000000Z`,
|
|
1353
|
+
});
|
|
1354
|
+
}
|
|
1355
|
+
// first page descending
|
|
1356
|
+
const page1 = yield compoundIndex.query(compoundTenant, [{ protocol: 'https://proto.xyz', protocolPath: 'items' }], { sortProperty: 'messageTimestamp', sortDirection: SortDirection.Descending, limit: 3 });
|
|
1357
|
+
expect(page1.length).toBe(3);
|
|
1358
|
+
expect(page1.map(r => r.messageCid)).toEqual(['msg-5', 'msg-4', 'msg-3']);
|
|
1359
|
+
// second page descending using cursor
|
|
1360
|
+
const cursor = IndexLevel.createCursorFromLastArrayItem(page1, 'messageTimestamp');
|
|
1361
|
+
const page2 = yield compoundIndex.query(compoundTenant, [{ protocol: 'https://proto.xyz', protocolPath: 'items' }], { sortProperty: 'messageTimestamp', sortDirection: SortDirection.Descending, cursor });
|
|
1362
|
+
expect(page2.length).toBe(3);
|
|
1363
|
+
expect(page2.map(r => r.messageCid)).toEqual(['msg-2', 'msg-1', 'msg-0']);
|
|
1364
|
+
}));
|
|
1365
|
+
it('should verify residual filter properties in memory', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
1366
|
+
// insert records with same protocol+protocolPath but different 'published' values
|
|
1367
|
+
for (let i = 0; i < 4; i++) {
|
|
1368
|
+
yield compoundIndex.put(compoundTenant, `msg-${i}`, {
|
|
1369
|
+
protocol: 'https://proto.xyz',
|
|
1370
|
+
protocolPath: 'items',
|
|
1371
|
+
messageTimestamp: `2024-01-15T1${i}:00:00.000000Z`,
|
|
1372
|
+
published: i % 2 === 0, // msg-0: true, msg-1: false, msg-2: true, msg-3: false
|
|
1373
|
+
});
|
|
1374
|
+
}
|
|
1375
|
+
// compound index covers protocol+protocolPath+messageTimestamp but NOT published
|
|
1376
|
+
// published should be verified as a residual filter
|
|
1377
|
+
const results = yield compoundIndex.query(compoundTenant, [{ protocol: 'https://proto.xyz', protocolPath: 'items', published: true }], { sortProperty: 'messageTimestamp' });
|
|
1378
|
+
expect(results.length).toBe(2);
|
|
1379
|
+
expect(results.map(r => r.messageCid)).toEqual(['msg-0', 'msg-2']);
|
|
1380
|
+
}));
|
|
1381
|
+
it('should only return results matching the specific filter values', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
1382
|
+
// insert records with different protocol paths
|
|
1383
|
+
yield compoundIndex.put(compoundTenant, 'msg-1', {
|
|
1384
|
+
protocol: 'https://proto.xyz',
|
|
1385
|
+
protocolPath: 'thread/post',
|
|
1386
|
+
messageTimestamp: '2024-01-15T10:00:00.000000Z',
|
|
1387
|
+
});
|
|
1388
|
+
yield compoundIndex.put(compoundTenant, 'msg-2', {
|
|
1389
|
+
protocol: 'https://proto.xyz',
|
|
1390
|
+
protocolPath: 'thread/reply',
|
|
1391
|
+
messageTimestamp: '2024-01-15T11:00:00.000000Z',
|
|
1392
|
+
});
|
|
1393
|
+
yield compoundIndex.put(compoundTenant, 'msg-3', {
|
|
1394
|
+
protocol: 'https://other.xyz',
|
|
1395
|
+
protocolPath: 'thread/post',
|
|
1396
|
+
messageTimestamp: '2024-01-15T12:00:00.000000Z',
|
|
1397
|
+
});
|
|
1398
|
+
// query for only protocol.xyz + thread/post
|
|
1399
|
+
const results = yield compoundIndex.query(compoundTenant, [{ protocol: 'https://proto.xyz', protocolPath: 'thread/post' }], { sortProperty: 'messageTimestamp' });
|
|
1400
|
+
expect(results.length).toBe(1);
|
|
1401
|
+
expect(results[0].messageCid).toBe('msg-1');
|
|
1402
|
+
}));
|
|
1403
|
+
it('should fall back to non-compound strategy for OR (multi-filter) queries', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
1404
|
+
yield compoundIndex.put(compoundTenant, 'msg-1', {
|
|
1405
|
+
protocol: 'https://proto.xyz',
|
|
1406
|
+
protocolPath: 'thread/post',
|
|
1407
|
+
messageTimestamp: '2024-01-15T10:00:00.000000Z',
|
|
1408
|
+
});
|
|
1409
|
+
yield compoundIndex.put(compoundTenant, 'msg-2', {
|
|
1410
|
+
protocol: 'https://proto.xyz',
|
|
1411
|
+
protocolPath: 'thread/reply',
|
|
1412
|
+
messageTimestamp: '2024-01-15T11:00:00.000000Z',
|
|
1413
|
+
});
|
|
1414
|
+
// OR queries (multiple filters) should still work via fallback strategies
|
|
1415
|
+
const results = yield compoundIndex.query(compoundTenant, [
|
|
1416
|
+
{ protocol: 'https://proto.xyz', protocolPath: 'thread/post' },
|
|
1417
|
+
{ protocol: 'https://proto.xyz', protocolPath: 'thread/reply' },
|
|
1418
|
+
], { sortProperty: 'messageTimestamp' });
|
|
1419
|
+
expect(results.length).toBe(2);
|
|
1420
|
+
}));
|
|
1421
|
+
it('should prefer the compound index with the most properties', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
1422
|
+
// both compound indexes could potentially match a query with schema + dateCreated
|
|
1423
|
+
// but only the schema-dateCreated one actually applies
|
|
1424
|
+
// also, the protocol-protocolPath-messageTimestamp index should be preferred over
|
|
1425
|
+
// a hypothetical single-property index when both protocol and protocolPath are present
|
|
1426
|
+
yield compoundIndex.put(compoundTenant, 'msg-1', {
|
|
1427
|
+
protocol: 'https://proto.xyz',
|
|
1428
|
+
protocolPath: 'items',
|
|
1429
|
+
messageTimestamp: '2024-01-15T10:00:00.000000Z',
|
|
1430
|
+
schema: 'https://schema.org/Item',
|
|
1431
|
+
dateCreated: '2024-01-15T10:00:00.000000Z',
|
|
1432
|
+
});
|
|
1433
|
+
// query using schema compound index
|
|
1434
|
+
const schemaResults = yield compoundIndex.query(compoundTenant, [{ schema: 'https://schema.org/Item' }], { sortProperty: 'dateCreated' });
|
|
1435
|
+
expect(schemaResults.length).toBe(1);
|
|
1436
|
+
expect(schemaResults[0].messageCid).toBe('msg-1');
|
|
1437
|
+
// query using protocol+protocolPath compound index
|
|
1438
|
+
const protocolResults = yield compoundIndex.query(compoundTenant, [{ protocol: 'https://proto.xyz', protocolPath: 'items' }], { sortProperty: 'messageTimestamp' });
|
|
1439
|
+
expect(protocolResults.length).toBe(1);
|
|
1440
|
+
expect(protocolResults[0].messageCid).toBe('msg-1');
|
|
1441
|
+
}));
|
|
1442
|
+
it('should not use compound index when sort property does not match', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
1443
|
+
yield compoundIndex.put(compoundTenant, 'msg-1', {
|
|
1444
|
+
protocol: 'https://proto.xyz',
|
|
1445
|
+
protocolPath: 'items',
|
|
1446
|
+
messageTimestamp: '2024-01-15T10:00:00.000000Z',
|
|
1447
|
+
schema: 'https://schema.org/Item',
|
|
1448
|
+
dateCreated: '2024-01-15T10:00:00.000000Z',
|
|
1449
|
+
});
|
|
1450
|
+
// query with protocol+protocolPath but sort by dateCreated (not messageTimestamp)
|
|
1451
|
+
// this should NOT use the protocol-protocolPath-messageTimestamp compound index
|
|
1452
|
+
// it should still return correct results via fallback strategy
|
|
1453
|
+
const results = yield compoundIndex.query(compoundTenant, [{ protocol: 'https://proto.xyz', protocolPath: 'items' }], { sortProperty: 'dateCreated' });
|
|
1454
|
+
expect(results.length).toBe(1);
|
|
1455
|
+
}));
|
|
1456
|
+
});
|
|
1457
|
+
describe('count()', () => {
|
|
1458
|
+
it('should count items matching a compound index filter', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
1459
|
+
for (let i = 0; i < 10; i++) {
|
|
1460
|
+
yield compoundIndex.put(compoundTenant, `msg-${i}`, {
|
|
1461
|
+
protocol: 'https://proto.xyz',
|
|
1462
|
+
protocolPath: 'items',
|
|
1463
|
+
messageTimestamp: `2024-01-15T1${i}:00:00.000000Z`,
|
|
1464
|
+
});
|
|
1465
|
+
}
|
|
1466
|
+
// add some non-matching records
|
|
1467
|
+
for (let i = 0; i < 5; i++) {
|
|
1468
|
+
yield compoundIndex.put(compoundTenant, `other-${i}`, {
|
|
1469
|
+
protocol: 'https://other.xyz',
|
|
1470
|
+
protocolPath: 'items',
|
|
1471
|
+
messageTimestamp: `2024-01-15T1${i}:00:00.000000Z`,
|
|
1472
|
+
});
|
|
1473
|
+
}
|
|
1474
|
+
const count = yield compoundIndex.count(compoundTenant, [{ protocol: 'https://proto.xyz', protocolPath: 'items' }], { sortProperty: 'messageTimestamp' });
|
|
1475
|
+
expect(count).toBe(10);
|
|
1476
|
+
}));
|
|
1477
|
+
it('should count items with residual filter verification', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
1478
|
+
for (let i = 0; i < 6; i++) {
|
|
1479
|
+
yield compoundIndex.put(compoundTenant, `msg-${i}`, {
|
|
1480
|
+
protocol: 'https://proto.xyz',
|
|
1481
|
+
protocolPath: 'items',
|
|
1482
|
+
messageTimestamp: `2024-01-15T1${i}:00:00.000000Z`,
|
|
1483
|
+
published: i % 2 === 0, // msg-0: true, msg-1: false, msg-2: true, msg-3: false, msg-4: true, msg-5: false
|
|
1484
|
+
});
|
|
1485
|
+
}
|
|
1486
|
+
const count = yield compoundIndex.count(compoundTenant, [{ protocol: 'https://proto.xyz', protocolPath: 'items', published: true }], { sortProperty: 'messageTimestamp' });
|
|
1487
|
+
expect(count).toBe(3); // msg-0, msg-2, msg-4
|
|
1488
|
+
}));
|
|
1489
|
+
it('should return 0 when no items match', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
1490
|
+
yield compoundIndex.put(compoundTenant, 'msg-1', {
|
|
1491
|
+
protocol: 'https://proto.xyz',
|
|
1492
|
+
protocolPath: 'items',
|
|
1493
|
+
messageTimestamp: '2024-01-15T10:00:00.000000Z',
|
|
1494
|
+
});
|
|
1495
|
+
const count = yield compoundIndex.count(compoundTenant, [{ protocol: 'https://nonexistent.xyz', protocolPath: 'items' }], { sortProperty: 'messageTimestamp' });
|
|
1496
|
+
expect(count).toBe(0);
|
|
1497
|
+
}));
|
|
1498
|
+
it('should fall back to full query for non-compound-index filters', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
1499
|
+
for (let i = 0; i < 4; i++) {
|
|
1500
|
+
yield compoundIndex.put(compoundTenant, `msg-${i}`, {
|
|
1501
|
+
protocol: 'https://proto.xyz',
|
|
1502
|
+
protocolPath: 'items',
|
|
1503
|
+
messageTimestamp: `2024-01-15T1${i}:00:00.000000Z`,
|
|
1504
|
+
published: i < 2,
|
|
1505
|
+
});
|
|
1506
|
+
}
|
|
1507
|
+
// filter by 'published' alone — no compound index covers this
|
|
1508
|
+
const count = yield compoundIndex.count(compoundTenant, [{ published: true }], { sortProperty: 'messageTimestamp' });
|
|
1509
|
+
expect(count).toBe(2);
|
|
1510
|
+
}));
|
|
1511
|
+
it('should count correctly with OR (multi-filter) queries', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
1512
|
+
yield compoundIndex.put(compoundTenant, 'msg-1', {
|
|
1513
|
+
protocol: 'https://proto.xyz',
|
|
1514
|
+
protocolPath: 'thread/post',
|
|
1515
|
+
messageTimestamp: '2024-01-15T10:00:00.000000Z',
|
|
1516
|
+
});
|
|
1517
|
+
yield compoundIndex.put(compoundTenant, 'msg-2', {
|
|
1518
|
+
protocol: 'https://proto.xyz',
|
|
1519
|
+
protocolPath: 'thread/reply',
|
|
1520
|
+
messageTimestamp: '2024-01-15T11:00:00.000000Z',
|
|
1521
|
+
});
|
|
1522
|
+
yield compoundIndex.put(compoundTenant, 'msg-3', {
|
|
1523
|
+
protocol: 'https://other.xyz',
|
|
1524
|
+
protocolPath: 'thread/post',
|
|
1525
|
+
messageTimestamp: '2024-01-15T12:00:00.000000Z',
|
|
1526
|
+
});
|
|
1527
|
+
// OR query — compound index can't serve this, falls back
|
|
1528
|
+
const count = yield compoundIndex.count(compoundTenant, [
|
|
1529
|
+
{ protocol: 'https://proto.xyz', protocolPath: 'thread/post' },
|
|
1530
|
+
{ protocol: 'https://proto.xyz', protocolPath: 'thread/reply' },
|
|
1531
|
+
], { sortProperty: 'messageTimestamp' });
|
|
1532
|
+
expect(count).toBe(2);
|
|
1533
|
+
}));
|
|
1534
|
+
});
|
|
1535
|
+
describe('query() dispatch selects compound index when available', () => {
|
|
1536
|
+
it('should use compound index for matching single-filter queries with cursor', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
1537
|
+
// compound indexes support cursors natively, unlike in-memory paging
|
|
1538
|
+
// which would normally reject a cursor with "concise" filters
|
|
1539
|
+
for (let i = 0; i < 6; i++) {
|
|
1540
|
+
yield compoundIndex.put(compoundTenant, `msg-${i}`, {
|
|
1541
|
+
schema: 'https://schema.org/Item',
|
|
1542
|
+
dateCreated: `2024-01-15T1${i}:00:00.000000Z`,
|
|
1543
|
+
});
|
|
1544
|
+
}
|
|
1545
|
+
// first page
|
|
1546
|
+
const page1 = yield compoundIndex.query(compoundTenant, [{ schema: 'https://schema.org/Item' }], { sortProperty: 'dateCreated', limit: 3 });
|
|
1547
|
+
expect(page1.length).toBe(3);
|
|
1548
|
+
expect(page1.map(r => r.messageCid)).toEqual(['msg-0', 'msg-1', 'msg-2']);
|
|
1549
|
+
// second page with cursor — this should still use the compound index
|
|
1550
|
+
const cursor = IndexLevel.createCursorFromLastArrayItem(page1, 'dateCreated');
|
|
1551
|
+
const page2 = yield compoundIndex.query(compoundTenant, [{ schema: 'https://schema.org/Item' }], { sortProperty: 'dateCreated', cursor });
|
|
1552
|
+
expect(page2.length).toBe(3);
|
|
1553
|
+
expect(page2.map(r => r.messageCid)).toEqual(['msg-3', 'msg-4', 'msg-5']);
|
|
1554
|
+
}));
|
|
1555
|
+
});
|
|
1206
1556
|
});
|
|
1207
1557
|
});
|
|
1208
1558
|
//# sourceMappingURL=index-level.spec.js.map
|