@travetto/runtime 5.0.0-rc.3 → 5.0.0-rc.4
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 +11 -4
- package/__index__.ts +1 -0
- package/package.json +6 -3
- package/src/context.ts +7 -2
- package/src/debug.ts +18 -0
- package/src/function.ts +26 -9
- package/src/trv.d.ts +6 -1
- package/src/types.ts +12 -1
- package/support/transformer.debug-method.ts +41 -0
- package/support/transformer.function-metadata.ts +9 -2
package/README.md
CHANGED
|
@@ -61,12 +61,14 @@ class $Runtime {
|
|
|
61
61
|
/** Resolve resource paths */
|
|
62
62
|
resourcePaths(paths: string[] = []): string[];
|
|
63
63
|
/** Get source for function */
|
|
64
|
-
|
|
64
|
+
getSourceFile(fn: Function): string;
|
|
65
|
+
/** Get import for function */
|
|
66
|
+
getImport(fn: Function): string;
|
|
65
67
|
}
|
|
66
68
|
```
|
|
67
69
|
|
|
68
70
|
## Environment Support
|
|
69
|
-
The functionality we support for testing and retrieving environment information for known environment variables. They can be accessed directly on the [Env](https://github.com/travetto/travetto/tree/main/module/runtime/src/env.ts#
|
|
71
|
+
The functionality we support for testing and retrieving environment information for known environment variables. They can be accessed directly on the [Env](https://github.com/travetto/travetto/tree/main/module/runtime/src/env.ts#L108) object, and will return a scoped [EnvProp](https://github.com/travetto/travetto/tree/main/module/runtime/src/env.ts#L4), that is compatible with the property definition. E.g. only showing boolean related fields when the underlying flag supports `true` or `false`
|
|
70
72
|
|
|
71
73
|
**Code: Base Known Environment Flags**
|
|
72
74
|
```typescript
|
|
@@ -118,7 +120,12 @@ interface TravettoEnv {
|
|
|
118
120
|
/**
|
|
119
121
|
* trvc log level
|
|
120
122
|
*/
|
|
121
|
-
TRV_BUILD: 'none' | 'info' | 'debug' | 'error' | 'warn'
|
|
123
|
+
TRV_BUILD: 'none' | 'info' | 'debug' | 'error' | 'warn',
|
|
124
|
+
/**
|
|
125
|
+
* Should break on first line of a method when using the @DebugBreak decorator
|
|
126
|
+
* @default false
|
|
127
|
+
*/
|
|
128
|
+
TRV_DEBUG_BREAK: boolean;
|
|
122
129
|
}
|
|
123
130
|
```
|
|
124
131
|
|
|
@@ -245,7 +252,7 @@ The primary access patterns for resources, is to directly request a file, and to
|
|
|
245
252
|
|
|
246
253
|
The [FileLoader](https://github.com/travetto/travetto/tree/main/module/runtime/src/file-loader.ts#L11) allows for accessing information about the resources, and subsequently reading the file as text/binary or to access the resource as a `Readable` stream. If a file is not found, it will throw an [AppError](https://github.com/travetto/travetto/tree/main/module/runtime/src/error.ts#L13) with a category of 'notfound'.
|
|
247
254
|
|
|
248
|
-
The [FileLoader](https://github.com/travetto/travetto/tree/main/module/runtime/src/file-loader.ts#L11) also supports tying itself to [Env](https://github.com/travetto/travetto/tree/main/module/runtime/src/env.ts#
|
|
255
|
+
The [FileLoader](https://github.com/travetto/travetto/tree/main/module/runtime/src/file-loader.ts#L11) also supports tying itself to [Env](https://github.com/travetto/travetto/tree/main/module/runtime/src/env.ts#L108)'s `TRV_RESOURCES` information on where to attempt to find a requested resource.
|
|
249
256
|
|
|
250
257
|
## Common Utilities
|
|
251
258
|
Common utilities used throughout the framework. Currently [Util](https://github.com/travetto/travetto/tree/main/module/runtime/src/util.ts#L17) includes:
|
package/__index__.ts
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@travetto/runtime",
|
|
3
|
-
"version": "5.0.0-rc.
|
|
3
|
+
"version": "5.0.0-rc.4",
|
|
4
4
|
"description": "Runtime for travetto applications.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"console-manager",
|
|
@@ -24,14 +24,17 @@
|
|
|
24
24
|
"url": "https://github.com/travetto/travetto.git",
|
|
25
25
|
"directory": "module/runtime"
|
|
26
26
|
},
|
|
27
|
+
"engines": {
|
|
28
|
+
"node": ">=22.0.0"
|
|
29
|
+
},
|
|
27
30
|
"dependencies": {
|
|
28
31
|
"@travetto/manifest": "^5.0.0-rc.2",
|
|
29
32
|
"@types/debug": "^4.1.12",
|
|
30
|
-
"@types/node": "^
|
|
33
|
+
"@types/node": "^22.1.0",
|
|
31
34
|
"debug": "^4.3.5"
|
|
32
35
|
},
|
|
33
36
|
"peerDependencies": {
|
|
34
|
-
"@travetto/transformer": "^5.0.0-rc.
|
|
37
|
+
"@travetto/transformer": "^5.0.0-rc.3"
|
|
35
38
|
},
|
|
36
39
|
"peerDependenciesMeta": {
|
|
37
40
|
"@travetto/transformer": {
|
package/src/context.ts
CHANGED
|
@@ -93,8 +93,13 @@ class $Runtime {
|
|
|
93
93
|
}
|
|
94
94
|
|
|
95
95
|
/** Get source for function */
|
|
96
|
-
|
|
97
|
-
return this.#idx.getFromImport(
|
|
96
|
+
getSourceFile(fn: Function): string {
|
|
97
|
+
return this.#idx.getFromImport(this.getImport(fn))?.sourceFile!;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/** Get import for function */
|
|
101
|
+
getImport(fn: Function): string {
|
|
102
|
+
return describeFunction(fn).import;
|
|
98
103
|
}
|
|
99
104
|
}
|
|
100
105
|
|
package/src/debug.ts
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { Env } from './env';
|
|
2
|
+
import { ClassInstance } from './types';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* The `@DebugBreak` indicates that a function inserts an optional debugger keyword to stop on entry
|
|
6
|
+
* @augments `@travetto/runtime:DebugBreak`
|
|
7
|
+
*/
|
|
8
|
+
export function DebugBreak(): MethodDecorator {
|
|
9
|
+
return (inst: ClassInstance, prop: string | symbol, descriptor: PropertyDescriptor) => descriptor;
|
|
10
|
+
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Determine if we should invoke the debugger
|
|
15
|
+
*/
|
|
16
|
+
export function tryDebugger(): boolean {
|
|
17
|
+
return Env.TRV_DEBUG_BREAK.isTrue;
|
|
18
|
+
}
|
package/src/function.ts
CHANGED
|
@@ -1,14 +1,19 @@
|
|
|
1
|
-
export type FunctionMetadataTag = { hash: number, lines: [number, number] };
|
|
1
|
+
export type FunctionMetadataTag = { hash: number, lines: [start: number, end: number, bodyStart?: number] };
|
|
2
2
|
export type FunctionMetadata = FunctionMetadataTag & {
|
|
3
3
|
id: string;
|
|
4
4
|
import: string;
|
|
5
|
+
module: string;
|
|
6
|
+
modulePath: string;
|
|
5
7
|
methods?: Record<string, FunctionMetadataTag>;
|
|
6
8
|
synthetic?: boolean;
|
|
9
|
+
class?: boolean;
|
|
7
10
|
abstract?: boolean;
|
|
8
11
|
};
|
|
9
12
|
|
|
10
13
|
const METADATA = Symbol.for('@travetto/runtime:function-metadata');
|
|
11
14
|
|
|
15
|
+
const pending = new Set<Function>([]);
|
|
16
|
+
|
|
12
17
|
/**
|
|
13
18
|
* Initialize the meta data for a function/class
|
|
14
19
|
* @param fn Class
|
|
@@ -20,16 +25,28 @@ const METADATA = Symbol.for('@travetto/runtime:function-metadata');
|
|
|
20
25
|
* @param `synthetic` Is this code generated at build time
|
|
21
26
|
* @private
|
|
22
27
|
*/
|
|
23
|
-
export function
|
|
24
|
-
fn: Function,
|
|
28
|
+
export function registerFunction(
|
|
29
|
+
fn: Function, [pkg, pth]: [string, string], tag: FunctionMetadataTag,
|
|
25
30
|
methods?: Record<string, FunctionMetadataTag>, abstract?: boolean, synthetic?: boolean
|
|
26
31
|
): void {
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
32
|
+
const metadata = {
|
|
33
|
+
id: fn.name ? `${pkg}:${pth}○${fn.name}` : `${pkg}:${pth}`,
|
|
34
|
+
import: `${pkg}/${pth}`,
|
|
35
|
+
module: pkg,
|
|
36
|
+
modulePath: pth,
|
|
37
|
+
...tag, methods, abstract, synthetic, class: abstract !== undefined
|
|
38
|
+
};
|
|
39
|
+
pending.add(fn);
|
|
40
|
+
Object.defineProperties(fn, { Ⲑid: { value: metadata.id }, [METADATA]: { value: metadata } });
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Flush all pending function registers
|
|
45
|
+
*/
|
|
46
|
+
export function flushPendingFunctions(): Function[] {
|
|
47
|
+
const fns = [...pending];
|
|
48
|
+
pending.clear();
|
|
49
|
+
return fns;
|
|
33
50
|
}
|
|
34
51
|
|
|
35
52
|
/**
|
package/src/trv.d.ts
CHANGED
|
@@ -54,6 +54,11 @@ declare global {
|
|
|
54
54
|
/**
|
|
55
55
|
* trvc log level
|
|
56
56
|
*/
|
|
57
|
-
TRV_BUILD: 'none' | 'info' | 'debug' | 'error' | 'warn'
|
|
57
|
+
TRV_BUILD: 'none' | 'info' | 'debug' | 'error' | 'warn',
|
|
58
|
+
/**
|
|
59
|
+
* Should break on first line of a method when using the @DebugBreak decorator
|
|
60
|
+
* @default false
|
|
61
|
+
*/
|
|
62
|
+
TRV_DEBUG_BREAK: boolean;
|
|
58
63
|
}
|
|
59
64
|
}
|
package/src/types.ts
CHANGED
|
@@ -5,8 +5,19 @@ export type ClassInstance<T = any> = T & {
|
|
|
5
5
|
constructor: ConcreteClass<T> & { Ⲑid: string };
|
|
6
6
|
};
|
|
7
7
|
|
|
8
|
+
export type AnyMap = {
|
|
9
|
+
[key: string]: any
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
export type Primitive = number | bigint | boolean | string | Date;
|
|
13
|
+
|
|
14
|
+
export type DeepPartial<T> = {
|
|
15
|
+
[P in keyof T]?: (T[P] extends (Primitive | undefined) ? (T[P] | undefined) :
|
|
16
|
+
(T[P] extends any[] ? (DeepPartial<T[P][number]> | null | undefined)[] : DeepPartial<T[P]>));
|
|
17
|
+
};
|
|
18
|
+
|
|
8
19
|
export const TypedObject: {
|
|
9
20
|
keys<T = unknown, K extends keyof T = keyof T>(o: T): K[];
|
|
10
21
|
fromEntries<K extends string | symbol, V>(items: ([K, V] | readonly [K, V])[]): Record<K, V>;
|
|
11
22
|
entries<K extends Record<symbol | string, unknown>>(record: K): [keyof K, K[keyof K]][];
|
|
12
|
-
} & ObjectConstructor = Object;
|
|
23
|
+
} & ObjectConstructor = Object;
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import ts from 'typescript';
|
|
2
|
+
|
|
3
|
+
import { TransformerState, OnMethod, CoreUtil } from '@travetto/transformer';
|
|
4
|
+
|
|
5
|
+
const DebugⲐ = Symbol.for('@travetto/runtime:debug');
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Debug transformation state
|
|
9
|
+
*/
|
|
10
|
+
interface DebugState {
|
|
11
|
+
[DebugⲐ]?: ts.Expression;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Add debugger-optional statement to methods that should be debuggable
|
|
16
|
+
*/
|
|
17
|
+
export class DebugEntryTransformer {
|
|
18
|
+
|
|
19
|
+
@OnMethod('DebugBreak')
|
|
20
|
+
static debugOnEntry(state: TransformerState & DebugState, node: ts.MethodDeclaration): ts.MethodDeclaration {
|
|
21
|
+
if (!state[DebugⲐ]) {
|
|
22
|
+
const imp = state.importFile('@travetto/runtime/src/debug').ident;
|
|
23
|
+
state[DebugⲐ] = CoreUtil.createAccess(state.factory, imp, 'tryDebugger');
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
return state.factory.updateMethodDeclaration(node,
|
|
27
|
+
node.modifiers,
|
|
28
|
+
node.asteriskToken,
|
|
29
|
+
node.name,
|
|
30
|
+
node.questionToken,
|
|
31
|
+
node.typeParameters,
|
|
32
|
+
node.parameters,
|
|
33
|
+
node.type,
|
|
34
|
+
node.body ? state.factory.updateBlock(node.body, [
|
|
35
|
+
state.factory.createIfStatement(state[DebugⲐ]!,
|
|
36
|
+
state.factory.createExpressionStatement(state.factory.createIdentifier('debugger'))),
|
|
37
|
+
...node.body.statements
|
|
38
|
+
]) : node.body
|
|
39
|
+
);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
@@ -15,6 +15,7 @@ const methods = Symbol.for(`${RUNTIME_MOD}:methods`);
|
|
|
15
15
|
const cls = Symbol.for(`${RUNTIME_MOD}:class`);
|
|
16
16
|
const fn = Symbol.for(`${RUNTIME_MOD}:function`);
|
|
17
17
|
const registerImport = Symbol.for(`${RUNTIME_MOD}:registerImport`);
|
|
18
|
+
const registerFn = 'registerFunction';
|
|
18
19
|
|
|
19
20
|
interface MetadataInfo {
|
|
20
21
|
[registerImport]?: Import;
|
|
@@ -32,6 +33,12 @@ export class RegisterTransformer {
|
|
|
32
33
|
const hash = SystemUtil.naiveHash(node.getText());
|
|
33
34
|
try {
|
|
34
35
|
const range = CoreUtil.getRangeOf(state.source, node) ?? [0, 0];
|
|
36
|
+
if (ts.isMethodDeclaration(node) || ts.isFunctionDeclaration(node) || ts.isFunctionExpression(node)) {
|
|
37
|
+
const bodyStart = CoreUtil.getRangeOf(state.source, node?.body?.statements[0])?.[0];
|
|
38
|
+
if (bodyStart) {
|
|
39
|
+
range.push(bodyStart);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
35
42
|
return { hash, lines: range };
|
|
36
43
|
} catch (err) {
|
|
37
44
|
return { hash, lines: [0, 0] };
|
|
@@ -80,7 +87,7 @@ export class RegisterTransformer {
|
|
|
80
87
|
const name = node.name?.escapedText.toString() ?? '';
|
|
81
88
|
|
|
82
89
|
const meta = state.factory.createCallExpression(
|
|
83
|
-
state.createAccess(state[registerImport].ident,
|
|
90
|
+
state.createAccess(state[registerImport].ident, registerFn),
|
|
84
91
|
[],
|
|
85
92
|
[
|
|
86
93
|
state.createIdentifier(name),
|
|
@@ -122,7 +129,7 @@ export class RegisterTransformer {
|
|
|
122
129
|
state[registerImport] ??= state.importFile(REGISTER_IMPORT);
|
|
123
130
|
const tag = this.#tag(state, node);
|
|
124
131
|
const meta = state.factory.createCallExpression(
|
|
125
|
-
state.createAccess(state[registerImport].ident,
|
|
132
|
+
state.createAccess(state[registerImport].ident, registerFn),
|
|
126
133
|
[],
|
|
127
134
|
[
|
|
128
135
|
state.createIdentifier(node.name),
|