laif-ds
Version:
Design System di Laif con componenti React basati su principi di Atomic Design
177 lines (176 loc) • 5.09 kB
JavaScript
"use client";
class n {
/**
* @param {ReadonlyArray<T> | null | undefined} [initial]
* Initial items (optional).
* @returns
* Splice buffer.
*/
constructor(t) {
this.left = t ? [...t] : [], this.right = [];
}
/**
* Array access;
* does not move the cursor.
*
* @param {number} index
* Index.
* @return {T}
* Item.
*/
get(t) {
if (t < 0 || t >= this.left.length + this.right.length)
throw new RangeError("Cannot access index `" + t + "` in a splice buffer of size `" + (this.left.length + this.right.length) + "`");
return t < this.left.length ? this.left[t] : this.right[this.right.length - t + this.left.length - 1];
}
/**
* The length of the splice buffer, one greater than the largest index in the
* array.
*/
get length() {
return this.left.length + this.right.length;
}
/**
* Remove and return `list[0]`;
* moves the cursor to `0`.
*
* @returns {T | undefined}
* Item, optional.
*/
shift() {
return this.setCursor(0), this.right.pop();
}
/**
* Slice the buffer to get an array;
* does not move the cursor.
*
* @param {number} start
* Start.
* @param {number | null | undefined} [end]
* End (optional).
* @returns {Array<T>}
* Array of items.
*/
slice(t, e) {
const h = e ?? Number.POSITIVE_INFINITY;
return h < this.left.length ? this.left.slice(t, h) : t > this.left.length ? this.right.slice(this.right.length - h + this.left.length, this.right.length - t + this.left.length).reverse() : this.left.slice(t).concat(this.right.slice(this.right.length - h + this.left.length).reverse());
}
/**
* Mimics the behavior of Array.prototype.splice() except for the change of
* interface necessary to avoid segfaults when patching in very large arrays.
*
* This operation moves cursor is moved to `start` and results in the cursor
* placed after any inserted items.
*
* @param {number} start
* Start;
* zero-based index at which to start changing the array;
* negative numbers count backwards from the end of the array and values
* that are out-of bounds are clamped to the appropriate end of the array.
* @param {number | null | undefined} [deleteCount=0]
* Delete count (default: `0`);
* maximum number of elements to delete, starting from start.
* @param {Array<T> | null | undefined} [items=[]]
* Items to include in place of the deleted items (default: `[]`).
* @return {Array<T>}
* Any removed items.
*/
splice(t, e, h) {
const r = e || 0;
this.setCursor(Math.trunc(t));
const l = this.right.splice(this.right.length - r, Number.POSITIVE_INFINITY);
return h && s(this.left, h), l.reverse();
}
/**
* Remove and return the highest-numbered item in the array, so
* `list[list.length - 1]`;
* Moves the cursor to `length`.
*
* @returns {T | undefined}
* Item, optional.
*/
pop() {
return this.setCursor(Number.POSITIVE_INFINITY), this.left.pop();
}
/**
* Inserts a single item to the high-numbered side of the array;
* moves the cursor to `length`.
*
* @param {T} item
* Item.
* @returns {undefined}
* Nothing.
*/
push(t) {
this.setCursor(Number.POSITIVE_INFINITY), this.left.push(t);
}
/**
* Inserts many items to the high-numbered side of the array.
* Moves the cursor to `length`.
*
* @param {Array<T>} items
* Items.
* @returns {undefined}
* Nothing.
*/
pushMany(t) {
this.setCursor(Number.POSITIVE_INFINITY), s(this.left, t);
}
/**
* Inserts a single item to the low-numbered side of the array;
* Moves the cursor to `0`.
*
* @param {T} item
* Item.
* @returns {undefined}
* Nothing.
*/
unshift(t) {
this.setCursor(0), this.right.push(t);
}
/**
* Inserts many items to the low-numbered side of the array;
* moves the cursor to `0`.
*
* @param {Array<T>} items
* Items.
* @returns {undefined}
* Nothing.
*/
unshiftMany(t) {
this.setCursor(0), s(this.right, t.reverse());
}
/**
* Move the cursor to a specific position in the array. Requires
* time proportional to the distance moved.
*
* If `n < 0`, the cursor will end up at the beginning.
* If `n > length`, the cursor will end up at the end.
*
* @param {number} n
* Position.
* @return {undefined}
* Nothing.
*/
setCursor(t) {
if (!(t === this.left.length || t > this.left.length && this.right.length === 0 || t < 0 && this.left.length === 0))
if (t < this.left.length) {
const e = this.left.splice(t, Number.POSITIVE_INFINITY);
s(this.right, e.reverse());
} else {
const e = this.right.splice(this.left.length + this.right.length - t, Number.POSITIVE_INFINITY);
s(this.left, e.reverse());
}
}
}
function s(i, t) {
let e = 0;
if (t.length < 1e4)
i.push(...t);
else
for (; e < t.length; )
i.push(...t.slice(e, e + 1e4)), e += 1e4;
}
export {
n as SpliceBuffer
};