@solidjs/web 2.0.0-beta.26 → 2.0.0-beta.27

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 (39) hide show
  1. package/dist/dev.cjs +3 -1
  2. package/dist/dev.js +3 -2
  3. package/dist/server.cjs +41 -78
  4. package/dist/server.js +42 -80
  5. package/dist/web.cjs +3 -1
  6. package/dist/web.js +3 -2
  7. package/frames/dist/client.cjs +69 -21
  8. package/frames/dist/client.dev.cjs +69 -21
  9. package/frames/dist/client.dev.js +70 -22
  10. package/frames/dist/client.js +70 -22
  11. package/frames/dist/server.cjs +33 -45
  12. package/frames/dist/server.js +33 -45
  13. package/package.json +4 -4
  14. package/serialization/dist/serialization.cjs +6 -3
  15. package/serialization/dist/serialization.js +6 -3
  16. package/serialization/types/index.d.ts +7 -1
  17. package/serialization/types-cjs/index.d.cts +7 -1
  18. package/server-functions/dist/client.cjs +15 -2
  19. package/server-functions/dist/client.js +13 -3
  20. package/server-functions/dist/server.cjs +161 -5
  21. package/server-functions/dist/server.js +155 -6
  22. package/types/client.d.ts +3 -3
  23. package/types/frames/serializer.d.ts +7 -1
  24. package/types/jsx.d.ts +1 -1
  25. package/types/response.d.ts +10 -0
  26. package/types/serializer.d.ts +7 -1
  27. package/types/server-functions/client.d.ts +3 -0
  28. package/types/server-functions/flash.d.ts +38 -0
  29. package/types/server-functions/server.d.ts +79 -4
  30. package/types/server-functions/shared.d.ts +35 -0
  31. package/types-cjs/client.d.cts +3 -3
  32. package/types-cjs/frames/serializer.d.cts +7 -1
  33. package/types-cjs/jsx.d.cts +1 -1
  34. package/types-cjs/response.d.cts +10 -0
  35. package/types-cjs/serializer.d.cts +7 -1
  36. package/types-cjs/server-functions/client.d.cts +3 -0
  37. package/types-cjs/server-functions/flash.d.cts +38 -0
  38. package/types-cjs/server-functions/server.d.cts +79 -4
  39. package/types-cjs/server-functions/shared.d.cts +35 -0
@@ -4,13 +4,16 @@ import { RequestEvent } from "../server.js";
4
4
 
