feat: add local OneNote and ONEPKG reader
This commit is contained in:
122
src/worker/onenote.worker.ts
Normal file
122
src/worker/onenote.worker.ts
Normal file
@@ -0,0 +1,122 @@
|
||||
import type { OneNotePageDto } from '../onenote/model/dto.js';
|
||||
import {
|
||||
failureFromUnknown,
|
||||
openPackageForWorker,
|
||||
openSectionForWorker,
|
||||
workerPageKey,
|
||||
} from './parser-adapter.js';
|
||||
import type { WorkerRequest, WorkerResponse } from './worker-protocol.js';
|
||||
|
||||
interface ModuleWorkerScope {
|
||||
onmessage: ((event: MessageEvent<WorkerRequest>) => void) | null;
|
||||
postMessage(response: WorkerResponse): void;
|
||||
}
|
||||
|
||||
interface ParserSession {
|
||||
pages: Map<string, OneNotePageDto>;
|
||||
}
|
||||
|
||||
const workerScope = globalThis as unknown as ModuleWorkerScope;
|
||||
const sessions = new Map<string, ParserSession>();
|
||||
let sessionSequence = 0;
|
||||
|
||||
function createSession(pages: Map<string, OneNotePageDto>): string {
|
||||
const id = `session-${++sessionSequence}`;
|
||||
sessions.set(id, { pages });
|
||||
return id;
|
||||
}
|
||||
|
||||
async function handleRequest(data: WorkerRequest): Promise<void> {
|
||||
switch (data.type) {
|
||||
case 'parse-one': {
|
||||
try {
|
||||
const parsed = openSectionForWorker(
|
||||
new Uint8Array(data.bytes),
|
||||
data.fileName
|
||||
);
|
||||
const sessionId = createSession(parsed.pages);
|
||||
workerScope.postMessage({
|
||||
type: 'section',
|
||||
requestId: data.requestId,
|
||||
sessionId,
|
||||
section: parsed.section,
|
||||
});
|
||||
} catch (error) {
|
||||
workerScope.postMessage({
|
||||
type: 'failure',
|
||||
requestId: data.requestId,
|
||||
error: failureFromUnknown(error),
|
||||
});
|
||||
}
|
||||
return;
|
||||
}
|
||||
case 'parse-onepkg':
|
||||
try {
|
||||
const parsed = await openPackageForWorker(
|
||||
new Uint8Array(data.bytes),
|
||||
data.fileName
|
||||
);
|
||||
const sessionId = createSession(parsed.pages);
|
||||
workerScope.postMessage({
|
||||
type: 'package',
|
||||
requestId: data.requestId,
|
||||
sessionId,
|
||||
notebook: parsed.notebook,
|
||||
});
|
||||
} catch (error) {
|
||||
workerScope.postMessage({
|
||||
type: 'failure',
|
||||
requestId: data.requestId,
|
||||
error: failureFromUnknown(error),
|
||||
});
|
||||
}
|
||||
return;
|
||||
case 'get-page': {
|
||||
const session = sessions.get(data.sessionId);
|
||||
if (!session) {
|
||||
workerScope.postMessage({
|
||||
type: 'failure',
|
||||
requestId: data.requestId,
|
||||
error: {
|
||||
code: 'session-not-available',
|
||||
message: 'The parser session is no longer available.',
|
||||
recoverable: false,
|
||||
},
|
||||
});
|
||||
return;
|
||||
}
|
||||
const page = session.pages.get(
|
||||
workerPageKey(data.pageId, data.sectionId)
|
||||
);
|
||||
if (!page) {
|
||||
workerScope.postMessage({
|
||||
type: 'failure',
|
||||
requestId: data.requestId,
|
||||
error: {
|
||||
code: 'page-not-available',
|
||||
message: 'The selected page is not available in this source.',
|
||||
recoverable: true,
|
||||
},
|
||||
});
|
||||
return;
|
||||
}
|
||||
workerScope.postMessage({
|
||||
type: 'page',
|
||||
requestId: data.requestId,
|
||||
sessionId: data.sessionId,
|
||||
page,
|
||||
});
|
||||
return;
|
||||
}
|
||||
case 'dispose':
|
||||
sessions.delete(data.sessionId);
|
||||
workerScope.postMessage({
|
||||
type: 'disposed',
|
||||
sessionId: data.sessionId,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
workerScope.onmessage = ({ data }) => {
|
||||
void handleRequest(data);
|
||||
};
|
||||
Reference in New Issue
Block a user