@lls/offline 24.27.0-9f297e77 → 24.27.0-a1932716

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 };
@@ -220,23 +202,12 @@ var coreFetchPagesApi = async (ev, { offlineWorkerSync: offlineWorkerSync2, vari
220
202
  }
221
203
  }
222
204
  };
223
- var cocoreFetchPrimaryMethod = async (_ev, { offlineWorkerSync: offlineWorkerSync2, variables }) => {
224
- const uri = variables.uris?.[0];
225
- if (!uri) {
226
- throw new Error("invalid uri");
227
- }
228
- const method = await offlineWorkerSync2.readZipEntry({ bookId: uri, entryName: "gqls/method.json", asJson: true });
229
- return {
230
- data: method
231
- };
232
- };
233
205
  var handles = {
234
206
  coreFetchBookDrawerScreen,
235
207
  cocoreFetchBookScreen,
236
208
  coreFetchPagesApi,
237
209
  cocoreFetchPartialPageScreen,
238
- cocoreFetchPartialPageSiblingsScreen,
239
- cocoreFetchPrimaryMethod
210
+ cocoreFetchPartialPageSiblingsScreen
240
211
  };
241
212
  var canHandleScreenCall = (url) => new RegExp(Object.keys(handles).join("|")).test(url);
242
213
  var handleScreenCall = async (ev, { offlineWorkerSync: offlineWorkerSync2, knownLinks: knownLinks2 }) => {
@@ -245,8 +216,8 @@ var handleScreenCall = async (ev, { offlineWorkerSync: offlineWorkerSync2, known
245
216
  // @ts-expect-error TODO: handle variables from body(stream) properly!!
246
217
  ev.request.body?.variables || JSON.parse(new URLSearchParams(new URL(ev.request.url).search).get("variables") || "{}")
247
218
  );
219
+ console.debug("variables are", variables, "vs", ev.request.body);
248
220
  const key = ev.request.url.match(Object.keys(handles).join("|"))?.[0];
249
- console.debug("screencall", key, "qs", variables, "vs body", ev.request.body);
250
221
  if (!key) {
251
222
  throw new Error("unknown ev");
252
223
  }
@@ -267,39 +238,17 @@ var setKnownLinks = (knownLinks2, { entryNames, bookId }) => {
267
238
  // src/worker/fetch-worker.ts
268
239
  var STORAGE = "cache";
269
240
  var CONF_ENV = "development";
270
- var fetchAsset = async (ev, { entryId, mimeType, offlineWorkerSync: offlineWorkerSync2 }) => {
241
+ var fetchAsset = async (_ev, { entryId, mimeType, offlineWorkerSync: offlineWorkerSync2 }) => {
271
242
  try {
272
- const [buf, maybeRangeHeaders] = await offlineWorkerSync2.readZipEntry(entryId).then((buf2) => {
273
- const range = ev.request.headers.get("Range");
274
- if (!ev.request.url.endsWith(".mp4") && !ev.request.url.endsWith(".webm")) {
275
- return [buf2, {}];
276
- }
277
- if (!range) {
278
- return [
279
- buf2,
280
- {
281
- "Accept-Ranges": "bytes",
282
- "Content-Range": `bytes ${0}-${buf2.byteLength}/${buf2.byteLength}`
283
- }
284
- ];
285
- }
286
- const { start, end, chunkSize } = parseRange(range, buf2.byteLength);
287
- const rangeHeaders = {
288
- "Content-Length": chunkSize,
289
- "Accept-Ranges": "bytes",
290
- "Content-Range": `bytes ${start}-${end}/${buf2.byteLength}`
291
- };
292
- return [buf2.slice(start, end + 1), rangeHeaders];
293
- });
243
+ const buf = await offlineWorkerSync2.readZipEntry(entryId);
294
244
  return new Response(buf, {
295
245
  headers: {
296
246
  "Cache-Control": "max-age=600, s-maxage=600, public, proxy-revalidate",
297
247
  "Content-Length": buf.byteLength,
298
- "Content-Type": mimeType,
299
- ...maybeRangeHeaders
248
+ "Content-Type": mimeType
300
249
  },
301
250
  // @ts-ignore: poor ts typing
302
- status: maybeRangeHeaders["Content-Range"] ? 206 : 200,
251
+ status: 200,
303
252
  statusText: "OK"
304
253
  });
305
254
  } catch (e) {
@@ -398,16 +347,14 @@ swSelf.addEventListener("fetch", (ev) => {
398
347
  return;
399
348
  }
400
349
  if (!mimeType && !isValidScreenCall) {
401
- 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)) {
402
351
  console.debug("no ext", extension || url);
403
352
  }
404
353
  return ev.respondWith(onlineFirst(ev.request, ev));
405
354
  }
406
- if (/http:\/\/localhost:\d+\/(favicon\.svg|assets\/)/.test(url)) {
407
- return;
408
- }
409
355
  const entryId = knownLinks.get(url.replace(/https:\/\/.*?\//, "")) || knownLinks.get(`medias/${url.replace(/https:\/\/.*?\//, "")}`);
410
356
  if (isValidScreenCall) {
357
+ console.debug("screencall!");
411
358
  return ev.respondWith(fetchScreenCall(ev, { offlineWorkerSync, knownLinks }));
412
359
  }
413
360
  if (entryId) {
@@ -416,7 +363,6 @@ swSelf.addEventListener("fetch", (ev) => {
416
363
  if (/lls|lelivrescolaire/.test(url)) {
417
364
  console.info("no link for", url.replace(/https:\/\/.*?\//, ""), `medias/${url.replace(/https:\/\/.*?\//, "")}`);
418
365
  }
419
- console.debug("unintercepted url", url);
420
366
  return;
421
367
  });
422
368
  swSelf.addEventListener("install", (_event) => {
@@ -437,10 +383,7 @@ var initChannel = async (__, { ports }) => {
437
383
  );
438
384
  offlineWorkerSync = sender;
439
385
  offlineWorker.onmessage = handler.handle;
440
- offlineWorkerSync.on("setKnownLinks", ({ entryNames, bookId, eventId }) => {
441
- setKnownLinks(knownLinks, { entryNames, bookId });
442
- offlineWorker.postMessage({ methodName: "setKnownLinks:back", eventId });
443
- });
386
+ offlineWorkerSync.on("setKnownLinks", setKnownLinks.bind(null, knownLinks));
444
387
  offlineWorker.postMessage({ methodName: "sendAppReady" });
445
388
  };
446
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")) {
@@ -955,7 +947,6 @@ var fetchZipFile = async (zipUrl, { forceRefresh } = {}) => {
955
947
  self.postMessage({ methodName: "opfsProgress", arg: { total: contentLength, bytes: position } });
956
948
  }
957
949
  }
958
- console.debug("zip loaded:", arrayBuffer.byteLength);
959
950
  if (STORAGE === "native") {
960
951
  await sender.nativeWriteFile({ fname: fileName, buffer: arrayBuffer });
961
952
  } else if (STORAGE === "opfs") {
@@ -1001,12 +992,7 @@ var loadBook2 = async ({ id: bookId, forceRefresh }) => {
1001
992
  const buf = await fetchZipFile(`${ZIP_BASE_URL}/${bookId}.zip`, { forceRefresh });
1002
993
  try {
1003
994
  const entryNames = await loadZip(new Uint8Array(buf), bookId);
1004
- const eventId = `setKnownLinks:${Date.now()}-${Math.random().toFixed(5)}`;
1005
- const responseForEventId = new Promise((resolve, reject) => {
1006
- dicFetchWorkerCallback[eventId] = { resolve, reject };
1007
- });
1008
- fetchWorker.postMessage({ methodName: "setKnownLinks", arg: { entryNames, bookId, eventId } });
1009
- await responseForEventId;
995
+ fetchWorker.postMessage({ methodName: "setKnownLinks", arg: { entryNames, bookId } });
1010
996
  if (isOldZip(bookId)) {
1011
997
  const json = await readZipEntry({
1012
998
  entryName: `preload/${bookId}.json`,
@@ -1014,13 +1000,6 @@ var loadBook2 = async ({ id: bookId, forceRefresh }) => {
1014
1000
  asJson: true
1015
1001
  });
1016
1002
  loadBook(json);
1017
- } else {
1018
- try {
1019
- const { createdAt } = await readZipEntry({ bookId, entryName: "manifest.json", asJson: true });
1020
- console.debug("zipversion", createdAt);
1021
- } catch (e) {
1022
- console.debug("failed to read manifest.json", e);
1023
- }
1024
1003
  }
1025
1004
  return true;
1026
1005
  } catch (e) {
@@ -1050,14 +1029,6 @@ var loadPageContent2 = async ({
1050
1029
  return await loadPageContent({ chapterId, json });
1051
1030
  };
1052
1031
  var fetchWorker;
1053
- var dicFetchWorkerCallback = {};
1054
- var handleFetchWorkerCallback = ({ data: { eventId } }) => {
1055
- if (dicFetchWorkerCallback[eventId]) {
1056
- dicFetchWorkerCallback[eventId].resolve();
1057
- } else {
1058
- console.debug("unknown eventId", eventId);
1059
- }
1060
- };
1061
1032
  var initChannel = (__, { ports }) => {
1062
1033
  fetchWorker = ports[0];
1063
1034
  const { canHandle, handle } = makeSyncHandler(fetchWorker, {
@@ -1072,14 +1043,6 @@ var initChannel = (__, { ports }) => {
1072
1043
  self.postMessage({ methodName: "ready" });
1073
1044
  return;
1074
1045
  }
1075
- if (dataObj.data?.methodName === "setKnownLinks:back") {
1076
- if (typeof dataObj?.data?.eventId !== "string") {
1077
- console.debug("missing eventId to get response back for setKnownLinks:back");
1078
- return;
1079
- }
1080
- handleFetchWorkerCallback(dataObj);
1081
- return;
1082
- }
1083
1046
  if (canHandle(dataObj.data?.methodName || "")) {
1084
1047
  return handle(dataObj);
1085
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-9f297e77",
3
+ "version": "24.27.0-a1932716",
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-9f297e77"
55
+ "@lls/vitescripts": "24.27.0-a1932716"
56
56
  },
57
57
  "dependencies": {
58
58
  "fflate": "0.8.2"