@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 CHANGED
@@ -1,10 +1,10 @@
1
1
  # BCP Framework
2
2
 
3
- BCP Framework is a React full-stack framework for file-based routing, SSR, SPA navigation, server data loading, API routes, authentication, authorization, SQL databases, background jobs, scheduling, workflow orchestration, transactional events, realtime delivery, framework-native testing, plugin/module composition, distributed caching, observability, uploads, storage and standalone Node.js deployment.
3
+ BCP Framework is a React full-stack framework for file-based routing, SSR, SPA navigation, server data loading, API routes, authentication, authorization, SQL databases, background jobs, scheduling, workflow orchestration, transactional events, realtime delivery, framework-native testing, plugin/module composition, distributed caching, observability, deployment lifecycle, uploads, storage and standalone Node.js deployment.
4
4
 
5
- > **Development target:** `0.2.17Observability Platform v3`
5
+ > **Development target:** `0.2.18Deployment Platform v2`
6
6
  >
7
- > `0.2.17` remains unreleased until local validation, RC checks, tagging and npm publication complete.
7
+ > `0.2.18` remains unreleased until local validation, RC checks, tagging and npm publication complete.
8
8
 
9
9
  ## Current platform
10
10
 
@@ -27,11 +27,12 @@ BCP Framework is a React full-stack framework for file-based routing, SSR, SPA n
27
27
  | Realtime | Channels/rooms, presence, broker delivery, WebSocket adapter contract, SSE and heartbeat |
28
28
  | Testing | Request/route/page/auth/database/middleware/jobs/workflow/outbox/realtime/SSE test harnesses |
29
29
  | Plugins & modules | Dependency ordering, lifecycle hooks, config parsing, service registry and async extension hooks |
30
- | Caching | Legacy request/data cache plus Cache Platform v2 adapters, Redis-compatible cache/locks, stampede protection, TTL/tag/path invalidation and metrics |
30
+ | Caching | Cache Platform v2 adapters, Redis-compatible cache/locks, stampede protection, TTL/tag/path invalidation and metrics |
31
31
  | Observability | Metrics, Prometheus, health/readiness, distributed tracing, W3C trace context and correlation IDs |
32
+ | Deployment | Resource lifecycle, readiness, diagnostics, runtime identity, signal handling and graceful shutdown |
32
33
  | Uploads & storage | Multipart streaming, Local/S3-compatible storage and signed URLs |
33
34
  | Configuration | Typed config/environment validation and diagnostics |
34
- | Production | Standalone Node.js build, packaging, dependency pruning, Docker starter and graceful shutdown |
35
+ | Production | Standalone Node.js build, compiled server entrypoints, packaging, dependency pruning and Docker starter |
35
36
  | Documentation | Manifest-driven docs, platform metadata and API reference |
36
37
 
37
38
  ## Requirements
@@ -78,345 +79,221 @@ import { createTransactionalOutbox } from "bcp/events";
78
79
  import { createRealtime } from "bcp/realtime";
79
80
  import { createTestApp } from "bcp/testing";
80
81
  import { createPluginHost } from "bcp/plugins";
81
- import {
82
- createMetricsRegistry,
83
- createTracer,
84
- } from "bcp/observability";
82
+ import { createTracer } from "bcp/observability";
83
+ import { createDeploymentRuntime } from "bcp/deployment";
85
84
  ```
86
85
 
87
- ## Durable jobs and scheduling
86
+ ## Durable application infrastructure
88
87
 
89
- ```ts
90
- import {
91
- createJobQueue,
92
- createJobScheduler,
93
- } from "bcp/jobs";
94
-
95
- export const jobs =
96
- createJobQueue();
88
+ BCP keeps durable application state separate from transient delivery:
97
89
 
98
- export const scheduler =
99
- createJobScheduler({
100
- queue: jobs,
101
- });
90
+ ```text
91
+ HTTP / API
92
+ |
93
+ +-- Database
94
+ | +-- Transactional Outbox
95
+ |
96
+ +-- Jobs / Scheduler
97
+ | +-- Workflow
98
+ |
99
+ +-- Realtime
100
+ |
101
+ +-- Cache
102
+ |
103
+ +-- Observability
104
+ |
105
+ +-- Deployment lifecycle
102
106
  ```
103
107
 
104
- Production adapters can provide Redis-compatible durable queue/schedule storage without BCP owning the Redis connection.
108
+ Database/outbox/jobs/workflows remain durable truth. Realtime is transient delivery. Cache is an optimization layer. Tracing correlates operations without replacing state contracts.
105
109
 
106
- ## Workflow Orchestration — 0.2.11
110
+ ## Deployment Platform v2 — 0.2.18
111
+
112
+ `0.2.18` adds the server-only `bcp/deployment` entrypoint.
107
113
 
108
114
  ```ts
109
115
  import {
110
- createWorkflow,
111
- } from "bcp/workflow";
112
-
113
- export const onboarding =
114
- createWorkflow<{
115
- userId: number;
116
- }>(
117
- "user.onboarding",
118
- workflow => {
119
- workflow.step(
120
- "profile",
121
- createProfile
122
- );
123
- workflow.parallel(
124
- "initialize",
125
- parallel => {
126
- parallel.step(
127
- "preferences",
128
- createPreferences
129
- );
130
- parallel.step(
131
- "workspace",
132
- createWorkspace
133
- );
134
- }
135
- );
136
- workflow.delay(
137
- "cooldown",
138
- 1_000
139
- );
140
- }
141
- );
116
+ createDeploymentRuntime,
117
+ } from "bcp/deployment";
118
+
119
+ export const deployment =
120
+ createDeploymentRuntime({
121
+ serviceName: "orders-api",
122
+ version: "1.0.0",
123
+ });
142
124
  ```
143
125
 
144
- Workflows support retries, compensation, persisted delays and optional durable queue execution.
126
+ Register resources in dependency order:
145
127
 
146
- ## Transactional Outbox & Events — 0.2.12
128
+ ```ts
129
+ deployment.addResource({
130
+ name: "database",
147
131
 
148
- Use the same SQL transaction for business data and its outbox event:
132
+ async start() {
133
+ await db.connect();
134
+ },
149
135
 
150
- ```ts
151
- await db.transaction(
152
- async tx => {
153
- await tx.execute(
154
- "INSERT INTO orders ..."
155
- );
156
-
157
- await outbox.publish(
158
- tx,
159
- "order.created",
160
- {
161
- orderId: 42,
162
- }
163
- );
164
- }
165
- );
166
- ```
136
+ async ready() {
137
+ return db.status === "ready";
138
+ },
167
139
 
168
- After commit, an outbox dispatcher can deliver through `bcp/jobs`, a custom publisher or the local event bus.
140
+ async stop() {
141
+ await db.close();
142
+ },
143
+ });
169
144
 
170
- Read more: [Transactional Outbox & Events](docs/transactional-outbox-events.md)
145
+ deployment.addResource({
146
+ name: "workers",
171
147
 
172
- ## Realtime Platform — 0.2.13
148
+ start() {
149
+ worker = jobs.startWorker();
150
+ },
173
151
 
174
- ```ts
175
- import {
176
- createRealtime,
177
- } from "bcp/realtime";
152
+ async stop() {
153
+ await worker.stop();
154
+ },
155
+ });
178
156
 
