@@ -8,6 +8,7 @@ import esbuild from 'esbuild'
8
8
import { unicodeLines } from './fixtures.js'
9
9
10
10
const isDeno = typeof globalThis . Deno !== 'undefined'
11
+ const idedListeners = new Map < string , Set < ServerResponse > > ( )
11
12
12
13
export function getServer ( port : number ) : Promise < Server > {
13
14
return new Promise ( ( resolve , reject ) => {
@@ -23,12 +24,15 @@ function onRequest(req: IncomingMessage, res: ServerResponse) {
23
24
res . socket . setNoDelay ( true )
24
25
}
25
26
26
- switch ( req . url ) {
27
+ const path = new URL ( req . url || '/' , 'http://localhost' ) . pathname
28
+ switch ( path ) {
27
29
// Server-Sent Event endpoints
28
30
case '/' :
29
31
return writeDefault ( req , res )
30
32
case '/counter' :
31
33
return writeCounter ( req , res )
34
+ case '/identified' :
35
+ return writeIdentifiedListeners ( req , res )
32
36
case '/end-after-one' :
33
37
return writeOne ( req , res )
34
38
case '/slow-connect' :
@@ -109,6 +113,42 @@ async function writeCounter(req: IncomingMessage, res: ServerResponse) {
109
113
res . end ( )
110
114
}
111
115
116
+ function writeIdentifiedListeners ( req : IncomingMessage , res : ServerResponse ) {
117
+ const url = new URL ( req . url || '/' , 'http://localhost' )
118
+ const id = url . searchParams . get ( 'id' )
119
+ if ( ! id ) {
120
+ res . writeHead ( 400 , {
121
+ 'Content-Type' : 'application/json' ,
122
+ 'Cache-Control' : 'no-cache' ,
123
+ Connection : 'keep-alive' ,
124
+ } )
125
+ tryWrite ( res , JSON . stringify ( { error : 'Missing "id" query parameter' } ) )
126
+ res . end ( )
127
+ return
128
+ }
129
+
130
+ if ( ( req . headers . accept || '' ) . includes ( 'text/event-stream' ) ) {
131
+ const current = ( idedListeners . get ( id ) || new Set ( ) ) . add ( res )
132
+ idedListeners . set ( id , current )
133
+ res . writeHead ( 200 , {
134
+ 'Content-Type' : 'text/event-stream' ,
135
+ 'Cache-Control' : 'no-cache' ,
136
+ Connection : 'keep-alive' ,
137
+ } )
138
+ tryWrite ( res , formatEvent ( { data : '' , retry : 250 } ) )
139
+ tryWrite ( res , formatEvent ( { data : `${ idedListeners . size } ` } ) )
140
+ res . on ( 'close' , ( ) => ( idedListeners . get ( id ) || new Set ( ) ) . delete ( res ) )
141
+ return
142
+ }
143
+
144
+ res . writeHead ( 200 , {
145
+ 'Content-Type' : 'application/json' ,
146
+ 'Cache-Control' : 'no-cache' ,
147
+ } )
148
+ tryWrite ( res , JSON . stringify ( { numListeners : ( idedListeners . get ( id ) || new Set ( ) ) . size } ) )
149
+ res . end ( )
150
+ }
151
+
112
152
function writeOne ( req : IncomingMessage , res : ServerResponse ) {
113
153
const last = getLastEventId ( req )
114
154
res . writeHead ( last ? 204 : 200 , {
0 commit comments