@@ -7,10 +7,11 @@ const {
77 ObjectDefineProperty,
88 PromiseResolve,
99 PromiseReject,
10- PromisePrototypeFinally ,
10+ SafePromisePrototypeFinally ,
1111 ReflectConstruct,
1212 RegExpPrototypeTest,
1313 StringPrototypeToLowerCase,
14+ StringPrototypeSplit,
1415 Symbol,
1516 SymbolIterator,
1617 SymbolToStringTag,
@@ -20,7 +21,8 @@ const {
2021const {
2122 createBlob : _createBlob ,
2223 FixedSizeBlobCopyJob,
23- } = internalBinding ( 'buffer' ) ;
24+ getDataObject,
25+ } = internalBinding ( 'blob' ) ;
2426
2527const { TextDecoder } = require ( 'internal/encoding' ) ;
2628
@@ -65,18 +67,26 @@ const disallowedTypeCharacters = /[^\u{0020}-\u{007E}]/u;
6567
6668let Buffer ;
6769let ReadableStream ;
70+ let URL ;
71+
72+
73+ // Yes, lazy loading is annoying but because of circular
74+ // references between the url, internal/blob, and buffer
75+ // modules, lazy loading here makes sure that things work.
76+
77+ function lazyURL ( id ) {
78+ URL ??= require ( 'internal/url' ) . URL ;
79+ return new URL ( id ) ;
80+ }
6881
6982function lazyBuffer ( ) {
70- if ( Buffer === undefined )
71- Buffer = require ( 'buffer' ) . Buffer ;
83+ Buffer ??= require ( 'buffer' ) . Buffer ;
7284 return Buffer ;
7385}
7486
7587function lazyReadableStream ( options ) {
76- if ( ReadableStream === undefined ) {
77- ReadableStream =
78- require ( 'internal/webstreams/readablestream' ) . ReadableStream ;
79- }
88+ ReadableStream ??=
89+ require ( 'internal/webstreams/readablestream' ) . ReadableStream ;
8090 return new ReadableStream ( options ) ;
8191}
8292
@@ -232,9 +242,9 @@ class Blob {
232242 return PromiseReject ( new ERR_INVALID_THIS ( 'Blob' ) ) ;
233243
234244 // If there's already a promise in flight for the content,
235- // reuse it, but only once . After the cached promise resolves
236- // it will be cleared, allowing it to be garbage collected
237- // as soon as possible.
245+ // reuse it, but only while it's in flight . After the cached
246+ // promise resolves it will be cleared, allowing it to be
247+ // garbage collected as soon as possible.
238248 if ( this [ kArrayBufferPromise ] )
239249 return this [ kArrayBufferPromise ] ;
240250
@@ -260,15 +270,14 @@ class Blob {
260270 resolve ( ab ) ;
261271 } ;
262272 this [ kArrayBufferPromise ] =
263- PromisePrototypeFinally (
273+ SafePromisePrototypeFinally (
264274 promise ,
265275 ( ) => this [ kArrayBufferPromise ] = undefined ) ;
266276
267277 return this [ kArrayBufferPromise ] ;
268278 }
269279
270280 /**
271- *
272281 * @returns {Promise<string> }
273282 */
274283 async text ( ) {
@@ -315,9 +324,47 @@ ObjectDefineProperty(Blob.prototype, SymbolToStringTag, {
315324 value : 'Blob' ,
316325} ) ;
317326
327+ function resolveObjectURL ( url ) {
328+ url = `${ url } ` ;
329+ try {
330+ const parsed = new lazyURL ( url ) ;
331+
332+ const split = StringPrototypeSplit ( parsed . pathname , ':' ) ;
333+
334+ if ( split . length !== 2 )
335+ return ;
336+
337+ const {
338+ 0 : base ,
339+ 1 : id ,
340+ } = split ;
341+
342+ if ( base !== 'nodedata' )
343+ return ;
344+
345+ const ret = getDataObject ( id ) ;
346+
347+ if ( ret === undefined )
348+ return ;
349+
350+ const {
351+ 0 : handle ,
352+ 1 : length ,
353+ 2 : type ,
354+ } = ret ;
355+
356+ if ( handle !== undefined )
357+ return createBlob ( handle , length , type ) ;
358+ } catch {
359+ // If there's an error, it's ignored and nothing is returned
360+ }
361+ }
362+
318363module . exports = {
319364 Blob,
320365 ClonedBlob,
321366 createBlob,
322367 isBlob,
368+ kHandle,
369+ resolveObjectURL,
323370} ;
0 commit comments