jsonmergepatch

package
v1.0.3 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 20, 2026 License: MIT Imports: 4 Imported by: 0

Documentation

Overview

Package jsonmergepatch is a hand-rolled, stdlib-only implementation of JSON Merge Patch (RFC 7396). It powers delta-sync notifications on the MCP `notifications/resources/updated` channel: the server caches the previously-emitted serialisation of a subscribed resource and emits the smallest JSON Merge Patch that, when applied to that cache entry, yields the fresh state. The sub-package is deliberately kept tiny and self-contained so ADR 001's stdlib-only default build is preserved.

Two exported functions live here:

  • Diff(prev, curr []byte) ([]byte, error)
  • Apply(prev, patch []byte) ([]byte, error)

Diff emits a merge patch according to RFC 7396 §2: members present in curr but not in prev, or with a different value, appear in the patch verbatim. Members present in prev but absent from curr appear as JSON null in the patch to signal removal. Objects are walked recursively; arrays and non-object scalars are compared as atomic values and copied whole when they differ.

RFC 7396 has one notable limitation: there is no way to encode a JSON null value in the target document because null is reserved to mean delete. The DiffOrFull helper below handles this by falling back to a full replacement when the curr document contains any null value. The fallback is an additive signalling layer on top of the base RFC: callers that only need a textually-compliant merge patch should use Diff directly, while callers that want a lossless delta should use DiffOrFull and inspect the returned format code.

Index

Constants

View Source
const FormatDeleted = "deleted"

FormatDeleted signals that the subscribed URI's backing resource was deleted. The patch field is absent and clients should drop their cached state.

View Source
const FormatFull = "full"

FormatFull means the current document contains a null value that RFC 7396 cannot encode losslessly. The patch field is the full curr document; clients should replace their cached state wholesale.

View Source
const FormatMerge = "merge"

FormatMerge means the patch is a minimal RFC 7396 merge patch producible via Diff. Apply(prev, patch) == curr.

View Source
const FormatNone = "none"

FormatNone means no delta was computed because there was no prior state (a fresh subscription or a cache eviction). Callers should emit the notification with format="none" and let the client fetch.

Variables

This section is empty.

Functions

func Apply

func Apply(prev, patch []byte) ([]byte, error)

Apply applies a merge patch to prev and returns the updated document. Mirrors the RFC 7396 §1 MergePatch algorithm. Used by tests and available to downstream callers that want to round-trip Diff.

func Diff

func Diff(prev, curr []byte) ([]byte, error)

Diff returns the minimal RFC 7396 merge patch that, when applied to prev, yields curr. Both inputs must be valid JSON documents. The returned bytes are also a valid JSON document (either an object, or for non-object curr, curr itself).

Semantics for non-object inputs follow RFC 7396 §2 paragraph 1: if either prev or curr is not a JSON object, the patch is simply curr. This matches the merge-patch apply algorithm: MergePatch(any, curr) when curr is not an object replaces the entire target with curr.

func DiffOrFull

func DiffOrFull(prev, curr []byte) (patch []byte, format string, err error)

DiffOrFull wraps Diff with a null-scan: if curr contains any JSON null value anywhere in the document tree, the returned patch is curr itself and the format code is FormatFull. Otherwise the patch is the minimal merge patch and format is FormatMerge. Empty patches (no changes) still return FormatMerge with an empty-object body so the caller can distinguish from "cannot compute".

Types

This section is empty.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL