{"version":3,"file":"index.umd.production.min.cjs","sources":["../src/index.ts"],"sourcesContent":["// @ts-ignore\nimport { shim as _flatMapShim } from \"array.prototype.flatmap\";\n// @ts-ignore\nimport { shim as _ownKeysShim } from \"reflect.ownkeys\";\nimport { classWithoutCallParentConstructor } from 'class-without-call-parent-constructor';\n\ndeclare var __DEV__: boolean;\n\nif (typeof Reflect.ownKeys === \"undefined\") {\n\t_ownKeysShim();\n}\n\nif (typeof Array.prototype.flatMap === \"undefined\") {\n\t_flatMapShim();\n}\n\nfunction onlyUnique<T> (value: T, index: number, self: T[]) {\n\treturn self.indexOf(value) === index;\n}\n\n/**\n * The type of the constructor of an object.\n */\nexport type ICtor = new(...params: any[]) => any;\n\ntype IAnyInstancesOf<T extends ICtor[]> = InstanceType<T[number]>;\n\n/**\n * Black magic.\n *\n * Note: Works only in one way.\n *\n * @internal\n */\ntype IUnionToIntersection<U> =\n\t(U extends any ? (k: U) => void : never) extends ((k: infer I) => void) ? I : never;\n\n/**\n * Specifies that the array contains all the instances of specified constructors in order.\n */\nexport type IInstancesArray<Ts extends ICtor[]> = {\n\t[I in keyof Ts]: Ts[I] extends ICtor ? InstanceType<Ts[I]> : never;\n} & Array<InstanceType<Ts[number]>>;\n\nexport const SymbolBases = Symbol.for('extend-bases#bases');\n\n/**\n * Specifies that the object has an array containing instances of all of the bases.\n */\nexport type IHasBasesArray<TBases extends ICtor[]> = {\n\treadonly [SymbolBases]: IInstancesArray<TBases>\n}\n\n/**\n * Specifies that the object is an intersection of all of the bases, and has an array containing all of the base instances.\n */\nexport type IHasBases<TBases extends ICtor[]> =\n\tIUnionToIntersection<IAnyInstancesOf<TBases>> &\n\tIHasBasesArray<TBases>;\n\nfunction extendStatics (derived: any, base: any): any {\n\tfor (const p of Reflect.ownKeys(base)) {\n\t\tif (p === \"length\" || p === \"prototype\" || p === \"name\") {\n\t\t\tcontinue;\n\t\t}\n\t\t// Avoid bugs when hasOwnProperty is shadowed\n\t\tif (Object.prototype.hasOwnProperty.call(base, p)) {\n\t\t\tderived[p] = base[p];\n\t\t}\n\t}\n}\n\nfunction setPrototypeToProxy<TBases extends ICtor[]> (\n\tself: (...args: any[]) => void,\n\tbaseClasses: TBases\n) {\n\tconst proto = self.prototype;\n\tfor (let i = baseClasses.length - 1; i >= 0; i--) {\n\t\tconst basePrototype = baseClasses[i].prototype;\n\t\textendStatics(self, baseClasses[i]);\n\t\tfor (const nextKey of Reflect.ownKeys(basePrototype)) {\n\t\t\t// Avoid bugs when hasOwnProperty is shadowed\n\t\t\tif (nextKey !== SymbolBases && Object.prototype.hasOwnProperty.call(basePrototype, nextKey)) {\n\t\t\t\tconst val = basePrototype[nextKey];\n\t\t\t\t// Only transfer functions\n\t\t\t\tif (nextKey !== \"constructor\" && typeof val === \"function\") {\n\t\t\t\t\t// Make sure that the function is only called on the specific base.\n\t\t\t\t\t// @ts-ignore\n\t\t\t\t\tproto[nextKey] = function (this: IHasBases<TBases>, ...args: any[]): any {\n\t\t\t\t\t\treturn val.apply(this[SymbolBases][i], args);\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\t// proto.constructor = self;\n\t Object.freeze(proto);\n// \tself.prototype = proto;\n\treturn self as unknown as new() => object;\n}\n\n/**\n * Returns a class which when \"inherits\" from all of the base classes.\n *\n * This function isolates the method calls on the bases, so if any of the 2 bases share a property or method with the same name then, they will not affect each other.\n *\n * When you access a property or method directly on `this` and not on `this[SymbolBases]`, and it doesn't exist on the `this` instance, then the first base class with the method/property will be the one given precedence and its method/property will be the one given.\n *\n * The returned class must be initialized with the <i><b>instances</b></i> of each of the respective base classes\n *\n * Note: There is a caveat in setting properties, if you directly set a property in the constructor and the super class has the same property name then it will be overwritten, and the super class will refer to the same property, and things may break.\n * This is not due to this library, this is due to the inherent dynamic nature of JavaScript.\n * But, this library isolates the derived and base classes, ie prevents collision of their properties and methods.\n * Thus, this problem can be avoided by using the <code>defineProperties</code> method from this library, if you use the <code>[SymbolBases]</code> methods as well.\n * @param baseClasses The base classes to be inherited.\n * @return A constructor taking in the *instances* of the base classes.\n *\n * @example\n * class Activatable {\n *     val: boolean;\n *\n *     constructor (val: boolean) {\n *         this.val = val;\n *     }\n *\n *     activate () {\n *         this.val = true;\n *     }\n *\n *     deactivate () {\n *         this.val = false;\n *     }\n *\n *     get (): boolean {\n *         return this.val;\n *     }\n * }\n *\n * class Accumulator {\n *     val: number;\n *\n *     constructor (result: number) {\n *         this.val = result;\n *     }\n *\n *     add (val: number) {\n *         this.val += val;\n *     }\n *\n *     get (): number {\n *         return this.val;\n *     }\n * }\n *\n * // Now let’s declare a new class inheriting from both of the classes:\n * class NewClass extends bases(Activatable, Accumulator) {\n *     constructor () {\n *         // To initialize the bases create a new instance of them and pass them to the constructor of the super class, now you will no longer need the `super` keyword.\n *         super(\n *             new Activatable(true),\n *             new Accumulator(0),\n *         );\n *     }\n *\n *     getBoth () {\n *         // To get a specific base use `this[SymbolBases][index]` where index is the index of the base as given in the bases function.\n *         return `Gotten: ${this[SymbolBases][0].get()} ${this[SymbolBases][1].get()}`\n *     }\n * }\n *\n * const n = new NewClass();\n * console.log(n.val); // true: The base given first is given preference.\n * console.log(n.get()); // true: The base given first is given preference, of course.\n * n.add(10);\n * n.deactivate();\n * console.log(n.val, n[SymbolBases][1].val); // false 10: The [SymbolBases] are isolated, one can't affect the other, not directly that is.\n */\nexport function bases<TBases extends ICtor[]> (...baseClasses: TBases):\n\tnew (...baseInstances: IInstancesArray<TBases>) => IHasBases<TBases> {\n\ttype BaseInstances = IInstancesArray<TBases>;\n\ttype Self = IHasBases<TBases>;\n\n\tclass Self2 extends classWithoutCallParentConstructor(baseClasses[0]) {\n\n\t\tconstructor (...baseInstances: BaseInstances) {\n\t\t\tsuper();\n\n\t\t\t/*\n\t\t\tReflect.defineProperty(this, 'bases', {\n\t\t\t\tconfigurable: false,\n\t\t\t\tenumerable: false,\n\t\t\t\tvalue: baseInstances,\n\t\t\t\twritable: false,\n\t\t\t});\n\t\t\t */\n\n\t\t\tReflect.defineProperty(this, SymbolBases, {\n\t\t\t\tconfigurable: false,\n\t\t\t\tenumerable: false,\n\t\t\t\tvalue: baseInstances,\n\t\t\t\twritable: false,\n\t\t\t});\n\n\t\t\treturn new Proxy(this as any as Self, {\n\n\t\t\t\tisExtensible (target: Self): boolean {\n\t\t\t\t\treturn Reflect.isExtensible(target) && target[SymbolBases].every(Reflect.isExtensible);\n\t\t\t\t},\n\t\t\t\tpreventExtensions (target: Self): boolean {\n\t\t\t\t\treturn Reflect.preventExtensions(target) && target[SymbolBases].every(Reflect.preventExtensions);\n\t\t\t\t},\n\t\t\t\tgetOwnPropertyDescriptor (target: Self, p: string | number | symbol): PropertyDescriptor | undefined {\n\t\t\t\t\tlet pd: PropertyDescriptor | undefined = Reflect.getOwnPropertyDescriptor(target, p);\n\t\t\t\t\tfor (const base of target[SymbolBases]) {\n\t\t\t\t\t\tif (pd != null) {\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tpd = Reflect.getOwnPropertyDescriptor(base, p);\n\t\t\t\t\t}\n\t\t\t\t\treturn pd;\n\t\t\t\t},\n\t\t\t\thas (target: Self, p: string | number | symbol): boolean {\n\t\t\t\t\treturn Reflect.has(target, p) || target[SymbolBases].some(base => Reflect.has(base, p));\n\t\t\t\t},\n\t\t\t\tget (target: Self, p: string | number | symbol, receiver): any {\n//\t\t\t\t\tif (__DEV__)\n//\t\t\t\t\t{\n//\t\t\t\t\t\tconsole.log('target', p, p in target, Object.getOwnPropertyDescriptor(target, p));\n//\t\t\t\t\t\tconsole.log('receiver', p, p in receiver, Object.getOwnPropertyDescriptor(receiver, p));\n//\t\t\t\t\t}\n\n\t\t\t\t\tif (p in target) {\n\t\t\t\t\t\t// @ts-ignore\n\t\t\t\t\t\treturn target[p];\n\t\t\t\t\t}\n\t\t\t\t\tfor (const base of target[SymbolBases]) {\n\n\t\t\t\t\t\t//if (__DEV__) console.log('base', p in base);\n\n\t\t\t\t\t\tif (p in base) {\n\t\t\t\t\t\t\t// @ts-ignore\n\t\t\t\t\t\t\treturn base[p];\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\t// @ts-ignore\n\t\t\t\t\treturn target[p];\n\t\t\t\t},\n\t\t\t\tset (target: Self, p: string | number | symbol, value: any): boolean {\n\t\t\t\t\tif (p in target) {\n\t\t\t\t\t\t// @ts-ignore\n\t\t\t\t\t\ttarget[p] = value;\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t\tfor (const base of target[SymbolBases]) {\n\t\t\t\t\t\tif (p in base) {\n\t\t\t\t\t\t\t// @ts-ignore\n\t\t\t\t\t\t\tbase[p] = value;\n\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\t// @ts-ignore\n\t\t\t\t\ttarget[p] = value;\n\t\t\t\t\treturn true;\n\t\t\t\t},\n\t\t\t\tdeleteProperty (target: Self, p: string | number | symbol): boolean {\n\t\t\t\t\tif (p in target) {\n\t\t\t\t\t\treturn Reflect.deleteProperty(target, p);\n\t\t\t\t\t}\n\t\t\t\t\tfor (const base of target[SymbolBases]) {\n\t\t\t\t\t\tif (p in base) {\n\t\t\t\t\t\t\treturn Reflect.deleteProperty(base, p);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\treturn Reflect.deleteProperty(target, p);\n\t\t\t\t},\n\t\t\t\tenumerate (target: Self): PropertyKey[] {\n\t\t\t\t\treturn Reflect.ownKeys(target).concat(target[SymbolBases].flatMap(Reflect.ownKeys)).filter(onlyUnique);\n\t\t\t\t},\n\t\t\t\t// @ts-ignore\n\t\t\t\townKeys (target: Self): PropertyKey[] {\n\t\t\t\t\treturn Reflect.ownKeys(target).concat(target[SymbolBases].flatMap(Reflect.ownKeys)).filter(onlyUnique);\n\t\t\t\t},\n\t\t\t\t// If you want to define a property then you certainly don't want it to be on the base class.\n\t\t\t\tdefineProperty (target: Self, p: string | number | symbol, attributes: PropertyDescriptor): boolean {\n\t\t\t\t\treturn Reflect.defineProperty(target, p, attributes);\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t}\n\n\tsetPrototypeToProxy(Self2 as any, baseClasses);\n\n\treturn Self2 as unknown as new(...baseInstances: BaseInstances) => IHasBases<TBases>;\n}\n\n/**\n * Defines the properties on the given object, the key represents the name of the property and the value as the, well, value.\n * Moreover, if the property name if prefixed with `readonly` then the property will be set to be readonly, ie non-writable, ie any attempts to edit it in strict mode will fail with a `TypeError`.\n *\n * Use this function to set the properties of the objects inheriting from multiple base classes.\n *\n * @param v The object on which to define the properties\n * @param props A object with the keys as the property names and the values as the values of the properties.\n *\n * @example\n * // In the constructor\n * defineProperties(this, {\n *     <prop>: <value>, // Define a property on `this` with the name <prop> and value <value>\n *     \"readonly <>\": <value>, // Define a readonly property on `this` with the name <prop> and value <value>, readonly ie any attempts to edit it in strict mode will fail with a TypeError.\n * });\n */\nexport function defineProperties<T extends object> (v: T, props: { [key: string]: any }) {\n\tfor (const prop of Reflect.ownKeys(props)) {\n\t\tif (typeof prop !== \"string\") {\n\t\t\tcontinue;\n\t\t}\n\t\tlet propName = prop;\n\t\tlet isWritable = true;\n\t\tif (prop.startsWith(\"readonly \")) {\n\t\t\tisWritable = false;\n\t\t\tpropName = prop.slice(9);\n\t\t}\n\n\t\tReflect.defineProperty(v, propName, {\n\t\t\tvalue: props[prop],\n\t\t\twritable: isWritable,\n\t\t\tconfigurable: true,\n\t\t\tenumerable: true,\n\t\t})\n\t}\n}\n\n/**\n * Checks if the value `v` is an instance of the class `cls`.\n * This function takes into account the multiple base classes.\n *\n * @param v The object to check.\n * @param cls The constructor of the class to check.\n * @return Whether or not the object `v` is an instance of the given class `cls`.\n */\nexport function isInstanceOf<T extends object, TBase extends ICtor> (v: T, cls: TBase): boolean {\n\tif (v instanceof cls) {\n\t\treturn true;\n\t}\n\t// @ts-ignore\n\tif (SymbolBases in v && Array.isArray(v[SymbolBases])) {\n\t\t// @ts-ignore\n\t\tfor (const base of v[SymbolBases]) {\n\t\t\tif (isInstanceOf(base, cls)) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\t}\n\n\treturn false;\n}\n\nexport default bases\n"],"names":["onlyUnique","value","index","self","indexOf","_ownKeysShim","Array","prototype","flatMap","_flatMapShim","SymbolBases","for","extendStatics","derived","p","Reflect","ownKeys","base","Object","hasOwnProperty","call","classWithoutCallParentConstructor","baseClasses","baseInstances","defineProperty","this","enumerable","writable","Proxy","isExtensible","target","every","i","length","basePrototype","nextKey","val","proto","args","apply"],"mappings":"shBAYA,SAAIA,WAAaC,EAASC,EAAQC,GACjC,OAAAA,EAAAC,QAAYH,KAAAC,CACZ,2BAbDG,EAAAA,YAGS,IAATC,MAAAC,UAASC,SAITC,EAAAA,aASQC,SAAmBC,IAAA,+BAC1BC,cAAAC,EAAAA,GA0BK,IAAA,MAAAC,KAAAC,QAAAC,QAAAC,GAiB0BH,WAA1BA,GAAkC,cAARA,YAAQA,GAoHxBI,OAAAX,UAAqDY,eAAAC,KAAAH,EAAAH,yDAyE/DO,EAAAA,kCAAAC,EAAA,oBACAC,GAUD,uBARAC,eAAAC,KAAAf,EAAA,eAAA,EAGEgB,YAHF,EAIEzB,MAJFsB,EAKEI,UAAAA,IAGF,IAAAC,MAAAH,KAAA,CACAI,aAAOC,GACPf,QAAAc,aAAAC,IAAAA,EAAApB,GAAAqB,MAAAhB,QAAAc,uQAFA,sJAAA,uGAAA,sKAAA,kPAhDA1B,SAAAA,oBAAAA,EAAAA,+BAEQ6B,EAAAV,EAAAW,OAAA,EAAAD,GAAA,EAAAA,IAAA,CACN,MAAAE,EAAAZ,EAAAA,GAAAf,gCAED,IAAA,MAAA4B,KAAApB,QAAAC,QAAAkB,GACD,GAAAC,IAAAzB,GAAAQ,OAAAX,UAAAY,eAAAC,KAAAc,EAAAC,GAAA,iCAKI,mBAAAC,IASHC,KAAA,YAAAC,GACA,OAAAF,EAAAG,MAAAd,KAAAf,GAAAsB,GAAAM,IAOC,EAIFD,OAAAA,OAAAA"}