惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Apple Machine Learning Research
Apple Machine Learning Research
AWS News Blog
AWS News Blog
Google DeepMind News
Google DeepMind News
U
Unit 42
博客园 - 叶小钗
博客园 - 聂微东
GbyAI
GbyAI
Stack Overflow Blog
Stack Overflow Blog
有赞技术团队
有赞技术团队
aimingoo的专栏
aimingoo的专栏
D
DataBreaches.Net
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
Jina AI
Jina AI
美团技术团队
The Cloudflare Blog
M
MIT News - Artificial intelligence
Microsoft Azure Blog
Microsoft Azure Blog
I
InfoQ
S
Schneier on Security
C
Check Point Blog
Project Zero
Project Zero
The Hacker News
The Hacker News
Scott Helme
Scott Helme
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
Cisco Talos Blog
Cisco Talos Blog
P
Privacy International News Feed
SecWiki News
SecWiki News
Latest news
Latest news
MongoDB | Blog
MongoDB | Blog
S
Secure Thoughts
Google Online Security Blog
Google Online Security Blog
F
Fortinet All Blogs
博客园 - 三生石上(FineUI控件)
H
Help Net Security
TaoSecurity Blog
TaoSecurity Blog
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
Last Week in AI
Last Week in AI
P
Privacy & Cybersecurity Law Blog
Forbes - Security
Forbes - Security
G
GRAHAM CLULEY
N
Netflix TechBlog - Medium
L
Lohrmann on Cybersecurity
A
About on SuperTechFans
T
The Exploit Database - CXSecurity.com
C
Cisco Blogs
PCI Perspectives
PCI Perspectives
大猫的无限游戏
大猫的无限游戏
T
Troy Hunt's Blog
H
Hacker News: Front Page
Vercel News
Vercel News

Sanity.io

