mirror of
https://github.com/rxliuli/apps.apple.com.git
synced 2025-11-09 22:00:32 +00:00
119 lines
4.0 KiB
JavaScript
119 lines
4.0 KiB
JavaScript
"use strict";
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
exports.ObjectCursor = void 0;
|
|
const optional_1 = require("../../types/optional");
|
|
const clone_1 = require("../../util/clone");
|
|
const key_path_1 = require("./key-path");
|
|
const traverse_1 = require("./traverse");
|
|
class ObjectCursor {
|
|
/**
|
|
* Create a cursor for an object.
|
|
*
|
|
* @param root - An object to traverse.
|
|
*/
|
|
constructor(root) {
|
|
this.values = [root];
|
|
this.keyPaths = [key_path_1.thisKeyPath];
|
|
this.savedDepths = [];
|
|
}
|
|
/**
|
|
* The current value this cursor is pointing at.
|
|
*/
|
|
get currentValue() {
|
|
return this.values[this.values.length - 1];
|
|
}
|
|
/**
|
|
* The key path of the value this cursor is pointing at.
|
|
*/
|
|
get currentKeyPath() {
|
|
return this.keyPaths[this.keyPaths.length - 1];
|
|
}
|
|
/**
|
|
* Advance this cursor to a given value and the key path which
|
|
* was used to reach it.
|
|
*
|
|
* Use this method to override the internal traversal logic of
|
|
* the cursor as needed. Like `moveTo`, calls to this method can
|
|
* be balanced with calls to `back`.
|
|
*
|
|
* @param value - The new value for the cursor to represent.
|
|
* @param keyPath - The key path used to reach the value.
|
|
*/
|
|
interject(value, keyPath) {
|
|
this.values.push(value);
|
|
this.keyPaths.push(keyPath);
|
|
}
|
|
/**
|
|
* Reconfigure this cursor to traverse a given object.
|
|
*
|
|
* @param newRoot - The new root object to traverse.
|
|
* @param keyPath - The key path specifying where the root object came from.
|
|
* Typically this should be `thisKeyPath` (the default value for this parameter.)
|
|
*/
|
|
reuse(newRoot, keyPath = key_path_1.thisKeyPath) {
|
|
this.values.length = 0;
|
|
this.values.push(newRoot);
|
|
this.keyPaths.length = 0;
|
|
this.keyPaths.push(keyPath);
|
|
this.savedDepths.length = 0;
|
|
}
|
|
/**
|
|
* Advance this cursor to a new position in the object it is traversing,
|
|
* saving its previous position so that the cursor may be moved back.
|
|
*
|
|
* @param keyPath - A key path referring to a location in the cursor's current value.
|
|
* @returns The new current value of the cursor.
|
|
*/
|
|
moveTo(keyPath) {
|
|
const newValue = (0, traverse_1.traverse)(this.currentValue, keyPath);
|
|
this.values.push(newValue);
|
|
this.keyPaths.push(keyPath);
|
|
return newValue;
|
|
}
|
|
/**
|
|
* Rewind this cursor to its previous position in the object it is traversing.
|
|
*/
|
|
moveBack() {
|
|
const currentDepth = this.values.length;
|
|
if (currentDepth === 1) {
|
|
throw new Error("Cannot move back past the root of a cursor");
|
|
}
|
|
const numberOfSaves = this.savedDepths.length;
|
|
if (numberOfSaves > 0 && currentDepth <= this.savedDepths[numberOfSaves - 1]) {
|
|
throw new Error("Cannot move back past the most recent saved state");
|
|
}
|
|
this.values.pop();
|
|
this.keyPaths.pop();
|
|
}
|
|
/**
|
|
* Save the current position of this cursor so that it may be restored later.
|
|
*
|
|
* Calls to this method must be balanced with a call to `restoreState`.
|
|
*/
|
|
saveState() {
|
|
this.savedDepths.push(this.values.length);
|
|
}
|
|
/**
|
|
* Restore this cursor's position to a previously saved state.
|
|
*
|
|
* Use this method to balance a previous call to `saveState`.
|
|
*/
|
|
restoreState() {
|
|
const savedLength = this.savedDepths.pop();
|
|
if ((0, optional_1.isNothing)(savedLength)) {
|
|
throw new Error("Calls to restoreState must balance previous calls to saveState");
|
|
}
|
|
this.values.length = savedLength;
|
|
this.keyPaths.length = savedLength;
|
|
}
|
|
// section Cloneable
|
|
clone() {
|
|
const copy = (0, clone_1.shallowCloneOf)(this);
|
|
copy.values = this.values.slice();
|
|
copy.keyPaths = this.keyPaths.slice();
|
|
copy.savedDepths = this.savedDepths.slice();
|
|
return copy;
|
|
}
|
|
}
|
|
exports.ObjectCursor = ObjectCursor;
|
|
//# sourceMappingURL=object-cursor.js.map
|