@gobing-ai/ts-infra 0.3.3 → 0.3.5
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 +113 -0
- package/dist/application/index.d.ts +57 -0
- package/dist/application/index.d.ts.map +1 -0
- package/dist/application/index.js +210 -0
- package/dist/application/types.d.ts +188 -0
- package/dist/application/types.d.ts.map +1 -0
- package/dist/application/types.js +9 -0
- package/dist/application-node.d.ts +68 -0
- package/dist/application-node.d.ts.map +1 -0
- package/dist/application-node.js +245 -0
- package/package.json +16 -3
- package/src/application/index.ts +278 -0
- package/src/application/types.ts +203 -0
- package/src/application-node.ts +329 -0
package/README.md
CHANGED
|
@@ -419,6 +419,119 @@ bun add @opentelemetry/sdk-trace-node @opentelemetry/sdk-metrics \
|
|
|
419
419
|
@opentelemetry/exporter-metrics-otlp-http
|
|
420
420
|
```
|
|
421
421
|
|
|
422
|
+
|
|
423
|
+
### Application Bootstrap
|
|
424
|
+
|
|
425
|
+
The application bootstrap API provides a deterministic lifecycle for wiring
|
|
426
|
+
infrastructure services. Two layers:
|
|
427
|
+
|
|
428
|
+
1. **Portable DI bootstrap** (`@gobing-ai/ts-infra/application`) — orchestrates
|
|
429
|
+
injected dependencies. Never opens files, creates DB connections, or wires
|
|
430
|
+
runtime-specific exporters.
|
|
431
|
+
2. **Node/Bun convenience** (`@gobing-ai/ts-infra/application-node`) — composes
|
|
432
|
+
the portable bootstrap with runtime-specific adapters: YAML config loading,
|
|
433
|
+
file log sink, Bun SQLite DB creation, Node OTel export, Node scheduler.
|
|
434
|
+
|
|
435
|
+
#### Portable DI bootstrap
|
|
436
|
+
|
|
437
|
+
```ts
|
|
438
|
+
import { runApplication } from '@gobing-ai/ts-infra/application';
|
|
439
|
+
|
|
440
|
+
const app = await runApplication({
|
|
441
|
+
config: {
|
|
442
|
+
logging: { level: 'info', console: true },
|
|
443
|
+
telemetry: { enabled: true, serviceName: 'my-api' },
|
|
444
|
+
},
|
|
445
|
+
appConfig: { port: 3000 },
|
|
446
|
+
async start(app) {
|
|
447
|
+
app.logger.info('started', { port: app.appConfig.port });
|
|
448
|
+
},
|
|
449
|
+
});
|
|
450
|
+
|
|
451
|
+
// Graceful shutdown — idempotent
|
|
452
|
+
await app.stop();
|
|
453
|
+
```
|
|
454
|
+
|
|
455
|
+
The portable `runApplication` accepts pre-built services via `services` and
|
|
456
|
+
never reads files. All services are created with defaults; feature flags
|
|
457
|
+
control what gets initialized. Startup order is deterministic:
|
|
458
|
+
|
|
459
|
+
1. Resolve bootstrap config + app config
|
|
460
|
+
2. Initialize logger
|
|
461
|
+
3. Initialize telemetry
|
|
462
|
+
4. Create lifecycle bus + EventBus
|
|
463
|
+
5. Register injected DB adapter
|
|
464
|
+
6. Initialize scheduler + register entries
|
|
465
|
+
7. Call user `start(app)` callback
|
|
466
|
+
8. Start scheduler if `autoStart`
|
|
467
|
+
|
|
468
|
+
Shutdown runs in reverse order. `stop()` is idempotent — safe to call from
|
|
469
|
+
multiple signal handlers.
|
|
470
|
+
|
|
471
|
+
#### Node/Bun convenience bootstrap
|
|
472
|
+
|
|
473
|
+
```ts
|
|
474
|
+
import { runNodeApplication } from '@gobing-ai/ts-infra/application-node';
|
|
475
|
+
|
|
476
|
+
await runNodeApplication({
|
|
477
|
+
configLoader: {
|
|
478
|
+
configFile: 'config/app.yaml',
|
|
479
|
+
bootstrapSection: 'bootstrap',
|
|
480
|
+
appSection: 'billing',
|
|
481
|
+
appConfig: {
|
|
482
|
+
// Structural safeParse adapter — works with Zod or any validator
|
|
483
|
+
safeParse(raw) {
|
|
484
|
+
return billingSchema.safeParse(raw);
|
|
485
|
+
},
|
|
486
|
+
},
|
|
487
|
+
},
|
|
488
|
+
async start(app) {
|
|
489
|
+
app.logger.info('billing app started', {
|
|
490
|
+
settlementWindowMinutes: app.appConfig.settlementWindowMinutes,
|
|
491
|
+
});
|
|
492
|
+
},
|
|
493
|
+
});
|
|
494
|
+
```
|
|
495
|
+
|
|
496
|
+
Example YAML config file:
|
|
497
|
+
|
|
498
|
+
```yaml
|
|
499
|
+
app:
|
|
500
|
+
name: billing-api
|
|
501
|
+
env: production
|
|
502
|
+
|
|
503
|
+
bootstrap:
|
|
504
|
+
logging:
|
|
505
|
+
level: info
|
|
506
|
+
console: true
|
|
507
|
+
filePath: ./logs/app.jsonl
|
|
508
|
+
telemetry:
|
|
509
|
+
enabled: true
|
|
510
|
+
serviceName: billing-api
|
|
511
|
+
endpoint: http://otel-collector:4318
|
|
512
|
+
database:
|
|
513
|
+
enabled: true
|
|
514
|
+
driver: bun-sqlite
|
|
515
|
+
url: ./data/app.db
|
|
516
|
+
|
|
517
|
+
billing:
|
|
518
|
+
settlementWindowMinutes: 15
|
|
519
|
+
riskLimit: 100000
|
|
520
|
+
```
|
|
521
|
+
|
|
522
|
+
Config validators accept four shapes:
|
|
523
|
+
- `{ safeParse(raw) → { success, data?, errors? } }` — Zod-compatible
|
|
524
|
+
- `(raw) => TAppConfig` — bare function
|
|
525
|
+
- `{ validate(raw) => TAppConfig }` — method form
|
|
526
|
+
- `{ parse(raw) => TAppConfig }` — method form
|
|
527
|
+
|
|
528
|
+
Validation errors include the config file path and section name for diagnostics.
|
|
529
|
+
|
|
530
|
+
**What is intentionally NOT in the main barrel:** `runApplication` and
|
|
531
|
+
`runNodeApplication` live behind explicit subpaths so the main
|
|
532
|
+
`@gobing-ai/ts-infra` import stays portable and adapter-light. A future ADR
|
|
533
|
+
may decide whether type-only re-exports are acceptable.
|
|
534
|
+
|
|
422
535
|
## Usage
|
|
423
536
|
|
|
424
537
|
### Install
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Portable `runApplication` — DI bootstrap over existing ts-infra primitives.
|
|
3
|
+
*
|
|
4
|
+
* Orchestrates logger, telemetry, event bus, (optional) DB adapter, and
|
|
5
|
+
* (optional) scheduler into a deterministic startup/shutdown lifecycle.
|
|
6
|
+
* The portable subpath never opens files, creates DB connections, or wires
|
|
7
|
+
* runtime-specific exporters — those are injected or handled by the
|
|
8
|
+
* Node/Bun convenience subpath.
|
|
9
|
+
*
|
|
10
|
+
* @module application
|
|
11
|
+
*/
|
|
12
|
+
import type { EventMap } from '../event-bus/types';
|
|
13
|
+
import type { InfraEvents } from '../events';
|
|
14
|
+
import type { ApplicationBootstrapOptions, ApplicationRuntime } from './types';
|
|
15
|
+
/**
|
|
16
|
+
* Portable application bootstrap.
|
|
17
|
+
*
|
|
18
|
+
* Orchestrates logger, telemetry, events, optional DB, and optional scheduler.
|
|
19
|
+
* Accepts injected dependencies; never opens files, reads config from disk,
|
|
20
|
+
* or wires runtime-specific exporters.
|
|
21
|
+
*
|
|
22
|
+
* Startup order (deterministic, per R5):
|
|
23
|
+
* 1. Resolve bootstrap config + app config
|
|
24
|
+
* 2. Initialize logger
|
|
25
|
+
* 3. Initialize telemetry
|
|
26
|
+
* 4. Create lifecycle bus + application EventBus
|
|
27
|
+
* 5. Register DB adapter (injected only)
|
|
28
|
+
* 6. Initialize scheduler + register entries
|
|
29
|
+
* 7. Call user `start(app)` callback
|
|
30
|
+
* 8. Start scheduler if `autoStart`
|
|
31
|
+
*
|
|
32
|
+
* Shutdown order (reverse, per R5):
|
|
33
|
+
* 1. User `stop(app, reason)` callback
|
|
34
|
+
* 2. Stop scheduler
|
|
35
|
+
* 3. Close DB adapter
|
|
36
|
+
* 4. Shut down telemetry
|
|
37
|
+
*
|
|
38
|
+
* If any startup step fails, already-started services are cleaned up in reverse
|
|
39
|
+
* order before rethrowing. `stop()` is idempotent.
|
|
40
|
+
*
|
|
41
|
+
* @example
|
|
42
|
+
* ```ts
|
|
43
|
+
* import { runApplication } from '@gobing-ai/ts-infra/application';
|
|
44
|
+
*
|
|
45
|
+
* const app = await runApplication({
|
|
46
|
+
* config: { logging: { level: 'debug' } },
|
|
47
|
+
* async start(app) {
|
|
48
|
+
* app.logger.info('started');
|
|
49
|
+
* },
|
|
50
|
+
* });
|
|
51
|
+
* ```
|
|
52
|
+
*/
|
|
53
|
+
export declare function runApplication<TAppConfig = unknown, TEvents extends EventMap = InfraEvents>(options: ApplicationBootstrapOptions<TAppConfig, TEvents>): Promise<ApplicationRuntime<TAppConfig, TEvents>>;
|
|
54
|
+
export type { BusLifecycleEvents, EventMap } from '../event-bus/types';
|
|
55
|
+
export type { InfraEvents } from '../events';
|
|
56
|
+
export type { ApplicationBootstrapConfig, ApplicationBootstrapOptions, ApplicationConfigLoader, ApplicationConfigValidator, ApplicationRuntime, ApplicationServices, ApplicationStopReason, ConfigValidationResult, DbAdapterLike, EventsOptions, LoggingOptions, SchedulerOptions, TelemetryOptions, } from './types';
|
|
57
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/application/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAIH,OAAO,KAAK,EAAsB,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AACvE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAK7C,OAAO,KAAK,EAER,2BAA2B,EAC3B,kBAAkB,EAGrB,MAAM,SAAS,CAAC;AAuDjB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AACH,wBAAsB,cAAc,CAAC,UAAU,GAAG,OAAO,EAAE,OAAO,SAAS,QAAQ,GAAG,WAAW,EAC7F,OAAO,EAAE,2BAA2B,CAAC,UAAU,EAAE,OAAO,CAAC,GAC1D,OAAO,CAAC,kBAAkB,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC,CAyIlD;AAED,YAAY,EAAE,kBAAkB,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AACvE,YAAY,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAE7C,YAAY,EACR,0BAA0B,EAC1B,2BAA2B,EAC3B,uBAAuB,EACvB,0BAA0B,EAC1B,kBAAkB,EAClB,mBAAmB,EACnB,qBAAqB,EACrB,sBAAsB,EACtB,aAAa,EACb,aAAa,EACb,cAAc,EACd,gBAAgB,EAChB,gBAAgB,GACnB,MAAM,SAAS,CAAC"}
|
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Portable `runApplication` — DI bootstrap over existing ts-infra primitives.
|
|
3
|
+
*
|
|
4
|
+
* Orchestrates logger, telemetry, event bus, (optional) DB adapter, and
|
|
5
|
+
* (optional) scheduler into a deterministic startup/shutdown lifecycle.
|
|
6
|
+
* The portable subpath never opens files, creates DB connections, or wires
|
|
7
|
+
* runtime-specific exporters — those are injected or handled by the
|
|
8
|
+
* Node/Bun convenience subpath.
|
|
9
|
+
*
|
|
10
|
+
* @module application
|
|
11
|
+
*/
|
|
12
|
+
import { attachDefaultObservers, createLifecycleBus } from '../event-bus/default-observers.js';
|
|
13
|
+
import { EventBus } from '../event-bus/event-bus.js';
|
|
14
|
+
import { getLogger, initializeLogger } from '../logger.js';
|
|
15
|
+
import { initScheduler, setSchedulerAdapter } from '../scheduler/factory.js';
|
|
16
|
+
import { initTelemetry, shutdownTelemetry } from '../telemetry/sdk.js';
|
|
17
|
+
// ── Shutdown (deterministic reverse order per R5) ─────────────────────────
|
|
18
|
+
async function performShutdown(state, reason) {
|
|
19
|
+
if (state.stopped)
|
|
20
|
+
return;
|
|
21
|
+
state.stopped = true;
|
|
22
|
+
const app = state.app;
|
|
23
|
+
if (!app)
|
|
24
|
+
return;
|
|
25
|
+
// 1. User stop callback
|
|
26
|
+
if (state.userStop) {
|
|
27
|
+
await state.userStop(app, reason);
|
|
28
|
+
}
|
|
29
|
+
// 2. Stop scheduler
|
|
30
|
+
if (state.schedulerStarted && state.schedulerAdapter) {
|
|
31
|
+
await state.schedulerAdapter.stop().catch(() => { });
|
|
32
|
+
state.schedulerStarted = false;
|
|
33
|
+
}
|
|
34
|
+
// 3. Close DB adapter
|
|
35
|
+
if (app.db) {
|
|
36
|
+
try {
|
|
37
|
+
app.db.close();
|
|
38
|
+
}
|
|
39
|
+
catch {
|
|
40
|
+
/* best-effort */
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
// 4. Shutdown telemetry
|
|
44
|
+
if (state.telemetryInitialized) {
|
|
45
|
+
await shutdownTelemetry();
|
|
46
|
+
state.telemetryInitialized = false;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
// ── Public API ────────────────────────────────────────────────────────────
|
|
50
|
+
/**
|
|
51
|
+
* Portable application bootstrap.
|
|
52
|
+
*
|
|
53
|
+
* Orchestrates logger, telemetry, events, optional DB, and optional scheduler.
|
|
54
|
+
* Accepts injected dependencies; never opens files, reads config from disk,
|
|
55
|
+
* or wires runtime-specific exporters.
|
|
56
|
+
*
|
|
57
|
+
* Startup order (deterministic, per R5):
|
|
58
|
+
* 1. Resolve bootstrap config + app config
|
|
59
|
+
* 2. Initialize logger
|
|
60
|
+
* 3. Initialize telemetry
|
|
61
|
+
* 4. Create lifecycle bus + application EventBus
|
|
62
|
+
* 5. Register DB adapter (injected only)
|
|
63
|
+
* 6. Initialize scheduler + register entries
|
|
64
|
+
* 7. Call user `start(app)` callback
|
|
65
|
+
* 8. Start scheduler if `autoStart`
|
|
66
|
+
*
|
|
67
|
+
* Shutdown order (reverse, per R5):
|
|
68
|
+
* 1. User `stop(app, reason)` callback
|
|
69
|
+
* 2. Stop scheduler
|
|
70
|
+
* 3. Close DB adapter
|
|
71
|
+
* 4. Shut down telemetry
|
|
72
|
+
*
|
|
73
|
+
* If any startup step fails, already-started services are cleaned up in reverse
|
|
74
|
+
* order before rethrowing. `stop()` is idempotent.
|
|
75
|
+
*
|
|
76
|
+
* @example
|
|
77
|
+
* ```ts
|
|
78
|
+
* import { runApplication } from '@gobing-ai/ts-infra/application';
|
|
79
|
+
*
|
|
80
|
+
* const app = await runApplication({
|
|
81
|
+
* config: { logging: { level: 'debug' } },
|
|
82
|
+
* async start(app) {
|
|
83
|
+
* app.logger.info('started');
|
|
84
|
+
* },
|
|
85
|
+
* });
|
|
86
|
+
* ```
|
|
87
|
+
*/
|
|
88
|
+
export async function runApplication(options) {
|
|
89
|
+
// ── Resolve config ─────────────────────────────────────────────────
|
|
90
|
+
const logOpts = options.config?.logging;
|
|
91
|
+
const loggingConfig = {
|
|
92
|
+
enabled: logOpts?.enabled ?? true,
|
|
93
|
+
level: logOpts?.level ?? 'info',
|
|
94
|
+
console: logOpts?.console ?? true,
|
|
95
|
+
json: logOpts?.json ?? true,
|
|
96
|
+
...(logOpts?.fileSink ? { fileSink: logOpts.fileSink } : {}),
|
|
97
|
+
};
|
|
98
|
+
const telOpts = options.config?.telemetry;
|
|
99
|
+
const telemetryConfig = {
|
|
100
|
+
enabled: telOpts?.enabled ?? true,
|
|
101
|
+
serviceName: telOpts?.serviceName ?? 'ts-libs',
|
|
102
|
+
environment: telOpts?.environment ?? 'development',
|
|
103
|
+
dbStatementDebug: telOpts?.dbStatementDebug ?? false,
|
|
104
|
+
};
|
|
105
|
+
const schedOpts = options.config?.scheduler;
|
|
106
|
+
const schedulerConfig = {
|
|
107
|
+
enabled: schedOpts?.enabled ?? false,
|
|
108
|
+
autoStart: schedOpts?.autoStart ?? true,
|
|
109
|
+
};
|
|
110
|
+
const eventsEnabled = options.config?.events?.enabled ?? true;
|
|
111
|
+
const eventsLifecycle = options.config?.events?.lifecycle ?? true;
|
|
112
|
+
const eventsDefaultObservers = options.config?.events?.defaultObservers ?? true;
|
|
113
|
+
const state = {
|
|
114
|
+
app: undefined,
|
|
115
|
+
userStop: options.stop,
|
|
116
|
+
schedulerAdapter: undefined,
|
|
117
|
+
schedulerStarted: false,
|
|
118
|
+
loggerInitialized: false,
|
|
119
|
+
telemetryInitialized: false,
|
|
120
|
+
stopped: false,
|
|
121
|
+
};
|
|
122
|
+
try {
|
|
123
|
+
// ── 1. Initialize logger ────────────────────────────────────────
|
|
124
|
+
let logger;
|
|
125
|
+
if (options.services?.logger) {
|
|
126
|
+
logger = options.services.logger;
|
|
127
|
+
}
|
|
128
|
+
else if (loggingConfig.enabled) {
|
|
129
|
+
await initializeLogger({
|
|
130
|
+
level: loggingConfig.level,
|
|
131
|
+
console: loggingConfig.console,
|
|
132
|
+
fileSink: loggingConfig.fileSink,
|
|
133
|
+
json: loggingConfig.json,
|
|
134
|
+
});
|
|
135
|
+
logger = getLogger('bootstrap');
|
|
136
|
+
}
|
|
137
|
+
else {
|
|
138
|
+
logger = getLogger('bootstrap');
|
|
139
|
+
}
|
|
140
|
+
// ── 2. Initialize telemetry ────────────────────────────────────
|
|
141
|
+
if (telemetryConfig.enabled) {
|
|
142
|
+
initTelemetry({
|
|
143
|
+
enabled: telemetryConfig.enabled,
|
|
144
|
+
serviceName: telemetryConfig.serviceName,
|
|
145
|
+
environment: telemetryConfig.environment,
|
|
146
|
+
dbStatementDebug: telemetryConfig.dbStatementDebug,
|
|
147
|
+
});
|
|
148
|
+
state.telemetryInitialized = true;
|
|
149
|
+
}
|
|
150
|
+
// ── 3. Create lifecycle bus + EventBus ─────────────────────────
|
|
151
|
+
const lifecycleBus = eventsEnabled && eventsLifecycle ? (options.services?.lifecycleBus ?? createLifecycleBus()) : undefined;
|
|
152
|
+
if (lifecycleBus && eventsDefaultObservers) {
|
|
153
|
+
attachDefaultObservers(lifecycleBus);
|
|
154
|
+
}
|
|
155
|
+
const events = options.services?.events
|
|
156
|
+
? options.services.events
|
|
157
|
+
: new EventBus({ lifecycleBus: lifecycleBus });
|
|
158
|
+
// ── 4. Database (injected only) ────────────────────────────────
|
|
159
|
+
const db = options.services?.db;
|
|
160
|
+
// ── 5. Scheduler ───────────────────────────────────────────────
|
|
161
|
+
let scheduler;
|
|
162
|
+
if (schedulerConfig.enabled) {
|
|
163
|
+
const adapter = options.services?.scheduler ?? schedOpts?.adapter;
|
|
164
|
+
if (adapter) {
|
|
165
|
+
setSchedulerAdapter(adapter);
|
|
166
|
+
}
|
|
167
|
+
scheduler = initScheduler(schedOpts?.entries);
|
|
168
|
+
state.schedulerAdapter = scheduler;
|
|
169
|
+
}
|
|
170
|
+
// ── Build resolved config ──────────────────────────────────────
|
|
171
|
+
const resolvedConfig = {
|
|
172
|
+
logging: loggingConfig,
|
|
173
|
+
events: { enabled: eventsEnabled, lifecycle: eventsLifecycle, defaultObservers: eventsDefaultObservers },
|
|
174
|
+
telemetry: telemetryConfig,
|
|
175
|
+
scheduler: schedulerConfig,
|
|
176
|
+
};
|
|
177
|
+
// ── Build runtime handle ───────────────────────────────────────
|
|
178
|
+
const app = {
|
|
179
|
+
config: resolvedConfig,
|
|
180
|
+
appConfig: options.appConfig,
|
|
181
|
+
logger,
|
|
182
|
+
events,
|
|
183
|
+
lifecycleBus,
|
|
184
|
+
db,
|
|
185
|
+
scheduler,
|
|
186
|
+
stop: (reason) => performShutdown(state, reason ?? 'manual'),
|
|
187
|
+
};
|
|
188
|
+
state.app = app;
|
|
189
|
+
// ── 6. User start callback ─────────────────────────────────────
|
|
190
|
+
await options.start(app);
|
|
191
|
+
// ── 7. Start scheduler ─────────────────────────────────────────
|
|
192
|
+
if (schedulerConfig.enabled && schedulerConfig.autoStart && scheduler) {
|
|
193
|
+
await scheduler.start();
|
|
194
|
+
state.schedulerStarted = true;
|
|
195
|
+
}
|
|
196
|
+
return app;
|
|
197
|
+
}
|
|
198
|
+
catch (error) {
|
|
199
|
+
// Reverse-order cleanup of services this bootstrap owns.
|
|
200
|
+
// Scheduler: start() is the last async op before return; if it throws,
|
|
201
|
+
// schedulerStarted is still false, so there is nothing started to stop.
|
|
202
|
+
// DB: injected by the caller (portable bootstrap never creates one), so
|
|
203
|
+
// its lifecycle is caller-owned and not closed here.
|
|
204
|
+
// Telemetry: owned by the bootstrap — shut it down if it was initialized.
|
|
205
|
+
if (state.telemetryInitialized) {
|
|
206
|
+
await shutdownTelemetry();
|
|
207
|
+
}
|
|
208
|
+
throw error;
|
|
209
|
+
}
|
|
210
|
+
}
|
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Portable application bootstrap types.
|
|
3
|
+
*
|
|
4
|
+
* These types define the DI contract for `runApplication` — a thin orchestration
|
|
5
|
+
* layer over existing ts-infra primitives. The portable subpath does not import
|
|
6
|
+
* any runtime-specific adapters; everything injectable comes through the options.
|
|
7
|
+
*
|
|
8
|
+
* @module application/types
|
|
9
|
+
*/
|
|
10
|
+
import type { EventBus } from '../event-bus/event-bus';
|
|
11
|
+
import type { BusLifecycleEvents, EventMap } from '../event-bus/types';
|
|
12
|
+
import type { InfraEvents } from '../events';
|
|
13
|
+
import type { Logger, LogLevel } from '../logger';
|
|
14
|
+
import type { SchedulerAdapter } from '../scheduler/types';
|
|
15
|
+
/** Logging feature flags. */
|
|
16
|
+
export interface LoggingOptions {
|
|
17
|
+
/** Enable logging. Default `true`. */
|
|
18
|
+
enabled?: boolean;
|
|
19
|
+
/** Minimum log level. Default `'info'`. */
|
|
20
|
+
level?: LogLevel;
|
|
21
|
+
/** Enable console output. Default `true`. */
|
|
22
|
+
console?: boolean;
|
|
23
|
+
/**
|
|
24
|
+
* File sink writer. The portable bootstrap never opens files — the caller
|
|
25
|
+
* (or Node convenience subpath) provides a writer.
|
|
26
|
+
*/
|
|
27
|
+
fileSink?: (line: string) => void;
|
|
28
|
+
/** JSON Lines format. Default `true`. */
|
|
29
|
+
json?: boolean;
|
|
30
|
+
}
|
|
31
|
+
/** Event bus feature flags. */
|
|
32
|
+
export interface EventsOptions<TEvents extends EventMap = InfraEvents> {
|
|
33
|
+
/** Enable event bus. Default `true`. */
|
|
34
|
+
enabled?: boolean;
|
|
35
|
+
/** Create and attach a lifecycle bus. Default `true`. */
|
|
36
|
+
lifecycle?: boolean;
|
|
37
|
+
/** Attach default observers (log + telemetry). Default `true`. */
|
|
38
|
+
defaultObservers?: boolean;
|
|
39
|
+
/** Pre-built event bus (skips creation when provided). */
|
|
40
|
+
bus?: EventBus<TEvents>;
|
|
41
|
+
}
|
|
42
|
+
/** Telemetry feature flags. */
|
|
43
|
+
export interface TelemetryOptions {
|
|
44
|
+
/** Enable telemetry instrumentation. Default `true`. */
|
|
45
|
+
enabled?: boolean;
|
|
46
|
+
/** Service name for spans. Default `'ts-libs'`. */
|
|
47
|
+
serviceName?: string;
|
|
48
|
+
/** Deployment environment. Default `'development'`. */
|
|
49
|
+
environment?: string;
|
|
50
|
+
/** Capture sanitized SQL in DB spans. Default `false`. */
|
|
51
|
+
dbStatementDebug?: boolean;
|
|
52
|
+
}
|
|
53
|
+
/** Scheduler feature flags. */
|
|
54
|
+
export interface SchedulerOptions {
|
|
55
|
+
/** Enable scheduler. Default `false`. */
|
|
56
|
+
enabled?: boolean;
|
|
57
|
+
/** Injected adapter (skips noop default when provided). */
|
|
58
|
+
adapter?: SchedulerAdapter;
|
|
59
|
+
/** Cron entries to register: `[cron, action][]`. */
|
|
60
|
+
entries?: Array<[string, () => Promise<void>]>;
|
|
61
|
+
/** Start scheduler immediately after registration. Default `true` when enabled. */
|
|
62
|
+
autoStart?: boolean;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Fully-resolved bootstrap config (all optionals filled with defaults).
|
|
66
|
+
* Constructed internally by `resolveBootstrapConfig`.
|
|
67
|
+
*/
|
|
68
|
+
export interface ApplicationBootstrapConfig {
|
|
69
|
+
readonly logging: Readonly<Required<Pick<LoggingOptions, 'enabled' | 'level' | 'console' | 'json'>> & {
|
|
70
|
+
fileSink?: (line: string) => void;
|
|
71
|
+
}>;
|
|
72
|
+
readonly events: {
|
|
73
|
+
enabled: boolean;
|
|
74
|
+
lifecycle: boolean;
|
|
75
|
+
defaultObservers: boolean;
|
|
76
|
+
};
|
|
77
|
+
readonly telemetry: {
|
|
78
|
+
enabled: boolean;
|
|
79
|
+
serviceName: string;
|
|
80
|
+
environment: string;
|
|
81
|
+
dbStatementDebug: boolean;
|
|
82
|
+
};
|
|
83
|
+
readonly scheduler: {
|
|
84
|
+
enabled: boolean;
|
|
85
|
+
autoStart: boolean;
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
/** Services that may be pre-injected instead of created by the bootstrap. */
|
|
89
|
+
export interface ApplicationServices<TEvents extends EventMap = InfraEvents> {
|
|
90
|
+
logger?: Logger;
|
|
91
|
+
events?: EventBus<TEvents>;
|
|
92
|
+
lifecycleBus?: EventBus<BusLifecycleEvents>;
|
|
93
|
+
db?: DbAdapterLike;
|
|
94
|
+
scheduler?: SchedulerAdapter;
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Minimal DB adapter shape the bootstrap cares about: `close()` for lifecycle.
|
|
98
|
+
* This avoids importing `ts-db` (an optional peer) from the portable subpath.
|
|
99
|
+
*/
|
|
100
|
+
export interface DbAdapterLike {
|
|
101
|
+
close(): void;
|
|
102
|
+
}
|
|
103
|
+
/** Why the application is stopping. */
|
|
104
|
+
export type ApplicationStopReason = 'manual' | 'signal' | 'error' | 'shutdown';
|
|
105
|
+
/**
|
|
106
|
+
* Runtime handle returned by `runApplication`.
|
|
107
|
+
*
|
|
108
|
+
* Exposes all resolved services and a `stop()` method for graceful shutdown.
|
|
109
|
+
*/
|
|
110
|
+
export interface ApplicationRuntime<TAppConfig = unknown, TEvents extends EventMap = InfraEvents> {
|
|
111
|
+
/** Fully-resolved bootstrap config (feature flags + defaults). */
|
|
112
|
+
readonly config: ApplicationBootstrapConfig;
|
|
113
|
+
/** Caller-provided application config, or `undefined`. */
|
|
114
|
+
readonly appConfig: TAppConfig;
|
|
115
|
+
/** Structured logger. */
|
|
116
|
+
readonly logger: Logger;
|
|
117
|
+
/** Application event bus. */
|
|
118
|
+
readonly events: EventBus<TEvents>;
|
|
119
|
+
/** Lifecycle bus (when enabled). */
|
|
120
|
+
readonly lifecycleBus?: EventBus<BusLifecycleEvents>;
|
|
121
|
+
/** DB adapter (when enabled and injected). */
|
|
122
|
+
readonly db?: DbAdapterLike;
|
|
123
|
+
/** Scheduler adapter (when enabled). */
|
|
124
|
+
readonly scheduler?: SchedulerAdapter;
|
|
125
|
+
/** Graceful shutdown. Idempotent — safe to call multiple times. */
|
|
126
|
+
stop(reason?: ApplicationStopReason): Promise<void>;
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Options for the portable `runApplication`.
|
|
130
|
+
*/
|
|
131
|
+
export interface ApplicationBootstrapOptions<TAppConfig = unknown, TEvents extends EventMap = InfraEvents> {
|
|
132
|
+
/** Bootstrap feature flags (partial — defaults applied internally). */
|
|
133
|
+
readonly config?: {
|
|
134
|
+
logging?: LoggingOptions;
|
|
135
|
+
events?: EventsOptions<TEvents>;
|
|
136
|
+
telemetry?: TelemetryOptions;
|
|
137
|
+
scheduler?: SchedulerOptions;
|
|
138
|
+
};
|
|
139
|
+
/** Already-resolved application config. Portable — no file reads. */
|
|
140
|
+
readonly appConfig?: TAppConfig;
|
|
141
|
+
/** Pre-built services to inject instead of creating defaults. */
|
|
142
|
+
readonly services?: Partial<ApplicationServices<TEvents>>;
|
|
143
|
+
/** User callback: application logic. Called after all services are ready. */
|
|
144
|
+
readonly start: (app: ApplicationRuntime<TAppConfig, TEvents>) => Promise<void> | void;
|
|
145
|
+
/** User callback: cleanup before services shut down. */
|
|
146
|
+
readonly stop?: (app: ApplicationRuntime<TAppConfig, TEvents>, reason: ApplicationStopReason) => Promise<void> | void;
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Validation result matching the structural `safeParse` pattern.
|
|
150
|
+
* Avoids hard-coupling to a specific validation library.
|
|
151
|
+
*/
|
|
152
|
+
export interface ConfigValidationResult<T> {
|
|
153
|
+
readonly success: boolean;
|
|
154
|
+
readonly data?: T;
|
|
155
|
+
readonly errors?: ReadonlyArray<{
|
|
156
|
+
path: string;
|
|
157
|
+
message: string;
|
|
158
|
+
}>;
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* Config validator: structural `safeParse`-compatible adapter.
|
|
162
|
+
* Accepts any validation library that produces `{ success, data?, errors? }`.
|
|
163
|
+
*/
|
|
164
|
+
export type ApplicationConfigValidator<TAppConfig> = {
|
|
165
|
+
safeParse(raw: unknown): ConfigValidationResult<TAppConfig>;
|
|
166
|
+
} | ((raw: unknown) => TAppConfig) | {
|
|
167
|
+
validate(raw: unknown): TAppConfig;
|
|
168
|
+
} | {
|
|
169
|
+
parse(raw: unknown): TAppConfig;
|
|
170
|
+
};
|
|
171
|
+
/**
|
|
172
|
+
* Config loader options for the Node/Bun convenience subpath.
|
|
173
|
+
*/
|
|
174
|
+
export interface ApplicationConfigLoader<TAppConfig = unknown> {
|
|
175
|
+
/** Path to the YAML config file. */
|
|
176
|
+
readonly configFile?: string;
|
|
177
|
+
/** YAML section name for bootstrap config. Default `'bootstrap'`. */
|
|
178
|
+
readonly bootstrapSection?: string;
|
|
179
|
+
/** YAML section name for app-specific config. Default: remaining object. */
|
|
180
|
+
readonly appSection?: string;
|
|
181
|
+
/** Caller-provided validator for the app config section. */
|
|
182
|
+
readonly appConfig?: ApplicationConfigValidator<TAppConfig>;
|
|
183
|
+
/** Override values merged after loading. */
|
|
184
|
+
readonly overrides?: Record<string, unknown>;
|
|
185
|
+
}
|
|
186
|
+
export type { BusLifecycleEvents, EventMap } from '../event-bus/types';
|
|
187
|
+
export type { InfraEvents } from '../events';
|
|
188
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/application/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Portable application bootstrap types.
|
|
3
|
+
*
|
|
4
|
+
* These types define the DI contract for `runApplication` — a thin orchestration
|
|
5
|
+
* layer over existing ts-infra primitives. The portable subpath does not import
|
|
6
|
+
* any runtime-specific adapters; everything injectable comes through the options.
|
|
7
|
+
*
|
|
8
|
+
* @module application/types
|
|
9
|
+
*/
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Node/Bun convenience bootstrap for `@gobing-ai/ts-infra`.
|
|
3
|
+
*
|
|
4
|
+
* Composes the portable `runApplication` with runtime-specific wiring:
|
|
5
|
+
* - YAML config loading via `@gobing-ai/ts-runtime`
|
|
6
|
+
* - Application-specific config validation with caller-provided validator
|
|
7
|
+
* - File log sink via `node:fs`
|
|
8
|
+
* - Bun SQLite DB adapter creation from config
|
|
9
|
+
* - Optional Node OTel exporter initialization
|
|
10
|
+
* - Optional Node scheduler adapter
|
|
11
|
+
*
|
|
12
|
+
* This subpath may import runtime-specific adapters. The portable bootstrap
|
|
13
|
+
* subpath (`@gobing-ai/ts-infra/application`) must not.
|
|
14
|
+
*
|
|
15
|
+
* @module application-node
|
|
16
|
+
*/
|
|
17
|
+
import type { ApplicationBootstrapOptions, ApplicationConfigLoader, ApplicationRuntime, ApplicationStopReason, EventMap, InfraEvents } from './application/types';
|
|
18
|
+
/** Error thrown when application config validation fails. Includes file path and section name. */
|
|
19
|
+
export declare class ConfigValidationError extends Error {
|
|
20
|
+
constructor(message: string);
|
|
21
|
+
}
|
|
22
|
+
/** Options for the Node/Bun convenience {@link runNodeApplication}. */
|
|
23
|
+
export interface NodeApplicationOptions<TAppConfig = unknown, TEvents extends EventMap = InfraEvents> {
|
|
24
|
+
/** YAML config loading options. When omitted, uses defaults. */
|
|
25
|
+
readonly configLoader?: ApplicationConfigLoader<TAppConfig>;
|
|
26
|
+
/** Inline bootstrap config (overrides YAML-loaded config). */
|
|
27
|
+
readonly config?: ApplicationBootstrapOptions<TAppConfig, TEvents>['config'];
|
|
28
|
+
/** Pre-built services to inject. */
|
|
29
|
+
readonly services?: ApplicationBootstrapOptions<TAppConfig, TEvents>['services'];
|
|
30
|
+
/** User callback: application logic. */
|
|
31
|
+
readonly start: (app: ApplicationRuntime<TAppConfig, TEvents>) => Promise<void> | void;
|
|
32
|
+
/** User callback: cleanup before services shut down. */
|
|
33
|
+
readonly stop?: (app: ApplicationRuntime<TAppConfig, TEvents>, reason: ApplicationStopReason) => Promise<void> | void;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Node/Bun convenience application bootstrap.
|
|
37
|
+
*
|
|
38
|
+
* Extends the portable `runApplication` with:
|
|
39
|
+
* - YAML config file loading with section splitting
|
|
40
|
+
* - Application-specific config validation
|
|
41
|
+
* - File log sink creation from `logging.filePath`
|
|
42
|
+
* - Bun SQLite DB adapter creation when `database.enabled` + `database.driver`
|
|
43
|
+
* - Optional Node OTel telemetry exporter
|
|
44
|
+
* - Optional Node scheduler adapter
|
|
45
|
+
*
|
|
46
|
+
* @example
|
|
47
|
+
* ```ts
|
|
48
|
+
* import { runNodeApplication } from '@gobing-ai/ts-infra/application-node';
|
|
49
|
+
*
|
|
50
|
+
* await runNodeApplication({
|
|
51
|
+
* configLoader: {
|
|
52
|
+
* configFile: 'config/app.yaml',
|
|
53
|
+
* bootstrapSection: 'bootstrap',
|
|
54
|
+
* appSection: 'billing',
|
|
55
|
+
* appConfig: {
|
|
56
|
+
* safeParse(raw) {
|
|
57
|
+
* return billingSchema.safeParse(raw);
|
|
58
|
+
* },
|
|
59
|
+
* },
|
|
60
|
+
* },
|
|
61
|
+
* async start(app) {
|
|
62
|
+
* app.logger.info('started');
|
|
63
|
+
* },
|
|
64
|
+
* });
|
|
65
|
+
* ```
|
|
66
|
+
*/
|
|
67
|
+
export declare function runNodeApplication<TAppConfig = unknown, TEvents extends EventMap = InfraEvents>(options: NodeApplicationOptions<TAppConfig, TEvents>): Promise<ApplicationRuntime<TAppConfig, TEvents>>;
|
|
68
|
+
//# sourceMappingURL=application-node.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"application-node.d.ts","sourceRoot":"","sources":["../src/application-node.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AASH,OAAO,KAAK,EACR,2BAA2B,EAC3B,uBAAuB,EAEvB,kBAAkB,EAClB,qBAAqB,EAGrB,QAAQ,EACR,WAAW,EAId,MAAM,qBAAqB,CAAC;AAM7B,kGAAkG;AAClG,qBAAa,qBAAsB,SAAQ,KAAK;gBAChC,OAAO,EAAE,MAAM;CAI9B;AAgHD,uEAAuE;AACvE,MAAM,WAAW,sBAAsB,CAAC,UAAU,GAAG,OAAO,EAAE,OAAO,SAAS,QAAQ,GAAG,WAAW;IAChG,gEAAgE;IAChE,QAAQ,CAAC,YAAY,CAAC,EAAE,uBAAuB,CAAC,UAAU,CAAC,CAAC;IAC5D,8DAA8D;IAC9D,QAAQ,CAAC,MAAM,CAAC,EAAE,2BAA2B,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC,QAAQ,CAAC,CAAC;IAC7E,oCAAoC;IACpC,QAAQ,CAAC,QAAQ,CAAC,EAAE,2BAA2B,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC,UAAU,CAAC,CAAC;IACjF,wCAAwC;IACxC,QAAQ,CAAC,KAAK,EAAE,CAAC,GAAG,EAAE,kBAAkB,CAAC,UAAU,EAAE,OAAO,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IACvF,wDAAwD;IACxD,QAAQ,CAAC,IAAI,CAAC,EAAE,CACZ,GAAG,EAAE,kBAAkB,CAAC,UAAU,EAAE,OAAO,CAAC,EAC5C,MAAM,EAAE,qBAAqB,KAC5B,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;CAC7B;AAID;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,wBAAsB,kBAAkB,CAAC,UAAU,GAAG,OAAO,EAAE,OAAO,SAAS,QAAQ,GAAG,WAAW,EACjG,OAAO,EAAE,sBAAsB,CAAC,UAAU,EAAE,OAAO,CAAC,GACrD,OAAO,CAAC,kBAAkB,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC,CAkHlD"}
|