quickwin 2.3.1 → 3.0.1
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 +1 -2
- package/README.md +1 -2
- package/constants.ts +15 -0
- package/enum_map.d.ts +3 -0
- package/examples/PdfCanvas.js +1 -1
- package/examples/PdfCanvas.tsx +2 -2
- package/examples/execd/main.js +334 -188
- package/examples/pdf_preview2.js +76 -67
- package/examples/pdf_preview2.ts +84 -64
- package/examples/pdf_viewer.js +4932 -1029
- package/examples/pdf_viewer.tsx +11 -22
- package/examples/test_gallery.js +308 -143
- package/examples/test_gallery.tsx +12 -7
- package/examples/test_react_lazy.js +295 -133
- package/examples/test_react_lazy.tsx +4 -3
- package/examples/test_react_listbox.js +293 -132
- package/examples/test_react_listbox.tsx +3 -2
- package/examples/test_root_window.js +283 -126
- package/examples/test_tab.js +295 -133
- package/examples/test_tab.tsx +4 -3
- package/examples/tray_demo.js +37 -30
- package/examples/tray_demo.tsx +39 -32
- package/lib/abort.d.ts +21 -0
- package/lib/assert.d.ts +2 -0
- package/lib/bitmap.d.ts +7 -0
- package/lib/bitmap.js +40 -0
- package/lib/cache-utils.d.ts +6 -0
- package/lib/certs.d.ts +1 -0
- package/lib/certs.js +31 -3
- package/lib/dpi.d.ts +9 -0
- package/lib/dpi.js +30 -0
- package/lib/dumpRects.d.ts +2 -0
- package/lib/dumpRects.js +14 -7
- package/lib/exec-log.d.ts +23 -0
- package/lib/fetch.d.ts +4 -0
- package/lib/ffi/bind.d.ts +70 -0
- package/lib/ffi/bind.js +5 -4
- package/lib/ffi/ctype.d.ts +117 -0
- package/lib/ffi/index.d.ts +2 -0
- package/lib/ffi/struct.d.ts +174 -0
- package/lib/http-common.d.ts +143 -0
- package/lib/http-server.d.ts +59 -0
- package/lib/polyfill.d.ts +22 -0
- package/lib/react-qw/components/Button.d.ts +9 -0
- package/lib/react-qw/components/CheckBox.d.ts +11 -0
- package/lib/react-qw/components/ComboBox.d.ts +11 -0
- package/lib/react-qw/components/DateTimePicker.d.ts +15 -0
- package/lib/react-qw/components/DateTimePicker.js +6 -7
- package/lib/react-qw/components/Input.d.ts +15 -0
- package/lib/react-qw/components/Input.js +5 -1
- package/lib/react-qw/components/Link.d.ts +12 -0
- package/lib/react-qw/components/ListBox.d.ts +13 -0
- package/lib/react-qw/components/ListView.d.ts +37 -0
- package/lib/react-qw/components/ListView.js +8 -6
- package/lib/react-qw/components/PathPicker.d.ts +23 -0
- package/lib/react-qw/components/ProgressBar.d.ts +9 -0
- package/lib/react-qw/components/RadioButton.d.ts +11 -0
- package/lib/react-qw/components/ScrollView.d.ts +9 -0
- package/lib/react-qw/components/ScrollView.js +28 -22
- package/lib/react-qw/components/Slider.d.ts +12 -0
- package/lib/react-qw/components/Tab.d.ts +14 -0
- package/lib/react-qw/components/Tooltip.d.ts +7 -0
- package/lib/react-qw/components/TreeView.d.ts +18 -0
- package/lib/react-qw/components/index.d.ts +16 -0
- package/lib/react-qw/index.d.ts +24 -0
- package/lib/react-qw/index.js +7 -5
- package/lib/react-qw/layout.d.ts +29 -0
- package/lib/react-qw/nmhdr.d.ts +1 -0
- package/lib/react-qw/props.d.ts +2 -0
- package/lib/react-qw/props.js +3 -3
- package/lib/react-qw/reconciler.d.ts +21 -0
- package/lib/react-qw/reconciler.js +12 -17
- package/lib/stream.d.ts +20 -0
- package/lib/text-codec.d.ts +39 -0
- package/lib/text-measure.d.ts +14 -0
- package/lib/text-measure.js +9 -6
- package/lib/url.d.ts +54 -0
- package/lib/websocket.d.ts +73 -0
- package/lib/windows/{advapi32.ts → advapi32.d.ts} +6 -21
- package/lib/windows/comctl32.d.ts +14 -0
- package/lib/windows/comctl32.js +3 -2
- package/lib/windows/comdlg32.d.ts +4 -0
- package/lib/windows/{gdi32.ts → gdi32.d.ts} +184 -97
- package/lib/windows/gdi32.js +28 -6
- package/lib/windows/{kernel32.ts → kernel32.d.ts} +145 -113
- package/lib/windows/kernel32.js +9 -0
- package/lib/windows/{msimg32.ts → msimg32.d.ts} +11 -14
- package/lib/windows/ntdll.d.ts +5 -0
- package/lib/windows/ole32.d.ts +3 -0
- package/lib/windows/{psapi.ts → psapi.d.ts} +9 -18
- package/lib/windows/shell32.d.ts +51 -0
- package/lib/windows/shell32.js +11 -2
- package/lib/windows/structs.d.ts +3141 -0
- package/lib/windows/structs.js +51 -0
- package/lib/windows/user32.d.ts +623 -0
- package/lib/windows/user32.js +6 -5
- package/lib/windows/version.d.ts +27 -0
- package/lib/windows/{winspool.ts → winspool.d.ts} +18 -32
- package/main.js +13 -5
- package/package.json +16 -7
- package/quickwin.d.ts +13 -115
- package/qwin-nowasm-x86.exe +0 -0
- package/qwin-nowasm.exe +0 -0
- package/qwin-x86.exe +0 -0
- package/qwin.exe +0 -0
- package/test/bench_ffi_callraw.js +3 -4
- package/test/bench_ffi_callraw.ts +3 -4
- package/test/debug/mupdf_debug.js +4 -22
- package/test/debug/wasm_export_debug.js +2 -12
- package/test/debug/wasm_names.js +3 -13
- package/test/example.pdf +0 -0
- package/test/mupdf-cdn.js +40 -0
- package/test/mupdf-cdn.ts +43 -0
- package/test/test_ffi.js +8 -9
- package/test/test_ffi.ts +8 -9
- package/test/test_ffi_abi.js +6 -6
- package/test/test_ffi_abi.ts +8 -8
- package/test/test_ffi_windows.js +82 -11
- package/test/test_ffi_windows.ts +85 -11
- package/test/test_gdi_draw.js +3 -3
- package/test/test_gdi_draw.ts +4 -4
- package/test/test_mupdf_render.js +4 -22
- package/test/test_mupdf_render.ts +4 -23
- package/test/test_mupdf_twice.js +4 -19
- package/test/test_mupdf_twice.ts +4 -20
- package/test/test_mupdf_wasm.js +10 -4
- package/test/test_mupdf_wasm.ts +6 -4
- package/test/test_react_complex.js +316 -140
- package/test/test_react_counter.js +295 -133
- package/test/test_react_flex.js +297 -138
- package/test/test_react_hidden.js +296 -134
- package/test/test_react_listview_link.js +288 -131
- package/test/test_react_notify.js +290 -133
- package/test/test_react_render.js +295 -133
- package/lib/abort.ts +0 -69
- package/lib/assert.ts +0 -7
- package/lib/cache-utils.ts +0 -40
- package/lib/certs.ts +0 -229
- package/lib/dumpRects.ts +0 -26
- package/lib/exec-log.ts +0 -30
- package/lib/fetch.ts +0 -589
- package/lib/ffi/bind.ts +0 -539
- package/lib/ffi/ctype.ts +0 -371
- package/lib/ffi/index.ts +0 -6
- package/lib/ffi/struct.ts +0 -780
- package/lib/http-common.ts +0 -441
- package/lib/http-server.ts +0 -604
- package/lib/polyfill.ts +0 -171
- package/lib/react-qw/components/index.ts +0 -17
- package/lib/react-qw/index.ts +0 -96
- package/lib/react-qw/layout.ts +0 -111
- package/lib/react-qw/nmhdr.ts +0 -7
- package/lib/react-qw/props.ts +0 -41
- package/lib/react-qw/reconciler.ts +0 -383
- package/lib/stream.ts +0 -22
- package/lib/text-codec.ts +0 -171
- package/lib/text-measure.ts +0 -41
- package/lib/url.ts +0 -201
- package/lib/websocket.ts +0 -600
- package/lib/windows/comctl32.ts +0 -19
- package/lib/windows/comdlg32.ts +0 -10
- package/lib/windows/ntdll.ts +0 -11
- package/lib/windows/ole32.ts +0 -9
- package/lib/windows/shell32.ts +0 -39
- package/lib/windows/structs.ts +0 -752
- package/lib/windows/user32.ts +0 -619
- package/lib/windows/version.ts +0 -35
- package/vendor/mupdf-wasm/mupdf-wasm.d.ts +0 -571
- package/vendor/mupdf-wasm/mupdf-wasm.js +0 -2749
- package/vendor/mupdf-wasm/mupdf-wasm.wasm +0 -0
- package/vendor/mupdf-wasm/mupdf.d.ts +0 -939
- package/vendor/mupdf-wasm/mupdf.js +0 -3317
package/lib/windows/user32.js
CHANGED
|
@@ -495,10 +495,10 @@ export const GetSubMenu = /*@__PURE__*/ b('GetSubMenu', '<HMENU>ptr i32 -> <HMEN
|
|
|
495
495
|
* @param args_1 uFlags TPM_* 标志
|
|
496
496
|
* @param args_2 x 屏幕 x
|
|
497
497
|
* @param args_3 y 屏幕 y
|
|
498
|
-
* @param args_4 nReserved 保留,传 0
|
|
499
|
-
* @param args_5
|
|
500
|
-
* @param args_6
|
|
501
|
-
export const TrackPopupMenu = /*@__PURE__*/ b('TrackPopupMenu', '<HMENU>ptr u32 i32 i32 i32 <
|
|
498
|
+
* @param args_4 nReserved 保留,传 0(TrackPopupMenuEx 才用)
|
|
499
|
+
* @param args_5 hWnd 拥有者窗口(TPM_RETURNCMD 时命令 ID 回到该窗口所属线程队列)
|
|
500
|
+
* @param args_6 prcRect 保留位,传 NULL(Win32 文档标注本 API 忽略此参数) */
|
|
501
|
+
export const TrackPopupMenu = /*@__PURE__*/ b('TrackPopupMenu', '<HMENU>ptr u32 i32 i32 i32 <HWND>ptr <RECT>ptr -> i32', { RECT });
|
|
502
502
|
/** 创建弹出菜单;配对 DestroyMenu
|
|
503
503
|
* @returns 菜单句柄;失败 → NULL */
|
|
504
504
|
export const CreatePopupMenu = /*@__PURE__*/ b('CreatePopupMenu', ' -> <HMENU>ptr');
|
|
@@ -534,7 +534,8 @@ export const MessageBox = /*@__PURE__*/ b('MessageBoxW', '<HWND>ptr <WCHAR>ptr <
|
|
|
534
534
|
// ============ 图像 ============
|
|
535
535
|
/** 按名加载图像(string 自动编码;uType/fuLoad 用 Win32 真值——与 ImageType 枚举当前值
|
|
536
536
|
* 不同)
|
|
537
|
-
* @returns
|
|
537
|
+
* @returns 图像句柄——类型随 uType(IMAGE_ICON→HICON / CURSOR→HCURSOR / BITMAP→HBITMAP),
|
|
538
|
+
* 绑定侧给不出品牌故为裸地址档;失败 → 0
|
|
538
539
|
* @param args_0 hinst 模块句柄,NULL = 系统资源或 .ico 文件
|
|
539
540
|
* @param args_1 name 图像名 string(资源名或文件路径)
|
|
540
541
|
* @param args_2 uType IMAGE_* 真值(BITMAP=0/CURSOR=1/ICON=2)
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/** 取文件版本资源大小
|
|
2
|
+
* @returns 字节数(0 = 文件无版本资源)
|
|
3
|
+
* @param args_0 lptstrFilename 文件路径(禁空)
|
|
4
|
+
* @param args_1 lpdwHandle 出参槽(Info 步的入参句柄,MSDN 恒 0 但仍须传),
|
|
5
|
+
* PtrArrayBuffer(4) + Uint32Array 读回 */
|
|
6
|
+
export declare const GetFileVersionInfoSize: (args_0: string | (number & {
|
|
7
|
+
readonly ptrBrand: "WCHAR";
|
|
8
|
+
}), args_1: import("../ffi/ctype.js").PtrArrayBuffer<any> | import("../ffi/ctype.js").MaybePtr<"BYTE">) => number;
|
|
9
|
+
/** 读版本资源进缓冲
|
|
10
|
+
* @returns 成功 → 非 0
|
|
11
|
+
* @param args_0 lptstrFilename 文件路径(禁空)
|
|
12
|
+
* @param args_1 dwHandle Size 步读回的句柄(恒 0)
|
|
13
|
+
* @param args_2 dwLen 缓冲字节数(= Size 返回值)
|
|
14
|
+
* @param args_3 lpData 接收缓冲(PtrArrayBuffer(dwLen)) */
|
|
15
|
+
export declare const GetFileVersionInfo: (args_0: string | (number & {
|
|
16
|
+
readonly ptrBrand: "WCHAR";
|
|
17
|
+
}), args_1: number, args_2: number, args_3: import("../ffi/ctype.js").PtrArrayBuffer<any> | import("../ffi/ctype.js").MaybePtr<"BYTE">) => number;
|
|
18
|
+
/** 在版本资源缓冲内查询子块
|
|
19
|
+
* @returns 成功 → 非 0
|
|
20
|
+
* @param args_0 pBlock Info 步的资源缓冲(PtrArrayBuffer 直传)
|
|
21
|
+
* @param args_1 lpszSubBlock 子块路径(禁空):'\\' = 根块 VS_FIXEDFILEINFO、
|
|
22
|
+
* '\\StringFileInfo\\040904B0\\FileVersion' 等字符串表项
|
|
23
|
+
* @param args_2 lplpBuffer 出参槽(块内偏移指针写回),PtrArrayBuffer(8)
|
|
24
|
+
* @param args_3 puLen 出参槽(块字节数,VS_FIXEDFILEINFO = 52),PtrArrayBuffer(4) */
|
|
25
|
+
export declare const VerQueryValue: (args_0: import("../ffi/ctype.js").PtrArrayBuffer<any> | import("../ffi/ctype.js").MaybePtr<"BYTE">, args_1: string | (number & {
|
|
26
|
+
readonly ptrBrand: "WCHAR";
|
|
27
|
+
}), args_2: import("../ffi/ctype.js").PtrArrayBuffer<any> | import("../ffi/ctype.js").MaybePtr<"BYTE">, args_3: import("../ffi/ctype.js").PtrArrayBuffer<any> | import("../ffi/ctype.js").MaybePtr<"BYTE">) => number;
|
|
@@ -1,19 +1,3 @@
|
|
|
1
|
-
// winspool.drv 绑定(打印后台处理:枚举 / 能力查询 / 原始作业链;品牌约定见
|
|
2
|
-
// lib/windows/user32.ts 头注释):
|
|
3
|
-
// - 打印机句柄(OpenPrinter 的 HPRINTER* 出参槽写回)位宽无关:出参槽 = <BYTE>ptr
|
|
4
|
-
// 收 PtrArrayBuffer(8) + readPtr 读回 number,作业链句柄位 <>ptr 收宽(批 5 HKey 同型)
|
|
5
|
-
// - 结构位按方向分流(结构定义见 ./structs.ts):DOC_INFO_1W 纯入参位注册 encoder →
|
|
6
|
-
// 对象直传;PRINTER_INFO_2W 出参数组不注册 → structArray(PRINTER_INFO_2W).decode
|
|
7
|
-
// (buf, count) 读回(缓冲尾部含字符串,须显式 count),指针字段跟进读字符串
|
|
8
|
-
// - 枚举标注:DeviceCap 是单选查询位标枚举;PrinterEnum 是 LOCAL|CONNECTIONS 可组合
|
|
9
|
-
// flags → 裸 u32 + JSDoc(组合 OR 结果不是枚举成员,位标枚举反而传不进)
|
|
10
|
-
import { bind, type CodecMap } from '../ffi/bind.js'
|
|
11
|
-
import { DOC_INFO_1W } from './structs.js'
|
|
12
|
-
|
|
13
|
-
// dll 名部分应用(工厂转调保泛型 infer,见 lib/windows/user32.ts 头注释)
|
|
14
|
-
const b = <const S extends string, const LE extends CodecMap = {}>(name: string, sig: S, encoders?: LE) =>
|
|
15
|
-
bind('winspool.drv', name, sig, encoders)
|
|
16
|
-
|
|
17
1
|
/** 枚举打印队列(Level=2 → PRINTER_INFO_2W 数组);两段式:先
|
|
18
2
|
* NULL+cbBuf 0 拿 pcbNeeded,再按需分配缓冲重调
|
|
19
3
|
* @returns 成功 → 非 0
|
|
@@ -25,15 +9,12 @@ const b = <const S extends string, const LE extends CodecMap = {}>(name: string,
|
|
|
25
9
|
* @param args_4 cbBuf 缓冲字节数
|
|
26
10
|
* @param args_5 pcbNeeded 出参槽(需求字节数)PtrArrayBuffer(4)
|
|
27
11
|
* @param args_6 pcReturned 出参槽(返回条数)PtrArrayBuffer(4) */
|
|
28
|
-
export const EnumPrinters
|
|
29
|
-
'u32 <WCHAR>ptr u32 <BYTE>ptr u32 <BYTE>ptr <BYTE>ptr -> i32')
|
|
30
|
-
|
|
12
|
+
export declare const EnumPrinters: (args_0: number, args_1: string | import("../ffi/ctype.js").MaybePtr<"WCHAR">, args_2: number, args_3: import("../ffi/ctype.js").PtrArrayBuffer<any> | import("../ffi/ctype.js").MaybePtr<"BYTE">, args_4: number, args_5: import("../ffi/ctype.js").PtrArrayBuffer<any> | import("../ffi/ctype.js").MaybePtr<"BYTE">, args_6: import("../ffi/ctype.js").PtrArrayBuffer<any> | import("../ffi/ctype.js").MaybePtr<"BYTE">) => number;
|
|
31
13
|
/** 取默认打印机名
|
|
32
14
|
* @returns 成功 → 非 0,0 = 失败(缓冲不足时 pcchBuffer 带回所需长度)
|
|
33
15
|
* @param args_0 pszBuffer 出参缓冲,WCHAR.alloc(n)、WCHAR.decode 读回
|
|
34
16
|
* @param args_1 pcchBuffer 出入长度槽(入 = 缓冲 WCHAR 容量,出 = 实际长度),PtrArrayBuffer(4) */
|
|
35
|
-
export const GetDefaultPrinter
|
|
36
|
-
|
|
17
|
+
export declare const GetDefaultPrinter: (args_0: import("../ffi/ctype.js").PtrArrayBuffer<any> | import("../ffi/ctype.js").MaybePtr<"BYTE">, args_1: import("../ffi/ctype.js").PtrArrayBuffer<any> | import("../ffi/ctype.js").MaybePtr<"BYTE">) => number;
|
|
37
18
|
/** 查设备能力;nCapability 单选 DeviceCap.*
|
|
38
19
|
* @returns 返回值随能力(数值能力 = 数值,
|
|
39
20
|
* -1 = 失败)
|
|
@@ -42,39 +23,44 @@ export const GetDefaultPrinter = /*@__PURE__*/ b('GetDefaultPrinterW', '<BYTE>pt
|
|
|
42
23
|
* @param args_2 nCapability 能力码(DeviceCap.HORZRES 等单选)
|
|
43
24
|
* @param args_3 pOutput 字符串列表型能力的缓冲;数值型查询传 NULL
|
|
44
25
|
* @param args_4 pDevmode DEVMODE,传 NULL */
|
|
45
|
-
export const DeviceCapabilities
|
|
46
|
-
|
|
47
|
-
|
|
26
|
+
export declare const DeviceCapabilities: (args_0: string | (number & {
|
|
27
|
+
readonly ptrBrand: "WCHAR";
|
|
28
|
+
}), args_1: string | import("../ffi/ctype.js").MaybePtr<"WCHAR">, args_2: import("../../constants.js").DeviceCap, args_3: import("../ffi/ctype.js").PtrArrayBuffer<any> | import("../ffi/ctype.js").MaybePtr<"BYTE">, args_4: import("../ffi/ctype.js").MaybePtr<"">) => number;
|
|
48
29
|
/** 打开打印机对象(不产生打印作业)
|
|
49
30
|
* @returns 成功 → 非 0,hPrinter 写回
|
|
50
31
|
* @param args_0 pPrinterName 打印机名(禁空)
|
|
51
32
|
* @param args_1 phPrinter 出参槽(句柄写回),PtrArrayBuffer(8) + readPtr 读回
|
|
52
33
|
* @param args_2 pDefault 默认值(Datatype/DevMode/DesiredAccess),传 NULL 全默认 */
|
|
53
|
-
export const OpenPrinter
|
|
34
|
+
export declare const OpenPrinter: (args_0: string | (number & {
|
|
35
|
+
readonly ptrBrand: "WCHAR";
|
|
36
|
+
}), args_1: import("../ffi/ctype.js").PtrArrayBuffer<any> | import("../ffi/ctype.js").MaybePtr<"BYTE">, args_2: import("../ffi/ctype.js").MaybePtr<"">) => number;
|
|
54
37
|
/** 关闭打印机句柄
|
|
55
38
|
* @returns 成功 → 非 0 */
|
|
56
|
-
export const ClosePrinter
|
|
39
|
+
export declare const ClosePrinter: (args_0: import("../ffi/ctype.js").MaybePtr<"">) => number;
|
|
57
40
|
/** 起打印作业
|
|
58
41
|
* @returns 作业 id(0 = 失败)
|
|
59
42
|
* @param args_0 hPrinter 打印机句柄
|
|
60
43
|
* @param args_1 dwLevel 固定 1(DOC_INFO_1W)
|
|
61
44
|
* @param args_2 pDocInfo DOC_INFO_1W 对象(指针字段收裸地址 number:WCHAR.encode(s).ptr,
|
|
62
45
|
* PAB 须在调用返回前保持引用) */
|
|
63
|
-
export const StartDocPrinter
|
|
64
|
-
|
|
46
|
+
export declare const StartDocPrinter: (args_0: import("../ffi/ctype.js").MaybePtr<"">, args_1: number, args_2: {
|
|
47
|
+
pDatatype?: import("../ffi/ctype.js").MaybePtr<""> | undefined;
|
|
48
|
+
pDocName?: import("../ffi/ctype.js").MaybePtr<""> | undefined;
|
|
49
|
+
pOutputFile?: import("../ffi/ctype.js").MaybePtr<""> | undefined;
|
|
50
|
+
} | import("../ffi/ctype.js").MaybePtr<"DOC_INFO_1W">) => number;
|
|
65
51
|
/** 结束打印作业(提交)
|
|
66
52
|
* @returns 成功 → 非 0 */
|
|
67
|
-
export const EndDocPrinter
|
|
53
|
+
export declare const EndDocPrinter: (args_0: import("../ffi/ctype.js").MaybePtr<"">) => number;
|
|
68
54
|
/** 起页
|
|
69
55
|
* @returns 成功 → 非 0 */
|
|
70
|
-
export const StartPagePrinter
|
|
56
|
+
export declare const StartPagePrinter: (args_0: import("../ffi/ctype.js").MaybePtr<"">) => number;
|
|
71
57
|
/** 结束页
|
|
72
58
|
* @returns 成功 → 非 0 */
|
|
73
|
-
export const EndPagePrinter
|
|
59
|
+
export declare const EndPagePrinter: (args_0: import("../ffi/ctype.js").MaybePtr<"">) => number;
|
|
74
60
|
/** 写作业数据(RAW 直写 spooler)
|
|
75
61
|
* @returns 成功 → 非 0
|
|
76
62
|
* @param args_0 hPrinter 打印机句柄
|
|
77
63
|
* @param args_1 lpBuffer 数据缓冲(<BYTE>ptr,PtrArrayBuffer)
|
|
78
64
|
* @param args_2 nNumberOfBytesToWrite 写入字节数
|
|
79
65
|
* @param args_3 lpNumberOfBytesWritten 出参槽,PtrArrayBuffer(4) 读实际写入字节数 */
|
|
80
|
-
export const WritePrinter
|
|
66
|
+
export declare const WritePrinter: (args_0: import("../ffi/ctype.js").MaybePtr<"">, args_1: import("../ffi/ctype.js").PtrArrayBuffer<any> | import("../ffi/ctype.js").MaybePtr<"BYTE">, args_2: number, args_3: import("../ffi/ctype.js").PtrArrayBuffer<any> | import("../ffi/ctype.js").MaybePtr<"BYTE">) => number;
|
package/main.js
CHANGED
|
@@ -1,6 +1,11 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
import { CreateWindow as CreateWindowWithoutScale, DefWindowProc, RegisterClass, SendMessage, SetWindowProc, } from "gui";
|
|
2
|
+
// Win32 直通:CallWindowProc / GetWindowLongPtr / GetWindowText 无引擎状态,
|
|
3
|
+
// 已从 gui 模块摘除,走 lib/windows 的 FFI 绑定
|
|
4
|
+
import { CallWindowProc, GetWindowLongPtr, GetWindowText, GetWindowTextLength, ShowWindow } from "./lib/windows/user32.js";
|
|
5
|
+
import { WCHAR } from "./lib/ffi/bind.js";
|
|
6
|
+
import { createSystemDpiFont, getScaleFactor } from "./lib/dpi.js";
|
|
7
|
+
const scaleFactor = getScaleFactor();
|
|
8
|
+
const dpiFont = createSystemDpiFont();
|
|
4
9
|
if (!dpiFont)
|
|
5
10
|
throw new Error('Failed to create DPI font');
|
|
6
11
|
const CreateWindow = (className, title, style, x, y, cx, cy, parent, id) => {
|
|
@@ -26,7 +31,10 @@ function wndProc(hwnd, msg, wParam, lParam) {
|
|
|
26
31
|
return 0;
|
|
27
32
|
if (!list)
|
|
28
33
|
return 0;
|
|
29
|
-
const
|
|
34
|
+
const cap = GetWindowTextLength(edit) + 1;
|
|
35
|
+
const buf = WCHAR.alloc(cap);
|
|
36
|
+
GetWindowText(edit, buf, cap);
|
|
37
|
+
const text = WCHAR.decode(buf);
|
|
30
38
|
if (text.trim())
|
|
31
39
|
SendMessage(list, 384 /* LbMsg.ADDSTRING */, 0, text);
|
|
32
40
|
return 0;
|
|
@@ -43,4 +51,4 @@ function wndProc(hwnd, msg, wParam, lParam) {
|
|
|
43
51
|
RegisterClass("MainWindow", wndProc);
|
|
44
52
|
var hwnd = CreateWindow("MainWindow", "Todo List", 13565952 /* WindowStyle.OVERLAPPEDWINDOW */, 0, 0, 600, 400, null, null);
|
|
45
53
|
if (hwnd)
|
|
46
|
-
ShowWindow(hwnd);
|
|
54
|
+
ShowWindow(hwnd, 1 /* ShowWindowCmd.SHOWNORMAL */);
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"type": "module",
|
|
3
3
|
"name": "quickwin",
|
|
4
|
-
"version": "
|
|
4
|
+
"version": "3.0.1",
|
|
5
5
|
"description": "QuickJS Win32 runtime — GUI, networking, WASM, FFI, and more",
|
|
6
6
|
"bin": {
|
|
7
7
|
"quickwin": "qwin.exe",
|
|
@@ -22,7 +22,6 @@
|
|
|
22
22
|
"lib/",
|
|
23
23
|
"test/",
|
|
24
24
|
"examples/",
|
|
25
|
-
"vendor/",
|
|
26
25
|
"quickwin.d.ts",
|
|
27
26
|
"constants.ts",
|
|
28
27
|
"enum_map.d.ts",
|
|
@@ -35,17 +34,27 @@
|
|
|
35
34
|
"type": "git",
|
|
36
35
|
"url": "git+https://github.com/quickwinlabs/quickwin.git"
|
|
37
36
|
},
|
|
37
|
+
"dependencies": {
|
|
38
|
+
"@types/react-reconciler": "^0.33.0",
|
|
39
|
+
"react-reconciler": "^0.33.0"
|
|
40
|
+
},
|
|
41
|
+
"peerDependencies": {
|
|
42
|
+
"@types/react": "^19.2.17",
|
|
43
|
+
"react": "^19.2.7"
|
|
44
|
+
},
|
|
45
|
+
"peerDependenciesMeta": {
|
|
46
|
+
"@types/react": {
|
|
47
|
+
"optional": true
|
|
48
|
+
}
|
|
49
|
+
},
|
|
38
50
|
"devDependencies": {
|
|
51
|
+
"@quickwinlabs/mupdf-wasm": "^1.28.0",
|
|
39
52
|
"@types/node": "^24.13.2",
|
|
40
53
|
"@types/react": "^19.2.17",
|
|
41
|
-
"@types/react-reconciler": "^0.33.0",
|
|
42
54
|
"@types/ws": "^8.18.1",
|
|
43
55
|
"esbuild": "^0.28.0",
|
|
44
|
-
"typescript": "^7.0.2"
|
|
45
|
-
},
|
|
46
|
-
"dependencies": {
|
|
47
56
|
"react": "^19.2.7",
|
|
48
|
-
"
|
|
57
|
+
"typescript": "^7.0.2",
|
|
49
58
|
"web-streams-polyfill": "^4.3.0",
|
|
50
59
|
"ws": "^8.21.0"
|
|
51
60
|
}
|
package/quickwin.d.ts
CHANGED
|
@@ -421,96 +421,23 @@ declare module "wolfssl" {
|
|
|
421
421
|
|
|
422
422
|
}
|
|
423
423
|
|
|
424
|
-
declare module "win" {
|
|
425
|
-
/** 与 ffi 的 Ptr<"HMODULE"> 同型(ptrBrand string 键)——FFI 侧 <HMODULE>ptr 位(HINSTANCE 语义)直收 */
|
|
426
|
-
type HMODULE = number & { readonly ptrBrand: "HMODULE" };
|
|
427
|
-
|
|
428
|
-
function LoadLibrary(libName: string): HMODULE | null;
|
|
429
|
-
function GetProcAddress(hModule: HMODULE, procName: string): number | null;
|
|
430
|
-
function FreeLibrary(hModule: HMODULE): boolean;
|
|
431
|
-
/** GetModuleFileName(hModule?) — 传 HMODULE 或不传(当前进程),返回模块完整路径;失败返回 undefined */
|
|
432
|
-
function GetModuleFileName(hModule?: HMODULE): string | undefined;
|
|
433
|
-
/** GetModuleHandle(moduleName?) — 不传返回当前 exe 的模块句柄;失败返回 null */
|
|
434
|
-
function GetModuleHandle(moduleName?: string): HMODULE | null;
|
|
435
|
-
}
|
|
436
|
-
|
|
437
424
|
declare module "gui" {
|
|
438
425
|
/** 与 ffi 的 Ptr<"N"> 结构同型(ptrBrand string 键,见 lib/ffi/ctype.ts)——各句柄可在
|
|
439
426
|
* gui 模块与 FFI 绑定两体系间互认直传(原 unique symbol 键只有 HWND 打通) */
|
|
440
427
|
type HWND = number & { readonly ptrBrand: "HWND" };
|
|
441
428
|
type HMENU = number & { readonly ptrBrand: "HMENU" };
|
|
442
|
-
type HFONT = number & { readonly ptrBrand: "HFONT" };
|
|
443
429
|
type HICON = number & { readonly ptrBrand: "HICON" };
|
|
444
|
-
|
|
445
|
-
//
|
|
446
|
-
// 使用方请直接 import { WindowStyle } from 'quickwin/constants'。
|
|
447
|
-
// Gwlp/ImageType 的成员访问(如 Gwlp.WNDPROC)需写 import('./constants').Gwlp.WNDPROC
|
|
448
|
-
// ——类型别名不建命名空间,无法穿透取成员。
|
|
449
|
-
type GetWindowCmd = import('./constants').GetWindowCmd;
|
|
450
|
-
type ShowWindowCmd = import('./constants').ShowWindowCmd;
|
|
451
|
-
type SetWindowPosHwnd = import('./constants').SetWindowPosHwnd;
|
|
452
|
-
type Gwlp = import('./constants').Gwlp;
|
|
453
|
-
type NotifyIconCmd = import('./constants').NotifyIconCmd;
|
|
454
|
-
type ImageType = import('./constants').ImageType;
|
|
455
|
-
type IDI = import('./constants').IDI;
|
|
456
|
-
type ScrollBar = import('./constants').ScrollBar;
|
|
430
|
+
// 枚举唯一定义在 constants.ts(真实 .ts,tsc/esbuild 均内联);本模块不再转出枚举
|
|
431
|
+
// 别名与 RECT 等结构类型——Win32 直通请走 lib/windows(含常量与结构定义)
|
|
457
432
|
|
|
458
433
|
function RegisterClass(className: string, wndProc?: (hwnd: HWND, msg: number, wParam: number, lParam: number) => number): number;
|
|
459
434
|
function CreateWindow(className: string, title: string, style: number, x: number, y: number, width: number, height: number, parent: HWND | null, menu: HMENU | null): HWND | null;
|
|
460
435
|
// 销毁窗口及其所有子窗口,自动清理 WNDPROC 和 JS 引用
|
|
461
436
|
function DestroyWindow(hwnd: HWND): boolean;
|
|
462
|
-
function GetWindow(hwnd: HWND, cmd: GetWindowCmd): HWND;
|
|
463
|
-
|
|
464
|
-
function ShowWindow(hwnd: HWND, nCmdShow?: ShowWindowCmd): void;
|
|
465
437
|
function SetWindowProc(hwnd: HWND, wndProc: (hwnd: HWND, msg: number, wParam: number, lParam: number) => number): void;
|
|
466
438
|
function DefWindowProc(hwnd: HWND, msg: number, wParam: number, lParam: number): number;
|
|
467
|
-
function PostQuitMessage(exitCode: number): void;
|
|
468
439
|
function SendMessage(hwnd: HWND, msg: number, wParam: number, lParam: number | string): number;
|
|
469
|
-
function MessageBox(message: string): void;
|
|
470
|
-
function SetWindowText(hwnd: HWND, text: string): void;
|
|
471
|
-
function GetWindowText(hwnd: HWND): string;
|
|
472
|
-
function GetScaleFactor(): number;
|
|
473
|
-
function CreateSystemDpiFont(): HFONT | null;
|
|
474
|
-
type GwlpReturnType<T extends Gwlp> = T extends import('./constants').Gwlp.WNDPROC ? WNDPROC : number;
|
|
475
|
-
function GetWindowLongPtr<T extends Gwlp>(hwnd: HWND, nIndex: T): GwlpReturnType<T>;
|
|
476
|
-
function SetWindowLongPtr(hwnd: HWND, nIndex: Gwlp, newLong: number): number;
|
|
477
440
|
function UnsetWindowProc(hwnd: HWND): boolean;
|
|
478
|
-
function CallWindowProc(wndProc: WNDPROC, hwnd: HWND, msg: number, wParam: number, lParam: number): number;
|
|
479
|
-
function SetParent(hwnd: HWND, parent: HWND | null): void;
|
|
480
|
-
function EnableWindow(hwnd: HWND, enable: boolean): void;
|
|
481
|
-
function SetWindowPos(hwnd: HWND, insertAfter: SetWindowPosHwnd, x: number, y: number, width: number, height: number, flags: number): void;
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
interface NotifyIconData {
|
|
486
|
-
hwnd: HWND
|
|
487
|
-
uID?: number
|
|
488
|
-
flags?: number
|
|
489
|
-
callbackMessage?: number
|
|
490
|
-
hIcon?: HICON
|
|
491
|
-
tip?: string
|
|
492
|
-
}
|
|
493
|
-
|
|
494
|
-
function ShellNotifyIcon(cmd: NotifyIconCmd, nid: NotifyIconData): boolean;
|
|
495
|
-
/**
|
|
496
|
-
* Thin wrapper around LoadImageW. Parameter order matches Win32 LoadImageW: (hinst, name, uType?, cx?, cy?, fuLoad?).
|
|
497
|
-
* hinst: null for system resources/file path, number for module handle;
|
|
498
|
-
* name: when hinst=null, a system icon IDI or .ico file path; when hinst=module handle, a resource ID (number) or resource name (string);
|
|
499
|
-
* uType: ImageType constant, default IMAGE_ICON (returns HICON), pass BITMAP/CURSOR for number return;
|
|
500
|
-
* cx/cy: target size (0 for default, use LoadImageFlag.DEFAULTSIZE for system default size);
|
|
501
|
-
* fuLoad: LoadImageFlag constants. Note: loading system icons (IDI_*, hinst=null) requires LoadImageFlag.SHARED.
|
|
502
|
-
* Example: import { IDI, ImageType, LoadImageFlag } from 'quickwin/constants'
|
|
503
|
-
* gui.LoadImage(null, "app.ico", ImageType.ICON, 32, 32, LoadImageFlag.LOADFROMFILE)
|
|
504
|
-
* gui.LoadImage(null, IDI.APPLICATION, ImageType.ICON, 0, 0, LoadImageFlag.SHARED)
|
|
505
|
-
*/
|
|
506
|
-
function LoadImage<H extends (import("win").HMODULE) | null, T extends ImageType = import('./constants').ImageType.ICON>(
|
|
507
|
-
hinst: H,
|
|
508
|
-
name: H extends null ? string | IDI : string | number,
|
|
509
|
-
uType?: T,
|
|
510
|
-
cx?: number,
|
|
511
|
-
cy?: number,
|
|
512
|
-
fuLoad?: number
|
|
513
|
-
): T extends import('./constants').ImageType.ICON ? HICON | null : number | null;
|
|
514
441
|
/**
|
|
515
442
|
* Loads the first icon group (RT_GROUP_ICON) from this exe, i.e. the custom icon
|
|
516
443
|
* embedded by rcedit. Works with any resource ID including 0. Returns null if the
|
|
@@ -519,46 +446,6 @@ declare module "gui" {
|
|
|
519
446
|
* Example: gui.LoadAppIcon() → HICON of the exe's icon.
|
|
520
447
|
*/
|
|
521
448
|
function LoadAppIcon(cx?: number, cy?: number): HICON | null;
|
|
522
|
-
/** 从 BGRA 像素数据创建 32bpp top-down DIB,data 为 length >= width*height*4 的 ArrayBuffer,返回 HBITMAP */
|
|
523
|
-
function CreateBitmapFromPixels(width: number, height: number, data: ArrayBuffer): number | null;
|
|
524
|
-
function DeleteObject(hObject: number): boolean;
|
|
525
|
-
function ImageListCreate(cx: number, cy: number, flags?: number, initial?: number, grow?: number): number | null;
|
|
526
|
-
function ImageListAdd(himl: number, hBitmap: number): number;
|
|
527
|
-
function ImageListDestroy(himl: number): boolean;
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
function CreatePopupMenu(): HMENU | null;
|
|
531
|
-
function AppendMenu(menu: HMENU, flags: number, id: number, text: string): boolean;
|
|
532
|
-
function TrackPopupMenu(menu: HMENU, x: number, y: number, flags?: number, hwnd?: HWND): number;
|
|
533
|
-
function DestroyMenu(menu: HMENU): boolean;
|
|
534
|
-
function SetForegroundWindow(hwnd: HWND): boolean;
|
|
535
|
-
/** Returns [x, y] or null */
|
|
536
|
-
function GetCursorPos(): [number, number] | null;
|
|
537
|
-
/** Returns [width, height] of the primary monitor */
|
|
538
|
-
function GetScreenSize(): [number, number];
|
|
539
|
-
/** Client-area/mouse rect: { left, top, right, bottom } */
|
|
540
|
-
type RECT = { left: number; top: number; right: number; bottom: number };
|
|
541
|
-
/** Returns { left, top, right, bottom } of client area, or null if invalid */
|
|
542
|
-
function GetClientRect(hwnd: HWND): RECT | null;
|
|
543
|
-
|
|
544
|
-
function GetWindowRect(hwnd: HWND): RECT | null;
|
|
545
|
-
/** Invalidates client area (rect can be null/undefined for full window) */
|
|
546
|
-
function InvalidateRect(hwnd: HWND, rect?: RECT | null, erase?: boolean): void;
|
|
547
|
-
/** Forces immediate repaint of invalidated area */
|
|
548
|
-
function UpdateWindow(hwnd: HWND): void;
|
|
549
|
-
/** Checks if the window handle is valid */
|
|
550
|
-
function IsWindow(hwnd: HWND): boolean;
|
|
551
|
-
/** Sets scroll info; returns current scroll box position. Signature matches Win32 SetScrollInfo. */
|
|
552
|
-
function SetScrollInfo(hwnd: HWND, bar: ScrollBar, info: { pos?: number; page?: number; min?: number; max?: number }, redraw?: boolean): number;
|
|
553
|
-
|
|
554
|
-
/** Gets scroll info. Signature matches Win32 GetScrollInfo. */
|
|
555
|
-
function GetScrollInfo(hwnd: HWND, bar: ScrollBar): { pos: number; page: number; min: number; max: number; trackPos: number };
|
|
556
|
-
|
|
557
|
-
/** Shows or hides a scroll bar. Signature matches Win32 ShowScrollBar. */
|
|
558
|
-
function ShowScrollBar(hwnd: HWND, bar: ScrollBar, show: boolean): boolean;
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
449
|
|
|
563
450
|
|
|
564
451
|
|
|
@@ -585,6 +472,12 @@ declare module "gui" {
|
|
|
585
472
|
}
|
|
586
473
|
|
|
587
474
|
declare module "ffi" {
|
|
475
|
+
/** 指针品牌唯一定义在 lib/ffi/ctype.ts(此处只转发,不手抄结构)——本模块返回的
|
|
476
|
+
* 句柄 / 地址即对应 C 侧指针位,空值形态同 FFI 层:NULL(0),不是 JS null。 */
|
|
477
|
+
type Ptr<N extends string> = import('./lib/ffi/ctype').Ptr<N>;
|
|
478
|
+
type MaybePtr<N extends string> = import('./lib/ffi/ctype').MaybePtr<N>;
|
|
479
|
+
type HMODULE = Ptr<"HMODULE">;
|
|
480
|
+
|
|
588
481
|
function ffiCall(func: number, argFrame: ArrayBuffer, retBuf: ArrayBuffer, retIsFp: 0 | 1): void;
|
|
589
482
|
function bufferPtr(buf: ArrayBuffer): number;
|
|
590
483
|
function readByte(ptr: number): number;
|
|
@@ -592,6 +485,11 @@ declare module "ffi" {
|
|
|
592
485
|
function writeByte(ptr: number, value: number): void;
|
|
593
486
|
function closureNew(argBytes: number, retKind: number, wrapper: (frame: ArrayBuffer, retBuf: ArrayBuffer) => void): number;
|
|
594
487
|
function closureFree(ptr: number): void;
|
|
488
|
+
/** LoadLibraryW 直映:FFI 自举入口(ffi 自身没有 dlopen,取符号必先装载),
|
|
489
|
+
* 成功为模块句柄 <HMODULE>ptr(HINSTANCE 语义),失败为空指针(0);按真值收窄。 */
|
|
490
|
+
function LoadLibrary(libName: string): MaybePtr<"HMODULE">;
|
|
491
|
+
/** GetProcAddress 直映:成功为函数地址 <FARPROC>ptr,失败为空指针(0)。 */
|
|
492
|
+
function GetProcAddress(hModule: HMODULE, procName: string): MaybePtr<"FARPROC">;
|
|
595
493
|
}
|
|
596
494
|
|
|
597
495
|
|
package/qwin-nowasm-x86.exe
CHANGED
|
Binary file
|
package/qwin-nowasm.exe
CHANGED
|
Binary file
|
package/qwin-x86.exe
CHANGED
|
Binary file
|
package/qwin.exe
CHANGED
|
Binary file
|
|
@@ -13,7 +13,6 @@
|
|
|
13
13
|
// 结束必须 DestroyWindow + std.exit。
|
|
14
14
|
import * as std from 'std';
|
|
15
15
|
import * as gui from 'gui';
|
|
16
|
-
import * as win from 'win';
|
|
17
16
|
import * as ffi from 'ffi';
|
|
18
17
|
import { bind } from '../lib/ffi/bind.js';
|
|
19
18
|
const WM_NULL = 0x0000;
|
|
@@ -37,11 +36,11 @@ function step(msg) {
|
|
|
37
36
|
step('stage: imports ok');
|
|
38
37
|
// ---- proc 地址(B/C 臂绕过 bind 直驱 ffiCall)----
|
|
39
38
|
function procOf(dll, name) {
|
|
40
|
-
const h =
|
|
39
|
+
const h = ffi.LoadLibrary(dll);
|
|
41
40
|
if (!h)
|
|
42
41
|
throw new Error('LoadLibrary(' + dll + ') failed');
|
|
43
|
-
const p =
|
|
44
|
-
if (p
|
|
42
|
+
const p = ffi.GetProcAddress(h, name);
|
|
43
|
+
if (!p)
|
|
45
44
|
throw new Error('GetProcAddress(' + dll + '!' + name + ') failed');
|
|
46
45
|
return p;
|
|
47
46
|
}
|
|
@@ -13,7 +13,6 @@
|
|
|
13
13
|
// 结束必须 DestroyWindow + std.exit。
|
|
14
14
|
import * as std from 'std'
|
|
15
15
|
import * as gui from 'gui'
|
|
16
|
-
import * as win from 'win'
|
|
17
16
|
import * as ffi from 'ffi'
|
|
18
17
|
import { bind } from '../lib/ffi/bind.js'
|
|
19
18
|
|
|
@@ -39,10 +38,10 @@ step('stage: imports ok')
|
|
|
39
38
|
|
|
40
39
|
// ---- proc 地址(B/C 臂绕过 bind 直驱 ffiCall)----
|
|
41
40
|
function procOf(dll: string, name: string): number {
|
|
42
|
-
const h =
|
|
41
|
+
const h = ffi.LoadLibrary(dll)
|
|
43
42
|
if (!h) throw new Error('LoadLibrary(' + dll + ') failed')
|
|
44
|
-
const p =
|
|
45
|
-
if (p
|
|
43
|
+
const p = ffi.GetProcAddress(h, name)
|
|
44
|
+
if (!p) throw new Error('GetProcAddress(' + dll + '!' + name + ') failed')
|
|
46
45
|
return p
|
|
47
46
|
}
|
|
48
47
|
const pNop0 = procOf('test/nop.dll', 'nop0')
|
|
@@ -1,25 +1,7 @@
|
|
|
1
1
|
import * as std from 'std';
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
throw new Error('Cannot open: ' + path);
|
|
6
|
-
fp.seek(0, 2);
|
|
7
|
-
const size = fp.tell();
|
|
8
|
-
fp.seek(0, 0);
|
|
9
|
-
const buffer = new ArrayBuffer(size);
|
|
10
|
-
fp.read(buffer, 0, size);
|
|
11
|
-
fp.close();
|
|
12
|
-
return buffer;
|
|
13
|
-
}
|
|
14
|
-
function setupMupdfModule(wasmPath) {
|
|
15
|
-
const wasmBinary = loadWasmBytes(wasmPath);
|
|
16
|
-
globalThis["$libmupdf_wasm_Module"] = {
|
|
17
|
-
wasmBinary,
|
|
18
|
-
locateFile: (p) => p
|
|
19
|
-
};
|
|
20
|
-
}
|
|
21
|
-
setupMupdfModule('./vendor/mupdf-wasm/mupdf-wasm.wasm');
|
|
22
|
-
await import('../../vendor/mupdf-wasm/mupdf.js');
|
|
2
|
+
import { MUPDF_JS_URL, preloadMupdfWasm } from '../mupdf-cdn.js';
|
|
3
|
+
await preloadMupdfWasm();
|
|
4
|
+
await import(MUPDF_JS_URL);
|
|
23
5
|
// Debug the instance exports
|
|
24
6
|
const inst = globalThis["$wasm_inst"];
|
|
25
7
|
const mod = globalThis["$wasm_mod"];
|
|
@@ -39,7 +21,7 @@ console.log('Sf index:', sf_idx, 'Tf index:', tf_idx);
|
|
|
39
21
|
console.log('instance exports Sf:', typeof inst.exports['Sf']);
|
|
40
22
|
console.log('instance exports Tf:', typeof inst.exports['Tf']);
|
|
41
23
|
// Load a simple WASM to verify bridge works
|
|
42
|
-
const fp = std.open('./example.pdf', 'rb');
|
|
24
|
+
const fp = std.open('./test/example.pdf', 'rb');
|
|
43
25
|
if (!fp) {
|
|
44
26
|
console.log('cannot open example.pdf');
|
|
45
27
|
std.exit(1);
|
|
@@ -1,15 +1,5 @@
|
|
|
1
|
-
import
|
|
2
|
-
const
|
|
3
|
-
if (!fp) {
|
|
4
|
-
console.log('cannot open vendor/mupdf-wasm/mupdf-wasm.wasm');
|
|
5
|
-
std.exit(1);
|
|
6
|
-
}
|
|
7
|
-
fp.seek(0, 2);
|
|
8
|
-
const size = fp.tell();
|
|
9
|
-
fp.seek(0, 0);
|
|
10
|
-
const buf = new ArrayBuffer(size);
|
|
11
|
-
fp.read(buf, 0, size);
|
|
12
|
-
fp.close();
|
|
1
|
+
import { fetchMupdfWasm } from '../mupdf-cdn.js';
|
|
2
|
+
const buf = await fetchMupdfWasm();
|
|
13
3
|
const module = new WebAssembly.Module(buf);
|
|
14
4
|
const exports = WebAssembly.Module.exports(module);
|
|
15
5
|
const imports = WebAssembly.Module.imports(module);
|
package/test/debug/wasm_names.js
CHANGED
|
@@ -1,16 +1,6 @@
|
|
|
1
|
-
import
|
|
2
|
-
//
|
|
3
|
-
const
|
|
4
|
-
if (!fp) {
|
|
5
|
-
console.log('cannot open vendor/mupdf-wasm/mupdf-wasm.wasm');
|
|
6
|
-
std.exit(1);
|
|
7
|
-
}
|
|
8
|
-
fp.seek(0, 2);
|
|
9
|
-
const size = fp.tell();
|
|
10
|
-
fp.seek(0, 0);
|
|
11
|
-
const buf = new ArrayBuffer(size);
|
|
12
|
-
fp.read(buf, 0, size);
|
|
13
|
-
fp.close();
|
|
1
|
+
import { fetchMupdfWasm } from '../mupdf-cdn.js';
|
|
2
|
+
// Fetch the mupdf-wasm binary over HTTPS (process-wide HTTP cache applies)
|
|
3
|
+
const buf = await fetchMupdfWasm();
|
|
14
4
|
// Check exports for Tf
|
|
15
5
|
const module = new WebAssembly.Module(buf);
|
|
16
6
|
const exports = WebAssembly.Module.exports(module);
|
package/test/example.pdf
ADDED
|
Binary file
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
// ── mupdf-wasm CDN loading ──
|
|
2
|
+
//
|
|
3
|
+
// The runtime loads mupdf from unpkg; the npm package itself only ships
|
|
4
|
+
// types (devDependency @quickwinlabs/mupdf-wasm resolved through the
|
|
5
|
+
// package's exports types mapping — no local vendor copy involved).
|
|
6
|
+
// MUPDF_VERSION must stay in sync with the devDependency in package.json
|
|
7
|
+
// when bumping.
|
|
8
|
+
//
|
|
9
|
+
// Importing this module wires up the HTTPS stack (certs + fetch): the
|
|
10
|
+
// wasm bytes travel through the process-wide HTTP cache next to the
|
|
11
|
+
// executable, so the first fetch is the only network hit.
|
|
12
|
+
import '../lib/certs.js';
|
|
13
|
+
import '../lib/fetch.js';
|
|
14
|
+
export const MUPDF_VERSION = '1.28.0';
|
|
15
|
+
const BASE = `https://unpkg.com/@quickwinlabs/mupdf-wasm@${MUPDF_VERSION}`;
|
|
16
|
+
export const MUPDF_JS_URL = `${BASE}/mupdf.js`;
|
|
17
|
+
export const MUPDF_WASM_URL = `${BASE}/mupdf-wasm.wasm`;
|
|
18
|
+
/** Fetch the wasm binary over HTTPS (HTTP-cached, no filesystem involved). */
|
|
19
|
+
export async function fetchMupdfWasm() {
|
|
20
|
+
const resp = await fetch(MUPDF_WASM_URL);
|
|
21
|
+
if (resp.status !== 200)
|
|
22
|
+
throw new Error(`mupdf wasm fetch failed: HTTP ${resp.status}`);
|
|
23
|
+
const wasmBinary = await resp.arrayBuffer();
|
|
24
|
+
if (wasmBinary.byteLength < 1_000_000)
|
|
25
|
+
throw new Error(`mupdf wasm truncated: ${wasmBinary.byteLength} bytes`);
|
|
26
|
+
return wasmBinary;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Fetch the wasm binary and pre-wire it as $libmupdf_wasm_Module so the
|
|
30
|
+
* mupdf.js module factory instantiates from memory (same injection the
|
|
31
|
+
* local-vendor loading used).
|
|
32
|
+
*/
|
|
33
|
+
export async function preloadMupdfWasm() {
|
|
34
|
+
const wasmBinary = await fetchMupdfWasm();
|
|
35
|
+
globalThis.$libmupdf_wasm_Module = {
|
|
36
|
+
wasmBinary,
|
|
37
|
+
locateFile: (p) => p,
|
|
38
|
+
};
|
|
39
|
+
return wasmBinary;
|
|
40
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
// ── mupdf-wasm CDN loading ──
|
|
2
|
+
//
|
|
3
|
+
// The runtime loads mupdf from unpkg; the npm package itself only ships
|
|
4
|
+
// types (devDependency @quickwinlabs/mupdf-wasm resolved through the
|
|
5
|
+
// package's exports types mapping — no local vendor copy involved).
|
|
6
|
+
// MUPDF_VERSION must stay in sync with the devDependency in package.json
|
|
7
|
+
// when bumping.
|
|
8
|
+
//
|
|
9
|
+
// Importing this module wires up the HTTPS stack (certs + fetch): the
|
|
10
|
+
// wasm bytes travel through the process-wide HTTP cache next to the
|
|
11
|
+
// executable, so the first fetch is the only network hit.
|
|
12
|
+
|
|
13
|
+
import '../lib/certs.js'
|
|
14
|
+
import '../lib/fetch.js'
|
|
15
|
+
|
|
16
|
+
export const MUPDF_VERSION = '1.28.0'
|
|
17
|
+
const BASE = `https://unpkg.com/@quickwinlabs/mupdf-wasm@${MUPDF_VERSION}`
|
|
18
|
+
|
|
19
|
+
export const MUPDF_JS_URL = `${BASE}/mupdf.js`
|
|
20
|
+
export const MUPDF_WASM_URL = `${BASE}/mupdf-wasm.wasm`
|
|
21
|
+
|
|
22
|
+
/** Fetch the wasm binary over HTTPS (HTTP-cached, no filesystem involved). */
|
|
23
|
+
export async function fetchMupdfWasm(): Promise<ArrayBuffer> {
|
|
24
|
+
const resp = await fetch(MUPDF_WASM_URL)
|
|
25
|
+
if (resp.status !== 200) throw new Error(`mupdf wasm fetch failed: HTTP ${resp.status}`)
|
|
26
|
+
const wasmBinary = await resp.arrayBuffer()
|
|
27
|
+
if (wasmBinary.byteLength < 1_000_000) throw new Error(`mupdf wasm truncated: ${wasmBinary.byteLength} bytes`)
|
|
28
|
+
return wasmBinary
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Fetch the wasm binary and pre-wire it as $libmupdf_wasm_Module so the
|
|
33
|
+
* mupdf.js module factory instantiates from memory (same injection the
|
|
34
|
+
* local-vendor loading used).
|
|
35
|
+
*/
|
|
36
|
+
export async function preloadMupdfWasm(): Promise<ArrayBuffer> {
|
|
37
|
+
const wasmBinary = await fetchMupdfWasm()
|
|
38
|
+
;(globalThis as any).$libmupdf_wasm_Module = {
|
|
39
|
+
wasmBinary,
|
|
40
|
+
locateFile: (p: string) => p,
|
|
41
|
+
}
|
|
42
|
+
return wasmBinary
|
|
43
|
+
}
|