This commit is contained in:
Lukian LEIZOUR 2023-01-29 00:57:47 +01:00
parent a15c733e45
commit 2a5130cbda
2838 changed files with 288613 additions and 0 deletions

116
node_modules/ts-mixer/dist/cjs/decorator.js generated vendored Normal file
View file

@ -0,0 +1,116 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.decorate = exports.getDecoratorsForClass = exports.directDecoratorSearch = exports.deepDecoratorSearch = void 0;
const util_1 = require("./util");
const mixin_tracking_1 = require("./mixin-tracking");
const mergeObjectsOfDecorators = (o1, o2) => {
var _a, _b;
const allKeys = util_1.unique([...Object.getOwnPropertyNames(o1), ...Object.getOwnPropertyNames(o2)]);
const mergedObject = {};
for (let key of allKeys)
mergedObject[key] = util_1.unique([...((_a = o1 === null || o1 === void 0 ? void 0 : o1[key]) !== null && _a !== void 0 ? _a : []), ...((_b = o2 === null || o2 === void 0 ? void 0 : o2[key]) !== null && _b !== void 0 ? _b : [])]);
return mergedObject;
};
const mergePropertyAndMethodDecorators = (d1, d2) => {
var _a, _b, _c, _d;
return ({
property: mergeObjectsOfDecorators((_a = d1 === null || d1 === void 0 ? void 0 : d1.property) !== null && _a !== void 0 ? _a : {}, (_b = d2 === null || d2 === void 0 ? void 0 : d2.property) !== null && _b !== void 0 ? _b : {}),
method: mergeObjectsOfDecorators((_c = d1 === null || d1 === void 0 ? void 0 : d1.method) !== null && _c !== void 0 ? _c : {}, (_d = d2 === null || d2 === void 0 ? void 0 : d2.method) !== null && _d !== void 0 ? _d : {}),
});
};
const mergeDecorators = (d1, d2) => {
var _a, _b, _c, _d, _e, _f;
return ({
class: util_1.unique([...(_a = d1 === null || d1 === void 0 ? void 0 : d1.class) !== null && _a !== void 0 ? _a : [], ...(_b = d2 === null || d2 === void 0 ? void 0 : d2.class) !== null && _b !== void 0 ? _b : []]),
static: mergePropertyAndMethodDecorators((_c = d1 === null || d1 === void 0 ? void 0 : d1.static) !== null && _c !== void 0 ? _c : {}, (_d = d2 === null || d2 === void 0 ? void 0 : d2.static) !== null && _d !== void 0 ? _d : {}),
instance: mergePropertyAndMethodDecorators((_e = d1 === null || d1 === void 0 ? void 0 : d1.instance) !== null && _e !== void 0 ? _e : {}, (_f = d2 === null || d2 === void 0 ? void 0 : d2.instance) !== null && _f !== void 0 ? _f : {}),
});
};
const decorators = new Map();
const findAllConstituentClasses = (...classes) => {
var _a;
const allClasses = new Set();
const frontier = new Set([...classes]);
while (frontier.size > 0) {
for (let clazz of frontier) {
const protoChainClasses = util_1.protoChain(clazz.prototype).map(proto => proto.constructor);
const mixinClasses = (_a = mixin_tracking_1.getMixinsForClass(clazz)) !== null && _a !== void 0 ? _a : [];
const potentiallyNewClasses = [...protoChainClasses, ...mixinClasses];
const newClasses = potentiallyNewClasses.filter(c => !allClasses.has(c));
for (let newClass of newClasses)
frontier.add(newClass);
allClasses.add(clazz);
frontier.delete(clazz);
}
}
return [...allClasses];
};
const deepDecoratorSearch = (...classes) => {
const decoratorsForClassChain = findAllConstituentClasses(...classes)
.map(clazz => decorators.get(clazz))
.filter(decorators => !!decorators);
if (decoratorsForClassChain.length == 0)
return {};
if (decoratorsForClassChain.length == 1)
return decoratorsForClassChain[0];
return decoratorsForClassChain.reduce((d1, d2) => mergeDecorators(d1, d2));
};
exports.deepDecoratorSearch = deepDecoratorSearch;
const directDecoratorSearch = (...classes) => {
const classDecorators = classes.map(clazz => exports.getDecoratorsForClass(clazz));
if (classDecorators.length === 0)
return {};
if (classDecorators.length === 1)
return classDecorators[0];
return classDecorators.reduce((d1, d2) => mergeDecorators(d1, d2));
};
exports.directDecoratorSearch = directDecoratorSearch;
const getDecoratorsForClass = (clazz) => {
let decoratorsForClass = decorators.get(clazz);
if (!decoratorsForClass) {
decoratorsForClass = {};
decorators.set(clazz, decoratorsForClass);
}
return decoratorsForClass;
};
exports.getDecoratorsForClass = getDecoratorsForClass;
const decorateClass = (decorator) => ((clazz) => {
const decoratorsForClass = exports.getDecoratorsForClass(clazz);
let classDecorators = decoratorsForClass.class;
if (!classDecorators) {
classDecorators = [];
decoratorsForClass.class = classDecorators;
}
classDecorators.push(decorator);
return decorator(clazz);
});
const decorateMember = (decorator) => ((object, key, ...otherArgs) => {
const decoratorTargetType = typeof object === 'function' ? 'static' : 'instance';
const decoratorType = typeof object[key] === 'function' ? 'method' : 'property';
const clazz = decoratorTargetType === 'static' ? object : object.constructor;
const decoratorsForClass = exports.getDecoratorsForClass(clazz);
let decoratorsForTargetType = decoratorsForClass === null || decoratorsForClass === void 0 ? void 0 : decoratorsForClass[decoratorTargetType];
if (!decoratorsForTargetType) {
decoratorsForTargetType = {};
decoratorsForClass[decoratorTargetType] = decoratorsForTargetType;
}
let decoratorsForType = decoratorsForTargetType === null || decoratorsForTargetType === void 0 ? void 0 : decoratorsForTargetType[decoratorType];
if (!decoratorsForType) {
decoratorsForType = {};
decoratorsForTargetType[decoratorType] = decoratorsForType;
}
let decoratorsForKey = decoratorsForType === null || decoratorsForType === void 0 ? void 0 : decoratorsForType[key];
if (!decoratorsForKey) {
decoratorsForKey = [];
decoratorsForType[key] = decoratorsForKey;
}
decoratorsForKey.push(decorator);
// @ts-ignore
return decorator(object, key, ...otherArgs);
});
const decorate = (decorator) => ((...args) => {
if (args.length === 1)
return decorateClass(decorator)(args[0]);
return decorateMember(decorator)(...args);
});
exports.decorate = decorate;