A Board Game agent built using Sanity Context and Vercel's AI SDK | Sanity Build a prototype with Claude Code that your whole team can edit | Sanity What’s New - May 2026 | Sanity I built a London pub guide with v0 and the Sanity MCP in six hours. Here's what I learned. | Sanity Build a conference concierge with Agent Context and Anthropic | Sanity Build a content-aware Telegram agent with Vercel AI SDK and Chat SDK | Sanity How I used Agent API to generate photos for my family’s recipes | Sanity What’s New April - 2026 | Sanity Better context, better matches: An AI love story (for dogs) | Sanity How to write for an agent | Sanity Content Agent, meet Slack: AI content operations in your workflow | Sanity Structure powers intelligence | Sanity Your agent needs better content. Here's how to give it. | Sanity How to serve content to agents (a field guide) | Sanity Sanity TypeGen GA: Automatic TypeScript types for content and GROQ | Sanity Sanity is now available on the Vercel Marketplace | Sanity The logo soup problem (and how to solve it) | Sanity Content Releases: From scattered updates to coordinated publishing | Sanity What's New - February 2026 | Sanity How we solved the agent memory problem | Sanity v0 Builder Challenge: The winners | Sanity Introducing: Sanity Agent Skills | Sanity Content Agent: Days of work in one conversation | Sanity Our Sanity Values | Sanity Open Source Pledge 2025: Stepping up when it matters | Sanity v0 builder challenge: $3000 in prizes | Sanity Why AI Breaks Without Structured Content Operations | Sanity What’s New January - 2026 | Sanity BFCM 2025: What teams built when infrastructure stopped being the problem | Sanity How AI shaped holiday shopping and what it means for content in 2026 | Sanity Sanity Studio v5: Embracing React 19 | Sanity You’ll need a CMS eventually. Let your agent set it up. | Sanity “You should never build a CMS” | Sanity AI Content Operations: A 30-Day Implementation Guide | Sanity What’s New December - 2025 | Sanity Scheduled Drafts: Stop manually publishing content at midnight | Sanity What’s New November - 2025 | Sanity Everything *[NYC] 2025 recap: A day of AI, Content Operations, and Culture | Sanity Clankers and content operations | Sanity Content Agent: AI that understands your structured content is here | Sanity Why design-driven content modeling creates technical debt, not velocity | Sanity What's New October - 2025 | Sanity From studio to inbox: How Kevin Green eliminated email campaign friction | Sanity The content editor's guide to content operations [E-commerce edition] | Sanity styled-components maintenance mode: A 40% faster fork | Sanity From zero code to a live website in 7 hours (thanks, Cursor!) | Sanity First attempt will be 95% garbage: A staff engineer's 6-week journey with Claude Code | Sanity Internationalization is more than translating words | Sanity What's New - September 2025 | Sanity We just deleted our 35k-member community Slack | Sanity What's New - August 2025 | Sanity The engineer's guide to content operations [E-commerce edition] | Sanity SEO for AI: Evolving from Web Pages to the Content Lake | Sanity What's New - July 2025 | Sanity Sanity Studio v4: A major version bump for a minor reason | Sanity What's New - June 2025 | Sanity Dashboard and Insights: Your New Content HQ | Sanity Canvas: AI-accelerated, context-aware, freeform authoring | Sanity Agent Actions: AI building blocks for structured content | Sanity Functions: Life beyond pressing publish | Sanity A new era for content applications with Sanity App SDK | Sanity The end of CMS era and our $85M Series C. | Sanity What's New – May 2025 | Sanity Introducing the Sanity Model Context Protocol (MCP) server | Sanity What's New – April 2025 | Sanity Pushing all the envelopes with ambitious content | Sanity Self-hosting is only free if your time is worth nothing | Sanity Content that lasts: Scaling beyond your frontend | Sanity The Live Content API is now Generally Available | Sanity The future beyond AI chat bots | Sanity Learning the new skill of working with AI | Sanity What's New - March 2025 | Sanity Give it in plain text: Making your content AI-Ready | Sanity No More 'DO NOT PUBLISH': Introducing Content Releases | Sanity React in 2025, what's next? | Sanity The final boss of front-end: block editors | Sanity Introducing Sanity for Startups | Sanity A block content editor that loves you back | Sanity A Black Friday Snooze Fest: Massive Traffic, No Drama | Sanity How to make a recipe site that scales well | Sanity The Sanity Winter Release 2024 | Sanity AVIF Arrives, Sanity’s Promise Fulfilled | Sanity Sanity joins the Open Source Pledge | Sanity Your content is now Live by default | Sanity Begin Team to Join Sanity | Sanity Sanity Digest - September '24 Edition | Sanity Sanity partners with Google. Now live on the Google Cloud Marketplace. | Sanity Sanity Digest - August ‘24 Edition | Sanity Now playing: the latest Mux Video Input plugin for Sanity | Sanity Community Digest - June ‘24 Edition | Sanity Community Digest - May ‘24 Edition | Sanity Guide to Sanity's newest product announcements | Sanity AI and Content Creation: A Leader's Guide | Sanity Of course, you should be able to type your content quickly! | Sanity New to AI Assist: translation, reference suggestions, image generation | Sanity Speak the language of your editors: Sanity Studio UI localization | Sanity Introducing the new Sanity Growth plan to serve collaborative teams | Sanity Presentation: Work faster than ever with structured content | Sanity Goodbye Feedback Frenzy, Hello Sanity Studio Comments! | Sanity Easing into the App Router with the Sanity Toolkit for Next.js | Sanity
Mendoza - The totally non-human readable diff format for structured JSON documents | Sanity
Magnus Holm · 2020-10-27 · via Sanity.io

When we started work on the recently released feature Review Changes, we needed a way to keep a significant part of the edit history of a document in the browser memory to be able to respond quickly to different user interface states. As the user picked various document versions to compare we wanted to be able to quickly reconstruct a specific section of the history of a document.

The Portable Text Editor with the Review Changes panel showing content changes
Review Changes for Sanity Studio. Powered by Mendoza.

For text diffs, we use the diff-match-patch format, and we just assumed someone would have implemented a similarly efficient and compact diff format for JSON documents, but no such luck. If we wanted a general JSON diff format that was super compact and fast to apply, we would have to invent it ourselves. And thus, Mendoza, the totally non-human readable diff format for structured JSON documents, was born.

