@opentuah/core 0.1.77

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