UNPKG

thorish

Version:

This is a library of useful JS concepts and data structures for Node and the browser. It it, unashamedly, a dumping ground for code needed by [@samthor](https://twitter.com/samthor)'s projects.

111 lines (110 loc) 3.12 kB
/** * @fileoverview Derived from @josephg's implementation here: https://github.com/josephg/jumprope * * MIT license etc etc */ /** * Returns a value [1,31] inclusive, with 50% chance of 1, 25% chance of 2, 12.5% chance of 3, ... */ export declare const randomHeight: () => number; export type RopeLookup<K, T> = { data: T; length: number; id: K; prevId: K; nextId: K; }; export type RopeRead<T> = { out: T[]; len: number[]; }; /** * Actually an 'immutable rope'. * * Parts cannot be modified, because they are objects with length that have some kind of rendering that this class won't understand. */ export declare class Rope<K, T> { private _length; private head; private tail; private readonly zeroId; private byId; private readonly _nodesBuffer; private readonly _subBuffer; private readonly _nodesPool; /** * Clones this {@link Rope} using {@link structuredClone}. */ clone(): Rope<K, T>; constructor(zeroId: K, root: T); length(): number; last(): K; count(): number; /** * Find the length between these two valid IDs. * * This isn't a substitute for {@link compare} as zero length entries are allowed, so this won't return which one is first. * * Currently just calls {@link find} twice. */ lengthBetween(low: K, high: K): number; /** * Prints out the rope for debugging. */ _debug(): void; [Symbol.iterator](): Generator<T, void, unknown>; /** * Finds the position after the given ID. * * Perf: `O(logn)-ish`. */ find(ropeId: K): number; has(ropeId: K): boolean; lookup(ropeId: K): RopeLookup<K, T>; /** * Find the ID for the given position, and the offset from the end of that ID. * Always returns a valid value, is clamped to edge. * * By default, this will be the left-most ID that contains the position (even 'at end'). * For example, looking up `offset=0` in an already-used rope will always yield `id=0`, as it has zero length. * * Specify the `biasEnd` parameter to flip this behavior. */ byPosition(position: number, biasAfter?: boolean): { id: K; offset: number; }; /** * Reduced version of `rseek` for various purposes... * * Result placed in `_nodesBuffer`. */ private rseekNodes; /** * Adjust the given entry's data/length. */ adjust(id: K, data: T, length: number): void; /** * Inserts a node after a previous node. */ insertAfter(afterId: K, newId: K, length: number, data: T): void; /** * Deletes the given ID from this rope. */ deleteById(id: K): T[]; /** * Deletes after the given ID until the target ID. */ deleteTo(afterId: K, untilId: K): T[]; private insertIntoPool; /** * Is the ID in `a` before the ID in `b`? */ before(a: K, b: K): boolean; compare(a: K, b: K): number; iter(afterId: K): Iterable<{ id: K; data: T; }>; read(from: K, to?: K): RopeRead<T> | undefined; }