@jitl/opentui-core 0.1.97 → 0.2.15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/NativeSpanFeed.d.ts +2 -2
- package/README.md +2 -1
- package/Renderable.d.ts +12 -1
- package/audio.d.ts +89 -0
- package/buffer.d.ts +6 -5
- package/console.d.ts +3 -1
- package/edit-buffer.d.ts +1 -1
- package/editor-view.d.ts +1 -1
- package/{index-yxe6e14n.js → index-46f5e8m6.js} +1388 -1721
- package/index-46f5e8m6.js.map +36 -0
- package/index-5zwezmgj.js +639 -0
- package/index-5zwezmgj.js.map +11 -0
- package/index-axv7cw60.js +44 -0
- package/index-axv7cw60.js.map +10 -0
- package/{index-rhfjv9c1.js → index-g9agybj3.js} +4626 -984
- package/index-g9agybj3.js.map +82 -0
- package/index-k18nf2r7.js +21 -0
- package/{ffi-x3zvcksd.js.map → index-k18nf2r7.js.map} +1 -1
- package/{index-tkk6cmr2.js → index-rp7vz5rh.js} +125 -23
- package/index-rp7vz5rh.js.map +10 -0
- package/{index-kcpn1hka.js → index-xwsdfq5x.js} +16 -6
- package/index-xwsdfq5x.js.map +10 -0
- package/index.d.ts +1 -0
- package/index.js +37 -17
- package/index.js.map +1 -1
- package/lib/RGBA.d.ts +22 -6
- package/lib/clipboard.d.ts +1 -1
- package/lib/{keymapping.d.ts → keybinding.internal.d.ts} +10 -2
- package/lib/objects-in-viewport.d.ts +4 -4
- package/lib/parse.keypress-kitty.d.ts +1 -0
- package/lib/parse.keypress.d.ts +1 -0
- package/lib/render-geometry.d.ts +8 -0
- package/lib/stdin-parser.d.ts +4 -1
- package/lib/terminal-capability-detection.d.ts +2 -0
- package/lib/terminal-palette.d.ts +20 -5
- package/lib/tree-sitter/assets/update.d.ts +1 -0
- package/lib/tree-sitter/client.d.ts +2 -0
- package/lib/tree-sitter/default-parsers.d.ts +1 -1
- package/lib/tree-sitter/index.d.ts +0 -2
- package/lib/tree-sitter/update-assets.d.ts +3 -0
- package/lib/tree-sitter/update-assets.js +377 -0
- package/lib/tree-sitter/update-assets.js.map +12 -0
- package/lib/tree-sitter-styled-text.d.ts +6 -4
- package/node22-bun-ffi-structs-ha8fmzzb.js +396 -0
- package/node22-bun-ffi-structs-ha8fmzzb.js.map +10 -0
- package/package.json +23 -22
- package/parser.worker.js +161 -24
- package/parser.worker.js.map +12 -5
- package/platform/bun-ffi-structs.d.ts +2 -0
- package/platform/ffi.d.ts +126 -0
- package/platform/node22-bun-ffi-structs.d.ts +33 -0
- package/platform/node22-ffi.d.ts +33 -0
- package/{compat → platform}/runtime.d.ts +6 -0
- package/platform/worker.d.ts +4 -0
- package/renderables/Code.d.ts +4 -0
- package/renderables/Markdown.d.ts +62 -0
- package/renderables/ScrollBox.d.ts +1 -0
- package/renderables/Select.d.ts +3 -1
- package/renderables/TabSelect.d.ts +3 -1
- package/renderables/TextBufferRenderable.d.ts +1 -0
- package/renderables/TextTable.d.ts +15 -1
- package/renderables/Textarea.d.ts +5 -3
- package/renderables/markdown-parser.d.ts +1 -0
- package/renderer-theme-mode.d.ts +29 -0
- package/renderer.d.ts +142 -16
- package/runtime-plugin-support-configure.d.ts +4 -0
- package/runtime-plugin-support-configure.js +20 -0
- package/{index-re3ntm60.js.map → runtime-plugin-support-configure.js.map} +1 -1
- package/runtime-plugin-support.d.ts +3 -3
- package/runtime-plugin-support.js +9 -18
- package/runtime-plugin-support.js.map +3 -3
- package/runtime-plugin.d.ts +1 -4
- package/runtime-plugin.js +5 -5
- package/syntax-style.d.ts +11 -3
- package/testing/terminal-capabilities.d.ts +7 -0
- package/testing/test-recorder.d.ts +6 -6
- package/testing/test-renderer.d.ts +34 -2
- package/testing.d.ts +2 -0
- package/testing.js +329 -23
- package/testing.js.map +7 -5
- package/text-buffer-view.d.ts +2 -1
- package/text-buffer.d.ts +1 -1
- package/types.d.ts +33 -1
- package/zig-structs.d.ts +111 -20
- package/zig.d.ts +57 -7
- package/3d/SpriteResourceManager.d.ts +0 -74
- package/3d/SpriteUtils.d.ts +0 -13
- package/3d/TextureUtils.d.ts +0 -24
- package/3d/ThreeRenderable.d.ts +0 -40
- package/3d/WGPURenderer.d.ts +0 -61
- package/3d/animation/ExplodingSpriteEffect.d.ts +0 -71
- package/3d/animation/PhysicsExplodingSpriteEffect.d.ts +0 -76
- package/3d/animation/SpriteAnimator.d.ts +0 -124
- package/3d/animation/SpriteParticleGenerator.d.ts +0 -62
- package/3d/canvas.d.ts +0 -44
- package/3d/index.d.ts +0 -12
- package/3d/physics/PlanckPhysicsAdapter.d.ts +0 -19
- package/3d/physics/RapierPhysicsAdapter.d.ts +0 -19
- package/3d/physics/physics-interface.d.ts +0 -27
- package/3d.d.ts +0 -2
- package/3d.js +0 -33843
- package/3d.js.map +0 -155
- package/Worker-vajwjk0s.js +0 -94
- package/Worker-vajwjk0s.js.map +0 -10
- package/compat/FFIType.d.ts +0 -304
- package/compat/Worker.d.ts +0 -1
- package/compat/bun-ffi-structs.d.ts +0 -2
- package/compat/ffi.d.ts +0 -86
- package/compat/nodejs/Worker.d.ts +0 -16
- package/compat/nodejs/bun-ffi-structs/index.d.ts +0 -46
- package/compat/nodejs/ffi.d.ts +0 -21
- package/compat/nodejs/registerResolveJs.d.ts +0 -1
- package/compat/nodejs/runtime.d.ts +0 -7
- package/compat/nodejs/test.d.ts +0 -4
- package/compat/nodejs/trampoline.worker.d.ts +0 -1
- package/compat/test.d.ts +0 -1
- package/compat/testHelpers.d.ts +0 -18
- package/ffi-x3zvcksd.js +0 -25
- package/index-5yqvbmcz.js +0 -220
- package/index-5yqvbmcz.js.map +0 -10
- package/index-bnfz2g63.js +0 -654
- package/index-bnfz2g63.js.map +0 -10
- package/index-cbvybypy.js +0 -43
- package/index-cbvybypy.js.map +0 -10
- package/index-kcpn1hka.js.map +0 -10
- package/index-re3ntm60.js +0 -51
- package/index-rhfjv9c1.js.map +0 -70
- package/index-tkk6cmr2.js.map +0 -10
- package/index-yxe6e14n.js.map +0 -42
- package/runtime-hdpkc6qf.js +0 -220
- package/runtime-hdpkc6qf.js.map +0 -17
- /package/{compat/nodejs/registerBun.d.ts → native-event-worker-repro.worker.d.ts} +0 -0
package/testing.js
CHANGED
|
@@ -3,10 +3,11 @@ import {
|
|
|
3
3
|
ANSI,
|
|
4
4
|
CliRenderer,
|
|
5
5
|
TreeSitterClient,
|
|
6
|
+
calculateRenderGeometry,
|
|
6
7
|
resolveRenderLib
|
|
7
|
-
} from "./index-
|
|
8
|
-
import"./index-
|
|
9
|
-
import"./index-
|
|
8
|
+
} from "./index-g9agybj3.js";
|
|
9
|
+
import"./index-5zwezmgj.js";
|
|
10
|
+
import"./index-k18nf2r7.js";
|
|
10
11
|
|
|
11
12
|
// src/testing/test-renderer.ts
|
|
12
13
|
import { Readable, Writable } from "stream";
|
|
@@ -458,6 +459,106 @@ function createMockMouse(renderer) {
|
|
|
458
459
|
|
|
459
460
|
// src/testing/test-renderer.ts
|
|
460
461
|
var decoder = new TextDecoder;
|
|
462
|
+
var DEFAULT_MAX_PASSES = 20;
|
|
463
|
+
var DEFAULT_MAX_VISUAL_IDLE_FRAMES = 20;
|
|
464
|
+
var DEFAULT_QUIET_FRAMES = 1;
|
|
465
|
+
async function drainImmediateWork() {
|
|
466
|
+
await Promise.resolve();
|
|
467
|
+
await new Promise((resolve) => process.nextTick(resolve));
|
|
468
|
+
await Promise.resolve();
|
|
469
|
+
}
|
|
470
|
+
function normalizePositiveInteger(value, fallback) {
|
|
471
|
+
if (typeof value !== "number" || !Number.isFinite(value) || value <= 0) {
|
|
472
|
+
return fallback;
|
|
473
|
+
}
|
|
474
|
+
return Math.floor(value);
|
|
475
|
+
}
|
|
476
|
+
function createWaitError(renderer, message, frame) {
|
|
477
|
+
const stats = renderer.getStats();
|
|
478
|
+
const scheduler = renderer.getSchedulerState();
|
|
479
|
+
const details = [
|
|
480
|
+
message,
|
|
481
|
+
`frameId: ${renderer.frameId}`,
|
|
482
|
+
`nativeFrameCount: ${stats.nativeFrameCount}`,
|
|
483
|
+
`cellsUpdated: ${stats.cellsUpdated}`,
|
|
484
|
+
`isRunning: ${scheduler.isRunning}`,
|
|
485
|
+
`isRendering: ${scheduler.isRendering}`,
|
|
486
|
+
`hasScheduledRender: ${scheduler.hasScheduledRender}`
|
|
487
|
+
];
|
|
488
|
+
if (frame !== undefined) {
|
|
489
|
+
details.push(`lastFrame:
|
|
490
|
+
${frame}`);
|
|
491
|
+
}
|
|
492
|
+
return new Error(details.join(`
|
|
493
|
+
`));
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
class TestExternalOutputRecorder {
|
|
497
|
+
commits = [];
|
|
498
|
+
constructor(renderer) {
|
|
499
|
+
renderer.on("external_output" /* EXTERNAL_OUTPUT */, this.record);
|
|
500
|
+
renderer.once("destroy" /* DESTROY */, () => {
|
|
501
|
+
renderer.off("external_output" /* EXTERNAL_OUTPUT */, this.record);
|
|
502
|
+
});
|
|
503
|
+
}
|
|
504
|
+
record = (event) => {
|
|
505
|
+
const raw = decoder.decode(event.snapshot.getRealCharBytes(false));
|
|
506
|
+
const rows = Array.from({ length: event.snapshot.height }, (_, index) => raw.slice(index * event.snapshot.width, (index + 1) * event.snapshot.width).trimEnd());
|
|
507
|
+
this.commits.push({
|
|
508
|
+
text: rows.join(`
|
|
509
|
+
`),
|
|
510
|
+
rows,
|
|
511
|
+
width: event.snapshot.width,
|
|
512
|
+
height: event.snapshot.height,
|
|
513
|
+
rowColumns: event.rowColumns,
|
|
514
|
+
startOnNewLine: event.startOnNewLine,
|
|
515
|
+
trailingNewline: event.trailingNewline
|
|
516
|
+
});
|
|
517
|
+
};
|
|
518
|
+
take() {
|
|
519
|
+
const commits = this.commits;
|
|
520
|
+
this.commits = [];
|
|
521
|
+
return commits;
|
|
522
|
+
}
|
|
523
|
+
takeText() {
|
|
524
|
+
return this.take().flatMap((commit) => commit.rows).join(`
|
|
525
|
+
`);
|
|
526
|
+
}
|
|
527
|
+
clear() {
|
|
528
|
+
this.commits = [];
|
|
529
|
+
}
|
|
530
|
+
}
|
|
531
|
+
function waitForNextFrameOrIdle(renderer) {
|
|
532
|
+
const scheduler = renderer.getSchedulerState();
|
|
533
|
+
if (!scheduler.isRunning && !scheduler.isRendering && !scheduler.hasScheduledRender) {
|
|
534
|
+
return Promise.resolve(null);
|
|
535
|
+
}
|
|
536
|
+
return new Promise((resolve) => {
|
|
537
|
+
let settled = false;
|
|
538
|
+
const cleanup = () => {
|
|
539
|
+
renderer.off("frame" /* FRAME */, onFrame);
|
|
540
|
+
renderer.off("destroy" /* DESTROY */, onDestroy);
|
|
541
|
+
};
|
|
542
|
+
const finish = (event) => {
|
|
543
|
+
if (settled)
|
|
544
|
+
return;
|
|
545
|
+
settled = true;
|
|
546
|
+
cleanup();
|
|
547
|
+
resolve(event);
|
|
548
|
+
};
|
|
549
|
+
const onFrame = (event) => {
|
|
550
|
+
finish(event);
|
|
551
|
+
};
|
|
552
|
+
const onDestroy = () => {
|
|
553
|
+
finish(null);
|
|
554
|
+
};
|
|
555
|
+
renderer.on("frame" /* FRAME */, onFrame);
|
|
556
|
+
renderer.once("destroy" /* DESTROY */, onDestroy);
|
|
557
|
+
if (!scheduler.isRunning) {
|
|
558
|
+
renderer.idle().then(() => finish(null));
|
|
559
|
+
}
|
|
560
|
+
});
|
|
561
|
+
}
|
|
461
562
|
|
|
462
563
|
class TestWriteStream extends Writable {
|
|
463
564
|
isTTY = true;
|
|
@@ -485,6 +586,7 @@ async function createTestRenderer(options) {
|
|
|
485
586
|
consoleMode: options.consoleMode ?? "disabled",
|
|
486
587
|
externalOutputMode: options.externalOutputMode ?? "passthrough"
|
|
487
588
|
});
|
|
589
|
+
const externalOutput = new TestExternalOutputRecorder(renderer);
|
|
488
590
|
const mockInput = createMockKeys(renderer, {
|
|
489
591
|
kittyKeyboard: options.kittyKeyboard,
|
|
490
592
|
otherModifiersMode: options.otherModifiersMode
|
|
@@ -493,16 +595,95 @@ async function createTestRenderer(options) {
|
|
|
493
595
|
const renderOnce = async () => {
|
|
494
596
|
await renderer.loop();
|
|
495
597
|
};
|
|
598
|
+
const captureCharFrame = () => {
|
|
599
|
+
const currentBuffer = renderer.currentRenderBuffer;
|
|
600
|
+
const frameBytes = currentBuffer.getRealCharBytes(true);
|
|
601
|
+
return decoder.decode(frameBytes);
|
|
602
|
+
};
|
|
603
|
+
const waitForVisualIdle = async (waitOptions = {}) => {
|
|
604
|
+
const maxFrames = normalizePositiveInteger(waitOptions.maxFrames, DEFAULT_MAX_VISUAL_IDLE_FRAMES);
|
|
605
|
+
const quietFrames = normalizePositiveInteger(waitOptions.quietFrames, DEFAULT_QUIET_FRAMES);
|
|
606
|
+
let consecutiveQuietFrames = 0;
|
|
607
|
+
for (let frame = 0;frame < maxFrames; frame++) {
|
|
608
|
+
await drainImmediateWork();
|
|
609
|
+
const scheduler2 = renderer.getSchedulerState();
|
|
610
|
+
if (!scheduler2.isRunning && !scheduler2.isRendering && !scheduler2.hasScheduledRender) {
|
|
611
|
+
return;
|
|
612
|
+
}
|
|
613
|
+
const event = await waitForNextFrameOrIdle(renderer);
|
|
614
|
+
if (!event) {
|
|
615
|
+
return;
|
|
616
|
+
}
|
|
617
|
+
if (renderer.getNativeStats().cellsUpdated === 0) {
|
|
618
|
+
consecutiveQuietFrames++;
|
|
619
|
+
if (consecutiveQuietFrames >= quietFrames) {
|
|
620
|
+
return;
|
|
621
|
+
}
|
|
622
|
+
} else {
|
|
623
|
+
consecutiveQuietFrames = 0;
|
|
624
|
+
}
|
|
625
|
+
}
|
|
626
|
+
await drainImmediateWork();
|
|
627
|
+
const scheduler = renderer.getSchedulerState();
|
|
628
|
+
if (!scheduler.isRunning && !scheduler.isRendering && !scheduler.hasScheduledRender) {
|
|
629
|
+
return;
|
|
630
|
+
}
|
|
631
|
+
throw createWaitError(renderer, `Timed out waiting for visual idle after ${maxFrames} frames`);
|
|
632
|
+
};
|
|
633
|
+
const flush = async (flushOptions = {}) => {
|
|
634
|
+
await waitForVisualIdle({ maxFrames: normalizePositiveInteger(flushOptions.maxPasses, DEFAULT_MAX_PASSES) });
|
|
635
|
+
};
|
|
636
|
+
const waitFor = async (predicate, waitOptions = {}) => {
|
|
637
|
+
const maxPasses = normalizePositiveInteger(waitOptions.maxPasses, DEFAULT_MAX_PASSES);
|
|
638
|
+
for (let pass = 0;pass <= maxPasses; pass++) {
|
|
639
|
+
await drainImmediateWork();
|
|
640
|
+
if (await predicate()) {
|
|
641
|
+
return;
|
|
642
|
+
}
|
|
643
|
+
if (pass === maxPasses) {
|
|
644
|
+
break;
|
|
645
|
+
}
|
|
646
|
+
const scheduler = renderer.getSchedulerState();
|
|
647
|
+
if (!scheduler.isRunning && !scheduler.isRendering && !scheduler.hasScheduledRender) {
|
|
648
|
+
break;
|
|
649
|
+
}
|
|
650
|
+
await waitForNextFrameOrIdle(renderer);
|
|
651
|
+
}
|
|
652
|
+
throw createWaitError(renderer, `Timed out waiting for predicate after ${maxPasses} passes`);
|
|
653
|
+
};
|
|
654
|
+
const waitForFrame = async (predicate, waitOptions = {}) => {
|
|
655
|
+
const maxPasses = normalizePositiveInteger(waitOptions.maxPasses, DEFAULT_MAX_PASSES);
|
|
656
|
+
let frame = captureCharFrame();
|
|
657
|
+
for (let pass = 0;pass <= maxPasses; pass++) {
|
|
658
|
+
await drainImmediateWork();
|
|
659
|
+
frame = captureCharFrame();
|
|
660
|
+
if (await predicate(frame)) {
|
|
661
|
+
return frame;
|
|
662
|
+
}
|
|
663
|
+
if (pass === maxPasses) {
|
|
664
|
+
break;
|
|
665
|
+
}
|
|
666
|
+
const scheduler = renderer.getSchedulerState();
|
|
667
|
+
if (!scheduler.isRunning && !scheduler.isRendering && !scheduler.hasScheduledRender) {
|
|
668
|
+
break;
|
|
669
|
+
}
|
|
670
|
+
await waitForNextFrameOrIdle(renderer);
|
|
671
|
+
}
|
|
672
|
+
frame = captureCharFrame();
|
|
673
|
+
throw createWaitError(renderer, `Timed out waiting for frame predicate after ${maxPasses} passes`, frame);
|
|
674
|
+
};
|
|
496
675
|
return {
|
|
497
676
|
renderer,
|
|
498
677
|
mockInput,
|
|
499
678
|
mockMouse,
|
|
500
679
|
renderOnce,
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
680
|
+
flush,
|
|
681
|
+
waitFor,
|
|
682
|
+
waitForFrame,
|
|
683
|
+
waitForVisualIdle,
|
|
684
|
+
externalOutput,
|
|
685
|
+
getNativeStats: () => renderer.getNativeStats(),
|
|
686
|
+
captureCharFrame,
|
|
506
687
|
captureSpans: () => {
|
|
507
688
|
const currentBuffer = renderer.currentRenderBuffer;
|
|
508
689
|
const lines = currentBuffer.getSpanLines();
|
|
@@ -524,9 +705,11 @@ async function setupTestRenderer(config) {
|
|
|
524
705
|
const width = config.width || config.stdout?.columns || process.stdout.columns || 80;
|
|
525
706
|
const height = config.height || config.stdout?.rows || process.stdout.rows || 24;
|
|
526
707
|
const stdout = config.stdout || new TestWriteStream(width, height);
|
|
527
|
-
const
|
|
708
|
+
const screenMode = config.screenMode ?? "alternate-screen";
|
|
709
|
+
const footerHeight = config.footerHeight ?? 12;
|
|
710
|
+
const geometry = calculateRenderGeometry(screenMode, width, height, footerHeight);
|
|
528
711
|
const ziglib = resolveRenderLib();
|
|
529
|
-
const rendererPtr = ziglib.createRenderer(
|
|
712
|
+
const rendererPtr = ziglib.createRenderer(geometry.renderWidth, geometry.renderHeight, {
|
|
530
713
|
testing: true,
|
|
531
714
|
remote: config.remote ?? false
|
|
532
715
|
});
|
|
@@ -594,6 +777,41 @@ class MockTreeSitterClient extends TreeSitterClient {
|
|
|
594
777
|
return this._highlightPromises.length > 0;
|
|
595
778
|
}
|
|
596
779
|
}
|
|
780
|
+
// src/testing/terminal-capabilities.ts
|
|
781
|
+
function createTerminalCapabilities(overrides = {}) {
|
|
782
|
+
return {
|
|
783
|
+
kitty_keyboard: false,
|
|
784
|
+
kitty_graphics: false,
|
|
785
|
+
rgb: false,
|
|
786
|
+
ansi256: false,
|
|
787
|
+
unicode: "unicode",
|
|
788
|
+
sgr_pixels: false,
|
|
789
|
+
color_scheme_updates: false,
|
|
790
|
+
explicit_width: false,
|
|
791
|
+
scaled_text: false,
|
|
792
|
+
sixel: false,
|
|
793
|
+
focus_tracking: false,
|
|
794
|
+
sync: false,
|
|
795
|
+
bracketed_paste: false,
|
|
796
|
+
hyperlinks: false,
|
|
797
|
+
osc52: false,
|
|
798
|
+
notifications: false,
|
|
799
|
+
explicit_cursor_positioning: false,
|
|
800
|
+
in_tmux: false,
|
|
801
|
+
...overrides,
|
|
802
|
+
terminal: {
|
|
803
|
+
name: "",
|
|
804
|
+
version: "",
|
|
805
|
+
from_xtversion: false,
|
|
806
|
+
...overrides.terminal
|
|
807
|
+
}
|
|
808
|
+
};
|
|
809
|
+
}
|
|
810
|
+
function setRendererCapabilities(renderer, overrides = {}) {
|
|
811
|
+
const capabilities = createTerminalCapabilities(overrides);
|
|
812
|
+
renderer._capabilities = capabilities;
|
|
813
|
+
return capabilities;
|
|
814
|
+
}
|
|
597
815
|
// src/testing/spy.ts
|
|
598
816
|
function createSpy() {
|
|
599
817
|
const calls = [];
|
|
@@ -608,6 +826,94 @@ function createSpy() {
|
|
|
608
826
|
spy.reset = () => calls.length = 0;
|
|
609
827
|
return spy;
|
|
610
828
|
}
|
|
829
|
+
// src/testing/manual-clock.ts
|
|
830
|
+
function compareTimers(left, right) {
|
|
831
|
+
if (left.fireAt !== right.fireAt) {
|
|
832
|
+
return left.fireAt - right.fireAt;
|
|
833
|
+
}
|
|
834
|
+
return left.order - right.order;
|
|
835
|
+
}
|
|
836
|
+
|
|
837
|
+
class ManualClock {
|
|
838
|
+
time = 0;
|
|
839
|
+
nextId = 1;
|
|
840
|
+
nextOrder = 0;
|
|
841
|
+
timers = new Map;
|
|
842
|
+
now() {
|
|
843
|
+
return this.time;
|
|
844
|
+
}
|
|
845
|
+
setTime(time) {
|
|
846
|
+
const targetTime = Math.floor(time);
|
|
847
|
+
if (targetTime >= this.time) {
|
|
848
|
+
this.advance(targetTime - this.time);
|
|
849
|
+
return;
|
|
850
|
+
}
|
|
851
|
+
this.time = targetTime;
|
|
852
|
+
}
|
|
853
|
+
setTimeout(fn, delayMs) {
|
|
854
|
+
return this.schedule(fn, delayMs, false);
|
|
855
|
+
}
|
|
856
|
+
clearTimeout(handle) {
|
|
857
|
+
this.timers.delete(Number(handle));
|
|
858
|
+
}
|
|
859
|
+
setInterval(fn, delayMs) {
|
|
860
|
+
return this.schedule(fn, delayMs, true);
|
|
861
|
+
}
|
|
862
|
+
clearInterval(handle) {
|
|
863
|
+
this.clearTimeout(handle);
|
|
864
|
+
}
|
|
865
|
+
advance(delayMs) {
|
|
866
|
+
const targetTime = this.time + Math.max(0, Math.floor(delayMs));
|
|
867
|
+
while (true) {
|
|
868
|
+
const nextTimer = this.peekNextTimer();
|
|
869
|
+
if (!nextTimer || nextTimer.fireAt > targetTime) {
|
|
870
|
+
break;
|
|
871
|
+
}
|
|
872
|
+
this.timers.delete(nextTimer.id);
|
|
873
|
+
this.time = nextTimer.fireAt;
|
|
874
|
+
nextTimer.fn();
|
|
875
|
+
if (nextTimer.repeat && !this.timers.has(nextTimer.id)) {
|
|
876
|
+
this.timers.set(nextTimer.id, {
|
|
877
|
+
...nextTimer,
|
|
878
|
+
fireAt: this.time + nextTimer.delayMs,
|
|
879
|
+
order: this.nextOrder++
|
|
880
|
+
});
|
|
881
|
+
}
|
|
882
|
+
}
|
|
883
|
+
this.time = targetTime;
|
|
884
|
+
}
|
|
885
|
+
runAll() {
|
|
886
|
+
while (true) {
|
|
887
|
+
const nextTimer = this.peekNextTimer();
|
|
888
|
+
if (!nextTimer) {
|
|
889
|
+
return;
|
|
890
|
+
}
|
|
891
|
+
this.advance(nextTimer.fireAt - this.time);
|
|
892
|
+
}
|
|
893
|
+
}
|
|
894
|
+
schedule(fn, delayMs, repeat) {
|
|
895
|
+
const id = this.nextId++;
|
|
896
|
+
const normalizedDelay = Math.max(0, Math.floor(delayMs));
|
|
897
|
+
this.timers.set(id, {
|
|
898
|
+
id,
|
|
899
|
+
fireAt: this.time + normalizedDelay,
|
|
900
|
+
order: this.nextOrder++,
|
|
901
|
+
delayMs: normalizedDelay,
|
|
902
|
+
repeat,
|
|
903
|
+
fn
|
|
904
|
+
});
|
|
905
|
+
return id;
|
|
906
|
+
}
|
|
907
|
+
peekNextTimer() {
|
|
908
|
+
let nextTimer = null;
|
|
909
|
+
for (const timer of this.timers.values()) {
|
|
910
|
+
if (!nextTimer || compareTimers(timer, nextTimer) < 0) {
|
|
911
|
+
nextTimer = timer;
|
|
912
|
+
}
|
|
913
|
+
}
|
|
914
|
+
return nextTimer;
|
|
915
|
+
}
|
|
916
|
+
}
|
|
611
917
|
// src/testing/test-recorder.ts
|
|
612
918
|
class TestRecorder {
|
|
613
919
|
renderer;
|
|
@@ -615,10 +921,14 @@ class TestRecorder {
|
|
|
615
921
|
recording = false;
|
|
616
922
|
frameNumber = 0;
|
|
617
923
|
startTime = 0;
|
|
618
|
-
originalRenderNative;
|
|
619
924
|
decoder = new TextDecoder;
|
|
620
925
|
recordBuffers;
|
|
621
926
|
now;
|
|
927
|
+
onFrame = () => {
|
|
928
|
+
if (!this.recording)
|
|
929
|
+
return;
|
|
930
|
+
this.captureFrame();
|
|
931
|
+
};
|
|
622
932
|
constructor(renderer, options) {
|
|
623
933
|
this.renderer = renderer;
|
|
624
934
|
this.recordBuffers = options?.recordBuffers || {};
|
|
@@ -632,21 +942,14 @@ class TestRecorder {
|
|
|
632
942
|
this.frames = [];
|
|
633
943
|
this.frameNumber = 0;
|
|
634
944
|
this.startTime = this.now();
|
|
635
|
-
this.
|
|
636
|
-
this.renderer["renderNative"] = () => {
|
|
637
|
-
this.originalRenderNative();
|
|
638
|
-
this.captureFrame();
|
|
639
|
-
};
|
|
945
|
+
this.renderer.on("frame" /* FRAME */, this.onFrame);
|
|
640
946
|
}
|
|
641
947
|
stop() {
|
|
642
948
|
if (!this.recording) {
|
|
643
949
|
return;
|
|
644
950
|
}
|
|
645
951
|
this.recording = false;
|
|
646
|
-
|
|
647
|
-
this.renderer["renderNative"] = this.originalRenderNative;
|
|
648
|
-
this.originalRenderNative = undefined;
|
|
649
|
-
}
|
|
952
|
+
this.renderer.off("frame" /* FRAME */, this.onFrame);
|
|
650
953
|
}
|
|
651
954
|
get recordedFrames() {
|
|
652
955
|
return [...this.frames];
|
|
@@ -671,10 +974,10 @@ class TestRecorder {
|
|
|
671
974
|
const buffers = currentBuffer.buffers;
|
|
672
975
|
recordedFrame.buffers = {};
|
|
673
976
|
if (this.recordBuffers.fg) {
|
|
674
|
-
recordedFrame.buffers.fg = new
|
|
977
|
+
recordedFrame.buffers.fg = new Uint16Array(buffers.fg);
|
|
675
978
|
}
|
|
676
979
|
if (this.recordBuffers.bg) {
|
|
677
|
-
recordedFrame.buffers.bg = new
|
|
980
|
+
recordedFrame.buffers.bg = new Uint16Array(buffers.bg);
|
|
678
981
|
}
|
|
679
982
|
if (this.recordBuffers.attributes) {
|
|
680
983
|
recordedFrame.buffers.attributes = new Uint8Array(buffers.attributes);
|
|
@@ -684,16 +987,19 @@ class TestRecorder {
|
|
|
684
987
|
}
|
|
685
988
|
}
|
|
686
989
|
export {
|
|
990
|
+
setRendererCapabilities,
|
|
687
991
|
pasteBytes,
|
|
688
992
|
createTestRenderer,
|
|
993
|
+
createTerminalCapabilities,
|
|
689
994
|
createSpy,
|
|
690
995
|
createMockMouse,
|
|
691
996
|
createMockKeys,
|
|
692
997
|
TestRecorder,
|
|
693
998
|
MouseButtons,
|
|
694
999
|
MockTreeSitterClient,
|
|
1000
|
+
ManualClock,
|
|
695
1001
|
KeyCodes
|
|
696
1002
|
};
|
|
697
1003
|
|
|
698
|
-
//# debugId=
|
|
1004
|
+
//# debugId=11276D484C35A4DF64756E2164756E21
|
|
699
1005
|
//# sourceMappingURL=testing.js.map
|