@makaio/framework 1.0.0-dev-1788511348215 → 1.0.0-dev-1788811230746

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 (300) hide show
  1. package/dist/.makaio-build.json +2 -2
  2. package/dist/adapters/config/index.d.mts +1 -1
  3. package/dist/adapters/index.d.mts +2 -2
  4. package/dist/adapters/node.d.mts +1 -1
  5. package/dist/attempt-fixtures-CnrnF5_4.mjs +1 -0
  6. package/dist/attempt-record-codec-B32Whx75.mjs +1 -0
  7. package/dist/authority-state-bootstrap-7Cgb9TR2.mjs +1 -0
  8. package/dist/bootstrap-start-client-DrvofWwi.mjs +1 -0
  9. package/dist/bus/index.d.mts +27 -9
  10. package/dist/bus/index.mjs +1 -1
  11. package/dist/bus-CobBUqjo.mjs +2 -0
  12. package/dist/bus-Uy9C3TBM.mjs +1 -0
  13. package/dist/clients/index.d.mts +1 -1
  14. package/dist/clients/managed-install.d.mts +1 -1
  15. package/dist/code-execution/worker-entry.d.mts +1 -1
  16. package/dist/{context-resolution-841T7jBI.d.mts → context-resolution-C2VBZhaR.d.mts} +5 -5
  17. package/dist/contracts/adapter/index.d.mts +2 -2
  18. package/dist/contracts/adapter/schemas/session-lineage.d.mts +1 -1
  19. package/dist/contracts/artifact/index.d.mts +2 -2
  20. package/dist/contracts/auth/index.d.mts +2 -2
  21. package/dist/contracts/automation-trigger/index.d.mts +3 -3
  22. package/dist/contracts/canonical-model/index.d.mts +1 -1
  23. package/dist/contracts/capabilities/index.d.mts +2 -2
  24. package/dist/contracts/client/index.d.mts +2 -2
  25. package/dist/contracts/code-execution/index.d.mts +1 -1
  26. package/dist/contracts/common/index.d.mts +1 -1
  27. package/dist/contracts/config/index.d.mts +1 -1
  28. package/dist/contracts/extension/index.d.mts +5 -5
  29. package/dist/contracts/facet/index.d.mts +1 -1
  30. package/dist/contracts/harness/index.d.mts +1 -1
  31. package/dist/contracts/host/index.d.mts +1 -1
  32. package/dist/contracts/index.d.mts +1254 -42
  33. package/dist/contracts/index.mjs +1 -1
  34. package/dist/contracts/materialization/index.d.mts +3 -3
  35. package/dist/contracts/model-registry/index.d.mts +1 -1
  36. package/dist/contracts/native-session-supervisor/index.d.mts +1 -1
  37. package/dist/contracts/platform/index.d.mts +1 -1
  38. package/dist/contracts/provider/index.d.mts +2 -2
  39. package/dist/contracts/reaction/index.d.mts +1 -1
  40. package/dist/contracts/session/index.d.mts +2 -2
  41. package/dist/contracts/shared/index.d.mts +2 -2
  42. package/dist/contracts/skill/index.d.mts +1 -1
  43. package/dist/contracts/telemetry/index.d.mts +1 -1
  44. package/dist/contracts/timeout/index.d.mts +1 -1
  45. package/dist/contracts/variant/index.d.mts +1 -1
  46. package/dist/contracts/worker/index.d.mts +2 -2
  47. package/dist/contracts/worker/index.mjs +1 -1
  48. package/dist/contracts/workflow/index.d.mts +2 -2
  49. package/dist/{contribution-CUHLVLsT.d.mts → contribution-Crm-mctl.d.mts} +2 -2
  50. package/dist/{definition-DyGImhyi.d.mts → definition-u_5rYQtc.d.mts} +1 -1
  51. package/dist/{detached-extension-handle-D0aI0pJA.mjs → detached-extension-handle-DAXKQT9c.mjs} +1 -1
  52. package/dist/execution-attempt-repository-Djg3qDRv.mjs +1 -0
  53. package/dist/{execution-attempt-repository-DY4KTptE.d.mts → execution-attempt-repository-OryBjQQI.d.mts} +740 -9
  54. package/dist/{execution-target-H0RWV7Py.mjs → execution-target-BcoF_oDB.mjs} +1 -1
  55. package/dist/{hook-responses-9Ywsqzzq.d.mts → hook-responses-DcapjzLb.d.mts} +1 -1
  56. package/dist/{index-C6aSnO8m.d.mts → index-9PUmCySn.d.mts} +587 -67
  57. package/dist/{index-BmilK-co2.d.mts → index-B6Kr3cxD2.d.mts} +245 -46
  58. package/dist/{index-BNzUyVwV.d.mts → index-BDDavX2S.d.mts} +2 -2
  59. package/dist/{index-DHnSLGP4.d.mts → index-BDzqNCXs.d.mts} +1 -1
  60. package/dist/{index-Wbd_syN2.d.mts → index-BTCodvXA.d.mts} +41 -36
  61. package/dist/{index-B0VO0rAl.d.mts → index-Bo3LRb2u.d.mts} +1 -1
  62. package/dist/{index-Dg11JxKZ.d.mts → index-BwccWakG.d.mts} +1 -1
  63. package/dist/{index-DHH-93YD.d.mts → index-BxTM9lY0.d.mts} +3 -3
  64. package/dist/{index-CDud4NAm.d.mts → index-CAYbui7g.d.mts} +28 -21
  65. package/dist/{index-CPRQ4dWX.d.mts → index-CBixkF0n.d.mts} +12 -0
  66. package/dist/{index-C146Eq_J.d.mts → index-CXH1Bk0W.d.mts} +3 -3
  67. package/dist/{index-BmevAPME2.d.mts → index-Cbv_3Xi12.d.mts} +1 -1
  68. package/dist/{index-DWBkiiXH.d.mts → index-CfJKwWJa.d.mts} +1 -1
  69. package/dist/{index-B0yMCJW8.d.mts → index-CgqEyk9R.d.mts} +1 -1
  70. package/dist/{index-DI2lS7VT.d.mts → index-CnGHGFMC.d.mts} +13 -13
  71. package/dist/{index-B_8bA2JW.d.mts → index-DEpAI8CY.d.mts} +1 -1
  72. package/dist/{index-CIEycZrt.d.mts → index-DIhkK4Y0.d.mts} +1 -1
  73. package/dist/{index-DNI6UF9h.d.mts → index-Df9L5wwp.d.mts} +10 -10
  74. package/dist/{index-Bqk0pJBQ2.d.mts → index-DrO6QLwf2.d.mts} +1 -1
  75. package/dist/{index-DXtQRehh.d.mts → index-DsjUnKyr.d.mts} +1 -1
  76. package/dist/{index-Cny5RvjO.d.mts → index-J-kv32zv.d.mts} +2 -2
  77. package/dist/{index-CmwAJ8-5.d.mts → index-QJW9g1mG.d.mts} +1 -1
  78. package/dist/kernel/cli/index.d.mts +2 -2
  79. package/dist/kernel/cli/register.d.mts +1 -1
  80. package/dist/kernel/extension/index.d.mts +1 -1
  81. package/dist/kernel/index.d.mts +5 -5
  82. package/dist/kernel/namespace/index.d.mts +1 -1
  83. package/dist/kernel/observability/index.d.mts +1 -1
  84. package/dist/kernel/providers/index.d.mts +1 -1
  85. package/dist/kernel/window/index.d.mts +1 -1
  86. package/dist/{lib-Cm-uEoC1.mjs → lib-271rPR7A.mjs} +1 -1
  87. package/dist/{lib-BpGvHZye.mjs → lib-RFpLjUda.mjs} +1 -1
  88. package/dist/{load-extensions-BQoXaHhR.d.mts → load-extensions-CY8ELnCp.d.mts} +1 -1
  89. package/dist/{load-extensions-DG5LvPyM.mjs → load-extensions-D9inWcDy.mjs} +1 -1
  90. package/dist/{namespace-K23m4b0n.d.mts → namespace-BkOvOAU5.d.mts} +6 -6
  91. package/dist/node/bus-server/index.d.mts +1 -1
  92. package/dist/node/bus-server/server-lifecycle.d.mts +1 -1
  93. package/dist/node/transports/index.d.mts +56 -16
  94. package/dist/node/transports/index.mjs +2 -2
  95. package/dist/package-DEYXB80d.mjs +7 -0
  96. package/dist/{package-efR90JGe.d.mts → package-eOEt1w6u.d.mts} +498 -17
  97. package/dist/package.json +1 -1
  98. package/dist/rules/index.d.mts +1 -1
  99. package/dist/rules/schemas.d.mts +1 -1
  100. package/dist/runtime-bun/index.mjs +1 -1
  101. package/dist/runtime-node/code-execution/index.d.mts +2 -2
  102. package/dist/runtime-node/extension-discovery.d.mts +1 -1
  103. package/dist/runtime-node/extension-validation.d.mts +1 -1
  104. package/dist/runtime-node/extension-validation.mjs +1 -1
  105. package/dist/runtime-node/index.d.mts +6 -6
  106. package/dist/runtime-node/index.mjs +24 -24
  107. package/dist/runtime-node/makaio-config.d.mts +1 -1
  108. package/dist/runtime-node/workflow-execution-bus-access.mjs +1 -1
  109. package/dist/runtime-node/workflow-worker/index.d.mts +2 -2
  110. package/dist/runtime-node/workflow-worker/index.mjs +1 -1
  111. package/dist/runtime-node/workflow-worker/worker-entry.d.mts +69 -9
  112. package/dist/runtime-node/workflow-worker/worker-entry.mjs +1 -1
  113. package/dist/schemas-CeHU889f.mjs +1 -0
  114. package/dist/{schemas-BCXvEWyF.d.mts → schemas-DqnA42bw.d.mts} +4 -4
  115. package/dist/{schemas-D7EeKBDJ.d.mts → schemas-DuJs6Iqj.d.mts} +4 -4
  116. package/dist/scoped-bus-DwVrmi_1.mjs +1 -0
  117. package/dist/services/adapter-runtime/index.d.mts +3 -3
  118. package/dist/services/adapter-runtime/namespace.d.mts +1 -1
  119. package/dist/services/adapter-runtime/schemas.d.mts +1 -1
  120. package/dist/services/adapter-subsystem/index.d.mts +3 -3
  121. package/dist/services/adapter-subsystem/namespace.d.mts +1 -1
  122. package/dist/services/agent-runtime/index.d.mts +2 -2
  123. package/dist/services/agent-runtime/namespace.d.mts +1 -1
  124. package/dist/services/agent-runtime/schemas.d.mts +1 -1
  125. package/dist/services/capability/index.d.mts +2 -2
  126. package/dist/services/code-execution/index.d.mts +1 -1
  127. package/dist/services/codebase/index.d.mts +2 -2
  128. package/dist/services/codebase/namespace.d.mts +1 -1
  129. package/dist/services/codebase/schemas.d.mts +1 -1
  130. package/dist/services/compression/index.d.mts +2 -2
  131. package/dist/services/compression/namespace.d.mts +1 -1
  132. package/dist/services/compression/schemas.d.mts +1 -1
  133. package/dist/services/context-rules/index.d.mts +1 -1
  134. package/dist/services/execution-target/index.d.mts +3 -3
  135. package/dist/services/execution-target/index.mjs +1 -1
  136. package/dist/services/execution-target/namespace.d.mts +1 -1
  137. package/dist/services/execution-target/namespace.mjs +1 -1
  138. package/dist/services/execution-target/schemas.d.mts +1 -1
  139. package/dist/services/execution-target/schemas.mjs +1 -1
  140. package/dist/services/filesystem/index.d.mts +1 -1
  141. package/dist/services/filesystem/namespace.d.mts +6 -6
  142. package/dist/services/filesystem/schemas.d.mts +3 -3
  143. package/dist/services/index.d.mts +48 -46
  144. package/dist/services/index.mjs +1 -1
  145. package/dist/services/log-import/browser.d.mts +2 -2
  146. package/dist/services/log-import/index.d.mts +2 -2
  147. package/dist/services/log-import/log-import.d.mts +1 -1
  148. package/dist/services/materialization/index.d.mts +1 -1
  149. package/dist/services/model-registry/index.d.mts +1 -1
  150. package/dist/services/preferences/index.d.mts +2 -2
  151. package/dist/services/preferences/schemas.d.mts +1 -1
  152. package/dist/services/preferences/storage-namespace.d.mts +2 -2
  153. package/dist/services/provider-context/index.d.mts +1 -1
  154. package/dist/services/session/handlers/index.d.mts +1 -1
  155. package/dist/services/session/index.d.mts +9 -9
  156. package/dist/services/session/messages/namespace.d.mts +1 -1
  157. package/dist/services/session/orchestrator-testing/index.d.mts +1 -1
  158. package/dist/services/session/session-events/namespace.d.mts +1 -1
  159. package/dist/services/session/storage/namespace.d.mts +1 -1
  160. package/dist/services/session/storage/schema.d.mts +1 -1
  161. package/dist/services/session/testing/orchestrator-shared.d.mts +1 -1
  162. package/dist/services/session/turns/namespace.d.mts +1 -1
  163. package/dist/services/session-editor/index.d.mts +1 -1
  164. package/dist/services/settings/index.d.mts +3 -3
  165. package/dist/services/settings/namespace.d.mts +4 -4
  166. package/dist/services/settings/storage/clients-namespace.d.mts +1 -1
  167. package/dist/services/settings/storage/index.d.mts +3 -3
  168. package/dist/services/settings/storage/providers-namespace.d.mts +1 -1
  169. package/dist/services/subagent/index.d.mts +1 -1
  170. package/dist/services/subagent-template/index.d.mts +2 -2
  171. package/dist/services/subagent-template/namespace.d.mts +1 -1
  172. package/dist/services/subagent-template/schemas.d.mts +1 -1
  173. package/dist/services/tool-approval/index.d.mts +1 -1
  174. package/dist/services/tools/index.d.mts +1 -1
  175. package/dist/services/tray-menu/index.d.mts +3 -3
  176. package/dist/services/tray-menu/namespace.d.mts +1 -1
  177. package/dist/services/tray-menu/schemas.d.mts +1 -1
  178. package/dist/services/turn/index.d.mts +1 -1
  179. package/dist/services/turn/namespace.d.mts +1 -1
  180. package/dist/services/workflow-transitions/index.d.mts +1 -1
  181. package/dist/{src-BmSQ3rlz.mjs → src-DEgV239R.mjs} +1 -1
  182. package/dist/storage/drizzle/client.d.mts +1 -1
  183. package/dist/storage/drizzle/index.d.mts +1 -1
  184. package/dist/storage/handlers/drizzle/index.d.mts +1 -1
  185. package/dist/storage/handlers/index.d.mts +1 -1
  186. package/dist/{transition-D3zUBTPc.d.mts → transition-BB138WkK.d.mts} +2 -2
  187. package/dist/{types-DcxBYlPA.d.mts → types-CR23FzmK.d.mts} +3 -3
  188. package/dist/{types-CtDGkyLx2.d.mts → types-p55qvq922.d.mts} +1 -1
  189. package/dist/ui-kernel/index.d.mts +1 -1
  190. package/dist/ui-kernel/pages/schemas.d.mts +1 -1
  191. package/dist/{view-builder-B0j9p5C0.d.mts → view-builder-qIGQrZfs.d.mts} +1 -1
  192. package/dist/worker-DPTYFyNP.mjs +1 -0
  193. package/dist/workflow-engine/execution-attempt-repository.d.mts +2 -2
  194. package/dist/workflow-engine/execution-attempt-repository.mjs +1 -1
  195. package/dist/workflow-engine/index.d.mts +396 -177
  196. package/dist/workflow-engine/index.mjs +1 -1
  197. package/dist/workflow-engine/package.d.mts +1 -1
  198. package/dist/workflow-engine/package.mjs +1 -1
  199. package/dist/workflow-engine/provider-operation.d.mts +1 -1
  200. package/dist/workflow-engine/testing/conformance.d.mts +85 -0
  201. package/dist/workflow-engine/testing/conformance.mjs +1 -0
  202. package/dist/workflow-engine/testing/index.d.mts +63 -4
  203. package/dist/workflow-engine/testing/index.mjs +1 -1
  204. package/dist/workflow-engine/testing/sqlite.d.mts +1 -1
  205. package/dist/workflow-engine/testing/sqlite.mjs +136 -39
  206. package/dist/workflow-engine/workflow-orchestrator.mjs +1 -1
  207. package/dist/workflow-worker-BW3CE0YG.mjs +2 -0
  208. package/package.json +13 -1
  209. package/dist/attempt-record-codec-dC9LSFUE.mjs +0 -1
  210. package/dist/authority-state-bootstrap-eitx6Ukn.mjs +0 -1
  211. package/dist/await-trigger-Bkg2BQfg.mjs +0 -1
  212. package/dist/bus-D6NoBhIV.mjs +0 -2
  213. package/dist/bus-UgFdHybD.mjs +0 -1
  214. package/dist/package-Cgjpm9om.mjs +0 -7
  215. package/dist/schemas-TK29KWx-.mjs +0 -1
  216. package/dist/scoped-bus-DoPmCJeM.mjs +0 -1
  217. package/dist/worker-CARV52hT.mjs +0 -1
  218. package/dist/workflow-worker-Dul-wcOR.mjs +0 -1
  219. /package/dist/{adapter-binding-CATvmGuz.d.mts → adapter-binding-D68U_Hmh.d.mts} +0 -0
  220. /package/dist/{base-orchestrator-B4YW6z_Q.d.mts → base-orchestrator-DA95InJU.d.mts} +0 -0
  221. /package/dist/{capability-service-BW1-teFU.d.mts → capability-service-s4ZYSEWc.d.mts} +0 -0
  222. /package/dist/{client-binary-version-verifier-lcv83Hq3.d.mts → client-binary-version-verifier-kd9LP9AQ.d.mts} +0 -0
  223. /package/dist/{client-BG0WX5Vz.d.mts → client-f5A-6La5.d.mts} +0 -0
  224. /package/dist/{clients-namespace-DLAjOTTb.d.mts → clients-namespace-q4PqU1cA.d.mts} +0 -0
  225. /package/dist/{config-namespace-CH7sJZ4f.d.mts → config-namespace-Cp71zTT0.d.mts} +0 -0
  226. /package/dist/{create-static-mount-DxuixuLZ.mjs → create-static-mount-CmQgA0jq.mjs} +0 -0
  227. /package/dist/{definition-BrgzUuFk.d.mts → definition-BHSzhrUf.d.mts} +0 -0
  228. /package/dist/{extension-context-QmFuHdq5.d.mts → extension-context-BmU5XKjI.d.mts} +0 -0
  229. /package/dist/{extension-discovery-Dhu3WplO.d.mts → extension-discovery-DnO7bINK.d.mts} +0 -0
  230. /package/dist/{filesystem-service-ZJ43SbBi.d.mts → filesystem-service-BBArEDPL.d.mts} +0 -0
  231. /package/dist/{index-BC-6qNeo.d.mts → index-B-zl-O-Y.d.mts} +0 -0
  232. /package/dist/{index-BfV8U4XX.d.mts → index-BB0HypzC.d.mts} +0 -0
  233. /package/dist/{index-8y4hT9WL.d.mts → index-Bf2MgOni.d.mts} +0 -0
  234. /package/dist/{index-6trZYnUP2.d.mts → index-BhOMZWZa2.d.mts} +0 -0
  235. /package/dist/{index-BkbnC65b.d.mts → index-C-cnB1Te.d.mts} +0 -0
  236. /package/dist/{index-B4svZC6L.d.mts → index-C9xVZ-gt.d.mts} +0 -0
  237. /package/dist/{index-kzIjbrS02.d.mts → index-CDLf3Fka2.d.mts} +0 -0
  238. /package/dist/{index-jxPncqWZ2.d.mts → index-COOM1j_L2.d.mts} +0 -0
  239. /package/dist/{index-BuMsrli0.d.mts → index-CPWBGotQ.d.mts} +0 -0
  240. /package/dist/{index-pvX-BIpr2.d.mts → index-CcrXttC02.d.mts} +0 -0
  241. /package/dist/{index-B5dP8rj6.d.mts → index-CkpR5sIH.d.mts} +0 -0
  242. /package/dist/{index-CmbkCxj-.d.mts → index-Co1da7YK.d.mts} +0 -0
  243. /package/dist/{index-VzLAV0Yt.d.mts → index-CrcfeFOo.d.mts} +0 -0
  244. /package/dist/{index-BM56936c.d.mts → index-CsFN2nv7.d.mts} +0 -0
  245. /package/dist/{index-CVpaGijY.d.mts → index-D-JbTXIH.d.mts} +0 -0
  246. /package/dist/{index-B-3I98nw.d.mts → index-D6RMsZko.d.mts} +0 -0
  247. /package/dist/{index-l01zsChf.d.mts → index-D94yE5Dr.d.mts} +0 -0
  248. /package/dist/{index-D037TVsm.d.mts → index-DQD2-jcL.d.mts} +0 -0
  249. /package/dist/{index-D8D-yibS2.d.mts → index-DSLTgc7h2.d.mts} +0 -0
  250. /package/dist/{index-CL0Jo1b92.d.mts → index-DSN2t48K.d.mts} +0 -0
  251. /package/dist/{index-DQ8o3JGi.d.mts → index-DW4SE_sH.d.mts} +0 -0
  252. /package/dist/{index-DgspOUa72.d.mts → index-DYHxzwok2.d.mts} +0 -0
  253. /package/dist/{index-BMRB9yhF.d.mts → index-D_sMzTvv.d.mts} +0 -0
  254. /package/dist/{index-BFWvT0NG.d.mts → index-Df1c_2PF.d.mts} +0 -0
  255. /package/dist/{index-B2Y1Wvbh.d.mts → index-Dn_SGTgp.d.mts} +0 -0
  256. /package/dist/{index-C4V8Pmi4.d.mts → index-KAAnSRZt.d.mts} +0 -0
  257. /package/dist/{index-Ek4y8M9J2.d.mts → index-NhW2h2wH2.d.mts} +0 -0
  258. /package/dist/{index-CqdMbYmR.d.mts → index-mK-rgiit.d.mts} +0 -0
  259. /package/dist/{index-BTEJfzjE.d.mts → index-xaBSwHxJ.d.mts} +0 -0
  260. /package/dist/{json-value-DPqb-SJ8.d.mts → json-value-pX6xnLGw.d.mts} +0 -0
  261. /package/dist/{jsonl-transport-Cyyh5Wje.mjs → jsonl-transport-DQIlRX_y.mjs} +0 -0
  262. /package/dist/{lib-BqV8hYtk.mjs → lib-6eNAiNK7.mjs} +0 -0
  263. /package/dist/{namespace-DknCutQZ.d.mts → namespace-2qvc6E2Y.d.mts} +0 -0
  264. /package/dist/{namespace-DBO1OzYB.d.mts → namespace-9ychTEk_.d.mts} +0 -0
  265. /package/dist/{namespace-CVFaZv8x.d.mts → namespace-BGDq7HmW.d.mts} +0 -0
  266. /package/dist/{namespace-BUYDmd0r.d.mts → namespace-CPR2xem0.d.mts} +0 -0
  267. /package/dist/{namespace-CPG6u60N.d.mts → namespace-CQEYu8az.d.mts} +0 -0
  268. /package/dist/{namespace-DqZweTbX.d.mts → namespace-CVg_cpkh.d.mts} +0 -0
  269. /package/dist/{namespace-DOezqDti.d.mts → namespace-CirognbA.d.mts} +0 -0
  270. /package/dist/{namespace-l-HG1rLF.d.mts → namespace-Cs-cOyrn.d.mts} +0 -0
  271. /package/dist/{namespace-BNp7n_gu.d.mts → namespace-CxXNlHpn.d.mts} +0 -0
  272. /package/dist/{namespace-BdAK0lD8.d.mts → namespace-DAINF1II.d.mts} +0 -0
  273. /package/dist/{namespace-B0ftHlK3.d.mts → namespace-DG0hjPcx.d.mts} +0 -0
  274. /package/dist/{namespace-BRuHzhPo.d.mts → namespace-DokogwAZ.d.mts} +0 -0
  275. /package/dist/{namespace-BGRHcrmp.d.mts → namespace-DykqxEyX.d.mts} +0 -0
  276. /package/dist/{orchestrator-shared-CNHSImNY.d.mts → orchestrator-shared-BzqqcY2z.d.mts} +0 -0
  277. /package/dist/{packages-CxPMEg8D.d.mts → packages-Cx-BwSZr.d.mts} +0 -0
  278. /package/dist/{provider-operation-DbdyFwNm.d.mts → provider-operation-B2wQST6N.d.mts} +0 -0
  279. /package/dist/{providers-namespace-CfZKp-C0.d.mts → providers-namespace-DsKTnuO1.d.mts} +0 -0
  280. /package/dist/{schema-B3Pf7JP7.d.mts → schema-zSyY22Ck.d.mts} +0 -0
  281. /package/dist/{schemas-ChmQldVH.d.mts → schemas--LAbwXvw.d.mts} +0 -0
  282. /package/dist/{schemas-CF8QwRqt.d.mts → schemas-Bk50UoMA.d.mts} +0 -0
  283. /package/dist/{schemas-bfZNpl0B.d.mts → schemas-CHRuwe18.d.mts} +0 -0
  284. /package/dist/{schemas-D7ScxLrf.d.mts → schemas-ClGDFa44.d.mts} +0 -0
  285. /package/dist/{schemas-BGvkTiCx.d.mts → schemas-CzGN0eqW.d.mts} +0 -0
  286. /package/dist/{schemas-C1mxTfd7.d.mts → schemas-D0_kfoDf.d.mts} +0 -0
  287. /package/dist/{schemas-Pe892GgN.d.mts → schemas-DmULJ7Jk.d.mts} +0 -0
  288. /package/dist/{schemas-B50oWBuj.d.mts → schemas-Dn1JDTPw.d.mts} +0 -0
  289. /package/dist/{schemas-B6Q-qdmn.d.mts → schemas-Dxvjq-Bi.d.mts} +0 -0
  290. /package/dist/{server-lifecycle-L8zja8t8.d.mts → server-lifecycle-WFZcCMwF.d.mts} +0 -0
  291. /package/dist/{session-lineage-bUkd3fqx.d.mts → session-lineage-C9kppcCa.d.mts} +0 -0
  292. /package/dist/{src-BacfeiI4.mjs → src-DIyWekjW.mjs} +0 -0
  293. /package/dist/{storage-namespace-YmE8XCCL.d.mts → storage-namespace-BWU-8rvj.d.mts} +0 -0
  294. /package/dist/{storage-namespace-definition-BsnYAPot.d.mts → storage-namespace-definition-B-8JKvzm.d.mts} +0 -0
  295. /package/dist/{types-DdpSEmTO.d.mts → types-8rMNe3AS.d.mts} +0 -0
  296. /package/dist/{types-DnK6Wa_Y.d.mts → types-BFeWU3WM.d.mts} +0 -0
  297. /package/dist/{types-tyv0B605.d.mts → types-BnPJa-C_.d.mts} +0 -0
  298. /package/dist/{types-OKJCOjme.d.mts → types-DQTCNM2i.d.mts} +0 -0
  299. /package/dist/{types-BlB23n4f.d.mts → types-DxHeL0pF.d.mts} +0 -0
  300. /package/dist/{window-registry-Pcf35cac.d.mts → window-registry-DQP5P2_0.d.mts} +0 -0
