IFClite TypeScript API
    Preparing search index...

    Function upsertGeometry

    • Write a carrier's fields onto a geometry record, creating it if absent.

      createGeometry returns an existing record untouched, which is what seeding a fresh doc wants: a file listing the same geomId twice must not have the second mention rewrite the first. An overlay is the opposite case — it exists precisely to carry edits to records the parent already has — so routing it through createGeometry drops every in-place geometry change silently, with the merge still reporting success.

      Carriers are PARTIAL: geometryRecordLookup in snapshot/structured-attrs.ts omits blobHash and bbox when absent and params entirely when empty. That is why the optional fields are guarded here — an absent field is "no opinion", not "clear it".

      params therefore MERGE rather than replace, for a reason that was measured: merging emits one Yjs change per key at [geomId, 'params'], which conflicts/detector.ts classifies as a geometry-param conflict, while node.set(PARAMS, new Y.Map()) emits a single change at [geomId] that classify returns null for — so replacing would make a concurrent param edit stop being a detectable conflict.

      Two costs, both real. A param the branch DELETED cannot be represented, the same limit the overlay has for structured removals generally. And because type/source are required and so always written while the optional fields are not, a stale carrier can leave a record mixing one representation's type with another's blobHash.

      The version vector is deliberately left alone: it records who replaced this geometry, and applying someone's overlay is not this peer replacing it. bumpGeometryVersion is the explicit way to say that.

      Parameters

      Returns YMap<unknown>