@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 +2 -2
- package/src/download-manager.js +4 -2
- package/src/widget-html.js +14 -1
- package/src/widget-html.test.js +36 -2
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@xiboplayer/cache",
|
|
3
|
-
"version": "0.6.
|
|
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.
|
|
19
|
+
"@xiboplayer/utils": "0.6.3"
|
|
20
20
|
},
|
|
21
21
|
"devDependencies": {
|
|
22
22
|
"vitest": "^2.0.0",
|
package/src/download-manager.js
CHANGED
|
@@ -708,13 +708,15 @@ export class DownloadQueue {
|
|
|
708
708
|
|
|
709
709
|
let boosted = 0;
|
|
710
710
|
for (const t of this.queue) {
|
|
711
|
-
|
|
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
|
-
|
|
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
|
}
|
package/src/widget-html.js
CHANGED
|
@@ -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,
|
package/src/widget-html.test.js
CHANGED
|
@@ -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', () => {
|