@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 +216 -9
- package/binaries/darwin-arm64/gox +0 -0
- package/binaries/darwin-x64/gox +0 -0
- package/binaries/linux-arm64/gox +0 -0
- package/binaries/linux-x64/gox +0 -0
- package/binaries/windows-x64/gox.exe +0 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,16 +1,223 @@
|
|
|
1
1
|
# @goxjs/goxjs
|
|
2
2
|
|
|
3
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
396
|
+
### License
|
|
190
397
|
|
|
191
|
-
[
|
|
398
|
+
[MIT License](https://github.com/14752222/Gox/blob/main/LICENSE)
|
|
Binary file
|
package/binaries/darwin-x64/gox
CHANGED
|
Binary file
|
package/binaries/linux-arm64/gox
CHANGED
|
Binary file
|
package/binaries/linux-x64/gox
CHANGED
|
Binary file
|
|
Binary file
|