this repo has no description
at main 4.1 kB view raw
1"use strict"; 2Object.defineProperty(exports, "__esModule", { value: true }); 3exports.ObjectCursor = void 0; 4const optional_1 = require("../../types/optional"); 5const clone_1 = require("../../util/clone"); 6const key_path_1 = require("./key-path"); 7const traverse_1 = require("./traverse"); 8class ObjectCursor { 9 /** 10 * Create a cursor for an object. 11 * 12 * @param root - An object to traverse. 13 */ 14 constructor(root) { 15 this.values = [root]; 16 this.keyPaths = [key_path_1.thisKeyPath]; 17 this.savedDepths = []; 18 } 19 /** 20 * The current value this cursor is pointing at. 21 */ 22 get currentValue() { 23 return this.values[this.values.length - 1]; 24 } 25 /** 26 * The key path of the value this cursor is pointing at. 27 */ 28 get currentKeyPath() { 29 return this.keyPaths[this.keyPaths.length - 1]; 30 } 31 /** 32 * Advance this cursor to a given value and the key path which 33 * was used to reach it. 34 * 35 * Use this method to override the internal traversal logic of 36 * the cursor as needed. Like `moveTo`, calls to this method can 37 * be balanced with calls to `back`. 38 * 39 * @param value - The new value for the cursor to represent. 40 * @param keyPath - The key path used to reach the value. 41 */ 42 interject(value, keyPath) { 43 this.values.push(value); 44 this.keyPaths.push(keyPath); 45 } 46 /** 47 * Reconfigure this cursor to traverse a given object. 48 * 49 * @param newRoot - The new root object to traverse. 50 * @param keyPath - The key path specifying where the root object came from. 51 * Typically this should be `thisKeyPath` (the default value for this parameter.) 52 */ 53 reuse(newRoot, keyPath = key_path_1.thisKeyPath) { 54 this.values.length = 0; 55 this.values.push(newRoot); 56 this.keyPaths.length = 0; 57 this.keyPaths.push(keyPath); 58 this.savedDepths.length = 0; 59 } 60 /** 61 * Advance this cursor to a new position in the object it is traversing, 62 * saving its previous position so that the cursor may be moved back. 63 * 64 * @param keyPath - A key path referring to a location in the cursor's current value. 65 * @returns The new current value of the cursor. 66 */ 67 moveTo(keyPath) { 68 const newValue = (0, traverse_1.traverse)(this.currentValue, keyPath); 69 this.values.push(newValue); 70 this.keyPaths.push(keyPath); 71 return newValue; 72 } 73 /** 74 * Rewind this cursor to its previous position in the object it is traversing. 75 */ 76 moveBack() { 77 const currentDepth = this.values.length; 78 if (currentDepth === 1) { 79 throw new Error("Cannot move back past the root of a cursor"); 80 } 81 const numberOfSaves = this.savedDepths.length; 82 if (numberOfSaves > 0 && currentDepth <= this.savedDepths[numberOfSaves - 1]) { 83 throw new Error("Cannot move back past the most recent saved state"); 84 } 85 this.values.pop(); 86 this.keyPaths.pop(); 87 } 88 /** 89 * Save the current position of this cursor so that it may be restored later. 90 * 91 * Calls to this method must be balanced with a call to `restoreState`. 92 */ 93 saveState() { 94 this.savedDepths.push(this.values.length); 95 } 96 /** 97 * Restore this cursor's position to a previously saved state. 98 * 99 * Use this method to balance a previous call to `saveState`. 100 */ 101 restoreState() { 102 const savedLength = this.savedDepths.pop(); 103 if ((0, optional_1.isNothing)(savedLength)) { 104 throw new Error("Calls to restoreState must balance previous calls to saveState"); 105 } 106 this.values.length = savedLength; 107 this.keyPaths.length = savedLength; 108 } 109 // section Cloneable 110 clone() { 111 const copy = (0, clone_1.shallowCloneOf)(this); 112 copy.values = this.values.slice(); 113 copy.keyPaths = this.keyPaths.slice(); 114 copy.savedDepths = this.savedDepths.slice(); 115 return copy; 116 } 117} 118exports.ObjectCursor = ObjectCursor; 119//# sourceMappingURL=object-cursor.js.map