@lls/offline 24.22.0-34f32711 → 24.22.0-4b32311c
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/lib/assets/fetch-worker.js +18 -65
- package/lib/assets/offline-worker.js +35 -95
- package/lib/index.js +22 -57
- package/package.json +2 -2
|
@@ -62,7 +62,6 @@ var makeSyncHandler = a(
|
|
|
62
62
|
})
|
|
63
63
|
);
|
|
64
64
|
var jsonToBuf = (json) => new TextEncoder().encode(JSON.stringify(json));
|
|
65
|
-
var openCache = async () => caches.open(`LLS_OFFLINE_${process.env.CONF_ENV}`);
|
|
66
65
|
|
|
67
66
|
// src/worker/swFetchScreenCall.ts
|
|
68
67
|
var zipSlugName = (str) => str.replace(/[^a-zA-Z0-9-.]/g, "");
|
|
@@ -197,7 +196,7 @@ var canHandleScreenCall = (url) => new RegExp(Object.keys(handles).join("|")).te
|
|
|
197
196
|
var handleScreenCall = async (ev, { offlineWorkerSync: offlineWorkerSync2, knownLinks: knownLinks2 }) => {
|
|
198
197
|
try {
|
|
199
198
|
const variables = (
|
|
200
|
-
// @ts-
|
|
199
|
+
// @ts-ignore TODO: handle variables from body(stream) properly!!
|
|
201
200
|
ev.request.body?.variables || JSON.parse(new URLSearchParams(new URL(ev.request.url).search).get("variables") || "{}")
|
|
202
201
|
);
|
|
203
202
|
console.debug("variables are", variables, "vs", ev.request.body);
|
|
@@ -212,12 +211,6 @@ var handleScreenCall = async (ev, { offlineWorkerSync: offlineWorkerSync2, known
|
|
|
212
211
|
return { status: 500, json: JSON.stringify(e) };
|
|
213
212
|
}
|
|
214
213
|
};
|
|
215
|
-
var setKnownLinks = (knownLinks2, { entryNames, bookId }) => {
|
|
216
|
-
entryNames.forEach((entryName) => {
|
|
217
|
-
const link = entryName.replace(new RegExp(`^\\d+/media/|^${bookId}/medias/`), "").replace(new RegExp(`^${bookId}/gqls/`), "gqls/");
|
|
218
|
-
knownLinks2.set(link, { entryName, bookId });
|
|
219
|
-
});
|
|
220
|
-
};
|
|
221
214
|
|
|
222
215
|
// src/worker/fetch-worker.ts
|
|
223
216
|
var fetchAsset = async (ev, { entryId, mimeType, offlineWorkerSync: offlineWorkerSync2 }) => {
|
|
@@ -285,70 +278,36 @@ var ACCEPTED_EXTENSIONS = {
|
|
|
285
278
|
".m4a": "audio/mp4",
|
|
286
279
|
".webp": "image/webp"
|
|
287
280
|
};
|
|
288
|
-
var putInCache = async (request, response) => {
|
|
289
|
-
const cache = await openCache();
|
|
290
|
-
await cache.put(request, response);
|
|
291
|
-
};
|
|
292
|
-
var onlineFirst = async (request, event) => {
|
|
293
|
-
try {
|
|
294
|
-
const responseFromNetwork = await fetch(request);
|
|
295
|
-
const cached = putInCache(request, responseFromNetwork.clone());
|
|
296
|
-
if (request.url.endsWith(".zip")) {
|
|
297
|
-
await cached;
|
|
298
|
-
event.waitUntil(Promise.resolve());
|
|
299
|
-
} else {
|
|
300
|
-
event.waitUntil(cached);
|
|
301
|
-
}
|
|
302
|
-
return responseFromNetwork;
|
|
303
|
-
} catch (_e) {
|
|
304
|
-
const over = /\/\?story=basic/.test(request.url) ? request.url.replace(/\/\?story=.*$/, "") : request;
|
|
305
|
-
const responseFromCache = await caches.match(over);
|
|
306
|
-
if (!responseFromCache) {
|
|
307
|
-
return new Response("FAILED fetch", {
|
|
308
|
-
// @ts-ignore: poor ts typing
|
|
309
|
-
ok: false,
|
|
310
|
-
status: 500,
|
|
311
|
-
type: "cors",
|
|
312
|
-
url: event.request.url
|
|
313
|
-
});
|
|
314
|
-
}
|
|
315
|
-
return responseFromCache;
|
|
316
|
-
}
|
|
317
|
-
};
|
|
318
|
-
var STORAGE = "cache";
|
|
319
281
|
var swSelf = self;
|
|
320
282
|
swSelf.addEventListener("fetch", (ev) => {
|
|
321
283
|
const url = ev.request.url;
|
|
322
284
|
const extension = url.match(/\.[^.]+$/)?.[0];
|
|
323
285
|
const mimeType = extension && extension in ACCEPTED_EXTENSIONS ? ACCEPTED_EXTENSIONS[extension] : "";
|
|
324
286
|
const isValidScreenCall = canHandleScreenCall(url);
|
|
325
|
-
if (STORAGE !== "cache" && url.endsWith(".zip")) {
|
|
326
|
-
return;
|
|
327
|
-
}
|
|
328
287
|
if (!mimeType && !isValidScreenCall) {
|
|
329
288
|
if (!/\.(css|tsx?|jsx?|woff2|fr|manifest)(\??|$)|@(vite|react|id)/.test(url)) {
|
|
330
289
|
console.debug("no ext", extension || url);
|
|
331
290
|
}
|
|
332
|
-
return
|
|
291
|
+
return;
|
|
333
292
|
}
|
|
334
293
|
const entryId = knownLinks.get(url.replace(/https:\/\/.*?\//, "")) || knownLinks.get(`medias/${url.replace(/https:\/\/.*?\//, "")}`);
|
|
294
|
+
if (!entryId && !isValidScreenCall) {
|
|
295
|
+
if (/lls|lelivrescolaire/.test(url)) {
|
|
296
|
+
console.info("no link for", url.replace(/https:\/\/.*?\//, ""));
|
|
297
|
+
}
|
|
298
|
+
return;
|
|
299
|
+
}
|
|
335
300
|
if (isValidScreenCall) {
|
|
336
301
|
console.debug("screencall!");
|
|
337
302
|
return ev.respondWith(fetchScreenCall(ev, { offlineWorkerSync, knownLinks }));
|
|
338
303
|
}
|
|
339
|
-
|
|
340
|
-
return ev.respondWith(fetchAsset(ev, { entryId, mimeType, offlineWorkerSync }));
|
|
341
|
-
}
|
|
342
|
-
if (/lls|lelivrescolaire/.test(url)) {
|
|
343
|
-
console.info("no link for", url.replace(/https:\/\/.*?\//, ""), `medias/${url.replace(/https:\/\/.*?\//, "")}`);
|
|
344
|
-
}
|
|
345
|
-
return;
|
|
304
|
+
return ev.respondWith(fetchAsset(ev, { entryId, mimeType, offlineWorkerSync }));
|
|
346
305
|
});
|
|
347
306
|
swSelf.addEventListener("install", (_event) => {
|
|
348
307
|
swSelf.skipWaiting();
|
|
349
308
|
});
|
|
350
|
-
swSelf.addEventListener("activate", (
|
|
351
|
-
|
|
309
|
+
swSelf.addEventListener("activate", (_event) => {
|
|
310
|
+
return swSelf.clients.claim();
|
|
352
311
|
});
|
|
353
312
|
var offlineWorker;
|
|
354
313
|
var offlineWorkerSync;
|
|
@@ -362,30 +321,24 @@ var initChannel = async (__, { ports }) => {
|
|
|
362
321
|
);
|
|
363
322
|
offlineWorkerSync = sender;
|
|
364
323
|
offlineWorker.onmessage = handler.handle;
|
|
365
|
-
offlineWorkerSync.on("setKnownLinks", setKnownLinks
|
|
324
|
+
offlineWorkerSync.on("setKnownLinks", setKnownLinks);
|
|
366
325
|
offlineWorker.postMessage({ methodName: "sendAppReady" });
|
|
367
326
|
};
|
|
368
327
|
var knownLinks = /* @__PURE__ */ new Map();
|
|
369
|
-
var
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
}
|
|
374
|
-
console.info("sw::configure", { STORAGE });
|
|
328
|
+
var setKnownLinks = ({ entryNames, bookId }) => {
|
|
329
|
+
entryNames.forEach((entryName) => {
|
|
330
|
+
const link = entryName.replace(/^\d+\/media\//, "");
|
|
331
|
+
knownLinks.set(link, { entryName, bookId });
|
|
332
|
+
});
|
|
375
333
|
};
|
|
376
334
|
swSelf.onmessage = async ({
|
|
377
335
|
data: { methodName, arg } = {},
|
|
378
336
|
ports
|
|
379
337
|
}) => {
|
|
380
338
|
const services = {
|
|
381
|
-
initChannel
|
|
382
|
-
configure
|
|
339
|
+
initChannel
|
|
383
340
|
};
|
|
384
341
|
try {
|
|
385
|
-
if (methodName === "configure") {
|
|
386
|
-
await services[methodName](arg);
|
|
387
|
-
return;
|
|
388
|
-
}
|
|
389
342
|
if (methodName === "initChannel") {
|
|
390
343
|
if (!ports.length) {
|
|
391
344
|
throw new Error("fetchworker::missing port!");
|
|
@@ -1,14 +1,3 @@
|
|
|
1
|
-
// src/utils/error.ts
|
|
2
|
-
var tryCatch = (fn) => {
|
|
3
|
-
return (resolve, reject) => {
|
|
4
|
-
try {
|
|
5
|
-
return fn().then(resolve);
|
|
6
|
-
} catch (e) {
|
|
7
|
-
return reject(e);
|
|
8
|
-
}
|
|
9
|
-
};
|
|
10
|
-
};
|
|
11
|
-
|
|
12
1
|
// src/utils/worker.ts
|
|
13
2
|
var makeSyncWorker = (offlineWorker, methodNames, dbg) => {
|
|
14
3
|
const dic = {};
|
|
@@ -83,7 +72,6 @@ var combineHandlers = (...handlers) => {
|
|
|
83
72
|
console.error("no handlers matched", methodName);
|
|
84
73
|
};
|
|
85
74
|
};
|
|
86
|
-
var openCache = async () => caches.open(`LLS_OFFLINE_${process.env.CONF_ENV}`);
|
|
87
75
|
|
|
88
76
|
// src/worker/wwApi.ts
|
|
89
77
|
var STATE = {
|
|
@@ -842,24 +830,17 @@ var loadZip = async (buf, bookId) => {
|
|
|
842
830
|
|
|
843
831
|
// src/worker/offline-worker.ts
|
|
844
832
|
var CHECK_UPDATES = true;
|
|
845
|
-
var
|
|
846
|
-
var
|
|
847
|
-
var LOADED_BOOKS = /* @__PURE__ */ new Map();
|
|
833
|
+
var NATIVE = false;
|
|
834
|
+
var LOADED_BOOKS = /* @__PURE__ */ new Set();
|
|
848
835
|
var fetchZipFile = async (zipUrl, { forceRefresh } = {}) => {
|
|
849
836
|
const fileName = zipUrl.split("/").slice(-1)[0];
|
|
850
837
|
const readArrayBuffer = async () => {
|
|
851
|
-
if (
|
|
838
|
+
if (NATIVE) {
|
|
839
|
+
console.debug("try reading native", fileName);
|
|
852
840
|
const back = await sender.nativeReadFile({ fname: fileName });
|
|
841
|
+
console.debug("done readnig");
|
|
853
842
|
return back;
|
|
854
843
|
}
|
|
855
|
-
if (STORAGE === "cache") {
|
|
856
|
-
const response = await caches.match(zipUrl);
|
|
857
|
-
if (!response) {
|
|
858
|
-
throw new Error(`missing zip ${zipUrl}`);
|
|
859
|
-
}
|
|
860
|
-
const buf = await response.arrayBuffer();
|
|
861
|
-
return buf;
|
|
862
|
-
}
|
|
863
844
|
const opfsRoot = await navigator.storage.getDirectory();
|
|
864
845
|
const handle = await opfsRoot.getFileHandle(fileName);
|
|
865
846
|
const accessHandle = await handle.createSyncAccessHandle();
|
|
@@ -887,7 +868,7 @@ var fetchZipFile = async (zipUrl, { forceRefresh } = {}) => {
|
|
|
887
868
|
return buf;
|
|
888
869
|
} catch (e) {
|
|
889
870
|
if (e instanceof Error && e.message !== "forceRefresh" && !e.message.includes("refetching")) {
|
|
890
|
-
console.debug(
|
|
871
|
+
console.debug("opfs db not found, creating it", e, zipUrl);
|
|
891
872
|
}
|
|
892
873
|
const response = await fetch(zipUrl);
|
|
893
874
|
const contentLength = +response.headers.get("Content-Length");
|
|
@@ -898,7 +879,6 @@ var fetchZipFile = async (zipUrl, { forceRefresh } = {}) => {
|
|
|
898
879
|
while (true) {
|
|
899
880
|
const { done, value: chunk } = await reader.read();
|
|
900
881
|
if (done) {
|
|
901
|
-
self.postMessage({ methodName: "opfsProgress", arg: { total: contentLength, bytes: contentLength } });
|
|
902
882
|
break;
|
|
903
883
|
}
|
|
904
884
|
arrayBuffer.set(chunk, position);
|
|
@@ -913,69 +893,44 @@ var fetchZipFile = async (zipUrl, { forceRefresh } = {}) => {
|
|
|
913
893
|
console.debug(error);
|
|
914
894
|
throw new Error(error);
|
|
915
895
|
}
|
|
916
|
-
if (
|
|
896
|
+
if (NATIVE) {
|
|
917
897
|
await sender.nativeWriteFile({ fname: fileName, buffer: arrayBuffer });
|
|
918
|
-
|
|
919
|
-
const opfsRoot = await navigator.storage.getDirectory();
|
|
920
|
-
const handle = await opfsRoot.getFileHandle(fileName, { create: true });
|
|
921
|
-
const accessHandle = await handle.createSyncAccessHandle();
|
|
922
|
-
await accessHandle.truncate(0);
|
|
923
|
-
await accessHandle.write(arrayBuffer);
|
|
924
|
-
await accessHandle.close();
|
|
925
|
-
} else {
|
|
926
|
-
const cache = await openCache();
|
|
927
|
-
const response2 = new Response(arrayBuffer, {
|
|
928
|
-
headers: {
|
|
929
|
-
"Cache-Control": "max-age=600, s-maxage=600, public, proxy-revalidate",
|
|
930
|
-
"Content-Type": "application/zip"
|
|
931
|
-
},
|
|
932
|
-
// @ts-ignore: poor ts typing
|
|
933
|
-
ok: true,
|
|
934
|
-
redirected: false,
|
|
935
|
-
status: 200,
|
|
936
|
-
type: "cors",
|
|
937
|
-
url: zipUrl
|
|
938
|
-
});
|
|
939
|
-
await cache.put(zipUrl, response2);
|
|
898
|
+
return await readArrayBuffer();
|
|
940
899
|
}
|
|
900
|
+
const opfsRoot = await navigator.storage.getDirectory();
|
|
901
|
+
const handle = await opfsRoot.getFileHandle(fileName, { create: true });
|
|
902
|
+
const accessHandle = await handle.createSyncAccessHandle();
|
|
903
|
+
await accessHandle.truncate(0);
|
|
904
|
+
await accessHandle.write(arrayBuffer);
|
|
905
|
+
await accessHandle.close();
|
|
941
906
|
return await readArrayBuffer();
|
|
942
907
|
}
|
|
943
908
|
};
|
|
944
909
|
var slugToFileMeta2 = async ({ slug }) => {
|
|
910
|
+
console.debug("hereshit");
|
|
945
911
|
const json = await readZipEntry({ bookId: "preload", entryName: "preload/hashmap_slugToMetaPage.json", asJson: true });
|
|
912
|
+
console.debug("hereshit2");
|
|
946
913
|
return slugToFileMeta({ slug, json });
|
|
947
914
|
};
|
|
948
915
|
var PRELOAD_AS_BOOK_ID = "preload";
|
|
949
916
|
var isOldZip = (bookId) => typeof bookId === "number";
|
|
950
917
|
var loadBook2 = async ({ id: bookId, forceRefresh }) => {
|
|
951
918
|
if (LOADED_BOOKS.has(bookId)) {
|
|
952
|
-
await LOADED_BOOKS.get(bookId);
|
|
953
919
|
self.postMessage({ methodName: "opfsProgress", arg: { total: 1, bytes: 1 } });
|
|
954
920
|
return;
|
|
955
921
|
}
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
loadBook(json);
|
|
969
|
-
}
|
|
970
|
-
return true;
|
|
971
|
-
} catch (e) {
|
|
972
|
-
console.error("failed", e);
|
|
973
|
-
return false;
|
|
974
|
-
}
|
|
975
|
-
})
|
|
976
|
-
);
|
|
977
|
-
LOADED_BOOKS.set(bookId, p);
|
|
978
|
-
await p;
|
|
922
|
+
LOADED_BOOKS.add(bookId);
|
|
923
|
+
const buf = await fetchZipFile(`https://ci.lls.fr/artefacts/content/development/${bookId}.zip`, { forceRefresh });
|
|
924
|
+
try {
|
|
925
|
+
const entryNames = await loadZip(new Uint8Array(buf), bookId);
|
|
926
|
+
fetchWorker.postMessage({ methodName: "setKnownLinks", arg: { entryNames, bookId } });
|
|
927
|
+
if (isOldZip(bookId)) {
|
|
928
|
+
const json = await readZipEntry({ entryName: `preload/${bookId}.json`, bookId: PRELOAD_AS_BOOK_ID, asJson: true });
|
|
929
|
+
loadBook(json);
|
|
930
|
+
}
|
|
931
|
+
} catch (e) {
|
|
932
|
+
console.error("failed", e);
|
|
933
|
+
}
|
|
979
934
|
};
|
|
980
935
|
var loadPageContent2 = async ({
|
|
981
936
|
bookId: iBookId,
|
|
@@ -1018,16 +973,11 @@ var initChannel = (__, { ports }) => {
|
|
|
1018
973
|
};
|
|
1019
974
|
var loadBooks = async ({ primaryOnly = false } = {}) => {
|
|
1020
975
|
let entries = [];
|
|
1021
|
-
if (
|
|
976
|
+
if (NATIVE) {
|
|
1022
977
|
entries = await sender.nativeListZips();
|
|
1023
|
-
} else
|
|
978
|
+
} else {
|
|
1024
979
|
const opfsRoot = await navigator.storage.getDirectory();
|
|
1025
980
|
entries = await opfsRoot.values();
|
|
1026
|
-
} else {
|
|
1027
|
-
const cache = await openCache();
|
|
1028
|
-
const keys = await cache.keys();
|
|
1029
|
-
const zips = keys.filter((key2) => key2.url.endsWith(".zip"));
|
|
1030
|
-
entries = zips.map((zip) => ({ name: String(zip.url.split("/").pop()) }));
|
|
1031
981
|
}
|
|
1032
982
|
for await (const entry of entries) {
|
|
1033
983
|
if (/preload/.test(entry.name)) {
|
|
@@ -1046,24 +996,14 @@ var loadBooks = async ({ primaryOnly = false } = {}) => {
|
|
|
1046
996
|
}
|
|
1047
997
|
}
|
|
1048
998
|
};
|
|
1049
|
-
var configure = ({
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
}) => {
|
|
1054
|
-
CHECK_UPDATES = true;
|
|
1055
|
-
STORAGE = "cache";
|
|
1056
|
-
ZIP_BASE_URL = "https://ci.lls.fr/artefacts/content/development";
|
|
1057
|
-
if (typeof storage !== "undefined") {
|
|
1058
|
-
STORAGE = storage;
|
|
999
|
+
var configure = ({ native, checkUpdates }) => {
|
|
1000
|
+
console.info("configuring!!", native, checkUpdates);
|
|
1001
|
+
if (typeof native !== "undefined") {
|
|
1002
|
+
NATIVE = !!native;
|
|
1059
1003
|
}
|
|
1060
|
-
if (typeof
|
|
1004
|
+
if (typeof native !== "undefined") {
|
|
1061
1005
|
CHECK_UPDATES = !!checkUpdates;
|
|
1062
1006
|
}
|
|
1063
|
-
if (typeof zipBaseUrl !== "undefined") {
|
|
1064
|
-
ZIP_BASE_URL = zipBaseUrl;
|
|
1065
|
-
}
|
|
1066
|
-
console.info("ow::configure", { STORAGE, CHECK_UPDATES, ZIP_BASE_URL });
|
|
1067
1007
|
};
|
|
1068
1008
|
var loadPreload2 = async () => {
|
|
1069
1009
|
const zipUrl = "https://lls-ci-fr.s3.eu-west-3.amazonaws.com/artefacts/content/development/preload.zip";
|
package/lib/index.js
CHANGED
|
@@ -1,14 +1,3 @@
|
|
|
1
|
-
// src/utils/error.ts
|
|
2
|
-
var tryCatch = (fn) => {
|
|
3
|
-
return (resolve, reject) => {
|
|
4
|
-
try {
|
|
5
|
-
return fn().then(resolve);
|
|
6
|
-
} catch (e) {
|
|
7
|
-
return reject(e);
|
|
8
|
-
}
|
|
9
|
-
};
|
|
10
|
-
};
|
|
11
|
-
|
|
12
1
|
// src/utils/worker.ts
|
|
13
2
|
var makeSyncWorker = (offlineWorker2, methodNames, dbg) => {
|
|
14
3
|
const dic = {};
|
|
@@ -87,28 +76,11 @@ var combineHandlers = (...handlers) => {
|
|
|
87
76
|
import { useCallback, useEffect, useState } from "react";
|
|
88
77
|
var offlineWorker = new Worker("/src/worker/offline-worker.js", { type: "module" });
|
|
89
78
|
var { handler, ...offlineWorkerSync } = makeSyncWorker(
|
|
79
|
+
// @ts-ignore: TODO
|
|
90
80
|
offlineWorker,
|
|
91
81
|
["initChannel", "readZipEntry", "configure", "loadPreload", "loadBooks", "loadBook"],
|
|
92
82
|
"app:offlineWorker"
|
|
93
83
|
);
|
|
94
|
-
var fetchWorkerPromise = new Promise(
|
|
95
|
-
tryCatch(async () => {
|
|
96
|
-
let fetchWorker = null;
|
|
97
|
-
await navigator.serviceWorker.register("/fetch-worker.js", { type: "module" }).then((reg) => {
|
|
98
|
-
return reg.update().catch((e) => {
|
|
99
|
-
console.debug(e, "likely we are offline");
|
|
100
|
-
});
|
|
101
|
-
});
|
|
102
|
-
await navigator.serviceWorker.ready.then(async (reg) => {
|
|
103
|
-
console.debug("Service Worker registered:", reg.scope);
|
|
104
|
-
fetchWorker = reg.active;
|
|
105
|
-
}).catch((err) => console.error("Service Worker registration failed:", err));
|
|
106
|
-
if (!fetchWorker) {
|
|
107
|
-
console.debug("failed to get fetch worker");
|
|
108
|
-
}
|
|
109
|
-
return fetchWorker;
|
|
110
|
-
})
|
|
111
|
-
);
|
|
112
84
|
var setWorkersReady;
|
|
113
85
|
var workersReadyPromise = new Promise((resolve) => {
|
|
114
86
|
setWorkersReady = resolve;
|
|
@@ -118,41 +90,45 @@ var setBooksLoadedPromise = new Promise((resolve) => {
|
|
|
118
90
|
setBooksLoaded = resolve;
|
|
119
91
|
});
|
|
120
92
|
var installWorker = async ({
|
|
121
|
-
skipLoadBooks = false,
|
|
122
93
|
primaryOnly = false,
|
|
123
94
|
nativeReadFile,
|
|
124
95
|
nativeWriteFile,
|
|
125
96
|
nativeListZips,
|
|
126
|
-
storage,
|
|
127
|
-
zipBaseUrl,
|
|
128
97
|
checkUpdates
|
|
129
98
|
} = {}) => {
|
|
130
|
-
|
|
131
|
-
|
|
99
|
+
let fetchWorker = null;
|
|
100
|
+
await navigator.serviceWorker.getRegistrations().then(async (registrations) => {
|
|
101
|
+
for (const registration of registrations) {
|
|
102
|
+
await registration.unregister();
|
|
103
|
+
}
|
|
104
|
+
});
|
|
105
|
+
await navigator.serviceWorker.register("/fetch-worker.js", { type: "module" }).then((reg) => reg.update());
|
|
106
|
+
await navigator.serviceWorker.ready.then(async (reg) => {
|
|
107
|
+
console.debug("Service Worker registered:", reg.scope);
|
|
108
|
+
fetchWorker = reg.active;
|
|
109
|
+
}).catch((err) => console.error("Service Worker registration failed:", err));
|
|
110
|
+
if (!fetchWorker) {
|
|
111
|
+
console.debug("failed to get fetch worker");
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
132
114
|
if (nativeReadFile) {
|
|
133
115
|
const wwHandler = makeSyncHandler(offlineWorker, { nativeReadFile, nativeWriteFile, nativeListZips });
|
|
134
116
|
offlineWorker.onmessage = combineHandlers(handler, wwHandler);
|
|
135
|
-
|
|
136
|
-
console.warn("nativeReadFile given, ignoring storage", storage);
|
|
137
|
-
}
|
|
138
|
-
offlineWorkerSync.configure({ ...configureOptions, storage: "native" });
|
|
117
|
+
offlineWorkerSync.configure({ native: true, checkUpdates });
|
|
139
118
|
} else {
|
|
119
|
+
offlineWorkerSync.configure({ native: false, checkUpdates });
|
|
140
120
|
offlineWorker.onmessage = handler.handle;
|
|
141
|
-
offlineWorkerSync.configure(configureOptions);
|
|
142
121
|
}
|
|
143
122
|
offlineWorkerSync.on("ready", setWorkersReady);
|
|
144
123
|
const channel = new MessageChannel();
|
|
145
124
|
offlineWorkerSync.initChannel({ ports: [channel.port1] });
|
|
146
125
|
fetchWorker.postMessage({ methodName: "initChannel" }, [channel.port2]);
|
|
147
|
-
fetchWorker.postMessage({ methodName: "configure", arg: { storage } });
|
|
148
126
|
offlineWorkerSync.on("opfsProgress", () => {
|
|
149
127
|
});
|
|
150
128
|
if (!primaryOnly) {
|
|
151
129
|
await offlineWorkerSync.loadPreload();
|
|
152
130
|
}
|
|
153
|
-
|
|
154
|
-
await offlineWorkerSync.loadBooks({ primaryOnly });
|
|
155
|
-
}
|
|
131
|
+
await offlineWorkerSync.loadBooks();
|
|
156
132
|
setBooksLoaded();
|
|
157
133
|
};
|
|
158
134
|
var useOfflineWorker_default = ({
|
|
@@ -160,28 +136,17 @@ var useOfflineWorker_default = ({
|
|
|
160
136
|
nativeReadFile,
|
|
161
137
|
nativeWriteFile,
|
|
162
138
|
nativeListZips,
|
|
163
|
-
checkUpdates
|
|
164
|
-
storage,
|
|
165
|
-
zipBaseUrl
|
|
139
|
+
checkUpdates
|
|
166
140
|
} = {}) => {
|
|
167
141
|
const [ready, setReady] = useState(false);
|
|
168
142
|
useEffect(() => {
|
|
169
143
|
const fn = async () => {
|
|
170
|
-
await installWorker({
|
|
171
|
-
primaryOnly,
|
|
172
|
-
nativeReadFile,
|
|
173
|
-
nativeWriteFile,
|
|
174
|
-
nativeListZips,
|
|
175
|
-
storage,
|
|
176
|
-
zipBaseUrl,
|
|
177
|
-
checkUpdates
|
|
178
|
-
});
|
|
144
|
+
await installWorker({ primaryOnly, nativeReadFile, nativeWriteFile, nativeListZips, checkUpdates });
|
|
179
145
|
await Promise.all([workersReadyPromise, setBooksLoadedPromise]);
|
|
180
|
-
fetch(window.location.href.replace(window.location.search, ""));
|
|
181
146
|
setReady(true);
|
|
182
147
|
};
|
|
183
148
|
fn();
|
|
184
|
-
}, [primaryOnly, nativeReadFile, nativeWriteFile, nativeListZips,
|
|
149
|
+
}, [primaryOnly, nativeReadFile, nativeWriteFile, nativeListZips, checkUpdates]);
|
|
185
150
|
const loadBook = useCallback(
|
|
186
151
|
async ({ id, forceRefresh }, cbk) => {
|
|
187
152
|
offlineWorkerSync.on("opfsProgress", cbk);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lls/offline",
|
|
3
|
-
"version": "24.22.0-
|
|
3
|
+
"version": "24.22.0-4b32311c",
|
|
4
4
|
"description": "offline",
|
|
5
5
|
"main": "./lib/index.js",
|
|
6
6
|
"module": "./lib/index.js",
|
|
@@ -52,7 +52,7 @@
|
|
|
52
52
|
"vite": "7.0.0",
|
|
53
53
|
"vite-tsconfig-paths": "5.1.4",
|
|
54
54
|
"zod": "3.25.50",
|
|
55
|
-
"@lls/vitescripts": "24.22.0-
|
|
55
|
+
"@lls/vitescripts": "24.22.0-4b32311c"
|
|
56
56
|
},
|
|
57
57
|
"dependencies": {
|
|
58
58
|
"fflate": "0.8.2"
|