quickwin 2026.5.2-3.145209

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 (83) hide show
  1. package/README.md +6 -0
  2. package/examples/pdf_preview.js +440 -0
  3. package/examples/pdf_preview.ts +470 -0
  4. package/examples/preact_demo.js +35 -0
  5. package/examples/preact_demo.tsx +49 -0
  6. package/examples/tray_demo.js +75 -0
  7. package/examples/tray_demo.tsx +79 -0
  8. package/lib/fetch.js +746 -0
  9. package/lib/fetch.ts +811 -0
  10. package/lib/polyfill.js +500 -0
  11. package/lib/polyfill.ts +454 -0
  12. package/lib/preact/hooks.js +287 -0
  13. package/lib/preact/hooks.ts +330 -0
  14. package/lib/preact/jsx-runtime.js +1 -0
  15. package/lib/preact/jsx-runtime.ts +2 -0
  16. package/lib/preact/jsx.d.ts +36 -0
  17. package/lib/preact/layout.js +153 -0
  18. package/lib/preact/layout.ts +183 -0
  19. package/lib/preact/preact.js +54 -0
  20. package/lib/preact/preact.ts +133 -0
  21. package/lib/preact/props.js +99 -0
  22. package/lib/preact/props.ts +119 -0
  23. package/lib/preact/render.js +320 -0
  24. package/lib/preact/render.ts +353 -0
  25. package/lib/websocket.js +540 -0
  26. package/lib/websocket.ts +574 -0
  27. package/package.json +32 -0
  28. package/quickwin.d.ts +657 -0
  29. package/test/add.wasm +0 -0
  30. package/test/complex.wasm +0 -0
  31. package/test/complex_imports.wasm +0 -0
  32. package/test/global_imports.wasm +0 -0
  33. package/test/import_func.wasm +0 -0
  34. package/test/imports.wasm +0 -0
  35. package/test/run.js +86 -0
  36. package/test/run.ts +90 -0
  37. package/test/sjlj.wasm +0 -0
  38. package/test/test_basic.js +7 -0
  39. package/test/test_basic.ts +9 -0
  40. package/test/test_brotli.js +48 -0
  41. package/test/test_brotli.ts +52 -0
  42. package/test/test_fetch_cache.js +131 -0
  43. package/test/test_fetch_cache.ts +141 -0
  44. package/test/test_ffi.js +157 -0
  45. package/test/test_ffi.ts +174 -0
  46. package/test/test_frame_encoding.js +128 -0
  47. package/test/test_frame_encoding.ts +132 -0
  48. package/test/test_helper.js +84 -0
  49. package/test/test_helper.ts +80 -0
  50. package/test/test_http_import.js +78 -0
  51. package/test/test_http_import.ts +74 -0
  52. package/test/test_mupdf_render.js +69 -0
  53. package/test/test_mupdf_render.ts +74 -0
  54. package/test/test_mupdf_twice.js +77 -0
  55. package/test/test_mupdf_twice.ts +81 -0
  56. package/test/test_mupdf_wasm.js +33 -0
  57. package/test/test_mupdf_wasm.ts +30 -0
  58. package/test/test_net_event.js +63 -0
  59. package/test/test_net_event.ts +59 -0
  60. package/test/test_net_fetch.js +153 -0
  61. package/test/test_net_fetch.ts +131 -0
  62. package/test/test_net_websocket.js +158 -0
  63. package/test/test_net_websocket.ts +144 -0
  64. package/test/test_polyfill.js +58 -0
  65. package/test/test_polyfill.ts +60 -0
  66. package/test/test_url.js +173 -0
  67. package/test/test_url.ts +183 -0
  68. package/test/test_wasm_basic.js +82 -0
  69. package/test/test_wasm_basic.ts +70 -0
  70. package/test/test_wasm_import_global.js +41 -0
  71. package/test/test_wasm_import_global.ts +39 -0
  72. package/test/test_wasm_sjlj.js +153 -0
  73. package/test/test_wasm_sjlj.ts +134 -0
  74. package/test/test_wasm_types.js +96 -0
  75. package/test/test_wasm_types.ts +108 -0
  76. package/test/types.wasm +0 -0
  77. package/tsconfig.json +18 -0
  78. package/vendor/mupdf-wasm/mupdf-wasm.d.ts +571 -0
  79. package/vendor/mupdf-wasm/mupdf-wasm.js +2749 -0
  80. package/vendor/mupdf-wasm/mupdf-wasm.wasm +0 -0
  81. package/vendor/mupdf-wasm/mupdf.d.ts +939 -0
  82. package/vendor/mupdf-wasm/mupdf.js +3317 -0
  83. package/win-mingw64.exe +0 -0
