position-strings
Version:
Lexicographically-ordered position strings for collaborative lists and text
73 lines • 2.99 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.Cursors = void 0;
const find_position_1 = require("./find_position");
const position_source_1 = require("./position_source");
const util_1 = require("./util");
/**
* Utilities for working with cursors in a collaborative list
* or text string.
*
* A *cursor* points to a particular spot in a list, in between
* two list elements (or text characters). This class handles
* cursors for lists that use our position strings.
*
* A cursor is represented as a string.
* Specifically, it is the position of the element
* to its left, or `PositionSource.FIRST` if it is at the beginning
* of the list. If that position is later deleted, the cursor stays the
* same, but its index shifts to next element on its left.
*
* You can use cursor strings as ordinary cursors, selection endpoints,
* range endpoints for a comment or formatting span, etc.
*/
class Cursors {
constructor() {
// Not instantiable.
}
/**
* Returns the cursor at `index` within the given list of positions. Invert with `Cursors.toIndex`.
*
* That is, the cursor is between the list elements at `index - 1` and `index`.
*
* If this method is inconvenient (e.g., the positions are in a database
* instead of an array), you can instead run the following algorithm yourself:
* - If `index` is 0, return `PositionSource.FIRST = ""`.
* - Else return `positions[index - 1]`.
*
* @param positions The target list's positions, in lexicographic order.
* There should be no duplicate positions.
*/
static fromIndex(index, positions) {
(0, util_1.precond)(index >= 0 && index <= positions.length, "Index out of bounds:", index, positions.length);
return index === 0 ? position_source_1.PositionSource.FIRST : positions[index - 1];
}
/**
* Returns the current index of `cursor` within the given list of
* positions. Inverse of `Cursors.fromIndex`.
*
* That is, the cursor is between the list elements at `index - 1` and `index`.
*
* If this method is inconvenient (e.g., the positions are in a database
* instead of an array), you can instead compute
* `index` by finding the number of positions less than
* or equal to `position`.
* For example, in SQL, use:
* ```sql
* SELECT COUNT(*) FROM table WHERE position <= $position
* ```
*
* See also: `findPosition`.
*
* @param positions The target list's positions, in lexicographic order.
* There should be no duplicate positions.
*/
static toIndex(cursor, positions) {
const { index, isPresent } = (0, find_position_1.findPosition)(cursor, positions);
// findPosition gives < elements, but we want <= elements.
// So if there's an == element, add 1.
return isPresent ? index + 1 : index;
}
}
exports.Cursors = Cursors;
//# sourceMappingURL=cursors.js.map