@pristine-ts/core 1.0.440 → 2.0.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.
Files changed (93) hide show
  1. package/dist/lib/cjs/core.module.js +1 -0
  2. package/dist/lib/cjs/core.module.js.map +1 -1
  3. package/dist/lib/cjs/enums/enums.js +2 -0
  4. package/dist/lib/cjs/enums/enums.js.map +1 -1
  5. package/dist/lib/cjs/enums/execution-context-keyname.enum.js +6 -0
  6. package/dist/lib/cjs/enums/execution-context-keyname.enum.js.map +1 -1
  7. package/dist/lib/cjs/enums/instantiation-phase.enum.js +18 -0
  8. package/dist/lib/cjs/enums/instantiation-phase.enum.js.map +1 -0
  9. package/dist/lib/cjs/enums/instantiation-status.enum.js +11 -0
  10. package/dist/lib/cjs/enums/instantiation-status.enum.js.map +1 -0
  11. package/dist/lib/cjs/interfaces/instantiation-test-result.interface.js +3 -0
  12. package/dist/lib/cjs/interfaces/instantiation-test-result.interface.js.map +1 -0
  13. package/dist/lib/cjs/interfaces/instantiation-test.interface.js +3 -0
  14. package/dist/lib/cjs/interfaces/instantiation-test.interface.js.map +1 -0
  15. package/dist/lib/cjs/interfaces/interfaces.js +4 -0
  16. package/dist/lib/cjs/interfaces/interfaces.js.map +1 -1
  17. package/dist/lib/cjs/interfaces/runtime-server.interface.js +3 -0
  18. package/dist/lib/cjs/interfaces/runtime-server.interface.js.map +1 -0
  19. package/dist/lib/cjs/interfaces/serialized-error.interface.js +3 -0
  20. package/dist/lib/cjs/interfaces/serialized-error.interface.js.map +1 -0
  21. package/dist/lib/cjs/kernel.js +316 -17
  22. package/dist/lib/cjs/kernel.js.map +1 -1
  23. package/dist/lib/cjs/models/instantiation-report.js +138 -0
  24. package/dist/lib/cjs/models/instantiation-report.js.map +1 -0
  25. package/dist/lib/cjs/models/instantiation-test-execution-result.js +16 -0
  26. package/dist/lib/cjs/models/instantiation-test-execution-result.js.map +1 -0
  27. package/dist/lib/cjs/models/missing-required-configuration-entry.js +11 -0
  28. package/dist/lib/cjs/models/missing-required-configuration-entry.js.map +1 -0
  29. package/dist/lib/cjs/models/models.js +4 -0
  30. package/dist/lib/cjs/models/models.js.map +1 -1
  31. package/dist/lib/cjs/models/phase-result.js +18 -0
  32. package/dist/lib/cjs/models/phase-result.js.map +1 -0
  33. package/dist/lib/cjs/runtime-servers/default-runtime-server.js +59 -0
  34. package/dist/lib/cjs/runtime-servers/default-runtime-server.js.map +1 -0
  35. package/dist/lib/cjs/runtime-servers/runtime-servers.js +18 -0
  36. package/dist/lib/cjs/runtime-servers/runtime-servers.js.map +1 -0
  37. package/dist/lib/cjs/tsconfig.cjs.tsbuildinfo +1 -0
  38. package/dist/lib/esm/core.module.js +1 -0
  39. package/dist/lib/esm/core.module.js.map +1 -1
  40. package/dist/lib/esm/enums/enums.js +2 -0
  41. package/dist/lib/esm/enums/enums.js.map +1 -1
  42. package/dist/lib/esm/enums/execution-context-keyname.enum.js +6 -0
  43. package/dist/lib/esm/enums/execution-context-keyname.enum.js.map +1 -1
  44. package/dist/lib/esm/enums/instantiation-phase.enum.js +15 -0
  45. package/dist/lib/esm/enums/instantiation-phase.enum.js.map +1 -0
  46. package/dist/lib/esm/enums/instantiation-status.enum.js +8 -0
  47. package/dist/lib/esm/enums/instantiation-status.enum.js.map +1 -0
  48. package/dist/lib/esm/interfaces/instantiation-test-result.interface.js +2 -0
  49. package/dist/lib/esm/interfaces/instantiation-test-result.interface.js.map +1 -0
  50. package/dist/lib/esm/interfaces/instantiation-test.interface.js +2 -0
  51. package/dist/lib/esm/interfaces/instantiation-test.interface.js.map +1 -0
  52. package/dist/lib/esm/interfaces/interfaces.js +4 -0
  53. package/dist/lib/esm/interfaces/interfaces.js.map +1 -1
  54. package/dist/lib/esm/interfaces/runtime-server.interface.js +2 -0
  55. package/dist/lib/esm/interfaces/runtime-server.interface.js.map +1 -0
  56. package/dist/lib/esm/interfaces/serialized-error.interface.js +2 -0
  57. package/dist/lib/esm/interfaces/serialized-error.interface.js.map +1 -0
  58. package/dist/lib/esm/kernel.js +317 -18
  59. package/dist/lib/esm/kernel.js.map +1 -1
  60. package/dist/lib/esm/models/instantiation-report.js +134 -0
  61. package/dist/lib/esm/models/instantiation-report.js.map +1 -0
  62. package/dist/lib/esm/models/instantiation-test-execution-result.js +12 -0
  63. package/dist/lib/esm/models/instantiation-test-execution-result.js.map +1 -0
  64. package/dist/lib/esm/models/missing-required-configuration-entry.js +7 -0
  65. package/dist/lib/esm/models/missing-required-configuration-entry.js.map +1 -0
  66. package/dist/lib/esm/models/models.js +4 -0
  67. package/dist/lib/esm/models/models.js.map +1 -1
  68. package/dist/lib/esm/models/phase-result.js +14 -0
  69. package/dist/lib/esm/models/phase-result.js.map +1 -0
  70. package/dist/lib/esm/runtime-servers/default-runtime-server.js +56 -0
  71. package/dist/lib/esm/runtime-servers/default-runtime-server.js.map +1 -0
  72. package/dist/lib/esm/runtime-servers/runtime-servers.js +2 -0
  73. package/dist/lib/esm/runtime-servers/runtime-servers.js.map +1 -0
  74. package/dist/lib/esm/tsconfig.tsbuildinfo +1 -0
  75. package/dist/types/core.module.d.ts +1 -0
  76. package/dist/types/enums/enums.d.ts +2 -0
  77. package/dist/types/enums/execution-context-keyname.enum.d.ts +6 -0
  78. package/dist/types/enums/instantiation-phase.enum.d.ts +13 -0
  79. package/dist/types/enums/instantiation-status.enum.d.ts +6 -0
  80. package/dist/types/interfaces/instantiation-test-result.interface.d.ts +11 -0
  81. package/dist/types/interfaces/instantiation-test.interface.d.ts +13 -0
  82. package/dist/types/interfaces/interfaces.d.ts +4 -0
  83. package/dist/types/interfaces/runtime-server.interface.d.ts +33 -0
  84. package/dist/types/interfaces/serialized-error.interface.d.ts +11 -0
  85. package/dist/types/kernel.d.ts +77 -6
  86. package/dist/types/models/instantiation-report.d.ts +43 -0
  87. package/dist/types/models/instantiation-test-execution-result.d.ts +11 -0
  88. package/dist/types/models/missing-required-configuration-entry.d.ts +5 -0
  89. package/dist/types/models/models.d.ts +4 -0
  90. package/dist/types/models/phase-result.d.ts +15 -0
  91. package/dist/types/runtime-servers/default-runtime-server.d.ts +22 -0
  92. package/dist/types/runtime-servers/runtime-servers.d.ts +1 -0
  93. package/package.json +7 -7
