@travetto/runtime 5.0.0-rc.2 → 5.0.0-rc.3

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 CHANGED
@@ -14,17 +14,57 @@ yarn add @travetto/runtime
14
14
  ```
15
15
 
16
16
  Runtime is the foundation of all [Travetto](https://travetto.dev) applications. It is intended to be a minimal application set, as well as support for commonly shared functionality. It has support for the following key areas:
17
- * Environment Support
18
17
  * Runtime Context
18
+ * Environment Support
19
+ * Standard Error Support
19
20
  * Console Management
20
21
  * Resource Access
21
- * Standard Error Support
22
22
  * Common Utilities
23
23
  * Time Utilities
24
24
  * Process Execution
25
25
  * Shutdown Management
26
26
  * Path behavior
27
27
 
28
+ ## Runtime Context
29
+ While running any code within the framework, there are common patterns/goals for interacting with the underlying code repository. These include:
30
+ * Determining attributes of the running environment (e.g., name, debug information, production flags)
31
+ * Resolving paths within the workspace (e.g. standard, tooling, resourcing, modules)
32
+
33
+ **Code: Runtime Shape**
34
+ ```typescript
35
+ class $Runtime {
36
+ constructor(idx: ManifestIndex, resourceOverrides?: Record<string, string>);
37
+ /** Get env name, with support for the default env */
38
+ get envName(): string | undefined;
39
+ /** Are we in development mode */
40
+ get production(): boolean;
41
+ /** Is the app in dynamic mode? */
42
+ get dynamic(): boolean;
43
+ /** Get debug value */
44
+ get debug(): false | string;
45
+ /** Manifest main */
46
+ get main(): ManifestContext['main'];
47
+ /** Manifest workspace */
48
+ get workspace(): ManifestContext['workspace'];
49
+ /** Are we running from a mono-root? */
50
+ get monoRoot(): boolean;
51
+ /** Main source path */
52
+ get mainSourcePath(): string;
53
+ /** Produce a workspace relative path */
54
+ workspaceRelative(...rel: string[]): string;
55
+ /** Strip off the workspace path from a file */
56
+ stripWorkspacePath(full: string): string;
57
+ /** Produce a workspace path for tooling, with '@' being replaced by node_module/name folder */
58
+ toolPath(...rel: string[]): string;
59
+ /** Resolve single module path */
60
+ modulePath(modulePath: string): string;
61
+ /** Resolve resource paths */
62
+ resourcePaths(paths: string[] = []): string[];
63
+ /** Get source for function */
64
+ getSource(fn: Function): string;
65
+ }
66
+ ```
67
+
28
68
  ## Environment Support
29
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#L109) 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`
30
70
 
@@ -114,13 +154,6 @@ export class EnvProp<T> {
114
154
  }
115
155
  ```
116
156
 
117
- ## Resource Access
118
- The primary access patterns for resources, is to directly request a file, and to resolve that file either via file-system look up or leveraging the [Manifest](https://github.com/travetto/travetto/tree/main/module/manifest#readme "Support for project indexing, manifesting, along with file watching")'s data for what resources were found at manifesting time.
119
-
120
- 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'.
121
-
122
- 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#L109)'s `TRV_RESOURCES` information on where to attempt to find a requested resource.
123
-
124
157
  ## Standard Error Support
125
158
  While the framework is 100 % compatible with standard `Error` instances, there are cases in which additional functionality is desired. Within the framework we use [AppError](https://github.com/travetto/travetto/tree/main/module/runtime/src/error.ts#L13) (or its derivatives) to represent framework errors. This class is available for use in your own projects. Some of the additional benefits of using this class is enhanced error reporting, as well as better integration with other modules (e.g. the [RESTful API](https://github.com/travetto/travetto/tree/main/module/rest#readme "Declarative api for RESTful APIs with support for the dependency injection module.") module and HTTP status codes).
126
159
 
@@ -146,7 +179,7 @@ The supported operations are:
146
179
 
147
180
  **Note**: All other console methods are excluded, specifically `trace`, `inspect`, `dir`, `time`/`timeEnd`
148
181
 
149
- ## How Logging is Instrumented
182
+ ### How Logging is Instrumented
150
183
  All of the logging instrumentation occurs at transpilation time. All `console.*` methods are replaced with a call to a globally defined variable that delegates to the [ConsoleManager](https://github.com/travetto/travetto/tree/main/module/runtime/src/console.ts#L35). This module, hooks into the [ConsoleManager](https://github.com/travetto/travetto/tree/main/module/runtime/src/console.ts#L35) and receives all logging events from all files compiled by the [Travetto](https://travetto.dev).
151
184
 
152
185
  A sample of the instrumentation would be:
@@ -185,7 +218,7 @@ function work() {
185
218
  }
186
219
  ```
187
220
 
