-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathexample_one__launcher.js
More file actions
118 lines (112 loc) 路 3.48 KB
/
Copy pathexample_one__launcher.js
File metadata and controls
118 lines (112 loc) 路 3.48 KB
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
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
const SkyrocketMessageIdentifier = '-srwm';
const SkyrocketErrorIdentifier = '-srwme';
function createShell(Global, schema, WorkerMain) {
const channel = {
onmessage: function (...args) { },
postMessage: function (a, b) {
Global.postMessage(a, b);
},
};
const isWorker = typeof WorkerGlobalScope !== 'undefined' && self instanceof WorkerGlobalScope;
const worker = new WorkerMain(channel, { isWorker });
let DEF_CACHE = Object.create(null);
async function recieve(event) {
const data = event.data;
if (Array.isArray(data) && data[0] === SkyrocketMessageIdentifier) {
const fieldDef = getFieldDef(data[1]);
switch (fieldDef[0]) {
case 1: // method
try {
const result = await exec(worker, data[1], data[2]);
return send(result, data[3]);
}
catch (e) {
const result = {
message: e.message,
stack: e.stack,
};
return send(result, data[3]);
}
case 2: // event
return exec(worker, data[1], data[2]);
case 3: // signal
return exec(worker, data[1], data[2]);
default:
throw new Error(`Unknown field type`);
}
}
else {
channel.onmessage(...arguments);
}
}
function getFieldDef(name) {
let def = DEF_CACHE[name];
if (def === undefined) {
for (let i = 0; i < schema.length; i += 3) {
let fieldType = schema[i];
let fieldName = schema[i + 1];
let fieldConfig = schema[i + 2];
if (fieldName === name) {
def = DEF_CACHE[name] = [fieldType, fieldConfig];
}
}
if (!def) {
throw new Error(`No such SkyrocketWorker field ${name}`);
}
}
return def;
}
function send(data, id) {
if (data instanceof Error) {
Global.postMessage([SkyrocketErrorIdentifier, data, id]);
}
else {
Global.postMessage([SkyrocketMessageIdentifier, data, id]);
}
}
Global.onmessage = recieve;
}
function exec(worker, fieldName, args) {
if (args !== undefined) {
return worker[fieldName](...args);
}
return worker[fieldName]();
}
function setupWorkerShell(Global, schemaStr, WorkerMain) {
const schema = JSON.parse(schemaStr);
createShell(Global, schema, WorkerMain);
}
/**
* The `method` decorator allows you to specify
* a method callable by the main thread that
* has a return value.
*
* It may take any number of args, as long as they
* are serializeable in JSON.
*
* The response must also be serializable.
*
* ```ts
* class DataWorker extends SkyrocketWorker {
* @method
* fetchData(url, options) {
* return fetch(url).then(r => r.toJSON());
* }
* }
* ```
*
* @method signal
* @public
*/
// TODO async iteration with @iterable
// TODO byte streams with @stream
// TODO async byte iteration with @chunk
// TODO Atomics and SharedArrayBuffer
class SkyrocketWorker {
}
class WorkerOne extends SkyrocketWorker {
fetchUsers() {}
reload() {}
}
var schema = '[1,"fetchUsers",0,2,"reload",0]';
setupWorkerShell(self, schema, WorkerOne);