@ngxsp/plugin-offline 0.0.1-next.0
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/index.d.ts +11 -0
- package/index.js +52 -0
- package/index.js.map +1 -0
- package/package.json +16 -0
package/index.d.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { PlayerPlugin, PlayerConfig } from '@ngxsp/core';
|
|
2
|
+
|
|
3
|
+
type OfflineConfig = {
|
|
4
|
+
enabled?: boolean;
|
|
5
|
+
/** Storage key override; default = `offline:${contentId || url}` */
|
|
6
|
+
key?: string;
|
|
7
|
+
};
|
|
8
|
+
declare function offlineKeyForConfig(cfg: PlayerConfig, override?: string): string;
|
|
9
|
+
declare function createOfflinePlugin(): PlayerPlugin;
|
|
10
|
+
|
|
11
|
+
export { type OfflineConfig, createOfflinePlugin, offlineKeyForConfig };
|
package/index.js
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
// src/index.ts
|
|
2
|
+
function offlineKeyForConfig(cfg, override) {
|
|
3
|
+
if (override) return override;
|
|
4
|
+
const src = cfg.source ?? {};
|
|
5
|
+
const cid = src.contentId;
|
|
6
|
+
const url = src.url;
|
|
7
|
+
return `offline:${cid || url || "unknown"}`;
|
|
8
|
+
}
|
|
9
|
+
function createOfflinePlugin() {
|
|
10
|
+
let currentBlobUrl = null;
|
|
11
|
+
async function materializeOfflineUrl(ports, cfg) {
|
|
12
|
+
const bin = ports.storageBinary;
|
|
13
|
+
if (!bin?.get) return null;
|
|
14
|
+
const key = offlineKeyForConfig(cfg, cfg.offline?.key);
|
|
15
|
+
const bytes = await bin.get(key);
|
|
16
|
+
if (!bytes) return null;
|
|
17
|
+
const blobBytes = new Uint8Array(bytes.byteLength);
|
|
18
|
+
blobBytes.set(bytes);
|
|
19
|
+
const blob = new Blob([blobBytes]);
|
|
20
|
+
return URL.createObjectURL(blob);
|
|
21
|
+
}
|
|
22
|
+
return {
|
|
23
|
+
id: "offline",
|
|
24
|
+
async onLoadStart(ctx) {
|
|
25
|
+
const offline = ctx.config.offline;
|
|
26
|
+
if (!offline?.enabled) return;
|
|
27
|
+
const url = await materializeOfflineUrl(ctx.ports, ctx.config);
|
|
28
|
+
if (!url) return;
|
|
29
|
+
if (currentBlobUrl) URL.revokeObjectURL(currentBlobUrl);
|
|
30
|
+
currentBlobUrl = url;
|
|
31
|
+
ctx.config.source = {
|
|
32
|
+
...ctx.config.source,
|
|
33
|
+
type: "url",
|
|
34
|
+
url,
|
|
35
|
+
live: false
|
|
36
|
+
};
|
|
37
|
+
ctx.ports?.log?.debug?.("[ngxsp/offline] using cached bytes");
|
|
38
|
+
},
|
|
39
|
+
async onDestroy(ctx) {
|
|
40
|
+
void ctx;
|
|
41
|
+
if (currentBlobUrl) {
|
|
42
|
+
URL.revokeObjectURL(currentBlobUrl);
|
|
43
|
+
currentBlobUrl = null;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
export {
|
|
49
|
+
createOfflinePlugin,
|
|
50
|
+
offlineKeyForConfig
|
|
51
|
+
};
|
|
52
|
+
//# sourceMappingURL=index.js.map
|
package/index.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["import type { PlayerPlugin, PlayerContext, PlayerConfig, PlayerPorts } from '@ngxsp/core';\n\nexport type OfflineConfig = {\n enabled?: boolean;\n /** Storage key override; default = `offline:${contentId || url}` */\n key?: string;\n};\n\nexport function offlineKeyForConfig(cfg: PlayerConfig, override?: string): string {\n if (override) return override;\n const src: any = (cfg as any).source ?? {};\n const cid = src.contentId as string | undefined;\n const url = src.url as string | undefined;\n return `offline:${cid || url || 'unknown'}`;\n}\n\nexport function createOfflinePlugin(): PlayerPlugin {\n let currentBlobUrl: string | null = null;\n\n async function materializeOfflineUrl(ports: Partial<PlayerPorts>, cfg: PlayerConfig): Promise<string | null> {\n const bin: any = (ports as any).storageBinary;\n if (!bin?.get) return null;\n const key = offlineKeyForConfig(cfg, (cfg as any).offline?.key);\n const bytes: Uint8Array | null = await bin.get(key);\n if (!bytes) return null;\n\n const blobBytes = new Uint8Array(bytes.byteLength);\n blobBytes.set(bytes);\n const blob = new Blob([blobBytes]);\n return URL.createObjectURL(blob);\n }\n\n return {\n id: 'offline',\n async onLoadStart(ctx: PlayerContext): Promise<void> {\n const offline: OfflineConfig | undefined = (ctx.config as any).offline;\n if (!offline?.enabled) return;\n\n const url = await materializeOfflineUrl(ctx.ports, ctx.config);\n if (!url) return;\n\n // Revoke previous materialized url, if any\n if (currentBlobUrl) URL.revokeObjectURL(currentBlobUrl);\n currentBlobUrl = url;\n\n // Mutate config in-place before engines are selected\n (ctx.config as any).source = {\n ...(ctx.config as any).source,\n type: 'url',\n url,\n live: false\n };\n\n ctx.ports?.log?.debug?.('[ngxsp/offline] using cached bytes');\n },\n\n async onDestroy(ctx: PlayerContext): Promise<void> {\n void ctx;\n if (currentBlobUrl) {\n URL.revokeObjectURL(currentBlobUrl);\n currentBlobUrl = null;\n }\n }\n };\n}\n"],"mappings":";AAQO,SAAS,oBAAoB,KAAmB,UAA2B;AAChF,MAAI,SAAU,QAAO;AACrB,QAAM,MAAY,IAAY,UAAU,CAAC;AACzC,QAAM,MAAM,IAAI;AAChB,QAAM,MAAM,IAAI;AAChB,SAAO,WAAW,OAAO,OAAO,SAAS;AAC3C;AAEO,SAAS,sBAAoC;AAClD,MAAI,iBAAgC;AAEpC,iBAAe,sBAAsB,OAA6B,KAA2C;AAC3G,UAAM,MAAY,MAAc;AAChC,QAAI,CAAC,KAAK,IAAK,QAAO;AACtB,UAAM,MAAM,oBAAoB,KAAM,IAAY,SAAS,GAAG;AAC9D,UAAM,QAA2B,MAAM,IAAI,IAAI,GAAG;AAClD,QAAI,CAAC,MAAO,QAAO;AAEnB,UAAM,YAAY,IAAI,WAAW,MAAM,UAAU;AACjD,cAAU,IAAI,KAAK;AACnB,UAAM,OAAO,IAAI,KAAK,CAAC,SAAS,CAAC;AACjC,WAAO,IAAI,gBAAgB,IAAI;AAAA,EACjC;AAEA,SAAO;AAAA,IACL,IAAI;AAAA,IACJ,MAAM,YAAY,KAAmC;AACnD,YAAM,UAAsC,IAAI,OAAe;AAC/D,UAAI,CAAC,SAAS,QAAS;AAEvB,YAAM,MAAM,MAAM,sBAAsB,IAAI,OAAO,IAAI,MAAM;AAC7D,UAAI,CAAC,IAAK;AAGV,UAAI,eAAgB,KAAI,gBAAgB,cAAc;AACtD,uBAAiB;AAGjB,MAAC,IAAI,OAAe,SAAS;AAAA,QAC3B,GAAI,IAAI,OAAe;AAAA,QACvB,MAAM;AAAA,QACN;AAAA,QACA,MAAM;AAAA,MACR;AAEA,UAAI,OAAO,KAAK,QAAQ,oCAAoC;AAAA,IAC9D;AAAA,IAEA,MAAM,UAAU,KAAmC;AACjD,WAAK;AACL,UAAI,gBAAgB;AAClB,YAAI,gBAAgB,cAAc;AAClC,yBAAiB;AAAA,MACnB;AAAA,IACF;AAAA,EACF;AACF;","names":[]}
|
package/package.json
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@ngxsp/plugin-offline",
|
|
3
|
+
"version": "0.0.1-next.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"types": "dist/index.d.ts",
|
|
7
|
+
"exports": {
|
|
8
|
+
".": {
|
|
9
|
+
"types": "./dist/index.d.ts",
|
|
10
|
+
"default": "./dist/index.js"
|
|
11
|
+
}
|
|
12
|
+
},
|
|
13
|
+
"dependencies": {
|
|
14
|
+
"@ngxsp/core": "0.0.1-next.0"
|
|
15
|
+
}
|
|
16
|
+
}
|