Collaboration architecture¶
IFC-Lite collaboration is built around @ifc-lite/collab, with the sync and
persistence service provided by @ifc-lite/collab-server. The browser viewer,
CLI, MCP server, and third-party clients consume these shared packages rather
than implementing independent collaboration protocols.
Model¶
An editing session stores IFCX operations in a Yjs document. Operations are identified independently of transient STEP express IDs, and snapshots are materialized through the same IFCX composition and mutation paths used by headless consumers. Tombstones represent deletions; immutable published layers carry canonical content identifiers and provenance manifests.
Geometry blobs are content-addressed and remain separate from the CRDT document. The document contains references and parametric state, which keeps ordinary updates small and makes missing or corrupt blobs detectable.
A room carries one or more model slots (models map, slotId → record).
Slot ids are minted in share order (m0, m1, …), never derived from a file
name, its bytes or its GlobalIds, and every entity path is qualified by its
slot: /<slotId>/<GlobalId> for STEP-seeded entities, /<slotId> prepended to
the file's own path for IFCX seeds, whose header, imports and schemas are
recorded per slot as well. Two copies of one file are therefore two disjoint
entity sets, each with its own geometry references (STEP mesh blobs encode the
federation-global express id, so the copies do not share blobs). Rooms shared
before slots existed have an empty models map and unqualified paths; readers
treat them as a single implicit slot with an empty prefix, so nothing on disk
is rewritten. A recipient reconstructs one federated viewer model per slot,
registered in its own global-id range like any added file, and suffixes a
model name that another slot also carries (AC20-FZK-Haus.ifc (2)). The
reconstructed store keys entities by their room path (the IFCX ingest uses the
node path as GlobalId); an IFCX export of a room model removes the slot prefix
again (Ifc5ExportOptions.stripPathPrefix, chosen by roomExportPathPrefix
for the recipient's room:<roomId>:<slotId> models only), so the file carries
/<GlobalId> like a single-model room's export. The owner's seed writes each
slot in four transactions (slot record, structure, mesh resolve with every
placement-baseline stamp, geometry records + refs) plus one seed marker: the
relay's per-connection write budget is a token bucket, and an unbatched burst of
per-entity frames is dropped there — after which Yjs holds every later frame
from that client pending — so the frame count is pinned by test.
STEP models with authored IfcAnnotation representations also carry one
content-addressed, mutation-materialized STEP source in their slot record. The
room snapshot remains authoritative for live roots and edits; recipients attach
the STEP source for representation-level symbolic extraction and remap its
owners through slot-qualified GlobalIds. This preserves native 2D fills while
the same annotation's mesh blobs remain selectable 3D parts. The source upload
and recipient fetch are both capped at 96 MiB, and only canonical 32-character lowercase blob
references are accepted. When that source still covers every live room root,
Export emits ordinary STEP and remaps room edits and visibility IDs back to
source express IDs. A root created later in the room makes IFCX the complete
export again, so it is never omitted to preserve the older STEP representation.
Synchronization¶
Clients exchange Yjs updates through @ifc-lite/collab-server. The server owns
room admission, authorization, persistence, audit records, retention, and blob
transport. It does not introduce a second IFC decoding or geometry pipeline.
The client provider handles reconnects and awareness state. Awareness—cursor, selection, identity, and presence—is ephemeral and is not part of a model snapshot.
Conflict and history model¶
CRDT convergence guarantees that peers reach the same operation state; it does not make concurrent BIM edits semantically compatible. Domain conflicts are detected separately and presented through the shared merge and review models. Published layers and refs provide durable history, while local undo remains a session concern.
Security boundary¶
Deployments choose anonymous or token-authenticated access. Authorization is checked by the server for room, role, and protected registry operations. Audit events and content hashes provide evidence for changes, but callers must still apply transport security, retention, and deployment controls appropriate to their data.