Skip to content

Commit 8157616

Browse files
authored
Merge branch 'main' into refactor-alignment
2 parents af6eb5f + ebaf397 commit 8157616

11 files changed

Lines changed: 546 additions & 243 deletions

File tree

.github/workflows/benchmark.yml

Lines changed: 118 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -9,40 +9,146 @@ on:
99
# performance analysis in order to generate initial data.
1010
workflow_dispatch:
1111

12-
permissions:
13-
contents: read
14-
id-token: write
12+
permissions: {}
13+
14+
concurrency:
15+
group: ${{ github.workflow }}-${{ github.ref }}
16+
cancel-in-progress: true
1517

1618
jobs:
17-
benchmarks:
18-
name: Run benchmarks
19+
build:
20+
name: Build
1921
runs-on: ubuntu-latest
20-
22+
permissions:
23+
contents: read # clone repo
2124
steps:
2225
- name: Checkout
23-
uses: actions/checkout@v4
26+
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
2427
with:
2528
submodules: true
29+
persist-credentials: false
2630

2731
- name: Setup Deno
28-
uses: denoland/setup-deno@v2
32+
uses: denoland/setup-deno@667a34cdef165d8d2b2e98dde39547c9daac7282 # v2.0.4
2933
with:
3034
deno-version: v2.x
3135

32-
- name: Setup Node
33-
uses: actions/setup-node@v4
36+
- name: Cache WASM
37+
uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
38+
id: wasm-cache
3439
with:
35-
node-version: 22
40+
path: |
41+
clayterm.wasm
42+
wasm.ts
43+
key: wasm-${{ hashFiles('Makefile', 'src/**', 'tasks/bundle-wasm.ts') }}
3644

3745
- name: Build WASM
46+
if: steps.wasm-cache.outputs.cache-hit != 'true'
3847
run: make
3948

49+
- name: Cache dependencies
50+
uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
51+
id: deno-cache
52+
with:
53+
path: node_modules
54+
key: deno-${{ hashFiles('deno.lock') }}
55+
56+
- name: Install dependencies
57+
if: steps.deno-cache.outputs.cache-hit != 'true'
58+
run: deno install
59+
60+
- name: Upload build artifact
61+
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
62+
with:
63+
name: bench-build
64+
retention-days: 1
65+
path: wasm.ts
66+
67+
simulation:
68+
name: Run benchmarks (simulation)
69+
needs: build
70+
runs-on: ubuntu-latest
71+
permissions:
72+
contents: read # clone repo
73+
id-token: write # upload benchmark results to codspeed
74+
75+
steps:
76+
- name: Checkout
77+
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
78+
79+
- name: Setup Deno
80+
uses: denoland/setup-deno@667a34cdef165d8d2b2e98dde39547c9daac7282 # v2.0.4
81+
with:
82+
deno-version: v2.x
83+
84+
- name: Setup Node
85+
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
86+
with:
87+
node-version: 24
88+
89+
- name: Download build artifact
90+
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
91+
with:
92+
name: bench-build
93+
94+
- name: Restore dependencies
95+
uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
96+
id: deno-cache
97+
with:
98+
path: node_modules
99+
key: deno-${{ hashFiles('deno.lock') }}
100+
40101
- name: Install dependencies
102+
if: steps.deno-cache.outputs.cache-hit != 'true'
41103
run: deno install
42104

43105
- name: Run benchmarks
44-
uses: CodSpeedHQ/action@v4
106+
uses: CodSpeedHQ/action@9d332c4d90b43981c3e55ae8e38e68709996240f # v4.17.0
45107
with:
46108
mode: simulation
47109
# IMPORTANT! deno task bench fails in CI due to incompatible V8 bindings
48110
run: node bench/mod.ts
111+
112+
walltime:
113+
name: Run benchmarks (walltime)
114+
needs: build
115+
runs-on: codspeed-macro
116+
permissions:
117+
contents: read # clone repo
118+
id-token: write # upload benchmark results to codspeed
119+
120+
steps:
121+
- name: Checkout
122+
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
123+
124+
- name: Setup Deno
125+
uses: denoland/setup-deno@667a34cdef165d8d2b2e98dde39547c9daac7282 # v2.0.4
126+
with:
127+
deno-version: v2.x
128+
129+
- name: Setup Node
130+
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
131+
with:
132+
node-version: 24
133+
134+
- name: Download build artifact
135+
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
136+
with:
137+
name: bench-build
138+
139+
- name: Restore dependencies
140+
uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
141+
id: deno-cache
142+
with:
143+
path: node_modules
144+
key: deno-codspeed-${{ runner.arch }}-${{ hashFiles('deno.lock') }}
145+
146+
- name: Install dependencies
147+
if: steps.deno-cache.outputs.cache-hit != 'true'
148+
run: deno install
149+
150+
- name: Run process startup benchmarks
151+
uses: CodSpeedHQ/action@9d332c4d90b43981c3e55ae8e38e68709996240f # v4.17.0
152+
with:
153+
mode: walltime
154+
run: node bench/startup.bench.ts

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,8 @@ for consumers.
2323

