/ node_modules / @jet / environment / json / reader / object-cursor.js
object-cursor.js
  1  "use strict";
  2  Object.defineProperty(exports, "__esModule", { value: true });
  3  exports.ObjectCursor = void 0;
  4  const optional_1 = require("../../types/optional");
  5  const clone_1 = require("../../util/clone");
  6  const key_path_1 = require("./key-path");
  7  const traverse_1 = require("./traverse");
  8  class 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  }
118  exports.ObjectCursor = ObjectCursor;
119  //# sourceMappingURL=object-cursor.js.map