@@ -0,0 +1,13 @@
1
+ import { DependencyContainer } from "tsyringe";
2
+ import { InstantiationTestResultInterface } from "./instantiation-test-result.interface";
3
+ /**
4
+ * Embedders register implementations of this interface (decorated with
5
+ * `@tag(ServiceDefinitionTagEnum.InstantiationTest)`) to contribute checks that run as part
6
+ * of `Kernel.verifyInstantiation`. Implementations receive the verifier's container so they
7
+ * can resolve services and assert on them. Tests should be cheap and side-effect-free.
8
+ */
9
+ export interface InstantiationTestInterface {
10
+ name: string;
11
+ description?: string;
12
+ run(container: DependencyContainer): Promise<InstantiationTestResultInterface>;
13
+ }
@@ -5,4 +5,8 @@ export * from "./event-listener.interface";
5
5
  export * from "./event-mapper.interface";
6
6
  export * from "./events-execution-options.interface";
7
7
  export * from "./execution-context.interface";
8
+ export * from "./instantiation-test.interface";
9
+ export * from "./instantiation-test-result.interface";
8
10
  export * from "./options-mapper.interface";
11
+ export * from "./runtime-server.interface";
12
+ export * from "./serialized-error.interface";
@@ -0,0 +1,33 @@
1
+ /**
2
+ * A long-running server orchestrated by `pristine start`. Implementations (an HTTP server,
3
+ * a gRPC server, a websocket listener, etc.) tag themselves with
4
+ * `ServiceDefinitionTagEnum.RuntimeServer` and `pristine start` resolves them all and calls
5
+ * `start()` on each. Graceful shutdown is the module's responsibility — typically wired via
6
+ * `ModuleInterface.onShutdown` calling the server's `stop()`.
7
+ *
8
+ * Why the layer exists: `pristine start` cannot directly import from `@pristine-ts/http`
9
+ * (that would invert the dependency direction — http already depends on cli). This interface
10
+ * lets the cli orchestrate any number of server types without knowing about any of them
11
+ * specifically. Modules opt in by implementing and tagging.
12
+ */
13
+ export interface RuntimeServerInterface {
14
+ /**
15
+ * A short label for log lines and diagnostic output (e.g. "http", "https", "grpc").
16
+ * Implementations should keep it stable across restarts so log filtering works.
17
+ */
18
+ name: string;
19
+ /**
20
+ * Boots the server and returns once it is accepting requests. The optional overrides let
21
+ * `pristine start` propagate runtime flags like `--port` / `--address` to whichever server
22
+ * cares to honor them. Implementations are free to ignore overrides that don't apply.
23
+ */
24
+ start(overrides?: {
25
+ port?: number;
26
+ address?: string;
27
+ }): Promise<void>;
28
+ /**
29
+ * Drains and shuts the server down. Should be idempotent — `pristine start` may call it
30
+ * after `Kernel.stop()` has already triggered an `onShutdown`-driven stop.
31
+ */
32
+ stop(): Promise<void>;
33
+ }
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Plain-data shape of an `Error` captured during instantiation. The original `Error` instance
3
+ * is not retained because the report it lives in is meant to be JSON-serializable (logged,
4
+ * sent over the wire, persisted) — and a thrown `Error` does not survive serialization
5
+ * round-trips with name/message/stack intact.
6
+ */
7
+ export interface SerializedError {
8
+ name: string;
9
+ message: string;
10
+ stack?: string;
11
+ }
@@ -1,9 +1,10 @@
1
1
  import "reflect-metadata";