@@ -221,6 +221,17 @@ declare class HmacAuth implements TransportAuth {
221
221
  * @throws Error if authentication fails
222
222
  */
223
223
  authenticateClient(send: (message: unknown) => void): Promise<void>;
224
+ /**
225
+ * Fence a client continuation whose handshake was cleaned up or replaced.
226
+ * @param owner - Pending challenge retained for the entire handshake.
227
+ */
228
+ private assertClientOwner;
229
+ /**
230
+ * Fence server crypto completion after socket cleanup.
231
+ * @param socket - Authenticating socket.
232
+ * @param owner - Pending response retained until authentication finishes.
233
+ */
234
+ private assertServerOwner;
224
235
  /**
225
236
  * Handle incoming message during authentication phase.
226
237
  *
@@ -302,13 +313,13 @@ declare class HmacAuth implements TransportAuth {
302
313
  * characters match, enabling timing-based secret recovery. This method decodes
303
314
  * both signatures to byte arrays and uses a constant-time XOR accumulator so
304
315
  * every comparison takes the same wall-clock time regardless of the match point.
305
- * @param a - First hex signature
316
+ * @param a - Untrusted signature received from the peer
306
317
  * @param b - Second hex signature
307
318
  * @returns True when both signatures are identical
308
319
  */
309
320
  private constantTimeEqual;
310
321
  /**
311
- * Send auth result messages without masking the original auth error.
322
+ * Send negative auth results without masking the original auth error.
312
323
  *
313
324
  * Disconnect races can make `send` throw after auth already failed; callers
314
325
  * should still observe the original failure reason.
@@ -484,6 +495,17 @@ declare class E2EAuth implements TransportAuth {
484
495
  * @param send - Function to send auth messages to the client
485
496
  */
486
497
  authenticateServer(socket: WebSocketLike, send: (message: unknown) => void): Promise<void>;
498
+ /**
499
+ * Reject a client continuation whose handshake was cleaned up or replaced.
500
+ * @param owner - Pending exchange that owns the handshake.
501
+ */
502
+ private assertClientOwner;
503
+ /**
504
+ * Reject server work that outlived its socket handshake.
505
+ * @param socket - Authenticating socket.
506
+ * @param owner - Pending exchange that owns this socket handshake.
507
+ */
508
+ private assertServerOwner;
487
509
  /**
488
510
  * Handle incoming message during authentication phase.
489
511
  * @param message - Parsed message object
@@ -996,6 +1018,20 @@ interface ClientTransportCodec {
996
1018
  decode(message: unknown): Promise<BusMessage>;
997
1019
  }
998
1020
  //#endregion
1021
+ //#region transports/ws/src/connection-error.d.ts
1022
+ /** Stable connection failure categories; callers own the retry policy. */
1023
+ type WebSocketConnectionErrorCode = 'WS_CONNECTION_UNAVAILABLE' | 'WS_HANDSHAKE_TIMEOUT' | 'WS_CONNECTION_TIMEOUT' | 'WS_AUTHENTICATION_REJECTED' | 'WS_POLICY_REJECTED';
1024
+ /** A transport-classified failure, distinct from unknown factory, codec or auth errors. */
1025
+ declare class WebSocketConnectionError extends Error {
1026
+ readonly code: WebSocketConnectionErrorCode;
1027
+ /**
1028
+ * @param code - Machine-readable failure category.
1029
+ * @param message - Human-readable diagnostic.
1030
+ * @param options - Original cause, when available.
1031
+ */
1032
+ constructor(code: WebSocketConnectionErrorCode, message: string, options?: ErrorOptions);
1033
+ }
1034
+ //#endregion
999
1035
  //#region transports/ws/src/ws-client-reconnect.d.ts
1000
1036
  /**
1001
1037
  * Reconnection utilities for `WebSocketClientTransport`.
@@ -1107,16 +1143,15 @@ interface WebSocketClientTransportOptions {
1107
1143
  */
1108
1144
  heartbeat?: WebSocketClientTransportHeartbeatOptions | false;
1109
1145
  /**
1110
- * Maximum time in milliseconds a single connect attempt may wait for the
1111
- * socket to open before the attempt is failed and the socket discarded.
1146
+ * Maximum time in milliseconds for one complete connection attempt:
1147
+ * asynchronous socket creation, opening, authentication and subscription replay.
1112
1148
  *
1113
1149
  * Bounds the WebSocket upgrade so a server (or intermediary) that accepts
1114
1150
  * the TCP connection but never answers cannot wedge the reconnect loop.
1115
- * Also passed as `handshakeTimeout` to the default `ws` factory.
1116
- *
1117
- * This bound starts after `createWebSocket` resolves with a socket instance.
1118
- * Custom async factories that may block before returning a socket should
1119
- * enforce their own factory-level timeout.
1151
+ * The budget starts before `createWebSocket` is called. If a cancelled factory
1152
+ * resolves later, its socket is closed without becoming the active connection.
1153
+ * This does not include waiting for the peer's subscribe-sync-complete frame;
1154
+ * callers requiring a total bootstrap-readiness budget must also bound `ready`.
1120
1155
  * @defaultValue 30000
1121
1156
  */
1122
1157
  connectTimeoutMs?: number;
@@ -1180,7 +1215,7 @@ declare class WebSocketClientTransport implements BusTransport {
1180
1215
  private readonly debug;
1181
1216
  private readonly onConnectedCallback;
1182
1217
  private readonly onDisconnectedCallback;
1183
- private socket;
1218
+ private session;
1184
1219
  private authComplete;
1185
1220
  private readonly correlations;
1186
1221
  private readonly handlers;
@@ -1189,12 +1224,12 @@ declare class WebSocketClientTransport implements BusTransport {
1189
1224
  private subscriptionAckSeq;
1190
1225
  private messageListener;
1191
1226
  private closeListener;
1192
- /** AbortController for the active reconnect loop; `null` when not connected. */
1227
+ /** Owns initial connection and its reconnect loop; `null` when disconnected. */
1193
1228
  private reconnectAbort;
1194
1229
  /**
1195
1230
  * In-flight `handleInboundMessage` promises for the current socket session.
1196
1231
  *
1197
- * Reset to a new `Set` at the start of each connection attempt so that the
1232
+ * Drained and cleared at the start of each connection attempt so that the
1198
1233
  * drain-before-rejectAll logic in `drainAndRejectPendingCorrelations` only
1199
1234
  * waits on the promises belonging to the active session.
1200
1235
  */
@@ -1218,6 +1253,11 @@ declare class WebSocketClientTransport implements BusTransport {
1218
1253
  onConnected: (() => void) | undefined;
1219
1254
  /** Set by the transport registry; called when the connection drops unexpectedly. */
1220
1255
  onDisconnected: (() => void) | undefined;
1256
+ /**
1257
+ * Current socket remains owned during buffered reply drain, even after termination.
1258
+ * @returns The retained socket, or null after its release.
1259
+ */
1260
+ private get socket();
1221
1261
  /**
1222
1262
  * Create a new `WebSocketClientTransport`.
1223
1263
  * @param options - Transport configuration
@@ -1334,9 +1374,9 @@ declare class WebSocketClientTransport implements BusTransport {
1334
1374
  /**
1335
1375
  * Default `ws`-package WebSocket factory (dynamic import avoids bundling in browsers).
1336
1376
  *
1337
- * Passes `connectTimeoutMs` as the `ws` handshake timeout so the protocol
1338
- * layer enforces the same bound as `waitForSocketOpen` (defense in depth —
1339
- * the `ws` default is no handshake timeout at all).
1377
+ * The connection lifecycle owns the single timeout budget, including this
1378
+ * import and socket creation. A second protocol timer would race its typed
1379
+ * outcome and give callers an unstable failure category.
1340
1380
  * @param url - WebSocket server URL
1341
1381
  * @returns Promise resolving to a `WebSocketLike` instance
1342
1382
  */
@@ -2081,4 +2121,4 @@ declare module '@makaio/framework/bus' {
2081
2121
  }
2082
2122
  }
2083
2123
  //#endregion
2084
- export { type ClientTransportCodec, DispatchingAuth, E2EAuth, E2ERelayAuth, type E2ERelayAuthOptions, HmacAuth, type HmacIdentitySecretRegistrationOptions, type HmacIdentitySecretRotationOptions, type RelayControlBusMessage, type RelayControlEnvelopeMessage, type RelayControlHelpers, type RelayControlRegistry, ServerTransport, type TransportAuth, WebSocketClientTransport, type WebSocketClientTransportHeartbeatOptions, type WebSocketClientTransportOptions, type WebSocketClientTransportReconnectOptions, type WebSocketCloseEvent, type WebSocketLike, type WebSocketServerLike, clearHmacIdentitySecretsForTesting, createE2EClientTransport, createE2ERelayClientTransport, createE2ERelayCodec, createRelayControlHelpers, createRelayControlRegistry, createWebSocketCloseEvent, createWebSocketTransport, index_d_exports as crypto, extractSocketErrorMessage, registerHmacIdentitySecret, resolveHmacIdentityAllowedSubjects, resolveHmacIdentityPeer, resolveHmacIdentitySecret, rotateHmacIdentitySecret };
2124
+ export { type ClientTransportCodec, DispatchingAuth, E2EAuth, E2ERelayAuth, type E2ERelayAuthOptions, HmacAuth, type HmacIdentitySecretRegistrationOptions, type HmacIdentitySecretRotationOptions, type RelayControlBusMessage, type RelayControlEnvelopeMessage, type RelayControlHelpers, type RelayControlRegistry, ServerTransport, type TransportAuth, WebSocketClientTransport, type WebSocketClientTransportHeartbeatOptions, type WebSocketClientTransportOptions, type WebSocketClientTransportReconnectOptions, type WebSocketCloseEvent, WebSocketConnectionError, type WebSocketConnectionErrorCode, type WebSocketLike, type WebSocketServerLike, clearHmacIdentitySecretsForTesting, createE2EClientTransport, createE2ERelayClientTransport, createE2ERelayCodec, createRelayControlHelpers, createRelayControlRegistry, createWebSocketCloseEvent, createWebSocketTransport, index_d_exports as crypto, extractSocketErrorMessage, registerHmacIdentitySecret, resolveHmacIdentityAllowedSubjects, resolveHmacIdentityPeer, resolveHmacIdentitySecret, rotateHmacIdentitySecret };
@@ -1,2 +1,2 @@
1
- import{r as e}from"../../chunk-DTipWd-i.mjs";import{isRecord as t}from"@makaio/framework/utils";import{ConnectionLostError as n,CorrelationTracker as r,DEFAULT_REQUEST_TIMEOUT_MS as i,NoHandlerError as a,TimeoutError as o,buildSubscribeMessage as s,buildUnsubscribeMessage as c,deserializeTransportError as l,getSubjectFromBusMessage as u,handleCorrelationResponse as d,isNoHandlerErrorForSubject as f,matchesSubscription as p,shouldReceiveMessage as m,trackMessageCorrelation as ee}from"@makaio/framework/bus";const te={baseMs:1e3,maxMs:1e4};function ne(e,t,n){let r=Math.max(t,100),i=Math.max(n,r);return Math.min(r*2**e,i)}function re(e,t){return new Promise(n=>{if(t.aborted){n();return}let r=()=>{clearTimeout(i),t.removeEventListener(`abort`,r),n()},i=setTimeout(()=>{t.removeEventListener(`abort`,r),n()},e);t.addEventListener(`abort`,r)})}const h={intervalMs:3e4,timeoutMs:1e4},ie={encode:async e=>JSON.stringify(e),decode:async e=>e};function ae(e){return e===!1?!1:{baseMs:e?.baseMs??te.baseMs,maxMs:e?.maxMs??te.maxMs}}function oe(e){if(e===!1)return!1;let t=e?.intervalMs??h.intervalMs,n=e?.timeoutMs??h.timeoutMs;if(!Number.isFinite(t)||t<=0)throw RangeError(`heartbeat.intervalMs must be a finite number > 0 (got ${String(t)})`);if(!Number.isFinite(n)||n<=0)throw RangeError(`heartbeat.timeoutMs must be a finite number > 0 (got ${String(n)})`);return{intervalMs:t,timeoutMs:n}}function g(e,t=`unknown error`){return`message`in e?String(e.message):t}async function _(e,t,n){let r=await t.encode(e);n.send(r)}function se(e,t){return e.readyState===1?Promise.resolve():e.readyState>=2?Promise.reject(Error(`WebSocket closed before opening`)):new Promise((n,r)=>{let i=()=>{c!==void 0&&clearTimeout(c),e.removeEventListener(`open`,a),e.removeEventListener(`error`,o),e.removeEventListener(`close`,s)},a=()=>{i(),n()},o=e=>{i(),r(Error(`WebSocket connection failed — ${g(e)}`))},s=()=>{i(),r(Error(`WebSocket closed before opening`))},c=t===void 0?void 0:setTimeout(()=>{i(),r(Error(`WebSocket open timed out after ${t}ms`))},t);e.addEventListener(`open`,a),e.addEventListener(`error`,o),e.addEventListener(`close`,s)})}async function ce(e,t,n){let r=await Promise.allSettled(Array.from(t).map(t=>t(e,n.receiveContext)));for(let e of r)e.status===`rejected`&&n.debug&&console.error(`[WebSocketClientTransport:${n.name}] Handler error:`,e.reason);return r.every(e=>e.status===`fulfilled`)}function le(e,t){return{...t?.getReceiveContext?.(),transportName:e}}async function ue(e,t){let{name:n,debug:r,auth:i,codec:a,messageTransform:o,correlations:s}=t,c=JSON.parse(e.toString());if(typeof c!=`object`||!c||typeof c.type!=`string`)return r&&console.error(`[WebSocketClientTransport:${n}] Invalid message structure:`,c),null;let l=c;if(i?.handleAuthMessage(l)||l.type===`heartbeat`)return null;let u=await a.decode(l);return o&&(u=await o(u)),u.type===`heartbeat`?null:u.type===`subscribe-sync-complete`?(t.onSyncComplete(),null):u.type===`subscription-ack`?(typeof u.ackId==`string`&&t.onSubscriptionAck(u.ackId),null):d(u,s)?null:u}async function de(e,t){let{name:n,debug:r,auth:i,handlers:a}=t,o=null;try{o=await ue(e,t)}catch(e){r&&console.error(`[WebSocketClientTransport:${n}] Failed to parse message:`,e);return}if(o===null)return;let s=le(n,i),c=o;ce(c,a,{debug:r,name:n,receiveContext:s}).then(async e=>{e&&(c.type===`subscribe`||c.type===`unsubscribe`)&&typeof c.ackId==`string`&&await t.sendSubscriptionAck(c.ackId)}).catch(e=>{r&&console.error(`[WebSocketClientTransport:${n}] Handler dispatch error:`,e)})}function fe(e){let t=e;return typeof t.ping==`function`&&typeof t.terminate==`function`&&typeof t.on==`function`&&typeof t.off==`function`}function v(e){e.unref?.()}function pe(e,t,n){if(!fe(e))return()=>{};let r=!1,i=Date.now(),a=null,o=null,s=()=>{if(r)return;let e=Date.now()-i,n=Math.max(0,t.intervalMs-e);a=setTimeout(l,n),v(a)},c=()=>{o=null,f(),n.debug&&console.warn(`[WebSocketClientTransport:${n.name}] ${new Date().toISOString()} Heartbeat deadline expired (no message/pong within ${t.timeoutMs}ms) — terminating socket`),e.terminate()},l=()=>{if(a=null,!r&&o===null){if(Date.now()-i<t.intervalMs){s();return}e.readyState===1&&(e.ping(),o=setTimeout(c,t.timeoutMs),v(o))}},u=()=>{i=Date.now(),o!==null&&(clearTimeout(o),o=null),a===null&&s()},d=()=>{f()},f=()=>{r||(r=!0,a!==null&&(clearTimeout(a),a=null),o!==null&&(clearTimeout(o),o=null),e.removeEventListener(`message`,u),e.removeEventListener(`close`,d),e.off(`pong`,u))};return e.addEventListener(`message`,u),e.on(`pong`,u),e.addEventListener(`close`,d),s(),f}async function y(e){await Promise.allSettled(e.inFlightMessages),e.correlations.rejectAll(new n(e.name))}function me(e,t){let n=n=>{let r=de(n.data,{name:t.name,debug:t.debug,auth:t.auth,codec:t.codec,messageTransform:t.messageTransform,correlations:t.correlations,handlers:t.handlers,onSyncComplete:()=>{t.resolveReady()},onSubscriptionAck:e=>{t.resolveSubscriptionAck(e)},sendSubscriptionAck:async n=>{e.readyState===1&&await _({type:`subscription-ack`,ackId:n},t.codec,e)}}).finally(()=>{t.inFlightMessages.delete(r)});t.inFlightMessages.add(r)};t.setMessageListener(n),e.addEventListener(`message`,n)}function b(e,t){let n=t.getMessageListener();n!==null&&(e.removeEventListener(`message`,n),t.setMessageListener(null));let r=t.getCloseListener();r!==null&&(e.removeEventListener(`close`,r),t.setCloseListener(null))}async function x(e){e.inFlightMessages.size>0?await y(e):e.correlations.rejectAll(new n(e.name)),e.inFlightMessages.clear(),e.resolveReady(),e.rejectPendingSubscriptionAcks(Error(`WebSocketClientTransport: reconnecting before subscription ack`)),e.resetReadyPromise();let t=e.getSocket();t!==null&&b(t,e);let r=await e.wsFactory(e.url);e.setSocket(r),e.setAuthComplete(!1);try{me(r,e),await se(r,e.connectTimeoutMs),e.auth&&await e.auth.authenticateClient(e=>{if(r.readyState!==1)throw Error(`WebSocketClientTransport: cannot send auth message — socket not open`);r.send(JSON.stringify(e))}),e.setAuthComplete(!0),e.debug&&console.info(`[WebSocketClientTransport:${e.name}] Connected to ${e.url}`),e.localSubscriptions.size>0&&(await _(s(e.localSubscriptions),e.codec,r),e.debug&&console.info(`[WebSocketClientTransport:${e.name}] Replayed ${e.localSubscriptions.size} subscription(s)`)),e.heartbeat!==!1&&pe(r,e.heartbeat,e),e.notifyConnected()}catch(t){let n=e.getSocket()===r;throw n&&e.auth?.cleanup(),b(r,e),n&&e.setSocket(null),e.setAuthComplete(!1),n&&(r.readyState===0||r.readyState===1)&&(r.addEventListener(`error`,()=>{}),r.close()),t}}function he(e,t){return new Promise(n=>{if(e.readyState===3||t.aborted){n();return}let r=()=>{t.removeEventListener(`abort`,i),n()},i=()=>{e.removeEventListener(`close`,r),n()};e.addEventListener(`close`,r),t.addEventListener(`abort`,i)})}async function ge(e,t,n,r,i){i(!0);try{for(;!e.aborted;){let i=n.getSocket(),a=i!==null;if(i!==null&&i.readyState!==3&&await he(i,e),e.aborted)break;a&&(await y(n),n.debug&&console.info(`[WebSocketClientTransport:${n.name}] ${new Date().toISOString()} Connection lost, starting reconnect loop (maxMs=${t.maxMs})`),n.notifyDisconnected());let o=0;for(;!e.aborted;){let i=ne(o,t.baseMs,t.maxMs);n.debug&&console.info(`[WebSocketClientTransport:${n.name}] ${new Date().toISOString()} Reconnecting in ${i}ms (attempt ${o+1})`);let a=new AbortController;if(r(a),await re(i,AbortSignal.any([e,a.signal])),r(null),e.aborted)break;try{await x(n),o=0;let t=n.getSocket();if(t!==null){let r=async()=>{await y(n),n.auth?.cleanup(),n.setAuthComplete(!1),n.debug&&console.info(`[WebSocketClientTransport:${n.name}] ${new Date().toISOString()} Connection closed`),n.rejectPendingSubscriptionAcks(Error(`WebSocketClientTransport: disconnected before subscription ack`))};n.setCloseListener(r),t.addEventListener(`close`,r),await he(t,e)}break}catch(e){if(n.debug){let t=e instanceof Error?e.message:String(e);console.warn(`[WebSocketClientTransport:${n.name}] ${new Date().toISOString()} Connect attempt ${o+1} failed: ${t}`)}o++}}}}finally{i(!1)}}function _e(e,t,n){let r=async()=>{b(e,t),t.auth?.cleanup(),t.setAuthComplete(!1),t.setSocket(null),n(),t.resolveReady(),t.notifyDisconnected(),await y(t),t.rejectPendingSubscriptionAcks(Error(`WebSocketClientTransport: disconnected before subscription ack`))};t.setCloseListener(r),e.addEventListener(`close`,r)}async function ve(e,t,n,r,i){let a=i.localSubscriptions.get(e),o=a?.filter,c=t??o,l=r??a?.deliveryClass??`relayable`;if(i.localSubscriptions.set(e,{filter:c,priorities:n,deliveryClass:l}),i.socket!==null&&i.socket.readyState===1){let t=i.beginSubscriptionAck?.(),r=s(new Map([[e,{filter:c,priorities:n,deliveryClass:l}]]),t?.ackId);try{await _(r,i.codec,i.socket),await t?.promise}catch(e){throw t?.reject(e),e}}i.debug&&console.info(`[WebSocketClientTransport:${i.name}] Subscribed to ${e}${c?` with filter`:``}`)}async function ye(e,t){let n=t.localSubscriptions.get(e);if(t.localSubscriptions.delete(e),t.socket!==null&&t.socket.readyState===1){let r=t.beginSubscriptionAck?.(),i=c({[e]:n?.priorities??[]},r?.ackId);try{await _(i,t.codec,t.socket),await r?.promise}catch(e){throw r?.reject(e),e}}t.debug&&console.info(`[WebSocketClientTransport:${t.name}] Unsubscribed from ${e}`)}var S=class{name;url;auth;codec;messageTransform;autoReconnectConfig;heartbeatConfig;connectTimeoutMs;wsFactory;debug;onConnectedCallback;onDisconnectedCallback;socket=null;authComplete=!1;correlations=new r;handlers=new Set;localSubscriptions=new Map;pendingSubscriptionAcks=new Map;subscriptionAckSeq=0;messageListener=null;closeListener=null;reconnectAbort=null;inFlightMessages=new Set;backoffWakeAbort=null;reconnectLoopRunning=!1;readyResolve=null;ready;onNewReadySession=void 0;onConnected=void 0;onDisconnected=void 0;constructor(e){this.url=e.url,this.name=e.name??`ws-client`,this.auth=e.auth,this.codec=e.codec??ie,this.messageTransform=e.messageTransform,this.debug=e.debug??!1,this.autoReconnectConfig=ae(e.autoReconnect),this.heartbeatConfig=oe(e.heartbeat),this.connectTimeoutMs=e.connectTimeoutMs??3e4,this.wsFactory=e.createWebSocket??this.defaultWsFactory,this.onConnectedCallback=e.onConnected,this.onDisconnectedCallback=e.onDisconnected,this.ready=new Promise(e=>{this.readyResolve=e})}async connect(){if(this.reconnectAbort!==null)throw Error(`WebSocketClientTransport: already connected`);let e=new AbortController;this.reconnectAbort=e;try{await x(this.connectionDeps())}catch(e){throw this.reconnectAbort=null,e}this.autoReconnectConfig===!1?this.socket!==null&&this.wireNoReconnectClose(this.socket):this.startReconnectLoop(e.signal)}async disconnect(){let e=this.reconnectAbort;if(this.reconnectAbort=null,e?.abort(),this.readyResolve?.(),this.readyResolve=null,this.socket!==null){b(this.socket,this.connectionDeps());let e=this.socket;this.socket=null,this.authComplete=!1,(e.readyState===0||e.readyState===1)&&e.close()}this.correlations.cleanup(),this.rejectPendingSubscriptionAcks(Error(`WebSocketClientTransport: disconnected before subscription ack`)),this.auth?.cleanup(),this.handlers.clear(),this.debug&&console.info(`[WebSocketClientTransport:${this.name}] Disconnected`)}async send(e,t){if(this.socket===null||this.socket.readyState!==1)throw Error(`WebSocketClientTransport: not connected`);let n=await this.codec.encode(e);return this.socket.send(n),ee(e,this.correlations,t??i)}onReceive(e){return this.handlers.add(e),()=>{this.handlers.delete(e)}}async subscribe(e,t,n=[],r){await ve(e,t,n,r,this.subscriptionDeps())}async unsubscribe(e){await ye(e,this.subscriptionDeps())}getSubscriptions(){return new Set(this.localSubscriptions.keys())}cancelRequest(e,t){this.correlations.cancel(e,t)}isReady(){return this.socket!==null&&this.socket.readyState===1&&this.authComplete}async reconnect(){if(!this.isReady()){if(this.backoffWakeAbort!==null){this.backoffWakeAbort.abort(),this.backoffWakeAbort=null;return}if(this.autoReconnectConfig!==!1){if(this.reconnectLoopRunning){let e=this.socket;e!==null&&e.readyState===0&&e.close();return}return}try{await x(this.connectionDeps()),this.socket!==null&&(this.reconnectAbort=new AbortController,this.wireNoReconnectClose(this.socket))}catch{}}}startReconnectLoop(e){return ge(e,this.autoReconnectConfig,this.connectionDeps(),e=>{this.backoffWakeAbort=e},e=>{this.reconnectLoopRunning=e})}subscriptionDeps(){return{name:this.name,debug:this.debug,codec:this.codec,socket:this.socket,localSubscriptions:this.localSubscriptions,beginSubscriptionAck:()=>this.beginSubscriptionAck()}}beginSubscriptionAck(){let e=`${this.name}:sub:${++this.subscriptionAckSeq}`,t,n,r=new Promise((e,r)=>{t=e,n=r});r.catch(()=>void 0);let i=t=>{this.pendingSubscriptionAcks.has(e)&&(this.pendingSubscriptionAcks.delete(e),t())};return this.pendingSubscriptionAcks.set(e,{resolve:()=>i(t),reject:e=>i(()=>n(e))}),{ackId:e,promise:r,reject:t=>this.rejectSubscriptionAck(e,t)}}resolveSubscriptionAck(e){this.pendingSubscriptionAcks.get(e)?.resolve()}rejectSubscriptionAck(e,t){this.pendingSubscriptionAcks.get(e)?.reject(t)}rejectPendingSubscriptionAcks(e){for(let t of this.pendingSubscriptionAcks.keys())this.rejectSubscriptionAck(t,e)}connectionDeps(){return{name:this.name,debug:this.debug,auth:this.auth,codec:this.codec,messageTransform:this.messageTransform,correlations:this.correlations,handlers:this.handlers,localSubscriptions:this.localSubscriptions,wsFactory:this.wsFactory,url:this.url,connectTimeoutMs:this.connectTimeoutMs,heartbeat:this.heartbeatConfig,getSocket:()=>this.socket,setSocket:e=>{this.socket=e},setAuthComplete:e=>{this.authComplete=e},getMessageListener:()=>this.messageListener,setMessageListener:e=>{this.messageListener=e},getCloseListener:()=>this.closeListener,setCloseListener:e=>{this.closeListener=e},resolveReady:()=>{this.readyResolve?.(),this.readyResolve=null},resetReadyPromise:()=>{this.ready=new Promise(e=>{this.readyResolve=e}),this.onNewReadySession?.(this.ready)},resolveSubscriptionAck:e=>{this.resolveSubscriptionAck(e)},rejectPendingSubscriptionAcks:e=>{this.rejectPendingSubscriptionAcks(e)},notifyConnected:()=>{this.onConnectedCallback?.(),this.onConnected?.()},notifyDisconnected:()=>{this.onDisconnectedCallback?.(),this.onDisconnected?.()},inFlightMessages:this.inFlightMessages}}defaultWsFactory=async e=>new(await(import(`ws`))).WebSocket(e,{handshakeTimeout:this.connectTimeoutMs});wireNoReconnectClose(e){_e(e,this.connectionDeps(),()=>{this.reconnectAbort=null})}};function C(e){e.timer!==void 0&&clearTimeout(e.timer)}var be=class{pendingBroadcasts=new Map;timeout;debug;constructor(e={}){this.timeout=e.timeout??5e3,this.debug=e.debug??!1}startClientBroadcast(e,t,n,r,i){let a=t.correlationId,o=i??this.timeout,s={kind:`client`,sender:e,results:[],pendingClients:new Set(n),nodeResultsReceived:!1,timer:o===0?void 0:setTimeout(()=>{this.debug&&console.warn(`[BroadcastAggregator] Broadcast ${a} timed out`),this.finalizeBroadcast(a)},o)};this.pendingBroadcasts.set(a,s);let c=JSON.stringify(t);for(let e of n)r(e,c);this.debug&&console.info(`[BroadcastAggregator] Broadcast ${a} forwarded to ${n.length} clients`)}startServerBroadcast(e,t,n,r){let i=e.correlationId,a=r??this.timeout;return t.length===0?(this.debug&&console.info(`[BroadcastAggregator] Server broadcast ${i} - no target clients`),Promise.resolve([])):new Promise(r=>{let o={kind:`server`,results:[],pendingClients:new Set(t),timer:a===0?void 0:setTimeout(()=>{this.debug&&console.warn(`[BroadcastAggregator] Server broadcast ${i} timed out`),this.finalizeServerBroadcast(i)},a),resolve:r};this.pendingBroadcasts.set(i,o);let s=JSON.stringify(e);for(let e of t)n(e,s);this.debug&&console.info(`[BroadcastAggregator] Server broadcast ${i} sent to ${t.length} clients`)})}handleResponse(e,t){let n=this.pendingBroadcasts.get(t.correlationId);return n?(t.results&&n.results.push(...t.results),n.pendingClients.delete(e),this.debug&&console.info(`[BroadcastAggregator] Broadcast ${t.correlationId} got response, ${n.pendingClients.size} pending`),this.checkBroadcastComplete(t.correlationId,n),!0):!1}handleNodeResults(e,t,n){let r=this.pendingBroadcasts.get(e);return!r||r.kind!==`client`?!1:(r.results.push(...t),r.nodeResultsReceived=!0,r.nodeError=n,this.debug&&console.info(`[BroadcastAggregator] Broadcast ${e} node results aggregated${n?` (with error)`:``}`),this.checkBroadcastComplete(e,r),!0)}handleClientDisconnect(e){for(let[t,n]of this.pendingBroadcasts)n.kind===`client`&&n.sender===e?(C(n),this.pendingBroadcasts.delete(t)):n.pendingClients.has(e)&&(n.pendingClients.delete(e),this.checkBroadcastComplete(t,n))}cleanup(){for(let e of this.pendingBroadcasts.values())C(e),e.kind===`server`&&e.resolve(e.results);this.pendingBroadcasts.clear()}checkBroadcastComplete(e,t){if(!(t.pendingClients.size>0))if(t.kind===`client`){if(!t.nodeResultsReceived)return;this.finalizeBroadcast(e)}else this.finalizeServerBroadcast(e)}finalizeBroadcast(e){let t=this.pendingBroadcasts.get(e);if(!t||t.kind!==`client`)return;C(t),this.pendingBroadcasts.delete(e);let n=t.nodeError?{type:`broadcast-response`,correlationId:e,error:t.nodeError}:{type:`broadcast-response`,correlationId:e,results:t.results};t.sender.readyState===1&&t.sender.send(JSON.stringify(n)),this.debug&&console.info(`[BroadcastAggregator] Broadcast ${e} finalized with ${t.results.length} results`)}finalizeServerBroadcast(e){let t=this.pendingBroadcasts.get(e);!t||t.kind!==`server`||(C(t),this.pendingBroadcasts.delete(e),t.resolve(t.results),this.debug&&console.info(`[BroadcastAggregator] Server broadcast ${e} finalized with ${t.results.length} results`))}},xe=class{clients=new Set;authenticatingClients=new Set;clientSubscriptions=new Map;clientSubscriptionState=new Map;clientFilters=new Map;requestOrigins=new Map;debug;subjectRestrictionResolver;socketAuthChecker;constructor(e={}){this.debug=e.debug??!1,this.subjectRestrictionResolver=e.subjectRestrictionResolver,this.socketAuthChecker=e.socketAuthChecker}addAuthenticating(e){this.authenticatingClients.add(e)}removeAuthenticating(e){this.authenticatingClients.delete(e)}isAuthenticating(e){return this.authenticatingClients.has(e)}addClient(e){this.clients.add(e)}removeClient(e){let t=new Set(this.clientSubscriptionState.get(e)?.keys()??[]);this.clients.delete(e),this.authenticatingClients.delete(e),this.clientSubscriptions.delete(e),this.clientSubscriptionState.delete(e),this.clientFilters.delete(e);for(let[t,n]of this.requestOrigins)n.socket===e&&this.clearRequestOrigin(t,n);return this.debug&&console.info(`[ClientRegistry] Client removed (${this.clients.size} remaining)`),this.buildAggregateUpdates(t)}get size(){return this.clients.size}getAllSockets(){return new Set([...this.clients,...this.authenticatingClients])}handleSubscribeMessage(e,t){let n=this.clientSubscriptions.get(e);n||(n=new Set,this.clientSubscriptions.set(e,n));let r=this.clientFilters.get(e),i=this.clientSubscriptionState.get(e);i||(i=new Map,this.clientSubscriptionState.set(e,i));for(let[a,o]of Object.entries(t.subjects)){n.add(a),i.set(a,{priorities:o,deliveryClass:t.deliveryClasses?.[a]===`relayable`?`relayable`:`first-hop-only`});let s=t.filters?.[a];s===void 0?r?.delete(a):(r||(r=new Map,this.clientFilters.set(e,r)),r.set(a,s))}if(this.debug){let e=Object.keys(t.subjects).length,n=t.filters?Object.keys(t.filters).length:0;console.info(`[ClientRegistry] Client subscribed to ${e} subjects, ${n} filters`)}return this.buildAggregateUpdates(new Set(Object.keys(t.subjects)))}handleUnsubscribeMessage(e,t){let n=this.clientSubscriptions.get(e),r=this.clientFilters.get(e);for(let i of Object.keys(t))n?.delete(i),this.clientSubscriptionState.get(e)?.delete(i),r?.delete(i);return this.debug&&console.info(`[ClientRegistry] Client unsubscribed from ${Object.keys(t).length} subjects`),this.buildAggregateUpdates(new Set(Object.keys(t)))}getReadyClients(){let e=[];for(let t of this.clients)t.readyState===1&&e.push(t);return e}trackRequestOrigin(e,t){let{correlationId:n}=t;if(this.requestOrigins.has(n))return;let r=this.getRequestRemainingLifetime(t);if(r===0)return;let i={socket:e,expiration:void 0};r!==void 0&&(i.expiration=setTimeout(()=>{this.requestOrigins.get(n)===i&&this.requestOrigins.delete(n)},r)),this.requestOrigins.set(n,i)}getRequestOrigin(e){return this.requestOrigins.get(e)?.socket}consumeResponseClient(e){let t=this.requestOrigins.get(e);if(t)return this.clearRequestOrigin(e,t),this.isReadyAndAuthenticated(t.socket)?t.socket:void 0}cancelRequestOrigin(e){let t=this.requestOrigins.get(e);t&&this.clearRequestOrigin(e,t)}getInterestedClients(e,t,n){let r=[];for(let i of this.clients)i===n||!this.isReadyAndAuthenticated(i)||this.clientWantsMessage(i,e,t)&&this.isSubjectAllowedForClient(i,e)&&r.push(i);return r}getInterestedRequestClients(e,t,n){return this.getInterestedClients(e,t,n).filter(t=>{let n=this.clientSubscriptionState.get(t);return n?[...n].some(([t,n])=>n.priorities.length>0&&p(e,t)):!1})}forwardEventToClients(e,t,n){let r=u(t)??void 0,i=`payload`in t?t.payload:void 0,a=JSON.stringify(t),o=this.getInterestedClients(r,i,e);for(let e of o)n(e,a)}clientWantsMessage(e,t,n){return m(t,n,this.clientSubscriptions.get(e)??new Set,this.clientFilters.get(e)??new Map)}isReadyAndAuthenticated(e){return e.readyState===1?!this.socketAuthChecker||this.socketAuthChecker(e)?!0:(e.close(1008,`Authentication expired`),!1):!1}getRequestRemainingLifetime(e){if(e.deadline!==void 0)return Math.max(0,e.deadline-Date.now());let t=e.timeout??i;return t>0?t:void 0}clearRequestOrigin(e,t){t.expiration!==void 0&&clearTimeout(t.expiration),this.requestOrigins.delete(e)}isSubjectAllowedForClient(e,t){if(!this.subjectRestrictionResolver||t===void 0)return!0;let n=this.subjectRestrictionResolver(e);return n===null?!0:n.has(t)}buildAggregateUpdates(e){let t={},n={},r={};for(let i of e){let e=new Set,a=!1,o=`relayable`;for(let t of this.clientSubscriptionState.values()){let n=t.get(i);if(n){a=!0;for(let t of n.priorities)e.add(t);n.deliveryClass===`first-hop-only`&&(o=`first-hop-only`)}}a?(t[i]=[...e].sort((e,t)=>t-e),n[i]=o):r[i]=[]}let i=[];return Object.keys(t).length>0&&i.push({type:`subscribe`,subjects:t,deliveryClasses:n}),Object.keys(r).length>0&&i.push({type:`unsubscribe`,subjects:r}),i}};const w=new Map;function Se(e,t,n){if(e.trim().length===0)throw Error(`registerHmacIdentitySecret requires a non-empty identityId`);if(t.length===0)throw Error(`registerHmacIdentitySecret requires a non-empty secret`);let r=n.peerKind.trim();if(r.length===0)throw Error(`registerHmacIdentitySecret requires a non-empty peerKind`);let i={secret:t,peerKind:r,...n.claims===void 0?{}:{claims:n.claims},...n.allowedSubjects===void 0?{}:{allowedSubjects:new Set(n.allowedSubjects)}};w.set(e,i);let a=!0;return()=>{a&&(a=!1,w.get(e)===i&&w.delete(e))}}function Ce(e,t,n={}){if(t.length===0)throw Error(`rotateHmacIdentitySecret requires a non-empty secret`);let r=w.get(e);if(!r)throw Error(`Cannot rotate HMAC identity secret: no registration exists for '${e}'`);let i={secret:t,peerKind:r.peerKind,...n.claims===void 0?r.claims===void 0?{}:{claims:r.claims}:{claims:n.claims},...r.allowedSubjects===void 0?{}:{allowedSubjects:r.allowedSubjects}};w.set(e,i);let a=!0;return()=>{a&&(a=!1,w.get(e)===i&&w.delete(e))}}function we(e){return w.get(e)?.secret??null}function Te(e){let t=w.get(e);return t?{kind:t.peerKind,id:e,authenticated:!0,...t.claims===void 0?{}:{claims:t.claims}}:null}function T(e){return w.get(e)?.allowedSubjects??null}function Ee(){w.clear()}function De(e){return e.type===`request`||e.type===`event`||e.type===`broadcast`}function Oe(e){return t(e)&&Object.values(e).every(e=>Array.isArray(e)&&e.every(e=>typeof e==`number`&&Number.isFinite(e)))}function ke(e){return e.endsWith(`*`)}function Ae(e,t,n,r){let i={};for(let[a,o]of Object.entries(e))ke(a)?t.has(a)?i[a]=o:n&&console.debug(`[ServerTransport] Dropping wildcard subscription '${a}': not in allowedSubjects for peer '${r}'`):t.has(a)?i[a]=o:n&&console.debug(`[ServerTransport] Dropping subscription subject '${a}': not allowed for peer '${r}'`);return Object.keys(i).length>0?i:null}async function E(e,t,n){let r=await Promise.allSettled(Array.from(t).map(t=>t(e,n.receiveContext)));for(let e of r)if(e.status===`rejected`&&n.debug){let t=n.logContext?` ${n.logContext}`:``;console.error(`[ServerTransport] Handler error${t}:`,e.reason)}return r.every(e=>e.status===`fulfilled`)}async function D(e,t,n){let r=!0;for(let i of e)await E(i,t,n)||(r=!1);return r}function je(e,t,n){let{correlations:r,broadcastAggregator:i,debug:a}=t;if(e.type===`heartbeat`)return!0;if(e.type===`response`){let t=e;return typeof t.correlationId==`string`?(t.error?r.reject(t.correlationId,l(t.error)):r.resolve(t.correlationId,t.result),!0):(a&&console.warn(`[ServerTransport] Malformed response message: missing correlationId`),!0)}if(e.type===`broadcast-response`){let t=e;return typeof t.correlationId==`string`?(i.handleResponse(n,t),!0):(a&&console.warn(`[ServerTransport] Malformed broadcast-response: missing correlationId`),!0)}return!1}function Me(e){let t=e?.peer?.id;if(t===void 0)return null;let n=T(t);return n===null?null:{peerId:t,allowedSubjects:n}}function Ne(e,t,n,r){if(r===null||!De(e))return!1;let i=`${e.namespace}.${e.subject}`;return r.allowedSubjects.has(i)?!1:(e.type===`request`&&n.sendSafely(t,JSON.stringify({type:`response`,correlationId:e.correlationId,error:{message:`Subject '${i}' is not allowed for peer '${r.peerId}'`}})),n.debug&&console.warn(`[ServerTransport] Dropping ${e.type} to '${i}': not allowed for peer '${r.peerId}'`),!0)}function Pe(e,t,n){if(!Oe(e.subjects))return n&&console.warn(`[ServerTransport] Malformed ${e.type} message: missing subjects record`),null;if(t===null)return e.subjects;let r=Ae(e.subjects,t.allowedSubjects,n,t.peerId);return r===null&&n&&console.debug(`[ServerTransport] Dropping ${e.type} message: all subjects filtered for peer '${t.peerId}'`),r}async function Fe(e,t,n,r,i){if(e.type!==`subscribe`&&e.type!==`unsubscribe`)return!1;let a=e,o=Pe(a,i,n.debug);return o===null||await D(a.type===`subscribe`?n.registry.handleSubscribeMessage(t,{...a,subjects:o}):n.registry.handleUnsubscribeMessage(t,o),n.handlers,{debug:n.debug,receiveContext:r,logContext:`dispatching ${a.type}`})&&typeof a.ackId==`string`&&n.sendSafely(t,JSON.stringify({type:`subscription-ack`,ackId:a.ackId})),!0}async function Ie(e,t,n,r){if(e.type!==`broadcast`)return!1;let i=e;if(typeof i.correlationId!=`string`||typeof i.subject!=`string`)return n.debug&&console.warn(`[ServerTransport] Malformed broadcast message: missing correlationId or subject`),!0;let a=n.registry.getInterestedClients(i.subject,i.payload,t),o=n.normalizeBroadcastTimeout(i.timeout);return n.broadcastAggregator.startClientBroadcast(t,i,a,n.sendSafely,o),await E(e,n.handlers,{debug:n.debug,receiveContext:r}),!0}async function Le(e,t,n){if(je(e,n,t))return;let r=n.auth?.getReceiveContext?.(t),i=Me(r);if(!Ne(e,t,n,i)){if(e.type===`subscribe`||e.type===`unsubscribe`){await Fe(e,t,n,r,i);return}if(e.type===`broadcast`){await Ie(e,t,n,r);return}e.type===`event`&&n.registry.forwardEventToClients(t,e,n.sendSafely),e.type===`request`&&n.registry.trackRequestOrigin(t,e),await E(e,n.handlers,{debug:n.debug,receiveContext:r})}}function Re(e,t){let{auth:n,registry:r,debug:i}=t;return async a=>{let o;try{o=JSON.parse(a.toString())}catch(e){i&&console.error(`[ServerTransport] Failed to parse message:`,e);return}let s=o&&typeof o==`object`?o:void 0;if(!s||typeof s.type!=`string`){i&&console.error(`[ServerTransport] Invalid message structure:`,o);return}let c=o;try{if(n?.handleAuthMessage(c,e))return;if(n&&r.isAuthenticating(e)){i&&console.warn(`[ServerTransport] Ignoring message from unauthenticated client`);return}if(n?.isSocketAuthenticated?.(e)===!1){i&&console.warn(`[ServerTransport] Closing socket with expired authentication`),n.cleanupSocket(e),e.close(1008,`Authentication expired`);return}await Le(c,e,t)}catch(e){i&&console.error(`[ServerTransport] Failed to process message:`,e)}}}function ze(e){return typeof e!=`number`||!Number.isFinite(e)||e<=0?5e3:Math.min(e,6e4)}async function Be(e,t){let{registry:n,correlations:r,broadcastAggregator:i,handlers:a,auth:o,serverSubscriptions:c,sendSafely:l,debug:u}=t;o&&n.addAuthenticating(e);let d=Re(e,{registry:n,correlations:r,broadcastAggregator:i,handlers:a,auth:o,normalizeBroadcastTimeout:ze,sendSafely:l,debug:u}),f=e=>{d(e.data)},p=()=>{o?.cleanupSocket(e);let t=n.removeClient(e);e.removeEventListener(`message`,f),e.removeEventListener(`close`,p),e.removeEventListener(`error`,m),i.handleClientDisconnect(e),D(t,a,{debug:u,logContext:`dispatching disconnected client subscriptions`}),u&&console.info(`[ServerTransport] Client disconnected (${n.size} remaining)`)},m=e=>{u&&console.error(`[ServerTransport] Client socket error:`,e)};e.addEventListener(`message`,f),e.addEventListener(`close`,p),e.addEventListener(`error`,m);try{if(o&&(await o.authenticateServer(e,t=>{if(e.readyState!==1)throw Error(`Cannot send auth message: socket not ready (state: ${e.readyState})`);e.send(JSON.stringify(t))}),n.removeAuthenticating(e)),e.readyState!==1)return;if(n.addClient(e),c.size>0){let t=s(c);l(e,JSON.stringify(t))}l(e,JSON.stringify({type:`subscribe-sync-complete`})),u&&console.info(`[ServerTransport] Client connected (${n.size} total)`)}catch(t){u&&console.error(`[ServerTransport] Client authentication failed:`,t),e.close(1008,`Authentication failed`)}}async function Ve(e,t,n){let{registry:r,correlations:i}=n,s=`${e.namespace}.${e.subject}`,c=r.getRequestOrigin(e.correlationId),l=r.getInterestedRequestClients(s,e.payload,c);if(l.length===0)throw new a(s);for(let[n,r]of l.entries()){let a=`${e.correlationId}:attempt-${n+1}`,c={...e,correlationId:a};try{r.send(JSON.stringify(c))}catch{continue}try{return await i.track(a,t)}catch(e){if(f(e,s)||e instanceof o)continue;throw e}}throw new a(s)}var O=class{name;wss;auth;debug;handlers=new Set;registry;serverSubscriptions=new Map;broadcastAggregator;correlations=new r;connectionListener=null;constructor(e){let{websocket:t,name:n=`websocket`,auth:r,debug:i=!1}=e;this.wss=t,this.name=n,this.auth=r,this.debug=i,this.registry=new xe({debug:i,subjectRestrictionResolver:r?e=>{let t=(r.getReceiveContext?.(e))?.peer?.id;return t===void 0?null:T(t)}:void 0,socketAuthChecker:r?e=>r.isSocketAuthenticated?.(e)??!0:void 0}),this.broadcastAggregator=new be({debug:i})}sendToClientSafely(e,t){try{e.send(t)}catch(e){this.debug&&console.warn(`[ServerTransport] Failed to send message to client:`,e)}}async connect(){if(this.connectionListener!==null)throw Error(`ServerTransport.connect() called while already connected`);this.connectionListener=e=>{Be(e,{registry:this.registry,correlations:this.correlations,broadcastAggregator:this.broadcastAggregator,handlers:this.handlers,auth:this.auth,serverSubscriptions:this.serverSubscriptions,sendSafely:(e,t)=>this.sendToClientSafely(e,t),debug:this.debug})},this.wss.on(`connection`,this.connectionListener),this.debug&&console.info(`[ServerTransport] Listening for connections`)}async disconnect(){this.connectionListener&&=(this.wss.off(`connection`,this.connectionListener),null);let e=this.registry.getAllSockets();for(let t of e)t.close();await new Promise((e,t)=>{this.wss.close(n=>n?t(n):e())}),this.correlations.cleanup(),this.broadcastAggregator.cleanup(),this.auth?.cleanup(),this.handlers.clear(),this.serverSubscriptions.clear(),this.debug&&console.info(`[ServerTransport] Disconnected`)}async send(e,t){if(e.type===`response`){let t=this.registry.consumeResponseClient(e.correlationId);return t?(this.sendToClientSafely(t,JSON.stringify(e)),!0):!1}if(e.type===`broadcast`){let n=u(e)??void 0,r=`payload`in e?e.payload:void 0,i=this.registry.getInterestedClients(n,r);return this.broadcastAggregator.startServerBroadcast(e,i,(e,t)=>{this.sendToClientSafely(e,t)},t)}if(e.type===`request`)return Ve(e,t??i,{registry:this.registry,correlations:this.correlations});if(this.registry.size===0){if(this.debug){let t=u(e);console.debug(`[ServerTransport] No clients to receive ${e.type}${t?`: ${t}`:``}`)}return!1}let n=u(e)??void 0,r=`payload`in e?e.payload:void 0,a=JSON.stringify(e),o=this.registry.getInterestedClients(n,r);for(let e of o)this.sendToClientSafely(e,a);let s=o.length>0;if(!s&&(n&&this.debug&&console.warn(`[ServerTransport] No interested clients for subject: ${n}`),!n))throw Error(`No connected clients available to receive message`);return s}onReceive(e){return this.handlers.add(e),()=>{this.handlers.delete(e)}}cancelRequest(e,t){this.correlations.cancel(e,t),this.registry.cancelRequestOrigin(e)}onBroadcastResults(e,t,n){this.broadcastAggregator.handleNodeResults(e,t,n)}async subscribe(e,t,n=[],r){let i=this.serverSubscriptions.get(e),a=i?.filter,o=t??a,c=r??i?.deliveryClass??`relayable`;if(this.serverSubscriptions.set(e,{filter:o,priorities:n,deliveryClass:c}),this.registry.size>0){let t=s(new Map([[e,{filter:o,priorities:n,deliveryClass:c}]])),r=JSON.stringify(t);for(let e of this.registry.getReadyClients())this.sendToClientSafely(e,r)}}getConnectionCount(){return this.registry.getReadyClients().length}async unsubscribe(e){if(this.serverSubscriptions.delete(e),this.registry.size>0){let t=c({[e]:[]}),n=JSON.stringify(t);for(let e of this.registry.getReadyClients())this.sendToClientSafely(e,n)}}};function He(e,t){let n=new Event(`close`);return Object.defineProperties(n,{code:{value:e??1e3,enumerable:!0},reason:{value:t??``,enumerable:!0}}),n}function Ue(e){if(typeof e!=`object`||!e)throw TypeError(`WebSocket transport options must be an object`);let t=e;if(t.mode!==`client`&&t.mode!==`server`)throw TypeError(`WebSocket transport mode must be "client" or "server"`);if(t.mode===`client`){if(!We(t.websocket))throw TypeError(`WebSocket transport client mode requires a websocket with addEventListener/removeEventListener`);return}if(!Ge(t.websocket))throw TypeError(`WebSocket transport server mode requires a websocket with on/off listener methods`)}function We(e){if(typeof e!=`object`||!e)return!1;let t=e;return typeof t.send==`function`&&typeof t.close==`function`&&typeof t.addEventListener==`function`&&typeof t.removeEventListener==`function`}function Ge(e){if(typeof e!=`object`||!e)return!1;let t=e;return typeof t.on==`function`&&typeof t.off==`function`&&typeof t.close==`function`}var Ke=class{secret;algorithm;challengeTimeout;identityId;resolveSecret;resolvePeer;pendingChallenge;pendingResult;queuedChallengeNonce;queuedResult;clientAuthComplete=!1;serverPendingResponses=new Map;serverAuthenticatedSockets=new Set;serverAuthenticatedPeers=new Map;serverAuthenticatedSecrets=new Map;constructor(e){this.secret=e.secret,this.algorithm=e.algorithm??`sha256`,this.challengeTimeout=e.challengeTimeout??5e3,this.identityId=e.identityId,this.resolveSecret=e.resolveSecret,this.resolvePeer=e.resolvePeer}async authenticateServer(e,t){let n=crypto.getRandomValues(new Uint8Array(32)),r=Array.from(n).map(e=>e.toString(16).padStart(2,`0`)).join(``),i=await this.computeHmac(r);t({type:`auth-challenge`,nonce:r});let a=!1;try{let{signature:n,identityId:o}=await this.waitForAuthResponseWithIdentity(e),s;if(this.resolveSecret&&o!==void 0){let i=this.resolveSecret(o);if(i===null)throw this.sendAuthResultBestEffort(t,{type:`auth-result`,success:!1,error:`Unknown identity`}),a=!0,Error(`HMAC authentication failed: Unknown identity '${o}'`);s=await this.computeHmacWithSecret(r,i),this.constantTimeEqual(n,s)&&(this.serverAuthenticatedPeers.set(e,o),this.serverAuthenticatedSecrets.set(e,i))}else s=i;if(!this.constantTimeEqual(n,s))throw this.sendAuthResultBestEffort(t,{type:`auth-result`,success:!1,error:`Invalid signature`}),a=!0,Error(`HMAC authentication failed: Invalid signature`);this.serverAuthenticatedSockets.add(e),this.sendAuthResultBestEffort(t,{type:`auth-result`,success:!0}),a=!0}catch(n){let r=this.serverPendingResponses.has(e);throw this.serverPendingResponses.delete(e),!a&&r&&this.sendAuthResultBestEffort(t,{type:`auth-result`,success:!1,error:n instanceof Error?n.message:`Authentication failed`}),n}finally{this.serverPendingResponses.delete(e)}}async authenticateClient(e){this.clientAuthComplete=!1;let t=await this.waitForAuthChallenge();e({type:`auth-response`,signature:await this.computeHmac(t),...this.identityId!==void 0&&{identityId:this.identityId}});let n=await this.waitForAuthResult();if(!n.success)throw Error(`HMAC authentication failed: ${n.error??`Unknown error`}`);this.clientAuthComplete=!0}handleAuthMessage(e,t){if(typeof e!=`object`||!e||!(`type`in e)||typeof e.type!=`string`)return!1;let n=e;if(n.type===`auth-challenge`)return typeof n.nonce!=`string`||this.clientAuthComplete||(this.pendingChallenge?(clearTimeout(this.pendingChallenge.timeoutHandle),this.pendingChallenge.resolve(n.nonce),this.pendingChallenge=void 0):this.queuedChallengeNonce=n.nonce),!0;if(n.type===`auth-result`){if(typeof n.success!=`boolean`||this.clientAuthComplete)return!0;let e={success:n.success,error:n.error};return this.pendingResult?(clearTimeout(this.pendingResult.timeoutHandle),this.pendingResult.resolve(e),this.pendingResult=void 0):this.queuedResult=e,!0}if(n.type===`auth-response`){if(t){let e=this.serverPendingResponses.get(t);e&&(clearTimeout(e.timeoutHandle),e.resolve({signature:n.signature,identityId:n.identityId}))}return!0}return!1}async waitForAuthChallenge(){if(this.queuedChallengeNonce!==void 0){let e=this.queuedChallengeNonce;return this.queuedChallengeNonce=void 0,e}return new Promise((e,t)=>{let n=setTimeout(()=>{this.pendingChallenge=void 0,t(Error(`Authentication challenge timeout`))},this.challengeTimeout);this.pendingChallenge={resolve:e,reject:t,timeoutHandle:n}})}async waitForAuthResponseWithIdentity(e){return new Promise((t,n)=>{let r={resolve:t,reject:n,timeoutHandle:setTimeout(()=>{n(Error(`Authentication response timeout`))},this.challengeTimeout)};this.serverPendingResponses.set(e,r)})}async waitForAuthResult(){if(this.queuedResult!==void 0){let e=this.queuedResult;return this.queuedResult=void 0,e}return new Promise((e,t)=>{let n=setTimeout(()=>{this.pendingResult=void 0,t(Error(`Authentication result timeout`))},this.challengeTimeout);this.pendingResult={resolve:e,reject:t,timeoutHandle:n}})}async computeHmac(e){return this.computeHmacWithSecret(e,this.secret)}async computeHmacWithSecret(e,t){let n=new TextEncoder,r=n.encode(t),i=this.algorithm.replace(/^sha/,`SHA-`),a=await crypto.subtle.importKey(`raw`,r,{name:`HMAC`,hash:i},!1,[`sign`]),o=await crypto.subtle.sign(`HMAC`,a,n.encode(e));return Array.from(new Uint8Array(o)).map(e=>e.toString(16).padStart(2,`0`)).join(``)}getReceiveContext(e){if(!e)return;let t=this.serverAuthenticatedPeers.get(e);if(t===void 0)return;let n=this.resolvePeer?.(t);if(n!=null)return{transportName:``,peer:{...n,id:n.id??t,authenticated:!0}}}isSocketAuthenticated(e){if(!this.serverAuthenticatedSockets.has(e))return!1;if(!this.resolveSecret)return!0;let t=this.serverAuthenticatedPeers.get(e);if(t===void 0)return!0;let n=this.resolveSecret(t);if(n===null)return this.cleanupSocket(e),!1;let r=this.serverAuthenticatedSecrets.get(e);return r!==void 0&&n!==r?(this.cleanupSocket(e),!1):!0}constantTimeEqual(e,t){if(e.length!==t.length)return!1;let n=new Uint8Array(e.length/2),r=new Uint8Array(t.length/2);for(let i=0;i<n.length;i++)n[i]=parseInt(e.slice(i*2,i*2+2),16),r[i]=parseInt(t.slice(i*2,i*2+2),16);let i=0;for(let e=0;e<n.length;e++)i|=n[e]^r[e];return i===0}sendAuthResultBestEffort(e,t){try{e(t)}catch{}}cleanupSocket(e){let t=this.serverPendingResponses.get(e);t&&(clearTimeout(t.timeoutHandle),this.serverPendingResponses.delete(e),t.reject(Error(`Socket disconnected during HMAC authentication`))),this.serverAuthenticatedPeers.delete(e),this.serverAuthenticatedSecrets.delete(e),this.serverAuthenticatedSockets.delete(e)}cleanup(){this.pendingChallenge&&=(clearTimeout(this.pendingChallenge.timeoutHandle),void 0),this.pendingResult&&=(clearTimeout(this.pendingResult.timeoutHandle),void 0),this.queuedChallengeNonce=void 0,this.queuedResult=void 0,this.clientAuthComplete=!1;for(let e of this.serverPendingResponses.values())clearTimeout(e.timeoutHandle);this.serverPendingResponses.clear(),this.serverAuthenticatedPeers.clear(),this.serverAuthenticatedSecrets.clear(),this.serverAuthenticatedSockets.clear()}};function k(e){let t=Array.from(e,e=>String.fromCharCode(e)).join(``);return btoa(t).replace(/\+/g,`-`).replace(/\//g,`_`).replace(/=/g,``)}function A(e){let t=e.replace(/-/g,`+`).replace(/_/g,`/`),n=(4-t.length%4)%4;t+=`=`.repeat(n);let r=atob(t),i=new Uint8Array(r.length);for(let e=0;e<r.length;e++)i[e]=r.charCodeAt(e);return i}function j(e){return new TextEncoder().encode(e)}function M(e){return new TextDecoder().decode(e)}async function N(e){let t=await crypto.subtle.exportKey(`spki`,e);return k(new Uint8Array(t))}async function P(e){let t=await crypto.subtle.exportKey(`raw`,e);return k(new Uint8Array(t))}async function F(e,t,n=[]){let r=A(e);return crypto.subtle.importKey(`spki`,r,t,!0,n)}async function I(e,t,n=[]){let r=A(e);return crypto.subtle.importKey(`raw`,r,t,!0,n)}async function L(e){let t=await crypto.subtle.exportKey(`pkcs8`,e),n=k(new Uint8Array(t)).replace(/-/g,`+`).replace(/_/g,`/`),r=(4-n.length%4)%4;return n+=`=`.repeat(r),`-----BEGIN PRIVATE KEY-----\n${n.match(/.{1,64}/g)?.join(`
2
- `)??n}\n-----END PRIVATE KEY-----`}async function R(e,t,n){let r=A(e.replace(/-----BEGIN PRIVATE KEY-----/,``).replace(/-----END PRIVATE KEY-----/,``).replace(/\s/g,``).replace(/\+/g,`-`).replace(/\//g,`_`).replace(/=/g,``));return crypto.subtle.importKey(`pkcs8`,r,t,!0,n)}const z={name:`ECDH`,namedCurve:`P-256`};async function B(e=!0){return crypto.subtle.generateKey(z,e,[`deriveKey`,`deriveBits`])}async function V(e){return N(e)}async function qe(e){return P(e)}async function Je(e){return I(e,z)}async function H(e,t=[]){return F(e,z,t)}async function Ye(e){return L(e)}async function Xe(e){return R(e,z,[`deriveKey`,`deriveBits`])}async function U(e,t){return crypto.subtle.deriveBits({name:`ECDH`,public:t},e,256)}async function W(e,t){let n=crypto.getRandomValues(new Uint8Array(12)),r=await crypto.subtle.encrypt({name:`AES-GCM`,iv:n},e,t);return{ciphertext:new Uint8Array(r),nonce:n}}async function G(e,t,n){let r=await crypto.subtle.decrypt({name:`AES-GCM`,iv:n},e,t);return new Uint8Array(r)}async function Ze(e){return crypto.subtle.importKey(`raw`,e,{name:`AES-GCM`},!1,[`encrypt`,`decrypt`])}async function Qe(e,t,n){let r=await crypto.subtle.importKey(`raw`,e,{name:`HKDF`},!1,[`deriveKey`]);return crypto.subtle.deriveKey({name:`HKDF`,hash:`SHA-256`,salt:t,info:j(n)},r,{name:`AES-GCM`,length:256},!1,[`encrypt`,`decrypt`])}const K={name:`ECDSA`,namedCurve:`P-256`};async function $e(e=!0){return crypto.subtle.generateKey(K,e,[`sign`,`verify`])}async function et(e,t){let n=await crypto.subtle.sign({name:`ECDSA`,hash:{name:`SHA-256`}},e,t);return new Uint8Array(n)}async function tt(e,t,n){return crypto.subtle.verify({name:`ECDSA`,hash:{name:`SHA-256`}},e,t,n)}async function nt(e){return N(e)}async function rt(e){return F(e,K,[`verify`])}async function it(e){return P(e)}async function at(e){return I(e,K,[`verify`])}async function ot(e){return L(e)}async function st(e){return R(e,K,[`sign`])}var ct=e({decodeText:()=>M,decrypt:()=>G,deriveSessionKey:()=>Qe,deriveSharedSecret:()=>U,encodeText:()=>j,encrypt:()=>W,exportPrivateKeyPEM:()=>Ye,exportPublicKey:()=>V,exportPublicKeyRaw:()=>qe,exportSigningPrivateKeyPEM:()=>ot,exportSigningPublicKey:()=>nt,exportSigningPublicKeyRaw:()=>it,fromBase64Url:()=>A,generateECDHKeyPair:()=>B,generateSigningKeyPair:()=>$e,importAESKey:()=>Ze,importPrivateKeyPEM:()=>Xe,importPublicKey:()=>H,importPublicKeyRaw:()=>Je,importSigningPrivateKeyPEM:()=>st,importSigningPublicKey:()=>rt,importSigningPublicKeyRaw:()=>at,sign:()=>et,toBase64Url:()=>k,verify:()=>tt});function lt(e){let t=e.match(/.{1,2}/g);return new Uint8Array(t?.map(e=>parseInt(e,16))??[])}function q(e){return Array.from(e).map(e=>e.toString(16).padStart(2,`0`)).join(``)}async function J(e,t){let n=await B(!0),r=await V(n.publicKey);return{ephemeralKeyPair:n,ephemeralPublicKey:r,signature:q(await et(e,j(r+t)))}}function ut(){return q(crypto.getRandomValues(new Uint8Array(16)))}async function Y(e,t,n,r){let i=j(t+r);return tt(e,lt(n),i)}async function X(e,t,n,r){return Qe(await U(e,await H(t)),lt(n),r)}async function dt(e,t,n,r){if(e===t)throw Error(`deriveRelaySaltHex: identityId must differ from peerId`);let[i,a]=e<t?[e,t]:[t,e],[o,s]=e<t?[n,r]:[r,n],c=j(`${i}${a}${o}${s}`),l=new Uint8Array(c).buffer,u=await crypto.subtle.digest(`SHA-256`,l);return q(new Uint8Array(u))}var ft=class{signingKeyPair;identityId;peerId;getPeerSigningKey;timeout;pendingKeyExchange;pendingResult;clientSession;clientEphemeralKeyPair;serverPendingKeyExchange=new Map;serverSessions=new Map;serverEphemeralKeyPairs=new Map;constructor(e){this.signingKeyPair=e.signingKeyPair,this.identityId=e.identityId,this.peerId=e.peerId,this.getPeerSigningKey=e.getPeerSigningKey,this.timeout=e.timeout??1e4}async authenticateClient(e){if(!this.peerId)throw Error(`E2E authentication failed: peerId is required for client authentication`);let{ephemeralKeyPair:t,ephemeralPublicKey:n,signature:r}=await J(this.signingKeyPair.privateKey,this.identityId);this.clientEphemeralKeyPair=t;try{let i=this.waitForKeyExchangeResponse(),a=this.waitForAuthResult();e({type:`e2e-key-exchange`,deviceId:this.identityId,ephemeralPublicKey:n,signature:r});let o=await i,s=await this.getPeerSigningKey(this.peerId);if(!s)throw Error(`E2E authentication failed: Unknown server`);if(!await Y(s,o.ephemeralPublicKey,o.signature,this.peerId))throw Error(`E2E authentication failed: Invalid server signature`);let c=await X(t.privateKey,o.ephemeralPublicKey,o.salt,`makaio-e2e-session-v1`);this.clientSession={sessionKey:c,peerId:this.peerId};let l=await a;if(!l.success)throw Error(`E2E authentication failed: ${l.error??`Unknown error`}`)}catch(e){throw this.pendingKeyExchange&&=(clearTimeout(this.pendingKeyExchange.timeoutHandle),void 0),this.pendingResult&&=(clearTimeout(this.pendingResult.timeoutHandle),void 0),this.clientSession=void 0,this.clientEphemeralKeyPair=void 0,e}}async authenticateServer(e,t){try{let n=await this.waitForClientKeyExchange(e),r=await this.getPeerSigningKey(n.deviceId);if(!r)throw t({type:`e2e-auth-result`,success:!1,error:`Unknown device`}),Error(`E2E authentication failed: Unknown device ${n.deviceId}`);if(!await Y(r,n.ephemeralPublicKey,n.signature,n.deviceId))throw t({type:`e2e-auth-result`,success:!1,error:`Invalid signature`}),Error(`E2E authentication failed: Invalid client signature`);let{ephemeralKeyPair:i,ephemeralPublicKey:a,signature:o}=await J(this.signingKeyPair.privateKey,this.identityId),s=ut();this.serverEphemeralKeyPairs.set(e,i),t({type:`e2e-key-exchange-response`,ephemeralPublicKey:a,signature:o,salt:s});let c=await X(i.privateKey,n.ephemeralPublicKey,s,`makaio-e2e-session-v1`);this.serverSessions.set(e,{sessionKey:c,peerId:n.deviceId}),t({type:`e2e-auth-result`,success:!0})}catch(n){throw this.serverPendingKeyExchange.delete(e),this.serverEphemeralKeyPairs.delete(e),t({type:`e2e-auth-result`,success:!1,error:n instanceof Error?n.message:`Authentication failed`}),n}finally{this.serverPendingKeyExchange.delete(e)}}handleAuthMessage(e,t){if(typeof e!=`object`||!e||!(`type`in e)||typeof e.type!=`string`)return!1;let n=e;if(n.type===`e2e-key-exchange-response`)return this.pendingKeyExchange&&=(clearTimeout(this.pendingKeyExchange.timeoutHandle),this.pendingKeyExchange.resolve({ephemeralPublicKey:n.ephemeralPublicKey,signature:n.signature,salt:n.salt}),void 0),!0;if(n.type===`e2e-auth-result`)return!n.success&&this.pendingKeyExchange&&(clearTimeout(this.pendingKeyExchange.timeoutHandle),this.pendingKeyExchange.reject(Error(`E2E authentication failed: ${n.error??`Unknown error`}`)),this.pendingKeyExchange=void 0),this.pendingResult&&=(clearTimeout(this.pendingResult.timeoutHandle),this.pendingResult.resolve({success:n.success,error:n.error}),void 0),!0;if(n.type===`e2e-key-exchange`&&t){let e=this.serverPendingKeyExchange.get(t);return e&&(clearTimeout(e.timeoutHandle),e.resolve({deviceId:n.deviceId,ephemeralPublicKey:n.ephemeralPublicKey,signature:n.signature})),!0}return!1}async waitForKeyExchangeResponse(){return new Promise((e,t)=>{let n=setTimeout(()=>{this.pendingKeyExchange=void 0,t(Error(`E2E key exchange timeout`))},this.timeout);this.pendingKeyExchange={resolve:e,reject:t,timeoutHandle:n}})}async waitForAuthResult(){return new Promise((e,t)=>{let n=setTimeout(()=>{this.pendingResult=void 0,t(Error(`E2E authentication result timeout`))},this.timeout);this.pendingResult={resolve:e,reject:t,timeoutHandle:n}})}async waitForClientKeyExchange(e){return new Promise((t,n)=>{let r={resolve:t,reject:n,timeoutHandle:setTimeout(()=>{this.serverPendingKeyExchange.delete(e),n(Error(`E2E key exchange timeout`))},this.timeout)};this.serverPendingKeyExchange.set(e,r)})}getSessionKey(e){return e?this.serverSessions.get(e)?.sessionKey??null:this.clientSession?.sessionKey??null}getPeerId(e){return e?this.serverSessions.get(e)?.peerId??null:this.clientSession?.peerId??null}getReceiveContext(e){let t=this.getPeerId(e);if(t!==null)return{transportName:``,peer:{kind:`e2e`,id:t,authenticated:!0,encrypted:!0}}}cleanupSocket(e){let t=this.serverPendingKeyExchange.get(e);t&&(clearTimeout(t.timeoutHandle),this.serverPendingKeyExchange.delete(e)),this.serverSessions.delete(e),this.serverEphemeralKeyPairs.delete(e)}cleanup(){this.pendingKeyExchange&&=(clearTimeout(this.pendingKeyExchange.timeoutHandle),void 0),this.pendingResult&&=(clearTimeout(this.pendingResult.timeoutHandle),void 0),this.clientSession=void 0,this.clientEphemeralKeyPair=void 0;for(let e of this.serverPendingKeyExchange.values())clearTimeout(e.timeoutHandle);this.serverPendingKeyExchange.clear(),this.serverSessions.clear(),this.serverEphemeralKeyPairs.clear()}};const Z=`E2E relay auth session aborted by reconnect`;var pt=class{signingKeyPair;identityId;getPeerSigningKey;timeout;mode;blocking;pendingPeer;sessionKey;peerId;localEphemeral;localExchangeMessage;sentLocalExchange=!1;earlyPeer;sendAuthMessage;authGeneration=0;processingExchange=!1;constructor(e){this.signingKeyPair=e.signingKeyPair,this.identityId=e.identityId,this.getPeerSigningKey=e.getPeerSigningKey,this.timeout=e.timeout??1e4,this.mode=e.mode??`initiator`,this.blocking=e.blocking??!0}async authenticateClient(e){let t=this.sendAuthMessage===void 0?this.earlyPeer:void 0;this.cleanup();let n=this.authGeneration;if(this.earlyPeer=t,this.sendAuthMessage=e,this.mode===`initiator`){if(await this.ensureLocalExchangeMessage(),n!==this.authGeneration)throw Error(Z);this.sendLocalExchange()}if(!this.blocking){if(this.earlyPeer){let e=this.earlyPeer;this.earlyPeer=void 0,this.dispatchPeerExchange(e,n)}return}let r=await this.waitForPeerExchange();if(await this.processPeerExchange(r,n),n!==this.authGeneration||!this.sessionKey)throw Error(Z)}async authenticateServer(e,t){throw Error(`E2ERelayAuth does not support server authentication`)}handleAuthMessage(e){let t=e;return!t||t.type!==`e2e-relay-key-exchange`?!1:t.identityId===this.identityId?!0:this.pendingPeer?(this.pendingPeer.resolve(t),this.pendingPeer=void 0,!0):(this.earlyPeer=t,!this.blocking&&this.sendAuthMessage&&!this.sessionKey&&!this.processingExchange&&this.dispatchPeerExchange(t,this.authGeneration),!0)}cleanupSocket(e){}cleanup(){this.authGeneration++,this.pendingPeer&&=(this.pendingPeer.reject(Error(Z)),void 0),this.earlyPeer&&=void 0,this.sessionKey=void 0,this.peerId=void 0,this.localEphemeral=void 0,this.localExchangeMessage=void 0,this.sentLocalExchange=!1,this.processingExchange=!1,this.sendAuthMessage=void 0}dispatchPeerExchange(e,t){this.processingExchange=!0,this.processPeerExchange(e,t).catch(e=>{e instanceof Error&&e.message===Z||console.error(`[E2ERelayAuth] Peer exchange failed:`,e)}).finally(()=>{t===this.authGeneration&&(this.processingExchange=!1,this.retryQueuedPeerExchange(t))})}getSessionKey(){return this.sessionKey??null}getPeerId(){return this.peerId??null}getReceiveContext(){let e=this.getPeerId();if(e!==null)return{transportName:``,peer:{kind:`e2e`,id:e,authenticated:!0,encrypted:!0}}}async waitForPeerExchange(){if(this.earlyPeer){let e=this.earlyPeer;return this.earlyPeer=void 0,e}return new Promise((e,t)=>{let n=setTimeout(()=>{this.pendingPeer=void 0,t(Error(`E2E relay key exchange timeout`))},this.timeout),r=()=>{clearTimeout(n),this.pendingPeer=void 0};this.pendingPeer={resolve:t=>{r(),e(t)},reject:e=>{r(),t(e)},timeoutHandle:n}})}async ensureLocalExchangeMessage(){if(this.localExchangeMessage&&this.localEphemeral)return this.localExchangeMessage;let{ephemeralKeyPair:e,ephemeralPublicKey:t,signature:n}=await J(this.signingKeyPair.privateKey,this.identityId);return this.localEphemeral=e,this.localExchangeMessage={type:`e2e-relay-key-exchange`,identityId:this.identityId,ephemeralPublicKey:t,signature:n},this.localExchangeMessage}sendLocalExchange(e=!1){!this.sendAuthMessage||!this.localExchangeMessage||!e&&this.sentLocalExchange||(this.sendAuthMessage(this.localExchangeMessage),this.sentLocalExchange=!0)}retryQueuedPeerExchange(e){if(this.blocking||!this.sendAuthMessage||this.sessionKey||this.processingExchange||e!==this.authGeneration)return;let t=this.earlyPeer;t&&(this.earlyPeer=void 0,this.dispatchPeerExchange(t,e))}async processPeerExchange(e,t){if(!this.sendAuthMessage){this.earlyPeer=e;return}let n=await this.ensureLocalExchangeMessage();if(t!==this.authGeneration)return;let r=await this.getPeerSigningKey(e.identityId);if(!r)throw Error(`E2E relay authentication failed: Unknown peer ${e.identityId}`);if(!await Y(r,e.ephemeralPublicKey,e.signature,e.identityId))throw Error(`E2E relay authentication failed: Invalid peer signature`);let i=await dt(this.identityId,e.identityId,n.ephemeralPublicKey,e.ephemeralPublicKey);if(!this.localEphemeral)throw Error(`E2E relay authentication failed: Local ephemeral key missing`);let a=await X(this.localEphemeral.privateKey,e.ephemeralPublicKey,i,`makaio-e2e-relay-v1`);t===this.authGeneration&&(this.sessionKey=a,this.peerId=e.identityId,this.mode===`initiator`?this.sendLocalExchange(!0):this.sendLocalExchange())}},mt=class{hmac;e2e;socketStrategy=new Map;pendingServerAuth=new Map;hmacCancelled=new Map;constructor(e){this.hmac=e.hmac,this.e2e=e.e2e}setE2EAuth(e){this.e2e=e}async authenticateClient(e){let t=this.hmac??this.e2e;if(!t)throw Error(`DispatchingAuth: no auth strategy configured`);return t.authenticateClient(e)}async authenticateServer(e,t){let n=this.resolveSingleStrategy();if(n)return n.authenticateServer(e,t);if(!this.hmac||!this.e2e)throw Error(`DispatchingAuth: no auth strategy configured`);let r={cancelled:!1};this.hmacCancelled.set(e,r);let i=this.hmac.authenticateServer(e,e=>{r.cancelled||t(e)});return new Promise((n,a)=>{this.pendingServerAuth.set(e,{resolve:n,reject:a,send:t}),i.then(n).catch(e=>{r.cancelled||a(e instanceof Error?e:Error(String(e)))})})}handleAuthMessage(e,t){if(!t)return(this.hmac??this.e2e)?.handleAuthMessage(e)??!1;let n=this.socketStrategy.get(t);if(n)return n.handleAuthMessage(e,t);let r=this.resolveStrategy(e),i=this.pendingServerAuth.get(t);return r?(this.socketStrategy.set(t,r),this.pendingServerAuth.delete(t),r===this.hmac?this.hmacCancelled.delete(t):(this.cancelHmac(t),i&&r.authenticateServer(t,i.send).then(i.resolve).catch(e=>{i.reject(e instanceof Error?e:Error(String(e)))})),r.handleAuthMessage(e,t)):(this.cancelHmac(t),i&&(this.pendingServerAuth.delete(t),i.reject(Error(`DispatchingAuth: unrecognised auth message type "${this.peekType(e)}" — no matching strategy`))),!1)}cleanupSocket(e){let t=this.socketStrategy.get(e);t&&(t.cleanupSocket(e),this.socketStrategy.delete(e)),this.cancelHmac(e);let n=this.pendingServerAuth.get(e);n&&(this.pendingServerAuth.delete(e),n.reject(Error(`DispatchingAuth: socket disconnected before auth type was determined`)))}cleanup(){this.hmac?.cleanup(),this.e2e?.cleanup(),this.socketStrategy.clear();for(let e of this.pendingServerAuth.values())e.reject(Error(`DispatchingAuth: cleanup called before authentication completed`));this.pendingServerAuth.clear(),this.hmacCancelled.clear()}peekType(e){if(typeof e!=`object`||!e||!(`type`in e))return;let{type:t}=e;return typeof t==`string`?t:void 0}resolveSingleStrategy(){if(this.hmac&&!this.e2e)return this.hmac;if(this.e2e&&!this.hmac)return this.e2e}resolveStrategy(e){let t=this.peekType(e);if(t){if(t===`e2e-key-exchange`&&this.e2e)return this.e2e;if(t===`auth-response`&&this.hmac)return this.hmac}}cancelHmac(e){let t=this.hmacCancelled.get(e);t&&(t.cancelled=!0,this.hmacCancelled.delete(e),this.hmac?.cleanupSocket(e))}};function ht(e){return`payload`in e}async function gt(e,t,n){if(e.type!==`response`||e.result===void 0||e.error!==void 0)return;let{ciphertext:r,nonce:i}=await W(n,j(JSON.stringify(e.result)));t.result=k(r),t.e2e={nonce:k(i),v:1}}async function _t(e,t,n){if(e.type!==`broadcast-response`||e.results===void 0||e.error!==void 0)return;let{ciphertext:r,nonce:i}=await W(n,j(JSON.stringify(e.results)));t.results=k(r),t.e2e={nonce:k(i),v:1}}async function vt(e,t,n){if(!ht(e)||e.payload===void 0)return;let{ciphertext:r,nonce:i}=await W(n,j(JSON.stringify(e.payload)));t.payload=k(r),t.e2e={nonce:k(i),v:1}}async function yt(e,t,n){if(e.type!==`response`&&e.type!==`broadcast-response`||e.error===void 0)return;let{ciphertext:r,nonce:i}=await W(n,j(JSON.stringify(e.error)));t.error=k(r),t.e2e={nonce:k(i),v:1}}async function bt(e,t,n,r){if(!ht(e)||typeof e.payload!=`string`)return;let i=M(await G(n,A(e.payload),r));t.payload=JSON.parse(i)}async function xt(e,t,n,r){if(e.type!==`response`||typeof e.result!=`string`)return;let i=M(await G(n,A(e.result),r));t.result=JSON.parse(i)}async function St(e,t,n,r){if(e.type!==`broadcast-response`||typeof e.results!=`string`)return;let i=M(await G(n,A(e.results),r));t.results=JSON.parse(i)}async function Ct(e,t,n,r){if(e.type!==`response`&&e.type!==`broadcast-response`||typeof e.error!=`string`)return;let i=M(await G(n,A(e.error),r));t.error=JSON.parse(i)}async function wt(e,t){let n={...e};return await vt(e,n,t),await gt(e,n,t),await _t(e,n,t),await yt(e,n,t),n}async function Tt(e,t){if(!e.e2e)return e;let n={...e};delete n.e2e;let r=A(e.e2e.nonce);return await bt(e,n,t,r),await xt(e,n,t,r),await St(e,n,t,r),await Ct(e,n,t,r),n}function Et(e){return e.type===`subscription-ack`&&typeof e.ackId==`string`}function Dt(e){let{e2eAuth:t,websocket:n,...r}=e,i=new S({...r,url:`<pre-connected>`,createWebSocket:()=>n,auth:t,autoReconnect:!1,heartbeat:r.heartbeat??!1,messageTransform:async e=>{let n=t.getSessionKey();if(!n||Et(e))return e;let r=e;if(!r.e2e)throw Error(`Received plaintext message on E2E-encrypted channel — possible injection`);return Tt(r,n)}});async function a(e,n){let r=t.getSessionKey();if(!r)throw Error(`E2E session key not available - authentication may have failed`);let a=await wt(e,r);return i.send(a,n)}return{name:i.name,connect:i.connect.bind(i),disconnect:i.disconnect.bind(i),send:a,cancelRequest:i.cancelRequest.bind(i),onReceive:i.onReceive.bind(i),subscribe:i.subscribe.bind(i),unsubscribe:i.unsubscribe.bind(i),getSubscriptions:i.getSubscriptions.bind(i)}}function Ot(e){return Dt(e)}function kt(e){if(!e||typeof e!=`object`)return!1;let t=e;if(t.type!==`e2e-relay-envelope`||typeof t.payload!=`string`)return!1;let n=t.e2e;return!!n&&typeof n.nonce==`string`&&typeof n.v==`number`}async function At(e,t){let{ciphertext:n,nonce:r}=await W(t,j(JSON.stringify(e)));return{type:`e2e-relay-envelope`,payload:k(n),e2e:{nonce:k(r),v:1}}}async function jt(e,t){let n=A(e.e2e.nonce),r=M(await G(t,A(e.payload),n));return JSON.parse(r)}function Mt(e){let t=()=>{if(!e.isFrozen())throw Error(`RelayControlRegistry must be frozen before processing relay control messages`)};function n(t){return typeof t.namespace!=`string`||typeof t.subject!=`string`||!e.isControlEvent(t.namespace,t.subject)||typeof t.messageId!=`string`?!1:t.payload!==void 0}function r(t){return typeof t.namespace!=`string`||typeof t.subject!=`string`||!e.isControlRequest(t.namespace,t.subject)||typeof t.messageId!=`string`||typeof t.correlationId!=`string`?!1:t.payload!==void 0}function i(e){if(t(),!e||typeof e!=`object`)return!1;let i=e;return i.type===`event`?n(i):i.type===`request`?r(i):!1}function a(e){if(t(),!e||typeof e!=`object`)return!1;let n=e;return n.type!==`relay-control`||n.v!==1||!n.payload||typeof n.payload!=`object`?!1:i(n.payload)}function o(e){if(t(),!i(e))throw Error(`Invalid relay control message`);return{type:`relay-control`,v:1,payload:e}}return{createRelayControlEnvelope:o,isRelayControlEnvelopeMessage:a,isRelayControlBusMessage:i}}function Q(e){let t=Date.now()-3e5;for(let[n,r]of e)r>=t||e.delete(n);for(;e.size>2048;){let t=e.keys().next().value;if(!t)break;e.delete(t)}}const Nt=e=>{if(!e||typeof e!=`object`)return!1;let t=e;return t.type===`response`&&typeof t.correlationId==`string`},Pt=e=>e.type===`subscribe`||e.type===`unsubscribe`,Ft=e=>{if(!e||typeof e!=`object`)return!1;let t=e;return t.type===`subscription-ack`&&typeof t.ackId==`string`};function $(e,t,n,r){if(!r.isFrozen())throw Error(`E2ERelay transport requires a frozen relay control registry`);let{createRelayControlEnvelope:i,isRelayControlEnvelopeMessage:a,isRelayControlBusMessage:o}=Mt(r),s=e=>{n.delete(e),n.set(e,Date.now()),Q(n)};return{encode:async t=>{if(o(t))return t.type===`request`&&s(t.correlationId),JSON.stringify(i(t));if(Q(n),t.type===`response`&&n.has(t.correlationId))return n.delete(t.correlationId),JSON.stringify(t);let r=e.getSessionKey();if(!r&&Pt(t)||!r&&Ft(t))return JSON.stringify(t);if(!r)throw Error(`E2E relay session not established`);let a=await At(t,r);return JSON.stringify(a)},decode:async r=>{let i=e.getSessionKey();if(a(r)){let e=r.payload;return t&&console.info(`[E2ERelayTransport] Decoded relay control envelope:`,e.type,e.namespace,e.subject),e.type===`request`&&s(e.correlationId),e}if(Q(n),Nt(r)&&n.has(r.correlationId))return n.delete(r.correlationId),r;if(!i&&Ft(r))return r;if(!i)throw Error(`E2E relay session not established`);if(!kt(r))throw Error(`Received plaintext message on relay E2E channel — possible injection`);return jt(r,i)}}}function It(e,t,n=!1){let r=new Map;return{codec:$(e,n,r,t),reset:()=>r.clear()}}function Lt(e){let{e2eAuth:t,registry:n,websocket:r,...i}=e,a=e.debug??!1,o=new Map,s=$(t,a,o,n);a&&console.info(`[E2ERelayTransport] Creating inner transport...`);let c=new S({...i,url:`<pre-connected>`,createWebSocket:()=>r,auth:t,codec:s,autoReconnect:!1,heartbeat:i.heartbeat??!1});return a&&console.info(`[E2ERelayTransport] Inner transport created`),{name:c.name,connect:async()=>{if(!n.isFrozen())throw Error(`E2ERelayClientTransport: registry must be frozen before connect()`);o.clear();try{await c.connect()}catch(e){throw o.clear(),e}},disconnect:async()=>{o.clear();try{await c.disconnect()}finally{o.clear()}},send:c.send.bind(c),cancelRequest:c.cancelRequest.bind(c),onReceive:(...e)=>(a&&console.info(`[E2ERelayTransport] onReceive called, delegating to inner transport`),c.onReceive(...e)),subscribe:c.subscribe.bind(c),unsubscribe:c.unsubscribe.bind(c),getSubscriptions:c.getSubscriptions.bind(c),isReady:()=>!!t.getSessionKey()&&c.isReady()}}function Rt(){let e=!1,t=new Map,n=new Map,r=()=>{if(e)throw Error(`RelayControlRegistry is frozen and cannot be modified`)};return{registerEventSubjects(e,n){r();let i=t.get(e)??new Set;for(let e of n)i.add(e);t.set(e,i)},registerRequestNamespace(e,t){if(r(),t.length===0)throw Error(`RelayControlRegistry request namespace "${e}" requires at least one subject`);let i=n.get(e)??new Set;for(let e of t)i.add(e);n.set(e,i)},freeze(){e=!0},isFrozen(){return e},isControlEvent(e,n){return t.get(e)?.has(n)??!1},isControlRequest(e,t){return n.get(e)?.has(t)??!1}}}function zt(e){if(Ue(e),e.mode===`client`){if(e.connectionOptions!==void 0)throw Error(`createWebSocketTransport(client) does not support connectionOptions when wrapping a pre-created WebSocket. Use WebSocketClientTransport for reconnect or dial-time socket options.`);let t=e.websocket;return new S({url:`<pre-connected>`,createWebSocket:()=>t,auth:e.auth,debug:e.debug,autoReconnect:!1,heartbeat:!1})}else return new O({websocket:e.websocket,auth:e.auth,debug:e.debug})}export{mt as DispatchingAuth,ft as E2EAuth,pt as E2ERelayAuth,Ke as HmacAuth,O as ServerTransport,S as WebSocketClientTransport,Ee as clearHmacIdentitySecretsForTesting,Ot as createE2EClientTransport,Lt as createE2ERelayClientTransport,It as createE2ERelayCodec,Mt as createRelayControlHelpers,Rt as createRelayControlRegistry,He as createWebSocketCloseEvent,zt as createWebSocketTransport,ct as crypto,g as extractSocketErrorMessage,Se as registerHmacIdentitySecret,T as resolveHmacIdentityAllowedSubjects,Te as resolveHmacIdentityPeer,we as resolveHmacIdentitySecret,Ce as rotateHmacIdentitySecret};
1
+ import{r as e}from"../../chunk-DTipWd-i.mjs";import{isRecord as t}from"@makaio/framework/utils";import{ConnectionLostError as n,CorrelationTracker as r,DEFAULT_REQUEST_TIMEOUT_MS as i,NoHandlerError as a,TimeoutError as o,buildSubscribeMessage as s,buildUnsubscribeMessage as c,deserializeTransportError as l,getSubjectFromBusMessage as u,handleCorrelationResponse as d,isNoHandlerErrorForSubject as f,matchesSubscription as p,shouldReceiveMessage as m,trackMessageCorrelation as h}from"@makaio/framework/bus";const g={baseMs:1e3,maxMs:1e4};function ee(e,t,n){let r=Math.max(t,100),i=Math.max(n,r);return Math.min(r*2**e,i)}function te(e,t){return new Promise(n=>{if(t.aborted){n();return}let r=()=>{clearTimeout(i),t.removeEventListener(`abort`,r),n()},i=setTimeout(()=>{t.removeEventListener(`abort`,r),n()},e);t.addEventListener(`abort`,r)})}const _={intervalMs:3e4,timeoutMs:1e4},ne={encode:async e=>JSON.stringify(e),decode:async e=>e};function re(e){return e===!1?!1:{baseMs:e?.baseMs??g.baseMs,maxMs:e?.maxMs??g.maxMs}}function ie(e){if(e===!1)return!1;let t=e?.intervalMs??_.intervalMs,n=e?.timeoutMs??_.timeoutMs;if(!Number.isFinite(t)||t<=0)throw RangeError(`heartbeat.intervalMs must be a finite number > 0 (got ${String(t)})`);if(!Number.isFinite(n)||n<=0)throw RangeError(`heartbeat.timeoutMs must be a finite number > 0 (got ${String(n)})`);return{intervalMs:t,timeoutMs:n}}var v=class extends Error{code;constructor(e,t,n){super(t,n),this.code=e,this.name=`WebSocketConnectionError`}};function y(e){let t=typeof e==`object`&&!!e&&`code`in e&&e.code===1008;return new v(t?`WS_POLICY_REJECTED`:`WS_CONNECTION_UNAVAILABLE`,t?`WebSocket connection rejected by peer policy`:`WebSocket closed before connection completed`)}function b(e,t=`unknown error`){return`message`in e?String(e.message):t}async function x(e,t,n){let r=await t.encode(e);n.send(r)}function ae(e,t,n){return n?.aborted?Promise.reject(n.reason):e.readyState===1?Promise.resolve():e.readyState>=2?Promise.reject(y()):new Promise((r,i)=>{let a=()=>{u!==void 0&&clearTimeout(u),e.removeEventListener(`open`,o),e.removeEventListener(`error`,s),e.removeEventListener(`close`,c),n?.removeEventListener(`abort`,l)},o=()=>{a(),r()},s=e=>{a(),i(new v(`WS_CONNECTION_UNAVAILABLE`,`WebSocket connection failed — ${b(e)}`,{cause:e}))},c=e=>{a(),i(y(e))},l=()=>{a(),i(n?.reason)},u=t===void 0?void 0:setTimeout(()=>{a(),i(new v(`WS_CONNECTION_TIMEOUT`,`WebSocket open timed out after ${t}ms`))},t);e.addEventListener(`open`,o),e.addEventListener(`error`,s),e.addEventListener(`close`,c),n?.addEventListener(`abort`,l)})}function S(e){if(e.readyState!==0&&e.readyState!==1)return;let t=()=>{},n=()=>{e.removeEventListener(`error`,t),e.removeEventListener(`close`,n)};e.addEventListener(`error`,t),e.addEventListener(`close`,n);try{e.close()}catch(e){throw n(),e}}async function oe(e,t,n){let r=await Promise.allSettled(Array.from(t).map(t=>t(e,n.receiveContext)));for(let e of r)e.status===`rejected`&&n.debug&&console.error(`[WebSocketClientTransport:${n.name}] Handler error:`,e.reason);return r.every(e=>e.status===`fulfilled`)}function se(e,t){return{...t?.getReceiveContext?.(),transportName:e}}async function ce(e,t){let{name:n,debug:r,auth:i,codec:a,messageTransform:o,correlations:s}=t,c=JSON.parse(e.toString());if(typeof c!=`object`||!c||typeof c.type!=`string`)return r&&console.error(`[WebSocketClientTransport:${n}] Invalid message structure:`,c),null;let l=c;if(i?.handleAuthMessage(l)||l.type===`heartbeat`)return null;let u=await a.decode(l);return!t.isCurrentSession()||o&&(u=await o(u),!t.isCurrentSession())||u.type===`heartbeat`?null:u.type===`subscribe-sync-complete`?(t.onSyncComplete(),null):u.type===`subscription-ack`?(typeof u.ackId==`string`&&t.onSubscriptionAck(u.ackId),null):d(u,s)?null:u}async function le(e,t){let{name:n,debug:r,auth:i,handlers:a}=t,o=null;try{o=await ce(e,t)}catch(e){r&&console.error(`[WebSocketClientTransport:${n}] Failed to parse message:`,e);return}if(o===null||!t.isCurrentSession())return;let s=se(n,i),c=o;oe(c,a,{debug:r,name:n,receiveContext:s}).then(async e=>{e&&(c.type===`subscribe`||c.type===`unsubscribe`)&&typeof c.ackId==`string`&&await t.sendSubscriptionAck(c.ackId)}).catch(e=>{r&&console.error(`[WebSocketClientTransport:${n}] Handler dispatch error:`,e)})}function ue(e){let t=e;return typeof t.ping==`function`&&typeof t.terminate==`function`&&typeof t.on==`function`&&typeof t.off==`function`}function de(e){e.unref?.()}function fe(e,t,n){if(!ue(e))return()=>{};let r=!1,i=Date.now(),a=null,o=null,s=()=>{if(r)return;let e=Date.now()-i,n=Math.max(0,t.intervalMs-e);a=setTimeout(l,n),de(a)},c=()=>{o=null,f(),n.debug&&console.warn(`[WebSocketClientTransport:${n.name}] ${new Date().toISOString()} Heartbeat deadline expired (no message/pong within ${t.timeoutMs}ms) — terminating socket`),e.terminate()},l=()=>{if(a=null,!r&&o===null){if(Date.now()-i<t.intervalMs){s();return}e.readyState===1&&(e.ping(),o=setTimeout(c,t.timeoutMs),de(o))}},u=()=>{i=Date.now(),o!==null&&(clearTimeout(o),o=null),a===null&&s()},d=()=>{f()},f=()=>{r||(r=!0,a!==null&&(clearTimeout(a),a=null),o!==null&&(clearTimeout(o),o=null),e.removeEventListener(`message`,u),e.removeEventListener(`close`,d),e.off(`pong`,u))};return e.addEventListener(`message`,u),e.on(`pong`,u),e.addEventListener(`close`,d),s(),f}async function pe(e,t){await Promise.allSettled(e.inFlightMessages),e.getSocket()===t&&e.correlations.rejectAll(e.getSessionFailure()??new n(e.name))}function me(e,t){let n=n=>{if(t.getSocket()!==e)return;let r=le(n.data,{isCurrentSession:()=>t.getSocket()===e,name:t.name,debug:t.debug,auth:t.auth,codec:t.codec,messageTransform:t.messageTransform,correlations:t.correlations,handlers:t.handlers,onSyncComplete:()=>{t.resolveReady()},onSubscriptionAck:e=>{t.resolveSubscriptionAck(e)},sendSubscriptionAck:async n=>{t.getSocket()!==e||e.readyState!==1||await x({type:`subscription-ack`,ackId:n},t.codec,e)}}).finally(()=>{t.inFlightMessages.delete(r)});t.inFlightMessages.add(r)};t.setMessageListener(n),e.addEventListener(`message`,n)}function C(e,t){if(t.getSocket()!==e)return;let n=t.getMessageListener();n!==null&&(e.removeEventListener(`message`,n),t.setMessageListener(null));let r=t.getCloseListener();r!==null&&(e.removeEventListener(`close`,r),t.setCloseListener(null))}function he(e,t,n){let r=[n];if(t.getSocket()===e){C(e,t),t.setSocket(null,n instanceof Error?n:Error(`WebSocket connection failed`,{cause:n})),t.setAuthComplete(!1);try{t.auth?.cleanup()}catch(e){r.push(e)}}try{S(e)}catch(e){r.push(e)}return r.length===1?n:AggregateError(r,`WebSocket connection failed and cleanup was incomplete`,{cause:n})}async function ge(e,t){t.throwIfAborted();let n=new AbortController,r=()=>n.abort(new v(`WS_CONNECTION_UNAVAILABLE`,`WebSocket connection cancelled`));t.addEventListener(`abort`,r);let i=setTimeout(()=>n.abort(new v(`WS_CONNECTION_TIMEOUT`,`WebSocket connection timed out after ${e.connectTimeoutMs}ms`)),e.connectTimeoutMs),a=null,o=()=>{},s=()=>{a?.removeEventListener(`close`,c),a?.removeEventListener(`error`,l)},c=e=>n.abort(y(e)),l=e=>n.abort(new v(`WS_CONNECTION_UNAVAILABLE`,`WebSocket connection failed — ${b(e)}`,{cause:e})),u=t=>{if(o(),a===null)return t;let n=a;return s(),a=null,he(n,e,t)},d=()=>{},f=new Promise((e,t)=>{d=()=>{t(u(n.signal.reason))},n.signal.addEventListener(`abort`,d)});try{let t=_e(e,n.signal,()=>{o=e.resetReadyPromise()},t=>{a=t,e.setSocket(t),e.setAuthComplete(!1),t.addEventListener(`close`,c),t.addEventListener(`error`,l),me(t,e)});await Promise.race([t,f])}catch(e){throw u(e)}finally{clearTimeout(i),t.removeEventListener(`abort`,r),n.signal.removeEventListener(`abort`,d),s()}}async function _e(e,t,r,i){e.inFlightMessages.size>0&&await Promise.allSettled(e.inFlightMessages),t.throwIfAborted();let a=e.getSocket();e.correlations.rejectAll(e.getSessionFailure()??new n(e.name)),e.inFlightMessages.clear(),e.resolveReady(),e.rejectPendingSubscriptionAcks(Error(`WebSocketClientTransport: reconnecting before subscription ack`)),r(),t.throwIfAborted(),a!==null&&C(a,e);let o=await e.wsFactory(e.url);t.aborted&&(S(o),t.throwIfAborted()),i(o),await ve(o,e,t)}async function ve(e,t,n){if(await ae(e,void 0,n),n.throwIfAborted(),t.auth&&(await t.auth.authenticateClient(t=>{if(n.throwIfAborted(),e.readyState!==1)throw y();e.send(JSON.stringify(t))}),n.throwIfAborted()),t.setAuthComplete(!0),t.localSubscriptions.size>0){let r=await t.codec.encode(s(t.localSubscriptions));n.throwIfAborted(),e.send(r)}t.heartbeat!==!1&&fe(e,t.heartbeat,t),t.debug&&console.info(`[WebSocketClientTransport:${t.name}] Connected to ${t.url}`),t.notifyConnected()}function w(e,t){return new Promise(n=>{if(e.readyState===3||t.aborted){n();return}let r=()=>{t.removeEventListener(`abort`,i),n()},i=()=>{e.removeEventListener(`close`,r),n()};e.addEventListener(`close`,r),t.addEventListener(`abort`,i)})}async function ye(e,t,r,i,a){a(!0);try{for(;!e.aborted;){let a=r.getSocket(),o=a!==null;if(a!==null&&a.readyState!==3&&await w(a,e),e.aborted)break;if(o&&a!==null){if(await pe(r,a),e.aborted)break;r.debug&&console.info(`[WebSocketClientTransport:${r.name}] ${new Date().toISOString()} Connection lost, starting reconnect loop (maxMs=${t.maxMs})`),r.notifyDisconnected()}let s=0;for(;!e.aborted;){let a=ee(s,t.baseMs,t.maxMs);r.debug&&console.info(`[WebSocketClientTransport:${r.name}] ${new Date().toISOString()} Reconnecting in ${a}ms (attempt ${s+1})`);let o=new AbortController;if(i(o),await te(a,AbortSignal.any([e,o.signal])),i(null),e.aborted)break;try{if(await ge(r,e),e.aborted)break;s=0;let t=r.getSocket();if(t!==null){let i=async()=>{await Promise.allSettled(r.inFlightMessages),!(e.aborted||r.getSocket()!==t)&&(r.correlations.rejectAll(r.getSessionFailure()??new n(r.name)),r.auth?.cleanup(),r.setAuthComplete(!1),r.debug&&console.info(`[WebSocketClientTransport:${r.name}] ${new Date().toISOString()} Connection closed`),r.rejectPendingSubscriptionAcks(Error(`WebSocketClientTransport: disconnected before subscription ack`)))};r.setCloseListener(i),t.addEventListener(`close`,i),await w(t,e)}break}catch(e){if(r.debug){let t=e instanceof Error?e.message:String(e);console.warn(`[WebSocketClientTransport:${r.name}] ${new Date().toISOString()} Connect attempt ${s+1} failed: ${t}`)}s++}}}}finally{a(!1)}}function be(e,t,n){let r=async()=>{t.getSocket()===e&&(C(e,t),t.auth?.cleanup(),t.setAuthComplete(!1),n(),t.resolveReady(),t.notifyDisconnected(),await pe(t,e),t.getSocket()===e&&(t.setSocket(null),t.rejectPendingSubscriptionAcks(Error(`WebSocketClientTransport: disconnected before subscription ack`))))};t.setCloseListener(r),e.addEventListener(`close`,r)}async function xe(e,t,n,r,i){let a=i.localSubscriptions.get(e),o=a?.filter,c=t??o,l=r??a?.deliveryClass??`relayable`;if(i.localSubscriptions.set(e,{filter:c,priorities:n,deliveryClass:l}),i.socket!==null&&i.socket.readyState===1){let t=i.beginSubscriptionAck?.(),r=s(new Map([[e,{filter:c,priorities:n,deliveryClass:l}]]),t?.ackId);try{await x(r,i.codec,i.socket),await t?.promise}catch(e){throw t?.reject(e),e}}i.debug&&console.info(`[WebSocketClientTransport:${i.name}] Subscribed to ${e}${c?` with filter`:``}`)}async function Se(e,t){let n=t.localSubscriptions.get(e);if(t.localSubscriptions.delete(e),t.socket!==null&&t.socket.readyState===1){let r=t.beginSubscriptionAck?.(),i=c({[e]:n?.priorities??[]},r?.ackId);try{await x(i,t.codec,t.socket),await r?.promise}catch(e){throw r?.reject(e),e}}t.debug&&console.info(`[WebSocketClientTransport:${t.name}] Unsubscribed from ${e}`)}var Ce=class{name;termination=new AbortController;ownedSocket;onClose;constructor(e,t){this.name=t,this.ownedSocket=e,this.onClose=e=>{let r=y(e);this.end(r.code===`WS_POLICY_REJECTED`?r:new n(t))},e.addEventListener(`close`,this.onClose)}get socket(){return this.ownedSocket}get signal(){return this.termination.signal}get failure(){return this.signal.reason instanceof Error?this.signal.reason:void 0}end(e){this.ownedSocket?.removeEventListener(`close`,this.onClose),this.termination.abort(e)}release(e=new n(this.name)){this.end(e),this.ownedSocket=null}writable(e,t){if(t?.throwIfAborted(),this.signal.throwIfAborted(),e!==this||this.ownedSocket===null)throw new n(this.name);let r=this.ownedSocket;if(r.readyState===2||r.readyState===3){if(t===void 0)throw Error(`WebSocket is closing; uncorrelated message was not sent`);return T(new Promise(()=>{}),AbortSignal.any([t,this.signal]))}if(r.readyState!==1)throw new n(this.name);return r}};async function T(e,t){let n=()=>{},r=new Promise((e,r)=>{n=()=>r(t.reason),t.addEventListener(`abort`,n,{once:!0}),t.aborted&&n()});try{return await Promise.race([e,r])}finally{t.removeEventListener(`abort`,n)}}async function we(e,t,r){let i=e.session;if(i===null)throw new n(e.name);if(i.signal.throwIfAborted(),t.type!==`request`&&t.type!==`broadcast`)return await E(e,i,t),h(t,e.correlations,r);let a=new AbortController,o=h(t,e.correlations,r).then(e=>(a.abort(),e),e=>{throw a.abort(e),e});return E(e,i,t,a.signal).catch(n=>{if(a.signal.aborted)return;let r=n instanceof Error?n:Error(`WebSocket send failed`,{cause:n});e.correlations.reject(t.correlationId,r)}),o}async function E(e,t,n,r){let i=t.writable(e.currentSession(),r);i instanceof Promise&&await i;let a=r===void 0?t.signal:AbortSignal.any([r,t.signal]);a.throwIfAborted();let o=await T(e.codec.encode(n),a),s=t.writable(e.currentSession(),r);s instanceof Promise?await s:s.send(o)}var D=class{name;url;auth;codec;messageTransform;autoReconnectConfig;heartbeatConfig;connectTimeoutMs;wsFactory;debug;onConnectedCallback;onDisconnectedCallback;session=null;authComplete=!1;correlations=new r;handlers=new Set;localSubscriptions=new Map;pendingSubscriptionAcks=new Map;subscriptionAckSeq=0;messageListener=null;closeListener=null;reconnectAbort=null;inFlightMessages=new Set;backoffWakeAbort=null;reconnectLoopRunning=!1;readyResolve=null;ready;onNewReadySession=void 0;onConnected=void 0;onDisconnected=void 0;get socket(){return this.session?.socket??null}constructor(e){this.url=e.url,this.name=e.name??`ws-client`,this.auth=e.auth,this.codec=e.codec??ne,this.messageTransform=e.messageTransform,this.debug=e.debug??!1,this.autoReconnectConfig=re(e.autoReconnect),this.heartbeatConfig=ie(e.heartbeat),this.connectTimeoutMs=e.connectTimeoutMs??3e4,this.wsFactory=e.createWebSocket??this.defaultWsFactory,this.onConnectedCallback=e.onConnected,this.onDisconnectedCallback=e.onDisconnected,this.ready=new Promise(e=>{this.readyResolve=e})}async connect(){if(this.reconnectAbort!==null)throw Error(`WebSocketClientTransport: already connected`);let e=new AbortController;this.reconnectAbort=e;try{await ge(this.connectionDeps(),e.signal)}catch(t){throw this.reconnectAbort===e&&(this.reconnectAbort=null),t}if(e.signal.aborted||this.reconnectAbort!==e)throw new v(`WS_CONNECTION_UNAVAILABLE`,`WebSocket connection cancelled`);this.autoReconnectConfig===!1?this.socket!==null&&this.wireNoReconnectClose(this.socket):this.startReconnectLoop(e.signal)}async disconnect(){let e=this.reconnectAbort,t=this.socket;this.reconnectAbort=null,e?.abort(new v(`WS_CONNECTION_UNAVAILABLE`,`WebSocket connection cancelled`));let r=t===null||this.socket===t;if(this.reconnectLoopRunning=!1,this.backoffWakeAbort=null,this.readyResolve?.(),this.readyResolve=null,this.socket!==null){C(this.socket,this.connectionDeps());let e=this.socket;this.session?.release(),this.authComplete=!1,S(e)}this.correlations.rejectAll(this.session?.failure??new n(this.name)),this.rejectPendingSubscriptionAcks(Error(`WebSocketClientTransport: disconnected before subscription ack`)),r&&this.auth?.cleanup(),this.handlers.clear(),this.debug&&console.info(`[WebSocketClientTransport:${this.name}] Disconnected`)}async send(e,t){return we({session:this.session,currentSession:()=>this.session,name:this.name,codec:this.codec,correlations:this.correlations},e,t??i)}onReceive(e){return this.handlers.add(e),()=>{this.handlers.delete(e)}}async subscribe(e,t,n=[],r){await xe(e,t,n,r,this.subscriptionDeps())}async unsubscribe(e){await Se(e,this.subscriptionDeps())}getSubscriptions(){return new Set(this.localSubscriptions.keys())}cancelRequest(e,t){this.correlations.cancel(e,t)}isReady(){return this.socket!==null&&this.socket.readyState===1&&this.authComplete}async reconnect(){if(!this.isReady()){if(this.backoffWakeAbort!==null){this.backoffWakeAbort.abort(),this.backoffWakeAbort=null;return}if(this.autoReconnectConfig!==!1){if(this.reconnectLoopRunning){let e=this.socket;e!==null&&e.readyState===0&&e.close();return}return}try{this.reconnectAbort===null&&await this.connect()}catch{}}}startReconnectLoop(e){return ye(e,this.autoReconnectConfig,this.connectionDeps(),t=>{e.aborted||(this.backoffWakeAbort=t)},t=>{this.reconnectAbort?.signal===e&&(this.reconnectLoopRunning=t)})}subscriptionDeps(){return{name:this.name,debug:this.debug,codec:this.codec,socket:this.socket,localSubscriptions:this.localSubscriptions,beginSubscriptionAck:()=>this.beginSubscriptionAck()}}beginSubscriptionAck(){let e=`${this.name}:sub:${++this.subscriptionAckSeq}`,t,n,r=new Promise((e,r)=>{t=e,n=r});r.catch(()=>void 0);let i=t=>{this.pendingSubscriptionAcks.has(e)&&(this.pendingSubscriptionAcks.delete(e),t())};return this.pendingSubscriptionAcks.set(e,{resolve:()=>i(t),reject:e=>i(()=>n(e))}),{ackId:e,promise:r,reject:t=>this.rejectSubscriptionAck(e,t)}}resolveSubscriptionAck(e){this.pendingSubscriptionAcks.get(e)?.resolve()}rejectSubscriptionAck(e,t){this.pendingSubscriptionAcks.get(e)?.reject(t)}rejectPendingSubscriptionAcks(e){for(let t of this.pendingSubscriptionAcks.keys())this.rejectSubscriptionAck(t,e)}connectionDeps(){return{name:this.name,debug:this.debug,auth:this.auth,codec:this.codec,messageTransform:this.messageTransform,correlations:this.correlations,handlers:this.handlers,localSubscriptions:this.localSubscriptions,wsFactory:this.wsFactory,url:this.url,connectTimeoutMs:this.connectTimeoutMs,heartbeat:this.heartbeatConfig,getSocket:()=>this.socket,setSocket:(e,t)=>{this.session?.release(t),e!==null&&(this.session=new Ce(e,this.name))},getSessionFailure:()=>this.session?.failure,setAuthComplete:e=>{this.authComplete=e},getMessageListener:()=>this.messageListener,setMessageListener:e=>{this.messageListener=e},getCloseListener:()=>this.closeListener,setCloseListener:e=>{this.closeListener=e},resolveReady:()=>{this.readyResolve?.(),this.readyResolve=null},resetReadyPromise:()=>{let e;this.ready=new Promise(t=>{this.readyResolve=t,e=t});let t=()=>{e(),this.readyResolve===e&&(this.readyResolve=null)};try{this.onNewReadySession?.(this.ready)}catch(e){throw t(),e}return t},resolveSubscriptionAck:e=>{this.resolveSubscriptionAck(e)},rejectPendingSubscriptionAcks:e=>{this.rejectPendingSubscriptionAcks(e)},notifyConnected:()=>{let e=this.socket;this.onConnectedCallback?.(),e!==null&&this.socket===e&&this.isReady()&&this.onConnected?.()},notifyDisconnected:()=>{this.onDisconnectedCallback?.(),this.onDisconnected?.()},inFlightMessages:this.inFlightMessages}}defaultWsFactory=async e=>new(await(import(`ws`))).WebSocket(e);wireNoReconnectClose(e){be(e,this.connectionDeps(),()=>{this.reconnectAbort=null})}};function O(e){e.timer!==void 0&&clearTimeout(e.timer)}var Te=class{pendingBroadcasts=new Map;timeout;debug;constructor(e={}){this.timeout=e.timeout??5e3,this.debug=e.debug??!1}startClientBroadcast(e,t,n,r,i){let a=t.correlationId,o=i??this.timeout,s={kind:`client`,sender:e,results:[],pendingClients:new Set(n),nodeResultsReceived:!1,timer:o===0?void 0:setTimeout(()=>{this.debug&&console.warn(`[BroadcastAggregator] Broadcast ${a} timed out`),this.finalizeBroadcast(a)},o)};this.pendingBroadcasts.set(a,s);let c=JSON.stringify(t);for(let e of n)r(e,c);this.debug&&console.info(`[BroadcastAggregator] Broadcast ${a} forwarded to ${n.length} clients`)}startServerBroadcast(e,t,n,r){let i=e.correlationId,a=r??this.timeout;return t.length===0?(this.debug&&console.info(`[BroadcastAggregator] Server broadcast ${i} - no target clients`),Promise.resolve([])):new Promise(r=>{let o={kind:`server`,results:[],pendingClients:new Set(t),timer:a===0?void 0:setTimeout(()=>{this.debug&&console.warn(`[BroadcastAggregator] Server broadcast ${i} timed out`),this.finalizeServerBroadcast(i)},a),resolve:r};this.pendingBroadcasts.set(i,o);let s=JSON.stringify(e);for(let e of t)n(e,s);this.debug&&console.info(`[BroadcastAggregator] Server broadcast ${i} sent to ${t.length} clients`)})}handleResponse(e,t){let n=this.pendingBroadcasts.get(t.correlationId);return n?(t.results&&n.results.push(...t.results),n.pendingClients.delete(e),this.debug&&console.info(`[BroadcastAggregator] Broadcast ${t.correlationId} got response, ${n.pendingClients.size} pending`),this.checkBroadcastComplete(t.correlationId,n),!0):!1}handleNodeResults(e,t,n){let r=this.pendingBroadcasts.get(e);return!r||r.kind!==`client`?!1:(r.results.push(...t),r.nodeResultsReceived=!0,r.nodeError=n,this.debug&&console.info(`[BroadcastAggregator] Broadcast ${e} node results aggregated${n?` (with error)`:``}`),this.checkBroadcastComplete(e,r),!0)}handleClientDisconnect(e){for(let[t,n]of this.pendingBroadcasts)n.kind===`client`&&n.sender===e?(O(n),this.pendingBroadcasts.delete(t)):n.pendingClients.has(e)&&(n.pendingClients.delete(e),this.checkBroadcastComplete(t,n))}cleanup(){for(let e of this.pendingBroadcasts.values())O(e),e.kind===`server`&&e.resolve(e.results);this.pendingBroadcasts.clear()}checkBroadcastComplete(e,t){if(!(t.pendingClients.size>0))if(t.kind===`client`){if(!t.nodeResultsReceived)return;this.finalizeBroadcast(e)}else this.finalizeServerBroadcast(e)}finalizeBroadcast(e){let t=this.pendingBroadcasts.get(e);if(!t||t.kind!==`client`)return;O(t),this.pendingBroadcasts.delete(e);let n=t.nodeError?{type:`broadcast-response`,correlationId:e,error:t.nodeError}:{type:`broadcast-response`,correlationId:e,results:t.results};t.sender.readyState===1&&t.sender.send(JSON.stringify(n)),this.debug&&console.info(`[BroadcastAggregator] Broadcast ${e} finalized with ${t.results.length} results`)}finalizeServerBroadcast(e){let t=this.pendingBroadcasts.get(e);!t||t.kind!==`server`||(O(t),this.pendingBroadcasts.delete(e),t.resolve(t.results),this.debug&&console.info(`[BroadcastAggregator] Server broadcast ${e} finalized with ${t.results.length} results`))}},Ee=class{clients=new Set;authenticatingClients=new Set;clientSubscriptions=new Map;clientSubscriptionState=new Map;clientFilters=new Map;requestOrigins=new Map;debug;subjectRestrictionResolver;socketAuthChecker;constructor(e={}){this.debug=e.debug??!1,this.subjectRestrictionResolver=e.subjectRestrictionResolver,this.socketAuthChecker=e.socketAuthChecker}addAuthenticating(e){this.authenticatingClients.add(e)}removeAuthenticating(e){this.authenticatingClients.delete(e)}isAuthenticating(e){return this.authenticatingClients.has(e)}addClient(e){this.clients.add(e)}removeClient(e){let t=new Set(this.clientSubscriptionState.get(e)?.keys()??[]);this.clients.delete(e),this.authenticatingClients.delete(e),this.clientSubscriptions.delete(e),this.clientSubscriptionState.delete(e),this.clientFilters.delete(e);for(let[t,n]of this.requestOrigins)n.socket===e&&this.clearRequestOrigin(t,n);return this.debug&&console.info(`[ClientRegistry] Client removed (${this.clients.size} remaining)`),this.buildAggregateUpdates(t)}get size(){return this.clients.size}getAllSockets(){return new Set([...this.clients,...this.authenticatingClients])}handleSubscribeMessage(e,t){let n=this.clientSubscriptions.get(e);n||(n=new Set,this.clientSubscriptions.set(e,n));let r=this.clientFilters.get(e),i=this.clientSubscriptionState.get(e);i||(i=new Map,this.clientSubscriptionState.set(e,i));for(let[a,o]of Object.entries(t.subjects)){n.add(a),i.set(a,{priorities:o,deliveryClass:t.deliveryClasses?.[a]===`relayable`?`relayable`:`first-hop-only`});let s=t.filters?.[a];s===void 0?r?.delete(a):(r||(r=new Map,this.clientFilters.set(e,r)),r.set(a,s))}if(this.debug){let e=Object.keys(t.subjects).length,n=t.filters?Object.keys(t.filters).length:0;console.info(`[ClientRegistry] Client subscribed to ${e} subjects, ${n} filters`)}return this.buildAggregateUpdates(new Set(Object.keys(t.subjects)))}handleUnsubscribeMessage(e,t){let n=this.clientSubscriptions.get(e),r=this.clientFilters.get(e);for(let i of Object.keys(t))n?.delete(i),this.clientSubscriptionState.get(e)?.delete(i),r?.delete(i);return this.debug&&console.info(`[ClientRegistry] Client unsubscribed from ${Object.keys(t).length} subjects`),this.buildAggregateUpdates(new Set(Object.keys(t)))}getReadyClients(){let e=[];for(let t of this.clients)t.readyState===1&&e.push(t);return e}trackRequestOrigin(e,t){let{correlationId:n}=t;if(this.requestOrigins.has(n))return;let r=this.getRequestRemainingLifetime(t);if(r===0)return;let i={socket:e,expiration:void 0};r!==void 0&&(i.expiration=setTimeout(()=>{this.requestOrigins.get(n)===i&&this.requestOrigins.delete(n)},r)),this.requestOrigins.set(n,i)}getRequestOrigin(e){return this.requestOrigins.get(e)?.socket}consumeResponseClient(e){let t=this.requestOrigins.get(e);if(t)return this.clearRequestOrigin(e,t),this.isReadyAndAuthenticated(t.socket)?t.socket:void 0}cancelRequestOrigin(e){let t=this.requestOrigins.get(e);t&&this.clearRequestOrigin(e,t)}getInterestedClients(e,t,n){let r=[];for(let i of this.clients)i===n||!this.isReadyAndAuthenticated(i)||this.clientWantsMessage(i,e,t)&&this.isSubjectAllowedForClient(i,e)&&r.push(i);return r}getInterestedRequestClients(e,t,n){return this.getInterestedClients(e,t,n).filter(t=>{let n=this.clientSubscriptionState.get(t);return n?[...n].some(([t,n])=>n.priorities.length>0&&p(e,t)):!1})}forwardEventToClients(e,t,n){let r=u(t)??void 0,i=`payload`in t?t.payload:void 0,a=JSON.stringify(t),o=this.getInterestedClients(r,i,e);for(let e of o)n(e,a)}clientWantsMessage(e,t,n){return m(t,n,this.clientSubscriptions.get(e)??new Set,this.clientFilters.get(e)??new Map)}isReadyAndAuthenticated(e){return e.readyState===1?!this.socketAuthChecker||this.socketAuthChecker(e)?!0:(e.close(1008,`Authentication expired`),!1):!1}getRequestRemainingLifetime(e){if(e.deadline!==void 0)return Math.max(0,e.deadline-Date.now());let t=e.timeout??i;return t>0?t:void 0}clearRequestOrigin(e,t){t.expiration!==void 0&&clearTimeout(t.expiration),this.requestOrigins.delete(e)}isSubjectAllowedForClient(e,t){if(!this.subjectRestrictionResolver||t===void 0)return!0;let n=this.subjectRestrictionResolver(e);return n===null?!0:n.has(t)}buildAggregateUpdates(e){let t={},n={},r={};for(let i of e){let e=new Set,a=!1,o=`relayable`;for(let t of this.clientSubscriptionState.values()){let n=t.get(i);if(n){a=!0;for(let t of n.priorities)e.add(t);n.deliveryClass===`first-hop-only`&&(o=`first-hop-only`)}}a?(t[i]=[...e].sort((e,t)=>t-e),n[i]=o):r[i]=[]}let i=[];return Object.keys(t).length>0&&i.push({type:`subscribe`,subjects:t,deliveryClasses:n}),Object.keys(r).length>0&&i.push({type:`unsubscribe`,subjects:r}),i}};const k=new Map;function De(e,t,n){if(e.trim().length===0)throw Error(`registerHmacIdentitySecret requires a non-empty identityId`);if(t.length===0)throw Error(`registerHmacIdentitySecret requires a non-empty secret`);let r=n.peerKind.trim();if(r.length===0)throw Error(`registerHmacIdentitySecret requires a non-empty peerKind`);let i={secret:t,peerKind:r,...n.claims===void 0?{}:{claims:n.claims},...n.allowedSubjects===void 0?{}:{allowedSubjects:new Set(n.allowedSubjects)}};k.set(e,i);let a=!0;return()=>{a&&(a=!1,k.get(e)===i&&k.delete(e))}}function Oe(e,t,n={}){if(t.length===0)throw Error(`rotateHmacIdentitySecret requires a non-empty secret`);let r=k.get(e);if(!r)throw Error(`Cannot rotate HMAC identity secret: no registration exists for '${e}'`);let i={secret:t,peerKind:r.peerKind,...n.claims===void 0?r.claims===void 0?{}:{claims:r.claims}:{claims:n.claims},...r.allowedSubjects===void 0?{}:{allowedSubjects:r.allowedSubjects}};k.set(e,i);let a=!0;return()=>{a&&(a=!1,k.get(e)===i&&k.delete(e))}}function ke(e){return k.get(e)?.secret??null}function Ae(e){let t=k.get(e);return t?{kind:t.peerKind,id:e,authenticated:!0,...t.claims===void 0?{}:{claims:t.claims}}:null}function A(e){return k.get(e)?.allowedSubjects??null}function je(){k.clear()}function Me(e){return e.type===`request`||e.type===`event`||e.type===`broadcast`}function Ne(e){return t(e)&&Object.values(e).every(e=>Array.isArray(e)&&e.every(e=>typeof e==`number`&&Number.isFinite(e)))}function Pe(e){return e.endsWith(`*`)}function Fe(e,t,n,r){let i={};for(let[a,o]of Object.entries(e))Pe(a)?t.has(a)?i[a]=o:n&&console.debug(`[ServerTransport] Dropping wildcard subscription '${a}': not in allowedSubjects for peer '${r}'`):t.has(a)?i[a]=o:n&&console.debug(`[ServerTransport] Dropping subscription subject '${a}': not allowed for peer '${r}'`);return Object.keys(i).length>0?i:null}async function j(e,t,n){let r=await Promise.allSettled(Array.from(t).map(t=>t(e,n.receiveContext)));for(let e of r)if(e.status===`rejected`&&n.debug){let t=n.logContext?` ${n.logContext}`:``;console.error(`[ServerTransport] Handler error${t}:`,e.reason)}return r.every(e=>e.status===`fulfilled`)}async function M(e,t,n){let r=!0;for(let i of e)await j(i,t,n)||(r=!1);return r}function Ie(e,t,n){let{correlations:r,broadcastAggregator:i,debug:a}=t;if(e.type===`heartbeat`)return!0;if(e.type===`response`){let t=e;return typeof t.correlationId==`string`?(t.error?r.reject(t.correlationId,l(t.error)):r.resolve(t.correlationId,t.result),!0):(a&&console.warn(`[ServerTransport] Malformed response message: missing correlationId`),!0)}if(e.type===`broadcast-response`){let t=e;return typeof t.correlationId==`string`?(i.handleResponse(n,t),!0):(a&&console.warn(`[ServerTransport] Malformed broadcast-response: missing correlationId`),!0)}return!1}function Le(e){let t=e?.peer?.id;if(t===void 0)return null;let n=A(t);return n===null?null:{peerId:t,allowedSubjects:n}}function Re(e,t,n,r){if(r===null||!Me(e))return!1;let i=`${e.namespace}.${e.subject}`;return r.allowedSubjects.has(i)?!1:(e.type===`request`&&n.sendSafely(t,JSON.stringify({type:`response`,correlationId:e.correlationId,error:{message:`Subject '${i}' is not allowed for peer '${r.peerId}'`}})),n.debug&&console.warn(`[ServerTransport] Dropping ${e.type} to '${i}': not allowed for peer '${r.peerId}'`),!0)}function ze(e,t,n){if(!Ne(e.subjects))return n&&console.warn(`[ServerTransport] Malformed ${e.type} message: missing subjects record`),null;if(t===null)return e.subjects;let r=Fe(e.subjects,t.allowedSubjects,n,t.peerId);return r===null&&n&&console.debug(`[ServerTransport] Dropping ${e.type} message: all subjects filtered for peer '${t.peerId}'`),r}async function Be(e,t,n,r,i){if(e.type!==`subscribe`&&e.type!==`unsubscribe`)return!1;let a=e,o=ze(a,i,n.debug);return o===null||await M(a.type===`subscribe`?n.registry.handleSubscribeMessage(t,{...a,subjects:o}):n.registry.handleUnsubscribeMessage(t,o),n.handlers,{debug:n.debug,receiveContext:r,logContext:`dispatching ${a.type}`})&&typeof a.ackId==`string`&&n.sendSafely(t,JSON.stringify({type:`subscription-ack`,ackId:a.ackId})),!0}async function Ve(e,t,n,r){if(e.type!==`broadcast`)return!1;let i=e;if(typeof i.correlationId!=`string`||typeof i.subject!=`string`)return n.debug&&console.warn(`[ServerTransport] Malformed broadcast message: missing correlationId or subject`),!0;let a=n.registry.getInterestedClients(i.subject,i.payload,t),o=n.normalizeBroadcastTimeout(i.timeout);return n.broadcastAggregator.startClientBroadcast(t,i,a,n.sendSafely,o),await j(e,n.handlers,{debug:n.debug,receiveContext:r}),!0}async function He(e,t,n){if(Ie(e,n,t))return;let r=n.auth?.getReceiveContext?.(t),i=Le(r);if(!Re(e,t,n,i)){if(e.type===`subscribe`||e.type===`unsubscribe`){await Be(e,t,n,r,i);return}if(e.type===`broadcast`){await Ve(e,t,n,r);return}e.type===`event`&&n.registry.forwardEventToClients(t,e,n.sendSafely),e.type===`request`&&n.registry.trackRequestOrigin(t,e),await j(e,n.handlers,{debug:n.debug,receiveContext:r})}}function Ue(e,t){let{auth:n,registry:r,debug:i}=t;return async a=>{let o;try{o=JSON.parse(a.toString())}catch(e){i&&console.error(`[ServerTransport] Failed to parse message:`,e);return}let s=o&&typeof o==`object`?o:void 0;if(!s||typeof s.type!=`string`){i&&console.error(`[ServerTransport] Invalid message structure:`,o);return}let c=o;try{if(n?.handleAuthMessage(c,e))return;if(n&&r.isAuthenticating(e)){i&&console.warn(`[ServerTransport] Ignoring message from unauthenticated client`);return}if(n?.isSocketAuthenticated?.(e)===!1){i&&console.warn(`[ServerTransport] Closing socket with expired authentication`),n.cleanupSocket(e),e.close(1008,`Authentication expired`);return}await He(c,e,t)}catch(e){i&&console.error(`[ServerTransport] Failed to process message:`,e)}}}function We(e){return typeof e!=`number`||!Number.isFinite(e)||e<=0?5e3:Math.min(e,6e4)}async function Ge(e,t){let{registry:n,correlations:r,broadcastAggregator:i,handlers:a,auth:o,serverSubscriptions:c,sendSafely:l,debug:u}=t;o&&n.addAuthenticating(e);let d=Ue(e,{registry:n,correlations:r,broadcastAggregator:i,handlers:a,auth:o,normalizeBroadcastTimeout:We,sendSafely:l,debug:u}),f=e=>{d(e.data)},p=()=>{o?.cleanupSocket(e);let t=n.removeClient(e);e.removeEventListener(`message`,f),e.removeEventListener(`close`,p),e.removeEventListener(`error`,m),i.handleClientDisconnect(e),M(t,a,{debug:u,logContext:`dispatching disconnected client subscriptions`}),u&&console.info(`[ServerTransport] Client disconnected (${n.size} remaining)`)},m=e=>{u&&console.error(`[ServerTransport] Client socket error:`,e)};e.addEventListener(`message`,f),e.addEventListener(`close`,p),e.addEventListener(`error`,m);try{if(o&&(await o.authenticateServer(e,t=>{if(e.readyState!==1)throw Error(`Cannot send auth message: socket not ready (state: ${e.readyState})`);e.send(JSON.stringify(t))}),n.removeAuthenticating(e)),e.readyState!==1)return;if(n.addClient(e),c.size>0){let t=s(c);l(e,JSON.stringify(t))}l(e,JSON.stringify({type:`subscribe-sync-complete`})),u&&console.info(`[ServerTransport] Client connected (${n.size} total)`)}catch(t){if(u&&console.error(`[ServerTransport] Client connection setup failed:`,t),e.readyState>=2)return;let n=t instanceof v&&(t.code===`WS_AUTHENTICATION_REJECTED`||t.code===`WS_POLICY_REJECTED`);e.close(n?1008:1011,n?`Authentication failed`:`Connection setup failed`)}}async function Ke(e,t,n){let{registry:r,correlations:i}=n,s=`${e.namespace}.${e.subject}`,c=r.getRequestOrigin(e.correlationId),l=r.getInterestedRequestClients(s,e.payload,c);if(l.length===0)throw new a(s);for(let[n,r]of l.entries()){let a=`${e.correlationId}:attempt-${n+1}`,c={...e,correlationId:a};try{r.send(JSON.stringify(c))}catch{continue}try{return await i.track(a,t)}catch(e){if(f(e,s)||e instanceof o)continue;throw e}}throw new a(s)}var N=class{name;wss;auth;debug;handlers=new Set;registry;serverSubscriptions=new Map;broadcastAggregator;correlations=new r;connectionListener=null;constructor(e){let{websocket:t,name:n=`websocket`,auth:r,debug:i=!1}=e;this.wss=t,this.name=n,this.auth=r,this.debug=i,this.registry=new Ee({debug:i,subjectRestrictionResolver:r?e=>{let t=(r.getReceiveContext?.(e))?.peer?.id;return t===void 0?null:A(t)}:void 0,socketAuthChecker:r?e=>r.isSocketAuthenticated?.(e)??!0:void 0}),this.broadcastAggregator=new Te({debug:i})}sendToClientSafely(e,t){try{e.send(t)}catch(e){this.debug&&console.warn(`[ServerTransport] Failed to send message to client:`,e)}}async connect(){if(this.connectionListener!==null)throw Error(`ServerTransport.connect() called while already connected`);this.connectionListener=e=>{Ge(e,{registry:this.registry,correlations:this.correlations,broadcastAggregator:this.broadcastAggregator,handlers:this.handlers,auth:this.auth,serverSubscriptions:this.serverSubscriptions,sendSafely:(e,t)=>this.sendToClientSafely(e,t),debug:this.debug})},this.wss.on(`connection`,this.connectionListener),this.debug&&console.info(`[ServerTransport] Listening for connections`)}async disconnect(){this.connectionListener&&=(this.wss.off(`connection`,this.connectionListener),null);let e=this.registry.getAllSockets();for(let t of e)t.close();await new Promise((e,t)=>{this.wss.close(n=>n?t(n):e())}),this.correlations.cleanup(),this.broadcastAggregator.cleanup(),this.auth?.cleanup(),this.handlers.clear(),this.serverSubscriptions.clear(),this.debug&&console.info(`[ServerTransport] Disconnected`)}async send(e,t){if(e.type===`response`){let t=this.registry.consumeResponseClient(e.correlationId);return t?(this.sendToClientSafely(t,JSON.stringify(e)),!0):!1}if(e.type===`broadcast`){let n=u(e)??void 0,r=`payload`in e?e.payload:void 0,i=this.registry.getInterestedClients(n,r);return this.broadcastAggregator.startServerBroadcast(e,i,(e,t)=>{this.sendToClientSafely(e,t)},t)}if(e.type===`request`)return Ke(e,t??i,{registry:this.registry,correlations:this.correlations});if(this.registry.size===0){if(this.debug){let t=u(e);console.debug(`[ServerTransport] No clients to receive ${e.type}${t?`: ${t}`:``}`)}return!1}let n=u(e)??void 0,r=`payload`in e?e.payload:void 0,a=JSON.stringify(e),o=this.registry.getInterestedClients(n,r);for(let e of o)this.sendToClientSafely(e,a);let s=o.length>0;if(!s&&(n&&this.debug&&console.warn(`[ServerTransport] No interested clients for subject: ${n}`),!n))throw Error(`No connected clients available to receive message`);return s}onReceive(e){return this.handlers.add(e),()=>{this.handlers.delete(e)}}cancelRequest(e,t){this.correlations.cancel(e,t),this.registry.cancelRequestOrigin(e)}onBroadcastResults(e,t,n){this.broadcastAggregator.handleNodeResults(e,t,n)}async subscribe(e,t,n=[],r){let i=this.serverSubscriptions.get(e),a=i?.filter,o=t??a,c=r??i?.deliveryClass??`relayable`;if(this.serverSubscriptions.set(e,{filter:o,priorities:n,deliveryClass:c}),this.registry.size>0){let t=s(new Map([[e,{filter:o,priorities:n,deliveryClass:c}]])),r=JSON.stringify(t);for(let e of this.registry.getReadyClients())this.sendToClientSafely(e,r)}}getConnectionCount(){return this.registry.getReadyClients().length}async unsubscribe(e){if(this.serverSubscriptions.delete(e),this.registry.size>0){let t=c({[e]:[]}),n=JSON.stringify(t);for(let e of this.registry.getReadyClients())this.sendToClientSafely(e,n)}}};function qe(e,t){let n=new Event(`close`);return Object.defineProperties(n,{code:{value:e??1e3,enumerable:!0},reason:{value:t??``,enumerable:!0}}),n}function Je(e){if(typeof e!=`object`||!e)throw TypeError(`WebSocket transport options must be an object`);let t=e;if(t.mode!==`client`&&t.mode!==`server`)throw TypeError(`WebSocket transport mode must be "client" or "server"`);if(t.mode===`client`){if(!Ye(t.websocket))throw TypeError(`WebSocket transport client mode requires a websocket with addEventListener/removeEventListener`);return}if(!Xe(t.websocket))throw TypeError(`WebSocket transport server mode requires a websocket with on/off listener methods`)}function Ye(e){if(typeof e!=`object`||!e)return!1;let t=e;return typeof t.send==`function`&&typeof t.close==`function`&&typeof t.addEventListener==`function`&&typeof t.removeEventListener==`function`}function Xe(e){if(typeof e!=`object`||!e)return!1;let t=e;return typeof t.on==`function`&&typeof t.off==`function`&&typeof t.close==`function`}var Ze=class{secret;algorithm;challengeTimeout;identityId;resolveSecret;resolvePeer;pendingChallenge;pendingResult;queuedChallengeNonce;queuedResult;clientAuthComplete=!1;serverPendingResponses=new Map;serverAuthenticatedSockets=new Set;serverAuthenticatedPeers=new Map;serverAuthenticatedSecrets=new Map;constructor(e){this.secret=e.secret,this.algorithm=e.algorithm??`sha256`,this.challengeTimeout=e.challengeTimeout??5e3,this.identityId=e.identityId,this.resolveSecret=e.resolveSecret,this.resolvePeer=e.resolvePeer}async authenticateServer(e,t){let n=crypto.getRandomValues(new Uint8Array(32)),r=Array.from(n).map(e=>e.toString(16).padStart(2,`0`)).join(``),i=this.waitForAuthResponseWithIdentity(e),a=this.serverPendingResponses.get(e);i.catch(()=>void 0);try{t({type:`auth-challenge`,nonce:r});let{signature:n,identityId:o}=await i;this.assertServerOwner(e,a);let s;if(this.resolveSecret&&o!==void 0){let i=this.resolveSecret(o);if(i===null)throw this.sendAuthResultBestEffort(t,{type:`auth-result`,success:!1,error:`Unknown identity`}),new v(`WS_AUTHENTICATION_REJECTED`,`HMAC authentication failed: Unknown identity '${o}'`);s=await this.computeHmacWithSecret(r,i),this.assertServerOwner(e,a),this.constantTimeEqual(n,s)&&(this.serverAuthenticatedPeers.set(e,o),this.serverAuthenticatedSecrets.set(e,i))}else s=await this.computeHmac(r),this.assertServerOwner(e,a);if(!this.constantTimeEqual(n,s))throw this.sendAuthResultBestEffort(t,{type:`auth-result`,success:!1,error:`Invalid signature`}),new v(`WS_AUTHENTICATION_REJECTED`,`HMAC authentication failed: Invalid signature`);try{t({type:`auth-result`,success:!0}),this.assertServerOwner(e,a)}catch(t){throw this.serverPendingResponses.get(e)===a&&this.cleanupSocket(e),t}this.serverAuthenticatedSockets.add(e)}finally{clearTimeout(a.timeoutHandle),this.serverPendingResponses.get(e)===a&&this.serverPendingResponses.delete(e)}}async authenticateClient(e){this.clientAuthComplete=!1;let t=this.waitForAuthChallenge(),n=this.pendingChallenge;try{let r=await t;this.assertClientOwner(n);let i=await this.computeHmac(r);this.assertClientOwner(n),e({type:`auth-response`,signature:i,...this.identityId!==void 0&&{identityId:this.identityId}}),this.assertClientOwner(n);let a=await this.waitForAuthResult();if(this.assertClientOwner(n),!a.success)throw new v(`WS_AUTHENTICATION_REJECTED`,`HMAC authentication failed: ${a.error??`Unknown error`}`);this.clientAuthComplete=!0}finally{clearTimeout(n.timeoutHandle),this.pendingChallenge===n&&(this.pendingChallenge=void 0)}}assertClientOwner(e){if(this.pendingChallenge!==e)throw new v(`WS_CONNECTION_UNAVAILABLE`,`Socket disconnected during HMAC authentication`)}assertServerOwner(e,t){if(this.serverPendingResponses.get(e)!==t)throw new v(`WS_CONNECTION_UNAVAILABLE`,`Socket disconnected during HMAC authentication`)}handleAuthMessage(e,t){if(typeof e!=`object`||!e||!(`type`in e)||typeof e.type!=`string`)return!1;let n=e;if(n.type===`auth-challenge`)return typeof n.nonce!=`string`||this.clientAuthComplete||(this.pendingChallenge?(clearTimeout(this.pendingChallenge.timeoutHandle),this.pendingChallenge.resolve(n.nonce)):this.queuedChallengeNonce=n.nonce),!0;if(n.type===`auth-result`){if(typeof n.success!=`boolean`||this.clientAuthComplete)return!0;let e={success:n.success,error:typeof n.error==`string`?n.error:void 0};return this.pendingResult?(clearTimeout(this.pendingResult.timeoutHandle),this.pendingResult.resolve(e),this.pendingResult=void 0):this.queuedResult=e,!0}if(n.type===`auth-response`){if(t){let e=this.serverPendingResponses.get(t);if(e){if(clearTimeout(e.timeoutHandle),n.identityId!==void 0&&typeof n.identityId!=`string`)return e.reject(new v(`WS_AUTHENTICATION_REJECTED`,`Malformed HMAC identity`)),!0;e.resolve({signature:n.signature,identityId:n.identityId})}}return!0}return!1}async waitForAuthChallenge(){return new Promise((e,t)=>{let n=setTimeout(()=>{t(new v(`WS_HANDSHAKE_TIMEOUT`,`Authentication challenge timeout`))},this.challengeTimeout);this.pendingChallenge={resolve:e,reject:t,timeoutHandle:n},this.queuedChallengeNonce!==void 0&&(clearTimeout(n),e(this.queuedChallengeNonce),this.queuedChallengeNonce=void 0)})}async waitForAuthResponseWithIdentity(e){return new Promise((t,n)=>{let r={resolve:t,reject:n,timeoutHandle:setTimeout(()=>{n(new v(`WS_HANDSHAKE_TIMEOUT`,`Authentication response timeout`))},this.challengeTimeout)};this.serverPendingResponses.set(e,r)})}async waitForAuthResult(){if(this.queuedResult!==void 0){let e=this.queuedResult;return this.queuedResult=void 0,e}return new Promise((e,t)=>{let n=setTimeout(()=>{this.pendingResult=void 0,t(new v(`WS_HANDSHAKE_TIMEOUT`,`Authentication result timeout`))},this.challengeTimeout);this.pendingResult={resolve:e,reject:t,timeoutHandle:n}})}async computeHmac(e){return this.computeHmacWithSecret(e,this.secret)}async computeHmacWithSecret(e,t){let n=new TextEncoder,r=n.encode(t),i=this.algorithm.replace(/^sha/,`SHA-`),a=await crypto.subtle.importKey(`raw`,r,{name:`HMAC`,hash:i},!1,[`sign`]),o=await crypto.subtle.sign(`HMAC`,a,n.encode(e));return Array.from(new Uint8Array(o)).map(e=>e.toString(16).padStart(2,`0`)).join(``)}getReceiveContext(e){if(!e)return;let t=this.serverAuthenticatedPeers.get(e);if(t===void 0)return;let n=this.resolvePeer?.(t);if(n!=null)return{transportName:``,peer:{...n,id:n.id??t,authenticated:!0}}}isSocketAuthenticated(e){if(!this.serverAuthenticatedSockets.has(e))return!1;if(!this.resolveSecret)return!0;let t=this.serverAuthenticatedPeers.get(e);if(t===void 0)return!0;let n=this.resolveSecret(t);if(n===null)return this.cleanupSocket(e),!1;let r=this.serverAuthenticatedSecrets.get(e);return r!==void 0&&n!==r?(this.cleanupSocket(e),!1):!0}constantTimeEqual(e,t){if(typeof e!=`string`||e.length!==t.length||!/^[0-9a-f]+$/i.test(e))return!1;let n=new Uint8Array(e.length/2),r=new Uint8Array(t.length/2);for(let i=0;i<n.length;i++)n[i]=parseInt(e.slice(i*2,i*2+2),16),r[i]=parseInt(t.slice(i*2,i*2+2),16);let i=0;for(let e=0;e<n.length;e++)i|=n[e]^r[e];return i===0}sendAuthResultBestEffort(e,t){try{e(t)}catch{}}cleanupSocket(e){let t=this.serverPendingResponses.get(e);t&&(clearTimeout(t.timeoutHandle),this.serverPendingResponses.delete(e),t.reject(new v(`WS_CONNECTION_UNAVAILABLE`,`Socket disconnected during HMAC authentication`))),this.serverAuthenticatedPeers.delete(e),this.serverAuthenticatedSecrets.delete(e),this.serverAuthenticatedSockets.delete(e)}cleanup(){this.pendingChallenge&&=(clearTimeout(this.pendingChallenge.timeoutHandle),this.pendingChallenge.reject(new v(`WS_CONNECTION_UNAVAILABLE`,`Socket disconnected during HMAC authentication`)),void 0),this.pendingResult&&=(clearTimeout(this.pendingResult.timeoutHandle),this.pendingResult.reject(new v(`WS_CONNECTION_UNAVAILABLE`,`Socket disconnected during HMAC authentication`)),void 0),this.queuedChallengeNonce=void 0,this.queuedResult=void 0,this.clientAuthComplete=!1;for(let e of this.serverPendingResponses.values())clearTimeout(e.timeoutHandle),e.reject(new v(`WS_CONNECTION_UNAVAILABLE`,`Socket disconnected during HMAC authentication`));this.serverPendingResponses.clear(),this.serverAuthenticatedPeers.clear(),this.serverAuthenticatedSecrets.clear(),this.serverAuthenticatedSockets.clear()}};function P(e){let t=Array.from(e,e=>String.fromCharCode(e)).join(``);return btoa(t).replace(/\+/g,`-`).replace(/\//g,`_`).replace(/=/g,``)}function F(e){let t=e.replace(/-/g,`+`).replace(/_/g,`/`),n=(4-t.length%4)%4;t+=`=`.repeat(n);let r=atob(t),i=new Uint8Array(r.length);for(let e=0;e<r.length;e++)i[e]=r.charCodeAt(e);return i}function I(e){return new TextEncoder().encode(e)}function L(e){return new TextDecoder().decode(e)}async function R(e){let t=await crypto.subtle.exportKey(`spki`,e);return P(new Uint8Array(t))}async function z(e){let t=await crypto.subtle.exportKey(`raw`,e);return P(new Uint8Array(t))}async function B(e,t,n=[]){let r=F(e);return crypto.subtle.importKey(`spki`,r,t,!0,n)}async function V(e,t,n=[]){let r=F(e);return crypto.subtle.importKey(`raw`,r,t,!0,n)}async function H(e){let t=await crypto.subtle.exportKey(`pkcs8`,e),n=P(new Uint8Array(t)).replace(/-/g,`+`).replace(/_/g,`/`),r=(4-n.length%4)%4;return n+=`=`.repeat(r),`-----BEGIN PRIVATE KEY-----\n${n.match(/.{1,64}/g)?.join(`
2
+ `)??n}\n-----END PRIVATE KEY-----`}async function Qe(e,t,n){let r=F(e.replace(/-----BEGIN PRIVATE KEY-----/,``).replace(/-----END PRIVATE KEY-----/,``).replace(/\s/g,``).replace(/\+/g,`-`).replace(/\//g,`_`).replace(/=/g,``));return crypto.subtle.importKey(`pkcs8`,r,t,!0,n)}const U={name:`ECDH`,namedCurve:`P-256`};async function $e(e=!0){return crypto.subtle.generateKey(U,e,[`deriveKey`,`deriveBits`])}async function et(e){return R(e)}async function tt(e){return z(e)}async function nt(e){return V(e,U)}async function rt(e,t=[]){return B(e,U,t)}async function it(e){return H(e)}async function at(e){return Qe(e,U,[`deriveKey`,`deriveBits`])}async function ot(e,t){return crypto.subtle.deriveBits({name:`ECDH`,public:t},e,256)}async function W(e,t){let n=crypto.getRandomValues(new Uint8Array(12)),r=await crypto.subtle.encrypt({name:`AES-GCM`,iv:n},e,t);return{ciphertext:new Uint8Array(r),nonce:n}}async function G(e,t,n){let r=await crypto.subtle.decrypt({name:`AES-GCM`,iv:n},e,t);return new Uint8Array(r)}async function st(e){return crypto.subtle.importKey(`raw`,e,{name:`AES-GCM`},!1,[`encrypt`,`decrypt`])}async function ct(e,t,n){let r=await crypto.subtle.importKey(`raw`,e,{name:`HKDF`},!1,[`deriveKey`]);return crypto.subtle.deriveKey({name:`HKDF`,hash:`SHA-256`,salt:t,info:I(n)},r,{name:`AES-GCM`,length:256},!1,[`encrypt`,`decrypt`])}const K={name:`ECDSA`,namedCurve:`P-256`};async function lt(e=!0){return crypto.subtle.generateKey(K,e,[`sign`,`verify`])}async function ut(e,t){let n=await crypto.subtle.sign({name:`ECDSA`,hash:{name:`SHA-256`}},e,t);return new Uint8Array(n)}async function dt(e,t,n){return crypto.subtle.verify({name:`ECDSA`,hash:{name:`SHA-256`}},e,t,n)}async function ft(e){return R(e)}async function pt(e){return B(e,K,[`verify`])}async function mt(e){return z(e)}async function ht(e){return V(e,K,[`verify`])}async function gt(e){return H(e)}async function _t(e){return Qe(e,K,[`sign`])}var vt=e({decodeText:()=>L,decrypt:()=>G,deriveSessionKey:()=>ct,deriveSharedSecret:()=>ot,encodeText:()=>I,encrypt:()=>W,exportPrivateKeyPEM:()=>it,exportPublicKey:()=>et,exportPublicKeyRaw:()=>tt,exportSigningPrivateKeyPEM:()=>gt,exportSigningPublicKey:()=>ft,exportSigningPublicKeyRaw:()=>mt,fromBase64Url:()=>F,generateECDHKeyPair:()=>$e,generateSigningKeyPair:()=>lt,importAESKey:()=>st,importPrivateKeyPEM:()=>at,importPublicKey:()=>rt,importPublicKeyRaw:()=>nt,importSigningPrivateKeyPEM:()=>_t,importSigningPublicKey:()=>pt,importSigningPublicKeyRaw:()=>ht,sign:()=>ut,toBase64Url:()=>P,verify:()=>dt});function yt(e){let t=e.match(/.{1,2}/g);return new Uint8Array(t?.map(e=>parseInt(e,16))??[])}function q(e){return Array.from(e).map(e=>e.toString(16).padStart(2,`0`)).join(``)}async function J(e,t){let n=await $e(!0),r=await et(n.publicKey);return{ephemeralKeyPair:n,ephemeralPublicKey:r,signature:q(await ut(e,I(r+t)))}}function bt(){return q(crypto.getRandomValues(new Uint8Array(16)))}async function Y(e,t,n,r){let i=I(t+r);return dt(e,yt(n),i)}async function X(e,t,n,r){let i;try{i=await rt(t)}catch(e){throw e instanceof DOMException&&e.name===`DataError`?new v(`WS_AUTHENTICATION_REJECTED`,`Invalid E2E peer public key`,{cause:e}):e}return ct(await ot(e,i),yt(n),r)}async function xt(e,t,n,r){if(e===t)throw Error(`deriveRelaySaltHex: identityId must differ from peerId`);let[i,a]=e<t?[e,t]:[t,e],[o,s]=e<t?[n,r]:[r,n],c=I(`${i}${a}${o}${s}`),l=new Uint8Array(c).buffer,u=await crypto.subtle.digest(`SHA-256`,l);return q(new Uint8Array(u))}function St(e,t){return typeof e==`string`&&/^[A-Za-z0-9_-]+$/.test(e)&&e.length%4!=1&&typeof t==`string`&&/^[0-9a-f]{128}$/i.test(t)}function Ct(e){return St(e.ephemeralPublicKey,e.signature)&&typeof e.salt==`string`&&/^[0-9a-f]{32}$/i.test(e.salt)}var wt=class{signingKeyPair;identityId;peerId;getPeerSigningKey;timeout;pendingKeyExchange;pendingResult;clientSession;clientEphemeralKeyPair;serverPendingKeyExchange=new Map;serverSessions=new Map;serverEphemeralKeyPairs=new Map;constructor(e){this.signingKeyPair=e.signingKeyPair,this.identityId=e.identityId,this.peerId=e.peerId,this.getPeerSigningKey=e.getPeerSigningKey,this.timeout=e.timeout??1e4}async authenticateClient(e){if(!this.peerId)throw Error(`E2E authentication failed: peerId is required for client authentication`);let t=this.waitForKeyExchangeResponse(),n=this.pendingKeyExchange,r=this.waitForAuthResult();t.catch(()=>void 0),r.catch(()=>void 0);try{let{ephemeralKeyPair:i,ephemeralPublicKey:a,signature:o}=await J(this.signingKeyPair.privateKey,this.identityId);this.assertClientOwner(n),this.clientEphemeralKeyPair=i,e({type:`e2e-key-exchange`,deviceId:this.identityId,ephemeralPublicKey:a,signature:o}),this.assertClientOwner(n);let s=await t;this.assertClientOwner(n);let c=await this.getPeerSigningKey(this.peerId);if(this.assertClientOwner(n),!c)throw new v(`WS_AUTHENTICATION_REJECTED`,`E2E authentication failed: Unknown server`);let l=await Y(c,s.ephemeralPublicKey,s.signature,this.peerId);if(this.assertClientOwner(n),!l)throw new v(`WS_AUTHENTICATION_REJECTED`,`E2E authentication failed: Invalid server signature`);let u=await X(i.privateKey,s.ephemeralPublicKey,s.salt,`makaio-e2e-session-v1`);this.assertClientOwner(n);let d=await r;if(this.assertClientOwner(n),!d.success)throw new v(`WS_AUTHENTICATION_REJECTED`,`E2E authentication failed: ${d.error??`Unknown error`}`);this.clientSession={sessionKey:u,peerId:this.peerId}}catch(e){throw this.pendingKeyExchange===n&&(this.clientSession=void 0,this.clientEphemeralKeyPair=void 0),e}finally{clearTimeout(n.timeoutHandle),this.pendingKeyExchange===n&&(this.pendingKeyExchange=void 0,this.pendingResult&&clearTimeout(this.pendingResult.timeoutHandle),this.pendingResult=void 0)}}async authenticateServer(e,t){let n=this.waitForClientKeyExchange(e),r=this.serverPendingKeyExchange.get(e);try{let i=await n;this.assertServerOwner(e,r);let a=await this.getPeerSigningKey(i.deviceId);if(this.assertServerOwner(e,r),!a)throw new v(`WS_AUTHENTICATION_REJECTED`,`E2E authentication failed: Unknown device ${i.deviceId}`);let o=await Y(a,i.ephemeralPublicKey,i.signature,i.deviceId);if(this.assertServerOwner(e,r),!o)throw new v(`WS_AUTHENTICATION_REJECTED`,`E2E authentication failed: Invalid client signature`);let{ephemeralKeyPair:s,ephemeralPublicKey:c,signature:l}=await J(this.signingKeyPair.privateKey,this.identityId);this.assertServerOwner(e,r);let u=bt();this.serverEphemeralKeyPairs.set(e,s),t({type:`e2e-key-exchange-response`,ephemeralPublicKey:c,signature:l,salt:u}),this.assertServerOwner(e,r);let d=await X(s.privateKey,i.ephemeralPublicKey,u,`makaio-e2e-session-v1`);this.assertServerOwner(e,r),this.serverSessions.set(e,{sessionKey:d,peerId:i.deviceId}),t({type:`e2e-auth-result`,success:!0}),this.assertServerOwner(e,r)}catch(n){if(this.serverPendingKeyExchange.get(e)===r){this.serverEphemeralKeyPairs.delete(e),this.serverSessions.delete(e);try{n instanceof v&&n.code===`WS_AUTHENTICATION_REJECTED`&&t({type:`e2e-auth-result`,success:!1,error:n.message})}catch{}}throw n}finally{clearTimeout(r.timeoutHandle),this.serverPendingKeyExchange.get(e)===r&&this.serverPendingKeyExchange.delete(e)}}assertClientOwner(e){if(this.pendingKeyExchange!==e)throw new v(`WS_CONNECTION_UNAVAILABLE`,`Connection closed during E2E authentication`)}assertServerOwner(e,t){if(this.serverPendingKeyExchange.get(e)!==t)throw new v(`WS_CONNECTION_UNAVAILABLE`,`Connection closed during E2E authentication`)}handleAuthMessage(e,t){if(typeof e!=`object`||!e||!(`type`in e)||typeof e.type!=`string`)return!1;let n=e;if(n.type===`e2e-key-exchange-response`){if(this.pendingKeyExchange){if(clearTimeout(this.pendingKeyExchange.timeoutHandle),!Ct(n))return this.pendingKeyExchange.reject(new v(`WS_AUTHENTICATION_REJECTED`,`Malformed E2E key exchange response`)),!0;this.pendingKeyExchange.resolve({ephemeralPublicKey:n.ephemeralPublicKey,signature:n.signature,salt:n.salt})}return!0}if(n.type===`e2e-auth-result`){if(typeof n.success!=`boolean`)return!0;let e=typeof n.error==`string`?n.error:void 0;return!n.success&&this.pendingKeyExchange&&(clearTimeout(this.pendingKeyExchange.timeoutHandle),this.pendingKeyExchange.reject(new v(`WS_AUTHENTICATION_REJECTED`,`E2E authentication failed: ${e??`Unknown error`}`))),this.pendingResult&&=(clearTimeout(this.pendingResult.timeoutHandle),this.pendingResult.resolve({success:n.success,error:e}),void 0),!0}if(n.type===`e2e-key-exchange`&&t){let e=this.serverPendingKeyExchange.get(t);if(e){if(clearTimeout(e.timeoutHandle),typeof n.deviceId!=`string`||!St(n.ephemeralPublicKey,n.signature))return e.reject(new v(`WS_AUTHENTICATION_REJECTED`,`Malformed E2E key exchange`)),!0;e.resolve({deviceId:n.deviceId,ephemeralPublicKey:n.ephemeralPublicKey,signature:n.signature})}return!0}return!1}async waitForKeyExchangeResponse(){return new Promise((e,t)=>{let n=setTimeout(()=>{t(new v(`WS_HANDSHAKE_TIMEOUT`,`E2E key exchange timeout`))},this.timeout);this.pendingKeyExchange={resolve:e,reject:t,timeoutHandle:n}})}async waitForAuthResult(){return new Promise((e,t)=>{let n=setTimeout(()=>{this.pendingResult=void 0,t(new v(`WS_HANDSHAKE_TIMEOUT`,`E2E authentication result timeout`))},this.timeout);this.pendingResult={resolve:e,reject:t,timeoutHandle:n}})}async waitForClientKeyExchange(e){return new Promise((t,n)=>{let r={resolve:t,reject:n,timeoutHandle:setTimeout(()=>{n(new v(`WS_HANDSHAKE_TIMEOUT`,`E2E key exchange timeout`))},this.timeout)};this.serverPendingKeyExchange.set(e,r)})}getSessionKey(e){return e?this.serverSessions.get(e)?.sessionKey??null:this.clientSession?.sessionKey??null}getPeerId(e){return e?this.serverSessions.get(e)?.peerId??null:this.clientSession?.peerId??null}getReceiveContext(e){let t=this.getPeerId(e);if(t!==null)return{transportName:``,peer:{kind:`e2e`,id:t,authenticated:!0,encrypted:!0}}}cleanupSocket(e){let t=this.serverPendingKeyExchange.get(e);t&&(clearTimeout(t.timeoutHandle),t.reject(new v(`WS_CONNECTION_UNAVAILABLE`,`Connection closed during E2E authentication`)),this.serverPendingKeyExchange.delete(e)),this.serverSessions.delete(e),this.serverEphemeralKeyPairs.delete(e)}cleanup(){this.pendingKeyExchange&&=(clearTimeout(this.pendingKeyExchange.timeoutHandle),this.pendingKeyExchange.reject(new v(`WS_CONNECTION_UNAVAILABLE`,`Connection closed during E2E authentication`)),void 0),this.pendingResult&&=(clearTimeout(this.pendingResult.timeoutHandle),this.pendingResult.reject(new v(`WS_CONNECTION_UNAVAILABLE`,`Connection closed during E2E authentication`)),void 0),this.clientSession=void 0,this.clientEphemeralKeyPair=void 0;for(let e of this.serverPendingKeyExchange.values())clearTimeout(e.timeoutHandle),e.reject(new v(`WS_CONNECTION_UNAVAILABLE`,`Connection closed during E2E authentication`));this.serverPendingKeyExchange.clear(),this.serverSessions.clear(),this.serverEphemeralKeyPairs.clear()}};const Z=`E2E relay auth session aborted by reconnect`;var Tt=class{signingKeyPair;identityId;getPeerSigningKey;timeout;mode;blocking;pendingPeer;sessionKey;peerId;localEphemeral;localExchangeMessage;sentLocalExchange=!1;earlyPeer;sendAuthMessage;authGeneration=0;processingExchange=!1;constructor(e){this.signingKeyPair=e.signingKeyPair,this.identityId=e.identityId,this.getPeerSigningKey=e.getPeerSigningKey,this.timeout=e.timeout??1e4,this.mode=e.mode??`initiator`,this.blocking=e.blocking??!0}async authenticateClient(e){let t=this.sendAuthMessage===void 0?this.earlyPeer:void 0;this.cleanup();let n=this.authGeneration;if(this.earlyPeer=t,this.sendAuthMessage=e,this.mode===`initiator`){if(await this.ensureLocalExchangeMessage(),n!==this.authGeneration)throw Error(Z);this.sendLocalExchange()}if(!this.blocking){if(this.earlyPeer){let e=this.earlyPeer;this.earlyPeer=void 0,this.dispatchPeerExchange(e,n)}return}let r=await this.waitForPeerExchange();if(await this.processPeerExchange(r,n),n!==this.authGeneration||!this.sessionKey)throw Error(Z)}async authenticateServer(e,t){throw Error(`E2ERelayAuth does not support server authentication`)}handleAuthMessage(e){let t=e;return!t||t.type!==`e2e-relay-key-exchange`?!1:t.identityId===this.identityId?!0:this.pendingPeer?(this.pendingPeer.resolve(t),this.pendingPeer=void 0,!0):(this.earlyPeer=t,!this.blocking&&this.sendAuthMessage&&!this.sessionKey&&!this.processingExchange&&this.dispatchPeerExchange(t,this.authGeneration),!0)}cleanupSocket(e){}cleanup(){this.authGeneration++,this.pendingPeer&&=(this.pendingPeer.reject(Error(Z)),void 0),this.earlyPeer&&=void 0,this.sessionKey=void 0,this.peerId=void 0,this.localEphemeral=void 0,this.localExchangeMessage=void 0,this.sentLocalExchange=!1,this.processingExchange=!1,this.sendAuthMessage=void 0}dispatchPeerExchange(e,t){this.processingExchange=!0,this.processPeerExchange(e,t).catch(e=>{e instanceof Error&&e.message===Z||console.error(`[E2ERelayAuth] Peer exchange failed:`,e)}).finally(()=>{t===this.authGeneration&&(this.processingExchange=!1,this.retryQueuedPeerExchange(t))})}getSessionKey(){return this.sessionKey??null}getPeerId(){return this.peerId??null}getReceiveContext(){let e=this.getPeerId();if(e!==null)return{transportName:``,peer:{kind:`e2e`,id:e,authenticated:!0,encrypted:!0}}}async waitForPeerExchange(){if(this.earlyPeer){let e=this.earlyPeer;return this.earlyPeer=void 0,e}return new Promise((e,t)=>{let n=setTimeout(()=>{this.pendingPeer=void 0,t(Error(`E2E relay key exchange timeout`))},this.timeout),r=()=>{clearTimeout(n),this.pendingPeer=void 0};this.pendingPeer={resolve:t=>{r(),e(t)},reject:e=>{r(),t(e)},timeoutHandle:n}})}async ensureLocalExchangeMessage(){if(this.localExchangeMessage&&this.localEphemeral)return this.localExchangeMessage;let{ephemeralKeyPair:e,ephemeralPublicKey:t,signature:n}=await J(this.signingKeyPair.privateKey,this.identityId);return this.localEphemeral=e,this.localExchangeMessage={type:`e2e-relay-key-exchange`,identityId:this.identityId,ephemeralPublicKey:t,signature:n},this.localExchangeMessage}sendLocalExchange(e=!1){!this.sendAuthMessage||!this.localExchangeMessage||!e&&this.sentLocalExchange||(this.sendAuthMessage(this.localExchangeMessage),this.sentLocalExchange=!0)}retryQueuedPeerExchange(e){if(this.blocking||!this.sendAuthMessage||this.sessionKey||this.processingExchange||e!==this.authGeneration)return;let t=this.earlyPeer;t&&(this.earlyPeer=void 0,this.dispatchPeerExchange(t,e))}async processPeerExchange(e,t){if(!this.sendAuthMessage){this.earlyPeer=e;return}let n=await this.ensureLocalExchangeMessage();if(t!==this.authGeneration)return;let r=await this.getPeerSigningKey(e.identityId);if(!r)throw Error(`E2E relay authentication failed: Unknown peer ${e.identityId}`);if(!await Y(r,e.ephemeralPublicKey,e.signature,e.identityId))throw Error(`E2E relay authentication failed: Invalid peer signature`);let i=await xt(this.identityId,e.identityId,n.ephemeralPublicKey,e.ephemeralPublicKey);if(!this.localEphemeral)throw Error(`E2E relay authentication failed: Local ephemeral key missing`);let a=await X(this.localEphemeral.privateKey,e.ephemeralPublicKey,i,`makaio-e2e-relay-v1`);t===this.authGeneration&&(this.sessionKey=a,this.peerId=e.identityId,this.mode===`initiator`?this.sendLocalExchange(!0):this.sendLocalExchange())}},Et=class{hmac;e2e;socketStrategy=new Map;pendingServerAuth=new Map;hmacCancelled=new Map;constructor(e){this.hmac=e.hmac,this.e2e=e.e2e}setE2EAuth(e){this.e2e=e}async authenticateClient(e){let t=this.hmac??this.e2e;if(!t)throw Error(`DispatchingAuth: no auth strategy configured`);return t.authenticateClient(e)}async authenticateServer(e,t){let n=this.resolveSingleStrategy();if(n)return n.authenticateServer(e,t);if(!this.hmac||!this.e2e)throw Error(`DispatchingAuth: no auth strategy configured`);let r={cancelled:!1};this.hmacCancelled.set(e,r);let i=this.hmac.authenticateServer(e,e=>{r.cancelled||t(e)});return new Promise((n,a)=>{this.pendingServerAuth.set(e,{resolve:n,reject:a,send:t}),i.then(n).catch(e=>{r.cancelled||a(e instanceof Error?e:Error(String(e)))})})}handleAuthMessage(e,t){if(!t)return(this.hmac??this.e2e)?.handleAuthMessage(e)??!1;let n=this.socketStrategy.get(t);if(n)return n.handleAuthMessage(e,t);let r=this.resolveStrategy(e),i=this.pendingServerAuth.get(t);return r?(this.socketStrategy.set(t,r),this.pendingServerAuth.delete(t),r===this.hmac?this.hmacCancelled.delete(t):(this.cancelHmac(t),i&&r.authenticateServer(t,i.send).then(i.resolve).catch(e=>{i.reject(e instanceof Error?e:Error(String(e)))})),r.handleAuthMessage(e,t)):(this.cancelHmac(t),i&&(this.pendingServerAuth.delete(t),i.reject(new v(`WS_POLICY_REJECTED`,`DispatchingAuth: unrecognised auth message type "${this.peekType(e)}" — no matching strategy`))),!1)}cleanupSocket(e){let t=this.socketStrategy.get(e);t&&(t.cleanupSocket(e),this.socketStrategy.delete(e)),this.cancelHmac(e);let n=this.pendingServerAuth.get(e);n&&(this.pendingServerAuth.delete(e),n.reject(Error(`DispatchingAuth: socket disconnected before auth type was determined`)))}cleanup(){this.hmac?.cleanup(),this.e2e?.cleanup(),this.socketStrategy.clear();for(let e of this.pendingServerAuth.values())e.reject(Error(`DispatchingAuth: cleanup called before authentication completed`));this.pendingServerAuth.clear(),this.hmacCancelled.clear()}peekType(e){if(typeof e!=`object`||!e||!(`type`in e))return;let{type:t}=e;return typeof t==`string`?t:void 0}resolveSingleStrategy(){if(this.hmac&&!this.e2e)return this.hmac;if(this.e2e&&!this.hmac)return this.e2e}resolveStrategy(e){let t=this.peekType(e);if(t){if(t===`e2e-key-exchange`&&this.e2e)return this.e2e;if(t===`auth-response`&&this.hmac)return this.hmac}}cancelHmac(e){let t=this.hmacCancelled.get(e);t&&(t.cancelled=!0,this.hmacCancelled.delete(e),this.hmac?.cleanupSocket(e))}};function Dt(e){return`payload`in e}async function Ot(e,t,n){if(e.type!==`response`||e.result===void 0||e.error!==void 0)return;let{ciphertext:r,nonce:i}=await W(n,I(JSON.stringify(e.result)));t.result=P(r),t.e2e={nonce:P(i),v:1}}async function kt(e,t,n){if(e.type!==`broadcast-response`||e.results===void 0||e.error!==void 0)return;let{ciphertext:r,nonce:i}=await W(n,I(JSON.stringify(e.results)));t.results=P(r),t.e2e={nonce:P(i),v:1}}async function At(e,t,n){if(!Dt(e)||e.payload===void 0)return;let{ciphertext:r,nonce:i}=await W(n,I(JSON.stringify(e.payload)));t.payload=P(r),t.e2e={nonce:P(i),v:1}}async function jt(e,t,n){if(e.type!==`response`&&e.type!==`broadcast-response`||e.error===void 0)return;let{ciphertext:r,nonce:i}=await W(n,I(JSON.stringify(e.error)));t.error=P(r),t.e2e={nonce:P(i),v:1}}async function Mt(e,t,n,r){if(!Dt(e)||typeof e.payload!=`string`)return;let i=L(await G(n,F(e.payload),r));t.payload=JSON.parse(i)}async function Nt(e,t,n,r){if(e.type!==`response`||typeof e.result!=`string`)return;let i=L(await G(n,F(e.result),r));t.result=JSON.parse(i)}async function Pt(e,t,n,r){if(e.type!==`broadcast-response`||typeof e.results!=`string`)return;let i=L(await G(n,F(e.results),r));t.results=JSON.parse(i)}async function Ft(e,t,n,r){if(e.type!==`response`&&e.type!==`broadcast-response`||typeof e.error!=`string`)return;let i=L(await G(n,F(e.error),r));t.error=JSON.parse(i)}async function It(e,t){let n={...e};return await At(e,n,t),await Ot(e,n,t),await kt(e,n,t),await jt(e,n,t),n}async function Lt(e,t){if(!e.e2e)return e;let n={...e};delete n.e2e;let r=F(e.e2e.nonce);return await Mt(e,n,t,r),await Nt(e,n,t,r),await Pt(e,n,t,r),await Ft(e,n,t,r),n}function Rt(e){return e.type===`subscription-ack`&&typeof e.ackId==`string`}function zt(e){let{e2eAuth:t,websocket:n,...r}=e,i=new D({...r,url:`<pre-connected>`,createWebSocket:()=>n,auth:t,autoReconnect:!1,heartbeat:r.heartbeat??!1,messageTransform:async e=>{let n=t.getSessionKey();if(!n||Rt(e))return e;let r=e;if(!r.e2e)throw Error(`Received plaintext message on E2E-encrypted channel — possible injection`);return Lt(r,n)}});async function a(e,n){let r=t.getSessionKey();if(!r)throw Error(`E2E session key not available - authentication may have failed`);let a=await It(e,r);return i.send(a,n)}return{name:i.name,connect:i.connect.bind(i),disconnect:i.disconnect.bind(i),send:a,cancelRequest:i.cancelRequest.bind(i),onReceive:i.onReceive.bind(i),subscribe:i.subscribe.bind(i),unsubscribe:i.unsubscribe.bind(i),getSubscriptions:i.getSubscriptions.bind(i)}}function Bt(e){return zt(e)}function Vt(e){if(!e||typeof e!=`object`)return!1;let t=e;if(t.type!==`e2e-relay-envelope`||typeof t.payload!=`string`)return!1;let n=t.e2e;return!!n&&typeof n.nonce==`string`&&typeof n.v==`number`}async function Ht(e,t){let{ciphertext:n,nonce:r}=await W(t,I(JSON.stringify(e)));return{type:`e2e-relay-envelope`,payload:P(n),e2e:{nonce:P(r),v:1}}}async function Ut(e,t){let n=F(e.e2e.nonce),r=L(await G(t,F(e.payload),n));return JSON.parse(r)}function Wt(e){let t=()=>{if(!e.isFrozen())throw Error(`RelayControlRegistry must be frozen before processing relay control messages`)};function n(t){return typeof t.namespace!=`string`||typeof t.subject!=`string`||!e.isControlEvent(t.namespace,t.subject)||typeof t.messageId!=`string`?!1:t.payload!==void 0}function r(t){return typeof t.namespace!=`string`||typeof t.subject!=`string`||!e.isControlRequest(t.namespace,t.subject)||typeof t.messageId!=`string`||typeof t.correlationId!=`string`?!1:t.payload!==void 0}function i(e){if(t(),!e||typeof e!=`object`)return!1;let i=e;return i.type===`event`?n(i):i.type===`request`?r(i):!1}function a(e){if(t(),!e||typeof e!=`object`)return!1;let n=e;return n.type!==`relay-control`||n.v!==1||!n.payload||typeof n.payload!=`object`?!1:i(n.payload)}function o(e){if(t(),!i(e))throw Error(`Invalid relay control message`);return{type:`relay-control`,v:1,payload:e}}return{createRelayControlEnvelope:o,isRelayControlEnvelopeMessage:a,isRelayControlBusMessage:i}}function Q(e){let t=Date.now()-3e5;for(let[n,r]of e)r>=t||e.delete(n);for(;e.size>2048;){let t=e.keys().next().value;if(!t)break;e.delete(t)}}const Gt=e=>{if(!e||typeof e!=`object`)return!1;let t=e;return t.type===`response`&&typeof t.correlationId==`string`},Kt=e=>e.type===`subscribe`||e.type===`unsubscribe`,qt=e=>{if(!e||typeof e!=`object`)return!1;let t=e;return t.type===`subscription-ack`&&typeof t.ackId==`string`};function $(e,t,n,r){if(!r.isFrozen())throw Error(`E2ERelay transport requires a frozen relay control registry`);let{createRelayControlEnvelope:i,isRelayControlEnvelopeMessage:a,isRelayControlBusMessage:o}=Wt(r),s=e=>{n.delete(e),n.set(e,Date.now()),Q(n)};return{encode:async t=>{if(o(t))return t.type===`request`&&s(t.correlationId),JSON.stringify(i(t));if(Q(n),t.type===`response`&&n.has(t.correlationId))return n.delete(t.correlationId),JSON.stringify(t);let r=e.getSessionKey();if(!r&&Kt(t)||!r&&qt(t))return JSON.stringify(t);if(!r)throw Error(`E2E relay session not established`);let a=await Ht(t,r);return JSON.stringify(a)},decode:async r=>{let i=e.getSessionKey();if(a(r)){let e=r.payload;return t&&console.info(`[E2ERelayTransport] Decoded relay control envelope:`,e.type,e.namespace,e.subject),e.type===`request`&&s(e.correlationId),e}if(Q(n),Gt(r)&&n.has(r.correlationId))return n.delete(r.correlationId),r;if(!i&&qt(r))return r;if(!i)throw Error(`E2E relay session not established`);if(!Vt(r))throw Error(`Received plaintext message on relay E2E channel — possible injection`);return Ut(r,i)}}}function Jt(e,t,n=!1){let r=new Map;return{codec:$(e,n,r,t),reset:()=>r.clear()}}function Yt(e){let{e2eAuth:t,registry:n,websocket:r,...i}=e,a=e.debug??!1,o=new Map,s=$(t,a,o,n);a&&console.info(`[E2ERelayTransport] Creating inner transport...`);let c=new D({...i,url:`<pre-connected>`,createWebSocket:()=>r,auth:t,codec:s,autoReconnect:!1,heartbeat:i.heartbeat??!1});return a&&console.info(`[E2ERelayTransport] Inner transport created`),{name:c.name,connect:async()=>{if(!n.isFrozen())throw Error(`E2ERelayClientTransport: registry must be frozen before connect()`);o.clear();try{await c.connect()}catch(e){throw o.clear(),e}},disconnect:async()=>{o.clear();try{await c.disconnect()}finally{o.clear()}},send:c.send.bind(c),cancelRequest:c.cancelRequest.bind(c),onReceive:(...e)=>(a&&console.info(`[E2ERelayTransport] onReceive called, delegating to inner transport`),c.onReceive(...e)),subscribe:c.subscribe.bind(c),unsubscribe:c.unsubscribe.bind(c),getSubscriptions:c.getSubscriptions.bind(c),isReady:()=>!!t.getSessionKey()&&c.isReady()}}function Xt(){let e=!1,t=new Map,n=new Map,r=()=>{if(e)throw Error(`RelayControlRegistry is frozen and cannot be modified`)};return{registerEventSubjects(e,n){r();let i=t.get(e)??new Set;for(let e of n)i.add(e);t.set(e,i)},registerRequestNamespace(e,t){if(r(),t.length===0)throw Error(`RelayControlRegistry request namespace "${e}" requires at least one subject`);let i=n.get(e)??new Set;for(let e of t)i.add(e);n.set(e,i)},freeze(){e=!0},isFrozen(){return e},isControlEvent(e,n){return t.get(e)?.has(n)??!1},isControlRequest(e,t){return n.get(e)?.has(t)??!1}}}function Zt(e){if(Je(e),e.mode===`client`){if(e.connectionOptions!==void 0)throw Error(`createWebSocketTransport(client) does not support connectionOptions when wrapping a pre-created WebSocket. Use WebSocketClientTransport for reconnect or dial-time socket options.`);let t=e.websocket;return new D({url:`<pre-connected>`,createWebSocket:()=>t,auth:e.auth,debug:e.debug,autoReconnect:!1,heartbeat:!1})}else return new N({websocket:e.websocket,auth:e.auth,debug:e.debug})}export{Et as DispatchingAuth,wt as E2EAuth,Tt as E2ERelayAuth,Ze as HmacAuth,N as ServerTransport,D as WebSocketClientTransport,v as WebSocketConnectionError,je as clearHmacIdentitySecretsForTesting,Bt as createE2EClientTransport,Yt as createE2ERelayClientTransport,Jt as createE2ERelayCodec,Wt as createRelayControlHelpers,Xt as createRelayControlRegistry,qe as createWebSocketCloseEvent,Zt as createWebSocketTransport,vt as crypto,b as extractSocketErrorMessage,De as registerHmacIdentitySecret,A as resolveHmacIdentityAllowedSubjects,Ae as resolveHmacIdentityPeer,ke as resolveHmacIdentitySecret,Oe as rotateHmacIdentitySecret};