create-bcp-app 0.2.12 → 0.2.14
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 +117 -44
- package/package.json +1 -1
- package/template/README.md +98 -40
package/README.md
CHANGED
|
@@ -69,17 +69,17 @@ Select storage provider:
|
|
|
69
69
|
|
|
70
70
|
New projects include `bcp.project.json`.
|
|
71
71
|
|
|
72
|
-
Example for the `0.2.
|
|
72
|
+
Example for the `0.2.14` target:
|
|
73
73
|
|
|
74
74
|
```json
|
|
75
75
|
{
|
|
76
76
|
"schemaVersion": 1,
|
|
77
77
|
"framework": "bcp",
|
|
78
78
|
"projectName": "my-app",
|
|
79
|
-
"frameworkPackage": "npm:@chidchanun/bcp@0.2.
|
|
79
|
+
"frameworkPackage": "npm:@chidchanun/bcp@0.2.14",
|
|
80
80
|
"createdWith": {
|
|
81
81
|
"package": "create-bcp-app",
|
|
82
|
-
"version": "0.2.
|
|
82
|
+
"version": "0.2.14"
|
|
83
83
|
},
|
|
84
84
|
"packageManager": "npm",
|
|
85
85
|
"presets": {
|
|
@@ -167,26 +167,6 @@ export const onboarding =
|
|
|
167
167
|
Applications using the SQL Database Platform can persist integration events in the same transaction as business data:
|
|
168
168
|
|
|
169
169
|
```ts
|
|
170
|
-
import {
|
|
171
|
-
db,
|
|
172
|
-
} from "bcp/database";
|
|
173
|
-
|
|
174
|
-
import {
|
|
175
|
-
createSqlOutboxStore,
|
|
176
|
-
createTransactionalOutbox,
|
|
177
|
-
} from "bcp/events";
|
|
178
|
-
|
|
179
|
-
const outboxStore =
|
|
180
|
-
createSqlOutboxStore({
|
|
181
|
-
database: db,
|
|
182
|
-
driver: "mysql",
|
|
183
|
-
});
|
|
184
|
-
|
|
185
|
-
const outbox =
|
|
186
|
-
createTransactionalOutbox({
|
|
187
|
-
store: outboxStore,
|
|
188
|
-
});
|
|
189
|
-
|
|
190
170
|
await db.transaction(
|
|
191
171
|
async tx => {
|
|
192
172
|
await tx.execute(
|
|
@@ -204,42 +184,135 @@ await db.transaction(
|
|
|
204
184
|
);
|
|
205
185
|
```
|
|
206
186
|
|
|
207
|
-
|
|
187
|
+
After commit, `createOutboxDispatcher()` can hand off events to durable jobs/custom publishers.
|
|
188
|
+
|
|
189
|
+
## Realtime Platform — 0.2.13+
|
|
190
|
+
|
|
191
|
+
Generated applications can add server-side realtime channels without changing the scaffold preset model:
|
|
208
192
|
|
|
209
193
|
```ts
|
|
210
194
|
import {
|
|
211
|
-
|
|
212
|
-
} from "bcp/
|
|
195
|
+
createRealtime,
|
|
196
|
+
} from "bcp/realtime";
|
|
213
197
|
|
|
214
|
-
const
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
198
|
+
export const realtime =
|
|
199
|
+
createRealtime();
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
Channel/room usage:
|
|
203
|
+
|
|
204
|
+
```ts
|
|
205
|
+
const connection =
|
|
206
|
+
await realtime.connect();
|
|
207
|
+
|
|
208
|
+
await connection.join(
|
|
209
|
+
"orders:42"
|
|
210
|
+
);
|
|
211
|
+
|
|
212
|
+
await realtime.broadcast(
|
|
213
|
+
"orders:42",
|
|
214
|
+
"order.updated",
|
|
215
|
+
{
|
|
216
|
+
status: "paid",
|
|
217
|
+
}
|
|
218
|
+
);
|
|
218
219
|
```
|
|
219
220
|
|
|
220
|
-
|
|
221
|
+
BCP does not install a WebSocket library. Adapt your selected provider to `RealtimeSocket`. SSE is available directly through `realtime.sse()`.
|
|
222
|
+
|
|
223
|
+
The memory broker/presence store are local-only. Multi-instance production deployments should provide shared `RealtimeBroker` and `RealtimePresenceStore` implementations.
|
|
224
|
+
|
|
225
|
+
## Testing Platform — 0.2.14+
|
|
226
|
+
|
|
227
|
+
`bcp/testing` adds framework-native test helpers without requiring a specific test runner.
|
|
228
|
+
|
|
229
|
+
Request/route example:
|
|
221
230
|
|
|
222
231
|
```ts
|
|
223
232
|
import {
|
|
224
|
-
|
|
225
|
-
|
|
233
|
+
createRouteTestHandler,
|
|
234
|
+
createTestApp,
|
|
235
|
+
expectResponse,
|
|
236
|
+
} from "bcp/testing";
|
|
237
|
+
|
|
238
|
+
const app =
|
|
239
|
+
createTestApp({
|
|
240
|
+
handler:
|
|
241
|
+
createRouteTestHandler({
|
|
242
|
+
GET() {
|
|
243
|
+
return {
|
|
244
|
+
ok: true,
|
|
245
|
+
};
|
|
246
|
+
},
|
|
247
|
+
}),
|
|
248
|
+
});
|
|
226
249
|
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
250
|
+
await expectResponse(
|
|
251
|
+
await app.get("/api/health")
|
|
252
|
+
)
|
|
253
|
+
.status(200)
|
|
254
|
+
.json({
|
|
255
|
+
ok: true,
|
|
232
256
|
});
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
Create a real signed BCP auth session for authenticated requests:
|
|
260
|
+
|
|
261
|
+
```ts
|
|
262
|
+
import {
|
|
263
|
+
createTestAuthSession,
|
|
264
|
+
} from "bcp/testing";
|
|
265
|
+
|
|
266
|
+
const session =
|
|
267
|
+
await createTestAuthSession(
|
|
268
|
+
{
|
|
269
|
+
id: 42,
|
|
270
|
+
role: "admin",
|
|
271
|
+
},
|
|
272
|
+
{
|
|
273
|
+
secret:
|
|
274
|
+
process.env.BCP_SESSION_SECRET,
|
|
275
|
+
}
|
|
276
|
+
);
|
|
277
|
+
|
|
278
|
+
app.setCookie(
|
|
279
|
+
session.cookieName,
|
|
280
|
+
session.token
|
|
281
|
+
);
|
|
282
|
+
```
|
|
233
283
|
|
|
234
|
-
|
|
235
|
-
|
|
284
|
+
Rollback database tests:
|
|
285
|
+
|
|
286
|
+
```ts
|
|
287
|
+
import {
|
|
288
|
+
withTestTransaction,
|
|
289
|
+
} from "bcp/testing";
|
|
290
|
+
|
|
291
|
+
await withTestTransaction(
|
|
292
|
+
db,
|
|
293
|
+
async tx => {
|
|
294
|
+
await tx.execute(
|
|
295
|
+
"INSERT INTO users ..."
|
|
296
|
+
);
|
|
297
|
+
}
|
|
298
|
+
);
|
|
236
299
|
```
|
|
237
300
|
|
|
238
|
-
|
|
301
|
+
Infrastructure helpers include:
|
|
239
302
|
|
|
240
|
-
|
|
303
|
+
```text
|
|
304
|
+
createJobTestHarness()
|
|
305
|
+
createWorkflowTestHarness()
|
|
306
|
+
createOutboxTestHarness()
|
|
307
|
+
createRealtimeTestSocket()
|
|
308
|
+
createRealtimeTestHarness()
|
|
309
|
+
readSseEvents()
|
|
310
|
+
createFakeClock()
|
|
311
|
+
createSequenceIdFactory()
|
|
312
|
+
runTestMiddleware()
|
|
313
|
+
```
|
|
241
314
|
|
|
242
|
-
`bcp/
|
|
315
|
+
`bcp/testing` is server-only. It can be used with Node `node:test`, Vitest, Jest or another runner; BCP does not install those runners as framework dependencies.
|
|
243
316
|
|
|
244
317
|
## Storage providers
|
|
245
318
|
|
|
@@ -279,5 +352,5 @@ npm run generate -- migration create_users
|
|
|
279
352
|
For prerelease/local package verification:
|
|
280
353
|
|
|
281
354
|
```bash
|
|
282
|
-
npx create-bcp-app my-app --bcp file:../chidchanun-bcp-0.2.
|
|
355
|
+
npx create-bcp-app my-app --bcp file:../chidchanun-bcp-0.2.14.tgz
|
|
283
356
|
```
|
package/package.json
CHANGED
package/template/README.md
CHANGED
|
@@ -112,26 +112,6 @@ Workflows support sequential/parallel steps, retries, persisted delays, compensa
|
|
|
112
112
|
Use `bcp/events` when application data and an integration event must commit atomically in the same SQL transaction.
|
|
113
113
|
|
|
114
114
|
```ts
|
|
115
|
-
import {
|
|
116
|
-
db,
|
|
117
|
-
} from "bcp/database";
|
|
118
|
-
|
|
119
|
-
import {
|
|
120
|
-
createSqlOutboxStore,
|
|
121
|
-
createTransactionalOutbox,
|
|
122
|
-
} from "bcp/events";
|
|
123
|
-
|
|
124
|
-
const outboxStore =
|
|
125
|
-
createSqlOutboxStore({
|
|
126
|
-
database: db,
|
|
127
|
-
driver: "mysql",
|
|
128
|
-
});
|
|
129
|
-
|
|
130
|
-
const outbox =
|
|
131
|
-
createTransactionalOutbox({
|
|
132
|
-
store: outboxStore,
|
|
133
|
-
});
|
|
134
|
-
|
|
135
115
|
await db.transaction(
|
|
136
116
|
async tx => {
|
|
137
117
|
await tx.execute(
|
|
@@ -149,42 +129,120 @@ await db.transaction(
|
|
|
149
129
|
);
|
|
150
130
|
```
|
|
151
131
|
|
|
152
|
-
|
|
132
|
+
After commit, `createOutboxDispatcher()` can deliver through durable jobs or a custom publisher.
|
|
133
|
+
|
|
134
|
+
## Realtime Platform — BCP 0.2.13+
|
|
135
|
+
|
|
136
|
+
Create a server-side realtime hub:
|
|
153
137
|
|
|
154
138
|
```ts
|
|
155
139
|
import {
|
|
156
|
-
|
|
157
|
-
} from "bcp/
|
|
140
|
+
createRealtime,
|
|
141
|
+
} from "bcp/realtime";
|
|
158
142
|
|
|
159
|
-
const
|
|
160
|
-
|
|
161
|
-
"mysql"
|
|
162
|
-
);
|
|
143
|
+
export const realtime =
|
|
144
|
+
createRealtime();
|
|
163
145
|
```
|
|
164
146
|
|
|
165
|
-
|
|
147
|
+
Channels/rooms:
|
|
148
|
+
|
|
149
|
+
```ts
|
|
150
|
+
const connection =
|
|
151
|
+
await realtime.connect();
|
|
152
|
+
|
|
153
|
+
await connection.join(
|
|
154
|
+
"orders:42"
|
|
155
|
+
);
|
|
156
|
+
|
|
157
|
+
await realtime.broadcast(
|
|
158
|
+
"orders:42",
|
|
159
|
+
"order.updated",
|
|
160
|
+
{
|
|
161
|
+
status: "paid",
|
|
162
|
+
}
|
|
163
|
+
);
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
BCP does not install a WebSocket server dependency. Adapt the selected provider to `RealtimeSocket`. SSE is built in through `realtime.sse()`.
|
|
167
|
+
|
|
168
|
+
For multi-instance deployment, replace the memory broker/presence store with shared `RealtimeBroker` and `RealtimePresenceStore` implementations.
|
|
169
|
+
|
|
170
|
+
## Testing Platform — BCP 0.2.14+
|
|
171
|
+
|
|
172
|
+
Use server-only `bcp/testing` to exercise framework contracts without adding a BCP-specific test runner.
|
|
166
173
|
|
|
167
174
|
```ts
|
|
168
175
|
import {
|
|
169
|
-
|
|
170
|
-
|
|
176
|
+
createRouteTestHandler,
|
|
177
|
+
createTestApp,
|
|
178
|
+
expectResponse,
|
|
179
|
+
} from "bcp/testing";
|
|
180
|
+
|
|
181
|
+
const app =
|
|
182
|
+
createTestApp({
|
|
183
|
+
handler:
|
|
184
|
+
createRouteTestHandler({
|
|
185
|
+
GET() {
|
|
186
|
+
return {
|
|
187
|
+
ok: true,
|
|
188
|
+
};
|
|
189
|
+
},
|
|
190
|
+
}),
|
|
191
|
+
});
|
|
171
192
|
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
193
|
+
await expectResponse(
|
|
194
|
+
await app.get("/api/health")
|
|
195
|
+
)
|
|
196
|
+
.status(200)
|
|
197
|
+
.json({
|
|
198
|
+
ok: true,
|
|
177
199
|
});
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
Authentication tests can create a real signed BCP session:
|
|
178
203
|
|
|
179
|
-
|
|
180
|
-
|
|
204
|
+
```ts
|
|
205
|
+
import {
|
|
206
|
+
createTestAuthSession,
|
|
207
|
+
} from "bcp/testing";
|
|
208
|
+
|
|
209
|
+
const session =
|
|
210
|
+
await createTestAuthSession(
|
|
211
|
+
{
|
|
212
|
+
id: 42,
|
|
213
|
+
},
|
|
214
|
+
{
|
|
215
|
+
secret:
|
|
216
|
+
process.env.BCP_SESSION_SECRET,
|
|
217
|
+
}
|
|
218
|
+
);
|
|
219
|
+
|
|
220
|
+
app.setCookie(
|
|
221
|
+
session.cookieName,
|
|
222
|
+
session.token
|
|
223
|
+
);
|
|
181
224
|
```
|
|
182
225
|
|
|
183
|
-
|
|
226
|
+
Database tests can force rollback after assertions:
|
|
227
|
+
|
|
228
|
+
```ts
|
|
229
|
+
import {
|
|
230
|
+
withTestTransaction,
|
|
231
|
+
} from "bcp/testing";
|
|
232
|
+
|
|
233
|
+
await withTestTransaction(
|
|
234
|
+
db,
|
|
235
|
+
async tx => {
|
|
236
|
+
await tx.execute(
|
|
237
|
+
"INSERT INTO users ..."
|
|
238
|
+
);
|
|
239
|
+
}
|
|
240
|
+
);
|
|
241
|
+
```
|
|
184
242
|
|
|
185
|
-
|
|
243
|
+
Additional helpers include job/workflow/outbox harnesses, `runTestMiddleware()`, fake clocks and IDs, a fake `RealtimeSocket`, realtime event assertions and `readSseEvents()`.
|
|
186
244
|
|
|
187
|
-
|
|
245
|
+
BCP does not require Jest or Vitest; these helpers work with Node `node:test` or another runner.
|
|
188
246
|
|
|
189
247
|
## Generate framework files
|
|
190
248
|
|