@@ -23,60 +23,6 @@ export namespace Pty {
2323 close : ( code ?: number , reason ?: string ) => void
2424 }
2525
26- type Subscriber = {
27- id : number
28- token : unknown
29- }
30-
31- const sockets = new WeakMap < object , number > ( )
32- const owners = new WeakMap < object , string > ( )
33- let socketCounter = 0
34-
35- const tagSocket = ( ws : Socket ) => {
36- if ( ! ws || typeof ws !== "object" ) return
37- const next = ( socketCounter = ( socketCounter + 1 ) % Number . MAX_SAFE_INTEGER )
38- sockets . set ( ws , next )
39- return next
40- }
41-
42- const token = ( ws : Socket ) => {
43- const data = ws . data
44- if ( data === undefined ) return
45- if ( data === null ) return
46- if ( typeof data !== "object" ) return data
47-
48- const id = ( data as { connId ?: unknown } ) . connId
49- if ( typeof id === "number" || typeof id === "string" ) return id
50-
51- const href = ( data as { href ?: unknown } ) . href
52- if ( typeof href === "string" ) return href
53-
54- const url = ( data as { url ?: unknown } ) . url
55- if ( typeof url === "string" ) return url
56- if ( url && typeof url === "object" ) {
57- const href = ( url as { href ?: unknown } ) . href
58- if ( typeof href === "string" ) return href
59- return url
60- }
61-
62- const events = ( data as { events ?: unknown } ) . events
63- if ( typeof events === "number" || typeof events === "string" ) return events
64- if ( events && typeof events === "object" ) {
65- const id = ( events as { connId ?: unknown } ) . connId
66- if ( typeof id === "number" || typeof id === "string" ) return id
67-
68- const id2 = ( events as { connection ?: unknown } ) . connection
69- if ( typeof id2 === "number" || typeof id2 === "string" ) return id2
70-
71- const id3 = ( events as { id ?: unknown } ) . id
72- if ( typeof id3 === "number" || typeof id3 === "string" ) return id3
73-
74- return events
75- }
76-
77- return data
78- }
79-
8026 // WebSocket control frame: 0x00 + UTF-8 JSON.
8127 const meta = ( cursor : number ) => {
8228 const json = JSON . stringify ( { cursor } )
@@ -141,7 +87,7 @@ export namespace Pty {
14187 buffer : string
14288 bufferCursor : number
14389 cursor : number
144- subscribers : Map < Socket , Subscriber >
90+ subscribers : Map < unknown , Socket >
14591 }
14692
14793 const state = Instance . state (
@@ -151,9 +97,9 @@ export namespace Pty {
15197 try {
15298 session . process . kill ( )
15399 } catch { }
154- for ( const ws of session . subscribers . keys ( ) ) {
100+ for ( const [ key , ws ] of session . subscribers . entries ( ) ) {
155101 try {
156- ws . close ( )
102+ if ( ws . data === key ) ws . close ( )
157103 } catch {
158104 // ignore
159105 }
@@ -224,26 +170,21 @@ export namespace Pty {
224170 ptyProcess . onData ( ( chunk ) => {
225171 session . cursor += chunk . length
226172
227- for ( const [ ws , sub ] of session . subscribers ) {
173+ for ( const [ key , ws ] of session . subscribers . entries ( ) ) {
228174 if ( ws . readyState !== 1 ) {
229- session . subscribers . delete ( ws )
230- continue
231- }
232-
233- if ( typeof ws === "object" && sockets . get ( ws ) !== sub . id ) {
234- session . subscribers . delete ( ws )
175+ session . subscribers . delete ( key )
235176 continue
236177 }
237178
238- if ( token ( ws ) !== sub . token ) {
239- session . subscribers . delete ( ws )
179+ if ( ws . data !== key ) {
180+ session . subscribers . delete ( key )
240181 continue
241182 }
242183
243184 try {
244185 ws . send ( chunk )
245186 } catch {
246- session . subscribers . delete ( ws )
187+ session . subscribers . delete ( key )
247188 }
248189 }
249190
@@ -256,9 +197,9 @@ export namespace Pty {
256197 ptyProcess . onExit ( ( { exitCode } ) => {
257198 log . info ( "session exited" , { id, exitCode } )
258199 session . info . status = "exited"
259- for ( const ws of session . subscribers . keys ( ) ) {
200+ for ( const [ key , ws ] of session . subscribers . entries ( ) ) {
260201 try {
261- ws . close ( )
202+ if ( ws . data === key ) ws . close ( )
262203 } catch {
263204 // ignore
264205 }
@@ -291,9 +232,9 @@ export namespace Pty {
291232 try {
292233 session . process . kill ( )
293234 } catch { }
294- for ( const ws of session . subscribers . keys ( ) ) {
235+ for ( const [ key , ws ] of session . subscribers . entries ( ) ) {
295236 try {
296- ws . close ( )
237+ if ( ws . data === key ) ws . close ( )
297238 } catch {
298239 // ignore
299240 }
@@ -325,23 +266,16 @@ export namespace Pty {
325266 }
326267 log . info ( "client connected to session" , { id } )
327268
328- const socketId = tagSocket ( ws )
329- if ( socketId === undefined ) {
330- ws . close ( )
331- return
332- }
333-
334- const previous = owners . get ( ws )
335- if ( previous && previous !== id ) {
336- state ( ) . get ( previous ) ?. subscribers . delete ( ws )
337- }
269+ // Use ws.data as the unique key for this connection lifecycle.
270+ // If ws.data is undefined, fallback to ws object.
271+ const connectionKey = ws . data && typeof ws . data === "object" ? ws . data : ws
338272
339- owners . set ( ws , id )
340- session . subscribers . set ( ws , { id : socketId , token : token ( ws ) } )
273+ // Optionally cleanup if the key somehow exists
274+ session . subscribers . delete ( connectionKey )
275+ session . subscribers . set ( connectionKey , ws )
341276
342277 const cleanup = ( ) => {
343- session . subscribers . delete ( ws )
344- if ( owners . get ( ws ) === id ) owners . delete ( ws )
278+ session . subscribers . delete ( connectionKey )
345279 }
346280
347281 const start = session . bufferCursor
0 commit comments