@jitl/opentui-core 0.1.97-next.61f6679

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 (180) hide show
  1. package/3d/SpriteResourceManager.d.ts +74 -0
  2. package/3d/SpriteUtils.d.ts +13 -0
  3. package/3d/TextureUtils.d.ts +24 -0
  4. package/3d/ThreeRenderable.d.ts +40 -0
  5. package/3d/WGPURenderer.d.ts +61 -0
  6. package/3d/animation/ExplodingSpriteEffect.d.ts +71 -0
  7. package/3d/animation/PhysicsExplodingSpriteEffect.d.ts +76 -0
  8. package/3d/animation/SpriteAnimator.d.ts +124 -0
  9. package/3d/animation/SpriteParticleGenerator.d.ts +62 -0
  10. package/3d/canvas.d.ts +44 -0
  11. package/3d/index.d.ts +12 -0
  12. package/3d/physics/PlanckPhysicsAdapter.d.ts +19 -0
  13. package/3d/physics/RapierPhysicsAdapter.d.ts +19 -0
  14. package/3d/physics/physics-interface.d.ts +27 -0
  15. package/3d.d.ts +2 -0
  16. package/3d.js +33843 -0
  17. package/3d.js.map +155 -0
  18. package/LICENSE +21 -0
  19. package/NativeSpanFeed.d.ts +41 -0
  20. package/README.md +65 -0
  21. package/Renderable.d.ts +334 -0
  22. package/Worker-vajwjk0s.js +94 -0
  23. package/Worker-vajwjk0s.js.map +10 -0
  24. package/animation/Timeline.d.ts +126 -0
  25. package/ansi.d.ts +13 -0
  26. package/assets/javascript/highlights.scm +205 -0
  27. package/assets/javascript/tree-sitter-javascript.wasm +0 -0
  28. package/assets/markdown/highlights.scm +150 -0
  29. package/assets/markdown/injections.scm +27 -0
  30. package/assets/markdown/tree-sitter-markdown.wasm +0 -0
  31. package/assets/markdown_inline/highlights.scm +115 -0
  32. package/assets/markdown_inline/tree-sitter-markdown_inline.wasm +0 -0
  33. package/assets/typescript/highlights.scm +604 -0
  34. package/assets/typescript/tree-sitter-typescript.wasm +0 -0
  35. package/assets/zig/highlights.scm +284 -0
  36. package/assets/zig/tree-sitter-zig.wasm +0 -0
  37. package/buffer.d.ts +111 -0
  38. package/compat/FFIType.d.ts +304 -0
  39. package/compat/Worker.d.ts +1 -0
  40. package/compat/bun-ffi-structs.d.ts +2 -0
  41. package/compat/ffi.d.ts +86 -0
  42. package/compat/nodejs/Worker.d.ts +16 -0
  43. package/compat/nodejs/bun-ffi-structs/index.d.ts +46 -0
  44. package/compat/nodejs/ffi.d.ts +21 -0
  45. package/compat/nodejs/registerBun.d.ts +1 -0
  46. package/compat/nodejs/registerResolveJs.d.ts +1 -0
  47. package/compat/nodejs/runtime.d.ts +7 -0
  48. package/compat/nodejs/test.d.ts +4 -0
  49. package/compat/nodejs/trampoline.worker.d.ts +1 -0
  50. package/compat/runtime.d.ts +8 -0
  51. package/compat/test.d.ts +1 -0
  52. package/compat/testHelpers.d.ts +18 -0
  53. package/console.d.ts +144 -0
  54. package/edit-buffer.d.ts +98 -0
  55. package/editor-view.d.ts +73 -0
  56. package/ffi-x3zvcksd.js +25 -0
  57. package/ffi-x3zvcksd.js.map +9 -0
  58. package/index-5yqvbmcz.js +220 -0
  59. package/index-5yqvbmcz.js.map +10 -0
  60. package/index-bnfz2g63.js +654 -0
  61. package/index-bnfz2g63.js.map +10 -0
  62. package/index-cbvybypy.js +43 -0
  63. package/index-cbvybypy.js.map +10 -0
  64. package/index-hjna9d1h.js +12074 -0
  65. package/index-hjna9d1h.js.map +42 -0
  66. package/index-jjp8mmgk.js +19991 -0
  67. package/index-jjp8mmgk.js.map +70 -0
  68. package/index-re3ntm60.js +51 -0
  69. package/index-re3ntm60.js.map +9 -0
  70. package/index-t16hn6zn.js +411 -0
  71. package/index-t16hn6zn.js.map +10 -0
  72. package/index-tkk6cmr2.js +650 -0
  73. package/index-tkk6cmr2.js.map +10 -0
  74. package/index.d.ts +23 -0
  75. package/index.js +480 -0
  76. package/index.js.map +9 -0
  77. package/lib/KeyHandler.d.ts +61 -0
  78. package/lib/RGBA.d.ts +26 -0
  79. package/lib/ascii.font.d.ts +508 -0
  80. package/lib/border.d.ts +51 -0
  81. package/lib/bunfs.d.ts +7 -0
  82. package/lib/clipboard.d.ts +17 -0
  83. package/lib/clock.d.ts +15 -0
  84. package/lib/data-paths.d.ts +26 -0
  85. package/lib/debounce.d.ts +42 -0
  86. package/lib/detect-links.d.ts +6 -0
  87. package/lib/env.d.ts +42 -0
  88. package/lib/extmarks-history.d.ts +17 -0
  89. package/lib/extmarks.d.ts +89 -0
  90. package/lib/hast-styled-text.d.ts +17 -0
  91. package/lib/index.d.ts +21 -0
  92. package/lib/keymapping.d.ts +25 -0
  93. package/lib/objects-in-viewport.d.ts +24 -0
  94. package/lib/output.capture.d.ts +24 -0
  95. package/lib/parse.keypress-kitty.d.ts +2 -0
  96. package/lib/parse.keypress.d.ts +26 -0
  97. package/lib/parse.mouse.d.ts +30 -0
  98. package/lib/paste.d.ts +7 -0
  99. package/lib/queue.d.ts +15 -0
  100. package/lib/renderable.validations.d.ts +12 -0
  101. package/lib/scroll-acceleration.d.ts +43 -0
  102. package/lib/selection.d.ts +64 -0
  103. package/lib/singleton.d.ts +7 -0
  104. package/lib/stdin-parser.d.ts +87 -0
  105. package/lib/styled-text.d.ts +63 -0
  106. package/lib/terminal-capability-detection.d.ts +30 -0
  107. package/lib/terminal-palette.d.ts +50 -0
  108. package/lib/tree-sitter/assets/update.d.ts +11 -0
  109. package/lib/tree-sitter/client.d.ts +47 -0
  110. package/lib/tree-sitter/default-parsers.d.ts +2 -0
  111. package/lib/tree-sitter/download-utils.d.ts +21 -0
  112. package/lib/tree-sitter/index.d.ts +8 -0
  113. package/lib/tree-sitter/parser.worker.d.ts +1 -0
  114. package/lib/tree-sitter/parsers-config.d.ts +53 -0
  115. package/lib/tree-sitter/resolve-ft.d.ts +5 -0
  116. package/lib/tree-sitter/types.d.ts +82 -0
  117. package/lib/tree-sitter-styled-text.d.ts +14 -0
  118. package/lib/validate-dir-name.d.ts +1 -0
  119. package/lib/yoga.options.d.ts +32 -0
  120. package/package.json +80 -0
  121. package/parser.worker.js +888 -0
  122. package/parser.worker.js.map +12 -0
  123. package/plugins/core-slot.d.ts +72 -0
  124. package/plugins/registry.d.ts +42 -0
  125. package/plugins/types.d.ts +34 -0
  126. package/post/effects.d.ts +147 -0
  127. package/post/filters.d.ts +65 -0
  128. package/post/matrices.d.ts +20 -0
  129. package/renderables/ASCIIFont.d.ts +52 -0
  130. package/renderables/Box.d.ts +81 -0
  131. package/renderables/Code.d.ts +78 -0
  132. package/renderables/Diff.d.ts +142 -0
  133. package/renderables/EditBufferRenderable.d.ts +237 -0
  134. package/renderables/FrameBuffer.d.ts +16 -0
  135. package/renderables/Input.d.ts +67 -0
  136. package/renderables/LineNumberRenderable.d.ts +78 -0
  137. package/renderables/Markdown.d.ts +181 -0
  138. package/renderables/ScrollBar.d.ts +77 -0
  139. package/renderables/ScrollBox.d.ts +124 -0
  140. package/renderables/Select.d.ts +115 -0
  141. package/renderables/Slider.d.ts +47 -0
  142. package/renderables/TabSelect.d.ts +96 -0
  143. package/renderables/Text.d.ts +36 -0
  144. package/renderables/TextBufferRenderable.d.ts +105 -0
  145. package/renderables/TextNode.d.ts +91 -0
  146. package/renderables/TextTable.d.ts +140 -0
  147. package/renderables/Textarea.d.ts +63 -0
  148. package/renderables/TimeToFirstDraw.d.ts +24 -0
  149. package/renderables/__tests__/renderable-test-utils.d.ts +12 -0
  150. package/renderables/composition/VRenderable.d.ts +16 -0
  151. package/renderables/composition/constructs.d.ts +35 -0
  152. package/renderables/composition/vnode.d.ts +46 -0
  153. package/renderables/index.d.ts +23 -0
  154. package/renderables/markdown-parser.d.ts +10 -0
  155. package/renderer.d.ts +419 -0
  156. package/runtime-hdpkc6qf.js +220 -0
  157. package/runtime-hdpkc6qf.js.map +17 -0
  158. package/runtime-plugin-support.d.ts +3 -0
  159. package/runtime-plugin-support.js +31 -0
  160. package/runtime-plugin-support.js.map +10 -0
  161. package/runtime-plugin.d.ts +19 -0
  162. package/runtime-plugin.js +18 -0
  163. package/runtime-plugin.js.map +9 -0
  164. package/syntax-style.d.ts +54 -0
  165. package/testing/manual-clock.d.ts +17 -0
  166. package/testing/mock-keys.d.ts +81 -0
  167. package/testing/mock-mouse.d.ts +38 -0
  168. package/testing/mock-tree-sitter-client.d.ts +23 -0
  169. package/testing/spy.d.ts +7 -0
  170. package/testing/test-recorder.d.ts +61 -0
  171. package/testing/test-renderer.d.ts +23 -0
  172. package/testing.d.ts +6 -0
  173. package/testing.js +699 -0
  174. package/testing.js.map +15 -0
  175. package/text-buffer-view.d.ts +42 -0
  176. package/text-buffer.d.ts +67 -0
  177. package/types.d.ts +139 -0
  178. package/utils.d.ts +14 -0
  179. package/zig-structs.d.ts +155 -0
  180. package/zig.d.ts +353 -0
