@aimform/files
v0.1.0
Published
Aimform file uploads, document processing, indexing, and progress.
Downloads
239
Readme
@aimform/files
Aimform-owned file lifecycle and document-processing package.
This package owns resumable uploads, large-file processing, adaptive chunking, source offsets, translation alignment, vectorization jobs, artifacts, and real-time progress. FileUploadStore is the persistence seam: production hosts implement it with @aimform/spaces records plus their storage adapter, while InMemoryFileUploadStore is a deterministic local/test implementation. The package must not maintain a parallel file metadata store.
The store contract covers capability negotiation, idempotent session creation, part replay/conflict detection, completion/abort, processing jobs, and progress replay after reconnect. Progress events are versioned and monotonically sequenced per file.
The processing core analyzes normalized Markdown before vectorization and selects a structure-aware strategy by source type: page/document structure for PDF/DOCX/Markdown, rows for sheets, slide boundaries, code boundaries, dialogue turns, or paragraphs. Chunks retain exact character offsets and deterministic IDs. prepareDocument owns the extraction/translation orchestration seam, while providers remain injectable so PDF/DOCX conversion is not coupled to a vendor.
The browser uploadFile helper sends one multipart part at a time and reports server-acknowledged byte progress. Persistent stores emit durable upload and processing progress events on the host's realtime channel. The legacy progress endpoint returns a single replay snapshot only; it does not hold a request open or poll D1. vectorizeChunks/vectorizeSource batch embeddings and index messages, Pages, Collections, documents, web snapshots, and knowledge records without buffering the entire source.
Completed files have a stable fileId. PersistentFileUploadStore.replaceFileContent() overwrites the existing storage object in place with an optional ETag precondition, while creating a new processing versionId. moveFile() changes the owning Space and normalized relative directory without changing the file ID or object key. Use normalizeDirectory() at adapter boundaries to reject absolute paths and traversal segments.
FileLifecycleAdapter.createFile() materializes the shared file metadata row as
part of successful multipart completion. Implementations should make this
operation idempotent because completion can be retried after the object store
has already finalized the upload. Progress event persistence must likewise
replay an existing (fileId, eventId) instead of inserting a duplicate.
Hosts that need to resolve a session or file before checking its tenant may use getSessionScopeUnscoped() or getFileScopeUnscoped(), then must authorize the returned scope before any other lifecycle operation.
The Files package owns the multipart lifecycle contract and Cloudflare R2
provider. R2MultipartStorageAdapter is constructed by a service composition
root with an injected R2 bucket; it preserves resumable upload, completion,
abort, ETag replacement, and crash-recovery checks.
Conformance
conformance/manifest.json and conformance/core.json define the owner-local
upload contract. src/conformance.test.ts verifies idempotent session replay,
part ordering, completion progress, capability negotiation, and traversal
rejection without a Cloudflare binding.
R2 providers take { guard } as their final options argument. Production
composition must provide it so simple and multipart object operations are
bounded before the R2 binding runs.
