@opentui/core 0.0.0-20250912-12c969f4 → 0.0.0-20250915-7be4d9eb

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.
@@ -1,3 +1,4 @@
1
+ // @bun
1
2
  var __create = Object.create;
2
3
  var __getProtoOf = Object.getPrototypeOf;
3
4
  var __defProp = Object.defineProperty;
@@ -1804,12 +1805,6 @@ class TrackedNode extends EventEmitter {
1804
1805
  const index = this.children.length;
1805
1806
  this.children.push(childNode);
1806
1807
  this.yogaNode.insertChild(childNode.yogaNode, index);
1807
- try {
1808
- childNode.yogaNode.setWidth(childNode.parseWidth(childNode._width));
1809
- childNode.yogaNode.setHeight(childNode.parseHeight(childNode._height));
1810
- } catch (e) {
1811
- console.error("Error setting width and height", e);
1812
- }
1813
1808
  return index;
1814
1809
  }
1815
1810
  getChildIndex(childNode) {
@@ -1858,12 +1853,6 @@ class TrackedNode extends EventEmitter {
1858
1853
  const boundedIndex = Math.max(0, Math.min(index, this.children.length));
1859
1854
  this.children.splice(boundedIndex, 0, childNode);
1860
1855
  this.yogaNode.insertChild(childNode.yogaNode, boundedIndex);
1861
- try {
1862
- childNode.yogaNode.setWidth(childNode.parseWidth(childNode._width));
1863
- childNode.yogaNode.setHeight(childNode.parseHeight(childNode._height));
1864
- } catch (e) {
1865
- console.error("Error setting width and height", e);
1866
- }
1867
1856
  return boundedIndex;
1868
1857
  }
1869
1858
  getChildCount() {
@@ -1907,6 +1896,237 @@ function createTrackedNode(metadata = {}, yogaConfig) {
1907
1896
 
1908
1897
  // src/lib/parse.keypress.ts
1909
1898
  import { Buffer } from "buffer";
1899
+
1900
+ // src/lib/parse.keypress-kitty.ts
1901
+ var kittyKeyMap = {
1902
+ 27: "escape",
1903
+ 9: "tab",
1904
+ 13: "enter",
1905
+ 127: "backspace",
1906
+ 57344: "escape",
1907
+ 57345: "enter",
1908
+ 57346: "tab",
1909
+ 57347: "backspace",
1910
+ 57348: "insert",
1911
+ 57349: "delete",
1912
+ 57350: "left",
1913
+ 57351: "right",
1914
+ 57352: "up",
1915
+ 57353: "down",
1916
+ 57354: "pageup",
1917
+ 57355: "pagedown",
1918
+ 57356: "home",
1919
+ 57357: "end",
1920
+ 57364: "f1",
1921
+ 57365: "f2",
1922
+ 57366: "f3",
1923
+ 57367: "f4",
1924
+ 57368: "f5",
1925
+ 57369: "f6",
1926
+ 57370: "f7",
1927
+ 57371: "f8",
1928
+ 57372: "f9",
1929
+ 57373: "f10",
1930
+ 57374: "f11",
1931
+ 57375: "f12",
1932
+ 57376: "f13",
1933
+ 57377: "f14",
1934
+ 57378: "f15",
1935
+ 57379: "f16",
1936
+ 57380: "f17",
1937
+ 57381: "f18",
1938
+ 57382: "f19",
1939
+ 57383: "f20",
1940
+ 57384: "f21",
1941
+ 57385: "f22",
1942
+ 57386: "f23",
1943
+ 57387: "f24",
1944
+ 57388: "f25",
1945
+ 57389: "f26",
1946
+ 57390: "f27",
1947
+ 57391: "f28",
1948
+ 57392: "f29",
1949
+ 57393: "f30",
1950
+ 57394: "f31",
1951
+ 57395: "f32",
1952
+ 57396: "f33",
1953
+ 57397: "f34",
1954
+ 57398: "f35",
1955
+ 57400: "kp0",
1956
+ 57401: "kp1",
1957
+ 57402: "kp2",
1958
+ 57403: "kp3",
1959
+ 57404: "kp4",
1960
+ 57405: "kp5",
1961
+ 57406: "kp6",
1962
+ 57407: "kp7",
1963
+ 57408: "kp8",
1964
+ 57409: "kp9",
1965
+ 57410: "kpdecimal",
1966
+ 57411: "kpdivide",
1967
+ 57412: "kpmultiply",
1968
+ 57413: "kpminus",
1969
+ 57414: "kpplus",
1970
+ 57415: "kpenter",
1971
+ 57416: "kpequal",
1972
+ 57428: "mediaplay",
1973
+ 57429: "mediapause",
1974
+ 57430: "mediaplaypause",
1975
+ 57431: "mediareverse",
1976
+ 57432: "mediastop",
1977
+ 57433: "mediafastforward",
1978
+ 57434: "mediarewind",
1979
+ 57435: "medianext",
1980
+ 57436: "mediaprev",
1981
+ 57437: "mediarecord",
1982
+ 57438: "volumedown",
1983
+ 57439: "volumeup",
1984
+ 57440: "mute",
1985
+ 57441: "leftshift",
1986
+ 57442: "leftctrl",
1987
+ 57443: "leftalt",
1988
+ 57444: "leftsuper",
1989
+ 57445: "lefthyper",
1990
+ 57446: "leftmeta",
1991
+ 57447: "rightshift",
1992
+ 57448: "rightctrl",
1993
+ 57449: "rightalt",
1994
+ 57450: "rightsuper",
1995
+ 57451: "righthyper",
1996
+ 57452: "rightmeta",
1997
+ 57453: "iso_level3_shift",
1998
+ 57454: "iso_level5_shift"
1999
+ };
2000
+ function fromKittyMods(mod) {
2001
+ return {
2002
+ shift: !!(mod & 1),
2003
+ alt: !!(mod & 2),
2004
+ ctrl: !!(mod & 4),
2005
+ super: !!(mod & 8),
2006
+ hyper: !!(mod & 16),
2007
+ meta: !!(mod & 32),
2008
+ capsLock: !!(mod & 64),
2009
+ numLock: !!(mod & 128)
2010
+ };
2011
+ }
2012
+ function parseKittyKeyboard(sequence) {
2013
+ const kittyRe = /^\x1b\[([^\x1b]+)u$/;
2014
+ const match = kittyRe.exec(sequence);
2015
+ if (!match)
2016
+ return null;
2017
+ const params = match[1];
2018
+ const fields = params.split(";");
2019
+ if (fields.length < 1)
2020
+ return null;
2021
+ const key = {
2022
+ name: "",
2023
+ ctrl: false,
2024
+ meta: false,
2025
+ shift: false,
2026
+ option: false,
2027
+ number: false,
2028
+ sequence,
2029
+ raw: sequence,
2030
+ eventType: "press",
2031
+ super: false,
2032
+ hyper: false,
2033
+ capsLock: false,
2034
+ numLock: false
2035
+ };
2036
+ let text = "";
2037
+ const field1 = fields[0]?.split(":") || [];
2038
+ const codepointStr = field1[0];
2039
+ if (!codepointStr)
2040
+ return null;
2041
+ const codepoint = parseInt(codepointStr, 10);
2042
+ if (isNaN(codepoint))
2043
+ return null;
2044
+ let shiftedCodepoint;
2045
+ let baseCodepoint;
2046
+ if (field1[1]) {
2047
+ const shifted = parseInt(field1[1], 10);
2048
+ if (!isNaN(shifted) && shifted > 0 && shifted <= 1114111) {
2049
+ shiftedCodepoint = shifted;
2050
+ }
2051
+ }
2052
+ if (field1[2]) {
2053
+ const base = parseInt(field1[2], 10);
2054
+ if (!isNaN(base) && base > 0 && base <= 1114111) {
2055
+ baseCodepoint = base;
2056
+ }
2057
+ }
2058
+ const knownKey = kittyKeyMap[codepoint];
2059
+ if (knownKey) {
2060
+ key.name = knownKey;
2061
+ key.code = `[${codepoint}u`;
2062
+ } else {
2063
+ if (codepoint > 0 && codepoint <= 1114111) {
2064
+ const char = String.fromCodePoint(codepoint);
2065
+ key.name = char;
2066
+ if (baseCodepoint) {
2067
+ key.baseCode = baseCodepoint;
2068
+ }
2069
+ } else {
2070
+ return null;
2071
+ }
2072
+ }
2073
+ if (fields[1]) {
2074
+ const field2 = fields[1].split(":");
2075
+ const modifierStr = field2[0];
2076
+ const eventTypeStr = field2[1];
2077
+ if (modifierStr) {
2078
+ const modifierMask = parseInt(modifierStr, 10);
2079
+ if (!isNaN(modifierMask) && modifierMask > 1) {
2080
+ const mods = fromKittyMods(modifierMask - 1);
2081
+ key.shift = mods.shift;
2082
+ key.ctrl = mods.ctrl;
2083
+ key.meta = mods.alt || mods.meta;
2084
+ key.option = mods.alt;
2085
+ key.super = mods.super;
2086
+ key.hyper = mods.hyper;
2087
+ key.capsLock = mods.capsLock;
2088
+ key.numLock = mods.numLock;
2089
+ }
2090
+ }
2091
+ if (eventTypeStr === "1" || !eventTypeStr) {
2092
+ key.eventType = "press";
2093
+ } else if (eventTypeStr === "2") {
2094
+ key.eventType = "repeat";
2095
+ } else if (eventTypeStr === "3") {
2096
+ key.eventType = "release";
2097
+ } else {
2098
+ key.eventType = "press";
2099
+ }
2100
+ }
2101
+ if (fields[2]) {
2102
+ const codepoints = fields[2].split(":");
2103
+ for (const cpStr of codepoints) {
2104
+ const cp = parseInt(cpStr, 10);
2105
+ if (!isNaN(cp) && cp > 0 && cp <= 1114111) {
2106
+ text += String.fromCodePoint(cp);
2107
+ }
2108
+ }
2109
+ }
2110
+ if (text === "") {
2111
+ const isPrintable = key.name.length > 0 && !kittyKeyMap[codepoint];
2112
+ if (isPrintable) {
2113
+ if (key.shift && shiftedCodepoint) {
2114
+ text = String.fromCodePoint(shiftedCodepoint);
2115
+ } else {
2116
+ text = key.name;
2117
+ }
2118
+ }
2119
+ }
2120
+ if (key.name === " " && key.shift && !key.ctrl && !key.meta) {
2121
+ text = " ";
2122
+ }
2123
+ if (text) {
2124
+ key.sequence = text;
2125
+ }
2126
+ return key;
2127
+ }
2128
+
2129
+ // src/lib/parse.keypress.ts
1910
2130
  var metaKeyCodeRe = /^(?:\x1b)([a-zA-Z0-9])$/;
1911
2131
  var fnKeyRe = /^(?:\x1b+)(O|N|\[|\[\[)(?:(\d+)(?:;(\d+))?([~^$])|(?:1;)?(\d+)?([a-zA-Z]))/;
1912
2132
  var keyName = {
@@ -1990,7 +2210,7 @@ var isShiftKey = (code) => {
1990
2210
  var isCtrlKey = (code) => {
1991
2211
  return ["Oa", "Ob", "Oc", "Od", "Oe", "[2^", "[3^", "[5^", "[6^", "[7^", "[8^"].includes(code);
1992
2212
  };
1993
- var parseKeypress = (s = "") => {
2213
+ var parseKeypress = (s = "", options = {}) => {
1994
2214
  let parts;
1995
2215
  if (Buffer.isBuffer(s)) {
1996
2216
  if (s[0] > 127 && s[1] === undefined) {
@@ -2012,9 +2232,16 @@ var parseKeypress = (s = "") => {
2012
2232
  option: false,
2013
2233
  number: false,
2014
2234
  sequence: s,
2015
- raw: s
2235
+ raw: s,
2236
+ eventType: "press"
2016
2237
  };
2017
2238
  key.sequence = key.sequence || s || key.name;
2239
+ if (options.useKittyKeyboard && /^\x1b\[.*u$/.test(s)) {
2240
+ const kittyResult = parseKittyKeyboard(s);
2241
+ if (kittyResult) {
2242
+ return kittyResult;
2243
+ }
2244
+ }
2018
2245
  if (s === "\r") {
2019
2246
  key.name = "return";
2020
2247
  } else if (s === `
@@ -2054,15 +2281,21 @@ var parseKeypress = (s = "") => {
2054
2281
  key.option = true;
2055
2282
  }
2056
2283
  const code = [parts[1], parts[2], parts[4], parts[6]].filter(Boolean).join("");
2057
- const modifier = (parts[3] || parts[5] || 1) - 1;
2284
+ const modifier = parseInt(parts[3] || parts[5] || "1", 10) - 1;
2058
2285
  key.ctrl = !!(modifier & 4);
2059
2286
  key.meta = !!(modifier & 10);
2060
2287
  key.shift = !!(modifier & 1);
2061
2288
  key.option = !!(modifier & 2);
2062
2289
  key.code = code;
2063
- key.name = keyName[code];
2064
- key.shift = isShiftKey(code) || key.shift;
2065
- key.ctrl = isCtrlKey(code) || key.ctrl;
2290
+ const keyNameResult = keyName[code];
2291
+ if (keyNameResult) {
2292
+ key.name = keyNameResult;
2293
+ key.shift = isShiftKey(code) || key.shift;
2294
+ key.ctrl = isCtrlKey(code) || key.ctrl;
2295
+ } else {
2296
+ key.name = "";
2297
+ key.code = undefined;
2298
+ }
2066
2299
  } else if (s === "\x1B[3~") {
2067
2300
  key.name = "delete";
2068
2301
  key.meta = false;
@@ -2086,26 +2319,43 @@ function singleton(key, factory) {
2086
2319
 
2087
2320
  // src/lib/KeyHandler.ts
2088
2321
  class KeyHandler extends EventEmitter2 {
2089
- constructor() {
2322
+ stdin;
2323
+ useKittyKeyboard;
2324
+ constructor(stdin, useKittyKeyboard = false) {
2090
2325
  super();
2091
- if (process.stdin.setRawMode) {
2092
- process.stdin.setRawMode(true);
2093
- }
2094
- process.stdin.resume();
2095
- process.stdin.setEncoding("utf8");
2096
- process.stdin.on("data", (key) => {
2097
- const parsedKey = parseKeypress(key);
2098
- this.emit("keypress", parsedKey);
2326
+ this.stdin = stdin || process.stdin;
2327
+ this.useKittyKeyboard = useKittyKeyboard;
2328
+ if (this.stdin.setRawMode) {
2329
+ this.stdin.setRawMode(true);
2330
+ }
2331
+ this.stdin.resume();
2332
+ this.stdin.setEncoding("utf8");
2333
+ this.stdin.on("data", (key) => {
2334
+ const parsedKey = parseKeypress(key, { useKittyKeyboard: this.useKittyKeyboard });
2335
+ switch (parsedKey.eventType) {
2336
+ case "press":
2337
+ this.emit("keypress", parsedKey);
2338
+ break;
2339
+ case "repeat":
2340
+ this.emit("keyrepeat", parsedKey);
2341
+ break;
2342
+ case "release":
2343
+ this.emit("keyrelease", parsedKey);
2344
+ break;
2345
+ default:
2346
+ this.emit("keypress", parsedKey);
2347
+ break;
2348
+ }
2099
2349
  });
2100
2350
  }
2101
2351
  destroy() {
2102
- process.stdin.removeAllListeners("data");
2352
+ this.stdin.removeAllListeners("data");
2103
2353
  }
2104
2354
  }
2105
2355
  var keyHandler = null;
2106
- function getKeyHandler() {
2356
+ function getKeyHandler(useKittyKeyboard = false) {
2107
2357
  if (!keyHandler) {
2108
- keyHandler = singleton("KeyHandler", () => new KeyHandler);
2358
+ keyHandler = singleton("KeyHandler", () => new KeyHandler(process.stdin, useKittyKeyboard));
2109
2359
  }
2110
2360
  return keyHandler;
2111
2361
  }
@@ -4782,6 +5032,13 @@ class OptimizedBuffer {
4782
5032
  this.guard();
4783
5033
  return this.lib.bufferGetId(this.bufferPtr);
4784
5034
  }
5035
+ getRealCharBytes(addLineBreaks = false) {
5036
+ this.guard();
5037
+ const realSize = this.lib.bufferGetRealCharSize(this.bufferPtr);
5038
+ const outputBuffer = new Uint8Array(realSize);
5039
+ const bytesWritten = this.lib.bufferWriteResolvedChars(this.bufferPtr, outputBuffer, addLineBreaks);
5040
+ return outputBuffer.slice(0, bytesWritten);
5041
+ }
4785
5042
  clear(bg2 = RGBA.fromValues(0, 0, 0, 1)) {
4786
5043
  this.guard();
4787
5044
  this.lib.bufferClear(this.bufferPtr, bg2);
@@ -4887,7 +5144,7 @@ if (!existsSync(targetLibPath)) {
4887
5144
  }
4888
5145
  function getOpenTUILib(libPath) {
4889
5146
  const resolvedLibPath = libPath || targetLibPath;
4890
- return dlopen(resolvedLibPath, {
5147
+ const rawSymbols = dlopen(resolvedLibPath, {
4891
5148
  setLogCallback: {
4892
5149
  args: ["ptr"],
4893
5150
  returns: "void"
@@ -4897,7 +5154,7 @@ function getOpenTUILib(libPath) {
4897
5154
  returns: "ptr"
4898
5155
  },
4899
5156
  destroyRenderer: {
4900
- args: ["ptr", "bool", "u32"],
5157
+ args: ["ptr"],
4901
5158
  returns: "void"
4902
5159
  },
4903
5160
  setUseThread: {
@@ -4984,6 +5241,14 @@ function getOpenTUILib(libPath) {
4984
5241
  args: ["ptr", "ptr", "usize"],
4985
5242
  returns: "usize"
4986
5243
  },
5244
+ bufferGetRealCharSize: {
5245
+ args: ["ptr"],
5246
+ returns: "u32"
5247
+ },
5248
+ bufferWriteResolvedChars: {
5249
+ args: ["ptr", "ptr", "usize", "bool"],
5250
+ returns: "u32"
5251
+ },
4987
5252
  bufferDrawText: {
4988
5253
  args: ["ptr", "ptr", "u32", "u32", "u32", "ptr", "ptr", "u8"],
4989
5254
  returns: "void"
@@ -5217,6 +5482,115 @@ function getOpenTUILib(libPath) {
5217
5482
  returns: "void"
5218
5483
  }
5219
5484
  });
5485
+ if (process.env.DEBUG_FFI === "true" || process.env.TRACE_FFI === "true") {
5486
+ return {
5487
+ symbols: convertToDebugSymbols(rawSymbols.symbols)
5488
+ };
5489
+ }
5490
+ return rawSymbols;
5491
+ }
5492
+ function convertToDebugSymbols(symbols) {
5493
+ const debugSymbols = {};
5494
+ const traceSymbols = {};
5495
+ let hasTracing = false;
5496
+ Object.entries(symbols).forEach(([key, value]) => {
5497
+ debugSymbols[key] = value;
5498
+ });
5499
+ if (process.env.DEBUG_FFI === "true") {
5500
+ Object.entries(symbols).forEach(([key, value]) => {
5501
+ if (typeof value === "function") {
5502
+ debugSymbols[key] = (...args) => {
5503
+ console.log(`${key}(${args.map((arg) => String(arg)).join(", ")})`);
5504
+ const result = value(...args);
5505
+ console.log(`${key} returned:`, String(result));
5506
+ return result;
5507
+ };
5508
+ }
5509
+ });
5510
+ }
5511
+ if (process.env.TRACE_FFI === "true") {
5512
+ hasTracing = true;
5513
+ Object.entries(symbols).forEach(([key, value]) => {
5514
+ if (typeof value === "function") {
5515
+ traceSymbols[key] = [];
5516
+ const originalFunc = debugSymbols[key];
5517
+ debugSymbols[key] = (...args) => {
5518
+ const start = performance.now();
5519
+ const result = originalFunc(...args);
5520
+ const end = performance.now();
5521
+ traceSymbols[key].push(end - start);
5522
+ return result;
5523
+ };
5524
+ }
5525
+ });
5526
+ }
5527
+ if (hasTracing) {
5528
+ process.on("exit", () => {
5529
+ const allStats = [];
5530
+ for (const [key, timings] of Object.entries(traceSymbols)) {
5531
+ if (!Array.isArray(timings) || timings.length === 0) {
5532
+ continue;
5533
+ }
5534
+ const sortedTimings = [...timings].sort((a, b) => a - b);
5535
+ const count = sortedTimings.length;
5536
+ const total = sortedTimings.reduce((acc, t2) => acc + t2, 0);
5537
+ const average = total / count;
5538
+ const min = sortedTimings[0];
5539
+ const max = sortedTimings[count - 1];
5540
+ const medianIndex = Math.floor(count / 2);
5541
+ const p90Index = Math.floor(count * 0.9);
5542
+ const p99Index = Math.floor(count * 0.99);
5543
+ const median = sortedTimings[medianIndex];
5544
+ const p90 = sortedTimings[Math.min(p90Index, count - 1)];
5545
+ const p99 = sortedTimings[Math.min(p99Index, count - 1)];
5546
+ allStats.push({
5547
+ name: key,
5548
+ count,
5549
+ total,
5550
+ average,
5551
+ min,
5552
+ max,
5553
+ median,
5554
+ p90,
5555
+ p99
5556
+ });
5557
+ }
5558
+ allStats.sort((a, b) => b.total - a.total);
5559
+ console.log(`
5560
+ --- OpenTUI FFI Call Performance ---`);
5561
+ console.log("Sorted by total time spent (descending)");
5562
+ console.log("-------------------------------------------------------------------------------------------------------------------------");
5563
+ if (allStats.length === 0) {
5564
+ console.log("No trace data collected or all symbols had zero calls.");
5565
+ } else {
5566
+ const nameHeader = "Symbol";
5567
+ const callsHeader = "Calls";
5568
+ const totalHeader = "Total (ms)";
5569
+ const avgHeader = "Avg (ms)";
5570
+ const minHeader = "Min (ms)";
5571
+ const maxHeader = "Max (ms)";
5572
+ const medHeader = "Med (ms)";
5573
+ const p90Header = "P90 (ms)";
5574
+ const p99Header = "P99 (ms)";
5575
+ const nameWidth = Math.max(nameHeader.length, ...allStats.map((s) => s.name.length));
5576
+ const countWidth = Math.max(callsHeader.length, ...allStats.map((s) => String(s.count).length));
5577
+ const totalWidth = Math.max(totalHeader.length, ...allStats.map((s) => s.total.toFixed(2).length));
5578
+ const avgWidth = Math.max(avgHeader.length, ...allStats.map((s) => s.average.toFixed(2).length));
5579
+ const minWidth = Math.max(minHeader.length, ...allStats.map((s) => s.min.toFixed(2).length));
5580
+ const maxWidth = Math.max(maxHeader.length, ...allStats.map((s) => s.max.toFixed(2).length));
5581
+ const medianWidth = Math.max(medHeader.length, ...allStats.map((s) => s.median.toFixed(2).length));
5582
+ const p90Width = Math.max(p90Header.length, ...allStats.map((s) => s.p90.toFixed(2).length));
5583
+ const p99Width = Math.max(p99Header.length, ...allStats.map((s) => s.p99.toFixed(2).length));
5584
+ console.log(`${nameHeader.padEnd(nameWidth)} | ${callsHeader.padStart(countWidth)} | ${totalHeader.padStart(totalWidth)} | ${avgHeader.padStart(avgWidth)} | ${minHeader.padStart(minWidth)} | ${maxHeader.padStart(maxWidth)} | ${medHeader.padStart(medianWidth)} | ${p90Header.padStart(p90Width)} | ${p99Header.padStart(p99Width)}`);
5585
+ console.log(`${"-".repeat(nameWidth)}-+-${"-".repeat(countWidth)}-+-${"-".repeat(totalWidth)}-+-${"-".repeat(avgWidth)}-+-${"-".repeat(minWidth)}-+-${"-".repeat(maxWidth)}-+-${"-".repeat(medianWidth)}-+-${"-".repeat(p90Width)}-+-${"-".repeat(p99Width)}`);
5586
+ allStats.forEach((stat) => {
5587
+ console.log(`${stat.name.padEnd(nameWidth)} | ${String(stat.count).padStart(countWidth)} | ${stat.total.toFixed(2).padStart(totalWidth)} | ${stat.average.toFixed(2).padStart(avgWidth)} | ${stat.min.toFixed(2).padStart(minWidth)} | ${stat.max.toFixed(2).padStart(maxWidth)} | ${stat.median.toFixed(2).padStart(medianWidth)} | ${stat.p90.toFixed(2).padStart(p90Width)} | ${stat.p99.toFixed(2).padStart(p99Width)}`);
5588
+ });
5589
+ }
5590
+ console.log("-------------------------------------------------------------------------------------------------------------------------");
5591
+ });
5592
+ }
5593
+ return debugSymbols;
5220
5594
  }
5221
5595
  var LogLevel2;
5222
5596
  ((LogLevel3) => {
@@ -5283,8 +5657,8 @@ class FFIRenderLib {
5283
5657
  createRenderer(width, height, options = { testing: false }) {
5284
5658
  return this.opentui.symbols.createRenderer(width, height, options.testing);
5285
5659
  }
5286
- destroyRenderer(renderer, useAlternateScreen, splitHeight) {
5287
- this.opentui.symbols.destroyRenderer(renderer, useAlternateScreen, splitHeight);
5660
+ destroyRenderer(renderer) {
5661
+ this.opentui.symbols.destroyRenderer(renderer);
5288
5662
  }
5289
5663
  setUseThread(renderer, useThread) {
5290
5664
  this.opentui.symbols.setUseThread(renderer, useThread);
@@ -5360,6 +5734,13 @@ class FFIRenderLib {
5360
5734
  const len = typeof actualLen === "bigint" ? Number(actualLen) : actualLen;
5361
5735
  return this.decoder.decode(outBuffer.slice(0, len));
5362
5736
  }
5737
+ bufferGetRealCharSize(buffer) {
5738
+ return this.opentui.symbols.bufferGetRealCharSize(buffer);
5739
+ }
5740
+ bufferWriteResolvedChars(buffer, outputBuffer, addLineBreaks) {
5741
+ const bytesWritten = this.opentui.symbols.bufferWriteResolvedChars(buffer, outputBuffer, outputBuffer.length, addLineBreaks);
5742
+ return typeof bytesWritten === "bigint" ? Number(bytesWritten) : bytesWritten;
5743
+ }
5363
5744
  getBufferWidth(buffer) {
5364
5745
  return this.opentui.symbols.getBufferWidth(buffer);
5365
5746
  }
@@ -5990,7 +6371,6 @@ class Renderable extends BaseRenderable {
5990
6371
  frameBuffer = null;
5991
6372
  _focusable = false;
5992
6373
  _focused = false;
5993
- keyHandler = getKeyHandler();
5994
6374
  keypressHandler = null;
5995
6375
  _live = false;
5996
6376
  _liveCount = 0;
@@ -6095,7 +6475,7 @@ class Renderable extends BaseRenderable {
6095
6475
  this.handleKeyPress(key);
6096
6476
  }
6097
6477
  };
6098
- this.keyHandler.on("keypress", this.keypressHandler);
6478
+ this.ctx.keyInput.on("keypress", this.keypressHandler);
6099
6479
  this.emit("focused" /* FOCUSED */);
6100
6480
  }
6101
6481
  blur() {
@@ -6104,7 +6484,7 @@ class Renderable extends BaseRenderable {
6104
6484
  this._focused = false;
6105
6485
  this.requestRender();
6106
6486
  if (this.keypressHandler) {
6107
- this.keyHandler.off("keypress", this.keypressHandler);
6487
+ this.ctx.keyInput.off("keypress", this.keypressHandler);
6108
6488
  this.keypressHandler = null;
6109
6489
  }
6110
6490
  this.emit("blurred" /* BLURRED */);
@@ -8061,6 +8441,7 @@ class CliRenderer extends EventEmitter6 {
8061
8441
  };
8062
8442
  _console;
8063
8443
  _resolution = null;
8444
+ _keyHandler;
8064
8445
  animationRequest = new Map;
8065
8446
  resizeTimeoutId = null;
8066
8447
  resizeDebounceDelay = 100;
@@ -8085,11 +8466,57 @@ class CliRenderer extends EventEmitter6 {
8085
8466
  };
8086
8467
  _useConsole = true;
8087
8468
  mouseParser = new MouseParser;
8088
- sigwinchHandler = null;
8469
+ sigwinchHandler = (() => {
8470
+ const width = this.stdout.columns || 80;
8471
+ const height = this.stdout.rows || 24;
8472
+ this.handleResize(width, height);
8473
+ }).bind(this);
8089
8474
  _capabilities = null;
8090
8475
  _latestPointer = { x: 0, y: 0 };
8091
8476
  _currentFocusedRenderable = null;
8092
8477
  lifecyclePasses = new Set;
8478
+ handleError = ((error) => {
8479
+ this.stop();
8480
+ this.destroy();
8481
+ new Promise((resolve) => {
8482
+ setTimeout(() => {
8483
+ resolve(true);
8484
+ }, 100);
8485
+ }).then(() => {
8486
+ this.realStdoutWrite.call(this.stdout, `
8487
+ `.repeat(this._terminalHeight));
8488
+ this.realStdoutWrite.call(this.stdout, `
8489
+ === FATAL ERROR OCCURRED ===
8490
+ `);
8491
+ this.realStdoutWrite.call(this.stdout, `Console cache:
8492
+ `);
8493
+ this.realStdoutWrite.call(this.stdout, this.console.getCachedLogs());
8494
+ this.realStdoutWrite.call(this.stdout, `
8495
+ Captured output:
8496
+ `);
8497
+ const capturedOutput = capture.claimOutput();
8498
+ if (capturedOutput) {
8499
+ this.realStdoutWrite.call(this.stdout, capturedOutput + `
8500
+ `);
8501
+ }
8502
+ this.realStdoutWrite.call(this.stdout, `
8503
+ Error details:
8504
+ `);
8505
+ this.realStdoutWrite.call(this.stdout, error.message || "unknown error");
8506
+ this.realStdoutWrite.call(this.stdout, `
8507
+ `);
8508
+ this.realStdoutWrite.call(this.stdout, error.stack || error.toString());
8509
+ this.realStdoutWrite.call(this.stdout, `
8510
+ `);
8511
+ process.exit(1);
8512
+ });
8513
+ }).bind(this);
8514
+ exitHandler = (() => {
8515
+ this.destroy();
8516
+ }).bind(this);
8517
+ warningHandler = ((warning) => {
8518
+ console.warn(JSON.stringify(warning.message, null, 2));
8519
+ }).bind(this);
8093
8520
  constructor(lib, rendererPtr, stdin, stdout, width, height, config = {}) {
8094
8521
  super();
8095
8522
  this.stdin = stdin;
@@ -8112,7 +8539,7 @@ class CliRenderer extends EventEmitter6 {
8112
8539
  this.exitOnCtrlC = config.exitOnCtrlC === undefined ? true : config.exitOnCtrlC;
8113
8540
  this.resizeDebounceDelay = config.debounceDelay || 100;
8114
8541
  this.targetFps = config.targetFps || 30;
8115
- this.memorySnapshotInterval = config.memorySnapshotInterval || 5000;
8542
+ this.memorySnapshotInterval = config.memorySnapshotInterval ?? 0;
8116
8543
  this.gatherStats = config.gatherStats || false;
8117
8544
  this.maxStatSamples = config.maxStatSamples || 300;
8118
8545
  this.enableMouseMovement = config.enableMouseMovement || true;
@@ -8127,58 +8554,14 @@ class CliRenderer extends EventEmitter6 {
8127
8554
  this.startMemorySnapshotTimer();
8128
8555
  }
8129
8556
  this.stdout.write = this.interceptStdoutWrite.bind(this);
8130
- this.sigwinchHandler = () => {
8131
- const width2 = this.stdout.columns || 80;
8132
- const height2 = this.stdout.rows || 24;
8133
- this.handleResize(width2, height2);
8134
- };
8135
8557
  process.on("SIGWINCH", this.sigwinchHandler);
8136
- const handleError = (error) => {
8137
- this.stop();
8138
- this.destroy();
8139
- new Promise((resolve) => {
8140
- setTimeout(() => {
8141
- resolve(true);
8142
- }, 100);
8143
- }).then(() => {
8144
- this.realStdoutWrite.call(this.stdout, `
8145
- `.repeat(this._terminalHeight));
8146
- this.realStdoutWrite.call(this.stdout, `
8147
- === FATAL ERROR OCCURRED ===
8148
- `);
8149
- this.realStdoutWrite.call(this.stdout, `Console cache:
8150
- `);
8151
- this.realStdoutWrite.call(this.stdout, this.console.getCachedLogs());
8152
- this.realStdoutWrite.call(this.stdout, `
8153
- Captured output:
8154
- `);
8155
- const capturedOutput = capture.claimOutput();
8156
- if (capturedOutput) {
8157
- this.realStdoutWrite.call(this.stdout, capturedOutput + `
8158
- `);
8159
- }
8160
- this.realStdoutWrite.call(this.stdout, `
8161
- Error details:
8162
- `);
8163
- this.realStdoutWrite.call(this.stdout, error.message || "unknown error");
8164
- this.realStdoutWrite.call(this.stdout, `
8165
- `);
8166
- this.realStdoutWrite.call(this.stdout, error.stack || error.toString());
8167
- this.realStdoutWrite.call(this.stdout, `
8168
- `);
8169
- process.exit(1);
8170
- });
8171
- };
8172
- process.on("warning", (warning) => {
8173
- console.warn(JSON.stringify(warning.message, null, 2));
8174
- });
8175
- process.on("uncaughtException", handleError);
8176
- process.on("unhandledRejection", handleError);
8177
- process.on("exit", () => {
8178
- this.destroy();
8179
- });
8558
+ process.on("warning", this.warningHandler);
8559
+ process.on("uncaughtException", this.handleError);
8560
+ process.on("unhandledRejection", this.handleError);
8561
+ process.on("exit", this.exitHandler);
8180
8562
  this._console = new TerminalConsole(this, config.consoleOptions);
8181
8563
  this.useConsole = config.useConsole ?? true;
8564
+ this._keyHandler = new KeyHandler(this.stdin, config.useKittyKeyboard ?? false);
8182
8565
  global.requestAnimationFrame = (callback) => {
8183
8566
  const id = CliRenderer.animationFrameId++;
8184
8567
  this.animationRequest.set(id, callback);
@@ -8263,6 +8646,9 @@ Error details:
8263
8646
  get console() {
8264
8647
  return this._console;
8265
8648
  }
8649
+ get keyInput() {
8650
+ return this._keyHandler;
8651
+ }
8266
8652
  get terminalWidth() {
8267
8653
  return this._terminalWidth;
8268
8654
  }
@@ -8362,10 +8748,13 @@ Error details:
8362
8748
  const flush = ANSI.moveCursorAndClear(rendererStartLine, 1);
8363
8749
  const outputLine = this._terminalHeight - this._splitHeight;
8364
8750
  const move = ANSI.moveCursor(outputLine, 1);
8365
- const backgroundColor = this.backgroundColor.toInts();
8366
- const newlines = " ".repeat(this.width) + `
8751
+ let clear = "";
8752
+ if (space > 0) {
8753
+ const backgroundColor = this.backgroundColor.toInts();
8754
+ const newlines = " ".repeat(this.width) + `
8367
8755
  `.repeat(space);
8368
- const clear = ANSI.setRgbBackground(backgroundColor[0], backgroundColor[1], backgroundColor[2]) + newlines + ANSI.resetBackground;
8756
+ clear = ANSI.setRgbBackground(backgroundColor[0], backgroundColor[1], backgroundColor[2]) + newlines + ANSI.resetBackground;
8757
+ }
8369
8758
  this.writeOut(flush + move + output + clear);
8370
8759
  return true;
8371
8760
  }
@@ -8416,32 +8805,33 @@ Error details:
8416
8805
  }
8417
8806
  this.queryPixelResolution();
8418
8807
  }
8419
- setupInput() {
8420
- this.stdin.on("data", (data) => {
8421
- const str = data.toString();
8422
- if (this.waitingForPixelResolution && /\x1b\[4;\d+;\d+t/.test(str)) {
8423
- const match = str.match(/\x1b\[4;(\d+);(\d+)t/);
8424
- if (match) {
8425
- const resolution = {
8426
- width: parseInt(match[2]),
8427
- height: parseInt(match[1])
8428
- };
8429
- this._resolution = resolution;
8430
- this.waitingForPixelResolution = false;
8431
- return;
8432
- }
8433
- }
8434
- if (this.exitOnCtrlC && str === "\x03") {
8435
- process.nextTick(() => {
8436
- process.exit();
8437
- });
8438
- return;
8439
- }
8440
- if (this._useMouse && this.handleMouseData(data)) {
8808
+ stdinListener = ((data) => {
8809
+ const str = data.toString();
8810
+ if (this.waitingForPixelResolution && /\x1b\[4;\d+;\d+t/.test(str)) {
8811
+ const match = str.match(/\x1b\[4;(\d+);(\d+)t/);
8812
+ if (match) {
8813
+ const resolution = {
8814
+ width: parseInt(match[2]),
8815
+ height: parseInt(match[1])
8816
+ };
8817
+ this._resolution = resolution;
8818
+ this.waitingForPixelResolution = false;
8441
8819
  return;
8442
8820
  }
8443
- this.emit("key", data);
8444
- });
8821
+ }
8822
+ if (this.exitOnCtrlC && str === "\x03") {
8823
+ process.nextTick(() => {
8824
+ process.exit();
8825
+ });
8826
+ return;
8827
+ }
8828
+ if (this._useMouse && this.handleMouseData(data)) {
8829
+ return;
8830
+ }
8831
+ this.emit("key", data);
8832
+ }).bind(this);
8833
+ setupInput() {
8834
+ this.stdin.on("data", this.stdinListener);
8445
8835
  }
8446
8836
  handleMouseData(data) {
8447
8837
  const mouseEvent = this.mouseParser.parseMouseEvent(data);
@@ -8556,6 +8946,8 @@ Error details:
8556
8946
  return false;
8557
8947
  }
8558
8948
  takeMemorySnapshot() {
8949
+ if (this.isDestroyed)
8950
+ return;
8559
8951
  const memoryUsage = process.memoryUsage();
8560
8952
  this.lastMemorySnapshot = {
8561
8953
  heapUsed: memoryUsage.heapUsed,
@@ -8768,19 +9160,28 @@ Error details:
8768
9160
  }
8769
9161
  }
8770
9162
  destroy() {
8771
- this.stdin.setRawMode(false);
9163
+ this.stdin.removeListener("data", this.stdinListener);
9164
+ process.removeListener("SIGWINCH", this.sigwinchHandler);
9165
+ process.removeListener("uncaughtException", this.handleError);
9166
+ process.removeListener("unhandledRejection", this.handleError);
9167
+ process.removeListener("exit", this.exitHandler);
9168
+ process.removeListener("warning", this.warningHandler);
9169
+ capture.removeListener("write", this.captureCallback);
9170
+ if (this.memorySnapshotTimer) {
9171
+ clearInterval(this.memorySnapshotTimer);
9172
+ }
9173
+ if (this.stdin.setRawMode) {
9174
+ this.stdin.setRawMode(false);
9175
+ }
8772
9176
  if (this.isDestroyed)
8773
9177
  return;
8774
9178
  this.isDestroyed = true;
8775
9179
  this.waitingForPixelResolution = false;
8776
9180
  this.capturedRenderable = undefined;
8777
- if (this.sigwinchHandler) {
8778
- process.removeListener("SIGWINCH", this.sigwinchHandler);
8779
- this.sigwinchHandler = null;
8780
- }
9181
+ this._keyHandler.destroy();
8781
9182
  this._console.deactivate();
8782
9183
  this.disableStdoutInterception();
8783
- this.lib.destroyRenderer(this.rendererPtr, this._useAlternateScreen, this._splitHeight);
9184
+ this.lib.destroyRenderer(this.rendererPtr);
8784
9185
  }
8785
9186
  startRenderLoop() {
8786
9187
  if (!this._isRunning)
@@ -9006,5 +9407,5 @@ Error details:
9006
9407
 
9007
9408
  export { __toESM, __commonJS, __export, __require, Edge, Gutter, MeasureMode, BorderChars, getBorderFromSides, getBorderSides, borderCharsToArray, BorderCharArrays, TrackedNode, createTrackedNode, nonAlphanumericKeys, parseKeypress, KeyHandler, getKeyHandler, RGBA, hexToRgb, rgbToHex, hsvToRgb, parseColor, fonts, measureText, getCharacterPositions, coordinateToCharacterIndex, renderFontToFrameBuffer, TextAttributes, DebugOverlayCorner, createTextAttributes, visualizeRenderableTree, isStyledText, StyledText, stringToStyledText, black, red, green, yellow, blue, magenta, cyan, white, brightBlack, brightRed, brightGreen, brightYellow, brightBlue, brightMagenta, brightCyan, brightWhite, bgBlack, bgRed, bgGreen, bgYellow, bgBlue, bgMagenta, bgCyan, bgWhite, bold, italic, underline, strikethrough, dim, reverse, blink, fg, bg, t, SyntaxStyle, hastToStyledText, parseAlign, parseBoxSizing, parseDimension, parseDirection, parseDisplay, parseEdge, parseFlexDirection, parseGutter, parseJustify, parseLogLevel, parseMeasureMode, parseOverflow, parsePositionType, parseUnit, parseWrap, MouseParser, Selection, convertGlobalToLocalSelection, ASCIIFontSelectionHelper, TextBuffer, LogLevel2 as LogLevel, setRenderLibPath, resolveRenderLib, OptimizedBuffer, h, isVNode, maybeMakeRenderable, wrapWithDelegates, instantiate, delegate, LayoutEvents, RenderableEvents, isValidPercentage, isMarginType, isPaddingType, isPositionType, isPositionTypeType, isOverflowType, isDimensionType, isFlexBasisType, isSizeType, isRenderable, BaseRenderable, Renderable, RootRenderable, capture, ConsolePosition, TerminalConsole, getObjectsInViewport, MouseEvent, MouseButton, createCliRenderer, CliRenderEvents, CliRenderer };
9008
9409
 
9009
- //# debugId=5DA797F1A7D4887764756E2164756E21
9010
- //# sourceMappingURL=index-mh94hn7d.js.map
9410
+ //# debugId=912FF4522FC22ACA64756E2164756E21
9411
+ //# sourceMappingURL=index-dgjbzqw3.js.map