@chidchanun/bcp 0.2.10 → 0.2.12

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.
@@ -0,0 +1,180 @@
1
+ # BCP Framework 0.2.11 — Workflow Orchestration
2
+
3
+ > Release state: unreleased development target until RC validation, tagging and npm publication complete.
4
+
5
+ `0.2.11` adds server-side workflow orchestration on top of the durable jobs foundation introduced in `0.2.8`–`0.2.10`.
6
+
7
+ ## Highlights
8
+
9
+ - new `bcp/workflow` server-only public entrypoint,
10
+ - sequential workflow steps,
11
+ - parallel step groups,
12
+ - per-step retry policies,
13
+ - persisted workflow delays,
14
+ - manual resume/retry/cancel controls,
15
+ - saga-style compensation in reverse completion order,
16
+ - `WorkflowStore` persistence contract,
17
+ - workflow run leases via atomic `claim()` / `release()`,
18
+ - optional `bcp/jobs` queue-backed execution,
19
+ - delayed workflow continuation through the job queue,
20
+ - compiled `workflow.mjs` runtime in the npm package,
21
+ - browser/client bundle boundary enforcement,
22
+ - unit and prepared-package smoke coverage.
23
+
24
+ ## Basic API
25
+
26
+ ```ts
27
+ import {
28
+ createWorkflow,
29
+ } from "bcp/workflow";
30
+
31
+ const onboarding =
32
+ createWorkflow<{
33
+ userId: number;
34
+ }>(
35
+ "user.onboarding",
36
+ workflow => {
37
+ workflow.step(
38
+ "profile",
39
+ createProfile
40
+ );
41
+
42
+ workflow.parallel(
43
+ "initialize",
44
+ parallel => {
45
+ parallel.step(
46
+ "preferences",
47
+ createPreferences
48
+ );
49
+ parallel.step(
50
+ "workspace",
51
+ createWorkspace
52
+ );
53
+ }
54
+ );
55
+
56
+ workflow.delay(
57
+ "cooldown",
58
+ 1_000
59
+ );
60
+ }
61
+ );
62
+ ```
63
+
64
+ ## Queue-backed workflows
65
+
66
+ Applications may provide an existing `BackgroundJobQueue`:
67
+
68
+ ```ts
69
+ const workflow =
70
+ createWorkflow(
71
+ "order.fulfillment",
72
+ defineWorkflow,
73
+ {
74
+ queue: jobs,
75
+ store:
76
+ workflowStore,
77
+ }
78
+ );
79
+ ```
80
+
81
+ `start()`, `retry()` and `resume()` then enqueue workflow execution rather than executing the run inline. Delay steps enqueue delayed continuation jobs.
82
+
83
+ The queue retains responsibility for delivery, worker concurrency, visibility timeout, heartbeat and stale-job recovery.
84
+
85
+ ## Persistence
86
+
87
+ `createMemoryWorkflowStore()` is included for development/tests.
88
+
89
+ Production multi-instance deployments should implement `WorkflowStore` with shared durable storage. `claim()` must atomically lease a workflow run so multiple workers cannot execute the same run concurrently.
90
+
91
+ ## Retry behavior
92
+
93
+ A step can define:
94
+
95
+ ```ts
96
+ {
97
+ maxAttempts: 3,
98
+ retryDelayMs:
99
+ attempt =>
100
+ attempt * 1_000,
101
+ }
102
+ ```
103
+
104
+ A run that remains failed after its step retry policy is exhausted can later be retried with:
105
+
106
+ ```ts
107
+ await workflow.retry(
108
+ runId
109
+ );
110
+ ```
111
+
112
+ Already-successful preceding steps remain complete.
113
+
114
+ ## Compensation
115
+
116
+ Steps can define compensation handlers:
117
+
118
+ ```ts
119
+ workflow.step(
120
+ "reserve-stock",
121
+ reserveStock,
122
+ {
123
+ compensate:
124
+ releaseStock,
125
+ }
126
+ );
127
+ ```
128
+
129
+ Then:
130
+
131
+ ```ts
132
+ await workflow.compensate(
133
+ runId
134
+ );
135
+ ```
136
+
137
+ Successful compensatable steps execute in reverse completion order.
138
+
139
+ ## Delays
140
+
141
+ Delay steps persist `waiting` state and `waitUntil` rather than holding a long-running process timer.
142
+
143
+ Without a queue, application code calls `resume()` after the due time. With a queue, BCP schedules a delayed workflow continuation job.
144
+
145
+ ## Compatibility
146
+
147
+ `0.2.11` is additive relative to `0.2.10`.
148
+
149
+ Existing `bcp/jobs`, scheduler, Redis durable adapters and all prior public entrypoints remain supported.
150
+
151
+ No intentional breaking changes are introduced from the `0.2.10` baseline.
152
+
153
+ ## Validation
154
+
155
+ Before release:
156
+
157
+ ```bash
158
+ npm run typecheck
159
+ npm run test:unit
160
+ npm run test:integration
161
+ npm run test:e2e
162
+ npm run test:package
163
+ npm run rc:check
164
+ ```
165
+
166
+ Workflow validation covers:
167
+
168
+ - sequential step execution,
169
+ - transient step retry,
170
+ - parallel groups,
171
+ - persisted delay/resume semantics,
172
+ - manual failed-run retry,
173
+ - reverse compensation order,
174
+ - queue-backed execution,
175
+ - workflow store lease behavior,
176
+ - browser bundle rejection,
177
+ - compiled `workflow.mjs` package execution,
178
+ - API/platform/docs manifest parity.
179
+
180
+ The final release tag must point to the exact commit that passed the complete RC sequence.
@@ -0,0 +1,147 @@
1
+ # BCP Framework 0.2.12 — Transactional Outbox & Events
2
+
3
+ Release state: unreleased development target.
4
+
5
+ `0.2.12` adds a server-only transactional outbox and event-delivery platform that bridges BCP Database transactions with durable jobs or application-owned publishers without performing external side effects inside the business transaction.
6
+
7
+ ## New public entrypoint
8
+
9
+ ```ts
10
+ import {
11
+ createEventBus,
12
+ createMemoryOutboxStore,
13
+ createOutboxDispatcher,
14
+ createOutboxMigrationSql,
15
+ createSqlOutboxStore,
16
+ createTransactionalOutbox,
17
+ } from "bcp/events";
18
+ ```
19
+
20
+ `bcp/events` is server-only and receives the same browser/client boundary protection as `bcp/database`, `bcp/jobs` and `bcp/workflow`.
21
+
22
+ ## Transaction-bound outbox writes
23
+
24
+ Application code can insert business rows and outbox rows through the same `TransactionDatabase`:
25
+
26
+ ```ts
27
+ await db.transaction(async tx => {
28
+ await tx.execute(
29
+ "INSERT INTO orders ..."
30
+ );
31
+
32
+ await outbox.publish(
33
+ tx,
34
+ "order.created",
35
+ {
36
+ orderId: 42,
37
+ }
38
+ );
39
+ });
40
+ ```
41
+
42
+ `createSqlOutboxStore()` writes through the caller transaction rather than the root database connection.
43
+
44
+ ## SQL providers
45
+
46
+ Provider-specific migration SQL is available for:
47
+
48
+ ```text
49
+ mysql
50
+ postgresql
51
+ sqlite
52
+ ```
53
+
54
+ The SQL store persists:
55
+
56
+ - event ID/type/payload,
57
+ - metadata,
58
+ - correlation/causation/aggregate IDs,
59
+ - state,
60
+ - attempts/max attempts,
61
+ - created/available/processing/published/failed timestamps,
62
+ - delivery errors,
63
+ - lease owner/expiry.
64
+
65
+ ## Dispatcher
66
+
67
+ `createOutboxDispatcher()` adds:
68
+
69
+ - batched claiming,
70
+ - dispatcher leases,
71
+ - stale-lease recovery,
72
+ - retry/backoff,
73
+ - terminal failed state,
74
+ - durable job-queue handoff,
75
+ - custom publisher delivery,
76
+ - in-process EventBus delivery,
77
+ - polling runner lifecycle,
78
+ - cleanup/statistics through the store.
79
+
80
+ ## Durable job handoff
81
+
82
+ With `queue: jobs`, event type:
83
+
84
+ ```text
85
+ order.created
86
+ ```
87
+
88
+ is handed off as:
89
+
90
+ ```text
91
+ event.order.created
92
+ ```
93
+
94
+ The queued payload contains the event envelope and uses stable job ID:
95
+
96
+ ```text
97
+ outbox:<event-id>
98
+ ```
99
+
100
+ A successful enqueue marks the outbox event `published`. Downstream job completion remains the responsibility of the job runtime.
101
+
102
+ ## Event bus
103
+
104
+ `createEventBus()` provides local server-side handler registration and sequential event delivery for tests, local composition and single-process handlers.
105
+
106
+ It is not a distributed durable broker.
107
+
108
+ ## States
109
+
110
+ ```text
111
+ pending
112
+ processing
113
+ published
114
+ failed
115
+ ```
116
+
117
+ Expired `processing` leases can return to `pending` for another dispatcher attempt.
118
+
119
+ ## Delivery semantics
120
+
121
+ The platform closes the database-commit / external-publish gap but intentionally uses at-least-once delivery semantics.
122
+
123
+ Consumers should use stable event IDs and application-level idempotency when duplicate external side effects are unsafe.
124
+
125
+ ## Backward compatibility
126
+
127
+ `0.2.12` is additive relative to `0.2.11`:
128
+
129
+ - existing `bcp/jobs` APIs remain unchanged,
130
+ - existing `bcp/workflow` APIs remain unchanged,
131
+ - no database adapter contract method was removed,
132
+ - existing applications do not need an outbox unless they opt into `bcp/events`.
133
+
134
+ ## Validation
135
+
136
+ The release candidate must pass:
137
+
138
+ ```bash
139
+ npm run typecheck
140
+ npm run test:unit
141
+ npm run test:integration
142
+ npm run test:e2e
143
+ npm run test:package
144
+ npm run rc:check
145
+ ```
146
+
147
+ Package validation executes the compiled `events.mjs` runtime and verifies the `bcp/events` export, transaction/outbox API, dispatcher delivery and migration helper.