@jrichman/ink 6.4.10 → 6.4.12

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.
Files changed (108) hide show
  1. package/build/components/App.d.ts +6 -0
  2. package/build/components/App.js +5 -0
  3. package/build/components/App.js.map +1 -1
  4. package/build/components/AppContext.d.ts +36 -1
  5. package/build/components/AppContext.js +7 -2
  6. package/build/components/AppContext.js.map +1 -1
  7. package/build/components/Box.d.ts +26 -2
  8. package/build/components/Box.js +3 -2
  9. package/build/components/Box.js.map +1 -1
  10. package/build/components/StaticRender.d.ts +8 -0
  11. package/build/components/StaticRender.js +11 -0
  12. package/build/components/StaticRender.js.map +1 -0
  13. package/build/debug-log.d.ts +2 -0
  14. package/build/debug-log.js +44 -0
  15. package/build/debug-log.js.map +1 -0
  16. package/build/dom.d.ts +37 -3
  17. package/build/dom.js +19 -3
  18. package/build/dom.js.map +1 -1
  19. package/build/index.d.ts +4 -1
  20. package/build/index.js +3 -1
  21. package/build/index.js.map +1 -1
  22. package/build/ink.d.ts +38 -2
  23. package/build/ink.js +223 -97
  24. package/build/ink.js.map +1 -1
  25. package/build/measure-element.d.ts +20 -1
  26. package/build/measure-element.js +201 -51
  27. package/build/measure-element.js.map +1 -1
  28. package/build/output.d.ts +195 -10
  29. package/build/output.js +494 -160
  30. package/build/output.js.map +1 -1
  31. package/build/reconciler.js +19 -3
  32. package/build/reconciler.js.map +1 -1
  33. package/build/render-background.js +1 -1
  34. package/build/render-background.js.map +1 -1
  35. package/build/render-cached.d.ts +17 -0
  36. package/build/render-cached.js +62 -0
  37. package/build/render-cached.js.map +1 -0
  38. package/build/render-container.d.ts +24 -0
  39. package/build/render-container.js +169 -0
  40. package/build/render-container.js.map +1 -0
  41. package/build/render-node-to-output.d.ts +15 -7
  42. package/build/render-node-to-output.js +123 -485
  43. package/build/render-node-to-output.js.map +1 -1
  44. package/build/render-screen-reader.d.ts +5 -0
  45. package/build/render-screen-reader.js +54 -0
  46. package/build/render-screen-reader.js.map +1 -0
  47. package/build/render-scrollbar.d.ts +22 -0
  48. package/build/render-scrollbar.js +77 -0
  49. package/build/render-scrollbar.js.map +1 -0
  50. package/build/render-sticky.d.ts +56 -0
  51. package/build/render-sticky.js +314 -0
  52. package/build/render-sticky.js.map +1 -0
  53. package/build/render-text-node.d.ts +24 -0
  54. package/build/render-text-node.js +133 -0
  55. package/build/render-text-node.js.map +1 -0
  56. package/build/render.d.ts +39 -0
  57. package/build/render.js +5 -0
  58. package/build/render.js.map +1 -1
  59. package/build/renderer.d.ts +10 -2
  60. package/build/renderer.js +103 -7
  61. package/build/renderer.js.map +1 -1
  62. package/build/replay.d.ts +60 -0
  63. package/build/replay.js +138 -0
  64. package/build/replay.js.map +1 -0
  65. package/build/scroll.js +20 -1
  66. package/build/scroll.js.map +1 -1
  67. package/build/selection.d.ts +9 -0
  68. package/build/selection.js +47 -0
  69. package/build/selection.js.map +1 -1
  70. package/build/serialization.d.ts +28 -0
  71. package/build/serialization.js +267 -0
  72. package/build/serialization.js.map +1 -0
  73. package/build/styles.d.ts +18 -0
  74. package/build/styles.js.map +1 -1
  75. package/build/terminal-buffer.d.ts +53 -0
  76. package/build/terminal-buffer.js +441 -0
  77. package/build/terminal-buffer.js.map +1 -0
  78. package/build/worker/animation-controller.d.ts +72 -0
  79. package/build/worker/animation-controller.js +128 -0
  80. package/build/worker/animation-controller.js.map +1 -0
  81. package/build/worker/ansi-utils.d.ts +16 -0
  82. package/build/worker/ansi-utils.js +40 -0
  83. package/build/worker/ansi-utils.js.map +1 -0
  84. package/build/worker/canvas.d.ts +47 -0
  85. package/build/worker/canvas.js +94 -0
  86. package/build/worker/canvas.js.map +1 -0
  87. package/build/worker/compositor.d.ts +33 -0
  88. package/build/worker/compositor.js +314 -0
  89. package/build/worker/compositor.js.map +1 -0
  90. package/build/worker/platform.d.ts +15 -0
  91. package/build/worker/platform.js +19 -0
  92. package/build/worker/platform.js.map +1 -0
  93. package/build/worker/render-worker.d.ts +112 -0
  94. package/build/worker/render-worker.js +936 -0
  95. package/build/worker/render-worker.js.map +1 -0
  96. package/build/worker/scene-manager.d.ts +26 -0
  97. package/build/worker/scene-manager.js +99 -0
  98. package/build/worker/scene-manager.js.map +1 -0
  99. package/build/worker/scroll-optimizer.d.ts +32 -0
  100. package/build/worker/scroll-optimizer.js +110 -0
  101. package/build/worker/scroll-optimizer.js.map +1 -0
  102. package/build/worker/terminal-writer.d.ts +116 -0
  103. package/build/worker/terminal-writer.js +722 -0
  104. package/build/worker/terminal-writer.js.map +1 -0
  105. package/build/worker/worker-entry.d.ts +6 -0
  106. package/build/worker/worker-entry.js +130 -0
  107. package/build/worker/worker-entry.js.map +1 -0
  108. package/package.json +3 -1
