@typescript-package/set
Version:
A lightweight TypeScript library for enhanced `set` management.
244 lines (235 loc) • 6.74 kB
JavaScript
import { Data, SymbolValue } from '@typescript-package/data';
/**
* @description Immutable version of `Set`.
* @export
* @class ImmutableSet
* @template Type
* @extends {Set<Readonly<Type>>}
*/
class ImmutableSet extends Set {
constructor(iterable) {
super(iterable);
this.add = (value) => this;
}
delete(value) { return false; }
clear() { return this; }
}
/**
* @description
* @export
* @abstract
* @class OnHook
* @template Value
* @template {DataCore<any>} DataType
*/
class SetOnHook {
/**
* @description Hook called when a value is added.
* @protected
* @param {Value} value The added value.
* @param {DataType} data The data holder.
*/
onAdd(value, data) { }
/**
* @description Hook called when the `Set` is cleared.
* @protected
* @param {DataType} data The data holder.
*/
onClear(data) { }
/**
* @description Hook called when a value is deleted.
* @protected
* @param {Value} value The deleted value.
* @param {boolean} success Whether the deletion was successful.
* @param {DataType} data The data holder.
*/
onDelete(value, success, data) { }
}
// Class.
/**
* @description The abstract core class for building customizable `Set` and `DataCore` related classes.
* @export
* @abstract
* @class CoreSet
* @template Type
* @template {Set<Type>} [SetType=Set<Type>]
* @template {DataCore<SetType>} [DataType=Data<SetType>]
* @extends {SetOnHook<Type, DataType>}
*/
class CoreSet extends SetOnHook {
/**
* @description Returns the `string` tag representation of the `CoreSet` class when used in `Object.prototype.toString.call(instance)`.
* @public
* @readonly
*/
get [Symbol.toStringTag]() {
return CoreSet.name;
}
/**
* @description The data instance used to hold the `Set` value, but omit direct access to it.
* @public
* @readonly
* @type {Omit<DataType, 'value'>}
*/
get data() {
return this.#data;
}
/**
* @description Returns the readonly `ImmutableSet` of `Type`.
* @public
* @readonly
* @type {ReadonlySet<Type>}
*/
get value() {
return new ImmutableSet(this.#data.value);
}
/**
* @inheritdoc
* @public
* @readonly
* @type {number}
*/
get size() {
return this.#data.value.size;
}
/**
* @description The `Set` data holder of `DataCore` type.
* @type {DataType}
*/
#data;
/**
* Creates an instance of `CoreSet` child class.
* @constructor
* @param {?Iterable<Type>} [iterable] Initial value for `Set`.
* @param {?SetTypeConstructor<Type, SetType>} [set] Custom `Set`.
* @param {?DataConstructorInput<SetType, DataType>} [data] Custom data holder of generic type variable `DataType` to store the `Set`.
*/
constructor(iterable, set, data) {
super();
this.#data = new (Array.isArray(data) ? data[0] : data ?? Data)(new (set || Set)(iterable));
}
/**
* @description Access to the readonly set by using a symbol.
* @public
* @returns {Readonly<SetType>}
*/
[SymbolValue]() {
return this.#data.value;
}
/**
* @description "Appends a new element with a specified value to the end of the `Set`."
* @public
* @param {Type} value
* @returns {this}
*/
add(value) {
this.#data.value.add(value);
this.onAdd(value, this.#data);
return this;
}
/**
* Clears all entries.
* @inheritdoc
* @public
* @returns {this}
*/
clear() {
this.#data.value.clear();
this.onClear(this.#data);
return this;
}
/**
* "Removes a specified value from the Set."
* @public
* @param {Type} value The value to delete.
* @returns {boolean} "Returns true if an element in the Set existed and has been removed, or false if the element does not exist."
*/
delete(value) {
const result = this.#data.value.delete(value);
return this.onDelete(value, result, this.#data), result;
}
/**
* @description "Returns an iterable of [v,v] pairs for every value v in the set."
* @public
* @returns {SetIterator<[Readonly<Type>, Readonly<Type>]>}
*/
entries() {
return this.#data.value.entries();
}
/**
* @description
* @public
* @param {(value: Readonly<Type>, value2: Readonly<Type>, set: Set<Readonly<Type>>) => void} callbackfn
* @param {?*} [thisArg]
* @returns {this}
*/
forEach(callbackfn, thisArg) {
this.#data.value.forEach(callbackfn, thisArg);
return this;
}
/**
* Checks if a value exists in the `Set`.
* @inheritdoc
* @public
* @param {Type} value The value to check.
* @returns {boolean} "a boolean indicating whether an element with the specified value exists in the Set or not."
*/
has(value) {
return this.#data.value.has(value);
}
/**
* "Despite its name, returns an iterable of the values in the set."
* @inheritdoc
* @public
* @returns {SetIterator<Readonly<Type>>}
*/
keys() {
return this.#data.value.keys();
}
/**
* "Returns an iterable of values in the set."
* @inheritdoc
* @public
* @returns {SetIterator<Readonly<Type>>}
*/
values() {
return this.#data.value.values();
}
}
// Abstract.
/**
* @description The `DataSet` is a concrete class that extends `CoreSet` and encapsulates its data within a `DataCore` store, providing additional data management capabilities.
* @export
* @class DataSet
* @template Type
* @template {DataCore<Set<Type>>} [DataType=Data<Set<Type>>]
* @extends {CoreSet<Type, Set<Type>, DataType>}
*/
class DataSet extends CoreSet {
/**
* @description Returns the `string` tag representation of the `DataSet` class when used in `Object.prototype.toString.call(instance)`.
* @public
* @readonly
*/
get [Symbol.toStringTag]() {
return DataSet.name;
}
/**
* Creates an instance of `DataSet`.
* @constructor
* @param {?Iterable<Type>} [iterable] Initial value for `Set`.
* @param {?DataConstructorInput<Set<Type>, DataType>} [data] Optional data instance of generic type variable `DataType` to store the `Set`.
*/
constructor(iterable, data) {
super(iterable, Set, data);
}
}
// Abstract.
/*
* Public API Surface of set
*/
/**
* Generated bundle index. Do not edit.
*/
export { CoreSet, DataSet, ImmutableSet, SetOnHook };
//# sourceMappingURL=typescript-package-set.mjs.map