@chidchanun/bcp 0.2.17 → 0.2.18
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 +153 -292
- package/docs/README.md +33 -41
- package/docs/api-manifest.json +24 -16
- package/docs/api-reference.md +150 -140
- package/docs/deployment-platform-v2.md +449 -0
- package/docs/docs-web-manifest.json +5 -3
- package/docs/platform-manifest.json +18 -4
- package/docs/releases/0.2.18.md +136 -0
- package/package.json +10 -5
- package/packages/bundler/src/client-boundary.ts +1 -0
- package/packages/client/src/auth.mjs +1391 -0
- package/packages/client/src/config.mjs +1132 -0
- package/packages/client/src/deployment.mjs +609 -0
- package/packages/client/src/deployment.ts +20 -0
- package/packages/client/src/server.mjs +5615 -0
- package/packages/server/src/deployment.ts +936 -0
- package/packages/server/src/middleware.mjs +631 -0
|
@@ -0,0 +1,449 @@
|
|
|
1
|
+
# Deployment Platform v2
|
|
2
|
+
|
|
3
|
+
BCP Framework `0.2.18` adds a server-only deployment lifecycle layer through `bcp/deployment` and hardens published production entrypoints so application runtime code does not need to execute framework TypeScript directly.
|
|
4
|
+
|
|
5
|
+
## Goals
|
|
6
|
+
|
|
7
|
+
Deployment Platform v2 provides:
|
|
8
|
+
|
|
9
|
+
- application resource startup ordering;
|
|
10
|
+
- reverse-order graceful shutdown;
|
|
11
|
+
- startup rollback when a later resource fails;
|
|
12
|
+
- readiness checks for orchestrators/load balancers;
|
|
13
|
+
- runtime diagnostics and deployment identity;
|
|
14
|
+
- `SIGTERM` / `SIGINT` integration;
|
|
15
|
+
- integration with the existing BCP shutdown-hook registry;
|
|
16
|
+
- compiled production runtimes for key server entrypoints.
|
|
17
|
+
|
|
18
|
+
It does not replace Kubernetes, Docker, systemd, PM2 or another process orchestrator. BCP provides lifecycle primitives that those systems can drive.
|
|
19
|
+
|
|
20
|
+
## Create a deployment runtime
|
|
21
|
+
|
|
22
|
+
```ts
|
|
23
|
+
import {
|
|
24
|
+
createDeploymentRuntime,
|
|
25
|
+
} from "bcp/deployment";
|
|
26
|
+
|
|
27
|
+
export const deployment =
|
|
28
|
+
createDeploymentRuntime({
|
|
29
|
+
serviceName: "orders-api",
|
|
30
|
+
version: "1.4.0",
|
|
31
|
+
});
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
Runtime states are:
|
|
35
|
+
|
|
36
|
+
```text
|
|
37
|
+
idle
|
|
38
|
+
starting
|
|
39
|
+
ready
|
|
40
|
+
draining
|
|
41
|
+
stopped
|
|
42
|
+
failed
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## Register resources
|
|
46
|
+
|
|
47
|
+
Resources are started in registration order and stopped in reverse order.
|
|
48
|
+
|
|
49
|
+
```ts
|
|
50
|
+
deployment.addResource({
|
|
51
|
+
name: "database",
|
|
52
|
+
|
|
53
|
+
async start() {
|
|
54
|
+
await db.connect();
|
|
55
|
+
},
|
|
56
|
+
|
|
57
|
+
async ready() {
|
|
58
|
+
return {
|
|
59
|
+
ok:
|
|
60
|
+
db.status ===
|
|
61
|
+
"ready",
|
|
62
|
+
detail:
|
|
63
|
+
db.status,
|
|
64
|
+
};
|
|
65
|
+
},
|
|
66
|
+
|
|
67
|
+
async stop() {
|
|
68
|
+
await db.close();
|
|
69
|
+
},
|
|
70
|
+
|
|
71
|
+
diagnostics() {
|
|
72
|
+
return {
|
|
73
|
+
provider:
|
|
74
|
+
"postgresql",
|
|
75
|
+
};
|
|
76
|
+
},
|
|
77
|
+
});
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
Then register dependent services later:
|
|
81
|
+
|
|
82
|
+
```ts
|
|
83
|
+
deployment.addResource({
|
|
84
|
+
name: "jobs",
|
|
85
|
+
|
|
86
|
+
async start() {
|
|
87
|
+
workers.start();
|
|
88
|
+
},
|
|
89
|
+
|
|
90
|
+
async stop() {
|
|
91
|
+
await workers.stop();
|
|
92
|
+
},
|
|
93
|
+
});
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
Starting:
|
|
97
|
+
|
|
98
|
+
```ts
|
|
99
|
+
await deployment.start();
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
produces:
|
|
103
|
+
|
|
104
|
+
```text
|
|
105
|
+
database.start()
|
|
106
|
+
↓
|
|
107
|
+
jobs.start()
|
|
108
|
+
↓
|
|
109
|
+
state = ready
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
Shutdown reverses the order:
|
|
113
|
+
|
|
114
|
+
```text
|
|
115
|
+
jobs.stop()
|
|
116
|
+
↓
|
|
117
|
+
database.stop()
|
|
118
|
+
↓
|
|
119
|
+
state = stopped
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
## Startup rollback
|
|
123
|
+
|
|
124
|
+
If a resource fails during startup, already-started resources are stopped in reverse order.
|
|
125
|
+
|
|
126
|
+
```text
|
|
127
|
+
database.start() ✅
|
|
128
|
+
jobs.start() ✅
|
|
129
|
+
realtime.start() ❌
|
|
130
|
+
|
|
131
|
+
rollback:
|
|
132
|
+
|
|
133
|
+
jobs.stop()
|
|
134
|
+
database.stop()
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
The runtime moves to `failed` and `start()` rejects.
|
|
138
|
+
|
|
139
|
+
## Resource context
|
|
140
|
+
|
|
141
|
+
Lifecycle callbacks receive:
|
|
142
|
+
|
|
143
|
+
```ts
|
|
144
|
+
{
|
|
145
|
+
metadata,
|
|
146
|
+
signal,
|
|
147
|
+
}
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
`signal` is aborted when shutdown begins. Long-running BCP/application components can use it to stop accepting new work or cancel background loops.
|
|
151
|
+
|
|
152
|
+
## Readiness
|
|
153
|
+
|
|
154
|
+
```ts
|
|
155
|
+
const report =
|
|
156
|
+
await deployment.readiness();
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
A runtime is ready only when:
|
|
160
|
+
|
|
161
|
+
1. runtime state is `ready`;
|
|
162
|
+
2. all registered resources are in the started state;
|
|
163
|
+
3. every resource readiness function reports success.
|
|
164
|
+
|
|
165
|
+
Create an HTTP response directly:
|
|
166
|
+
|
|
167
|
+
```ts
|
|
168
|
+
import {
|
|
169
|
+
createDeploymentReadinessResponse,
|
|
170
|
+
} from "bcp/deployment";
|
|
171
|
+
|
|
172
|
+
export function GET() {
|
|
173
|
+
return createDeploymentReadinessResponse(
|
|
174
|
+
deployment
|
|
175
|
+
);
|
|
176
|
+
}
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
Successful readiness returns HTTP `200`. A non-ready runtime returns `503`.
|
|
180
|
+
|
|
181
|
+
The response uses:
|
|
182
|
+
|
|
183
|
+
```text
|
|
184
|
+
Cache-Control: no-store
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
Recommended route:
|
|
188
|
+
|
|
189
|
+
```text
|
|
190
|
+
/api/ready
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
Do not place authentication/user data in this endpoint when it is consumed by infrastructure health probes.
|
|
194
|
+
|
|
195
|
+
## Diagnostics
|
|
196
|
+
|
|
197
|
+
```ts
|
|
198
|
+
const diagnostics =
|
|
199
|
+
await deployment.diagnostics();
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
The report includes:
|
|
203
|
+
|
|
204
|
+
- service/deployment identity;
|
|
205
|
+
- process ID;
|
|
206
|
+
- Node version;
|
|
207
|
+
- platform/architecture;
|
|
208
|
+
- runtime state;
|
|
209
|
+
- uptime;
|
|
210
|
+
- lifecycle state for each registered resource;
|
|
211
|
+
- optional resource-specific diagnostic metadata.
|
|
212
|
+
|
|
213
|
+
An HTTP response helper is available:
|
|
214
|
+
|
|
215
|
+
```ts
|
|
216
|
+
import {
|
|
217
|
+
createDeploymentDiagnosticsResponse,
|
|
218
|
+
} from "bcp/deployment";
|
|
219
|
+
|
|
220
|
+
export function GET() {
|
|
221
|
+
return createDeploymentDiagnosticsResponse(
|
|
222
|
+
deployment
|
|
223
|
+
);
|
|
224
|
+
}
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
Diagnostics can reveal infrastructure details. Protect the route when exposing it outside a trusted operations network.
|
|
228
|
+
|
|
229
|
+
## Deployment metadata
|
|
230
|
+
|
|
231
|
+
The runtime accepts explicit identifiers:
|
|
232
|
+
|
|
233
|
+
```ts
|
|
234
|
+
createDeploymentRuntime({
|
|
235
|
+
serviceName:
|
|
236
|
+
"orders-api",
|
|
237
|
+
deploymentId:
|
|
238
|
+
"deploy-20260831-01",
|
|
239
|
+
instanceId:
|
|
240
|
+
"orders-api-7f5d9",
|
|
241
|
+
release:
|
|
242
|
+
"2026.08.31",
|
|
243
|
+
environmentName:
|
|
244
|
+
"production",
|
|
245
|
+
});
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
Or resolve them from runtime environment variables:
|
|
249
|
+
|
|
250
|
+
```text
|
|
251
|
+
BCP_DEPLOYMENT_ID
|
|
252
|
+
BCP_INSTANCE_ID
|
|
253
|
+
BCP_RELEASE
|
|
254
|
+
NODE_ENV
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
If `BCP_DEPLOYMENT_ID` is not supplied, BCP generates a UUID for the process.
|
|
258
|
+
|
|
259
|
+
## Shutdown timeout
|
|
260
|
+
|
|
261
|
+
Default shutdown timeout:
|
|
262
|
+
|
|
263
|
+
```text
|
|
264
|
+
10 seconds
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
Configure it explicitly:
|
|
268
|
+
|
|
269
|
+
```ts
|
|
270
|
+
createDeploymentRuntime({
|
|
271
|
+
serviceName: "orders-api",
|
|
272
|
+
shutdownTimeoutMs:
|
|
273
|
+
30_000,
|
|
274
|
+
});
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
or through:
|
|
278
|
+
|
|
279
|
+
```dotenv
|
|
280
|
+
BCP_SHUTDOWN_TIMEOUT_MS=30000
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
The timeout is shared by reverse-order resource shutdown. If a resource does not finish before the remaining deadline, shutdown records the failure and eventually rejects with `AggregateError`.
|
|
284
|
+
|
|
285
|
+
## Signal handling
|
|
286
|
+
|
|
287
|
+
Install handlers:
|
|
288
|
+
|
|
289
|
+
```ts
|
|
290
|
+
const removeSignals =
|
|
291
|
+
deployment.installSignalHandlers();
|
|
292
|
+
```
|
|
293
|
+
|
|
294
|
+
Default signals:
|
|
295
|
+
|
|
296
|
+
```text
|
|
297
|
+
SIGTERM
|
|
298
|
+
SIGINT
|
|
299
|
+
```
|
|
300
|
+
|
|
301
|
+
The handlers start graceful shutdown and set `process.exitCode` rather than immediately calling `process.exit()`. This allows pending cleanup/microtasks to finish.
|
|
302
|
+
|
|
303
|
+
Remove handlers when ownership moves elsewhere:
|
|
304
|
+
|
|
305
|
+
```ts
|
|
306
|
+
removeSignals();
|
|
307
|
+
```
|
|
308
|
+
|
|
309
|
+
Custom signal set:
|
|
310
|
+
|
|
311
|
+
```ts
|
|
312
|
+
deployment.installSignalHandlers({
|
|
313
|
+
signals: [
|
|
314
|
+
"SIGTERM",
|
|
315
|
+
],
|
|
316
|
+
});
|
|
317
|
+
```
|
|
318
|
+
|
|
319
|
+
## Existing BCP shutdown hooks
|
|
320
|
+
|
|
321
|
+
Deployment runtime can participate in the existing production-hardening shutdown registry:
|
|
322
|
+
|
|
323
|
+
```ts
|
|
324
|
+
const unregister =
|
|
325
|
+
deployment.registerShutdownHook();
|
|
326
|
+
```
|
|
327
|
+
|
|
328
|
+
When the framework executes registered shutdown hooks, the deployment runtime drains its resources.
|
|
329
|
+
|
|
330
|
+
Use either direct signal ownership or integrate with an application-level signal coordinator. Avoid installing multiple independent handlers that all own the same resource lifecycle.
|
|
331
|
+
|
|
332
|
+
## Recommended topology
|
|
333
|
+
|
|
334
|
+
```text
|
|
335
|
+
Load balancer / orchestrator
|
|
336
|
+
│
|
|
337
|
+
├── readiness probe
|
|
338
|
+
│ ↓
|
|
339
|
+
│ bcp/deployment
|
|
340
|
+
│
|
|
341
|
+
└── SIGTERM
|
|
342
|
+
↓
|
|
343
|
+
state = draining
|
|
344
|
+
↓
|
|
345
|
+
stop inbound/realtime
|
|
346
|
+
↓
|
|
347
|
+
stop workers/jobs
|
|
348
|
+
↓
|
|
349
|
+
close database
|
|
350
|
+
↓
|
|
351
|
+
state = stopped
|
|
352
|
+
```
|
|
353
|
+
|
|
354
|
+
## Jobs and workflow workers
|
|
355
|
+
|
|
356
|
+
Register workers as resources so they stop before shared dependencies such as Redis or SQL connections:
|
|
357
|
+
|
|
358
|
+
```ts
|
|
359
|
+
deployment.addResource({
|
|
360
|
+
name: "workers",
|
|
361
|
+
|
|
362
|
+
start() {
|
|
363
|
+
worker =
|
|
364
|
+
jobs.startWorker();
|
|
365
|
+
},
|
|
366
|
+
|
|
367
|
+
async stop() {
|
|
368
|
+
await worker.stop();
|
|
369
|
+
},
|
|
370
|
+
});
|
|
371
|
+
```
|
|
372
|
+
|
|
373
|
+
Register database/cache connections before workers. Reverse-order shutdown then naturally stops workers before closing their dependencies.
|
|
374
|
+
|
|
375
|
+
## Realtime
|
|
376
|
+
|
|
377
|
+
For realtime transports, mark the system not-ready before closing shared storage/transport resources. Runtime state changes to `draining` before resource stop hooks run, so readiness probes begin returning `503` while shutdown is in progress.
|
|
378
|
+
|
|
379
|
+
## Observability
|
|
380
|
+
|
|
381
|
+
Deployment metadata can be attached to logs/traces:
|
|
382
|
+
|
|
383
|
+
```ts
|
|
384
|
+
const metadata =
|
|
385
|
+
deployment.metadata;
|
|
386
|
+
|
|
387
|
+
logger.info(
|
|
388
|
+
"runtime ready",
|
|
389
|
+
{
|
|
390
|
+
deploymentId:
|
|
391
|
+
metadata.deploymentId,
|
|
392
|
+
instanceId:
|
|
393
|
+
metadata.instanceId,
|
|
394
|
+
release:
|
|
395
|
+
metadata.release,
|
|
396
|
+
}
|
|
397
|
+
);
|
|
398
|
+
```
|
|
399
|
+
|
|
400
|
+
Use `bcp/observability` for trace/span correlation and `bcp/deployment` for process/deployment identity and lifecycle state.
|
|
401
|
+
|
|
402
|
+
## Compiled server runtimes
|
|
403
|
+
|
|
404
|
+
Prepared `bcp` packages now compile these production entrypoints:
|
|
405
|
+
|
|
406
|
+
```text
|
|
407
|
+
bcp/cache -> cache.mjs
|
|
408
|
+
bcp/config -> config.mjs
|
|
409
|
+
bcp/database -> database.mjs
|
|
410
|
+
bcp/auth -> auth.mjs
|
|
411
|
+
bcp/jobs -> jobs.mjs
|
|
412
|
+
bcp/workflow -> workflow.mjs
|
|
413
|
+
bcp/events -> events.mjs
|
|
414
|
+
bcp/realtime -> realtime.mjs
|
|
415
|
+
bcp/testing -> testing.mjs
|
|
416
|
+
bcp/plugins -> plugins.mjs
|
|
417
|
+
bcp/observability -> observability.mjs
|
|
418
|
+
bcp/deployment -> deployment.mjs
|
|
419
|
+
bcp/server -> server.mjs
|
|
420
|
+
bcp/middleware -> middleware.mjs
|
|
421
|
+
```
|
|
422
|
+
|
|
423
|
+
Type declarations/source types remain available from the TypeScript source entrypoint while runtime resolution points to compiled ESM in prepared npm packages.
|
|
424
|
+
|
|
425
|
+
This reduces reliance on Node TypeScript stripping for server framework runtime entrypoints and provides a more deterministic production package.
|
|
426
|
+
|
|
427
|
+
## Compatibility
|
|
428
|
+
|
|
429
|
+
`0.2.18` is intended to be backward compatible with `0.2.17`.
|
|
430
|
+
|
|
431
|
+
Existing:
|
|
432
|
+
|
|
433
|
+
```text
|
|
434
|
+
bcp build
|
|
435
|
+
bcp package
|
|
436
|
+
npm start
|
|
437
|
+
registerShutdownHook()
|
|
438
|
+
```
|
|
439
|
+
|
|
440
|
+
remain available. `bcp/deployment` is additive.
|
|
441
|
+
|
|
442
|
+
## Related guides
|
|
443
|
+
|
|
444
|
+
- [Application Packaging](application-packaging.md)
|
|
445
|
+
- [Deployment](deployment.md)
|
|
446
|
+
- [Production Hardening](production-hardening.md)
|
|
447
|
+
- [Observability Platform v3](observability-v3.md)
|
|
448
|
+
- [Background Jobs](background-jobs.md)
|
|
449
|
+
- [Realtime Platform](realtime-platform.md)
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schemaVersion": 1,
|
|
3
3
|
"framework": "bcp",
|
|
4
|
-
"versionTarget": "0.2.
|
|
4
|
+
"versionTarget": "0.2.18",
|
|
5
5
|
"releaseState": "unreleased",
|
|
6
6
|
"sections": [
|
|
7
7
|
{
|
|
@@ -58,13 +58,14 @@
|
|
|
58
58
|
{
|
|
59
59
|
"id": "runtime",
|
|
60
60
|
"title": "Runtime & Infrastructure",
|
|
61
|
-
"description": "Middleware, jobs, scheduling, workflows, event delivery, realtime channels, observability, distributed caching, security and production hardening.",
|
|
61
|
+
"description": "Middleware, jobs, scheduling, workflows, event delivery, realtime channels, observability, deployment lifecycle, distributed caching, security and production hardening.",
|
|
62
62
|
"pages": [
|
|
63
63
|
{ "route": "/docs/middleware", "source": "middleware.md", "title": "Middleware" },
|
|
64
64
|
{ "route": "/docs/hydration", "source": "hydration.md", "title": "Hydration" },
|
|
65
65
|
{ "route": "/docs/development-logging", "source": "development-logging.md", "title": "Logging" },
|
|
66
66
|
{ "route": "/docs/observability", "source": "observability.md", "title": "Observability Platform v2" },
|
|
67
67
|
{ "route": "/docs/observability-v3", "source": "observability-v3.md", "title": "Observability Platform v3" },
|
|
68
|
+
{ "route": "/docs/deployment-platform-v2", "source": "deployment-platform-v2.md", "title": "Deployment Platform v2" },
|
|
68
69
|
{ "route": "/docs/background-jobs", "source": "background-jobs.md", "title": "Background Jobs Platform" },
|
|
69
70
|
{ "route": "/docs/job-scheduling", "source": "job-scheduling.md", "title": "Job Scheduling Platform" },
|
|
70
71
|
{ "route": "/docs/durable-jobs", "source": "durable-jobs.md", "title": "Durable Jobs Platform" },
|
|
@@ -118,7 +119,8 @@
|
|
|
118
119
|
}
|
|
119
120
|
],
|
|
120
121
|
"releases": [
|
|
121
|
-
{ "route": "/releases/0.2.
|
|
122
|
+
{ "route": "/releases/0.2.18", "source": "releases/0.2.18.md", "version": "0.2.18", "state": "unreleased" },
|
|
123
|
+
{ "route": "/releases/0.2.17", "source": "releases/0.2.17.md", "version": "0.2.17" },
|
|
122
124
|
{ "route": "/releases/0.2.16", "source": "releases/0.2.16.md", "version": "0.2.16" },
|
|
123
125
|
{ "route": "/releases/0.2.15", "source": "releases/0.2.15.md", "version": "0.2.15" },
|
|
124
126
|
{ "route": "/releases/0.2.14", "source": "releases/0.2.14.md", "version": "0.2.14" },
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schemaVersion": 1,
|
|
3
3
|
"framework": "bcp",
|
|
4
|
-
"version": "0.2.
|
|
4
|
+
"version": "0.2.18",
|
|
5
5
|
"releaseState": "unreleased",
|
|
6
|
-
"baseline": "
|
|
6
|
+
"baseline": "deployment-platform-v2",
|
|
7
7
|
"runtime": {
|
|
8
8
|
"node": ">=24.11.0",
|
|
9
9
|
"react": "19",
|
|
@@ -26,6 +26,7 @@
|
|
|
26
26
|
"bcp/testing",
|
|
27
27
|
"bcp/plugins",
|
|
28
28
|
"bcp/observability",
|
|
29
|
+
"bcp/deployment",
|
|
29
30
|
"bcp/server",
|
|
30
31
|
"bcp/server-only",
|
|
31
32
|
"bcp/middleware"
|
|
@@ -82,6 +83,18 @@
|
|
|
82
83
|
"traceMetricsExporter": true,
|
|
83
84
|
"traceLogFields": true,
|
|
84
85
|
"compiledObservabilityRuntime": true,
|
|
86
|
+
"deploymentPlatformV2": true,
|
|
87
|
+
"deploymentRuntimeLifecycle": true,
|
|
88
|
+
"deploymentResourceRegistry": true,
|
|
89
|
+
"deploymentReadiness": true,
|
|
90
|
+
"deploymentDiagnostics": true,
|
|
91
|
+
"deploymentSignalHandling": true,
|
|
92
|
+
"deploymentShutdownHooks": true,
|
|
93
|
+
"deploymentRuntimeMetadata": true,
|
|
94
|
+
"compiledConfigRuntime": true,
|
|
95
|
+
"compiledAuthRuntime": true,
|
|
96
|
+
"compiledServerRuntime": true,
|
|
97
|
+
"compiledMiddlewareRuntime": true,
|
|
85
98
|
"backgroundJobsPlatform": true,
|
|
86
99
|
"jobQueueAdapterContract": true,
|
|
87
100
|
"inMemoryJobQueue": true,
|
|
@@ -211,7 +224,7 @@
|
|
|
211
224
|
"s3-compatible"
|
|
212
225
|
],
|
|
213
226
|
"compatibility": {
|
|
214
|
-
"previousBaseline": "0.2.
|
|
227
|
+
"previousBaseline": "0.2.17",
|
|
215
228
|
"intentionalBreakingChangesFromPreviousBaseline": false,
|
|
216
229
|
"migrationGuide": "migration-0.2.md"
|
|
217
230
|
},
|
|
@@ -229,6 +242,7 @@
|
|
|
229
242
|
"authorizationSecurity": "authorization-security.md",
|
|
230
243
|
"observability": "observability.md",
|
|
231
244
|
"observabilityV3": "observability-v3.md",
|
|
245
|
+
"deploymentPlatformV2": "deployment-platform-v2.md",
|
|
232
246
|
"backgroundJobs": "background-jobs.md",
|
|
233
247
|
"jobScheduling": "job-scheduling.md",
|
|
234
248
|
"durableJobs": "durable-jobs.md",
|
|
@@ -239,6 +253,6 @@
|
|
|
239
253
|
"pluginModulePlatform": "plugin-module-platform.md",
|
|
240
254
|
"cachePlatformV2": "cache-platform-v2.md",
|
|
241
255
|
"migrationGuide": "migration-0.2.md",
|
|
242
|
-
"releaseNotes": "releases/0.2.
|
|
256
|
+
"releaseNotes": "releases/0.2.18.md"
|
|
243
257
|
}
|
|
244
258
|
}
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
# BCP Framework 0.2.18 — Deployment Platform v2
|
|
2
|
+
|
|
3
|
+
Status: **unreleased**
|
|
4
|
+
|
|
5
|
+
`0.2.18` adds a framework-native deployment lifecycle and hardens prepared npm runtime entrypoints for standalone Node production use.
|
|
6
|
+
|
|
7
|
+
## Highlights
|
|
8
|
+
|
|
9
|
+
### New `bcp/deployment` entrypoint
|
|
10
|
+
|
|
11
|
+
```ts
|
|
12
|
+
import {
|
|
13
|
+
createDeploymentRuntime,
|
|
14
|
+
} from "bcp/deployment";
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
Deployment runtime provides:
|
|
18
|
+
|
|
19
|
+
- ordered resource startup;
|
|
20
|
+
- reverse-order graceful shutdown;
|
|
21
|
+
- startup rollback;
|
|
22
|
+
- readiness checks;
|
|
23
|
+
- deployment/process diagnostics;
|
|
24
|
+
- deployment/instance/release metadata;
|
|
25
|
+
- `SIGTERM` / `SIGINT` handling;
|
|
26
|
+
- integration with existing BCP shutdown hooks.
|
|
27
|
+
|
|
28
|
+
### Readiness endpoints
|
|
29
|
+
|
|
30
|
+
```ts
|
|
31
|
+
return createDeploymentReadinessResponse(
|
|
32
|
+
deployment
|
|
33
|
+
);
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
Ready runtime returns `200`; non-ready/draining/failed runtime returns `503`.
|
|
37
|
+
|
|
38
|
+
### Diagnostics
|
|
39
|
+
|
|
40
|
+
```ts
|
|
41
|
+
return createDeploymentDiagnosticsResponse(
|
|
42
|
+
deployment
|
|
43
|
+
);
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
Diagnostics include process/runtime identity, uptime and resource lifecycle state plus optional resource diagnostics.
|
|
47
|
+
|
|
48
|
+
### Runtime identity
|
|
49
|
+
|
|
50
|
+
Supported runtime environment values:
|
|
51
|
+
|
|
52
|
+
```text
|
|
53
|
+
BCP_DEPLOYMENT_ID
|
|
54
|
+
BCP_INSTANCE_ID
|
|
55
|
+
BCP_RELEASE
|
|
56
|
+
NODE_ENV
|
|
57
|
+
BCP_SHUTDOWN_TIMEOUT_MS
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
### Compiled production entrypoints
|
|
61
|
+
|
|
62
|
+
Prepared framework packages now use compiled ESM runtime files for additional server-side entrypoints:
|
|
63
|
+
|
|
64
|
+
```text
|
|
65
|
+
bcp/config -> config.mjs
|
|
66
|
+
bcp/auth -> auth.mjs
|
|
67
|
+
bcp/deployment -> deployment.mjs
|
|
68
|
+
bcp/server -> server.mjs
|
|
69
|
+
bcp/middleware -> middleware.mjs
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
Existing compiled server runtimes such as cache/database/jobs/workflow/events/realtime/testing/plugins/observability remain compiled as before.
|
|
73
|
+
|
|
74
|
+
This closes a packaging gap where several server entrypoints still resolved directly to TypeScript in the published package.
|
|
75
|
+
|
|
76
|
+
## Public API additions
|
|
77
|
+
|
|
78
|
+
```text
|
|
79
|
+
createDeploymentRuntime
|
|
80
|
+
createDeploymentReadinessResponse
|
|
81
|
+
createDeploymentDiagnosticsResponse
|
|
82
|
+
|
|
83
|
+
DeploymentRuntime
|
|
84
|
+
DeploymentRuntimeOptions
|
|
85
|
+
DeploymentRuntimeState
|
|
86
|
+
DeploymentResource
|
|
87
|
+
DeploymentResourceContext
|
|
88
|
+
DeploymentResourceStatus
|
|
89
|
+
DeploymentReadinessResult
|
|
90
|
+
DeploymentReadinessReport
|
|
91
|
+
DeploymentDiagnosticsReport
|
|
92
|
+
DeploymentMetadata
|
|
93
|
+
DeploymentSignalOptions
|
|
94
|
+
DeploymentShutdownOptions
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
## Lifecycle model
|
|
98
|
+
|
|
99
|
+
```text
|
|
100
|
+
idle
|
|
101
|
+
↓
|
|
102
|
+
starting
|
|
103
|
+
↓
|
|
104
|
+
ready
|
|
105
|
+
↓
|
|
106
|
+
draining
|
|
107
|
+
↓
|
|
108
|
+
stopped
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
Failures move the runtime to `failed`.
|
|
112
|
+
|
|
113
|
+
## Compatibility
|
|
114
|
+
|
|
115
|
+
There are no intentional breaking changes from `0.2.17`.
|
|
116
|
+
|
|
117
|
+
Existing production hardening APIs, shutdown hooks, `bcp build`, `bcp package` and application package manifests remain supported.
|
|
118
|
+
|
|
119
|
+
`bcp/deployment` is additive.
|
|
120
|
+
|
|
121
|
+
## Validation
|
|
122
|
+
|
|
123
|
+
Before tagging/publishing:
|
|
124
|
+
|
|
125
|
+
```bash
|
|
126
|
+
npm run typecheck
|
|
127
|
+
npm run test:unit
|
|
128
|
+
npm run test:integration
|
|
129
|
+
npm run test:e2e
|
|
130
|
+
npm run test:package
|
|
131
|
+
npm run rc:check
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
The `0.2.18` package smoke validates the compiled deployment runtime plus compiled config/auth/server/middleware entrypoints from the prepared `.package/bcp` staging directory.
|
|
135
|
+
|
|
136
|
+
Do not tag/publish until the final commit passes the complete RC sequence.
|