epos-unit 1.17.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 +31 -29
- package/dist/epos-unit.js +293 -219
- package/dist/epos-unit.js.map +1 -1
- package/package.json +7 -7
- package/src/epos-unit.ts +118 -84
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
|
*/
|
|
@@ -27,42 +34,37 @@ declare class Unit<TRoot = unknown> {
|
|
|
27
34
|
[_attached_]?: boolean;
|
|
28
35
|
[_disposers_]?: Set<() => void>;
|
|
29
36
|
[_ancestors_]?: Map<Cls, unknown>;
|
|
30
|
-
[
|
|
37
|
+
[_attachQueue_]?: (() => void)[];
|
|
38
|
+
static defineVersioner<T extends Unit>(this: Cls<T>, versioner: Versioner<T>): Versioner<T>;
|
|
31
39
|
constructor(parent: Unit<TRoot> | null);
|
|
32
40
|
/**
|
|
33
|
-
*
|
|
41
|
+
* Get the root unit of the current unit's tree.
|
|
34
42
|
* The result is cached for subsequent calls.
|
|
35
43
|
*/
|
|
36
44
|
get $(): TRoot | (undefined & TRoot);
|
|
37
45
|
/**
|
|
38
|
-
* A wrapper around MobX's `autorun` that automatically disposes
|
|
39
|
-
* the reaction when the unit is detached.
|
|
46
|
+
* A wrapper around MobX's `autorun` that automatically disposes the reaction when the unit is detached.
|
|
40
47
|
*/
|
|
41
|
-
autorun(...args: Parameters<typeof epos.libs.mobx.autorun>): mobx.IReactionDisposer;
|
|
48
|
+
autorun(...args: Parameters<typeof epos.libs.mobx.autorun>): import("mobx").IReactionDisposer;
|
|
42
49
|
/**
|
|
43
|
-
* A wrapper around MobX's `reaction` that automatically disposes
|
|
44
|
-
* the reaction when the unit is detached.
|
|
50
|
+
* A wrapper around MobX's `reaction` that automatically disposes the reaction when the unit is detached.
|
|
45
51
|
*/
|
|
46
|
-
reaction(...args: Parameters<typeof epos.libs.mobx.reaction>): mobx.IReactionDisposer;
|
|
52
|
+
reaction(...args: Parameters<typeof epos.libs.mobx.reaction>): import("mobx").IReactionDisposer;
|
|
47
53
|
/**
|
|
48
|
-
* A wrapper around `setTimeout` that automatically clears the timeout
|
|
49
|
-
* when the unit is detached.
|
|
54
|
+
* A wrapper around `setTimeout` that automatically clears the timeout when the unit is detached.
|
|
50
55
|
*/
|
|
51
|
-
setTimeout(...args: Parameters<typeof
|
|
56
|
+
setTimeout(...args: Parameters<typeof setTimeout>): NodeJS.Timeout;
|
|
52
57
|
/**
|
|
53
|
-
* A wrapper around `setInterval` that automatically clears the interval
|
|
54
|
-
* when the unit is detached.
|
|
58
|
+
* A wrapper around `setInterval` that automatically clears the interval when the unit is detached.
|
|
55
59
|
*/
|
|
56
|
-
setInterval(...args: Parameters<typeof
|
|
60
|
+
setInterval(...args: Parameters<typeof setInterval>): NodeJS.Timeout;
|
|
57
61
|
/**
|
|
58
|
-
*
|
|
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.
|
|
63
67
|
* The result is cached for subsequent calls.
|
|
64
68
|
*/
|
|
65
69
|
closest<T extends Unit>(Ancestor: Cls<T>): T | null;
|
|
66
70
|
}
|
|
67
|
-
|
|
68
|
-
export { type Node, Unit, _ancestors_, _attached_, _disposers_, _parent_, _pendingAttachHooks_, _root_ };
|
package/dist/epos-unit.js
CHANGED
|
@@ -1,239 +1,313 @@
|
|
|
1
|
-
|
|
2
|
-
import
|
|
3
|
-
import
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
if (versions.length > 0) this[":version"] = versions.at(-1);
|
|
19
|
-
}
|
|
20
|
-
// ---------------------------------------------------------------------------
|
|
21
|
-
// ATTACH / DETACH
|
|
22
|
-
// ---------------------------------------------------------------------------
|
|
23
|
-
/**
|
|
24
|
-
* Lifecycle method called when the unit is attached to the state tree.
|
|
25
|
-
*/
|
|
26
|
-
[epos.state.ATTACH]() {
|
|
27
|
-
epos.state.transaction(() => {
|
|
28
|
-
const versioner = getVersioner(this);
|
|
29
|
-
const versions = getVersions(versioner);
|
|
30
|
-
for (const version of versions) {
|
|
31
|
-
if (is.number(this[":version"]) && this[":version"] >= version) continue;
|
|
32
|
-
const versionFn = versioner[version];
|
|
33
|
-
if (!is.function(versionFn)) continue;
|
|
34
|
-
versionFn.call(this, this);
|
|
35
|
-
this[":version"] = version;
|
|
36
|
-
}
|
|
37
|
-
});
|
|
38
|
-
let log = createLog(this["@"]);
|
|
39
|
-
Reflect.defineProperty(this, "log", {
|
|
40
|
-
configurable: true,
|
|
41
|
-
get: () => log,
|
|
42
|
-
set: (v) => log = v
|
|
43
|
-
});
|
|
44
|
-
const stateDescriptor = Reflect.getOwnPropertyDescriptor(this.constructor.prototype, "state");
|
|
45
|
-
if (stateDescriptor && stateDescriptor.get) {
|
|
46
|
-
const value = stateDescriptor.get.call(this);
|
|
47
|
-
const state = epos.state.local(value, { deep: false });
|
|
48
|
-
Reflect.defineProperty(this, "state", { get: () => state });
|
|
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;
|
|
49
18
|
}
|
|
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
|
-
|
|
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
|
+
}
|
|
78
109
|
}
|
|
79
|
-
|
|
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_];
|
|
125
|
+
}
|
|
126
|
+
// Mark as attached
|
|
127
|
+
Reflect.defineProperty(this, _attached_, { configurable: true, get: () => true });
|
|
80
128
|
}
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
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();
|
|
87
149
|
}
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
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_];
|
|
91
160
|
}
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
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;
|
|
101
172
|
}
|
|
102
|
-
|
|
103
|
-
|
|
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;
|
|
104
181
|
}
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
/**
|
|
123
|
-
* A wrapper around MobX's `autorun` that automatically disposes
|
|
124
|
-
* the reaction when the unit is detached.
|
|
125
|
-
*/
|
|
126
|
-
autorun(...args) {
|
|
127
|
-
const disposer = epos.libs.mobx.autorun(...args);
|
|
128
|
-
ensure(this, _disposers_, () => /* @__PURE__ */ new Set());
|
|
129
|
-
this[_disposers_].add(disposer);
|
|
130
|
-
return disposer;
|
|
131
|
-
}
|
|
132
|
-
/**
|
|
133
|
-
* A wrapper around MobX's `reaction` that automatically disposes
|
|
134
|
-
* the reaction when the unit is detached.
|
|
135
|
-
*/
|
|
136
|
-
reaction(...args) {
|
|
137
|
-
const disposer = epos.libs.mobx.reaction(...args);
|
|
138
|
-
ensure(this, _disposers_, () => /* @__PURE__ */ new Set());
|
|
139
|
-
this[_disposers_].add(disposer);
|
|
140
|
-
return disposer;
|
|
141
|
-
}
|
|
142
|
-
/**
|
|
143
|
-
* A wrapper around `setTimeout` that automatically clears the timeout
|
|
144
|
-
* when the unit is detached.
|
|
145
|
-
*/
|
|
146
|
-
setTimeout(...args) {
|
|
147
|
-
const id = self.setTimeout(...args);
|
|
148
|
-
ensure(this, _disposers_, () => /* @__PURE__ */ new Set());
|
|
149
|
-
this[_disposers_].add(() => self.clearTimeout(id));
|
|
150
|
-
return id;
|
|
151
|
-
}
|
|
152
|
-
/**
|
|
153
|
-
* A wrapper around `setInterval` that automatically clears the interval
|
|
154
|
-
* when the unit is detached.
|
|
155
|
-
*/
|
|
156
|
-
setInterval(...args) {
|
|
157
|
-
const id = self.setInterval(...args);
|
|
158
|
-
ensure(this, _disposers_, () => /* @__PURE__ */ new Set());
|
|
159
|
-
this[_disposers_].add(() => self.clearInterval(id));
|
|
160
|
-
return id;
|
|
161
|
-
}
|
|
162
|
-
/**
|
|
163
|
-
* Creates an error for an unreachable code path.
|
|
164
|
-
*/
|
|
165
|
-
never(message = "This should never happen") {
|
|
166
|
-
const details = message ? `: ${message}` : "";
|
|
167
|
-
const error = new Error(`[${this.constructor.name}] This should never happen${details}`);
|
|
168
|
-
Error.captureStackTrace(error, this.never);
|
|
169
|
-
return error;
|
|
170
|
-
}
|
|
171
|
-
/**
|
|
172
|
-
* Finds the closest ancestor unit of a given type.
|
|
173
|
-
* The result is cached for subsequent calls.
|
|
174
|
-
*/
|
|
175
|
-
closest(Ancestor) {
|
|
176
|
-
ensure(this, _ancestors_, () => /* @__PURE__ */ new Map());
|
|
177
|
-
if (this[_ancestors_].has(Ancestor)) return this[_ancestors_].get(Ancestor);
|
|
178
|
-
let cursor = this;
|
|
179
|
-
while (cursor) {
|
|
180
|
-
if (cursor instanceof Ancestor) {
|
|
181
|
-
this[_ancestors_].set(Ancestor, cursor);
|
|
182
|
-
return cursor;
|
|
183
|
-
}
|
|
184
|
-
cursor = getParent(cursor);
|
|
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;
|
|
185
199
|
}
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
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;
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
// ---------------------------------------------------------------------------
|
|
231
|
+
// HELPERS
|
|
232
|
+
// ---------------------------------------------------------------------------
|
|
233
|
+
/**
|
|
234
|
+
* Ensure a property exists on an object, initialize it if it doesn't.
|
|
235
|
+
*/
|
|
189
236
|
function ensure(object, key, getInitialValue) {
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
237
|
+
if (key in object)
|
|
238
|
+
return;
|
|
239
|
+
const value = getInitialValue();
|
|
240
|
+
Reflect.defineProperty(object, key, { configurable: true, get: () => value });
|
|
193
241
|
}
|
|
242
|
+
/**
|
|
243
|
+
* Get all prototypes of an object up to `Object.prototype`.
|
|
244
|
+
*/
|
|
194
245
|
function getPrototypes(object) {
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
246
|
+
const prototype = Reflect.getPrototypeOf(object);
|
|
247
|
+
if (!prototype || prototype === Object.prototype)
|
|
248
|
+
return [];
|
|
249
|
+
return [prototype, ...getPrototypes(prototype)];
|
|
198
250
|
}
|
|
251
|
+
/**
|
|
252
|
+
* Find the root `Unit` in the hierarchy for a given unit.
|
|
253
|
+
*/
|
|
199
254
|
function findRoot(unit) {
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
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;
|
|
207
263
|
}
|
|
264
|
+
/**
|
|
265
|
+
* Find the highest unattached `Unit` in the hierarchy for a given unit.
|
|
266
|
+
*/
|
|
208
267
|
function findUnattachedRoot(unit) {
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
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;
|
|
216
276
|
}
|
|
277
|
+
/**
|
|
278
|
+
* Get the parent of a node, which can be a `Unit`, an object, or an array.
|
|
279
|
+
*/
|
|
217
280
|
function getParent(node) {
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
}
|
|
221
|
-
function getVersioner(unit) {
|
|
222
|
-
const versioner = Reflect.get(unit.constructor, "versioner");
|
|
223
|
-
if (!is.object(versioner)) return {};
|
|
224
|
-
return versioner;
|
|
281
|
+
const parent = Reflect.get(node, _parent_) ?? Reflect.get(node, epos.state.PARENT) ?? null;
|
|
282
|
+
return parent;
|
|
225
283
|
}
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
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;
|
|
229
312
|
}
|
|
230
|
-
export {
|
|
231
|
-
Unit,
|
|
232
|
-
_ancestors_,
|
|
233
|
-
_attached_,
|
|
234
|
-
_disposers_,
|
|
235
|
-
_parent_,
|
|
236
|
-
_pendingAttachHooks_,
|
|
237
|
-
_root_
|
|
238
|
-
};
|
|
239
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'\nimport { customAlphabet } from 'nanoid'\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 _pendingAttachHooks_ = Symbol('pendingAttachHooks')\nconst nanoid = customAlphabet('abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789', 8)\n\nexport type Node<T> = Unit<T> | Obj | Arr\n\nexport class Unit<TRoot = unknown> {\n declare '@': string\n declare id: 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 [_pendingAttachHooks_]?: (() => void)[]\n\n constructor(parent: Unit<TRoot> | null) {\n this.id = nanoid()\n this[_parent_] = parent\n const versioner = getVersioner(this)\n const versions = getVersions(versioner)\n if (versions.length > 0) this[':version'] = versions.at(-1)!\n }\n\n // ---------------------------------------------------------------------------\n // ATTACH / DETACH\n // ---------------------------------------------------------------------------\n\n /**\n * Lifecycle method called when the unit is attached to the state tree.\n */\n [epos.state.ATTACH]() {\n // Apply versioner\n epos.state.transaction(() => {\n const versioner = getVersioner(this)\n const versions = getVersions(versioner)\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 // Setup logger\n let log = createLog(this['@'])\n Reflect.defineProperty(this, 'log', {\n configurable: true,\n get: () => log,\n set: v => (log = v),\n })\n\n // Setup state\n const stateDescriptor = Reflect.getOwnPropertyDescriptor(this.constructor.prototype, 'state')\n if (stateDescriptor && stateDescriptor.get) {\n const value = stateDescriptor.get.call(this)\n const state = epos.state.local(value, { deep: false })\n Reflect.defineProperty(this, 'state', { get: () => state })\n }\n\n // Prepare properties for the whole prototype chain:\n // - Create components for methods ending with `View`\n // - Bind all other methods to the unit instance\n // - Turn getters into MobX computed properties\n for (const prototype of getPrototypes(this)) {\n const descriptors = Object.getOwnPropertyDescriptors(prototype)\n for (const [key, descriptor] of Object.entries(descriptors)) {\n // Skip constructor and already defined properties\n if (key === 'constructor') continue\n if (this.hasOwnProperty(key)) continue\n\n // Create components for methods ending with `View`\n if (is.function(descriptor.value) && key.endsWith('View')) {\n let Component = epos.component(descriptor.value.bind(this))\n Component.displayName = `${this.constructor.name}.${key}`\n Reflect.defineProperty(this, key, {\n configurable: true,\n get: () => Component,\n set: v => (Component = v),\n })\n }\n\n // Bind all other methods to the unit instance\n else if (is.function(descriptor.value)) {\n let method = descriptor.value.bind(this)\n Reflect.defineProperty(this, key, {\n configurable: true,\n get: () => method,\n set: v => (method = v),\n })\n }\n\n // Turn getters into MobX computed properties\n else if (descriptor.get) {\n const getter = descriptor.get\n const computed = epos.libs.mobx.computed(() => getter.call(this))\n Reflect.defineProperty(this, key, {\n configurable: true,\n get: () => computed.get(),\n set: descriptor.set,\n })\n }\n }\n }\n\n // Queue attach hook.\n // Do not execute `attach` hooks immediately, but rather queue them on the highest unattached ancestor.\n // This way `attach` hooks 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 ensure(unattachedRoot, _pendingAttachHooks_, () => [])\n unattachedRoot[_pendingAttachHooks_].push(() => attach())\n }\n\n // Release attach hooks\n if (this[_pendingAttachHooks_]) {\n this[_pendingAttachHooks_].forEach(attach => attach())\n delete this[_pendingAttachHooks_]\n }\n\n // Mark as attached\n Reflect.defineProperty(this, _attached_, { configurable: true, get: () => true })\n }\n\n /**\n * Lifecycle method called when the unit is detached from the state tree.\n */\n [epos.state.DETACH]() {\n // Run and clear disposers\n if (this[_disposers_]) {\n this[_disposers_].forEach(disposer => disposer())\n this[_disposers_].clear()\n }\n\n // Clear ancestors cache\n if (this[_ancestors_]) {\n this[_ancestors_].clear()\n }\n\n // Call detach method\n const detach = Reflect.get(this, 'detach')\n if (is.function(detach)) detach()\n }\n\n // ---------------------------------------------------------------------------\n // ROOT GETTER\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 ensure(this, _root_, () => findRoot(this))\n return this[_root_]\n }\n\n // ---------------------------------------------------------------------------\n // METHODS\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 ensure(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 ensure(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 ensure(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 ensure(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 * 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 ensure(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// ---------------------------------------------------------------------------\n// HELPERS\n// ---------------------------------------------------------------------------\n\n/**\n * Ensures a property exists on an object, initializing it if it doesn't.\n */\nfunction ensure<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(versioner: Obj) {\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,8 +20,8 @@
|
|
|
20
20
|
"src"
|
|
21
21
|
],
|
|
22
22
|
"dependencies": {
|
|
23
|
-
"dropcap": "^1.
|
|
24
|
-
"epos": "^1.
|
|
25
|
-
"nanoid": "^
|
|
23
|
+
"dropcap": "^1.5.0",
|
|
24
|
+
"epos": "^1.35.0",
|
|
25
|
+
"nanoid": "^5.1.6"
|
|
26
26
|
}
|
|
27
27
|
}
|
package/src/epos-unit.ts
CHANGED
|
@@ -2,16 +2,24 @@ import type { Arr, Cls, Obj } from 'dropcap/types'
|
|
|
2
2
|
import { createLog, is } from 'dropcap/utils'
|
|
3
3
|
import 'epos'
|
|
4
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
|
+
}
|
|
5
12
|
|
|
6
13
|
export const _root_ = Symbol('root')
|
|
7
14
|
export const _parent_ = Symbol('parent')
|
|
8
15
|
export const _attached_ = Symbol('attached')
|
|
9
16
|
export const _disposers_ = Symbol('disposers')
|
|
10
17
|
export const _ancestors_ = Symbol('ancestors')
|
|
11
|
-
export const
|
|
12
|
-
const nanoid = customAlphabet('
|
|
18
|
+
export const _attachQueue_ = Symbol('pendingAttachHooks')
|
|
19
|
+
const nanoid = customAlphabet('abcdefghijklmnopqrstuvwxyz0123456789', 10)
|
|
13
20
|
|
|
14
21
|
export type Node<T> = Unit<T> | Obj | Arr
|
|
22
|
+
export type Versioner<T> = { [version: number]: (this: T) => void }
|
|
15
23
|
|
|
16
24
|
export class Unit<TRoot = unknown> {
|
|
17
25
|
declare '@': string
|
|
@@ -23,52 +31,68 @@ export class Unit<TRoot = unknown> {
|
|
|
23
31
|
declare [_attached_]?: boolean;
|
|
24
32
|
declare [_disposers_]?: Set<() => void>;
|
|
25
33
|
declare [_ancestors_]?: Map<Cls, unknown>;
|
|
26
|
-
declare [
|
|
34
|
+
declare [_attachQueue_]?: (() => void)[]
|
|
35
|
+
|
|
36
|
+
static defineVersioner<T extends Unit>(this: Cls<T>, versioner: Versioner<T>) {
|
|
37
|
+
return versioner
|
|
38
|
+
}
|
|
27
39
|
|
|
28
40
|
constructor(parent: Unit<TRoot> | null) {
|
|
29
41
|
this.id = nanoid()
|
|
30
42
|
this[_parent_] = parent
|
|
31
|
-
const versioner = getVersioner(this)
|
|
32
|
-
const versions = getVersions(versioner)
|
|
33
|
-
if (versions.length > 0) this[':version'] = versions.at(-1)!
|
|
34
43
|
}
|
|
35
44
|
|
|
36
45
|
// ---------------------------------------------------------------------------
|
|
37
|
-
// ATTACH
|
|
46
|
+
// ATTACH
|
|
38
47
|
// ---------------------------------------------------------------------------
|
|
39
48
|
|
|
40
49
|
/**
|
|
41
50
|
* Lifecycle method called when the unit is attached to the state tree.
|
|
42
51
|
*/
|
|
43
52
|
[epos.state.ATTACH]() {
|
|
44
|
-
// Apply versioner
|
|
45
|
-
epos.state.transaction(() => {
|
|
46
|
-
const versioner = getVersioner(this)
|
|
47
|
-
const versions = getVersions(versioner)
|
|
48
|
-
for (const version of versions) {
|
|
49
|
-
if (is.number(this[':version']) && this[':version'] >= version) continue
|
|
50
|
-
const versionFn = versioner[version]
|
|
51
|
-
if (!is.function(versionFn)) continue
|
|
52
|
-
versionFn.call(this, this)
|
|
53
|
-
this[':version'] = version
|
|
54
|
-
}
|
|
55
|
-
})
|
|
56
|
-
|
|
57
53
|
// Setup logger
|
|
58
54
|
let log = createLog(this['@'])
|
|
59
|
-
Reflect.defineProperty(this, 'log', {
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
55
|
+
Reflect.defineProperty(this, 'log', { configurable: true, get: () => log, set: v => (log = v) })
|
|
56
|
+
|
|
57
|
+
// Apply versioner
|
|
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
|
+
})()
|
|
64
76
|
|
|
65
77
|
// Setup state
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
const
|
|
70
|
-
|
|
71
|
-
|
|
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
|
+
})()
|
|
72
96
|
|
|
73
97
|
// Prepare properties for the whole prototype chain:
|
|
74
98
|
// - Create components for methods ending with `View`
|
|
@@ -83,13 +107,8 @@ export class Unit<TRoot = unknown> {
|
|
|
83
107
|
|
|
84
108
|
// Create components for methods ending with `View`
|
|
85
109
|
if (is.function(descriptor.value) && key.endsWith('View')) {
|
|
86
|
-
let
|
|
87
|
-
|
|
88
|
-
Reflect.defineProperty(this, key, {
|
|
89
|
-
configurable: true,
|
|
90
|
-
get: () => Component,
|
|
91
|
-
set: v => (Component = v),
|
|
92
|
-
})
|
|
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) })
|
|
93
112
|
}
|
|
94
113
|
|
|
95
114
|
// Bind all other methods to the unit instance
|
|
@@ -115,27 +134,31 @@ export class Unit<TRoot = unknown> {
|
|
|
115
134
|
}
|
|
116
135
|
}
|
|
117
136
|
|
|
118
|
-
// Queue attach
|
|
119
|
-
// Do not execute `attach`
|
|
120
|
-
// This way `attach`
|
|
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.
|
|
121
140
|
const attach = Reflect.get(this, 'attach')
|
|
122
141
|
if (is.function(attach)) {
|
|
123
|
-
const
|
|
124
|
-
if (!
|
|
125
|
-
ensure(
|
|
126
|
-
|
|
142
|
+
const head = findUnattachedRoot(this)
|
|
143
|
+
if (!head) throw this.never()
|
|
144
|
+
ensure(head, _attachQueue_, () => [])
|
|
145
|
+
head[_attachQueue_].push(() => attach.call(this))
|
|
127
146
|
}
|
|
128
147
|
|
|
129
|
-
// Release attach
|
|
130
|
-
if (this[
|
|
131
|
-
this[
|
|
132
|
-
delete this[
|
|
148
|
+
// Release attach queue
|
|
149
|
+
if (this[_attachQueue_]) {
|
|
150
|
+
this[_attachQueue_].forEach(attach => attach())
|
|
151
|
+
delete this[_attachQueue_]
|
|
133
152
|
}
|
|
134
153
|
|
|
135
154
|
// Mark as attached
|
|
136
155
|
Reflect.defineProperty(this, _attached_, { configurable: true, get: () => true })
|
|
137
156
|
}
|
|
138
157
|
|
|
158
|
+
// ---------------------------------------------------------------------------
|
|
159
|
+
// DETACH
|
|
160
|
+
// ---------------------------------------------------------------------------
|
|
161
|
+
|
|
139
162
|
/**
|
|
140
163
|
* Lifecycle method called when the unit is detached from the state tree.
|
|
141
164
|
*/
|
|
@@ -161,7 +184,7 @@ export class Unit<TRoot = unknown> {
|
|
|
161
184
|
// ---------------------------------------------------------------------------
|
|
162
185
|
|
|
163
186
|
/**
|
|
164
|
-
*
|
|
187
|
+
* Get the root unit of the current unit's tree.
|
|
165
188
|
* The result is cached for subsequent calls.
|
|
166
189
|
*/
|
|
167
190
|
get $() {
|
|
@@ -174,8 +197,7 @@ export class Unit<TRoot = unknown> {
|
|
|
174
197
|
// ---------------------------------------------------------------------------
|
|
175
198
|
|
|
176
199
|
/**
|
|
177
|
-
* A wrapper around MobX's `autorun` that automatically disposes
|
|
178
|
-
* the reaction when the unit is detached.
|
|
200
|
+
* A wrapper around MobX's `autorun` that automatically disposes the reaction when the unit is detached.
|
|
179
201
|
*/
|
|
180
202
|
autorun(...args: Parameters<typeof epos.libs.mobx.autorun>) {
|
|
181
203
|
const disposer = epos.libs.mobx.autorun(...args)
|
|
@@ -185,8 +207,7 @@ export class Unit<TRoot = unknown> {
|
|
|
185
207
|
}
|
|
186
208
|
|
|
187
209
|
/**
|
|
188
|
-
* A wrapper around MobX's `reaction` that automatically disposes
|
|
189
|
-
* the reaction when the unit is detached.
|
|
210
|
+
* A wrapper around MobX's `reaction` that automatically disposes the reaction when the unit is detached.
|
|
190
211
|
*/
|
|
191
212
|
reaction(...args: Parameters<typeof epos.libs.mobx.reaction>) {
|
|
192
213
|
const disposer = epos.libs.mobx.reaction(...args)
|
|
@@ -196,39 +217,37 @@ export class Unit<TRoot = unknown> {
|
|
|
196
217
|
}
|
|
197
218
|
|
|
198
219
|
/**
|
|
199
|
-
* A wrapper around `setTimeout` that automatically clears the timeout
|
|
200
|
-
* when the unit is detached.
|
|
220
|
+
* A wrapper around `setTimeout` that automatically clears the timeout when the unit is detached.
|
|
201
221
|
*/
|
|
202
|
-
setTimeout(...args: Parameters<typeof
|
|
203
|
-
const id =
|
|
222
|
+
setTimeout(...args: Parameters<typeof setTimeout>) {
|
|
223
|
+
const id = setTimeout(...args)
|
|
204
224
|
ensure(this, _disposers_, () => new Set())
|
|
205
|
-
this[_disposers_].add(() =>
|
|
225
|
+
this[_disposers_].add(() => clearTimeout(id))
|
|
206
226
|
return id
|
|
207
227
|
}
|
|
208
228
|
|
|
209
229
|
/**
|
|
210
|
-
* A wrapper around `setInterval` that automatically clears the interval
|
|
211
|
-
* when the unit is detached.
|
|
230
|
+
* A wrapper around `setInterval` that automatically clears the interval when the unit is detached.
|
|
212
231
|
*/
|
|
213
|
-
setInterval(...args: Parameters<typeof
|
|
214
|
-
const id =
|
|
232
|
+
setInterval(...args: Parameters<typeof setInterval>) {
|
|
233
|
+
const id = setInterval(...args)
|
|
215
234
|
ensure(this, _disposers_, () => new Set())
|
|
216
|
-
this[_disposers_].add(() =>
|
|
235
|
+
this[_disposers_].add(() => clearInterval(id))
|
|
217
236
|
return id
|
|
218
237
|
}
|
|
219
238
|
|
|
220
239
|
/**
|
|
221
|
-
*
|
|
240
|
+
* Create an error for code paths that are logically unreachable.
|
|
222
241
|
*/
|
|
223
242
|
never(message = 'This should never happen') {
|
|
224
243
|
const details = message ? `: ${message}` : ''
|
|
225
|
-
const error = new Error(`[${this
|
|
244
|
+
const error = new Error(`[${this['@']}] This should never happen${details}`)
|
|
226
245
|
Error.captureStackTrace(error, this.never)
|
|
227
246
|
return error
|
|
228
247
|
}
|
|
229
248
|
|
|
230
249
|
/**
|
|
231
|
-
*
|
|
250
|
+
* Find the closest ancestor unit of a given type.
|
|
232
251
|
* The result is cached for subsequent calls.
|
|
233
252
|
*/
|
|
234
253
|
closest<T extends Unit>(Ancestor: Cls<T>) {
|
|
@@ -255,7 +274,7 @@ export class Unit<TRoot = unknown> {
|
|
|
255
274
|
// ---------------------------------------------------------------------------
|
|
256
275
|
|
|
257
276
|
/**
|
|
258
|
-
*
|
|
277
|
+
* Ensure a property exists on an object, initialize it if it doesn't.
|
|
259
278
|
*/
|
|
260
279
|
function ensure<T extends object, K extends PropertyKey, V>(
|
|
261
280
|
object: T,
|
|
@@ -268,7 +287,7 @@ function ensure<T extends object, K extends PropertyKey, V>(
|
|
|
268
287
|
}
|
|
269
288
|
|
|
270
289
|
/**
|
|
271
|
-
*
|
|
290
|
+
* Get all prototypes of an object up to `Object.prototype`.
|
|
272
291
|
*/
|
|
273
292
|
function getPrototypes(object: object): object[] {
|
|
274
293
|
const prototype = Reflect.getPrototypeOf(object)
|
|
@@ -277,7 +296,7 @@ function getPrototypes(object: object): object[] {
|
|
|
277
296
|
}
|
|
278
297
|
|
|
279
298
|
/**
|
|
280
|
-
*
|
|
299
|
+
* Find the root `Unit` in the hierarchy for a given unit.
|
|
281
300
|
*/
|
|
282
301
|
function findRoot<T>(unit: Unit<T>) {
|
|
283
302
|
let root: Unit<T> | null = null
|
|
@@ -292,7 +311,7 @@ function findRoot<T>(unit: Unit<T>) {
|
|
|
292
311
|
}
|
|
293
312
|
|
|
294
313
|
/**
|
|
295
|
-
*
|
|
314
|
+
* Find the highest unattached `Unit` in the hierarchy for a given unit.
|
|
296
315
|
*/
|
|
297
316
|
function findUnattachedRoot<T>(unit: Unit<T>) {
|
|
298
317
|
let unattachedRoot: Unit<T> | null = null
|
|
@@ -307,7 +326,7 @@ function findUnattachedRoot<T>(unit: Unit<T>) {
|
|
|
307
326
|
}
|
|
308
327
|
|
|
309
328
|
/**
|
|
310
|
-
*
|
|
329
|
+
* Get the parent of a node, which can be a `Unit`, an object, or an array.
|
|
311
330
|
*/
|
|
312
331
|
function getParent<T>(node: Node<T>) {
|
|
313
332
|
const parent: Node<T> | null = Reflect.get(node, _parent_) ?? Reflect.get(node, epos.state.PARENT) ?? null
|
|
@@ -315,18 +334,33 @@ function getParent<T>(node: Node<T>) {
|
|
|
315
334
|
}
|
|
316
335
|
|
|
317
336
|
/**
|
|
318
|
-
*
|
|
337
|
+
* Create view component for the unit.
|
|
319
338
|
*/
|
|
320
|
-
function
|
|
321
|
-
const
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
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
|
+
})
|
|
325
362
|
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
function getVersions(versioner: Obj) {
|
|
330
|
-
const numericKeys = Object.keys(versioner).filter(key => is.numeric(key))
|
|
331
|
-
return numericKeys.map(Number).sort((v1, v2) => v1 - v2)
|
|
363
|
+
View.displayName = fullName
|
|
364
|
+
|
|
365
|
+
return View
|
|
332
366
|
}
|