UNPKG

dreamstate

Version:

Store management library based on react context and observers

64 lines (61 loc) 2.46 kB
import { DreamstateError } from '../core/error/DreamstateError.js'; import { EDreamstateErrorCode } from '../types/error.js'; /** * Factory function that creates a bound method descriptor for a given method. * This ensures the method is bound to the instance, preserving the correct `this` context when invoked. * * @template T The type of the method being bound. * @param {TypedPropertyDescriptor<T>} from The original typed property descriptor of the method to bind. * @param {PropertyKey} property The property key of the method being modified. * @returns {PropertyDescriptor} A new property descriptor with the method bound to the instance. */ function createBoundDescriptor(from, property) { // Todo: Wait for autobind merge with fix of shared callbacks issue and other. var definingProperty = false; return { configurable: true, get: function () { if (definingProperty /* this === target.prototype || - will it fire? Check parent prototypes? Object.prototype.hasOwnProperty.call(this, property) || typeof from.value !== "function" */) { return from.value; } // Expect only functions to be called, throw errors on other cases. var bound = from.value.bind(this); definingProperty = true; Object.defineProperty(this, property, { configurable: true, writable: false, value: bound }); definingProperty = false; return bound; }, set: function () { throw new DreamstateError(EDreamstateErrorCode.RESTRICTED_OPERATION, "Direct runtime modification of bound method is not allowed."); } }; } /** * Decorator factory that modifies the method descriptor to bind the method to the prototype instance. * This ensures that the method retains the correct `this` context when invoked. * * All credits: 'https://www.npmjs.com/package/autobind-decorator'. * Modified to support proposal syntax. * * @returns {MethodDecorator} A method decorator that binds the method to the instance prototype. */ function Bind() { return function (targetOrDescriptor, propertyKey, descriptor) { // Different behaviour for legacy and proposal decorators. if (propertyKey && descriptor) { return createBoundDescriptor(descriptor, propertyKey); } else { targetOrDescriptor.descriptor = createBoundDescriptor(targetOrDescriptor.descriptor, targetOrDescriptor.key); } }; } export { Bind };