@aiti-ai/grdpwasm 0.0.0-stage → 0.2.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/LICENSE +674 -0
- package/README.md +159 -2
- package/README.zh-CN.md +145 -0
- package/package.json +27 -4
- package/scripts/postinstall.mjs +28 -0
- package/scripts/sync-version.mjs +23 -0
- package/static/index.html +894 -0
- package/static/main.wasm +0 -0
- package/static/remote-keys.js +59 -0
- package/static/shortcut-bar.js +95 -0
- package/static/system-keyboard.js +59 -0
- package/static/type-text.js +91 -0
- package/static/vendor/justget.browser.js +1 -0
- package/static/vendor/simple-keyboard.css +11 -0
- package/static/vendor/simple-keyboard.js +12 -0
- package/static/virtual-keyboard.css +77 -0
- package/static/virtual-keyboard.js +199 -0
- package/static/wasm_exec.js +575 -0
package/README.md
CHANGED
|
@@ -1,3 +1,160 @@
|
|
|
1
|
-
#
|
|
1
|
+
# grdpwasm
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
[English](README.md) | [中文说明](README.zh-CN.md)
|
|
4
|
+
|
|
5
|
+
A web-based RDP client built with Go WebAssembly and [grdp](https://github.com/nakagami/grdp).
|
|
6
|
+
Connect to a Windows Remote Desktop server directly from your browser — no plugins required.
|
|
7
|
+
|
|
8
|
+
> **This is the `aiti-aigrdpwasm` fork** of [nakagami/grdpwasm](https://github.com/nakagami/grdpwasm).
|
|
9
|
+
> It carries a patched `grdp` vendor fork and several feature/fix layers on top of upstream —
|
|
10
|
+
> see [Updates in this fork](#updates-in-this-fork) below.
|
|
11
|
+
> Published to npm as [`@aiti-ai/grdpwasm`](https://www.npmjs.com/package/@aiti-ai/grdpwasm).
|
|
12
|
+
|
|
13
|
+
> **Availability**: published to npm as [`@aiti-ai/grdpwasm`](https://www.npmjs.com/package/@aiti-ai/grdpwasm) —
|
|
14
|
+
> `npm install @aiti-ai/grdpwasm`. jsDelivr/unpkg serve `main.wasm` straight from the npm tarball;
|
|
15
|
+
> when served behind a backend (e.g. aiti-ui-env's rdp-bridge), the wasm loads same-origin.
|
|
16
|
+
|
|
17
|
+
## Updates in this fork
|
|
18
|
+
|
|
19
|
+
### xrdp / gnome-remote-desktop compatibility
|
|
20
|
+
|
|
21
|
+
- Vendored patched `grdp` fork (`third_party/grdp`): planar codec constant fix, capability
|
|
22
|
+
advertisement trimmed to what this client can honor (no SURFACE_COMMANDS, no frame
|
|
23
|
+
marker, no bitmap-cache REV2), NSCodec-capture server-type detection, fullscreen
|
|
24
|
+
refresh recovery, ECDSA CredSSP key echo, fast-path input PDU padding, clear NLA errors.
|
|
25
|
+
- Automatic EGFX negotiation: connects with GFX first; if the server's actual codec is
|
|
26
|
+
undecodable (xrdp sends progressive/planar only), it reconnects once in compat mode.
|
|
27
|
+
GDS/Windows (H.264) connect normally.
|
|
28
|
+
- Lossless WASM transport: inbound messages queue without blocking the JS thread or
|
|
29
|
+
dropping data (dropping caused stream desync → artifacting/disconnects); bursts are
|
|
30
|
+
bounded by the bridge's backpressure.
|
|
31
|
+
|
|
32
|
+
### Frontend
|
|
33
|
+
|
|
34
|
+
- **fixedTarget mode**: the target host/port is provided by the server (injected
|
|
35
|
+
`__rdpTarget`) or `?fixedTarget=true`, and can no longer be tampered with from the
|
|
36
|
+
frontend; standalone mode keeps free-form connection fields.
|
|
37
|
+
- Virtual keyboard (programmer layout), shortcut bar, native system-keyboard proxy,
|
|
38
|
+
X11/RFB keysym helpers — shared, host-agnostic components.
|
|
39
|
+
- xrdp color-cursor mitigation: cursors whose AND mask makes them fully opaque render
|
|
40
|
+
as black blocks; they are detected (≥95% opaque ratio) and discarded.
|
|
41
|
+
|
|
42
|
+
### Packaging & delivery (@aiti-ai/grdpwasm)
|
|
43
|
+
|
|
44
|
+
- Published as an npm package. The tarball ships `main.wasm` (that's what jsDelivr/unpkg
|
|
45
|
+
serve from), but `postinstall` removes the local copy after install — at runtime the
|
|
46
|
+
page race-downloads the wasm from CDNs via [justget](https://github.com/justdb/justget)
|
|
47
|
+
with same-origin fallback (override: `?wasm=<url>` or `localStorage['grdpwasm.wasmUrl']`).
|
|
48
|
+
- Server-side fallback for embedders: a backend helper (`ensureRdpWasm` pattern) can
|
|
49
|
+
pre-fetch the wasm into a cache dir so the static server always has one to serve.
|
|
50
|
+
|
|
51
|
+
## Architecture
|
|
52
|
+
|
|
53
|
+
```
|
|
54
|
+
Browser (WASM) ──WebSocket──► proxy (Go) ──TCP──► RDP Server
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
Because browsers cannot open raw TCP sockets, a lightweight Go proxy server bridges
|
|
58
|
+
WebSocket connections from the browser to the RDP server's TCP port.
|
|
59
|
+
|
|
60
|
+
## Requirements
|
|
61
|
+
|
|
62
|
+
- Go 1.24 or later
|
|
63
|
+
- A reachable RDP server (Windows or any RDP-compatible host)
|
|
64
|
+
|
|
65
|
+
## Build
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
git clone https://github.com/nakagami/grdpwasm.git
|
|
69
|
+
cd grdpwasm
|
|
70
|
+
make all
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
`make all` produces:
|
|
74
|
+
|
|
75
|
+
| Output | Description |
|
|
76
|
+
|---|---|
|
|
77
|
+
| `static/main.wasm` | Go WASM binary (runs in the browser) |
|
|
78
|
+
| `static/wasm_exec.js` | Go runtime JS support file |
|
|
79
|
+
| `proxy/proxy` | WebSocket-to-TCP proxy + static file server |
|
|
80
|
+
|
|
81
|
+
## Run
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
make serve
|
|
85
|
+
# or equivalently:
|
|
86
|
+
./proxy/proxy -listen :8080 -static static
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
Then open **http://localhost:8080** in your browser.
|
|
90
|
+
|
|
91
|
+
### Proxy options
|
|
92
|
+
|
|
93
|
+
| Flag | Default | Description |
|
|
94
|
+
|---|---|---|
|
|
95
|
+
| `-listen` | `:8080` | Address and port to listen on |
|
|
96
|
+
| `-static` | `static` | Directory to serve static files from |
|
|
97
|
+
|
|
98
|
+
## Usage
|
|
99
|
+
|
|
100
|
+
1. Open `http://localhost:8080` in a browser.
|
|
101
|
+
2. Fill in the connection form:
|
|
102
|
+
- **Host** — hostname or IP address of the RDP server
|
|
103
|
+
- **Port** — RDP port (default `3389`)
|
|
104
|
+
- **Domain** — Windows domain (leave blank for local accounts)
|
|
105
|
+
- **User** — username
|
|
106
|
+
- **Password** — password
|
|
107
|
+
- **Width / Height** — initial desktop resolution
|
|
108
|
+
3. Click **Connect**.
|
|
109
|
+
4. The remote desktop appears in the canvas. Click the canvas to capture keyboard focus.
|
|
110
|
+
5. Click **Disconnect** to end the session.
|
|
111
|
+
|
|
112
|
+
## Keyboard & Mouse
|
|
113
|
+
|
|
114
|
+
All standard keyboard input is forwarded to the remote desktop via RDP scan codes.
|
|
115
|
+
Mouse move, button clicks, and scroll wheel are fully supported.
|
|
116
|
+
|
|
117
|
+
> **Note:** The browser tab must have focus for keyboard events to be forwarded.
|
|
118
|
+
> Click inside the canvas area if keys stop responding.
|
|
119
|
+
|
|
120
|
+
## Audio
|
|
121
|
+
|
|
122
|
+
Remote audio is streamed via RDPSND and played through the browser's Web Audio API
|
|
123
|
+
(PCM 44100 Hz, stereo, 16-bit signed little-endian).
|
|
124
|
+
|
|
125
|
+
## Security notes
|
|
126
|
+
|
|
127
|
+
- The proxy accepts connections from any origin. Run it only on a trusted network
|
|
128
|
+
or add authentication before exposing it to the internet.
|
|
129
|
+
- Credentials are transmitted from the browser to the proxy over WebSocket.
|
|
130
|
+
Use HTTPS/WSS (put the proxy behind a TLS-terminating reverse proxy such as
|
|
131
|
+
nginx or Caddy) when accessing it over an untrusted network.
|
|
132
|
+
|
|
133
|
+
## Development
|
|
134
|
+
|
|
135
|
+
```
|
|
136
|
+
npm install # install JS dependencies (justget, esbuild)
|
|
137
|
+
make wasm # rebuild only the WASM binary
|
|
138
|
+
make proxy # rebuild only the proxy server
|
|
139
|
+
make wasm_exec # refresh wasm_exec.js from the local Go toolchain
|
|
140
|
+
npm run build:vendor # rebuild static/vendor/justget.browser.js from the installed justget
|
|
141
|
+
make clean # remove all build artifacts
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
## npm package
|
|
145
|
+
|
|
146
|
+
Publish the browser assets as `@aiti-ai/grdpwasm`. Consumers get everything except
|
|
147
|
+
`main.wasm` — the page fetches it from CDN at runtime.
|
|
148
|
+
|
|
149
|
+
```bash
|
|
150
|
+
npm run build:vendor # bundle justget/browser into static/vendor/
|
|
151
|
+
make all # build main.wasm + wasm_exec.js + proxy
|
|
152
|
+
npm publish # prepack syncs the version into index.html; tarball ships the wasm
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
Consumers get `static/` (html/js/vendor) without `main.wasm` — the page fetches it
|
|
156
|
+
from CDN at runtime. Set `GRDPWASM_KEEP_WASM=1` before install to keep the local copy.
|
|
157
|
+
|
|
158
|
+
## License
|
|
159
|
+
|
|
160
|
+
GPLv3 — see [grdp LICENSE](https://github.com/nakagami/grdp/blob/master/LICENSE).
|
package/README.zh-CN.md
ADDED
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
# grdpwasm
|
|
2
|
+
|
|
3
|
+
[English](README.md) | 中文说明
|
|
4
|
+
|
|
5
|
+
基于 Go WebAssembly 与 [grdp](https://github.com/nakagami/grdp) 构建的网页版 RDP 客户端。
|
|
6
|
+
在浏览器里直连 Windows 远程桌面——无需任何插件。
|
|
7
|
+
|
|
8
|
+
> **本仓库是 [nakagami/grdpwasm](https://github.com/nakagami/grdpwasm) 的 `aiti-aigrdpwasm` fork**,
|
|
9
|
+
> 在上游之上带有一个补丁版 grdp vendor fork 及多层功能/修复,详见下方
|
|
10
|
+
> [本 fork 更新说明](#本-fork-更新说明)。
|
|
11
|
+
> 已发布为 npm 包 [`@aiti-ai/grdpwasm`](https://www.npmjs.com/package/@aiti-ai/grdpwasm)。
|
|
12
|
+
|
|
13
|
+
## 本 fork 更新说明
|
|
14
|
+
|
|
15
|
+
### xrdp / gnome-remote-desktop 兼容
|
|
16
|
+
|
|
17
|
+
- 内置补丁版 grdp fork(`third_party/grdp`):planar codec 常量修复;能力集广播裁剪到本客户端能真正
|
|
18
|
+
支持的范围(不广播 SURFACE_COMMANDS、frame marker、bitmap-cache REV2);NSCodec 捕获检测用于
|
|
19
|
+
服务器类型判别;全屏刷新恢复初始画面损伤;ECDSA CredSSP 公钥回显;fast-path 输入 PDU 8 字节对齐;
|
|
20
|
+
NLA 失败返回明确错误信息。
|
|
21
|
+
- EGFX 自动协商:先带 GFX 连接;若服务器实际编码本客户端无法解码(xrdp 只发 progressive/planar),
|
|
22
|
+
自动以兼容模式重连一次。GDS/Windows(H.264)正常连接,无感知。
|
|
23
|
+
- 无损 WASM 传输层:收包队列既不阻塞 JS 线程也不丢消息(丢包 = 流失步 → 花屏/断连);突发期内存
|
|
24
|
+
由桥的背压机制约束有界。
|
|
25
|
+
|
|
26
|
+
### 前端
|
|
27
|
+
|
|
28
|
+
- **fixedTarget 模式**:目标 host/port 由服务端提供(注入 `__rdpTarget`)或经 `?fixedTarget=true` 传入,
|
|
29
|
+
前端不可篡改;standalone 模式保留自由连接表单。
|
|
30
|
+
- 虚拟键盘(程序员布局)、快捷键条、原生系统键盘代理、X11/RFB keysym 工具——载体无关公共组件。
|
|
31
|
+
- xrdp 彩色光标缓解:AND 掩码导致整个矩形全不透明的光标会渲染成黑块,检测到(不透明占比 ≥95%)即丢弃。
|
|
32
|
+
|
|
33
|
+
### 打包与分发(@aiti-ai/grdpwasm)
|
|
34
|
+
|
|
35
|
+
- 已发布为 npm 包。tarball 里带 `main.wasm`(jsDelivr/unpkg 分发的源头),但 postinstall 在安装后即删除
|
|
36
|
+
本地副本——运行时页面经 [justget](https://github.com/justdb/justget) 从 CDN 竞速下载 wasm,同源兜底
|
|
37
|
+
(覆盖方式:`?wasm=<url>` 或 `localStorage['grdpwasm.wasmUrl']`)。
|
|
38
|
+
- 面向嵌入方的服务端兜底:后端可按 `ensureRdpWasm` 模式把 wasm 预取到缓存目录,静态服务随时有得 serve。
|
|
39
|
+
|
|
40
|
+
## 架构
|
|
41
|
+
|
|
42
|
+
```
|
|
43
|
+
浏览器 (WASM) ──WebSocket──► proxy (Go) ──TCP──► RDP 服务器
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
浏览器无法直接开 TCP socket,由一个轻量 Go 代理把浏览器的 WebSocket 连接桥接到
|
|
47
|
+
RDP 服务器的 TCP 端口。
|
|
48
|
+
|
|
49
|
+
## 环境要求
|
|
50
|
+
|
|
51
|
+
- Go 1.24 或更高
|
|
52
|
+
- 一台可达的 RDP 服务器(Windows 或任何 RDP 兼容主机)
|
|
53
|
+
|
|
54
|
+
## 构建
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
git clone https://github.com/nakagami/grdpwasm.git
|
|
58
|
+
cd grdpwasm
|
|
59
|
+
make all
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
`make all` 产物:
|
|
63
|
+
|
|
64
|
+
| 产物 | 说明 |
|
|
65
|
+
|---|---|
|
|
66
|
+
| `static/main.wasm` | Go WASM 二进制(跑在浏览器里) |
|
|
67
|
+
| `static/wasm_exec.js` | Go 运行时 JS 支撑文件 |
|
|
68
|
+
| `proxy/proxy` | WebSocket↔TCP 代理 + 静态文件服务 |
|
|
69
|
+
|
|
70
|
+
## 运行
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
make serve
|
|
74
|
+
# 或者等价手动启动:
|
|
75
|
+
./proxy/proxy -listen :8080 -static static
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
然后用浏览器打开 **http://localhost:8080**。
|
|
79
|
+
|
|
80
|
+
### 代理参数
|
|
81
|
+
|
|
82
|
+
| 参数 | 默认值 | 说明 |
|
|
83
|
+
|---|---|---|
|
|
84
|
+
| `-listen` | `:8080` | 监听地址与端口 |
|
|
85
|
+
| `-static` | `static` | 静态文件目录 |
|
|
86
|
+
|
|
87
|
+
## 使用
|
|
88
|
+
|
|
89
|
+
1. 浏览器打开 `http://localhost:8080`。
|
|
90
|
+
2. 填写连接表单:
|
|
91
|
+
- **Host** — RDP 服务器主机名或 IP
|
|
92
|
+
- **Port** — RDP 端口(默认 `3389`)
|
|
93
|
+
- **Domain** — Windows 域(本地账号留空)
|
|
94
|
+
- **User** — 用户名
|
|
95
|
+
- **Password** — 密码
|
|
96
|
+
- **Width / Height** — 初始桌面分辨率
|
|
97
|
+
3. 点击 **Connect**。
|
|
98
|
+
4. 远程桌面出现在画布里;点击画布捕获键盘焦点。
|
|
99
|
+
5. 点击 **Disconnect** 结束会话。
|
|
100
|
+
|
|
101
|
+
## 键盘与鼠标
|
|
102
|
+
|
|
103
|
+
所有标准键盘输入经 RDP 扫描码转发到远程桌面。鼠标移动、按键点击、滚轮完整支持。
|
|
104
|
+
|
|
105
|
+
> **注意:** 浏览器标签页必须持有焦点,键盘事件才会转发。按键无响应时请点击画布区域。
|
|
106
|
+
|
|
107
|
+
## 音频
|
|
108
|
+
|
|
109
|
+
远程音频经 RDPSND 流式传输,通过浏览器 Web Audio API 播放
|
|
110
|
+
(PCM 44100 Hz、立体声、16 位有符号小端)。
|
|
111
|
+
|
|
112
|
+
## 安全须知
|
|
113
|
+
|
|
114
|
+
- 代理接受任意来源的连接。请只在可信网络运行,或先加认证再暴露到公网。
|
|
115
|
+
- 凭据经 WebSocket 从浏览器传到代理。跨不可信网络访问时请使用 HTTPS/WSS
|
|
116
|
+
(把代理放在 nginx/Caddy 等 TLS 终结反代之后)。
|
|
117
|
+
|
|
118
|
+
## 开发
|
|
119
|
+
|
|
120
|
+
```
|
|
121
|
+
npm install # 安装 JS 依赖(justget、esbuild)
|
|
122
|
+
make wasm # 只重编 WASM 二进制
|
|
123
|
+
make proxy # 只重编代理服务
|
|
124
|
+
make wasm_exec # 用本地 Go 工具链刷新 wasm_exec.js
|
|
125
|
+
npm run build:vendor # 从已安装的 justget 重编 static/vendor/justget.browser.js
|
|
126
|
+
make clean # 清理全部构建产物
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
## npm 包
|
|
130
|
+
|
|
131
|
+
把前端资产发布为 `@aiti-ai/grdpwasm`。消费者装到除 `main.wasm` 外的全部文件——
|
|
132
|
+
页面运行时自行从 CDN 拉取。
|
|
133
|
+
|
|
134
|
+
```bash
|
|
135
|
+
npm run build:vendor # 把 justget/browser 打包进 static/vendor/
|
|
136
|
+
make all # 构建 main.wasm + wasm_exec.js + proxy
|
|
137
|
+
npm publish # prepack 会把版本号同步进 index.html;tarball 带 wasm
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
安装方拿到的是不含 `main.wasm` 的 `static/`(html/js/vendor)——页面运行时从 CDN 拉取。
|
|
141
|
+
如需保留本地副本,安装前设置 `GRDPWASM_KEEP_WASM=1`。
|
|
142
|
+
|
|
143
|
+
## 许可证
|
|
144
|
+
|
|
145
|
+
GPLv3 —— 见 [grdp LICENSE](https://github.com/nakagami/grdp/blob/master/LICENSE)。
|
package/package.json
CHANGED
|
@@ -1,6 +1,29 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aiti-ai/grdpwasm",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
|
|
3
|
+
"version": "0.2.2",
|
|
4
|
+
"description": "Web-based RDP client (Go WASM + WebSocket proxy) — browser assets; main.wasm fetched from CDN at runtime via justget",
|
|
5
|
+
"license": "GPL-3.0",
|
|
6
|
+
"homepage": "https://github.com/aiti-ai/aiti-aigrdpwasm#readme",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "git+https://github.com/aiti-ai/aiti-aigrdpwasm.git"
|
|
10
|
+
},
|
|
11
|
+
"files": [
|
|
12
|
+
"static/",
|
|
13
|
+
"scripts/",
|
|
14
|
+
"README.md",
|
|
15
|
+
"LICENSE"
|
|
16
|
+
],
|
|
17
|
+
"scripts": {
|
|
18
|
+
"prepack": "node scripts/sync-version.mjs",
|
|
19
|
+
"postinstall": "node scripts/postinstall.mjs",
|
|
20
|
+
"build:vendor": "esbuild node_modules/justget/dist/browser/index.js --bundle --format=iife --global-name=justget --minify --outfile=static/vendor/justget.browser.js"
|
|
21
|
+
},
|
|
22
|
+
"dependencies": {
|
|
23
|
+
"justget": "^0.2.4"
|
|
24
|
+
},
|
|
25
|
+
"devDependencies": {
|
|
26
|
+
"esbuild": "^0.28.2"
|
|
27
|
+
},
|
|
28
|
+
"bugs": "https://github.com/aiti-ai/aiti-aigrdpwasm/issues"
|
|
29
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* postinstall: remove main.wasm (~11MB) from the installed copy.
|
|
3
|
+
*
|
|
4
|
+
* The npm tarball ships the wasm (that's what jsDelivr/unpkg serve from), but at
|
|
5
|
+
* runtime the page race-downloads it from CDNs via justget — no need to keep a
|
|
6
|
+
* local copy, so delete it right after install to save disk.
|
|
7
|
+
*
|
|
8
|
+
* Skipped when:
|
|
9
|
+
* - inside a source checkout (.git exists): running `npm install` in the repo
|
|
10
|
+
* triggers this lifecycle hook too; dev build artifacts must survive;
|
|
11
|
+
* - GRDPWASM_KEEP_WASM=1 is set explicitly.
|
|
12
|
+
*/
|
|
13
|
+
import { existsSync, rmSync, statSync } from "node:fs";
|
|
14
|
+
import { dirname, join } from "node:path";
|
|
15
|
+
import { fileURLToPath } from "node:url";
|
|
16
|
+
|
|
17
|
+
const root = join(dirname(fileURLToPath(import.meta.url)), "..");
|
|
18
|
+
const wasm = join(root, "static", "main.wasm");
|
|
19
|
+
|
|
20
|
+
if (process.env.GRDPWASM_KEEP_WASM === "1") {
|
|
21
|
+
console.log("[grdpwasm] GRDPWASM_KEEP_WASM=1, keep static/main.wasm");
|
|
22
|
+
} else if (existsSync(join(root, ".git"))) {
|
|
23
|
+
console.log("[grdpwasm] source checkout detected (.git), keep static/main.wasm");
|
|
24
|
+
} else if (existsSync(wasm)) {
|
|
25
|
+
const mb = (statSync(wasm).size / 1048576).toFixed(1);
|
|
26
|
+
rmSync(wasm);
|
|
27
|
+
console.log(`[grdpwasm] removed static/main.wasm (${mb} MB) - runtime fetches from CDN`);
|
|
28
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* prepack: sync the package.json version into PKG_VERSION inside
|
|
3
|
+
* static/index.html so the runtime CDN URLs always match the published version.
|
|
4
|
+
*/
|
|
5
|
+
import { readFileSync, writeFileSync } from "node:fs";
|
|
6
|
+
import { dirname, join } from "node:path";
|
|
7
|
+
import { fileURLToPath } from "node:url";
|
|
8
|
+
|
|
9
|
+
const root = join(dirname(fileURLToPath(import.meta.url)), "..");
|
|
10
|
+
const { version } = JSON.parse(readFileSync(join(root, "package.json"), "utf8"));
|
|
11
|
+
|
|
12
|
+
const html = join(root, "static", "index.html");
|
|
13
|
+
const src = readFileSync(html, "utf8");
|
|
14
|
+
if (!/const PKG_VERSION = "[^"]*";/.test(src)) {
|
|
15
|
+
console.error("[grdpwasm] PKG_VERSION placeholder not found in index.html");
|
|
16
|
+
process.exit(1);
|
|
17
|
+
}
|
|
18
|
+
const next = src.replace(
|
|
19
|
+
/const PKG_VERSION = "[^"]*";/,
|
|
20
|
+
`const PKG_VERSION = "${version}";`
|
|
21
|
+
);
|
|
22
|
+
if (next !== src) writeFileSync(html, next);
|
|
23
|
+
console.log(`[grdpwasm] index.html PKG_VERSION -> ${version}`);
|