12
node_modules/ts-mixer/dist/cjs/index.js generated vendored Normal file
View file

@ -0,0 +1,12 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.hasMixin = exports.decorate = exports.settings = exports.mix = exports.Mixin = void 0;
var mixins_1 = require("./mixins");
Object.defineProperty(exports, "Mixin", { enumerable: true, get: function () { return mixins_1.Mixin; } });
Object.defineProperty(exports, "mix", { enumerable: true, get: function () { return mixins_1.mix; } });
var settings_1 = require("./settings");
Object.defineProperty(exports, "settings", { enumerable: true, get: function () { return settings_1.settings; } });
var decorator_1 = require("./decorator");
Object.defineProperty(exports, "decorate", { enumerable: true, get: function () { return decorator_1.decorate; } });
var mixin_tracking_1 = require("./mixin-tracking");
Object.defineProperty(exports, "hasMixin", { enumerable: true, get: function () { return mixin_tracking_1.hasMixin; } });

40
node_modules/ts-mixer/dist/cjs/mixin-tracking.js generated vendored Normal file
View file

@ -0,0 +1,40 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.hasMixin = exports.registerMixins = exports.getMixinsForClass = void 0;
const util_1 = require("./util");
// Keeps track of constituent classes for every mixin class created by ts-mixer.
const mixins = new Map();
const getMixinsForClass = (clazz) => mixins.get(clazz);
exports.getMixinsForClass = getMixinsForClass;
const registerMixins = (mixedClass, constituents) => mixins.set(mixedClass, constituents);
exports.registerMixins = registerMixins;
const hasMixin = (instance, mixin) => {
if (instance instanceof mixin)
return true;
const constructor = instance.constructor;
const visited = new Set();
let frontier = new Set();
frontier.add(constructor);
while (frontier.size > 0) {
// check if the frontier has the mixin we're looking for. if not, we can say we visited every item in the frontier
if (frontier.has(mixin))
return true;
frontier.forEach(item => visited.add(item));
// build a new frontier based on the associated mixin classes and prototype chains of each frontier item
const newFrontier = new Set();
frontier.forEach(item => {
var _a;
const itemConstituents = (_a = mixins.get(item)) !== null && _a !== void 0 ? _a : util_1.protoChain(item.prototype).map(proto => proto.constructor).filter(item => item !== null);
if (itemConstituents)
itemConstituents.forEach(constituent => {
if (!visited.has(constituent) && !frontier.has(constituent))
newFrontier.add(constituent);
});
});
// we have a new frontier, now search again
frontier = newFrontier;
}
// if we get here, we couldn't find the mixin anywhere in the prototype chain or associated mixin classes
return false;
};
exports.hasMixin = hasMixin;

82
node_modules/ts-mixer/dist/cjs/mixins.js generated vendored Normal file
View file

@ -0,0 +1,82 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.mix = exports.Mixin = void 0;
const proxy_1 = require("./proxy");
const settings_1 = require("./settings");
const util_1 = require("./util");
const decorator_1 = require("./decorator");
const mixin_tracking_1 = require("./mixin-tracking");
function Mixin(...constructors) {
var _a, _b, _c;
const prototypes = constructors.map(constructor => constructor.prototype);
// Here we gather up the init functions of the ingredient prototypes, combine them into one init function, and
// attach it to the mixed class prototype. The reason we do this is because we want the init functions to mix
// similarly to constructors -- not methods, which simply override each other.
const initFunctionName = settings_1.settings.initFunction;
if (initFunctionName !== null) {
const initFunctions = prototypes
.map(proto => proto[initFunctionName])
.filter(func => typeof func === 'function');
const combinedInitFunction = function (...args) {
for (let initFunction of initFunctions)
initFunction.apply(this, args);
};
const extraProto = { [initFunctionName]: combinedInitFunction };
prototypes.push(extraProto);
}
function MixedClass(...args) {
for (const constructor of constructors)
// @ts-ignore: potentially abstract class
util_1.copyProps(this, new constructor(...args));
if (initFunctionName !== null && typeof this[initFunctionName] === 'function')
this[initFunctionName].apply(this, args);
}
MixedClass.prototype = settings_1.settings.prototypeStrategy === 'copy'
? util_1.hardMixProtos(prototypes, MixedClass)
: proxy_1.softMixProtos(prototypes, MixedClass);
Object.setPrototypeOf(MixedClass, settings_1.settings.staticsStrategy === 'copy'
? util_1.hardMixProtos(constructors, null, ['prototype'])
: proxy_1.proxyMix(constructors, Function.prototype));
let DecoratedMixedClass = MixedClass;
if (settings_1.settings.decoratorInheritance !== 'none') {
const classDecorators = settings_1.settings.decoratorInheritance === 'deep'
? decorator_1.deepDecoratorSearch(...constructors)
: decorator_1.directDecoratorSearch(...constructors);
for (let decorator of (_a = classDecorators === null || classDecorators === void 0 ? void 0 : classDecorators.class) !== null && _a !== void 0 ? _a : []) {
const result = decorator(DecoratedMixedClass);
if (result) {
DecoratedMixedClass = result;
}
}
applyPropAndMethodDecorators((_b = classDecorators === null || classDecorators === void 0 ? void 0 : classDecorators.static) !== null && _b !== void 0 ? _b : {}, DecoratedMixedClass);
applyPropAndMethodDecorators((_c = classDecorators === null || classDecorators === void 0 ? void 0 : classDecorators.instance) !== null && _c !== void 0 ? _c : {}, DecoratedMixedClass.prototype);
}
mixin_tracking_1.registerMixins(DecoratedMixedClass, constructors);
return DecoratedMixedClass;
}
exports.Mixin = Mixin;
const applyPropAndMethodDecorators = (propAndMethodDecorators, target) => {
const propDecorators = propAndMethodDecorators.property;
const methodDecorators = propAndMethodDecorators.method;
if (propDecorators)
for (let key in propDecorators)
for (let decorator of propDecorators[key])
decorator(target, key);
if (methodDecorators)
for (let key in methodDecorators)
for (let decorator of methodDecorators[key])
decorator(target, key, Object.getOwnPropertyDescriptor(target, key));
};
/**
* A decorator version of the `Mixin` function. You'll want to use this instead of `Mixin` for mixing generic classes.
*/
const mix = (...ingredients) => decoratedClass => {
// @ts-ignore
const mixedClass = Mixin(...ingredients.concat([decoratedClass]));
Object.defineProperty(mixedClass, 'name', {
value: decoratedClass.name,
writable: false,
});
return mixedClass;
};
exports.mix = mix;

82
node_modules/ts-mixer/dist/cjs/proxy.js generated vendored Normal file
View file

@ -0,0 +1,82 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.softMixProtos = exports.proxyMix = exports.getIngredientWithProp = void 0;
const util_1 = require("./util");
/**
* Finds the ingredient with the given prop, searching in reverse order and breadth-first if searching ingredient
* prototypes is required.
*/
const getIngredientWithProp = (prop, ingredients) => {
const protoChains = ingredients.map(ingredient => util_1.protoChain(ingredient));
// since we search breadth-first, we need to keep track of our depth in the prototype chains
let protoDepth = 0;
// not all prototype chains are the same depth, so this remains true as long as at least one of the ingredients'
// prototype chains has an object at this depth
let protosAreLeftToSearch = true;
while (protosAreLeftToSearch) {
// with the start of each horizontal slice, we assume this is the one that's deeper than any of the proto chains
protosAreLeftToSearch = false;
// scan through the ingredients right to left
for (let i = ingredients.length - 1; i >= 0; i--) {
const searchTarget = protoChains[i][protoDepth];
if (searchTarget !== undefined && searchTarget !== null) {
// if we find something, this is proof that this horizontal slice potentially more objects to search
protosAreLeftToSearch = true;
// eureka, we found it
if (Object.getOwnPropertyDescriptor(searchTarget, prop) != undefined) {
return protoChains[i][0];
}
}
}
protoDepth++;
}
return undefined;
};
exports.getIngredientWithProp = getIngredientWithProp;
/**
* "Mixes" ingredients by wrapping them in a Proxy. The optional prototype argument allows the mixed object to sit
* downstream of an existing prototype chain. Note that "properties" cannot be added, deleted, or modified.
*/
const proxyMix = (ingredients, prototype = Object.prototype) => new Proxy({}, {
getPrototypeOf() {
return prototype;
},
setPrototypeOf() {
throw Error('Cannot set prototype of Proxies created by ts-mixer');
},
getOwnPropertyDescriptor(_, prop) {
return Object.getOwnPropertyDescriptor(exports.getIngredientWithProp(prop, ingredients) || {}, prop);
},
defineProperty() {
throw new Error('Cannot define new properties on Proxies created by ts-mixer');
},
has(_, prop) {
return exports.getIngredientWithProp(prop, ingredients) !== undefined || prototype[prop] !== undefined;
},
get(_, prop) {
return (exports.getIngredientWithProp(prop, ingredients) || prototype)[prop];
},
set(_, prop, val) {
const ingredientWithProp = exports.getIngredientWithProp(prop, ingredients);
if (ingredientWithProp === undefined)
throw new Error('Cannot set new properties on Proxies created by ts-mixer');
ingredientWithProp[prop] = val;
return true;
},
deleteProperty() {
throw new Error('Cannot delete properties on Proxies created by ts-mixer');
},
ownKeys() {
return ingredients
.map(Object.getOwnPropertyNames)
.reduce((prev, curr) => curr.concat(prev.filter(key => curr.indexOf(key) < 0)));
},
});
exports.proxyMix = proxyMix;
/**
* Creates a new proxy-prototype object that is a "soft" mixture of the given prototypes. The mixing is achieved by
* proxying all property access to the ingredients. This is not ES5 compatible and less performant. However, any
* changes made to the source prototypes will be reflected in the proxy-prototype, which may be desirable.
*/
const softMixProtos = (ingredients, constructor) => exports.proxyMix([...ingredients, { constructor }]);
exports.softMixProtos = softMixProtos;

9
node_modules/ts-mixer/dist/cjs/settings.js generated vendored Normal file
View file

@ -0,0 +1,9 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.settings = void 0;
exports.settings = {
initFunction: null,
staticsStrategy: 'copy',
prototypeStrategy: 'copy',
decoratorInheritance: 'deep',
};

2
node_modules/ts-mixer/dist/cjs/types.js generated vendored Normal file
View file

@ -0,0 +1,2 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });

85
node_modules/ts-mixer/dist/cjs/util.js generated vendored Normal file
View file

