@chidchanun/bcp 0.2.14 → 0.2.15

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, 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, observability, uploads, storage and standalone Node.js deployment.
4
4
 
5
- > **Development target:** `0.2.14Testing Platform`
5
+ > **Development target:** `0.2.15Plugin & Module Platform`
6
6
  >
7
- > `0.2.14` remains unreleased until local validation, RC checks, tagging and npm publication complete.
7
+ > `0.2.15` remains unreleased until local validation, RC checks, tagging and npm publication complete.
8
8
 
9
9
  ## Current platform
10
10
 
@@ -25,7 +25,8 @@ BCP Framework is a React full-stack framework for file-based routing, SSR, SPA n
25
25
  | Workflows | Sequential/parallel steps, retries, persisted delays, compensation and run leases |
26
26
  | Events | Transactional outbox, SQL persistence, dispatcher leases, retries, event bus and durable queue handoff |
27
27
  | Realtime | Channels/rooms, presence, broker delivery, WebSocket adapter contract, SSE and heartbeat |
28
- | Testing | Request/route/auth/database/middleware/jobs/workflow/outbox/realtime/SSE test harnesses |
28
+ | Testing | Request/route/page/auth/database/middleware/jobs/workflow/outbox/realtime/SSE test harnesses |
29
+ | Plugins & modules | Dependency ordering, lifecycle hooks, config parsing, service registry and async extension hooks |
29
30
  | Observability | Structured logs, metrics, Prometheus output and health/readiness checks |
30
31
  | Uploads & storage | Multipart streaming, Local/S3-compatible storage and signed URLs |
31
32
  | Caching | Response cache and revalidation primitives |
@@ -75,6 +76,7 @@ import { createWorkflow } from "bcp/workflow";
75
76
  import { createTransactionalOutbox } from "bcp/events";
76
77
  import { createRealtime } from "bcp/realtime";
77
78
  import { createTestApp } from "bcp/testing";
79
+ import { createPluginHost } from "bcp/plugins";
78
80
  import { createMetricsRegistry } from "bcp/observability";
79
81
  ```
80
82
 
@@ -369,6 +371,81 @@ readSseEvents()
369
371
 
370
372
  Read more: [Testing Platform](docs/testing-platform.md)
371
373
 
374
+ ## Plugin & Module Platform — 0.2.15
375
+
376
+ `0.2.15` adds the server-only `bcp/plugins` entrypoint for reusable application/framework extensions.
377
+
378
+ Define plugins with explicit dependencies:
379
+
380
+ ```ts
381
+ import {
382
+ createPluginHost,
383
+ definePlugin,
384
+ } from "bcp/plugins";
385
+
386
+ const databasePlugin =
387
+ definePlugin({
388
+ name: "database",
389
+ setup(context) {
390
+ context.services.provide(
391
+ "database",
392
+ db
393
+ );
394
+ },
395
+ start() {
396
+ return db.connect();
397
+ },
398
+ stop() {
399
+ return db.disconnect();
400
+ },
401
+ });
402
+
403
+ const jobsPlugin =
404
+ definePlugin({
405
+ name: "jobs",
406
+ requires: [
407
+ "database",
408
+ ],
409
+ });
410
+
411
+ const host =
412
+ createPluginHost({
413
+ plugins: [
414
+ jobsPlugin,
415
+ databasePlugin,
416
+ ],
417
+ });
418
+
419
+ await host.start();
420
+ ```
421
+
422
+ Dependency order is resolved automatically. Startup follows dependency order while stop/dispose runs in reverse order.
423
+
424
+ Modules group reusable plugin sets:
425
+
426
+ ```ts
427
+ import {
428
+ defineModule,
429
+ } from "bcp/plugins";
430
+
431
+ const backendModule =
432
+ defineModule({
433
+ name: "backend",
434
+ plugins: [
435
+ databasePlugin,
436
+ jobsPlugin,
437
+ ],
438
+ });
439
+ ```
440
+
441
+ Plugin configuration can be parsed at setup time and overridden through `createPluginHost({ configs })`.
442
+
443
+ Plugins share a service registry and awaited in-process hook bus through `context.services` and `context.hooks`.
444
+
445
+ If startup fails, already-started plugins are stopped in reverse order before the lifecycle error is propagated.
446
+
447
+ Read more: [Plugin & Module Platform](docs/plugin-module-platform.md)
448
+
372
449
  ## Public entrypoints
373
450
 
374
451
  ```text
@@ -385,6 +462,7 @@ bcp/workflow
385
462
  bcp/events
386
463
  bcp/realtime
