@enbox/dwn-sdk-js 0.4.0 → 0.4.1
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 +8 -8
- 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 +30 -68
- 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 +7 -3
- 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/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/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 +13 -16
- 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/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/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 +39 -96
- 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 +12 -4
- 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/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,10 +1,9 @@
|
|
|
1
1
|
import type { DataStore } from '../types/data-store.js';
|
|
2
|
-
import type { EventLog } from '../types/subscriptions.js';
|
|
3
2
|
import type { Filter } from '../types/query-types.js';
|
|
4
3
|
import type { GenericMessage } from '../types/message-types.js';
|
|
5
4
|
import type { MessageStore } from '../types/message-store.js';
|
|
6
|
-
import type {
|
|
7
|
-
import type { RecordsDeleteMessage,
|
|
5
|
+
import type { ProgressToken } from '../types/subscriptions.js';
|
|
6
|
+
import type { RecordsDeleteMessage, RecordsWriteMessage } from '../types/records-types.js';
|
|
8
7
|
|
|
9
8
|
import { DwnConstant } from '../core/dwn-constant.js';
|
|
10
9
|
import { FilterUtility } from '../utils/filter.js';
|
|
@@ -25,29 +24,28 @@ export type ResumableRecordsSquashData = {
|
|
|
25
24
|
message: RecordsWriteMessage;
|
|
26
25
|
};
|
|
27
26
|
|
|
27
|
+
export type RecordsDeleteTaskResult = {
|
|
28
|
+
position?: ProgressToken;
|
|
29
|
+
};
|
|
30
|
+
|
|
28
31
|
/**
|
|
29
|
-
* A class that provides an abstraction for
|
|
32
|
+
* A class that provides an abstraction for coordinated MessageStore and DataStore mutations.
|
|
30
33
|
*/
|
|
31
34
|
export class StorageController {
|
|
32
35
|
|
|
33
36
|
private readonly messageStore: MessageStore;
|
|
34
37
|
private readonly dataStore: DataStore;
|
|
35
|
-
private readonly stateIndex: StateIndex;
|
|
36
|
-
private readonly eventLog?: EventLog;
|
|
37
38
|
|
|
38
|
-
public constructor({ messageStore, dataStore
|
|
39
|
+
public constructor({ messageStore, dataStore }: {
|
|
39
40
|
messageStore : MessageStore,
|
|
40
41
|
dataStore : DataStore,
|
|
41
|
-
|
|
42
|
-
eventLog? : EventLog}
|
|
42
|
+
}
|
|
43
43
|
) {
|
|
44
44
|
this.messageStore = messageStore;
|
|
45
45
|
this.dataStore = dataStore;
|
|
46
|
-
this.stateIndex = stateIndex;
|
|
47
|
-
this.eventLog = eventLog;
|
|
48
46
|
}
|
|
49
47
|
|
|
50
|
-
public async performRecordsDelete({ tenant, message }: ResumableRecordsDeleteData): Promise<
|
|
48
|
+
public async performRecordsDelete({ tenant, message }: ResumableRecordsDeleteData): Promise<RecordsDeleteTaskResult> {
|
|
51
49
|
// get existing records matching the `recordId`
|
|
52
50
|
const query = {
|
|
53
51
|
interface : DwnInterfaceName.Records,
|
|
@@ -58,8 +56,15 @@ export class StorageController {
|
|
|
58
56
|
// find which message is the newest, and if the incoming message is the newest
|
|
59
57
|
const newestExistingMessage = await Message.getNewestMessage(existingMessages);
|
|
60
58
|
|
|
61
|
-
if (
|
|
62
|
-
return;
|
|
59
|
+
if (newestExistingMessage === undefined) {
|
|
60
|
+
return {};
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// Same tombstone-lattice gate as the RecordsDelete handler: state can advance between
|
|
64
|
+
// acceptance and task replay, and a beaten delete accepted earlier must not displace the
|
|
65
|
+
// tombstone that has since become the record's canonical winner.
|
|
66
|
+
if (await Records.isDeleteBeatenByExistingTombstone(message, newestExistingMessage)) {
|
|
67
|
+
return {};
|
|
63
68
|
}
|
|
64
69
|
|
|
65
70
|
// NOTE: code above is duplicated from `RecordsDeleteHandler` and is already performed if this was invoked by the `RecordsDeleteHandler`,
|
|
@@ -68,15 +73,14 @@ export class StorageController {
|
|
|
68
73
|
|
|
69
74
|
const recordsDelete = await RecordsDelete.parse(message);
|
|
70
75
|
const initialWrite = await RecordsWrite.getInitialWrite(existingMessages);
|
|
71
|
-
const
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
//
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
}
|
|
76
|
+
const newestPreDeleteWrite = await Records.getNewestRecordsWrite(existingMessages) ?? initialWrite;
|
|
77
|
+
|
|
78
|
+
// Tombstone mutable query-visibility facts (`tag.*`, `published`, `datePublished`) come from
|
|
79
|
+
// the newest retained RecordsWrite. This remains true when replacing an existing tombstone:
|
|
80
|
+
// tombstones carry no visibility facts in their descriptors, so the retained write is the
|
|
81
|
+
// durable source of truth for later prune/replay/replication index reconstruction.
|
|
82
|
+
const indexes = recordsDelete.constructIndexes(initialWrite, newestPreDeleteWrite);
|
|
83
|
+
const { position } = await this.messageStore.put(tenant, message, indexes);
|
|
80
84
|
|
|
81
85
|
if (message.descriptor.prune) {
|
|
82
86
|
// purge/hard-delete all descendant records. Cascade is intentionally protocol-agnostic:
|
|
@@ -84,14 +88,16 @@ export class StorageController {
|
|
|
84
88
|
// of which protocol a descendant lives in. Cross-protocol composing children (linked via
|
|
85
89
|
// `$ref`/`uses`) participate in the cascade. See issue #298 for the design discussion.
|
|
86
90
|
await StorageController.purgeRecordDescendants(
|
|
87
|
-
tenant, message.descriptor.recordId, this.messageStore, this.dataStore
|
|
91
|
+
tenant, message.descriptor.recordId, this.messageStore, this.dataStore
|
|
88
92
|
);
|
|
89
93
|
}
|
|
90
94
|
|
|
91
|
-
//
|
|
92
|
-
await StorageController.
|
|
93
|
-
tenant, existingMessages, message, this.messageStore, this.dataStore,
|
|
95
|
+
// displace every other message for this record, retaining the writes needed for replay and future tombstone visibility
|
|
96
|
+
await StorageController.deleteDisplacedMessagesAndRetainWrites(
|
|
97
|
+
tenant, existingMessages, message, this.messageStore, this.dataStore, [newestPreDeleteWrite]
|
|
94
98
|
);
|
|
99
|
+
|
|
100
|
+
return { position };
|
|
95
101
|
}
|
|
96
102
|
|
|
97
103
|
/**
|
|
@@ -159,7 +165,7 @@ export class StorageController {
|
|
|
159
165
|
const newestTimestamp = newestMessage.descriptor.messageTimestamp;
|
|
160
166
|
if (newestTimestamp < messageTimestamp) {
|
|
161
167
|
// Fully purge this record — all messages (including initial write) and their data
|
|
162
|
-
await StorageController.purgeRecordMessages(tenant, messages, this.messageStore, this.dataStore
|
|
168
|
+
await StorageController.purgeRecordMessages(tenant, messages, this.messageStore, this.dataStore);
|
|
163
169
|
}
|
|
164
170
|
}
|
|
165
171
|
}
|
|
@@ -216,8 +222,7 @@ export class StorageController {
|
|
|
216
222
|
tenant: string,
|
|
217
223
|
recordId: string,
|
|
218
224
|
messageStore: MessageStore,
|
|
219
|
-
dataStore: DataStore
|
|
220
|
-
stateIndex: StateIndex
|
|
225
|
+
dataStore: DataStore
|
|
221
226
|
): Promise<void> {
|
|
222
227
|
const filter: Filter = {
|
|
223
228
|
interface : DwnInterfaceName.Records,
|
|
@@ -244,11 +249,11 @@ export class StorageController {
|
|
|
244
249
|
}
|
|
245
250
|
|
|
246
251
|
for (const childRecordId of recordIdToMessagesMap.keys()) {
|
|
247
|
-
await StorageController.purgeRecordDescendants(tenant, childRecordId, messageStore, dataStore
|
|
252
|
+
await StorageController.purgeRecordDescendants(tenant, childRecordId, messageStore, dataStore);
|
|
248
253
|
}
|
|
249
254
|
|
|
250
255
|
for (const childRecordId of recordIdToMessagesMap.keys()) {
|
|
251
|
-
await StorageController.purgeRecordMessages(tenant, recordIdToMessagesMap.get(childRecordId)!, messageStore, dataStore
|
|
256
|
+
await StorageController.purgeRecordMessages(tenant, recordIdToMessagesMap.get(childRecordId)!, messageStore, dataStore);
|
|
252
257
|
}
|
|
253
258
|
}
|
|
254
259
|
|
|
@@ -260,8 +265,7 @@ export class StorageController {
|
|
|
260
265
|
tenant: string,
|
|
261
266
|
recordMessages: GenericMessage[],
|
|
262
267
|
messageStore: MessageStore,
|
|
263
|
-
dataStore: DataStore
|
|
264
|
-
stateIndex: StateIndex
|
|
268
|
+
dataStore: DataStore
|
|
265
269
|
): Promise<void> {
|
|
266
270
|
// delete the data from the data store first so no chance of orphaned data (not having a message referencing it) in case of server crash
|
|
267
271
|
// NOTE: only the `RecordsWrite` with latest timestamp can possibly have data associated with it so we do this filtering as an optimization
|
|
@@ -275,60 +279,67 @@ export class StorageController {
|
|
|
275
279
|
const newestRecordsWrite = (await Message.getNewestMessage(recordsWrites)) as RecordsWriteMessage;
|
|
276
280
|
await dataStore.delete(tenant, newestRecordsWrite.recordId, newestRecordsWrite.descriptor.dataCid);
|
|
277
281
|
|
|
278
|
-
// then delete all events associated with the record messages before deleting the messages so we don't have orphaned events
|
|
279
282
|
const messageCids = await Promise.all(recordMessages.map((message) => Message.getCid(message)));
|
|
280
|
-
await stateIndex.delete(tenant, messageCids);
|
|
281
283
|
|
|
282
|
-
// finally delete all record messages
|
|
283
284
|
await Promise.all(messageCids.map((messageCid) => messageStore.delete(tenant, messageCid)));
|
|
284
285
|
}
|
|
285
286
|
|
|
286
287
|
/**
|
|
287
|
-
* Deletes all messages in `existingMessages` that
|
|
288
|
-
*
|
|
288
|
+
* Deletes all messages in `existingMessages` that the `retainedMessage` displaces, while keeping
|
|
289
|
+
* the initial write and the caller-supplied writes as non-latest state for future replay and
|
|
290
|
+
* tombstone visibility reconstruction. Displacement is deliberately NOT a timestamp comparison:
|
|
291
|
+
* a RecordsDelete displaces even a newer RecordsWrite (delete-wins convergence), and on
|
|
292
|
+
* resumable-task replay the retained message itself is back in `existingMessages` and must
|
|
293
|
+
* survive — so membership is decided by CID.
|
|
289
294
|
*/
|
|
290
|
-
public static async
|
|
295
|
+
public static async deleteDisplacedMessagesAndRetainWrites(
|
|
291
296
|
tenant: string,
|
|
292
297
|
existingMessages: GenericMessage[],
|
|
293
|
-
|
|
298
|
+
retainedMessage: GenericMessage,
|
|
294
299
|
messageStore: MessageStore,
|
|
295
300
|
dataStore: DataStore,
|
|
296
|
-
|
|
301
|
+
additionalRetainedRecordsWrites: RecordsWriteMessage[],
|
|
297
302
|
): Promise<void> {
|
|
298
|
-
const
|
|
303
|
+
const retainedMessageCid = await Message.getCid(retainedMessage);
|
|
304
|
+
const additionalRetainedRecordsWriteCids = new Set<string>();
|
|
305
|
+
for (const retainedRecordsWrite of additionalRetainedRecordsWrites) {
|
|
306
|
+
additionalRetainedRecordsWriteCids.add(await Message.getCid(retainedRecordsWrite));
|
|
307
|
+
}
|
|
299
308
|
|
|
300
309
|
// NOTE: under normal operation, there should only be at most two existing records per `recordId` (initial + a potential subsequent write/delete),
|
|
301
310
|
// but the DWN may crash before `delete()` is called below, so we use a loop as a tactic to clean up lingering data as needed
|
|
302
311
|
for (const message of existingMessages) {
|
|
303
|
-
const
|
|
304
|
-
|
|
312
|
+
const messageCid = await Message.getCid(message);
|
|
313
|
+
const messageIsDisplaced = messageCid !== retainedMessageCid;
|
|
314
|
+
if (messageIsDisplaced) {
|
|
305
315
|
// the easiest implementation here is delete each old messages
|
|
306
|
-
// and re-create it with the right index (isLatestBaseState = 'false') if the message is
|
|
316
|
+
// and re-create it with the right index (isLatestBaseState = 'false') if the message is a retained write,
|
|
307
317
|
// but there is room for better/more efficient implementation here
|
|
308
318
|
|
|
309
|
-
await StorageController.deleteFromDataStoreIfNeeded(dataStore, tenant, message,
|
|
319
|
+
await StorageController.deleteFromDataStoreIfNeeded(dataStore, tenant, message, retainedMessage);
|
|
310
320
|
|
|
311
|
-
//
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
const existingRecordsWrite = await RecordsWrite.parse(message as RecordsWriteMessage);
|
|
321
|
+
// Retained writes must stay in the message store and state index so future deletes and
|
|
322
|
+
// replicas can reconstruct tombstone visibility, but they must no longer be latest state.
|
|
323
|
+
const shouldKeepAsNonLatestWrite =
|
|
324
|
+
await RecordsWrite.isInitialWrite(message) ||
|
|
325
|
+
additionalRetainedRecordsWriteCids.has(messageCid);
|
|
326
|
+
if (shouldKeepAsNonLatestWrite) {
|
|
327
|
+
const retainedRecordsWriteMessage = StorageController.stripInlineData(message as RecordsWriteMessage);
|
|
328
|
+
const existingRecordsWrite = await RecordsWrite.parse(retainedRecordsWriteMessage);
|
|
320
329
|
const isLatestBaseState = false;
|
|
321
330
|
const indexes = await existingRecordsWrite.constructIndexes(isLatestBaseState);
|
|
322
|
-
|
|
323
|
-
delete writeMessage.encodedData;
|
|
324
|
-
await messageStore.put(tenant, writeMessage, indexes);
|
|
331
|
+
await messageStore.updateMessageAndIndexes(tenant, messageCid, retainedRecordsWriteMessage, indexes);
|
|
325
332
|
} else {
|
|
326
|
-
|
|
327
|
-
|
|
333
|
+
// delete message from message store
|
|
334
|
+
await messageStore.delete(tenant, messageCid);
|
|
328
335
|
}
|
|
329
336
|
}
|
|
330
|
-
|
|
331
|
-
await stateIndex.delete(tenant, deletedMessageCids);
|
|
332
337
|
}
|
|
333
338
|
}
|
|
339
|
+
|
|
340
|
+
private static stripInlineData(message: RecordsWriteMessage): RecordsWriteMessage {
|
|
341
|
+
const retainedMessage = { ...message } as RecordsWriteMessage & { encodedData?: string };
|
|
342
|
+
delete retainedMessage.encodedData;
|
|
343
|
+
return retainedMessage;
|
|
344
|
+
}
|
|
334
345
|
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { ProgressToken } from './subscriptions.js';
|
|
1
2
|
import type { Filter, KeyValues, PaginationCursor } from './query-types.js';
|
|
2
3
|
import type { GenericMessage, MessageSort, Pagination } from './message-types.js';
|
|
3
4
|
|
|
@@ -5,6 +6,24 @@ export interface MessageStoreOptions {
|
|
|
5
6
|
signal?: AbortSignal;
|
|
6
7
|
}
|
|
7
8
|
|
|
9
|
+
/**
|
|
10
|
+
* Result of a {@link MessageStore.put} operation.
|
|
11
|
+
*/
|
|
12
|
+
export type MessageStorePutResult = {
|
|
13
|
+
/**
|
|
14
|
+
* `inserted` when a new row was created; `duplicate` when a row for the same
|
|
15
|
+
* `(tenant, messageCid)` already exists.
|
|
16
|
+
*/
|
|
17
|
+
status: 'inserted' | 'duplicate';
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* The inserted row's log position. Present for stores that maintain a
|
|
21
|
+
* replication log; omitted for duplicates and store implementations whose
|
|
22
|
+
* durable log support has not landed.
|
|
23
|
+
*/
|
|
24
|
+
position?: ProgressToken;
|
|
25
|
+
};
|
|
26
|
+
|
|
8
27
|
export interface MessageStore {
|
|
9
28
|
/**
|
|
10
29
|
* opens a connection to the underlying store
|
|
@@ -25,7 +44,7 @@ export interface MessageStore {
|
|
|
25
44
|
message: GenericMessage,
|
|
26
45
|
indexes: KeyValues,
|
|
27
46
|
options?: MessageStoreOptions
|
|
28
|
-
): Promise<
|
|
47
|
+
): Promise<MessageStorePutResult>;
|
|
29
48
|
|
|
30
49
|
/**
|
|
31
50
|
* Fetches a single message by `cid` from the underlying store.
|
|
@@ -56,6 +75,30 @@ export interface MessageStore {
|
|
|
56
75
|
options?: MessageStoreOptions
|
|
57
76
|
): Promise<number>;
|
|
58
77
|
|
|
78
|
+
/**
|
|
79
|
+
* Replaces the indexes of an existing message in place: same row and same log
|
|
80
|
+
* sequence.
|
|
81
|
+
*/
|
|
82
|
+
updateIndexes(
|
|
83
|
+
tenant: string,
|
|
84
|
+
messageCid: string,
|
|
85
|
+
indexes: KeyValues,
|
|
86
|
+
options?: MessageStoreOptions
|
|
87
|
+
): Promise<void>;
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Replaces the stored same-CID message payload and indexes in place: same
|
|
91
|
+
* row and same log sequence. The replacement message must resolve to
|
|
92
|
+
* `messageCid` under DWN CID rules.
|
|
93
|
+
*/
|
|
94
|
+
updateMessageAndIndexes(
|
|
95
|
+
tenant: string,
|
|
96
|
+
messageCid: string,
|
|
97
|
+
message: GenericMessage,
|
|
98
|
+
indexes: KeyValues,
|
|
99
|
+
options?: MessageStoreOptions
|
|
100
|
+
): Promise<void>;
|
|
101
|
+
|
|
59
102
|
/**
|
|
60
103
|
* Deletes the message associated with the id provided.
|
|
61
104
|
*/
|
|
@@ -65,4 +108,4 @@ export interface MessageStore {
|
|
|
65
108
|
* Clears the entire store. Mainly used for cleaning up in test environment.
|
|
66
109
|
*/
|
|
67
110
|
clear(): Promise<void>;
|
|
68
|
-
}
|
|
111
|
+
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { GeneralJws } from './jws-types.js';
|
|
2
|
+
import type { ProgressToken } from './subscriptions.js';
|
|
2
3
|
import type { PublicKeyJwk } from './jose-types.js';
|
|
3
4
|
import type { DwnInterfaceName, DwnMethodName } from '../enums/dwn-interface-method.js';
|
|
4
5
|
import type { PaginationCursor, SortDirection } from './query-types.js';
|
|
@@ -145,10 +146,11 @@ export type Status = {
|
|
|
145
146
|
|
|
146
147
|
export type GenericMessageReply = {
|
|
147
148
|
status: Status;
|
|
149
|
+
position?: ProgressToken;
|
|
148
150
|
};
|
|
149
151
|
|
|
150
152
|
export type MessageSort = {
|
|
151
153
|
dateCreated?: SortDirection;
|
|
152
154
|
datePublished?: SortDirection;
|
|
153
155
|
messageTimestamp?: SortDirection;
|
|
154
|
-
};
|
|
156
|
+
};
|
|
@@ -42,57 +42,38 @@ export type MessagesReadReply = GenericMessageReply & {
|
|
|
42
42
|
entry?: MessagesReadReplyEntry;
|
|
43
43
|
};
|
|
44
44
|
|
|
45
|
-
export type
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
permissionGrantIds? : string[];
|
|
55
|
-
/**
|
|
56
|
-
* For `action: 'diff'`: a map of `{ bitPrefix: hexHash }` representing the client's
|
|
57
|
-
* subtree hashes at `depth`. The server compares each hash against its own tree
|
|
58
|
-
* and returns the set difference in a single round-trip.
|
|
59
|
-
*
|
|
60
|
-
* Only non-default (non-empty) subtree hashes need to be included — prefixes
|
|
61
|
-
* whose hash equals the default empty-subtree hash may be omitted.
|
|
62
|
-
*/
|
|
63
|
-
hashes? : Record<string, string>;
|
|
64
|
-
/**
|
|
65
|
-
* For `action: 'diff'`: the bit depth at which the client computed its subtree
|
|
66
|
-
* hashes. Required when `action` is `'diff'`.
|
|
67
|
-
*/
|
|
68
|
-
depth? : number;
|
|
45
|
+
export type MessagesQueryDescriptor = {
|
|
46
|
+
interface: DwnInterfaceName.Messages;
|
|
47
|
+
method: DwnMethodName.Query;
|
|
48
|
+
messageTimestamp: string;
|
|
49
|
+
filters: MessagesFilter[];
|
|
50
|
+
permissionGrantIds?: string[];
|
|
51
|
+
cursor?: ProgressToken;
|
|
52
|
+
limit?: number;
|
|
53
|
+
cidsOnly?: boolean;
|
|
69
54
|
};
|
|
70
55
|
|
|
71
|
-
export type
|
|
72
|
-
authorization
|
|
73
|
-
descriptor
|
|
56
|
+
export type MessagesQueryMessage = {
|
|
57
|
+
authorization: AuthorizationModel;
|
|
58
|
+
descriptor: MessagesQueryDescriptor;
|
|
74
59
|
};
|
|
75
60
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
message? : GenericMessage;
|
|
84
|
-
/** Base64url-encoded data for small RecordsWrite payloads (≤ maxInlineDataSize). */
|
|
85
|
-
encodedData? : string;
|
|
61
|
+
export type MessagesQueryReplyEntry = {
|
|
62
|
+
seq: string;
|
|
63
|
+
messageCid: string;
|
|
64
|
+
isLatestBaseState: boolean;
|
|
65
|
+
protocol?: string;
|
|
66
|
+
message?: GenericMessage;
|
|
67
|
+
encodedData?: string;
|
|
86
68
|
};
|
|
87
69
|
|
|
88
|
-
export type
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
onlyLocal? : string[];
|
|
70
|
+
export type MessagesQueryReply = GenericMessageReply & {
|
|
71
|
+
entries?: MessagesQueryReplyEntry[];
|
|
72
|
+
cursor?: ProgressToken;
|
|
73
|
+
drained?: boolean;
|
|
74
|
+
fingerprint?: string;
|
|
75
|
+
/** Present when status.code is 410 — structured gap metadata. */
|
|
76
|
+
error?: { code: 'ProgressGap' } & ProgressGapInfo;
|
|
96
77
|
};
|
|
97
78
|
|
|
98
79
|
export type MessagesSubscribeMessageOptions = {
|
|
@@ -3,7 +3,7 @@ import type { DataStore } from './data-store.js';
|
|
|
3
3
|
import type { DidResolver } from '@enbox/dids';
|
|
4
4
|
import type { MessageStore } from './message-store.js';
|
|
5
5
|
import type { ResumableTaskManager } from '../core/resumable-task-manager.js';
|
|
6
|
-
import type {
|
|
6
|
+
import type { ValidationStateReader } from './validation-state-reader.js';
|
|
7
7
|
import type { EventLog, SubscriptionListener } from './subscriptions.js';
|
|
8
8
|
import type { GenericMessage, GenericMessageReply } from './message-types.js';
|
|
9
9
|
|
|
@@ -17,7 +17,7 @@ export interface MethodHandler {
|
|
|
17
17
|
handle(input: {
|
|
18
18
|
tenant: string;
|
|
19
19
|
message: GenericMessage;
|
|
20
|
-
dataStream?: ReadableStream<Uint8Array
|
|
20
|
+
dataStream?: ReadableStream<Uint8Array>;
|
|
21
21
|
subscriptionHandler?: SubscriptionListener;
|
|
22
22
|
}): Promise<GenericMessageReply>;
|
|
23
23
|
}
|
|
@@ -32,8 +32,8 @@ export interface MethodHandler {
|
|
|
32
32
|
export type HandlerDependencies = {
|
|
33
33
|
didResolver: DidResolver;
|
|
34
34
|
messageStore: MessageStore;
|
|
35
|
+
validationStateReader: ValidationStateReader;
|
|
35
36
|
dataStore?: DataStore;
|
|
36
|
-
stateIndex?: StateIndex;
|
|
37
37
|
resumableTaskManager?: ResumableTaskManager;
|
|
38
38
|
coreProtocols?: CoreProtocolRegistry;
|
|
39
39
|
eventLog?: EventLog;
|
|
@@ -90,7 +90,7 @@ export type ProtocolPermissionScope = {
|
|
|
90
90
|
* Permission scope for the Messages interface.
|
|
91
91
|
*
|
|
92
92
|
* `Read` is the only valid method and acts as a unified scope that authorizes
|
|
93
|
-
* `MessagesRead`, `
|
|
93
|
+
* `MessagesRead`, `MessagesQuery`, and `MessagesSubscribe` operations.
|
|
94
94
|
*/
|
|
95
95
|
export type MessagesPermissionScope = {
|
|
96
96
|
interface: DwnInterfaceName.Messages;
|
|
@@ -23,15 +23,18 @@ export type ProgressToken = {
|
|
|
23
23
|
epoch : string;
|
|
24
24
|
/** Monotonic decimal string within `(streamId, epoch)`. Compared numerically. */
|
|
25
25
|
position : string;
|
|
26
|
-
/**
|
|
27
|
-
|
|
26
|
+
/**
|
|
27
|
+
* The CID of the message associated with this event. Omitted for high-water
|
|
28
|
+
* cursors that do not point at a delivered in-scope message.
|
|
29
|
+
*/
|
|
30
|
+
messageCid? : string;
|
|
28
31
|
};
|
|
29
32
|
|
|
30
33
|
/**
|
|
31
34
|
* Reason code for a {@link ProgressGapInfo} — explains why the cursor
|
|
32
35
|
* cannot be resumed.
|
|
33
36
|
*/
|
|
34
|
-
export type ProgressGapReason = 'token_too_old' | 'epoch_mismatch' | 'stream_mismatch';
|
|
37
|
+
export type ProgressGapReason = 'token_too_old' | 'token_too_new' | 'epoch_mismatch' | 'stream_mismatch' | 'message_mismatch';
|
|
35
38
|
|
|
36
39
|
/**
|
|
37
40
|
* Metadata attached to a `DwnError(DwnErrorCode.EventLogProgressGap, ...)`
|
|
@@ -51,14 +54,7 @@ export type ProgressGapInfo = {
|
|
|
51
54
|
};
|
|
52
55
|
|
|
53
56
|
/**
|
|
54
|
-
*
|
|
55
|
-
* subscribers. Not intended for direct consumer use — consumers should use
|
|
56
|
-
* {@link SubscriptionListener} via {@link EventLog.subscribe}.
|
|
57
|
-
*/
|
|
58
|
-
export type EventListener = (tenant: string, event: MessageEvent, indexes: KeyValues, seq: number) => void;
|
|
59
|
-
|
|
60
|
-
/**
|
|
61
|
-
* MessageEvent contains the message being emitted and an optional initial write message.
|
|
57
|
+
* MessageEvent contains a committed message and an optional initial write message.
|
|
62
58
|
*/
|
|
63
59
|
export type MessageEvent = {
|
|
64
60
|
message: GenericMessage;
|
|
@@ -92,6 +88,16 @@ export type SubscriptionEvent = {
|
|
|
92
88
|
cursor : ProgressToken;
|
|
93
89
|
/** The event payload (message + optional initialWrite). */
|
|
94
90
|
event : MessageEvent;
|
|
91
|
+
/** Original row sequence for this message. */
|
|
92
|
+
seq? : string;
|
|
93
|
+
/** CID of the message that produced this event. */
|
|
94
|
+
messageCid? : string;
|
|
95
|
+
/** Whether this event's source row was latest base state at read time. */
|
|
96
|
+
isLatestBaseState? : boolean;
|
|
97
|
+
/** Protocol index value associated with the source row, when present. */
|
|
98
|
+
protocol? : string;
|
|
99
|
+
/** Base64url-encoded inline data carried beside the message payload. */
|
|
100
|
+
encodedData? : string;
|
|
95
101
|
};
|
|
96
102
|
|
|
97
103
|
/**
|
|
@@ -148,8 +154,7 @@ export type EventLogSubscribeOptions = {
|
|
|
148
154
|
* an EOSE marker, then live events. When omitted, only live events are delivered.
|
|
149
155
|
*
|
|
150
156
|
* Tokens must be obtained from a prior interaction with the same EventLog
|
|
151
|
-
* instance (e.g. `SubscriptionEvent.cursor
|
|
152
|
-
* or the return value of `emit()`).
|
|
157
|
+
* instance (e.g. `SubscriptionEvent.cursor` or `EventLogReadResult.cursor`).
|
|
153
158
|
*/
|
|
154
159
|
cursor? : ProgressToken;
|
|
155
160
|
|
|
@@ -168,18 +173,23 @@ export type EventLogSubscribeOptions = {
|
|
|
168
173
|
* A single entry returned by {@link EventLog.read}.
|
|
169
174
|
*/
|
|
170
175
|
export type EventLogEntry = {
|
|
171
|
-
/** Monotonic sequence number scoped to (instance, tenant). */
|
|
172
|
-
seq:
|
|
176
|
+
/** Monotonic sequence number scoped to (instance, tenant), as a decimal string. */
|
|
177
|
+
seq: string;
|
|
178
|
+
|
|
179
|
+
/** The actual delivered log position. Equal to `seq` for store-backed feeds. */
|
|
180
|
+
position?: string;
|
|
173
181
|
|
|
174
182
|
/** The event payload. */
|
|
175
183
|
event: MessageEvent;
|
|
184
|
+
/** Base64url-encoded inline data carried beside the message payload. */
|
|
185
|
+
encodedData?: string;
|
|
176
186
|
|
|
177
187
|
/** Indexes associated with the event (used for filter matching). */
|
|
178
188
|
indexes: KeyValues;
|
|
179
189
|
|
|
180
190
|
/**
|
|
181
191
|
* The CID of the message that produced this event. Populated by
|
|
182
|
-
* implementations that track it
|
|
192
|
+
* implementations that track it.
|
|
183
193
|
* Consumers should fall back to computing the CID from the message
|
|
184
194
|
* if this is absent.
|
|
185
195
|
*/
|
|
@@ -207,15 +217,11 @@ export type EventLogReadResult = {
|
|
|
207
217
|
/** Events matching the read request, ordered by ascending seq. */
|
|
208
218
|
events : EventLogEntry[];
|
|
209
219
|
|
|
210
|
-
/**
|
|
211
|
-
* Progress token for resuming subsequent reads or subscriptions.
|
|
212
|
-
*
|
|
213
|
-
* - When events are returned: token of the last event.
|
|
214
|
-
* - When no events are returned but a cursor was provided: the input cursor
|
|
215
|
-
* (meaning "you are caught up, nothing new since this point").
|
|
216
|
-
* - When no events exist and no cursor was provided: `undefined`.
|
|
217
|
-
*/
|
|
220
|
+
/** High-water progress token for resuming subsequent reads or subscriptions. */
|
|
218
221
|
cursor? : ProgressToken;
|
|
222
|
+
|
|
223
|
+
/** True when the scan reached the captured tenant head. */
|
|
224
|
+
drained : boolean;
|
|
219
225
|
};
|
|
220
226
|
|
|
221
227
|
/**
|
|
@@ -226,21 +232,11 @@ export type EventLogReadResult = {
|
|
|
226
232
|
* that enable cursor-based resume after disconnects.
|
|
227
233
|
*
|
|
228
234
|
* The interface is intentionally transport-agnostic — implementations can be
|
|
229
|
-
* backed by
|
|
230
|
-
*
|
|
231
|
-
*
|
|
235
|
+
* backed by an embedded store, SQL, or another durable ordered feed. Each
|
|
236
|
+
* implementation owns the catch-up + live transition strategy appropriate to
|
|
237
|
+
* its backend.
|
|
232
238
|
*/
|
|
233
239
|
export interface EventLog {
|
|
234
|
-
/**
|
|
235
|
-
* Persist an event and notify in-process subscribers.
|
|
236
|
-
* @param tenant The tenant DID.
|
|
237
|
-
* @param event The event payload.
|
|
238
|
-
* @param indexes Index values for the event.
|
|
239
|
-
* @param messageCid The CID of the message being emitted — embedded in the returned token.
|
|
240
|
-
* @returns A {@link ProgressToken} assigned to the event, or `undefined` on failure.
|
|
241
|
-
*/
|
|
242
|
-
emit(tenant: string, event: MessageEvent, indexes: KeyValues, messageCid: string): Promise<ProgressToken | undefined>;
|
|
243
|
-
|
|
244
240
|
/**
|
|
245
241
|
* Read events from the log starting after `cursor`, optionally filtered.
|
|
246
242
|
*/
|
|
@@ -270,11 +266,26 @@ export interface EventLog {
|
|
|
270
266
|
*/
|
|
271
267
|
getReplayBounds(tenant: string): Promise<{ oldest: ProgressToken; latest: ProgressToken } | undefined>;
|
|
272
268
|
|
|
273
|
-
/**
|
|
274
|
-
* Delete events older than the given sequence number or ISO-8601 timestamp.
|
|
275
|
-
*/
|
|
276
|
-
trim(tenant: string, olderThan: number | string): Promise<void>;
|
|
277
|
-
|
|
278
269
|
open(): Promise<void>;
|
|
279
270
|
close(): Promise<void>;
|
|
280
271
|
}
|
|
272
|
+
|
|
273
|
+
export type Wake = {
|
|
274
|
+
tenant : string;
|
|
275
|
+
seq : string;
|
|
276
|
+
};
|
|
277
|
+
|
|
278
|
+
export interface WakePublisher {
|
|
279
|
+
publish(wake: Wake): void;
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
export interface WakeSubscriber {
|
|
283
|
+
subscribe(listener: (wake: Wake) => void): () => void;
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
export interface ReplicationFeedReader {
|
|
287
|
+
logRead(tenant: string, options?: EventLogReadOptions): Promise<EventLogReadResult>;
|
|
288
|
+
logBounds(tenant: string): Promise<{ oldest: ProgressToken; latest: ProgressToken } | undefined>;
|
|
289
|
+
fingerprint(tenant: string, scopes: string[]): Promise<string>;
|
|
290
|
+
epoch(): Promise<string>;
|
|
291
|
+
}
|