@chidchanun/bcp 0.3.1 → 0.3.2
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/docs/api-freeze-snapshot.json +13 -2
- package/docs/api-manifest.json +22 -14
- package/docs/docs-web-manifest.json +6 -4
- package/docs/module-system-v2.md +386 -0
- package/docs/platform-manifest.json +19 -4
- package/docs/releases/0.3.2.md +125 -0
- package/package.json +7 -1
- package/packages/bundler/src/client-boundary.ts +1 -0
- package/packages/client/src/application.mjs +434 -30
- package/packages/client/src/modules.mjs +392 -0
- package/packages/client/src/modules.ts +17 -0
- package/packages/server/src/application.ts +58 -9
- package/packages/server/src/modules.ts +682 -0
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schemaVersion": 1,
|
|
3
3
|
"framework": "bcp",
|
|
4
|
-
"version": "0.3.
|
|
5
|
-
"baselineVersion": "0.3.
|
|
4
|
+
"version": "0.3.2",
|
|
5
|
+
"baselineVersion": "0.3.1",
|
|
6
6
|
"state": "frozen",
|
|
7
7
|
"intentionalBreakingChanges": false,
|
|
8
8
|
"publicEntrypoints": [
|
|
@@ -23,6 +23,7 @@
|
|
|
23
23
|
"bcp/observability",
|
|
24
24
|
"bcp/deployment",
|
|
25
25
|
"bcp/container",
|
|
26
|
+
"bcp/modules",
|
|
26
27
|
"bcp/application",
|
|
27
28
|
"bcp/server",
|
|
28
29
|
"bcp/server-only",
|
|
@@ -103,6 +104,11 @@
|
|
|
103
104
|
"default": "./packages/server/src/middleware.mjs",
|
|
104
105
|
"types": "./packages/server/src/middleware.ts"
|
|
105
106
|
},
|
|
107
|
+
"./modules": {
|
|
108
|
+
"browser": "./packages/client/src/server-only.browser.mjs",
|
|
109
|
+
"default": "./packages/client/src/modules.mjs",
|
|
110
|
+
"types": "./packages/client/src/modules.ts"
|
|
111
|
+
},
|
|
106
112
|
"./observability": {
|
|
107
113
|
"browser": "./packages/client/src/server-only.browser.mjs",
|
|
108
114
|
"default": "./packages/client/src/observability.mjs",
|
|
@@ -230,6 +236,11 @@
|
|
|
230
236
|
"source": "packages/client/src/container.ts",
|
|
231
237
|
"environment": "server"
|
|
232
238
|
},
|
|
239
|
+
{
|
|
240
|
+
"package": "bcp/modules",
|
|
241
|
+
"source": "packages/client/src/modules.ts",
|
|
242
|
+
"environment": "server"
|
|
243
|
+
},
|
|
233
244
|
{
|
|
234
245
|
"package": "bcp/application",
|
|
235
246
|
"source": "packages/client/src/application.ts",
|
package/docs/api-manifest.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schemaVersion": 1,
|
|
3
3
|
"framework": "bcp",
|
|
4
|
-
"version": "0.3.
|
|
4
|
+
"version": "0.3.2",
|
|
5
5
|
"releaseState": "unreleased",
|
|
6
6
|
"coverage": "public-entrypoints",
|
|
7
7
|
"entrypoints": [
|
|
@@ -59,7 +59,7 @@
|
|
|
59
59
|
"environment": "server",
|
|
60
60
|
"route": "/docs/api-reference#bcp-database",
|
|
61
61
|
"summary": "Provider-neutral MySQL, PostgreSQL and SQLite query, transaction, lifecycle and migration primitives.",
|
|
62
|
-
"guides": ["/docs/database", "/docs/database-migrations", "/docs/transactional-outbox-events", "/docs/testing-platform", "/docs/observability-v3", "/docs/deployment-platform-v2", "/docs/application-platform", "/docs/service-container"]
|
|
62
|
+
"guides": ["/docs/database", "/docs/database-migrations", "/docs/transactional-outbox-events", "/docs/testing-platform", "/docs/observability-v3", "/docs/deployment-platform-v2", "/docs/application-platform", "/docs/service-container", "/docs/module-system-v2"]
|
|
63
63
|
},
|
|
64
64
|
{
|
|
65
65
|
"package": "bcp/auth",
|
|
@@ -67,7 +67,7 @@
|
|
|
67
67
|
"environment": "server",
|
|
68
68
|
"route": "/docs/api-reference#bcp-auth",
|
|
69
69
|
"summary": "Authentication Platform v2 plus permission checks, authorization policies and auth/guest/role/permission route guards, published with a compiled Node runtime.",
|
|
70
|
-
"guides": ["/docs/authentication", "/docs/auth-session-store", "/docs/auth-route-guards", "/docs/authorization-security", "/docs/session-auth", "/docs/testing-platform", "/docs/deployment-platform-v2", "/docs/application-platform", "/docs/service-container"]
|
|
70
|
+
"guides": ["/docs/authentication", "/docs/auth-session-store", "/docs/auth-route-guards", "/docs/authorization-security", "/docs/session-auth", "/docs/testing-platform", "/docs/deployment-platform-v2", "/docs/application-platform", "/docs/service-container", "/docs/module-system-v2"]
|
|
71
71
|
},
|
|
72
72
|
{
|
|
73
73
|
"package": "bcp/jobs",
|
|
@@ -75,7 +75,7 @@
|
|
|
75
75
|
"environment": "server",
|
|
76
76
|
"route": "/docs/api-reference#bcp-jobs",
|
|
77
77
|
"summary": "Background queues and schedules with visibility leases, heartbeats, stale recovery, DLQ maintenance and Redis-compatible durable adapters.",
|
|
78
|
-
"guides": ["/docs/background-jobs", "/docs/job-scheduling", "/docs/durable-jobs", "/docs/transactional-outbox-events", "/docs/realtime-platform", "/docs/testing-platform", "/docs/observability-v3", "/docs/deployment-platform-v2", "/docs/application-platform", "/docs/service-container"]
|
|
78
|
+
"guides": ["/docs/background-jobs", "/docs/job-scheduling", "/docs/durable-jobs", "/docs/transactional-outbox-events", "/docs/realtime-platform", "/docs/testing-platform", "/docs/observability-v3", "/docs/deployment-platform-v2", "/docs/application-platform", "/docs/service-container", "/docs/module-system-v2"]
|
|
79
79
|
},
|
|
80
80
|
{
|
|
81
81
|
"package": "bcp/workflow",
|
|
@@ -83,7 +83,7 @@
|
|
|
83
83
|
"environment": "server",
|
|
84
84
|
"route": "/docs/api-reference#bcp-workflow",
|
|
85
85
|
"summary": "Persistent workflow orchestration with sequential and parallel steps, retries, delays, compensation, run leases and optional durable queue execution.",
|
|
86
|
-
"guides": ["/docs/workflow-orchestration", "/docs/durable-jobs", "/docs/realtime-platform", "/docs/testing-platform", "/docs/observability-v3", "/docs/deployment-platform-v2", "/docs/application-platform", "/docs/service-container"]
|
|
86
|
+
"guides": ["/docs/workflow-orchestration", "/docs/durable-jobs", "/docs/realtime-platform", "/docs/testing-platform", "/docs/observability-v3", "/docs/deployment-platform-v2", "/docs/application-platform", "/docs/service-container", "/docs/module-system-v2"]
|
|
87
87
|
},
|
|
88
88
|
{
|
|
89
89
|
"package": "bcp/events",
|
|
@@ -91,7 +91,7 @@
|
|
|
91
91
|
"environment": "server",
|
|
92
92
|
"route": "/docs/api-reference#bcp-events",
|
|
93
93
|
"summary": "Transactional outbox and event delivery APIs with SQL persistence, dispatcher leases, retries, stale recovery, queue handoff and in-process event bus delivery.",
|
|
94
|
-
"guides": ["/docs/transactional-outbox-events", "/docs/database", "/docs/durable-jobs", "/docs/realtime-platform", "/docs/testing-platform", "/docs/observability-v3", "/docs/deployment-platform-v2", "/docs/application-platform", "/docs/service-container"]
|
|
94
|
+
"guides": ["/docs/transactional-outbox-events", "/docs/database", "/docs/durable-jobs", "/docs/realtime-platform", "/docs/testing-platform", "/docs/observability-v3", "/docs/deployment-platform-v2", "/docs/application-platform", "/docs/service-container", "/docs/module-system-v2"]
|
|
95
95
|
},
|
|
96
96
|
{
|
|
97
97
|
"package": "bcp/realtime",
|
|
@@ -99,7 +99,7 @@
|
|
|
99
99
|
"environment": "server",
|
|
100
100
|
"route": "/docs/api-reference#bcp-realtime",
|
|
101
101
|
"summary": "Realtime channels, cross-hub broker delivery, presence, channel authorization, WebSocket adapter integration, heartbeat handling and built-in Server-Sent Events responses.",
|
|
102
|
-
"guides": ["/docs/realtime-platform", "/docs/authentication", "/docs/testing-platform", "/docs/observability-v3", "/docs/deployment-platform-v2", "/docs/application-platform", "/docs/service-container"]
|
|
102
|
+
"guides": ["/docs/realtime-platform", "/docs/authentication", "/docs/testing-platform", "/docs/observability-v3", "/docs/deployment-platform-v2", "/docs/application-platform", "/docs/service-container", "/docs/module-system-v2"]
|
|
103
103
|
},
|
|
104
104
|
{
|
|
105
105
|
"package": "bcp/testing",
|
|
@@ -107,15 +107,15 @@
|
|
|
107
107
|
"environment": "server",
|
|
108
108
|
"route": "/docs/api-reference#bcp-testing",
|
|
109
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
|
-
"guides": ["/docs/testing-platform", "/docs/authentication", "/docs/database", "/docs/durable-jobs", "/docs/workflow-orchestration", "/docs/transactional-outbox-events", "/docs/realtime-platform", "/docs/observability-v3", "/docs/application-platform", "/docs/service-container"]
|
|
110
|
+
"guides": ["/docs/testing-platform", "/docs/authentication", "/docs/database", "/docs/durable-jobs", "/docs/workflow-orchestration", "/docs/transactional-outbox-events", "/docs/realtime-platform", "/docs/observability-v3", "/docs/application-platform", "/docs/service-container", "/docs/module-system-v2"]
|
|
111
111
|
},
|
|
112
112
|
{
|
|
113
113
|
"package": "bcp/plugins",
|
|
114
114
|
"source": "packages/client/src/plugins.ts",
|
|
115
115
|
"environment": "server",
|
|
116
116
|
"route": "/docs/api-reference#bcp-plugins",
|
|
117
|
-
"summary": "Plugin
|
|
118
|
-
"guides": ["/docs/plugin-module-platform", "/docs/configuration", "/docs/testing-platform", "/docs/observability-v3", "/docs/deployment-platform-v2", "/docs/application-platform", "/docs/service-container"]
|
|
117
|
+
"summary": "Plugin composition with dependency ordering, lifecycle hooks, typed config parsing, shared services and asynchronous extension hooks. Legacy plugin-group modules remain supported.",
|
|
118
|
+
"guides": ["/docs/plugin-module-platform", "/docs/module-system-v2", "/docs/configuration", "/docs/testing-platform", "/docs/observability-v3", "/docs/deployment-platform-v2", "/docs/application-platform", "/docs/service-container"]
|
|
119
119
|
},
|
|
120
120
|
{
|
|
121
121
|
"package": "bcp/observability",
|
|
@@ -131,7 +131,7 @@
|
|
|
131
131
|
"environment": "server",
|
|
132
132
|
"route": "/docs/api-reference#bcp-deployment",
|
|
133
133
|
"summary": "Deployment Platform v2 runtime lifecycle with resource startup/shutdown ordering, readiness, diagnostics, deployment metadata, signal handling and framework shutdown-hook integration.",
|
|
134
|
-
"guides": ["/docs/deployment-platform-v2", "/docs/application-packaging", "/docs/production-hardening", "/docs/observability-v3", "/docs/application-platform", "/docs/service-container"]
|
|
134
|
+
"guides": ["/docs/deployment-platform-v2", "/docs/application-packaging", "/docs/production-hardening", "/docs/observability-v3", "/docs/application-platform", "/docs/service-container", "/docs/module-system-v2"]
|
|
135
135
|
},
|
|
136
136
|
{
|
|
137
137
|
"package": "bcp/container",
|
|
@@ -139,15 +139,23 @@
|
|
|
139
139
|
"environment": "server",
|
|
140
140
|
"route": "/docs/api-reference#bcp-container",
|
|
141
141
|
"summary": "Typed dependency injection and service container with value/factory/class providers, singleton/scoped/transient lifetimes, child scopes, test overrides, dependency graph diagnostics, circular-dependency detection and reverse disposal.",
|
|
142
|
-
"guides": ["/docs/service-container", "/docs/application-platform", "/docs/testing-platform", "/docs/migration-0.3"]
|
|
142
|
+
"guides": ["/docs/service-container", "/docs/module-system-v2", "/docs/application-platform", "/docs/testing-platform", "/docs/migration-0.3"]
|
|
143
|
+
},
|
|
144
|
+
{
|
|
145
|
+
"package": "bcp/modules",
|
|
146
|
+
"source": "packages/client/src/modules.ts",
|
|
147
|
+
"environment": "server",
|
|
148
|
+
"route": "/docs/api-reference#bcp-modules",
|
|
149
|
+
"summary": "Module System v2 definitions and composition with dependency imports, DI provider exports/re-exports, plugins, shared services, deployment resources, lifecycle hooks, diagnostics and application integration.",
|
|
150
|
+
"guides": ["/docs/module-system-v2", "/docs/application-platform", "/docs/service-container", "/docs/plugin-module-platform", "/docs/migration-0.3"]
|
|
143
151
|
},
|
|
144
152
|
{
|
|
145
153
|
"package": "bcp/application",
|
|
146
154
|
"source": "packages/client/src/application.ts",
|
|
147
155
|
"environment": "server",
|
|
148
156
|
"route": "/docs/api-reference#bcp-application",
|
|
149
|
-
"summary": "Application Platform composition root for typed app config, dependency injection, legacy shared services
|
|
150
|
-
"guides": ["/docs/application-platform", "/docs/service-container", "/docs/plugin-module-platform", "/docs/deployment-platform-v2", "/docs/observability-v3", "/docs/migration-0.3"]
|
|
157
|
+
"summary": "Application Platform composition root for typed app config, dependency injection, Module System v2, legacy shared services/plugins/modules, deployment resources, lifecycle ordering, readiness, diagnostics and graceful shutdown.",
|
|
158
|
+
"guides": ["/docs/application-platform", "/docs/module-system-v2", "/docs/service-container", "/docs/plugin-module-platform", "/docs/deployment-platform-v2", "/docs/observability-v3", "/docs/migration-0.3"]
|
|
151
159
|
},
|
|
152
160
|
{
|
|
153
161
|
"package": "bcp/server",
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schemaVersion": 1,
|
|
3
3
|
"framework": "bcp",
|
|
4
|
-
"versionTarget": "0.3.
|
|
4
|
+
"versionTarget": "0.3.2",
|
|
5
5
|
"releaseState": "unreleased",
|
|
6
6
|
"sections": [
|
|
7
7
|
{
|
|
@@ -58,10 +58,11 @@
|
|
|
58
58
|
{
|
|
59
59
|
"id": "runtime",
|
|
60
60
|
"title": "Runtime & Infrastructure",
|
|
61
|
-
"description": "Application composition, dependency injection, middleware, jobs, scheduling, workflows, event delivery, realtime channels, observability, deployment lifecycle, distributed caching, security and production hardening.",
|
|
61
|
+
"description": "Application composition, dependency injection, modules, middleware, jobs, scheduling, workflows, event delivery, realtime channels, observability, deployment lifecycle, distributed caching, security and production hardening.",
|
|
62
62
|
"pages": [
|
|
63
63
|
{ "route": "/docs/application-platform", "source": "application-platform.md", "title": "Application Platform" },
|
|
64
64
|
{ "route": "/docs/service-container", "source": "service-container.md", "title": "Dependency Injection & Service Container" },
|
|
65
|
+
{ "route": "/docs/module-system-v2", "source": "module-system-v2.md", "title": "Module System v2" },
|
|
65
66
|
{ "route": "/docs/middleware", "source": "middleware.md", "title": "Middleware" },
|
|
66
67
|
{ "route": "/docs/hydration", "source": "hydration.md", "title": "Hydration" },
|
|
67
68
|
{ "route": "/docs/development-logging", "source": "development-logging.md", "title": "Logging" },
|
|
@@ -98,7 +99,7 @@
|
|
|
98
99
|
{ "route": "/docs/generators", "source": "generators.md", "title": "Project Generators" },
|
|
99
100
|
{ "route": "/docs/developer-tools", "source": "developer-tools.md", "title": "Doctor & Inspect" },
|
|
100
101
|
{ "route": "/docs/testing-platform", "source": "testing-platform.md", "title": "Testing Platform" },
|
|
101
|
-
{ "route": "/docs/plugin-module-platform", "source": "plugin-module-platform.md", "title": "Plugin & Module Platform" }
|
|
102
|
+
{ "route": "/docs/plugin-module-platform", "source": "plugin-module-platform.md", "title": "Plugin & Legacy Module Platform" }
|
|
102
103
|
]
|
|
103
104
|
},
|
|
104
105
|
{
|
|
@@ -123,7 +124,8 @@
|
|
|
123
124
|
}
|
|
124
125
|
],
|
|
125
126
|
"releases": [
|
|
126
|
-
{ "route": "/releases/0.3.
|
|
127
|
+
{ "route": "/releases/0.3.2", "source": "releases/0.3.2.md", "version": "0.3.2", "state": "unreleased" },
|
|
128
|
+
{ "route": "/releases/0.3.1", "source": "releases/0.3.1.md", "version": "0.3.1" },
|
|
127
129
|
{ "route": "/releases/0.3.0", "source": "releases/0.3.0.md", "version": "0.3.0" },
|
|
128
130
|
{ "route": "/releases/0.2.19", "source": "releases/0.2.19.md", "version": "0.2.19" },
|
|
129
131
|
{ "route": "/releases/0.2.18", "source": "releases/0.2.18.md", "version": "0.2.18" },
|
|
@@ -0,0 +1,386 @@
|
|
|
1
|
+
# BCP Module System v2
|
|
2
|
+
|
|
3
|
+
BCP Framework `0.3.2` adds a server-only application module system on top of the `0.3.0` Application Platform and `0.3.1` dependency-injection container.
|
|
4
|
+
|
|
5
|
+
> **Release state:** unreleased until the complete RC workflow passes, the exact `v0.3.2` release commit is tagged and npm publication succeeds.
|
|
6
|
+
|
|
7
|
+
## Public entrypoint
|
|
8
|
+
|
|
9
|
+
```ts
|
|
10
|
+
import {
|
|
11
|
+
defineModule,
|
|
12
|
+
composeModules,
|
|
13
|
+
} from "bcp/modules";
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
`bcp/modules` is server-only and is blocked from browser/page dependency graphs.
|
|
17
|
+
|
|
18
|
+
The old `defineModule()` exported by `bcp/plugins` remains supported as the legacy plugin-group module API. Module System v2 lives in `bcp/modules` so existing imports do not change behavior.
|
|
19
|
+
|
|
20
|
+
## Basic module
|
|
21
|
+
|
|
22
|
+
```ts
|
|
23
|
+
import {
|
|
24
|
+
defineModule,
|
|
25
|
+
} from "bcp/modules";
|
|
26
|
+
import {
|
|
27
|
+
createServiceToken,
|
|
28
|
+
provideValue,
|
|
29
|
+
} from "bcp/container";
|
|
30
|
+
|
|
31
|
+
export const databaseToken =
|
|
32
|
+
createServiceToken<Database>(
|
|
33
|
+
"database"
|
|
34
|
+
);
|
|
35
|
+
|
|
36
|
+
export const databaseModule =
|
|
37
|
+
defineModule({
|
|
38
|
+
name: "database",
|
|
39
|
+
providers: [
|
|
40
|
+
provideValue(
|
|
41
|
+
databaseToken,
|
|
42
|
+
database
|
|
43
|
+
),
|
|
44
|
+
],
|
|
45
|
+
exports: [
|
|
46
|
+
databaseToken,
|
|
47
|
+
],
|
|
48
|
+
});
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
Pass modules to the application composition root:
|
|
52
|
+
|
|
53
|
+
```ts
|
|
54
|
+
import {
|
|
55
|
+
createApp,
|
|
56
|
+
} from "bcp/application";
|
|
57
|
+
|
|
58
|
+
export const app =
|
|
59
|
+
createApp({
|
|
60
|
+
name: "orders-api",
|
|
61
|
+
modules: [
|
|
62
|
+
databaseModule,
|
|
63
|
+
],
|
|
64
|
+
});
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
## Imports and dependency ordering
|
|
68
|
+
|
|
69
|
+
Modules can import other v2 modules:
|
|
70
|
+
|
|
71
|
+
```ts
|
|
72
|
+
export const ordersModule =
|
|
73
|
+
defineModule({
|
|
74
|
+
name: "orders",
|
|
75
|
+
imports: [
|
|
76
|
+
databaseModule,
|
|
77
|
+
],
|
|
78
|
+
});
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
The graph is resolved dependency-first:
|
|
82
|
+
|
|
83
|
+
```text
|
|
84
|
+
database
|
|
85
|
+
↓
|
|
86
|
+
orders
|
|
87
|
+
↓
|
|
88
|
+
application
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
Repeated references to the same module definition are de-duplicated. Two different definitions using the same module name are rejected. Circular imports are rejected with `ModuleDependencyError`.
|
|
92
|
+
|
|
93
|
+
## Providers and exports
|
|
94
|
+
|
|
95
|
+
A module can own DI providers:
|
|
96
|
+
|
|
97
|
+
```ts
|
|
98
|
+
const repositoryToken =
|
|
99
|
+
createServiceToken<OrderRepository>(
|
|
100
|
+
"orders.repository"
|
|
101
|
+
);
|
|
102
|
+
|
|
103
|
+
export const ordersModule =
|
|
104
|
+
defineModule({
|
|
105
|
+
name: "orders",
|
|
106
|
+
imports: [
|
|
107
|
+
databaseModule,
|
|
108
|
+
],
|
|
109
|
+
providers: [
|
|
110
|
+
provideFactory(
|
|
111
|
+
repositoryToken,
|
|
112
|
+
[
|
|
113
|
+
databaseToken,
|
|
114
|
+
] as const,
|
|
115
|
+
(_context, [database]) =>
|
|
116
|
+
new OrderRepository(
|
|
117
|
+
database
|
|
118
|
+
)
|
|
119
|
+
),
|
|
120
|
+
],
|
|
121
|
+
exports: [
|
|
122
|
+
repositoryToken,
|
|
123
|
+
],
|
|
124
|
+
});
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
An exported token must either:
|
|
128
|
+
|
|
129
|
+
- be provided by the module itself; or
|
|
130
|
+
- be exported by one of its imported modules.
|
|
131
|
+
|
|
132
|
+
That allows explicit re-export:
|
|
133
|
+
|
|
134
|
+
```ts
|
|
135
|
+
export const applicationDataModule =
|
|
136
|
+
defineModule({
|
|
137
|
+
name: "application-data",
|
|
138
|
+
imports: [
|
|
139
|
+
databaseModule,
|
|
140
|
+
],
|
|
141
|
+
exports: [
|
|
142
|
+
databaseToken,
|
|
143
|
+
],
|
|
144
|
+
});
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
The current `0.3.2` runtime uses the application container as the physical provider store. Export metadata defines the reviewed module boundary and is available for diagnostics/introspection; it does not create a second DI container per module.
|
|
148
|
+
|
|
149
|
+
## Plugins
|
|
150
|
+
|
|
151
|
+
Modules may contribute existing BCP plugins:
|
|
152
|
+
|
|
153
|
+
```ts
|
|
154
|
+
const auditPlugin =
|
|
155
|
+
definePlugin({
|
|
156
|
+
name: "audit",
|
|
157
|
+
});
|
|
158
|
+
|
|
159
|
+
export const auditModule =
|
|
160
|
+
defineModule({
|
|
161
|
+
name: "audit-module",
|
|
162
|
+
plugins: [
|
|
163
|
+
auditPlugin,
|
|
164
|
+
],
|
|
165
|
+
});
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
All module plugins are composed into the application Plugin Host before deployment resources start.
|
|
169
|
+
|
|
170
|
+
## Shared legacy services
|
|
171
|
+
|
|
172
|
+
For compatibility with `bcp/plugins`, a module may contribute entries to the legacy shared service registry:
|
|
173
|
+
|
|
174
|
+
```ts
|
|
175
|
+
export const featureModule =
|
|
176
|
+
defineModule({
|
|
177
|
+
name: "feature",
|
|
178
|
+
services: [
|
|
179
|
+
[
|
|
180
|
+
"feature-flags",
|
|
181
|
+
featureFlags,
|
|
182
|
+
],
|
|
183
|
+
],
|
|
184
|
+
});
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
New typed dependencies should generally prefer `bcp/container` providers/tokens. `services` exists for interoperability with existing plugins.
|
|
188
|
+
|
|
189
|
+
## Resources
|
|
190
|
+
|
|
191
|
+
Modules can own Deployment Platform resources:
|
|
192
|
+
|
|
193
|
+
```ts
|
|
194
|
+
export const jobsModule =
|
|
195
|
+
defineModule({
|
|
196
|
+
name: "jobs",
|
|
197
|
+
resources: [
|
|
198
|
+
{
|
|
199
|
+
name: "jobs-worker",
|
|
200
|
+
|
|
201
|
+
start() {
|
|
202
|
+
return worker.start();
|
|
203
|
+
},
|
|
204
|
+
|
|
205
|
+
ready() {
|
|
206
|
+
return worker.ready;
|
|
207
|
+
},
|
|
208
|
+
|
|
209
|
+
stop() {
|
|
210
|
+
return worker.stop();
|
|
211
|
+
},
|
|
212
|
+
},
|
|
213
|
+
],
|
|
214
|
+
});
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
Resources from imported modules are registered before resources from importing modules.
|
|
218
|
+
|
|
219
|
+
## Module lifecycle
|
|
220
|
+
|
|
221
|
+
Each module may define:
|
|
222
|
+
|
|
223
|
+
```text
|
|
224
|
+
setup
|
|
225
|
+
start
|
|
226
|
+
stop
|
|
227
|
+
dispose
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
Example:
|
|
231
|
+
|
|
232
|
+
```ts
|
|
233
|
+
export const mailModule =
|
|
234
|
+
defineModule({
|
|
235
|
+
name: "mail",
|
|
236
|
+
|
|
237
|
+
setup(context) {
|
|
238
|
+
// Providers/services are already registered.
|
|
239
|
+
},
|
|
240
|
+
|
|
241
|
+
start(context) {
|
|
242
|
+
// Module resources and imported modules are available.
|
|
243
|
+
},
|
|
244
|
+
|
|
245
|
+
stop(context) {
|
|
246
|
+
// Stop module-level work before its resources disappear.
|
|
247
|
+
},
|
|
248
|
+
|
|
249
|
+
dispose(context) {
|
|
250
|
+
// Release module-only in-process state.
|
|
251
|
+
},
|
|
252
|
+
});
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
For each module, its deployment resources are registered before its lifecycle resource. Therefore startup is:
|
|
256
|
+
|
|
257
|
+
```text
|
|
258
|
+
imported module resources/lifecycle
|
|
259
|
+
↓
|
|
260
|
+
module resources
|
|
261
|
+
↓
|
|
262
|
+
module setup/start
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
Shutdown is the reverse:
|
|
266
|
+
|
|
267
|
+
```text
|
|
268
|
+
module stop/dispose
|
|
269
|
+
↓
|
|
270
|
+
module resources stop (reverse)
|
|
271
|
+
↓
|
|
272
|
+
imported module stop/dispose
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
If `setup()` or `start()` fails, Module System v2 runs that module's `dispose()` before propagating the startup error. Deployment Platform then rolls back resources/modules that were already started earlier.
|
|
276
|
+
|
|
277
|
+
Lifecycle errors use `ModuleLifecycleError`.
|
|
278
|
+
|
|
279
|
+
## Typed module config
|
|
280
|
+
|
|
281
|
+
Modules support parser functions or schema objects with `parse()`:
|
|
282
|
+
|
|
283
|
+
```ts
|
|
284
|
+
export const mailModule =
|
|
285
|
+
defineModule({
|
|
286
|
+
name: "mail",
|
|
287
|
+
config: {
|
|
288
|
+
from:
|
|
289
|
+
process.env.MAIL_FROM,
|
|
290
|
+
},
|
|
291
|
+
schema: {
|
|
292
|
+
parse(value) {
|
|
293
|
+
const raw =
|
|
294
|
+
value as {
|
|
295
|
+
from?: string;
|
|
296
|
+
};
|
|
297
|
+
|
|
298
|
+
if (!raw.from) {
|
|
299
|
+
throw new Error(
|
|
300
|
+
"MAIL_FROM is required"
|
|
301
|
+
);
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
return {
|
|
305
|
+
from: raw.from,
|
|
306
|
+
};
|
|
307
|
+
},
|
|
308
|
+
},
|
|
309
|
+
start(context) {
|
|
310
|
+
console.log(
|
|
311
|
+
context.config.from
|
|
312
|
+
);
|
|
313
|
+
},
|
|
314
|
+
});
|
|
315
|
+
```
|
|
316
|
+
|
|
317
|
+
## Composition diagnostics
|
|
318
|
+
|
|
319
|
+
Application instances expose the resolved composition:
|
|
320
|
+
|
|
321
|
+
```ts
|
|
322
|
+
app.modules.records();
|
|
323
|
+
```
|
|
324
|
+
|
|
325
|
+
A record includes:
|
|
326
|
+
|
|
327
|
+
```text
|
|
328
|
+
name
|
|
329
|
+
version
|
|
330
|
+
imports
|
|
331
|
+
providers
|
|
332
|
+
exports
|
|
333
|
+
plugins
|
|
334
|
+
resources
|
|
335
|
+
```
|
|
336
|
+
|
|
337
|
+
Inspect one module's exports:
|
|
338
|
+
|
|
339
|
+
```ts
|
|
340
|
+
app.modules.exportedTokens(
|
|
341
|
+
"orders"
|
|
342
|
+
);
|
|
343
|
+
```
|
|
344
|
+
|
|
345
|
+
Application diagnostics also include the module records.
|
|
346
|
+
|
|
347
|
+
## Legacy plugin modules
|
|
348
|
+
|
|
349
|
+
Existing code remains valid:
|
|
350
|
+
|
|
351
|
+
```ts
|
|
352
|
+
import {
|
|
353
|
+
defineModule,
|
|
354
|
+
} from "bcp/plugins";
|
|
355
|
+
|
|
356
|
+
const legacy =
|
|
357
|
+
defineModule({
|
|
358
|
+
name: "legacy",
|
|
359
|
+
plugins: [
|
|
360
|
+
plugin,
|
|
361
|
+
],
|
|
362
|
+
});
|
|
363
|
+
```
|
|
364
|
+
|
|
365
|
+
`createApp({ modules: [...] })` accepts both legacy plugin modules and Module System v2 definitions. The two formats are distinguished by the v2 module marker created by `bcp/modules` `defineModule()`.
|
|
366
|
+
|
|
367
|
+
## Package/runtime contract
|
|
368
|
+
|
|
369
|
+
Prepared npm packages expose:
|
|
370
|
+
|
|
371
|
+
```text
|
|
372
|
+
bcp/modules -> packages/client/src/modules.mjs
|
|
373
|
+
```
|
|
374
|
+
|
|
375
|
+
Types remain in `packages/client/src/modules.ts`, and browser builds resolve to the standard server-only poison module.
|
|
376
|
+
|
|
377
|
+
## Compatibility
|
|
378
|
+
|
|
379
|
+
`0.3.2` is additive relative to `0.3.1`:
|
|
380
|
+
|
|
381
|
+
- existing `bcp/plugins` module behavior remains available;
|
|
382
|
+
- existing `createApp()` definitions without v2 modules behave as before;
|
|
383
|
+
- `bcp/modules` is a new public entrypoint;
|
|
384
|
+
- `ApplicationContext` and `Application` gain the additive `modules` composition view.
|
|
385
|
+
|
|
386
|
+
No intentional breaking change is introduced from `0.3.1`.
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schemaVersion": 1,
|
|
3
3
|
"framework": "bcp",
|
|
4
|
-
"version": "0.3.
|
|
4
|
+
"version": "0.3.2",
|
|
5
5
|
"releaseState": "unreleased",
|
|
6
|
-
"baseline": "
|
|
6
|
+
"baseline": "module-system-v2",
|
|
7
7
|
"runtime": {
|
|
8
8
|
"node": ">=24.11.0",
|
|
9
9
|
"react": "19",
|
|
@@ -28,6 +28,7 @@
|
|
|
28
28
|
"bcp/observability",
|
|
29
29
|
"bcp/deployment",
|
|
30
30
|
"bcp/container",
|
|
31
|
+
"bcp/modules",
|
|
31
32
|
"bcp/application",
|
|
32
33
|
"bcp/server",
|
|
33
34
|
"bcp/server-only",
|
|
@@ -125,6 +126,19 @@
|
|
|
125
126
|
"serviceReverseDisposal": true,
|
|
126
127
|
"applicationServiceContainer": true,
|
|
127
128
|
"compiledContainerRuntime": true,
|
|
129
|
+
"moduleSystemV2": true,
|
|
130
|
+
"applicationModulesV2": true,
|
|
131
|
+
"moduleDependencyGraph": true,
|
|
132
|
+
"moduleImports": true,
|
|
133
|
+
"moduleExports": true,
|
|
134
|
+
"moduleProviderComposition": true,
|
|
135
|
+
"modulePluginComposition": true,
|
|
136
|
+
"moduleServiceComposition": true,
|
|
137
|
+
"moduleResourceComposition": true,
|
|
138
|
+
"moduleLifecycle": true,
|
|
139
|
+
"moduleConfigSchemas": true,
|
|
140
|
+
"moduleDiagnostics": true,
|
|
141
|
+
"compiledModulesRuntime": true,
|
|
128
142
|
"stabilityApiFreeze": true,
|
|
129
143
|
"apiFreezeSnapshot": true,
|
|
130
144
|
"apiCompatibilityGate": true,
|
|
@@ -260,7 +274,7 @@
|
|
|
260
274
|
"s3-compatible"
|
|
261
275
|
],
|
|
262
276
|
"compatibility": {
|
|
263
|
-
"previousBaseline": "0.3.
|
|
277
|
+
"previousBaseline": "0.3.1",
|
|
264
278
|
"intentionalBreakingChangesFromPreviousBaseline": false,
|
|
265
279
|
"migrationGuide": "migration-0.3.md"
|
|
266
280
|
},
|
|
@@ -275,6 +289,7 @@
|
|
|
275
289
|
"stabilityApiFreeze": "stability-api-freeze.md",
|
|
276
290
|
"applicationPlatform": "application-platform.md",
|
|
277
291
|
"serviceContainer": "service-container.md",
|
|
292
|
+
"moduleSystemV2": "module-system-v2.md",
|
|
278
293
|
"environmentValidation": "environment-validation.md",
|
|
279
294
|
"applicationPackaging": "application-packaging.md",
|
|
280
295
|
"authentication": "authentication.md",
|
|
@@ -293,6 +308,6 @@
|
|
|
293
308
|
"pluginModulePlatform": "plugin-module-platform.md",
|
|
294
309
|
"cachePlatformV2": "cache-platform-v2.md",
|
|
295
310
|
"migrationGuide": "migration-0.3.md",
|
|
296
|
-
"releaseNotes": "releases/0.3.
|
|
311
|
+
"releaseNotes": "releases/0.3.2.md"
|
|
297
312
|
}
|
|
298
313
|
}
|