@principal-ai/control-tower-core 0.1.24 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (117) hide show
  1. package/dist/abstractions/AuthAdapter.d.ts +1 -1
  2. package/dist/abstractions/AuthAdapter.d.ts.map +1 -1
  3. package/dist/abstractions/DefaultLockManager.d.ts +2 -2
  4. package/dist/abstractions/DefaultLockManager.d.ts.map +1 -1
  5. package/dist/abstractions/DefaultLockManager.js +7 -8
  6. package/dist/abstractions/DefaultPresenceManager.d.ts +4 -4
  7. package/dist/abstractions/DefaultPresenceManager.d.ts.map +1 -1
  8. package/dist/abstractions/DefaultPresenceManager.js +25 -25
  9. package/dist/abstractions/DefaultRoomManager.d.ts +3 -3
  10. package/dist/abstractions/DefaultRoomManager.d.ts.map +1 -1
  11. package/dist/abstractions/DefaultRoomManager.js +6 -4
  12. package/dist/abstractions/EventEmitter.d.ts.map +1 -1
  13. package/dist/abstractions/LockManager.d.ts +1 -1
  14. package/dist/abstractions/LockManager.d.ts.map +1 -1
  15. package/dist/abstractions/LockManager.js +1 -1
  16. package/dist/abstractions/PresenceExtension.d.ts +2 -2
  17. package/dist/abstractions/PresenceExtension.d.ts.map +1 -1
  18. package/dist/abstractions/PresenceManager.d.ts +1 -1
  19. package/dist/abstractions/PresenceManager.d.ts.map +1 -1
  20. package/dist/abstractions/PresenceManager.js +5 -5
  21. package/dist/abstractions/RoomManager.d.ts +2 -2
  22. package/dist/abstractions/RoomManager.d.ts.map +1 -1
  23. package/dist/abstractions/StorageAdapter.d.ts +4 -4
  24. package/dist/abstractions/StorageAdapter.d.ts.map +1 -1
  25. package/dist/abstractions/TransportAdapter.d.ts +4 -4
  26. package/dist/abstractions/TransportAdapter.d.ts.map +1 -1
  27. package/dist/abstractions/index.d.ts +11 -11
  28. package/dist/abstractions/index.d.ts.map +1 -1
  29. package/dist/abstractions/index.js +9 -9
  30. package/dist/adapters/mock/MockAuthAdapter.d.ts +2 -2
  31. package/dist/adapters/mock/MockAuthAdapter.d.ts.map +1 -1
  32. package/dist/adapters/mock/MockAuthAdapter.js +13 -11
  33. package/dist/adapters/mock/MockRTCDataChannel.d.ts +83 -0
  34. package/dist/adapters/mock/MockRTCDataChannel.d.ts.map +1 -0
  35. package/dist/adapters/mock/MockRTCDataChannel.js +146 -0
  36. package/dist/adapters/mock/MockRTCPeerConnection.d.ts +168 -0
  37. package/dist/adapters/mock/MockRTCPeerConnection.d.ts.map +1 -0
  38. package/dist/adapters/mock/MockRTCPeerConnection.js +449 -0
  39. package/dist/adapters/mock/MockStorageAdapter.d.ts +1 -1
  40. package/dist/adapters/mock/MockStorageAdapter.d.ts.map +1 -1
  41. package/dist/adapters/mock/MockStorageAdapter.js +18 -18
  42. package/dist/adapters/mock/MockTransportAdapter.d.ts +2 -2
  43. package/dist/adapters/mock/MockTransportAdapter.d.ts.map +1 -1
  44. package/dist/adapters/mock/MockTransportAdapter.js +38 -38
  45. package/dist/adapters/mock/index.d.ts +5 -3
  46. package/dist/adapters/mock/index.d.ts.map +1 -1
  47. package/dist/adapters/mock/index.js +10 -5
  48. package/dist/adapters/webrtc/WebRTCSignalingAdapter.d.ts +135 -0
  49. package/dist/adapters/webrtc/WebRTCSignalingAdapter.d.ts.map +1 -0
  50. package/dist/adapters/webrtc/WebRTCSignalingAdapter.js +368 -0
  51. package/dist/adapters/webrtc/index.d.ts +2 -0
  52. package/dist/adapters/webrtc/index.d.ts.map +1 -0
  53. package/dist/adapters/webrtc/index.js +5 -0
  54. package/dist/adapters/websocket/BrowserWebSocketTransportAdapter.d.ts +75 -0
  55. package/dist/adapters/websocket/BrowserWebSocketTransportAdapter.d.ts.map +1 -0
  56. package/dist/adapters/websocket/BrowserWebSocketTransportAdapter.js +231 -0
  57. package/dist/adapters/websocket/WebSocketClientTransportAdapter.d.ts +3 -3
  58. package/dist/adapters/websocket/WebSocketClientTransportAdapter.d.ts.map +1 -1
  59. package/dist/adapters/websocket/WebSocketClientTransportAdapter.js +38 -38
  60. package/dist/adapters/websocket/WebSocketServerTransportAdapter.d.ts +7 -7
  61. package/dist/adapters/websocket/WebSocketServerTransportAdapter.d.ts.map +1 -1
  62. package/dist/adapters/websocket/WebSocketServerTransportAdapter.js +94 -91
  63. package/dist/adapters/websocket/browser.d.ts +2 -0
  64. package/dist/adapters/websocket/browser.d.ts.map +1 -0
  65. package/dist/adapters/websocket/browser.js +6 -0
  66. package/dist/adapters/websocket/index.d.ts +3 -2
  67. package/dist/adapters/websocket/index.d.ts.map +1 -1
  68. package/dist/adapters/websocket/index.js +7 -3
  69. package/dist/adapters/websocket/node.d.ts +3 -0
  70. package/dist/adapters/websocket/node.d.ts.map +1 -0
  71. package/dist/adapters/websocket/node.js +8 -0
  72. package/dist/client/BaseClient.d.ts +6 -6
  73. package/dist/client/BaseClient.d.ts.map +1 -1
  74. package/dist/client/BaseClient.js +86 -72
  75. package/dist/client/ClientBuilder.d.ts +5 -5
  76. package/dist/client/ClientBuilder.d.ts.map +1 -1
  77. package/dist/client/ClientBuilder.js +3 -3
  78. package/dist/client/PresenceClient.d.ts +4 -4
  79. package/dist/client/PresenceClient.d.ts.map +1 -1
  80. package/dist/client/PresenceClient.js +30 -30
  81. package/dist/client/index.d.ts +3 -3
  82. package/dist/client/index.d.ts.map +1 -1
  83. package/dist/index.d.ts +7 -6
  84. package/dist/index.d.ts.map +1 -1
  85. package/dist/index.js +27 -19
  86. package/dist/index.js.map +27 -23
  87. package/dist/index.mjs +1590 -558
  88. package/dist/index.mjs.map +27 -23
  89. package/dist/server/BaseServer.d.ts +13 -13
  90. package/dist/server/BaseServer.d.ts.map +1 -1
  91. package/dist/server/BaseServer.js +224 -143
  92. package/dist/server/ExperimentalAPI.d.ts +7 -7
  93. package/dist/server/ExperimentalAPI.d.ts.map +1 -1
  94. package/dist/server/ExperimentalAPI.js +22 -22
  95. package/dist/server/ServerBuilder.d.ts +11 -11
  96. package/dist/server/ServerBuilder.d.ts.map +1 -1
  97. package/dist/server/ServerBuilder.js +10 -10
  98. package/dist/server/index.d.ts +3 -3
  99. package/dist/server/index.d.ts.map +1 -1
  100. package/dist/server/index.js +3 -3
  101. package/dist/types/auth.d.ts.map +1 -1
  102. package/dist/types/events.d.ts +10 -10
  103. package/dist/types/events.d.ts.map +1 -1
  104. package/dist/types/experimental.d.ts +2 -2
  105. package/dist/types/experimental.d.ts.map +1 -1
  106. package/dist/types/experimental.js +1 -1
  107. package/dist/types/index.d.ts +7 -7
  108. package/dist/types/index.d.ts.map +1 -1
  109. package/dist/types/index.js +2 -2
  110. package/dist/types/lock.d.ts +2 -2
  111. package/dist/types/lock.d.ts.map +1 -1
  112. package/dist/types/presence.d.ts +3 -3
  113. package/dist/types/presence.d.ts.map +1 -1
  114. package/dist/types/room.d.ts +4 -4
  115. package/dist/types/room.d.ts.map +1 -1
  116. package/dist/types/room.js +2 -2
  117. package/package.json +15 -7
