@opentui/core 0.1.24 → 0.1.25
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/3d.js +1 -1
- package/Renderable.d.ts +11 -2
- package/ansi.d.ts +2 -17
- package/{index-0yx9rnxg.js → index-6kvgbzah.js} +338 -107
- package/{index-0yx9rnxg.js.map → index-6kvgbzah.js.map} +11 -10
- package/index.js +45 -26
- package/index.js.map +7 -7
- package/lib/KeyHandler.d.ts +4 -1
- package/lib/env.d.ts +41 -0
- package/lib/index.d.ts +1 -0
- package/package.json +7 -7
- package/renderables/ASCIIFont.d.ts +1 -1
- package/renderables/Input.d.ts +2 -2
- package/renderables/Text.d.ts +3 -0
- package/renderer.d.ts +1 -1
- package/testing/mock-keys.d.ts +1 -0
- package/testing/test-renderer.d.ts +1 -0
- package/testing.js +16 -6
- package/testing.js.map +4 -4
- package/zig.d.ts +1 -0
- /package/{singleton.d.ts → lib/singleton.d.ts} +0 -0
|
@@ -2175,30 +2175,46 @@ var parseKeypress = (s = "", options = {}) => {
|
|
|
2175
2175
|
// src/lib/KeyHandler.ts
|
|
2176
2176
|
import { EventEmitter } from "events";
|
|
2177
2177
|
|
|
2178
|
-
// src/
|
|
2179
|
-
var
|
|
2180
|
-
|
|
2181
|
-
|
|
2182
|
-
|
|
2183
|
-
|
|
2184
|
-
}
|
|
2185
|
-
|
|
2186
|
-
}
|
|
2178
|
+
// src/ansi.ts
|
|
2179
|
+
var ANSI = {
|
|
2180
|
+
switchToAlternateScreen: "\x1B[?1049h",
|
|
2181
|
+
switchToMainScreen: "\x1B[?1049l",
|
|
2182
|
+
reset: "\x1B[0m",
|
|
2183
|
+
scrollDown: (lines) => `\x1B[${lines}T`,
|
|
2184
|
+
scrollUp: (lines) => `\x1B[${lines}S`,
|
|
2185
|
+
moveCursor: (row, col) => `\x1B[${row};${col}H`,
|
|
2186
|
+
moveCursorAndClear: (row, col) => `\x1B[${row};${col}H\x1B[J`,
|
|
2187
|
+
setRgbBackground: (r, g, b) => `\x1B[48;2;${r};${g};${b}m`,
|
|
2188
|
+
resetBackground: "\x1B[49m",
|
|
2189
|
+
bracketedPasteStart: "\x1B[200~",
|
|
2190
|
+
bracketedPasteEnd: "\x1B[201~"
|
|
2191
|
+
};
|
|
2187
2192
|
|
|
2188
2193
|
// src/lib/KeyHandler.ts
|
|
2189
2194
|
class KeyHandler extends EventEmitter {
|
|
2190
2195
|
stdin;
|
|
2191
2196
|
useKittyKeyboard;
|
|
2197
|
+
listener;
|
|
2198
|
+
pasteMode = false;
|
|
2199
|
+
pasteBuffer = [];
|
|
2192
2200
|
constructor(stdin, useKittyKeyboard = false) {
|
|
2193
2201
|
super();
|
|
2194
2202
|
this.stdin = stdin || process.stdin;
|
|
2195
2203
|
this.useKittyKeyboard = useKittyKeyboard;
|
|
2196
|
-
|
|
2197
|
-
|
|
2198
|
-
|
|
2199
|
-
|
|
2200
|
-
|
|
2201
|
-
|
|
2204
|
+
this.listener = (key) => {
|
|
2205
|
+
let data = key.toString();
|
|
2206
|
+
if (data.startsWith(ANSI.bracketedPasteStart)) {
|
|
2207
|
+
this.pasteMode = true;
|
|
2208
|
+
}
|
|
2209
|
+
if (this.pasteMode) {
|
|
2210
|
+
this.pasteBuffer.push(Bun.stripANSI(data));
|
|
2211
|
+
if (data.endsWith(ANSI.bracketedPasteEnd)) {
|
|
2212
|
+
this.pasteMode = false;
|
|
2213
|
+
this.emit("paste", this.pasteBuffer.join(""));
|
|
2214
|
+
this.pasteBuffer = [];
|
|
2215
|
+
}
|
|
2216
|
+
return;
|
|
2217
|
+
}
|
|
2202
2218
|
const parsedKey = parseKeypress(key, { useKittyKeyboard: this.useKittyKeyboard });
|
|
2203
2219
|
switch (parsedKey.eventType) {
|
|
2204
2220
|
case "press":
|
|
@@ -2214,18 +2230,12 @@ class KeyHandler extends EventEmitter {
|
|
|
2214
2230
|
this.emit("keypress", parsedKey);
|
|
2215
2231
|
break;
|
|
2216
2232
|
}
|
|
2217
|
-
}
|
|
2233
|
+
};
|
|
2234
|
+
this.stdin.on("data", this.listener);
|
|
2218
2235
|
}
|
|
2219
2236
|
destroy() {
|
|
2220
|
-
this.stdin.
|
|
2221
|
-
}
|
|
2222
|
-
}
|
|
2223
|
-
var keyHandler = null;
|
|
2224
|
-
function getKeyHandler(useKittyKeyboard = false) {
|
|
2225
|
-
if (!keyHandler) {
|
|
2226
|
-
keyHandler = singleton("KeyHandler", () => new KeyHandler(process.stdin, useKittyKeyboard));
|
|
2237
|
+
this.stdin.removeListener("data", this.listener);
|
|
2227
2238
|
}
|
|
2228
|
-
return keyHandler;
|
|
2229
2239
|
}
|
|
2230
2240
|
|
|
2231
2241
|
// src/lib/RGBA.ts
|
|
@@ -4804,6 +4814,166 @@ class ASCIIFontSelectionHelper {
|
|
|
4804
4814
|
return previousSelection?.start !== this.localSelection?.start || previousSelection?.end !== this.localSelection?.end;
|
|
4805
4815
|
}
|
|
4806
4816
|
}
|
|
4817
|
+
|
|
4818
|
+
// src/lib/singleton.ts
|
|
4819
|
+
var singletonCacheSymbol = Symbol.for("@opentui/core/singleton");
|
|
4820
|
+
function singleton(key, factory) {
|
|
4821
|
+
const bag = globalThis[singletonCacheSymbol] ??= {};
|
|
4822
|
+
if (!(key in bag)) {
|
|
4823
|
+
bag[key] = factory();
|
|
4824
|
+
}
|
|
4825
|
+
return bag[key];
|
|
4826
|
+
}
|
|
4827
|
+
|
|
4828
|
+
// src/lib/env.ts
|
|
4829
|
+
var envRegistry = {};
|
|
4830
|
+
function registerEnvVar(config) {
|
|
4831
|
+
const existing = envRegistry[config.name];
|
|
4832
|
+
if (existing) {
|
|
4833
|
+
if (existing.description !== config.description || existing.type !== config.type || existing.default !== config.default) {
|
|
4834
|
+
throw new Error(`Environment variable "${config.name}" is already registered with different configuration. ` + `Existing: ${JSON.stringify(existing)}, New: ${JSON.stringify(config)}`);
|
|
4835
|
+
}
|
|
4836
|
+
return;
|
|
4837
|
+
}
|
|
4838
|
+
envRegistry[config.name] = config;
|
|
4839
|
+
}
|
|
4840
|
+
function normalizeBoolean(value) {
|
|
4841
|
+
const lowerValue = value.toLowerCase();
|
|
4842
|
+
return ["true", "1", "on", "yes"].includes(lowerValue);
|
|
4843
|
+
}
|
|
4844
|
+
function parseEnvValue(config) {
|
|
4845
|
+
const envValue = process.env[config.name];
|
|
4846
|
+
if (envValue === undefined && config.default !== undefined) {
|
|
4847
|
+
return config.default;
|
|
4848
|
+
}
|
|
4849
|
+
if (envValue === undefined) {
|
|
4850
|
+
throw new Error(`Required environment variable ${config.name} is not set. ${config.description}`);
|
|
4851
|
+
}
|
|
4852
|
+
switch (config.type) {
|
|
4853
|
+
case "boolean":
|
|
4854
|
+
return typeof envValue === "boolean" ? envValue : normalizeBoolean(envValue);
|
|
4855
|
+
case "number":
|
|
4856
|
+
const numValue = Number(envValue);
|
|
4857
|
+
if (isNaN(numValue)) {
|
|
4858
|
+
throw new Error(`Environment variable ${config.name} must be a valid number, got: ${envValue}`);
|
|
4859
|
+
}
|
|
4860
|
+
return numValue;
|
|
4861
|
+
case "string":
|
|
4862
|
+
default:
|
|
4863
|
+
return envValue;
|
|
4864
|
+
}
|
|
4865
|
+
}
|
|
4866
|
+
|
|
4867
|
+
class EnvStore {
|
|
4868
|
+
parsedValues = new Map;
|
|
4869
|
+
get(key) {
|
|
4870
|
+
if (this.parsedValues.has(key)) {
|
|
4871
|
+
return this.parsedValues.get(key);
|
|
4872
|
+
}
|
|
4873
|
+
if (!(key in envRegistry)) {
|
|
4874
|
+
throw new Error(`Environment variable ${key} is not registered.`);
|
|
4875
|
+
}
|
|
4876
|
+
try {
|
|
4877
|
+
const value = parseEnvValue(envRegistry[key]);
|
|
4878
|
+
this.parsedValues.set(key, value);
|
|
4879
|
+
return value;
|
|
4880
|
+
} catch (error) {
|
|
4881
|
+
throw new Error(`Failed to parse env var ${key}: ${error instanceof Error ? error.message : String(error)}`);
|
|
4882
|
+
}
|
|
4883
|
+
}
|
|
4884
|
+
has(key) {
|
|
4885
|
+
return key in envRegistry;
|
|
4886
|
+
}
|
|
4887
|
+
}
|
|
4888
|
+
var envStore = singleton("env-store", () => new EnvStore);
|
|
4889
|
+
function generateEnvMarkdown() {
|
|
4890
|
+
const configs = Object.values(envRegistry);
|
|
4891
|
+
if (configs.length === 0) {
|
|
4892
|
+
return `# Environment Variables
|
|
4893
|
+
|
|
4894
|
+
No environment variables registered.
|
|
4895
|
+
`;
|
|
4896
|
+
}
|
|
4897
|
+
let markdown = `# Environment Variables
|
|
4898
|
+
|
|
4899
|
+
`;
|
|
4900
|
+
for (const config of configs) {
|
|
4901
|
+
markdown += `## ${config.name}
|
|
4902
|
+
|
|
4903
|
+
`;
|
|
4904
|
+
markdown += `${config.description}
|
|
4905
|
+
|
|
4906
|
+
`;
|
|
4907
|
+
markdown += `**Type:** \`${config.type || "string"}\`
|
|
4908
|
+
`;
|
|
4909
|
+
if (config.default !== undefined) {
|
|
4910
|
+
const defaultValue = typeof config.default === "string" ? `"${config.default}"` : String(config.default);
|
|
4911
|
+
markdown += `**Default:** \`${defaultValue}\`
|
|
4912
|
+
`;
|
|
4913
|
+
} else {
|
|
4914
|
+
markdown += `**Default:** *Required*
|
|
4915
|
+
`;
|
|
4916
|
+
}
|
|
4917
|
+
markdown += `
|
|
4918
|
+
`;
|
|
4919
|
+
}
|
|
4920
|
+
return markdown;
|
|
4921
|
+
}
|
|
4922
|
+
function generateEnvColored() {
|
|
4923
|
+
const configs = Object.values(envRegistry);
|
|
4924
|
+
if (configs.length === 0) {
|
|
4925
|
+
return `\x1B[1;36mEnvironment Variables\x1B[0m
|
|
4926
|
+
|
|
4927
|
+
No environment variables registered.
|
|
4928
|
+
`;
|
|
4929
|
+
}
|
|
4930
|
+
let output = `\x1B[1;36mEnvironment Variables\x1B[0m
|
|
4931
|
+
|
|
4932
|
+
`;
|
|
4933
|
+
for (const config of configs) {
|
|
4934
|
+
output += `\x1B[1;33m${config.name}\x1B[0m
|
|
4935
|
+
`;
|
|
4936
|
+
output += `${config.description}
|
|
4937
|
+
`;
|
|
4938
|
+
output += `\x1B[32mType:\x1B[0m \x1B[36m${config.type || "string"}\x1B[0m
|
|
4939
|
+
`;
|
|
4940
|
+
if (config.default !== undefined) {
|
|
4941
|
+
const defaultValue = typeof config.default === "string" ? `"${config.default}"` : String(config.default);
|
|
4942
|
+
output += `\x1B[32mDefault:\x1B[0m \x1B[35m${defaultValue}\x1B[0m
|
|
4943
|
+
`;
|
|
4944
|
+
} else {
|
|
4945
|
+
output += `\x1B[32mDefault:\x1B[0m \x1B[31mRequired\x1B[0m
|
|
4946
|
+
`;
|
|
4947
|
+
}
|
|
4948
|
+
output += `
|
|
4949
|
+
`;
|
|
4950
|
+
}
|
|
4951
|
+
return output;
|
|
4952
|
+
}
|
|
4953
|
+
var env = new Proxy({}, {
|
|
4954
|
+
get(target, prop) {
|
|
4955
|
+
if (typeof prop !== "string") {
|
|
4956
|
+
return;
|
|
4957
|
+
}
|
|
4958
|
+
return envStore.get(prop);
|
|
4959
|
+
},
|
|
4960
|
+
has(target, prop) {
|
|
4961
|
+
return envStore.has(prop);
|
|
4962
|
+
},
|
|
4963
|
+
ownKeys() {
|
|
4964
|
+
return Object.keys(envRegistry);
|
|
4965
|
+
},
|
|
4966
|
+
getOwnPropertyDescriptor(target, prop) {
|
|
4967
|
+
if (envStore.has(prop)) {
|
|
4968
|
+
return {
|
|
4969
|
+
enumerable: true,
|
|
4970
|
+
configurable: true,
|
|
4971
|
+
get: () => envStore.get(prop)
|
|
4972
|
+
};
|
|
4973
|
+
}
|
|
4974
|
+
return;
|
|
4975
|
+
}
|
|
4976
|
+
});
|
|
4807
4977
|
// src/zig.ts
|
|
4808
4978
|
import { dlopen, toArrayBuffer as toArrayBuffer2, JSCallback, ptr } from "bun:ffi";
|
|
4809
4979
|
import { existsSync } from "fs";
|
|
@@ -5010,6 +5180,18 @@ var targetLibPath = module.default;
|
|
|
5010
5180
|
if (!existsSync(targetLibPath)) {
|
|
5011
5181
|
throw new Error(`opentui is not supported on the current platform: ${process.platform}-${process.arch}`);
|
|
5012
5182
|
}
|
|
5183
|
+
registerEnvVar({
|
|
5184
|
+
name: "OTUI_DEBUG_FFI",
|
|
5185
|
+
description: "Enable debug logging for the FFI bindings.",
|
|
5186
|
+
type: "boolean",
|
|
5187
|
+
default: false
|
|
5188
|
+
});
|
|
5189
|
+
registerEnvVar({
|
|
5190
|
+
name: "OTUI_TRACE_FFI",
|
|
5191
|
+
description: "Enable tracing for the FFI bindings.",
|
|
5192
|
+
type: "boolean",
|
|
5193
|
+
default: false
|
|
5194
|
+
});
|
|
5013
5195
|
function getOpenTUILib(libPath) {
|
|
5014
5196
|
const resolvedLibPath = libPath || targetLibPath;
|
|
5015
5197
|
const rawSymbols = dlopen(resolvedLibPath, {
|
|
@@ -5057,6 +5239,10 @@ function getOpenTUILib(libPath) {
|
|
|
5057
5239
|
args: ["ptr"],
|
|
5058
5240
|
returns: "ptr"
|
|
5059
5241
|
},
|
|
5242
|
+
queryPixelResolution: {
|
|
5243
|
+
args: ["ptr"],
|
|
5244
|
+
returns: "void"
|
|
5245
|
+
},
|
|
5060
5246
|
createOptimizedBuffer: {
|
|
5061
5247
|
args: ["u32", "u32", "bool", "u8", "ptr", "usize"],
|
|
5062
5248
|
returns: "ptr"
|
|
@@ -5346,7 +5532,7 @@ function getOpenTUILib(libPath) {
|
|
|
5346
5532
|
returns: "void"
|
|
5347
5533
|
}
|
|
5348
5534
|
});
|
|
5349
|
-
if (
|
|
5535
|
+
if (env.OTUI_DEBUG_FFI || env.OTUI_TRACE_FFI) {
|
|
5350
5536
|
return {
|
|
5351
5537
|
symbols: convertToDebugSymbols(rawSymbols.symbols)
|
|
5352
5538
|
};
|
|
@@ -5360,7 +5546,7 @@ function convertToDebugSymbols(symbols) {
|
|
|
5360
5546
|
Object.entries(symbols).forEach(([key, value]) => {
|
|
5361
5547
|
debugSymbols[key] = value;
|
|
5362
5548
|
});
|
|
5363
|
-
if (
|
|
5549
|
+
if (env.OTUI_DEBUG_FFI) {
|
|
5364
5550
|
Object.entries(symbols).forEach(([key, value]) => {
|
|
5365
5551
|
if (typeof value === "function") {
|
|
5366
5552
|
debugSymbols[key] = (...args) => {
|
|
@@ -5372,7 +5558,7 @@ function convertToDebugSymbols(symbols) {
|
|
|
5372
5558
|
}
|
|
5373
5559
|
});
|
|
5374
5560
|
}
|
|
5375
|
-
if (
|
|
5561
|
+
if (env.OTUI_TRACE_FFI) {
|
|
5376
5562
|
hasTracing = true;
|
|
5377
5563
|
Object.entries(symbols).forEach(([key, value]) => {
|
|
5378
5564
|
if (typeof value === "function") {
|
|
@@ -5734,6 +5920,9 @@ class FFIRenderLib {
|
|
|
5734
5920
|
setupTerminal(renderer, useAlternateScreen) {
|
|
5735
5921
|
this.opentui.symbols.setupTerminal(renderer, useAlternateScreen);
|
|
5736
5922
|
}
|
|
5923
|
+
queryPixelResolution(renderer) {
|
|
5924
|
+
this.opentui.symbols.queryPixelResolution(renderer);
|
|
5925
|
+
}
|
|
5737
5926
|
createTextBuffer(widthMethod) {
|
|
5738
5927
|
const widthMethodCode = widthMethod === "wcwidth" ? 0 : 1;
|
|
5739
5928
|
const bufferPtr = this.opentui.symbols.createTextBuffer(widthMethodCode);
|
|
@@ -6222,6 +6411,9 @@ class BaseRenderable extends EventEmitter2 {
|
|
|
6222
6411
|
this._visible = value;
|
|
6223
6412
|
}
|
|
6224
6413
|
}
|
|
6414
|
+
var yogaConfig = src_default.Config.create();
|
|
6415
|
+
yogaConfig.setUseWebDefaults(false);
|
|
6416
|
+
yogaConfig.setPointScaleFactor(1);
|
|
6225
6417
|
|
|
6226
6418
|
class Renderable extends BaseRenderable {
|
|
6227
6419
|
static renderablesByNumber = new Map;
|
|
@@ -6242,11 +6434,13 @@ class Renderable extends BaseRenderable {
|
|
|
6242
6434
|
_focusable = false;
|
|
6243
6435
|
_focused = false;
|
|
6244
6436
|
keypressHandler = null;
|
|
6437
|
+
pasteHandler = null;
|
|
6245
6438
|
_live = false;
|
|
6246
6439
|
_liveCount = 0;
|
|
6247
6440
|
_sizeChangeListener = undefined;
|
|
6248
6441
|
_mouseListener = null;
|
|
6249
6442
|
_mouseListeners = {};
|
|
6443
|
+
_pasteListener = undefined;
|
|
6250
6444
|
_keyListeners = {};
|
|
6251
6445
|
yogaNode;
|
|
6252
6446
|
_positionType = "relative";
|
|
@@ -6283,7 +6477,7 @@ class Renderable extends BaseRenderable {
|
|
|
6283
6477
|
this.buffered = options.buffered ?? false;
|
|
6284
6478
|
this._live = options.live ?? false;
|
|
6285
6479
|
this._liveCount = this._live && this._visible ? 1 : 0;
|
|
6286
|
-
this.yogaNode = src_default.Node.create();
|
|
6480
|
+
this.yogaNode = src_default.Node.create(yogaConfig);
|
|
6287
6481
|
this.yogaNode.setDisplay(this._visible ? Display.Flex : Display.None);
|
|
6288
6482
|
this.setupYogaProperties(options);
|
|
6289
6483
|
this.applyEventOptions(options);
|
|
@@ -6356,7 +6550,14 @@ class Renderable extends BaseRenderable {
|
|
|
6356
6550
|
this.handleKeyPress(key);
|
|
6357
6551
|
}
|
|
6358
6552
|
};
|
|
6553
|
+
this.pasteHandler = (text) => {
|
|
6554
|
+
this._pasteListener?.call(this, text);
|
|
6555
|
+
if (this.handlePaste) {
|
|
6556
|
+
this.handlePaste(text);
|
|
6557
|
+
}
|
|
6558
|
+
};
|
|
6359
6559
|
this.ctx.keyInput.on("keypress", this.keypressHandler);
|
|
6560
|
+
this.ctx.keyInput.on("paste", this.pasteHandler);
|
|
6360
6561
|
this.emit("focused" /* FOCUSED */);
|
|
6361
6562
|
}
|
|
6362
6563
|
blur() {
|
|
@@ -6368,6 +6569,10 @@ class Renderable extends BaseRenderable {
|
|
|
6368
6569
|
this.ctx.keyInput.off("keypress", this.keypressHandler);
|
|
6369
6570
|
this.keypressHandler = null;
|
|
6370
6571
|
}
|
|
6572
|
+
if (this.pasteHandler) {
|
|
6573
|
+
this.ctx.keyInput.off("paste", this.pasteHandler);
|
|
6574
|
+
this.pasteHandler = null;
|
|
6575
|
+
}
|
|
6371
6576
|
this.emit("blurred" /* BLURRED */);
|
|
6372
6577
|
}
|
|
6373
6578
|
get focused() {
|
|
@@ -6396,9 +6601,11 @@ class Renderable extends BaseRenderable {
|
|
|
6396
6601
|
for (const child of this._childrenInLayoutOrder) {
|
|
6397
6602
|
if (child.id === id)
|
|
6398
6603
|
return child;
|
|
6399
|
-
|
|
6400
|
-
|
|
6401
|
-
|
|
6604
|
+
if (isRenderable(child)) {
|
|
6605
|
+
const found = child.findDescendantById(id);
|
|
6606
|
+
if (found)
|
|
6607
|
+
return found;
|
|
6608
|
+
}
|
|
6402
6609
|
}
|
|
6403
6610
|
return;
|
|
6404
6611
|
}
|
|
@@ -6551,8 +6758,7 @@ class Renderable extends BaseRenderable {
|
|
|
6551
6758
|
if (options.flexShrink !== undefined) {
|
|
6552
6759
|
node.setFlexShrink(options.flexShrink);
|
|
6553
6760
|
} else {
|
|
6554
|
-
|
|
6555
|
-
node.setFlexShrink(shrinkValue);
|
|
6761
|
+
node.setFlexShrink(1);
|
|
6556
6762
|
}
|
|
6557
6763
|
if (options.flexDirection !== undefined) {
|
|
6558
6764
|
node.setFlexDirection(parseFlexDirection(options.flexDirection));
|
|
@@ -7196,6 +7402,12 @@ class Renderable extends BaseRenderable {
|
|
|
7196
7402
|
else
|
|
7197
7403
|
delete this._mouseListeners["scroll"];
|
|
7198
7404
|
}
|
|
7405
|
+
set onPaste(handler) {
|
|
7406
|
+
this._pasteListener = handler;
|
|
7407
|
+
}
|
|
7408
|
+
get onPaste() {
|
|
7409
|
+
return this._pasteListener;
|
|
7410
|
+
}
|
|
7199
7411
|
set onKeyDown(handler) {
|
|
7200
7412
|
if (handler)
|
|
7201
7413
|
this._keyListeners["down"] = handler;
|
|
@@ -7222,23 +7434,20 @@ class Renderable extends BaseRenderable {
|
|
|
7222
7434
|
this.onMouseOver = options.onMouseOver;
|
|
7223
7435
|
this.onMouseOut = options.onMouseOut;
|
|
7224
7436
|
this.onMouseScroll = options.onMouseScroll;
|
|
7437
|
+
this.onPaste = options.onPaste;
|
|
7225
7438
|
this.onKeyDown = options.onKeyDown;
|
|
7226
7439
|
this.onSizeChange = options.onSizeChange;
|
|
7227
7440
|
}
|
|
7228
7441
|
}
|
|
7229
7442
|
|
|
7230
7443
|
class RootRenderable extends Renderable {
|
|
7231
|
-
yogaConfig;
|
|
7232
7444
|
renderList = [];
|
|
7233
7445
|
constructor(ctx) {
|
|
7234
7446
|
super(ctx, { id: "__root__", zIndex: 0, visible: true, width: ctx.width, height: ctx.height, enableLayout: true });
|
|
7235
|
-
this.yogaConfig = src_default.Config.create();
|
|
7236
|
-
this.yogaConfig.setUseWebDefaults(false);
|
|
7237
|
-
this.yogaConfig.setPointScaleFactor(1);
|
|
7238
7447
|
if (this.yogaNode) {
|
|
7239
7448
|
this.yogaNode.free();
|
|
7240
7449
|
}
|
|
7241
|
-
this.yogaNode = src_default.Node.create(
|
|
7450
|
+
this.yogaNode = src_default.Node.create(yogaConfig);
|
|
7242
7451
|
this.yogaNode.setWidth(ctx.width);
|
|
7243
7452
|
this.yogaNode.setHeight(ctx.height);
|
|
7244
7453
|
this.yogaNode.setFlexDirection(FlexDirection.Column);
|
|
@@ -7288,11 +7497,6 @@ class RootRenderable extends Renderable {
|
|
|
7288
7497
|
this.height = height;
|
|
7289
7498
|
this.emit("resized" /* RESIZED */, { width, height });
|
|
7290
7499
|
}
|
|
7291
|
-
destroySelf() {
|
|
7292
|
-
try {
|
|
7293
|
-
this.yogaConfig.free();
|
|
7294
|
-
} catch (error) {}
|
|
7295
|
-
}
|
|
7296
7500
|
}
|
|
7297
7501
|
|
|
7298
7502
|
// src/renderables/composition/vnode.ts
|
|
@@ -7535,6 +7739,18 @@ function getCallerInfo() {
|
|
|
7535
7739
|
return { functionName, fullPath, fileName, lineNumber, columnNumber };
|
|
7536
7740
|
}
|
|
7537
7741
|
var capture = singleton("ConsoleCapture", () => new Capture);
|
|
7742
|
+
registerEnvVar({
|
|
7743
|
+
name: "OTUI_USE_CONSOLE",
|
|
7744
|
+
description: "Whether to use the console. Will not capture console output if set to false.",
|
|
7745
|
+
type: "boolean",
|
|
7746
|
+
default: true
|
|
7747
|
+
});
|
|
7748
|
+
registerEnvVar({
|
|
7749
|
+
name: "SHOW_CONSOLE",
|
|
7750
|
+
description: "Show the console at startup if set to true.",
|
|
7751
|
+
type: "boolean",
|
|
7752
|
+
default: false
|
|
7753
|
+
});
|
|
7538
7754
|
|
|
7539
7755
|
class TerminalConsoleCache extends EventEmitter4 {
|
|
7540
7756
|
_cachedLogs = [];
|
|
@@ -7552,7 +7768,7 @@ class TerminalConsoleCache extends EventEmitter4 {
|
|
|
7552
7768
|
this.overrideConsoleMethods();
|
|
7553
7769
|
}
|
|
7554
7770
|
setupConsoleCapture() {
|
|
7555
|
-
if (
|
|
7771
|
+
if (!env.OTUI_USE_CONSOLE)
|
|
7556
7772
|
return;
|
|
7557
7773
|
const mockStdout = new CapturedWritableStream("stdout", capture);
|
|
7558
7774
|
const mockStderr = new CapturedWritableStream("stderr", capture);
|
|
@@ -7717,7 +7933,7 @@ class TerminalConsole extends EventEmitter4 {
|
|
|
7717
7933
|
terminalConsoleCache.on("entry", (logEntry) => {
|
|
7718
7934
|
this._handleNewLog(logEntry);
|
|
7719
7935
|
});
|
|
7720
|
-
if (
|
|
7936
|
+
if (env.SHOW_CONSOLE) {
|
|
7721
7937
|
this.show();
|
|
7722
7938
|
}
|
|
7723
7939
|
}
|
|
@@ -8116,37 +8332,6 @@ class TerminalConsole extends EventEmitter4 {
|
|
|
8116
8332
|
}
|
|
8117
8333
|
}
|
|
8118
8334
|
|
|
8119
|
-
// src/ansi.ts
|
|
8120
|
-
var ANSI = {
|
|
8121
|
-
switchToAlternateScreen: "\x1B[?1049h",
|
|
8122
|
-
switchToMainScreen: "\x1B[?1049l",
|
|
8123
|
-
reset: "\x1B[0m",
|
|
8124
|
-
hideCursor: "\x1B[?25l",
|
|
8125
|
-
showCursor: "\x1B[?25h",
|
|
8126
|
-
resetCursorColor: "\x1B]12;default\x07",
|
|
8127
|
-
saveCursorState: "\x1B[s",
|
|
8128
|
-
restoreCursorState: "\x1B[u",
|
|
8129
|
-
queryPixelSize: "\x1B[14t",
|
|
8130
|
-
scrollDown: (lines) => `\x1B[${lines}T`,
|
|
8131
|
-
scrollUp: (lines) => `\x1B[${lines}S`,
|
|
8132
|
-
moveCursor: (row, col) => `\x1B[${row};${col}H`,
|
|
8133
|
-
moveCursorAndClear: (row, col) => `\x1B[${row};${col}H\x1B[J`,
|
|
8134
|
-
clearFromCursor: "\x1B[J",
|
|
8135
|
-
setRgbBackground: (r, g, b) => `\x1B[48;2;${r};${g};${b}m`,
|
|
8136
|
-
resetBackground: "\x1B[49m",
|
|
8137
|
-
enableMouseTracking: "\x1B[?1000h",
|
|
8138
|
-
disableMouseTracking: "\x1B[?1000l",
|
|
8139
|
-
enableButtonEventTracking: "\x1B[?1002h",
|
|
8140
|
-
disableButtonEventTracking: "\x1B[?1002l",
|
|
8141
|
-
enableAnyEventTracking: "\x1B[?1003h",
|
|
8142
|
-
disableAnyEventTracking: "\x1B[?1003l",
|
|
8143
|
-
enableSGRMouseMode: "\x1B[?1006h",
|
|
8144
|
-
disableSGRMouseMode: "\x1B[?1006l",
|
|
8145
|
-
makeRoomForRenderer: (height) => `
|
|
8146
|
-
`.repeat(height) + `\x1B[${height}A`,
|
|
8147
|
-
clearRendererSpace: (height) => `\x1B[${height}A\x1B[1G\x1B[J`
|
|
8148
|
-
};
|
|
8149
|
-
|
|
8150
8335
|
// src/renderer.ts
|
|
8151
8336
|
import { EventEmitter as EventEmitter5 } from "events";
|
|
8152
8337
|
|
|
@@ -8226,6 +8411,19 @@ function getObjectsInViewport(viewport, objects, direction = "column", padding =
|
|
|
8226
8411
|
}
|
|
8227
8412
|
|
|
8228
8413
|
// src/renderer.ts
|
|
8414
|
+
registerEnvVar({
|
|
8415
|
+
name: "OTUI_DUMP_CAPTURES",
|
|
8416
|
+
description: "Dump captured output when the renderer exits.",
|
|
8417
|
+
type: "boolean",
|
|
8418
|
+
default: false
|
|
8419
|
+
});
|
|
8420
|
+
registerEnvVar({
|
|
8421
|
+
name: "OTUI_NO_NATIVE_RENDER",
|
|
8422
|
+
description: "Disable native rendering. This will not actually output ansi and is useful for debugging.",
|
|
8423
|
+
type: "boolean",
|
|
8424
|
+
default: false
|
|
8425
|
+
});
|
|
8426
|
+
|
|
8229
8427
|
class MouseEvent {
|
|
8230
8428
|
type;
|
|
8231
8429
|
button;
|
|
@@ -8277,6 +8475,20 @@ singleton("ProcessExitSignals", () => {
|
|
|
8277
8475
|
});
|
|
8278
8476
|
});
|
|
8279
8477
|
});
|
|
8478
|
+
var rendererTracker = singleton("RendererTracker", () => {
|
|
8479
|
+
const renderers = new Set;
|
|
8480
|
+
return {
|
|
8481
|
+
addRenderer: (renderer) => {
|
|
8482
|
+
renderers.add(renderer);
|
|
8483
|
+
},
|
|
8484
|
+
removeRenderer: (renderer) => {
|
|
8485
|
+
renderers.delete(renderer);
|
|
8486
|
+
if (renderers.size === 0) {
|
|
8487
|
+
process.stdin.pause();
|
|
8488
|
+
}
|
|
8489
|
+
}
|
|
8490
|
+
};
|
|
8491
|
+
});
|
|
8280
8492
|
async function createCliRenderer(config = {}) {
|
|
8281
8493
|
if (process.argv.includes("--delay-start")) {
|
|
8282
8494
|
await new Promise((resolve) => setTimeout(resolve, 5000));
|
|
@@ -8408,17 +8620,7 @@ class CliRenderer extends EventEmitter5 {
|
|
|
8408
8620
|
this.realStdoutWrite.call(this.stdout, `
|
|
8409
8621
|
=== FATAL ERROR OCCURRED ===
|
|
8410
8622
|
`);
|
|
8411
|
-
this.
|
|
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
|
-
}
|
|
8623
|
+
this.dumpOutputCache();
|
|
8422
8624
|
this.realStdoutWrite.call(this.stdout, `
|
|
8423
8625
|
Error details:
|
|
8424
8626
|
`);
|
|
@@ -8431,14 +8633,39 @@ Error details:
|
|
|
8431
8633
|
process.exit(1);
|
|
8432
8634
|
});
|
|
8433
8635
|
}).bind(this);
|
|
8636
|
+
dumpOutputCache(optionalMessage = "") {
|
|
8637
|
+
const cachedLogs = this.console.getCachedLogs();
|
|
8638
|
+
const capturedOutput = capture.claimOutput();
|
|
8639
|
+
if (capturedOutput.length > 0 || cachedLogs.length > 0) {
|
|
8640
|
+
this.realStdoutWrite.call(this.stdout, optionalMessage);
|
|
8641
|
+
}
|
|
8642
|
+
if (cachedLogs.length > 0) {
|
|
8643
|
+
this.realStdoutWrite.call(this.stdout, `Console cache:
|
|
8644
|
+
`);
|
|
8645
|
+
this.realStdoutWrite.call(this.stdout, cachedLogs);
|
|
8646
|
+
}
|
|
8647
|
+
if (capturedOutput.length > 0) {
|
|
8648
|
+
this.realStdoutWrite.call(this.stdout, `
|
|
8649
|
+
Captured output:
|
|
8650
|
+
`);
|
|
8651
|
+
this.realStdoutWrite.call(this.stdout, capturedOutput + `
|
|
8652
|
+
`);
|
|
8653
|
+
}
|
|
8654
|
+
this.realStdoutWrite.call(this.stdout, ANSI.reset);
|
|
8655
|
+
}
|
|
8434
8656
|
exitHandler = (() => {
|
|
8435
8657
|
this.destroy();
|
|
8658
|
+
if (env.OTUI_DUMP_CAPTURES) {
|
|
8659
|
+
this.dumpOutputCache(`=== CAPTURED OUTPUT ===
|
|
8660
|
+
`);
|
|
8661
|
+
}
|
|
8436
8662
|
}).bind(this);
|
|
8437
8663
|
warningHandler = ((warning) => {
|
|
8438
8664
|
console.warn(JSON.stringify(warning.message, null, 2));
|
|
8439
8665
|
}).bind(this);
|
|
8440
8666
|
constructor(lib, rendererPtr, stdin, stdout, width, height, config = {}) {
|
|
8441
8667
|
super();
|
|
8668
|
+
rendererTracker.addRenderer(this);
|
|
8442
8669
|
this.stdin = stdin;
|
|
8443
8670
|
this.stdout = stdout;
|
|
8444
8671
|
this.realStdoutWrite = stdout.write;
|
|
@@ -8495,7 +8722,7 @@ Error details:
|
|
|
8495
8722
|
global.window = {};
|
|
8496
8723
|
}
|
|
8497
8724
|
global.window.requestAnimationFrame = requestAnimationFrame;
|
|
8498
|
-
if (
|
|
8725
|
+
if (env.OTUI_NO_NATIVE_RENDER) {
|
|
8499
8726
|
this.renderNative = () => {
|
|
8500
8727
|
if (this._splitHeight > 0) {
|
|
8501
8728
|
this.flushStdoutCache(this._splitHeight);
|
|
@@ -8698,11 +8925,6 @@ Error details:
|
|
|
8698
8925
|
if (this._terminalIsSetup)
|
|
8699
8926
|
return;
|
|
8700
8927
|
this._terminalIsSetup = true;
|
|
8701
|
-
if (this.stdin.setRawMode) {
|
|
8702
|
-
this.stdin.setRawMode(true);
|
|
8703
|
-
}
|
|
8704
|
-
this.stdin.resume();
|
|
8705
|
-
this.stdin.setEncoding("utf8");
|
|
8706
8928
|
await new Promise((resolve) => {
|
|
8707
8929
|
const timeout = setTimeout(() => {
|
|
8708
8930
|
this.stdin.off("data", capListener);
|
|
@@ -8739,7 +8961,7 @@ Error details:
|
|
|
8739
8961
|
}
|
|
8740
8962
|
if (this.exitOnCtrlC && str === "\x03") {
|
|
8741
8963
|
process.nextTick(() => {
|
|
8742
|
-
|
|
8964
|
+
this.destroy();
|
|
8743
8965
|
});
|
|
8744
8966
|
return;
|
|
8745
8967
|
}
|
|
@@ -8749,6 +8971,11 @@ Error details:
|
|
|
8749
8971
|
this.emit("key", data);
|
|
8750
8972
|
}).bind(this);
|
|
8751
8973
|
setupInput() {
|
|
8974
|
+
if (this.stdin.setRawMode) {
|
|
8975
|
+
this.stdin.setRawMode(true);
|
|
8976
|
+
}
|
|
8977
|
+
this.stdin.resume();
|
|
8978
|
+
this.stdin.setEncoding("utf8");
|
|
8752
8979
|
this.stdin.on("data", this.stdinListener);
|
|
8753
8980
|
}
|
|
8754
8981
|
handleMouseData(data) {
|
|
@@ -8914,7 +9141,7 @@ Error details:
|
|
|
8914
9141
|
}
|
|
8915
9142
|
queryPixelResolution() {
|
|
8916
9143
|
this.waitingForPixelResolution = true;
|
|
8917
|
-
this.
|
|
9144
|
+
this.lib.queryPixelResolution(this.rendererPtr);
|
|
8918
9145
|
}
|
|
8919
9146
|
processResize(width, height) {
|
|
8920
9147
|
if (width === this._terminalWidth && height === this._terminalHeight)
|
|
@@ -8977,9 +9204,6 @@ Error details:
|
|
|
8977
9204
|
this.lib.setDebugOverlay(this.rendererPtr, this.debugOverlay.enabled, this.debugOverlay.corner);
|
|
8978
9205
|
this.requestRender();
|
|
8979
9206
|
}
|
|
8980
|
-
clearTerminal() {
|
|
8981
|
-
this.lib.clearTerminal(this.rendererPtr);
|
|
8982
|
-
}
|
|
8983
9207
|
setTerminalTitle(title) {
|
|
8984
9208
|
this.lib.setTerminalTitle(this.rendererPtr, title);
|
|
8985
9209
|
}
|
|
@@ -9092,22 +9316,22 @@ Error details:
|
|
|
9092
9316
|
}
|
|
9093
9317
|
}
|
|
9094
9318
|
destroy() {
|
|
9095
|
-
this.stdin.removeListener("data", this.stdinListener);
|
|
9096
9319
|
process.removeListener("SIGWINCH", this.sigwinchHandler);
|
|
9097
9320
|
process.removeListener("uncaughtException", this.handleError);
|
|
9098
9321
|
process.removeListener("unhandledRejection", this.handleError);
|
|
9099
|
-
process.removeListener("exit", this.exitHandler);
|
|
9100
9322
|
process.removeListener("warning", this.warningHandler);
|
|
9101
9323
|
capture.removeListener("write", this.captureCallback);
|
|
9102
9324
|
if (this.memorySnapshotTimer) {
|
|
9103
9325
|
clearInterval(this.memorySnapshotTimer);
|
|
9104
9326
|
}
|
|
9105
|
-
if (this.stdin.setRawMode) {
|
|
9106
|
-
this.stdin.setRawMode(false);
|
|
9107
|
-
}
|
|
9108
9327
|
if (this.isDestroyed)
|
|
9109
9328
|
return;
|
|
9110
9329
|
this.isDestroyed = true;
|
|
9330
|
+
if (this.renderTimeout) {
|
|
9331
|
+
clearTimeout(this.renderTimeout);
|
|
9332
|
+
this.renderTimeout = null;
|
|
9333
|
+
}
|
|
9334
|
+
this._isRunning = false;
|
|
9111
9335
|
this.waitingForPixelResolution = false;
|
|
9112
9336
|
this.capturedRenderable = undefined;
|
|
9113
9337
|
this.root.destroyRecursively();
|
|
@@ -9117,7 +9341,12 @@ Error details:
|
|
|
9117
9341
|
if (this._splitHeight > 0) {
|
|
9118
9342
|
this.flushStdoutCache(this._splitHeight, true);
|
|
9119
9343
|
}
|
|
9344
|
+
if (this.stdin.setRawMode) {
|
|
9345
|
+
this.stdin.setRawMode(false);
|
|
9346
|
+
}
|
|
9347
|
+
this.stdin.removeListener("data", this.stdinListener);
|
|
9120
9348
|
this.lib.destroyRenderer(this.rendererPtr);
|
|
9349
|
+
rendererTracker.removeRenderer(this);
|
|
9121
9350
|
}
|
|
9122
9351
|
startRenderLoop() {
|
|
9123
9352
|
if (!this._isRunning)
|
|
@@ -9174,7 +9403,9 @@ Error details:
|
|
|
9174
9403
|
postProcessFn(this.nextRenderBuffer, deltaTime);
|
|
9175
9404
|
}
|
|
9176
9405
|
this._console.renderToBuffer(this.nextRenderBuffer);
|
|
9177
|
-
this.
|
|
9406
|
+
if (!this.isDestroyed) {
|
|
9407
|
+
this.renderNative();
|
|
9408
|
+
}
|
|
9178
9409
|
const overallFrameTime = performance.now() - overallStart;
|
|
9179
9410
|
this.lib.updateStats(this.rendererPtr, overallFrameTime, this.renderStats.fps, this.renderStats.frameCallbackTime);
|
|
9180
9411
|
if (this.gatherStats) {
|
|
@@ -9341,7 +9572,7 @@ Error details:
|
|
|
9341
9572
|
}
|
|
9342
9573
|
}
|
|
9343
9574
|
|
|
9344
|
-
export { __toESM, __commonJS, __export, __require, Edge, Gutter, exports_src, BorderChars, getBorderFromSides, getBorderSides, borderCharsToArray, BorderCharArrays, nonAlphanumericKeys, parseKeypress,
|
|
9575
|
+
export { __toESM, __commonJS, __export, __require, Edge, Gutter, exports_src, BorderChars, getBorderFromSides, getBorderSides, borderCharsToArray, BorderCharArrays, nonAlphanumericKeys, parseKeypress, ANSI, KeyHandler, 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, envRegistry, registerEnvVar, generateEnvMarkdown, generateEnvColored, env, 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 };
|
|
9345
9576
|
|
|
9346
|
-
//# debugId=
|
|
9347
|
-
//# sourceMappingURL=index-
|
|
9577
|
+
//# debugId=FA47EE78BCA83E8664756E2164756E21
|
|
9578
|
+
//# sourceMappingURL=index-6kvgbzah.js.map
|