Skip to content

Conversation

@ricokahler
Copy link
Contributor

@ricokahler ricokahler commented Jun 3, 2025

This PR introduces a BREAKING CHANGE by replacing the previously exported diffItem function with a new, more clearly named public API: diffValue. It also significantly refactors the internal patch serialization logic and introduces more granular type definitions for patch operations.

The primary goals are to:

  1. Provide a clear, dedicated public API (diffValue) for generating patch operations on arbitrary values (not necessarily whole documents).
  2. Make the internal diffItem function truly internal.
  3. Improve the structure and type safety of patch serialization, moving away from monolithic SanityPatch types to more specific SanityPatchOperation types.
  4. Ensure that ifRevisionID is only added to the very first patch in a set of mutations.

Key Changes:

  • BREAKING CHANGE: API Rename and Visibility:
    • The diffItem function is no longer exported. Its functionality is now primarily internal.
    • A new function diffValue(source: unknown, target: unknown, basePath?: Path): SanityPatchOperations[] is introduced and exported. This function generates an array of SanityPatchOperations (which are plain objects like {set: {...}}, {unset: [...]}) based on the differences between source and target values. It does not wrap these operations in the SanityPatchMutation structure.
    • The diffPatch function (which diffs documents and returns SanityPatchMutation[]) now internally calls diffItem and then uses the refactored serializePatches to construct the final mutations. The logic for adding id and ifRevisionID to the patch mutations now resides within diffPatch.
  • BREAKING CHANGE: Patch Type Refinements:
    • Removed older, more generic patch types like SetPatch, InsertAfterPatch, SanitySetPatch, SanityUnsetPatch, SanityInsertPatch, and SanityDiffMatchPatch from the public API (some were previously exported from patches.ts).
    • Introduced new, more specific types for patch operations:
      • SanitySetPatchOperation ({ set: Record<string, unknown> })
      • SanityUnsetPatchOperation ({ unset: string[] })
      • SanityInsertPatchOperation ({ insert: { before/after/replace: string, items: unknown[] } })
      • SanityDiffMatchPatchOperation ({ diffMatchPatch: Record<string, string> })
    • The SanityPatchOperations type is now a Partial union of these new operation types, reflecting that a single patch object from diffValue will contain one or more of these operations.
    • The SanityPatch type (used within SanityPatchMutation) now extends SanityPatchOperations and includes id and optional ifRevisionID.
    • The internal Patch type (used by diffItem) remains but is now an internal detail.
  • Refactored serializePatches Function:
    • The serializePatches function now takes an array of internal Patch objects and returns an array of SanityPatchOperation[] (the raw operation objects like {set: {...}}).
    • It no longer handles adding id or ifRevisionID; this responsibility is moved to the diffPatch function.
    • The logic for grouping set, unset, insert, and diffMatchPatch operations into distinct objects in the output array has been improved for clarity.
  • Refactored diffPatch Function:
    • Now calls the internal diffItem to get the raw patch list.
    • Calls the refactored serializePatches to get SanityPatchOperations[].
    • Maps over these operations to create SanityPatchMutation[], adding the id to each and ifRevisionID only to the first patch mutation in the array.
  • JSDoc Updates:
    • Updated JSDoc for diffValue to clearly explain its purpose, parameters, and return type.
    • Updated JSDoc for diffPatch and internal types to reflect the changes.

Rationale:

  • Clearer Public API: diffValue provides a more intuitive name for diffing arbitrary JavaScript values and returning the raw operations, distinct from diffPatch which is document-centric.
  • Improved Type Safety & Granularity: The new Sanity...Operation types are more precise and make it easier to work with the different kinds of patch operations programmatically.
  • Correct ifRevisionID Handling: Ensuring ifRevisionID is only on the first patch of a transaction is crucial for correct optimistic locking in Sanity.
  • Better Separation of Concerns: diffItem focuses on generating a flat list of diffs, serializePatches (as used by diffValue) groups them into operations, and diffPatch handles the document-specific concerns like _id and ifRevisionID.

This refactor provides a cleaner and more robust API for generating patches, both for full documents and for arbitrary values.

Copy link
Contributor Author

ricokahler commented Jun 3, 2025

@ricokahler ricokahler force-pushed the v6_remove-undefined-to-null-warnings branch from fc0b806 to e538df3 Compare June 6, 2025 21:57
@ricokahler ricokahler force-pushed the v6_replace-diffitem-with-diffvalue branch from 61a3ffc to 5067260 Compare June 6, 2025 21:57
Copy link
Contributor Author

ricokahler commented Jun 13, 2025

Merge activity

  • Jun 13, 7:24 PM UTC: A user started a stack merge that includes this pull request via Graphite.
  • Jun 13, 7:31 PM UTC: Graphite rebased this pull request as part of a merge.
  • Jun 13, 7:33 PM UTC: @ricokahler merged this pull request with Graphite.

@ricokahler ricokahler changed the base branch from v6_remove-undefined-to-null-warnings to graphite-base/39 June 13, 2025 19:28
@ricokahler ricokahler changed the base branch from graphite-base/39 to main June 13, 2025 19:30
ricokahler and others added 2 commits June 13, 2025 19:31
- Add new diffValue function that returns SanityPatchOperations[]
- Remove diffItem from public API (now internal)
- Simplify exported types to reduce API surface area
- Internalize special patch format implementation details

BREAKING CHANGE: diffItem is no longer exported from the public API. Use diffValue instead, which returns an array of SanityPatchOperations rather than the internal Patch format.
Co-authored-by: Espen Hovlandsdal <espen@hovlandsdal.com>
@ricokahler ricokahler force-pushed the v6_replace-diffitem-with-diffvalue branch from c4070aa to 11e9d4f Compare June 13, 2025 19:31
@ricokahler ricokahler merged commit b8ad36a into main Jun 13, 2025
7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants