source: node_modules/ts-mixer/dist/cjs/util.js

main
Last change on this file was d24f17c, checked in by Aleksandar Panovski <apano77@…>, 15 months ago

Initial commit

  • Property mode set to 100644
File size: 3.8 KB
RevLine 
[d24f17c]1"use strict";
2Object.defineProperty(exports, "__esModule", { value: true });
3exports.flatten = exports.unique = exports.hardMixProtos = exports.nearestCommonProto = exports.protoChain = exports.copyProps = void 0;
4/**
5 * Utility function that works like `Object.apply`, but copies getters and setters properly as well. Additionally gives
6 * the option to exclude properties by name.
7 */
8const copyProps = (dest, src, exclude = []) => {
9 const props = Object.getOwnPropertyDescriptors(src);
10 for (let prop of exclude)
11 delete props[prop];
12 Object.defineProperties(dest, props);
13};
14exports.copyProps = copyProps;
15/**
16 * Returns the full chain of prototypes up until Object.prototype given a starting object. The order of prototypes will
17 * be closest to farthest in the chain.
18 */
19const protoChain = (obj, currentChain = [obj]) => {
20 const proto = Object.getPrototypeOf(obj);
21 if (proto === null)
22 return currentChain;
23 return (0, exports.protoChain)(proto, [...currentChain, proto]);
24};
25exports.protoChain = protoChain;
26/**
27 * Identifies the nearest ancestor common to all the given objects in their prototype chains. For most unrelated
28 * objects, this function should return Object.prototype.
29 */
30const nearestCommonProto = (...objs) => {
31 if (objs.length === 0)
32 return undefined;
33 let commonProto = undefined;
34 const protoChains = objs.map(obj => (0, exports.protoChain)(obj));
35 while (protoChains.every(protoChain => protoChain.length > 0)) {
36 const protos = protoChains.map(protoChain => protoChain.pop());
37 const potentialCommonProto = protos[0];
38 if (protos.every(proto => proto === potentialCommonProto))
39 commonProto = potentialCommonProto;
40 else
41 break;
42 }
43 return commonProto;
44};
45exports.nearestCommonProto = nearestCommonProto;
46/**
47 * Creates a new prototype object that is a mixture of the given prototypes. The mixing is achieved by first
48 * identifying the nearest common ancestor and using it as the prototype for a new object. Then all properties/methods
49 * downstream of this prototype (ONLY downstream) are copied into the new object.
50 *
51 * The resulting prototype is more performant than softMixProtos(...), as well as ES5 compatible. However, it's not as
52 * flexible as updates to the source prototypes aren't captured by the mixed result. See softMixProtos for why you may
53 * want to use that instead.
54 */
55const hardMixProtos = (ingredients, constructor, exclude = []) => {
56 var _a;
57 const base = (_a = (0, exports.nearestCommonProto)(...ingredients)) !== null && _a !== void 0 ? _a : Object.prototype;
58 const mixedProto = Object.create(base);
59 // Keeps track of prototypes we've already visited to avoid copying the same properties multiple times. We init the
60 // list with the proto chain below the nearest common ancestor because we don't want any of those methods mixed in
61 // when they will already be accessible via prototype access.
62 const visitedProtos = (0, exports.protoChain)(base);
63 for (let prototype of ingredients) {
64 let protos = (0, exports.protoChain)(prototype);
65 // Apply the prototype chain in reverse order so that old methods don't override newer ones.
66 for (let i = protos.length - 1; i >= 0; i--) {
67 let newProto = protos[i];
68 if (visitedProtos.indexOf(newProto) === -1) {
69 (0, exports.copyProps)(mixedProto, newProto, ['constructor', ...exclude]);
70 visitedProtos.push(newProto);
71 }
72 }
73 }
74 mixedProto.constructor = constructor;
75 return mixedProto;
76};
77exports.hardMixProtos = hardMixProtos;
78const unique = (arr) => arr.filter((e, i) => arr.indexOf(e) == i);
79exports.unique = unique;
80const flatten = (arr) => arr.length === 0
81 ? []
82 : arr.length === 1
83 ? arr[0]
84 : arr.reduce((a1, a2) => [...a1, ...a2]);
85exports.flatten = flatten;
Note: See TracBrowser for help on using the repository browser.