Liking cljdoc? Tell your friends :D

remuda.diff

Server-side data/state diff.

Compares two view values and reports what changed. This is not a DOM diff and not a hiccup diff: it answers "which paths changed, and which keyed items were inserted, deleted, updated or moved". Turning that into HTML is :render's job; reconciling HTML into the live DOM is datastar/idiomorph's.

Two properties carry the design:

  1. identical? short-circuiting. Clojure's structural sharing means an untouched subtree is pointer-identical between old and new, so it can be pruned in O(1) without descending. Diff cost is proportional to what changed, not to view size.

  2. Keyed collections. A vector marked ^{:live/key :id} is diffed by key rather than by position, so persisted items produce update/move ops and never delete+insert. Positional diffing would cascade on a head insertion and lose DOM state (focus, scroll, input contents).

Op vocabulary is deliberately constrained to what datastar's eight patch modes can express, so nothing emitted here is unshippable:

:replace -> mode outer :insert (:before/:after) -> mode before/after :assoc -> mode outer :insert (:after last) -> mode append :dissoc -> mode remove :insert (:before first) -> mode prepend :delete -> mode remove :move -> mode before/after

Server-side data/state diff.

Compares two view *values* and reports what changed. This is not a DOM diff
and not a hiccup diff: it answers "which paths changed, and which keyed
items were inserted, deleted, updated or moved". Turning that into HTML is
`:render`'s job; reconciling HTML into the live DOM is datastar/idiomorph's.

Two properties carry the design:

1. `identical?` short-circuiting. Clojure's structural sharing means an
   untouched subtree is pointer-identical between old and new, so it can be
   pruned in O(1) without descending. Diff cost is proportional to what
   changed, not to view size.

2. Keyed collections. A vector marked `^{:live/key :id}` is diffed by key
   rather than by position, so persisted items produce update/move ops and
   never delete+insert. Positional diffing would cascade on a head
   insertion and lose DOM state (focus, scroll, input contents).

Op vocabulary is deliberately constrained to what datastar's eight patch
modes can express, so nothing emitted here is unshippable:

  :replace  -> mode outer      :insert (:before/:after) -> mode before/after
  :assoc    -> mode outer      :insert (:after last)    -> mode append
  :dissoc   -> mode remove     :insert (:before first)  -> mode prepend
  :delete   -> mode remove     :move                    -> mode before/after
raw docstring

apply-opsclj

(apply-ops view ops)

Applies diff ops to a view, reconstructing the new view.

Reference implementation of op semantics, used to verify the round-trip property. Ops are applied in order; diff emits deletes before updates before moves before inserts so anchors resolve against a stable collection.

Applies diff ops to a view, reconstructing the new view.

Reference implementation of op semantics, used to verify the round-trip
property. Ops are applied in order; `diff` emits deletes before updates
before moves before inserts so anchors resolve against a stable collection.
sourceraw docstring

diffclj

(diff old new)

Diffs two view values, returning a vector of ops.

Ops carry a :path (an update-in-style vector) and, for keyed collection ops, a :key identifying the item plus a :before/:after anchor.

Diffs two view values, returning a vector of ops.

Ops carry a `:path` (an `update-in`-style vector) and, for keyed collection
ops, a `:key` identifying the item plus a `:before`/`:after` anchor.
sourceraw docstring

diff-instrumentedclj

(diff-instrumented old new)

Like diff, but also reports how the work was done.

Returns {:ops :visited :pruned :deep-compares :scalar-compares}.

Exists for tests. A broken identical? short-circuit yields the same ops as a working one, so pruning is only observable through these counters — and specifically through :deep-compares, which counts collections whose equality had to be established the expensive way.

Like `diff`, but also reports how the work was done.

Returns `{:ops :visited :pruned :deep-compares :scalar-compares}`.

Exists for tests. A broken `identical?` short-circuit yields the same ops as
a working one, so pruning is only observable through these counters — and
specifically through `:deep-compares`, which counts collections whose
equality had to be established the expensive way.
sourceraw docstring

keyed-collection?clj

(keyed-collection? x)

True if x is a vector marked as a keyed collection via :live/key metadata.

Metadata is used rather than a wrapper type or a declaration in :state because metadata does not participate in =. Keying therefore stays invisible to value equality, and the convergence invariant remains testable as plain = on views.

True if `x` is a vector marked as a keyed collection via `:live/key`
metadata.

Metadata is used rather than a wrapper type or a declaration in `:state`
because metadata does not participate in `=`. Keying therefore stays
invisible to value equality, and the convergence invariant remains testable
as plain `=` on views.
sourceraw docstring

cljdoc builds & hosts documentation for Clojure/Script libraries

Keyboard shortcuts
Ctrl+kJump to recent docs
Move to previous article
Move to next article
Ctrl+/Jump to the search field
× close