spooder 4.4.9 → 4.4.11

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 (2) hide show
  1. package/package.json +1 -1
  2. package/src/api.ts +33 -21
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "spooder",
3
3
  "type": "module",
4
- "version": "4.4.9",
4
+ "version": "4.4.11",
5
5
  "exports": {
6
6
  ".": {
7
7
  "bun": "./src/api.ts",
package/src/api.ts CHANGED
@@ -507,7 +507,7 @@ type StatusCodeHandler = (req: Request) => HandlerReturnType;
507
507
 
508
508
  type JSONRequestHandler = (req: Request, url: URL, json: JsonObject) => HandlerReturnType;
509
509
 
510
- type ServerSentEventClient = {
510
+ export type ServerSentEventClient = {
511
511
  message: (message: string) => void;
512
512
  event: (event_name: string, message: string) => void;
513
513
  close: () => void;
@@ -819,53 +819,65 @@ export function serve(port: number) {
819
819
  routes.push([path.split('/'), (req: Request, url: URL) => {
820
820
  let stream_controller: ReadableStreamDirectController;
821
821
  let close_resolver: () => void;
822
-
822
+
823
823
  function close_controller() {
824
824
  stream_controller?.close();
825
825
  close_resolver?.();
826
826
  }
827
-
828
- const queue = Array<string>();
827
+
828
+ let lastEventTime = Date.now();
829
+ const KEEP_ALIVE_INTERVAL = 15000;
830
+
829
831
  const stream = new ReadableStream({
830
832
  // @ts-ignore Bun implements a "direct" mode which does not exist in the spec.
831
833
  type: 'direct',
832
-
834
+
833
835
  async pull(controller) {
834
836
  // @ts-ignore `controller` in "direct" mode is ReadableStreamDirectController.
835
837
  stream_controller = controller as ReadableStreamDirectController;
838
+
836
839
  while (!req.signal.aborted) {
837
- if (queue.length > 0) {
838
- stream_controller.write(queue.shift()!);
840
+ const now = Date.now();
841
+ if (now - lastEventTime >= KEEP_ALIVE_INTERVAL) {
842
+ stream_controller.write(':keep-alive\n\n');
839
843
  stream_controller.flush();
840
- } else {
841
- await Bun.sleep(50);
844
+ lastEventTime = now;
842
845
  }
846
+
847
+ await Bun.sleep(100); // prevent tight loop
843
848
  }
844
849
  }
845
850
  });
846
-
851
+
847
852
  const closed = new Promise<void>(resolve => close_resolver = resolve);
848
853
  req.signal.onabort = close_controller;
849
-
854
+
850
855
  handler(req, url, {
851
856
  message: (message: string) => {
852
- queue.push('data:' + message + '\n\n');
857
+ stream_controller.write('data: ' + message + '\n\n');
858
+ stream_controller.flush();
859
+ lastEventTime = Date.now();
853
860
  },
854
-
861
+
855
862
  event: (event_name: string, message: string) => {
856
- queue.push('event:' + event_name + '\ndata:' + message + '\n\n');
863
+ stream_controller.write('event: ' + event_name + '\ndata: ' + message + '\n\n');
864
+ stream_controller.flush();
865
+ lastEventTime = Date.now();
857
866
  },
858
-
867
+
859
868
  close: close_controller,
860
869
  closed
861
870
  });
862
871
 
863
- return new Response(stream, { headers: {
864
- 'Content-Type': 'text/event-stream',
865
- 'Cache-Control': 'no-cache',
866
- 'Connection': 'keep-alive'
867
- }});
872
+ return new Response(stream, {
873
+ headers: {
874
+ 'Content-Type': 'text/event-stream',
875
+ 'Cache-Control': 'no-cache',
876
+ 'Connection': 'keep-alive',
877
+ 'X-Accel-Buffering': 'no', // Disable proxy buffering
878
+ }
879
+ });
868
880
  }, 'GET']);
869
881
  }
870
- }
882
+ };
871
883
  }