@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
|
@@ -0,0 +1,716 @@
|
|
|
1
|
+
import friendRoleProtocolDefinition from '../vectors/protocol-definitions/friend-role.json' with { type: 'json' };
|
|
2
|
+
import nestedProtocolDefinition from '../vectors/protocol-definitions/nested.json' with { type: 'json' };
|
|
3
|
+
import { DataStream } from '../../src/utils/data-stream.js';
|
|
4
|
+
import { Dwn } from '../../src/dwn.js';
|
|
5
|
+
import { DwnErrorCode } from '../../src/core/dwn-error.js';
|
|
6
|
+
import { Jws } from '../../src/utils/jws.js';
|
|
7
|
+
import { RecordsWrite } from '../../src/interfaces/records-write.js';
|
|
8
|
+
import { TestDataGenerator } from '../utils/test-data-generator.js';
|
|
9
|
+
import { TestEventLog } from '../test-event-stream.js';
|
|
10
|
+
import { TestStores } from '../test-stores.js';
|
|
11
|
+
import { Time } from '../../src/utils/time.js';
|
|
12
|
+
import { afterAll, beforeAll, beforeEach, describe, expect, it } from 'bun:test';
|
|
13
|
+
import { DidKey, UniversalResolver } from '@enbox/dids';
|
|
14
|
+
/**
|
|
15
|
+
* Validation-state reader parity: replicated apply returns structured repair outcomes, but it
|
|
16
|
+
* must not admit messages through a weaker validation basis than `processMessage()`.
|
|
17
|
+
*/
|
|
18
|
+
describe('validation-state reader admission parity', () => {
|
|
19
|
+
let didResolver;
|
|
20
|
+
let messageStore;
|
|
21
|
+
let dataStore;
|
|
22
|
+
let resumableTaskStore;
|
|
23
|
+
let eventLog;
|
|
24
|
+
let dwn;
|
|
25
|
+
beforeAll(async () => {
|
|
26
|
+
didResolver = new UniversalResolver({ didResolvers: [DidKey] });
|
|
27
|
+
const stores = TestStores.get();
|
|
28
|
+
messageStore = stores.messageStore;
|
|
29
|
+
dataStore = stores.dataStore;
|
|
30
|
+
resumableTaskStore = stores.resumableTaskStore;
|
|
31
|
+
eventLog = TestEventLog.get();
|
|
32
|
+
dwn = await Dwn.create({ didResolver, messageStore, dataStore, eventLog, resumableTaskStore });
|
|
33
|
+
});
|
|
34
|
+
beforeEach(async () => {
|
|
35
|
+
await messageStore.clear();
|
|
36
|
+
await dataStore.clear();
|
|
37
|
+
await resumableTaskStore.clear();
|
|
38
|
+
});
|
|
39
|
+
afterAll(async () => {
|
|
40
|
+
await dwn.close();
|
|
41
|
+
});
|
|
42
|
+
describe('parent existence', () => {
|
|
43
|
+
it('should admit a child of a dataless parent through processMessage and replication apply', async () => {
|
|
44
|
+
const alice = await TestDataGenerator.generateDidKeyPersona();
|
|
45
|
+
const protocolDefinition = nestedProtocolDefinition;
|
|
46
|
+
const { message: configureMessage } = await TestDataGenerator.generateProtocolsConfigure({
|
|
47
|
+
author: alice,
|
|
48
|
+
protocolDefinition,
|
|
49
|
+
});
|
|
50
|
+
const configureReply = await dwn.processMessage(alice.did, configureMessage);
|
|
51
|
+
expect(configureReply.status.code).toBe(202);
|
|
52
|
+
// the parent replays dataless — a data-compacted parent is ancestry-only mid-replay
|
|
53
|
+
const { message: parentMessage, recordsWrite: parentWrite } = await TestDataGenerator.generateRecordsWrite({
|
|
54
|
+
author: alice,
|
|
55
|
+
protocol: protocolDefinition.protocol,
|
|
56
|
+
protocolPath: 'foo',
|
|
57
|
+
schema: 'foo',
|
|
58
|
+
dataFormat: 'text/plain',
|
|
59
|
+
});
|
|
60
|
+
const parentResult = await dwn.applyReplicatedMessage(alice.did, parentMessage);
|
|
61
|
+
expect(parentResult.kind).toBe('Applied'); // stored as non-queryable initial state (204)
|
|
62
|
+
const { message: processChildMessage, dataStream: processChildDataStream } = await TestDataGenerator.generateRecordsWrite({
|
|
63
|
+
author: alice,
|
|
64
|
+
protocol: protocolDefinition.protocol,
|
|
65
|
+
protocolPath: 'foo/bar',
|
|
66
|
+
schema: 'bar',
|
|
67
|
+
dataFormat: 'text/plain',
|
|
68
|
+
parentContextId: parentWrite.message.contextId,
|
|
69
|
+
});
|
|
70
|
+
const processReply = await dwn.processMessage(alice.did, processChildMessage, { dataStream: processChildDataStream });
|
|
71
|
+
expect(processReply.status.code).toBe(202);
|
|
72
|
+
const { message: replicatedChildMessage, dataBytes: replicatedChildDataBytes } = await TestDataGenerator.generateRecordsWrite({
|
|
73
|
+
author: alice,
|
|
74
|
+
protocol: protocolDefinition.protocol,
|
|
75
|
+
protocolPath: 'foo/bar',
|
|
76
|
+
schema: 'bar',
|
|
77
|
+
dataFormat: 'text/plain',
|
|
78
|
+
parentContextId: parentWrite.message.contextId,
|
|
79
|
+
});
|
|
80
|
+
const replicatedResult = await dwn.applyReplicatedMessage(alice.did, replicatedChildMessage, {
|
|
81
|
+
dataStream: DataStream.fromBytes(replicatedChildDataBytes),
|
|
82
|
+
});
|
|
83
|
+
expect(replicatedResult.kind).toBe('Applied');
|
|
84
|
+
});
|
|
85
|
+
it('should continue to admit a child after same-CID data retry is rejected', async () => {
|
|
86
|
+
const alice = await TestDataGenerator.generateDidKeyPersona();
|
|
87
|
+
const protocolDefinition = nestedProtocolDefinition;
|
|
88
|
+
const { message: configureMessage } = await TestDataGenerator.generateProtocolsConfigure({
|
|
89
|
+
author: alice,
|
|
90
|
+
protocolDefinition,
|
|
91
|
+
});
|
|
92
|
+
const configureReply = await dwn.processMessage(alice.did, configureMessage);
|
|
93
|
+
expect(configureReply.status.code).toBe(202);
|
|
94
|
+
const { message: parentMessage, recordsWrite: parentWrite, dataBytes: parentDataBytes } = await TestDataGenerator.generateRecordsWrite({
|
|
95
|
+
author: alice,
|
|
96
|
+
protocol: protocolDefinition.protocol,
|
|
97
|
+
protocolPath: 'foo',
|
|
98
|
+
schema: 'foo',
|
|
99
|
+
dataFormat: 'text/plain',
|
|
100
|
+
});
|
|
101
|
+
const datalessParentReply = await dwn.processMessage(alice.did, parentMessage);
|
|
102
|
+
expect(datalessParentReply.status.code).toBe(204);
|
|
103
|
+
const { message: childBeforeRetryMessage, dataStream: childBeforeRetryDataStream } = await TestDataGenerator.generateRecordsWrite({
|
|
104
|
+
author: alice,
|
|
105
|
+
protocol: protocolDefinition.protocol,
|
|
106
|
+
protocolPath: 'foo/bar',
|
|
107
|
+
schema: 'bar',
|
|
108
|
+
dataFormat: 'text/plain',
|
|
109
|
+
parentContextId: parentWrite.message.contextId,
|
|
110
|
+
});
|
|
111
|
+
const childBeforeRetryReply = await dwn.processMessage(alice.did, childBeforeRetryMessage, {
|
|
112
|
+
dataStream: childBeforeRetryDataStream,
|
|
113
|
+
});
|
|
114
|
+
expect(childBeforeRetryReply.status.code).toBe(202);
|
|
115
|
+
// Same-CID delivery with data is not a completion mechanism; the retained parent still
|
|
116
|
+
// authorizes children through immutable ancestry facts.
|
|
117
|
+
const retriedParentReply = await dwn.processMessage(alice.did, parentMessage, {
|
|
118
|
+
dataStream: DataStream.fromBytes(parentDataBytes),
|
|
119
|
+
});
|
|
120
|
+
expect(retriedParentReply.status.code).toBe(409);
|
|
121
|
+
const { message: childAfterRetryMessage, dataStream: childAfterRetryDataStream } = await TestDataGenerator.generateRecordsWrite({
|
|
122
|
+
author: alice,
|
|
123
|
+
protocol: protocolDefinition.protocol,
|
|
124
|
+
protocolPath: 'foo/bar',
|
|
125
|
+
schema: 'bar',
|
|
126
|
+
dataFormat: 'text/plain',
|
|
127
|
+
parentContextId: parentWrite.message.contextId,
|
|
128
|
+
});
|
|
129
|
+
const childAfterRetryReply = await dwn.processMessage(alice.did, childAfterRetryMessage, {
|
|
130
|
+
dataStream: childAfterRetryDataStream,
|
|
131
|
+
});
|
|
132
|
+
expect(childAfterRetryReply.status.code).toBe(202);
|
|
133
|
+
});
|
|
134
|
+
it('should admit a child after a parent update because immutable parent facts are unchanged', async () => {
|
|
135
|
+
const alice = await TestDataGenerator.generateDidKeyPersona();
|
|
136
|
+
const protocolDefinition = nestedProtocolDefinition;
|
|
137
|
+
const { message: configureMessage } = await TestDataGenerator.generateProtocolsConfigure({
|
|
138
|
+
author: alice,
|
|
139
|
+
protocolDefinition,
|
|
140
|
+
});
|
|
141
|
+
const configureReply = await dwn.processMessage(alice.did, configureMessage);
|
|
142
|
+
expect(configureReply.status.code).toBe(202);
|
|
143
|
+
const { message: parentMessage, dataStream: parentDataStream, recordsWrite: parentWrite } = await TestDataGenerator.generateRecordsWrite({
|
|
144
|
+
author: alice,
|
|
145
|
+
protocol: protocolDefinition.protocol,
|
|
146
|
+
protocolPath: 'foo',
|
|
147
|
+
schema: 'foo',
|
|
148
|
+
dataFormat: 'text/plain',
|
|
149
|
+
});
|
|
150
|
+
const parentReply = await dwn.processMessage(alice.did, parentMessage, { dataStream: parentDataStream });
|
|
151
|
+
expect(parentReply.status.code).toBe(202);
|
|
152
|
+
const parentUpdate = await RecordsWrite.createFrom({
|
|
153
|
+
recordsWriteMessage: parentMessage,
|
|
154
|
+
published: true,
|
|
155
|
+
signer: Jws.createSigner(alice),
|
|
156
|
+
});
|
|
157
|
+
const parentUpdateReply = await dwn.processMessage(alice.did, parentUpdate.message);
|
|
158
|
+
expect(parentUpdateReply.status.code).toBe(202);
|
|
159
|
+
const { message: childMessage, dataStream: childDataStream } = await TestDataGenerator.generateRecordsWrite({
|
|
160
|
+
author: alice,
|
|
161
|
+
protocol: protocolDefinition.protocol,
|
|
162
|
+
protocolPath: 'foo/bar',
|
|
163
|
+
schema: 'bar',
|
|
164
|
+
dataFormat: 'text/plain',
|
|
165
|
+
parentContextId: parentWrite.message.contextId,
|
|
166
|
+
});
|
|
167
|
+
const childReply = await dwn.processMessage(alice.did, childMessage, { dataStream: childDataStream });
|
|
168
|
+
expect(childReply.status.code).toBe(202);
|
|
169
|
+
});
|
|
170
|
+
it('should reject a child of a tombstoned parent through processMessage and replication apply', async () => {
|
|
171
|
+
const alice = await TestDataGenerator.generateDidKeyPersona();
|
|
172
|
+
const protocolDefinition = nestedProtocolDefinition;
|
|
173
|
+
const { message: configureMessage } = await TestDataGenerator.generateProtocolsConfigure({
|
|
174
|
+
author: alice,
|
|
175
|
+
protocolDefinition,
|
|
176
|
+
});
|
|
177
|
+
const configureReply = await dwn.processMessage(alice.did, configureMessage);
|
|
178
|
+
expect(configureReply.status.code).toBe(202);
|
|
179
|
+
// parent is written with data, then deleted — its initial write is retained beside the tombstone
|
|
180
|
+
const { message: parentMessage, dataStream: parentDataStream, recordsWrite: parentWrite } = await TestDataGenerator.generateRecordsWrite({
|
|
181
|
+
author: alice,
|
|
182
|
+
protocol: protocolDefinition.protocol,
|
|
183
|
+
protocolPath: 'foo',
|
|
184
|
+
schema: 'foo',
|
|
185
|
+
dataFormat: 'text/plain',
|
|
186
|
+
});
|
|
187
|
+
const parentReply = await dwn.processMessage(alice.did, parentMessage, { dataStream: parentDataStream });
|
|
188
|
+
expect(parentReply.status.code).toBe(202);
|
|
189
|
+
const { message: deleteMessage } = await TestDataGenerator.generateRecordsDelete({
|
|
190
|
+
author: alice,
|
|
191
|
+
recordId: parentMessage.recordId,
|
|
192
|
+
});
|
|
193
|
+
const deleteReply = await dwn.processMessage(alice.did, deleteMessage);
|
|
194
|
+
expect(deleteReply.status.code).toBe(202);
|
|
195
|
+
const { message: childMessage, dataStream: childDataStream, dataBytes: childDataBytes } = await TestDataGenerator.generateRecordsWrite({
|
|
196
|
+
author: alice,
|
|
197
|
+
protocol: protocolDefinition.protocol,
|
|
198
|
+
protocolPath: 'foo/bar',
|
|
199
|
+
schema: 'bar',
|
|
200
|
+
dataFormat: 'text/plain',
|
|
201
|
+
parentContextId: parentWrite.message.contextId,
|
|
202
|
+
});
|
|
203
|
+
// processMessage rejects — the latest-only filter exists exactly to exclude deleted parents
|
|
204
|
+
const processReply = await dwn.processMessage(alice.did, childMessage, { dataStream: childDataStream });
|
|
205
|
+
expect(processReply.status.code).toBe(400);
|
|
206
|
+
expect(processReply.status.detail).toContain(DwnErrorCode.ProtocolAuthorizationParentRecordNotFound);
|
|
207
|
+
// applyReplicatedMessage uses the same admission rule
|
|
208
|
+
const replicatedResult = await dwn.applyReplicatedMessage(alice.did, childMessage, {
|
|
209
|
+
dataStream: DataStream.fromBytes(childDataBytes),
|
|
210
|
+
});
|
|
211
|
+
expect(replicatedResult.kind).toBe('Incomplete');
|
|
212
|
+
if (replicatedResult.kind === 'Incomplete') {
|
|
213
|
+
expect(replicatedResult.missing[0].type).toBe('Parent');
|
|
214
|
+
}
|
|
215
|
+
});
|
|
216
|
+
});
|
|
217
|
+
describe('role records', () => {
|
|
218
|
+
it('should authorize a role-invoking write against a dataless role record through processMessage and replication apply', async () => {
|
|
219
|
+
const alice = await TestDataGenerator.generateDidKeyPersona();
|
|
220
|
+
const bob = await TestDataGenerator.generateDidKeyPersona();
|
|
221
|
+
const protocolDefinition = friendRoleProtocolDefinition;
|
|
222
|
+
const { message: configureMessage } = await TestDataGenerator.generateProtocolsConfigure({
|
|
223
|
+
author: alice,
|
|
224
|
+
protocolDefinition,
|
|
225
|
+
});
|
|
226
|
+
const configureReply = await dwn.processMessage(alice.did, configureMessage);
|
|
227
|
+
expect(configureReply.status.code).toBe(202);
|
|
228
|
+
// the role record replays dataless — an above-threshold role record is ancestry-only mid-replay
|
|
229
|
+
const { message: roleMessage } = await TestDataGenerator.generateRecordsWrite({
|
|
230
|
+
author: alice,
|
|
231
|
+
recipient: bob.did,
|
|
232
|
+
protocol: protocolDefinition.protocol,
|
|
233
|
+
protocolPath: 'friend',
|
|
234
|
+
});
|
|
235
|
+
const roleResult = await dwn.applyReplicatedMessage(alice.did, roleMessage);
|
|
236
|
+
expect(roleResult.kind).toBe('Applied'); // stored as non-queryable initial state (204)
|
|
237
|
+
const { message: processChatMessage, dataStream: processChatDataStream } = await TestDataGenerator.generateRecordsWrite({
|
|
238
|
+
author: bob,
|
|
239
|
+
protocol: protocolDefinition.protocol,
|
|
240
|
+
protocolPath: 'chat',
|
|
241
|
+
protocolRole: 'friend',
|
|
242
|
+
});
|
|
243
|
+
const processReply = await dwn.processMessage(alice.did, processChatMessage, { dataStream: processChatDataStream });
|
|
244
|
+
expect(processReply.status.code).toBe(202);
|
|
245
|
+
const { message: replicatedChatMessage, dataBytes: replicatedChatDataBytes } = await TestDataGenerator.generateRecordsWrite({
|
|
246
|
+
author: bob,
|
|
247
|
+
protocol: protocolDefinition.protocol,
|
|
248
|
+
protocolPath: 'chat',
|
|
249
|
+
protocolRole: 'friend',
|
|
250
|
+
});
|
|
251
|
+
const replicatedResult = await dwn.applyReplicatedMessage(alice.did, replicatedChatMessage, {
|
|
252
|
+
dataStream: DataStream.fromBytes(replicatedChatDataBytes),
|
|
253
|
+
});
|
|
254
|
+
expect(replicatedResult.kind).toBe('Applied');
|
|
255
|
+
});
|
|
256
|
+
it('should reject a role-invoking write against a tombstoned role record through processMessage and replication apply', async () => {
|
|
257
|
+
const alice = await TestDataGenerator.generateDidKeyPersona();
|
|
258
|
+
const bob = await TestDataGenerator.generateDidKeyPersona();
|
|
259
|
+
const protocolDefinition = friendRoleProtocolDefinition;
|
|
260
|
+
const { message: configureMessage } = await TestDataGenerator.generateProtocolsConfigure({
|
|
261
|
+
author: alice,
|
|
262
|
+
protocolDefinition,
|
|
263
|
+
});
|
|
264
|
+
const configureReply = await dwn.processMessage(alice.did, configureMessage);
|
|
265
|
+
expect(configureReply.status.code).toBe(202);
|
|
266
|
+
const { message: roleMessage, dataStream: roleDataStream } = await TestDataGenerator.generateRecordsWrite({
|
|
267
|
+
author: alice,
|
|
268
|
+
recipient: bob.did,
|
|
269
|
+
protocol: protocolDefinition.protocol,
|
|
270
|
+
protocolPath: 'friend',
|
|
271
|
+
});
|
|
272
|
+
const roleReply = await dwn.processMessage(alice.did, roleMessage, { dataStream: roleDataStream });
|
|
273
|
+
expect(roleReply.status.code).toBe(202);
|
|
274
|
+
const { message: deleteMessage } = await TestDataGenerator.generateRecordsDelete({
|
|
275
|
+
author: alice,
|
|
276
|
+
recordId: roleMessage.recordId,
|
|
277
|
+
});
|
|
278
|
+
const deleteReply = await dwn.processMessage(alice.did, deleteMessage);
|
|
279
|
+
expect(deleteReply.status.code).toBe(202);
|
|
280
|
+
const { message: chatMessage, dataStream: chatDataStream, dataBytes: chatDataBytes } = await TestDataGenerator.generateRecordsWrite({
|
|
281
|
+
author: bob,
|
|
282
|
+
protocol: protocolDefinition.protocol,
|
|
283
|
+
protocolPath: 'chat',
|
|
284
|
+
protocolRole: 'friend',
|
|
285
|
+
});
|
|
286
|
+
// processMessage rejects
|
|
287
|
+
const processReply = await dwn.processMessage(alice.did, chatMessage, { dataStream: chatDataStream });
|
|
288
|
+
expect(processReply.status.code).toBe(401);
|
|
289
|
+
expect(processReply.status.detail).toContain(DwnErrorCode.ProtocolAuthorizationMatchingRoleRecordNotFound);
|
|
290
|
+
// applyReplicatedMessage uses the same admission rule
|
|
291
|
+
const replicatedResult = await dwn.applyReplicatedMessage(alice.did, chatMessage, {
|
|
292
|
+
dataStream: DataStream.fromBytes(chatDataBytes),
|
|
293
|
+
});
|
|
294
|
+
expect(replicatedResult.kind).toBe('Incomplete');
|
|
295
|
+
if (replicatedResult.kind === 'Incomplete') {
|
|
296
|
+
expect(replicatedResult.missing[0].type).toBe('Role');
|
|
297
|
+
}
|
|
298
|
+
});
|
|
299
|
+
});
|
|
300
|
+
describe('protocol definition history', () => {
|
|
301
|
+
it('should accept backdated initial writes using the earliest retained config in both entry points', async () => {
|
|
302
|
+
const alice = await TestDataGenerator.generateDidKeyPersona();
|
|
303
|
+
const protocolUri = 'http://earliest-retained-config.xyz';
|
|
304
|
+
const v1Definition = {
|
|
305
|
+
protocol: protocolUri,
|
|
306
|
+
published: false,
|
|
307
|
+
types: {
|
|
308
|
+
foo: { schema: 'foo', dataFormats: ['text/plain'] },
|
|
309
|
+
bar: { schema: 'bar', dataFormats: ['text/plain'] },
|
|
310
|
+
},
|
|
311
|
+
structure: {
|
|
312
|
+
foo: {},
|
|
313
|
+
bar: {},
|
|
314
|
+
},
|
|
315
|
+
};
|
|
316
|
+
const v2Definition = {
|
|
317
|
+
protocol: protocolUri,
|
|
318
|
+
published: false,
|
|
319
|
+
types: {
|
|
320
|
+
bar: { schema: 'bar', dataFormats: ['text/plain'] },
|
|
321
|
+
},
|
|
322
|
+
structure: {
|
|
323
|
+
bar: {},
|
|
324
|
+
},
|
|
325
|
+
};
|
|
326
|
+
const writeTimestamp = Time.createTimestamp({ year: 2023, month: 1, day: 1 });
|
|
327
|
+
const v1Timestamp = Time.createTimestamp({ year: 2024, month: 1, day: 1 });
|
|
328
|
+
const v2Timestamp = Time.createTimestamp({ year: 2025, month: 1, day: 1 });
|
|
329
|
+
const recordsWrite = await TestDataGenerator.generateRecordsWrite({
|
|
330
|
+
author: alice,
|
|
331
|
+
protocol: protocolUri,
|
|
332
|
+
protocolPath: 'foo',
|
|
333
|
+
schema: 'foo',
|
|
334
|
+
dataFormat: 'text/plain',
|
|
335
|
+
dateCreated: writeTimestamp,
|
|
336
|
+
messageTimestamp: writeTimestamp,
|
|
337
|
+
});
|
|
338
|
+
const v1Configure = await TestDataGenerator.generateProtocolsConfigure({
|
|
339
|
+
author: alice,
|
|
340
|
+
protocolDefinition: v1Definition,
|
|
341
|
+
messageTimestamp: v1Timestamp,
|
|
342
|
+
});
|
|
343
|
+
expect((await dwn.processMessage(alice.did, v1Configure.message)).status.code).toBe(202);
|
|
344
|
+
const v2Configure = await TestDataGenerator.generateProtocolsConfigure({
|
|
345
|
+
author: alice,
|
|
346
|
+
protocolDefinition: v2Definition,
|
|
347
|
+
messageTimestamp: v2Timestamp,
|
|
348
|
+
});
|
|
349
|
+
expect((await dwn.processMessage(alice.did, v2Configure.message)).status.code).toBe(202);
|
|
350
|
+
const processReply = await dwn.processMessage(alice.did, recordsWrite.message, { dataStream: recordsWrite.dataStream });
|
|
351
|
+
expect(processReply.status.code).toBe(202);
|
|
352
|
+
const replicatedWrite = await TestDataGenerator.generateRecordsWrite({
|
|
353
|
+
author: alice,
|
|
354
|
+
protocol: protocolUri,
|
|
355
|
+
protocolPath: 'foo',
|
|
356
|
+
schema: 'foo',
|
|
357
|
+
dataFormat: 'text/plain',
|
|
358
|
+
dateCreated: writeTimestamp,
|
|
359
|
+
messageTimestamp: writeTimestamp,
|
|
360
|
+
});
|
|
361
|
+
const result = await dwn.applyReplicatedMessage(alice.did, replicatedWrite.message, { dataStream: DataStream.fromBytes(replicatedWrite.dataBytes) });
|
|
362
|
+
expect(result.kind).toBe('Applied');
|
|
363
|
+
});
|
|
364
|
+
it('should report a missing initial write through standard admission before replication maps it to incomplete', async () => {
|
|
365
|
+
const alice = await TestDataGenerator.generateDidKeyPersona();
|
|
366
|
+
const protocolDefinition = nestedProtocolDefinition;
|
|
367
|
+
const { message: configureMessage } = await TestDataGenerator.generateProtocolsConfigure({
|
|
368
|
+
author: alice,
|
|
369
|
+
protocolDefinition,
|
|
370
|
+
});
|
|
371
|
+
expect((await dwn.processMessage(alice.did, configureMessage)).status.code).toBe(202);
|
|
372
|
+
const initialWrite = await TestDataGenerator.generateRecordsWrite({
|
|
373
|
+
author: alice,
|
|
374
|
+
protocol: protocolDefinition.protocol,
|
|
375
|
+
protocolPath: 'foo',
|
|
376
|
+
schema: 'foo',
|
|
377
|
+
dataFormat: 'text/plain',
|
|
378
|
+
});
|
|
379
|
+
const update = await TestDataGenerator.generateFromRecordsWrite({
|
|
380
|
+
author: alice,
|
|
381
|
+
existingWrite: initialWrite.recordsWrite,
|
|
382
|
+
});
|
|
383
|
+
const processReply = await dwn.processMessage(alice.did, update.message, { dataStream: DataStream.fromBytes(update.dataBytes) });
|
|
384
|
+
expect(processReply.status.code).toBe(400);
|
|
385
|
+
expect(processReply.status.detail).toContain(DwnErrorCode.RecordsWriteGetInitialWriteNotFound);
|
|
386
|
+
const result = await dwn.applyReplicatedMessage(alice.did, update.message, { dataStream: DataStream.fromBytes(update.dataBytes) });
|
|
387
|
+
expect(result).toEqual({
|
|
388
|
+
kind: 'Incomplete',
|
|
389
|
+
missing: [{
|
|
390
|
+
type: 'InitialWrite',
|
|
391
|
+
recordId: update.message.recordId,
|
|
392
|
+
protocol: protocolDefinition.protocol,
|
|
393
|
+
}],
|
|
394
|
+
});
|
|
395
|
+
});
|
|
396
|
+
it('should validate replicated ProtocolsConfigure composition against current referenced configs', async () => {
|
|
397
|
+
const alice = await TestDataGenerator.generateDidKeyPersona();
|
|
398
|
+
const baseProtocolUri = 'http://historical-composition-base.xyz';
|
|
399
|
+
const composedProtocolUri = 'http://historical-composition-composed.xyz';
|
|
400
|
+
const v1Timestamp = Time.createTimestamp({ year: 2024, month: 1, day: 1 });
|
|
401
|
+
const composedTimestamp = Time.createTimestamp({ year: 2024, month: 6, day: 1 });
|
|
402
|
+
const v2Timestamp = Time.createTimestamp({ year: 2025, month: 1, day: 1 });
|
|
403
|
+
const baseV1Definition = {
|
|
404
|
+
protocol: baseProtocolUri,
|
|
405
|
+
published: false,
|
|
406
|
+
types: {
|
|
407
|
+
profile: { schema: 'profile', dataFormats: ['text/plain'] },
|
|
408
|
+
keeper: { schema: 'keeper', dataFormats: ['text/plain'] },
|
|
409
|
+
},
|
|
410
|
+
structure: {
|
|
411
|
+
profile: {},
|
|
412
|
+
keeper: {},
|
|
413
|
+
},
|
|
414
|
+
};
|
|
415
|
+
const baseV2Definition = {
|
|
416
|
+
protocol: baseProtocolUri,
|
|
417
|
+
published: false,
|
|
418
|
+
types: {
|
|
419
|
+
keeper: { schema: 'keeper', dataFormats: ['text/plain'] },
|
|
420
|
+
},
|
|
421
|
+
structure: {
|
|
422
|
+
keeper: {},
|
|
423
|
+
},
|
|
424
|
+
};
|
|
425
|
+
const composedDefinition = {
|
|
426
|
+
protocol: composedProtocolUri,
|
|
427
|
+
published: false,
|
|
428
|
+
uses: {
|
|
429
|
+
base: baseProtocolUri,
|
|
430
|
+
},
|
|
431
|
+
types: {
|
|
432
|
+
mirror: { schema: 'mirror', dataFormats: ['text/plain'] },
|
|
433
|
+
},
|
|
434
|
+
structure: {
|
|
435
|
+
mirror: {
|
|
436
|
+
$ref: 'base:profile',
|
|
437
|
+
},
|
|
438
|
+
},
|
|
439
|
+
};
|
|
440
|
+
const baseV1Configure = await TestDataGenerator.generateProtocolsConfigure({
|
|
441
|
+
author: alice,
|
|
442
|
+
protocolDefinition: baseV1Definition,
|
|
443
|
+
messageTimestamp: v1Timestamp,
|
|
444
|
+
});
|
|
445
|
+
expect((await dwn.processMessage(alice.did, baseV1Configure.message)).status.code).toBe(202);
|
|
446
|
+
const baseV2Configure = await TestDataGenerator.generateProtocolsConfigure({
|
|
447
|
+
author: alice,
|
|
448
|
+
protocolDefinition: baseV2Definition,
|
|
449
|
+
messageTimestamp: v2Timestamp,
|
|
450
|
+
});
|
|
451
|
+
expect((await dwn.processMessage(alice.did, baseV2Configure.message)).status.code).toBe(202);
|
|
452
|
+
const composedConfigure = await TestDataGenerator.generateProtocolsConfigure({
|
|
453
|
+
author: alice,
|
|
454
|
+
protocolDefinition: composedDefinition,
|
|
455
|
+
messageTimestamp: composedTimestamp,
|
|
456
|
+
});
|
|
457
|
+
const processReply = await dwn.processMessage(alice.did, composedConfigure.message);
|
|
458
|
+
expect(processReply.status.code).toBe(400);
|
|
459
|
+
expect(processReply.status.detail).toContain(DwnErrorCode.ProtocolsConfigureInvalidRefProtocolPath);
|
|
460
|
+
const replicatedResult = await dwn.applyReplicatedMessage(alice.did, composedConfigure.message);
|
|
461
|
+
expect(replicatedResult.kind).toBe('Invalid');
|
|
462
|
+
if (replicatedResult.kind === 'Invalid') {
|
|
463
|
+
expect(replicatedResult.reason).toContain(DwnErrorCode.ProtocolsConfigureInvalidRefProtocolPath);
|
|
464
|
+
}
|
|
465
|
+
});
|
|
466
|
+
it('should derive missing cross-protocol role dependencies from the incoming message timestamp config', async () => {
|
|
467
|
+
const alice = await TestDataGenerator.generateDidKeyPersona();
|
|
468
|
+
const bob = await TestDataGenerator.generateDidKeyPersona();
|
|
469
|
+
const roleProtocolV1Uri = 'http://role-context-v1.xyz';
|
|
470
|
+
const roleProtocolV2Uri = 'http://role-context-v2.xyz';
|
|
471
|
+
const composedProtocolUri = 'http://role-context-composed.xyz';
|
|
472
|
+
const v1Timestamp = Time.createTimestamp({ year: 2024, month: 1, day: 1 });
|
|
473
|
+
const initialTimestamp = Time.createTimestamp({ year: 2024, month: 6, day: 1 });
|
|
474
|
+
const v2Timestamp = Time.createTimestamp({ year: 2025, month: 1, day: 1 });
|
|
475
|
+
const updateTimestamp = Time.createTimestamp({ year: 2025, month: 6, day: 1 });
|
|
476
|
+
const roleProtocolV1 = {
|
|
477
|
+
protocol: roleProtocolV1Uri,
|
|
478
|
+
published: false,
|
|
479
|
+
types: {
|
|
480
|
+
participant: {},
|
|
481
|
+
},
|
|
482
|
+
structure: {
|
|
483
|
+
participant: {
|
|
484
|
+
$role: true,
|
|
485
|
+
},
|
|
486
|
+
},
|
|
487
|
+
};
|
|
488
|
+
const roleProtocolV2 = {
|
|
489
|
+
protocol: roleProtocolV2Uri,
|
|
490
|
+
published: false,
|
|
491
|
+
types: {
|
|
492
|
+
participant: {},
|
|
493
|
+
},
|
|
494
|
+
structure: {
|
|
495
|
+
participant: {
|
|
496
|
+
$role: true,
|
|
497
|
+
},
|
|
498
|
+
},
|
|
499
|
+
};
|
|
500
|
+
const composedV1 = {
|
|
501
|
+
protocol: composedProtocolUri,
|
|
502
|
+
published: false,
|
|
503
|
+
uses: {
|
|
504
|
+
roles: roleProtocolV1Uri,
|
|
505
|
+
},
|
|
506
|
+
types: {
|
|
507
|
+
comment: { schema: 'comment', dataFormats: ['text/plain'] },
|
|
508
|
+
},
|
|
509
|
+
structure: {
|
|
510
|
+
comment: {
|
|
511
|
+
$actions: [
|
|
512
|
+
{ who: 'anyone', can: ['create'] },
|
|
513
|
+
{ role: 'roles:participant', can: ['co-update'] },
|
|
514
|
+
],
|
|
515
|
+
},
|
|
516
|
+
},
|
|
517
|
+
};
|
|
518
|
+
const composedV2 = {
|
|
519
|
+
...composedV1,
|
|
520
|
+
uses: {
|
|
521
|
+
roles: roleProtocolV2Uri,
|
|
522
|
+
},
|
|
523
|
+
};
|
|
524
|
+
for (const protocolDefinition of [roleProtocolV1, roleProtocolV2]) {
|
|
525
|
+
const configure = await TestDataGenerator.generateProtocolsConfigure({ author: alice, protocolDefinition });
|
|
526
|
+
expect((await dwn.processMessage(alice.did, configure.message)).status.code).toBe(202);
|
|
527
|
+
}
|
|
528
|
+
const composedV1Configure = await TestDataGenerator.generateProtocolsConfigure({
|
|
529
|
+
author: alice,
|
|
530
|
+
protocolDefinition: composedV1,
|
|
531
|
+
messageTimestamp: v1Timestamp,
|
|
532
|
+
});
|
|
533
|
+
expect((await dwn.processMessage(alice.did, composedV1Configure.message)).status.code).toBe(202);
|
|
534
|
+
const initialComment = await TestDataGenerator.generateRecordsWrite({
|
|
535
|
+
author: alice,
|
|
536
|
+
protocol: composedProtocolUri,
|
|
537
|
+
protocolPath: 'comment',
|
|
538
|
+
schema: 'comment',
|
|
539
|
+
dataFormat: 'text/plain',
|
|
540
|
+
dateCreated: initialTimestamp,
|
|
541
|
+
messageTimestamp: initialTimestamp,
|
|
542
|
+
});
|
|
543
|
+
expect(await dwn.applyReplicatedMessage(alice.did, initialComment.message, { dataStream: DataStream.fromBytes(initialComment.dataBytes) })).toEqual(expect.objectContaining({ kind: 'Applied' }));
|
|
544
|
+
const composedV2Configure = await TestDataGenerator.generateProtocolsConfigure({
|
|
545
|
+
author: alice,
|
|
546
|
+
protocolDefinition: composedV2,
|
|
547
|
+
messageTimestamp: v2Timestamp,
|
|
548
|
+
});
|
|
549
|
+
expect((await dwn.processMessage(alice.did, composedV2Configure.message)).status.code).toBe(202);
|
|
550
|
+
const update = await TestDataGenerator.generateFromRecordsWrite({
|
|
551
|
+
author: bob,
|
|
552
|
+
existingWrite: initialComment.recordsWrite,
|
|
553
|
+
protocolRole: 'roles:participant',
|
|
554
|
+
messageTimestamp: updateTimestamp,
|
|
555
|
+
});
|
|
556
|
+
const result = await dwn.applyReplicatedMessage(alice.did, update.message, { dataStream: update.dataStream });
|
|
557
|
+
expect(result).toEqual({
|
|
558
|
+
kind: 'Incomplete',
|
|
559
|
+
missing: [{
|
|
560
|
+
type: 'Role',
|
|
561
|
+
protocol: roleProtocolV2Uri,
|
|
562
|
+
protocolPath: 'participant',
|
|
563
|
+
recipient: bob.did,
|
|
564
|
+
}],
|
|
565
|
+
});
|
|
566
|
+
});
|
|
567
|
+
it('should validate initial writes against the config active at their message timestamp in both entry points', async () => {
|
|
568
|
+
const alice = await TestDataGenerator.generateDidKeyPersona();
|
|
569
|
+
const protocolUri = 'http://config-history.xyz';
|
|
570
|
+
const v1Definition = {
|
|
571
|
+
protocol: protocolUri,
|
|
572
|
+
published: false,
|
|
573
|
+
types: {
|
|
574
|
+
alpha: { schema: 'alpha', dataFormats: ['text/plain'] },
|
|
575
|
+
keeper: { schema: 'keeper', dataFormats: ['text/plain'] },
|
|
576
|
+
},
|
|
577
|
+
structure: {
|
|
578
|
+
alpha: {},
|
|
579
|
+
keeper: {},
|
|
580
|
+
},
|
|
581
|
+
};
|
|
582
|
+
// v2 removes the `alpha` type entirely
|
|
583
|
+
const v2Definition = {
|
|
584
|
+
protocol: protocolUri,
|
|
585
|
+
published: false,
|
|
586
|
+
types: {
|
|
587
|
+
keeper: { schema: 'keeper', dataFormats: ['text/plain'] },
|
|
588
|
+
},
|
|
589
|
+
structure: {
|
|
590
|
+
keeper: {},
|
|
591
|
+
},
|
|
592
|
+
};
|
|
593
|
+
const v1Timestamp = Time.createTimestamp({ year: 2024, month: 1, day: 1 });
|
|
594
|
+
const writeTimestamp = Time.createTimestamp({ year: 2024, month: 6, day: 1 });
|
|
595
|
+
const v2Timestamp = Time.createTimestamp({ year: 2025, month: 1, day: 1 });
|
|
596
|
+
const { message: v1Message } = await TestDataGenerator.generateProtocolsConfigure({
|
|
597
|
+
author: alice,
|
|
598
|
+
protocolDefinition: v1Definition,
|
|
599
|
+
messageTimestamp: v1Timestamp,
|
|
600
|
+
});
|
|
601
|
+
const v1Reply = await dwn.processMessage(alice.did, v1Message);
|
|
602
|
+
expect(v1Reply.status.code).toBe(202);
|
|
603
|
+
const { message: v2Message } = await TestDataGenerator.generateProtocolsConfigure({
|
|
604
|
+
author: alice,
|
|
605
|
+
protocolDefinition: v2Definition,
|
|
606
|
+
messageTimestamp: v2Timestamp,
|
|
607
|
+
});
|
|
608
|
+
const v2Reply = await dwn.processMessage(alice.did, v2Message);
|
|
609
|
+
expect(v2Reply.status.code).toBe(202);
|
|
610
|
+
// an initial write authored between v1 and v2, arriving after v2 superseded v1
|
|
611
|
+
const { message: alphaMessage, dataStream: alphaDataStream } = await TestDataGenerator.generateRecordsWrite({
|
|
612
|
+
author: alice,
|
|
613
|
+
protocol: protocolUri,
|
|
614
|
+
protocolPath: 'alpha',
|
|
615
|
+
schema: 'alpha',
|
|
616
|
+
dataFormat: 'text/plain',
|
|
617
|
+
dateCreated: writeTimestamp,
|
|
618
|
+
messageTimestamp: writeTimestamp,
|
|
619
|
+
});
|
|
620
|
+
const processReply = await dwn.processMessage(alice.did, alphaMessage, { dataStream: alphaDataStream });
|
|
621
|
+
expect(processReply.status.code).toBe(202);
|
|
622
|
+
const replicatedWrite = await TestDataGenerator.generateRecordsWrite({
|
|
623
|
+
author: alice,
|
|
624
|
+
protocol: protocolUri,
|
|
625
|
+
protocolPath: 'alpha',
|
|
626
|
+
schema: 'alpha',
|
|
627
|
+
dataFormat: 'text/plain',
|
|
628
|
+
dateCreated: writeTimestamp,
|
|
629
|
+
messageTimestamp: writeTimestamp,
|
|
630
|
+
});
|
|
631
|
+
const replicatedResult = await dwn.applyReplicatedMessage(alice.did, replicatedWrite.message, {
|
|
632
|
+
dataStream: DataStream.fromBytes(replicatedWrite.dataBytes),
|
|
633
|
+
});
|
|
634
|
+
expect(replicatedResult.kind).toBe('Applied');
|
|
635
|
+
});
|
|
636
|
+
it('should enforce squash backstop from the config active at the incoming write timestamp in both entry points', async () => {
|
|
637
|
+
const alice = await TestDataGenerator.generateDidKeyPersona();
|
|
638
|
+
const protocolUri = 'http://config-history-squash.xyz';
|
|
639
|
+
const v1Definition = {
|
|
640
|
+
protocol: protocolUri,
|
|
641
|
+
published: false,
|
|
642
|
+
types: {
|
|
643
|
+
patch: { schema: 'patch', dataFormats: ['text/plain'] },
|
|
644
|
+
},
|
|
645
|
+
structure: {
|
|
646
|
+
patch: { $squash: true },
|
|
647
|
+
},
|
|
648
|
+
};
|
|
649
|
+
const v2Definition = {
|
|
650
|
+
protocol: protocolUri,
|
|
651
|
+
published: false,
|
|
652
|
+
types: {
|
|
653
|
+
patch: { schema: 'patch', dataFormats: ['text/plain'] },
|
|
654
|
+
},
|
|
655
|
+
structure: {
|
|
656
|
+
patch: {},
|
|
657
|
+
},
|
|
658
|
+
};
|
|
659
|
+
const v1Timestamp = Time.createTimestamp({ year: 2024, month: 1, day: 1 });
|
|
660
|
+
const olderPatchTimestamp = Time.createTimestamp({ year: 2024, month: 2, day: 1 });
|
|
661
|
+
const squashTimestamp = Time.createTimestamp({ year: 2024, month: 3, day: 1 });
|
|
662
|
+
const v2Timestamp = Time.createTimestamp({ year: 2024, month: 4, day: 1 });
|
|
663
|
+
const { message: v1Message } = await TestDataGenerator.generateProtocolsConfigure({
|
|
664
|
+
author: alice,
|
|
665
|
+
protocolDefinition: v1Definition,
|
|
666
|
+
messageTimestamp: v1Timestamp,
|
|
667
|
+
});
|
|
668
|
+
expect((await dwn.processMessage(alice.did, v1Message)).status.code).toBe(202);
|
|
669
|
+
const squashRecord = await TestDataGenerator.generateRecordsWrite({
|
|
670
|
+
author: alice,
|
|
671
|
+
protocol: protocolUri,
|
|
672
|
+
protocolPath: 'patch',
|
|
673
|
+
schema: 'patch',
|
|
674
|
+
dataFormat: 'text/plain',
|
|
675
|
+
dateCreated: squashTimestamp,
|
|
676
|
+
messageTimestamp: squashTimestamp,
|
|
677
|
+
squash: true,
|
|
678
|
+
});
|
|
679
|
+
expect((await dwn.processMessage(alice.did, squashRecord.message, { dataStream: squashRecord.dataStream })).status.code).toBe(202);
|
|
680
|
+
const { message: v2Message } = await TestDataGenerator.generateProtocolsConfigure({
|
|
681
|
+
author: alice,
|
|
682
|
+
protocolDefinition: v2Definition,
|
|
683
|
+
messageTimestamp: v2Timestamp,
|
|
684
|
+
});
|
|
685
|
+
expect((await dwn.processMessage(alice.did, v2Message)).status.code).toBe(202);
|
|
686
|
+
const processOlderPatch = await TestDataGenerator.generateRecordsWrite({
|
|
687
|
+
author: alice,
|
|
688
|
+
protocol: protocolUri,
|
|
689
|
+
protocolPath: 'patch',
|
|
690
|
+
schema: 'patch',
|
|
691
|
+
dataFormat: 'text/plain',
|
|
692
|
+
dateCreated: olderPatchTimestamp,
|
|
693
|
+
messageTimestamp: olderPatchTimestamp,
|
|
694
|
+
});
|
|
695
|
+
const processReply = await dwn.processMessage(alice.did, processOlderPatch.message, {
|
|
696
|
+
dataStream: processOlderPatch.dataStream,
|
|
697
|
+
});
|
|
698
|
+
expect(processReply.status.code).toBe(409);
|
|
699
|
+
expect(processReply.status.detail).toContain(DwnErrorCode.ProtocolAuthorizationSquashBackstop);
|
|
700
|
+
const olderPatch = await TestDataGenerator.generateRecordsWrite({
|
|
701
|
+
author: alice,
|
|
702
|
+
protocol: protocolUri,
|
|
703
|
+
protocolPath: 'patch',
|
|
704
|
+
schema: 'patch',
|
|
705
|
+
dataFormat: 'text/plain',
|
|
706
|
+
dateCreated: olderPatchTimestamp,
|
|
707
|
+
messageTimestamp: olderPatchTimestamp,
|
|
708
|
+
});
|
|
709
|
+
const result = await dwn.applyReplicatedMessage(alice.did, olderPatch.message, {
|
|
710
|
+
dataStream: DataStream.fromBytes(olderPatch.dataBytes),
|
|
711
|
+
});
|
|
712
|
+
expect(result.kind).toBe('Superseded');
|
|
713
|
+
});
|
|
714
|
+
});
|
|
715
|
+
});
|
|
716
|
+
//# sourceMappingURL=validation-state-reader.spec.js.map
|