feat: add local OneNote and ONEPKG reader

This commit is contained in:
2026-07-22 17:06:03 +02:00
commit f581cbdced
93 changed files with 14949 additions and 0 deletions

View 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);
};