5
5
  export {
6
6
  ERROR_HEADER,
7
+ FLASH_COOKIE,
7
8
  FUNCTION_HEADER,
8
9
  INSTANCE_HEADER,
9
10
  SINGLE_FLIGHT_HEADER,
11
+ clearFlashCookie,
10
12
  decodeErrorHeaderValue,
11
13
  decodeResponse,
12
14
  encodeErrorHeaderValue,
13
15
  getServerFunctionMetadata,
16
+ hasFlashCookie,
14
17
  isServerFunction,
15
18
  subscribeFlightData,
16
19
  withMeta
@@ -22,6 +25,8 @@ export type {
22
25
  ServerFunctionMetadata,
23
26
  SingleFlightPayload
24
27
  } from "./shared.js";
28
+ export { decodeFlashCookie, encodeFlashCookie } from "./flash.js";
29
+ export type { FlashSubmission } from "./flash.js";
25
30
  import { ServerFunction } from "./shared.js";
26
31
 
27
32
  /**
@@ -85,6 +90,57 @@ export type CollectFlightDataHook = (
85
90
  outcome: ServerFunctionOutcome
86
91
  ) => unknown | Promise<unknown>;
87
92
 
93
+ /**
94
+ * Request headers with `setCookies` folded into the `Cookie` header, as the
95
+ * browser would have applied them before its next request. Later entries
96
+ * win on conflict, and deletions are honored (`Max-Age` at or below zero,
97
+ * `Expires` in the past). The input headers are not modified.
98
+ *
99
+ * For work re-run on the server after a mutation — a
100
+ * `CollectFlightDataHook` gathering fresh data, typically. That pass starts
101
+ * from the request that triggered the mutation, whose cookies are
102
+ * pre-mutation by definition, so a read depending on a session the mutation
103
+ * just established would otherwise see the old state. Which responses
104
+ * contribute their `Set-Cookie`s, and in what order, is the caller's
105
+ * decision.
106
+ *
107
+ * @example
108
+ * ```ts
109
+ * const headers = foldSetCookies(event.request.headers, [
110
+ * ...(event.response?.headers?.getSetCookie() ?? []),
111
+ * ...(outcome.response?.headers?.getSetCookie() ?? [])
112
+ * ]);
113
+ * ```
114
+ */
115
+ export function foldSetCookies(headers: Headers, setCookies: readonly string[]): Headers;
116
+
117
+ /** Options for `createNoJSHandler`. */
118
+ export interface NoJSHandlerOptions {
119
+ /** The app's mount path, for resolving a relative redirect `Location`. */
120
+ base?: string;
121
+ }
122
+
123
+ /**
124
+ * Builds the `handleNoJS` implementation for the no-JS form convention: a
125
+ * form posted without the client runtime has no way to receive a value, so
126
+ * the call redirects back to the referring page (or to the result's own
127
+ * `Location`, resolved against `base`) with the outcome riding a one-shot
128
+ * flash cookie. `303 See Other` turns the POST into a GET unless the result
129
+ * names a redirect status of its own. A result that is already a `Response`
130
+ * carries its meaning in its metadata and is not flashed.
131
+ *
132
+ * The render that follows reads the cookie with `decodeFlashCookie` and
133
+ * surfaces the outcome however it likes — that half is the integration's.
134
+ *
135
+ * The handler applies to every call it receives. `handleServerFunctionRequest`
136
+ * already uses it for browser form posts, so wire it explicitly only to set
137
+ * a `base`, or to extend the convention to direct HTTP calls by registering
138
+ * it through `configureServerFunctionsServer`.
139
+ */
140
+ export function createNoJSHandler(
141
+ options?: NoJSHandlerOptions
142
+ ): (result: unknown, request: Request, args: unknown[], thrown?: boolean) => Response;
143
+
88
144
  /** Options for `configureServerFunctionsServer`. */
89
145
  export interface ServerFunctionsServerConfig {
90
146
  /**
@@ -119,6 +175,23 @@ export interface ServerFunctionsServerConfig {
119
175
  * calls during document SSR — e.g. frames' `frameTransformDirectResult`.
120
176
  */
121
177
  transformDirectResult?(value: unknown, options: { id: string }): unknown;
178
+ /**
179
+ * Server-wide response builder for calls made without the client runtime
180
+ * (see `handleNoJS` in `HandleServerFunctionRequestOptions`); a
181
+ * per-request option overrides it. Set it to `createNoJSHandler({ base })`
182
+ * to apply the convention to every non-scripted call rather than only to
183
+ * browser form posts, to a handler of your own to replace it, or to
184
+ * `null` to disable the built-in convention and answer form posts with
185
+ * the plain serialized response.
186
+ */
187
+ handleNoJS?:
188
+ | ((
189
+ result: unknown,
190
+ request: Request,
191
+ args: unknown[],
192
+ thrown?: boolean
193
+ ) => Response | Promise<Response>)
194
+ | null;
122
195
  /**
123
196
  * Endpoint the HTTP handler is mounted on, used for the `url` of SSR'd
124
197
  * references (e.g. form actions) — must match the client configuration.
@@ -285,11 +358,13 @@ export interface HandleServerFunctionOptions {
285
358
  collectFlightData?: CollectFlightDataHook;
286
359
  /**
287
360
  * Builds the response for calls made without the client runtime (no
288
- * instance header — no-JS form posts, direct HTTP) the extension
289
- * point for conventions like redirect-with-flash-cookie. Receives the
361
+ * instance header — no-JS form posts, direct HTTP). Receives the
290
362
  * (transformed) result, the request, and the decoded arguments; `thrown`
291
- * is set when the result was thrown rather than returned. Defaults to
292
- * the normal serialized response.
363
+ * is set when the result was thrown rather than returned.
364
+ *
365
+ * Overrides the configured hook, which in turn overrides the built-in
366
+ * `createNoJSHandler()` applied to browser form posts. Other
367
+ * no-instance callers get the normal serialized response.
293
368
  */
294
369
  handleNoJS?(
295
370
  result: unknown,
@@ -136,6 +136,41 @@ export type FlightDataConsumer<D = unknown> = (
136
136
  */
137
137
  export function subscribeFlightData<D = unknown>(consumer: FlightDataConsumer<D>): () => void;
138
138
 
139
+ /**
140
+ * Name of the cookie carrying the outcome of a call made without the client
141
+ * runtime (`"flash"`). A no-JS form post has no way to receive a value —
142
+ * the browser follows the redirect and renders the next page — so the
143
+ * handler stashes the outcome here for the render after it to pick up,
144
+ * which is how a form submitted without JavaScript still shows its result.
145
+ *
146
+ * The name, detection and clearing are isomorphic (integrations read the
147
+ * cookie from code that also ships to the browser); the codec that fills it
148
+ * is server-only and lives behind the server entry.
149
+ */
150
+ export const FLASH_COOKIE: string;
151
+
152
+ /**
153
+ * Whether a Cookie header carries a flash cookie, readable or not. Cheap
154
+ * enough to call on every render so the clear can be queued before the
155
+ * response headers flush.
156
+ */
157
+ export function hasFlashCookie(cookieHeader: string | null): boolean;
158
+
159
+ /**
160
+ * The `Set-Cookie` value clearing the flash cookie. The outcome is
161
+ * one-shot: append this as soon as the cookie is detected, whether or not
162
+ * it decodes, so a stale outcome cannot resurface on a later request.
163
+ */
164
+ export function clearFlashCookie(): string;
165
+
166
+ /**
167
+ * The raw encoded flash payload out of a Cookie header, if present — the
168
+ * codec's own accessor.
169
+ *
170
+ * @internal
171
+ */
172
+ export function matchFlashCookie(cookieHeader: string | null): string | undefined;
173
+
139
174
  /**
140
175
  * The currently registered single-flight consumer.
141
176
  *
@@ -109,9 +109,9 @@ export function style(
109
109
  export function getOwner(): unknown;
110
110
  export function mergeProps(...sources: unknown[]): unknown;
111
111
  export function dynamicProperty(props: unknown, key: string): unknown;
112
- export function applyRef(
113
- r: ((element: Element) => void) | ((element: Element) => void)[],
114
- element: Element
112
+ export function applyRef<T extends Element = Element>(
113
+ r: ((element: NoInfer<T>) => void) | ((element: NoInfer<T>) => void)[],
114
+ element: T
115
115
  ): void;
116
116
  export function ref(
117
117
  fn: () => ((element: Element) => void) | ((element: Element) => void)[],
@@ -37,7 +37,9 @@ export interface WebSerializerOptions {
37
37
  scopeId?: string;
38
38
  /**
39
39
  * Seroval feature bitflags to exclude from output. Defaults to disabling
40
- * post-ES2017 features (AggregateError, BigInt typed arrays).
40
+ * post-ES2017 features (AggregateError, BigInt typed arrays). Outside
41
+ * development, `Error.prototype.stack` is additionally stripped on top of
42
+ * any override — serialized stacks leak server paths to the client.
41
43
  */
42
44
  disabledFeatures?: number;
43
45
  /** Extra plugins, composed ahead of `DEFAULT_WEB_PLUGINS`. */
@@ -101,6 +103,10 @@ export interface JSONCodecOptions {
101
103
  /**
102
104
  * Seroval feature bitflags to exclude. Defaults to disabling `RegExp`
103
105
  * (payloads may come from an untrusted peer). Must match on both peers.
106
+ * Outside development, the encoding side additionally strips
107
+ * `Error.prototype.stack` on top of any override — serialized stacks leak
108
+ * server paths to the client. Decoding stays permissive, so payloads from
109
+ * a development peer still round-trip.
104
110
  */
105
111
  disabledFeatures?: number;
106
112
  /** Maximum parse/deserialize depth. Defaults to 64. Must match on both peers. */
@@ -240,7 +240,7 @@ export namespace JSX {
240
240
  }
241
241
 
242
242
  type RefCallback<T> = (el: T) => void;
243
- type Ref<T> = T | RefCallback<T> | (RefCallback<T> | Ref<T>)[];
243
+ type Ref<T> = T | RefCallback<T> | Ref<T>[];
244
244
 
245
245
  interface IntrinsicAttributes {
246
246
  ref?: Ref<unknown> | undefined;
@@ -49,6 +49,16 @@ export interface Href {
49
49
  */
50
50
  export function isHref(value: unknown): value is Href;
51
51
 
52
+ /**
53
+ * Response header naming the cache keys a mutation invalidated
54
+ * (`"X-Revalidate"`), comma separated. The response helpers below set it
55
+ * from their `revalidate` option; the client transport treats its presence
56
+ * as control flow, and integrations read it to invalidate their own cache.
57
+ * Core never inspects the keys, so how they are matched (prefixes, exact
58
+ * names, namespaces) is the integration's business.
59
+ */
60
+ export const REVALIDATE_HEADER: string;
61
+
52
62
  /** `ResponseInit` accepted by the response helpers, plus `revalidate`. */
53
63
  export interface ResponseHelperInit extends ResponseInit {
54
64
  /**
@@ -37,7 +37,9 @@ export interface WebSerializerOptions {
37
37
  scopeId?: string;
38
38
  /**
39
39
  * Seroval feature bitflags to exclude from output. Defaults to disabling
40
- * post-ES2017 features (AggregateError, BigInt typed arrays).
40
+ * post-ES2017 features (AggregateError, BigInt typed arrays). Outside
41
+ * development, `Error.prototype.stack` is additionally stripped on top of
42
+ * any override — serialized stacks leak server paths to the client.
41
43
  */
42
44
  disabledFeatures?: number;
43
45
  /** Extra plugins, composed ahead of `DEFAULT_WEB_PLUGINS`. */
@@ -101,6 +103,10 @@ export interface JSONCodecOptions {
101
103
  /**
102
104
  * Seroval feature bitflags to exclude. Defaults to disabling `RegExp`
103
105
  * (payloads may come from an untrusted peer). Must match on both peers.
106
+ * Outside development, the encoding side additionally strips
107
+ * `Error.prototype.stack` on top of any override — serialized stacks leak
108
+ * server paths to the client. Decoding stays permissive, so payloads from
109
+ * a development peer still round-trip.
104
110
  */
105
111
  disabledFeatures?: number;
106
112
  /** Maximum parse/deserialize depth. Defaults to 64. Must match on both peers. */
@@ -3,13 +3,16 @@ import { ServerFunction, ServerFunctionMetadata } from "./shared.cjs";
3
3
 
4
4
  export {
5
5
  ERROR_HEADER,
6
+ FLASH_COOKIE,
6
7
  FUNCTION_HEADER,
7
8
  INSTANCE_HEADER,
8
9
  SINGLE_FLIGHT_HEADER,
10
+ clearFlashCookie,
9
11
  decodeErrorHeaderValue,
10
12
  decodeResponse,
11
13
  encodeErrorHeaderValue,
12
14
  getServerFunctionMetadata,
15
+ hasFlashCookie,
13
16
  isServerFunction,
14
17
  subscribeFlightData,
15
18
  withMeta
@@ -0,0 +1,38 @@
1
+ /**
2
+ * The outcome of a call made without the client runtime, as it rides the
3
+ * flash cookie: what was submitted, where, and what came back. `result` and
4
+ * `error` are mutually exclusive — a thrown outcome fills `error`, a
5
+ * returned one fills `result` — mirroring the split a scripted call sees.
6
+ */
7
+ export interface FlashSubmission {
8
+ /** The arguments the call was made with (files are dropped). */
9
+ input: any[];
10
+ /** The call's url: pathname + search of the server function request. */
11
+ url: string;
12
+ /** The returned value, when the call returned. */
13
+ result?: any;
14
+ /** The thrown value, when the call threw. */
15
+ error?: any;
16
+ }
17
+
18
+ /**
19
+ * Encodes the outcome of a no-JS call as a `Set-Cookie` value, for the
20
+ * handler to send with its redirect. `url` identifies which submission the
21
+ * outcome belongs to; pass `thrown` when the call threw rather than
22
+ * returned.
23
+ *
24
+ * The payload is JSON inside the cookie: `FormData` and `URLSearchParams`
25
+ * arguments are captured as entry pairs and revived on decode, and `File`
26
+ * entries are dropped (they cannot ride a cookie). Keep in mind the 4 KB
27
+ * cookie budget — outcomes larger than that will not survive the round
28
+ * trip.
29
+ */
30
+ export function encodeFlashCookie(url: string, result: any, input: any[], thrown?: boolean): string;
31
+
32
+ /**
33
+ * Decodes the flash cookie out of a request's `Cookie` header, for the
34
+ * render that follows the redirect. Returns undefined when the cookie is
35
+ * absent or unreadable — a malformed cookie never takes down the render,
36
+ * and `clearFlashCookie` should be appended regardless.
37
+ */
38
+ export function decodeFlashCookie(cookieHeader: string | null): FlashSubmission | undefined;
@@ -4,13 +4,16 @@ import { RequestEvent } from "../server.cjs";
4
4
 
5
5
  export {
6
6
  ERROR_HEADER,
7
+ FLASH_COOKIE,
7
8
  FUNCTION_HEADER,
8
9
  INSTANCE_HEADER,
9
10
  SINGLE_FLIGHT_HEADER,
11
+ clearFlashCookie,
10
12
  decodeErrorHeaderValue,
11
13
  decodeResponse,
12
14
  encodeErrorHeaderValue,
13
15
  getServerFunctionMetadata,
16
+ hasFlashCookie,
14
17
  isServerFunction,
15
18
  subscribeFlightData,
16
19
  withMeta
@@ -22,6 +25,8 @@ export type {
22
25
  ServerFunctionMetadata,
23
26
  SingleFlightPayload
24
27
  } from "./shared.cjs";
28
+ export { decodeFlashCookie, encodeFlashCookie } from "./flash.cjs";
29
+ export type { FlashSubmission } from "./flash.cjs";
25
30
  import { ServerFunction } from "./shared.cjs";
26
31
 
27
32
  /**
@@ -85,6 +90,57 @@ export type CollectFlightDataHook = (
85
90
  outcome: ServerFunctionOutcome
86
91
  ) => unknown | Promise<unknown>;
87
92
 
93
+ /**
94
+ * Request headers with `setCookies` folded into the `Cookie` header, as the
95
+ * browser would have applied them before its next request. Later entries
96
+ * win on conflict, and deletions are honored (`Max-Age` at or below zero,
97
+ * `Expires` in the past). The input headers are not modified.
98
+ *
99
+ * For work re-run on the server after a mutation — a
100
+ * `CollectFlightDataHook` gathering fresh data, typically. That pass starts
101
+ * from the request that triggered the mutation, whose cookies are
102
+ * pre-mutation by definition, so a read depending on a session the mutation
103
+ * just established would otherwise see the old state. Which responses
104
+ * contribute their `Set-Cookie`s, and in what order, is the caller's
105
+ * decision.
106
+ *
107
+ * @example
108
+ * ```ts
109
+ * const headers = foldSetCookies(event.request.headers, [
110
+ * ...(event.response?.headers?.getSetCookie() ?? []),
111
+ * ...(outcome.response?.headers?.getSetCookie() ?? [])
112
+ * ]);
113
+ * ```
114
+ */
115
+ export function foldSetCookies(headers: Headers, setCookies: readonly string[]): Headers;
116
+
117
+ /** Options for `createNoJSHandler`. */
118
+ export interface NoJSHandlerOptions {
119
+ /** The app's mount path, for resolving a relative redirect `Location`. */
120
+ base?: string;
121
+ }
122
+
123
+ /**
124
+ * Builds the `handleNoJS` implementation for the no-JS form convention: a
125
+ * form posted without the client runtime has no way to receive a value, so
126
+ * the call redirects back to the referring page (or to the result's own
127
+ * `Location`, resolved against `base`) with the outcome riding a one-shot
128
+ * flash cookie. `303 See Other` turns the POST into a GET unless the result
129
+ * names a redirect status of its own. A result that is already a `Response`
130
+ * carries its meaning in its metadata and is not flashed.
131
+ *
132
+ * The render that follows reads the cookie with `decodeFlashCookie` and
133
+ * surfaces the outcome however it likes — that half is the integration's.
134
+ *
135
+ * The handler applies to every call it receives. `handleServerFunctionRequest`
136
+ * already uses it for browser form posts, so wire it explicitly only to set
137
+ * a `base`, or to extend the convention to direct HTTP calls by registering
138
+ * it through `configureServerFunctionsServer`.
139
+ */
140
+ export function createNoJSHandler(
141
+ options?: NoJSHandlerOptions
142
+ ): (result: unknown, request: Request, args: unknown[], thrown?: boolean) => Response;
143
+
88
144
  /** Options for `configureServerFunctionsServer`. */
89
145
  export interface ServerFunctionsServerConfig {
90
146
  /**
@@ -119,6 +175,23 @@ export interface ServerFunctionsServerConfig {
119
175
  * calls during document SSR — e.g. frames' `frameTransformDirectResult`.
120
176
  */
121
177
  transformDirectResult?(value: unknown, options: { id: string }): unknown;
178
+ /**
179
+ * Server-wide response builder for calls made without the client runtime
180
+ * (see `handleNoJS` in `HandleServerFunctionRequestOptions`); a
181
+ * per-request option overrides it. Set it to `createNoJSHandler({ base })`
182
+ * to apply the convention to every non-scripted call rather than only to
183
+ * browser form posts, to a handler of your own to replace it, or to
184
+ * `null` to disable the built-in convention and answer form posts with
185
+ * the plain serialized response.
186
+ */
187
+ handleNoJS?:
188
+ | ((
189
+ result: unknown,
190
+ request: Request,
191
+ args: unknown[],
192
+ thrown?: boolean
193
+ ) => Response | Promise<Response>)
194
+ | null;
122
195
  /**
123
196
  * Endpoint the HTTP handler is mounted on, used for the `url` of SSR'd
124
197
  * references (e.g. form actions) — must match the client configuration.
@@ -285,11 +358,13 @@ export interface HandleServerFunctionOptions {
285
358
  collectFlightData?: CollectFlightDataHook;
286
359
  /**
287
360
  * Builds the response for calls made without the client runtime (no
288
- * instance header — no-JS form posts, direct HTTP) the extension
289
- * point for conventions like redirect-with-flash-cookie. Receives the
361
+ * instance header — no-JS form posts, direct HTTP). Receives the
290
362
  * (transformed) result, the request, and the decoded arguments; `thrown`
291
- * is set when the result was thrown rather than returned. Defaults to
292
- * the normal serialized response.
363
+ * is set when the result was thrown rather than returned.
364
+ *
365
+ * Overrides the configured hook, which in turn overrides the built-in
366
+ * `createNoJSHandler()` applied to browser form posts. Other
367
+ * no-instance callers get the normal serialized response.
293
368
  */
294
369
  handleNoJS?(
295
370
  result: unknown,
@@ -136,6 +136,41 @@ export type FlightDataConsumer<D = unknown> = (
136
136
  */
137
137
  export function subscribeFlightData<D = unknown>(consumer: FlightDataConsumer<D>): () => void;
138
138
 
139
+ /**
140
+ * Name of the cookie carrying the outcome of a call made without the client
141
+ * runtime (`"flash"`). A no-JS form post has no way to receive a value —
142
+ * the browser follows the redirect and renders the next page — so the
143
+ * handler stashes the outcome here for the render after it to pick up,
144
+ * which is how a form submitted without JavaScript still shows its result.
145
+ *
146
+ * The name, detection and clearing are isomorphic (integrations read the
147
+ * cookie from code that also ships to the browser); the codec that fills it
148
+ * is server-only and lives behind the server entry.
149
+ */
150
+ export const FLASH_COOKIE: string;
151
+
152
+ /**
153
+ * Whether a Cookie header carries a flash cookie, readable or not. Cheap
154
+ * enough to call on every render so the clear can be queued before the
155
+ * response headers flush.
156
+ */
157
+ export function hasFlashCookie(cookieHeader: string | null): boolean;
158
+
159
+ /**
160
+ * The `Set-Cookie` value clearing the flash cookie. The outcome is
161
+ * one-shot: append this as soon as the cookie is detected, whether or not
162
+ * it decodes, so a stale outcome cannot resurface on a later request.
163
+ */
164
+ export function clearFlashCookie(): string;
165
+
166
+ /**
167
+ * The raw encoded flash payload out of a Cookie header, if present — the
168
+ * codec's own accessor.
169
+ *
170
+ * @internal
171
+ */
172
+ export function matchFlashCookie(cookieHeader: string | null): string | undefined;
173
+
139
174
  /**
140
175
  * The currently registered single-flight consumer.
141
176
  *