2
2
  import { DependencyContainer } from "tsyringe";
3
- import { AppModuleInterface, Request } from "@pristine-ts/common";
3
+ import { AppModuleInterface, ModuleInterface, Request } from "@pristine-ts/common";
4
4
  import { ModuleConfigurationValue } from "@pristine-ts/configuration";
5
5
  import { ExecutionContextInterface } from "./interfaces/execution-context.interface";
6
6
  import { Event } from "./models/event";
7
+ import { InstantiationReport } from "./models/instantiation-report";
7
8
  /**
8
9
  * This is the central class that manages the lifecyle of this library.
9
10
  */
@@ -19,9 +20,11 @@ export declare class Kernel {
19
20
  instantiationId: string;
20
21
  /**
21
22
  * Contains a map of all the modules that were instantiated indexed by the modules names.
22
- * @private
23
+ * @public Exposed read-only so commands like `pristine info` can introspect the boot graph.
23
24
  */
24
- private instantiatedModules;
25
+ instantiatedModules: {
26
+ [id: string]: ModuleInterface;
27
+ };
25
28
  /**
26
29
  * Contains a map of all the modules that the afterInit was run for, indexed by the modules names .
27
30
  * @private
@@ -32,6 +35,12 @@ export declare class Kernel {
32
35
  * @private
33
36
  */
34
37
  private initializationSpan?;
38
+ /**
39
+ * True after `stop()` has begun (or completed). Prevents double-shutdown when multiple
40
+ * SIGTERM/SIGINT signals arrive in quick succession.
41
+ * @private
42
+ */
43
+ private stopped;
35
44
  /**
36
45
  * This function is the entry point of the Kernel. It initializes the module for your application (AppModule) as well as its the dependencies,
37
46
  * it registers the services, registers the configurations and runs the afterInit for each module.
@@ -41,6 +50,51 @@ export declare class Kernel {
41
50
  start(module: AppModuleInterface, moduleConfigurationValues?: {
42
51
  [key: string]: ModuleConfigurationValue;
43
52
  }): Promise<void>;
53
+ /**
54
+ * Verifies that this kernel can be fully instantiated against the provided AppModule and configuration values.
55
+ * Runs the same boot phases as `start()` on this kernel, capturing each phase's outcome rather than letting
56
+ * exceptions propagate, then collects and runs every embedder-registered `InstantiationTestInterface`.
57
+ *
58
+ * Important: this method mutates the kernel's container (it actually performs registration). It should be
59
+ * called on a fresh `new Kernel()` instance, not on a kernel that has already had `start()` invoked.
60
+ *
61
+ * @param module The AppModule to verify.
62
+ * @param moduleConfigurationValues The configuration values that would be passed to `start()`.
63
+ * @param options.runInstantiationTests When false, skips the test discovery/execution phase. Default true.
64
+ * @param options.stopOnFirstFailure When true, halts after the first failed phase and marks the rest as skipped. Default false.
65
+ */
66
+ verifyInstantiation(module: AppModuleInterface, moduleConfigurationValues?: {
67
+ [key: string]: ModuleConfigurationValue;
68
+ }, options?: {
69
+ runInstantiationTests?: boolean;
70
+ stopOnFirstFailure?: boolean;
71
+ }): Promise<InstantiationReport>;
72
+ /**
73
+ * Gracefully shuts down the kernel by invoking each instantiated module's `onShutdown` hook
74
+ * in reverse instantiation order (root module first, deepest dependencies last). Modules
75
+ * without an `onShutdown` hook are skipped silently.
76
+ *
77
+ * Each hook runs under a per-hook timeout so a single misbehaving module cannot block the
78
+ * shutdown indefinitely. When a hook throws or times out, the error is logged via the
79
+ * resolved `LogHandlerInterface` (or stderr if logging itself failed) and shutdown continues
80
+ * with the next module — the goal is to release as much as possible, not to abort on the
81
+ * first failure.
82
+ *
83
+ * Calling `stop()` more than once is a no-op (subsequent calls return immediately) so this
84
+ * method is safe to wire up to multiple signal handlers.
85
+ *
86
+ * @param options.perHookTimeoutMs Maximum milliseconds to wait for a single module's
87
+ * `onShutdown` to resolve. Default 10_000 (10 seconds). Set to 0 to wait indefinitely.
88
+ */
89
+ stop(options?: {
90
+ perHookTimeoutMs?: number;
91
+ }): Promise<void>;
92
+ /**
93
+ * Wraps a Promise in a timeout that rejects with a clear error if not settled in time.
94
+ * `timeoutMs <= 0` disables the timeout entirely.
95
+ * @private
96
+ */
97
+ private runWithTimeout;
44
98
  /**
45
99
  *
46
100
  * @param event
@@ -64,11 +118,18 @@ export declare class Kernel {
64
118
  */
65
119
  private initModule;
66
120
  /**
67
- * Registers all the configuration definitions that all the modules have defined.
68
- * @param moduleConfigurationValues
121
+ * Resolves the ConfigurationManager and registers every module's configuration definitions onto it.
122
+ * Returns the manager so the caller can subsequently inspect required parameters or call `load()`.
123
+ * Split out from the original `initConfiguration` so `verifyInstantiation` can run a non-mutating
124
+ * check between definition registration and value loading.
69
125
  * @private
70
126
  */
71
- private initConfiguration;
127
+ private registerConfigurationDefinitions;
128
+ /**
129
+ * Loads the configuration values into the previously-registered ConfigurationManager.
130
+ * @private
131
+ */
132
+ private loadConfiguration;
72
133
  /**
73
134
  * This method receives a module and recursively calls back this method with the module dependencies
74
135
  * specified as imported by the module.
@@ -91,4 +152,14 @@ export declare class Kernel {
91
152
  * @private
92
153
  */
93
154
  private registerNonModuleScopedServiceTags;
155
+ /**
156
+ * Wraps a phase invocation: times it, captures any thrown error into a serialized form, appends a
157
+ * PhaseResult to the report, and returns whether the phase passed.
158
+ * @private
159
+ */
160
+ private runPhase;
161
+ private runInstantiationTest;
162
+ private skipPhase;
163
+ private skipRemainingPhases;
164
+ private serializeError;
94
165
  }
