Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 19 additions & 16 deletions src/lib/data-base.abstract.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,11 +52,12 @@ export abstract class DataBase<T> extends DataCore<T> {
public clear(): this {
const oldValue = this.value;
const newValue = null as unknown as T;
return this.#value = null as unknown as T,
// Invokes the onChange callback if `newValue` and `this.value` has changed.
(typeof this.onChangeCallback === 'function' && DataBase.hasChanged(oldValue, newValue)
? this.onChangeCallback(newValue, this.value) : newValue),
this;
this.#value = null as unknown as T;
// Invokes the onChange callback if `newValue` and `this.value` has changed.
if (typeof this.onChangeCallback === 'function' && DataBase.hasChanged(oldValue, newValue)) {
this.onChangeCallback(newValue, oldValue);
}
return this;
}

/**
Expand All @@ -80,17 +81,19 @@ export abstract class DataBase<T> extends DataCore<T> {
* @returns {this} The `this` current instance.
*/
public set(value: T): this {
super.validate();
const oldValue = this.value;
let newValue: T;
return super.validate(),
// Assigns the new value.
(newValue = typeof super.onSetCallback === 'function' ? super.onSetCallback(value) : value),
// Assigns the new value to the private value.
(this.#value = newValue),
// Invokes the onChange callback if `newValue` and `this.value` has changed.
(typeof this.onChangeCallback === 'function' && DataBase.hasChanged(oldValue, newValue)
? this.onChangeCallback(newValue, this.value) : newValue),
// Returns this instance.
this;
// Invoke onSet callback before setting the value.
if (typeof super.onSetCallback === 'function') {
super.onSetCallback(value);
}
// Assign the new value to the private value.
this.#value = value;
// Invokes the onChange callback if the value has changed.
if (typeof this.onChangeCallback === 'function' && DataBase.hasChanged(oldValue, value)) {
this.onChangeCallback(value, oldValue);
}
// Returns this instance.
return this;
}
}
85 changes: 4 additions & 81 deletions src/lib/data-core.abstract.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
// Abstract.
import { HooksBase } from './hooks-base.abstract';
import { Immutability } from './immutability.abstract';
// Interface.
import { DataShape } from '@typedly/data';
Expand All @@ -8,12 +9,12 @@ import { DataShape } from '@typedly/data';
* @abstract
* @class DataCore
* @template T Represents the type of data value.
* @extends {Immutability}
* @extends {HooksBase<T>}
* @implements {DataShape<T>}
*/
export abstract class DataCore<T>
// For immutability features.
extends Immutability
// For immutability and hooks features.
extends HooksBase<T>
// For data shape contract, to use instead of `DataCore`.
implements DataShape<T> {
/**
Expand Down Expand Up @@ -82,53 +83,7 @@ export abstract class DataCore<T>
*/
public abstract get value(): T;

/**
* @description Returns the onChange callback function.
* @protected
* @readonly
* @type {((value: T, oldValue: T) => T) | undefined}
*/
protected get onChangeCallback(): ((value: T, oldValue: T) => T) | undefined {
return this.#onChangeCallback;
}

/**
* @description Returns the onDestroy callback function.
* @protected
* @readonly
* @type {(() => void) | undefined}
*/
protected get onDestroyCallback(): (() => void) | undefined {
return this.#onDestroyCallback;
}

/**
* @description Returns the onSet callback function.
* @protected
* @readonly
* @type {((value: T) => T) | undefined}
*/
protected get onSetCallback(): ((value: T) => T) | undefined {
return this.#onSetCallback;
}

/**
* @description Privately stored onChange callback function, defaults `undefined`.
* @type {?(value: T, oldValue: T) => T}
*/
#onChangeCallback?: (value: T, oldValue: T) => T;

/**
* @description Privately stored onDestroy callback function, defaults `undefined`.
* @type {?() => void}
*/
#onDestroyCallback?: () => void;

/**
* @description Privately stored onSet callback function, defaults `undefined`.
* @type {?(value: T) => T}
*/
#onSetCallback?: (value: T) => T;

/**
* @description Clears the value by setting to `undefined` or `null`.
Expand Down Expand Up @@ -157,38 +112,6 @@ export abstract class DataCore<T>
this;
}

/**
* @description Sets the callback function invoked when the data value changes.
* @public
* @abstract
* @param {?(value: T, oldValue: T) => T} callbackfn The callback function to invoke.
* @returns {this} The `this` current instance.
*/
public onChange(callbackfn?: (value: T, oldValue: T) => T): this {
return this.#onChangeCallback = callbackfn, this;
}

/**
* @description Sets the callback function to be invoked when destroying the data instance.
* @public
* @param {?() => void} callbackfn
* @returns {this}
*/
public onDestroy(callbackfn?: () => void): this {
return this.#onDestroyCallback = callbackfn, this;
}

/**
* @description Sets the callback function to be invoked when setting the data value.
* @public
* @abstract
* @param {?(value: T) => T} callbackfn The callback function to invoke.
* @returns {this} The `this` current instance.
*/
public onSet(callbackfn?: (value: T) => T): this {
return this.#onSetCallback = callbackfn, this;
}

/**
* @description Sets the value of `T` in arbitrary parameter array.
* @public
Expand Down
64 changes: 64 additions & 0 deletions src/lib/hooks-base.abstract.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
// Abstract.
import { HooksCore } from './hooks-core.abstract';

/**
* @description Enhanced hooks system with property-specific change and set hooks.
* @export
* @abstract
* @class HooksBase
* @template T Represents the type of data value.
* @extends {HooksCore}
*/
export abstract class HooksBase<T> extends HooksCore {
/**
* @description Privately stored property-specific onChange callback function, defaults `undefined`.
* @type {?(value: T, oldValue: T) => void}
*/
#onChangeCallback?: (value: T, oldValue: T) => void;

/**
* @description Privately stored property-specific onSet callback function, defaults `undefined`.
* @type {?(value: T) => void}
*/
#onSetCallback?: (value: T) => void;

/**
* @description Returns the property-specific onChange callback function.
* @protected
* @readonly
* @type {((value: T, oldValue: T) => void) | undefined}
*/
protected get onChangeCallback(): ((value: T, oldValue: T) => void) | undefined {
return this.#onChangeCallback;
}

/**
* @description Returns the property-specific onSet callback function.
* @protected
* @readonly
* @type {((value: T) => void) | undefined}
*/
protected get onSetCallback(): ((value: T) => void) | undefined {
return this.#onSetCallback;
}

/**
* @description Sets the property-specific callback function invoked when the data value changes.
* @public
* @param {?(value: T, oldValue: T) => void} callbackfn The callback function to invoke.
* @returns {this} The `this` current instance.
*/
public onChange(callbackfn?: (value: T, oldValue: T) => void): this {
return this.#onChangeCallback = callbackfn, this;
}

/**
* @description Sets the property-specific callback function to be invoked when setting the data value.
* @public
* @param {?(value: T) => void} callbackfn The callback function to invoke.
* @returns {this} The `this` current instance.
*/
public onSet(callbackfn?: (value: T) => void): this {
return this.#onSetCallback = callbackfn, this;
}
}
37 changes: 37 additions & 0 deletions src/lib/hooks-core.abstract.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
// Abstract.
import { Immutability } from './immutability.abstract';

/**
* @description Core hooks system for managing callbacks.
* @export
* @abstract
* @class HooksCore
* @extends {Immutability}
*/
export abstract class HooksCore extends Immutability {
/**
* @description Privately stored onDestroy callback function, defaults `undefined`.
* @type {?() => void}
*/
#onDestroyCallback?: () => void;

/**
* @description Returns the onDestroy callback function.
* @protected
* @readonly
* @type {(() => void) | undefined}
*/
protected get onDestroyCallback(): (() => void) | undefined {
return this.#onDestroyCallback;
}

/**
* @description Sets the callback function to be invoked when destroying the data instance.
* @public
* @param {?() => void} callbackfn
* @returns {this}
*/
public onDestroy(callbackfn?: () => void): this {
return this.#onDestroyCallback = callbackfn, this;
}
}
2 changes: 2 additions & 0 deletions src/lib/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
// Abstract class.
export { DataCore } from './data-core.abstract';
export { HooksBase } from './hooks-base.abstract';
export { HooksCore } from './hooks-core.abstract';
export { Immutability } from './immutability.abstract';
// Class.
export { Data } from './data.class';
Expand Down
20 changes: 13 additions & 7 deletions src/lib/weak-data.class.ts
Original file line number Diff line number Diff line change
Expand Up @@ -144,13 +144,19 @@ export class WeakData<T> extends DataCore<T> {
* @returns {this} The `this` current instance.
*/
public set(value: T): this {
let newValue: T;
return super.validate(),
(newValue = super.onSetCallback ? super.onSetCallback(value) : value),
// Invokes the onChange callback if `newValue` and `this.value` has changed.
(this.onChangeCallback && DataCore.hasChanged(this.value, newValue) ? this.onChangeCallback(newValue, this.value) : newValue),
WeakData.#valueOf<T>().set(this, newValue),
this;
super.validate();
const oldValue = this.value;
// Invoke onSet callback before setting the value.
if (super.onSetCallback) {
super.onSetCallback(value);
}
// Set the new value.
WeakData.#valueOf<T>().set(this, value);
// Invokes the onChange callback if the value has changed.
if (this.onChangeCallback && DataCore.hasChanged(oldValue, value)) {
this.onChangeCallback(value, oldValue);
}
return this;
}

/**
Expand Down
2 changes: 2 additions & 0 deletions src/public-api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
export {
// Abstract.
DataCore,
HooksBase,
HooksCore,
Immutability,

// Class.
Expand Down
Loading