Skip to content

Commit c8676d7

Browse files
committed
v0.6.0
1 parent 0cddd29 commit c8676d7

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+804
-110
lines changed

CHANGE.md

+5
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
## v0.6.0
2+
3+
- New tests are added to the platform lib.
4+
- Running WebAssembly modules is implemented.
5+
16
## v0.5.15
27

38
- New tests are added to the platform lib.

apps/sample/wasm/asconfig.json

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
{
2+
"targets": {
3+
"debug": {
4+
"outFile": "build/index.debug.wasm",
5+
"textFile": "build/index.debug.wat",
6+
"sourceMap": true,
7+
"debug": true
8+
},
9+
"release": {
10+
"outFile": "build/index.wasm",
11+
"textFile": "build/index.wat",
12+
"sourceMap": true,
13+
"optimizeLevel": 3,
14+
"shrinkLevel": 0,
15+
"converge": false,
16+
"noAssert": false
17+
}
18+
},
19+
"options": {
20+
"bindings": "esm"
21+
}
22+
}

apps/sample/wasm/package.json

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{
2+
"type": "module",
3+
"scripts": {
4+
"build": "bash ./scripts/build.sh"
5+
},
6+
"devDependencies": {
7+
"assemblyscript": "^0.27.1",
8+
"typescript": "^4.9.5"
9+
},
10+
"license": "MIT"
11+
}

apps/sample/wasm/scripts/build.sh

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
#!/bin/bash
2+
3+
rm -rf build
4+
5+
npx asc src/index.ts --target release

apps/sample/wasm/src/index.ts

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
export function add(a: i32, b: i32): i32 {
2+
return a + b
3+
}

apps/sample/wasm/tsconfig.json

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"extends": "./node_modules/assemblyscript/std/assembly.json",
3+
"include": ["src/**/*.ts"]
4+
}

dist/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"type": "module",
33
"name": "@bitair/concurrent.js",
4-
"version": "0.5.15",
4+
"version": "0.6.0",
55
"description": "Easy Multithreading for JavaScript (Node.js, Deno & Browser)",
66
"main": "src/node/index.js",
77
"browser": "src/browser/index.js",

dist/src/browser/index.js

