| 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
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141 |
52x
46x
46x
88x
88x
88x
88x
88x
104x
86x
20x
6x
6x
58x
2x
56x
30x
54x
52x
28x
60x
59x
58x
59x
59x
60x
38x
35x
36x
35x
42x
34x
34x
28x
6x
2x
4x
4x
4x
3x
29x
6x
1x
2x
2x
2x
2x
2x
2x
1x
1x
1x
1x
1x
2x
21x
5x
| import cartesian from 'cartesian';
import { Component } from 'react';
import { AppCtx } from '@tao.js/core';
import { noop, normalizeClean } from './helpers';
const wrappedHandler = (ComponentHandler = null, props, _adapter) => (
tao,
data
) => {
_adapter._current = {
ComponentHandler,
tao,
props: {
...props,
...data
}
};
_adapter._reactors.forEach(notify => notify());
};
class Adapter {
constructor(TAO) {
this._tao = TAO;
this._current = null;
this._default = {};
this._reactors = new Map();
this._components = new Map();
}
get current() {
return this._current;
}
get defaultCtx() {
return { ...this._default };
}
set defaultCtx({ t, term, a, action, o, orient } = {}) {
this._default = normalizeClean({ t, term, a, action, o, orient });
}
setDefaultCtx({ t, term, a, action, o, orient } = {}) {
this.defaultCtx = { t, term, a, action, o, orient };
return this;
}
addComponentHandler(
{ t, term, a, action, o, orient } = {},
ComponentHandler,
props
) {
if (
ComponentHandler &&
!(
ComponentHandler instanceof Component ||
ComponentHandler instanceof Function
)
) {
throw new Error(
'cannot add a Component handler that is not a React.Component or Function'
);
}
const tao = normalizeClean({ t, term, a, action, o, orient });
const ctx = Object.assign(this.defaultCtx, tao);
const permutations = cartesian(ctx);
if (!permutations.length) {
return this;
}
const handler = wrappedHandler(ComponentHandler, props, this);
if (!this._components.has(ComponentHandler)) {
this._components.set(ComponentHandler, {
handlers: new Map(),
index: new Map()
});
}
const componentHandlers = this._components.get(ComponentHandler);
permutations.forEach(tao => {
const { term, action, orient } = tao;
const acKey = AppCtx.getKey(term, action, orient);
if (!componentHandlers.index.has(acKey)) {
componentHandlers.index.set(acKey, new AppCtx(term, action, orient));
}
const ac = componentHandlers.index.get(acKey);
if (!componentHandlers.handlers.has(ac)) {
componentHandlers.handlers.set(ac, handler);
this._tao.addInlineHandler(ac.unwrapCtx(), handler);
}
});
return this;
}
removeComponentHandler(
{ t, term, a, action, o, orient } = {},
ComponentHandler
) {
if (!this._components.has(ComponentHandler)) {
return this;
}
const componentHandlers = this._components.get(ComponentHandler);
const tao = normalizeClean({ t, term, a, action, o, orient });
if (!tao.term && !tao.action && !tao.orient) {
// remove all handlers
for (let [ac, handler] of componentHandlers.handlers) {
this._tao.removeInlineHandler(ac.unwrapCtx(), handler);
}
this._components.delete(ComponentHandler);
return this;
}
const ctx = Object.assign(this.defaultCtx, tao);
const permutations = cartesian(ctx);
permutations.forEach(({ term: t, action: a, orient: o }) => {
const acKey = AppCtx.getKey(t, a, o);
const ac = componentHandlers.index.get(acKey);
if (!ac) {
return;
}
componentHandlers.index.delete(acKey);
// currently cannot hit this guard
// if (!componentHandlers.handlers.has(ac)) {
// return;
// }
const handler = componentHandlers.handlers.get(ac);
this._tao.removeInlineHandler(ac.unwrapCtx(), handler);
componentHandlers.handlers.delete(ac);
});
return this;
}
registerReactor(reactor, notify = noop) {
this._reactors.set(reactor, notify);
}
unregisterReactor(reactor) {
this._reactors.delete(reactor);
}
}
export default Adapter;
|