UNPKG

@tldraw/state

Version:

tldraw infinite canvas SDK (state).

137 lines (136 loc) 4.65 kB
"use strict"; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); var HistoryBuffer_exports = {}; __export(HistoryBuffer_exports, { HistoryBuffer: () => HistoryBuffer }); module.exports = __toCommonJS(HistoryBuffer_exports); var import_types = require("./types"); class HistoryBuffer { /** * Creates a new HistoryBuffer with the specified capacity. * * capacity - Maximum number of diffs to store in the buffer * @example * ```ts * const buffer = new HistoryBuffer<number>(10) // Store up to 10 diffs * ``` */ constructor(capacity) { this.capacity = capacity; this.buffer = new Array(capacity); } /** * Current write position in the circular buffer. * @internal */ index = 0; /** * Circular buffer storing range tuples. Uses undefined to represent empty slots. * @internal */ buffer; /** * Adds a diff entry to the history buffer, representing a change between two epochs. * * If the diff is undefined, the operation is ignored. If the diff is RESET_VALUE, * the entire buffer is cleared to indicate that historical tracking should restart. * * @param lastComputedEpoch - The epoch when the previous value was computed * @param currentEpoch - The epoch when the current value was computed * @param diff - The diff representing the change, or RESET_VALUE to clear history * @example * ```ts * const buffer = new HistoryBuffer<string>(5) * buffer.pushEntry(0, 1, 'added text') * buffer.pushEntry(1, 2, RESET_VALUE) // Clears the buffer * ``` */ pushEntry(lastComputedEpoch, currentEpoch, diff) { if (diff === void 0) { return; } if (diff === import_types.RESET_VALUE) { this.clear(); return; } this.buffer[this.index] = [lastComputedEpoch, currentEpoch, diff]; this.index = (this.index + 1) % this.capacity; } /** * Clears all entries from the history buffer and resets the write position. * This is called when a RESET_VALUE diff is encountered. * * @example * ```ts * const buffer = new HistoryBuffer<string>(5) * buffer.pushEntry(0, 1, 'change') * buffer.clear() * console.log(buffer.getChangesSince(0)) // RESET_VALUE * ``` */ clear() { this.index = 0; this.buffer.fill(void 0); } /** * Retrieves all diffs that occurred since the specified epoch. * * The method searches backwards through the circular buffer to find changes * that occurred after the given epoch. If insufficient history is available * or the requested epoch is too old, returns RESET_VALUE indicating that * a complete state rebuild is required. * * @param sinceEpoch - The epoch from which to retrieve changes * @returns Array of diffs since the epoch, or RESET_VALUE if history is insufficient * @example * ```ts * const buffer = new HistoryBuffer<string>(5) * buffer.pushEntry(0, 1, 'first') * buffer.pushEntry(1, 2, 'second') * const changes = buffer.getChangesSince(0) // ['first', 'second'] * const recentChanges = buffer.getChangesSince(1) // ['second'] * const tooOld = buffer.getChangesSince(-100) // RESET_VALUE * ``` */ getChangesSince(sinceEpoch) { const { index, capacity, buffer } = this; for (let i = 0; i < capacity; i++) { const offset = (index - 1 + capacity - i) % capacity; const elem = buffer[offset]; if (!elem) { return import_types.RESET_VALUE; } const [fromEpoch, toEpoch] = elem; if (i === 0 && sinceEpoch >= toEpoch) { return []; } if (fromEpoch <= sinceEpoch && sinceEpoch < toEpoch) { const len = i + 1; const result = new Array(len); for (let j = 0; j < len; j++) { result[j] = buffer[(offset + j) % capacity][2]; } return result; } } return import_types.RESET_VALUE; } } //# sourceMappingURL=HistoryBuffer.js.map