@@ -16,18 +16,34 @@ function getPort() {
16
16
const u = esmurl ( import . meta, async ( ) => {
17
17
const { workerData } = await import ( "node:worker_threads" ) ;
18
18
const port = workerData . port ;
19
+ /** @type {((...a: any[]) => any)[] } */
20
+ const rememberedFunctions = [ ] ;
19
21
port . onmessage = async ( e ) => {
20
- /** @type {[SharedArrayBuffer, string, any[]] } */
21
- const [ lockBuffer , moduleURL , args ] = e . data ;
22
+ /** @type {SharedArrayBuffer } */
23
+ const lockBuffer = e . data [ 0 ] ;
24
+ /** @type {string | number } */
25
+ const executorURLOrId = e . data [ 1 ] ;
26
+ /** @type {any[] } */
27
+ const args = e . data [ 2 ] ;
22
28
const lock = new Int32Array ( lockBuffer ) ;
29
+
23
30
/** @type {[any] | [void, any] } */
24
31
let r ;
25
32
try {
26
- const module = await import ( moduleURL ) ;
27
- r = [ await module . default . apply ( undefined , args ) ] ;
33
+ /** @type {((...a: any[]) => any) } */
34
+ let f ;
35
+ if ( typeof executorURLOrId === "number" ) {
36
+ f = rememberedFunctions [ executorURLOrId ] ;
37
+ } else {
38
+ const module = await import ( executorURLOrId ) ;
39
+ f = await module . default ;
40
+ rememberedFunctions . push ( f ) ;
41
+ }
42
+ r = [ await f ( ...args ) ] ;
28
43
} catch ( e ) {
29
44
r = [ , e ] ;
30
45
}
46
+
31
47
port . postMessage ( r ) ;
32
48
Atomics . store ( lock , 0 , 1 ) ;
33
49
Atomics . notify ( lock , 0 ) ;
@@ -48,34 +64,48 @@ function getPort() {
48
64
/** @type {{ worker: NodeWorker, port: MessagePort } | null | undefined } */
49
65
getPort . c ;
50
66
67
+ /** @type {string[] } */
68
+ const rememberedURLs = [ ] ;
69
+
51
70
/**
52
71
* @template {any[]} A
53
72
* @template R
54
73
* @param {((...args: A) => R) | string | URL } functionOrURL
55
74
* @returns {(...args: A) => Awaited<R> }
56
75
*/
57
76
function redlet ( functionOrURL ) {
77
+ /** @type {string } */
58
78
let executorURL ;
79
+ /** @type {((...args: A) => R) | null | undefined } */
59
80
let maybeFunction ;
60
81
if ( typeof functionOrURL === "function" ) {
61
82
maybeFunction = functionOrURL ;
62
83
const code = `export default ${ functionOrURL } ` ;
63
84
executorURL =
64
85
"data:text/javascript;base64," + Buffer . from ( code ) . toString ( "base64" ) ;
65
86
} else if ( URLCanParse ( functionOrURL ) ) {
66
- executorURL = functionOrURL ;
87
+ executorURL = ` ${ functionOrURL } ` ;
67
88
} else {
68
89
const code = `export default ${ functionOrURL } ` ;
69
90
executorURL =
70
91
"data:text/javascript;base64," + Buffer . from ( code ) . toString ( "base64" ) ;
71
92
}
72
93
94
+ /**
95
+ * @param {A } args
96
+ * @returns {Awaited<R> }
97
+ */
73
98
function run ( ...args ) {
74
99
const port = getPort ( ) ;
75
100
76
101
const lockBuffer = new SharedArrayBuffer ( 4 ) ;
77
102
const lock = new Int32Array ( lockBuffer ) ;
78
- port . postMessage ( [ lockBuffer , executorURL , args ] ) ;
103
+ if ( rememberedURLs . includes ( executorURL ) ) {
104
+ port . postMessage ( [ lockBuffer , rememberedURLs . indexOf ( executorURL ) , args ] ) ;
105
+ } else {
106
+ port . postMessage ( [ lockBuffer , executorURL , args ] ) ;
107
+ rememberedURLs . push ( executorURL ) ;
108
+ }
79
109
Atomics . wait ( lock , 0 , 0 ) ;
80
110
81
111
/** @type {[any] | [void, any] } */
0 commit comments