33 * @public
44 */
55export default function greenlet ( asyncFunction ) {
6+ // A simple counter is used to generate worker-global unique ID's for RPC:
7+ let currentId = 0 ;
8+
9+ // Outward-facing promises store their "controllers" (`[request, reject]`) here:
10+ const promises = { } ;
11+
612 // Create an "inline" worker (1:1 at definition time)
7- let worker = new Worker (
8- // The URL is a pointer to a stringified function (as a blob object)
9- URL . createObjectURL (
10- new Blob ( [
11- // Register our wrapper function as the message handler
12- 'onmessage=(' + (
13- // userFunc() is the user-supplied async function
14- userFunc => e => {
15- // Invoking within then() captures exceptions in userFunc() as rejections
16- Promise . resolve ( e . data [ 1 ] ) . then (
17- userFunc . apply . bind ( userFunc , userFunc )
18- ) . then (
19- // success handler - callback(id, SUCCESS(0), result)
20- // if `d` is transferable transfer zero-copy
21- d => {
22- postMessage ( [ e . data [ 0 ] , 0 , d ] , (
23- d instanceof ArrayBuffer ||
24- d instanceof MessagePort ||
25- d instanceof ImageBitmap ) ? [ d ] : [ ] ) ;
26- } ,
27- // error handler - callback(id, ERROR(1), error)
28- er => { postMessage ( [ e . data [ 0 ] , 1 , '' + er ] ) ; }
29- ) ;
30- }
31- ) + ')(' + asyncFunction + ')' // pass user-supplied function to the closure
32- ] )
33- )
34- ) ,
13+ const worker = new Worker (
14+ 'data:,$$=' + asyncFunction + ';onmessage=' + ( e => {
15+ /* global $$ */
3516
36- // A simple counter is used to generate worker-global unique ID's for RPC:
37- currentId = 0 ,
17+ // Invoking within then() captures exceptions in userFunc() as rejections
18+ Promise . resolve ( ) . then (
19+ $$ . bind . apply ( $$ , e . data )
20+ ) . then (
21+ // success handler - callback(id, SUCCESS(0), result)
22+ // if `d` is transferable transfer zero-copy
23+ d => {
24+ postMessage ( [ e . data [ 0 ] , 0 , d ] , [ d ] . filter ( x => (
25+ ( x instanceof ArrayBuffer ) ||
26+ ( x instanceof MessagePort ) ||
27+ ( x instanceof ImageBitmap )
28+ ) ) ) ;
29+ } ,
30+ // error handler - callback(id, ERROR(1), error)
31+ er => { postMessage ( [ e . data [ 0 ] , 1 , '' + er ] ) ; }
32+ ) ;
33+ } )
3834
39- // Outward-facing promises store their "controllers" (`[request, reject]`) here:
40- promises = { } ;
35+ /*
36+ // The URL is a pointer to a stringified function (as a blob object)
37+ URL.createObjectURL(
38+ new Blob([
39+ '$$=', asyncFunction,
40+ // Register our wrapper function as the message handler
41+ ';onmessage=',
42+ // userFunc() is the user-supplied async function
43+ e => {
44+ // Invoking within then() captures exceptions in userFunc() as rejections
45+ Promise.resolve().then(
46+ $$.bind.apply($$, e.data)
47+ ).then(
48+ // success handler - callback(id, SUCCESS(0), result)
49+ // if `d` is transferable transfer zero-copy
50+ d => {
51+ postMessage([e.data[0], 0, d], [d].filter(x => (
52+ (x instanceof ArrayBuffer) ||
53+ (x instanceof MessagePort) ||
54+ (x instanceof ImageBitmap)
55+ )));
56+ },
57+ // error handler - callback(id, ERROR(1), error)
58+ er => { postMessage([e.data[0], 1, '' + er]); }
59+ );
60+ }
61+ ])
62+ )
63+ */
64+ ) ;
4165
4266 /** Handle RPC results/errors coming back out of the worker.
4367 * Messages coming from the worker take the form `[id, status, result]`:
@@ -63,9 +87,9 @@ export default function greenlet(asyncFunction) {
6387 // Send an RPC call to the worker - call(id, params)
6488 // The filter is to provide a list of transferables to send zero-copy
6589 worker . postMessage ( [ currentId , args ] , args . filter ( x => (
66- x instanceof ArrayBuffer ||
67- x instanceof MessagePort ||
68- x instanceof ImageBitmap
90+ ( x instanceof ArrayBuffer ) ||
91+ ( x instanceof MessagePort ) ||
92+ ( x instanceof ImageBitmap )
6993 ) ) ) ;
7094 } ) ;
7195 } ;
0 commit comments