@chidchanun/bcp 0.2.18 → 0.3.0

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.
@@ -37,15 +37,15 @@ createCacheMetrics
37
37
 
38
38
  Public contracts include `CacheAdapter`, `CacheLockAdapter`, `CacheStore`, cache statistics/options and Redis command-client adapter types.
39
39
 
40
- Related guides: [Caching](caching.md), [Cache Platform v2](cache-platform-v2.md).
40
+ Related guides: [Caching](caching.md), [Cache Platform v2](cache-platform-v2.md), [Application Platform](application-platform.md).
41
41
 
42
42
  ## `bcp/config`
43
43
 
44
44
  Typed BCP configuration, environment-schema validation and diagnostics APIs.
45
45
 
46
- Prepared npm packages resolve the production runtime to compiled `config.mjs` in `0.2.18+`.
46
+ Prepared npm packages resolve the production runtime to compiled `config.mjs`.
47
47
 
48
- Related guides: [Configuration](configuration.md), [Environment Validation](environment-validation.md), [Deployment Platform v2](deployment-platform-v2.md).
48
+ Related guides: [Configuration](configuration.md), [Environment Validation](environment-validation.md), [Application Platform](application-platform.md).
49
49
 
50
50
  ## `bcp/validation`
51
51
 
@@ -61,7 +61,7 @@ Server-only provider-neutral SQL APIs for MySQL, PostgreSQL and SQLite.
61
61
 
62
62
  Core capabilities include query/execute, transactions, lifecycle and migrations.
63
63
 
64
- Related guides: [Database](database.md), [Database Migrations](database-migrations.md), [Transactional Outbox & Events](transactional-outbox-events.md).
64
+ Related guides: [Database](database.md), [Database Migrations](database-migrations.md), [Transactional Outbox & Events](transactional-outbox-events.md), [Application Platform](application-platform.md).
65
65
 
66
66
  ## `bcp/auth`
67
67
 
@@ -69,7 +69,7 @@ Server-only Authentication Platform v2 and Authorization & Security v2 APIs.
69
69
 
70
70
  Capabilities include JWT-cookie sessions, optional server-side session stores, revocation, logout-all, idle timeout, role/permission guards, policies, same-origin protection and auth/guest guards.
71
71
 
72
- Prepared npm packages resolve the runtime to compiled `auth.mjs` in `0.2.18+`.
72
+ Prepared npm packages resolve the runtime to compiled `auth.mjs`.
73
73
 
74
74
  ## `bcp/jobs`
75
75
 
@@ -211,11 +211,11 @@ Active trace context uses Node `AsyncLocalStorage`. W3C `traceparent`, optional
211
211
 
212
212
  Prepared npm packages expose compiled `observability.mjs`.
213
213
 
214
- Related guides: [Observability Platform v2](observability.md), [Observability Platform v3](observability-v3.md).
214
+ Related guides: [Observability Platform v2](observability.md), [Observability Platform v3](observability-v3.md), [Application Platform](application-platform.md).
215
215
 
216
216
  ## `bcp/deployment`
217
217
 
218
- Server-only Deployment Platform v2 lifecycle APIs introduced in `0.2.18`.
218
+ Server-only Deployment Platform v2 lifecycle APIs.
219
219
 
220
220
  Primary functions:
221
221
 
@@ -348,13 +348,105 @@ const unregister =
348
348
 
349
349
  Prepared npm packages expose compiled `deployment.mjs`.
350
350
 
