Appearance
Patches
Structura can create a serializable list of patches with all the modifications that were applied in a producer, and can also obtain the inverse modifications to return to the original state.
Patches and inverse patches are useful for example if you want to send them over a network or to implement undo/redo functionality.
Patches do not comply with RFC 6902, so if you want to use them in another language/library you should create your own parser but you can change this by turning a setting on. Alternatively there is a converter which can turn patches generated by structura into standard JSON Patches.
Example with callback
typescript
type Make = () => Record<string, number>[]
const makeObj: Make = () => [{ A: 1 }];
// first we get the result and the patches
let patches: Patch[] = [];
let inverse: Patch[] = [];
const result = produce(
makeObj(),
(draft) => {
draft.push({ B: 2 });
},
(_patches, _inverse) => {
patches = _patches;
inverse = _inverse;
}
);
// if we apply the patches from the same starting point, we get the same result
const newResult = applyPatches(makeObj(), patches);
expect(newResult).toEqual(result);
// then, if we apply the inverse patches, we obtain the original state
const undone = applyPatches(newResult, inverse);
expect(undone).toEqual(makeObj());
Example with produceWithPatches
The same example can be written more concisely by using produceWithPatches:
typescript
type Make = () => Record<string, number>[]
const makeObj: Make = () => [{ A: 1 }];
// first we get the result and the patches
const [result, patches, inverse] = produceWithPatches(makeObj(), (draft) => {
draft.push({ B: 2 });
});
// if we apply the patches from the same starting point, we get the same result
const newResult = applyPatches(makeObj(), patches);
expect(newResult).toEqual(result);
// then, if we apply the inverse patches, we obtain the original state
const undone = applyPatches(newResult, inverse);
expect(undone).toEqual(makeObj());