@travetto/registry 5.0.0-rc.1 → 5.0.0-rc.10
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/README.md +13 -17
- package/package.json +4 -4
- package/src/internal/commonjs-loader.ts +4 -5
- package/src/internal/file-loader.ts +3 -3
- package/src/proxy.ts +16 -28
- package/src/registry.ts +1 -1
- package/src/service/metadata.ts +2 -3
- package/src/service/root.ts +1 -1
- package/src/source/class-source.ts +53 -38
- package/src/source/method-source.ts +3 -4
- package/src/decorator.ts +0 -44
- package/support/transformer.register.ts +0 -36
package/README.md
CHANGED
|
@@ -27,7 +27,7 @@ This flow ensures all files are loaded and processed before application starts.
|
|
|
27
27
|
|
|
28
28
|
**Code: Sample Registry**
|
|
29
29
|
```typescript
|
|
30
|
-
import { Class } from '@travetto/
|
|
30
|
+
import { Class } from '@travetto/runtime';
|
|
31
31
|
import { MetadataRegistry } from '@travetto/registry';
|
|
32
32
|
|
|
33
33
|
interface Group {
|
|
@@ -82,47 +82,43 @@ As mentioned in [Manifest](https://github.com/travetto/travetto/tree/main/module
|
|
|
82
82
|
**Code: Sample Class Diffing**
|
|
83
83
|
```typescript
|
|
84
84
|
|
|
85
|
-
#handleFileChanges(
|
|
85
|
+
#handleFileChanges(importFile: string, classes: Class[] = []): number {
|
|
86
86
|
const next = new Map<string, Class>(classes.map(cls => [cls.Ⲑid, cls] as const));
|
|
87
87
|
|
|
88
88
|
let prev = new Map<string, Class>();
|
|
89
|
-
if (this.#classes.has(
|
|
90
|
-
prev = new Map(this.#classes.get(
|
|
89
|
+
if (this.#classes.has(importFile)) {
|
|
90
|
+
prev = new Map(this.#classes.get(importFile)!.entries());
|
|
91
91
|
}
|
|
92
92
|
|
|
93
93
|
const keys = new Set([...Array.from(prev.keys()), ...Array.from(next.keys())]);
|
|
94
94
|
|
|
95
|
-
if (!this.#classes.has(
|
|
96
|
-
this.#classes.set(
|
|
95
|
+
if (!this.#classes.has(importFile)) {
|
|
96
|
+
this.#classes.set(importFile, new Map());
|
|
97
97
|
}
|
|
98
98
|
|
|
99
99
|
let changes = 0;
|
|
100
100
|
|
|
101
|
-
|
|
102
|
-
* Determine delta based on the various classes (if being added, removed or updated)
|
|
103
|
-
*/
|
|
101
|
+
// Determine delta based on the various classes (if being added, removed or updated)
|
|
104
102
|
for (const k of keys) {
|
|
105
103
|
if (!next.has(k)) {
|
|
106
104
|
changes += 1;
|
|
107
105
|
this.emit({ type: 'removing', prev: prev.get(k)! });
|
|
108
|
-
this.#classes.get(
|
|
106
|
+
this.#classes.get(importFile)!.delete(k);
|
|
109
107
|
} else {
|
|
110
|
-
this.#classes.get(
|
|
108
|
+
this.#classes.get(importFile)!.set(k, next.get(k)!);
|
|
111
109
|
if (!prev.has(k)) {
|
|
112
110
|
changes += 1;
|
|
113
111
|
this.emit({ type: 'added', curr: next.get(k)! });
|
|
114
112
|
} else {
|
|
115
|
-
const
|
|
116
|
-
const
|
|
117
|
-
if (
|
|
113
|
+
const prevHash = describeFunction(prev.get(k)!)?.hash;
|
|
114
|
+
const nextHash = describeFunction(next.get(k)!)?.hash;
|
|
115
|
+
if (prevHash !== nextHash) {
|
|
118
116
|
changes += 1;
|
|
119
117
|
this.emit({ type: 'changed', curr: next.get(k)!, prev: prev.get(k) });
|
|
120
118
|
}
|
|
121
119
|
}
|
|
122
120
|
}
|
|
123
121
|
}
|
|
124
|
-
|
|
125
|
-
this.#emitter.emit('unchanged-file', file);
|
|
126
|
-
}
|
|
122
|
+
return changes;
|
|
127
123
|
}
|
|
128
124
|
```
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@travetto/registry",
|
|
3
|
-
"version": "5.0.0-rc.
|
|
3
|
+
"version": "5.0.0-rc.10",
|
|
4
4
|
"description": "Patterns and utilities for handling registration of metadata and functionality for run-time use",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ast-transformations",
|
|
@@ -27,11 +27,11 @@
|
|
|
27
27
|
"directory": "module/registry"
|
|
28
28
|
},
|
|
29
29
|
"dependencies": {
|
|
30
|
-
"@travetto/
|
|
30
|
+
"@travetto/runtime": "^5.0.0-rc.10"
|
|
31
31
|
},
|
|
32
32
|
"peerDependencies": {
|
|
33
|
-
"@travetto/cli": "^5.0.0-rc.
|
|
34
|
-
"@travetto/transformer": "^5.0.0-rc.
|
|
33
|
+
"@travetto/cli": "^5.0.0-rc.11",
|
|
34
|
+
"@travetto/transformer": "^5.0.0-rc.7"
|
|
35
35
|
},
|
|
36
36
|
"peerDependenciesMeta": {
|
|
37
37
|
"@travetto/transformer": {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Module } from 'node:module';
|
|
2
2
|
|
|
3
|
-
import { path
|
|
4
|
-
import {
|
|
3
|
+
import { path } from '@travetto/manifest';
|
|
4
|
+
import { Runtime, RuntimeIndex } from '@travetto/runtime';
|
|
5
5
|
|
|
6
6
|
import { RetargettingProxy } from '../proxy';
|
|
7
7
|
|
|
@@ -32,7 +32,7 @@ export class DynamicCommonjsLoader {
|
|
|
32
32
|
mod = moduleLoad.apply(null, [request, parent]);
|
|
33
33
|
} catch (err: unknown) {
|
|
34
34
|
const name = Module._resolveFilename!(request, parent);
|
|
35
|
-
if (err instanceof Error &&
|
|
35
|
+
if (err instanceof Error && Runtime.dynamic && !name.startsWith('test/')) {
|
|
36
36
|
const errMsg = err.message;
|
|
37
37
|
console.debug(`Unable to load ${name}: stubbing out with error proxy.`, errMsg);
|
|
38
38
|
const e = (): never => { throw new Error(errMsg); };
|
|
@@ -62,8 +62,7 @@ export class DynamicCommonjsLoader {
|
|
|
62
62
|
} else {
|
|
63
63
|
this.#modules.get(file)!.setTarget(mod);
|
|
64
64
|
}
|
|
65
|
-
|
|
66
|
-
return this.#modules.get(file)!.get() as T;
|
|
65
|
+
return this.#modules.get(file)!.get<T>();
|
|
67
66
|
}
|
|
68
67
|
|
|
69
68
|
async init(): Promise<void> {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { ManifestModuleUtil
|
|
2
|
-
import { watchCompiler, WatchEvent,
|
|
1
|
+
import { ManifestModuleUtil } from '@travetto/manifest';
|
|
2
|
+
import { watchCompiler, WatchEvent, Runtime, RuntimeIndex } from '@travetto/runtime';
|
|
3
3
|
|
|
4
4
|
interface ModuleLoader {
|
|
5
5
|
init?(): Promise<void>;
|
|
@@ -24,7 +24,7 @@ class $DynamicFileLoader {
|
|
|
24
24
|
await this.#loader.unload(ev.output);
|
|
25
25
|
}
|
|
26
26
|
if (ev.action === 'create' || ev.action === 'delete') {
|
|
27
|
-
RuntimeIndex.reinitForModule(
|
|
27
|
+
RuntimeIndex.reinitForModule(Runtime.main.name);
|
|
28
28
|
}
|
|
29
29
|
if (ev.action === 'create' || ev.action === 'update') {
|
|
30
30
|
await this.#loader.load(ev.output);
|
package/src/proxy.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
const ProxyTargetⲐ = Symbol.for('@travetto/
|
|
1
|
+
import { Any, castKey, castTo, classConstruct } from '@travetto/runtime';
|
|
2
|
+
|
|
3
|
+
const ProxyTargetⲐ = Symbol.for('@travetto/runtime:proxy-target');
|
|
4
4
|
|
|
5
5
|
const AsyncGeneratorFunction = Object.getPrototypeOf(async function* () { });
|
|
6
6
|
const GeneratorFunction = Object.getPrototypeOf(function* () { });
|
|
@@ -14,8 +14,7 @@ function isFunction(o: unknown): o is Function {
|
|
|
14
14
|
/**
|
|
15
15
|
* Handler for for proxying modules while watching
|
|
16
16
|
*/
|
|
17
|
-
|
|
18
|
-
export class RetargettingHandler<T> implements ProxyHandler<any> {
|
|
17
|
+
export class RetargettingHandler<T> implements ProxyHandler<Any> {
|
|
19
18
|
constructor(public target: T) { }
|
|
20
19
|
|
|
21
20
|
isExtensible(target: T): boolean {
|
|
@@ -35,31 +34,26 @@ export class RetargettingHandler<T> implements ProxyHandler<any> {
|
|
|
35
34
|
}
|
|
36
35
|
|
|
37
36
|
apply(target: T, thisArg: T, argArray?: unknown[]): unknown {
|
|
38
|
-
|
|
39
|
-
return (this.target as unknown as Function).apply(this.target, argArray);
|
|
37
|
+
return castTo<Function>(this.target).apply(this.target, argArray);
|
|
40
38
|
}
|
|
41
39
|
|
|
42
40
|
construct(target: T, argArray: unknown[], newTarget?: unknown): object {
|
|
43
|
-
|
|
44
|
-
return new (this.target as unknown as ConcreteClass)(...argArray);
|
|
41
|
+
return classConstruct(castTo(this.target), argArray);
|
|
45
42
|
}
|
|
46
43
|
|
|
47
44
|
setPrototypeOf(target: T, v: unknown): boolean {
|
|
48
|
-
|
|
49
|
-
return Object.setPrototypeOf(this.target, v as Record<string, unknown>);
|
|
45
|
+
return Object.setPrototypeOf(this.target, castTo(v));
|
|
50
46
|
}
|
|
51
47
|
|
|
52
48
|
getPrototypeOf(target: T): object | null {
|
|
53
49
|
return Object.getPrototypeOf(this.target);
|
|
54
50
|
}
|
|
55
51
|
|
|
56
|
-
|
|
57
|
-
get(target: T, prop: PropertyKey, receiver: unknown): any {
|
|
52
|
+
get(target: T, prop: PropertyKey, receiver: unknown): Any {
|
|
58
53
|
if (prop === ProxyTargetⲐ) {
|
|
59
54
|
return this.target;
|
|
60
55
|
}
|
|
61
|
-
|
|
62
|
-
let ret = this.target[prop as keyof T];
|
|
56
|
+
let ret = this.target[castKey<T>(prop)];
|
|
63
57
|
if (isFunction(ret) && !/^class\s/.test(Function.prototype.toString.call(ret))) {
|
|
64
58
|
// Bind class members to class instance instead of proxy propagating
|
|
65
59
|
ret = ret.bind(this.target);
|
|
@@ -68,13 +62,11 @@ export class RetargettingHandler<T> implements ProxyHandler<any> {
|
|
|
68
62
|
}
|
|
69
63
|
|
|
70
64
|
has(target: T, prop: PropertyKey): boolean {
|
|
71
|
-
|
|
72
|
-
return (this.target as Object).hasOwnProperty(prop);
|
|
65
|
+
return castTo<object>(this.target).hasOwnProperty(prop);
|
|
73
66
|
}
|
|
74
67
|
|
|
75
68
|
set(target: T, prop: PropertyKey, value: unknown): boolean {
|
|
76
|
-
|
|
77
|
-
this.target[prop as keyof T] = value as any;
|
|
69
|
+
this.target[castKey<T>(prop)] = castTo(value);
|
|
78
70
|
return true;
|
|
79
71
|
}
|
|
80
72
|
|
|
@@ -86,8 +78,7 @@ export class RetargettingHandler<T> implements ProxyHandler<any> {
|
|
|
86
78
|
}
|
|
87
79
|
|
|
88
80
|
deleteProperty(target: T, p: PropertyKey): boolean {
|
|
89
|
-
|
|
90
|
-
return delete this.target[p as keyof T];
|
|
81
|
+
return delete this.target[castKey<T>(p)];
|
|
91
82
|
}
|
|
92
83
|
|
|
93
84
|
defineProperty(target: T, p: PropertyKey, attributes: PropertyDescriptor): boolean {
|
|
@@ -107,8 +98,7 @@ export class RetargettingProxy<T> {
|
|
|
107
98
|
* Unwrap proxy
|
|
108
99
|
*/
|
|
109
100
|
static unwrap<U>(el: U): U {
|
|
110
|
-
|
|
111
|
-
return (el ? ((el as any)[ProxyTargetⲐ] ?? el) : el) as U;
|
|
101
|
+
return castTo<{ [ProxyTargetⲐ]: U }>(el)?.[ProxyTargetⲐ] ?? el;
|
|
112
102
|
}
|
|
113
103
|
|
|
114
104
|
#handler: RetargettingHandler<T>;
|
|
@@ -116,8 +106,7 @@ export class RetargettingProxy<T> {
|
|
|
116
106
|
|
|
117
107
|
constructor(initial: T) {
|
|
118
108
|
this.#handler = new RetargettingHandler(initial);
|
|
119
|
-
|
|
120
|
-
this.#instance = new Proxy({}, this.#handler as ProxyHandler<object>);
|
|
109
|
+
this.#instance = new Proxy({}, castTo(this.#handler));
|
|
121
110
|
}
|
|
122
111
|
|
|
123
112
|
setTarget(next: T): void {
|
|
@@ -130,8 +119,7 @@ export class RetargettingProxy<T> {
|
|
|
130
119
|
return this.#handler.target;
|
|
131
120
|
}
|
|
132
121
|
|
|
133
|
-
get():
|
|
134
|
-
|
|
135
|
-
return this.#instance as T;
|
|
122
|
+
get<V extends T>(): V {
|
|
123
|
+
return castTo(this.#instance);
|
|
136
124
|
}
|
|
137
125
|
}
|
package/src/registry.ts
CHANGED
package/src/service/metadata.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Class } from '@travetto/
|
|
1
|
+
import { Class } from '@travetto/runtime';
|
|
2
2
|
|
|
3
3
|
import { Registry } from '../registry';
|
|
4
4
|
import { ChangeEvent } from '../types';
|
|
@@ -107,8 +107,7 @@ export abstract class MetadataRegistry<C extends { class: Class }, M = unknown,
|
|
|
107
107
|
* Find parent class for a given class object
|
|
108
108
|
*/
|
|
109
109
|
getParentClass(cls: Class): Class | null {
|
|
110
|
-
|
|
111
|
-
const parent = Object.getPrototypeOf(cls) as Class;
|
|
110
|
+
const parent: Class = Object.getPrototypeOf(cls);
|
|
112
111
|
return parent.name && parent !== Object ? parent : null;
|
|
113
112
|
}
|
|
114
113
|
|
package/src/service/root.ts
CHANGED
|
@@ -1,23 +1,26 @@
|
|
|
1
1
|
import { EventEmitter } from 'node:events';
|
|
2
2
|
|
|
3
|
-
import { type FindConfig
|
|
4
|
-
import { Class, Env } from '@travetto/
|
|
3
|
+
import { type FindConfig } from '@travetto/manifest';
|
|
4
|
+
import { Class, Env, Runtime, RuntimeIndex, describeFunction, flushPendingFunctions } from '@travetto/runtime';
|
|
5
5
|
|
|
6
6
|
import { DynamicFileLoader } from '../internal/file-loader';
|
|
7
7
|
import { ChangeSource, ChangeEvent, ChangeHandler } from '../types';
|
|
8
|
-
import { PendingRegister } from '../decorator';
|
|
9
8
|
|
|
10
9
|
const moduleFindConfig: FindConfig = {
|
|
11
10
|
module: (m) => {
|
|
12
11
|
const role = Env.TRV_ROLE.val;
|
|
13
12
|
return m.roles.includes('std') && (
|
|
14
|
-
!
|
|
13
|
+
!Runtime.production || m.prod ||
|
|
15
14
|
((role === 'doc' || role === 'test') && m.roles.includes(role))
|
|
16
15
|
);
|
|
17
16
|
},
|
|
18
17
|
folder: f => f === 'src' || f === '$index'
|
|
19
18
|
};
|
|
20
19
|
|
|
20
|
+
function isClass(cls: Function): cls is Class {
|
|
21
|
+
return !!describeFunction(cls).class;
|
|
22
|
+
}
|
|
23
|
+
|
|
21
24
|
/**
|
|
22
25
|
* A class change source. Meant to be hooked into the
|
|
23
26
|
* compiler as a way to listen to changes via the compiler
|
|
@@ -37,63 +40,76 @@ export class ClassSource implements ChangeSource<Class> {
|
|
|
37
40
|
* Flush classes
|
|
38
41
|
*/
|
|
39
42
|
#flush(): void {
|
|
40
|
-
for (const
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
this.#classes.set(file, new Map());
|
|
45
|
-
for (const cls of classes) {
|
|
46
|
-
const src = RuntimeIndex.getFunctionMetadata(cls)!.source;
|
|
47
|
-
this.#classes.get(src)!.set(cls.Ⲑid, cls);
|
|
48
|
-
this.emit({ type: 'added', curr: cls });
|
|
43
|
+
for (const cls of flushPendingFunctions().filter(isClass)) {
|
|
44
|
+
const src = Runtime.getImport(cls);
|
|
45
|
+
if (!this.#classes.has(src)) {
|
|
46
|
+
this.#classes.set(src, new Map());
|
|
49
47
|
}
|
|
48
|
+
this.#classes.get(src)!.set(cls.Ⲑid, cls);
|
|
49
|
+
this.emit({ type: 'added', curr: cls });
|
|
50
50
|
}
|
|
51
51
|
}
|
|
52
52
|
|
|
53
53
|
/**
|
|
54
|
-
*
|
|
54
|
+
* Process changes for a single file, looking for add/remove/update of classes
|
|
55
55
|
*/
|
|
56
|
-
#handleFileChanges(
|
|
56
|
+
#handleFileChanges(importFile: string, classes: Class[] = []): number {
|
|
57
57
|
const next = new Map<string, Class>(classes.map(cls => [cls.Ⲑid, cls] as const));
|
|
58
58
|
|
|
59
59
|
let prev = new Map<string, Class>();
|
|
60
|
-
if (this.#classes.has(
|
|
61
|
-
prev = new Map(this.#classes.get(
|
|
60
|
+
if (this.#classes.has(importFile)) {
|
|
61
|
+
prev = new Map(this.#classes.get(importFile)!.entries());
|
|
62
62
|
}
|
|
63
63
|
|
|
64
64
|
const keys = new Set([...Array.from(prev.keys()), ...Array.from(next.keys())]);
|
|
65
65
|
|
|
66
|
-
if (!this.#classes.has(
|
|
67
|
-
this.#classes.set(
|
|
66
|
+
if (!this.#classes.has(importFile)) {
|
|
67
|
+
this.#classes.set(importFile, new Map());
|
|
68
68
|
}
|
|
69
69
|
|
|
70
70
|
let changes = 0;
|
|
71
71
|
|
|
72
|
-
|
|
73
|
-
* Determine delta based on the various classes (if being added, removed or updated)
|
|
74
|
-
*/
|
|
72
|
+
// Determine delta based on the various classes (if being added, removed or updated)
|
|
75
73
|
for (const k of keys) {
|
|
76
74
|
if (!next.has(k)) {
|
|
77
75
|
changes += 1;
|
|
78
76
|
this.emit({ type: 'removing', prev: prev.get(k)! });
|
|
79
|
-
this.#classes.get(
|
|
77
|
+
this.#classes.get(importFile)!.delete(k);
|
|
80
78
|
} else {
|
|
81
|
-
this.#classes.get(
|
|
79
|
+
this.#classes.get(importFile)!.set(k, next.get(k)!);
|
|
82
80
|
if (!prev.has(k)) {
|
|
83
81
|
changes += 1;
|
|
84
82
|
this.emit({ type: 'added', curr: next.get(k)! });
|
|
85
83
|
} else {
|
|
86
|
-
const
|
|
87
|
-
const
|
|
88
|
-
if (
|
|
84
|
+
const prevHash = describeFunction(prev.get(k)!)?.hash;
|
|
85
|
+
const nextHash = describeFunction(next.get(k)!)?.hash;
|
|
86
|
+
if (prevHash !== nextHash) {
|
|
89
87
|
changes += 1;
|
|
90
88
|
this.emit({ type: 'changed', curr: next.get(k)!, prev: prev.get(k) });
|
|
91
89
|
}
|
|
92
90
|
}
|
|
93
91
|
}
|
|
94
92
|
}
|
|
95
|
-
|
|
96
|
-
|
|
93
|
+
return changes;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Process all class changes
|
|
98
|
+
*/
|
|
99
|
+
#handleChanges(classes: Class[] = []): void {
|
|
100
|
+
const classesByFile = new Map<string, Class[]>();
|
|
101
|
+
for (const el of classes) {
|
|
102
|
+
const imp = Runtime.getImport(el);
|
|
103
|
+
if (!classesByFile.has(imp)) {
|
|
104
|
+
classesByFile.set(imp, []);
|
|
105
|
+
}
|
|
106
|
+
classesByFile.get(imp)!.push(el);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
for (const [imp, els] of classesByFile.entries()) {
|
|
110
|
+
if (!this.#handleFileChanges(imp, els)) {
|
|
111
|
+
this.#emitter.emit('unchanged-import', imp);
|
|
112
|
+
}
|
|
97
113
|
}
|
|
98
114
|
}
|
|
99
115
|
|
|
@@ -111,11 +127,10 @@ export class ClassSource implements ChangeSource<Class> {
|
|
|
111
127
|
* Initialize
|
|
112
128
|
*/
|
|
113
129
|
async init(): Promise<void> {
|
|
114
|
-
if (
|
|
130
|
+
if (Runtime.dynamic) {
|
|
115
131
|
DynamicFileLoader.onLoadEvent(ev => {
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
}
|
|
132
|
+
this.#handleChanges(flushPendingFunctions().filter(isClass));
|
|
133
|
+
|
|
119
134
|
if (ev.action === 'create') {
|
|
120
135
|
this.#flush();
|
|
121
136
|
}
|
|
@@ -124,8 +139,8 @@ export class ClassSource implements ChangeSource<Class> {
|
|
|
124
139
|
}
|
|
125
140
|
|
|
126
141
|
// Ensure everything is loaded
|
|
127
|
-
for (const
|
|
128
|
-
await
|
|
142
|
+
for (const entry of RuntimeIndex.find(moduleFindConfig)) {
|
|
143
|
+
await Runtime.importFrom(entry.import);
|
|
129
144
|
}
|
|
130
145
|
|
|
131
146
|
// Flush all load events
|
|
@@ -140,9 +155,9 @@ export class ClassSource implements ChangeSource<Class> {
|
|
|
140
155
|
}
|
|
141
156
|
|
|
142
157
|
/**
|
|
143
|
-
* Add callback for when a
|
|
158
|
+
* Add callback for when a import is changed, but emits no class changes
|
|
144
159
|
*/
|
|
145
|
-
onNonClassChanges(callback: (
|
|
146
|
-
this.#emitter.on('unchanged-
|
|
160
|
+
onNonClassChanges(callback: (imp: string) => void): void {
|
|
161
|
+
this.#emitter.on('unchanged-import', callback);
|
|
147
162
|
}
|
|
148
163
|
}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { EventEmitter } from 'node:events';
|
|
2
2
|
|
|
3
|
-
import { Class } from '@travetto/
|
|
4
|
-
import { RuntimeIndex } from '@travetto/manifest';
|
|
3
|
+
import { Class, describeFunction } from '@travetto/runtime';
|
|
5
4
|
|
|
6
5
|
import { ChangeSource, ChangeEvent, ChangeHandler } from '../types';
|
|
7
6
|
|
|
@@ -30,8 +29,8 @@ export class MethodSource implements ChangeSource<[Class, Function]> {
|
|
|
30
29
|
* On a class being emitted, check methods
|
|
31
30
|
*/
|
|
32
31
|
onClassEvent(e: ChangeEvent<Class>): void {
|
|
33
|
-
const next =
|
|
34
|
-
const prev =
|
|
32
|
+
const next = describeFunction(e.curr!)?.methods ?? {};
|
|
33
|
+
const prev = describeFunction(e.prev!)?.methods ?? {};
|
|
35
34
|
|
|
36
35
|
/**
|
|
37
36
|
* Go through each method, comparing hashes. To see added/removed and changed
|
package/src/decorator.ts
DELETED
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
import { Class } from '@travetto/base';
|
|
2
|
-
import { RuntimeIndex } from '@travetto/manifest';
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Register a class as pending
|
|
6
|
-
*/
|
|
7
|
-
class $PendingRegister {
|
|
8
|
-
map = new Map<string, Class[]>();
|
|
9
|
-
ordered: [string, Class[]][] = [];
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* Register class as pending
|
|
13
|
-
*/
|
|
14
|
-
add(cls: Class): void {
|
|
15
|
-
const src = RuntimeIndex.getFunctionMetadata(cls)!.source;
|
|
16
|
-
if (!this.map.has(src)) {
|
|
17
|
-
const sub: Class[] = [];
|
|
18
|
-
this.map.set(src, sub);
|
|
19
|
-
this.ordered.push([src, sub]);
|
|
20
|
-
}
|
|
21
|
-
this.map.get(src)!.push(cls);
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
/**
|
|
25
|
-
* Clear pending classes
|
|
26
|
-
*/
|
|
27
|
-
flush(log?: boolean): [string, Class[]][] {
|
|
28
|
-
if (log) {
|
|
29
|
-
console.debug('Pending changes', { changes: this.ordered.map(([, x]) => x.map(y => y.Ⲑid)) });
|
|
30
|
-
}
|
|
31
|
-
const out = this.ordered.slice(0);
|
|
32
|
-
this.map.clear();
|
|
33
|
-
this.ordered = [];
|
|
34
|
-
return out;
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
export const PendingRegister = new $PendingRegister();
|
|
39
|
-
|
|
40
|
-
/**
|
|
41
|
-
* Decorator to track class as pending
|
|
42
|
-
*/
|
|
43
|
-
export const Register = () =>
|
|
44
|
-
(target: Class): void => PendingRegister.add(target);
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
import ts from 'typescript';
|
|
2
|
-
|
|
3
|
-
import { TransformerState, AfterClass, DecoratorUtil } from '@travetto/transformer';
|
|
4
|
-
|
|
5
|
-
const REGISTER_MOD = '@travetto/registry/src/decorator';
|
|
6
|
-
const SKIP_SRC = /^@travetto\/(base|manifest)\/(src|support)/;
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* Registration of all classes to support the registry
|
|
10
|
-
*/
|
|
11
|
-
export class RegisterTransformer {
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* After visiting each class, register all the collected metadata
|
|
15
|
-
*/
|
|
16
|
-
@AfterClass()
|
|
17
|
-
static registerClass(state: TransformerState, node: ts.ClassDeclaration): ts.ClassDeclaration {
|
|
18
|
-
if (
|
|
19
|
-
state.importName === REGISTER_MOD ||
|
|
20
|
-
SKIP_SRC.test(state.importName)
|
|
21
|
-
) { // Cannot process self
|
|
22
|
-
return node;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
return state.factory.updateClassDeclaration(
|
|
26
|
-
node,
|
|
27
|
-
DecoratorUtil.spliceDecorators(
|
|
28
|
-
node, undefined, [state.createDecorator(REGISTER_MOD, 'Register')], 0
|
|
29
|
-
),
|
|
30
|
-
node.name,
|
|
31
|
-
node.typeParameters,
|
|
32
|
-
node.heritageClauses,
|
|
33
|
-
node.members
|
|
34
|
-
);
|
|
35
|
-
}
|
|
36
|
-
}
|