Document Formats
Detailed specifications of the document formats used by each Cloudillo application.
Overview
Each Cloudillo app stores collaborative documents using application-specific data models. Most apps use Yjs CRDTs for conflict-free concurrent editing, while some use the Real-Time Database (RTDB) for query-oriented structured data. This section provides the complete format specification for each app’s document structure, enabling third-party developers, tool builders, and contributors to understand, extend, and interoperate with Cloudillo documents.
Relationship to CRDT Design Guide
The CRDT Design Guide teaches generic patterns for building collaborative apps (ID-based storage, style inheritance, separate content maps). This section documents the concrete format specifications — the exact field names, types, and structures used by each app.
Application Formats
| Application | Content Type | Storage | Complexity | Status |
|---|---|---|---|---|
| Prezillo | application/vnd.cloudillo.prezillo+json |
CRDT (Yjs) | High (14 object types, palette, templates) | Documented |
| Calcillo | application/vnd.cloudillo.calcillo+json |
CRDT (Yjs) | Medium (cells, formulas, sheets) | Documented |
| Ideallo | application/vnd.cloudillo.ideallo+json |
CRDT (Yjs) | Medium (9 object types, linked copies) | Documented |
| Notillo | application/vnd.cloudillo.notillo+json |
RTDB | Low (rich text document) | Planned |
| Quillo | application/vnd.cloudillo.quillo+json |
CRDT (Yjs) | Low (rich text editor) | Planned |
Common Conventions
Compact Field Names
CRDT-based apps use short field names (typically 1-3 characters) to minimize wire overhead during real-time synchronization. For example, t for type, xy for position, wh for dimensions. Each app’s format spec documents the mapping from compact names to their meanings.
ID Format
All entity IDs (objects, containers, views, styles, templates) use 72-bit entropy encoded as 12 base64url characters. IDs are generated client-side using crypto.getRandomValues() and are typed using branded types (ObjectId, ContainerId, ViewId, StyleId, RichTextId, TemplateId) for compile-time safety.
ChildRef Tuples
Several apps use a ChildRef tuple to reference children that can be either objects or containers:
type ChildRef = [0 | 1, string] // [0, objectId] or [1, containerId]
The discriminant (0 or 1) allows a single ordered array to contain references to both types without ambiguity.
v3 Generic Export Format
Starting with format version 3.0.0, all CRDT-based apps use a unified export function (exportYDoc()) from @cloudillo/crdt. This function walks yDoc.share and serializes all shared types with inline @T type markers that preserve the original Yjs type information.
Export Envelope
Every exported document shares this envelope structure:
{
"contentType": "application/vnd.cloudillo.<app>+json",
"appVersion": "<semver>",
"formatVersion": "3.0.0",
"exportedAt": "<ISO 8601 timestamp>",
"data": { ... }
}The data object contains one entry per top-level Yjs shared type, using the raw CRDT key names (e.g., o, r, m instead of objects, rootChildren, meta).
@T Type Markers
Each Yjs type is serialized with an inline marker so importers can reconstruct the correct Yjs type:
| Yjs Type | Marker | Serialized Form |
|---|---|---|
Y.Map |
"@T": "M" |
{ "@T": "M", "key1": ..., "key2": ... } |
Y.Array |
"@T:A" |
[ "@T:A", element1, element2, ... ] |
Y.Text |
"@T": "T" |
{ "@T": "T", "text": "...", "delta": [...] } |
Y.XmlText |
"@T": "XT" |
{ "@T": "XT", "text": "...", "delta": [...] } |
Y.XmlElement |
"@T": "XE" |
{ "@T": "XE", "n": "...", "a": {...}, "c": [...] } |
Y.XmlFragment |
"@T": "XF" |
{ "@T": "XF", "c": [...] } |
Nested types are serialized recursively. For example, a Y.Map<Y.Text> becomes a map with "@T": "M" containing entries that each have "@T": "T" with text and delta fields.
Primitive values pass through
Plain values (strings, numbers, booleans, null) inside Yjs types are serialized as-is without markers. The @T marker only appears on Yjs shared types.
Changes from Previous Versions
| Aspect | Pre-v3 | v3 |
|---|---|---|
| Data keys | Long descriptive names (objects, rootChildren, richTexts) |
Raw CRDT keys (o, r, rt) |
| Type information | Implicit (consumer must know the schema) | Explicit @T markers on every Yjs type |
| Text content | Plain text string or { plainText, delta } |
{ "@T": "T", "text": "...", "delta": [...] } |
| Export function | App-specific custom serialization | Generic exportYDoc() from @cloudillo/crdt |
| Format version | App-specific (1.0.0 or 2.0.0) |
Unified 3.0.0 across all apps |
See Also
- CRDT Design Guide — Generic collaboration patterns and best practices
- CRDT API Reference — CRDT integration with Cloudillo
- CRDT Architecture — CRDT storage implementation
- RTDB Architecture — Real-Time Database storage implementation