@optimystic/db-p2p 0.24.2 → 0.25.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (249) hide show
  1. package/{readme.md → README.md} +688 -668
  2. package/dist/src/cluster/block-transfer-service.d.ts +133 -10
  3. package/dist/src/cluster/block-transfer-service.d.ts.map +1 -1
  4. package/dist/src/cluster/block-transfer-service.js +155 -9
  5. package/dist/src/cluster/block-transfer-service.js.map +1 -1
  6. package/dist/src/cluster/block-transfer.d.ts +67 -7
  7. package/dist/src/cluster/block-transfer.d.ts.map +1 -1
  8. package/dist/src/cluster/block-transfer.js +127 -24
  9. package/dist/src/cluster/block-transfer.js.map +1 -1
  10. package/dist/src/cluster/certified-claims.d.ts +170 -0
  11. package/dist/src/cluster/certified-claims.d.ts.map +1 -0
  12. package/dist/src/cluster/certified-claims.js +200 -0
  13. package/dist/src/cluster/certified-claims.js.map +1 -0
  14. package/dist/src/cluster/client-signature-verifier.d.ts +23 -0
  15. package/dist/src/cluster/client-signature-verifier.d.ts.map +1 -0
  16. package/dist/src/cluster/client-signature-verifier.js +33 -0
  17. package/dist/src/cluster/client-signature-verifier.js.map +1 -0
  18. package/dist/src/cluster/cluster-policy.d.ts +9 -3
  19. package/dist/src/cluster/cluster-policy.d.ts.map +1 -1
  20. package/dist/src/cluster/cluster-policy.js +111 -27
  21. package/dist/src/cluster/cluster-policy.js.map +1 -1
  22. package/dist/src/cluster/cluster-repo.d.ts +140 -11
  23. package/dist/src/cluster/cluster-repo.d.ts.map +1 -1
  24. package/dist/src/cluster/cluster-repo.js +485 -29
  25. package/dist/src/cluster/cluster-repo.js.map +1 -1
  26. package/dist/src/cluster/commit-proof.d.ts +134 -0
  27. package/dist/src/cluster/commit-proof.d.ts.map +1 -0
  28. package/dist/src/cluster/commit-proof.js +263 -0
  29. package/dist/src/cluster/commit-proof.js.map +1 -0
  30. package/dist/src/cluster/quorum-restore.d.ts +95 -8
  31. package/dist/src/cluster/quorum-restore.d.ts.map +1 -1
  32. package/dist/src/cluster/quorum-restore.js +113 -14
  33. package/dist/src/cluster/quorum-restore.js.map +1 -1
  34. package/dist/src/cluster/rebalance-monitor.d.ts +84 -0
  35. package/dist/src/cluster/rebalance-monitor.d.ts.map +1 -1
  36. package/dist/src/cluster/rebalance-monitor.js +207 -5
  37. package/dist/src/cluster/rebalance-monitor.js.map +1 -1
  38. package/dist/src/cluster/reconcile-block.d.ts +27 -7
  39. package/dist/src/cluster/reconcile-block.d.ts.map +1 -1
  40. package/dist/src/cluster/reconcile-block.js +179 -38
  41. package/dist/src/cluster/reconcile-block.js.map +1 -1
  42. package/dist/src/cluster/service.d.ts +13 -4
  43. package/dist/src/cluster/service.d.ts.map +1 -1
  44. package/dist/src/cluster/service.js +17 -18
  45. package/dist/src/cluster/service.js.map +1 -1
  46. package/dist/src/cluster/spread-on-churn.d.ts +8 -2
  47. package/dist/src/cluster/spread-on-churn.d.ts.map +1 -1
  48. package/dist/src/cluster/spread-on-churn.js +7 -7
  49. package/dist/src/cluster/spread-on-churn.js.map +1 -1
  50. package/dist/src/cohort-topic/host.d.ts.map +1 -1
  51. package/dist/src/cohort-topic/host.js +8 -7
  52. package/dist/src/cohort-topic/host.js.map +1 -1
  53. package/dist/src/cohort-topic/stream-util.d.ts +7 -6
  54. package/dist/src/cohort-topic/stream-util.d.ts.map +1 -1
  55. package/dist/src/cohort-topic/stream-util.js +14 -41
  56. package/dist/src/cohort-topic/stream-util.js.map +1 -1
  57. package/dist/src/dispute/cascade.d.ts +7 -8
  58. package/dist/src/dispute/cascade.d.ts.map +1 -1
  59. package/dist/src/dispute/cascade.js +24 -7
  60. package/dist/src/dispute/cascade.js.map +1 -1
  61. package/dist/src/dispute/dispute-service.d.ts +5 -0
  62. package/dist/src/dispute/dispute-service.d.ts.map +1 -1
  63. package/dist/src/dispute/dispute-service.js +13 -3
  64. package/dist/src/dispute/dispute-service.js.map +1 -1
  65. package/dist/src/dispute/invalidation.d.ts +33 -15
  66. package/dist/src/dispute/invalidation.d.ts.map +1 -1
  67. package/dist/src/dispute/invalidation.js +127 -34
  68. package/dist/src/dispute/invalidation.js.map +1 -1
  69. package/dist/src/dispute/service.d.ts.map +1 -1
  70. package/dist/src/dispute/service.js +2 -1
  71. package/dist/src/dispute/service.js.map +1 -1
  72. package/dist/src/index.d.ts +7 -0
  73. package/dist/src/index.d.ts.map +1 -1
  74. package/dist/src/index.js +7 -0
  75. package/dist/src/index.js.map +1 -1
  76. package/dist/src/libp2p-key-network.d.ts +14 -10
  77. package/dist/src/libp2p-key-network.d.ts.map +1 -1
  78. package/dist/src/libp2p-key-network.js +28 -58
  79. package/dist/src/libp2p-key-network.js.map +1 -1
  80. package/dist/src/libp2p-node-base.d.ts +38 -7
  81. package/dist/src/libp2p-node-base.d.ts.map +1 -1
  82. package/dist/src/libp2p-node-base.js +148 -63
  83. package/dist/src/libp2p-node-base.js.map +1 -1
  84. package/dist/src/network/open-protocol-stream.d.ts +56 -0
  85. package/dist/src/network/open-protocol-stream.d.ts.map +1 -0
  86. package/dist/src/network/open-protocol-stream.js +60 -0
  87. package/dist/src/network/open-protocol-stream.js.map +1 -0
  88. package/dist/src/network/register-protocol-handler.d.ts +66 -0
  89. package/dist/src/network/register-protocol-handler.d.ts.map +1 -0
  90. package/dist/src/network/register-protocol-handler.js +51 -0
  91. package/dist/src/network/register-protocol-handler.js.map +1 -0
  92. package/dist/src/peer-address-book.d.ts +60 -2
  93. package/dist/src/peer-address-book.d.ts.map +1 -1
  94. package/dist/src/peer-address-book.js +89 -1
  95. package/dist/src/peer-address-book.js.map +1 -1
  96. package/dist/src/pend-validation.d.ts +65 -0
  97. package/dist/src/pend-validation.d.ts.map +1 -0
  98. package/dist/src/pend-validation.js +69 -0
  99. package/dist/src/pend-validation.js.map +1 -0
  100. package/dist/src/reactivity/notify-transport.d.ts.map +1 -1
  101. package/dist/src/reactivity/notify-transport.js +2 -1
  102. package/dist/src/reactivity/notify-transport.js.map +1 -1
  103. package/dist/src/reactivity/push-state-gossip.d.ts.map +1 -1
  104. package/dist/src/reactivity/push-state-gossip.js +2 -1
  105. package/dist/src/reactivity/push-state-gossip.js.map +1 -1
  106. package/dist/src/repo/cluster-coordinator.d.ts +32 -6
  107. package/dist/src/repo/cluster-coordinator.d.ts.map +1 -1
  108. package/dist/src/repo/cluster-coordinator.js +44 -10
  109. package/dist/src/repo/cluster-coordinator.js.map +1 -1
  110. package/dist/src/repo/coordinator-repo.d.ts +181 -25
  111. package/dist/src/repo/coordinator-repo.d.ts.map +1 -1
  112. package/dist/src/repo/coordinator-repo.js +650 -62
  113. package/dist/src/repo/coordinator-repo.js.map +1 -1
  114. package/dist/src/repo/served-repo-proxy.d.ts +30 -0
  115. package/dist/src/repo/served-repo-proxy.d.ts.map +1 -0
  116. package/dist/src/repo/served-repo-proxy.js +50 -0
  117. package/dist/src/repo/served-repo-proxy.js.map +1 -0
  118. package/dist/src/repo/service.d.ts +16 -1
  119. package/dist/src/repo/service.d.ts.map +1 -1
  120. package/dist/src/repo/service.js +18 -16
  121. package/dist/src/repo/service.js.map +1 -1
  122. package/dist/src/reputation/types.d.ts +3 -1
  123. package/dist/src/reputation/types.d.ts.map +1 -1
  124. package/dist/src/reputation/types.js +3 -1
  125. package/dist/src/reputation/types.js.map +1 -1
  126. package/dist/src/rn.d.ts +24 -2
  127. package/dist/src/rn.d.ts.map +1 -1
  128. package/dist/src/rn.js +33 -4
  129. package/dist/src/rn.js.map +1 -1
  130. package/dist/src/storage/block-archive.d.ts +153 -0
  131. package/dist/src/storage/block-archive.d.ts.map +1 -0
  132. package/dist/src/storage/block-archive.js +194 -0
  133. package/dist/src/storage/block-archive.js.map +1 -0
  134. package/dist/src/storage/block-latch.d.ts +92 -0
  135. package/dist/src/storage/block-latch.d.ts.map +1 -0
  136. package/dist/src/storage/block-latch.js +132 -0
  137. package/dist/src/storage/block-latch.js.map +1 -0
  138. package/dist/src/storage/block-storage.d.ts +169 -12
  139. package/dist/src/storage/block-storage.d.ts.map +1 -1
  140. package/dist/src/storage/block-storage.js +415 -152
  141. package/dist/src/storage/block-storage.js.map +1 -1
  142. package/dist/src/storage/cached-raw-storage.d.ts +5 -1
  143. package/dist/src/storage/cached-raw-storage.d.ts.map +1 -1
  144. package/dist/src/storage/cached-raw-storage.js +16 -1
  145. package/dist/src/storage/cached-raw-storage.js.map +1 -1
  146. package/dist/src/storage/cached-store-driver.d.ts +14 -4
  147. package/dist/src/storage/cached-store-driver.d.ts.map +1 -1
  148. package/dist/src/storage/cached-store-driver.js +39 -5
  149. package/dist/src/storage/cached-store-driver.js.map +1 -1
  150. package/dist/src/storage/i-block-storage.d.ts +70 -19
  151. package/dist/src/storage/i-block-storage.d.ts.map +1 -1
  152. package/dist/src/storage/i-block-storage.js +21 -1
  153. package/dist/src/storage/i-block-storage.js.map +1 -1
  154. package/dist/src/storage/i-raw-storage.d.ts +38 -0
  155. package/dist/src/storage/i-raw-storage.d.ts.map +1 -1
  156. package/dist/src/storage/kv-raw-storage.d.ts +14 -8
  157. package/dist/src/storage/kv-raw-storage.d.ts.map +1 -1
  158. package/dist/src/storage/kv-raw-storage.js +29 -9
  159. package/dist/src/storage/kv-raw-storage.js.map +1 -1
  160. package/dist/src/storage/memory-store-driver.d.ts +4 -1
  161. package/dist/src/storage/memory-store-driver.d.ts.map +1 -1
  162. package/dist/src/storage/memory-store-driver.js +22 -2
  163. package/dist/src/storage/memory-store-driver.js.map +1 -1
  164. package/dist/src/storage/raw-store-codec.js +2 -2
  165. package/dist/src/storage/raw-store-driver.d.ts +44 -3
  166. package/dist/src/storage/raw-store-driver.d.ts.map +1 -1
  167. package/dist/src/storage/shared-cache-pool.d.ts +60 -3
  168. package/dist/src/storage/shared-cache-pool.d.ts.map +1 -1
  169. package/dist/src/storage/shared-cache-pool.js +68 -4
  170. package/dist/src/storage/shared-cache-pool.js.map +1 -1
  171. package/dist/src/storage/storage-repo.d.ts +204 -26
  172. package/dist/src/storage/storage-repo.d.ts.map +1 -1
  173. package/dist/src/storage/storage-repo.js +422 -119
  174. package/dist/src/storage/storage-repo.js.map +1 -1
  175. package/dist/src/storage/store-identity.d.ts +21 -0
  176. package/dist/src/storage/store-identity.d.ts.map +1 -0
  177. package/dist/src/storage/store-identity.js +33 -0
  178. package/dist/src/storage/store-identity.js.map +1 -0
  179. package/dist/src/storage/struct.d.ts +15 -0
  180. package/dist/src/storage/struct.d.ts.map +1 -1
  181. package/dist/src/storage/with-read-cache.d.ts +92 -0
  182. package/dist/src/storage/with-read-cache.d.ts.map +1 -0
  183. package/dist/src/storage/with-read-cache.js +132 -0
  184. package/dist/src/storage/with-read-cache.js.map +1 -0
  185. package/dist/src/sync/service.d.ts +13 -3
  186. package/dist/src/sync/service.d.ts.map +1 -1
  187. package/dist/src/sync/service.js +7 -30
  188. package/dist/src/sync/service.js.map +1 -1
  189. package/dist/src/testing/mesh-harness.d.ts +75 -2
  190. package/dist/src/testing/mesh-harness.d.ts.map +1 -1
  191. package/dist/src/testing/mesh-harness.js +193 -81
  192. package/dist/src/testing/mesh-harness.js.map +1 -1
  193. package/dist/src/testing/raw-storage-conformance.d.ts +8 -0
  194. package/dist/src/testing/raw-storage-conformance.d.ts.map +1 -1
  195. package/dist/src/testing/raw-storage-conformance.js +97 -2
  196. package/dist/src/testing/raw-storage-conformance.js.map +1 -1
  197. package/package.json +5 -6
  198. package/src/cluster/block-transfer-service.ts +528 -312
  199. package/src/cluster/block-transfer.ts +547 -424
  200. package/src/cluster/certified-claims.ts +319 -0
  201. package/src/cluster/client-signature-verifier.ts +34 -0
  202. package/src/cluster/cluster-policy.ts +294 -203
  203. package/src/cluster/cluster-repo.ts +2501 -2034
  204. package/src/cluster/commit-proof.ts +344 -0
  205. package/src/cluster/quorum-restore.ts +348 -223
  206. package/src/cluster/rebalance-monitor.ts +539 -254
  207. package/src/cluster/reconcile-block.ts +404 -203
  208. package/src/cluster/service.ts +23 -20
  209. package/src/cluster/spread-on-churn.ts +352 -346
  210. package/src/cohort-topic/host.ts +8 -7
  211. package/src/cohort-topic/stream-util.ts +14 -43
  212. package/src/dispute/cascade.ts +31 -15
  213. package/src/dispute/dispute-service.ts +706 -696
  214. package/src/dispute/invalidation.ts +162 -52
  215. package/src/dispute/service.ts +126 -125
  216. package/src/index.ts +7 -0
  217. package/src/libp2p-key-network.ts +1204 -1235
  218. package/src/libp2p-node-base.ts +185 -70
  219. package/src/network/open-protocol-stream.ts +87 -0
  220. package/src/network/register-protocol-handler.ts +85 -0
  221. package/src/peer-address-book.ts +96 -2
  222. package/src/pend-validation.ts +89 -0
  223. package/src/reactivity/notify-transport.ts +2 -1
  224. package/src/reactivity/push-state-gossip.ts +2 -1
  225. package/src/repo/cluster-coordinator.ts +65 -11
  226. package/src/repo/coordinator-repo.ts +729 -71
  227. package/src/repo/served-repo-proxy.ts +55 -0
  228. package/src/repo/service.ts +25 -16
  229. package/src/reputation/types.ts +3 -1
  230. package/src/rn.ts +34 -4
  231. package/src/storage/block-archive.ts +242 -0
  232. package/src/storage/block-latch.ts +144 -0
  233. package/src/storage/block-storage.ts +787 -498
  234. package/src/storage/cached-raw-storage.ts +21 -1
  235. package/src/storage/cached-store-driver.ts +898 -859
  236. package/src/storage/i-block-storage.ts +172 -116
  237. package/src/storage/i-raw-storage.ts +40 -0
  238. package/src/storage/kv-raw-storage.ts +34 -9
  239. package/src/storage/memory-store-driver.ts +26 -2
  240. package/src/storage/raw-store-codec.ts +42 -42
  241. package/src/storage/raw-store-driver.ts +45 -3
  242. package/src/storage/shared-cache-pool.ts +516 -452
  243. package/src/storage/storage-repo.ts +1421 -1014
  244. package/src/storage/store-identity.ts +41 -0
  245. package/src/storage/struct.ts +52 -34
  246. package/src/storage/with-read-cache.ts +182 -0
  247. package/src/sync/service.ts +178 -198
  248. package/src/testing/mesh-harness.ts +524 -344
  249. package/src/testing/raw-storage-conformance.ts +114 -2
