/
list.ts
107 lines (88 loc) · 1.95 KB
/
list.ts
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
import * as EventEmitter from 'events';
import * as _ from 'lodash';
import {
TClass,
IInstance,
} from './mixins';
import {
Node,
INode,
INodeEventsList,
INodeEventData,
TNode,
} from './node';
export type TList = IList<TNode, IListEventsList>;
export interface IListEventsList extends INodeEventsList {
/**
* Emits, when called `node.destroy()`.
*/
destroyed: INodeEventData;
}
export interface IList<IN, IEventsList extends IListEventsList> extends INode<IEventsList> {
/**
* Node class for simple adding new item to list.
*/
Node: TClass<IN>;
/**
* Container for list.
*/
nodes: { [id:string]: IN };
/**
* Add item to list.
*/
add(node: IN): this;
/**
* Unsafe. Adding `Emit` event for node events.
*/
wrap(node: IN): this;
/**
* Remove node from list.
*/
remove(node: IN): this;
/**
* Create node with string id.
*/
create(id?: string): IN;
}
/**
* Mixin your Node with List functionality.
* @example
* ```typescript
*
* import { mixin, TList } from 'ancient-mixins/lib/List';
* import { TClass } from 'ancient-mixins/lib/mixins';
* const MixedList: TClass<TList> = mixin(Node);
* ```
*/
export function mixin<T extends TClass<IInstance>>(
superClass: T,
): any {
return class List extends superClass {
public Node = Node;
nodes = {};
add(node) {
this.nodes[node.id] = node;
this.wrap(node);
return this;
}
wrap(node) {
const listener = ({ eventName, data }) => {
this.emit(eventName, data);
};
node.on('emit', listener);
this.on('destroyed', () => node.off('emit', listener));
return this;
}
remove(node) {
if (this.nodes[node.id]) {
delete this.nodes[node.id];
}
return this;
}
};
}
export const MixedList: TClass<TList> = mixin(Node);
/**
* Already mixed class. Plug and play.
*/
export class List extends MixedList {}