@makaio/framework 1.0.0-dev-1790760814648 → 1.0.0-dev-1790783144258

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 (89) hide show
  1. package/dist/.makaio-build.json +2 -2
  2. package/dist/adapters/claude/index.d.mts +20 -20
  3. package/dist/bus/index.d.mts +39 -9
  4. package/dist/bus/index.mjs +1 -1
  5. package/dist/bus-B-ksy7YX.mjs +9 -0
  6. package/dist/contracts/adapter/index.d.mts +1 -1
  7. package/dist/contracts/adapter/schemas/session-lineage.d.mts +1 -1
  8. package/dist/contracts/artifact/index.d.mts +1 -1
  9. package/dist/contracts/automation-trigger/index.d.mts +1 -1
  10. package/dist/contracts/capabilities/index.d.mts +1 -1
  11. package/dist/contracts/client/index.d.mts +2 -2
  12. package/dist/contracts/extension/index.d.mts +4 -4
  13. package/dist/contracts/harness/index.d.mts +1 -1
  14. package/dist/contracts/index.d.mts +62 -62
  15. package/dist/contracts/native-session-supervisor/index.d.mts +1 -1
  16. package/dist/contracts/reaction/index.d.mts +1 -1
  17. package/dist/contracts/session/index.d.mts +2 -2
  18. package/dist/contracts/worker/index.d.mts +1 -1
  19. package/dist/contracts/workflow/index.d.mts +1 -1
  20. package/dist/{contribution-CCVRsaNB.d.mts → contribution-CsDOPiDo.d.mts} +1 -1
  21. package/dist/{extension-context-BWrjVPXR.d.mts → extension-context-BY9o1ITm.d.mts} +3 -3
  22. package/dist/fast-connection-FG3yAA7o.mjs +1 -0
  23. package/dist/{hook-responses-v6EA_7WC.d.mts → hook-responses-Xxq6QAL2.d.mts} +1 -1
  24. package/dist/inbound-hooks/fast-connection.d.mts +1 -1
  25. package/dist/inbound-hooks/fast-connection.mjs +1 -1
  26. package/dist/inbound-hooks/index.d.mts +1 -1
  27. package/dist/inbound-hooks/index.mjs +1 -1
  28. package/dist/{index-MzTQNTb8.d.mts → index-BBrLhtLK.d.mts} +1 -1
  29. package/dist/{index-C0NhPcTU.d.mts → index-BrnOW7-5.d.mts} +12 -12
  30. package/dist/{index-BytbaguH.d.mts → index-C9X6ei7S.d.mts} +8 -8
  31. package/dist/{index-f9ok_Fxi.d.mts → index-CDezXPm9.d.mts} +6 -6
  32. package/dist/{index-Bl995t8Y.d.mts → index-CnVhfLrY.d.mts} +62 -62
  33. package/dist/{index-Cxx1aoPR.d.mts → index-DMFFSC7x.d.mts} +1 -1
  34. package/dist/{index-Bt6KIvVk.d.mts → index-DWWP2cUb.d.mts} +1 -1
  35. package/dist/{index-RiRTBXfr.d.mts → index-D_Zdnh0U.d.mts} +6 -6
  36. package/dist/{index-Dj60LBqi2.d.mts → index-Dnc0PaTv2.d.mts} +12 -12
  37. package/dist/{index-HsD17NLG.d.mts → index-Fmdwbgei.d.mts} +1 -1
  38. package/dist/{index-ClDAqLxW.d.mts → index-Fo4ALycy.d.mts} +58 -58
  39. package/dist/{index-CfGPuR1W.d.mts → index-OA1A-NWE.d.mts} +1 -1
  40. package/dist/{index-CFet5T7v2.d.mts → index-PymaxRkQ2.d.mts} +6 -6
  41. package/dist/{index-gOYLLgKk.d.mts → index-VG-C-ZHN.d.mts} +4 -4
  42. package/dist/{index-Bxm5RUGG2.d.mts → index-chwNKVMu2.d.mts} +33 -33
  43. package/dist/kernel/extension/index.d.mts +2 -2
  44. package/dist/kernel/index.d.mts +2 -2
  45. package/dist/kernel/observability/index.d.mts +1 -1
  46. package/dist/{namespace-ChJ-C9m_.d.mts → namespace-BH9U2C1O.d.mts} +2 -2
  47. package/dist/{namespace-D_NJoYyN.d.mts → namespace-DK5qZpST.d.mts} +6 -6
  48. package/dist/{namespace-u4eoUCLp.d.mts → namespace-DZooy1DW.d.mts} +18 -18
  49. package/dist/node/transports/index.d.mts +12 -1
  50. package/dist/node/transports/index.mjs +2 -2
  51. package/dist/package.json +1 -1
  52. package/dist/{schemas-DrrpHMbF2.d.mts → schemas-BYEgjPst2.d.mts} +7 -7
  53. package/dist/{schemas-DKaUrczB.d.mts → schemas-CEc_v3dl.d.mts} +2 -2
  54. package/dist/{schemas-BQhtYuCM.d.mts → schemas-CiJpGURT.d.mts} +10 -10
  55. package/dist/{schemas-yyNP39HU.d.mts → schemas-CtL2su-K.d.mts} +4 -4
  56. package/dist/{schemas-BBMHnFq8.d.mts → schemas-JPaSXxNr.d.mts} +4 -4
  57. package/dist/services/adapter-subsystem/index.d.mts +2 -2
  58. package/dist/services/adapter-subsystem/namespace.d.mts +1 -1
  59. package/dist/services/context-rules/index.d.mts +3 -3
  60. package/dist/services/execution-target/index.d.mts +2 -2
  61. package/dist/services/execution-target/namespace.d.mts +1 -1
  62. package/dist/services/execution-target/schemas.d.mts +1 -1
  63. package/dist/services/filesystem/namespace.d.mts +6 -6
  64. package/dist/services/filesystem/schemas.d.mts +3 -3
  65. package/dist/services/git/namespace.d.mts +2 -2
  66. package/dist/services/git/schemas.d.mts +2 -2
  67. package/dist/services/harness/index.d.mts +3 -3
  68. package/dist/services/index.d.mts +29 -29
  69. package/dist/services/preferences/index.d.mts +2 -2
  70. package/dist/services/preferences/schemas.d.mts +1 -1
  71. package/dist/services/preferences/storage-namespace.d.mts +2 -2
  72. package/dist/services/provider-context/index.d.mts +1 -1
  73. package/dist/services/session/handlers/index.d.mts +1 -1
  74. package/dist/services/session/index.d.mts +4 -4
  75. package/dist/services/session/session-events/namespace.d.mts +1 -1
  76. package/dist/services/settings/namespace.d.mts +10 -10
  77. package/dist/services/settings/storage/extension-configs/namespace.d.mts +3 -3
  78. package/dist/services/subagent-template/index.d.mts +1 -1
  79. package/dist/services/subagent-template/schemas.d.mts +1 -1
  80. package/dist/{session-lineage-Bjh0Ccu7.d.mts → session-lineage-DZr5w2-z.d.mts} +1 -1
  81. package/dist/{storage-namespace-DoxNJ9Cg.d.mts → storage-namespace-Cl8qtHDu.d.mts} +10 -10
  82. package/dist/{types-DsZBnL7z.d.mts → types-CRKyrt5_.d.mts} +12 -12
  83. package/dist/ui-kernel/index.d.mts +4 -4
  84. package/dist/ui-kernel/pages/namespace.d.mts +4 -4
  85. package/dist/ui-kernel/pages/schemas.d.mts +1 -1
  86. package/dist/workflow-engine/index.d.mts +39 -39
  87. package/package.json +1 -1
  88. package/dist/bus--m38BS3i.mjs +0 -9
  89. package/dist/fast-connection-Y4_AFwCD.mjs +0 -1