@ -0,0 +1,85 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.flatten = exports.unique = exports.hardMixProtos = exports.nearestCommonProto = exports.protoChain = exports.copyProps = void 0;
/**
* Utility function that works like `Object.apply`, but copies getters and setters properly as well. Additionally gives
* the option to exclude properties by name.
*/
const copyProps = (dest, src, exclude = []) => {
const props = Object.getOwnPropertyDescriptors(src);
for (let prop of exclude)
delete props[prop];
Object.defineProperties(dest, props);
};
exports.copyProps = copyProps;
/**
* Returns the full chain of prototypes up until Object.prototype given a starting object. The order of prototypes will
* be closest to farthest in the chain.
*/
const protoChain = (obj, currentChain = [obj]) => {
const proto = Object.getPrototypeOf(obj);
if (proto === null)
return currentChain;
return exports.protoChain(proto, [...currentChain, proto]);
};
exports.protoChain = protoChain;
/**
* Identifies the nearest ancestor common to all the given objects in their prototype chains. For most unrelated
* objects, this function should return Object.prototype.
*/
const nearestCommonProto = (...objs) => {
if (objs.length === 0)
return undefined;
let commonProto = undefined;
const protoChains = objs.map(obj => exports.protoChain(obj));
while (protoChains.every(protoChain => protoChain.length > 0)) {
const protos = protoChains.map(protoChain => protoChain.pop());
const potentialCommonProto = protos[0];
if (protos.every(proto => proto === potentialCommonProto))
commonProto = potentialCommonProto;
else
break;
}
return commonProto;
};
exports.nearestCommonProto = nearestCommonProto;
/**
* Creates a new prototype object that is a mixture of the given prototypes. The mixing is achieved by first
* identifying the nearest common ancestor and using it as the prototype for a new object. Then all properties/methods
* downstream of this prototype (ONLY downstream) are copied into the new object.
*
* The resulting prototype is more performant than softMixProtos(...), as well as ES5 compatible. However, it's not as
* flexible as updates to the source prototypes aren't captured by the mixed result. See softMixProtos for why you may
* want to use that instead.
*/
const hardMixProtos = (ingredients, constructor, exclude = []) => {
var _a;
const base = (_a = exports.nearestCommonProto(...ingredients)) !== null && _a !== void 0 ? _a : Object.prototype;
const mixedProto = Object.create(base);
// Keeps track of prototypes we've already visited to avoid copying the same properties multiple times. We init the
// list with the proto chain below the nearest common ancestor because we don't want any of those methods mixed in
// when they will already be accessible via prototype access.
const visitedProtos = exports.protoChain(base);
for (let prototype of ingredients) {
let protos = exports.protoChain(prototype);
// Apply the prototype chain in reverse order so that old methods don't override newer ones.
for (let i = protos.length - 1; i >= 0; i--) {
let newProto = protos[i];
if (visitedProtos.indexOf(newProto) === -1) {
exports.copyProps(mixedProto, newProto, ['constructor', ...exclude]);
visitedProtos.push(newProto);
}
}
}
mixedProto.constructor = constructor;
return mixedProto;
};
exports.hardMixProtos = hardMixProtos;
const unique = (arr) => arr.filter((e, i) => arr.indexOf(e) == i);
exports.unique = unique;
const flatten = (arr) => arr.length === 0
? []
: arr.length === 1
? arr[0]
: arr.reduce((a1, a2) => [...a1, ...a2]);
exports.flatten = flatten;

371
node_modules/ts-mixer/dist/esm/index.js generated vendored Normal file
View file

