@optimystic/db-p2p 0.13.4 → 0.14.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/README.md +6 -6
- package/dist/src/cluster/block-transfer-service.d.ts +67 -8
- package/dist/src/cluster/block-transfer-service.d.ts.map +1 -1
- package/dist/src/cluster/block-transfer-service.js +101 -62
- package/dist/src/cluster/block-transfer-service.js.map +1 -1
- package/dist/src/cluster/client.d.ts +18 -1
- package/dist/src/cluster/client.d.ts.map +1 -1
- package/dist/src/cluster/client.js +55 -39
- package/dist/src/cluster/client.js.map +1 -1
- package/dist/src/cluster/cluster-error.d.ts +38 -0
- package/dist/src/cluster/cluster-error.d.ts.map +1 -0
- package/dist/src/cluster/cluster-error.js +51 -0
- package/dist/src/cluster/cluster-error.js.map +1 -0
- package/dist/src/cluster/cluster-repo.d.ts +135 -3
- package/dist/src/cluster/cluster-repo.d.ts.map +1 -1
- package/dist/src/cluster/cluster-repo.js +333 -58
- package/dist/src/cluster/cluster-repo.js.map +1 -1
- package/dist/src/cluster/commit-cert.d.ts +63 -0
- package/dist/src/cluster/commit-cert.d.ts.map +1 -0
- package/dist/src/cluster/commit-cert.js +108 -0
- package/dist/src/cluster/commit-cert.js.map +1 -0
- package/dist/src/cluster/service.d.ts +46 -11
- package/dist/src/cluster/service.d.ts.map +1 -1
- package/dist/src/cluster/service.js +97 -33
- package/dist/src/cluster/service.js.map +1 -1
- package/dist/src/cluster/spread-on-churn.d.ts +13 -0
- package/dist/src/cluster/spread-on-churn.d.ts.map +1 -1
- package/dist/src/cluster/spread-on-churn.js +34 -4
- package/dist/src/cluster/spread-on-churn.js.map +1 -1
- package/dist/src/cohort-topic/bootstrap-evidence-builder.d.ts +59 -0
- package/dist/src/cohort-topic/bootstrap-evidence-builder.d.ts.map +1 -0
- package/dist/src/cohort-topic/bootstrap-evidence-builder.js +79 -0
- package/dist/src/cohort-topic/bootstrap-evidence-builder.js.map +1 -0
- package/dist/src/cohort-topic/bootstrap-evidence-verifiers.d.ts +81 -0
- package/dist/src/cohort-topic/bootstrap-evidence-verifiers.d.ts.map +1 -0
- package/dist/src/cohort-topic/bootstrap-evidence-verifiers.js +93 -0
- package/dist/src/cohort-topic/bootstrap-evidence-verifiers.js.map +1 -0
- package/dist/src/cohort-topic/bootstrap-parent-reference.d.ts +108 -0
- package/dist/src/cohort-topic/bootstrap-parent-reference.d.ts.map +1 -0
- package/dist/src/cohort-topic/bootstrap-parent-reference.js +108 -0
- package/dist/src/cohort-topic/bootstrap-parent-reference.js.map +1 -0
- package/dist/src/cohort-topic/change-bridge.d.ts +65 -0
- package/dist/src/cohort-topic/change-bridge.d.ts.map +1 -0
- package/dist/src/cohort-topic/change-bridge.js +76 -0
- package/dist/src/cohort-topic/change-bridge.js.map +1 -0
- package/dist/src/cohort-topic/cohort-gossip-driver.d.ts +74 -0
- package/dist/src/cohort-topic/cohort-gossip-driver.d.ts.map +1 -0
- package/dist/src/cohort-topic/cohort-gossip-driver.js +87 -0
- package/dist/src/cohort-topic/cohort-gossip-driver.js.map +1 -0
- package/dist/src/cohort-topic/cohort-gossip-transport.d.ts +42 -0
- package/dist/src/cohort-topic/cohort-gossip-transport.d.ts.map +1 -0
- package/dist/src/cohort-topic/cohort-gossip-transport.js +57 -0
- package/dist/src/cohort-topic/cohort-gossip-transport.js.map +1 -0
- package/dist/src/cohort-topic/fret-trust-anchor.d.ts +100 -0
- package/dist/src/cohort-topic/fret-trust-anchor.d.ts.map +1 -0
- package/dist/src/cohort-topic/fret-trust-anchor.js +115 -0
- package/dist/src/cohort-topic/fret-trust-anchor.js.map +1 -0
- package/dist/src/cohort-topic/host.d.ts +573 -0
- package/dist/src/cohort-topic/host.d.ts.map +1 -0
- package/dist/src/cohort-topic/host.js +1460 -0
- package/dist/src/cohort-topic/host.js.map +1 -0
- package/dist/src/cohort-topic/index.d.ts +14 -0
- package/dist/src/cohort-topic/index.d.ts.map +1 -0
- package/dist/src/cohort-topic/index.js +14 -0
- package/dist/src/cohort-topic/index.js.map +1 -0
- package/dist/src/cohort-topic/membership-publish-sink.d.ts +14 -0
- package/dist/src/cohort-topic/membership-publish-sink.d.ts.map +1 -0
- package/dist/src/cohort-topic/membership-publish-sink.js +17 -0
- package/dist/src/cohort-topic/membership-publish-sink.js.map +1 -0
- package/dist/src/cohort-topic/membership-source.d.ts +36 -0
- package/dist/src/cohort-topic/membership-source.d.ts.map +1 -0
- package/dist/src/cohort-topic/membership-source.js +58 -0
- package/dist/src/cohort-topic/membership-source.js.map +1 -0
- package/dist/src/cohort-topic/peer-codec.d.ts +18 -0
- package/dist/src/cohort-topic/peer-codec.d.ts.map +1 -0
- package/dist/src/cohort-topic/peer-codec.js +26 -0
- package/dist/src/cohort-topic/peer-codec.js.map +1 -0
- package/dist/src/cohort-topic/peer-sig.d.ts +52 -0
- package/dist/src/cohort-topic/peer-sig.d.ts.map +1 -0
- package/dist/src/cohort-topic/peer-sig.js +83 -0
- package/dist/src/cohort-topic/peer-sig.js.map +1 -0
- package/dist/src/cohort-topic/protocols.d.ts +49 -0
- package/dist/src/cohort-topic/protocols.d.ts.map +1 -0
- package/dist/src/cohort-topic/protocols.js +58 -0
- package/dist/src/cohort-topic/protocols.js.map +1 -0
- package/dist/src/cohort-topic/reactivity-membership-gate.d.ts +49 -0
- package/dist/src/cohort-topic/reactivity-membership-gate.d.ts.map +1 -0
- package/dist/src/cohort-topic/reactivity-membership-gate.js +42 -0
- package/dist/src/cohort-topic/reactivity-membership-gate.js.map +1 -0
- package/dist/src/cohort-topic/size-estimator.d.ts +16 -0
- package/dist/src/cohort-topic/size-estimator.d.ts.map +1 -0
- package/dist/src/cohort-topic/size-estimator.js +16 -0
- package/dist/src/cohort-topic/size-estimator.js.map +1 -0
- package/dist/src/cohort-topic/stream-util.d.ts +19 -0
- package/dist/src/cohort-topic/stream-util.d.ts.map +1 -0
- package/dist/src/cohort-topic/stream-util.js +76 -0
- package/dist/src/cohort-topic/stream-util.js.map +1 -0
- package/dist/src/cohort-topic/threshold-crypto.d.ts +94 -0
- package/dist/src/cohort-topic/threshold-crypto.d.ts.map +1 -0
- package/dist/src/cohort-topic/threshold-crypto.js +178 -0
- package/dist/src/cohort-topic/threshold-crypto.js.map +1 -0
- package/dist/src/cohort-topic/topic-router.d.ts +41 -0
- package/dist/src/cohort-topic/topic-router.d.ts.map +1 -0
- package/dist/src/cohort-topic/topic-router.js +63 -0
- package/dist/src/cohort-topic/topic-router.js.map +1 -0
- package/dist/src/dispute/cascade.d.ts +179 -0
- package/dist/src/dispute/cascade.d.ts.map +1 -0
- package/dist/src/dispute/cascade.js +315 -0
- package/dist/src/dispute/cascade.js.map +1 -0
- package/dist/src/dispute/client.d.ts +2 -1
- package/dist/src/dispute/client.d.ts.map +1 -1
- package/dist/src/dispute/client.js +12 -3
- package/dist/src/dispute/client.js.map +1 -1
- package/dist/src/dispute/dispute-service.d.ts +41 -1
- package/dist/src/dispute/dispute-service.d.ts.map +1 -1
- package/dist/src/dispute/dispute-service.js +147 -21
- package/dist/src/dispute/dispute-service.js.map +1 -1
- package/dist/src/dispute/index.d.ts +2 -0
- package/dist/src/dispute/index.d.ts.map +1 -1
- package/dist/src/dispute/index.js +2 -0
- package/dist/src/dispute/index.js.map +1 -1
- package/dist/src/dispute/invalidation.d.ts +266 -0
- package/dist/src/dispute/invalidation.d.ts.map +1 -0
- package/dist/src/dispute/invalidation.js +405 -0
- package/dist/src/dispute/invalidation.js.map +1 -0
- package/dist/src/dispute/types.d.ts +14 -0
- package/dist/src/dispute/types.d.ts.map +1 -1
- package/dist/src/dispute/types.js.map +1 -1
- package/dist/src/index.d.ts +4 -0
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +4 -0
- package/dist/src/index.js.map +1 -1
- package/dist/src/libp2p-key-network.d.ts +8 -1
- package/dist/src/libp2p-key-network.d.ts.map +1 -1
- package/dist/src/libp2p-key-network.js +67 -8
- package/dist/src/libp2p-key-network.js.map +1 -1
- package/dist/src/libp2p-node-base.d.ts +57 -3
- package/dist/src/libp2p-node-base.d.ts.map +1 -1
- package/dist/src/libp2p-node-base.js +523 -6
- package/dist/src/libp2p-node-base.js.map +1 -1
- package/dist/src/matchmaking/aggregate-counts.d.ts +67 -0
- package/dist/src/matchmaking/aggregate-counts.d.ts.map +1 -0
- package/dist/src/matchmaking/aggregate-counts.js +60 -0
- package/dist/src/matchmaking/aggregate-counts.js.map +1 -0
- package/dist/src/matchmaking/index.d.ts +20 -0
- package/dist/src/matchmaking/index.d.ts.map +1 -0
- package/dist/src/matchmaking/index.js +20 -0
- package/dist/src/matchmaking/index.js.map +1 -0
- package/dist/src/matchmaking/module.d.ts +181 -0
- package/dist/src/matchmaking/module.d.ts.map +1 -0
- package/dist/src/matchmaking/module.js +221 -0
- package/dist/src/matchmaking/module.js.map +1 -0
- package/dist/src/matchmaking/protocols.d.ts +37 -0
- package/dist/src/matchmaking/protocols.d.ts.map +1 -0
- package/dist/src/matchmaking/protocols.js +42 -0
- package/dist/src/matchmaking/protocols.js.map +1 -0
- package/dist/src/matchmaking/provider-manager.d.ts +52 -0
- package/dist/src/matchmaking/provider-manager.d.ts.map +1 -0
- package/dist/src/matchmaking/provider-manager.js +74 -0
- package/dist/src/matchmaking/provider-manager.js.map +1 -0
- package/dist/src/matchmaking/query-handler.d.ts +34 -0
- package/dist/src/matchmaking/query-handler.d.ts.map +1 -0
- package/dist/src/matchmaking/query-handler.js +62 -0
- package/dist/src/matchmaking/query-handler.js.map +1 -0
- package/dist/src/matchmaking/query-transport.d.ts +180 -0
- package/dist/src/matchmaking/query-transport.d.ts.map +1 -0
- package/dist/src/matchmaking/query-transport.js +315 -0
- package/dist/src/matchmaking/query-transport.js.map +1 -0
- package/dist/src/matchmaking/seeker-manager.d.ts +39 -0
- package/dist/src/matchmaking/seeker-manager.d.ts.map +1 -0
- package/dist/src/matchmaking/seeker-manager.js +49 -0
- package/dist/src/matchmaking/seeker-manager.js.map +1 -0
- package/dist/src/matchmaking/seeker-walk-client.d.ts +127 -0
- package/dist/src/matchmaking/seeker-walk-client.d.ts.map +1 -0
- package/dist/src/matchmaking/seeker-walk-client.js +189 -0
- package/dist/src/matchmaking/seeker-walk-client.js.map +1 -0
- package/dist/src/matchmaking/traffic-validation.d.ts +128 -0
- package/dist/src/matchmaking/traffic-validation.d.ts.map +1 -0
- package/dist/src/matchmaking/traffic-validation.js +105 -0
- package/dist/src/matchmaking/traffic-validation.js.map +1 -0
- package/dist/src/network/network-manager-service.d.ts +4 -2
- package/dist/src/network/network-manager-service.d.ts.map +1 -1
- package/dist/src/network/network-manager-service.js +9 -3
- package/dist/src/network/network-manager-service.js.map +1 -1
- package/dist/src/protocol-client.d.ts +25 -0
- package/dist/src/protocol-client.d.ts.map +1 -1
- package/dist/src/protocol-client.js +126 -4
- package/dist/src/protocol-client.js.map +1 -1
- package/dist/src/reactivity/forwarder-host.d.ts +198 -0
- package/dist/src/reactivity/forwarder-host.d.ts.map +1 -0
- package/dist/src/reactivity/forwarder-host.js +355 -0
- package/dist/src/reactivity/forwarder-host.js.map +1 -0
- package/dist/src/reactivity/index.d.ts +19 -0
- package/dist/src/reactivity/index.d.ts.map +1 -0
- package/dist/src/reactivity/index.js +19 -0
- package/dist/src/reactivity/index.js.map +1 -0
- package/dist/src/reactivity/notify-transport.d.ts +70 -0
- package/dist/src/reactivity/notify-transport.d.ts.map +1 -0
- package/dist/src/reactivity/notify-transport.js +111 -0
- package/dist/src/reactivity/notify-transport.js.map +1 -0
- package/dist/src/reactivity/origination-manager.d.ts +110 -0
- package/dist/src/reactivity/origination-manager.d.ts.map +1 -0
- package/dist/src/reactivity/origination-manager.js +129 -0
- package/dist/src/reactivity/origination-manager.js.map +1 -0
- package/dist/src/reactivity/protocols.d.ts +43 -0
- package/dist/src/reactivity/protocols.d.ts.map +1 -0
- package/dist/src/reactivity/protocols.js +50 -0
- package/dist/src/reactivity/protocols.js.map +1 -0
- package/dist/src/reactivity/push-state-gossip.d.ts +132 -0
- package/dist/src/reactivity/push-state-gossip.d.ts.map +1 -0
- package/dist/src/reactivity/push-state-gossip.js +231 -0
- package/dist/src/reactivity/push-state-gossip.js.map +1 -0
- package/dist/src/reactivity/recover-transport.d.ts +167 -0
- package/dist/src/reactivity/recover-transport.d.ts.map +1 -0
- package/dist/src/reactivity/recover-transport.js +308 -0
- package/dist/src/reactivity/recover-transport.js.map +1 -0
- package/dist/src/reactivity/rotation-rereg-scheduler.d.ts +142 -0
- package/dist/src/reactivity/rotation-rereg-scheduler.d.ts.map +1 -0
- package/dist/src/reactivity/rotation-rereg-scheduler.js +223 -0
- package/dist/src/reactivity/rotation-rereg-scheduler.js.map +1 -0
- package/dist/src/reactivity/subscriber-registry.d.ts +47 -0
- package/dist/src/reactivity/subscriber-registry.d.ts.map +1 -0
- package/dist/src/reactivity/subscriber-registry.js +87 -0
- package/dist/src/reactivity/subscriber-registry.js.map +1 -0
- package/dist/src/reactivity/subscription-manager.d.ts +221 -0
- package/dist/src/reactivity/subscription-manager.d.ts.map +1 -0
- package/dist/src/reactivity/subscription-manager.js +302 -0
- package/dist/src/reactivity/subscription-manager.js.map +1 -0
- package/dist/src/reactivity/topic-bytes.d.ts +32 -0
- package/dist/src/reactivity/topic-bytes.d.ts.map +1 -0
- package/dist/src/reactivity/topic-bytes.js +34 -0
- package/dist/src/reactivity/topic-bytes.js.map +1 -0
- package/dist/src/repo/client.d.ts.map +1 -1
- package/dist/src/repo/client.js +51 -19
- package/dist/src/repo/client.js.map +1 -1
- package/dist/src/repo/cluster-coordinator.d.ts +9 -0
- package/dist/src/repo/cluster-coordinator.d.ts.map +1 -1
- package/dist/src/repo/cluster-coordinator.js +65 -22
- package/dist/src/repo/cluster-coordinator.js.map +1 -1
- package/dist/src/repo/coordinator-repo.d.ts +20 -0
- package/dist/src/repo/coordinator-repo.d.ts.map +1 -1
- package/dist/src/repo/coordinator-repo.js +101 -16
- package/dist/src/repo/coordinator-repo.js.map +1 -1
- package/dist/src/repo/service.d.ts +46 -1
- package/dist/src/repo/service.d.ts.map +1 -1
- package/dist/src/repo/service.js +79 -45
- package/dist/src/repo/service.js.map +1 -1
- package/dist/src/rpc-deadline.d.ts +37 -0
- package/dist/src/rpc-deadline.d.ts.map +1 -0
- package/dist/src/rpc-deadline.js +31 -0
- package/dist/src/rpc-deadline.js.map +1 -0
- package/dist/src/storage/block-storage.d.ts +2 -0
- package/dist/src/storage/block-storage.d.ts.map +1 -1
- package/dist/src/storage/block-storage.js +95 -2
- package/dist/src/storage/block-storage.js.map +1 -1
- package/dist/src/storage/i-block-storage.d.ts +25 -0
- package/dist/src/storage/i-block-storage.d.ts.map +1 -1
- package/dist/src/storage/storage-repo.d.ts +53 -2
- package/dist/src/storage/storage-repo.d.ts.map +1 -1
- package/dist/src/storage/storage-repo.js +193 -9
- package/dist/src/storage/storage-repo.js.map +1 -1
- package/dist/src/sync/client.d.ts +4 -1
- package/dist/src/sync/client.d.ts.map +1 -1
- package/dist/src/sync/client.js +5 -2
- package/dist/src/sync/client.js.map +1 -1
- package/dist/src/testing/cohort-topic-mesh-harness.d.ts +219 -0
- package/dist/src/testing/cohort-topic-mesh-harness.d.ts.map +1 -0
- package/dist/src/testing/cohort-topic-mesh-harness.js +467 -0
- package/dist/src/testing/cohort-topic-mesh-harness.js.map +1 -0
- package/dist/src/testing/matchmaking-mesh-harness.d.ts +187 -0
- package/dist/src/testing/matchmaking-mesh-harness.d.ts.map +1 -0
- package/dist/src/testing/matchmaking-mesh-harness.js +358 -0
- package/dist/src/testing/matchmaking-mesh-harness.js.map +1 -0
- package/dist/src/testing/mesh-harness.d.ts.map +1 -1
- package/dist/src/testing/mesh-harness.js +23 -1
- package/dist/src/testing/mesh-harness.js.map +1 -1
- package/dist/src/testing/reactivity-mesh-harness.d.ts +298 -0
- package/dist/src/testing/reactivity-mesh-harness.d.ts.map +1 -0
- package/dist/src/testing/reactivity-mesh-harness.js +663 -0
- package/dist/src/testing/reactivity-mesh-harness.js.map +1 -0
- package/package.json +7 -4
- package/src/cluster/block-transfer-service.ts +133 -68
- package/src/cluster/client.ts +64 -45
- package/src/cluster/cluster-error.ts +64 -0
- package/src/cluster/cluster-repo.ts +405 -55
- package/src/cluster/commit-cert.ts +139 -0
- package/src/cluster/service.ts +116 -44
- package/src/cluster/spread-on-churn.ts +328 -285
- package/src/cohort-topic/bootstrap-evidence-builder.ts +122 -0
- package/src/cohort-topic/bootstrap-evidence-verifiers.ts +132 -0
- package/src/cohort-topic/bootstrap-parent-reference.ts +159 -0
- package/src/cohort-topic/change-bridge.ts +109 -0
- package/src/cohort-topic/cohort-gossip-driver.ts +144 -0
- package/src/cohort-topic/cohort-gossip-transport.ts +74 -0
- package/src/cohort-topic/fret-trust-anchor.ts +153 -0
- package/src/cohort-topic/host.ts +2175 -0
- package/src/cohort-topic/index.ts +13 -0
- package/src/cohort-topic/membership-publish-sink.ts +20 -0
- package/src/cohort-topic/membership-source.ts +68 -0
- package/src/cohort-topic/peer-codec.ts +31 -0
- package/src/cohort-topic/peer-sig.ts +86 -0
- package/src/cohort-topic/protocols.ts +71 -0
- package/src/cohort-topic/reactivity-membership-gate.ts +77 -0
- package/src/cohort-topic/size-estimator.ts +16 -0
- package/src/cohort-topic/stream-util.ts +87 -0
- package/src/cohort-topic/threshold-crypto.ts +239 -0
- package/src/cohort-topic/topic-router.ts +77 -0
- package/src/dispute/cascade.ts +517 -0
- package/src/dispute/client.ts +12 -2
- package/src/dispute/dispute-service.ts +171 -24
- package/src/dispute/index.ts +42 -0
- package/src/dispute/invalidation.ts +587 -0
- package/src/dispute/types.ts +14 -0
- package/src/index.ts +4 -0
- package/src/libp2p-key-network.ts +67 -9
- package/src/libp2p-node-base.ts +633 -14
- package/src/matchmaking/aggregate-counts.ts +104 -0
- package/src/matchmaking/index.ts +20 -0
- package/src/matchmaking/module.ts +363 -0
- package/src/matchmaking/protocols.ts +51 -0
- package/src/matchmaking/provider-manager.ts +95 -0
- package/src/matchmaking/query-handler.ts +88 -0
- package/src/matchmaking/query-transport.ts +483 -0
- package/src/matchmaking/seeker-manager.ts +64 -0
- package/src/matchmaking/seeker-walk-client.ts +293 -0
- package/src/matchmaking/traffic-validation.ts +195 -0
- package/src/network/network-manager-service.ts +9 -2
- package/src/protocol-client.ts +119 -5
- package/src/reactivity/forwarder-host.ts +438 -0
- package/src/reactivity/index.ts +19 -0
- package/src/reactivity/notify-transport.ts +144 -0
- package/src/reactivity/origination-manager.ts +192 -0
- package/src/reactivity/protocols.ts +61 -0
- package/src/reactivity/push-state-gossip.ts +291 -0
- package/src/reactivity/recover-transport.ts +408 -0
- package/src/reactivity/rotation-rereg-scheduler.ts +256 -0
- package/src/reactivity/subscriber-registry.ts +96 -0
- package/src/reactivity/subscription-manager.ts +450 -0
- package/src/reactivity/topic-bytes.ts +37 -0
- package/src/repo/client.ts +54 -19
- package/src/repo/cluster-coordinator.ts +66 -26
- package/src/repo/coordinator-repo.ts +99 -15
- package/src/repo/service.ts +90 -42
- package/src/rpc-deadline.ts +45 -0
- package/src/storage/block-storage.ts +106 -3
- package/src/storage/i-block-storage.ts +27 -0
- package/src/storage/storage-repo.ts +209 -13
- package/src/sync/client.ts +5 -2
- package/src/testing/cohort-topic-mesh-harness.ts +613 -0
- package/src/testing/matchmaking-mesh-harness.ts +475 -0
- package/src/testing/mesh-harness.ts +22 -2
- package/src/testing/reactivity-mesh-harness.ts +922 -0
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Matchmaking — cohesive public module (db-p2p, the cohort-topic-integrated entry points).
|
|
3
|
+
*
|
|
4
|
+
* `docs/matchmaking.md` §Overview / §Configuration names two public roles. This module composes the
|
|
5
|
+
* lower db-core state + db-p2p substrate wiring (managers, seeker walk client, multi-cohort sweep) into
|
|
6
|
+
* those roles, plus the `QuorumDiscovery` binding the voting plan consumes:
|
|
7
|
+
*
|
|
8
|
+
* - {@link MatchmakingProviderSession} — `register(topic, payload)` / `renew()` / `withdraw()` (plus
|
|
9
|
+
* `setCapacity` / `signalFull` self-throttling), driving a {@link MatchmakingProvider} through the
|
|
10
|
+
* {@link MatchmakingProviderManager} at cohort-topic tier **T2**.
|
|
11
|
+
* - {@link MatchmakingSeekerSession} — `register(topic, payload)` (brief T2 registration), `query(q)`
|
|
12
|
+
* (one-shot cohort query), and `walk(topic, want)` (the hang-out engine, escalating to the
|
|
13
|
+
* multi-cohort sweep on a hot topic).
|
|
14
|
+
* - {@link createMatchmakingQuorumDiscovery} — binds the db-core voting `QuorumDiscovery` port to the
|
|
15
|
+
* seeker walk (single-cohort) + {@link runMultiCohortSweep} (sweep), so `VotingQuorumAssembler` runs
|
|
16
|
+
* over real substrate I/O.
|
|
17
|
+
*
|
|
18
|
+
* **Naming note (honest):** the db-core `MatchmakingProvider` / `MatchmakingSeeker` are the
|
|
19
|
+
* transport-free *state + signed-payload builders*; these `*Session` classes are the substrate-wired
|
|
20
|
+
* *public entry points* the doc's `MatchmakingProvider` / `MatchmakingSeeker` sketch refers to. They are
|
|
21
|
+
* named `*Session` to avoid colliding with the re-exported db-core state classes.
|
|
22
|
+
*
|
|
23
|
+
* The substrate I/O is **injected** — the seeker walk transport, the one-shot query, the `d_max`
|
|
24
|
+
* estimate, and the sweep ports are all ports the FRET host binds. The module therefore unit-tests
|
|
25
|
+
* without a live libp2p stack; the mock-tier e2e that drives these against a real promoted tree is a
|
|
26
|
+
* documented follow-on (the same posture as the rest of the subsystem).
|
|
27
|
+
*/
|
|
28
|
+
import { MatchmakingProvider, MatchmakingSeeker, createMatchTopicAnchor, runMultiCohortSweep, } from "@optimystic/db-core";
|
|
29
|
+
import { MatchmakingProviderManager } from "./provider-manager.js";
|
|
30
|
+
import { MatchmakingSeekerManager } from "./seeker-manager.js";
|
|
31
|
+
import { SeekerWalkClient } from "./seeker-walk-client.js";
|
|
32
|
+
/**
|
|
33
|
+
* Public provider entry point: registers a {@link MatchmakingProvider} at a topic (cohort-topic T2) and
|
|
34
|
+
* drives its lifecycle. One session owns one live registration; calling {@link register} again
|
|
35
|
+
* re-registers (e.g. at a different topic).
|
|
36
|
+
*/
|
|
37
|
+
export class MatchmakingProviderSession {
|
|
38
|
+
deps;
|
|
39
|
+
anchor;
|
|
40
|
+
manager;
|
|
41
|
+
constructor(deps) {
|
|
42
|
+
this.deps = deps;
|
|
43
|
+
this.anchor = deps.anchor ?? createMatchTopicAnchor();
|
|
44
|
+
}
|
|
45
|
+
/** The live registration handle, or `undefined` before the first {@link register}. */
|
|
46
|
+
get registration() {
|
|
47
|
+
return this.manager?.registration;
|
|
48
|
+
}
|
|
49
|
+
/** Register the provider at `topic` with the signed payload, at cohort-topic tier T2. */
|
|
50
|
+
async register(topic, reg) {
|
|
51
|
+
const topicId = this.anchor.topicId(topic.kind, topic.label);
|
|
52
|
+
const provider = new MatchmakingProvider({
|
|
53
|
+
topicId,
|
|
54
|
+
capabilities: reg.capabilities,
|
|
55
|
+
capacityBudget: reg.capacityBudget,
|
|
56
|
+
contactHint: reg.contactHint,
|
|
57
|
+
sign: this.deps.sign,
|
|
58
|
+
...(reg.serviceUntil !== undefined ? { serviceUntil: reg.serviceUntil } : {}),
|
|
59
|
+
...(this.deps.randomBytes !== undefined ? { randomBytes: this.deps.randomBytes } : {}),
|
|
60
|
+
});
|
|
61
|
+
this.manager = new MatchmakingProviderManager({
|
|
62
|
+
service: this.deps.service,
|
|
63
|
+
provider,
|
|
64
|
+
...(this.deps.ttlMs !== undefined ? { ttlMs: this.deps.ttlMs } : {}),
|
|
65
|
+
...(this.deps.profile !== undefined ? { profile: this.deps.profile } : {}),
|
|
66
|
+
});
|
|
67
|
+
await this.manager.register();
|
|
68
|
+
}
|
|
69
|
+
/** Run one renewal cycle (keep-alive). No-op before {@link register}. */
|
|
70
|
+
async renew() {
|
|
71
|
+
await this.manager?.renew();
|
|
72
|
+
}
|
|
73
|
+
/** Update the live capacity budget and push it by re-registering (`RenewV1` cannot carry a payload). */
|
|
74
|
+
async setCapacity(budget) {
|
|
75
|
+
await this.requireManager().setCapacity(budget);
|
|
76
|
+
}
|
|
77
|
+
/** Signal "available but at capacity" (`capacityBudget = 0`) by re-registering. */
|
|
78
|
+
async signalFull() {
|
|
79
|
+
await this.requireManager().signalFull();
|
|
80
|
+
}
|
|
81
|
+
/** Withdraw: sends a best-effort signed `RenewV1.withdraw` tombstone so the cohort frees the record
|
|
82
|
+
* immediately (an optimization; the record otherwise TTL-expires). No-op before register. */
|
|
83
|
+
async withdraw() {
|
|
84
|
+
await this.manager?.withdraw();
|
|
85
|
+
}
|
|
86
|
+
requireManager() {
|
|
87
|
+
if (this.manager === undefined) {
|
|
88
|
+
throw new Error("MatchmakingProviderSession: register() must precede setCapacity()/signalFull()");
|
|
89
|
+
}
|
|
90
|
+
return this.manager;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Public seeker entry point: brief registration, one-shot query, and the hang-out `walk` (which escalates
|
|
95
|
+
* to the multi-cohort sweep on a hot topic). One session may register and walk independently.
|
|
96
|
+
*/
|
|
97
|
+
export class MatchmakingSeekerSession {
|
|
98
|
+
deps;
|
|
99
|
+
anchor;
|
|
100
|
+
manager;
|
|
101
|
+
constructor(deps) {
|
|
102
|
+
this.deps = deps;
|
|
103
|
+
this.anchor = deps.anchor ?? createMatchTopicAnchor();
|
|
104
|
+
}
|
|
105
|
+
/** Resolve the `topicId` for a topic ref. */
|
|
106
|
+
topicIdFor(topic) {
|
|
107
|
+
return this.anchor.topicId(topic.kind, topic.label);
|
|
108
|
+
}
|
|
109
|
+
/** Register the seeker briefly at `topic` (cohort-topic T2, short TTL). */
|
|
110
|
+
async register(topic, reg) {
|
|
111
|
+
const topicId = this.topicIdFor(topic);
|
|
112
|
+
const seeker = new MatchmakingSeeker({
|
|
113
|
+
topicId,
|
|
114
|
+
wantCount: reg.wantCount,
|
|
115
|
+
contactHint: reg.contactHint,
|
|
116
|
+
sign: this.deps.sign,
|
|
117
|
+
...(reg.filter !== undefined ? { filter: reg.filter } : {}),
|
|
118
|
+
...(reg.pushOnArrival !== undefined ? { pushOnArrival: reg.pushOnArrival } : {}),
|
|
119
|
+
});
|
|
120
|
+
this.manager = new MatchmakingSeekerManager({
|
|
121
|
+
service: this.deps.service,
|
|
122
|
+
seeker,
|
|
123
|
+
...(this.deps.ttlMs !== undefined ? { ttlMs: this.deps.ttlMs } : {}),
|
|
124
|
+
});
|
|
125
|
+
await this.manager.register();
|
|
126
|
+
}
|
|
127
|
+
/** Drop the seeker registration: sends a best-effort tombstone so the cohort frees the record
|
|
128
|
+
* immediately (the record otherwise TTL-expires). No-op before register. */
|
|
129
|
+
async withdraw() {
|
|
130
|
+
await this.manager?.withdraw();
|
|
131
|
+
}
|
|
132
|
+
/** Issue a one-shot `QueryV1` against the topic's cohort (resolved from `q.topicId`). */
|
|
133
|
+
async query(q) {
|
|
134
|
+
return this.deps.queryCohort(q);
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Run the hang-out walk for `topic`, then — on a hot topic (`childCohortCount > 0`) or when
|
|
138
|
+
* `preferSweep` is set, and when the sweep ports are bound — escalate to the multi-cohort sweep and
|
|
139
|
+
* union the deduped providers. Returns the assembled (possibly `< wantCount`) provider set.
|
|
140
|
+
*/
|
|
141
|
+
async walk(topic, want) {
|
|
142
|
+
const topicId = this.topicIdFor(topic);
|
|
143
|
+
const dMax = await this.deps.estimateDMax(topicId);
|
|
144
|
+
const client = new SeekerWalkClient({
|
|
145
|
+
transport: this.deps.walkTransport(topicId),
|
|
146
|
+
topicId,
|
|
147
|
+
wantCount: want.wantCount,
|
|
148
|
+
dMax,
|
|
149
|
+
patienceMs: want.patienceMs,
|
|
150
|
+
verifyEntry: this.deps.verifyEntry,
|
|
151
|
+
...(want.filter !== undefined ? { filter: want.filter } : {}),
|
|
152
|
+
...(this.deps.config !== undefined ? { config: this.deps.config } : {}),
|
|
153
|
+
...(this.deps.meanWantCount !== undefined ? { meanWantCount: this.deps.meanWantCount } : {}),
|
|
154
|
+
...(this.deps.clock !== undefined ? { clock: this.deps.clock } : {}),
|
|
155
|
+
...(this.deps.sleep !== undefined ? { sleep: this.deps.sleep } : {}),
|
|
156
|
+
});
|
|
157
|
+
const result = await client.run();
|
|
158
|
+
const providers = new Map(result.providers.map((p) => [p.participantId, p]));
|
|
159
|
+
const hot = result.maxChildCohortCount > 0;
|
|
160
|
+
const wantSweep = want.preferSweep === true || (hot && providers.size < want.wantCount);
|
|
161
|
+
if (wantSweep && this.deps.sweepPorts !== undefined) {
|
|
162
|
+
// Pass want.patienceMs as a fresh (coarser) bound — this path does not track a draining
|
|
163
|
+
// remainder (SeekerWalkClient ran on its own deadline). Still strictly better than unbounded.
|
|
164
|
+
const sweep = await runMultiCohortSweep(this.deps.sweepPorts(topicId), {
|
|
165
|
+
topicId,
|
|
166
|
+
wantCount: want.wantCount,
|
|
167
|
+
verifyEntry: this.deps.verifyEntry,
|
|
168
|
+
patienceMs: want.patienceMs,
|
|
169
|
+
...(want.filter !== undefined ? { filter: want.filter } : {}),
|
|
170
|
+
...(this.deps.clock !== undefined ? { clock: this.deps.clock } : {}),
|
|
171
|
+
});
|
|
172
|
+
for (const entry of sweep.providers) {
|
|
173
|
+
providers.set(entry.participantId, entry);
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
return [...providers.values()];
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* Bind the db-core voting {@link QuorumDiscovery} port (`docs/matchmaking.md` §Voting-quorum assembly)
|
|
181
|
+
* to the matchmaking substrate: `walk` runs the single-cohort hang-out walk and surfaces its hotness
|
|
182
|
+
* signal (`childCohortCount`); `sweep` runs {@link runMultiCohortSweep} across the high-population tier
|
|
183
|
+
* shards. `VotingQuorumAssembler` composes the two — walk, then sweep on a hot topic — re-validating
|
|
184
|
+
* every entry itself, so this binding stays a thin transport adapter.
|
|
185
|
+
*/
|
|
186
|
+
export function createMatchmakingQuorumDiscovery(deps) {
|
|
187
|
+
return {
|
|
188
|
+
async walk(req) {
|
|
189
|
+
const dMax = await deps.estimateDMax(req.topicId);
|
|
190
|
+
const client = new SeekerWalkClient({
|
|
191
|
+
transport: deps.walkTransport(req.topicId),
|
|
192
|
+
topicId: req.topicId,
|
|
193
|
+
wantCount: req.wantCount,
|
|
194
|
+
dMax,
|
|
195
|
+
patienceMs: req.patienceMs,
|
|
196
|
+
verifyEntry: deps.verifyEntry,
|
|
197
|
+
...(deps.filter !== undefined ? { filter: deps.filter } : {}),
|
|
198
|
+
...(deps.config !== undefined ? { config: deps.config } : {}),
|
|
199
|
+
...(deps.meanWantCount !== undefined ? { meanWantCount: deps.meanWantCount } : {}),
|
|
200
|
+
...(deps.clock !== undefined ? { clock: deps.clock } : {}),
|
|
201
|
+
...(deps.sleep !== undefined ? { sleep: deps.sleep } : {}),
|
|
202
|
+
});
|
|
203
|
+
const result = await client.run();
|
|
204
|
+
return { entries: result.providers, childCohortCount: result.maxChildCohortCount };
|
|
205
|
+
},
|
|
206
|
+
async sweep(req) {
|
|
207
|
+
const result = await runMultiCohortSweep(deps.sweepPorts(req.topicId), {
|
|
208
|
+
topicId: req.topicId,
|
|
209
|
+
wantCount: req.wantCount,
|
|
210
|
+
verifyEntry: deps.verifyEntry,
|
|
211
|
+
patienceMs: req.patienceMs,
|
|
212
|
+
...(deps.filter !== undefined ? { filter: deps.filter } : {}),
|
|
213
|
+
...(deps.clock !== undefined ? { clock: deps.clock } : {}),
|
|
214
|
+
});
|
|
215
|
+
// The sweep hop has already crossed the ring — its childCohortCount is moot (the escalation
|
|
216
|
+
// decision is made). Report 0 so the assembler never double-escalates.
|
|
217
|
+
return { entries: result.providers, childCohortCount: 0 };
|
|
218
|
+
},
|
|
219
|
+
};
|
|
220
|
+
}
|
|
221
|
+
//# sourceMappingURL=module.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"module.js","sourceRoot":"","sources":["../../../src/matchmaking/module.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Matchmaking libp2p protocol IDs (`docs/matchmaking.md` §Seeker query).
|
|
3
|
+
*
|
|
4
|
+
* Matchmaking is an application layered **above** the cohort-topic substrate, so it owns its own protocol
|
|
5
|
+
* family rather than riding the cohort-topic protocols (which carry only substrate concerns — register,
|
|
6
|
+
* gossip, promote, membership, sign). Exactly one protocol lives here today:
|
|
7
|
+
*
|
|
8
|
+
* - `query` — `QueryV1` → `QueryReplyV1`, the seeker's request-reply RPC against a cohort for the
|
|
9
|
+
* providers/seekers it locally holds (the serve side is `query-transport.ts`; the seeker
|
|
10
|
+
* walk client is the follow-on `matchmaking-query-rpc-seeker-walk`).
|
|
11
|
+
*
|
|
12
|
+
* The default (network-agnostic) ID omits the network segment; {@link makeMatchmakingProtocols} mirrors
|
|
13
|
+
* FRET's `makeProtocols(networkName)` so a named network namespaces its matchmaking protocols the same way
|
|
14
|
+
* FRET namespaces its routing protocols (and the cohort-topic / reactivity families namespace via their own
|
|
15
|
+
* `make*Protocols`). Production wires the network-agnostic default, matching the cohort-topic + reactivity
|
|
16
|
+
* families' production default.
|
|
17
|
+
*/
|
|
18
|
+
/** Base path for the matchmaking protocol family. */
|
|
19
|
+
export declare const MATCHMAKING_BASE: "/optimystic/matchmaking/1.0.0";
|
|
20
|
+
/** `QueryV1` / `QueryReplyV1` — a seeker's query for a cohort's locally-held provider/seeker registrations. */
|
|
21
|
+
export declare const PROTOCOL_MATCHMAKING_QUERY: "/optimystic/matchmaking/1.0.0/query";
|
|
22
|
+
/** The matchmaking protocol IDs in registration order. */
|
|
23
|
+
export interface MatchmakingProtocols {
|
|
24
|
+
readonly query: string;
|
|
25
|
+
}
|
|
26
|
+
/** Default (network-agnostic) protocol IDs, matching `docs/matchmaking.md`. */
|
|
27
|
+
export declare const DEFAULT_MATCHMAKING_PROTOCOLS: MatchmakingProtocols;
|
|
28
|
+
/**
|
|
29
|
+
* Namespaced matchmaking protocol IDs for `networkName` (mirrors FRET's `makeProtocols`, which inserts the
|
|
30
|
+
* network segment even for `"default"` → `/optimystic/default/...`). Note this does NOT equal
|
|
31
|
+
* {@link DEFAULT_MATCHMAKING_PROTOCOLS}: the canonical, network-agnostic IDs omit the segment entirely
|
|
32
|
+
* (`/optimystic/matchmaking/1.0.0/...`); use those unless you need per-network namespacing.
|
|
33
|
+
*/
|
|
34
|
+
export declare function makeMatchmakingProtocols(networkName?: string): MatchmakingProtocols;
|
|
35
|
+
/** All matchmaking protocol IDs as an array (for `node.handle` / `unhandle` over the set). */
|
|
36
|
+
export declare function matchmakingProtocolList(p: MatchmakingProtocols): string[];
|
|
37
|
+
//# sourceMappingURL=protocols.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"protocols.d.ts","sourceRoot":"","sources":["../../../src/matchmaking/protocols.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,qDAAqD;AACrD,eAAO,MAAM,gBAAgB,EAAG,+BAAwC,CAAC;AAEzE,+GAA+G;AAC/G,eAAO,MAAM,0BAA0B,uCAAuC,CAAC;AAE/E,0DAA0D;AAC1D,MAAM,WAAW,oBAAoB;IACpC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;CACvB;AAED,+EAA+E;AAC/E,eAAO,MAAM,6BAA6B,EAAE,oBAE3C,CAAC;AAEF;;;;;GAKG;AACH,wBAAgB,wBAAwB,CAAC,WAAW,SAAY,GAAG,oBAAoB,CAKtF;AAED,8FAA8F;AAC9F,wBAAgB,uBAAuB,CAAC,CAAC,EAAE,oBAAoB,GAAG,MAAM,EAAE,CAEzE"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Matchmaking libp2p protocol IDs (`docs/matchmaking.md` §Seeker query).
|
|
3
|
+
*
|
|
4
|
+
* Matchmaking is an application layered **above** the cohort-topic substrate, so it owns its own protocol
|
|
5
|
+
* family rather than riding the cohort-topic protocols (which carry only substrate concerns — register,
|
|
6
|
+
* gossip, promote, membership, sign). Exactly one protocol lives here today:
|
|
7
|
+
*
|
|
8
|
+
* - `query` — `QueryV1` → `QueryReplyV1`, the seeker's request-reply RPC against a cohort for the
|
|
9
|
+
* providers/seekers it locally holds (the serve side is `query-transport.ts`; the seeker
|
|
10
|
+
* walk client is the follow-on `matchmaking-query-rpc-seeker-walk`).
|
|
11
|
+
*
|
|
12
|
+
* The default (network-agnostic) ID omits the network segment; {@link makeMatchmakingProtocols} mirrors
|
|
13
|
+
* FRET's `makeProtocols(networkName)` so a named network namespaces its matchmaking protocols the same way
|
|
14
|
+
* FRET namespaces its routing protocols (and the cohort-topic / reactivity families namespace via their own
|
|
15
|
+
* `make*Protocols`). Production wires the network-agnostic default, matching the cohort-topic + reactivity
|
|
16
|
+
* families' production default.
|
|
17
|
+
*/
|
|
18
|
+
/** Base path for the matchmaking protocol family. */
|
|
19
|
+
export const MATCHMAKING_BASE = "/optimystic/matchmaking/1.0.0";
|
|
20
|
+
/** `QueryV1` / `QueryReplyV1` — a seeker's query for a cohort's locally-held provider/seeker registrations. */
|
|
21
|
+
export const PROTOCOL_MATCHMAKING_QUERY = `${MATCHMAKING_BASE}/query`;
|
|
22
|
+
/** Default (network-agnostic) protocol IDs, matching `docs/matchmaking.md`. */
|
|
23
|
+
export const DEFAULT_MATCHMAKING_PROTOCOLS = {
|
|
24
|
+
query: PROTOCOL_MATCHMAKING_QUERY,
|
|
25
|
+
};
|
|
26
|
+
/**
|
|
27
|
+
* Namespaced matchmaking protocol IDs for `networkName` (mirrors FRET's `makeProtocols`, which inserts the
|
|
28
|
+
* network segment even for `"default"` → `/optimystic/default/...`). Note this does NOT equal
|
|
29
|
+
* {@link DEFAULT_MATCHMAKING_PROTOCOLS}: the canonical, network-agnostic IDs omit the segment entirely
|
|
30
|
+
* (`/optimystic/matchmaking/1.0.0/...`); use those unless you need per-network namespacing.
|
|
31
|
+
*/
|
|
32
|
+
export function makeMatchmakingProtocols(networkName = "default") {
|
|
33
|
+
const base = `/optimystic/${networkName}/matchmaking/1.0.0`;
|
|
34
|
+
return {
|
|
35
|
+
query: `${base}/query`,
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
/** All matchmaking protocol IDs as an array (for `node.handle` / `unhandle` over the set). */
|
|
39
|
+
export function matchmakingProtocolList(p) {
|
|
40
|
+
return [p.query];
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=protocols.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"protocols.js","sourceRoot":"","sources":["../../../src/matchmaking/protocols.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,qDAAqD;AACrD,MAAM,CAAC,MAAM,gBAAgB,GAAG,+BAAwC,CAAC;AAEzE,+GAA+G;AAC/G,MAAM,CAAC,MAAM,0BAA0B,GAAG,GAAG,gBAAgB,QAAiB,CAAC;AAO/E,+EAA+E;AAC/E,MAAM,CAAC,MAAM,6BAA6B,GAAyB;IAClE,KAAK,EAAE,0BAA0B;CACjC,CAAC;AAEF;;;;;GAKG;AACH,MAAM,UAAU,wBAAwB,CAAC,WAAW,GAAG,SAAS;IAC/D,MAAM,IAAI,GAAG,eAAe,WAAW,oBAAoB,CAAC;IAC5D,OAAO;QACN,KAAK,EAAE,GAAG,IAAI,QAAQ;KACtB,CAAC;AACH,CAAC;AAED,8FAA8F;AAC9F,MAAM,UAAU,uBAAuB,CAAC,CAAuB;IAC9D,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;AAClB,CAAC"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Matchmaking — provider manager (db-p2p, wires to the cohort-topic substrate).
|
|
3
|
+
*
|
|
4
|
+
* Drives a db-core {@link MatchmakingProvider}'s lifecycle against the participant-facing
|
|
5
|
+
* {@link CohortTopicService}: register at cohort-topic tier **T2 (functional)** with a profile-based
|
|
6
|
+
* TTL, renew to keep the record alive, and withdraw by ceasing renewal (`docs/matchmaking.md`
|
|
7
|
+
* §Provider registration).
|
|
8
|
+
*
|
|
9
|
+
* Self-throttling maps onto the substrate as follows (an honest gap surfaced for the reviewer): the
|
|
10
|
+
* cohort-topic `RenewV1` carries **no** `appPayload` and **no** `ttl` field — a renewal is a pure
|
|
11
|
+
* keep-alive touch. So a capacity change ("signal full", `capacityBudget = 0`) is realized by
|
|
12
|
+
* **re-registering** with the new signed payload (which updates the cohort record's `appState`), not
|
|
13
|
+
* by a renewal. Likewise immediate withdrawal (`RenewV1` TTL = 0 in the matchmaking doc) has no wire
|
|
14
|
+
* realization yet — {@link withdraw} stops renewing and lets the record age out by TTL. Per the
|
|
15
|
+
* §Provider self-throttling GROUNDING resolution, withdrawal is an **optimization, not correctness**,
|
|
16
|
+
* so passive TTL expiry is acceptable; an immediate-tombstone renew is a documented cohort-topic
|
|
17
|
+
* follow-on.
|
|
18
|
+
*/
|
|
19
|
+
import { type CohortTopicService, type MatchmakingProvider, type NodeProfile, type RegistrationHandle } from "@optimystic/db-core";
|
|
20
|
+
/** Construction inputs for a {@link MatchmakingProviderManager}. */
|
|
21
|
+
export interface MatchmakingProviderManagerOptions {
|
|
22
|
+
/** Participant-facing cohort-topic substrate API. */
|
|
23
|
+
readonly service: CohortTopicService;
|
|
24
|
+
/** The provider state/decision object this manager drives. */
|
|
25
|
+
readonly provider: MatchmakingProvider;
|
|
26
|
+
/** Provider TTL (ms). Default: derived from {@link profile} via `providerTtlForProfile`. */
|
|
27
|
+
readonly ttlMs?: number;
|
|
28
|
+
/** Node profile used to derive the TTL when {@link ttlMs} is absent (Core 90 s / Edge 60 s). */
|
|
29
|
+
readonly profile?: NodeProfile;
|
|
30
|
+
}
|
|
31
|
+
/** Wires one matchmaking provider to the cohort-topic substrate at tier T2. */
|
|
32
|
+
export declare class MatchmakingProviderManager {
|
|
33
|
+
private readonly service;
|
|
34
|
+
private readonly provider;
|
|
35
|
+
private readonly ttlMs;
|
|
36
|
+
private handle?;
|
|
37
|
+
constructor(options: MatchmakingProviderManagerOptions);
|
|
38
|
+
/** The live registration handle, or `undefined` before the first {@link register}. */
|
|
39
|
+
get registration(): RegistrationHandle | undefined;
|
|
40
|
+
/** Register (or re-register) the provider at tier T2 with the current signed payload. */
|
|
41
|
+
register(): Promise<RegistrationHandle>;
|
|
42
|
+
/** Run one renewal cycle (keep-alive touch). No-op before the first {@link register}. */
|
|
43
|
+
renew(): Promise<void>;
|
|
44
|
+
/** Set the live capacity budget and push it by re-registering (`RenewV1` cannot carry payload). */
|
|
45
|
+
setCapacity(budget: number): Promise<RegistrationHandle>;
|
|
46
|
+
/** Signal "available but at capacity" (`capacityBudget = 0`) and push it by re-registering. */
|
|
47
|
+
signalFull(): Promise<RegistrationHandle>;
|
|
48
|
+
/** Withdraw: stop renewing and send a best-effort signed tombstone so the cohort frees the record
|
|
49
|
+
* immediately; TTL expiry is the fallback (the immediate tombstone is an optimization, not correctness). */
|
|
50
|
+
withdraw(): Promise<void>;
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=provider-manager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"provider-manager.d.ts","sourceRoot":"","sources":["../../../src/matchmaking/provider-manager.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,EAA+B,KAAK,kBAAkB,EAAE,KAAK,mBAAmB,EAAE,KAAK,WAAW,EAAE,KAAK,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAEhK,oEAAoE;AACpE,MAAM,WAAW,iCAAiC;IACjD,qDAAqD;IACrD,QAAQ,CAAC,OAAO,EAAE,kBAAkB,CAAC;IACrC,8DAA8D;IAC9D,QAAQ,CAAC,QAAQ,EAAE,mBAAmB,CAAC;IACvC,4FAA4F;IAC5F,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,gGAAgG;IAChG,QAAQ,CAAC,OAAO,CAAC,EAAE,WAAW,CAAC;CAC/B;AAED,+EAA+E;AAC/E,qBAAa,0BAA0B;IACtC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAqB;IAC7C,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAsB;IAC/C,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAS;IAC/B,OAAO,CAAC,MAAM,CAAC,CAAqB;gBAExB,OAAO,EAAE,iCAAiC;IAMtD,sFAAsF;IACtF,IAAI,YAAY,IAAI,kBAAkB,GAAG,SAAS,CAEjD;IAED,yFAAyF;IACnF,QAAQ,IAAI,OAAO,CAAC,kBAAkB,CAAC;IAW7C,yFAAyF;IACnF,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAO5B,mGAAmG;IAC7F,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,CAAC;IAK9D,+FAA+F;IACzF,UAAU,IAAI,OAAO,CAAC,kBAAkB,CAAC;IAK/C;gHAC4G;IACtG,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;CAM/B"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Matchmaking — provider manager (db-p2p, wires to the cohort-topic substrate).
|
|
3
|
+
*
|
|
4
|
+
* Drives a db-core {@link MatchmakingProvider}'s lifecycle against the participant-facing
|
|
5
|
+
* {@link CohortTopicService}: register at cohort-topic tier **T2 (functional)** with a profile-based
|
|
6
|
+
* TTL, renew to keep the record alive, and withdraw by ceasing renewal (`docs/matchmaking.md`
|
|
7
|
+
* §Provider registration).
|
|
8
|
+
*
|
|
9
|
+
* Self-throttling maps onto the substrate as follows (an honest gap surfaced for the reviewer): the
|
|
10
|
+
* cohort-topic `RenewV1` carries **no** `appPayload` and **no** `ttl` field — a renewal is a pure
|
|
11
|
+
* keep-alive touch. So a capacity change ("signal full", `capacityBudget = 0`) is realized by
|
|
12
|
+
* **re-registering** with the new signed payload (which updates the cohort record's `appState`), not
|
|
13
|
+
* by a renewal. Likewise immediate withdrawal (`RenewV1` TTL = 0 in the matchmaking doc) has no wire
|
|
14
|
+
* realization yet — {@link withdraw} stops renewing and lets the record age out by TTL. Per the
|
|
15
|
+
* §Provider self-throttling GROUNDING resolution, withdrawal is an **optimization, not correctness**,
|
|
16
|
+
* so passive TTL expiry is acceptable; an immediate-tombstone renew is a documented cohort-topic
|
|
17
|
+
* follow-on.
|
|
18
|
+
*/
|
|
19
|
+
import { Tier, providerTtlForProfile } from "@optimystic/db-core";
|
|
20
|
+
/** Wires one matchmaking provider to the cohort-topic substrate at tier T2. */
|
|
21
|
+
export class MatchmakingProviderManager {
|
|
22
|
+
service;
|
|
23
|
+
provider;
|
|
24
|
+
ttlMs;
|
|
25
|
+
handle;
|
|
26
|
+
constructor(options) {
|
|
27
|
+
this.service = options.service;
|
|
28
|
+
this.provider = options.provider;
|
|
29
|
+
this.ttlMs = options.ttlMs ?? (options.profile !== undefined ? providerTtlForProfile(options.profile) : undefined) ?? DEFAULT_PROVIDER_TTL_MS;
|
|
30
|
+
}
|
|
31
|
+
/** The live registration handle, or `undefined` before the first {@link register}. */
|
|
32
|
+
get registration() {
|
|
33
|
+
return this.handle;
|
|
34
|
+
}
|
|
35
|
+
/** Register (or re-register) the provider at tier T2 with the current signed payload. */
|
|
36
|
+
async register() {
|
|
37
|
+
const appPayload = await this.provider.appPayloadBytes();
|
|
38
|
+
this.handle = await this.service.register({
|
|
39
|
+
topicId: this.provider.topicId,
|
|
40
|
+
tier: Tier.T2,
|
|
41
|
+
appPayload,
|
|
42
|
+
ttl: this.ttlMs,
|
|
43
|
+
});
|
|
44
|
+
return this.handle;
|
|
45
|
+
}
|
|
46
|
+
/** Run one renewal cycle (keep-alive touch). No-op before the first {@link register}. */
|
|
47
|
+
async renew() {
|
|
48
|
+
if (this.handle === undefined) {
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
await this.service.renew(this.handle);
|
|
52
|
+
}
|
|
53
|
+
/** Set the live capacity budget and push it by re-registering (`RenewV1` cannot carry payload). */
|
|
54
|
+
async setCapacity(budget) {
|
|
55
|
+
this.provider.setCapacity(budget);
|
|
56
|
+
return this.register();
|
|
57
|
+
}
|
|
58
|
+
/** Signal "available but at capacity" (`capacityBudget = 0`) and push it by re-registering. */
|
|
59
|
+
async signalFull() {
|
|
60
|
+
this.provider.signalFull();
|
|
61
|
+
return this.register();
|
|
62
|
+
}
|
|
63
|
+
/** Withdraw: stop renewing and send a best-effort signed tombstone so the cohort frees the record
|
|
64
|
+
* immediately; TTL expiry is the fallback (the immediate tombstone is an optimization, not correctness). */
|
|
65
|
+
async withdraw() {
|
|
66
|
+
this.provider.markWithdrawn();
|
|
67
|
+
if (this.handle !== undefined) {
|
|
68
|
+
await this.service.withdraw(this.handle);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
/** Fallback provider TTL when neither an explicit `ttlMs` nor a `profile` is supplied (Core default). */
|
|
73
|
+
const DEFAULT_PROVIDER_TTL_MS = 90_000;
|
|
74
|
+
//# sourceMappingURL=provider-manager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"provider-manager.js","sourceRoot":"","sources":["../../../src/matchmaking/provider-manager.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,EAAE,IAAI,EAAE,qBAAqB,EAAgG,MAAM,qBAAqB,CAAC;AAchK,+EAA+E;AAC/E,MAAM,OAAO,0BAA0B;IACrB,OAAO,CAAqB;IAC5B,QAAQ,CAAsB;IAC9B,KAAK,CAAS;IACvB,MAAM,CAAsB;IAEpC,YAAY,OAA0C;QACrD,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC;QAC/B,IAAI,CAAC,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC;QACjC,IAAI,CAAC,KAAK,GAAG,OAAO,CAAC,KAAK,IAAI,CAAC,OAAO,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,qBAAqB,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,IAAI,uBAAuB,CAAC;IAC/I,CAAC;IAED,sFAAsF;IACtF,IAAI,YAAY;QACf,OAAO,IAAI,CAAC,MAAM,CAAC;IACpB,CAAC;IAED,yFAAyF;IACzF,KAAK,CAAC,QAAQ;QACb,MAAM,UAAU,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,eAAe,EAAE,CAAC;QACzD,IAAI,CAAC,MAAM,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC;YACzC,OAAO,EAAE,IAAI,CAAC,QAAQ,CAAC,OAAO;YAC9B,IAAI,EAAE,IAAI,CAAC,EAAE;YACb,UAAU;YACV,GAAG,EAAE,IAAI,CAAC,KAAK;SACf,CAAC,CAAC;QACH,OAAO,IAAI,CAAC,MAAM,CAAC;IACpB,CAAC;IAED,yFAAyF;IACzF,KAAK,CAAC,KAAK;QACV,IAAI,IAAI,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;YAC/B,OAAO;QACR,CAAC;QACD,MAAM,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACvC,CAAC;IAED,mGAAmG;IACnG,KAAK,CAAC,WAAW,CAAC,MAAc;QAC/B,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;QAClC,OAAO,IAAI,CAAC,QAAQ,EAAE,CAAC;IACxB,CAAC;IAED,+FAA+F;IAC/F,KAAK,CAAC,UAAU;QACf,IAAI,CAAC,QAAQ,CAAC,UAAU,EAAE,CAAC;QAC3B,OAAO,IAAI,CAAC,QAAQ,EAAE,CAAC;IACxB,CAAC;IAED;gHAC4G;IAC5G,KAAK,CAAC,QAAQ;QACb,IAAI,CAAC,QAAQ,CAAC,aAAa,EAAE,CAAC;QAC9B,IAAI,IAAI,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;YAC/B,MAAM,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAC1C,CAAC;IACF,CAAC;CACD;AAED,yGAAyG;AACzG,MAAM,uBAAuB,GAAG,MAAM,CAAC"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Matchmaking — cohort-side `QueryV1` handler (db-p2p, wires the substrate store to the query reply).
|
|
3
|
+
*
|
|
4
|
+
* `docs/matchmaking.md` §Seeker query / §Capability filter. When a seeker dials a cohort with a
|
|
5
|
+
* {@link QueryV1}, the cohort returns its **locally-known direct registrations** for the topic, with the
|
|
6
|
+
* capability filter applied. This handler is the thin db-p2p binding: it reads the cohort's local
|
|
7
|
+
* {@link RegistrationRecord}s, decodes each one's `appState` into a provider/seeker payload, and hands
|
|
8
|
+
* them to the pure db-core {@link evaluateQuery} (filter + truncation + entry building). It then
|
|
9
|
+
* attaches the substrate's `topicTraffic` snapshot, the `cohortEpoch`, and the cohort **primary's**
|
|
10
|
+
* single-member reply signature (NOT a threshold signature — the reply is advisory; the seeker
|
|
11
|
+
* re-validates each entry's `registrationSig` via `verifyProviderEntry`).
|
|
12
|
+
*
|
|
13
|
+
* The handler is transport-light on purpose: the records, traffic, epoch, and signer are all injected,
|
|
14
|
+
* so it unit-tests without a live libp2p stack (mock-tier e2e is a documented follow-on). The FRET host
|
|
15
|
+
* supplies `records = store.listByTopic(topicId)`, `topicTraffic` from the cohort `TrafficCounters`,
|
|
16
|
+
* the current `cohortEpoch`, and a `sign` bound to this node's peer key.
|
|
17
|
+
*/
|
|
18
|
+
import { type QueryReplyV1, type QueryV1, type RegistrationRecord, type TopicTrafficV1 } from "@optimystic/db-core";
|
|
19
|
+
/** Everything the {@link handleMatchmakingQuery} needs from the cohort substrate, all injected. */
|
|
20
|
+
export interface CohortQueryContext {
|
|
21
|
+
/** The cohort's local registration records for the queried topic (e.g. `store.listByTopic(topicId)`). */
|
|
22
|
+
readonly records: readonly RegistrationRecord[];
|
|
23
|
+
/** The substrate's current traffic barometer for the topic (from the cohort `TrafficCounters`). */
|
|
24
|
+
readonly topicTraffic: TopicTrafficV1;
|
|
25
|
+
/** The current cohort epoch (32 bytes). */
|
|
26
|
+
readonly cohortEpoch: Uint8Array;
|
|
27
|
+
/** Sign the canonical reply image with the cohort primary's peer key; resolves the base64url signature. */
|
|
28
|
+
readonly sign: (payload: Uint8Array) => Promise<string>;
|
|
29
|
+
/** Optional logger for records whose `appState` fails to decode (skipped, not fatal). */
|
|
30
|
+
readonly log?: (formatter: string, ...args: unknown[]) => void;
|
|
31
|
+
}
|
|
32
|
+
/** Build the advisory {@link QueryReplyV1} for `query` from the cohort's local registrations. */
|
|
33
|
+
export declare function handleMatchmakingQuery(query: QueryV1, ctx: CohortQueryContext): Promise<QueryReplyV1>;
|
|
34
|
+
//# sourceMappingURL=query-handler.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"query-handler.d.ts","sourceRoot":"","sources":["../../../src/matchmaking/query-handler.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EAON,KAAK,YAAY,EACjB,KAAK,OAAO,EACZ,KAAK,kBAAkB,EACvB,KAAK,cAAc,EACnB,MAAM,qBAAqB,CAAC;AAG7B,mGAAmG;AACnG,MAAM,WAAW,kBAAkB;IAClC,yGAAyG;IACzG,QAAQ,CAAC,OAAO,EAAE,SAAS,kBAAkB,EAAE,CAAC;IAChD,mGAAmG;IACnG,QAAQ,CAAC,YAAY,EAAE,cAAc,CAAC;IACtC,2CAA2C;IAC3C,QAAQ,CAAC,WAAW,EAAE,UAAU,CAAC;IACjC,2GAA2G;IAC3G,QAAQ,CAAC,IAAI,EAAE,CAAC,OAAO,EAAE,UAAU,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IACxD,yFAAyF;IACzF,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC;CAC/D;AAED,iGAAiG;AACjG,wBAAsB,sBAAsB,CAAC,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,kBAAkB,GAAG,OAAO,CAAC,YAAY,CAAC,CAwC3G"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Matchmaking — cohort-side `QueryV1` handler (db-p2p, wires the substrate store to the query reply).
|
|
3
|
+
*
|
|
4
|
+
* `docs/matchmaking.md` §Seeker query / §Capability filter. When a seeker dials a cohort with a
|
|
5
|
+
* {@link QueryV1}, the cohort returns its **locally-known direct registrations** for the topic, with the
|
|
6
|
+
* capability filter applied. This handler is the thin db-p2p binding: it reads the cohort's local
|
|
7
|
+
* {@link RegistrationRecord}s, decodes each one's `appState` into a provider/seeker payload, and hands
|
|
8
|
+
* them to the pure db-core {@link evaluateQuery} (filter + truncation + entry building). It then
|
|
9
|
+
* attaches the substrate's `topicTraffic` snapshot, the `cohortEpoch`, and the cohort **primary's**
|
|
10
|
+
* single-member reply signature (NOT a threshold signature — the reply is advisory; the seeker
|
|
11
|
+
* re-validates each entry's `registrationSig` via `verifyProviderEntry`).
|
|
12
|
+
*
|
|
13
|
+
* The handler is transport-light on purpose: the records, traffic, epoch, and signer are all injected,
|
|
14
|
+
* so it unit-tests without a live libp2p stack (mock-tier e2e is a documented follow-on). The FRET host
|
|
15
|
+
* supplies `records = store.listByTopic(topicId)`, `topicTraffic` from the cohort `TrafficCounters`,
|
|
16
|
+
* the current `cohortEpoch`, and a `sign` bound to this node's peer key.
|
|
17
|
+
*/
|
|
18
|
+
import { bytesToB64url, decodeMatchAppPayload, evaluateQuery, queryReplySigningPayload, } from "@optimystic/db-core";
|
|
19
|
+
import { bytesToPeerIdString } from "../cohort-topic/peer-codec.js";
|
|
20
|
+
/** Build the advisory {@link QueryReplyV1} for `query` from the cohort's local registrations. */
|
|
21
|
+
export async function handleMatchmakingQuery(query, ctx) {
|
|
22
|
+
const providers = [];
|
|
23
|
+
const seekers = [];
|
|
24
|
+
for (const rec of ctx.records) {
|
|
25
|
+
if (rec.appState === undefined) {
|
|
26
|
+
continue;
|
|
27
|
+
}
|
|
28
|
+
const participantId = bytesToPeerIdString(rec.participantId);
|
|
29
|
+
let payload;
|
|
30
|
+
try {
|
|
31
|
+
payload = decodeMatchAppPayload(rec.appState);
|
|
32
|
+
}
|
|
33
|
+
catch (err) {
|
|
34
|
+
// A record whose appState isn't a matchmaking payload (or is malformed) is not ours to serve;
|
|
35
|
+
// skip it rather than fail the whole reply. Logged so it is never silently swallowed.
|
|
36
|
+
ctx.log?.("matchmaking query handler: skipping undecodable record for %s: %o", participantId, err);
|
|
37
|
+
continue;
|
|
38
|
+
}
|
|
39
|
+
if (payload.kind === "match-provider") {
|
|
40
|
+
providers.push({ participantId, attachedAt: rec.attachedAt, payload });
|
|
41
|
+
}
|
|
42
|
+
else {
|
|
43
|
+
seekers.push({ participantId, attachedAt: rec.attachedAt, payload });
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
const evaluated = evaluateQuery(query, providers, seekers);
|
|
47
|
+
const unsigned = {
|
|
48
|
+
v: 1,
|
|
49
|
+
truncated: evaluated.truncated,
|
|
50
|
+
cohortEpoch: bytesToB64url(ctx.cohortEpoch),
|
|
51
|
+
topicTraffic: ctx.topicTraffic,
|
|
52
|
+
};
|
|
53
|
+
if (evaluated.providers !== undefined) {
|
|
54
|
+
unsigned.providers = evaluated.providers;
|
|
55
|
+
}
|
|
56
|
+
if (evaluated.seekers !== undefined) {
|
|
57
|
+
unsigned.seekers = evaluated.seekers;
|
|
58
|
+
}
|
|
59
|
+
const signature = await ctx.sign(queryReplySigningPayload(unsigned));
|
|
60
|
+
return { ...unsigned, signature };
|
|
61
|
+
}
|
|
62
|
+
//# sourceMappingURL=query-handler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"query-handler.js","sourceRoot":"","sources":["../../../src/matchmaking/query-handler.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EACN,aAAa,EACb,qBAAqB,EACrB,aAAa,EACb,wBAAwB,GAOxB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,mBAAmB,EAAE,MAAM,+BAA+B,CAAC;AAgBpE,iGAAiG;AACjG,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAAC,KAAc,EAAE,GAAuB;IACnF,MAAM,SAAS,GAAgC,EAAE,CAAC;IAClD,MAAM,OAAO,GAA8B,EAAE,CAAC;IAE9C,KAAK,MAAM,GAAG,IAAI,GAAG,CAAC,OAAO,EAAE,CAAC;QAC/B,IAAI,GAAG,CAAC,QAAQ,KAAK,SAAS,EAAE,CAAC;YAChC,SAAS;QACV,CAAC;QACD,MAAM,aAAa,GAAG,mBAAmB,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;QAC7D,IAAI,OAAO,CAAC;QACZ,IAAI,CAAC;YACJ,OAAO,GAAG,qBAAqB,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QAC/C,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACd,8FAA8F;YAC9F,sFAAsF;YACtF,GAAG,CAAC,GAAG,EAAE,CAAC,mEAAmE,EAAE,aAAa,EAAE,GAAG,CAAC,CAAC;YACnG,SAAS;QACV,CAAC;QACD,IAAI,OAAO,CAAC,IAAI,KAAK,gBAAgB,EAAE,CAAC;YACvC,SAAS,CAAC,IAAI,CAAC,EAAE,aAAa,EAAE,UAAU,EAAE,GAAG,CAAC,UAAU,EAAE,OAAO,EAAE,CAAC,CAAC;QACxE,CAAC;aAAM,CAAC;YACP,OAAO,CAAC,IAAI,CAAC,EAAE,aAAa,EAAE,UAAU,EAAE,GAAG,CAAC,UAAU,EAAE,OAAO,EAAE,CAAC,CAAC;QACtE,CAAC;IACF,CAAC;IAED,MAAM,SAAS,GAAG,aAAa,CAAC,KAAK,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC;IAC3D,MAAM,QAAQ,GAAoC;QACjD,CAAC,EAAE,CAAC;QACJ,SAAS,EAAE,SAAS,CAAC,SAAS;QAC9B,WAAW,EAAE,aAAa,CAAC,GAAG,CAAC,WAAW,CAAC;QAC3C,YAAY,EAAE,GAAG,CAAC,YAAY;KAC9B,CAAC;IACF,IAAI,SAAS,CAAC,SAAS,KAAK,SAAS,EAAE,CAAC;QACvC,QAAQ,CAAC,SAAS,GAAG,SAAS,CAAC,SAAS,CAAC;IAC1C,CAAC;IACD,IAAI,SAAS,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC;QACrC,QAAQ,CAAC,OAAO,GAAG,SAAS,CAAC,OAAO,CAAC;IACtC,CAAC;IACD,MAAM,SAAS,GAAG,MAAM,GAAG,CAAC,IAAI,CAAC,wBAAwB,CAAC,QAAQ,CAAC,CAAC,CAAC;IACrE,OAAO,EAAE,GAAG,QAAQ,EAAE,SAAS,EAAE,CAAC;AACnC,CAAC"}
|