@lls/offline 24.27.0-ade60496 → 24.27.0-b7c9c281
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 +9 -55
- package/lib/assets/offline-worker.js +5 -41
- package/lib/index.js +4 -16
- package/package.json +2 -2
|
@@ -1,21 +1,3 @@
|
|
|
1
|
-
// src/utils/stream.ts
|
|
2
|
-
var parseRange = (range, size) => {
|
|
3
|
-
const parts = range.replace("bytes=", "").split("-");
|
|
4
|
-
let start = Number.parseInt(parts[0], 10);
|
|
5
|
-
let end = Number.parseInt(parts[1], 10);
|
|
6
|
-
if (isNaN(start)) {
|
|
7
|
-
start = size - end;
|
|
8
|
-
end = size - 1;
|
|
9
|
-
} else if (isNaN(end)) {
|
|
10
|
-
end = size - 1;
|
|
11
|
-
}
|
|
12
|
-
if (end > size - 1) {
|
|
13
|
-
end = size - 1;
|
|
14
|
-
}
|
|
15
|
-
const chunkSize = end - start + 1;
|
|
16
|
-
return { start, end, chunkSize };
|
|
17
|
-
};
|
|
18
|
-
|
|
19
1
|
// src/utils/worker.ts
|
|
20
2
|
var makeSyncWorker = (offlineWorker2, methodNames, dbg) => {
|
|
21
3
|
const dic = {};
|
|
@@ -95,7 +77,7 @@ var cocoreFetchPartialPageScreen = async (_ev, { offlineWorkerSync: offlineWorke
|
|
|
95
77
|
const key = `gqls/${zipSlugName(variables.slugs[0] || "")}.json`;
|
|
96
78
|
const entryId = knownLinks2.get(key);
|
|
97
79
|
if (!entryId) {
|
|
98
|
-
throw new Error(`slug not found ${key}
|
|
80
|
+
throw new Error(`slug not found ${key}`);
|
|
99
81
|
}
|
|
100
82
|
const gqlPage = await offlineWorkerSync2.loadPageContent({ entryId });
|
|
101
83
|
return { data: gqlPage };
|
|
@@ -234,8 +216,8 @@ var handleScreenCall = async (ev, { offlineWorkerSync: offlineWorkerSync2, known
|
|
|
234
216
|
// @ts-expect-error TODO: handle variables from body(stream) properly!!
|
|
235
217
|
ev.request.body?.variables || JSON.parse(new URLSearchParams(new URL(ev.request.url).search).get("variables") || "{}")
|
|
236
218
|
);
|
|
219
|
+
console.debug("variables are", variables, "vs", ev.request.body);
|
|
237
220
|
const key = ev.request.url.match(Object.keys(handles).join("|"))?.[0];
|
|
238
|
-
console.debug("screencall", key, "qs", variables, "vs body", ev.request.body);
|
|
239
221
|
if (!key) {
|
|
240
222
|
throw new Error("unknown ev");
|
|
241
223
|
}
|
|
@@ -256,39 +238,17 @@ var setKnownLinks = (knownLinks2, { entryNames, bookId }) => {
|
|
|
256
238
|
// src/worker/fetch-worker.ts
|
|
257
239
|
var STORAGE = "cache";
|
|
258
240
|
var CONF_ENV = "development";
|
|
259
|
-
var fetchAsset = async (
|
|
241
|
+
var fetchAsset = async (_ev, { entryId, mimeType, offlineWorkerSync: offlineWorkerSync2 }) => {
|
|
260
242
|
try {
|
|
261
|
-
const
|
|
262
|
-
const range = ev.request.headers.get("Range");
|
|
263
|
-
if (!ev.request.url.endsWith(".mp4") && !ev.request.url.endsWith(".webm")) {
|
|
264
|
-
return [buf2, {}];
|
|
265
|
-
}
|
|
266
|
-
if (!range) {
|
|
267
|
-
return [
|
|
268
|
-
buf2,
|
|
269
|
-
{
|
|
270
|
-
"Accept-Ranges": "bytes",
|
|
271
|
-
"Content-Range": `bytes ${0}-${buf2.byteLength}/${buf2.byteLength}`
|
|
272
|
-
}
|
|
273
|
-
];
|
|
274
|
-
}
|
|
275
|
-
const { start, end, chunkSize } = parseRange(range, buf2.byteLength);
|
|
276
|
-
const rangeHeaders = {
|
|
277
|
-
"Content-Length": chunkSize,
|
|
278
|
-
"Accept-Ranges": "bytes",
|
|
279
|
-
"Content-Range": `bytes ${start}-${end}/${buf2.byteLength}`
|
|
280
|
-
};
|
|
281
|
-
return [buf2.slice(start, end + 1), rangeHeaders];
|
|
282
|
-
});
|
|
243
|
+
const buf = await offlineWorkerSync2.readZipEntry(entryId);
|
|
283
244
|
return new Response(buf, {
|
|
284
245
|
headers: {
|
|
285
246
|
"Cache-Control": "max-age=600, s-maxage=600, public, proxy-revalidate",
|
|
286
247
|
"Content-Length": buf.byteLength,
|
|
287
|
-
"Content-Type": mimeType
|
|
288
|
-
...maybeRangeHeaders
|
|
248
|
+
"Content-Type": mimeType
|
|
289
249
|
},
|
|
290
250
|
// @ts-ignore: poor ts typing
|
|
291
|
-
status:
|
|
251
|
+
status: 200,
|
|
292
252
|
statusText: "OK"
|
|
293
253
|
});
|
|
294
254
|
} catch (e) {
|
|
@@ -387,16 +347,14 @@ swSelf.addEventListener("fetch", (ev) => {
|
|
|
387
347
|
return;
|
|
388
348
|
}
|
|
389
349
|
if (!mimeType && !isValidScreenCall) {
|
|
390
|
-
if (!/\.(css|tsx?|
|
|
350
|
+
if (!/\.(css|tsx?|jsx?|woff2|fr|manifest)(\??|$)|@(vite|react|id)/.test(url)) {
|
|
391
351
|
console.debug("no ext", extension || url);
|
|
392
352
|
}
|
|
393
353
|
return ev.respondWith(onlineFirst(ev.request, ev));
|
|
394
354
|
}
|
|
395
|
-
if (/favicon\.svg$/.test(url)) {
|
|
396
|
-
return;
|
|
397
|
-
}
|
|
398
355
|
const entryId = knownLinks.get(url.replace(/https:\/\/.*?\//, "")) || knownLinks.get(`medias/${url.replace(/https:\/\/.*?\//, "")}`);
|
|
399
356
|
if (isValidScreenCall) {
|
|
357
|
+
console.debug("screencall!");
|
|
400
358
|
return ev.respondWith(fetchScreenCall(ev, { offlineWorkerSync, knownLinks }));
|
|
401
359
|
}
|
|
402
360
|
if (entryId) {
|
|
@@ -405,7 +363,6 @@ swSelf.addEventListener("fetch", (ev) => {
|
|
|
405
363
|
if (/lls|lelivrescolaire/.test(url)) {
|
|
406
364
|
console.info("no link for", url.replace(/https:\/\/.*?\//, ""), `medias/${url.replace(/https:\/\/.*?\//, "")}`);
|
|
407
365
|
}
|
|
408
|
-
console.debug("unintercepted url", url);
|
|
409
366
|
return;
|
|
410
367
|
});
|
|
411
368
|
swSelf.addEventListener("install", (_event) => {
|
|
@@ -426,10 +383,7 @@ var initChannel = async (__, { ports }) => {
|
|
|
426
383
|
);
|
|
427
384
|
offlineWorkerSync = sender;
|
|
428
385
|
offlineWorker.onmessage = handler.handle;
|
|
429
|
-
offlineWorkerSync.on("setKnownLinks", (
|
|
430
|
-
setKnownLinks(knownLinks, { entryNames, bookId });
|
|
431
|
-
offlineWorker.postMessage({ methodName: "setKnownLinks:back", eventId });
|
|
432
|
-
});
|
|
386
|
+
offlineWorkerSync.on("setKnownLinks", setKnownLinks.bind(null, knownLinks));
|
|
433
387
|
offlineWorker.postMessage({ methodName: "sendAppReady" });
|
|
434
388
|
};
|
|
435
389
|
var knownLinks = /* @__PURE__ */ new Map();
|
|
@@ -802,14 +802,12 @@ var readZipEntry = async ({
|
|
|
802
802
|
const originalName = manifest.medias[zipName];
|
|
803
803
|
overridenName = `medias/${originalName}`;
|
|
804
804
|
} else {
|
|
805
|
-
|
|
806
|
-
console.error("any media should exist in manifest", zipName, entryName, bookId);
|
|
807
|
-
}
|
|
805
|
+
console.error("any media should exist in manifest", zipName, entryName, bookId);
|
|
808
806
|
}
|
|
809
807
|
}
|
|
810
808
|
const bookEntry = BOOKS[bookId].map.get(overridenName);
|
|
811
809
|
if (!bookEntry) {
|
|
812
|
-
console.info("no bookEntry", entryName, "
|
|
810
|
+
console.info("no bookEntry", entryName, "found", overridenName);
|
|
813
811
|
return null;
|
|
814
812
|
}
|
|
815
813
|
if (!bookEntry.decoded) {
|
|
@@ -888,8 +886,7 @@ var fetchZipFile = async (zipUrl, { forceRefresh } = {}) => {
|
|
|
888
886
|
return back;
|
|
889
887
|
}
|
|
890
888
|
if (STORAGE === "cache") {
|
|
891
|
-
const
|
|
892
|
-
const response = await cache.match(zipUrl);
|
|
889
|
+
const response = await caches.match(zipUrl);
|
|
893
890
|
if (!response) {
|
|
894
891
|
throw new Error(`missing zip ${zipUrl}`);
|
|
895
892
|
}
|
|
@@ -913,11 +910,7 @@ var fetchZipFile = async (zipUrl, { forceRefresh } = {}) => {
|
|
|
913
910
|
const buf = await readArrayBuffer();
|
|
914
911
|
if (CHECK_UPDATES) {
|
|
915
912
|
const response = await fetch(zipUrl, { method: "HEAD" });
|
|
916
|
-
|
|
917
|
-
if (!remoteSize) {
|
|
918
|
-
console.info("remoteSize not found. will skip update. Is the server up at", zipUrl);
|
|
919
|
-
remoteSize = buf.byteLength;
|
|
920
|
-
}
|
|
913
|
+
const remoteSize = Number.parseInt(response.headers.get("content-length") || "0", 10);
|
|
921
914
|
if (remoteSize !== buf.byteLength) {
|
|
922
915
|
const error = `new ${fileName} available, refetching (opfs:${buf.byteLength} vs remote:${remoteSize})`;
|
|
923
916
|
console.debug(error);
|
|
@@ -925,7 +918,6 @@ var fetchZipFile = async (zipUrl, { forceRefresh } = {}) => {
|
|
|
925
918
|
throw new Error(`new ${fileName} available, refetching`);
|
|
926
919
|
}
|
|
927
920
|
}
|
|
928
|
-
self.postMessage({ methodName: "opfsProgress", arg: { total: buf.byteLength, bytes: buf.byteLength } });
|
|
929
921
|
return buf;
|
|
930
922
|
} catch (e) {
|
|
931
923
|
if (e instanceof Error && e.message !== "forceRefresh" && !e.message.includes("refetching")) {
|
|
@@ -1000,12 +992,7 @@ var loadBook2 = async ({ id: bookId, forceRefresh }) => {
|
|
|
1000
992
|
const buf = await fetchZipFile(`${ZIP_BASE_URL}/${bookId}.zip`, { forceRefresh });
|
|
1001
993
|
try {
|
|
1002
994
|
const entryNames = await loadZip(new Uint8Array(buf), bookId);
|
|
1003
|
-
|
|
1004
|
-
const responseForEventId = new Promise((resolve, reject) => {
|
|
1005
|
-
dicFetchWorkerCallback[eventId] = { resolve, reject };
|
|
1006
|
-
});
|
|
1007
|
-
fetchWorker.postMessage({ methodName: "setKnownLinks", arg: { entryNames, bookId, eventId } });
|
|
1008
|
-
await responseForEventId;
|
|
995
|
+
fetchWorker.postMessage({ methodName: "setKnownLinks", arg: { entryNames, bookId } });
|
|
1009
996
|
if (isOldZip(bookId)) {
|
|
1010
997
|
const json = await readZipEntry({
|
|
1011
998
|
entryName: `preload/${bookId}.json`,
|
|
@@ -1013,13 +1000,6 @@ var loadBook2 = async ({ id: bookId, forceRefresh }) => {
|
|
|
1013
1000
|
asJson: true
|
|
1014
1001
|
});
|
|
1015
1002
|
loadBook(json);
|
|
1016
|
-
} else {
|
|
1017
|
-
try {
|
|
1018
|
-
const { createdAt } = await readZipEntry({ bookId, entryName: "manifest.json", asJson: true });
|
|
1019
|
-
console.debug("zipversion", createdAt);
|
|
1020
|
-
} catch (e) {
|
|
1021
|
-
console.debug("failed to read manifest.json", e);
|
|
1022
|
-
}
|
|
1023
1003
|
}
|
|
1024
1004
|
return true;
|
|
1025
1005
|
} catch (e) {
|
|
@@ -1049,14 +1029,6 @@ var loadPageContent2 = async ({
|
|
|
1049
1029
|
return await loadPageContent({ chapterId, json });
|
|
1050
1030
|
};
|
|
1051
1031
|
var fetchWorker;
|
|
1052
|
-
var dicFetchWorkerCallback = {};
|
|
1053
|
-
var handleFetchWorkerCallback = ({ data: { eventId } }) => {
|
|
1054
|
-
if (dicFetchWorkerCallback[eventId]) {
|
|
1055
|
-
dicFetchWorkerCallback[eventId].resolve();
|
|
1056
|
-
} else {
|
|
1057
|
-
console.debug("unknown eventId", eventId);
|
|
1058
|
-
}
|
|
1059
|
-
};
|
|
1060
1032
|
var initChannel = (__, { ports }) => {
|
|
1061
1033
|
fetchWorker = ports[0];
|
|
1062
1034
|
const { canHandle, handle } = makeSyncHandler(fetchWorker, {
|
|
@@ -1071,14 +1043,6 @@ var initChannel = (__, { ports }) => {
|
|
|
1071
1043
|
self.postMessage({ methodName: "ready" });
|
|
1072
1044
|
return;
|
|
1073
1045
|
}
|
|
1074
|
-
if (dataObj.data?.methodName === "setKnownLinks:back") {
|
|
1075
|
-
if (typeof dataObj?.data?.eventId !== "string") {
|
|
1076
|
-
console.debug("missing eventId to get response back for setKnownLinks:back");
|
|
1077
|
-
return;
|
|
1078
|
-
}
|
|
1079
|
-
handleFetchWorkerCallback(dataObj);
|
|
1080
|
-
return;
|
|
1081
|
-
}
|
|
1082
1046
|
if (canHandle(dataObj.data?.methodName || "")) {
|
|
1083
1047
|
return handle(dataObj);
|
|
1084
1048
|
}
|
package/lib/index.js
CHANGED
|
@@ -161,7 +161,6 @@ var installWorker = async ({
|
|
|
161
161
|
setBooksLoaded();
|
|
162
162
|
};
|
|
163
163
|
var useOfflineWorker_default = ({
|
|
164
|
-
skipLoadBooks,
|
|
165
164
|
primaryOnly = false,
|
|
166
165
|
nativeReadFile,
|
|
167
166
|
nativeWriteFile,
|
|
@@ -175,7 +174,6 @@ var useOfflineWorker_default = ({
|
|
|
175
174
|
useEffect(() => {
|
|
176
175
|
const fn = async () => {
|
|
177
176
|
await installWorker({
|
|
178
|
-
skipLoadBooks,
|
|
179
177
|
primaryOnly,
|
|
180
178
|
nativeReadFile,
|
|
181
179
|
nativeWriteFile,
|
|
@@ -190,21 +188,11 @@ var useOfflineWorker_default = ({
|
|
|
190
188
|
setReady(true);
|
|
191
189
|
};
|
|
192
190
|
fn();
|
|
193
|
-
}, [
|
|
194
|
-
skipLoadBooks,
|
|
195
|
-
primaryOnly,
|
|
196
|
-
nativeReadFile,
|
|
197
|
-
nativeWriteFile,
|
|
198
|
-
nativeListZips,
|
|
199
|
-
storage,
|
|
200
|
-
zipBaseUrl,
|
|
201
|
-
checkUpdates,
|
|
202
|
-
confEnv
|
|
203
|
-
]);
|
|
191
|
+
}, [primaryOnly, nativeReadFile, nativeWriteFile, nativeListZips, storage, zipBaseUrl, checkUpdates, confEnv]);
|
|
204
192
|
const loadBook = useCallback(
|
|
205
|
-
async ({
|
|
206
|
-
|
|
207
|
-
return await offlineWorkerSync.loadBook({ id
|
|
193
|
+
async ({ id, forceRefresh }, cbk) => {
|
|
194
|
+
offlineWorkerSync.on("opfsProgress", cbk);
|
|
195
|
+
return await offlineWorkerSync.loadBook({ id, forceRefresh });
|
|
208
196
|
},
|
|
209
197
|
[]
|
|
210
198
|
);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lls/offline",
|
|
3
|
-
"version": "24.27.0-
|
|
3
|
+
"version": "24.27.0-b7c9c281",
|
|
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.7",
|
|
53
53
|
"vite-tsconfig-paths": "5.1.4",
|
|
54
54
|
"zod": "3.25.50",
|
|
55
|
-
"@lls/vitescripts": "24.27.0-
|
|
55
|
+
"@lls/vitescripts": "24.27.0-b7c9c281"
|
|
56
56
|
},
|
|
57
57
|
"dependencies": {
|
|
58
58
|
"fflate": "0.8.2"
|