@ -0,0 +1,371 @@
/**
* Utility function that works like `Object.apply`, but copies getters and setters properly as well. Additionally gives
* the option to exclude properties by name.
*/
const copyProps = (dest, src, exclude = []) => {
const props = Object.getOwnPropertyDescriptors(src);
for (let prop of exclude)
delete props[prop];
Object.defineProperties(dest, props);
};
/**
* Returns the full chain of prototypes up until Object.prototype given a starting object. The order of prototypes will
* be closest to farthest in the chain.
*/
const protoChain = (obj, currentChain = [obj]) => {
const proto = Object.getPrototypeOf(obj);
if (proto === null)
return currentChain;
return protoChain(proto, [...currentChain, proto]);
};
/**
* Identifies the nearest ancestor common to all the given objects in their prototype chains. For most unrelated
* objects, this function should return Object.prototype.
*/
const nearestCommonProto = (...objs) => {
if (objs.length === 0)
return undefined;
let commonProto = undefined;
const protoChains = objs.map(obj => protoChain(obj));
while (protoChains.every(protoChain => protoChain.length > 0)) {
const protos = protoChains.map(protoChain => protoChain.pop());
const potentialCommonProto = protos[0];
if (protos.every(proto => proto === potentialCommonProto))
commonProto = potentialCommonProto;
else
break;
}
return commonProto;
};
/**
* Creates a new prototype object that is a mixture of the given prototypes. The mixing is achieved by first
* identifying the nearest common ancestor and using it as the prototype for a new object. Then all properties/methods
* downstream of this prototype (ONLY downstream) are copied into the new object.
*
* The resulting prototype is more performant than softMixProtos(...), as well as ES5 compatible. However, it's not as
* flexible as updates to the source prototypes aren't captured by the mixed result. See softMixProtos for why you may
* want to use that instead.
*/
const hardMixProtos = (ingredients, constructor, exclude = []) => {
var _a;
const base = (_a = nearestCommonProto(...ingredients)) !== null && _a !== void 0 ? _a : Object.prototype;
const mixedProto = Object.create(base);
// Keeps track of prototypes we've already visited to avoid copying the same properties multiple times. We init the
// list with the proto chain below the nearest common ancestor because we don't want any of those methods mixed in
// when they will already be accessible via prototype access.
const visitedProtos = protoChain(base);
for (let prototype of ingredients) {
let protos = protoChain(prototype);
// Apply the prototype chain in reverse order so that old methods don't override newer ones.
for (let i = protos.length - 1; i >= 0; i--) {
let newProto = protos[i];
if (visitedProtos.indexOf(newProto) === -1) {
copyProps(mixedProto, newProto, ['constructor', ...exclude]);
visitedProtos.push(newProto);
}
}
}
mixedProto.constructor = constructor;
return mixedProto;
};
const unique = (arr) => arr.filter((e, i) => arr.indexOf(e) == i);
/**
* Finds the ingredient with the given prop, searching in reverse order and breadth-first if searching ingredient
* prototypes is required.
*/
const getIngredientWithProp = (prop, ingredients) => {
const protoChains = ingredients.map(ingredient => protoChain(ingredient));
// since we search breadth-first, we need to keep track of our depth in the prototype chains
let protoDepth = 0;
// not all prototype chains are the same depth, so this remains true as long as at least one of the ingredients'
// prototype chains has an object at this depth
let protosAreLeftToSearch = true;
while (protosAreLeftToSearch) {
// with the start of each horizontal slice, we assume this is the one that's deeper than any of the proto chains
protosAreLeftToSearch = false;
// scan through the ingredients right to left
for (let i = ingredients.length - 1; i >= 0; i--) {
const searchTarget = protoChains[i][protoDepth];
if (searchTarget !== undefined && searchTarget !== null) {
// if we find something, this is proof that this horizontal slice potentially more objects to search
protosAreLeftToSearch = true;
// eureka, we found it
if (Object.getOwnPropertyDescriptor(searchTarget, prop) != undefined) {
return protoChains[i][0];
}
}
}
protoDepth++;
}
return undefined;
};
/**
* "Mixes" ingredients by wrapping them in a Proxy. The optional prototype argument allows the mixed object to sit
* downstream of an existing prototype chain. Note that "properties" cannot be added, deleted, or modified.
*/
const proxyMix = (ingredients, prototype = Object.prototype) => new Proxy({}, {
getPrototypeOf() {
return prototype;
},
setPrototypeOf() {
throw Error('Cannot set prototype of Proxies created by ts-mixer');
},
getOwnPropertyDescriptor(_, prop) {
return Object.getOwnPropertyDescriptor(getIngredientWithProp(prop, ingredients) || {}, prop);
},
defineProperty() {
throw new Error('Cannot define new properties on Proxies created by ts-mixer');
},
has(_, prop) {
return getIngredientWithProp(prop, ingredients) !== undefined || prototype[prop] !== undefined;
},
get(_, prop) {
return (getIngredientWithProp(prop, ingredients) || prototype)[prop];
},
set(_, prop, val) {
const ingredientWithProp = getIngredientWithProp(prop, ingredients);
if (ingredientWithProp === undefined)
throw new Error('Cannot set new properties on Proxies created by ts-mixer');
ingredientWithProp[prop] = val;
return true;
},
deleteProperty() {
throw new Error('Cannot delete properties on Proxies created by ts-mixer');
},
ownKeys() {
return ingredients
.map(Object.getOwnPropertyNames)
.reduce((prev, curr) => curr.concat(prev.filter(key => curr.indexOf(key) < 0)));
},
});
/**
* Creates a new proxy-prototype object that is a "soft" mixture of the given prototypes. The mixing is achieved by
* proxying all property access to the ingredients. This is not ES5 compatible and less performant. However, any
* changes made to the source prototypes will be reflected in the proxy-prototype, which may be desirable.
*/
const softMixProtos = (ingredients, constructor) => proxyMix([...ingredients, { constructor }]);
const settings = {
initFunction: null,
staticsStrategy: 'copy',
prototypeStrategy: 'copy',
decoratorInheritance: 'deep',
};
// Keeps track of constituent classes for every mixin class created by ts-mixer.
const mixins = new Map();
const getMixinsForClass = (clazz) => mixins.get(clazz);
const registerMixins = (mixedClass, constituents) => mixins.set(mixedClass, constituents);
const hasMixin = (instance, mixin) => {
if (instance instanceof mixin)
return true;
const constructor = instance.constructor;
const visited = new Set();
let frontier = new Set();
frontier.add(constructor);
while (frontier.size > 0) {
// check if the frontier has the mixin we're looking for. if not, we can say we visited every item in the frontier
if (frontier.has(mixin))
return true;
frontier.forEach(item => visited.add(item));
// build a new frontier based on the associated mixin classes and prototype chains of each frontier item
const newFrontier = new Set();
frontier.forEach(item => {
var _a;
const itemConstituents = (_a = mixins.get(item)) !== null && _a !== void 0 ? _a : protoChain(item.prototype).map(proto => proto.constructor).filter(item => item !== null);
if (itemConstituents)
itemConstituents.forEach(constituent => {
if (!visited.has(constituent) && !frontier.has(constituent))
newFrontier.add(constituent);
});
});
// we have a new frontier, now search again
frontier = newFrontier;
}
// if we get here, we couldn't find the mixin anywhere in the prototype chain or associated mixin classes
return false;
};
const mergeObjectsOfDecorators = (o1, o2) => {
var _a, _b;
const allKeys = unique([...Object.getOwnPropertyNames(o1), ...Object.getOwnPropertyNames(o2)]);
const mergedObject = {};
for (let key of allKeys)
mergedObject[key] = unique([...((_a = o1 === null || o1 === void 0 ? void 0 : o1[key]) !== null && _a !== void 0 ? _a : []), ...((_b = o2 === null || o2 === void 0 ? void 0 : o2[key]) !== null && _b !== void 0 ? _b : [])]);
return mergedObject;
};
const mergePropertyAndMethodDecorators = (d1, d2) => {
var _a, _b, _c, _d;
return ({
property: mergeObjectsOfDecorators((_a = d1 === null || d1 === void 0 ? void 0 : d1.property) !== null && _a !== void 0 ? _a : {}, (_b = d2 === null || d2 === void 0 ? void 0 : d2.property) !== null && _b !== void 0 ? _b : {}),
method: mergeObjectsOfDecorators((_c = d1 === null || d1 === void 0 ? void 0 : d1.method) !== null && _c !== void 0 ? _c : {}, (_d = d2 === null || d2 === void 0 ? void 0 : d2.method) !== null && _d !== void 0 ? _d : {}),
});
};
const mergeDecorators = (d1, d2) => {
var _a, _b, _c, _d, _e, _f;
return ({
class: unique([...(_a = d1 === null || d1 === void 0 ? void 0 : d1.class) !== null && _a !== void 0 ? _a : [], ...(_b = d2 === null || d2 === void 0 ? void 0 : d2.class) !== null && _b !== void 0 ? _b : []]),
static: mergePropertyAndMethodDecorators((_c = d1 === null || d1 === void 0 ? void 0 : d1.static) !== null && _c !== void 0 ? _c : {}, (_d = d2 === null || d2 === void 0 ? void 0 : d2.static) !== null && _d !== void 0 ? _d : {}),
instance: mergePropertyAndMethodDecorators((_e = d1 === null || d1 === void 0 ? void 0 : d1.instance) !== null && _e !== void 0 ? _e : {}, (_f = d2 === null || d2 === void 0 ? void 0 : d2.instance) !== null && _f !== void 0 ? _f : {}),
});
};
const decorators = new Map();
const findAllConstituentClasses = (...classes) => {
var _a;
const allClasses = new Set();
const frontier = new Set([...classes]);
while (frontier.size > 0) {
for (let clazz of frontier) {
const protoChainClasses = protoChain(clazz.prototype).map(proto => proto.constructor);
const mixinClasses = (_a = getMixinsForClass(clazz)) !== null && _a !== void 0 ? _a : [];
const potentiallyNewClasses = [...protoChainClasses, ...mixinClasses];
const newClasses = potentiallyNewClasses.filter(c => !allClasses.has(c));
for (let newClass of newClasses)
frontier.add(newClass);
allClasses.add(clazz);
frontier.delete(clazz);
}
}
return [...allClasses];
};
const deepDecoratorSearch = (...classes) => {
const decoratorsForClassChain = findAllConstituentClasses(...classes)
.map(clazz => decorators.get(clazz))
.filter(decorators => !!decorators);
if (decoratorsForClassChain.length == 0)
return {};
if (decoratorsForClassChain.length == 1)
return decoratorsForClassChain[0];
return decoratorsForClassChain.reduce((d1, d2) => mergeDecorators(d1, d2));
};
const directDecoratorSearch = (...classes) => {
const classDecorators = classes.map(clazz => getDecoratorsForClass(clazz));
if (classDecorators.length === 0)
return {};
if (classDecorators.length === 1)
return classDecorators[0];
return classDecorators.reduce((d1, d2) => mergeDecorators(d1, d2));
};
const getDecoratorsForClass = (clazz) => {
let decoratorsForClass = decorators.get(clazz);
if (!decoratorsForClass) {
decoratorsForClass = {};
decorators.set(clazz, decoratorsForClass);
}
return decoratorsForClass;
};
const decorateClass = (decorator) => ((clazz) => {
const decoratorsForClass = getDecoratorsForClass(clazz);
let classDecorators = decoratorsForClass.class;
if (!classDecorators) {
classDecorators = [];
decoratorsForClass.class = classDecorators;
}
classDecorators.push(decorator);
return decorator(clazz);
});
const decorateMember = (decorator) => ((object, key, ...otherArgs) => {
const decoratorTargetType = typeof object === 'function' ? 'static' : 'instance';
const decoratorType = typeof object[key] === 'function' ? 'method' : 'property';
const clazz = decoratorTargetType === 'static' ? object : object.constructor;
const decoratorsForClass = getDecoratorsForClass(clazz);
let decoratorsForTargetType = decoratorsForClass === null || decoratorsForClass === void 0 ? void 0 : decoratorsForClass[decoratorTargetType];
if (!decoratorsForTargetType) {
decoratorsForTargetType = {};
decoratorsForClass[decoratorTargetType] = decoratorsForTargetType;
}
let decoratorsForType = decoratorsForTargetType === null || decoratorsForTargetType === void 0 ? void 0 : decoratorsForTargetType[decoratorType];
if (!decoratorsForType) {
decoratorsForType = {};
decoratorsForTargetType[decoratorType] = decoratorsForType;
}
let decoratorsForKey = decoratorsForType === null || decoratorsForType === void 0 ? void 0 : decoratorsForType[key];
if (!decoratorsForKey) {
decoratorsForKey = [];
decoratorsForType[key] = decoratorsForKey;
}
decoratorsForKey.push(decorator);
// @ts-ignore
return decorator(object, key, ...otherArgs);
});
const decorate = (decorator) => ((...args) => {
if (args.length === 1)
return decorateClass(decorator)(args[0]);
return decorateMember(decorator)(...args);
});
function Mixin(...constructors) {
var _a, _b, _c;
const prototypes = constructors.map(constructor => constructor.prototype);
// Here we gather up the init functions of the ingredient prototypes, combine them into one init function, and
// attach it to the mixed class prototype. The reason we do this is because we want the init functions to mix
// similarly to constructors -- not methods, which simply override each other.
const initFunctionName = settings.initFunction;
if (initFunctionName !== null) {
const initFunctions = prototypes
.map(proto => proto[initFunctionName])
.filter(func => typeof func === 'function');
const combinedInitFunction = function (...args) {
for (let initFunction of initFunctions)
initFunction.apply(this, args);
};
const extraProto = { [initFunctionName]: combinedInitFunction };
prototypes.push(extraProto);
}
function MixedClass(...args) {
for (const constructor of constructors)
// @ts-ignore: potentially abstract class
copyProps(this, new constructor(...args));
if (initFunctionName !== null && typeof this[initFunctionName] === 'function')
this[initFunctionName].apply(this, args);
}
MixedClass.prototype = settings.prototypeStrategy === 'copy'
? hardMixProtos(prototypes, MixedClass)
: softMixProtos(prototypes, MixedClass);
Object.setPrototypeOf(MixedClass, settings.staticsStrategy === 'copy'
? hardMixProtos(constructors, null, ['prototype'])
: proxyMix(constructors, Function.prototype));
let DecoratedMixedClass = MixedClass;
if (settings.decoratorInheritance !== 'none') {
const classDecorators = settings.decoratorInheritance === 'deep'
? deepDecoratorSearch(...constructors)
: directDecoratorSearch(...constructors);
for (let decorator of (_a = classDecorators === null || classDecorators === void 0 ? void 0 : classDecorators.class) !== null && _a !== void 0 ? _a : []) {
const result = decorator(DecoratedMixedClass);
if (result) {
DecoratedMixedClass = result;
}
}
applyPropAndMethodDecorators((_b = classDecorators === null || classDecorators === void 0 ? void 0 : classDecorators.static) !== null && _b !== void 0 ? _b : {}, DecoratedMixedClass);
applyPropAndMethodDecorators((_c = classDecorators === null || classDecorators === void 0 ? void 0 : classDecorators.instance) !== null && _c !== void 0 ? _c : {}, DecoratedMixedClass.prototype);
}
registerMixins(DecoratedMixedClass, constructors);
return DecoratedMixedClass;
}
const applyPropAndMethodDecorators = (propAndMethodDecorators, target) => {
const propDecorators = propAndMethodDecorators.property;
const methodDecorators = propAndMethodDecorators.method;
if (propDecorators)
for (let key in propDecorators)
for (let decorator of propDecorators[key])
decorator(target, key);
if (methodDecorators)
for (let key in methodDecorators)
for (let decorator of methodDecorators[key])
decorator(target, key, Object.getOwnPropertyDescriptor(target, key));
};
/**
* A decorator version of the `Mixin` function. You'll want to use this instead of `Mixin` for mixing generic classes.
*/
const mix = (...ingredients) => decoratedClass => {
// @ts-ignore
const mixedClass = Mixin(...ingredients.concat([decoratedClass]));
Object.defineProperty(mixedClass, 'name', {
value: decoratedClass.name,
writable: false,
});
return mixedClass;
};
export { Mixin, decorate, hasMixin, mix, settings };

