this repo has no description
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