@lls/offline 24.27.0-ade60496 → 24.27.0-b0aebfc3

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.
@@ -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}, links size: ${knownLinks2.size}`);
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 (ev, { entryId, mimeType, offlineWorkerSync: offlineWorkerSync2 }) => {
241
+ var fetchAsset = async (_ev, { entryId, mimeType, offlineWorkerSync: offlineWorkerSync2 }) => {
260
242
  try {
261
- const [buf, maybeRangeHeaders] = await offlineWorkerSync2.readZipEntry(entryId).then((buf2) => {
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: maybeRangeHeaders["Content-Range"] ? 206 : 200,
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?|[mj]sx?|woff2|fr|(web)?manifest)(\??|$)|@(vite|react|id)|(:6019\/?$)/.test(url)) {
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", ({ entryNames, bookId, eventId }) => {
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
- if (entryName !== "manifest.json") {
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, "overridingName:", overridenName, "for book", bookId);
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 cache = await openCache(CONF_ENV);
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
- let remoteSize = Number.parseInt(response.headers.get("content-length") ?? "");
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
- const eventId = `setKnownLinks:${Date.now()}-${Math.random().toFixed(5)}`;
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 ({ forceRefresh, ...idOrUri }, cbk) => {
206
- cbk && offlineWorkerSync.on("opfsProgress", cbk);
207
- return await offlineWorkerSync.loadBook({ id: "id" in idOrUri ? idOrUri.id : idOrUri.uri, forceRefresh });
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-ade60496",
3
+ "version": "24.27.0-b0aebfc3",
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-ade60496"
55
+ "@lls/vitescripts": "24.27.0-b0aebfc3"
56
56
  },
57
57
  "dependencies": {
58
58
  "fflate": "0.8.2"