188
- ### Filtering Debug
221
+ #### Filtering Debug
189
222
  The `debug` messages can be filtered using the patterns from the [debug](https://www.npmjs.com/package/debug). You can specify wild cards to only `DEBUG` specific modules, folders or files. You can specify multiple, and you can also add negations to exclude specific packages.
190
223
 
191
224
  **Terminal: Sample environment flags**
@@ -207,6 +240,13 @@ Additionally, the logging framework will merge [debug](https://www.npmjs.com/pac
207
240
  $ DEBUG=express:*,@travetto/rest npx trv run rest
208
241
  ```
209
242
 
243
+ ## Resource Access
244
+ The primary access patterns for resources, is to directly request a file, and to resolve that file either via file-system look up or leveraging the [Manifest](https://github.com/travetto/travetto/tree/main/module/manifest#readme "Support for project indexing, manifesting, along with file watching")'s data for what resources were found at manifesting time.
245
+
246
+ 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
+
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#L109)'s `TRV_RESOURCES` information on where to attempt to find a requested resource.
249
+
210
250
  ## Common Utilities
211
251
  Common utilities used throughout the framework. Currently [Util](https://github.com/travetto/travetto/tree/main/module/runtime/src/util.ts#L17) includes:
212
252
  * `uuid(len: number)` generates a simple uuid for use within the application.
@@ -268,7 +308,7 @@ export class TimeUtil {
268
308
  ```
269
309
 
270
310
  ## Process Execution
271
- [ExecUtil](https://github.com/travetto/travetto/tree/main/module/runtime/src/exec.ts#L39) exposes `getResult` as a means to wrap [child_process](https://nodejs.org/api/child_process.html)'s process object. This wrapper allows for a promise-based resolution of the subprocess with the ability to capture the stderr/stdout.
311
+ [ExecUtil](https://github.com/travetto/travetto/tree/main/module/runtime/src/exec.ts#L41) exposes `getResult` as a means to wrap [child_process](https://nodejs.org/api/child_process.html)'s process object. This wrapper allows for a promise-based resolution of the subprocess with the ability to capture the stderr/stdout.
272
312
 
273
313
  A simple example would be:
274
314
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@travetto/runtime",
3
- "version": "5.0.0-rc.2",
3
+ "version": "5.0.0-rc.3",
4
4
  "description": "Runtime for travetto applications.",
5
5
  "keywords": [
6
6
  "console-manager",
package/src/context.ts CHANGED
@@ -1,100 +1,101 @@
1
1
  import path from 'node:path';
2
2
 
3
- import { type ManifestContext } from '@travetto/manifest';
3
+ import type { ManifestIndex, ManifestContext } from '@travetto/manifest';
4
4
 
5
5
  import { Env } from './env';
6
6
  import { RuntimeIndex } from './manifest-index';
7
7
  import { describeFunction } from './function';
8
8
 
9
- const prod = (): boolean => process.env.NODE_ENV === 'production';
10
-
11
- const OVERRIDES = Env.TRV_RESOURCE_OVERRIDES.object ?? {};
12
-
13
- const MODULE_ALIASES: Record<string, string> = {
14
- '@': RuntimeIndex.manifest.main.name,
15
- '@@': RuntimeIndex.manifest.workspace.path,
16
- };
17
-
18
-
19
9
  /** Constrained version of {@type ManifestContext} */
20
- export const Runtime = {
10
+ class $Runtime {
11
+
12
+ #idx: ManifestIndex;
13
+ #moduleAliases: Record<string, string>;
14
+ #resourceOverrides?: Record<string, string>;
15
+
16
+ constructor(idx: ManifestIndex, resourceOverrides?: Record<string, string>) {
17
+ this.#idx = idx;
18
+ this.#moduleAliases = {
19
+ '@': idx.manifest.main.name,
20
+ '@@': idx.manifest.workspace.path,
21
+ };
22
+ this.#resourceOverrides = resourceOverrides;
23
+ }
24
+
21
25
  /** Get env name, with support for the default env */
22
- get name(): string | undefined {
23
- return Env.TRV_ENV.val || (!prod() ? RuntimeIndex.manifest.workspace.defaultEnv : undefined);
24
- },
26
+ get envName(): string | undefined {
27
+ return Env.TRV_ENV.val || (!this.production ? this.#idx.manifest.workspace.defaultEnv : undefined);
28
+ }
25
29
 
26
30
  /** Are we in development mode */
27
31
  get production(): boolean {
28
- return prod();
29
- },
32
+ return process.env.NODE_ENV === 'production';
33
+ }
30
34
 
31
35
  /** Is the app in dynamic mode? */
32
36
  get dynamic(): boolean {
33
37
  return Env.TRV_DYNAMIC.isTrue;
34
- },
38
+ }
35
39
 
36
40
  /** Get debug value */
37
41
  get debug(): false | string {
38
42
  const val = Env.DEBUG.val ?? '';
39
- return (!val && prod()) || Env.DEBUG.isFalse ? false : val;
40
- },
43
+ return (!val && this.production) || Env.DEBUG.isFalse ? false : val;
44
+ }
41
45
 
42
46
  /** Manifest main */
43
47
  get main(): ManifestContext['main'] {
44
- return RuntimeIndex.manifest.main;
45
- },
48
+ return this.#idx.manifest.main;
49
+ }
46
50
 
47
51
  /** Manifest workspace */
48
52
  get workspace(): ManifestContext['workspace'] {
49
- return RuntimeIndex.manifest.workspace;
50
- },
53
+ return this.#idx.manifest.workspace;
54
+ }
51
55
 
52
56
  /** Are we running from a mono-root? */
53
57
  get monoRoot(): boolean {
54
- return !!RuntimeIndex.manifest.workspace.mono && !RuntimeIndex.manifest.main.folder;
55
- },
58
+ return !!this.workspace.mono && !this.main.folder;
59
+ }
56
60
 
57
61
  /** Main source path */
58
62
  get mainSourcePath(): string {
59
- return RuntimeIndex.mainModule.sourcePath;
60
- },
63
+ return this.#idx.mainModule.sourcePath;
64
+ }
61
65
 
