dreamstate
Version:
Store management library based on react context and observers
64 lines (61 loc) • 2.46 kB
JavaScript
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 };