LiveViewReact.Patch (liveview_react v1.0.0)

Copy Markdown View Source

Encodes LiveViewReact patch operations into the compact wire format used by data-props-diff and data-streams-diff.

The payload is a concatenated sequence of operations. Dynamic text fields are JavaScript-string-length-prefixed, so paths and values can contain delimiters without extra escaping.

Operation codes:

CodeOperation
aadd
dremove
rreplace
sstream

Normal operations use:

<op><path_len>:<path><value>

remove omits <value>.

Value tags:

TagValue
znil
b0, b1booleans
n<len>:<number>number
s<len>:<string>string
J<len>:<caret-encoded JSON>maps, lists, and complex values

Paths are transported as JSON Pointer strings unchanged.

Summary

Types

A list-shaped patch operation returned by deserialize/1.

A patch map accepted by serialize/1.

A canonical stream frame carried by a stream patch operation.

Functions

Deserializes a compact patch payload into list-shaped operations.

Encodes a JSON value for safe, compact HTML attribute transport.

Serializes patch maps into a compact binary payload.

Types

decoded_patch_op()

@type decoded_patch_op() :: [term(), ...]

A list-shaped patch operation returned by deserialize/1.

Remove operations are [op, path]; add, replace, and stream operations are [op, path, value]. A decoded stream value is a stream_frame/0. The non-empty element type is necessarily broader because Elixir typespecs do not model fixed-length heterogeneous lists.

patch_op()

@type patch_op() ::
  %{op: String.t(), path: String.t()}
  | %{op: String.t(), path: String.t(), value: term()}

A patch map accepted by serialize/1.

:op is "add", "replace", "remove", or "stream". Add, replace, and stream operations contain exactly :op, :path, and :value; remove operations contain only :op and :path. A stream operation's value must be a stream_frame/0. Elixir typespecs cannot express the accepted string literals or exact map sizes, so runtime validation remains stricter than this structural union.

stream_frame()

@type stream_frame() :: %{required(String.t()) => term()}

A canonical stream frame carried by a stream patch operation.

The frame has exactly the "items", "inserts", "deletes", and "reset" fields validated by the stream transport.

Functions

deserialize(payload)

@spec deserialize(binary()) :: [decoded_patch_op()]

Deserializes a compact patch payload into list-shaped operations.

Returns [] for an empty payload. Decoded operations are shaped as [op, path] for remove and [op, path, value] for all value-bearing operations.

encode_object(value)

@spec encode_object(term()) :: binary()

Encodes a JSON value for safe, compact HTML attribute transport.

The value is encoded with Jason's default JSON escaping, then JSON quote characters are replaced with ^. Literal ~ and ^ characters are escaped as ~~ and ~^, so the transform is reversible by decode_object/1.

serialize(patches)

@spec serialize([patch_op()]) :: binary()

Serializes patch maps into a compact binary payload.

Expected patch shapes are %{op: op, path: path, value: value} and %{op: "remove", path: path}. Unknown operations and malformed shapes fail immediately.