@chidchanun/bcp 0.2.16 → 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 +150 -408
- package/docs/README.md +36 -38
- package/docs/api-manifest.json +27 -19
- package/docs/api-reference.md +257 -305
- package/docs/deployment-platform-v2.md +449 -0
- package/docs/docs-web-manifest.json +7 -3
- package/docs/observability-v3.md +402 -0
- package/docs/platform-manifest.json +30 -4
- package/docs/releases/0.2.17.md +166 -0
- package/docs/releases/0.2.18.md +136 -0
- package/package.json +11 -6
- 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/observability.mjs +1251 -0
- package/packages/client/src/observability.ts +37 -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
- package/packages/server/src/observability-v3.ts +878 -0
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.
|
|
5
|
+
> **Development target:** `0.2.18 — Deployment Platform v2`
|
|
6
6
|
>
|
|
7
|
-
> `0.2.
|
|
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 |
|
|
31
|
-
| Observability |
|
|
30
|
+
| Caching | Cache Platform v2 adapters, Redis-compatible cache/locks, stampede protection, TTL/tag/path invalidation and metrics |
|
|
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
|
|
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,468 +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
|
+
import { createTracer } from "bcp/observability";
|
|
83
|
+
import { createDeploymentRuntime } from "bcp/deployment";
|
|
82
84
|
```
|
|
83
85
|
|
|
84
|
-
## Durable
|
|
86
|
+
## Durable application infrastructure
|
|
85
87
|
|
|
86
|
-
|
|
87
|
-
import {
|
|
88
|
-
createJobQueue,
|
|
89
|
-
createJobScheduler,
|
|
90
|
-
} from "bcp/jobs";
|
|
88
|
+
BCP keeps durable application state separate from transient delivery:
|
|
91
89
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
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
|
|
99
106
|
```
|
|
100
107
|
|
|
101
|
-
|
|
108
|
+
Database/outbox/jobs/workflows remain durable truth. Realtime is transient delivery. Cache is an optimization layer. Tracing correlates operations without replacing state contracts.
|
|
102
109
|
|
|
103
|
-
##
|
|
110
|
+
## Deployment Platform v2 — 0.2.18
|
|
111
|
+
|
|
112
|
+
`0.2.18` adds the server-only `bcp/deployment` entrypoint.
|
|
104
113
|
|
|
105
114
|
```ts
|
|
106
115
|
import {
|
|
107
|
-
|
|
108
|
-
} from "bcp/
|
|
109
|
-
|
|
110
|
-
export const onboarding =
|
|
111
|
-
createWorkflow<{
|
|
112
|
-
userId: number;
|
|
113
|
-
}>(
|
|
114
|
-
"user.onboarding",
|
|
115
|
-
workflow => {
|
|
116
|
-
workflow.step(
|
|
117
|
-
"profile",
|
|
118
|
-
createProfile
|
|
119
|
-
);
|
|
120
|
-
|
|
121
|
-
workflow.parallel(
|
|
122
|
-
"initialize",
|
|
123
|
-
parallel => {
|
|
124
|
-
parallel.step(
|
|
125
|
-
"preferences",
|
|
126
|
-
createPreferences
|
|
127
|
-
);
|
|
128
|
-
parallel.step(
|
|
129
|
-
"workspace",
|
|
130
|
-
createWorkspace
|
|
131
|
-
);
|
|
132
|
-
}
|
|
133
|
-
);
|
|
134
|
-
|
|
135
|
-
workflow.delay(
|
|
136
|
-
"cooldown",
|
|
137
|
-
1_000
|
|
138
|
-
);
|
|
139
|
-
}
|
|
140
|
-
);
|
|
141
|
-
```
|
|
116
|
+
createDeploymentRuntime,
|
|
117
|
+
} from "bcp/deployment";
|
|
142
118
|
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
119
|
+
export const deployment =
|
|
120
|
+
createDeploymentRuntime({
|
|
121
|
+
serviceName: "orders-api",
|
|
122
|
+
version: "1.0.0",
|
|
123
|
+
});
|
|
124
|
+
```
|
|
146
125
|
|
|
147
|
-
|
|
126
|
+
Register resources in dependency order:
|
|
148
127
|
|
|
149
128
|
```ts
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
await tx.execute(
|
|
153
|
-
"INSERT INTO orders ..."
|
|
154
|
-
);
|
|
155
|
-
|
|
156
|
-
await outbox.publish(
|
|
157
|
-
tx,
|
|
158
|
-
"order.created",
|
|
159
|
-
{
|
|
160
|
-
orderId: 42,
|
|
161
|
-
}
|
|
162
|
-
);
|
|
163
|
-
}
|
|
164
|
-
);
|
|
165
|
-
```
|
|
129
|
+
deployment.addResource({
|
|
130
|
+
name: "database",
|
|
166
131
|
|
|
167
|
-
|
|
132
|
+
async start() {
|
|
133
|
+
await db.connect();
|
|
134
|
+
},
|
|
168
135
|
|
|
169
|
-
|
|
136
|
+
async ready() {
|
|
137
|
+
return db.status === "ready";
|
|
138
|
+
},
|
|
170
139
|
|
|
171
|
-
|
|
140
|
+
async stop() {
|
|
141
|
+
await db.close();
|
|
142
|
+
},
|
|
143
|
+
});
|
|
172
144
|
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
createRealtime,
|
|
176
|
-
} from "bcp/realtime";
|
|
145
|
+
deployment.addResource({
|
|
146
|
+
name: "workers",
|
|
177
147
|
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
148
|
+
start() {
|
|
149
|
+
worker = jobs.startWorker();
|
|
150
|
+
},
|
|
181
151
|
|
|
182
|
-
|
|
152
|
+
async stop() {
|
|
153
|
+
await worker.stop();
|
|
154
|
+
},
|
|
155
|
+
});
|
|
183
156
|
|
|
184
|
-
|
|
185
|
-
const connection =
|
|
186
|
-
await realtime.connect();
|
|
187
|
-
|
|
188
|
-
await connection.join(
|
|
189
|
-
"orders:42"
|
|
190
|
-
);
|
|
191
|
-
|
|
192
|
-
await realtime.broadcast(
|
|
193
|
-
"orders:42",
|
|
194
|
-
"order.updated",
|
|
195
|
-
{
|
|
196
|
-
status: "paid",
|
|
197
|
-
}
|
|
198
|
-
);
|
|
157
|
+
await deployment.start();
|
|
199
158
|
```
|
|
200
159
|
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
Read more: [Realtime Platform](docs/realtime-platform.md)
|
|
204
|
-
|
|
205
|
-
## Testing Platform — 0.2.14
|
|
206
|
-
|
|
207
|
-
`0.2.14` adds the server-only `bcp/testing` entrypoint. It is test-runner neutral and does not add Jest or Vitest as framework dependencies.
|
|
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.
|
|
208
161
|
|
|
209
|
-
|
|
162
|
+
Readiness:
|
|
210
163
|
|
|
211
164
|
```ts
|
|
212
165
|
import {
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
expectResponse,
|
|
216
|
-
} from "bcp/testing";
|
|
217
|
-
|
|
218
|
-
const handler =
|
|
219
|
-
createRouteTestHandler({
|
|
220
|
-
GET() {
|
|
221
|
-
return {
|
|
222
|
-
ok: true,
|
|
223
|
-
};
|
|
224
|
-
},
|
|
225
|
-
});
|
|
226
|
-
|
|
227
|
-
const app =
|
|
228
|
-
createTestApp({
|
|
229
|
-
handler,
|
|
230
|
-
});
|
|
166
|
+
createDeploymentReadinessResponse,
|
|
167
|
+
} from "bcp/deployment";
|
|
231
168
|
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
169
|
+
export function GET() {
|
|
170
|
+
return createDeploymentReadinessResponse(
|
|
171
|
+
deployment
|
|
235
172
|
);
|
|
236
|
-
|
|
237
|
-
await expectResponse(response)
|
|
238
|
-
.status(200)
|
|
239
|
-
.json({
|
|
240
|
-
ok: true,
|
|
241
|
-
});
|
|
173
|
+
}
|
|
242
174
|
```
|
|
243
175
|
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
### Authentication tests
|
|
176
|
+
A ready runtime returns `200`; starting, draining, failed or unhealthy runtimes return `503`.
|
|
247
177
|
|
|
248
|
-
|
|
178
|
+
Diagnostics:
|
|
249
179
|
|
|
250
180
|
```ts
|
|
251
181
|
import {
|
|
252
|
-
|
|
253
|
-
} from "bcp/
|
|
254
|
-
|
|
255
|
-
const session =
|
|
256
|
-
await createTestAuthSession(
|
|
257
|
-
{
|
|
258
|
-
id: 42,
|
|
259
|
-
role: "admin",
|
|
260
|
-
},
|
|
261
|
-
{
|
|
262
|
-
secret:
|
|
263
|
-
process.env.BCP_SESSION_SECRET,
|
|
264
|
-
store:
|
|
265
|
-
authSessionStore,
|
|
266
|
-
}
|
|
267
|
-
);
|
|
268
|
-
|
|
269
|
-
app.setCookie(
|
|
270
|
-
session.cookieName,
|
|
271
|
-
session.token
|
|
272
|
-
);
|
|
182
|
+
createDeploymentDiagnosticsResponse,
|
|
183
|
+
} from "bcp/deployment";
|
|
273
184
|
```
|
|
274
185
|
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
### Rollback database tests
|
|
186
|
+
Deployment metadata can use:
|
|
278
187
|
|
|
279
|
-
```
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
db,
|
|
286
|
-
async tx => {
|
|
287
|
-
await tx.execute(
|
|
288
|
-
"INSERT INTO users ..."
|
|
289
|
-
);
|
|
290
|
-
|
|
291
|
-
// assertions run here
|
|
292
|
-
}
|
|
293
|
-
);
|
|
188
|
+
```text
|
|
189
|
+
BCP_DEPLOYMENT_ID
|
|
190
|
+
BCP_INSTANCE_ID
|
|
191
|
+
BCP_RELEASE
|
|
192
|
+
NODE_ENV
|
|
193
|
+
BCP_SHUTDOWN_TIMEOUT_MS
|
|
294
194
|
```
|
|
295
195
|
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
### Infrastructure harnesses
|
|
196
|
+
Signal ownership is optional:
|
|
299
197
|
|
|
300
198
|
```ts
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
createOutboxTestHarness,
|
|
304
|
-
createRealtimeTestHarness,
|
|
305
|
-
createWorkflowTestHarness,
|
|
306
|
-
} from "bcp/testing";
|
|
199
|
+
const removeSignalHandlers =
|
|
200
|
+
deployment.installSignalHandlers();
|
|
307
201
|
```
|
|
308
202
|
|
|
309
|
-
|
|
203
|
+
Default signals are `SIGTERM` and `SIGINT`. BCP sets `process.exitCode` after graceful shutdown instead of immediately terminating the process.
|
|
310
204
|
|
|
311
|
-
|
|
205
|
+
The runtime can also integrate with the existing framework shutdown registry:
|
|
312
206
|
|
|
313
207
|
```ts
|
|
314
|
-
const
|
|
315
|
-
|
|
316
|
-
jobs
|
|
317
|
-
);
|
|
318
|
-
|
|
319
|
-
await jobTest.drain();
|
|
320
|
-
|
|
321
|
-
await jobTest.expectCount(
|
|
322
|
-
1,
|
|
323
|
-
{
|
|
324
|
-
name: "email.welcome",
|
|
325
|
-
state: "succeeded",
|
|
326
|
-
}
|
|
327
|
-
);
|
|
208
|
+
const unregister =
|
|
209
|
+
deployment.registerShutdownHook();
|
|
328
210
|
```
|
|
329
211
|
|
|
330
|
-
|
|
212
|
+
Read more: [Deployment Platform v2](docs/deployment-platform-v2.md)
|
|
331
213
|
|
|
332
|
-
|
|
333
|
-
const realtimeTest =
|
|
334
|
-
createRealtimeTestHarness(
|
|
335
|
-
realtime
|
|
336
|
-
);
|
|
214
|
+
## Compiled production entrypoints
|
|
337
215
|
|
|
338
|
-
|
|
339
|
-
socket,
|
|
340
|
-
connection,
|
|
341
|
-
} =
|
|
342
|
-
await realtimeTest.connect();
|
|
343
|
-
|
|
344
|
-
await connection.join(
|
|
345
|
-
"orders:42"
|
|
346
|
-
);
|
|
347
|
-
|
|
348
|
-
await realtime.broadcast(
|
|
349
|
-
"orders:42",
|
|
350
|
-
"order.updated",
|
|
351
|
-
{
|
|
352
|
-
status: "paid",
|
|
353
|
-
}
|
|
354
|
-
);
|
|
355
|
-
|
|
356
|
-
realtimeTest.expectEvent(
|
|
357
|
-
socket,
|
|
358
|
-
"order.updated",
|
|
359
|
-
"orders:42"
|
|
360
|
-
);
|
|
361
|
-
```
|
|
362
|
-
|
|
363
|
-
Other testing primitives include:
|
|
216
|
+
Prepared npm packages use compiled ESM for the main server runtime surfaces:
|
|
364
217
|
|
|
365
218
|
```text
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
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
|
+
```
|
|
234
|
+
|
|
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
|
|
380
238
|
|
|
381
239
|
```ts
|
|
382
240
|
import {
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
} from "bcp/plugins";
|
|
386
|
-
|
|
387
|
-
const databasePlugin =
|
|
388
|
-
definePlugin({
|
|
389
|
-
name: "database",
|
|
390
|
-
setup(context) {
|
|
391
|
-
context.services.provide(
|
|
392
|
-
"database",
|
|
393
|
-
db
|
|
394
|
-
);
|
|
395
|
-
},
|
|
396
|
-
start() {
|
|
397
|
-
return db.connect();
|
|
398
|
-
},
|
|
399
|
-
stop() {
|
|
400
|
-
return db.disconnect();
|
|
401
|
-
},
|
|
402
|
-
});
|
|
241
|
+
createTracer,
|
|
242
|
+
} from "bcp/observability";
|
|
403
243
|
|
|
404
|
-
const
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
requires: [
|
|
408
|
-
"database",
|
|
409
|
-
],
|
|
410
|
-
});
|
|
411
|
-
|
|
412
|
-
const host =
|
|
413
|
-
createPluginHost({
|
|
414
|
-
plugins: [
|
|
415
|
-
jobsPlugin,
|
|
416
|
-
databasePlugin,
|
|
417
|
-
],
|
|
418
|
-
});
|
|
419
|
-
|
|
420
|
-
await host.start();
|
|
421
|
-
```
|
|
422
|
-
|
|
423
|
-
Dependency order is resolved automatically. Startup follows dependency order while stop/dispose runs in reverse order.
|
|
424
|
-
|
|
425
|
-
Modules group reusable plugin sets:
|
|
426
|
-
|
|
427
|
-
```ts
|
|
428
|
-
import {
|
|
429
|
-
defineModule,
|
|
430
|
-
} from "bcp/plugins";
|
|
431
|
-
|
|
432
|
-
const backendModule =
|
|
433
|
-
defineModule({
|
|
434
|
-
name: "backend",
|
|
435
|
-
plugins: [
|
|
436
|
-
databasePlugin,
|
|
437
|
-
jobsPlugin,
|
|
438
|
-
],
|
|
244
|
+
export const tracer =
|
|
245
|
+
createTracer({
|
|
246
|
+
serviceName: "orders-api",
|
|
439
247
|
});
|
|
440
248
|
```
|
|
441
249
|
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
Plugins share a service registry and awaited in-process hook bus through `context.services` and `context.hooks`.
|
|
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.
|
|
445
251
|
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
Read more: [Plugin & Module Platform](docs/plugin-module-platform.md)
|
|
252
|
+
Read more: [Observability Platform v3](docs/observability-v3.md)
|
|
449
253
|
|
|
450
254
|
## Cache Platform v2 — 0.2.16
|
|
451
255
|
|
|
452
|
-
`0.2.16` keeps the original `cache()` and `dedupe()` APIs while adding provider-neutral asynchronous cache stores for production multi-instance applications.
|
|
453
|
-
|
|
454
|
-
Create a cache store:
|
|
455
|
-
|
|
456
256
|
```ts
|
|
457
257
|
import {
|
|
458
258
|
createCacheStore,
|
|
259
|
+
createRedisCacheAdapter,
|
|
260
|
+
createRedisCacheLockAdapter,
|
|
459
261
|
} from "bcp/cache";
|
|
460
|
-
|
|
461
|
-
export const applicationCache =
|
|
462
|
-
createCacheStore();
|
|
463
262
|
```
|
|
464
263
|
|
|
465
|
-
Cache-
|
|
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.
|
|
466
265
|
|
|
467
|
-
|
|
468
|
-
const user =
|
|
469
|
-
await applicationCache.getOrSet(
|
|
470
|
-
"user:42",
|
|
471
|
-
async () =>
|
|
472
|
-
loadUser(42),
|
|
473
|
-
{
|
|
474
|
-
ttlMs: 60_000,
|
|
475
|
-
tags: [
|
|
476
|
-
"users",
|
|
477
|
-
],
|
|
478
|
-
paths: [
|
|
479
|
-
"/users/42",
|
|
480
|
-
],
|
|
481
|
-
}
|
|
482
|
-
);
|
|
483
|
-
```
|
|
266
|
+
Read more: [Cache Platform v2](docs/cache-platform-v2.md)
|
|
484
267
|
|
|
485
|
-
|
|
268
|
+
## Plugin & Module Platform — 0.2.15
|
|
486
269
|
|
|
487
|
-
|
|
270
|
+
`bcp/plugins` supports dependency ordering, setup/start/stop/dispose lifecycle, modules, config parsing, shared services and async hooks.
|
|
488
271
|
|
|
489
|
-
|
|
490
|
-
import {
|
|
491
|
-
createRedisCacheAdapter,
|
|
492
|
-
createRedisCacheLockAdapter,
|
|
493
|
-
} from "bcp/cache";
|
|
272
|
+
Read more: [Plugin & Module Platform](docs/plugin-module-platform.md)
|
|
494
273
|
|
|
495
|
-
|
|
496
|
-
createRedisCacheAdapter({
|
|
497
|
-
client: redisClient,
|
|
498
|
-
});
|
|
274
|
+
## Testing Platform — 0.2.14
|
|
499
275
|
|
|
500
|
-
|
|
501
|
-
createRedisCacheLockAdapter({
|
|
502
|
-
client: redisClient,
|
|
503
|
-
});
|
|
276
|
+
`bcp/testing` provides runner-neutral request/route/page/auth/database/middleware/jobs/workflow/outbox/realtime/SSE test helpers.
|
|
504
277
|
|
|
505
|
-
|
|
506
|
-
createCacheStore({
|
|
507
|
-
adapter: redisCache,
|
|
508
|
-
lock: redisLock,
|
|
509
|
-
});
|
|
510
|
-
```
|
|
278
|
+
Read more: [Testing Platform](docs/testing-platform.md)
|
|
511
279
|
|
|
512
|
-
|
|
280
|
+
## Realtime Platform — 0.2.13
|
|
513
281
|
|
|
514
|
-
|
|
282
|
+
`bcp/realtime` provides channels/rooms, presence, broker delivery, provider-neutral socket adapters, SSE and heartbeat handling.
|
|
515
283
|
|
|
516
|
-
|
|
284
|
+
Read more: [Realtime Platform](docs/realtime-platform.md)
|
|
517
285
|
|
|
518
|
-
|
|
519
|
-
await cache.revalidateTag(
|
|
520
|
-
"users"
|
|
521
|
-
);
|
|
286
|
+
## Transactional Outbox & Events — 0.2.12
|
|
522
287
|
|
|
523
|
-
|
|
524
|
-
"/dashboard"
|
|
525
|
-
);
|
|
526
|
-
```
|
|
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.
|
|
527
289
|
|
|
528
|
-
|
|
290
|
+
Read more: [Transactional Outbox & Events](docs/transactional-outbox-events.md)
|
|
529
291
|
|
|
530
|
-
|
|
531
|
-
const cache =
|
|
532
|
-
createCacheStore({
|
|
533
|
-
metrics:
|
|
534
|
-
createCacheMetrics(
|
|
535
|
-
metricsRegistry
|
|
536
|
-
),
|
|
537
|
-
});
|
|
538
|
-
```
|
|
292
|
+
## Workflow Orchestration — 0.2.11
|
|
539
293
|
|
|
540
|
-
|
|
294
|
+
`bcp/workflow` supports sequential/parallel steps, retries, persisted delays, run leases, compensation and optional durable queue execution.
|
|
541
295
|
|
|
542
|
-
Read more: [
|
|
296
|
+
Read more: [Workflow Orchestration](docs/workflow-orchestration.md)
|
|
543
297
|
|
|
544
298
|
## Public entrypoints
|
|
545
299
|
|
|
@@ -559,6 +313,7 @@ bcp/realtime
|
|
|
559
313
|
bcp/testing
|
|
560
314
|
bcp/plugins
|
|
561
315
|
bcp/observability
|
|
316
|
+
bcp/deployment
|
|
562
317
|
bcp/server
|
|
563
318
|
bcp/server-only
|
|
564
319
|
bcp/middleware
|
|
@@ -599,40 +354,23 @@ bcp generate middleware
|
|
|
599
354
|
bcp generate migration create_users
|
|
600
355
|
```
|
|
601
356
|
|
|
602
|
-
## Production model
|
|
603
|
-
|
|
604
|
-
```text
|
|
605
|
-
Browser / API / Realtime clients
|
|
606
|
-
|
|
|
607
|
-
security + auth
|
|
608
|
-
|
|
|
609
|
-
Plugin Host
|
|
610
|
-
/ | \
|
|
611
|
-
database workflows realtime
|
|
612
|
-
| | ^
|
|
613
|
-
outbox jobs |
|
|
614
|
-
\__________|_________/
|
|
615
|
-
durable state
|
|
616
|
-
|
|
|
617
|
-
shared cache layer
|
|
618
|
-
Redis / other
|
|
619
|
-
```
|
|
620
|
-
|
|
621
|
-
Cache is an optimization layer and must not replace durable application truth or transactional invariants.
|
|
622
|
-
|
|
623
357
|
## Packaging
|
|
624
358
|
|
|
359
|
+
Build and run directly:
|
|
360
|
+
|
|
625
361
|
```bash
|
|
626
362
|
npm run build
|
|
627
363
|
npm start
|
|
628
364
|
```
|
|
629
365
|
|
|
630
|
-
|
|
366
|
+
Create a standalone deployment package:
|
|
631
367
|
|
|
632
368
|
```bash
|
|
633
369
|
bcp package
|
|
634
370
|
```
|
|
635
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
|
+
|
|
636
374
|
## Documentation Platform
|
|
637
375
|
|
|
638
376
|
Machine-readable contracts:
|
|
@@ -645,7 +383,7 @@ docs/api-manifest.json
|
|
|
645
383
|
|
|
646
384
|
## Release validation
|
|
647
385
|
|
|
648
|
-
Before publishing `0.2.
|
|
386
|
+
Before publishing `0.2.18`:
|
|
649
387
|
|
|
650
388
|
```bash
|
|
651
389
|
npm run typecheck
|
|
@@ -656,7 +394,7 @@ npm run test:package
|
|
|
656
394
|
npm run rc:check
|
|
657
395
|
```
|
|
658
396
|
|
|
659
|
-
`0.2.
|
|
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.
|
|
660
398
|
|
|
661
399
|
Do not tag or publish until the exact final release commit passes the full RC sequence.
|
|
662
400
|
|
|
@@ -687,12 +425,16 @@ Do not tag or publish until the exact final release commit passes the full RC se
|
|
|
687
425
|
| `0.2.14` | Testing Platform |
|
|
688
426
|
| `0.2.15` | Plugin & Module Platform |
|
|
689
427
|
| `0.2.16` | Cache Platform v2 |
|
|
428
|
+
| `0.2.17` | Observability Platform v3 |
|
|
429
|
+
| `0.2.18` | Deployment Platform v2 |
|
|
690
430
|
|
|
691
431
|
## Roadmap
|
|
692
432
|
|
|
693
|
-
`0.2.
|
|
433
|
+
`0.2.18` establishes a consistent production lifecycle and compiled server runtime boundary for the current BCP 0.2.x platform.
|
|
434
|
+
|
|
435
|
+
The next milestone is **`0.2.19 — Stability & API Freeze`**, focused on final API consistency, deprecation policy, performance/regression hardening, migration diagnostics and release-quality compatibility before `0.3.0`.
|
|
694
436
|
|
|
695
|
-
|
|
437
|
+
`0.3.0` is planned as the next BCP Application Platform baseline.
|
|
696
438
|
|
|
697
439
|
Native desktop/mobile compilation remains later roadmap work.
|
|
698
440
|
|