create-bcp-app 0.2.15 → 0.2.17

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.
Files changed (3) hide show
  1. package/README.md +103 -121
  2. package/package.json +1 -1
  3. package/template/README.md +138 -45
package/README.md CHANGED
@@ -34,7 +34,6 @@ For direct PowerShell usage, prefer the collision-free local alias:
34
34
  npm exec -- bcp-framework --version
35
35
  npm exec -- bcp-framework doctor
36
36
  npm exec -- bcp-framework inspect
37
- npm exec -- bcp-framework generate page dashboard/users
38
37
  npm exec -- bcp-framework routes
39
38
  npm exec -- bcp-framework dev
40
39
  npm exec -- bcp-framework build
@@ -45,8 +44,6 @@ Microsoft SQL Server can install another Windows executable named `bcp.exe`, so
45
44
 
46
45
  ## Interactive choices
47
46
 
48
- The generator asks for optional application presets:
49
-
50
47
  ```text
51
48
  Use Tailwind CSS?
52
49
  Select a database:
@@ -69,17 +66,17 @@ Select storage provider:
69
66
 
70
67
  New projects include `bcp.project.json`.
71
68
 
72
- Example for the `0.2.15` target:
69
+ Example for the `0.2.17` target:
73
70
 
74
71
  ```json
