opinionated-machine 10.5.0 → 11.2.0

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.
Files changed (63) hide show
  1. package/CHANGELOG.md +154 -0
  2. package/README.md +513 -52
  3. package/dist/lib/DIContext.d.ts +13 -1
  4. package/dist/lib/DIContext.js +28 -8
  5. package/dist/lib/DIContext.js.map +1 -1
  6. package/dist/lib/api-contracts/apiRouteBuilder.d.ts +47 -5
  7. package/dist/lib/api-contracts/apiRouteBuilder.js +57 -8
  8. package/dist/lib/api-contracts/apiRouteBuilder.js.map +1 -1
  9. package/dist/lib/api-contracts/apiSseConnectionRegistry.d.ts +182 -0
  10. package/dist/lib/api-contracts/apiSseConnectionRegistry.js +332 -0
  11. package/dist/lib/api-contracts/apiSseConnectionRegistry.js.map +1 -0
  12. package/dist/lib/api-contracts/index.d.ts +1 -0
  13. package/dist/lib/api-contracts/index.js +1 -0
  14. package/dist/lib/api-contracts/index.js.map +1 -1
  15. package/dist/lib/gateway/gatewayMetadata.d.ts +1 -0
  16. package/dist/lib/gateway/gatewayMetadata.js +11 -0
  17. package/dist/lib/gateway/gatewayMetadata.js.map +1 -1
  18. package/dist/lib/gateway/index.d.ts +1 -0
  19. package/dist/lib/gateway/index.js +1 -0
  20. package/dist/lib/gateway/index.js.map +1 -1
  21. package/dist/lib/gateway/manifest/buildManifest.d.ts +18 -0
  22. package/dist/lib/gateway/manifest/buildManifest.js +31 -0
  23. package/dist/lib/gateway/manifest/buildManifest.js.map +1 -1
  24. package/dist/lib/gateway/manifest/manifestSchema.d.ts +18 -0
  25. package/dist/lib/gateway/manifest/manifestSchema.js +27 -0
  26. package/dist/lib/gateway/manifest/manifestSchema.js.map +1 -1
  27. package/dist/lib/gateway/routeStreaming.d.ts +79 -0
  28. package/dist/lib/gateway/routeStreaming.js +70 -0
  29. package/dist/lib/gateway/routeStreaming.js.map +1 -0
  30. package/dist/lib/resolverFunctions.d.ts +7 -0
  31. package/dist/lib/resolverFunctions.js +13 -0
  32. package/dist/lib/resolverFunctions.js.map +1 -1
  33. package/dist/lib/routes/fastifyRouteBuilder.js +9 -2
  34. package/dist/lib/routes/fastifyRouteBuilder.js.map +1 -1
  35. package/dist/lib/sse/AbstractSSEController.d.ts +10 -0
  36. package/dist/lib/sse/AbstractSSEController.js +9 -0
  37. package/dist/lib/sse/AbstractSSEController.js.map +1 -1
  38. package/dist/lib/sse/eventIds.d.ts +138 -0
  39. package/dist/lib/sse/eventIds.js +155 -0
  40. package/dist/lib/sse/eventIds.js.map +1 -0
  41. package/dist/lib/sse/index.d.ts +3 -2
  42. package/dist/lib/sse/index.js +6 -2
  43. package/dist/lib/sse/index.js.map +1 -1
  44. package/dist/lib/sse/rooms/SSERoomEventPublisher.d.ts +121 -0
  45. package/dist/lib/sse/rooms/SSERoomEventPublisher.js +119 -0
  46. package/dist/lib/sse/rooms/SSERoomEventPublisher.js.map +1 -0
  47. package/dist/lib/sse/rooms/index.d.ts +1 -0
  48. package/dist/lib/sse/rooms/index.js +1 -0
  49. package/dist/lib/sse/rooms/index.js.map +1 -1
  50. package/dist/lib/testing/apiSseEventValidation.d.ts +1 -1
  51. package/dist/lib/testing/apiSseInjectHelpers.js +9 -10
  52. package/dist/lib/testing/apiSseInjectHelpers.js.map +1 -1
  53. package/dist/lib/testing/sseHttpClient.d.ts +10 -2
  54. package/dist/lib/testing/sseHttpClient.js +13 -6
  55. package/dist/lib/testing/sseHttpClient.js.map +1 -1
  56. package/dist/lib/testing/sseInjectClient.d.ts +1 -1
  57. package/dist/lib/testing/sseInjectClient.js +1 -1
  58. package/dist/lib/testing/sseInjectClient.js.map +1 -1
  59. package/dist/lib/testing/sseTestTypes.d.ts +1 -1
  60. package/package.json +13 -13
  61. package/dist/lib/sse/sseParser.d.ts +0 -167
  62. package/dist/lib/sse/sseParser.js +0 -225
  63. package/dist/lib/sse/sseParser.js.map +0 -1
