1
0

document-render.md 5.3 KB

Document rendering

English | 中文

The document package family converts Office files to PDFs on the Node Host. Consumers authorize source reads and own presentation; the shared provider owns conversion, bounded admission, and transient PDF reuse. This subsystem creates no model-facing tool or Session event.

Ownership

Owner Responsibility
document-render ctx.documentRender: authorized Office bytes and complete PDF results
document-render-libreoffice Host concurrency, reusable kit converters, private scratch files, and bounded PDF reads
Web bundle One configurable conversion provider shared by Host consumers

Requests and results

DocumentRenderRequest contains an already-authorized source key/version, optional stat size, a deferred read(signal, maxBytes) callback, foreground/background priority, and a DocumentExtension: doc, docx, xls, xlsx, ppt, or pptx. DocumentRenderer.render(request, signal?) returns one complete PDF result. Cancellation follows the caller and provider lifetimes; validation, output, and engine failures reject with a classified DocumentRenderError.

DocumentRenderPriority is foreground for requested preview/QA and background for speculation. DocumentSourceKey brands the caller-owned authorized source locator. DocumentRendererGeneration brands a provider lifetime, and DocumentRenderKey brands its content identity; neither opaque value is parsed by consumers.

Result field Meaning
pdf Caller-owned Uint8Array containing the complete PDF
missingFonts Requested document font families unavailable to this conversion
cacheKey Opaque renderer generation plus extension/source-content identity
generation Provider lifetime; replacement invalidates cached PDF reuse

The provider admits the deferred read before allocating source bytes, shares conversions by content identity, and removes its private scratch directory before returning. Returned PDF bytes remain valid after provider disposal. Source and PDF bytes do not enter Session storage. Consumers can use Workspace Files for authorized bounded reads.

Engine selection and limits

The external @deepseek-ai/libreoffice-kit Node API selects its precompiled engines. The kit has an independent version and release workflow, defined by the release ownership decision. Application builds install the published npm packages. macOS and Windows require their matching ARM64 or x64 native engine; Linux uses Node WASM. The platform engine decision defines installation and packaging. Invalid metadata, missing required assets, and conversion errors reject without switching engines. Conversion uses disk input and output paths on the Host, with no browser conversion engine or font RPC.

The Host provider configuration owns concurrency, deadlines, input/output limits, archive limits, image resolution, and font access. Native/WASM implementation and asset distribution belong to the kit workspace. System LibreOffice discovery, runtime engine downloads, persistent PDF caching, and model-facing rendering are outside this provider.

Cordis API

Generated from source by scripts/gen-cordis-catalog.ts (verified fresh by pnpm run verify-cordis-catalog in doc-sync; regenerate with pnpm run gen-cordis-catalog) — the language sides differ only in locale-specific paired document paths. Signature blocks use a ts cordis-catalog fence and keep the original source JSDoc; dispatch modes are defined in the primer, and the framework-inherited ctx API lives in cordis-api/inherited.md.

ctx.documentRenderDocumentRenderer (abstract seam)

Load one provider subclass per context; consumers own source authorization.

/**
 * Convert Office bytes without modifying the source or writing Session events.
 * @param request - authorized metadata and deferred bounded source read.
 * @param signal - caller cancellation; provider disposal also stops active work.
 * @returns caller-owned PDF bytes after conversion and scratch cleanup settle; canceled readers reject independently.
 * @throws {DocumentRenderError} Invalid input, unusable output, or engine failure; cancellation rejects with its reason.
 */
abstract render(request: DocumentRenderRequest, signal?: AbortSignal): Promise<DocumentRenderResult>

Source: packages/document/document-render/src/index.ts