@typescript-package/history
Version:
A lightweight TypeScript package for tracking the history of values.
1,025 lines (1,011 loc) • 30.9 kB
JavaScript
import { Data } from '@typescript-package/data';
/**
* @description The history storage of specified data.
* @export
* @abstract
* @class HistoryStorage
* @template Value
* @template {DataCore<readonly Value[]>} [DataType=Data<readonly Value[]>]
*/
class HistoryStorage {
/**
* @description Returns the `string` tag representation of the `HistoryStorage` class when used in `Object.prototype.toString.call(instance)`.
* @public
* @readonly
* @type {string}
*/
get [Symbol.toStringTag]() {
return HistoryStorage.name;
}
/**
* @description Returns the data holder of `DataType`.
* @public
* @readonly
* @type {DataType}
*/
get data() {
return this.#data;
}
/**
* @description The length of the history.
* @public
* @readonly
* @type {number}
*/
get length() {
return this.#data.value.length;
}
/**
* @description The data type to store the value.
* @type {DataType}
*/
#data;
/**
* Creates an instance of `HistoryStorage` child class.
* @constructor
* @param {readonly Value[]} value The initial array.
* @param {?DataConstructorInput<readonly Value[], DataType>} [data] Custom data holder, optionally with params.
*/
constructor(value, data) {
this.#data = new (Array.isArray(data) ? data[0] : data ?? Data)(value, ...Array.isArray(data) ? data.slice(1) : []);
}
/**
* @description Destroys the storage data, by default setting it to `null`.
* @public
* @returns {this} The `this` current instance.
*/
destroy() {
this.#data.destroy();
return this;
}
/**
* @description Gets the readonly history.
* @public
* @returns {readonly Value[]}
*/
get() {
return this.#data.value;
}
/**
* @description Checks whether the storage is empty.
* @public
* @returns {boolean}
*/
isEmpty() {
return this.#data.value.length === 0;
}
/**
* @description Sets the data value.
* @protected
* @param {readonly Value[]} value The data value of `Value[]` to set.
* @returns {this} The `this` current instance.
*/
set(value) {
this.#data.set(value);
return this;
}
}
// Abstract.
/**
* @description The core class for history append and prepend.
* @export
* @abstract
* @class HistoryCore
* @template Value
* @template {number} [Size=number]
* @template {DataCore<readonly Value[]>} [DataType=Data<readonly Value[]>]
* @extends {HistoryStorage<Value, DataType>}
*/
class HistoryCore extends HistoryStorage {
/**
* @description Returns the `string` tag representation of the `HistoryCore` class when used in `Object.prototype.toString.call(instance)`.
* @public
* @readonly
* @type {string}
*/
get [Symbol.toStringTag]() {
return HistoryCore.name;
}
/**
* @description Gets the history.
* @protected
* @readonly
* @type {readonly Value[]}
*/
get history() {
return super.data.value;
}
/**
* @description The maximum size of the history.
* @public
* @readonly
* @type {Size}
*/
get size() {
return this.#size;
}
/**
* @description The maximum size of the history.
* @type {Size}
*/
#size;
/**
* Creates an instance of `HistoryCore` child class.
* @constructor
* @param {Size} size The maximum undo history size.
* @param {?DataConstructorInput<readonly Value[], DataType>} [data] Custom data holder.
*/
constructor(size, data) {
super([], data);
this.#size = size;
}
/**
* @description Returns the value at the specified index in the history.
* @public
* @param {number} index The position in the history (0-based index).
* @returns {Value | undefined} The value at the specified position.
*/
at(index) {
return this.history[index];
}
/**
* @description Clears the history.
* @public
* @returns {this} The `this` current instance.
*/
clear() {
super.set([]);
return this;
}
/**
* @description Returns the first value without modifying history.
* @public
* @abstract
* @returns {(Value | undefined)}
*/
first() {
return this.history[0];
}
/**
* @description Returns the last value without modifying history.
* @public
* @abstract
* @returns {(Value | undefined)}
*/
last() {
return this.history.at(-1);
}
/**
* @description Sets the size for history.
* @public
* @param {Size} size The maximum size of `Size`.
* @returns {this} The `this` current instance.
*/
setSize(size) {
this.#size = size;
return this;
}
//#endregion
//#region protected method
/**
* @description "Removes the last element from an array and returns it. If the array is empty, undefined is returned and the array is not modified."
* @protected
* @returns {this} The `this` current instance.
*/
pop() {
const history = [...this.history];
if (Array.isArray(history) && history.length > 0) {
const last = history.pop();
this.set(history);
return last;
}
return undefined;
}
/**
* @description "Appends new elements to the end of an array, and returns the new length of the array."
* @protected
* @param {...readonly Value[]} items The items to append.
* @returns {number} The new length.
*/
push(...items) {
const history = [...this.history];
const length = history.push(...items);
return (this.set(history), length);
}
/**
* @description "Removes the first element from an array and returns it. If the array is empty, undefined is returned and the array is not modified."
* @protected
* @returns {this} The `this` current instance.
*/
shift() {
const history = [...this.history];
if (Array.isArray(history) && history.length > 0) {
const first = history.shift();
this.set(history);
return first;
}
return undefined;
}
/**
* @description The method to trim the history.
* @protected
* @param {('pop' | 'shift')} method The method `pop` or `shift` to trim the history.
* @returns {this} The `this` current instance.
*/
trim(method) {
if (this.#size > 0) {
while (this.history.length > this.size) {
method === 'pop' ? this.pop() : method === 'shift' && this.shift();
}
}
return this;
}
/**
* @description "Inserts new elements at the start of an array, and returns the new length of the array."
* @protected
* @param {...readonly Value[]} items The items to insert.
* @returns {number} The new length.
*/
unshift(...items) {
const history = [...this.history];
const length = history.unshift(...items);
return (this.set(history), length);
}
}
// Abstract.
/**
* @description Class extends the `HistoryCore` class to maintain a history of values in a append manner.
* This means that new entries are added to the end of the history, and as the history exceeds its size limit, entries from the beginning are removed.
* LIFO(Last in, First out): The last value that was added (the most recent one) will be the first one to be removed.
* Add: Add to the end of the array (push).
* Take: Remove from the end of the array (pop), which is the most recent item.
* PeekFirst: Look at the first item in the history (oldest).
* PeekLast: Look at the last item in the history (newest).
* @export
* @abstract
* @class HistoryAppend
* @template Value
* @template {number} [Size=number]
* @template {DataCore<readonly Value[]>} [DataType=Data<readonly Value[]>]
* @extends {HistoryCore<Value, Size, DataType>}
*/
class HistoryAppend extends HistoryCore {
/**
* @description The default value of maximum history size.
* @public
* @static
* @type {number}
*/
static size = 10;
/**
* @description Returns the `string` tag representation of the `HistoryAppend` class when used in `Object.prototype.toString.call(instance)`.
* @public
* @readonly
* @type {string}
*/
get [Symbol.toStringTag]() {
return HistoryAppend.name;
}
/**
* Creates an instance of `HistoryAppend` child class.
* @constructor
* @param {Size} [size=HistoryAppend.size as Size] The maximum history size.
* @param {?readonly Value[]} [initialValue] Initial value to add.
* @param {?DataConstructorInput<readonly Value[], DataType>} [data] Custom data holder.
*/
constructor(size = HistoryAppend.size, initialValue, data) {
super(size, data);
Array.isArray(initialValue) && initialValue.forEach(value => this.add(value));
}
/**
* @description Adds the value to the history.
* - FIFO unshift/queue style
* @public
* @param {Value} value The value to store.
* @returns {this} The `this` current instance.
*/
add(value) {
if (super.size > 0) {
super.push(value);
super.trim('shift');
}
return this;
}
/**
* @description Returns the most recent (last index added) value in the history without modifying it.
* @public
* @returns {(Value | undefined)}
*/
newest() {
return super.last();
}
/**
* @description Returns the next value that would be removed (the most recent one) without modifying history.
* - LIFO behavior
* @public
* @returns {(Value | undefined)} The next value in the append manner.
*/
next() {
return super.last();
}
/**
* @description Returns the first(index 0 the oldest) value in the history without modifying it.
* @public
* @returns {(Value | undefined)}
*/
oldest() {
return super.first();
}
/**
* @description Removes and returns the last value in the history.
* - LIFO behavior
* @public
* @returns {(Value | undefined)}
*/
take() {
return super.pop();
}
}
// Abstract.
/**
* @description The class represents the current value of the history.
* The class is used to:
* - store the current value of the history,
* - check whether the current value is set,
* - update the current value of the history,
* - clear the current value of the history,
* - get the current value of the history.
* @export
* @abstract
* @class HistoryCurrent
* @template Value
* @template {DataCore<readonly Value[]>} [DataType=Data<readonly Value[]>]
* @extends {HistoryStorage<Value, DataType>}
*/
class HistoryCurrent extends HistoryStorage {
/**
* @description Returns the `string` tag representation of the `HistoryCurrent` class when used in `Object.prototype.toString.call(instance)`.
* @public
* @readonly
* @type {string}
*/
get [Symbol.toStringTag]() {
return HistoryCurrent.name;
}
/**
* Creates an instance of `HistoryCurrent` child class.
* @constructor
* @param {{value?: Value}} [param0={}]
* @param {Value} param0.value
* @param {?DataConstructor<readonly Value[], DataType>} [data]
*/
constructor({ value } = {}, data) {
super(Object.hasOwn(arguments[0] || {}, 'value') ? [value] : [], data);
}
/**
* @description Clears the `current` history.
* @public
* @returns {this} The current instance.
*/
clear() {
super.set([]);
return this;
}
}
// Abstract.
/**
* @description Class extends the `HistoryCore` class to maintain a history of values in a prepend manner.
* This means that new entries are added to the beginning of the history, and older entries are shifted out as the history size exceeds its limit.
* LIFO(Last in, First out): The last value that was added (the most recent one) will be the first one to be removed.
* Add: Add to the beginning of the array (unshift).
* Take: Remove from the beginning of the array (shift), which is the most recent item.
* PeekFirst: Look at the first item in the history (newest).
* PeekLast: Look at the last item in the history (oldest).
* @export
* @abstract
* @class HistoryPrepend
* @template Value
* @template {number} [Size=number]
* @template {DataCore<readonly Value[]>} [DataType=Data<readonly Value[]>]
* @extends {HistoryCore<Value, Size, DataType>}
*/
class HistoryPrepend extends HistoryCore {
/**
* @description The default value of maximum history size.
* @public
* @static
* @type {number}
*/
static size = 10;
/**
* @description Returns the `string` tag representation of the `HistoryPrepend` class when used in `Object.prototype.toString.call(instance)`.
* @public
* @readonly
* @type {string}
*/
get [Symbol.toStringTag]() {
return HistoryPrepend.name;
}
/**
* Creates an instance of `HistoryPrepend` child class.
* @constructor
* @param {Size} [size=HistoryPrepend.size as Size] The maximum history size.
* @param {?readonly Value[]} [initialValue] Initial value to add.
* @param {?DataConstructorInput<readonly Value[], DataType>} [data] Custom data holder.
*/
constructor(size = HistoryPrepend.size, initialValue, data) {
super(size, data);
Array.isArray(initialValue) && initialValue.forEach(value => this.add(value));
}
/**
* @description Adds the value to the history in a backward manner.
* @public
* @param {Value} value The value to store.
* @returns {this} The `this` current instance.
*/
add(value) {
if (super.size > 0) {
super.unshift(value);
super.trim('pop');
}
return this;
}
/**
* @description Returns the next(index 0) value in the history, the newest value without modifying history.
* @public
* @returns {Value | undefined} The next redo value.
*/
next() {
return super.first();
}
/**
* @description Returns the most recent(first index 0) value in the history without modifying it.
* @public
* @returns {(Value | undefined)}
*/
newest() {
return super.first();
}
/**
* @description Returns the last value in the history, the oldest value without modifying history.
* @public
* @returns {Value | undefined} The next redo value.
*/
oldest() {
return super.last();
}
/**
* @description Removes and returns the first value in the history.
* @public
* @returns {(Value | undefined)}
*/
take() {
return super.shift();
}
}
// Abstract.
/**
* @description
* @export
* @class CurrentHistory
* @template Value
* @template {DataCore<readonly Value[]>} [DataType=Data<readonly Value[]>]
* @extends {HistoryCurrent<Value, DataType>}
*/
class CurrentHistory extends HistoryCurrent {
/**
* @description Returns the `string` tag representation of the `CurrentHistory` class when used in `Object.prototype.toString.call(instance)`.
* @public
* @readonly
* @type {string}
*/
get [Symbol.toStringTag]() {
return CurrentHistory.name;
}
/**
* @description The current history value.
* @public
* @readonly
* @type {Value}
*/
get value() {
return Array.isArray(super.data.value) ? super.data.value[0] : undefined;
}
/**
* Creates an instance of `CurrentHistory`.
* @constructor
* @param {{value?: Value}} [param0={}] THe object with current `value`.
* @param {Value} param0.value The current value inside the object.
* @param {?DataConstructorInput<Value, DataType>} [data] Custom data holder.
*/
constructor({ value } = {}, data) {
super(arguments[0], data);
}
/**
* @description Destroys the history of this instance.
* @public
* @returns {this} The `this` current instance.
*/
destroy() {
super.clear();
super.destroy();
return this;
}
/**
* @description Checks whether the current value is set.
* @public
* @returns {boolean} Indicates whether instance has set the current value.
*/
has() {
return Array.isArray(super.data.value) && super.data.value.length > 0;
}
/**
* @description Updates a current value.
* @public
* @param {Value} value The current value.
* @returns {this} The `this` current instance.
*/
update(value) {
super.set([value]);
return this;
}
}
/**
* @description The base abstract class to manage history.
* @export
* @abstract
* @class HistoryBase
* @template Value
* @template {number} [Size=number]
* @template {DataCore<readonly Value[]>} [DataType=Data<readonly Value[]>]
*/
class HistoryBase {
/**
* @description The max size for undo history.
* @public
* @static
* @type {number}
*/
static size = Infinity;
/**
* @description Returns the `string` tag representation of the `HistoryBase` class when used in `Object.prototype.toString.call(instance)`.
* @public
* @readonly
* @type {string}
*/
get [Symbol.toStringTag]() {
return HistoryBase.name;
}
/**
* @description Gets the current value stored in history.
* @public
* @readonly
* @type {Value}
*/
get current() {
return this.#current.value;
}
/**
* @description Returns the current history of `CurrentHistory`.
* @public
* @readonly
* @type {CurrentType}
*/
get currentHistory() {
return this.#current;
}
/**
* @description
* @public
* @readonly
* @type {{
* current: DataType,
* redo: DataType,
* undo: DataType
* }}
*/
get data() {
return {
current: this.#current.data,
redo: this.#redo.data,
undo: this.#undo.data,
};
}
/**
* @description Returns the redo history.
* @public
* @readonly
* @type {RedoType}
*/
get redoHistory() {
return this.#redo;
}
/**
* @description Returns the undo history.
* @public
* @readonly
* @type {UndoType}
*/
get undoHistory() {
return this.#undo;
}
/**
* @description A private field to store the current value.
* @type {CurrentType}
*/
#current;
/**
* @description Privately stored callback function invoked on redo.
* @type {(value: Value) => void}
*/
#onRedoCallback;
/**
* @description Privately stored callback function invoked on undo.
* @type {(value: Value) => void}
*/
#onUndoCallback;
/**
* @description The class to manage the redo history.
* @type {RedoType}
*/
#redo;
/**
* @description The class to manage the undo history.
* @type {UndoType}
*/
#undo;
/**
* Creates an instance of `HistoryBase` child class.
* @constructor
* @param {{ value?: Value, size?: Size}} [param0={}]
* @param {Value} param0.value
* @param {Size} param0.size
* @param {?DataConstructorInput<readonly Value[], DataType>} [data]
* @param {{
* current?: HistoryCurrentConstructor<Value, DataType, CurrentType>,
* redo?: HistoryCoreConstructor<Value, Size, DataType, RedoType>,
* undo?: HistoryCoreConstructor<Value, Size, DataType, UndoType>,
* }} [param1={}]
* @param {HistoryCurrentConstructor<Value, DataType, CurrentType>} param1.current
* @param {HistoryCoreConstructor<Value, Size, DataType, RedoType>} param1.redo
* @param {HistoryCoreConstructor<Value, Size, DataType, UndoType>} param1.undo
*/
constructor({ value, size } = {}, data, { current, redo, undo } = {}) {
this.#current = new (current)(arguments[0], data);
this.#redo = new (redo)(size, undefined, data);
this.#undo = new (undo)(size, undefined, data);
}
/**
* @description Clears the `current`, `undo` and `redo` history.
* @public
* @returns {this} The `this` current instance.
*/
clear() {
this.#current.clear();
this.#redo.clear();
this.#undo.clear();
return this;
}
/**
* @description Destroys the history of this instance.
* @public
* @returns {this} The `this` current instance.
*/
destroy() {
this.clear();
this.#current.destroy();
this.#redo.destroy();
this.#undo.destroy();
return this;
}
//#region get
/**
* @description Gets the current, undo and redo history.
* @public
* @returns {{ current: Readonly<Value>, undo: ImmutableArray<Value>; redo: ImmutableArray<Value> }}
*/
get() {
return {
current: this.#current.value,
undo: this.#undo.get(),
redo: this.#redo.get(),
};
}
/**
* @description The instance method returns read-only redo history.
* @public
* @template Type
* @returns {(ImmutableArray<Value>)}
*/
getRedo() {
return this.#redo.get();
}
/**
* @description The instance method returns read-only undo history.
* @public
* @template Type
* @returns {(ImmutableArray<Value>)}
*/
getUndo() {
return this.#undo.get();
}
//#endregion
/**
* @description Checks whether the current value is set.
* @public
* @returns {boolean}
*/
hasCurrent() {
return this.#current.has();
}
/**
* @description Checks whether the history is enabled by checking undo size.
* @public
* @returns {boolean}
*/
isEnabled() {
return this.#undo.size > 0 === true;
}
//#region on
/**
* @description Sets the callback function invoked on redo.
* @public
* @param {(value: Value) => void} callbackFn The callback function to invoke.
* @returns {this}
*/
onRedo(callbackFn) {
this.#onRedoCallback = callbackFn;
return this;
}
/**
* @description Sets the callback function invoked on undo.
* @public
* @param {(value: Value) => void} callbackFn The callback function to invoke.
* @returns {this}
*/
onUndo(callbackFn) {
this.#onUndoCallback = callbackFn;
return this;
}
//#endregion
/**
* @description Returns the specified by index value from redo history.
* @public
* @param {number} [index=0]
* @returns {(Value | undefined)}
*/
redoAt(index = 0) {
return this.#redo.at(index);
}
/**
* @description Returns the specified by index value from undo history.
* @public
* @param {number} [index=this.#undo.length - 1]
* @returns {(Value | undefined)}
*/
undoAt(index = this.#undo.length - 1) {
return this.#undo.at(index);
}
//#region first
/**
* @description Returns the first value that would be redone without modifying history.
* @public
* @returns {Value | undefined} The first redo value.
*/
firstRedo() {
return this.#redo.first();
}
/**
* @description Returns the first value that would be undone without modifying history.
* @public
* @returns {Value | undefined} The first undo value.
*/
firstUndo() {
return this.#undo.first();
}
//#endregion
//#region last
/**
* @description Returns the last value that would be redone without modifying history.
* @public
* @returns {Value | undefined} The last redo value.
*/
lastRedo() {
return this.#redo.last();
}
/**
* @description Returns the last value that would be undone without modifying history.
* @public
* @returns {Value | undefined} The last undo value.
*/
lastUndo() {
return this.#undo.last();
}
//#endregion
//#region next
/**
* @description Returns the next value that would be redone without modifying history.
* @public
* @returns {Value | undefined} The next redo value.
*/
nextRedo() {
return this.#redo.next();
}
/**
* @description Returns the next value that would be undone without modifying history.
* @public
* @returns {Value | undefined} The next undo value.
*/
nextUndo() {
return this.#undo.next();
}
//#endregion
/**
* @description Pick the current, redo or undo history.
* @public
* @param {('current' | 'redo' | 'undo')} type
* @returns {ImmutableArray<Value>}
*/
pick(type) {
switch (type) {
case 'current': return this.#current.get();
case 'redo': return this.#redo.get();
case 'undo': return this.#undo.get();
default: throw new Error(`Invalid type: ${type}. Expected 'current', 'redo', or 'undo'.`);
}
}
/**
* @description Redoes the last undone action.
* @public
* @returns {this} The current instance.
*/
redo() {
const redo = this.#redo;
if (redo.get()?.length) {
const value = redo.take();
this.#undo.add(this.#current.value);
this.#current.update(value);
this.#onRedoCallback?.(value);
}
return this;
}
/**
* @description Sets a new value and updates the undo history.
* @public
* @param {Value} value
* @returns {this} The `this` current instance.
*/
set(value) {
this.#current.has() && this.#undo.add(this.#current.value);
this.#current.update(value);
this.#redo.clear();
return this;
}
/**
* @description Sets the size of undo history.
* @public
* @param {Size} size The maximum size for undo history.
*/
setSize(size) {
this.#undo.setSize(size);
return this;
}
/**
* @description Undoes the last action and moves it to redo history.
* @public
* @returns {this} The current instance.
*/
undo() {
const undo = this.#undo;
if (undo.get()?.length) {
const value = undo.take();
this.#redo.add(this.#current.value);
this.#current.update(value);
this.#onUndoCallback?.(value);
}
return this;
}
}
// Abstract.
/**
* @description Manages the redo history with prepend mechanism.
* @export
* @class RedoHistory
* @template [Value=any] The type of elements stored in the history
* @template {number} [Size=number] The maximum size of the history.
* @template {DataCore<readonly Value[]>} [DataType=Data<readonly Value[]>]
* @extends {HistoryPrepend<Value, Size, DataType>}
*/
class RedoHistory extends HistoryPrepend {
/**
* Creates an instance of `RedoHistory`.
* @constructor
* @param {Size} [size=RedoHistory.size as Size]
* @param {?readonly [Value]} [initialValue]
* @param {?DataConstructorInput<readonly Value[], DataType>} [data]
*/
constructor(size = RedoHistory.size, initialValue, data) {
super(size, initialValue, data);
}
}
// Abstract.
/**
* @description Manages the undo history with append mechanism.
* @export
* @class UndoHistory
* @template [Value=any] The type of elements stored in the history.
* @template {number} [Size=number] The maximum size of the history.
* @template {DataCore<readonly Value[]>} [DataType=Data<readonly Value[]>]
* @extends {HistoryAppend<Value, Size, DataType>}
*/
class UndoHistory extends HistoryAppend {
/**
* Creates an instance of `UndoHistory`.
* @constructor
* @param {Size} [size=HistoryAppend.size as Size]
* @param {?readonly [Value]} [initialValue]
* @param {?DataConstructorInput<readonly Value[], DataType>} [data]
*/
constructor(size = HistoryAppend.size, initialValue, data) {
super(size, initialValue, data);
}
}
// Abstract.
/**
* @description The class to manage the value changes.
* @export
* @class History
* @template Value
* @template {number} [Size=number]
* @template {DataCore<readonly Value[]>} [DataType=Data<readonly Value[]>]
*/
class History extends HistoryBase {
/**
* @description The max size for undo history.
* @public
* @static
* @type {number}
*/
static size = Infinity;
/**
* @description Returns the `string` tag representation of the `History` class when used in `Object.prototype.toString.call(instance)`.
* @public
* @readonly
* @type {string}
*/
get [Symbol.toStringTag]() {
return History.name;
}
/**
* Creates an instance of `History`.
* @constructor
* @param {{ value?: Value, size?: Size}} [param0={}] The optional `value` and maximum undo history `size`.
* @param {Value} param0.value The initial value.
* @param {Size} param0.size The maximum undo history size.
* @param {?DataConstructorInput<readonly Value[], DataType>} [data] The custom data holder for history, current, undo and redo.
* @param {{
* current?: HistoryCurrentConstructor<Value, DataType, CurrentType>,
* redo?: HistoryCoreConstructor<Value, Size, DataType, RedoType>,
* undo?: HistoryCoreConstructor<Value, Size, DataType, UndoType>,
* }} [param1={}]
* @param {HistoryCurrentConstructor<Value, DataType, CurrentType>} param1.current Custom current history class of `HistoryCurrent`.
* @param {HistoryCoreConstructor<Value, Size, DataType, RedoType>} param1.redo Custom redo history class of `HistoryCore`.
* @param {HistoryCoreConstructor<Value, Size, DataType, UndoType>} param1.undo Custom undo history class of `HistoryCore`.
*/
constructor({ value, size } = {}, data, { current, redo, undo } = {}) {
super(arguments[0], data, {
current: current ?? CurrentHistory,
redo: redo ?? RedoHistory,
undo: undo ?? UndoHistory
});
}
}
/*
* Public API Surface of history
*/
// Main.
/**
* Generated bundle index. Do not edit.
*/
export { CurrentHistory, History, HistoryAppend, HistoryBase, HistoryCore, HistoryCurrent, HistoryPrepend, HistoryStorage, RedoHistory, UndoHistory };
//# sourceMappingURL=typescript-package-history.mjs.map