Skip to content
This repository has been archived by the owner on Jun 9, 2019. It is now read-only.

mohayonao/json-touch-patch

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

42 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

json-touch-patch

Build Status NPM Version License

Immutable JSON Patch implementation based on RFC 6902

Features

  • Immutable: The original JSON is not update. The patches apply to a new JSON.
  • Touch: The patches create a new object if it includes some changes into child elements.
  • Rollback: If error occurs, all patches are rejected. Return the original JSON.
  • Customizable: You can add custom operator using the operator API. → Wiki
  • Maybe, these features are suitable to operate store in React and Redux architecture.

Installation

$ npm install --save json-touch-patch

API

  • patch(prevObject: object, patches: object[], [ opts: object ]): object
    • opts.custom: object custom operator definition.
    • opts.partial: boolean not reject patches if error occurs (partial patching)
    • opts.strict: boolean throw an exception if error occurs
    • opts.error: object point to a cause patch if error occurs
    • returns nextObject: object

Quick example

const patch = require("json-touch-patch");

const prevObject = { "baz": "qux", "foo": "bar" };
const patches = [
  { "op": "replace", "path": "/baz", "value": "boo" },
];
const nextObject = patch(prevObject, patches);
// → { "baz": "boo", "foo": "bar" }
//              |
//             replaced

console.log(prevObject);
// → { "baz": "qux", "foo": "bar" }
//              |
//             not changed

How to apply patches

add

const patches = [
  { op: "add", path: "/matrix/1/-", value: 9 },
];

Return a new JSON. It contains shallow-copied elements that have some changes into child elements. And it contains original elements that are not updated any.

add

assert(prevObject.matrix[0] === nextObject.matrix[0]);
assert(prevObject.matrix[1] !== nextObject.matrix[1]);
assert(prevObject.matrix[2] === nextObject.matrix[2]);

remove

const patches = [
  { op: "remove", path: "/matrix/1" },
];

Return a new JSON. It contains shallow-copied elements that have some changes into child elements. And it contains original elements that are not updated any.

remove

assert(prevObject.matrix[0] === nextObject.matrix[0]);
assert(prevObject.matrix[1] !== nextObject.martix[1]);
assert(prevObject.matrix[2] === nextObject.matrix[1]);

replace

const patches = [
  { op: "replace", path: "/matrix/1/1", value: 9 },
];

Return a new JSON. It contains shallow-copied elements that have some changes into child elements. And it contains original elements that are not updated any.

replace

assert(prevObject.matrix[0] === nextObject.matrix[0]);
assert(prevObject.matrix[1] !== nextObject.matrix[1]);
assert(prevObject.matrix[2] === nextObject.matrix[2]);

replace (no changes)

const patches = [
  { op: "replace", path: "/matrix/1/1", value: 4 },
];

Return the original JSON. Because all elements are not changed.

replace

prevObject.matrix[1][1] is already 4. So, this patch is need not to update any.

assert(prevObject === nextObject);

move

const patches = [
  { op: "move", from: "/matrix/1", path: "/matrix/2" },
];

Return a new JSON. [op:move] works as [op:get(from)] -> [op:remove(from)] -> [op:add(path)].

move

assert(prevObject.matrix[0] === nextObject.matrix[0]);
assert(prevObject.matrix[1] === nextObject.martix[2]);
assert(prevObject.matrix[2] === nextObject.matrix[1]);

copy

const patches = [
  { op: "copy", from: "/matrix/1", path: "/matrix/1" },
];

Return a new JSON. [op:copy] works as [op:get(from)] -> [op:add(path)].

copy

assert(prevObject.matrix[0] === nextObject.matrix[0]);
assert(prevObject.matrix[1] === nextObject.martix[1]);
assert(prevObject.matrix[1] === nextObject.martix[2]);
assert(prevObject.matrix[2] === nextObject.matrix[3]);

test failed

const patch = [
  { op: "add" , path: "/matrix/1/-", value: 9 },
  { op: "test", path: "/matrix/1/1", value: 0 },
];

Return the original JSON. Because a test op is failed. All patches are rejected.

test

prevObject.matrix[1][1] is not 0 but 4. So, this test is failed.

assert(prevObject === nextObject);

invalid patch

const json = [
  { op: "replace", path: "/matrix/1/100", value: 9 },
];

Return the original JSON. Because all patches are rejected when error occurs.

invalid

prevObject.matrix[1][100] is not defined. So, this patch is invalid.

assert(prevObject === nextObject);

License

MIT

About

Immutable JSON Patch implementation based on RFC 6902

Resources

Stars

Watchers

Forks

Packages

No packages published