@@ -0,0 +1,43 @@
1
+ import { LogHandlerInterface } from "@pristine-ts/logging";
2
+ import { InstantiationStatusEnum } from "../enums/instantiation-status.enum";
3
+ import { PhaseResult } from "./phase-result";
4
+ import { InstantiationTestExecutionResult } from "./instantiation-test-execution-result";
5
+ import { MissingRequiredConfigurationEntry } from "./missing-required-configuration-entry";
6
+ /**
7
+ * Aggregated outcome of `Kernel.verifyInstantiation`. Plain data — callers serialize, render, or programmatically
8
+ * inspect it. The `log()` helper routes the report through the project's `LogHandlerInterface` (and falls back to
9
+ * stderr only when no LogHandler is available, e.g. when module registration itself failed before logging was wired up).
10
+ */
11
+ export declare class InstantiationReport {
12
+ phases: PhaseResult[];
13
+ missingRequiredConfiguration: MissingRequiredConfigurationEntry[];
14
+ instantiationTests: InstantiationTestExecutionResult[];
15
+ totalDurationMs: number;
16
+ /**
17
+ * LogHandler stamped onto the report by the verifier when one becomes resolvable. Optional because the
18
+ * verifier may never reach a state where logging is available (e.g., module registration threw).
19
+ */
20
+ logHandler?: LogHandlerInterface;
21
+ /**
22
+ * Overall status derived from phase + test outcomes. Failed if any phase failed; PassedWithWarnings if
23
+ * there are missing required configurations satisfied only by default resolvers, or any failed instantiation
24
+ * tests; Passed otherwise.
25
+ */
26
+ get overallStatus(): InstantiationStatusEnum;
27
+ /**
28
+ * Convenience boolean: `true` when the report contains anything that should fail a CI check or block startup.
29
+ * Equivalent to `overallStatus === Failed`.
30
+ */
31
+ get hasErrors(): boolean;
32
+ get failedInstantiationTests(): InstantiationTestExecutionResult[];
33
+ get succeededInstantiationTests(): InstantiationTestExecutionResult[];
34
+ /**
35
+ * Routes the report through the project's logging stack. Each phase, missing configuration entry, and
36
+ * test result is emitted as its own log entry at the appropriate severity. When no LogHandler is provided
37
+ * and none was stamped onto the report (typical when module registration itself failed), falls back to
38
+ * `process.stderr` so the report is never silently swallowed.
39
+ */
40
+ log(logHandler?: LogHandlerInterface): void;
41
+ private fallbackLog;
42
+ private toPlainObject;
43
+ }
@@ -0,0 +1,11 @@
1
+ import { SerializedError } from "../interfaces/serialized-error.interface";
2
+ export declare class InstantiationTestExecutionResult {
3
+ readonly name: string;
4
+ readonly passed: boolean;
5
+ readonly durationMs: number;
6
+ readonly description?: string | undefined;
7
+ readonly message?: string | undefined;
8
+ readonly details?: any | undefined;
9
+ readonly error?: SerializedError | undefined;
10
+ constructor(name: string, passed: boolean, durationMs: number, description?: string | undefined, message?: string | undefined, details?: any | undefined, error?: SerializedError | undefined);
11
+ }
@@ -0,0 +1,5 @@
1
+ export declare class MissingRequiredConfigurationEntry {
2
+ readonly parameterName: string;
3
+ readonly hasDefaultResolvers: boolean;
4
+ constructor(parameterName: string, hasDefaultResolvers: boolean);
5
+ }
@@ -1,2 +1,6 @@
1
1
  export * from "./event";