@@ -0,0 +1,119 @@
1
+ import * as gui from 'gui'
2
+ import * as ffi from 'ffi'
3
+ import * as win from 'win'
4
+
5
+ const FFI_PTR = ffi.FFI_TYPE_POINTER
6
+ const FFI_S32 = ffi.FFI_TYPE_SINT32
7
+ const FFI_U32 = ffi.FFI_TYPE_UINT32
8
+ const FFI_U64 = ffi.FFI_TYPE_UINT64
9
+
10
+ const _user32 = win.LoadLibrary('user32.dll')
11
+
12
+ const MoveWindow_proc = _user32 ? win.GetProcAddress(_user32, 'MoveWindow') : 0
13
+ const EnableWindow_proc = _user32 ? win.GetProcAddress(_user32, 'EnableWindow') : 0
14
+ const ShowWindow_proc = _user32 ? win.GetProcAddress(_user32, 'ShowWindow') : 0
15
+ const SendMessageW_proc = _user32 ? win.GetProcAddress(_user32, 'SendMessageW') : 0
16
+ const DestroyWindow_proc = _user32 ? win.GetProcAddress(_user32, 'DestroyWindow') : 0
17
+
18
+ const SW_HIDE = gui.ShowWindowCmd.HIDE
19
+ const SW_SHOW = gui.ShowWindowCmd.SHOW
20
+
21
+ const BM_GETCHECK = gui.ButtonMsg.GETCHECK
22
+ const BM_SETCHECK = gui.ButtonMsg.SETCHECK
23
+ const BST_CHECKED = gui.ButtonCheckState.CHECKED
24
+ const BST_UNCHECKED = gui.ButtonCheckState.UNCHECKED
25
+ const EM_SETCUEBANNER = gui.EditMsg.SETCUEBANNER
26
+ const EM_SETPASSWORDCHAR = gui.EditMsg.SETPASSWORDCHAR
27
+ const CB_ADDSTRING = gui.ComboBoxMsg.ADDSTRING
28
+ const LB_ADDSTRING = gui.LbMsg.ADDSTRING
29
+ const PBM_SETRANGE32 = gui.ProgressMsg.SETRANGE32
30
+ const PBM_SETPOS = gui.ProgressMsg.SETPOS
31
+
32
+ export interface WProps {
33
+ type?: string
34
+ text?: string
35
+ value?: string
36
+ disabled?: boolean
37
+ visible?: boolean
38
+ style?: Record<string, any>
39
+ onEvent?: (e: Record<string, any>) => void
40
+ placeholder?: string
41
+ password?: boolean
42
+ checked?: boolean
43
+ items?: string[]
44
+ max?: number
45
+ children?: any
46
+ }
47
+
48
+ export function applyProps(hwnd: number, props: WProps, vnode?: Record<string, any>): void {
49
+ if (props.text !== undefined) {
50
+ gui.SetWindowText(hwnd as gui.HWND, props.text)
51
+ }
52
+ if (props.value !== undefined) {
53
+ gui.SetWindowText(hwnd as gui.HWND, props.value)
54
+ }
55
+ if (props.disabled !== undefined && EnableWindow_proc) {
56
+ ffi.ffiCall(EnableWindow_proc, [FFI_U64, FFI_U32] as const, [hwnd, props.disabled ? 0 : 1], FFI_U32)
57
+ }
58
+ if (props.visible !== undefined && ShowWindow_proc) {
59
+ ffi.ffiCall(ShowWindow_proc, [FFI_U64, FFI_S32] as const, [hwnd, props.visible ? SW_SHOW : SW_HIDE], FFI_U32)
60
+ }
61
+ if (props.onEvent !== undefined && vnode) {
62
+ const h = hwnd as unknown as gui.HWND
63
+ const oldProc = vnode._oldProc || gui.GetWindowLongPtr(h, gui.Gwlp.WNDPROC)
64
+ vnode._oldProc = oldProc
65
+ gui.SetWindowProc(h, (hw, msg, wParam, lParam) => {
66
+ const cb = vnode!.props?.onEvent
67
+ if (cb) cb({ hwnd: hw as unknown as number, msg, wParam, lParam })
68
+ return gui.CallWindowProc(oldProc as unknown as gui.WNDPROC, hw, msg, wParam, lParam)
69
+ })
70
+ }
71
+ if (props.placeholder !== undefined && SendMessageW_proc) {
72
+ ffi.ffiCall(SendMessageW_proc, [FFI_U64, FFI_S32, FFI_U32, FFI_PTR] as const, [hwnd, EM_SETCUEBANNER, 0, strToWide(props.placeholder)], FFI_U64)
73
+ }
74
+ if (props.password !== undefined && SendMessageW_proc) {
75
+ ffi.ffiCall(SendMessageW_proc, [FFI_U64, FFI_U64, FFI_U64, FFI_U64] as const, [hwnd, EM_SETPASSWORDCHAR, props.password ? 42 : 0, 0], FFI_U64)
76
+ }
77
+ if (props.checked !== undefined && SendMessageW_proc) {
78
+ ffi.ffiCall(SendMessageW_proc, [FFI_U64, FFI_U64, FFI_U64, FFI_U64] as const, [hwnd, BM_SETCHECK, props.checked ? BST_CHECKED : BST_UNCHECKED, 0], FFI_U64)
79
+ }
80
+ if (props.items && SendMessageW_proc) {
81
+ const msg = props.type === 'combobox' ? CB_ADDSTRING : LB_ADDSTRING
82
+ for (const item of props.items) {
83
+ ffi.ffiCall(SendMessageW_proc, [FFI_U64, FFI_S32, FFI_U32, FFI_PTR] as const, [hwnd, msg, 0, strToWide(item)], FFI_U64)
84
+ }
85
+ }
86
+ if (props.max !== undefined && SendMessageW_proc) {
87
+ ffi.ffiCall(SendMessageW_proc, [FFI_U64, FFI_U64, FFI_U64, FFI_U64] as const, [hwnd, PBM_SETRANGE32, 0, props.max], FFI_U64)
88
+ }
89
+ if (props.value !== undefined && props.type === 'progressbar' && SendMessageW_proc) {
90
+ ffi.ffiCall(SendMessageW_proc, [FFI_U64, FFI_U64, FFI_U64, FFI_U64] as const, [hwnd, PBM_SETPOS, Number(props.value), 0], FFI_U64)
91
+ }
92
+ }
93
+
94
+ const wideCache = new Map<string, ArrayBuffer>()
95
+ const MAX_WIDE_CACHE = 50
96
+
97
+ function strToWide(str: string): ArrayBuffer {
98
+ const cached = wideCache.get(str)
99
+ if (cached) return cached
100
+ const buf = new ArrayBuffer((str.length + 1) * 2)
101
+ const dv = new DataView(buf)
102
+ for (let i = 0; i < str.length; i++) dv.setUint16(i * 2, str.charCodeAt(i), true)
103
+ if (wideCache.size >= MAX_WIDE_CACHE) {
104
+ const key = wideCache.keys().next().value
105
+ if (key !== undefined) wideCache.delete(key)
106
+ }
107
+ wideCache.set(str, buf)
108
+ return buf
109
+ }
110
+
111
+ export function moveWindow(hwnd: number, x: number, y: number, w: number, h: number): void {
112
+ if (!MoveWindow_proc) return
113
+ ffi.ffiCall(MoveWindow_proc, [FFI_U64, FFI_S32, FFI_S32, FFI_S32, FFI_S32, FFI_U32] as const, [hwnd, x, y, w, h, 1], FFI_U32)
114
+ }
115
+
116
+ export function destroyWindow(hwnd: number): boolean {
117
+ if (!DestroyWindow_proc) return false
118
+ return !!ffi.ffiCall(DestroyWindow_proc, [FFI_U64] as const, [hwnd], FFI_U32)
119
+ }
@@ -0,0 +1,320 @@
1
+ import '../polyfill.js';
2
+ import * as gui from 'gui';
3
+ import * as os from 'os';
4
+ import { applyProps, destroyWindow } from './props.js';
5
+ import { layout as doLayout } from './layout.js';
6
+ import { options } from './preact.js';
7
+ const scaleFactor = gui.GetScaleFactor();
8
+ const dpiFont = gui.CreateSystemDpiFont();
9
+ const HWND_PROP = '__qw_hwnd';
10
+ const STYLE_PROP = '__qw_style';
11
+ const CHILDREN_HWNDS_PROP = '__qw_children';
12
+ const RENDERED_VNODE_PROP = '__qw_rendered';
13
+ let rootHwnd = null;
14
+ let rootVNode = null;
15
+ const WIN32_CLASS = {
16
+ button: 'BUTTON', edit: 'EDIT', static: 'STATIC',
17
+ checkbox: 'BUTTON', groupbox: 'BUTTON', combobox: 'COMBOBOX',
18
+ listbox: 'LISTBOX', progressbar: 'msctls_progress32',
19
+ };
20
+ const WIN32_STYLE = {
21
+ button: 0 /* gui.ButtonStyle.PUSHBUTTON */,
22
+ edit: 8388608 /* gui.WindowStyle.BORDER */ | 128 /* gui.EditStyle.AUTOHSCROLL */,
23
+ static: 0 /* gui.StaticStyle.LEFT */,
24
+ checkbox: 3 /* gui.ButtonStyle.AUTOCHECKBOX */,
25
+ groupbox: 7 /* gui.ButtonStyle.GROUPBOX */,
26
+ combobox: 3 /* gui.ComboBoxStyle.DROPDOWNLIST */,
27
+ listbox: 1 /* gui.ListBoxStyle.NOTIFY */ | 2097152 /* gui.WindowStyle.VSCROLL */,
28
+ progressbar: 0,
29
+ };
30
+ function createControl(type, parentHwnd, vnode) {
31
+ const base = 1073741824 /* gui.WindowStyle.CHILD */ | 268435456 /* gui.WindowStyle.VISIBLE */;
32
+ const winClass = WIN32_CLASS[type] || 'STATIC';
33
+ const style = base | (WIN32_STYLE[type] ?? 0 /* gui.StaticStyle.LEFT */);
34
+ const text = (vnode.props?.text || vnode.props?.value || '');
35
+ const hwnd = gui.CreateWindow(winClass, text, style, 0, 0, 0, 0, parentHwnd, null);
36
+ if (!hwnd)
37
+ return 0;
38
+ gui.SendMessage(hwnd, 48 /* gui.WmMsg.SETFONT */, dpiFont, 1);
39
+ applyProps(hwnd, vnode.props || {}, vnode);
40
+ return hwnd;
41
+ }
42
+ function isVNode(val) {
43
+ return val != null && typeof val === 'object' && val.constructor === undefined && val.type !== undefined;
44
+ }
45
+ function getChildren(vnode) {
46
+ const children = vnode.props?.children;
47
+ if (children == null)
48
+ return [];
49
+ if (Array.isArray(children))
50
+ return children.filter((c) => c != null && c !== false && c !== true);
51
+ if (typeof children === 'object' && children.type !== undefined)
52
+ return [children];
53
+ return [];
54
+ }
55
+ function renderToWin32(vnode, parentHwnd, context) {
56
+ if (vnode == null || vnode === false || vnode === true)
57
+ return 0;
58
+ if (typeof vnode === 'string' || typeof vnode === 'number') {
59
+ const hwnd = gui.CreateWindow('STATIC', String(vnode), 1073741824 /* gui.WindowStyle.CHILD */ | 268435456 /* gui.WindowStyle.VISIBLE */ | 0 /* gui.StaticStyle.LEFT */, 0, 0, 0, 0, parentHwnd, null);
60
+ if (hwnd)
61
+ gui.SendMessage(hwnd, 48 /* gui.WmMsg.SETFONT */, dpiFont, 1);
62
+ return hwnd;
63
+ }
64
+ if (Array.isArray(vnode)) {
65
+ for (const child of vnode)
66
+ renderToWin32(child, parentHwnd, context);
67
+ return 0;
68
+ }
69
+ if (!isVNode(vnode))
70
+ return 0;
71
+ if (typeof vnode.type === 'function') {
72
+ return renderComponent(vnode, parentHwnd, context);
73
+ }
74
+ if (vnode.type === 'w') {
75
+ const ctrlType = vnode.props?.type || '';
76
+ let hwnd;
77
+ if (ctrlType) {
78
+ hwnd = createControl(ctrlType, parentHwnd, vnode);
79
+ }
80
+ else {
81
+ hwnd = gui.CreateWindow('STATIC', '', 1073741824 /* gui.WindowStyle.CHILD */ | 268435456 /* gui.WindowStyle.VISIBLE */, 0, 0, 0, 0, parentHwnd, null);
82
+ if (hwnd) {
83
+ gui.SendMessage(hwnd, 48 /* gui.WmMsg.SETFONT */, dpiFont, 1);
84
+ applyProps(hwnd, vnode.props || {}, vnode);
85
+ }
86
+ }
87
+ if (!hwnd)
88
+ return 0;
89
+ vnode[HWND_PROP] = hwnd;
90
+ vnode[STYLE_PROP] = vnode.props?.style ?? {};
91
+ const children = getChildren(vnode);
92
+ const childHwnds = [];
93
+ for (const child of children) {
94
+ const childHwnd = renderToWin32(child, hwnd, context);
95
+ if (childHwnd)
96
+ childHwnds.push(childHwnd);
97
+ }
98
+ vnode[CHILDREN_HWNDS_PROP] = childHwnds;
99
+ return hwnd;
100
+ }
101
+ return 0;
102
+ }
103
+ function invokeComponent(component, vnode) {
104
+ options._diff?.(vnode);
105
+ options._render?.(vnode);
106
+ try {
107
+ const fn = vnode.type;
108
+ return fn.call(component, component.props, component.context);
109
+ }
110
+ catch (e) {
111
+ const errHandler = component._errorHandler;
112
+ if (errHandler) {
113
+ errHandler(e);
114
+ return null;
115
+ }
116
+ console.log('[preact-render] render threw: ' + e);
117
+ return null;
118
+ }
119
+ finally {
120
+ options.diffed?.(vnode);
121
+ }
122
+ }
123
+ function renderComponent(vnode, parentHwnd, context) {
124
+ const rendered = invokeComponent(newComponent(vnode, parentHwnd, context), vnode);
125
+ if (rendered == null)
126
+ return 0;
127
+ const resultHwnd = renderToWin32(rendered, parentHwnd, context);
128
+ vnode[HWND_PROP] = resultHwnd;
129
+ vnode[RENDERED_VNODE_PROP] = rendered;
130
+ return resultHwnd;
131
+ }
132
+ function newComponent(vnode, parentHwnd, context) {
133
+ const component = {
134
+ _vnode: vnode,
135
+ props: vnode.props,
136
+ context,
137
+ __hooks: { _list: [], _pendingEffects: [] },
138
+ _renderCallbacks: [],
139
+ _parentDom: true,
140
+ _qw_parent_hwnd: parentHwnd,
141
+ _dirty: false,
142
+ _forceUpdate() {
143
+ component._dirty = true;
144
+ scheduleUpdate(component);
145
+ },
146
+ };
147
+ vnode._component = component;
148
+ return component;
149
+ }
150
+ function destroyHwnd(hwnd) {
151
+ if (!hwnd)
152
+ return;
153
+ gui.RemoveWindow(hwnd);
154
+ destroyWindow(hwnd);
155
+ }
156
+ function destroyVNode(vnode) {
157
+ options.unmount?.(vnode);
158
+ const hwnd = vnode[HWND_PROP];
159
+ if (hwnd)
160
+ destroyHwnd(hwnd);
161
+ vnode[HWND_PROP] = 0;
162
+ for (const child of getChildren(vnode)) {
163
+ if (isVNode(child))
164
+ destroyVNode(child);
165
+ }
166
+ const extra = vnode[CHILDREN_HWNDS_PROP];
167
+ if (extra) {
168
+ for (const h of extra)
169
+ destroyHwnd(h);
170
+ }
171
+ vnode[CHILDREN_HWNDS_PROP] = [];
172
+ }
173
+ function reconcile(oldVNode, newVNode, parentHwnd, context) {
174
+ if (oldVNode == null || oldVNode === false || oldVNode === true) {
175
+ return renderToWin32(newVNode, parentHwnd, context);
176
+ }
177
+ if (newVNode == null || newVNode === false || newVNode === true) {
178
+ if (isVNode(oldVNode))
179
+ destroyVNode(oldVNode);
180
+ return 0;
181
+ }
182
+ if (typeof oldVNode !== typeof newVNode ||
183
+ typeof oldVNode === 'string' || typeof oldVNode === 'number' ||
184
+ Array.isArray(oldVNode) || Array.isArray(newVNode)) {
185
+ if (isVNode(oldVNode))
186
+ destroyVNode(oldVNode);
187
+ return renderToWin32(newVNode, parentHwnd, context);
188
+ }
189
+ if (!isVNode(oldVNode) || !isVNode(newVNode)) {
190
+ return renderToWin32(newVNode, parentHwnd, context);
191
+ }
192
+ const o = oldVNode;
193
+ const n = newVNode;
194
+ if (typeof n.type === 'function') {
195
+ const oldComp = o._component;
196
+ let comp;
197
+ if (oldComp) {
198
+ oldComp._vnode = n;
199
+ oldComp.props = n.props;
200
+ oldComp._qw_parent_hwnd = parentHwnd;
201
+ comp = oldComp;
202
+ }
203
+ else {
204
+ comp = newComponent(n, parentHwnd, context);
205
+ }
206
+ n._component = comp;
207
+ const oldResult = o[RENDERED_VNODE_PROP];
208
+ const newResult = invokeComponent(comp, n);
209
+ let resultHwnd;
210
+ if (newResult != null) {
211
+ resultHwnd = reconcile(oldResult || null, newResult, parentHwnd, context);
212
+ }
213
+ else {
214
+ if (oldResult && isVNode(oldResult))
215
+ destroyVNode(oldResult);
216
+ resultHwnd = 0;
217
+ }
218
+ n[HWND_PROP] = resultHwnd;
219
+ n[RENDERED_VNODE_PROP] = newResult;
220
+ return resultHwnd;
221
+ }
222
+ if (o.type === 'w' && n.type === 'w') {
223
+ const oldCtrl = o.props?.type || '';
224
+ const newCtrl = n.props?.type || '';
225
+ if (oldCtrl === newCtrl) {
226
+ const hwnd = o[HWND_PROP];
227
+ if (hwnd) {
228
+ n[HWND_PROP] = hwnd;
229
+ n[STYLE_PROP] = n.props?.style ?? {};
230
+ n._oldProc = o._oldProc;
231
+ applyProps(hwnd, n.props || {}, n);
232
+ const oldChildren = getChildren(o);
233
+ const newChildren = getChildren(n);
234
+ const oldChildHwnds = o[CHILDREN_HWNDS_PROP];
235
+ const childHwnds = [];
236
+ const maxLen = Math.max(oldChildren.length, newChildren.length);
237
+ for (let i = 0; i < maxLen; i++) {
238
+ const oc = oldChildren[i];
239
+ const nc = newChildren[i];
240
+ if (oc != null && oc !== false && oc !== true) {
241
+ if (nc != null && nc !== false && nc !== true) {
242
+ if (typeof oc === 'string' && typeof nc === 'string') {
243
+ if (oc !== nc && oldChildHwnds && oldChildHwnds[i]) {
244
+ applyProps(oldChildHwnds[i], { text: nc });
245
+ }
246
+ if (oldChildHwnds && oldChildHwnds[i])
247
+ childHwnds.push(oldChildHwnds[i]);
248
+ }
249
+ else {
250
+ const ch = reconcile(oc, nc, hwnd, context);
251
+ if (ch)
252
+ childHwnds.push(ch);
253
+ }
254
+ }
255
+ else {
256
+ if (isVNode(oc))
257
+ destroyVNode(oc);
258
+ else if (oldChildHwnds && oldChildHwnds[i])
259
+ destroyHwnd(oldChildHwnds[i]);
260
+ }
261
+ }
262
+ else if (nc != null && nc !== false && nc !== true) {
263
+ const ch = renderToWin32(nc, hwnd, context);
264
+ if (ch)
265
+ childHwnds.push(ch);
266
+ }
267
+ }
268
+ n[CHILDREN_HWNDS_PROP] = childHwnds;
269
+ return hwnd;
270
+ }
271
+ }
272
+ }
273
+ destroyVNode(o);
274
+ return renderToWin32(n, parentHwnd, context);
275
+ }
276
+ function scheduleUpdate(component) {
277
+ if (!component._dirty)
278
+ return;
279
+ os.setTimeout(() => {
280
+ if (!component._dirty)
281
+ return;
282
+ component._dirty = false;
283
+ const vnode = component._vnode;
284
+ const parentHwnd = component._qw_parent_hwnd;
285
+ if (!parentHwnd)
286
+ return;
287
+ const oldRendered = vnode[RENDERED_VNODE_PROP];
288
+ const rendered = invokeComponent(component, vnode);
289
+ if (rendered != null) {
290
+ reconcile(oldRendered || null, rendered, parentHwnd, component.context);
291
+ }
292
+ else if (oldRendered) {
293
+ if (isVNode(oldRendered))
294
+ destroyVNode(oldRendered);
295
+ }
296
+ vnode[RENDERED_VNODE_PROP] = rendered;
297
+ const commitQueue = [component];
298
+ options._commit?.(vnode, commitQueue);
299
+ if (rootHwnd && rootVNode) {
300
+ doLayout(rootHwnd, rootVNode);
301
+ }
302
+ }, 0);
303
+ }
304
+ export function notifyResize(hwnd) {
305
+ if (rootVNode)
306
+ doLayout(hwnd, rootVNode);
307
+ }
308
+ export function render(vnode, containerHwnd) {
309
+ rootHwnd = containerHwnd;
310
+ rootVNode = vnode;
311
+ renderToWin32(vnode, containerHwnd, {});
312
+ if (vnode._component) {
313
+ const commitQueue = [vnode._component];
314
+ options._commit?.(vnode, commitQueue);
315
+ }
316
+ doLayout(containerHwnd, vnode);
317
+ return containerHwnd;
318
+ }
319
+ export { HWND_PROP, STYLE_PROP, CHILDREN_HWNDS_PROP, RENDERED_VNODE_PROP, isVNode, getChildren };
320
+ export { scaleFactor };