@hkdigital/lib-core 0.4.63 → 0.4.65

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.
@@ -464,5 +464,8 @@ export function parseFunctionName(frame) {
464
464
  }
465
465
  }
466
466
 
467
+ // Strip Firefox function naming artifacts like "</timeoutId<"
468
+ functionName = functionName.replace(/<\/[^<>]*</g, '');
469
+
467
470
  return functionName;
468
471
  }
@@ -45,6 +45,9 @@ export default class SceneBase {
45
45
  /** @type {((progress:SceneLoadingProgress)=>void)[]} */
46
46
  #preloadListeners = [];
47
47
 
48
+ /** @type {SceneLoadingProgress|null} */
49
+ #lastReportedProgress = null;
50
+
48
51
  /** @type {SceneLoadingProgress} */
49
52
  progress = $derived.by(() => {
50
53
  let totalSize = 0;
@@ -137,11 +140,24 @@ export default class SceneBase {
137
140
  } // end constructor
138
141
 
139
142
  /**
140
- * Call preload progress listeners
143
+ * Call preload progress listeners (with deduplication)
141
144
  *
142
145
  * @param {SceneLoadingProgress} progress
143
146
  */
144
147
  #updatePreloadProgressListeners(progress) {
148
+ // Skip if progress hasn't actually changed
149
+ if (this.#lastReportedProgress &&
150
+ this.#lastReportedProgress.totalBytesLoaded === progress.totalBytesLoaded &&
151
+ this.#lastReportedProgress.totalSize === progress.totalSize &&
152
+ this.#lastReportedProgress.sourcesLoaded === progress.sourcesLoaded &&
153
+ this.#lastReportedProgress.numberOfSources === progress.numberOfSources &&
154
+ this.#lastReportedProgress.percentageLoaded === progress.percentageLoaded) {
155
+ return;
156
+ }
157
+
158
+ // Update last reported progress
159
+ this.#lastReportedProgress = { ...progress };
160
+
145
161
  for (const fn of this.#preloadListeners) {
146
162
  try {
147
163
  fn(progress);
@@ -348,6 +364,17 @@ export default class SceneBase {
348
364
  /* ==== Internal methods */
349
365
 
350
366
  #startLoading() {
367
+ // Handle empty scenes - immediately transition to loaded if no sources
368
+ if (this.sources.length === 0) {
369
+ // Use setTimeout to avoid re-entrant state machine calls
370
+ setTimeout(() => {
371
+ if (this.#state.current === STATE_LOADING) {
372
+ this.#state.send(LOADED);
373
+ }
374
+ }, 0);
375
+ return;
376
+ }
377
+
351
378
  for (let i = 0; i < this.sources.length; i++) {
352
379
  const source = this.sources[i];
353
380
  const loader = this.getLoaderFromSource(source);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hkdigital/lib-core",
3
- "version": "0.4.63",
3
+ "version": "0.4.65",
4
4
  "author": {
5
5
  "name": "HKdigital",
6
6
  "url": "https://hkdigital.nl"