@@ -33,6 +33,8 @@ import { AppCheckInternalComponentName } from '@firebase/app-check-interop-types
3333
3434export const DEFAULT_REGION = 'us-central1' ;
3535
36+ const responseLineRE = / ^ d a t a : ( .* ?) (?: \n | $ ) / ;
37+
3638/**
3739 * The response to an http request.
3840 */
@@ -449,7 +451,6 @@ async function streamAtURL(
449451
450452 let resultResolver : ( value : unknown ) => void ;
451453 let resultRejecter : ( reason : unknown ) => void ;
452-
453454 const resultPromise = new Promise < unknown > ( ( resolve , reject ) => {
454455 resultResolver = resolve ;
455456 resultRejecter = reject ;
@@ -463,14 +464,51 @@ async function streamAtURL(
463464 resultRejecter ( error ) ;
464465 } ) ;
465466
467+ const reader = response . body ! . getReader ( ) ;
468+ const rstream = createResponseStream (
469+ reader ,
470+ resultResolver ! ,
471+ resultRejecter ! ,
472+ options ?. signal
473+ ) ;
474+
475+ return {
476+ stream : {
477+ [ Symbol . asyncIterator ] ( ) {
478+ const rreader = rstream . getReader ( ) ;
479+ return {
480+ async next ( ) {
481+ const { value, done } = await rreader . read ( ) ;
482+ return { value : value as unknown , done } ;
483+ } ,
484+ async return ( ) {
485+ await rreader . cancel ( ) ;
486+ return { done : true , value : undefined } ;
487+ }
488+ } ;
489+ }
490+ } ,
491+ data : resultPromise ,
492+ } ;
493+ }
494+
495+ function createResponseStream (
496+ reader : ReadableStreamDefaultReader < Uint8Array > ,
497+ resultResolver : ( value : unknown ) => void ,
498+ resultRejecter : ( reason : unknown ) => void ,
499+ signal ?: AbortSignal
500+ ) : ReadableStream < unknown > {
466501 const processLine = ( line : string , controller : ReadableStreamDefaultController ) : void => {
502+ const match = line . match ( responseLineRE ) ;
503+ //
467504 // ignore all other lines (newline, comments, etc.)
468- if ( ! line . startsWith ( 'data: ' ) ) {
505+ if ( ! match ) {
469506 return ;
470507 }
508+
509+ const data = match [ 1 ] ;
471510 try {
472- // Skip 'data: ' (5 chars)
473- const jsonData = JSON . parse ( line . slice ( 6 ) ) ;
511+ const jsonData = JSON . parse ( data ) ;
474512 if ( 'result' in jsonData ) {
475513 resultResolver ( decode ( jsonData . result ) ) ;
476514 return ;
@@ -495,14 +533,13 @@ async function streamAtURL(
495533 }
496534 } ;
497535
498- const reader = response . body ! . getReader ( ) ;
499536 const decoder = new TextDecoder ( ) ;
500- const rstream = new ReadableStream ( {
537+ return new ReadableStream ( {
501538 start ( controller ) {
502539 let currentText = '' ;
503540 return pump ( ) ;
504541 async function pump ( ) : Promise < void > {
505- if ( options ?. signal ?. aborted ) {
542+ if ( signal ?. aborted ) {
506543 const error = new FunctionsError ( 'cancelled' , 'Request was cancelled' ) ;
507544 controller . error ( error ) ;
508545 resultRejecter ( error ) ;
@@ -519,7 +556,7 @@ async function streamAtURL(
519556 return ;
520557 }
521558
522- if ( options ?. signal ?. aborted ) {
559+ if ( signal ?. aborted ) {
523560 const error = new FunctionsError ( 'cancelled' , 'Request was cancelled' ) ;
524561 controller . error ( error ) ;
525562 resultRejecter ( error ) ;
@@ -551,22 +588,5 @@ async function streamAtURL(
551588 }
552589 } ) ;
553590
554- return {
555- stream : {
556- [ Symbol . asyncIterator ] ( ) {
557- const rreader = rstream . getReader ( ) ;
558- return {
559- async next ( ) {
560- const { value, done } = await rreader . read ( ) ;
561- return { value : value as unknown , done } ;
562- } ,
563- async return ( ) {
564- await reader . cancel ( ) ;
565- return { done : true , value : undefined } ;
566- }
567- } ;
568- }
569- } ,
570- data : resultPromise ,
571- } ;
591+
572592}
0 commit comments