387
464
  bcp/testing
465
+ bcp/plugins
388
466
  bcp/observability
389
467
  bcp/server
390
468
  bcp/server-only
@@ -433,7 +511,7 @@ Browser / API / Realtime clients
433
511
  |
434
512
  security + auth
435
513
  |
436
- application APIs
514
+ Plugin Host
437
515
  / | \
438
516
  database workflows realtime
439
517
  | | ^
@@ -469,7 +547,7 @@ docs/api-manifest.json
469
547
 
470
548
  ## Release validation
471
549
 
472
- Before publishing `0.2.14`:
550
+ Before publishing `0.2.15`:
473
551
 
474
552
  ```bash
475
553
  npm run typecheck
@@ -480,7 +558,7 @@ npm run test:package
480
558
  npm run rc:check
481
559
  ```
482
560
 
483
- `0.2.14` adds unit and prepared-package smoke coverage for request/route handling, cookies, signed auth sessions, rollback transactions, middleware execution, jobs, workflows, outbox delivery, realtime sockets, SSE parsing, public runtime compilation and browser boundary enforcement.
561
+ `0.2.15` adds unit and prepared-package smoke coverage for plugin dependency ordering, missing/cyclic dependencies, modules, config parsing, shared services, async hooks, lifecycle rollback, compiled `plugins.mjs` execution and browser boundary enforcement.
484
562
 
485
563
  Do not tag or publish until the exact final release commit passes the full RC sequence.
486
564
 
@@ -509,12 +587,13 @@ Do not tag or publish until the exact final release commit passes the full RC se
509
587
  | `0.2.12` | Transactional Outbox & Events |
510
588
  | `0.2.13` | Realtime Platform |
511
589
  | `0.2.14` | Testing Platform |
590
+ | `0.2.15` | Plugin & Module Platform |
512
591
 
513
592
  ## Roadmap
514
593
 
515
- `0.2.14` establishes framework-native testing for the current BCP application/runtime stack without coupling the framework to a specific test runner.
594
+ `0.2.15` establishes reusable server-side extension composition while keeping BCP subsystem contracts provider-neutral and independently testable.
516
595
 
517
- The next logical milestone is **`0.2.15Plugin & Module Platform`**, focused on reusable framework modules, lifecycle hooks, configuration extension, package metadata and plugin discovery/registration while keeping the current public entrypoints stable.
596
+ The next logical milestone is **`0.2.16Cache Platform v2`**, focused on distributed cache adapters, Redis-compatible caching, locking, stampede protection and production cache observability.
518
597
 
519
598
  Native desktop/mobile compilation remains later roadmap work.
520
599
 
package/docs/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  The `docs/` directory is the documentation source of truth for BCP Framework and is organized for **`bcp-docs-web`**.
4
4
 
5
- > **Documentation target:** BCP Framework `0.2.14Testing Platform`
5
+ > **Documentation target:** BCP Framework `0.2.15Plugin & Module Platform`
6
6
  >
7
7
  > **Release state:** unreleased development target until RC validation, tagging and npm publication complete.
8
8
 
@@ -40,63 +40,56 @@ Framework source and tests remain authoritative for runtime behavior.
40
40
  | `0.2.12` | Transactional Outbox & Events |
41
41
  | `0.2.13` | Realtime Platform |
42
42
  | `0.2.14` | Testing Platform |
43
+ | `0.2.15` | Plugin & Module Platform |
43
44
 
44
- ## 0.2.14Testing Platform
45
+ ## 0.2.15Plugin & Module Platform
45
46
 
46
- `0.2.14` adds the server-only `bcp/testing` public entrypoint.
47
+ `0.2.15` adds the server-only `bcp/plugins` public entrypoint.
47
48
 
48
49
  Primary APIs:
49
50
 
50
51
  ```ts
51
52
  import {
52
- createFakeClock,
53
- createJobTestHarness,
54
- createOutboxTestHarness,
55
- createRealtimeTestHarness,
56
- createRealtimeTestSocket,
57
- createRouteTestHandler,
58
- createSequenceIdFactory,
59
- createTestApp,
60
- createTestAuthSession,
61
- createWorkflowTestHarness,
62
- expectResponse,
63
- readSseEvents,
64
- runTestMiddleware,
65
- withTestTransaction,
66
- } from "bcp/testing";
53
+ createPluginHookBus,
54
+ createPluginHost,
55
+ createPluginServiceRegistry,
56
+ defineModule,
57
+ definePlugin,
58
+ } from "bcp/plugins";
67
59
  ```
68
60
 