package/testing.js ADDED
@@ -0,0 +1,699 @@
1
+ // @bun
2
+ import {
3
+ ANSI,
4
+ CliRenderer,
5
+ TreeSitterClient,
6
+ resolveRenderLib
7
+ } from "./index-jjp8mmgk.js";
8
+ import"./index-cbvybypy.js";
9
+ import"./index-re3ntm60.js";
10
+
11
+ // src/testing/test-renderer.ts
12
+ import { Readable, Writable } from "stream";
13
+
14
+ // src/testing/mock-keys.ts
15
+ import { Buffer as Buffer2 } from "buffer";
16
+ function pasteBytes(text) {
17
+ return Uint8Array.from(Buffer2.from(text));
18
+ }
19
+ var KeyCodes = {
20
+ RETURN: "\r",
21
+ LINEFEED: `
22
+ `,
23
+ TAB: "\t",
24
+ BACKSPACE: "\b",
25
+ DELETE: "\x1B[3~",
26
+ HOME: "\x1B[H",
27
+ END: "\x1B[F",
28
+ ESCAPE: "\x1B",
29
+ ARROW_UP: "\x1B[A",
30
+ ARROW_DOWN: "\x1B[B",
31
+ ARROW_RIGHT: "\x1B[C",
32
+ ARROW_LEFT: "\x1B[D",
33
+ F1: "\x1BOP",
34
+ F2: "\x1BOQ",
35
+ F3: "\x1BOR",
36
+ F4: "\x1BOS",
37
+ F5: "\x1B[15~",
38
+ F6: "\x1B[17~",
39
+ F7: "\x1B[18~",
40
+ F8: "\x1B[19~",
41
+ F9: "\x1B[20~",
42
+ F10: "\x1B[21~",
43
+ F11: "\x1B[23~",
44
+ F12: "\x1B[24~"
45
+ };
46
+ var kittyKeyCodeMap = {
47
+ escape: 27,
48
+ tab: 9,
49
+ return: 13,
50
+ backspace: 127,
51
+ insert: 57348,
52
+ delete: 57349,
53
+ left: 57350,
54
+ right: 57351,
55
+ up: 57352,
56
+ down: 57353,
57
+ pageup: 57354,
58
+ pagedown: 57355,
59
+ home: 57356,
60
+ end: 57357,
61
+ f1: 57364,
62
+ f2: 57365,
63
+ f3: 57366,
64
+ f4: 57367,
65
+ f5: 57368,
66
+ f6: 57369,
67
+ f7: 57370,
68
+ f8: 57371,
69
+ f9: 57372,
70
+ f10: 57373,
71
+ f11: 57374,
72
+ f12: 57375
73
+ };
74
+ function encodeKittySequence(codepoint, modifiers) {
75
+ let modMask = 0;
76
+ if (modifiers?.shift)
77
+ modMask |= 1;
78
+ if (modifiers?.meta)
79
+ modMask |= 2;
80
+ if (modifiers?.ctrl)
81
+ modMask |= 4;
82
+ if (modifiers?.super)
83
+ modMask |= 8;
84
+ if (modifiers?.hyper)
85
+ modMask |= 16;
86
+ if (modMask === 0) {
87
+ return `\x1B[${codepoint}u`;
88
+ } else {
89
+ return `\x1B[${codepoint};${modMask + 1}u`;
90
+ }
91
+ }
92
+ function encodeModifyOtherKeysSequence(charCode, modifiers) {
93
+ let modMask = 0;
94
+ if (modifiers?.shift)
95
+ modMask |= 1;
96
+ if (modifiers?.meta)
97
+ modMask |= 2;
98
+ if (modifiers?.ctrl)
99
+ modMask |= 4;
100
+ if (modifiers?.super)
101
+ modMask |= 8;
102
+ if (modifiers?.hyper)
103
+ modMask |= 16;
104
+ if (modMask === 0) {
105
+ return String.fromCharCode(charCode);
106
+ }
107
+ return `\x1B[27;${modMask + 1};${charCode}~`;
108
+ }
109
+ function resolveKeyInput(key) {
110
+ let keyValue;
111
+ let keyName;
112
+ if (typeof key === "string") {
113
+ if (key in KeyCodes) {
114
+ keyValue = KeyCodes[key];
115
+ keyName = key.toLowerCase();
116
+ } else {
117
+ keyValue = key;
118
+ keyName = undefined;
119
+ }
120
+ } else {
121
+ keyValue = KeyCodes[key];
122
+ if (!keyValue) {
123
+ throw new Error(`Unknown key: ${key}`);
124
+ }
125
+ keyName = String(key).toLowerCase();
126
+ }
127
+ return { keyValue, keyName };
128
+ }
129
+ function createMockKeys(renderer, options) {
130
+ const useKittyKeyboard = options?.kittyKeyboard ?? false;
131
+ const useOtherModifiersMode = options?.otherModifiersMode ?? false;
132
+ const effectiveOtherModifiersMode = useOtherModifiersMode && !useKittyKeyboard;
133
+ const pressKeys = async (keys, delayMs = 0) => {
134
+ for (const key of keys) {
135
+ const { keyValue: keyCode } = resolveKeyInput(key);
136
+ renderer.stdin.emit("data", Buffer2.from(keyCode));
137
+ if (delayMs > 0) {
138
+ await new Promise((resolve) => setTimeout(resolve, delayMs));
139
+ }
140
+ }
141
+ };
142
+ const pressKey = (key, modifiers) => {
143
+ if (useKittyKeyboard) {
144
+ let { keyValue, keyName } = resolveKeyInput(key);
145
+ const valueToKeyNameMap = {
146
+ "\b": "backspace",
147
+ "\r": "return",
148
+ "\n": "return",
149
+ "\t": "tab",
150
+ "\x1B": "escape",
151
+ "\x1B[A": "up",
152
+ "\x1B[B": "down",
153
+ "\x1B[C": "right",
154
+ "\x1B[D": "left",
155
+ "\x1B[H": "home",
156
+ "\x1B[F": "end",
157
+ "\x1B[3~": "delete"
158
+ };
159
+ if (keyValue && valueToKeyNameMap[keyValue]) {
160
+ keyName = valueToKeyNameMap[keyValue];
161
+ }
162
+ if (keyName && keyName.startsWith("arrow_")) {
163
+ keyName = keyName.substring(6);
164
+ }
165
+ if (keyName && kittyKeyCodeMap[keyName]) {
166
+ const kittyCode = kittyKeyCodeMap[keyName];
167
+ const sequence = encodeKittySequence(kittyCode, modifiers);
168
+ renderer.stdin.emit("data", Buffer2.from(sequence));
169
+ return;
170
+ }
171
+ if (keyValue && keyValue.length === 1 && !keyValue.startsWith("\x1B")) {
172
+ const codepoint = keyValue.codePointAt(0);
173
+ if (codepoint) {
174
+ const sequence = encodeKittySequence(codepoint, modifiers);
175
+ renderer.stdin.emit("data", Buffer2.from(sequence));
176
+ return;
177
+ }
178
+ }
179
+ }
180
+ if (effectiveOtherModifiersMode && modifiers) {
181
+ let { keyValue, keyName } = resolveKeyInput(key);
182
+ const valueToCharCodeMap = {
183
+ "\b": 127,
184
+ "\r": 13,
185
+ "\n": 13,
186
+ "\t": 9,
187
+ "\x1B": 27,
188
+ " ": 32
189
+ };
190
+ let charCode;
191
+ if (keyValue && valueToCharCodeMap[keyValue] !== undefined) {
192
+ charCode = valueToCharCodeMap[keyValue];
193
+ } else if (keyValue && keyValue.length === 1 && !keyValue.startsWith("\x1B")) {
194
+ charCode = keyValue.charCodeAt(0);
195
+ }
196
+ if (charCode !== undefined) {
197
+ const sequence = encodeModifyOtherKeysSequence(charCode, modifiers);
198
+ renderer.stdin.emit("data", Buffer2.from(sequence));
199
+ return;
200
+ }
201
+ }
202
+ let keyCode = resolveKeyInput(key).keyValue;
203
+ if (modifiers) {
204
+ if (keyCode.startsWith("\x1B[") && keyCode.length > 2) {
205
+ const modifier = 1 + (modifiers.shift ? 1 : 0) + (modifiers.meta ? 2 : 0) + (modifiers.ctrl ? 4 : 0) + (modifiers.super ? 8 : 0) + (modifiers.hyper ? 16 : 0);
206
+ if (modifier > 1) {
207
+ const tildeMatch = keyCode.match(/^\x1b\[(\d+)~$/);
208
+ if (tildeMatch) {
209
+ keyCode = `\x1B[${tildeMatch[1]};${modifier}~`;
210
+ } else {
211
+ const ending = keyCode.slice(-1);
212
+ keyCode = `\x1B[1;${modifier}${ending}`;
213
+ }
214
+ }
215
+ } else if (keyCode.length === 1) {
216
+ let char = keyCode;
217
+ if (char === "\t" && modifiers.shift) {
218
+ keyCode = modifiers.meta ? "\x1B\x1B[Z" : "\x1B[Z";
219
+ renderer.stdin.emit("data", Buffer2.from(keyCode));
220
+ return;
221
+ }
222
+ if (char === "\b" && (modifiers.ctrl || modifiers.super || modifiers.hyper)) {
223
+ const modifier = 1 + (modifiers.shift ? 1 : 0) + (modifiers.meta ? 2 : 0) + (modifiers.ctrl ? 4 : 0) + (modifiers.super ? 8 : 0) + (modifiers.hyper ? 16 : 0);
224
+ keyCode = `\x1B[27;${modifier};127~`;
225
+ } else if (modifiers.ctrl) {
226
+ if (char >= "a" && char <= "z") {
227
+ keyCode = String.fromCharCode(char.charCodeAt(0) - 96);
228
+ } else if (char >= "A" && char <= "Z") {
229
+ keyCode = String.fromCharCode(char.charCodeAt(0) - 64);
230
+ } else {
231
+ const specialCtrlMap = {
232
+ "[": "\x1B",
233
+ "\\": "\x1C",
234
+ "]": "\x1D",
235
+ "^": "\x1E",
236
+ _: "\x1F",
237
+ "?": "\x7F",
238
+ "/": "\x1F",
239
+ "-": "\x1F",
240
+ ".": "\x1E",
241
+ ",": "\x1C",
242
+ "@": "\x00",
243
+ " ": "\x00"
244
+ };
245
+ if (char in specialCtrlMap) {
246
+ keyCode = specialCtrlMap[char];
247
+ }
248
+ }
249
+ if (modifiers.meta) {
250
+ keyCode = `\x1B${keyCode}`;
251
+ }
252
+ } else {
253
+ if (modifiers.shift && char >= "a" && char <= "z") {
254
+ char = char.toUpperCase();
255
+ }
256
+ if (modifiers.meta) {
257
+ keyCode = `\x1B${char}`;
258
+ } else {
259
+ keyCode = char;
260
+ }
261
+ }
262
+ } else if (modifiers.meta && !keyCode.startsWith("\x1B")) {
263
+ keyCode = `\x1B${keyCode}`;
264
+ }
265
+ }
266
+ renderer.stdin.emit("data", Buffer2.from(keyCode));
267
+ };
268
+ const typeText = async (text, delayMs = 0) => {
269
+ const keys = text.split("");
270
+ await pressKeys(keys, delayMs);
271
+ };
272
+ const pressReturn = (modifiers) => {
273
+ pressKey(KeyCodes.RETURN, modifiers);
274
+ };
275
+ const pressEscape = (modifiers) => {
276
+ pressKey(KeyCodes.ESCAPE, modifiers);
277
+ };
278
+ const pressTab = (modifiers) => {
279
+ pressKey(KeyCodes.TAB, modifiers);
280
+ };
281
+ const pressBackspace = (modifiers) => {
282
+ pressKey(KeyCodes.BACKSPACE, modifiers);
283
+ };
284
+ const pressArrow = (direction, modifiers) => {
285
+ const keyMap = {
286
+ up: KeyCodes.ARROW_UP,
287
+ down: KeyCodes.ARROW_DOWN,
288
+ left: KeyCodes.ARROW_LEFT,
289
+ right: KeyCodes.ARROW_RIGHT
290
+ };
291
+ pressKey(keyMap[direction], modifiers);
292
+ };
293
+ const pressCtrlC = () => {
294
+ pressKey("c", { ctrl: true });
295
+ };
296
+ const pasteBracketedText = (text) => {
297
+ return pressKeys([ANSI.bracketedPasteStart, text, ANSI.bracketedPasteEnd]);
298
+ };
299
+ return {
300
+ pressKeys,
301
+ pressKey,
302
+ typeText,
303
+ pressEnter: pressReturn,
304
+ pressEscape,
305
+ pressTab,
306
+ pressBackspace,
307
+ pressArrow,
308
+ pressCtrlC,
309
+ pasteBracketedText
310
+ };
311
+ }
312
+
313
+ // src/testing/mock-mouse.ts
314
+ var MouseButtons = {
315
+ LEFT: 0,
316
+ MIDDLE: 1,
317
+ RIGHT: 2,
318
+ WHEEL_UP: 64,
319
+ WHEEL_DOWN: 65,
320
+ WHEEL_LEFT: 66,
321
+ WHEEL_RIGHT: 67
322
+ };
323
+ function createMockMouse(renderer) {
324
+ let currentPosition = { x: 0, y: 0 };
325
+ let buttonsPressed = new Set;
326
+ const generateMouseEvent = (type, x, y, button = MouseButtons.LEFT, modifiers = {}) => {
327
+ let buttonCode = button;
328
+ if (modifiers.shift)
329
+ buttonCode |= 4;
330
+ if (modifiers.alt)
331
+ buttonCode |= 8;
332
+ if (modifiers.ctrl)
333
+ buttonCode |= 16;
334
+ switch (type) {
335
+ case "move":
336
+ buttonCode = 32 | 3;
337
+ if (modifiers.shift)
338
+ buttonCode |= 4;
339
+ if (modifiers.alt)
340
+ buttonCode |= 8;
341
+ if (modifiers.ctrl)
342
+ buttonCode |= 16;
343
+ break;
344
+ case "drag":
345
+ buttonCode = (buttonsPressed.size > 0 ? Array.from(buttonsPressed)[0] : button) | 32;
346
+ if (modifiers.shift)
347
+ buttonCode |= 4;
348
+ if (modifiers.alt)
349
+ buttonCode |= 8;
350
+ if (modifiers.ctrl)
351
+ buttonCode |= 16;
352
+ break;
353
+ case "scroll":
354
+ break;
355
+ }
356
+ const ansiX = x + 1;
357
+ const ansiY = y + 1;
358
+ let pressRelease = "M";
359
+ if (type === "up" || type === "move" || type === "drag") {
360
+ pressRelease = "m";
361
+ }
362
+ return `\x1B[<${buttonCode};${ansiX};${ansiY}${pressRelease}`;
363
+ };
364
+ const emitMouseEvent = async (type, x, y, button = MouseButtons.LEFT, options = {}) => {
365
+ const { modifiers = {}, delayMs = 0 } = options;
366
+ const eventSequence = generateMouseEvent(type, x, y, button, modifiers);
367
+ renderer.stdin.emit("data", Buffer.from(eventSequence));
368
+ currentPosition = { x, y };
369
+ if (type === "down" && button < 64) {
370
+ buttonsPressed.add(button);
371
+ } else if (type === "up") {
372
+ buttonsPressed.delete(button);
373
+ }
374
+ if (delayMs > 0) {
375
+ await new Promise((resolve) => setTimeout(resolve, delayMs));
376
+ }
377
+ };
378
+ const moveTo = async (x, y, options = {}) => {
379
+ const { button = MouseButtons.LEFT, delayMs = 0, modifiers = {} } = options;
380
+ if (buttonsPressed.size > 0) {
381
+ await emitMouseEvent("drag", x, y, Array.from(buttonsPressed)[0], { modifiers, delayMs });
382
+ } else {
383
+ await emitMouseEvent("move", x, y, button, { modifiers, delayMs });
384
+ }
385
+ currentPosition = { x, y };
386
+ };
387
+ const click = async (x, y, button = MouseButtons.LEFT, options = {}) => {
388
+ const { delayMs = 10, modifiers = {} } = options;
389
+ await emitMouseEvent("down", x, y, button, { modifiers, delayMs });
390
+ await new Promise((resolve) => setTimeout(resolve, delayMs));
391
+ await emitMouseEvent("up", x, y, button, { modifiers, delayMs });
392
+ };
393
+ const doubleClick = async (x, y, button = MouseButtons.LEFT, options = {}) => {
394
+ const { delayMs = 10, modifiers = {} } = options;
395
+ await click(x, y, button, { modifiers, delayMs });
396
+ await new Promise((resolve) => setTimeout(resolve, delayMs));
397
+ await click(x, y, button, { modifiers, delayMs });
398
+ };
399
+ const pressDown = async (x, y, button = MouseButtons.LEFT, options = {}) => {
400
+ const { modifiers = {}, delayMs = 0 } = options;
401
+ await emitMouseEvent("down", x, y, button, { modifiers, delayMs });
402
+ };
403
+ const release = async (x, y, button = MouseButtons.LEFT, options = {}) => {
404
+ const { modifiers = {}, delayMs = 0 } = options;
405
+ await emitMouseEvent("up", x, y, button, { modifiers, delayMs });
406
+ };
407
+ const drag = async (startX, startY, endX, endY, button = MouseButtons.LEFT, options = {}) => {
408
+ const { delayMs = 10, modifiers = {} } = options;
409
+ await pressDown(startX, startY, button, { modifiers });
410
+ const steps = 5;
411
+ const dx = (endX - startX) / steps;
412
+ const dy = (endY - startY) / steps;
413
+ for (let i = 1;i <= steps; i++) {
414
+ const currentX = Math.round(startX + dx * i);
415
+ const currentY = Math.round(startY + dy * i);
416
+ await emitMouseEvent("drag", currentX, currentY, button, { modifiers, delayMs });
417
+ }
418
+ await release(endX, endY, button, { modifiers });
419
+ };
420
+ const scroll = async (x, y, direction, options = {}) => {
421
+ const { modifiers = {}, delayMs = 0 } = options;
422
+ let button;
423
+ switch (direction) {
424
+ case "up":
425
+ button = MouseButtons.WHEEL_UP;
426
+ break;
427
+ case "down":
428
+ button = MouseButtons.WHEEL_DOWN;
429
+ break;
430
+ case "left":
431
+ button = MouseButtons.WHEEL_LEFT;
432
+ break;
433
+ case "right":
434
+ button = MouseButtons.WHEEL_RIGHT;
435
+ break;
436
+ }
437
+ await emitMouseEvent("scroll", x, y, button, { modifiers, delayMs });
438
+ };
439
+ const getCurrentPosition = () => {
440
+ return { ...currentPosition };
441
+ };
442
+ const getPressedButtons = () => {
443
+ return Array.from(buttonsPressed);
444
+ };
445
+ return {
446
+ moveTo,
447
+ click,
448
+ doubleClick,
449
+ pressDown,
450
+ release,
451
+ drag,
452
+ scroll,
453
+ getCurrentPosition,
454
+ getPressedButtons,
455
+ emitMouseEvent
456
+ };
457
+ }
458
+
459
+ // src/testing/test-renderer.ts
460
+ var decoder = new TextDecoder;
461
+
462
+ class TestWriteStream extends Writable {
463
+ isTTY = true;
464
+ columns;
465
+ rows;
466
+ constructor(columns, rows) {
467
+ super();
468
+ this.columns = columns;
469
+ this.rows = rows;
470
+ }
471
+ _write(_chunk, _encoding, callback) {
472
+ callback();
473
+ }
474
+ getColorDepth() {
475
+ return 24;
476
+ }
477
+ }
478
+ async function createTestRenderer(options) {
479
+ const useKittyKeyboard = options.kittyKeyboard ? { events: true } : options.useKittyKeyboard;
480
+ const renderer = await setupTestRenderer({
481
+ ...options,
482
+ useKittyKeyboard,
483
+ screenMode: options.screenMode ?? "main-screen",
484
+ footerHeight: options.footerHeight ?? 12,
485
+ consoleMode: options.consoleMode ?? "disabled",
486
+ externalOutputMode: options.externalOutputMode ?? "passthrough"
487
+ });
488
+ const mockInput = createMockKeys(renderer, {
489
+ kittyKeyboard: options.kittyKeyboard,
490
+ otherModifiersMode: options.otherModifiersMode
491
+ });
492
+ const mockMouse = createMockMouse(renderer);
493
+ const renderOnce = async () => {
494
+ await renderer.loop();
495
+ };
496
+ return {
497
+ renderer,
498
+ mockInput,
499
+ mockMouse,
500
+ renderOnce,
501
+ captureCharFrame: () => {
502
+ const currentBuffer = renderer.currentRenderBuffer;
503
+ const frameBytes = currentBuffer.getRealCharBytes(true);
504
+ return decoder.decode(frameBytes);
505
+ },
506
+ captureSpans: () => {
507
+ const currentBuffer = renderer.currentRenderBuffer;
508
+ const lines = currentBuffer.getSpanLines();
509
+ const cursorState = renderer.getCursorState();
510
+ return {
511
+ cols: currentBuffer.width,
512
+ rows: currentBuffer.height,
513
+ cursor: [cursorState.x, cursorState.y],
514
+ lines
515
+ };
516
+ },
517
+ resize: (width, height) => {
518
+ renderer.processResize(width, height);
519
+ }
520
+ };
521
+ }
522
+ async function setupTestRenderer(config) {
523
+ const stdin = config.stdin || new Readable({ read() {} });
524
+ const width = config.width || config.stdout?.columns || process.stdout.columns || 80;
525
+ const height = config.height || config.stdout?.rows || process.stdout.rows || 24;
526
+ const stdout = config.stdout || new TestWriteStream(width, height);
527
+ const renderHeight = config.screenMode === "split-footer" ? config.footerHeight ?? 12 : height;
528
+ const ziglib = resolveRenderLib();
529
+ const rendererPtr = ziglib.createRenderer(width, renderHeight, {
530
+ testing: true,
531
+ remote: config.remote ?? false
532
+ });
533
+ if (!rendererPtr) {
534
+ throw new Error("Failed to create test renderer");
535
+ }
536
+ if (config.useThread === undefined) {
537
+ config.useThread = true;
538
+ }
539
+ if (process.platform === "linux") {
540
+ config.useThread = false;
541
+ }
542
+ ziglib.setUseThread(rendererPtr, config.useThread);
543
+ const renderer = new CliRenderer(ziglib, rendererPtr, stdin, stdout, width, height, config);
544
+ process.off("SIGWINCH", renderer["sigwinchHandler"]);
545
+ return renderer;
546
+ }
547
+ // src/testing/mock-tree-sitter-client.ts
548
+ class MockTreeSitterClient extends TreeSitterClient {
549
+ _highlightPromises = [];
550
+ _mockResult = { highlights: [] };
551
+ _autoResolveTimeout;
552
+ constructor(options) {
553
+ super({ dataPath: "/tmp/mock" });
554
+ this._autoResolveTimeout = options?.autoResolveTimeout;
555
+ }
556
+ async highlightOnce(content, filetype) {
557
+ const { promise, resolve } = Promise.withResolvers();
558
+ let timeout;
559
+ if (this._autoResolveTimeout !== undefined) {
560
+ timeout = setTimeout(() => {
561
+ const index = this._highlightPromises.findIndex((p) => p.promise === promise);
562
+ if (index !== -1) {
563
+ resolve(this._mockResult);
564
+ this._highlightPromises.splice(index, 1);
565
+ }
566
+ }, this._autoResolveTimeout);
567
+ }
568
+ this._highlightPromises.push({ promise, resolve, timeout });
569
+ return promise;
570
+ }
571
+ setMockResult(result) {
572
+ this._mockResult = result;
573
+ }
574
+ resolveHighlightOnce(index = 0) {
575
+ if (index >= 0 && index < this._highlightPromises.length) {
576
+ const item = this._highlightPromises[index];
577
+ if (item.timeout) {
578
+ clearTimeout(item.timeout);
579
+ }
580
+ item.resolve(this._mockResult);
581
+ this._highlightPromises.splice(index, 1);
582
+ }
583
+ }
584
+ resolveAllHighlightOnce() {
585
+ for (const { resolve, timeout } of this._highlightPromises) {
586
+ if (timeout) {
587
+ clearTimeout(timeout);
588
+ }
589
+ resolve(this._mockResult);
590
+ }
591
+ this._highlightPromises = [];
592
+ }
593
+ isHighlighting() {
594
+ return this._highlightPromises.length > 0;
595
+ }
596
+ }
597
+ // src/testing/spy.ts
598
+ function createSpy() {
599
+ const calls = [];
600
+ const spy = (...args) => {
601
+ calls.push(args);
602
+ };
603
+ spy.calls = calls;
604
+ spy.callCount = () => calls.length;
605
+ spy.calledWith = (...expected) => {
606
+ return calls.some((call) => JSON.stringify(call) === JSON.stringify(expected));
607
+ };
608
+ spy.reset = () => calls.length = 0;
609
+ return spy;
610
+ }
611
+ // src/testing/test-recorder.ts
612
+ class TestRecorder {
613
+ renderer;
614
+ frames = [];
615
+ recording = false;
616
+ frameNumber = 0;
617
+ startTime = 0;
618
+ originalRenderNative;
619
+ decoder = new TextDecoder;
620
+ recordBuffers;
621
+ now;
622
+ constructor(renderer, options) {
623
+ this.renderer = renderer;
624
+ this.recordBuffers = options?.recordBuffers || {};
625
+ this.now = options?.now ?? (() => performance.now());
626
+ }
627
+ rec() {
628
+ if (this.recording) {
629
+ return;
630
+ }
631
+ this.recording = true;
632
+ this.frames = [];
633
+ this.frameNumber = 0;
634
+ this.startTime = this.now();
635
+ this.originalRenderNative = this.renderer["renderNative"].bind(this.renderer);
636
+ this.renderer["renderNative"] = () => {
637
+ this.originalRenderNative();
638
+ this.captureFrame();
639
+ };
640
+ }
641
+ stop() {
642
+ if (!this.recording) {
643
+ return;
644
+ }
645
+ this.recording = false;
646
+ if (this.originalRenderNative) {
647
+ this.renderer["renderNative"] = this.originalRenderNative;
648
+ this.originalRenderNative = undefined;
649
+ }
650
+ }
651
+ get recordedFrames() {
652
+ return [...this.frames];
653
+ }
654
+ clear() {
655
+ this.frames = [];
656
+ this.frameNumber = 0;
657
+ }
658
+ get isRecording() {
659
+ return this.recording;
660
+ }
661
+ captureFrame() {
662
+ const currentBuffer = this.renderer.currentRenderBuffer;
663
+ const frameBytes = currentBuffer.getRealCharBytes(true);
664
+ const frame = this.decoder.decode(frameBytes);
665
+ const recordedFrame = {
666
+ frame,
667
+ timestamp: this.now() - this.startTime,
668
+ frameNumber: this.frameNumber++
669
+ };
670
+ if (this.recordBuffers.fg || this.recordBuffers.bg || this.recordBuffers.attributes) {
671
+ const buffers = currentBuffer.buffers;
672
+ recordedFrame.buffers = {};
673
+ if (this.recordBuffers.fg) {
674
+ recordedFrame.buffers.fg = new Float32Array(buffers.fg);
675
+ }
676
+ if (this.recordBuffers.bg) {
677
+ recordedFrame.buffers.bg = new Float32Array(buffers.bg);
678
+ }
679
+ if (this.recordBuffers.attributes) {
680
+ recordedFrame.buffers.attributes = new Uint8Array(buffers.attributes);
681
+ }
682
+ }
683
+ this.frames.push(recordedFrame);
684
+ }
685
+ }
686
+ export {
687
+ pasteBytes,
688
+ createTestRenderer,
689
+ createSpy,
690
+ createMockMouse,
691
+ createMockKeys,
692
+ TestRecorder,
693
+ MouseButtons,
694
+ MockTreeSitterClient,
695
+ KeyCodes
696
+ };
697
+
698
+ //# debugId=5F2319EEEBCB872F64756E2164756E21
699
+ //# sourceMappingURL=testing.js.map