@beignet/core 0.0.49 → 0.0.50
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/CHANGELOG.md +22 -0
- package/README.md +160 -6
- package/dist/events/index.d.ts +54 -5
- package/dist/events/index.d.ts.map +1 -1
- package/dist/events/index.js +183 -32
- package/dist/events/index.js.map +1 -1
- package/dist/idempotency/index.d.ts +7 -3
- package/dist/idempotency/index.d.ts.map +1 -1
- package/dist/idempotency/index.js +45 -12
- package/dist/idempotency/index.js.map +1 -1
- package/dist/mail/index.d.ts.map +1 -1
- package/dist/mail/index.js +6 -3
- package/dist/mail/index.js.map +1 -1
- package/dist/ports/best-effort-work.d.ts +21 -0
- package/dist/ports/best-effort-work.d.ts.map +1 -0
- package/dist/ports/best-effort-work.js +2 -0
- package/dist/ports/best-effort-work.js.map +1 -0
- package/dist/ports/events.d.ts +7 -5
- package/dist/ports/events.d.ts.map +1 -1
- package/dist/ports/index.d.ts +6 -1
- package/dist/ports/index.d.ts.map +1 -1
- package/dist/ports/index.js +1 -0
- package/dist/ports/index.js.map +1 -1
- package/dist/ports/testing.d.ts +15 -0
- package/dist/ports/testing.d.ts.map +1 -1
- package/dist/ports/testing.js +38 -0
- package/dist/ports/testing.js.map +1 -1
- package/dist/providers/provider.d.ts +8 -5
- package/dist/providers/provider.d.ts.map +1 -1
- package/dist/providers/provider.js.map +1 -1
- package/dist/server/hooks/cors.d.ts +2 -2
- package/dist/server/hooks/cors.d.ts.map +1 -1
- package/dist/server/hooks/cors.js +2 -1
- package/dist/server/hooks/cors.js.map +1 -1
- package/dist/server/hooks/logging.d.ts +2 -2
- package/dist/server/hooks/logging.d.ts.map +1 -1
- package/dist/server/hooks/logging.js.map +1 -1
- package/dist/server/hooks/security.d.ts +2 -2
- package/dist/server/hooks/security.d.ts.map +1 -1
- package/dist/server/hooks/security.js.map +1 -1
- package/dist/server/http.d.ts +21 -2
- package/dist/server/http.d.ts.map +1 -1
- package/dist/server/index.d.ts +4 -0
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +4 -0
- package/dist/server/index.js.map +1 -1
- package/dist/server/instrumentation.d.ts.map +1 -1
- package/dist/server/instrumentation.js +5 -3
- package/dist/server/instrumentation.js.map +1 -1
- package/dist/server/request-executor.d.ts.map +1 -1
- package/dist/server/request-executor.js +9 -0
- package/dist/server/request-executor.js.map +1 -1
- package/dist/server/request-preparation.d.ts.map +1 -1
- package/dist/server/request-preparation.js +20 -2
- package/dist/server/request-preparation.js.map +1 -1
- package/dist/server/response-finalization.d.ts +2 -2
- package/dist/server/response-finalization.d.ts.map +1 -1
- package/dist/server/response-finalization.js +25 -8
- package/dist/server/response-finalization.js.map +1 -1
- package/dist/server/route-matching.d.ts.map +1 -1
- package/dist/server/route-matching.js +12 -1
- package/dist/server/route-matching.js.map +1 -1
- package/dist/server/server-sent-events.d.ts +94 -0
- package/dist/server/server-sent-events.d.ts.map +1 -0
- package/dist/server/server-sent-events.js +275 -0
- package/dist/server/server-sent-events.js.map +1 -0
- package/dist/server/server.d.ts.map +1 -1
- package/dist/server/server.js +41 -22
- package/dist/server/server.js.map +1 -1
- package/dist/server/trusted-proxy-internal.d.ts +4 -0
- package/dist/server/trusted-proxy-internal.d.ts.map +1 -1
- package/dist/server/trusted-proxy-internal.js +20 -0
- package/dist/server/trusted-proxy-internal.js.map +1 -1
- package/dist/server/trusted-proxy.d.ts.map +1 -1
- package/dist/server/trusted-proxy.js +3 -8
- package/dist/server/trusted-proxy.js.map +1 -1
- package/dist/testing/index.d.ts +17 -0
- package/dist/testing/index.d.ts.map +1 -1
- package/dist/testing/index.js +6 -1
- package/dist/testing/index.js.map +1 -1
- package/package.json +1 -1
- package/skills/app-architecture/SKILL.md +23 -3
- package/src/events/index.ts +263 -38
- package/src/idempotency/index.ts +65 -17
- package/src/mail/index.ts +7 -3
- package/src/ports/best-effort-work.ts +21 -0
- package/src/ports/events.ts +9 -4
- package/src/ports/index.ts +9 -0
- package/src/ports/testing.ts +45 -0
- package/src/providers/provider.ts +8 -5
- package/src/server/hooks/cors.ts +11 -5
- package/src/server/hooks/logging.ts +6 -2
- package/src/server/hooks/security.ts +8 -4
- package/src/server/http.ts +23 -2
- package/src/server/index.ts +4 -0
- package/src/server/instrumentation.ts +12 -4
- package/src/server/request-executor.ts +14 -0
- package/src/server/request-preparation.ts +23 -3
- package/src/server/response-finalization.ts +51 -15
- package/src/server/route-matching.ts +24 -1
- package/src/server/server-sent-events.ts +415 -0
- package/src/server/server.ts +46 -22
- package/src/server/trusted-proxy-internal.ts +20 -0
- package/src/server/trusted-proxy.ts +6 -7
- package/src/testing/index.ts +30 -0
- package/dist/query-codec.d.ts +0 -27
- package/dist/query-codec.d.ts.map +0 -1
- package/dist/query-codec.js +0 -245
- package/dist/query-codec.js.map +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,27 @@
|
|
|
1
1
|
# @beignet/core
|
|
2
2
|
|
|
3
|
+
## 0.0.50
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 6fe026a: Expose event-subscription readiness and asynchronous cleanup, await listener
|
|
8
|
+
registries during provider startup with bounded rollback, diagnose unsafe app
|
|
9
|
+
wiring, and make Redis subscription lifecycle failures observable with bounded
|
|
10
|
+
provider shutdown and recoverable channel state.
|
|
11
|
+
- 4be4573: Keep mail content out of provider instrumentation, document the Redis
|
|
12
|
+
deployment policy required for monotonic fencing, and align generated agent
|
|
13
|
+
guidance with optional seed, worker, and migration paths.
|
|
14
|
+
- ee402a9: Map invalid adapter URLs to framework responses, cancel oversized request
|
|
15
|
+
streams, distinguish typed idempotency inputs, preserve repeated response
|
|
16
|
+
headers, and match Unicode static routes against encoded URL pathnames.
|
|
17
|
+
- d1db53e: Add a portable Server-Sent Events response helper with JSON framing,
|
|
18
|
+
heartbeats, bounded unread buffering, optional maximum lifetime,
|
|
19
|
+
cancellation-aware asynchronous setup, eventual late cleanup, and safe
|
|
20
|
+
response headers, expose native request cancellation through
|
|
21
|
+
`HttpRequestLike.signal`, and use recoverable bounded snapshots for the
|
|
22
|
+
Devtools live stream with visible partial-data reporting.
|
|
23
|
+
- 7b0961b: Add a non-durable best-effort work port, a recording test adapter, and a Next.js `after()` adapter that isolates scheduler and callback failures.
|
|
24
|
+
|
|
3
25
|
## 0.0.49
|
|
4
26
|
|
|
5
27
|
### Patch Changes
|
package/README.md
CHANGED
|
@@ -72,11 +72,11 @@ name the framework area they depend on.
|
|
|
72
72
|
| `@beignet/core/outbox` | Durable event and job outbox |
|
|
73
73
|
| `@beignet/core/payments` | Payments port, memory payments adapter, and memory payments provider |
|
|
74
74
|
| `@beignet/core/pagination` | Offset/cursor page types, normalizers, and result helpers |
|
|
75
|
-
| `@beignet/core/ports` | App-facing ports, auth, audit, policies, cache, storage, logging, and redaction |
|
|
75
|
+
| `@beignet/core/ports` | App-facing ports, auth, audit, policies, cache, storage, best-effort work, logging, and redaction |
|
|
76
76
|
| `@beignet/core/providers` | Provider lifecycle and instrumentation primitives |
|
|
77
77
|
| `@beignet/core/search` | Search index definitions, SearchPort, memory adapter, memory provider, and helpers |
|
|
78
78
|
| `@beignet/core/schedules` | Schedule primitives |
|
|
79
|
-
| `@beignet/core/server` | Framework-agnostic server runtime, security headers, CSRF, and hook helpers |
|
|
79
|
+
| `@beignet/core/server` | Framework-agnostic server runtime, SSE responses, security headers, CSRF, and hook helpers |
|
|
80
80
|
| `@beignet/core/server-only` | Static lint marker for modules that must stay out of client bundles |
|
|
81
81
|
| `@beignet/core/tasks` | Operational task definitions and inline task execution |
|
|
82
82
|
| `@beignet/core/tenancy` | Branded tenant scope helpers for repository boundaries |
|
|
@@ -313,6 +313,55 @@ and dead-lettered messages when you pass a devtools or instrumentation port to
|
|
|
313
313
|
`drainOutbox(...)`. Pass `instrumentationContext` when the worker has request or
|
|
314
314
|
trace IDs that should connect the drain to devtools rows.
|
|
315
315
|
|
|
316
|
+
## Best-effort work
|
|
317
|
+
|
|
318
|
+
`BestEffortWorkPort` lets application code request non-durable follow-up work
|
|
319
|
+
without waiting for it in the originating operation:
|
|
320
|
+
|
|
321
|
+
```ts
|
|
322
|
+
import type { BestEffortWorkPort } from "@beignet/core/ports";
|
|
323
|
+
|
|
324
|
+
export type AppPorts = {
|
|
325
|
+
bestEffortWork: BestEffortWorkPort;
|
|
326
|
+
};
|
|
327
|
+
|
|
328
|
+
ctx.ports.bestEffortWork.defer(() =>
|
|
329
|
+
ctx.ports.workspaceBroadcast.publish(workspaceId, message),
|
|
330
|
+
);
|
|
331
|
+
```
|
|
332
|
+
|
|
333
|
+
Use it only when losing the callback does not change the operation's result,
|
|
334
|
+
such as publishing a cache-invalidation hint after the authoritative write has
|
|
335
|
+
committed. The adapter owns scheduler and callback error isolation. Use a job
|
|
336
|
+
or transaction-scoped outbox when work must be retried or survive process
|
|
337
|
+
termination.
|
|
338
|
+
|
|
339
|
+
Tests can use `createRecordingBestEffortWork()` directly or the default
|
|
340
|
+
`bestEffortWork` returned by `createTestPorts(...)`. Call
|
|
341
|
+
`fixture.flushBestEffortWork()` to run the current queued batch deterministically;
|
|
342
|
+
callbacks deferred by that batch remain pending until the next flush. A flush
|
|
343
|
+
attempts the complete batch before rejecting with any callback failures.
|
|
344
|
+
|
|
345
|
+
## Event subscriptions
|
|
346
|
+
|
|
347
|
+
`EventBusPort.subscribe(...)` returns an `EventSubscription` with a `ready`
|
|
348
|
+
promise and asynchronous, idempotent `unsubscribe()` method. Await `ready`
|
|
349
|
+
before advertising that a process can receive events, and await
|
|
350
|
+
`unsubscribe()` during shutdown. The memory adapter is ready immediately;
|
|
351
|
+
transport adapters resolve readiness only after their initial subscription is
|
|
352
|
+
active.
|
|
353
|
+
|
|
354
|
+
`registerListeners(...)` combines a listener registry into one subscription.
|
|
355
|
+
It waits for every child subscription and applies one 10-second registration
|
|
356
|
+
deadline by default. When setup fails or times out, Beignet starts every child
|
|
357
|
+
cleanup within the remaining deadline. If cleanup does not settle in time,
|
|
358
|
+
`ready` rejects with both the startup failure and a
|
|
359
|
+
`ListenerRegistrationCleanupTimeoutError` instead of hanging startup. Set
|
|
360
|
+
`readyTimeoutMs` when the process needs a different bounded startup policy.
|
|
361
|
+
Normal teardown after successful readiness still awaits transport cleanup;
|
|
362
|
+
apply a host-level shutdown deadline when required. Readiness is an initial
|
|
363
|
+
lifecycle signal, not an ongoing health check or durability guarantee.
|
|
364
|
+
|
|
316
365
|
## Provider-contributed ports
|
|
317
366
|
|
|
318
367
|
Apps bind app-owned ports directly and defer the rest to providers with the
|
|
@@ -381,7 +430,9 @@ defer those ports before choosing production infrastructure.
|
|
|
381
430
|
`createMemoryMailerProvider(options?)` contributes `{ mailer: MailerPort }`
|
|
382
431
|
backed by `createMemoryMailer(...)`. Deliveries are captured in memory and
|
|
383
432
|
recorded as `mail.sent` devtools events through the `mail` watcher when an
|
|
384
|
-
instrumentation port is installed.
|
|
433
|
+
instrumentation port is installed. Instrumentation records only the provider,
|
|
434
|
+
recipient count, delivery ID, and duration; it does not record addresses,
|
|
435
|
+
subjects, or message bodies. Options extend
|
|
385
436
|
`CreateMemoryMailerOptions` (`defaultFrom`, `now`, `id`, `onSend`) plus a
|
|
386
437
|
provider `name` that defaults to `"memory-mailer"`.
|
|
387
438
|
|
|
@@ -1080,6 +1131,78 @@ feeds metadata-driven hooks such as rate limiting exactly like contract
|
|
|
1080
1131
|
metadata, and the route is not added to the registry — the adapter mounts
|
|
1081
1132
|
the returned handler at the route's own path.
|
|
1082
1133
|
|
|
1134
|
+
### Server-sent events
|
|
1135
|
+
|
|
1136
|
+
`createServerSentEventResponse(...)` creates a portable Fetch `Response` for
|
|
1137
|
+
an SSE endpoint. Use it from a contract handler or raw route after
|
|
1138
|
+
application-owned authentication and authorization:
|
|
1139
|
+
|
|
1140
|
+
```ts
|
|
1141
|
+
import { createServerSentEventResponse } from "@beignet/core/server";
|
|
1142
|
+
|
|
1143
|
+
return createServerSentEventResponse({
|
|
1144
|
+
signal: req.signal,
|
|
1145
|
+
maxLifetimeMs: 240_000,
|
|
1146
|
+
start({ send }) {
|
|
1147
|
+
send({ event: "reconcile", data: { workspaceId } });
|
|
1148
|
+
const subscription = ctx.ports.workspaceBroadcast.subscribe(
|
|
1149
|
+
workspaceId,
|
|
1150
|
+
(change) => {
|
|
1151
|
+
send({ event: "changed", data: change });
|
|
1152
|
+
},
|
|
1153
|
+
);
|
|
1154
|
+
return { close: () => subscription.unsubscribe() };
|
|
1155
|
+
},
|
|
1156
|
+
onError: (error) => ctx.ports.logger.error("SSE stream failed", { error }),
|
|
1157
|
+
});
|
|
1158
|
+
```
|
|
1159
|
+
|
|
1160
|
+
Event `data` is JSON-encoded. Optional `event`, `id`, and `retry` fields use
|
|
1161
|
+
standard SSE framing; `retry` sets the browser reconnection delay in
|
|
1162
|
+
milliseconds. `comment(...)` sends an explicit comment, and `close()` ends the
|
|
1163
|
+
response. `send(...)` and `comment(...)` return `true` when they enqueue a
|
|
1164
|
+
frame and `false` after closure, when framing or encoding fails, or when the
|
|
1165
|
+
unread byte limit would be exceeded. Event names and IDs must fit on one line,
|
|
1166
|
+
and IDs cannot contain null characters. A producer, framing, encoding, stream,
|
|
1167
|
+
or buffer-overflow failure reports through `onError` and closes the connection.
|
|
1168
|
+
|
|
1169
|
+
Heartbeat comments default to 25 seconds; `heartbeatMs: false` disables them.
|
|
1170
|
+
`maxLifetimeMs` is opt-in. Both options accept `false` or an integer from `1`
|
|
1171
|
+
through `2_147_483_647`; `retry` accepts an integer from `0` through the same
|
|
1172
|
+
maximum. `start(...)` receives a stream-scoped `signal` that aborts whenever
|
|
1173
|
+
the response closes. Pass it to subscription APIs that perform asynchronous
|
|
1174
|
+
setup. `start(...)` may return a cleanup callback, a closeable subscription, a
|
|
1175
|
+
promise of either, or nothing. If it returns cleanup, request abort, response
|
|
1176
|
+
cancellation, explicit close, and maximum lifetime invoke that cleanup exactly
|
|
1177
|
+
once. `onError` also observes cleanup failures without creating an unhandled
|
|
1178
|
+
rejection. When stream closure aborts asynchronous setup, an expected
|
|
1179
|
+
`AbortError` rejection is treated as cancellation rather than a producer
|
|
1180
|
+
failure; other setup rejections still reach `onError`.
|
|
1181
|
+
|
|
1182
|
+
Unread encoded frames are bounded to `1_048_576` bytes by default. Set
|
|
1183
|
+
`maxBufferedBytes` to an integer from `1` through `2_147_483_647` when the
|
|
1184
|
+
endpoint has a verified frame-size requirement. If one frame or the
|
|
1185
|
+
accumulated unread queue would exceed the limit, the helper reports a
|
|
1186
|
+
`RangeError` and closes the connection; the limit remains active even when
|
|
1187
|
+
`maxLifetimeMs` is disabled. Response-body cancellation waits for cleanup that
|
|
1188
|
+
has already been registered, but it does not wait indefinitely for pending
|
|
1189
|
+
asynchronous setup. The stream signal lets setup stop cooperatively, and any
|
|
1190
|
+
cleanup returned after closure still runs exactly once.
|
|
1191
|
+
|
|
1192
|
+
The response always sets `Content-Type: text/event-stream`,
|
|
1193
|
+
`Cache-Control: no-store, no-transform`, and `X-Accel-Buffering: no`, removes
|
|
1194
|
+
`Content-Length` and hop-by-hop streaming headers, and preserves other custom
|
|
1195
|
+
headers supplied through `headers`. The helper does not own authorization,
|
|
1196
|
+
replay, durability, distributed connection limits, or client reconciliation.
|
|
1197
|
+
Keep authoritative state elsewhere and reconcile on initial connection and
|
|
1198
|
+
reconnect when messages are best-effort hints.
|
|
1199
|
+
|
|
1200
|
+
Use a contract handler when the stream belongs in the route registry and
|
|
1201
|
+
OpenAPI document. Use a raw route when the endpoint is transport-only and the
|
|
1202
|
+
app owns its request and response shape. Document a contract stream with a
|
|
1203
|
+
`.responses({ 200: null })` success schema and an OpenAPI `text/event-stream`
|
|
1204
|
+
media override.
|
|
1205
|
+
|
|
1083
1206
|
Use `.headers(...)` for request headers that are part of the endpoint contract. Declare header keys in lowercase; server and client runtime matching is case-insensitive.
|
|
1084
1207
|
|
|
1085
1208
|
Request bodies are supported for `POST`, `PUT`, and `PATCH` contracts only.
|
|
@@ -1177,7 +1300,8 @@ const tester = createUseCaseTester<AppContext>(createContext);
|
|
|
1177
1300
|
The returned fixture exposes captured side effects such as `events`,
|
|
1178
1301
|
`dispatchedJobs`, `audit.entries`, `mailer.deliveries`,
|
|
1179
1302
|
`notifications.deliveries`, `outbox.messages`, and memory storage for
|
|
1180
|
-
assertions.
|
|
1303
|
+
assertions. Its default `bestEffortWork` port queues callbacks in
|
|
1304
|
+
`pendingBestEffortWork`; call `flushBestEffortWork()` to run the current batch.
|
|
1181
1305
|
|
|
1182
1306
|
`overrides` is typed as `TestPortsOverrides<Ports>`, which accepts typed
|
|
1183
1307
|
partial ports without casts. The partial rule is one level deep: an
|
|
@@ -1821,6 +1945,14 @@ import { createMemoryIdempotencyStore } from "@beignet/core/idempotency";
|
|
|
1821
1945
|
const idempotency = createMemoryIdempotencyStore();
|
|
1822
1946
|
```
|
|
1823
1947
|
|
|
1948
|
+
`createIdempotencyFingerprint(...)` sorts object keys and tags non-JSON values
|
|
1949
|
+
before hashing while retaining the stable representation of ordinary JSON
|
|
1950
|
+
payloads. BigInts and Dates therefore remain distinct from same-looking
|
|
1951
|
+
strings; invalid dates, non-finite numbers, circular values, and the reserved
|
|
1952
|
+
tag key fail instead of producing ambiguous fingerprints. Non-plain objects
|
|
1953
|
+
other than `Date` fail as unsupported; project them to plain command data
|
|
1954
|
+
before hashing.
|
|
1955
|
+
|
|
1824
1956
|
Reservation tokens use Web Crypto `randomUUID()` or `getRandomValues()` when
|
|
1825
1957
|
available and securely fall back to `node:crypto` on supported Node runtimes.
|
|
1826
1958
|
The memory adapter accepts `createReservationToken` when a deterministic test
|
|
@@ -2053,6 +2185,24 @@ Use `{ contract, handle }` as the escape hatch for response headers,
|
|
|
2053
2185
|
streaming, and multi-status responses. `defineRoute` remains
|
|
2054
2186
|
available for full handlers that read hook-added `ctx` fields.
|
|
2055
2187
|
|
|
2188
|
+
Framework-neutral response header values may be strings or string arrays.
|
|
2189
|
+
Use an array for repeated fields such as `Set-Cookie`; Web-compatible adapters
|
|
2190
|
+
append every item separately, and hooks receive the same string-or-array
|
|
2191
|
+
header record:
|
|
2192
|
+
|
|
2193
|
+
```ts
|
|
2194
|
+
return {
|
|
2195
|
+
status: 200,
|
|
2196
|
+
headers: {
|
|
2197
|
+
"set-cookie": [
|
|
2198
|
+
"session=abc; Path=/; HttpOnly; Secure; SameSite=Lax",
|
|
2199
|
+
"theme=dark; Path=/; Secure; SameSite=Lax",
|
|
2200
|
+
],
|
|
2201
|
+
},
|
|
2202
|
+
body: { ok: true },
|
|
2203
|
+
};
|
|
2204
|
+
```
|
|
2205
|
+
|
|
2056
2206
|
When credentials live in request headers, declare a `headers` schema on the
|
|
2057
2207
|
auth hooks. The hook validates the raw lowercase request header record before
|
|
2058
2208
|
`resolve` runs, so `resolve` receives typed header values; on `required()`
|
|
@@ -2154,13 +2304,17 @@ status, including when reading the response stream itself fails.
|
|
|
2154
2304
|
request validation, response validation, error mapping, and provider lifecycle.
|
|
2155
2305
|
Adapters own the platform edge only:
|
|
2156
2306
|
|
|
2157
|
-
- Convert the native request into `HttpRequestLike
|
|
2307
|
+
- Convert the native request into `HttpRequestLike`, including its abort
|
|
2308
|
+
signal when the platform exposes one
|
|
2158
2309
|
- Call `server.api(...)` or a single route handler
|
|
2159
2310
|
- Convert `HttpResponse` back into the native response type
|
|
2160
2311
|
|
|
2161
2312
|
The public adapter contract is `HttpAdapter<NativeRequest, NativeResponse>`.
|
|
2162
2313
|
Use it when building a runtime package beyond the first-party `@beignet/web`
|
|
2163
|
-
and `@beignet/next` adapters.
|
|
2314
|
+
and `@beignet/next` adapters. Custom adapters must supply an absolute HTTP or
|
|
2315
|
+
HTTPS `HttpRequestLike.url`; invalid values are converted to a framework-owned
|
|
2316
|
+
`400 INVALID_REQUEST_URL` response instead of escaping as a rejected handler
|
|
2317
|
+
promise.
|
|
2164
2318
|
|
|
2165
2319
|
### Health and readiness
|
|
2166
2320
|
|
package/dist/events/index.d.ts
CHANGED
|
@@ -47,6 +47,45 @@ export interface EventPublishOptions {
|
|
|
47
47
|
/** Versioned trace context captured by the event producer. */
|
|
48
48
|
trace?: TraceCarrier;
|
|
49
49
|
}
|
|
50
|
+
/**
|
|
51
|
+
* Lifecycle handle for one event subscription or a composed listener
|
|
52
|
+
* registration.
|
|
53
|
+
*
|
|
54
|
+
* `ready` proves initial transport readiness. It does not represent ongoing
|
|
55
|
+
* connectivity, durability, replay, or handler success after startup.
|
|
56
|
+
*/
|
|
57
|
+
export interface EventSubscription {
|
|
58
|
+
/** Resolves when the subscription can receive events. */
|
|
59
|
+
readonly ready: Promise<void>;
|
|
60
|
+
/** Stop local delivery and await transport cleanup. Idempotent. */
|
|
61
|
+
unsubscribe(): Promise<void>;
|
|
62
|
+
}
|
|
63
|
+
/** Error used when a subscription closes before initial readiness. */
|
|
64
|
+
export declare class EventSubscriptionClosedError extends Error {
|
|
65
|
+
constructor(message?: string);
|
|
66
|
+
}
|
|
67
|
+
/** Error thrown when a listener registry misses its readiness deadline. */
|
|
68
|
+
export declare class ListenerRegistrationTimeoutError extends Error {
|
|
69
|
+
/** Configured readiness deadline in milliseconds. */
|
|
70
|
+
readonly timeoutMs: number;
|
|
71
|
+
/** Listener names that were part of the registration. */
|
|
72
|
+
readonly listenerNames: readonly string[];
|
|
73
|
+
constructor(args: {
|
|
74
|
+
timeoutMs: number;
|
|
75
|
+
listenerNames: readonly string[];
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
/** Error thrown when listener rollback misses the registration deadline. */
|
|
79
|
+
export declare class ListenerRegistrationCleanupTimeoutError extends Error {
|
|
80
|
+
/** Configured registration deadline in milliseconds. */
|
|
81
|
+
readonly timeoutMs: number;
|
|
82
|
+
/** Listener names that were part of the registration. */
|
|
83
|
+
readonly listenerNames: readonly string[];
|
|
84
|
+
constructor(args: {
|
|
85
|
+
timeoutMs: number;
|
|
86
|
+
listenerNames: readonly string[];
|
|
87
|
+
});
|
|
88
|
+
}
|
|
50
89
|
/**
|
|
51
90
|
* Options for `defineEvent(...)`.
|
|
52
91
|
*/
|
|
@@ -120,9 +159,9 @@ export interface EventBusLike {
|
|
|
120
159
|
*/
|
|
121
160
|
publish<E extends EventPayloadDef>(event: E, payload: InferEventPayload<E>, options?: EventPublishOptions): MaybePromise<void>;
|
|
122
161
|
/**
|
|
123
|
-
* Subscribe to an event and return
|
|
162
|
+
* Subscribe to an event and return its readiness and cleanup handle.
|
|
124
163
|
*/
|
|
125
|
-
subscribe<E extends EventPayloadDef>(event: E, handler: (payload: InferEventPayload<E>, options?: EventPublishOptions) => MaybePromise<void>):
|
|
164
|
+
subscribe<E extends EventPayloadDef>(event: E, handler: (payload: InferEventPayload<E>, options?: EventPublishOptions) => MaybePromise<void>): EventSubscription;
|
|
126
165
|
}
|
|
127
166
|
/**
|
|
128
167
|
* Options for `registerListeners(...)`.
|
|
@@ -142,6 +181,12 @@ export interface RegisterListenersOptions<Ctx> {
|
|
|
142
181
|
* the event bus subscription callback.
|
|
143
182
|
*/
|
|
144
183
|
onError?: (error: unknown, listener: ListenerDef<EventDef, Ctx>) => void;
|
|
184
|
+
/**
|
|
185
|
+
* Maximum time for the complete listener registry to become ready. The same
|
|
186
|
+
* registration deadline bounds automatic rollback after startup failure.
|
|
187
|
+
* Defaults to 10 seconds.
|
|
188
|
+
*/
|
|
189
|
+
readyTimeoutMs?: number;
|
|
145
190
|
}
|
|
146
191
|
/**
|
|
147
192
|
* Context-bound listener helper factory.
|
|
@@ -181,12 +226,16 @@ export declare function parseEventPayload<E extends EventPayloadDef>(event: E, p
|
|
|
181
226
|
*/
|
|
182
227
|
export declare function publishEvent<E extends EventPayloadDef>(eventBus: EventBusLike, event: E, payload: InferEventPayload<E>, options?: EventPublishOptions): Promise<void>;
|
|
183
228
|
/**
|
|
184
|
-
* Register listeners against an event bus and return
|
|
229
|
+
* Register listeners against an event bus and return a composite lifecycle
|
|
230
|
+
* handle.
|
|
185
231
|
*
|
|
186
232
|
* Payloads are validated before listener handlers run. Listener context is
|
|
187
|
-
* resolved per delivery when `options.ctx` is a factory.
|
|
233
|
+
* resolved per delivery when `options.ctx` is a factory. Initial registration
|
|
234
|
+
* starts every child cleanup after a synchronous subscribe failure, rejected
|
|
235
|
+
* readiness promise, or readiness timeout. Cleanup that cannot finish inside
|
|
236
|
+
* the registration deadline is reported without extending startup forever.
|
|
188
237
|
*/
|
|
189
|
-
export declare function registerListeners<Ctx>(eventBus: EventBusLike, listeners: readonly ListenerDef<EventDef, Ctx>[], options?: RegisterListenersOptions<Ctx>):
|
|
238
|
+
export declare function registerListeners<Ctx>(eventBus: EventBusLike, listeners: readonly ListenerDef<EventDef, Ctx>[], options?: RegisterListenersOptions<Ctx>): EventSubscription;
|
|
190
239
|
/**
|
|
191
240
|
* Create listener helper methods bound to an application context type.
|
|
192
241
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/events/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAE9D,OAAO,EAEL,KAAK,YAAY,EACjB,KAAK,WAAW,EACjB,MAAM,qBAAqB,CAAC;AAE7B;;GAEG;AACH,MAAM,MAAM,cAAc,GAAG,gBAAgB,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;AAEhE;;GAEG;AACH,MAAM,MAAM,YAAY,CAAC,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/events/index.ts"],"names":[],"mappings":"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"}
|
package/dist/events/index.js
CHANGED
|
@@ -1,5 +1,46 @@
|
|
|
1
1
|
import { runWithResolvedTracingContext } from "../tracing/execution.js";
|
|
2
2
|
import { parseTraceCarrier, } from "../tracing/index.js";
|
|
3
|
+
const DEFAULT_LISTENER_READY_TIMEOUT_MS = 10_000;
|
|
4
|
+
const MAX_TIMER_MS = 2_147_483_647;
|
|
5
|
+
/** Error used when a subscription closes before initial readiness. */
|
|
6
|
+
export class EventSubscriptionClosedError extends Error {
|
|
7
|
+
constructor(message = "Event subscription closed before it became ready.") {
|
|
8
|
+
super(message);
|
|
9
|
+
this.name = "EventSubscriptionClosedError";
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
/** Error thrown when a listener registry misses its readiness deadline. */
|
|
13
|
+
export class ListenerRegistrationTimeoutError extends Error {
|
|
14
|
+
/** Configured readiness deadline in milliseconds. */
|
|
15
|
+
timeoutMs;
|
|
16
|
+
/** Listener names that were part of the registration. */
|
|
17
|
+
listenerNames;
|
|
18
|
+
constructor(args) {
|
|
19
|
+
const suffix = args.listenerNames.length
|
|
20
|
+
? `: ${args.listenerNames.join(", ")}`
|
|
21
|
+
: "";
|
|
22
|
+
super(`Listeners did not become ready within ${args.timeoutMs}ms${suffix}.`);
|
|
23
|
+
this.name = "ListenerRegistrationTimeoutError";
|
|
24
|
+
this.timeoutMs = args.timeoutMs;
|
|
25
|
+
this.listenerNames = [...args.listenerNames];
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
/** Error thrown when listener rollback misses the registration deadline. */
|
|
29
|
+
export class ListenerRegistrationCleanupTimeoutError extends Error {
|
|
30
|
+
/** Configured registration deadline in milliseconds. */
|
|
31
|
+
timeoutMs;
|
|
32
|
+
/** Listener names that were part of the registration. */
|
|
33
|
+
listenerNames;
|
|
34
|
+
constructor(args) {
|
|
35
|
+
const suffix = args.listenerNames.length
|
|
36
|
+
? `: ${args.listenerNames.join(", ")}`
|
|
37
|
+
: "";
|
|
38
|
+
super(`Listener cleanup did not finish before the ${args.timeoutMs}ms registration deadline${suffix}.`);
|
|
39
|
+
this.name = "ListenerRegistrationCleanupTimeoutError";
|
|
40
|
+
this.timeoutMs = args.timeoutMs;
|
|
41
|
+
this.listenerNames = [...args.listenerNames];
|
|
42
|
+
}
|
|
43
|
+
}
|
|
3
44
|
/**
|
|
4
45
|
* Error thrown when event payload validation fails.
|
|
5
46
|
*/
|
|
@@ -81,48 +122,158 @@ export async function publishEvent(eventBus, event, payload, options) {
|
|
|
81
122
|
await parseEventPayload(event, payload);
|
|
82
123
|
await eventBus.publish(event, payload, options);
|
|
83
124
|
}
|
|
125
|
+
function assertReadyTimeoutMs(value) {
|
|
126
|
+
if (Number.isInteger(value) && value >= 1 && value <= MAX_TIMER_MS)
|
|
127
|
+
return;
|
|
128
|
+
throw new RangeError(`readyTimeoutMs must be an integer between 1 and ${MAX_TIMER_MS} milliseconds.`);
|
|
129
|
+
}
|
|
130
|
+
function errorsFromCleanup(error) {
|
|
131
|
+
return error instanceof AggregateError ? [...error.errors] : [error];
|
|
132
|
+
}
|
|
133
|
+
function unsubscribeAllSettled(subscriptions) {
|
|
134
|
+
const attempts = [];
|
|
135
|
+
for (const subscription of [...subscriptions].reverse()) {
|
|
136
|
+
try {
|
|
137
|
+
attempts.push(Promise.resolve(subscription.unsubscribe()));
|
|
138
|
+
}
|
|
139
|
+
catch (error) {
|
|
140
|
+
attempts.push(Promise.reject(error));
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
return Promise.allSettled(attempts);
|
|
144
|
+
}
|
|
145
|
+
function throwSubscriptionCleanupErrors(results) {
|
|
146
|
+
const errors = results.flatMap((result) => result.status === "rejected" ? errorsFromCleanup(result.reason) : []);
|
|
147
|
+
if (errors.length > 0) {
|
|
148
|
+
throw new AggregateError(errors, "Event subscription cleanup failed");
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
function withListenerDeadline(operation, args) {
|
|
152
|
+
let timeout;
|
|
153
|
+
const timedOut = new Promise((_, reject) => {
|
|
154
|
+
timeout = setTimeout(() => {
|
|
155
|
+
reject(args.timeoutError);
|
|
156
|
+
}, Math.max(0, args.deadlineAt - performance.now()));
|
|
157
|
+
});
|
|
158
|
+
return Promise.race([operation, timedOut]).finally(() => {
|
|
159
|
+
if (timeout !== undefined)
|
|
160
|
+
clearTimeout(timeout);
|
|
161
|
+
});
|
|
162
|
+
}
|
|
84
163
|
/**
|
|
85
|
-
* Register listeners against an event bus and return
|
|
164
|
+
* Register listeners against an event bus and return a composite lifecycle
|
|
165
|
+
* handle.
|
|
86
166
|
*
|
|
87
167
|
* Payloads are validated before listener handlers run. Listener context is
|
|
88
|
-
* resolved per delivery when `options.ctx` is a factory.
|
|
168
|
+
* resolved per delivery when `options.ctx` is a factory. Initial registration
|
|
169
|
+
* starts every child cleanup after a synchronous subscribe failure, rejected
|
|
170
|
+
* readiness promise, or readiness timeout. Cleanup that cannot finish inside
|
|
171
|
+
* the registration deadline is reported without extending startup forever.
|
|
89
172
|
*/
|
|
90
173
|
export function registerListeners(eventBus, listeners, options = {}) {
|
|
91
|
-
const
|
|
174
|
+
const readyTimeoutMs = options.readyTimeoutMs ?? DEFAULT_LISTENER_READY_TIMEOUT_MS;
|
|
175
|
+
assertReadyTimeoutMs(readyTimeoutMs);
|
|
176
|
+
const registrationDeadlineAt = performance.now() + readyTimeoutMs;
|
|
177
|
+
const listenerNames = listeners.map(({ name }) => name);
|
|
178
|
+
const subscriptions = [];
|
|
179
|
+
let registrationError;
|
|
180
|
+
for (const listener of listeners) {
|
|
92
181
|
try {
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
182
|
+
subscriptions.push(eventBus.subscribe(listener.event, async (rawPayload, publishOptions) => {
|
|
183
|
+
try {
|
|
184
|
+
const payload = await parseEventPayload(listener.event, rawPayload);
|
|
185
|
+
const traceAttributes = {
|
|
186
|
+
"beignet.listener.name": listener.name,
|
|
187
|
+
"beignet.event.name": listener.event.name,
|
|
188
|
+
};
|
|
189
|
+
await runWithResolvedTracingContext({
|
|
190
|
+
tracing: options.tracing,
|
|
191
|
+
ctx: options.ctx,
|
|
192
|
+
operation: {
|
|
193
|
+
name: `beignet.listener ${listener.name}`,
|
|
194
|
+
type: "listener",
|
|
195
|
+
kind: "consumer",
|
|
196
|
+
parent: parseTraceCarrier(publishOptions?.trace),
|
|
197
|
+
attributes: traceAttributes,
|
|
198
|
+
metricAttributes: traceAttributes,
|
|
199
|
+
},
|
|
200
|
+
run: (ctx) => listener.handle({
|
|
201
|
+
event: listener.event,
|
|
202
|
+
payload,
|
|
203
|
+
ctx,
|
|
204
|
+
}),
|
|
205
|
+
});
|
|
206
|
+
}
|
|
207
|
+
catch (error) {
|
|
208
|
+
options.onError?.(error, listener);
|
|
209
|
+
if (!options.onError)
|
|
210
|
+
throw error;
|
|
211
|
+
}
|
|
212
|
+
}));
|
|
115
213
|
}
|
|
116
214
|
catch (error) {
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
throw error;
|
|
215
|
+
registrationError = error;
|
|
216
|
+
break;
|
|
120
217
|
}
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
218
|
+
}
|
|
219
|
+
let rejectClosed;
|
|
220
|
+
const closedBeforeReady = new Promise((_, reject) => {
|
|
221
|
+
rejectClosed = reject;
|
|
222
|
+
});
|
|
223
|
+
// A consumer may only await cleanup. Keep an explicit observer on the
|
|
224
|
+
// cancellation signal so that use does not create an unhandled rejection.
|
|
225
|
+
void closedBeforeReady.catch(() => undefined);
|
|
226
|
+
let cleanupPromise;
|
|
227
|
+
const cleanup = (deadlineAt) => {
|
|
228
|
+
if (cleanupPromise)
|
|
229
|
+
return cleanupPromise;
|
|
230
|
+
const operation = unsubscribeAllSettled(subscriptions);
|
|
231
|
+
cleanupPromise =
|
|
232
|
+
deadlineAt === undefined
|
|
233
|
+
? operation.then(throwSubscriptionCleanupErrors)
|
|
234
|
+
: withListenerDeadline(operation, {
|
|
235
|
+
deadlineAt,
|
|
236
|
+
timeoutError: new ListenerRegistrationCleanupTimeoutError({
|
|
237
|
+
timeoutMs: readyTimeoutMs,
|
|
238
|
+
listenerNames,
|
|
239
|
+
}),
|
|
240
|
+
}).then(throwSubscriptionCleanupErrors);
|
|
241
|
+
return cleanupPromise;
|
|
242
|
+
};
|
|
243
|
+
const initialReadiness = registrationError
|
|
244
|
+
? Promise.reject(registrationError)
|
|
245
|
+
: Promise.all(subscriptions.map(({ ready }) => ready)).then(() => undefined);
|
|
246
|
+
let readySettled = false;
|
|
247
|
+
const ready = withListenerDeadline(Promise.race([initialReadiness, closedBeforeReady]), {
|
|
248
|
+
deadlineAt: registrationDeadlineAt,
|
|
249
|
+
timeoutError: new ListenerRegistrationTimeoutError({
|
|
250
|
+
timeoutMs: readyTimeoutMs,
|
|
251
|
+
listenerNames,
|
|
252
|
+
}),
|
|
253
|
+
})
|
|
254
|
+
.catch(async (primaryError) => {
|
|
255
|
+
try {
|
|
256
|
+
await cleanup(registrationDeadlineAt);
|
|
257
|
+
}
|
|
258
|
+
catch (cleanupError) {
|
|
259
|
+
throw new AggregateError([primaryError, ...errorsFromCleanup(cleanupError)], "Listener registration failed and cleanup failed");
|
|
125
260
|
}
|
|
261
|
+
throw primaryError;
|
|
262
|
+
})
|
|
263
|
+
.finally(() => {
|
|
264
|
+
readySettled = true;
|
|
265
|
+
});
|
|
266
|
+
// EventSubscription allows callers that only own cleanup. Preserve the
|
|
267
|
+
// rejection for awaiters while preventing process-level unhandled noise.
|
|
268
|
+
void ready.catch(() => undefined);
|
|
269
|
+
return {
|
|
270
|
+
ready,
|
|
271
|
+
unsubscribe() {
|
|
272
|
+
if (!readySettled) {
|
|
273
|
+
rejectClosed(new EventSubscriptionClosedError());
|
|
274
|
+
}
|
|
275
|
+
return cleanup(readySettled ? undefined : registrationDeadlineAt);
|
|
276
|
+
},
|
|
126
277
|
};
|
|
127
278
|
}
|
|
128
279
|
/**
|
package/dist/events/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/events/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,6BAA6B,EAAE,MAAM,yBAAyB,CAAC;AACxE,OAAO,EACL,iBAAiB,GAGlB,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/events/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -410,9 +410,13 @@ export declare function runIdempotently<Result>(idempotency: IdempotencyPort, op
|
|
|
410
410
|
/**
|
|
411
411
|
* Create a SHA-256 fingerprint from a canonicalized value.
|
|
412
412
|
*
|
|
413
|
-
* Object keys are sorted,
|
|
414
|
-
*
|
|
415
|
-
*
|
|
413
|
+
* Object keys are sorted, while non-JSON values carry reserved type tags so
|
|
414
|
+
* BigInts and Dates cannot collide with same-looking strings. Ordinary JSON
|
|
415
|
+
* inputs retain their existing canonical representation. `undefined` values
|
|
416
|
+
* and functions are omitted from objects and represented as omitted array
|
|
417
|
+
* positions. Circular or unsupported object values, reserved tag keys,
|
|
418
|
+
* invalid dates, and non-finite numbers throw. Exact omit paths may be supplied
|
|
419
|
+
* as dotted strings or string arrays.
|
|
416
420
|
*/
|
|
417
421
|
export declare function createIdempotencyFingerprint(value: unknown, options?: CreateIdempotencyFingerprintOptions): Promise<string>;
|
|
418
422
|
//# sourceMappingURL=index.d.ts.map
|