@trpc/client 9.20.1 → 10.0.0-alpha.10
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/TRPCClientError-17b117e1.mjs +81 -0
- package/dist/TRPCClientError-ec6bd2ca.js +94 -0
- package/dist/{declarations/src/TRPCClientError.d.ts → TRPCClientError.d.ts} +29 -33
- package/dist/TRPCClientError.d.ts.map +1 -0
- package/dist/createChain-3b458753.js +27 -0
- package/dist/createChain-b7cb1f5a.mjs +25 -0
- package/dist/{declarations/src/createTRPCClient.d.ts → createTRPCClient.d.ts} +5 -6
- package/dist/createTRPCClient.d.ts.map +1 -0
- package/dist/{declarations/src/getFetch.d.ts → getFetch.d.ts} +1 -1
- package/dist/getFetch.d.ts.map +1 -0
- package/dist/httpUtils-1f9e4e3c.js +97 -0
- package/dist/httpUtils-c09d7b79.mjs +91 -0
- package/dist/{declarations/src/index.d.ts → index.d.ts} +4 -4
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +243 -0
- package/dist/index.mjs +233 -0
- package/dist/index.ts.js +1 -0
- package/dist/{declarations/src/internals → internals}/TRPCClient.d.ts +62 -61
- package/dist/internals/TRPCClient.d.ts.map +1 -0
- package/dist/{declarations/src/internals → internals}/dataLoader.d.ts +16 -16
- package/dist/internals/dataLoader.d.ts.map +1 -0
- package/dist/{declarations/src/internals → internals}/fetchHelpers.d.ts +2 -2
- package/dist/internals/fetchHelpers.d.ts.map +1 -0
- package/dist/{declarations/src/internals → internals}/retryDelay.d.ts +1 -1
- package/dist/internals/retryDelay.d.ts.map +1 -0
- package/dist/links/dedupeLink.d.ts +4 -0
- package/dist/links/dedupeLink.d.ts.map +1 -0
- package/dist/{declarations/src/links → links}/httpBatchLink.d.ts +7 -6
- package/dist/links/httpBatchLink.d.ts.map +1 -0
- package/dist/links/httpBatchLink.js +195 -0
- package/dist/links/httpBatchLink.mjs +191 -0
- package/dist/links/httpBatchLink.ts.js +1 -0
- package/dist/{declarations/src/links → links}/httpLink.d.ts +4 -3
- package/dist/links/httpLink.d.ts.map +1 -0
- package/dist/links/httpLink.js +44 -0
- package/dist/links/httpLink.mjs +40 -0
- package/dist/links/httpLink.ts.js +1 -0
- package/dist/links/httpUtils.d.ts +22 -0
- package/dist/links/httpUtils.d.ts.map +1 -0
- package/dist/links/internals/createChain.d.ts +8 -0
- package/dist/links/internals/createChain.d.ts.map +1 -0
- package/dist/links/internals/transformOperationResult.d.ts +16 -0
- package/dist/links/internals/transformOperationResult.d.ts.map +1 -0
- package/dist/{declarations/src/links → links}/loggerLink.d.ts +38 -37
- package/dist/links/loggerLink.d.ts.map +1 -0
- package/dist/links/loggerLink.js +107 -0
- package/dist/links/loggerLink.mjs +98 -0
- package/dist/links/loggerLink.ts.js +1 -0
- package/dist/links/retryLink.d.ts +6 -0
- package/dist/links/retryLink.d.ts.map +1 -0
- package/dist/links/splitLink.d.ts +14 -0
- package/dist/links/splitLink.d.ts.map +1 -0
- package/dist/links/splitLink.js +32 -0
- package/dist/links/splitLink.mjs +28 -0
- package/dist/links/splitLink.ts.js +1 -0
- package/dist/links/transformerLink.d.ts +4 -0
- package/dist/links/transformerLink.d.ts.map +1 -0
- package/dist/links/transformerLink.js +79 -0
- package/dist/links/transformerLink.mjs +71 -0
- package/dist/links/transformerLink.ts.js +1 -0
- package/dist/links/types.d.ts +39 -0
- package/dist/links/types.d.ts.map +1 -0
- package/dist/links/wsLink.d.ts +21 -0
- package/dist/links/wsLink.d.ts.map +1 -0
- package/dist/links/wsLink.js +385 -0
- package/dist/links/wsLink.mjs +370 -0
- package/dist/links/wsLink.ts.js +1 -0
- package/dist/rx.d.ts +11 -0
- package/dist/rx.d.ts.map +1 -0
- package/dist/rx.js +88 -0
- package/dist/rx.mjs +73 -0
- package/dist/rx.ts.js +1 -0
- package/links/httpBatchLink/index.d.ts +1 -0
- package/links/httpBatchLink/index.js +1 -0
- package/links/httpLink/index.d.ts +1 -0
- package/links/httpLink/index.js +1 -0
- package/links/loggerLink/index.d.ts +1 -0
- package/links/loggerLink/index.js +1 -0
- package/links/splitLink/index.d.ts +1 -0
- package/links/splitLink/index.js +1 -0
- package/links/transformerLink/index.d.ts +1 -0
- package/links/transformerLink/index.js +1 -0
- package/links/wsLink/index.d.ts +1 -0
- package/links/wsLink/index.js +1 -0
- package/package.json +53 -18
- package/src/TRPCClientError.ts +17 -21
- package/src/createTRPCClient.ts +4 -3
- package/src/index.ts +1 -1
- package/src/internals/TRPCClient.ts +78 -92
- package/src/internals/dataLoader.ts +1 -1
- package/src/links/dedupeLink.test.ts +134 -0
- package/src/links/dedupeLink.ts +54 -0
- package/src/links/httpBatchLink.ts +36 -46
- package/src/links/httpLink.ts +26 -37
- package/src/{internals/httpRequest.ts → links/httpUtils.ts} +30 -21
- package/src/links/internals/createChain.test.ts +132 -0
- package/src/links/internals/createChain.ts +31 -0
- package/src/links/internals/transformOperationResult.ts +25 -0
- package/src/links/loggerLink.ts +39 -22
- package/src/links/retryLink.ts +44 -14
- package/src/links/splitLink.test.ts +56 -0
- package/src/links/splitLink.ts +23 -38
- package/src/links/transformerLink.ts +74 -0
- package/src/links/types.ts +64 -0
- package/src/links/wsLink.ts +57 -77
- package/src/rx.ts +50 -0
- package/dist/TRPCClientError-09b8a26b.esm.js +0 -77
- package/dist/TRPCClientError-bfee2bf5.cjs.dev.js +0 -79
- package/dist/TRPCClientError-e9bf96e9.cjs.prod.js +0 -79
- package/dist/declarations/src/TRPCClientError.d.ts.map +0 -1
- package/dist/declarations/src/createTRPCClient.d.ts.map +0 -1
- package/dist/declarations/src/getFetch.d.ts.map +0 -1
- package/dist/declarations/src/index.d.ts.map +0 -1
- package/dist/declarations/src/internals/TRPCAbortError.d.ts +0 -4
- package/dist/declarations/src/internals/TRPCAbortError.d.ts.map +0 -1
- package/dist/declarations/src/internals/TRPCClient.d.ts.map +0 -1
- package/dist/declarations/src/internals/dataLoader.d.ts.map +0 -1
- package/dist/declarations/src/internals/executeChain.d.ts +0 -9
- package/dist/declarations/src/internals/executeChain.d.ts.map +0 -1
- package/dist/declarations/src/internals/fetchHelpers.d.ts.map +0 -1
- package/dist/declarations/src/internals/httpRequest.d.ts +0 -14
- package/dist/declarations/src/internals/httpRequest.d.ts.map +0 -1
- package/dist/declarations/src/internals/observable.d.ts +0 -18
- package/dist/declarations/src/internals/observable.d.ts.map +0 -1
- package/dist/declarations/src/internals/retryDelay.d.ts.map +0 -1
- package/dist/declarations/src/internals/transformRPCResponse.d.ts +0 -15
- package/dist/declarations/src/internals/transformRPCResponse.d.ts.map +0 -1
- package/dist/declarations/src/links/core.d.ts +0 -45
- package/dist/declarations/src/links/core.d.ts.map +0 -1
- package/dist/declarations/src/links/httpBatchLink.d.ts.map +0 -1
- package/dist/declarations/src/links/httpLink.d.ts.map +0 -1
- package/dist/declarations/src/links/loggerLink.d.ts.map +0 -1
- package/dist/declarations/src/links/splitLink.d.ts +0 -24
- package/dist/declarations/src/links/splitLink.d.ts.map +0 -1
- package/dist/declarations/src/links/wsLink.d.ts +0 -30
- package/dist/declarations/src/links/wsLink.d.ts.map +0 -1
- package/dist/transformRPCResponse-57e80136.cjs.dev.js +0 -133
- package/dist/transformRPCResponse-739c13d0.cjs.prod.js +0 -133
- package/dist/transformRPCResponse-f7f8b0e1.esm.js +0 -129
- package/dist/trpc-client.cjs.d.ts +0 -1
- package/dist/trpc-client.cjs.dev.js +0 -379
- package/dist/trpc-client.cjs.js +0 -7
- package/dist/trpc-client.cjs.prod.js +0 -379
- package/dist/trpc-client.esm.js +0 -374
- package/links/httpBatchLink/package.json +0 -4
- package/links/httpLink/package.json +0 -4
- package/links/loggerLink/package.json +0 -4
- package/links/splitLink/package.json +0 -4
- package/links/wsLink/package.json +0 -4
- package/src/internals/TRPCAbortError.ts +0 -7
- package/src/internals/executeChain.ts +0 -67
- package/src/internals/observable.ts +0 -89
- package/src/internals/transformRPCResponse.ts +0 -25
- package/src/links/core.ts +0 -71
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-empty-function */
|
|
2
|
+
import { AnyRouter } from '../../../server/src';
|
|
3
|
+
import { createChain } from '../links/internals/createChain';
|
|
4
|
+
import { splitLink } from '../links/splitLink';
|
|
5
|
+
import { OperationLink, TRPCLink } from '../links/types';
|
|
6
|
+
import { Observable } from 'rxjs';
|
|
7
|
+
|
|
8
|
+
test('splitLink', () => {
|
|
9
|
+
const wsLinkSpy = jest.fn();
|
|
10
|
+
const wsLink: TRPCLink<any> = () => () =>
|
|
11
|
+
new Observable(() => {
|
|
12
|
+
wsLinkSpy();
|
|
13
|
+
});
|
|
14
|
+
const httpLinkSpy = jest.fn();
|
|
15
|
+
const httpLink: TRPCLink<any> = () => () =>
|
|
16
|
+
new Observable(() => {
|
|
17
|
+
httpLinkSpy();
|
|
18
|
+
});
|
|
19
|
+
const links: OperationLink<AnyRouter, any, any>[] = [
|
|
20
|
+
// "dedupe link"
|
|
21
|
+
splitLink({
|
|
22
|
+
condition(op) {
|
|
23
|
+
return op.type === 'subscription';
|
|
24
|
+
},
|
|
25
|
+
true: wsLink,
|
|
26
|
+
false: [httpLink],
|
|
27
|
+
})(null as any),
|
|
28
|
+
];
|
|
29
|
+
|
|
30
|
+
createChain({
|
|
31
|
+
links,
|
|
32
|
+
op: {
|
|
33
|
+
type: 'query',
|
|
34
|
+
input: null,
|
|
35
|
+
path: '.',
|
|
36
|
+
id: 0,
|
|
37
|
+
context: {},
|
|
38
|
+
},
|
|
39
|
+
}).subscribe({});
|
|
40
|
+
expect(httpLinkSpy).toHaveBeenCalledTimes(1);
|
|
41
|
+
expect(wsLinkSpy).toHaveBeenCalledTimes(0);
|
|
42
|
+
jest.resetAllMocks();
|
|
43
|
+
|
|
44
|
+
createChain({
|
|
45
|
+
links,
|
|
46
|
+
op: {
|
|
47
|
+
type: 'subscription',
|
|
48
|
+
input: null,
|
|
49
|
+
path: '.',
|
|
50
|
+
id: 0,
|
|
51
|
+
context: {},
|
|
52
|
+
},
|
|
53
|
+
}).subscribe({});
|
|
54
|
+
expect(httpLinkSpy).toHaveBeenCalledTimes(0);
|
|
55
|
+
expect(wsLinkSpy).toHaveBeenCalledTimes(1);
|
|
56
|
+
});
|
package/src/links/splitLink.ts
CHANGED
|
@@ -1,45 +1,30 @@
|
|
|
1
1
|
import { AnyRouter } from '@trpc/server';
|
|
2
|
-
import {
|
|
2
|
+
import { Observable } from 'rxjs';
|
|
3
|
+
import { TRPCLink, Operation } from './types';
|
|
4
|
+
import { createChain } from './internals/createChain';
|
|
3
5
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
| {
|
|
19
|
-
/**
|
|
20
|
-
* The link to execute next if the test function returns `true`.
|
|
21
|
-
*/
|
|
22
|
-
true: TRPCLink<TRouter>;
|
|
23
|
-
/**
|
|
24
|
-
* The link to execute next if the test function returns `false`.
|
|
25
|
-
*/
|
|
26
|
-
false: TRPCLink<TRouter>;
|
|
27
|
-
}
|
|
28
|
-
),
|
|
29
|
-
): TRPCLink<TRouter> {
|
|
6
|
+
function asArray<T>(value: T | T[]) {
|
|
7
|
+
return Array.isArray(value) ? value : [value];
|
|
8
|
+
}
|
|
9
|
+
export function splitLink<TRouter extends AnyRouter = AnyRouter>(opts: {
|
|
10
|
+
condition: (op: Operation) => boolean;
|
|
11
|
+
/**
|
|
12
|
+
* The link to execute next if the test function returns `true`.
|
|
13
|
+
*/
|
|
14
|
+
true: TRPCLink<TRouter> | TRPCLink<TRouter>[];
|
|
15
|
+
/**
|
|
16
|
+
* The link to execute next if the test function returns `false`.
|
|
17
|
+
*/
|
|
18
|
+
false: TRPCLink<TRouter> | TRPCLink<TRouter>[];
|
|
19
|
+
}): TRPCLink<TRouter> {
|
|
30
20
|
return (rt) => {
|
|
31
|
-
const
|
|
32
|
-
|
|
33
|
-
? {
|
|
34
|
-
true: opts.left,
|
|
35
|
-
false: opts.right,
|
|
36
|
-
}
|
|
37
|
-
: opts;
|
|
38
|
-
|
|
39
|
-
const yes = links.true(rt);
|
|
40
|
-
const no = links.false(rt);
|
|
21
|
+
const yes = asArray(opts.true).map((link) => link(rt));
|
|
22
|
+
const no = asArray(opts.false).map((link) => link(rt));
|
|
41
23
|
return (props) => {
|
|
42
|
-
|
|
24
|
+
return new Observable((observer) => {
|
|
25
|
+
const links = opts.condition(props.op) ? yes : no;
|
|
26
|
+
return createChain({ op: props.op, links }).subscribe(observer);
|
|
27
|
+
});
|
|
43
28
|
};
|
|
44
29
|
};
|
|
45
30
|
}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import {
|
|
2
|
+
AnyRouter,
|
|
3
|
+
ClientDataTransformerOptions,
|
|
4
|
+
DataTransformer,
|
|
5
|
+
} from '@trpc/server';
|
|
6
|
+
import { Observable } from 'rxjs';
|
|
7
|
+
import { OperationResult, TRPCLink } from './types';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* @internal
|
|
11
|
+
*/
|
|
12
|
+
function transformOperationResult<TResult extends OperationResult<any, any>>(
|
|
13
|
+
result: TResult,
|
|
14
|
+
transformer: DataTransformer,
|
|
15
|
+
) {
|
|
16
|
+
if ('error' in result.data) {
|
|
17
|
+
return {
|
|
18
|
+
...result,
|
|
19
|
+
data: {
|
|
20
|
+
...result.data,
|
|
21
|
+
error: transformer.deserialize(result.data.error),
|
|
22
|
+
},
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
if (result.data.result.type !== 'data') {
|
|
26
|
+
return result;
|
|
27
|
+
}
|
|
28
|
+
return {
|
|
29
|
+
...result,
|
|
30
|
+
data: {
|
|
31
|
+
...result.data,
|
|
32
|
+
result: {
|
|
33
|
+
...result.data.result,
|
|
34
|
+
data: transformer.deserialize(result.data.result.data),
|
|
35
|
+
},
|
|
36
|
+
},
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
export function transformerLink<TRouter extends AnyRouter = AnyRouter>(
|
|
40
|
+
transformer: ClientDataTransformerOptions,
|
|
41
|
+
): TRPCLink<TRouter> {
|
|
42
|
+
const _transformer: DataTransformer = transformer
|
|
43
|
+
? 'input' in transformer
|
|
44
|
+
? {
|
|
45
|
+
serialize: transformer.input.serialize,
|
|
46
|
+
deserialize: transformer.output.deserialize,
|
|
47
|
+
}
|
|
48
|
+
: transformer
|
|
49
|
+
: {
|
|
50
|
+
serialize: (data) => data,
|
|
51
|
+
deserialize: (data) => data,
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
return () => {
|
|
55
|
+
return (props) => {
|
|
56
|
+
const input = _transformer.serialize(props.op.input);
|
|
57
|
+
return new Observable((observer) => {
|
|
58
|
+
const subscription = props.next({ ...props.op, input }).subscribe({
|
|
59
|
+
next(value) {
|
|
60
|
+
const transformed = transformOperationResult(value, _transformer);
|
|
61
|
+
observer.next(transformed);
|
|
62
|
+
},
|
|
63
|
+
error(err) {
|
|
64
|
+
observer.error(err);
|
|
65
|
+
},
|
|
66
|
+
complete() {
|
|
67
|
+
observer.complete();
|
|
68
|
+
},
|
|
69
|
+
});
|
|
70
|
+
return subscription;
|
|
71
|
+
});
|
|
72
|
+
};
|
|
73
|
+
};
|
|
74
|
+
}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { AnyRouter, inferRouterError, Dict } from '@trpc/server';
|
|
2
|
+
import { TRPCResponse } from '@trpc/server/rpc';
|
|
3
|
+
import { Observable, Observer } from 'rxjs';
|
|
4
|
+
|
|
5
|
+
export type CancelFn = () => void;
|
|
6
|
+
|
|
7
|
+
export type PromiseAndCancel<TValue> = {
|
|
8
|
+
promise: Promise<TValue>;
|
|
9
|
+
cancel: CancelFn;
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
export type OperationContext = Record<string, unknown>;
|
|
13
|
+
export type Operation<TInput = unknown> = {
|
|
14
|
+
id: number;
|
|
15
|
+
type: 'query' | 'mutation' | 'subscription';
|
|
16
|
+
input: TInput;
|
|
17
|
+
path: string;
|
|
18
|
+
context?: OperationContext;
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
export type HTTPHeaders = Dict<string | string[]>;
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* The default `fetch` implementation has an overloaded signature. By convention this library
|
|
25
|
+
* only uses the overload taking a string and options object.
|
|
26
|
+
*/
|
|
27
|
+
export type TRPCFetch = (
|
|
28
|
+
url: string,
|
|
29
|
+
options?: RequestInit,
|
|
30
|
+
) => Promise<Response>;
|
|
31
|
+
|
|
32
|
+
export interface LinkRuntime {
|
|
33
|
+
headers: () => HTTPHeaders | Promise<HTTPHeaders>;
|
|
34
|
+
fetch: TRPCFetch;
|
|
35
|
+
AbortController?: typeof AbortController;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export interface OperationResult<TRouter extends AnyRouter, TOutput> {
|
|
39
|
+
data: TRPCResponse<TOutput, inferRouterError<TRouter>>;
|
|
40
|
+
context?: OperationContext;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export type OperationResultObservable<
|
|
44
|
+
TRouter extends AnyRouter,
|
|
45
|
+
TOutput,
|
|
46
|
+
> = Observable<OperationResult<TRouter, TOutput>>;
|
|
47
|
+
|
|
48
|
+
export type OperationResultObserver<
|
|
49
|
+
TRouter extends AnyRouter,
|
|
50
|
+
TOutput,
|
|
51
|
+
> = Observer<OperationResult<TRouter, TOutput>>;
|
|
52
|
+
|
|
53
|
+
export type OperationLink<
|
|
54
|
+
TRouter extends AnyRouter,
|
|
55
|
+
TInput = unknown,
|
|
56
|
+
TOutput = unknown,
|
|
57
|
+
> = (opts: {
|
|
58
|
+
op: Operation<TInput>;
|
|
59
|
+
next: (op: Operation<TInput>) => OperationResultObservable<TRouter, TOutput>;
|
|
60
|
+
}) => OperationResultObservable<TRouter, TOutput>;
|
|
61
|
+
|
|
62
|
+
export type TRPCLink<TRouter extends AnyRouter> = (
|
|
63
|
+
opts: LinkRuntime,
|
|
64
|
+
) => OperationLink<TRouter>;
|
package/src/links/wsLink.ts
CHANGED
|
@@ -4,20 +4,14 @@ import {
|
|
|
4
4
|
TRPCClientIncomingRequest,
|
|
5
5
|
TRPCRequest,
|
|
6
6
|
TRPCResponse,
|
|
7
|
-
TRPCResult,
|
|
8
7
|
} from '@trpc/server/rpc';
|
|
9
|
-
import { TRPCErrorResponse } from '@trpc/server/rpc';
|
|
10
|
-
import { ObservableCallbacks, UnsubscribeFn } from '../internals/observable';
|
|
11
8
|
import { retryDelay } from '../internals/retryDelay';
|
|
9
|
+
|
|
10
|
+
import { Observable } from 'rxjs';
|
|
12
11
|
import { TRPCClientError } from '../TRPCClientError';
|
|
13
|
-
import { TRPCLink } from './
|
|
12
|
+
import { Operation, OperationResultObserver, TRPCLink } from './types';
|
|
14
13
|
|
|
15
|
-
type
|
|
16
|
-
id: number | string;
|
|
17
|
-
type: ProcedureType;
|
|
18
|
-
input: unknown;
|
|
19
|
-
path: string;
|
|
20
|
-
};
|
|
14
|
+
type UnsubscribeFn = () => void;
|
|
21
15
|
export interface WebSocketClientOptions {
|
|
22
16
|
url: string;
|
|
23
17
|
WebSocket?: WebSocket;
|
|
@@ -42,10 +36,7 @@ export function createWSClient(opts: WebSocketClientOptions) {
|
|
|
42
36
|
/**
|
|
43
37
|
* pending outgoing requests that are awaiting callback
|
|
44
38
|
*/
|
|
45
|
-
type TCallbacks =
|
|
46
|
-
TRPCResult,
|
|
47
|
-
TRPCClientError<AnyRouter> | TRPCErrorResponse
|
|
48
|
-
>;
|
|
39
|
+
type TCallbacks = OperationResultObserver<AnyRouter, unknown>;
|
|
49
40
|
type TRequest = {
|
|
50
41
|
/**
|
|
51
42
|
* Reference to the WebSocket instance this request was made to
|
|
@@ -151,18 +142,14 @@ export function createWSClient(opts: WebSocketClientOptions) {
|
|
|
151
142
|
}
|
|
152
143
|
}
|
|
153
144
|
};
|
|
154
|
-
const handleIncomingResponse = (
|
|
155
|
-
const req =
|
|
145
|
+
const handleIncomingResponse = (data: TRPCResponse) => {
|
|
146
|
+
const req = data.id !== null && pendingRequests[data.id];
|
|
156
147
|
if (!req) {
|
|
157
148
|
// do something?
|
|
158
149
|
return;
|
|
159
150
|
}
|
|
160
|
-
if ('error' in res) {
|
|
161
|
-
req.callbacks.onError?.(res);
|
|
162
|
-
return;
|
|
163
|
-
}
|
|
164
151
|
|
|
165
|
-
req.callbacks.
|
|
152
|
+
req.callbacks.next?.({ data });
|
|
166
153
|
if (req.ws !== activeConnection && conn === activeConnection) {
|
|
167
154
|
const oldWs = req.ws;
|
|
168
155
|
// gracefully replace old connection with this
|
|
@@ -170,8 +157,12 @@ export function createWSClient(opts: WebSocketClientOptions) {
|
|
|
170
157
|
closeIfNoPending(oldWs);
|
|
171
158
|
}
|
|
172
159
|
|
|
173
|
-
if (
|
|
174
|
-
|
|
160
|
+
if (
|
|
161
|
+
'result' in data &&
|
|
162
|
+
data.result.type === 'stopped' &&
|
|
163
|
+
conn === activeConnection
|
|
164
|
+
) {
|
|
165
|
+
req.callbacks.complete();
|
|
175
166
|
}
|
|
176
167
|
};
|
|
177
168
|
conn.addEventListener('message', ({ data }) => {
|
|
@@ -199,14 +190,14 @@ export function createWSClient(opts: WebSocketClientOptions) {
|
|
|
199
190
|
if (req.ws !== conn) {
|
|
200
191
|
continue;
|
|
201
192
|
}
|
|
202
|
-
req.callbacks.
|
|
193
|
+
req.callbacks.error?.(
|
|
203
194
|
TRPCClientError.from(
|
|
204
195
|
new TRPCWebSocketClosedError('WebSocket closed prematurely'),
|
|
205
196
|
),
|
|
206
197
|
);
|
|
207
198
|
if (req.type !== 'subscription') {
|
|
208
199
|
delete pendingRequests[key];
|
|
209
|
-
req.callbacks.
|
|
200
|
+
req.callbacks.complete?.();
|
|
210
201
|
} else if (state !== 'closed') {
|
|
211
202
|
// request restart of sub with next connection
|
|
212
203
|
resumeSubscriptionOnReconnect(req);
|
|
@@ -243,7 +234,7 @@ export function createWSClient(opts: WebSocketClientOptions) {
|
|
|
243
234
|
delete pendingRequests[id];
|
|
244
235
|
outgoing = outgoing.filter((msg) => msg.id !== id);
|
|
245
236
|
|
|
246
|
-
callbacks?.
|
|
237
|
+
callbacks?.complete?.();
|
|
247
238
|
if (op.type === 'subscription') {
|
|
248
239
|
outgoing.push({
|
|
249
240
|
id,
|
|
@@ -289,63 +280,52 @@ class TRPCSubscriptionEndedError extends Error {
|
|
|
289
280
|
export function wsLink<TRouter extends AnyRouter>(
|
|
290
281
|
opts: WebSocketLinkOptions,
|
|
291
282
|
): TRPCLink<TRouter> {
|
|
292
|
-
|
|
293
|
-
return (rt) => {
|
|
283
|
+
return () => {
|
|
294
284
|
const { client } = opts;
|
|
285
|
+
return ({ op }) => {
|
|
286
|
+
return new Observable((observer) => {
|
|
287
|
+
const { type, input, path, id, context } = op;
|
|
295
288
|
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
{ type, path, input, id },
|
|
302
|
-
{
|
|
303
|
-
onNext(result) {
|
|
304
|
-
if (isDone) {
|
|
305
|
-
return;
|
|
306
|
-
}
|
|
307
|
-
if ('data' in result) {
|
|
308
|
-
const data = rt.transformer.deserialize(result.data);
|
|
309
|
-
prev({ type: 'data', data });
|
|
310
|
-
} else {
|
|
311
|
-
prev(result);
|
|
312
|
-
}
|
|
313
|
-
|
|
314
|
-
if (op.type !== 'subscription') {
|
|
315
|
-
// if it isn't a subscription we don't care about next response
|
|
289
|
+
let isDone = false;
|
|
290
|
+
const unsub = client.request(
|
|
291
|
+
{ type, path, input, id, context },
|
|
292
|
+
{
|
|
293
|
+
error(err) {
|
|
316
294
|
isDone = true;
|
|
295
|
+
observer.error(err);
|
|
317
296
|
unsub();
|
|
318
|
-
}
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
return;
|
|
336
|
-
}
|
|
337
|
-
const result = new TRPCSubscriptionEndedError(
|
|
338
|
-
'Operation ended prematurely',
|
|
339
|
-
);
|
|
297
|
+
},
|
|
298
|
+
complete() {
|
|
299
|
+
if (!isDone) {
|
|
300
|
+
isDone = true;
|
|
301
|
+
observer.error(
|
|
302
|
+
TRPCClientError.from(
|
|
303
|
+
new TRPCSubscriptionEndedError(
|
|
304
|
+
'Operation ended prematurely',
|
|
305
|
+
),
|
|
306
|
+
),
|
|
307
|
+
);
|
|
308
|
+
} else {
|
|
309
|
+
observer.complete();
|
|
310
|
+
}
|
|
311
|
+
},
|
|
312
|
+
next(result) {
|
|
313
|
+
observer.next(result);
|
|
340
314
|
|
|
341
|
-
|
|
342
|
-
|
|
315
|
+
if (op.type !== 'subscription') {
|
|
316
|
+
// if it isn't a subscription we don't care about next response
|
|
317
|
+
|
|
318
|
+
isDone = true;
|
|
319
|
+
unsub();
|
|
320
|
+
observer.complete();
|
|
321
|
+
}
|
|
322
|
+
},
|
|
343
323
|
},
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
324
|
+
);
|
|
325
|
+
return () => {
|
|
326
|
+
isDone = true;
|
|
327
|
+
unsub();
|
|
328
|
+
};
|
|
349
329
|
});
|
|
350
330
|
};
|
|
351
331
|
};
|
package/src/rx.ts
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { Observable } from 'rxjs';
|
|
2
|
+
|
|
3
|
+
export type inferObservableValue<TObservable extends Observable<any>> =
|
|
4
|
+
TObservable extends Observable<infer TValue> ? TValue : never;
|
|
5
|
+
|
|
6
|
+
export class ObservableAbortError extends Error {
|
|
7
|
+
constructor(message: string) {
|
|
8
|
+
super(message);
|
|
9
|
+
this.name = 'ObservableAbortError';
|
|
10
|
+
Object.setPrototypeOf(this, ObservableAbortError.prototype);
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/** @internal */
|
|
15
|
+
export function observableToPromise<TValue>(observable: Observable<TValue>) {
|
|
16
|
+
let abort: () => void;
|
|
17
|
+
const promise = new Promise<TValue>((resolve, reject) => {
|
|
18
|
+
let isDone = false;
|
|
19
|
+
function onDone() {
|
|
20
|
+
if (isDone) {
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
isDone = true;
|
|
24
|
+
reject(new ObservableAbortError('This operation was cancelled.'));
|
|
25
|
+
subscription.unsubscribe();
|
|
26
|
+
}
|
|
27
|
+
const subscription = observable.subscribe({
|
|
28
|
+
next(data) {
|
|
29
|
+
isDone = true;
|
|
30
|
+
resolve(data);
|
|
31
|
+
onDone();
|
|
32
|
+
},
|
|
33
|
+
error(data) {
|
|
34
|
+
isDone = true;
|
|
35
|
+
reject(data);
|
|
36
|
+
onDone();
|
|
37
|
+
},
|
|
38
|
+
complete() {
|
|
39
|
+
isDone = true;
|
|
40
|
+
onDone();
|
|
41
|
+
},
|
|
42
|
+
});
|
|
43
|
+
abort = onDone;
|
|
44
|
+
});
|
|
45
|
+
return {
|
|
46
|
+
promise,
|
|
47
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
48
|
+
abort: abort!,
|
|
49
|
+
};
|
|
50
|
+
}
|
|
@@ -1,77 +0,0 @@
|
|
|
1
|
-
import _objectSpread from '@babel/runtime/helpers/esm/objectSpread2';
|
|
2
|
-
import _classCallCheck from '@babel/runtime/helpers/esm/classCallCheck';
|
|
3
|
-
import _createClass from '@babel/runtime/helpers/esm/createClass';
|
|
4
|
-
import _assertThisInitialized from '@babel/runtime/helpers/esm/assertThisInitialized';
|
|
5
|
-
import _inherits from '@babel/runtime/helpers/esm/inherits';
|
|
6
|
-
import _createSuper from '@babel/runtime/helpers/esm/createSuper';
|
|
7
|
-
import _wrapNativeSuper from '@babel/runtime/helpers/esm/wrapNativeSuper';
|
|
8
|
-
|
|
9
|
-
var TRPCClientError = /*#__PURE__*/function (_Error) {
|
|
10
|
-
_inherits(TRPCClientError, _Error);
|
|
11
|
-
|
|
12
|
-
var _super = /*#__PURE__*/_createSuper(TRPCClientError);
|
|
13
|
-
|
|
14
|
-
/**
|
|
15
|
-
* @deprecated use `cause`
|
|
16
|
-
*/
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
* Fatal error - expect no more results after this error
|
|
20
|
-
* Used for when WebSockets disconnect prematurely.
|
|
21
|
-
*/
|
|
22
|
-
function TRPCClientError(message, opts) {
|
|
23
|
-
var _opts$cause, _opts$isDone, _opts$result, _opts$result2;
|
|
24
|
-
|
|
25
|
-
var _this;
|
|
26
|
-
|
|
27
|
-
_classCallCheck(this, TRPCClientError);
|
|
28
|
-
|
|
29
|
-
var cause = (_opts$cause = opts.cause) !== null && _opts$cause !== void 0 ? _opts$cause : opts.originalError; // eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
30
|
-
// @ts-ignore https://github.com/tc39/proposal-error-cause
|
|
31
|
-
|
|
32
|
-
_this = _super.call(this, message, {
|
|
33
|
-
cause: cause
|
|
34
|
-
});
|
|
35
|
-
_this.originalError = void 0;
|
|
36
|
-
_this.cause = void 0;
|
|
37
|
-
_this.shape = void 0;
|
|
38
|
-
_this.data = void 0;
|
|
39
|
-
_this.isDone = void 0;
|
|
40
|
-
_this.isDone = (_opts$isDone = opts.isDone) !== null && _opts$isDone !== void 0 ? _opts$isDone : false;
|
|
41
|
-
_this.cause = _this.originalError = cause;
|
|
42
|
-
_this.shape = (_opts$result = opts.result) === null || _opts$result === void 0 ? void 0 : _opts$result.error;
|
|
43
|
-
_this.data = (_opts$result2 = opts.result) === null || _opts$result2 === void 0 ? void 0 : _opts$result2.error.data;
|
|
44
|
-
_this.name = 'TRPCClientError';
|
|
45
|
-
Object.setPrototypeOf(_assertThisInitialized(_this), TRPCClientError.prototype);
|
|
46
|
-
return _this;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
_createClass(TRPCClientError, null, [{
|
|
50
|
-
key: "from",
|
|
51
|
-
value: function from(result) {
|
|
52
|
-
var opts = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|
53
|
-
|
|
54
|
-
if (!(result instanceof Error)) {
|
|
55
|
-
var _message;
|
|
56
|
-
|
|
57
|
-
return new TRPCClientError((_message = result.error.message) !== null && _message !== void 0 ? _message : '', _objectSpread(_objectSpread({}, opts), {}, {
|
|
58
|
-
cause: null,
|
|
59
|
-
result: result
|
|
60
|
-
}));
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
if (result.name === 'TRPCClientError') {
|
|
64
|
-
return result;
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
return new TRPCClientError(result.message, _objectSpread(_objectSpread({}, opts), {}, {
|
|
68
|
-
cause: result,
|
|
69
|
-
result: null
|
|
70
|
-
}));
|
|
71
|
-
}
|
|
72
|
-
}]);
|
|
73
|
-
|
|
74
|
-
return TRPCClientError;
|
|
75
|
-
}( /*#__PURE__*/_wrapNativeSuper(Error));
|
|
76
|
-
|
|
77
|
-
export { TRPCClientError as T };
|
|
@@ -1,79 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
var _objectSpread = require('@babel/runtime/helpers/objectSpread2');
|
|
4
|
-
var _classCallCheck = require('@babel/runtime/helpers/classCallCheck');
|
|
5
|
-
var _createClass = require('@babel/runtime/helpers/createClass');
|
|
6
|
-
var _assertThisInitialized = require('@babel/runtime/helpers/assertThisInitialized');
|
|
7
|
-
var _inherits = require('@babel/runtime/helpers/inherits');
|
|
8
|
-
var _createSuper = require('@babel/runtime/helpers/createSuper');
|
|
9
|
-
var _wrapNativeSuper = require('@babel/runtime/helpers/wrapNativeSuper');
|
|
10
|
-
|
|
11
|
-
var TRPCClientError = /*#__PURE__*/function (_Error) {
|
|
12
|
-
_inherits(TRPCClientError, _Error);
|
|
13
|
-
|
|
14
|
-
var _super = /*#__PURE__*/_createSuper(TRPCClientError);
|
|
15
|
-
|
|
16
|
-
/**
|
|
17
|
-
* @deprecated use `cause`
|
|
18
|
-
*/
|
|
19
|
-
|
|
20
|
-
/**
|
|
21
|
-
* Fatal error - expect no more results after this error
|
|
22
|
-
* Used for when WebSockets disconnect prematurely.
|
|
23
|
-
*/
|
|
24
|
-
function TRPCClientError(message, opts) {
|
|
25
|
-
var _opts$cause, _opts$isDone, _opts$result, _opts$result2;
|
|
26
|
-
|
|
27
|
-
var _this;
|
|
28
|
-
|
|
29
|
-
_classCallCheck(this, TRPCClientError);
|
|
30
|
-
|
|
31
|
-
var cause = (_opts$cause = opts.cause) !== null && _opts$cause !== void 0 ? _opts$cause : opts.originalError; // eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
32
|
-
// @ts-ignore https://github.com/tc39/proposal-error-cause
|
|
33
|
-
|
|
34
|
-
_this = _super.call(this, message, {
|
|
35
|
-
cause: cause
|
|
36
|
-
});
|
|
37
|
-
_this.originalError = void 0;
|
|
38
|
-
_this.cause = void 0;
|
|
39
|
-
_this.shape = void 0;
|
|
40
|
-
_this.data = void 0;
|
|
41
|
-
_this.isDone = void 0;
|
|
42
|
-
_this.isDone = (_opts$isDone = opts.isDone) !== null && _opts$isDone !== void 0 ? _opts$isDone : false;
|
|
43
|
-
_this.cause = _this.originalError = cause;
|
|
44
|
-
_this.shape = (_opts$result = opts.result) === null || _opts$result === void 0 ? void 0 : _opts$result.error;
|
|
45
|
-
_this.data = (_opts$result2 = opts.result) === null || _opts$result2 === void 0 ? void 0 : _opts$result2.error.data;
|
|
46
|
-
_this.name = 'TRPCClientError';
|
|
47
|
-
Object.setPrototypeOf(_assertThisInitialized(_this), TRPCClientError.prototype);
|
|
48
|
-
return _this;
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
_createClass(TRPCClientError, null, [{
|
|
52
|
-
key: "from",
|
|
53
|
-
value: function from(result) {
|
|
54
|
-
var opts = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|
55
|
-
|
|
56
|
-
if (!(result instanceof Error)) {
|
|
57
|
-
var _message;
|
|
58
|
-
|
|
59
|
-
return new TRPCClientError((_message = result.error.message) !== null && _message !== void 0 ? _message : '', _objectSpread(_objectSpread({}, opts), {}, {
|
|
60
|
-
cause: null,
|
|
61
|
-
result: result
|
|
62
|
-
}));
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
if (result.name === 'TRPCClientError') {
|
|
66
|
-
return result;
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
return new TRPCClientError(result.message, _objectSpread(_objectSpread({}, opts), {}, {
|
|
70
|
-
cause: result,
|
|
71
|
-
result: null
|
|
72
|
-
}));
|
|
73
|
-
}
|
|
74
|
-
}]);
|
|
75
|
-
|
|
76
|
-
return TRPCClientError;
|
|
77
|
-
}( /*#__PURE__*/_wrapNativeSuper(Error));
|
|
78
|
-
|
|
79
|
-
exports.TRPCClientError = TRPCClientError;
|