@trpc/server 11.0.0-rc.474 → 11.0.0-rc.475
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/index.d.ts +5 -1
- package/dist/@trpc/server/index.d.ts.map +1 -1
- package/dist/adapters/ws.d.ts.map +1 -1
- package/dist/adapters/ws.js +36 -6
- package/dist/adapters/ws.mjs +37 -7
- package/dist/bundle-analysis.json +112 -97
- package/dist/index.js +3 -2
- package/dist/index.mjs +1 -1
- package/dist/unstable-core-do-not-import/procedureBuilder.d.ts +2 -2
- package/dist/unstable-core-do-not-import/procedureBuilder.d.ts.map +1 -1
- package/dist/unstable-core-do-not-import/rpc/envelopes.d.ts +8 -0
- package/dist/unstable-core-do-not-import/rpc/envelopes.d.ts.map +1 -1
- package/dist/unstable-core-do-not-import/rpc/parseTRPCMessage.d.ts.map +1 -1
- package/dist/unstable-core-do-not-import/rpc/parseTRPCMessage.js +6 -2
- package/dist/unstable-core-do-not-import/rpc/parseTRPCMessage.mjs +6 -2
- package/dist/unstable-core-do-not-import/stream/sse.d.ts +2 -30
- package/dist/unstable-core-do-not-import/stream/sse.d.ts.map +1 -1
- package/dist/unstable-core-do-not-import/stream/sse.js +4 -20
- package/dist/unstable-core-do-not-import/stream/sse.mjs +5 -19
- package/dist/unstable-core-do-not-import/stream/tracked.d.ts +31 -0
- package/dist/unstable-core-do-not-import/stream/tracked.d.ts.map +1 -0
- package/dist/unstable-core-do-not-import/stream/tracked.js +29 -0
- package/dist/unstable-core-do-not-import/stream/tracked.mjs +25 -0
- package/dist/unstable-core-do-not-import/transformer.d.ts +1 -0
- package/dist/unstable-core-do-not-import/transformer.d.ts.map +1 -1
- package/dist/unstable-core-do-not-import.d.ts +1 -0
- package/dist/unstable-core-do-not-import.d.ts.map +1 -1
- package/dist/unstable-core-do-not-import.js +4 -2
- package/dist/unstable-core-do-not-import.mjs +2 -1
- package/package.json +2 -2
- package/src/@trpc/server/index.ts +4 -0
- package/src/adapters/ws.ts +42 -6
- package/src/unstable-core-do-not-import/procedureBuilder.ts +2 -2
- package/src/unstable-core-do-not-import/rpc/envelopes.ts +18 -2
- package/src/unstable-core-do-not-import/rpc/parseTRPCMessage.ts +5 -1
- package/src/unstable-core-do-not-import/stream/sse.ts +21 -65
- package/src/unstable-core-do-not-import/stream/tracked.ts +55 -0
- package/src/unstable-core-do-not-import.ts +1 -0
|
@@ -40,8 +40,11 @@ import { isObject } from '../utils.mjs';
|
|
|
40
40
|
}
|
|
41
41
|
assertIsProcedureType(method);
|
|
42
42
|
assertIsObject(params);
|
|
43
|
-
const { input: rawInput , path } = params;
|
|
43
|
+
const { input: rawInput , path , lastEventId } = params;
|
|
44
44
|
assertIsString(path);
|
|
45
|
+
if (lastEventId !== undefined) {
|
|
46
|
+
assertIsString(lastEventId);
|
|
47
|
+
}
|
|
45
48
|
const input = transformer.input.deserialize(rawInput);
|
|
46
49
|
return {
|
|
47
50
|
id,
|
|
@@ -49,7 +52,8 @@ import { isObject } from '../utils.mjs';
|
|
|
49
52
|
method,
|
|
50
53
|
params: {
|
|
51
54
|
input,
|
|
52
|
-
path
|
|
55
|
+
path,
|
|
56
|
+
lastEventId
|
|
53
57
|
}
|
|
54
58
|
};
|
|
55
59
|
}
|
|
@@ -1,34 +1,7 @@
|
|
|
1
|
-
import type { ValidateShape } from '../types';
|
|
2
1
|
import type { ConsumerOnError } from './jsonl';
|
|
2
|
+
import type { inferTrackedOutput } from './tracked';
|
|
3
3
|
type Serialize = (value: any) => any;
|
|
4
4
|
type Deserialize = (value: any) => any;
|
|
5
|
-
/**
|
|
6
|
-
* Server-sent Event Message
|
|
7
|
-
* @see https://html.spec.whatwg.org/multipage/server-sent-events.html
|
|
8
|
-
* @public
|
|
9
|
-
*/
|
|
10
|
-
export interface SSEMessage {
|
|
11
|
-
/**
|
|
12
|
-
* The data field of the message - this can be anything
|
|
13
|
-
*/
|
|
14
|
-
data: unknown;
|
|
15
|
-
/**
|
|
16
|
-
* The id for this message
|
|
17
|
-
* Passing this id will allow the client to resume the connection from this point if the connection is lost
|
|
18
|
-
* @see https://html.spec.whatwg.org/multipage/server-sent-events.html#the-last-event-id-header
|
|
19
|
-
*/
|
|
20
|
-
id: string;
|
|
21
|
-
}
|
|
22
|
-
declare const sseSymbol: unique symbol;
|
|
23
|
-
export type SSEMessageEnvelope<TData> = [typeof sseSymbol, TData];
|
|
24
|
-
/**
|
|
25
|
-
* Produce a typed server-sent event message
|
|
26
|
-
*/
|
|
27
|
-
export declare function sse<TData extends SSEMessage>(event: ValidateShape<TData, SSEMessage>): SSEMessageEnvelope<TData>;
|
|
28
|
-
export declare function isSSEMessageEnvelope<TData extends SSEMessage>(value: unknown): value is SSEMessageEnvelope<TData>;
|
|
29
|
-
export type SerializedSSEvent = Omit<SSEMessage, 'data'> & {
|
|
30
|
-
data?: string;
|
|
31
|
-
};
|
|
32
5
|
/**
|
|
33
6
|
* @internal
|
|
34
7
|
*/
|
|
@@ -67,7 +40,6 @@ export interface SSEStreamProducerOptions {
|
|
|
67
40
|
* @see https://html.spec.whatwg.org/multipage/server-sent-events.html
|
|
68
41
|
*/
|
|
69
42
|
export declare function sseStreamProducer(opts: SSEStreamProducerOptions): ReadableStream<string>;
|
|
70
|
-
export type inferSSEOutput<TData> = TData extends SSEMessageEnvelope<infer $Data> ? $Data : TData;
|
|
71
43
|
/**
|
|
72
44
|
* @see https://html.spec.whatwg.org/multipage/server-sent-events.html
|
|
73
45
|
*/
|
|
@@ -75,7 +47,7 @@ export declare function sseStreamConsumer<TData>(opts: {
|
|
|
75
47
|
from: EventSource;
|
|
76
48
|
onError?: ConsumerOnError;
|
|
77
49
|
deserialize?: Deserialize;
|
|
78
|
-
}): AsyncIterable<
|
|
50
|
+
}): AsyncIterable<inferTrackedOutput<TData>>;
|
|
79
51
|
export declare const sseHeaders: {
|
|
80
52
|
readonly 'Content-Type': "text/event-stream";
|
|
81
53
|
readonly 'Cache-Control': "no-cache, no-transform";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sse.d.ts","sourceRoot":"","sources":["../../../src/unstable-core-do-not-import/stream/sse.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"sse.d.ts","sourceRoot":"","sources":["../../../src/unstable-core-do-not-import/stream/sse.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAC/C,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAC;AAKpD,KAAK,SAAS,GAAG,CAAC,KAAK,EAAE,GAAG,KAAK,GAAG,CAAC;AACrC,KAAK,WAAW,GAAG,CAAC,KAAK,EAAE,GAAG,KAAK,GAAG,CAAC;AAEvC;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B;;;OAGG;IACH,OAAO,EAAE,OAAO,CAAC;IACjB;;;OAGG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,wBAAwB;IACvC,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB,IAAI,EAAE,aAAa,CAAC,OAAO,CAAC,CAAC;IAC7B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,WAAW,CAAC;IACnB;;;;OAIG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;;;;OAIG;IACH,qBAAqB,CAAC,EAAE,OAAO,CAAC;CACjC;AAQD;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,wBAAwB,0BA8G/D;AACD;;GAEG;AAEH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,IAAI,EAAE;IAC7C,IAAI,EAAE,WAAW,CAAC;IAClB,OAAO,CAAC,EAAE,eAAe,CAAC;IAC1B,WAAW,CAAC,EAAE,WAAW,CAAC;CAC3B,GAAG,aAAa,CAAC,kBAAkB,CAAC,KAAK,CAAC,CAAC,CA6D3C;AAED,eAAO,MAAM,UAAU;;;;;CAKb,CAAC"}
|
|
@@ -2,25 +2,10 @@
|
|
|
2
2
|
|
|
3
3
|
var TRPCError = require('../error/TRPCError.js');
|
|
4
4
|
var utils = require('../utils.js');
|
|
5
|
+
var tracked = require('./tracked.js');
|
|
5
6
|
var createDeferred = require('./utils/createDeferred.js');
|
|
6
7
|
var createReadableStream = require('./utils/createReadableStream.js');
|
|
7
8
|
|
|
8
|
-
const sseSymbol = Symbol('SSEMessageEnvelope');
|
|
9
|
-
/**
|
|
10
|
-
* Produce a typed server-sent event message
|
|
11
|
-
*/ function sse(event) {
|
|
12
|
-
if (event.id === '') {
|
|
13
|
-
// This could be removed by using different event names for `yield sse(x)`-emitted events and `yield y`-emitted events
|
|
14
|
-
throw new Error('`id` must not be an empty string as empty string is the same as not setting the id at all');
|
|
15
|
-
}
|
|
16
|
-
return [
|
|
17
|
-
sseSymbol,
|
|
18
|
-
event
|
|
19
|
-
];
|
|
20
|
-
}
|
|
21
|
-
function isSSEMessageEnvelope(value) {
|
|
22
|
-
return Array.isArray(value) && value[0] === sseSymbol;
|
|
23
|
-
}
|
|
24
9
|
/**
|
|
25
10
|
*
|
|
26
11
|
* @see https://html.spec.whatwg.org/multipage/server-sent-events.html
|
|
@@ -68,8 +53,9 @@ function isSSEMessageEnvelope(value) {
|
|
|
68
53
|
break;
|
|
69
54
|
}
|
|
70
55
|
const value = next.value;
|
|
71
|
-
const chunk =
|
|
72
|
-
|
|
56
|
+
const chunk = tracked.isTrackedEnvelope(value) ? {
|
|
57
|
+
id: value[0],
|
|
58
|
+
data: value[1]
|
|
73
59
|
} : {
|
|
74
60
|
data: value
|
|
75
61
|
};
|
|
@@ -171,8 +157,6 @@ const sseHeaders = {
|
|
|
171
157
|
Connection: 'keep-alive'
|
|
172
158
|
};
|
|
173
159
|
|
|
174
|
-
exports.isSSEMessageEnvelope = isSSEMessageEnvelope;
|
|
175
|
-
exports.sse = sse;
|
|
176
160
|
exports.sseHeaders = sseHeaders;
|
|
177
161
|
exports.sseStreamConsumer = sseStreamConsumer;
|
|
178
162
|
exports.sseStreamProducer = sseStreamProducer;
|
|
@@ -1,24 +1,9 @@
|
|
|
1
1
|
import { getTRPCErrorFromUnknown } from '../error/TRPCError.mjs';
|
|
2
2
|
import { run } from '../utils.mjs';
|
|
3
|
+
import { isTrackedEnvelope } from './tracked.mjs';
|
|
3
4
|
import { createTimeoutPromise } from './utils/createDeferred.mjs';
|
|
4
5
|
import { createReadableStream } from './utils/createReadableStream.mjs';
|
|
5
6
|
|
|
6
|
-
const sseSymbol = Symbol('SSEMessageEnvelope');
|
|
7
|
-
/**
|
|
8
|
-
* Produce a typed server-sent event message
|
|
9
|
-
*/ function sse(event) {
|
|
10
|
-
if (event.id === '') {
|
|
11
|
-
// This could be removed by using different event names for `yield sse(x)`-emitted events and `yield y`-emitted events
|
|
12
|
-
throw new Error('`id` must not be an empty string as empty string is the same as not setting the id at all');
|
|
13
|
-
}
|
|
14
|
-
return [
|
|
15
|
-
sseSymbol,
|
|
16
|
-
event
|
|
17
|
-
];
|
|
18
|
-
}
|
|
19
|
-
function isSSEMessageEnvelope(value) {
|
|
20
|
-
return Array.isArray(value) && value[0] === sseSymbol;
|
|
21
|
-
}
|
|
22
7
|
/**
|
|
23
8
|
*
|
|
24
9
|
* @see https://html.spec.whatwg.org/multipage/server-sent-events.html
|
|
@@ -66,8 +51,9 @@ function isSSEMessageEnvelope(value) {
|
|
|
66
51
|
break;
|
|
67
52
|
}
|
|
68
53
|
const value = next.value;
|
|
69
|
-
const chunk =
|
|
70
|
-
|
|
54
|
+
const chunk = isTrackedEnvelope(value) ? {
|
|
55
|
+
id: value[0],
|
|
56
|
+
data: value[1]
|
|
71
57
|
} : {
|
|
72
58
|
data: value
|
|
73
59
|
};
|
|
@@ -169,4 +155,4 @@ const sseHeaders = {
|
|
|
169
155
|
Connection: 'keep-alive'
|
|
170
156
|
};
|
|
171
157
|
|
|
172
|
-
export {
|
|
158
|
+
export { sseHeaders, sseStreamConsumer, sseStreamProducer };
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
declare const trackedSymbol: unique symbol;
|
|
2
|
+
type TrackedId = string & {
|
|
3
|
+
__brand: 'TrackedId';
|
|
4
|
+
};
|
|
5
|
+
export type TrackedEnvelope<TData> = [TrackedId, TData, typeof trackedSymbol];
|
|
6
|
+
type Tracked<TData> = {
|
|
7
|
+
/**
|
|
8
|
+
* The id of the message to keep track of in case the connection gets lost
|
|
9
|
+
*/
|
|
10
|
+
id: string;
|
|
11
|
+
/**
|
|
12
|
+
* The data field of the message - this can be anything
|
|
13
|
+
*/
|
|
14
|
+
data: TData;
|
|
15
|
+
};
|
|
16
|
+
/**
|
|
17
|
+
* Produce a typed server-sent event message
|
|
18
|
+
* @deprecated use `tracked(id, data)` instead
|
|
19
|
+
*/
|
|
20
|
+
export declare function sse<TData>(event: {
|
|
21
|
+
id: string;
|
|
22
|
+
data: TData;
|
|
23
|
+
}): TrackedEnvelope<TData>;
|
|
24
|
+
export declare function isTrackedEnvelope<TData>(value: unknown): value is TrackedEnvelope<TData>;
|
|
25
|
+
/**
|
|
26
|
+
* Automatically track an event so that it can be resumed from a given id if the connection is lost
|
|
27
|
+
*/
|
|
28
|
+
export declare function tracked<TData>(id: string, data: TData): TrackedEnvelope<TData>;
|
|
29
|
+
export type inferTrackedOutput<TData> = TData extends TrackedEnvelope<infer $Data> ? Tracked<$Data> : TData;
|
|
30
|
+
export {};
|
|
31
|
+
//# sourceMappingURL=tracked.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tracked.d.ts","sourceRoot":"","sources":["../../../src/unstable-core-do-not-import/stream/tracked.ts"],"names":[],"mappings":"AAAA,QAAA,MAAM,aAAa,eAA4B,CAAC;AAEhD,KAAK,SAAS,GAAG,MAAM,GAAG;IACxB,OAAO,EAAE,WAAW,CAAC;CACtB,CAAC;AACF,MAAM,MAAM,eAAe,CAAC,KAAK,IAAI,CAAC,SAAS,EAAE,KAAK,EAAE,OAAO,aAAa,CAAC,CAAC;AAE9E,KAAK,OAAO,CAAC,KAAK,IAAI;IACpB;;OAEG;IACH,EAAE,EAAE,MAAM,CAAC;IACX;;OAEG;IACH,IAAI,EAAE,KAAK,CAAC;CACb,CAAC;AACF;;;GAGG;AACH,wBAAgB,GAAG,CAAC,KAAK,EAAE,KAAK,EAAE;IAChC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,KAAK,CAAC;CACb,GAAG,eAAe,CAAC,KAAK,CAAC,CAEzB;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EACrC,KAAK,EAAE,OAAO,GACb,KAAK,IAAI,eAAe,CAAC,KAAK,CAAC,CAEjC;AAED;;GAEG;AACH,wBAAgB,OAAO,CAAC,KAAK,EAC3B,EAAE,EAAE,MAAM,EACV,IAAI,EAAE,KAAK,GACV,eAAe,CAAC,KAAK,CAAC,CAQxB;AAED,MAAM,MAAM,kBAAkB,CAAC,KAAK,IAAI,KAAK,SAAS,eAAe,CACnE,MAAM,KAAK,CACZ,GACG,OAAO,CAAC,KAAK,CAAC,GACd,KAAK,CAAC"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const trackedSymbol = Symbol('TrackedEnvelope');
|
|
4
|
+
/**
|
|
5
|
+
* Produce a typed server-sent event message
|
|
6
|
+
* @deprecated use `tracked(id, data)` instead
|
|
7
|
+
*/ function sse(event) {
|
|
8
|
+
return tracked(event.id, event.data);
|
|
9
|
+
}
|
|
10
|
+
function isTrackedEnvelope(value) {
|
|
11
|
+
return Array.isArray(value) && value[2] === trackedSymbol;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Automatically track an event so that it can be resumed from a given id if the connection is lost
|
|
15
|
+
*/ function tracked(id, data) {
|
|
16
|
+
if (id === '') {
|
|
17
|
+
// This limitation could be removed by using different SSE event names / channels for tracked event and non-tracked event
|
|
18
|
+
throw new Error('`id` must not be an empty string as empty string is the same as not setting the id at all');
|
|
19
|
+
}
|
|
20
|
+
return [
|
|
21
|
+
id,
|
|
22
|
+
data,
|
|
23
|
+
trackedSymbol
|
|
24
|
+
];
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
exports.isTrackedEnvelope = isTrackedEnvelope;
|
|
28
|
+
exports.sse = sse;
|
|
29
|
+
exports.tracked = tracked;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
const trackedSymbol = Symbol('TrackedEnvelope');
|
|
2
|
+
/**
|
|
3
|
+
* Produce a typed server-sent event message
|
|
4
|
+
* @deprecated use `tracked(id, data)` instead
|
|
5
|
+
*/ function sse(event) {
|
|
6
|
+
return tracked(event.id, event.data);
|
|
7
|
+
}
|
|
8
|
+
function isTrackedEnvelope(value) {
|
|
9
|
+
return Array.isArray(value) && value[2] === trackedSymbol;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Automatically track an event so that it can be resumed from a given id if the connection is lost
|
|
13
|
+
*/ function tracked(id, data) {
|
|
14
|
+
if (id === '') {
|
|
15
|
+
// This limitation could be removed by using different SSE event names / channels for tracked event and non-tracked event
|
|
16
|
+
throw new Error('`id` must not be an empty string as empty string is the same as not setting the id at all');
|
|
17
|
+
}
|
|
18
|
+
return [
|
|
19
|
+
id,
|
|
20
|
+
data,
|
|
21
|
+
trackedSymbol
|
|
22
|
+
];
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export { isTrackedEnvelope, sse, tracked };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"transformer.d.ts","sourceRoot":"","sources":["../../src/unstable-core-do-not-import/transformer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC7D,OAAO,KAAK,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAC5D,OAAO,KAAK,EACV,YAAY,EACZ,mBAAmB,EACnB,iBAAiB,EAClB,MAAM,OAAO,CAAC;AAGf;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,SAAS,EAAE,CAAC,MAAM,EAAE,GAAG,KAAK,GAAG,CAAC;IAChC,WAAW,EAAE,CAAC,MAAM,EAAE,GAAG,KAAK,GAAG,CAAC;CACnC;AAED,UAAU,oBAAqB,SAAQ,eAAe;IACpD;;OAEG;IACH,SAAS,EAAE,CAAC,MAAM,EAAE,GAAG,KAAK,GAAG,CAAC;IAChC;;OAEG;IACH,WAAW,EAAE,CAAC,MAAM,EAAE,GAAG,KAAK,GAAG,CAAC;CACnC;AAED,UAAU,qBAAsB,SAAQ,eAAe;IACrD;;OAEG;IACH,SAAS,EAAE,CAAC,MAAM,EAAE,GAAG,KAAK,GAAG,CAAC;IAChC;;OAEG;IACH,WAAW,EAAE,CAAC,MAAM,EAAE,GAAG,KAAK,GAAG,CAAC;CACnC;AAED;;GAEG;AACH,MAAM,WAAW,uBAAuB;IACtC;;OAEG;IACH,KAAK,EAAE,oBAAoB,CAAC;IAC5B;;OAEG;IACH,MAAM,EAAE,qBAAqB,CAAC;CAC/B;AAED;;GAEG;AACH,MAAM,MAAM,6BAA6B,GAAG;IAC1C,KAAK,EAAE,IAAI,CAAC,uBAAuB,CAAC,OAAO,CAAC,EAAE,WAAW,CAAC,CAAC;IAC3D,MAAM,EAAE,IAAI,CAAC,uBAAuB,CAAC,QAAQ,CAAC,EAAE,aAAa,CAAC,CAAC;CAChE,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,sBAAsB,GAAG,uBAAuB,GAAG,eAAe,CAAC;AAE/E;;GAEG;AACH,wBAAgB,kBAAkB,CAChC,WAAW,EAAE,sBAAsB,GAClC,uBAAuB,CAKzB;AAED;;GAEG;AACH,eAAO,MAAM,kBAAkB,EAAE,uBAGhC,CAAC;AAyBF;;IAEI;AACJ,wBAAgB,qBAAqB,CACnC,SAAS,SACL,YAAY,GACZ,YAAY,EAAE,GACd,mBAAmB,GACnB,mBAAmB,EAAE,EACzB,MAAM,EAAE,UAAU,CAAC,YAAY,CAAC,EAAE,WAAW,EAAE,SAAS;;yEAIzD;AAKD,gBAAgB;AAChB,iBAAS,oBAAoB,CAAC,OAAO,SAAS,SAAS,EAAE,OAAO,EAC9D,QAAQ,EACJ,YAAY,CAAC,OAAO,EAAE,gBAAgB,CAAC,OAAO,CAAC,CAAC,GAChD,mBAAmB,CAAC,OAAO,EAAE,gBAAgB,CAAC,OAAO,CAAC,CAAC,EAC3D,WAAW,EAAE,eAAe
|
|
1
|
+
{"version":3,"file":"transformer.d.ts","sourceRoot":"","sources":["../../src/unstable-core-do-not-import/transformer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC7D,OAAO,KAAK,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAC5D,OAAO,KAAK,EACV,YAAY,EACZ,mBAAmB,EACnB,iBAAiB,EAClB,MAAM,OAAO,CAAC;AAGf;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,SAAS,EAAE,CAAC,MAAM,EAAE,GAAG,KAAK,GAAG,CAAC;IAChC,WAAW,EAAE,CAAC,MAAM,EAAE,GAAG,KAAK,GAAG,CAAC;CACnC;AAED,UAAU,oBAAqB,SAAQ,eAAe;IACpD;;OAEG;IACH,SAAS,EAAE,CAAC,MAAM,EAAE,GAAG,KAAK,GAAG,CAAC;IAChC;;OAEG;IACH,WAAW,EAAE,CAAC,MAAM,EAAE,GAAG,KAAK,GAAG,CAAC;CACnC;AAED,UAAU,qBAAsB,SAAQ,eAAe;IACrD;;OAEG;IACH,SAAS,EAAE,CAAC,MAAM,EAAE,GAAG,KAAK,GAAG,CAAC;IAChC;;OAEG;IACH,WAAW,EAAE,CAAC,MAAM,EAAE,GAAG,KAAK,GAAG,CAAC;CACnC;AAED;;GAEG;AACH,MAAM,WAAW,uBAAuB;IACtC;;OAEG;IACH,KAAK,EAAE,oBAAoB,CAAC;IAC5B;;OAEG;IACH,MAAM,EAAE,qBAAqB,CAAC;CAC/B;AAED;;GAEG;AACH,MAAM,MAAM,6BAA6B,GAAG;IAC1C,KAAK,EAAE,IAAI,CAAC,uBAAuB,CAAC,OAAO,CAAC,EAAE,WAAW,CAAC,CAAC;IAC3D,MAAM,EAAE,IAAI,CAAC,uBAAuB,CAAC,QAAQ,CAAC,EAAE,aAAa,CAAC,CAAC;CAChE,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,sBAAsB,GAAG,uBAAuB,GAAG,eAAe,CAAC;AAE/E;;GAEG;AACH,wBAAgB,kBAAkB,CAChC,WAAW,EAAE,sBAAsB,GAClC,uBAAuB,CAKzB;AAED;;GAEG;AACH,eAAO,MAAM,kBAAkB,EAAE,uBAGhC,CAAC;AAyBF;;IAEI;AACJ,wBAAgB,qBAAqB,CACnC,SAAS,SACL,YAAY,GACZ,YAAY,EAAE,GACd,mBAAmB,GACnB,mBAAmB,EAAE,EACzB,MAAM,EAAE,UAAU,CAAC,YAAY,CAAC,EAAE,WAAW,EAAE,SAAS;;yEAIzD;AAKD,gBAAgB;AAChB,iBAAS,oBAAoB,CAAC,OAAO,SAAS,SAAS,EAAE,OAAO,EAC9D,QAAQ,EACJ,YAAY,CAAC,OAAO,EAAE,gBAAgB,CAAC,OAAO,CAAC,CAAC,GAChD,mBAAmB,CAAC,OAAO,EAAE,gBAAgB,CAAC,OAAO,CAAC,CAAC,EAC3D,WAAW,EAAE,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;EAuB7B;AAQD;;;GAGG;AACH,wBAAgB,eAAe,CAAC,OAAO,SAAS,SAAS,EAAE,OAAO,EAChE,QAAQ,EACJ,YAAY,CAAC,OAAO,EAAE,gBAAgB,CAAC,OAAO,CAAC,CAAC,GAChD,mBAAmB,CAAC,OAAO,EAAE,gBAAgB,CAAC,OAAO,CAAC,CAAC,EAC3D,WAAW,EAAE,eAAe,GAC3B,UAAU,CAAC,OAAO,oBAAoB,CAAC,CAqBzC"}
|
|
@@ -34,6 +34,7 @@ export * from './unstable-core-do-not-import/router';
|
|
|
34
34
|
export * from './unstable-core-do-not-import/rpc';
|
|
35
35
|
export * from './unstable-core-do-not-import/stream/jsonl';
|
|
36
36
|
export * from './unstable-core-do-not-import/stream/sse';
|
|
37
|
+
export * from './unstable-core-do-not-import/stream/tracked';
|
|
37
38
|
export * from './unstable-core-do-not-import/stream/utils/createDeferred';
|
|
38
39
|
export * from './unstable-core-do-not-import/transformer';
|
|
39
40
|
export * from './unstable-core-do-not-import/types';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"unstable-core-do-not-import.d.ts","sourceRoot":"","sources":["../src/unstable-core-do-not-import.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,cAAc,mDAAmD,CAAC;AAClE,cAAc,oDAAoD,CAAC;AACnE,cAAc,mDAAmD,CAAC;AAClE,cAAc,2CAA2C,CAAC;AAC1D,cAAc,+CAA+C,CAAC;AAC9D,cAAc,mDAAmD,CAAC;AAClE,cAAc,+CAA+C,CAAC;AAC9D,cAAc,yDAAyD,CAAC;AACxE,cAAc,gDAAgD,CAAC;AAC/D,cAAc,uDAAuD,CAAC;AACtE,cAAc,qDAAqD,CAAC;AACpE,cAAc,sDAAsD,CAAC;AACrE,cAAc,0DAA0D,CAAC;AACzE,cAAc,oDAAoD,CAAC;AACnE,cAAc,0CAA0C,CAAC;AACzD,cAAc,0CAA0C,CAAC;AACzD,cAAc,wCAAwC,CAAC;AACvD,cAAc,0CAA0C,CAAC;AACzD,cAAc,sCAAsC,CAAC;AACrD,cAAc,yCAAyC,CAAC;AACxD,cAAc,gDAAgD,CAAC;AAC/D,cAAc,0CAA0C,CAAC;AACzD,cAAc,sCAAsC,CAAC;AACrD,cAAc,mCAAmC,CAAC;AAClD,cAAc,4CAA4C,CAAC;AAC3D,cAAc,0CAA0C,CAAC;AACzD,cAAc,2DAA2D,CAAC;AAC1E,cAAc,2CAA2C,CAAC;AAC1D,cAAc,qCAAqC,CAAC;AACpD,cAAc,qCAAqC,CAAC"}
|
|
1
|
+
{"version":3,"file":"unstable-core-do-not-import.d.ts","sourceRoot":"","sources":["../src/unstable-core-do-not-import.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,cAAc,mDAAmD,CAAC;AAClE,cAAc,oDAAoD,CAAC;AACnE,cAAc,mDAAmD,CAAC;AAClE,cAAc,2CAA2C,CAAC;AAC1D,cAAc,+CAA+C,CAAC;AAC9D,cAAc,mDAAmD,CAAC;AAClE,cAAc,+CAA+C,CAAC;AAC9D,cAAc,yDAAyD,CAAC;AACxE,cAAc,gDAAgD,CAAC;AAC/D,cAAc,uDAAuD,CAAC;AACtE,cAAc,qDAAqD,CAAC;AACpE,cAAc,sDAAsD,CAAC;AACrE,cAAc,0DAA0D,CAAC;AACzE,cAAc,oDAAoD,CAAC;AACnE,cAAc,0CAA0C,CAAC;AACzD,cAAc,0CAA0C,CAAC;AACzD,cAAc,wCAAwC,CAAC;AACvD,cAAc,0CAA0C,CAAC;AACzD,cAAc,sCAAsC,CAAC;AACrD,cAAc,yCAAyC,CAAC;AACxD,cAAc,gDAAgD,CAAC;AAC/D,cAAc,0CAA0C,CAAC;AACzD,cAAc,sCAAsC,CAAC;AACrD,cAAc,mCAAmC,CAAC;AAClD,cAAc,4CAA4C,CAAC;AAC3D,cAAc,0CAA0C,CAAC;AACzD,cAAc,8CAA8C,CAAC;AAC7D,cAAc,2DAA2D,CAAC;AAC1E,cAAc,2CAA2C,CAAC;AAC1D,cAAc,qCAAqC,CAAC;AACpD,cAAc,qCAAqC,CAAC"}
|
|
@@ -23,6 +23,7 @@ var codes = require('./unstable-core-do-not-import/rpc/codes.js');
|
|
|
23
23
|
var parseTRPCMessage = require('./unstable-core-do-not-import/rpc/parseTRPCMessage.js');
|
|
24
24
|
var jsonl = require('./unstable-core-do-not-import/stream/jsonl.js');
|
|
25
25
|
var sse = require('./unstable-core-do-not-import/stream/sse.js');
|
|
26
|
+
var tracked = require('./unstable-core-do-not-import/stream/tracked.js');
|
|
26
27
|
var createDeferred = require('./unstable-core-do-not-import/stream/utils/createDeferred.js');
|
|
27
28
|
var transformer = require('./unstable-core-do-not-import/transformer.js');
|
|
28
29
|
var types = require('./unstable-core-do-not-import/types.js');
|
|
@@ -67,11 +68,12 @@ exports.parseTRPCMessage = parseTRPCMessage.parseTRPCMessage;
|
|
|
67
68
|
exports.isPromise = jsonl.isPromise;
|
|
68
69
|
exports.jsonlStreamConsumer = jsonl.jsonlStreamConsumer;
|
|
69
70
|
exports.jsonlStreamProducer = jsonl.jsonlStreamProducer;
|
|
70
|
-
exports.isSSEMessageEnvelope = sse.isSSEMessageEnvelope;
|
|
71
|
-
exports.sse = sse.sse;
|
|
72
71
|
exports.sseHeaders = sse.sseHeaders;
|
|
73
72
|
exports.sseStreamConsumer = sse.sseStreamConsumer;
|
|
74
73
|
exports.sseStreamProducer = sse.sseStreamProducer;
|
|
74
|
+
exports.isTrackedEnvelope = tracked.isTrackedEnvelope;
|
|
75
|
+
exports.sse = tracked.sse;
|
|
76
|
+
exports.tracked = tracked.tracked;
|
|
75
77
|
exports.createDeferred = createDeferred.createDeferred;
|
|
76
78
|
exports.createTimeoutPromise = createDeferred.createTimeoutPromise;
|
|
77
79
|
exports.defaultTransformer = transformer.defaultTransformer;
|
|
@@ -20,7 +20,8 @@ export { callProcedure, createCallerFactory, createRouterFactory, mergeRouters }
|
|
|
20
20
|
export { TRPC_ERROR_CODES_BY_KEY, TRPC_ERROR_CODES_BY_NUMBER } from './unstable-core-do-not-import/rpc/codes.mjs';
|
|
21
21
|
export { parseTRPCMessage } from './unstable-core-do-not-import/rpc/parseTRPCMessage.mjs';
|
|
22
22
|
export { isPromise, jsonlStreamConsumer, jsonlStreamProducer } from './unstable-core-do-not-import/stream/jsonl.mjs';
|
|
23
|
-
export {
|
|
23
|
+
export { sseHeaders, sseStreamConsumer, sseStreamProducer } from './unstable-core-do-not-import/stream/sse.mjs';
|
|
24
|
+
export { isTrackedEnvelope, sse, tracked } from './unstable-core-do-not-import/stream/tracked.mjs';
|
|
24
25
|
export { createDeferred, createTimeoutPromise } from './unstable-core-do-not-import/stream/utils/createDeferred.mjs';
|
|
25
26
|
export { defaultTransformer, getDataTransformer, transformResult, transformTRPCResponse } from './unstable-core-do-not-import/transformer.mjs';
|
|
26
27
|
export { ERROR_SYMBOL } from './unstable-core-do-not-import/types.mjs';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@trpc/server",
|
|
3
|
-
"version": "11.0.0-rc.
|
|
3
|
+
"version": "11.0.0-rc.475+10b4bde0c",
|
|
4
4
|
"description": "The tRPC server library",
|
|
5
5
|
"author": "KATT",
|
|
6
6
|
"license": "MIT",
|
|
@@ -149,5 +149,5 @@
|
|
|
149
149
|
"funding": [
|
|
150
150
|
"https://trpc.io/sponsor"
|
|
151
151
|
],
|
|
152
|
-
"gitHead": "
|
|
152
|
+
"gitHead": "10b4bde0cb497c29d00f3c78c09fe8b64391f93c"
|
|
153
153
|
}
|
|
@@ -37,7 +37,11 @@ export {
|
|
|
37
37
|
type QueryProcedure as TRPCQueryProcedure,
|
|
38
38
|
type SubscriptionProcedure as TRPCSubscriptionProcedure,
|
|
39
39
|
type TRPCBuilder,
|
|
40
|
+
/**
|
|
41
|
+
* @deprecated use `tracked(id, data)` instead
|
|
42
|
+
*/
|
|
40
43
|
sse,
|
|
44
|
+
tracked,
|
|
41
45
|
} from '../../unstable-core-do-not-import';
|
|
42
46
|
|
|
43
47
|
export type {
|
package/src/adapters/ws.ts
CHANGED
|
@@ -21,6 +21,7 @@ import type {
|
|
|
21
21
|
TRPCConnectionParamsMessage,
|
|
22
22
|
TRPCReconnectNotification,
|
|
23
23
|
TRPCResponseMessage,
|
|
24
|
+
TRPCResultMessage,
|
|
24
25
|
} from '../@trpc/server/rpc';
|
|
25
26
|
import { parseConnectionParamsFromUnknown } from '../http';
|
|
26
27
|
import { isObservable } from '../observable';
|
|
@@ -29,6 +30,7 @@ import { observableToAsyncIterable } from '../observable/observable';
|
|
|
29
30
|
import {
|
|
30
31
|
isAsyncIterable,
|
|
31
32
|
isObject,
|
|
33
|
+
isTrackedEnvelope,
|
|
32
34
|
run,
|
|
33
35
|
type MaybePromise,
|
|
34
36
|
} from '../unstable-core-do-not-import';
|
|
@@ -171,6 +173,7 @@ export function getWSConnectionHandler<TRouter extends AnyRouter>(
|
|
|
171
173
|
|
|
172
174
|
async function handleRequest(msg: TRPCClientOutgoingMessage) {
|
|
173
175
|
const { id, jsonrpc } = msg;
|
|
176
|
+
|
|
174
177
|
/* istanbul ignore next -- @preserve */
|
|
175
178
|
if (id === null) {
|
|
176
179
|
throw new TRPCError({
|
|
@@ -182,9 +185,22 @@ export function getWSConnectionHandler<TRouter extends AnyRouter>(
|
|
|
182
185
|
clientSubscriptions.get(id)?.abort();
|
|
183
186
|
return;
|
|
184
187
|
}
|
|
185
|
-
const { path,
|
|
188
|
+
const { path, lastEventId } = msg.params;
|
|
189
|
+
let { input } = msg.params;
|
|
186
190
|
const type = msg.method;
|
|
187
191
|
try {
|
|
192
|
+
if (lastEventId !== undefined) {
|
|
193
|
+
if (isObject(input)) {
|
|
194
|
+
input = {
|
|
195
|
+
...input,
|
|
196
|
+
lastEventId: lastEventId,
|
|
197
|
+
};
|
|
198
|
+
} else {
|
|
199
|
+
input ??= {
|
|
200
|
+
lastEventId: lastEventId,
|
|
201
|
+
};
|
|
202
|
+
}
|
|
203
|
+
}
|
|
188
204
|
await ctxPromise; // asserts context has been set
|
|
189
205
|
|
|
190
206
|
const result = await callProcedure({
|
|
@@ -195,7 +211,16 @@ export function getWSConnectionHandler<TRouter extends AnyRouter>(
|
|
|
195
211
|
type,
|
|
196
212
|
});
|
|
197
213
|
|
|
214
|
+
const isIterableResult =
|
|
215
|
+
isAsyncIterable(result) || isObservable(result);
|
|
216
|
+
|
|
198
217
|
if (type !== 'subscription') {
|
|
218
|
+
if (isIterableResult) {
|
|
219
|
+
throw new TRPCError({
|
|
220
|
+
code: 'UNSUPPORTED_MEDIA_TYPE',
|
|
221
|
+
message: `Cannot return an async iterable or observable from a ${type} procedure with WebSockets`,
|
|
222
|
+
});
|
|
223
|
+
}
|
|
199
224
|
// send the value as data if the method is not a subscription
|
|
200
225
|
respond({
|
|
201
226
|
id,
|
|
@@ -208,7 +233,7 @@ export function getWSConnectionHandler<TRouter extends AnyRouter>(
|
|
|
208
233
|
return;
|
|
209
234
|
}
|
|
210
235
|
|
|
211
|
-
if (!
|
|
236
|
+
if (!isIterableResult) {
|
|
212
237
|
throw new TRPCError({
|
|
213
238
|
message: `Subscription ${path} did not return an observable or a AsyncGenerator`,
|
|
214
239
|
code: 'INTERNAL_SERVER_ERROR',
|
|
@@ -277,13 +302,24 @@ export function getWSConnectionHandler<TRouter extends AnyRouter>(
|
|
|
277
302
|
break;
|
|
278
303
|
}
|
|
279
304
|
|
|
305
|
+
const result: TRPCResultMessage<unknown>['result'] = {
|
|
306
|
+
type: 'data',
|
|
307
|
+
data: next.value,
|
|
308
|
+
};
|
|
309
|
+
|
|
310
|
+
if (isTrackedEnvelope(next.value)) {
|
|
311
|
+
const [id, data] = next.value;
|
|
312
|
+
result.id = id;
|
|
313
|
+
result.data = {
|
|
314
|
+
id,
|
|
315
|
+
data,
|
|
316
|
+
};
|
|
317
|
+
}
|
|
318
|
+
|
|
280
319
|
respond({
|
|
281
320
|
id,
|
|
282
321
|
jsonrpc,
|
|
283
|
-
result
|
|
284
|
-
type: 'data',
|
|
285
|
-
data: next.value,
|
|
286
|
-
},
|
|
322
|
+
result,
|
|
287
323
|
});
|
|
288
324
|
}
|
|
289
325
|
|
|
@@ -23,7 +23,7 @@ import type {
|
|
|
23
23
|
QueryProcedure,
|
|
24
24
|
SubscriptionProcedure,
|
|
25
25
|
} from './procedure';
|
|
26
|
-
import type {
|
|
26
|
+
import type { inferTrackedOutput } from './stream/tracked';
|
|
27
27
|
import type {
|
|
28
28
|
GetRawInputFn,
|
|
29
29
|
MaybePromise,
|
|
@@ -47,7 +47,7 @@ type DefaultValue<TValue, TFallback> = TValue extends UnsetMarker
|
|
|
47
47
|
type inferSubscriptionOutput<TOutput> = TOutput extends AsyncIterable<
|
|
48
48
|
infer $Output
|
|
49
49
|
>
|
|
50
|
-
?
|
|
50
|
+
? inferTrackedOutput<$Output>
|
|
51
51
|
: inferObservableValue<TOutput>;
|
|
52
52
|
|
|
53
53
|
export type CallerOverride<TContext> = (opts: {
|
|
@@ -49,7 +49,17 @@ export namespace JSONRPC2 {
|
|
|
49
49
|
/////////////////////////// HTTP envelopes ///////////////////////
|
|
50
50
|
|
|
51
51
|
export interface TRPCRequest
|
|
52
|
-
extends JSONRPC2.Request<
|
|
52
|
+
extends JSONRPC2.Request<
|
|
53
|
+
ProcedureType,
|
|
54
|
+
{
|
|
55
|
+
path: string;
|
|
56
|
+
input: unknown;
|
|
57
|
+
/**
|
|
58
|
+
* The last event id that the client received
|
|
59
|
+
*/
|
|
60
|
+
lastEventId?: string;
|
|
61
|
+
}
|
|
62
|
+
> {}
|
|
53
63
|
|
|
54
64
|
export interface TRPCResult<TData = unknown> {
|
|
55
65
|
data: TData;
|
|
@@ -101,7 +111,13 @@ export interface TRPCResultMessage<TData>
|
|
|
101
111
|
extends JSONRPC2.ResultResponse<
|
|
102
112
|
| { type: 'started'; data?: never }
|
|
103
113
|
| { type: 'stopped'; data?: never }
|
|
104
|
-
| (TRPCResult<TData> & {
|
|
114
|
+
| (TRPCResult<TData> & {
|
|
115
|
+
type: 'data';
|
|
116
|
+
/**
|
|
117
|
+
* The id of the message to keep track of in case of a reconnect
|
|
118
|
+
*/
|
|
119
|
+
id?: string;
|
|
120
|
+
})
|
|
105
121
|
> {}
|
|
106
122
|
|
|
107
123
|
export type TRPCResponseMessage<
|
|
@@ -67,9 +67,12 @@ export function parseTRPCMessage(
|
|
|
67
67
|
}
|
|
68
68
|
assertIsProcedureType(method);
|
|
69
69
|
assertIsObject(params);
|
|
70
|
-
const { input: rawInput, path } = params;
|
|
70
|
+
const { input: rawInput, path, lastEventId } = params;
|
|
71
71
|
|
|
72
72
|
assertIsString(path);
|
|
73
|
+
if (lastEventId !== undefined) {
|
|
74
|
+
assertIsString(lastEventId);
|
|
75
|
+
}
|
|
73
76
|
|
|
74
77
|
const input = transformer.input.deserialize(rawInput);
|
|
75
78
|
|
|
@@ -80,6 +83,7 @@ export function parseTRPCMessage(
|
|
|
80
83
|
params: {
|
|
81
84
|
input,
|
|
82
85
|
path,
|
|
86
|
+
lastEventId,
|
|
83
87
|
},
|
|
84
88
|
};
|
|
85
89
|
}
|