@goxjs/goxjs 0.7.0 → 0.8.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.
package/README.md CHANGED
@@ -1,16 +1,223 @@
1
1
  # @goxjs/goxjs
2
2
 
3
- > Gox JavaScript Runtime — 用 Go 从零实现的 JavaScript 运行时:词法分析 → 语法分析 → 字节码编译 → 栈式虚拟机执行。单二进制、零外部依赖。
3
+ **English** | [简体中文](#简体中文)
4
+
5
+ > Gox JavaScript Runtime — built from scratch in Go: lexer → parser → bytecode compiler → stack VM. Single binary, zero external dependencies.
6
+
7
+ This package distributes Gox's platform binaries via npm. Installing it gives you the `goxjs` command.
8
+
9
+ ## Install
10
+
11
+ ```bash
12
+ npm i -g @goxjs/goxjs
13
+ ```
14
+
15
+ ## Usage
16
+
17
+ **REPL:**
18
+
19
+ ```bash
20
+ goxjs
21
+ ```
22
+
23
+ ```
24
+ Gox REPL (ES6 subset, no var)
25
+ Type :exit to quit, :help for help
26
+
27
+ > let x = 10
28
+ > [1, 2, 3].map(v => v * 2)
29
+ [2, 4, 6]
30
+ ```
31
+
32
+ **Run a script:**
33
+
34
+ ```bash
35
+ goxjs app.js
36
+ ```
37
+
38
+ **Run without installing:**
39
+
40
+ ```bash
41
+ npx goxjs app.js
42
+ ```
43
+
44
+ Supports the ES6+ language subset (`let`/`const`, classes, `async`/`await`, destructuring, template literals, ES modules), standard objects such as `Array` / `Map` / `Set` / `Promise` / `BigInt` / `Temporal`, and Node-style host APIs including `fs` / `http` / `fetch` / `path` / `process`.
45
+
46
+ ## Declarative UI (GUI)
47
+
48
+ `gx/gfx` is a pure-Go, self-drawn windowing layer; you write the UI in JSX. Bindings, lists, and conditionals are **element-level directives** (written on the element, no import needed):
49
+
50
+ ```jsx
51
+ import { h, render, createSignal, Switch, Match } from "gox";
52
+
53
+ const [name, setName] = createSignal("");
54
+ const [rows, setRows] = createSignal([{ id: "a", title: "Alpha" }]);
55
+ const [open, setOpen] = createSignal(true);
56
+ const [phase, setPhase] = createSignal("loading");
57
+
58
+ render(
59
+ <window title="app" width={420} height={260}>
60
+ <column gap={8} padding={12}>
61
+ <input model={name} /> {/* two-way binding */}
62
+ <view each={rows} key="id">{(row) => <text>{row.title}</text>}</view> {/* list: keyed reuse */}
63
+ <view show={open} fallback={<text>Hidden</text>}>Visible content</view> {/* conditional: kept alive */}
64
+ <Switch fallback={<text>Unknown state</text>}> {/* multi-branch */}
65
+ <Match when={() => phase() === "loading"}><text>Loading…</text></Match>
66
+ </Switch>
67
+ </column>
68
+ </window>
69
+ );
70
+ ```
71
+
72
+ - `model` — two-way binding for controlled components (like Vue's `v-model`): `input` / `textarea` / `slider` / `select` read and write `value`, `checkbox` / `switch` read and write `checked`, and `radio` writes its `value` attribute into the model when selected. You can also pass a `[get, set]` pair to wire up a custom source.
73
+ - `each` — list rendering: rows with the **same key + same row reference + same index** are reused as-is (inputs, scroll positions, and local signals inside the row are preserved); only rows that actually changed are rebuilt. Supports `stable` / `fallback` / `key="id"`.
74
+ - `show` — conditional visibility with **keep-alive**: hiding merely removes the subtree from layout flow; showing it again is instantaneous (no destroy/rebuild).
75
+ - `view` — a layout-transparent container (Fragment); the directive repeats/hides whichever element carries it.
76
+
77
+ > **Breaking change since 0.3.0**: the `<For>` / `<Show>` components have been removed —
78
+ > `<For each={x} key={k}>…</For>` → `<view each={x} key={k}>…</view>`,
79
+ > `<Show when={x} fallback={f}>…</Show>` → `<view show={x} fallback={f}>…</view>`.
80
+ > `gx/view` now only exports `Switch` / `Match`.
81
+
82
+ GUI examples (40+ runnable demos live in the repo's `testdata/` directory):
83
+
84
+ ```bash
85
+ goxjs testdata/view_demo2.js # list reuse / conditional keep-alive / multi-branch
86
+ goxjs testdata/model_demo.js # two-way binding across all eight control types
87
+ goxjs testdata/router_demo.js # route table / param matching / three-level guards / lazy loading
88
+ ```
89
+
90
+ ## Router & Screens (`gx/router` / `gx/screen`)
91
+
92
+ **New in 0.4.0**: no more hand-rolled signal-based page switching —
93
+
94
+ ```jsx
95
+ import { h, render } from "gx/gfx";
96
+ import { createRouter, RouterView, RouterLink } from "gx/router";
97
+
98
+ function HomePage() { return <text font={15}>home</text>; }
99
+ function ListPage() { return <text font={15}>list</text>; }
100
+ function DetailPage(props) { return <text font={15}>{"detail id=" + props.param.id}</text>; }
101
+
102
+ const router = createRouter({
103
+ routes: [
104
+ { path: "/", name: "home", component: HomePage },
105
+ { path: "/list", name: "list", component: ListPage, keepAlive: true },
106
+ { path: "/detail/:id", name: "detail", component: DetailPage },
107
+ { path: "*", name: "nf", component: HomePage },
108
+ ],
109
+ initial: "/",
110
+ });
111
+
112
+ render(
113
+ <window title="app" width={480} height={360}>
114
+ <column gap={8} padding={12}>
115
+ <text font={12}>{() => "route: " + router.currentRoute().path}</text>
116
+ <row gap={10}>
117
+ <RouterLink to="/list"><text font={13}>List</text></RouterLink>
118
+ <RouterLink to={{ name: "detail", params: { id: 7 } }}><text font={13}>Detail</text></RouterLink>
119
+ </row>
120
+ <RouterView />
121
+ </column>
122
+ </window>
123
+ );
124
+ ```
125
+
126
+ Out of the box: `:param` / `:param?` / `*` matching (priority independent of declaration order), three levels of guards
127
+ (`beforeEach` / `beforeEnter` / `beforeRouteLeave` …, may return a Promise for async), `push` returning a
128
+ Promise (`{ok:false, reason}` expresses interception), `Alt+←` / `Alt+→` back/forward, `lazy(() => import(…))`
129
+ lazy loading, **two tiers of state preservation** (route records with `keepAlive: true` preserve the whole subtree;
130
+ `useRouteState()` stores values),
131
+ per-window independent navigation stacks and `sync()` sync groups (mirror / share / follow).
132
+
133
+ `gx/screen` provides display enumeration, the window's screen, and fold-posture reporting; **when half-folded,
134
+ `RouterView` automatically switches to two panes**
135
+ (the previous entry in the left pane's history, typically the list).
136
+
137
+ > Three deliberate differences from browser routing: **no URL and no history mode** (desktop apps have no address
138
+ > bar; "history" is an in-memory stack); `to` is always resolved as an **absolute path**; regex path constraints /
139
+ > `alias` / relative paths are not supported — validate params in `beforeEnter`. Windows / X11 have no fold-posture
140
+ > query API — the framework only provides the `reportPosture()` channel and never guesses; with no reporter the
141
+ > screen stays permanently unfolded.
142
+ >
143
+ > Full manual: [`docs/gui-router.md`](https://github.com/14752222/Gox/blob/main/docs/gui-router.md).
144
+
145
+ ## Native capability layer (`gx/device` · `gx/app` · `gx/geo` · `gx/media` · `gx/permission` · `gx/viewport`)
146
+
147
+ **New in 0.5.0**: device info, battery, network, location, camera / photo album, permissions, safe area and soft
148
+ keyboard — six modules share one host contract with only three call shapes:
149
+
150
+ ```js
151
+ import { deviceInfo, battery, isOnline, canIUse } from "gx/device"; // pull-type + report-type
152
+ import { getLocation, watchLocation } from "gx/geo";
153
+ import { takePhoto } from "gx/media"; // action-type
154
+
155
+ const info = deviceInfo(); // synchronously available
156
+ console.log(info.platform, info.model, battery().level + "%", isOnline());
157
+ // battery() / isOnline() read snapshots; useBattery() returns a getter that refreshes when the host reports
158
+
159
+ if (canIUse("camera")) { // check capability up front; don't rely on catch
160
+ const photo = await takePhoto({ count: 1 }); // failures reject with an errCode
161
+ }
162
+
163
+ const stop = watchLocation((loc) => console.log(loc.latitude, loc.longitude));
164
+ try {
165
+ await getLocation({ highAccuracy: true });
166
+ } catch (e) {
167
+ if (e.errCode === "permission-denied") console.warn(e.message);
168
+ }
169
+ ```
170
+
171
+ - **Three shapes**: pull-type (sync read) · action-type (`await`, rejects on failure) · report-type (host pushes
172
+ updates, `useXxx()` refreshes reactively).
173
+ - **No soft fallback for missing capabilities**: action-type calls always reject; there are eight error codes
174
+ (`unsupported` / `permission-denied` / `cancelled` / `timeout` / `busy` / `unavailable` / `platform-error` /
175
+ `invalid-arg`) — check with `canIUse()` first. Only purely report-type states get explicit defaults when nobody
176
+ reports.
177
+ - **Desktop vs mobile**: desktop backends implement what they can (battery / network / brightness / screen
178
+ keep-awake / opening system settings) and honestly report `unsupported` for the rest (no fake data); a mobile
179
+ native shell implements the same `NativeHost` contract to plug in, without touching the core.
180
+ - **`gx/screen` vs `gx/viewport`**: the former is the device (displays / posture / hinge), the latter is the window
181
+ (safe area / soft keyboard / split-screen form).
182
+
183
+ Demo: `goxjs testdata/native_demo.js`. Semantics and export tables:
184
+ [`docs/gui-guide.md` §9.6](https://github.com/14752222/Gox/blob/main/docs/gui-guide.md#96-原生能力层).
185
+
186
+ ## 0.6.0 Release Notes
187
+
188
+ - **GUI on all platforms**: the macOS window backend (cocoa, driving AppKit via purego in pure Go) has landed —
189
+ desktop GUI now works on Windows / macOS / Linux, and the npm prebuilt binaries include it out of the box.
190
+ - **Developer workflow**: `gox dev [entry.js]` hot reload (watches `.js` changes under `src/`, rebuilds the VM and
191
+ reruns the entry); `gox.json` project config; `gox build <android|ios|windows|macos>` unified build entry (with
192
+ permission injection and icon generation built in); `gox icon` / `gox sync` also work standalone.
193
+ - **Language**: async arrow functions (`async () => {}`, `this` stays lexical); `for (const [a, b] of pairs)`
194
+ destructuring bindings; trailing commas in argument/parameter lists.
195
+ - **Fixes**: circular-import stack overflow, JSX default factory missed in module mode, nested destructuring
196
+ parsing, solid notifications re-triggering every pass, and more.
197
+
198
+ Full docs and language examples: [GitHub repository](https://github.com/14752222/Gox).
199
+
200
+ ## License
201
+
202
+ [MIT License](https://github.com/14752222/Gox/blob/main/LICENSE)
203
+
204
+ ---
205
+
206
+ ## 简体中文
207
+
208
+ **[English](#goxjsgoxjs) | 简体中文**
209
+
210
+ > Gox JavaScript 运行时 — 用 Go 从零实现:词法分析 → 语法分析 → 字节码编译 → 栈式虚拟机执行。单二进制、零外部依赖。
4
211
 
5
212
  本包把 Gox 的各平台二进制分发到 npm,安装后直接获得 `goxjs` 命令。
6
213
 
7
- ## 安装
214
+ ### 安装
8
215
 
9
216
  ```bash
10
217
  npm i -g @goxjs/goxjs
11
218
  ```
12
219
 
13
- ## 使用
220
+ ### 使用
14
221
 
15
222
  **REPL:**
16
223
 
@@ -41,7 +248,7 @@ npx goxjs app.js
41
248
 
42
249
  支持 ES6+ 语言子集(`let`/`const`、class、`async`/`await`、解构、模板字符串、ES 模块),内置 `Array` / `Map` / `Set` / `Promise` / `BigInt` / `Temporal` 等标准对象,以及 `fs` / `http` / `fetch` / `path` / `process` 等 Node 风格宿主 API。
43
250
 
44
- ## 声明式界面(GUI)
251
+ ### 声明式界面(GUI)
45
252
 
46
253
  `gx/gfx` 是纯 Go 自绘的窗口层,界面用 JSX 写。绑定、列表、条件都是**元素级指令**(写在元素上,不需要 import):
47
254
 
@@ -85,7 +292,7 @@ goxjs testdata/model_demo.js # 八类受控组件的双向绑定
85
292
  goxjs testdata/router_demo.js # 路由表 / 参数匹配 / 三级守卫 / 懒加载
86
293
  ```
87
294
 
88
- ## 路由与屏幕(`gx/router` / `gx/screen`)
295
+ ### 路由与屏幕(`gx/router` / `gx/screen`)
89
296
 
90
297
  **0.4.0 新增模块**:路由不用再自己手写 signal 切页了 ——
91
298
 
@@ -137,7 +344,7 @@ Promise(`{ok:false, reason}` 表达被拦截)、`Alt+←` / `Alt+→` 后退
137
344
  >
138
345
  > 完整手册:[`docs/gui-router.md`](https://github.com/14752222/Gox/blob/main/docs/gui-router.md)。
139
346
 
140
- ## 原生能力层(`gx/device` · `gx/app` · `gx/geo` · `gx/media` · `gx/permission` · `gx/viewport`)
347
+ ### 原生能力层(`gx/device` · `gx/app` · `gx/geo` · `gx/media` · `gx/permission` · `gx/viewport`)
141
348
 
142
349
  **0.5.0 新增模块**:设备信息、电量、网络、定位、相机 / 相册、权限、安全区与软键盘 —— 六个模块
143
350
  共用一个宿主契约,调用形态只有三种:
@@ -177,7 +384,7 @@ try {
177
384
  演示:`goxjs testdata/native_demo.js`。语义与导出表见
178
385
  [`docs/gui-guide.md` §9.6](https://github.com/14752222/Gox/blob/main/docs/gui-guide.md#96-原生能力层)。
179
386
 
180
- ## 0.6.0 更新
387
+ ### 0.6.0 更新
181
388
 
182
389
  - **GUI 全平台**:macOS 窗口后端(cocoa,purego 纯 Go 驱动 AppKit)落地 —— 桌面 GUI 现在 Windows / macOS / Linux 三平台可用,npm 预编译二进制开箱即含。
183
390
  - **开发工作流**:`gox dev [入口.js]` 热更新(监听 `src/` 的 `.js` 变更,自动重建 VM 重跑入口);`gox.json` 项目配置;`gox build <android|ios|windows|macos>` 统一构建入口(自动完成权限注入与图标生成);`gox icon` / `gox sync` 也可独立使用。
@@ -186,6 +393,6 @@ try {
186
393
 
187
394
  完整文档与语言示例见 [GitHub 仓库](https://github.com/14752222/Gox)。
188
395
 
189
- ## License
396
+ ### License
190
397
 
191
- [Apache License 2.0](https://github.com/14752222/Gox/blob/main/LICENSE)
398
+ [MIT License](https://github.com/14752222/Gox/blob/main/LICENSE)
Binary file
Binary file
Binary file
Binary file
Binary file
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@goxjs/goxjs",
3
- "version": "0.7.0",
3
+ "version": "0.8.0",
4
4
  "description": "Gox — 用 Go 从零实现的 JavaScript 运行时(lexer → parser → 字节码 VM),单二进制零外部依赖",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {