Separate Content Maps

Splitting data by type into separate Y.Maps for better organization and performance.

The Pattern

Instead of one nested structure, use separate maps by type:

// Instead of one big data.objects with mixed types...
const shapes = yDoc.getMap('shapes')
const images = yDoc.getMap('images')
const textBoxes = yDoc.getMap('textBoxes')
const paths = yDoc.getMap('paths')

Benefits

  • Targeted observers: Subscribe only to relevant types (shapes.observe() won’t fire for image changes)
  • Faster lookups: images.toJSON() is faster than filtering a mixed collection by type
  • Type safety: Each map can have its own TypeScript interface (Y.Map<ShapeData>, Y.Map<ImageData>)

Shared Ordering

Objects from different maps can share ordering via layer arrays:

const layerOrder = yDoc.getMap('layerOrder')  // Map<layerId, Array<objectId>>

// Object IDs in layers, regardless of type
layerOrder.get('default').push([shapeId])
layerOrder.get('default').push([imageId])

Getting All Objects

When you need all objects regardless of type, spread the values from each map or check each map when looking up by ID. With consistent ID formats (e.g., type-prefixed IDs like shape-xxx, image-xxx), lookups can go directly to the right map.

When to Separate

Separate when:

  • Different types have different properties
  • You query by type frequently
  • Different UI areas handle different types

Keep together when:

  • Objects are always processed together
  • You have very few objects total

See Also