@@ -0,0 +1,60 @@
1
+ /**
2
+ * The single place in `db-p2p` that opens a libp2p protocol stream.
3
+ *
4
+ * libp2p refuses to open a protocol stream over a *limited* (circuit-relay) connection unless the
5
+ * caller opts in with `runOnLimitedConnection: true`. Omitting it produces no compile error and no
6
+ * obvious failure — only "that peer never answers" — so every peer reachable only through a relay
7
+ * (the steady state for browsers, phones, and NATed peers) silently drops out. The flag is
8
+ * deliberately NOT an option here: a new call site gets relay support without its author needing to
9
+ * know the flag exists, and `test/dial-options-single-site.spec.ts` fails the build if a second
10
+ * source file calls `dialProtocol` / `newStream` directly.
11
+ *
12
+ * NOTE: accepted tradeoff — this duplicates FRET's `rpc/protocols.ts#openRpcStream` (exported since
13
+ * `p2p-fret@1.0.0-beta.3`) rather than delegating to it. FRET's helper pins `negotiateFully: false`
14
+ * with no way to opt out, and `cohort-topic/stream-util.ts` deliberately does not set that option
15
+ * (see the NOTE at its call sites); adopting FRET's would silently reverse a decision a human
16
+ * already made. It also has no hook for the pre-dial check `libp2p-key-network.ts#connect` runs.
17
+ * Revisit — and delete this module in favour of `openRpcStream` — if FRET ever parameterizes
18
+ * `negotiateFully`.
19
+ *
20
+ * Imports here are type-only on purpose: this module is reachable from the react-native entry
21
+ * (`src/rn.ts`) via `libp2p-key-network.ts`, which must not pull node-specific code.
22
+ */
23
+ /**
24
+ * True for a circuit-relay ("limited") connection: libp2p stamps one with per-circuit `limits`
25
+ * (data/duration caps); sniffing `/p2p-circuit` in the remote multiaddr covers transports and
26
+ * versions that leave `limits` unpopulated.
27
+ */
28
+ export function isLimitedConnection(c) {
29
+ if (c.limits != null)
30
+ return true;
31
+ return c.remoteAddr?.toString?.().includes("/p2p-circuit") ?? false;
32
+ }
33
+ /**
34
+ * Open `protocol` to `peer`, reusing a healthy existing connection when there is one.
35
+ *
36
+ * Skips connections libp2p has not yet evicted from its index but that are no longer open, and
37
+ * prefers a direct connection over a relayed one — a relayed connection can be reset once the
38
+ * relay's per-circuit cap or reservation lapses, and after DCUtR upgrades a link to direct both
39
+ * briefly coexist. Falls back to the relayed connection when it is the only open path.
40
+ */
41
+ export async function openProtocolStream(node, peer, protocol, options) {
42
+ // Before touching connections: a caller that has already given up is owed its own reason,
43
+ // not whatever libp2p would report several layers down.
44
+ options?.signal?.throwIfAborted();
45
+ const conns = node.getConnections?.(peer) ?? [];
46
+ const open = conns.filter(c => c?.status === "open" && typeof c?.newStream === "function");
47
+ const chosen = open.find(c => !isLimitedConnection(c)) ?? open[0];
48
+ // Keys are OMITTED rather than set to `undefined` when the caller did not supply them, so
49
+ // libp2p applies its own defaults instead of seeing an explicit `undefined`.
50
+ const streamOptions = {
51
+ runOnLimitedConnection: true,
52
+ ...(options?.negotiateFully !== undefined ? { negotiateFully: options.negotiateFully } : {}),
53
+ ...(options?.signal !== undefined ? { signal: options.signal } : {}),
54
+ };
55
+ if (chosen)
56
+ return await chosen.newStream([protocol], streamOptions);
57
+ await options?.beforeDial?.();
58
+ return await node.dialProtocol(peer, [protocol], streamOptions);
59
+ }
60
+ //# sourceMappingURL=open-protocol-stream.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"open-protocol-stream.js","sourceRoot":"","sources":["../../../src/network/open-protocol-stream.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAsBH;;;;GAIG;AACH,MAAM,UAAU,mBAAmB,CAAC,CAAa;IAChD,IAAI,CAAC,CAAC,MAAM,IAAI,IAAI;QAAE,OAAO,IAAI,CAAC;IAClC,OAAO,CAAC,CAAC,UAAU,EAAE,QAAQ,EAAE,EAAE,CAAC,QAAQ,CAAC,cAAc,CAAC,IAAI,KAAK,CAAC;AACrE,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACvC,IAAY,EACZ,IAAY,EACZ,QAAgB,EAChB,OAAmC;IAEnC,0FAA0F;IAC1F,wDAAwD;IACxD,OAAO,EAAE,MAAM,EAAE,cAAc,EAAE,CAAC;IAElC,MAAM,KAAK,GAAG,IAAI,CAAC,cAAc,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;IAChD,MAAM,IAAI,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,MAAM,IAAI,OAAO,CAAC,EAAE,SAAS,KAAK,UAAU,CAAC,CAAC;IAC3F,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,mBAAmB,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC;IAElE,0FAA0F;IAC1F,6EAA6E;IAC7E,MAAM,aAAa,GAAG;QACrB,sBAAsB,EAAE,IAAI;QAC5B,GAAG,CAAC,OAAO,EAAE,cAAc,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,cAAc,EAAE,OAAO,CAAC,cAAc,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC5F,GAAG,CAAC,OAAO,EAAE,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KACpE,CAAC;IAEF,IAAI,MAAM;QAAE,OAAO,MAAM,MAAM,CAAC,SAAS,CAAC,CAAC,QAAQ,CAAC,EAAE,aAAa,CAAC,CAAC;IACrE,MAAM,OAAO,EAAE,UAAU,EAAE,EAAE,CAAC;IAC9B,OAAO,MAAM,IAAI,CAAC,YAAY,CAAC,IAAI,EAAE,CAAC,QAAQ,CAAC,EAAE,aAAa,CAAC,CAAC;AACjE,CAAC"}
@@ -0,0 +1,66 @@
1
+ /**
2
+ * The single place in `db-p2p` that registers a libp2p protocol handler.
3
+ *
4
+ * The mirror image of `./open-protocol-stream.ts`. Opening a stream over a *limited* (circuit-relay)
5
+ * connection needs BOTH sides to opt in, and libp2p checks each side against its own options:
6
+ *
7
+ * - the dialer's `newStream` / `dialProtocol` options (`libp2p/src/connection.ts`, outbound path), and
8
+ * - the options the *answering* peer passed when it registered the handler
9
+ * (`libp2p/src/connection.ts`, incoming path — it reads back
10
+ * `registrar.getHandler(protocol).options.runOnLimitedConnection`).
11
+ *
12
+ * Miss either one and libp2p throws `LimitedConnectionError`. On the answering side it does so
13
+ * *after* multistream-select has already acknowledged the protocol, so the dialer's stream open
14
+ * appears to succeed and the stream is then reset with no reply — indistinguishable, from the
15
+ * dialer's seat, from a peer that simply does not hold the data. Every peer reachable only through
16
+ * a capped relay (phones, browsers, machines behind a home router) silently drops out.
17
+ *
18
+ * `openProtocolStream` fixed the dialling half; this fixes the answering half. As there, the flag is
19
+ * deliberately NOT an option: a new protocol gets relay support without its author needing to know
20
+ * the flag exists, and `test/dial-options-single-site.spec.ts` fails the build if a second source
21
+ * file calls `.handle(...)` directly.
22
+ *
23
+ * Accepting the stream is necessary but not sufficient. A stock relay also caps the *whole* relayed
24
+ * connection — `applyDefaultLimit: true` stamps `Limit { data: 128 KiB, duration: 2 min }` on every
25
+ * reservation — so a relay-only peer now answers, but the circuit is reset once either cap is hit,
26
+ * which one cohort frame (`DEFAULT_STREAM_MAX_BYTES`, 512 KiB) can do on its own. Lifting that is
27
+ * the relay operator's knob, not this one: see `NodeOptions.relayServerInit` in `libp2p-node-base.ts`.
28
+ *
29
+ * Imports here are type-only on purpose: this module is reachable from the react-native entry
30
+ * (`src/rn.ts`), which must not pull node-specific code.
31
+ */
32
+ import type { StreamHandler, StreamHandlerOptions, StreamMiddleware } from "@libp2p/interface";
33
+ /**
34
+ * Anything that can register a libp2p protocol handler.
35
+ *
36
+ * Both shapes in this package satisfy it: a `Libp2p` node (`node.handle(...)`) and the `registrar`
37
+ * component the service classes are constructed with (`components.registrar.handle(...)`).
38
+ */
39
+ export interface ProtocolRegistrar {
40
+ handle(protocol: string, handler: StreamHandler, options?: StreamHandlerOptions): Promise<void>;
41
+ }
42
+ /**
43
+ * The per-protocol settings that legitimately vary. `runOnLimitedConnection` is absent on purpose —
44
+ * it is a constant of this helper, not a caller's choice.
45
+ */
46
+ export interface RegisterProtocolHandlerOptions {
47
+ /** Concurrent inbound streams allowed per connection. Omit for libp2p's default (32). */
48
+ maxInboundStreams?: number;
49
+ /** Concurrent outbound streams allowed per connection. Omit for libp2p's default (64). */
50
+ maxOutboundStreams?: number;
51
+ /** Stream middleware, run around the handler. Omit for none. */
52
+ middleware?: StreamMiddleware[];
53
+ /** Replace an existing registration for this protocol instead of rejecting. */
54
+ force?: true;
55
+ /** Forwarded to libp2p so a caller's deadline cancels the registration. */
56
+ signal?: AbortSignal;
57
+ }
58
+ /**
59
+ * Register `handler` for `protocol`, accepting streams over limited (relay) connections.
60
+ *
61
+ * Rejects if the registrar rejects — a duplicate protocol id, or an aborted signal. Callers that
62
+ * register fire-and-forget (`void registerProtocolHandler(...)`) keep that behaviour; see the NOTE
63
+ * in `libp2p-node-base.ts` about the reactivity handlers.
64
+ */
65
+ export declare function registerProtocolHandler(target: ProtocolRegistrar, protocol: string, handler: StreamHandler, options?: RegisterProtocolHandlerOptions): Promise<void>;
66
+ //# sourceMappingURL=register-protocol-handler.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"register-protocol-handler.d.ts","sourceRoot":"","sources":["../../../src/network/register-protocol-handler.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,oBAAoB,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAE/F;;;;;GAKG;AACH,MAAM,WAAW,iBAAiB;IACjC,MAAM,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,aAAa,EAAE,OAAO,CAAC,EAAE,oBAAoB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAChG;AAED;;;GAGG;AACH,MAAM,WAAW,8BAA8B;IAC9C,yFAAyF;IACzF,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,0FAA0F;IAC1F,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,gEAAgE;IAChE,UAAU,CAAC,EAAE,gBAAgB,EAAE,CAAC;IAChC,+EAA+E;IAC/E,KAAK,CAAC,EAAE,IAAI,CAAC;IACb,2EAA2E;IAC3E,MAAM,CAAC,EAAE,WAAW,CAAC;CACrB;AAED;;;;;;GAMG;AACH,wBAAsB,uBAAuB,CAC5C,MAAM,EAAE,iBAAiB,EACzB,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,aAAa,EACtB,OAAO,CAAC,EAAE,8BAA8B,GACtC,OAAO,CAAC,IAAI,CAAC,CAWf"}
@@ -0,0 +1,51 @@
1
+ /**
2
+ * The single place in `db-p2p` that registers a libp2p protocol handler.
3
+ *
4
+ * The mirror image of `./open-protocol-stream.ts`. Opening a stream over a *limited* (circuit-relay)
5
+ * connection needs BOTH sides to opt in, and libp2p checks each side against its own options:
6
+ *
7
+ * - the dialer's `newStream` / `dialProtocol` options (`libp2p/src/connection.ts`, outbound path), and
8
+ * - the options the *answering* peer passed when it registered the handler
9
+ * (`libp2p/src/connection.ts`, incoming path — it reads back
10
+ * `registrar.getHandler(protocol).options.runOnLimitedConnection`).
11
+ *
12
+ * Miss either one and libp2p throws `LimitedConnectionError`. On the answering side it does so
13
+ * *after* multistream-select has already acknowledged the protocol, so the dialer's stream open
14
+ * appears to succeed and the stream is then reset with no reply — indistinguishable, from the
15
+ * dialer's seat, from a peer that simply does not hold the data. Every peer reachable only through
16
+ * a capped relay (phones, browsers, machines behind a home router) silently drops out.
17
+ *
18
+ * `openProtocolStream` fixed the dialling half; this fixes the answering half. As there, the flag is
19
+ * deliberately NOT an option: a new protocol gets relay support without its author needing to know
20
+ * the flag exists, and `test/dial-options-single-site.spec.ts` fails the build if a second source
21
+ * file calls `.handle(...)` directly.
22
+ *
23
+ * Accepting the stream is necessary but not sufficient. A stock relay also caps the *whole* relayed
24
+ * connection — `applyDefaultLimit: true` stamps `Limit { data: 128 KiB, duration: 2 min }` on every
25
+ * reservation — so a relay-only peer now answers, but the circuit is reset once either cap is hit,
26
+ * which one cohort frame (`DEFAULT_STREAM_MAX_BYTES`, 512 KiB) can do on its own. Lifting that is
27
+ * the relay operator's knob, not this one: see `NodeOptions.relayServerInit` in `libp2p-node-base.ts`.
28
+ *
29
+ * Imports here are type-only on purpose: this module is reachable from the react-native entry
30
+ * (`src/rn.ts`), which must not pull node-specific code.
31
+ */
32
+ /**
33
+ * Register `handler` for `protocol`, accepting streams over limited (relay) connections.
34
+ *
35
+ * Rejects if the registrar rejects — a duplicate protocol id, or an aborted signal. Callers that
36
+ * register fire-and-forget (`void registerProtocolHandler(...)`) keep that behaviour; see the NOTE
37
+ * in `libp2p-node-base.ts` about the reactivity handlers.
38
+ */
39
+ export async function registerProtocolHandler(target, protocol, handler, options) {
40
+ // Keys are OMITTED rather than set to `undefined` when the caller did not supply them, so
41
+ // libp2p applies its own defaults instead of seeing an explicit `undefined`.
42
+ await target.handle(protocol, handler, {
43
+ runOnLimitedConnection: true,
44
+ ...(options?.maxInboundStreams !== undefined ? { maxInboundStreams: options.maxInboundStreams } : {}),
45
+ ...(options?.maxOutboundStreams !== undefined ? { maxOutboundStreams: options.maxOutboundStreams } : {}),
46
+ ...(options?.middleware !== undefined ? { middleware: options.middleware } : {}),
47
+ ...(options?.force !== undefined ? { force: options.force } : {}),
48
+ ...(options?.signal !== undefined ? { signal: options.signal } : {}),
49
+ });
50
+ }
51
+ //# sourceMappingURL=register-protocol-handler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"register-protocol-handler.js","sourceRoot":"","sources":["../../../src/network/register-protocol-handler.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AA+BH;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAC5C,MAAyB,EACzB,QAAgB,EAChB,OAAsB,EACtB,OAAwC;IAExC,0FAA0F;IAC1F,6EAA6E;IAC7E,MAAM,MAAM,CAAC,MAAM,CAAC,QAAQ,EAAE,OAAO,EAAE;QACtC,sBAAsB,EAAE,IAAI;QAC5B,GAAG,CAAC,OAAO,EAAE,iBAAiB,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,iBAAiB,EAAE,OAAO,CAAC,iBAAiB,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACrG,GAAG,CAAC,OAAO,EAAE,kBAAkB,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,kBAAkB,EAAE,OAAO,CAAC,kBAAkB,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACxG,GAAG,CAAC,OAAO,EAAE,UAAU,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,OAAO,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAChF,GAAG,CAAC,OAAO,EAAE,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACjE,GAAG,CAAC,OAAO,EAAE,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KACpE,CAAC,CAAC;AACJ,CAAC"}
@@ -21,13 +21,20 @@ export declare const MAX_MERGED_ADDRS_PER_PEER = 8;
21
21
  * peers — single digits — so this is generous margin, not a functional limit.
