-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathmain.js
91 lines (81 loc) · 1.95 KB
/
main.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
// (c) Andrea Giammarchi - MIT
import {
Atomics,
Int32Array,
SharedArrayBuffer,
Worker as $Worker,
ignore,
polyfill,
} from 'sabayon/main';
import {
ACTION_INIT,
ACTION_WAIT,
ACTION_NOTIFY,
actionLength,
actionFill,
actionWait,
createProxy,
isChannel,
transfer,
} from './shared.js';
/**
* @typedef {Object} MainOptions
* @prop {(text: string, ...args:any) => any} [parse=JSON.parse]
* @prop {(value: any, ...args:any) => string} [stringify=JSON.stringify]
* @prop {(value: any) => any} [transform]
*/
/**
* @callback Coincident
* @param {MainOptions} [options]
* @returns {{Worker: import('./ts.js').CoincidentWorker, polyfill: boolean, transfer: (...args: Transferable[]) => Transferable[]}}
*/
export default /** @type {Coincident} */ ({
parse,
stringify,
transform,
} = JSON) => {
const waitLength = actionLength(stringify, transform);
class Worker extends $Worker {
constructor(url, options) {
const CHANNEL = crypto.randomUUID();
const map = new Map;
const results = new Map;
super(url, options);
this.proxy = createProxy(
[
CHANNEL,
bytes => new Int32Array(new SharedArrayBuffer(bytes)),
ignore,
false,
parse,
polyfill,
(...args) => this.postMessage(...args),
transform,
Atomics.waitAsync,
],
map,
);
this.postMessage(ignore([CHANNEL, ACTION_INIT, options]));
this.addEventListener('message', event => {
if (isChannel(event, CHANNEL)) {
const [_, ACTION, ...rest] = event.data;
switch (ACTION) {
case ACTION_WAIT: {
actionWait(waitLength, results, map, rest);
break;
}
case ACTION_NOTIFY: {
actionFill(results, rest);
break;
}
}
}
});
}
}
return {
Worker,
polyfill,
transfer,
};
};