@lls/offline 24.28.0 → 24.29.0-038ff270
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 +46 -49
- package/lib/assets/offline-worker.js +43 -50
- package/lib/builttypes/offline/src/hooks/useOfflineWorker.d.ts +33 -0
- package/lib/builttypes/offline/src/index.d.ts +3 -0
- package/lib/builttypes/offline/src/store/index.d.ts +3 -0
- package/lib/builttypes/offline/src/store/offlinePersist.d.ts +8 -0
- package/lib/builttypes/offline/src/utils/error.d.ts +2 -0
- package/lib/builttypes/offline/src/utils/stream.d.ts +5 -0
- package/lib/builttypes/offline/src/utils/worker.d.ts +29 -0
- package/lib/builttypes/offline/src/utils/zipDecoder.d.ts +7 -0
- package/lib/builttypes/offline/src/worker/fetch-worker.d.ts +16 -0
- package/lib/builttypes/offline/src/worker/offline-worker.d.ts +67 -0
- package/lib/builttypes/offline/src/worker/swFetchScreenCall.d.ts +14 -0
- package/lib/builttypes/offline/src/worker/wwApi.d.ts +58 -0
- package/lib/builttypes/offline/src/worker/wwZip.d.ts +9 -0
- package/lib/index.js +36 -31
- package/package.json +7 -3
- package/lib/index.d.ts +0 -1
|
@@ -17,10 +17,10 @@ var parseRange = (range, size) => {
|
|
|
17
17
|
};
|
|
18
18
|
|
|
19
19
|
// src/utils/worker.ts
|
|
20
|
-
var makeSyncWorker = (
|
|
20
|
+
var makeSyncWorker = (offlineWorker, methodNames, dbg) => {
|
|
21
21
|
const dic = {};
|
|
22
22
|
const cbks = {};
|
|
23
|
-
const fn = ({ data: { eventId, methodName, results, error, arg } = {} }
|
|
23
|
+
const fn = ({ source, data: { eventId, methodName, results, error, arg } = {} }) => {
|
|
24
24
|
if (eventId && eventId in dic) {
|
|
25
25
|
if (error) {
|
|
26
26
|
dic[eventId].reject(error);
|
|
@@ -28,11 +28,11 @@ var makeSyncWorker = (offlineWorker2, methodNames, dbg) => {
|
|
|
28
28
|
dic[eventId].resolve(results);
|
|
29
29
|
}
|
|
30
30
|
} else {
|
|
31
|
-
if (methodName && !
|
|
31
|
+
if (methodName && !(methodName in cbks)) {
|
|
32
32
|
console.error(`syncWorker: unknown methodName cbk ${dbg}`, eventId, methodName, error);
|
|
33
33
|
}
|
|
34
34
|
}
|
|
35
|
-
methodName && cbks[methodName]?.(arg);
|
|
35
|
+
methodName && cbks[methodName]?.({ source, ...arg });
|
|
36
36
|
};
|
|
37
37
|
const makeFn = (methodName) => {
|
|
38
38
|
return ({ ports, ...arg } = {}) => {
|
|
@@ -40,7 +40,7 @@ var makeSyncWorker = (offlineWorker2, methodNames, dbg) => {
|
|
|
40
40
|
const eventId = `${methodName}:${Date.now()}-${Math.random().toFixed(5)}`;
|
|
41
41
|
let resolved = false;
|
|
42
42
|
const timeout = setTimeout(() => {
|
|
43
|
-
console.warn("slow request for", methodName, arg);
|
|
43
|
+
console.warn("slow request for", methodName, arg, eventId);
|
|
44
44
|
}, 3e3);
|
|
45
45
|
const doResolve = (arg2) => {
|
|
46
46
|
if (!resolved) {
|
|
@@ -50,11 +50,16 @@ var makeSyncWorker = (offlineWorker2, methodNames, dbg) => {
|
|
|
50
50
|
}
|
|
51
51
|
};
|
|
52
52
|
dic[eventId] = { resolve: doResolve, reject };
|
|
53
|
-
|
|
53
|
+
if (ports) {
|
|
54
|
+
offlineWorker.postMessage({ eventId, methodName, arg }, ports);
|
|
55
|
+
} else {
|
|
56
|
+
offlineWorker.postMessage({ eventId, methodName, arg });
|
|
57
|
+
}
|
|
54
58
|
});
|
|
55
59
|
};
|
|
56
60
|
};
|
|
57
|
-
const
|
|
61
|
+
const fns = Object.fromEntries(methodNames.map((name) => [name, makeFn(name)]));
|
|
62
|
+
const obj = Object.assign(fns, {
|
|
58
63
|
on: (key, fn2) => {
|
|
59
64
|
cbks[key] = fn2;
|
|
60
65
|
}
|
|
@@ -71,26 +76,38 @@ var makeSyncWorker = (offlineWorker2, methodNames, dbg) => {
|
|
|
71
76
|
};
|
|
72
77
|
var a = (a2) => a2;
|
|
73
78
|
var makeSyncHandler = a(
|
|
74
|
-
(
|
|
79
|
+
(services) => ({
|
|
75
80
|
canHandle: (methodName) => {
|
|
76
81
|
return methodName in services;
|
|
77
82
|
},
|
|
78
|
-
handle: async ({ data: { eventId, methodName, arg } = {}, ports }) => {
|
|
83
|
+
handle: async ({ data: { eventId, methodName, arg } = {}, source, ports, target }) => {
|
|
84
|
+
const emitter = source?.postMessage && source || target?.postMessage && target || self;
|
|
79
85
|
try {
|
|
80
86
|
if (typeof methodName === "string" && methodName in services && services[methodName]) {
|
|
81
87
|
const results = await services[methodName](arg, { ports });
|
|
82
|
-
|
|
88
|
+
emitter.postMessage({ eventId, methodName, results });
|
|
83
89
|
return;
|
|
84
90
|
}
|
|
85
91
|
throw new Error(`invalid methodName ${Object.keys(services)} |${String(methodName)}`);
|
|
86
92
|
} catch (e) {
|
|
87
93
|
console.debug("failed", e);
|
|
88
|
-
|
|
94
|
+
emitter.postMessage({ eventId, methodName, error: e });
|
|
89
95
|
}
|
|
90
96
|
}
|
|
91
97
|
})
|
|
92
98
|
);
|
|
93
99
|
var jsonToBuf = (json) => new TextEncoder().encode(JSON.stringify(json));
|
|
100
|
+
var combineHandlers = (...handlers) => {
|
|
101
|
+
return (message) => {
|
|
102
|
+
const methodName = String("methodName" in message.data ? message.data.methodName : "");
|
|
103
|
+
for (const h of handlers) {
|
|
104
|
+
if (h.canHandle(methodName)) {
|
|
105
|
+
return h.handle(message);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
console.error("no handlers matched", methodName);
|
|
109
|
+
};
|
|
110
|
+
};
|
|
94
111
|
var openCache = async (mode) => caches.open(`LLS_OFFLINE_${mode}`);
|
|
95
112
|
var isStoryZip = (name) => /story-.*?\.zip/.test(name);
|
|
96
113
|
var isValidZipName = (name) => {
|
|
@@ -339,7 +356,7 @@ var fetchAsset = async (ev, { entryId, mimeType, offlineWorkerSync: offlineWorke
|
|
|
339
356
|
try {
|
|
340
357
|
const [buf, maybeRangeHeaders] = await offlineWorkerSync2.readZipEntry(entryId).then((buf2) => {
|
|
341
358
|
const range = ev.request.headers.get("Range");
|
|
342
|
-
if (!
|
|
359
|
+
if (!hasStreamingExtension(ev.request.url)) {
|
|
343
360
|
return [buf2, {}];
|
|
344
361
|
}
|
|
345
362
|
if (!range) {
|
|
@@ -420,6 +437,7 @@ var ACCEPTED_EXTENSIONS = {
|
|
|
420
437
|
".riv": "application/octet-stream",
|
|
421
438
|
".pdf": "application/pdf"
|
|
422
439
|
};
|
|
440
|
+
var hasStreamingExtension = (str) => /\.(mp3|mp4|webm|m4a)$/.test(str);
|
|
423
441
|
var putInCache = async (request, response) => {
|
|
424
442
|
const cache = await openCache(CONF_ENV);
|
|
425
443
|
await cache.put(request, response);
|
|
@@ -429,7 +447,7 @@ var tryOnline = async (request, event) => {
|
|
|
429
447
|
if (isValidZipName(request.url) && !isValidS3Zip(responseFromNetwork)) {
|
|
430
448
|
throw new Error(`zip is invalid: got ${responseFromNetwork.headers.get("Content-Length")} bytes`);
|
|
431
449
|
}
|
|
432
|
-
const cached = request.method === "
|
|
450
|
+
const cached = request.method === "GET" || request.method === "OPTIONS" ? putInCache(request, responseFromNetwork.clone()) : Promise.resolve();
|
|
433
451
|
if (request.url.endsWith(".zip")) {
|
|
434
452
|
await cached;
|
|
435
453
|
event.waitUntil(Promise.resolve());
|
|
@@ -450,7 +468,7 @@ var onlineFirst = async (request, event) => {
|
|
|
450
468
|
const responseFromCache = await tryOffline(request, event);
|
|
451
469
|
if (!responseFromCache) {
|
|
452
470
|
return new Response(
|
|
453
|
-
`FAILED fetch ${e && typeof e === "object" && "message" in e ? e.message : e?.toString?.()}`,
|
|
471
|
+
`FAILED onlineFirst fetch ${e && typeof e === "object" && "message" in e ? e.message : e?.toString?.()} | ${event.request.url}`,
|
|
454
472
|
{
|
|
455
473
|
// @ts-ignore: poor ts typing
|
|
456
474
|
ok: false,
|
|
@@ -475,6 +493,9 @@ swSelf.addEventListener("fetch", (ev) => {
|
|
|
475
493
|
}
|
|
476
494
|
return;
|
|
477
495
|
}
|
|
496
|
+
if (/api(-dev|-preprod)?\.lelivrescolaire\.fr\/?$/.test(url) && ev.request.method === "HEAD") {
|
|
497
|
+
return;
|
|
498
|
+
}
|
|
478
499
|
if (!mimeType && !isValidScreenCall) {
|
|
479
500
|
if (!/\.(css|tsx?|[mj]sx?|woff2|wasm|fr|(web)?manifest)(\??|$)|@(vite|react|id)|(:6019\/?$)/.test(url)) {
|
|
480
501
|
console.debug("no ext", extension || url);
|
|
@@ -503,23 +524,23 @@ swSelf.addEventListener("install", (_event) => {
|
|
|
503
524
|
swSelf.addEventListener("activate", (event) => {
|
|
504
525
|
event.waitUntil(swSelf.clients.claim());
|
|
505
526
|
});
|
|
506
|
-
var
|
|
527
|
+
var setKnownLinks2 = (arg) => setKnownLinks(knownLinks, arg);
|
|
507
528
|
var offlineWorkerSync;
|
|
508
529
|
var initChannel = async (__, { ports }) => {
|
|
509
530
|
console.info(`FETCH WORKER innitChannel v${/* @__PURE__ */ new Date()}`);
|
|
510
|
-
offlineWorker = ports[0];
|
|
511
|
-
const { handler, ...sender } = makeSyncWorker(
|
|
531
|
+
const offlineWorker = ports[0];
|
|
532
|
+
const { handler: syncHandler, ...sender } = makeSyncWorker(
|
|
512
533
|
offlineWorker,
|
|
513
|
-
["readZipEntry", "loadBook", "slugToFileMeta", "loadPageContent", "searchBooks"],
|
|
534
|
+
["readZipEntry", "loadBook", "slugToFileMeta", "loadPageContent", "searchBooks", "ensureAppReady"],
|
|
514
535
|
"fetchworker"
|
|
515
536
|
);
|
|
537
|
+
const onHandler = makeSyncHandler({ setKnownLinks: setKnownLinks2 });
|
|
516
538
|
offlineWorkerSync = sender;
|
|
517
|
-
offlineWorker.onmessage =
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
offlineWorker.postMessage({ methodName: "sendAppReady" });
|
|
539
|
+
offlineWorker.onmessage = combineHandlers(syncHandler, onHandler);
|
|
540
|
+
offlineWorker.onclose = () => {
|
|
541
|
+
console.error("socket to ow has been closed!");
|
|
542
|
+
};
|
|
543
|
+
await offlineWorkerSync.ensureAppReady();
|
|
523
544
|
};
|
|
524
545
|
var knownLinks = /* @__PURE__ */ new Map();
|
|
525
546
|
var configure = ({
|
|
@@ -536,28 +557,4 @@ var configure = ({
|
|
|
536
557
|
}
|
|
537
558
|
console.info("sw::configure", { STORAGE, CONF_ENV });
|
|
538
559
|
};
|
|
539
|
-
swSelf.onmessage =
|
|
540
|
-
data: { methodName, arg } = {},
|
|
541
|
-
ports
|
|
542
|
-
}) => {
|
|
543
|
-
const services = {
|
|
544
|
-
initChannel,
|
|
545
|
-
configure
|
|
546
|
-
};
|
|
547
|
-
try {
|
|
548
|
-
if (methodName === "configure") {
|
|
549
|
-
await services[methodName](arg);
|
|
550
|
-
return;
|
|
551
|
-
}
|
|
552
|
-
if (methodName === "initChannel") {
|
|
553
|
-
if (!ports.length) {
|
|
554
|
-
throw new Error("fetchworker::missing port!");
|
|
555
|
-
}
|
|
556
|
-
await services[methodName](arg, { ports });
|
|
557
|
-
return;
|
|
558
|
-
}
|
|
559
|
-
throw new Error(`fetchworker:invalid methodName ${Object.keys(services)} ${methodName}`);
|
|
560
|
-
} catch (e) {
|
|
561
|
-
console.error("failed", methodName, arg, e);
|
|
562
|
-
}
|
|
563
|
-
};
|
|
560
|
+
swSelf.onmessage = combineHandlers(makeSyncHandler({ initChannel, configure }));
|
|
@@ -13,7 +13,7 @@ var tryCatch = (fn) => {
|
|
|
13
13
|
var makeSyncWorker = (offlineWorker, methodNames, dbg) => {
|
|
14
14
|
const dic = {};
|
|
15
15
|
const cbks = {};
|
|
16
|
-
const fn = ({ data: { eventId, methodName, results, error, arg } = {} }
|
|
16
|
+
const fn = ({ source, data: { eventId, methodName, results, error, arg } = {} }) => {
|
|
17
17
|
if (eventId && eventId in dic) {
|
|
18
18
|
if (error) {
|
|
19
19
|
dic[eventId].reject(error);
|
|
@@ -21,11 +21,11 @@ var makeSyncWorker = (offlineWorker, methodNames, dbg) => {
|
|
|
21
21
|
dic[eventId].resolve(results);
|
|
22
22
|
}
|
|
23
23
|
} else {
|
|
24
|
-
if (methodName && !
|
|
24
|
+
if (methodName && !(methodName in cbks)) {
|
|
25
25
|
console.error(`syncWorker: unknown methodName cbk ${dbg}`, eventId, methodName, error);
|
|
26
26
|
}
|
|
27
27
|
}
|
|
28
|
-
methodName && cbks[methodName]?.(arg);
|
|
28
|
+
methodName && cbks[methodName]?.({ source, ...arg });
|
|
29
29
|
};
|
|
30
30
|
const makeFn = (methodName) => {
|
|
31
31
|
return ({ ports, ...arg } = {}) => {
|
|
@@ -33,7 +33,7 @@ var makeSyncWorker = (offlineWorker, methodNames, dbg) => {
|
|
|
33
33
|
const eventId = `${methodName}:${Date.now()}-${Math.random().toFixed(5)}`;
|
|
34
34
|
let resolved = false;
|
|
35
35
|
const timeout = setTimeout(() => {
|
|
36
|
-
console.warn("slow request for", methodName, arg);
|
|
36
|
+
console.warn("slow request for", methodName, arg, eventId);
|
|
37
37
|
}, 3e3);
|
|
38
38
|
const doResolve = (arg2) => {
|
|
39
39
|
if (!resolved) {
|
|
@@ -43,11 +43,16 @@ var makeSyncWorker = (offlineWorker, methodNames, dbg) => {
|
|
|
43
43
|
}
|
|
44
44
|
};
|
|
45
45
|
dic[eventId] = { resolve: doResolve, reject };
|
|
46
|
-
|
|
46
|
+
if (ports) {
|
|
47
|
+
offlineWorker.postMessage({ eventId, methodName, arg }, ports);
|
|
48
|
+
} else {
|
|
49
|
+
offlineWorker.postMessage({ eventId, methodName, arg });
|
|
50
|
+
}
|
|
47
51
|
});
|
|
48
52
|
};
|
|
49
53
|
};
|
|
50
|
-
const
|
|
54
|
+
const fns = Object.fromEntries(methodNames.map((name) => [name, makeFn(name)]));
|
|
55
|
+
const obj = Object.assign(fns, {
|
|
51
56
|
on: (key2, fn2) => {
|
|
52
57
|
cbks[key2] = fn2;
|
|
53
58
|
}
|
|
@@ -64,31 +69,33 @@ var makeSyncWorker = (offlineWorker, methodNames, dbg) => {
|
|
|
64
69
|
};
|
|
65
70
|
var a = (a2) => a2;
|
|
66
71
|
var makeSyncHandler = a(
|
|
67
|
-
(
|
|
72
|
+
(services) => ({
|
|
68
73
|
canHandle: (methodName) => {
|
|
69
74
|
return methodName in services;
|
|
70
75
|
},
|
|
71
|
-
handle: async ({ data: { eventId, methodName, arg } = {}, ports }) => {
|
|
76
|
+
handle: async ({ data: { eventId, methodName, arg } = {}, source, ports, target }) => {
|
|
77
|
+
const emitter = source?.postMessage && source || target?.postMessage && target || self;
|
|
72
78
|
try {
|
|
73
79
|
if (typeof methodName === "string" && methodName in services && services[methodName]) {
|
|
74
80
|
const results = await services[methodName](arg, { ports });
|
|
75
|
-
|
|
81
|
+
emitter.postMessage({ eventId, methodName, results });
|
|
76
82
|
return;
|
|
77
83
|
}
|
|
78
84
|
throw new Error(`invalid methodName ${Object.keys(services)} |${String(methodName)}`);
|
|
79
85
|
} catch (e) {
|
|
80
86
|
console.debug("failed", e);
|
|
81
|
-
|
|
87
|
+
emitter.postMessage({ eventId, methodName, error: e });
|
|
82
88
|
}
|
|
83
89
|
}
|
|
84
90
|
})
|
|
85
91
|
);
|
|
86
92
|
var bufToJson = (buf) => JSON.parse(new TextDecoder("UTF-8").decode(new Uint8Array(buf)));
|
|
87
93
|
var combineHandlers = (...handlers) => {
|
|
88
|
-
return (
|
|
94
|
+
return (message) => {
|
|
95
|
+
const methodName = String("methodName" in message.data ? message.data.methodName : "");
|
|
89
96
|
for (const h of handlers) {
|
|
90
|
-
if (h.canHandle(
|
|
91
|
-
return h.handle(
|
|
97
|
+
if (h.canHandle(methodName)) {
|
|
98
|
+
return h.handle(message);
|
|
92
99
|
}
|
|
93
100
|
}
|
|
94
101
|
console.error("no handlers matched", methodName);
|
|
@@ -401,6 +408,7 @@ var fetchZipFile = async (zipUrl, { forceRefresh } = {}) => {
|
|
|
401
408
|
await accessHandle.close();
|
|
402
409
|
} else {
|
|
403
410
|
const cache = await openCache(CONF_ENV);
|
|
411
|
+
console.time("writing cache");
|
|
404
412
|
const response2 = new Response(arrayBuffer, {
|
|
405
413
|
headers: {
|
|
406
414
|
"Cache-Control": "max-age=600, s-maxage=600, public, proxy-revalidate",
|
|
@@ -413,9 +421,12 @@ var fetchZipFile = async (zipUrl, { forceRefresh } = {}) => {
|
|
|
413
421
|
type: "cors",
|
|
414
422
|
url: zipUrl
|
|
415
423
|
});
|
|
416
|
-
|
|
424
|
+
console.debug("writing to cache asynchronously, because takes 4s");
|
|
425
|
+
cache.put(zipUrl, response2).then(() => {
|
|
426
|
+
console.timeEnd("writing cache");
|
|
427
|
+
});
|
|
417
428
|
}
|
|
418
|
-
return
|
|
429
|
+
return arrayBuffer;
|
|
419
430
|
}
|
|
420
431
|
};
|
|
421
432
|
var slugToFileMeta2 = async ({ slug }) => {
|
|
@@ -437,12 +448,7 @@ var loadBook2 = async ({ id: bookId, forceRefresh }) => {
|
|
|
437
448
|
console.time("loadzip");
|
|
438
449
|
const entryNames = await loadZip(new Uint8Array(buf), bookId);
|
|
439
450
|
console.timeEnd("loadzip");
|
|
440
|
-
|
|
441
|
-
const responseForEventId = new Promise((resolve, reject) => {
|
|
442
|
-
dicFetchWorkerCallback[eventId] = { resolve, reject };
|
|
443
|
-
});
|
|
444
|
-
fetchWorker.postMessage({ methodName: "setKnownLinks", arg: { entryNames, bookId, eventId } });
|
|
445
|
-
await responseForEventId;
|
|
451
|
+
await fetchWorkerSync.setKnownLinks({ entryNames, bookId });
|
|
446
452
|
if (isOldZip(bookId)) {
|
|
447
453
|
const json = await readZipEntry({
|
|
448
454
|
entryName: `preload/${bookId}.json`,
|
|
@@ -485,43 +491,30 @@ var loadPageContent2 = async ({
|
|
|
485
491
|
});
|
|
486
492
|
return await loadPageContent({ chapterId, json });
|
|
487
493
|
};
|
|
488
|
-
var
|
|
489
|
-
var dicFetchWorkerCallback = {};
|
|
490
|
-
var handleFetchWorkerCallback = ({ data: { eventId } }) => {
|
|
491
|
-
if (dicFetchWorkerCallback[eventId]) {
|
|
492
|
-
dicFetchWorkerCallback[eventId].resolve();
|
|
493
|
-
} else {
|
|
494
|
-
console.debug("unknown eventId", eventId);
|
|
495
|
-
}
|
|
494
|
+
var ensureAppReady = () => {
|
|
496
495
|
};
|
|
496
|
+
var fetchWorker;
|
|
497
|
+
var fetchWorkerSync;
|
|
497
498
|
var initChannel = (__, { ports }) => {
|
|
498
499
|
fetchWorker = ports[0];
|
|
499
|
-
const
|
|
500
|
+
const onHandler = makeSyncHandler({
|
|
500
501
|
readZipEntry,
|
|
501
502
|
loadBook: loadBook2,
|
|
502
503
|
slugToFileMeta: slugToFileMeta2,
|
|
503
504
|
loadPageContent: loadPageContent2,
|
|
504
|
-
searchBooks
|
|
505
|
+
searchBooks,
|
|
506
|
+
ensureAppReady
|
|
505
507
|
});
|
|
506
|
-
const
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
}
|
|
516
|
-
handleFetchWorkerCallback(dataObj);
|
|
517
|
-
return;
|
|
518
|
-
}
|
|
519
|
-
if (canHandle(dataObj.data?.methodName || "")) {
|
|
520
|
-
return handle(dataObj);
|
|
521
|
-
}
|
|
522
|
-
console.error("unknown methodName", dataObj.data?.methodName);
|
|
508
|
+
const { handler: syncHandler, ...sender2 } = makeSyncWorker(
|
|
509
|
+
fetchWorker,
|
|
510
|
+
["setKnownLinks"],
|
|
511
|
+
"offline-worker"
|
|
512
|
+
);
|
|
513
|
+
fetchWorkerSync = sender2;
|
|
514
|
+
fetchWorker.onmessage = combineHandlers(syncHandler, onHandler);
|
|
515
|
+
fetchWorker.onclose = () => {
|
|
516
|
+
console.error("socket to sw has been closed!");
|
|
523
517
|
};
|
|
524
|
-
fetchWorker.onmessage = fn;
|
|
525
518
|
};
|
|
526
519
|
var loadBooks = async ({ primaryOnly = false } = {}) => {
|
|
527
520
|
let entries = [];
|
|
@@ -593,7 +586,7 @@ var reset = async () => {
|
|
|
593
586
|
await (await navigator.storage.getDirectory()).remove({ recursive: true });
|
|
594
587
|
console.info("opfs cleared");
|
|
595
588
|
};
|
|
596
|
-
var mainHandle = makeSyncHandler(
|
|
589
|
+
var mainHandle = makeSyncHandler({
|
|
597
590
|
initChannel,
|
|
598
591
|
loadPreload: loadPreload2,
|
|
599
592
|
readZipEntry,
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
type UseOfflineProps = {
|
|
2
|
+
skipLoadBooks?: boolean;
|
|
3
|
+
primaryOnly?: boolean;
|
|
4
|
+
nativeReadFile?: (arg: {
|
|
5
|
+
fname: string;
|
|
6
|
+
}) => Promise<ArrayBuffer>;
|
|
7
|
+
nativeWriteFile?: (arg: {
|
|
8
|
+
fname: string;
|
|
9
|
+
buffer: ArrayBuffer;
|
|
10
|
+
}) => Promise<void>;
|
|
11
|
+
nativeListZips?: () => Promise<Array<{
|
|
12
|
+
name: string;
|
|
13
|
+
}>>;
|
|
14
|
+
checkUpdates?: boolean;
|
|
15
|
+
storage?: 'opfs' | 'native' | 'cache';
|
|
16
|
+
zipBaseUrl?: string;
|
|
17
|
+
confEnv?: 'development' | 'production';
|
|
18
|
+
};
|
|
19
|
+
declare const _default: ({ skipLoadBooks, primaryOnly, nativeReadFile, nativeWriteFile, nativeListZips, checkUpdates, storage, zipBaseUrl, confEnv }?: UseOfflineProps) => {
|
|
20
|
+
ready: boolean;
|
|
21
|
+
loadBook: ({ forceRefresh, ...idOrUri }: {
|
|
22
|
+
forceRefresh?: boolean;
|
|
23
|
+
} & ({
|
|
24
|
+
id: number;
|
|
25
|
+
} | {
|
|
26
|
+
uri: string;
|
|
27
|
+
}), cbk?: (arg: {
|
|
28
|
+
bytes: number;
|
|
29
|
+
total: number;
|
|
30
|
+
}) => void) => Promise<void>;
|
|
31
|
+
reset: () => Promise<void>;
|
|
32
|
+
};
|
|
33
|
+
export default _default;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { persistStore } from 'redux-persist';
|
|
2
|
+
type Store = Parameters<typeof persistStore>[0];
|
|
3
|
+
import { type ReactNode } from 'react';
|
|
4
|
+
export declare const OfflinePersist: ({ store, children }: {
|
|
5
|
+
store: Store;
|
|
6
|
+
children: ReactNode;
|
|
7
|
+
}) => import("react/jsx-runtime").JSX.Element;
|
|
8
|
+
export {};
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { AnyFunction } from '@lls/typings/utils';
|
|
2
|
+
type OnMessageEvent = (m: MessageEvent) => void;
|
|
3
|
+
type Handler = {
|
|
4
|
+
canHandle: (methodName: string) => boolean;
|
|
5
|
+
handle: OnMessageEvent;
|
|
6
|
+
};
|
|
7
|
+
export declare const makeSyncWorker: <WorkerApi extends {
|
|
8
|
+
[k: string]: AnyFunction;
|
|
9
|
+
}>(offlineWorker: {
|
|
10
|
+
postMessage: Worker["postMessage"];
|
|
11
|
+
}, methodNames: string[], dbg?: string) => WorkerApi & {
|
|
12
|
+
on: (key: string, fn: AnyFunction) => void;
|
|
13
|
+
} & {
|
|
14
|
+
handler: Handler;
|
|
15
|
+
};
|
|
16
|
+
export declare const makeSyncHandler: (services: {
|
|
17
|
+
[k: string]: (...args: any[]) => any;
|
|
18
|
+
}) => {
|
|
19
|
+
canHandle: (methodName: string) => boolean;
|
|
20
|
+
handle: OnMessageEvent;
|
|
21
|
+
};
|
|
22
|
+
export declare const bufToJson: (buf: ArrayBuffer) => any;
|
|
23
|
+
export declare const jsonToBuf: (json: {}) => Uint8Array<ArrayBuffer>;
|
|
24
|
+
export declare const combineHandlers: (...handlers: Handler[]) => (message: MessageEvent) => void;
|
|
25
|
+
export declare const openCache: (mode: string) => Promise<Cache>;
|
|
26
|
+
export declare const clearCache: (mode: string) => Promise<boolean>;
|
|
27
|
+
export declare const isValidZipName: (name: string) => boolean;
|
|
28
|
+
export declare const isValidS3Zip: (response: Response) => boolean;
|
|
29
|
+
export {};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { setKnownLinks as handleSetKnownLinks } from '#offline/worker/swFetchScreenCall.ts';
|
|
2
|
+
declare const setKnownLinks: (arg: Parameters<typeof handleSetKnownLinks>[1]) => void;
|
|
3
|
+
export type FetchWorkerSync = {
|
|
4
|
+
setKnownLinks: typeof setKnownLinks;
|
|
5
|
+
};
|
|
6
|
+
declare const configure: ({ storage, confEnv }?: {
|
|
7
|
+
storage?: "native" | "opfs" | "cache";
|
|
8
|
+
confEnv?: "development" | "production";
|
|
9
|
+
}) => void;
|
|
10
|
+
export type FetchWorkerMain = {
|
|
11
|
+
initChannel: (d: {
|
|
12
|
+
ports: [MessagePort];
|
|
13
|
+
}) => void;
|
|
14
|
+
configure: typeof configure;
|
|
15
|
+
};
|
|
16
|
+
export {};
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import type { EntryId } from './types.js';
|
|
2
|
+
import { searchBooks } from './wwApi.js';
|
|
3
|
+
import { readZipEntry } from './wwZip.js';
|
|
4
|
+
declare const slugToFileMeta: ({ slug }: {
|
|
5
|
+
slug: string;
|
|
6
|
+
}) => Promise<{
|
|
7
|
+
pageId: number | undefined;
|
|
8
|
+
chapterId: number | undefined;
|
|
9
|
+
}>;
|
|
10
|
+
type BookId = number | string;
|
|
11
|
+
declare const loadBook: ({ id: bookId, forceRefresh }: {
|
|
12
|
+
id: BookId;
|
|
13
|
+
forceRefresh?: boolean;
|
|
14
|
+
}) => Promise<void>;
|
|
15
|
+
declare const loadPageContent: ({ bookId: iBookId, chapterId, pageId, entryId }: {
|
|
16
|
+
bookId?: number;
|
|
17
|
+
chapterId?: number;
|
|
18
|
+
pageId?: number;
|
|
19
|
+
entryId?: EntryId;
|
|
20
|
+
}) => Promise<{
|
|
21
|
+
viewer: {
|
|
22
|
+
pages: {
|
|
23
|
+
hits: [{
|
|
24
|
+
id: number;
|
|
25
|
+
book: {
|
|
26
|
+
slug: string;
|
|
27
|
+
urlLite: string;
|
|
28
|
+
};
|
|
29
|
+
chapter: {
|
|
30
|
+
id: number;
|
|
31
|
+
};
|
|
32
|
+
}];
|
|
33
|
+
};
|
|
34
|
+
};
|
|
35
|
+
}>;
|
|
36
|
+
declare const ensureAppReady: () => void;
|
|
37
|
+
export type OfflineWorkerSync = {
|
|
38
|
+
readZipEntry: typeof readZipEntry;
|
|
39
|
+
loadBook: typeof loadBook;
|
|
40
|
+
slugToFileMeta: typeof slugToFileMeta;
|
|
41
|
+
loadPageContent: typeof loadPageContent;
|
|
42
|
+
searchBooks: typeof searchBooks;
|
|
43
|
+
ensureAppReady: typeof ensureAppReady;
|
|
44
|
+
};
|
|
45
|
+
declare const loadBooks: ({ primaryOnly }?: {
|
|
46
|
+
primaryOnly?: boolean | undefined;
|
|
47
|
+
}) => Promise<void>;
|
|
48
|
+
declare const configure: ({ storage, checkUpdates, zipBaseUrl, confEnv }: {
|
|
49
|
+
storage?: "native" | "opfs" | "cache";
|
|
50
|
+
checkUpdates?: boolean;
|
|
51
|
+
zipBaseUrl?: string;
|
|
52
|
+
confEnv?: "development" | "production";
|
|
53
|
+
}) => void;
|
|
54
|
+
declare const loadPreload: () => Promise<void>;
|
|
55
|
+
declare const reset: () => Promise<void>;
|
|
56
|
+
export type OfflineWorkerSyncMain = {
|
|
57
|
+
initChannel: (d: {
|
|
58
|
+
ports: [MessagePort];
|
|
59
|
+
}) => void;
|
|
60
|
+
loadPreload: typeof loadPreload;
|
|
61
|
+
readZipEntry: typeof readZipEntry;
|
|
62
|
+
loadBooks: typeof loadBooks;
|
|
63
|
+
loadBook: typeof loadBook;
|
|
64
|
+
configure: typeof configure;
|
|
65
|
+
reset: typeof reset;
|
|
66
|
+
};
|
|
67
|
+
export {};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { OfflineWorkerSync } from './offline-worker';
|
|
2
|
+
import type { EntryId, SwEvent } from './types';
|
|
3
|
+
export declare const canHandleScreenCall: (url: string) => boolean;
|
|
4
|
+
export declare const handleScreenCall: (ev: SwEvent, { offlineWorkerSync, knownLinks }: {
|
|
5
|
+
offlineWorkerSync: OfflineWorkerSync;
|
|
6
|
+
knownLinks: Map<string, EntryId>;
|
|
7
|
+
}) => Promise<{
|
|
8
|
+
status: number;
|
|
9
|
+
json: any;
|
|
10
|
+
}>;
|
|
11
|
+
export declare const setKnownLinks: (knownLinks: Map<string, EntryId>, { entryNames, bookId }: {
|
|
12
|
+
entryNames: string[];
|
|
13
|
+
bookId: number | string;
|
|
14
|
+
}) => void;
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
type Book = {
|
|
2
|
+
id: number;
|
|
3
|
+
chapters: {
|
|
4
|
+
id: number;
|
|
5
|
+
}[];
|
|
6
|
+
uri: string;
|
|
7
|
+
slug: string;
|
|
8
|
+
urlLite: string;
|
|
9
|
+
};
|
|
10
|
+
type Page = {
|
|
11
|
+
id: number;
|
|
12
|
+
book: {
|
|
13
|
+
slug: string;
|
|
14
|
+
urlLite: string;
|
|
15
|
+
};
|
|
16
|
+
chapter: {
|
|
17
|
+
id: number;
|
|
18
|
+
};
|
|
19
|
+
};
|
|
20
|
+
type GqlBook = {
|
|
21
|
+
viewer: {
|
|
22
|
+
books: {
|
|
23
|
+
hits: [Book];
|
|
24
|
+
};
|
|
25
|
+
};
|
|
26
|
+
};
|
|
27
|
+
type GqlPage = {
|
|
28
|
+
viewer: {
|
|
29
|
+
pages: {
|
|
30
|
+
hits: [Page];
|
|
31
|
+
};
|
|
32
|
+
};
|
|
33
|
+
};
|
|
34
|
+
export declare const loadBook: (json: GqlBook) => void;
|
|
35
|
+
type SlugFile = {
|
|
36
|
+
[pageId: string]: `${number};${number}`;
|
|
37
|
+
};
|
|
38
|
+
export declare const slugToFileMeta: ({ slug, json }: {
|
|
39
|
+
slug: string;
|
|
40
|
+
json: SlugFile;
|
|
41
|
+
}) => Promise<{
|
|
42
|
+
pageId: number | undefined;
|
|
43
|
+
chapterId: number | undefined;
|
|
44
|
+
}>;
|
|
45
|
+
export declare const loadPageContent: ({ chapterId, json }: {
|
|
46
|
+
chapterId?: number;
|
|
47
|
+
json: GqlPage;
|
|
48
|
+
}) => Promise<GqlPage>;
|
|
49
|
+
export declare const searchBooks: ({ uris, slugs, ids, chapterIds }: {
|
|
50
|
+
uris?: string[];
|
|
51
|
+
slugs?: string[];
|
|
52
|
+
ids?: number[];
|
|
53
|
+
chapterIds?: (number | undefined)[];
|
|
54
|
+
}) => Promise<(Omit<Book, "chapters"> & {
|
|
55
|
+
chapters: number[];
|
|
56
|
+
})[]>;
|
|
57
|
+
export declare const loadPreload: (json: GqlBook) => void;
|
|
58
|
+
export {};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
type BookId = number | string;
|
|
2
|
+
export declare const readZipEntry: ({ bookId, entryName, asJson }: {
|
|
3
|
+
bookId: number | string;
|
|
4
|
+
entryName: string;
|
|
5
|
+
asJson?: boolean;
|
|
6
|
+
}) => Promise<any>;
|
|
7
|
+
export declare const hasZip: (bookId: BookId | string) => boolean;
|
|
8
|
+
export declare const loadZip: (buf: Uint8Array, bookId: BookId) => Promise<string[]>;
|
|
9
|
+
export {};
|
package/lib/index.js
CHANGED
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
// src/hooks/useOfflineWorker.ts
|
|
2
|
+
import { useCallback, useEffect, useState } from "react";
|
|
3
|
+
|
|
1
4
|
// src/utils/error.ts
|
|
2
5
|
var tryCatch = (fn) => {
|
|
3
6
|
return (resolve, reject) => {
|
|
@@ -13,7 +16,7 @@ var tryCatch = (fn) => {
|
|
|
13
16
|
var makeSyncWorker = (offlineWorker2, methodNames, dbg) => {
|
|
14
17
|
const dic = {};
|
|
15
18
|
const cbks = {};
|
|
16
|
-
const fn = ({ data: { eventId, methodName, results, error, arg } = {} }
|
|
19
|
+
const fn = ({ source, data: { eventId, methodName, results, error, arg } = {} }) => {
|
|
17
20
|
if (eventId && eventId in dic) {
|
|
18
21
|
if (error) {
|
|
19
22
|
dic[eventId].reject(error);
|
|
@@ -21,11 +24,11 @@ var makeSyncWorker = (offlineWorker2, methodNames, dbg) => {
|
|
|
21
24
|
dic[eventId].resolve(results);
|
|
22
25
|
}
|
|
23
26
|
} else {
|
|
24
|
-
if (methodName && !
|
|
27
|
+
if (methodName && !(methodName in cbks)) {
|
|
25
28
|
console.error(`syncWorker: unknown methodName cbk ${dbg}`, eventId, methodName, error);
|
|
26
29
|
}
|
|
27
30
|
}
|
|
28
|
-
methodName && cbks[methodName]?.(arg);
|
|
31
|
+
methodName && cbks[methodName]?.({ source, ...arg });
|
|
29
32
|
};
|
|
30
33
|
const makeFn = (methodName) => {
|
|
31
34
|
return ({ ports, ...arg } = {}) => {
|
|
@@ -33,7 +36,7 @@ var makeSyncWorker = (offlineWorker2, methodNames, dbg) => {
|
|
|
33
36
|
const eventId = `${methodName}:${Date.now()}-${Math.random().toFixed(5)}`;
|
|
34
37
|
let resolved = false;
|
|
35
38
|
const timeout = setTimeout(() => {
|
|
36
|
-
console.warn("slow request for", methodName, arg);
|
|
39
|
+
console.warn("slow request for", methodName, arg, eventId);
|
|
37
40
|
}, 3e3);
|
|
38
41
|
const doResolve = (arg2) => {
|
|
39
42
|
if (!resolved) {
|
|
@@ -43,11 +46,16 @@ var makeSyncWorker = (offlineWorker2, methodNames, dbg) => {
|
|
|
43
46
|
}
|
|
44
47
|
};
|
|
45
48
|
dic[eventId] = { resolve: doResolve, reject };
|
|
46
|
-
|
|
49
|
+
if (ports) {
|
|
50
|
+
offlineWorker2.postMessage({ eventId, methodName, arg }, ports);
|
|
51
|
+
} else {
|
|
52
|
+
offlineWorker2.postMessage({ eventId, methodName, arg });
|
|
53
|
+
}
|
|
47
54
|
});
|
|
48
55
|
};
|
|
49
56
|
};
|
|
50
|
-
const
|
|
57
|
+
const fns = Object.fromEntries(methodNames.map((name) => [name, makeFn(name)]));
|
|
58
|
+
const obj = Object.assign(fns, {
|
|
51
59
|
on: (key, fn2) => {
|
|
52
60
|
cbks[key] = fn2;
|
|
53
61
|
}
|
|
@@ -64,30 +72,32 @@ var makeSyncWorker = (offlineWorker2, methodNames, dbg) => {
|
|
|
64
72
|
};
|
|
65
73
|
var a = (a2) => a2;
|
|
66
74
|
var makeSyncHandler = a(
|
|
67
|
-
(
|
|
75
|
+
(services) => ({
|
|
68
76
|
canHandle: (methodName) => {
|
|
69
77
|
return methodName in services;
|
|
70
78
|
},
|
|
71
|
-
handle: async ({ data: { eventId, methodName, arg } = {}, ports }) => {
|
|
79
|
+
handle: async ({ data: { eventId, methodName, arg } = {}, source, ports, target }) => {
|
|
80
|
+
const emitter = source?.postMessage && source || target?.postMessage && target || self;
|
|
72
81
|
try {
|
|
73
82
|
if (typeof methodName === "string" && methodName in services && services[methodName]) {
|
|
74
83
|
const results = await services[methodName](arg, { ports });
|
|
75
|
-
|
|
84
|
+
emitter.postMessage({ eventId, methodName, results });
|
|
76
85
|
return;
|
|
77
86
|
}
|
|
78
87
|
throw new Error(`invalid methodName ${Object.keys(services)} |${String(methodName)}`);
|
|
79
88
|
} catch (e) {
|
|
80
89
|
console.debug("failed", e);
|
|
81
|
-
|
|
90
|
+
emitter.postMessage({ eventId, methodName, error: e });
|
|
82
91
|
}
|
|
83
92
|
}
|
|
84
93
|
})
|
|
85
94
|
);
|
|
86
95
|
var combineHandlers = (...handlers) => {
|
|
87
|
-
return (
|
|
96
|
+
return (message) => {
|
|
97
|
+
const methodName = String("methodName" in message.data ? message.data.methodName : "");
|
|
88
98
|
for (const h of handlers) {
|
|
89
|
-
if (h.canHandle(
|
|
90
|
-
return h.handle(
|
|
99
|
+
if (h.canHandle(methodName)) {
|
|
100
|
+
return h.handle(message);
|
|
91
101
|
}
|
|
92
102
|
}
|
|
93
103
|
console.error("no handlers matched", methodName);
|
|
@@ -96,7 +106,6 @@ var combineHandlers = (...handlers) => {
|
|
|
96
106
|
var clearCache = async (mode) => caches.delete(`LLS_OFFLINE_${mode}`);
|
|
97
107
|
|
|
98
108
|
// src/hooks/useOfflineWorker.ts
|
|
99
|
-
import { useCallback, useEffect, useState } from "react";
|
|
100
109
|
var offlineWorker = new Worker("/src/worker/offline-worker.js", { type: "module" });
|
|
101
110
|
var { handler, ...offlineWorkerSync } = makeSyncWorker(
|
|
102
111
|
offlineWorker,
|
|
@@ -124,14 +133,6 @@ var fetchWorkerPromise = new Promise(
|
|
|
124
133
|
return fetchWorker;
|
|
125
134
|
})
|
|
126
135
|
);
|
|
127
|
-
var setWorkersReady;
|
|
128
|
-
var workersReadyPromise = new Promise((resolve) => {
|
|
129
|
-
setWorkersReady = resolve;
|
|
130
|
-
});
|
|
131
|
-
var setBooksLoaded;
|
|
132
|
-
var setBooksLoadedPromise = new Promise((resolve) => {
|
|
133
|
-
setBooksLoaded = resolve;
|
|
134
|
-
});
|
|
135
136
|
var installWorker = async ({
|
|
136
137
|
skipLoadBooks = false,
|
|
137
138
|
primaryOnly = false,
|
|
@@ -146,7 +147,7 @@ var installWorker = async ({
|
|
|
146
147
|
const fetchWorker = await fetchWorkerPromise;
|
|
147
148
|
const configureOptions = { storage, zipBaseUrl, checkUpdates, confEnv };
|
|
148
149
|
if (nativeReadFile) {
|
|
149
|
-
const wwHandler = makeSyncHandler(
|
|
150
|
+
const wwHandler = makeSyncHandler({ nativeReadFile, nativeWriteFile, nativeListZips });
|
|
150
151
|
offlineWorker.onmessage = combineHandlers(handler, wwHandler);
|
|
151
152
|
if (storage !== "native") {
|
|
152
153
|
console.warn("nativeReadFile given, ignoring storage", storage);
|
|
@@ -154,13 +155,17 @@ var installWorker = async ({
|
|
|
154
155
|
offlineWorkerSync.configure({ ...configureOptions, storage: "native" });
|
|
155
156
|
} else {
|
|
156
157
|
offlineWorker.onmessage = handler.handle;
|
|
157
|
-
offlineWorkerSync.configure(configureOptions);
|
|
158
|
+
await offlineWorkerSync.configure(configureOptions);
|
|
158
159
|
}
|
|
159
|
-
offlineWorkerSync.on("ready", setWorkersReady);
|
|
160
160
|
const channel = new MessageChannel();
|
|
161
|
-
offlineWorkerSync.initChannel({ ports: [channel.port1] });
|
|
162
|
-
|
|
163
|
-
|
|
161
|
+
await offlineWorkerSync.initChannel({ ports: [channel.port1] });
|
|
162
|
+
const { handler: fetchWorkerHandler, ...fetchWorkerSync } = makeSyncWorker(fetchWorker, [
|
|
163
|
+
"initChannel",
|
|
164
|
+
"configure"
|
|
165
|
+
]);
|
|
166
|
+
navigator.serviceWorker.onmessage = combineHandlers(fetchWorkerHandler);
|
|
167
|
+
await fetchWorkerSync.initChannel({ ports: [channel.port2] });
|
|
168
|
+
await fetchWorkerSync.configure({ storage, confEnv });
|
|
164
169
|
offlineWorkerSync.on("opfsProgress", () => {
|
|
165
170
|
});
|
|
166
171
|
if (!primaryOnly) {
|
|
@@ -169,7 +174,6 @@ var installWorker = async ({
|
|
|
169
174
|
if (!skipLoadBooks) {
|
|
170
175
|
await offlineWorkerSync.loadBooks({ primaryOnly });
|
|
171
176
|
}
|
|
172
|
-
setBooksLoaded();
|
|
173
177
|
};
|
|
174
178
|
var useOfflineWorker_default = ({
|
|
175
179
|
skipLoadBooks,
|
|
@@ -196,8 +200,9 @@ var useOfflineWorker_default = ({
|
|
|
196
200
|
checkUpdates,
|
|
197
201
|
confEnv
|
|
198
202
|
});
|
|
199
|
-
|
|
200
|
-
|
|
203
|
+
if (process.env.DESKTOP_FLOWER_OFFLINE !== "1") {
|
|
204
|
+
fetch(window.location.href.replace(window.location.search, ""));
|
|
205
|
+
}
|
|
201
206
|
setReady(true);
|
|
202
207
|
};
|
|
203
208
|
fn();
|
package/package.json
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lls/offline",
|
|
3
|
-
"version": "24.
|
|
3
|
+
"version": "24.29.0-038ff270",
|
|
4
4
|
"description": "offline",
|
|
5
5
|
"main": "./lib/index.js",
|
|
6
6
|
"module": "./lib/index.js",
|
|
7
7
|
"types": "./lib/builttypes/offline/src/index.d.ts",
|
|
8
8
|
"exports": {
|
|
9
|
-
"
|
|
9
|
+
"import": "./lib/index.js",
|
|
10
|
+
"types": "./lib/builttypes/offline/src/index.d.ts"
|
|
10
11
|
},
|
|
11
12
|
"files": [
|
|
12
13
|
"lib/",
|
|
@@ -53,7 +54,7 @@
|
|
|
53
54
|
"vite": "7.0.7",
|
|
54
55
|
"vite-tsconfig-paths": "5.1.4",
|
|
55
56
|
"zod": "3.25.50",
|
|
56
|
-
"@lls/vitescripts": "24.
|
|
57
|
+
"@lls/vitescripts": "24.29.0-038ff270"
|
|
57
58
|
},
|
|
58
59
|
"dependencies": {
|
|
59
60
|
"redux-persist": "6.0.0"
|
|
@@ -67,5 +68,8 @@
|
|
|
67
68
|
"test": "bun test --bail __tests__/unit __tests__/e2e",
|
|
68
69
|
"lint": "pnpm biome check --apply src __tests__ stories",
|
|
69
70
|
"precommit": "pnpm lint"
|
|
71
|
+
},
|
|
72
|
+
"imports": {
|
|
73
|
+
"#offline/*": "./lib/builttypes/offline/src/*.d.ts"
|
|
70
74
|
}
|
|
71
75
|
}
|
package/lib/index.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
declare module "@lls/offline"
|