Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Use lenses

Every migration is a lens. The lens API gives you direct access to the bidirectional transform: get lifts data forward, put projects new data back to the old shape, complement records what get discarded so put can restore it.

Prerequisites

A migration (Build a migration) or a hand-written lens via the lens DSL.

The task

A CompiledMigration is itself a lens; reach for LensHandle only when you want a free-standing protolens chain.

const { view, complement } = mig.get(oldRecord);

const editedView = { ...view, age: view.age + 1 };
const { data: updatedOld } = mig.put(editedView, complement);

mig.get returns the forward view together with the complement (the data discarded by get); mig.put consumes them and returns a LiftResult { data, ... } reconstructed with the edit applied. The round-trip laws guarantee this is well-defined.

To compose two compiled migrations sequentially:

const composed = p.compose(mig_ab, mig_bc);

To compose two free-standing protolens chains:

const composedChain = p.composeLenses(chainAB, chainBC);

Both are methods on Panproto; composition fails (throws) if the intermediate schemas do not chain.

Verification

const result = lens.checkLaws(instanceBytes);
console.log(result.holds, result.violation);

// For individual laws:
const getput = lens.checkGetPut(instanceBytes);
const putget = lens.checkPutGet(instanceBytes);

LensHandle.checkLaws(instance) returns a LawCheckResult { holds, violation } covering GetPut and PutGet together. checkGetPut and checkPutGet test each law individually; the Rust property tests in panproto-lens cover PutPut as well, exercised continuously in CI.

Common mistakes

  • Calling put with a complement from a different source. Complement::compose will refuse with ComplementFingerprintMismatch. Recompute the complement from the current source rather than reusing one.
  • Reading get and then mutating the source before calling put. The complement is computed against the source as it was at get time; if you mutate the source, the complement is stale.
  • Composing lenses whose intermediate schemas are isomorphic but not equal. The structural-equality check on protolens_composable will reject; rebuild one of the lenses against the other’s schema.

See also