In progress & stubs
These packages are being built right now. The lists below reflect their current src/index.ts; signatures may still change before the first release.
@nextgensoftwares/folio-plugin-collab in progress
Realtime collaboration: transport, presence, conflict-safe sync, version history, offline flush. Guide: Collaboration plugin.
Protocol and transports
| Export | Description |
|---|---|
PROTOCOL_VERSION | wire protocol version |
PUSH_PART_CHARS | characters of push JSON per push-part frame (1,000,000): the client splits larger pushes |
CollabUser, PeerStatus, PresencePayload, PeerPresence | who a client is and what it publishes (active / idle / away; positions valid at the server version) |
ClientMessage, ServerMessage, ServerEvent, Rejection, VersionInfo | message unions; rejections are mass-delete, diverged, invalid |
parseClientMessage(raw, maxSteps?) | server-side validation of untrusted input (null when malformed) |
isUser, isPresence, initialsOf(user) | guards and display helper |
CollabTransport, TransportStatus, BaseTransport, WebSocketTransport | a reconnectable, WebSocket-shaped message channel (connecting / open / closed) |
Scheduler, realScheduler, VirtualClock, seededRandom(seed) | timers that tests can run on a deterministic virtual clock; a seeded PRNG |
Server side
| Export | Description |
|---|---|
CollabRoom, RoomConnection, RoomHistory, RoomOptions | one document's room: identity from the connection (never the message body), broadcasting, presence, heartbeats, history recording. A WebSocket gateway reuses it |
LocalHub, LocalTransport, PERFECT_LINK, LinkConditions, HubStats, LocalHubOptions | an in-memory hub with simulated latency, jitter, drops, duplicates and disconnects; every message JSON round-tripped |
Client
| Export | Description |
|---|---|
CollabClient, collabClientFor(editor) | realtime collaboration for one editor over a transport: step sync, presence, reconnects with backoff, durable outbox, server events, history RPCs |
CollabClientOptions, CollabState, CollabStatus | options (docId, clientID matching the editor's collabPlugin, user, connectivity, backoff, heartbeatMs, presence, outbox + manifest, confirmed, onFollow…); state connecting / synced / saving / offline / needs-confirmation / diverged |
StopReason | Rejection or gone / ahead / unknown-doc / full: why sync stopped (diverged) or is held (needs-confirmation), also published as PresencePayload.reason |
STOP_TEXT | Record<StopReason, string>: a user-facing sentence per reason |
needsResync(status) | whether a host should recover by reopening from the server: state diverged, but not for full (not a sync problem) or unsupported (the server's schema lacks a plugin; reopening can't fix it) |
sendPush(send, msg, partChars?) | send a push, splitting its JSON into ordered push-part frames when over partChars (default PUSH_PART_CHARS); false as soon as send refuses a frame |
CollabEditor, HeadlessEditor | the editor surface the client needs; a minimal layout-free editor (cheap on huge docs, sharing immutable nodes) |
Connectivity, browserConnectivity(), ManualConnectivity, Backoff, BackoffOptions | online/offline signals; exponential backoff with jitter |
PresenceTracker, RemotePeer, PresenceOptions, CollabSnapshot | collaborators mapped into this editor's document (presence waits for the steps it refers to) |
REMOTE_META | transaction meta marking remote steps |
History
| Export | Description |
|---|---|
HistoryStore | append-only version history recorded by the room (restores are new steps) |
HistoryClient | fetch versions as deltas against what the client holds (O(changes)); every reconstructed version verified against the server's checksum |
compactHistory(store), CompactionReport | fold old steps while reproducing the same checksum at every kept version |
diffDocs(a, b), DocDiff, DiffPart, BlockChange, InlineChange | block diff by identity scan, character diffs inside changed blocks |
restoreTransaction(state, target), RESTORE_META | steps from the current document to an older version (null if they wouldn't reproduce it exactly) |
HistoryStorage, MemoryHistoryStorage, Stored, encode, decode, canCompress | storage abstraction; compact JSON, gzip via CompressionStream when available |
groupBlocks, blockKey, compactNode, sameBlock | content-addressed block groups shared between checkpoints |
diffSequences, applyHunks, Hunk | Myers diff over sequences |
HistoryOptions, Author, DeltaResult, HistoryMeta, Run, Timeline, TimelineEntry | history types (attribution runs, timeline) |
Plugin and React
| Export | Description |
|---|---|
createCollabPlugin(opts?), CollabPluginOptions | toolbar items "Name current version" and "Version history" (shown only when a CollabClient is attached); promptName, showHistory, sidebar (default true: contributes collab.people and collab.history tabs to the sidebar slot; { onPreview } to receive version previews; false for none) |
PeopleSlot, HistorySlot | the sidebar slot components: collaborators with follow buttons; version history (onPreview?). They show a hint when no CollabClient is attached |
CollaboratorsBar, CollaboratorsBarProps | avatars with status, click to follow a collaborator, save state |
VersionHistoryPanel, VersionHistoryPanelProps, VersionPreview | timeline, diff, preview, name and restore versions |
DiffView | changed blocks with inserted/deleted text marked |
useCollabSnapshot(client) | status, collaborators and follow state |
remoteLabel(peer), STATE_LABEL, STATE_COLOR | display helpers |
CollabRole | 'editor' | 'reader': a client's role in a room (the server decides it via roleOf; readers receive steps but can't push) |
Blame (author attribution)
| Export | Description |
|---|---|
blamePlugin(opts?), BlamePluginOptions | opt-in "Show authors": tints text by last author (hover card: name, time, version), margin initials per block (click opens that version). Options: enabled, visibleTo ('editors' default | 'everyone'), defaultVisible, color(author), onOpenVersion(version, editor) |
blameFor(editor) → BlameSession | undefined | the editor's blame session: load(), loaded, visible, spans for drawing |
BlameSession | follows the live step stream from a CollabClient, crediting unsaved local edits to the local user |
Attribution | author spans mapped through steps (apply(step, author, version, time)), the data structure behind blame |
BlameAuthor, BlameSpan, CompactBlame | { id, name, color }; { from, to, a (author index), v (version), t (time) }; the delta-coded form stored with history checkpoints |
rebuildBlame(store, version?) | rebuild attribution from a HistoryStore (server side, after restarts or for audits) |
@nextgensoftwares/folio-export-docx in progress
DOCX export from Folio documents. Guide: Exporters.
| Export | Description |
|---|---|
exportDocx(doc, opts?) => Promise<Uint8Array> | Word styles from the theme, numbering, tables, images, OMML equations, header/footer page fields, Word keep/page-break rules |
DocxExportOptions | theme, fetchImage, resolveSrc (sync or async), rasterizeSvg, headerFooter, variables, firstPageNumber, exporters, toc, math ('omml' / 'image' / 'text'; default 'image' with mathImage, else 'omml'), title, author, description, imageConcurrency, onWarning, onProgress(phase, done, total), plus DocxFidelityOptions |
DocxFidelityOptions | fonts(font) (bytes per face: embedded, variable fonts as static instances per weight, extra weights as their own family, e.g. "Geist SemiBold"), embedFonts (default true), fontInstancerWasm, layout (the document's layout, same theme and header/footer) and pagination ('fixed', the default with layout: Folio's page breaks, line heights, gaps, indents and splits; or 'flow'), mathImage(latex, display, size) |
DocxMathImage | { png, width, height, depth }: an equation picture (e.g. mathImageFromHtml from @nextgensoftwares/folio-export-pdf) |
NodeExporter, DocxContext, DocxImage | plugin mapping (attrs, ctx) => docx children | PrintFallback | null, keyed by node type or media:<type>; ctx.node is the node |
PrintFallback | { image?, title, detail, link? }, rendered as a card |
splitExporters(map, base?, resolveSrc?) | { exporters, resolveSrc? }: separates exporters from plugin-media's resolveSrc entry |
docxExportPlugin(opts?), DocxExportPluginOptions | "Export ▸ Word (.docx)" toolbar entry; theme, headerFooter, exporters, pageLayers and variables may be getters; faces (font URLs) for embedding; exports editor.layout with fixed pagination unless pagination: 'flow' |
DocxPageLayer | DocxExportOptions.pageLayers: page layers evaluated with target 'docx' on a first, an even and an odd page |
DocxWatermark | what a layer exporter (exporters[fragment.type], called with the fragment's attrs and ctx.fragment) returns to get Word's native watermark: { watermark: 'text', text, font?, size?, bold?, italic?, color?, opacity?, rotation?, width?, height? } or { watermark: 'image', src, width, height, washout? } |
layerHeaders(opts, state), LayerHeaders, LayerRuns | the watermark runs per Word header kind (default, first, even) |
applyLayerHeaders(section, layers) | adds them to a section's headers; turns on first-page / even-page headers only when the watermark differs there, copying the default header and footer |
fetchImageInBrowser, rasterizeSvgInBrowser | browser defaults |
buildStyles(theme) | the Word styles derived from a theme |
docForPages(doc, layout, pages), DocxPageSelection | the blocks on the selected pages (whole blocks; disjoint ranges start a new page). DOCX reflows in Word, so ranges can't be exact or enforced |
parseLatex, latexToText, mathChild(latex, mode?) | LaTeX → OMML (or plain text) |
ExportPlugin, ExportUIItem, ExportEditorLike | shared export-menu types (same as in @nextgensoftwares/folio-export-pdf) |
DocxComments, DocxCommentThread, DocxCommentEntry | DocxExportOptions.comments (off unless given): threads { id, author, initials?, text, date?, replies?, resolved? } keyed by the anchor id of the comment mark / commentIds attr. docxExportPlugin({ comments }) takes the object or a getter (editor) => DocxComments | undefined (see the comments plugin) |
CommentTracker, commentDefinitions(comments) | places commentRangeStart/End + commentReference while the body converts (by characters, so split paragraphs close once; top-level blocks with commentIds are wrapped); the Document({ comments }) definitions with replies threaded (parentId) and resolved threads marked done |
Stubs
| Package | Status |
|---|---|
@nextgensoftwares/folio-pdf | renderPdf(layout) throws "not implemented". Superseded by @nextgensoftwares/folio-export-pdf |