179
- export const realtime =
180
- createRealtime();
157
+ await deployment.start();
181
158
  ```
182
159
 
183
- BCP intentionally does not install a WebSocket server library. Applications adapt `ws`, uWebSockets.js or another transport to `RealtimeSocket`. SSE is built in through Web `Response`.
184
-
185
- Read more: [Realtime Platform](docs/realtime-platform.md)
160
+ Startup follows registration order. Shutdown runs in reverse order, so workers can stop before their database/cache/Redis dependencies close. If startup fails midway, already-started resources are rolled back in reverse order.
186
161
 
187
- ## Testing Platform — 0.2.14
188
-
189
- `bcp/testing` provides runner-neutral request/route/page/auth/database/middleware/jobs/workflow/outbox/realtime/SSE test helpers.
162
+ Readiness:
190
163
 
191
164
  ```ts
192
165
  import {
193
- createRouteTestHandler,
194
- createTestApp,
195
- expectResponse,
196
- } from "bcp/testing";
197
-
198
- const app =
199
- createTestApp({
200
- handler:
201
- createRouteTestHandler({
202
- GET() {
203
- return {
204
- ok: true,
205
- };
206
- },
207
- }),
208
- });
166
+ createDeploymentReadinessResponse,
167
+ } from "bcp/deployment";
209
168
 
210
- await expectResponse(
211
- await app.get("/api/health")
212
- )
213
- .status(200)
214
- .json({
215
- ok: true,
216
- });
169
+ export function GET() {
170
+ return createDeploymentReadinessResponse(
171
+ deployment
172
+ );
173
+ }
217
174
  ```
218
175
 
219
- Read more: [Testing Platform](docs/testing-platform.md)
176
+ A ready runtime returns `200`; starting, draining, failed or unhealthy runtimes return `503`.
220
177
 
221
- ## Plugin & Module Platform — 0.2.15
178
+ Diagnostics:
222
179
 
223
180
  ```ts
224
181
  import {
225
- createPluginHost,
226
- definePlugin,
227
- } from "bcp/plugins";
228
-
229
- const databasePlugin =
230
- definePlugin({
231
- name: "database",
232
- setup(context) {
233
- context.services.provide(
234
- "database",
235
- db
236
- );
237
- },
238
- });
182
+ createDeploymentDiagnosticsResponse,
183
+ } from "bcp/deployment";
184
+ ```
239
185
 
240
- const jobsPlugin =
241
- definePlugin({
242
- name: "jobs",
243
- requires: [
244
- "database",
245
- ],
246
- });
186
+ Deployment metadata can use:
247
187
 
248
- export const plugins =
249
- createPluginHost({
250
- plugins: [
251
- jobsPlugin,
252
- databasePlugin,
253
- ],
254
- });
188
+ ```text
189
+ BCP_DEPLOYMENT_ID
190
+ BCP_INSTANCE_ID
191
+ BCP_RELEASE
192
+ NODE_ENV
193
+ BCP_SHUTDOWN_TIMEOUT_MS
255
194
  ```
256
195
 
257
- Startup follows dependency order; stop/dispose runs in reverse order. Modules, config parsing, shared services and async hook buses are supported.
196
+ Signal ownership is optional:
258
197
 
259
- Read more: [Plugin & Module Platform](docs/plugin-module-platform.md)
198
+ ```ts
199
+ const removeSignalHandlers =
200
+ deployment.installSignalHandlers();
201
+ ```
260
202
 
261
- ## Cache Platform v2 0.2.16
203
+ Default signals are `SIGTERM` and `SIGINT`. BCP sets `process.exitCode` after graceful shutdown instead of immediately terminating the process.
262
204
 
263
- `0.2.16` keeps the original `cache()` / `dedupe()` APIs and adds provider-neutral asynchronous cache stores.
205
+ The runtime can also integrate with the existing framework shutdown registry:
264
206
 
265
207
  ```ts
