@trpc/server 11.0.0-alpha-tmp-subscription-connection-state.489 → 11.0.0-alpha-tmp-12-06-react.665
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/dist/@trpc/server/http.d.ts +1 -1
- package/dist/@trpc/server/http.d.ts.map +1 -1
- package/dist/@trpc/server/index.d.ts +1 -1
- package/dist/@trpc/server/index.d.ts.map +1 -1
- package/dist/adapters/aws-lambda/getPlanner.d.ts.map +1 -1
- package/dist/adapters/aws-lambda/getPlanner.js +2 -2
- package/dist/adapters/aws-lambda/getPlanner.mjs +2 -2
- package/dist/adapters/aws-lambda/index.d.ts.map +1 -1
- package/dist/adapters/aws-lambda/index.js +2 -0
- package/dist/adapters/aws-lambda/index.mjs +2 -0
- package/dist/adapters/express.d.ts.map +1 -1
- package/dist/adapters/express.js +27 -7
- package/dist/adapters/express.mjs +27 -7
- package/dist/adapters/fastify/fastifyRequestHandler.js +3 -1
- package/dist/adapters/fastify/fastifyRequestHandler.mjs +3 -1
- package/dist/adapters/fastify/fastifyTRPCPlugin.d.ts.map +1 -1
- package/dist/adapters/fastify/fastifyTRPCPlugin.js +9 -2
- package/dist/adapters/fastify/fastifyTRPCPlugin.mjs +10 -3
- package/dist/adapters/fetch/fetchRequestHandler.js +9 -8
- package/dist/adapters/fetch/fetchRequestHandler.mjs +9 -8
- package/dist/adapters/next-app-dir/nextAppDirCaller.d.ts.map +1 -1
- package/dist/adapters/next-app-dir/nextAppDirCaller.js +10 -5
- package/dist/adapters/next-app-dir/nextAppDirCaller.mjs +10 -5
- package/dist/adapters/next-app-dir/notFound.js +2 -0
- package/dist/adapters/next-app-dir/notFound.mjs +2 -0
- package/dist/adapters/next-app-dir/redirect.js +16 -1
- package/dist/adapters/next-app-dir/redirect.mjs +16 -1
- package/dist/adapters/next-app-dir/rethrowNextErrors.d.ts.map +1 -1
- package/dist/adapters/next-app-dir/rethrowNextErrors.js +4 -3
- package/dist/adapters/next-app-dir/rethrowNextErrors.mjs +4 -3
- package/dist/adapters/next.d.ts.map +1 -1
- package/dist/adapters/next.js +23 -30
- package/dist/adapters/next.mjs +24 -31
- package/dist/adapters/node-http/incomingMessageToRequest.d.ts +2 -1
- package/dist/adapters/node-http/incomingMessageToRequest.d.ts.map +1 -1
- package/dist/adapters/node-http/incomingMessageToRequest.js +83 -40
- package/dist/adapters/node-http/incomingMessageToRequest.mjs +83 -41
- package/dist/adapters/node-http/index.js +2 -0
- package/dist/adapters/node-http/index.mjs +2 -2
- package/dist/adapters/node-http/nodeHTTPRequestHandler.d.ts +7 -0
- package/dist/adapters/node-http/nodeHTTPRequestHandler.d.ts.map +1 -1
- package/dist/adapters/node-http/nodeHTTPRequestHandler.js +70 -58
- package/dist/adapters/node-http/nodeHTTPRequestHandler.mjs +70 -59
- package/dist/adapters/node-http/writeResponse.d.ts +18 -0
- package/dist/adapters/node-http/writeResponse.d.ts.map +1 -0
- package/dist/adapters/node-http/writeResponse.js +82 -0
- package/dist/adapters/node-http/writeResponse.mjs +79 -0
- package/dist/adapters/standalone.d.ts +5 -2
- package/dist/adapters/standalone.d.ts.map +1 -1
- package/dist/adapters/standalone.js +25 -13
- package/dist/adapters/standalone.mjs +26 -14
- package/dist/adapters/ws.d.ts +14 -4
- package/dist/adapters/ws.d.ts.map +1 -1
- package/dist/adapters/ws.js +217 -101
- package/dist/adapters/ws.mjs +217 -102
- package/dist/bundle-analysis.json +412 -310
- package/dist/http.js +2 -4
- package/dist/http.mjs +2 -2
- package/dist/index.js +3 -0
- package/dist/index.mjs +3 -1
- package/dist/node_modules/.pnpm/@rollup_plugin-typescript@12.1.1_rollup@4.27.4_tslib@2.8.1_typescript@5.7.2/node_modules/tslib/tslib.es6.js +73 -0
- package/dist/observable/behaviorSubject.d.ts +15 -0
- package/dist/observable/behaviorSubject.d.ts.map +1 -0
- package/dist/observable/behaviorSubject.js +40 -0
- package/dist/observable/behaviorSubject.mjs +38 -0
- package/dist/observable/index.d.ts +3 -3
- package/dist/observable/index.d.ts.map +1 -1
- package/dist/observable/index.js +5 -0
- package/dist/observable/index.mjs +3 -2
- package/dist/observable/observable.d.ts +2 -1
- package/dist/observable/observable.d.ts.map +1 -1
- package/dist/observable/observable.js +31 -8
- package/dist/observable/observable.mjs +31 -8
- package/dist/observable/operators.d.ts +2 -0
- package/dist/observable/operators.d.ts.map +1 -1
- package/dist/observable/operators.js +35 -0
- package/dist/observable/operators.mjs +34 -1
- package/dist/rpc.js +2 -0
- package/dist/rpc.mjs +2 -0
- package/dist/shared.js +2 -0
- package/dist/shared.mjs +2 -0
- package/dist/unstable-core-do-not-import/clientish/inference.d.ts.map +1 -1
- package/dist/unstable-core-do-not-import/clientish/inferrable.d.ts.map +1 -1
- package/dist/unstable-core-do-not-import/clientish/serialize.d.ts +2 -2
- package/dist/unstable-core-do-not-import/clientish/serialize.d.ts.map +1 -1
- package/dist/unstable-core-do-not-import/createProxy.js +1 -1
- package/dist/unstable-core-do-not-import/createProxy.mjs +1 -1
- package/dist/unstable-core-do-not-import/error/TRPCError.d.ts +1 -1
- package/dist/unstable-core-do-not-import/error/TRPCError.js +16 -1
- package/dist/unstable-core-do-not-import/error/TRPCError.mjs +16 -1
- package/dist/unstable-core-do-not-import/error/formatter.js +1 -1
- package/dist/unstable-core-do-not-import/error/formatter.mjs +1 -1
- package/dist/unstable-core-do-not-import/error/getErrorShape.js +2 -2
- package/dist/unstable-core-do-not-import/error/getErrorShape.mjs +2 -2
- package/dist/unstable-core-do-not-import/http/contentType.js +3 -3
- package/dist/unstable-core-do-not-import/http/contentType.mjs +3 -3
- package/dist/unstable-core-do-not-import/http/getHTTPStatusCode.d.ts +6 -1
- package/dist/unstable-core-do-not-import/http/getHTTPStatusCode.d.ts.map +1 -1
- package/dist/unstable-core-do-not-import/http/getHTTPStatusCode.js +28 -0
- package/dist/unstable-core-do-not-import/http/getHTTPStatusCode.mjs +25 -1
- package/dist/unstable-core-do-not-import/http/isAbortError.d.ts +4 -0
- package/dist/unstable-core-do-not-import/http/isAbortError.d.ts.map +1 -0
- package/dist/unstable-core-do-not-import/http/isAbortError.js +9 -0
- package/dist/unstable-core-do-not-import/http/isAbortError.mjs +7 -0
- package/dist/unstable-core-do-not-import/http/resolveResponse.d.ts.map +1 -1
- package/dist/unstable-core-do-not-import/http/resolveResponse.js +180 -96
- package/dist/unstable-core-do-not-import/http/resolveResponse.mjs +182 -98
- package/dist/unstable-core-do-not-import/http/types.d.ts +1 -1
- package/dist/unstable-core-do-not-import/initTRPC.d.ts +11 -11
- package/dist/unstable-core-do-not-import/initTRPC.d.ts.map +1 -1
- package/dist/unstable-core-do-not-import/initTRPC.js +11 -11
- package/dist/unstable-core-do-not-import/initTRPC.mjs +11 -11
- package/dist/unstable-core-do-not-import/middleware.d.ts +2 -1
- package/dist/unstable-core-do-not-import/middleware.d.ts.map +1 -1
- package/dist/unstable-core-do-not-import/middleware.js +2 -2
- package/dist/unstable-core-do-not-import/middleware.mjs +2 -2
- package/dist/unstable-core-do-not-import/parser.d.ts +5 -1
- package/dist/unstable-core-do-not-import/parser.d.ts.map +1 -1
- package/dist/unstable-core-do-not-import/parser.js +4 -0
- package/dist/unstable-core-do-not-import/parser.mjs +4 -0
- package/dist/unstable-core-do-not-import/procedure.d.ts +8 -2
- package/dist/unstable-core-do-not-import/procedure.d.ts.map +1 -1
- package/dist/unstable-core-do-not-import/procedureBuilder.d.ts +31 -12
- package/dist/unstable-core-do-not-import/procedureBuilder.d.ts.map +1 -1
- package/dist/unstable-core-do-not-import/procedureBuilder.js +33 -39
- package/dist/unstable-core-do-not-import/procedureBuilder.mjs +33 -39
- package/dist/unstable-core-do-not-import/rootConfig.d.ts +17 -17
- package/dist/unstable-core-do-not-import/rootConfig.d.ts.map +1 -1
- package/dist/unstable-core-do-not-import/router.d.ts +4 -3
- package/dist/unstable-core-do-not-import/router.d.ts.map +1 -1
- package/dist/unstable-core-do-not-import/router.js +6 -5
- package/dist/unstable-core-do-not-import/router.mjs +6 -5
- package/dist/unstable-core-do-not-import/rpc/codes.d.ts +2 -9
- package/dist/unstable-core-do-not-import/rpc/codes.d.ts.map +1 -1
- package/dist/unstable-core-do-not-import/rpc/envelopes.d.ts +7 -10
- package/dist/unstable-core-do-not-import/rpc/envelopes.d.ts.map +1 -1
- package/dist/unstable-core-do-not-import/rpc/parseTRPCMessage.js +2 -2
- package/dist/unstable-core-do-not-import/rpc/parseTRPCMessage.mjs +2 -2
- package/dist/unstable-core-do-not-import/stream/jsonl.d.ts +25 -14
- package/dist/unstable-core-do-not-import/stream/jsonl.d.ts.map +1 -1
- package/dist/unstable-core-do-not-import/stream/jsonl.js +439 -318
- package/dist/unstable-core-do-not-import/stream/jsonl.mjs +439 -318
- package/dist/unstable-core-do-not-import/stream/sse.d.ts +58 -18
- package/dist/unstable-core-do-not-import/stream/sse.d.ts.map +1 -1
- package/dist/unstable-core-do-not-import/stream/sse.js +297 -122
- package/dist/unstable-core-do-not-import/stream/sse.mjs +298 -123
- package/dist/unstable-core-do-not-import/stream/sse.types.d.ts +31 -0
- package/dist/unstable-core-do-not-import/stream/sse.types.d.ts.map +1 -0
- package/dist/unstable-core-do-not-import/stream/tracked.d.ts +2 -2
- package/dist/unstable-core-do-not-import/stream/tracked.d.ts.map +1 -1
- package/dist/unstable-core-do-not-import/stream/tracked.js +1 -1
- package/dist/unstable-core-do-not-import/stream/tracked.mjs +1 -1
- package/dist/unstable-core-do-not-import/stream/utils/asyncIterable.d.ts +17 -0
- package/dist/unstable-core-do-not-import/stream/utils/asyncIterable.d.ts.map +1 -0
- package/dist/unstable-core-do-not-import/stream/utils/asyncIterable.js +171 -0
- package/dist/unstable-core-do-not-import/stream/utils/asyncIterable.mjs +167 -0
- package/dist/unstable-core-do-not-import/stream/utils/createDeferred.d.ts +0 -11
- package/dist/unstable-core-do-not-import/stream/utils/createDeferred.d.ts.map +1 -1
- package/dist/unstable-core-do-not-import/stream/utils/createDeferred.js +0 -29
- package/dist/unstable-core-do-not-import/stream/utils/createDeferred.mjs +1 -29
- package/dist/unstable-core-do-not-import/stream/utils/disposable.d.ts +17 -0
- package/dist/unstable-core-do-not-import/stream/utils/disposable.d.ts.map +1 -0
- package/dist/unstable-core-do-not-import/stream/utils/disposable.js +44 -0
- package/dist/unstable-core-do-not-import/stream/utils/disposable.mjs +41 -0
- package/dist/unstable-core-do-not-import/stream/utils/readableStreamFrom.d.ts +8 -0
- package/dist/unstable-core-do-not-import/stream/utils/readableStreamFrom.d.ts.map +1 -0
- package/dist/unstable-core-do-not-import/stream/utils/readableStreamFrom.js +25 -0
- package/dist/unstable-core-do-not-import/stream/utils/readableStreamFrom.mjs +23 -0
- package/dist/unstable-core-do-not-import/stream/utils/timerResource.d.ts +5 -0
- package/dist/unstable-core-do-not-import/stream/utils/timerResource.d.ts.map +1 -0
- package/dist/unstable-core-do-not-import/stream/utils/timerResource.js +26 -0
- package/dist/unstable-core-do-not-import/stream/utils/timerResource.mjs +23 -0
- package/dist/unstable-core-do-not-import/stream/utils/withPing.d.ts +7 -0
- package/dist/unstable-core-do-not-import/stream/utils/withPing.d.ts.map +1 -0
- package/dist/unstable-core-do-not-import/stream/utils/withPing.js +130 -0
- package/dist/unstable-core-do-not-import/stream/utils/withPing.mjs +127 -0
- package/dist/unstable-core-do-not-import/transformer.d.ts +2 -5
- package/dist/unstable-core-do-not-import/transformer.d.ts.map +1 -1
- package/dist/unstable-core-do-not-import/transformer.js +1 -1
- package/dist/unstable-core-do-not-import/transformer.mjs +1 -1
- package/dist/unstable-core-do-not-import/types.d.ts +26 -3
- package/dist/unstable-core-do-not-import/types.d.ts.map +1 -1
- package/dist/unstable-core-do-not-import/utils.d.ts +15 -0
- package/dist/unstable-core-do-not-import/utils.d.ts.map +1 -1
- package/dist/unstable-core-do-not-import/utils.js +49 -1
- package/dist/unstable-core-do-not-import/utils.mjs +45 -2
- package/dist/unstable-core-do-not-import.d.ts +3 -2
- package/dist/unstable-core-do-not-import.d.ts.map +1 -1
- package/dist/unstable-core-do-not-import.js +14 -7
- package/dist/unstable-core-do-not-import.mjs +5 -6
- package/dist/vendor/unpromise/index.d.ts +3 -0
- package/dist/vendor/unpromise/index.d.ts.map +1 -0
- package/dist/vendor/unpromise/types.d.ts +28 -0
- package/dist/vendor/unpromise/types.d.ts.map +1 -0
- package/dist/vendor/unpromise/unpromise.d.ts +121 -0
- package/dist/vendor/unpromise/unpromise.d.ts.map +1 -0
- package/dist/vendor/unpromise/unpromise.js +292 -0
- package/dist/vendor/unpromise/unpromise.mjs +289 -0
- package/package.json +20 -17
- package/src/@trpc/server/http.ts +0 -2
- package/src/@trpc/server/index.ts +2 -0
- package/src/adapters/aws-lambda/getPlanner.ts +2 -2
- package/src/adapters/aws-lambda/index.ts +5 -6
- package/src/adapters/express.ts +21 -9
- package/src/adapters/fastify/fastifyRequestHandler.ts +1 -1
- package/src/adapters/fastify/fastifyTRPCPlugin.ts +16 -5
- package/src/adapters/fetch/fetchRequestHandler.ts +2 -2
- package/src/adapters/next-app-dir/nextAppDirCaller.ts +3 -0
- package/src/adapters/next-app-dir/rethrowNextErrors.ts +3 -2
- package/src/adapters/next.ts +29 -34
- package/src/adapters/node-http/incomingMessageToRequest.ts +110 -40
- package/src/adapters/node-http/nodeHTTPRequestHandler.ts +85 -63
- package/src/adapters/node-http/writeResponse.ts +94 -0
- package/src/adapters/standalone.ts +35 -18
- package/src/adapters/ws.ts +111 -57
- package/src/observable/behaviorSubject.ts +55 -0
- package/src/observable/index.ts +22 -3
- package/src/observable/observable.ts +32 -14
- package/src/observable/operators.ts +47 -0
- package/src/unstable-core-do-not-import/clientish/inference.ts +4 -4
- package/src/unstable-core-do-not-import/clientish/inferrable.ts +6 -6
- package/src/unstable-core-do-not-import/clientish/serialize.ts +5 -5
- package/src/unstable-core-do-not-import/http/getHTTPStatusCode.ts +37 -4
- package/src/unstable-core-do-not-import/http/isAbortError.ts +7 -0
- package/src/unstable-core-do-not-import/http/resolveResponse.ts +185 -90
- package/src/unstable-core-do-not-import/http/types.ts +1 -1
- package/src/unstable-core-do-not-import/initTRPC.ts +14 -20
- package/src/unstable-core-do-not-import/middleware.ts +5 -4
- package/src/unstable-core-do-not-import/parser.ts +17 -6
- package/src/unstable-core-do-not-import/procedure.ts +17 -2
- package/src/unstable-core-do-not-import/procedureBuilder.ts +137 -122
- package/src/unstable-core-do-not-import/rootConfig.ts +20 -20
- package/src/unstable-core-do-not-import/router.ts +15 -16
- package/src/unstable-core-do-not-import/rpc/codes.ts +2 -10
- package/src/unstable-core-do-not-import/rpc/envelopes.ts +7 -12
- package/src/unstable-core-do-not-import/stream/jsonl.ts +287 -296
- package/src/unstable-core-do-not-import/stream/sse.ts +338 -171
- package/src/unstable-core-do-not-import/stream/sse.types.ts +44 -0
- package/src/unstable-core-do-not-import/stream/tracked.ts +5 -11
- package/src/unstable-core-do-not-import/stream/utils/asyncIterable.ts +89 -0
- package/src/unstable-core-do-not-import/stream/utils/createDeferred.ts +0 -36
- package/src/unstable-core-do-not-import/stream/utils/disposable.ts +52 -0
- package/src/unstable-core-do-not-import/stream/utils/readableStreamFrom.ts +28 -0
- package/src/unstable-core-do-not-import/stream/utils/timerResource.ts +29 -0
- package/src/unstable-core-do-not-import/stream/utils/withPing.ts +47 -0
- package/src/unstable-core-do-not-import/transformer.ts +1 -1
- package/src/unstable-core-do-not-import/types.ts +35 -10
- package/src/unstable-core-do-not-import/utils.ts +56 -1
- package/src/unstable-core-do-not-import.ts +3 -2
- package/src/vendor/unpromise/ATTRIBUTION.txt +1 -0
- package/src/vendor/unpromise/LICENSE +20 -0
- package/src/vendor/unpromise/index.ts +7 -0
- package/src/vendor/unpromise/types.ts +55 -0
- package/src/vendor/unpromise/unpromise.ts +380 -0
- package/dist/unstable-core-do-not-import/http/batchStreamFormatter.d.ts +0 -24
- package/dist/unstable-core-do-not-import/http/batchStreamFormatter.d.ts.map +0 -1
- package/dist/unstable-core-do-not-import/http/batchStreamFormatter.js +0 -32
- package/dist/unstable-core-do-not-import/http/batchStreamFormatter.mjs +0 -30
- package/dist/unstable-core-do-not-import/http/toURL.d.ts +0 -2
- package/dist/unstable-core-do-not-import/http/toURL.d.ts.map +0 -1
- package/dist/unstable-core-do-not-import/http/toURL.js +0 -8
- package/dist/unstable-core-do-not-import/http/toURL.mjs +0 -6
- package/dist/unstable-core-do-not-import/stream/utils/createReadableStream.d.ts +0 -10
- package/dist/unstable-core-do-not-import/stream/utils/createReadableStream.d.ts.map +0 -1
- package/dist/unstable-core-do-not-import/stream/utils/createReadableStream.js +0 -31
- package/dist/unstable-core-do-not-import/stream/utils/createReadableStream.mjs +0 -29
- package/dist/unstable-core-do-not-import/stream/utils/createServer.d.ts +0 -7
- package/dist/unstable-core-do-not-import/stream/utils/createServer.d.ts.map +0 -1
- package/dist/unstable-core-do-not-import/types.js +0 -11
- package/dist/unstable-core-do-not-import/types.mjs +0 -9
- package/src/unstable-core-do-not-import/http/batchStreamFormatter.ts +0 -29
- package/src/unstable-core-do-not-import/http/toURL.ts +0 -7
- package/src/unstable-core-do-not-import/stream/utils/createReadableStream.ts +0 -31
- package/src/unstable-core-do-not-import/stream/utils/createServer.ts +0 -44
|
@@ -1,10 +1,19 @@
|
|
|
1
|
+
import { Unpromise } from '../../vendor/unpromise';
|
|
1
2
|
import { getTRPCErrorFromUnknown } from '../error/TRPCError';
|
|
2
|
-
import {
|
|
3
|
-
import type {
|
|
3
|
+
import { isAbortError } from '../http/isAbortError';
|
|
4
|
+
import type { MaybePromise } from '../types';
|
|
5
|
+
import { identity, run } from '../utils';
|
|
6
|
+
import type { EventSourceLike } from './sse.types';
|
|
4
7
|
import type { inferTrackedOutput } from './tracked';
|
|
5
8
|
import { isTrackedEnvelope } from './tracked';
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
9
|
+
import { takeWithGrace, withMaxDuration } from './utils/asyncIterable';
|
|
10
|
+
import { makeAsyncResource } from './utils/disposable';
|
|
11
|
+
import { readableStreamFrom } from './utils/readableStreamFrom';
|
|
12
|
+
import {
|
|
13
|
+
disposablePromiseTimerResult,
|
|
14
|
+
timerResource,
|
|
15
|
+
} from './utils/timerResource';
|
|
16
|
+
import { PING_SYM, withPing } from './utils/withPing';
|
|
8
17
|
|
|
9
18
|
type Serialize = (value: any) => any;
|
|
10
19
|
type Deserialize = (value: any) => any;
|
|
@@ -12,7 +21,7 @@ type Deserialize = (value: any) => any;
|
|
|
12
21
|
/**
|
|
13
22
|
* @internal
|
|
14
23
|
*/
|
|
15
|
-
export interface
|
|
24
|
+
export interface SSEPingOptions {
|
|
16
25
|
/**
|
|
17
26
|
* Enable ping comments sent from the server
|
|
18
27
|
* @default false
|
|
@@ -25,14 +34,22 @@ export interface PingOptions {
|
|
|
25
34
|
intervalMs?: number;
|
|
26
35
|
}
|
|
27
36
|
|
|
28
|
-
export interface
|
|
37
|
+
export interface SSEClientOptions {
|
|
38
|
+
/**
|
|
39
|
+
* Timeout and reconnect after inactivity in milliseconds
|
|
40
|
+
* @default undefined
|
|
41
|
+
*/
|
|
42
|
+
reconnectAfterInactivityMs?: number;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export interface SSEStreamProducerOptions<TValue = unknown> {
|
|
29
46
|
serialize?: Serialize;
|
|
30
|
-
data: AsyncIterable<
|
|
47
|
+
data: AsyncIterable<TValue>;
|
|
48
|
+
|
|
31
49
|
maxDepth?: number;
|
|
32
|
-
ping?:
|
|
50
|
+
ping?: SSEPingOptions;
|
|
33
51
|
/**
|
|
34
52
|
* Maximum duration in milliseconds for the request before ending the stream
|
|
35
|
-
* Only useful for serverless runtimes
|
|
36
53
|
* @default undefined
|
|
37
54
|
*/
|
|
38
55
|
maxDurationMs?: number;
|
|
@@ -43,120 +60,127 @@ export interface SSEStreamProducerOptions {
|
|
|
43
60
|
*/
|
|
44
61
|
emitAndEndImmediately?: boolean;
|
|
45
62
|
formatError?: (opts: { error: unknown }) => unknown;
|
|
63
|
+
/**
|
|
64
|
+
* Client-specific options - these will be sent to the client as part of the first message
|
|
65
|
+
* @default {}
|
|
66
|
+
*/
|
|
67
|
+
client?: SSEClientOptions;
|
|
46
68
|
}
|
|
47
69
|
|
|
70
|
+
const PING_EVENT = 'ping';
|
|
48
71
|
const SERIALIZED_ERROR_EVENT = 'serialized-error';
|
|
72
|
+
const CONNECTED_EVENT = 'connected';
|
|
49
73
|
|
|
50
|
-
|
|
51
|
-
id
|
|
74
|
+
interface SSEvent {
|
|
75
|
+
id?: string;
|
|
52
76
|
data: unknown;
|
|
53
|
-
comment
|
|
54
|
-
event
|
|
55
|
-
}
|
|
77
|
+
comment?: string;
|
|
78
|
+
event?: string;
|
|
79
|
+
}
|
|
56
80
|
/**
|
|
57
81
|
*
|
|
58
82
|
* @see https://html.spec.whatwg.org/multipage/server-sent-events.html
|
|
59
83
|
*/
|
|
60
|
-
export function sseStreamProducer
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
});
|
|
84
|
+
export function sseStreamProducer<TValue = unknown>(
|
|
85
|
+
opts: SSEStreamProducerOptions<TValue>,
|
|
86
|
+
) {
|
|
87
|
+
const { serialize = identity } = opts;
|
|
65
88
|
|
|
66
|
-
const
|
|
67
|
-
|
|
68
|
-
const ping: Required<PingOptions> = {
|
|
89
|
+
const ping: Required<SSEPingOptions> = {
|
|
69
90
|
enabled: opts.ping?.enabled ?? false,
|
|
70
91
|
intervalMs: opts.ping?.intervalMs ?? 1000,
|
|
71
92
|
};
|
|
93
|
+
const client: SSEClientOptions = opts.client ?? {};
|
|
72
94
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
95
|
+
if (
|
|
96
|
+
ping.enabled &&
|
|
97
|
+
client.reconnectAfterInactivityMs &&
|
|
98
|
+
ping.intervalMs > client.reconnectAfterInactivityMs
|
|
99
|
+
) {
|
|
100
|
+
throw new Error(
|
|
101
|
+
`Ping interval must be less than client reconnect interval to prevent unnecessary reconnection - ping.intervalMs: ${ping.intervalMs} client.reconnectAfterInactivityMs: ${client.reconnectAfterInactivityMs}`,
|
|
80
102
|
);
|
|
103
|
+
}
|
|
81
104
|
|
|
82
|
-
|
|
105
|
+
async function* generator(): AsyncIterable<SSEvent, void> {
|
|
106
|
+
yield {
|
|
107
|
+
event: CONNECTED_EVENT,
|
|
108
|
+
data: JSON.stringify(client),
|
|
109
|
+
};
|
|
83
110
|
|
|
84
|
-
|
|
85
|
-
const pingPromise = createTimeoutPromise(
|
|
86
|
-
ping.enabled ? ping.intervalMs : Infinity,
|
|
87
|
-
'ping' as const,
|
|
88
|
-
);
|
|
89
|
-
const next = await Promise.race([
|
|
90
|
-
nextPromise.catch(getTRPCErrorFromUnknown),
|
|
91
|
-
pingPromise.promise,
|
|
92
|
-
closedPromise,
|
|
93
|
-
maxDurationPromise.promise,
|
|
94
|
-
]);
|
|
95
|
-
|
|
96
|
-
pingPromise.clear();
|
|
97
|
-
if (next === 'closed') {
|
|
98
|
-
break;
|
|
99
|
-
}
|
|
100
|
-
if (next === 'maxDuration') {
|
|
101
|
-
break;
|
|
102
|
-
}
|
|
111
|
+
type TIteratorValue = Awaited<TValue> | typeof PING_SYM;
|
|
103
112
|
|
|
104
|
-
|
|
105
|
-
stream.controller.enqueue({
|
|
106
|
-
comment: 'ping',
|
|
107
|
-
});
|
|
108
|
-
continue;
|
|
109
|
-
}
|
|
113
|
+
let iterable: AsyncIterable<TValue | typeof PING_SYM> = opts.data;
|
|
110
114
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
data: JSON.stringify(serialize(data)),
|
|
118
|
-
});
|
|
119
|
-
break;
|
|
120
|
-
}
|
|
121
|
-
if (next.done) {
|
|
122
|
-
break;
|
|
123
|
-
}
|
|
115
|
+
if (opts.emitAndEndImmediately) {
|
|
116
|
+
iterable = takeWithGrace(iterable, {
|
|
117
|
+
count: 1,
|
|
118
|
+
gracePeriodMs: 1,
|
|
119
|
+
});
|
|
120
|
+
}
|
|
124
121
|
|
|
125
|
-
|
|
122
|
+
if (
|
|
123
|
+
opts.maxDurationMs &&
|
|
124
|
+
opts.maxDurationMs > 0 &&
|
|
125
|
+
opts.maxDurationMs !== Infinity
|
|
126
|
+
) {
|
|
127
|
+
iterable = withMaxDuration(iterable, {
|
|
128
|
+
maxDurationMs: opts.maxDurationMs,
|
|
129
|
+
});
|
|
130
|
+
}
|
|
126
131
|
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
data: value[1],
|
|
131
|
-
}
|
|
132
|
-
: {
|
|
133
|
-
data: value,
|
|
134
|
-
};
|
|
135
|
-
if ('data' in chunk) {
|
|
136
|
-
chunk.data = JSON.stringify(serialize(chunk.data));
|
|
137
|
-
}
|
|
132
|
+
if (ping.enabled && ping.intervalMs !== Infinity && ping.intervalMs > 0) {
|
|
133
|
+
iterable = withPing(iterable, ping.intervalMs);
|
|
134
|
+
}
|
|
138
135
|
|
|
139
|
-
|
|
136
|
+
// We need those declarations outside the loop for garbage collection reasons. If they were
|
|
137
|
+
// declared inside, they would not be freed until the next value is present.
|
|
138
|
+
let value: null | TIteratorValue;
|
|
139
|
+
let chunk: null | SSEvent;
|
|
140
140
|
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
141
|
+
for await (value of iterable) {
|
|
142
|
+
if (value === PING_SYM) {
|
|
143
|
+
yield { event: PING_EVENT, data: '' };
|
|
144
|
+
continue;
|
|
144
145
|
}
|
|
145
146
|
|
|
146
|
-
|
|
147
|
+
chunk = isTrackedEnvelope(value)
|
|
148
|
+
? { id: value[0], data: value[1] }
|
|
149
|
+
: { data: value };
|
|
150
|
+
|
|
151
|
+
chunk.data = JSON.stringify(serialize(chunk.data));
|
|
152
|
+
|
|
153
|
+
yield chunk;
|
|
154
|
+
|
|
155
|
+
// free up references for garbage collection
|
|
156
|
+
value = null;
|
|
157
|
+
chunk = null;
|
|
147
158
|
}
|
|
148
|
-
|
|
149
|
-
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
async function* generatorWithErrorHandling(): AsyncIterable<SSEvent, void> {
|
|
150
162
|
try {
|
|
151
|
-
|
|
152
|
-
} catch {
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
163
|
+
yield* generator();
|
|
164
|
+
} catch (cause) {
|
|
165
|
+
if (isAbortError(cause)) {
|
|
166
|
+
// ignore abort errors, send any other errors
|
|
167
|
+
return;
|
|
168
|
+
}
|
|
169
|
+
// `err` must be caused by `opts.data`, `JSON.stringify` or `serialize`.
|
|
170
|
+
// So, a user error in any case.
|
|
171
|
+
const error = getTRPCErrorFromUnknown(cause);
|
|
172
|
+
const data = opts.formatError?.({ error }) ?? null;
|
|
173
|
+
yield {
|
|
174
|
+
event: SERIALIZED_ERROR_EVENT,
|
|
175
|
+
data: JSON.stringify(serialize(data)),
|
|
176
|
+
};
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
const stream = readableStreamFrom(generatorWithErrorHandling());
|
|
156
180
|
|
|
157
|
-
return stream.
|
|
158
|
-
new TransformStream
|
|
159
|
-
transform(chunk, controller) {
|
|
181
|
+
return stream.pipeThrough(
|
|
182
|
+
new TransformStream({
|
|
183
|
+
transform(chunk, controller: TransformStreamDefaultController<string>) {
|
|
160
184
|
if ('event' in chunk) {
|
|
161
185
|
controller.enqueue(`event: ${chunk.event}\n`);
|
|
162
186
|
}
|
|
@@ -175,100 +199,243 @@ export function sseStreamProducer(opts: SSEStreamProducerOptions) {
|
|
|
175
199
|
);
|
|
176
200
|
}
|
|
177
201
|
|
|
178
|
-
|
|
179
|
-
|
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
202
|
+
interface ConsumerStreamResultBase<TConfig extends ConsumerConfig> {
|
|
203
|
+
eventSource: InstanceType<TConfig['EventSource']> | null;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
interface ConsumerStreamResultData<TConfig extends ConsumerConfig>
|
|
207
|
+
extends ConsumerStreamResultBase<TConfig> {
|
|
208
|
+
type: 'data';
|
|
209
|
+
data: inferTrackedOutput<TConfig['data']>;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
interface ConsumerStreamResultError<TConfig extends ConsumerConfig>
|
|
213
|
+
extends ConsumerStreamResultBase<TConfig> {
|
|
214
|
+
type: 'serialized-error';
|
|
215
|
+
error: TConfig['error'];
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
interface ConsumerStreamResultConnecting<TConfig extends ConsumerConfig>
|
|
219
|
+
extends ConsumerStreamResultBase<TConfig> {
|
|
220
|
+
type: 'connecting';
|
|
221
|
+
event: EventSourceLike.EventOf<TConfig['EventSource']> | null;
|
|
222
|
+
}
|
|
223
|
+
interface ConsumerStreamResultTimeout<TConfig extends ConsumerConfig>
|
|
224
|
+
extends ConsumerStreamResultBase<TConfig> {
|
|
225
|
+
type: 'timeout';
|
|
226
|
+
ms: number;
|
|
227
|
+
}
|
|
228
|
+
interface ConsumerStreamResultPing<TConfig extends ConsumerConfig>
|
|
229
|
+
extends ConsumerStreamResultBase<TConfig> {
|
|
230
|
+
type: 'ping';
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
interface ConsumerStreamResultConnected<TConfig extends ConsumerConfig>
|
|
234
|
+
extends ConsumerStreamResultBase<TConfig> {
|
|
235
|
+
type: 'connected';
|
|
236
|
+
options: SSEClientOptions;
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
type ConsumerStreamResult<TConfig extends ConsumerConfig> =
|
|
240
|
+
| ConsumerStreamResultData<TConfig>
|
|
241
|
+
| ConsumerStreamResultError<TConfig>
|
|
242
|
+
| ConsumerStreamResultConnecting<TConfig>
|
|
243
|
+
| ConsumerStreamResultTimeout<TConfig>
|
|
244
|
+
| ConsumerStreamResultPing<TConfig>
|
|
245
|
+
| ConsumerStreamResultConnected<TConfig>;
|
|
246
|
+
|
|
247
|
+
export interface SSEStreamConsumerOptions<TConfig extends ConsumerConfig> {
|
|
248
|
+
url: () => MaybePromise<string>;
|
|
249
|
+
init: () =>
|
|
250
|
+
| MaybePromise<EventSourceLike.InitDictOf<TConfig['EventSource']>>
|
|
251
|
+
| undefined;
|
|
252
|
+
signal: AbortSignal;
|
|
253
|
+
deserialize?: Deserialize;
|
|
254
|
+
EventSource: TConfig['EventSource'];
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
interface ConsumerConfig {
|
|
258
|
+
data: unknown;
|
|
259
|
+
error: unknown;
|
|
260
|
+
EventSource: EventSourceLike.AnyConstructor;
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
async function withTimeout<T>(opts: {
|
|
264
|
+
promise: Promise<T>;
|
|
265
|
+
timeoutMs: number;
|
|
266
|
+
onTimeout: () => Promise<NoInfer<T>>;
|
|
267
|
+
}): Promise<T> {
|
|
268
|
+
using timeoutPromise = timerResource(opts.timeoutMs);
|
|
269
|
+
const res = await Unpromise.race([opts.promise, timeoutPromise.start()]);
|
|
270
|
+
|
|
271
|
+
if (res === disposablePromiseTimerResult) {
|
|
272
|
+
return await opts.onTimeout();
|
|
273
|
+
}
|
|
274
|
+
return res;
|
|
275
|
+
}
|
|
187
276
|
|
|
188
277
|
/**
|
|
189
278
|
* @see https://html.spec.whatwg.org/multipage/server-sent-events.html
|
|
190
279
|
*/
|
|
191
|
-
export function sseStreamConsumer<
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
deserialize?: Deserialize;
|
|
195
|
-
}): AsyncIterable<ConsumerStreamResult<TData>> {
|
|
280
|
+
export function sseStreamConsumer<TConfig extends ConsumerConfig>(
|
|
281
|
+
opts: SSEStreamConsumerOptions<TConfig>,
|
|
282
|
+
): AsyncIterable<ConsumerStreamResult<TConfig>> {
|
|
196
283
|
const { deserialize = (v) => v } = opts;
|
|
197
|
-
const eventSource = opts.from;
|
|
198
284
|
|
|
199
|
-
|
|
285
|
+
let clientOptions: SSEClientOptions = {};
|
|
286
|
+
|
|
287
|
+
const signal = opts.signal;
|
|
288
|
+
|
|
289
|
+
let _es: InstanceType<TConfig['EventSource']> | null = null;
|
|
290
|
+
|
|
291
|
+
const createStream = () =>
|
|
292
|
+
new ReadableStream<ConsumerStreamResult<TConfig>>({
|
|
293
|
+
async start(controller) {
|
|
294
|
+
const [url, init] = await Promise.all([opts.url(), opts.init()]);
|
|
295
|
+
const eventSource = (_es = new opts.EventSource(
|
|
296
|
+
url,
|
|
297
|
+
init,
|
|
298
|
+
) as InstanceType<TConfig['EventSource']>);
|
|
200
299
|
|
|
201
|
-
const transform = new TransformStream<
|
|
202
|
-
MessageEvent,
|
|
203
|
-
ConsumerStreamResult<TData>
|
|
204
|
-
>({
|
|
205
|
-
async transform(chunk, controller) {
|
|
206
|
-
const data = deserialize(JSON.parse(chunk.data));
|
|
207
|
-
if (chunk.type === SERIALIZED_ERROR_EVENT) {
|
|
208
300
|
controller.enqueue({
|
|
209
|
-
|
|
210
|
-
|
|
301
|
+
type: 'connecting',
|
|
302
|
+
eventSource: _es,
|
|
303
|
+
event: null,
|
|
211
304
|
});
|
|
212
|
-
return;
|
|
213
|
-
}
|
|
214
|
-
// console.debug('transforming', chunk.type, chunk.data);
|
|
215
|
-
const def: SSEvent = {
|
|
216
|
-
data,
|
|
217
|
-
};
|
|
218
305
|
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
}
|
|
306
|
+
eventSource.addEventListener(CONNECTED_EVENT, (_msg) => {
|
|
307
|
+
const msg = _msg as EventSourceLike.MessageEvent;
|
|
222
308
|
|
|
223
|
-
|
|
224
|
-
ok: true,
|
|
225
|
-
data: def as inferTrackedOutput<TData>,
|
|
226
|
-
});
|
|
227
|
-
},
|
|
228
|
-
});
|
|
309
|
+
const options: SSEClientOptions = JSON.parse(msg.data);
|
|
229
310
|
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
if (eventSource.readyState === EventSource.CLOSED) {
|
|
238
|
-
stream.controller.error(cause);
|
|
239
|
-
}
|
|
240
|
-
});
|
|
311
|
+
clientOptions = options;
|
|
312
|
+
controller.enqueue({
|
|
313
|
+
type: 'connected',
|
|
314
|
+
options,
|
|
315
|
+
eventSource,
|
|
316
|
+
});
|
|
317
|
+
});
|
|
241
318
|
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
319
|
+
eventSource.addEventListener(SERIALIZED_ERROR_EVENT, (_msg) => {
|
|
320
|
+
const msg = _msg as EventSourceLike.MessageEvent;
|
|
321
|
+
|
|
322
|
+
controller.enqueue({
|
|
323
|
+
type: 'serialized-error',
|
|
324
|
+
error: deserialize(JSON.parse(msg.data)),
|
|
325
|
+
eventSource,
|
|
326
|
+
});
|
|
327
|
+
});
|
|
328
|
+
eventSource.addEventListener(PING_EVENT, () => {
|
|
329
|
+
controller.enqueue({
|
|
330
|
+
type: 'ping',
|
|
331
|
+
eventSource,
|
|
332
|
+
});
|
|
333
|
+
});
|
|
334
|
+
eventSource.addEventListener('error', (event) => {
|
|
335
|
+
if (eventSource.readyState === EventSource.CLOSED) {
|
|
336
|
+
controller.error(event);
|
|
337
|
+
} else {
|
|
338
|
+
controller.enqueue({
|
|
339
|
+
type: 'connecting',
|
|
340
|
+
eventSource,
|
|
341
|
+
event,
|
|
342
|
+
});
|
|
255
343
|
}
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
344
|
+
});
|
|
345
|
+
eventSource.addEventListener('message', (_msg) => {
|
|
346
|
+
const msg = _msg as EventSourceLike.MessageEvent;
|
|
347
|
+
|
|
348
|
+
const chunk = deserialize(JSON.parse(msg.data));
|
|
349
|
+
|
|
350
|
+
const def: SSEvent = {
|
|
351
|
+
data: chunk,
|
|
259
352
|
};
|
|
353
|
+
if (msg.lastEventId) {
|
|
354
|
+
def.id = msg.lastEventId;
|
|
355
|
+
}
|
|
356
|
+
controller.enqueue({
|
|
357
|
+
type: 'data',
|
|
358
|
+
data: def as inferTrackedOutput<TConfig['data']>,
|
|
359
|
+
eventSource,
|
|
360
|
+
});
|
|
361
|
+
});
|
|
362
|
+
|
|
363
|
+
const onAbort = () => {
|
|
364
|
+
controller.close();
|
|
365
|
+
eventSource.close();
|
|
366
|
+
};
|
|
367
|
+
if (signal.aborted) {
|
|
368
|
+
onAbort();
|
|
369
|
+
} else {
|
|
370
|
+
signal.addEventListener('abort', onAbort);
|
|
371
|
+
}
|
|
372
|
+
},
|
|
373
|
+
cancel() {
|
|
374
|
+
_es?.close();
|
|
375
|
+
},
|
|
376
|
+
});
|
|
377
|
+
|
|
378
|
+
const getStreamResource = () => {
|
|
379
|
+
let stream = createStream();
|
|
380
|
+
let reader = stream.getReader();
|
|
381
|
+
|
|
382
|
+
async function dispose() {
|
|
383
|
+
await reader.cancel();
|
|
384
|
+
_es = null;
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
return makeAsyncResource(
|
|
388
|
+
{
|
|
389
|
+
read() {
|
|
390
|
+
return reader.read();
|
|
260
391
|
},
|
|
261
|
-
async
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
};
|
|
392
|
+
async recreate() {
|
|
393
|
+
await dispose();
|
|
394
|
+
|
|
395
|
+
stream = createStream();
|
|
396
|
+
reader = stream.getReader();
|
|
267
397
|
},
|
|
268
|
-
}
|
|
269
|
-
|
|
270
|
-
|
|
398
|
+
},
|
|
399
|
+
dispose,
|
|
400
|
+
);
|
|
271
401
|
};
|
|
402
|
+
|
|
403
|
+
return run(async function* () {
|
|
404
|
+
await using stream = getStreamResource();
|
|
405
|
+
|
|
406
|
+
while (true) {
|
|
407
|
+
let promise = stream.read();
|
|
408
|
+
|
|
409
|
+
const timeoutMs = clientOptions.reconnectAfterInactivityMs;
|
|
410
|
+
if (timeoutMs) {
|
|
411
|
+
promise = withTimeout({
|
|
412
|
+
promise,
|
|
413
|
+
timeoutMs,
|
|
414
|
+
onTimeout: async () => {
|
|
415
|
+
const res: Awaited<typeof promise> = {
|
|
416
|
+
value: {
|
|
417
|
+
type: 'timeout',
|
|
418
|
+
ms: timeoutMs,
|
|
419
|
+
eventSource: _es,
|
|
420
|
+
},
|
|
421
|
+
done: false,
|
|
422
|
+
};
|
|
423
|
+
// Close and release old reader
|
|
424
|
+
await stream.recreate();
|
|
425
|
+
|
|
426
|
+
return res;
|
|
427
|
+
},
|
|
428
|
+
});
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
const result = await promise;
|
|
432
|
+
|
|
433
|
+
if (result.done) {
|
|
434
|
+
return result.value;
|
|
435
|
+
}
|
|
436
|
+
yield result.value;
|
|
437
|
+
}
|
|
438
|
+
});
|
|
272
439
|
}
|
|
273
440
|
|
|
274
441
|
export const sseHeaders = {
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-namespace */
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @internal
|
|
5
|
+
*/
|
|
6
|
+
export namespace EventSourceLike {
|
|
7
|
+
export interface InitDict {
|
|
8
|
+
withCredentials?: boolean;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export interface MessageEvent extends Event {
|
|
12
|
+
data: any;
|
|
13
|
+
lastEventId?: string;
|
|
14
|
+
}
|
|
15
|
+
export interface Event {}
|
|
16
|
+
|
|
17
|
+
type EventSourceListenerLike = (event: Event) => void;
|
|
18
|
+
|
|
19
|
+
export type AnyConstructorLike<TInit extends InitDict> = new (
|
|
20
|
+
url: string,
|
|
21
|
+
eventSourceInitDict?: TInit,
|
|
22
|
+
) => Instance;
|
|
23
|
+
|
|
24
|
+
export interface Instance {
|
|
25
|
+
readonly CLOSED: number;
|
|
26
|
+
readonly CONNECTING: number;
|
|
27
|
+
readonly OPEN: number;
|
|
28
|
+
|
|
29
|
+
addEventListener(type: string, listener: EventSourceListenerLike): void;
|
|
30
|
+
removeEventListener(type: string, listener: EventSourceListenerLike): void;
|
|
31
|
+
close: () => void;
|
|
32
|
+
|
|
33
|
+
readyState: number;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export type AnyConstructor = AnyConstructorLike<any>;
|
|
37
|
+
|
|
38
|
+
export type ListenerOf<T extends AnyConstructor> = Parameters<
|
|
39
|
+
InstanceType<T>['addEventListener']
|
|
40
|
+
>[1];
|
|
41
|
+
export type EventOf<T extends AnyConstructor> = Parameters<ListenerOf<T>>[0];
|
|
42
|
+
export type InitDictOf<T extends AnyConstructor> =
|
|
43
|
+
ConstructorParameters<T>[1];
|
|
44
|
+
}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
const trackedSymbol = Symbol(
|
|
1
|
+
const trackedSymbol = Symbol();
|
|
2
2
|
|
|
3
3
|
type TrackedId = string & {
|
|
4
4
|
__brand: 'TrackedId';
|
|
5
5
|
};
|
|
6
6
|
export type TrackedEnvelope<TData> = [TrackedId, TData, typeof trackedSymbol];
|
|
7
7
|
|
|
8
|
-
type
|
|
8
|
+
type TrackedData<TData> = {
|
|
9
9
|
/**
|
|
10
10
|
* The id of the message to keep track of in case the connection gets lost
|
|
11
11
|
*/
|
|
@@ -19,10 +19,7 @@ type Tracked<TData> = {
|
|
|
19
19
|
* Produce a typed server-sent event message
|
|
20
20
|
* @deprecated use `tracked(id, data)` instead
|
|
21
21
|
*/
|
|
22
|
-
export function sse<TData>(event: {
|
|
23
|
-
id: string;
|
|
24
|
-
data: TData;
|
|
25
|
-
}): TrackedEnvelope<TData> {
|
|
22
|
+
export function sse<TData>(event: { id: string; data: TData }) {
|
|
26
23
|
return tracked(event.id, event.data);
|
|
27
24
|
}
|
|
28
25
|
|
|
@@ -48,8 +45,5 @@ export function tracked<TData>(
|
|
|
48
45
|
return [id as TrackedId, data, trackedSymbol];
|
|
49
46
|
}
|
|
50
47
|
|
|
51
|
-
export type inferTrackedOutput<TData> =
|
|
52
|
-
infer $Data
|
|
53
|
-
>
|
|
54
|
-
? Tracked<$Data>
|
|
55
|
-
: TData;
|
|
48
|
+
export type inferTrackedOutput<TData> =
|
|
49
|
+
TData extends TrackedEnvelope<infer $Data> ? TrackedData<$Data> : TData;
|