@travetto/registry 2.1.4 → 2.2.1
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/package.json +3 -3
- package/src/decorator.ts +7 -7
- package/src/registry.ts +11 -11
- package/src/service/metadata.ts +12 -11
- package/src/service/root.ts +2 -2
- package/src/source/class-source.ts +7 -7
- package/src/source/method-source.ts +3 -3
- package/support/phase.init.ts +1 -1
- package/support/phase.reset.ts +1 -1
- package/support/transformer.class-metadata.ts +4 -4
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@travetto/registry",
|
|
3
3
|
"displayName": "Registry",
|
|
4
|
-
"version": "2.1
|
|
4
|
+
"version": "2.2.1",
|
|
5
5
|
"description": "Patterns and utilities for handling registration of metadata and functionality for run-time use",
|
|
6
6
|
"keywords": [
|
|
7
7
|
"ast-transformations",
|
|
@@ -28,8 +28,8 @@
|
|
|
28
28
|
"directory": "module/registry"
|
|
29
29
|
},
|
|
30
30
|
"dependencies": {
|
|
31
|
-
"@travetto/compiler": "^2.1
|
|
32
|
-
"@travetto/transformer": "^2.1
|
|
31
|
+
"@travetto/compiler": "^2.2.1",
|
|
32
|
+
"@travetto/transformer": "^2.2.1"
|
|
33
33
|
},
|
|
34
34
|
"docDependencies": {
|
|
35
35
|
"@travetto/di": true
|
package/src/decorator.ts
CHANGED
|
@@ -16,7 +16,7 @@ class $PendingRegister {
|
|
|
16
16
|
* @param `ᚕmethods` Methods and their hashes
|
|
17
17
|
* @param `ᚕabstract` Is the class abstract
|
|
18
18
|
*/
|
|
19
|
-
initMeta(cls: Class, ᚕfile: string, ᚕhash: number, ᚕmethods: Record<string, { hash: number }>, ᚕabstract: boolean, ᚕsynthetic: boolean) {
|
|
19
|
+
initMeta(cls: Class, ᚕfile: string, ᚕhash: number, ᚕmethods: Record<string, { hash: number }>, ᚕabstract: boolean, ᚕsynthetic: boolean): boolean {
|
|
20
20
|
const meta = {
|
|
21
21
|
ᚕid: ModuleUtil.getId(ᚕfile, cls.name),
|
|
22
22
|
ᚕfile,
|
|
@@ -26,8 +26,8 @@ class $PendingRegister {
|
|
|
26
26
|
ᚕsynthetic,
|
|
27
27
|
};
|
|
28
28
|
|
|
29
|
-
const keys = [...Object.keys(meta)]
|
|
30
|
-
Object.defineProperties(cls, keys.reduce((all, k) => {
|
|
29
|
+
const keys = [...Object.keys(meta)];
|
|
30
|
+
Object.defineProperties(cls, keys.reduce<Partial<Record<keyof typeof meta, PropertyDescriptor>>>((all, k) => {
|
|
31
31
|
all[k] = {
|
|
32
32
|
value: meta[k],
|
|
33
33
|
enumerable: false,
|
|
@@ -35,7 +35,7 @@ class $PendingRegister {
|
|
|
35
35
|
writable: false
|
|
36
36
|
};
|
|
37
37
|
return all;
|
|
38
|
-
}, {}
|
|
38
|
+
}, {}));
|
|
39
39
|
|
|
40
40
|
return true;
|
|
41
41
|
}
|
|
@@ -43,7 +43,7 @@ class $PendingRegister {
|
|
|
43
43
|
/**
|
|
44
44
|
* Register class as pending
|
|
45
45
|
*/
|
|
46
|
-
add(cls: Class) {
|
|
46
|
+
add(cls: Class): void {
|
|
47
47
|
if (!this.map.has(cls.ᚕfile)) {
|
|
48
48
|
const sub: Class[] = [];
|
|
49
49
|
this.map.set(cls.ᚕfile, sub);
|
|
@@ -55,7 +55,7 @@ class $PendingRegister {
|
|
|
55
55
|
/**
|
|
56
56
|
* Clear pending classes
|
|
57
57
|
*/
|
|
58
|
-
flush() {
|
|
58
|
+
flush(): [string, Class[]][] {
|
|
59
59
|
const out = this.ordered.slice(0);
|
|
60
60
|
this.map.clear();
|
|
61
61
|
this.ordered = [];
|
|
@@ -69,7 +69,7 @@ export const PendingRegister = new $PendingRegister();
|
|
|
69
69
|
* Decorator to track class as pending
|
|
70
70
|
*/
|
|
71
71
|
export function Register() {
|
|
72
|
-
return (target: Class) => PendingRegister.add(target);
|
|
72
|
+
return (target: Class): void => PendingRegister.add(target);
|
|
73
73
|
}
|
|
74
74
|
|
|
75
75
|
Register.initMeta = PendingRegister.initMeta;
|
package/src/registry.ts
CHANGED
|
@@ -53,7 +53,7 @@ export abstract class Registry implements ChangeSource<Class> {
|
|
|
53
53
|
/**
|
|
54
54
|
* Reset parents
|
|
55
55
|
*/
|
|
56
|
-
protected resetParents() {
|
|
56
|
+
protected resetParents(): void {
|
|
57
57
|
for (const parent of this.#parents) {
|
|
58
58
|
parent.reset();
|
|
59
59
|
}
|
|
@@ -86,7 +86,7 @@ export abstract class Registry implements ChangeSource<Class> {
|
|
|
86
86
|
}
|
|
87
87
|
}
|
|
88
88
|
|
|
89
|
-
get resolved() {
|
|
89
|
+
get resolved(): boolean {
|
|
90
90
|
return this.#resolved;
|
|
91
91
|
}
|
|
92
92
|
|
|
@@ -100,7 +100,7 @@ export abstract class Registry implements ChangeSource<Class> {
|
|
|
100
100
|
/**
|
|
101
101
|
* Verify initialized state
|
|
102
102
|
*/
|
|
103
|
-
verifyInitialized() {
|
|
103
|
+
verifyInitialized(): void {
|
|
104
104
|
if (!this.#resolved) {
|
|
105
105
|
throw new Error(`${this.constructor.name} has not been initialized, you probably need to call RootRegistry.init()`);
|
|
106
106
|
}
|
|
@@ -131,7 +131,7 @@ export abstract class Registry implements ChangeSource<Class> {
|
|
|
131
131
|
/**
|
|
132
132
|
* Uninstall a class or list of classes
|
|
133
133
|
*/
|
|
134
|
-
uninstall(classes: Class | Class[], e: ChangeEvent<Class>) {
|
|
134
|
+
uninstall(classes: Class | Class[], e: ChangeEvent<Class>): void {
|
|
135
135
|
if (!Array.isArray(classes)) {
|
|
136
136
|
classes = [classes];
|
|
137
137
|
}
|
|
@@ -143,7 +143,7 @@ export abstract class Registry implements ChangeSource<Class> {
|
|
|
143
143
|
/**
|
|
144
144
|
* Install a class or a list of classes
|
|
145
145
|
*/
|
|
146
|
-
install(classes: Class | Class[], e: ChangeEvent<Class>) {
|
|
146
|
+
install(classes: Class | Class[], e: ChangeEvent<Class>): void {
|
|
147
147
|
if (!Array.isArray(classes)) {
|
|
148
148
|
classes = [classes];
|
|
149
149
|
}
|
|
@@ -155,7 +155,7 @@ export abstract class Registry implements ChangeSource<Class> {
|
|
|
155
155
|
/**
|
|
156
156
|
* Listen for events from the parent
|
|
157
157
|
*/
|
|
158
|
-
onEvent(event: ChangeEvent<Class>) {
|
|
158
|
+
onEvent(event: ChangeEvent<Class>): void {
|
|
159
159
|
console.debug('Received', { id: this.constructor.ᚕid, type: event.type, targetId: (event.curr ?? event.prev)!.ᚕid });
|
|
160
160
|
|
|
161
161
|
switch (event.type) {
|
|
@@ -177,7 +177,7 @@ export abstract class Registry implements ChangeSource<Class> {
|
|
|
177
177
|
/**
|
|
178
178
|
* Emit a new event
|
|
179
179
|
*/
|
|
180
|
-
emit(e: ChangeEvent<Class>) {
|
|
180
|
+
emit(e: ChangeEvent<Class>): void {
|
|
181
181
|
this.#emitter.emit('change', e);
|
|
182
182
|
}
|
|
183
183
|
|
|
@@ -191,28 +191,28 @@ export abstract class Registry implements ChangeSource<Class> {
|
|
|
191
191
|
/**
|
|
192
192
|
* Remove listeners
|
|
193
193
|
*/
|
|
194
|
-
off<T>(callback: ChangeHandler<Class<T>>) {
|
|
194
|
+
off<T>(callback: ChangeHandler<Class<T>>): void {
|
|
195
195
|
this.#emitter.off('change', callback);
|
|
196
196
|
}
|
|
197
197
|
|
|
198
198
|
/**
|
|
199
199
|
* Connect changes sources
|
|
200
200
|
*/
|
|
201
|
-
listen(source: ChangeSource<Class>) {
|
|
201
|
+
listen(source: ChangeSource<Class>): void {
|
|
202
202
|
source.on(e => this.onEvent(e));
|
|
203
203
|
}
|
|
204
204
|
|
|
205
205
|
/**
|
|
206
206
|
* On registry reset
|
|
207
207
|
*/
|
|
208
|
-
onReset() {
|
|
208
|
+
onReset(): void {
|
|
209
209
|
this.#resolved = false;
|
|
210
210
|
}
|
|
211
211
|
|
|
212
212
|
/**
|
|
213
213
|
* Reset entire registry
|
|
214
214
|
*/
|
|
215
|
-
reset() {
|
|
215
|
+
reset(): void {
|
|
216
216
|
this.onReset();
|
|
217
217
|
for (const des of this.#dependents) {
|
|
218
218
|
des.reset();
|
package/src/service/metadata.ts
CHANGED
|
@@ -39,7 +39,7 @@ export abstract class MetadataRegistry<C extends { class: Class }, M = unknown,
|
|
|
39
39
|
/**
|
|
40
40
|
* Code to call when uninstall is finalized
|
|
41
41
|
*/
|
|
42
|
-
onUninstallFinalize<T>(cls: Class<T>) {
|
|
42
|
+
onUninstallFinalize<T>(cls: Class<T>): void {
|
|
43
43
|
|
|
44
44
|
}
|
|
45
45
|
|
|
@@ -51,7 +51,7 @@ export abstract class MetadataRegistry<C extends { class: Class }, M = unknown,
|
|
|
51
51
|
/**
|
|
52
52
|
* Is class found by id or by Class
|
|
53
53
|
*/
|
|
54
|
-
has(cls: string | Class) {
|
|
54
|
+
has(cls: string | Class): boolean {
|
|
55
55
|
return this.entries.has(id(cls));
|
|
56
56
|
}
|
|
57
57
|
|
|
@@ -72,21 +72,21 @@ export abstract class MetadataRegistry<C extends { class: Class }, M = unknown,
|
|
|
72
72
|
/**
|
|
73
73
|
* Is there a class that is expiring
|
|
74
74
|
*/
|
|
75
|
-
hasExpired(cls: string | Class) {
|
|
75
|
+
hasExpired(cls: string | Class): boolean {
|
|
76
76
|
return this.expired.has(id(cls));
|
|
77
77
|
}
|
|
78
78
|
|
|
79
79
|
/**
|
|
80
80
|
* Is there a pending state for the class
|
|
81
81
|
*/
|
|
82
|
-
hasPending(cls: string | Class) {
|
|
82
|
+
hasPending(cls: string | Class): boolean {
|
|
83
83
|
return this.pending.has(id(cls));
|
|
84
84
|
}
|
|
85
85
|
|
|
86
86
|
/**
|
|
87
87
|
* Get list of all classes that have been registered
|
|
88
88
|
*/
|
|
89
|
-
getClasses() {
|
|
89
|
+
getClasses(): Class[] {
|
|
90
90
|
return Array.from(this.entries.values()).map(x => x.class);
|
|
91
91
|
}
|
|
92
92
|
|
|
@@ -94,7 +94,7 @@ export abstract class MetadataRegistry<C extends { class: Class }, M = unknown,
|
|
|
94
94
|
* Trigger initial install, moves pending to finalized (active)
|
|
95
95
|
*/
|
|
96
96
|
override initialInstall(): Class[] {
|
|
97
|
-
return Array.from(this.pending.values()).map(x => x.class
|
|
97
|
+
return Array.from(this.pending.values()).map(x => x.class).filter((x): x is Class => !!x);
|
|
98
98
|
}
|
|
99
99
|
|
|
100
100
|
/**
|
|
@@ -108,6 +108,7 @@ export abstract class MetadataRegistry<C extends { class: Class }, M = unknown,
|
|
|
108
108
|
* Find parent class for a given class object
|
|
109
109
|
*/
|
|
110
110
|
getParentClass(cls: Class): Class | null {
|
|
111
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
111
112
|
const parent = Object.getPrototypeOf(cls) as Class;
|
|
112
113
|
return parent.name && parent !== Object ? parent : null;
|
|
113
114
|
}
|
|
@@ -139,7 +140,7 @@ export abstract class MetadataRegistry<C extends { class: Class }, M = unknown,
|
|
|
139
140
|
/**
|
|
140
141
|
* Register a pending class, with partial config to overlay
|
|
141
142
|
*/
|
|
142
|
-
register(cls: Class, pConfig: Partial<C> = {}) {
|
|
143
|
+
register(cls: Class, pConfig: Partial<C> = {}): void {
|
|
143
144
|
const conf = this.getOrCreatePending(cls);
|
|
144
145
|
Util.deepAssign(conf, pConfig);
|
|
145
146
|
}
|
|
@@ -147,7 +148,7 @@ export abstract class MetadataRegistry<C extends { class: Class }, M = unknown,
|
|
|
147
148
|
/**
|
|
148
149
|
* Register a pending field, with partial config to overlay
|
|
149
150
|
*/
|
|
150
|
-
registerField(cls: Class, field: F, pConfig: Partial<M>) {
|
|
151
|
+
registerField(cls: Class, field: F, pConfig: Partial<M>): void {
|
|
151
152
|
const conf = this.getOrCreatePendingField(cls, field);
|
|
152
153
|
Util.deepAssign(conf, pConfig);
|
|
153
154
|
}
|
|
@@ -155,7 +156,7 @@ export abstract class MetadataRegistry<C extends { class: Class }, M = unknown,
|
|
|
155
156
|
/**
|
|
156
157
|
* On an install event, finalize
|
|
157
158
|
*/
|
|
158
|
-
onInstall(cls: Class, e: ChangeEvent<Class>) {
|
|
159
|
+
onInstall(cls: Class, e: ChangeEvent<Class>): void {
|
|
159
160
|
if (this.pending.has(cls.ᚕid) || this.pendingFields.has(cls.ᚕid)) {
|
|
160
161
|
console.debug('Installing', { service: this.constructor.name, id: cls.ᚕid });
|
|
161
162
|
const result = this.onInstallFinalize(cls);
|
|
@@ -170,7 +171,7 @@ export abstract class MetadataRegistry<C extends { class: Class }, M = unknown,
|
|
|
170
171
|
/**
|
|
171
172
|
* On an uninstall event, remove
|
|
172
173
|
*/
|
|
173
|
-
onUninstall(cls: Class, e: ChangeEvent<Class>) {
|
|
174
|
+
onUninstall(cls: Class, e: ChangeEvent<Class>): void {
|
|
174
175
|
if (this.entries.has(cls.ᚕid)) {
|
|
175
176
|
console.debug('Uninstalling', { service: this.constructor.name, id: cls.ᚕid });
|
|
176
177
|
this.expired.set(cls.ᚕid, this.entries.get(cls.ᚕid)!);
|
|
@@ -186,7 +187,7 @@ export abstract class MetadataRegistry<C extends { class: Class }, M = unknown,
|
|
|
186
187
|
/**
|
|
187
188
|
* Clear all caches
|
|
188
189
|
*/
|
|
189
|
-
override onReset() {
|
|
190
|
+
override onReset(): void {
|
|
190
191
|
super.onReset();
|
|
191
192
|
this.entries.clear();
|
|
192
193
|
this.pending.clear();
|
package/src/service/root.ts
CHANGED
|
@@ -15,7 +15,7 @@ class $RootRegistry extends Registry {
|
|
|
15
15
|
/**
|
|
16
16
|
* Send event to all all of the children
|
|
17
17
|
*/
|
|
18
|
-
override async onEvent(e: ChangeEvent<Class>) {
|
|
18
|
+
override async onEvent(e: ChangeEvent<Class>): Promise<void> {
|
|
19
19
|
await super.onEvent(e); // Process event, and
|
|
20
20
|
this.emit(e); // Send to children
|
|
21
21
|
}
|
|
@@ -23,7 +23,7 @@ class $RootRegistry extends Registry {
|
|
|
23
23
|
/**
|
|
24
24
|
* Reset self and parents
|
|
25
25
|
*/
|
|
26
|
-
override onReset() {
|
|
26
|
+
override onReset(): void {
|
|
27
27
|
this.resetParents();
|
|
28
28
|
}
|
|
29
29
|
}
|
|
@@ -25,7 +25,7 @@ export class ClassSource implements ChangeSource<Class> {
|
|
|
25
25
|
/**
|
|
26
26
|
* Flush classes
|
|
27
27
|
*/
|
|
28
|
-
#flush() {
|
|
28
|
+
#flush(): void {
|
|
29
29
|
for (const [file, classes] of PendingRegister.flush()) {
|
|
30
30
|
if (!classes || !classes.length) {
|
|
31
31
|
continue;
|
|
@@ -41,8 +41,8 @@ export class ClassSource implements ChangeSource<Class> {
|
|
|
41
41
|
/**
|
|
42
42
|
* Listen for a single file, and process all the classes within
|
|
43
43
|
*/
|
|
44
|
-
async #handleFileChanges(file: string, classes: Class[] = []) {
|
|
45
|
-
const next = new Map(classes.map(cls => [cls.ᚕid, cls] as
|
|
44
|
+
async #handleFileChanges(file: string, classes: Class[] = []): Promise<void> {
|
|
45
|
+
const next = new Map<string, Class>(classes.map(cls => [cls.ᚕid, cls] as const));
|
|
46
46
|
|
|
47
47
|
let prev = new Map<string, Class>();
|
|
48
48
|
if (this.#classes.has(file)) {
|
|
@@ -76,7 +76,7 @@ export class ClassSource implements ChangeSource<Class> {
|
|
|
76
76
|
/**
|
|
77
77
|
* Flush all pending classes
|
|
78
78
|
*/
|
|
79
|
-
processFiles() {
|
|
79
|
+
processFiles(): void {
|
|
80
80
|
console.debug('Pending changes', { changes: PendingRegister.ordered.map(([, x]) => x.map(y => y.ᚕid)) });
|
|
81
81
|
for (const [file, classes] of PendingRegister.flush()) {
|
|
82
82
|
this.#handleFileChanges(file, classes);
|
|
@@ -86,7 +86,7 @@ export class ClassSource implements ChangeSource<Class> {
|
|
|
86
86
|
/**
|
|
87
87
|
* Emit a change event
|
|
88
88
|
*/
|
|
89
|
-
emit(e: ChangeEvent<Class>) {
|
|
89
|
+
emit(e: ChangeEvent<Class>): void {
|
|
90
90
|
console.debug('Emitting change', { type: e.type, curr: e.curr?.ᚕid, prev: e.prev?.ᚕid });
|
|
91
91
|
this.#emitter.emit('change', e);
|
|
92
92
|
}
|
|
@@ -94,14 +94,14 @@ export class ClassSource implements ChangeSource<Class> {
|
|
|
94
94
|
/**
|
|
95
95
|
* Clear all classes
|
|
96
96
|
*/
|
|
97
|
-
reset() {
|
|
97
|
+
reset(): void {
|
|
98
98
|
this.#classes.clear();
|
|
99
99
|
}
|
|
100
100
|
|
|
101
101
|
/**
|
|
102
102
|
* Initialize
|
|
103
103
|
*/
|
|
104
|
-
async init() {
|
|
104
|
+
async init(): Promise<void> {
|
|
105
105
|
this.#flush();
|
|
106
106
|
}
|
|
107
107
|
|
|
@@ -17,16 +17,16 @@ export class MethodSource implements ChangeSource<[Class, Function]> {
|
|
|
17
17
|
classSource.on(e => this.onClassEvent(e));
|
|
18
18
|
}
|
|
19
19
|
|
|
20
|
-
async init() { }
|
|
20
|
+
async init(): Promise<void> { }
|
|
21
21
|
|
|
22
|
-
emit(ev: ChangeEvent<[Class, Function]>) {
|
|
22
|
+
emit(ev: ChangeEvent<[Class, Function]>): void {
|
|
23
23
|
this.#emitter.emit('change', ev);
|
|
24
24
|
}
|
|
25
25
|
|
|
26
26
|
/**
|
|
27
27
|
* On a class being emitted, check methods
|
|
28
28
|
*/
|
|
29
|
-
onClassEvent(e: ChangeEvent<Class>) {
|
|
29
|
+
onClassEvent(e: ChangeEvent<Class>): void {
|
|
30
30
|
const next = e.curr?.ᚕmethods ?? {};
|
|
31
31
|
const prev = e.prev?.ᚕmethods ?? {};
|
|
32
32
|
|
package/support/phase.init.ts
CHANGED
package/support/phase.reset.ts
CHANGED
|
@@ -29,7 +29,7 @@ export class RegisterTransformer {
|
|
|
29
29
|
* Hash each class
|
|
30
30
|
*/
|
|
31
31
|
@OnClass()
|
|
32
|
-
static preprocessClass(state: TransformerState & RegisterInfo, node: ts.ClassDeclaration) {
|
|
32
|
+
static preprocessClass(state: TransformerState & RegisterInfo, node: ts.ClassDeclaration): ts.ClassDeclaration {
|
|
33
33
|
state[cls] = SystemUtil.naiveHash(node.getText());
|
|
34
34
|
return node;
|
|
35
35
|
}
|
|
@@ -38,7 +38,7 @@ export class RegisterTransformer {
|
|
|
38
38
|
* Hash each method
|
|
39
39
|
*/
|
|
40
40
|
@OnMethod()
|
|
41
|
-
static processMethod(state: TransformerState & RegisterInfo, node: ts.MethodDeclaration) {
|
|
41
|
+
static processMethod(state: TransformerState & RegisterInfo, node: ts.MethodDeclaration): ts.MethodDeclaration {
|
|
42
42
|
if (ts.isIdentifier(node.name) && !CoreUtil.isAbstract(node) && ts.isClassDeclaration(node.parent)) {
|
|
43
43
|
const hash = SystemUtil.naiveHash(node.getText());
|
|
44
44
|
const conf = { hash };
|
|
@@ -52,7 +52,7 @@ export class RegisterTransformer {
|
|
|
52
52
|
* After visiting each class, register all the collected metadata
|
|
53
53
|
*/
|
|
54
54
|
@AfterClass()
|
|
55
|
-
static registerClass(state: TransformerState & RegisterInfo, node: ts.ClassDeclaration) {
|
|
55
|
+
static registerClass(state: TransformerState & RegisterInfo, node: ts.ClassDeclaration): ts.ClassDeclaration {
|
|
56
56
|
if (state.module === REGISTER_MOD) { // Cannot process self
|
|
57
57
|
return node;
|
|
58
58
|
}
|
|
@@ -96,7 +96,7 @@ export class RegisterTransformer {
|
|
|
96
96
|
* Give proper functions a file name
|
|
97
97
|
*/
|
|
98
98
|
@AfterFunction()
|
|
99
|
-
static registerFunction(state: TransformerState & RegisterInfo, node: ts.FunctionDeclaration | ts.FunctionExpression) {
|
|
99
|
+
static registerFunction(state: TransformerState & RegisterInfo, node: ts.FunctionDeclaration | ts.FunctionExpression): typeof node {
|
|
100
100
|
if (!ts.isFunctionDeclaration(node)) {
|
|
101
101
|
return node;
|
|
102
102
|
}
|