@enbox/dwn-sdk-js 0.0.6 → 0.0.8
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/dist/browser.mjs +8 -8
- package/dist/browser.mjs.map +4 -4
- package/dist/esm/generated/precompiled-validators.js +762 -911
- package/dist/esm/generated/precompiled-validators.js.map +1 -1
- package/dist/esm/src/core/abstract-message.js +4 -0
- package/dist/esm/src/core/abstract-message.js.map +1 -1
- package/dist/esm/src/core/auth.js +22 -33
- package/dist/esm/src/core/auth.js.map +1 -1
- package/dist/esm/src/core/constants.js +11 -0
- package/dist/esm/src/core/constants.js.map +1 -0
- package/dist/esm/src/core/core-protocol.js +44 -0
- package/dist/esm/src/core/core-protocol.js.map +1 -0
- package/dist/esm/src/core/dwn-constant.js +7 -7
- package/dist/esm/src/core/dwn-constant.js.map +1 -1
- package/dist/esm/src/core/dwn-error.js +10 -12
- package/dist/esm/src/core/dwn-error.js.map +1 -1
- package/dist/esm/src/core/grant-authorization.js +50 -52
- package/dist/esm/src/core/grant-authorization.js.map +1 -1
- package/dist/esm/src/core/message.js +85 -116
- package/dist/esm/src/core/message.js.map +1 -1
- package/dist/esm/src/core/messages-grant-authorization.js +63 -78
- package/dist/esm/src/core/messages-grant-authorization.js.map +1 -1
- package/dist/esm/src/core/protocol-authorization-action.js +266 -0
- package/dist/esm/src/core/protocol-authorization-action.js.map +1 -0
- package/dist/esm/src/core/protocol-authorization-validation.js +321 -0
- package/dist/esm/src/core/protocol-authorization-validation.js.map +1 -0
- package/dist/esm/src/core/protocol-authorization.js +144 -741
- package/dist/esm/src/core/protocol-authorization.js.map +1 -1
- package/dist/esm/src/core/protocols-grant-authorization.js +24 -38
- package/dist/esm/src/core/protocols-grant-authorization.js.map +1 -1
- package/dist/esm/src/core/record-chain.js +64 -0
- package/dist/esm/src/core/record-chain.js.map +1 -0
- package/dist/esm/src/core/records-grant-authorization.js +53 -72
- package/dist/esm/src/core/records-grant-authorization.js.map +1 -1
- package/dist/esm/src/core/resumable-task-manager.js +50 -65
- package/dist/esm/src/core/resumable-task-manager.js.map +1 -1
- package/dist/esm/src/core/tenant-gate.js +2 -13
- package/dist/esm/src/core/tenant-gate.js.map +1 -1
- package/dist/esm/src/dwn.js +108 -101
- package/dist/esm/src/dwn.js.map +1 -1
- package/dist/esm/src/event-stream/event-emitter-event-log.js +204 -0
- package/dist/esm/src/event-stream/event-emitter-event-log.js.map +1 -0
- package/dist/esm/src/handlers/messages-read.js +67 -81
- package/dist/esm/src/handlers/messages-read.js.map +1 -1
- package/dist/esm/src/handlers/messages-subscribe.js +51 -63
- package/dist/esm/src/handlers/messages-subscribe.js.map +1 -1
- package/dist/esm/src/handlers/messages-sync.js +75 -89
- package/dist/esm/src/handlers/messages-sync.js.map +1 -1
- package/dist/esm/src/handlers/protocols-configure.js +153 -163
- package/dist/esm/src/handlers/protocols-configure.js.map +1 -1
- package/dist/esm/src/handlers/protocols-query.js +52 -55
- package/dist/esm/src/handlers/protocols-query.js.map +1 -1
- package/dist/esm/src/handlers/records-count.js +97 -85
- package/dist/esm/src/handlers/records-count.js.map +1 -1
- package/dist/esm/src/handlers/records-delete.js +75 -93
- package/dist/esm/src/handlers/records-delete.js.map +1 -1
- package/dist/esm/src/handlers/records-query.js +116 -105
- package/dist/esm/src/handlers/records-query.js.map +1 -1
- package/dist/esm/src/handlers/records-read.js +130 -132
- package/dist/esm/src/handlers/records-read.js.map +1 -1
- package/dist/esm/src/handlers/records-subscribe.js +164 -104
- package/dist/esm/src/handlers/records-subscribe.js.map +1 -1
- package/dist/esm/src/handlers/records-write.js +213 -280
- package/dist/esm/src/handlers/records-write.js.map +1 -1
- package/dist/esm/src/index.js +5 -2
- package/dist/esm/src/index.js.map +1 -1
- package/dist/esm/src/interfaces/messages-read.js +24 -32
- package/dist/esm/src/interfaces/messages-read.js.map +1 -1
- package/dist/esm/src/interfaces/messages-subscribe.js +28 -41
- package/dist/esm/src/interfaces/messages-subscribe.js.map +1 -1
- package/dist/esm/src/interfaces/messages-sync.js +26 -40
- package/dist/esm/src/interfaces/messages-sync.js.map +1 -1
- package/dist/esm/src/interfaces/protocols-configure.js +87 -65
- package/dist/esm/src/interfaces/protocols-configure.js.map +1 -1
- package/dist/esm/src/interfaces/protocols-query.js +55 -68
- package/dist/esm/src/interfaces/protocols-query.js.map +1 -1
- package/dist/esm/src/interfaces/records-count.js +50 -66
- package/dist/esm/src/interfaces/records-count.js.map +1 -1
- package/dist/esm/src/interfaces/records-delete.js +45 -55
- package/dist/esm/src/interfaces/records-delete.js.map +1 -1
- package/dist/esm/src/interfaces/records-query.js +60 -76
- package/dist/esm/src/interfaces/records-query.js.map +1 -1
- package/dist/esm/src/interfaces/records-read.js +51 -67
- package/dist/esm/src/interfaces/records-read.js.map +1 -1
- package/dist/esm/src/interfaces/records-subscribe.js +53 -68
- package/dist/esm/src/interfaces/records-subscribe.js.map +1 -1
- package/dist/esm/src/interfaces/records-write-query.js +102 -0
- package/dist/esm/src/interfaces/records-write-query.js.map +1 -0
- package/dist/esm/src/interfaces/records-write-signing.js +81 -0
- package/dist/esm/src/interfaces/records-write-signing.js.map +1 -0
- package/dist/esm/src/interfaces/records-write.js +396 -610
- package/dist/esm/src/interfaces/records-write.js.map +1 -1
- package/dist/esm/src/jose/algorithms/signing/ed25519.js +10 -19
- package/dist/esm/src/jose/algorithms/signing/ed25519.js.map +1 -1
- package/dist/esm/src/jose/jws/general/builder.js +23 -35
- package/dist/esm/src/jose/jws/general/builder.js.map +1 -1
- package/dist/esm/src/jose/jws/general/verifier.js +56 -69
- package/dist/esm/src/jose/jws/general/verifier.js.map +1 -1
- package/dist/esm/src/protocols/permission-grant.js +43 -14
- package/dist/esm/src/protocols/permission-grant.js.map +1 -1
- package/dist/esm/src/protocols/permission-request.js +28 -14
- package/dist/esm/src/protocols/permission-request.js.map +1 -1
- package/dist/esm/src/protocols/permissions.js +325 -227
- package/dist/esm/src/protocols/permissions.js.map +1 -1
- package/dist/esm/src/smt/smt-store-level.js +42 -64
- package/dist/esm/src/smt/smt-store-level.js.map +1 -1
- package/dist/esm/src/smt/smt-store-memory.js +19 -45
- package/dist/esm/src/smt/smt-store-memory.js.map +1 -1
- package/dist/esm/src/smt/smt-utils.js +28 -45
- package/dist/esm/src/smt/smt-utils.js.map +1 -1
- package/dist/esm/src/smt/sparse-merkle-tree.js +426 -471
- package/dist/esm/src/smt/sparse-merkle-tree.js.map +1 -1
- package/dist/esm/src/state-index/state-index-level.js +113 -150
- package/dist/esm/src/state-index/state-index-level.js.map +1 -1
- package/dist/esm/src/store/blockstore-level.js +54 -156
- package/dist/esm/src/store/blockstore-level.js.map +1 -1
- package/dist/esm/src/store/blockstore-mock.js +48 -153
- package/dist/esm/src/store/blockstore-mock.js.map +1 -1
- package/dist/esm/src/store/data-store-level.js +137 -100
- package/dist/esm/src/store/data-store-level.js.map +1 -1
- package/dist/esm/src/store/index-level-compound.js +246 -0
- package/dist/esm/src/store/index-level-compound.js.map +1 -0
- package/dist/esm/src/store/index-level.js +307 -715
- package/dist/esm/src/store/index-level.js.map +1 -1
- package/dist/esm/src/store/level-wrapper.js +143 -244
- package/dist/esm/src/store/level-wrapper.js.map +1 -1
- package/dist/esm/src/store/message-store-level.js +71 -94
- package/dist/esm/src/store/message-store-level.js.map +1 -1
- package/dist/esm/src/store/resumable-task-store-level.js +62 -101
- package/dist/esm/src/store/resumable-task-store-level.js.map +1 -1
- package/dist/esm/src/store/storage-controller.js +131 -146
- package/dist/esm/src/store/storage-controller.js.map +1 -1
- package/dist/esm/src/types/permission-types.js.map +1 -1
- package/dist/esm/src/types/protocols-types.js +10 -0
- package/dist/esm/src/types/protocols-types.js.map +1 -1
- package/dist/esm/src/types/records-types.js.map +1 -1
- package/dist/esm/src/utils/abort.js +8 -19
- package/dist/esm/src/utils/abort.js.map +1 -1
- package/dist/esm/src/utils/array.js +15 -49
- package/dist/esm/src/utils/array.js.map +1 -1
- package/dist/esm/src/utils/cid.js +29 -77
- package/dist/esm/src/utils/cid.js.map +1 -1
- package/dist/esm/src/utils/data-stream.js +37 -65
- package/dist/esm/src/utils/data-stream.js.map +1 -1
- package/dist/esm/src/utils/encryption.js +136 -162
- package/dist/esm/src/utils/encryption.js.map +1 -1
- package/dist/esm/src/utils/filter.js +1 -12
- package/dist/esm/src/utils/filter.js.map +1 -1
- package/dist/esm/src/utils/hd-key.js +45 -71
- package/dist/esm/src/utils/hd-key.js.map +1 -1
- package/dist/esm/src/utils/jws.js +9 -20
- package/dist/esm/src/utils/jws.js.map +1 -1
- package/dist/esm/src/utils/memory-cache.js +12 -23
- package/dist/esm/src/utils/memory-cache.js.map +1 -1
- package/dist/esm/src/utils/messages.js +21 -33
- package/dist/esm/src/utils/messages.js.map +1 -1
- package/dist/esm/src/utils/private-key-signer.js +9 -17
- package/dist/esm/src/utils/private-key-signer.js.map +1 -1
- package/dist/esm/src/utils/protocols.js +62 -70
- package/dist/esm/src/utils/protocols.js.map +1 -1
- package/dist/esm/src/utils/records.js +103 -166
- package/dist/esm/src/utils/records.js.map +1 -1
- package/dist/esm/src/utils/secp256k1.js +60 -96
- package/dist/esm/src/utils/secp256k1.js.map +1 -1
- package/dist/esm/src/utils/secp256r1.js +54 -71
- package/dist/esm/src/utils/secp256r1.js.map +1 -1
- package/dist/esm/src/utils/time.js +5 -18
- package/dist/esm/src/utils/time.js.map +1 -1
- package/dist/esm/src/utils/url.js +3 -3
- package/dist/esm/src/utils/url.js.map +1 -1
- package/dist/esm/tests/core/auth.spec.js +3 -12
- package/dist/esm/tests/core/auth.spec.js.map +1 -1
- package/dist/esm/tests/core/message.spec.js +50 -59
- package/dist/esm/tests/core/message.spec.js.map +1 -1
- package/dist/esm/tests/core/protocol-authorization.spec.js +10 -18
- package/dist/esm/tests/core/protocol-authorization.spec.js.map +1 -1
- package/dist/esm/tests/dwn.spec.js +65 -89
- package/dist/esm/tests/dwn.spec.js.map +1 -1
- package/dist/esm/tests/event-emitter-event-log.spec.js +305 -0
- package/dist/esm/tests/event-emitter-event-log.spec.js.map +1 -0
- package/dist/esm/tests/features/author-delegated-grant.spec.js +337 -347
- package/dist/esm/tests/features/author-delegated-grant.spec.js.map +1 -1
- package/dist/esm/tests/features/owner-delegated-grant.spec.js +160 -172
- package/dist/esm/tests/features/owner-delegated-grant.spec.js.map +1 -1
- package/dist/esm/tests/features/owner-signature.spec.js +78 -82
- package/dist/esm/tests/features/owner-signature.spec.js.map +1 -1
- package/dist/esm/tests/features/permissions.spec.js +449 -184
- package/dist/esm/tests/features/permissions.spec.js.map +1 -1
- package/dist/esm/tests/features/protocol-composition.spec.js +981 -360
- package/dist/esm/tests/features/protocol-composition.spec.js.map +1 -1
- package/dist/esm/tests/features/protocol-create-action.spec.js +45 -54
- package/dist/esm/tests/features/protocol-create-action.spec.js.map +1 -1
- package/dist/esm/tests/features/protocol-delete-action.spec.js +99 -108
- package/dist/esm/tests/features/protocol-delete-action.spec.js.map +1 -1
- package/dist/esm/tests/features/protocol-update-action.spec.js +108 -117
- package/dist/esm/tests/features/protocol-update-action.spec.js.map +1 -1
- package/dist/esm/tests/features/records-immutable.spec.js +315 -0
- package/dist/esm/tests/features/records-immutable.spec.js.map +1 -0
- package/dist/esm/tests/features/records-prune.spec.js +178 -194
- package/dist/esm/tests/features/records-prune.spec.js.map +1 -1
- package/dist/esm/tests/features/records-record-limit.spec.js +542 -0
- package/dist/esm/tests/features/records-record-limit.spec.js.map +1 -0
- package/dist/esm/tests/features/records-tags.spec.js +456 -463
- package/dist/esm/tests/features/records-tags.spec.js.map +1 -1
- package/dist/esm/tests/features/resumable-tasks.spec.js +88 -98
- package/dist/esm/tests/features/resumable-tasks.spec.js.map +1 -1
- package/dist/esm/tests/handlers/messages-read.spec.js +215 -210
- package/dist/esm/tests/handlers/messages-read.spec.js.map +1 -1
- package/dist/esm/tests/handlers/messages-subscribe.spec.js +309 -171
- package/dist/esm/tests/handlers/messages-subscribe.spec.js.map +1 -1
- package/dist/esm/tests/handlers/messages-sync.spec.js +272 -199
- package/dist/esm/tests/handlers/messages-sync.spec.js.map +1 -1
- package/dist/esm/tests/handlers/protocols-configure.spec.js +247 -241
- package/dist/esm/tests/handlers/protocols-configure.spec.js.map +1 -1
- package/dist/esm/tests/handlers/protocols-query.spec.js +159 -172
- package/dist/esm/tests/handlers/protocols-query.spec.js.map +1 -1
- package/dist/esm/tests/handlers/records-count.spec.js +101 -105
- package/dist/esm/tests/handlers/records-count.spec.js.map +1 -1
- package/dist/esm/tests/handlers/records-delete.spec.js +266 -279
- package/dist/esm/tests/handlers/records-delete.spec.js.map +1 -1
- package/dist/esm/tests/handlers/records-query.spec.js +984 -996
- package/dist/esm/tests/handlers/records-query.spec.js.map +1 -1
- package/dist/esm/tests/handlers/records-read.spec.js +542 -671
- package/dist/esm/tests/handlers/records-read.spec.js.map +1 -1
- package/dist/esm/tests/handlers/records-subscribe.spec.js +433 -302
- package/dist/esm/tests/handlers/records-subscribe.spec.js.map +1 -1
- package/dist/esm/tests/handlers/records-write.spec.js +1216 -1140
- package/dist/esm/tests/handlers/records-write.spec.js.map +1 -1
- package/dist/esm/tests/interfaces/messages-get.spec.js +39 -48
- package/dist/esm/tests/interfaces/messages-get.spec.js.map +1 -1
- package/dist/esm/tests/interfaces/messages-subscribe.spec.js +4 -13
- package/dist/esm/tests/interfaces/messages-subscribe.spec.js.map +1 -1
- package/dist/esm/tests/interfaces/protocols-configure.spec.js +212 -88
- package/dist/esm/tests/interfaces/protocols-configure.spec.js.map +1 -1
- package/dist/esm/tests/interfaces/protocols-query.spec.js +8 -17
- package/dist/esm/tests/interfaces/protocols-query.spec.js.map +1 -1
- package/dist/esm/tests/interfaces/records-delete.spec.js +8 -17
- package/dist/esm/tests/interfaces/records-delete.spec.js.map +1 -1
- package/dist/esm/tests/interfaces/records-query.spec.js +20 -29
- package/dist/esm/tests/interfaces/records-query.spec.js.map +1 -1
- package/dist/esm/tests/interfaces/records-read.spec.js +42 -51
- package/dist/esm/tests/interfaces/records-read.spec.js.map +1 -1
- package/dist/esm/tests/interfaces/records-subscribe.spec.js +16 -25
- package/dist/esm/tests/interfaces/records-subscribe.spec.js.map +1 -1
- package/dist/esm/tests/interfaces/records-write.spec.js +190 -219
- package/dist/esm/tests/interfaces/records-write.spec.js.map +1 -1
- package/dist/esm/tests/jose/jws/general.spec.js +36 -45
- package/dist/esm/tests/jose/jws/general.spec.js.map +1 -1
- package/dist/esm/tests/protocols/permission-grant.spec.js +44 -50
- package/dist/esm/tests/protocols/permission-grant.spec.js.map +1 -1
- package/dist/esm/tests/protocols/permission-request.spec.js +23 -32
- package/dist/esm/tests/protocols/permission-request.spec.js.map +1 -1
- package/dist/esm/tests/protocols/permissions.spec.js +49 -55
- package/dist/esm/tests/protocols/permissions.spec.js.map +1 -1
- package/dist/esm/tests/scenarios/aggregator.spec.js +127 -138
- package/dist/esm/tests/scenarios/aggregator.spec.js.map +1 -1
- package/dist/esm/tests/scenarios/deleted-record.spec.js +372 -36
- package/dist/esm/tests/scenarios/deleted-record.spec.js.map +1 -1
- package/dist/esm/tests/scenarios/end-to-end-tests.spec.js +55 -64
- package/dist/esm/tests/scenarios/end-to-end-tests.spec.js.map +1 -1
- package/dist/esm/tests/scenarios/nested-roles.spec.js +66 -76
- package/dist/esm/tests/scenarios/nested-roles.spec.js.map +1 -1
- package/dist/esm/tests/scenarios/subscriptions.spec.js +451 -354
- package/dist/esm/tests/scenarios/subscriptions.spec.js.map +1 -1
- package/dist/esm/tests/smt/smt-store-level.spec.js +76 -87
- package/dist/esm/tests/smt/smt-store-level.spec.js.map +1 -1
- package/dist/esm/tests/smt/sparse-merkle-tree.spec.js +344 -353
- package/dist/esm/tests/smt/sparse-merkle-tree.spec.js.map +1 -1
- package/dist/esm/tests/state-index/state-index-level.spec.js +117 -126
- package/dist/esm/tests/state-index/state-index-level.spec.js.map +1 -1
- package/dist/esm/tests/store/blockstore-level.spec.js +44 -99
- package/dist/esm/tests/store/blockstore-level.spec.js.map +1 -1
- package/dist/esm/tests/store/blockstore-mock.spec.js +40 -120
- package/dist/esm/tests/store/blockstore-mock.spec.js.map +1 -1
- package/dist/esm/tests/store/data-store-level.spec.js +160 -108
- package/dist/esm/tests/store/data-store-level.spec.js.map +1 -1
- package/dist/esm/tests/store/index-level.spec.js +404 -414
- package/dist/esm/tests/store/index-level.spec.js.map +1 -1
- package/dist/esm/tests/store/message-store-level.spec.js +13 -22
- package/dist/esm/tests/store/message-store-level.spec.js.map +1 -1
- package/dist/esm/tests/store/message-store.spec.js +229 -238
- package/dist/esm/tests/store/message-store.spec.js.map +1 -1
- package/dist/esm/tests/test-event-stream.js +12 -13
- package/dist/esm/tests/test-event-stream.js.map +1 -1
- package/dist/esm/tests/test-stores.js +16 -13
- package/dist/esm/tests/test-stores.js.map +1 -1
- package/dist/esm/tests/test-suite.js +8 -15
- package/dist/esm/tests/test-suite.js.map +1 -1
- package/dist/esm/tests/utils/cid.spec.js +24 -33
- package/dist/esm/tests/utils/cid.spec.js.map +1 -1
- package/dist/esm/tests/utils/data-stream.spec.js +48 -57
- package/dist/esm/tests/utils/data-stream.spec.js.map +1 -1
- package/dist/esm/tests/utils/encryption-callbacks.spec.js +45 -54
- package/dist/esm/tests/utils/encryption-callbacks.spec.js.map +1 -1
- package/dist/esm/tests/utils/encryption.spec.js +229 -82
- package/dist/esm/tests/utils/encryption.spec.js.map +1 -1
- package/dist/esm/tests/utils/filters.spec.js +46 -55
- package/dist/esm/tests/utils/filters.spec.js.map +1 -1
- package/dist/esm/tests/utils/hd-key.spec.js +10 -19
- package/dist/esm/tests/utils/hd-key.spec.js.map +1 -1
- package/dist/esm/tests/utils/jws.spec.js +3 -12
- package/dist/esm/tests/utils/jws.spec.js.map +1 -1
- package/dist/esm/tests/utils/memory-cache.spec.js +9 -18
- package/dist/esm/tests/utils/memory-cache.spec.js.map +1 -1
- package/dist/esm/tests/utils/messages.spec.js +18 -20
- package/dist/esm/tests/utils/messages.spec.js.map +1 -1
- package/dist/esm/tests/utils/poller.js +22 -33
- package/dist/esm/tests/utils/poller.js.map +1 -1
- package/dist/esm/tests/utils/private-key-signer.spec.js +15 -24
- package/dist/esm/tests/utils/private-key-signer.spec.js.map +1 -1
- package/dist/esm/tests/utils/records.spec.js +14 -27
- package/dist/esm/tests/utils/records.spec.js.map +1 -1
- package/dist/esm/tests/utils/secp256k1.spec.js +16 -25
- package/dist/esm/tests/utils/secp256k1.spec.js.map +1 -1
- package/dist/esm/tests/utils/secp256r1.spec.js +18 -27
- package/dist/esm/tests/utils/secp256r1.spec.js.map +1 -1
- package/dist/esm/tests/utils/test-data-generator.js +446 -467
- package/dist/esm/tests/utils/test-data-generator.js.map +1 -1
- package/dist/esm/tests/validation/json-schemas/definitions.spec.js +2 -11
- 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 +4 -13
- 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 -17
- 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 +3 -12
- 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 +4 -13
- 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 +2 -11
- 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 +2 -11
- package/dist/esm/tests/validation/json-schemas/records/records-read.spec.js.map +1 -1
- package/dist/esm/tests/validation/json-schemas/records/records-write.spec.js +44 -24
- package/dist/esm/tests/validation/json-schemas/records/records-write.spec.js.map +1 -1
- package/dist/types/generated/precompiled-validators.d.ts +49 -40
- package/dist/types/generated/precompiled-validators.d.ts.map +1 -1
- package/dist/types/src/core/constants.d.ts +11 -0
- package/dist/types/src/core/constants.d.ts.map +1 -0
- package/dist/types/src/core/core-protocol.d.ts +89 -0
- package/dist/types/src/core/core-protocol.d.ts.map +1 -0
- package/dist/types/src/core/dwn-error.d.ts +9 -12
- package/dist/types/src/core/dwn-error.d.ts.map +1 -1
- package/dist/types/src/core/grant-authorization.d.ts +6 -2
- package/dist/types/src/core/grant-authorization.d.ts.map +1 -1
- package/dist/types/src/core/protocol-authorization-action.d.ts +42 -0
- package/dist/types/src/core/protocol-authorization-action.d.ts.map +1 -0
- package/dist/types/src/core/protocol-authorization-validation.d.ts +81 -0
- package/dist/types/src/core/protocol-authorization-validation.d.ts.map +1 -0
- package/dist/types/src/core/protocol-authorization.d.ts +24 -106
- package/dist/types/src/core/protocol-authorization.d.ts.map +1 -1
- package/dist/types/src/core/record-chain.d.ts +24 -0
- package/dist/types/src/core/record-chain.d.ts.map +1 -0
- package/dist/types/src/core/records-grant-authorization.d.ts.map +1 -1
- package/dist/types/src/dwn.d.ts +19 -7
- package/dist/types/src/dwn.d.ts.map +1 -1
- package/dist/types/src/event-stream/event-emitter-event-log.d.ts +50 -0
- package/dist/types/src/event-stream/event-emitter-event-log.d.ts.map +1 -0
- package/dist/types/src/handlers/messages-read.d.ts +3 -8
- package/dist/types/src/handlers/messages-read.d.ts.map +1 -1
- package/dist/types/src/handlers/messages-subscribe.d.ts +6 -10
- package/dist/types/src/handlers/messages-subscribe.d.ts.map +1 -1
- package/dist/types/src/handlers/messages-sync.d.ts +3 -8
- package/dist/types/src/handlers/messages-sync.d.ts.map +1 -1
- package/dist/types/src/handlers/protocols-configure.d.ts +3 -10
- package/dist/types/src/handlers/protocols-configure.d.ts.map +1 -1
- package/dist/types/src/handlers/protocols-query.d.ts +3 -8
- package/dist/types/src/handlers/protocols-query.d.ts.map +1 -1
- package/dist/types/src/handlers/records-count.d.ts +3 -6
- package/dist/types/src/handlers/records-count.d.ts.map +1 -1
- package/dist/types/src/handlers/records-delete.d.ts +3 -8
- package/dist/types/src/handlers/records-delete.d.ts.map +1 -1
- package/dist/types/src/handlers/records-query.d.ts +3 -8
- package/dist/types/src/handlers/records-query.d.ts.map +1 -1
- package/dist/types/src/handlers/records-read.d.ts +3 -8
- package/dist/types/src/handlers/records-read.d.ts.map +1 -1
- package/dist/types/src/handlers/records-subscribe.d.ts +8 -10
- package/dist/types/src/handlers/records-subscribe.d.ts.map +1 -1
- package/dist/types/src/handlers/records-write.d.ts +4 -24
- package/dist/types/src/handlers/records-write.d.ts.map +1 -1
- package/dist/types/src/index.d.ts +8 -4
- package/dist/types/src/index.d.ts.map +1 -1
- package/dist/types/src/interfaces/messages-subscribe.d.ts +5 -0
- package/dist/types/src/interfaces/messages-subscribe.d.ts.map +1 -1
- package/dist/types/src/interfaces/protocols-configure.d.ts.map +1 -1
- package/dist/types/src/interfaces/records-subscribe.d.ts +5 -0
- package/dist/types/src/interfaces/records-subscribe.d.ts.map +1 -1
- package/dist/types/src/interfaces/records-write-query.d.ts +33 -0
- package/dist/types/src/interfaces/records-write-query.d.ts.map +1 -0
- package/dist/types/src/interfaces/records-write-signing.d.ts +34 -0
- package/dist/types/src/interfaces/records-write-signing.d.ts.map +1 -0
- package/dist/types/src/interfaces/records-write.d.ts +13 -53
- package/dist/types/src/interfaces/records-write.d.ts.map +1 -1
- package/dist/types/src/protocols/permission-grant.d.ts +1 -1
- package/dist/types/src/protocols/permission-grant.d.ts.map +1 -1
- package/dist/types/src/protocols/permission-request.d.ts +1 -1
- package/dist/types/src/protocols/permission-request.d.ts.map +1 -1
- package/dist/types/src/protocols/permissions.d.ts +40 -3
- package/dist/types/src/protocols/permissions.d.ts.map +1 -1
- package/dist/types/src/state-index/state-index-level.d.ts.map +1 -1
- package/dist/types/src/store/data-store-level.d.ts +20 -4
- package/dist/types/src/store/data-store-level.d.ts.map +1 -1
- package/dist/types/src/store/index-level-compound.d.ts +70 -0
- package/dist/types/src/store/index-level-compound.d.ts.map +1 -0
- package/dist/types/src/store/index-level.d.ts +4 -58
- package/dist/types/src/store/index-level.d.ts.map +1 -1
- package/dist/types/src/store/storage-controller.d.ts +4 -4
- package/dist/types/src/store/storage-controller.d.ts.map +1 -1
- package/dist/types/src/types/message-types.d.ts +3 -3
- package/dist/types/src/types/message-types.d.ts.map +1 -1
- package/dist/types/src/types/messages-types.d.ts +12 -3
- package/dist/types/src/types/messages-types.d.ts.map +1 -1
- package/dist/types/src/types/method-handler.d.ts +24 -3
- package/dist/types/src/types/method-handler.d.ts.map +1 -1
- package/dist/types/src/types/permission-types.d.ts +7 -0
- package/dist/types/src/types/permission-types.d.ts.map +1 -1
- package/dist/types/src/types/protocols-types.d.ts +41 -1
- package/dist/types/src/types/protocols-types.d.ts.map +1 -1
- package/dist/types/src/types/records-types.d.ts +16 -6
- package/dist/types/src/types/records-types.d.ts.map +1 -1
- package/dist/types/src/types/subscriptions.d.ts +151 -13
- package/dist/types/src/types/subscriptions.d.ts.map +1 -1
- package/dist/types/src/utils/hd-key.d.ts +1 -9
- package/dist/types/src/utils/hd-key.d.ts.map +1 -1
- package/dist/types/src/utils/messages.d.ts +7 -5
- package/dist/types/src/utils/messages.d.ts.map +1 -1
- package/dist/types/src/utils/protocols.d.ts +5 -0
- package/dist/types/src/utils/protocols.d.ts.map +1 -1
- package/dist/types/src/utils/records.d.ts +1 -11
- package/dist/types/src/utils/records.d.ts.map +1 -1
- package/dist/types/tests/dwn.spec.d.ts.map +1 -1
- package/dist/types/tests/event-emitter-event-log.spec.d.ts +2 -0
- package/dist/types/tests/event-emitter-event-log.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.map +1 -1
- package/dist/types/tests/features/records-immutable.spec.d.ts +2 -0
- package/dist/types/tests/features/records-immutable.spec.d.ts.map +1 -0
- package/dist/types/tests/features/records-record-limit.spec.d.ts +2 -0
- package/dist/types/tests/features/records-record-limit.spec.d.ts.map +1 -0
- 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.map +1 -1
- package/dist/types/tests/handlers/records-count.spec.d.ts.map +1 -1
- 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/scenarios/deleted-record.spec.d.ts.map +1 -1
- package/dist/types/tests/scenarios/subscriptions.spec.d.ts.map +1 -1
- package/dist/types/tests/test-event-stream.d.ts +11 -12
- package/dist/types/tests/test-event-stream.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/test-data-generator.d.ts +18 -0
- package/dist/types/tests/utils/test-data-generator.d.ts.map +1 -1
- package/package.json +5 -4
- package/src/core/constants.ts +11 -0
- package/src/core/core-protocol.ts +129 -0
- package/src/core/dwn-error.ts +15 -12
- package/src/core/grant-authorization.ts +20 -3
- package/src/core/protocol-authorization-action.ts +377 -0
- package/src/core/protocol-authorization-validation.ts +487 -0
- package/src/core/protocol-authorization.ts +111 -856
- package/src/core/record-chain.ts +99 -0
- package/src/core/records-grant-authorization.ts +6 -8
- package/src/dwn.ts +58 -73
- package/src/event-stream/event-emitter-event-log.ts +283 -0
- package/src/handlers/messages-read.ts +8 -9
- package/src/handlers/messages-subscribe.ts +24 -28
- package/src/handlers/messages-sync.ts +10 -16
- package/src/handlers/protocols-configure.ts +47 -32
- package/src/handlers/protocols-query.ts +6 -9
- package/src/handlers/records-count.ts +11 -10
- package/src/handlers/records-delete.ts +12 -21
- package/src/handlers/records-query.ts +12 -12
- package/src/handlers/records-read.ts +34 -22
- package/src/handlers/records-subscribe.ts +47 -26
- package/src/handlers/records-write.ts +47 -104
- package/src/index.ts +9 -5
- package/src/interfaces/messages-subscribe.ts +7 -1
- package/src/interfaces/protocols-configure.ts +73 -8
- package/src/interfaces/records-count.ts +1 -1
- package/src/interfaces/records-delete.ts +1 -1
- package/src/interfaces/records-query.ts +1 -1
- package/src/interfaces/records-read.ts +1 -1
- package/src/interfaces/records-subscribe.ts +8 -1
- package/src/interfaces/records-write-query.ts +139 -0
- package/src/interfaces/records-write-signing.ts +123 -0
- package/src/interfaces/records-write.ts +66 -261
- package/src/protocols/permission-grant.ts +1 -1
- package/src/protocols/permission-request.ts +1 -1
- package/src/protocols/permissions.ts +148 -6
- package/src/state-index/state-index-level.ts +5 -7
- package/src/store/data-store-level.ts +124 -34
- package/src/store/index-level-compound.ts +324 -0
- package/src/store/index-level.ts +68 -341
- package/src/store/storage-controller.ts +11 -11
- package/src/types/message-types.ts +3 -3
- package/src/types/messages-types.ts +12 -3
- package/src/types/method-handler.ts +26 -4
- package/src/types/mitt.d.ts +28 -0
- package/src/types/permission-types.ts +7 -0
- package/src/types/protocols-types.ts +46 -0
- package/src/types/records-types.ts +16 -6
- package/src/types/subscriptions.ts +178 -14
- package/src/utils/hd-key.ts +0 -9
- package/src/utils/messages.ts +17 -37
- package/src/utils/protocols.ts +8 -0
- package/src/utils/records.ts +8 -59
- package/dist/esm/src/event-stream/event-emitter-stream.js +0 -60
- package/dist/esm/src/event-stream/event-emitter-stream.js.map +0 -1
- package/dist/esm/tests/event-stream/event-emitter-stream.spec.js +0 -77
- package/dist/esm/tests/event-stream/event-emitter-stream.spec.js.map +0 -1
- package/dist/esm/tests/event-stream/event-stream.spec.js +0 -123
- package/dist/esm/tests/event-stream/event-stream.spec.js.map +0 -1
- package/dist/types/src/event-stream/event-emitter-stream.d.ts +0 -23
- package/dist/types/src/event-stream/event-emitter-stream.d.ts.map +0 -1
- package/dist/types/tests/event-stream/event-emitter-stream.spec.d.ts +0 -2
- package/dist/types/tests/event-stream/event-emitter-stream.spec.d.ts.map +0 -1
- package/dist/types/tests/event-stream/event-stream.spec.d.ts +0 -2
- package/dist/types/tests/event-stream/event-stream.spec.d.ts.map +0 -1
- package/src/event-stream/event-emitter-stream.ts +0 -69
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import type { Filter } from '../types/query-types.js';
|
|
2
|
+
import type { MessageStore } from '../types/message-store.js';
|
|
3
|
+
import type { RecordsWriteMessage } from '../types/records-types.js';
|
|
4
|
+
|
|
5
|
+
import { RecordsWrite } from '../interfaces/records-write.js';
|
|
6
|
+
import { DwnError, DwnErrorCode } from './dwn-error.js';
|
|
7
|
+
import { DwnInterfaceName, DwnMethodName } from '../enums/dwn-interface-method.js';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Fetches the initial RecordsWrite message associated with the given (tenant + recordId).
|
|
11
|
+
*/
|
|
12
|
+
export async function fetchInitialWrite(
|
|
13
|
+
tenant: string,
|
|
14
|
+
recordId: string,
|
|
15
|
+
messageStore: MessageStore
|
|
16
|
+
): Promise<RecordsWriteMessage | undefined> {
|
|
17
|
+
|
|
18
|
+
const query: Filter = {
|
|
19
|
+
interface : DwnInterfaceName.Records,
|
|
20
|
+
method : DwnMethodName.Write,
|
|
21
|
+
recordId : recordId
|
|
22
|
+
};
|
|
23
|
+
const { messages } = await messageStore.query(tenant, [query]);
|
|
24
|
+
|
|
25
|
+
if (messages.length === 0) {
|
|
26
|
+
return undefined;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const initialWrite = await RecordsWrite.getInitialWrite(messages);
|
|
30
|
+
return initialWrite;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Constructs the chain of EXISTING records in the datastore where the first record is the root initial `RecordsWrite` of the record chain
|
|
35
|
+
* and last record is the initial `RecordsWrite` of the descendant record specified.
|
|
36
|
+
* @param descendantRecordId The ID of the descendent record to start constructing the record chain from by repeatedly looking up the parent.
|
|
37
|
+
* @returns the record chain where each record is represented by its initial `RecordsWrite`;
|
|
38
|
+
* returns empty array if `descendantRecordId` is `undefined`.
|
|
39
|
+
* @throws {DwnError} if `descendantRecordId` is defined but any initial `RecordsWrite` is not found in the chain of records.
|
|
40
|
+
*/
|
|
41
|
+
export async function constructRecordChain(
|
|
42
|
+
tenant: string,
|
|
43
|
+
descendantRecordId: string | undefined,
|
|
44
|
+
messageStore: MessageStore
|
|
45
|
+
): Promise<RecordsWriteMessage[]> {
|
|
46
|
+
|
|
47
|
+
if (descendantRecordId === undefined) {
|
|
48
|
+
return [];
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
const recordChain: RecordsWriteMessage[] = [];
|
|
52
|
+
|
|
53
|
+
// keep walking up the chain from the inbound message's parent, until there is no more parent
|
|
54
|
+
let currentRecordId: string | undefined = descendantRecordId;
|
|
55
|
+
while (currentRecordId !== undefined) {
|
|
56
|
+
|
|
57
|
+
const initialWrite = await fetchInitialWrite(tenant, currentRecordId, messageStore);
|
|
58
|
+
|
|
59
|
+
// RecordsWrite needed should be available since we perform necessary checks at the time of writes,
|
|
60
|
+
// eg. check the immediate parent in `verifyProtocolPathAndContextId` at the time of writing,
|
|
61
|
+
// so if this condition is triggered, it means there is an unexpected bug that caused an incomplete chain.
|
|
62
|
+
// We add additional defensive check here because returning an unexpected/incorrect record chain could lead to security vulnerabilities.
|
|
63
|
+
if (initialWrite === undefined) {
|
|
64
|
+
throw new DwnError(
|
|
65
|
+
DwnErrorCode.ProtocolAuthorizationParentNotFoundConstructingRecordChain,
|
|
66
|
+
`Unexpected error that should never trigger: no parent found with ID ${currentRecordId} when constructing record chain.`
|
|
67
|
+
);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
recordChain.push(initialWrite);
|
|
71
|
+
currentRecordId = initialWrite.descriptor.parentId;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
return recordChain.reverse(); // root record first
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Determines the timestamp that governs which protocol definition version applies to the given RecordsWrite.
|
|
79
|
+
* For an update, this is the initial write's `messageTimestamp` (the protocol version is locked at creation time).
|
|
80
|
+
* For a new initial write, returns `undefined` — the latest protocol definition should be used because the
|
|
81
|
+
* record is being created now and must conform to the current protocol rules.
|
|
82
|
+
*/
|
|
83
|
+
export async function getGoverningTimestamp(
|
|
84
|
+
tenant: string,
|
|
85
|
+
incomingMessage: RecordsWrite,
|
|
86
|
+
messageStore: MessageStore,
|
|
87
|
+
): Promise<string | undefined> {
|
|
88
|
+
const existingInitialWrite = await fetchInitialWrite(
|
|
89
|
+
tenant, incomingMessage.message.recordId, messageStore
|
|
90
|
+
);
|
|
91
|
+
|
|
92
|
+
if (existingInitialWrite !== undefined) {
|
|
93
|
+
// update case: use the initial write's timestamp
|
|
94
|
+
return existingInitialWrite.descriptor.messageTimestamp;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// initial write case: validate against the latest protocol definition
|
|
98
|
+
return undefined;
|
|
99
|
+
}
|
|
@@ -87,15 +87,14 @@ export class RecordsGrantAuthorization {
|
|
|
87
87
|
messageStore
|
|
88
88
|
});
|
|
89
89
|
|
|
90
|
-
//
|
|
90
|
+
// The grant's protocol must match the query/subscribe filter's protocol.
|
|
91
91
|
// NOTE: validated the invoked permission is for Records in GrantAuthorization.performBaseValidation()
|
|
92
92
|
const permissionScope = permissionGrant.scope as RecordsPermissionScope;
|
|
93
|
-
const protocolInGrant = permissionScope.protocol;
|
|
94
93
|
const protocolInMessage = incomingMessage.descriptor.filter.protocol;
|
|
95
|
-
if (
|
|
94
|
+
if (protocolInMessage !== permissionScope.protocol) {
|
|
96
95
|
throw new DwnError(
|
|
97
96
|
DwnErrorCode.RecordsGrantAuthorizationQueryOrSubscribeProtocolScopeMismatch,
|
|
98
|
-
`Grant protocol scope ${
|
|
97
|
+
`Grant protocol scope ${permissionScope.protocol} does not match protocol in message ${protocolInMessage}`
|
|
99
98
|
);
|
|
100
99
|
}
|
|
101
100
|
}
|
|
@@ -124,15 +123,14 @@ export class RecordsGrantAuthorization {
|
|
|
124
123
|
messageStore
|
|
125
124
|
});
|
|
126
125
|
|
|
127
|
-
//
|
|
126
|
+
// The grant's protocol must match the protocol of the record being deleted.
|
|
128
127
|
// NOTE: validated the invoked permission is for Records in GrantAuthorization.performBaseValidation()
|
|
129
128
|
const permissionScope = permissionGrant.scope as RecordsPermissionScope;
|
|
130
|
-
const protocolInGrant = permissionScope.protocol;
|
|
131
129
|
const protocolOfRecordToDelete = recordsWriteToDelete.descriptor.protocol;
|
|
132
|
-
if (
|
|
130
|
+
if (protocolOfRecordToDelete !== permissionScope.protocol) {
|
|
133
131
|
throw new DwnError(
|
|
134
132
|
DwnErrorCode.RecordsGrantAuthorizationDeleteProtocolScopeMismatch,
|
|
135
|
-
`Grant protocol scope ${
|
|
133
|
+
`Grant protocol scope ${permissionScope.protocol} does not match protocol in record to delete ${protocolOfRecordToDelete}`
|
|
136
134
|
);
|
|
137
135
|
}
|
|
138
136
|
}
|
package/src/dwn.ts
CHANGED
|
@@ -1,24 +1,25 @@
|
|
|
1
|
-
|
|
2
1
|
import type { DataStore } from './types/data-store.js';
|
|
3
2
|
import type { DidResolver } from '@enbox/dids';
|
|
4
|
-
import type { EventStream } from './types/subscriptions.js';
|
|
5
3
|
import type { MessageStore } from './types/message-store.js';
|
|
6
|
-
import type { MethodHandler } from './types/method-handler.js';
|
|
7
4
|
import type { ResumableTaskStore } from './types/resumable-task-store.js';
|
|
8
5
|
import type { StateIndex } from './types/state-index.js';
|
|
9
6
|
import type { TenantGate } from './core/tenant-gate.js';
|
|
10
7
|
import type { UnionMessageReply } from './core/message-reply.js';
|
|
8
|
+
import type { EventLog, SubscriptionListener } from './types/subscriptions.js';
|
|
11
9
|
import type { GenericMessage, GenericMessageReply } from './types/message-types.js';
|
|
12
|
-
import type {
|
|
10
|
+
import type { HandlerDependencies, MethodHandler } from './types/method-handler.js';
|
|
11
|
+
import type { MessagesReadMessage, MessagesReadReply, MessagesSubscribeMessage, MessagesSubscribeMessageOptions, MessagesSubscribeReply, MessagesSyncMessage, MessagesSyncReply } from './types/messages-types.js';
|
|
13
12
|
import type { ProtocolsConfigureMessage, ProtocolsQueryMessage, ProtocolsQueryReply } from './types/protocols-types.js';
|
|
14
|
-
import type { RecordsCountMessage, RecordsCountReply, RecordsDeleteMessage, RecordsQueryMessage, RecordsQueryReply, RecordsReadMessage, RecordsReadReply, RecordsSubscribeMessage, RecordsSubscribeMessageOptions, RecordsSubscribeReply,
|
|
13
|
+
import type { RecordsCountMessage, RecordsCountReply, RecordsDeleteMessage, RecordsQueryMessage, RecordsQueryReply, RecordsReadMessage, RecordsReadReply, RecordsSubscribeMessage, RecordsSubscribeMessageOptions, RecordsSubscribeReply, RecordsWriteMessage, RecordsWriteMessageOptions } from './types/records-types.js';
|
|
15
14
|
|
|
16
15
|
import { AllowAllTenantGate } from './core/tenant-gate.js';
|
|
16
|
+
import { CoreProtocolRegistry } from './core/core-protocol.js';
|
|
17
17
|
import { Message } from './core/message.js';
|
|
18
18
|
import { messageReplyFromError } from './core/message-reply.js';
|
|
19
19
|
import { MessagesReadHandler } from './handlers/messages-read.js';
|
|
20
20
|
import { MessagesSubscribeHandler } from './handlers/messages-subscribe.js';
|
|
21
21
|
import { MessagesSyncHandler } from './handlers/messages-sync.js';
|
|
22
|
+
import { PermissionsProtocol } from './protocols/permissions.js';
|
|
22
23
|
import { ProtocolsConfigureHandler } from './handlers/protocols-configure.js';
|
|
23
24
|
import { ProtocolsQueryHandler } from './handlers/protocols-query.js';
|
|
24
25
|
import { RecordsCountHandler } from './handlers/records-count.js';
|
|
@@ -40,88 +41,60 @@ export class Dwn {
|
|
|
40
41
|
private resumableTaskStore: ResumableTaskStore;
|
|
41
42
|
private stateIndex: StateIndex;
|
|
42
43
|
private tenantGate: TenantGate;
|
|
43
|
-
private
|
|
44
|
+
private eventLog?: EventLog;
|
|
44
45
|
private storageController: StorageController;
|
|
45
46
|
private resumableTaskManager: ResumableTaskManager;
|
|
47
|
+
private _coreProtocols: CoreProtocolRegistry;
|
|
46
48
|
|
|
47
49
|
private constructor(config: DwnConfig) {
|
|
48
50
|
this.didResolver = config.didResolver!;
|
|
49
51
|
this.tenantGate = config.tenantGate!;
|
|
50
|
-
this.eventStream = config.eventStream!;
|
|
51
52
|
this.messageStore = config.messageStore;
|
|
52
53
|
this.dataStore = config.dataStore;
|
|
53
54
|
this.resumableTaskStore = config.resumableTaskStore;
|
|
54
55
|
this.stateIndex = config.stateIndex;
|
|
55
|
-
|
|
56
|
+
|
|
57
|
+
this.eventLog = config.eventLog;
|
|
58
|
+
|
|
56
59
|
this.storageController = new StorageController({
|
|
57
60
|
messageStore : this.messageStore,
|
|
58
61
|
dataStore : this.dataStore,
|
|
59
62
|
stateIndex : this.stateIndex,
|
|
60
|
-
|
|
63
|
+
eventLog : this.eventLog
|
|
61
64
|
});
|
|
62
65
|
this.resumableTaskManager = new ResumableTaskManager(
|
|
63
66
|
config.resumableTaskStore,
|
|
64
67
|
this.storageController
|
|
65
68
|
);
|
|
66
69
|
|
|
70
|
+
// Initialize the core protocol registry with built-in system protocols.
|
|
71
|
+
this._coreProtocols = new CoreProtocolRegistry();
|
|
72
|
+
this._coreProtocols.register(new PermissionsProtocol());
|
|
73
|
+
|
|
74
|
+
// Build the shared dependency bag once; every handler receives the same object
|
|
75
|
+
// and accesses only the dependencies it needs.
|
|
76
|
+
const deps: HandlerDependencies = {
|
|
77
|
+
didResolver : this.didResolver,
|
|
78
|
+
messageStore : this.messageStore,
|
|
79
|
+
dataStore : this.dataStore,
|
|
80
|
+
stateIndex : this.stateIndex,
|
|
81
|
+
resumableTaskManager : this.resumableTaskManager,
|
|
82
|
+
coreProtocols : this._coreProtocols,
|
|
83
|
+
eventLog : this.eventLog,
|
|
84
|
+
};
|
|
85
|
+
|
|
67
86
|
this.methodHandlers = {
|
|
68
|
-
[DwnInterfaceName.Messages + DwnMethodName.Read]: new MessagesReadHandler(
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
),
|
|
73
|
-
[DwnInterfaceName.
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
),
|
|
78
|
-
[DwnInterfaceName.
|
|
79
|
-
this.didResolver,
|
|
80
|
-
this.messageStore,
|
|
81
|
-
this.stateIndex,
|
|
82
|
-
),
|
|
83
|
-
[DwnInterfaceName.Protocols + DwnMethodName.Configure]: new ProtocolsConfigureHandler(
|
|
84
|
-
this.didResolver,
|
|
85
|
-
this.messageStore,
|
|
86
|
-
this.stateIndex,
|
|
87
|
-
this.eventStream
|
|
88
|
-
),
|
|
89
|
-
[DwnInterfaceName.Protocols + DwnMethodName.Query]: new ProtocolsQueryHandler(
|
|
90
|
-
this.didResolver,
|
|
91
|
-
this.messageStore,
|
|
92
|
-
this.dataStore
|
|
93
|
-
),
|
|
94
|
-
[DwnInterfaceName.Records + DwnMethodName.Count]: new RecordsCountHandler(
|
|
95
|
-
this.didResolver,
|
|
96
|
-
this.messageStore,
|
|
97
|
-
),
|
|
98
|
-
[DwnInterfaceName.Records + DwnMethodName.Delete]: new RecordsDeleteHandler(
|
|
99
|
-
this.didResolver,
|
|
100
|
-
this.messageStore,
|
|
101
|
-
this.resumableTaskManager
|
|
102
|
-
),
|
|
103
|
-
[DwnInterfaceName.Records + DwnMethodName.Query]: new RecordsQueryHandler(
|
|
104
|
-
this.didResolver,
|
|
105
|
-
this.messageStore,
|
|
106
|
-
this.dataStore
|
|
107
|
-
),
|
|
108
|
-
[DwnInterfaceName.Records + DwnMethodName.Read]: new RecordsReadHandler(
|
|
109
|
-
this.didResolver,
|
|
110
|
-
this.messageStore,
|
|
111
|
-
this.dataStore
|
|
112
|
-
),
|
|
113
|
-
[DwnInterfaceName.Records + DwnMethodName.Subscribe]: new RecordsSubscribeHandler(
|
|
114
|
-
this.didResolver,
|
|
115
|
-
this.messageStore,
|
|
116
|
-
this.eventStream
|
|
117
|
-
),
|
|
118
|
-
[DwnInterfaceName.Records + DwnMethodName.Write]: new RecordsWriteHandler(
|
|
119
|
-
this.didResolver,
|
|
120
|
-
this.messageStore,
|
|
121
|
-
this.dataStore,
|
|
122
|
-
this.stateIndex,
|
|
123
|
-
this.eventStream
|
|
124
|
-
)
|
|
87
|
+
[DwnInterfaceName.Messages + DwnMethodName.Read] : new MessagesReadHandler(deps),
|
|
88
|
+
[DwnInterfaceName.Messages + DwnMethodName.Subscribe] : new MessagesSubscribeHandler(deps),
|
|
89
|
+
[DwnInterfaceName.Messages + DwnMethodName.Sync] : new MessagesSyncHandler(deps),
|
|
90
|
+
[DwnInterfaceName.Protocols + DwnMethodName.Configure] : new ProtocolsConfigureHandler(deps),
|
|
91
|
+
[DwnInterfaceName.Protocols + DwnMethodName.Query] : new ProtocolsQueryHandler(deps),
|
|
92
|
+
[DwnInterfaceName.Records + DwnMethodName.Count] : new RecordsCountHandler(deps),
|
|
93
|
+
[DwnInterfaceName.Records + DwnMethodName.Delete] : new RecordsDeleteHandler(deps),
|
|
94
|
+
[DwnInterfaceName.Records + DwnMethodName.Query] : new RecordsQueryHandler(deps),
|
|
95
|
+
[DwnInterfaceName.Records + DwnMethodName.Read] : new RecordsReadHandler(deps),
|
|
96
|
+
[DwnInterfaceName.Records + DwnMethodName.Subscribe] : new RecordsSubscribeHandler(deps),
|
|
97
|
+
[DwnInterfaceName.Records + DwnMethodName.Write] : new RecordsWriteHandler(deps),
|
|
125
98
|
};
|
|
126
99
|
}
|
|
127
100
|
|
|
@@ -148,19 +121,28 @@ export class Dwn {
|
|
|
148
121
|
await this.dataStore.open();
|
|
149
122
|
await this.resumableTaskStore.open();
|
|
150
123
|
await this.stateIndex.open();
|
|
151
|
-
await this.
|
|
124
|
+
await this.eventLog?.open();
|
|
152
125
|
|
|
153
126
|
await this.resumableTaskManager.resumeTasksAndWaitForCompletion();
|
|
154
127
|
}
|
|
155
128
|
|
|
156
129
|
public async close(): Promise<void> {
|
|
157
|
-
await this.
|
|
130
|
+
await this.eventLog?.close();
|
|
158
131
|
await this.messageStore.close();
|
|
159
132
|
await this.dataStore.close();
|
|
160
133
|
await this.resumableTaskStore.close();
|
|
161
134
|
await this.stateIndex.close();
|
|
162
135
|
}
|
|
163
136
|
|
|
137
|
+
/**
|
|
138
|
+
* The registry of core protocols (hardcoded, immutable, always-installed).
|
|
139
|
+
* Used by handlers and utilities that need to check whether a protocol URI
|
|
140
|
+
* belongs to a core protocol or to dispatch lifecycle hooks.
|
|
141
|
+
*/
|
|
142
|
+
public get coreProtocols(): CoreProtocolRegistry {
|
|
143
|
+
return this._coreProtocols;
|
|
144
|
+
}
|
|
145
|
+
|
|
164
146
|
/**
|
|
165
147
|
* Returns the internal storage components for advanced operations that
|
|
166
148
|
* cannot be expressed through the standard `processMessage()` pipeline
|
|
@@ -168,11 +150,11 @@ export class Dwn {
|
|
|
168
150
|
*
|
|
169
151
|
* Callers are responsible for maintaining consistency across stores.
|
|
170
152
|
*/
|
|
171
|
-
public get storage(): { messageStore: MessageStore; stateIndex: StateIndex;
|
|
153
|
+
public get storage(): { messageStore: MessageStore; stateIndex: StateIndex; eventLog: EventLog | undefined } {
|
|
172
154
|
return {
|
|
173
155
|
messageStore : this.messageStore,
|
|
174
156
|
stateIndex : this.stateIndex,
|
|
175
|
-
|
|
157
|
+
eventLog : this.eventLog,
|
|
176
158
|
};
|
|
177
159
|
}
|
|
178
160
|
|
|
@@ -264,7 +246,7 @@ export class Dwn {
|
|
|
264
246
|
*/
|
|
265
247
|
export interface MessageOptions {
|
|
266
248
|
dataStream?: ReadableStream<Uint8Array>;
|
|
267
|
-
subscriptionHandler?:
|
|
249
|
+
subscriptionHandler?: SubscriptionListener;
|
|
268
250
|
};
|
|
269
251
|
|
|
270
252
|
/**
|
|
@@ -274,8 +256,11 @@ export type DwnConfig = {
|
|
|
274
256
|
didResolver?: DidResolver;
|
|
275
257
|
tenantGate?: TenantGate;
|
|
276
258
|
|
|
277
|
-
|
|
278
|
-
|
|
259
|
+
/**
|
|
260
|
+
* Persistent event log with cursor-based reads and in-process subscriptions.
|
|
261
|
+
* Optional — if not provided, subscriptions will not be supported.
|
|
262
|
+
*/
|
|
263
|
+
eventLog?: EventLog;
|
|
279
264
|
|
|
280
265
|
messageStore: MessageStore;
|
|
281
266
|
dataStore: DataStore;
|
|
@@ -0,0 +1,283 @@
|
|
|
1
|
+
import type { KeyValues } from '../types/query-types.js';
|
|
2
|
+
import type {
|
|
3
|
+
EventLog,
|
|
4
|
+
EventLogEntry,
|
|
5
|
+
EventLogReadOptions,
|
|
6
|
+
EventLogReadResult,
|
|
7
|
+
EventLogSubscribeOptions,
|
|
8
|
+
EventSubscription,
|
|
9
|
+
MessageEvent,
|
|
10
|
+
SubscriptionListener,
|
|
11
|
+
} from '../types/subscriptions.js';
|
|
12
|
+
|
|
13
|
+
import mitt from 'mitt';
|
|
14
|
+
|
|
15
|
+
import { FilterUtility } from '../utils/filter.js';
|
|
16
|
+
import { DwnError, DwnErrorCode } from '../core/dwn-error.js';
|
|
17
|
+
|
|
18
|
+
const EVENTS_LISTENER_CHANNEL = 'events';
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Payload shape used internally by mitt. We bundle the three EventListener
|
|
22
|
+
* arguments into a single object because mitt emits one value per event.
|
|
23
|
+
*/
|
|
24
|
+
type EmitterPayload = { tenant: string; event: MessageEvent; indexes: KeyValues; seq: number };
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* mitt event map — every channel name maps to an `EmitterPayload`.
|
|
28
|
+
* Using `Record<string, EmitterPayload>` lets us create channels dynamically.
|
|
29
|
+
*/
|
|
30
|
+
type EmitterEvents = Record<string, EmitterPayload>;
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Internal storage entry — the event plus its indexes.
|
|
34
|
+
*/
|
|
35
|
+
type StoredEntry = {
|
|
36
|
+
event : MessageEvent;
|
|
37
|
+
indexes : KeyValues;
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
export interface EventEmitterEventLogConfig {
|
|
41
|
+
/**
|
|
42
|
+
* Maximum number of events to retain per tenant.
|
|
43
|
+
* Oldest events are evicted when the limit is reached.
|
|
44
|
+
* Defaults to 10_000.
|
|
45
|
+
*/
|
|
46
|
+
maxEventsPerTenant?: number;
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* An optional error handler in order to be able to react to any errors or warnings.
|
|
50
|
+
* By default we log errors with `console.error`.
|
|
51
|
+
*/
|
|
52
|
+
errorHandler?: (error: any) => void;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* In-memory implementation of {@link EventLog} backed by `mitt` for in-process
|
|
57
|
+
* pub/sub and a per-tenant `Map<number, StoredEntry>` for persistence with
|
|
58
|
+
* cursor-based reads.
|
|
59
|
+
*
|
|
60
|
+
* Suitable for single-process embedded DWN instances and tests.
|
|
61
|
+
* For multi-node deployments, use a distributed implementation (NATS, Redis, etc.).
|
|
62
|
+
*/
|
|
63
|
+
export class EventEmitterEventLog implements EventLog {
|
|
64
|
+
private emitter = mitt<EmitterEvents>();
|
|
65
|
+
private isOpen: boolean = false;
|
|
66
|
+
private errorHandler: (error: any) => void = (error): void => { console.error('event log error', error); };
|
|
67
|
+
private maxEventsPerTenant: number;
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Per-tenant ordered event storage.
|
|
71
|
+
* Key: tenant DID → Map of seq → StoredEntry.
|
|
72
|
+
*/
|
|
73
|
+
private tenantLogs: Map<string, Map<number, StoredEntry>> = new Map();
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Per-tenant monotonic sequence counter.
|
|
77
|
+
*/
|
|
78
|
+
private tenantSeqs: Map<string, number> = new Map();
|
|
79
|
+
|
|
80
|
+
constructor(config: EventEmitterEventLogConfig = {}) {
|
|
81
|
+
this.maxEventsPerTenant = config.maxEventsPerTenant ?? 10_000;
|
|
82
|
+
|
|
83
|
+
if (config.errorHandler) {
|
|
84
|
+
this.errorHandler = config.errorHandler;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
public async open(): Promise<void> {
|
|
89
|
+
this.isOpen = true;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
public async close(): Promise<void> {
|
|
93
|
+
this.isOpen = false;
|
|
94
|
+
this.emitter.all.clear();
|
|
95
|
+
this.tenantLogs.clear();
|
|
96
|
+
this.tenantSeqs.clear();
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
public async emit(tenant: string, event: MessageEvent, indexes: KeyValues): Promise<string> {
|
|
100
|
+
if (!this.isOpen) {
|
|
101
|
+
this.errorHandler(new DwnError(
|
|
102
|
+
DwnErrorCode.EventLogNotOpenError,
|
|
103
|
+
'a message emitted when EventLog is closed'
|
|
104
|
+
));
|
|
105
|
+
return '';
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
// Assign a monotonic sequence number for this tenant.
|
|
109
|
+
const prevSeq = this.tenantSeqs.get(tenant) ?? 0;
|
|
110
|
+
const seq = prevSeq + 1;
|
|
111
|
+
this.tenantSeqs.set(tenant, seq);
|
|
112
|
+
|
|
113
|
+
// Persist the event.
|
|
114
|
+
let log = this.tenantLogs.get(tenant);
|
|
115
|
+
if (log === undefined) {
|
|
116
|
+
log = new Map();
|
|
117
|
+
this.tenantLogs.set(tenant, log);
|
|
118
|
+
}
|
|
119
|
+
log.set(seq, { event, indexes });
|
|
120
|
+
|
|
121
|
+
// Evict oldest entries if the log exceeds the retention limit.
|
|
122
|
+
if (log.size > this.maxEventsPerTenant) {
|
|
123
|
+
const evictCount = log.size - this.maxEventsPerTenant;
|
|
124
|
+
let evicted = 0;
|
|
125
|
+
for (const key of log.keys()) {
|
|
126
|
+
if (evicted >= evictCount) { break; }
|
|
127
|
+
log.delete(key);
|
|
128
|
+
evicted++;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
// Notify in-process subscribers.
|
|
133
|
+
const channel = `${tenant}_${EVENTS_LISTENER_CHANNEL}`;
|
|
134
|
+
this.emitter.emit(channel, { tenant, event, indexes, seq });
|
|
135
|
+
|
|
136
|
+
return String(seq);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
public async read(tenant: string, options: EventLogReadOptions = {}): Promise<EventLogReadResult> {
|
|
140
|
+
const { cursor, limit, filters } = options;
|
|
141
|
+
const cursorSeq = cursor !== undefined ? EventEmitterEventLog.parseCursor(cursor) : undefined;
|
|
142
|
+
const log = this.tenantLogs.get(tenant);
|
|
143
|
+
|
|
144
|
+
if (log === undefined || log.size === 0) {
|
|
145
|
+
return { events: [], cursor };
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
const results: EventLogEntry[] = [];
|
|
149
|
+
const maxResults = limit ?? Number.MAX_SAFE_INTEGER;
|
|
150
|
+
|
|
151
|
+
for (const [seq, entry] of log) {
|
|
152
|
+
// Skip entries at or before the cursor.
|
|
153
|
+
if (cursorSeq !== undefined && seq <= cursorSeq) { continue; }
|
|
154
|
+
|
|
155
|
+
// Apply filters if provided (OR semantics — match any filter).
|
|
156
|
+
if (filters !== undefined && filters.length > 0) {
|
|
157
|
+
if (!FilterUtility.matchAnyFilter(entry.indexes, filters)) { continue; }
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
results.push({
|
|
161
|
+
seq,
|
|
162
|
+
event : entry.event,
|
|
163
|
+
indexes : entry.indexes,
|
|
164
|
+
});
|
|
165
|
+
|
|
166
|
+
if (results.length >= maxResults) { break; }
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
const lastSeq = results.length > 0 ? results[results.length - 1].seq : undefined;
|
|
170
|
+
return { events: results, cursor: lastSeq !== undefined ? String(lastSeq) : cursor };
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
/**
|
|
174
|
+
* Parse an opaque cursor string into an internal sequence number.
|
|
175
|
+
*/
|
|
176
|
+
private static parseCursor(cursor: string): number {
|
|
177
|
+
const seq = Number(cursor);
|
|
178
|
+
if (Number.isNaN(seq) || seq < 0) {
|
|
179
|
+
throw new DwnError(DwnErrorCode.EventLogNotOpenError, `invalid cursor: '${cursor}'`);
|
|
180
|
+
}
|
|
181
|
+
return seq;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
public async subscribe(
|
|
185
|
+
tenant: string,
|
|
186
|
+
id: string,
|
|
187
|
+
listener: SubscriptionListener,
|
|
188
|
+
options?: EventLogSubscribeOptions,
|
|
189
|
+
): Promise<EventSubscription> {
|
|
190
|
+
const channel = `${tenant}_${EVENTS_LISTENER_CHANNEL}`;
|
|
191
|
+
const { cursor, filters } = options ?? {};
|
|
192
|
+
|
|
193
|
+
if (cursor !== undefined) {
|
|
194
|
+
// ---- Cursor mode: catch-up from stored events, then EOSE, then live ----
|
|
195
|
+
const cursorSeq = EventEmitterEventLog.parseCursor(cursor);
|
|
196
|
+
|
|
197
|
+
// Buffer live events that arrive during catch-up to avoid losing them.
|
|
198
|
+
type BufferedEvent = { event: MessageEvent; seq: number };
|
|
199
|
+
const pendingLiveEvents: BufferedEvent[] = [];
|
|
200
|
+
let catchUpComplete = false;
|
|
201
|
+
|
|
202
|
+
// Step 1: Register live listener FIRST so no events are missed during read.
|
|
203
|
+
const handler = (payload: EmitterPayload): void => {
|
|
204
|
+
if (filters !== undefined && filters.length > 0) {
|
|
205
|
+
if (!FilterUtility.matchAnyFilter(payload.indexes, filters)) { return; }
|
|
206
|
+
}
|
|
207
|
+
if (!catchUpComplete) {
|
|
208
|
+
pendingLiveEvents.push({ event: payload.event, seq: payload.seq });
|
|
209
|
+
} else {
|
|
210
|
+
listener({ type: 'event', cursor: String(payload.seq), event: payload.event });
|
|
211
|
+
}
|
|
212
|
+
};
|
|
213
|
+
|
|
214
|
+
this.emitter.on(channel, handler);
|
|
215
|
+
|
|
216
|
+
// Step 2: Read stored events from cursor and deliver them.
|
|
217
|
+
const readResult = await this.read(tenant, { cursor, filters });
|
|
218
|
+
// The read cursor is the last event's seq (string) or the input cursor if nothing new.
|
|
219
|
+
const eoseCursor = readResult.cursor ?? cursor;
|
|
220
|
+
const lastCatchUpSeq = readResult.cursor !== undefined ? Number(readResult.cursor) : cursorSeq;
|
|
221
|
+
|
|
222
|
+
for (const entry of readResult.events) {
|
|
223
|
+
listener({ type: 'event', cursor: String(entry.seq), event: entry.event });
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
// Step 3: Deliver any live events that arrived during catch-up (with seq > lastCatchUpSeq).
|
|
227
|
+
catchUpComplete = true;
|
|
228
|
+
for (const liveEvent of pendingLiveEvents) {
|
|
229
|
+
if (liveEvent.seq > lastCatchUpSeq) {
|
|
230
|
+
listener({ type: 'event', cursor: String(liveEvent.seq), event: liveEvent.event });
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
// Step 4: Send EOSE marker.
|
|
235
|
+
listener({ type: 'eose', cursor: eoseCursor });
|
|
236
|
+
|
|
237
|
+
return {
|
|
238
|
+
id,
|
|
239
|
+
close: async (): Promise<void> => { this.emitter.off(channel, handler); }
|
|
240
|
+
};
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
// ---- No cursor: live events only ----
|
|
244
|
+
|
|
245
|
+
const handler = (payload: EmitterPayload): void => {
|
|
246
|
+
if (filters !== undefined && filters.length > 0) {
|
|
247
|
+
if (!FilterUtility.matchAnyFilter(payload.indexes, filters)) { return; }
|
|
248
|
+
}
|
|
249
|
+
listener({ type: 'event', cursor: String(payload.seq), event: payload.event });
|
|
250
|
+
};
|
|
251
|
+
|
|
252
|
+
this.emitter.on(channel, handler);
|
|
253
|
+
|
|
254
|
+
return {
|
|
255
|
+
id,
|
|
256
|
+
close: async (): Promise<void> => { this.emitter.off(channel, handler); }
|
|
257
|
+
};
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
public async trim(tenant: string, olderThan: number | string): Promise<void> {
|
|
261
|
+
const log = this.tenantLogs.get(tenant);
|
|
262
|
+
if (log === undefined) { return; }
|
|
263
|
+
|
|
264
|
+
if (typeof olderThan === 'number') {
|
|
265
|
+
// Trim by sequence number: delete entries with seq < olderThan.
|
|
266
|
+
for (const seq of log.keys()) {
|
|
267
|
+
if (seq < olderThan) {
|
|
268
|
+
log.delete(seq);
|
|
269
|
+
} else {
|
|
270
|
+
break; // Map is ordered by insertion (ascending seq), safe to stop.
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
} else {
|
|
274
|
+
// Trim by ISO-8601 timestamp: delete entries whose message timestamp is before the given time.
|
|
275
|
+
for (const [seq, entry] of log) {
|
|
276
|
+
const messageTimestamp = (entry.indexes['messageTimestamp'] as string) ?? '';
|
|
277
|
+
if (messageTimestamp < olderThan) {
|
|
278
|
+
log.delete(seq);
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
}
|