266
- import {
267
- createCacheStore,
268
- createRedisCacheAdapter,
269
- createRedisCacheLockAdapter,
270
- } from "bcp/cache";
271
-
272
- export const cache =
273
- createCacheStore({
274
- adapter:
275
- createRedisCacheAdapter({
276
- client: redisClient,
277
- }),
278
- lock:
279
- createRedisCacheLockAdapter({
280
- client: redisClient,
281
- }),
282
- });
208
+ const unregister =
209
+ deployment.registerShutdownHook();
283
210
  ```
284
211
 
285
- Distributed `getOrSet()` supports local singleflight, owner-scoped lock leases, heartbeat renewal, double-check-after-lock and contention wait/poll.
212
+ Read more: [Deployment Platform v2](docs/deployment-platform-v2.md)
286
213
 
287
- Read more: [Cache Platform v2](docs/cache-platform-v2.md)
214
+ ## Compiled production entrypoints
288
215
 
289
- ## Observability Platform v3 0.2.17
216
+ Prepared npm packages use compiled ESM for the main server runtime surfaces:
290
217
 
291
- `0.2.17` keeps the metrics/Prometheus/health APIs from Observability v2 and adds provider-neutral tracing and correlation.
218
+ ```text
219
+ bcp/cache -> cache.mjs
220
+ bcp/config -> config.mjs
221
+ bcp/database -> database.mjs
222
+ bcp/auth -> auth.mjs
223
+ bcp/jobs -> jobs.mjs
224
+ bcp/workflow -> workflow.mjs
225
+ bcp/events -> events.mjs
226
+ bcp/realtime -> realtime.mjs
227
+ bcp/testing -> testing.mjs
228
+ bcp/plugins -> plugins.mjs
229
+ bcp/observability -> observability.mjs
230
+ bcp/deployment -> deployment.mjs
231
+ bcp/server -> server.mjs
232
+ bcp/middleware -> middleware.mjs
233
+ ```
292
234
 
293
- Create a tracer:
235
+ TypeScript source remains the type surface, while prepared production runtime resolution points to compiled `.mjs` files.
236
+
237
+ ## Observability Platform v3 — 0.2.17
294
238
 
295
239
  ```ts
296
240
  import {
297
- createMemoryTraceSpanExporter,
298
241
  createTracer,
299
242
  } from "bcp/observability";
300
243
 
301
- const traces =
302
- createMemoryTraceSpanExporter();
303
-
304
244
  export const tracer =
305
245
  createTracer({
306
- exporter: traces,
307
- serviceName: "api",
246
+ serviceName: "orders-api",
308
247
  });
309
248
  ```
310
249
 
311
- Create root/child spans:
250
+ `bcp/observability` supports root/child spans, AsyncLocalStorage context, W3C `traceparent`, correlation IDs, request tracing, trace carriers, memory/composite exporters and trace-to-Prometheus metrics.
312
251
 
313
- ```ts
314
- await tracer.withSpan(
315
- "order.checkout",
316
- async () => {
317
- await tracer.withSpan(
318
- "database.order.insert",
319
- createOrder,
320
- {
321
- kind: "client",
322
- }
323
- );
324
- }
325
- );
326
- ```
327
-
328
- Tracing context flows through normal awaited async work via Node `AsyncLocalStorage`.
252
+ Read more: [Observability Platform v3](docs/observability-v3.md)
329
253
 
330
- ### HTTP tracing
254
+ ## Cache Platform v2 — 0.2.16
331
255
 
332
256
  ```ts
333
257
  import {
334
- createRequestTracingMiddleware,
335
- } from "bcp/observability";
336
-
337
- export const middleware =
338
- createRequestTracingMiddleware(
339
- tracer
340
- );
258
+ createCacheStore,
259
+ createRedisCacheAdapter,
260
+ createRedisCacheLockAdapter,
261
+ } from "bcp/cache";
341
262
  ```
342
263
 
343
- The middleware continues valid W3C `traceparent` headers, preserves `x-correlation-id`, creates a server span and returns current trace headers on the response.
264
+ Cache Store v2 supports local singleflight, distributed cache-fill leases, heartbeat renewal, TTL, tag/path invalidation and cache metrics while keeping the original `cache()` / `dedupe()` APIs available.
344
265
 
345
- ### Jobs / workflow / events / realtime propagation
266
+ Read more: [Cache Platform v2](docs/cache-platform-v2.md)
346
267
 
347
- ```ts
348
- import {
349
- createTraceCarrier,
350
- runWithTraceCarrier,
351
- } from "bcp/observability";
268
+ ## Plugin & Module Platform — 0.2.15
352
269
 