2424
### Examples
2525

26-
The application in this demo uses Clayterm for all layout and input parsing
26+
See this keyboard example and more in the [examples folder](examples/README.md).
27+
This demo uses Clayterm for all layout and input parsing.
2728

2829
#### Keyboard Events
2930

bench/fixtures/create-term/mod.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
import { createTerm } from "../../../term.ts";
2+
3+
await createTerm({ width: 80, height: 24 });
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import { createTerm } from "../../../term.ts";
2+
import { close, grow, open, text } from "../../../ops.ts";
3+
4+
let term = await createTerm({ width: 80, height: 24 });
5+
term.render([
6+
open("root", { layout: { width: grow(), height: grow(), direction: "ttb" } }),
7+
text("Hello, World!"),
8+
close(),
9+
]);

bench/fixtures/utils.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import { fileURLToPath } from "node:url";
2+
import { spawn } from "node:child_process";
3+
4+
export const fixture = (name: string) => {
5+
return new URL(`./${name}/mod.ts`, import.meta.url);
6+
};
7+
8+
export const spawnFixture = (name: string): Promise<void> =>
9+
new Promise((resolve) => {
10+
spawn(process.execPath, [
11+
...process.execArgv,
12+
fileURLToPath(fixture(name)),
13+
], { stdio: "ignore" }).on("close", resolve);
14+
});

bench/startup.bench.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import { Bench } from "tinybench";
2+
import { withCodSpeed } from "@codspeed/tinybench-plugin";
3+
import { spawnFixture } from "./fixtures/utils.ts";
4+
5+
let bench = withCodSpeed(new Bench({ name: "startup" }));
6+
7+
bench
8+
.add("createTerm", () => spawnFixture("create-term"))
9+
.add("time to first render", () => spawnFixture("render-minimal"));
10+
11+
await bench.run();
12+
console.table(bench.table());

examples/README.md

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@ with information about your terminal, shell, operating system and any other
66
information that could be pertinent to reproducing the issue.
77

88
> [!NOTE]
9-
> Run the commands in this document from the repository root.
9+
> Run the commands in this document from the repository root. These examples use
10+
> `node:` terminal APIs so the same files can be run with either Deno or Node.
1011
1112
## Prerequisites
1213

@@ -24,6 +25,8 @@ Run it with:
2425

2526
```sh
2627
deno run examples/keyboard/index.ts
28+
# or
29+
node examples/keyboard/index.ts
2730
```
2831

2932
What it shows:
@@ -40,6 +43,20 @@ Related files:
4043
events
4144
- `examples/keyboard/use-stdin.ts` adapts stdin into a byte stream for the demo
4245

46+
#### Keyboard Events
47+
48+
The input parser decodes raw terminal bytes into structured events. Here you can
49+
see each key event as the string "hello world" is typed.
50+
51+
![Keyboard events demo](keyboard/keyboard-key-events.gif)
52+
53+
#### Pointer Events
54+
55+
Here we see hover styles applied to UI elements in response to the pointer
56+
state. Clay drives the hit testing; no manual coordinate math required.
57+
58+
![Pointer events demo](keyboard/keyboard-pointer-events.gif)
59+
4360
## Inline Regions
4461

4562
Path: `examples/inline-regions/index.ts`
@@ -48,12 +65,15 @@ Run it with:
4865

4966
```sh
5067
deno run examples/inline-regions/index.ts
68+
# or
69+
node examples/inline-regions/index.ts
5170
```
5271

5372
What it shows:
5473

5574
- rendering animated regions into normal terminal scrollback
56-
- querying cursor position with DSR to place later frames correctly
75+
- querying cursor position with Device Status Report (DSR) to place later frames
76+
correctly
5777
- updating a previously allocated region without taking over the whole screen
5878
- small animated demos including a spinner, a progress bar, and a nyan-cat-style
5979
sequence

0 commit comments

Comments
 (0)