package/dist/index.mjs CHANGED
@@ -1345,7 +1345,7 @@ var require_event_target = __commonJS((exports, module) => {
1345
1345
  var kType = Symbol("kType");
1346
1346
  var kWasClean = Symbol("kWasClean");
1347
1347
 
1348
- class Event2 {
1348
+ class Event {
1349
1349
  constructor(type) {
1350
1350
  this[kTarget] = null;
1351
1351
  this[kType] = type;
@@ -1357,10 +1357,10 @@ var require_event_target = __commonJS((exports, module) => {
1357
1357
  return this[kType];
1358
1358
  }
1359
1359
  }
1360
- Object.defineProperty(Event2.prototype, "target", { enumerable: true });
1361
- Object.defineProperty(Event2.prototype, "type", { enumerable: true });
1360
+ Object.defineProperty(Event.prototype, "target", { enumerable: true });
1361
+ Object.defineProperty(Event.prototype, "type", { enumerable: true });
1362
1362
 
1363
- class CloseEvent extends Event2 {
1363
+ class CloseEvent extends Event {
1364
1364
  constructor(type, options = {}) {
1365
1365
  super(type);
1366
1366
  this[kCode] = options.code === undefined ? 0 : options.code;
@@ -1381,7 +1381,7 @@ var require_event_target = __commonJS((exports, module) => {
1381
1381
  Object.defineProperty(CloseEvent.prototype, "reason", { enumerable: true });
1382
1382
  Object.defineProperty(CloseEvent.prototype, "wasClean", { enumerable: true });
1383
1383
 
1384
- class ErrorEvent extends Event2 {
1384
+ class ErrorEvent extends Event {
1385
1385
  constructor(type, options = {}) {
1386
1386
  super(type);
1387
1387
  this[kError] = options.error === undefined ? null : options.error;
@@ -1397,7 +1397,7 @@ var require_event_target = __commonJS((exports, module) => {
1397
1397
  Object.defineProperty(ErrorEvent.prototype, "error", { enumerable: true });
1398
1398
  Object.defineProperty(ErrorEvent.prototype, "message", { enumerable: true });
1399
1399
 
1400
- class MessageEvent extends Event2 {
1400
+ class MessageEvent extends Event {
1401
1401
  constructor(type, options = {}) {
1402
1402
  super(type);
1403
1403
  this[kData] = options.data === undefined ? null : options.data;
@@ -1444,7 +1444,7 @@ var require_event_target = __commonJS((exports, module) => {
1444
1444
  };
1445
1445
  } else if (type === "open") {
1446
1446
  wrapper = function onOpen() {
1447
- const event = new Event2("open");
1447
+ const event = new Event("open");
1448
1448
  event[kTarget] = this;
1449
1449
  callListener(handler, this, event);
1450
1450
  };
@@ -1471,7 +1471,7 @@ var require_event_target = __commonJS((exports, module) => {
1471
1471
  module.exports = {
1472
1472
  CloseEvent,
1473
1473
  ErrorEvent,
1474
- Event: Event2,
1474
+ Event,
1475
1475
  EventTarget,
1476
1476
  MessageEvent
1477
1477
  };
@@ -1684,7 +1684,7 @@ var require_websocket = __commonJS((exports, module) => {
1684
1684
  var readyStates = ["CONNECTING", "OPEN", "CLOSING", "CLOSED"];
1685
1685
  var subprotocolRegex = /^[!#$%&'*+\-.0-9A-Z^_`|a-z~]+$/;
1686
1686
 
1687
- class WebSocket extends EventEmitter {
1687
+ class WebSocket2 extends EventEmitter {
1688
1688
  constructor(address, protocols, options) {
1689
1689
  super();
1690
1690
  this._binaryType = BINARY_TYPES[0];
@@ -1697,7 +1697,7 @@ var require_websocket = __commonJS((exports, module) => {
1697
1697
  this._extensions = {};
1698
1698
  this._paused = false;
1699
1699
  this._protocol = "";
1700
- this._readyState = WebSocket.CONNECTING;
1700
+ this._readyState = WebSocket2.CONNECTING;
1701
1701
  this._receiver = null;
1702
1702
  this._sender = null;
1703
1703
  this._socket = null;
@@ -1796,12 +1796,12 @@ var require_websocket = __commonJS((exports, module) => {
1796
1796
  socket.on("data", socketOnData);
1797
1797
  socket.on("end", socketOnEnd);
1798
1798
  socket.on("error", socketOnError);
1799
- this._readyState = WebSocket.OPEN;
1799
+ this._readyState = WebSocket2.OPEN;
1800
1800
  this.emit("open");
1801
1801
  }
1802
1802
  emitClose() {
1803
1803
  if (!this._socket) {
1804
- this._readyState = WebSocket.CLOSED;
1804
+ this._readyState = WebSocket2.CLOSED;
1805
1805
  this.emit("close", this._closeCode, this._closeMessage);
1806
1806
  return;
1807
1807
  }
@@ -1809,24 +1809,24 @@ var require_websocket = __commonJS((exports, module) => {
1809
1809
  this._extensions[PerMessageDeflate.extensionName].cleanup();
1810
1810
  }
1811
1811
  this._receiver.removeAllListeners();
1812
- this._readyState = WebSocket.CLOSED;
1812
+ this._readyState = WebSocket2.CLOSED;
1813
1813
  this.emit("close", this._closeCode, this._closeMessage);
1814
1814
  }
1815
1815
  close(code, data) {
1816
- if (this.readyState === WebSocket.CLOSED)
1816
+ if (this.readyState === WebSocket2.CLOSED)
1817
1817
  return;
1818
- if (this.readyState === WebSocket.CONNECTING) {
1818
+ if (this.readyState === WebSocket2.CONNECTING) {
1819
1819
  const msg = "WebSocket was closed before the connection was established";
1820
1820
  abortHandshake(this, this._req, msg);
1821
1821
  return;
1822
1822
  }
1823
- if (this.readyState === WebSocket.CLOSING) {
1823
+ if (this.readyState === WebSocket2.CLOSING) {
1824
1824
  if (this._closeFrameSent && (this._closeFrameReceived || this._receiver._writableState.errorEmitted)) {
1825
1825
  this._socket.end();
1826
1826
  }
1827
1827
  return;
1828
1828
  }
1829
- this._readyState = WebSocket.CLOSING;
1829
+ this._readyState = WebSocket2.CLOSING;
1830
1830
  this._sender.close(code, data, !this._isServer, (err) => {
1831
1831
  if (err)
1832
1832
  return;
@@ -1838,14 +1838,14 @@ var require_websocket = __commonJS((exports, module) => {
1838
1838
  setCloseTimer(this);
1839
1839
  }
1840
1840
  pause() {
1841
- if (this.readyState === WebSocket.CONNECTING || this.readyState === WebSocket.CLOSED) {
1841
+ if (this.readyState === WebSocket2.CONNECTING || this.readyState === WebSocket2.CLOSED) {
1842
1842
  return;
1843
1843
  }
1844
1844
  this._paused = true;
1845
1845
  this._socket.pause();
1846
1846
  }
1847
1847
  ping(data, mask, cb) {
1848
- if (this.readyState === WebSocket.CONNECTING) {
1848
+ if (this.readyState === WebSocket2.CONNECTING) {
1849
1849
  throw new Error("WebSocket is not open: readyState 0 (CONNECTING)");
1850
1850
  }
1851
1851
  if (typeof data === "function") {
@@ -1857,7 +1857,7 @@ var require_websocket = __commonJS((exports, module) => {
1857
1857
  }
1858
1858
  if (typeof data === "number")
1859
1859
  data = data.toString();
1860
- if (this.readyState !== WebSocket.OPEN) {
1860
+ if (this.readyState !== WebSocket2.OPEN) {
1861
1861
  sendAfterClose(this, data, cb);
1862
1862
  return;
1863
1863
  }
@@ -1866,7 +1866,7 @@ var require_websocket = __commonJS((exports, module) => {
1866
1866
  this._sender.ping(data || EMPTY_BUFFER, mask, cb);
1867
1867
  }
1868
1868
  pong(data, mask, cb) {
1869
- if (this.readyState === WebSocket.CONNECTING) {
1869
+ if (this.readyState === WebSocket2.CONNECTING) {
1870
1870
  throw new Error("WebSocket is not open: readyState 0 (CONNECTING)");
1871
1871
  }
1872
1872
  if (typeof data === "function") {
@@ -1878,7 +1878,7 @@ var require_websocket = __commonJS((exports, module) => {
1878
1878
  }
1879
1879
  if (typeof data === "number")
1880
1880
  data = data.toString();
1881
- if (this.readyState !== WebSocket.OPEN) {
1881
+ if (this.readyState !== WebSocket2.OPEN) {
1882
1882
  sendAfterClose(this, data, cb);
1883
1883
  return;
1884
1884
  }
@@ -1887,7 +1887,7 @@ var require_websocket = __commonJS((exports, module) => {
1887
1887
  this._sender.pong(data || EMPTY_BUFFER, mask, cb);
1888
1888
  }
1889
1889
  resume() {
1890
- if (this.readyState === WebSocket.CONNECTING || this.readyState === WebSocket.CLOSED) {
1890
+ if (this.readyState === WebSocket2.CONNECTING || this.readyState === WebSocket2.CLOSED) {
1891
1891
  return;
1892
1892
  }
1893
1893
  this._paused = false;
@@ -1895,7 +1895,7 @@ var require_websocket = __commonJS((exports, module) => {
1895
1895
  this._socket.resume();
1896
1896
  }
1897
1897
  send(data, options, cb) {
1898
- if (this.readyState === WebSocket.CONNECTING) {
1898
+ if (this.readyState === WebSocket2.CONNECTING) {
1899
1899
  throw new Error("WebSocket is not open: readyState 0 (CONNECTING)");
1900
1900
  }
1901
1901
  if (typeof options === "function") {
@@ -1904,7 +1904,7 @@ var require_websocket = __commonJS((exports, module) => {
1904
1904
  }
1905
1905
  if (typeof data === "number")
1906
1906
  data = data.toString();
1907
- if (this.readyState !== WebSocket.OPEN) {
1907
+ if (this.readyState !== WebSocket2.OPEN) {
1908
1908
  sendAfterClose(this, data, cb);
1909
1909
  return;
1910
1910
  }
@@ -1921,48 +1921,48 @@ var require_websocket = __commonJS((exports, module) => {
1921
1921
  this._sender.send(data || EMPTY_BUFFER, opts, cb);
1922
1922
  }
1923
1923
  terminate() {
1924
- if (this.readyState === WebSocket.CLOSED)
1924
+ if (this.readyState === WebSocket2.CLOSED)
1925
1925
  return;
1926
- if (this.readyState === WebSocket.CONNECTING) {
1926
+ if (this.readyState === WebSocket2.CONNECTING) {
1927
1927
  const msg = "WebSocket was closed before the connection was established";
1928
1928
  abortHandshake(this, this._req, msg);
1929
1929
  return;
1930
1930
  }
1931
1931
  if (this._socket) {
1932
- this._readyState = WebSocket.CLOSING;
1932
+ this._readyState = WebSocket2.CLOSING;
1933
1933
  this._socket.destroy();
1934
1934
  }
1935
1935
  }
1936
1936
  }
1937
- Object.defineProperty(WebSocket, "CONNECTING", {
1937
+ Object.defineProperty(WebSocket2, "CONNECTING", {
1938
1938
  enumerable: true,
1939
1939
  value: readyStates.indexOf("CONNECTING")
1940
1940
  });
1941
- Object.defineProperty(WebSocket.prototype, "CONNECTING", {
1941
+ Object.defineProperty(WebSocket2.prototype, "CONNECTING", {
1942
1942
  enumerable: true,
1943
1943
  value: readyStates.indexOf("CONNECTING")
1944
1944
  });
1945
- Object.defineProperty(WebSocket, "OPEN", {
1945
+ Object.defineProperty(WebSocket2, "OPEN", {
1946
1946
  enumerable: true,
1947
1947
  value: readyStates.indexOf("OPEN")
1948
1948
  });
1949
- Object.defineProperty(WebSocket.prototype, "OPEN", {
1949
+ Object.defineProperty(WebSocket2.prototype, "OPEN", {
1950
1950
  enumerable: true,
1951
1951
  value: readyStates.indexOf("OPEN")
1952
1952
  });
1953
- Object.defineProperty(WebSocket, "CLOSING", {
1953
+ Object.defineProperty(WebSocket2, "CLOSING", {
1954
1954
  enumerable: true,
1955
1955
  value: readyStates.indexOf("CLOSING")
1956
1956
  });
1957
- Object.defineProperty(WebSocket.prototype, "CLOSING", {
1957
+ Object.defineProperty(WebSocket2.prototype, "CLOSING", {
1958
1958
  enumerable: true,
1959
1959
  value: readyStates.indexOf("CLOSING")
1960
1960
  });
1961
- Object.defineProperty(WebSocket, "CLOSED", {
1961
+ Object.defineProperty(WebSocket2, "CLOSED", {
1962
1962
  enumerable: true,
1963
1963
  value: readyStates.indexOf("CLOSED")
1964
1964
  });
1965
- Object.defineProperty(WebSocket.prototype, "CLOSED", {
1965
+ Object.defineProperty(WebSocket2.prototype, "CLOSED", {
1966
1966
  enumerable: true,
1967
1967
  value: readyStates.indexOf("CLOSED")
1968
1968
  });
@@ -1975,10 +1975,10 @@ var require_websocket = __commonJS((exports, module) => {
1975
1975
  "readyState",
1976
1976
  "url"
1977
1977
  ].forEach((property) => {
1978
- Object.defineProperty(WebSocket.prototype, property, { enumerable: true });
1978
+ Object.defineProperty(WebSocket2.prototype, property, { enumerable: true });
1979
1979
  });
1980
1980
  ["open", "error", "close", "message"].forEach((method) => {
1981
- Object.defineProperty(WebSocket.prototype, `on${method}`, {
1981
+ Object.defineProperty(WebSocket2.prototype, `on${method}`, {
1982
1982
  enumerable: true,
1983
1983
  get() {
1984
1984
  for (const listener of this.listeners(method)) {
@@ -2002,9 +2002,9 @@ var require_websocket = __commonJS((exports, module) => {
2002
2002
  }
2003
2003
  });
2004
2004
  });
2005
- WebSocket.prototype.addEventListener = addEventListener;
2006
- WebSocket.prototype.removeEventListener = removeEventListener;
2007
- module.exports = WebSocket;
2005
+ WebSocket2.prototype.addEventListener = addEventListener;
2006
+ WebSocket2.prototype.removeEventListener = removeEventListener;
2007
+ module.exports = WebSocket2;
2008
2008
  function initAsClient(websocket, address, protocols, options) {
2009
2009
  const opts = {
2010
2010
  allowSynchronousEvents: true,
@@ -2180,7 +2180,7 @@ var require_websocket = __commonJS((exports, module) => {
2180
2180
  });
2181
2181
  req.on("upgrade", (res, socket, head) => {
2182
2182
  websocket.emit("upgrade", res);
2183
- if (websocket.readyState !== WebSocket.CONNECTING)
2183
+ if (websocket.readyState !== WebSocket2.CONNECTING)
2184
2184
  return;
2185
2185
  req = websocket._req = null;
2186
2186
  const upgrade = res.headers.upgrade;
@@ -2254,7 +2254,7 @@ var require_websocket = __commonJS((exports, module) => {
2254
2254
  }
2255
2255
  }
2256
2256
  function emitErrorAndClose(websocket, err) {
2257
- websocket._readyState = WebSocket.CLOSING;
2257
+ websocket._readyState = WebSocket2.CLOSING;
2258
2258
  websocket._errorEmitted = true;
2259
2259
  websocket.emit("error", err);
2260
2260
  websocket.emitClose();
@@ -2271,7 +2271,7 @@ var require_websocket = __commonJS((exports, module) => {
2271
2271
  return tls.connect(options);
2272
2272
  }
2273
2273
  function abortHandshake(websocket, stream, message) {
2274
- websocket._readyState = WebSocket.CLOSING;
2274
+ websocket._readyState = WebSocket2.CLOSING;
2275
2275
  const err = new Error(message);
2276
2276
  Error.captureStackTrace(err, abortHandshake);
2277
2277
  if (stream.setHeader) {
@@ -2351,10 +2351,10 @@ var require_websocket = __commonJS((exports, module) => {
2351
2351
  }
2352
2352
  function senderOnError(err) {
2353
2353
  const websocket = this[kWebSocket];
2354
- if (websocket.readyState === WebSocket.CLOSED)
2354
+ if (websocket.readyState === WebSocket2.CLOSED)
2355
2355
  return;
2356
- if (websocket.readyState === WebSocket.OPEN) {
2357
- websocket._readyState = WebSocket.CLOSING;
2356
+ if (websocket.readyState === WebSocket2.OPEN) {
2357
+ websocket._readyState = WebSocket2.CLOSING;
2358
2358
  setCloseTimer(websocket);
2359
2359
  }
2360
2360
  this._socket.end();
@@ -2371,7 +2371,7 @@ var require_websocket = __commonJS((exports, module) => {
2371
2371
  this.removeListener("close", socketOnClose);
2372
2372
  this.removeListener("data", socketOnData);
2373
2373
  this.removeListener("end", socketOnEnd);
2374
- websocket._readyState = WebSocket.CLOSING;
2374
+ websocket._readyState = WebSocket2.CLOSING;
2375
2375
  let chunk;
2376
2376
  if (!this._readableState.endEmitted && !websocket._closeFrameReceived && !websocket._receiver._writableState.errorEmitted && (chunk = websocket._socket.read()) !== null) {
2377
2377
  websocket._receiver.write(chunk);
@@ -2393,7 +2393,7 @@ var require_websocket = __commonJS((exports, module) => {
2393
2393
  }
2394
2394
  function socketOnEnd() {
2395
2395
  const websocket = this[kWebSocket];
2396
- websocket._readyState = WebSocket.CLOSING;
2396
+ websocket._readyState = WebSocket2.CLOSING;
2397
2397
  websocket._receiver.end();
2398
2398
  this.end();
2399
2399
  }
@@ -2402,7 +2402,7 @@ var require_websocket = __commonJS((exports, module) => {
2402
2402
  this.removeListener("error", socketOnError);
2403
2403
  this.on("error", NOOP);
2404
2404
  if (websocket) {
2405
- websocket._readyState = WebSocket.CLOSING;
2405
+ websocket._readyState = WebSocket2.CLOSING;
2406
2406
  this.destroy();
2407
2407
  }
2408
2408
  }
@@ -2410,7 +2410,7 @@ var require_websocket = __commonJS((exports, module) => {
2410
2410
 
2411
2411
  // node_modules/ws/lib/stream.js
2412
2412
  var require_stream = __commonJS((exports, module) => {
2413
- var WebSocket = require_websocket();
2413
+ var WebSocket2 = require_websocket();
2414
2414
  var { Duplex } = __require("stream");
2415
2415
  function emitClose(stream) {
2416
2416
  stream.emit("close");
@@ -2565,7 +2565,7 @@ var require_websocket_server = __commonJS((exports, module) => {
2565
2565
  var extension = require_extension();
2566
2566
  var PerMessageDeflate = require_permessage_deflate();
2567
2567
  var subprotocol = require_subprotocol();
2568
- var WebSocket = require_websocket();
2568
+ var WebSocket2 = require_websocket();
2569
2569
  var { GUID, kWebSocket } = require_constants();
2570
2570
  var keyRegex = /^[+/0-9A-Za-z]{22}==$/;
2571
2571
  var RUNNING = 0;
@@ -2590,7 +2590,7 @@ var require_websocket_server = __commonJS((exports, module) => {
2590
2590
  host: null,
2591
2591
  path: null,
2592
2592
  port: null,
2593
- WebSocket,
2593
+ WebSocket: WebSocket2,
2594
2594
  ...options
2595
2595
  };
2596
2596
  if (options.port == null && !options.server && !options.noServer || options.port != null && (options.server || options.noServer) || options.server && options.noServer) {
@@ -2856,103 +2856,6 @@ var require_websocket_server = __commonJS((exports, module) => {
2856
2856
  }
2857
2857
  }
2858
2858
  });
2859
- // src/types/room.ts
2860
- function serializeRoomState(state) {
2861
- return {
2862
- room: state.room,
2863
- users: Object.fromEntries(state.users),
2864
- eventHistory: state.eventHistory,
2865
- locks: Object.fromEntries(state.locks)
2866
- };
2867
- }
2868
- function deserializeRoomState(serialized) {
2869
- return {
2870
- room: serialized.room,
2871
- users: new Map(Object.entries(serialized.users)),
2872
- eventHistory: serialized.eventHistory,
2873
- locks: new Map(Object.entries(serialized.locks))
2874
- };
2875
- }
2876
- // src/types/experimental.ts
2877
- class ExperimentalFeatureError extends Error {
2878
- feature;
2879
- configKey;
2880
- constructor(feature, configKey) {
2881
- super(`Experimental feature '${feature}' is not enabled.
2882
-
2883
- ` + `To enable, set '${String(configKey)}: true' in your server configuration:
2884
-
2885
- ` + ` const server = new ServerBuilder()
2886
- ` + ` .withExperimentalFeatures({ ${String(configKey)}: true })
2887
- ` + ` .build();
2888
-
2889
- ` + `⚠️ WARNING: Experimental APIs are for development only.
2890
- ` + `For production use, submit a feature request:
2891
- ` + `https://github.com/your-org/control-tower-core/issues/new
2892
-
2893
- ` + `See docs/EXPERIMENTAL_BROADCAST.md for details.`);
2894
- this.feature = feature;
2895
- this.configKey = configKey;
2896
- this.name = "ExperimentalFeatureError";
2897
- }
2898
- }
2899
- // src/abstractions/EventEmitter.ts
2900
- class TypedEventEmitter {
2901
- listeners = new Map;
2902
- onceListeners = new Map;
2903
- on(event, listener) {
2904
- if (!this.listeners.has(event)) {
2905
- this.listeners.set(event, new Set);
2906
- }
2907
- this.listeners.get(event).add(listener);
2908
- return () => this.off(event, listener);
2909
- }
2910
- once(event, listener) {
2911
- if (!this.onceListeners.has(event)) {
2912
- this.onceListeners.set(event, new Set);
2913
- }
2914
- this.onceListeners.get(event).add(listener);
2915
- return () => this.off(event, listener);
2916
- }
2917
- off(event, listener) {
2918
- this.listeners.get(event)?.delete(listener);
2919
- this.onceListeners.get(event)?.delete(listener);
2920
- }
2921
- async emit(event, data) {
2922
- const listeners = this.listeners.get(event);
2923
- const onceListeners = this.onceListeners.get(event);
2924
- if (onceListeners) {
2925
- const listenersToCall = Array.from(onceListeners);
2926
- this.onceListeners.delete(event);
2927
- for (const listener of listenersToCall) {
2928
- await listener(data);
2929
- }
2930
- }
2931
- if (listeners) {
2932
- for (const listener of Array.from(listeners)) {
2933
- await listener(data);
2934
- }
2935
- }
2936
- }
2937
- removeAllListeners(event) {
2938
- if (event) {
2939
- this.listeners.delete(event);
2940
- this.onceListeners.delete(event);
2941
- } else {
2942
- this.listeners.clear();
2943
- this.onceListeners.clear();
2944
- }
2945
- }
2946
- listenerCount(event) {
2947
- const regular = this.listeners.get(event)?.size ?? 0;
2948
- const once = this.onceListeners.get(event)?.size ?? 0;
2949
- return regular + once;
2950
- }
2951
- }
2952
- // src/abstractions/RoomManager.ts
2953
- class RoomManager {
2954
- rooms = new Map;
2955
- }
2956
2859
  // src/abstractions/LockManager.ts
2957
2860
  class LockManager {
2958
2861
  lockState = {
@@ -2961,98 +2864,18 @@ class LockManager {
2961
2864
  userLocks: new Map
2962
2865
  };
2963
2866
  }
2964
- // src/abstractions/DefaultRoomManager.ts
2965
- class DefaultRoomManager extends RoomManager {
2966
- async createRoom(id, config) {
2967
- const room = {
2968
- id,
2969
- name: config.name || id,
2970
- createdAt: Date.now(),
2971
- maxUsers: config.maxUsers,
2972
- maxHistory: config.maxHistory,
2973
- permissions: config.permissions,
2974
- metadata: config.metadata || {}
2975
- };
2976
- const roomState = {
2977
- room,
2978
- users: new Map,
2979
- eventHistory: [],
2980
- locks: new Map
2981
- };
2982
- this.rooms.set(id, roomState);
2983
- return room;
2984
- }
2985
- async deleteRoom(id) {
2986
- this.rooms.delete(id);
2987
- }
2988
- async joinRoom(roomId, user) {
2989
- const roomState = this.rooms.get(roomId);
2990
- if (!roomState) {
2991
- throw new Error(`Room ${roomId} not found`);
2992
- }
2993
- if (roomState.room.maxUsers && roomState.users.size >= roomState.room.maxUsers) {
2994
- throw new Error(`Room ${roomId} is full`);
2995
- }
2996
- roomState.users.set(user.id, user);
2997
- }
2998
- async leaveRoom(roomId, userId) {
2999
- const roomState = this.rooms.get(roomId);
3000
- if (!roomState) {
3001
- return;
3002
- }
3003
- roomState.users.delete(userId);
3004
- }
3005
- async broadcastToRoom(roomId, event, _excludeUserId) {
3006
- const roomState = this.rooms.get(roomId);
3007
- if (!roomState) {
3008
- throw new Error(`Room ${roomId} not found`);
3009
- }
3010
- await this.addEventToHistory(roomId, event);
3011
- }
3012
- async getRoomState(roomId) {
3013
- return this.rooms.get(roomId) || null;
3014
- }
3015
- async getUsersInRoom(roomId) {
3016
- const roomState = this.rooms.get(roomId);
3017
- if (!roomState) {
3018
- return [];
3019
- }
3020
- return Array.from(roomState.users.values());
3021
- }
3022
- async addEventToHistory(roomId, event) {
3023
- const roomState = this.rooms.get(roomId);
3024
- if (!roomState) {
3025
- throw new Error(`Room ${roomId} not found`);
3026
- }
3027
- roomState.eventHistory.push(event);
3028
- if (roomState.room.maxHistory && roomState.eventHistory.length > roomState.room.maxHistory) {
3029
- roomState.eventHistory = roomState.eventHistory.slice(-roomState.room.maxHistory);
3030
- }
3031
- }
3032
- async getEventHistory(roomId, limit) {
3033
- const roomState = this.rooms.get(roomId);
3034
- if (!roomState) {
3035
- return [];
3036
- }
3037
- const history = roomState.eventHistory;
3038
- return limit ? history.slice(-limit) : history;
3039
- }
3040
- async updateUserStatus(roomId, userId, status) {
3041
- const roomState = this.rooms.get(roomId);
3042
- if (!roomState) {
3043
- throw new Error(`Room ${roomId} not found`);
3044
- }
3045
- const user = roomState.users.get(userId);
3046
- if (user) {
3047
- user.status = status;
3048
- user.lastActivity = Date.now();
3049
- }
3050
- }
3051
- }
2867
+
3052
2868
  // src/abstractions/DefaultLockManager.ts
3053
2869
  class DefaultLockManager extends LockManager {
3054
2870
  async acquireLock(userId, username, request) {
3055
- const { path, type = "file", priority = "normal", ttl, branch, metadata } = request;
2871
+ const {
2872
+ path,
2873
+ type = "file",
2874
+ priority = "normal",
2875
+ ttl,
2876
+ branch,
2877
+ metadata
2878
+ } = request;
3056
2879
  const userLocks = this.lockState.userLocks.get(userId) || new Set;
3057
2880
  if (userLocks.has(path)) {
3058
2881
  throw new Error(`User ${username} already has a lock on ${path}`);
@@ -3225,6 +3048,7 @@ class PresenceManager {
3225
3048
  return now - device.lastActivity > timeout;
3226
3049
  }
3227
3050
  }
3051
+
3228
3052
  // src/abstractions/DefaultPresenceManager.ts
3229
3053
  class DefaultPresenceManager extends PresenceManager {
3230
3054
  userPresences = new Map;
@@ -3550,211 +3374,765 @@ class DefaultPresenceManager extends PresenceManager {
3550
3374
  return this.userPresences.size + this.gracePeriodEntries.size;
3551
3375
  }
3552
3376
  }
3553
- // src/adapters/mock/MockTransportAdapter.ts
3554
- class MockTransportAdapter {
3555
- state = "disconnected";
3556
- messageHandlers = new Set;
3557
- errorHandlers = new Set;
3558
- closeHandlers = new Set;
3559
- messageQueue = [];
3560
- simulateLatency = 0;
3561
- shouldFailConnection = false;
3562
- connectedUrl = null;
3563
- connectionAttempts = 0;
3564
- constructor(options) {
3565
- this.simulateLatency = options?.simulateLatency ?? 0;
3566
- this.shouldFailConnection = options?.shouldFailConnection ?? false;
3377
+ // src/abstractions/RoomManager.ts
3378
+ class RoomManager {
3379
+ rooms = new Map;
3380
+ }
3381
+
3382
+ // src/abstractions/DefaultRoomManager.ts
3383
+ class DefaultRoomManager extends RoomManager {
3384
+ async createRoom(id, config) {
3385
+ const room = {
3386
+ id,
3387
+ name: config.name || id,
3388
+ createdAt: Date.now(),
3389
+ maxUsers: config.maxUsers,
3390
+ maxHistory: config.maxHistory,
3391
+ permissions: config.permissions,
3392
+ metadata: config.metadata || {}
3393
+ };
3394
+ const roomState = {
3395
+ room,
3396
+ users: new Map,
3397
+ eventHistory: [],
3398
+ locks: new Map
3399
+ };
3400
+ this.rooms.set(id, roomState);
3401
+ return room;
3567
3402
  }
3568
- async connect(url, _options) {
3569
- this.connectionAttempts++;
3570
- if (this.shouldFailConnection) {
3571
- this.state = "disconnected";
3572
- const error = new Error("Mock connection failed");
3573
- this.errorHandlers.forEach((handler) => handler(error));
3574
- throw error;
3403
+ async deleteRoom(id) {
3404
+ this.rooms.delete(id);
3405
+ }
3406
+ async joinRoom(roomId, user) {
3407
+ const roomState = this.rooms.get(roomId);
3408
+ if (!roomState) {
3409
+ throw new Error(`Room ${roomId} not found`);
3575
3410
  }
3576
- this.state = "connecting";
3577
- this.connectedUrl = url;
3578
- if (this.simulateLatency > 0) {
3579
- await new Promise((resolve) => setTimeout(resolve, this.simulateLatency));
3411
+ if (roomState.room.maxUsers && roomState.users.size >= roomState.room.maxUsers) {
3412
+ throw new Error(`Room ${roomId} is full`);
3580
3413
  }
3581
- this.state = "connected";
3414
+ roomState.users.set(user.id, user);
3582
3415
  }
3583
- async disconnect() {
3584
- if (this.state === "disconnected")
3416
+ async leaveRoom(roomId, userId) {
3417
+ const roomState = this.rooms.get(roomId);
3418
+ if (!roomState) {
3585
3419
  return;
3586
- this.state = "disconnecting";
3587
- if (this.simulateLatency > 0) {
3588
- await new Promise((resolve) => setTimeout(resolve, this.simulateLatency / 2));
3589
3420
  }
3590
- this.state = "disconnected";
3591
- this.connectedUrl = null;
3592
- this.closeHandlers.forEach((handler) => handler(1000, "Normal closure"));
3593
- this.messageQueue = [];
3421
+ roomState.users.delete(userId);
3594
3422
  }
3595
- async send(message) {
3596
- if (this.state !== "connected") {
3597
- throw new Error("Not connected");
3598
- }
3599
- if (this.simulateLatency > 0) {
3600
- await new Promise((resolve) => setTimeout(resolve, this.simulateLatency));
3423
+ async broadcastToRoom(roomId, event, _excludeUserId) {
3424
+ const roomState = this.rooms.get(roomId);
3425
+ if (!roomState) {
3426
+ throw new Error(`Room ${roomId} not found`);
3601
3427
  }
3602
- this.messageQueue.push(message);
3603
- }
3604
- onMessage(handler) {
3605
- this.messageHandlers.add(handler);
3606
- }
3607
- onError(handler) {
3608
- this.errorHandlers.add(handler);
3609
- }
3610
- onClose(handler) {
3611
- this.closeHandlers.add(handler);
3612
- }
3613
- getState() {
3614
- return this.state;
3428
+ await this.addEventToHistory(roomId, event);
3615
3429
  }
3616
- isConnected() {
3617
- return this.state === "connected";
3430
+ async getRoomState(roomId) {
3431
+ return this.rooms.get(roomId) || null;
3618
3432
  }
3619
- simulateMessage(message, bypassConnectionCheck = false) {
3620
- if (!bypassConnectionCheck && this.state !== "connected") {
3621
- throw new Error("Cannot simulate message when not connected");
3433
+ async getUsersInRoom(roomId) {
3434
+ const roomState = this.rooms.get(roomId);
3435
+ if (!roomState) {
3436
+ return [];
3622
3437
  }
3623
- this.messageHandlers.forEach((handler) => handler(message));
3624
- }
3625
- simulateError(error) {
3626
- this.errorHandlers.forEach((handler) => handler(error));
3627
- }
3628
- simulateClose(code, reason) {
3629
- this.state = "disconnected";
3630
- this.closeHandlers.forEach((handler) => handler(code, reason));
3631
- }
3632
- getMessageQueue() {
3633
- return [...this.messageQueue];
3438
+ return Array.from(roomState.users.values());
3634
3439
  }
3635
- clearMessageQueue() {
3636
- this.messageQueue = [];
3440
+ async addEventToHistory(roomId, event) {
3441
+ const roomState = this.rooms.get(roomId);
3442
+ if (!roomState) {
3443
+ throw new Error(`Room ${roomId} not found`);
3444
+ }
3445
+ roomState.eventHistory.push(event);
3446
+ if (roomState.room.maxHistory && roomState.eventHistory.length > roomState.room.maxHistory) {
3447
+ roomState.eventHistory = roomState.eventHistory.slice(-roomState.room.maxHistory);
3448
+ }
3637
3449
  }
3638
- getConnectedUrl() {
3639
- return this.connectedUrl;
3450
+ async getEventHistory(roomId, limit) {
3451
+ const roomState = this.rooms.get(roomId);
3452
+ if (!roomState) {
3453
+ return [];
3454
+ }
3455
+ const history = roomState.eventHistory;
3456
+ return limit ? history.slice(-limit) : history;
3640
3457
  }
3641
- getConnectionAttempts() {
3642
- return this.connectionAttempts;
3458
+ async updateUserStatus(roomId, userId, status) {
3459
+ const roomState = this.rooms.get(roomId);
3460
+ if (!roomState) {
3461
+ throw new Error(`Room ${roomId} not found`);
3462
+ }
3463
+ const user = roomState.users.get(userId);
3464
+ if (user) {
3465
+ user.status = status;
3466
+ user.lastActivity = Date.now();
3467
+ }
3643
3468
  }
3644
- resetConnectionAttempts() {
3645
- this.connectionAttempts = 0;
3469
+ }
3470
+ // src/abstractions/EventEmitter.ts
3471
+ class TypedEventEmitter {
3472
+ listeners = new Map;
3473
+ onceListeners = new Map;
3474
+ on(event, listener) {
3475
+ if (!this.listeners.has(event)) {
3476
+ this.listeners.set(event, new Set);
3477
+ }
3478
+ this.listeners.get(event).add(listener);
3479
+ return () => this.off(event, listener);
3646
3480
  }
3647
- async simulateConnection(clientId, options = {}) {
3648
- if (this.state !== "connected") {
3649
- this.state = "connected";
3481
+ once(event, listener) {
3482
+ if (!this.onceListeners.has(event)) {
3483
+ this.onceListeners.set(event, new Set);
3650
3484
  }
3651
- const message = {
3652
- id: `conn-${clientId}`,
3653
- type: "connection",
3654
- payload: {
3655
- clientId,
3656
- authenticated: options.authenticated ?? false,
3657
- userId: options.userId,
3658
- metadata: options.metadata
3659
- },
3660
- timestamp: Date.now()
3661
- };
3662
- this.simulateMessage(message, true);
3485
+ this.onceListeners.get(event).add(listener);
3486
+ return () => this.off(event, listener);
3663
3487
  }
3664
- async simulateDisconnect(clientId, reason = "Normal closure") {
3665
- const message = {
3666
- id: `disconnect-${clientId}`,
3667
- type: "disconnect",
3668
- payload: {
3669
- clientId,
3670
- reason
3671
- },
3672
- timestamp: Date.now()
3673
- };
3674
- this.simulateMessage(message, true);
3488
+ off(event, listener) {
3489
+ this.listeners.get(event)?.delete(listener);
3490
+ this.onceListeners.get(event)?.delete(listener);
3675
3491
  }
3676
- async simulateClientMessage(clientId, messageType, messagePayload = {}) {
3677
- const message = {
3678
- id: `msg-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`,
3679
- type: "server_message",
3680
- payload: {
3681
- clientId,
3682
- type: messageType,
3683
- ...messagePayload
3684
- },
3685
- timestamp: Date.now()
3686
- };
3687
- this.simulateMessage(message, true);
3492
+ async emit(event, data) {
3493
+ const listeners = this.listeners.get(event);
3494
+ const onceListeners = this.onceListeners.get(event);
3495
+ if (onceListeners) {
3496
+ const listenersToCall = Array.from(onceListeners);
3497
+ this.onceListeners.delete(event);
3498
+ for (const listener of listenersToCall) {
3499
+ await listener(data);
3500
+ }
3501
+ }
3502
+ if (listeners) {
3503
+ for (const listener of Array.from(listeners)) {
3504
+ await listener(data);
3505
+ }
3506
+ }
3688
3507
  }
3689
- getSentMessages(clientId) {
3690
- return this.messageQueue.filter((msg) => {
3691
- const payload = msg.payload;
3692
- return payload?.clientId === clientId;
3693
- }).map((msg) => {
3694
- const { clientId: _, ...rest } = msg.payload;
3695
- return rest;
3696
- });
3508
+ removeAllListeners(event) {
3509
+ if (event) {
3510
+ this.listeners.delete(event);
3511
+ this.onceListeners.delete(event);
3512
+ } else {
3513
+ this.listeners.clear();
3514
+ this.onceListeners.clear();
3515
+ }
3697
3516
  }
3698
- simulateIncomingMessage(message) {
3699
- const fullMessage = {
3700
- id: message.id || `msg-${Date.now()}`,
3701
- type: message.type,
3702
- payload: message.payload || {},
3703
- timestamp: message.timestamp || Date.now()
3704
- };
3705
- this.messageHandlers.forEach((handler) => handler(fullMessage));
3517
+ listenerCount(event) {
3518
+ const regular = this.listeners.get(event)?.size ?? 0;
3519
+ const once = this.onceListeners.get(event)?.size ?? 0;
3520
+ return regular + once;
3706
3521
  }
3707
3522
  }
3708
- // src/adapters/mock/MockStorageAdapter.ts
3709
- class MockStorageAdapter {
3710
- storage = new Map;
3523
+ // src/adapters/mock/MockAuthAdapter.ts
3524
+ class MockAuthAdapter {
3525
+ tokens = new Map;
3526
+ revokedTokens = new Set;
3711
3527
  simulateLatency = 0;
3712
- shouldFailOperations = false;
3528
+ shouldFailAuth = false;
3529
+ tokenCounter = 0;
3530
+ currentToken = null;
3713
3531
  constructor(options) {
3714
3532
  this.simulateLatency = options?.simulateLatency ?? 0;
3715
- this.shouldFailOperations = options?.shouldFailOperations ?? false;
3533
+ this.shouldFailAuth = options?.shouldFailAuth ?? false;
3716
3534
  }
3717
- async get(key) {
3535
+ async validateToken(token) {
3718
3536
  await this.simulateDelay();
3719
- if (this.shouldFailOperations) {
3720
- throw new Error("Mock storage operation failed");
3537
+ if (this.shouldFailAuth) {
3538
+ throw new Error("Mock auth validation failed");
3721
3539
  }
3722
- const item = this.storage.get(key);
3723
- if (!item)
3724
- return null;
3725
- if (item.expiresAt && item.expiresAt < Date.now()) {
3726
- this.storage.delete(key);
3727
- return null;
3540
+ if (this.revokedTokens.has(token)) {
3541
+ throw new Error("Token has been revoked");
3728
3542
  }
3729
- return item.value;
3730
- }
3731
- async set(key, value, ttl) {
3732
- await this.simulateDelay();
3733
- if (this.shouldFailOperations) {
3734
- throw new Error("Mock storage operation failed");
3543
+ const payload = this.tokens.get(token);
3544
+ if (!payload) {
3545
+ throw new Error("Invalid token");
3735
3546
  }
3736
- const item = {
3737
- value,
3738
- expiresAt: ttl ? Date.now() + ttl : undefined
3739
- };
3740
- this.storage.set(key, item);
3547
+ if (payload.expiresAt && payload.expiresAt < Date.now()) {
3548
+ this.tokens.delete(token);
3549
+ throw new Error("Token expired");
3550
+ }
3551
+ return payload;
3741
3552
  }
3742
- async delete(key) {
3553
+ async generateToken(payload) {
3743
3554
  await this.simulateDelay();
3744
- if (this.shouldFailOperations) {
3745
- throw new Error("Mock storage operation failed");
3555
+ if (this.shouldFailAuth) {
3556
+ throw new Error("Mock token generation failed");
3746
3557
  }
3747
- this.storage.delete(key);
3558
+ const token = `mock-token-${++this.tokenCounter}`;
3559
+ const expiresAt = payload.expiresAt ?? Date.now() + 3600000;
3560
+ this.tokens.set(token, { ...payload, expiresAt });
3561
+ return token;
3748
3562
  }
3749
- async exists(key) {
3563
+ async refreshToken(token) {
3750
3564
  await this.simulateDelay();
3751
- if (this.shouldFailOperations) {
3752
- throw new Error("Mock storage operation failed");
3565
+ if (this.shouldFailAuth) {
3566
+ throw new Error("Mock token refresh failed");
3753
3567
  }
3754
- const item = this.storage.get(key);
3755
- if (!item)
3756
- return false;
3757
- if (item.expiresAt && item.expiresAt < Date.now()) {
3568
+ const payload = await this.validateToken(token);
3569
+ await this.revokeToken(token);
3570
+ const newPayload = {
3571
+ ...payload,
3572
+ expiresAt: Date.now() + 3600000
3573
+ };
3574
+ return this.generateToken(newPayload);
3575
+ }
3576
+ async revokeToken(token) {
3577
+ await this.simulateDelay();
3578
+ if (this.shouldFailAuth) {
3579
+ throw new Error("Mock token revocation failed");
3580
+ }
3581
+ this.tokens.delete(token);
3582
+ this.revokedTokens.add(token);
3583
+ }
3584
+ getCurrentToken() {
3585
+ return this.currentToken;
3586
+ }
3587
+ isAuthRequired() {
3588
+ return false;
3589
+ }
3590
+ getAuthTimeout() {
3591
+ return 1e4;
3592
+ }
3593
+ async simulateDelay() {
3594
+ if (this.simulateLatency > 0) {
3595
+ await new Promise((resolve) => setTimeout(resolve, this.simulateLatency));
3596
+ }
3597
+ }
3598
+ async createTestToken(userId, options) {
3599
+ const payload = {
3600
+ userId,
3601
+ permissions: options?.permissions ?? ["read", "write"],
3602
+ metadata: options?.metadata,
3603
+ expiresAt: options?.expiresIn ? Date.now() + options.expiresIn : undefined
3604
+ };
3605
+ const token = await this.generateToken(payload);
3606
+ this.currentToken = token;
3607
+ return token;
3608
+ }
3609
+ getTokenCount() {
3610
+ return this.tokens.size;
3611
+ }
3612
+ getRevokedTokenCount() {
3613
+ return this.revokedTokens.size;
3614
+ }
3615
+ clearTokens() {
3616
+ this.tokens.clear();
3617
+ this.revokedTokens.clear();
3618
+ this.currentToken = null;
3619
+ }
3620
+ setFailAuth(fail) {
3621
+ this.shouldFailAuth = fail;
3622
+ }
3623
+ setCurrentToken(token) {
3624
+ this.currentToken = token;
3625
+ }
3626
+ }
3627
+ // src/adapters/mock/MockRTCDataChannel.ts
3628
+ class MockRTCDataChannel {
3629
+ label;
3630
+ ordered;
3631
+ id;
3632
+ _readyState = "connecting";
3633
+ _bufferedAmount = 0;
3634
+ _linkedChannel = null;
3635
+ messageQueue = [];
3636
+ config;
3637
+ static channelIdCounter = 0;
3638
+ onopen = null;
3639
+ onclose = null;
3640
+ onerror = null;
3641
+ onmessage = null;
3642
+ onbufferedamountlow = null;
3643
+ bufferedAmountLowThreshold = 0;
3644
+ constructor(label, options, config) {
3645
+ this.label = label;
3646
+ this.ordered = options?.ordered ?? true;
3647
+ this.id = options?.id ?? MockRTCDataChannel.channelIdCounter++;
3648
+ this.config = {
3649
+ simulateLatency: config?.simulateLatency ?? 1,
3650
+ maxMessageSize: config?.maxMessageSize ?? 262144
3651
+ };
3652
+ }
3653
+ get readyState() {
3654
+ return this._readyState;
3655
+ }
3656
+ get bufferedAmount() {
3657
+ return this._bufferedAmount;
3658
+ }
3659
+ send(data) {
3660
+ if (this._readyState !== "open") {
3661
+ throw new Error(`Cannot send on channel in state: ${this._readyState}`);
3662
+ }
3663
+ const size = typeof data === "string" ? data.length : data.byteLength;
3664
+ if (size > this.config.maxMessageSize) {
3665
+ throw new Error(`Message size ${size} exceeds maximum ${this.config.maxMessageSize}`);
3666
+ }
3667
+ this._bufferedAmount += size;
3668
+ if (this._linkedChannel && this._linkedChannel._readyState === "open") {
3669
+ setTimeout(() => {
3670
+ this._bufferedAmount -= size;
3671
+ if (this._bufferedAmount <= this.bufferedAmountLowThreshold) {
3672
+ this.onbufferedamountlow?.();
3673
+ }
3674
+ this._linkedChannel?.onmessage?.({ data });
3675
+ }, this.config.simulateLatency);
3676
+ } else {
3677
+ this.messageQueue.push(data);
3678
+ }
3679
+ }
3680
+ close() {
3681
+ if (this._readyState === "closed" || this._readyState === "closing") {
3682
+ return;
3683
+ }
3684
+ this._readyState = "closing";
3685
+ setTimeout(() => {
3686
+ this._readyState = "closed";
3687
+ this.onclose?.();
3688
+ if (this._linkedChannel && this._linkedChannel._readyState !== "closed") {
3689
+ this._linkedChannel._handleRemoteClose();
3690
+ }
3691
+ }, this.config.simulateLatency);
3692
+ }
3693
+ _linkChannel(channel) {
3694
+ this._linkedChannel = channel;
3695
+ if (this._readyState === "open" && channel._readyState === "open") {
3696
+ this._flushQueue();
3697
+ }
3698
+ }
3699
+ _open() {
3700
+ if (this._readyState === "connecting") {
3701
+ this._readyState = "open";
3702
+ this.onopen?.();
3703
+ if (this._linkedChannel?._readyState === "open") {
3704
+ this._flushQueue();
3705
+ }
3706
+ }
3707
+ }
3708
+ _handleRemoteClose() {
3709
+ if (this._readyState !== "closed" && this._readyState !== "closing") {
3710
+ this._readyState = "closed";
3711
+ this.onclose?.();
3712
+ }
3713
+ }
3714
+ _getLinkedChannel() {
3715
+ return this._linkedChannel;
3716
+ }
3717
+ _flushQueue() {
3718
+ for (const data of this.messageQueue) {
3719
+ const size = typeof data === "string" ? data.length : data.byteLength;
3720
+ setTimeout(() => {
3721
+ this._bufferedAmount -= size;
3722
+ this._linkedChannel?.onmessage?.({ data });
3723
+ }, this.config.simulateLatency);
3724
+ }
3725
+ this.messageQueue = [];
3726
+ }
3727
+ static resetIdCounter() {
3728
+ MockRTCDataChannel.channelIdCounter = 0;
3729
+ }
3730
+ }
3731
+ // src/adapters/mock/MockRTCPeerConnection.ts
3732
+ class MockRTCPeerConnection {
3733
+ _signalingState = "stable";
3734
+ _iceConnectionState = "new";
3735
+ _iceGatheringState = "new";
3736
+ _connectionState = "new";
3737
+ _localDescription = null;
3738
+ _remoteDescription = null;
3739
+ _pendingLocalDescription = null;
3740
+ _pendingRemoteDescription = null;
3741
+ _localCandidates = [];
3742
+ _remoteCandidates = [];
3743
+ _pendingRemoteCandidates = [];
3744
+ _dataChannels = new Map;
3745
+ onicecandidate = null;
3746
+ onicecandidateerror = null;
3747
+ oniceconnectionstatechange = null;
3748
+ onicegatheringstatechange = null;
3749
+ onconnectionstatechange = null;
3750
+ onsignalingstatechange = null;
3751
+ ondatachannel = null;
3752
+ onnegotiationneeded = null;
3753
+ _linkedPeer = null;
3754
+ config;
3755
+ offerCounter = 0;
3756
+ iceUfrag;
3757
+ icePwd;
3758
+ constructor(config) {
3759
+ this.config = {
3760
+ simulateLatency: config?.simulateLatency ?? 10,
3761
+ iceFailureProbability: config?.iceFailureProbability ?? 0,
3762
+ iceGatheringTime: config?.iceGatheringTime ?? 50,
3763
+ autoGenerateIceCandidates: config?.autoGenerateIceCandidates ?? true,
3764
+ iceCandidateCount: config?.iceCandidateCount ?? 3,
3765
+ dataChannelConfig: config?.dataChannelConfig
3766
+ };
3767
+ this.iceUfrag = "mock" + Math.random().toString(36).substring(2, 6);
3768
+ this.icePwd = "mock" + Math.random().toString(36).substring(2, 26);
3769
+ }
3770
+ get signalingState() {
3771
+ return this._signalingState;
3772
+ }
3773
+ get iceConnectionState() {
3774
+ return this._iceConnectionState;
3775
+ }
3776
+ get iceGatheringState() {
3777
+ return this._iceGatheringState;
3778
+ }
3779
+ get connectionState() {
3780
+ return this._connectionState;
3781
+ }
3782
+ get localDescription() {
3783
+ return this._localDescription;
3784
+ }
3785
+ get remoteDescription() {
3786
+ return this._remoteDescription;
3787
+ }
3788
+ get pendingLocalDescription() {
3789
+ return this._pendingLocalDescription;
3790
+ }
3791
+ get pendingRemoteDescription() {
3792
+ return this._pendingRemoteDescription;
3793
+ }
3794
+ get currentLocalDescription() {
3795
+ return this._localDescription;
3796
+ }
3797
+ get currentRemoteDescription() {
3798
+ return this._remoteDescription;
3799
+ }
3800
+ static createLinkedPair(configA, configB) {
3801
+ const peerA = new MockRTCPeerConnection(configA);
3802
+ const peerB = new MockRTCPeerConnection(configB);
3803
+ peerA._linkedPeer = peerB;
3804
+ peerB._linkedPeer = peerA;
3805
+ return [peerA, peerB];
3806
+ }
3807
+ async createOffer() {
3808
+ if (this._signalingState === "closed") {
3809
+ throw new Error("Cannot create offer on closed connection");
3810
+ }
3811
+ await this.simulateDelay();
3812
+ this.offerCounter++;
3813
+ const sdp = this.generateMockSDP("offer");
3814
+ return {
3815
+ type: "offer",
3816
+ sdp
3817
+ };
3818
+ }
3819
+ async createAnswer() {
3820
+ if (this._signalingState !== "have-remote-offer") {
3821
+ throw new Error(`Cannot create answer in signaling state: ${this._signalingState}`);
3822
+ }
3823
+ await this.simulateDelay();
3824
+ const sdp = this.generateMockSDP("answer");
3825
+ return {
3826
+ type: "answer",
3827
+ sdp
3828
+ };
3829
+ }
3830
+ async setLocalDescription(description) {
3831
+ if (this._signalingState === "closed") {
3832
+ throw new Error("Cannot set local description on closed connection");
3833
+ }
3834
+ await this.simulateDelay();
3835
+ if (!description) {
3836
+ if (this._signalingState === "have-remote-offer") {
3837
+ description = await this.createAnswer();
3838
+ } else {
3839
+ description = await this.createOffer();
3840
+ }
3841
+ }
3842
+ this._localDescription = description;
3843
+ this._pendingLocalDescription = null;
3844
+ if (description.type === "offer") {
3845
+ this._signalingState = "have-local-offer";
3846
+ } else if (description.type === "answer") {
3847
+ this._signalingState = "stable";
3848
+ this.startIceConnection();
3849
+ }
3850
+ this.onsignalingstatechange?.();
3851
+ if (this.config.autoGenerateIceCandidates) {
3852
+ this.startIceGathering();
3853
+ }
3854
+ }
3855
+ async setRemoteDescription(description) {
3856
+ if (this._signalingState === "closed") {
3857
+ throw new Error("Cannot set remote description on closed connection");
3858
+ }
3859
+ await this.simulateDelay();
3860
+ this._remoteDescription = description;
3861
+ this._pendingRemoteDescription = null;
3862
+ if (description.type === "offer") {
3863
+ this._signalingState = "have-remote-offer";
3864
+ } else if (description.type === "answer") {
3865
+ this._signalingState = "stable";
3866
+ this.startIceConnection();
3867
+ }
3868
+ this.onsignalingstatechange?.();
3869
+ for (const candidate of this._pendingRemoteCandidates) {
3870
+ this._remoteCandidates.push(candidate);
3871
+ }
3872
+ this._pendingRemoteCandidates = [];
3873
+ if (description.type === "offer" && this._linkedPeer) {
3874
+ this.receiveDataChannelsFromPeer();
3875
+ }
3876
+ }
3877
+ async addIceCandidate(candidate) {
3878
+ if (this._signalingState === "closed") {
3879
+ throw new Error("Cannot add ICE candidate on closed connection");
3880
+ }
3881
+ if (!candidate) {
3882
+ return;
3883
+ }
3884
+ if (!this._remoteDescription) {
3885
+ this._pendingRemoteCandidates.push(candidate);
3886
+ return;
3887
+ }
3888
+ await this.simulateDelay();
3889
+ this._remoteCandidates.push(candidate);
3890
+ if (this._iceConnectionState === "new") {
3891
+ this._iceConnectionState = "checking";
3892
+ this.oniceconnectionstatechange?.();
3893
+ }
3894
+ }
3895
+ createDataChannel(label, options) {
3896
+ if (this._signalingState === "closed") {
3897
+ throw new Error("Cannot create data channel on closed connection");
3898
+ }
3899
+ const channel = new MockRTCDataChannel(label, options, this.config.dataChannelConfig);
3900
+ this._dataChannels.set(label, channel);
3901
+ setTimeout(() => {
3902
+ this.onnegotiationneeded?.();
3903
+ }, 0);
3904
+ return channel;
3905
+ }
3906
+ close() {
3907
+ if (this._signalingState === "closed") {
3908
+ return;
3909
+ }
3910
+ this._signalingState = "closed";
3911
+ this._iceConnectionState = "closed";
3912
+ this._connectionState = "closed";
3913
+ for (const channel of this._dataChannels.values()) {
3914
+ channel.close();
3915
+ }
3916
+ this._dataChannels.clear();
3917
+ this.onsignalingstatechange?.();
3918
+ this.oniceconnectionstatechange?.();
3919
+ this.onconnectionstatechange?.();
3920
+ }
3921
+ async getStats() {
3922
+ return new Map([
3923
+ [
3924
+ "peer-connection",
3925
+ {
3926
+ type: "peer-connection",
3927
+ timestamp: Date.now(),
3928
+ dataChannelsOpened: this._dataChannels.size,
3929
+ localCandidates: this._localCandidates.length,
3930
+ remoteCandidates: this._remoteCandidates.length,
3931
+ signalingState: this._signalingState,
3932
+ iceConnectionState: this._iceConnectionState,
3933
+ connectionState: this._connectionState
3934
+ }
3935
+ ]
3936
+ ]);
3937
+ }
3938
+ restartIce() {
3939
+ this.iceUfrag = "mock" + Math.random().toString(36).substring(2, 6);
3940
+ this.icePwd = "mock" + Math.random().toString(36).substring(2, 26);
3941
+ this._localCandidates = [];
3942
+ this._remoteCandidates = [];
3943
+ this._iceGatheringState = "new";
3944
+ this._iceConnectionState = "new";
3945
+ this.onicegatheringstatechange?.();
3946
+ this.oniceconnectionstatechange?.();
3947
+ }
3948
+ getDataChannels() {
3949
+ return new Map(this._dataChannels);
3950
+ }
3951
+ getLocalCandidates() {
3952
+ return [...this._localCandidates];
3953
+ }
3954
+ getRemoteCandidates() {
3955
+ return [...this._remoteCandidates];
3956
+ }
3957
+ getLinkedPeer() {
3958
+ return this._linkedPeer;
3959
+ }
3960
+ _forceConnected() {
3961
+ this._iceConnectionState = "connected";
3962
+ this._connectionState = "connected";
3963
+ this.oniceconnectionstatechange?.();
3964
+ this.onconnectionstatechange?.();
3965
+ for (const channel of this._dataChannels.values()) {
3966
+ channel._open();
3967
+ }
3968
+ }
3969
+ async simulateDelay() {
3970
+ if (this.config.simulateLatency > 0) {
3971
+ await new Promise((resolve) => setTimeout(resolve, this.config.simulateLatency));
3972
+ }
3973
+ }
3974
+ generateMockSDP(type) {
3975
+ const sessionId = Date.now();
3976
+ const version = this.offerCounter;
3977
+ const lines = [
3978
+ "v=0",
3979
+ `o=- ${sessionId} ${version} IN IP4 127.0.0.1`,
3980
+ "s=-",
3981
+ "t=0 0",
3982
+ "a=group:BUNDLE 0",
3983
+ "a=extmap-allow-mixed",
3984
+ "a=msid-semantic: WMS",
3985
+ "m=application 9 UDP/DTLS/SCTP webrtc-datachannel",
3986
+ "c=IN IP4 0.0.0.0",
3987
+ `a=ice-ufrag:${this.iceUfrag}`,
3988
+ `a=ice-pwd:${this.icePwd}`,
3989
+ "a=ice-options:trickle",
3990
+ "a=fingerprint:sha-256 00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00",
3991
+ type === "offer" ? "a=setup:actpass" : "a=setup:active",
3992
+ "a=mid:0",
3993
+ "a=sctp-port:5000",
3994
+ "a=max-message-size:262144"
3995
+ ];
3996
+ return lines.join(`\r
3997
+ `) + `\r
3998
+ `;
3999
+ }
4000
+ startIceGathering() {
4001
+ if (this._iceGatheringState !== "new") {
4002
+ return;
4003
+ }
4004
+ this._iceGatheringState = "gathering";
4005
+ this.onicegatheringstatechange?.();
4006
+ const candidateDelay = this.config.iceGatheringTime / this.config.iceCandidateCount;
4007
+ for (let i = 0;i < this.config.iceCandidateCount; i++) {
4008
+ setTimeout(() => {
4009
+ if (this._signalingState === "closed")
4010
+ return;
4011
+ if (Math.random() < this.config.iceFailureProbability) {
4012
+ this.onicecandidateerror?.({
4013
+ errorCode: 701,
4014
+ errorText: "Simulated ICE failure"
4015
+ });
4016
+ return;
4017
+ }
4018
+ const candidate = {
4019
+ candidate: `candidate:${i} 1 udp ${2000000000 - i * 100} 192.168.1.${100 + i} ${50000 + i} typ host generation 0 ufrag ${this.iceUfrag}`,
4020
+ sdpMid: "0",
4021
+ sdpMLineIndex: 0,
4022
+ usernameFragment: this.iceUfrag
4023
+ };
4024
+ this._localCandidates.push(candidate);
4025
+ this.onicecandidate?.({ candidate });
4026
+ if (i === this.config.iceCandidateCount - 1) {
4027
+ setTimeout(() => {
4028
+ if (this._signalingState === "closed")
4029
+ return;
4030
+ this._iceGatheringState = "complete";
4031
+ this.onicegatheringstatechange?.();
4032
+ this.onicecandidate?.({ candidate: null });
4033
+ }, this.config.simulateLatency);
4034
+ }
4035
+ }, candidateDelay * i);
4036
+ }
4037
+ }
4038
+ startIceConnection() {
4039
+ this._iceConnectionState = "checking";
4040
+ this._connectionState = "connecting";
4041
+ this.oniceconnectionstatechange?.();
4042
+ this.onconnectionstatechange?.();
4043
+ setTimeout(() => {
4044
+ if (this._signalingState === "closed")
4045
+ return;
4046
+ this._iceConnectionState = "connected";
4047
+ this._connectionState = "connected";
4048
+ this.oniceconnectionstatechange?.();
4049
+ this.onconnectionstatechange?.();
4050
+ this.openDataChannels();
4051
+ }, this.config.iceGatheringTime + this.config.simulateLatency);
4052
+ }
4053
+ openDataChannels() {
4054
+ for (const channel of this._dataChannels.values()) {
4055
+ channel._open();
4056
+ }
4057
+ if (this._linkedPeer) {
4058
+ for (const [label, localChannel] of this._dataChannels) {
4059
+ const remoteChannel = this._linkedPeer._dataChannels.get(label);
4060
+ if (remoteChannel) {
4061
+ localChannel._linkChannel(remoteChannel);
4062
+ remoteChannel._linkChannel(localChannel);
4063
+ }
4064
+ }
4065
+ for (const channel of this._linkedPeer._dataChannels.values()) {
4066
+ if (channel.readyState === "connecting") {
4067
+ channel._open();
4068
+ }
4069
+ }
4070
+ }
4071
+ }
4072
+ receiveDataChannelsFromPeer() {
4073
+ if (!this._linkedPeer)
4074
+ return;
4075
+ for (const [label, peerChannel] of this._linkedPeer._dataChannels) {
4076
+ if (!this._dataChannels.has(label)) {
4077
+ const localChannel = new MockRTCDataChannel(label, { ordered: peerChannel.ordered, id: peerChannel.id }, this.config.dataChannelConfig);
4078
+ this._dataChannels.set(label, localChannel);
4079
+ localChannel._linkChannel(peerChannel);
4080
+ peerChannel._linkChannel(localChannel);
4081
+ this.ondatachannel?.({ channel: localChannel });
4082
+ }
4083
+ }
4084
+ }
4085
+ }
4086
+ // src/adapters/mock/MockStorageAdapter.ts
4087
+ class MockStorageAdapter {
4088
+ storage = new Map;
4089
+ simulateLatency = 0;
4090
+ shouldFailOperations = false;
4091
+ constructor(options) {
4092
+ this.simulateLatency = options?.simulateLatency ?? 0;
4093
+ this.shouldFailOperations = options?.shouldFailOperations ?? false;
4094
+ }
4095
+ async get(key) {
4096
+ await this.simulateDelay();
4097
+ if (this.shouldFailOperations) {
4098
+ throw new Error("Mock storage operation failed");
4099
+ }
4100
+ const item = this.storage.get(key);
4101
+ if (!item)
4102
+ return null;
4103
+ if (item.expiresAt && item.expiresAt < Date.now()) {
4104
+ this.storage.delete(key);
4105
+ return null;
4106
+ }
4107
+ return item.value;
4108
+ }
4109
+ async set(key, value, ttl) {
4110
+ await this.simulateDelay();
4111
+ if (this.shouldFailOperations) {
4112
+ throw new Error("Mock storage operation failed");
4113
+ }
4114
+ const item = {
4115
+ value,
4116
+ expiresAt: ttl ? Date.now() + ttl : undefined
4117
+ };
4118
+ this.storage.set(key, item);
4119
+ }
4120
+ async delete(key) {
4121
+ await this.simulateDelay();
4122
+ if (this.shouldFailOperations) {
4123
+ throw new Error("Mock storage operation failed");
4124
+ }
4125
+ this.storage.delete(key);
4126
+ }
4127
+ async exists(key) {
4128
+ await this.simulateDelay();
4129
+ if (this.shouldFailOperations) {
4130
+ throw new Error("Mock storage operation failed");
4131
+ }
4132
+ const item = this.storage.get(key);
4133
+ if (!item)
4134
+ return false;
4135
+ if (item.expiresAt && item.expiresAt < Date.now()) {
3758
4136
  this.storage.delete(key);
3759
4137
  return false;
3760
4138
  }
@@ -3855,117 +4233,645 @@ class MockStorageAdapter {
3855
4233
  this.shouldFailOperations = fail;
3856
4234
  }
3857
4235
  }
3858
- // src/adapters/mock/MockAuthAdapter.ts
3859
- class MockAuthAdapter {
3860
- tokens = new Map;
3861
- revokedTokens = new Set;
4236
+ // src/adapters/mock/MockTransportAdapter.ts
4237
+ class MockTransportAdapter {
4238
+ state = "disconnected";
4239
+ messageHandlers = new Set;
4240
+ errorHandlers = new Set;
4241
+ closeHandlers = new Set;
4242
+ messageQueue = [];
3862
4243
  simulateLatency = 0;
3863
- shouldFailAuth = false;
3864
- tokenCounter = 0;
3865
- currentToken = null;
4244
+ shouldFailConnection = false;
4245
+ connectedUrl = null;
4246
+ connectionAttempts = 0;
3866
4247
  constructor(options) {
3867
4248
  this.simulateLatency = options?.simulateLatency ?? 0;
3868
- this.shouldFailAuth = options?.shouldFailAuth ?? false;
4249
+ this.shouldFailConnection = options?.shouldFailConnection ?? false;
3869
4250
  }
3870
- async validateToken(token) {
3871
- await this.simulateDelay();
3872
- if (this.shouldFailAuth) {
3873
- throw new Error("Mock auth validation failed");
4251
+ async connect(url, _options) {
4252
+ this.connectionAttempts++;
4253
+ if (this.shouldFailConnection) {
4254
+ this.state = "disconnected";
4255
+ const error = new Error("Mock connection failed");
4256
+ this.errorHandlers.forEach((handler) => handler(error));
4257
+ throw error;
3874
4258
  }
3875
- if (this.revokedTokens.has(token)) {
3876
- throw new Error("Token has been revoked");
4259
+ this.state = "connecting";
4260
+ this.connectedUrl = url;
4261
+ if (this.simulateLatency > 0) {
4262
+ await new Promise((resolve) => setTimeout(resolve, this.simulateLatency));
3877
4263
  }
3878
- const payload = this.tokens.get(token);
3879
- if (!payload) {
3880
- throw new Error("Invalid token");
4264
+ this.state = "connected";
4265
+ }
4266
+ async disconnect() {
4267
+ if (this.state === "disconnected")
4268
+ return;
4269
+ this.state = "disconnecting";
4270
+ if (this.simulateLatency > 0) {
4271
+ await new Promise((resolve) => setTimeout(resolve, this.simulateLatency / 2));
3881
4272
  }
3882
- if (payload.expiresAt && payload.expiresAt < Date.now()) {
3883
- this.tokens.delete(token);
3884
- throw new Error("Token expired");
4273
+ this.state = "disconnected";
4274
+ this.connectedUrl = null;
4275
+ this.closeHandlers.forEach((handler) => handler(1000, "Normal closure"));
4276
+ this.messageQueue = [];
4277
+ }
4278
+ async send(message) {
4279
+ if (this.state !== "connected") {
4280
+ throw new Error("Not connected");
3885
4281
  }
3886
- return payload;
4282
+ if (this.simulateLatency > 0) {
4283
+ await new Promise((resolve) => setTimeout(resolve, this.simulateLatency));
4284
+ }
4285
+ this.messageQueue.push(message);
3887
4286
  }
3888
- async generateToken(payload) {
3889
- await this.simulateDelay();
3890
- if (this.shouldFailAuth) {
3891
- throw new Error("Mock token generation failed");
4287
+ onMessage(handler) {
4288
+ this.messageHandlers.add(handler);
4289
+ }
4290
+ onError(handler) {
4291
+ this.errorHandlers.add(handler);
4292
+ }
4293
+ onClose(handler) {
4294
+ this.closeHandlers.add(handler);
4295
+ }
4296
+ getState() {
4297
+ return this.state;
4298
+ }
4299
+ isConnected() {
4300
+ return this.state === "connected";
4301
+ }
4302
+ simulateMessage(message, bypassConnectionCheck = false) {
4303
+ if (!bypassConnectionCheck && this.state !== "connected") {
4304
+ throw new Error("Cannot simulate message when not connected");
3892
4305
  }
3893
- const token = `mock-token-${++this.tokenCounter}`;
3894
- const expiresAt = payload.expiresAt ?? Date.now() + 3600000;
3895
- this.tokens.set(token, { ...payload, expiresAt });
3896
- return token;
4306
+ this.messageHandlers.forEach((handler) => handler(message));
3897
4307
  }
3898
- async refreshToken(token) {
3899
- await this.simulateDelay();
3900
- if (this.shouldFailAuth) {
3901
- throw new Error("Mock token refresh failed");
4308
+ simulateError(error) {
4309
+ this.errorHandlers.forEach((handler) => handler(error));
4310
+ }
4311
+ simulateClose(code, reason) {
4312
+ this.state = "disconnected";
4313
+ this.closeHandlers.forEach((handler) => handler(code, reason));
4314
+ }
4315
+ getMessageQueue() {
4316
+ return [...this.messageQueue];
4317
+ }
4318
+ clearMessageQueue() {
4319
+ this.messageQueue = [];
4320
+ }
4321
+ getConnectedUrl() {
4322
+ return this.connectedUrl;
4323
+ }
4324
+ getConnectionAttempts() {
4325
+ return this.connectionAttempts;
4326
+ }
4327
+ resetConnectionAttempts() {
4328
+ this.connectionAttempts = 0;
4329
+ }
4330
+ async simulateConnection(clientId, options = {}) {
4331
+ if (this.state !== "connected") {
4332
+ this.state = "connected";
4333
+ }
4334
+ const message = {
4335
+ id: `conn-${clientId}`,
4336
+ type: "connection",
4337
+ payload: {
4338
+ clientId,
4339
+ authenticated: options.authenticated ?? false,
4340
+ userId: options.userId,
4341
+ metadata: options.metadata
4342
+ },
4343
+ timestamp: Date.now()
4344
+ };
4345
+ this.simulateMessage(message, true);
4346
+ }
4347
+ async simulateDisconnect(clientId, reason = "Normal closure") {
4348
+ const message = {
4349
+ id: `disconnect-${clientId}`,
4350
+ type: "disconnect",
4351
+ payload: {
4352
+ clientId,
4353
+ reason
4354
+ },
4355
+ timestamp: Date.now()
4356
+ };
4357
+ this.simulateMessage(message, true);
4358
+ }
4359
+ async simulateClientMessage(clientId, messageType, messagePayload = {}) {
4360
+ const message = {
4361
+ id: `msg-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`,
4362
+ type: "server_message",
4363
+ payload: {
4364
+ clientId,
4365
+ type: messageType,
4366
+ ...messagePayload
4367
+ },
4368
+ timestamp: Date.now()
4369
+ };
4370
+ this.simulateMessage(message, true);
4371
+ }
4372
+ getSentMessages(clientId) {
4373
+ return this.messageQueue.filter((msg) => {
4374
+ const payload = msg.payload;
4375
+ return payload?.clientId === clientId;
4376
+ }).map((msg) => {
4377
+ const { clientId: _, ...rest } = msg.payload;
4378
+ return rest;
4379
+ });
4380
+ }
4381
+ simulateIncomingMessage(message) {
4382
+ const fullMessage = {
4383
+ id: message.id || `msg-${Date.now()}`,
4384
+ type: message.type,
4385
+ payload: message.payload || {},
4386
+ timestamp: message.timestamp || Date.now()
4387
+ };
4388
+ this.messageHandlers.forEach((handler) => handler(fullMessage));
4389
+ }
4390
+ }
4391
+ // src/adapters/webrtc/WebRTCSignalingAdapter.ts
4392
+ class WebRTCSignalingAdapter {
4393
+ client;
4394
+ config;
4395
+ peers = new Map;
4396
+ eventUnsubscribers = [];
4397
+ onPeerConnected = null;
4398
+ onPeerDisconnected = null;
4399
+ onPeerMessage = null;
4400
+ onError = null;
4401
+ onStateChange = null;
4402
+ constructor(client, config) {
4403
+ this.client = client;
4404
+ this.config = {
4405
+ useMock: config?.useMock ?? true,
4406
+ iceServers: config?.iceServers,
4407
+ mockConfig: config?.mockConfig,
4408
+ dataChannelLabel: config?.dataChannelLabel ?? "data",
4409
+ orderedDelivery: config?.orderedDelivery ?? true
4410
+ };
4411
+ this.setupSignalingListeners();
4412
+ }
4413
+ async connectToPeer(peerId) {
4414
+ if (this.peers.has(peerId)) {
4415
+ throw new Error(`Already connected or connecting to peer: ${peerId}`);
4416
+ }
4417
+ const connection = this.createPeerConnection();
4418
+ const peerState = {
4419
+ peerId,
4420
+ connection,
4421
+ dataChannel: null,
4422
+ state: "new",
4423
+ createdAt: Date.now()
4424
+ };
4425
+ this.peers.set(peerId, peerState);
4426
+ this.setupConnectionHandlers(peerState);
4427
+ const dataChannel = connection.createDataChannel(this.config.dataChannelLabel, {
4428
+ ordered: this.config.orderedDelivery
4429
+ });
4430
+ peerState.dataChannel = dataChannel;
4431
+ this.setupDataChannelHandlers(peerState, dataChannel);
4432
+ this.updatePeerState(peerState, "connecting");
4433
+ const offer = await connection.createOffer();
4434
+ await connection.setLocalDescription(offer);
4435
+ await this.sendSignal(peerId, "webrtc:offer", {
4436
+ sdp: offer.sdp,
4437
+ type: offer.type
4438
+ });
4439
+ }
4440
+ disconnectFromPeer(peerId) {
4441
+ const peer = this.peers.get(peerId);
4442
+ if (!peer)
4443
+ return;
4444
+ this.sendSignal(peerId, "webrtc:disconnect", {}).catch(() => {});
4445
+ peer.dataChannel?.close();
4446
+ peer.connection.close();
4447
+ this.updatePeerState(peer, "disconnected");
4448
+ this.peers.delete(peerId);
4449
+ this.onPeerDisconnected?.(peerId);
4450
+ }
4451
+ sendToPeer(peerId, data) {
4452
+ const peer = this.peers.get(peerId);
4453
+ if (!peer || !peer.dataChannel) {
4454
+ throw new Error(`No data channel to peer: ${peerId}`);
4455
+ }
4456
+ if (peer.dataChannel.readyState !== "open") {
4457
+ throw new Error(`Data channel not open for peer: ${peerId} (state: ${peer.dataChannel.readyState})`);
4458
+ }
4459
+ peer.dataChannel.send(data);
4460
+ }
4461
+ broadcastToPeers(data) {
4462
+ for (const peerId of this.getConnectedPeers()) {
4463
+ try {
4464
+ this.sendToPeer(peerId, data);
4465
+ } catch (error) {
4466
+ console.warn(`Failed to send to peer ${peerId}:`, error);
4467
+ }
4468
+ }
4469
+ }
4470
+ getConnectedPeers() {
4471
+ return Array.from(this.peers.entries()).filter(([_, peer]) => peer.state === "connected").map(([peerId]) => peerId);
4472
+ }
4473
+ getAllPeers() {
4474
+ return Array.from(this.peers.keys());
4475
+ }
4476
+ getPeerState(peerId) {
4477
+ return this.peers.get(peerId)?.state ?? null;
4478
+ }
4479
+ getPeerInfo(peerId) {
4480
+ return this.peers.get(peerId) ?? null;
4481
+ }
4482
+ isConnectedToPeer(peerId) {
4483
+ return this.peers.get(peerId)?.state === "connected";
4484
+ }
4485
+ dispose() {
4486
+ for (const peerId of this.getAllPeers()) {
4487
+ this.disconnectFromPeer(peerId);
4488
+ }
4489
+ for (const unsubscribe of this.eventUnsubscribers) {
4490
+ unsubscribe();
4491
+ }
4492
+ this.eventUnsubscribers = [];
4493
+ }
4494
+ createPeerConnection() {
4495
+ if (this.config.useMock) {
4496
+ return new MockRTCPeerConnection(this.config.mockConfig);
4497
+ } else {
4498
+ throw new Error("Real WebRTC not yet implemented. Use useMock: true");
4499
+ }
4500
+ }
4501
+ setupSignalingListeners() {
4502
+ const unsubscribe = this.client.on("event_received", ({ event }) => {
4503
+ this.handleSignalingMessage(event).catch((error) => {
4504
+ console.error("Error handling signaling message:", error);
4505
+ });
4506
+ });
4507
+ this.eventUnsubscribers.push(unsubscribe);
4508
+ }
4509
+ async handleSignalingMessage(event) {
4510
+ const eventAny = event;
4511
+ const type = eventAny.type;
4512
+ const fromUserId = eventAny.metadata?.userId;
4513
+ const myUserId = this.client.getUserId();
4514
+ if (!fromUserId || fromUserId === myUserId) {
4515
+ return;
4516
+ }
4517
+ const data = eventAny.data;
4518
+ const targetPeerId = data?.targetPeerId;
4519
+ if (targetPeerId && targetPeerId !== myUserId) {
4520
+ return;
4521
+ }
4522
+ switch (type) {
4523
+ case "webrtc:offer":
4524
+ await this.handleOffer(fromUserId, data ?? {});
4525
+ break;
4526
+ case "webrtc:answer":
4527
+ await this.handleAnswer(fromUserId, data ?? {});
4528
+ break;
4529
+ case "webrtc:ice_candidate":
4530
+ await this.handleIceCandidate(fromUserId, data ?? {});
4531
+ break;
4532
+ case "webrtc:disconnect":
4533
+ this.handlePeerDisconnect(fromUserId);
4534
+ break;
4535
+ }
4536
+ }
4537
+ async handleOffer(peerId, data) {
4538
+ if (this.peers.has(peerId)) {
4539
+ console.warn(`Received offer from peer ${peerId} but already have a connection`);
4540
+ return;
4541
+ }
4542
+ const connection = this.createPeerConnection();
4543
+ const peerState = {
4544
+ peerId,
4545
+ connection,
4546
+ dataChannel: null,
4547
+ state: "connecting",
4548
+ createdAt: Date.now()
4549
+ };
4550
+ this.peers.set(peerId, peerState);
4551
+ this.setupConnectionHandlers(peerState);
4552
+ connection.ondatachannel = (event) => {
4553
+ peerState.dataChannel = event.channel;
4554
+ this.setupDataChannelHandlers(peerState, event.channel);
4555
+ };
4556
+ await connection.setRemoteDescription({
4557
+ type: "offer",
4558
+ sdp: data.sdp
4559
+ });
4560
+ const answer = await connection.createAnswer();
4561
+ await connection.setLocalDescription(answer);
4562
+ await this.sendSignal(peerId, "webrtc:answer", {
4563
+ sdp: answer.sdp,
4564
+ type: answer.type
4565
+ });
4566
+ }
4567
+ async handleAnswer(peerId, data) {
4568
+ const peer = this.peers.get(peerId);
4569
+ if (!peer) {
4570
+ console.warn(`Received answer from unknown peer: ${peerId}`);
4571
+ return;
4572
+ }
4573
+ await peer.connection.setRemoteDescription({
4574
+ type: "answer",
4575
+ sdp: data.sdp
4576
+ });
4577
+ }
4578
+ async handleIceCandidate(peerId, data) {
4579
+ const peer = this.peers.get(peerId);
4580
+ if (!peer) {
4581
+ console.warn(`Received ICE candidate from unknown peer: ${peerId}`);
4582
+ return;
4583
+ }
4584
+ const candidate = data.candidate;
4585
+ if (candidate) {
4586
+ await peer.connection.addIceCandidate(candidate);
4587
+ }
4588
+ }
4589
+ handlePeerDisconnect(peerId) {
4590
+ const peer = this.peers.get(peerId);
4591
+ if (!peer)
4592
+ return;
4593
+ peer.dataChannel?.close();
4594
+ peer.connection.close();
4595
+ this.updatePeerState(peer, "disconnected");
4596
+ this.peers.delete(peerId);
4597
+ this.onPeerDisconnected?.(peerId);
4598
+ }
4599
+ setupConnectionHandlers(peer) {
4600
+ const connection = peer.connection;
4601
+ connection.onicecandidate = (event) => {
4602
+ if (event.candidate) {
4603
+ this.sendSignal(peer.peerId, "webrtc:ice_candidate", {
4604
+ candidate: event.candidate
4605
+ }).catch((error) => {
4606
+ console.error("Failed to send ICE candidate:", error);
4607
+ });
4608
+ }
4609
+ };
4610
+ connection.onconnectionstatechange = () => {
4611
+ const state = connection.connectionState;
4612
+ if (state === "connected") {
4613
+ peer.connectedAt = Date.now();
4614
+ this.updatePeerState(peer, "connected");
4615
+ } else if (state === "disconnected" || state === "closed") {
4616
+ this.updatePeerState(peer, "disconnected");
4617
+ this.peers.delete(peer.peerId);
4618
+ this.onPeerDisconnected?.(peer.peerId);
4619
+ } else if (state === "failed") {
4620
+ this.updatePeerState(peer, "failed");
4621
+ this.onError?.(peer.peerId, new Error("Connection failed"));
4622
+ }
4623
+ };
4624
+ connection.oniceconnectionstatechange = () => {
4625
+ if (connection.iceConnectionState === "failed") {
4626
+ this.updatePeerState(peer, "failed");
4627
+ this.onError?.(peer.peerId, new Error("ICE connection failed"));
4628
+ }
4629
+ };
4630
+ }
4631
+ setupDataChannelHandlers(peer, channel) {
4632
+ channel.onopen = () => {
4633
+ this.updatePeerState(peer, "connected");
4634
+ peer.connectedAt = Date.now();
4635
+ this.onPeerConnected?.(peer.peerId, channel);
4636
+ };
4637
+ channel.onclose = () => {
4638
+ if (peer.state === "connected") {
4639
+ this.updatePeerState(peer, "disconnected");
4640
+ this.onPeerDisconnected?.(peer.peerId);
4641
+ }
4642
+ };
4643
+ channel.onerror = (event) => {
4644
+ this.onError?.(peer.peerId, event.error);
4645
+ };
4646
+ channel.onmessage = (event) => {
4647
+ this.onPeerMessage?.(peer.peerId, event.data);
4648
+ };
4649
+ }
4650
+ updatePeerState(peer, state) {
4651
+ const oldState = peer.state;
4652
+ peer.state = state;
4653
+ if (oldState !== state) {
4654
+ this.onStateChange?.(peer.peerId, state);
4655
+ }
4656
+ }
4657
+ async sendSignal(peerId, type, data) {
4658
+ const myUserId = this.client.getUserId();
4659
+ const roomId = this.client.getCurrentRoomId();
4660
+ if (!roomId) {
4661
+ throw new Error("Cannot send WebRTC signal: not in a room");
4662
+ }
4663
+ const signalEvent = {
4664
+ id: `webrtc-${Date.now()}-${Math.random().toString(36).substring(2, 9)}`,
4665
+ type,
4666
+ timestamp: Date.now(),
4667
+ userId: myUserId || "",
4668
+ roomId,
4669
+ data: {
4670
+ ...data,
4671
+ targetPeerId: peerId
4672
+ },
4673
+ metadata: {
4674
+ userId: myUserId,
4675
+ timestamp: Date.now(),
4676
+ roomId
4677
+ }
4678
+ };
4679
+ await this.client.broadcast(signalEvent);
4680
+ }
4681
+ }
4682
+ // node_modules/ws/wrapper.mjs
4683
+ var import_stream = __toESM(require_stream(), 1);
4684
+ var import_receiver = __toESM(require_receiver(), 1);
4685
+ var import_sender = __toESM(require_sender(), 1);
4686
+ var import_websocket = __toESM(require_websocket(), 1);
4687
+ var import_websocket_server = __toESM(require_websocket_server(), 1);
4688
+
4689
+ // src/adapters/websocket/WebSocketClientTransportAdapter.ts
4690
+ class WebSocketClientTransportAdapter {
4691
+ ws;
4692
+ state = "disconnected";
4693
+ messageHandlers = new Set;
4694
+ errorHandlers = new Set;
4695
+ closeHandlers = new Set;
4696
+ config;
4697
+ heartbeatTimer;
4698
+ connectionTimer;
4699
+ constructor(config) {
4700
+ this.config = {
4701
+ headers: config?.headers ?? {},
4702
+ connectionTimeout: config?.connectionTimeout ?? 30000,
4703
+ enableHeartbeat: config?.enableHeartbeat ?? true,
4704
+ heartbeatInterval: config?.heartbeatInterval ?? 30000
4705
+ };
4706
+ }
4707
+ async connect(url, options) {
4708
+ if (this.state === "connected" || this.state === "connecting") {
4709
+ throw new Error("Already connected or connecting");
4710
+ }
4711
+ this.state = "connecting";
4712
+ return new Promise((resolve, reject) => {
4713
+ try {
4714
+ const wsOptions = {};
4715
+ if (Object.keys(this.config.headers).length > 0) {
4716
+ wsOptions.headers = this.config.headers;
4717
+ }
4718
+ this.ws = new import_websocket.default(url, wsOptions);
4719
+ this.connectionTimer = setTimeout(() => {
4720
+ if (this.state === "connecting") {
4721
+ this.ws?.terminate();
4722
+ this.state = "disconnected";
4723
+ const error = new Error("Connection timeout");
4724
+ this.errorHandlers.forEach((handler) => handler(error));
4725
+ reject(error);
4726
+ }
4727
+ }, this.config.connectionTimeout);
4728
+ this.ws.on("open", () => {
4729
+ if (this.connectionTimer) {
4730
+ clearTimeout(this.connectionTimer);
4731
+ this.connectionTimer = undefined;
4732
+ }
4733
+ this.state = "connected";
4734
+ if (this.config.enableHeartbeat) {
4735
+ this.startHeartbeat();
4736
+ }
4737
+ resolve();
4738
+ });
4739
+ this.ws.on("message", (data) => {
4740
+ try {
4741
+ const message = JSON.parse(data.toString());
4742
+ this.messageHandlers.forEach((handler) => handler(message));
4743
+ } catch (error) {
4744
+ this.errorHandlers.forEach((handler) => handler(error));
4745
+ }
4746
+ });
4747
+ this.ws.on("error", (error) => {
4748
+ if (this.connectionTimer) {
4749
+ clearTimeout(this.connectionTimer);
4750
+ this.connectionTimer = undefined;
4751
+ }
4752
+ this.errorHandlers.forEach((handler) => handler(error));
4753
+ if (this.state === "connecting") {
4754
+ this.state = "disconnected";
4755
+ reject(error);
4756
+ }
4757
+ });
4758
+ this.ws.on("close", (code, reason) => {
4759
+ if (this.connectionTimer) {
4760
+ clearTimeout(this.connectionTimer);
4761
+ this.connectionTimer = undefined;
4762
+ }
4763
+ this.stopHeartbeat();
4764
+ const wasConnected = this.state === "connected";
4765
+ this.state = "disconnected";
4766
+ if (wasConnected) {
4767
+ this.closeHandlers.forEach((handler) => handler(code, reason.toString()));
4768
+ }
4769
+ });
4770
+ if (this.config.enableHeartbeat) {
4771
+ this.ws.on("pong", () => {});
4772
+ }
4773
+ } catch (error) {
4774
+ if (this.connectionTimer) {
4775
+ clearTimeout(this.connectionTimer);
4776
+ this.connectionTimer = undefined;
4777
+ }
4778
+ this.state = "disconnected";
4779
+ reject(error);
4780
+ }
4781
+ });
4782
+ }
4783
+ async disconnect() {
4784
+ if (this.state === "disconnected") {
4785
+ return;
4786
+ }
4787
+ this.state = "disconnecting";
4788
+ this.stopHeartbeat();
4789
+ if (this.connectionTimer) {
4790
+ clearTimeout(this.connectionTimer);
4791
+ this.connectionTimer = undefined;
4792
+ }
4793
+ if (this.ws) {
4794
+ this.ws.close(1000, "Client disconnecting");
4795
+ await new Promise((resolve) => {
4796
+ const timeout = setTimeout(() => {
4797
+ this.ws?.terminate();
4798
+ resolve();
4799
+ }, 5000);
4800
+ const onClose = () => {
4801
+ clearTimeout(timeout);
4802
+ resolve();
4803
+ };
4804
+ this.ws?.once("close", onClose);
4805
+ });
4806
+ this.ws = undefined;
3902
4807
  }
3903
- const payload = await this.validateToken(token);
3904
- await this.revokeToken(token);
3905
- const newPayload = {
3906
- ...payload,
3907
- expiresAt: Date.now() + 3600000
3908
- };
3909
- return this.generateToken(newPayload);
4808
+ this.state = "disconnected";
3910
4809
  }
3911
- async revokeToken(token) {
3912
- await this.simulateDelay();
3913
- if (this.shouldFailAuth) {
3914
- throw new Error("Mock token revocation failed");
4810
+ async send(message) {
4811
+ if (this.state !== "connected") {
4812
+ throw new Error("Not connected");
4813
+ }
4814
+ if (!this.ws || this.ws.readyState !== import_websocket.default.OPEN) {
4815
+ throw new Error("WebSocket connection is not open");
4816
+ }
4817
+ try {
4818
+ const data = JSON.stringify(message);
4819
+ this.ws.send(data);
4820
+ } catch (error) {
4821
+ this.errorHandlers.forEach((handler) => handler(error));
4822
+ throw error;
3915
4823
  }
3916
- this.tokens.delete(token);
3917
- this.revokedTokens.add(token);
3918
4824
  }
3919
- getCurrentToken() {
3920
- return this.currentToken;
4825
+ onMessage(handler) {
4826
+ this.messageHandlers.add(handler);
3921
4827
  }
3922
- isAuthRequired() {
3923
- return false;
4828
+ onError(handler) {
4829
+ this.errorHandlers.add(handler);
3924
4830
  }
3925
- getAuthTimeout() {
3926
- return 1e4;
4831
+ onClose(handler) {
4832
+ this.closeHandlers.add(handler);
3927
4833
  }
3928
- async simulateDelay() {
3929
- if (this.simulateLatency > 0) {
3930
- await new Promise((resolve) => setTimeout(resolve, this.simulateLatency));
3931
- }
4834
+ getState() {
4835
+ return this.state;
3932
4836
  }
3933
- async createTestToken(userId, options) {
3934
- const payload = {
3935
- userId,
3936
- permissions: options?.permissions ?? ["read", "write"],
3937
- metadata: options?.metadata,
3938
- expiresAt: options?.expiresIn ? Date.now() + options.expiresIn : undefined
3939
- };
3940
- const token = await this.generateToken(payload);
3941
- this.currentToken = token;
3942
- return token;
4837
+ isConnected() {
4838
+ return this.state === "connected" && this.ws?.readyState === import_websocket.default.OPEN;
3943
4839
  }
3944
- getTokenCount() {
3945
- return this.tokens.size;
4840
+ getWebSocket() {
4841
+ return this.ws;
3946
4842
  }
3947
- getRevokedTokenCount() {
3948
- return this.revokedTokens.size;
4843
+ setHeaders(headers) {
4844
+ if (this.state !== "disconnected") {
4845
+ throw new Error("Cannot set headers while connected");
4846
+ }
4847
+ this.config.headers = { ...this.config.headers, ...headers };
3949
4848
  }
3950
- clearTokens() {
3951
- this.tokens.clear();
3952
- this.revokedTokens.clear();
3953
- this.currentToken = null;
4849
+ setAuthToken(token) {
4850
+ this.setHeaders({ Authorization: `Bearer ${token}` });
3954
4851
  }
3955
- setFailAuth(fail) {
3956
- this.shouldFailAuth = fail;
4852
+ startHeartbeat() {
4853
+ if (this.heartbeatTimer) {
4854
+ clearInterval(this.heartbeatTimer);
4855
+ }
4856
+ this.heartbeatTimer = setInterval(() => {
4857
+ if (this.ws && this.ws.readyState === import_websocket.default.OPEN) {
4858
+ const heartbeatMessage = {
4859
+ id: `heartbeat-${Date.now()}`,
4860
+ type: "heartbeat",
4861
+ payload: { timestamp: Date.now() },
4862
+ timestamp: Date.now()
4863
+ };
4864
+ this.ws.send(JSON.stringify(heartbeatMessage));
4865
+ }
4866
+ }, this.config.heartbeatInterval);
3957
4867
  }
3958
- setCurrentToken(token) {
3959
- this.currentToken = token;
4868
+ stopHeartbeat() {
4869
+ if (this.heartbeatTimer) {
4870
+ clearInterval(this.heartbeatTimer);
4871
+ this.heartbeatTimer = undefined;
4872
+ }
3960
4873
  }
3961
4874
  }
3962
- // node_modules/ws/wrapper.mjs
3963
- var import_stream = __toESM(require_stream(), 1);
3964
- var import_receiver = __toESM(require_receiver(), 1);
3965
- var import_sender = __toESM(require_sender(), 1);
3966
- var import_websocket = __toESM(require_websocket(), 1);
3967
- var import_websocket_server = __toESM(require_websocket_server(), 1);
3968
-
3969
4875
  // src/adapters/websocket/WebSocketServerTransportAdapter.ts
3970
4876
  class WebSocketServerTransportAdapter {
3971
4877
  state = "disconnected";
@@ -4325,8 +5231,8 @@ class WebSocketServerTransportAdapter {
4325
5231
  return Math.random().toString(36).substring(2) + Date.now().toString(36);
4326
5232
  }
4327
5233
  }
4328
- // src/adapters/websocket/WebSocketClientTransportAdapter.ts
4329
- class WebSocketClientTransportAdapter {
5234
+ // src/adapters/websocket/BrowserWebSocketTransportAdapter.ts
5235
+ class BrowserWebSocketTransportAdapter {
4330
5236
  ws;
4331
5237
  state = "disconnected";
4332
5238
  messageHandlers = new Set;
@@ -4335,36 +5241,38 @@ class WebSocketClientTransportAdapter {
4335
5241
  config;
4336
5242
  heartbeatTimer;
4337
5243
  connectionTimer;
5244
+ authToken;
4338
5245
  constructor(config) {
4339
5246
  this.config = {
4340
- headers: config?.headers ?? {},
4341
5247
  connectionTimeout: config?.connectionTimeout ?? 30000,
4342
5248
  enableHeartbeat: config?.enableHeartbeat ?? true,
4343
- heartbeatInterval: config?.heartbeatInterval ?? 30000
5249
+ heartbeatInterval: config?.heartbeatInterval ?? 30000,
5250
+ authToken: config?.authToken
4344
5251
  };
5252
+ this.authToken = config?.authToken;
4345
5253
  }
4346
- async connect(url, options) {
5254
+ setAuthToken(token) {
5255
+ this.authToken = token;
5256
+ }
5257
+ async connect(url, _options) {
4347
5258
  if (this.state === "connected" || this.state === "connecting") {
4348
5259
  throw new Error("Already connected or connecting");
4349
5260
  }
4350
5261
  this.state = "connecting";
4351
5262
  return new Promise((resolve, reject) => {
4352
5263
  try {
4353
- const wsOptions = {};
4354
- if (Object.keys(this.config.headers).length > 0) {
4355
- wsOptions.headers = this.config.headers;
4356
- }
4357
- this.ws = new import_websocket.default(url, wsOptions);
4358
- this.connectionTimer = setTimeout(() => {
5264
+ const wsUrl = this.authToken ? `${url}${url.includes("?") ? "&" : "?"}token=${encodeURIComponent(this.authToken)}` : url;
5265
+ this.ws = new WebSocket(wsUrl);
5266
+ this.connectionTimer = window.setTimeout(() => {
4359
5267
  if (this.state === "connecting") {
4360
- this.ws?.terminate();
5268
+ this.ws?.close();
4361
5269
  this.state = "disconnected";
4362
5270
  const error = new Error("Connection timeout");
4363
5271
  this.errorHandlers.forEach((handler) => handler(error));
4364
5272
  reject(error);
4365
5273
  }
4366
5274
  }, this.config.connectionTimeout);
4367
- this.ws.on("open", () => {
5275
+ this.ws.onopen = () => {
4368
5276
  if (this.connectionTimer) {
4369
5277
  clearTimeout(this.connectionTimer);
4370
5278
  this.connectionTimer = undefined;
@@ -4374,41 +5282,44 @@ class WebSocketClientTransportAdapter {
4374
5282
  this.startHeartbeat();
4375
5283
  }
4376
5284
  resolve();
4377
- });
4378
- this.ws.on("message", (data) => {
5285
+ };
5286
+ this.ws.onmessage = (event) => {
4379
5287
  try {
4380
- const message = JSON.parse(data.toString());
5288
+ const message = JSON.parse(event.data);
4381
5289
  this.messageHandlers.forEach((handler) => handler(message));
4382
5290
  } catch (error) {
4383
- this.errorHandlers.forEach((handler) => handler(error));
5291
+ const err = new Error(`Failed to parse message: ${error}`);
5292
+ this.errorHandlers.forEach((handler) => handler(err));
4384
5293
  }
4385
- });
4386
- this.ws.on("error", (error) => {
5294
+ };
5295
+ this.ws.onerror = (_event) => {
4387
5296
  if (this.connectionTimer) {
4388
5297
  clearTimeout(this.connectionTimer);
4389
5298
  this.connectionTimer = undefined;
4390
5299
  }
5300
+ const error = new Error("WebSocket error occurred");
4391
5301
  this.errorHandlers.forEach((handler) => handler(error));
4392
5302
  if (this.state === "connecting") {
4393
5303
  this.state = "disconnected";
4394
5304
  reject(error);
4395
5305
  }
4396
- });
4397
- this.ws.on("close", (code, reason) => {
5306
+ };
5307
+ this.ws.onclose = (event) => {
4398
5308
  if (this.connectionTimer) {
4399
5309
  clearTimeout(this.connectionTimer);
4400
5310
  this.connectionTimer = undefined;
4401
5311
  }
4402
5312
  this.stopHeartbeat();
4403
5313
  const wasConnected = this.state === "connected";
5314
+ const wasConnecting = this.state === "connecting";
4404
5315
  this.state = "disconnected";
4405
5316
  if (wasConnected) {
4406
- this.closeHandlers.forEach((handler) => handler(code, reason.toString()));
5317
+ this.closeHandlers.forEach((handler) => handler(event.code, event.reason || "Connection closed"));
4407
5318
  }
4408
- });
4409
- if (this.config.enableHeartbeat) {
4410
- this.ws.on("pong", () => {});
4411
- }
5319
+ if (wasConnecting) {
5320
+ reject(new Error(`Connection closed: ${event.reason}`));
5321
+ }
5322
+ };
4412
5323
  } catch (error) {
4413
5324
  if (this.connectionTimer) {
4414
5325
  clearTimeout(this.connectionTimer);
@@ -4433,14 +5344,18 @@ class WebSocketClientTransportAdapter {
4433
5344
  this.ws.close(1000, "Client disconnecting");
4434
5345
  await new Promise((resolve) => {
4435
5346
  const timeout = setTimeout(() => {
4436
- this.ws?.terminate();
4437
5347
  resolve();
4438
5348
  }, 5000);
4439
5349
  const onClose = () => {
4440
5350
  clearTimeout(timeout);
4441
5351
  resolve();
4442
5352
  };
4443
- this.ws?.once("close", onClose);
5353
+ if (this.ws) {
5354
+ this.ws.addEventListener("close", onClose, { once: true });
5355
+ } else {
5356
+ clearTimeout(timeout);
5357
+ resolve();
5358
+ }
4444
5359
  });
4445
5360
  this.ws = undefined;
4446
5361
  }
@@ -4450,7 +5365,7 @@ class WebSocketClientTransportAdapter {
4450
5365
  if (this.state !== "connected") {
4451
5366
  throw new Error("Not connected");
4452
5367
  }
4453
- if (!this.ws || this.ws.readyState !== import_websocket.default.OPEN) {
5368
+ if (!this.ws || this.ws.readyState !== WebSocket.OPEN) {
4454
5369
  throw new Error("WebSocket connection is not open");
4455
5370
  }
4456
5371
  try {
@@ -4474,26 +5389,17 @@ class WebSocketClientTransportAdapter {
4474
5389
  return this.state;
4475
5390
  }
4476
5391
  isConnected() {
4477
- return this.state === "connected" && this.ws?.readyState === import_websocket.default.OPEN;
5392
+ return this.state === "connected" && this.ws?.readyState === WebSocket.OPEN;
4478
5393
  }
4479
5394
  getWebSocket() {
4480
5395
  return this.ws;
4481
5396
  }
4482
- setHeaders(headers) {
4483
- if (this.state !== "disconnected") {
4484
- throw new Error("Cannot set headers while connected");
4485
- }
4486
- this.config.headers = { ...this.config.headers, ...headers };
4487
- }
4488
- setAuthToken(token) {
4489
- this.setHeaders({ Authorization: `Bearer ${token}` });
4490
- }
4491
5397
  startHeartbeat() {
4492
5398
  if (this.heartbeatTimer) {
4493
5399
  clearInterval(this.heartbeatTimer);
4494
5400
  }
4495
- this.heartbeatTimer = setInterval(() => {
4496
- if (this.ws && this.ws.readyState === import_websocket.default.OPEN) {
5401
+ this.heartbeatTimer = window.setInterval(() => {
5402
+ if (this.ws && this.ws.readyState === WebSocket.OPEN) {
4497
5403
  const heartbeatMessage = {
4498
5404
  id: `heartbeat-${Date.now()}`,
4499
5405
  type: "heartbeat",
@@ -4511,6 +5417,24 @@ class WebSocketClientTransportAdapter {
4511
5417
  }
4512
5418
  }
4513
5419
  }
5420
+ // src/types/room.ts
5421
+ function serializeRoomState(state) {
5422
+ return {
5423
+ room: state.room,
5424
+ users: Object.fromEntries(state.users),
5425
+ eventHistory: state.eventHistory,
5426
+ locks: Object.fromEntries(state.locks)
5427
+ };
5428
+ }
5429
+ function deserializeRoomState(serialized) {
5430
+ return {
5431
+ room: serialized.room,
5432
+ users: new Map(Object.entries(serialized.users)),
5433
+ eventHistory: serialized.eventHistory,
5434
+ locks: new Map(Object.entries(serialized.locks))
5435
+ };
5436
+ }
5437
+
4514
5438
  // src/client/BaseClient.ts
4515
5439
  class BaseClient extends TypedEventEmitter {
4516
5440
  transport;
@@ -4595,7 +5519,10 @@ class BaseClient extends TypedEventEmitter {
4595
5519
  this.authToken = null;
4596
5520
  this.userId = null;
4597
5521
  this.reconnectAttempts = 0;
4598
- await this.emit("disconnected", { code: 1000, reason: "Client disconnected" });
5522
+ await this.emit("disconnected", {
5523
+ code: 1000,
5524
+ reason: "Client disconnected"
5525
+ });
4599
5526
  }
4600
5527
  }
4601
5528
  async reconnect() {
@@ -4764,14 +5691,19 @@ class BaseClient extends TypedEventEmitter {
4764
5691
  }
4765
5692
  await this.emit("authenticated", { userId: this.userId || "" });
4766
5693
  } else {
4767
- await this.emit("authentication_failed", { error: payload.error || "Authentication failed" });
5694
+ await this.emit("authentication_failed", {
5695
+ error: payload.error || "Authentication failed"
5696
+ });
4768
5697
  }
4769
5698
  }
4770
5699
  async handleRoomJoined(payload) {
4771
5700
  this.currentRoomId = payload.roomId;
4772
5701
  const roomState = deserializeRoomState(payload.state);
4773
5702
  this.currentRoomState = roomState;
4774
- await this.emit("room_joined", { roomId: payload.roomId, state: roomState });
5703
+ await this.emit("room_joined", {
5704
+ roomId: payload.roomId,
5705
+ state: roomState
5706
+ });
4775
5707
  }
4776
5708
  async handleRoomLeft(payload) {
4777
5709
  if (this.currentRoomId === payload.roomId) {
@@ -4965,6 +5897,30 @@ class PresenceClient extends TypedEventEmitter {
4965
5897
  });
4966
5898
  }
4967
5899
  }
5900
+ // src/types/experimental.ts
5901
+ class ExperimentalFeatureError extends Error {
5902
+ feature;
5903
+ configKey;
5904
+ constructor(feature, configKey) {
5905
+ super(`Experimental feature '${feature}' is not enabled.
5906
+
5907
+ ` + `To enable, set '${String(configKey)}: true' in your server configuration:
5908
+
5909
+ ` + ` const server = new ServerBuilder()
5910
+ ` + ` .withExperimentalFeatures({ ${String(configKey)}: true })
5911
+ ` + ` .build();
5912
+
5913
+ ` + `⚠️ WARNING: Experimental APIs are for development only.
5914
+ ` + `For production use, submit a feature request:
5915
+ ` + `https://github.com/your-org/control-tower-core/issues/new
5916
+
5917
+ ` + `See docs/EXPERIMENTAL_BROADCAST.md for details.`);
5918
+ this.feature = feature;
5919
+ this.configKey = configKey;
5920
+ this.name = "ExperimentalFeatureError";
5921
+ }
5922
+ }
5923
+
4968
5924
  // src/server/ExperimentalAPI.ts
4969
5925
  class ExperimentalAPI {
4970
5926
  config;
@@ -5198,12 +6154,17 @@ class BaseServer extends TypedEventEmitter {
5198
6154
  throw new Error("Server is already running");
5199
6155
  }
5200
6156
  try {
5201
- await this.transport.connect(`ws://localhost:${port}`, { url: `ws://localhost:${port}` });
6157
+ await this.transport.connect(`ws://localhost:${port}`, {
6158
+ url: `ws://localhost:${port}`
6159
+ });
5202
6160
  this.running = true;
5203
6161
  this.initialized = true;
5204
6162
  await this.emit("started", { port });
5205
6163
  } catch (error) {
5206
- await this.emit("error", { error, context: "server_start" });
6164
+ await this.emit("error", {
6165
+ error,
6166
+ context: "server_start"
6167
+ });
5207
6168
  throw error;
5208
6169
  }
5209
6170
  }
@@ -5235,7 +6196,10 @@ class BaseServer extends TypedEventEmitter {
5235
6196
  this.initialized = true;
5236
6197
  await this.emit("started", { port: 0 });
5237
6198
  } catch (error) {
5238
- await this.emit("error", { error, context: "server_initialize" });
6199
+ await this.emit("error", {
6200
+ error,
6201
+ context: "server_initialize"
6202
+ });
5239
6203
  throw error;
5240
6204
  }
5241
6205
  }
@@ -5251,7 +6215,10 @@ class BaseServer extends TypedEventEmitter {
5251
6215
  try {
5252
6216
  await this.transport.disconnect();
5253
6217
  } catch (error) {
5254
- await this.emit("error", { error, context: "server_stop" });
6218
+ await this.emit("error", {
6219
+ error,
6220
+ context: "server_stop"
6221
+ });
5255
6222
  }
5256
6223
  this.clients.clear();
5257
6224
  this.clientMessageHandlers.clear();
@@ -5478,10 +6445,16 @@ class BaseServer extends TypedEventEmitter {
5478
6445
  await this.handleLockRelease(clientId, message.payload);
5479
6446
  break;
5480
6447
  case "ping":
5481
- await this.sendToClient(clientId, { type: "pong", timestamp: Date.now() });
6448
+ await this.sendToClient(clientId, {
6449
+ type: "pong",
6450
+ timestamp: Date.now()
6451
+ });
5482
6452
  break;
5483
6453
  case "heartbeat":
5484
- await this.sendToClient(clientId, { type: "heartbeat_ack", timestamp: Date.now() });
6454
+ await this.sendToClient(clientId, {
6455
+ type: "heartbeat_ack",
6456
+ timestamp: Date.now()
6457
+ });
5485
6458
  break;
5486
6459
  default:
5487
6460
  await this.sendToClient(clientId, {
@@ -5494,13 +6467,20 @@ class BaseServer extends TypedEventEmitter {
5494
6467
  type: "error",
5495
6468
  error: error.message
5496
6469
  });
5497
- await this.emit("error", { error, context: `client_${clientId}` });
6470
+ await this.emit("error", {
6471
+ error,
6472
+ context: `client_${clientId}`
6473
+ });
5498
6474
  }
5499
6475
  };
5500
6476
  }
5501
6477
  async handleAuthenticate(clientId, payload) {
5502
6478
  if (!this.auth) {
5503
- await this.sendToClient(clientId, { type: "auth_result", success: false, error: "Authentication not configured" });
6479
+ await this.sendToClient(clientId, {
6480
+ type: "auth_result",
6481
+ success: false,
6482
+ error: "Authentication not configured"
6483
+ });
5504
6484
  return;
5505
6485
  }
5506
6486
  try {
@@ -5509,15 +6489,28 @@ class BaseServer extends TypedEventEmitter {
5509
6489
  if (client) {
5510
6490
  client.userId = tokenPayload.userId;
5511
6491
  client.authenticated = true;
6492
+ this.clientUserMap.set(clientId, tokenPayload.userId);
6493
+ if (!this.userClientMap.has(tokenPayload.userId)) {
6494
+ this.userClientMap.set(tokenPayload.userId, new Set);
6495
+ }
6496
+ this.userClientMap.get(tokenPayload.userId).add(clientId);
5512
6497
  await this.emit("client_authenticated", {
5513
6498
  clientId,
5514
6499
  userId: tokenPayload.userId,
5515
6500
  metadata: tokenPayload.metadata
5516
6501
  });
5517
6502
  }
5518
- await this.sendToClient(clientId, { type: "auth_result", success: true, userId: tokenPayload.userId });
6503
+ await this.sendToClient(clientId, {
6504
+ type: "auth_result",
6505
+ success: true,
6506
+ userId: tokenPayload.userId
6507
+ });
5519
6508
  } catch (error) {
5520
- await this.sendToClient(clientId, { type: "auth_result", success: false, error: error.message });
6509
+ await this.sendToClient(clientId, {
6510
+ type: "auth_result",
6511
+ success: false,
6512
+ error: error.message
6513
+ });
5521
6514
  }
5522
6515
  }
5523
6516
  async handleJoinRoom(clientId, payload) {
@@ -5529,17 +6522,26 @@ class BaseServer extends TypedEventEmitter {
5529
6522
  await this.handleAuthenticate(clientId, { token: payload.token });
5530
6523
  }
5531
6524
  if (!client.authenticated) {
5532
- await this.sendToClient(clientId, { type: "error", error: "Authentication required to join room" });
6525
+ await this.sendToClient(clientId, {
6526
+ type: "error",
6527
+ error: "Authentication required to join room"
6528
+ });
5533
6529
  return;
5534
6530
  }
5535
6531
  try {
5536
6532
  if (client.roomIds.has(payload.roomId)) {
5537
- await this.sendToClient(clientId, { type: "error", error: "Already in this room" });
6533
+ await this.sendToClient(clientId, {
6534
+ type: "error",
6535
+ error: "Already in this room"
6536
+ });
5538
6537
  return;
5539
6538
  }
5540
6539
  let roomState = await this.roomManager.getRoomState(payload.roomId);
5541
6540
  if (!roomState) {
5542
- const roomConfig = { ...this.config.defaultRoomConfig, id: payload.roomId };
6541
+ const roomConfig = {
6542
+ ...this.config.defaultRoomConfig,
6543
+ id: payload.roomId
6544
+ };
5543
6545
  const room = await this.roomManager.createRoom(payload.roomId, roomConfig);
5544
6546
  roomState = await this.roomManager.getRoomState(payload.roomId);
5545
6547
  await this.emit("room_created", { room });
@@ -5557,7 +6559,10 @@ class BaseServer extends TypedEventEmitter {
5557
6559
  };
5558
6560
  await this.roomManager.joinRoom(payload.roomId, user);
5559
6561
  client.roomIds.add(payload.roomId);
5560
- await this.emit("client_joined_room", { clientId, roomId: payload.roomId });
6562
+ await this.emit("client_joined_room", {
6563
+ clientId,
6564
+ roomId: payload.roomId
6565
+ });
5561
6566
  const updatedRoomState = await this.roomManager.getRoomState(payload.roomId);
5562
6567
  if (!updatedRoomState) {
5563
6568
  throw new Error("Failed to get updated room state after joining");
@@ -5576,7 +6581,10 @@ class BaseServer extends TypedEventEmitter {
5576
6581
  });
5577
6582
  }
5578
6583
  } catch (error) {
5579
- await this.sendToClient(clientId, { type: "error", error: error.message });
6584
+ await this.sendToClient(clientId, {
6585
+ type: "error",
6586
+ error: error.message
6587
+ });
5580
6588
  }
5581
6589
  }
5582
6590
  async handleLeaveRoom(clientId, payload) {
@@ -5601,7 +6609,10 @@ class BaseServer extends TypedEventEmitter {
5601
6609
  async handleBroadcastEvent(clientId, payload) {
5602
6610
  const client = this.clients.get(clientId);
5603
6611
  if (!client || !client.roomIds.has(payload.roomId)) {
5604
- await this.sendToClient(clientId, { type: "error", error: "Not in specified room" });
6612
+ await this.sendToClient(clientId, {
6613
+ type: "error",
6614
+ error: "Not in specified room"
6615
+ });
5605
6616
  return;
5606
6617
  }
5607
6618
  const enrichedEvent = {
@@ -5624,7 +6635,10 @@ class BaseServer extends TypedEventEmitter {
5624
6635
  async handleLockRequest(clientId, payload) {
5625
6636
  const client = this.clients.get(clientId);
5626
6637
  if (!client || !client.roomIds.has(payload.roomId)) {
5627
- await this.sendToClient(clientId, { type: "error", error: "Not in specified room" });
6638
+ await this.sendToClient(clientId, {
6639
+ type: "error",
6640
+ error: "Not in specified room"
6641
+ });
5628
6642
  return;
5629
6643
  }
5630
6644
  try {
@@ -5638,10 +6652,18 @@ class BaseServer extends TypedEventEmitter {
5638
6652
  userId: client.userId,
5639
6653
  roomId: payload.roomId,
5640
6654
  data: { lock, action: "acquired" },
5641
- metadata: { userId: client.userId, timestamp: Date.now(), roomId: payload.roomId }
6655
+ metadata: {
6656
+ userId: client.userId,
6657
+ timestamp: Date.now(),
6658
+ roomId: payload.roomId
6659
+ }
5642
6660
  });
5643
6661
  } catch (error) {
5644
- await this.sendToClient(clientId, { type: "lock_denied", request: payload.request, reason: error.message });
6662
+ await this.sendToClient(clientId, {
6663
+ type: "lock_denied",
6664
+ request: payload.request,
6665
+ reason: error.message
6666
+ });
5645
6667
  }
5646
6668
  }
5647
6669
  async handleLockRelease(clientId, payload) {
@@ -5652,7 +6674,10 @@ class BaseServer extends TypedEventEmitter {
5652
6674
  try {
5653
6675
  await this.lockManager.releaseLock(payload.lockId);
5654
6676
  await this.emit("lock_released", { lockId: payload.lockId, clientId });
5655
- await this.sendToClient(clientId, { type: "lock_released", lockId: payload.lockId });
6677
+ await this.sendToClient(clientId, {
6678
+ type: "lock_released",
6679
+ lockId: payload.lockId
6680
+ });
5656
6681
  for (const roomId of client.roomIds) {
5657
6682
  await this.roomManager.broadcastToRoom(roomId, {
5658
6683
  id: this.generateId(),
@@ -5665,7 +6690,10 @@ class BaseServer extends TypedEventEmitter {
5665
6690
  });
5666
6691
  }
5667
6692
  } catch (error) {
5668
- await this.sendToClient(clientId, { type: "error", error: error.message });
6693
+ await this.sendToClient(clientId, {
6694
+ type: "error",
6695
+ error: error.message
6696
+ });
5669
6697
  }
5670
6698
  }
5671
6699
  async sendToClient(clientId, message) {
@@ -5871,6 +6899,7 @@ class ServerBuilder {
5871
6899
  export {
5872
6900
  WebSocketServerTransportAdapter,
5873
6901
  WebSocketClientTransportAdapter,
6902
+ WebRTCSignalingAdapter,
5874
6903
  TypedEventEmitter,
5875
6904
  ServerBuilder,
5876
6905
  RoomManager,
@@ -5878,6 +6907,8 @@ export {
5878
6907
  PresenceClient,
5879
6908
  MockTransportAdapter,
5880
6909
  MockStorageAdapter,
6910
+ MockRTCPeerConnection,
6911
+ MockRTCDataChannel,
5881
6912
  MockAuthAdapter,
5882
6913
  LockManager,
5883
6914
  ExperimentalFeatureError,
@@ -5886,8 +6917,9 @@ export {
5886
6917
  DefaultPresenceManager,
5887
6918
  DefaultLockManager,
5888
6919
  ClientBuilder,
6920
+ BrowserWebSocketTransportAdapter,
5889
6921
  BaseServer,
5890
6922
  BaseClient
5891
6923
  };
5892
6924
 
5893
- //# debugId=144E7B07131D042564756E2164756E21
6925
+ //# debugId=94389897A03B4D7064756E2164756E21