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.
Files changed (163) hide show
  1. package/README.en.md +3 -0
  2. package/README.md +2 -0
  3. package/package.json +2 -3
  4. package/qwin-nowasm-x86.exe +0 -0
  5. package/qwin-nowasm.exe +0 -0
  6. package/qwin-x86.exe +0 -0
  7. package/qwin.exe +0 -0
  8. package/examples/PdfCanvas.js +0 -38
  9. package/examples/PdfCanvas.tsx +0 -54
  10. package/examples/execd/main.js +0 -23379
  11. package/examples/execd/tray.js +0 -192
  12. package/examples/execd/worker.js +0 -122
  13. package/examples/pdf_preview2.js +0 -398
  14. package/examples/pdf_preview2.ts +0 -353
  15. package/examples/pdf_viewer.js +0 -22515
  16. package/examples/pdf_viewer.tsx +0 -228
  17. package/examples/test_gallery.js +0 -18692
  18. package/examples/test_gallery.tsx +0 -291
  19. package/examples/test_react_lazy.js +0 -18560
  20. package/examples/test_react_lazy.tsx +0 -65
  21. package/examples/test_react_listbox.js +0 -18562
  22. package/examples/test_react_listbox.tsx +0 -73
  23. package/examples/test_root_window.js +0 -18532
  24. package/examples/test_root_window.tsx +0 -41
  25. package/examples/test_tab.js +0 -18563
  26. package/examples/test_tab.tsx +0 -77
  27. package/examples/tray_demo.js +0 -86
  28. package/examples/tray_demo.tsx +0 -89
  29. package/test/add.wasm +0 -0
  30. package/test/bench_ffi_callraw.js +0 -235
  31. package/test/bench_ffi_callraw.ts +0 -235
  32. package/test/bench_ffi_overhead.js +0 -139
  33. package/test/bench_ffi_overhead.ts +0 -141
  34. package/test/bench_sendmessage.js +0 -104
  35. package/test/bench_sendmessage.ts +0 -100
  36. package/test/bench_sendmessage_nonnull.js +0 -187
  37. package/test/bench_sendmessage_nonnull.ts +0 -188
  38. package/test/complex.wasm +0 -0
  39. package/test/complex_imports.wasm +0 -0
  40. package/test/debug/http_server_e2e.js +0 -31
  41. package/test/debug/minwasm.js +0 -52
  42. package/test/debug/mupdf_debug.js +0 -86
  43. package/test/debug/wasm.js +0 -122
  44. package/test/debug/wasm_export_debug.js +0 -54
  45. package/test/debug/wasm_names.js +0 -36
  46. package/test/example.pdf +0 -0
  47. package/test/global_imports.wasm +0 -0
  48. package/test/import_func.wasm +0 -0
  49. package/test/imports.wasm +0 -0
  50. package/test/mupdf-cdn.js +0 -40
  51. package/test/mupdf-cdn.ts +0 -43
  52. package/test/run.js +0 -111
  53. package/test/run.ts +0 -116
  54. package/test/sjlj.wasm +0 -0
  55. package/test/test_basic.js +0 -7
  56. package/test/test_basic.ts +0 -9
  57. package/test/test_basic_fetch.js +0 -63
  58. package/test/test_basic_fetch.ts +0 -59
  59. package/test/test_brotli.js +0 -48
  60. package/test/test_brotli.ts +0 -52
  61. package/test/test_fetch_cache.js +0 -169
  62. package/test/test_fetch_cache.ts +0 -187
  63. package/test/test_ffi.js +0 -157
  64. package/test/test_ffi.ts +0 -170
  65. package/test/test_ffi_abi.js +0 -290
  66. package/test/test_ffi_abi.ts +0 -274
  67. package/test/test_ffi_array.js +0 -116
  68. package/test/test_ffi_array.ts +0 -141
  69. package/test/test_ffi_bind.js +0 -656
  70. package/test/test_ffi_bind.ts +0 -670
  71. package/test/test_ffi_struct.js +0 -779
  72. package/test/test_ffi_struct.ts +0 -828
  73. package/test/test_ffi_struct_layout.js +0 -495
  74. package/test/test_ffi_struct_layout.ts +0 -543
  75. package/test/test_ffi_user32.js +0 -103
  76. package/test/test_ffi_user32.ts +0 -113
  77. package/test/test_ffi_windows.js +0 -172
  78. package/test/test_ffi_windows.ts +0 -187
  79. package/test/test_files.js +0 -102
  80. package/test/test_files.ts +0 -121
  81. package/test/test_frame_encoding.js +0 -128
  82. package/test/test_frame_encoding.ts +0 -132
  83. package/test/test_gdi_draw.js +0 -681
  84. package/test/test_gdi_draw.ts +0 -725
  85. package/test/test_helper.js +0 -91
  86. package/test/test_helper.ts +0 -88
  87. package/test/test_http_import.js +0 -96
  88. package/test/test_http_import.ts +0 -93
  89. package/test/test_http_server.js +0 -214
  90. package/test/test_http_server.ts +0 -211
  91. package/test/test_import_dir.js +0 -4
  92. package/test/test_import_dir.ts +0 -5
  93. package/test/test_ipv6.js +0 -134
  94. package/test/test_ipv6.ts +0 -130
  95. package/test/test_jsx.js +0 -1314
  96. package/test/test_meta_url.js +0 -3
  97. package/test/test_meta_url.ts +0 -4
  98. package/test/test_mupdf_render.js +0 -51
  99. package/test/test_mupdf_render.ts +0 -55
  100. package/test/test_mupdf_twice.js +0 -62
  101. package/test/test_mupdf_twice.ts +0 -65
  102. package/test/test_mupdf_wasm.js +0 -39
  103. package/test/test_mupdf_wasm.ts +0 -32
  104. package/test/test_net_event.js +0 -57
  105. package/test/test_net_event.ts +0 -56
  106. package/test/test_net_fetch.js +0 -384
  107. package/test/test_net_fetch.ts +0 -373
  108. package/test/test_net_websocket.js +0 -180
  109. package/test/test_net_websocket.ts +0 -164
  110. package/test/test_polyfill.js +0 -144
  111. package/test/test_polyfill.ts +0 -159
  112. package/test/test_printer.js +0 -137
  113. package/test/test_printer.ts +0 -148
  114. package/test/test_proc.js +0 -141
  115. package/test/test_proc.ts +0 -163
  116. package/test/test_react_complex.js +0 -18678
  117. package/test/test_react_counter.js +0 -18555
  118. package/test/test_react_flex.js +0 -18871
  119. package/test/test_react_hidden.js +0 -18560
  120. package/test/test_react_listview_link.js +0 -18590
  121. package/test/test_react_notify.js +0 -18797
  122. package/test/test_react_render.js +0 -18550
  123. package/test/test_registry.js +0 -74
  124. package/test/test_registry.ts +0 -95
  125. package/test/test_sysinfo.js +0 -122
  126. package/test/test_sysinfo.ts +0 -141
  127. package/test/test_url.js +0 -173
  128. package/test/test_url.ts +0 -183
  129. package/test/test_wasm_basic.js +0 -85
  130. package/test/test_wasm_basic.ts +0 -73
  131. package/test/test_wasm_import_global.js +0 -41
  132. package/test/test_wasm_import_global.ts +0 -45
  133. package/test/test_wasm_sjlj.js +0 -145
  134. package/test/test_wasm_sjlj.ts +0 -125
  135. package/test/test_wasm_types.js +0 -97
  136. package/test/test_wasm_types.ts +0 -124
  137. package/test/test_wolfssl_read.js +0 -203
  138. package/test/test_wolfssl_read.ts +0 -184
  139. package/test/test_worker.js +0 -21
  140. package/test/test_worker.ts +0 -24
  141. package/test/test_worker_concurrent.js +0 -45
  142. package/test/test_worker_concurrent.ts +0 -56
  143. package/test/test_worker_data_url.js +0 -46
  144. package/test/test_worker_data_url.ts +0 -51
  145. package/test/test_worker_fetch.js +0 -26
  146. package/test/test_worker_fetch.ts +0 -27
  147. package/test/test_worker_net.js +0 -69
  148. package/test/test_worker_net.ts +0 -66
  149. package/test/test_worker_wasm_concurrent.js +0 -44
  150. package/test/test_worker_wasm_concurrent.ts +0 -45
  151. package/test/types.wasm +0 -0
  152. package/test/worker_fetch.js +0 -13
  153. package/test/worker_fetch.ts +0 -13
  154. package/test/worker_helper.js +0 -1
  155. package/test/worker_helper.ts +0 -1
  156. package/test/worker_http.js +0 -18
  157. package/test/worker_http.ts +0 -20
  158. package/test/worker_import_lib.js +0 -12
  159. package/test/worker_import_lib.ts +0 -13
  160. package/test/worker_module.js +0 -16
  161. package/test/worker_module.ts +0 -17
  162. package/test/worker_wasm_concurrent.js +0 -22
  163. package/test/worker_wasm_concurrent.ts +0 -22
