@adhdev/session-host-core 1.0.82-rc.26 → 1.0.82-rc.27

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -746,6 +746,19 @@ function disconnectSessionHostClients(endpoint, error) {
746
746
  }
747
747
  }
748
748
  }
749
+ function findConnectedSessionHostClient(endpoint) {
750
+ for (const ref of activeClientRefs) {
751
+ const client = ref.deref();
752
+ if (!client) {
753
+ activeClientRefs.delete(ref);
754
+ continue;
755
+ }
756
+ if ((!endpoint || client.endpoint.path === endpoint.path) && client.isConnected()) {
757
+ return client;
758
+ }
759
+ }
760
+ return null;
761
+ }
749
762
  var SessionHostClient = class {
750
763
  endpoint;
751
764
  socket = null;
@@ -763,11 +776,17 @@ var SessionHostClient = class {
763
776
  if (typeof options.requestTimeoutMs === "number" && options.requestTimeoutMs > 0) {
764
777
  this.requestTimeoutMs = options.requestTimeoutMs;
765
778
  }
766
- activeClientRefs.add(new WeakRef(this));
779
+ if (options.registerAsShared !== false) activeClientRefs.add(new WeakRef(this));
767
780
  }
768
781
  static disconnectClients(endpoint, error) {
769
782
  disconnectSessionHostClients(endpoint, error);
770
783
  }
784
+ static findConnectedClient(endpoint) {
785
+ return findConnectedSessionHostClient(endpoint);
786
+ }
787
+ isConnected() {
788
+ return Boolean(this.socket && !this.socket.destroyed && establishedSockets.has(this.socket));
789
+ }
771
790
  /**
772
791
  * Fires when an established connection to the session host goes away.
773
792
  *
@@ -829,18 +848,17 @@ var SessionHostClient = class {
829
848
  }
830
849
  }
831
850
  }
832
- sendRawRequestOnSocket(socket, request) {
851
+ sendRawRequestOnSocket(socket, request, timeoutMs = this.requestTimeoutMs) {
833
852
  const requestId = generateUUID();
834
853
  const envelope = {
835
854
  kind: "request",
836
855
  requestId,
837
856
  request
838
857
  };
839
- const timeoutMs = this.requestTimeoutMs > 0 ? this.requestTimeoutMs : 3e4;
840
858
  const timeoutLabel = timeoutMs % 1e3 === 0 ? `${timeoutMs / 1e3}s` : `${timeoutMs}ms`;
841
859
  return new Promise((resolve3, reject) => {
842
860
  const timeout = setTimeout(() => {
843
- const timeoutError = new Error(`Session host request timed out after ${timeoutLabel} (${request.type})`);
861
+ const timeoutError = Object.assign(new Error(`Session host request timed out after ${timeoutLabel} (${request.type})`), { code: "SESSION_HOST_REQUEST_TIMEOUT", requestType: request.type });
844
862
  if (this.socket === socket) {
845
863
  this.disconnect(timeoutError);
846
864
  } else {
@@ -866,7 +884,7 @@ var SessionHostClient = class {
866
884
  socket.write(serializeEnvelope(envelope));
867
885
  });
868
886
  }
869
- async connect() {
887
+ async connect(timeoutMs = this.requestTimeoutMs) {
870
888
  if (this.socket && !this.socket.destroyed) {
871
889
  if (this.connectPromise) await this.connectPromise;
872
890
  return;
@@ -914,11 +932,30 @@ var SessionHostClient = class {
914
932
  });
915
933
  const connectTask = (async () => {
916
934
  await new Promise((resolve3, reject) => {
917
- socket.once("connect", () => {
935
+ const cleanup = () => {
936
+ clearTimeout(timer);
937
+ socket.off("connect", connected);
938
+ socket.off("error", failed);
939
+ socket.off("close", closed);
940
+ };
941
+ const connected = () => {
942
+ cleanup();
918
943
  establishedSockets.add(socket);
919
944
  resolve3();
920
- });
921
- socket.once("error", reject);
945
+ };
946
+ const failed = (error) => {
947
+ cleanup();
948
+ reject(error);
949
+ };
950
+ const closed = () => failed(new Error("Session host connection closed before connect"));
951
+ const timer = setTimeout(() => {
952
+ const error = Object.assign(new Error(`Session host connect timed out after ${timeoutMs}ms`), { code: "SESSION_HOST_CONNECT_TIMEOUT" });
953
+ failed(error);
954
+ if (this.socket === socket) this.disconnect(error);
955
+ }, timeoutMs);
956
+ socket.once("connect", connected);
957
+ socket.once("error", failed);
958
+ socket.once("close", closed);
922
959
  });
923
960
  if (this.attachedSessions.size > 0 && this.socket === socket && !socket.destroyed) {
924
961
  for (const [sessionId, sub] of [...this.attachedSessions.entries()]) {
@@ -948,11 +985,32 @@ var SessionHostClient = class {
948
985
  this.eventListeners.delete(listener);
949
986
  };
950
987
  }
951
- async request(request) {
952
- await this.connect();
988
+ async request(request, options = {}) {
989
+ const timeoutMs = Math.max(1, options.timeoutMs ?? this.requestTimeoutMs);
990
+ const deadline = Date.now() + timeoutMs;
991
+ const alreadyConnected = this.isConnected() && !this.connectPromise;
992
+ if (options.timeoutMs !== void 0) {
993
+ let timer;
994
+ try {
995
+ await Promise.race([
996
+ this.connect(timeoutMs),
997
+ new Promise((_resolve, reject) => {
998
+ timer = setTimeout(() => {
999
+ const error = Object.assign(new Error(`Session host connect timed out after ${timeoutMs}ms`), { code: "SESSION_HOST_CONNECT_TIMEOUT" });
1000
+ reject(error);
1001
+ this.disconnect(error);
1002
+ }, timeoutMs);
1003
+ })
1004
+ ]);
1005
+ } finally {
1006
+ if (timer) clearTimeout(timer);
1007
+ }
1008
+ } else {
1009
+ await this.connect(timeoutMs);
1010
+ }
953
1011
  const requestSocket = this.socket;
954
1012
  if (!requestSocket) throw new Error("Session host socket unavailable");
955
- const response = await this.sendRawRequestOnSocket(requestSocket, request);
1013
+ const response = await this.sendRawRequestOnSocket(requestSocket, request, options.timeoutMs === void 0 || alreadyConnected ? timeoutMs : Math.max(1, deadline - Date.now()));
956
1014
  if (response.success) {
957
1015
  if (request.type === "attach_session") {
958
1016
  this.attachedSessions.set(request.payload.sessionId, {
@@ -1212,6 +1270,7 @@ export {
1212
1270
  createSessionHostControlPlane,
1213
1271
  disconnectSessionHostClients,
1214
1272
  ensureNodePtySpawnHelperPermissions,
1273
+ findConnectedSessionHostClient,
1215
1274
  formatRuntimeOwner,
1216
1275
  getDefaultSessionHostEndpoint,
1217
1276
  getSessionHostRecoveryLabel,