@@ -50,7 +50,11 @@ export declare class DIContext<Dependencies extends object, Config extends objec
50
50
  * like `@opinionated-machine/gateway-envoy` or
51
51
  * `@opinionated-machine/gateway-krakend` to produce a config.
52
52
  *
53
- * SSE and dual-mode controllers are not included in v1.
53
+ * SSE and dual-mode routes declared through `AbstractApiController` are
54
+ * always included and carry a `streaming: 'sse' | 'dual'` marker. Routes
55
+ * from legacy `AbstractSSEController` / `AbstractDualModeController`
56
+ * controllers are included only when `includeStreamingControllers: true`
57
+ * is passed (off by default so existing manifests don't silently grow).
54
58
  *
55
59
  * @example
56
60
  * ```ts
@@ -116,6 +120,14 @@ export declare class DIContext<Dependencies extends object, Config extends objec
116
120
  registerDualModeRoutes(app: FastifyInstance<any, any, any, any>, options?: RegisterDualModeRoutesOptions): void;
117
121
  private applyDualModeRouteOptions;
118
122
  private applySSERouteOptions;
123
+ /**
124
+ * Apply registration-time options to an SSE/dual-mode route before app.route().
125
+ *
126
+ * Shared by the SSE-only and dual-mode registration paths: both apply the same
127
+ * pre-handlers, rate limit and `sse` field defaults. Route-level options
128
+ * (buildHandler / buildApiRoute) take precedence over these.
129
+ */
130
+ private applyStreamRouteOptions;
119
131
  private applyPreHandlers;
120
132
  private applyRateLimit;
121
133
  destroy(): Promise<void>;
@@ -159,7 +159,11 @@ export class DIContext {
159
159
  * like `@opinionated-machine/gateway-envoy` or
160
160
  * `@opinionated-machine/gateway-krakend` to produce a config.
161
161
  *
162
- * SSE and dual-mode controllers are not included in v1.
162
+ * SSE and dual-mode routes declared through `AbstractApiController` are
163
+ * always included and carry a `streaming: 'sse' | 'dual'` marker. Routes
164
+ * from legacy `AbstractSSEController` / `AbstractDualModeController`
165
+ * controllers are included only when `includeStreamingControllers: true`
166
+ * is passed (off by default so existing manifests don't silently grow).
163
167
  *
164
168
  * @example
165
169
  * ```ts
@@ -183,6 +187,18 @@ export class DIContext {
183
187
  const controller = this.diContainer.resolve(name);
184
188
  collected.push({ name, kind: 'api', controller });
185
189
  }
190
+ if (options.includeStreamingControllers) {
191
+ for (const name of this.sseControllerNames) {
192
+ // biome-ignore lint/suspicious/noExplicitAny: any SSE controller works here
193
+ const controller = this.diContainer.resolve(name);
194
+ collected.push({ name, kind: 'sse-legacy', controller });
195
+ }
196
+ for (const name of this.dualModeControllerNames) {
197
+ // biome-ignore lint/suspicious/noExplicitAny: any dual-mode controller works here
198
+ const controller = this.diContainer.resolve(name);
199
+ collected.push({ name, kind: 'dualmode-legacy', controller });
200
+ }
201
+ }
186
202
  return buildGatewayManifestFrom(collected, options);
187
203
  }
