Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 | 4x 4x 8x 8x 8x 8x 8x 1x 2x 13x 6x 6x 6x 8x 6x 4x 4x 8x 11x 11x 6x 4x 2x | import {
XGroup,
XGroupSpec,
XInit,
XGroupEvent,
XUnsubsribe,
WithXEventsBySpec,
} from '../typing';
import { defineStaticProperies } from '../utils';
export function createXGroup<
D extends string,
G extends XGroupSpec,
I extends XInit,
>(
descr: D,
spec: G,
init?: I,
): XGroup<D, G, I> {
let listeners = 0;
const keys = Object.keys(spec);
const path = init ? init.group.$path().concat(init.name) : [] as string[];
const group = defineStaticProperies({} as XGroup<D, G, I>, {
$use: (xevents?: WithXEventsBySpec<G, true>) => {
return overrideXEvents(group, xevents);
},
$observed: () => (listeners > 0) && (!init || init.group.$observed()),
$keys: () => keys,
$descr: () => descr,
$clone: <NI extends XInit = I>(ninit?: NI) => {
return createXGroup(descr, spec, (ninit || init) as NI)
},
$path: () => path,
$name: () => init?.name,
$group: () => init?.group,
$on: (listener: (xevt: XGroupEvent<G>) => void): XUnsubsribe => {
const list = [] as XUnsubsribe[];
listeners++;
keys.forEach(key => {
list.push(group[key].$on(listener));
});
return () => {
listeners--;
list.forEach(callUnsubsribe);
};
},
});
return keys.reduce((group, name) => {
Object.defineProperty(group, name, {
value: spec[name].$clone({
name,
group,
}),
enumerable: true,
configurable: false,
writable: false,
});
return group;
}, group);
}
function callUnsubsribe(fn: XUnsubsribe) {
fn();
}
function overrideXEvents(group: XGroup<any, any, any>, xevents?: WithXEventsBySpec<any, true>) {
if (xevents == null) {
return group;
}
return group.$keys().reduce((xover, key: string) => {
const orig = group[key];
const extra = xevents[key];
if (extra === void 0) {
xover[key] = orig;
} else if (orig.$keys !== void 0) {
xover[key] = overrideXEvents(group[key], extra as any);
} else {
xover[key] = function (data: object) {
orig(data);
try {
(extra as any).call(data);
} catch (err) {
console.error(err);
}
};
}
return xover;
}, {});
}
export function isXGroup(val: any): val is XGroup<string, XGroupSpec, XInit> {
return val ? typeof val.$observed === 'function' : false;
}
|