Skip to content

Document

A Doc holds the shapes and bindings by id, plus the ids written since it was derived from its base.

type Doc = {
readonly shapes: ReadonlyMap<ShapeId, Shape>;
readonly bindings: ReadonlyMap<BindingId, Binding>;
readonly touched: {
readonly shapes: ReadonlySet<ShapeId>;
readonly bindings: ReadonlySet<BindingId>;
};
};

The type is branded. Only this module builds a Doc, so every change is recorded in touched. Z-order is each shape’s index, not the map’s order.

Writing

Every helper returns a new Doc and leaves its input unchanged. A helper adds to touched only the ids whose record it actually replaced or removed. When nothing changes, it returns the same Doc object.

Helper Does
putShapes(doc, shapes) Adds each shape, or replaces the shape with the same id
updateShapes(doc, ids, change) Replaces each present shape with change(shape). A data-equal result keeps the old object
removeShapes(doc, ids) Removes the present shapes. Their bindings stay until settle drops them
putBindings(doc, bindings) Adds each binding, or replaces the binding with the same id
removeBindings(doc, ids) Removes the present bindings

EMPTY_DOC has no shapes, no bindings and nothing touched.

Converting

fromShapeDocument(document) builds a Doc from a parsed ShapeDocument, as if every record were written onto EMPTY_DOC, so every id is touched. toShapeDocument(doc) returns the shapes sorted by compareShapes and the bindings in map order, ready to serialize.