188
204
  /**
@@ -273,15 +289,19 @@ export class DIContext {
273
289
  }
274
290
  }
275
291
  applyDualModeRouteOptions(route, options) {
276
- if (options?.preHandler) {
277
- this.applyPreHandlers(route, options.preHandler);
278
- }
279
- if (options?.rateLimit) {
280
- this.applyRateLimit(route, options.rateLimit);
281
- }
282
- applyGlobalSSEOptions(route, options);
292
+ this.applyStreamRouteOptions(route, options);
283
293
  }
284
294
  applySSERouteOptions(route, options) {
295
+ this.applyStreamRouteOptions(route, options);
296
+ }
297
+ /**
298
+ * Apply registration-time options to an SSE/dual-mode route before app.route().
299
+ *
300
+ * Shared by the SSE-only and dual-mode registration paths: both apply the same
301
+ * pre-handlers, rate limit and `sse` field defaults. Route-level options
302
+ * (buildHandler / buildApiRoute) take precedence over these.
303
+ */
304
+ applyStreamRouteOptions(route, options) {
285
305
  if (options?.preHandler) {
286
306
  this.applyPreHandlers(route, options.preHandler);
287
307
  }
@@ -1 +1 @@
1
- {"version":3,"file":"DIContext.js","sourceRoot":"","sources":["../../lib/DIContext.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"DIContext.js","sourceRoot":"","sources":["../../lib/DIContext.ts"],"names":[],"mappings":"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"}
@@ -1,7 +1,9 @@
1
- import { type ApiContract } from '@lokalise/api-contracts';
1
+ import type { ApiContract } from '@lokalise/api-contracts';
2
2
  import { type ApiRouteOptions as FastifyApiRouteOptions, type InferApiHandler } from '@lokalise/fastify-api-contracts';
3
3
  import type { RouteOptions } from 'fastify';
4
4
  import type { GatewayMetadata } from '../gateway/gatewayTypes.ts';
5
+ import type { SSERoomBroadcaster } from '../sse/rooms/SSERoomBroadcaster.ts';
6
+ import { type SSERoomsOptions } from './apiSseConnectionRegistry.ts';
5
7
  /**
6
8
  * Options for configuring an ApiContract route.
7
9
  *
@@ -46,6 +48,42 @@ export type ApiRouteOptions<Contract extends ApiContract> = FastifyApiRouteOptio
46
48
  * ```
47
49
  */
48
50
  gatewayMetadata?: GatewayMetadata<Contract>;
51
+ /**
52
+ * Enable SSE rooms for this route by passing the shared `SSERoomBroadcaster`
53
+ * from the DI container. Sessions opened by the route's SSE handler are
54
+ * registered with the broadcaster (so `broadcastToRoom`/`broadcastMessage`
55
+ * reach them), get room operations via {@link getSessionRooms}, and are
56
+ * cleaned up (rooms left, dedup cache cleared) when the connection closes.
57
+ *
58
+ * Without this option `getSessionRooms()` returns no-ops and the session
59
+ * receives no room broadcasts.
60
+ *
61
+ * Pass an {@link SSERoomsOptions} object instead of the bare broadcaster to
62
+ * declare an `authorizeJoin` scope check (so a room name built from a path
63
+ * param cannot leak across tenants) and a `maxSessionLifetimeMs` bound (so
64
+ * authorization checked at connect cannot stay in force forever).
65
+ *
66
+ * @example
67
+ * ```ts
68
+ * buildApiRoute(contracts.watchProject, this.watch, { sseRooms: this.roomBroadcaster })
69
+ * // inside the handler:
70
+ * const session = sse.start('keepAlive')
71
+ * getSessionRooms(session).join(`project:${request.params.projectId}`)
72
+ * ```
73
+ *
74
+ * @example
75
+ * ```ts
76
+ * buildApiRoute(contracts.watchProject, this.watch, {
77
+ * sseRooms: {
78
+ * broadcaster: this.roomBroadcaster,
79
+ * authorizeJoin: (session, room) =>
80
+ * this.membership.canRead(session.request.user, room),
81
+ * maxSessionLifetimeMs: 30 * 60 * 1000,
82
+ * },
83
+ * })
84
+ * ```
85
+ */
86
+ sseRooms?: SSERoomBroadcaster | SSERoomsOptions;
49
87
  };
50
88
  /**
51
89
  * Build a Fastify `RouteOptions` object from an `ApiContract` + handler.
@@ -56,10 +94,14 @@ export type ApiRouteOptions<Contract extends ApiContract> = FastifyApiRouteOptio
56
94
  * See its docs for the `(request, reply, context) => { status, body }`
57
95
  * handler model and `context.sse` streaming.
58
96
  *
59
- * On top of the package builder this adds one option: `gatewayMetadata` —
60
- * per-route gateway policy with header / query keys narrowed to the
61
- * contract; equivalent to wrapping the result with `withGatewayMetadata`.
62
- * See `ApiRouteOptions` for full details.
97
+ * On top of the package builder this adds:
98
+ * - `gatewayMetadata` — per-route gateway policy with header / query keys
99
+ * narrowed to the contract; equivalent to wrapping the result with
100
+ * `withGatewayMetadata`. See `ApiRouteOptions` for full details.
101
+ * - `sseRooms` — wires SSE rooms for the route (see `ApiRouteOptions`).
102
+ * - a `streaming: 'sse' | 'dual'` marker on SSE-capable routes, read back by
103
+ * the gateway manifest builder so generators can apply streaming-appropriate
104
+ * timeouts and buffering.
63
105
  *
64
106
  * @returns Fastify `RouteOptions` ready to pass to `app.route()`
65
107
  */
@@ -1,7 +1,41 @@
1
- import { getSseSchemaByEventName, } from '@lokalise/api-contracts';
1
+ import { getSseSchemaByEventName, hasAnySuccessSseResponse, isContentResponseEntry, isSseBody, SUCCESSFUL_HTTP_STATUS_CODES, } from '@lokalise/api-contracts';
2
2
  import { buildFastifyApiRoute, } from '@lokalise/fastify-api-contracts';
3
+ import { attachRouteStreamingMode } from "../gateway/routeStreaming.js";
3
4
  import { attachGatewayMetadata } from "../gateway/withGatewayMetadata.js";
4
5
  import { attachSSESendDiagnostics, reportSSEHandlerOutcome } from "../sse/sseSendDiagnostics.js";
6
+ import { withSessionRooms } from "./apiSseConnectionRegistry.js";
7
+ /**
8
+ * True when the contract's success response for a status code has a non-SSE
9
+ * representation as well — i.e. the route can answer a plain HTTP request.
10
+ */
11
+ function isSuccessResponseDual(value) {
12
+ if (isContentResponseEntry(value)) {
13
+ // A content-map entry offers a non-SSE representation when it allows an empty
14
+ // body or declares any non-SSE media type descriptor.
15
+ if (value.allowNoBody || !value.content)
16
+ return true;
17
+ return Object.values(value.content).some((descriptor) => !isSseBody(descriptor));
18
+ }
19
+ // A bare Zod schema is a JSON response, which always has a non-SSE representation.
20
+ return true;
21
+ }
22
+ /**
23
+ * Derive how a contract streams, for the gateway streaming marker.
24
+ *
25
+ * Mirrors `ContractResponseMode` from `@lokalise/api-contracts` at runtime:
26
+ * a contract with no SSE success response is plain, one whose SSE statuses all
27
+ * lack a non-SSE representation is `'sse'`, and one that offers both is `'dual'`.
28
+ */
29
+ function getContractStreamingMode(contract) {
30
+ if (!hasAnySuccessSseResponse(contract))
31
+ return undefined;
32
+ for (const code of SUCCESSFUL_HTTP_STATUS_CODES) {
33
+ const value = contract.responsesByStatusCode[code];
34
+ if (value && isSuccessResponseDual(value))
35
+ return 'dual';
36
+ }
37
+ return 'sse';
38
+ }
5
39
  /**
6
40
  * Build a Fastify `RouteOptions` object from an `ApiContract` + handler.
7
41
  *
@@ -11,24 +45,39 @@ import { attachSSESendDiagnostics, reportSSEHandlerOutcome } from "../sse/sseSen
11
45
  * See its docs for the `(request, reply, context) => { status, body }`
12
46
  * handler model and `context.sse` streaming.
13
47
  *
14
- * On top of the package builder this adds one option: `gatewayMetadata` —
15
- * per-route gateway policy with header / query keys narrowed to the
16
- * contract; equivalent to wrapping the result with `withGatewayMetadata`.
17
- * See `ApiRouteOptions` for full details.
48
+ * On top of the package builder this adds:
49
+ * - `gatewayMetadata` — per-route gateway policy with header / query keys
50
+ * narrowed to the contract; equivalent to wrapping the result with
51
+ * `withGatewayMetadata`. See `ApiRouteOptions` for full details.
52
+ * - `sseRooms` — wires SSE rooms for the route (see `ApiRouteOptions`).
53
+ * - a `streaming: 'sse' | 'dual'` marker on SSE-capable routes, read back by
54
+ * the gateway manifest builder so generators can apply streaming-appropriate
55
+ * timeouts and buffering.
18
56
  *
19
57
  * @returns Fastify `RouteOptions` ready to pass to `app.route()`
20
58
  */
21
59
  export function buildApiRoute(contract, handler, options) {
22
- // Gateway metadata is stamped via Symbol, not spread into Fastify options.
23
- const { gatewayMetadata, ...fastifyOptions } = options ?? {};
60
+ // Gateway metadata is stamped via Symbol, not spread into Fastify options;
61
+ // `sseRooms` is framework-level and composed into the SSE lifecycle hooks.
62
+ const { gatewayMetadata, sseRooms, ...passthroughOptions } = options ?? {};
63
+ const fastifyOptions = sseRooms
64
+ ? withSessionRooms(sseRooms, passthroughOptions)
65
+ : passthroughOptions;
24
66
  const schemaByEventName = getSseSchemaByEventName(contract);
25
67
  const built = buildFastifyApiRoute(contract, handler, schemaByEventName ? withSendDiagnostics(fastifyOptions, schemaByEventName) : fastifyOptions);
26
68
  // Recording a failed send is only half of the diagnostic: whether the route recovered from
27
69
  // it decides whether a test reading the stream should fail on it. That is what the handler's
28
- // own outcome says, so it is observed here — for scoped requests only.
70
+ // own outcome says, so it is observed here, for scoped requests only.
29
71
  const route = schemaByEventName
30
72
  ? { ...built, handler: reportSSEHandlerOutcome(built.handler) }
31
73
  : built;
74
+ // Mark streaming routes (derived from the contract's response mode) so
75
+ // gateway generators can apply streaming-appropriate timeouts/buffering.
76
+ // After the spread above: it drops the non-enumerable symbol the stamp sets.
77
+ const streamingMode = getContractStreamingMode(contract);
78
+ if (streamingMode) {
79
+ attachRouteStreamingMode(route, streamingMode);
80
+ }
32
81
  return gatewayMetadata !== undefined ? attachGatewayMetadata(route, gatewayMetadata) : route;
33
82
  }
34
83
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"apiRouteBuilder.js","sourceRoot":"","sources":["../../../lib/api-contracts/apiRouteBuilder.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,uBAAuB,GAExB,MAAM,yBAAyB,CAAA;AAChC,OAAO,EACL,oBAAoB,GAGrB,MAAM,iCAAiC,CAAA;AAGxC,OAAO,EAAE,qBAAqB,EAAE,MAAM,mCAAmC,CAAA;AACzE,OAAO,EAAE,wBAAwB,EAAE,uBAAuB,EAAE,MAAM,8BAA8B,CAAA;AAgDhG;;;;;;;;;;;;;;;GAeG;AACH,MAAM,UAAU,aAAa,CAC3B,QAAkB,EAClB,OAAkC,EAClC,OAAmC;IAEnC,2EAA2E;IAC3E,MAAM,EAAE,eAAe,EAAE,GAAG,cAAc,EAAE,GAAG,OAAO,IAAI,EAAE,CAAA;IAC5D,MAAM,iBAAiB,GAAG,uBAAuB,CAAC,QAAQ,CAAC,CAAA;IAC3D,MAAM,KAAK,GAAG,oBAAoB,CAChC,QAAQ,EACR,OAAO,EACP,iBAAiB,CAAC,CAAC,CAAC,mBAAmB,CAAC,cAAc,EAAE,iBAAiB,CAAC,CAAC,CAAC,CAAC,cAAc,CAC5F,CAAA;IACD,2FAA2F;IAC3F,6FAA6F;IAC7F,uEAAuE;IACvE,MAAM,KAAK,GAAG,iBAAiB;QAC7B,CAAC,CAAC,EAAE,GAAG,KAAK,EAAE,OAAO,EAAE,uBAAuB,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE;QAC/D,CAAC,CAAC,KAAK,CAAA;IACT,OAAO,eAAe,KAAK,SAAS,CAAC,CAAC,CAAC,qBAAqB,CAAC,KAAK,EAAE,eAAe,CAAC,CAAC,CAAC,CAAC,KAAK,CAAA;AAC9F,CAAC;AAED;;;;;;;;;;;;;GAaG;AACH,SAAS,mBAAmB,CAC1B,OAA+B,EAC/B,iBAAkC;IAElC,MAAM,EAAE,SAAS,EAAE,GAAG,OAAO,CAAA;IAC7B,OAAO;QACL,GAAG,OAAO;QACV,uFAAuF;QACvF,+DAA+D;QAC/D,SAAS,EAAE,CAAC,OAAO,EAAE,EAAE;YACrB,wBAAwB,CAAC,OAAO,EAAE,iBAAiB,CAAC,CAAA;YACpD,OAAO,SAAS,EAAE,CAAC,OAAO,CAAC,CAAA;QAC7B,CAAC;KACF,CAAA;AACH,CAAC"}
1
+ {"version":3,"file":"apiRouteBuilder.js","sourceRoot":"","sources":["../../../lib/api-contracts/apiRouteBuilder.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,182 @@
1
+ import type { SSEEventSchemas } from '@lokalise/api-contracts';
2
+ import type { ApiRouteOptions as FastifyApiRouteOptions, SSESession } from '@lokalise/fastify-api-contracts';
3
+ import type { SSERoomBroadcaster } from '../sse/rooms/SSERoomBroadcaster.ts';
4
+ import type { SSERoomOperations } from '../sse/rooms/types.ts';
5
+ import type { SSEMessage } from '../sse/sseTypes.ts';
6
+ /**
7
+ * A join whose `authorizeJoin` verdict has not resolved yet.
8
+ *
9
+ * An async verdict lands after `join()` has already returned, so anything that
10
+ * revokes access in between (a `leave`, an `evictFromRoom`, an eviction, a
11
+ * closed room, the session closing) has to be able to cancel it. Without that
12
+ * the resolved verdict re-adds the connection to a room it was just removed
13
+ * from, and the revocation silently does not stick.
14
+ */
15
+ export type PendingJoin = {
16
+ readonly room: string;
17
+ cancelled: boolean;
18
+ };
19
+ export declare class ApiSseConnectionRegistry {
20
+ private readonly connections;
21
+ /** In-flight async joins per connection id. Empty for a synchronous verdict. */
22
+ private readonly pendingJoins;
23
+ private readonly broadcaster;
24
+ constructor(broadcaster: SSERoomBroadcaster);
25
+ /**
26
+ * Register an active SSE connection with its send function.
27
+ * The send function must return `false` (not throw) on delivery failure so
28
+ * room broadcasts keep fanning out to the remaining connections.
29
+ *
30
+ * Pass `close` to make the connection evictable — without it {@link evict}
31
+ * can stop delivery but cannot terminate the stream.
32
+ */
33
+ register(connectionId: string, send: (message: SSEMessage) => Promise<boolean>, close?: () => void): void;
34
+ /**
35
+ * Remove a connection: drops the sender, leaves all rooms, and clears the
36
+ * broadcaster's dedup cache for the connection.
37
+ */
38
+ unregister(connectionId: string): void;
39
+ /**
40
+ * Record an async `authorizeJoin` verdict that is still in flight, so a
41
+ * revocation arriving before it resolves can cancel it.
42
+ *
43
+ * Pair every call with {@link settlePendingJoin}; the room wiring in
44
+ * {@link withSessionRooms} does this for routes.
45
+ */
46
+ beginPendingJoin(connectionId: string, room: string): PendingJoin;
47
+ /**
48
+ * Retire an in-flight join.
49
+ *
50
+ * @returns `true` when the join is still valid and may be applied, `false`
51
+ * when it was cancelled while the verdict was pending.
52
+ */
53
+ settlePendingJoin(connectionId: string, pending: PendingJoin): boolean;
54
+ /**
55
+ * Cancel in-flight joins for a connection — all of them, or only those for
56
+ * one room. A cancelled join is dropped when its verdict resolves.
57
+ *
58
+ * @returns How many joins were cancelled.
59
+ */
60
+ cancelPendingJoins(connectionId: string, room?: string): number;
61
+ /**
62
+ * Terminate one connection: leave its rooms, stop delivering to it, and
63
+ * close its stream.
64
+ *
65
+ * This is the revocation path. Authorization is checked when a stream opens
66
+ * and then goes stale, so removing a principal's access has to be able to
67
+ * end the streams that access already opened; without a call like this, a
68
+ * revoked user keeps receiving broadcasts until they close the tab.
69
+ *
70
+ * A client that reconnects (as `@opinionated-machine/sse-fallback` does)
71
+ * comes back through the route's own authorization, so an eviction of a
72
+ * still-authorized principal costs a reconnect, not a broken surface.
73
+ *
74
+ * @returns `true` when a connection was registered under that id.
75
+ */
76
+ evict(connectionId: string): boolean;
77
+ /**
78
+ * Remove one connection from one room, leaving its other rooms and its
79
+ * stream intact. For revoking access to a single scope.
80
+ *
81
+ * A join whose async `authorizeJoin` verdict is still pending counts as
82
+ * membership here: the connection is not in the room yet, but it is about to
83
+ * be, and letting that land after a revocation would undo it.
84
+ *
85
+ * @returns `true` when the connection was in the room, or was on its way in.
86
+ */
87
+ evictFromRoom(room: string, connectionId: string): boolean;
88
+ /**
89
+ * Evict every connection currently in a room, terminating their streams.
90
+ * For revoking a whole scope (a deleted project, a disbanded team).
91
+ *
92
+ * Only connections on THIS node are closed — room membership elsewhere in
93
+ * the cluster is another node's registry to evict, so a revocation event
94
+ * has to reach every node.
95
+ *
96
+ * Joins still awaiting an async `authorizeJoin` verdict are cancelled rather
97
+ * than evicted: they hold no membership yet, so the revocation just denies
98
+ * them the room and leaves their other rooms and their stream alone. They
99
+ * are not counted in the return value for the same reason.
100
+ *
101
+ * @returns How many connections were evicted here.
102
+ */
103
+ closeRoom(room: string): number;
104
+ }
105
+ /**
106
+ * Get (or lazily create) the shared registry for a broadcaster.
107
+ * Ensures `registerSender` is called exactly once per broadcaster no matter
108
+ * how many routes opt into rooms.
109
+ */
110
+ export declare function getApiSseConnectionRegistry(broadcaster: SSERoomBroadcaster): ApiSseConnectionRegistry;
111
+ /**
112
+ * Room operations for an SSE session opened by a `buildApiRoute` route.
113
+ *
114
+ * Returns no-ops when the route did not pass `sseRooms` — mirroring the legacy
115
+ * `session.rooms` accessor, which is inert on controllers without a broadcaster.
116
+ *
117
+ * @example
118
+ * ```ts
119
+ * const session = sse.start('keepAlive')
120
+ * getSessionRooms(session).join(`project:${request.params.projectId}`)
121
+ * ```
122
+ */
123
+ export declare function getSessionRooms<Events extends SSEEventSchemas, Context>(session: SSESession<Events, Context>): SSERoomOperations;
124
+ /**
125
+ * Room wiring for a route, when the bare broadcaster is not enough.
126
+ *
127
+ * Pass an `SSERoomBroadcaster` directly for the default behaviour; pass this
128
+ * object to add a scope check on joins and a bounded session lifetime.
129
+ */
130
+ export type SSERoomsOptions = {
131
+ /** The broadcaster whose rooms this route's sessions join. */
132
+ broadcaster: SSERoomBroadcaster;
133
+ /**
134
+ * Decide whether a session may join a room. Declared once per route, so the
135
+ * scope check is not left to every handler body.
136
+ *
137
+ * Without it, `getSessionRooms(session).join(room)` joins whatever room
138
+ * string the handler names, and nothing checks that the authenticated
139
+ * principal belongs to that room's scope — a path param read straight into
140
+ * a room name is a cross-tenant leak.
141
+ *
142
+ * Return `false` (or reject) to refuse; the refusal is logged on the
143
+ * request logger and the join is dropped. A synchronous verdict is applied
144
+ * before `join()` returns; an async one is applied when it resolves, so the
145
+ * session joins a moment later — the client's reconciliation poll covers
146
+ * anything broadcast in between. A `leave`, an `evictFromRoom`, an `evict`,
147
+ * a `closeRoom` or the session closing while the verdict is pending cancels
148
+ * it, so a revocation cannot be undone by a join that was already in flight.
149
+ */
150
+ authorizeJoin?: (session: SSESession, room: string) => boolean | Promise<boolean>;
151
+ /**
152
+ * Close the session gracefully after this many milliseconds.
153
+ *
154
+ * Authorization is checked when the stream opens and then goes stale: a
155
+ * principal removed from a scope keeps receiving events for as long as the
156
+ * connection lives. A bounded lifetime forces a reconnect, and the reconnect
157
+ * re-runs authentication and authorization — making this both the
158
+ * token-refresh mechanism and the backstop for a revocation that never
159
+ * reached {@link ApiSseConnectionRegistry.evict}.
160
+ *
161
+ * A client that treats a server close as a routine reconnect (with
162
+ * `Last-Event-ID` and a reconciliation poll, as
163
+ * `@opinionated-machine/sse-fallback` does) makes this invisible to users.
164
+ */
165
+ maxSessionLifetimeMs?: number;
166
+ };
167
+ /**
168
+ * Compose room wiring into a route's SSE lifecycle hooks.
169
+ *
170
+ * On connect the session is registered with the broadcaster's registry and its
171
+ * room operations are published for {@link getSessionRooms}; on close the
172
+ * connection is unregistered (rooms left, dedup cache cleared). The route's own
173
+ * `onConnect` / `onClose` hooks still run — room wiring is applied first on
174
+ * connect (so a hook can already join rooms) and last on close.
175
+ *
176
+ * `onConnect` is invoked synchronously by the package's `sse.start()`, so the
177
+ * registration is in place before `start()` returns to the handler.
178
+ *
179
+ * Pass {@link SSERoomsOptions} instead of a bare broadcaster to add an
180
+ * `authorizeJoin` scope check or a `maxSessionLifetimeMs` bound.
181
+ */
182
+ export declare function withSessionRooms<Options extends FastifyApiRouteOptions>(config: SSERoomBroadcaster | SSERoomsOptions, options: Options): Options;