@cascadetui/core 0.1.6 → 0.1.8

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-rj3f00a6.js";
9
+ } from "./index-r7vqrd61.js";
10
10
 
11
11
  // ../../node_modules/.bun/omggif@1.0.10/node_modules/omggif/omggif.js
12
12
  var require_omggif = __commonJS((exports) => {
package/Renderable.d.ts CHANGED
@@ -155,6 +155,15 @@ export declare abstract class Renderable extends BaseRenderable {
155
155
  private childrenPrimarySortDirty;
156
156
  private childrenSortedByPrimaryAxis;
157
157
  private _shouldUpdateBefore;
158
+ private renderRequestDepth;
159
+ private renderRequestPending;
160
+ private lastLayoutVersion;
161
+ protected dirtyLayout: boolean;
162
+ protected dirtyPaint: boolean;
163
+ protected dirtyStructure: boolean;
164
+ protected subtreeDirtyLayout: boolean;
165
+ protected subtreeDirtyPaint: boolean;
166
+ protected subtreeDirtyStructure: boolean;
158
167
  onLifecyclePass: (() => void) | null;
159
168
  renderBefore?: (this: Renderable, buffer: OptimizedBuffer, deltaTime: number) => void;
160
169
  renderAfter?: (this: Renderable, buffer: OptimizedBuffer, deltaTime: number) => void;
@@ -186,7 +195,16 @@ export declare abstract class Renderable extends BaseRenderable {
186
195
  handleKeyPress?(key: KeyEvent): boolean;
187
196
  handlePaste?(event: PasteEvent): void;
188
197
  findDescendantById(id: string): Renderable | undefined;
198
+ protected markClean(): void;
199
+ private markSubtreeDirtyPaint;
200
+ private markSubtreeDirtyLayout;
201
+ private markSubtreeDirtyStructure;
202
+ protected markDirtyPaint(): void;
203
+ protected markDirtyLayout(): void;
204
+ protected markDirtyStructure(): void;
189
205
  requestRender(): void;
206
+ protected beginRenderBatch(): void;
207
+ protected endRenderBatch(): void;
190
208
  get translateX(): number;
191
209
  set translateX(value: number);
192
210
  get translateY(): number;
@@ -260,6 +278,10 @@ export declare abstract class Renderable extends BaseRenderable {
260
278
  private assertCanAdoptChild;
261
279
  add(obj: Renderable | VNode<any, any[]> | unknown, index?: number): number;
262
280
  insertBefore(obj: Renderable | VNode<any, any[]> | unknown, anchor?: Renderable | unknown): number;
281
+ replaceChildren(nextChildren: Array<Renderable | VNode<any, any[]> | unknown>, options?: {
282
+ destroyRemoved?: boolean;
283
+ }): void;
284
+ setChildren(nextChildren: Array<Renderable | VNode<any, any[]> | unknown>): void;
263
285
  getRenderable(id: string): Renderable | undefined;
264
286
  remove(id: string): void;
265
287
  protected onRemove(): void;
@@ -329,6 +351,8 @@ interface RenderCommandPopOpacity extends RenderCommandBase {
329
351
  export type RenderCommand = RenderCommandPushScissorRect | RenderCommandPopScissorRect | RenderCommandRender | RenderCommandPushOpacity | RenderCommandPopOpacity;
330
352
  export declare class RootRenderable extends Renderable {
331
353
  private renderList;
354
+ private renderListDirty;
355
+ private lastRenderListLayoutVersion;
332
356
  constructor(ctx: RenderContext);
333
357
  render(buffer: OptimizedBuffer, deltaTime: number): void;
334
358
  protected propagateLiveCount(delta: number): void;
@@ -13370,6 +13370,15 @@ class Renderable extends BaseRenderable {
13370
13370
  childrenPrimarySortDirty = true;
13371
13371
  childrenSortedByPrimaryAxis = [];
13372
13372
  _shouldUpdateBefore = new Set;
13373
+ renderRequestDepth = 0;
13374
+ renderRequestPending = false;
13375
+ lastLayoutVersion = -1;
13376
+ dirtyLayout = false;
13377
+ dirtyPaint = false;
13378
+ dirtyStructure = false;
13379
+ subtreeDirtyLayout = false;
13380
+ subtreeDirtyPaint = false;
13381
+ subtreeDirtyStructure = false;
13373
13382
  onLifecyclePass = null;
13374
13383
  renderBefore;
13375
13384
  renderAfter;
@@ -13434,6 +13443,7 @@ class Renderable extends BaseRenderable {
13434
13443
  const wasVisible = this._visible;
13435
13444
  this._visible = value;
13436
13445
  this.yogaNode.setDisplay(value ? Display.Flex : Display.None);
13446
+ this.markDirtyStructure();
13437
13447
  if (this._live) {
13438
13448
  if (!wasVisible && value) {
13439
13449
  this.propagateLiveCount(1);
@@ -13453,6 +13463,7 @@ class Renderable extends BaseRenderable {
13453
13463
  const clamped = Math.max(0, Math.min(1, value));
13454
13464
  if (this._opacity !== clamped) {
13455
13465
  this._opacity = clamped;
13466
+ this.markDirtyStructure();
13456
13467
  this.requestRender();
13457
13468
  }
13458
13469
  }
@@ -13566,10 +13577,68 @@ class Renderable extends BaseRenderable {
13566
13577
  }
13567
13578
  return;
13568
13579
  }
13580
+ markClean() {
13581
+ super.markClean();
13582
+ this.dirtyPaint = false;
13583
+ }
13584
+ markSubtreeDirtyPaint(force = false) {
13585
+ if (this.subtreeDirtyPaint)
13586
+ return;
13587
+ this.subtreeDirtyPaint = true;
13588
+ if (this.parent && (force || this._visible)) {
13589
+ this.parent.markSubtreeDirtyPaint(force);
13590
+ }
13591
+ }
13592
+ markSubtreeDirtyLayout(force = false) {
13593
+ if (this.subtreeDirtyLayout)
13594
+ return;
13595
+ this.subtreeDirtyLayout = true;
13596
+ if (this.parent && (force || this._visible)) {
13597
+ this.parent.markSubtreeDirtyLayout(force);
13598
+ }
13599
+ }
13600
+ markSubtreeDirtyStructure(force = false) {
13601
+ if (this.subtreeDirtyStructure)
13602
+ return;
13603
+ this.subtreeDirtyStructure = true;
13604
+ if (this.parent && (force || this._visible)) {
13605
+ this.parent.markSubtreeDirtyStructure(force);
13606
+ }
13607
+ }
13608
+ markDirtyPaint() {
13609
+ this.dirtyPaint = true;
13610
+ this.markSubtreeDirtyPaint();
13611
+ }
13612
+ markDirtyLayout() {
13613
+ this.dirtyLayout = true;
13614
+ this.markSubtreeDirtyLayout();
13615
+ }
13616
+ markDirtyStructure() {
13617
+ this.dirtyStructure = true;
13618
+ this.markSubtreeDirtyStructure(true);
13619
+ this.markDirtyLayout();
13620
+ }
13569
13621
  requestRender() {
13570
13622
  this.markDirty();
13623
+ this.markDirtyPaint();
13624
+ if (this.renderRequestDepth > 0) {
13625
+ this.renderRequestPending = true;
13626
+ return;
13627
+ }
13571
13628
  this._ctx.requestRender();
13572
13629
  }
13630
+ beginRenderBatch() {
13631
+ this.renderRequestDepth += 1;
13632
+ }
13633
+ endRenderBatch() {
13634
+ if (this.renderRequestDepth === 0)
13635
+ return;
13636
+ this.renderRequestDepth -= 1;
13637
+ if (this.renderRequestDepth === 0 && this.renderRequestPending) {
13638
+ this.renderRequestPending = false;
13639
+ this._ctx.requestRender();
13640
+ }
13641
+ }
13573
13642
  get translateX() {
13574
13643
  return this._translateX;
13575
13644
  }
@@ -13579,6 +13648,7 @@ class Renderable extends BaseRenderable {
13579
13648
  this._translateX = value;
13580
13649
  if (this.parent)
13581
13650
  this.parent.childrenPrimarySortDirty = true;
13651
+ this.markDirtyStructure();
13582
13652
  this.requestRender();
13583
13653
  }
13584
13654
  get translateY() {
@@ -13590,6 +13660,7 @@ class Renderable extends BaseRenderable {
13590
13660
  this._translateY = value;
13591
13661
  if (this.parent)
13592
13662
  this.parent.childrenPrimarySortDirty = true;
13663
+ this.markDirtyStructure();
13593
13664
  this.requestRender();
13594
13665
  }
13595
13666
  get x() {
@@ -14043,6 +14114,7 @@ class Renderable extends BaseRenderable {
14043
14114
  }
14044
14115
  onLayoutResize(width, height) {
14045
14116
  if (this._visible) {
14117
+ this.markDirtyLayout();
14046
14118
  this.handleFrameBufferResize(width, height);
14047
14119
  this.onResize(width, height);
14048
14120
  this.requestRender();
@@ -14105,6 +14177,9 @@ class Renderable extends BaseRenderable {
14105
14177
  if (!obj) {
14106
14178
  return -1;
14107
14179
  }
14180
+ const trace = this._ctx.trace;
14181
+ const traceEnabled = trace?.enabled === true;
14182
+ const traceStart = traceEnabled ? trace.now() : 0;
14108
14183
  const renderable = maybeMakeRenderable(this._ctx, obj);
14109
14184
  if (!renderable) {
14110
14185
  return -1;
@@ -14141,7 +14216,11 @@ class Renderable extends BaseRenderable {
14141
14216
  this.yogaNode.insertChild(childLayoutNode, insertedIndex);
14142
14217
  this.childrenPrimarySortDirty = true;
14143
14218
  this._shouldUpdateBefore.add(renderable);
14219
+ this.markDirtyStructure();
14144
14220
  this.requestRender();
14221
+ if (traceEnabled) {
14222
+ trace.write(`trace.container.add id=${this.id} child=${renderable.id} index=${insertedIndex} ms=${(trace.now() - traceStart).toFixed(3)}`);
14223
+ }
14145
14224
  return insertedIndex;
14146
14225
  }
14147
14226
  insertBefore(obj, anchor) {
@@ -14151,6 +14230,9 @@ class Renderable extends BaseRenderable {
14151
14230
  if (!obj) {
14152
14231
  return -1;
14153
14232
  }
14233
+ const trace = this._ctx.trace;
14234
+ const traceEnabled = trace?.enabled === true;
14235
+ const traceStart = traceEnabled ? trace.now() : 0;
14154
14236
  const renderable = maybeMakeRenderable(this._ctx, obj);
14155
14237
  if (!renderable) {
14156
14238
  return -1;
@@ -14204,9 +14286,120 @@ class Renderable extends BaseRenderable {
14204
14286
  this._childrenInLayoutOrder.splice(insertedIndex, 0, renderable);
14205
14287
  this.yogaNode.insertChild(renderable.getLayoutNode(), insertedIndex);
14206
14288
  this._shouldUpdateBefore.add(renderable);
14289
+ this.markDirtyStructure();
14207
14290
  this.requestRender();
14291
+ if (traceEnabled) {
14292
+ trace.write(`trace.container.insertBefore id=${this.id} child=${renderable.id} index=${insertedIndex} ms=${(trace.now() - traceStart).toFixed(3)}`);
14293
+ }
14208
14294
  return insertedIndex;
14209
14295
  }
14296
+ replaceChildren(nextChildren, options) {
14297
+ const trace = this._ctx.trace;
14298
+ const traceEnabled = trace?.enabled === true;
14299
+ const traceStart = traceEnabled ? trace.now() : 0;
14300
+ const destroyRemoved = options?.destroyRemoved ?? false;
14301
+ this.beginRenderBatch();
14302
+ let removedCount = 0;
14303
+ let addedCount = 0;
14304
+ let orderChanged = false;
14305
+ try {
14306
+ const nextRenderables = [];
14307
+ const nextIds = new Set;
14308
+ const added = [];
14309
+ for (const child of nextChildren ?? []) {
14310
+ if (!child)
14311
+ continue;
14312
+ const renderable = maybeMakeRenderable(this._ctx, child);
14313
+ if (!renderable)
14314
+ continue;
14315
+ if (renderable.isDestroyed)
14316
+ continue;
14317
+ if (nextIds.has(renderable.id))
14318
+ continue;
14319
+ this.assertCanAdoptChild(renderable);
14320
+ if (renderable.parent !== this) {
14321
+ this.replaceParent(renderable);
14322
+ this.needsZIndexSort = true;
14323
+ this.renderableMapById.set(renderable.id, renderable);
14324
+ this._childrenInZIndexOrder.push(renderable);
14325
+ if (typeof renderable.onLifecyclePass === "function") {
14326
+ this._ctx.registerLifecyclePass(renderable);
14327
+ }
14328
+ if (renderable._liveCount > 0) {
14329
+ this.propagateLiveCount(renderable._liveCount);
14330
+ }
14331
+ added.push(renderable);
14332
+ }
14333
+ nextRenderables.push(renderable);
14334
+ nextIds.add(renderable.id);
14335
+ }
14336
+ const previousChildren = this._childrenInLayoutOrder;
14337
+ const removed = [];
14338
+ if (previousChildren.length > 0) {
14339
+ for (const child of previousChildren) {
14340
+ if (!nextIds.has(child.id)) {
14341
+ removed.push(child);
14342
+ }
14343
+ }
14344
+ }
14345
+ removedCount = removed.length;
14346
+ addedCount = added.length;
14347
+ if (removed.length > 0) {
14348
+ for (const child of removed) {
14349
+ if (child._liveCount > 0) {
14350
+ this.propagateLiveCount(-child._liveCount);
14351
+ }
14352
+ child.onRemove();
14353
+ child.parent = null;
14354
+ this._ctx.unregisterLifecyclePass(child);
14355
+ this.renderableMapById.delete(child.id);
14356
+ }
14357
+ this._childrenInZIndexOrder = this._childrenInZIndexOrder.filter((child) => nextIds.has(child.id));
14358
+ }
14359
+ if (previousChildren.length !== nextRenderables.length) {
14360
+ orderChanged = true;
14361
+ } else {
14362
+ for (let i = 0;i < previousChildren.length; i += 1) {
14363
+ if (previousChildren[i] !== nextRenderables[i]) {
14364
+ orderChanged = true;
14365
+ break;
14366
+ }
14367
+ }
14368
+ }
14369
+ if (orderChanged) {
14370
+ for (const child of previousChildren) {
14371
+ this.yogaNode.removeChild(child.getLayoutNode());
14372
+ }
14373
+ for (let i = 0;i < nextRenderables.length; i += 1) {
14374
+ this.yogaNode.insertChild(nextRenderables[i].getLayoutNode(), i);
14375
+ }
14376
+ }
14377
+ this._childrenInLayoutOrder = nextRenderables;
14378
+ if (added.length > 0) {
14379
+ for (const child of added) {
14380
+ this._shouldUpdateBefore.add(child);
14381
+ }
14382
+ }
14383
+ if (orderChanged || removed.length > 0 || added.length > 0) {
14384
+ this.childrenPrimarySortDirty = true;
14385
+ this.markDirtyStructure();
14386
+ this.requestRender();
14387
+ }
14388
+ if (destroyRemoved) {
14389
+ for (const child of removed) {
14390
+ child.destroyRecursively();
14391
+ }
14392
+ }
14393
+ } finally {
14394
+ this.endRenderBatch();
14395
+ }
14396
+ if (traceEnabled) {
14397
+ trace.write(`trace.container.replaceChildren id=${this.id} next=${this._childrenInLayoutOrder.length} added=${addedCount} removed=${removedCount} reordered=${orderChanged} ms=${(trace.now() - traceStart).toFixed(3)}`);
14398
+ }
14399
+ }
14400
+ setChildren(nextChildren) {
14401
+ this.replaceChildren(nextChildren);
14402
+ }
14210
14403
  getRenderable(id) {
14211
14404
  return this.renderableMapById.get(id);
14212
14405
  }
@@ -14214,6 +14407,9 @@ class Renderable extends BaseRenderable {
14214
14407
  if (!id) {
14215
14408
  return;
14216
14409
  }
14410
+ const trace = this._ctx.trace;
14411
+ const traceEnabled = trace?.enabled === true;
14412
+ const traceStart = traceEnabled ? trace.now() : 0;
14217
14413
  if (this.renderableMapById.has(id)) {
14218
14414
  const obj = this.renderableMapById.get(id);
14219
14415
  if (obj) {
@@ -14222,6 +14418,7 @@ class Renderable extends BaseRenderable {
14222
14418
  }
14223
14419
  const childLayoutNode = obj.getLayoutNode();
14224
14420
  this.yogaNode.removeChild(childLayoutNode);
14421
+ this.markDirtyStructure();
14225
14422
  this.requestRender();
14226
14423
  obj.onRemove();
14227
14424
  obj.parent = null;
@@ -14238,6 +14435,9 @@ class Renderable extends BaseRenderable {
14238
14435
  this.childrenPrimarySortDirty = true;
14239
14436
  }
14240
14437
  }
14438
+ if (traceEnabled) {
14439
+ trace.write(`trace.container.remove id=${this.id} child=${id} ms=${(trace.now() - traceStart).toFixed(3)}`);
14440
+ }
14241
14441
  }
14242
14442
  onRemove() {}
14243
14443
  getChildren() {
@@ -14252,11 +14452,16 @@ class Renderable extends BaseRenderable {
14252
14452
  this.onUpdate(deltaTime);
14253
14453
  if (this._isDestroyed)
14254
14454
  return;
14255
- this.updateFromLayout();
14455
+ const layoutVersion = this._ctx.layoutVersion;
14456
+ if (this.lastLayoutVersion !== layoutVersion) {
14457
+ this.updateFromLayout();
14458
+ this.lastLayoutVersion = layoutVersion;
14459
+ }
14256
14460
  if (this._shouldUpdateBefore.size > 0) {
14257
14461
  for (const child of this._shouldUpdateBefore) {
14258
14462
  if (!child.isDestroyed) {
14259
14463
  child.updateFromLayout();
14464
+ child.lastLayoutVersion = layoutVersion;
14260
14465
  }
14261
14466
  }
14262
14467
  this._shouldUpdateBefore.clear();
@@ -14283,13 +14488,39 @@ class Renderable extends BaseRenderable {
14283
14488
  });
14284
14489
  }
14285
14490
  const visibleChildren = this._getVisibleChildren();
14286
- for (const child of this._childrenInZIndexOrder) {
14287
- if (!visibleChildren.includes(child.num)) {
14288
- child.updateFromLayout();
14289
- continue;
14491
+ if (visibleChildren.length === this._childrenInZIndexOrder.length) {
14492
+ for (const child of this._childrenInZIndexOrder) {
14493
+ child.updateLayout(deltaTime, renderList);
14494
+ }
14495
+ } else {
14496
+ const visibleSet = new Set(visibleChildren);
14497
+ for (const child of this._childrenInZIndexOrder) {
14498
+ if (!visibleSet.has(child.num)) {
14499
+ if (child.lastLayoutVersion !== layoutVersion) {
14500
+ child.updateFromLayout();
14501
+ child.lastLayoutVersion = layoutVersion;
14502
+ }
14503
+ continue;
14504
+ }
14505
+ child.updateLayout(deltaTime, renderList);
14290
14506
  }
14291
- child.updateLayout(deltaTime, renderList);
14292
14507
  }
14508
+ let hasDirtyStructure = this.dirtyStructure;
14509
+ let hasDirtyLayout = this.dirtyLayout;
14510
+ let hasDirtyPaint = this.dirtyPaint;
14511
+ for (const child of this._childrenInZIndexOrder) {
14512
+ if (child.subtreeDirtyStructure)
14513
+ hasDirtyStructure = true;
14514
+ if (child.subtreeDirtyLayout)
14515
+ hasDirtyLayout = true;
14516
+ if (child.subtreeDirtyPaint)
14517
+ hasDirtyPaint = true;
14518
+ }
14519
+ this.dirtyStructure = false;
14520
+ this.dirtyLayout = false;
14521
+ this.subtreeDirtyStructure = hasDirtyStructure;
14522
+ this.subtreeDirtyLayout = hasDirtyLayout;
14523
+ this.subtreeDirtyPaint = hasDirtyPaint;
14293
14524
  if (shouldPushScissor) {
14294
14525
  renderList.push({ action: "popScissorRect" });
14295
14526
  }
@@ -14343,7 +14574,10 @@ class Renderable extends BaseRenderable {
14343
14574
  this.frameBuffer.destroy();
14344
14575
  this.frameBuffer = null;
14345
14576
  }
14346
- for (const child of this._childrenInLayoutOrder) {
14577
+ while (this._childrenInLayoutOrder.length > 0) {
14578
+ const child = this._childrenInLayoutOrder[0];
14579
+ if (!child)
14580
+ break;
14347
14581
  this.remove(child.id);
14348
14582
  }
14349
14583
  this._childrenInLayoutOrder = [];
@@ -14476,6 +14710,8 @@ class Renderable extends BaseRenderable {
14476
14710
 
14477
14711
  class RootRenderable extends Renderable {
14478
14712
  renderList = [];
14713
+ renderListDirty = true;
14714
+ lastRenderListLayoutVersion = -1;
14479
14715
  constructor(ctx) {
14480
14716
  super(ctx, { id: "__root__", zIndex: 0, visible: true, width: ctx.width, height: ctx.height, enableLayout: true });
14481
14717
  if (this.yogaNode) {
@@ -14490,14 +14726,38 @@ class RootRenderable extends Renderable {
14490
14726
  render(buffer, deltaTime) {
14491
14727
  if (!this.visible)
14492
14728
  return;
14729
+ const trace = this._ctx.trace;
14730
+ const traceEnabled = trace?.enabled === true;
14493
14731
  for (const renderable of this._ctx.getLifecyclePasses()) {
14494
14732
  renderable.onLifecyclePass?.call(renderable);
14495
14733
  }
14734
+ const layoutStart = traceEnabled ? trace.now() : 0;
14496
14735
  if (this.yogaNode.isDirty()) {
14497
14736
  this.calculateLayout();
14498
14737
  }
14499
- this.renderList.length = 0;
14500
- this.updateLayout(deltaTime, this.renderList);
14738
+ const layoutMs = traceEnabled ? trace.now() - layoutStart : 0;
14739
+ const layoutVersion = this._ctx.layoutVersion;
14740
+ if (this.renderList.length === 0) {
14741
+ this.renderListDirty = true;
14742
+ }
14743
+ if (this.subtreeDirtyStructure || this.subtreeDirtyLayout) {
14744
+ this.renderListDirty = true;
14745
+ }
14746
+ if (layoutVersion !== this.lastRenderListLayoutVersion) {
14747
+ this.renderListDirty = true;
14748
+ }
14749
+ let updateMs = 0;
14750
+ let renderListBuildMs = 0;
14751
+ if (this.renderListDirty) {
14752
+ const updateStart = traceEnabled ? trace.now() : 0;
14753
+ this.renderList.length = 0;
14754
+ this.updateLayout(deltaTime, this.renderList);
14755
+ updateMs = traceEnabled ? trace.now() - updateStart : 0;
14756
+ renderListBuildMs = updateMs;
14757
+ this.renderListDirty = false;
14758
+ this.lastRenderListLayoutVersion = layoutVersion;
14759
+ }
14760
+ const renderStart = traceEnabled ? trace.now() : 0;
14501
14761
  this._ctx.clearHitGridScissorRects();
14502
14762
  for (let i = 1;i < this.renderList.length; i++) {
14503
14763
  const command = this.renderList[i];
@@ -14523,6 +14783,13 @@ class RootRenderable extends Renderable {
14523
14783
  break;
14524
14784
  }
14525
14785
  }
14786
+ if (traceEnabled) {
14787
+ const drawMs = trace.now() - renderStart;
14788
+ trace.write(`trace.render.layout ms=${layoutMs.toFixed(3)}`);
14789
+ trace.write(`trace.render.updateTraversal ms=${updateMs.toFixed(3)}`);
14790
+ trace.write(`trace.render.renderListBuild ms=${renderListBuildMs.toFixed(3)} count=${this.renderList.length}`);
14791
+ trace.write(`trace.render.draw ms=${drawMs.toFixed(3)}`);
14792
+ }
14526
14793
  }
14527
14794
  propagateLiveCount(delta) {
14528
14795
  const oldCount = this._liveCount;
@@ -14535,6 +14802,7 @@ class RootRenderable extends Renderable {
14535
14802
  }
14536
14803
  calculateLayout() {
14537
14804
  this.yogaNode.calculateLayout(this.width, this.height, Direction.LTR);
14805
+ this._ctx.layoutVersion += 1;
14538
14806
  this.emit("layout-changed" /* LAYOUT_CHANGED */);
14539
14807
  }
14540
14808
  resize(width, height) {
@@ -16283,6 +16551,8 @@ class CliRenderer extends EventEmitter9 {
16283
16551
  arrayBuffers: 0
16284
16552
  };
16285
16553
  root;
16554
+ trace;
16555
+ layoutVersion = 0;
16286
16556
  width;
16287
16557
  height;
16288
16558
  _useThread = false;
@@ -16483,6 +16753,17 @@ Captured output:
16483
16753
  this.nextRenderBuffer = this.lib.getNextBuffer(this.rendererPtr);
16484
16754
  this.currentRenderBuffer = this.lib.getCurrentBuffer(this.rendererPtr);
16485
16755
  this.postProcessFns = config.postProcessFns || [];
16756
+ if (config.trace) {
16757
+ const writer = config.traceWriter ?? ((line) => {
16758
+ this.realStdoutWrite.call(this.stdout, `${line}
16759
+ `);
16760
+ });
16761
+ this.trace = {
16762
+ enabled: true,
16763
+ now: () => performance.now(),
16764
+ write: writer
16765
+ };
16766
+ }
16486
16767
  this.prependedInputHandlers = config.prependInputHandlers || [];
16487
16768
  this.root = new RootRenderable(this);
16488
16769
  if (this.memorySnapshotInterval > 0) {
@@ -17695,6 +17976,8 @@ Captured output:
17695
17976
  this.renderStats.frameCount++;
17696
17977
  this.renderStats.fps = this.currentFps;
17697
17978
  const overallStart = performance.now();
17979
+ const trace = this.trace;
17980
+ const traceEnabled = trace?.enabled === true;
17698
17981
  const frameRequests = Array.from(this.animationRequest.values());
17699
17982
  this.animationRequest.clear();
17700
17983
  const animationRequestStart = performance.now();
@@ -17715,17 +17998,27 @@ Captured output:
17715
17998
  }
17716
17999
  const end = performance.now();
17717
18000
  this.renderStats.frameCallbackTime = end - start;
18001
+ const renderTreeStart = traceEnabled ? trace.now() : 0;
17718
18002
  this.root.render(this.nextRenderBuffer, deltaTime);
18003
+ const renderTreeMs = traceEnabled ? trace.now() - renderTreeStart : 0;
18004
+ const postProcessStart = traceEnabled ? trace.now() : 0;
17719
18005
  for (const postProcessFn of this.postProcessFns) {
17720
18006
  postProcessFn(this.nextRenderBuffer, deltaTime);
17721
18007
  }
17722
18008
  this._console.renderToBuffer(this.nextRenderBuffer);
18009
+ const postProcessMs = traceEnabled ? trace.now() - postProcessStart : 0;
17723
18010
  if (!this._isDestroyed) {
18011
+ const nativeStart = traceEnabled ? trace.now() : 0;
17724
18012
  this.renderNative();
18013
+ const nativeMs = traceEnabled ? trace.now() - nativeStart : 0;
17725
18014
  if (this._useMouse && this.lib.getHitGridDirty(this.rendererPtr)) {
17726
18015
  this.recheckHoverState();
17727
18016
  }
17728
18017
  const overallFrameTime = performance.now() - overallStart;
18018
+ if (traceEnabled) {
18019
+ trace.write(`trace.render.native ms=${nativeMs.toFixed(3)}`);
18020
+ 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)}`);
18021
+ }
17729
18022
  this.lib.updateStats(this.rendererPtr, overallFrameTime, this.renderStats.fps, this.renderStats.frameCallbackTime);
17730
18023
  if (this.gatherStats) {
17731
18024
  this.collectStatSample(overallFrameTime);
@@ -17996,5 +18289,5 @@ Captured output:
17996
18289
 
17997
18290
  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 };
17998
18291
 
17999
- //# debugId=F994E7E6202035C864756E2164756E21
18000
- //# sourceMappingURL=index-rj3f00a6.js.map
18292
+ //# debugId=A43FA725E26A0ABA64756E2164756E21
18293
+ //# sourceMappingURL=index-r7vqrd61.js.map