66 MathMin,
77 ObjectDefineProperties,
88 ObjectDefineProperty,
9- PromiseResolve,
109 PromiseReject,
11- SafePromisePrototypeFinally,
1210 ReflectConstruct,
1311 RegExpPrototypeExec,
1412 RegExpPrototypeSymbolReplace,
@@ -22,7 +20,7 @@ const {
2220
2321const {
2422 createBlob : _createBlob ,
25- FixedSizeBlobCopyJob ,
23+ concat ,
2624 getDataObject,
2725} = internalBinding ( 'blob' ) ;
2826
@@ -51,7 +49,6 @@ const {
5149const { inspect } = require ( 'internal/util/inspect' ) ;
5250
5351const {
54- AbortError,
5552 codes : {
5653 ERR_INVALID_ARG_TYPE ,
5754 ERR_INVALID_ARG_VALUE ,
@@ -66,13 +63,8 @@ const {
6663} = require ( 'internal/validators' ) ;
6764
6865const kHandle = Symbol ( 'kHandle' ) ;
69- const kState = Symbol ( 'kState' ) ;
70- const kIndex = Symbol ( 'kIndex' ) ;
7166const kType = Symbol ( 'kType' ) ;
7267const kLength = Symbol ( 'kLength' ) ;
73- const kArrayBufferPromise = Symbol ( 'kArrayBufferPromise' ) ;
74-
75- const kMaxChunkSize = 65536 ;
7668
7769const disallowedTypeCharacters = / [ ^ \u{0020} - \u{007E} ] / u;
7870
@@ -271,40 +263,23 @@ class Blob {
271263 if ( ! isBlob ( this ) )
272264 return PromiseReject ( new ERR_INVALID_THIS ( 'Blob' ) ) ;
273265
274- // If there's already a promise in flight for the content,
275- // reuse it, but only while it's in flight. After the cached
276- // promise resolves it will be cleared, allowing it to be
277- // garbage collected as soon as possible.
278- if ( this [ kArrayBufferPromise ] )
279- return this [ kArrayBufferPromise ] ;
280-
281- const job = new FixedSizeBlobCopyJob ( this [ kHandle ] ) ;
282-
283- const ret = job . run ( ) ;
284-
285- // If the job returns a value immediately, the ArrayBuffer
286- // was generated synchronously and should just be returned
287- // directly.
288- if ( ret !== undefined )
289- return PromiseResolve ( ret ) ;
290-
291- const {
292- promise,
293- resolve,
294- reject,
295- } = createDeferredPromise ( ) ;
296-
297- job . ondone = ( err , ab ) => {
298- if ( err !== undefined )
299- return reject ( new AbortError ( undefined , { cause : err } ) ) ;
300- resolve ( ab ) ;
266+ const { promise, resolve } = createDeferredPromise ( ) ;
267+ const reader = this [ kHandle ] . getReader ( ) ;
268+ const buffers = [ ] ;
269+ const readNext = ( ) => {
270+ const result = reader . pull ( ( status , buffer ) => {
271+ if ( status === - 1 ) {
272+ // EOS, concat & resolve
273+ // buffer should be undefined here
274+ resolve ( concat ( buffers ) ) ;
275+ return ;
276+ }
277+ buffers . push ( buffer ) ;
278+ readNext ( ) ;
279+ } ) ;
301280 } ;
302- this [ kArrayBufferPromise ] =
303- SafePromisePrototypeFinally (
304- promise ,
305- ( ) => this [ kArrayBufferPromise ] = undefined ) ;
306-
307- return this [ kArrayBufferPromise ] ;
281+ readNext ( ) ;
282+ return promise ;
308283 }
309284
310285 /**
@@ -326,22 +301,22 @@ class Blob {
326301 if ( ! isBlob ( this ) )
327302 throw new ERR_INVALID_THIS ( 'Blob' ) ;
328303
329- const self = this ;
304+ const reader = this [ kHandle ] . getReader ( ) ;
330305 return new lazyReadableStream ( {
331- async start ( ) {
332- this [ kState ] = await self . arrayBuffer ( ) ;
333- this [ kIndex ] = 0 ;
334- } ,
335-
336- pull ( controller ) {
337- if ( this [ kState ] . byteLength - this [ kIndex ] <= kMaxChunkSize ) {
338- controller . enqueue ( new Uint8Array ( this [ kState ] , this [ kIndex ] ) ) ;
339- controller . close ( ) ;
340- this [ kState ] = undefined ;
341- } else {
342- controller . enqueue ( new Uint8Array ( this [ kState ] , this [ kIndex ] , kMaxChunkSize ) ) ;
343- this [ kIndex ] += kMaxChunkSize ;
344- }
306+ #reader: reader ,
307+ pull ( c ) {
308+ const { promise , resolve } = createDeferredPromise ( ) ;
309+ reader . pull ( ( status , buffer ) => {
310+ if ( status === 1 ) {
311+ // EOS
312+ c . close ( ) ;
313+ resolve ( ) ;
314+ return ;
315+ }
316+ c . enqueue ( new Uint8Array ( buffer ) ) ;
317+ resolve ( ) ;
318+ } ) ;
319+ return promise ;
345320 }
346321 } ) ;
347322 }
0 commit comments