@adhdev/session-host-core 1.0.82-rc.26 → 1.0.82-rc.29
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.d.mts +33 -3
- package/dist/index.d.ts +33 -3
- package/dist/index.js +115 -11
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +114 -11
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/index.ts +4 -0
- package/src/ipc.ts +112 -12
- package/src/types.ts +11 -0
package/dist/index.d.mts
CHANGED
|
@@ -148,6 +148,26 @@ interface ResizeSessionPayload {
|
|
|
148
148
|
interface StopSessionPayload {
|
|
149
149
|
sessionId: string;
|
|
150
150
|
}
|
|
151
|
+
interface MeshWriterAssignment {
|
|
152
|
+
meshId: string;
|
|
153
|
+
nodeId: string;
|
|
154
|
+
taskId: string;
|
|
155
|
+
attemptId: string;
|
|
156
|
+
generation: number;
|
|
157
|
+
dispatchNonce: number;
|
|
158
|
+
ownerDaemonId: string;
|
|
159
|
+
}
|
|
160
|
+
interface MeshWriterStopTarget {
|
|
161
|
+
runtimeKey: string;
|
|
162
|
+
startedAt: number;
|
|
163
|
+
osPid: number;
|
|
164
|
+
providerType: string;
|
|
165
|
+
assignment: MeshWriterAssignment;
|
|
166
|
+
}
|
|
167
|
+
interface StopMeshWriterPayload extends MeshWriterStopTarget {
|
|
168
|
+
sessionId: string;
|
|
169
|
+
clientId: string;
|
|
170
|
+
}
|
|
151
171
|
interface DeleteSessionPayload {
|
|
152
172
|
sessionId: string;
|
|
153
173
|
/** Stop a live runtime before deleting the persisted record. */
|
|
@@ -304,6 +324,9 @@ type SessionHostRequest = {
|
|
|
304
324
|
} | {
|
|
305
325
|
type: 'stop_session';
|
|
306
326
|
payload: StopSessionPayload;
|
|
327
|
+
} | {
|
|
328
|
+
type: 'stop_mesh_writer';
|
|
329
|
+
payload: StopMeshWriterPayload;
|
|
307
330
|
} | {
|
|
308
331
|
type: 'delete_session';
|
|
309
332
|
payload: DeleteSessionPayload;
|
|
@@ -663,6 +686,8 @@ interface SessionHostClientOptions {
|
|
|
663
686
|
endpoint?: SessionHostEndpoint;
|
|
664
687
|
appName?: string;
|
|
665
688
|
requestTimeoutMs?: number;
|
|
689
|
+
/** Join the shared client registry (default true). Disable for short-lived probes. */
|
|
690
|
+
registerAsShared?: boolean;
|
|
666
691
|
}
|
|
667
692
|
/**
|
|
668
693
|
* Why an established session-host connection went away.
|
|
@@ -672,6 +697,7 @@ interface SessionHostClientOptions {
|
|
|
672
697
|
*/
|
|
673
698
|
type SessionHostDisconnectReason = 'error' | 'ended' | 'closed';
|
|
674
699
|
declare function disconnectSessionHostClients(endpoint?: SessionHostEndpoint, error?: Error): void;
|
|
700
|
+
declare function findConnectedSessionHostClient(endpoint?: SessionHostEndpoint): SessionHostClient | null;
|
|
675
701
|
interface SessionHostDisconnectInfo {
|
|
676
702
|
reason: SessionHostDisconnectReason;
|
|
677
703
|
endpointPath: string;
|
|
@@ -703,6 +729,8 @@ declare class SessionHostClient {
|
|
|
703
729
|
private attachedSessions;
|
|
704
730
|
constructor(options?: SessionHostClientOptions);
|
|
705
731
|
static disconnectClients(endpoint?: SessionHostEndpoint, error?: Error): void;
|
|
732
|
+
static findConnectedClient(endpoint?: SessionHostEndpoint): SessionHostClient | null;
|
|
733
|
+
isConnected(): boolean;
|
|
706
734
|
/**
|
|
707
735
|
* Fires when an established connection to the session host goes away.
|
|
708
736
|
*
|
|
@@ -718,9 +746,11 @@ declare class SessionHostClient {
|
|
|
718
746
|
onDisconnect(listener: (info: SessionHostDisconnectInfo) => void): () => void;
|
|
719
747
|
private handleDisconnect;
|
|
720
748
|
private sendRawRequestOnSocket;
|
|
721
|
-
connect(): Promise<void>;
|
|
749
|
+
connect(timeoutMs?: number): Promise<void>;
|
|
722
750
|
onEvent(listener: (event: SessionHostEvent) => void): () => void;
|
|
723
|
-
request<T = unknown>(request: SessionHostRequest
|
|
751
|
+
request<T = unknown>(request: SessionHostRequest, options?: {
|
|
752
|
+
timeoutMs?: number;
|
|
753
|
+
}): Promise<SessionHostResponse<T>>;
|
|
724
754
|
disconnect(error?: Error): void;
|
|
725
755
|
close(): Promise<void>;
|
|
726
756
|
}
|
|
@@ -880,4 +910,4 @@ interface SessionHostControlTransport {
|
|
|
880
910
|
*/
|
|
881
911
|
declare function createSessionHostControlPlane(transport: SessionHostControlTransport): SessionHostControlPlane;
|
|
882
912
|
|
|
883
|
-
export { type AcquireWritePayload, type AttachSessionPayload, CLI_CHILD_NICE_ENV, CLI_CHILD_NICE_INCREMENT, CLI_CHILD_SCHEDULING_ENV, type ClearSessionBufferPayload, type CreateSessionPayload, DEFAULT_CONFIG_DIR_NAME, DEFAULT_SESSION_RING_BUFFER_MAX_BYTES, type DetachSessionPayload, type ForceDetachClientPayload, type GetHostDiagnosticsPayload, type GetSnapshotPayload, type GetTerminalSnapshotPayload, type HostUpgradeLeasePayload, type PruneDuplicateSessionsPayload, type ReleaseWritePayload, type ResizeSessionPayload, type RestartSessionPayload, type ResumeSessionPayload, SESSION_HOST_SUPPORTED_REQUEST_TYPES, type SendInputPayload, type SendSignalPayload, type SessionAttachedClient, type SessionBufferSnapshot, type SessionClientType, type SessionHostCategory, SessionHostClient, type SessionHostClientOptions, type SessionHostControlPlane, type SessionHostControlTransport, type SessionHostDiagnostics, type SessionHostDisconnectInfo, type SessionHostDisconnectReason, type SessionHostDuplicateSessionGroup, type SessionHostEndpoint, type SessionHostEndpointOptions, type SessionHostEvent, type SessionHostEventEnvelope, type SessionHostLogEntry, type SessionHostPruneDuplicatesResult, type SessionHostRecord, SessionHostRegistry, type SessionHostRequest, type SessionHostRequestEnvelope, type SessionHostRequestTrace, type SessionHostRequestType, type SessionHostResponse, type SessionHostResponseEnvelope, type SessionHostRuntimeTransition, type SessionHostSnapshot, type SessionHostSurfaceKind, type SessionHostSurfaceRecordLike, type SessionHostWireEnvelope, type SessionLaunchCommand, type SessionLifecycle, type SessionOwnerType, SessionRingBuffer, type SessionRingBufferOptions, type SessionTerminalSnapshot, type SessionTerminalState, type SessionTermination, type SessionTransport, type SessionWriteOwner, type StopSessionPayload, type UpdateSessionMetaPayload, applyTerminalColorEnv, buildRuntimeDisplayName, buildRuntimeKey, canonicalizeInstancePath, classifyTermination, createCliChildPriorityPolicy, createLineParser, createResponseEnvelope, createSessionHostControlPlane, disconnectSessionHostClients, ensureNodePtySpawnHelperPermissions, formatRuntimeOwner, getDefaultSessionHostEndpoint, getSessionHostRecoveryLabel, getSessionHostSurfaceKind, getWorkspaceLabel, hiddenSpawn as hiddenSpawnProcess, isDefaultInstanceConfigDir, isSessionHostLiveRuntime, isSessionHostRecoverySnapshot, isTerminalRecord, partitionSessionHostDiagnosticsSessions, partitionSessionHostRecords, replayLaunchEnv, resolveAttachableRuntimeRecord, resolveInstanceConfigDir, resolveRuntimeRecord, resolveSessionHostIpcKey, sanitizeSpawnEnv, spawnCliChild, writeEnvelope };
|
|
913
|
+
export { type AcquireWritePayload, type AttachSessionPayload, CLI_CHILD_NICE_ENV, CLI_CHILD_NICE_INCREMENT, CLI_CHILD_SCHEDULING_ENV, type ClearSessionBufferPayload, type CreateSessionPayload, DEFAULT_CONFIG_DIR_NAME, DEFAULT_SESSION_RING_BUFFER_MAX_BYTES, type DetachSessionPayload, type ForceDetachClientPayload, type GetHostDiagnosticsPayload, type GetSnapshotPayload, type GetTerminalSnapshotPayload, type HostUpgradeLeasePayload, type MeshWriterAssignment, type MeshWriterStopTarget, type PruneDuplicateSessionsPayload, type ReleaseWritePayload, type ResizeSessionPayload, type RestartSessionPayload, type ResumeSessionPayload, SESSION_HOST_SUPPORTED_REQUEST_TYPES, type SendInputPayload, type SendSignalPayload, type SessionAttachedClient, type SessionBufferSnapshot, type SessionClientType, type SessionHostCategory, SessionHostClient, type SessionHostClientOptions, type SessionHostControlPlane, type SessionHostControlTransport, type SessionHostDiagnostics, type SessionHostDisconnectInfo, type SessionHostDisconnectReason, type SessionHostDuplicateSessionGroup, type SessionHostEndpoint, type SessionHostEndpointOptions, type SessionHostEvent, type SessionHostEventEnvelope, type SessionHostLogEntry, type SessionHostPruneDuplicatesResult, type SessionHostRecord, SessionHostRegistry, type SessionHostRequest, type SessionHostRequestEnvelope, type SessionHostRequestTrace, type SessionHostRequestType, type SessionHostResponse, type SessionHostResponseEnvelope, type SessionHostRuntimeTransition, type SessionHostSnapshot, type SessionHostSurfaceKind, type SessionHostSurfaceRecordLike, type SessionHostWireEnvelope, type SessionLaunchCommand, type SessionLifecycle, type SessionOwnerType, SessionRingBuffer, type SessionRingBufferOptions, type SessionTerminalSnapshot, type SessionTerminalState, type SessionTermination, type SessionTransport, type SessionWriteOwner, type StopMeshWriterPayload, type StopSessionPayload, type UpdateSessionMetaPayload, applyTerminalColorEnv, buildRuntimeDisplayName, buildRuntimeKey, canonicalizeInstancePath, classifyTermination, createCliChildPriorityPolicy, createLineParser, createResponseEnvelope, createSessionHostControlPlane, disconnectSessionHostClients, ensureNodePtySpawnHelperPermissions, findConnectedSessionHostClient, formatRuntimeOwner, getDefaultSessionHostEndpoint, getSessionHostRecoveryLabel, getSessionHostSurfaceKind, getWorkspaceLabel, hiddenSpawn as hiddenSpawnProcess, isDefaultInstanceConfigDir, isSessionHostLiveRuntime, isSessionHostRecoverySnapshot, isTerminalRecord, partitionSessionHostDiagnosticsSessions, partitionSessionHostRecords, replayLaunchEnv, resolveAttachableRuntimeRecord, resolveInstanceConfigDir, resolveRuntimeRecord, resolveSessionHostIpcKey, sanitizeSpawnEnv, spawnCliChild, writeEnvelope };
|
package/dist/index.d.ts
CHANGED
|
@@ -148,6 +148,26 @@ interface ResizeSessionPayload {
|
|
|
148
148
|
interface StopSessionPayload {
|
|
149
149
|
sessionId: string;
|
|
150
150
|
}
|
|
151
|
+
interface MeshWriterAssignment {
|
|
152
|
+
meshId: string;
|
|
153
|
+
nodeId: string;
|
|
154
|
+
taskId: string;
|
|
155
|
+
attemptId: string;
|
|
156
|
+
generation: number;
|
|
157
|
+
dispatchNonce: number;
|
|
158
|
+
ownerDaemonId: string;
|
|
159
|
+
}
|
|
160
|
+
interface MeshWriterStopTarget {
|
|
161
|
+
runtimeKey: string;
|
|
162
|
+
startedAt: number;
|
|
163
|
+
osPid: number;
|
|
164
|
+
providerType: string;
|
|
165
|
+
assignment: MeshWriterAssignment;
|
|
166
|
+
}
|
|
167
|
+
interface StopMeshWriterPayload extends MeshWriterStopTarget {
|
|
168
|
+
sessionId: string;
|
|
169
|
+
clientId: string;
|
|
170
|
+
}
|
|
151
171
|
interface DeleteSessionPayload {
|
|
152
172
|
sessionId: string;
|
|
153
173
|
/** Stop a live runtime before deleting the persisted record. */
|
|
@@ -304,6 +324,9 @@ type SessionHostRequest = {
|
|
|
304
324
|
} | {
|
|
305
325
|
type: 'stop_session';
|
|
306
326
|
payload: StopSessionPayload;
|
|
327
|
+
} | {
|
|
328
|
+
type: 'stop_mesh_writer';
|
|
329
|
+
payload: StopMeshWriterPayload;
|
|
307
330
|
} | {
|
|
308
331
|
type: 'delete_session';
|
|
309
332
|
payload: DeleteSessionPayload;
|
|
@@ -663,6 +686,8 @@ interface SessionHostClientOptions {
|
|
|
663
686
|
endpoint?: SessionHostEndpoint;
|
|
664
687
|
appName?: string;
|
|
665
688
|
requestTimeoutMs?: number;
|
|
689
|
+
/** Join the shared client registry (default true). Disable for short-lived probes. */
|
|
690
|
+
registerAsShared?: boolean;
|
|
666
691
|
}
|
|
667
692
|
/**
|
|
668
693
|
* Why an established session-host connection went away.
|
|
@@ -672,6 +697,7 @@ interface SessionHostClientOptions {
|
|
|
672
697
|
*/
|
|
673
698
|
type SessionHostDisconnectReason = 'error' | 'ended' | 'closed';
|
|
674
699
|
declare function disconnectSessionHostClients(endpoint?: SessionHostEndpoint, error?: Error): void;
|
|
700
|
+
declare function findConnectedSessionHostClient(endpoint?: SessionHostEndpoint): SessionHostClient | null;
|
|
675
701
|
interface SessionHostDisconnectInfo {
|
|
676
702
|
reason: SessionHostDisconnectReason;
|
|
677
703
|
endpointPath: string;
|
|
@@ -703,6 +729,8 @@ declare class SessionHostClient {
|
|
|
703
729
|
private attachedSessions;
|
|
704
730
|
constructor(options?: SessionHostClientOptions);
|
|
705
731
|
static disconnectClients(endpoint?: SessionHostEndpoint, error?: Error): void;
|
|
732
|
+
static findConnectedClient(endpoint?: SessionHostEndpoint): SessionHostClient | null;
|
|
733
|
+
isConnected(): boolean;
|
|
706
734
|
/**
|
|
707
735
|
* Fires when an established connection to the session host goes away.
|
|
708
736
|
*
|
|
@@ -718,9 +746,11 @@ declare class SessionHostClient {
|
|
|
718
746
|
onDisconnect(listener: (info: SessionHostDisconnectInfo) => void): () => void;
|
|
719
747
|
private handleDisconnect;
|
|
720
748
|
private sendRawRequestOnSocket;
|
|
721
|
-
connect(): Promise<void>;
|
|
749
|
+
connect(timeoutMs?: number): Promise<void>;
|
|
722
750
|
onEvent(listener: (event: SessionHostEvent) => void): () => void;
|
|
723
|
-
request<T = unknown>(request: SessionHostRequest
|
|
751
|
+
request<T = unknown>(request: SessionHostRequest, options?: {
|
|
752
|
+
timeoutMs?: number;
|
|
753
|
+
}): Promise<SessionHostResponse<T>>;
|
|
724
754
|
disconnect(error?: Error): void;
|
|
725
755
|
close(): Promise<void>;
|
|
726
756
|
}
|
|
@@ -880,4 +910,4 @@ interface SessionHostControlTransport {
|
|
|
880
910
|
*/
|
|
881
911
|
declare function createSessionHostControlPlane(transport: SessionHostControlTransport): SessionHostControlPlane;
|
|
882
912
|
|
|
883
|
-
export { type AcquireWritePayload, type AttachSessionPayload, CLI_CHILD_NICE_ENV, CLI_CHILD_NICE_INCREMENT, CLI_CHILD_SCHEDULING_ENV, type ClearSessionBufferPayload, type CreateSessionPayload, DEFAULT_CONFIG_DIR_NAME, DEFAULT_SESSION_RING_BUFFER_MAX_BYTES, type DetachSessionPayload, type ForceDetachClientPayload, type GetHostDiagnosticsPayload, type GetSnapshotPayload, type GetTerminalSnapshotPayload, type HostUpgradeLeasePayload, type PruneDuplicateSessionsPayload, type ReleaseWritePayload, type ResizeSessionPayload, type RestartSessionPayload, type ResumeSessionPayload, SESSION_HOST_SUPPORTED_REQUEST_TYPES, type SendInputPayload, type SendSignalPayload, type SessionAttachedClient, type SessionBufferSnapshot, type SessionClientType, type SessionHostCategory, SessionHostClient, type SessionHostClientOptions, type SessionHostControlPlane, type SessionHostControlTransport, type SessionHostDiagnostics, type SessionHostDisconnectInfo, type SessionHostDisconnectReason, type SessionHostDuplicateSessionGroup, type SessionHostEndpoint, type SessionHostEndpointOptions, type SessionHostEvent, type SessionHostEventEnvelope, type SessionHostLogEntry, type SessionHostPruneDuplicatesResult, type SessionHostRecord, SessionHostRegistry, type SessionHostRequest, type SessionHostRequestEnvelope, type SessionHostRequestTrace, type SessionHostRequestType, type SessionHostResponse, type SessionHostResponseEnvelope, type SessionHostRuntimeTransition, type SessionHostSnapshot, type SessionHostSurfaceKind, type SessionHostSurfaceRecordLike, type SessionHostWireEnvelope, type SessionLaunchCommand, type SessionLifecycle, type SessionOwnerType, SessionRingBuffer, type SessionRingBufferOptions, type SessionTerminalSnapshot, type SessionTerminalState, type SessionTermination, type SessionTransport, type SessionWriteOwner, type StopSessionPayload, type UpdateSessionMetaPayload, applyTerminalColorEnv, buildRuntimeDisplayName, buildRuntimeKey, canonicalizeInstancePath, classifyTermination, createCliChildPriorityPolicy, createLineParser, createResponseEnvelope, createSessionHostControlPlane, disconnectSessionHostClients, ensureNodePtySpawnHelperPermissions, formatRuntimeOwner, getDefaultSessionHostEndpoint, getSessionHostRecoveryLabel, getSessionHostSurfaceKind, getWorkspaceLabel, hiddenSpawn as hiddenSpawnProcess, isDefaultInstanceConfigDir, isSessionHostLiveRuntime, isSessionHostRecoverySnapshot, isTerminalRecord, partitionSessionHostDiagnosticsSessions, partitionSessionHostRecords, replayLaunchEnv, resolveAttachableRuntimeRecord, resolveInstanceConfigDir, resolveRuntimeRecord, resolveSessionHostIpcKey, sanitizeSpawnEnv, spawnCliChild, writeEnvelope };
|
|
913
|
+
export { type AcquireWritePayload, type AttachSessionPayload, CLI_CHILD_NICE_ENV, CLI_CHILD_NICE_INCREMENT, CLI_CHILD_SCHEDULING_ENV, type ClearSessionBufferPayload, type CreateSessionPayload, DEFAULT_CONFIG_DIR_NAME, DEFAULT_SESSION_RING_BUFFER_MAX_BYTES, type DetachSessionPayload, type ForceDetachClientPayload, type GetHostDiagnosticsPayload, type GetSnapshotPayload, type GetTerminalSnapshotPayload, type HostUpgradeLeasePayload, type MeshWriterAssignment, type MeshWriterStopTarget, type PruneDuplicateSessionsPayload, type ReleaseWritePayload, type ResizeSessionPayload, type RestartSessionPayload, type ResumeSessionPayload, SESSION_HOST_SUPPORTED_REQUEST_TYPES, type SendInputPayload, type SendSignalPayload, type SessionAttachedClient, type SessionBufferSnapshot, type SessionClientType, type SessionHostCategory, SessionHostClient, type SessionHostClientOptions, type SessionHostControlPlane, type SessionHostControlTransport, type SessionHostDiagnostics, type SessionHostDisconnectInfo, type SessionHostDisconnectReason, type SessionHostDuplicateSessionGroup, type SessionHostEndpoint, type SessionHostEndpointOptions, type SessionHostEvent, type SessionHostEventEnvelope, type SessionHostLogEntry, type SessionHostPruneDuplicatesResult, type SessionHostRecord, SessionHostRegistry, type SessionHostRequest, type SessionHostRequestEnvelope, type SessionHostRequestTrace, type SessionHostRequestType, type SessionHostResponse, type SessionHostResponseEnvelope, type SessionHostRuntimeTransition, type SessionHostSnapshot, type SessionHostSurfaceKind, type SessionHostSurfaceRecordLike, type SessionHostWireEnvelope, type SessionLaunchCommand, type SessionLifecycle, type SessionOwnerType, SessionRingBuffer, type SessionRingBufferOptions, type SessionTerminalSnapshot, type SessionTerminalState, type SessionTermination, type SessionTransport, type SessionWriteOwner, type StopMeshWriterPayload, type StopSessionPayload, type UpdateSessionMetaPayload, applyTerminalColorEnv, buildRuntimeDisplayName, buildRuntimeKey, canonicalizeInstancePath, classifyTermination, createCliChildPriorityPolicy, createLineParser, createResponseEnvelope, createSessionHostControlPlane, disconnectSessionHostClients, ensureNodePtySpawnHelperPermissions, findConnectedSessionHostClient, formatRuntimeOwner, getDefaultSessionHostEndpoint, getSessionHostRecoveryLabel, getSessionHostSurfaceKind, getWorkspaceLabel, hiddenSpawn as hiddenSpawnProcess, isDefaultInstanceConfigDir, isSessionHostLiveRuntime, isSessionHostRecoverySnapshot, isTerminalRecord, partitionSessionHostDiagnosticsSessions, partitionSessionHostRecords, replayLaunchEnv, resolveAttachableRuntimeRecord, resolveInstanceConfigDir, resolveRuntimeRecord, resolveSessionHostIpcKey, sanitizeSpawnEnv, spawnCliChild, writeEnvelope };
|
package/dist/index.js
CHANGED
|
@@ -52,6 +52,7 @@ __export(index_exports, {
|
|
|
52
52
|
createSessionHostControlPlane: () => createSessionHostControlPlane,
|
|
53
53
|
disconnectSessionHostClients: () => disconnectSessionHostClients,
|
|
54
54
|
ensureNodePtySpawnHelperPermissions: () => ensureNodePtySpawnHelperPermissions,
|
|
55
|
+
findConnectedSessionHostClient: () => findConnectedSessionHostClient,
|
|
55
56
|
formatRuntimeOwner: () => formatRuntimeOwner,
|
|
56
57
|
getDefaultSessionHostEndpoint: () => getDefaultSessionHostEndpoint,
|
|
57
58
|
getSessionHostRecoveryLabel: () => getSessionHostRecoveryLabel,
|
|
@@ -88,6 +89,7 @@ var SESSION_HOST_SUPPORTED_REQUEST_TYPES = [
|
|
|
88
89
|
"send_input",
|
|
89
90
|
"resize_session",
|
|
90
91
|
"stop_session",
|
|
92
|
+
"stop_mesh_writer",
|
|
91
93
|
"delete_session",
|
|
92
94
|
"resume_session",
|
|
93
95
|
"acquire_write",
|
|
@@ -818,6 +820,19 @@ function disconnectSessionHostClients(endpoint, error) {
|
|
|
818
820
|
}
|
|
819
821
|
}
|
|
820
822
|
}
|
|
823
|
+
function findConnectedSessionHostClient(endpoint) {
|
|
824
|
+
for (const ref of activeClientRefs) {
|
|
825
|
+
const client = ref.deref();
|
|
826
|
+
if (!client) {
|
|
827
|
+
activeClientRefs.delete(ref);
|
|
828
|
+
continue;
|
|
829
|
+
}
|
|
830
|
+
if ((!endpoint || client.endpoint.path === endpoint.path) && client.isConnected()) {
|
|
831
|
+
return client;
|
|
832
|
+
}
|
|
833
|
+
}
|
|
834
|
+
return null;
|
|
835
|
+
}
|
|
821
836
|
var SessionHostClient = class {
|
|
822
837
|
endpoint;
|
|
823
838
|
socket = null;
|
|
@@ -835,11 +850,17 @@ var SessionHostClient = class {
|
|
|
835
850
|
if (typeof options.requestTimeoutMs === "number" && options.requestTimeoutMs > 0) {
|
|
836
851
|
this.requestTimeoutMs = options.requestTimeoutMs;
|
|
837
852
|
}
|
|
838
|
-
activeClientRefs.add(new WeakRef(this));
|
|
853
|
+
if (options.registerAsShared !== false) activeClientRefs.add(new WeakRef(this));
|
|
839
854
|
}
|
|
840
855
|
static disconnectClients(endpoint, error) {
|
|
841
856
|
disconnectSessionHostClients(endpoint, error);
|
|
842
857
|
}
|
|
858
|
+
static findConnectedClient(endpoint) {
|
|
859
|
+
return findConnectedSessionHostClient(endpoint);
|
|
860
|
+
}
|
|
861
|
+
isConnected() {
|
|
862
|
+
return Boolean(this.socket && !this.socket.destroyed && establishedSockets.has(this.socket));
|
|
863
|
+
}
|
|
843
864
|
/**
|
|
844
865
|
* Fires when an established connection to the session host goes away.
|
|
845
866
|
*
|
|
@@ -901,18 +922,32 @@ var SessionHostClient = class {
|
|
|
901
922
|
}
|
|
902
923
|
}
|
|
903
924
|
}
|
|
904
|
-
sendRawRequestOnSocket(socket, request) {
|
|
925
|
+
sendRawRequestOnSocket(socket, request, timeoutMs = this.requestTimeoutMs) {
|
|
905
926
|
const requestId = generateUUID();
|
|
906
927
|
const envelope = {
|
|
907
928
|
kind: "request",
|
|
908
929
|
requestId,
|
|
909
930
|
request
|
|
910
931
|
};
|
|
911
|
-
const timeoutMs = this.requestTimeoutMs > 0 ? this.requestTimeoutMs : 3e4;
|
|
912
932
|
const timeoutLabel = timeoutMs % 1e3 === 0 ? `${timeoutMs / 1e3}s` : `${timeoutMs}ms`;
|
|
933
|
+
const startedAt = Date.now();
|
|
934
|
+
const startedMonotonicAt = performance.now();
|
|
913
935
|
return new Promise((resolve3, reject) => {
|
|
914
936
|
const timeout = setTimeout(() => {
|
|
915
|
-
const
|
|
937
|
+
const actualElapsedMs = Math.max(0, Math.round(performance.now() - startedMonotonicAt));
|
|
938
|
+
const wallElapsedMs = Math.max(0, Date.now() - startedAt);
|
|
939
|
+
const observerLagMs = Math.max(0, actualElapsedMs - timeoutMs);
|
|
940
|
+
const timeoutError = Object.assign(
|
|
941
|
+
new Error(`Session host request timed out after ${timeoutLabel} (${request.type})`),
|
|
942
|
+
{
|
|
943
|
+
code: "SESSION_HOST_REQUEST_TIMEOUT",
|
|
944
|
+
requestType: request.type,
|
|
945
|
+
scheduledTimeoutMs: timeoutMs,
|
|
946
|
+
actualElapsedMs,
|
|
947
|
+
wallElapsedMs,
|
|
948
|
+
observerLagMs
|
|
949
|
+
}
|
|
950
|
+
);
|
|
916
951
|
if (this.socket === socket) {
|
|
917
952
|
this.disconnect(timeoutError);
|
|
918
953
|
} else {
|
|
@@ -938,7 +973,7 @@ var SessionHostClient = class {
|
|
|
938
973
|
socket.write(serializeEnvelope(envelope));
|
|
939
974
|
});
|
|
940
975
|
}
|
|
941
|
-
async connect() {
|
|
976
|
+
async connect(timeoutMs = this.requestTimeoutMs) {
|
|
942
977
|
if (this.socket && !this.socket.destroyed) {
|
|
943
978
|
if (this.connectPromise) await this.connectPromise;
|
|
944
979
|
return;
|
|
@@ -986,11 +1021,44 @@ var SessionHostClient = class {
|
|
|
986
1021
|
});
|
|
987
1022
|
const connectTask = (async () => {
|
|
988
1023
|
await new Promise((resolve3, reject) => {
|
|
989
|
-
|
|
1024
|
+
const cleanup = () => {
|
|
1025
|
+
clearTimeout(timer);
|
|
1026
|
+
socket.off("connect", connected);
|
|
1027
|
+
socket.off("error", failed);
|
|
1028
|
+
socket.off("close", closed);
|
|
1029
|
+
};
|
|
1030
|
+
const connected = () => {
|
|
1031
|
+
cleanup();
|
|
990
1032
|
establishedSockets.add(socket);
|
|
991
1033
|
resolve3();
|
|
992
|
-
}
|
|
993
|
-
|
|
1034
|
+
};
|
|
1035
|
+
const failed = (error) => {
|
|
1036
|
+
cleanup();
|
|
1037
|
+
reject(error);
|
|
1038
|
+
};
|
|
1039
|
+
const closed = () => failed(new Error("Session host connection closed before connect"));
|
|
1040
|
+
const connectStartedAt = Date.now();
|
|
1041
|
+
const connectStartedMonotonicAt = performance.now();
|
|
1042
|
+
const timer = setTimeout(() => {
|
|
1043
|
+
const actualElapsedMs = Math.max(0, Math.round(performance.now() - connectStartedMonotonicAt));
|
|
1044
|
+
const wallElapsedMs = Math.max(0, Date.now() - connectStartedAt);
|
|
1045
|
+
const observerLagMs = Math.max(0, actualElapsedMs - timeoutMs);
|
|
1046
|
+
const error = Object.assign(
|
|
1047
|
+
new Error(`Session host connect timed out after ${timeoutMs}ms`),
|
|
1048
|
+
{
|
|
1049
|
+
code: "SESSION_HOST_CONNECT_TIMEOUT",
|
|
1050
|
+
scheduledTimeoutMs: timeoutMs,
|
|
1051
|
+
actualElapsedMs,
|
|
1052
|
+
wallElapsedMs,
|
|
1053
|
+
observerLagMs
|
|
1054
|
+
}
|
|
1055
|
+
);
|
|
1056
|
+
failed(error);
|
|
1057
|
+
if (this.socket === socket) this.disconnect(error);
|
|
1058
|
+
}, timeoutMs);
|
|
1059
|
+
socket.once("connect", connected);
|
|
1060
|
+
socket.once("error", failed);
|
|
1061
|
+
socket.once("close", closed);
|
|
994
1062
|
});
|
|
995
1063
|
if (this.attachedSessions.size > 0 && this.socket === socket && !socket.destroyed) {
|
|
996
1064
|
for (const [sessionId, sub] of [...this.attachedSessions.entries()]) {
|
|
@@ -1020,11 +1088,46 @@ var SessionHostClient = class {
|
|
|
1020
1088
|
this.eventListeners.delete(listener);
|
|
1021
1089
|
};
|
|
1022
1090
|
}
|
|
1023
|
-
async request(request) {
|
|
1024
|
-
|
|
1091
|
+
async request(request, options = {}) {
|
|
1092
|
+
const timeoutMs = Math.max(1, options.timeoutMs ?? this.requestTimeoutMs);
|
|
1093
|
+
const deadline = Date.now() + timeoutMs;
|
|
1094
|
+
const alreadyConnected = this.isConnected() && !this.connectPromise;
|
|
1095
|
+
if (options.timeoutMs !== void 0) {
|
|
1096
|
+
let timer;
|
|
1097
|
+
const raceStartedAt = Date.now();
|
|
1098
|
+
const raceStartedMonotonicAt = performance.now();
|
|
1099
|
+
try {
|
|
1100
|
+
await Promise.race([
|
|
1101
|
+
this.connect(timeoutMs),
|
|
1102
|
+
new Promise((_resolve, reject) => {
|
|
1103
|
+
timer = setTimeout(() => {
|
|
1104
|
+
const actualElapsedMs = Math.max(0, Math.round(performance.now() - raceStartedMonotonicAt));
|
|
1105
|
+
const wallElapsedMs = Math.max(0, Date.now() - raceStartedAt);
|
|
1106
|
+
const observerLagMs = Math.max(0, actualElapsedMs - timeoutMs);
|
|
1107
|
+
const error = Object.assign(
|
|
1108
|
+
new Error(`Session host connect timed out after ${timeoutMs}ms`),
|
|
1109
|
+
{
|
|
1110
|
+
code: "SESSION_HOST_CONNECT_TIMEOUT",
|
|
1111
|
+
scheduledTimeoutMs: timeoutMs,
|
|
1112
|
+
actualElapsedMs,
|
|
1113
|
+
wallElapsedMs,
|
|
1114
|
+
observerLagMs
|
|
1115
|
+
}
|
|
1116
|
+
);
|
|
1117
|
+
reject(error);
|
|
1118
|
+
this.disconnect(error);
|
|
1119
|
+
}, timeoutMs);
|
|
1120
|
+
})
|
|
1121
|
+
]);
|
|
1122
|
+
} finally {
|
|
1123
|
+
if (timer) clearTimeout(timer);
|
|
1124
|
+
}
|
|
1125
|
+
} else {
|
|
1126
|
+
await this.connect(timeoutMs);
|
|
1127
|
+
}
|
|
1025
1128
|
const requestSocket = this.socket;
|
|
1026
1129
|
if (!requestSocket) throw new Error("Session host socket unavailable");
|
|
1027
|
-
const response = await this.sendRawRequestOnSocket(requestSocket, request);
|
|
1130
|
+
const response = await this.sendRawRequestOnSocket(requestSocket, request, options.timeoutMs === void 0 || alreadyConnected ? timeoutMs : Math.max(1, deadline - Date.now()));
|
|
1028
1131
|
if (response.success) {
|
|
1029
1132
|
if (request.type === "attach_session") {
|
|
1030
1133
|
this.attachedSessions.set(request.payload.sessionId, {
|
|
@@ -1285,6 +1388,7 @@ function createSessionHostControlPlane(transport) {
|
|
|
1285
1388
|
createSessionHostControlPlane,
|
|
1286
1389
|
disconnectSessionHostClients,
|
|
1287
1390
|
ensureNodePtySpawnHelperPermissions,
|
|
1391
|
+
findConnectedSessionHostClient,
|
|
1288
1392
|
formatRuntimeOwner,
|
|
1289
1393
|
getDefaultSessionHostEndpoint,
|
|
1290
1394
|
getSessionHostRecoveryLabel,
|