@@ -1,384 +0,0 @@
1
- import '../lib/fetch.js';
2
- import * as std from 'std';
3
- import * as os from 'os';
4
- export const suite = {
5
- name: 'net-fetch',
6
- run: async (t) => {
7
- function assert(name, ok) {
8
- if (ok) {
9
- t.ok++;
10
- std.printf(' PASS: %s\n', name);
11
- }
12
- else {
13
- t.fail++;
14
- std.printf(' FAIL: %s\n', name);
15
- }
16
- }
17
- // Retry: public-site reachability (baidu/jsdelivr/esm.sh) depends on
18
- // CI network conditions, and a single dropped connection must not be
19
- // reported as a certificate regression. The last error is printed so a
20
- // real failure is still diagnosable.
21
- async function safeFetch(url, init) {
22
- let last = 'unknown';
23
- for (let attempt = 0; attempt < 3; attempt++) {
24
- try {
25
- return await fetch(url, init);
26
- }
27
- catch (e) {
28
- last = String(e?.message || e);
29
- if (attempt < 2)
30
- os.sleep(500);
31
- }
32
- }
33
- std.printf(' fetch %s failed after 3 attempts: %s\n', String(url), last);
34
- return null;
35
- }
36
- const BASE = 'http://localhost:18923';
37
- // ── Plain HTTP GET (regression: slot 0 + !s bug) ──
38
- t.section('plain HTTP');
39
- const r0 = await safeFetch(BASE + '/', { timeout: 5000 });
40
- if (r0) {
41
- assert('plain HTTP status 200', r0.status === 200);
42
- const body = await r0.text();
43
- assert('plain HTTP body non-empty', body.length > 0);
44
- assert('plain HTTP body matches', body === 'hello from test server');
45
- }
46
- else {
47
- assert('plain HTTP endpoint reachable', false);
48
- }
49
- // ── Basic HTTP GET ──
50
- t.section('HTTP GET');
51
- const r1 = await safeFetch(BASE + '/any');
52
- if (r1) {
53
- assert('status received', r1.status > 0);
54
- const body = await r1.text();
55
- assert('body received', body.length > 0);
56
- }
57
- else {
58
- assert('local server reachable', false);
59
- }
60
- // ── Query string ──
61
- t.section('query string');
62
- const rq = await safeFetch(BASE + '/any?foo=bar&baz=42');
63
- if (rq) {
64
- const body = JSON.parse(await rq.text());
65
- assert('query args received', body.args !== undefined);
66
- assert('?foo=bar preserved', body.args.foo === 'bar');
67
- assert('?baz=42 preserved', body.args.baz === '42');
68
- }
69
- else {
70
- assert('query string endpoint reachable', false);
71
- }
72
- // ── Request constructor ──
73
- t.section('Request constructor');
74
- {
75
- const r = new Request('https://httpbun.com/any?x=1&y=2', { method: 'POST', headers: { 'X-Test': 'val' }, body: 'hello' });
76
- assert('Request.url', r.url === 'https://httpbun.com/any?x=1&y=2');
77
- assert('Request.method', r.method === 'POST');
78
- assert('Request.headers get', r.headers.get('x-test') === 'val');
79
- assert('Request.body is ReadableStream', r.body !== null && typeof r.body.getReader === 'function');
80
- }
81
- {
82
- const r1 = new Request('https://example.com/path');
83
- assert('Request default method GET', r1.method === 'GET');
84
- assert('Request default redirect follow', r1.redirect === 'follow');
85
- }
86
- {
87
- const r2 = new Request('https://httpbun.com/any');
88
- const r3 = new Request(r2, { method: 'PUT' });
89
- assert('Request clone same url', r3.url === r2.url);
90
- assert('Request clone override method', r3.method === 'PUT');
91
- }
92
- {
93
- const r = await safeFetch(new Request(BASE + '/any', { method: 'POST', headers: { 'Content-Type': 'text/plain' }, body: 'req-class' }));
94
- if (r) {
95
- const body = JSON.parse(await r.text());
96
- assert('fetch(Request) status', r.status > 0);
97
- assert('fetch(Request) method POST', body.method === 'POST');
98
- assert('fetch(Request) body received', body.data === 'req-class');
99
- assert('fetch(Request) content-type', body.headers['content-type'] === 'text/plain');
100
- }
101
- else {
102
- assert('fetch(Request) endpoint reachable', false);
103
- }
104
- }
105
- // ── body / bodyUsed / stream ──
106
- t.section('body / bodyUsed / stream');
107
- const r2 = await safeFetch(BASE + '/any');
108
- if (r2) {
109
- assert('r.body exists', typeof r2.body === 'object' && r2.body !== null);
110
- assert('bodyUsed false before read', r2.bodyUsed === false);
111
- const reader = r2.body.getReader();
112
- let total = 0;
113
- while (true) {
114
- const { done, value } = await reader.read();
115
- if (done)
116
- break;
117
- total += value.length;
118
- }
119
- assert('reader streams all bytes', total > 0);
120
- assert('bodyUsed true after stream', r2.bodyUsed === true);
121
- }
122
- else {
123
- assert('body test endpoint reachable', false);
124
- }
125
- // ── text/json/arrayBuffer ──
126
- t.section('text / json / arrayBuffer');
127
- const r3 = await safeFetch(BASE + '/any');
128
- if (r3) {
129
- const text = await r3.text();
130
- assert('text() returns string', typeof text === 'string' && text.length > 0);
131
- assert('bodyUsed true after text()', r3.bodyUsed === true);
132
- const r4 = await safeFetch(BASE + '/any');
133
- if (r4) {
134
- const buf = await r4.arrayBuffer();
135
- assert('arrayBuffer() returns bytes', buf.byteLength > 0);
136
- }
137
- }
138
- else {
139
- assert('text/json/ab endpoint reachable', false);
140
- }
141
- // double text() throws
142
- t.section('bodyUsed throws');
143
- const r5 = await safeFetch(BASE + '/any');
144
- if (r5) {
145
- await r5.text();
146
- try {
147
- await r5.text();
148
- assert('double text() throws', false);
149
- }
150
- catch (e) {
151
- assert('double text() throws TypeError', e.message === 'Body already used');
152
- }
153
- }
154
- // ── POST ──
155
- t.section('POST');
156
- const r6 = await safeFetch(BASE + '/any', {
157
- method: 'POST',
158
- headers: { 'Content-Type': 'application/json' },
159
- body: JSON.stringify({ msg: 'hello' })
160
- });
161
- if (r6) {
162
- const body = await r6.text();
163
- assert('POST body received', body.length > 0);
164
- }
165
- else {
166
- assert('POST endpoint reachable', false);
167
- }
168
- // ── Headers (local, no network) ──
169
- t.section('Headers (local)');
170
- const h = new Headers({ 'Content-Type': 'text/html', 'X-Custom': 'hello', 'Accept': '*/*' });
171
- let c = 0;
172
- for (const [k, v] of h) {
173
- c++;
174
- if (typeof k !== 'string' || typeof v !== 'string')
175
- assert('for...of type', false);
176
- }
177
- assert('for...of yields entries', c === 3);
178
- assert('get()', h.get('content-type') === 'text/html');
179
- assert('get() case-insensitive', h.get('Content-Type') === 'text/html');
180
- assert('has()', h.has('x-custom'));
181
- assert('set() overwrites', (h.set('accept', 'application/json'), h.get('accept') === 'application/json'));
182
- assert('append() adds', (h.append('accept', 'text/plain'), h.get('accept') === 'application/json, text/plain'));
183
- assert('delete()', (h.delete('accept'), h.has('accept') === false));
184
- const h2 = new Headers({ 'a': '1', 'b': '2' });
185
- let ec = 0;
186
- for (const _ of h2.entries()) {
187
- ec++;
188
- }
189
- assert('entries()', ec === 2);
190
- let kc = 0;
191
- for (const _ of h2.keys()) {
192
- kc++;
193
- }
194
- assert('keys()', kc === 2);
195
- let vc = 0;
196
- for (const _ of h2.values()) {
197
- vc++;
198
- }
199
- assert('values()', vc === 2);
200
- // ── Chunked Transfer-Encoding ──
201
- t.section('chunked transfer encoding');
202
- const r8 = await safeFetch(BASE + '/anything');
203
- if (r8) {
204
- assert('chunked status 200', r8.status === 200);
205
- const body = await r8.json();
206
- assert('chunked json has url', typeof body.url === 'string' && body.url.length > 0);
207
- }
208
- else {
209
- assert('local server reachable', false);
210
- }
211
- // ── stream cancel ──
212
- t.section('stream cancel');
213
- const r7 = await safeFetch(BASE + '/any');
214
- if (r7) {
215
- r7.body.cancel();
216
- assert('cancel() succeeds', true);
217
- // After cancel: buffered chunks still readable, then done
218
- const reader = r7.body.getReader();
219
- let finalDone = false;
220
- while (true) {
221
- const { done } = await reader.read();
222
- if (done) {
223
- finalDone = true;
224
- break;
225
- }
226
- }
227
- assert('reader done after cancel', finalDone === true);
228
- }
229
- else {
230
- assert('cancel test endpoint reachable', false);
231
- }
232
- // ── UTF-8 Chinese text body ──
233
- t.section('utf-8 chinese text');
234
- const r9 = await safeFetch(BASE + '/base64/5Lit5paH');
235
- if (r9) {
236
- assert('chinese status 200', r9.status === 200);
237
- const body = await r9.text();
238
- assert('chinese body is 中文', body === '\u4e2d\u6587');
239
- assert('chinese body length=2', body.length === 2);
240
- }
241
- else {
242
- assert('local server reachable', false);
243
- }
244
- // ── POST with Chinese body ──
245
- t.section('post with chinese body');
246
- const r10 = await safeFetch(BASE + '/post', {
247
- method: 'POST',
248
- body: '\u4e2d\u6587',
249
- headers: { 'Content-Type': 'text/plain; charset=utf-8' }
250
- });
251
- if (r10) {
252
- assert('post status 200', r10.status === 200);
253
- const body = await r10.text();
254
- assert('post body contains 中文', body.includes('\u4e2d\u6587'));
255
- }
256
- else {
257
- assert('local server reachable', false);
258
- }
259
- // ── HTTPS fetch ──
260
- t.section('HTTPS fetch');
261
- const r11 = await safeFetch('https://localhost:18924/', { timeout: 5000, rejectUnauthorized: false });
262
- if (r11) {
263
- assert('https status 200', r11.status === 200);
264
- const body = await r11.text();
265
- assert('https body matches', body === 'hello from test server');
266
- }
267
- else {
268
- assert('https endpoint reachable', false);
269
- }
270
- // ── GlobalSign R3 root chain (regression: ASN_SIG_CONFIRM_E -155) ──
271
- // baidu.com and jsdelivr terminate in GlobalSign's 2018 re-keyed R3,
272
- // which reuses the self-signed R3's subject-key-identifier with a
273
- // different public key. Shipping the self-signed R3 in lib/certs.ts
274
- // made wolfSSL match the wrong key and fail the handshake with -155.
275
- // Both are public CDNs: a 500/429 or a dropped connection then counts
276
- // as a retried attempt, not an immediate failure — only a persistent
277
- // failure (cert regression or long-lived outage) should fail CI.
278
- t.section('GlobalSign R3 root chain');
279
- {
280
- async function fetchR3(url) {
281
- const init = { timeout: 10000 };
282
- for (let attempt = 0; attempt < 3; attempt++) {
283
- try {
284
- const r = await fetch(url, init);
285
- const body = await r.text();
286
- if (r.status === 200 && body.length > 0)
287
- return body;
288
- std.printf(' fetch %s status=%s len=%d (attempt %d)\n', String(url), String(r.status), body.length, attempt);
289
- }
290
- catch (e) {
291
- std.printf(' fetch %s error: %s (attempt %d)\n', String(url), String(e?.message || e), attempt);
292
- }
293
- os.sleep(1000);
294
- }
295
- return null;
296
- }
297
- const bb = await fetchR3('https://www.baidu.com/');
298
- if (bb) {
299
- assert('baidu (GlobalSign R3) status', true);
300
- assert('baidu (GlobalSign R3) body non-empty', bb.length > 0);
301
- }
302
- else {
303
- assert('baidu (GlobalSign R3) reachable', false);
304
- }
305
- const JSDELIVR_HOSTS = ['cdn.jsdelivr.net', 'fastly.jsdelivr.net', 'gcore.jsdelivr.net'];
306
- for (const host of JSDELIVR_HOSTS) {
307
- const bj = await fetchR3('https://' + host + '/npm/left-pad@1.3.0');
308
- if (bj) {
309
- assert('jsdelivr (GlobalSign R3) status', true);
310
- assert('jsdelivr (GlobalSign R3) body non-empty', bj.length > 0);
311
- break;
312
- }
313
- if (host !== JSDELIVR_HOSTS[JSDELIVR_HOSTS.length - 1]) {
314
- std.printf(' jsdelivr host %s failed, trying next\n', host);
315
- }
316
- else {
317
- assert('jsdelivr (GlobalSign R3) reachable', false);
318
- }
319
- }
320
- }
321
- // ── large HTTPS body (wolfSSL_read int contract) ──
322
- // read returns the raw int; -1/WANT_READ must never leak into
323
- // byte accounting (regression: a leaked -1 made receivedBytes
324
- // NaN → stream never closed → hang).
325
- t.section('large HTTPS body');
326
- {
327
- const LARGE = 200000;
328
- try {
329
- const r = await Promise.race([
330
- fetch(`https://localhost:18924/large/${LARGE}`, { timeout: 15000, rejectUnauthorized: false }),
331
- new Promise((_, rej) => os.setTimeout(() => rej(new Error('Body hang watchdog 15s')), 15000))
332
- ]);
333
- assert('large HTTPS status 200', r.status === 200);
334
- const buf = await Promise.race([
335
- r.arrayBuffer(),
336
- new Promise((_, rej) => os.setTimeout(() => rej(new Error('arrayBuffer hang watchdog 15s')), 15000))
337
- ]);
338
- assert('large HTTPS byteLength exact', buf.byteLength === LARGE);
339
- }
340
- catch (e) {
341
- assert('large HTTPS completed without hang (' + String(e.message) + ')', false);
342
- }
343
- }
344
- // ── large HTTP body (sock.recv path same null contract) ──
345
- t.section('large HTTP body');
346
- {
347
- const LARGE = 200000;
348
- try {
349
- const r = await Promise.race([
350
- fetch(`http://localhost:18923/large/${LARGE}`, { timeout: 15000 }),
351
- new Promise((_, rej) => os.setTimeout(() => rej(new Error('Body hang watchdog 15s')), 15000))
352
- ]);
353
- assert('large HTTP status 200', r.status === 200);
354
- const buf = await Promise.race([
355
- r.arrayBuffer(),
356
- new Promise((_, rej) => os.setTimeout(() => rej(new Error('arrayBuffer hang watchdog 15s')), 15000))
357
- ]);
358
- assert('large HTTP byteLength exact', buf.byteLength === LARGE);
359
- }
360
- catch (e) {
361
- assert('large HTTP completed (' + String(e.message) + ')', false);
362
- }
363
- }
364
- // ── body timeout after headers (armTimeout after doResolve) ──
365
- t.section('HTTPS body timeout');
366
- {
367
- let rejected = false;
368
- let msg = '';
369
- try {
370
- const r = await fetch('https://localhost:18924/stall', { timeout: 2000, rejectUnauthorized: false });
371
- await Promise.race([
372
- r.arrayBuffer(),
373
- new Promise((_, rej) => os.setTimeout(() => rej(new Error('Body timeout')), 8000))
374
- ]);
375
- }
376
- catch (e) {
377
- rejected = true;
378
- msg = String(e.message);
379
- }
380
- assert('stall body rejects (timeout)', rejected);
381
- assert('stall error mentions timeout', /timeout/i.test(msg));
382
- }
383
- }
384
- };