1
node_modules/ts-mixer/dist/esm/index.min.js generated vendored Normal file

File diff suppressed because one or more lines are too long

18
node_modules/ts-mixer/dist/types/decorator.d.ts generated vendored Normal file
View file

@ -0,0 +1,18 @@
import { Class } from './types';
declare type ObjectOfDecorators<T extends PropertyDecorator | MethodDecorator> = {
[key: string]: T[];
};
export declare type PropertyAndMethodDecorators = {
property?: ObjectOfDecorators<PropertyDecorator>;
method?: ObjectOfDecorators<MethodDecorator>;
};
declare type Decorators = {
class?: ClassDecorator[];
static?: PropertyAndMethodDecorators;
instance?: PropertyAndMethodDecorators;
};
export declare const deepDecoratorSearch: (...classes: Class[]) => Decorators;
export declare const directDecoratorSearch: (...classes: Class[]) => Decorators;
export declare const getDecoratorsForClass: (clazz: Class) => Decorators;
export declare const decorate: <T extends PropertyDecorator | MethodDecorator | ClassDecorator>(decorator: T) => T;
export {};

4
node_modules/ts-mixer/dist/types/index.d.ts generated vendored Normal file
View file

@ -0,0 +1,4 @@
export { Mixin, mix } from './mixins';
export { settings } from './settings';
export { decorate } from './decorator';
export { hasMixin } from './mixin-tracking';

