Skip to content
Source
Sign inSign up

officePreview.worker.ts

52 lines1.9 KB

1import { boundedArchive, prepareOffice } from "./officeArchive";
2import { PREVIEW_PAGE_ROWS } from "./largeTextProtocol";
3import type { OfficeWorkerRequest, OfficeWorkerResult } from "./officePreviewProtocol";
4​
5let workbook: string[][][] = [];
6function reply(result: OfficeWorkerResult) {
7 self.postMessage(result, { transfer: "bytes" in result ? [result.bytes] : [] });
8}
9async function handle(input: OfficeWorkerRequest) {
10 if (input.type === "sheet-page") {
11 const rows = workbook[input.sheet];
12 if (!rows) throw new Error("This sheet is unavailable.");
13 reply({
14 type: "sheet-page",
15 sheet: input.sheet,
16 index: input.index,
17 rows: rows.slice(input.index * PREVIEW_PAGE_ROWS, (input.index + 1) * PREVIEW_PAGE_ROWS),
18 });
19 return;
20 }
21 if (input.kind === "docx" || input.kind === "xlsx" || input.kind === "pptx") {
22 reply({ type: input.kind, ...(await prepareOffice(input.bytes, input.kind)) });
23 return;
24 }
25 const { openDocument, openEpub, openNotebook, openRtf } =
26 await import("./extendedDocumentPreview");
27 if (input.kind === "ipynb" || input.kind === "rtf") {
28 reply(input.kind === "ipynb" ? openNotebook(input.bytes) : openRtf(input.bytes));
29 return;
30 }
31 const { archive } = await boundedArchive(input);
32 const result =
33 input.kind === "epub" ? await openEpub(archive) : await openDocument(archive, input.kind);
34 if (result.type === "ods") {
35 workbook = result.sheets.map((sheet) => sheet.rows);
36 reply({
37 ...result,
38 sheets: result.sheets.map((sheet) => ({
39 ...sheet,
40 rows: sheet.rows.slice(0, PREVIEW_PAGE_ROWS),
41 })),
42 });
43 } else reply(result);
45self.addEventListener("message", (event: MessageEvent<OfficeWorkerRequest>) => {
46 void handle(event.data).catch((cause: unknown) =>
47 reply({
48 type: "error",
49 message: cause instanceof Error ? cause.message : "Could not parse this file.",
50 }),
51 );
52});