2
2
  export * from "./event.response";
3
+ export * from "./instantiation-report";
4
+ export * from "./instantiation-test-execution-result";
5
+ export * from "./missing-required-configuration-entry";
6
+ export * from "./phase-result";
@@ -0,0 +1,15 @@
1
+ import { InstantiationPhaseEnum } from "../enums/instantiation-phase.enum";
2
+ import { InstantiationStatusEnum } from "../enums/instantiation-status.enum";
3
+ import { SerializedError } from "../interfaces/serialized-error.interface";
4
+ /**
5
+ * Outcome of a single phase of `Kernel.verifyInstantiation` (e.g. `ModuleRegistration`,
6
+ * `ConfigurationLoad`, `BootProbe`). One `PhaseResult` per phase appears in the report.
7
+ */
8
+ export declare class PhaseResult {
9
+ readonly phase: InstantiationPhaseEnum;
10
+ status: InstantiationStatusEnum;
11
+ durationMs: number;
12
+ error?: SerializedError | undefined;
13
+ details?: any | undefined;
14
+ constructor(phase: InstantiationPhaseEnum, status: InstantiationStatusEnum, durationMs: number, error?: SerializedError | undefined, details?: any | undefined);
15
+ }
@@ -0,0 +1,22 @@
1
+ import { RuntimeServerInterface } from "../interfaces/runtime-server.interface";
2
+ /**
3
+ * No-op default registration for `ServiceDefinitionTagEnum.RuntimeServer`. Without this,
4
+ * tsyringe's `@injectAll(RuntimeServer)` would throw "Attempted to resolve unregistered
5
+ * dependency token" in apps that don't import any module providing a real RuntimeServer
6
+ * (e.g. an AppModule that doesn't include `@pristine-ts/http`). Registering one default
7
+ * lets `pristine start` cleanly handle the "no servers" case as an empty-loop scenario
8
+ * (after filtering this out) rather than an exception.
9
+ *
10
+ * Same pattern as `DefaultEventMapper` and `DefaultEventListener` use for their respective
11
+ * tags.
12
+ */
13
+ export declare class DefaultRuntimeServer implements RuntimeServerInterface {
14
+ /**
15
+ * Sentinel name. Consumers that iterate the resolved server list should filter on this
16
+ * value (or simply skip servers whose `start()` is a no-op) when they want to ignore
17
+ * the default placeholder.
18
+ */
19
+ readonly name: string;
20
+ start(): Promise<void>;
21
+ stop(): Promise<void>;
22
+ }
@@ -0,0 +1 @@
1
+ export * from "./default-runtime-server";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pristine-ts/core",
3
- "version": "1.0.440",
3
+ "version": "2.0.1",
4
4
  "description": "",
