@enbox/dwn-sdk-js 0.0.7 → 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 +761 -909
- package/dist/esm/generated/precompiled-validators.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-error.js +9 -12
- package/dist/esm/src/core/dwn-error.js.map +1 -1
- package/dist/esm/src/core/grant-authorization.js +16 -3
- package/dist/esm/src/core/grant-authorization.js.map +1 -1
- package/dist/esm/src/core/protocol-authorization-validation.js +67 -0
- package/dist/esm/src/core/protocol-authorization-validation.js.map +1 -1
- package/dist/esm/src/core/protocol-authorization.js +51 -30
- package/dist/esm/src/core/protocol-authorization.js.map +1 -1
- package/dist/esm/src/core/records-grant-authorization.js +6 -8
- package/dist/esm/src/core/records-grant-authorization.js.map +1 -1
- package/dist/esm/src/dwn.js +42 -18
- 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 +7 -11
- package/dist/esm/src/handlers/messages-read.js.map +1 -1
- package/dist/esm/src/handlers/messages-subscribe.js +22 -24
- package/dist/esm/src/handlers/messages-subscribe.js.map +1 -1
- package/dist/esm/src/handlers/messages-sync.js +11 -15
- package/dist/esm/src/handlers/messages-sync.js.map +1 -1
- package/dist/esm/src/handlers/protocols-configure.js +37 -27
- package/dist/esm/src/handlers/protocols-configure.js.map +1 -1
- package/dist/esm/src/handlers/protocols-query.js +7 -11
- package/dist/esm/src/handlers/protocols-query.js.map +1 -1
- package/dist/esm/src/handlers/records-count.js +10 -12
- package/dist/esm/src/handlers/records-count.js.map +1 -1
- package/dist/esm/src/handlers/records-delete.js +10 -18
- package/dist/esm/src/handlers/records-delete.js.map +1 -1
- package/dist/esm/src/handlers/records-query.js +11 -15
- package/dist/esm/src/handlers/records-query.js.map +1 -1
- package/dist/esm/src/handlers/records-read.js +31 -26
- package/dist/esm/src/handlers/records-read.js.map +1 -1
- package/dist/esm/src/handlers/records-subscribe.js +39 -26
- package/dist/esm/src/handlers/records-subscribe.js.map +1 -1
- package/dist/esm/src/handlers/records-write.js +47 -105
- 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-subscribe.js +1 -0
- package/dist/esm/src/interfaces/messages-subscribe.js.map +1 -1
- package/dist/esm/src/interfaces/protocols-configure.js +25 -3
- package/dist/esm/src/interfaces/protocols-configure.js.map +1 -1
- package/dist/esm/src/interfaces/records-count.js +1 -1
- package/dist/esm/src/interfaces/records-count.js.map +1 -1
- package/dist/esm/src/interfaces/records-delete.js +1 -1
- package/dist/esm/src/interfaces/records-delete.js.map +1 -1
- package/dist/esm/src/interfaces/records-query.js +1 -1
- package/dist/esm/src/interfaces/records-query.js.map +1 -1
- package/dist/esm/src/interfaces/records-read.js +1 -1
- package/dist/esm/src/interfaces/records-read.js.map +1 -1
- package/dist/esm/src/interfaces/records-subscribe.js +2 -1
- package/dist/esm/src/interfaces/records-subscribe.js.map +1 -1
- package/dist/esm/src/interfaces/records-write-signing.js +1 -12
- package/dist/esm/src/interfaces/records-write-signing.js.map +1 -1
- package/dist/esm/src/interfaces/records-write.js +22 -41
- package/dist/esm/src/interfaces/records-write.js.map +1 -1
- package/dist/esm/src/protocols/permission-grant.js +1 -1
- package/dist/esm/src/protocols/permission-grant.js.map +1 -1
- package/dist/esm/src/protocols/permission-request.js +1 -1
- package/dist/esm/src/protocols/permission-request.js.map +1 -1
- package/dist/esm/src/protocols/permissions.js +113 -5
- package/dist/esm/src/protocols/permissions.js.map +1 -1
- package/dist/esm/src/state-index/state-index-level.js +5 -7
- package/dist/esm/src/state-index/state-index-level.js.map +1 -1
- package/dist/esm/src/store/data-store-level.js +110 -33
- package/dist/esm/src/store/data-store-level.js.map +1 -1
- package/dist/esm/src/store/index-level.js +42 -32
- package/dist/esm/src/store/index-level.js.map +1 -1
- package/dist/esm/src/store/storage-controller.js +6 -6
- 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/hd-key.js +0 -8
- package/dist/esm/src/utils/hd-key.js.map +1 -1
- package/dist/esm/src/utils/messages.js +16 -34
- package/dist/esm/src/utils/messages.js.map +1 -1
- package/dist/esm/src/utils/records.js +5 -43
- package/dist/esm/src/utils/records.js.map +1 -1
- package/dist/esm/tests/core/protocol-authorization.spec.js +2 -1
- package/dist/esm/tests/core/protocol-authorization.spec.js.map +1 -1
- package/dist/esm/tests/dwn.spec.js +32 -43
- 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 +14 -7
- package/dist/esm/tests/features/author-delegated-grant.spec.js.map +1 -1
- package/dist/esm/tests/features/owner-delegated-grant.spec.js +9 -5
- package/dist/esm/tests/features/owner-delegated-grant.spec.js.map +1 -1
- package/dist/esm/tests/features/owner-signature.spec.js +14 -7
- package/dist/esm/tests/features/owner-signature.spec.js.map +1 -1
- package/dist/esm/tests/features/permissions.spec.js +12 -12
- package/dist/esm/tests/features/permissions.spec.js.map +1 -1
- package/dist/esm/tests/features/protocol-composition.spec.js +636 -5
- package/dist/esm/tests/features/protocol-composition.spec.js.map +1 -1
- package/dist/esm/tests/features/protocol-create-action.spec.js +4 -4
- package/dist/esm/tests/features/protocol-create-action.spec.js.map +1 -1
- package/dist/esm/tests/features/protocol-delete-action.spec.js +7 -7
- package/dist/esm/tests/features/protocol-delete-action.spec.js.map +1 -1
- package/dist/esm/tests/features/protocol-update-action.spec.js +4 -4
- 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 +4 -4
- 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 +16 -4
- package/dist/esm/tests/features/records-tags.spec.js.map +1 -1
- package/dist/esm/tests/features/resumable-tasks.spec.js +7 -8
- package/dist/esm/tests/features/resumable-tasks.spec.js.map +1 -1
- package/dist/esm/tests/handlers/messages-read.spec.js +11 -5
- package/dist/esm/tests/handlers/messages-read.spec.js.map +1 -1
- package/dist/esm/tests/handlers/messages-subscribe.spec.js +169 -22
- package/dist/esm/tests/handlers/messages-subscribe.spec.js.map +1 -1
- package/dist/esm/tests/handlers/messages-sync.spec.js +103 -21
- package/dist/esm/tests/handlers/messages-sync.spec.js.map +1 -1
- package/dist/esm/tests/handlers/protocols-configure.spec.js +5 -5
- package/dist/esm/tests/handlers/protocols-configure.spec.js.map +1 -1
- package/dist/esm/tests/handlers/protocols-query.spec.js +5 -5
- package/dist/esm/tests/handlers/protocols-query.spec.js.map +1 -1
- package/dist/esm/tests/handlers/records-count.spec.js +9 -4
- package/dist/esm/tests/handlers/records-count.spec.js.map +1 -1
- package/dist/esm/tests/handlers/records-delete.spec.js +24 -25
- package/dist/esm/tests/handlers/records-delete.spec.js.map +1 -1
- package/dist/esm/tests/handlers/records-query.spec.js +68 -9
- package/dist/esm/tests/handlers/records-query.spec.js.map +1 -1
- package/dist/esm/tests/handlers/records-read.spec.js +24 -138
- package/dist/esm/tests/handlers/records-read.spec.js.map +1 -1
- package/dist/esm/tests/handlers/records-subscribe.spec.js +175 -35
- package/dist/esm/tests/handlers/records-subscribe.spec.js.map +1 -1
- package/dist/esm/tests/handlers/records-write.spec.js +173 -72
- package/dist/esm/tests/handlers/records-write.spec.js.map +1 -1
- package/dist/esm/tests/interfaces/records-write.spec.js +52 -68
- package/dist/esm/tests/interfaces/records-write.spec.js.map +1 -1
- package/dist/esm/tests/protocols/permission-grant.spec.js +6 -6
- package/dist/esm/tests/protocols/permission-grant.spec.js.map +1 -1
- package/dist/esm/tests/protocols/permission-request.spec.js +4 -4
- package/dist/esm/tests/protocols/permission-request.spec.js.map +1 -1
- package/dist/esm/tests/protocols/permissions.spec.js +4 -4
- package/dist/esm/tests/protocols/permissions.spec.js.map +1 -1
- package/dist/esm/tests/scenarios/aggregator.spec.js +4 -4
- package/dist/esm/tests/scenarios/aggregator.spec.js.map +1 -1
- package/dist/esm/tests/scenarios/deleted-record.spec.js +350 -5
- package/dist/esm/tests/scenarios/deleted-record.spec.js.map +1 -1
- package/dist/esm/tests/scenarios/end-to-end-tests.spec.js +4 -4
- package/dist/esm/tests/scenarios/end-to-end-tests.spec.js.map +1 -1
- package/dist/esm/tests/scenarios/nested-roles.spec.js +4 -4
- package/dist/esm/tests/scenarios/nested-roles.spec.js.map +1 -1
- package/dist/esm/tests/scenarios/subscriptions.spec.js +93 -40
- package/dist/esm/tests/scenarios/subscriptions.spec.js.map +1 -1
- package/dist/esm/tests/store/data-store-level.spec.js +102 -41
- package/dist/esm/tests/store/data-store-level.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-suite.js +6 -4
- package/dist/esm/tests/test-suite.js.map +1 -1
- package/dist/esm/tests/utils/messages.spec.js +12 -5
- package/dist/esm/tests/utils/messages.spec.js.map +1 -1
- package/dist/esm/tests/utils/records.spec.js +8 -12
- package/dist/esm/tests/utils/records.spec.js.map +1 -1
- package/dist/esm/tests/utils/test-data-generator.js +35 -2
- package/dist/esm/tests/utils/test-data-generator.js.map +1 -1
- package/dist/esm/tests/validation/json-schemas/records/records-write.spec.js +37 -8
- 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-validation.d.ts +21 -0
- package/dist/types/src/core/protocol-authorization-validation.d.ts.map +1 -1
- package/dist/types/src/core/protocol-authorization.d.ts +19 -11
- package/dist/types/src/core/protocol-authorization.d.ts.map +1 -1
- 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 -25
- 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-signing.d.ts +3 -4
- package/dist/types/src/interfaces/records-write-signing.d.ts.map +1 -1
- package/dist/types/src/interfaces/records-write.d.ts +5 -11
- 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.d.ts +4 -0
- 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/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/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-validation.ts +96 -0
- package/src/core/protocol-authorization.ts +67 -23
- 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 -120
- package/src/index.ts +9 -5
- package/src/interfaces/messages-subscribe.ts +7 -1
- package/src/interfaces/protocols-configure.ts +40 -3
- 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-signing.ts +2 -22
- package/src/interfaces/records-write.ts +25 -48
- 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.ts +44 -35
- 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/records.ts +7 -58
- package/dist/esm/src/event-stream/event-emitter-stream.js +0 -46
- 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 -68
- 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 -114
- 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,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
|
+
}
|
|
@@ -1,9 +1,7 @@
|
|
|
1
|
-
import type { DataStore } from '../types/data-store.js';
|
|
2
|
-
import type { DidResolver } from '@enbox/dids';
|
|
3
1
|
import type { GenericMessage } from '../types/message-types.js';
|
|
4
2
|
import type { MessageStore } from '../types/message-store.js';
|
|
5
|
-
import type { MethodHandler } from '../types/method-handler.js';
|
|
6
3
|
import type { RecordsQueryReplyEntry } from '../types/records-types.js';
|
|
4
|
+
import type { HandlerDependencies, MethodHandler } from '../types/method-handler.js';
|
|
7
5
|
import type { MessagesReadMessage, MessagesReadReply, MessagesReadReplyEntry } from '../types/messages-types.js';
|
|
8
6
|
|
|
9
7
|
import { authenticate } from '../core/auth.js';
|
|
@@ -19,7 +17,8 @@ import { DwnError, DwnErrorCode } from '../core/dwn-error.js';
|
|
|
19
17
|
type HandleArgs = { tenant: string, message: MessagesReadMessage };
|
|
20
18
|
|
|
21
19
|
export class MessagesReadHandler implements MethodHandler {
|
|
22
|
-
|
|
20
|
+
|
|
21
|
+
constructor(private deps: HandlerDependencies) {}
|
|
23
22
|
|
|
24
23
|
public async handle({ tenant, message }: HandleArgs): Promise<MessagesReadReply> {
|
|
25
24
|
let messagesRead: MessagesRead;
|
|
@@ -31,18 +30,18 @@ export class MessagesReadHandler implements MethodHandler {
|
|
|
31
30
|
}
|
|
32
31
|
|
|
33
32
|
try {
|
|
34
|
-
await authenticate(message.authorization, this.didResolver);
|
|
33
|
+
await authenticate(message.authorization, this.deps.didResolver);
|
|
35
34
|
} catch (e) {
|
|
36
35
|
return messageReplyFromError(e, 401);
|
|
37
36
|
}
|
|
38
37
|
|
|
39
|
-
const messageResult = await this.messageStore.get(tenant, message.descriptor.messageCid);
|
|
38
|
+
const messageResult = await this.deps.messageStore.get(tenant, message.descriptor.messageCid);
|
|
40
39
|
if (messageResult === undefined) {
|
|
41
40
|
return { status: { code: 404, detail: 'Not Found' } };
|
|
42
41
|
}
|
|
43
42
|
|
|
44
43
|
try {
|
|
45
|
-
await MessagesReadHandler.authorizeMessagesRead(tenant, messagesRead, messageResult, this.messageStore);
|
|
44
|
+
await MessagesReadHandler.authorizeMessagesRead(tenant, messagesRead, messageResult, this.deps.messageStore);
|
|
46
45
|
} catch (error) {
|
|
47
46
|
return messageReplyFromError(error, 401);
|
|
48
47
|
}
|
|
@@ -59,7 +58,7 @@ export class MessagesReadHandler implements MethodHandler {
|
|
|
59
58
|
delete recordsWrite.encodedData;
|
|
60
59
|
} else {
|
|
61
60
|
// otherwise check the data store for the associated data
|
|
62
|
-
const result = await this.dataStore
|
|
61
|
+
const result = await this.deps.dataStore!.get(tenant, recordsWrite.recordId, recordsWrite.descriptor.dataCid);
|
|
63
62
|
if (result?.dataStream !== undefined) {
|
|
64
63
|
entry.data = result.dataStream;
|
|
65
64
|
}
|
|
@@ -100,4 +99,4 @@ export class MessagesReadHandler implements MethodHandler {
|
|
|
100
99
|
throw new DwnError(DwnErrorCode.MessagesReadAuthorizationFailed, 'protocol message failed authorization');
|
|
101
100
|
}
|
|
102
101
|
}
|
|
103
|
-
}
|
|
102
|
+
}
|
|
@@ -1,11 +1,9 @@
|
|
|
1
|
-
import type { DidResolver } from '@enbox/dids';
|
|
2
1
|
import type { MessageStore } from '../types/message-store.js';
|
|
3
|
-
import type {
|
|
4
|
-
import type {
|
|
5
|
-
import type { MessagesSubscribeMessage, MessagesSubscribeReply
|
|
2
|
+
import type { SubscriptionListener } from '../types/subscriptions.js';
|
|
3
|
+
import type { HandlerDependencies, MethodHandler } from '../types/method-handler.js';
|
|
4
|
+
import type { MessagesSubscribeMessage, MessagesSubscribeReply } from '../types/messages-types.js';
|
|
6
5
|
|
|
7
6
|
import { authenticate } from '../core/auth.js';
|
|
8
|
-
import { FilterUtility } from '../utils/filter.js';
|
|
9
7
|
import { Message } from '../core/message.js';
|
|
10
8
|
import { messageReplyFromError } from '../core/message-reply.js';
|
|
11
9
|
import { Messages } from '../utils/messages.js';
|
|
@@ -15,11 +13,8 @@ import { PermissionsProtocol } from '../protocols/permissions.js';
|
|
|
15
13
|
import { DwnError, DwnErrorCode } from '../core/dwn-error.js';
|
|
16
14
|
|
|
17
15
|
export class MessagesSubscribeHandler implements MethodHandler {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
private messageStore: MessageStore,
|
|
21
|
-
private eventStream?: EventStream
|
|
22
|
-
) {}
|
|
16
|
+
|
|
17
|
+
constructor(private deps: HandlerDependencies) {}
|
|
23
18
|
|
|
24
19
|
public async handle({
|
|
25
20
|
tenant,
|
|
@@ -28,11 +23,11 @@ export class MessagesSubscribeHandler implements MethodHandler {
|
|
|
28
23
|
}: {
|
|
29
24
|
tenant: string;
|
|
30
25
|
message: MessagesSubscribeMessage;
|
|
31
|
-
subscriptionHandler:
|
|
26
|
+
subscriptionHandler: SubscriptionListener;
|
|
32
27
|
}): Promise<MessagesSubscribeReply> {
|
|
33
|
-
if (this.
|
|
28
|
+
if (this.deps.eventLog === undefined) {
|
|
34
29
|
return messageReplyFromError(new DwnError(
|
|
35
|
-
DwnErrorCode.
|
|
30
|
+
DwnErrorCode.MessagesSubscribeEventLogUnimplemented,
|
|
36
31
|
'Subscriptions are not supported'
|
|
37
32
|
), 501);
|
|
38
33
|
}
|
|
@@ -45,28 +40,29 @@ export class MessagesSubscribeHandler implements MethodHandler {
|
|
|
45
40
|
}
|
|
46
41
|
|
|
47
42
|
try {
|
|
48
|
-
await authenticate(message.authorization, this.didResolver);
|
|
49
|
-
await MessagesSubscribeHandler.authorizeMessagesSubscribe(tenant, messagesSubscribe, this.messageStore);
|
|
43
|
+
await authenticate(message.authorization, this.deps.didResolver);
|
|
44
|
+
await MessagesSubscribeHandler.authorizeMessagesSubscribe(tenant, messagesSubscribe, this.deps.messageStore);
|
|
50
45
|
} catch (error) {
|
|
51
46
|
return messageReplyFromError(error, 401);
|
|
52
47
|
}
|
|
53
48
|
|
|
54
|
-
const { filters } = message.descriptor;
|
|
55
|
-
const messagesFilters = Messages.convertFilters(filters);
|
|
49
|
+
const { filters, cursor: eventLogCursor } = message.descriptor;
|
|
50
|
+
const messagesFilters = Messages.convertFilters(filters, this.deps.coreProtocols);
|
|
56
51
|
const messageCid = await Message.getCid(message);
|
|
57
52
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
const subscription = await this.eventStream.subscribe(tenant, messageCid, listener);
|
|
53
|
+
try {
|
|
54
|
+
const subscription = await this.deps.eventLog.subscribe(tenant, messageCid, subscriptionHandler, {
|
|
55
|
+
cursor : eventLogCursor,
|
|
56
|
+
filters : messagesFilters,
|
|
57
|
+
});
|
|
65
58
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
59
|
+
return {
|
|
60
|
+
status: { code: 200, detail: 'OK' },
|
|
61
|
+
subscription,
|
|
62
|
+
};
|
|
63
|
+
} catch (error) {
|
|
64
|
+
return messageReplyFromError(error, 500);
|
|
65
|
+
}
|
|
70
66
|
}
|
|
71
67
|
|
|
72
68
|
private static async authorizeMessagesSubscribe(tenant: string, messagesSubscribe: MessagesSubscribe, messageStore: MessageStore): Promise<void> {
|
|
@@ -1,7 +1,5 @@
|
|
|
1
|
-
import type { DidResolver } from '@enbox/dids';
|
|
2
1
|
import type { MessageStore } from '../types/message-store.js';
|
|
3
|
-
import type { MethodHandler } from '../types/method-handler.js';
|
|
4
|
-
import type { StateIndex } from '../types/state-index.js';
|
|
2
|
+
import type { HandlerDependencies, MethodHandler } from '../types/method-handler.js';
|
|
5
3
|
import type { MessagesSyncMessage, MessagesSyncReply } from '../types/messages-types.js';
|
|
6
4
|
|
|
7
5
|
import { authenticate } from '../core/auth.js';
|
|
@@ -15,11 +13,7 @@ import { DwnError, DwnErrorCode } from '../core/dwn-error.js';
|
|
|
15
13
|
|
|
16
14
|
export class MessagesSyncHandler implements MethodHandler {
|
|
17
15
|
|
|
18
|
-
constructor(
|
|
19
|
-
private didResolver: DidResolver,
|
|
20
|
-
private messageStore: MessageStore,
|
|
21
|
-
private stateIndex: StateIndex,
|
|
22
|
-
) { }
|
|
16
|
+
constructor(private deps: HandlerDependencies) { }
|
|
23
17
|
|
|
24
18
|
public async handle({
|
|
25
19
|
tenant,
|
|
@@ -34,8 +28,8 @@ export class MessagesSyncHandler implements MethodHandler {
|
|
|
34
28
|
}
|
|
35
29
|
|
|
36
30
|
try {
|
|
37
|
-
await authenticate(message.authorization, this.didResolver);
|
|
38
|
-
await MessagesSyncHandler.authorizeMessagesSync(tenant, messagesSync, this.messageStore);
|
|
31
|
+
await authenticate(message.authorization, this.deps.didResolver);
|
|
32
|
+
await MessagesSyncHandler.authorizeMessagesSync(tenant, messagesSync, this.deps.messageStore);
|
|
39
33
|
} catch (e) {
|
|
40
34
|
return messageReplyFromError(e, 401);
|
|
41
35
|
}
|
|
@@ -46,8 +40,8 @@ export class MessagesSyncHandler implements MethodHandler {
|
|
|
46
40
|
switch (action) {
|
|
47
41
|
case 'root': {
|
|
48
42
|
const rootHash = protocol !== undefined
|
|
49
|
-
? await this.stateIndex
|
|
50
|
-
: await this.stateIndex
|
|
43
|
+
? await this.deps.stateIndex!.getProtocolRoot(tenant, protocol)
|
|
44
|
+
: await this.deps.stateIndex!.getRoot(tenant);
|
|
51
45
|
return {
|
|
52
46
|
status : { code: 200, detail: 'OK' },
|
|
53
47
|
root : hashToHex(rootHash),
|
|
@@ -57,8 +51,8 @@ export class MessagesSyncHandler implements MethodHandler {
|
|
|
57
51
|
case 'subtree': {
|
|
58
52
|
const bitPath = MessagesSyncHandler.parseBitPrefix(prefix!);
|
|
59
53
|
const hash = protocol !== undefined
|
|
60
|
-
? await this.stateIndex
|
|
61
|
-
: await this.stateIndex
|
|
54
|
+
? await this.deps.stateIndex!.getProtocolSubtreeHash(tenant, protocol, bitPath)
|
|
55
|
+
: await this.deps.stateIndex!.getSubtreeHash(tenant, bitPath);
|
|
62
56
|
return {
|
|
63
57
|
status : { code: 200, detail: 'OK' },
|
|
64
58
|
hash : hashToHex(hash),
|
|
@@ -68,8 +62,8 @@ export class MessagesSyncHandler implements MethodHandler {
|
|
|
68
62
|
case 'leaves': {
|
|
69
63
|
const bitPath = MessagesSyncHandler.parseBitPrefix(prefix!);
|
|
70
64
|
const leaves = protocol !== undefined
|
|
71
|
-
? await this.stateIndex
|
|
72
|
-
: await this.stateIndex
|
|
65
|
+
? await this.deps.stateIndex!.getProtocolLeaves(tenant, protocol, bitPath)
|
|
66
|
+
: await this.deps.stateIndex!.getLeaves(tenant, bitPath);
|
|
73
67
|
return {
|
|
74
68
|
status : { code: 200, detail: 'OK' },
|
|
75
69
|
entries : leaves,
|
|
@@ -1,9 +1,6 @@
|
|
|
1
|
-
import type { DidResolver } from '@enbox/dids';
|
|
2
|
-
import type { EventStream } from '../types/subscriptions.js';
|
|
3
1
|
import type { GenericMessageReply } from '../types/message-types.js';
|
|
4
2
|
import type { MessageStore } from '../types//message-store.js';
|
|
5
|
-
import type { MethodHandler } from '../types/method-handler.js';
|
|
6
|
-
import type { StateIndex } from '../types/state-index.js';
|
|
3
|
+
import type { HandlerDependencies, MethodHandler } from '../types/method-handler.js';
|
|
7
4
|
import type { ProtocolDefinition, ProtocolRuleSet, ProtocolsConfigureMessage } from '../types/protocols-types.js';
|
|
8
5
|
|
|
9
6
|
import { authenticate } from '../core/auth.js';
|
|
@@ -18,12 +15,7 @@ import { getRuleSetAtPath, parseCrossProtocolRef } from '../utils/protocols.js';
|
|
|
18
15
|
|
|
19
16
|
export class ProtocolsConfigureHandler implements MethodHandler {
|
|
20
17
|
|
|
21
|
-
constructor(
|
|
22
|
-
private didResolver: DidResolver,
|
|
23
|
-
private messageStore: MessageStore,
|
|
24
|
-
private stateIndex: StateIndex,
|
|
25
|
-
private eventStream?: EventStream
|
|
26
|
-
) { }
|
|
18
|
+
constructor(private deps: HandlerDependencies) { }
|
|
27
19
|
|
|
28
20
|
public async handle({
|
|
29
21
|
tenant,
|
|
@@ -38,8 +30,8 @@ export class ProtocolsConfigureHandler implements MethodHandler {
|
|
|
38
30
|
|
|
39
31
|
// authentication & authorization
|
|
40
32
|
try {
|
|
41
|
-
await authenticate(message.authorization, this.didResolver);
|
|
42
|
-
await ProtocolsConfigureHandler.authorizeProtocolsConfigure(tenant, protocolsConfigure, this.messageStore);
|
|
33
|
+
await authenticate(message.authorization, this.deps.didResolver);
|
|
34
|
+
await ProtocolsConfigureHandler.authorizeProtocolsConfigure(tenant, protocolsConfigure, this.deps.messageStore);
|
|
43
35
|
} catch (e) {
|
|
44
36
|
return messageReplyFromError(e, 401);
|
|
45
37
|
}
|
|
@@ -48,7 +40,7 @@ export class ProtocolsConfigureHandler implements MethodHandler {
|
|
|
48
40
|
// `$ref` paths must exist in the referenced protocols, and cross-protocol roles must exist.
|
|
49
41
|
try {
|
|
50
42
|
await ProtocolsConfigureHandler.validateCompositionDependencies(
|
|
51
|
-
tenant, message.descriptor.definition, this.messageStore
|
|
43
|
+
tenant, message.descriptor.definition, this.deps.messageStore
|
|
52
44
|
);
|
|
53
45
|
} catch (e) {
|
|
54
46
|
return messageReplyFromError(e, 400);
|
|
@@ -60,7 +52,7 @@ export class ProtocolsConfigureHandler implements MethodHandler {
|
|
|
60
52
|
method : DwnMethodName.Configure,
|
|
61
53
|
protocol : message.descriptor.definition.protocol
|
|
62
54
|
};
|
|
63
|
-
const { messages: existingMessages } = await this.messageStore.query(tenant, [ query ]);
|
|
55
|
+
const { messages: existingMessages } = await this.deps.messageStore.query(tenant, [ query ]);
|
|
64
56
|
|
|
65
57
|
// find newest message, and if the incoming message is the newest
|
|
66
58
|
let newestMessage = await Message.getNewestMessage(existingMessages);
|
|
@@ -75,13 +67,13 @@ export class ProtocolsConfigureHandler implements MethodHandler {
|
|
|
75
67
|
if (incomingMessageIsNewest) {
|
|
76
68
|
const indexes = ProtocolsConfigureHandler.constructIndexes(protocolsConfigure, true);
|
|
77
69
|
|
|
78
|
-
await this.messageStore.put(tenant, message, indexes);
|
|
70
|
+
await this.deps.messageStore.put(tenant, message, indexes);
|
|
79
71
|
const messageCid = await Message.getCid(message);
|
|
80
|
-
await this.stateIndex
|
|
72
|
+
await this.deps.stateIndex!.insert(tenant, messageCid, indexes);
|
|
81
73
|
|
|
82
|
-
// only emit if the event
|
|
83
|
-
if (this.
|
|
84
|
-
this.
|
|
74
|
+
// only emit if the event log is set
|
|
75
|
+
if (this.deps.eventLog !== undefined) {
|
|
76
|
+
await this.deps.eventLog.emit(tenant, { message }, indexes);
|
|
85
77
|
}
|
|
86
78
|
|
|
87
79
|
messageReply = {
|
|
@@ -91,9 +83,9 @@ export class ProtocolsConfigureHandler implements MethodHandler {
|
|
|
91
83
|
// incoming message is older — still store it as a historical version (not the latest)
|
|
92
84
|
const indexes = ProtocolsConfigureHandler.constructIndexes(protocolsConfigure, false);
|
|
93
85
|
|
|
94
|
-
await this.messageStore.put(tenant, message, indexes);
|
|
86
|
+
await this.deps.messageStore.put(tenant, message, indexes);
|
|
95
87
|
const messageCid = await Message.getCid(message);
|
|
96
|
-
await this.stateIndex
|
|
88
|
+
await this.deps.stateIndex!.insert(tenant, messageCid, indexes);
|
|
97
89
|
|
|
98
90
|
messageReply = {
|
|
99
91
|
status: { code: 202, detail: 'Accepted' }
|
|
@@ -108,8 +100,8 @@ export class ProtocolsConfigureHandler implements MethodHandler {
|
|
|
108
100
|
const updatedIndexes = ProtocolsConfigureHandler.constructIndexes(existingProtocolsConfigure, false);
|
|
109
101
|
const existingCid = await Message.getCid(existingMessage);
|
|
110
102
|
|
|
111
|
-
await this.messageStore.delete(tenant, existingCid);
|
|
112
|
-
await this.messageStore.put(tenant, existingMessage, updatedIndexes);
|
|
103
|
+
await this.deps.messageStore.delete(tenant, existingCid);
|
|
104
|
+
await this.deps.messageStore.put(tenant, existingMessage, updatedIndexes);
|
|
113
105
|
}
|
|
114
106
|
}
|
|
115
107
|
|
|
@@ -230,7 +222,7 @@ export class ProtocolsConfigureHandler implements MethodHandler {
|
|
|
230
222
|
const childRuleSet = ruleSet[key] as ProtocolRuleSet;
|
|
231
223
|
const childProtocolPath = protocolPath === '' ? key : `${protocolPath}/${key}`;
|
|
232
224
|
|
|
233
|
-
// Validate $ref path exists in the referenced protocol
|
|
225
|
+
// Validate $ref path exists in the referenced protocol and does not traverse through another $ref
|
|
234
226
|
if (childRuleSet.$ref !== undefined) {
|
|
235
227
|
const parsed = parseCrossProtocolRef(childRuleSet.$ref);
|
|
236
228
|
if (parsed !== undefined) {
|
|
@@ -244,13 +236,36 @@ export class ProtocolsConfigureHandler implements MethodHandler {
|
|
|
244
236
|
);
|
|
245
237
|
}
|
|
246
238
|
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
239
|
+
// Walk the target path segment-by-segment and reject if any intermediate node has a $ref
|
|
240
|
+
const segments = parsed.protocolPath.split('/');
|
|
241
|
+
let currentLevel: { [key: string]: ProtocolRuleSet } = refDefinition.structure;
|
|
242
|
+
|
|
243
|
+
for (let i = 0; i < segments.length; i++) {
|
|
244
|
+
const segment = segments[i];
|
|
245
|
+
const node = currentLevel[segment] as ProtocolRuleSet | undefined;
|
|
246
|
+
|
|
247
|
+
if (node === undefined) {
|
|
248
|
+
throw new DwnError(
|
|
249
|
+
DwnErrorCode.ProtocolsConfigureInvalidRefProtocolPath,
|
|
250
|
+
`'$ref' at protocol path '${childProtocolPath}' references type path '${parsed.protocolPath}' ` +
|
|
251
|
+
`which does not exist in protocol '${refDefinition.protocol}'.`
|
|
252
|
+
);
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
// If any node along the target path (including the final target) has a $ref,
|
|
256
|
+
// it means the composition chain passes through another protocol boundary.
|
|
257
|
+
// Multi-level composition is not supported — reject at install time.
|
|
258
|
+
if (node.$ref !== undefined) {
|
|
259
|
+
const traversedPath = segments.slice(0, i + 1).join('/');
|
|
260
|
+
throw new DwnError(
|
|
261
|
+
DwnErrorCode.ProtocolsConfigureInvalidRefTargetThroughRef,
|
|
262
|
+
`'$ref' at protocol path '${childProtocolPath}' references type path '${parsed.protocolPath}' ` +
|
|
263
|
+
`in protocol '${refDefinition.protocol}', but the node '${traversedPath}' is itself ` +
|
|
264
|
+
`a '$ref' composition point. multi-level composition (chaining through '$ref' nodes) is not supported.`
|
|
265
|
+
);
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
currentLevel = node as { [key: string]: ProtocolRuleSet };
|
|
254
269
|
}
|
|
255
270
|
}
|
|
256
271
|
}
|
|
@@ -312,4 +327,4 @@ export class ProtocolsConfigureHandler implements MethodHandler {
|
|
|
312
327
|
ProtocolsConfigureHandler.validateRefsAndRolesRecursively(childRuleSet, childProtocolPath, referencedDefinitions);
|
|
313
328
|
}
|
|
314
329
|
}
|
|
315
|
-
}
|
|
330
|
+
}
|