@xiboplayer/renderer 0.7.8 → 0.7.9

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xiboplayer/renderer",
3
- "version": "0.7.8",
3
+ "version": "0.7.9",
4
4
  "description": "RendererLite - Fast, efficient XLF layout rendering engine",
5
5
  "type": "module",
6
6
  "main": "./src/index.js",
@@ -12,9 +12,9 @@
12
12
  },
13
13
  "dependencies": {
14
14
  "pdfjs-dist": "^4.10.38",
15
- "@xiboplayer/cache": "0.7.8",
16
- "@xiboplayer/schedule": "0.7.8",
17
- "@xiboplayer/utils": "0.7.8"
15
+ "@xiboplayer/utils": "0.7.9",
16
+ "@xiboplayer/cache": "0.7.9",
17
+ "@xiboplayer/schedule": "0.7.9"
18
18
  },
19
19
  "devDependencies": {
20
20
  "jsdom": "^25.0.1",
@@ -211,6 +211,7 @@ export class RendererLite {
211
211
  this.currentLayout = null;
212
212
  this.currentLayoutId = null;
213
213
  this._preloadingLayoutId = null; // Set during preload for blob URL tracking
214
+ this._preloadingPromise = null; // Promise for in-flight preload (await instead of skip)
214
215
  this.regions = new Map(); // regionId => { element, widgets, currentIndex, timer }
215
216
  this.layoutTimer = null;
216
217
  this.layoutEndEmitted = false; // Prevents double layoutEnd on stop after timer
@@ -2887,13 +2888,20 @@ export class RendererLite {
2887
2888
  return true;
2888
2889
  }
2889
2890
 
2890
- // Don't preload if already in-flight (prevents triple preload when
2891
- // 75% and 90% timers both fire before the async preload completes)
2892
- if (this._preloadingLayoutId === layoutId) {
2893
- this.log.info(`Layout ${layoutId} preload already in-flight, skipping`);
2894
- return true;
2891
+ // If already in-flight, wait for it instead of skipping (prevents the race
2892
+ // where showLayout is called before the background preload finishes adding
2893
+ // the layout to the pool).
2894
+ if (this._preloadingLayoutId === layoutId && this._preloadingPromise) {
2895
+ this.log.info(`Layout ${layoutId} preload in-flight, waiting for it...`);
2896
+ return this._preloadingPromise;
2895
2897
  }
2896
2898
 
2899
+ // Store the preload promise so concurrent callers can await it
2900
+ this._preloadingPromise = this._doPreloadLayout(xlfXml, layoutId);
2901
+ return this._preloadingPromise;
2902
+ }
2903
+
2904
+ async _doPreloadLayout(xlfXml, layoutId) {
2897
2905
  try {
2898
2906
  this.log.info(`Preloading layout ${layoutId} into pool...`);
2899
2907
 
@@ -2996,6 +3004,11 @@ export class RendererLite {
2996
3004
  } catch (error) {
2997
3005
  this.log.error(`Preload failed for layout ${layoutId}:`, error);
2998
3006
  return false;
3007
+ } finally {
3008
+ if (this._preloadingLayoutId === layoutId) {
3009
+ this._preloadingLayoutId = null;
3010
+ this._preloadingPromise = null;
3011
+ }
2999
3012
  }
3000
3013
  }
3001
3014