75
72
  {
76
73
  "schemaVersion": 1,
77
74
  "framework": "bcp",
78
75
  "projectName": "my-app",
79
- "frameworkPackage": "npm:@chidchanun/bcp@0.2.15",
76
+ "frameworkPackage": "npm:@chidchanun/bcp@0.2.17",
80
77
  "createdWith": {
81
78
  "package": "create-bcp-app",
82
- "version": "0.2.15"
79
+ "version": "0.2.17"
83
80
  },
84
81
  "packageManager": "npm",
85
82
  "presets": {
@@ -109,15 +106,6 @@ For MySQL, PostgreSQL and SQLite, generated `lib/database.ts` exposes BCP databa
109
106
 
110
107
  The JWT Cookie preset creates `lib/auth.ts` and starter auth routes. BCP `0.2.5+` supports optional revocable server-side auth state, while `0.2.6+` adds permission/policy authorization plus same-origin/CSRF helpers.
111
108
 
112
- ## Observability
113
-
114
- ```ts
115
- import {
116
- createHealthRegistry,
117
- createMetricsRegistry,
118
- } from "bcp/observability";
119
- ```
120
-
121
109
  ## Background jobs and scheduling
122
110
 
123
111
  ```ts
@@ -160,12 +148,8 @@ export const onboarding =
160
148
  );
161
149
  ```
162
150
 
163
- `bcp/workflow` supports sequential/parallel steps, retry, persisted delays, compensation and optional execution through `bcp/jobs`.
164
-
165
151
  ## Transactional Outbox & Events — 0.2.12+
166
152
 
167
- Applications using the SQL Database Platform can persist integration events in the same transaction as business data:
168
-
169
153
  ```ts
170
154
  await db.transaction(
171
155
  async tx => {
@@ -184,12 +168,8 @@ await db.transaction(
184
168
  );
185
169
  ```
186
170
 
187
- After commit, `createOutboxDispatcher()` can hand off events to durable jobs/custom publishers.
188
-
189
171
  ## Realtime Platform — 0.2.13+
190
172
 
191
- Generated applications can add server-side realtime channels without changing the scaffold preset model:
192
-
193
173
  ```ts
194
174
  import {
195
175
  createRealtime,
@@ -199,35 +179,10 @@ export const realtime =
199
179
  createRealtime();
200
180
  ```
201
181
 
202
- Channel/room usage:
203
-
204
- ```ts
205
- const connection =
206
- await realtime.connect();
207
-
208
- await connection.join(
209
- "orders:42"
210
- );
211
-
212
- await realtime.broadcast(
213
- "orders:42",
214
- "order.updated",
215
- {
216
- status: "paid",
217
- }
218
- );
219
- ```
220
-
221
182
  BCP does not install a WebSocket library. Adapt your selected provider to `RealtimeSocket`. SSE is available directly through `realtime.sse()`.
222
183
 
223
- The memory broker/presence store are local-only. Multi-instance production deployments should provide shared `RealtimeBroker` and `RealtimePresenceStore` implementations.
224
-
225
184
  ## Testing Platform — 0.2.14+
226
185
 
227
- `bcp/testing` adds framework-native test helpers without requiring a specific test runner.
228
-
229
- Request/route example:
230
-
231
186
  ```ts
232
187
  import {
233
188
  createRouteTestHandler,
@@ -256,72 +211,13 @@ await expectResponse(
256
211
  });
257
212
  ```
258
213
 
259
- Create a real signed BCP auth session for authenticated requests:
260
-
261
- ```ts
262
- import {
263
- createTestAuthSession,
264
- } from "bcp/testing";
265
-
266
- const session =
267
- await createTestAuthSession(
268
- {
269
- id: 42,
270
- role: "admin",
271
- },
272
- {
273
- secret:
274
- process.env.BCP_SESSION_SECRET,
275
- }
276
- );
277
-
278
- app.setCookie(
279
- session.cookieName,
280
- session.token
281
- );
282
- ```
283
-
284
- Rollback database tests:
285
-
286
- ```ts
287
- import {
288
- withTestTransaction,
289
- } from "bcp/testing";
290
-
291
- await withTestTransaction(
292
- db,
293
- async tx => {
294
- await tx.execute(
295
- "INSERT INTO users ..."
296
- );
297
- }
298
- );
299
- ```
300
-
301
- Infrastructure helpers include:
302
-
303
- ```text
304
- createJobTestHarness()
305
- createWorkflowTestHarness()
306
- createOutboxTestHarness()
307
- createRealtimeTestSocket()
308
- createRealtimeTestHarness()
309
- readSseEvents()
310
- createFakeClock()
311
- createSequenceIdFactory()
312
- runTestMiddleware()
313
- ```
314
-
315
- `bcp/testing` is server-only. It can be used with Node `node:test`, Vitest, Jest or another runner; BCP does not install those runners as framework dependencies.
214
+ BCP testing helpers are runner-neutral and can be used with Node `node:test`, Vitest, Jest or another runner.
316
215
 
317
216
  ## Plugin & Module Platform — 0.2.15+
318
217
 
319
- Use `bcp/plugins` to compose reusable server-side application modules with explicit lifecycle and dependencies.
320
-
321
218
  ```ts
322
219
  import {
323
220
  createPluginHost,
324
- defineModule,
325
221
  definePlugin,
326
222
  } from "bcp/plugins";
327
223
 
@@ -344,28 +240,114 @@ const jobsPlugin =
344
240
  ],
345
241
  });
346
242
 
347
- const backendModule =
348
- defineModule({
349
- name: "backend",
243
+ export const plugins =
244
+ createPluginHost({
350
245
  plugins: [
351
- databasePlugin,
352
246
  jobsPlugin,
247
+ databasePlugin,
353
248
  ],
354
249
  });
250
+ ```
355
251
 
356
- const host =
357
- createPluginHost({
358
- modules: [
359
- backendModule,
360
- ],
252
+ ## Cache Platform v2 — 0.2.16+
253
+
254
+ ```ts
255
+ import {
256
+ createCacheStore,
257
+ createRedisCacheAdapter,
258
+ createRedisCacheLockAdapter,
259
+ } from "bcp/cache";
260
+
261
+ export const cache =
262
+ createCacheStore({
263
+ adapter:
264
+ createRedisCacheAdapter({
265
+ client: redisClient,
266
+ }),
267
+ lock:
268
+ createRedisCacheLockAdapter({
269
+ client: redisClient,
270
+ }),
361
271
  });
272
+ ```
273
+
274
+ BCP does not install or own the Redis client. Applications remain responsible for credentials, TLS, Cluster/Sentinel configuration, reconnect behavior and connection shutdown.
362
275
 
363
- await host.start();
276
+ ## Observability Platform v3 — 0.2.17+
277
+
278
+ Metrics and health remain available through the same entrypoint:
279
+
280
+ ```ts
281
+ import {
282
+ createHealthRegistry,
283
+ createMetricsRegistry,
284
+ createTracer,
285
+ } from "bcp/observability";
286
+ ```
287
+
288
+ Create a tracer:
289
+
290
+ ```ts
291
+ export const tracer =
292
+ createTracer({
293
+ serviceName: "my-app",
294
+ });
295
+ ```
296
+
297
+ Trace incoming HTTP requests with Middleware System v2:
298
+
299
+ ```ts
300
+ import {
301
+ createRequestTracingMiddleware,
302
+ } from "bcp/observability";
303
+
304
+ export const middleware =
305
+ createRequestTracingMiddleware(
306
+ tracer
307
+ );
308
+ ```
309
+
310
+ The middleware understands W3C `traceparent`, preserves `x-correlation-id`, creates a server span and returns the current trace headers on the response.
311
+
312
+ For jobs/workflows/events/realtime payloads use explicit trace carriers:
313
+
314
+ ```ts
315
+ import {
316
+ createTraceCarrier,
317
+ runWithTraceCarrier,
318
+ } from "bcp/observability";
319
+
320
+ const trace =
321
+ createTraceCarrier();
322
+
323
+ await jobs.enqueue(
324
+ "order.process",
325
+ {
326
+ orderId,
327
+ trace,
328
+ }
329
+ );
330
+ ```
331
+
332
+ Consumer:
333
+
334
+ ```ts
335
+ await runWithTraceCarrier(
336
+ payload.trace,
337
+ () =>
338
+ tracer.withSpan(
339
+ "job order.process",
340
+ handler,
341
+ {
342
+ kind: "consumer",
343
+ }
344
+ )
345
+ );
364
346
  ```
365
347
 
366
- Plugins can use `setup/start/stop/dispose`, typed config parsers, a shared service registry and an awaited in-process hook bus. Required dependencies start first; shutdown runs in reverse order.
348
+ Use `getTraceLogFields()` to add `traceId`, `spanId` and `correlationId` to structured logs.
367
349
 
368
- `bcp/plugins` is server-only and cannot be imported into page/client bundles.
350
+ BCP does not install OpenTelemetry or a vendor APM package. Implement `TraceSpanExporter` when production spans need to be sent to an external collector.
369
351
 
370
352
  ## Storage providers
371
353
 
@@ -405,5 +387,5 @@ npm run generate -- migration create_users
405
387
  For prerelease/local package verification:
406
388
 
407
389
  ```bash
408
- npx create-bcp-app my-app --bcp file:../chidchanun-bcp-0.2.15.tgz
390
+ npx create-bcp-app my-app --bcp file:../chidchanun-bcp-0.2.17.tgz
409
391
  ```
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-bcp-app",
3
- "version": "0.2.15",
3
+ "version": "0.2.17",
4
4
  "description": "Create a new BCP Framework application.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -199,49 +199,6 @@ await expectResponse(
199
199
  });
200
200
  ```
201
201
 
202
- Authentication tests can create a real signed BCP session:
203
-
204
- ```ts
205
- import {
206
- createTestAuthSession,
207
- } from "bcp/testing";
208
-
209
- const session =
210
- await createTestAuthSession(
211
- {
212
- id: 42,
213
- },
214
- {
215
- secret:
216
- process.env.BCP_SESSION_SECRET,
217
- }
218
- );
219
-
220
- app.setCookie(
221
- session.cookieName,
222
- session.token
223
- );
224
- ```
225
-
226
- Database tests can force rollback after assertions:
227
-
228
- ```ts
229
- import {
230
- withTestTransaction,
231
- } from "bcp/testing";
232
-
233
- await withTestTransaction(
234
- db,
235
- async tx => {
236
- await tx.execute(
237
- "INSERT INTO users ..."
238
- );
239
- }
240
- );
241
- ```
242
-
243
- Additional helpers include job/workflow/outbox harnesses, `runTestMiddleware()`, page loader/guard/action helpers, fake clocks and IDs, a fake `RealtimeSocket`, realtime event assertions and `readSseEvents()`.
244
-
245
202
  BCP does not require Jest or Vitest; these helpers work with Node `node:test` or another runner.
246
203
 
247
204
  ## Plugin & Module Platform — BCP 0.2.15+
@@ -284,9 +241,145 @@ export const plugins =
284
241
 
285
242
  Plugin startup follows dependency order and shutdown reverses it. Plugins can use `setup/start/stop/dispose`, config parsers, shared services and async hooks.
286
243
 
287
- Use `defineModule()` when a reusable package needs to bundle multiple plugin definitions into one named module.
244
+ ## Cache Platform v2 BCP 0.2.16+
245
+
246
+ Use `createCacheStore()` for async cache-aside loading, shared adapters and distributed cache-fill coordination.
247
+
248
+ ```ts
249
+ import {
250
+ createCacheStore,
251
+ } from "bcp/cache";
252
+
253
+ export const cache =
254
+ createCacheStore();
255
+ ```
256
+
257
+ ```ts
258
+ const user =
259
+ await cache.getOrSet(
260
+ "user:42",
261
+ () => loadUser(42),
262
+ {
263
+ ttlMs: 60_000,
264
+ tags: ["users"],
265
+ paths: ["/users/42"],
266
+ }
267
+ );
268
+ ```
269
+
270
+ For multiple instances, connect a shared cache and lock provider:
271
+
272
+ ```ts
273
+ import {
274
+ createRedisCacheAdapter,
275
+ createRedisCacheLockAdapter,
276
+ } from "bcp/cache";
277
+
278
+ const redisCache =
279
+ createRedisCacheAdapter({
280
+ client: redisClient,
281
+ });
282
+
283
+ const redisLock =
284
+ createRedisCacheLockAdapter({
285
+ client: redisClient,
286
+ });
287
+
288
+ export const cache =
289
+ createCacheStore({
290
+ adapter: redisCache,
291
+ lock: redisLock,
292
+ });
293
+ ```
294
+
295
+ BCP does not install or own a Redis client. The default adapter namespace is `bcp:{cache}`. The original `cache()` and `dedupe()` APIs remain available for backward-compatible process-local caching.
296
+
297
+ ## Observability Platform v3 — BCP 0.2.17+
298
+
299
+ Use the existing `bcp/observability` entrypoint for tracing as well as metrics and health.
300
+
301
+ ```ts
302
+ import {
303
+ createTracer,
304
+ } from "bcp/observability";
305
+
306
+ export const tracer =
307
+ createTracer({
308
+ serviceName: "my-app",
309
+ });
310
+ ```
311
+
312
+ Trace incoming Middleware System v2 requests:
313
+
314
+ ```ts
315
+ import {
316
+ createRequestTracingMiddleware,
317
+ } from "bcp/observability";
318
+
319
+ export const middleware =
320
+ createRequestTracingMiddleware(
321
+ tracer
322
+ );
323
+ ```
324
+
325
+ The middleware continues valid W3C `traceparent` headers, preserves `x-correlation-id`, creates a server span and includes active trace headers in the response.
326
+
327
+ Create child spans for application work:
328
+
329
+ ```ts
330
+ await tracer.withSpan(
331
+ "order.checkout",
332
+ async () => {
333
+ await tracer.withSpan(
334
+ "database.order.insert",
335
+ createOrder,
336
+ {
337
+ kind: "client",
338
+ }
339
+ );
340
+ }
341
+ );
342
+ ```
343
+
344
+ For jobs, workflows, events and realtime payloads, propagate context explicitly:
345
+
346
+ ```ts
347
+ import {
348
+ createTraceCarrier,
349
+ runWithTraceCarrier,
350
+ } from "bcp/observability";
351
+
352
+ const trace =
353
+ createTraceCarrier();
354
+
355
+ await jobs.enqueue(
356
+ "order.process",
357
+ {
358
+ orderId,
359
+ trace,
360
+ }
361
+ );
362
+ ```
363
+
364
+ Consumer:
365
+
366
+ ```ts
367
+ await runWithTraceCarrier(
368
+ payload.trace,
369
+ () =>
370
+ tracer.withSpan(
371
+ "job order.process",
372
+ handler,
373
+ {
374
+ kind: "consumer",
375
+ }
376
+ )
377
+ );
378
+ ```
379
+
380
+ Use `getTraceLogFields()` to attach `traceId`, `spanId` and `correlationId` to structured logs.
288
381
 
289
- `bcp/plugins` is server-only and cannot be imported from page/client bundles.
382
+ BCP does not install OpenTelemetry or a vendor APM SDK. Production collector integration is application-owned through `TraceSpanExporter`.
290
383
 
291
384
  ## Generate framework files
292
385