Mendoza is:

  • Lightweight JSON format
  • A flexible format that can accommodate more advanced encodings in the future
  • As a Go library for encoding and decoding
  • A JavaScript library for decoding
  • Efficient handling of the renaming of fields
  • Efficient handling of reordering of arrays
  • Not designed to be human-readable

Mendoza differs (hah!) from normal diffs as they are:

  • Made for humans to read and understand and based on simple operations (like keep, insert, and delete text)
  • Possible to apply even if the source has changed a bit by including some of the contexts around every part that has changed
  • Designed for text, and not structured documents

Now, this is great when you are collaborating with humans on code development and use something like git to track your changes. What it isn’t great for, however, is expressing differences between structured documents (such as JSON) in a compact manner that can be efficiently transferred over the network and parsed in JavaScript inside of browsers.

Most diffs aren't meant for machines

Most diff formats are made to be human-readable. Take these two documents, where a key and the array have some changes between them:

If these where two commits, the Git diff between them would be expressed like this:

This makes it somewhat practical for humans to understand what is going on when the latter change is applied. But as you can see, in terms of pure data, there is a lot of repetition going on. and expressing all changes with only plusses and minuses isn't very efficient.

The same diff with Mendoza is expressed like this:

Mendoza constructs a minimal recipe for transforming a document into another. All it really does is to compare two JSON documents and figure out the most minimal way to express their difference as strings and integers in an array. You can use this difference to reconstruct the first document to the other.

How to read a Mendoza patch (even though you shouldn't)

A Mendoza patch consists of an array of integers and strings. The integers are opcodes (short for “operation codes”), 8-bit numbers that correspond to an operation. Opcodes take parameters as strings, positive numbers, or JSON values (that is: the actual data that is changing). The list of available opcodes is as follows, notice that 10-18 are composites of the preceding ones:

  • 0 Value​
  • 1 Copy​
  • 2 Blank​
  • 3 ReturnIntoArray​
  • 4 ReturnIntoObject​
  • 5 ReturnIntoObjectSameKey​
  • 6 PushField​
  • 7 PushElement​
  • 8 PushParent​
  • 9 Pop​
  • 10 PushFieldCopy
  • 11 PushFieldBlank
  • 12 PushElementCopy
  • 13 PushFieldBlank
  • 14 ReturnIntoObjectPop
  • 15 ReturnIntoObjectSameKeyPop
  • 16 ReturnIntoArrayPop
  • 17 ObjectSetFieldValue
  • 18 ObjectCopyField
  • 19 ObjectDeleteField
  • 20 ArrayAppendValue
  • 21 ArrayAppendSlice​
  • 22 StringAppendString​

Mendoza reads these opcodes from the patch and produces the resulting document from them. Depending on the patch, Mendoza might choose not to strictly follow the opcodes but take a simpler path. If every field and value has changed, for example, it’s more efficient just to replace the whole document with the new data without going through all the operations. Or if you have a list of objects where one has moved to another position and changed a key-value, Mendoza will manage to go back to the original and represent the change in a cheap way.

Run your own Mendoza

Mendoza is implemented in Go and can be found in this GitHub repository. We have also made a parser for Mendoza patches in JavaScript, that you can use in your own application.

Of course, you can dive into the source code for the Sanity Studio and explore how Mendoza is used there. If you want a slightly simpler use-case, you can also check out how we’re using Mendoza to simulate a part of Sanity’s real-time datastore in the browser to power the real-time preview for Next.js.

Why “Mendoza”?

Naming a project is always difficult. Since this project is focused on representing changes between JSON documents I naturally started thinking about names like "JSON differ, JSON changes, JSON patch, …". However, most of these names have already been used by existing projects. While I was muttering "JSON, JSON, JSON" it suddenly turned into "JSON, JSON, Jason, Jason Mendoza".

Jason Mendoza is a character from the show The Good Place, and while this project has little in common with the stupidest DJ from Florida, at least it's short and catchy.

Some caveats

Since a Mendoza patch is just describing the effect of a change it is also limited to work for the documents it was based on. It doesn’t come with guarantees for consistency if the document you apply it on has changed from the original in meanwhile. This is one of the tradeoffs that we needed to do to make it really compressed.