@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 CHANGED
@@ -6,7 +6,7 @@ import {
6
6
  __export,
7
7
  __require,
8
8
  __toESM
9
- } from "./index-9j6zba34.js";
9
+ } from "./index-gv8mtakv.js";
10
10
 
11
11
  // ../../node_modules/.bun/omggif@1.0.10/node_modules/omggif/omggif.js
12
12
  var require_omggif = __commonJS((exports) => {
@@ -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 = `ffi_otui_debug_${timestamp}.log`;
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
- globalTraceSymbols[key].push(end - start);
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 = `ffi_otui_trace_${timestamp}.log`;
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=417D82C6F387312F64756E2164756E21
18358
- //# sourceMappingURL=index-9j6zba34.js.map
18524
+ //# debugId=D41C1FFE474972FF64756E2164756E21
18525
+ //# sourceMappingURL=index-gv8mtakv.js.map