quickwin 1.0.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.
Files changed (175) hide show
  1. package/README.en.md +197 -0
  2. package/README.md +196 -0
  3. package/examples/PdfCanvas.js +67 -0
  4. package/examples/PdfCanvas.tsx +83 -0
  5. package/examples/pdf_preview2.js +431 -0
  6. package/examples/pdf_preview2.ts +375 -0
  7. package/examples/pdf_viewer.js +17623 -0
  8. package/examples/pdf_viewer.tsx +279 -0
  9. package/examples/test_gallery.js +17452 -0
  10. package/examples/test_gallery.tsx +285 -0
  11. package/examples/test_react_lazy.js +17336 -0
  12. package/examples/test_react_lazy.tsx +63 -0
  13. package/examples/test_react_listbox.js +17339 -0
  14. package/examples/test_react_listbox.tsx +71 -0
  15. package/examples/test_root_window.js +17313 -0
  16. package/examples/test_root_window.tsx +41 -0
  17. package/examples/test_tab.js +17339 -0
  18. package/examples/test_tab.tsx +75 -0
  19. package/examples/tray_demo.js +79 -0
  20. package/examples/tray_demo.tsx +81 -0
  21. package/lib/assert.js +8 -0
  22. package/lib/assert.ts +7 -0
  23. package/lib/cache-utils.js +43 -0
  24. package/lib/cache-utils.ts +40 -0
  25. package/lib/dumpRects.js +25 -0
  26. package/lib/dumpRects.ts +25 -0
  27. package/lib/fetch.js +490 -0
  28. package/lib/fetch.ts +502 -0
  29. package/lib/http-common.js +342 -0
  30. package/lib/http-common.ts +399 -0
  31. package/lib/http-server.js +416 -0
  32. package/lib/http-server.ts +424 -0
  33. package/lib/polyfill.js +156 -0
  34. package/lib/polyfill.ts +171 -0
  35. package/lib/react-qw/components/Button.js +8 -0
  36. package/lib/react-qw/components/CheckBox.js +31 -0
  37. package/lib/react-qw/components/ComboBox.js +42 -0
  38. package/lib/react-qw/components/DateTimePicker.js +96 -0
  39. package/lib/react-qw/components/Input.js +50 -0
  40. package/lib/react-qw/components/Link.js +43 -0
  41. package/lib/react-qw/components/ListBox.js +48 -0
  42. package/lib/react-qw/components/ListView.js +328 -0
  43. package/lib/react-qw/components/PathPicker.js +136 -0
  44. package/lib/react-qw/components/ProgressBar.js +22 -0
  45. package/lib/react-qw/components/RadioButton.js +31 -0
  46. package/lib/react-qw/components/ScrollView.js +139 -0
  47. package/lib/react-qw/components/Slider.js +45 -0
  48. package/lib/react-qw/components/Tab.js +61 -0
  49. package/lib/react-qw/components/Tooltip.js +55 -0
  50. package/lib/react-qw/components/TreeView.js +130 -0
  51. package/lib/react-qw/components/index.js +16 -0
  52. package/lib/react-qw/components/index.ts +17 -0
  53. package/lib/react-qw/index.js +73 -0
  54. package/lib/react-qw/index.ts +90 -0
  55. package/lib/react-qw/jsx.d.ts +34 -0
  56. package/lib/react-qw/layout.js +82 -0
  57. package/lib/react-qw/layout.ts +111 -0
  58. package/lib/react-qw/props.js +27 -0
  59. package/lib/react-qw/props.ts +36 -0
  60. package/lib/react-qw/reconciler.js +333 -0
  61. package/lib/react-qw/reconciler.ts +373 -0
  62. package/lib/stream.js +2 -0
  63. package/lib/stream.ts +22 -0
  64. package/lib/text-codec.js +197 -0
  65. package/lib/text-codec.ts +171 -0
  66. package/lib/text-measure.js +52 -0
  67. package/lib/text-measure.ts +54 -0
  68. package/lib/url.js +278 -0
  69. package/lib/url.ts +201 -0
  70. package/lib/vendor/web-streams/ponyfill.d.mts +829 -0
  71. package/lib/vendor/web-streams/ponyfill.mjs +8 -0
  72. package/lib/websocket.js +541 -0
  73. package/lib/websocket.ts +555 -0
  74. package/package.json +44 -0
  75. package/quickwin.d.ts +594 -0
  76. package/quickwin_const.d.ts +900 -0
  77. package/qwin-nowasm.exe +0 -0
  78. package/qwin.exe +0 -0
  79. package/test/add.wasm +0 -0
  80. package/test/complex.wasm +0 -0
  81. package/test/complex_imports.wasm +0 -0
  82. package/test/debug/http_server_e2e.js +31 -0
  83. package/test/debug/minwasm.js +52 -0
  84. package/test/debug/mupdf_debug.js +104 -0
  85. package/test/debug/wasm.js +122 -0
  86. package/test/debug/wasm_export_debug.js +64 -0
  87. package/test/debug/wasm_names.js +46 -0
  88. package/test/global_imports.wasm +0 -0
  89. package/test/import_func.wasm +0 -0
  90. package/test/imports.wasm +0 -0
  91. package/test/run.js +91 -0
  92. package/test/run.ts +96 -0
  93. package/test/sjlj.wasm +0 -0
  94. package/test/test_basic.js +7 -0
  95. package/test/test_basic.ts +9 -0
  96. package/test/test_basic_fetch.js +34 -0
  97. package/test/test_basic_fetch.ts +33 -0
  98. package/test/test_brotli.js +48 -0
  99. package/test/test_brotli.ts +52 -0
  100. package/test/test_fetch_cache.js +169 -0
  101. package/test/test_fetch_cache.ts +187 -0
  102. package/test/test_ffi.js +157 -0
  103. package/test/test_ffi.ts +174 -0
  104. package/test/test_frame_encoding.js +128 -0
  105. package/test/test_frame_encoding.ts +132 -0
  106. package/test/test_helper.js +84 -0
  107. package/test/test_helper.ts +80 -0
  108. package/test/test_http_import.js +78 -0
  109. package/test/test_http_import.ts +74 -0
  110. package/test/test_http_server.js +142 -0
  111. package/test/test_http_server.ts +136 -0
  112. package/test/test_import_dir.js +4 -0
  113. package/test/test_import_dir.ts +5 -0
  114. package/test/test_ipv6.js +134 -0
  115. package/test/test_ipv6.ts +129 -0
  116. package/test/test_jsx.js +1314 -0
  117. package/test/test_meta_url.js +3 -0
  118. package/test/test_meta_url.ts +4 -0
  119. package/test/test_mupdf_render.js +69 -0
  120. package/test/test_mupdf_render.ts +74 -0
  121. package/test/test_mupdf_twice.js +77 -0
  122. package/test/test_mupdf_twice.ts +81 -0
  123. package/test/test_mupdf_wasm.js +33 -0
  124. package/test/test_mupdf_wasm.ts +30 -0
  125. package/test/test_net_event.js +57 -0
  126. package/test/test_net_event.ts +55 -0
  127. package/test/test_net_fetch.js +259 -0
  128. package/test/test_net_fetch.ts +238 -0
  129. package/test/test_net_websocket.js +180 -0
  130. package/test/test_net_websocket.ts +164 -0
  131. package/test/test_polyfill.js +144 -0
  132. package/test/test_polyfill.ts +159 -0
  133. package/test/test_react_complex.js +17440 -0
  134. package/test/test_react_counter.js +17331 -0
  135. package/test/test_react_flex.js +17643 -0
  136. package/test/test_react_hidden.js +17336 -0
  137. package/test/test_react_listview_link.js +17371 -0
  138. package/test/test_react_render.js +17326 -0
  139. package/test/test_url.js +173 -0
  140. package/test/test_url.ts +183 -0
  141. package/test/test_wasm_basic.js +85 -0
  142. package/test/test_wasm_basic.ts +73 -0
  143. package/test/test_wasm_import_global.js +41 -0
  144. package/test/test_wasm_import_global.ts +45 -0
  145. package/test/test_wasm_sjlj.js +145 -0
  146. package/test/test_wasm_sjlj.ts +125 -0
  147. package/test/test_wasm_types.js +97 -0
  148. package/test/test_wasm_types.ts +124 -0
  149. package/test/test_worker.js +21 -0
  150. package/test/test_worker.ts +24 -0
  151. package/test/test_worker_fetch.js +26 -0
  152. package/test/test_worker_fetch.ts +27 -0
  153. package/test/test_worker_net.js +51 -0
  154. package/test/test_worker_net.ts +54 -0
  155. package/test/test_worker_wasm_concurrent.js +44 -0
  156. package/test/test_worker_wasm_concurrent.ts +45 -0
  157. package/test/types.wasm +0 -0
  158. package/test/worker_fetch.js +13 -0
  159. package/test/worker_fetch.ts +13 -0
  160. package/test/worker_helper.js +1 -0
  161. package/test/worker_helper.ts +1 -0
  162. package/test/worker_http.js +18 -0
  163. package/test/worker_http.ts +20 -0
  164. package/test/worker_import_lib.js +12 -0
  165. package/test/worker_import_lib.ts +13 -0
  166. package/test/worker_module.js +16 -0
  167. package/test/worker_module.ts +17 -0
  168. package/test/worker_wasm_concurrent.js +22 -0
  169. package/test/worker_wasm_concurrent.ts +22 -0
  170. package/tsconfig.json +27 -0
  171. package/vendor/mupdf-wasm/mupdf-wasm.d.ts +571 -0
  172. package/vendor/mupdf-wasm/mupdf-wasm.js +2749 -0
  173. package/vendor/mupdf-wasm/mupdf-wasm.wasm +0 -0
  174. package/vendor/mupdf-wasm/mupdf.d.ts +939 -0
  175. package/vendor/mupdf-wasm/mupdf.js +3317 -0
