vterm.js 0.5.1 → 0.6.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 +6 -15
- package/dist/index.d.mts +66 -41
- package/dist/index.mjs +132 -20
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -243,18 +243,11 @@ screen.signals.damage$.subscribe((d: DirtyRegion) => {
|
|
|
243
243
|
})
|
|
244
244
|
```
|
|
245
245
|
|
|
246
|
-
## Naming
|
|
246
|
+
## Naming
|
|
247
247
|
|
|
248
|
-
The public vocabulary
|
|
248
|
+
The public vocabulary follows the terminal domain model (name the thing, not the mechanism; **row = cells, line = text**; flat progressive shapes over discriminated unions): `Color`, `Snapshot`, `getRow(row)`, `getCursor(): Cursor` (`Cursor` is `{ col, row }`). The pre-§9 names — `CellColor`, `ScreenSnapshot`/`VtermScreenSnapshot`, `getLine(row)`, `getCursorPosition(): {x,y}` — rode a deprecation window as `@deprecated` aliases and have since been deleted; they no longer compile.
|
|
249
249
|
|
|
250
|
-
|
|
251
|
-
| ---------------------------------------- | --------------------- | ------------------------------------------------------------------------------------------------------------ |
|
|
252
|
-
| `CellColor` | `Color` | Same shape `{ r, g, b, index? }`; a type named `RGB`/`CellColor` carrying `.index` was the smell. |
|
|
253
|
-
| `ScreenSnapshot` / `VtermScreenSnapshot` | `Snapshot` | The namespace supplies the context; `VtermScreenSnapshot` stays exported as an alias for existing consumers. |
|
|
254
|
-
| `getLine(row): ScreenCell[]` | `getRow(row)` | Row = cells; the text readers (`getText`, `getScrollbackText`) keep "line/text". |
|
|
255
|
-
| `getCursorPosition(): {x,y}` | `getCursor(): Cursor` | `Cursor` is `{ col, row }` — the grid's own vocabulary. |
|
|
256
|
-
|
|
257
|
-
**Deferred (not renamed this slice):** the `Snapshot.cursor` / `Snapshot.savedState` fields keep `x`/`y` rather than `col`/`row`, because those field names are the wire shape read by `encodeScreenSnapshotBinary` — renaming them would silently change the persisted binary format. The `col`/`row` vocabulary is available at the read boundary via `getCursor()` / the `Cursor` type. The snapshot field rename is a codec-format concern for a coordinated schema bump.
|
|
250
|
+
**Deferred (not renamed):** the `Snapshot.cursor` / `Snapshot.savedState` fields keep `x`/`y` rather than `col`/`row`, because those field names are the wire shape read by `encodeScreenSnapshotBinary` — renaming them would silently change the persisted binary format. The `col`/`row` vocabulary is available at the read boundary via `getCursor()` / the `Cursor` type. The snapshot field rename is a codec-format concern for a coordinated schema bump.
|
|
258
251
|
|
|
259
252
|
## API
|
|
260
253
|
|
|
@@ -279,10 +272,8 @@ The public vocabulary is converging on the terminal domain model (name the thing
|
|
|
279
272
|
| `getText()` | Get all text (scrollback + screen) |
|
|
280
273
|
| `getTextRange(sr, sc, er, ec)` | Get text in a range |
|
|
281
274
|
| `getRow(row)` | Get cells for a screen row (row = cells, line = text) |
|
|
282
|
-
| `getLine(row)` | **Deprecated** — alias of `getRow` |
|
|
283
275
|
| `getCell(row, col)` | Get a single cell |
|
|
284
276
|
| `getCursor()` | Get cursor `{ col, row }` |
|
|
285
|
-
| `getCursorPosition()` | **Deprecated** — cursor `{ x, y }`; use `getCursor()` |
|
|
286
277
|
| `getCursorVisible()` | Check cursor visibility |
|
|
287
278
|
| `getCursorShape()` | Get cursor shape: `"block"`, `"underline"`, or `"bar"` |
|
|
288
279
|
| `getCursorBlinking()` | Check if cursor is blinking |
|
|
@@ -314,7 +305,7 @@ interface ScreenCell {
|
|
|
314
305
|
faint: boolean
|
|
315
306
|
italic: boolean
|
|
316
307
|
underline: "none" | "single" | "double" | "curly" | "dotted" | "dashed"
|
|
317
|
-
underlineColor:
|
|
308
|
+
underlineColor: Color | null
|
|
318
309
|
overline: boolean
|
|
319
310
|
strikethrough: boolean
|
|
320
311
|
inverse: boolean
|
|
@@ -363,7 +354,7 @@ history and repaint only what changed.
|
|
|
363
354
|
The buffer is the retained scrollback followed by the screen. **Absolute row 0 is the
|
|
364
355
|
oldest retained scrollback line**; the screen occupies the last `screenRows()` rows
|
|
365
356
|
(absolute `totalRows() - screenRows()` through `totalRows() - 1`). The existing
|
|
366
|
-
screen-relative reads (`
|
|
357
|
+
screen-relative reads (`getRow`, `getCell`) are unchanged — absolute addressing is
|
|
367
358
|
additive.
|
|
368
359
|
|
|
369
360
|
```typescript
|
|
@@ -376,7 +367,7 @@ screen.viewportTop() // absolute row of the viewport's top line
|
|
|
376
367
|
|
|
377
368
|
Naming follows the ecosystem rule **row = cells, line = text**: `getRowAbsolute`
|
|
378
369
|
returns cells; colors are stripped of palette-origin index at the read boundary (same
|
|
379
|
-
contract as `
|
|
370
|
+
contract as `getRow`). Out-of-range indices return a blank row.
|
|
380
371
|
|
|
381
372
|
**Stability contract.** As lines scroll IN, an existing scrollback row keeps its
|
|
382
373
|
absolute index (the screen shifts up in absolute terms, but its content keeps the same
|
package/dist/index.d.mts
CHANGED
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
* An RGB color, identity-preserving. `r`/`g`/`b` are always present (painters read
|
|
38
38
|
* them unconditionally); `index` is optional palette provenance. Named `Color` per the
|
|
39
39
|
* §9 naming ruling (rule 5: flat progressive shape over a discriminated union — a type
|
|
40
|
-
* named `RGB` that carries `.index` would lie).
|
|
40
|
+
* named `RGB` that carries `.index` would lie).
|
|
41
41
|
*/
|
|
42
42
|
interface Color {
|
|
43
43
|
r: number;
|
|
@@ -61,18 +61,16 @@ interface Color {
|
|
|
61
61
|
*/
|
|
62
62
|
index?: number;
|
|
63
63
|
}
|
|
64
|
-
/** @deprecated Renamed to {@link Color} (§9 naming ruling). This alias rides the migration window. */
|
|
65
|
-
type CellColor = Color;
|
|
66
64
|
type UnderlineStyle = "none" | "single" | "double" | "curly" | "dotted" | "dashed";
|
|
67
65
|
interface ScreenCell {
|
|
68
66
|
char: string;
|
|
69
|
-
fg:
|
|
70
|
-
bg:
|
|
67
|
+
fg: Color | null;
|
|
68
|
+
bg: Color | null;
|
|
71
69
|
bold: boolean;
|
|
72
70
|
faint: boolean;
|
|
73
71
|
italic: boolean;
|
|
74
72
|
underline: UnderlineStyle;
|
|
75
|
-
underlineColor:
|
|
73
|
+
underlineColor: Color | null;
|
|
76
74
|
overline: boolean;
|
|
77
75
|
strikethrough: boolean;
|
|
78
76
|
inverse: boolean;
|
|
@@ -87,7 +85,16 @@ interface ScreenOptions {
|
|
|
87
85
|
scrollbackLimit?: number;
|
|
88
86
|
/** Callback for DA1/DA2/DSR responses — write these back to the PTY */
|
|
89
87
|
onResponse?: (data: string) => void;
|
|
88
|
+
/**
|
|
89
|
+
* Maximum UTF-16 code units retained for one APC or DCS string sequence.
|
|
90
|
+
* Image protocols use ASCII/base64 payloads, so this is also their byte
|
|
91
|
+
* bound. Longer sequences are consumed without buffering or dispatch and
|
|
92
|
+
* surface one typed `string-overflow` parser event at their terminator.
|
|
93
|
+
*/
|
|
94
|
+
maxStringSequenceLength?: number;
|
|
90
95
|
}
|
|
96
|
+
/** Default retained payload bound for one APC/DCS sequence (16 MiB of ASCII/base64). */
|
|
97
|
+
declare const DEFAULT_MAX_STRING_SEQUENCE_LENGTH: number;
|
|
91
98
|
interface SemanticZone {
|
|
92
99
|
type: "prompt" | "command" | "output";
|
|
93
100
|
startRow: number;
|
|
@@ -99,13 +106,13 @@ interface SixelImage {
|
|
|
99
106
|
col: number;
|
|
100
107
|
}
|
|
101
108
|
interface ScreenAttrsSnapshot {
|
|
102
|
-
fg:
|
|
103
|
-
bg:
|
|
109
|
+
fg: Color | null;
|
|
110
|
+
bg: Color | null;
|
|
104
111
|
bold: boolean;
|
|
105
112
|
faint: boolean;
|
|
106
113
|
italic: boolean;
|
|
107
114
|
underline: UnderlineStyle;
|
|
108
|
-
underlineColor:
|
|
115
|
+
underlineColor: Color | null;
|
|
109
116
|
overline: boolean;
|
|
110
117
|
strikethrough: boolean;
|
|
111
118
|
inverse: boolean;
|
|
@@ -114,15 +121,15 @@ interface ScreenAttrsSnapshot {
|
|
|
114
121
|
url: string | null;
|
|
115
122
|
}
|
|
116
123
|
interface ScreenColorStateSnapshot {
|
|
117
|
-
palette256:
|
|
118
|
-
defaultFgColor:
|
|
119
|
-
defaultBgColor:
|
|
120
|
-
cursorColor:
|
|
121
|
-
specialColors: [number,
|
|
122
|
-
pointerFgColor:
|
|
123
|
-
pointerBgColor:
|
|
124
|
-
highlightBgColor:
|
|
125
|
-
highlightFgColor:
|
|
124
|
+
palette256: Color[];
|
|
125
|
+
defaultFgColor: Color | null;
|
|
126
|
+
defaultBgColor: Color | null;
|
|
127
|
+
cursorColor: Color | null;
|
|
128
|
+
specialColors: [number, Color][];
|
|
129
|
+
pointerFgColor: Color | null;
|
|
130
|
+
pointerBgColor: Color | null;
|
|
131
|
+
highlightBgColor: Color | null;
|
|
132
|
+
highlightFgColor: Color | null;
|
|
126
133
|
}
|
|
127
134
|
type ScreenParserState = "ground" | "escape" | "escape_charset" | "escape_hash" | "csi" | "osc" | "dcs" | "dcs_passthrough" | "osc_st" | "dcs_st" | "apc" | "apc_st";
|
|
128
135
|
interface ScreenBufferSnapshot {
|
|
@@ -132,8 +139,7 @@ interface ScreenBufferSnapshot {
|
|
|
132
139
|
/**
|
|
133
140
|
* The whole-world persist/restore value — grids, ranges, modes, cursor, colors,
|
|
134
141
|
* parser transients, wrap bits. JSON-safe plain data; the persist boundary, not the
|
|
135
|
-
* incremental read path. Named `Snapshot` per §9 (the namespace supplies the context)
|
|
136
|
-
* {@link ScreenSnapshot} is the deprecated alias.
|
|
142
|
+
* incremental read path. Named `Snapshot` per §9 (the namespace supplies the context).
|
|
137
143
|
*
|
|
138
144
|
* Note: `cursor`/`savedState` still carry `x`/`y` (not `col`/`row`) — the §9
|
|
139
145
|
* `Cursor{col,row}` field rename is DEFERRED here because these fields are the wire
|
|
@@ -223,7 +229,15 @@ interface Snapshot {
|
|
|
223
229
|
row: number;
|
|
224
230
|
col: number;
|
|
225
231
|
};
|
|
232
|
+
dcsReceivedLength?: number;
|
|
233
|
+
dcsOverflow?: boolean;
|
|
226
234
|
apc: string;
|
|
235
|
+
apcStart?: {
|
|
236
|
+
row: number;
|
|
237
|
+
col: number;
|
|
238
|
+
};
|
|
239
|
+
apcReceivedLength?: number;
|
|
240
|
+
apcOverflow?: boolean;
|
|
227
241
|
utf8PendingBytes: number[];
|
|
228
242
|
};
|
|
229
243
|
unicode: {
|
|
@@ -233,13 +247,10 @@ interface Snapshot {
|
|
|
233
247
|
afterZWJ: boolean;
|
|
234
248
|
};
|
|
235
249
|
}
|
|
236
|
-
/** @deprecated Renamed to {@link Snapshot} (§9 naming ruling). This alias rides the migration window. */
|
|
237
|
-
type ScreenSnapshot = Snapshot;
|
|
238
250
|
/**
|
|
239
251
|
* The cursor position at the read boundary, in the grid's own `col`/`row` vocabulary
|
|
240
252
|
* (§9 naming ruling: `x`/`y` contradicted the row/col naming used everywhere else, and
|
|
241
|
-
* the `State` suffix was redundant). Returned by {@link VtermScreen.getCursor}
|
|
242
|
-
* {@link VtermScreen.getCursorPosition} still returns the `{ x, y }` shape (deprecated).
|
|
253
|
+
* the `State` suffix was redundant). Returned by {@link VtermScreen.getCursor}.
|
|
243
254
|
*/
|
|
244
255
|
interface Cursor {
|
|
245
256
|
col: number;
|
|
@@ -279,8 +290,12 @@ type TerminalOp = {
|
|
|
279
290
|
* charset/`#` designators); `final` is the dispatching byte, `intermediates`
|
|
280
291
|
* carries the `(`/`)`/`#` designator byte when present.
|
|
281
292
|
*
|
|
282
|
-
*
|
|
283
|
-
*
|
|
293
|
+
* - `dcs` / `apc` — a complete bounded string sequence with the guest-local cursor anchor at
|
|
294
|
+
* sequence start. Payloads beyond `maxStringSequenceLength` are not dispatched;
|
|
295
|
+
* their terminator emits one typed `string-overflow` event instead.
|
|
296
|
+
*
|
|
297
|
+
* A listener MUST NOT throw — taps are fail-loud: an exception propagates out of the write call
|
|
298
|
+
* (the engine state stays consistent).
|
|
284
299
|
*/
|
|
285
300
|
type ParserEvent = {
|
|
286
301
|
kind: "print";
|
|
@@ -302,6 +317,23 @@ type ParserEvent = {
|
|
|
302
317
|
kind: "esc";
|
|
303
318
|
final: string;
|
|
304
319
|
intermediates?: string;
|
|
320
|
+
} | {
|
|
321
|
+
kind: "apc";
|
|
322
|
+
data: string;
|
|
323
|
+
row: number;
|
|
324
|
+
col: number;
|
|
325
|
+
} | {
|
|
326
|
+
kind: "dcs";
|
|
327
|
+
data: string;
|
|
328
|
+
row: number;
|
|
329
|
+
col: number;
|
|
330
|
+
} | {
|
|
331
|
+
kind: "string-overflow";
|
|
332
|
+
sequence: "apc" | "dcs";
|
|
333
|
+
maxLength: number;
|
|
334
|
+
receivedLength: number;
|
|
335
|
+
row: number;
|
|
336
|
+
col: number;
|
|
305
337
|
};
|
|
306
338
|
/**
|
|
307
339
|
* Accumulated per-row damage since the previous {@link Screen.takeDirty} call — the PULL-plane
|
|
@@ -452,8 +484,6 @@ interface Screen {
|
|
|
452
484
|
* stripped of palette-origin index at the read boundary.
|
|
453
485
|
*/
|
|
454
486
|
getRow(row: number): ScreenCell[];
|
|
455
|
-
/** @deprecated Renamed to {@link getRow} (§9: row = cells, line = text). */
|
|
456
|
-
getLine(row: number): ScreenCell[];
|
|
457
487
|
getText(): string;
|
|
458
488
|
/** Scrollback rows above the visible grid, oldest first, rendered like getText(). */
|
|
459
489
|
getScrollbackText(): string;
|
|
@@ -469,8 +499,8 @@ interface Screen {
|
|
|
469
499
|
viewportTop(): number;
|
|
470
500
|
/**
|
|
471
501
|
* The row at ABSOLUTE index `row` (row 0 = oldest retained scrollback line; the screen occupies
|
|
472
|
-
* the last `screenRows()` rows). Colors are stripped of palette-origin index like {@link
|
|
473
|
-
* Out-of-range indices return a blank row (matching the {@link
|
|
502
|
+
* the last `screenRows()` rows). Colors are stripped of palette-origin index like {@link getRow}.
|
|
503
|
+
* Out-of-range indices return a blank row (matching the {@link getRow} read-boundary contract).
|
|
474
504
|
*/
|
|
475
505
|
getRowAbsolute(row: number): ScreenCell[];
|
|
476
506
|
/**
|
|
@@ -488,11 +518,6 @@ interface Screen {
|
|
|
488
518
|
takeDirty(): DirtyRegion;
|
|
489
519
|
/** Cursor position in the grid's `col`/`row` vocabulary (§9). See {@link Cursor}. */
|
|
490
520
|
getCursor(): Cursor;
|
|
491
|
-
/** @deprecated Use {@link getCursor} — returns `{ col, row }` per the §9 naming ruling. */
|
|
492
|
-
getCursorPosition(): {
|
|
493
|
-
x: number;
|
|
494
|
-
y: number;
|
|
495
|
-
};
|
|
496
521
|
getCursorVisible(): boolean;
|
|
497
522
|
getCursorShape(): "block" | "underline" | "bar";
|
|
498
523
|
getCursorBlinking(): boolean;
|
|
@@ -534,19 +559,19 @@ interface SerializeOptions {
|
|
|
534
559
|
* color stack, and parser/pending-wrap/mid-parse state are unserializable to
|
|
535
560
|
* a VT byte stream by design — the binary snapshot carries them.
|
|
536
561
|
*/
|
|
537
|
-
declare function serializeSnapshot(snapshot:
|
|
562
|
+
declare function serializeSnapshot(snapshot: Snapshot, options?: SerializeOptions): string;
|
|
538
563
|
//#endregion
|
|
539
564
|
//#region src/snapshot-codec.d.ts
|
|
540
565
|
/**
|
|
541
|
-
* Encode a {@link
|
|
566
|
+
* Encode a {@link Snapshot} to a compact binary buffer. Output is
|
|
542
567
|
* deterministic for identical input and decodes back to a deep-equal snapshot.
|
|
543
568
|
*/
|
|
544
|
-
declare function encodeScreenSnapshotBinary(snapshot:
|
|
569
|
+
declare function encodeScreenSnapshotBinary(snapshot: Snapshot): Uint8Array;
|
|
545
570
|
/**
|
|
546
571
|
* Decode a buffer produced by {@link encodeScreenSnapshotBinary} back into a
|
|
547
|
-
* {@link
|
|
572
|
+
* {@link Snapshot}. Throws loudly on an unknown version byte, truncated
|
|
548
573
|
* input, or any internal inconsistency — never returns a partial/normalized result.
|
|
549
574
|
*/
|
|
550
|
-
declare function decodeScreenSnapshotBinary(bytes: Uint8Array):
|
|
575
|
+
declare function decodeScreenSnapshotBinary(bytes: Uint8Array): Snapshot;
|
|
551
576
|
//#endregion
|
|
552
|
-
export { type
|
|
577
|
+
export { type Color, type Cursor, DEFAULT_MAX_STRING_SEQUENCE_LENGTH, type DirtyRegion, type ParserEvent, type ReadSignal, type ScreenCell, type ScreenSignals, type SemanticZone, type SerializeOptions, type SixelImage, type Size, type Snapshot, type TerminalModes, type TerminalOp, type UnderlineStyle, type Screen as VtermScreen, type ScreenAttrsSnapshot as VtermScreenAttrsSnapshot, type ScreenBufferSnapshot as VtermScreenBufferSnapshot, type ScreenColorStateSnapshot as VtermScreenColorStateSnapshot, type ScreenOptions as VtermScreenOptions, type ScreenParserState as VtermScreenParserState, createScreen as createVtermScreen, decodeScreenSnapshotBinary, encodeScreenSnapshotBinary, serializeSnapshot };
|
package/dist/index.mjs
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
//#region src/screen.ts
|
|
2
|
+
/** Default retained payload bound for one APC/DCS sequence (16 MiB of ASCII/base64). */
|
|
3
|
+
const DEFAULT_MAX_STRING_SEQUENCE_LENGTH = 16 * 1024 * 1024;
|
|
2
4
|
/** Frozen sentinel for unwritten cells — never mutate, copy-on-write in writeChar(). */
|
|
3
5
|
const EMPTY_CELL = Object.freeze({
|
|
4
6
|
char: "",
|
|
@@ -21,10 +23,10 @@ function emptyCell() {
|
|
|
21
23
|
return { ...EMPTY_CELL };
|
|
22
24
|
}
|
|
23
25
|
/**
|
|
24
|
-
* Drop the palette-origin {@link
|
|
25
|
-
* boundary. `getCell`/`
|
|
26
|
+
* Drop the palette-origin {@link Color.index} for the public per-cell read
|
|
27
|
+
* boundary. `getCell`/`getRow` return the RESOLVED RGB — their long-standing
|
|
26
28
|
* contract — while the origin index is serialization-only provenance that rides
|
|
27
|
-
* {@link
|
|
29
|
+
* {@link Snapshot} (and thus `serialize()`), not the inspection API.
|
|
28
30
|
* Returns the SAME reference when there is no index (the common truecolor/null
|
|
29
31
|
* case), so the read path allocates nothing there.
|
|
30
32
|
*/
|
|
@@ -79,7 +81,7 @@ function bitsToUnderline(meta) {
|
|
|
79
81
|
function packRgb(c) {
|
|
80
82
|
return ((c.r & 255) << 16 | (c.g & 255) << 8 | c.b & 255) >>> 0;
|
|
81
83
|
}
|
|
82
|
-
/** Materialize a {@link
|
|
84
|
+
/** Materialize a {@link Color} from a packed RGB word + index (`-1` = no index). */
|
|
83
85
|
function unpackColor(rgb, idx) {
|
|
84
86
|
const r = rgb >> 16 & 255;
|
|
85
87
|
const g = rgb >> 8 & 255;
|
|
@@ -461,6 +463,8 @@ function createScreen(options = {}) {
|
|
|
461
463
|
let rows = options.rows ?? 24;
|
|
462
464
|
let scrollbackLimit = options.scrollbackLimit ?? 1e3;
|
|
463
465
|
const onResponse = options.onResponse;
|
|
466
|
+
const maxStringSequenceLength = options.maxStringSequenceLength ?? 16777216;
|
|
467
|
+
if (!Number.isSafeInteger(maxStringSequenceLength) || maxStringSequenceLength < 0) throw new RangeError("maxStringSequenceLength must be a non-negative safe integer");
|
|
464
468
|
let mainGrid = makeGrid(cols, rows);
|
|
465
469
|
let altGrid = makeGrid(cols, rows);
|
|
466
470
|
let grid = mainGrid;
|
|
@@ -718,7 +722,16 @@ function createScreen(options = {}) {
|
|
|
718
722
|
assertRecord("parser.dcsStart", parser.dcsStart);
|
|
719
723
|
assertInteger("parser.dcsStart.row", parser.dcsStart.row);
|
|
720
724
|
assertInteger("parser.dcsStart.col", parser.dcsStart.col);
|
|
725
|
+
if (parser.dcsReceivedLength !== void 0) assertInteger("parser.dcsReceivedLength", parser.dcsReceivedLength, 0);
|
|
726
|
+
if (parser.dcsOverflow !== void 0) assertBoolean("parser.dcsOverflow", parser.dcsOverflow);
|
|
721
727
|
assertString("parser.apc", parser.apc);
|
|
728
|
+
if (parser.apcStart !== void 0) {
|
|
729
|
+
assertRecord("parser.apcStart", parser.apcStart);
|
|
730
|
+
assertInteger("parser.apcStart.row", parser.apcStart.row);
|
|
731
|
+
assertInteger("parser.apcStart.col", parser.apcStart.col);
|
|
732
|
+
}
|
|
733
|
+
if (parser.apcReceivedLength !== void 0) assertInteger("parser.apcReceivedLength", parser.apcReceivedLength, 0);
|
|
734
|
+
if (parser.apcOverflow !== void 0) assertBoolean("parser.apcOverflow", parser.apcOverflow);
|
|
722
735
|
if (!Array.isArray(parser.utf8PendingBytes)) throw new TypeError("Invalid vterm snapshot parser.utf8PendingBytes");
|
|
723
736
|
for (const byte of parser.utf8PendingBytes) {
|
|
724
737
|
assertInteger("parser.utf8PendingBytes", byte, 0);
|
|
@@ -775,7 +788,13 @@ function createScreen(options = {}) {
|
|
|
775
788
|
let dcsBuf = "";
|
|
776
789
|
let dcsStartRow = 0;
|
|
777
790
|
let dcsStartCol = 0;
|
|
791
|
+
let dcsReceivedLength = 0;
|
|
792
|
+
let dcsOverflow = false;
|
|
778
793
|
let apcBuf = "";
|
|
794
|
+
let apcStartRow = 0;
|
|
795
|
+
let apcStartCol = 0;
|
|
796
|
+
let apcReceivedLength = 0;
|
|
797
|
+
let apcOverflow = false;
|
|
779
798
|
const opListeners = /* @__PURE__ */ new Set();
|
|
780
799
|
const parserListeners = /* @__PURE__ */ new Set();
|
|
781
800
|
let printRunParts = [];
|
|
@@ -2686,7 +2705,13 @@ function createScreen(options = {}) {
|
|
|
2686
2705
|
dcsBuf = "";
|
|
2687
2706
|
dcsStartRow = 0;
|
|
2688
2707
|
dcsStartCol = 0;
|
|
2708
|
+
dcsReceivedLength = 0;
|
|
2709
|
+
dcsOverflow = false;
|
|
2689
2710
|
apcBuf = "";
|
|
2711
|
+
apcStartRow = 0;
|
|
2712
|
+
apcStartCol = 0;
|
|
2713
|
+
apcReceivedLength = 0;
|
|
2714
|
+
apcOverflow = false;
|
|
2690
2715
|
utf8PendingBytes = [];
|
|
2691
2716
|
semanticZones = [];
|
|
2692
2717
|
mainSoftWrapped = new Array(rows).fill(false);
|
|
@@ -2759,6 +2784,68 @@ function createScreen(options = {}) {
|
|
|
2759
2784
|
if (intermediates !== "") ev.intermediates = intermediates;
|
|
2760
2785
|
emitParserEvent(ev);
|
|
2761
2786
|
}
|
|
2787
|
+
function emitStringEvent(sequence, data, row, col) {
|
|
2788
|
+
if (parserListeners.size === 0) return;
|
|
2789
|
+
flushPrintRun();
|
|
2790
|
+
emitParserEvent({
|
|
2791
|
+
kind: sequence,
|
|
2792
|
+
data,
|
|
2793
|
+
row,
|
|
2794
|
+
col
|
|
2795
|
+
});
|
|
2796
|
+
}
|
|
2797
|
+
function emitStringOverflow(sequence, receivedLength, row, col) {
|
|
2798
|
+
if (parserListeners.size === 0) return;
|
|
2799
|
+
flushPrintRun();
|
|
2800
|
+
emitParserEvent({
|
|
2801
|
+
kind: "string-overflow",
|
|
2802
|
+
sequence,
|
|
2803
|
+
maxLength: maxStringSequenceLength,
|
|
2804
|
+
receivedLength,
|
|
2805
|
+
row,
|
|
2806
|
+
col
|
|
2807
|
+
});
|
|
2808
|
+
}
|
|
2809
|
+
function appendDCS(ch) {
|
|
2810
|
+
dcsReceivedLength += ch.length;
|
|
2811
|
+
if (dcsOverflow) return;
|
|
2812
|
+
if (dcsReceivedLength > maxStringSequenceLength) {
|
|
2813
|
+
dcsOverflow = true;
|
|
2814
|
+
dcsBuf = "";
|
|
2815
|
+
return;
|
|
2816
|
+
}
|
|
2817
|
+
dcsBuf += ch;
|
|
2818
|
+
}
|
|
2819
|
+
function appendAPC(ch) {
|
|
2820
|
+
apcReceivedLength += ch.length;
|
|
2821
|
+
if (apcOverflow) return;
|
|
2822
|
+
if (apcReceivedLength > maxStringSequenceLength) {
|
|
2823
|
+
apcOverflow = true;
|
|
2824
|
+
apcBuf = "";
|
|
2825
|
+
return;
|
|
2826
|
+
}
|
|
2827
|
+
apcBuf += ch;
|
|
2828
|
+
}
|
|
2829
|
+
function finishDCS() {
|
|
2830
|
+
if (dcsOverflow) emitStringOverflow("dcs", dcsReceivedLength, dcsStartRow, dcsStartCol);
|
|
2831
|
+
else {
|
|
2832
|
+
handleDCS(dcsBuf);
|
|
2833
|
+
emitStringEvent("dcs", dcsBuf, dcsStartRow, dcsStartCol);
|
|
2834
|
+
}
|
|
2835
|
+
dcsBuf = "";
|
|
2836
|
+
dcsReceivedLength = 0;
|
|
2837
|
+
dcsOverflow = false;
|
|
2838
|
+
}
|
|
2839
|
+
function finishAPC() {
|
|
2840
|
+
if (apcOverflow) emitStringOverflow("apc", apcReceivedLength, apcStartRow, apcStartCol);
|
|
2841
|
+
else {
|
|
2842
|
+
handleAPC(apcBuf);
|
|
2843
|
+
emitStringEvent("apc", apcBuf, apcStartRow, apcStartCol);
|
|
2844
|
+
}
|
|
2845
|
+
apcBuf = "";
|
|
2846
|
+
apcReceivedLength = 0;
|
|
2847
|
+
apcOverflow = false;
|
|
2848
|
+
}
|
|
2762
2849
|
function emitOp(op) {
|
|
2763
2850
|
for (const listener of opListeners) listener(op);
|
|
2764
2851
|
}
|
|
@@ -2816,6 +2903,8 @@ function createScreen(options = {}) {
|
|
|
2816
2903
|
dcsBuf = "";
|
|
2817
2904
|
dcsStartRow = curY;
|
|
2818
2905
|
dcsStartCol = curX;
|
|
2906
|
+
dcsReceivedLength = 0;
|
|
2907
|
+
dcsOverflow = false;
|
|
2819
2908
|
} else if (ch === "c") {
|
|
2820
2909
|
fullReset();
|
|
2821
2910
|
parserState = "ground";
|
|
@@ -2900,6 +2989,10 @@ function createScreen(options = {}) {
|
|
|
2900
2989
|
} else if (ch === "_") {
|
|
2901
2990
|
parserState = "apc";
|
|
2902
2991
|
apcBuf = "";
|
|
2992
|
+
apcStartRow = curY;
|
|
2993
|
+
apcStartCol = curX;
|
|
2994
|
+
apcReceivedLength = 0;
|
|
2995
|
+
apcOverflow = false;
|
|
2903
2996
|
} else parserState = "ground";
|
|
2904
2997
|
break;
|
|
2905
2998
|
case "escape_charset":
|
|
@@ -2966,12 +3059,17 @@ function createScreen(options = {}) {
|
|
|
2966
3059
|
case "dcs":
|
|
2967
3060
|
if (code === 27) parserState = "dcs_st";
|
|
2968
3061
|
else if (code === 7) {
|
|
2969
|
-
|
|
3062
|
+
finishDCS();
|
|
2970
3063
|
parserState = "ground";
|
|
2971
|
-
} else
|
|
3064
|
+
} else appendDCS(ch);
|
|
2972
3065
|
break;
|
|
2973
3066
|
case "dcs_st":
|
|
2974
|
-
if (ch === "\\")
|
|
3067
|
+
if (ch === "\\") finishDCS();
|
|
3068
|
+
else {
|
|
3069
|
+
dcsBuf = "";
|
|
3070
|
+
dcsReceivedLength = 0;
|
|
3071
|
+
dcsOverflow = false;
|
|
3072
|
+
}
|
|
2975
3073
|
parserState = "ground";
|
|
2976
3074
|
break;
|
|
2977
3075
|
case "dcs_passthrough":
|
|
@@ -2980,12 +3078,17 @@ function createScreen(options = {}) {
|
|
|
2980
3078
|
case "apc":
|
|
2981
3079
|
if (code === 27) parserState = "apc_st";
|
|
2982
3080
|
else if (code === 7) {
|
|
2983
|
-
|
|
3081
|
+
finishAPC();
|
|
2984
3082
|
parserState = "ground";
|
|
2985
|
-
} else
|
|
3083
|
+
} else appendAPC(ch);
|
|
2986
3084
|
break;
|
|
2987
3085
|
case "apc_st":
|
|
2988
|
-
if (ch === "\\")
|
|
3086
|
+
if (ch === "\\") finishAPC();
|
|
3087
|
+
else {
|
|
3088
|
+
apcBuf = "";
|
|
3089
|
+
apcReceivedLength = 0;
|
|
3090
|
+
apcOverflow = false;
|
|
3091
|
+
}
|
|
2989
3092
|
parserState = "ground";
|
|
2990
3093
|
break;
|
|
2991
3094
|
}
|
|
@@ -3239,7 +3342,15 @@ function createScreen(options = {}) {
|
|
|
3239
3342
|
row: dcsStartRow,
|
|
3240
3343
|
col: dcsStartCol
|
|
3241
3344
|
},
|
|
3345
|
+
dcsReceivedLength,
|
|
3346
|
+
dcsOverflow,
|
|
3242
3347
|
apc: apcBuf,
|
|
3348
|
+
apcStart: {
|
|
3349
|
+
row: apcStartRow,
|
|
3350
|
+
col: apcStartCol
|
|
3351
|
+
},
|
|
3352
|
+
apcReceivedLength,
|
|
3353
|
+
apcOverflow,
|
|
3243
3354
|
utf8PendingBytes: [...utf8PendingBytes]
|
|
3244
3355
|
},
|
|
3245
3356
|
unicode: {
|
|
@@ -3319,7 +3430,13 @@ function createScreen(options = {}) {
|
|
|
3319
3430
|
dcsBuf = snapshotValue.parser.dcs;
|
|
3320
3431
|
dcsStartRow = snapshotValue.parser.dcsStart.row;
|
|
3321
3432
|
dcsStartCol = snapshotValue.parser.dcsStart.col;
|
|
3433
|
+
dcsReceivedLength = snapshotValue.parser.dcsReceivedLength ?? dcsBuf.length;
|
|
3434
|
+
dcsOverflow = snapshotValue.parser.dcsOverflow ?? false;
|
|
3322
3435
|
apcBuf = snapshotValue.parser.apc;
|
|
3436
|
+
apcStartRow = snapshotValue.parser.apcStart?.row ?? curY;
|
|
3437
|
+
apcStartCol = snapshotValue.parser.apcStart?.col ?? curX;
|
|
3438
|
+
apcReceivedLength = snapshotValue.parser.apcReceivedLength ?? apcBuf.length;
|
|
3439
|
+
apcOverflow = snapshotValue.parser.apcOverflow ?? false;
|
|
3323
3440
|
utf8PendingBytes = [...snapshotValue.parser.utf8PendingBytes];
|
|
3324
3441
|
charsetG0 = snapshotValue.unicode.charsetG0;
|
|
3325
3442
|
lastChar = snapshotValue.unicode.lastChar;
|
|
@@ -3348,7 +3465,7 @@ function createScreen(options = {}) {
|
|
|
3348
3465
|
if (!r || col >= cols) return emptyCell();
|
|
3349
3466
|
return stripCellColorIndex(r.getCellRaw(col));
|
|
3350
3467
|
}
|
|
3351
|
-
function
|
|
3468
|
+
function getRow(row) {
|
|
3352
3469
|
const r = grid[row];
|
|
3353
3470
|
if (!r) return makeRow(cols).toCells();
|
|
3354
3471
|
return r.toCells().map(stripCellColorIndex);
|
|
@@ -3642,8 +3759,7 @@ function createScreen(options = {}) {
|
|
|
3642
3759
|
snapshot,
|
|
3643
3760
|
restore,
|
|
3644
3761
|
getCell,
|
|
3645
|
-
getRow
|
|
3646
|
-
getLine,
|
|
3762
|
+
getRow,
|
|
3647
3763
|
getText,
|
|
3648
3764
|
getScrollbackText,
|
|
3649
3765
|
getTextRange,
|
|
@@ -3657,10 +3773,6 @@ function createScreen(options = {}) {
|
|
|
3657
3773
|
col: curX,
|
|
3658
3774
|
row: curY
|
|
3659
3775
|
}),
|
|
3660
|
-
getCursorPosition: () => ({
|
|
3661
|
-
x: curX,
|
|
3662
|
-
y: curY
|
|
3663
|
-
}),
|
|
3664
3776
|
getCursorVisible: () => curVisible,
|
|
3665
3777
|
getCursorShape: () => cursorShape,
|
|
3666
3778
|
getCursorBlinking: () => cursorBlinking,
|
|
@@ -4462,7 +4574,7 @@ function readGridSection(r, softWrapNullable, expected, strings, colors, styles)
|
|
|
4462
4574
|
};
|
|
4463
4575
|
}
|
|
4464
4576
|
/**
|
|
4465
|
-
* Encode a {@link
|
|
4577
|
+
* Encode a {@link Snapshot} to a compact binary buffer. Output is
|
|
4466
4578
|
* deterministic for identical input and decodes back to a deep-equal snapshot.
|
|
4467
4579
|
*/
|
|
4468
4580
|
function encodeScreenSnapshotBinary(snapshot) {
|
|
@@ -4505,7 +4617,7 @@ function encodeScreenSnapshotBinary(snapshot) {
|
|
|
4505
4617
|
}
|
|
4506
4618
|
/**
|
|
4507
4619
|
* Decode a buffer produced by {@link encodeScreenSnapshotBinary} back into a
|
|
4508
|
-
* {@link
|
|
4620
|
+
* {@link Snapshot}. Throws loudly on an unknown version byte, truncated
|
|
4509
4621
|
* input, or any internal inconsistency — never returns a partial/normalized result.
|
|
4510
4622
|
*/
|
|
4511
4623
|
function decodeScreenSnapshotBinary(bytes) {
|
|
@@ -4557,4 +4669,4 @@ function decodeScreenSnapshotBinary(bytes) {
|
|
|
4557
4669
|
};
|
|
4558
4670
|
}
|
|
4559
4671
|
//#endregion
|
|
4560
|
-
export { createScreen as createVtermScreen, decodeScreenSnapshotBinary, encodeScreenSnapshotBinary, serializeSnapshot };
|
|
4672
|
+
export { DEFAULT_MAX_STRING_SEQUENCE_LENGTH, createScreen as createVtermScreen, decodeScreenSnapshotBinary, encodeScreenSnapshotBinary, serializeSnapshot };
|