353
- const trace =
354
- createTraceCarrier();
270
+ `bcp/plugins` supports dependency ordering, setup/start/stop/dispose lifecycle, modules, config parsing, shared services and async hooks.
355
271
 
356
- await jobs.enqueue(
357
- "order.process",
358
- {
359
- orderId,
360
- trace,
361
- }
362
- );
363
- ```
272
+ Read more: [Plugin & Module Platform](docs/plugin-module-platform.md)
364
273
 
365
- Consumer:
274
+ ## Testing Platform — 0.2.14
366
275
 
367
- ```ts
368
- await runWithTraceCarrier(
369
- payload.trace,
370
- () =>
371
- tracer.withSpan(
372
- "job order.process",
373
- handler,
374
- {
375
- kind: "consumer",
376
- }
377
- )
378
- );
379
- ```
276
+ `bcp/testing` provides runner-neutral request/route/page/auth/database/middleware/jobs/workflow/outbox/realtime/SSE test helpers.
277
+
278
+ Read more: [Testing Platform](docs/testing-platform.md)
380
279
 
381
- The same carrier can be placed in workflow input, outbox/event metadata and realtime payloads when trace continuity is needed across those boundaries.
280
+ ## Realtime Platform 0.2.13
382
281
 
383
- ### Trace-to-metrics and logs
282
+ `bcp/realtime` provides channels/rooms, presence, broker delivery, provider-neutral socket adapters, SSE and heartbeat handling.
384
283
 
385
- ```ts
386
- import {
387
- createCompositeTraceSpanExporter,
388
- createMetricsRegistry,
389
- createTraceMetricsExporter,
390
- getTraceLogFields,
391
- } from "bcp/observability";
284
+ Read more: [Realtime Platform](docs/realtime-platform.md)
392
285
 
393
- const metrics =
394
- createMetricsRegistry();
395
-
396
- const exporter =
397
- createCompositeTraceSpanExporter([
398
- createTraceMetricsExporter(
399
- metrics
400
- ),
401
- productionTraceExporter,
402
- ]);
403
-
404
- logger.info(
405
- "order created",
406
- {
407
- ...getTraceLogFields(),
408
- orderId,
409
- }
410
- );
411
- ```
286
+ ## Transactional Outbox & Events — 0.2.12
287
+
288
+ Use `bcp/events` to persist integration events in the same SQL transaction as business data, then dispatch after commit through durable jobs or custom publishers.
412
289
 
413
- Default trace metrics use low-cardinality `kind` and `status` labels. Span-name labels are opt-in.
290
+ Read more: [Transactional Outbox & Events](docs/transactional-outbox-events.md)
414
291
 
415
- BCP does not install an OpenTelemetry SDK or vendor APM package; production exporters remain application-owned through `TraceSpanExporter`.
292
+ ## Workflow Orchestration 0.2.11
416
293
 
417
- Prepared npm packages compile `bcp/observability` to `observability.mjs` for standalone Node runtime use.
294
+ `bcp/workflow` supports sequential/parallel steps, retries, persisted delays, run leases, compensation and optional durable queue execution.
418
295
 
419
- Read more: [Observability Platform v3](docs/observability-v3.md)
296
+ Read more: [Workflow Orchestration](docs/workflow-orchestration.md)
420
297
 
421
298
  ## Public entrypoints
422
299
 
@@ -436,6 +313,7 @@ bcp/realtime
436
313
  bcp/testing
437
314
  bcp/plugins
438
315
  bcp/observability
316
+ bcp/deployment
439
317
  bcp/server
440
318
  bcp/server-only
441
319
  bcp/middleware
@@ -476,41 +354,23 @@ bcp generate middleware
476
354
  bcp generate migration create_users
477
355
  ```
