@opentui/core 0.1.22 → 0.1.24

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;
@@ -26,102 +27,29 @@ var __export = (target, all) => {
26
27
  };
27
28
  var __require = import.meta.require;
28
29
 
29
- // src/lib/border.ts
30
- var BorderChars = {
31
- single: {
32
- topLeft: "\u250C",
33
- topRight: "\u2510",
34
- bottomLeft: "\u2514",
35
- bottomRight: "\u2518",
36
- horizontal: "\u2500",
37
- vertical: "\u2502",
38
- topT: "\u252C",
39
- bottomT: "\u2534",
40
- leftT: "\u251C",
41
- rightT: "\u2524",
42
- cross: "\u253C"
43
- },
44
- double: {
45
- topLeft: "\u2554",
46
- topRight: "\u2557",
47
- bottomLeft: "\u255A",
48
- bottomRight: "\u255D",
49
- horizontal: "\u2550",
50
- vertical: "\u2551",
51
- topT: "\u2566",
52
- bottomT: "\u2569",
53
- leftT: "\u2560",
54
- rightT: "\u2563",
55
- cross: "\u256C"
56
- },
57
- rounded: {
58
- topLeft: "\u256D",
59
- topRight: "\u256E",
60
- bottomLeft: "\u2570",
61
- bottomRight: "\u256F",
62
- horizontal: "\u2500",
63
- vertical: "\u2502",
64
- topT: "\u252C",
65
- bottomT: "\u2534",
66
- leftT: "\u251C",
67
- rightT: "\u2524",
68
- cross: "\u253C"
69
- },
70
- heavy: {
71
- topLeft: "\u250F",
72
- topRight: "\u2513",
73
- bottomLeft: "\u2517",
74
- bottomRight: "\u251B",
75
- horizontal: "\u2501",
76
- vertical: "\u2503",
77
- topT: "\u2533",
78
- bottomT: "\u253B",
79
- leftT: "\u2523",
80
- rightT: "\u252B",
81
- cross: "\u254B"
82
- }
83
- };
84
- function getBorderFromSides(sides) {
85
- const result = [];
86
- if (sides.top)
87
- result.push("top");
88
- if (sides.right)
89
- result.push("right");
90
- if (sides.bottom)
91
- result.push("bottom");
92
- if (sides.left)
93
- result.push("left");
94
- return result.length > 0 ? result : false;
95
- }
96
- function getBorderSides(border) {
97
- return border === true ? { top: true, right: true, bottom: true, left: true } : Array.isArray(border) ? {
98
- top: border.includes("top"),
99
- right: border.includes("right"),
100
- bottom: border.includes("bottom"),
101
- left: border.includes("left")
102
- } : { top: false, right: false, bottom: false, left: false };
103
- }
104
- function borderCharsToArray(chars) {
105
- const array = new Uint32Array(11);
106
- array[0] = chars.topLeft.codePointAt(0);
107
- array[1] = chars.topRight.codePointAt(0);
108
- array[2] = chars.bottomLeft.codePointAt(0);
109
- array[3] = chars.bottomRight.codePointAt(0);
110
- array[4] = chars.horizontal.codePointAt(0);
111
- array[5] = chars.vertical.codePointAt(0);
112
- array[6] = chars.topT.codePointAt(0);
113
- array[7] = chars.bottomT.codePointAt(0);
114
- array[8] = chars.leftT.codePointAt(0);
115
- array[9] = chars.rightT.codePointAt(0);
116
- array[10] = chars.cross.codePointAt(0);
117
- return array;
118
- }
119
- var BorderCharArrays = {
120
- single: borderCharsToArray(BorderChars.single),
121
- double: borderCharsToArray(BorderChars.double),
122
- rounded: borderCharsToArray(BorderChars.rounded),
123
- heavy: borderCharsToArray(BorderChars.heavy)
124
- };
30
+ // ../../node_modules/yoga-layout/dist/src/index.js
31
+ var exports_src = {};
32
+ __export(exports_src, {
33
+ default: () => src_default,
34
+ Wrap: () => Wrap,
35
+ Unit: () => Unit,
36
+ PositionType: () => PositionType,
37
+ Overflow: () => Overflow,
38
+ NodeType: () => NodeType,
39
+ MeasureMode: () => MeasureMode,
40
+ LogLevel: () => LogLevel,
41
+ Justify: () => Justify,
42
+ Gutter: () => Gutter,
43
+ FlexDirection: () => FlexDirection,
44
+ ExperimentalFeature: () => ExperimentalFeature,
45
+ Errata: () => Errata,
46
+ Edge: () => Edge,
47
+ Display: () => Display,
48
+ Direction: () => Direction,
49
+ Dimension: () => Dimension,
50
+ BoxSizing: () => BoxSizing,
51
+ Align: () => Align
52
+ });
125
53
 
126
54
  // ../../node_modules/yoga-layout/dist/binaries/yoga-wasm-base64-esm.js