5
5
  "module": "dist/lib/esm/core.module.js",
6
6
  "main": "dist/lib/cjs/core.module.js",
@@ -20,11 +20,11 @@
20
20
  "access": "public"
21
21
  },
22
22
  "dependencies": {
23
- "@pristine-ts/common": "^1.0.440",
24
- "@pristine-ts/configuration": "^1.0.440",
25
- "@pristine-ts/logging": "^1.0.440",
26
- "@pristine-ts/security": "^1.0.440",
27
- "@pristine-ts/telemetry": "^1.0.440",
23
+ "@pristine-ts/common": "^2.0.1",
24
+ "@pristine-ts/configuration": "^2.0.1",
25
+ "@pristine-ts/logging": "^2.0.1",
26
+ "@pristine-ts/security": "^2.0.1",
27
+ "@pristine-ts/telemetry": "^2.0.1",
28
28
  "uuid": "^9.0.1"
29
29
  },
30
30
  "devDependencies": {
@@ -64,7 +64,7 @@
64
64
  "src/*.{js,ts}"
65
65
  ]
66
66
  },
67
- "gitHead": "2828491bc8cc720476584f3cf60791a4a705a77e",
67
+ "gitHead": "a5e40ea0fcdeaf743666c1981a9315bfde9c4c00",
68
68
  "repository": {
69
69
  "type": "git",
70
70
  "url": "https://github.com/magieno/pristine-ts.git",