62
66
  /** Produce a workspace relative path */
63
67
  workspaceRelative(...rel: string[]): string {
64
- return path.resolve(RuntimeIndex.manifest.workspace.path, ...rel);
65
- },
68
+ return path.resolve(this.workspace.path, ...rel);
69
+ }
66
70
 
67
71
  /** Strip off the workspace path from a file */
68
72
  stripWorkspacePath(full: string): string {
69
- return full === RuntimeIndex.manifest.workspace.path ? '' : full.replace(`${RuntimeIndex.manifest.workspace.path}/`, '');
70
- },
73
+ return full === this.workspace.path ? '' : full.replace(`${this.workspace.path}/`, '');
74
+ }
71
75
 
72
76
  /** Produce a workspace path for tooling, with '@' being replaced by node_module/name folder */
73
77
  toolPath(...rel: string[]): string {
74
- rel = rel.flatMap(x => x === '@' ? ['node_modules', RuntimeIndex.manifest.main.name] : [x]);
75
- return path.resolve(RuntimeIndex.manifest.workspace.path, RuntimeIndex.manifest.build.toolFolder, ...rel);
76
- },
78
+ rel = rel.flatMap(x => x === '@' ? ['node_modules', this.#idx.manifest.main.name] : [x]);
79
+ return path.resolve(this.workspace.path, this.#idx.manifest.build.toolFolder, ...rel);
80
+ }
77
81
 
78
82
  /** Resolve single module path */
79
83
  modulePath(modulePath: string): string {
80
- const [base, sub] = (OVERRIDES[modulePath] ?? modulePath)
81
- .replace(/^([^#]*)(#|$)/g, (_, v, r) => `${MODULE_ALIASES[v] ?? v}${r}`)
84
+ const [base, sub] = (this.#resourceOverrides?.[modulePath] ?? modulePath)
85
+ .replace(/^([^#]*)(#|$)/g, (_, v, r) => `${this.#moduleAliases[v] ?? v}${r}`)
82
86
  .split('#');
83
- return path.resolve(RuntimeIndex.getModule(base)?.sourcePath ?? base, sub ?? '.');
84
- },
85
-
86
- /** Resolve module paths */
87
- modulePaths(paths: string[]): string[] {
88
- return [...new Set(paths.map(this.modulePath))];
89
- },
87
+ return path.resolve(this.#idx.getModule(base)?.sourcePath ?? base, sub ?? '.');
88
+ }
90
89
 
91
90
  /** Resolve resource paths */
92
91
  resourcePaths(paths: string[] = []): string[] {
93
- return this.modulePaths([...paths, ...Env.TRV_RESOURCES.list ?? [], '@#resources', '@@#resources']);
94
- },
92
+ return [...paths, ...Env.TRV_RESOURCES.list ?? [], '@#resources', '@@#resources'].map(v => this.modulePath(v));
93
+ }
95
94
 
96
95
  /** Get source for function */
97
96
  getSource(fn: Function): string {
98
- return RuntimeIndex.getFromImport(describeFunction(fn).import)?.sourceFile!;
97
+ return this.#idx.getFromImport(describeFunction(fn).import)?.sourceFile!;
99
98
  }
100
- };
99
+ }
100
+
101
+ export const Runtime = new $Runtime(RuntimeIndex, Env.TRV_RESOURCE_OVERRIDES.object);
@@ -13,7 +13,7 @@ export class FileLoader {
13
13
  #searchPaths: readonly string[];
14
14
 
15
15
  constructor(paths: string[]) {
16
- this.#searchPaths = paths;
16
+ this.#searchPaths = [...new Set(paths)]; // Dedupe
17
17
  }
18
18
 
19
19
  /**