@hex1b/web-terminal 0.1.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/LICENSE +21 -0
- package/README.md +243 -0
- package/dist/fonts/cascadia-mono-nf/CascadiaMonoNF.woff2 +0 -0
- package/dist/fonts/cascadia-mono-nf/LICENSE.txt +94 -0
- package/dist/fonts/cascadia-mono-nf/README.md +29 -0
- package/dist/history-state.d.ts +27 -0
- package/dist/history-state.d.ts.map +1 -0
- package/dist/history-state.js +194 -0
- package/dist/history-state.js.map +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -0
- package/dist/input-policy.d.ts +42 -0
- package/dist/input-policy.d.ts.map +1 -0
- package/dist/input-policy.js +143 -0
- package/dist/input-policy.js.map +1 -0
- package/dist/mouse-input.d.ts +26 -0
- package/dist/mouse-input.d.ts.map +1 -0
- package/dist/mouse-input.js +356 -0
- package/dist/mouse-input.js.map +1 -0
- package/dist/protocol.d.ts +17 -0
- package/dist/protocol.d.ts.map +1 -0
- package/dist/protocol.js +270 -0
- package/dist/protocol.js.map +1 -0
- package/dist/renderer.d.ts +113 -0
- package/dist/renderer.d.ts.map +1 -0
- package/dist/renderer.js +595 -0
- package/dist/renderer.js.map +1 -0
- package/dist/selection-input.d.ts +36 -0
- package/dist/selection-input.d.ts.map +1 -0
- package/dist/selection-input.js +69 -0
- package/dist/selection-input.js.map +1 -0
- package/dist/selection-ui.d.ts +24 -0
- package/dist/selection-ui.d.ts.map +1 -0
- package/dist/selection-ui.js +113 -0
- package/dist/selection-ui.js.map +1 -0
- package/dist/terminal-font.d.ts +23 -0
- package/dist/terminal-font.d.ts.map +1 -0
- package/dist/terminal-font.js +85 -0
- package/dist/terminal-font.js.map +1 -0
- package/dist/terminal-sizing.d.ts +8 -0
- package/dist/terminal-sizing.d.ts.map +1 -0
- package/dist/terminal-sizing.js +38 -0
- package/dist/terminal-sizing.js.map +1 -0
- package/dist/terminal-theme.d.ts +2 -0
- package/dist/terminal-theme.d.ts.map +1 -0
- package/dist/terminal-theme.js +39 -0
- package/dist/terminal-theme.js.map +1 -0
- package/dist/terminal-worker.d.ts +2 -0
- package/dist/terminal-worker.d.ts.map +1 -0
- package/dist/terminal-worker.js +285 -0
- package/dist/terminal-worker.js.map +1 -0
- package/dist/types.d.ts +312 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/validation.d.ts +3 -0
- package/dist/validation.d.ts.map +1 -0
- package/dist/validation.js +7 -0
- package/dist/validation.js.map +1 -0
- package/dist/web-terminal.d.ts +51 -0
- package/dist/web-terminal.d.ts.map +1 -0
- package/dist/web-terminal.js +728 -0
- package/dist/web-terminal.js.map +1 -0
- package/dist/wire-types.d.ts +218 -0
- package/dist/wire-types.d.ts.map +1 -0
- package/dist/wire-types.js +2 -0
- package/dist/wire-types.js.map +1 -0
- package/package.json +42 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024 Mitch Denny
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
# @hex1b/web-terminal
|
|
2
|
+
|
|
3
|
+
The first-party WebGPU browser terminal for Hex1b. It renders server-authoritative
|
|
4
|
+
cells and graphics in a module worker, with local input routing, producer-backed
|
|
5
|
+
history and selection, clipboard actions, and primary/secondary view sizing.
|
|
6
|
+
There are no runtime package dependencies.
|
|
7
|
+
|
|
8
|
+
**Experimental and paired with Hex1b:** this client speaks the evolving HWT1
|
|
9
|
+
transport implemented by the matching Hex1b server. HWT1 and internal browser
|
|
10
|
+
modules are not a supported third-party protocol or renderer API. The bootstrap
|
|
11
|
+
npm version `0.1.0` must be paired with the server build from the **same
|
|
12
|
+
implementation commit**; it is not compatible merely by version number with the
|
|
13
|
+
historical Hex1b NuGet `0.1.0`. Subsequent normal CI releases coordinate npm and
|
|
14
|
+
NuGet versions; use matching builds from the same release.
|
|
15
|
+
|
|
16
|
+
## Install and mount
|
|
17
|
+
|
|
18
|
+
```sh
|
|
19
|
+
npm install @hex1b/web-terminal
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
Give the container a nonzero width and height. Mount resolves after a connected
|
|
23
|
+
frame has been presented, or rejects on initialization failure or a 30-second
|
|
24
|
+
first-frame timeout.
|
|
25
|
+
|
|
26
|
+
```html
|
|
27
|
+
<div id="terminal" style="width: 100%; height: 480px"></div>
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
```ts
|
|
31
|
+
import { WebTerminal } from "@hex1b/web-terminal";
|
|
32
|
+
|
|
33
|
+
const container = document.getElementById("terminal");
|
|
34
|
+
if (!container) throw new Error("Missing terminal container");
|
|
35
|
+
|
|
36
|
+
const terminal = await WebTerminal.mount(container, {
|
|
37
|
+
url: "/ws/terminal", // Your matching Hex1b HWT1 WebSocket endpoint.
|
|
38
|
+
sizing: { mode: "auto", fontSize: 16 },
|
|
39
|
+
onStatus(message, level) {
|
|
40
|
+
console.log(level, message);
|
|
41
|
+
}
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
terminal.focus();
|
|
45
|
+
// On component teardown:
|
|
46
|
+
// terminal.dispose();
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
`url` accepts a string or URL; relative URLs resolve against the page, and
|
|
50
|
+
`http:`/`https:` become `ws:`/`wss:`. An optional `AbortSignal` cancels mounting
|
|
51
|
+
or disposes a mounted view. Disposal removes only the appended element and its
|
|
52
|
+
connection, not the container or server-side shared terminal.
|
|
53
|
+
|
|
54
|
+
### Browser and deployment requirements
|
|
55
|
+
|
|
56
|
+
Use HTTPS or localhost and a browser with WebGPU, module workers, transferable
|
|
57
|
+
OffscreenCanvas, worker animation frames, ResizeObserver, and CSS Font Loading.
|
|
58
|
+
Clipboard access also requires browser permission and, for relevant actions, a
|
|
59
|
+
user gesture. There is no Canvas2D terminal-rendering fallback.
|
|
60
|
+
|
|
61
|
+
The package contains browser ES modules, not a single bundle. For bare static
|
|
62
|
+
hosting, copy **all of `dist/`**, preserving its directory structure, and import
|
|
63
|
+
`/web-terminal/index.js` from a module script. `dist/web-terminal.js` also remains
|
|
64
|
+
available for relative static imports. Package consumers should import only from
|
|
65
|
+
`@hex1b/web-terminal`; internal protocol/renderer modules are not public exports.
|
|
66
|
+
|
|
67
|
+
The worker is created with
|
|
68
|
+
`new Worker(new URL("./terminal-worker.js", import.meta.url), { type: "module" })`.
|
|
69
|
+
The default font is resolved relative to its module, not the host page.
|
|
70
|
+
Bundlers differ in whether they discover and rewrite assets inside dependencies;
|
|
71
|
+
this package does not claim universal or individually verified bundler support.
|
|
72
|
+
The reliable static deployment layout is the complete emitted tree described
|
|
73
|
+
above.
|
|
74
|
+
|
|
75
|
+
If your bundler does not handle the dependency's worker URL, explicitly provide
|
|
76
|
+
the entry point you deployed:
|
|
77
|
+
|
|
78
|
+
```ts
|
|
79
|
+
const terminal = await WebTerminal.mount(container, {
|
|
80
|
+
url: "/ws/terminal",
|
|
81
|
+
workerUrl: "/web-terminal/terminal-worker.js"
|
|
82
|
+
});
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
`workerUrl` accepts a nonempty string or URL and resolves relative strings against
|
|
86
|
+
the page, not the package module. It still creates a **module** worker. Deploy its
|
|
87
|
+
complete relative module tree, or provide a separately bundled worker entry from
|
|
88
|
+
the same package build. The override does not automatically copy fonts: retain
|
|
89
|
+
the default font asset URL or provide explicit `font.faces` URLs as shown below.
|
|
90
|
+
The browser's worker origin and CSP restrictions still apply.
|
|
91
|
+
|
|
92
|
+
Configure your server's JavaScript and WOFF2 MIME types and CSP to allow these
|
|
93
|
+
workers, fonts, and the intended WebSocket endpoint.
|
|
94
|
+
|
|
95
|
+
## Configuration and state
|
|
96
|
+
|
|
97
|
+
`WebTerminalOptions` includes:
|
|
98
|
+
|
|
99
|
+
| Option | Meaning |
|
|
100
|
+
| --- | --- |
|
|
101
|
+
| `workerUrl` | Optional module-worker entry; useful when worker assets are deployed separately. |
|
|
102
|
+
| `scale` | GPU backing scale `0.5`–`3`, or `"auto"` (default, bounded device pixel ratio). |
|
|
103
|
+
| `font` | One family and optional downloadable font faces; see below. |
|
|
104
|
+
| `sizing` | `{ mode: "auto", fontSize?: number }` or `{ mode: "fixed", columns, rows, fontSize?: number }`. |
|
|
105
|
+
| `readOnly` | Disable application input while retaining history inspection and selection. |
|
|
106
|
+
| `label` | Accessible label for the terminal's hidden keyboard input. |
|
|
107
|
+
| `inputBindings`, `onInput`, `actions` | Per-view input policy and custom actions. |
|
|
108
|
+
| `onSelectionUI` | Synchronous, cancelable UI notification hook. |
|
|
109
|
+
|
|
110
|
+
Font size is an integer from 8–32, defaulting to 16. Import `MIN_FONT_SIZE` and
|
|
111
|
+
`MAX_FONT_SIZE` from `@hex1b/web-terminal` for sizing controls. Requested fixed grids allow
|
|
112
|
+
20–300 columns and 10–100 rows. The producer still owns actual grid geometry.
|
|
113
|
+
`resize()`, `setSizing()`, and automatic resize requests require primary
|
|
114
|
+
ownership. `requestPrimary()` explicitly requests ownership; inspect `peer` or
|
|
115
|
+
`onRoleChange` to observe the result.
|
|
116
|
+
|
|
117
|
+
The handle exposes `geometry`, `peer`, `connected`, `stats`, `screenText`,
|
|
118
|
+
`sizing`, `viewport`, `selection`, `inputBindings`, and `inputContext`.
|
|
119
|
+
Metrics start empty; check optional fields before using them. History may be
|
|
120
|
+
unavailable, and selection can be unavailable, none, pending, valid, or
|
|
121
|
+
invalidated. Narrow `viewport.available` and `selection.status` before using
|
|
122
|
+
their state-specific values. `screenText` reflects the presented viewport, not
|
|
123
|
+
an independently reconstructed ANSI buffer.
|
|
124
|
+
|
|
125
|
+
Callbacks include `onGeometry`, `onRoleChange`, `onSizingChange`, `onStats`,
|
|
126
|
+
`onViewportChange`, `onSelectionChange`, `onStatus`, and `onInputError`.
|
|
127
|
+
|
|
128
|
+
## Input and clipboard
|
|
129
|
+
|
|
130
|
+
Import `InputRoute`, `TerminalAction`, and `defaultInputBindings` to inspect and
|
|
131
|
+
customize routing. Defaults preserve browser shortcuts, forward terminal keys,
|
|
132
|
+
copy with Cmd+C or Ctrl+Shift+C, and use a local right-click to copy or paste
|
|
133
|
+
when application mouse capture does not own that gesture. IME composition and
|
|
134
|
+
paste are forwarded through the producer's mode-aware input encoder.
|
|
135
|
+
|
|
136
|
+
Overrides match first. Reuse a default binding's ID to replace it, or specify
|
|
137
|
+
`{ id: "clipboard.context-click", remove: true }` to remove that default.
|
|
138
|
+
`match`, `when`, and `onInput` must finish synchronously. Actions may be async.
|
|
139
|
+
|
|
140
|
+
```ts
|
|
141
|
+
import { InputRoute, TerminalAction, type WebTerminalOptions } from "@hex1b/web-terminal";
|
|
142
|
+
|
|
143
|
+
const options: WebTerminalOptions = {
|
|
144
|
+
url: "/ws/terminal",
|
|
145
|
+
inputBindings: [
|
|
146
|
+
{
|
|
147
|
+
id: "history.previous-page",
|
|
148
|
+
match: input => input.type === "key" && input.key === "PageUp" && input.shift,
|
|
149
|
+
action: TerminalAction.ScrollLines,
|
|
150
|
+
args: -20
|
|
151
|
+
},
|
|
152
|
+
{ id: "clipboard.context-click", remove: true }
|
|
153
|
+
],
|
|
154
|
+
onInput(input) {
|
|
155
|
+
if (input.type === "key" && input.meta) return InputRoute.Browser;
|
|
156
|
+
return InputRoute.Continue;
|
|
157
|
+
}
|
|
158
|
+
};
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
Named actions are `copySelection`, `pasteClipboard`, `copyOrPaste`,
|
|
162
|
+
`clearSelection`, `scrollToLive`, and `scrollLines`.
|
|
163
|
+
`terminal.runAction(TerminalAction.ScrollLines, -20)` shares the same
|
|
164
|
+
implementation as bindings and UI controls. Custom `actions` receive
|
|
165
|
+
`(context, args, input)`; their argument/result types are `unknown`, so custom
|
|
166
|
+
handlers validate their own data. Built-in action names cannot be overridden.
|
|
167
|
+
|
|
168
|
+
You can also call `scrollLines()`, `scrollToLive()`, `clearSelection()`,
|
|
169
|
+
`copySelection({ clear: true })`, `paste(text)`, or `pasteClipboard()` directly.
|
|
170
|
+
Copy uses authoritative producer selection text, not rendered cells. Clipboard
|
|
171
|
+
actions reject if selection/input/focus changes before their asynchronous work
|
|
172
|
+
can be applied safely. Errors are surfaced rather than silently reported as
|
|
173
|
+
successful copies or pastes.
|
|
174
|
+
|
|
175
|
+
## Selection UI hooks
|
|
176
|
+
|
|
177
|
+
`onSelectionUI` receives a typed `SelectionUIEvent`, also dispatched as the
|
|
178
|
+
`selectionui` DOM event on `terminal.element`. Its frozen detail includes
|
|
179
|
+
selection, viewport, geometry, canvas size, connection/read-only state, and:
|
|
180
|
+
|
|
181
|
+
- `overlay`: a stable light-DOM host for custom UI; style your controls and set
|
|
182
|
+
`pointer-events: auto` on interactive descendants.
|
|
183
|
+
- `rects`: selection rectangles in overlay-local CSS pixels.
|
|
184
|
+
- `runAction`: the same typed action API as the terminal handle.
|
|
185
|
+
- `signal`: cleanup lifetime, aborted on disposal.
|
|
186
|
+
|
|
187
|
+
Call `event.preventDefault()` **synchronously** to replace the default Copy
|
|
188
|
+
button. This does not remove selection highlights or transfer ownership of
|
|
189
|
+
selection/clipboard state. The callback must return `undefined`, not a Promise.
|
|
190
|
+
Events coalesce meaningful changes; `refreshSelectionUI()` re-notifies hosts
|
|
191
|
+
after external styling or policy changes. External DOM listeners may also
|
|
192
|
+
cancel the default UI.
|
|
193
|
+
|
|
194
|
+
Inspection UI inherits the embedding page's `--cp-*` theme tokens and otherwise
|
|
195
|
+
uses its own light/dark defaults. Shadow parts include `selection-highlights`,
|
|
196
|
+
`selection-highlight`, and `selection-copy-button`.
|
|
197
|
+
|
|
198
|
+
## Fonts and licenses
|
|
199
|
+
|
|
200
|
+
The default is the bundled **Cascadia Mono NF** variable WOFF2 font. The package
|
|
201
|
+
includes the unmodified font, SIL Open Font License, and provenance in
|
|
202
|
+
`dist/fonts/cascadia-mono-nf/`; no sample assets are required.
|
|
203
|
+
|
|
204
|
+
```ts
|
|
205
|
+
const font = {
|
|
206
|
+
family: "My Terminal Font",
|
|
207
|
+
faces: [{ url: "/fonts/my-terminal.woff2", weight: "100 900", style: "normal" }]
|
|
208
|
+
};
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
Custom face URLs resolve against the host page before the configuration reaches
|
|
212
|
+
the worker. Page-loaded fonts are not inherited by workers: supply face URLs,
|
|
213
|
+
a locally installed family, or a generic family such as `monospace`. A generic
|
|
214
|
+
family cannot have downloadable faces. Font loading failures reject rather
|
|
215
|
+
than silently selecting a different font.
|
|
216
|
+
|
|
217
|
+
Hex1b's code is MIT licensed (`LICENSE`); the bundled font uses its separate
|
|
218
|
+
SIL Open Font License.
|
|
219
|
+
|
|
220
|
+
## Build, test, and pack
|
|
221
|
+
|
|
222
|
+
From this package directory, with Node.js 22 or later:
|
|
223
|
+
|
|
224
|
+
```sh
|
|
225
|
+
npm ci
|
|
226
|
+
npm run build
|
|
227
|
+
npm test
|
|
228
|
+
npm pack
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
The strict TypeScript build emits JavaScript, declarations, declaration maps,
|
|
232
|
+
and source maps (with embedded sources), then copies fonts into `dist/`.
|
|
233
|
+
`npm test` runs zero-dependency `node:test` tests against those emitted modules
|
|
234
|
+
and strict public-consumer declaration checks in NodeNext and bundler modes.
|
|
235
|
+
`npm run typecheck` validates sources without emitting.
|
|
236
|
+
|
|
237
|
+
`prepack` rebuilds for `npm pack` and manual `npm publish` from this directory.
|
|
238
|
+
Only `dist/`, this README, the MIT license, and package metadata are shipped.
|
|
239
|
+
A prepared tarball is self-contained and can be published with
|
|
240
|
+
`npm publish ./hex1b-web-terminal-<version>.tgz --ignore-scripts`; it does not
|
|
241
|
+
need development sources or build scripts. The package name is always
|
|
242
|
+
`@hex1b/web-terminal`, including GitHub Packages. Registry selection is left to
|
|
243
|
+
the caller; no registry is pinned in `package.json`.
|
|
Binary file
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
Copyright (c) 2019 - Present, Microsoft Corporation,
|
|
2
|
+
with Reserved Font Name Cascadia Code.
|
|
3
|
+
|
|
4
|
+
This Font Software is licensed under the SIL Open Font License, Version 1.1.
|
|
5
|
+
This license is copied below, and is also available with a FAQ at:
|
|
6
|
+
http://scripts.sil.org/OFL
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
-----------------------------------------------------------
|
|
10
|
+
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
|
|
11
|
+
-----------------------------------------------------------
|
|
12
|
+
|
|
13
|
+
PREAMBLE
|
|
14
|
+
The goals of the Open Font License (OFL) are to stimulate worldwide
|
|
15
|
+
development of collaborative font projects, to support the font creation
|
|
16
|
+
efforts of academic and linguistic communities, and to provide a free and
|
|
17
|
+
open framework in which fonts may be shared and improved in partnership
|
|
18
|
+
with others.
|
|
19
|
+
|
|
20
|
+
The OFL allows the licensed fonts to be used, studied, modified and
|
|
21
|
+
redistributed freely as long as they are not sold by themselves. The
|
|
22
|
+
fonts, including any derivative works, can be bundled, embedded,
|
|
23
|
+
redistributed and/or sold with any software provided that any reserved
|
|
24
|
+
names are not used by derivative works. The fonts and derivatives,
|
|
25
|
+
however, cannot be released under any other type of license. The
|
|
26
|
+
requirement for fonts to remain under this license does not apply
|
|
27
|
+
to any document created using the fonts or their derivatives.
|
|
28
|
+
|
|
29
|
+
DEFINITIONS
|
|
30
|
+
"Font Software" refers to the set of files released by the Copyright
|
|
31
|
+
Holder(s) under this license and clearly marked as such. This may
|
|
32
|
+
include source files, build scripts and documentation.
|
|
33
|
+
|
|
34
|
+
"Reserved Font Name" refers to any names specified as such after the
|
|
35
|
+
copyright statement(s).
|
|
36
|
+
|
|
37
|
+
"Original Version" refers to the collection of Font Software components as
|
|
38
|
+
distributed by the Copyright Holder(s).
|
|
39
|
+
|
|
40
|
+
"Modified Version" refers to any derivative made by adding to, deleting,
|
|
41
|
+
or substituting -- in part or in whole -- any of the components of the
|
|
42
|
+
Original Version, by changing formats or by porting the Font Software to a
|
|
43
|
+
new environment.
|
|
44
|
+
|
|
45
|
+
"Author" refers to any designer, engineer, programmer, technical
|
|
46
|
+
writer or other person who contributed to the Font Software.
|
|
47
|
+
|
|
48
|
+
PERMISSION & CONDITIONS
|
|
49
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
|
50
|
+
a copy of the Font Software, to use, study, copy, merge, embed, modify,
|
|
51
|
+
redistribute, and sell modified and unmodified copies of the Font
|
|
52
|
+
Software, subject to the following conditions:
|
|
53
|
+
|
|
54
|
+
1) Neither the Font Software nor any of its individual components,
|
|
55
|
+
in Original or Modified Versions, may be sold by itself.
|
|
56
|
+
|
|
57
|
+
2) Original or Modified Versions of the Font Software may be bundled,
|
|
58
|
+
redistributed and/or sold with any software, provided that each copy
|
|
59
|
+
contains the above copyright notice and this license. These can be
|
|
60
|
+
included either as stand-alone text files, human-readable headers or
|
|
61
|
+
in the appropriate machine-readable metadata fields within text or
|
|
62
|
+
binary files as long as those fields can be easily viewed by the user.
|
|
63
|
+
|
|
64
|
+
3) No Modified Version of the Font Software may use the Reserved Font
|
|
65
|
+
Name(s) unless explicit written permission is granted by the corresponding
|
|
66
|
+
Copyright Holder. This restriction only applies to the primary font name as
|
|
67
|
+
presented to the users.
|
|
68
|
+
|
|
69
|
+
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
|
|
70
|
+
Software shall not be used to promote, endorse or advertise any
|
|
71
|
+
Modified Version, except to acknowledge the contribution(s) of the
|
|
72
|
+
Copyright Holder(s) and the Author(s) or with their explicit written
|
|
73
|
+
permission.
|
|
74
|
+
|
|
75
|
+
5) The Font Software, modified or unmodified, in part or in whole,
|
|
76
|
+
must be distributed entirely under this license, and must not be
|
|
77
|
+
distributed under any other license. The requirement for fonts to
|
|
78
|
+
remain under this license does not apply to any document created
|
|
79
|
+
using the Font Software.
|
|
80
|
+
|
|
81
|
+
TERMINATION
|
|
82
|
+
This license becomes null and void if any of the above conditions are
|
|
83
|
+
not met.
|
|
84
|
+
|
|
85
|
+
DISCLAIMER
|
|
86
|
+
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
87
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
|
|
88
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
|
|
89
|
+
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
|
|
90
|
+
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
|
91
|
+
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
|
|
92
|
+
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
93
|
+
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
|
|
94
|
+
OTHER DEALINGS IN THE FONT SOFTWARE.
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# Cascadia Mono NF
|
|
2
|
+
|
|
3
|
+
The web terminal's default font is Microsoft's Cascadia Mono with Nerd Font
|
|
4
|
+
symbols and without programming ligatures. The font file is unmodified.
|
|
5
|
+
|
|
6
|
+
- Upstream: <https://github.com/microsoft/cascadia-code>
|
|
7
|
+
- Release: [v2407.24](https://github.com/microsoft/cascadia-code/releases/tag/v2407.24)
|
|
8
|
+
- Upstream release path: `woff2/CascadiaMonoNF.woff2`
|
|
9
|
+
- Retrieved from Aspire's copy at commit
|
|
10
|
+
[`1dd4584e3df56f5544a3e7f5fda8aa767f92318e`](https://github.com/microsoft/aspire/tree/1dd4584e3df56f5544a3e7f5fda8aa767f92318e/src/Aspire.Dashboard/wwwroot/fonts/cascadia-mono-nf)
|
|
11
|
+
- Size: 976,460 bytes
|
|
12
|
+
- SHA-256: `bd42b0c992de9c42d8a770112e8140d67d6437798be39d49e57f4954e2f6e8e2`
|
|
13
|
+
|
|
14
|
+
## License and redistribution
|
|
15
|
+
|
|
16
|
+
Copyright (c) 2019 - Present, Microsoft Corporation,
|
|
17
|
+
with Reserved Font Name Cascadia Code.
|
|
18
|
+
|
|
19
|
+
The font is licensed under the **SIL Open Font License 1.1**, not Hex1b's code
|
|
20
|
+
license. The full, unmodified license and copyright notice are in
|
|
21
|
+
[`LICENSE.txt`](LICENSE.txt). Include that notice and license whenever
|
|
22
|
+
redistributing the font, including future embedded-resource or npm packaging.
|
|
23
|
+
OFL permits bundling and embedding alongside software; the font cannot be sold
|
|
24
|
+
on its own. Modified versions must respect the reserved-font-name and other
|
|
25
|
+
OFL conditions.
|
|
26
|
+
|
|
27
|
+
To update, take the unmodified WOFF2 from an official upstream release, retain
|
|
28
|
+
the accompanying license, and update the version, provenance, size, and hash
|
|
29
|
+
above. Do not subset or patch the asset as an incidental packaging step.
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/** Commands contain producer identities; text and ranges are never inferred from painted cells. */
|
|
2
|
+
export declare class HistoryState {
|
|
3
|
+
#private;
|
|
4
|
+
constructor(send: (command: TerminalCommand) => void, change?: () => void);
|
|
5
|
+
get viewport(): HistoryViewport;
|
|
6
|
+
get selection(): HistorySelectionState;
|
|
7
|
+
accept(history: HistoryMetadata | null, revision: number): boolean;
|
|
8
|
+
begin(point: TerminalPoint, { mode, extend }: {
|
|
9
|
+
mode: SelectionMode;
|
|
10
|
+
extend?: boolean;
|
|
11
|
+
}): void;
|
|
12
|
+
extend(point: TerminalPoint): void;
|
|
13
|
+
scroll(delta: number, endpoint?: TerminalPoint): void;
|
|
14
|
+
live(): void;
|
|
15
|
+
clear(): void;
|
|
16
|
+
endGesture(cancelled?: boolean): void;
|
|
17
|
+
cancelCopy(error: unknown): void;
|
|
18
|
+
copy(): Promise<string>;
|
|
19
|
+
disconnect(): void;
|
|
20
|
+
}
|
|
21
|
+
import type { SelectionMode, TerminalPoint, TerminalSelection, TerminalViewport } from "./types.js";
|
|
22
|
+
import type { HistoryMetadata, TerminalCommand } from "./wire-types.js";
|
|
23
|
+
type OmitEach<T, K extends PropertyKey> = T extends unknown ? Omit<T, K> : never;
|
|
24
|
+
type HistoryViewport = OmitEach<TerminalViewport, "followTail" | "offset">;
|
|
25
|
+
type HistorySelectionState = OmitEach<TerminalSelection, "active" | "pending" | "copying" | "copyError">;
|
|
26
|
+
export {};
|
|
27
|
+
//# sourceMappingURL=history-state.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"history-state.d.ts","sourceRoot":"","sources":["../src/history-state.ts"],"names":[],"mappings":"AAIA,mGAAmG;AACnG,qBAAa,YAAY;;gBAaX,IAAI,EAAE,CAAC,OAAO,EAAE,eAAe,KAAK,IAAI,EAAE,MAAM,GAAE,MAAM,IAAe;IAKnF,IAAI,QAAQ,IAAI,eAAe,CAK9B;IAED,IAAI,SAAS,IAAI,qBAAqB,CAYrC;IAED,MAAM,CAAC,OAAO,EAAE,eAAe,GAAG,IAAI,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO;IAuDlE,KAAK,CAAC,KAAK,EAAE,aAAa,EAAE,EAAE,IAAI,EAAE,MAAc,EAAE,EAAE;QAAE,IAAI,EAAE,aAAa,CAAC;QAAC,MAAM,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,IAAI;IAStG,MAAM,CAAC,KAAK,EAAE,aAAa,GAAG,IAAI;IAalC,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,aAAa,GAAG,IAAI;IAcrD,IAAI;IAQJ,KAAK;IAQL,UAAU,CAAC,SAAS,UAAQ;IAc5B,UAAU,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI;IAEhC,IAAI,IAAI,OAAO,CAAC,MAAM,CAAC;IAyBvB,UAAU;CAIX;AACD,OAAO,KAAK,EAAE,aAAa,EAAE,aAAa,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AACpG,OAAO,KAAK,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAExE,KAAK,QAAQ,CAAC,CAAC,EAAE,CAAC,SAAS,WAAW,IAAI,CAAC,SAAS,OAAO,GAAG,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,KAAK,CAAC;AACjF,KAAK,eAAe,GAAG,QAAQ,CAAC,gBAAgB,EAAE,YAAY,GAAG,QAAQ,CAAC,CAAC;AAC3E,KAAK,qBAAqB,GAAG,QAAQ,CAAC,iBAAiB,EAAE,QAAQ,GAAG,SAAS,GAAG,SAAS,GAAG,WAAW,CAAC,CAAC"}
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
const unavailable = "Text history is not available for this terminal view";
|
|
2
|
+
const expired = "Selection expired: its text was changed, evicted, reset, or resized. Select the text again.";
|
|
3
|
+
const changedBeforeCopy = "Selection changed before copy completed. Copy the new selection again.";
|
|
4
|
+
/** Commands contain producer identities; text and ranges are never inferred from painted cells. */
|
|
5
|
+
export class HistoryState {
|
|
6
|
+
#send;
|
|
7
|
+
#change;
|
|
8
|
+
#history = null;
|
|
9
|
+
#revision = 0;
|
|
10
|
+
#nextRequest = 0;
|
|
11
|
+
#selectionRequest = 0;
|
|
12
|
+
#viewportRequest = 0;
|
|
13
|
+
#pendingMode = "character";
|
|
14
|
+
#pendingAction = "clear";
|
|
15
|
+
#pendingCopy;
|
|
16
|
+
#deferredEndpoint;
|
|
17
|
+
constructor(send, change = () => { }) {
|
|
18
|
+
this.#send = send;
|
|
19
|
+
this.#change = change;
|
|
20
|
+
}
|
|
21
|
+
get viewport() {
|
|
22
|
+
if (!this.#history)
|
|
23
|
+
return { available: false, following: true, pending: false };
|
|
24
|
+
const { selection, copy, ...viewport } = this.#history;
|
|
25
|
+
return { ...viewport, rowIds: [...viewport.rowIds], available: true, revision: this.#revision,
|
|
26
|
+
pending: viewport.requestId < this.#viewportRequest };
|
|
27
|
+
}
|
|
28
|
+
get selection() {
|
|
29
|
+
if (!this.#history)
|
|
30
|
+
return { status: "unavailable", mode: "character", ranges: [], text: null, message: unavailable };
|
|
31
|
+
const selection = this.#history.selection;
|
|
32
|
+
if (selection.requestId < this.#selectionRequest || this.#deferredEndpoint) {
|
|
33
|
+
return { requestId: this.#selectionRequest, status: "pending", mode: this.#pendingMode,
|
|
34
|
+
canExtend: this.#pendingAction !== "clear",
|
|
35
|
+
ranges: this.#pendingAction === "clear" ? [] : selection.ranges.map(range => ({ ...range })), text: null,
|
|
36
|
+
message: "Resolving selection…" };
|
|
37
|
+
}
|
|
38
|
+
return { ...selection, canExtend: selection.status === "valid",
|
|
39
|
+
ranges: selection.ranges.map(range => ({ ...range })), revision: this.#revision,
|
|
40
|
+
message: selection.status === "invalidated" ? expired : "" };
|
|
41
|
+
}
|
|
42
|
+
accept(history, revision) {
|
|
43
|
+
if (revision <= this.#revision)
|
|
44
|
+
return false;
|
|
45
|
+
const previousGeneration = this.#history?.generation;
|
|
46
|
+
this.#history = history;
|
|
47
|
+
this.#revision = revision;
|
|
48
|
+
if (!history || (previousGeneration && previousGeneration !== history.generation) ||
|
|
49
|
+
history.selection.status === "invalidated") {
|
|
50
|
+
this.endGesture(true);
|
|
51
|
+
this.#rejectCopy(new Error(expired));
|
|
52
|
+
}
|
|
53
|
+
const pending = this.#pendingCopy;
|
|
54
|
+
if (pending && history?.copy?.requestId === pending.requestId) {
|
|
55
|
+
if (history.copy.status !== "valid" || history.selection.status !== "valid" ||
|
|
56
|
+
history.selection.requestId !== pending.selectionRequestId ||
|
|
57
|
+
history.generation !== pending.generation || this.#selectionRequest > pending.selectionRequestId ||
|
|
58
|
+
history.copy.text !== history.selection.text) {
|
|
59
|
+
this.#rejectCopy(new Error(expired));
|
|
60
|
+
}
|
|
61
|
+
else {
|
|
62
|
+
clearTimeout(pending.timer);
|
|
63
|
+
this.#pendingCopy = undefined;
|
|
64
|
+
pending.resolve(history.copy.text);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
if (this.#deferredEndpoint && !this.viewport.pending) {
|
|
68
|
+
const point = this.#deferredEndpoint;
|
|
69
|
+
this.#deferredEndpoint = undefined;
|
|
70
|
+
this.extend(point);
|
|
71
|
+
}
|
|
72
|
+
this.#change();
|
|
73
|
+
return true;
|
|
74
|
+
}
|
|
75
|
+
#requireHistory() {
|
|
76
|
+
if (!this.#history)
|
|
77
|
+
throw new Error(unavailable);
|
|
78
|
+
return this.#history;
|
|
79
|
+
}
|
|
80
|
+
#pointRowId(point) {
|
|
81
|
+
const history = this.#requireHistory();
|
|
82
|
+
if (!point || !Number.isInteger(point.x) || point.x < 0 || point.x > 1023 ||
|
|
83
|
+
!Number.isInteger(point.y) || point.y < 0 ||
|
|
84
|
+
typeof history.rowIds[point.y] !== "string" || !history.rowIds[point.y].length) {
|
|
85
|
+
throw new Error("Terminal viewport is not ready for that selection point. Wait for the next frame and try again.");
|
|
86
|
+
}
|
|
87
|
+
return history.rowIds[point.y];
|
|
88
|
+
}
|
|
89
|
+
#selectionChanged(mode = this.selection.mode, action = "extend") {
|
|
90
|
+
this.#rejectCopy(new Error(changedBeforeCopy));
|
|
91
|
+
this.#pendingMode = mode;
|
|
92
|
+
this.#pendingAction = action;
|
|
93
|
+
this.#selectionRequest = ++this.#nextRequest;
|
|
94
|
+
return this.#selectionRequest;
|
|
95
|
+
}
|
|
96
|
+
begin(point, { mode, extend = false }) {
|
|
97
|
+
const rowId = this.#pointRowId(point);
|
|
98
|
+
this.#deferredEndpoint = undefined;
|
|
99
|
+
const requestId = this.#selectionChanged(mode, extend ? "extend" : "start");
|
|
100
|
+
this.#send({ type: "selection", action: extend ? "extend" : "start", mode, requestId,
|
|
101
|
+
generation: this.#requireHistory().generation, rowId, column: point.x });
|
|
102
|
+
this.#change();
|
|
103
|
+
}
|
|
104
|
+
extend(point) {
|
|
105
|
+
this.#pointRowId(point);
|
|
106
|
+
if (this.viewport.pending) {
|
|
107
|
+
this.#rejectCopy(new Error(changedBeforeCopy));
|
|
108
|
+
this.#pendingMode = this.selection.mode;
|
|
109
|
+
this.#pendingAction = "extend";
|
|
110
|
+
this.#deferredEndpoint = { ...point };
|
|
111
|
+
this.#change();
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
this.begin(point, { mode: this.selection.mode, extend: true });
|
|
115
|
+
}
|
|
116
|
+
scroll(delta, endpoint) {
|
|
117
|
+
this.#requireHistory();
|
|
118
|
+
if (!Number.isSafeInteger(delta) || delta < -2147483648 || delta > 2147483647)
|
|
119
|
+
throw new RangeError("Scroll delta must be a signed 32-bit integer");
|
|
120
|
+
if (endpoint)
|
|
121
|
+
this.#pointRowId(endpoint);
|
|
122
|
+
if (!delta && !endpoint)
|
|
123
|
+
return;
|
|
124
|
+
if (endpoint)
|
|
125
|
+
this.#deferredEndpoint = undefined;
|
|
126
|
+
else
|
|
127
|
+
this.#flushDeferredEndpoint();
|
|
128
|
+
const requestId = endpoint ? this.#selectionChanged() : ++this.#nextRequest;
|
|
129
|
+
this.#viewportRequest = requestId;
|
|
130
|
+
this.#send({ type: "viewport", requestId, delta,
|
|
131
|
+
...(endpoint ? { extend: { row: endpoint.y, column: endpoint.x } } : {}) });
|
|
132
|
+
this.#change();
|
|
133
|
+
}
|
|
134
|
+
live() {
|
|
135
|
+
this.#requireHistory();
|
|
136
|
+
this.#flushDeferredEndpoint();
|
|
137
|
+
this.#viewportRequest = ++this.#nextRequest;
|
|
138
|
+
this.#send({ type: "viewport", live: true, requestId: this.#viewportRequest });
|
|
139
|
+
this.#change();
|
|
140
|
+
}
|
|
141
|
+
clear() {
|
|
142
|
+
this.#requireHistory();
|
|
143
|
+
this.#deferredEndpoint = undefined;
|
|
144
|
+
const requestId = this.#selectionChanged(this.selection.mode, "clear");
|
|
145
|
+
this.#send({ type: "selection", action: "clear", requestId });
|
|
146
|
+
this.#change();
|
|
147
|
+
}
|
|
148
|
+
endGesture(cancelled = false) {
|
|
149
|
+
if (cancelled && this.#deferredEndpoint) {
|
|
150
|
+
this.#deferredEndpoint = undefined;
|
|
151
|
+
this.#change();
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
#flushDeferredEndpoint() {
|
|
155
|
+
if (!this.#deferredEndpoint)
|
|
156
|
+
return;
|
|
157
|
+
const endpoint = this.#deferredEndpoint;
|
|
158
|
+
this.#deferredEndpoint = undefined;
|
|
159
|
+
// Preserve command order if another scroll overtakes the pending presentation.
|
|
160
|
+
this.scroll(0, endpoint);
|
|
161
|
+
}
|
|
162
|
+
cancelCopy(error) { this.#rejectCopy(error); }
|
|
163
|
+
copy() {
|
|
164
|
+
const history = this.#requireHistory();
|
|
165
|
+
const selection = this.selection;
|
|
166
|
+
if (selection.status !== "valid")
|
|
167
|
+
throw new Error(selection.message || "Select text before copying.");
|
|
168
|
+
this.#rejectCopy(new Error("A newer copy request replaced this request."));
|
|
169
|
+
const requestId = ++this.#nextRequest;
|
|
170
|
+
const { promise, resolve, reject } = Promise.withResolvers();
|
|
171
|
+
const timer = setTimeout(() => this.#rejectCopy(new Error("Timed out resolving selection. Copy again.")), 10000);
|
|
172
|
+
this.#pendingCopy = { requestId, selectionRequestId: selection.requestId, generation: history.generation,
|
|
173
|
+
resolve, reject, timer };
|
|
174
|
+
try {
|
|
175
|
+
this.#send({ type: "copy", requestId, selectionRequestId: selection.requestId, generation: history.generation });
|
|
176
|
+
}
|
|
177
|
+
catch (error) {
|
|
178
|
+
this.#rejectCopy(error);
|
|
179
|
+
}
|
|
180
|
+
return promise;
|
|
181
|
+
}
|
|
182
|
+
#rejectCopy(error) {
|
|
183
|
+
if (!this.#pendingCopy)
|
|
184
|
+
return;
|
|
185
|
+
clearTimeout(this.#pendingCopy.timer);
|
|
186
|
+
this.#pendingCopy.reject(error);
|
|
187
|
+
this.#pendingCopy = undefined;
|
|
188
|
+
}
|
|
189
|
+
disconnect() {
|
|
190
|
+
this.#rejectCopy(new Error("Terminal view disconnected before copy completed."));
|
|
191
|
+
this.#deferredEndpoint = undefined;
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
//# sourceMappingURL=history-state.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"history-state.js","sourceRoot":"","sources":["../src/history-state.ts"],"names":[],"mappings":"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","sourcesContent":["const unavailable = \"Text history is not available for this terminal view\";\nconst expired = \"Selection expired: its text was changed, evicted, reset, or resized. Select the text again.\";\nconst changedBeforeCopy = \"Selection changed before copy completed. Copy the new selection again.\";\n\n/** Commands contain producer identities; text and ranges are never inferred from painted cells. */\nexport class HistoryState {\n #send: (command: TerminalCommand) => void;\n #change: () => void;\n #history: HistoryMetadata | null = null;\n #revision = 0;\n #nextRequest = 0;\n #selectionRequest = 0;\n #viewportRequest = 0;\n #pendingMode: SelectionMode = \"character\";\n #pendingAction = \"clear\";\n #pendingCopy: PendingCopy | undefined;\n #deferredEndpoint: TerminalPoint | undefined;\n\n constructor(send: (command: TerminalCommand) => void, change: () => void = () => {}) {\n this.#send = send;\n this.#change = change;\n }\n\n get viewport(): HistoryViewport {\n if (!this.#history) return { available: false, following: true, pending: false };\n const { selection, copy, ...viewport } = this.#history;\n return { ...viewport, rowIds: [...viewport.rowIds], available: true, revision: this.#revision,\n pending: viewport.requestId < this.#viewportRequest };\n }\n\n get selection(): HistorySelectionState {\n if (!this.#history) return { status: \"unavailable\", mode: \"character\", ranges: [], text: null, message: unavailable };\n const selection = this.#history.selection;\n if (selection.requestId < this.#selectionRequest || this.#deferredEndpoint) {\n return { requestId: this.#selectionRequest, status: \"pending\", mode: this.#pendingMode,\n canExtend: this.#pendingAction !== \"clear\",\n ranges: this.#pendingAction === \"clear\" ? [] : selection.ranges.map(range => ({ ...range })), text: null,\n message: \"Resolving selection…\" };\n }\n return { ...selection, canExtend: selection.status === \"valid\",\n ranges: selection.ranges.map(range => ({ ...range })), revision: this.#revision,\n message: selection.status === \"invalidated\" ? expired : \"\" };\n }\n\n accept(history: HistoryMetadata | null, revision: number): boolean {\n if (revision <= this.#revision) return false;\n const previousGeneration = this.#history?.generation;\n this.#history = history;\n this.#revision = revision;\n if (!history || (previousGeneration && previousGeneration !== history.generation) ||\n history.selection.status === \"invalidated\") {\n this.endGesture(true);\n this.#rejectCopy(new Error(expired));\n }\n const pending = this.#pendingCopy;\n if (pending && history?.copy?.requestId === pending.requestId) {\n if (history.copy.status !== \"valid\" || history.selection.status !== \"valid\" ||\n history.selection.requestId !== pending.selectionRequestId ||\n history.generation !== pending.generation || this.#selectionRequest > pending.selectionRequestId ||\n history.copy.text !== history.selection.text) {\n this.#rejectCopy(new Error(expired));\n } else {\n clearTimeout(pending.timer);\n this.#pendingCopy = undefined;\n pending.resolve(history.copy.text);\n }\n }\n if (this.#deferredEndpoint && !this.viewport.pending) {\n const point = this.#deferredEndpoint;\n this.#deferredEndpoint = undefined;\n this.extend(point);\n }\n this.#change();\n return true;\n }\n\n #requireHistory(): HistoryMetadata {\n if (!this.#history) throw new Error(unavailable);\n return this.#history;\n }\n\n #pointRowId(point: TerminalPoint): string {\n const history = this.#requireHistory();\n if (!point || !Number.isInteger(point.x) || point.x < 0 || point.x > 1023 ||\n !Number.isInteger(point.y) || point.y < 0 ||\n typeof history.rowIds[point.y] !== \"string\" || !history.rowIds[point.y].length) {\n throw new Error(\"Terminal viewport is not ready for that selection point. Wait for the next frame and try again.\");\n }\n return history.rowIds[point.y];\n }\n\n #selectionChanged(mode = this.selection.mode, action = \"extend\") {\n this.#rejectCopy(new Error(changedBeforeCopy));\n this.#pendingMode = mode;\n this.#pendingAction = action;\n this.#selectionRequest = ++this.#nextRequest;\n return this.#selectionRequest;\n }\n\n begin(point: TerminalPoint, { mode, extend = false }: { mode: SelectionMode; extend?: boolean }): void {\n const rowId = this.#pointRowId(point);\n this.#deferredEndpoint = undefined;\n const requestId = this.#selectionChanged(mode, extend ? \"extend\" : \"start\");\n this.#send({ type: \"selection\", action: extend ? \"extend\" : \"start\", mode, requestId,\n generation: this.#requireHistory().generation, rowId, column: point.x });\n this.#change();\n }\n\n extend(point: TerminalPoint): void {\n this.#pointRowId(point);\n if (this.viewport.pending) {\n this.#rejectCopy(new Error(changedBeforeCopy));\n this.#pendingMode = this.selection.mode;\n this.#pendingAction = \"extend\";\n this.#deferredEndpoint = { ...point };\n this.#change();\n return;\n }\n this.begin(point, { mode: this.selection.mode, extend: true });\n }\n\n scroll(delta: number, endpoint?: TerminalPoint): void {\n this.#requireHistory();\n if (!Number.isSafeInteger(delta) || delta < -2147483648 || delta > 2147483647) throw new RangeError(\"Scroll delta must be a signed 32-bit integer\");\n if (endpoint) this.#pointRowId(endpoint);\n if (!delta && !endpoint) return;\n if (endpoint) this.#deferredEndpoint = undefined;\n else this.#flushDeferredEndpoint();\n const requestId = endpoint ? this.#selectionChanged() : ++this.#nextRequest;\n this.#viewportRequest = requestId;\n this.#send({ type: \"viewport\", requestId, delta,\n ...(endpoint ? { extend: { row: endpoint.y, column: endpoint.x } } : {}) });\n this.#change();\n }\n\n live() {\n this.#requireHistory();\n this.#flushDeferredEndpoint();\n this.#viewportRequest = ++this.#nextRequest;\n this.#send({ type: \"viewport\", live: true, requestId: this.#viewportRequest });\n this.#change();\n }\n\n clear() {\n this.#requireHistory();\n this.#deferredEndpoint = undefined;\n const requestId = this.#selectionChanged(this.selection.mode, \"clear\");\n this.#send({ type: \"selection\", action: \"clear\", requestId });\n this.#change();\n }\n\n endGesture(cancelled = false) {\n if (cancelled && this.#deferredEndpoint) {\n this.#deferredEndpoint = undefined;\n this.#change();\n }\n }\n\n #flushDeferredEndpoint() {\n if (!this.#deferredEndpoint) return;\n const endpoint = this.#deferredEndpoint;\n this.#deferredEndpoint = undefined;\n // Preserve command order if another scroll overtakes the pending presentation.\n this.scroll(0, endpoint);\n }\n cancelCopy(error: unknown): void { this.#rejectCopy(error); }\n\n copy(): Promise<string> {\n const history = this.#requireHistory();\n const selection = this.selection;\n if (selection.status !== \"valid\") throw new Error(selection.message || \"Select text before copying.\");\n this.#rejectCopy(new Error(\"A newer copy request replaced this request.\"));\n const requestId = ++this.#nextRequest;\n const { promise, resolve, reject } = Promise.withResolvers<string>();\n const timer = setTimeout(() => this.#rejectCopy(new Error(\"Timed out resolving selection. Copy again.\")), 10000);\n this.#pendingCopy = { requestId, selectionRequestId: selection.requestId, generation: history.generation,\n resolve, reject, timer };\n try {\n this.#send({ type: \"copy\", requestId, selectionRequestId: selection.requestId, generation: history.generation });\n } catch (error) {\n this.#rejectCopy(error);\n }\n return promise;\n }\n\n #rejectCopy(error: unknown): void {\n if (!this.#pendingCopy) return;\n clearTimeout(this.#pendingCopy.timer);\n this.#pendingCopy.reject(error);\n this.#pendingCopy = undefined;\n }\n\n disconnect() {\n this.#rejectCopy(new Error(\"Terminal view disconnected before copy completed.\"));\n this.#deferredEndpoint = undefined;\n }\n}\nimport type { SelectionMode, TerminalPoint, TerminalSelection, TerminalViewport } from \"./types.js\";\nimport type { HistoryMetadata, TerminalCommand } from \"./wire-types.js\";\n\ntype OmitEach<T, K extends PropertyKey> = T extends unknown ? Omit<T, K> : never;\ntype HistoryViewport = OmitEach<TerminalViewport, \"followTail\" | \"offset\">;\ntype HistorySelectionState = OmitEach<TerminalSelection, \"active\" | \"pending\" | \"copying\" | \"copyError\">;\ninterface PendingCopy {\n requestId: number; selectionRequestId: number; generation: string;\n resolve: (text: string) => void; reject: (error: unknown) => void;\n timer: ReturnType<typeof setTimeout>;\n}\n"]}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { WebTerminal } from "./web-terminal.js";
|
|
2
|
+
export { InputRoute, TerminalAction, defaultInputBindings } from "./input-policy.js";
|
|
3
|
+
export { MIN_FONT_SIZE, MAX_FONT_SIZE } from "./terminal-sizing.js";
|
|
4
|
+
export type * from "./types.js";
|
|
5
|
+
//# sourceMappingURL=index.d.ts.map
|