@moltzap/client 2026.811.0 → 2026.902.0
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/LICENSE +202 -21
- package/NOTICE +19 -0
- package/README.md +50 -0
- package/bin/moltzapd +9 -0
- package/dist/client-runtime.d.ts +10 -0
- package/dist/client-runtime.d.ts.map +1 -0
- package/dist/client-runtime.js +218 -0
- package/dist/client-runtime.js.map +1 -0
- package/dist/contract.d.ts +338 -0
- package/dist/contract.d.ts.map +1 -0
- package/dist/contract.js +213 -0
- package/dist/contract.js.map +1 -0
- package/dist/contract.types-check.d.ts +99 -0
- package/dist/contract.types-check.d.ts.map +1 -0
- package/dist/contract.types-check.js +7 -0
- package/dist/contract.types-check.js.map +1 -0
- package/dist/daemon/configuration.d.ts +46 -0
- package/dist/daemon/configuration.d.ts.map +1 -0
- package/dist/daemon/configuration.js +69 -0
- package/dist/daemon/configuration.js.map +1 -0
- package/dist/daemon/management.d.ts +23 -0
- package/dist/daemon/management.d.ts.map +1 -0
- package/dist/daemon/management.js +489 -0
- package/dist/daemon/management.js.map +1 -0
- package/dist/daemon/registration.d.ts +72 -0
- package/dist/daemon/registration.d.ts.map +1 -0
- package/dist/daemon/registration.js +109 -0
- package/dist/daemon/registration.js.map +1 -0
- package/dist/daemon/runtime/activation.d.ts +95 -0
- package/dist/daemon/runtime/activation.d.ts.map +1 -0
- package/dist/daemon/runtime/activation.js +99 -0
- package/dist/daemon/runtime/activation.js.map +1 -0
- package/dist/daemon/runtime/controller.d.ts +34 -0
- package/dist/daemon/runtime/controller.d.ts.map +1 -0
- package/dist/daemon/runtime/controller.js +106 -0
- package/dist/daemon/runtime/controller.js.map +1 -0
- package/dist/daemon/runtime/history-export.d.ts +23 -0
- package/dist/daemon/runtime/history-export.d.ts.map +1 -0
- package/dist/daemon/runtime/history-export.js +47 -0
- package/dist/daemon/runtime/history-export.js.map +1 -0
- package/dist/daemon/runtime/index.d.ts +24 -0
- package/dist/daemon/runtime/index.d.ts.map +1 -0
- package/dist/daemon/runtime/index.js +65 -0
- package/dist/daemon/runtime/index.js.map +1 -0
- package/dist/daemon/runtime/protocol.d.ts +63 -0
- package/dist/daemon/runtime/protocol.d.ts.map +1 -0
- package/dist/daemon/runtime/protocol.js +133 -0
- package/dist/daemon/runtime/protocol.js.map +1 -0
- package/dist/endpoint/addressing/index.d.ts +39 -0
- package/dist/endpoint/addressing/index.d.ts.map +1 -0
- package/dist/endpoint/addressing/index.js +114 -0
- package/dist/endpoint/addressing/index.js.map +1 -0
- package/dist/endpoint/engine-dissemination.d.ts +11 -0
- package/dist/endpoint/engine-dissemination.d.ts.map +1 -0
- package/dist/endpoint/engine-dissemination.js +71 -0
- package/dist/endpoint/engine-dissemination.js.map +1 -0
- package/dist/endpoint/engine-durability.d.ts +69 -0
- package/dist/endpoint/engine-durability.d.ts.map +1 -0
- package/dist/endpoint/engine-durability.js +210 -0
- package/dist/endpoint/engine-durability.js.map +1 -0
- package/dist/endpoint/engine-send.d.ts +50 -0
- package/dist/endpoint/engine-send.d.ts.map +1 -0
- package/dist/endpoint/engine-send.js +422 -0
- package/dist/endpoint/engine-send.js.map +1 -0
- package/dist/endpoint/engine-types.d.ts +132 -0
- package/dist/endpoint/engine-types.d.ts.map +1 -0
- package/dist/endpoint/engine-types.js +13 -0
- package/dist/endpoint/engine-types.js.map +1 -0
- package/dist/endpoint/engine.d.ts +14 -0
- package/dist/endpoint/engine.d.ts.map +1 -0
- package/dist/endpoint/engine.js +280 -0
- package/dist/endpoint/engine.js.map +1 -0
- package/dist/endpoint/protocol/evidence.d.ts +37 -0
- package/dist/endpoint/protocol/evidence.d.ts.map +1 -0
- package/dist/endpoint/protocol/evidence.js +80 -0
- package/dist/endpoint/protocol/evidence.js.map +1 -0
- package/dist/endpoint/protocol/index.d.ts +26 -0
- package/dist/endpoint/protocol/index.d.ts.map +1 -0
- package/dist/endpoint/protocol/index.js +543 -0
- package/dist/endpoint/protocol/index.js.map +1 -0
- package/dist/endpoint/recovery/barrier.d.ts +23 -0
- package/dist/endpoint/recovery/barrier.d.ts.map +1 -0
- package/dist/endpoint/recovery/barrier.js +47 -0
- package/dist/endpoint/recovery/barrier.js.map +1 -0
- package/dist/endpoint/recovery/index.d.ts +29 -0
- package/dist/endpoint/recovery/index.d.ts.map +1 -0
- package/dist/endpoint/recovery/index.js +489 -0
- package/dist/endpoint/recovery/index.js.map +1 -0
- package/dist/endpoint/recovery/reanchor/empty.d.ts +22 -0
- package/dist/endpoint/recovery/reanchor/empty.d.ts.map +1 -0
- package/dist/endpoint/recovery/reanchor/empty.js +163 -0
- package/dist/endpoint/recovery/reanchor/empty.js.map +1 -0
- package/dist/endpoint/recovery/reanchor/index.d.ts +30 -0
- package/dist/endpoint/recovery/reanchor/index.d.ts.map +1 -0
- package/dist/endpoint/recovery/reanchor/index.js +479 -0
- package/dist/endpoint/recovery/reanchor/index.js.map +1 -0
- package/dist/endpoint/recovery/state.d.ts +130 -0
- package/dist/endpoint/recovery/state.d.ts.map +1 -0
- package/dist/endpoint/recovery/state.js +296 -0
- package/dist/endpoint/recovery/state.js.map +1 -0
- package/dist/endpoint/recovery/store-evidence.d.ts +17 -0
- package/dist/endpoint/recovery/store-evidence.d.ts.map +1 -0
- package/dist/endpoint/recovery/store-evidence.js +79 -0
- package/dist/endpoint/recovery/store-evidence.js.map +1 -0
- package/dist/endpoint/recovery/store.d.ts +56 -0
- package/dist/endpoint/recovery/store.d.ts.map +1 -0
- package/dist/endpoint/recovery/store.js +499 -0
- package/dist/endpoint/recovery/store.js.map +1 -0
- package/dist/endpoint/representation-canonical.d.ts +17 -0
- package/dist/endpoint/representation-canonical.d.ts.map +1 -0
- package/dist/endpoint/representation-canonical.js +48 -0
- package/dist/endpoint/representation-canonical.js.map +1 -0
- package/dist/endpoint/representation-codec.d.ts +51 -0
- package/dist/endpoint/representation-codec.d.ts.map +1 -0
- package/dist/endpoint/representation-codec.js +159 -0
- package/dist/endpoint/representation-codec.js.map +1 -0
- package/dist/endpoint/representation-schemas.d.ts +1831 -0
- package/dist/endpoint/representation-schemas.d.ts.map +1 -0
- package/dist/endpoint/representation-schemas.js +195 -0
- package/dist/endpoint/representation-schemas.js.map +1 -0
- package/dist/endpoint/representation-verification.d.ts +79 -0
- package/dist/endpoint/representation-verification.d.ts.map +1 -0
- package/dist/endpoint/representation-verification.js +420 -0
- package/dist/endpoint/representation-verification.js.map +1 -0
- package/dist/endpoint/representation.d.ts +6 -0
- package/dist/endpoint/representation.d.ts.map +1 -0
- package/dist/endpoint/representation.js +8 -0
- package/dist/endpoint/representation.js.map +1 -0
- package/dist/endpoint/router-worker/index.d.ts +16 -0
- package/dist/endpoint/router-worker/index.d.ts.map +1 -0
- package/dist/endpoint/router-worker/index.js +547 -0
- package/dist/endpoint/router-worker/index.js.map +1 -0
- package/dist/endpoint/router-worker/types.d.ts +183 -0
- package/dist/endpoint/router-worker/types.d.ts.map +1 -0
- package/dist/endpoint/router-worker/types.js +31 -0
- package/dist/endpoint/router-worker/types.js.map +1 -0
- package/dist/endpoint/store/anchors.d.ts +83 -0
- package/dist/endpoint/store/anchors.d.ts.map +1 -0
- package/dist/endpoint/store/anchors.js +471 -0
- package/dist/endpoint/store/anchors.js.map +1 -0
- package/dist/endpoint/store/database/index.d.ts +6 -0
- package/dist/endpoint/store/database/index.d.ts.map +1 -0
- package/dist/endpoint/store/database/index.js +6 -0
- package/dist/endpoint/store/database/index.js.map +1 -0
- package/dist/endpoint/store/database/schema.d.ts +44 -0
- package/dist/endpoint/store/database/schema.d.ts.map +1 -0
- package/dist/endpoint/store/database/schema.js +345 -0
- package/dist/endpoint/store/database/schema.js.map +1 -0
- package/dist/endpoint/store/database/values.d.ts +119 -0
- package/dist/endpoint/store/database/values.d.ts.map +1 -0
- package/dist/endpoint/store/database/values.js +194 -0
- package/dist/endpoint/store/database/values.js.map +1 -0
- package/dist/endpoint/store/deliveries.d.ts +38 -0
- package/dist/endpoint/store/deliveries.d.ts.map +1 -0
- package/dist/endpoint/store/deliveries.js +124 -0
- package/dist/endpoint/store/deliveries.js.map +1 -0
- package/dist/endpoint/store/dissemination.d.ts +27 -0
- package/dist/endpoint/store/dissemination.d.ts.map +1 -0
- package/dist/endpoint/store/dissemination.js +139 -0
- package/dist/endpoint/store/dissemination.js.map +1 -0
- package/dist/endpoint/store/index.d.ts +15 -0
- package/dist/endpoint/store/index.d.ts.map +1 -0
- package/dist/endpoint/store/index.js +76 -0
- package/dist/endpoint/store/index.js.map +1 -0
- package/dist/endpoint/store/management.d.ts +42 -0
- package/dist/endpoint/store/management.d.ts.map +1 -0
- package/dist/endpoint/store/management.js +259 -0
- package/dist/endpoint/store/management.js.map +1 -0
- package/dist/endpoint/store/outbound.d.ts +62 -0
- package/dist/endpoint/store/outbound.d.ts.map +1 -0
- package/dist/endpoint/store/outbound.js +278 -0
- package/dist/endpoint/store/outbound.js.map +1 -0
- package/dist/endpoint/store/records.d.ts +56 -0
- package/dist/endpoint/store/records.d.ts.map +1 -0
- package/dist/endpoint/store/records.js +352 -0
- package/dist/endpoint/store/records.js.map +1 -0
- package/dist/endpoint/store/rows/index.d.ts +138 -0
- package/dist/endpoint/store/rows/index.d.ts.map +1 -0
- package/dist/endpoint/store/rows/index.js +307 -0
- package/dist/endpoint/store/rows/index.js.map +1 -0
- package/dist/endpoint/store/types.d.ts +223 -0
- package/dist/endpoint/store/types.d.ts.map +1 -0
- package/dist/endpoint/store/types.js +15 -0
- package/dist/endpoint/store/types.js.map +1 -0
- package/dist/endpoint/store.d.ts +10 -0
- package/dist/endpoint/store.d.ts.map +1 -0
- package/dist/endpoint/store.js +6 -0
- package/dist/endpoint/store.js.map +1 -0
- package/dist/harness-mcp-contract.d.ts +101 -0
- package/dist/harness-mcp-contract.d.ts.map +1 -0
- package/dist/harness-mcp-contract.js +61 -0
- package/dist/harness-mcp-contract.js.map +1 -0
- package/dist/harness-mcp-http.d.ts +19 -0
- package/dist/harness-mcp-http.d.ts.map +1 -0
- package/dist/{harness-mcp-server.js → harness-mcp-http.js} +43 -71
- package/dist/harness-mcp-http.js.map +1 -0
- package/dist/harness-mcp-subscription.d.ts +12 -7
- package/dist/harness-mcp-subscription.d.ts.map +1 -1
- package/dist/harness-mcp-subscription.js +113 -100
- package/dist/harness-mcp-subscription.js.map +1 -1
- package/dist/harness-mcp-wire.d.ts +26 -19
- package/dist/harness-mcp-wire.d.ts.map +1 -1
- package/dist/harness-mcp-wire.js +380 -67
- package/dist/harness-mcp-wire.js.map +1 -1
- package/dist/index.d.ts +4 -8
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -8
- package/dist/index.js.map +1 -1
- package/dist/management-runtime.d.ts +217 -0
- package/dist/management-runtime.d.ts.map +1 -0
- package/dist/management-runtime.js +127 -0
- package/dist/management-runtime.js.map +1 -0
- package/dist/server.d.ts +16 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +46 -0
- package/dist/server.js.map +1 -0
- package/dist/server.types-check.d.ts +23 -0
- package/dist/server.types-check.d.ts.map +1 -0
- package/dist/server.types-check.js +7 -0
- package/dist/server.types-check.js.map +1 -0
- package/package.json +45 -47
- package/dist/agent-client.d.ts +0 -5
- package/dist/agent-client.d.ts.map +0 -1
- package/dist/agent-client.js +0 -3
- package/dist/agent-client.js.map +0 -1
- package/dist/auth.d.ts +0 -37
- package/dist/auth.d.ts.map +0 -1
- package/dist/auth.js +0 -79
- package/dist/auth.js.map +0 -1
- package/dist/bounded-map.d.ts +0 -32
- package/dist/bounded-map.d.ts.map +0 -1
- package/dist/bounded-map.js +0 -79
- package/dist/bounded-map.js.map +0 -1
- package/dist/channel-base/format-cross-conv.d.ts +0 -43
- package/dist/channel-base/format-cross-conv.d.ts.map +0 -1
- package/dist/channel-base/format-cross-conv.js +0 -65
- package/dist/channel-base/format-cross-conv.js.map +0 -1
- package/dist/channel-base/format-group-block.d.ts +0 -48
- package/dist/channel-base/format-group-block.d.ts.map +0 -1
- package/dist/channel-base/format-group-block.js +0 -62
- package/dist/channel-base/format-group-block.js.map +0 -1
- package/dist/channel-base/index.d.ts +0 -12
- package/dist/channel-base/index.d.ts.map +0 -1
- package/dist/channel-base/index.js +0 -13
- package/dist/channel-base/index.js.map +0 -1
- package/dist/channel-core-enrichment.d.ts +0 -14
- package/dist/channel-core-enrichment.d.ts.map +0 -1
- package/dist/channel-core-enrichment.js +0 -143
- package/dist/channel-core-enrichment.js.map +0 -1
- package/dist/channel-core-test-support.d.ts +0 -75
- package/dist/channel-core-test-support.d.ts.map +0 -1
- package/dist/channel-core-test-support.js +0 -74
- package/dist/channel-core-test-support.js.map +0 -1
- package/dist/channel-core.d.ts +0 -304
- package/dist/channel-core.d.ts.map +0 -1
- package/dist/channel-core.js +0 -363
- package/dist/channel-core.js.map +0 -1
- package/dist/cli/adapters.d.ts +0 -21
- package/dist/cli/adapters.d.ts.map +0 -1
- package/dist/cli/adapters.js +0 -111
- package/dist/cli/adapters.js.map +0 -1
- package/dist/cli/commands/agents.d.ts +0 -11
- package/dist/cli/commands/agents.d.ts.map +0 -1
- package/dist/cli/commands/agents.js +0 -27
- package/dist/cli/commands/agents.js.map +0 -1
- package/dist/cli/commands/conversations.d.ts +0 -18
- package/dist/cli/commands/conversations.d.ts.map +0 -1
- package/dist/cli/commands/conversations.js +0 -33
- package/dist/cli/commands/conversations.js.map +0 -1
- package/dist/cli/commands/messages.d.ts +0 -41
- package/dist/cli/commands/messages.d.ts.map +0 -1
- package/dist/cli/commands/messages.js +0 -39
- package/dist/cli/commands/messages.js.map +0 -1
- package/dist/cli/commands/register.d.ts +0 -46
- package/dist/cli/commands/register.d.ts.map +0 -1
- package/dist/cli/commands/register.js +0 -103
- package/dist/cli/commands/register.js.map +0 -1
- package/dist/cli/commands/send.d.ts +0 -53
- package/dist/cli/commands/send.d.ts.map +0 -1
- package/dist/cli/commands/send.js +0 -57
- package/dist/cli/commands/send.js.map +0 -1
- package/dist/cli/commands/start.d.ts +0 -34
- package/dist/cli/commands/start.d.ts.map +0 -1
- package/dist/cli/commands/start.js +0 -59
- package/dist/cli/commands/start.js.map +0 -1
- package/dist/cli/commands/status.d.ts +0 -7
- package/dist/cli/commands/status.d.ts.map +0 -1
- package/dist/cli/commands/status.js +0 -16
- package/dist/cli/commands/status.js.map +0 -1
- package/dist/cli/commands/test-transport.d.ts +0 -28
- package/dist/cli/commands/test-transport.d.ts.map +0 -1
- package/dist/cli/commands/test-transport.js +0 -40
- package/dist/cli/commands/test-transport.js.map +0 -1
- package/dist/cli/index.d.ts +0 -3
- package/dist/cli/index.d.ts.map +0 -1
- package/dist/cli/index.js +0 -105
- package/dist/cli/index.js.map +0 -1
- package/dist/cli/output.d.ts +0 -14
- package/dist/cli/output.d.ts.map +0 -1
- package/dist/cli/output.js +0 -19
- package/dist/cli/output.js.map +0 -1
- package/dist/cli/socket-client.d.ts +0 -28
- package/dist/cli/socket-client.d.ts.map +0 -1
- package/dist/cli/socket-client.js +0 -63
- package/dist/cli/socket-client.js.map +0 -1
- package/dist/cli/transport.d.ts +0 -132
- package/dist/cli/transport.d.ts.map +0 -1
- package/dist/cli/transport.js +0 -127
- package/dist/cli/transport.js.map +0 -1
- package/dist/config.d.ts +0 -33
- package/dist/config.d.ts.map +0 -1
- package/dist/config.js +0 -45
- package/dist/config.js.map +0 -1
- package/dist/config.test-utils.d.ts +0 -18
- package/dist/config.test-utils.d.ts.map +0 -1
- package/dist/config.test-utils.js +0 -53
- package/dist/config.test-utils.js.map +0 -1
- package/dist/harness/client-runtime.d.ts +0 -24
- package/dist/harness/client-runtime.d.ts.map +0 -1
- package/dist/harness/client-runtime.js +0 -107
- package/dist/harness/client-runtime.js.map +0 -1
- package/dist/harness/index.d.ts +0 -5
- package/dist/harness/index.d.ts.map +0 -1
- package/dist/harness/index.js +0 -5
- package/dist/harness/index.js.map +0 -1
- package/dist/harness/runtime.d.ts +0 -149
- package/dist/harness/runtime.d.ts.map +0 -1
- package/dist/harness/runtime.js +0 -68
- package/dist/harness/runtime.js.map +0 -1
- package/dist/harness-client.d.ts +0 -43
- package/dist/harness-client.d.ts.map +0 -1
- package/dist/harness-client.js +0 -21
- package/dist/harness-client.js.map +0 -1
- package/dist/harness-mcp-server.d.ts +0 -19
- package/dist/harness-mcp-server.d.ts.map +0 -1
- package/dist/harness-mcp-server.js.map +0 -1
- package/dist/local-daemon-rpc.d.ts +0 -1170
- package/dist/local-daemon-rpc.d.ts.map +0 -1
- package/dist/local-daemon-rpc.js +0 -178
- package/dist/local-daemon-rpc.js.map +0 -1
- package/dist/local-history.d.ts +0 -75
- package/dist/local-history.d.ts.map +0 -1
- package/dist/local-history.js +0 -82
- package/dist/local-history.js.map +0 -1
- package/dist/local-paths.d.ts +0 -22
- package/dist/local-paths.d.ts.map +0 -1
- package/dist/local-paths.js +0 -33
- package/dist/local-paths.js.map +0 -1
- package/dist/local-socket-server.d.ts +0 -33
- package/dist/local-socket-server.d.ts.map +0 -1
- package/dist/local-socket-server.js +0 -100
- package/dist/local-socket-server.js.map +0 -1
- package/dist/message-rendering.d.ts +0 -4
- package/dist/message-rendering.d.ts.map +0 -1
- package/dist/message-rendering.js +0 -8
- package/dist/message-rendering.js.map +0 -1
- package/dist/moltzapd.d.ts +0 -38
- package/dist/moltzapd.d.ts.map +0 -1
- package/dist/moltzapd.js +0 -78
- package/dist/moltzapd.js.map +0 -1
- package/dist/notification/__tests__/subscribe-signatures.types-check.d.ts +0 -53
- package/dist/notification/__tests__/subscribe-signatures.types-check.d.ts.map +0 -1
- package/dist/notification/__tests__/subscribe-signatures.types-check.js +0 -29
- package/dist/notification/__tests__/subscribe-signatures.types-check.js.map +0 -1
- package/dist/notification/errors.d.ts +0 -41
- package/dist/notification/errors.d.ts.map +0 -1
- package/dist/notification/errors.js +0 -24
- package/dist/notification/errors.js.map +0 -1
- package/dist/notification/index.d.ts +0 -6
- package/dist/notification/index.d.ts.map +0 -1
- package/dist/notification/index.js +0 -6
- package/dist/notification/index.js.map +0 -1
- package/dist/notification/stream.d.ts +0 -75
- package/dist/notification/stream.d.ts.map +0 -1
- package/dist/notification/stream.js +0 -30
- package/dist/notification/stream.js.map +0 -1
- package/dist/pagination.d.ts +0 -52
- package/dist/pagination.d.ts.map +0 -1
- package/dist/pagination.js +0 -51
- package/dist/pagination.js.map +0 -1
- package/dist/profile.d.ts +0 -104
- package/dist/profile.d.ts.map +0 -1
- package/dist/profile.js +0 -163
- package/dist/profile.js.map +0 -1
- package/dist/refs.d.ts +0 -18
- package/dist/refs.d.ts.map +0 -1
- package/dist/refs.js +0 -18
- package/dist/refs.js.map +0 -1
- package/dist/service-event-trace.d.ts +0 -15
- package/dist/service-event-trace.d.ts.map +0 -1
- package/dist/service-event-trace.js +0 -35
- package/dist/service-event-trace.js.map +0 -1
- package/dist/service-helpers.d.ts +0 -55
- package/dist/service-helpers.d.ts.map +0 -1
- package/dist/service-helpers.js +0 -108
- package/dist/service-helpers.js.map +0 -1
- package/dist/service-local-daemon.d.ts +0 -32
- package/dist/service-local-daemon.d.ts.map +0 -1
- package/dist/service-local-daemon.js +0 -153
- package/dist/service-local-daemon.js.map +0 -1
- package/dist/service.d.ts +0 -299
- package/dist/service.d.ts.map +0 -1
- package/dist/service.js +0 -789
- package/dist/service.js.map +0 -1
- package/dist/test-utils/channel-service-fixture.d.ts +0 -53
- package/dist/test-utils/channel-service-fixture.d.ts.map +0 -1
- package/dist/test-utils/channel-service-fixture.js +0 -178
- package/dist/test-utils/channel-service-fixture.js.map +0 -1
- package/dist/test-utils/fake-service.d.ts +0 -84
- package/dist/test-utils/fake-service.d.ts.map +0 -1
- package/dist/test-utils/fake-service.js +0 -108
- package/dist/test-utils/fake-service.js.map +0 -1
- package/dist/test-utils/harness.d.ts +0 -27
- package/dist/test-utils/harness.d.ts.map +0 -1
- package/dist/test-utils/harness.js +0 -33
- package/dist/test-utils/harness.js.map +0 -1
- package/dist/test-utils/ids.d.ts +0 -21
- package/dist/test-utils/ids.d.ts.map +0 -1
- package/dist/test-utils/ids.js +0 -68
- package/dist/test-utils/ids.js.map +0 -1
- package/dist/test-utils/index.d.ts +0 -54
- package/dist/test-utils/index.d.ts.map +0 -1
- package/dist/test-utils/index.js +0 -65
- package/dist/test-utils/index.js.map +0 -1
- package/dist/test-utils/standalone-provisioning.d.ts +0 -22
- package/dist/test-utils/standalone-provisioning.d.ts.map +0 -1
- package/dist/test-utils/standalone-provisioning.js +0 -17
- package/dist/test-utils/standalone-provisioning.js.map +0 -1
- package/dist/tsconfig.tsbuildinfo +0 -1
|
@@ -0,0 +1,259 @@
|
|
|
1
|
+
/** @file Recovery and frozen local management reads over certified history. */
|
|
2
|
+
import { copyBytes, mintContinuation, readBytes, readInteger, readOptionalText, readText, StoreSignal, validateContinuation, } from "./database/index.js";
|
|
3
|
+
import { readRetainedDeliveries } from "./deliveries.js";
|
|
4
|
+
import { readPendingDissemination } from "./dissemination.js";
|
|
5
|
+
import { readPendingOutbound } from "./outbound.js";
|
|
6
|
+
import { readCertifiedRecord, readConversationPosition, readProposalLock, readProtocolEvidence, readRecoveredReanchor, readStagedRecord, readStoredIdentity, } from "./rows/index.js";
|
|
7
|
+
const HISTORY_PAGE_SIZE = 50;
|
|
8
|
+
const historyQuery = `
|
|
9
|
+
SELECT staged.conversation_id, staged.record_hash,
|
|
10
|
+
staged.previous_record_hash, staged.membership_hash,
|
|
11
|
+
staged.anchor_hash, staged.action_hash, staged.author_agent_id,
|
|
12
|
+
staged.post_id, staged.canonical_record_core
|
|
13
|
+
FROM certified_records AS certified
|
|
14
|
+
JOIN staged_records AS staged
|
|
15
|
+
ON staged.conversation_id = certified.conversation_id
|
|
16
|
+
AND staged.record_hash = certified.record_hash
|
|
17
|
+
WHERE certified.conversation_id = ? AND certified.ordinal > ?
|
|
18
|
+
ORDER BY certified.ordinal
|
|
19
|
+
`;
|
|
20
|
+
/**
|
|
21
|
+
* Lists locally certified conversation identifiers in canonical order.
|
|
22
|
+
*
|
|
23
|
+
* @param database Exclusively owned endpoint database.
|
|
24
|
+
* @param input Optional exclusive canonical lower bound.
|
|
25
|
+
* @returns At most fifty identifiers and whether more remain.
|
|
26
|
+
*/
|
|
27
|
+
export function searchStoredConversations(database, input) {
|
|
28
|
+
const rows = readConversationIdRows(database, input.afterConversationId);
|
|
29
|
+
const conversationIds = rows
|
|
30
|
+
.slice(0, HISTORY_PAGE_SIZE)
|
|
31
|
+
.map((row) => readText(row, "conversation_id"));
|
|
32
|
+
return Object.freeze({
|
|
33
|
+
conversationIds: Object.freeze(conversationIds),
|
|
34
|
+
hasMore: rows.length > HISTORY_PAGE_SIZE,
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Reads or continues one process-local frozen certified-history snapshot.
|
|
39
|
+
*
|
|
40
|
+
* @param state Acquired database and process-local snapshots.
|
|
41
|
+
* @param request New read anchor or opaque continuation.
|
|
42
|
+
* @returns At most fifty complete contiguous records.
|
|
43
|
+
*/
|
|
44
|
+
export function readStoredConversation(state, request) {
|
|
45
|
+
return "continuation" in request
|
|
46
|
+
? continueConversation(state, request.continuation)
|
|
47
|
+
: beginConversationRead(state, request);
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Releases one live continuation without changing durable state.
|
|
51
|
+
*
|
|
52
|
+
* @param state Acquired database and process-local snapshots.
|
|
53
|
+
* @param continuation Opaque process-local continuation to invalidate.
|
|
54
|
+
*/
|
|
55
|
+
export function releaseStoredContinuation(state, continuation) {
|
|
56
|
+
validateContinuation(continuation);
|
|
57
|
+
if (!state.snapshots.delete(continuation)) {
|
|
58
|
+
throw new StoreSignal("invalid-continuation");
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Recovers all durable endpoint state needed to resume protocol work.
|
|
63
|
+
*
|
|
64
|
+
* @param database Exclusively owned endpoint database.
|
|
65
|
+
* @returns A detached snapshot of all durable endpoint protocol state.
|
|
66
|
+
*/
|
|
67
|
+
export function recoverStoredState(database) {
|
|
68
|
+
const identity = readStoredIdentity(database);
|
|
69
|
+
return Object.freeze({
|
|
70
|
+
...(identity === undefined ? {} : { identity }),
|
|
71
|
+
postIntents: readPostIntents(database),
|
|
72
|
+
memberships: readMemberships(database),
|
|
73
|
+
anchors: readAnchors(database),
|
|
74
|
+
positions: Object.freeze(database
|
|
75
|
+
.prepare(`SELECT conversation_id, membership_hash, current_anchor_hash,
|
|
76
|
+
head_record_hash FROM conversation_state
|
|
77
|
+
ORDER BY conversation_id`)
|
|
78
|
+
.all()
|
|
79
|
+
.map(readConversationPosition)),
|
|
80
|
+
proposalLocks: Object.freeze(database
|
|
81
|
+
.prepare(`SELECT conversation_id, previous_record_hash, action_hash,
|
|
82
|
+
canonical_action_core
|
|
83
|
+
FROM proposal_locks ORDER BY conversation_id, predecessor_key`)
|
|
84
|
+
.all()
|
|
85
|
+
.map(readProposalLock)),
|
|
86
|
+
stagedRecords: Object.freeze(database
|
|
87
|
+
.prepare(`SELECT conversation_id, record_hash, previous_record_hash,
|
|
88
|
+
membership_hash, anchor_hash, action_hash, author_agent_id,
|
|
89
|
+
post_id, canonical_record_core
|
|
90
|
+
FROM staged_records ORDER BY conversation_id, rowid`)
|
|
91
|
+
.all()
|
|
92
|
+
.map(readStagedRecord)),
|
|
93
|
+
evidence: readEvidence(database),
|
|
94
|
+
certifiedRecords: readAllCertifiedRecords(database),
|
|
95
|
+
stagedReanchors: readReanchors(database),
|
|
96
|
+
pendingDeliveries: readRetainedDeliveries(database),
|
|
97
|
+
disseminationObligations: readPendingDissemination(database),
|
|
98
|
+
outboundMessages: readPendingOutbound(database),
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
function readConversationIdRows(database, afterConversationId) {
|
|
102
|
+
if (afterConversationId === undefined) {
|
|
103
|
+
return database
|
|
104
|
+
.prepare(`SELECT conversation_id FROM conversation_state
|
|
105
|
+
WHERE head_record_hash IS NOT NULL
|
|
106
|
+
ORDER BY conversation_id COLLATE BINARY LIMIT 51`)
|
|
107
|
+
.all();
|
|
108
|
+
}
|
|
109
|
+
if (afterConversationId.length === 0 ||
|
|
110
|
+
afterConversationId.includes("\u0000")) {
|
|
111
|
+
throw new StoreSignal("invalid-input");
|
|
112
|
+
}
|
|
113
|
+
return database
|
|
114
|
+
.prepare(`SELECT conversation_id FROM conversation_state
|
|
115
|
+
WHERE head_record_hash IS NOT NULL AND conversation_id > ?
|
|
116
|
+
ORDER BY conversation_id COLLATE BINARY LIMIT 51`)
|
|
117
|
+
.all(afterConversationId);
|
|
118
|
+
}
|
|
119
|
+
function beginConversationRead(state, request) {
|
|
120
|
+
const afterOrdinal = resolveAfterOrdinal(state.database, request);
|
|
121
|
+
const rows = state.database
|
|
122
|
+
.prepare(historyQuery)
|
|
123
|
+
.all(request.conversationId, afterOrdinal);
|
|
124
|
+
if (rows.length === 0 && afterOrdinal === -1) {
|
|
125
|
+
throw new StoreSignal("not-found");
|
|
126
|
+
}
|
|
127
|
+
const records = Object.freeze(rows.map((row) => readCertifiedRecord(state.database, row)));
|
|
128
|
+
return pageFromSnapshot(state, { records, offset: 0 });
|
|
129
|
+
}
|
|
130
|
+
function resolveAfterOrdinal(database, request) {
|
|
131
|
+
if (request.conversationId.length === 0) {
|
|
132
|
+
throw new StoreSignal("invalid-input");
|
|
133
|
+
}
|
|
134
|
+
if (request.afterRecordHash === undefined) {
|
|
135
|
+
return -1;
|
|
136
|
+
}
|
|
137
|
+
const anchor = database
|
|
138
|
+
.prepare(`SELECT ordinal FROM certified_records
|
|
139
|
+
WHERE conversation_id = ? AND record_hash = ?`)
|
|
140
|
+
.get(request.conversationId, request.afterRecordHash);
|
|
141
|
+
if (anchor === undefined) {
|
|
142
|
+
throw new StoreSignal("not-found");
|
|
143
|
+
}
|
|
144
|
+
return readInteger(anchor, "ordinal");
|
|
145
|
+
}
|
|
146
|
+
function continueConversation(state, continuation) {
|
|
147
|
+
validateContinuation(continuation);
|
|
148
|
+
const snapshot = state.snapshots.get(continuation);
|
|
149
|
+
if (snapshot === undefined) {
|
|
150
|
+
throw new StoreSignal("invalid-continuation");
|
|
151
|
+
}
|
|
152
|
+
state.snapshots.delete(continuation);
|
|
153
|
+
return pageFromSnapshot(state, snapshot);
|
|
154
|
+
}
|
|
155
|
+
function pageFromSnapshot(state, snapshot) {
|
|
156
|
+
const records = snapshot.records.slice(snapshot.offset, snapshot.offset + HISTORY_PAGE_SIZE);
|
|
157
|
+
const nextOffset = snapshot.offset + records.length;
|
|
158
|
+
const continuation = retainNextPage(state, snapshot.records, nextOffset);
|
|
159
|
+
return Object.freeze({
|
|
160
|
+
records: Object.freeze(records.map(copyCertifiedRecord)),
|
|
161
|
+
continuation,
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
function retainNextPage(state, records, nextOffset) {
|
|
165
|
+
if (nextOffset >= records.length) {
|
|
166
|
+
return null;
|
|
167
|
+
}
|
|
168
|
+
const continuation = mintContinuation(new Set(state.snapshots.keys()));
|
|
169
|
+
state.snapshots.set(continuation, Object.freeze({ records, offset: nextOffset }));
|
|
170
|
+
return continuation;
|
|
171
|
+
}
|
|
172
|
+
function copyCertifiedRecord(record) {
|
|
173
|
+
return Object.freeze({
|
|
174
|
+
...record,
|
|
175
|
+
canonicalRecordCore: copyBytes(record.canonicalRecordCore),
|
|
176
|
+
actionEvidence: copyEvidence(record.actionEvidence),
|
|
177
|
+
durabilityEvidence: copyEvidence(record.durabilityEvidence),
|
|
178
|
+
});
|
|
179
|
+
}
|
|
180
|
+
function copyEvidence(evidenceItems) {
|
|
181
|
+
return Object.freeze(evidenceItems.map((evidence) => Object.freeze({
|
|
182
|
+
...evidence,
|
|
183
|
+
canonicalEvidence: copyBytes(evidence.canonicalEvidence),
|
|
184
|
+
})));
|
|
185
|
+
}
|
|
186
|
+
function readPostIntents(database) {
|
|
187
|
+
return Object.freeze(database
|
|
188
|
+
.prepare(`SELECT conversation_id, membership_hash, author_agent_id, post_id,
|
|
189
|
+
canonical_intent, completed_record_hash
|
|
190
|
+
FROM post_intents ORDER BY author_agent_id, post_id`)
|
|
191
|
+
.all()
|
|
192
|
+
.map((row) => {
|
|
193
|
+
const completedRecordHash = readOptionalText(row, "completed_record_hash");
|
|
194
|
+
return Object.freeze({
|
|
195
|
+
conversationId: readText(row, "conversation_id"),
|
|
196
|
+
membershipHash: readText(row, "membership_hash"),
|
|
197
|
+
authorAgentId: readText(row, "author_agent_id"),
|
|
198
|
+
postId: readText(row, "post_id"),
|
|
199
|
+
canonicalIntent: readBytes(row, "canonical_intent"),
|
|
200
|
+
...(completedRecordHash === undefined ? {} : { completedRecordHash }),
|
|
201
|
+
});
|
|
202
|
+
}));
|
|
203
|
+
}
|
|
204
|
+
function readMemberships(database) {
|
|
205
|
+
return Object.freeze(database
|
|
206
|
+
.prepare(`SELECT conversation_id, membership_hash, canonical_membership
|
|
207
|
+
FROM memberships ORDER BY conversation_id`)
|
|
208
|
+
.all()
|
|
209
|
+
.map((row) => Object.freeze({
|
|
210
|
+
conversationId: readText(row, "conversation_id"),
|
|
211
|
+
membershipHash: readText(row, "membership_hash"),
|
|
212
|
+
canonicalMembership: readBytes(row, "canonical_membership"),
|
|
213
|
+
})));
|
|
214
|
+
}
|
|
215
|
+
function readAnchors(database) {
|
|
216
|
+
return Object.freeze(database
|
|
217
|
+
.prepare(`SELECT conversation_id, anchor_hash, previous_anchor_hash,
|
|
218
|
+
selected_record_hash, canonical_anchor
|
|
219
|
+
FROM anchors ORDER BY conversation_id, rowid`)
|
|
220
|
+
.all()
|
|
221
|
+
.map((row) => {
|
|
222
|
+
const previousAnchorHash = readOptionalText(row, "previous_anchor_hash");
|
|
223
|
+
const selectedRecordHash = readOptionalText(row, "selected_record_hash");
|
|
224
|
+
return Object.freeze({
|
|
225
|
+
conversationId: readText(row, "conversation_id"),
|
|
226
|
+
anchorHash: readText(row, "anchor_hash"),
|
|
227
|
+
...(previousAnchorHash === undefined ? {} : { previousAnchorHash }),
|
|
228
|
+
...(selectedRecordHash === undefined ? {} : { selectedRecordHash }),
|
|
229
|
+
canonicalAnchor: readBytes(row, "canonical_anchor"),
|
|
230
|
+
});
|
|
231
|
+
}));
|
|
232
|
+
}
|
|
233
|
+
function readEvidence(database) {
|
|
234
|
+
return Object.freeze(database
|
|
235
|
+
.prepare(`SELECT conversation_id, evidence_kind, subject_id,
|
|
236
|
+
evidence_key, canonical_evidence
|
|
237
|
+
FROM protocol_evidence
|
|
238
|
+
ORDER BY conversation_id, evidence_kind, subject_id, evidence_key`)
|
|
239
|
+
.all()
|
|
240
|
+
.map(readProtocolEvidence));
|
|
241
|
+
}
|
|
242
|
+
function readAllCertifiedRecords(database) {
|
|
243
|
+
return Object.freeze(database
|
|
244
|
+
.prepare(historyQuery
|
|
245
|
+
.replace("WHERE certified.conversation_id = ? AND certified.ordinal > ?", "")
|
|
246
|
+
.replace("ORDER BY certified.ordinal", "ORDER BY certified.conversation_id, certified.ordinal"))
|
|
247
|
+
.all()
|
|
248
|
+
.map((row) => readCertifiedRecord(database, row)));
|
|
249
|
+
}
|
|
250
|
+
function readReanchors(database) {
|
|
251
|
+
return Object.freeze(database
|
|
252
|
+
.prepare(`SELECT conversation_id, anchor_hash, previous_anchor_hash,
|
|
253
|
+
router_instance_id, selected_record_hash, canonical_body,
|
|
254
|
+
canonical_completed_reanchor
|
|
255
|
+
FROM reanchors ORDER BY conversation_id, rowid`)
|
|
256
|
+
.all()
|
|
257
|
+
.map(readRecoveredReanchor));
|
|
258
|
+
}
|
|
259
|
+
//# sourceMappingURL=management.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"management.js","sourceRoot":"","sources":["../../../src/endpoint/store/management.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/** @file Durable exact-envelope ownership across Router retries and restart. */
|
|
2
|
+
import type { DatabaseSync } from "node:sqlite";
|
|
3
|
+
import type { OutboundAttempt, OutboundMessageInput, StoredOutboundMessage, StoreMutation } from "./types.js";
|
|
4
|
+
/**
|
|
5
|
+
* Stages one complete outer envelope before it can reach Router transport.
|
|
6
|
+
*
|
|
7
|
+
* The initial MessageId remains the durable handle even when Router retry
|
|
8
|
+
* identity loss requires a replacement outer envelope.
|
|
9
|
+
*
|
|
10
|
+
* @param database Exclusively owned endpoint database.
|
|
11
|
+
* @param message Canonical complete initial outer message.
|
|
12
|
+
* @returns The retained current envelope under its stable initial identity.
|
|
13
|
+
*/
|
|
14
|
+
export declare function enqueueOutbound(database: DatabaseSync, message: OutboundMessageInput): StoredOutboundMessage;
|
|
15
|
+
/**
|
|
16
|
+
* Retains one validated envelope inside a caller-owned SQLite transaction.
|
|
17
|
+
* @param database Exclusively owned endpoint database.
|
|
18
|
+
* @param message Canonical complete initial outer message.
|
|
19
|
+
* @returns The retained current envelope under its stable initial identity.
|
|
20
|
+
*/
|
|
21
|
+
export declare function enqueueOutboundInTransaction(database: DatabaseSync, message: OutboundMessageInput): StoredOutboundMessage;
|
|
22
|
+
/**
|
|
23
|
+
* Selects the exact durable envelope and retry mode for one Router attempt.
|
|
24
|
+
*
|
|
25
|
+
* @param database Exclusively owned endpoint database.
|
|
26
|
+
* @param outboundId Stable identity of the initial outer envelope.
|
|
27
|
+
* @returns The current stored bytes, or an inactive terminal disposition.
|
|
28
|
+
*/
|
|
29
|
+
export declare function beginOutbound(database: DatabaseSync, outboundId: string): OutboundAttempt;
|
|
30
|
+
/**
|
|
31
|
+
* Atomically replaces only one expected current outer envelope.
|
|
32
|
+
*
|
|
33
|
+
* @param database Exclusively owned endpoint database.
|
|
34
|
+
* @param current Exact durable envelope that Router no longer recognizes.
|
|
35
|
+
* @param replacement Fresh outer identity over the byte-identical body.
|
|
36
|
+
* @returns The durable replacement under the unchanged outbox identity.
|
|
37
|
+
*/
|
|
38
|
+
export declare function replaceOutbound(database: DatabaseSync, current: StoredOutboundMessage, replacement: OutboundMessageInput): StoredOutboundMessage;
|
|
39
|
+
/**
|
|
40
|
+
* Marks one exact current envelope complete after Router accepts its bytes.
|
|
41
|
+
*
|
|
42
|
+
* @param database Exclusively owned endpoint database.
|
|
43
|
+
* @param outbound Exact envelope whose Router digest was verified.
|
|
44
|
+
* @returns Whether this call recorded acceptance or observed it already.
|
|
45
|
+
*/
|
|
46
|
+
export declare function completeOutbound(database: DatabaseSync, outbound: StoredOutboundMessage): StoreMutation;
|
|
47
|
+
/**
|
|
48
|
+
* Atomically invalidates exact pending envelopes before protocol regeneration.
|
|
49
|
+
*
|
|
50
|
+
* @param database Exclusively owned endpoint database.
|
|
51
|
+
* @param outbounds Complete expected-current envelopes to invalidate.
|
|
52
|
+
* @returns Whether at least one pending envelope became inactive.
|
|
53
|
+
*/
|
|
54
|
+
export declare function discardOutbound(database: DatabaseSync, outbounds: readonly StoredOutboundMessage[]): StoreMutation;
|
|
55
|
+
/**
|
|
56
|
+
* Reads every pending current envelope in durable insertion order.
|
|
57
|
+
*
|
|
58
|
+
* @param database Exclusively owned endpoint database.
|
|
59
|
+
* @returns Detached pending envelopes, excluding accepted and discarded rows.
|
|
60
|
+
*/
|
|
61
|
+
export declare function readPendingOutbound(database: DatabaseSync): readonly StoredOutboundMessage[];
|
|
62
|
+
//# sourceMappingURL=outbound.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"outbound.d.ts","sourceRoot":"","sources":["../../../src/endpoint/store/outbound.ts"],"names":[],"mappings":"AAAA,gFAAgF;AAEhF,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,KAAK,EACV,eAAe,EACf,oBAAoB,EACpB,qBAAqB,EACrB,aAAa,EACd,MAAM,YAAY,CAAC;AAuBpB;;;;;;;;;GASG;AACH,wBAAgB,eAAe,CAC7B,QAAQ,EAAE,YAAY,EACtB,OAAO,EAAE,oBAAoB,GAC5B,qBAAqB,CAKvB;AAED;;;;;GAKG;AACH,wBAAgB,4BAA4B,CAC1C,QAAQ,EAAE,YAAY,EACtB,OAAO,EAAE,oBAAoB,GAC5B,qBAAqB,CAgCvB;AAED;;;;;;GAMG;AACH,wBAAgB,aAAa,CAC3B,QAAQ,EAAE,YAAY,EACtB,UAAU,EAAE,MAAM,GACjB,eAAe,CAsBjB;AAED;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAC7B,QAAQ,EAAE,YAAY,EACtB,OAAO,EAAE,qBAAqB,EAC9B,WAAW,EAAE,oBAAoB,GAChC,qBAAqB,CA6BvB;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAC9B,QAAQ,EAAE,YAAY,EACtB,QAAQ,EAAE,qBAAqB,GAC9B,aAAa,CAwBf;AAED;;;;;;GAMG;AACH,wBAAgB,eAAe,CAC7B,QAAQ,EAAE,YAAY,EACtB,SAAS,EAAE,SAAS,qBAAqB,EAAE,GAC1C,aAAa,CAuCf;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,YAAY,GACrB,SAAS,qBAAqB,EAAE,CAalC"}
|
|
@@ -0,0 +1,278 @@
|
|
|
1
|
+
/** @file Durable exact-envelope ownership across Router retries and restart. */
|
|
2
|
+
import { copyBytes, readBytes, readInteger, readText, requireBytes, requireEqual, requireSameBytes, requireText, StoreSignal, transaction, } from "./database/index.js";
|
|
3
|
+
/**
|
|
4
|
+
* Stages one complete outer envelope before it can reach Router transport.
|
|
5
|
+
*
|
|
6
|
+
* The initial MessageId remains the durable handle even when Router retry
|
|
7
|
+
* identity loss requires a replacement outer envelope.
|
|
8
|
+
*
|
|
9
|
+
* @param database Exclusively owned endpoint database.
|
|
10
|
+
* @param message Canonical complete initial outer message.
|
|
11
|
+
* @returns The retained current envelope under its stable initial identity.
|
|
12
|
+
*/
|
|
13
|
+
export function enqueueOutbound(database, message) {
|
|
14
|
+
validateMessageInput(message);
|
|
15
|
+
return transaction(database, () => enqueueOutboundInTransaction(database, message));
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Retains one validated envelope inside a caller-owned SQLite transaction.
|
|
19
|
+
* @param database Exclusively owned endpoint database.
|
|
20
|
+
* @param message Canonical complete initial outer message.
|
|
21
|
+
* @returns The retained current envelope under its stable initial identity.
|
|
22
|
+
*/
|
|
23
|
+
export function enqueueOutboundInTransaction(database, message) {
|
|
24
|
+
validateMessageInput(message);
|
|
25
|
+
requireConversation(database, message.conversationId);
|
|
26
|
+
const existing = findOutbound(database, message.messageId);
|
|
27
|
+
if (existing !== undefined) {
|
|
28
|
+
requireEqual(existing.outbound.conversationId, message.conversationId);
|
|
29
|
+
requireSameBytes(existing.initialCanonicalSignedMessage, message.canonicalSignedMessage);
|
|
30
|
+
return copyOutbound(existing.outbound);
|
|
31
|
+
}
|
|
32
|
+
requireMessageIdAvailable(database, message.messageId);
|
|
33
|
+
database
|
|
34
|
+
.prepare(`INSERT INTO outbound_messages
|
|
35
|
+
(outbound_id, conversation_id, current_message_id,
|
|
36
|
+
canonical_initial_signed_message,
|
|
37
|
+
canonical_current_signed_message, attempted, disposition)
|
|
38
|
+
VALUES (?, ?, ?, ?, ?, 0, 'pending')`)
|
|
39
|
+
.run(message.messageId, message.conversationId, message.messageId, copyBytes(message.canonicalSignedMessage), copyBytes(message.canonicalSignedMessage));
|
|
40
|
+
return copyOutbound({
|
|
41
|
+
outboundId: message.messageId,
|
|
42
|
+
...message,
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Selects the exact durable envelope and retry mode for one Router attempt.
|
|
47
|
+
*
|
|
48
|
+
* @param database Exclusively owned endpoint database.
|
|
49
|
+
* @param outboundId Stable identity of the initial outer envelope.
|
|
50
|
+
* @returns The current stored bytes, or an inactive terminal disposition.
|
|
51
|
+
*/
|
|
52
|
+
export function beginOutbound(database, outboundId) {
|
|
53
|
+
requireText(outboundId);
|
|
54
|
+
return transaction(database, () => {
|
|
55
|
+
const retained = requireOutbound(database, outboundId);
|
|
56
|
+
if (retained.disposition !== "pending") {
|
|
57
|
+
return Object.freeze({ kind: "inactive" });
|
|
58
|
+
}
|
|
59
|
+
const mode = retained.attempted ? "retry" : "initial";
|
|
60
|
+
if (!retained.attempted) {
|
|
61
|
+
database
|
|
62
|
+
.prepare(`UPDATE outbound_messages SET attempted = 1
|
|
63
|
+
WHERE outbound_id = ? AND disposition = 'pending'`)
|
|
64
|
+
.run(outboundId);
|
|
65
|
+
}
|
|
66
|
+
return Object.freeze({
|
|
67
|
+
kind: "pending",
|
|
68
|
+
mode,
|
|
69
|
+
outbound: copyOutbound(retained.outbound),
|
|
70
|
+
});
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Atomically replaces only one expected current outer envelope.
|
|
75
|
+
*
|
|
76
|
+
* @param database Exclusively owned endpoint database.
|
|
77
|
+
* @param current Exact durable envelope that Router no longer recognizes.
|
|
78
|
+
* @param replacement Fresh outer identity over the byte-identical body.
|
|
79
|
+
* @returns The durable replacement under the unchanged outbox identity.
|
|
80
|
+
*/
|
|
81
|
+
export function replaceOutbound(database, current, replacement) {
|
|
82
|
+
validateStoredOutbound(current);
|
|
83
|
+
validateMessageInput(replacement);
|
|
84
|
+
requireEqual(current.conversationId, replacement.conversationId);
|
|
85
|
+
if (current.messageId === replacement.messageId) {
|
|
86
|
+
throw new StoreSignal("invalid-input");
|
|
87
|
+
}
|
|
88
|
+
return transaction(database, () => {
|
|
89
|
+
const retained = requireOutbound(database, current.outboundId);
|
|
90
|
+
requirePending(retained);
|
|
91
|
+
requireSameOutbound(retained.outbound, current);
|
|
92
|
+
requireMessageIdAvailable(database, replacement.messageId);
|
|
93
|
+
database
|
|
94
|
+
.prepare(`UPDATE outbound_messages
|
|
95
|
+
SET current_message_id = ?, canonical_current_signed_message = ?,
|
|
96
|
+
attempted = 0
|
|
97
|
+
WHERE outbound_id = ? AND disposition = 'pending'`)
|
|
98
|
+
.run(replacement.messageId, copyBytes(replacement.canonicalSignedMessage), current.outboundId);
|
|
99
|
+
return copyOutbound({
|
|
100
|
+
outboundId: current.outboundId,
|
|
101
|
+
...replacement,
|
|
102
|
+
});
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Marks one exact current envelope complete after Router accepts its bytes.
|
|
107
|
+
*
|
|
108
|
+
* @param database Exclusively owned endpoint database.
|
|
109
|
+
* @param outbound Exact envelope whose Router digest was verified.
|
|
110
|
+
* @returns Whether this call recorded acceptance or observed it already.
|
|
111
|
+
*/
|
|
112
|
+
export function completeOutbound(database, outbound) {
|
|
113
|
+
validateStoredOutbound(outbound);
|
|
114
|
+
return transaction(database, () => {
|
|
115
|
+
const retained = requireOutbound(database, outbound.outboundId);
|
|
116
|
+
requireSameOutbound(retained.outbound, outbound);
|
|
117
|
+
switch (retained.disposition) {
|
|
118
|
+
case "accepted":
|
|
119
|
+
return "existing";
|
|
120
|
+
case "discarded":
|
|
121
|
+
throw new StoreSignal("conflict");
|
|
122
|
+
case "pending":
|
|
123
|
+
database
|
|
124
|
+
.prepare(`UPDATE outbound_messages SET disposition = 'accepted'
|
|
125
|
+
WHERE outbound_id = ? AND disposition = 'pending'`)
|
|
126
|
+
.run(outbound.outboundId);
|
|
127
|
+
return "inserted";
|
|
128
|
+
default: {
|
|
129
|
+
const exhaustive = retained.disposition;
|
|
130
|
+
return exhaustive;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Atomically invalidates exact pending envelopes before protocol regeneration.
|
|
137
|
+
*
|
|
138
|
+
* @param database Exclusively owned endpoint database.
|
|
139
|
+
* @param outbounds Complete expected-current envelopes to invalidate.
|
|
140
|
+
* @returns Whether at least one pending envelope became inactive.
|
|
141
|
+
*/
|
|
142
|
+
export function discardOutbound(database, outbounds) {
|
|
143
|
+
const distinctIds = new Set();
|
|
144
|
+
for (const outbound of outbounds) {
|
|
145
|
+
validateStoredOutbound(outbound);
|
|
146
|
+
if (distinctIds.has(outbound.outboundId)) {
|
|
147
|
+
throw new StoreSignal("invalid-input");
|
|
148
|
+
}
|
|
149
|
+
distinctIds.add(outbound.outboundId);
|
|
150
|
+
}
|
|
151
|
+
return transaction(database, () => {
|
|
152
|
+
const retained = outbounds.map((outbound) => {
|
|
153
|
+
const row = requireOutbound(database, outbound.outboundId);
|
|
154
|
+
requireSameOutbound(row.outbound, outbound);
|
|
155
|
+
if (row.disposition === "accepted") {
|
|
156
|
+
throw new StoreSignal("conflict");
|
|
157
|
+
}
|
|
158
|
+
return row;
|
|
159
|
+
});
|
|
160
|
+
const inserted = retained.some((outbound) => outbound.disposition === "pending");
|
|
161
|
+
for (const outbound of retained) {
|
|
162
|
+
if (outbound.disposition === "pending") {
|
|
163
|
+
database
|
|
164
|
+
.prepare(`UPDATE dissemination_obligations SET outbound_id = NULL
|
|
165
|
+
WHERE outbound_id = ?`)
|
|
166
|
+
.run(outbound.outbound.outboundId);
|
|
167
|
+
database
|
|
168
|
+
.prepare(`UPDATE outbound_messages SET disposition = 'discarded'
|
|
169
|
+
WHERE outbound_id = ? AND disposition = 'pending'`)
|
|
170
|
+
.run(outbound.outbound.outboundId);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
return inserted ? "inserted" : "existing";
|
|
174
|
+
});
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* Reads every pending current envelope in durable insertion order.
|
|
178
|
+
*
|
|
179
|
+
* @param database Exclusively owned endpoint database.
|
|
180
|
+
* @returns Detached pending envelopes, excluding accepted and discarded rows.
|
|
181
|
+
*/
|
|
182
|
+
export function readPendingOutbound(database) {
|
|
183
|
+
return Object.freeze(database
|
|
184
|
+
.prepare(`SELECT outbound_id, conversation_id, current_message_id,
|
|
185
|
+
canonical_initial_signed_message,
|
|
186
|
+
canonical_current_signed_message, attempted, disposition
|
|
187
|
+
FROM outbound_messages WHERE disposition = 'pending'
|
|
188
|
+
ORDER BY outbound_sequence`)
|
|
189
|
+
.all()
|
|
190
|
+
.map((row) => copyOutbound(readOutbound(row).outbound)));
|
|
191
|
+
}
|
|
192
|
+
function requireOutbound(database, outboundId) {
|
|
193
|
+
const retained = findOutbound(database, outboundId);
|
|
194
|
+
if (retained === undefined) {
|
|
195
|
+
throw new StoreSignal("not-found");
|
|
196
|
+
}
|
|
197
|
+
return retained;
|
|
198
|
+
}
|
|
199
|
+
function findOutbound(database, outboundId) {
|
|
200
|
+
const row = database
|
|
201
|
+
.prepare(`SELECT outbound_id, conversation_id, current_message_id,
|
|
202
|
+
canonical_initial_signed_message,
|
|
203
|
+
canonical_current_signed_message, attempted, disposition
|
|
204
|
+
FROM outbound_messages WHERE outbound_id = ?`)
|
|
205
|
+
.get(outboundId);
|
|
206
|
+
return row === undefined ? undefined : readOutbound(row);
|
|
207
|
+
}
|
|
208
|
+
function readOutbound(row) {
|
|
209
|
+
const attempted = readInteger(row, "attempted");
|
|
210
|
+
if (attempted !== 0 && attempted !== 1) {
|
|
211
|
+
throw new StoreSignal("corrupt");
|
|
212
|
+
}
|
|
213
|
+
return Object.freeze({
|
|
214
|
+
outbound: Object.freeze({
|
|
215
|
+
outboundId: readText(row, "outbound_id"),
|
|
216
|
+
conversationId: readText(row, "conversation_id"),
|
|
217
|
+
messageId: readText(row, "current_message_id"),
|
|
218
|
+
canonicalSignedMessage: readBytes(row, "canonical_current_signed_message"),
|
|
219
|
+
}),
|
|
220
|
+
initialCanonicalSignedMessage: readBytes(row, "canonical_initial_signed_message"),
|
|
221
|
+
attempted: attempted === 1,
|
|
222
|
+
disposition: readDisposition(row),
|
|
223
|
+
});
|
|
224
|
+
}
|
|
225
|
+
function readDisposition(row) {
|
|
226
|
+
const disposition = readText(row, "disposition");
|
|
227
|
+
switch (disposition) {
|
|
228
|
+
case "accepted":
|
|
229
|
+
case "discarded":
|
|
230
|
+
case "pending":
|
|
231
|
+
return disposition;
|
|
232
|
+
default:
|
|
233
|
+
throw new StoreSignal("corrupt");
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
function requireConversation(database, conversationId) {
|
|
237
|
+
if (database
|
|
238
|
+
.prepare(`SELECT 1 AS retained FROM conversation_state
|
|
239
|
+
WHERE conversation_id = ?`)
|
|
240
|
+
.get(conversationId) === undefined) {
|
|
241
|
+
throw new StoreSignal("not-found");
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
function requireMessageIdAvailable(database, messageId) {
|
|
245
|
+
if (database
|
|
246
|
+
.prepare(`SELECT 1 AS retained FROM outbound_messages
|
|
247
|
+
WHERE outbound_id = ? OR current_message_id = ? LIMIT 1`)
|
|
248
|
+
.get(messageId, messageId) !== undefined) {
|
|
249
|
+
throw new StoreSignal("conflict");
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
function requirePending(retained) {
|
|
253
|
+
if (retained.disposition !== "pending") {
|
|
254
|
+
throw new StoreSignal("conflict");
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
function validateStoredOutbound(outbound) {
|
|
258
|
+
requireText(outbound.outboundId);
|
|
259
|
+
validateMessageInput(outbound);
|
|
260
|
+
}
|
|
261
|
+
function validateMessageInput(message) {
|
|
262
|
+
requireText(message.conversationId);
|
|
263
|
+
requireText(message.messageId);
|
|
264
|
+
requireBytes(message.canonicalSignedMessage);
|
|
265
|
+
}
|
|
266
|
+
function requireSameOutbound(left, right) {
|
|
267
|
+
requireEqual(left.outboundId, right.outboundId);
|
|
268
|
+
requireEqual(left.conversationId, right.conversationId);
|
|
269
|
+
requireEqual(left.messageId, right.messageId);
|
|
270
|
+
requireSameBytes(left.canonicalSignedMessage, right.canonicalSignedMessage);
|
|
271
|
+
}
|
|
272
|
+
function copyOutbound(outbound) {
|
|
273
|
+
return Object.freeze({
|
|
274
|
+
...outbound,
|
|
275
|
+
canonicalSignedMessage: copyBytes(outbound.canonicalSignedMessage),
|
|
276
|
+
});
|
|
277
|
+
}
|
|
278
|
+
//# sourceMappingURL=outbound.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"outbound.js","sourceRoot":"","sources":["../../../src/endpoint/store/outbound.ts"],"names":[],"mappings":"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"}
|