478
356
 
479
- ## Production model
480
-
481
- ```text
482
- Browser / API / Realtime clients
483
- |
484
- tracing + security
485
- |
486
- Plugin Host
487
- / | \
488
- database workflows realtime
489
- | | ^
490
- outbox jobs |
491
- \__________|_________/
492
- durable state
493
- |
494
- shared cache layer
495
- |
496
- metrics + trace export
497
- ```
498
-
499
- Cache remains an optimization layer. Database/outbox/jobs/workflows remain the durable truth. Realtime remains transient delivery. Tracing correlates those operations without replacing their state contracts.
500
-
501
357
  ## Packaging
502
358
 
359
+ Build and run directly:
360
+
503
361
  ```bash
504
362
  npm run build
505
363
  npm start
506
364
  ```
507
365
 
508
- Deployment package:
366
+ Create a standalone deployment package:
509
367
 
510
368
  ```bash
511
369
  bcp package
512
370
  ```
513
371
 
372
+ Application packages include production dependency manifests, deployment/environment metadata, file integrity metadata and a Docker starter while excluding `.env` secrets and application devDependencies.
373
+
514
374
  ## Documentation Platform
515
375
 
516
376
  Machine-readable contracts:
@@ -523,7 +383,7 @@ docs/api-manifest.json
523
383
 
524
384
  ## Release validation
525
385
 
526
- Before publishing `0.2.17`:
386
+ Before publishing `0.2.18`:
527
387
 
528
388
  ```bash
529
389
  npm run typecheck
@@ -534,7 +394,7 @@ npm run test:package
534
394
  npm run rc:check
535
395
  ```
536
396
 
537
- `0.2.17` adds unit and prepared-package smoke coverage for root/child spans, async context propagation, W3C trace headers, correlation carriers, request tracing, error spans, trace metrics and compiled `observability.mjs` execution.
397
+ `0.2.18` adds unit and prepared-package smoke coverage for deployment lifecycle ordering, startup rollback, readiness/diagnostics, runtime metadata, server-only boundaries and compiled config/auth/observability/deployment/server/middleware runtimes.
538
398
 
539
399
  Do not tag or publish until the exact final release commit passes the full RC sequence.
540
400
 
@@ -566,14 +426,15 @@ Do not tag or publish until the exact final release commit passes the full RC se
566
426
  | `0.2.15` | Plugin & Module Platform |
567
427
  | `0.2.16` | Cache Platform v2 |
568
428
  | `0.2.17` | Observability Platform v3 |
429
+ | `0.2.18` | Deployment Platform v2 |
569
430
 
570
431
  ## Roadmap
571
432
 
572
- `0.2.17` establishes trace/correlation continuity across the current server platform without coupling BCP to a specific telemetry vendor.
433
+ `0.2.18` establishes a consistent production lifecycle and compiled server runtime boundary for the current BCP 0.2.x platform.
573
434
 
574
- The next logical milestone is **`0.2.18Deployment Platform v2`**, focused on completing compiled production entrypoints, deployment/runtime adapters, process lifecycle integration, container/runtime metadata and production diagnostics.
435
+ The next milestone is **`0.2.19Stability & API Freeze`**, focused on final API consistency, deprecation policy, performance/regression hardening, migration diagnostics and release-quality compatibility before `0.3.0`.
575
436
 
576
- `0.2.19` is planned as the stabilization/API-freeze pass before the next `0.3.0` platform baseline.
437
+ `0.3.0` is planned as the next BCP Application Platform baseline.
577
438
 
578
439
  Native desktop/mobile compilation remains later roadmap work.
579
440