@@ -0,0 +1,133 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Google LLC
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ import { isNodeSelectable } from './dom.js';
7
+ import { measureStyledChars, splitStyledCharsByNewline, toStyledCharacters, } from './measure-text.js';
8
+ import { wrapOrTruncateStyledChars } from './text-wrap.js';
9
+ import getMaxWidth from './get-max-width.js';
10
+ import squashTextNodes from './squash-text-nodes.js';
11
+ import { applySelectionToStyledChars } from './selection.js';
12
+ export const applyPaddingToStyledChars = (node, lines) => {
13
+ const yogaNode = node.childNodes[0]?.yogaNode;
14
+ if (yogaNode) {
15
+ const offsetX = yogaNode.getComputedLeft();
16
+ const offsetY = yogaNode.getComputedTop();
17
+ const space = {
18
+ type: 'char',
19
+ value: ' ',
20
+ fullWidth: false,
21
+ styles: [],
22
+ };
23
+ const paddingLeft = Array.from({ length: offsetX }).map(() => space);
24
+ lines = lines.map(line => [...paddingLeft, ...line]);
25
+ const paddingTop = Array.from({ length: offsetY }).map(() => []);
26
+ lines.unshift(...paddingTop);
27
+ }
28
+ return lines;
29
+ };
30
+ export const calculateWrappedCursorPosition = (lines, styledChars, targetOffset) => {
31
+ const styledCharToOffset = new Map();
32
+ let offset = 0;
33
+ for (const char of styledChars) {
34
+ styledCharToOffset.set(char, offset);
35
+ offset += char.value.length;
36
+ }
37
+ let cursorLineIndex = lines.length - 1;
38
+ let relativeCursorPosition = targetOffset;
39
+ // -1 represents "before document start" so first character (offset 0) is handled correctly
40
+ let previousLineEndOffset = -1;
41
+ for (const [i, line] of lines.entries()) {
42
+ if (line.length > 0) {
43
+ const firstChar = line.find(char => styledCharToOffset.has(char));
44
+ const lastChar = line.findLast(char => styledCharToOffset.has(char));
45
+ if (!firstChar || !lastChar) {
46
+ // Padding-only line (originally empty), treat as empty line
47
+ if (targetOffset > previousLineEndOffset) {
48
+ cursorLineIndex = i;
49
+ relativeCursorPosition = targetOffset - previousLineEndOffset - 1;
50
+ previousLineEndOffset++;
51
+ }
52
+ continue;
53
+ }
54
+ const lineStartOffset = styledCharToOffset.get(firstChar);
55
+ const lineEndOffset = styledCharToOffset.get(lastChar) + lastChar.value.length;
56
+ // Set as candidate if targetOffset is at or after line start
57
+ if (targetOffset >= lineStartOffset) {
58
+ cursorLineIndex = i;
59
+ relativeCursorPosition = Math.max(0, targetOffset - lineStartOffset);
60
+ }
61
+ // Finalize and exit if targetOffset is within or before this line's range.
62
+ // If targetOffset is in a gap (between previousLineEndOffset and lineStartOffset),
63
+ // the cursor stays at the previous line's end (already set in previous iteration).
64
+ if (targetOffset <= lineEndOffset) {
65
+ break;
66
+ }
67
+ previousLineEndOffset = lineEndOffset;
68
+ }
69
+ else if (i === 0 && targetOffset === 0) {
70
+ // Edge case: First line is empty and cursor is at position 0
71
+ cursorLineIndex = 0;
72
+ relativeCursorPosition = 0;
73
+ break;
74
+ }
75
+ else if (i > 0 && targetOffset > previousLineEndOffset) {
76
+ // Handle empty lines (usually caused by \n)
77
+ cursorLineIndex = i;
78
+ relativeCursorPosition = targetOffset - previousLineEndOffset - 1;
79
+ // Advance past the \n character
80
+ previousLineEndOffset++;
81
+ }
82
+ }
83
+ return { cursorLineIndex, relativeCursorPosition };
84
+ };
85
+ export function handleTextNode(node, output, options) {
86
+ const { x, y, newTransformers, selectionMap, selectionStyle } = options;
87
+ const text = squashTextNodes(node);
88
+ let styledChars = toStyledCharacters(text);
89
+ let selectionState;
90
+ const selectionRange = selectionMap?.get(node);
91
+ if (selectionRange) {
92
+ selectionState = {
93
+ range: selectionRange,
94
+ currentOffset: 0,
95
+ };
96
+ }
97
+ if (selectionState) {
98
+ styledChars = applySelectionToStyledChars(styledChars, selectionState, selectionStyle);
99
+ }
100
+ if (styledChars.length > 0 || node.internal_terminalCursorFocus) {
101
+ let lines = [];
102
+ let cursorLineIndex = 0;
103
+ let relativeCursorPosition = node.internal_terminalCursorPosition ?? 0;
104
+ if (styledChars.length > 0) {
105
+ const { width: currentWidth } = measureStyledChars(styledChars);
106
+ const maxWidth = getMaxWidth(node.yogaNode);
107
+ lines =
108
+ currentWidth > maxWidth
109
+ ? wrapOrTruncateStyledChars(styledChars, maxWidth, node.style.textWrap ?? 'wrap')
110
+ : splitStyledCharsByNewline(styledChars);
111
+ lines = applyPaddingToStyledChars(node, lines);
112
+ cursorLineIndex = lines.length - 1;
113
+ if (node.internal_terminalCursorFocus &&
114
+ node.internal_terminalCursorPosition !== undefined) {
115
+ ({ cursorLineIndex, relativeCursorPosition } =
116
+ calculateWrappedCursorPosition(lines, styledChars, node.internal_terminalCursorPosition));
117
+ }
118
+ }
119
+ else {
120
+ lines = [[]];
121
+ }
122
+ for (const [index, line] of lines.entries()) {
123
+ output.write(x, y + index, line, {
124
+ transformers: newTransformers,
125
+ lineIndex: index,
126
+ isTerminalCursorFocused: node.internal_terminalCursorFocus && index === cursorLineIndex,
127
+ terminalCursorPosition: relativeCursorPosition,
128
+ isSelectable: isNodeSelectable(node),
129
+ });
130
+ }
131
+ }
132
+ }
133
+ //# sourceMappingURL=render-text-node.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"render-text-node.js","sourceRoot":"","sources":["../src/render-text-node.ts"],"names":[],"mappings":"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"}
package/build/render.d.ts CHANGED
@@ -2,6 +2,7 @@ import type { ReactNode } from 'react';
2
2
  import { type StyledChar } from '@alcalzone/ansi-tokenize';
3
3
  import Ink, { type RenderMetrics } from './ink.js';
4
4
  import { type Selection } from './selection.js';