69
- Testing model:
61
+ Runtime model:
70
62
 
71
63
  ```text
72
- node:test / Vitest / Jest / other runner
73
- |
74
- v
75
- bcp/testing
76
- |
77
- +----------+-----------+
78
- | | |
79
- Request Database Infrastructure
80
- Route rollback jobs/workflow
81
- Response tx outbox/realtime
82
- Auth SSE/socket
83
- Middleware
64
+ Plugin Host
65
+ |
66
+ +-- dependency graph
67
+ | -> required / optional dependencies
68
+ |
69
+ +-- lifecycle
70
+ | -> setup -> start -> stop -> dispose
71
+ |
72
+ +-- service registry
73
+ | -> typed shared application services
74
+ |
75
+ +-- async hook bus
76
+ -> in-process extension points
84
77
  ```
85
78
 
86
- The helpers use existing BCP runtime contracts rather than defining a parallel mock framework. Signed auth sessions use the production session token implementation; middleware tests execute the real onion pipeline; job/workflow/outbox/realtime harnesses wrap their actual platform APIs.
79
+ Startup follows topological dependency order. Stop/dispose runs in reverse order. A failed startup rolls back plugins that already started.
87
80
 
88
- BCP does not add a Jest or Vitest dependency.
81
+ Modules are named bundles of plugins; they do not create a separate lifecycle graph.
89
82
 
90
83
  New/updated sources:
91
84
 
92
85
  | Source | Purpose |
93
86
  | --- | --- |
94
- | `testing-platform.md` | Request, auth, database, middleware, jobs, workflow, outbox, realtime and SSE testing |
95
- | `api-reference.md` | `bcp/testing` public APIs |
96
- | `platform-manifest.json` | Testing capability flags and public entrypoint |
97
- | `api-manifest.json` | `bcp/testing` source/guide ownership |
98
- | `docs-web-manifest.json` | Testing docs navigation and `0.2.14` release route |
99
- | `releases/0.2.14.md` | Testing Platform release notes |
87
+ | `plugin-module-platform.md` | Plugin definitions, modules, dependency order, lifecycle, config, services and hooks |
88
+ | `api-reference.md` | `bcp/plugins` public APIs |
89
+ | `platform-manifest.json` | Plugin capability flags and public entrypoint |
90
+ | `api-manifest.json` | `bcp/plugins` source/guide ownership |
91
+ | `docs-web-manifest.json` | Plugin docs navigation and `0.2.15` release route |
92
+ | `releases/0.2.15.md` | Plugin & Module Platform release notes |
100
93
 
101
94
  ## Update rule
102
95
 
@@ -123,8 +116,9 @@ When framework behavior or public surface changes:
123
116
  | `/docs/transactional-outbox-events` | `transactional-outbox-events.md` |
124
117
  | `/docs/realtime-platform` | `realtime-platform.md` |
125
118
  | `/docs/testing-platform` | `testing-platform.md` |
119
+ | `/docs/plugin-module-platform` | `plugin-module-platform.md` |
126
120
  | `/docs/api-reference` | `api-reference.md` |
127
- | `/releases/0.2.14` | `releases/0.2.14.md` |
121
+ | `/releases/0.2.15` | `releases/0.2.15.md` |
128
122
 
129
123
  Every route/source pair is validated by unit tests.
130
124
 
@@ -144,6 +138,7 @@ bcp/workflow
144
138
  bcp/events
145
139
  bcp/realtime
146
140
  bcp/testing
141
+ bcp/plugins
147
142
  bcp/observability
148
143
  bcp/server
149
144
  bcp/server-only
@@ -154,7 +149,7 @@ The API-manifest entrypoint set must match the platform public-entrypoint set ex
154
149
 
155
150
  ## Release validation
156
151
 
157
- Before publishing `0.2.14`:
152
+ Before publishing `0.2.15`:
158
153
 
159
154
  ```bash
160
155
  npm run typecheck
@@ -165,6 +160,6 @@ npm run test:package
165
160
  npm run rc:check
166
161
  ```
167
162
 
168
- Testing Platform validation covers request/route behavior, cookie persistence, signed auth sessions, rollback transactions, middleware execution, deterministic clocks/IDs, job/workflow/outbox/realtime harnesses, SSE parsing, server-only boundaries, compiled `testing.mjs` execution and docs/platform/API parity.
163
+ Plugin Platform validation covers dependency ordering, missing/cyclic dependencies, module composition, typed config parsing, service sharing, async hooks, reverse shutdown, startup rollback, server-only boundaries, compiled `plugins.mjs` package execution and docs/platform/API parity.
169
164
 