22
22
  */
23
23
  export declare const MAX_LEARNED_PEERS_PER_RECORD = 64;
24
- /** The narrow slice of libp2p this module needs — a peer id and (optionally) a peerStore writer. */
24
+ /** The narrow slice of libp2p this module needs — a peer id and (optionally) a peerStore. */
25
25
  export interface PeerAddressBookHost {
26
26
  peerId: PeerId;
27
27
  peerStore?: {
28
28
  merge?: (id: PeerId, data: {
29
29
  multiaddrs: Multiaddr[];
30
30
  }) => Promise<unknown>;
31
+ get?: (id: PeerId) => Promise<{
32
+ addresses?: Array<{
33
+ multiaddr: {
34
+ toString(): string;
35
+ };
36
+ }>;
37
+ }>;
31
38
  };
32
39
  }
33
40
  /** Log sink shaped like both `debug` loggers and libp2p's `Logger`. */
@@ -68,9 +75,60 @@ export interface DirectionalConnection {
68
75
  * that merges it. So the cure has to be here, at the producer.
69
76
  *
70
77
  * An inbound-only peer loses nothing by this: its own advertised addresses reach us through
71
- * `identify`/`identifyPush` and are published from the peerStore instead.
78
+ * `identify`/`identifyPush` and are published from the peerStore instead — see
79
+ * {@link publishableAddrsForPeer}, which is where the two halves are joined.
80
+ *
81
+ * NOTE: accepted tradeoff — making an INBOUND connection's `remoteAddr` publishable when it is a
82
+ * circuit address was proposed (the "at least a relayed dialer has a real address" reading) and
83
+ * declined. Read from `@libp2p/circuit-relay-v2@4.1.3` as vendored under
84
+ * `packages/db-p2p/node_modules`: the destination side composes that address as
85
+ * `ourConnectionToTheRelay.remoteAddr` encapsulated with `/p2p-circuit/p2p/<dialer>`
86
+ * (`dist/src/transport/index.js:272`), so the relay it names is the one WE hold a reservation
87
+ * with, not one the dialer is reachable on. A relay's `handleConnect` requires a reservation for
88
+ * the DESTINATION only (`dist/src/server/index.js:219-222`, status `NO_RESERVATION`) — a dialer
89
+ * needs none — so a third party dialing that composed address reaches the dialer only if the
90
+ * dialer coincidentally also holds a reservation on our relay, which nothing establishes. When our
91
+ * own hop to the relay was itself inbound the prefix is an ephemeral source socket, making it
92
+ * undialable twice over. And in the one case where it would work — dialer and we share a relay —
93
+ * the dialer's genuine self-advertised circuit address has already reached us through `identify`,
94
+ * so publishing the composed form adds nothing and costs a slot against
95
+ * {@link MAX_MERGED_ADDRS_PER_PEER}. Revisit only on a MEASURED case where a peer's genuine
96
+ * circuit address reaches a third party by no other route.
72
97
  */
73
98
  export declare function publishableConnectionAddr(conn: DirectionalConnection, log: AddressLog): string | undefined;
99
+ /**
100
+ * Join the two sources of a third-party-publishable address set: the publishable half of our live
101
+ * connections, then the peer's own advertised addresses. De-duplicated, **connection-first**.
102
+ *
103
+ * The ordering is not cosmetic. An address that reaches `connectionAddrs` is one we OUTBOUND-dialed,
104
+ * so libp2p has just succeeded with it; an advertised address is one we have never tried. So the
105
+ * proven one goes first, and the recipient — which caps what it merges at
106
+ * {@link MAX_MERGED_ADDRS_PER_PEER} — keeps the proven ones when it truncates.
107
+ *
108
+ * `connectionAddrs` are already validated by {@link publishableConnectionAddr}; the advertised half
109
+ * arrives from a peerStore or a record and is put through {@link validMultiaddrStrings} here, so the
110
+ * union is uniformly carriable regardless of which side an address came from.
111
+ *
112
+ * Split out from {@link publishableAddrsForPeer} for the one caller that has already read the
113
+ * peerStore for other reasons (`findCluster`'s membership-scoped path reads protocols and addresses
114
+ * in a single `store.get` per member) and must not pay a second read to reuse the rule.
115
+ */
116
+ export declare function unionPublishableAddrs(connectionAddrs: string[], advertisedAddrs: string[], log: AddressLog): string[];
117
+ /**
118
+ * Every address we may hand a **third** party for `peerId`.
119
+ *
120
+ * The single answer to that question: `findCluster` (via {@link unionPublishableAddrs}) and all
121
+ * three redirect-address resolvers — `RepoService.getPeerAddrs`, `ClusterService.getPeerAddrs`, and
122
+ * the `getConnectionAddrs` the node wires into the cluster service — go through this one rule.
123
+ * They used to answer it two different ways, and the connections-only half was the weaker one: a
124
+ * cohort member that only ever dialed US and is reachable only through a relay has its real circuit
125
+ * address in exactly one place — the peerStore, where `identify`/`identifyPush` put it — so a
126
+ * redirect built from connections alone described it as having no address at all.
127
+ *
128
+ * A peerStore read that fails or finds nothing yields the connection-derived half rather than
129
+ * throwing: a redirect carrying half the answer is strictly better than a redirect that errors.
130
+ */
131
+ export declare function publishableAddrsForPeer(host: PeerAddressBookHost, connections: DirectionalConnection[], peerId: PeerId, log: AddressLog): Promise<string[]>;
74
132
  /**
75
133
  * How useful the addresses we hold for a peer are **to this node's own dialer**.
76
134
  *
@@ -1 +1 @@
1
- {"version":3,"file":"peer-address-book.d.ts","sourceRoot":"","sources":["../../src/peer-address-book.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAA;AAE/C,OAAO,EAA6B,KAAK,SAAS,EAAE,MAAM,yBAAyB,CAAA;AAEnF;;;;;;;GAOG;AACH,eAAO,MAAM,yBAAyB,IAAI,CAAA;AAE1C;;;;;;;;;;GAUG;AACH,eAAO,MAAM,4BAA4B,KAAK,CAAA;AAE9C,oGAAoG;AACpG,MAAM,WAAW,mBAAmB;IACnC,MAAM,EAAE,MAAM,CAAA;IACd,SAAS,CAAC,EAAE;QACX,KAAK,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE;YAAE,UAAU,EAAE,SAAS,EAAE,CAAA;SAAE,KAAK,OAAO,CAAC,OAAO,CAAC,CAAA;KAC3E,CAAA;CACD;AAED,uEAAuE;AACvE,MAAM,MAAM,UAAU,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,CAAA;AAElE;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,GAAG,EAAE,UAAU,GAAG,MAAM,EAAE,CAEhF;AAmBD;;;;;;GAMG;AACH,MAAM,WAAW,qBAAqB;IACrC,SAAS,CAAC,EAAE,SAAS,GAAG,UAAU,CAAA;IAClC,UAAU,CAAC,EAAE;QAAE,QAAQ,CAAC,EAAE,MAAM,MAAM,CAAA;KAAE,CAAA;CACxC;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,qBAAqB,EAAE,GAAG,EAAE,UAAU,GAAG,MAAM,GAAG,SAAS,CAK1G;AAED;;;;;;;;GAQG;AACH,MAAM,MAAM,eAAe,GAAG,MAAM,GAAG,iBAAiB,GAAG,UAAU,CAAA;AAErE;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,GAAG,EAAE,UAAU,GAAG,OAAO,CAY9F;AAyBD;;;;;;;;;GASG;AACH,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,UAAU,EAAE,MAAM,EAAE,GAAG,EAAE,UAAU,GAAG,eAAe,CAG7G;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,kBAAkB,CACjC,IAAI,EAAE,mBAAmB,EACzB,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,MAAM,EAAE,EACf,GAAG,EAAE,UAAU,GACb,IAAI,CAuBN;AAED,wGAAwG;AACxG,MAAM,MAAM,aAAa,GAAG,MAAM,CAAC,MAAM,EAAE;IAAE,UAAU,CAAC,EAAE,MAAM,EAAE,CAAA;CAAE,GAAG,SAAS,CAAC,CAAA;AAEjF;;;;;;;;;;;GAWG;AACH,wBAAgB,wBAAwB,CACvC,KAAK,EAAE,aAAa,GAAG,SAAS,EAChC,IAAI,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,IAAI,EAC/C,GAAG,EAAE,UAAU,EACf,MAAM,CAAC,EAAE,MAAM,GACb,IAAI,CAuBN"}
1
+ {"version":3,"file":"peer-address-book.d.ts","sourceRoot":"","sources":["../../src/peer-address-book.ts"],"names":[],"mappings":"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"}
@@ -63,7 +63,25 @@ function isCarriableMultiaddrString(addr, log) {
63
63
  * that merges it. So the cure has to be here, at the producer.
64
64
  *
65
65
  * An inbound-only peer loses nothing by this: its own advertised addresses reach us through
66
- * `identify`/`identifyPush` and are published from the peerStore instead.
66
+ * `identify`/`identifyPush` and are published from the peerStore instead — see
67
+ * {@link publishableAddrsForPeer}, which is where the two halves are joined.
68
+ *
69
+ * NOTE: accepted tradeoff — making an INBOUND connection's `remoteAddr` publishable when it is a
70
+ * circuit address was proposed (the "at least a relayed dialer has a real address" reading) and
71
+ * declined. Read from `@libp2p/circuit-relay-v2@4.1.3` as vendored under
72
+ * `packages/db-p2p/node_modules`: the destination side composes that address as
73
+ * `ourConnectionToTheRelay.remoteAddr` encapsulated with `/p2p-circuit/p2p/<dialer>`
74
+ * (`dist/src/transport/index.js:272`), so the relay it names is the one WE hold a reservation
75
+ * with, not one the dialer is reachable on. A relay's `handleConnect` requires a reservation for
76
+ * the DESTINATION only (`dist/src/server/index.js:219-222`, status `NO_RESERVATION`) — a dialer
77
+ * needs none — so a third party dialing that composed address reaches the dialer only if the
78
+ * dialer coincidentally also holds a reservation on our relay, which nothing establishes. When our
79
+ * own hop to the relay was itself inbound the prefix is an ephemeral source socket, making it
80
+ * undialable twice over. And in the one case where it would work — dialer and we share a relay —
81
+ * the dialer's genuine self-advertised circuit address has already reached us through `identify`,
82
+ * so publishing the composed form adds nothing and costs a slot against
83
+ * {@link MAX_MERGED_ADDRS_PER_PEER}. Revisit only on a MEASURED case where a peer's genuine
84
+ * circuit address reaches a third party by no other route.
67
85
  */
68
86
  export function publishableConnectionAddr(conn, log) {
69
87
  if (conn.direction !== 'outbound')
@@ -73,6 +91,76 @@ export function publishableConnectionAddr(conn, log) {
73
91
  return undefined;
74
92
  return isCarriableMultiaddrString(addr, log) ? addr : undefined;
75
93
  }
94
+ /**
95
+ * Join the two sources of a third-party-publishable address set: the publishable half of our live
96
+ * connections, then the peer's own advertised addresses. De-duplicated, **connection-first**.
97
+ *
98
+ * The ordering is not cosmetic. An address that reaches `connectionAddrs` is one we OUTBOUND-dialed,
99
+ * so libp2p has just succeeded with it; an advertised address is one we have never tried. So the
100
+ * proven one goes first, and the recipient — which caps what it merges at
101
+ * {@link MAX_MERGED_ADDRS_PER_PEER} — keeps the proven ones when it truncates.
102
+ *
103
+ * `connectionAddrs` are already validated by {@link publishableConnectionAddr}; the advertised half
104
+ * arrives from a peerStore or a record and is put through {@link validMultiaddrStrings} here, so the
105
+ * union is uniformly carriable regardless of which side an address came from.
106
+ *
107
+ * Split out from {@link publishableAddrsForPeer} for the one caller that has already read the
108
+ * peerStore for other reasons (`findCluster`'s membership-scoped path reads protocols and addresses
109
+ * in a single `store.get` per member) and must not pay a second read to reuse the rule.
110
+ */
111
+ export function unionPublishableAddrs(connectionAddrs, advertisedAddrs, log) {
112
+ return Array.from(new Set([...connectionAddrs, ...validMultiaddrStrings(advertisedAddrs, log)]));
113
+ }
114
+ /**
115
+ * Every address we may hand a **third** party for `peerId`.
116
+ *
117
+ * The single answer to that question: `findCluster` (via {@link unionPublishableAddrs}) and all
118
+ * three redirect-address resolvers — `RepoService.getPeerAddrs`, `ClusterService.getPeerAddrs`, and
119
+ * the `getConnectionAddrs` the node wires into the cluster service — go through this one rule.
120
+ * They used to answer it two different ways, and the connections-only half was the weaker one: a
121
+ * cohort member that only ever dialed US and is reachable only through a relay has its real circuit
122
+ * address in exactly one place — the peerStore, where `identify`/`identifyPush` put it — so a
123
+ * redirect built from connections alone described it as having no address at all.
124
+ *
125
+ * A peerStore read that fails or finds nothing yields the connection-derived half rather than
126
+ * throwing: a redirect carrying half the answer is strictly better than a redirect that errors.
127
+ */
128
+ export async function publishableAddrsForPeer(host, connections, peerId, log) {
129
+ const connectionAddrs = [];
130
+ for (const conn of connections) {
131
+ const addr = publishableConnectionAddr(conn, log);
132
+ if (addr !== undefined)
133
+ connectionAddrs.push(addr);
134
+ }
135
+ return unionPublishableAddrs(connectionAddrs, await advertisedAddrsForPeer(host, peerId, log), log);
136
+ }
137
+ /**
138
+ * The addresses `peerId` has advertised to us, as libp2p's peerStore holds them.
139
+ *
140
+ * A miss is the common case, not an anomaly — libp2p's `peerStore.get` THROWS for a peer it has no
141
+ * record of, and a redirect routinely names cohort members we have never met — so this logs under
142
+ * the ordinary `peer-address-book:*` tag family rather than `WARN:`, which is reserved for input we
143
+ * were handed and rejected.
144
+ *
145
+ * NOTE: this adds one `peerStore.get` per redirect target where the redirect resolvers previously
146
+ * did none. A redirect names at most `clusterSize` peers — single digits — and only fires when this
147
+ * node is NOT responsible for the key, so the reads are bounded and off the hot path. Unmeasured;
148
+ * if redirect volume ever shows up in a profile, batch the reads per payload (they are already
149
+ * issued concurrently by `Promise.all` at both call sites) rather than dropping the peerStore arm.
150
+ */
151
+ async function advertisedAddrsForPeer(host, peerId, log) {
152
+ const get = host.peerStore?.get;
153
+ if (typeof get !== 'function')
154
+ return [];
155
+ try {
156
+ const peer = await get.call(host.peerStore, peerId);
157
+ return (peer?.addresses ?? []).map(a => a.multiaddr.toString());
158
+ }
159
+ catch (err) {
160
+ log('peer-address-book:peerstore-miss peer=%s %o', peerId.toString().substring(0, 12), err);
161
+ return [];
162
+ }
163
+ }
76
164
  /**
77
165
  * Does `addr` reach its target by relaying through `relayPeerId`?
78
166
  *
@@ -1 +1 @@
1
- {"version":3,"file":"peer-address-book.js","sourceRoot":"","sources":["../../src/peer-address-book.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"peer-address-book.js","sourceRoot":"","sources":["../../src/peer-address-book.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,65 @@
1
+ import type { PendRequest, PendValidationResult, UnvalidatablePendPolicy } from "@optimystic/db-core";
2
+ /**
3
+ * Stable, greppable prefix on the failure reason a validating receiver emits when it refuses a pend
4
+ * that carries no `validation` payload (nothing to re-execute — the single-collection
5
+ * `Collection.sync` shape) under the fail-closed `unvalidatablePendPolicy: 'reject'`.
6
+ */
7
+ export declare const PEND_NOT_VALIDATABLE = "pend-not-validatable";
8
+ /**
9
+ * Stable, greppable prefix on the failure reason a validating receiver emits when the checker
10
+ * itself THREW (engine fault, missing table, parse error) rather than returning a verdict. Distinct
11
+ * from a content verdict on purpose: an operator reading a reject reason can tell "this transaction
12
+ * is wrong" from "this node could not tell".
13
+ */
14
+ export declare const VALIDATOR_FAULT = "validator-fault";
15
+ /**
16
+ * One re-check attempt: hand the pend's `validation` pair to whatever checker this tier holds
17
+ * (a `ClusterMember`'s `ITransactionValidator`, a `StorageRepo`'s `validatePend` hook) and
18
+ * return its verdict. Throwing is allowed — {@link checkPendValidation} converts a throw into a
19
+ * {@link VALIDATOR_FAULT} rejection.
20
+ */
21
+ export type PendChecker = (validation: NonNullable<PendRequest['validation']>) => Promise<PendValidationResult>;
22
+ /** Structured trace of the decision this helper took, rendered by whichever tier called it. */
23
+ export type PendValidationEvent = {
24
+ kind: 'unvalidatable';
25
+ policy: UnvalidatablePendPolicy;
26
+ } | {
27
+ kind: 'validator-fault';
28
+ error: string;
29
+ };
30
+ /**
31
+ * The fail-closed pend re-check, shared by BOTH tiers that hold a checker — `ClusterMember`
32
+ * (voting on a cluster record) and `StorageRepo` (applying a pend locally). One implementation
33
+ * rather than two mirrored copies, because the two tiers refusing with *different* prefixes or
34
+ * *different* policy semantics is a silent inconsistency nothing would catch: they are read by the
35
+ * same operator, and a member that votes approve while its own storage refuses at apply burns a
36
+ * consensus round for nothing.
37
+ *
38
+ * Two decisions live here:
39
+ *
40
+ * - **No `validation` pair** (the single-collection `Collection.sync` shape — bare transforms, so
41
+ * there is nothing to re-execute): an explicit, LOGGED policy branch on both arms, never a silent
42
+ * fall-through. `'accept'` admits it unchecked, preserving the historical behaviour; `'reject'`
43
+ * refuses with {@link PEND_NOT_VALIDATABLE}. The presence test is on the whole pair, so a sender
44
+ * cannot talk a receiver out of validating by omitting half of it.
45
+ * - **A checker that throws**: caught and turned into a {@link VALIDATOR_FAULT} rejection, never an
46
+ * escaping error. At the cluster tier an escaping throw costs the member its vote entirely —
47
+ * indistinguishable from an unreachable peer, and with no signed reason for the dispute path.
48
+ *
49
+ * NOTE: a TRANSIENT checker fault (database busy, momentary connection loss) therefore produces a
50
+ * terminal reject where a redelivery might have produced an approve. `CoordinatorRepo`'s two
51
+ * rejection classifiers confirm retryability against LOCAL storage state and never read this prose,
52
+ * so a validator-fault reject is returned as retryable only when local state independently shows a
53
+ * stale revision or a rival pending — otherwise it reaches the writer as a throw. If transient
54
+ * validator faults ever show up in practice, give the classifier an arm keyed on this prefix rather
55
+ * than reverting to a silent pass or a lost vote.
56
+ *
57
+ * @param request the pend under consideration
58
+ * @param check the tier's checker, or undefined when this node re-validates nothing (then every
59
+ * pend passes and the policy is irrelevant — a storage-only node)
60
+ * @param policy what to do with a pend that carries no `validation` pair
61
+ * @param onEvent trace sink; called on every decision this helper takes, so the two tiers log the
62
+ * same facts in their own formats
63
+ */
64
+ export declare function checkPendValidation(request: PendRequest, check: PendChecker | undefined, policy: UnvalidatablePendPolicy, onEvent: (event: PendValidationEvent) => void): Promise<PendValidationResult>;
65
+ //# sourceMappingURL=pend-validation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pend-validation.d.ts","sourceRoot":"","sources":["../../src/pend-validation.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,oBAAoB,EAAE,uBAAuB,EAAE,MAAM,qBAAqB,CAAC;AAEtG;;;;GAIG;AACH,eAAO,MAAM,oBAAoB,yBAAyB,CAAC;AAE3D;;;;;GAKG;AACH,eAAO,MAAM,eAAe,oBAAoB,CAAC;AAEjD;;;;;GAKG;AACH,MAAM,MAAM,WAAW,GAAG,CAAC,UAAU,EAAE,WAAW,CAAC,WAAW,CAAC,YAAY,CAAC,CAAC,KAAK,OAAO,CAAC,oBAAoB,CAAC,CAAC;AAEhH,+FAA+F;AAC/F,MAAM,MAAM,mBAAmB,GAC5B;IAAE,IAAI,EAAE,eAAe,CAAC;IAAC,MAAM,EAAE,uBAAuB,CAAA;CAAE,GAC1D;IAAE,IAAI,EAAE,iBAAiB,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAE9C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,wBAAsB,mBAAmB,CACxC,OAAO,EAAE,WAAW,EACpB,KAAK,EAAE,WAAW,GAAG,SAAS,EAC9B,MAAM,EAAE,uBAAuB,EAC/B,OAAO,EAAE,CAAC,KAAK,EAAE,mBAAmB,KAAK,IAAI,GAC3C,OAAO,CAAC,oBAAoB,CAAC,CAmB/B"}
@@ -0,0 +1,69 @@
1
+ /**
2
+ * Stable, greppable prefix on the failure reason a validating receiver emits when it refuses a pend
3
+ * that carries no `validation` payload (nothing to re-execute — the single-collection
4
+ * `Collection.sync` shape) under the fail-closed `unvalidatablePendPolicy: 'reject'`.
5
+ */
6
+ export const PEND_NOT_VALIDATABLE = 'pend-not-validatable';
7
+ /**
8
+ * Stable, greppable prefix on the failure reason a validating receiver emits when the checker
9
+ * itself THREW (engine fault, missing table, parse error) rather than returning a verdict. Distinct
10
+ * from a content verdict on purpose: an operator reading a reject reason can tell "this transaction
11
+ * is wrong" from "this node could not tell".
12
+ */
13
+ export const VALIDATOR_FAULT = 'validator-fault';
14
+ /**
15
+ * The fail-closed pend re-check, shared by BOTH tiers that hold a checker — `ClusterMember`
16
+ * (voting on a cluster record) and `StorageRepo` (applying a pend locally). One implementation
17
+ * rather than two mirrored copies, because the two tiers refusing with *different* prefixes or
18
+ * *different* policy semantics is a silent inconsistency nothing would catch: they are read by the
19
+ * same operator, and a member that votes approve while its own storage refuses at apply burns a
20
+ * consensus round for nothing.
21
+ *
22
+ * Two decisions live here:
23
+ *
24
+ * - **No `validation` pair** (the single-collection `Collection.sync` shape — bare transforms, so
25
+ * there is nothing to re-execute): an explicit, LOGGED policy branch on both arms, never a silent
26
+ * fall-through. `'accept'` admits it unchecked, preserving the historical behaviour; `'reject'`
27
+ * refuses with {@link PEND_NOT_VALIDATABLE}. The presence test is on the whole pair, so a sender
28
+ * cannot talk a receiver out of validating by omitting half of it.
29
+ * - **A checker that throws**: caught and turned into a {@link VALIDATOR_FAULT} rejection, never an
30
+ * escaping error. At the cluster tier an escaping throw costs the member its vote entirely —
31
+ * indistinguishable from an unreachable peer, and with no signed reason for the dispute path.
32
+ *
33
+ * NOTE: a TRANSIENT checker fault (database busy, momentary connection loss) therefore produces a
34
+ * terminal reject where a redelivery might have produced an approve. `CoordinatorRepo`'s two
35
+ * rejection classifiers confirm retryability against LOCAL storage state and never read this prose,
36
+ * so a validator-fault reject is returned as retryable only when local state independently shows a
37
+ * stale revision or a rival pending — otherwise it reaches the writer as a throw. If transient
38
+ * validator faults ever show up in practice, give the classifier an arm keyed on this prefix rather
39
+ * than reverting to a silent pass or a lost vote.
40
+ *
41
+ * @param request the pend under consideration
42
+ * @param check the tier's checker, or undefined when this node re-validates nothing (then every
43
+ * pend passes and the policy is irrelevant — a storage-only node)
44
+ * @param policy what to do with a pend that carries no `validation` pair
45
+ * @param onEvent trace sink; called on every decision this helper takes, so the two tiers log the
46
+ * same facts in their own formats
47
+ */
48
+ export async function checkPendValidation(request, check, policy, onEvent) {
49
+ if (!check) {
50
+ return { valid: true };
51
+ }
52
+ if (!request.validation) {
53
+ onEvent({ kind: 'unvalidatable', policy });
54
+ return policy === 'reject'
55
+ // Plain prose after the stable prefix: at the cluster tier this reason is fed to
56
+ // computeSigningPayload and carried as Signature.rejectReason, so it must stay a string.
57
+ ? { valid: false, reason: `${PEND_NOT_VALIDATABLE}: pend carries no transaction to re-execute` }
58
+ : { valid: true };
59
+ }
60
+ try {
61
+ return await check(request.validation);
62
+ }
63
+ catch (err) {
64
+ const error = err.message;
65
+ onEvent({ kind: 'validator-fault', error });
66
+ return { valid: false, reason: `${VALIDATOR_FAULT}: ${error}` };
67
+ }
68
+ }
69
+ //# sourceMappingURL=pend-validation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pend-validation.js","sourceRoot":"","sources":["../../src/pend-validation.ts"],"names":[],"mappings":"AAEA;;;;GAIG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG,sBAAsB,CAAC;AAE3D;;;;;GAKG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,iBAAiB,CAAC;AAejD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB,CACxC,OAAoB,EACpB,KAA8B,EAC9B,MAA+B,EAC/B,OAA6C;IAE7C,IAAI,CAAC,KAAK,EAAE,CAAC;QACZ,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;IACxB,CAAC;IACD,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,CAAC;QACzB,OAAO,CAAC,EAAE,IAAI,EAAE,eAAe,EAAE,MAAM,EAAE,CAAC,CAAC;QAC3C,OAAO,MAAM,KAAK,QAAQ;YACzB,iFAAiF;YACjF,yFAAyF;YACzF,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,oBAAoB,6CAA6C,EAAE;YAChG,CAAC,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;IACpB,CAAC;IACD,IAAI,CAAC;QACJ,OAAO,MAAM,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;IACxC,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACd,MAAM,KAAK,GAAI,GAAa,CAAC,OAAO,CAAC;QACrC,OAAO,CAAC,EAAE,IAAI,EAAE,iBAAiB,EAAE,KAAK,EAAE,CAAC,CAAC;QAC5C,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,eAAe,KAAK,KAAK,EAAE,EAAE,CAAC;IACjE,CAAC;AACF,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"notify-transport.d.ts","sourceRoot":"","sources":["../../../src/reactivity/notify-transport.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAEnE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAWrC,wGAAwG;AACxG,MAAM,WAAW,yBAAyB;IACzC;;;;OAIG;IACH,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACvD,wFAAwF;IACxF,cAAc,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,OAAO,EAAE,CAAC,EAAE,cAAc,KAAK,IAAI,GAAG,MAAM,IAAI,CAAC;IAChF,mFAAmF;IACnF,OAAO,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,GAAG,IAAI,CAAC;CACrD;AAED,wEAAwE;AACxE,MAAM,WAAW,gCAAgC;IAChD,sEAAsE;IACtE,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;IACjC,gGAAgG;IAChG,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,2GAA2G;IAC3G,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED;;;;;GAKG;AACH,qBAAa,+BAAgC,YAAW,yBAAyB;IAMpE,OAAO,CAAC,QAAQ,CAAC,IAAI;IALjC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAyD;IAClF,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAS;IACxC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAClC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAS;gBAER,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,gCAAqC;IAMzF,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC;IAkBtD,cAAc,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,OAAO,EAAE,CAAC,EAAE,cAAc,KAAK,IAAI,GAAG,MAAM,IAAI;IAK/E,mFAAmF;IACnF,OAAO,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,GAAG,IAAI;CAcpD;AAED;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CACpC,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,yBAAyB,EACpC,QAAQ,SAA2B,GACjC,IAAI,CAgBN"}
1
+ {"version":3,"file":"notify-transport.d.ts","sourceRoot":"","sources":["../../../src/reactivity/notify-transport.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAEnE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAYrC,wGAAwG;AACxG,MAAM,WAAW,yBAAyB;IACzC;;;;OAIG;IACH,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACvD,wFAAwF;IACxF,cAAc,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,OAAO,EAAE,CAAC,EAAE,cAAc,KAAK,IAAI,GAAG,MAAM,IAAI,CAAC;IAChF,mFAAmF;IACnF,OAAO,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,GAAG,IAAI,CAAC;CACrD;AAED,wEAAwE;AACxE,MAAM,WAAW,gCAAgC;IAChD,sEAAsE;IACtE,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;IACjC,gGAAgG;IAChG,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,2GAA2G;IAC3G,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED;;;;;GAKG;AACH,qBAAa,+BAAgC,YAAW,yBAAyB;IAMpE,OAAO,CAAC,QAAQ,CAAC,IAAI;IALjC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAyD;IAClF,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAS;IACxC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAClC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAS;gBAER,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,gCAAqC;IAMzF,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC;IAkBtD,cAAc,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,OAAO,EAAE,CAAC,EAAE,cAAc,KAAK,IAAI,GAAG,MAAM,IAAI;IAK/E,mFAAmF;IACnF,OAAO,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,GAAG,IAAI;CAcpD;AAED;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CACpC,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,yBAAyB,EACpC,QAAQ,SAA2B,GACjC,IAAI,CAgBN"}
@@ -23,6 +23,7 @@ import { readFramed } from "p2p-fret";
23
23
  import { peerIdToBytes } from "../cohort-topic/peer-codec.js";
24
24
  import { sendOneWay, DEFAULT_STREAM_MAX_BYTES } from "../cohort-topic/stream-util.js";
25
25
  import { PROTOCOL_REACTIVITY_NOTIFY } from "./protocols.js";
26
+ import { registerProtocolHandler } from "../network/register-protocol-handler.js";
26
27
  import { createLogger } from "../logger.js";
27
28
  const log = createLogger("reactivity-notify");
28
29
  /**
@@ -90,7 +91,7 @@ export class Libp2pReactivityNotifyTransport {
90
91
  * swallows a decode failure, so the handler never throws on the stream.
91
92
  */
92
93
  export function registerNotifyHandler(node, protocol, transport, maxBytes = DEFAULT_STREAM_MAX_BYTES) {
93
- void node.handle(protocol, (stream, connection) => {
94
+ void registerProtocolHandler(node, protocol, (stream, connection) => {
94
95
  void (async () => {
95
96
  try {
96
97
  const frame = await readFramed(stream, maxBytes);
@@ -1 +1 @@
1
- {"version":3,"file":"notify-transport.js","sourceRoot":"","sources":["../../../src/reactivity/notify-transport.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"notify-transport.js","sourceRoot":"","sources":["../../../src/reactivity/notify-transport.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAGH,OAAO,EAAE,oBAAoB,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAGjF,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACnD,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AACtC,OAAO,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AAC9D,OAAO,EAAE,UAAU,EAAE,wBAAwB,EAAE,MAAM,gCAAgC,CAAC;AACtF,OAAO,EAAE,0BAA0B,EAAE,MAAM,gBAAgB,CAAC;AAC5D,OAAO,EAAE,uBAAuB,EAAE,MAAM,yCAAyC,CAAC;AAClF,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAE5C,MAAM,GAAG,GAAG,YAAY,CAAC,mBAAmB,CAAC,CAAC;AA0B9C;;;;;GAKG;AACH,MAAM,OAAO,+BAA+B;IAMd;IALZ,QAAQ,GAAG,IAAI,GAAG,EAA8C,CAAC;IACjE,cAAc,CAAS;IACvB,QAAQ,CAAS;IACjB,UAAU,CAAU;IAErC,YAA6B,IAAY,EAAE,UAA4C,EAAE;QAA5D,SAAI,GAAJ,IAAI,CAAQ;QACxC,IAAI,CAAC,cAAc,GAAG,OAAO,CAAC,cAAc,IAAI,0BAA0B,CAAC;QAC3E,IAAI,CAAC,QAAQ,GAAG,OAAO,CAAC,QAAQ,IAAI,wBAAwB,CAAC;QAC7D,IAAI,CAAC,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC;IACtC,CAAC;IAED,IAAI,CAAC,MAAc,EAAE,CAAiB;QACrC,IAAI,IAAI,CAAC,UAAU,KAAK,SAAS,IAAI,MAAM,KAAK,IAAI,CAAC,UAAU,EAAE,CAAC;YACjE,0FAA0F;YAC1F,OAAO,OAAO,CAAC,OAAO,EAAE,CAAC;QAC1B,CAAC;QACD,IAAI,CAAC;YACJ,MAAM,KAAK,GAAG,oBAAoB,CAAC,CAAC,CAAC,CAAC;YACtC,OAAO,UAAU,CAAC,IAAI,CAAC,IAAI,EAAE,gBAAgB,CAAC,MAAM,CAAC,EAAE,IAAI,CAAC,cAAc,EAAE,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,GAAY,EAAE,EAAE;gBACzG,mGAAmG;gBACnG,GAAG,CAAC,mCAAmC,EAAE,MAAM,EAAE,GAAG,CAAC,CAAC;YACvD,CAAC,CAAC,CAAC;QACJ,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACd,gGAAgG;YAChG,GAAG,CAAC,0BAA0B,EAAE,MAAM,EAAE,GAAG,CAAC,CAAC;YAC7C,OAAO,OAAO,CAAC,OAAO,EAAE,CAAC;QAC1B,CAAC;IACF,CAAC;IAED,cAAc,CAAC,OAAmD;QACjE,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QAC3B,OAAO,GAAG,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IAC5C,CAAC;IAED,mFAAmF;IACnF,OAAO,CAAC,UAAkB,EAAE,KAAiB;QAC5C,IAAI,CAAiB,CAAC;QACtB,IAAI,CAAC;YACJ,CAAC,GAAG,oBAAoB,CAAC,KAAK,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;QAChD,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACd,0EAA0E;YAC1E,GAAG,CAAC,kDAAkD,EAAE,UAAU,EAAE,GAAG,CAAC,CAAC;YACzE,OAAO;QACR,CAAC;QACD,MAAM,IAAI,GAAY,EAAE,EAAE,EAAE,aAAa,CAAC,UAAU,CAAC,EAAE,CAAC;QACxD,KAAK,MAAM,OAAO,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YACrC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;QAClB,CAAC;IACF,CAAC;CACD;AAED;;;;;;GAMG;AACH,MAAM,UAAU,qBAAqB,CACpC,IAAY,EACZ,QAAgB,EAChB,SAAoC,EACpC,QAAQ,GAAG,wBAAwB;IAEnC,KAAK,uBAAuB,CAAC,IAAI,EAAE,QAAQ,EAAE,CAAC,MAAc,EAAE,UAAsB,EAAE,EAAE;QACvF,KAAK,CAAC,KAAK,IAAmB,EAAE;YAC/B,IAAI,CAAC;gBACJ,MAAM,KAAK,GAAG,MAAM,UAAU,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;gBACjD,SAAS,CAAC,OAAO,CAAC,UAAU,CAAC,UAAU,CAAC,QAAQ,EAAE,EAAE,KAAK,CAAC,CAAC;gBAC3D,MAAM,MAAM,CAAC,KAAK,EAAE,CAAC;YACtB,CAAC;YAAC,MAAM,CAAC;gBACR,IAAI,CAAC;oBACJ,MAAM,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,wCAAwC,CAAC,CAAC,CAAC;gBACnE,CAAC;gBAAC,MAAM,CAAC;oBACR,qBAAqB;gBACtB,CAAC;YACF,CAAC;QACF,CAAC,CAAC,EAAE,CAAC;IACN,CAAC,CAAC,CAAC;AACJ,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"push-state-gossip.d.ts","sourceRoot":"","sources":["../../../src/reactivity/push-state-gossip.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"push-state-gossip.d.ts","sourceRoot":"","sources":["../../../src/reactivity/push-state-gossip.ts"],"names":[],"mappings":"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"}