@chidchanun/bcp 0.1.22 → 0.1.23
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/README.md +41 -9
- package/docs/developer-tools.md +48 -0
- package/docs/development-logging.md +234 -6
- package/docs/releases/0.1.22.md +66 -1
- package/docs/releases/0.1.23.md +131 -0
- package/package.json +3 -2
- package/packages/cli/bin/bcp.mjs +111 -0
- package/packages/client/src/form.tsx +20 -13
- package/packages/client/src/server.ts +15 -0
- package/packages/server/src/dev-hmr.ts +131 -9
- package/packages/server/src/logger.ts +474 -0
package/docs/README.md
CHANGED
|
@@ -4,7 +4,7 @@ This directory is the documentation source of truth for the BCP Framework docume
|
|
|
4
4
|
|
|
5
5
|
The recommended documentation website project name is `bcp-docs`.
|
|
6
6
|
|
|
7
|
-
> Documentation target: BCP Framework `0.1.
|
|
7
|
+
> Documentation target: BCP Framework `0.1.23`
|
|
8
8
|
|
|
9
9
|
## Purpose
|
|
10
10
|
|
|
@@ -65,9 +65,9 @@ The website should not invent API behavior that is not documented or tested in t
|
|
|
65
65
|
| `/docs/middleware` | `middleware.md` | Middleware System v2 and v1 compatibility |
|
|
66
66
|
| `/docs/hydration` | `hydration.md` | SSR/client transform parity, deterministic rendering and Windows line endings |
|
|
67
67
|
| `/docs/developer-tools` | `developer-tools.md` | `bcp doctor`, `bcp inspect` and JSON diagnostics |
|
|
68
|
+
| `/docs/development-logging` | `development-logging.md` | Structured logging, request identity and development observability |
|
|
68
69
|
| `/docs/caching` | `caching.md` | Cache and revalidation |
|
|
69
70
|
| `/docs/security` | `security.md` | Framework security defaults |
|
|
70
|
-
| `/docs/development-logging` | `development-logging.md` | Development request logging |
|
|
71
71
|
|
|
72
72
|
### Releases
|
|
73
73
|
|
|
@@ -76,9 +76,9 @@ Use the files under `docs/releases/` for release pages.
|
|
|
76
76
|
Recommended route format:
|
|
77
77
|
|
|
78
78
|
```text
|
|
79
|
-
/releases/0.1.20
|
|
80
79
|
/releases/0.1.21
|
|
81
80
|
/releases/0.1.22
|
|
81
|
+
/releases/0.1.23
|
|
82
82
|
```
|
|
83
83
|
|
|
84
84
|
The newest release should also be available from `/releases`.
|
|
@@ -155,7 +155,13 @@ Recommended feature groups:
|
|
|
155
155
|
- `bcp doctor` project/runtime diagnostics
|
|
156
156
|
- `bcp inspect` environment/config/route inspection
|
|
157
157
|
- JSON developer-tool output for CI/automation
|
|
158
|
-
- Duplicate React
|
|
158
|
+
- Duplicate React and duplicate BCP installation diagnostics
|
|
159
|
+
- `bcp-framework` Windows-safe CLI alias
|
|
160
|
+
- Structured server logger
|
|
161
|
+
- Request-scoped loggers with request identity
|
|
162
|
+
- Pretty and JSON log formats
|
|
163
|
+
- Configurable log levels
|
|
164
|
+
- Structured development HTTP/SSR timing events
|
|
159
165
|
- Standalone production builds
|
|
160
166
|
- Critical CSS
|
|
161
167
|
- Cache/revalidation
|
|
@@ -170,7 +176,7 @@ Suggested content, not a required exact copy:
|
|
|
170
176
|
BCP Framework
|
|
171
177
|
A React full-stack framework for building server-rendered applications with routing,
|
|
172
178
|
data loading, server mutations, authentication, databases, validation, structured errors,
|
|
173
|
-
middleware and production tooling.
|
|
179
|
+
middleware, observability and production tooling.
|
|
174
180
|
```
|
|
175
181
|
|
|
176
182
|
Primary actions:
|
|
@@ -216,17 +222,17 @@ Runtime
|
|
|
216
222
|
Middleware
|
|
217
223
|
Hydration
|
|
218
224
|
Developer Tools
|
|
225
|
+
Logging & Observability
|
|
219
226
|
Caching
|
|
220
227
|
Security
|
|
221
228
|
|
|
222
229
|
Production
|
|
223
230
|
Deployment
|
|
224
|
-
Development Logging
|
|
225
231
|
|
|
226
232
|
Releases
|
|
233
|
+
0.1.23
|
|
227
234
|
0.1.22
|
|
228
235
|
0.1.21
|
|
229
|
-
0.1.20
|
|
230
236
|
```
|
|
231
237
|
|
|
232
238
|
## Suggested documentation page layout
|
|
@@ -280,6 +286,11 @@ import {
|
|
|
280
286
|
unauthorized,
|
|
281
287
|
} from "bcp/error";
|
|
282
288
|
|
|
289
|
+
import {
|
|
290
|
+
logger,
|
|
291
|
+
requestLogger,
|
|
292
|
+
} from "bcp/server";
|
|
293
|
+
|
|
283
294
|
import {
|
|
284
295
|
type MiddlewarePipelineHandler,
|
|
285
296
|
} from "bcp/middleware";
|
|
@@ -324,6 +335,8 @@ bcp db status
|
|
|
324
335
|
bcp db rollback
|
|
325
336
|
```
|
|
326
337
|
|
|
338
|
+
On Windows systems where Microsoft SQL Server owns the `bcp` executable name, document the equivalent collision-free commands with `bcp-framework`.
|
|
339
|
+
|
|
327
340
|
Project creation:
|
|
328
341
|
|
|
329
342
|
```bash
|
|
@@ -411,16 +424,35 @@ The docs website should surface:
|
|
|
411
424
|
- PASS/WARN/FAIL health checks,
|
|
412
425
|
- non-zero exit codes for blocking doctor failures,
|
|
413
426
|
- React / React DOM version and package-root parity,
|
|
427
|
+
- duplicate `bcp` / `@chidchanun/bcp` installation detection,
|
|
414
428
|
- config and development environment inspection,
|
|
415
429
|
- page/API route summaries,
|
|
416
430
|
- `--json` output for CI and automation,
|
|
417
|
-
- the recommendation to verify local releases from packed `.tgz` artifacts rather than linked staging directories.
|
|
431
|
+
- the recommendation to verify local releases from packed `.tgz` artifacts installed under the existing `bcp` dependency key rather than linked staging directories.
|
|
418
432
|
|
|
419
433
|
See `developer-tools.md` for the full command reference.
|
|
420
434
|
|
|
435
|
+
## Logging and observability documentation priority
|
|
436
|
+
|
|
437
|
+
BCP 0.1.23 adds the structured logging foundation through `bcp/server`.
|
|
438
|
+
|
|
439
|
+
The docs website should surface:
|
|
440
|
+
|
|
441
|
+
- `logger.debug/info/warn/error`,
|
|
442
|
+
- `createLogger()` and child loggers,
|
|
443
|
+
- `requestLogger()` and its request ID/method/path bindings,
|
|
444
|
+
- `attachRequestId()` for `X-Request-Id` response propagation,
|
|
445
|
+
- `BCP_LOG_LEVEL`,
|
|
446
|
+
- `BCP_LOG_FORMAT=pretty|json`,
|
|
447
|
+
- JSON-safe `Error`, `bigint` and circular value handling,
|
|
448
|
+
- structured `http.request`, `module.import` and `ssr.render` development events,
|
|
449
|
+
- the existing dev noise filter for framework-internal requests.
|
|
450
|
+
|
|
451
|
+
See `development-logging.md` for the complete API and examples.
|
|
452
|
+
|
|
421
453
|
## Release roadmap
|
|
422
454
|
|
|
423
|
-
`0.1.
|
|
455
|
+
`0.1.23` is the Logging & Observability milestone. The next planned milestone is `0.1.24` — File Upload foundation, followed by Background Jobs, Testing Utilities, Production Build Hardening and Plugin Architecture unless milestones are regrouped.
|
|
424
456
|
|
|
425
457
|
## Release workflow for documentation
|
|
426
458
|
|
package/docs/developer-tools.md
CHANGED
|
@@ -2,6 +2,37 @@
|
|
|
2
2
|
|
|
3
3
|
BCP Framework 0.1.22 adds project diagnostics and runtime inspection commands for debugging a BCP application without starting the development server.
|
|
4
4
|
|
|
5
|
+
## CLI executable names
|
|
6
|
+
|
|
7
|
+
The published BCP package exposes two executable names that point to the same CLI:
|
|
8
|
+
|
|
9
|
+
```text
|
|
10
|
+
bcp
|
|
11
|
+
bcp-framework
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
`bcp` remains the primary and backward-compatible command.
|
|
15
|
+
|
|
16
|
+
On Windows, Microsoft SQL Server also installs a native utility named `bcp.exe`. When that executable appears earlier on `PATH`, typing `bcp` in PowerShell can launch the SQL Server utility instead of BCP Framework.
|
|
17
|
+
|
|
18
|
+
Use the Windows-safe alias in that situation:
|
|
19
|
+
|
|
20
|
+
```powershell
|
|
21
|
+
bcp-framework doctor
|
|
22
|
+
bcp-framework inspect
|
|
23
|
+
bcp-framework dev
|
|
24
|
+
bcp-framework build
|
|
25
|
+
bcp-framework update
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
You can also explicitly run the project-local executable with npm:
|
|
29
|
+
|
|
30
|
+
```powershell
|
|
31
|
+
npm exec -- bcp doctor
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
BCP application npm scripts can continue using `bcp dev`, `bcp build`, and other existing commands because npm places the project's `node_modules/.bin` directory on the script `PATH` before system executables.
|
|
35
|
+
|
|
5
36
|
## `bcp doctor`
|
|
6
37
|
|
|
7
38
|
Run a health check from the application root:
|
|
@@ -54,6 +85,23 @@ Invalid hook call. Hooks can only be called inside of the body of a function com
|
|
|
54
85
|
|
|
55
86
|
For local release testing, install the packed `.tgz` artifact instead of linking `.package/bcp` directly into another project. A packed package lets the BCP peer dependencies resolve from the application's normal `node_modules` tree.
|
|
56
87
|
|
|
88
|
+
### Duplicate BCP package protection
|
|
89
|
+
|
|
90
|
+
A BCP application must not load `node_modules/bcp` and `node_modules/@chidchanun/bcp` as two separate framework copies.
|
|
91
|
+
|
|
92
|
+
The CLI performs a startup preflight. If both package roots exist, runtime commands such as `dev`, `build`, and `start` stop before SSR starts. Two framework copies create separate React contexts, which can make APIs such as `useLoaderData()` incorrectly report missing loader data even when the route loader executed successfully.
|
|
93
|
+
|
|
94
|
+
For local release verification, install the tarball under the existing `bcp` dependency key instead of adding the scoped package beside it:
|
|
95
|
+
|
|
96
|
+
```powershell
|
|
97
|
+
npm install `
|
|
98
|
+
--no-save `
|
|
99
|
+
--package-lock=false `
|
|
100
|
+
"bcp@file:D:\bcp-framework\.package\artifacts\chidchanun-bcp-0.1.22.tgz"
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
The installed folder remains `node_modules/bcp` even when the package inside the tarball is published as `@chidchanun/bcp`.
|
|
104
|
+
|
|
57
105
|
## `bcp inspect`
|
|
58
106
|
|
|
59
107
|
Use `inspect` when you want a deterministic snapshot of the project inputs BCP sees:
|
|
@@ -1,13 +1,241 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Logging and observability
|
|
2
2
|
|
|
3
|
-
BCP
|
|
3
|
+
BCP Framework 0.1.23 adds a structured server logger and upgrades development request timing output while keeping framework-internal browser/bootstrap traffic quiet by default.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
## Server logger
|
|
6
|
+
|
|
7
|
+
Import logging APIs from the server-only `bcp/server` entry:
|
|
8
|
+
|
|
9
|
+
```ts
|
|
10
|
+
import {
|
|
11
|
+
logger,
|
|
12
|
+
} from "bcp/server";
|
|
13
|
+
|
|
14
|
+
logger.info(
|
|
15
|
+
"Application started",
|
|
16
|
+
{
|
|
17
|
+
service: "catalog",
|
|
18
|
+
}
|
|
19
|
+
);
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
Available levels are:
|
|
23
|
+
|
|
24
|
+
```text
|
|
25
|
+
debug
|
|
26
|
+
info
|
|
27
|
+
warn
|
|
28
|
+
error
|
|
29
|
+
silent
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
The default level is `info`.
|
|
33
|
+
|
|
34
|
+
Structured fields can contain strings, numbers, booleans, objects, arrays, `Error` values and `bigint` values. Circular references are replaced with `[Circular]` rather than crashing the logger.
|
|
35
|
+
|
|
36
|
+
## Request-scoped logging
|
|
37
|
+
|
|
38
|
+
Use `requestLogger()` while handling an API route, loader, guard or form action:
|
|
39
|
+
|
|
40
|
+
```ts
|
|
41
|
+
import {
|
|
42
|
+
requestLogger,
|
|
43
|
+
} from "bcp/server";
|
|
44
|
+
|
|
45
|
+
export async function loader() {
|
|
46
|
+
const log =
|
|
47
|
+
await requestLogger({
|
|
48
|
+
feature: "categories",
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
log.info(
|
|
52
|
+
"Loading categories"
|
|
53
|
+
);
|
|
54
|
+
|
|
55
|
+
return {
|
|
56
|
+
items: [],
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
The returned child logger automatically binds the current request identity:
|
|
62
|
+
|
|
63
|
+
```text
|
|
64
|
+
requestId
|
|
65
|
+
method
|
|
66
|
+
path
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
`requestId` uses the same request-scoped value exposed by `requestId()`: a valid incoming `X-Request-Id` is reused, otherwise BCP creates a UUID for the request.
|
|
70
|
+
|
|
71
|
+
## Response request ID
|
|
72
|
+
|
|
73
|
+
When an application wants to return the request identity to a caller, wrap a response with `attachRequestId()`:
|
|
74
|
+
|
|
75
|
+
```ts
|
|
76
|
+
import {
|
|
77
|
+
attachRequestId,
|
|
78
|
+
json,
|
|
79
|
+
} from "bcp/server";
|
|
80
|
+
|
|
81
|
+
export async function GET() {
|
|
82
|
+
return attachRequestId(
|
|
83
|
+
json({
|
|
84
|
+
ok: true,
|
|
85
|
+
})
|
|
86
|
+
);
|
|
87
|
+
}
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
The returned response includes:
|
|
6
91
|
|
|
7
92
|
```text
|
|
8
|
-
|
|
93
|
+
X-Request-Id: <current request id>
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
This helper preserves the original response status, status text, body and headers.
|
|
97
|
+
|
|
98
|
+
## Child loggers
|
|
99
|
+
|
|
100
|
+
Bind shared fields once with `child()`:
|
|
101
|
+
|
|
102
|
+
```ts
|
|
103
|
+
import {
|
|
104
|
+
logger,
|
|
105
|
+
} from "bcp/server";
|
|
106
|
+
|
|
107
|
+
const dbLog =
|
|
108
|
+
logger.child({
|
|
109
|
+
component: "database",
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
dbLog.debug(
|
|
113
|
+
"Executing query",
|
|
114
|
+
{
|
|
115
|
+
operation: "users.list",
|
|
116
|
+
}
|
|
117
|
+
);
|
|
9
118
|
```
|
|
10
119
|
|
|
11
|
-
|
|
120
|
+
Child bindings are inherited by further child loggers.
|
|
121
|
+
|
|
122
|
+
## Log level
|
|
123
|
+
|
|
124
|
+
Set the minimum log level with:
|
|
125
|
+
|
|
126
|
+
```bash
|
|
127
|
+
BCP_LOG_LEVEL=debug
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
Supported values:
|
|
131
|
+
|
|
132
|
+
```text
|
|
133
|
+
debug
|
|
134
|
+
info
|
|
135
|
+
warn
|
|
136
|
+
error
|
|
137
|
+
silent
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
Invalid or missing values fall back to `info`.
|
|
141
|
+
|
|
142
|
+
Use `debug` during framework/application diagnostics to see development SSR and module-import timing events.
|
|
143
|
+
|
|
144
|
+
## Log format
|
|
12
145
|
|
|
13
|
-
|
|
146
|
+
Human-readable output is the default:
|
|
147
|
+
|
|
148
|
+
```bash
|
|
149
|
+
BCP_LOG_FORMAT=pretty
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
Example:
|
|
153
|
+
|
|
154
|
+
```text
|
|
155
|
+
[2026-08-27T10:00:00.000Z] [INFO] [bcp] User loaded userId=42
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
For containers, log collectors and CI systems use JSON lines:
|
|
159
|
+
|
|
160
|
+
```bash
|
|
161
|
+
BCP_LOG_FORMAT=json
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
Example:
|
|
165
|
+
|
|
166
|
+
```json
|
|
167
|
+
{"timestamp":"2026-08-27T10:00:00.000Z","level":"info","logger":"bcp","message":"User loaded","userId":42}
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
Each log call emits exactly one line.
|
|
171
|
+
|
|
172
|
+
## Development HTTP logging
|
|
173
|
+
|
|
174
|
+
Development request output remains focused on application API traffic. BCP suppresses request-style logs for framework and browser bootstrap traffic such as:
|
|
175
|
+
|
|
176
|
+
```text
|
|
177
|
+
/_bcp/*
|
|
178
|
+
/api/bcp-styles
|
|
179
|
+
page/document requests
|
|
180
|
+
public static assets
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
An application API request is converted into the structured logger format. With pretty output it resembles:
|
|
184
|
+
|
|
185
|
+
```text
|
|
186
|
+
[2026-08-27T10:00:00.000Z] [INFO] [bcp-dev] HTTP request event=http.request method=GET path=/api/users status=200 durationMs=1.24
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
With `BCP_LOG_FORMAT=json` the same event is emitted as one JSON object containing:
|
|
190
|
+
|
|
191
|
+
```text
|
|
192
|
+
event=http.request
|
|
193
|
+
method
|
|
194
|
+
path
|
|
195
|
+
status
|
|
196
|
+
durationMs
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
Existing development `Import: ...ms` and `SSR: ...ms` measurements are converted into `debug` events:
|
|
200
|
+
|
|
201
|
+
```text
|
|
202
|
+
module.import
|
|
203
|
+
ssr.render
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
They are therefore visible when `BCP_LOG_LEVEL=debug` and stay out of normal `info` output.
|
|
207
|
+
|
|
208
|
+
## Errors
|
|
209
|
+
|
|
210
|
+
Pass an `Error` as a structured field:
|
|
211
|
+
|
|
212
|
+
```ts
|
|
213
|
+
try {
|
|
214
|
+
// ...
|
|
215
|
+
} catch (error) {
|
|
216
|
+
logger.error(
|
|
217
|
+
"Operation failed",
|
|
218
|
+
{
|
|
219
|
+
error,
|
|
220
|
+
}
|
|
221
|
+
);
|
|
222
|
+
}
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
`Error` values are serialized with their name, message, stack and cause when available.
|
|
226
|
+
|
|
227
|
+
## Environment example
|
|
228
|
+
|
|
229
|
+
A development `.env.local` can use:
|
|
230
|
+
|
|
231
|
+
```text
|
|
232
|
+
BCP_LOG_LEVEL=debug
|
|
233
|
+
BCP_LOG_FORMAT=pretty
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
A production/container environment can use:
|
|
237
|
+
|
|
238
|
+
```text
|
|
239
|
+
BCP_LOG_LEVEL=info
|
|
240
|
+
BCP_LOG_FORMAT=json
|
|
241
|
+
```
|
package/docs/releases/0.1.22.md
CHANGED
|
@@ -12,6 +12,35 @@ BCP 0.1.22 adds the first dedicated Developer Tools milestone.
|
|
|
12
12
|
- Added route conflict and client-boundary validation without starting the dev server.
|
|
13
13
|
- Added development environment diagnostics without printing private environment values.
|
|
14
14
|
- Added unit coverage for CLI parsing, version checks, missing-project diagnostics and deterministic inspection output.
|
|
15
|
+
- Added the `bcp-framework` executable alias for Windows systems where the `bcp` command is already occupied by Microsoft SQL Server's `bcp.exe` utility.
|
|
16
|
+
- Fixed `<Form>` SSR so framework runtime rendering no longer depends on a global `React` binding when an application uses the classic JSX transform.
|
|
17
|
+
- Added CLI preflight protection against installing `bcp` and `@chidchanun/bcp` as two separate framework copies, which can split loader/context state across package instances.
|
|
18
|
+
|
|
19
|
+
## CLI executable compatibility
|
|
20
|
+
|
|
21
|
+
The published package now exposes both executable names:
|
|
22
|
+
|
|
23
|
+
```text
|
|
24
|
+
bcp
|
|
25
|
+
bcp-framework
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
Both names execute the same BCP Framework CLI. Existing applications and npm scripts can continue using `bcp` unchanged.
|
|
29
|
+
|
|
30
|
+
On Windows installations that include Microsoft SQL Server tools, use the collision-free alias for direct shell commands:
|
|
31
|
+
|
|
32
|
+
```powershell
|
|
33
|
+
bcp-framework doctor
|
|
34
|
+
bcp-framework inspect
|
|
35
|
+
bcp-framework dev
|
|
36
|
+
bcp-framework build
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
Alternatively, explicitly run the project-local `bcp` executable through npm:
|
|
40
|
+
|
|
41
|
+
```powershell
|
|
42
|
+
npm exec -- bcp doctor
|
|
43
|
+
```
|
|
15
44
|
|
|
16
45
|
## `bcp doctor`
|
|
17
46
|
|
|
@@ -66,11 +95,47 @@ If an application is linked directly to a framework staging directory, the appli
|
|
|
66
95
|
|
|
67
96
|
For local release verification, continue using packed `.tgz` artifacts rather than installing `.package/bcp` as a linked directory.
|
|
68
97
|
|
|
98
|
+
## Duplicate BCP package protection
|
|
99
|
+
|
|
100
|
+
Local tarball verification must keep one BCP package root in the application.
|
|
101
|
+
|
|
102
|
+
Installing a tarball directly when the application already declares an npm alias named `bcp` can leave both of these paths installed:
|
|
103
|
+
|
|
104
|
+
```text
|
|
105
|
+
node_modules/bcp
|
|
106
|
+
node_modules/@chidchanun/bcp
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
That layout is unsafe because application imports can use one `BcpLoaderDataProvider` context while the CLI/SSR runtime uses the other package copy. The visible error can therefore incorrectly say that `useLoaderData()` has no loader data.
|
|
110
|
+
|
|
111
|
+
BCP 0.1.22 now checks this before runtime commands start and fails with an actionable duplicate-install message.
|
|
112
|
+
|
|
113
|
+
For local tarball verification, install the artifact under the existing dependency key:
|
|
114
|
+
|
|
115
|
+
```powershell
|
|
116
|
+
npm install `
|
|
117
|
+
--no-save `
|
|
118
|
+
--package-lock=false `
|
|
119
|
+
"bcp@file:D:\bcp-framework\.package\artifacts\chidchanun-bcp-0.1.22.tgz"
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
## SSR JSX-runtime compatibility
|
|
123
|
+
|
|
124
|
+
Framework runtime components must not inherit JSX runtime assumptions from the consuming application's `tsconfig.json`.
|
|
125
|
+
|
|
126
|
+
`<Form>` now renders its provider and native `<form>` element through `createElement()`. This keeps SSR compatible with both automatic JSX runtime projects and projects that still use the classic JSX transform, where unbound generated `React.createElement(...)` calls would otherwise produce:
|
|
127
|
+
|
|
128
|
+
```text
|
|
129
|
+
ReferenceError: React is not defined
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
Regression coverage includes server rendering and a classic-JSX transform check that rejects implicit `React.createElement` output from the Form runtime source.
|
|
133
|
+
|
|
69
134
|
## Compatibility
|
|
70
135
|
|
|
71
136
|
0.1.22 does not change public rendering, routing, database, authentication, validation, middleware or error-handling APIs.
|
|
72
137
|
|
|
73
|
-
The
|
|
138
|
+
The Developer Tools commands and `bcp-framework` executable alias are additive. Existing BCP applications can continue using current commands unchanged.
|
|
74
139
|
|
|
75
140
|
## Next milestone
|
|
76
141
|
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
# BCP Framework 0.1.23
|
|
2
|
+
|
|
3
|
+
BCP 0.1.23 introduces the Logging & Observability foundation and carries forward the stabilization fixes verified against the BCP documentation application during the 0.1.22 release-candidate cycle.
|
|
4
|
+
|
|
5
|
+
## Highlights
|
|
6
|
+
|
|
7
|
+
- Added structured server logging through `bcp/server`.
|
|
8
|
+
- Added `logger.debug()`, `logger.info()`, `logger.warn()` and `logger.error()`.
|
|
9
|
+
- Added child loggers with persistent structured bindings.
|
|
10
|
+
- Added `requestLogger()` for request-scoped `requestId`, HTTP method and path bindings.
|
|
11
|
+
- Added `attachRequestId()` for explicit `X-Request-Id` response propagation.
|
|
12
|
+
- Added `BCP_LOG_LEVEL=debug|info|warn|error|silent`.
|
|
13
|
+
- Added `BCP_LOG_FORMAT=pretty|json`.
|
|
14
|
+
- Added safe serialization for `Error`, `bigint` and circular structured fields.
|
|
15
|
+
- Development API request logs now flow through the structured logger while framework bootstrap traffic remains filtered.
|
|
16
|
+
- Development module-import and SSR timing lines are normalized into `module.import` and `ssr.render` debug events.
|
|
17
|
+
- Added regression coverage for log filtering, JSON records, error serialization, request-scoped identity and response request IDs.
|
|
18
|
+
|
|
19
|
+
## Server logger
|
|
20
|
+
|
|
21
|
+
```ts
|
|
22
|
+
import {
|
|
23
|
+
logger,
|
|
24
|
+
} from "bcp/server";
|
|
25
|
+
|
|
26
|
+
logger.info(
|
|
27
|
+
"User loaded",
|
|
28
|
+
{
|
|
29
|
+
userId: 42,
|
|
30
|
+
}
|
|
31
|
+
);
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
The default logger reads its level and format from the environment at log time, so normal application configuration can set:
|
|
35
|
+
|
|
36
|
+
```text
|
|
37
|
+
BCP_LOG_LEVEL=info
|
|
38
|
+
BCP_LOG_FORMAT=json
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
## Request-scoped logger
|
|
42
|
+
|
|
43
|
+
```ts
|
|
44
|
+
import {
|
|
45
|
+
requestLogger,
|
|
46
|
+
} from "bcp/server";
|
|
47
|
+
|
|
48
|
+
export async function loader() {
|
|
49
|
+
const log =
|
|
50
|
+
await requestLogger({
|
|
51
|
+
feature: "categories",
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
log.info(
|
|
55
|
+
"Loading categories"
|
|
56
|
+
);
|
|
57
|
+
|
|
58
|
+
return {
|
|
59
|
+
items: [],
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
The child logger binds:
|
|
65
|
+
|
|
66
|
+
```text
|
|
67
|
+
requestId
|
|
68
|
+
method
|
|
69
|
+
path
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
using the same request context already used by `requestId()`, `requestMethod()` and `requestUrl()`.
|
|
73
|
+
|
|
74
|
+
## Request ID response helper
|
|
75
|
+
|
|
76
|
+
```ts
|
|
77
|
+
import {
|
|
78
|
+
attachRequestId,
|
|
79
|
+
json,
|
|
80
|
+
} from "bcp/server";
|
|
81
|
+
|
|
82
|
+
export async function GET() {
|
|
83
|
+
return attachRequestId(
|
|
84
|
+
json({
|
|
85
|
+
ok: true,
|
|
86
|
+
})
|
|
87
|
+
);
|
|
88
|
+
}
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
The response contains `X-Request-Id` with the active request identity.
|
|
92
|
+
|
|
93
|
+
## Development observability
|
|
94
|
+
|
|
95
|
+
Application API request logs retain the existing development noise filter but are now emitted as structured events with:
|
|
96
|
+
|
|
97
|
+
```text
|
|
98
|
+
event=http.request
|
|
99
|
+
method
|
|
100
|
+
path
|
|
101
|
+
status
|
|
102
|
+
durationMs
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
SSR and module import measurements are emitted at `debug` level as:
|
|
106
|
+
|
|
107
|
+
```text
|
|
108
|
+
ssr.render
|
|
109
|
+
module.import
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
Set `BCP_LOG_LEVEL=debug` when profiling development rendering.
|
|
113
|
+
|
|
114
|
+
## Stabilization fixes included
|
|
115
|
+
|
|
116
|
+
The 0.1.23 source line also contains the fixes completed while validating 0.1.22 against `bcp-docs`:
|
|
117
|
+
|
|
118
|
+
- the `bcp-framework` Windows-safe executable alias avoids the Microsoft SQL Server `bcp.exe` command collision,
|
|
119
|
+
- `<Form>` SSR no longer depends on an implicit global `React` binding under classic JSX transforms,
|
|
120
|
+
- the CLI detects duplicate `bcp` / `@chidchanun/bcp` installations before they produce split React contexts or misleading `useLoaderData()` failures,
|
|
121
|
+
- local release verification guidance uses packed tarballs under the existing `bcp` dependency key so only one framework copy is installed.
|
|
122
|
+
|
|
123
|
+
## Compatibility
|
|
124
|
+
|
|
125
|
+
Logging is additive and server-only. Existing rendering, routing, loaders, guards, actions, middleware, validation, database and authentication APIs remain compatible.
|
|
126
|
+
|
|
127
|
+
Existing application code does not need to adopt the logger to upgrade to 0.1.23.
|
|
128
|
+
|
|
129
|
+
## Next milestone
|
|
130
|
+
|
|
131
|
+
The next planned milestone is BCP 0.1.24 — File Upload foundation.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@chidchanun/bcp",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.23",
|
|
4
4
|
"description": "BCP Framework - a React full-stack framework with file-based routing, SSR, APIs, middleware, islands, caching and standalone production builds.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -24,7 +24,8 @@
|
|
|
24
24
|
"node": ">=24.11.0"
|
|
25
25
|
},
|
|
26
26
|
"bin": {
|
|
27
|
-
"bcp": "packages/cli/bin/bcp.mjs"
|
|
27
|
+
"bcp": "packages/cli/bin/bcp.mjs",
|
|
28
|
+
"bcp-framework": "packages/cli/bin/bcp.mjs"
|
|
28
29
|
},
|
|
29
30
|
"exports": {
|
|
30
31
|
".": {
|