@lls/offline 24.31.0 → 24.32.0-32e34fe7
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 +5 -0
- package/lib/assets/offline-worker.js +1 -0
- 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 +8 -3
- package/package.json +2 -2
|
@@ -539,6 +539,11 @@ var initChannel = async (__, { ports }) => {
|
|
|
539
539
|
offlineWorker.onmessage = combineHandlers(syncHandler, onHandler);
|
|
540
540
|
offlineWorker.onclose = () => {
|
|
541
541
|
console.error("socket to ow has been closed!");
|
|
542
|
+
swSelf.clients.matchAll({ includeUncontrolled: true }).then((clientList) => {
|
|
543
|
+
for (const client of clientList) {
|
|
544
|
+
client.postMessage({ methodName: "reloadChannels" });
|
|
545
|
+
}
|
|
546
|
+
});
|
|
542
547
|
};
|
|
543
548
|
await offlineWorkerSync.ensureAppReady();
|
|
544
549
|
};
|
|
@@ -514,6 +514,7 @@ var initChannel = (__, { ports }) => {
|
|
|
514
514
|
fetchWorker.onmessage = combineHandlers(syncHandler, onHandler);
|
|
515
515
|
fetchWorker.onclose = () => {
|
|
516
516
|
console.error("socket to sw has been closed!");
|
|
517
|
+
self.postMessage({ methodName: "reloadChannels" });
|
|
517
518
|
};
|
|
518
519
|
};
|
|
519
520
|
var loadBooks = async ({ primaryOnly = false } = {}) => {
|
|
@@ -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
|
@@ -146,15 +146,19 @@ var installWorker = async ({
|
|
|
146
146
|
} = {}) => {
|
|
147
147
|
const fetchWorker = await fetchWorkerPromise;
|
|
148
148
|
const configureOptions = { storage, zipBaseUrl, checkUpdates, confEnv };
|
|
149
|
+
const reloadChannels = async () => {
|
|
150
|
+
location.reload();
|
|
151
|
+
};
|
|
149
152
|
if (nativeReadFile) {
|
|
150
|
-
const wwHandler = makeSyncHandler({ nativeReadFile, nativeWriteFile, nativeListZips });
|
|
153
|
+
const wwHandler = makeSyncHandler({ reloadChannels, nativeReadFile, nativeWriteFile, nativeListZips });
|
|
151
154
|
offlineWorker.onmessage = combineHandlers(handler, wwHandler);
|
|
152
155
|
if (storage !== "native") {
|
|
153
156
|
console.warn("nativeReadFile given, ignoring storage", storage);
|
|
154
157
|
}
|
|
155
158
|
offlineWorkerSync.configure({ ...configureOptions, storage: "native" });
|
|
156
159
|
} else {
|
|
157
|
-
|
|
160
|
+
const wwHandler = makeSyncHandler({ reloadChannels });
|
|
161
|
+
offlineWorker.onmessage = combineHandlers(handler, wwHandler);
|
|
158
162
|
await offlineWorkerSync.configure(configureOptions);
|
|
159
163
|
}
|
|
160
164
|
const channel = new MessageChannel();
|
|
@@ -163,7 +167,8 @@ var installWorker = async ({
|
|
|
163
167
|
"initChannel",
|
|
164
168
|
"configure"
|
|
165
169
|
]);
|
|
166
|
-
|
|
170
|
+
const swHandler = makeSyncHandler({ reloadChannels });
|
|
171
|
+
navigator.serviceWorker.onmessage = combineHandlers(fetchWorkerHandler, swHandler);
|
|
167
172
|
await fetchWorkerSync.initChannel({ ports: [channel.port2] });
|
|
168
173
|
await fetchWorkerSync.configure({ storage, confEnv });
|
|
169
174
|
offlineWorkerSync.on("opfsProgress", () => {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lls/offline",
|
|
3
|
-
"version": "24.
|
|
3
|
+
"version": "24.32.0-32e34fe7",
|
|
4
4
|
"description": "offline",
|
|
5
5
|
"main": "./lib/index.js",
|
|
6
6
|
"module": "./lib/index.js",
|
|
@@ -54,7 +54,7 @@
|
|
|
54
54
|
"vite": "7.1.11",
|
|
55
55
|
"vite-tsconfig-paths": "5.1.4",
|
|
56
56
|
"zod": "3.25.50",
|
|
57
|
-
"@lls/vitescripts": "24.
|
|
57
|
+
"@lls/vitescripts": "24.32.0-32e34fe7"
|
|
58
58
|
},
|
|
59
59
|
"dependencies": {
|
|
60
60
|
"redux-persist": "6.0.0"
|