@@ -0,0 +1,342 @@
1
+ import './polyfill.js';
2
+ import './stream.js';
3
+ // ── Byte helpers ──
4
+ export function _concat(parts) {
5
+ if (parts.length === 0)
6
+ return new Uint8Array(0);
7
+ let totalLen = 0;
8
+ for (const p of parts)
9
+ totalLen += p.length;
10
+ const result = new Uint8Array(totalLen);
11
+ let offset = 0;
12
+ for (const p of parts) {
13
+ result.set(p, offset);
14
+ offset += p.length;
15
+ }
16
+ return result;
17
+ }
18
+ export function _toReadableStream(body) {
19
+ if (body instanceof ReadableStream)
20
+ return body;
21
+ const bytes = (typeof body === 'string')
22
+ ? new TextEncoder().encode(body)
23
+ : (body instanceof ArrayBuffer)
24
+ ? new Uint8Array(body)
25
+ : new Uint8Array(body.buffer, body.byteOffset, body.byteLength);
26
+ return new ReadableStream({
27
+ start(ctrl) {
28
+ ctrl.enqueue(bytes);
29
+ ctrl.close();
30
+ }
31
+ });
32
+ }
33
+ export async function _readStream(stream) {
34
+ const reader = stream.getReader();
35
+ const chunks = [];
36
+ while (true) {
37
+ const { done, value } = await reader.read();
38
+ if (done)
39
+ break;
40
+ chunks.push(value);
41
+ }
42
+ return _concat(chunks);
43
+ }
44
+ export function _hasChunkedEnd(data) {
45
+ if (data.length < 7)
46
+ return false;
47
+ let i = data.length - 7;
48
+ return data[i] === 0x0D && data[i + 1] === 0x0A && data[i + 2] === 0x30 && data[i + 3] === 0x0D && data[i + 4] === 0x0A && data[i + 5] === 0x0D && data[i + 6] === 0x0A;
49
+ }
50
+ export function decodeChunked(data) {
51
+ const chunks = [];
52
+ let pos = 0;
53
+ while (pos < data.length) {
54
+ let crlf = -1;
55
+ for (let i = pos; i < data.length - 1; i++) {
56
+ if (data[i] === 0x0D && data[i + 1] === 0x0A) {
57
+ crlf = i;
58
+ break;
59
+ }
60
+ }
61
+ if (crlf < 0)
62
+ break;
63
+ let size = 0;
64
+ for (let i = pos; i < crlf; i++) {
65
+ const b = data[i];
66
+ if (b >= 0x30 && b <= 0x39)
67
+ size = size * 16 + (b - 0x30);
68
+ else if (b >= 0x41 && b <= 0x46)
69
+ size = size * 16 + (b - 0x37);
70
+ else if (b >= 0x61 && b <= 0x66)
71
+ size = size * 16 + (b - 0x57);
72
+ else
73
+ break;
74
+ }
75
+ const dataStart = crlf + 2;
76
+ if (size === 0) {
77
+ for (let i = dataStart; i < data.length - 3; i++) {
78
+ if (data[i] === 0x0D && data[i + 1] === 0x0A && data[i + 2] === 0x0D && data[i + 3] === 0x0A) {
79
+ pos = i + 4;
80
+ break;
81
+ }
82
+ }
83
+ if (pos === dataStart)
84
+ break;
85
+ break;
86
+ }
87
+ if (dataStart + size > data.length)
88
+ break;
89
+ chunks.push(data.subarray(dataStart, dataStart + size));
90
+ pos = dataStart + size + 2;
91
+ }
92
+ return _concat(chunks);
93
+ }
94
+ // ── Headers ──
95
+ // Flat array storage: [name0, value0, name1, value1, ...]
96
+ // Pairs at even/odd indices. Strings are immutable, so [...this._headers] is a correct deep copy.
97
+ export class HeadersImpl {
98
+ _headers = [];
99
+ constructor(init) {
100
+ if (init) {
101
+ if (init instanceof HeadersImpl) {
102
+ this._headers = [...init._headers];
103
+ }
104
+ else if (Array.isArray(init)) {
105
+ this._headers = init.flatMap(([k, v]) => [k.toLowerCase(), v]);
106
+ }
107
+ else if (typeof init === 'object') {
108
+ this._headers = Object.entries(init).flatMap(([k, v]) => [k.toLowerCase(), v]);
109
+ }
110
+ }
111
+ }
112
+ append(name, value) {
113
+ this._headers.push(name.toLowerCase(), value);
114
+ }
115
+ delete(name) {
116
+ const key = name.toLowerCase();
117
+ const h = this._headers;
118
+ let i = h.length - 2;
119
+ while (i >= 0) {
120
+ if (h[i] === key) {
121
+ h.splice(i, 2);
122
+ i -= 2;
123
+ }
124
+ else
125
+ i -= 2;
126
+ }
127
+ }
128
+ get(name) {
129
+ const key = name.toLowerCase();
130
+ const matches = [...this.entries()].filter(([k]) => k === key).map(([, v]) => v);
131
+ return matches.length ? matches.join(', ') : null;
132
+ }
133
+ has(name) {
134
+ return [...this.keys()].includes(name.toLowerCase());
135
+ }
136
+ set(name, value) {
137
+ const key = name.toLowerCase();
138
+ const h = this._headers;
139
+ let found = false;
140
+ let i = h.length - 2;
141
+ while (i >= 0) {
142
+ if (h[i] === key) {
143
+ if (!found) {
144
+ h[i + 1] = value;
145
+ found = true;
146
+ }
147
+ else {
148
+ h.splice(i, 2);
149
+ }
150
+ }
151
+ i -= 2;
152
+ }
153
+ if (!found)
154
+ h.push(key, value);
155
+ }
156
+ forEach(callback) {
157
+ for (const [name, value] of this) {
158
+ callback(value, name, this);
159
+ }
160
+ }
161
+ *entries() {
162
+ const h = this._headers;
163
+ for (let i = 0; i < h.length; i += 2) {
164
+ yield [h[i], h[i + 1]];
165
+ }
166
+ }
167
+ *keys() {
168
+ for (const [k] of this)
169
+ yield k;
170
+ }
171
+ *values() {
172
+ for (const [, v] of this)
173
+ yield v;
174
+ }
175
+ [Symbol.iterator]() {
176
+ return this.entries();
177
+ }
178
+ }
179
+ // ── Request ──
180
+ export class RequestImpl {
181
+ url;
182
+ method;
183
+ headers;
184
+ _body;
185
+ redirect;
186
+ timeout;
187
+ maxRedirects;
188
+ _bodyConsumed = false;
189
+ integrity = '';
190
+ keepalive = false;
191
+ mode = 'cors';
192
+ cache = 'default';
193
+ credentials = 'same-origin';
194
+ referrer = 'about:client';
195
+ referrerPolicy = '';
196
+ signal = null;
197
+ destination = '';
198
+ get body() { return this._body; }
199
+ get bodyUsed() {
200
+ return this._bodyConsumed || (this._body?.locked ?? false);
201
+ }
202
+ constructor(input, init = {}) {
203
+ const initBody = init.body;
204
+ if (input instanceof RequestImpl) {
205
+ this.url = input.url;
206
+ this.method = init.method || input.method;
207
+ this.headers = new HeadersImpl(init.headers || input.headers);
208
+ if (initBody !== undefined && initBody !== null) {
209
+ this._body = _toReadableStream(initBody);
210
+ }
211
+ else {
212
+ this._body = input._body;
213
+ }
214
+ this.redirect = init.redirect || input.redirect;
215
+ this.timeout = init.timeout || input.timeout;
216
+ this.maxRedirects = init.maxRedirects || input.maxRedirects;
217
+ }
218
+ else {
219
+ this.url = input;
220
+ this.method = init.method || 'GET';
221
+ this.headers = new HeadersImpl(init.headers);
222
+ this._body = initBody !== null && initBody !== undefined ? _toReadableStream(initBody) : null;
223
+ this.redirect = init.redirect || 'follow';
224
+ this.timeout = init.timeout || 30000;
225
+ this.maxRedirects = init.maxRedirects || 5;
226
+ }
227
+ }
228
+ async arrayBuffer() {
229
+ if (!this.body)
230
+ return new ArrayBuffer(0);
231
+ if (this._bodyConsumed)
232
+ throw new TypeError('Body already used');
233
+ this._bodyConsumed = true;
234
+ const bytes = await _readStream(this.body);
235
+ return bytes.buffer;
236
+ }
237
+ async json() {
238
+ return JSON.parse(await this.text());
239
+ }
240
+ async text() {
241
+ if (!this.body)
242
+ return '';
243
+ if (this._bodyConsumed)
244
+ throw new TypeError('Body already used');
245
+ this._bodyConsumed = true;
246
+ const bytes = await _readStream(this.body);
247
+ return new TextDecoder('utf-8').decode(bytes);
248
+ }
249
+ clone() {
250
+ if (this.bodyUsed)
251
+ throw new TypeError('Body already used');
252
+ if (this._body) {
253
+ const [branch1, branch2] = this._body.tee();
254
+ this._body = branch1;
255
+ const req = new RequestImpl(this.url, {
256
+ method: this.method,
257
+ headers: this.headers,
258
+ body: branch2,
259
+ redirect: this.redirect,
260
+ timeout: this.timeout,
261
+ maxRedirects: this.maxRedirects,
262
+ });
263
+ return req;
264
+ }
265
+ return new RequestImpl(this.url, {
266
+ method: this.method,
267
+ headers: this.headers,
268
+ redirect: this.redirect,
269
+ timeout: this.timeout,
270
+ maxRedirects: this.maxRedirects,
271
+ });
272
+ }
273
+ }
274
+ // ── Response ──
275
+ export class ResponseImpl {
276
+ status;
277
+ statusText;
278
+ ok;
279
+ _headers;
280
+ _redirected = false;
281
+ _type = 'basic';
282
+ _url = '';
283
+ _body;
284
+ _bodyConsumed = false;
285
+ get body() { return this._body; }
286
+ get bodyUsed() { return this._bodyConsumed || this._body.locked; }
287
+ get headers() { return this._headers; }
288
+ get redirected() { return this._redirected; }
289
+ get type() { return this._type; }
290
+ get url() { return this._url; }
291
+ constructor(body, init) {
292
+ const status = init?.status ?? 200;
293
+ const statusText = init?.statusText ?? '';
294
+ const headers = new HeadersImpl(init?.headers);
295
+ this.status = status;
296
+ this.statusText = statusText;
297
+ this._headers = headers;
298
+ this.ok = status >= 200 && status < 300;
299
+ this._body = body != null ? _toReadableStream(body) : new ReadableStream({
300
+ start(ctrl) { ctrl.close(); }
301
+ });
302
+ }
303
+ async text() {
304
+ if (this.bodyUsed)
305
+ throw new TypeError('Body already used');
306
+ this._bodyConsumed = true;
307
+ const bytes = await _readStream(this._body);
308
+ return new TextDecoder('utf-8').decode(bytes);
309
+ }
310
+ async json() {
311
+ return JSON.parse(await this.text());
312
+ }
313
+ async arrayBuffer() {
314
+ if (this.bodyUsed)
315
+ throw new TypeError('Body already used');
316
+ this._bodyConsumed = true;
317
+ const bytes = await _readStream(this._body);
318
+ return bytes.buffer;
319
+ }
320
+ async bytes() {
321
+ if (this.bodyUsed)
322
+ throw new TypeError('Body already used');
323
+ this._bodyConsumed = true;
324
+ return await _readStream(this._body);
325
+ }
326
+ clone() {
327
+ if (this.bodyUsed)
328
+ throw new TypeError('Body already used');
329
+ const [branch1, branch2] = this._body.tee();
330
+ this._body = branch1;
331
+ return new ResponseImpl(branch2, { status: this.status, statusText: this.statusText, headers: this._headers });
332
+ }
333
+ _applyDecompressedBody(stream, _body, newHeaders) {
334
+ this._bodyConsumed = false;
335
+ this._body = stream;
336
+ this._headers = newHeaders;
337
+ }
338
+ }
339
+ // ── Register globals ──
340
+ globalThis.Headers = HeadersImpl;
341
+ globalThis.Request = RequestImpl;
342
+ globalThis.Response = ResponseImpl;