351
- Related guides: [Deployment Platform v2](deployment-platform-v2.md), [Application Packaging](application-packaging.md), [Production Hardening](production-hardening.md), [Observability Platform v3](observability-v3.md).
351
+ Related guides: [Deployment Platform v2](deployment-platform-v2.md), [Application Packaging](application-packaging.md), [Production Hardening](production-hardening.md), [Observability Platform v3](observability-v3.md), [Application Platform](application-platform.md).
352
+
353
+ ## `bcp/application`
354
+
355
+ Server-only BCP Application Platform composition APIs introduced in `0.3.0`.
356
+
357
+ Primary exports:
358
+
359
+ ```text
360
+ defineApp
361
+ createApp
362
+ ApplicationLifecycleError
363
+ ```
364
+
365
+ Important public types:
366
+
367
+ ```text
368
+ Application
369
+ ApplicationState
370
+ ApplicationDefinition
371
+ ApplicationContext
372
+ ApplicationConfigSchema
373
+ ApplicationConfigParser
374
+ ```
375
+
376
+ Create an application:
377
+
378
+ ```ts
379
+ import {
380
+ createApp,
381
+ } from "bcp/application";
382
+
383
+ const app =
384
+ createApp({
385
+ name: "orders-api",
386
+ version: "1.0.0",
387
+ });
388
+ ```
389
+
390
+ The application exposes the existing Plugin and Deployment platform objects:
391
+
392
+ ```text
393
+ app.services
394
+ app.hooks
395
+ app.plugins
396
+ app.deployment
397
+ ```
398
+
399
+ Register a shared service before startup:
400
+
401
+ ```ts
402
+ app.provide(
403
+ "database",
404
+ database
405
+ );
406
+ ```
407
+
408
+ Register an infrastructure resource:
409
+
410
+ ```ts
411
+ app.addResource({
412
+ name: "database",
413
+ start: () => database.connect(),
414
+ ready: () => database.ready,
415
+ stop: () => database.close(),
416
+ });
417
+ ```
418
+
419
+ Application lifecycle order:
420
+
421
+ ```text
422
+ application.setup
423
+ plugins start
424
+ resources start
425
+ application.start
426
+ ```
427
+
428
+ Shutdown runs the inverse dependency order:
429
+
430
+ ```text
431
+ application.stop
432
+ resources stop in reverse order
433
+ plugins stop/dispose
434
+ application.dispose
435
+ ```
436
+
437
+ `readiness()` and `diagnostics()` delegate to the integrated Deployment Platform. `installSignalHandlers()` and `registerShutdownHook()` expose the same graceful-shutdown capabilities through the application root.
438
+
439
+ The runtime is terminal after `stop()`/`shutdown()`/`close()` and rejects service/plugin/resource registration after startup begins.
440
+
441
+ Prepared npm packages expose compiled `application.mjs`, and the entrypoint is blocked from browser/page dependency graphs.
442
+
443
+ Related guides: [Application Platform](application-platform.md), [Migrating to 0.3.0](migration-0.3.md), [Plugin & Module Platform](plugin-module-platform.md), [Deployment Platform v2](deployment-platform-v2.md).
352
444
 
353
445
  ## `bcp/server`
354
446
 
355
447
  Server request/runtime APIs including request context, cookies, CSRF/same-origin protection, logging, graceful shutdown hooks, multipart upload helpers, storage adapters, file delivery, response helpers and low-level session primitives.
356
448
 
357
- Prepared npm packages resolve this runtime to compiled `server.mjs` in `0.2.18+`.
449
+ Prepared npm packages resolve this runtime to compiled `server.mjs`.
358
450
 
359
451
  ## `bcp/server-only`
360
452
 
@@ -368,11 +460,11 @@ import "bcp/server-only";
368
460
 
369
461
  Middleware System v2 request/response pipeline types and helpers.
370
462
 
371
- Prepared npm packages resolve this runtime to compiled `middleware.mjs` in `0.2.18+`.
463
+ Prepared npm packages resolve this runtime to compiled `middleware.mjs`.
372
464
 
373
465
  ## Prepared server runtime map
374
466
 
375
- For `0.2.18`, the prepared npm package uses compiled ESM runtime defaults for:
467
+ For `0.3.0`, the prepared npm package uses compiled ESM runtime defaults for:
376
468
 
377
469
  ```text
378
470
  bcp/cache -> cache.mjs
@@ -387,6 +479,7 @@ bcp/testing -> testing.mjs
387
479
  bcp/plugins -> plugins.mjs
388
480
  bcp/observability -> observability.mjs
389
481
  bcp/deployment -> deployment.mjs
482
+ bcp/application -> application.mjs
390
483
  bcp/server -> server.mjs
391
484
  bcp/middleware -> middleware.mjs
392
485
  ```
@@ -397,4 +490,4 @@ Types remain sourced from the TypeScript public entrypoint files.
397
490
 
398
491
  Only entrypoints listed in both `docs/platform-manifest.json` and `docs/api-manifest.json` are part of the documented platform surface.
399
492
 
