@opentui/core 0.0.0-20250912-12c969f4 → 0.0.0-20250915-f5db043a

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;
@@ -1907,6 +1908,237 @@ function createTrackedNode(metadata = {}, yogaConfig) {
1907
1908
 
1908
1909
  // src/lib/parse.keypress.ts
1909
1910
  import { Buffer } from "buffer";
1911
+
1912
+ // src/lib/parse.keypress-kitty.ts
1913
+ var kittyKeyMap = {
1914
+ 27: "escape",
1915
+ 9: "tab",
1916
+ 13: "enter",
1917
+ 127: "backspace",
1918
+ 57344: "escape",
1919
+ 57345: "enter",
1920
+ 57346: "tab",
1921
+ 57347: "backspace",
1922
+ 57348: "insert",
1923
+ 57349: "delete",
1924
+ 57350: "left",
1925
+ 57351: "right",
1926
+ 57352: "up",
1927
+ 57353: "down",
1928
+ 57354: "pageup",
1929
+ 57355: "pagedown",
1930
+ 57356: "home",
1931
+ 57357: "end",
1932
+ 57364: "f1",
1933
+ 57365: "f2",
1934
+ 57366: "f3",
1935
+ 57367: "f4",
1936
+ 57368: "f5",
1937
+ 57369: "f6",
1938
+ 57370: "f7",
1939
+ 57371: "f8",
1940
+ 57372: "f9",
1941
+ 57373: "f10",
1942
+ 57374: "f11",
1943
+ 57375: "f12",
1944
+ 57376: "f13",
1945
+ 57377: "f14",
1946
+ 57378: "f15",
1947
+ 57379: "f16",
1948
+ 57380: "f17",
1949
+ 57381: "f18",
1950
+ 57382: "f19",
1951
+ 57383: "f20",
1952
+ 57384: "f21",
1953
+ 57385: "f22",
1954
+ 57386: "f23",
1955
+ 57387: "f24",
1956
+ 57388: "f25",
1957
+ 57389: "f26",
1958
+ 57390: "f27",
1959
+ 57391: "f28",
1960
+ 57392: "f29",
1961
+ 57393: "f30",
1962
+ 57394: "f31",
1963
+ 57395: "f32",
1964
+ 57396: "f33",
1965
+ 57397: "f34",
1966
+ 57398: "f35",
1967
+ 57400: "kp0",
1968
+ 57401: "kp1",
1969
+ 57402: "kp2",
1970
+ 57403: "kp3",
1971
+ 57404: "kp4",
1972
+ 57405: "kp5",
1973
+ 57406: "kp6",
1974
+ 57407: "kp7",
1975
+ 57408: "kp8",
1976
+ 57409: "kp9",
1977
+ 57410: "kpdecimal",
1978
+ 57411: "kpdivide",
1979
+ 57412: "kpmultiply",
1980
+ 57413: "kpminus",
1981
+ 57414: "kpplus",
1982
+ 57415: "kpenter",
1983
+ 57416: "kpequal",
1984
+ 57428: "mediaplay",
1985
+ 57429: "mediapause",
1986
+ 57430: "mediaplaypause",
1987
+ 57431: "mediareverse",
1988
+ 57432: "mediastop",
1989
+ 57433: "mediafastforward",
1990
+ 57434: "mediarewind",
1991
+ 57435: "medianext",
1992
+ 57436: "mediaprev",
1993
+ 57437: "mediarecord",
1994
+ 57438: "volumedown",
1995
+ 57439: "volumeup",
1996
+ 57440: "mute",
1997
+ 57441: "leftshift",
1998
+ 57442: "leftctrl",
1999
+ 57443: "leftalt",
2000
+ 57444: "leftsuper",
2001
+ 57445: "lefthyper",
2002
+ 57446: "leftmeta",
2003
+ 57447: "rightshift",
2004
+ 57448: "rightctrl",
2005
+ 57449: "rightalt",
2006
+ 57450: "rightsuper",
2007
+ 57451: "righthyper",
2008
+ 57452: "rightmeta",
2009
+ 57453: "iso_level3_shift",
2010
+ 57454: "iso_level5_shift"
2011
+ };
2012
+ function fromKittyMods(mod) {
2013
+ return {
2014
+ shift: !!(mod & 1),
2015
+ alt: !!(mod & 2),
2016
+ ctrl: !!(mod & 4),
2017
+ super: !!(mod & 8),
2018
+ hyper: !!(mod & 16),
2019
+ meta: !!(mod & 32),
2020
+ capsLock: !!(mod & 64),
2021
+ numLock: !!(mod & 128)
2022
+ };
2023
+ }
2024
+ function parseKittyKeyboard(sequence) {
2025
+ const kittyRe = /^\x1b\[([^\x1b]+)u$/;
2026
+ const match = kittyRe.exec(sequence);
2027
+ if (!match)
2028
+ return null;
2029
+ const params = match[1];
2030
+ const fields = params.split(";");
2031
+ if (fields.length < 1)
2032
+ return null;
2033
+ const key = {
2034
+ name: "",
2035
+ ctrl: false,
2036
+ meta: false,
2037
+ shift: false,
2038
+ option: false,
2039
+ number: false,
2040
+ sequence,
2041
+ raw: sequence,
2042
+ eventType: "press",
2043
+ super: false,
2044
+ hyper: false,
2045
+ capsLock: false,
2046
+ numLock: false
2047
+ };
2048
+ let text = "";
2049
+ const field1 = fields[0]?.split(":") || [];
2050
+ const codepointStr = field1[0];
2051
+ if (!codepointStr)
2052
+ return null;
2053
+ const codepoint = parseInt(codepointStr, 10);
2054
+ if (isNaN(codepoint))
2055
+ return null;
2056
+ let shiftedCodepoint;
2057
+ let baseCodepoint;
2058
+ if (field1[1]) {
2059
+ const shifted = parseInt(field1[1], 10);
2060
+ if (!isNaN(shifted) && shifted > 0 && shifted <= 1114111) {
2061
+ shiftedCodepoint = shifted;
2062
+ }
2063
+ }
2064
+ if (field1[2]) {
2065
+ const base = parseInt(field1[2], 10);
2066
+ if (!isNaN(base) && base > 0 && base <= 1114111) {
2067
+ baseCodepoint = base;
2068
+ }
2069
+ }
2070
+ const knownKey = kittyKeyMap[codepoint];
2071
+ if (knownKey) {
2072
+ key.name = knownKey;
2073
+ key.code = `[${codepoint}u`;
2074
+ } else {
2075
+ if (codepoint > 0 && codepoint <= 1114111) {
2076
+ const char = String.fromCodePoint(codepoint);
2077
+ key.name = char;
2078
+ if (baseCodepoint) {
2079
+ key.baseCode = baseCodepoint;
2080
+ }
2081
+ } else {
2082
+ return null;
2083
+ }
2084
+ }
2085
+ if (fields[1]) {
2086
+ const field2 = fields[1].split(":");
2087
+ const modifierStr = field2[0];
2088
+ const eventTypeStr = field2[1];
2089
+ if (modifierStr) {
2090
+ const modifierMask = parseInt(modifierStr, 10);
2091
+ if (!isNaN(modifierMask) && modifierMask > 1) {
2092
+ const mods = fromKittyMods(modifierMask - 1);
2093
+ key.shift = mods.shift;
2094
+ key.ctrl = mods.ctrl;
2095
+ key.meta = mods.alt || mods.meta;
2096
+ key.option = mods.alt;
2097
+ key.super = mods.super;
2098
+ key.hyper = mods.hyper;
2099
+ key.capsLock = mods.capsLock;
2100
+ key.numLock = mods.numLock;
2101
+ }
2102
+ }
2103
+ if (eventTypeStr === "1" || !eventTypeStr) {
2104
+ key.eventType = "press";
2105
+ } else if (eventTypeStr === "2") {
2106
+ key.eventType = "repeat";
2107
+ } else if (eventTypeStr === "3") {
2108
+ key.eventType = "release";
2109
+ } else {
2110
+ key.eventType = "press";
2111
+ }
2112
+ }
2113
+ if (fields[2]) {
2114
+ const codepoints = fields[2].split(":");
2115
+ for (const cpStr of codepoints) {
2116
+ const cp = parseInt(cpStr, 10);
2117
+ if (!isNaN(cp) && cp > 0 && cp <= 1114111) {
2118
+ text += String.fromCodePoint(cp);
2119
+ }
2120
+ }
2121
+ }
2122
+ if (text === "") {
2123
+ const isPrintable = key.name.length > 0 && !kittyKeyMap[codepoint];
2124
+ if (isPrintable) {
2125
+ if (key.shift && shiftedCodepoint) {
2126
+ text = String.fromCodePoint(shiftedCodepoint);
2127
+ } else {
2128
+ text = key.name;
2129
+ }
2130
+ }
2131
+ }
2132
+ if (key.name === " " && key.shift && !key.ctrl && !key.meta) {
2133
+ text = " ";
2134
+ }
2135
+ if (text) {
2136
+ key.sequence = text;
2137
+ }
2138
+ return key;
2139
+ }
2140
+
2141
+ // src/lib/parse.keypress.ts
1910
2142
  var metaKeyCodeRe = /^(?:\x1b)([a-zA-Z0-9])$/;
1911
2143
  var fnKeyRe = /^(?:\x1b+)(O|N|\[|\[\[)(?:(\d+)(?:;(\d+))?([~^$])|(?:1;)?(\d+)?([a-zA-Z]))/;
1912
2144
  var keyName = {
@@ -1990,7 +2222,7 @@ var isShiftKey = (code) => {
1990
2222
  var isCtrlKey = (code) => {
1991
2223
  return ["Oa", "Ob", "Oc", "Od", "Oe", "[2^", "[3^", "[5^", "[6^", "[7^", "[8^"].includes(code);
1992
2224
  };
1993
- var parseKeypress = (s = "") => {
2225
+ var parseKeypress = (s = "", options = {}) => {
1994
2226
  let parts;
1995
2227
  if (Buffer.isBuffer(s)) {
1996
2228
  if (s[0] > 127 && s[1] === undefined) {
@@ -2012,9 +2244,16 @@ var parseKeypress = (s = "") => {
2012
2244
  option: false,
2013
2245
  number: false,
2014
2246
  sequence: s,
2015
- raw: s
2247
+ raw: s,
2248
+ eventType: "press"
2016
2249
  };
2017
2250
  key.sequence = key.sequence || s || key.name;
2251
+ if (options.useKittyKeyboard && /^\x1b\[.*u$/.test(s)) {
2252
+ const kittyResult = parseKittyKeyboard(s);
2253
+ if (kittyResult) {
2254
+ return kittyResult;
2255
+ }
2256
+ }
2018
2257
  if (s === "\r") {
2019
2258
  key.name = "return";
2020
2259
  } else if (s === `
@@ -2054,15 +2293,21 @@ var parseKeypress = (s = "") => {
2054
2293
  key.option = true;
2055
2294
  }
2056
2295
  const code = [parts[1], parts[2], parts[4], parts[6]].filter(Boolean).join("");
2057
- const modifier = (parts[3] || parts[5] || 1) - 1;
2296
+ const modifier = parseInt(parts[3] || parts[5] || "1", 10) - 1;
2058
2297
  key.ctrl = !!(modifier & 4);
2059
2298
  key.meta = !!(modifier & 10);
2060
2299
  key.shift = !!(modifier & 1);
2061
2300
  key.option = !!(modifier & 2);
2062
2301
  key.code = code;
2063
- key.name = keyName[code];
2064
- key.shift = isShiftKey(code) || key.shift;
2065
- key.ctrl = isCtrlKey(code) || key.ctrl;
2302
+ const keyNameResult = keyName[code];
2303
+ if (keyNameResult) {
2304
+ key.name = keyNameResult;
2305
+ key.shift = isShiftKey(code) || key.shift;
2306
+ key.ctrl = isCtrlKey(code) || key.ctrl;
2307
+ } else {
2308
+ key.name = "";
2309
+ key.code = undefined;
2310
+ }
2066
2311
  } else if (s === "\x1B[3~") {
2067
2312
  key.name = "delete";
2068
2313
  key.meta = false;
@@ -2086,26 +2331,43 @@ function singleton(key, factory) {
2086
2331
 
2087
2332
  // src/lib/KeyHandler.ts
2088
2333
  class KeyHandler extends EventEmitter2 {
2089
- constructor() {
2334
+ stdin;
2335
+ useKittyKeyboard;
2336
+ constructor(stdin, useKittyKeyboard = false) {
2090
2337
  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);
2338
+ this.stdin = stdin || process.stdin;
2339
+ this.useKittyKeyboard = useKittyKeyboard;
2340
+ if (this.stdin.setRawMode) {
2341
+ this.stdin.setRawMode(true);
2342
+ }
2343
+ this.stdin.resume();
2344
+ this.stdin.setEncoding("utf8");
2345
+ this.stdin.on("data", (key) => {
2346
+ const parsedKey = parseKeypress(key, { useKittyKeyboard: this.useKittyKeyboard });
2347
+ switch (parsedKey.eventType) {
2348
+ case "press":
2349
+ this.emit("keypress", parsedKey);
2350
+ break;
2351
+ case "repeat":
2352
+ this.emit("keyrepeat", parsedKey);
2353
+ break;
2354
+ case "release":
2355
+ this.emit("keyrelease", parsedKey);
2356
+ break;
2357
+ default:
2358
+ this.emit("keypress", parsedKey);
2359
+ break;
2360
+ }
2099
2361
  });
2100
2362
  }
2101
2363
  destroy() {
2102
- process.stdin.removeAllListeners("data");
2364
+ this.stdin.removeAllListeners("data");
2103
2365
  }
2104
2366
  }
2105
2367
  var keyHandler = null;
2106
- function getKeyHandler() {
2368
+ function getKeyHandler(useKittyKeyboard = false) {
2107
2369
  if (!keyHandler) {
2108
- keyHandler = singleton("KeyHandler", () => new KeyHandler);
2370
+ keyHandler = singleton("KeyHandler", () => new KeyHandler(process.stdin, useKittyKeyboard));
2109
2371
  }
2110
2372
  return keyHandler;
2111
2373
  }
@@ -4782,6 +5044,13 @@ class OptimizedBuffer {
4782
5044
  this.guard();
4783
5045
  return this.lib.bufferGetId(this.bufferPtr);
4784
5046
  }
5047
+ getRealCharBytes(addLineBreaks = false) {
5048
+ this.guard();
5049
+ const realSize = this.lib.bufferGetRealCharSize(this.bufferPtr);
5050
+ const outputBuffer = new Uint8Array(realSize);
5051
+ const bytesWritten = this.lib.bufferWriteResolvedChars(this.bufferPtr, outputBuffer, addLineBreaks);
5052
+ return outputBuffer.slice(0, bytesWritten);
5053
+ }
4785
5054
  clear(bg2 = RGBA.fromValues(0, 0, 0, 1)) {
4786
5055
  this.guard();
4787
5056
  this.lib.bufferClear(this.bufferPtr, bg2);
@@ -4887,7 +5156,7 @@ if (!existsSync(targetLibPath)) {
4887
5156
  }
4888
5157
  function getOpenTUILib(libPath) {
4889
5158
  const resolvedLibPath = libPath || targetLibPath;
4890
- return dlopen(resolvedLibPath, {
5159
+ const rawSymbols = dlopen(resolvedLibPath, {
4891
5160
  setLogCallback: {
4892
5161
  args: ["ptr"],
4893
5162
  returns: "void"
@@ -4897,7 +5166,7 @@ function getOpenTUILib(libPath) {
4897
5166
  returns: "ptr"
4898
5167
  },
4899
5168
  destroyRenderer: {
4900
- args: ["ptr", "bool", "u32"],
5169
+ args: ["ptr"],
4901
5170
  returns: "void"
4902
5171
  },
4903
5172
  setUseThread: {
@@ -4984,6 +5253,14 @@ function getOpenTUILib(libPath) {
4984
5253
  args: ["ptr", "ptr", "usize"],
4985
5254
  returns: "usize"
4986
5255
  },
5256
+ bufferGetRealCharSize: {
5257
+ args: ["ptr"],
5258
+ returns: "u32"
5259
+ },
5260
+ bufferWriteResolvedChars: {
5261
+ args: ["ptr", "ptr", "usize", "bool"],
5262
+ returns: "u32"
5263
+ },
4987
5264
  bufferDrawText: {
4988
5265
  args: ["ptr", "ptr", "u32", "u32", "u32", "ptr", "ptr", "u8"],
4989
5266
  returns: "void"
@@ -5217,6 +5494,115 @@ function getOpenTUILib(libPath) {
5217
5494
  returns: "void"
5218
5495
  }
5219
5496
  });
5497
+ if (process.env.DEBUG_FFI === "true" || process.env.TRACE_FFI === "true") {
5498
+ return {
5499
+ symbols: convertToDebugSymbols(rawSymbols.symbols)
5500
+ };
5501
+ }
5502
+ return rawSymbols;
5503
+ }
5504
+ function convertToDebugSymbols(symbols) {
5505
+ const debugSymbols = {};
5506
+ const traceSymbols = {};
5507
+ let hasTracing = false;
5508
+ Object.entries(symbols).forEach(([key, value]) => {
5509
+ debugSymbols[key] = value;
5510
+ });
5511
+ if (process.env.DEBUG_FFI === "true") {
5512
+ Object.entries(symbols).forEach(([key, value]) => {
5513
+ if (typeof value === "function") {
5514
+ debugSymbols[key] = (...args) => {
5515
+ console.log(`${key}(${args.map((arg) => String(arg)).join(", ")})`);
5516
+ const result = value(...args);
5517
+ console.log(`${key} returned:`, String(result));
5518
+ return result;
5519
+ };
5520
+ }
5521
+ });
5522
+ }
5523
+ if (process.env.TRACE_FFI === "true") {
5524
+ hasTracing = true;
5525
+ Object.entries(symbols).forEach(([key, value]) => {
5526
+ if (typeof value === "function") {
5527
+ traceSymbols[key] = [];
5528
+ const originalFunc = debugSymbols[key];
5529
+ debugSymbols[key] = (...args) => {
5530
+ const start = performance.now();
5531
+ const result = originalFunc(...args);
5532
+ const end = performance.now();
5533
+ traceSymbols[key].push(end - start);
5534
+ return result;
5535
+ };
5536
+ }
5537
+ });
5538
+ }
5539
+ if (hasTracing) {
5540
+ process.on("exit", () => {
5541
+ const allStats = [];
5542
+ for (const [key, timings] of Object.entries(traceSymbols)) {
5543
+ if (!Array.isArray(timings) || timings.length === 0) {
5544
+ continue;
5545
+ }
5546
+ const sortedTimings = [...timings].sort((a, b) => a - b);
5547
+ const count = sortedTimings.length;
5548
+ const total = sortedTimings.reduce((acc, t2) => acc + t2, 0);
5549
+ const average = total / count;
5550
+ const min = sortedTimings[0];
5551
+ const max = sortedTimings[count - 1];
5552
+ const medianIndex = Math.floor(count / 2);
5553
+ const p90Index = Math.floor(count * 0.9);
5554
+ const p99Index = Math.floor(count * 0.99);
5555
+ const median = sortedTimings[medianIndex];
5556
+ const p90 = sortedTimings[Math.min(p90Index, count - 1)];
5557
+ const p99 = sortedTimings[Math.min(p99Index, count - 1)];
5558
+ allStats.push({
5559
+ name: key,
5560
+ count,
5561
+ total,
5562
+ average,
5563
+ min,
5564
+ max,
5565
+ median,
5566
+ p90,
5567
+ p99
5568
+ });
5569
+ }
5570
+ allStats.sort((a, b) => b.total - a.total);
5571
+ console.log(`
5572
+ --- OpenTUI FFI Call Performance ---`);
5573
+ console.log("Sorted by total time spent (descending)");
5574
+ console.log("-------------------------------------------------------------------------------------------------------------------------");
5575
+ if (allStats.length === 0) {
5576
+ console.log("No trace data collected or all symbols had zero calls.");
5577
+ } else {
5578
+ const nameHeader = "Symbol";
5579
+ const callsHeader = "Calls";
5580
+ const totalHeader = "Total (ms)";
5581
+ const avgHeader = "Avg (ms)";
5582
+ const minHeader = "Min (ms)";
5583
+ const maxHeader = "Max (ms)";
5584
+ const medHeader = "Med (ms)";
5585
+ const p90Header = "P90 (ms)";
5586
+ const p99Header = "P99 (ms)";
5587
+ const nameWidth = Math.max(nameHeader.length, ...allStats.map((s) => s.name.length));
5588
+ const countWidth = Math.max(callsHeader.length, ...allStats.map((s) => String(s.count).length));
5589
+ const totalWidth = Math.max(totalHeader.length, ...allStats.map((s) => s.total.toFixed(2).length));
5590
+ const avgWidth = Math.max(avgHeader.length, ...allStats.map((s) => s.average.toFixed(2).length));
5591
+ const minWidth = Math.max(minHeader.length, ...allStats.map((s) => s.min.toFixed(2).length));
5592
+ const maxWidth = Math.max(maxHeader.length, ...allStats.map((s) => s.max.toFixed(2).length));
5593
+ const medianWidth = Math.max(medHeader.length, ...allStats.map((s) => s.median.toFixed(2).length));
5594
+ const p90Width = Math.max(p90Header.length, ...allStats.map((s) => s.p90.toFixed(2).length));
5595
+ const p99Width = Math.max(p99Header.length, ...allStats.map((s) => s.p99.toFixed(2).length));
5596
+ 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)}`);
5597
+ console.log(`${"-".repeat(nameWidth)}-+-${"-".repeat(countWidth)}-+-${"-".repeat(totalWidth)}-+-${"-".repeat(avgWidth)}-+-${"-".repeat(minWidth)}-+-${"-".repeat(maxWidth)}-+-${"-".repeat(medianWidth)}-+-${"-".repeat(p90Width)}-+-${"-".repeat(p99Width)}`);
5598
+ allStats.forEach((stat) => {
5599
+ 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)}`);
5600
+ });
5601
+ }
5602
+ console.log("-------------------------------------------------------------------------------------------------------------------------");
5603
+ });
5604
+ }
5605
+ return debugSymbols;
5220
5606
  }
5221
5607
  var LogLevel2;
5222
5608
  ((LogLevel3) => {
@@ -5283,8 +5669,8 @@ class FFIRenderLib {
5283
5669
  createRenderer(width, height, options = { testing: false }) {
5284
5670
  return this.opentui.symbols.createRenderer(width, height, options.testing);
5285
5671
  }
5286
- destroyRenderer(renderer, useAlternateScreen, splitHeight) {
5287
- this.opentui.symbols.destroyRenderer(renderer, useAlternateScreen, splitHeight);
5672
+ destroyRenderer(renderer) {
5673
+ this.opentui.symbols.destroyRenderer(renderer);
5288
5674
  }
5289
5675
  setUseThread(renderer, useThread) {
5290
5676
  this.opentui.symbols.setUseThread(renderer, useThread);
@@ -5360,6 +5746,13 @@ class FFIRenderLib {
5360
5746
  const len = typeof actualLen === "bigint" ? Number(actualLen) : actualLen;
5361
5747
  return this.decoder.decode(outBuffer.slice(0, len));
5362
5748
  }
5749
+ bufferGetRealCharSize(buffer) {
5750
+ return this.opentui.symbols.bufferGetRealCharSize(buffer);
5751
+ }
5752
+ bufferWriteResolvedChars(buffer, outputBuffer, addLineBreaks) {
5753
+ const bytesWritten = this.opentui.symbols.bufferWriteResolvedChars(buffer, outputBuffer, outputBuffer.length, addLineBreaks);
5754
+ return typeof bytesWritten === "bigint" ? Number(bytesWritten) : bytesWritten;
5755
+ }
5363
5756
  getBufferWidth(buffer) {
5364
5757
  return this.opentui.symbols.getBufferWidth(buffer);
5365
5758
  }
@@ -5990,7 +6383,6 @@ class Renderable extends BaseRenderable {
5990
6383
  frameBuffer = null;
5991
6384
  _focusable = false;
5992
6385
  _focused = false;
5993
- keyHandler = getKeyHandler();
5994
6386
  keypressHandler = null;
5995
6387
  _live = false;
5996
6388
  _liveCount = 0;
@@ -6095,7 +6487,7 @@ class Renderable extends BaseRenderable {
6095
6487
  this.handleKeyPress(key);
6096
6488
  }
6097
6489
  };
6098
- this.keyHandler.on("keypress", this.keypressHandler);
6490
+ this.ctx.keyInput.on("keypress", this.keypressHandler);
6099
6491
  this.emit("focused" /* FOCUSED */);
6100
6492
  }
6101
6493
  blur() {
@@ -6104,7 +6496,7 @@ class Renderable extends BaseRenderable {
6104
6496
  this._focused = false;
6105
6497
  this.requestRender();
6106
6498
  if (this.keypressHandler) {
6107
- this.keyHandler.off("keypress", this.keypressHandler);
6499
+ this.ctx.keyInput.off("keypress", this.keypressHandler);
6108
6500
  this.keypressHandler = null;
6109
6501
  }
6110
6502
  this.emit("blurred" /* BLURRED */);
@@ -8061,6 +8453,7 @@ class CliRenderer extends EventEmitter6 {
8061
8453
  };
8062
8454
  _console;
8063
8455
  _resolution = null;
8456
+ _keyHandler;
8064
8457
  animationRequest = new Map;
8065
8458
  resizeTimeoutId = null;
8066
8459
  resizeDebounceDelay = 100;
@@ -8085,11 +8478,57 @@ class CliRenderer extends EventEmitter6 {
8085
8478
  };
8086
8479
  _useConsole = true;
8087
8480
  mouseParser = new MouseParser;
8088
- sigwinchHandler = null;
8481
+ sigwinchHandler = (() => {
8482
+ const width = this.stdout.columns || 80;
8483
+ const height = this.stdout.rows || 24;
8484
+ this.handleResize(width, height);
8485
+ }).bind(this);
8089
8486
  _capabilities = null;
8090
8487
  _latestPointer = { x: 0, y: 0 };
8091
8488
  _currentFocusedRenderable = null;
8092
8489
  lifecyclePasses = new Set;
8490
+ handleError = ((error) => {
8491
+ this.stop();
8492
+ this.destroy();
8493
+ new Promise((resolve) => {
8494
+ setTimeout(() => {
8495
+ resolve(true);
8496
+ }, 100);
8497
+ }).then(() => {
8498
+ this.realStdoutWrite.call(this.stdout, `
8499
+ `.repeat(this._terminalHeight));
8500
+ this.realStdoutWrite.call(this.stdout, `
8501
+ === FATAL ERROR OCCURRED ===
8502
+ `);
8503
+ this.realStdoutWrite.call(this.stdout, `Console cache:
8504
+ `);
8505
+ this.realStdoutWrite.call(this.stdout, this.console.getCachedLogs());
8506
+ this.realStdoutWrite.call(this.stdout, `
8507
+ Captured output:
8508
+ `);
8509
+ const capturedOutput = capture.claimOutput();
8510
+ if (capturedOutput) {
8511
+ this.realStdoutWrite.call(this.stdout, capturedOutput + `
8512
+ `);
8513
+ }
8514
+ this.realStdoutWrite.call(this.stdout, `
8515
+ Error details:
8516
+ `);
8517
+ this.realStdoutWrite.call(this.stdout, error.message || "unknown error");
8518
+ this.realStdoutWrite.call(this.stdout, `
8519
+ `);
8520
+ this.realStdoutWrite.call(this.stdout, error.stack || error.toString());
8521
+ this.realStdoutWrite.call(this.stdout, `
8522
+ `);
8523
+ process.exit(1);
8524
+ });
8525
+ }).bind(this);
8526
+ exitHandler = (() => {
8527
+ this.destroy();
8528
+ }).bind(this);
8529
+ warningHandler = ((warning) => {
8530
+ console.warn(JSON.stringify(warning.message, null, 2));
8531
+ }).bind(this);
8093
8532
  constructor(lib, rendererPtr, stdin, stdout, width, height, config = {}) {
8094
8533
  super();
8095
8534
  this.stdin = stdin;
@@ -8112,7 +8551,7 @@ class CliRenderer extends EventEmitter6 {
8112
8551
  this.exitOnCtrlC = config.exitOnCtrlC === undefined ? true : config.exitOnCtrlC;
8113
8552
  this.resizeDebounceDelay = config.debounceDelay || 100;
8114
8553
  this.targetFps = config.targetFps || 30;
8115
- this.memorySnapshotInterval = config.memorySnapshotInterval || 5000;
8554
+ this.memorySnapshotInterval = config.memorySnapshotInterval ?? 0;
8116
8555
  this.gatherStats = config.gatherStats || false;
8117
8556
  this.maxStatSamples = config.maxStatSamples || 300;
8118
8557
  this.enableMouseMovement = config.enableMouseMovement || true;
@@ -8127,58 +8566,14 @@ class CliRenderer extends EventEmitter6 {
8127
8566
  this.startMemorySnapshotTimer();
8128
8567
  }
8129
8568
  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
8569
  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
- });
8570
+ process.on("warning", this.warningHandler);
8571
+ process.on("uncaughtException", this.handleError);
8572
+ process.on("unhandledRejection", this.handleError);
8573
+ process.on("exit", this.exitHandler);
8180
8574
  this._console = new TerminalConsole(this, config.consoleOptions);
8181
8575
  this.useConsole = config.useConsole ?? true;
8576
+ this._keyHandler = new KeyHandler(this.stdin, config.useKittyKeyboard ?? false);
8182
8577
  global.requestAnimationFrame = (callback) => {
8183
8578
  const id = CliRenderer.animationFrameId++;
8184
8579
  this.animationRequest.set(id, callback);
@@ -8263,6 +8658,9 @@ Error details:
8263
8658
  get console() {
8264
8659
  return this._console;
8265
8660
  }
8661
+ get keyInput() {
8662
+ return this._keyHandler;
8663
+ }
8266
8664
  get terminalWidth() {
8267
8665
  return this._terminalWidth;
8268
8666
  }
@@ -8362,10 +8760,13 @@ Error details:
8362
8760
  const flush = ANSI.moveCursorAndClear(rendererStartLine, 1);
8363
8761
  const outputLine = this._terminalHeight - this._splitHeight;
8364
8762
  const move = ANSI.moveCursor(outputLine, 1);
8365
- const backgroundColor = this.backgroundColor.toInts();
8366
- const newlines = " ".repeat(this.width) + `
8763
+ let clear = "";
8764
+ if (space > 0) {
8765
+ const backgroundColor = this.backgroundColor.toInts();
8766
+ const newlines = " ".repeat(this.width) + `
8367
8767
  `.repeat(space);
8368
- const clear = ANSI.setRgbBackground(backgroundColor[0], backgroundColor[1], backgroundColor[2]) + newlines + ANSI.resetBackground;
8768
+ clear = ANSI.setRgbBackground(backgroundColor[0], backgroundColor[1], backgroundColor[2]) + newlines + ANSI.resetBackground;
8769
+ }
8369
8770
  this.writeOut(flush + move + output + clear);
8370
8771
  return true;
8371
8772
  }
@@ -8416,32 +8817,33 @@ Error details:
8416
8817
  }
8417
8818
  this.queryPixelResolution();
8418
8819
  }
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)) {
8820
+ stdinListener = ((data) => {
8821
+ const str = data.toString();
8822
+ if (this.waitingForPixelResolution && /\x1b\[4;\d+;\d+t/.test(str)) {
8823
+ const match = str.match(/\x1b\[4;(\d+);(\d+)t/);
8824
+ if (match) {
8825
+ const resolution = {
8826
+ width: parseInt(match[2]),
8827
+ height: parseInt(match[1])
8828
+ };
8829
+ this._resolution = resolution;
8830
+ this.waitingForPixelResolution = false;
8441
8831
  return;
8442
8832
  }
8443
- this.emit("key", data);
8444
- });
8833
+ }
8834
+ if (this.exitOnCtrlC && str === "\x03") {
8835
+ process.nextTick(() => {
8836
+ process.exit();
8837
+ });
8838
+ return;
8839
+ }
8840
+ if (this._useMouse && this.handleMouseData(data)) {
8841
+ return;
8842
+ }
8843
+ this.emit("key", data);
8844
+ }).bind(this);
8845
+ setupInput() {
8846
+ this.stdin.on("data", this.stdinListener);
8445
8847
  }
8446
8848
  handleMouseData(data) {
8447
8849
  const mouseEvent = this.mouseParser.parseMouseEvent(data);
@@ -8556,6 +8958,8 @@ Error details:
8556
8958
  return false;
8557
8959
  }
8558
8960
  takeMemorySnapshot() {
8961
+ if (this.isDestroyed)
8962
+ return;
8559
8963
  const memoryUsage = process.memoryUsage();
8560
8964
  this.lastMemorySnapshot = {
8561
8965
  heapUsed: memoryUsage.heapUsed,
@@ -8768,19 +9172,28 @@ Error details:
8768
9172
  }
8769
9173
  }
8770
9174
  destroy() {
8771
- this.stdin.setRawMode(false);
9175
+ this.stdin.removeListener("data", this.stdinListener);
9176
+ process.removeListener("SIGWINCH", this.sigwinchHandler);
9177
+ process.removeListener("uncaughtException", this.handleError);
9178
+ process.removeListener("unhandledRejection", this.handleError);
9179
+ process.removeListener("exit", this.exitHandler);
9180
+ process.removeListener("warning", this.warningHandler);
9181
+ capture.removeListener("write", this.captureCallback);
9182
+ if (this.memorySnapshotTimer) {
9183
+ clearInterval(this.memorySnapshotTimer);
9184
+ }
9185
+ if (this.stdin.setRawMode) {
9186
+ this.stdin.setRawMode(false);
9187
+ }
8772
9188
  if (this.isDestroyed)
8773
9189
  return;
8774
9190
  this.isDestroyed = true;
8775
9191
  this.waitingForPixelResolution = false;
8776
9192
  this.capturedRenderable = undefined;
8777
- if (this.sigwinchHandler) {
8778
- process.removeListener("SIGWINCH", this.sigwinchHandler);
8779
- this.sigwinchHandler = null;
8780
- }
9193
+ this._keyHandler.destroy();
8781
9194
  this._console.deactivate();
8782
9195
  this.disableStdoutInterception();
8783
- this.lib.destroyRenderer(this.rendererPtr, this._useAlternateScreen, this._splitHeight);
9196
+ this.lib.destroyRenderer(this.rendererPtr);
8784
9197
  }
8785
9198
  startRenderLoop() {
8786
9199
  if (!this._isRunning)
@@ -9006,5 +9419,5 @@ Error details:
9006
9419
 
9007
9420
  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
9421
 
9009
- //# debugId=5DA797F1A7D4887764756E2164756E21
9010
- //# sourceMappingURL=index-mh94hn7d.js.map
9422
+ //# debugId=ACCACBFBC5B1AC8B64756E2164756E21
9423
+ //# sourceMappingURL=index-6esrcarp.js.map