quickwin 1.1.3 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.en.md +7 -3
- package/README.md +7 -3
- package/examples/exec_server.js +3535 -34
- package/examples/exec_server.ts +71 -26
- package/examples/exec_server_worker.js +45 -0
- package/examples/exec_server_worker.ts +39 -0
- package/examples/setres.js +104 -0
- package/examples/setres.ts +120 -0
- package/package.json +1 -1
- package/quickwin.d.ts +3 -3
- package/qwin-nowasm-x86.exe +0 -0
- package/qwin-nowasm.exe +0 -0
- package/qwin-x86.exe +0 -0
- package/qwin.exe +0 -0
- package/test/run.js +3 -1
- package/test/run.ts +3 -1
- package/test/test_ffi.js +23 -8
- package/test/test_ffi.ts +24 -8
- package/test/test_worker_concurrent.js +45 -0
- package/test/test_worker_concurrent.ts +56 -0
- package/test/test_worker_data_url.js +46 -0
- package/test/test_worker_data_url.ts +51 -0
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { Tester } from './test_helper.js'
|
|
2
|
+
import * as os from 'os'
|
|
3
|
+
import * as std from 'std'
|
|
4
|
+
|
|
5
|
+
interface RoundResults {
|
|
6
|
+
type: string
|
|
7
|
+
value: number
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
function runRound(): Promise<RoundResults[]> {
|
|
11
|
+
const ids = [1, 2]
|
|
12
|
+
return Promise.all(ids.map((id) =>
|
|
13
|
+
new Promise<RoundResults>((resolve, reject) => {
|
|
14
|
+
const worker: any = new os.Worker('./worker_module.js')
|
|
15
|
+
const timer = os.setTimeout(() => {
|
|
16
|
+
worker.onmessage = null
|
|
17
|
+
reject(new Error(`worker ${id} timeout`))
|
|
18
|
+
}, 5000)
|
|
19
|
+
worker.onmessage = (e: any) => {
|
|
20
|
+
os.clearTimeout(timer)
|
|
21
|
+
worker.postMessage({ type: 'done' })
|
|
22
|
+
worker.onmessage = null
|
|
23
|
+
resolve(e.data)
|
|
24
|
+
}
|
|
25
|
+
worker.postMessage({ type: 'start' })
|
|
26
|
+
})
|
|
27
|
+
))
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export const suite = {
|
|
31
|
+
name: 'worker-concurrent',
|
|
32
|
+
run: async (t: Tester) => {
|
|
33
|
+
t.section('dual-worker-init')
|
|
34
|
+
const N = 20
|
|
35
|
+
let ok = 0
|
|
36
|
+
let lastErr: unknown = null
|
|
37
|
+
for (let i = 0; i < N; i++) {
|
|
38
|
+
try {
|
|
39
|
+
const results = await runRound()
|
|
40
|
+
if (
|
|
41
|
+
results.length === 2 &&
|
|
42
|
+
results.every((r) => r.type === 'result' && r.value === 42)
|
|
43
|
+
) {
|
|
44
|
+
ok++
|
|
45
|
+
}
|
|
46
|
+
} catch (e) {
|
|
47
|
+
lastErr = e
|
|
48
|
+
break
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
if (ok !== N && lastErr) {
|
|
52
|
+
std.printf('round error: %s\n', String(lastErr))
|
|
53
|
+
}
|
|
54
|
+
t.check('concurrent dual-worker rounds', N, ok)
|
|
55
|
+
}
|
|
56
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import * as os from 'os';
|
|
2
|
+
// base64 of worker body (see comment). Split manually to keep lines short.
|
|
3
|
+
const B64_WORKER = 'aW1wb3J0ICogYXMgb3MgZnJvbSAnb3MnCmNvbnN0IHBhcmVudCA9IG9zLldvcmtlci5wYXJl' +
|
|
4
|
+
'bnQKcGFyZW50Lm9ubWVzc2FnZSA9IChlKSA9PiB7CiAgICBjb25zdCBkID0gZS5kYXRhCiAg' +
|
|
5
|
+
'ICBpZiAoZC50eXBlID09PSAnc3RhcnQnKSBwYXJlbnQucG9zdE1lc3NhZ2UoeyB0eXBlOiAn' +
|
|
6
|
+
'cmVzdWx0JywgdmFsdWU6IDQyIH0pCiAgICBlbHNlIGlmIChkLnR5cGUgPT09ICdkb25lJykg' +
|
|
7
|
+
'cGFyZW50Lm9ubWVzc2FnZSA9IG51bGwKfQo=';
|
|
8
|
+
const DATA_WORKER = 'data:text/javascript;base64,' + B64_WORKER;
|
|
9
|
+
// export const answer = 42\n
|
|
10
|
+
const DATA_MOD = 'data:text/javascript;base64,ZXhwb3J0IGNvbnN0IGFuc3dlciA9IDQyCg==';
|
|
11
|
+
export const suite = {
|
|
12
|
+
name: 'worker-data-url',
|
|
13
|
+
run: async (t) => {
|
|
14
|
+
t.section('base64-worker-entry');
|
|
15
|
+
let worker;
|
|
16
|
+
try {
|
|
17
|
+
const { data: result } = await new Promise((resolve, reject) => {
|
|
18
|
+
worker = new os.Worker(DATA_WORKER);
|
|
19
|
+
const timer = os.setTimeout(() => reject(new Error('worker timeout')), 5000);
|
|
20
|
+
worker.onmessage = (e) => {
|
|
21
|
+
os.clearTimeout(timer);
|
|
22
|
+
resolve({ data: e.data });
|
|
23
|
+
};
|
|
24
|
+
worker.postMessage({ type: 'start' });
|
|
25
|
+
});
|
|
26
|
+
t.check('message type', 'result', result.type);
|
|
27
|
+
t.check('imported value', 42, result.value);
|
|
28
|
+
worker.postMessage({ type: 'done' });
|
|
29
|
+
worker.onmessage = null;
|
|
30
|
+
}
|
|
31
|
+
catch (e) {
|
|
32
|
+
t.checkTrue('data url worker failed: ' + e, false);
|
|
33
|
+
if (worker) {
|
|
34
|
+
worker.onmessage = null;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
t.section('dynamic-import-data-url');
|
|
38
|
+
try {
|
|
39
|
+
const mod = await import(DATA_MOD);
|
|
40
|
+
t.check('import(data:) answer', 42, mod.answer);
|
|
41
|
+
}
|
|
42
|
+
catch (e) {
|
|
43
|
+
t.checkTrue('import(data:) failed: ' + e, false);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
};
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { Tester } from './test_helper.js'
|
|
2
|
+
import * as os from 'os'
|
|
3
|
+
|
|
4
|
+
// base64 of worker body (see comment). Split manually to keep lines short.
|
|
5
|
+
const B64_WORKER =
|
|
6
|
+
'aW1wb3J0ICogYXMgb3MgZnJvbSAnb3MnCmNvbnN0IHBhcmVudCA9IG9zLldvcmtlci5wYXJl' +
|
|
7
|
+
'bnQKcGFyZW50Lm9ubWVzc2FnZSA9IChlKSA9PiB7CiAgICBjb25zdCBkID0gZS5kYXRhCiAg' +
|
|
8
|
+
'ICBpZiAoZC50eXBlID09PSAnc3RhcnQnKSBwYXJlbnQucG9zdE1lc3NhZ2UoeyB0eXBlOiAn' +
|
|
9
|
+
'cmVzdWx0JywgdmFsdWU6IDQyIH0pCiAgICBlbHNlIGlmIChkLnR5cGUgPT09ICdkb25lJykg' +
|
|
10
|
+
'cGFyZW50Lm9ubWVzc2FnZSA9IG51bGwKfQo='
|
|
11
|
+
|
|
12
|
+
const DATA_WORKER = 'data:text/javascript;base64,' + B64_WORKER
|
|
13
|
+
|
|
14
|
+
// export const answer = 42\n
|
|
15
|
+
const DATA_MOD = 'data:text/javascript;base64,ZXhwb3J0IGNvbnN0IGFuc3dlciA9IDQyCg=='
|
|
16
|
+
|
|
17
|
+
export const suite = {
|
|
18
|
+
name: 'worker-data-url',
|
|
19
|
+
run: async (t: Tester) => {
|
|
20
|
+
t.section('base64-worker-entry')
|
|
21
|
+
let worker: any
|
|
22
|
+
try {
|
|
23
|
+
const { data: result } = await new Promise<any>((resolve, reject) => {
|
|
24
|
+
worker = new os.Worker(DATA_WORKER)
|
|
25
|
+
const timer = os.setTimeout(() => reject(new Error('worker timeout')), 5000)
|
|
26
|
+
worker.onmessage = (e: any) => {
|
|
27
|
+
os.clearTimeout(timer)
|
|
28
|
+
resolve({ data: e.data })
|
|
29
|
+
}
|
|
30
|
+
worker.postMessage({ type: 'start' })
|
|
31
|
+
})
|
|
32
|
+
t.check('message type', 'result', result.type)
|
|
33
|
+
t.check('imported value', 42, result.value)
|
|
34
|
+
worker.postMessage({ type: 'done' })
|
|
35
|
+
worker.onmessage = null
|
|
36
|
+
} catch (e) {
|
|
37
|
+
t.checkTrue('data url worker failed: ' + e, false)
|
|
38
|
+
if (worker) {
|
|
39
|
+
worker.onmessage = null
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
t.section('dynamic-import-data-url')
|
|
44
|
+
try {
|
|
45
|
+
const mod = await import(DATA_MOD)
|
|
46
|
+
t.check('import(data:) answer', 42, (mod as any).answer)
|
|
47
|
+
} catch (e) {
|
|
48
|
+
t.checkTrue('import(data:) failed: ' + e, false)
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|