Patch is a single 3k javascript file with no dependencies that provides an immutable object with 4 isomorphisms including a URI encoded query string form.
Patch comes in handy when you have 2-D languages that:
Patch gets its power from its isomorphisms. With Patch, you design your query params so that they map to a TSV document. Then Patch encodes and decodes that document.
{
"selection": "Canada",
"year": "2000",
"tab": "map"
}
Serializing this Object Literal into a URL looks like:
selection=Canada&year=2000&tab=map
patch=selection~Canada...year~2000...tab~map
The Patch is isomorphic to this TSV:
selection\tCanada
year\t2000
tab\tmap
A Patch object has 4 forms:
countries~Canada~France...year~2020
countries\tCanada\tFrance
year\t2020
{
"countries": ["Canada", "France"],
"years": ["2020"],
}
Note: if you use this form and have duplicate identifiers, be sure to parse yourself as JSON does not support duplicate identifiers.
[
["countries", "Canada", "France"],
["years", "2020", "France],
]
Patch requires 2 delimiters, one for separating "rows" and one for separating "columns". Currently for the delimiters we use "~" for tabs and "..." for newlines. You can change those to suit your own preferences or needs.
If needed, use semantic versioning, only caring about breaking changes so only a major version: patchVersion=2&patch=
Patch encodes spaces to +
instead of %20
and uses the standard encoding of +
to %2B
.
String inputs to the Patch constructor are assumed to be encoded and will be decoded before parsing. Similarly the string output is always encoded.
URL query strings can be thought of as a domain specific language for describing this structure:
type UrlEncodedString = Omit<string, [RestrictedCharacters]>
Map<UrlEncodedString, UrlEncodedString>
It has a one very restricted string type, and does not have any concept of numbers, booleans, arrays, enums, trees, nested maps, et cetera.
It is a very low level DSL; arguably adds little to no value on top of just a single string.
Patch is a DSL let's you use any data structure you want and handles the compiling/decompiling to QueryString, while preserving human readability.
JSON would be a similar alternative to Patch, except you completely lose human readability in query strings, and it suffers from JSONs lack of certain data structures, like tuple arrays.
Patch was originally developed for https://ourworldindata.org. This is a fork.