[d24f17c] | 1 | Object.defineProperty(exports, "__esModule", { value: true });
|
---|
| 2 | /*!
|
---|
| 3 | * https://github.com/Starcounter-Jack/JSON-Patch
|
---|
| 4 | * (c) 2017-2021 Joachim Wester
|
---|
| 5 | * MIT license
|
---|
| 6 | */
|
---|
| 7 | var helpers_js_1 = require("./helpers.js");
|
---|
| 8 | var core_js_1 = require("./core.js");
|
---|
| 9 | var beforeDict = new WeakMap();
|
---|
| 10 | var Mirror = /** @class */ (function () {
|
---|
| 11 | function Mirror(obj) {
|
---|
| 12 | this.observers = new Map();
|
---|
| 13 | this.obj = obj;
|
---|
| 14 | }
|
---|
| 15 | return Mirror;
|
---|
| 16 | }());
|
---|
| 17 | var ObserverInfo = /** @class */ (function () {
|
---|
| 18 | function ObserverInfo(callback, observer) {
|
---|
| 19 | this.callback = callback;
|
---|
| 20 | this.observer = observer;
|
---|
| 21 | }
|
---|
| 22 | return ObserverInfo;
|
---|
| 23 | }());
|
---|
| 24 | function getMirror(obj) {
|
---|
| 25 | return beforeDict.get(obj);
|
---|
| 26 | }
|
---|
| 27 | function getObserverFromMirror(mirror, callback) {
|
---|
| 28 | return mirror.observers.get(callback);
|
---|
| 29 | }
|
---|
| 30 | function removeObserverFromMirror(mirror, observer) {
|
---|
| 31 | mirror.observers.delete(observer.callback);
|
---|
| 32 | }
|
---|
| 33 | /**
|
---|
| 34 | * Detach an observer from an object
|
---|
| 35 | */
|
---|
| 36 | function unobserve(root, observer) {
|
---|
| 37 | observer.unobserve();
|
---|
| 38 | }
|
---|
| 39 | exports.unobserve = unobserve;
|
---|
| 40 | /**
|
---|
| 41 | * Observes changes made to an object, which can then be retrieved using generate
|
---|
| 42 | */
|
---|
| 43 | function observe(obj, callback) {
|
---|
| 44 | var patches = [];
|
---|
| 45 | var observer;
|
---|
| 46 | var mirror = getMirror(obj);
|
---|
| 47 | if (!mirror) {
|
---|
| 48 | mirror = new Mirror(obj);
|
---|
| 49 | beforeDict.set(obj, mirror);
|
---|
| 50 | }
|
---|
| 51 | else {
|
---|
| 52 | var observerInfo = getObserverFromMirror(mirror, callback);
|
---|
| 53 | observer = observerInfo && observerInfo.observer;
|
---|
| 54 | }
|
---|
| 55 | if (observer) {
|
---|
| 56 | return observer;
|
---|
| 57 | }
|
---|
| 58 | observer = {};
|
---|
| 59 | mirror.value = helpers_js_1._deepClone(obj);
|
---|
| 60 | if (callback) {
|
---|
| 61 | observer.callback = callback;
|
---|
| 62 | observer.next = null;
|
---|
| 63 | var dirtyCheck = function () {
|
---|
| 64 | generate(observer);
|
---|
| 65 | };
|
---|
| 66 | var fastCheck = function () {
|
---|
| 67 | clearTimeout(observer.next);
|
---|
| 68 | observer.next = setTimeout(dirtyCheck);
|
---|
| 69 | };
|
---|
| 70 | if (typeof window !== 'undefined') { //not Node
|
---|
| 71 | window.addEventListener('mouseup', fastCheck);
|
---|
| 72 | window.addEventListener('keyup', fastCheck);
|
---|
| 73 | window.addEventListener('mousedown', fastCheck);
|
---|
| 74 | window.addEventListener('keydown', fastCheck);
|
---|
| 75 | window.addEventListener('change', fastCheck);
|
---|
| 76 | }
|
---|
| 77 | }
|
---|
| 78 | observer.patches = patches;
|
---|
| 79 | observer.object = obj;
|
---|
| 80 | observer.unobserve = function () {
|
---|
| 81 | generate(observer);
|
---|
| 82 | clearTimeout(observer.next);
|
---|
| 83 | removeObserverFromMirror(mirror, observer);
|
---|
| 84 | if (typeof window !== 'undefined') {
|
---|
| 85 | window.removeEventListener('mouseup', fastCheck);
|
---|
| 86 | window.removeEventListener('keyup', fastCheck);
|
---|
| 87 | window.removeEventListener('mousedown', fastCheck);
|
---|
| 88 | window.removeEventListener('keydown', fastCheck);
|
---|
| 89 | window.removeEventListener('change', fastCheck);
|
---|
| 90 | }
|
---|
| 91 | };
|
---|
| 92 | mirror.observers.set(callback, new ObserverInfo(callback, observer));
|
---|
| 93 | return observer;
|
---|
| 94 | }
|
---|
| 95 | exports.observe = observe;
|
---|
| 96 | /**
|
---|
| 97 | * Generate an array of patches from an observer
|
---|
| 98 | */
|
---|
| 99 | function generate(observer, invertible) {
|
---|
| 100 | if (invertible === void 0) { invertible = false; }
|
---|
| 101 | var mirror = beforeDict.get(observer.object);
|
---|
| 102 | _generate(mirror.value, observer.object, observer.patches, "", invertible);
|
---|
| 103 | if (observer.patches.length) {
|
---|
| 104 | core_js_1.applyPatch(mirror.value, observer.patches);
|
---|
| 105 | }
|
---|
| 106 | var temp = observer.patches;
|
---|
| 107 | if (temp.length > 0) {
|
---|
| 108 | observer.patches = [];
|
---|
| 109 | if (observer.callback) {
|
---|
| 110 | observer.callback(temp);
|
---|
| 111 | }
|
---|
| 112 | }
|
---|
| 113 | return temp;
|
---|
| 114 | }
|
---|
| 115 | exports.generate = generate;
|
---|
| 116 | // Dirty check if obj is different from mirror, generate patches and update mirror
|
---|
| 117 | function _generate(mirror, obj, patches, path, invertible) {
|
---|
| 118 | if (obj === mirror) {
|
---|
| 119 | return;
|
---|
| 120 | }
|
---|
| 121 | if (typeof obj.toJSON === "function") {
|
---|
| 122 | obj = obj.toJSON();
|
---|
| 123 | }
|
---|
| 124 | var newKeys = helpers_js_1._objectKeys(obj);
|
---|
| 125 | var oldKeys = helpers_js_1._objectKeys(mirror);
|
---|
| 126 | var changed = false;
|
---|
| 127 | var deleted = false;
|
---|
| 128 | //if ever "move" operation is implemented here, make sure this test runs OK: "should not generate the same patch twice (move)"
|
---|
| 129 | for (var t = oldKeys.length - 1; t >= 0; t--) {
|
---|
| 130 | var key = oldKeys[t];
|
---|
| 131 | var oldVal = mirror[key];
|
---|
| 132 | if (helpers_js_1.hasOwnProperty(obj, key) && !(obj[key] === undefined && oldVal !== undefined && Array.isArray(obj) === false)) {
|
---|
| 133 | var newVal = obj[key];
|
---|
| 134 | if (typeof oldVal == "object" && oldVal != null && typeof newVal == "object" && newVal != null && Array.isArray(oldVal) === Array.isArray(newVal)) {
|
---|
| 135 | _generate(oldVal, newVal, patches, path + "/" + helpers_js_1.escapePathComponent(key), invertible);
|
---|
| 136 | }
|
---|
| 137 | else {
|
---|
| 138 | if (oldVal !== newVal) {
|
---|
| 139 | changed = true;
|
---|
| 140 | if (invertible) {
|
---|
| 141 | patches.push({ op: "test", path: path + "/" + helpers_js_1.escapePathComponent(key), value: helpers_js_1._deepClone(oldVal) });
|
---|
| 142 | }
|
---|
| 143 | patches.push({ op: "replace", path: path + "/" + helpers_js_1.escapePathComponent(key), value: helpers_js_1._deepClone(newVal) });
|
---|
| 144 | }
|
---|
| 145 | }
|
---|
| 146 | }
|
---|
| 147 | else if (Array.isArray(mirror) === Array.isArray(obj)) {
|
---|
| 148 | if (invertible) {
|
---|
| 149 | patches.push({ op: "test", path: path + "/" + helpers_js_1.escapePathComponent(key), value: helpers_js_1._deepClone(oldVal) });
|
---|
| 150 | }
|
---|
| 151 | patches.push({ op: "remove", path: path + "/" + helpers_js_1.escapePathComponent(key) });
|
---|
| 152 | deleted = true; // property has been deleted
|
---|
| 153 | }
|
---|
| 154 | else {
|
---|
| 155 | if (invertible) {
|
---|
| 156 | patches.push({ op: "test", path: path, value: mirror });
|
---|
| 157 | }
|
---|
| 158 | patches.push({ op: "replace", path: path, value: obj });
|
---|
| 159 | changed = true;
|
---|
| 160 | }
|
---|
| 161 | }
|
---|
| 162 | if (!deleted && newKeys.length == oldKeys.length) {
|
---|
| 163 | return;
|
---|
| 164 | }
|
---|
| 165 | for (var t = 0; t < newKeys.length; t++) {
|
---|
| 166 | var key = newKeys[t];
|
---|
| 167 | if (!helpers_js_1.hasOwnProperty(mirror, key) && obj[key] !== undefined) {
|
---|
| 168 | patches.push({ op: "add", path: path + "/" + helpers_js_1.escapePathComponent(key), value: helpers_js_1._deepClone(obj[key]) });
|
---|
| 169 | }
|
---|
| 170 | }
|
---|
| 171 | }
|
---|
| 172 | /**
|
---|
| 173 | * Create an array of patches from the differences in two objects
|
---|
| 174 | */
|
---|
| 175 | function compare(tree1, tree2, invertible) {
|
---|
| 176 | if (invertible === void 0) { invertible = false; }
|
---|
| 177 | var patches = [];
|
---|
| 178 | _generate(tree1, tree2, patches, '', invertible);
|
---|
| 179 | return patches;
|
---|
| 180 | }
|
---|
| 181 | exports.compare = compare;
|
---|