@3dsource/angular-unreal-module 0.0.137 → 0.0.139

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.
@@ -5107,6 +5107,16 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.16", ngImpo
5107
5107
  type: Injectable
5108
5108
  }], ctorParameters: () => [] });
5109
5109
 
5110
+ /** Trim a resource URL to its path: drop origin and query string so the
5111
+ * emitted name is short, stable, and not a PII-bearing query. */
5112
+ function shortResourceName(url) {
5113
+ try {
5114
+ return new URL(url).pathname;
5115
+ }
5116
+ catch {
5117
+ return (url || '').split('?')[0];
5118
+ }
5119
+ }
5110
5120
  const QP_RED_THRESHOLD = 35;
5111
5121
  const FPS_LOW_RATIO = 0.7; // p50 fps below 70% of target
5112
5122
  const UNLIMITED_REFERENCE_FPS = 60;
@@ -5384,9 +5394,19 @@ class StreamStatusTelemetryService2 {
5384
5394
  }
5385
5395
  }
5386
5396
  init() {
5387
- // Start a new session on every initSignalling dispatch.
5397
+ // Start a new session when a real connection attempt BEGINS, not on
5398
+ // every `initSignalling` dispatch. `initSignalling` is fired multiple
5399
+ // times per page load (the unreal-scene effect, `startStream`, the
5400
+ // reconnect effect), but the connection layer collapses them into one
5401
+ // attempt via `connectToSignaling$` (`exhaustMap` + `!cirrusConnected`
5402
+ // filter). `setEstablishingConnection(true)` is dispatched exactly
5403
+ // once per real attempt from `SignallingService.startEstablishingConnection()`,
5404
+ // downstream of that guard — so binding here yields one session per
5405
+ // attempt instead of a burst of `restart` churn sessions. Genuine
5406
+ // reconnects (e.g. DataChannelTimeout) re-enter the same path and
5407
+ // correctly end the prior session as `restart` + start a new one.
5388
5408
  this.actions$
5389
- .pipe(ofType(initSignalling), takeUntil$1(this.destroy$))
5409
+ .pipe(ofType(setEstablishingConnection), filter$1(({ value }) => value === true), takeUntil$1(this.destroy$))
5390
5410
  .subscribe(() => this.startSession());
5391
5411
  // Action-stream end triggers (NOT a state-observable subscription).
5392
5412
  //
@@ -5787,6 +5807,9 @@ class StreamStatusTelemetryService2 {
5787
5807
  // attributes them to `HTML loading` and `Route idle` respectively.
5788
5808
  resources: split.resources,
5789
5809
  lazyResources: split.lazyResources,
5810
+ // Top-8 slowest individual resources (path + duration), so the viewer
5811
+ // can name the offending file / GraphQL endpoint.
5812
+ slowestResources: split.slowestResources,
5790
5813
  };
5791
5814
  }
5792
5815
  catch {
@@ -5815,19 +5838,22 @@ class StreamStatusTelemetryService2 {
5815
5838
  try {
5816
5839
  const list = performance.getEntriesByType('resource');
5817
5840
  if (!list.length)
5818
- return { resources: null, lazyResources: null };
5841
+ return { resources: null, lazyResources: null, slowestResources: [] };
5819
5842
  const empty = () => ({
5820
5843
  count: 0,
5821
5844
  cachedCount: 0,
5822
5845
  transferSize: 0,
5823
5846
  encodedBodySize: 0,
5824
5847
  decodedBodySize: 0,
5848
+ durationMs: 0,
5849
+ maxDurationMs: 0,
5825
5850
  });
5826
5851
  const splitEnabled = loadEventEnd > 0;
5827
5852
  const pageLoadTotals = empty();
5828
5853
  const pageLoadByType = {};
5829
5854
  const lazyTotals = empty();
5830
5855
  const lazyByType = {};
5856
+ const slow = []; // every timed resource; trimmed to top-N
5831
5857
  for (const r of list) {
5832
5858
  const type = r.initiatorType || 'other';
5833
5859
  const isLazy = splitEnabled && r.startTime > loadEventEnd;
@@ -5838,28 +5864,50 @@ class StreamStatusTelemetryService2 {
5838
5864
  const t = r.transferSize || 0;
5839
5865
  const enc = r.encodedBodySize || 0;
5840
5866
  const dec = r.decodedBodySize || 0;
5867
+ const dur = r.duration || 0; // responseEnd − startTime (ms)
5841
5868
  b.count++;
5842
5869
  if (fromCache)
5843
5870
  b.cachedCount++;
5844
5871
  b.transferSize += t;
5845
5872
  b.encodedBodySize += enc;
5846
5873
  b.decodedBodySize += dec;
5874
+ b.durationMs += dur;
5875
+ if (dur > b.maxDurationMs)
5876
+ b.maxDurationMs = dur;
5847
5877
  totals.count++;
5848
5878
  if (fromCache)
5849
5879
  totals.cachedCount++;
5850
5880
  totals.transferSize += t;
5851
5881
  totals.encodedBodySize += enc;
5852
5882
  totals.decodedBodySize += dec;
5883
+ totals.durationMs += dur;
5884
+ if (dur > totals.maxDurationMs)
5885
+ totals.maxDurationMs = dur;
5886
+ if (dur > 0) {
5887
+ slow.push({
5888
+ name: shortResourceName(r.name),
5889
+ type,
5890
+ durationMs: Math.round(dur),
5891
+ transferKb: Math.round((t / 1024) * 10) / 10,
5892
+ lazy: isLazy,
5893
+ });
5894
+ }
5853
5895
  }
5896
+ slow.sort((a, b) => b.durationMs - a.durationMs);
5854
5897
  return {
5855
5898
  resources: pageLoadTotals.count > 0
5856
5899
  ? { ...pageLoadTotals, byType: pageLoadByType }
5857
5900
  : null,
5858
5901
  lazyResources: lazyTotals.count > 0 ? { ...lazyTotals, byType: lazyByType } : null,
5902
+ // Top-8 slowest individual resources (path only, query stripped) so
5903
+ // the viewer can name the offending file / endpoint. GraphQL appears
5904
+ // here as its endpoint path (one entry per call) — Resource Timing
5905
+ // can't expose the operation name (it's in the POST body).
5906
+ slowestResources: slow.slice(0, 8),
5859
5907
  };
5860
5908
  }
5861
5909
  catch {
5862
- return { resources: null, lazyResources: null };
5910
+ return { resources: null, lazyResources: null, slowestResources: [] };
5863
5911
  }
5864
5912
  }
5865
5913
  aggregate(values) {