+36-6
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ var __publicField = (obj, key, value) => {
1313
var constants_exports = {};
1414
__export(constants_exports, {
1515
ErrorMessage: () => ErrorMessage,
16+
ModuleExt: () => ModuleExt,
1617
TaskType: () => TaskType,
1718
ThreadMessageType: () => ThreadMessageType,
1819
ValueType: () => ValueType,
@@ -46,9 +47,20 @@ var ErrorMessage = {
4647
WorkerNotSupported: { code: 507, text: "This browser doesn't support web workers." },
4748
ThreadAllocationTimeout: { code: 508, text: "Thread allocation failed due to timeout." },
4849
MethodAssignment: { code: 509, text: "Can't assign a method." },
49-
NotAccessibleExport: { code: 510, text: "Can't access an export of type '%{0}'. Only top level functions and classes are imported." },
50+
NotAccessibleExport: {
51+
code: 510,
52+
text: "Can't access an export of type '%{0}'. Only top level functions and classes are imported."
53+
},
5054
ThreadPoolTerminated: { code: 511, text: "Thread pool has been terminated." },
51-
ThreadTerminated: { code: 512, text: "Thread has been terminated." }
55+
ThreadTerminated: { code: 512, text: "Thread has been terminated." },
56+
UnrecognizedModuleType: {
57+
code: 513,
58+
text: "A module with an unrecognized type has been passed '%{0}'."
59+
},
60+
UnexportedFunction: {
61+
code: 514,
62+
text: "No function with the name '%{0}' has been exported in module '{%1}'."
63+
}
5264
};
5365
var ValueType = {
5466
undefined: 1,
@@ -71,6 +83,10 @@ var defaultConcurrencySettings = Object.assign(
7183
},
7284
defaultThreadPoolSettings
7385
);
86+
var ModuleExt = /* @__PURE__ */ ((ModuleExt2) => {
87+
ModuleExt2["WASM"] = ".wasm";
88+
return ModuleExt2;
89+
})(ModuleExt || {});
7490

7591
// libs/platform/src/core/utils.ts
7692
function isBoolean(val) {
@@ -128,6 +144,12 @@ function createObject(properties) {
128144
}
129145
return obj;
130146
}
147+
function isNativeModule(moduleSrc) {
148+
if (moduleSrc.endsWith(".wasm" /* WASM */))
149+
return false;
150+
else
151+
return true;
152+
}
131153

132154
// libs/platform/src/core/error.ts
133155
var ConcurrencyError = class extends Error {
@@ -238,14 +260,22 @@ var ConcurrentModule = class {
238260
this.src = src;
239261
}
240262
async load() {
241-
const moduleSrc = this.src;
242-
const module = await import(this.src);
263+
const moduleSrc = this.src.toString();
264+
const module = isNativeModule(moduleSrc) ? await import(moduleSrc) : {};
243265
const thread = await this.pool.getThread();
244266
const cache = {};
245267
return new Proxy(module, {
246268
get(obj, key) {
247269
const _export = Reflect.get(obj, key);
248-
if (!Reflect.has(obj, key))
270+
if (key === "then")
271+
return;
272+
else if (!isNativeModule(moduleSrc)) {
273+
if (!Reflect.has(cache, key)) {
274+
const threadedFunction = new ThreadedFunction(thread, moduleSrc, key);
275+
Reflect.set(cache, key, (...params) => threadedFunction.invoke(params));
276+
}
277+
return Reflect.get(cache, key);
278+
} else if (!Reflect.has(obj, key))
249279
return;
250280
else if (!isFunction(_export))
251281
throw new ConcurrencyError(ErrorMessage.NotAccessibleExport);
@@ -485,7 +515,7 @@ var Master = class {
485515
this.start();
486516
const module = this.settings.disabled ? {
487517
load: () => import(moduleSrc.toString())
488-
} : new ConcurrentModule(this.pool, moduleSrc.toString());
518+
} : new ConcurrentModule(this.pool, moduleSrc);
489519
return module;
490520
}
491521
async terminate(force) {

dist/src/browser/worker_script.js

+64-7
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,20 @@ var ErrorMessage = {
2828
WorkerNotSupported: { code: 507, text: "This browser doesn't support web workers." },
2929
ThreadAllocationTimeout: { code: 508, text: "Thread allocation failed due to timeout." },
3030
MethodAssignment: { code: 509, text: "Can't assign a method." },
31-
NotAccessibleExport: { code: 510, text: "Can't access an export of type '%{0}'. Only top level functions and classes are imported." },
31+
NotAccessibleExport: {
32+
code: 510,
33+
text: "Can't access an export of type '%{0}'. Only top level functions and classes are imported."
34+
},
3235
ThreadPoolTerminated: { code: 511, text: "Thread pool has been terminated." },
33-
ThreadTerminated: { code: 512, text: "Thread has been terminated." }
36+
ThreadTerminated: { code: 512, text: "Thread has been terminated." },
37+
UnrecognizedModuleType: {
38+
code: 513,
39+
text: "A module with an unrecognized type has been passed '%{0}'."
40+
},
41+
UnexportedFunction: {
42+
code: 514,
43+
text: "No function with the name '%{0}' has been exported in module '{%1}'."
44+
}
3445
};
3546
var ValueType = {
3647
undefined: 1,
@@ -111,6 +122,12 @@ function createObject(properties) {
111122
}
112123
return obj;
113124
}
125+
function isNativeModule(moduleSrc) {
126+
if (moduleSrc.endsWith(".wasm" /* WASM */))
127+
return false;
128+
else
129+
return true;
130+
}
114131

115132
// libs/platform/src/core/error.ts
116133
var ConcurrencyError = class extends Error {
@@ -173,6 +190,9 @@ __publicField(ThreadedObject, "objectRegistry", new FinalizationRegistry(({ id,
173190

174191
// libs/platform/src/core/worker_manager.ts
175192
var WorkerManager = class {
193+
constructor(interopHandler) {
194+
this.interopHandler = interopHandler;
195+
}
176196
objects = /* @__PURE__ */ new Map();
177197
lastObjectId = 0;
178198
async handleMessage(type, data) {
@@ -240,9 +260,13 @@ var WorkerManager = class {
240260
async invokeFunction(moduleSrc, functionName, args = []) {
241261
let result, error;
242262
try {
243-
const module = await import(moduleSrc);
244-
const method = Reflect.get(module, functionName);
245-
result = await method.apply(module.exports, args);
263+
if (!isNativeModule(moduleSrc)) {
264+
result = await this.interopHandler.run(moduleSrc, functionName, args);
265+
} else {
266+
const module = await import(moduleSrc);
267+
const method = Reflect.get(module, functionName);
268+
result = await method.apply(module.exports, args);
269+
}
246270
} catch (err) {
247271
error = err;
248272
}
@@ -347,10 +371,43 @@ var WorkerManager = class {
347371
}
348372
};
349373

374+
// libs/platform/src/core/interop/wasm.ts
375+
var WasmInteropHandler = class {
376+
constructor(createInstance) {
377+
this.createInstance = createInstance;
378+
}
379+
cache = /* @__PURE__ */ new Map();
380+
async run(moduleSrc, functionName, args) {
381+
let instance;
382+
if (this.cache.has(moduleSrc))
383+
instance = this.cache.get(moduleSrc);
384+
else {
385+
instance = await this.createInstance(moduleSrc);
386+
this.cache.set(moduleSrc, instance);
387+
}
388+
const fn = Reflect.get(instance.exports, functionName);
389+
if (!fn)
390+
throw new ConcurrencyError(ErrorMessage.UnexportedFunction, functionName, moduleSrc);
391+
const result = Reflect.apply(fn, instance.exports, args);
392+
return result;
393+
}
394+
};
395+
350396
// libs/platform/src/browser/worker_script.ts
351397
if (void 0)
352-
throw new ConcurrencyError2(Constants.ErrorMessage.NotRunningOnWorker);
353-
var manager = new WorkerManager();
398+
throw new ConcurrencyError(Constants.ErrorMessage.NotRunningOnWorker);
399+
var wasmInteropHandler = new WasmInteropHandler(async (moduleSrc) => {
400+
const { instance } = await WebAssembly.instantiateStreaming(fetch(moduleSrc));
401+
return instance;
402+
});
403+
var manager = new WorkerManager({
404+
run(moduleSrc, functionName, args) {
405+
if (moduleSrc.endsWith(".wasm" /* WASM */))
406+
return wasmInteropHandler.run(moduleSrc, functionName, args);
407+
else
408+
throw new ConcurrencyError(ErrorMessage.UnrecognizedModuleType, moduleSrc);
409+
}
410+
});
354411
onmessage = function(e) {
355412
const [type, data] = e.data;
356413
manager.handleMessage(type, data).then((reply) => {

dist/src/deno/index.js

+31-6
Original file line numberDiff line numberDiff line change
@@ -65,9 +65,20 @@ var ErrorMessage = {
6565
WorkerNotSupported: { code: 507, text: "This browser doesn't support web workers." },
6666
ThreadAllocationTimeout: { code: 508, text: "Thread allocation failed due to timeout." },
6767
MethodAssignment: { code: 509, text: "Can't assign a method." },
68-
NotAccessibleExport: { code: 510, text: "Can't access an export of type '%{0}'. Only top level functions and classes are imported." },
68+
NotAccessibleExport: {
69+
code: 510,
70+
text: "Can't access an export of type '%{0}'. Only top level functions and classes are imported."
71+
},
6972
ThreadPoolTerminated: { code: 511, text: "Thread pool has been terminated." },
70-
ThreadTerminated: { code: 512, text: "Thread has been terminated." }
73+
ThreadTerminated: { code: 512, text: "Thread has been terminated." },
74+
UnrecognizedModuleType: {
75+
code: 513,
76+
text: "A module with an unrecognized type has been passed '%{0}'."
77+
},
78+
UnexportedFunction: {
79+
code: 514,
80+
text: "No function with the name '%{0}' has been exported in module '{%1}'."
81+
}
7182
};
7283
var defaultThreadPoolSettings = {
7384
maxThreads: 1,
@@ -137,6 +148,12 @@ function createObject(properties) {
137148
}
138149
return obj;
139150
}
151+
function isNativeModule(moduleSrc) {
152+
if (moduleSrc.endsWith(".wasm" /* WASM */))
153+
return false;
154+
else
155+
return true;
156+
}
140157

141158
// libs/platform/src/core/error.ts
142159
var ConcurrencyError = class extends Error {
@@ -247,14 +264,22 @@ var ConcurrentModule = class {
247264
this.src = src;
248265
}
249266
async load() {
250-
const moduleSrc = this.src;
251-
const module = await import(this.src);
267+
const moduleSrc = this.src.toString();
268+
const module = isNativeModule(moduleSrc) ? await import(moduleSrc) : {};
252269
const thread = await this.pool.getThread();
253270
const cache = {};
254271
return new Proxy(module, {
255272
get(obj, key) {
256273
const _export = Reflect.get(obj, key);
257-
if (!Reflect.has(obj, key))
274+
if (key === "then")
275+
return;
276+
else if (!isNativeModule(moduleSrc)) {
277+
if (!Reflect.has(cache, key)) {
278+
const threadedFunction = new ThreadedFunction(thread, moduleSrc, key);
279+
Reflect.set(cache, key, (...params) => threadedFunction.invoke(params));
280+
}
281+
return Reflect.get(cache, key);
282+
} else if (!Reflect.has(obj, key))
258283
return;
259284
else if (!isFunction(_export))
260285
throw new ConcurrencyError(ErrorMessage.NotAccessibleExport);
@@ -494,7 +519,7 @@ var Master = class {
494519
this.start();
495520
const module = this.settings.disabled ? {
496521
load: () => import(moduleSrc.toString())
497-
} : new ConcurrentModule(this.pool, moduleSrc.toString());
522+
} : new ConcurrentModule(this.pool, moduleSrc);
498523
return module;
499524
}
500525
async terminate(force) {

0 commit comments

Comments
 (0)