11'use strict'
22
33const assert = require ( 'node:assert' )
4+ const { Readable } = require ( 'node:stream' )
45const util = require ( '../core/util' )
56const CacheHandler = require ( '../handler/cache-handler' )
67const MemoryCacheStore = require ( '../cache/memory-cache-store' )
@@ -57,20 +58,20 @@ module.exports = (opts = {}) => {
5758 // Where body can be a Buffer, string, stream or blob?
5859 const result = store . get ( cacheKey )
5960 if ( ! result ) {
60- // Request isn't cached
6161 return dispatch ( opts , new CacheHandler ( globalOpts , cacheKey , handler ) )
6262 }
6363
6464 /**
65- * @param {import('node:stream').Readable | undefined } stream
65+ * @param {import('node:stream').Readable } stream
6666 * @param {import('../../types/cache-interceptor.d.ts').default.CachedResponse } value
6767 */
6868 const respondWithCachedValue = ( stream , value ) => {
69- assert ( ! stream || ! stream . destroyed , 'stream should not be destroyed' )
70- assert ( ! stream || ! stream . readableDidRead , 'stream should not be readableDidRead' )
69+ assert ( ! stream . destroyed , 'stream should not be destroyed' )
70+ assert ( ! stream . readableDidRead , 'stream should not be readableDidRead' )
71+
7172 try {
7273 stream
73- ? .on ( 'error' , function ( err ) {
74+ . on ( 'error' , function ( err ) {
7475 if ( ! this . readableEnded ) {
7576 if ( typeof handler . onError === 'function' ) {
7677 handler . onError ( err )
@@ -89,10 +90,10 @@ module.exports = (opts = {}) => {
8990
9091 if ( typeof handler . onConnect === 'function' ) {
9192 handler . onConnect ( ( err ) => {
92- stream ? .destroy ( err )
93+ stream . destroy ( err )
9394 } )
9495
95- if ( stream ? .destroyed ) {
96+ if ( stream . destroyed ) {
9697 return
9798 }
9899 }
@@ -106,16 +107,12 @@ module.exports = (opts = {}) => {
106107 const rawHeaders = [ ...value . rawHeaders , AGE_HEADER , Buffer . from ( `${ age } ` ) ]
107108
108109 if ( handler . onHeaders ( value . statusCode , rawHeaders , ( ) => stream ?. resume ( ) , value . statusMessage ) === false ) {
109- stream ? .pause ( )
110+ stream . pause ( )
110111 }
111112 }
112113
113114 if ( opts . method === 'HEAD' ) {
114- if ( typeof handler . onComplete === 'function' ) {
115- handler . onComplete ( [ ] )
116- }
117-
118- stream ?. destroy ( )
115+ stream . destroy ( )
119116 } else {
120117 stream . on ( 'data' , function ( chunk ) {
121118 if ( typeof handler . onData === 'function' && ! handler . onData ( chunk ) ) {
@@ -124,15 +121,20 @@ module.exports = (opts = {}) => {
124121 } )
125122 }
126123 } catch ( err ) {
127- stream ? .destroy ( err )
124+ stream . destroy ( err )
128125 }
129126 }
130127
131128 /**
132129 * @param {import('../../types/cache-interceptor.d.ts').default.GetResult } result
133130 */
134131 const handleStream = ( result ) => {
135- const { response : value , body : stream } = result
132+ const { response : value , body } = result
133+
134+ // TODO (perf): Readable.from path can be optimized...
135+ const stream = util . isStream ( body )
136+ ? body
137+ : Readable . from ( body ?? [ ] )
136138
137139 if ( ! stream && opts . method !== 'HEAD' ) {
138140 throw new Error ( 'stream is undefined but method isn\'t HEAD' )
@@ -177,12 +179,17 @@ module.exports = (opts = {}) => {
177179 if ( typeof result . then === 'function' ) {
178180 result . then ( ( result ) => {
179181 if ( ! result ) {
180- // Request isn't cached
181- return dispatch ( opts , new CacheHandler ( globalOpts , cacheKey , handler ) )
182+ dispatch ( opts , new CacheHandler ( globalOpts , cacheKey , handler ) )
183+ } else {
184+ handleStream ( result )
182185 }
183-
184- handleStream ( result )
185- } ) . catch ( err => handler . onError ( err ) )
186+ } , err => {
187+ if ( typeof handler . onError === 'function' ) {
188+ handler . onError ( err )
189+ } else {
190+ throw err
191+ }
192+ } )
186193 } else {
187194 handleStream ( result )
188195 }
0 commit comments