document structure
The top-level CRDT document structure, initialization defaults, ID system, and metadata.
Top-Level Shared Types
A Prezillo document is a Y.Doc with 12 named shared types:
| Map Key | Yjs Type | Description |
|---|---|---|
o |
Y.Map<StoredObject> |
All drawable objects keyed by ObjectId |
c |
Y.Map<StoredContainer> |
Layers and groups keyed by ContainerId |
r |
Y.Array<ChildRef> |
Root-level children (ordered) |
ch |
Y.Map<Y.Array<ChildRef>> |
Children arrays keyed by ContainerId |
v |
Y.Map<StoredView> |
Views (slides/pages) keyed by ViewId |
vo |
Y.Array<string> |
View order (presentation sequence of ViewId strings) |
m |
Y.Map |
Document metadata |
rt |
Y.Map<Y.Text> |
Rich text content keyed by ObjectId (Quill Delta) |
st |
Y.Map<StoredStyle> |
Global style definitions keyed by StyleId |
pl |
Y.Map<StoredPalette> |
Palette (single entry keyed by 'default') |
tpl |
Y.Map<StoredTemplate> |
Templates keyed by TemplateId |
tpo |
Y.Map<Y.Array<string>> |
Template prototype objects: TemplateId → ObjectId[] |
Why compact map keys?
Map keys like o, c, r are used instead of objects, containers, rootChildren because these keys appear in every Yjs sync message. Shorter keys reduce wire overhead during real-time collaboration without affecting readability — this documentation provides the complete mapping.
Accessing the Document
import * as Y from 'yjs'
const yDoc = new Y.Doc()
// Access each shared type by its map key
const objects = yDoc.getMap('o') // StoredObject entries
const containers = yDoc.getMap('c') // StoredContainer entries
const root = yDoc.getArray('r') // Root ChildRef array
const children = yDoc.getMap('ch') // Per-container children
const views = yDoc.getMap('v') // StoredView entries
const viewOrder = yDoc.getArray('vo') // ViewId ordering
const meta = yDoc.getMap('m') // Metadata
const richTexts = yDoc.getMap('rt') // Y.Text entries
const styles = yDoc.getMap('st') // StoredStyle entries
const palette = yDoc.getMap('pl') // StoredPalette
const templates = yDoc.getMap('tpl') // StoredTemplate entries
const tplProtos = yDoc.getMap('tpo') // Template prototype arrays
ID System
All entity IDs use 72-bit entropy encoded as 12 base64url characters, generated client-side via crypto.getRandomValues().
Six branded types prevent accidental ID mixing at compile time:
| Branded Type | Used In | Example |
|---|---|---|
ObjectId |
o map keys, ChildRef[1] when [0] is 0 |
"aB3x_Qm7kL9p" |
ContainerId |
c map keys, ch map keys, ChildRef[1] when [0] is 1 |
"Xk2nR8vH_wYq" |
ViewId |
v map keys, vo array entries, object vi field |
"m4Jf_L1pZq8w" |
StyleId |
st map keys, object si/ti fields, style p field |
"Nz9cK_vW3xRb" |
RichTextId |
rt map keys (same value as ObjectId for text objects) |
"aB3x_Qm7kL9p" |
TemplateId |
tpl map keys, tpo map keys, view tpl field |
"Hw5_qT2mLkJx" |
ChildRef Convention
The ChildRef tuple encodes a reference that can point to either an object or a container:
type ChildRef = [0 | 1, string]
// ^ ^
// | └── ObjectId or ContainerId
// └── 0 = object, 1 = container
Examples:
[0, "aB3x_Qm7kL9p"]— references an object[1, "Xk2nR8vH_wYq"]— references a container (layer or group)
ChildRef arrays are used in the root children (r) and per-container children (ch) to maintain draw order.
Metadata
The m map stores document-level settings as individual key-value entries:
| Key | Type | Default | Description |
|---|---|---|---|
name |
string |
"Untitled Presentation" |
Document name |
defaultViewWidth |
number |
1920 |
Default width for new views |
defaultViewHeight |
number |
1080 |
Default height for new views |
gridSize |
number |
— | Grid spacing in pixels (if grid enabled) |
snapToGrid |
boolean |
— | Whether objects snap to grid |
snapToObjects |
boolean |
— | Whether objects snap to other objects |
Document Initialization
When a new empty document is created, the following defaults are established in a single Yjs transaction:
- Default layer: A container of type
'L'named"Layer 1"with expanded state (x: true), added to root children as[1, layerId] - Default view: A view named
"Page 1"at position(0, 0)with dimensions1920×1080, white background, border visible - Metadata:
defaultViewWidth: 1920,defaultViewHeight: 1080,name: "Untitled Presentation" - Default palette: The built-in palette with background, text, 6 accent colors, and 4 gradients (see Styling and Palette)
- Default styles: 10 built-in styles — 6 shape styles (Default Shape, Primary, Secondary, Accent, Outline, Connector) and 4 text styles (Default Text, Heading, Body, Caption) with parent-child inheritance chains
Rich Text Storage
Text objects (type 'T') store their formatted content as Y.Text entries in the rt map, keyed by the same ObjectId used in the o map. The Y.Text uses Quill Delta format for rich text operations (bold, italic, links, etc.).
A legacy tx field on the stored object held plain text in older documents. On load, migration code automatically converts tx strings to Y.Text entries in rt and removes the tx field.
Separate map for rich text
Rich text content is stored in the rt map, not embedded in the object data in o. This is because Y.Text is a Yjs shared type that needs its own identity for collaborative editing — it cannot be stored as a plain JSON value inside a Y.Map entry.