127
55
  var loadYoga = (() => {
@@ -1737,186 +1665,336 @@ function wrapAssembly(lib) {
1737
1665
  var Yoga = wrapAssembly(await yoga_wasm_base64_esm_default());
1738
1666
  var src_default = Yoga;
1739
1667
 
1740
- // src/lib/TrackedNode.ts
1741
- import { EventEmitter } from "events";
1742
-
1743
- class TrackedNode extends EventEmitter {
1744
- static idCounter = 0;
1745
- id;
1746
- yogaNode;
1747
- metadata;
1748
- parent;
1749
- children;
1750
- _destroyed = false;
1751
- _width = "auto";
1752
- _height = "auto";
1753
- constructor(yogaNode, metadata = {}) {
1754
- super();
1755
- this.id = TrackedNode.idCounter++;
1756
- this.yogaNode = yogaNode;
1757
- this.metadata = metadata;
1758
- this.parent = null;
1759
- this.children = [];
1760
- }
1761
- parseWidth(width) {
1762
- if (this._destroyed) {
1763
- throw new Error("Node is destroyed");
1764
- }
1765
- if (typeof width === "number" || width === "auto") {
1766
- return width;
1767
- }
1768
- if (!this.parent) {
1769
- return this.yogaNode.getComputedWidth();
1770
- }
1771
- if (this.parent._destroyed) {
1772
- throw new Error("Parent node is destroyed");
1773
- }
1774
- return Math.floor(this.parent.yogaNode.getComputedWidth() * parseInt(width) / 100);
1668
+ // src/lib/border.ts
1669
+ var BorderChars = {
1670
+ single: {
1671
+ topLeft: "\u250C",
1672
+ topRight: "\u2510",
1673
+ bottomLeft: "\u2514",
1674
+ bottomRight: "\u2518",
1675
+ horizontal: "\u2500",
1676
+ vertical: "\u2502",
1677
+ topT: "\u252C",
1678
+ bottomT: "\u2534",
1679
+ leftT: "\u251C",
1680
+ rightT: "\u2524",
1681
+ cross: "\u253C"
1682
+ },
1683
+ double: {
1684
+ topLeft: "\u2554",
1685
+ topRight: "\u2557",
1686
+ bottomLeft: "\u255A",
1687
+ bottomRight: "\u255D",
1688
+ horizontal: "\u2550",
1689
+ vertical: "\u2551",
1690
+ topT: "\u2566",
1691
+ bottomT: "\u2569",
1692
+ leftT: "\u2560",
1693
+ rightT: "\u2563",
1694
+ cross: "\u256C"
1695
+ },
1696
+ rounded: {
1697
+ topLeft: "\u256D",
1698
+ topRight: "\u256E",
1699
+ bottomLeft: "\u2570",
1700
+ bottomRight: "\u256F",
1701
+ horizontal: "\u2500",
1702
+ vertical: "\u2502",
1703
+ topT: "\u252C",
1704
+ bottomT: "\u2534",
1705
+ leftT: "\u251C",
1706
+ rightT: "\u2524",
1707
+ cross: "\u253C"
1708
+ },
1709
+ heavy: {
1710
+ topLeft: "\u250F",
1711
+ topRight: "\u2513",
1712
+ bottomLeft: "\u2517",
1713
+ bottomRight: "\u251B",
1714
+ horizontal: "\u2501",
1715
+ vertical: "\u2503",
1716
+ topT: "\u2533",
1717
+ bottomT: "\u253B",
1718
+ leftT: "\u2523",
1719
+ rightT: "\u252B",
1720
+ cross: "\u254B"
1775
1721
  }
1776
- parseHeight(height) {
1777
- if (this._destroyed) {
1778
- throw new Error("Node is destroyed");
1779
- }
1780
- if (typeof height === "number" || height === "auto") {
1781
- return height;
1782
- }
1783
- if (!this.parent) {
1784
- return this.yogaNode.getComputedHeight();
1785
- }
1786
- if (this.parent._destroyed) {
1787
- throw new Error("Parent node is destroyed");
1722
+ };
1723
+ function getBorderFromSides(sides) {
1724
+ const result = [];
1725
+ if (sides.top)
1726
+ result.push("top");
1727
+ if (sides.right)
1728
+ result.push("right");
1729
+ if (sides.bottom)
1730
+ result.push("bottom");
1731
+ if (sides.left)
1732
+ result.push("left");
1733
+ return result.length > 0 ? result : false;
1734
+ }
1735
+ function getBorderSides(border) {
1736
+ return border === true ? { top: true, right: true, bottom: true, left: true } : Array.isArray(border) ? {
1737
+ top: border.includes("top"),
1738
+ right: border.includes("right"),
1739
+ bottom: border.includes("bottom"),
1740
+ left: border.includes("left")
1741
+ } : { top: false, right: false, bottom: false, left: false };
1742
+ }
1743
+ function borderCharsToArray(chars) {
1744
+ const array = new Uint32Array(11);
1745
+ array[0] = chars.topLeft.codePointAt(0);
1746
+ array[1] = chars.topRight.codePointAt(0);
1747
+ array[2] = chars.bottomLeft.codePointAt(0);
1748
+ array[3] = chars.bottomRight.codePointAt(0);
1749
+ array[4] = chars.horizontal.codePointAt(0);
1750
+ array[5] = chars.vertical.codePointAt(0);
1751
+ array[6] = chars.topT.codePointAt(0);
1752
+ array[7] = chars.bottomT.codePointAt(0);
1753
+ array[8] = chars.leftT.codePointAt(0);
1754
+ array[9] = chars.rightT.codePointAt(0);
1755
+ array[10] = chars.cross.codePointAt(0);
1756
+ return array;
1757
+ }
1758
+ var BorderCharArrays = {
1759
+ single: borderCharsToArray(BorderChars.single),
1760
+ double: borderCharsToArray(BorderChars.double),
1761
+ rounded: borderCharsToArray(BorderChars.rounded),
1762
+ heavy: borderCharsToArray(BorderChars.heavy)
1763
+ };
1764
+
1765
+ // src/lib/parse.keypress.ts
1766
+ import { Buffer } from "buffer";
1767
+
1768
+ // src/lib/parse.keypress-kitty.ts
1769
+ var kittyKeyMap = {
1770
+ 27: "escape",
1771
+ 9: "tab",
1772
+ 13: "enter",
1773
+ 127: "backspace",
1774
+ 57344: "escape",
1775
+ 57345: "enter",
1776
+ 57346: "tab",
1777
+ 57347: "backspace",
1778
+ 57348: "insert",
1779
+ 57349: "delete",
1780
+ 57350: "left",
1781
+ 57351: "right",
1782
+ 57352: "up",
1783
+ 57353: "down",
1784
+ 57354: "pageup",
1785
+ 57355: "pagedown",
1786
+ 57356: "home",
1787
+ 57357: "end",
1788
+ 57364: "f1",
1789
+ 57365: "f2",
1790
+ 57366: "f3",
1791
+ 57367: "f4",
1792
+ 57368: "f5",
1793
+ 57369: "f6",
1794
+ 57370: "f7",
1795
+ 57371: "f8",
1796
+ 57372: "f9",
1797
+ 57373: "f10",
1798
+ 57374: "f11",
1799
+ 57375: "f12",
1800
+ 57376: "f13",
1801
+ 57377: "f14",
1802
+ 57378: "f15",
1803
+ 57379: "f16",
1804
+ 57380: "f17",
1805
+ 57381: "f18",
1806
+ 57382: "f19",
1807
+ 57383: "f20",
1808
+ 57384: "f21",
1809
+ 57385: "f22",
1810
+ 57386: "f23",
1811
+ 57387: "f24",
1812
+ 57388: "f25",
1813
+ 57389: "f26",
1814
+ 57390: "f27",
1815
+ 57391: "f28",
1816
+ 57392: "f29",
1817
+ 57393: "f30",
1818
+ 57394: "f31",
1819
+ 57395: "f32",
1820
+ 57396: "f33",
1821
+ 57397: "f34",
1822
+ 57398: "f35",
1823
+ 57400: "kp0",
1824
+ 57401: "kp1",
1825
+ 57402: "kp2",
1826
+ 57403: "kp3",
1827
+ 57404: "kp4",
1828
+ 57405: "kp5",
1829
+ 57406: "kp6",
1830
+ 57407: "kp7",
1831
+ 57408: "kp8",
1832
+ 57409: "kp9",
1833
+ 57410: "kpdecimal",
1834
+ 57411: "kpdivide",
1835
+ 57412: "kpmultiply",
1836
+ 57413: "kpminus",
1837
+ 57414: "kpplus",
1838
+ 57415: "kpenter",
1839
+ 57416: "kpequal",
1840
+ 57428: "mediaplay",
1841
+ 57429: "mediapause",
1842
+ 57430: "mediaplaypause",
1843
+ 57431: "mediareverse",
1844
+ 57432: "mediastop",
1845
+ 57433: "mediafastforward",
1846
+ 57434: "mediarewind",
1847
+ 57435: "medianext",
1848
+ 57436: "mediaprev",
1849
+ 57437: "mediarecord",
1850
+ 57438: "volumedown",
1851
+ 57439: "volumeup",
1852
+ 57440: "mute",
1853
+ 57441: "leftshift",
1854
+ 57442: "leftctrl",
1855
+ 57443: "leftalt",
1856
+ 57444: "leftsuper",
1857
+ 57445: "lefthyper",
1858
+ 57446: "leftmeta",
1859
+ 57447: "rightshift",
1860
+ 57448: "rightctrl",
1861
+ 57449: "rightalt",
1862
+ 57450: "rightsuper",
1863
+ 57451: "righthyper",
1864
+ 57452: "rightmeta",
1865
+ 57453: "iso_level3_shift",
1866
+ 57454: "iso_level5_shift"
1867
+ };
1868
+ function fromKittyMods(mod) {
1869
+ return {
1870
+ shift: !!(mod & 1),
1871
+ alt: !!(mod & 2),
1872
+ ctrl: !!(mod & 4),
1873
+ super: !!(mod & 8),
1874
+ hyper: !!(mod & 16),
1875
+ meta: !!(mod & 32),
1876
+ capsLock: !!(mod & 64),
1877
+ numLock: !!(mod & 128)
1878
+ };
1879
+ }
1880
+ function parseKittyKeyboard(sequence) {
1881
+ const kittyRe = /^\x1b\[([^\x1b]+)u$/;
1882
+ const match = kittyRe.exec(sequence);
1883
+ if (!match)
1884
+ return null;
1885
+ const params = match[1];
1886
+ const fields = params.split(";");
1887
+ if (fields.length < 1)
1888
+ return null;
1889
+ const key = {
1890
+ name: "",
1891
+ ctrl: false,
1892
+ meta: false,
1893
+ shift: false,
1894
+ option: false,
1895
+ number: false,
1896
+ sequence,
1897
+ raw: sequence,
1898
+ eventType: "press",
1899
+ super: false,
1900
+ hyper: false,
1901
+ capsLock: false,
1902
+ numLock: false
1903
+ };
1904
+ let text = "";
1905
+ const field1 = fields[0]?.split(":") || [];
1906
+ const codepointStr = field1[0];
1907
+ if (!codepointStr)
1908
+ return null;
1909
+ const codepoint = parseInt(codepointStr, 10);
1910
+ if (isNaN(codepoint))
1911
+ return null;
1912
+ let shiftedCodepoint;
1913
+ let baseCodepoint;
1914
+ if (field1[1]) {
1915
+ const shifted = parseInt(field1[1], 10);
1916
+ if (!isNaN(shifted) && shifted > 0 && shifted <= 1114111) {
1917
+ shiftedCodepoint = shifted;
1788
1918
  }
1789
- return Math.floor(this.parent.yogaNode.getComputedHeight() * parseInt(height) / 100);
1790
1919
  }
1791
- setWidth(width) {
1792
- this._width = width;
1793
- const parsedWidth = this.parseWidth(width);
1794
- if (parsedWidth === "auto") {
1795
- this.yogaNode.setWidthAuto();
1796
- } else {
1797
- this.yogaNode.setWidth(parsedWidth);
1920
+ if (field1[2]) {
1921
+ const base = parseInt(field1[2], 10);
1922
+ if (!isNaN(base) && base > 0 && base <= 1114111) {
1923
+ baseCodepoint = base;
1798
1924
  }
1799
1925
  }
1800
- setHeight(height) {
1801
- this._height = height;
1802
- const parsedHeight = this.parseHeight(height);
1803
- if (parsedHeight === "auto") {
1804
- this.yogaNode.setHeightAuto();
1926
+ const knownKey = kittyKeyMap[codepoint];
1927
+ if (knownKey) {
1928
+ key.name = knownKey;
1929
+ key.code = `[${codepoint}u`;
1930
+ } else {
1931
+ if (codepoint > 0 && codepoint <= 1114111) {
1932
+ const char = String.fromCodePoint(codepoint);
1933
+ key.name = char;
1934
+ if (baseCodepoint) {
1935
+ key.baseCode = baseCodepoint;
1936
+ }
1805
1937
  } else {
1806
- this.yogaNode.setHeight(parsedHeight);
1938
+ return null;
1807
1939
  }
1808
1940
  }
1809
- addChild(childNode) {
1810
- if (childNode.parent) {
1811
- childNode.parent.removeChild(childNode);
1812
- }
1813
- childNode.parent = this;
1814
- const index = this.children.length;
1815
- this.children.push(childNode);
1816
- this.yogaNode.insertChild(childNode.yogaNode, index);
1817
- try {
1818
- childNode.yogaNode.setWidth(childNode.parseWidth(childNode._width));
1819
- childNode.yogaNode.setHeight(childNode.parseHeight(childNode._height));
1820
- } catch (e) {
1821
- console.error("Error setting width and height", e);
1941
+ if (fields[1]) {
1942
+ const field2 = fields[1].split(":");
1943
+ const modifierStr = field2[0];
1944
+ const eventTypeStr = field2[1];
1945
+ if (modifierStr) {
1946
+ const modifierMask = parseInt(modifierStr, 10);
1947
+ if (!isNaN(modifierMask) && modifierMask > 1) {
1948
+ const mods = fromKittyMods(modifierMask - 1);
1949
+ key.shift = mods.shift;
1950
+ key.ctrl = mods.ctrl;
1951
+ key.meta = mods.alt || mods.meta;
1952
+ key.option = mods.alt;
1953
+ key.super = mods.super;
1954
+ key.hyper = mods.hyper;
1955
+ key.capsLock = mods.capsLock;
1956
+ key.numLock = mods.numLock;
1957
+ }
1822
1958
  }
1823
- return index;
1824
- }
1825
- getChildIndex(childNode) {
1826
- return this.children.indexOf(childNode);
1827
- }
1828
- removeChild(childNode) {
1829
- const index = this.children.indexOf(childNode);
1830
- if (index === -1) {
1831
- return false;
1959
+ if (eventTypeStr === "1" || !eventTypeStr) {
1960
+ key.eventType = "press";
1961
+ } else if (eventTypeStr === "2") {
1962
+ key.eventType = "repeat";
1963
+ } else if (eventTypeStr === "3") {
1964
+ key.eventType = "release";
1965
+ } else {
1966
+ key.eventType = "press";
1832
1967
  }
1833
- this.children.splice(index, 1);
1834
- this.yogaNode.removeChild(childNode.yogaNode);
1835
- childNode.parent = null;
1836
- return true;
1837
1968
  }
1838
- removeChildAtIndex(index) {
1839
- if (index < 0 || index >= this.children.length) {
1840
- return null;
1841
- }
1842
- const childNode = this.children[index];
1843
- this.children.splice(index, 1);
1844
- this.yogaNode.removeChild(childNode.yogaNode);
1845
- childNode.parent = null;
1846
- return childNode;
1847
- }
1848
- moveChild(childNode, newIndex) {
1849
- const currentIndex = this.children.indexOf(childNode);
1850
- if (currentIndex === -1) {
1851
- throw new Error("Node is not a child of this parent");
1852
- }
1853
- const boundedNewIndex = Math.max(0, Math.min(newIndex, this.children.length - 1));
1854
- if (currentIndex === boundedNewIndex) {
1855
- return currentIndex;
1856
- }
1857
- this.children.splice(currentIndex, 1);
1858
- this.children.splice(boundedNewIndex, 0, childNode);
1859
- this.yogaNode.removeChild(childNode.yogaNode);
1860
- this.yogaNode.insertChild(childNode.yogaNode, boundedNewIndex);
1861
- return boundedNewIndex;
1862
- }
1863
- insertChild(childNode, index) {
1864
- if (childNode.parent) {
1865
- childNode.parent.removeChild(childNode);
1866
- }
1867
- childNode.parent = this;
1868
- const boundedIndex = Math.max(0, Math.min(index, this.children.length));
1869
- this.children.splice(boundedIndex, 0, childNode);
1870
- this.yogaNode.insertChild(childNode.yogaNode, boundedIndex);
1871
- try {
1872
- childNode.yogaNode.setWidth(childNode.parseWidth(childNode._width));
1873
- childNode.yogaNode.setHeight(childNode.parseHeight(childNode._height));
1874
- } catch (e) {
1875
- console.error("Error setting width and height", e);
1969
+ if (fields[2]) {
1970
+ const codepoints = fields[2].split(":");
1971
+ for (const cpStr of codepoints) {
1972
+ const cp = parseInt(cpStr, 10);
1973
+ if (!isNaN(cp) && cp > 0 && cp <= 1114111) {
1974
+ text += String.fromCodePoint(cp);
1975
+ }
1876
1976
  }
1877
- return boundedIndex;
1878
- }
1879
- getChildCount() {
1880
- return this.children.length;
1881
1977
  }
1882
- getChildAtIndex(index) {
1883
- if (index < 0 || index >= this.children.length) {
1884
- return null;
1978
+ if (text === "") {
1979
+ const isPrintable = key.name.length > 0 && !kittyKeyMap[codepoint];
1980
+ if (isPrintable) {
1981
+ if (key.shift && shiftedCodepoint) {
1982
+ text = String.fromCodePoint(shiftedCodepoint);
1983
+ } else {
1984
+ text = key.name;
1985
+ }
1885
1986
  }
1886
- return this.children[index];
1887
- }
1888
- setMetadata(key, value) {
1889
- this.metadata[key] = value;
1890
1987
  }
1891
- getMetadata(key) {
1892
- return this.metadata[key];
1988
+ if (key.name === " " && key.shift && !key.ctrl && !key.meta) {
1989
+ text = " ";
1893
1990
  }
1894
- removeMetadata(key) {
1895
- delete this.metadata[key];
1991
+ if (text) {
1992
+ key.sequence = text;
1896
1993
  }
1897
- hasChild(childNode) {
1898
- return this.children.includes(childNode);
1899
- }
1900
- destroy() {
1901
- if (this._destroyed) {
1902
- return;
1903
- }
1904
- if (this.parent) {
1905
- this.parent.removeChild(this);
1906
- }
1907
- try {
1908
- this.yogaNode.free();
1909
- } catch (e) {}
1910
- this._destroyed = true;
1911
- }
1912
- }
1913
- function createTrackedNode(metadata = {}, yogaConfig) {
1914
- const yogaNode = src_default.Node.create(yogaConfig);
1915
- return new TrackedNode(yogaNode, metadata);
1994
+ return key;
1916
1995
  }
1917
1996
 
1918
1997
  // src/lib/parse.keypress.ts
1919
- import { Buffer } from "buffer";
1920
1998
  var metaKeyCodeRe = /^(?:\x1b)([a-zA-Z0-9])$/;
1921
1999
  var fnKeyRe = /^(?:\x1b+)(O|N|\[|\[\[)(?:(\d+)(?:;(\d+))?([~^$])|(?:1;)?(\d+)?([a-zA-Z]))/;
1922
2000
  var keyName = {
@@ -2000,7 +2078,7 @@ var isShiftKey = (code) => {
2000
2078
  var isCtrlKey = (code) => {
2001
2079
  return ["Oa", "Ob", "Oc", "Od", "Oe", "[2^", "[3^", "[5^", "[6^", "[7^", "[8^"].includes(code);
2002
2080
  };
2003
- var parseKeypress = (s = "") => {
2081
+ var parseKeypress = (s = "", options = {}) => {
2004
2082
  let parts;
2005
2083
  if (Buffer.isBuffer(s)) {
2006
2084
  if (s[0] > 127 && s[1] === undefined) {
@@ -2022,9 +2100,16 @@ var parseKeypress = (s = "") => {
2022
2100
  option: false,
2023
2101
  number: false,
2024
2102
  sequence: s,
2025
- raw: s
2103
+ raw: s,
2104
+ eventType: "press"
2026
2105
  };
2027
2106
  key.sequence = key.sequence || s || key.name;
2107
+ if (options.useKittyKeyboard && /^\x1b\[.*u$/.test(s)) {
2108
+ const kittyResult = parseKittyKeyboard(s);
2109
+ if (kittyResult) {
2110
+ return kittyResult;
2111
+ }
2112
+ }
2028
2113
  if (s === "\r") {
2029
2114
  key.name = "return";
2030
2115
  } else if (s === `
@@ -2064,15 +2149,21 @@ var parseKeypress = (s = "") => {
2064
2149
  key.option = true;
2065
2150
  }
2066
2151
  const code = [parts[1], parts[2], parts[4], parts[6]].filter(Boolean).join("");
2067
- const modifier = (parts[3] || parts[5] || 1) - 1;
2152
+ const modifier = parseInt(parts[3] || parts[5] || "1", 10) - 1;
2068
2153
  key.ctrl = !!(modifier & 4);
2069
2154
  key.meta = !!(modifier & 10);
2070
2155
  key.shift = !!(modifier & 1);
2071
2156
  key.option = !!(modifier & 2);
2072
2157
  key.code = code;
2073
- key.name = keyName[code];
2074
- key.shift = isShiftKey(code) || key.shift;
2075
- key.ctrl = isCtrlKey(code) || key.ctrl;
2158
+ const keyNameResult = keyName[code];
2159
+ if (keyNameResult) {
2160
+ key.name = keyNameResult;
2161
+ key.shift = isShiftKey(code) || key.shift;
2162
+ key.ctrl = isCtrlKey(code) || key.ctrl;
2163
+ } else {
2164
+ key.name = "";
2165
+ key.code = undefined;
2166
+ }
2076
2167
  } else if (s === "\x1B[3~") {
2077
2168
  key.name = "delete";
2078
2169
  key.meta = false;
@@ -2082,7 +2173,7 @@ var parseKeypress = (s = "") => {
2082
2173
  };
2083
2174
 
2084
2175
  // src/lib/KeyHandler.ts
2085
- import { EventEmitter as EventEmitter2 } from "events";
2176
+ import { EventEmitter } from "events";
2086
2177
 
2087
2178
  // src/singleton.ts
2088
2179
  var singletonCacheSymbol = Symbol.for("@opentui/core/singleton");
@@ -2095,27 +2186,44 @@ function singleton(key, factory) {
2095
2186
  }
2096
2187
 
2097
2188
  // src/lib/KeyHandler.ts
2098
- class KeyHandler extends EventEmitter2 {
2099
- constructor() {
2189
+ class KeyHandler extends EventEmitter {
2190
+ stdin;
2191
+ useKittyKeyboard;
2192
+ constructor(stdin, useKittyKeyboard = false) {
2100
2193
  super();
2101
- if (process.stdin.setRawMode) {
2102
- process.stdin.setRawMode(true);
2103
- }
2104
- process.stdin.resume();
2105
- process.stdin.setEncoding("utf8");
2106
- process.stdin.on("data", (key) => {
2107
- const parsedKey = parseKeypress(key);
2108
- this.emit("keypress", parsedKey);
2194
+ this.stdin = stdin || process.stdin;
2195
+ this.useKittyKeyboard = useKittyKeyboard;
2196
+ if (this.stdin.setRawMode) {
2197
+ this.stdin.setRawMode(true);
2198
+ }
2199
+ this.stdin.resume();
2200
+ this.stdin.setEncoding("utf8");
2201
+ this.stdin.on("data", (key) => {
2202
+ const parsedKey = parseKeypress(key, { useKittyKeyboard: this.useKittyKeyboard });
2203
+ switch (parsedKey.eventType) {
2204
+ case "press":
2205
+ this.emit("keypress", parsedKey);
2206
+ break;
2207
+ case "repeat":
2208
+ this.emit("keyrepeat", parsedKey);
2209
+ break;
2210
+ case "release":
2211
+ this.emit("keyrelease", parsedKey);
2212
+ break;
2213
+ default:
2214
+ this.emit("keypress", parsedKey);
2215
+ break;
2216
+ }
2109
2217
  });
2110
2218
  }
2111
2219
  destroy() {
2112
- process.stdin.removeAllListeners("data");
2220
+ this.stdin.removeAllListeners("data");
2113
2221
  }
2114
2222
  }
2115
2223
  var keyHandler = null;
2116
- function getKeyHandler() {
2224
+ function getKeyHandler(useKittyKeyboard = false) {
2117
2225
  if (!keyHandler) {
2118
- keyHandler = singleton("KeyHandler", () => new KeyHandler);
2226
+ keyHandler = singleton("KeyHandler", () => new KeyHandler(process.stdin, useKittyKeyboard));
2119
2227
  }
2120
2228
  return keyHandler;
2121
2229
  }
@@ -3936,6 +4044,31 @@ function createTextAttributes({
3936
4044
  attributes |= TextAttributes.STRIKETHROUGH;
3937
4045
  return attributes;
3938
4046
  }
4047
+ function visualizeRenderableTree(renderable, maxDepth = 10) {
4048
+ function buildTreeLines(node, prefix = "", parentPrefix = "", isLastChild = true, depth = 0) {
4049
+ if (depth >= maxDepth) {
4050
+ return [`${prefix}${node.id} ... (max depth reached)`];
4051
+ }
4052
+ const lines = [];
4053
+ const children = node.getChildren();
4054
+ lines.push(`${prefix}${node.id}`);
4055
+ if (children.length > 0) {
4056
+ const lastChildIndex = children.length - 1;
4057
+ children.forEach((child, index) => {
4058
+ const childIsLast = index === lastChildIndex;
4059
+ const connector = childIsLast ? "\u2514\u2500\u2500 " : "\u251C\u2500\u2500 ";
4060
+ const childPrefix = parentPrefix + (isLastChild ? " " : "\u2502 ");
4061
+ const childLines = buildTreeLines(child, childPrefix + connector, childPrefix, childIsLast, depth + 1);
4062
+ lines.push(...childLines);
4063
+ });
4064
+ }
4065
+ return lines;
4066
+ }
4067
+ const treeLines = buildTreeLines(renderable);
4068
+ console.log(`Renderable Tree:
4069
+ ` + treeLines.join(`
4070
+ `));
4071
+ }
3939
4072
 
3940
4073
  // src/lib/styled-text.ts
3941
4074
  var BrandedStyledText = Symbol.for("@opentui/core/StyledText");
@@ -4713,10 +4846,16 @@ class OptimizedBuffer {
4713
4846
  _height;
4714
4847
  respectAlpha = false;
4715
4848
  _rawBuffers = null;
4849
+ _destroyed = false;
4716
4850
  get ptr() {
4717
4851
  return this.bufferPtr;
4718
4852
  }
4853
+ guard() {
4854
+ if (this._destroyed)
4855
+ throw new Error(`Buffer ${this.id} is destroyed`);
4856
+ }
4719
4857
  get buffers() {
4858
+ this.guard();
4720
4859
  if (this._rawBuffers === null) {
4721
4860
  const size = this._width * this._height;
4722
4861
  const charPtr = this.lib.bufferGetCharPtr(this.bufferPtr);
@@ -4746,9 +4885,6 @@ class OptimizedBuffer {
4746
4885
  const id = options.id && options.id.trim() !== "" ? options.id : "unnamed buffer";
4747
4886
  return lib.createOptimizedBuffer(width, height, widthMethod, respectAlpha, id);
4748
4887
  }
4749
- coordsToIndex(x, y) {
4750
- return y * this._width + x;
4751
- }
4752
4888
  get width() {
4753
4889
  return this._width;
4754
4890
  }
@@ -4756,22 +4892,35 @@ class OptimizedBuffer {
4756
4892
  return this._height;
4757
4893
  }
4758
4894
  setRespectAlpha(respectAlpha) {
4895
+ this.guard();
4759
4896
  this.lib.bufferSetRespectAlpha(this.bufferPtr, respectAlpha);
4760
4897
  this.respectAlpha = respectAlpha;
4761
4898
  }
4762
4899
  getNativeId() {
4900
+ this.guard();
4763
4901
  return this.lib.bufferGetId(this.bufferPtr);
4764
4902
  }
4903
+ getRealCharBytes(addLineBreaks = false) {
4904
+ this.guard();
4905
+ const realSize = this.lib.bufferGetRealCharSize(this.bufferPtr);
4906
+ const outputBuffer = new Uint8Array(realSize);
4907
+ const bytesWritten = this.lib.bufferWriteResolvedChars(this.bufferPtr, outputBuffer, addLineBreaks);
4908
+ return outputBuffer.slice(0, bytesWritten);
4909
+ }
4765
4910
  clear(bg2 = RGBA.fromValues(0, 0, 0, 1)) {
4911
+ this.guard();
4766
4912
  this.lib.bufferClear(this.bufferPtr, bg2);
4767
4913
  }
4768
4914
  setCell(x, y, char, fg2, bg2, attributes = 0) {
4915
+ this.guard();
4769
4916
  this.lib.bufferSetCell(this.bufferPtr, x, y, char, fg2, bg2, attributes);
4770
4917
  }
4771
4918
  setCellWithAlphaBlending(x, y, char, fg2, bg2, attributes = 0) {
4919
+ this.guard();
4772
4920
  this.lib.bufferSetCellWithAlphaBlending(this.bufferPtr, x, y, char, fg2, bg2, attributes);
4773
4921
  }
4774
4922
  drawText(text, x, y, fg2, bg2, attributes = 0, selection2) {
4923
+ this.guard();
4775
4924
  if (!selection2) {
4776
4925
  this.lib.bufferDrawText(this.bufferPtr, text, x, y, fg2, bg2, attributes);
4777
4926
  return;
@@ -4804,21 +4953,29 @@ class OptimizedBuffer {
4804
4953
  this.lib.bufferFillRect(this.bufferPtr, x, y, width, height, bg2);
4805
4954
  }
4806
4955
  drawFrameBuffer(destX, destY, frameBuffer, sourceX, sourceY, sourceWidth, sourceHeight) {
4956
+ this.guard();
4807
4957
  this.lib.drawFrameBuffer(this.bufferPtr, destX, destY, frameBuffer.ptr, sourceX, sourceY, sourceWidth, sourceHeight);
4808
4958
  }
4809
4959
  destroy() {
4960
+ if (this._destroyed)
4961
+ return;
4962
+ this._destroyed = true;
4810
4963
  this.lib.destroyOptimizedBuffer(this.bufferPtr);
4811
4964
  }
4812
4965
  drawTextBuffer(textBuffer, x, y, clipRect) {
4966
+ this.guard();
4813
4967
  this.lib.bufferDrawTextBuffer(this.bufferPtr, textBuffer.ptr, x, y, clipRect);
4814
4968
  }
4815
4969
  drawSuperSampleBuffer(x, y, pixelDataPtr, pixelDataLength, format, alignedBytesPerRow) {
4970
+ this.guard();
4816
4971
  this.lib.bufferDrawSuperSampleBuffer(this.bufferPtr, x, y, pixelDataPtr, pixelDataLength, format, alignedBytesPerRow);
4817
4972
  }
4818
4973
  drawPackedBuffer(dataPtr, dataLen, posX, posY, terminalWidthCells, terminalHeightCells) {
4974
+ this.guard();
4819
4975
  this.lib.bufferDrawPackedBuffer(this.bufferPtr, dataPtr, dataLen, posX, posY, terminalWidthCells, terminalHeightCells);
4820
4976
  }
4821
4977
  resize(width, height) {
4978
+ this.guard();
4822
4979
  if (this._width === width && this._height === height)
4823
4980
  return;
4824
4981
  this._width = width;
@@ -4827,18 +4984,22 @@ class OptimizedBuffer {
4827
4984
  this.lib.bufferResize(this.bufferPtr, width, height);
4828
4985
  }
4829
4986
  drawBox(options) {
4987
+ this.guard();
4830
4988
  const style = options.borderStyle || "single";
4831
4989
  const borderChars = options.customBorderChars ?? BorderCharArrays[style];
4832
4990
  const packedOptions = packDrawOptions(options.border, options.shouldFill ?? false, options.titleAlignment || "left");
4833
4991
  this.lib.bufferDrawBox(this.bufferPtr, options.x, options.y, options.width, options.height, borderChars, packedOptions, options.borderColor, options.backgroundColor, options.title ?? null);
4834
4992
  }
4835
4993
  pushScissorRect(x, y, width, height) {
4994
+ this.guard();
4836
4995
  this.lib.bufferPushScissorRect(this.bufferPtr, x, y, width, height);
4837
4996
  }
4838
4997
  popScissorRect() {
4998
+ this.guard();
4839
4999
  this.lib.bufferPopScissorRect(this.bufferPtr);
4840
5000
  }
4841
5001
  clearScissorRects() {
5002
+ this.guard();
4842
5003
  this.lib.bufferClearScissorRects(this.bufferPtr);
4843
5004
  }
4844
5005
  }
@@ -4851,17 +5012,17 @@ if (!existsSync(targetLibPath)) {
4851
5012
  }
4852
5013
  function getOpenTUILib(libPath) {
4853
5014
  const resolvedLibPath = libPath || targetLibPath;
4854
- return dlopen(resolvedLibPath, {
5015
+ const rawSymbols = dlopen(resolvedLibPath, {
4855
5016
  setLogCallback: {
4856
5017
  args: ["ptr"],
4857
5018
  returns: "void"
4858
5019
  },
4859
5020
  createRenderer: {
4860
- args: ["u32", "u32"],
5021
+ args: ["u32", "u32", "bool"],
4861
5022
  returns: "ptr"
4862
5023
  },
4863
5024
  destroyRenderer: {
4864
- args: ["ptr", "bool", "u32"],
5025
+ args: ["ptr"],
4865
5026
  returns: "void"
4866
5027
  },
4867
5028
  setUseThread: {
@@ -4948,6 +5109,14 @@ function getOpenTUILib(libPath) {
4948
5109
  args: ["ptr", "ptr", "usize"],
4949
5110
  returns: "usize"
4950
5111
  },
5112
+ bufferGetRealCharSize: {
5113
+ args: ["ptr"],
5114
+ returns: "u32"
5115
+ },
5116
+ bufferWriteResolvedChars: {
5117
+ args: ["ptr", "ptr", "usize", "bool"],
5118
+ returns: "u32"
5119
+ },
4951
5120
  bufferDrawText: {
4952
5121
  args: ["ptr", "ptr", "u32", "u32", "u32", "ptr", "ptr", "u8"],
4953
5122
  returns: "void"
@@ -5061,25 +5230,17 @@ function getOpenTUILib(libPath) {
5061
5230
  returns: "void"
5062
5231
  },
5063
5232
  createTextBuffer: {
5064
- args: ["u32", "u8"],
5233
+ args: ["u8"],
5065
5234
  returns: "ptr"
5066
5235
  },
5067
5236
  destroyTextBuffer: {
5068
5237
  args: ["ptr"],
5069
5238
  returns: "void"
5070
5239
  },
5071
- textBufferGetCharPtr: {
5072
- args: ["ptr"],
5073
- returns: "ptr"
5074
- },
5075
5240
  textBufferGetLength: {
5076
5241
  args: ["ptr"],
5077
5242
  returns: "u32"
5078
5243
  },
5079
- textBufferResize: {
5080
- args: ["ptr", "u32"],
5081
- returns: "void"
5082
- },
5083
5244
  textBufferReset: {
5084
5245
  args: ["ptr"],
5085
5246
  returns: "void"
@@ -5112,10 +5273,6 @@ function getOpenTUILib(libPath) {
5112
5273
  args: ["ptr", "ptr", "u32", "ptr", "ptr", "ptr"],
5113
5274
  returns: "u32"
5114
5275
  },
5115
- textBufferGetCapacity: {
5116
- args: ["ptr"],
5117
- returns: "u32"
5118
- },
5119
5276
  textBufferFinalizeLineInfo: {
5120
5277
  args: ["ptr"],
5121
5278
  returns: "void"
@@ -5126,7 +5283,7 @@ function getOpenTUILib(libPath) {
5126
5283
  },
5127
5284
  textBufferGetLineInfoDirect: {
5128
5285
  args: ["ptr", "ptr", "ptr"],
5129
- returns: "void"
5286
+ returns: "u32"
5130
5287
  },
5131
5288
  textBufferGetSelectionInfo: {
5132
5289
  args: ["ptr"],
@@ -5164,6 +5321,14 @@ function getOpenTUILib(libPath) {
5164
5321
  args: ["ptr"],
5165
5322
  returns: "usize"
5166
5323
  },
5324
+ textBufferSetWrapWidth: {
5325
+ args: ["ptr", "u32"],
5326
+ returns: "void"
5327
+ },
5328
+ textBufferSetWrapMode: {
5329
+ args: ["ptr", "u8"],
5330
+ returns: "void"
5331
+ },
5167
5332
  getArenaAllocatedBytes: {
5168
5333
  args: [],
5169
5334
  returns: "usize"
@@ -5181,6 +5346,115 @@ function getOpenTUILib(libPath) {
5181
5346
  returns: "void"
5182
5347
  }
5183
5348
  });
5349
+ if (process.env.DEBUG_FFI === "true" || process.env.TRACE_FFI === "true") {
5350
+ return {
5351
+ symbols: convertToDebugSymbols(rawSymbols.symbols)
5352
+ };
5353
+ }
5354
+ return rawSymbols;
5355
+ }
5356
+ function convertToDebugSymbols(symbols) {
5357
+ const debugSymbols = {};
5358
+ const traceSymbols = {};
5359
+ let hasTracing = false;
5360
+ Object.entries(symbols).forEach(([key, value]) => {
5361
+ debugSymbols[key] = value;
5362
+ });
5363
+ if (process.env.DEBUG_FFI === "true") {
5364
+ Object.entries(symbols).forEach(([key, value]) => {
5365
+ if (typeof value === "function") {
5366
+ debugSymbols[key] = (...args) => {
5367
+ console.log(`${key}(${args.map((arg) => String(arg)).join(", ")})`);
5368
+ const result = value(...args);
5369
+ console.log(`${key} returned:`, String(result));
5370
+ return result;
5371
+ };
5372
+ }
5373
+ });
5374
+ }
5375
+ if (process.env.TRACE_FFI === "true") {
5376
+ hasTracing = true;
5377
+ Object.entries(symbols).forEach(([key, value]) => {
5378
+ if (typeof value === "function") {
5379
+ traceSymbols[key] = [];
5380
+ const originalFunc = debugSymbols[key];
5381
+ debugSymbols[key] = (...args) => {
5382
+ const start = performance.now();
5383
+ const result = originalFunc(...args);
5384
+ const end = performance.now();
5385
+ traceSymbols[key].push(end - start);
5386
+ return result;
5387
+ };
5388
+ }
5389
+ });
5390
+ }
5391
+ if (hasTracing) {
5392
+ process.on("exit", () => {
5393
+ const allStats = [];
5394
+ for (const [key, timings] of Object.entries(traceSymbols)) {
5395
+ if (!Array.isArray(timings) || timings.length === 0) {
5396
+ continue;
5397
+ }
5398
+ const sortedTimings = [...timings].sort((a, b) => a - b);
5399
+ const count = sortedTimings.length;
5400
+ const total = sortedTimings.reduce((acc, t2) => acc + t2, 0);
5401
+ const average = total / count;
5402
+ const min = sortedTimings[0];
5403
+ const max = sortedTimings[count - 1];
5404
+ const medianIndex = Math.floor(count / 2);
5405
+ const p90Index = Math.floor(count * 0.9);
5406
+ const p99Index = Math.floor(count * 0.99);
5407
+ const median = sortedTimings[medianIndex];
5408
+ const p90 = sortedTimings[Math.min(p90Index, count - 1)];
5409
+ const p99 = sortedTimings[Math.min(p99Index, count - 1)];
5410
+ allStats.push({
5411
+ name: key,
5412
+ count,
5413
+ total,
5414
+ average,
5415
+ min,
5416
+ max,
5417
+ median,
5418
+ p90,
5419
+ p99
5420
+ });
5421
+ }
5422
+ allStats.sort((a, b) => b.total - a.total);
5423
+ console.log(`
5424
+ --- OpenTUI FFI Call Performance ---`);
5425
+ console.log("Sorted by total time spent (descending)");
5426
+ console.log("-------------------------------------------------------------------------------------------------------------------------");
5427
+ if (allStats.length === 0) {
5428
+ console.log("No trace data collected or all symbols had zero calls.");
5429
+ } else {
5430
+ const nameHeader = "Symbol";
5431
+ const callsHeader = "Calls";
5432
+ const totalHeader = "Total (ms)";
5433
+ const avgHeader = "Avg (ms)";
5434
+ const minHeader = "Min (ms)";
5435
+ const maxHeader = "Max (ms)";
5436
+ const medHeader = "Med (ms)";
5437
+ const p90Header = "P90 (ms)";
5438
+ const p99Header = "P99 (ms)";
5439
+ const nameWidth = Math.max(nameHeader.length, ...allStats.map((s) => s.name.length));
5440
+ const countWidth = Math.max(callsHeader.length, ...allStats.map((s) => String(s.count).length));
5441
+ const totalWidth = Math.max(totalHeader.length, ...allStats.map((s) => s.total.toFixed(2).length));
5442
+ const avgWidth = Math.max(avgHeader.length, ...allStats.map((s) => s.average.toFixed(2).length));
5443
+ const minWidth = Math.max(minHeader.length, ...allStats.map((s) => s.min.toFixed(2).length));
5444
+ const maxWidth = Math.max(maxHeader.length, ...allStats.map((s) => s.max.toFixed(2).length));
5445
+ const medianWidth = Math.max(medHeader.length, ...allStats.map((s) => s.median.toFixed(2).length));
5446
+ const p90Width = Math.max(p90Header.length, ...allStats.map((s) => s.p90.toFixed(2).length));
5447
+ const p99Width = Math.max(p99Header.length, ...allStats.map((s) => s.p99.toFixed(2).length));
5448
+ 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)}`);
5449
+ console.log(`${"-".repeat(nameWidth)}-+-${"-".repeat(countWidth)}-+-${"-".repeat(totalWidth)}-+-${"-".repeat(avgWidth)}-+-${"-".repeat(minWidth)}-+-${"-".repeat(maxWidth)}-+-${"-".repeat(medianWidth)}-+-${"-".repeat(p90Width)}-+-${"-".repeat(p99Width)}`);
5450
+ allStats.forEach((stat) => {
5451
+ 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)}`);
5452
+ });
5453
+ }
5454
+ console.log("-------------------------------------------------------------------------------------------------------------------------");
5455
+ });
5456
+ }
5457
+ return debugSymbols;
5184
5458
  }
5185
5459
  var LogLevel2;
5186
5460
  ((LogLevel3) => {
@@ -5244,11 +5518,11 @@ class FFIRenderLib {
5244
5518
  setLogCallback(callbackPtr) {
5245
5519
  this.opentui.symbols.setLogCallback(callbackPtr);
5246
5520
  }
5247
- createRenderer(width, height) {
5248
- return this.opentui.symbols.createRenderer(width, height);
5521
+ createRenderer(width, height, options = { testing: false }) {
5522
+ return this.opentui.symbols.createRenderer(width, height, options.testing);
5249
5523
  }
5250
- destroyRenderer(renderer, useAlternateScreen, splitHeight) {
5251
- this.opentui.symbols.destroyRenderer(renderer, useAlternateScreen, splitHeight);
5524
+ destroyRenderer(renderer) {
5525
+ this.opentui.symbols.destroyRenderer(renderer);
5252
5526
  }
5253
5527
  setUseThread(renderer, useThread) {
5254
5528
  this.opentui.symbols.setUseThread(renderer, useThread);
@@ -5324,6 +5598,13 @@ class FFIRenderLib {
5324
5598
  const len = typeof actualLen === "bigint" ? Number(actualLen) : actualLen;
5325
5599
  return this.decoder.decode(outBuffer.slice(0, len));
5326
5600
  }
5601
+ bufferGetRealCharSize(buffer) {
5602
+ return this.opentui.symbols.bufferGetRealCharSize(buffer);
5603
+ }
5604
+ bufferWriteResolvedChars(buffer, outputBuffer, addLineBreaks) {
5605
+ const bytesWritten = this.opentui.symbols.bufferWriteResolvedChars(buffer, outputBuffer, outputBuffer.length, addLineBreaks);
5606
+ return typeof bytesWritten === "bigint" ? Number(bytesWritten) : bytesWritten;
5607
+ }
5327
5608
  getBufferWidth(buffer) {
5328
5609
  return this.opentui.symbols.getBufferWidth(buffer);
5329
5610
  }
@@ -5453,30 +5734,20 @@ class FFIRenderLib {
5453
5734
  setupTerminal(renderer, useAlternateScreen) {
5454
5735
  this.opentui.symbols.setupTerminal(renderer, useAlternateScreen);
5455
5736
  }
5456
- createTextBuffer(capacity, widthMethod) {
5737
+ createTextBuffer(widthMethod) {
5457
5738
  const widthMethodCode = widthMethod === "wcwidth" ? 0 : 1;
5458
- const bufferPtr = this.opentui.symbols.createTextBuffer(capacity, widthMethodCode);
5739
+ const bufferPtr = this.opentui.symbols.createTextBuffer(widthMethodCode);
5459
5740
  if (!bufferPtr) {
5460
- throw new Error(`Failed to create TextBuffer with capacity ${capacity}`);
5741
+ throw new Error(`Failed to create TextBuffer`);
5461
5742
  }
5462
- return new TextBuffer(this, bufferPtr, capacity);
5743
+ return new TextBuffer(this, bufferPtr);
5463
5744
  }
5464
5745
  destroyTextBuffer(buffer) {
5465
5746
  this.opentui.symbols.destroyTextBuffer(buffer);
5466
5747
  }
5467
- textBufferGetCharPtr(buffer) {
5468
- const ptr2 = this.opentui.symbols.textBufferGetCharPtr(buffer);
5469
- if (!ptr2) {
5470
- throw new Error("Failed to get TextBuffer char pointer");
5471
- }
5472
- return ptr2;
5473
- }
5474
5748
  textBufferGetLength(buffer) {
5475
5749
  return this.opentui.symbols.textBufferGetLength(buffer);
5476
5750
  }
5477
- textBufferResize(buffer, newLength) {
5478
- this.opentui.symbols.textBufferResize(buffer, newLength);
5479
- }
5480
5751
  textBufferReset(buffer) {
5481
5752
  this.opentui.symbols.textBufferReset(buffer);
5482
5753
  }
@@ -5507,9 +5778,6 @@ class FFIRenderLib {
5507
5778
  const attrValue = attributes === null ? null : new Uint8Array([attributes]);
5508
5779
  return this.opentui.symbols.textBufferWriteChunk(buffer, textBytes, textBytes.length, fg2 ? fg2.buffer : null, bg2 ? bg2.buffer : null, attrValue);
5509
5780
  }
5510
- textBufferGetCapacity(buffer) {
5511
- return this.opentui.symbols.textBufferGetCapacity(buffer);
5512
- }
5513
5781
  textBufferFinalizeLineInfo(buffer) {
5514
5782
  this.opentui.symbols.textBufferFinalizeLineInfo(buffer);
5515
5783
  }
@@ -5517,7 +5785,7 @@ class FFIRenderLib {
5517
5785
  return this.opentui.symbols.textBufferGetLineCount(buffer);
5518
5786
  }
5519
5787
  textBufferGetLineInfoDirect(buffer, lineStartsPtr, lineWidthsPtr) {
5520
- this.opentui.symbols.textBufferGetLineInfoDirect(buffer, lineStartsPtr, lineWidthsPtr);
5788
+ return this.opentui.symbols.textBufferGetLineInfoDirect(buffer, lineStartsPtr, lineWidthsPtr);
5521
5789
  }
5522
5790
  textBufferGetSelection(buffer) {
5523
5791
  const packedInfo = this.textBufferGetSelectionInfo(buffer);
@@ -5582,6 +5850,13 @@ class FFIRenderLib {
5582
5850
  const result = this.opentui.symbols.textBufferGetChunkGroupCount(buffer);
5583
5851
  return typeof result === "bigint" ? Number(result) : result;
5584
5852
  }
5853
+ textBufferSetWrapWidth(buffer, width) {
5854
+ this.opentui.symbols.textBufferSetWrapWidth(buffer, width);
5855
+ }
5856
+ textBufferSetWrapMode(buffer, mode) {
5857
+ const modeValue = mode === "char" ? 0 : 1;
5858
+ this.opentui.symbols.textBufferSetWrapMode(buffer, modeValue);
5859
+ }
5585
5860
  getArenaAllocatedBytes() {
5586
5861
  const result = this.opentui.symbols.getArenaAllocatedBytes();
5587
5862
  return typeof result === "bigint" ? Number(result) : result;
@@ -5589,12 +5864,13 @@ class FFIRenderLib {
5589
5864
  textBufferGetLineInfo(buffer) {
5590
5865
  const lineCount = this.textBufferGetLineCount(buffer);
5591
5866
  if (lineCount === 0) {
5592
- return { lineStarts: [], lineWidths: [] };
5867
+ return { lineStarts: [], lineWidths: [], maxLineWidth: 0 };
5593
5868
  }
5594
5869
  const lineStarts = new Uint32Array(lineCount);
5595
5870
  const lineWidths = new Uint32Array(lineCount);
5596
- this.textBufferGetLineInfoDirect(buffer, ptr(lineStarts), ptr(lineWidths));
5871
+ const maxLineWidth = this.textBufferGetLineInfoDirect(buffer, ptr(lineStarts), ptr(lineWidths));
5597
5872
  return {
5873
+ maxLineWidth,
5598
5874
  lineStarts: Array.from(lineStarts),
5599
5875
  lineWidths: Array.from(lineWidths)
5600
5876
  };
@@ -5669,53 +5945,58 @@ class TextBuffer {
5669
5945
  lib;
5670
5946
  bufferPtr;
5671
5947
  _length = 0;
5672
- _capacity;
5673
5948
  _lineInfo;
5674
- constructor(lib, ptr2, capacity) {
5949
+ _destroyed = false;
5950
+ constructor(lib, ptr2) {
5675
5951
  this.lib = lib;
5676
5952
  this.bufferPtr = ptr2;
5677
- this._capacity = capacity;
5678
5953
  }
5679
- static create(capacity = 256, widthMethod) {
5954
+ static create(widthMethod) {
5680
5955
  const lib = resolveRenderLib();
5681
- return lib.createTextBuffer(capacity, widthMethod);
5956
+ return lib.createTextBuffer(widthMethod);
5957
+ }
5958
+ guard() {
5959
+ if (this._destroyed)
5960
+ throw new Error("TextBuffer is destroyed");
5682
5961
  }
5683
5962
  setStyledText(text) {
5963
+ this.guard();
5684
5964
  this.lib.textBufferReset(this.bufferPtr);
5685
5965
  this._length = 0;
5686
5966
  this._lineInfo = undefined;
5687
5967
  for (const chunk of text.chunks) {
5688
5968
  const textBytes = this.lib.encoder.encode(chunk.text);
5689
- const result = this.lib.textBufferWriteChunk(this.bufferPtr, textBytes, chunk.fg || null, chunk.bg || null, chunk.attributes ?? null);
5690
- if (result & 1) {
5691
- this._capacity = this.lib.textBufferGetCapacity(this.bufferPtr);
5692
- }
5969
+ this.lib.textBufferWriteChunk(this.bufferPtr, textBytes, chunk.fg || null, chunk.bg || null, chunk.attributes ?? null);
5693
5970
  }
5694
5971
  this.lib.textBufferFinalizeLineInfo(this.bufferPtr);
5695
5972
  this._length = this.lib.textBufferGetLength(this.bufferPtr);
5696
5973
  }
5697
5974
  setDefaultFg(fg2) {
5975
+ this.guard();
5698
5976
  this.lib.textBufferSetDefaultFg(this.bufferPtr, fg2);
5699
5977
  }
5700
5978
  setDefaultBg(bg2) {
5979
+ this.guard();
5701
5980
  this.lib.textBufferSetDefaultBg(this.bufferPtr, bg2);
5702
5981
  }
5703
5982
  setDefaultAttributes(attributes) {
5983
+ this.guard();
5704
5984
  this.lib.textBufferSetDefaultAttributes(this.bufferPtr, attributes);
5705
5985
  }
5706
5986
  resetDefaults() {
5987
+ this.guard();
5707
5988
  this.lib.textBufferResetDefaults(this.bufferPtr);
5708
5989
  }
5709
5990
  get length() {
5991
+ this.guard();
5710
5992
  return this._length;
5711
5993
  }
5712
- get capacity() {
5713
- return this._capacity;
5714
- }
5715
5994
  get ptr() {
5995
+ this.guard();
5716
5996
  return this.bufferPtr;
5717
5997
  }
5718
5998
  getSelectedText() {
5999
+ this.guard();
5719
6000
  if (this._length === 0)
5720
6001
  return "";
5721
6002
  const selectedBytes = this.lib.getSelectedTextBytes(this.bufferPtr, this.length * 4);
@@ -5724,6 +6005,7 @@ class TextBuffer {
5724
6005
  return this.lib.decoder.decode(selectedBytes);
5725
6006
  }
5726
6007
  getPlainText() {
6008
+ this.guard();
5727
6009
  if (this._length === 0)
5728
6010
  return "";
5729
6011
  const plainBytes = this.lib.getPlainTextBytes(this.bufferPtr, this.length * 4);
@@ -5732,72 +6014,87 @@ class TextBuffer {
5732
6014
  return this.lib.decoder.decode(plainBytes);
5733
6015
  }
5734
6016
  get lineInfo() {
6017
+ this.guard();
5735
6018
  if (!this._lineInfo) {
5736
6019
  this._lineInfo = this.lib.textBufferGetLineInfo(this.bufferPtr);
5737
6020
  }
5738
6021
  return this._lineInfo;
5739
6022
  }
5740
6023
  setSelection(start, end, bgColor, fgColor) {
6024
+ this.guard();
5741
6025
  this.lib.textBufferSetSelection(this.bufferPtr, start, end, bgColor || null, fgColor || null);
5742
6026
  }
5743
6027
  resetSelection() {
6028
+ this.guard();
5744
6029
  this.lib.textBufferResetSelection(this.bufferPtr);
5745
6030
  }
5746
6031
  setLocalSelection(anchorX, anchorY, focusX, focusY, bgColor, fgColor) {
6032
+ this.guard();
5747
6033
  return this.lib.textBufferSetLocalSelection(this.bufferPtr, anchorX, anchorY, focusX, focusY, bgColor || null, fgColor || null);
5748
6034
  }
5749
6035
  resetLocalSelection() {
6036
+ this.guard();
5750
6037
  this.lib.textBufferResetLocalSelection(this.bufferPtr);
5751
6038
  }
5752
6039
  getSelection() {
6040
+ this.guard();
5753
6041
  return this.lib.textBufferGetSelection(this.bufferPtr);
5754
6042
  }
5755
6043
  hasSelection() {
6044
+ this.guard();
5756
6045
  return this.getSelection() !== null;
5757
6046
  }
5758
6047
  insertChunkGroup(index, text, fg2, bg2, attributes) {
6048
+ this.guard();
5759
6049
  const textBytes = this.lib.encoder.encode(text);
5760
6050
  this.insertEncodedChunkGroup(index, textBytes, fg2, bg2, attributes);
5761
6051
  }
5762
6052
  insertEncodedChunkGroup(index, textBytes, fg2, bg2, attributes) {
6053
+ this.guard();
5763
6054
  this._length = this.lib.textBufferInsertChunkGroup(this.bufferPtr, index, textBytes, fg2 || null, bg2 || null, attributes ?? null);
5764
6055
  this._lineInfo = undefined;
5765
6056
  }
5766
6057
  removeChunkGroup(index) {
6058
+ this.guard();
5767
6059
  this._length = this.lib.textBufferRemoveChunkGroup(this.bufferPtr, index);
5768
6060
  this._lineInfo = undefined;
5769
6061
  }
5770
6062
  replaceChunkGroup(index, text, fg2, bg2, attributes) {
6063
+ this.guard();
5771
6064
  const textBytes = this.lib.encoder.encode(text);
5772
6065
  this.replaceEncodedChunkGroup(index, textBytes, fg2, bg2, attributes);
5773
6066
  }
5774
6067
  replaceEncodedChunkGroup(index, textBytes, fg2, bg2, attributes) {
6068
+ this.guard();
5775
6069
  this._length = this.lib.textBufferReplaceChunkGroup(this.bufferPtr, index, textBytes, fg2 || null, bg2 || null, attributes ?? null);
5776
6070
  this._lineInfo = undefined;
5777
6071
  }
5778
6072
  get chunkGroupCount() {
6073
+ this.guard();
5779
6074
  return this.lib.textBufferGetChunkGroupCount(this.bufferPtr);
5780
6075
  }
6076
+ setWrapWidth(width) {
6077
+ this.guard();
6078
+ this.lib.textBufferSetWrapWidth(this.bufferPtr, width ?? 0);
6079
+ this._lineInfo = undefined;
6080
+ }
6081
+ setWrapMode(mode) {
6082
+ this.guard();
6083
+ this.lib.textBufferSetWrapMode(this.bufferPtr, mode);
6084
+ this._lineInfo = undefined;
6085
+ }
5781
6086
  destroy() {
6087
+ if (this._destroyed)
6088
+ return;
6089
+ this._destroyed = true;
5782
6090
  this.lib.destroyTextBuffer(this.bufferPtr);
5783
6091
  }
5784
6092
  }
5785
6093
 
5786
6094
  // src/Renderable.ts
5787
- import { EventEmitter as EventEmitter3 } from "events";
5788
- var BrandedRenderable = Symbol.for("@opentui/core/Renderable");
5789
- var LayoutEvents;
5790
- ((LayoutEvents2) => {
5791
- LayoutEvents2["LAYOUT_CHANGED"] = "layout-changed";
5792
- LayoutEvents2["ADDED"] = "added";
5793
- LayoutEvents2["REMOVED"] = "removed";
5794
- LayoutEvents2["RESIZED"] = "resized";
5795
- })(LayoutEvents ||= {});
5796
- var RenderableEvents;
5797
- ((RenderableEvents2) => {
5798
- RenderableEvents2["FOCUSED"] = "focused";
5799
- RenderableEvents2["BLURRED"] = "blurred";
5800
- })(RenderableEvents ||= {});
6095
+ import { EventEmitter as EventEmitter2 } from "events";
6096
+
6097
+ // src/lib/renderable.validations.ts
5801
6098
  function validateOptions(id, options) {
5802
6099
  if (typeof options.width === "number") {
5803
6100
  if (options.width < 0) {
@@ -5869,20 +6166,43 @@ function isSizeType(value) {
5869
6166
  }
5870
6167
  return isValidPercentage(value);
5871
6168
  }
6169
+
6170
+ // src/Renderable.ts
6171
+ var BrandedRenderable = Symbol.for("@opentui/core/Renderable");
6172
+ var LayoutEvents;
6173
+ ((LayoutEvents2) => {
6174
+ LayoutEvents2["LAYOUT_CHANGED"] = "layout-changed";
6175
+ LayoutEvents2["ADDED"] = "added";
6176
+ LayoutEvents2["REMOVED"] = "removed";
6177
+ LayoutEvents2["RESIZED"] = "resized";
6178
+ })(LayoutEvents ||= {});
6179
+ var RenderableEvents;
6180
+ ((RenderableEvents2) => {
6181
+ RenderableEvents2["FOCUSED"] = "focused";
6182
+ RenderableEvents2["BLURRED"] = "blurred";
6183
+ })(RenderableEvents ||= {});
5872
6184
  function isRenderable(obj) {
5873
6185
  return !!obj?.[BrandedRenderable];
5874
6186
  }
5875
6187
 
5876
- class BaseRenderable extends EventEmitter3 {
6188
+ class BaseRenderable extends EventEmitter2 {
5877
6189
  [BrandedRenderable] = true;
5878
6190
  static renderableNumber = 1;
5879
- id;
6191
+ _id;
5880
6192
  num;
5881
6193
  _dirty = false;
6194
+ parent = null;
6195
+ _visible = true;
5882
6196
  constructor(options) {
5883
6197
  super();
5884
6198
  this.num = BaseRenderable.renderableNumber++;
5885
- this.id = options.id ?? `renderable-${this.num}`;
6199
+ this._id = options.id ?? `renderable-${this.num}`;
6200
+ }
6201
+ get id() {
6202
+ return this._id;
6203
+ }
6204
+ set id(value) {
6205
+ this._id = value;
5886
6206
  }
5887
6207
  get isDirty() {
5888
6208
  return this._dirty;
@@ -5893,6 +6213,14 @@ class BaseRenderable extends EventEmitter3 {
5893
6213
  markDirty() {
5894
6214
  this._dirty = true;
5895
6215
  }
6216
+ destroy() {}
6217
+ destroyRecursively() {}
6218
+ get visible() {
6219
+ return this._visible;
6220
+ }
6221
+ set visible(value) {
6222
+ this._visible = value;
6223
+ }
5896
6224
  }
5897
6225
 
5898
6226
  class Renderable extends BaseRenderable {
@@ -5908,13 +6236,11 @@ class Renderable extends BaseRenderable {
5908
6236
  _widthValue = 0;
5909
6237
  _heightValue = 0;
5910
6238
  _zIndex;
5911
- _visible;
5912
6239
  selectable = false;
5913
6240
  buffered;
5914
6241
  frameBuffer = null;
5915
6242
  _focusable = false;
5916
6243
  _focused = false;
5917
- keyHandler = getKeyHandler();
5918
6244
  keypressHandler = null;
5919
6245
  _live = false;
5920
6246
  _liveCount = 0;
@@ -5922,17 +6248,19 @@ class Renderable extends BaseRenderable {
5922
6248
  _mouseListener = null;
5923
6249
  _mouseListeners = {};
5924
6250
  _keyListeners = {};
5925
- layoutNode;
6251
+ yogaNode;
5926
6252
  _positionType = "relative";
5927
6253
  _overflow = "visible";
5928
6254
  _position = {};
5929
- renderableMap = new Map;
5930
- renderableArray = [];
6255
+ renderableMapById = new Map;
6256
+ _childrenInLayoutOrder = [];
6257
+ _childrenInZIndexOrder = [];
5931
6258
  needsZIndexSort = false;
5932
6259
  parent = null;
5933
6260
  childrenPrimarySortDirty = true;
5934
6261
  childrenSortedByPrimaryAxis = [];
5935
6262
  _newChildren = [];
6263
+ onLifecyclePass = null;
5936
6264
  renderBefore;
5937
6265
  renderAfter;
5938
6266
  constructor(ctx, options) {
@@ -5955,14 +6283,24 @@ class Renderable extends BaseRenderable {
5955
6283
  this.buffered = options.buffered ?? false;
5956
6284
  this._live = options.live ?? false;
5957
6285
  this._liveCount = this._live && this._visible ? 1 : 0;
5958
- this.layoutNode = createTrackedNode({ renderable: this });
5959
- this.layoutNode.yogaNode.setDisplay(this._visible ? Display.Flex : Display.None);
6286
+ this.yogaNode = src_default.Node.create();
6287
+ this.yogaNode.setDisplay(this._visible ? Display.Flex : Display.None);
5960
6288
  this.setupYogaProperties(options);
5961
6289
  this.applyEventOptions(options);
5962
6290
  if (this.buffered) {
5963
6291
  this.createFrameBuffer();
5964
6292
  }
5965
6293
  }
6294
+ get id() {
6295
+ return this._id;
6296
+ }
6297
+ set id(value) {
6298
+ if (this.parent) {
6299
+ this.parent.renderableMapById.delete(this.id);
6300
+ this.parent.renderableMapById.set(value, this);
6301
+ }
6302
+ super.id = value;
6303
+ }
5966
6304
  get focusable() {
5967
6305
  return this._focusable;
5968
6306
  }
@@ -5973,7 +6311,7 @@ class Renderable extends BaseRenderable {
5973
6311
  return this._visible;
5974
6312
  }
5975
6313
  get primaryAxis() {
5976
- const dir = this.layoutNode.yogaNode.getFlexDirection();
6314
+ const dir = this.yogaNode.getFlexDirection();
5977
6315
  return dir === 2 || dir === 3 ? "row" : "column";
5978
6316
  }
5979
6317
  set visible(value) {
@@ -5981,7 +6319,7 @@ class Renderable extends BaseRenderable {
5981
6319
  return;
5982
6320
  const wasVisible = this._visible;
5983
6321
  this._visible = value;
5984
- this.layoutNode.yogaNode.setDisplay(value ? Display.Flex : Display.None);
6322
+ this.yogaNode.setDisplay(value ? Display.Flex : Display.None);
5985
6323
  if (this._live) {
5986
6324
  if (!wasVisible && value) {
5987
6325
  this.propagateLiveCount(1);
@@ -6018,7 +6356,7 @@ class Renderable extends BaseRenderable {
6018
6356
  this.handleKeyPress(key);
6019
6357
  }
6020
6358
  };
6021
- this.keyHandler.on("keypress", this.keypressHandler);
6359
+ this.ctx.keyInput.on("keypress", this.keypressHandler);
6022
6360
  this.emit("focused" /* FOCUSED */);
6023
6361
  }
6024
6362
  blur() {
@@ -6027,7 +6365,7 @@ class Renderable extends BaseRenderable {
6027
6365
  this._focused = false;
6028
6366
  this.requestRender();
6029
6367
  if (this.keypressHandler) {
6030
- this.keyHandler.off("keypress", this.keypressHandler);
6368
+ this.ctx.keyInput.off("keypress", this.keypressHandler);
6031
6369
  this.keypressHandler = null;
6032
6370
  }
6033
6371
  this.emit("blurred" /* BLURRED */);
@@ -6055,7 +6393,7 @@ class Renderable extends BaseRenderable {
6055
6393
  this.parent?.propagateLiveCount(delta);
6056
6394
  }
6057
6395
  findDescendantById(id) {
6058
- for (const child of this.renderableArray) {
6396
+ for (const child of this._childrenInLayoutOrder) {
6059
6397
  if (child.id === id)
6060
6398
  return child;
6061
6399
  const found = child.findDescendantById(id);
@@ -6146,7 +6484,7 @@ class Renderable extends BaseRenderable {
6146
6484
  set width(value) {
6147
6485
  if (isDimensionType(value)) {
6148
6486
  this._width = value;
6149
- this.layoutNode.setWidth(value);
6487
+ this.yogaNode.setWidth(value);
6150
6488
  this.requestRender();
6151
6489
  }
6152
6490
  }
@@ -6156,7 +6494,7 @@ class Renderable extends BaseRenderable {
6156
6494
  set height(value) {
6157
6495
  if (isDimensionType(value)) {
6158
6496
  this._height = value;
6159
- this.layoutNode.setHeight(value);
6497
+ this.yogaNode.setHeight(value);
6160
6498
  this.requestRender();
6161
6499
  }
6162
6500
  }
@@ -6174,17 +6512,17 @@ class Renderable extends BaseRenderable {
6174
6512
  }
6175
6513
  ensureZIndexSorted() {
6176
6514
  if (this.needsZIndexSort) {
6177
- this.renderableArray.sort((a, b) => a.zIndex > b.zIndex ? 1 : a.zIndex < b.zIndex ? -1 : 0);
6515
+ this._childrenInZIndexOrder.sort((a, b) => a.zIndex > b.zIndex ? 1 : a.zIndex < b.zIndex ? -1 : 0);
6178
6516
  this.needsZIndexSort = false;
6179
6517
  }
6180
6518
  }
6181
6519
  getChildrenSortedByPrimaryAxis() {
6182
- if (!this.childrenPrimarySortDirty && this.childrenSortedByPrimaryAxis.length === this.renderableArray.length) {
6520
+ if (!this.childrenPrimarySortDirty && this.childrenSortedByPrimaryAxis.length === this._childrenInLayoutOrder.length) {
6183
6521
  return this.childrenSortedByPrimaryAxis;
6184
6522
  }
6185
- const dir = this.layoutNode.yogaNode.getFlexDirection();
6523
+ const dir = this.yogaNode.getFlexDirection();
6186
6524
  const axis = dir === 2 || dir === 3 ? "x" : "y";
6187
- const sorted = [...this.renderableArray];
6525
+ const sorted = [...this._childrenInLayoutOrder];
6188
6526
  sorted.sort((a, b) => {
6189
6527
  const va = axis === "y" ? a.y : a.x;
6190
6528
  const vb = axis === "y" ? b.y : b.x;
@@ -6195,7 +6533,7 @@ class Renderable extends BaseRenderable {
6195
6533
  return this.childrenSortedByPrimaryAxis;
6196
6534
  }
6197
6535
  setupYogaProperties(options) {
6198
- const node = this.layoutNode.yogaNode;
6536
+ const node = this.yogaNode;
6199
6537
  if (isFlexBasisType(options.flexBasis)) {
6200
6538
  node.setFlexBasis(options.flexBasis);
6201
6539
  }
@@ -6233,11 +6571,11 @@ class Renderable extends BaseRenderable {
6233
6571
  }
6234
6572
  if (isDimensionType(options.width)) {
6235
6573
  this._width = options.width;
6236
- this.layoutNode.setWidth(options.width);
6574
+ this.yogaNode.setWidth(options.width);
6237
6575
  }
6238
6576
  if (isDimensionType(options.height)) {
6239
6577
  this._height = options.height;
6240
- this.layoutNode.setHeight(options.height);
6578
+ this.yogaNode.setHeight(options.height);
6241
6579
  }
6242
6580
  this._positionType = options.position === "absolute" ? "absolute" : "relative";
6243
6581
  if (this._positionType !== "relative") {
@@ -6266,7 +6604,7 @@ class Renderable extends BaseRenderable {
6266
6604
  this.setupMarginAndPadding(options);
6267
6605
  }
6268
6606
  setupMarginAndPadding(options) {
6269
- const node = this.layoutNode.yogaNode;
6607
+ const node = this.yogaNode;
6270
6608
  if (isMarginType(options.margin)) {
6271
6609
  node.setMargin(Edge.Top, options.margin);
6272
6610
  node.setMargin(Edge.Right, options.margin);
@@ -6308,7 +6646,7 @@ class Renderable extends BaseRenderable {
6308
6646
  if (!isPositionTypeType(positionType) || this._positionType === positionType)
6309
6647
  return;
6310
6648
  this._positionType = positionType;
6311
- this.layoutNode.yogaNode.setPositionType(parsePositionType(positionType));
6649
+ this.yogaNode.setPositionType(parsePositionType(positionType));
6312
6650
  this.requestRender();
6313
6651
  }
6314
6652
  get overflow() {
@@ -6318,7 +6656,7 @@ class Renderable extends BaseRenderable {
6318
6656
  if (!isOverflowType(overflow) || this._overflow === overflow)
6319
6657
  return;
6320
6658
  this._overflow = overflow;
6321
- this.layoutNode.yogaNode.setOverflow(parseOverflow(overflow));
6659
+ this.yogaNode.setOverflow(parseOverflow(overflow));
6322
6660
  this.requestRender();
6323
6661
  }
6324
6662
  setPosition(position) {
@@ -6326,7 +6664,7 @@ class Renderable extends BaseRenderable {
6326
6664
  this.updateYogaPosition(position);
6327
6665
  }
6328
6666
  updateYogaPosition(position) {
6329
- const node = this.layoutNode.yogaNode;
6667
+ const node = this.yogaNode;
6330
6668
  const { top, right, bottom, left } = position;
6331
6669
  if (isPositionType(top)) {
6332
6670
  if (top === "auto") {
@@ -6359,66 +6697,66 @@ class Renderable extends BaseRenderable {
6359
6697
  this.requestRender();
6360
6698
  }
6361
6699
  set flexGrow(grow) {
6362
- this.layoutNode.yogaNode.setFlexGrow(grow);
6700
+ this.yogaNode.setFlexGrow(grow);
6363
6701
  this.requestRender();
6364
6702
  }
6365
6703
  set flexShrink(shrink) {
6366
- this.layoutNode.yogaNode.setFlexShrink(shrink);
6704
+ this.yogaNode.setFlexShrink(shrink);
6367
6705
  this.requestRender();
6368
6706
  }
6369
6707
  set flexDirection(direction) {
6370
- this.layoutNode.yogaNode.setFlexDirection(parseFlexDirection(direction));
6708
+ this.yogaNode.setFlexDirection(parseFlexDirection(direction));
6371
6709
  this.requestRender();
6372
6710
  }
6373
6711
  set flexWrap(wrap) {
6374
- this.layoutNode.yogaNode.setFlexWrap(parseWrap(wrap));
6712
+ this.yogaNode.setFlexWrap(parseWrap(wrap));
6375
6713
  this.requestRender();
6376
6714
  }
6377
6715
  set alignItems(alignItems) {
6378
- this.layoutNode.yogaNode.setAlignItems(parseAlign(alignItems));
6716
+ this.yogaNode.setAlignItems(parseAlign(alignItems));
6379
6717
  this.requestRender();
6380
6718
  }
6381
6719
  set justifyContent(justifyContent) {
6382
- this.layoutNode.yogaNode.setJustifyContent(parseJustify(justifyContent));
6720
+ this.yogaNode.setJustifyContent(parseJustify(justifyContent));
6383
6721
  this.requestRender();
6384
6722
  }
6385
6723
  set alignSelf(alignSelf) {
6386
- this.layoutNode.yogaNode.setAlignSelf(parseAlign(alignSelf));
6724
+ this.yogaNode.setAlignSelf(parseAlign(alignSelf));
6387
6725
  this.requestRender();
6388
6726
  }
6389
6727
  set flexBasis(basis) {
6390
6728
  if (isFlexBasisType(basis)) {
6391
- this.layoutNode.yogaNode.setFlexBasis(basis);
6729
+ this.yogaNode.setFlexBasis(basis);
6392
6730
  this.requestRender();
6393
6731
  }
6394
6732
  }
6395
6733
  set minWidth(minWidth) {
6396
6734
  if (isSizeType(minWidth)) {
6397
- this.layoutNode.yogaNode.setMinWidth(minWidth);
6735
+ this.yogaNode.setMinWidth(minWidth);
6398
6736
  this.requestRender();
6399
6737
  }
6400
6738
  }
6401
6739
  set maxWidth(maxWidth) {
6402
6740
  if (isSizeType(maxWidth)) {
6403
- this.layoutNode.yogaNode.setMaxWidth(maxWidth);
6741
+ this.yogaNode.setMaxWidth(maxWidth);
6404
6742
  this.requestRender();
6405
6743
  }
6406
6744
  }
6407
6745
  set minHeight(minHeight) {
6408
6746
  if (isSizeType(minHeight)) {
6409
- this.layoutNode.yogaNode.setMinHeight(minHeight);
6747
+ this.yogaNode.setMinHeight(minHeight);
6410
6748
  this.requestRender();
6411
6749
  }
6412
6750
  }
6413
6751
  set maxHeight(maxHeight) {
6414
6752
  if (isSizeType(maxHeight)) {
6415
- this.layoutNode.yogaNode.setMaxHeight(maxHeight);
6753
+ this.yogaNode.setMaxHeight(maxHeight);
6416
6754
  this.requestRender();
6417
6755
  }
6418
6756
  }
6419
6757
  set margin(margin) {
6420
6758
  if (isMarginType(margin)) {
6421
- const node = this.layoutNode.yogaNode;
6759
+ const node = this.yogaNode;
6422
6760
  node.setMargin(Edge.Top, margin);
6423
6761
  node.setMargin(Edge.Right, margin);
6424
6762
  node.setMargin(Edge.Bottom, margin);
@@ -6428,31 +6766,31 @@ class Renderable extends BaseRenderable {
6428
6766
  }
6429
6767
  set marginTop(margin) {
6430
6768
  if (isMarginType(margin)) {
6431
- this.layoutNode.yogaNode.setMargin(Edge.Top, margin);
6769
+ this.yogaNode.setMargin(Edge.Top, margin);
6432
6770
  this.requestRender();
6433
6771
  }
6434
6772
  }
6435
6773
  set marginRight(margin) {
6436
6774
  if (isMarginType(margin)) {
6437
- this.layoutNode.yogaNode.setMargin(Edge.Right, margin);
6775
+ this.yogaNode.setMargin(Edge.Right, margin);
6438
6776
  this.requestRender();
6439
6777
  }
6440
6778
  }
6441
6779
  set marginBottom(margin) {
6442
6780
  if (isMarginType(margin)) {
6443
- this.layoutNode.yogaNode.setMargin(Edge.Bottom, margin);
6781
+ this.yogaNode.setMargin(Edge.Bottom, margin);
6444
6782
  this.requestRender();
6445
6783
  }
6446
6784
  }
6447
6785
  set marginLeft(margin) {
6448
6786
  if (isMarginType(margin)) {
6449
- this.layoutNode.yogaNode.setMargin(Edge.Left, margin);
6787
+ this.yogaNode.setMargin(Edge.Left, margin);
6450
6788
  this.requestRender();
6451
6789
  }
6452
6790
  }
6453
6791
  set padding(padding) {
6454
6792
  if (isPaddingType(padding)) {
6455
- const node = this.layoutNode.yogaNode;
6793
+ const node = this.yogaNode;
6456
6794
  node.setPadding(Edge.Top, padding);
6457
6795
  node.setPadding(Edge.Right, padding);
6458
6796
  node.setPadding(Edge.Bottom, padding);
@@ -6462,33 +6800,33 @@ class Renderable extends BaseRenderable {
6462
6800
  }
6463
6801
  set paddingTop(padding) {
6464
6802
  if (isPaddingType(padding)) {
6465
- this.layoutNode.yogaNode.setPadding(Edge.Top, padding);
6803
+ this.yogaNode.setPadding(Edge.Top, padding);
6466
6804
  this.requestRender();
6467
6805
  }
6468
6806
  }
6469
6807
  set paddingRight(padding) {
6470
6808
  if (isPaddingType(padding)) {
6471
- this.layoutNode.yogaNode.setPadding(Edge.Right, padding);
6809
+ this.yogaNode.setPadding(Edge.Right, padding);
6472
6810
  this.requestRender();
6473
6811
  }
6474
6812
  }
6475
6813
  set paddingBottom(padding) {
6476
6814
  if (isPaddingType(padding)) {
6477
- this.layoutNode.yogaNode.setPadding(Edge.Bottom, padding);
6815
+ this.yogaNode.setPadding(Edge.Bottom, padding);
6478
6816
  this.requestRender();
6479
6817
  }
6480
6818
  }
6481
6819
  set paddingLeft(padding) {
6482
6820
  if (isPaddingType(padding)) {
6483
- this.layoutNode.yogaNode.setPadding(Edge.Left, padding);
6821
+ this.yogaNode.setPadding(Edge.Left, padding);
6484
6822
  this.requestRender();
6485
6823
  }
6486
6824
  }
6487
6825
  getLayoutNode() {
6488
- return this.layoutNode;
6826
+ return this.yogaNode;
6489
6827
  }
6490
6828
  updateFromLayout() {
6491
- const layout = this.layoutNode.yogaNode.getComputedLayout();
6829
+ const layout = this.yogaNode.getComputedLayout();
6492
6830
  const oldX = this._x;
6493
6831
  const oldY = this._y;
6494
6832
  this._x = layout.left;
@@ -6549,6 +6887,7 @@ class Renderable extends BaseRenderable {
6549
6887
  }
6550
6888
  obj.parent = this;
6551
6889
  }
6890
+ _forceLayoutUpdateFor = null;
6552
6891
  add(obj, index) {
6553
6892
  if (!obj) {
6554
6893
  return -1;
@@ -6563,7 +6902,7 @@ class Renderable extends BaseRenderable {
6563
6902
  }
6564
6903
  return -1;
6565
6904
  }
6566
- if (this.renderableMap.has(renderable.id)) {
6905
+ if (this.renderableMapById.has(renderable.id)) {
6567
6906
  console.warn(`A renderable with id ${renderable.id} already exists in ${this.id}, removing it`);
6568
6907
  this.remove(renderable.id);
6569
6908
  }
@@ -6571,15 +6910,22 @@ class Renderable extends BaseRenderable {
6571
6910
  const childLayoutNode = renderable.getLayoutNode();
6572
6911
  let insertedIndex;
6573
6912
  if (index !== undefined) {
6574
- this.renderableArray.splice(index, 0, renderable);
6575
- insertedIndex = this.layoutNode.insertChild(childLayoutNode, index);
6913
+ insertedIndex = Math.max(0, Math.min(index, this._childrenInLayoutOrder.length));
6914
+ this._childrenInLayoutOrder.splice(index, 0, renderable);
6915
+ this._forceLayoutUpdateFor = this._childrenInLayoutOrder.slice(index);
6916
+ this.yogaNode.insertChild(childLayoutNode, insertedIndex);
6576
6917
  } else {
6577
- this.renderableArray.push(renderable);
6578
- insertedIndex = this.layoutNode.addChild(childLayoutNode);
6918
+ insertedIndex = this._childrenInLayoutOrder.length;
6919
+ this._childrenInLayoutOrder.push(renderable);
6920
+ this.yogaNode.insertChild(childLayoutNode, insertedIndex);
6579
6921
  }
6580
6922
  this.needsZIndexSort = true;
6581
6923
  this.childrenPrimarySortDirty = true;
6582
- this.renderableMap.set(renderable.id, renderable);
6924
+ this.renderableMapById.set(renderable.id, renderable);
6925
+ this._childrenInZIndexOrder.push(renderable);
6926
+ if (typeof renderable.onLifecyclePass === "function") {
6927
+ this._ctx.registerLifecyclePass(renderable);
6928
+ }
6583
6929
  this._newChildren.push(renderable);
6584
6930
  if (renderable._liveCount > 0) {
6585
6931
  this.propagateLiveCount(renderable._liveCount);
@@ -6588,6 +6934,9 @@ class Renderable extends BaseRenderable {
6588
6934
  return insertedIndex;
6589
6935
  }
6590
6936
  insertBefore(obj, anchor) {
6937
+ if (!anchor) {
6938
+ return this.add(obj);
6939
+ }
6591
6940
  if (!obj) {
6592
6941
  return -1;
6593
6942
  }
@@ -6595,60 +6944,91 @@ class Renderable extends BaseRenderable {
6595
6944
  if (!renderable) {
6596
6945
  return -1;
6597
6946
  }
6598
- if (!anchor) {
6599
- return this.add(renderable);
6947
+ if (renderable.isDestroyed) {
6948
+ if (true) {
6949
+ console.warn(`Renderable with id ${renderable.id} was already destroyed, skipping insertBefore`);
6950
+ }
6951
+ return -1;
6600
6952
  }
6601
6953
  if (!isRenderable(anchor)) {
6602
6954
  throw new Error("Anchor must be a Renderable");
6603
6955
  }
6604
- if (!this.renderableMap.has(anchor.id)) {
6605
- throw new Error("Anchor does not exist");
6956
+ if (anchor.isDestroyed) {
6957
+ if (true) {
6958
+ console.warn(`Anchor with id ${anchor.id} was already destroyed, skipping insertBefore`);
6959
+ }
6960
+ return -1;
6606
6961
  }
6607
- const anchorIndex = this.renderableArray.indexOf(anchor);
6608
- if (anchorIndex === -1) {
6962
+ if (!this.renderableMapById.has(anchor.id)) {
6609
6963
  throw new Error("Anchor does not exist");
6610
6964
  }
6611
- return this.add(renderable, anchorIndex);
6965
+ if (renderable.parent === this) {
6966
+ this.yogaNode.removeChild(renderable.getLayoutNode());
6967
+ this._childrenInLayoutOrder.splice(this._childrenInLayoutOrder.indexOf(renderable), 1);
6968
+ } else if (renderable.parent) {
6969
+ this.replaceParent(renderable);
6970
+ this.needsZIndexSort = true;
6971
+ this.renderableMapById.set(renderable.id, renderable);
6972
+ if (typeof renderable.onLifecyclePass === "function") {
6973
+ this._ctx.registerLifecyclePass(renderable);
6974
+ }
6975
+ if (renderable._liveCount > 0) {
6976
+ this.propagateLiveCount(renderable._liveCount);
6977
+ }
6978
+ }
6979
+ this._newChildren.push(renderable);
6980
+ this.childrenPrimarySortDirty = true;
6981
+ const anchorIndex = this._childrenInLayoutOrder.indexOf(anchor);
6982
+ const insertedIndex = Math.max(0, Math.min(anchorIndex, this._childrenInLayoutOrder.length));
6983
+ this._forceLayoutUpdateFor = this._childrenInLayoutOrder.slice(insertedIndex);
6984
+ this._childrenInLayoutOrder.splice(insertedIndex, 0, renderable);
6985
+ this.yogaNode.insertChild(renderable.getLayoutNode(), insertedIndex);
6986
+ return insertedIndex;
6612
6987
  }
6613
6988
  getRenderable(id) {
6614
- return this.renderableMap.get(id);
6989
+ return this.renderableMapById.get(id);
6615
6990
  }
6616
6991
  remove(id) {
6617
6992
  if (!id) {
6618
6993
  return;
6619
6994
  }
6620
- if (this.renderableMap.has(id)) {
6621
- const obj = this.renderableMap.get(id);
6995
+ if (this.renderableMapById.has(id)) {
6996
+ const obj = this.renderableMapById.get(id);
6622
6997
  if (obj) {
6623
6998
  if (obj._liveCount > 0) {
6624
6999
  this.propagateLiveCount(-obj._liveCount);
6625
7000
  }
6626
7001
  const childLayoutNode = obj.getLayoutNode();
6627
- this.layoutNode.removeChild(childLayoutNode);
7002
+ this.yogaNode.removeChild(childLayoutNode);
6628
7003
  this.requestRender();
6629
7004
  obj.onRemove();
6630
7005
  obj.parent = null;
7006
+ this._ctx.unregisterLifecyclePass(obj);
7007
+ this.renderableMapById.delete(id);
7008
+ const index = this._childrenInLayoutOrder.findIndex((obj2) => obj2.id === id);
7009
+ if (index !== -1) {
7010
+ this._childrenInLayoutOrder.splice(index, 1);
7011
+ }
7012
+ const zIndexIndex = this._childrenInZIndexOrder.findIndex((obj2) => obj2.id === id);
7013
+ if (zIndexIndex !== -1) {
7014
+ this._childrenInZIndexOrder.splice(zIndexIndex, 1);
7015
+ }
7016
+ this.childrenPrimarySortDirty = true;
6631
7017
  }
6632
- this.renderableMap.delete(id);
6633
- const index = this.renderableArray.findIndex((obj2) => obj2.id === id);
6634
- if (index !== -1) {
6635
- this.renderableArray.splice(index, 1);
6636
- }
6637
- this.childrenPrimarySortDirty = true;
6638
7018
  }
6639
7019
  }
6640
7020
  onRemove() {}
6641
7021
  getChildren() {
6642
- return [...this.renderableArray];
7022
+ return [...this._childrenInLayoutOrder];
6643
7023
  }
6644
7024
  getChildrenCount() {
6645
- return this.renderableArray.length;
7025
+ return this._childrenInLayoutOrder.length;
6646
7026
  }
6647
7027
  updateLayout(deltaTime, renderList = []) {
6648
7028
  if (!this.visible)
6649
7029
  return;
6650
- this.updateFromLayout();
6651
7030
  this.onUpdate(deltaTime);
7031
+ this.updateFromLayout();
6652
7032
  renderList.push({ action: "render", renderable: this });
6653
7033
  if (this._newChildren.length > 0) {
6654
7034
  for (const child of this._newChildren) {
@@ -6656,6 +7036,12 @@ class Renderable extends BaseRenderable {
6656
7036
  }
6657
7037
  this._newChildren = [];
6658
7038
  }
7039
+ if (this._forceLayoutUpdateFor) {
7040
+ for (const child of this._forceLayoutUpdateFor) {
7041
+ child.updateFromLayout();
7042
+ }
7043
+ this._forceLayoutUpdateFor = null;
7044
+ }
6659
7045
  this.ensureZIndexSorted();
6660
7046
  const shouldPushScissor = this._overflow !== "visible" && this.width > 0 && this.height > 0;
6661
7047
  if (shouldPushScissor) {
@@ -6694,7 +7080,7 @@ class Renderable extends BaseRenderable {
6694
7080
  }
6695
7081
  }
6696
7082
  _getChildren() {
6697
- return this.renderableArray;
7083
+ return this._childrenInZIndexOrder;
6698
7084
  }
6699
7085
  onUpdate(deltaTime) {}
6700
7086
  getScissorRect() {
@@ -6721,19 +7107,21 @@ class Renderable extends BaseRenderable {
6721
7107
  this.frameBuffer.destroy();
6722
7108
  this.frameBuffer = null;
6723
7109
  }
6724
- for (const child of this.renderableArray) {
7110
+ for (const child of this._childrenInLayoutOrder) {
6725
7111
  this.remove(child.id);
6726
7112
  }
6727
- this.renderableArray = [];
6728
- this.renderableMap.clear();
7113
+ this._childrenInLayoutOrder = [];
7114
+ this.renderableMapById.clear();
6729
7115
  Renderable.renderablesByNumber.delete(this.num);
6730
7116
  this.blur();
6731
7117
  this.removeAllListeners();
6732
7118
  this.destroySelf();
6733
- this.layoutNode.destroy();
7119
+ try {
7120
+ this.yogaNode.free();
7121
+ } catch (e) {}
6734
7122
  }
6735
7123
  destroyRecursively() {
6736
- for (const child of this.renderableArray) {
7124
+ for (const child of this._childrenInLayoutOrder) {
6737
7125
  child.destroyRecursively();
6738
7126
  }
6739
7127
  this.destroy();
@@ -6847,19 +7235,22 @@ class RootRenderable extends Renderable {
6847
7235
  this.yogaConfig = src_default.Config.create();
6848
7236
  this.yogaConfig.setUseWebDefaults(false);
6849
7237
  this.yogaConfig.setPointScaleFactor(1);
6850
- if (this.layoutNode) {
6851
- this.layoutNode.destroy();
7238
+ if (this.yogaNode) {
7239
+ this.yogaNode.free();
6852
7240
  }
6853
- this.layoutNode = createTrackedNode({}, this.yogaConfig);
6854
- this.layoutNode.setWidth(ctx.width);
6855
- this.layoutNode.setHeight(ctx.height);
6856
- this.layoutNode.yogaNode.setFlexDirection(FlexDirection.Column);
7241
+ this.yogaNode = src_default.Node.create(this.yogaConfig);
7242
+ this.yogaNode.setWidth(ctx.width);
7243
+ this.yogaNode.setHeight(ctx.height);
7244
+ this.yogaNode.setFlexDirection(FlexDirection.Column);
6857
7245
  this.calculateLayout();
6858
7246
  }
6859
7247
  render(buffer, deltaTime) {
6860
7248
  if (!this.visible)
6861
7249
  return;
6862
- if (this.layoutNode.yogaNode.isDirty()) {
7250
+ for (const renderable of this._ctx.getLifecyclePasses()) {
7251
+ renderable.onLifecyclePass?.call(renderable);
7252
+ }
7253
+ if (this.yogaNode.isDirty()) {
6863
7254
  this.calculateLayout();
6864
7255
  }
6865
7256
  this.renderList.length = 0;
@@ -6889,7 +7280,7 @@ class RootRenderable extends Renderable {
6889
7280
  }
6890
7281
  }
6891
7282
  calculateLayout() {
6892
- this.layoutNode.yogaNode.calculateLayout(this.width, this.height, Direction.LTR);
7283
+ this.yogaNode.calculateLayout(this.width, this.height, Direction.LTR);
6893
7284
  this.emit("layout-changed" /* LAYOUT_CHANGED */);
6894
7285
  }
6895
7286
  resize(width, height) {
@@ -6897,11 +7288,7 @@ class RootRenderable extends Renderable {
6897
7288
  this.height = height;
6898
7289
  this.emit("resized" /* RESIZED */, { width, height });
6899
7290
  }
6900
- onUpdate(deltaTime) {}
6901
7291
  destroySelf() {
6902
- if (this.layoutNode) {
6903
- this.layoutNode.destroy();
6904
- }
6905
7292
  try {
6906
7293
  this.yogaConfig.free();
6907
7294
  } catch (error) {}
@@ -7075,7 +7462,7 @@ function delegate(mapping, vnode) {
7075
7462
  }
7076
7463
 
7077
7464
  // src/console.ts
7078
- import { EventEmitter as EventEmitter5 } from "events";
7465
+ import { EventEmitter as EventEmitter4 } from "events";
7079
7466
  import { Console } from "console";
7080
7467
  import fs from "fs";
7081
7468
  import path from "path";
@@ -7083,9 +7470,9 @@ import util2 from "util";
7083
7470
 
7084
7471
  // src/lib/output.capture.ts
7085
7472
  import { Writable } from "stream";
7086
- import { EventEmitter as EventEmitter4 } from "events";
7473
+ import { EventEmitter as EventEmitter3 } from "events";
7087
7474
 
7088
- class Capture extends EventEmitter4 {
7475
+ class Capture extends EventEmitter3 {
7089
7476
  output = [];
7090
7477
  constructor() {
7091
7478
  super();
@@ -7149,7 +7536,7 @@ function getCallerInfo() {
7149
7536
  }
7150
7537
  var capture = singleton("ConsoleCapture", () => new Capture);
7151
7538
 
7152
- class TerminalConsoleCache extends EventEmitter5 {
7539
+ class TerminalConsoleCache extends EventEmitter4 {
7153
7540
  _cachedLogs = [];
7154
7541
  MAX_CACHE_SIZE = 1000;
7155
7542
  _collectCallerInfo = false;
@@ -7270,7 +7657,7 @@ var DEFAULT_CONSOLE_OPTIONS = {
7270
7657
  };
7271
7658
  var INDENT_WIDTH = 2;
7272
7659
 
7273
- class TerminalConsole extends EventEmitter5 {
7660
+ class TerminalConsole extends EventEmitter4 {
7274
7661
  isVisible = false;
7275
7662
  isFocused = false;
7276
7663
  renderer;
@@ -7761,7 +8148,7 @@ var ANSI = {
7761
8148
  };
7762
8149
 
7763
8150
  // src/renderer.ts
7764
- import { EventEmitter as EventEmitter6 } from "events";
8151
+ import { EventEmitter as EventEmitter5 } from "events";
7765
8152
 
7766
8153
  // src/lib/objects-in-viewport.ts
7767
8154
  function getObjectsInViewport(viewport, objects, direction = "column", padding = 10, minTriggerSize = 16) {
@@ -7919,7 +8306,7 @@ var CliRenderEvents;
7919
8306
  ((CliRenderEvents2) => {
7920
8307
  CliRenderEvents2["DEBUG_OVERLAY_TOGGLE"] = "debugOverlay:toggle";
7921
8308
  })(CliRenderEvents ||= {});
7922
- class CliRenderer extends EventEmitter6 {
8309
+ class CliRenderer extends EventEmitter5 {
7923
8310
  static animationFrameId = 0;
7924
8311
  lib;
7925
8312
  rendererPtr;
@@ -7931,6 +8318,7 @@ class CliRenderer extends EventEmitter6 {
7931
8318
  currentRenderBuffer;
7932
8319
  _isRunning = false;
7933
8320
  targetFps = 30;
8321
+ automaticMemorySnapshot = false;
7934
8322
  memorySnapshotInterval;
7935
8323
  memorySnapshotTimer = null;
7936
8324
  lastMemorySnapshot = {
@@ -7973,6 +8361,7 @@ class CliRenderer extends EventEmitter6 {
7973
8361
  };
7974
8362
  _console;
7975
8363
  _resolution = null;
8364
+ _keyHandler;
7976
8365
  animationRequest = new Map;
7977
8366
  resizeTimeoutId = null;
7978
8367
  resizeDebounceDelay = 100;
@@ -7997,10 +8386,57 @@ class CliRenderer extends EventEmitter6 {
7997
8386
  };
7998
8387
  _useConsole = true;
7999
8388
  mouseParser = new MouseParser;
8000
- sigwinchHandler = null;
8389
+ sigwinchHandler = (() => {
8390
+ const width = this.stdout.columns || 80;
8391
+ const height = this.stdout.rows || 24;
8392
+ this.handleResize(width, height);
8393
+ }).bind(this);
8001
8394
  _capabilities = null;
8002
8395
  _latestPointer = { x: 0, y: 0 };
8003
8396
  _currentFocusedRenderable = null;
8397
+ lifecyclePasses = new Set;
8398
+ handleError = ((error) => {
8399
+ this.stop();
8400
+ this.destroy();
8401
+ new Promise((resolve) => {
8402
+ setTimeout(() => {
8403
+ resolve(true);
8404
+ }, 100);
8405
+ }).then(() => {
8406
+ this.realStdoutWrite.call(this.stdout, `
8407
+ `.repeat(this._terminalHeight));
8408
+ this.realStdoutWrite.call(this.stdout, `
8409
+ === FATAL ERROR OCCURRED ===
8410
+ `);
8411
+ this.realStdoutWrite.call(this.stdout, `Console cache:
8412
+ `);
8413
+ this.realStdoutWrite.call(this.stdout, this.console.getCachedLogs());
8414
+ this.realStdoutWrite.call(this.stdout, `
8415
+ Captured output:
8416
+ `);
8417
+ const capturedOutput = capture.claimOutput();
8418
+ if (capturedOutput) {
8419
+ this.realStdoutWrite.call(this.stdout, capturedOutput + `
8420
+ `);
8421
+ }
8422
+ this.realStdoutWrite.call(this.stdout, `
8423
+ Error details:
8424
+ `);
8425
+ this.realStdoutWrite.call(this.stdout, error.message || "unknown error");
8426
+ this.realStdoutWrite.call(this.stdout, `
8427
+ `);
8428
+ this.realStdoutWrite.call(this.stdout, error.stack || error.toString());
8429
+ this.realStdoutWrite.call(this.stdout, `
8430
+ `);
8431
+ process.exit(1);
8432
+ });
8433
+ }).bind(this);
8434
+ exitHandler = (() => {
8435
+ this.destroy();
8436
+ }).bind(this);
8437
+ warningHandler = ((warning) => {
8438
+ console.warn(JSON.stringify(warning.message, null, 2));
8439
+ }).bind(this);
8004
8440
  constructor(lib, rendererPtr, stdin, stdout, width, height, config = {}) {
8005
8441
  super();
8006
8442
  this.stdin = stdin;
@@ -8023,7 +8459,7 @@ class CliRenderer extends EventEmitter6 {
8023
8459
  this.exitOnCtrlC = config.exitOnCtrlC === undefined ? true : config.exitOnCtrlC;
8024
8460
  this.resizeDebounceDelay = config.debounceDelay || 100;
8025
8461
  this.targetFps = config.targetFps || 30;
8026
- this.memorySnapshotInterval = config.memorySnapshotInterval || 5000;
8462
+ this.memorySnapshotInterval = config.memorySnapshotInterval ?? 0;
8027
8463
  this.gatherStats = config.gatherStats || false;
8028
8464
  this.maxStatSamples = config.maxStatSamples || 300;
8029
8465
  this.enableMouseMovement = config.enableMouseMovement || true;
@@ -8033,63 +8469,18 @@ class CliRenderer extends EventEmitter6 {
8033
8469
  this.currentRenderBuffer = this.lib.getCurrentBuffer(this.rendererPtr);
8034
8470
  this.postProcessFns = config.postProcessFns || [];
8035
8471
  this.root = new RootRenderable(this);
8036
- this.takeMemorySnapshot();
8037
8472
  if (this.memorySnapshotInterval > 0) {
8038
8473
  this.startMemorySnapshotTimer();
8039
8474
  }
8040
8475
  this.stdout.write = this.interceptStdoutWrite.bind(this);
8041
- this.sigwinchHandler = () => {
8042
- const width2 = this.stdout.columns || 80;
8043
- const height2 = this.stdout.rows || 24;
8044
- this.handleResize(width2, height2);
8045
- };
8046
8476
  process.on("SIGWINCH", this.sigwinchHandler);
8047
- const handleError = (error) => {
8048
- this.stop();
8049
- this.destroy();
8050
- new Promise((resolve) => {
8051
- setTimeout(() => {
8052
- resolve(true);
8053
- }, 100);
8054
- }).then(() => {
8055
- this.realStdoutWrite.call(this.stdout, `
8056
- `.repeat(this._terminalHeight));
8057
- this.realStdoutWrite.call(this.stdout, `
8058
- === FATAL ERROR OCCURRED ===
8059
- `);
8060
- this.realStdoutWrite.call(this.stdout, `Console cache:
8061
- `);
8062
- this.realStdoutWrite.call(this.stdout, this.console.getCachedLogs());
8063
- this.realStdoutWrite.call(this.stdout, `
8064
- Captured output:
8065
- `);
8066
- const capturedOutput = capture.claimOutput();
8067
- if (capturedOutput) {
8068
- this.realStdoutWrite.call(this.stdout, capturedOutput + `
8069
- `);
8070
- }
8071
- this.realStdoutWrite.call(this.stdout, `
8072
- Error details:
8073
- `);
8074
- this.realStdoutWrite.call(this.stdout, error.message || "unknown error");
8075
- this.realStdoutWrite.call(this.stdout, `
8076
- `);
8077
- this.realStdoutWrite.call(this.stdout, error.stack || error.toString());
8078
- this.realStdoutWrite.call(this.stdout, `
8079
- `);
8080
- process.exit(1);
8081
- });
8082
- };
8083
- process.on("warning", (warning) => {
8084
- console.warn(JSON.stringify(warning.message, null, 2));
8085
- });
8086
- process.on("uncaughtException", handleError);
8087
- process.on("unhandledRejection", handleError);
8088
- process.on("exit", () => {
8089
- this.destroy();
8090
- });
8477
+ process.on("warning", this.warningHandler);
8478
+ process.on("uncaughtException", this.handleError);
8479
+ process.on("unhandledRejection", this.handleError);
8480
+ process.on("exit", this.exitHandler);
8091
8481
  this._console = new TerminalConsole(this, config.consoleOptions);
8092
8482
  this.useConsole = config.useConsole ?? true;
8483
+ this._keyHandler = new KeyHandler(this.stdin, config.useKittyKeyboard ?? false);
8093
8484
  global.requestAnimationFrame = (callback) => {
8094
8485
  const id = CliRenderer.animationFrameId++;
8095
8486
  this.animationRequest.set(id, callback);
@@ -8111,6 +8502,16 @@ Error details:
8111
8502
  }
8112
8503
  };
8113
8504
  }
8505
+ this.setupInput();
8506
+ }
8507
+ registerLifecyclePass(renderable) {
8508
+ this.lifecyclePasses.add(renderable);
8509
+ }
8510
+ unregisterLifecyclePass(renderable) {
8511
+ this.lifecyclePasses.delete(renderable);
8512
+ }
8513
+ getLifecyclePasses() {
8514
+ return this.lifecyclePasses;
8114
8515
  }
8115
8516
  get currentFocusedRenderable() {
8116
8517
  return this._currentFocusedRenderable;
@@ -8164,6 +8565,9 @@ Error details:
8164
8565
  get console() {
8165
8566
  return this._console;
8166
8567
  }
8568
+ get keyInput() {
8569
+ return this._keyHandler;
8570
+ }
8167
8571
  get terminalWidth() {
8168
8572
  return this._terminalWidth;
8169
8573
  }
@@ -8252,7 +8656,6 @@ Error details:
8252
8656
  return true;
8253
8657
  };
8254
8658
  disableStdoutInterception() {
8255
- this.flushStdoutCache(this._splitHeight);
8256
8659
  this.stdout.write = this.realStdoutWrite;
8257
8660
  }
8258
8661
  flushStdoutCache(space, force = false) {
@@ -8263,10 +8666,13 @@ Error details:
8263
8666
  const flush = ANSI.moveCursorAndClear(rendererStartLine, 1);
8264
8667
  const outputLine = this._terminalHeight - this._splitHeight;
8265
8668
  const move = ANSI.moveCursor(outputLine, 1);
8266
- const backgroundColor = this.backgroundColor.toInts();
8267
- const newlines = " ".repeat(this.width) + `
8669
+ let clear = "";
8670
+ if (space > 0) {
8671
+ const backgroundColor = this.backgroundColor.toInts();
8672
+ const newlines = " ".repeat(this.width) + `
8268
8673
  `.repeat(space);
8269
- const clear = ANSI.setRgbBackground(backgroundColor[0], backgroundColor[1], backgroundColor[2]) + newlines + ANSI.resetBackground;
8674
+ clear = ANSI.setRgbBackground(backgroundColor[0], backgroundColor[1], backgroundColor[2]) + newlines + ANSI.resetBackground;
8675
+ }
8270
8676
  this.writeOut(flush + move + output + clear);
8271
8677
  return true;
8272
8678
  }
@@ -8315,32 +8721,35 @@ Error details:
8315
8721
  if (this._useMouse) {
8316
8722
  this.enableMouse();
8317
8723
  }
8318
- this.stdin.on("data", (data) => {
8319
- const str = data.toString();
8320
- if (this.waitingForPixelResolution && /\x1b\[4;\d+;\d+t/.test(str)) {
8321
- const match = str.match(/\x1b\[4;(\d+);(\d+)t/);
8322
- if (match) {
8323
- const resolution = {
8324
- width: parseInt(match[2]),
8325
- height: parseInt(match[1])
8326
- };
8327
- this._resolution = resolution;
8328
- this.waitingForPixelResolution = false;
8329
- return;
8330
- }
8331
- }
8332
- if (this.exitOnCtrlC && str === "\x03") {
8333
- process.nextTick(() => {
8334
- process.exit();
8335
- });
8336
- return;
8337
- }
8338
- if (this._useMouse && this.handleMouseData(data)) {
8724
+ this.queryPixelResolution();
8725
+ }
8726
+ stdinListener = ((data) => {
8727
+ const str = data.toString();
8728
+ if (this.waitingForPixelResolution && /\x1b\[4;\d+;\d+t/.test(str)) {
8729
+ const match = str.match(/\x1b\[4;(\d+);(\d+)t/);
8730
+ if (match) {
8731
+ const resolution = {
8732
+ width: parseInt(match[2]),
8733
+ height: parseInt(match[1])
8734
+ };
8735
+ this._resolution = resolution;
8736
+ this.waitingForPixelResolution = false;
8339
8737
  return;
8340
8738
  }
8341
- this.emit("key", data);
8342
- });
8343
- this.queryPixelResolution();
8739
+ }
8740
+ if (this.exitOnCtrlC && str === "\x03") {
8741
+ process.nextTick(() => {
8742
+ process.exit();
8743
+ });
8744
+ return;
8745
+ }
8746
+ if (this._useMouse && this.handleMouseData(data)) {
8747
+ return;
8748
+ }
8749
+ this.emit("key", data);
8750
+ }).bind(this);
8751
+ setupInput() {
8752
+ this.stdin.on("data", this.stdinListener);
8344
8753
  }
8345
8754
  handleMouseData(data) {
8346
8755
  const mouseEvent = this.mouseParser.parseMouseEvent(data);
@@ -8367,7 +8776,7 @@ Error details:
8367
8776
  this.lastOverRenderableNum = maybeRenderableId;
8368
8777
  const maybeRenderable = Renderable.renderablesByNumber.get(maybeRenderableId);
8369
8778
  if (mouseEvent.type === "down" && mouseEvent.button === 0 /* LEFT */ && !this.currentSelection?.isSelecting && !mouseEvent.modifiers.ctrl) {
8370
- if (maybeRenderable && maybeRenderable.selectable && maybeRenderable.shouldStartSelection(mouseEvent.x, mouseEvent.y)) {
8779
+ if (maybeRenderable && maybeRenderable.selectable && !maybeRenderable.isDestroyed && maybeRenderable.shouldStartSelection(mouseEvent.x, mouseEvent.y)) {
8371
8780
  this.startSelection(maybeRenderable, mouseEvent.x, mouseEvent.y);
8372
8781
  const event2 = new MouseEvent(maybeRenderable, mouseEvent);
8373
8782
  maybeRenderable.processMouseEvent(event2);
@@ -8455,6 +8864,8 @@ Error details:
8455
8864
  return false;
8456
8865
  }
8457
8866
  takeMemorySnapshot() {
8867
+ if (this.isDestroyed)
8868
+ return;
8458
8869
  const memoryUsage = process.memoryUsage();
8459
8870
  this.lastMemorySnapshot = {
8460
8871
  heapUsed: memoryUsage.heapUsed,
@@ -8465,13 +8876,17 @@ Error details:
8465
8876
  this.emit("memory:snapshot", this.lastMemorySnapshot);
8466
8877
  }
8467
8878
  startMemorySnapshotTimer() {
8468
- if (this.memorySnapshotTimer) {
8469
- clearInterval(this.memorySnapshotTimer);
8470
- }
8879
+ this.stopMemorySnapshotTimer();
8471
8880
  this.memorySnapshotTimer = setInterval(() => {
8472
8881
  this.takeMemorySnapshot();
8473
8882
  }, this.memorySnapshotInterval);
8474
8883
  }
8884
+ stopMemorySnapshotTimer() {
8885
+ if (this.memorySnapshotTimer) {
8886
+ clearInterval(this.memorySnapshotTimer);
8887
+ this.memorySnapshotTimer = null;
8888
+ }
8889
+ }
8475
8890
  setMemorySnapshotInterval(interval) {
8476
8891
  this.memorySnapshotInterval = interval;
8477
8892
  if (this._isRunning && interval > 0) {
@@ -8541,6 +8956,16 @@ Error details:
8541
8956
  this.requestRender();
8542
8957
  }
8543
8958
  toggleDebugOverlay() {
8959
+ const willBeEnabled = !this.debugOverlay.enabled;
8960
+ if (willBeEnabled && !this.memorySnapshotInterval) {
8961
+ this.memorySnapshotInterval = 3000;
8962
+ this.startMemorySnapshotTimer();
8963
+ this.automaticMemorySnapshot = true;
8964
+ } else if (!willBeEnabled && this.automaticMemorySnapshot) {
8965
+ this.stopMemorySnapshotTimer();
8966
+ this.memorySnapshotInterval = 0;
8967
+ this.automaticMemorySnapshot = false;
8968
+ }
8544
8969
  this.debugOverlay.enabled = !this.debugOverlay.enabled;
8545
8970
  this.lib.setDebugOverlay(this.rendererPtr, this.debugOverlay.enabled, this.debugOverlay.corner);
8546
8971
  this.emit("debugOverlay:toggle" /* DEBUG_OVERLAY_TOGGLE */, this.debugOverlay.enabled);
@@ -8667,19 +9092,32 @@ Error details:
8667
9092
  }
8668
9093
  }
8669
9094
  destroy() {
8670
- this.stdin.setRawMode(false);
9095
+ this.stdin.removeListener("data", this.stdinListener);
9096
+ process.removeListener("SIGWINCH", this.sigwinchHandler);
9097
+ process.removeListener("uncaughtException", this.handleError);
9098
+ process.removeListener("unhandledRejection", this.handleError);
9099
+ process.removeListener("exit", this.exitHandler);
9100
+ process.removeListener("warning", this.warningHandler);
9101
+ capture.removeListener("write", this.captureCallback);
9102
+ if (this.memorySnapshotTimer) {
9103
+ clearInterval(this.memorySnapshotTimer);
9104
+ }
9105
+ if (this.stdin.setRawMode) {
9106
+ this.stdin.setRawMode(false);
9107
+ }
8671
9108
  if (this.isDestroyed)
8672
9109
  return;
8673
9110
  this.isDestroyed = true;
8674
9111
  this.waitingForPixelResolution = false;
8675
9112
  this.capturedRenderable = undefined;
8676
- if (this.sigwinchHandler) {
8677
- process.removeListener("SIGWINCH", this.sigwinchHandler);
8678
- this.sigwinchHandler = null;
8679
- }
9113
+ this.root.destroyRecursively();
9114
+ this._keyHandler.destroy();
8680
9115
  this._console.deactivate();
8681
9116
  this.disableStdoutInterception();
8682
- this.lib.destroyRenderer(this.rendererPtr, this._useAlternateScreen, this._splitHeight);
9117
+ if (this._splitHeight > 0) {
9118
+ this.flushStdoutCache(this._splitHeight, true);
9119
+ }
9120
+ this.lib.destroyRenderer(this.rendererPtr);
8683
9121
  }
8684
9122
  startRenderLoop() {
8685
9123
  if (!this._isRunning)
@@ -8812,7 +9250,7 @@ Error details:
8812
9250
  clearSelection() {
8813
9251
  if (this.currentSelection) {
8814
9252
  for (const renderable of this.currentSelection.touchedRenderables) {
8815
- if (renderable.selectable) {
9253
+ if (renderable.selectable && !renderable.isDestroyed) {
8816
9254
  renderable.onSelectionChanged(null);
8817
9255
  }
8818
9256
  }
@@ -8903,7 +9341,7 @@ Error details:
8903
9341
  }
8904
9342
  }
8905
9343
 
8906
- 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, 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 };
9344
+ export { __toESM, __commonJS, __export, __require, Edge, Gutter, exports_src, BorderChars, getBorderFromSides, getBorderSides, borderCharsToArray, BorderCharArrays, 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, isValidPercentage, LayoutEvents, RenderableEvents, isRenderable, BaseRenderable, Renderable, RootRenderable, capture, ConsolePosition, TerminalConsole, getObjectsInViewport, MouseEvent, MouseButton, createCliRenderer, CliRenderEvents, CliRenderer };
8907
9345
 
8908
- //# debugId=688CA104E8866AAF64756E2164756E21
8909
- //# sourceMappingURL=index-443j38eh.js.map
9346
+ //# debugId=F7540B181A9A091164756E2164756E21
9347
+ //# sourceMappingURL=index-0yx9rnxg.js.map