@gnsx/three 0.184.18 → 0.184.19

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/build/three.cjs CHANGED
@@ -59733,7 +59733,7 @@ class ProfilerServiceClass {
59733
59733
  this._profile = 'full';
59734
59734
  this._enabled = false;
59735
59735
 
59736
- /** @type {Map<string, Float64Array>} */
59736
+ /** @type {Map<string, Float64Array>} Inclusive time ring buffers (one per label). */
59737
59737
  this.buffers = new Map();
59738
59738
  /** @type {Map<string, number>} */
59739
59739
  this.cursors = new Map();
@@ -59746,6 +59746,20 @@ class ProfilerServiceClass {
59746
59746
  this.traceStartTime = 0;
59747
59747
  this._markId = 0;
59748
59748
 
59749
+ /** @type {Map<string, Float64Array>} Exclusive (self) time ring buffers (one per label). */
59750
+ this.selfBuffers = new Map();
59751
+ /** @type {Map<string, number>} */
59752
+ this.selfCursors = new Map();
59753
+ /** @type {Map<string, number>} */
59754
+ this.selfCounts = new Map();
59755
+ /**
59756
+ * Global call stack tracking nesting across all labels for exclusive-time computation.
59757
+ * @type {Array<{ label: string, childTime: number }>}
59758
+ */
59759
+ this.callStack = [];
59760
+ /** @type {Map<string, number>} Total (uncapped) invocation count since last reset, for calls-per-frame. */
59761
+ this.invocations = new Map();
59762
+
59749
59763
  if ( this._enabled ) {
59750
59764
 
59751
59765
  this.traceStartTime = performance.now();
@@ -59852,6 +59866,9 @@ class ProfilerServiceClass {
59852
59866
  performance.mark( startMark );
59853
59867
  stack.push( { startTime, startMark, traced } );
59854
59868
 
59869
+ // Push onto the global call stack for exclusive-time tracking.
59870
+ this.callStack.push( { label, childTime: 0 } );
59871
+
59855
59872
  }
59856
59873
 
59857
59874
  /**
@@ -59887,6 +59904,42 @@ class ProfilerServiceClass {
59887
59904
  this.cursors.set( label, ( cursor + 1 ) % RING_SIZE );
59888
59905
  this.counts.set( label, Math.min( ( this.counts.get( label ) + 1 ), RING_SIZE ) );
59889
59906
 
59907
+ // Track total invocations (uncapped) for calls-per-frame computation.
59908
+ this.invocations.set( label, ( this.invocations.get( label ) ?? 0 ) + 1 );
59909
+
59910
+ // Exclusive (self) time via the global call stack.
59911
+ const top = this.callStack.length > 0 ? this.callStack[ this.callStack.length - 1 ] : undefined;
59912
+ if ( top !== undefined && top.label === label ) {
59913
+
59914
+ this.callStack.pop();
59915
+ const selfTime = Math.max( 0, duration - top.childTime );
59916
+
59917
+ let selfBuffer = this.selfBuffers.get( label );
59918
+ if ( ! selfBuffer ) {
59919
+
59920
+ selfBuffer = new Float64Array( RING_SIZE );
59921
+ this.selfBuffers.set( label, selfBuffer );
59922
+ this.selfCursors.set( label, 0 );
59923
+ this.selfCounts.set( label, 0 );
59924
+
59925
+ }
59926
+
59927
+ const selfCursor = this.selfCursors.get( label );
59928
+ selfBuffer[ selfCursor ] = selfTime;
59929
+ this.selfCursors.set( label, ( selfCursor + 1 ) % RING_SIZE );
59930
+ this.selfCounts.set( label, Math.min( ( this.selfCounts.get( label ) + 1 ), RING_SIZE ) );
59931
+
59932
+ // Propagate inclusive duration to the parent scope's child accumulator.
59933
+ const parent = this.callStack.length > 0 ? this.callStack[ this.callStack.length - 1 ] : undefined;
59934
+ if ( parent !== undefined ) parent.childTime += duration;
59935
+
59936
+ } else {
59937
+
59938
+ // Label mismatch — likely async interleaving. Reset to avoid corruption.
59939
+ this.callStack.length = 0;
59940
+
59941
+ }
59942
+
59890
59943
  if ( traced ) {
59891
59944
 
59892
59945
  this.traceEvents.push( {
@@ -59929,6 +59982,23 @@ class ProfilerServiceClass {
59929
59982
  const sorted = [ ...samples ].sort( ( a, b ) => a - b );
59930
59983
  const avg = sorted.reduce( ( a, b ) => a + b, 0 ) / sorted.length;
59931
59984
 
59985
+ // Exclusive (self) time stats.
59986
+ const selfCount = this.selfCounts.get( label ) ?? 0;
59987
+ let selfAvg, selfMin, selfMax, selfP95, selfFrameBudget;
59988
+ if ( selfCount > 0 ) {
59989
+
59990
+ const selfBuffer = this.selfBuffers.get( label );
59991
+ const selfSamples = [ ...( selfCount < RING_SIZE
59992
+ ? selfBuffer.subarray( 0, selfCount )
59993
+ : selfBuffer ) ].sort( ( a, b ) => a - b );
59994
+ selfAvg = selfSamples.reduce( ( a, b ) => a + b, 0 ) / selfSamples.length;
59995
+ selfMin = selfSamples[ 0 ];
59996
+ selfMax = selfSamples[ selfSamples.length - 1 ];
59997
+ selfP95 = selfSamples[ Math.floor( selfSamples.length * 0.95 ) ];
59998
+ selfFrameBudget = ( selfAvg / FRAME_BUDGET_MS ) * 100;
59999
+
60000
+ }
60001
+
59932
60002
  return {
59933
60003
  label,
59934
60004
  samples: samples.length,
@@ -59937,6 +60007,12 @@ class ProfilerServiceClass {
59937
60007
  max: sorted[ sorted.length - 1 ],
59938
60008
  p95: sorted[ Math.floor( sorted.length * 0.95 ) ],
59939
60009
  frameBudget: ( avg / FRAME_BUDGET_MS ) * 100,
60010
+ totalInvocations: this.invocations.get( label ) ?? 0,
60011
+ selfAvg,
60012
+ selfMin,
60013
+ selfMax,
60014
+ selfP95,
60015
+ selfFrameBudget,
59940
60016
  };
59941
60017
 
59942
60018
  }
@@ -60059,6 +60135,11 @@ class ProfilerServiceClass {
60059
60135
  this.traceEvents = [];
60060
60136
  this.traceStartTime = performance.now();
60061
60137
  this._markId = 0;
60138
+ this.selfBuffers.clear();
60139
+ this.selfCursors.clear();
60140
+ this.selfCounts.clear();
60141
+ this.callStack.length = 0;
60142
+ this.invocations.clear();
60062
60143
 
60063
60144
  }
60064
60145
 
@@ -60080,6 +60161,12 @@ class ProfilerServiceClass {
60080
60161
  * @property {number} max
60081
60162
  * @property {number} p95
60082
60163
  * @property {number} frameBudget Percentage of a 60 fps frame budget (16.67 ms)
60164
+ * @property {number} totalInvocations Total (uncapped) call count since last reset, for calls-per-frame computation.
60165
+ * @property {number|undefined} selfAvg Exclusive (self) avg ms — inclusive time minus child scope time.
60166
+ * @property {number|undefined} selfMin
60167
+ * @property {number|undefined} selfMax
60168
+ * @property {number|undefined} selfP95
60169
+ * @property {number|undefined} selfFrameBudget Exclusive time as percentage of a 60 fps frame budget.
60083
60170
  */
60084
60171
 
60085
60172
  /**
@@ -59753,7 +59753,7 @@ class ProfilerServiceClass {
59753
59753
  this._profile = 'full';
59754
59754
  this._enabled = false;
59755
59755
 
59756
- /** @type {Map<string, Float64Array>} */
59756
+ /** @type {Map<string, Float64Array>} Inclusive time ring buffers (one per label). */
59757
59757
  this.buffers = new Map();
59758
59758
  /** @type {Map<string, number>} */
59759
59759
  this.cursors = new Map();
@@ -59766,6 +59766,20 @@ class ProfilerServiceClass {
59766
59766
  this.traceStartTime = 0;
59767
59767
  this._markId = 0;
59768
59768
 
59769
+ /** @type {Map<string, Float64Array>} Exclusive (self) time ring buffers (one per label). */
59770
+ this.selfBuffers = new Map();
59771
+ /** @type {Map<string, number>} */
59772
+ this.selfCursors = new Map();
59773
+ /** @type {Map<string, number>} */
59774
+ this.selfCounts = new Map();
59775
+ /**
59776
+ * Global call stack tracking nesting across all labels for exclusive-time computation.
59777
+ * @type {Array<{ label: string, childTime: number }>}
59778
+ */
59779
+ this.callStack = [];
59780
+ /** @type {Map<string, number>} Total (uncapped) invocation count since last reset, for calls-per-frame. */
59781
+ this.invocations = new Map();
59782
+
59769
59783
  if ( this._enabled ) {
59770
59784
 
59771
59785
  this.traceStartTime = performance.now();
@@ -59872,6 +59886,9 @@ class ProfilerServiceClass {
59872
59886
  performance.mark( startMark );
59873
59887
  stack.push( { startTime, startMark, traced } );
59874
59888
 
59889
+ // Push onto the global call stack for exclusive-time tracking.
59890
+ this.callStack.push( { label, childTime: 0 } );
59891
+
59875
59892
  }
59876
59893
 
59877
59894
  /**
@@ -59907,6 +59924,42 @@ class ProfilerServiceClass {
59907
59924
  this.cursors.set( label, ( cursor + 1 ) % RING_SIZE );
59908
59925
  this.counts.set( label, Math.min( ( this.counts.get( label ) + 1 ), RING_SIZE ) );
59909
59926
 
59927
+ // Track total invocations (uncapped) for calls-per-frame computation.
59928
+ this.invocations.set( label, ( this.invocations.get( label ) ?? 0 ) + 1 );
59929
+
59930
+ // Exclusive (self) time via the global call stack.
59931
+ const top = this.callStack.length > 0 ? this.callStack[ this.callStack.length - 1 ] : undefined;
59932
+ if ( top !== undefined && top.label === label ) {
59933
+
59934
+ this.callStack.pop();
59935
+ const selfTime = Math.max( 0, duration - top.childTime );
59936
+
59937
+ let selfBuffer = this.selfBuffers.get( label );
59938
+ if ( ! selfBuffer ) {
59939
+
59940
+ selfBuffer = new Float64Array( RING_SIZE );
59941
+ this.selfBuffers.set( label, selfBuffer );
59942
+ this.selfCursors.set( label, 0 );
59943
+ this.selfCounts.set( label, 0 );
59944
+
59945
+ }
59946
+
59947
+ const selfCursor = this.selfCursors.get( label );
59948
+ selfBuffer[ selfCursor ] = selfTime;
59949
+ this.selfCursors.set( label, ( selfCursor + 1 ) % RING_SIZE );
59950
+ this.selfCounts.set( label, Math.min( ( this.selfCounts.get( label ) + 1 ), RING_SIZE ) );
59951
+
59952
+ // Propagate inclusive duration to the parent scope's child accumulator.
59953
+ const parent = this.callStack.length > 0 ? this.callStack[ this.callStack.length - 1 ] : undefined;
59954
+ if ( parent !== undefined ) parent.childTime += duration;
59955
+
59956
+ } else {
59957
+
59958
+ // Label mismatch — likely async interleaving. Reset to avoid corruption.
59959
+ this.callStack.length = 0;
59960
+
59961
+ }
59962
+
59910
59963
  if ( traced ) {
59911
59964
 
59912
59965
  this.traceEvents.push( {
@@ -59949,6 +60002,23 @@ class ProfilerServiceClass {
59949
60002
  const sorted = [ ...samples ].sort( ( a, b ) => a - b );
59950
60003
  const avg = sorted.reduce( ( a, b ) => a + b, 0 ) / sorted.length;
59951
60004
 
60005
+ // Exclusive (self) time stats.
60006
+ const selfCount = this.selfCounts.get( label ) ?? 0;
60007
+ let selfAvg, selfMin, selfMax, selfP95, selfFrameBudget;
60008
+ if ( selfCount > 0 ) {
60009
+
60010
+ const selfBuffer = this.selfBuffers.get( label );
60011
+ const selfSamples = [ ...( selfCount < RING_SIZE
60012
+ ? selfBuffer.subarray( 0, selfCount )
60013
+ : selfBuffer ) ].sort( ( a, b ) => a - b );
60014
+ selfAvg = selfSamples.reduce( ( a, b ) => a + b, 0 ) / selfSamples.length;
60015
+ selfMin = selfSamples[ 0 ];
60016
+ selfMax = selfSamples[ selfSamples.length - 1 ];
60017
+ selfP95 = selfSamples[ Math.floor( selfSamples.length * 0.95 ) ];
60018
+ selfFrameBudget = ( selfAvg / FRAME_BUDGET_MS ) * 100;
60019
+
60020
+ }
60021
+
59952
60022
  return {
59953
60023
  label,
59954
60024
  samples: samples.length,
@@ -59957,6 +60027,12 @@ class ProfilerServiceClass {
59957
60027
  max: sorted[ sorted.length - 1 ],
59958
60028
  p95: sorted[ Math.floor( sorted.length * 0.95 ) ],
59959
60029
  frameBudget: ( avg / FRAME_BUDGET_MS ) * 100,
60030
+ totalInvocations: this.invocations.get( label ) ?? 0,
60031
+ selfAvg,
60032
+ selfMin,
60033
+ selfMax,
60034
+ selfP95,
60035
+ selfFrameBudget,
59960
60036
  };
59961
60037
 
59962
60038
  }
@@ -60079,6 +60155,11 @@ class ProfilerServiceClass {
60079
60155
  this.traceEvents = [];
60080
60156
  this.traceStartTime = performance.now();
60081
60157
  this._markId = 0;
60158
+ this.selfBuffers.clear();
60159
+ this.selfCursors.clear();
60160
+ this.selfCounts.clear();
60161
+ this.callStack.length = 0;
60162
+ this.invocations.clear();
60082
60163
 
60083
60164
  }
60084
60165
 
@@ -60100,6 +60181,12 @@ class ProfilerServiceClass {
60100
60181
  * @property {number} max
60101
60182
  * @property {number} p95
60102
60183
  * @property {number} frameBudget Percentage of a 60 fps frame budget (16.67 ms)
60184
+ * @property {number} totalInvocations Total (uncapped) call count since last reset, for calls-per-frame computation.
60185
+ * @property {number|undefined} selfAvg Exclusive (self) avg ms — inclusive time minus child scope time.
60186
+ * @property {number|undefined} selfMin
60187
+ * @property {number|undefined} selfMax
60188
+ * @property {number|undefined} selfP95
60189
+ * @property {number|undefined} selfFrameBudget Exclusive time as percentage of a 60 fps frame budget.
60103
60190
  */
60104
60191
 
60105
60192
  /**