5
+ import { type DOMElement } from './dom.js';
5
6
  export type RenderOptions = {
6
7
  /**
7
8
  Output stream where app will be rendered.
@@ -89,6 +90,34 @@ export type RenderOptions = {
89
90
  */
90
91
  selectionStyle?: (char: StyledChar) => StyledChar;
91
92
  standardReactLayoutTiming?: boolean;
93
+ /**
94
+ * Use a separate process-based rendering mode so that render updates are
95
+ * not blocked by the main thread
96
+ *
97
+ * @default false
98
+ */
99
+ renderProcess?: boolean;
100
+ /**
101
+ * Use the terminal buffer logic (backbuffer tracking) for rendering.
102
+ * If `renderProcess` is also true, this is implied.
103
+ * If `renderProcess` is false and this is true, the terminal buffer logic runs in the main process.
104
+ *
105
+ * @default false
106
+ */
107
+ terminalBuffer?: boolean;
108
+ /**
109
+ * If true, the worker-based renderer will automatically scroll all scrollable regions
110
+ * by 1 line every 16ms. This is only supported when using `terminalBuffer` or `renderProcess`.
111
+ *
112
+ * @default false
113
+ */
114
+ animatedScroll?: boolean;
115
+ /**
116
+ * Render sticky headers stuck at the top/bottom of scrollable regions
117
+ * when they are pushed to the terminal backbuffer.
118
+ * @default false
119
+ */
120
+ stickyHeadersInBackbuffer?: boolean;
92
121
  };
93
122
  export type Instance = {
94
123
  /**
@@ -116,6 +145,16 @@ export type Instance = {
116
145
  * Get the selection object.
117
146
  */
118
147
  getSelection: () => Selection;
148
+ /**
149
+ * Exports the current internal rendering state to a JSON file and a human-readable text dump.
150
+ * Only supported when `terminalBuffer` is enabled.
151
+ * @param filename The path/name for the JSON file (e.g., 'snapshot.json').
152
+ */
153
+ dumpCurrentFrame: (filename: string) => void;
154
+ /**
155
+ * Internal root node of the Ink tree.
156
+ */
157
+ rootNode: DOMElement;
119
158
  };