4
node_modules/ts-mixer/dist/types/mixin-tracking.d.ts generated vendored Normal file
View file

@ -0,0 +1,4 @@
import { Class } from './types';
export declare const getMixinsForClass: (clazz: Class) => Function[] | undefined;
export declare const registerMixins: (mixedClass: any, constituents: Function[]) => Map<any, Function[]>;
export declare const hasMixin: <M>(instance: any, mixin: new (...args: any[]) => M) => instance is M;

16
node_modules/ts-mixer/dist/types/mixins.d.ts generated vendored Normal file
View file

@ -0,0 +1,16 @@
import { Class, Longest } from './types';
declare function Mixin<A extends any[], I1, S1>(c1: Class<A, I1, S1>): Class<A, I1, S1>;
declare function Mixin<A1 extends any[], I1, S1, A2 extends any[], I2, S2>(c1: Class<A1, I1, S1>, c2: Class<A2, I2, S2>): Class<Longest<A1, A2>, I1 & I2, S1 & S2>;
declare function Mixin<A1 extends any[], I1, S1, A2 extends any[], I2, S2, A3 extends any[], I3, S3>(c1: Class<A1, I1, S1>, c2: Class<A2, I2, S2>, c3: Class<A3, I3, S3>): Class<Longest<A1, A2, A3>, I1 & I2 & I3, S1 & S2 & S3>;
declare function Mixin<A1 extends any[], I1, S1, A2 extends any[], I2, S2, A3 extends any[], I3, S3, A4 extends any[], I4, S4>(c1: Class<A1, I1, S1>, c2: Class<A2, I2, S2>, c3: Class<A3, I3, S3>, c4: Class<A4, I4, S4>): Class<Longest<A1, A2, A3, A4>, I1 & I2 & I3 & I4, S1 & S2 & S3 & S4>;
declare function Mixin<A1 extends any[], I1, S1, A2 extends any[], I2, S2, A3 extends any[], I3, S3, A4 extends any[], I4, S4, A5 extends any[], I5, S5>(c1: Class<A1, I1, S1>, c2: Class<A2, I2, S2>, c3: Class<A3, I3, S3>, c4: Class<A4, I4, S4>, c5: Class<A5, I5, S5>): Class<Longest<A1, A2, A3, A4, A5>, I1 & I2 & I3 & I4 & I5, S1 & S2 & S3 & S4 & S5>;
declare function Mixin<A1 extends any[], I1, S1, A2 extends any[], I2, S2, A3 extends any[], I3, S3, A4 extends any[], I4, S4, A5 extends any[], I5, S5, A6 extends any[], I6, S6>(c1: Class<A1, I1, S1>, c2: Class<A2, I2, S2>, c3: Class<A3, I3, S3>, c4: Class<A4, I4, S4>, c5: Class<A5, I5, S5>, c6: Class<A6, I6, S6>): Class<Longest<A1, A2, A3, A4, A5, A6>, I1 & I2 & I3 & I4 & I5 & I6, S1 & S2 & S3 & S4 & S5 & S6>;
declare function Mixin<A1 extends any[], I1, S1, A2 extends any[], I2, S2, A3 extends any[], I3, S3, A4 extends any[], I4, S4, A5 extends any[], I5, S5, A6 extends any[], I6, S6, A7 extends any[], I7, S7>(c1: Class<A1, I1, S1>, c2: Class<A2, I2, S2>, c3: Class<A3, I3, S3>, c4: Class<A4, I4, S4>, c5: Class<A5, I5, S5>, c6: Class<A6, I6, S6>, c7: Class<A7, I7, S7>): Class<Longest<A1, A2, A3, A4, A5, A6, A7>, I1 & I2 & I3 & I4 & I5 & I6 & I7, S1 & S2 & S3 & S4 & S5 & S6 & S7>;
declare function Mixin<A1 extends any[], I1, S1, A2 extends any[], I2, S2, A3 extends any[], I3, S3, A4 extends any[], I4, S4, A5 extends any[], I5, S5, A6 extends any[], I6, S6, A7 extends any[], I7, S7, A8 extends any[], I8, S8>(c1: Class<A1, I1, S1>, c2: Class<A2, I2, S2>, c3: Class<A3, I3, S3>, c4: Class<A4, I4, S4>, c5: Class<A5, I5, S5>, c6: Class<A6, I6, S6>, c7: Class<A7, I7, S7>, c8: Class<A8, I8, S8>): Class<Longest<A1, A2, A3, A4, A5, A6, A7, A8>, I1 & I2 & I3 & I4 & I5 & I6 & I7 & I8, S1 & S2 & S3 & S4 & S5 & S6 & S7 & S8>;
declare function Mixin<A1 extends any[], I1, S1, A2 extends any[], I2, S2, A3 extends any[], I3, S3, A4 extends any[], I4, S4, A5 extends any[], I5, S5, A6 extends any[], I6, S6, A7 extends any[], I7, S7, A8 extends any[], I8, S8, A9 extends any[], I9, S9>(c1: Class<A1, I1, S1>, c2: Class<A2, I2, S2>, c3: Class<A3, I3, S3>, c4: Class<A4, I4, S4>, c5: Class<A5, I5, S5>, c6: Class<A6, I6, S6>, c7: Class<A7, I7, S7>, c8: Class<A8, I8, S8>, c9: Class<A9, I9, S9>): Class<Longest<A1, A2, A3, A4, A5, A6, A7, A8, A9>, I1 & I2 & I3 & I4 & I5 & I6 & I7 & I8 & I9, S1 & S2 & S3 & S4 & S5 & S6 & S7 & S8 & S9>;
declare function Mixin<A1 extends any[], I1, S1, A2 extends any[], I2, S2, A3 extends any[], I3, S3, A4 extends any[], I4, S4, A5 extends any[], I5, S5, A6 extends any[], I6, S6, A7 extends any[], I7, S7, A8 extends any[], I8, S8, A9 extends any[], I9, S9, A10 extends any[], I10, S10>(c1: Class<A1, I1, S1>, c2: Class<A2, I2, S2>, c3: Class<A3, I3, S3>, c4: Class<A4, I4, S4>, c5: Class<A5, I5, S5>, c6: Class<A6, I6, S6>, c7: Class<A7, I7, S7>, c8: Class<A8, I8, S8>, c9: Class<A9, I9, S9>, c10: Class<A10, I10, S10>): Class<Longest<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10>, I1 & I2 & I3 & I4 & I5 & I6 & I7 & I8 & I9 & I10, S1 & S2 & S3 & S4 & S5 & S6 & S7 & S8 & S9 & S10>;
/**
* A decorator version of the `Mixin` function. You'll want to use this instead of `Mixin` for mixing generic classes.
*/
declare const mix: (...ingredients: Class[]) => (decoratedClass: any) => any;
export { Mixin, mix };