@@ -585,8 +585,8 @@ declare const SessionEventStorageNamespace$1: {
585
585
  type: _$zod.ZodLiteral<"locality.degraded">;
586
586
  payload: _$zod.ZodDiscriminatedUnion<[_$zod.ZodObject<{
587
587
  intent: _$zod.ZodEnum<{
588
- fork: "fork";
589
588
  resume: "resume";
589
+ fork: "fork";
590
590
  }>;
591
591
  verdictKind: _$zod.ZodLiteral<"degrade">;
592
592
  reason: _$zod.ZodEnum<{
@@ -611,8 +611,8 @@ declare const SessionEventStorageNamespace$1: {
611
611
  turnId: _$zod.ZodOptional<_$zod.ZodString>;
612
612
  }, _$zod_v4_core0.$strip>, _$zod.ZodObject<{
613
613
  intent: _$zod.ZodEnum<{
614
- fork: "fork";
615
614
  resume: "resume";
615
+ fork: "fork";
616
616
  }>;
617
617
  verdictKind: _$zod.ZodLiteral<"foreign">;
618
618
  foreignMachineId: _$zod.ZodString;
@@ -967,8 +967,8 @@ declare const SessionEventStorageNamespace$1: {
967
967
  type: _$zod.ZodLiteral<"locality.degraded">;
968
968
  payload: _$zod.ZodDiscriminatedUnion<[_$zod.ZodObject<{
969
969
  intent: _$zod.ZodEnum<{
970
- fork: "fork";
971
970
  resume: "resume";
971
+ fork: "fork";
972
972
  }>;
973
973
  verdictKind: _$zod.ZodLiteral<"degrade">;
974
974
  reason: _$zod.ZodEnum<{
@@ -993,8 +993,8 @@ declare const SessionEventStorageNamespace$1: {
993
993
  turnId: _$zod.ZodOptional<_$zod.ZodString>;
994
994
  }, _$zod_v4_core0.$strip>, _$zod.ZodObject<{
995
995
  intent: _$zod.ZodEnum<{
996
- fork: "fork";
997
996
  resume: "resume";
997
+ fork: "fork";
998
998
  }>;
999
999
  verdictKind: _$zod.ZodLiteral<"foreign">;
1000
1000
  foreignMachineId: _$zod.ZodString;
@@ -1339,8 +1339,8 @@ declare const SessionEventStorageNamespace$1: {
1339
1339
  type: _$zod.ZodLiteral<"locality.degraded">;
1340
1340
  payload: _$zod.ZodDiscriminatedUnion<[_$zod.ZodObject<{
1341
1341
  intent: _$zod.ZodEnum<{
1342
- fork: "fork";
1343
1342
  resume: "resume";
1343
+ fork: "fork";
1344
1344
  }>;
1345
1345
  verdictKind: _$zod.ZodLiteral<"degrade">;
1346
1346
  reason: _$zod.ZodEnum<{
@@ -1365,8 +1365,8 @@ declare const SessionEventStorageNamespace$1: {
1365
1365
  turnId: _$zod.ZodOptional<_$zod.ZodString>;
1366
1366
  }, _$zod_v4_core0.$strip>, _$zod.ZodObject<{
1367
1367
  intent: _$zod.ZodEnum<{
1368
- fork: "fork";
1369
1368
  resume: "resume";
1369
+ fork: "fork";
1370
1370
  }>;
1371
1371
  verdictKind: _$zod.ZodLiteral<"foreign">;
1372
1372
  foreignMachineId: _$zod.ZodString;
@@ -1719,8 +1719,8 @@ declare const SessionEventStorageNamespace$1: {
1719
1719
  type: _$zod.ZodLiteral<"locality.degraded">;
1720
1720
  payload: _$zod.ZodDiscriminatedUnion<[_$zod.ZodObject<{
1721
1721
  intent: _$zod.ZodEnum<{
1722
- fork: "fork";
1723
1722
  resume: "resume";
1723
+ fork: "fork";
1724
1724
  }>;
1725
1725
  verdictKind: _$zod.ZodLiteral<"degrade">;
1726
1726
  reason: _$zod.ZodEnum<{
@@ -1745,8 +1745,8 @@ declare const SessionEventStorageNamespace$1: {
1745
1745
  turnId: _$zod.ZodOptional<_$zod.ZodString>;
1746
1746
  }, _$zod_v4_core0.$strip>, _$zod.ZodObject<{
1747
1747
  intent: _$zod.ZodEnum<{
1748
- fork: "fork";
1749
1748
  resume: "resume";
1749
+ fork: "fork";
1750
1750
  }>;
1751
1751
  verdictKind: _$zod.ZodLiteral<"foreign">;
1752
1752
  foreignMachineId: _$zod.ZodString;
@@ -2087,8 +2087,8 @@ declare const SessionEventStorageNamespace$1: {
2087
2087
  type: _$zod.ZodLiteral<"locality.degraded">;
2088
2088
  payload: _$zod.ZodDiscriminatedUnion<[_$zod.ZodObject<{
2089
2089
  intent: _$zod.ZodEnum<{
2090
- fork: "fork";
2091
2090
  resume: "resume";
2091
+ fork: "fork";
2092
2092
  }>;
2093
2093
  verdictKind: _$zod.ZodLiteral<"degrade">;
2094
2094
  reason: _$zod.ZodEnum<{
@@ -2113,8 +2113,8 @@ declare const SessionEventStorageNamespace$1: {
2113
2113
  turnId: _$zod.ZodOptional<_$zod.ZodString>;
2114
2114
  }, _$zod_v4_core0.$strip>, _$zod.ZodObject<{
2115
2115
  intent: _$zod.ZodEnum<{
2116
- fork: "fork";
2117
2116
  resume: "resume";
2117
+ fork: "fork";
2118
2118
  }>;
2119
2119
  verdictKind: _$zod.ZodLiteral<"foreign">;
2120
2120
  foreignMachineId: _$zod.ZodString;
@@ -2469,8 +2469,8 @@ declare const SessionEventStorageNamespace$1: {
2469
2469
  type: _$zod.ZodLiteral<"locality.degraded">;
2470
2470
  payload: _$zod.ZodDiscriminatedUnion<[_$zod.ZodObject<{
2471
2471
  intent: _$zod.ZodEnum<{
2472
- fork: "fork";
2473
2472
  resume: "resume";
2473
+ fork: "fork";
2474
2474
  }>;
2475
2475
  verdictKind: _$zod.ZodLiteral<"degrade">;
2476
2476
  reason: _$zod.ZodEnum<{
@@ -2495,8 +2495,8 @@ declare const SessionEventStorageNamespace$1: {
2495
2495
  turnId: _$zod.ZodOptional<_$zod.ZodString>;
2496
2496
  }, _$zod_v4_core0.$strip>, _$zod.ZodObject<{
2497
2497
  intent: _$zod.ZodEnum<{
2498
- fork: "fork";
2499
2498
  resume: "resume";
2499
+ fork: "fork";
2500
2500
  }>;
2501
2501
  verdictKind: _$zod.ZodLiteral<"foreign">;
2502
2502
  foreignMachineId: _$zod.ZodString;
@@ -2841,8 +2841,8 @@ declare const SessionEventStorageNamespace$1: {
2841
2841
  type: _$zod.ZodLiteral<"locality.degraded">;
2842
2842
  payload: _$zod.ZodDiscriminatedUnion<[_$zod.ZodObject<{
2843
2843
  intent: _$zod.ZodEnum<{
2844
- fork: "fork";
2845
2844
  resume: "resume";
2845
+ fork: "fork";
2846
2846
  }>;
2847
2847
  verdictKind: _$zod.ZodLiteral<"degrade">;
2848
2848
  reason: _$zod.ZodEnum<{
@@ -2867,8 +2867,8 @@ declare const SessionEventStorageNamespace$1: {
2867
2867
  turnId: _$zod.ZodOptional<_$zod.ZodString>;
2868
2868
  }, _$zod_v4_core0.$strip>, _$zod.ZodObject<{
2869
2869
  intent: _$zod.ZodEnum<{
2870
- fork: "fork";
2871
2870
  resume: "resume";
2871
+ fork: "fork";
2872
2872
  }>;
2873
2873
  verdictKind: _$zod.ZodLiteral<"foreign">;
2874
2874
  foreignMachineId: _$zod.ZodString;
@@ -3221,8 +3221,8 @@ declare const SessionEventStorageNamespace$1: {
3221
3221
  type: _$zod.ZodLiteral<"locality.degraded">;
3222
3222
  payload: _$zod.ZodDiscriminatedUnion<[_$zod.ZodObject<{
3223
3223
  intent: _$zod.ZodEnum<{
3224
- fork: "fork";
3225
3224
  resume: "resume";
3225
+ fork: "fork";
3226
3226
  }>;
3227
3227
  verdictKind: _$zod.ZodLiteral<"degrade">;
3228
3228
  reason: _$zod.ZodEnum<{
@@ -3247,8 +3247,8 @@ declare const SessionEventStorageNamespace$1: {
3247
3247
  turnId: _$zod.ZodOptional<_$zod.ZodString>;
3248
3248
  }, _$zod_v4_core0.$strip>, _$zod.ZodObject<{
3249
3249
  intent: _$zod.ZodEnum<{
3250
- fork: "fork";
3251
3250
  resume: "resume";
3251
+ fork: "fork";
3252
3252
  }>;
3253
3253
  verdictKind: _$zod.ZodLiteral<"foreign">;
3254
3254
  foreignMachineId: _$zod.ZodString;
@@ -3537,14 +3537,14 @@ declare const SessionEventStorageNamespace$1: {
3537
3537
  timestamp: number;
3538
3538
  type: "locality.degraded";
3539
3539
  payload: {
3540
- intent: "fork" | "resume";
3540
+ intent: "resume" | "fork";
3541
3541
  verdictKind: "degrade";
3542
3542
  reason: "adapter-unsupported" | "adapter-mismatch" | "no-adapter-session" | "missing-machine-id" | "machine-mismatch" | "cwd-mismatch" | "transforms-present" | "compression-present" | "connector-swap" | "mid-history-unsupported" | "hybrid-imported-orchestrated" | "native-attempt-failed" | "agent-already-started" | "fork-point-unresolvable" | "adapter-session-moved";
3543
3543
  agentId?: string | undefined;
3544
3544
  adapterId?: string | undefined;
3545
3545
  turnId?: string | undefined;
3546
3546
  } | {
3547
- intent: "fork" | "resume";
3547
+ intent: "resume" | "fork";
3548
3548
  verdictKind: "foreign";
3549
3549
  foreignMachineId: string;
3550
3550
  agentId?: string | undefined;
@@ -1300,6 +1300,15 @@ interface WebSocketClientTransportOptions {
1300
1300
  * @defaultValue false
1301
1301
  */
1302
1302
  debug?: boolean;
1303
+ /**
1304
+ * Sink for debug log lines emitted while `debug` is enabled.
1305
+ *
1306
+ * Override when stdout is a protocol channel (e.g. hook subprocesses) and debug
1307
+ * output must go elsewhere. Only the client transport's debug lines are routed
1308
+ * here; error and warning output keeps using `console.error` / `console.warn`.
1309
+ * @defaultValue `console.info`
1310
+ */
1311
+ debugLog?: (message: string) => void;
1303
1312
  }
1304
1313
  //#endregion
1305
1314
  //#region transports/ws/src/ws-client-transport.d.ts
@@ -1329,6 +1338,7 @@ declare class WebSocketClientTransport implements BusTransport {
1329
1338
  private readonly readiness;
1330
1339
  private readonly wsFactory;
1331
1340
  private readonly debug;
1341
+ private readonly debugLog;
1332
1342
  private readonly onConnectedCallback;
1333
1343
  private readonly onDisconnectedCallback;
1334
1344
  private session;
@@ -1929,9 +1939,10 @@ interface E2ERelayCodecHandle {
1929
1939
  * @param e2eAuth - Relay-mode E2E auth instance
1930
1940
  * @param registry - Frozen relay control registry for subject classification
1931
1941
  * @param debug - Enable diagnostic logging
1942
+ * @param debugLog - Sink for diagnostic log lines while `debug` is enabled (defaults to `console.info`)
1932
1943
  * @returns Codec handle containing the wire codec and a session-reset function
1933
1944
  */
1934
- declare function createE2ERelayCodec(e2eAuth: E2ERelayAuth, registry: RelayControlRegistry, debug?: boolean): E2ERelayCodecHandle;
1945
+ declare function createE2ERelayCodec(e2eAuth: E2ERelayAuth, registry: RelayControlRegistry, debug?: boolean, debugLog?: (message: string) => void): E2ERelayCodecHandle;
1935
1946
  /**
1936
1947
  * Create an E2E encrypted relay client transport.
1937
1948
  * @param options - Transport configuration
@@ -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,matchesFilter as p,matchesSubscription as m,shouldReceiveMessage as h,trackMessageCorrelation as ee}from"@makaio/framework/bus";const g={baseMs:1e3,maxMs:1e4};function te(e,t,n){let r=Math.max(t,100),i=Math.max(n,r);return Math.min(r*2**e,i)}function ne(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 re={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??g.baseMs,maxMs:e?.maxMs??g.maxMs}}function oe(e){if(e===!1)return!1;let t=e?.intervalMs??re.intervalMs,n=e?.timeoutMs??re.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 _=class extends Error{code;constructor(e,t,n){super(t,n),this.code=e,this.name=`WebSocketConnectionError`}};function v(e){let t=typeof e==`object`&&!!e&&`code`in e&&e.code===1008;return new _(t?`WS_POLICY_REJECTED`:`WS_CONNECTION_UNAVAILABLE`,t?`WebSocket connection rejected by peer policy`:`WebSocket closed before connection completed`)}function y(e,t=`unknown error`){return`message`in e?String(e.message):t}async function b(e,t,n){let r=await t.encode(e);n.send(r)}function se(e,t,n){return n?.aborted?Promise.reject(n.reason):e.readyState===1?Promise.resolve():e.readyState>=2?Promise.reject(v()):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 _(`WS_CONNECTION_UNAVAILABLE`,`WebSocket connection failed — ${y(e)}`,{cause:e}))},c=e=>{a(),i(v(e))},l=()=>{a(),i(n?.reason)},u=t===void 0?void 0:setTimeout(()=>{a(),i(new _(`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 x(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 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!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 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||!t.isCurrentSession())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 S(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),S(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),S(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 me(e,t){await Promise.allSettled(e.inFlightMessages),e.getSocket()===t&&e.correlations.rejectAll(e.getSessionFailure()??new n(e.name))}function he(e,t){let n=n=>{if(t.getSocket()!==e)return;let r=de(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.readiness===`peer-sync`&&t.resolveReady()},onSubscriptionAck:e=>{t.resolveSubscriptionAck(e)},sendSubscriptionAck:async n=>{t.getSocket()!==e||e.readyState!==1||await b({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 ge(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{x(e)}catch(e){r.push(e)}return r.length===1?n:AggregateError(r,`WebSocket connection failed and cleanup was incomplete`,{cause:n})}async function _e(e,t){t.throwIfAborted();let n=new AbortController,r=()=>n.abort(new _(`WS_CONNECTION_UNAVAILABLE`,`WebSocket connection cancelled`));t.addEventListener(`abort`,r);let i=setTimeout(()=>n.abort(new _(`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(v(e)),l=e=>n.abort(new _(`WS_CONNECTION_UNAVAILABLE`,`WebSocket connection failed — ${y(e)}`,{cause:e})),u=t=>{if(o(),a===null)return t;let n=a;return s(),a=null,ge(n,e,t)},d=()=>{},f=new Promise((e,t)=>{d=()=>{t(u(n.signal.reason))},n.signal.addEventListener(`abort`,d)});try{let t=ve(e,n.signal,()=>{o=e.resetReadyPromise()},t=>{a=t,e.setSocket(t),e.setAuthComplete(!1),t.addEventListener(`close`,c),t.addEventListener(`error`,l),he(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 ve(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&&(x(o),t.throwIfAborted()),i(o),await ye(o,e,t)}async function ye(e,t,n){if(await se(e,void 0,n),n.throwIfAborted(),t.auth&&(await t.auth.authenticateClient(t=>{if(n.throwIfAborted(),e.readyState!==1)throw v();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&&pe(e,t.heartbeat,t),t.readiness===`session-established`&&t.resolveReady(),t.debug&&console.info(`[WebSocketClientTransport:${t.name}] Connected to ${t.url}`),t.notifyConnected()}function be(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 xe(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 be(a,e),e.aborted)break;if(o&&a!==null){if(await me(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=te(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 ne(a,AbortSignal.any([e,o.signal])),i(null),e.aborted)break;try{if(await _e(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 be(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 Se(e,t,n){let r=async()=>{t.getSocket()===e&&(C(e,t),t.auth?.cleanup(),t.setAuthComplete(!1),n(),t.resolveReady(),t.notifyDisconnected(),await me(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 Ce(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 b(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 we(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 b(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 Te=class{name;termination=new AbortController;ownedSocket;onClose;constructor(e,t){this.name=t,this.ownedSocket=e,this.onClose=e=>{let r=v(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 Ee(new Promise(()=>{}),AbortSignal.any([t,this.signal]))}if(r.readyState!==1)throw new n(this.name);return r}};async function Ee(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 De(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 Oe(e,i,t),ee(t,e.correlations,r);let a=new AbortController,o=ee(t,e.correlations,r).then(e=>(a.abort(),e),e=>{throw a.abort(e),e});return Oe(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 Oe(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 Ee(e.codec.encode(n),a),s=t.writable(e.currentSession(),r);s instanceof Promise?await s:s.send(o)}var w=class{name;url;auth;codec;messageTransform;autoReconnectConfig;heartbeatConfig;connectTimeoutMs;readiness;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??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.readiness=e.readiness??`peer-sync`,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 _e(this.connectionDeps(),e.signal)}catch(t){throw this.reconnectAbort===e&&(this.reconnectAbort=null),t}if(e.signal.aborted||this.reconnectAbort!==e)throw new _(`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 _(`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,x(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 De({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 Ce(e,t,n,r,this.subscriptionDeps())}async unsubscribe(e){await we(e,this.subscriptionDeps())}getSubscriptions(){return new Set(this.localSubscriptions.keys())}cancelRequest(e,t){this.correlations.cancel(e,t)}hasLiveWireSession(){return this.socket!==null&&this.socket.readyState===1&&this.authComplete}isReady(){return this.hasLiveWireSession()}canSend(e){return this.hasLiveWireSession()&&(this.codec.canEncode?.(e)??!0)}async reconnect(){if(!this.hasLiveWireSession()){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 xe(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,readiness:this.readiness,heartbeat:this.heartbeatConfig,getSocket:()=>this.socket,setSocket:(e,t)=>{this.session?.release(t),e!==null&&(this.session=new Te(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?.(),this.socket===e&&this.hasLiveWireSession()&&this.onConnected?.()},notifyDisconnected:()=>{this.onDisconnectedCallback?.(),this.onDisconnected?.()},inFlightMessages:this.inFlightMessages}}defaultWsFactory=async e=>new(await(import(`ws`))).WebSocket(e);wireNoReconnectClose(e){Se(e,this.connectionDeps(),()=>{this.reconnectAbort=null})}};function T(e){e.timer!==void 0&&clearTimeout(e.timer)}var ke=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?(T(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())T(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;T(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`||(T(t),this.pendingBroadcasts.delete(e),t.resolve(t.results),this.debug&&console.info(`[BroadcastAggregator] Server broadcast ${e} finalized with ${t.results.length} results`))}},Ae=class{clients=new Set;clientsByConnectionId=new Map;authenticatingClients=new Set;clientSubscriptions=new Map;clientSubscriptionState=new Map;clientFilters=new Map;requestOrigins=new Map;debug;subscriptionSubjectRestrictionResolver;requiredSubscriptionFilterResolver;socketAuthChecker;constructor(e={}){this.debug=e.debug??!1,this.subscriptionSubjectRestrictionResolver=e.subscriptionSubjectRestrictionResolver,this.requiredSubscriptionFilterResolver=e.requiredSubscriptionFilterResolver,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,t){this.clients.add(e),t!==void 0&&this.clientsByConnectionId.set(t,e)}removeClient(e){for(let[t,n]of this.clientsByConnectionId)n===e&&this.clientsByConnectionId.delete(t);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}getClientByConnectionId(e){let t=this.clientsByConnectionId.get(e);return t!==void 0&&this.isReadyAndAuthenticated(t)?t:void 0}trackRequestOrigin(e,t){let{correlationId:n}=t;if(this.requestOrigins.has(n))return;let r=this.getRequestRemainingLifetime(t);if(r!==void 0&&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)&&this.isPayloadAllowedForClient(i,e,t)&&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&&m(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 h(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){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.subscriptionSubjectRestrictionResolver||t===void 0)return!0;let n=this.subscriptionSubjectRestrictionResolver(e);return n===null?!0:[...n].some(e=>m(t,e))}isPayloadAllowedForClient(e,t,n){if(!this.requiredSubscriptionFilterResolver||t===void 0)return!0;let r=this.requiredSubscriptionFilterResolver(e)?.[t];return r===void 0||p(n,r)}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 E=new Map;function je(e){if(typeof e==`object`&&e){for(let t of Object.values(e))je(t);Object.freeze(e)}return e}function Me(e){let t=Object.fromEntries(Object.entries(e).map(([e,t])=>[e,je(structuredClone(t))]));return Object.freeze(t)}function D(e,t){let n=!0;return()=>{n&&(n=!1,E.get(e)===t&&E.delete(e))}}function O(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`);if(`allowedSubjects`in n)throw Error(`registerHmacIdentitySecret no longer accepts allowedSubjects; use allowedMessageSubjects and/or allowedSubscriptionSubjects`);let r=n.peerKind.trim();if(r.length===0)throw Error(`registerHmacIdentitySecret requires a non-empty peerKind`);let i=n.allowedMessageSubjects!==void 0||n.allowedSubscriptionSubjects!==void 0;if(n.requiredSubscriptionFilters!==void 0){for(let e of Object.keys(n.requiredSubscriptionFilters))if(e.includes(`*`))throw Error(`registerHmacIdentitySecret requires exact full subjects for requiredSubscriptionFilters`)}let a={secret:t,peerKind:r,...n.claims===void 0?{}:{claims:n.claims},...i?{allowedMessageSubjects:new Set(n.allowedMessageSubjects??[]),allowedSubscriptionSubjects:new Set(n.allowedSubscriptionSubjects??[])}:{},...n.requiredSubscriptionFilters===void 0?{}:{requiredSubscriptionFilters:Me(n.requiredSubscriptionFilters)}};return E.set(e,a),D(e,a)}function Ne(e,t,n={}){if(t.length===0)throw Error(`rotateHmacIdentitySecret requires a non-empty secret`);let r=E.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.allowedMessageSubjects===void 0?{}:{allowedMessageSubjects:r.allowedMessageSubjects},...r.allowedSubscriptionSubjects===void 0?{}:{allowedSubscriptionSubjects:r.allowedSubscriptionSubjects},...r.requiredSubscriptionFilters===void 0?{}:{requiredSubscriptionFilters:r.requiredSubscriptionFilters}};return E.set(e,i),D(e,i)}function Pe(e){let t=E.get(e);return t===void 0?void 0:D(e,t)}function Fe(e){return E.get(e)?.secret??null}function Ie(e){let t=E.get(e);return t?{kind:t.peerKind,id:e,authenticated:!0,...t.claims===void 0?{}:{claims:t.claims}}:null}function Le(e){return E.get(e)?.allowedMessageSubjects??null}function k(e){return E.get(e)?.allowedSubscriptionSubjects??null}function Re(e){return E.get(e)?.requiredSubscriptionFilters??null}function ze(){E.clear()}function Be(e){return e.type===`request`||e.type===`event`||e.type===`broadcast`}function Ve(e){return t(e)&&Object.values(e).every(e=>Array.isArray(e)&&e.every(e=>typeof e==`number`&&Number.isFinite(e)))}function He(e){return e.endsWith(`*`)}function Ue(e,t,n,r){let i={};for(let[a,o]of Object.entries(e))He(a)?t===null||t.has(a)?i[a]=o:n&&console.debug(`[ServerTransport] Dropping wildcard subscription '${a}': not in allowedSubscriptionSubjects for peer '${r}'`):t===null||[...t].some(e=>m(a,e))?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 A(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 j(e,t,n){let r=!0;for(let i of e)await A(i,t,n)||(r=!1);return r}function We(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 Ge(e){let t=e?.peer?.id;if(t===void 0)return null;let n=Le(t),r=k(t);return n===null&&r===null?null:{peerId:t,allowedMessageSubjects:n,allowedSubscriptionSubjects:r}}function Ke(e,t,n,r){if(r===null||!Be(e))return!1;let i=`${e.namespace}.${e.subject}`;return r.allowedMessageSubjects===null||r.allowedMessageSubjects.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 qe(e,t,n){if(!Ve(e.subjects))return n&&console.warn(`[ServerTransport] Malformed ${e.type} message: missing subjects record`),null;if(t===null)return e.subjects;let r=Ue(e.subjects,t.allowedSubscriptionSubjects,n,t.peerId);return r===null&&n&&console.debug(`[ServerTransport] Dropping ${e.type} message: all subjects filtered for peer '${t.peerId}'`),r}async function Je(e,t,n,r,i){if(e.type!==`subscribe`&&e.type!==`unsubscribe`)return!1;let a=e,o=qe(a,i,n.debug);return o===null||await j(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 Ye(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=u(i)??void 0,o=n.registry.getInterestedClients(a,i.payload,t),s=n.normalizeBroadcastTimeout(i.timeout);return n.broadcastAggregator.startClientBroadcast(t,i,o,n.sendSafely,s),await A(e,n.handlers,{debug:n.debug,receiveContext:r}),!0}async function Xe(e,t,n){if(We(e,n,t))return;let r=n.auth?.getReceiveContext?.(t),i=Ge(r);if(!Ke(e,t,n,i)){if(e.type===`subscribe`||e.type===`unsubscribe`){await Je(e,t,n,r,i);return}if(e.type===`broadcast`){await Ye(e,t,n,r);return}e.type===`event`&&n.registry.forwardEventToClients(t,e,n.sendSafely),e.type===`request`&&n.registry.trackRequestOrigin(t,e),await A(e,n.handlers,{debug:n.debug,receiveContext:r})}}function Ze(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 Xe(c,e,t)}catch(e){i&&console.error(`[ServerTransport] Failed to process message:`,e)}}}function Qe(e){return typeof e!=`number`||!Number.isFinite(e)||e<=0?5e3:Math.min(e,6e4)}async function $e(e,t){let{registry:n,correlations:r,broadcastAggregator:i,handlers:a,auth:o,serverSubscriptions:c,sendSafely:l,debug:u,onConnectionClosed:d}=t;o&&n.addAuthenticating(e);let f=Ze(e,{registry:n,correlations:r,broadcastAggregator:i,handlers:a,auth:o,normalizeBroadcastTimeout:Qe,sendSafely:l,debug:u}),p=e=>{f(e.data)},m=()=>{let t=o?.getReceiveContext?.(e)?.connectionId;o?.cleanupSocket(e);let r=n.removeClient(e);t!==void 0&&d(t),e.removeEventListener(`message`,p),e.removeEventListener(`close`,m),e.removeEventListener(`error`,h),i.handleClientDisconnect(e),j(r,a,{debug:u,logContext:`dispatching disconnected client subscriptions`}),u&&console.info(`[ServerTransport] Client disconnected (${n.size} remaining)`)},h=e=>{u&&console.error(`[ServerTransport] Client socket error:`,e)};e.addEventListener(`message`,p),e.addEventListener(`close`,m),e.addEventListener(`error`,h);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,o?.getReceiveContext?.(e)?.connectionId),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 _&&(t.code===`WS_AUTHENTICATION_REJECTED`||t.code===`WS_POLICY_REJECTED`);e.close(n?1008:1011,n?`Authentication failed`:`Connection setup failed`)}}async function et(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 tt=class{name;wss;auth;debug;handlers=new Set;registry;serverSubscriptions=new Map;broadcastAggregator;correlations=new r;connectionListener=null;connectionClosedHandlers=new Set;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 Ae({debug:i,subscriptionSubjectRestrictionResolver:r?e=>{let t=(r.getReceiveContext?.(e))?.peer?.id;return t===void 0?null:k(t)}:void 0,requiredSubscriptionFilterResolver:r?e=>{let t=(r.getReceiveContext?.(e))?.peer?.id;return t===void 0?null:Re(t)}:void 0,socketAuthChecker:r?e=>r.isSocketAuthenticated?.(e)??!0:void 0}),this.broadcastAggregator=new ke({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=>{$e(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,onConnectionClosed:e=>{for(let t of this.connectionClosedHandlers)t(e)}})},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 et(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}async sendToConnection(e,t){let n=this.registry.getClientByConnectionId(t);return n===void 0?!1:(this.sendToClientSafely(n,JSON.stringify(e)),!0)}onConnectionClosed(e){return this.connectionClosedHandlers.add(e),()=>this.connectionClosedHandlers.delete(e)}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 nt(e,t){let n=new Event(`close`);return Object.defineProperties(n,{code:{value:e??1e3,enumerable:!0},reason:{value:t??``,enumerable:!0}}),n}function rt(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(!it(t.websocket))throw TypeError(`WebSocket transport client mode requires a websocket with addEventListener/removeEventListener`);return}if(!at(t.websocket))throw TypeError(`WebSocket transport server mode requires a websocket with on/off listener methods`)}function it(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 at(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 ot=class{secret;algorithm;challengeTimeout;identityId;resolveSecret;resolvePeer;pendingChallenge;pendingResult;queuedChallengeNonce;queuedResult;clientAuthComplete=!1;serverPendingResponses=new Map;serverAuthenticatedSockets=new Set;serverAuthenticatedPeers=new Map;serverConnectionIds=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 _(`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 _(`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),this.serverConnectionIds.set(e,globalThis.crypto.randomUUID())}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 _(`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 _(`WS_CONNECTION_UNAVAILABLE`,`Socket disconnected during HMAC authentication`)}assertServerOwner(e,t){if(this.serverPendingResponses.get(e)!==t)throw new _(`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 _(`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 _(`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 _(`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 _(`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:``,connectionId:this.serverConnectionIds.get(e),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 _(`WS_CONNECTION_UNAVAILABLE`,`Socket disconnected during HMAC authentication`))),this.serverAuthenticatedPeers.delete(e),this.serverConnectionIds.delete(e),this.serverAuthenticatedSecrets.delete(e),this.serverAuthenticatedSockets.delete(e)}cleanup(){this.pendingChallenge&&=(clearTimeout(this.pendingChallenge.timeoutHandle),this.pendingChallenge.reject(new _(`WS_CONNECTION_UNAVAILABLE`,`Socket disconnected during HMAC authentication`)),void 0),this.pendingResult&&=(clearTimeout(this.pendingResult.timeoutHandle),this.pendingResult.reject(new _(`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 _(`WS_CONNECTION_UNAVAILABLE`,`Socket disconnected during HMAC authentication`));this.serverPendingResponses.clear(),this.serverAuthenticatedPeers.clear(),this.serverConnectionIds.clear(),this.serverAuthenticatedSecrets.clear(),this.serverAuthenticatedSockets.clear()}};const st=`makaio-cli-local:v1`,ct=`makaio-cli-local`;function lt(e){return O(st,e,{peerKind:ct})}function M(e){let t=Array.from(e,e=>String.fromCharCode(e)).join(``);return btoa(t).replace(/\+/g,`-`).replace(/\//g,`_`).replace(/=/g,``)}function N(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 P(e){return new TextEncoder().encode(e)}function F(e){return new TextDecoder().decode(e)}async function I(e){let t=await crypto.subtle.exportKey(`spki`,e);return M(new Uint8Array(t))}async function L(e){let t=await crypto.subtle.exportKey(`raw`,e);return M(new Uint8Array(t))}async function R(e,t,n=[]){let r=N(e);return crypto.subtle.importKey(`spki`,r,t,!0,n)}async function z(e,t,n=[]){let r=N(e);return crypto.subtle.importKey(`raw`,r,t,!0,n)}async function B(e){let t=await crypto.subtle.exportKey(`pkcs8`,e),n=M(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 V(e,t,n){let r=N(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 H={name:`ECDH`,namedCurve:`P-256`};async function U(e=!0){return crypto.subtle.generateKey(H,e,[`deriveKey`,`deriveBits`])}async function ut(e){return I(e)}async function dt(e){return L(e)}async function ft(e){return z(e,H)}async function pt(e,t=[]){return R(e,H,t)}async function mt(e){return B(e)}async function ht(e){return V(e,H,[`deriveKey`,`deriveBits`])}async function gt(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 _t(e){return crypto.subtle.importKey(`raw`,e,{name:`AES-GCM`},!1,[`encrypt`,`decrypt`])}async function vt(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:P(n)},r,{name:`AES-GCM`,length:256},!1,[`encrypt`,`decrypt`])}const K={name:`ECDSA`,namedCurve:`P-256`};async function yt(e=!0){return crypto.subtle.generateKey(K,e,[`sign`,`verify`])}async function bt(e,t){let n=await crypto.subtle.sign({name:`ECDSA`,hash:{name:`SHA-256`}},e,t);return new Uint8Array(n)}async function xt(e,t,n){return crypto.subtle.verify({name:`ECDSA`,hash:{name:`SHA-256`}},e,t,n)}async function St(e){return I(e)}async function Ct(e){return R(e,K,[`verify`])}async function wt(e){return L(e)}async function Tt(e){return z(e,K,[`verify`])}async function Et(e){return B(e)}async function Dt(e){return V(e,K,[`sign`])}var Ot=e({decodeText:()=>F,decrypt:()=>G,deriveSessionKey:()=>vt,deriveSharedSecret:()=>gt,encodeText:()=>P,encrypt:()=>W,exportPrivateKeyPEM:()=>mt,exportPublicKey:()=>ut,exportPublicKeyRaw:()=>dt,exportSigningPrivateKeyPEM:()=>Et,exportSigningPublicKey:()=>St,exportSigningPublicKeyRaw:()=>wt,fromBase64Url:()=>N,generateECDHKeyPair:()=>U,generateSigningKeyPair:()=>yt,importAESKey:()=>_t,importPrivateKeyPEM:()=>ht,importPublicKey:()=>pt,importPublicKeyRaw:()=>ft,importSigningPrivateKeyPEM:()=>Dt,importSigningPublicKey:()=>Ct,importSigningPublicKeyRaw:()=>Tt,sign:()=>bt,toBase64Url:()=>M,verify:()=>xt});function kt(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 U(!0),r=await ut(n.publicKey);return{ephemeralKeyPair:n,ephemeralPublicKey:r,signature:q(await bt(e,P(r+t)))}}function At(){return q(crypto.getRandomValues(new Uint8Array(16)))}async function Y(e,t,n,r){let i=P(t+r);return xt(e,kt(n),i)}async function X(e,t,n,r){let i;try{i=await pt(t)}catch(e){throw e instanceof DOMException&&e.name===`DataError`?new _(`WS_AUTHENTICATION_REJECTED`,`Invalid E2E peer public key`,{cause:e}):e}return vt(await gt(e,i),kt(n),r)}async function jt(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=P(`${i}${a}${o}${s}`),l=new Uint8Array(c).buffer,u=await crypto.subtle.digest(`SHA-256`,l);return q(new Uint8Array(u))}function Mt(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 Nt(e){return Mt(e.ephemeralPublicKey,e.signature)&&typeof e.salt==`string`&&/^[0-9a-f]{32}$/i.test(e.salt)}var Pt=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 _(`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 _(`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 _(`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 _(`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 _(`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=At();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 _&&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 _(`WS_CONNECTION_UNAVAILABLE`,`Connection closed during E2E authentication`)}assertServerOwner(e,t){if(this.serverPendingKeyExchange.get(e)!==t)throw new _(`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),!Nt(n))return this.pendingKeyExchange.reject(new _(`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 _(`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`||!Mt(n.ephemeralPublicKey,n.signature))return e.reject(new _(`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 _(`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 _(`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 _(`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 _(`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 _(`WS_CONNECTION_UNAVAILABLE`,`Connection closed during E2E authentication`)),void 0),this.pendingResult&&=(clearTimeout(this.pendingResult.timeoutHandle),this.pendingResult.reject(new _(`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 _(`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 Ft=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 jt(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())}},It=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 _(`WS_POLICY_REJECTED`,`DispatchingAuth: unrecognised auth message type "${this.peekType(e)}" — no matching strategy`))),!1)}getReceiveContext(e){return this.resolveSocketStrategy(e)?.getReceiveContext?.(e)}isSocketAuthenticated(e){return this.resolveSocketStrategy(e)?.isSocketAuthenticated?.(e)??!0}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}resolveSocketStrategy(e){return e===void 0?this.resolveSingleStrategy():this.socketStrategy.get(e)??this.resolveSingleStrategy()}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 Lt(e){return`payload`in e}async function Rt(e,t,n){if(e.type!==`response`||e.result===void 0||e.error!==void 0)return;let{ciphertext:r,nonce:i}=await W(n,P(JSON.stringify(e.result)));t.result=M(r),t.e2e={nonce:M(i),v:1}}async function zt(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,P(JSON.stringify(e.results)));t.results=M(r),t.e2e={nonce:M(i),v:1}}async function Bt(e,t,n){if(!Lt(e)||e.payload===void 0)return;let{ciphertext:r,nonce:i}=await W(n,P(JSON.stringify(e.payload)));t.payload=M(r),t.e2e={nonce:M(i),v:1}}async function Vt(e,t,n){if(e.type!==`response`&&e.type!==`broadcast-response`||e.error===void 0)return;let{ciphertext:r,nonce:i}=await W(n,P(JSON.stringify(e.error)));t.error=M(r),t.e2e={nonce:M(i),v:1}}async function Ht(e,t,n,r){if(!Lt(e)||typeof e.payload!=`string`)return;let i=F(await G(n,N(e.payload),r));t.payload=JSON.parse(i)}async function Ut(e,t,n,r){if(e.type!==`response`||typeof e.result!=`string`)return;let i=F(await G(n,N(e.result),r));t.result=JSON.parse(i)}async function Wt(e,t,n,r){if(e.type!==`broadcast-response`||typeof e.results!=`string`)return;let i=F(await G(n,N(e.results),r));t.results=JSON.parse(i)}async function Gt(e,t,n,r){if(e.type!==`response`&&e.type!==`broadcast-response`||typeof e.error!=`string`)return;let i=F(await G(n,N(e.error),r));t.error=JSON.parse(i)}async function Kt(e,t){let n={...e};return await Bt(e,n,t),await Rt(e,n,t),await zt(e,n,t),await Vt(e,n,t),n}async function qt(e,t){if(!e.e2e)return e;let n={...e};delete n.e2e;let r=N(e.e2e.nonce);return await Ht(e,n,t,r),await Ut(e,n,t,r),await Wt(e,n,t,r),await Gt(e,n,t,r),n}function Jt(e){return e.type===`subscription-ack`&&typeof e.ackId==`string`}function Yt(e){let{e2eAuth:t,websocket:n,...r}=e,i=new w({...r,url:`<pre-connected>`,createWebSocket:()=>n,auth:t,autoReconnect:!1,heartbeat:r.heartbeat??!1,messageTransform:async e=>{let n=t.getSessionKey();if(!n||Jt(e))return e;let r=e;if(!r.e2e)throw Error(`Received plaintext message on E2E-encrypted channel — possible injection`);return qt(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 Kt(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 Xt(e){return Yt(e)}function Zt(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 Qt(e,t){let{ciphertext:n,nonce:r}=await W(t,P(JSON.stringify(e)));return{type:`e2e-relay-envelope`,payload:M(n),e2e:{nonce:M(r),v:1}}}async function $t(e,t){let n=N(e.e2e.nonce),r=F(await G(t,N(e.payload),n));return JSON.parse(r)}function en(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 tn=e=>{if(!e||typeof e!=`object`)return!1;let t=e;return t.type===`response`&&typeof t.correlationId==`string`},nn=e=>e.type===`subscribe`||e.type===`unsubscribe`,$=e=>{if(!e||typeof e!=`object`)return!1;let t=e;return t.type===`subscription-ack`&&typeof t.ackId==`string`};function rn(e,t,n,r){if(t(e)||e.type===`response`&&n.has(e.correlationId))return!0;let i=r.getSessionKey();return!i&&(nn(e)||$(e))?!0:!!i}function an(e,t,n,r){if(!r.isFrozen())throw Error(`E2ERelay transport requires a frozen relay control registry`);let{createRelayControlEnvelope:i,isRelayControlEnvelopeMessage:a,isRelayControlBusMessage:o}=en(r),s=e=>{n.delete(e),n.set(e,Date.now()),Q(n)};return{canEncode:t=>rn(t,o,n,e),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&&nn(t)||!r&&$(t))return JSON.stringify(t);if(!r)throw Error(`E2E relay session not established`);let a=await Qt(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),tn(r)&&n.has(r.correlationId))return n.delete(r.correlationId),r;if(!i&&$(r))return r;if(!i)throw Error(`E2E relay session not established`);if(!Zt(r))throw Error(`Received plaintext message on relay E2E channel — possible injection`);return $t(r,i)}}}function on(e,t,n=!1){let r=new Map;return{codec:an(e,n,r,t),reset:()=>r.clear()}}function sn(e){let{e2eAuth:t,registry:n,websocket:r,...i}=e,a=e.debug??!1,o=new Map,s=an(t,a,o,n);a&&console.info(`[E2ERelayTransport] Creating inner transport...`);let c=new w({...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:c.isReady.bind(c),canSend:c.canSend.bind(c)}}function cn(){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 ln(e){if(rt(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 w({url:`<pre-connected>`,createWebSocket:()=>t,auth:e.auth,debug:e.debug,autoReconnect:!1,heartbeat:!1})}else return new tt({websocket:e.websocket,auth:e.auth,debug:e.debug})}export{It as DispatchingAuth,Pt as E2EAuth,Ft as E2ERelayAuth,ot as HmacAuth,st as MAKAIO_LOCAL_CLI_HMAC_IDENTITY_ID,ct as MAKAIO_LOCAL_CLI_PEER_KIND,tt as ServerTransport,w as WebSocketClientTransport,_ as WebSocketConnectionError,Pe as captureHmacIdentitySecretCleanup,ze as clearHmacIdentitySecretsForTesting,Xt as createE2EClientTransport,sn as createE2ERelayClientTransport,on as createE2ERelayCodec,en as createRelayControlHelpers,cn as createRelayControlRegistry,nt as createWebSocketCloseEvent,ln as createWebSocketTransport,Ot as crypto,y as extractSocketErrorMessage,O as registerHmacIdentitySecret,lt as registerMakaioLocalCliHmacIdentity,Le as resolveHmacIdentityAllowedMessageSubjects,k as resolveHmacIdentityAllowedSubscriptionSubjects,Ie as resolveHmacIdentityPeer,Fe as resolveHmacIdentitySecret,Ne 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,matchesFilter as p,matchesSubscription as m,shouldReceiveMessage as h,toSafeDebugLog as g,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 _=e=>{console.info(e)},ie={intervalMs:3e4,timeoutMs:1e4},ae={encode:async e=>JSON.stringify(e),decode:async e=>e};function oe(e){return e===!1?!1:{baseMs:e?.baseMs??te.baseMs,maxMs:e?.maxMs??te.maxMs}}function se(e){if(e===!1)return!1;let t=e?.intervalMs??ie.intervalMs,n=e?.timeoutMs??ie.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 ce(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 le(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 ue(e,t){return{...t?.getReceiveContext?.(),transportName:e}}async function de(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 fe(e,t){let{name:n,debug:r,auth:i,handlers:a}=t,o=null;try{o=await de(e,t)}catch(e){r&&console.error(`[WebSocketClientTransport:${n}] Failed to parse message:`,e);return}if(o===null||!t.isCurrentSession())return;let s=ue(n,i),c=o;le(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 pe(e){let t=e;return typeof t.ping==`function`&&typeof t.terminate==`function`&&typeof t.on==`function`&&typeof t.off==`function`}function me(e){e.unref?.()}function he(e,t,n){if(!pe(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),me(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),me(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 ge(e,t){await Promise.allSettled(e.inFlightMessages),e.getSocket()===t&&e.correlations.rejectAll(e.getSessionFailure()??new n(e.name))}function _e(e,t){let n=n=>{if(t.getSocket()!==e)return;let r=fe(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.readiness===`peer-sync`&&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 ve(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 ye(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,ve(n,e,t)},d=()=>{},f=new Promise((e,t)=>{d=()=>{t(u(n.signal.reason))},n.signal.addEventListener(`abort`,d)});try{let t=be(e,n.signal,()=>{o=e.resetReadyPromise()},t=>{a=t,e.setSocket(t),e.setAuthComplete(!1),t.addEventListener(`close`,c),t.addEventListener(`error`,l),_e(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 be(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 xe(o,e,t)}async function xe(e,t,n){if(await ce(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&&he(e,t.heartbeat,t),t.readiness===`session-established`&&t.resolveReady(),t.debug&&t.debugLog(`[WebSocketClientTransport:${t.name}] Connected to ${t.url}`),t.notifyConnected()}function Se(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 Ce(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 Se(a,e),e.aborted)break;if(o&&a!==null){if(await ge(r,a),e.aborted)break;r.debug&&r.debugLog(`[WebSocketClientTransport:${r.name}] ${new Date().toISOString()} Connection lost, starting reconnect loop (maxMs=${t.maxMs})`),r.notifyDisconnected()}let s=0;for(;!e.aborted;){let a=ne(s,t.baseMs,t.maxMs);r.debug&&r.debugLog(`[WebSocketClientTransport:${r.name}] ${new Date().toISOString()} Reconnecting in ${a}ms (attempt ${s+1})`);let o=new AbortController;if(i(o),await re(a,AbortSignal.any([e,o.signal])),i(null),e.aborted)break;try{if(await ye(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&&r.debugLog(`[WebSocketClientTransport:${r.name}] ${new Date().toISOString()} Connection closed`),r.rejectPendingSubscriptionAcks(Error(`WebSocketClientTransport: disconnected before subscription ack`)))};r.setCloseListener(i),t.addEventListener(`close`,i),await Se(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 we(e,t,n){let r=async()=>{t.getSocket()===e&&(C(e,t),t.auth?.cleanup(),t.setAuthComplete(!1),n(),t.resolveReady(),t.notifyDisconnected(),await ge(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 Te(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&&i.debugLog(`[WebSocketClientTransport:${i.name}] Subscribed to ${e}${c?` with filter`:``}`)}async function Ee(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&&t.debugLog(`[WebSocketClientTransport:${t.name}] Unsubscribed from ${e}`)}var De=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 w(new Promise(()=>{}),AbortSignal.any([t,this.signal]))}if(r.readyState!==1)throw new n(this.name);return r}};async function w(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 Oe(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 ke(e,i,t),ee(t,e.correlations,r);let a=new AbortController,o=ee(t,e.correlations,r).then(e=>(a.abort(),e),e=>{throw a.abort(e),e});return ke(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 ke(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 w(e.codec.encode(n),a),s=t.writable(e.currentSession(),r);s instanceof Promise?await s:s.send(o)}var T=class{name;url;auth;codec;messageTransform;autoReconnectConfig;heartbeatConfig;connectTimeoutMs;readiness;wsFactory;debug;debugLog;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??ae,this.messageTransform=e.messageTransform,this.debug=e.debug??!1,this.debugLog=g(e.debugLog??_),this.autoReconnectConfig=oe(e.autoReconnect),this.heartbeatConfig=se(e.heartbeat),this.connectTimeoutMs=e.connectTimeoutMs??3e4,this.readiness=e.readiness??`peer-sync`,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 ye(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&&this.debugLog(`[WebSocketClientTransport:${this.name}] Disconnected`)}async send(e,t){return Oe({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 Te(e,t,n,r,this.subscriptionDeps())}async unsubscribe(e){await Ee(e,this.subscriptionDeps())}getSubscriptions(){return new Set(this.localSubscriptions.keys())}cancelRequest(e,t){this.correlations.cancel(e,t)}hasLiveWireSession(){return this.socket!==null&&this.socket.readyState===1&&this.authComplete}isReady(){return this.hasLiveWireSession()}canSend(e){return this.hasLiveWireSession()&&(this.codec.canEncode?.(e)??!0)}async reconnect(){if(!this.hasLiveWireSession()){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 Ce(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,debugLog:this.debugLog,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,debugLog:this.debugLog,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,readiness:this.readiness,heartbeat:this.heartbeatConfig,getSocket:()=>this.socket,setSocket:(e,t)=>{this.session?.release(t),e!==null&&(this.session=new De(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?.(),this.socket===e&&this.hasLiveWireSession()&&this.onConnected?.()},notifyDisconnected:()=>{this.onDisconnectedCallback?.(),this.onDisconnected?.()},inFlightMessages:this.inFlightMessages}}defaultWsFactory=async e=>new(await(import(`ws`))).WebSocket(e);wireNoReconnectClose(e){we(e,this.connectionDeps(),()=>{this.reconnectAbort=null})}};function E(e){e.timer!==void 0&&clearTimeout(e.timer)}var Ae=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?(E(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())E(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;E(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`||(E(t),this.pendingBroadcasts.delete(e),t.resolve(t.results),this.debug&&console.info(`[BroadcastAggregator] Server broadcast ${e} finalized with ${t.results.length} results`))}},je=class{clients=new Set;clientsByConnectionId=new Map;authenticatingClients=new Set;clientSubscriptions=new Map;clientSubscriptionState=new Map;clientFilters=new Map;requestOrigins=new Map;debug;subscriptionSubjectRestrictionResolver;requiredSubscriptionFilterResolver;socketAuthChecker;constructor(e={}){this.debug=e.debug??!1,this.subscriptionSubjectRestrictionResolver=e.subscriptionSubjectRestrictionResolver,this.requiredSubscriptionFilterResolver=e.requiredSubscriptionFilterResolver,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,t){this.clients.add(e),t!==void 0&&this.clientsByConnectionId.set(t,e)}removeClient(e){for(let[t,n]of this.clientsByConnectionId)n===e&&this.clientsByConnectionId.delete(t);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}getClientByConnectionId(e){let t=this.clientsByConnectionId.get(e);return t!==void 0&&this.isReadyAndAuthenticated(t)?t:void 0}trackRequestOrigin(e,t){let{correlationId:n}=t;if(this.requestOrigins.has(n))return;let r=this.getRequestRemainingLifetime(t);if(r!==void 0&&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)&&this.isPayloadAllowedForClient(i,e,t)&&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&&m(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 h(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){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.subscriptionSubjectRestrictionResolver||t===void 0)return!0;let n=this.subscriptionSubjectRestrictionResolver(e);return n===null?!0:[...n].some(e=>m(t,e))}isPayloadAllowedForClient(e,t,n){if(!this.requiredSubscriptionFilterResolver||t===void 0)return!0;let r=this.requiredSubscriptionFilterResolver(e)?.[t];return r===void 0||p(n,r)}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 D=new Map;function Me(e){if(typeof e==`object`&&e){for(let t of Object.values(e))Me(t);Object.freeze(e)}return e}function Ne(e){let t=Object.fromEntries(Object.entries(e).map(([e,t])=>[e,Me(structuredClone(t))]));return Object.freeze(t)}function O(e,t){let n=!0;return()=>{n&&(n=!1,D.get(e)===t&&D.delete(e))}}function k(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`);if(`allowedSubjects`in n)throw Error(`registerHmacIdentitySecret no longer accepts allowedSubjects; use allowedMessageSubjects and/or allowedSubscriptionSubjects`);let r=n.peerKind.trim();if(r.length===0)throw Error(`registerHmacIdentitySecret requires a non-empty peerKind`);let i=n.allowedMessageSubjects!==void 0||n.allowedSubscriptionSubjects!==void 0;if(n.requiredSubscriptionFilters!==void 0){for(let e of Object.keys(n.requiredSubscriptionFilters))if(e.includes(`*`))throw Error(`registerHmacIdentitySecret requires exact full subjects for requiredSubscriptionFilters`)}let a={secret:t,peerKind:r,...n.claims===void 0?{}:{claims:n.claims},...i?{allowedMessageSubjects:new Set(n.allowedMessageSubjects??[]),allowedSubscriptionSubjects:new Set(n.allowedSubscriptionSubjects??[])}:{},...n.requiredSubscriptionFilters===void 0?{}:{requiredSubscriptionFilters:Ne(n.requiredSubscriptionFilters)}};return D.set(e,a),O(e,a)}function Pe(e,t,n={}){if(t.length===0)throw Error(`rotateHmacIdentitySecret requires a non-empty secret`);let r=D.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.allowedMessageSubjects===void 0?{}:{allowedMessageSubjects:r.allowedMessageSubjects},...r.allowedSubscriptionSubjects===void 0?{}:{allowedSubscriptionSubjects:r.allowedSubscriptionSubjects},...r.requiredSubscriptionFilters===void 0?{}:{requiredSubscriptionFilters:r.requiredSubscriptionFilters}};return D.set(e,i),O(e,i)}function Fe(e){let t=D.get(e);return t===void 0?void 0:O(e,t)}function Ie(e){return D.get(e)?.secret??null}function Le(e){let t=D.get(e);return t?{kind:t.peerKind,id:e,authenticated:!0,...t.claims===void 0?{}:{claims:t.claims}}:null}function A(e){return D.get(e)?.allowedMessageSubjects??null}function j(e){return D.get(e)?.allowedSubscriptionSubjects??null}function Re(e){return D.get(e)?.requiredSubscriptionFilters??null}function ze(){D.clear()}function Be(e){return e.type===`request`||e.type===`event`||e.type===`broadcast`}function Ve(e){return t(e)&&Object.values(e).every(e=>Array.isArray(e)&&e.every(e=>typeof e==`number`&&Number.isFinite(e)))}function He(e){return e.endsWith(`*`)}function Ue(e,t,n,r){let i={};for(let[a,o]of Object.entries(e))He(a)?t===null||t.has(a)?i[a]=o:n&&console.debug(`[ServerTransport] Dropping wildcard subscription '${a}': not in allowedSubscriptionSubjects for peer '${r}'`):t===null||[...t].some(e=>m(a,e))?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 M(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 We(e,t,n){let r=!0;for(let i of e)await M(i,t,n)||(r=!1);return r}function Ge(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 Ke(e){let t=e?.peer?.id;if(t===void 0)return null;let n=A(t),r=j(t);return n===null&&r===null?null:{peerId:t,allowedMessageSubjects:n,allowedSubscriptionSubjects:r}}function qe(e,t,n,r){if(r===null||!Be(e))return!1;let i=`${e.namespace}.${e.subject}`;return r.allowedMessageSubjects===null||r.allowedMessageSubjects.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 Je(e,t,n){if(!Ve(e.subjects))return n&&console.warn(`[ServerTransport] Malformed ${e.type} message: missing subjects record`),null;if(t===null)return e.subjects;let r=Ue(e.subjects,t.allowedSubscriptionSubjects,n,t.peerId);return r===null&&n&&console.debug(`[ServerTransport] Dropping ${e.type} message: all subjects filtered for peer '${t.peerId}'`),r}async function Ye(e,t,n,r,i){if(e.type!==`subscribe`&&e.type!==`unsubscribe`)return!1;let a=e,o=Je(a,i,n.debug);return o===null||await We(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 Xe(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=u(i)??void 0,o=n.registry.getInterestedClients(a,i.payload,t),s=n.normalizeBroadcastTimeout(i.timeout);return n.broadcastAggregator.startClientBroadcast(t,i,o,n.sendSafely,s),await M(e,n.handlers,{debug:n.debug,receiveContext:r}),!0}async function Ze(e,t,n){if(Ge(e,n,t))return;let r=n.auth?.getReceiveContext?.(t),i=Ke(r);if(!qe(e,t,n,i)){if(e.type===`subscribe`||e.type===`unsubscribe`){await Ye(e,t,n,r,i);return}if(e.type===`broadcast`){await Xe(e,t,n,r);return}e.type===`event`&&n.registry.forwardEventToClients(t,e,n.sendSafely),e.type===`request`&&n.registry.trackRequestOrigin(t,e),await M(e,n.handlers,{debug:n.debug,receiveContext:r})}}function Qe(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 Ze(c,e,t)}catch(e){i&&console.error(`[ServerTransport] Failed to process message:`,e)}}}function $e(e){return typeof e!=`number`||!Number.isFinite(e)||e<=0?5e3:Math.min(e,6e4)}async function et(e,t){let{registry:n,correlations:r,broadcastAggregator:i,handlers:a,auth:o,serverSubscriptions:c,sendSafely:l,debug:u,onConnectionClosed:d}=t;o&&n.addAuthenticating(e);let f=Qe(e,{registry:n,correlations:r,broadcastAggregator:i,handlers:a,auth:o,normalizeBroadcastTimeout:$e,sendSafely:l,debug:u}),p=e=>{f(e.data)},m=()=>{let t=o?.getReceiveContext?.(e)?.connectionId;o?.cleanupSocket(e);let r=n.removeClient(e);t!==void 0&&d(t),e.removeEventListener(`message`,p),e.removeEventListener(`close`,m),e.removeEventListener(`error`,h),i.handleClientDisconnect(e),We(r,a,{debug:u,logContext:`dispatching disconnected client subscriptions`}),u&&console.info(`[ServerTransport] Client disconnected (${n.size} remaining)`)},h=e=>{u&&console.error(`[ServerTransport] Client socket error:`,e)};e.addEventListener(`message`,p),e.addEventListener(`close`,m),e.addEventListener(`error`,h);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,o?.getReceiveContext?.(e)?.connectionId),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 tt(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 nt=class{name;wss;auth;debug;handlers=new Set;registry;serverSubscriptions=new Map;broadcastAggregator;correlations=new r;connectionListener=null;connectionClosedHandlers=new Set;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 je({debug:i,subscriptionSubjectRestrictionResolver:r?e=>{let t=(r.getReceiveContext?.(e))?.peer?.id;return t===void 0?null:j(t)}:void 0,requiredSubscriptionFilterResolver:r?e=>{let t=(r.getReceiveContext?.(e))?.peer?.id;return t===void 0?null:Re(t)}:void 0,socketAuthChecker:r?e=>r.isSocketAuthenticated?.(e)??!0:void 0}),this.broadcastAggregator=new Ae({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=>{et(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,onConnectionClosed:e=>{for(let t of this.connectionClosedHandlers)t(e)}})},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 tt(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}async sendToConnection(e,t){let n=this.registry.getClientByConnectionId(t);return n===void 0?!1:(this.sendToClientSafely(n,JSON.stringify(e)),!0)}onConnectionClosed(e){return this.connectionClosedHandlers.add(e),()=>this.connectionClosedHandlers.delete(e)}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 rt(e,t){let n=new Event(`close`);return Object.defineProperties(n,{code:{value:e??1e3,enumerable:!0},reason:{value:t??``,enumerable:!0}}),n}function it(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(!at(t.websocket))throw TypeError(`WebSocket transport client mode requires a websocket with addEventListener/removeEventListener`);return}if(!ot(t.websocket))throw TypeError(`WebSocket transport server mode requires a websocket with on/off listener methods`)}function at(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 ot(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 st=class{secret;algorithm;challengeTimeout;identityId;resolveSecret;resolvePeer;pendingChallenge;pendingResult;queuedChallengeNonce;queuedResult;clientAuthComplete=!1;serverPendingResponses=new Map;serverAuthenticatedSockets=new Set;serverAuthenticatedPeers=new Map;serverConnectionIds=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),this.serverConnectionIds.set(e,globalThis.crypto.randomUUID())}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:``,connectionId:this.serverConnectionIds.get(e),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.serverConnectionIds.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.serverConnectionIds.clear(),this.serverAuthenticatedSecrets.clear(),this.serverAuthenticatedSockets.clear()}};const ct=`makaio-cli-local:v1`,lt=`makaio-cli-local`;function ut(e){return k(ct,e,{peerKind:lt})}function N(e){let t=Array.from(e,e=>String.fromCharCode(e)).join(``);return btoa(t).replace(/\+/g,`-`).replace(/\//g,`_`).replace(/=/g,``)}function P(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 F(e){return new TextEncoder().encode(e)}function I(e){return new TextDecoder().decode(e)}async function L(e){let t=await crypto.subtle.exportKey(`spki`,e);return N(new Uint8Array(t))}async function R(e){let t=await crypto.subtle.exportKey(`raw`,e);return N(new Uint8Array(t))}async function z(e,t,n=[]){let r=P(e);return crypto.subtle.importKey(`spki`,r,t,!0,n)}async function B(e,t,n=[]){let r=P(e);return crypto.subtle.importKey(`raw`,r,t,!0,n)}async function V(e){let t=await crypto.subtle.exportKey(`pkcs8`,e),n=N(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 H(e,t,n){let r=P(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 dt(e=!0){return crypto.subtle.generateKey(U,e,[`deriveKey`,`deriveBits`])}async function ft(e){return L(e)}async function pt(e){return R(e)}async function mt(e){return B(e,U)}async function ht(e,t=[]){return z(e,U,t)}async function gt(e){return V(e)}async function _t(e){return H(e,U,[`deriveKey`,`deriveBits`])}async function vt(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 yt(e){return crypto.subtle.importKey(`raw`,e,{name:`AES-GCM`},!1,[`encrypt`,`decrypt`])}async function bt(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:F(n)},r,{name:`AES-GCM`,length:256},!1,[`encrypt`,`decrypt`])}const K={name:`ECDSA`,namedCurve:`P-256`};async function xt(e=!0){return crypto.subtle.generateKey(K,e,[`sign`,`verify`])}async function St(e,t){let n=await crypto.subtle.sign({name:`ECDSA`,hash:{name:`SHA-256`}},e,t);return new Uint8Array(n)}async function Ct(e,t,n){return crypto.subtle.verify({name:`ECDSA`,hash:{name:`SHA-256`}},e,t,n)}async function wt(e){return L(e)}async function Tt(e){return z(e,K,[`verify`])}async function Et(e){return R(e)}async function Dt(e){return B(e,K,[`verify`])}async function Ot(e){return V(e)}async function kt(e){return H(e,K,[`sign`])}var At=e({decodeText:()=>I,decrypt:()=>G,deriveSessionKey:()=>bt,deriveSharedSecret:()=>vt,encodeText:()=>F,encrypt:()=>W,exportPrivateKeyPEM:()=>gt,exportPublicKey:()=>ft,exportPublicKeyRaw:()=>pt,exportSigningPrivateKeyPEM:()=>Ot,exportSigningPublicKey:()=>wt,exportSigningPublicKeyRaw:()=>Et,fromBase64Url:()=>P,generateECDHKeyPair:()=>dt,generateSigningKeyPair:()=>xt,importAESKey:()=>yt,importPrivateKeyPEM:()=>_t,importPublicKey:()=>ht,importPublicKeyRaw:()=>mt,importSigningPrivateKeyPEM:()=>kt,importSigningPublicKey:()=>Tt,importSigningPublicKeyRaw:()=>Dt,sign:()=>St,toBase64Url:()=>N,verify:()=>Ct});function jt(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 dt(!0),r=await ft(n.publicKey);return{ephemeralKeyPair:n,ephemeralPublicKey:r,signature:q(await St(e,F(r+t)))}}function Mt(){return q(crypto.getRandomValues(new Uint8Array(16)))}async function Y(e,t,n,r){let i=F(t+r);return Ct(e,jt(n),i)}async function X(e,t,n,r){let i;try{i=await ht(t)}catch(e){throw e instanceof DOMException&&e.name===`DataError`?new v(`WS_AUTHENTICATION_REJECTED`,`Invalid E2E peer public key`,{cause:e}):e}return bt(await vt(e,i),jt(n),r)}async function Nt(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=F(`${i}${a}${o}${s}`),l=new Uint8Array(c).buffer,u=await crypto.subtle.digest(`SHA-256`,l);return q(new Uint8Array(u))}function Pt(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 Ft(e){return Pt(e.ephemeralPublicKey,e.signature)&&typeof e.salt==`string`&&/^[0-9a-f]{32}$/i.test(e.salt)}var It=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=Mt();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),!Ft(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`||!Pt(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 Lt=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 Nt(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())}},Rt=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)}getReceiveContext(e){return this.resolveSocketStrategy(e)?.getReceiveContext?.(e)}isSocketAuthenticated(e){return this.resolveSocketStrategy(e)?.isSocketAuthenticated?.(e)??!0}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}resolveSocketStrategy(e){return e===void 0?this.resolveSingleStrategy():this.socketStrategy.get(e)??this.resolveSingleStrategy()}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 zt(e){return`payload`in e}async function Bt(e,t,n){if(e.type!==`response`||e.result===void 0||e.error!==void 0)return;let{ciphertext:r,nonce:i}=await W(n,F(JSON.stringify(e.result)));t.result=N(r),t.e2e={nonce:N(i),v:1}}async function Vt(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,F(JSON.stringify(e.results)));t.results=N(r),t.e2e={nonce:N(i),v:1}}async function Ht(e,t,n){if(!zt(e)||e.payload===void 0)return;let{ciphertext:r,nonce:i}=await W(n,F(JSON.stringify(e.payload)));t.payload=N(r),t.e2e={nonce:N(i),v:1}}async function Ut(e,t,n){if(e.type!==`response`&&e.type!==`broadcast-response`||e.error===void 0)return;let{ciphertext:r,nonce:i}=await W(n,F(JSON.stringify(e.error)));t.error=N(r),t.e2e={nonce:N(i),v:1}}async function Wt(e,t,n,r){if(!zt(e)||typeof e.payload!=`string`)return;let i=I(await G(n,P(e.payload),r));t.payload=JSON.parse(i)}async function Gt(e,t,n,r){if(e.type!==`response`||typeof e.result!=`string`)return;let i=I(await G(n,P(e.result),r));t.result=JSON.parse(i)}async function Kt(e,t,n,r){if(e.type!==`broadcast-response`||typeof e.results!=`string`)return;let i=I(await G(n,P(e.results),r));t.results=JSON.parse(i)}async function qt(e,t,n,r){if(e.type!==`response`&&e.type!==`broadcast-response`||typeof e.error!=`string`)return;let i=I(await G(n,P(e.error),r));t.error=JSON.parse(i)}async function Jt(e,t){let n={...e};return await Ht(e,n,t),await Bt(e,n,t),await Vt(e,n,t),await Ut(e,n,t),n}async function Yt(e,t){if(!e.e2e)return e;let n={...e};delete n.e2e;let r=P(e.e2e.nonce);return await Wt(e,n,t,r),await Gt(e,n,t,r),await Kt(e,n,t,r),await qt(e,n,t,r),n}function Xt(e){return e.type===`subscription-ack`&&typeof e.ackId==`string`}function Zt(e){let{e2eAuth:t,websocket:n,...r}=e,i=new T({...r,url:`<pre-connected>`,createWebSocket:()=>n,auth:t,autoReconnect:!1,heartbeat:r.heartbeat??!1,messageTransform:async e=>{let n=t.getSessionKey();if(!n||Xt(e))return e;let r=e;if(!r.e2e)throw Error(`Received plaintext message on E2E-encrypted channel — possible injection`);return Yt(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 Jt(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 Qt(e){return Zt(e)}function $t(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 en(e,t){let{ciphertext:n,nonce:r}=await W(t,F(JSON.stringify(e)));return{type:`e2e-relay-envelope`,payload:N(n),e2e:{nonce:N(r),v:1}}}async function tn(e,t){let n=P(e.e2e.nonce),r=I(await G(t,P(e.payload),n));return JSON.parse(r)}function nn(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 rn=e=>{if(!e||typeof e!=`object`)return!1;let t=e;return t.type===`response`&&typeof t.correlationId==`string`},an=e=>e.type===`subscribe`||e.type===`unsubscribe`,$=e=>{if(!e||typeof e!=`object`)return!1;let t=e;return t.type===`subscription-ack`&&typeof t.ackId==`string`};function on(e,t,n,r){if(t(e)||e.type===`response`&&n.has(e.correlationId))return!0;let i=r.getSessionKey();return!i&&(an(e)||$(e))?!0:!!i}function sn(e,t,n,r){if(!r.isFrozen())throw Error(`E2ERelay transport requires a frozen relay control registry`);let{createRelayControlEnvelope:i,isRelayControlEnvelopeMessage:a,isRelayControlBusMessage:o}=nn(r),s=e=>{n.delete(e),n.set(e,Date.now()),Q(n)};return{canEncode:t=>on(t,o,n,e),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&&an(t)||!r&&$(t))return JSON.stringify(t);if(!r)throw Error(`E2E relay session not established`);let a=await en(t,r);return JSON.stringify(a)},decode:async r=>{let i=e.getSessionKey();if(a(r)){let e=r.payload;return t&&t(`[E2ERelayTransport] Decoded relay control envelope: ${e.type} ${e.namespace} ${e.subject}`),e.type===`request`&&s(e.correlationId),e}if(Q(n),rn(r)&&n.has(r.correlationId))return n.delete(r.correlationId),r;if(!i&&$(r))return r;if(!i)throw Error(`E2E relay session not established`);if(!$t(r))throw Error(`Received plaintext message on relay E2E channel — possible injection`);return tn(r,i)}}}function cn(e,t,n=!1,r=_){let i=new Map;return{codec:sn(e,n?g(r):void 0,i,t),reset:()=>i.clear()}}function ln(e){let{e2eAuth:t,registry:n,websocket:r,...i}=e,a=e.debug??!1,o=g(e.debugLog??_),s=new Map,c=sn(t,a?o:void 0,s,n);a&&o(`[E2ERelayTransport] Creating inner transport...`);let l=new T({...i,url:`<pre-connected>`,createWebSocket:()=>r,auth:t,codec:c,autoReconnect:!1,heartbeat:i.heartbeat??!1});return a&&o(`[E2ERelayTransport] Inner transport created`),{name:l.name,connect:async()=>{if(!n.isFrozen())throw Error(`E2ERelayClientTransport: registry must be frozen before connect()`);s.clear();try{await l.connect()}catch(e){throw s.clear(),e}},disconnect:async()=>{s.clear();try{await l.disconnect()}finally{s.clear()}},send:l.send.bind(l),cancelRequest:l.cancelRequest.bind(l),onReceive:(...e)=>(a&&o(`[E2ERelayTransport] onReceive called, delegating to inner transport`),l.onReceive(...e)),subscribe:l.subscribe.bind(l),unsubscribe:l.unsubscribe.bind(l),getSubscriptions:l.getSubscriptions.bind(l),isReady:l.isReady.bind(l),canSend:l.canSend.bind(l)}}function un(){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 dn(e){if(it(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 T({url:`<pre-connected>`,createWebSocket:()=>t,auth:e.auth,debug:e.debug,autoReconnect:!1,heartbeat:!1})}else return new nt({websocket:e.websocket,auth:e.auth,debug:e.debug})}export{Rt as DispatchingAuth,It as E2EAuth,Lt as E2ERelayAuth,st as HmacAuth,ct as MAKAIO_LOCAL_CLI_HMAC_IDENTITY_ID,lt as MAKAIO_LOCAL_CLI_PEER_KIND,nt as ServerTransport,T as WebSocketClientTransport,v as WebSocketConnectionError,Fe as captureHmacIdentitySecretCleanup,ze as clearHmacIdentitySecretsForTesting,Qt as createE2EClientTransport,ln as createE2ERelayClientTransport,cn as createE2ERelayCodec,nn as createRelayControlHelpers,un as createRelayControlRegistry,rt as createWebSocketCloseEvent,dn as createWebSocketTransport,At as crypto,b as extractSocketErrorMessage,k as registerHmacIdentitySecret,ut as registerMakaioLocalCliHmacIdentity,A as resolveHmacIdentityAllowedMessageSubjects,j as resolveHmacIdentityAllowedSubscriptionSubjects,Le as resolveHmacIdentityPeer,Ie as resolveHmacIdentitySecret,Pe as rotateHmacIdentitySecret};
package/dist/package.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "name": "@makaio/framework",
3
- "version": "1.0.0-dev-1790760814648",
3
+ "version": "1.0.0-dev-1790783144258",
4
4
  "type": "module"
5
5
  }