@xiboplayer/cache 0.6.1 → 0.6.3

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/cache",
3
- "version": "0.6.1",
3
+ "version": "0.6.3",
4
4
  "description": "Offline caching and download management with parallel chunk downloads",
5
5
  "type": "module",
6
6
  "main": "./src/index.js",
@@ -16,7 +16,7 @@
16
16
  },
17
17
  "dependencies": {
18
18
  "spark-md5": "^3.0.2",
19
- "@xiboplayer/utils": "0.6.1"
19
+ "@xiboplayer/utils": "0.6.3"
20
20
  },
21
21
  "devDependencies": {
22
22
  "vitest": "^2.0.0",
@@ -708,13 +708,15 @@ export class DownloadQueue {
708
708
 
709
709
  let boosted = 0;
710
710
  for (const t of this.queue) {
711
- if (idSet.has(String(t._parentFile?.fileInfo.id)) && t._priority < priority) {
711
+ const matchValue = t._parentFile?.fileInfo.saveAs || String(t._parentFile?.fileInfo.id);
712
+ if (idSet.has(matchValue) && t._priority < priority) {
712
713
  t._priority = priority;
713
714
  boosted++;
714
715
  }
715
716
  }
716
717
  for (const t of this._activeTasks) {
717
- if (idSet.has(String(t._parentFile?.fileInfo.id)) && t._priority < priority) {
718
+ const matchValue = t._parentFile?.fileInfo.saveAs || String(t._parentFile?.fileInfo.id);
719
+ if (idSet.has(matchValue) && t._priority < priority) {
718
720
  t._priority = priority;
719
721
  }
720
722
  }
@@ -38,7 +38,7 @@ export async function cacheWidgetHtml(layoutId, regionId, mediaId, html) {
38
38
  const cacheKey = `${PLAYER_API}/widgets/${layoutId}/${regionId}/${mediaId}`;
39
39
 
40
40
  // Inject <base> tag — resolves relative media refs (e.g. "42") to mirror route
41
- const baseTag = `<base href="${PLAYER_API}/media/">`;
41
+ const baseTag = `<base href="${PLAYER_API}/media/file/">`;
42
42
  let modifiedHtml = html;
43
43
 
44
44
  // Insert base tag after <head> opening tag (skip if already present)
@@ -70,6 +70,19 @@ export async function cacheWidgetHtml(layoutId, regionId, mediaId, html) {
70
70
  (_, path) => path
71
71
  );
72
72
 
73
+ // Inject xiboICTargetId — XIC library reads this global before its IIFE runs
74
+ // to set _lib.targetId, which is included in every IC HTTP request as {id: ...}
75
+ if (!modifiedHtml.includes('xiboICTargetId')) {
76
+ const targetIdScript = `<script>var xiboICTargetId = '${mediaId}';</script>`;
77
+ if (modifiedHtml.includes(baseTag)) {
78
+ modifiedHtml = modifiedHtml.replace(baseTag, baseTag + targetIdScript);
79
+ } else if (modifiedHtml.includes('<head>')) {
80
+ modifiedHtml = modifiedHtml.replace('<head>', '<head>' + targetIdScript);
81
+ } else {
82
+ modifiedHtml = targetIdScript + modifiedHtml;
83
+ }
84
+ }
85
+
73
86
  // Rewrite Interactive Control hostAddress to SW-interceptable path
74
87
  modifiedHtml = modifiedHtml.replace(
75
88
  /hostAddress\s*:\s*["']https?:\/\/[^"']+["']/g,
@@ -101,7 +101,7 @@ describe('cacheWidgetHtml', () => {
101
101
  await cacheWidgetHtml('472', '223', '193', html);
102
102
 
103
103
  const stored = getStoredWidget();
104
- expect(stored).toContain('<base href="/api/v2/player/media/">');
104
+ expect(stored).toContain('<base href="/api/v2/player/media/file/">');
105
105
  });
106
106
 
107
107
  it('injects <base> tag when no <head> tag exists', async () => {
@@ -109,7 +109,7 @@ describe('cacheWidgetHtml', () => {
109
109
  await cacheWidgetHtml('472', '223', '193', html);
110
110
 
111
111
  const stored = getStoredWidget();
112
- expect(stored).toContain('<base href="/api/v2/player/media/">');
112
+ expect(stored).toContain('<base href="/api/v2/player/media/file/">');
113
113
  });
114
114
  });
115
115
 
@@ -173,6 +173,40 @@ describe('cacheWidgetHtml', () => {
173
173
  });
174
174
  });
175
175
 
176
+ // --- xiboICTargetId injection ---
177
+
178
+ describe('xiboICTargetId injection', () => {
179
+ it('injects xiboICTargetId script with the media ID', async () => {
180
+ await cacheWidgetHtml('472', '223', '193', makeRssTickerHtml());
181
+
182
+ const stored = getStoredWidget();
183
+ expect(stored).toContain("var xiboICTargetId = '193'");
184
+ });
185
+
186
+ it('injects before XIC library script', async () => {
187
+ await cacheWidgetHtml('472', '223', '193', makeRssTickerHtml());
188
+
189
+ const stored = getStoredWidget();
190
+ const targetIdPos = stored.indexOf('xiboICTargetId');
191
+ const xicInitPos = stored.indexOf('xiboIC.init');
192
+ expect(targetIdPos).toBeLessThan(xicInitPos);
193
+ });
194
+
195
+ it('is idempotent (no double injection)', async () => {
196
+ await cacheWidgetHtml('472', '223', '193', makeRssTickerHtml());
197
+ const firstPass = getStoredWidget();
198
+
199
+ storeContents.clear();
200
+ await cacheWidgetHtml('472', '223', '193', firstPass);
201
+ const secondPass = getStoredWidget();
202
+
203
+ const count = (secondPass.match(/xiboICTargetId/g) || []).length;
204
+ // 1 in the injected script + 1 in the original xiboIC.init options (if any)
205
+ // But the original HTML doesn't have xiboICTargetId, so count should be exactly 1
206
+ expect(count).toBe(1);
207
+ });
208
+ });
209
+
176
210
  // --- CSS object-position fix ---
177
211
 
178
212
  describe('CSS object-position fix', () => {