quickwin 3.0.1 → 3.0.3
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 +3 -0
- package/README.md +2 -0
- package/package.json +2 -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/examples/PdfCanvas.js +0 -38
- package/examples/PdfCanvas.tsx +0 -54
- package/examples/execd/main.js +0 -23379
- package/examples/execd/tray.js +0 -192
- package/examples/execd/worker.js +0 -122
- package/examples/pdf_preview2.js +0 -398
- package/examples/pdf_preview2.ts +0 -353
- package/examples/pdf_viewer.js +0 -22515
- package/examples/pdf_viewer.tsx +0 -228
- package/examples/test_gallery.js +0 -18692
- package/examples/test_gallery.tsx +0 -291
- package/examples/test_react_lazy.js +0 -18560
- package/examples/test_react_lazy.tsx +0 -65
- package/examples/test_react_listbox.js +0 -18562
- package/examples/test_react_listbox.tsx +0 -73
- package/examples/test_root_window.js +0 -18532
- package/examples/test_root_window.tsx +0 -41
- package/examples/test_tab.js +0 -18563
- package/examples/test_tab.tsx +0 -77
- package/examples/tray_demo.js +0 -86
- package/examples/tray_demo.tsx +0 -89
- package/test/add.wasm +0 -0
- package/test/bench_ffi_callraw.js +0 -235
- package/test/bench_ffi_callraw.ts +0 -235
- package/test/bench_ffi_overhead.js +0 -139
- package/test/bench_ffi_overhead.ts +0 -141
- package/test/bench_sendmessage.js +0 -104
- package/test/bench_sendmessage.ts +0 -100
- package/test/bench_sendmessage_nonnull.js +0 -187
- package/test/bench_sendmessage_nonnull.ts +0 -188
- package/test/complex.wasm +0 -0
- package/test/complex_imports.wasm +0 -0
- package/test/debug/http_server_e2e.js +0 -31
- package/test/debug/minwasm.js +0 -52
- package/test/debug/mupdf_debug.js +0 -86
- package/test/debug/wasm.js +0 -122
- package/test/debug/wasm_export_debug.js +0 -54
- package/test/debug/wasm_names.js +0 -36
- package/test/example.pdf +0 -0
- package/test/global_imports.wasm +0 -0
- package/test/import_func.wasm +0 -0
- package/test/imports.wasm +0 -0
- package/test/mupdf-cdn.js +0 -40
- package/test/mupdf-cdn.ts +0 -43
- package/test/run.js +0 -111
- package/test/run.ts +0 -116
- package/test/sjlj.wasm +0 -0
- package/test/test_basic.js +0 -7
- package/test/test_basic.ts +0 -9
- package/test/test_basic_fetch.js +0 -63
- package/test/test_basic_fetch.ts +0 -59
- package/test/test_brotli.js +0 -48
- package/test/test_brotli.ts +0 -52
- package/test/test_fetch_cache.js +0 -169
- package/test/test_fetch_cache.ts +0 -187
- package/test/test_ffi.js +0 -157
- package/test/test_ffi.ts +0 -170
- package/test/test_ffi_abi.js +0 -290
- package/test/test_ffi_abi.ts +0 -274
- package/test/test_ffi_array.js +0 -116
- package/test/test_ffi_array.ts +0 -141
- package/test/test_ffi_bind.js +0 -656
- package/test/test_ffi_bind.ts +0 -670
- package/test/test_ffi_struct.js +0 -779
- package/test/test_ffi_struct.ts +0 -828
- package/test/test_ffi_struct_layout.js +0 -495
- package/test/test_ffi_struct_layout.ts +0 -543
- package/test/test_ffi_user32.js +0 -103
- package/test/test_ffi_user32.ts +0 -113
- package/test/test_ffi_windows.js +0 -172
- package/test/test_ffi_windows.ts +0 -187
- package/test/test_files.js +0 -102
- package/test/test_files.ts +0 -121
- package/test/test_frame_encoding.js +0 -128
- package/test/test_frame_encoding.ts +0 -132
- package/test/test_gdi_draw.js +0 -681
- package/test/test_gdi_draw.ts +0 -725
- package/test/test_helper.js +0 -91
- package/test/test_helper.ts +0 -88
- package/test/test_http_import.js +0 -96
- package/test/test_http_import.ts +0 -93
- package/test/test_http_server.js +0 -214
- package/test/test_http_server.ts +0 -211
- package/test/test_import_dir.js +0 -4
- package/test/test_import_dir.ts +0 -5
- package/test/test_ipv6.js +0 -134
- package/test/test_ipv6.ts +0 -130
- package/test/test_jsx.js +0 -1314
- package/test/test_meta_url.js +0 -3
- package/test/test_meta_url.ts +0 -4
- package/test/test_mupdf_render.js +0 -51
- package/test/test_mupdf_render.ts +0 -55
- package/test/test_mupdf_twice.js +0 -62
- package/test/test_mupdf_twice.ts +0 -65
- package/test/test_mupdf_wasm.js +0 -39
- package/test/test_mupdf_wasm.ts +0 -32
- package/test/test_net_event.js +0 -57
- package/test/test_net_event.ts +0 -56
- package/test/test_net_fetch.js +0 -384
- package/test/test_net_fetch.ts +0 -373
- package/test/test_net_websocket.js +0 -180
- package/test/test_net_websocket.ts +0 -164
- package/test/test_polyfill.js +0 -144
- package/test/test_polyfill.ts +0 -159
- package/test/test_printer.js +0 -137
- package/test/test_printer.ts +0 -148
- package/test/test_proc.js +0 -141
- package/test/test_proc.ts +0 -163
- package/test/test_react_complex.js +0 -18678
- package/test/test_react_counter.js +0 -18555
- package/test/test_react_flex.js +0 -18871
- package/test/test_react_hidden.js +0 -18560
- package/test/test_react_listview_link.js +0 -18590
- package/test/test_react_notify.js +0 -18797
- package/test/test_react_render.js +0 -18550
- package/test/test_registry.js +0 -74
- package/test/test_registry.ts +0 -95
- package/test/test_sysinfo.js +0 -122
- package/test/test_sysinfo.ts +0 -141
- package/test/test_url.js +0 -173
- package/test/test_url.ts +0 -183
- package/test/test_wasm_basic.js +0 -85
- package/test/test_wasm_basic.ts +0 -73
- package/test/test_wasm_import_global.js +0 -41
- package/test/test_wasm_import_global.ts +0 -45
- package/test/test_wasm_sjlj.js +0 -145
- package/test/test_wasm_sjlj.ts +0 -125
- package/test/test_wasm_types.js +0 -97
- package/test/test_wasm_types.ts +0 -124
- package/test/test_wolfssl_read.js +0 -203
- package/test/test_wolfssl_read.ts +0 -184
- package/test/test_worker.js +0 -21
- package/test/test_worker.ts +0 -24
- package/test/test_worker_concurrent.js +0 -45
- package/test/test_worker_concurrent.ts +0 -56
- package/test/test_worker_data_url.js +0 -46
- package/test/test_worker_data_url.ts +0 -51
- package/test/test_worker_fetch.js +0 -26
- package/test/test_worker_fetch.ts +0 -27
- package/test/test_worker_net.js +0 -69
- package/test/test_worker_net.ts +0 -66
- package/test/test_worker_wasm_concurrent.js +0 -44
- package/test/test_worker_wasm_concurrent.ts +0 -45
- package/test/types.wasm +0 -0
- package/test/worker_fetch.js +0 -13
- package/test/worker_fetch.ts +0 -13
- package/test/worker_helper.js +0 -1
- package/test/worker_helper.ts +0 -1
- package/test/worker_http.js +0 -18
- package/test/worker_http.ts +0 -20
- package/test/worker_import_lib.js +0 -12
- package/test/worker_import_lib.ts +0 -13
- package/test/worker_module.js +0 -16
- package/test/worker_module.ts +0 -17
- package/test/worker_wasm_concurrent.js +0 -22
- package/test/worker_wasm_concurrent.ts +0 -22
|
@@ -1,184 +0,0 @@
|
|
|
1
|
-
import * as sock from 'sock'
|
|
2
|
-
import * as wolfssl from 'wolfssl'
|
|
3
|
-
import * as os from 'os'
|
|
4
|
-
import * as std from 'std'
|
|
5
|
-
import { Tester } from './test_helper.js'
|
|
6
|
-
import { FdEvent, ReturnCode, SniType, VerifyMode } from '../constants'
|
|
7
|
-
|
|
8
|
-
const HTTPS_PORT = 18924
|
|
9
|
-
const WANT_READ = 2
|
|
10
|
-
const WANT_WRITE = 3
|
|
11
|
-
const ZERO_RETURN = 6
|
|
12
|
-
|
|
13
|
-
export const suite = {
|
|
14
|
-
name: 'net-wolfssl-read',
|
|
15
|
-
run: async (t: Tester) => {
|
|
16
|
-
function assert(name: string, ok: boolean): void {
|
|
17
|
-
if (ok) { t.ok++; std.printf(' PASS: %s\n', name) }
|
|
18
|
-
else { t.fail++; std.printf(' FAIL: %s\n', name) }
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
// ── wolfSSL_read return contract: raw int, data lands in the
|
|
22
|
-
// caller-owned buffer (thin wrapper — errors stay numbers) ──
|
|
23
|
-
t.section('wolfSSL_read contract (HTTPS /large/65536)')
|
|
24
|
-
await new Promise<void>((resolve) => {
|
|
25
|
-
const s = sock.socket()
|
|
26
|
-
if (s === null || s < 0) {
|
|
27
|
-
assert('socket() ok', false)
|
|
28
|
-
resolve()
|
|
29
|
-
return
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
let ssl: wolfssl.WOLFSSL | null = null
|
|
33
|
-
let ctx: wolfssl.WOLFSSL_CTX | null = null
|
|
34
|
-
let connected = false
|
|
35
|
-
let handshakeDone = false
|
|
36
|
-
let sentRequest = false
|
|
37
|
-
let total = 0
|
|
38
|
-
const EXPECTED = 65536
|
|
39
|
-
let sawNonNumber = false
|
|
40
|
-
let sawEof = false
|
|
41
|
-
let errOk = true
|
|
42
|
-
let done = false
|
|
43
|
-
|
|
44
|
-
const finish = () => {
|
|
45
|
-
if (done) return
|
|
46
|
-
done = true
|
|
47
|
-
os.clearTimeout(timeoutId)
|
|
48
|
-
assert('connected', connected)
|
|
49
|
-
assert('handshake ok', handshakeDone)
|
|
50
|
-
assert('request sent', sentRequest)
|
|
51
|
-
assert('received full body', total >= EXPECTED)
|
|
52
|
-
assert('wolfSSL_read always returned number', !sawNonNumber)
|
|
53
|
-
assert('no-data/EOF observed via int (0 or ZERO_RETURN)', sawEof)
|
|
54
|
-
assert('n<=0 get_error in {WANT_READ,WANT_WRITE,ZERO_RETURN}', errOk)
|
|
55
|
-
if (ssl) { wolfssl.wolfSSL_free(ssl); ssl = null }
|
|
56
|
-
if (ctx) { wolfssl.wolfSSL_CTX_free(ctx); ctx = null }
|
|
57
|
-
sock.closesocket(s)
|
|
58
|
-
resolve()
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
const timeoutId = os.setTimeout(() => {
|
|
62
|
-
assert('wolfSSL_read contract timeout (15s)', false)
|
|
63
|
-
finish()
|
|
64
|
-
}, 15000)
|
|
65
|
-
|
|
66
|
-
const sendReq = () => {
|
|
67
|
-
const req = 'GET /large/65536 HTTP/1.1\r\nHost: localhost\r\nConnection: close\r\n\r\n'
|
|
68
|
-
const buf = new ArrayBuffer(req.length)
|
|
69
|
-
const v = new Uint8Array(buf)
|
|
70
|
-
for (let i = 0; i < req.length; i++) v[i] = req.charCodeAt(i)
|
|
71
|
-
wolfssl.wolfSSL_write(ssl!, buf)
|
|
72
|
-
sentRequest = true
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
const onReadable = () => {
|
|
76
|
-
// Drain until EOF (n===0 / ZERO_RETURN) or WANT_* hands back
|
|
77
|
-
// to the event loop.
|
|
78
|
-
for (let guard = 0; guard < 10000; guard++) {
|
|
79
|
-
const buf = new ArrayBuffer(8192)
|
|
80
|
-
const n = wolfssl.wolfSSL_read(ssl!, buf)
|
|
81
|
-
if (typeof n !== 'number') {
|
|
82
|
-
sawNonNumber = true
|
|
83
|
-
std.printf(' FAIL got non-number %s (want int)\n', String(n))
|
|
84
|
-
finish()
|
|
85
|
-
return
|
|
86
|
-
}
|
|
87
|
-
if (n > 0) {
|
|
88
|
-
total += n
|
|
89
|
-
// Keep draining after the body is complete: the point of
|
|
90
|
-
// this suite is the no-data/EOF contract, so a full body
|
|
91
|
-
// must not short-circuit the read that would observe it.
|
|
92
|
-
continue
|
|
93
|
-
}
|
|
94
|
-
const err = wolfssl.wolfSSL_get_error(ssl!, n)
|
|
95
|
-
if (err !== WANT_READ && err !== WANT_WRITE && err !== ZERO_RETURN) {
|
|
96
|
-
errOk = false
|
|
97
|
-
std.printf(' n=%d get_error=%d outside {WANT_READ,WANT_WRITE,ZERO_RETURN}\n', n, err)
|
|
98
|
-
finish()
|
|
99
|
-
return
|
|
100
|
-
}
|
|
101
|
-
if (n === 0 || err === ZERO_RETURN) {
|
|
102
|
-
sawEof = true
|
|
103
|
-
break
|
|
104
|
-
}
|
|
105
|
-
// WANT_*: wait for next FD_READ/WRITE
|
|
106
|
-
return
|
|
107
|
-
}
|
|
108
|
-
if (sawEof) finish()
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
sock.set_on_event(s, (event: { lNetworkEvents: number; iErrorCode: number[] }) => {
|
|
112
|
-
if (done) return
|
|
113
|
-
|
|
114
|
-
if (event.lNetworkEvents & FdEvent.FD_CONNECT) {
|
|
115
|
-
if (event.iErrorCode[0] !== 0) {
|
|
116
|
-
assert('connect error code 0', false)
|
|
117
|
-
finish()
|
|
118
|
-
return
|
|
119
|
-
}
|
|
120
|
-
connected = true
|
|
121
|
-
const method = wolfssl.wolfTLSv1_2_client_method()
|
|
122
|
-
ctx = wolfssl.wolfSSL_CTX_new(method)
|
|
123
|
-
if (!ctx) { assert('CTX_new', false); finish(); return }
|
|
124
|
-
wolfssl.wolfSSL_CTX_set_verify(ctx, VerifyMode.SSL_VERIFY_NONE)
|
|
125
|
-
ssl = wolfssl.wolfSSL_new(ctx)
|
|
126
|
-
if (!ssl) { assert('SSL_new', false); finish(); return }
|
|
127
|
-
wolfssl.wolfSSL_set_fd(ssl, sock.get_fd(s))
|
|
128
|
-
wolfssl.wolfSSL_UseSNI(ssl, SniType.WOLFSSL_SNI_HOST_NAME, 'localhost')
|
|
129
|
-
// kick handshake immediately (FD_WRITE may not re-fire)
|
|
130
|
-
{
|
|
131
|
-
const ret = wolfssl.wolfSSL_connect(ssl)
|
|
132
|
-
if (ret === ReturnCode.SSL_SUCCESS) {
|
|
133
|
-
handshakeDone = true
|
|
134
|
-
sendReq()
|
|
135
|
-
} else {
|
|
136
|
-
const err = wolfssl.wolfSSL_get_error(ssl, ret)
|
|
137
|
-
if (err !== WANT_READ && err !== WANT_WRITE) {
|
|
138
|
-
assert('TLS handshake failed err=' + err, false)
|
|
139
|
-
finish()
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
if ((event.lNetworkEvents & FdEvent.FD_READ) ||
|
|
146
|
-
(event.lNetworkEvents & FdEvent.FD_WRITE)) {
|
|
147
|
-
if (!ssl) return
|
|
148
|
-
if (!handshakeDone) {
|
|
149
|
-
const ret = wolfssl.wolfSSL_connect(ssl)
|
|
150
|
-
if (ret === ReturnCode.SSL_SUCCESS) {
|
|
151
|
-
handshakeDone = true
|
|
152
|
-
sendReq()
|
|
153
|
-
} else {
|
|
154
|
-
const err = wolfssl.wolfSSL_get_error(ssl, ret)
|
|
155
|
-
if (err !== WANT_READ && err !== WANT_WRITE) {
|
|
156
|
-
assert('TLS handshake failed err=' + err, false)
|
|
157
|
-
finish()
|
|
158
|
-
}
|
|
159
|
-
}
|
|
160
|
-
return
|
|
161
|
-
}
|
|
162
|
-
if (sentRequest) onReadable()
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
if (event.lNetworkEvents & FdEvent.FD_CLOSE) {
|
|
166
|
-
// drain remaining then finish
|
|
167
|
-
if (ssl && sentRequest && !sawNonNumber) {
|
|
168
|
-
onReadable()
|
|
169
|
-
}
|
|
170
|
-
if (!sawNonNumber) {
|
|
171
|
-
// Server close without an observed EOF read is an edge —
|
|
172
|
-
// don't fail if the body already completed.
|
|
173
|
-
if (!sawEof && total < EXPECTED && total > 0) {
|
|
174
|
-
sawEof = true
|
|
175
|
-
}
|
|
176
|
-
if (total >= EXPECTED || sawEof) finish()
|
|
177
|
-
else { assert('data before close', false); if (!done) finish() }
|
|
178
|
-
}
|
|
179
|
-
}
|
|
180
|
-
})
|
|
181
|
-
sock.connect(s, '127.0.0.1', HTTPS_PORT)
|
|
182
|
-
})
|
|
183
|
-
}
|
|
184
|
-
}
|
package/test/test_worker.js
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
import * as os from 'os';
|
|
2
|
-
export const suite = {
|
|
3
|
-
name: 'worker',
|
|
4
|
-
run: async (t) => {
|
|
5
|
-
t.section('relative-import');
|
|
6
|
-
let worker;
|
|
7
|
-
const { data: result } = await new Promise((resolve, reject) => {
|
|
8
|
-
worker = new os.Worker('./worker_module.js');
|
|
9
|
-
const timer = os.setTimeout(() => reject(new Error('worker timeout')), 5000);
|
|
10
|
-
worker.onmessage = (e) => {
|
|
11
|
-
os.clearTimeout(timer);
|
|
12
|
-
resolve({ data: e.data });
|
|
13
|
-
};
|
|
14
|
-
worker.postMessage({ type: 'start' });
|
|
15
|
-
});
|
|
16
|
-
t.check('message type', 'result', result.type);
|
|
17
|
-
t.check('imported value', 42, result.value);
|
|
18
|
-
worker.postMessage({ type: 'done' });
|
|
19
|
-
worker.onmessage = null;
|
|
20
|
-
}
|
|
21
|
-
};
|
package/test/test_worker.ts
DELETED
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
import { Tester } from './test_helper.js'
|
|
2
|
-
import * as os from 'os'
|
|
3
|
-
|
|
4
|
-
export const suite = {
|
|
5
|
-
name: 'worker',
|
|
6
|
-
run: async (t: Tester) => {
|
|
7
|
-
t.section('relative-import')
|
|
8
|
-
let worker: any
|
|
9
|
-
const { data: result } = await new Promise<any>((resolve, reject) => {
|
|
10
|
-
worker = new os.Worker('./worker_module.js')
|
|
11
|
-
const timer = os.setTimeout(() => reject(new Error('worker timeout')), 5000)
|
|
12
|
-
worker.onmessage = (e: any) => {
|
|
13
|
-
os.clearTimeout(timer)
|
|
14
|
-
resolve({ data: e.data })
|
|
15
|
-
}
|
|
16
|
-
worker.postMessage({ type: 'start' })
|
|
17
|
-
})
|
|
18
|
-
t.check('message type', 'result', result.type)
|
|
19
|
-
t.check('imported value', 42, result.value)
|
|
20
|
-
|
|
21
|
-
worker.postMessage({ type: 'done' })
|
|
22
|
-
worker.onmessage = null
|
|
23
|
-
}
|
|
24
|
-
}
|
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
import * as os from 'os';
|
|
2
|
-
import * as std from 'std';
|
|
3
|
-
function runRound() {
|
|
4
|
-
const ids = [1, 2];
|
|
5
|
-
return Promise.all(ids.map((id) => new Promise((resolve, reject) => {
|
|
6
|
-
const worker = new os.Worker('./worker_module.js');
|
|
7
|
-
const timer = os.setTimeout(() => {
|
|
8
|
-
worker.onmessage = null;
|
|
9
|
-
reject(new Error(`worker ${id} timeout`));
|
|
10
|
-
}, 5000);
|
|
11
|
-
worker.onmessage = (e) => {
|
|
12
|
-
os.clearTimeout(timer);
|
|
13
|
-
worker.postMessage({ type: 'done' });
|
|
14
|
-
worker.onmessage = null;
|
|
15
|
-
resolve(e.data);
|
|
16
|
-
};
|
|
17
|
-
worker.postMessage({ type: 'start' });
|
|
18
|
-
})));
|
|
19
|
-
}
|
|
20
|
-
export const suite = {
|
|
21
|
-
name: 'worker-concurrent',
|
|
22
|
-
run: async (t) => {
|
|
23
|
-
t.section('dual-worker-init');
|
|
24
|
-
const N = 20;
|
|
25
|
-
let ok = 0;
|
|
26
|
-
let lastErr = null;
|
|
27
|
-
for (let i = 0; i < N; i++) {
|
|
28
|
-
try {
|
|
29
|
-
const results = await runRound();
|
|
30
|
-
if (results.length === 2 &&
|
|
31
|
-
results.every((r) => r.type === 'result' && r.value === 42)) {
|
|
32
|
-
ok++;
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
catch (e) {
|
|
36
|
-
lastErr = e;
|
|
37
|
-
break;
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
if (ok !== N && lastErr) {
|
|
41
|
-
std.printf('round error: %s\n', String(lastErr));
|
|
42
|
-
}
|
|
43
|
-
t.check('concurrent dual-worker rounds', N, ok);
|
|
44
|
-
}
|
|
45
|
-
};
|
|
@@ -1,56 +0,0 @@
|
|
|
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
|
-
}
|
|
@@ -1,46 +0,0 @@
|
|
|
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
|
-
};
|
|
@@ -1,51 +0,0 @@
|
|
|
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
|
-
}
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
import * as os from 'os';
|
|
2
|
-
export const suite = {
|
|
3
|
-
name: 'worker-fetch',
|
|
4
|
-
run: async (t) => {
|
|
5
|
-
t.section('fetch-in-worker');
|
|
6
|
-
let worker;
|
|
7
|
-
const { data: result } = await new Promise((resolve, reject) => {
|
|
8
|
-
worker = new os.Worker('./worker_fetch.js');
|
|
9
|
-
const timer = os.setTimeout(() => reject(new Error('timeout')), 15000);
|
|
10
|
-
worker.onmessage = (e) => {
|
|
11
|
-
os.clearTimeout(timer);
|
|
12
|
-
resolve({ worker, data: e.data });
|
|
13
|
-
};
|
|
14
|
-
worker.postMessage({ type: 'start' });
|
|
15
|
-
});
|
|
16
|
-
if (result.type === 'result') {
|
|
17
|
-
t.checkTrue('fetch ok', result.ok);
|
|
18
|
-
t.check('status', result.status, 200);
|
|
19
|
-
}
|
|
20
|
-
else {
|
|
21
|
-
t.checkTrue('worker fetch failed: ' + result.msg, false);
|
|
22
|
-
}
|
|
23
|
-
worker.postMessage({ type: 'done' });
|
|
24
|
-
worker.onmessage = null;
|
|
25
|
-
}
|
|
26
|
-
};
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
import { Tester } from './test_helper.js'
|
|
2
|
-
import * as os from 'os'
|
|
3
|
-
|
|
4
|
-
export const suite = {
|
|
5
|
-
name: 'worker-fetch',
|
|
6
|
-
run: async (t: Tester) => {
|
|
7
|
-
t.section('fetch-in-worker')
|
|
8
|
-
let worker: any
|
|
9
|
-
const { data: result } = await new Promise<any>((resolve, reject) => {
|
|
10
|
-
worker = new os.Worker('./worker_fetch.js')
|
|
11
|
-
const timer = os.setTimeout(() => reject(new Error('timeout')), 15000)
|
|
12
|
-
worker.onmessage = (e: any) => {
|
|
13
|
-
os.clearTimeout(timer)
|
|
14
|
-
resolve({ worker, data: e.data })
|
|
15
|
-
}
|
|
16
|
-
worker.postMessage({ type: 'start' })
|
|
17
|
-
})
|
|
18
|
-
if (result.type === 'result') {
|
|
19
|
-
t.checkTrue('fetch ok', result.ok)
|
|
20
|
-
t.check('status', result.status, 200)
|
|
21
|
-
} else {
|
|
22
|
-
t.checkTrue('worker fetch failed: ' + result.msg, false)
|
|
23
|
-
}
|
|
24
|
-
worker.postMessage({ type: 'done' })
|
|
25
|
-
worker.onmessage = null
|
|
26
|
-
}
|
|
27
|
-
}
|
package/test/test_worker_net.js
DELETED
|
@@ -1,69 +0,0 @@
|
|
|
1
|
-
import * as os from 'os';
|
|
2
|
-
export const suite = {
|
|
3
|
-
name: 'worker-http',
|
|
4
|
-
run: async (t) => {
|
|
5
|
-
t.section('import-inside');
|
|
6
|
-
let worker1;
|
|
7
|
-
const { data: r1 } = await new Promise((resolve, reject) => {
|
|
8
|
-
worker1 = new os.Worker('./worker_http.js');
|
|
9
|
-
const timer = os.setTimeout(() => reject(new Error('timeout')), 15000);
|
|
10
|
-
worker1.onmessage = (e) => {
|
|
11
|
-
os.clearTimeout(timer);
|
|
12
|
-
resolve({ worker: worker1, data: e.data });
|
|
13
|
-
};
|
|
14
|
-
worker1.postMessage({ type: 'start' });
|
|
15
|
-
});
|
|
16
|
-
t.check('message type', 'result', r1.type);
|
|
17
|
-
t.checkTrue('isArray([])', r1.isArrayWorks);
|
|
18
|
-
t.checkTrue('isArray({}) rejects', r1.isArrayRejects);
|
|
19
|
-
worker1.postMessage({ type: 'done' });
|
|
20
|
-
worker1.onmessage = null;
|
|
21
|
-
t.section('http-entry');
|
|
22
|
-
try {
|
|
23
|
-
new os.Worker('https://esm.sh/isarray');
|
|
24
|
-
await new Promise(resolve => os.setTimeout(() => resolve(), 3000));
|
|
25
|
-
t.checkTrue('worker created with http url', true);
|
|
26
|
-
}
|
|
27
|
-
catch (e) {
|
|
28
|
-
t.checkTrue('worker creation failed: ' + e, false);
|
|
29
|
-
}
|
|
30
|
-
// Retry across jsdelivr's official CDN hosts: a dropped connection
|
|
31
|
-
// on a slow CI network must not be reported as a TLS regression.
|
|
32
|
-
t.section('npm-package');
|
|
33
|
-
let worker3;
|
|
34
|
-
const NPM_HOSTS = ['cdn.jsdelivr.net', 'fastly.jsdelivr.net', 'gcore.jsdelivr.net'];
|
|
35
|
-
let workerOk = false;
|
|
36
|
-
for (const host of NPM_HOSTS) {
|
|
37
|
-
for (let attempt = 0; attempt < 3 && !workerOk; attempt++) {
|
|
38
|
-
try {
|
|
39
|
-
const { data: r3 } = await new Promise((resolve, reject) => {
|
|
40
|
-
worker3 = new os.Worker('https://' + host + '/npm/quickwin/test/worker_module.js');
|
|
41
|
-
const timer = os.setTimeout(() => reject(new Error('timeout')), 15000);
|
|
42
|
-
worker3.onmessage = (e) => {
|
|
43
|
-
os.clearTimeout(timer);
|
|
44
|
-
resolve({ worker: worker3, data: e.data });
|
|
45
|
-
};
|
|
46
|
-
worker3.postMessage({ type: 'start' });
|
|
47
|
-
});
|
|
48
|
-
t.check('npm worker message type', 'result', r3.type);
|
|
49
|
-
t.check('npm worker imported value', 42, r3.value);
|
|
50
|
-
worker3.postMessage({ type: 'done' });
|
|
51
|
-
worker3.onmessage = null;
|
|
52
|
-
workerOk = true;
|
|
53
|
-
}
|
|
54
|
-
catch (e) {
|
|
55
|
-
if (worker3) {
|
|
56
|
-
worker3.onmessage = null;
|
|
57
|
-
worker3 = null;
|
|
58
|
-
}
|
|
59
|
-
if (attempt === 2 && host === NPM_HOSTS[NPM_HOSTS.length - 1])
|
|
60
|
-
t.checkTrue('npm worker failed: ' + e, false);
|
|
61
|
-
else
|
|
62
|
-
os.sleep(500);
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
if (workerOk)
|
|
66
|
-
break;
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
};
|
package/test/test_worker_net.ts
DELETED
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
import { Tester } from './test_helper.js'
|
|
2
|
-
import * as os from 'os'
|
|
3
|
-
|
|
4
|
-
export const suite = {
|
|
5
|
-
name: 'worker-http',
|
|
6
|
-
run: async (t: Tester) => {
|
|
7
|
-
t.section('import-inside')
|
|
8
|
-
let worker1: any
|
|
9
|
-
const { data: r1 } = await new Promise<any>((resolve, reject) => {
|
|
10
|
-
worker1 = new os.Worker('./worker_http.js')
|
|
11
|
-
const timer = os.setTimeout(() => reject(new Error('timeout')), 15000)
|
|
12
|
-
worker1.onmessage = (e: any) => {
|
|
13
|
-
os.clearTimeout(timer)
|
|
14
|
-
resolve({ worker: worker1, data: e.data })
|
|
15
|
-
}
|
|
16
|
-
worker1.postMessage({ type: 'start' })
|
|
17
|
-
})
|
|
18
|
-
t.check('message type', 'result', r1.type)
|
|
19
|
-
t.checkTrue('isArray([])', r1.isArrayWorks)
|
|
20
|
-
t.checkTrue('isArray({}) rejects', r1.isArrayRejects)
|
|
21
|
-
|
|
22
|
-
worker1.postMessage({ type: 'done' })
|
|
23
|
-
worker1.onmessage = null
|
|
24
|
-
|
|
25
|
-
t.section('http-entry')
|
|
26
|
-
try {
|
|
27
|
-
new os.Worker('https://esm.sh/isarray')
|
|
28
|
-
await new Promise<void>(resolve => os.setTimeout(() => resolve(), 3000))
|
|
29
|
-
t.checkTrue('worker created with http url', true)
|
|
30
|
-
} catch (e) {
|
|
31
|
-
t.checkTrue('worker creation failed: ' + e, false)
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
// Retry across jsdelivr's official CDN hosts: a dropped connection
|
|
35
|
-
// on a slow CI network must not be reported as a TLS regression.
|
|
36
|
-
t.section('npm-package')
|
|
37
|
-
let worker3: any
|
|
38
|
-
const NPM_HOSTS = ['cdn.jsdelivr.net', 'fastly.jsdelivr.net', 'gcore.jsdelivr.net']
|
|
39
|
-
let workerOk = false
|
|
40
|
-
for (const host of NPM_HOSTS) {
|
|
41
|
-
for (let attempt = 0; attempt < 3 && !workerOk; attempt++) {
|
|
42
|
-
try {
|
|
43
|
-
const { data: r3 } = await new Promise<any>((resolve, reject) => {
|
|
44
|
-
worker3 = new os.Worker('https://' + host + '/npm/quickwin/test/worker_module.js')
|
|
45
|
-
const timer = os.setTimeout(() => reject(new Error('timeout')), 15000)
|
|
46
|
-
worker3.onmessage = (e: any) => {
|
|
47
|
-
os.clearTimeout(timer)
|
|
48
|
-
resolve({ worker: worker3, data: e.data })
|
|
49
|
-
}
|
|
50
|
-
worker3.postMessage({ type: 'start' })
|
|
51
|
-
})
|
|
52
|
-
t.check('npm worker message type', 'result', r3.type)
|
|
53
|
-
t.check('npm worker imported value', 42, r3.value)
|
|
54
|
-
worker3.postMessage({ type: 'done' })
|
|
55
|
-
worker3.onmessage = null
|
|
56
|
-
workerOk = true
|
|
57
|
-
} catch (e) {
|
|
58
|
-
if (worker3) { worker3.onmessage = null; worker3 = null }
|
|
59
|
-
if (attempt === 2 && host === NPM_HOSTS[NPM_HOSTS.length - 1]) t.checkTrue('npm worker failed: ' + e, false)
|
|
60
|
-
else os.sleep(500)
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
if (workerOk) break
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
}
|
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
import { readWasmFile } from './test_helper.js';
|
|
2
|
-
import * as os from 'os';
|
|
3
|
-
export const suite = {
|
|
4
|
-
name: 'worker-wasm',
|
|
5
|
-
run: async (t) => {
|
|
6
|
-
const wasmBuf = readWasmFile('./add.wasm');
|
|
7
|
-
if (!wasmBuf) {
|
|
8
|
-
t.fail++;
|
|
9
|
-
return;
|
|
10
|
-
}
|
|
11
|
-
const complexBuf = readWasmFile('./complex.wasm');
|
|
12
|
-
if (!complexBuf) {
|
|
13
|
-
t.fail++;
|
|
14
|
-
return;
|
|
15
|
-
}
|
|
16
|
-
t.section('concurrent');
|
|
17
|
-
const worker = new os.Worker('./worker_wasm_concurrent.js');
|
|
18
|
-
const workerResult = new Promise((resolve, reject) => {
|
|
19
|
-
const timer = os.setTimeout(() => reject(new Error('worker timeout')), 5000);
|
|
20
|
-
worker.onmessage = (e) => {
|
|
21
|
-
os.clearTimeout(timer);
|
|
22
|
-
resolve(e.data);
|
|
23
|
-
};
|
|
24
|
-
worker.postMessage({
|
|
25
|
-
type: 'start',
|
|
26
|
-
wasmBuf,
|
|
27
|
-
calls: [['add', [1, 2]], ['add', [10, 20]]]
|
|
28
|
-
});
|
|
29
|
-
});
|
|
30
|
-
const mainMod = new WebAssembly.Module(wasmBuf);
|
|
31
|
-
const mainInst = new WebAssembly.Instance(mainMod);
|
|
32
|
-
const mainExp = mainInst.exports;
|
|
33
|
-
const mainR1 = mainExp.add(1, 2);
|
|
34
|
-
const mainR2 = mainExp.add(10, 20);
|
|
35
|
-
const wr = await workerResult;
|
|
36
|
-
t.check('main add(1, 2)', 3, mainR1);
|
|
37
|
-
t.check('main add(10, 20)', 30, mainR2);
|
|
38
|
-
t.check('worker ok', true, wr.ok);
|
|
39
|
-
t.check('worker add(1, 2)', 3, wr.results[0]);
|
|
40
|
-
t.check('worker add(10, 20)', 30, wr.results[1]);
|
|
41
|
-
worker.postMessage({ type: 'done' });
|
|
42
|
-
worker.onmessage = null;
|
|
43
|
-
}
|
|
44
|
-
};
|