@cascadetui/core 0.1.9 → 0.1.11
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/{index-9j6zba34.js → index-gv8mtakv.js} +172 -5
- package/{index-9j6zba34.js.map → index-gv8mtakv.js.map} +4 -4
- package/index.js +33 -4
- package/index.js.map +3 -3
- package/package.json +7 -7
- package/renderables/TextBufferRenderable.d.ts +6 -0
- package/renderer.d.ts +14 -0
- package/testing.js +1 -1
package/3d.js
CHANGED
|
@@ -10533,6 +10533,24 @@ registerEnvVar({
|
|
|
10533
10533
|
type: "boolean",
|
|
10534
10534
|
default: false
|
|
10535
10535
|
});
|
|
10536
|
+
registerEnvVar({
|
|
10537
|
+
name: "CASCADE_TRACE_FFI_SLOW_MS",
|
|
10538
|
+
description: "Log slow FFI calls (>= threshold, in ms).",
|
|
10539
|
+
type: "number",
|
|
10540
|
+
default: 0
|
|
10541
|
+
});
|
|
10542
|
+
registerEnvVar({
|
|
10543
|
+
name: "CASCADE_TRACE_FFI_MAX_SAMPLES",
|
|
10544
|
+
description: "Max timing samples to keep per FFI symbol when CASCADE_TRACE_FFI is enabled.",
|
|
10545
|
+
type: "number",
|
|
10546
|
+
default: 5000
|
|
10547
|
+
});
|
|
10548
|
+
registerEnvVar({
|
|
10549
|
+
name: "CASCADE_TRACE_FRAME_BREAKDOWN",
|
|
10550
|
+
description: "Enable detailed frame timing breakdown (yoga, render tree, native, stdout write)",
|
|
10551
|
+
type: "boolean",
|
|
10552
|
+
default: false
|
|
10553
|
+
});
|
|
10536
10554
|
registerEnvVar({
|
|
10537
10555
|
name: "CASCADE_FORCE_WCWIDTH",
|
|
10538
10556
|
description: "Use wcwidth for character width calculations",
|
|
@@ -11553,9 +11571,56 @@ function convertToDebugSymbols(symbols) {
|
|
|
11553
11571
|
if (env.CASCADE_DEBUG_FFI && !globalFFILogWriter) {
|
|
11554
11572
|
const now = new Date;
|
|
11555
11573
|
const timestamp = now.toISOString().replace(/[:.]/g, "-").replace(/T/, "_").split("Z")[0];
|
|
11556
|
-
const logFilePath = `
|
|
11574
|
+
const logFilePath = `ffi_cascade_debug_${timestamp}.log`;
|
|
11557
11575
|
globalFFILogWriter = Bun.file(logFilePath).writer();
|
|
11558
11576
|
}
|
|
11577
|
+
const slowThresholdMs = typeof env.CASCADE_TRACE_FFI_SLOW_MS === "number" ? env.CASCADE_TRACE_FFI_SLOW_MS : 0;
|
|
11578
|
+
const maxSamples = typeof env.CASCADE_TRACE_FFI_MAX_SAMPLES === "number" && env.CASCADE_TRACE_FFI_MAX_SAMPLES > 0 ? env.CASCADE_TRACE_FFI_MAX_SAMPLES : 5000;
|
|
11579
|
+
const formatArg = (arg) => {
|
|
11580
|
+
if (arg === null)
|
|
11581
|
+
return "null";
|
|
11582
|
+
if (arg === undefined)
|
|
11583
|
+
return "undefined";
|
|
11584
|
+
const t2 = typeof arg;
|
|
11585
|
+
if (t2 === "string")
|
|
11586
|
+
return JSON.stringify(arg.length > 200 ? arg.slice(0, 200) + "\u2026" : arg);
|
|
11587
|
+
if (t2 === "number" || t2 === "boolean" || t2 === "bigint")
|
|
11588
|
+
return String(arg);
|
|
11589
|
+
if (arg instanceof Uint8Array)
|
|
11590
|
+
return `Uint8Array(${arg.byteLength})`;
|
|
11591
|
+
if (arg instanceof ArrayBuffer)
|
|
11592
|
+
return `ArrayBuffer(${arg.byteLength})`;
|
|
11593
|
+
if (Array.isArray(arg))
|
|
11594
|
+
return `Array(${arg.length})`;
|
|
11595
|
+
if (t2 === "object") {
|
|
11596
|
+
const ctor = arg?.constructor?.name;
|
|
11597
|
+
if (ctor && ctor !== "Object")
|
|
11598
|
+
return ctor;
|
|
11599
|
+
try {
|
|
11600
|
+
const json = JSON.stringify(arg);
|
|
11601
|
+
if (typeof json === "string")
|
|
11602
|
+
return json.length > 200 ? json.slice(0, 200) + "\u2026" : json;
|
|
11603
|
+
} catch {
|
|
11604
|
+
return "Object";
|
|
11605
|
+
}
|
|
11606
|
+
return "Object";
|
|
11607
|
+
}
|
|
11608
|
+
return String(arg);
|
|
11609
|
+
};
|
|
11610
|
+
let slowWriter = null;
|
|
11611
|
+
const writeSlow = (line) => {
|
|
11612
|
+
if (slowThresholdMs <= 0)
|
|
11613
|
+
return;
|
|
11614
|
+
if (!slowWriter) {
|
|
11615
|
+
const now = new Date;
|
|
11616
|
+
const timestamp = now.toISOString().replace(/[:.]/g, "-").replace(/T/, "_").split("Z")[0];
|
|
11617
|
+
const slowFilePath = `ffi_cascade_slow_${timestamp}.log`;
|
|
11618
|
+
slowWriter = Bun.file(slowFilePath).writer();
|
|
11619
|
+
}
|
|
11620
|
+
const buffer = new TextEncoder().encode(line + `
|
|
11621
|
+
`);
|
|
11622
|
+
slowWriter.write(buffer);
|
|
11623
|
+
};
|
|
11559
11624
|
const debugSymbols = {};
|
|
11560
11625
|
let hasTracing = false;
|
|
11561
11626
|
Object.entries(symbols).forEach(([key, value]) => {
|
|
@@ -11592,7 +11657,16 @@ function convertToDebugSymbols(symbols) {
|
|
|
11592
11657
|
const start = performance.now();
|
|
11593
11658
|
const result = originalFunc(...args);
|
|
11594
11659
|
const end = performance.now();
|
|
11595
|
-
|
|
11660
|
+
const dt = end - start;
|
|
11661
|
+
const timings = globalTraceSymbols[key];
|
|
11662
|
+
timings.push(dt);
|
|
11663
|
+
if (timings.length > maxSamples) {
|
|
11664
|
+
timings.splice(0, timings.length - maxSamples);
|
|
11665
|
+
}
|
|
11666
|
+
if (slowThresholdMs > 0 && dt >= slowThresholdMs) {
|
|
11667
|
+
const argStr = args.map(formatArg).join(", ");
|
|
11668
|
+
writeSlow(`${new Date().toISOString()} ${key} ${dt.toFixed(2)}ms (${argStr})`);
|
|
11669
|
+
}
|
|
11596
11670
|
return result;
|
|
11597
11671
|
};
|
|
11598
11672
|
}
|
|
@@ -11605,6 +11679,9 @@ function convertToDebugSymbols(symbols) {
|
|
|
11605
11679
|
if (globalFFILogWriter) {
|
|
11606
11680
|
globalFFILogWriter.end();
|
|
11607
11681
|
}
|
|
11682
|
+
if (slowWriter) {
|
|
11683
|
+
slowWriter.end();
|
|
11684
|
+
}
|
|
11608
11685
|
} catch (e) {}
|
|
11609
11686
|
if (globalTraceSymbols) {
|
|
11610
11687
|
const allStats = [];
|
|
@@ -11676,7 +11753,7 @@ function convertToDebugSymbols(symbols) {
|
|
|
11676
11753
|
try {
|
|
11677
11754
|
const now = new Date;
|
|
11678
11755
|
const timestamp = now.toISOString().replace(/[:.]/g, "-").replace(/T/, "_").split("Z")[0];
|
|
11679
|
-
const traceFilePath = `
|
|
11756
|
+
const traceFilePath = `ffi_cascade_trace_${timestamp}.log`;
|
|
11680
11757
|
Bun.write(traceFilePath, output);
|
|
11681
11758
|
} catch (e) {
|
|
11682
11759
|
console.error("Failed to write FFI trace file:", e);
|
|
@@ -16537,6 +16614,8 @@ class CliRenderer extends EventEmitter9 {
|
|
|
16537
16614
|
_isDestroyed = false;
|
|
16538
16615
|
_destroyPending = false;
|
|
16539
16616
|
_destroyFinalized = false;
|
|
16617
|
+
destroyTimeoutId = null;
|
|
16618
|
+
destroyTimeoutMs = 100;
|
|
16540
16619
|
nextRenderBuffer;
|
|
16541
16620
|
currentRenderBuffer;
|
|
16542
16621
|
_isRunning = false;
|
|
@@ -16578,6 +16657,10 @@ class CliRenderer extends EventEmitter9 {
|
|
|
16578
16657
|
minTargetFrameTime = 1000 / this.maxFps;
|
|
16579
16658
|
immediateRerenderRequested = false;
|
|
16580
16659
|
updateScheduled = false;
|
|
16660
|
+
consecutiveImmediateRerenders = 0;
|
|
16661
|
+
lastImmediateRerenderTime = 0;
|
|
16662
|
+
maxConsecutiveImmediateRerenders = 10;
|
|
16663
|
+
immediateRerenderResetMs = 1000;
|
|
16581
16664
|
liveRequestCounter = 0;
|
|
16582
16665
|
_controlState = "idle" /* IDLE */;
|
|
16583
16666
|
frameCallbacks = [];
|
|
@@ -16587,6 +16670,9 @@ class CliRenderer extends EventEmitter9 {
|
|
|
16587
16670
|
renderTime: 0,
|
|
16588
16671
|
frameCallbackTime: 0
|
|
16589
16672
|
};
|
|
16673
|
+
frameBreakdownBuffer = [];
|
|
16674
|
+
frameBreakdownMaxSize = 100;
|
|
16675
|
+
traceFrameBreakdown = env.CASCADE_TRACE_FRAME_BREAKDOWN;
|
|
16590
16676
|
debugOverlay = {
|
|
16591
16677
|
enabled: env.CASCADE_SHOW_STATS,
|
|
16592
16678
|
corner: 3 /* bottomRight */
|
|
@@ -17660,6 +17746,16 @@ Captured output:
|
|
|
17660
17746
|
if (this._logCrashReportsToConsole) {
|
|
17661
17747
|
console.error(this.formatCrashReportForConsole(report));
|
|
17662
17748
|
}
|
|
17749
|
+
if (this.traceFrameBreakdown && this.frameBreakdownBuffer.length > 0) {
|
|
17750
|
+
const breakdownDump = this.dumpFrameBreakdown();
|
|
17751
|
+
console.error(`
|
|
17752
|
+
` + breakdownDump);
|
|
17753
|
+
report.recentEvents.push({
|
|
17754
|
+
timestamp: report.timestamp,
|
|
17755
|
+
type: "crash:frame_breakdown",
|
|
17756
|
+
payload: { breakdown: breakdownDump }
|
|
17757
|
+
});
|
|
17758
|
+
}
|
|
17663
17759
|
this.emit("crash" /* CRASH */, report);
|
|
17664
17760
|
return report;
|
|
17665
17761
|
}
|
|
@@ -17925,6 +18021,14 @@ Captured output:
|
|
|
17925
18021
|
this._isDestroyed = true;
|
|
17926
18022
|
this._destroyPending = true;
|
|
17927
18023
|
if (this.rendering) {
|
|
18024
|
+
if (this.destroyTimeoutId === null) {
|
|
18025
|
+
this.destroyTimeoutId = setTimeout(() => {
|
|
18026
|
+
this.destroyTimeoutId = null;
|
|
18027
|
+
if (this._destroyPending && !this._destroyFinalized && !this.renderingNative) {
|
|
18028
|
+
this.finalizeDestroy();
|
|
18029
|
+
}
|
|
18030
|
+
}, this.destroyTimeoutMs);
|
|
18031
|
+
}
|
|
17928
18032
|
return;
|
|
17929
18033
|
}
|
|
17930
18034
|
this.finalizeDestroy();
|
|
@@ -17934,6 +18038,10 @@ Captured output:
|
|
|
17934
18038
|
return;
|
|
17935
18039
|
this._destroyFinalized = true;
|
|
17936
18040
|
this._destroyPending = false;
|
|
18041
|
+
if (this.destroyTimeoutId !== null) {
|
|
18042
|
+
clearTimeout(this.destroyTimeoutId);
|
|
18043
|
+
this.destroyTimeoutId = null;
|
|
18044
|
+
}
|
|
17937
18045
|
process.removeListener("SIGWINCH", this.sigwinchHandler);
|
|
17938
18046
|
process.removeListener("uncaughtException", this.uncaughtExceptionHandler);
|
|
17939
18047
|
process.removeListener("unhandledRejection", this.unhandledRejectionHandler);
|
|
@@ -17964,6 +18072,9 @@ Captured output:
|
|
|
17964
18072
|
this.renderTimeout = null;
|
|
17965
18073
|
}
|
|
17966
18074
|
this._isRunning = false;
|
|
18075
|
+
this.rendering = false;
|
|
18076
|
+
this.updateScheduled = false;
|
|
18077
|
+
this.immediateRerenderRequested = false;
|
|
17967
18078
|
this.waitingForPixelResolution = false;
|
|
17968
18079
|
this.setCapturedRenderable(undefined);
|
|
17969
18080
|
try {
|
|
@@ -17992,6 +18103,26 @@ Captured output:
|
|
|
17992
18103
|
}
|
|
17993
18104
|
this.resolveIdleIfNeeded();
|
|
17994
18105
|
}
|
|
18106
|
+
dumpFrameBreakdown() {
|
|
18107
|
+
if (this.frameBreakdownBuffer.length === 0) {
|
|
18108
|
+
return "No frame breakdown data recorded";
|
|
18109
|
+
}
|
|
18110
|
+
const lines = this.frameBreakdownBuffer.map((f, i) => {
|
|
18111
|
+
const time = new Date(f.timestamp).toISOString();
|
|
18112
|
+
return `[${i}] ${time} total=${f.totalMs.toFixed(2)}ms tree=${f.renderTreeMs.toFixed(2)}ms native=${f.nativeMs.toFixed(2)}ms callback=${f.frameCallbackMs.toFixed(2)}ms`;
|
|
18113
|
+
});
|
|
18114
|
+
const totals = this.frameBreakdownBuffer.map((f) => f.totalMs);
|
|
18115
|
+
const avgTotal = totals.reduce((a, b) => a + b, 0) / totals.length;
|
|
18116
|
+
const maxTotal = Math.max(...totals);
|
|
18117
|
+
const minTotal = Math.min(...totals);
|
|
18118
|
+
return [
|
|
18119
|
+
`=== Frame Breakdown (${this.frameBreakdownBuffer.length} frames) ===`,
|
|
18120
|
+
`Avg: ${avgTotal.toFixed(2)}ms, Max: ${maxTotal.toFixed(2)}ms, Min: ${minTotal.toFixed(2)}ms`,
|
|
18121
|
+
"",
|
|
18122
|
+
...lines
|
|
18123
|
+
].join(`
|
|
18124
|
+
`);
|
|
18125
|
+
}
|
|
17995
18126
|
startRenderLoop() {
|
|
17996
18127
|
if (!this._isRunning)
|
|
17997
18128
|
return;
|
|
@@ -18043,6 +18174,9 @@ Captured output:
|
|
|
18043
18174
|
}
|
|
18044
18175
|
const end = performance.now();
|
|
18045
18176
|
this.renderStats.frameCallbackTime = end - start;
|
|
18177
|
+
if (this._destroyPending) {
|
|
18178
|
+
return;
|
|
18179
|
+
}
|
|
18046
18180
|
const renderTreeStart = traceEnabled ? trace.now() : 0;
|
|
18047
18181
|
this.root.render(this.nextRenderBuffer, deltaTime);
|
|
18048
18182
|
const renderTreeMs = traceEnabled ? trace.now() - renderTreeStart : 0;
|
|
@@ -18062,6 +18196,21 @@ Captured output:
|
|
|
18062
18196
|
}
|
|
18063
18197
|
}
|
|
18064
18198
|
const overallFrameTime = performance.now() - overallStart;
|
|
18199
|
+
if (this.traceFrameBreakdown) {
|
|
18200
|
+
const breakdown = {
|
|
18201
|
+
timestamp: Date.now(),
|
|
18202
|
+
yogaMs: 0,
|
|
18203
|
+
renderTreeMs,
|
|
18204
|
+
nativeMs,
|
|
18205
|
+
stdoutMs: 0,
|
|
18206
|
+
frameCallbackMs: this.renderStats.frameCallbackTime,
|
|
18207
|
+
totalMs: overallFrameTime
|
|
18208
|
+
};
|
|
18209
|
+
if (this.frameBreakdownBuffer.length >= this.frameBreakdownMaxSize) {
|
|
18210
|
+
this.frameBreakdownBuffer.shift();
|
|
18211
|
+
}
|
|
18212
|
+
this.frameBreakdownBuffer.push(breakdown);
|
|
18213
|
+
}
|
|
18065
18214
|
if (traceEnabled) {
|
|
18066
18215
|
trace.write(`trace.render.native ms=${nativeMs.toFixed(3)}`);
|
|
18067
18216
|
trace.write(`trace.render.pipeline treeMs=${renderTreeMs.toFixed(3)} postMs=${postProcessMs.toFixed(3)} nativeMs=${nativeMs.toFixed(3)} frameMs=${overallFrameTime.toFixed(3)} animMs=${animationRequestTime.toFixed(3)}`);
|
|
@@ -18071,6 +18220,24 @@ Captured output:
|
|
|
18071
18220
|
this.collectStatSample(overallFrameTime);
|
|
18072
18221
|
}
|
|
18073
18222
|
if (this._isRunning || this.immediateRerenderRequested) {
|
|
18223
|
+
const now2 = Date.now();
|
|
18224
|
+
if (this.immediateRerenderRequested) {
|
|
18225
|
+
if (now2 - this.lastImmediateRerenderTime > this.immediateRerenderResetMs) {
|
|
18226
|
+
this.consecutiveImmediateRerenders = 0;
|
|
18227
|
+
}
|
|
18228
|
+
this.consecutiveImmediateRerenders++;
|
|
18229
|
+
this.lastImmediateRerenderTime = now2;
|
|
18230
|
+
if (this.consecutiveImmediateRerenders > this.maxConsecutiveImmediateRerenders) {
|
|
18231
|
+
console.warn(`[Cascade] Too many consecutive immediate re-renders (${this.consecutiveImmediateRerenders}), forcing delay`);
|
|
18232
|
+
this.consecutiveImmediateRerenders = 0;
|
|
18233
|
+
this.immediateRerenderRequested = false;
|
|
18234
|
+
this.renderTimeout = setTimeout(() => {
|
|
18235
|
+
this.renderTimeout = null;
|
|
18236
|
+
this.loop();
|
|
18237
|
+
}, 100);
|
|
18238
|
+
return;
|
|
18239
|
+
}
|
|
18240
|
+
}
|
|
18074
18241
|
const targetFrameTime = this.immediateRerenderRequested ? this.minTargetFrameTime : this.targetFrameTime;
|
|
18075
18242
|
const delay = Math.max(1, targetFrameTime - Math.floor(overallFrameTime));
|
|
18076
18243
|
this.immediateRerenderRequested = false;
|
|
@@ -18354,5 +18521,5 @@ Captured output:
|
|
|
18354
18521
|
|
|
18355
18522
|
export { __toESM, __commonJS, __export, __require, Edge, Gutter, MeasureMode, exports_src, isValidBorderStyle, parseBorderStyle, BorderChars, getBorderFromSides, getBorderSides, borderCharsToArray, BorderCharArrays, nonAlphanumericKeys, parseKeypress, KeyEvent, PasteEvent, KeyHandler, InternalKeyHandler, RGBA, hexToRgb, rgbToHex, hsvToRgb, parseColor, fonts, measureText, getCharacterPositions, coordinateToCharacterIndex, renderFontToFrameBuffer, TextAttributes, ATTRIBUTE_BASE_BITS, ATTRIBUTE_BASE_MASK, getBaseAttributes, DebugOverlayCorner, createTextAttributes, attributesWithLink, getLinkId, 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, link, t, hastToStyledText, LinearScrollAccel, MacOSScrollAccel, StdinBuffer, parseAlign, parseAlignItems, parseBoxSizing, parseDimension, parseDirection, parseDisplay, parseEdge, parseFlexDirection, parseGutter, parseJustify, parseLogLevel, parseMeasureMode, parseOverflow, parsePositionType, parseUnit, parseWrap, MouseParser, Selection, convertGlobalToLocalSelection, ASCIIFontSelectionHelper, envRegistry, registerEnvVar, clearEnvCache, generateEnvMarkdown, generateEnvColored, env, treeSitterToTextChunks, treeSitterToStyledText, addDefaultParsers, TreeSitterClient, DataPathsManager, getDataPaths, extToFiletype, pathToFiletype, main, getTreeSitterClient, ExtmarksController, createExtmarksController, TerminalPalette, createTerminalPalette, TextBuffer, SpanInfoStruct, LogLevel2 as LogLevel, setRenderLibPath, resolveRenderLib, OptimizedBuffer, h, isVNode, maybeMakeRenderable, wrapWithDelegates, instantiate, delegate, isValidPercentage, LayoutEvents, RenderableEvents, isRenderable, BaseRenderable, Renderable, RootRenderable, ANSI, defaultKeyAliases, mergeKeyAliases, mergeKeyBindings, getKeyBindingKey, buildKeyBindingsMap, capture, ConsolePosition, TerminalConsole, getObjectsInViewport, buildKittyKeyboardFlags, MouseEvent, MouseButton, createCliRenderer, CliRenderEvents, RendererControlState, CliRenderer };
|
|
18356
18523
|
|
|
18357
|
-
//# debugId=
|
|
18358
|
-
//# sourceMappingURL=index-
|
|
18524
|
+
//# debugId=D41C1FFE474972FF64756E2164756E21
|
|
18525
|
+
//# sourceMappingURL=index-gv8mtakv.js.map
|