16
node_modules/ts-mixer/dist/types/proxy.d.ts generated vendored Normal file
View file

@ -0,0 +1,16 @@
/**
* Finds the ingredient with the given prop, searching in reverse order and breadth-first if searching ingredient
* prototypes is required.
*/
export declare const getIngredientWithProp: (prop: string | number | symbol, ingredients: any[]) => object | undefined;
/**
* "Mixes" ingredients by wrapping them in a Proxy. The optional prototype argument allows the mixed object to sit
* downstream of an existing prototype chain. Note that "properties" cannot be added, deleted, or modified.
*/
export declare const proxyMix: (ingredients: any[], prototype?: Object) => {};
/**
* Creates a new proxy-prototype object that is a "soft" mixture of the given prototypes. The mixing is achieved by
* proxying all property access to the ingredients. This is not ES5 compatible and less performant. However, any
* changes made to the source prototypes will be reflected in the proxy-prototype, which may be desirable.
*/
export declare const softMixProtos: (ingredients: any[], constructor: Function) => object;

7
node_modules/ts-mixer/dist/types/settings.d.ts generated vendored Normal file
View file

@ -0,0 +1,7 @@
export declare type Settings = {
initFunction: string | null;
staticsStrategy: 'copy' | 'proxy';
prototypeStrategy: 'copy' | 'proxy';
decoratorInheritance: 'deep' | 'direct' | 'none';
};
export declare const settings: Settings;

13
node_modules/ts-mixer/dist/types/types.d.ts generated vendored Normal file
View file

@ -0,0 +1,13 @@
/**
* Returns the longer of the two tuples. Indefinite tuples will always be considered longest.
*/
declare type _Longest<T1 extends any[], T2 extends any[]> = any[] extends T1 ? T1 : any[] extends T2 ? T2 : Exclude<keyof T1, keyof T2> extends never ? T2 : T1;
/**
* Returns the longest of up to 10 different tuples.
*/
export declare type Longest<T1 extends any[], T2 extends any[] = [], T3 extends any[] = [], T4 extends any[] = [], T5 extends any[] = [], T6 extends any[] = [], T7 extends any[] = [], T8 extends any[] = [], T9 extends any[] = [], T10 extends any[] = []> = _Longest<_Longest<_Longest<_Longest<T1, T2>, _Longest<T3, T4>>, _Longest<_Longest<T5, T6>, _Longest<T7, T8>>>, _Longest<T9, T10>>;
/**
* A rigorous type alias for a class.
*/
export declare type Class<CtorArgs extends any[] = any[], InstanceType = {}, StaticType = {}, IsAbstract = false> = (abstract new (...args: any[]) => InstanceType) & StaticType;
export {};

27
node_modules/ts-mixer/dist/types/util.d.ts generated vendored Normal file
View file

@ -0,0 +1,27 @@
/**
* Utility function that works like `Object.apply`, but copies getters and setters properly as well. Additionally gives
* the option to exclude properties by name.
*/
export declare const copyProps: (dest: object, src: object, exclude?: string[]) => void;
/**
* Returns the full chain of prototypes up until Object.prototype given a starting object. The order of prototypes will
* be closest to farthest in the chain.
*/
export declare const protoChain: (obj: object, currentChain?: object[]) => object[];
/**
* Identifies the nearest ancestor common to all the given objects in their prototype chains. For most unrelated
* objects, this function should return Object.prototype.
*/
export declare const nearestCommonProto: (...objs: object[]) => object | undefined;
/**
* Creates a new prototype object that is a mixture of the given prototypes. The mixing is achieved by first
* identifying the nearest common ancestor and using it as the prototype for a new object. Then all properties/methods
* downstream of this prototype (ONLY downstream) are copied into the new object.
*
* The resulting prototype is more performant than softMixProtos(...), as well as ES5 compatible. However, it's not as
* flexible as updates to the source prototypes aren't captured by the mixed result. See softMixProtos for why you may
* want to use that instead.
*/
export declare const hardMixProtos: (ingredients: any[], constructor: Function | null, exclude?: string[]) => object;
export declare const unique: <T>(arr: T[]) => T[];
export declare const flatten: <T>(arr: T[][]) => T[];