@exadel/esl
Version:
Exadel Smart Library (ESL) is the lightweight custom elements library that provide a set of super-flexible components
54 lines (53 loc) • 1.97 kB
JavaScript
/** Builds getter from provider */
function getter(provider) {
return function () {
return provider.call(this, this);
};
}
/** Builds own property setter */
function setter(name, readonly) {
if (readonly)
return () => void 0;
return function (value) {
Object.defineProperty(this, name, {
value,
writable: true,
configurable: true
});
};
}
/**
* `@prop` decorator: defines a prototype-level property (value or computed via provider) with optional flags.
* - Static value: defined on prototype (writable unless `readonly`)
* - Provider function: installed as getter; each access invokes provider with `(this)`; optional setter creates own value
* - Readonly: setter becomes no-op (provider case) or value made non-writable (static case)
* - Enumerable flag passed through
* - Throws if attempting to decorate an already own property on the prototype object
*
* @param value - static value or provider function producing the value per access
* @param prototypeConfig - configuration object with optional `readonly` and `enumerable` flags
*/
export function prop(value, prototypeConfig = {}) {
return function (obj, name) {
if (Object.hasOwnProperty.call(obj, name)) {
throw new TypeError('Can\'t override own property');
}
if (typeof value === 'function') {
Object.defineProperty(obj, name, {
get: getter(value),
set: setter(name, prototypeConfig.readonly),
enumerable: prototypeConfig.enumerable,
configurable: true
});
}
else {
Object.defineProperty(obj, name, {
value,
writable: !prototypeConfig.readonly,
enumerable: prototypeConfig.enumerable,
configurable: true
});
}
return { /* To make babel transpiler work */};
};
}