epos-unit 1.16.0 → 1.18.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/epos-unit.d.ts +35 -32
- package/dist/epos-unit.js +294 -196
- package/dist/epos-unit.js.map +1 -1
- package/package.json +7 -6
- package/src/epos-unit.ts +192 -128
package/dist/epos-unit.d.ts
CHANGED
|
@@ -1,15 +1,22 @@
|
|
|
1
|
-
import
|
|
2
|
-
import { Cls, Obj, Arr } from 'dropcap/types';
|
|
1
|
+
import type { Arr, Cls, Obj } from 'dropcap/types';
|
|
3
2
|
import { createLog } from 'dropcap/utils';
|
|
4
|
-
|
|
5
|
-
declare
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
declare const
|
|
11
|
-
|
|
12
|
-
declare
|
|
3
|
+
import 'epos';
|
|
4
|
+
declare global {
|
|
5
|
+
interface ErrorConstructor {
|
|
6
|
+
captureStackTrace(targetObject: object, constructorOpt?: Function): void;
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
export declare const _root_: unique symbol;
|
|
10
|
+
export declare const _parent_: unique symbol;
|
|
11
|
+
export declare const _attached_: unique symbol;
|
|
12
|
+
export declare const _disposers_: unique symbol;
|
|
13
|
+
export declare const _ancestors_: unique symbol;
|
|
14
|
+
export declare const _attachQueue_: unique symbol;
|
|
15
|
+
export type Node<T> = Unit<T> | Obj | Arr;
|
|
16
|
+
export type Versioner<T> = {
|
|
17
|
+
[version: number]: (this: T) => void;
|
|
18
|
+
};
|
|
19
|
+
export declare class Unit<TRoot = unknown> {
|
|
13
20
|
/**
|
|
14
21
|
* Lifecycle method called when the unit is attached to the state tree.
|
|
15
22
|
*/
|
|
@@ -19,6 +26,7 @@ declare class Unit<TRoot = unknown> {
|
|
|
19
26
|
*/
|
|
20
27
|
[epos.state.DETACH]: () => void;
|
|
21
28
|
'@': string;
|
|
29
|
+
id: string;
|
|
22
30
|
log: ReturnType<typeof createLog>;
|
|
23
31
|
[':version']?: number;
|
|
24
32
|
[_root_]?: TRoot;
|
|
@@ -26,42 +34,37 @@ declare class Unit<TRoot = unknown> {
|
|
|
26
34
|
[_attached_]?: boolean;
|
|
27
35
|
[_disposers_]?: Set<() => void>;
|
|
28
36
|
[_ancestors_]?: Map<Cls, unknown>;
|
|
29
|
-
[
|
|
37
|
+
[_attachQueue_]?: (() => void)[];
|
|
38
|
+
static defineVersioner<T extends Unit>(this: Cls<T>, versioner: Versioner<T>): Versioner<T>;
|
|
30
39
|
constructor(parent: Unit<TRoot> | null);
|
|
31
40
|
/**
|
|
32
|
-
*
|
|
41
|
+
* Get the root unit of the current unit's tree.
|
|
33
42
|
* The result is cached for subsequent calls.
|
|
34
43
|
*/
|
|
35
44
|
get $(): TRoot | (undefined & TRoot);
|
|
36
45
|
/**
|
|
37
|
-
*
|
|
38
|
-
* The result is cached for subsequent calls.
|
|
46
|
+
* A wrapper around MobX's `autorun` that automatically disposes the reaction when the unit is detached.
|
|
39
47
|
*/
|
|
40
|
-
|
|
48
|
+
autorun(...args: Parameters<typeof epos.libs.mobx.autorun>): import("mobx").IReactionDisposer;
|
|
41
49
|
/**
|
|
42
|
-
* A wrapper around MobX's `
|
|
43
|
-
* the reaction when the unit is detached.
|
|
50
|
+
* A wrapper around MobX's `reaction` that automatically disposes the reaction when the unit is detached.
|
|
44
51
|
*/
|
|
45
|
-
|
|
52
|
+
reaction(...args: Parameters<typeof epos.libs.mobx.reaction>): import("mobx").IReactionDisposer;
|
|
46
53
|
/**
|
|
47
|
-
* A wrapper around
|
|
48
|
-
* the reaction when the unit is detached.
|
|
54
|
+
* A wrapper around `setTimeout` that automatically clears the timeout when the unit is detached.
|
|
49
55
|
*/
|
|
50
|
-
|
|
56
|
+
setTimeout(...args: Parameters<typeof setTimeout>): NodeJS.Timeout;
|
|
51
57
|
/**
|
|
52
|
-
* A wrapper around `
|
|
53
|
-
* when the unit is detached.
|
|
58
|
+
* A wrapper around `setInterval` that automatically clears the interval when the unit is detached.
|
|
54
59
|
*/
|
|
55
|
-
|
|
60
|
+
setInterval(...args: Parameters<typeof setInterval>): NodeJS.Timeout;
|
|
56
61
|
/**
|
|
57
|
-
*
|
|
58
|
-
* when the unit is detached.
|
|
62
|
+
* Create an error for code paths that are logically unreachable.
|
|
59
63
|
*/
|
|
60
|
-
|
|
64
|
+
never(message?: string): Error;
|
|
61
65
|
/**
|
|
62
|
-
*
|
|
66
|
+
* Find the closest ancestor unit of a given type.
|
|
67
|
+
* The result is cached for subsequent calls.
|
|
63
68
|
*/
|
|
64
|
-
|
|
69
|
+
closest<T extends Unit>(Ancestor: Cls<T>): T | null;
|
|
65
70
|
}
|
|
66
|
-
|
|
67
|
-
export { type Node, Unit, _ancestors_, _attached_, _disposers_, _parent_, _pendingAttachFns_, _root_ };
|
package/dist/epos-unit.js
CHANGED
|
@@ -1,215 +1,313 @@
|
|
|
1
|
-
|
|
2
|
-
import
|
|
3
|
-
import
|
|
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
|
-
|
|
1
|
+
import { createLog, is } from 'dropcap/utils';
|
|
2
|
+
import 'epos';
|
|
3
|
+
import { customAlphabet } from 'nanoid';
|
|
4
|
+
export const _root_ = Symbol('root');
|
|
5
|
+
export const _parent_ = Symbol('parent');
|
|
6
|
+
export const _attached_ = Symbol('attached');
|
|
7
|
+
export const _disposers_ = Symbol('disposers');
|
|
8
|
+
export const _ancestors_ = Symbol('ancestors');
|
|
9
|
+
export const _attachQueue_ = Symbol('pendingAttachHooks');
|
|
10
|
+
const nanoid = customAlphabet('abcdefghijklmnopqrstuvwxyz0123456789', 10);
|
|
11
|
+
export class Unit {
|
|
12
|
+
static defineVersioner(versioner) {
|
|
13
|
+
return versioner;
|
|
14
|
+
}
|
|
15
|
+
constructor(parent) {
|
|
16
|
+
this.id = nanoid();
|
|
17
|
+
this[_parent_] = parent;
|
|
18
|
+
}
|
|
19
|
+
// ---------------------------------------------------------------------------
|
|
20
|
+
// ATTACH
|
|
21
|
+
// ---------------------------------------------------------------------------
|
|
22
|
+
/**
|
|
23
|
+
* Lifecycle method called when the unit is attached to the state tree.
|
|
24
|
+
*/
|
|
25
|
+
[epos.state.ATTACH]() {
|
|
26
|
+
// Setup logger
|
|
27
|
+
let log = createLog(this['@']);
|
|
28
|
+
Reflect.defineProperty(this, 'log', { configurable: true, get: () => log, set: v => (log = v) });
|
|
29
|
+
// Apply versioner
|
|
30
|
+
void (() => {
|
|
31
|
+
const versioner = Reflect.get(this.constructor, 'versioner');
|
|
32
|
+
if (!is.object(versioner))
|
|
33
|
+
return;
|
|
34
|
+
const asc = (v1, v2) => v1 - v2;
|
|
35
|
+
const versions = Object.keys(versioner).filter(is.numeric).map(Number).sort(asc);
|
|
36
|
+
if (versions.length === 0)
|
|
37
|
+
return;
|
|
38
|
+
epos.state.transaction(() => {
|
|
39
|
+
for (const version of versions) {
|
|
40
|
+
if (is.number(this[':version']) && this[':version'] >= version)
|
|
41
|
+
continue;
|
|
42
|
+
const versionFn = versioner[version];
|
|
43
|
+
if (!is.function(versionFn))
|
|
44
|
+
continue;
|
|
45
|
+
versionFn.call(this);
|
|
46
|
+
this[':version'] = version;
|
|
47
|
+
}
|
|
48
|
+
});
|
|
49
|
+
})();
|
|
50
|
+
// Setup state
|
|
51
|
+
void (() => {
|
|
52
|
+
const descriptor = Reflect.getOwnPropertyDescriptor(this.constructor.prototype, 'state');
|
|
53
|
+
if (!descriptor || !descriptor.get)
|
|
54
|
+
return;
|
|
55
|
+
const value = descriptor.get.call(this);
|
|
56
|
+
if (!is.object(value))
|
|
57
|
+
throw new Error(`'state' getter return an object`);
|
|
58
|
+
const state = epos.state.create(value);
|
|
59
|
+
Reflect.defineProperty(state, epos.state.PARENT, { configurable: true, value: this });
|
|
60
|
+
Reflect.defineProperty(this, 'state', { enumerable: true, get: () => state });
|
|
61
|
+
})();
|
|
62
|
+
// Setup inert
|
|
63
|
+
void (() => {
|
|
64
|
+
const descriptor = Reflect.getOwnPropertyDescriptor(this.constructor.prototype, 'inert');
|
|
65
|
+
if (!descriptor || !descriptor.get)
|
|
66
|
+
return;
|
|
67
|
+
const value = descriptor.get.call(this);
|
|
68
|
+
if (!is.object(value))
|
|
69
|
+
throw new Error(`'inert' getter return an object`);
|
|
70
|
+
Reflect.defineProperty(this, 'inert', { enumerable: true, get: () => value });
|
|
71
|
+
})();
|
|
72
|
+
// Prepare properties for the whole prototype chain:
|
|
73
|
+
// - Create components for methods ending with `View`
|
|
74
|
+
// - Bind all other methods to the unit instance
|
|
75
|
+
// - Turn getters into MobX computed properties
|
|
76
|
+
for (const prototype of getPrototypes(this)) {
|
|
77
|
+
const descriptors = Object.getOwnPropertyDescriptors(prototype);
|
|
78
|
+
for (const [key, descriptor] of Object.entries(descriptors)) {
|
|
79
|
+
// Skip constructor and already defined properties
|
|
80
|
+
if (key === 'constructor')
|
|
81
|
+
continue;
|
|
82
|
+
if (this.hasOwnProperty(key))
|
|
83
|
+
continue;
|
|
84
|
+
// Create components for methods ending with `View`
|
|
85
|
+
if (is.function(descriptor.value) && key.endsWith('View')) {
|
|
86
|
+
let View = createView(this, key, descriptor.value.bind(this));
|
|
87
|
+
Reflect.defineProperty(this, key, { configurable: true, get: () => View, set: v => (View = v) });
|
|
88
|
+
}
|
|
89
|
+
// Bind all other methods to the unit instance
|
|
90
|
+
else if (is.function(descriptor.value)) {
|
|
91
|
+
let method = descriptor.value.bind(this);
|
|
92
|
+
Reflect.defineProperty(this, key, {
|
|
93
|
+
configurable: true,
|
|
94
|
+
get: () => method,
|
|
95
|
+
set: v => (method = v),
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
// Turn getters into MobX computed properties
|
|
99
|
+
else if (descriptor.get) {
|
|
100
|
+
const getter = descriptor.get;
|
|
101
|
+
const computed = epos.libs.mobx.computed(() => getter.call(this));
|
|
102
|
+
Reflect.defineProperty(this, key, {
|
|
103
|
+
configurable: true,
|
|
104
|
+
get: () => computed.get(),
|
|
105
|
+
set: descriptor.set,
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
// Queue attach method.
|
|
111
|
+
// Do not execute `attach` methods immediately, but rather queue them on the highest unattached ancestor.
|
|
112
|
+
// This way `attach` methods are called after all versioners have been applied in the entire subtree.
|
|
113
|
+
const attach = Reflect.get(this, 'attach');
|
|
114
|
+
if (is.function(attach)) {
|
|
115
|
+
const head = findUnattachedRoot(this);
|
|
116
|
+
if (!head)
|
|
117
|
+
throw this.never();
|
|
118
|
+
ensure(head, _attachQueue_, () => []);
|
|
119
|
+
head[_attachQueue_].push(() => attach.call(this));
|
|
120
|
+
}
|
|
121
|
+
// Release attach queue
|
|
122
|
+
if (this[_attachQueue_]) {
|
|
123
|
+
this[_attachQueue_].forEach(attach => attach());
|
|
124
|
+
delete this[_attachQueue_];
|
|
46
125
|
}
|
|
47
|
-
|
|
126
|
+
// Mark as attached
|
|
127
|
+
Reflect.defineProperty(this, _attached_, { configurable: true, get: () => true });
|
|
48
128
|
}
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
129
|
+
// ---------------------------------------------------------------------------
|
|
130
|
+
// DETACH
|
|
131
|
+
// ---------------------------------------------------------------------------
|
|
132
|
+
/**
|
|
133
|
+
* Lifecycle method called when the unit is detached from the state tree.
|
|
134
|
+
*/
|
|
135
|
+
[epos.state.DETACH]() {
|
|
136
|
+
// Run and clear disposers
|
|
137
|
+
if (this[_disposers_]) {
|
|
138
|
+
this[_disposers_].forEach(disposer => disposer());
|
|
139
|
+
this[_disposers_].clear();
|
|
140
|
+
}
|
|
141
|
+
// Clear ancestors cache
|
|
142
|
+
if (this[_ancestors_]) {
|
|
143
|
+
this[_ancestors_].clear();
|
|
144
|
+
}
|
|
145
|
+
// Call detach method
|
|
146
|
+
const detach = Reflect.get(this, 'detach');
|
|
147
|
+
if (is.function(detach))
|
|
148
|
+
detach();
|
|
53
149
|
}
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
150
|
+
// ---------------------------------------------------------------------------
|
|
151
|
+
// ROOT GETTER
|
|
152
|
+
// ---------------------------------------------------------------------------
|
|
153
|
+
/**
|
|
154
|
+
* Get the root unit of the current unit's tree.
|
|
155
|
+
* The result is cached for subsequent calls.
|
|
156
|
+
*/
|
|
157
|
+
get $() {
|
|
158
|
+
ensure(this, _root_, () => findRoot(this));
|
|
159
|
+
return this[_root_];
|
|
60
160
|
}
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
161
|
+
// ---------------------------------------------------------------------------
|
|
162
|
+
// METHODS
|
|
163
|
+
// ---------------------------------------------------------------------------
|
|
164
|
+
/**
|
|
165
|
+
* A wrapper around MobX's `autorun` that automatically disposes the reaction when the unit is detached.
|
|
166
|
+
*/
|
|
167
|
+
autorun(...args) {
|
|
168
|
+
const disposer = epos.libs.mobx.autorun(...args);
|
|
169
|
+
ensure(this, _disposers_, () => new Set());
|
|
170
|
+
this[_disposers_].add(disposer);
|
|
171
|
+
return disposer;
|
|
64
172
|
}
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
this[_disposers_].clear();
|
|
173
|
+
/**
|
|
174
|
+
* A wrapper around MobX's `reaction` that automatically disposes the reaction when the unit is detached.
|
|
175
|
+
*/
|
|
176
|
+
reaction(...args) {
|
|
177
|
+
const disposer = epos.libs.mobx.reaction(...args);
|
|
178
|
+
ensure(this, _disposers_, () => new Set());
|
|
179
|
+
this[_disposers_].add(disposer);
|
|
180
|
+
return disposer;
|
|
74
181
|
}
|
|
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
|
-
|
|
182
|
+
/**
|
|
183
|
+
* A wrapper around `setTimeout` that automatically clears the timeout when the unit is detached.
|
|
184
|
+
*/
|
|
185
|
+
setTimeout(...args) {
|
|
186
|
+
const id = setTimeout(...args);
|
|
187
|
+
ensure(this, _disposers_, () => new Set());
|
|
188
|
+
this[_disposers_].add(() => clearTimeout(id));
|
|
189
|
+
return id;
|
|
190
|
+
}
|
|
191
|
+
/**
|
|
192
|
+
* A wrapper around `setInterval` that automatically clears the interval when the unit is detached.
|
|
193
|
+
*/
|
|
194
|
+
setInterval(...args) {
|
|
195
|
+
const id = setInterval(...args);
|
|
196
|
+
ensure(this, _disposers_, () => new Set());
|
|
197
|
+
this[_disposers_].add(() => clearInterval(id));
|
|
198
|
+
return id;
|
|
199
|
+
}
|
|
200
|
+
/**
|
|
201
|
+
* Create an error for code paths that are logically unreachable.
|
|
202
|
+
*/
|
|
203
|
+
never(message = 'This should never happen') {
|
|
204
|
+
const details = message ? `: ${message}` : '';
|
|
205
|
+
const error = new Error(`[${this['@']}] This should never happen${details}`);
|
|
206
|
+
Error.captureStackTrace(error, this.never);
|
|
207
|
+
return error;
|
|
208
|
+
}
|
|
209
|
+
/**
|
|
210
|
+
* Find the closest ancestor unit of a given type.
|
|
211
|
+
* The result is cached for subsequent calls.
|
|
212
|
+
*/
|
|
213
|
+
closest(Ancestor) {
|
|
214
|
+
// Has cached value? -> Return it
|
|
215
|
+
ensure(this, _ancestors_, () => new Map());
|
|
216
|
+
if (this[_ancestors_].has(Ancestor))
|
|
217
|
+
return this[_ancestors_].get(Ancestor);
|
|
218
|
+
// Find the closest ancestor and cache it
|
|
219
|
+
let cursor = this;
|
|
220
|
+
while (cursor) {
|
|
221
|
+
if (cursor instanceof Ancestor) {
|
|
222
|
+
this[_ancestors_].set(Ancestor, cursor);
|
|
223
|
+
return cursor;
|
|
224
|
+
}
|
|
225
|
+
cursor = getParent(cursor);
|
|
226
|
+
}
|
|
227
|
+
return null;
|
|
104
228
|
}
|
|
105
|
-
return null;
|
|
106
|
-
}
|
|
107
|
-
/**
|
|
108
|
-
* A wrapper around MobX's `autorun` that automatically disposes
|
|
109
|
-
* the reaction when the unit is detached.
|
|
110
|
-
*/
|
|
111
|
-
autorun(...args) {
|
|
112
|
-
const disposer = epos.libs.mobx.autorun(...args);
|
|
113
|
-
ensureProperty(this, _disposers_, () => /* @__PURE__ */ new Set());
|
|
114
|
-
this[_disposers_].add(disposer);
|
|
115
|
-
return disposer;
|
|
116
|
-
}
|
|
117
|
-
/**
|
|
118
|
-
* A wrapper around MobX's `reaction` that automatically disposes
|
|
119
|
-
* the reaction when the unit is detached.
|
|
120
|
-
*/
|
|
121
|
-
reaction(...args) {
|
|
122
|
-
const disposer = epos.libs.mobx.reaction(...args);
|
|
123
|
-
ensureProperty(this, _disposers_, () => /* @__PURE__ */ new Set());
|
|
124
|
-
this[_disposers_].add(disposer);
|
|
125
|
-
return disposer;
|
|
126
|
-
}
|
|
127
|
-
/**
|
|
128
|
-
* A wrapper around `setTimeout` that automatically clears the timeout
|
|
129
|
-
* when the unit is detached.
|
|
130
|
-
*/
|
|
131
|
-
setTimeout(...args) {
|
|
132
|
-
const id = self.setTimeout(...args);
|
|
133
|
-
ensureProperty(this, _disposers_, () => /* @__PURE__ */ new Set());
|
|
134
|
-
this[_disposers_].add(() => self.clearTimeout(id));
|
|
135
|
-
return id;
|
|
136
|
-
}
|
|
137
|
-
/**
|
|
138
|
-
* A wrapper around `setInterval` that automatically clears the interval
|
|
139
|
-
* when the unit is detached.
|
|
140
|
-
*/
|
|
141
|
-
setInterval(...args) {
|
|
142
|
-
const id = self.setInterval(...args);
|
|
143
|
-
ensureProperty(this, _disposers_, () => /* @__PURE__ */ new Set());
|
|
144
|
-
this[_disposers_].add(() => self.clearInterval(id));
|
|
145
|
-
return id;
|
|
146
|
-
}
|
|
147
|
-
/**
|
|
148
|
-
* Creates an error for an unreachable code path.
|
|
149
|
-
*/
|
|
150
|
-
never(message = "This should never happen") {
|
|
151
|
-
const details = message ? `: ${message}` : "";
|
|
152
|
-
const error = new Error(`[${this.constructor.name}] This should never happen${details}`);
|
|
153
|
-
Error.captureStackTrace(error, this.never);
|
|
154
|
-
return error;
|
|
155
|
-
}
|
|
156
|
-
};
|
|
157
|
-
function setProperty(object, key, value) {
|
|
158
|
-
Reflect.defineProperty(object, key, {
|
|
159
|
-
configurable: true,
|
|
160
|
-
get: () => value,
|
|
161
|
-
set: (v) => value = v
|
|
162
|
-
});
|
|
163
229
|
}
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
230
|
+
// ---------------------------------------------------------------------------
|
|
231
|
+
// HELPERS
|
|
232
|
+
// ---------------------------------------------------------------------------
|
|
233
|
+
/**
|
|
234
|
+
* Ensure a property exists on an object, initialize it if it doesn't.
|
|
235
|
+
*/
|
|
236
|
+
function ensure(object, key, getInitialValue) {
|
|
237
|
+
if (key in object)
|
|
238
|
+
return;
|
|
239
|
+
const value = getInitialValue();
|
|
240
|
+
Reflect.defineProperty(object, key, { configurable: true, get: () => value });
|
|
168
241
|
}
|
|
242
|
+
/**
|
|
243
|
+
* Get all prototypes of an object up to `Object.prototype`.
|
|
244
|
+
*/
|
|
169
245
|
function getPrototypes(object) {
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
246
|
+
const prototype = Reflect.getPrototypeOf(object);
|
|
247
|
+
if (!prototype || prototype === Object.prototype)
|
|
248
|
+
return [];
|
|
249
|
+
return [prototype, ...getPrototypes(prototype)];
|
|
173
250
|
}
|
|
251
|
+
/**
|
|
252
|
+
* Find the root `Unit` in the hierarchy for a given unit.
|
|
253
|
+
*/
|
|
174
254
|
function findRoot(unit) {
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
255
|
+
let root = null;
|
|
256
|
+
let cursor = unit;
|
|
257
|
+
while (cursor) {
|
|
258
|
+
if (cursor instanceof Unit)
|
|
259
|
+
root = cursor;
|
|
260
|
+
cursor = getParent(cursor);
|
|
261
|
+
}
|
|
262
|
+
return root;
|
|
182
263
|
}
|
|
264
|
+
/**
|
|
265
|
+
* Find the highest unattached `Unit` in the hierarchy for a given unit.
|
|
266
|
+
*/
|
|
183
267
|
function findUnattachedRoot(unit) {
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
268
|
+
let unattachedRoot = null;
|
|
269
|
+
let cursor = unit;
|
|
270
|
+
while (cursor) {
|
|
271
|
+
if (cursor instanceof Unit && !cursor[_attached_])
|
|
272
|
+
unattachedRoot = cursor;
|
|
273
|
+
cursor = getParent(cursor);
|
|
274
|
+
}
|
|
275
|
+
return unattachedRoot;
|
|
191
276
|
}
|
|
277
|
+
/**
|
|
278
|
+
* Get the parent of a node, which can be a `Unit`, an object, or an array.
|
|
279
|
+
*/
|
|
192
280
|
function getParent(node) {
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
}
|
|
196
|
-
function getVersioner(unit) {
|
|
197
|
-
const versioner = Reflect.get(unit.constructor, "versioner");
|
|
198
|
-
if (!is.object(versioner)) return {};
|
|
199
|
-
return versioner;
|
|
281
|
+
const parent = Reflect.get(node, _parent_) ?? Reflect.get(node, epos.state.PARENT) ?? null;
|
|
282
|
+
return parent;
|
|
200
283
|
}
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
284
|
+
/**
|
|
285
|
+
* Create view component for the unit.
|
|
286
|
+
*/
|
|
287
|
+
function createView(unit, name, render) {
|
|
288
|
+
const fullName = `${unit['@']}.${name}`;
|
|
289
|
+
const View = epos.component((props) => {
|
|
290
|
+
try {
|
|
291
|
+
return render(props);
|
|
292
|
+
}
|
|
293
|
+
catch (error) {
|
|
294
|
+
unit.log.error(error);
|
|
295
|
+
const message = is.error(error) ? error.message : String(error);
|
|
296
|
+
return epos.libs.reactJsxRuntime.jsx('div', {
|
|
297
|
+
children: `[${fullName}] ${message}`,
|
|
298
|
+
style: {
|
|
299
|
+
width: 'fit-content',
|
|
300
|
+
padding: '4px 6px 4px 4px',
|
|
301
|
+
color: '#f00',
|
|
302
|
+
border: '1px solid #f00',
|
|
303
|
+
background: 'rgba(255, 0, 0, 0.1)',
|
|
304
|
+
fontSize: 12,
|
|
305
|
+
fontWeight: 400,
|
|
306
|
+
},
|
|
307
|
+
});
|
|
308
|
+
}
|
|
309
|
+
});
|
|
310
|
+
View.displayName = fullName;
|
|
311
|
+
return View;
|
|
205
312
|
}
|
|
206
|
-
export {
|
|
207
|
-
Unit,
|
|
208
|
-
_ancestors_,
|
|
209
|
-
_attached_,
|
|
210
|
-
_disposers_,
|
|
211
|
-
_parent_,
|
|
212
|
-
_pendingAttachFns_,
|
|
213
|
-
_root_
|
|
214
|
-
};
|
|
215
313
|
//# sourceMappingURL=epos-unit.js.map
|
package/dist/epos-unit.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/epos-unit.ts"],"sourcesContent":["import type { Arr, Cls, Obj } from 'dropcap/types'\nimport { createLog, is } from 'dropcap/utils'\nimport 'epos'\n\nexport const _root_ = Symbol('root')\nexport const _parent_ = Symbol('parent')\nexport const _attached_ = Symbol('attached')\nexport const _disposers_ = Symbol('disposers')\nexport const _ancestors_ = Symbol('ancestors')\nexport const _pendingAttachFns_ = Symbol('pendingAttachFns')\n\nexport type Node<T> = Unit<T> | Obj | Arr\n\nexport class Unit<TRoot = unknown> {\n declare '@': string\n declare log: ReturnType<typeof createLog>;\n declare [':version']?: number;\n declare [_root_]?: TRoot;\n declare [_parent_]?: Unit<TRoot> | null; // Parent reference for a not-yet-attached units\n declare [_attached_]?: boolean;\n declare [_disposers_]?: Set<() => void>;\n declare [_ancestors_]?: Map<Cls, unknown>;\n declare [_pendingAttachFns_]?: (() => void)[]\n\n constructor(parent: Unit<TRoot> | null) {\n this[_parent_] = parent\n const versions = getVersions(this)\n if (versions.length > 0) this[':version'] = versions.at(-1)!\n }\n\n /**\n * Lifecycle method called when the unit is attached to the state tree.\n */\n [epos.state.ATTACH]() {\n // Setup logger\n setProperty(this, 'log', createLog(this['@']))\n\n // Apply versioner\n epos.state.transaction(() => {\n const versioner = getVersioner(this)\n const versions = getVersions(this)\n for (const version of versions) {\n if (is.number(this[':version']) && this[':version'] >= version) continue\n const versionFn = versioner[version]\n if (!is.function(versionFn)) continue\n versionFn.call(this, this)\n this[':version'] = version\n }\n })\n\n // Prepare methods:\n // - Create components for methods ending with `View`\n // - Bind all other methods to the unit instance\n for (const prototype of getPrototypes(this)) {\n const descriptors = Object.getOwnPropertyDescriptors(prototype)\n\n for (const [key, descriptor] of Object.entries(descriptors)) {\n if (key === 'constructor') continue\n if (this.hasOwnProperty(key)) continue\n\n if (descriptor.get || descriptor.set) continue\n if (!is.function(descriptor.value)) continue\n const fn = descriptor.value.bind(this)\n\n if (key.endsWith('View')) {\n let Component = epos.component(fn)\n Component.displayName = `${this.constructor.name}.${key}`\n setProperty(this, key, Component)\n } else {\n setProperty(this, key, fn)\n }\n }\n }\n\n // Setup state\n const stateDescriptor = Reflect.getOwnPropertyDescriptor(this.constructor.prototype, 'state')\n if (stateDescriptor && stateDescriptor.get) {\n const state = stateDescriptor.get.call(this)\n setProperty(this, 'state', epos.libs.mobx.observable.object(state, {}, { deep: false }))\n }\n\n // Process attach queue.\n // We do not execute `attach` methods immediately, but rather queue them\n // on the highest unattached ancestor. This way we ensure that `attach`\n // methods are called after all versioners have been applied in the entire subtree.\n const attach = Reflect.get(this, 'attach')\n if (is.function(attach)) {\n const unattachedRoot = findUnattachedRoot(this)\n if (!unattachedRoot) throw this.never()\n\n ensureProperty(unattachedRoot, _pendingAttachFns_, () => [])\n unattachedRoot[_pendingAttachFns_].push(() => attach())\n }\n\n if (this[_pendingAttachFns_]) {\n this[_pendingAttachFns_].forEach(attach => attach())\n delete this[_pendingAttachFns_]\n }\n\n // Mark as attached\n setProperty(this, _attached_, true)\n }\n\n /**\n * Lifecycle method called when the unit is detached from the state tree.\n */\n [epos.state.DETACH]() {\n // 1. Run disposers\n if (this[_disposers_]) {\n this[_disposers_].forEach(disposer => disposer())\n this[_disposers_].clear()\n }\n\n // 2. Call detach method\n const detach = Reflect.get(this, 'detach')\n if (is.function(detach)) detach()\n\n // 3. Clean up internal properties\n delete this[_root_]\n delete this[_attached_]\n delete this[_ancestors_]\n delete this[_disposers_]\n }\n\n /**\n * Gets the root unit of the current unit's tree.\n * The result is cached for subsequent calls.\n */\n get $() {\n ensureProperty(this, _root_, () => findRoot(this))\n return this[_root_]\n }\n\n /**\n * Finds the closest ancestor unit of a given type.\n * The result is cached for subsequent calls.\n */\n closest<T extends Unit>(Ancestor: Cls<T>) {\n // Has cached value? -> Return it\n ensureProperty(this, _ancestors_, () => new Map())\n if (this[_ancestors_].has(Ancestor)) return this[_ancestors_].get(Ancestor) as T\n\n // Find the closest ancestor and cache it\n let cursor: Node<TRoot> | null = this\n while (cursor) {\n if (cursor instanceof Ancestor) {\n this[_ancestors_].set(Ancestor, cursor)\n return cursor\n }\n cursor = getParent(cursor)\n }\n\n return null\n }\n\n /**\n * A wrapper around MobX's `autorun` that automatically disposes\n * the reaction when the unit is detached.\n */\n autorun(...args: Parameters<typeof epos.libs.mobx.autorun>) {\n const disposer = epos.libs.mobx.autorun(...args)\n ensureProperty(this, _disposers_, () => new Set())\n this[_disposers_].add(disposer)\n return disposer\n }\n\n /**\n * A wrapper around MobX's `reaction` that automatically disposes\n * the reaction when the unit is detached.\n */\n reaction(...args: Parameters<typeof epos.libs.mobx.reaction>) {\n const disposer = epos.libs.mobx.reaction(...args)\n ensureProperty(this, _disposers_, () => new Set())\n this[_disposers_].add(disposer)\n return disposer\n }\n\n /**\n * A wrapper around `setTimeout` that automatically clears the timeout\n * when the unit is detached.\n */\n setTimeout(...args: Parameters<typeof self.setTimeout>) {\n const id = self.setTimeout(...args)\n ensureProperty(this, _disposers_, () => new Set())\n this[_disposers_].add(() => self.clearTimeout(id))\n return id\n }\n\n /**\n * A wrapper around `setInterval` that automatically clears the interval\n * when the unit is detached.\n */\n setInterval(...args: Parameters<typeof self.setInterval>) {\n const id = self.setInterval(...args)\n ensureProperty(this, _disposers_, () => new Set())\n this[_disposers_].add(() => self.clearInterval(id))\n return id\n }\n\n /**\n * Creates an error for an unreachable code path.\n */\n never(message = 'This should never happen') {\n const details = message ? `: ${message}` : ''\n const error = new Error(`[${this.constructor.name}] This should never happen${details}`)\n Error.captureStackTrace(error, this.never)\n return error\n }\n}\n\n// ---------------------------------------------------------------------------\n// HELPERS\n// ---------------------------------------------------------------------------\n\n/**\n * Defines a configurable property on an object.\n */\nfunction setProperty(object: object, key: PropertyKey, value: unknown) {\n Reflect.defineProperty(object, key, {\n configurable: true,\n get: () => value,\n set: v => (value = v),\n })\n}\n\n/**\n * Ensures a property exists on an object, initializing it if it doesn't.\n */\nfunction ensureProperty<T extends object, K extends PropertyKey, V>(\n object: T,\n key: K,\n getInitialValue: () => V,\n): asserts object is T & { [key in K]: V } {\n if (key in object) return\n const value = getInitialValue()\n Reflect.defineProperty(object, key, { configurable: true, get: () => value })\n}\n\n/**\n * Gets all prototypes of an object up to `Object.prototype`.\n */\nfunction getPrototypes(object: object): object[] {\n const prototype = Reflect.getPrototypeOf(object)\n if (!prototype || prototype === Object.prototype) return []\n return [prototype, ...getPrototypes(prototype)]\n}\n\n/**\n * Finds the root `Unit` in the hierarchy for a given unit.\n */\nfunction findRoot<T>(unit: Unit<T>) {\n let root: Unit<T> | null = null\n let cursor: Node<T> | null = unit\n\n while (cursor) {\n if (cursor instanceof Unit) root = cursor\n cursor = getParent(cursor)\n }\n\n return root as T\n}\n\n/**\n * Finds the highest unattached `Unit` in the hierarchy for a given unit.\n */\nfunction findUnattachedRoot<T>(unit: Unit<T>) {\n let unattachedRoot: Unit<T> | null = null\n let cursor: Node<T> | null = unit\n\n while (cursor) {\n if (cursor instanceof Unit && !cursor[_attached_]) unattachedRoot = cursor\n cursor = getParent(cursor)\n }\n\n return unattachedRoot\n}\n\n/**\n * Gets the parent of a node, which can be a `Unit`, an object, or an array.\n */\nfunction getParent<T>(node: Node<T>) {\n const parent: Node<T> | null = Reflect.get(node, _parent_) ?? Reflect.get(node, epos.state.PARENT) ?? null\n return parent\n}\n\n/**\n * Gets the versioner object from a unit's constructor.\n */\nfunction getVersioner<T>(unit: Unit<T>) {\n const versioner: unknown = Reflect.get(unit.constructor, 'versioner')\n if (!is.object(versioner)) return {}\n return versioner\n}\n\n/**\n * Gets a sorted list of numeric version keys from a unit's versioner.\n */\nfunction getVersions<T>(unit: Unit<T>) {\n const versioner = getVersioner(unit)\n const numericKeys = Object.keys(versioner).filter(key => is.numeric(key))\n return numericKeys.map(Number).sort((v1, v2) => v1 - v2)\n}\n"],"mappings":"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","names":["attach"]}
|
|
1
|
+
{"version":3,"file":"epos-unit.js","sourceRoot":"","sources":["../src/epos-unit.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "epos-unit",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.18.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "imkost",
|
|
7
7
|
"description": "",
|
|
8
8
|
"keywords": [],
|
|
9
9
|
"scripts": {
|
|
10
|
-
"dev": "
|
|
11
|
-
"build": "
|
|
12
|
-
"lint": "
|
|
10
|
+
"dev": "rimraf dist && tsgo --watch",
|
|
11
|
+
"build": "rimraf dist && tsgo",
|
|
12
|
+
"lint": "tsgo --noEmit",
|
|
13
13
|
"release": "sh -c 'npm version ${1:-minor} && npm run build && npm publish' --"
|
|
14
14
|
},
|
|
15
15
|
"exports": {
|
|
@@ -20,7 +20,8 @@
|
|
|
20
20
|
"src"
|
|
21
21
|
],
|
|
22
22
|
"dependencies": {
|
|
23
|
-
"dropcap": "^1.
|
|
24
|
-
"epos": "^1.
|
|
23
|
+
"dropcap": "^1.5.0",
|
|
24
|
+
"epos": "^1.35.0",
|
|
25
|
+
"nanoid": "^5.1.6"
|
|
25
26
|
}
|
|
26
27
|
}
|
package/src/epos-unit.ts
CHANGED
|
@@ -1,18 +1,29 @@
|
|
|
1
1
|
import type { Arr, Cls, Obj } from 'dropcap/types'
|
|
2
2
|
import { createLog, is } from 'dropcap/utils'
|
|
3
3
|
import 'epos'
|
|
4
|
+
import { customAlphabet } from 'nanoid'
|
|
5
|
+
import type { FC } from 'react'
|
|
6
|
+
|
|
7
|
+
declare global {
|
|
8
|
+
interface ErrorConstructor {
|
|
9
|
+
captureStackTrace(targetObject: object, constructorOpt?: Function): void
|
|
10
|
+
}
|
|
11
|
+
}
|
|
4
12
|
|
|
5
13
|
export const _root_ = Symbol('root')
|
|
6
14
|
export const _parent_ = Symbol('parent')
|
|
7
15
|
export const _attached_ = Symbol('attached')
|
|
8
16
|
export const _disposers_ = Symbol('disposers')
|
|
9
17
|
export const _ancestors_ = Symbol('ancestors')
|
|
10
|
-
export const
|
|
18
|
+
export const _attachQueue_ = Symbol('pendingAttachHooks')
|
|
19
|
+
const nanoid = customAlphabet('abcdefghijklmnopqrstuvwxyz0123456789', 10)
|
|
11
20
|
|
|
12
21
|
export type Node<T> = Unit<T> | Obj | Arr
|
|
22
|
+
export type Versioner<T> = { [version: number]: (this: T) => void }
|
|
13
23
|
|
|
14
24
|
export class Unit<TRoot = unknown> {
|
|
15
25
|
declare '@': string
|
|
26
|
+
declare id: string
|
|
16
27
|
declare log: ReturnType<typeof createLog>;
|
|
17
28
|
declare [':version']?: number;
|
|
18
29
|
declare [_root_]?: TRoot;
|
|
@@ -20,192 +31,242 @@ export class Unit<TRoot = unknown> {
|
|
|
20
31
|
declare [_attached_]?: boolean;
|
|
21
32
|
declare [_disposers_]?: Set<() => void>;
|
|
22
33
|
declare [_ancestors_]?: Map<Cls, unknown>;
|
|
23
|
-
declare [
|
|
34
|
+
declare [_attachQueue_]?: (() => void)[]
|
|
35
|
+
|
|
36
|
+
static defineVersioner<T extends Unit>(this: Cls<T>, versioner: Versioner<T>) {
|
|
37
|
+
return versioner
|
|
38
|
+
}
|
|
24
39
|
|
|
25
40
|
constructor(parent: Unit<TRoot> | null) {
|
|
41
|
+
this.id = nanoid()
|
|
26
42
|
this[_parent_] = parent
|
|
27
|
-
const versions = getVersions(this)
|
|
28
|
-
if (versions.length > 0) this[':version'] = versions.at(-1)!
|
|
29
43
|
}
|
|
30
44
|
|
|
45
|
+
// ---------------------------------------------------------------------------
|
|
46
|
+
// ATTACH
|
|
47
|
+
// ---------------------------------------------------------------------------
|
|
48
|
+
|
|
31
49
|
/**
|
|
32
50
|
* Lifecycle method called when the unit is attached to the state tree.
|
|
33
51
|
*/
|
|
34
52
|
[epos.state.ATTACH]() {
|
|
35
53
|
// Setup logger
|
|
36
|
-
|
|
54
|
+
let log = createLog(this['@'])
|
|
55
|
+
Reflect.defineProperty(this, 'log', { configurable: true, get: () => log, set: v => (log = v) })
|
|
37
56
|
|
|
38
57
|
// Apply versioner
|
|
39
|
-
|
|
40
|
-
const versioner =
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
58
|
+
void (() => {
|
|
59
|
+
const versioner: unknown = Reflect.get(this.constructor, 'versioner')
|
|
60
|
+
if (!is.object(versioner)) return
|
|
61
|
+
|
|
62
|
+
const asc = (v1: number, v2: number) => v1 - v2
|
|
63
|
+
const versions = Object.keys(versioner).filter(is.numeric).map(Number).sort(asc)
|
|
64
|
+
if (versions.length === 0) return
|
|
65
|
+
|
|
66
|
+
epos.state.transaction(() => {
|
|
67
|
+
for (const version of versions) {
|
|
68
|
+
if (is.number(this[':version']) && this[':version'] >= version) continue
|
|
69
|
+
const versionFn = versioner[version]
|
|
70
|
+
if (!is.function(versionFn)) continue
|
|
71
|
+
versionFn.call(this)
|
|
72
|
+
this[':version'] = version
|
|
73
|
+
}
|
|
74
|
+
})
|
|
75
|
+
})()
|
|
50
76
|
|
|
51
|
-
//
|
|
77
|
+
// Setup state
|
|
78
|
+
void (() => {
|
|
79
|
+
const descriptor = Reflect.getOwnPropertyDescriptor(this.constructor.prototype, 'state')
|
|
80
|
+
if (!descriptor || !descriptor.get) return
|
|
81
|
+
const value: unknown = descriptor.get.call(this)
|
|
82
|
+
if (!is.object(value)) throw new Error(`'state' getter return an object`)
|
|
83
|
+
const state = epos.state.create(value)
|
|
84
|
+
Reflect.defineProperty(state, epos.state.PARENT, { configurable: true, value: this })
|
|
85
|
+
Reflect.defineProperty(this, 'state', { enumerable: true, get: () => state })
|
|
86
|
+
})()
|
|
87
|
+
|
|
88
|
+
// Setup inert
|
|
89
|
+
void (() => {
|
|
90
|
+
const descriptor = Reflect.getOwnPropertyDescriptor(this.constructor.prototype, 'inert')
|
|
91
|
+
if (!descriptor || !descriptor.get) return
|
|
92
|
+
const value: unknown = descriptor.get.call(this)
|
|
93
|
+
if (!is.object(value)) throw new Error(`'inert' getter return an object`)
|
|
94
|
+
Reflect.defineProperty(this, 'inert', { enumerable: true, get: () => value })
|
|
95
|
+
})()
|
|
96
|
+
|
|
97
|
+
// Prepare properties for the whole prototype chain:
|
|
52
98
|
// - Create components for methods ending with `View`
|
|
53
99
|
// - Bind all other methods to the unit instance
|
|
100
|
+
// - Turn getters into MobX computed properties
|
|
54
101
|
for (const prototype of getPrototypes(this)) {
|
|
55
102
|
const descriptors = Object.getOwnPropertyDescriptors(prototype)
|
|
56
|
-
|
|
57
103
|
for (const [key, descriptor] of Object.entries(descriptors)) {
|
|
104
|
+
// Skip constructor and already defined properties
|
|
58
105
|
if (key === 'constructor') continue
|
|
59
106
|
if (this.hasOwnProperty(key)) continue
|
|
60
107
|
|
|
61
|
-
|
|
62
|
-
if (
|
|
63
|
-
|
|
108
|
+
// Create components for methods ending with `View`
|
|
109
|
+
if (is.function(descriptor.value) && key.endsWith('View')) {
|
|
110
|
+
let View = createView(this, key, descriptor.value.bind(this) as FC<unknown>)
|
|
111
|
+
Reflect.defineProperty(this, key, { configurable: true, get: () => View, set: v => (View = v) })
|
|
112
|
+
}
|
|
64
113
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
114
|
+
// Bind all other methods to the unit instance
|
|
115
|
+
else if (is.function(descriptor.value)) {
|
|
116
|
+
let method = descriptor.value.bind(this)
|
|
117
|
+
Reflect.defineProperty(this, key, {
|
|
118
|
+
configurable: true,
|
|
119
|
+
get: () => method,
|
|
120
|
+
set: v => (method = v),
|
|
121
|
+
})
|
|
71
122
|
}
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
123
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
124
|
+
// Turn getters into MobX computed properties
|
|
125
|
+
else if (descriptor.get) {
|
|
126
|
+
const getter = descriptor.get
|
|
127
|
+
const computed = epos.libs.mobx.computed(() => getter.call(this))
|
|
128
|
+
Reflect.defineProperty(this, key, {
|
|
129
|
+
configurable: true,
|
|
130
|
+
get: () => computed.get(),
|
|
131
|
+
set: descriptor.set,
|
|
132
|
+
})
|
|
133
|
+
}
|
|
134
|
+
}
|
|
80
135
|
}
|
|
81
136
|
|
|
82
|
-
//
|
|
83
|
-
//
|
|
84
|
-
//
|
|
85
|
-
// methods are called after all versioners have been applied in the entire subtree.
|
|
137
|
+
// Queue attach method.
|
|
138
|
+
// Do not execute `attach` methods immediately, but rather queue them on the highest unattached ancestor.
|
|
139
|
+
// This way `attach` methods are called after all versioners have been applied in the entire subtree.
|
|
86
140
|
const attach = Reflect.get(this, 'attach')
|
|
87
141
|
if (is.function(attach)) {
|
|
88
|
-
const
|
|
89
|
-
if (!
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
unattachedRoot[_pendingAttachFns_].push(() => attach())
|
|
142
|
+
const head = findUnattachedRoot(this)
|
|
143
|
+
if (!head) throw this.never()
|
|
144
|
+
ensure(head, _attachQueue_, () => [])
|
|
145
|
+
head[_attachQueue_].push(() => attach.call(this))
|
|
93
146
|
}
|
|
94
147
|
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
148
|
+
// Release attach queue
|
|
149
|
+
if (this[_attachQueue_]) {
|
|
150
|
+
this[_attachQueue_].forEach(attach => attach())
|
|
151
|
+
delete this[_attachQueue_]
|
|
98
152
|
}
|
|
99
153
|
|
|
100
154
|
// Mark as attached
|
|
101
|
-
|
|
155
|
+
Reflect.defineProperty(this, _attached_, { configurable: true, get: () => true })
|
|
102
156
|
}
|
|
103
157
|
|
|
158
|
+
// ---------------------------------------------------------------------------
|
|
159
|
+
// DETACH
|
|
160
|
+
// ---------------------------------------------------------------------------
|
|
161
|
+
|
|
104
162
|
/**
|
|
105
163
|
* Lifecycle method called when the unit is detached from the state tree.
|
|
106
164
|
*/
|
|
107
165
|
[epos.state.DETACH]() {
|
|
108
|
-
//
|
|
166
|
+
// Run and clear disposers
|
|
109
167
|
if (this[_disposers_]) {
|
|
110
168
|
this[_disposers_].forEach(disposer => disposer())
|
|
111
169
|
this[_disposers_].clear()
|
|
112
170
|
}
|
|
113
171
|
|
|
114
|
-
//
|
|
172
|
+
// Clear ancestors cache
|
|
173
|
+
if (this[_ancestors_]) {
|
|
174
|
+
this[_ancestors_].clear()
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
// Call detach method
|
|
115
178
|
const detach = Reflect.get(this, 'detach')
|
|
116
179
|
if (is.function(detach)) detach()
|
|
117
|
-
|
|
118
|
-
// 3. Clean up internal properties
|
|
119
|
-
delete this[_root_]
|
|
120
|
-
delete this[_attached_]
|
|
121
|
-
delete this[_ancestors_]
|
|
122
|
-
delete this[_disposers_]
|
|
123
180
|
}
|
|
124
181
|
|
|
182
|
+
// ---------------------------------------------------------------------------
|
|
183
|
+
// ROOT GETTER
|
|
184
|
+
// ---------------------------------------------------------------------------
|
|
185
|
+
|
|
125
186
|
/**
|
|
126
|
-
*
|
|
187
|
+
* Get the root unit of the current unit's tree.
|
|
127
188
|
* The result is cached for subsequent calls.
|
|
128
189
|
*/
|
|
129
190
|
get $() {
|
|
130
|
-
|
|
191
|
+
ensure(this, _root_, () => findRoot(this))
|
|
131
192
|
return this[_root_]
|
|
132
193
|
}
|
|
133
194
|
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
*/
|
|
138
|
-
closest<T extends Unit>(Ancestor: Cls<T>) {
|
|
139
|
-
// Has cached value? -> Return it
|
|
140
|
-
ensureProperty(this, _ancestors_, () => new Map())
|
|
141
|
-
if (this[_ancestors_].has(Ancestor)) return this[_ancestors_].get(Ancestor) as T
|
|
142
|
-
|
|
143
|
-
// Find the closest ancestor and cache it
|
|
144
|
-
let cursor: Node<TRoot> | null = this
|
|
145
|
-
while (cursor) {
|
|
146
|
-
if (cursor instanceof Ancestor) {
|
|
147
|
-
this[_ancestors_].set(Ancestor, cursor)
|
|
148
|
-
return cursor
|
|
149
|
-
}
|
|
150
|
-
cursor = getParent(cursor)
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
return null
|
|
154
|
-
}
|
|
195
|
+
// ---------------------------------------------------------------------------
|
|
196
|
+
// METHODS
|
|
197
|
+
// ---------------------------------------------------------------------------
|
|
155
198
|
|
|
156
199
|
/**
|
|
157
|
-
* A wrapper around MobX's `autorun` that automatically disposes
|
|
158
|
-
* the reaction when the unit is detached.
|
|
200
|
+
* A wrapper around MobX's `autorun` that automatically disposes the reaction when the unit is detached.
|
|
159
201
|
*/
|
|
160
202
|
autorun(...args: Parameters<typeof epos.libs.mobx.autorun>) {
|
|
161
203
|
const disposer = epos.libs.mobx.autorun(...args)
|
|
162
|
-
|
|
204
|
+
ensure(this, _disposers_, () => new Set())
|
|
163
205
|
this[_disposers_].add(disposer)
|
|
164
206
|
return disposer
|
|
165
207
|
}
|
|
166
208
|
|
|
167
209
|
/**
|
|
168
|
-
* A wrapper around MobX's `reaction` that automatically disposes
|
|
169
|
-
* the reaction when the unit is detached.
|
|
210
|
+
* A wrapper around MobX's `reaction` that automatically disposes the reaction when the unit is detached.
|
|
170
211
|
*/
|
|
171
212
|
reaction(...args: Parameters<typeof epos.libs.mobx.reaction>) {
|
|
172
213
|
const disposer = epos.libs.mobx.reaction(...args)
|
|
173
|
-
|
|
214
|
+
ensure(this, _disposers_, () => new Set())
|
|
174
215
|
this[_disposers_].add(disposer)
|
|
175
216
|
return disposer
|
|
176
217
|
}
|
|
177
218
|
|
|
178
219
|
/**
|
|
179
|
-
* A wrapper around `setTimeout` that automatically clears the timeout
|
|
180
|
-
* when the unit is detached.
|
|
220
|
+
* A wrapper around `setTimeout` that automatically clears the timeout when the unit is detached.
|
|
181
221
|
*/
|
|
182
|
-
setTimeout(...args: Parameters<typeof
|
|
183
|
-
const id =
|
|
184
|
-
|
|
185
|
-
this[_disposers_].add(() =>
|
|
222
|
+
setTimeout(...args: Parameters<typeof setTimeout>) {
|
|
223
|
+
const id = setTimeout(...args)
|
|
224
|
+
ensure(this, _disposers_, () => new Set())
|
|
225
|
+
this[_disposers_].add(() => clearTimeout(id))
|
|
186
226
|
return id
|
|
187
227
|
}
|
|
188
228
|
|
|
189
229
|
/**
|
|
190
|
-
* A wrapper around `setInterval` that automatically clears the interval
|
|
191
|
-
* when the unit is detached.
|
|
230
|
+
* A wrapper around `setInterval` that automatically clears the interval when the unit is detached.
|
|
192
231
|
*/
|
|
193
|
-
setInterval(...args: Parameters<typeof
|
|
194
|
-
const id =
|
|
195
|
-
|
|
196
|
-
this[_disposers_].add(() =>
|
|
232
|
+
setInterval(...args: Parameters<typeof setInterval>) {
|
|
233
|
+
const id = setInterval(...args)
|
|
234
|
+
ensure(this, _disposers_, () => new Set())
|
|
235
|
+
this[_disposers_].add(() => clearInterval(id))
|
|
197
236
|
return id
|
|
198
237
|
}
|
|
199
238
|
|
|
200
239
|
/**
|
|
201
|
-
*
|
|
240
|
+
* Create an error for code paths that are logically unreachable.
|
|
202
241
|
*/
|
|
203
242
|
never(message = 'This should never happen') {
|
|
204
243
|
const details = message ? `: ${message}` : ''
|
|
205
|
-
const error = new Error(`[${this
|
|
244
|
+
const error = new Error(`[${this['@']}] This should never happen${details}`)
|
|
206
245
|
Error.captureStackTrace(error, this.never)
|
|
207
246
|
return error
|
|
208
247
|
}
|
|
248
|
+
|
|
249
|
+
/**
|
|
250
|
+
* Find the closest ancestor unit of a given type.
|
|
251
|
+
* The result is cached for subsequent calls.
|
|
252
|
+
*/
|
|
253
|
+
closest<T extends Unit>(Ancestor: Cls<T>) {
|
|
254
|
+
// Has cached value? -> Return it
|
|
255
|
+
ensure(this, _ancestors_, () => new Map())
|
|
256
|
+
if (this[_ancestors_].has(Ancestor)) return this[_ancestors_].get(Ancestor) as T
|
|
257
|
+
|
|
258
|
+
// Find the closest ancestor and cache it
|
|
259
|
+
let cursor: Node<TRoot> | null = this
|
|
260
|
+
while (cursor) {
|
|
261
|
+
if (cursor instanceof Ancestor) {
|
|
262
|
+
this[_ancestors_].set(Ancestor, cursor)
|
|
263
|
+
return cursor
|
|
264
|
+
}
|
|
265
|
+
cursor = getParent(cursor)
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
return null
|
|
269
|
+
}
|
|
209
270
|
}
|
|
210
271
|
|
|
211
272
|
// ---------------------------------------------------------------------------
|
|
@@ -213,20 +274,9 @@ export class Unit<TRoot = unknown> {
|
|
|
213
274
|
// ---------------------------------------------------------------------------
|
|
214
275
|
|
|
215
276
|
/**
|
|
216
|
-
*
|
|
217
|
-
*/
|
|
218
|
-
function setProperty(object: object, key: PropertyKey, value: unknown) {
|
|
219
|
-
Reflect.defineProperty(object, key, {
|
|
220
|
-
configurable: true,
|
|
221
|
-
get: () => value,
|
|
222
|
-
set: v => (value = v),
|
|
223
|
-
})
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
/**
|
|
227
|
-
* Ensures a property exists on an object, initializing it if it doesn't.
|
|
277
|
+
* Ensure a property exists on an object, initialize it if it doesn't.
|
|
228
278
|
*/
|
|
229
|
-
function
|
|
279
|
+
function ensure<T extends object, K extends PropertyKey, V>(
|
|
230
280
|
object: T,
|
|
231
281
|
key: K,
|
|
232
282
|
getInitialValue: () => V,
|
|
@@ -237,7 +287,7 @@ function ensureProperty<T extends object, K extends PropertyKey, V>(
|
|
|
237
287
|
}
|
|
238
288
|
|
|
239
289
|
/**
|
|
240
|
-
*
|
|
290
|
+
* Get all prototypes of an object up to `Object.prototype`.
|
|
241
291
|
*/
|
|
242
292
|
function getPrototypes(object: object): object[] {
|
|
243
293
|
const prototype = Reflect.getPrototypeOf(object)
|
|
@@ -246,7 +296,7 @@ function getPrototypes(object: object): object[] {
|
|
|
246
296
|
}
|
|
247
297
|
|
|
248
298
|
/**
|
|
249
|
-
*
|
|
299
|
+
* Find the root `Unit` in the hierarchy for a given unit.
|
|
250
300
|
*/
|
|
251
301
|
function findRoot<T>(unit: Unit<T>) {
|
|
252
302
|
let root: Unit<T> | null = null
|
|
@@ -261,7 +311,7 @@ function findRoot<T>(unit: Unit<T>) {
|
|
|
261
311
|
}
|
|
262
312
|
|
|
263
313
|
/**
|
|
264
|
-
*
|
|
314
|
+
* Find the highest unattached `Unit` in the hierarchy for a given unit.
|
|
265
315
|
*/
|
|
266
316
|
function findUnattachedRoot<T>(unit: Unit<T>) {
|
|
267
317
|
let unattachedRoot: Unit<T> | null = null
|
|
@@ -276,7 +326,7 @@ function findUnattachedRoot<T>(unit: Unit<T>) {
|
|
|
276
326
|
}
|
|
277
327
|
|
|
278
328
|
/**
|
|
279
|
-
*
|
|
329
|
+
* Get the parent of a node, which can be a `Unit`, an object, or an array.
|
|
280
330
|
*/
|
|
281
331
|
function getParent<T>(node: Node<T>) {
|
|
282
332
|
const parent: Node<T> | null = Reflect.get(node, _parent_) ?? Reflect.get(node, epos.state.PARENT) ?? null
|
|
@@ -284,19 +334,33 @@ function getParent<T>(node: Node<T>) {
|
|
|
284
334
|
}
|
|
285
335
|
|
|
286
336
|
/**
|
|
287
|
-
*
|
|
337
|
+
* Create view component for the unit.
|
|
288
338
|
*/
|
|
289
|
-
function
|
|
290
|
-
const
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
339
|
+
function createView<T>(unit: Unit<T>, name: string, render: FC<unknown>) {
|
|
340
|
+
const fullName = `${unit['@']}.${name}`
|
|
341
|
+
|
|
342
|
+
const View = epos.component((props: unknown) => {
|
|
343
|
+
try {
|
|
344
|
+
return render(props)
|
|
345
|
+
} catch (error) {
|
|
346
|
+
unit.log.error(error)
|
|
347
|
+
const message = is.error(error) ? error.message : String(error)
|
|
348
|
+
return epos.libs.reactJsxRuntime.jsx('div', {
|
|
349
|
+
children: `[${fullName}] ${message}`,
|
|
350
|
+
style: {
|
|
351
|
+
width: 'fit-content',
|
|
352
|
+
padding: '4px 6px 4px 4px',
|
|
353
|
+
color: '#f00',
|
|
354
|
+
border: '1px solid #f00',
|
|
355
|
+
background: 'rgba(255, 0, 0, 0.1)',
|
|
356
|
+
fontSize: 12,
|
|
357
|
+
fontWeight: 400,
|
|
358
|
+
},
|
|
359
|
+
})
|
|
360
|
+
}
|
|
361
|
+
})
|
|
294
362
|
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
function getVersions<T>(unit: Unit<T>) {
|
|
299
|
-
const versioner = getVersioner(unit)
|
|
300
|
-
const numericKeys = Object.keys(versioner).filter(key => is.numeric(key))
|
|
301
|
-
return numericKeys.map(Number).sort((v1, v2) => v1 - v2)
|
|
363
|
+
View.displayName = fullName
|
|
364
|
+
|
|
365
|
+
return View
|
|
302
366
|
}
|