@enbox/dwn-sdk-js 0.4.0 → 0.4.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -4
- package/dist/browser.mjs +3 -10
- package/dist/browser.mjs.map +4 -4
- package/dist/esm/generated/precompiled-validators.js +799 -885
- package/dist/esm/generated/precompiled-validators.js.map +1 -1
- package/dist/esm/src/core/dwn-constant.js +5 -0
- package/dist/esm/src/core/dwn-constant.js.map +1 -1
- package/dist/esm/src/core/dwn-error.js +12 -4
- package/dist/esm/src/core/dwn-error.js.map +1 -1
- package/dist/esm/src/core/grant-authorization.js +9 -18
- package/dist/esm/src/core/grant-authorization.js.map +1 -1
- package/dist/esm/src/core/message-reply.js.map +1 -1
- package/dist/esm/src/core/messages-grant-authorization.js +28 -45
- package/dist/esm/src/core/messages-grant-authorization.js.map +1 -1
- package/dist/esm/src/core/protocol-authorization-action.js +25 -27
- package/dist/esm/src/core/protocol-authorization-action.js.map +1 -1
- package/dist/esm/src/core/protocol-authorization-validation.js +34 -89
- package/dist/esm/src/core/protocol-authorization-validation.js.map +1 -1
- package/dist/esm/src/core/protocol-authorization.js +44 -118
- package/dist/esm/src/core/protocol-authorization.js.map +1 -1
- package/dist/esm/src/core/protocols-grant-authorization.js +5 -5
- package/dist/esm/src/core/protocols-grant-authorization.js.map +1 -1
- package/dist/esm/src/core/recording-validation-state-reader.js +84 -0
- package/dist/esm/src/core/recording-validation-state-reader.js.map +1 -0
- package/dist/esm/src/core/records-grant-authorization.js +11 -11
- package/dist/esm/src/core/records-grant-authorization.js.map +1 -1
- package/dist/esm/src/core/replication-apply.js +123 -28
- package/dist/esm/src/core/replication-apply.js.map +1 -1
- package/dist/esm/src/core/resumable-task-manager.js +5 -4
- package/dist/esm/src/core/resumable-task-manager.js.map +1 -1
- package/dist/esm/src/core/validation-state-reader.js +237 -0
- package/dist/esm/src/core/validation-state-reader.js.map +1 -0
- package/dist/esm/src/dwn.js +165 -132
- package/dist/esm/src/dwn.js.map +1 -1
- package/dist/esm/src/enums/dwn-interface-method.js +0 -1
- package/dist/esm/src/enums/dwn-interface-method.js.map +1 -1
- package/dist/esm/src/event-stream/durable-event-log.js +365 -0
- package/dist/esm/src/event-stream/durable-event-log.js.map +1 -0
- package/dist/esm/src/event-stream/event-emitter-wake-publisher.js +25 -0
- package/dist/esm/src/event-stream/event-emitter-wake-publisher.js.map +1 -0
- package/dist/esm/src/handlers/messages-query.js +159 -0
- package/dist/esm/src/handlers/messages-query.js.map +1 -0
- package/dist/esm/src/handlers/messages-read.js +5 -5
- package/dist/esm/src/handlers/messages-read.js.map +1 -1
- package/dist/esm/src/handlers/messages-subscribe.js +8 -8
- package/dist/esm/src/handlers/messages-subscribe.js.map +1 -1
- package/dist/esm/src/handlers/protocols-configure.js +30 -49
- package/dist/esm/src/handlers/protocols-configure.js.map +1 -1
- package/dist/esm/src/handlers/protocols-query.js +1 -1
- package/dist/esm/src/handlers/protocols-query.js.map +1 -1
- package/dist/esm/src/handlers/records-count.js +20 -11
- package/dist/esm/src/handlers/records-count.js.map +1 -1
- package/dist/esm/src/handlers/records-delete.js +20 -16
- package/dist/esm/src/handlers/records-delete.js.map +1 -1
- package/dist/esm/src/handlers/records-query.js +35 -11
- package/dist/esm/src/handlers/records-query.js.map +1 -1
- package/dist/esm/src/handlers/records-read.js +52 -42
- package/dist/esm/src/handlers/records-read.js.map +1 -1
- package/dist/esm/src/handlers/records-subscribe.js +107 -11
- package/dist/esm/src/handlers/records-subscribe.js.map +1 -1
- package/dist/esm/src/handlers/records-write.js +62 -116
- package/dist/esm/src/handlers/records-write.js.map +1 -1
- package/dist/esm/src/index.js +6 -7
- package/dist/esm/src/index.js.map +1 -1
- package/dist/esm/src/interfaces/{messages-sync.js → messages-query.js} +21 -15
- package/dist/esm/src/interfaces/messages-query.js.map +1 -0
- package/dist/esm/src/interfaces/protocols-configure.js +12 -9
- package/dist/esm/src/interfaces/protocols-configure.js.map +1 -1
- package/dist/esm/src/interfaces/protocols-query.js +3 -4
- package/dist/esm/src/interfaces/protocols-query.js.map +1 -1
- package/dist/esm/src/interfaces/records-count.js +4 -3
- package/dist/esm/src/interfaces/records-count.js.map +1 -1
- package/dist/esm/src/interfaces/records-delete.js +21 -4
- package/dist/esm/src/interfaces/records-delete.js.map +1 -1
- package/dist/esm/src/interfaces/records-query.js +4 -3
- package/dist/esm/src/interfaces/records-query.js.map +1 -1
- package/dist/esm/src/interfaces/records-read.js +3 -3
- package/dist/esm/src/interfaces/records-read.js.map +1 -1
- package/dist/esm/src/interfaces/records-subscribe.js +4 -3
- package/dist/esm/src/interfaces/records-subscribe.js.map +1 -1
- package/dist/esm/src/interfaces/records-write.js +27 -13
- package/dist/esm/src/interfaces/records-write.js.map +1 -1
- package/dist/esm/src/protocols/permissions.js +27 -34
- package/dist/esm/src/protocols/permissions.js.map +1 -1
- package/dist/esm/src/store/index-level.js +24 -9
- package/dist/esm/src/store/index-level.js.map +1 -1
- package/dist/esm/src/store/level-wrapper.js +7 -0
- package/dist/esm/src/store/level-wrapper.js.map +1 -1
- package/dist/esm/src/store/message-store-level.js +536 -42
- package/dist/esm/src/store/message-store-level.js.map +1 -1
- package/dist/esm/src/store/storage-controller.js +58 -49
- package/dist/esm/src/store/storage-controller.js.map +1 -1
- package/dist/esm/src/types/message-types.js.map +1 -1
- package/dist/esm/src/types/validation-state-reader.js +2 -0
- package/dist/esm/src/types/validation-state-reader.js.map +1 -0
- package/dist/esm/src/utils/messages.js +17 -0
- package/dist/esm/src/utils/messages.js.map +1 -1
- package/dist/esm/src/utils/protocol-tags.js +262 -0
- package/dist/esm/src/utils/protocol-tags.js.map +1 -0
- package/dist/esm/src/utils/record-limit-occupancy.js +244 -0
- package/dist/esm/src/utils/record-limit-occupancy.js.map +1 -0
- package/dist/esm/src/utils/records.js +50 -14
- package/dist/esm/src/utils/records.js.map +1 -1
- package/dist/esm/src/utils/replication.js +85 -0
- package/dist/esm/src/utils/replication.js.map +1 -0
- package/dist/esm/tests/core/grant-authorization.spec.js +4 -4
- package/dist/esm/tests/core/grant-authorization.spec.js.map +1 -1
- package/dist/esm/tests/core/process-message-parity.spec.js +222 -0
- package/dist/esm/tests/core/process-message-parity.spec.js.map +1 -0
- package/dist/esm/tests/core/protocol-authorization.spec.js +5 -2
- package/dist/esm/tests/core/protocol-authorization.spec.js.map +1 -1
- package/dist/esm/tests/core/records-grant-authorization.spec.js +5 -5
- package/dist/esm/tests/core/records-grant-authorization.spec.js.map +1 -1
- package/dist/esm/tests/core/replication-apply.spec.js +55 -1
- package/dist/esm/tests/core/replication-apply.spec.js.map +1 -1
- package/dist/esm/tests/core/replication-replay-property.spec.js +350 -0
- package/dist/esm/tests/core/replication-replay-property.spec.js.map +1 -0
- package/dist/esm/tests/core/validation-read-closure.spec.js +469 -0
- package/dist/esm/tests/core/validation-read-closure.spec.js.map +1 -0
- package/dist/esm/tests/core/validation-state-reader.spec.js +716 -0
- package/dist/esm/tests/core/validation-state-reader.spec.js.map +1 -0
- package/dist/esm/tests/durable-event-log.spec.js +373 -0
- package/dist/esm/tests/durable-event-log.spec.js.map +1 -0
- package/dist/esm/tests/dwn.spec.js +504 -35
- package/dist/esm/tests/dwn.spec.js.map +1 -1
- package/dist/esm/tests/features/author-delegated-grant.spec.js +9 -6
- package/dist/esm/tests/features/author-delegated-grant.spec.js.map +1 -1
- package/dist/esm/tests/features/owner-delegated-grant.spec.js +1 -4
- package/dist/esm/tests/features/owner-delegated-grant.spec.js.map +1 -1
- package/dist/esm/tests/features/owner-signature.spec.js +1 -4
- package/dist/esm/tests/features/owner-signature.spec.js.map +1 -1
- package/dist/esm/tests/features/permissions.spec.js +165 -4
- package/dist/esm/tests/features/permissions.spec.js.map +1 -1
- package/dist/esm/tests/features/protocol-composition.spec.js +8 -11
- package/dist/esm/tests/features/protocol-composition.spec.js.map +1 -1
- package/dist/esm/tests/features/protocol-create-action.spec.js +1 -4
- package/dist/esm/tests/features/protocol-create-action.spec.js.map +1 -1
- package/dist/esm/tests/features/protocol-delete-action.spec.js +3 -5
- package/dist/esm/tests/features/protocol-delete-action.spec.js.map +1 -1
- package/dist/esm/tests/features/protocol-update-action.spec.js +3 -6
- package/dist/esm/tests/features/protocol-update-action.spec.js.map +1 -1
- package/dist/esm/tests/features/records-delivery.spec.js +1 -4
- package/dist/esm/tests/features/records-delivery.spec.js.map +1 -1
- package/dist/esm/tests/features/records-immutable.spec.js +1 -4
- package/dist/esm/tests/features/records-immutable.spec.js.map +1 -1
- package/dist/esm/tests/features/records-nested-query-scope.spec.js +281 -0
- package/dist/esm/tests/features/records-nested-query-scope.spec.js.map +1 -0
- package/dist/esm/tests/features/records-prune-cross-protocol.spec.js +3 -7
- package/dist/esm/tests/features/records-prune-cross-protocol.spec.js.map +1 -1
- package/dist/esm/tests/features/records-prune.spec.js +11 -22
- package/dist/esm/tests/features/records-prune.spec.js.map +1 -1
- package/dist/esm/tests/features/records-record-limit.spec.js +441 -231
- package/dist/esm/tests/features/records-record-limit.spec.js.map +1 -1
- package/dist/esm/tests/features/records-squash.spec.js +6 -4
- package/dist/esm/tests/features/records-squash.spec.js.map +1 -1
- package/dist/esm/tests/features/records-tags.spec.js +1 -4
- package/dist/esm/tests/features/records-tags.spec.js.map +1 -1
- package/dist/esm/tests/features/resumable-tasks.spec.js +3 -5
- package/dist/esm/tests/features/resumable-tasks.spec.js.map +1 -1
- package/dist/esm/tests/fuzz/message-store.fuzz.spec.js +1 -2
- package/dist/esm/tests/fuzz/message-store.fuzz.spec.js.map +1 -1
- package/dist/esm/tests/fuzz/process-message.fuzz.spec.js +2 -4
- package/dist/esm/tests/fuzz/process-message.fuzz.spec.js.map +1 -1
- package/dist/esm/tests/fuzz/schema-validation.fuzz.spec.js +1 -1
- package/dist/esm/tests/fuzz/schema-validation.fuzz.spec.js.map +1 -1
- package/dist/esm/tests/handlers/messages-query.spec.js +246 -0
- package/dist/esm/tests/handlers/messages-query.spec.js.map +1 -0
- package/dist/esm/tests/handlers/messages-read.spec.js +2 -5
- package/dist/esm/tests/handlers/messages-read.spec.js.map +1 -1
- package/dist/esm/tests/handlers/messages-subscribe.spec.js +3 -14
- package/dist/esm/tests/handlers/messages-subscribe.spec.js.map +1 -1
- package/dist/esm/tests/handlers/protocols-configure.spec.js +27 -26
- package/dist/esm/tests/handlers/protocols-configure.spec.js.map +1 -1
- package/dist/esm/tests/handlers/protocols-query.spec.js +1 -4
- package/dist/esm/tests/handlers/protocols-query.spec.js.map +1 -1
- package/dist/esm/tests/handlers/records-count.spec.js +1 -4
- package/dist/esm/tests/handlers/records-count.spec.js.map +1 -1
- package/dist/esm/tests/handlers/records-delete.spec.js +312 -30
- package/dist/esm/tests/handlers/records-delete.spec.js.map +1 -1
- package/dist/esm/tests/handlers/records-query.spec.js +32 -9
- package/dist/esm/tests/handlers/records-query.spec.js.map +1 -1
- package/dist/esm/tests/handlers/records-read.spec.js +4 -4
- package/dist/esm/tests/handlers/records-read.spec.js.map +1 -1
- package/dist/esm/tests/handlers/records-subscribe.spec.js +33 -14
- package/dist/esm/tests/handlers/records-subscribe.spec.js.map +1 -1
- package/dist/esm/tests/handlers/records-write.spec.js +82 -36
- package/dist/esm/tests/handlers/records-write.spec.js.map +1 -1
- package/dist/esm/tests/interfaces/records-delete.spec.js +69 -2
- package/dist/esm/tests/interfaces/records-delete.spec.js.map +1 -1
- package/dist/esm/tests/interfaces/records-write.spec.js +4 -3
- package/dist/esm/tests/interfaces/records-write.spec.js.map +1 -1
- package/dist/esm/tests/protocols/permissions.spec.js +55 -6
- package/dist/esm/tests/protocols/permissions.spec.js.map +1 -1
- package/dist/esm/tests/scenarios/aggregator.spec.js +1 -4
- package/dist/esm/tests/scenarios/aggregator.spec.js.map +1 -1
- package/dist/esm/tests/scenarios/deleted-record.spec.js +1 -4
- package/dist/esm/tests/scenarios/deleted-record.spec.js.map +1 -1
- package/dist/esm/tests/scenarios/end-to-end-tests.spec.js +1 -4
- package/dist/esm/tests/scenarios/end-to-end-tests.spec.js.map +1 -1
- package/dist/esm/tests/scenarios/nested-roles.spec.js +1 -4
- package/dist/esm/tests/scenarios/nested-roles.spec.js.map +1 -1
- package/dist/esm/tests/scenarios/subscriptions.spec.js +1 -4
- package/dist/esm/tests/scenarios/subscriptions.spec.js.map +1 -1
- package/dist/esm/tests/store/message-store-level.spec.js +361 -5
- package/dist/esm/tests/store/message-store-level.spec.js.map +1 -1
- package/dist/esm/tests/store/message-store.spec.js +60 -0
- package/dist/esm/tests/store/message-store.spec.js.map +1 -1
- package/dist/esm/tests/test-event-stream.js +7 -3
- package/dist/esm/tests/test-event-stream.js.map +1 -1
- package/dist/esm/tests/test-stores.js +19 -9
- package/dist/esm/tests/test-stores.js.map +1 -1
- package/dist/esm/tests/test-suite.js +4 -2
- package/dist/esm/tests/test-suite.js.map +1 -1
- package/dist/esm/tests/utils/protocol-tags.spec.js +96 -0
- package/dist/esm/tests/utils/protocol-tags.spec.js.map +1 -0
- package/dist/esm/tests/utils/test-data-generator.js +25 -0
- package/dist/esm/tests/utils/test-data-generator.js.map +1 -1
- package/dist/esm/tests/utils/test-stub-generator.js.map +1 -1
- package/dist/esm/tests/utils/test-validation-state-reader.js +16 -0
- package/dist/esm/tests/utils/test-validation-state-reader.js.map +1 -0
- package/dist/types/generated/precompiled-validators.d.ts +6 -6
- package/dist/types/generated/precompiled-validators.d.ts.map +1 -1
- package/dist/types/src/core/core-protocol.d.ts +3 -3
- package/dist/types/src/core/core-protocol.d.ts.map +1 -1
- package/dist/types/src/core/dwn-constant.d.ts +5 -0
- package/dist/types/src/core/dwn-constant.d.ts.map +1 -1
- package/dist/types/src/core/dwn-error.d.ts +12 -4
- package/dist/types/src/core/dwn-error.d.ts.map +1 -1
- package/dist/types/src/core/grant-authorization.d.ts +5 -5
- package/dist/types/src/core/grant-authorization.d.ts.map +1 -1
- package/dist/types/src/core/message-reply.d.ts +5 -4
- package/dist/types/src/core/message-reply.d.ts.map +1 -1
- package/dist/types/src/core/messages-grant-authorization.d.ts +12 -14
- package/dist/types/src/core/messages-grant-authorization.d.ts.map +1 -1
- package/dist/types/src/core/protocol-authorization-action.d.ts +4 -5
- package/dist/types/src/core/protocol-authorization-action.d.ts.map +1 -1
- package/dist/types/src/core/protocol-authorization-validation.d.ts +14 -17
- package/dist/types/src/core/protocol-authorization-validation.d.ts.map +1 -1
- package/dist/types/src/core/protocol-authorization.d.ts +8 -33
- package/dist/types/src/core/protocol-authorization.d.ts.map +1 -1
- package/dist/types/src/core/protocols-grant-authorization.d.ts +4 -4
- package/dist/types/src/core/protocols-grant-authorization.d.ts.map +1 -1
- package/dist/types/src/core/recording-validation-state-reader.d.ts +75 -0
- package/dist/types/src/core/recording-validation-state-reader.d.ts.map +1 -0
- package/dist/types/src/core/records-grant-authorization.d.ts +8 -8
- package/dist/types/src/core/records-grant-authorization.d.ts.map +1 -1
- package/dist/types/src/core/replication-apply.d.ts +36 -0
- package/dist/types/src/core/replication-apply.d.ts.map +1 -1
- package/dist/types/src/core/resumable-task-manager.d.ts +1 -1
- package/dist/types/src/core/resumable-task-manager.d.ts.map +1 -1
- package/dist/types/src/core/validation-state-reader.d.ts +79 -0
- package/dist/types/src/core/validation-state-reader.d.ts.map +1 -0
- package/dist/types/src/dwn.d.ts +33 -20
- package/dist/types/src/dwn.d.ts.map +1 -1
- package/dist/types/src/enums/dwn-interface-method.d.ts +0 -1
- package/dist/types/src/enums/dwn-interface-method.d.ts.map +1 -1
- package/dist/types/src/event-stream/durable-event-log.d.ts +69 -0
- package/dist/types/src/event-stream/durable-event-log.d.ts.map +1 -0
- package/dist/types/src/event-stream/event-emitter-wake-publisher.d.ts +13 -0
- package/dist/types/src/event-stream/event-emitter-wake-publisher.d.ts.map +1 -0
- package/dist/types/src/handlers/messages-query.d.ts +20 -0
- package/dist/types/src/handlers/messages-query.d.ts.map +1 -0
- package/dist/types/src/handlers/messages-read.d.ts +1 -1
- package/dist/types/src/handlers/messages-read.d.ts.map +1 -1
- package/dist/types/src/handlers/messages-subscribe.d.ts.map +1 -1
- package/dist/types/src/handlers/protocols-configure.d.ts +0 -5
- package/dist/types/src/handlers/protocols-configure.d.ts.map +1 -1
- package/dist/types/src/handlers/records-count.d.ts +2 -1
- package/dist/types/src/handlers/records-count.d.ts.map +1 -1
- package/dist/types/src/handlers/records-delete.d.ts +2 -2
- package/dist/types/src/handlers/records-delete.d.ts.map +1 -1
- package/dist/types/src/handlers/records-query.d.ts +1 -1
- package/dist/types/src/handlers/records-query.d.ts.map +1 -1
- package/dist/types/src/handlers/records-read.d.ts +2 -1
- package/dist/types/src/handlers/records-read.d.ts.map +1 -1
- package/dist/types/src/handlers/records-subscribe.d.ts +4 -5
- package/dist/types/src/handlers/records-subscribe.d.ts.map +1 -1
- package/dist/types/src/handlers/records-write.d.ts +3 -11
- package/dist/types/src/handlers/records-write.d.ts.map +1 -1
- package/dist/types/src/index.d.ts +14 -16
- package/dist/types/src/index.d.ts.map +1 -1
- package/dist/types/src/interfaces/messages-query.d.ts +23 -0
- package/dist/types/src/interfaces/messages-query.d.ts.map +1 -0
- package/dist/types/src/interfaces/protocols-configure.d.ts +3 -3
- package/dist/types/src/interfaces/protocols-configure.d.ts.map +1 -1
- package/dist/types/src/interfaces/protocols-query.d.ts +2 -2
- package/dist/types/src/interfaces/protocols-query.d.ts.map +1 -1
- package/dist/types/src/interfaces/records-count.d.ts +3 -3
- package/dist/types/src/interfaces/records-count.d.ts.map +1 -1
- package/dist/types/src/interfaces/records-delete.d.ts +11 -3
- package/dist/types/src/interfaces/records-delete.d.ts.map +1 -1
- package/dist/types/src/interfaces/records-query.d.ts +3 -3
- package/dist/types/src/interfaces/records-query.d.ts.map +1 -1
- package/dist/types/src/interfaces/records-read.d.ts +3 -3
- package/dist/types/src/interfaces/records-read.d.ts.map +1 -1
- package/dist/types/src/interfaces/records-subscribe.d.ts +3 -3
- package/dist/types/src/interfaces/records-subscribe.d.ts.map +1 -1
- package/dist/types/src/interfaces/records-write.d.ts +15 -7
- package/dist/types/src/interfaces/records-write.d.ts.map +1 -1
- package/dist/types/src/protocols/permissions.d.ts +9 -12
- package/dist/types/src/protocols/permissions.d.ts.map +1 -1
- package/dist/types/src/store/index-level.d.ts +10 -1
- package/dist/types/src/store/index-level.d.ts.map +1 -1
- package/dist/types/src/store/level-wrapper.d.ts +5 -0
- package/dist/types/src/store/level-wrapper.d.ts.map +1 -1
- package/dist/types/src/store/message-store-level.d.ts +94 -14
- package/dist/types/src/store/message-store-level.d.ts.map +1 -1
- package/dist/types/src/store/storage-controller.d.ts +17 -14
- package/dist/types/src/store/storage-controller.d.ts.map +1 -1
- package/dist/types/src/types/message-store.d.ts +29 -1
- package/dist/types/src/types/message-store.d.ts.map +1 -1
- package/dist/types/src/types/message-types.d.ts +2 -0
- package/dist/types/src/types/message-types.d.ts.map +1 -1
- package/dist/types/src/types/messages-types.d.ts +21 -37
- package/dist/types/src/types/messages-types.d.ts.map +1 -1
- package/dist/types/src/types/method-handler.d.ts +2 -2
- package/dist/types/src/types/method-handler.d.ts.map +1 -1
- package/dist/types/src/types/permission-types.d.ts +1 -1
- package/dist/types/src/types/subscriptions.d.ts +50 -39
- package/dist/types/src/types/subscriptions.d.ts.map +1 -1
- package/dist/types/src/types/validation-state-reader.d.ts +116 -0
- package/dist/types/src/types/validation-state-reader.d.ts.map +1 -0
- package/dist/types/src/utils/messages.d.ts +10 -0
- package/dist/types/src/utils/messages.d.ts.map +1 -1
- package/dist/types/src/utils/protocol-tags.d.ts +15 -0
- package/dist/types/src/utils/protocol-tags.d.ts.map +1 -0
- package/dist/types/src/utils/record-limit-occupancy.d.ts +40 -0
- package/dist/types/src/utils/record-limit-occupancy.d.ts.map +1 -0
- package/dist/types/src/utils/records.d.ts +25 -3
- package/dist/types/src/utils/records.d.ts.map +1 -1
- package/dist/types/src/utils/replication.d.ts +22 -0
- package/dist/types/src/utils/replication.d.ts.map +1 -0
- package/dist/types/tests/core/process-message-parity.spec.d.ts +2 -0
- package/dist/types/tests/core/process-message-parity.spec.d.ts.map +1 -0
- package/dist/types/tests/core/replication-replay-property.spec.d.ts +2 -0
- package/dist/types/tests/core/replication-replay-property.spec.d.ts.map +1 -0
- package/dist/types/tests/core/validation-read-closure.spec.d.ts +2 -0
- package/dist/types/tests/core/validation-read-closure.spec.d.ts.map +1 -0
- package/dist/types/tests/core/validation-state-reader.spec.d.ts +2 -0
- package/dist/types/tests/core/validation-state-reader.spec.d.ts.map +1 -0
- package/dist/types/tests/durable-event-log.spec.d.ts +2 -0
- package/dist/types/tests/durable-event-log.spec.d.ts.map +1 -0
- package/dist/types/tests/dwn.spec.d.ts.map +1 -1
- 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/protocol-create-action.spec.d.ts.map +1 -1
- package/dist/types/tests/features/protocol-delete-action.spec.d.ts.map +1 -1
- package/dist/types/tests/features/protocol-update-action.spec.d.ts.map +1 -1
- package/dist/types/tests/features/records-delivery.spec.d.ts.map +1 -1
- package/dist/types/tests/features/records-immutable.spec.d.ts.map +1 -1
- package/dist/types/tests/features/records-nested-query-scope.spec.d.ts +2 -0
- package/dist/types/tests/features/records-nested-query-scope.spec.d.ts.map +1 -0
- package/dist/types/tests/features/records-prune-cross-protocol.spec.d.ts.map +1 -1
- package/dist/types/tests/features/records-prune.spec.d.ts.map +1 -1
- package/dist/types/tests/features/records-record-limit.spec.d.ts.map +1 -1
- package/dist/types/tests/features/records-squash.spec.d.ts.map +1 -1
- package/dist/types/tests/features/records-tags.spec.d.ts.map +1 -1
- package/dist/types/tests/features/resumable-tasks.spec.d.ts.map +1 -1
- package/dist/types/tests/handlers/messages-query.spec.d.ts +2 -0
- package/dist/types/tests/handlers/messages-query.spec.d.ts.map +1 -0
- 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/protocols-configure.spec.d.ts.map +1 -1
- package/dist/types/tests/handlers/protocols-query.spec.d.ts.map +1 -1
- package/dist/types/tests/handlers/records-count.spec.d.ts.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/end-to-end-tests.spec.d.ts.map +1 -1
- package/dist/types/tests/scenarios/nested-roles.spec.d.ts.map +1 -1
- package/dist/types/tests/scenarios/subscriptions.spec.d.ts.map +1 -1
- package/dist/types/tests/store/message-store.spec.d.ts.map +1 -1
- package/dist/types/tests/test-event-stream.d.ts +1 -1
- package/dist/types/tests/test-event-stream.d.ts.map +1 -1
- package/dist/types/tests/test-stores.d.ts +5 -4
- package/dist/types/tests/test-stores.d.ts.map +1 -1
- package/dist/types/tests/test-suite.d.ts +1 -2
- package/dist/types/tests/test-suite.d.ts.map +1 -1
- package/dist/types/tests/utils/protocol-tags.spec.d.ts +2 -0
- package/dist/types/tests/utils/protocol-tags.spec.d.ts.map +1 -0
- package/dist/types/tests/utils/test-data-generator.d.ts +20 -1
- package/dist/types/tests/utils/test-data-generator.d.ts.map +1 -1
- package/dist/types/tests/utils/test-validation-state-reader.d.ts +15 -0
- package/dist/types/tests/utils/test-validation-state-reader.d.ts.map +1 -0
- package/package.json +2 -2
- package/src/core/core-protocol.ts +3 -3
- package/src/core/dwn-constant.ts +7 -1
- package/src/core/dwn-error.ts +12 -4
- package/src/core/grant-authorization.ts +11 -20
- package/src/core/message-reply.ts +6 -5
- package/src/core/messages-grant-authorization.ts +37 -70
- package/src/core/protocol-authorization-action.ts +29 -38
- package/src/core/protocol-authorization-validation.ts +47 -121
- package/src/core/protocol-authorization.ts +56 -202
- package/src/core/protocols-grant-authorization.ts +9 -9
- package/src/core/recording-validation-state-reader.ts +130 -0
- package/src/core/records-grant-authorization.ts +16 -16
- package/src/core/replication-apply.ts +172 -32
- package/src/core/resumable-task-manager.ts +10 -8
- package/src/core/validation-state-reader.ts +350 -0
- package/src/dwn.ts +285 -192
- package/src/enums/dwn-interface-method.ts +0 -1
- package/src/event-stream/durable-event-log.ts +509 -0
- package/src/event-stream/event-emitter-wake-publisher.ts +34 -0
- package/src/handlers/messages-query.ts +203 -0
- package/src/handlers/messages-read.ts +9 -10
- package/src/handlers/messages-subscribe.ts +12 -13
- package/src/handlers/protocols-configure.ts +37 -58
- package/src/handlers/protocols-query.ts +1 -1
- package/src/handlers/records-count.ts +24 -17
- package/src/handlers/records-delete.ts +29 -27
- package/src/handlers/records-query.ts +38 -17
- package/src/handlers/records-read.ts +63 -50
- package/src/handlers/records-subscribe.ts +132 -19
- package/src/handlers/records-write.ts +77 -168
- package/src/index.ts +14 -17
- package/src/interfaces/messages-query.ts +70 -0
- package/src/interfaces/protocols-configure.ts +20 -10
- package/src/interfaces/protocols-query.ts +4 -5
- package/src/interfaces/records-count.ts +9 -4
- package/src/interfaces/records-delete.ts +25 -5
- package/src/interfaces/records-query.ts +9 -4
- package/src/interfaces/records-read.ts +4 -4
- package/src/interfaces/records-subscribe.ts +9 -4
- package/src/interfaces/records-write.ts +41 -13
- package/src/protocols/permissions.ts +32 -52
- package/src/store/index-level.ts +30 -9
- package/src/store/level-wrapper.ts +9 -1
- package/src/store/message-store-level.ts +757 -47
- package/src/store/storage-controller.ts +74 -63
- package/src/types/message-store.ts +45 -2
- package/src/types/message-types.ts +3 -1
- package/src/types/messages-types.ts +26 -45
- package/src/types/method-handler.ts +3 -3
- package/src/types/permission-types.ts +1 -1
- package/src/types/subscriptions.ts +53 -42
- package/src/types/validation-state-reader.ts +127 -0
- package/src/utils/messages.ts +25 -1
- package/src/utils/protocol-tags.ts +366 -0
- package/src/utils/record-limit-occupancy.ts +377 -0
- package/src/utils/records.ts +69 -13
- package/src/utils/replication.ts +122 -0
- package/dist/esm/src/core/record-chain.js +0 -64
- package/dist/esm/src/core/record-chain.js.map +0 -1
- package/dist/esm/src/event-stream/event-emitter-event-log.js +0 -334
- package/dist/esm/src/event-stream/event-emitter-event-log.js.map +0 -1
- package/dist/esm/src/handlers/messages-sync.js +0 -278
- package/dist/esm/src/handlers/messages-sync.js.map +0 -1
- package/dist/esm/src/interfaces/messages-sync.js.map +0 -1
- package/dist/esm/src/smt/smt-store-level.js +0 -103
- package/dist/esm/src/smt/smt-store-level.js.map +0 -1
- package/dist/esm/src/smt/smt-store-memory.js +0 -41
- package/dist/esm/src/smt/smt-store-memory.js.map +0 -1
- package/dist/esm/src/smt/smt-utils.js +0 -129
- package/dist/esm/src/smt/smt-utils.js.map +0 -1
- package/dist/esm/src/smt/sparse-merkle-tree.js +0 -577
- package/dist/esm/src/smt/sparse-merkle-tree.js.map +0 -1
- package/dist/esm/src/state-index/state-index-level.js +0 -191
- package/dist/esm/src/state-index/state-index-level.js.map +0 -1
- package/dist/esm/src/types/smt-types.js +0 -5
- package/dist/esm/src/types/smt-types.js.map +0 -1
- package/dist/esm/src/types/state-index.js +0 -2
- package/dist/esm/src/types/state-index.js.map +0 -1
- package/dist/esm/tests/event-emitter-event-log.spec.js +0 -499
- package/dist/esm/tests/event-emitter-event-log.spec.js.map +0 -1
- package/dist/esm/tests/handlers/messages-sync.spec.js +0 -1088
- package/dist/esm/tests/handlers/messages-sync.spec.js.map +0 -1
- package/dist/esm/tests/smt/smt-store-level.spec.js +0 -132
- package/dist/esm/tests/smt/smt-store-level.spec.js.map +0 -1
- package/dist/esm/tests/smt/sparse-merkle-tree.spec.js +0 -732
- package/dist/esm/tests/smt/sparse-merkle-tree.spec.js.map +0 -1
- package/dist/esm/tests/state-index/state-index-level.spec.js +0 -245
- package/dist/esm/tests/state-index/state-index-level.spec.js.map +0 -1
- package/dist/types/src/core/record-chain.d.ts +0 -24
- package/dist/types/src/core/record-chain.d.ts.map +0 -1
- package/dist/types/src/event-stream/event-emitter-event-log.d.ts +0 -80
- package/dist/types/src/event-stream/event-emitter-event-log.d.ts.map +0 -1
- package/dist/types/src/handlers/messages-sync.d.ts +0 -39
- package/dist/types/src/handlers/messages-sync.d.ts.map +0 -1
- package/dist/types/src/interfaces/messages-sync.d.ts +0 -20
- package/dist/types/src/interfaces/messages-sync.d.ts.map +0 -1
- package/dist/types/src/smt/smt-store-level.d.ts +0 -32
- package/dist/types/src/smt/smt-store-level.d.ts.map +0 -1
- package/dist/types/src/smt/smt-store-memory.d.ts +0 -22
- package/dist/types/src/smt/smt-store-memory.d.ts.map +0 -1
- package/dist/types/src/smt/smt-utils.d.ts +0 -58
- package/dist/types/src/smt/smt-utils.d.ts.map +0 -1
- package/dist/types/src/smt/sparse-merkle-tree.d.ts +0 -124
- package/dist/types/src/smt/sparse-merkle-tree.d.ts.map +0 -1
- package/dist/types/src/state-index/state-index-level.d.ts +0 -83
- package/dist/types/src/state-index/state-index-level.d.ts.map +0 -1
- package/dist/types/src/types/smt-types.d.ts +0 -81
- package/dist/types/src/types/smt-types.d.ts.map +0 -1
- package/dist/types/src/types/state-index.d.ts +0 -90
- package/dist/types/src/types/state-index.d.ts.map +0 -1
- package/dist/types/tests/event-emitter-event-log.spec.d.ts +0 -2
- package/dist/types/tests/event-emitter-event-log.spec.d.ts.map +0 -1
- package/dist/types/tests/handlers/messages-sync.spec.d.ts +0 -2
- package/dist/types/tests/handlers/messages-sync.spec.d.ts.map +0 -1
- package/dist/types/tests/smt/smt-store-level.spec.d.ts +0 -2
- package/dist/types/tests/smt/smt-store-level.spec.d.ts.map +0 -1
- package/dist/types/tests/smt/sparse-merkle-tree.spec.d.ts +0 -2
- package/dist/types/tests/smt/sparse-merkle-tree.spec.d.ts.map +0 -1
- package/dist/types/tests/state-index/state-index-level.spec.d.ts +0 -2
- package/dist/types/tests/state-index/state-index-level.spec.d.ts.map +0 -1
- package/src/core/record-chain.ts +0 -99
- package/src/event-stream/event-emitter-event-log.ts +0 -430
- package/src/handlers/messages-sync.ts +0 -403
- package/src/interfaces/messages-sync.ts +0 -69
- package/src/smt/smt-store-level.ts +0 -143
- package/src/smt/smt-store-memory.ts +0 -53
- package/src/smt/smt-utils.ts +0 -149
- package/src/smt/sparse-merkle-tree.ts +0 -698
- package/src/state-index/state-index-level.ts +0 -239
- package/src/types/smt-types.ts +0 -95
- package/src/types/state-index.ts +0 -100
|
@@ -1,430 +0,0 @@
|
|
|
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
|
-
ProgressGapInfo,
|
|
11
|
-
ProgressGapReason,
|
|
12
|
-
ProgressToken,
|
|
13
|
-
SubscriptionListener,
|
|
14
|
-
} from '../types/subscriptions.js';
|
|
15
|
-
|
|
16
|
-
import mitt from 'mitt';
|
|
17
|
-
|
|
18
|
-
import { FilterUtility } from '../utils/filter.js';
|
|
19
|
-
import { DwnError, DwnErrorCode } from '../core/dwn-error.js';
|
|
20
|
-
|
|
21
|
-
const EVENTS_LISTENER_CHANNEL = 'events';
|
|
22
|
-
|
|
23
|
-
/**
|
|
24
|
-
* Payload shape used internally by mitt. We bundle the three EventListener
|
|
25
|
-
* arguments into a single object because mitt emits one value per event.
|
|
26
|
-
*/
|
|
27
|
-
type EmitterPayload = { tenant: string; event: MessageEvent; indexes: KeyValues; seq: number; messageCid: string };
|
|
28
|
-
|
|
29
|
-
/**
|
|
30
|
-
* mitt event map — every channel name maps to an `EmitterPayload`.
|
|
31
|
-
* Using `Record<string, EmitterPayload>` lets us create channels dynamically.
|
|
32
|
-
*/
|
|
33
|
-
type EmitterEvents = Record<string, EmitterPayload>;
|
|
34
|
-
|
|
35
|
-
/**
|
|
36
|
-
* Internal storage entry — the event plus its indexes and message CID.
|
|
37
|
-
*/
|
|
38
|
-
type StoredEntry = {
|
|
39
|
-
event : MessageEvent;
|
|
40
|
-
indexes : KeyValues;
|
|
41
|
-
messageCid : string;
|
|
42
|
-
};
|
|
43
|
-
|
|
44
|
-
export interface EventEmitterEventLogConfig {
|
|
45
|
-
/**
|
|
46
|
-
* Maximum number of events to retain per tenant.
|
|
47
|
-
* Oldest events are evicted when the limit is reached.
|
|
48
|
-
* Defaults to 10_000.
|
|
49
|
-
*/
|
|
50
|
-
maxEventsPerTenant?: number;
|
|
51
|
-
|
|
52
|
-
/**
|
|
53
|
-
* An optional error handler in order to be able to react to any errors or warnings.
|
|
54
|
-
* By default we log errors with `console.error`.
|
|
55
|
-
*/
|
|
56
|
-
errorHandler?: (error: any) => void;
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
/**
|
|
60
|
-
* In-memory implementation of {@link EventLog} backed by `mitt` for in-process
|
|
61
|
-
* pub/sub and a per-tenant `Map<number, StoredEntry>` for persistence with
|
|
62
|
-
* cursor-based reads.
|
|
63
|
-
*
|
|
64
|
-
* Suitable for single-process embedded DWN instances and tests.
|
|
65
|
-
* For multi-node deployments, use a distributed implementation (NATS, Redis, etc.).
|
|
66
|
-
*/
|
|
67
|
-
export class EventEmitterEventLog implements EventLog {
|
|
68
|
-
private readonly emitter = mitt<EmitterEvents>();
|
|
69
|
-
private isOpen: boolean = false;
|
|
70
|
-
private readonly errorHandler: (error: any) => void = (error): void => { console.error('event log error', error); };
|
|
71
|
-
private readonly maxEventsPerTenant: number;
|
|
72
|
-
|
|
73
|
-
/**
|
|
74
|
-
* Per-tenant ordered event storage.
|
|
75
|
-
* Key: tenant DID → Map of seq → StoredEntry.
|
|
76
|
-
*/
|
|
77
|
-
private readonly tenantLogs: Map<string, Map<number, StoredEntry>> = new Map();
|
|
78
|
-
|
|
79
|
-
/**
|
|
80
|
-
* Per-tenant monotonic sequence counter.
|
|
81
|
-
*/
|
|
82
|
-
private readonly tenantSeqs: Map<string, number> = new Map();
|
|
83
|
-
|
|
84
|
-
/**
|
|
85
|
-
* Epoch for this EventLog instance. Generated once at construction as a
|
|
86
|
-
* UUID v4. Changes every restart (correct for in-memory — state is lost).
|
|
87
|
-
*/
|
|
88
|
-
private readonly epoch: string;
|
|
89
|
-
|
|
90
|
-
constructor(config: EventEmitterEventLogConfig = {}) {
|
|
91
|
-
this.maxEventsPerTenant = config.maxEventsPerTenant ?? 10_000;
|
|
92
|
-
this.epoch = crypto.randomUUID();
|
|
93
|
-
|
|
94
|
-
if (config.errorHandler) {
|
|
95
|
-
this.errorHandler = config.errorHandler;
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
/**
|
|
100
|
-
* Derives a stable `streamId` for a given tenant. Deterministic — same
|
|
101
|
-
* tenant always produces the same streamId on any instance.
|
|
102
|
-
*/
|
|
103
|
-
private async getStreamId(tenant: string): Promise<string> {
|
|
104
|
-
const bytes = new TextEncoder().encode(tenant);
|
|
105
|
-
const hashBuffer = await crypto.subtle.digest('SHA-256', bytes);
|
|
106
|
-
const hashArray = new Uint8Array(hashBuffer);
|
|
107
|
-
// Take first 16 hex chars (64 bits) of the hash for a compact stable ID.
|
|
108
|
-
return Array.from(hashArray.slice(0, 8), (b: number) => b.toString(16).padStart(2, '0')).join('');
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
/**
|
|
112
|
-
* Constructs a {@link ProgressToken} from internal state.
|
|
113
|
-
*/
|
|
114
|
-
private async buildToken(tenant: string, seq: number, messageCid: string): Promise<ProgressToken> {
|
|
115
|
-
return {
|
|
116
|
-
streamId : await this.getStreamId(tenant),
|
|
117
|
-
epoch : this.epoch,
|
|
118
|
-
position : String(seq),
|
|
119
|
-
messageCid,
|
|
120
|
-
};
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
/**
|
|
124
|
-
* Validates a cursor against the current EventLog state. Throws
|
|
125
|
-
* `DwnError(EventLogProgressGap)` with {@link ProgressGapInfo} metadata
|
|
126
|
-
* if the cursor cannot be resumed.
|
|
127
|
-
*/
|
|
128
|
-
private async validateCursor(tenant: string, cursor: ProgressToken): Promise<void> {
|
|
129
|
-
const expectedStreamId = await this.getStreamId(tenant);
|
|
130
|
-
|
|
131
|
-
let reason: ProgressGapReason;
|
|
132
|
-
if (cursor.streamId !== expectedStreamId) {
|
|
133
|
-
reason = 'stream_mismatch';
|
|
134
|
-
} else if (cursor.epoch === this.epoch) {
|
|
135
|
-
// Check if position is still within replay bounds.
|
|
136
|
-
const log = this.tenantLogs.get(tenant);
|
|
137
|
-
if (log !== undefined && log.size > 0) {
|
|
138
|
-
const firstSeq = log.keys().next().value as number;
|
|
139
|
-
const cursorSeq = EventEmitterEventLog.parsePosition(cursor.position);
|
|
140
|
-
if (cursorSeq < firstSeq - 1) {
|
|
141
|
-
// Cursor position has been evicted — events between cursor and firstSeq are lost.
|
|
142
|
-
reason = 'token_too_old';
|
|
143
|
-
} else {
|
|
144
|
-
return; // Cursor is valid.
|
|
145
|
-
}
|
|
146
|
-
} else {
|
|
147
|
-
return; // No events for tenant — cursor is vacuously valid (will get empty catch-up + EOSE).
|
|
148
|
-
}
|
|
149
|
-
} else {
|
|
150
|
-
reason = 'epoch_mismatch';
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
// Build gap metadata.
|
|
154
|
-
const bounds = await this.getReplayBounds(tenant);
|
|
155
|
-
const gapInfo: ProgressGapInfo = {
|
|
156
|
-
requested : cursor,
|
|
157
|
-
oldestAvailable : bounds?.oldest ?? cursor,
|
|
158
|
-
latestAvailable : bounds?.latest ?? cursor,
|
|
159
|
-
reason,
|
|
160
|
-
};
|
|
161
|
-
|
|
162
|
-
const error = new DwnError(
|
|
163
|
-
DwnErrorCode.EventLogProgressGap,
|
|
164
|
-
`progress token gap: ${reason}`
|
|
165
|
-
);
|
|
166
|
-
(error as any).gapInfo = gapInfo;
|
|
167
|
-
throw error;
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
public async open(): Promise<void> {
|
|
171
|
-
this.isOpen = true;
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
public async close(): Promise<void> {
|
|
175
|
-
this.isOpen = false;
|
|
176
|
-
this.emitter.all.clear();
|
|
177
|
-
this.tenantLogs.clear();
|
|
178
|
-
this.tenantSeqs.clear();
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
public async emit(tenant: string, event: MessageEvent, indexes: KeyValues, messageCid: string): Promise<ProgressToken | undefined> {
|
|
182
|
-
if (!this.isOpen) {
|
|
183
|
-
this.errorHandler(new DwnError(
|
|
184
|
-
DwnErrorCode.EventLogNotOpenError,
|
|
185
|
-
'a message emitted when EventLog is closed'
|
|
186
|
-
));
|
|
187
|
-
return undefined;
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
// Assign a monotonic sequence number for this tenant.
|
|
191
|
-
const prevSeq = this.tenantSeqs.get(tenant) ?? 0;
|
|
192
|
-
const seq = prevSeq + 1;
|
|
193
|
-
this.tenantSeqs.set(tenant, seq);
|
|
194
|
-
|
|
195
|
-
// Persist the event.
|
|
196
|
-
let log = this.tenantLogs.get(tenant);
|
|
197
|
-
if (log === undefined) {
|
|
198
|
-
log = new Map();
|
|
199
|
-
this.tenantLogs.set(tenant, log);
|
|
200
|
-
}
|
|
201
|
-
log.set(seq, { event, indexes, messageCid });
|
|
202
|
-
|
|
203
|
-
// Evict oldest entries if the log exceeds the retention limit.
|
|
204
|
-
if (log.size > this.maxEventsPerTenant) {
|
|
205
|
-
const evictCount = log.size - this.maxEventsPerTenant;
|
|
206
|
-
let evicted = 0;
|
|
207
|
-
for (const key of log.keys()) {
|
|
208
|
-
if (evicted >= evictCount) { break; }
|
|
209
|
-
log.delete(key);
|
|
210
|
-
evicted++;
|
|
211
|
-
}
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
// Notify in-process subscribers.
|
|
215
|
-
const channel = `${tenant}_${EVENTS_LISTENER_CHANNEL}`;
|
|
216
|
-
this.emitter.emit(channel, { tenant, event, indexes, seq, messageCid });
|
|
217
|
-
|
|
218
|
-
return this.buildToken(tenant, seq, messageCid);
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
public async read(tenant: string, options: EventLogReadOptions = {}): Promise<EventLogReadResult> {
|
|
222
|
-
const { cursor, limit, filters } = options;
|
|
223
|
-
|
|
224
|
-
// Validate cursor before attempting to read.
|
|
225
|
-
if (cursor !== undefined) {
|
|
226
|
-
await this.validateCursor(tenant, cursor);
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
const cursorSeq = cursor === undefined ? undefined : EventEmitterEventLog.parsePosition(cursor.position);
|
|
230
|
-
const log = this.tenantLogs.get(tenant);
|
|
231
|
-
|
|
232
|
-
if (log === undefined || log.size === 0) {
|
|
233
|
-
return { events: [], cursor };
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
const results: EventLogEntry[] = [];
|
|
237
|
-
const maxResults = limit ?? Number.MAX_SAFE_INTEGER;
|
|
238
|
-
|
|
239
|
-
for (const [seq, entry] of log) {
|
|
240
|
-
// Skip entries at or before the cursor.
|
|
241
|
-
if (cursorSeq !== undefined && seq <= cursorSeq) { continue; }
|
|
242
|
-
|
|
243
|
-
// Apply filters if provided (OR semantics — match any filter).
|
|
244
|
-
if (filters !== undefined && filters.length > 0) {
|
|
245
|
-
if (!FilterUtility.matchAnyFilter(entry.indexes, filters)) { continue; }
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
results.push({
|
|
249
|
-
seq,
|
|
250
|
-
event : entry.event,
|
|
251
|
-
indexes : entry.indexes,
|
|
252
|
-
messageCid : entry.messageCid,
|
|
253
|
-
});
|
|
254
|
-
|
|
255
|
-
if (results.length >= maxResults) { break; }
|
|
256
|
-
}
|
|
257
|
-
|
|
258
|
-
if (results.length > 0) {
|
|
259
|
-
const lastEntry = results[results.length - 1];
|
|
260
|
-
// Use the messageCid captured during the synchronous iteration above —
|
|
261
|
-
// no re-lookup needed, so eviction during the await cannot lose it.
|
|
262
|
-
const lastToken = await this.buildToken(tenant, lastEntry.seq, lastEntry.messageCid!);
|
|
263
|
-
return { events: results, cursor: lastToken };
|
|
264
|
-
}
|
|
265
|
-
|
|
266
|
-
return { events: results, cursor };
|
|
267
|
-
}
|
|
268
|
-
|
|
269
|
-
/**
|
|
270
|
-
* Parse a position string into an internal sequence number using BigInt
|
|
271
|
-
* for safe handling of values beyond `Number.MAX_SAFE_INTEGER`.
|
|
272
|
-
*
|
|
273
|
-
* The returned `number` is safe for the in-memory EventLog which uses
|
|
274
|
-
* `Map<number, StoredEntry>` keys — in-memory sequences will never
|
|
275
|
-
* exceed safe integer range. The BigInt parse validates correctness
|
|
276
|
-
* before the narrowing conversion.
|
|
277
|
-
*/
|
|
278
|
-
private static parsePosition(position: string): number {
|
|
279
|
-
try {
|
|
280
|
-
const big = BigInt(position);
|
|
281
|
-
if (big < 0n) {
|
|
282
|
-
throw new DwnError(DwnErrorCode.EventLogNotOpenError, `invalid cursor position: '${position}'`);
|
|
283
|
-
}
|
|
284
|
-
return Number(big);
|
|
285
|
-
} catch (e) {
|
|
286
|
-
if (e instanceof DwnError) { throw e; }
|
|
287
|
-
throw new DwnError(DwnErrorCode.EventLogNotOpenError, `invalid cursor position: '${position}'`);
|
|
288
|
-
}
|
|
289
|
-
}
|
|
290
|
-
|
|
291
|
-
public async subscribe(
|
|
292
|
-
tenant: string,
|
|
293
|
-
id: string,
|
|
294
|
-
listener: SubscriptionListener,
|
|
295
|
-
options?: EventLogSubscribeOptions,
|
|
296
|
-
): Promise<EventSubscription> {
|
|
297
|
-
const channel = `${tenant}_${EVENTS_LISTENER_CHANNEL}`;
|
|
298
|
-
const { cursor, filters } = options ?? {};
|
|
299
|
-
|
|
300
|
-
// Helper to build a token from a live emitter payload.
|
|
301
|
-
const tokenFromPayload = async (payload: EmitterPayload): Promise<ProgressToken> => {
|
|
302
|
-
return this.buildToken(tenant, payload.seq, payload.messageCid);
|
|
303
|
-
};
|
|
304
|
-
|
|
305
|
-
if (cursor !== undefined) {
|
|
306
|
-
// ---- Cursor mode: catch-up from stored events, then EOSE, then live ----
|
|
307
|
-
// Validate cursor before subscribing — throws DwnError(EventLogProgressGap) on gap.
|
|
308
|
-
await this.validateCursor(tenant, cursor);
|
|
309
|
-
|
|
310
|
-
const cursorSeq = EventEmitterEventLog.parsePosition(cursor.position);
|
|
311
|
-
|
|
312
|
-
// Buffer live events that arrive during catch-up to avoid losing them.
|
|
313
|
-
type BufferedEvent = { event: MessageEvent; seq: number; messageCid: string };
|
|
314
|
-
const pendingLiveEvents: BufferedEvent[] = [];
|
|
315
|
-
let catchUpComplete = false;
|
|
316
|
-
|
|
317
|
-
// Step 1: Register live listener FIRST so no events are missed during read.
|
|
318
|
-
const handler = (payload: EmitterPayload): void => {
|
|
319
|
-
if (filters !== undefined && filters.length > 0) {
|
|
320
|
-
if (!FilterUtility.matchAnyFilter(payload.indexes, filters)) { return; }
|
|
321
|
-
}
|
|
322
|
-
if (catchUpComplete) {
|
|
323
|
-
void tokenFromPayload(payload).then((token) => {
|
|
324
|
-
listener({ type: 'event', cursor: token, event: payload.event });
|
|
325
|
-
});
|
|
326
|
-
} else {
|
|
327
|
-
pendingLiveEvents.push({ event: payload.event, seq: payload.seq, messageCid: payload.messageCid });
|
|
328
|
-
}
|
|
329
|
-
};
|
|
330
|
-
|
|
331
|
-
this.emitter.on(channel, handler);
|
|
332
|
-
|
|
333
|
-
// Step 2: Read stored events from cursor and deliver them.
|
|
334
|
-
const readResult = await this.read(tenant, { cursor, filters });
|
|
335
|
-
// The read cursor is the token of the last read event, or the input cursor if nothing new.
|
|
336
|
-
const eoseCursor = readResult.cursor ?? cursor;
|
|
337
|
-
const lastCatchUpSeq = readResult.cursor === undefined
|
|
338
|
-
? cursorSeq
|
|
339
|
-
: EventEmitterEventLog.parsePosition(readResult.cursor.position);
|
|
340
|
-
|
|
341
|
-
// Use the messageCid captured by read() during its synchronous iteration.
|
|
342
|
-
// This eliminates re-lookup races: read() populates entry.messageCid before
|
|
343
|
-
// any async yield, so eviction during read()'s buildToken() cannot lose it.
|
|
344
|
-
for (const entry of readResult.events) {
|
|
345
|
-
const token = await this.buildToken(tenant, entry.seq, entry.messageCid ?? '');
|
|
346
|
-
listener({ type: 'event', cursor: token, event: entry.event });
|
|
347
|
-
}
|
|
348
|
-
|
|
349
|
-
// Step 3: Deliver any live events that arrived during catch-up (with seq > lastCatchUpSeq).
|
|
350
|
-
// messageCid was captured at buffer time from the EmitterPayload.
|
|
351
|
-
catchUpComplete = true;
|
|
352
|
-
for (const liveEvent of pendingLiveEvents) {
|
|
353
|
-
if (liveEvent.seq > lastCatchUpSeq) {
|
|
354
|
-
const token = await this.buildToken(tenant, liveEvent.seq, liveEvent.messageCid);
|
|
355
|
-
listener({ type: 'event', cursor: token, event: liveEvent.event });
|
|
356
|
-
}
|
|
357
|
-
}
|
|
358
|
-
|
|
359
|
-
// Step 4: Send EOSE marker.
|
|
360
|
-
listener({ type: 'eose', cursor: eoseCursor });
|
|
361
|
-
|
|
362
|
-
return {
|
|
363
|
-
id,
|
|
364
|
-
close: async (): Promise<void> => { this.emitter.off(channel, handler); }
|
|
365
|
-
};
|
|
366
|
-
}
|
|
367
|
-
|
|
368
|
-
// ---- No cursor: live events only ----
|
|
369
|
-
|
|
370
|
-
const handler = (payload: EmitterPayload): void => {
|
|
371
|
-
if (filters !== undefined && filters.length > 0) {
|
|
372
|
-
if (!FilterUtility.matchAnyFilter(payload.indexes, filters)) { return; }
|
|
373
|
-
}
|
|
374
|
-
void tokenFromPayload(payload).then((token) => {
|
|
375
|
-
listener({ type: 'event', cursor: token, event: payload.event });
|
|
376
|
-
});
|
|
377
|
-
};
|
|
378
|
-
|
|
379
|
-
this.emitter.on(channel, handler);
|
|
380
|
-
|
|
381
|
-
return {
|
|
382
|
-
id,
|
|
383
|
-
close: async (): Promise<void> => { this.emitter.off(channel, handler); }
|
|
384
|
-
};
|
|
385
|
-
}
|
|
386
|
-
|
|
387
|
-
public async getReplayBounds(tenant: string): Promise<{ oldest: ProgressToken; latest: ProgressToken } | undefined> {
|
|
388
|
-
const log = this.tenantLogs.get(tenant);
|
|
389
|
-
if (log === undefined || log.size === 0) {
|
|
390
|
-
return undefined;
|
|
391
|
-
}
|
|
392
|
-
|
|
393
|
-
// Map is ordered by insertion (ascending seq). First and last keys are min/max.
|
|
394
|
-
const keys = [...log.keys()];
|
|
395
|
-
const oldestSeq = keys[0];
|
|
396
|
-
const latestSeq = keys[keys.length - 1];
|
|
397
|
-
|
|
398
|
-
const oldestEntry = log.get(oldestSeq)!;
|
|
399
|
-
const latestEntry = log.get(latestSeq)!;
|
|
400
|
-
|
|
401
|
-
const oldest = await this.buildToken(tenant, oldestSeq, oldestEntry.messageCid);
|
|
402
|
-
const latest = await this.buildToken(tenant, latestSeq, latestEntry.messageCid);
|
|
403
|
-
|
|
404
|
-
return { oldest, latest };
|
|
405
|
-
}
|
|
406
|
-
|
|
407
|
-
public async trim(tenant: string, olderThan: number | string): Promise<void> {
|
|
408
|
-
const log = this.tenantLogs.get(tenant);
|
|
409
|
-
if (log === undefined) { return; }
|
|
410
|
-
|
|
411
|
-
if (typeof olderThan === 'number') {
|
|
412
|
-
// Trim by sequence number: delete entries with seq < olderThan.
|
|
413
|
-
for (const seq of log.keys()) {
|
|
414
|
-
if (seq < olderThan) {
|
|
415
|
-
log.delete(seq);
|
|
416
|
-
} else {
|
|
417
|
-
break; // Map is ordered by insertion (ascending seq), safe to stop.
|
|
418
|
-
}
|
|
419
|
-
}
|
|
420
|
-
} else {
|
|
421
|
-
// Trim by ISO-8601 timestamp: delete entries whose message timestamp is before the given time.
|
|
422
|
-
for (const [seq, entry] of log) {
|
|
423
|
-
const messageTimestamp = (entry.indexes['messageTimestamp'] as string) ?? '';
|
|
424
|
-
if (messageTimestamp < olderThan) {
|
|
425
|
-
log.delete(seq);
|
|
426
|
-
}
|
|
427
|
-
}
|
|
428
|
-
}
|
|
429
|
-
}
|
|
430
|
-
}
|