120
159
  /**
121
160
  Mount a component and render the output.
package/build/render.js CHANGED
@@ -18,6 +18,9 @@ const render = (node, options) => {
18
18
  alternateBufferAlreadyActive: false,
19
19
  incrementalRendering: false,
20
20
  standardReactLayoutTiming: false,
21
+ renderProcess: false,
22
+ terminalBuffer: false,
23
+ animatedScroll: false,
21
24
  ...getOptions(options),
22
25
  };
23
26
  const instance = getInstance(inkOptions.stdout, () => new Ink(inkOptions));
@@ -32,6 +35,8 @@ const render = (node, options) => {
32
35
  clear: instance.clear,
33
36
  recalculateLayout: instance.recalculateLayout,
34
37
  getSelection: instance.getSelection,
38
+ dumpCurrentFrame: instance.dumpCurrentFrame,
39
+ rootNode: instance.rootNode,
35
40
  };
36
41
  };
37
42
  export default render;
@@ -1 +1 @@
1
- {"version":3,"file":"render.js","sourceRoot":"","sources":["../src/render.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,MAAM,EAAC,MAAM,aAAa,CAAC;AACnC,OAAO,OAAO,MAAM,cAAc,CAAC;AAGnC,OAAO,GAAqD,MAAM,UAAU,CAAC;AAC7E,OAAO,SAAS,MAAM,gBAAgB,CAAC;AAmJvC;;EAEE;AACF,MAAM,MAAM,GAAG,CACd,IAAe,EACf,OAA4C,EACjC,EAAE;IACb,MAAM,UAAU,GAAe;QAC9B,MAAM,EAAE,OAAO,CAAC,MAAM;QACtB,KAAK,EAAE,OAAO,CAAC,KAAK;QACpB,MAAM,EAAE,OAAO,CAAC,MAAM;QACtB,KAAK,EAAE,KAAK;QACZ,WAAW,EAAE,IAAI;QACjB,YAAY,EAAE,IAAI;QAClB,MAAM,EAAE,EAAE;QACV,eAAe,EAAE,KAAK;QACtB,4BAA4B,EAAE,KAAK;QACnC,oBAAoB,EAAE,KAAK;QAC3B,yBAAyB,EAAE,KAAK;QAChC,GAAG,UAAU,CAAC,OAAO,CAAC;KACtB,CAAC;IAEF,MAAM,QAAQ,GAAQ,WAAW,CAChC,UAAU,CAAC,MAAM,EACjB,GAAG,EAAE,CAAC,IAAI,GAAG,CAAC,UAAU,CAAC,CACzB,CAAC;IAEF,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IAEtB,OAAO;QACN,QAAQ,EAAE,QAAQ,CAAC,MAAM;QACzB,OAAO;YACN,QAAQ,CAAC,OAAO,EAAE,CAAC;QACpB,CAAC;QACD,aAAa,EAAE,QAAQ,CAAC,aAAa;QACrC,OAAO,EAAE,GAAG,EAAE,CAAC,SAAS,CAAC,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC;QAClD,KAAK,EAAE,QAAQ,CAAC,KAAK;QACrB,iBAAiB,EAAE,QAAQ,CAAC,iBAAiB;QAC7C,YAAY,EAAE,QAAQ,CAAC,YAAY;KACnC,CAAC;AACH,CAAC,CAAC;AAEF,eAAe,MAAM,CAAC;AAEtB,MAAM,UAAU,GAAG,CAClB,SAAyD,EAAE,EAC3C,EAAE;IAClB,IAAI,MAAM,YAAY,MAAM,EAAE,CAAC;QAC9B,OAAO;YACN,MAAM;YACN,KAAK,EAAE,OAAO,CAAC,KAAK;SACpB,CAAC;IACH,CAAC;IAED,OAAO,MAAM,CAAC;AACf,CAAC,CAAC;AAEF,MAAM,WAAW,GAAG,CACnB,MAA0B,EAC1B,cAAyB,EACnB,EAAE;IACR,IAAI,QAAQ,GAAG,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IAErC,IAAI,CAAC,QAAQ,EAAE,CAAC;QACf,QAAQ,GAAG,cAAc,EAAE,CAAC;QAC5B,SAAS,CAAC,GAAG,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;IACjC,CAAC;IAED,OAAO,QAAQ,CAAC;AACjB,CAAC,CAAC"}
1
+ {"version":3,"file":"render.js","sourceRoot":"","sources":["../src/render.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,MAAM,EAAC,MAAM,aAAa,CAAC;AACnC,OAAO,OAAO,MAAM,cAAc,CAAC;AAGnC,OAAO,GAAqD,MAAM,UAAU,CAAC;AAC7E,OAAO,SAAS,MAAM,gBAAgB,CAAC;AAgMvC;;EAEE;AACF,MAAM,MAAM,GAAG,CACd,IAAe,EACf,OAA4C,EACjC,EAAE;IACb,MAAM,UAAU,GAAe;QAC9B,MAAM,EAAE,OAAO,CAAC,MAAM;QACtB,KAAK,EAAE,OAAO,CAAC,KAAK;QACpB,MAAM,EAAE,OAAO,CAAC,MAAM;QACtB,KAAK,EAAE,KAAK;QACZ,WAAW,EAAE,IAAI;QACjB,YAAY,EAAE,IAAI;QAClB,MAAM,EAAE,EAAE;QACV,eAAe,EAAE,KAAK;QACtB,4BAA4B,EAAE,KAAK;QACnC,oBAAoB,EAAE,KAAK;QAC3B,yBAAyB,EAAE,KAAK;QAChC,aAAa,EAAE,KAAK;QACpB,cAAc,EAAE,KAAK;QACrB,cAAc,EAAE,KAAK;QACrB,GAAG,UAAU,CAAC,OAAO,CAAC;KACtB,CAAC;IAEF,MAAM,QAAQ,GAAQ,WAAW,CAChC,UAAU,CAAC,MAAM,EACjB,GAAG,EAAE,CAAC,IAAI,GAAG,CAAC,UAAU,CAAC,CACzB,CAAC;IAEF,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IAEtB,OAAO;QACN,QAAQ,EAAE,QAAQ,CAAC,MAAM;QACzB,OAAO;YACN,QAAQ,CAAC,OAAO,EAAE,CAAC;QACpB,CAAC;QACD,aAAa,EAAE,QAAQ,CAAC,aAAa;QACrC,OAAO,EAAE,GAAG,EAAE,CAAC,SAAS,CAAC,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC;QAClD,KAAK,EAAE,QAAQ,CAAC,KAAK;QACrB,iBAAiB,EAAE,QAAQ,CAAC,iBAAiB;QAC7C,YAAY,EAAE,QAAQ,CAAC,YAAY;QACnC,gBAAgB,EAAE,QAAQ,CAAC,gBAAgB;QAC3C,QAAQ,EAAE,QAAQ,CAAC,QAAQ;KAC3B,CAAC;AACH,CAAC,CAAC;AAEF,eAAe,MAAM,CAAC;AAEtB,MAAM,UAAU,GAAG,CAClB,SAAyD,EAAE,EAC3C,EAAE;IAClB,IAAI,MAAM,YAAY,MAAM,EAAE,CAAC;QAC9B,OAAO;YACN,MAAM;YACN,KAAK,EAAE,OAAO,CAAC,KAAK;SACpB,CAAC;IACH,CAAC;IAED,OAAO,MAAM,CAAC;AACf,CAAC,CAAC;AAEF,MAAM,WAAW,GAAG,CACnB,MAA0B,EAC1B,cAAyB,EACnB,EAAE;IACR,IAAI,QAAQ,GAAG,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IAErC,IAAI,CAAC,QAAQ,EAAE,CAAC;QACf,QAAQ,GAAG,cAAc,EAAE,CAAC;QAC5B,SAAS,CAAC,GAAG,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;IACjC,CAAC;IAED,OAAO,QAAQ,CAAC;AACjB,CAAC,CAAC"}
@@ -1,5 +1,6 @@
1
1
  import { type StyledChar } from '@alcalzone/ansi-tokenize';
2
- import { type DOMElement } from './dom.js';
2
+ import { type Region } from './output.js';
3
+ import { type DOMElement, type StickyHeader } from './dom.js';
3
4
  import { type Selection } from './selection.js';
4
5
  type Result = {
5
6
  output: string;
@@ -10,6 +11,13 @@ type Result = {
10
11
  row: number;
11
12
  col: number;
12
13
  };
14
+ stickyHeaders: StickyHeader[];
15
+ root?: Region;
13
16
  };
14
- declare const renderer: (node: DOMElement, isScreenReaderEnabled: boolean, selection?: Selection, selectionStyle?: (char: StyledChar) => StyledChar) => Result;
17
+ declare const renderer: (node: DOMElement, options: {
18
+ isScreenReaderEnabled: boolean;
19
+ selection?: Selection;
20
+ selectionStyle?: (char: StyledChar) => StyledChar;
21
+ skipScrollbars?: boolean;
22
+ }) => Result;
15
23
  export default renderer;
package/build/renderer.js CHANGED
@@ -1,6 +1,8 @@
1
- import renderNodeToOutput, { renderNodeToScreenReaderOutput, } from './render-node-to-output.js';
2
- import Output from './output.js';
3
- import { isNodeSelectable } from './dom.js';
1
+ import { styledCharsToString } from '@alcalzone/ansi-tokenize';
2
+ import renderNodeToOutput from './render-node-to-output.js';
3
+ import { renderNodeToScreenReaderOutput } from './render-screen-reader.js';
4
+ import Output, { flattenRegion, clampCursorColumn, } from './output.js';
5
+ import { isNodeSelectable, } from './dom.js';
4
6
  const calculateSelectionMap = (root, selection) => {
5
7
  const map = new Map();
6
8
  if (selection.rangeCount === 0) {
@@ -99,6 +101,53 @@ const calculateSelectionMap = (root, selection) => {
99
101
  hasFoundEnd = true;
100
102
  }
101
103
  }
104
+ else if (node.nodeName === 'ink-static-render') {
105
+ if (!isNodeSelectable(node)) {
106
+ return;
107
+ }
108
+ // For StaticRender, the node itself is returned by hitTest and behaves like a text node.
109
+ // However, if the user clicked inside it, startContainer or endContainer might be this node itself,
110
+ // or it could be spanned by a selection outside it.
111
+ const localLength = node.cachedRender?.selectableText?.length ?? 0;
112
+ let nodeStartIndex = -1;
113
+ let nodeEndIndex = -1;
114
+ let foundStartInNode = false;
115
+ let foundEndInNode = false;
116
+ if (startContainer === node) {
117
+ foundStartInNode = true;
118
+ nodeStartIndex = startOffset;
119
+ }
120
+ if (endContainer === node) {
121
+ foundEndInNode = true;
122
+ nodeEndIndex = endOffset;
123
+ }
124
+ // Also check if its parent contains it as start/end, though hitTest usually sets the node itself
125
+ if (node.parentNode) {
126
+ const index = node.parentNode.childNodes.indexOf(node);
127
+ if (startContainer === node.parentNode && startOffset === index) {
128
+ foundStartInNode = true;
129
+ nodeStartIndex = 0;
130
+ }
131
+ if (endContainer === node.parentNode && endOffset === index + 1) {
132
+ foundEndInNode = true;
133
+ nodeEndIndex = localLength;
134
+ }
135
+ }
136
+ if ((hasFoundStart || foundStartInNode) &&
137
+ (!hasFoundEnd || foundEndInNode)) {
138
+ const start = foundStartInNode ? nodeStartIndex : 0;
139
+ const end = foundEndInNode ? nodeEndIndex : localLength;
140
+ if (start !== -1 && end !== -1 && start < end) {
141
+ map.set(node, { start, end });
142
+ }
143
+ }
144
+ if (foundStartInNode) {
145
+ hasFoundStart = true;
146
+ }
147
+ if (foundEndInNode) {
148
+ hasFoundEnd = true;
149
+ }
150
+ }
102
151
  else {
103
152
  const { childNodes } = node;
104
153
  if (childNodes) {
@@ -125,7 +174,19 @@ const calculateSelectionMap = (root, selection) => {
125
174
  visit(root);
126
175
  return map;
127
176
  };
128
- const renderer = (node, isScreenReaderEnabled, selection, selectionStyle) => {
177
+ const renderer = (node, options) => {
178
+ const { isScreenReaderEnabled, selection, selectionStyle, skipScrollbars } = options;
179
+ const callBeforeRender = (n) => {
180
+ if (typeof n.internalOnBeforeRender === 'function') {
181
+ n.internalOnBeforeRender(n);
182
+ }
183
+ for (const child of n.childNodes) {
184
+ if (child.nodeName !== '#text') {
185
+ callBeforeRender(child);
186
+ }
187
+ }
188
+ };
189
+ callBeforeRender(node);
129
190
  if (node.yogaNode) {
130
191
  if (isScreenReaderEnabled) {
131
192
  const output = renderNodeToScreenReaderOutput(node, {
@@ -143,11 +204,13 @@ const renderer = (node, isScreenReaderEnabled, selection, selectionStyle) => {
143
204
  outputHeight,
144
205
  staticOutput: staticOutput ? `${staticOutput}\n` : '',
145
206
  styledOutput: [],
207
+ stickyHeaders: [],
146
208
  };
147
209
  }
148
210
  const output = new Output({
149
211
  width: node.yogaNode.getComputedWidth(),
150
212
  height: node.yogaNode.getComputedHeight(),
213
+ node,
151
214
  });
152
215
  const selectionMap = selection
153
216
  ? calculateSelectionMap(node, selection)
@@ -162,6 +225,8 @@ const renderer = (node, isScreenReaderEnabled, selection, selectionStyle) => {
162
225
  staticOutput = new Output({
163
226
  width: node.staticNode.yogaNode.getComputedWidth(),
164
227
  height: node.staticNode.yogaNode.getComputedHeight(),
228
+ node: node.staticNode,
229
+ id: node.staticNode.internalId,
165
230
  });
166
231
  renderNodeToOutput(node.staticNode, staticOutput, {
167
232
  skipStaticElements: false,
@@ -171,15 +236,20 @@ const renderer = (node, isScreenReaderEnabled, selection, selectionStyle) => {
171
236
  : undefined,
172
237
  });
173
238
  }
174
- const { output: generatedOutput, height: outputHeight, styledOutput, cursorPosition, } = output.get();
239
+ const rootRegion = output.get();
240
+ const { output: generatedOutput, height: outputHeight, styledOutput, cursorPosition, } = regionToOutput(rootRegion, { skipScrollbars });
175
241
  return {
176
242
  output: generatedOutput,
177
243
  outputHeight,
178
244
  // Newline at the end is needed, because static output doesn't have one, so
179
- // interactive output will override last line of static output
180
- staticOutput: staticOutput ? `${staticOutput.get().output}\n` : '',
245
+ // interactive output will override last line of static output.
246
+ staticOutput: staticOutput
247
+ ? `${regionToOutput(staticOutput.get()).output}\n`
248
+ : '',
181
249
  styledOutput,
182
250
  cursorPosition,
251
+ stickyHeaders: [],
252
+ root: rootRegion,
183
253
  };
184
254
  }
185
255
  return {
@@ -187,7 +257,33 @@ const renderer = (node, isScreenReaderEnabled, selection, selectionStyle) => {
187
257
  outputHeight: 0,
188
258
  staticOutput: '',
189
259
  styledOutput: [],
260
+ stickyHeaders: [],
261
+ root: undefined,
190
262
  };
191
263
  };
264
+ function regionToOutput(region, options) {
265
+ const context = {};
266
+ const lines = flattenRegion(region, { context, ...options });
267
+ if (context.cursorPosition) {
268
+ const { row, col } = context.cursorPosition;
269
+ const line = lines[row];
270
+ if (line) {
271
+ context.cursorPosition.col = clampCursorColumn(line, col);
272
+ }
273
+ }
274
+ // Flatten the root region for legacy string output
275
+ const generatedOutput = lines
276
+ .map(line => {
277
+ const lineWithoutEmptyItems = line.filter(item => item !== undefined);
278
+ return styledCharsToString(lineWithoutEmptyItems).trimEnd();
279
+ })
280
+ .join('\n');
281
+ return {
282
+ output: generatedOutput,
283
+ height: lines.length,
284
+ styledOutput: lines,
285
+ cursorPosition: context.cursorPosition,
286
+ };
287
+ }
192
288
  export default renderer;
193
289
  //# sourceMappingURL=renderer.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"renderer.js","sourceRoot":"","sources":["../src/renderer.ts"],"names":[],"mappings":"AACA,OAAO,kBAAkB,EAAE,EAC1B,8BAA8B,GAC9B,MAAM,4BAA4B,CAAC;AACpC,OAAO,MAAM,MAAM,aAAa,CAAC;AACjC,OAAO,EAAgC,gBAAgB,EAAC,MAAM,UAAU,CAAC;AAWzE,MAAM,qBAAqB,GAAG,CAC7B,IAAgB,EAChB,SAAoB,EACyB,EAAE;IAC/C,MAAM,GAAG,GAAG,IAAI,GAAG,EAAyC,CAAC;IAE7D,IAAI,SAAS,CAAC,UAAU,KAAK,CAAC,EAAE,CAAC;QAChC,OAAO,GAAG,CAAC;IACZ,CAAC;IAED,MAAM,KAAK,GAAG,SAAS,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;IACtC,MAAM,EAAC,cAAc,EAAE,WAAW,EAAE,YAAY,EAAE,SAAS,EAAC,GAAG,KAAK,CAAC;IAErE,IAAI,aAAa,GAAG,KAAK,CAAC;IAC1B,IAAI,WAAW,GAAG,KAAK,CAAC;IAExB,MAAM,KAAK,GAAG,CAAC,IAAa,EAAE,EAAE;QAC/B,IAAI,IAAI,CAAC,QAAQ,KAAK,UAAU,EAAE,CAAC;YAClC,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,EAAE,CAAC;gBAC7B,OAAO;YACR,CAAC;YAED,IAAI,WAAW,GAAG,CAAC,CAAC;YACpB,IAAI,cAAc,GAAG,CAAC,CAAC,CAAC;YACxB,IAAI,YAAY,GAAG,CAAC,CAAC,CAAC;YACtB,IAAI,gBAAgB,GAAG,KAAK,CAAC;YAC7B,IAAI,cAAc,GAAG,KAAK,CAAC;YAE3B,MAAM,aAAa,GAAG,CAAC,CAAU,EAAE,EAAE;gBACpC,IAAI,CAAC,CAAC,QAAQ,KAAK,OAAO,EAAE,CAAC;oBAC5B,MAAM,EAAC,MAAM,EAAC,GAAG,CAAC,CAAC,SAAS,CAAC;oBAE7B,IAAI,cAAc,KAAK,CAAC,EAAE,CAAC;wBAC1B,gBAAgB,GAAG,IAAI,CAAC;wBACxB,cAAc,GAAG,WAAW,GAAG,WAAW,CAAC;oBAC5C,CAAC;oBAED,IAAI,YAAY,KAAK,CAAC,EAAE,CAAC;wBACxB,cAAc,GAAG,IAAI,CAAC;wBACtB,YAAY,GAAG,WAAW,GAAG,SAAS,CAAC;oBACxC,CAAC;oBAED,WAAW,IAAI,MAAM,CAAC;gBACvB,CAAC;qBAAM,CAAC;oBACP,MAAM,EAAC,UAAU,EAAC,GAAG,CAAC,CAAC;oBACvB,IAAI,UAAU,EAAE,CAAC;wBAChB,KAAK,MAAM,KAAK,IAAI,UAAU,EAAE,CAAC;4BAChC,IAAI,CAAC,KAAK,cAAc,EAAE,CAAC;gCAC1B,gBAAgB,GAAG,IAAI,CAAC;gCACxB,cAAc,GAAG,WAAW,CAAC;4BAC9B,CAAC;4BAED,IAAI,CAAC,KAAK,YAAY,EAAE,CAAC;gCACxB,cAAc,GAAG,IAAI,CAAC;gCACtB,YAAY,GAAG,WAAW,CAAC;4BAC5B,CAAC;4BAED,IAAI,KAAK,EAAE,CAAC;gCACX,aAAa,CAAC,KAAK,CAAC,CAAC;4BACtB,CAAC;wBACF,CAAC;wBAED,IAAI,CAAC,KAAK,cAAc,IAAI,WAAW,KAAK,UAAU,CAAC,MAAM,EAAE,CAAC;4BAC/D,gBAAgB,GAAG,IAAI,CAAC;4BACxB,cAAc,GAAG,WAAW,CAAC;wBAC9B,CAAC;wBAED,IAAI,CAAC,KAAK,YAAY,IAAI,SAAS,KAAK,UAAU,CAAC,MAAM,EAAE,CAAC;4BAC3D,cAAc,GAAG,IAAI,CAAC;4BACtB,YAAY,GAAG,WAAW,CAAC;wBAC5B,CAAC;oBACF,CAAC;gBACF,CAAC;YACF,CAAC,CAAC;YAEF,MAAM,EAAC,UAAU,EAAC,GAAG,IAAI,CAAC;YAC1B,IAAI,UAAU,EAAE,CAAC;gBAChB,KAAK,MAAM,KAAK,IAAI,UAAU,EAAE,CAAC;oBAChC,IAAI,IAAI,KAAK,cAAc,EAAE,CAAC;wBAC7B,gBAAgB,GAAG,IAAI,CAAC;wBACxB,cAAc,GAAG,WAAW,CAAC;oBAC9B,CAAC;oBAED,IAAI,IAAI,KAAK,YAAY,EAAE,CAAC;wBAC3B,cAAc,GAAG,IAAI,CAAC;wBACtB,YAAY,GAAG,WAAW,CAAC;oBAC5B,CAAC;oBAED,IAAI,KAAK,EAAE,CAAC;wBACX,aAAa,CAAC,KAAK,CAAC,CAAC;oBACtB,CAAC;gBACF,CAAC;gBAED,IAAI,IAAI,KAAK,cAAc,IAAI,WAAW,KAAK,UAAU,CAAC,MAAM,EAAE,CAAC;oBAClE,gBAAgB,GAAG,IAAI,CAAC;oBACxB,cAAc,GAAG,WAAW,CAAC;gBAC9B,CAAC;gBAED,IAAI,IAAI,KAAK,YAAY,IAAI,SAAS,KAAK,UAAU,CAAC,MAAM,EAAE,CAAC;oBAC9D,cAAc,GAAG,IAAI,CAAC;oBACtB,YAAY,GAAG,WAAW,CAAC;gBAC5B,CAAC;YACF,CAAC;YAED,IACC,CAAC,aAAa,IAAI,gBAAgB,CAAC;gBACnC,CAAC,CAAC,WAAW,IAAI,cAAc,CAAC,EAC/B,CAAC;gBACF,MAAM,KAAK,GAAG,gBAAgB,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,CAAC;gBACpD,MAAM,GAAG,GAAG,cAAc,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,WAAW,CAAC;gBAExD,IAAI,KAAK,KAAK,CAAC,CAAC,IAAI,GAAG,KAAK,CAAC,CAAC,IAAI,KAAK,GAAG,GAAG,EAAE,CAAC;oBAC/C,GAAG,CAAC,GAAG,CAAC,IAAI,EAAE,EAAC,KAAK,EAAE,GAAG,EAAC,CAAC,CAAC;gBAC7B,CAAC;YACF,CAAC;YAED,IAAI,gBAAgB,EAAE,CAAC;gBACtB,aAAa,GAAG,IAAI,CAAC;YACtB,CAAC;YAED,IAAI,cAAc,EAAE,CAAC;gBACpB,WAAW,GAAG,IAAI,CAAC;YACpB,CAAC;QACF,CAAC;aAAM,CAAC;YACP,MAAM,EAAC,UAAU,EAAC,GAAG,IAAkB,CAAC;YACxC,IAAI,UAAU,EAAE,CAAC;gBAChB,KAAK,MAAM,KAAK,IAAI,UAAU,EAAE,CAAC;oBAChC,IAAI,IAAI,KAAK,cAAc,EAAE,CAAC;wBAC7B,aAAa,GAAG,IAAI,CAAC;oBACtB,CAAC;oBAED,IAAI,IAAI,KAAK,YAAY,EAAE,CAAC;wBAC3B,WAAW,GAAG,IAAI,CAAC;oBACpB,CAAC;oBAED,IAAI,KAAK,EAAE,CAAC;wBACX,KAAK,CAAC,KAAK,CAAC,CAAC;oBACd,CAAC;gBACF,CAAC;gBAED,IAAI,IAAI,KAAK,cAAc,IAAI,WAAW,KAAK,UAAU,CAAC,MAAM,EAAE,CAAC;oBAClE,aAAa,GAAG,IAAI,CAAC;gBACtB,CAAC;gBAED,IAAI,IAAI,KAAK,YAAY,IAAI,SAAS,KAAK,UAAU,CAAC,MAAM,EAAE,CAAC;oBAC9D,WAAW,GAAG,IAAI,CAAC;gBACpB,CAAC;YACF,CAAC;QACF,CAAC;IACF,CAAC,CAAC;IAEF,KAAK,CAAC,IAAI,CAAC,CAAC;IAEZ,OAAO,GAAG,CAAC;AACZ,CAAC,CAAC;AAEF,MAAM,QAAQ,GAAG,CAChB,IAAgB,EAChB,qBAA8B,EAC9B,SAAqB,EACrB,cAAiD,EACxC,EAAE;IACX,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;QACnB,IAAI,qBAAqB,EAAE,CAAC;YAC3B,MAAM,MAAM,GAAG,8BAA8B,CAAC,IAAI,EAAE;gBACnD,kBAAkB,EAAE,IAAI;aACxB,CAAC,CAAC;YAEH,MAAM,YAAY,GAAG,MAAM,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC;YAEnE,IAAI,YAAY,GAAG,EAAE,CAAC;YAEtB,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;gBACrB,YAAY,GAAG,8BAA8B,CAAC,IAAI,CAAC,UAAU,EAAE;oBAC9D,kBAAkB,EAAE,KAAK;iBACzB,CAAC,CAAC;YACJ,CAAC;YAED,OAAO;gBACN,MAAM;gBACN,YAAY;gBACZ,YAAY,EAAE,YAAY,CAAC,CAAC,CAAC,GAAG,YAAY,IAAI,CAAC,CAAC,CAAC,EAAE;gBACrD,YAAY,EAAE,EAAE;aAChB,CAAC;QACH,CAAC;QAED,MAAM,MAAM,GAAG,IAAI,MAAM,CAAC;YACzB,KAAK,EAAE,IAAI,CAAC,QAAQ,CAAC,gBAAgB,EAAE;YACvC,MAAM,EAAE,IAAI,CAAC,QAAQ,CAAC,iBAAiB,EAAE;SACzC,CAAC,CAAC;QAEH,MAAM,YAAY,GAAG,SAAS;YAC7B,CAAC,CAAC,qBAAqB,CAAC,IAAI,EAAE,SAAS,CAAC;YACxC,CAAC,CAAC,SAAS,CAAC;QAEb,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE;YAChC,kBAAkB,EAAE,IAAI;YACxB,cAAc;YACd,YAAY;SACZ,CAAC,CAAC;QAEH,IAAI,YAAY,CAAC;QAEjB,IAAI,IAAI,CAAC,UAAU,EAAE,QAAQ,EAAE,CAAC;YAC/B,YAAY,GAAG,IAAI,MAAM,CAAC;gBACzB,KAAK,EAAE,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,gBAAgB,EAAE;gBAClD,MAAM,EAAE,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,iBAAiB,EAAE;aACpD,CAAC,CAAC;YAEH,kBAAkB,CAAC,IAAI,CAAC,UAAU,EAAE,YAAY,EAAE;gBACjD,kBAAkB,EAAE,KAAK;gBACzB,cAAc;gBACd,YAAY,EAAE,SAAS;oBACtB,CAAC,CAAC,qBAAqB,CAAC,IAAI,CAAC,UAAU,EAAE,SAAS,CAAC;oBACnD,CAAC,CAAC,SAAS;aACZ,CAAC,CAAC;QACJ,CAAC;QAED,MAAM,EACL,MAAM,EAAE,eAAe,EACvB,MAAM,EAAE,YAAY,EACpB,YAAY,EACZ,cAAc,GACd,GAAG,MAAM,CAAC,GAAG,EAAE,CAAC;QAEjB,OAAO;YACN,MAAM,EAAE,eAAe;YACvB,YAAY;YACZ,2EAA2E;YAC3E,8DAA8D;YAC9D,YAAY,EAAE,YAAY,CAAC,CAAC,CAAC,GAAG,YAAY,CAAC,GAAG,EAAE,CAAC,MAAM,IAAI,CAAC,CAAC,CAAC,EAAE;YAClE,YAAY;YACZ,cAAc;SACd,CAAC;IACH,CAAC;IAED,OAAO;QACN,MAAM,EAAE,EAAE;QACV,YAAY,EAAE,CAAC;QACf,YAAY,EAAE,EAAE;QAChB,YAAY,EAAE,EAAE;KAChB,CAAC;AACH,CAAC,CAAC;AAEF,eAAe,QAAQ,CAAC"}
1
+ {"version":3,"file":"renderer.js","sourceRoot":"","sources":["../src/renderer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,60 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Google LLC
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ import { type RegionNode, type RegionUpdate } from './output.js';
7
+ import { type Serializer } from './serialization.js';
8
+ import { type StickyHeader } from './dom.js';
9
+ export type ReplayData = {
10
+ type: 'single' | 'sequence';
11
+ columns: number;
12
+ rows: number;
13
+ frames: ReplayFrame[];
14
+ };
15
+ export type ReplayFrame = {
16
+ tree: RegionNode;
17
+ updates: ReplayRegionUpdate[];
18
+ cursorPosition?: {
19
+ row: number;
20
+ col: number;
21
+ };
22
+ timestamp: number;
23
+ };
24
+ export type ReplayRegionUpdate = Omit<RegionUpdate, 'lines' | 'stickyHeaders'> & {
25
+ lines?: {
26
+ updates: Array<{
27
+ start: number;
28
+ end: number;
29
+ data: string;
30
+ source?: string;
31
+ }>;
32
+ totalLength: number;
33
+ };
34
+ stickyHeaders?: ReplayStickyHeader[];
35
+ };
36
+ export type ReplayStickyHeader = Omit<StickyHeader, 'node' | 'anchor' | 'lines' | 'stuckLines' | 'styledOutput'> & {
37
+ lines: string;
38
+ stuckLines?: string;
39
+ styledOutput: string;
40
+ };
41
+ export declare function serializeReplayUpdate(update: RegionUpdate, serializer: Serializer): ReplayRegionUpdate;
42
+ export declare function deserializeReplayUpdate(update: ReplayRegionUpdate): RegionUpdate;
43
+ export declare function saveReplay(data: ReplayData, filename: string): void;
44
+ export type LoadedReplayData = {
45
+ type: 'single' | 'sequence';
46
+ columns: number;
47
+ rows: number;
48
+ frames: LoadedReplayFrame[];
49
+ };
50
+ export type LoadedReplayFrame = {
51
+ tree: RegionNode;
52
+ updates: RegionUpdate[];
53
+ cursorPosition?: {
54
+ row: number;
55
+ col: number;
56
+ };
57
+ timestamp: number;
58
+ };
59
+ export declare function loadReplay(jsonStr: string): LoadedReplayData;
60
+ export declare function createHumanReadableDump(data: LoadedReplayData): string;
@@ -0,0 +1,138 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Google LLC
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ import fs from 'node:fs';
7
+ import { Buffer } from 'node:buffer';
8
+ import { Deserializer } from './serialization.js';
9
+ export function serializeReplayUpdate(update, serializer) {
10
+ const { lines, stickyHeaders, ...rest } = update;
11
+ const result = {
12
+ ...rest,
13
+ };
14
+ if (lines) {
15
+ result.lines = {
16
+ totalLength: lines.totalLength,
17
+ updates: lines.updates.map(u => ({
18
+ start: u.start,
19
+ end: u.end,
20
+ data: Buffer.from(u.data).toString('base64'),
21
+ source: u.source ? Buffer.from(u.source).toString('base64') : undefined,
22
+ })),
23
+ };
24
+ }
25
+ if (stickyHeaders) {
26
+ result.stickyHeaders = stickyHeaders.map(h => ({
27
+ ...h,
28
+ node: undefined,
29
+ lines: Buffer.from(serializer.serialize(h.lines ?? [])).toString('base64'),
30
+ stuckLines: h.stuckLines
31
+ ? Buffer.from(serializer.serialize(h.stuckLines)).toString('base64')
32
+ : undefined,
33
+ styledOutput: Buffer.from(serializer.serialize(h.styledOutput ?? [])).toString('base64'),
34
+ }));
35
+ }
36
+ return result;
37
+ }
38
+ export function deserializeReplayUpdate(update) {
39
+ const { lines, stickyHeaders, ...rest } = update;
40
+ const result = {
41
+ ...rest,
42
+ };
43
+ if (lines) {
44
+ result.lines = {
45
+ totalLength: lines.totalLength,
46
+ updates: lines.updates.map(u => ({
47
+ start: u.start,
48
+ end: u.end,
49
+ data: Buffer.from(u.data, 'base64'),
50
+ source: u.source ? Buffer.from(u.source, 'base64') : undefined,
51
+ })),
52
+ };
53
+ }
54
+ if (stickyHeaders) {
55
+ result.stickyHeaders = stickyHeaders.map(h => {
56
+ const header = {
57
+ ...h,
58
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
59
+ node: undefined,
60
+ lines: new Deserializer(Buffer.from(h.lines, 'base64')).deserialize(),
61
+ stuckLines: h.stuckLines
62
+ ? new Deserializer(Buffer.from(h.stuckLines, 'base64')).deserialize()
63
+ : undefined,
64
+ styledOutput: new Deserializer(Buffer.from(h.styledOutput, 'base64')).deserialize(),
65
+ };
66
+ return header;
67
+ });
68
+ }
69
+ return result;
70
+ }
71
+ export function saveReplay(data, filename) {
72
+ fs.writeFileSync(filename, JSON.stringify(data, null, 2));
73
+ }
74
+ export function loadReplay(jsonStr) {
75
+ const raw = JSON.parse(jsonStr);
76
+ return {
77
+ ...raw,
78
+ frames: raw.frames.map(f => ({
79
+ ...f,
80
+ updates: f.updates.map(u => deserializeReplayUpdate(u)),
81
+ })),
82
+ };
83
+ }
84
+ export function createHumanReadableDump(data) {
85
+ const dumpData = {
86
+ type: data.type,
87
+ columns: data.columns,
88
+ rows: data.rows,
89
+ frames: data.frames.map(frame => ({
90
+ tree: frame.tree,
91
+ cursorPosition: frame.cursorPosition,
92
+ updates: frame.updates.map(update => {
93
+ const dumpUpdate = { ...update };
94
+ // Explicitly copy properties that could be undefined if omitted in object spread occasionally
95
+ dumpUpdate['overflowToBackbuffer'] = update.overflowToBackbuffer;
96
+ dumpUpdate['isScrollable'] = update.isScrollable;
97
+ if (update.lines) {
98
+ dumpUpdate['lines'] = {
99
+ totalLength: update.lines.totalLength,
100
+ updates: update.lines.updates.map(u => {
101
+ const deserializer = new Deserializer(Buffer.from(u.data));
102
+ const lines = deserializer.deserialize();
103
+ return {
104
+ start: u.start,
105
+ end: u.end,
106
+ text: lines.map(line => line
107
+ .map(c => c.value)
108
+ .join('')
109
+ .trimEnd()),
110
+ };
111
+ }),
112
+ };
113
+ }
114
+ if (update.stickyHeaders) {
115
+ dumpUpdate['stickyHeaders'] = update.stickyHeaders.map(h => ({
116
+ ...h,
117
+ lines: (h.lines ?? []).map(line => line
118
+ .map(c => c.value)
119
+ .join('')
120
+ .trimEnd()),
121
+ stuckLines: h.stuckLines?.map(line => line
122
+ .map(c => c.value)
123
+ .join('')
124
+ .trimEnd()),
125
+ styledOutput: (h.styledOutput ?? []).map(line => line
126
+ .map(c => c.value)
127
+ .join('')
128
+ .trimEnd()),
129
+ node: undefined,
130
+ }));
131
+ }
132
+ return dumpUpdate;
133
+ }),
134
+ })),
135
+ };
136
+ return JSON.stringify(dumpData, null, 2);
137
+ }
138
+ //# sourceMappingURL=replay.js.map