@grest-ts/runtime 0.0.14 → 0.0.16
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 +87 -0
- package/package.json +9 -12
package/README.md
CHANGED
|
@@ -3,3 +3,90 @@
|
|
|
3
3
|
> [Documentation](https://github.com/grest-ts/grest-ts#readme) | [All packages](https://github.com/grest-ts/grest-ts#package-reference)
|
|
4
4
|
<!-- GREST-TS-BANNER-END -->
|
|
5
5
|
|
|
6
|
+
# @grest-ts/runtime
|
|
7
|
+
|
|
8
|
+
Base class for bootstrapping and managing the lifecycle of a grest-ts service. Handles startup, service composition, graceful shutdown, and signal handling.
|
|
9
|
+
|
|
10
|
+
## Core Concept
|
|
11
|
+
|
|
12
|
+
You extend `GGRuntime` and implement the `compose()` method to register your services. The runtime takes care of the rest — starting services in order, wiring up logging/tracing/discovery, and tearing everything down gracefully on shutdown.
|
|
13
|
+
|
|
14
|
+
## Quick Start
|
|
15
|
+
|
|
16
|
+
```typescript
|
|
17
|
+
import {GGRuntime} from "@grest-ts/runtime"
|
|
18
|
+
|
|
19
|
+
class MyRuntime extends GGRuntime {
|
|
20
|
+
|
|
21
|
+
public static readonly NAME = "my-service"
|
|
22
|
+
|
|
23
|
+
compose() {
|
|
24
|
+
// Register your services here.
|
|
25
|
+
// Everything registered via the locator scope during compose()
|
|
26
|
+
// gets lifecycle-managed automatically.
|
|
27
|
+
new MyHttpServer()
|
|
28
|
+
new MyDatabaseClient()
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// When this file is run directly, starts the runtime.
|
|
33
|
+
MyRuntime.cli(import.meta.url)
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## Lifecycle
|
|
37
|
+
|
|
38
|
+
The runtime goes through these states in order:
|
|
39
|
+
|
|
40
|
+
```
|
|
41
|
+
CREATED → BOOTSTRAPPING → COMPOSING → STARTING → RUNNING → STOPPING → STOPPED
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
1. **Bootstrapping** — Initializes the locator scope, logging, and tracing
|
|
45
|
+
2. **Composing** — Calls your `compose()` method where you register services
|
|
46
|
+
3. **Starting** — Calls `start()` on all registered services (by priority)
|
|
47
|
+
4. **Running** — Service is live
|
|
48
|
+
5. **Stopping** — On `SIGTERM`/`SIGINT`, tears down services in reverse order with a configurable timeout (default 10s)
|
|
49
|
+
|
|
50
|
+
If any service fails to start, already-started services are cleaned up automatically.
|
|
51
|
+
|
|
52
|
+
## Compose and Service Registration
|
|
53
|
+
|
|
54
|
+
`compose()` is synchronous — you should not do any async loading (connecting to databases, fetching config, etc.) directly in it. Instead, register services via `setWithLifecycle` and put async work into the lifecycle's `start()` callback. The runtime will call `start()` on all registered services after compose finishes, ordered by `GGLocatorServiceType` priority.
|
|
55
|
+
|
|
56
|
+
```typescript
|
|
57
|
+
import {GGLocator, GGLocatorKey, GGLocatorServiceType} from "@grest-ts/locator"
|
|
58
|
+
|
|
59
|
+
const MY_SERVICE = new GGLocatorKey<MyService>("MyService")
|
|
60
|
+
|
|
61
|
+
class MyService {
|
|
62
|
+
|
|
63
|
+
constructor() {
|
|
64
|
+
// Register in the locator with lifecycle callbacks.
|
|
65
|
+
// No async work here — just wire things up.
|
|
66
|
+
GGLocator.getScope().setWithLifecycle(MY_SERVICE, this, {
|
|
67
|
+
type: GGLocatorServiceType.DATABASE,
|
|
68
|
+
start: () => this.connect(), // async work goes here
|
|
69
|
+
teardown: () => this.disconnect() // cleanup on shutdown
|
|
70
|
+
})
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
private async connect() { /* open connections, load resources, etc. */ }
|
|
74
|
+
private async disconnect() { /* close connections */ }
|
|
75
|
+
}
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
Services of the same priority type start concurrently. Different priority levels start sequentially (CONFIG first, then DATABASE, HTTP, and so on). Teardown runs in reverse order.
|
|
79
|
+
|
|
80
|
+
## `cli()` Entry Point
|
|
81
|
+
|
|
82
|
+
The static `cli()` method lets your runtime file work as both an importable module and a standalone entry point:
|
|
83
|
+
|
|
84
|
+
```typescript
|
|
85
|
+
MyRuntime.cli(import.meta.url)
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
When the file is run directly (e.g. `node my-runtime.ts`), it starts the runtime. When imported by tests or other runtimes, it does nothing.
|
|
89
|
+
|
|
90
|
+
## Runtime Metrics
|
|
91
|
+
|
|
92
|
+
The package also exports `GGRuntimeMetrics` for process-level monitoring — memory usage (heap, RSS, external, array buffers), active handles/requests, and process start time. These are lazy gauges that compute values on read.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@grest-ts/runtime",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.16",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"description": "Service bootstrap and lifecycle management utilities",
|
|
@@ -44,16 +44,13 @@
|
|
|
44
44
|
"node": ">=25"
|
|
45
45
|
},
|
|
46
46
|
"dependencies": {
|
|
47
|
-
"@grest-ts/common": "0.0.
|
|
48
|
-
"@grest-ts/context": "0.0.
|
|
49
|
-
"@grest-ts/discovery": "0.0.
|
|
50
|
-
"@grest-ts/discovery-local": "0.0.
|
|
51
|
-
"@grest-ts/locator": "0.0.
|
|
52
|
-
"@grest-ts/logger": "0.0.
|
|
53
|
-
"@grest-ts/metrics": "0.0.
|
|
54
|
-
"@grest-ts/trace": "0.0.
|
|
55
|
-
},
|
|
56
|
-
"devDependencies": {
|
|
57
|
-
"@grest-ts/x-packager": "0.0.14"
|
|
47
|
+
"@grest-ts/common": "0.0.16",
|
|
48
|
+
"@grest-ts/context": "0.0.16",
|
|
49
|
+
"@grest-ts/discovery": "0.0.16",
|
|
50
|
+
"@grest-ts/discovery-local": "0.0.16",
|
|
51
|
+
"@grest-ts/locator": "0.0.16",
|
|
52
|
+
"@grest-ts/logger": "0.0.16",
|
|
53
|
+
"@grest-ts/metrics": "0.0.16",
|
|
54
|
+
"@grest-ts/trace": "0.0.16"
|
|
58
55
|
}
|
|
59
56
|
}
|