routup 3.2.0 → 3.3.0

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.
@@ -20,6 +20,7 @@ export declare enum HeaderName {
20
20
  CONTENT_LENGTH = "content-length",
21
21
  CONTENT_RANGE = "content-range",
22
22
  CONTENT_TYPE = "content-type",
23
+ CONNECTION = "connection",
23
24
  COOKIE = "cookie",
24
25
  ETag = "etag",
25
26
  HOST = "host",
@@ -34,6 +35,7 @@ export declare enum HeaderName {
34
35
  RETRY_AFTER = "retry-after",
35
36
  SET_COOKIE = "set-cookie",
36
37
  TRANSFER_ENCODING = "transfer-encoding",
38
+ X_ACCEL_BUFFERING = "x-accel-buffering",
37
39
  X_FORWARDED_HOST = "x-forwarded-host",
38
40
  X_FORWARDED_FOR = "x-forwarded-for",
39
41
  X_FORWARDED_PROTO = "x-forwarded-proto"
package/dist/index.cjs CHANGED
@@ -34,6 +34,7 @@ exports.HeaderName = void 0;
34
34
  HeaderName["CONTENT_LENGTH"] = "content-length";
35
35
  HeaderName["CONTENT_RANGE"] = "content-range";
36
36
  HeaderName["CONTENT_TYPE"] = "content-type";
37
+ HeaderName["CONNECTION"] = "connection";
37
38
  HeaderName["COOKIE"] = "cookie";
38
39
  HeaderName["ETag"] = "etag";
39
40
  HeaderName["HOST"] = "host";
@@ -48,6 +49,7 @@ exports.HeaderName = void 0;
48
49
  HeaderName["RETRY_AFTER"] = "retry-after";
49
50
  HeaderName["SET_COOKIE"] = "set-cookie";
50
51
  HeaderName["TRANSFER_ENCODING"] = "transfer-encoding";
52
+ HeaderName["X_ACCEL_BUFFERING"] = "x-accel-buffering";
51
53
  HeaderName["X_FORWARDED_HOST"] = "x-forwarded-host";
52
54
  HeaderName["X_FORWARDED_FOR"] = "x-forwarded-for";
53
55
  HeaderName["X_FORWARDED_PROTO"] = "x-forwarded-proto";
@@ -546,6 +548,10 @@ function getRequestHostName(req, options) {
546
548
  return index !== -1 ? hostname.substring(0, index) : hostname;
547
549
  }
548
550
 
551
+ function isRequestHTTP2(req) {
552
+ return typeof getRequestHeader(req, ':path') !== 'undefined' && typeof getRequestHeader(req, ':method') !== 'undefined';
553
+ }
554
+
549
555
  function getRequestIP(req, options) {
550
556
  options = options || {};
551
557
  let trustProxy;
@@ -761,6 +767,96 @@ function isResponseGone(res) {
761
767
  }
762
768
  return false;
763
769
  }
770
+ function setResponseGone(res, value) {
771
+ res[GoneSymbol] = value;
772
+ }
773
+
774
+ function serializeEventStreamMessage(message) {
775
+ let result = '';
776
+ if (message.id) {
777
+ result += `id: ${message.id}\n`;
778
+ }
779
+ if (message.event) {
780
+ result += `event: ${message.event}\n`;
781
+ }
782
+ if (typeof message.retry === 'number' && Number.isInteger(message.retry)) {
783
+ result += `retry: ${message.retry}\n`;
784
+ }
785
+ result += `data: ${message.data}\n\n`;
786
+ return result;
787
+ }
788
+
789
+ class EventStream {
790
+ open() {
791
+ this.response.req.on('close', ()=>this.end());
792
+ this.response.req.on('error', (err)=>{
793
+ this.emit('error', err);
794
+ this.end();
795
+ });
796
+ this.passThrough.on('data', (chunk)=>this.response.write(chunk));
797
+ this.passThrough.on('error', (err)=>{
798
+ this.emit('error', err);
799
+ this.end();
800
+ });
801
+ this.passThrough.on('close', ()=>this.end());
802
+ this.response.setHeader(exports.HeaderName.CONTENT_TYPE, 'text/event-stream');
803
+ this.response.setHeader(exports.HeaderName.CACHE_CONTROL, 'private, no-cache, no-store, no-transform, must-revalidate, max-age=0');
804
+ this.response.setHeader(exports.HeaderName.X_ACCEL_BUFFERING, 'no');
805
+ if (!isRequestHTTP2(this.response.req)) {
806
+ this.response.setHeader(exports.HeaderName.CONNECTION, 'keep-alive');
807
+ }
808
+ this.response.statusCode = 200;
809
+ }
810
+ write(message) {
811
+ if (typeof message === 'string') {
812
+ this.write({
813
+ data: message
814
+ });
815
+ return;
816
+ }
817
+ if (!this.passThrough.closed && this.passThrough.writable) {
818
+ this.passThrough.write(serializeEventStreamMessage(message));
819
+ }
820
+ }
821
+ end() {
822
+ if (this.flushed) return;
823
+ this.flushed = true;
824
+ if (!this.passThrough.closed) {
825
+ this.passThrough.end();
826
+ }
827
+ this.emit('close');
828
+ setResponseGone(this.response, true);
829
+ this.response.end();
830
+ }
831
+ on(event, listener) {
832
+ if (typeof this.eventHandlers[event] === 'undefined') {
833
+ this.eventHandlers[event] = [];
834
+ }
835
+ this.eventHandlers[event].push(listener);
836
+ }
837
+ emit(event, ...args) {
838
+ if (typeof this.eventHandlers[event] === 'undefined') {
839
+ return;
840
+ }
841
+ const listeners = this.eventHandlers[event].slice();
842
+ for(let i = 0; i < listeners.length; i++){
843
+ listeners[i].apply(this, args);
844
+ }
845
+ }
846
+ constructor(response){
847
+ this.response = response;
848
+ this.passThrough = new readableStream.PassThrough({
849
+ encoding: 'utf-8'
850
+ });
851
+ this.flushed = false;
852
+ this.eventHandlers = {};
853
+ this.open();
854
+ }
855
+ }
856
+
857
+ function createEventStream(response) {
858
+ return new EventStream(response);
859
+ }
764
860
 
765
861
  function appendResponseHeader(res, name, value) {
766
862
  let header = res.getHeader(name);
@@ -2141,6 +2237,7 @@ class Router {
2141
2237
 
2142
2238
  exports.DispatchErrorEvent = DispatchErrorEvent;
2143
2239
  exports.DispatchEvent = DispatchEvent;
2240
+ exports.EventStream = EventStream;
2144
2241
  exports.Handler = Handler;
2145
2242
  exports.HandlerSymbol = HandlerSymbol;
2146
2243
  exports.PathMatcher = PathMatcher;
@@ -2150,6 +2247,7 @@ exports.appendResponseHeader = appendResponseHeader;
2150
2247
  exports.appendResponseHeaderDirective = appendResponseHeaderDirective;
2151
2248
  exports.coreHandler = coreHandler;
2152
2249
  exports.createError = createError;
2250
+ exports.createEventStream = createEventStream;
2153
2251
  exports.createNodeDispatcher = createNodeDispatcher;
2154
2252
  exports.createRawDispatcher = createRawDispatcher;
2155
2253
  exports.createRequest = createRequest;
@@ -2179,6 +2277,7 @@ exports.isHandlerConfig = isHandlerConfig;
2179
2277
  exports.isPath = isPath;
2180
2278
  exports.isPlugin = isPlugin;
2181
2279
  exports.isRequestCacheable = isRequestCacheable;
2280
+ exports.isRequestHTTP2 = isRequestHTTP2;
2182
2281
  exports.isResponseGone = isResponseGone;
2183
2282
  exports.matchRequestContentType = matchRequestContentType;
2184
2283
  exports.send = send;
@@ -2198,6 +2297,7 @@ exports.setRequestParams = setRequestParams;
2198
2297
  exports.setRequestRouterPath = setRequestRouterPath;
2199
2298
  exports.setResponseCacheHeaders = setResponseCacheHeaders;
2200
2299
  exports.setResponseContentTypeByFileName = setResponseContentTypeByFileName;
2300
+ exports.setResponseGone = setResponseGone;
2201
2301
  exports.setResponseHeaderAttachment = setResponseHeaderAttachment;
2202
2302
  exports.setResponseHeaderContentType = setResponseHeaderContentType;
2203
2303
  exports.transformHeaderToTuples = transformHeaderToTuples;