400
- Files under internal `packages/*` paths are implementation details unless re-exported through a documented public package entrypoint.
493
+ The reviewed `docs/api-freeze-snapshot.json` records the current package/CLI/API baseline. Files under internal `packages/*` paths remain implementation details unless re-exported through a documented public package entrypoint.
@@ -0,0 +1,378 @@
1
+ # BCP Application Platform
2
+
3
+ BCP Framework `0.3.0` adds a framework-level application runtime that composes the infrastructure platforms introduced throughout `0.2.x` without replacing their individual APIs.
4
+
5
+ > **Release state:** unreleased development target until the complete RC workflow passes, the `v0.3.0` tag is created and npm publication succeeds.
6
+
7
+ ## Public entrypoint
8
+
9
+ ```ts
10
+ import {
11
+ createApp,
12
+ defineApp,
13
+ } from "bcp/application";
14
+ ```
15
+
16
+ `bcp/application` is server-only and is blocked from browser/page dependency graphs.
17
+
18
+ ## Why an application runtime
19
+
20
+ Before `0.3.0`, applications could use BCP databases, jobs, workflows, events, realtime, plugins, cache, observability and deployment independently. That remains supported.
21
+
22
+ The Application Platform adds one composition root for applications that want those systems to share lifecycle and services:
23
+
24
+ ```text
25
+ BCP Application
26
+ |
27
+ +-- typed application config
28
+ +-- shared service registry
29
+ +-- plugin/modules host
30
+ +-- infrastructure resources
31
+ +-- deployment metadata/readiness/diagnostics
32
+ +-- graceful shutdown
33
+ |
34
+ +-- database
35
+ +-- cache / Redis
36
+ +-- jobs / scheduler
37
+ +-- workflow
38
+ +-- events / outbox
39
+ +-- realtime
40
+ +-- observability
41
+ ```
42
+
43
+ The application runtime does not create hidden database/job/cache implementations. Applications continue constructing the provider/runtime objects they need and register them with the composition root.
44
+
45
+ ## Basic application
46
+
47
+ ```ts
48
+ import {
49
+ createApp,
50
+ } from "bcp/application";
51
+
52
+ export const app =
53
+ createApp({
54
+ name: "orders-api",
55
+ version: "1.0.0",
56
+ });
57
+
58
+ await app.start();
59
+ ```
60
+
61
+ Shutdown:
62
+
63
+ ```ts
64
+ await app.stop();
65
+ ```
66
+
67
+ `shutdown()` and `close()` are aliases for the same terminal application shutdown operation.
68
+
69
+ ## Typed application config
70
+
71
+ ```ts
72
+ const app =
73
+ createApp<{
74
+ port: number;
75
+ }>({
76
+ name: "orders-api",
77
+ config: {
78
+ port: process.env.PORT,
79
+ },
80
+ schema: {
81
+ parse(value) {
82
+ const raw = value as {
83
+ port?: string;
84
+ };
85
+
86
+ return {
87
+ port:
88
+ Number(
89
+ raw.port ?? 3000
90
+ ),
91
+ };
92
+ },
93
+ },
94
+ });
95
+ ```
96
+
97
+ The schema may be an object with `parse()` or a parser function.
98
+
99
+ ## Shared services
100
+
101
+ The application service registry is the same registry used by BCP plugins.
102
+
103
+ Register before startup:
104
+
105
+ ```ts
106
+ app.provide(
107
+ "database",
108
+ database
109
+ );
110
+
111
+ app.provide(
112
+ "cache",
113
+ cache
114
+ );
115
+ ```
116
+
117
+ Consume from application hooks:
118
+
119
+ ```ts
120
+ const app =
121
+ createApp({
122
+ name: "orders-api",
123
+
124
+ start(context) {
125
+ const database =
126
+ context.services.get(
127
+ "database"
128
+ );
129
+ },
130
+ });
131
+ ```
132
+
133
+ Plugins receive the same registry through their normal `PluginContext`.
134
+
135
+ ## Plugins and modules
136
+
137
+ Existing `bcp/plugins` definitions plug directly into the application runtime:
138
+
139
+ ```ts
140
+ import {
141
+ definePlugin,
142
+ } from "bcp/plugins";
143
+ import {
144
+ createApp,
145
+ } from "bcp/application";
146
+
147
+ const mailPlugin =
148
+ definePlugin({
149
+ name: "mail",
150
+
151
+ setup(context) {
152
+ context.services.provide(
153
+ "mail",
154
+ mailer
155
+ );
156
+ },
157
+ });
158
+
159
+ const app =
160
+ createApp({
161
+ name: "orders-api",
162
+ plugins: [
163
+ mailPlugin,
164
+ ],
165
+ });
166
+ ```
167
+
168
+ Existing `defineModule()` plugin modules can be passed through `modules` without conversion.
169
+
170
+ Before startup, applications may also register extensions fluently:
171
+
172
+ ```ts
173
+ app.use(mailPlugin);
174
+ ```
175
+
176
+ ## Infrastructure resources
177
+
178
+ Register lifecycle resources using the existing Deployment Platform resource contract:
179
+
180
+ ```ts
181
+ const app =
182
+ createApp({
183
+ name: "orders-api",
184
+ resources: [
185
+ {
186
+ name: "database",
187
+
188
+ async start() {
189
+ await database.connect();
190
+ },
191
+
192
+ ready() {
193
+ return database.ready;
194
+ },
195
+
196
+ async stop() {
197
+ await database.close();
198
+ },
199
+ },
200
+ ],
201
+ });
202
+ ```
203
+
204
+ Or before `start()`:
205
+
206
+ ```ts
207
+ app.addResource({
208
+ name: "workers",
209
+
210
+ start() {
211
+ worker = jobs.startWorker();
212
+ },
213
+
214
+ stop() {
215
+ return worker.stop();
216
+ },
217
+ });
218
+ ```
219
+
220
+ ## Lifecycle order
221
+
222
+ Application startup has one deterministic order:
223
+
224
+ ```text
225
+ application.setup()
226
+ |
227
+ v
228
+ plugin setup/start
229
+ |
230
+ v
231
+ resource 1 start
232
+ resource 2 start
233
+ ...
234
+ |
235
+ v
236
+ application.start()
237
+ |
238
+ v
239
+ state = ready
240
+ ```
241
+
242
+ Shutdown reverses the dependency order:
243
+
244
+ ```text
245
+ application.stop()
246
+ |
247
+ v
248
+ resource N stop
249
+ ...
250
+ resource 1 stop
251
+ |
252
+ v
253
+ plugin stop/dispose
254
+ |
255
+ v
256
+ application.dispose()
257
+ ```
258
+
259
+ This allows application logic and workers to stop before their shared database/cache/Redis dependencies disappear.
260
+
261
+ Startup failures use Deployment Platform rollback. Already-started resources are stopped in reverse order and application/plugin disposal still runs.
262
+
263
+ ## Setup versus start
264
+
265
+ `setup()` runs before the deployment resource graph starts. It is useful for service registration and in-process configuration:
266
+
267
+ ```ts
268
+ createApp({
269
+ name: "orders-api",
270
+
271
+ setup(context) {
272
+ context.services.provide(
273
+ "feature-flags",
274
+ flags
275
+ );
276
+ },
277
+ });
278
+ ```
279
+
280
+ `start()` runs after plugins and infrastructure resources have started:
281
+
282
+ ```ts
283
+ createApp({
284
+ name: "orders-api",
285
+
286
+ start(context) {
287
+ const database =
288
+ context.services.get(
289
+ "database"
290
+ );
291
+
292
+ // Application-level startup after infrastructure is available.
293
+ },
294
+ });
295
+ ```
296
+
297
+ ## Readiness and diagnostics
298
+
299
+ Application readiness delegates to the Deployment Platform:
300
+
301
+ ```ts
302
+ const report =
303
+ await app.readiness();
304
+ ```
305
+
306
+ The report includes the internal plugin host, registered resources and the application lifecycle resource.
307
+
308
+ Diagnostics:
309
+
310
+ ```ts
311
+ const diagnostics =
312
+ await app.diagnostics();
313
+ ```
314
+
315
+ Application diagnostics include deployment identity plus lifecycle information for every registered resource.
316
+
317
+ ## Signals and framework shutdown hooks
318
+
319
+ If this process owns termination signals:
320
+
321
+ ```ts
322
+ const removeSignals =
323
+ app.installSignalHandlers();
324
+ ```
325
+
326
+ The default deployment signals remain `SIGTERM` and `SIGINT`.
327
+
328
+ To participate in the existing BCP production shutdown registry:
329
+
330
+ ```ts
331
+ const unregister =
332
+ app.registerShutdownHook();
333
+ ```
334
+
335
+ ## Application state
336
+
337
+ The public state model is:
338
+
339
+ ```text
340
+ created
341
+ starting
342
+ ready
343
+ stopping
344
+ stopped
345
+ failed
346
+ ```
347
+
348
+ Startup and shutdown are idempotent for concurrent/repeated calls while the application remains in the corresponding active/terminal lifecycle.
349
+
350
+ A stopped application is terminal and cannot be started again. Create a new application runtime for a new process lifecycle.
351
+
352
+ ## Mutation boundary
353
+
354
+ Plugins, services and deployment resources must be registered before `start()`.
355
+
356
+ The following are intentionally rejected after startup begins:
357
+
358
+ ```ts
359
+ app.use(...)
360
+ app.provide(...)
361
+ app.addResource(...)
362
+ ```
363
+
364
+ This keeps the production lifecycle graph deterministic.
365
+
366
+ ## Relationship to 0.2.19 API freeze
367
+
368
+ `0.2.19` froze the `0.2.x` package/API baseline. `0.3.0` intentionally establishes the next baseline by adding one public server-only entrypoint:
369
+
370
+ ```text
371
+ bcp/application
372
+ ```
373
+
374
+ Existing `0.2.19` public entrypoints remain available. `0.3.0` does not intentionally remove them.
375
+
376
+ ## Next platform work
377
+
378
+ The next planned milestone is `0.3.1 — Dependency Injection & Service Container`, which can build typed service tokens, scopes and testing overrides on top of the shared service composition introduced here.
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "schemaVersion": 1,
3
3
  "framework": "bcp",