170
165
  The final release tag must point to the exact commit that passed the complete RC sequence.
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "schemaVersion": 1,
3
3
  "framework": "bcp",
4
- "version": "0.2.14",
4
+ "version": "0.2.15",
5
5
  "releaseState": "unreleased",
6
6
  "coverage": "public-entrypoints",
7
7
  "entrypoints": [
@@ -106,9 +106,17 @@
106
106
  "source": "packages/client/src/testing.ts",
107
107
  "environment": "server",
108
108
  "route": "/docs/api-reference#bcp-testing",
109
- "summary": "Framework-native testing utilities for Request/Response handlers, signed auth sessions, rollback transactions, middleware, jobs, workflows, outbox delivery, realtime sockets and SSE.",
109
+ "summary": "Framework-native testing utilities for Request/Response handlers, signed auth sessions, rollback transactions, page/server execution, middleware, jobs, workflows, outbox delivery, realtime sockets and SSE.",
110
110
  "guides": ["/docs/testing-platform", "/docs/authentication", "/docs/database", "/docs/durable-jobs", "/docs/workflow-orchestration", "/docs/transactional-outbox-events", "/docs/realtime-platform"]
111
111
  },
112
+ {
113
+ "package": "bcp/plugins",
114
+ "source": "packages/client/src/plugins.ts",
115
+ "environment": "server",
116
+ "route": "/docs/api-reference#bcp-plugins",
117
+ "summary": "Plugin and module composition with dependency ordering, lifecycle hooks, typed config parsing, shared services and asynchronous extension hooks.",
118
+ "guides": ["/docs/plugin-module-platform", "/docs/configuration", "/docs/testing-platform", "/docs/observability"]
119
+ },
112
120
  {
113
121
  "package": "bcp/observability",
114
122
  "source": "packages/client/src/observability.ts",
@@ -308,6 +308,52 @@ The package is server-only; the client boundary validator rejects `bcp/testing`
308
308
 
309
309
  Related guides: [Testing Platform](testing-platform.md), [Authentication](authentication.md), [Database](database.md), [Durable Jobs](durable-jobs.md), [Workflow Orchestration](workflow-orchestration.md), [Transactional Outbox & Events](transactional-outbox-events.md), [Realtime Platform](realtime-platform.md).
310
310
 
311
+ ## `bcp/plugins`
312
+
313
+ Server-only Plugin & Module Platform APIs added in `0.2.15`.
314
+
315
+ ```ts
316
+ import {
317
+ createPluginHookBus,
318
+ createPluginHost,
319
+ createPluginServiceRegistry,
320
+ defineModule,
321
+ definePlugin,
322
+ PluginDependencyError,
323
+ PluginLifecycleError,
324
+ type PluginConfigParser,
325
+ type PluginConfigSchema,
326
+ type PluginContext,
327
+ type PluginDefinition,
328
+ type PluginHookBus,
329
+ type PluginHookHandler,
330
+ type PluginHost,
331
+ type PluginHostOptions,
332
+ type PluginHostView,
333
+ type PluginModule,
334
+ type PluginRecord,
335
+ type PluginServiceKey,
336
+ type PluginServiceRegistry,
337
+ type PluginState,
338
+ } from "bcp/plugins";
339
+ ```
340
+
341
+ `createPluginHost()` resolves required and optional plugin dependencies and starts plugins in topological order. `stop()` and `close()` shut them down/dispose them in reverse dependency order.
342
+
343
+ `defineModule()` groups reusable plugin definitions while preserving one global host dependency graph.
344
+
345
+ Plugin configuration can be parsed with a schema/parser during setup. Values from `PluginHostOptions.configs` override plugin-local defaults before parsing.
346
+
347
+ `PluginServiceRegistry` provides shared string/Symbol-keyed services. `PluginHookBus` provides awaited, in-process extension hooks in registration order.
348
+
349
+ Missing dependencies and dependency cycles throw `PluginDependencyError`. Setup/start failures surface `PluginLifecycleError`; startup failures roll back plugins that already started in the current transition.
350
+
351
+ `host.plugin()` and `host.plugins()` expose inspectable lifecycle records.
352
+
353
+ `bcp/plugins` is server-only and is rejected from page/client bundles.
354
+
355
+ Related guides: [Plugin & Module Platform](plugin-module-platform.md), [Configuration](configuration.md), [Testing Platform](testing-platform.md), [Observability Platform v2](observability.md).
356
+
311
357
  ## `bcp/observability`
312
358
 
313
359
  Server-only Observability Platform v2 APIs for process-local counters, gauges, histograms, Prometheus exposition, request metrics middleware and health/readiness checks.
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "schemaVersion": 1,
3
3
  "framework": "bcp",
4
- "versionTarget": "0.2.14",
4
+ "versionTarget": "0.2.15",
5
5
  "releaseState": "unreleased",
6
6
  "sections": [
7
7
  {
@@ -88,11 +88,12 @@
88
88
  {
89
89
  "id": "developer-experience",
90
90
  "title": "Developer Experience",
91
- "description": "Project generators, diagnostics, testing, project metadata and framework maintenance tooling.",
91
+ "description": "Project generators, diagnostics, testing, plugin composition, project metadata and framework maintenance tooling.",
92
92
  "pages": [
93
93
  { "route": "/docs/generators", "source": "generators.md", "title": "Project Generators" },
94
94
  { "route": "/docs/developer-tools", "source": "developer-tools.md", "title": "Doctor & Inspect" },
95
- { "route": "/docs/testing-platform", "source": "testing-platform.md", "title": "Testing Platform" }
95
+ { "route": "/docs/testing-platform", "source": "testing-platform.md", "title": "Testing Platform" },
96
+ { "route": "/docs/plugin-module-platform", "source": "plugin-module-platform.md", "title": "Plugin & Module Platform" }
96
97
  ]
97
98
  },
98
99
  {
@@ -115,7 +116,8 @@
115
116
  }
116
117
  ],
117
118
  "releases": [
118
- { "route": "/releases/0.2.14", "source": "releases/0.2.14.md", "version": "0.2.14", "state": "unreleased" },
119
+ { "route": "/releases/0.2.15", "source": "releases/0.2.15.md", "version": "0.2.15", "state": "unreleased" },
120
+ { "route": "/releases/0.2.14", "source": "releases/0.2.14.md", "version": "0.2.14" },
119
121
  { "route": "/releases/0.2.13", "source": "releases/0.2.13.md", "version": "0.2.13" },
120
122
  { "route": "/releases/0.2.12", "source": "releases/0.2.12.md", "version": "0.2.12" },
121
123
  { "route": "/releases/0.2.11", "source": "releases/0.2.11.md", "version": "0.2.11" },
@@ -1,9 +1,9 @@
1
1
  {
2
2
  "schemaVersion": 1,
3
3
  "framework": "bcp",
4
- "version": "0.2.14",
4
+ "version": "0.2.15",
5
5
  "releaseState": "unreleased",
6
- "baseline": "testing-platform",
6
+ "baseline": "plugin-module-platform",
7
7
  "runtime": {
8
8
  "node": ">=24.11.0",
9
9
  "react": "19",
@@ -24,6 +24,7 @@
24
24
  "bcp/events",
25
25
  "bcp/realtime",
26
26
  "bcp/testing",
27
+ "bcp/plugins",
27
28
  "bcp/observability",
28
29
  "bcp/server",
29
30
  "bcp/server-only",
@@ -138,6 +139,15 @@
138
139
  "testRealtimeSocket": true,
139
140
  "testSseReader": true,
140
141
  "deterministicTestClock": true,
142
+ "pluginModulePlatform": true,
143
+ "pluginDefinitions": true,
144
+ "pluginModules": true,
145
+ "pluginDependencyOrdering": true,
146
+ "pluginLifecycleHooks": true,
147
+ "pluginConfigSchemas": true,
148
+ "pluginServiceRegistry": true,
149
+ "pluginHookBus": true,
150
+ "pluginLifecycleRollback": true,
141
151
  "databaseMigrations": true,
142
152
  "databaseAdapterContract": true,
143
153
  "databasePostgresql": true,
@@ -177,7 +187,7 @@
177
187
  "s3-compatible"
178
188
  ],
179
189
  "compatibility": {
180
- "previousBaseline": "0.2.13",
190
+ "previousBaseline": "0.2.14",
181
191
  "intentionalBreakingChangesFromPreviousBaseline": false,
182
192
  "migrationGuide": "migration-0.2.md"
183
193
  },
@@ -201,7 +211,8 @@
201
211
  "transactionalOutboxEvents": "transactional-outbox-events.md",
202
212
  "realtimePlatform": "realtime-platform.md",
203
213
  "testingPlatform": "testing-platform.md",
214
+ "pluginModulePlatform": "plugin-module-platform.md",
204
215
  "migrationGuide": "migration-0.2.md",
205
- "releaseNotes": "releases/0.2.14.md"
216
+ "releaseNotes": "releases/0.2.15.md"
206
217
  }
207
218
  }