@aedart/support
Version:
The Ion support package
385 lines (377 loc) • 9.64 kB
JavaScript
/**
* @aedart/support
*
* BSD-3-Clause, Copyright (c) 2023-present Alin Eugen Deac <aedart@gmail.com>.
*/
'use strict';
var concerns = require('@aedart/support/concerns');
var objects = require('@aedart/support/objects');
var tslib = require('tslib');
/**
* Concerns Arbitrary Data
*
* @see HasArbitraryData
*
* @mixin
* @extends AbstractConcern
*/
class ArbitraryData extends concerns.AbstractConcern {
/**
* The arbitrary data record
*
* @type {Record<PropertyKey, any>}
*
* @protected
*/
_data = {}; /* eslint-disable-line @typescript-eslint/no-explicit-any */
/**
* Set value for key
*
* @param {Key} key
* @param {any} value
*
* @return {this}
*/
set(key, value) {
objects.set(this._data, key, value);
return this.concernOwner;
}
/**
* Get value for key, or default if key does not exist
*
* @template T
* @template D=undefined
*
* @param {Key} key
* @param {D} [defaultValue]
*
* @return {T | D}
*/
get(key, defaultValue) {
return objects.get(this._data, key, defaultValue);
}
/**
* Determine if value exists for key
*
* @param {Key} key
*
* @return {boolean}
*/
has(key) {
return objects.has(this._data, key);
}
/**
* Delete value for key
*
* @param {Key} key
*
* @return {boolean}
*/
forget(key) {
return objects.forget(this._data, key);
}
/**
* Returns all arbitrary data
*
* @return {Record<PropertyKey, any>}
*/
all() {
// Returns a copy of the arbitrary data record
return objects.merge(this._data);
}
/**
* Flush all arbitrary data
*
* @return {void}
*/
flush() {
this._data = {};
}
}
let CallbackWrapper = (() => {
let _classDecorators = [concerns.use(ArbitraryData)];
let _classDescriptor;
let _classExtraInitializers = [];
let _classThis;
(class {
static { _classThis = this; }
static {
const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(null) : void 0;
tslib.__esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
_classThis = _classDescriptor.value;
if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
tslib.__runInitializers(_classThis, _classExtraInitializers);
}
/**
* Alias for {@link ArbitraryData#set}
*
* @function set
* @param {Key} key
* @param {any} value
* @return {this}
*
* @instance
* @memberof CallbackWrapper
*/
/**
* Alias for {@link ArbitraryData#get}
*
* @function get
*
* @template T
* @template D=undefined
*
* @param {Key} key
* @param {D} [defaultValue]
* @return {this}
*
* @instance
* @memberof CallbackWrapper
*/
/**
* Alias for {@link ArbitraryData#has}
*
* @function has
* @param {Key} key
* @return {boolean}
*
* @instance
* @memberof CallbackWrapper
*/
/**
* Alias for {@link ArbitraryData#forget}
*
* @function forget
* @param {Key} key
* @return {boolean}
*
* @instance
* @memberof CallbackWrapper
*/
/**
* Alias for {@link ArbitraryData#all}
*
* @function all
* @return {Record<PropertyKey, any>}
*
* @instance
* @memberof CallbackWrapper
*/
/**
* Alias for {@link ArbitraryData#flush}
*
* @function flush
* @return {void}
*
* @instance
* @memberof CallbackWrapper
*/
/**
* The callback
*
* @type {Callback}
*
* @protected
* @readonly
*/
_callback;
/**
* "This" value that callback is bound to
*
* @type {object | undefined}
*
* @readonly
* @protected
*/
_binding = undefined;
/**
* Arguments to be passed on to the callback
* when invoked.
*
* @type {any[]}
*
* @protected
*/
_arguments = []; /* eslint-disable-line @typescript-eslint/no-explicit-any */
/**
* Create a new Callback Wrapper instance
*
* @param {Callback} callback
* @param {...any} [args]
*
* @throws {TypeError}
*/
constructor(callback, ...args /* eslint-disable-line @typescript-eslint/no-explicit-any */) {
if (typeof callback != 'function') {
throw new TypeError('Argument must be a valid callable function');
}
this._callback = callback;
this.with(...args);
}
/**
* Create a new Callback Wrapper instance
*
* @param {Callback} callback
* @param {...any} [args]
*
* @return {this|CallbackWrapper}
*
* @throws {TypeError}
*/
static make(callback, ...args /* eslint-disable-line @typescript-eslint/no-explicit-any */) {
return new this(callback, ...args);
}
/**
* Create a new Callback Wrapper instance, using given binding
*
* @param {object} thisArg Binding
* @param {Callback} callback
* @param {...any} [args]
*
* @return {this|CallbackWrapper}
*
* @throws {TypeError}
*/
static makeFor(thisArg, callback, ...args /* eslint-disable-line @typescript-eslint/no-explicit-any */) {
return this.make(callback, ...args).bind(thisArg);
}
/**
* The callback
*
* @type {Callback}
*
* @readonly
*/
get callback() {
return this._callback;
}
/**
* "This" value that callback is bound to
*
* @type {object | undefined}
*
* @readonly
*/
get binding() {
return this._binding;
}
/**
* Arguments to be passed on to the callback
* when invoked.
*
* @param {any[]} args
*/
set arguments(args) {
this._arguments = args;
}
/**
* Arguments to be passed on to the callback
* when invoked.
*
* @return {any[]}
*/
get arguments() {
return this._arguments;
}
/**
* Add arguments to be passed on to the callback
* when it is invoked.
*
* @param {...any} args
*
* @return {this}
*/
with(...args) {
this.arguments = this.arguments.concat(...args);
return this;
}
/**
* Determine if callback has any arguments
*
* @return {boolean}
*/
hasArguments() {
return this.arguments.length !== 0;
}
/**
* Bind callback to given "this" value
*
* @param {object} thisArg
*
* @return {this}
*
* @throws {TypeError}
*/
bind(thisArg) {
this._binding = thisArg;
return this;
}
/**
* Determine if a binding has been set
*
* @return {boolean}
*/
hasBinding() {
return this.binding !== undefined && this.binding !== null;
}
/**
* Invoke the callback
*
* @return {any}
*
* @throws {Error}
*/
call() {
const callback = this.callback;
if (this.hasBinding()) {
return callback.call(this.binding, ...this.arguments);
}
return callback(...this.arguments);
}
});
return _classThis;
})();
/**
* Determine if given value is a [CallbackWrapper]{@link import('@aedart/contracts/support').CallbackWrapper}
*
* @param {unknown} value
*
* @return {boolean}
*/
function isCallbackWrapper(value) {
if (!value || typeof value != 'object') {
return false;
}
if (value instanceof CallbackWrapper) {
return true;
}
// Determine if value "looks like" a callback wrapper object
const blueprint = [
'callback',
'binding',
'arguments',
'with',
'hasArguments',
'bind',
'hasBinding',
'call'
];
for (const property of blueprint) {
if (!Reflect.has(value, property)) {
return false;
}
}
return true;
}
/**
* Support identifier
*
* @type {Symbol}
*/
const SUPPORT = Symbol('@aedart/support');
exports.ArbitraryData = ArbitraryData;
exports.CallbackWrapper = CallbackWrapper;
exports.SUPPORT = SUPPORT;
exports.isCallbackWrapper = isCallbackWrapper;
module.exports = Object.assign(exports.default, exports);
//# sourceMappingURL=support.cjs.map