4
- "versionTarget": "0.2.18",
4
+ "versionTarget": "0.3.0",
5
5
  "releaseState": "unreleased",
6
6
  "sections": [
7
7
  {
@@ -58,8 +58,9 @@
58
58
  {
59
59
  "id": "runtime",
60
60
  "title": "Runtime & Infrastructure",
61
- "description": "Middleware, jobs, scheduling, workflows, event delivery, realtime channels, observability, deployment lifecycle, distributed caching, security and production hardening.",
61
+ "description": "Application composition, middleware, jobs, scheduling, workflows, event delivery, realtime channels, observability, deployment lifecycle, distributed caching, security and production hardening.",
62
62
  "pages": [
63
+ { "route": "/docs/application-platform", "source": "application-platform.md", "title": "Application Platform" },
63
64
  { "route": "/docs/middleware", "source": "middleware.md", "title": "Middleware" },
64
65
  { "route": "/docs/hydration", "source": "hydration.md", "title": "Hydration" },
65
66
  { "route": "/docs/development-logging", "source": "development-logging.md", "title": "Logging" },
@@ -102,10 +103,12 @@
102
103
  {
103
104
  "id": "platform-compatibility",
104
105
  "title": "Platform & Compatibility",
105
- "description": "Supported platform contracts, documentation integration and migration guidance.",
106
+ "description": "Supported platform contracts, API baselines, documentation integration and migration guidance.",
106
107
  "pages": [
107
108
  { "route": "/docs/platform-contract", "source": "platform-contract.md", "title": "Framework Platform Contract" },
109
+ { "route": "/docs/stability-api-freeze", "source": "stability-api-freeze.md", "title": "0.2 Stability & API Freeze" },
108
110
  { "route": "/docs/documentation-platform", "source": "documentation-platform.md", "title": "Documentation Platform" },
111
+ { "route": "/docs/migration-0.3", "source": "migration-0.3.md", "title": "Migrating to 0.3.0" },
109
112
  { "route": "/docs/migration-0.2", "source": "migration-0.2.md", "title": "Migrating to 0.2.x" }
110
113
  ]
111
114
  },
@@ -119,7 +122,9 @@
119
122
  }
120
123
  ],
121
124
  "releases": [
122
- { "route": "/releases/0.2.18", "source": "releases/0.2.18.md", "version": "0.2.18", "state": "unreleased" },
125
+ { "route": "/releases/0.3.0", "source": "releases/0.3.0.md", "version": "0.3.0", "state": "unreleased" },
126
+ { "route": "/releases/0.2.19", "source": "releases/0.2.19.md", "version": "0.2.19" },
127
+ { "route": "/releases/0.2.18", "source": "releases/0.2.18.md", "version": "0.2.18" },
123
128
  { "route": "/releases/0.2.17", "source": "releases/0.2.17.md", "version": "0.2.17" },
124
129
  { "route": "/releases/0.2.16", "source": "releases/0.2.16.md", "version": "0.2.16" },
125
130
  { "route": "/releases/0.2.15", "source": "releases/0.2.15.md", "version": "0.2.15" },