Skip to content

Add an option to set initial path #30

@Valian

Description

@Valian

Is your feature request related to a problem? Please describe.
For a quite specific reason, I have to perform diff starting not at a root of object, but rather inside Map keys.

Describe the solution you'd like
I would like an option to set initial ancestor_path to a different value than "". Eg

Jsonpatch.diff(one, two, ancestor_path: "/some/nested/path")

Describe alternatives you've considered
Currently I'm postprocessing all the patches, mapping all paths to have values I need.

Additional context
This is a function I'm trying to optimize, coming from LiveVue. LiveView changed has true for simple updated values, so I have to generate replace patches manually for these

# Calculates minimal JSON Patch operations for changed props only.
  # Uses Phoenix LiveView's __changed__ tracking to identify what props have changed.
  # For simple values, generates direct replace operations.
  # For complex values (maps, lists), uses Jsonpatch.diff to find minimal changes.
  # Uses LiveVue.Encoder to safely encode structs before diffing.
  defp calculate_props_diff(changed_props, %{__changed__: changed}) do
    # For simple types: changed[k] == true
    # For complex types: changed[k] is the old value
    Enum.flat_map(changed_props, fn {k, new_value} ->
      case changed[k] do
        nil ->
          []

        # For simple types, generate replace operation
        true ->
          [%{op: "replace", path: "/#{k}", value: new_value}]

        # For complex types, use Jsonpatch to find minimal diff
        old_value ->
          new_value = Encoder.encode(new_value)

          old_value
          |> Encoder.encode()
          |> Jsonpatch.diff(new_value)
          |> update_in([Access.all(), :path], fn path -> "/#{k}#{path}" end)
      end
    end)
  end

Of course, I'm happy to push a PR! Just let me know if it's something you'd consider accepting. Related PR in my library: Valian/live_vue#60

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions