UNPKG

veil-objects

Version:

The JS/TS implementation of Veil objects approach from EO oriented programming

79 lines (71 loc) 2.05 kB
/** * Wraps a target object with provided presets object * and when trying to access the provided presets methods on the veil object * it passes them throuhg, until the veil object is pierced, meaning the use methods * not listed in the provided preset object */ class Veil { #pierced; #target; #presets; #targetProto; constructor( target, presets, ) { this.#pierced = false; this.#target = target; this.#presets = new Map(Object.entries(presets)); /** * Accept the target object methods only (no) */ this.#targetProto = Object.getPrototypeOf(this.#target); Object.getOwnPropertyNames(this.#targetProto).forEach( methodName => { if (typeof this.#target[methodName] === 'function' && methodName !== 'constructor') { this.#useTargetMethod(methodName); } } ); }; /** * If a target method satisfies - use it as a native Veil object method (caching). */ #useTargetMethod(methodName) { this[methodName] = (...args) => { return this.#acceptPresetMethodOrPierce(methodName, args); }; }; /** * Depending on a #pierced flag: * Either use the target presets data (not pierced) or invoke a target method (pierced). */ #acceptPresetMethodOrPierce(methodName, ...args) { if (!this.#pierced && this.#presets.has(methodName)) { return this.#presets.get(methodName); } if (!this.#pierced) { this.#pierce(); } return this.#applyTargetMethod(methodName, args) }; /** * Apply target method if the veil is pierced. */ #applyTargetMethod(methodName, ...args) { var targetMethod = this.#target[methodName]; return targetMethod.apply(this.#target, args); }; /** * Pierce the veil (drop a cache) to use a target method. */ #pierce() { this.#pierced = true; }; isTargetInstanceOf(obj) { return typeof obj === 'function' ? this.#target instanceof obj : Object.getPrototypeOf(obj) === this.#targetProto }; }; export default Veil;