@trpc/client 10.0.0-alpha.3 → 10.0.0-alpha.32
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.d.ts +3 -11
- package/dist/TRPCClientError.d.ts.map +1 -1
- package/dist/createTRPCClient.d.ts +3 -4
- package/dist/createTRPCClient.d.ts.map +1 -1
- package/dist/createTRPCClientProxy.d.ts +8 -0
- package/dist/createTRPCClientProxy.d.ts.map +1 -0
- package/dist/{httpUtils-c09d7b79.mjs → httpUtils-089853f6.mjs} +38 -30
- package/dist/{httpUtils-1f9e4e3c.js → httpUtils-a0169eef.js} +38 -29
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +266 -104
- package/dist/index.mjs +253 -95
- package/dist/internals/TRPCClient.d.ts +14 -17
- package/dist/internals/TRPCClient.d.ts.map +1 -1
- package/dist/internals/dataLoader.d.ts +7 -4
- package/dist/internals/dataLoader.d.ts.map +1 -1
- package/dist/links/dedupeLink.d.ts.map +1 -1
- package/dist/links/httpBatchLink.d.ts +5 -2
- package/dist/links/httpBatchLink.d.ts.map +1 -1
- package/dist/links/httpBatchLink.js +197 -69
- package/dist/links/httpBatchLink.mjs +197 -69
- package/dist/links/httpLink.d.ts +1 -1
- package/dist/links/httpLink.d.ts.map +1 -1
- package/dist/links/httpLink.js +5 -5
- package/dist/links/httpLink.mjs +5 -5
- package/dist/links/index.d.ts +9 -0
- package/dist/links/index.d.ts.map +1 -0
- package/dist/links/internals/httpUtils.d.ts +30 -0
- package/dist/links/internals/httpUtils.d.ts.map +1 -0
- package/dist/links/internals/transformOperationResult.d.ts +17 -3
- package/dist/links/internals/transformOperationResult.d.ts.map +1 -1
- package/dist/links/loggerLink.d.ts.map +1 -1
- package/dist/links/loggerLink.js +2 -3
- package/dist/links/loggerLink.mjs +1 -2
- package/dist/links/retryLink.d.ts.map +1 -1
- package/dist/links/splitLink.d.ts +1 -1
- package/dist/links/splitLink.d.ts.map +1 -1
- package/dist/links/splitLink.js +3 -25
- package/dist/links/splitLink.mjs +2 -28
- package/dist/links/types.d.ts +12 -9
- package/dist/links/types.d.ts.map +1 -1
- package/dist/links/wsLink.d.ts +3 -3
- package/dist/links/wsLink.d.ts.map +1 -1
- package/dist/links/wsLink.js +11 -376
- package/dist/links/wsLink.mjs +9 -369
- package/dist/splitLink-62ff9db0.mjs +49 -0
- package/dist/splitLink-8202386e.js +52 -0
- package/dist/wsLink-69f5adb8.js +451 -0
- package/dist/wsLink-9468a563.mjs +436 -0
- package/links/httpBatchLink/dist/trpc-client-links-httpBatchLink.cjs.dev.js +81 -15
- package/links/httpBatchLink/dist/trpc-client-links-httpBatchLink.cjs.prod.js +81 -15
- package/links/httpBatchLink/dist/trpc-client-links-httpBatchLink.esm.js +77 -15
- package/links/httpBatchLink/index.d.ts +1 -1
- package/links/httpBatchLink/index.js +1 -1
- package/links/httpLink/dist/trpc-client-links-httpLink.cjs.dev.js +76 -9
- package/links/httpLink/dist/trpc-client-links-httpLink.cjs.prod.js +76 -9
- package/links/httpLink/dist/trpc-client-links-httpLink.esm.js +72 -9
- package/links/httpLink/index.d.ts +1 -1
- package/links/httpLink/index.js +1 -1
- package/links/loggerLink/index.d.ts +1 -1
- package/links/loggerLink/index.js +1 -1
- package/links/splitLink/index.d.ts +1 -1
- package/links/splitLink/index.js +1 -1
- package/links/wsLink/dist/trpc-client-links-wsLink.cjs.dev.js +3 -1
- package/links/wsLink/dist/trpc-client-links-wsLink.cjs.prod.js +3 -1
- package/links/wsLink/dist/trpc-client-links-wsLink.esm.js +3 -1
- package/links/wsLink/index.d.ts +1 -1
- package/links/wsLink/index.js +1 -1
- package/package.json +23 -30
- package/src/TRPCClientError.ts +5 -13
- package/src/createTRPCClient.ts +8 -3
- package/src/createTRPCClientProxy.ts +56 -0
- package/src/index.ts +2 -1
- package/src/internals/TRPCClient.ts +52 -36
- package/src/internals/dataLoader.ts +120 -45
- package/src/links/dedupeLink.test.ts +1 -1
- package/src/links/dedupeLink.ts +3 -5
- package/src/links/httpBatchLink.ts +64 -31
- package/src/links/httpLink.ts +4 -4
- package/src/links/index.ts +8 -0
- package/src/links/internals/createChain.test.ts +5 -5
- package/src/links/internals/createChain.ts +3 -3
- package/src/links/internals/httpUtils.ts +116 -0
- package/src/links/internals/transformOperationResult.ts +40 -12
- package/src/links/loggerLink.ts +1 -2
- package/src/links/retryLink.ts +1 -2
- package/src/links/splitLink.test.ts +3 -3
- package/src/links/splitLink.ts +5 -5
- package/src/links/types.ts +14 -9
- package/src/links/wsLink.ts +16 -14
- package/dist/TRPCClientError-17b117e1.mjs +0 -81
- package/dist/TRPCClientError-ec6bd2ca.js +0 -94
- package/dist/createChain-389cc116.mjs +0 -25
- package/dist/createChain-864dbb30.js +0 -27
- package/dist/internals/transformRPCResponse.d.ts +0 -15
- package/dist/internals/transformRPCResponse.d.ts.map +0 -1
- package/dist/links/httpUtils.d.ts +0 -22
- package/dist/links/httpUtils.d.ts.map +0 -1
- package/dist/links/transformerLink.d.ts +0 -4
- package/dist/links/transformerLink.d.ts.map +0 -1
- package/dist/links/transformerLink.js +0 -75
- package/dist/links/transformerLink.mjs +0 -67
- package/dist/links/transformerLink.ts.js +0 -1
- package/dist/observable-7e66cb56.mjs +0 -102
- package/dist/observable-85669100.js +0 -104
- package/dist/rx/index.d.ts +0 -3
- package/dist/rx/index.d.ts.map +0 -1
- package/dist/rx/index.js +0 -9
- package/dist/rx/index.mjs +0 -1
- package/dist/rx/index.ts.js +0 -1
- package/dist/rx/observable.d.ts +0 -4
- package/dist/rx/observable.d.ts.map +0 -1
- package/dist/rx/operators/index.d.ts +0 -4
- package/dist/rx/operators/index.d.ts.map +0 -1
- package/dist/rx/operators/index.js +0 -38
- package/dist/rx/operators/index.mjs +0 -32
- package/dist/rx/operators/index.ts.js +0 -1
- package/dist/rx/operators/map.d.ts +0 -3
- package/dist/rx/operators/map.d.ts.map +0 -1
- package/dist/rx/operators/share.d.ts +0 -6
- package/dist/rx/operators/share.d.ts.map +0 -1
- package/dist/rx/operators/tap.d.ts +0 -3
- package/dist/rx/operators/tap.d.ts.map +0 -1
- package/dist/rx/types.d.ts +0 -29
- package/dist/rx/types.d.ts.map +0 -1
- package/dist/rx/util/identity.d.ts +0 -2
- package/dist/rx/util/identity.d.ts.map +0 -1
- package/dist/rx/util/observableToPromise.d.ts +0 -10
- package/dist/rx/util/observableToPromise.d.ts.map +0 -1
- package/dist/rx/util/pipe.d.ts +0 -4
- package/dist/rx/util/pipe.d.ts.map +0 -1
- package/dist/share-4d79dc49.js +0 -110
- package/dist/share-671b63fa.mjs +0 -108
- package/dist/tap-538fa07f.mjs +0 -30
- package/dist/tap-799a2d33.js +0 -32
- package/links/transformerLink/dist/trpc-client-links-transformerLink.cjs.d.ts +0 -1
- package/links/transformerLink/dist/trpc-client-links-transformerLink.cjs.dev.js +0 -67
- package/links/transformerLink/dist/trpc-client-links-transformerLink.cjs.js +0 -7
- package/links/transformerLink/dist/trpc-client-links-transformerLink.cjs.prod.js +0 -67
- package/links/transformerLink/dist/trpc-client-links-transformerLink.esm.js +0 -63
- package/links/transformerLink/index.d.ts +0 -1
- package/links/transformerLink/index.js +0 -1
- package/rx/dist/trpc-client-rx.cjs.d.ts +0 -1
- package/rx/dist/trpc-client-rx.cjs.dev.js +0 -9
- package/rx/dist/trpc-client-rx.cjs.js +0 -7
- package/rx/dist/trpc-client-rx.cjs.prod.js +0 -9
- package/rx/dist/trpc-client-rx.esm.js +0 -1
- package/rx/index.d.ts +0 -1
- package/rx/index.js +0 -1
- package/rx/operators/dist/trpc-client-rx-operators.cjs.d.ts +0 -1
- package/rx/operators/dist/trpc-client-rx-operators.cjs.dev.js +0 -39
- package/rx/operators/dist/trpc-client-rx-operators.cjs.js +0 -7
- package/rx/operators/dist/trpc-client-rx-operators.cjs.prod.js +0 -39
- package/rx/operators/dist/trpc-client-rx-operators.esm.js +0 -33
- package/rx/operators/index.d.ts +0 -1
- package/rx/operators/index.js +0 -1
- package/src/internals/transformRPCResponse.ts +0 -25
- package/src/links/httpUtils.ts +0 -94
- package/src/links/transformerLink.ts +0 -70
- package/src/rx/index.ts +0 -2
- package/src/rx/observable.test.ts +0 -83
- package/src/rx/observable.ts +0 -70
- package/src/rx/operators/index.ts +0 -3
- package/src/rx/operators/map.test.ts +0 -92
- package/src/rx/operators/map.ts +0 -25
- package/src/rx/operators/share.test.ts +0 -60
- package/src/rx/operators/share.ts +0 -67
- package/src/rx/operators/tap.ts +0 -26
- package/src/rx/types.ts +0 -69
- package/src/rx/util/identity.ts +0 -3
- package/src/rx/util/observableToPromise.ts +0 -49
- package/src/rx/util/pipe.ts +0 -22
package/src/links/dedupeLink.ts
CHANGED
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
import { AnyRouter } from '@trpc/server';
|
|
2
|
-
import { observable } from '
|
|
3
|
-
import { share } from '../rx/operators';
|
|
4
|
-
import { Observable } from '../rx/types';
|
|
2
|
+
import { Observable, observable, share } from '@trpc/server/observable';
|
|
5
3
|
import { TRPCLink } from './types';
|
|
6
4
|
|
|
7
5
|
export function dedupeLink<
|
|
@@ -28,7 +26,7 @@ export function dedupeLink<
|
|
|
28
26
|
function reset() {
|
|
29
27
|
delete pending[key];
|
|
30
28
|
}
|
|
31
|
-
const
|
|
29
|
+
const subscription = next(op).subscribe({
|
|
32
30
|
next(v) {
|
|
33
31
|
observer.next(v);
|
|
34
32
|
},
|
|
@@ -43,7 +41,7 @@ export function dedupeLink<
|
|
|
43
41
|
});
|
|
44
42
|
return () => {
|
|
45
43
|
reset();
|
|
46
|
-
|
|
44
|
+
subscription.unsubscribe();
|
|
47
45
|
};
|
|
48
46
|
}).pipe(share());
|
|
49
47
|
pending[key] = shared$;
|
|
@@ -1,47 +1,80 @@
|
|
|
1
1
|
import { AnyRouter, ProcedureType } from '@trpc/server';
|
|
2
|
+
import { observable } from '@trpc/server/observable';
|
|
2
3
|
import { dataLoader } from '../internals/dataLoader';
|
|
3
|
-
import {
|
|
4
|
+
import {
|
|
5
|
+
HTTPLinkOptions,
|
|
6
|
+
ResponseShape,
|
|
7
|
+
getUrl,
|
|
8
|
+
httpRequest,
|
|
9
|
+
} from './internals/httpUtils';
|
|
4
10
|
import { TRPCLink } from './types';
|
|
5
|
-
|
|
11
|
+
|
|
12
|
+
export interface HttpBatchLinkOptions extends HTTPLinkOptions {
|
|
13
|
+
maxURLLength?: number;
|
|
14
|
+
}
|
|
6
15
|
|
|
7
16
|
export function httpBatchLink<TRouter extends AnyRouter>(
|
|
8
|
-
opts:
|
|
17
|
+
opts: HttpBatchLinkOptions,
|
|
9
18
|
): TRPCLink<TRouter> {
|
|
10
|
-
|
|
19
|
+
// initialized config
|
|
11
20
|
return (runtime) => {
|
|
12
|
-
type
|
|
13
|
-
const fetcher = (type: ProcedureType) => (keyInputPairs: Key[]) => {
|
|
14
|
-
const path = keyInputPairs.map((op) => op.path).join(',');
|
|
15
|
-
const inputs = keyInputPairs.map((op) => op.input);
|
|
21
|
+
type BatchOperation = { id: number; path: string; input: unknown };
|
|
16
22
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
23
|
+
const maxURLLength = opts.maxURLLength || Infinity;
|
|
24
|
+
|
|
25
|
+
const batchLoader = (type: ProcedureType) => {
|
|
26
|
+
const validate = (batchOps: BatchOperation[]) => {
|
|
27
|
+
if (maxURLLength === Infinity) {
|
|
28
|
+
// escape hatch for quick calcs
|
|
29
|
+
return true;
|
|
30
|
+
}
|
|
31
|
+
const path = batchOps.map((op) => op.path).join(',');
|
|
32
|
+
const inputs = batchOps.map((op) => op.input);
|
|
33
|
+
|
|
34
|
+
const url = getUrl({ url: opts.url, runtime, type, path, inputs });
|
|
35
|
+
return url.length <= maxURLLength;
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
const fetch = (batchOps: BatchOperation[]) => {
|
|
39
|
+
const path = batchOps.map((op) => op.path).join(',');
|
|
40
|
+
const inputs = batchOps.map((op) => op.input);
|
|
24
41
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
42
|
+
const { promise, cancel } = httpRequest({
|
|
43
|
+
url: opts.url,
|
|
44
|
+
runtime,
|
|
45
|
+
type,
|
|
46
|
+
path,
|
|
47
|
+
inputs,
|
|
48
|
+
});
|
|
30
49
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
json
|
|
34
|
-
|
|
50
|
+
return {
|
|
51
|
+
promise: promise.then((res) => {
|
|
52
|
+
const resJSON = Array.isArray(res.json)
|
|
53
|
+
? res.json
|
|
54
|
+
: batchOps.map(() => res.json);
|
|
35
55
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
56
|
+
const result = resJSON.map((item) => ({
|
|
57
|
+
meta: res.meta,
|
|
58
|
+
json: item,
|
|
59
|
+
}));
|
|
60
|
+
|
|
61
|
+
return result;
|
|
62
|
+
}),
|
|
63
|
+
cancel,
|
|
64
|
+
};
|
|
39
65
|
};
|
|
66
|
+
|
|
67
|
+
return { validate, fetch };
|
|
40
68
|
};
|
|
41
|
-
|
|
42
|
-
const
|
|
43
|
-
|
|
44
|
-
|
|
69
|
+
|
|
70
|
+
const query = dataLoader<BatchOperation, ResponseShape>(
|
|
71
|
+
batchLoader('query'),
|
|
72
|
+
);
|
|
73
|
+
const mutation = dataLoader<BatchOperation, ResponseShape>(
|
|
74
|
+
batchLoader('mutation'),
|
|
75
|
+
);
|
|
76
|
+
const subscription = dataLoader<BatchOperation, ResponseShape>(
|
|
77
|
+
batchLoader('subscription'),
|
|
45
78
|
);
|
|
46
79
|
|
|
47
80
|
const loaders = { query, subscription, mutation };
|
package/src/links/httpLink.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { AnyRouter } from '@trpc/server';
|
|
2
|
-
import { observable } from '
|
|
2
|
+
import { observable } from '@trpc/server/observable';
|
|
3
|
+
import { HTTPLinkOptions, httpRequest } from './internals/httpUtils';
|
|
3
4
|
import { TRPCLink } from './types';
|
|
4
|
-
import { HTTPLinkOptions, httpRequest } from './httpUtils';
|
|
5
5
|
|
|
6
6
|
export function httpLink<TRouter extends AnyRouter>(
|
|
7
7
|
opts: HTTPLinkOptions,
|
|
@@ -12,11 +12,11 @@ export function httpLink<TRouter extends AnyRouter>(
|
|
|
12
12
|
observable((observer) => {
|
|
13
13
|
const { path, input, type } = op;
|
|
14
14
|
const { promise, cancel } = httpRequest({
|
|
15
|
+
url,
|
|
15
16
|
runtime,
|
|
17
|
+
type,
|
|
16
18
|
path,
|
|
17
19
|
input,
|
|
18
|
-
type,
|
|
19
|
-
url,
|
|
20
20
|
});
|
|
21
21
|
promise
|
|
22
22
|
.then((res) => {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
+
import { observable } from '@trpc/server/observable';
|
|
1
2
|
import { AnyRouter } from '@trpc/server/src';
|
|
2
3
|
import { createChain } from './createChain';
|
|
3
|
-
import { observable } from '../../rx/observable';
|
|
4
4
|
|
|
5
5
|
describe('chain', () => {
|
|
6
6
|
test('trivial', () => {
|
|
@@ -8,9 +8,9 @@ describe('chain', () => {
|
|
|
8
8
|
links: [
|
|
9
9
|
({ next, op }) => {
|
|
10
10
|
return observable((observer) => {
|
|
11
|
-
const
|
|
11
|
+
const subscription = next(op).subscribe(observer);
|
|
12
12
|
return () => {
|
|
13
|
-
|
|
13
|
+
subscription.unsubscribe();
|
|
14
14
|
};
|
|
15
15
|
});
|
|
16
16
|
},
|
|
@@ -62,9 +62,9 @@ describe('chain', () => {
|
|
|
62
62
|
},
|
|
63
63
|
},
|
|
64
64
|
});
|
|
65
|
-
const
|
|
65
|
+
const subscription = next(op).subscribe(observer);
|
|
66
66
|
return () => {
|
|
67
|
-
|
|
67
|
+
subscription.unsubscribe();
|
|
68
68
|
};
|
|
69
69
|
});
|
|
70
70
|
},
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { AnyRouter } from '@trpc/server';
|
|
2
|
-
import { observable } from '
|
|
2
|
+
import { observable } from '@trpc/server/observable';
|
|
3
3
|
import { Operation, OperationLink, OperationResultObservable } from '../types';
|
|
4
4
|
|
|
5
5
|
/** @internal */
|
|
@@ -14,7 +14,7 @@ export function createChain<
|
|
|
14
14
|
return observable((observer) => {
|
|
15
15
|
function execute(index = 0, op = opts.op) {
|
|
16
16
|
const next = opts.links[index];
|
|
17
|
-
const
|
|
17
|
+
const subscription = next({
|
|
18
18
|
op,
|
|
19
19
|
next(nextOp) {
|
|
20
20
|
const nextObserver = execute(index + 1, nextOp);
|
|
@@ -22,7 +22,7 @@ export function createChain<
|
|
|
22
22
|
return nextObserver;
|
|
23
23
|
},
|
|
24
24
|
});
|
|
25
|
-
return
|
|
25
|
+
return subscription;
|
|
26
26
|
}
|
|
27
27
|
|
|
28
28
|
const obs$ = execute();
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import { ProcedureType } from '@trpc/server';
|
|
2
|
+
import { PromiseAndCancel, TRPCClientRuntime } from '../types';
|
|
3
|
+
|
|
4
|
+
export interface HTTPLinkOptions {
|
|
5
|
+
url: string;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
// https://github.com/trpc/trpc/pull/669
|
|
9
|
+
function arrayToDict(array: unknown[]) {
|
|
10
|
+
const dict: Record<number, unknown> = {};
|
|
11
|
+
for (let index = 0; index < array.length; index++) {
|
|
12
|
+
const element = array[index];
|
|
13
|
+
dict[index] = element;
|
|
14
|
+
}
|
|
15
|
+
return dict;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const METHOD = {
|
|
19
|
+
query: 'GET',
|
|
20
|
+
mutation: 'POST',
|
|
21
|
+
subscription: 'PATCH',
|
|
22
|
+
} as const;
|
|
23
|
+
|
|
24
|
+
export interface ResponseShape {
|
|
25
|
+
json: unknown;
|
|
26
|
+
meta: {
|
|
27
|
+
response: Response;
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
type GetInputOptions = {
|
|
32
|
+
runtime: TRPCClientRuntime;
|
|
33
|
+
} & ({ inputs: unknown[] } | { input: unknown });
|
|
34
|
+
|
|
35
|
+
function getInput(opts: GetInputOptions) {
|
|
36
|
+
return 'input' in opts
|
|
37
|
+
? opts.runtime.transformer.serialize(opts.input)
|
|
38
|
+
: arrayToDict(
|
|
39
|
+
opts.inputs.map((_input) => opts.runtime.transformer.serialize(_input)),
|
|
40
|
+
);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export type HTTPRequestOptions = HTTPLinkOptions &
|
|
44
|
+
GetInputOptions & {
|
|
45
|
+
type: ProcedureType;
|
|
46
|
+
path: string;
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
export function getUrl(opts: HTTPRequestOptions) {
|
|
50
|
+
let url = opts.url + '/' + opts.path;
|
|
51
|
+
const queryParts: string[] = [];
|
|
52
|
+
if ('inputs' in opts) {
|
|
53
|
+
queryParts.push('batch=1');
|
|
54
|
+
}
|
|
55
|
+
if (opts.type === 'query') {
|
|
56
|
+
const input = getInput(opts);
|
|
57
|
+
if (input !== undefined) {
|
|
58
|
+
queryParts.push(`input=${encodeURIComponent(JSON.stringify(input))}`);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
if (queryParts.length) {
|
|
62
|
+
url += '?' + queryParts.join('&');
|
|
63
|
+
}
|
|
64
|
+
return url;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
type GetBodyOptions = { type: ProcedureType } & GetInputOptions;
|
|
68
|
+
|
|
69
|
+
export function getBody(opts: GetBodyOptions) {
|
|
70
|
+
if (opts.type === 'query') {
|
|
71
|
+
return undefined;
|
|
72
|
+
}
|
|
73
|
+
const input = getInput(opts);
|
|
74
|
+
return input !== undefined ? JSON.stringify(input) : undefined;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
export function httpRequest(
|
|
78
|
+
opts: HTTPRequestOptions,
|
|
79
|
+
): PromiseAndCancel<ResponseShape> {
|
|
80
|
+
const { type, runtime } = opts;
|
|
81
|
+
const ac = runtime.AbortController ? new runtime.AbortController() : null;
|
|
82
|
+
|
|
83
|
+
const promise = new Promise<ResponseShape>((resolve, reject) => {
|
|
84
|
+
const url = getUrl(opts);
|
|
85
|
+
const body = getBody(opts);
|
|
86
|
+
|
|
87
|
+
const meta = {} as any as ResponseShape['meta'];
|
|
88
|
+
Promise.resolve(runtime.headers())
|
|
89
|
+
.then((headers) =>
|
|
90
|
+
runtime.fetch(url, {
|
|
91
|
+
method: METHOD[type],
|
|
92
|
+
signal: ac?.signal,
|
|
93
|
+
body: body,
|
|
94
|
+
headers: {
|
|
95
|
+
'content-type': 'application/json',
|
|
96
|
+
...headers,
|
|
97
|
+
},
|
|
98
|
+
}),
|
|
99
|
+
)
|
|
100
|
+
.then((_res) => {
|
|
101
|
+
meta.response = _res;
|
|
102
|
+
return _res.json();
|
|
103
|
+
})
|
|
104
|
+
.then((json) => {
|
|
105
|
+
resolve({
|
|
106
|
+
json,
|
|
107
|
+
meta,
|
|
108
|
+
});
|
|
109
|
+
})
|
|
110
|
+
.catch(reject);
|
|
111
|
+
});
|
|
112
|
+
const cancel = () => {
|
|
113
|
+
ac?.abort();
|
|
114
|
+
};
|
|
115
|
+
return { promise, cancel };
|
|
116
|
+
}
|
|
@@ -1,25 +1,53 @@
|
|
|
1
1
|
import { AnyRouter } from '@trpc/server';
|
|
2
|
+
import { TRPCResultMessage } from '@trpc/server/rpc';
|
|
3
|
+
import { TRPCClientRuntime } from '..';
|
|
2
4
|
import { TRPCClientError } from '../../TRPCClientError';
|
|
3
5
|
import { OperationResult } from '../types';
|
|
4
6
|
|
|
5
7
|
/** @internal */
|
|
6
8
|
export function transformOperationResult<TRouter extends AnyRouter, TOutput>(
|
|
7
9
|
result: OperationResult<TRouter, TOutput>,
|
|
10
|
+
runtime: TRPCClientRuntime,
|
|
8
11
|
) {
|
|
9
12
|
const { context } = result;
|
|
10
13
|
|
|
11
14
|
if ('error' in result.data) {
|
|
12
|
-
const error = TRPCClientError.from<TRouter>(
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
} as const;
|
|
15
|
+
const error = TRPCClientError.from<TRouter>({
|
|
16
|
+
...result.data,
|
|
17
|
+
error: runtime.transformer.deserialize(result.data.error),
|
|
18
|
+
});
|
|
19
|
+
return { ok: false, error, context } as const;
|
|
18
20
|
}
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
21
|
+
|
|
22
|
+
const data = runtime.transformer.deserialize(
|
|
23
|
+
(result.data.result as any).data,
|
|
24
|
+
) as TOutput;
|
|
25
|
+
return { ok: true, data, context } as const;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/** @internal */
|
|
29
|
+
export function transformSubscriptionOperationResult<
|
|
30
|
+
TRouter extends AnyRouter,
|
|
31
|
+
TOutput,
|
|
32
|
+
>(result: OperationResult<TRouter, TOutput>, runtime: TRPCClientRuntime) {
|
|
33
|
+
const { context } = result;
|
|
34
|
+
|
|
35
|
+
if ('error' in result.data) {
|
|
36
|
+
const error = TRPCClientError.from<TRouter>(
|
|
37
|
+
{
|
|
38
|
+
...result.data,
|
|
39
|
+
error: runtime.transformer.deserialize(result.data.error),
|
|
40
|
+
},
|
|
41
|
+
{ meta: context },
|
|
42
|
+
);
|
|
43
|
+
return { ok: false, error, context } as const;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const data = {
|
|
47
|
+
...result.data.result,
|
|
48
|
+
...((result.data.result as any).type === 'data' && {
|
|
49
|
+
data: runtime.transformer.deserialize((result.data.result as any).data),
|
|
50
|
+
}),
|
|
51
|
+
} as TRPCResultMessage<TOutput>;
|
|
52
|
+
return { ok: true, data, context } as const;
|
|
25
53
|
}
|
package/src/links/loggerLink.ts
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { AnyRouter } from '@trpc/server';
|
|
2
|
+
import { observable, tap } from '@trpc/server/observable';
|
|
2
3
|
import { TRPCClientError } from '..';
|
|
3
|
-
import { observable } from '../rx/observable';
|
|
4
|
-
import { tap } from '../rx/operators';
|
|
5
4
|
import { Operation, OperationResult, TRPCLink } from './types';
|
|
6
5
|
|
|
7
6
|
type ConsoleEsque = {
|
package/src/links/retryLink.ts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { AnyRouter } from '@trpc/server';
|
|
2
|
-
import { observable } from '
|
|
3
|
-
import { Unsubscribable } from '../rx/types';
|
|
2
|
+
import { Unsubscribable, observable } from '@trpc/server/observable';
|
|
4
3
|
import { TRPCLink } from './types';
|
|
5
4
|
|
|
6
5
|
export function retryLink<TRouter extends AnyRouter = AnyRouter>(opts: {
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
/* eslint-disable @typescript-eslint/no-empty-function */
|
|
2
|
+
import { observable } from '@trpc/server/observable';
|
|
3
|
+
import { splitLink } from '../';
|
|
4
|
+
import { OperationLink, TRPCLink } from '../';
|
|
2
5
|
import { AnyRouter } from '../../../server/src';
|
|
3
6
|
import { createChain } from '../links/internals/createChain';
|
|
4
|
-
import { splitLink } from '../links/splitLink';
|
|
5
|
-
import { OperationLink, TRPCLink } from '../links/types';
|
|
6
|
-
import { observable } from '../rx';
|
|
7
7
|
|
|
8
8
|
test('splitLink', () => {
|
|
9
9
|
const wsLinkSpy = jest.fn();
|
package/src/links/splitLink.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { AnyRouter } from '@trpc/server';
|
|
2
|
-
import { observable } from '
|
|
3
|
-
import { TRPCLink, Operation } from './types';
|
|
2
|
+
import { observable } from '@trpc/server/observable';
|
|
4
3
|
import { createChain } from './internals/createChain';
|
|
4
|
+
import { Operation, TRPCLink } from './types';
|
|
5
5
|
|
|
6
6
|
function asArray<T>(value: T | T[]) {
|
|
7
7
|
return Array.isArray(value) ? value : [value];
|
|
@@ -17,9 +17,9 @@ export function splitLink<TRouter extends AnyRouter = AnyRouter>(opts: {
|
|
|
17
17
|
*/
|
|
18
18
|
false: TRPCLink<TRouter> | TRPCLink<TRouter>[];
|
|
19
19
|
}): TRPCLink<TRouter> {
|
|
20
|
-
return (
|
|
21
|
-
const yes = asArray(opts.true).map((link) => link(
|
|
22
|
-
const no = asArray(opts.false).map((link) => link(
|
|
20
|
+
return (runtime) => {
|
|
21
|
+
const yes = asArray(opts.true).map((link) => link(runtime));
|
|
22
|
+
const no = asArray(opts.false).map((link) => link(runtime));
|
|
23
23
|
return (props) => {
|
|
24
24
|
return observable((observer) => {
|
|
25
25
|
const links = opts.condition(props.op) ? yes : no;
|
package/src/links/types.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { AnyRouter,
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
1
|
+
import { AnyRouter, DataTransformer, inferRouterError } from '@trpc/server';
|
|
2
|
+
import { Observable, Observer } from '@trpc/server/observable';
|
|
3
|
+
import { TRPCResponse, TRPCResponseMessage } from '@trpc/server/rpc';
|
|
4
4
|
import { TRPCClientError } from '../TRPCClientError';
|
|
5
5
|
|
|
6
6
|
export type CancelFn = () => void;
|
|
@@ -16,10 +16,10 @@ export type Operation<TInput = unknown> = {
|
|
|
16
16
|
type: 'query' | 'mutation' | 'subscription';
|
|
17
17
|
input: TInput;
|
|
18
18
|
path: string;
|
|
19
|
-
context
|
|
19
|
+
context: OperationContext;
|
|
20
20
|
};
|
|
21
21
|
|
|
22
|
-
export type HTTPHeaders =
|
|
22
|
+
export type HTTPHeaders = Record<string, string | string[]>;
|
|
23
23
|
|
|
24
24
|
/**
|
|
25
25
|
* The default `fetch` implementation has an overloaded signature. By convention this library
|
|
@@ -30,14 +30,19 @@ export type TRPCFetch = (
|
|
|
30
30
|
options?: RequestInit,
|
|
31
31
|
) => Promise<Response>;
|
|
32
32
|
|
|
33
|
-
export interface
|
|
34
|
-
headers: () => HTTPHeaders | Promise<HTTPHeaders>;
|
|
33
|
+
export interface TRPCClientRuntime {
|
|
35
34
|
fetch: TRPCFetch;
|
|
36
35
|
AbortController?: typeof AbortController;
|
|
36
|
+
headers: () => HTTPHeaders | Promise<HTTPHeaders>;
|
|
37
|
+
transformer: DataTransformer;
|
|
37
38
|
}
|
|
38
39
|
|
|
40
|
+
type OperationResultData<TRouter extends AnyRouter, TOutput> =
|
|
41
|
+
| TRPCResponse<TOutput, inferRouterError<TRouter>>
|
|
42
|
+
| TRPCResponseMessage<TOutput, inferRouterError<TRouter>>;
|
|
43
|
+
|
|
39
44
|
export interface OperationResult<TRouter extends AnyRouter, TOutput> {
|
|
40
|
-
data:
|
|
45
|
+
data: OperationResultData<TRouter, TOutput>;
|
|
41
46
|
context?: OperationContext;
|
|
42
47
|
}
|
|
43
48
|
|
|
@@ -61,5 +66,5 @@ export type OperationLink<
|
|
|
61
66
|
}) => OperationResultObservable<TRouter, TOutput>;
|
|
62
67
|
|
|
63
68
|
export type TRPCLink<TRouter extends AnyRouter> = (
|
|
64
|
-
opts:
|
|
69
|
+
opts: TRPCClientRuntime,
|
|
65
70
|
) => OperationLink<TRouter>;
|
package/src/links/wsLink.ts
CHANGED
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
import { AnyRouter, ProcedureType } from '@trpc/server';
|
|
2
|
+
import { UnsubscribeFn, observable } from '@trpc/server/observable';
|
|
2
3
|
import {
|
|
3
4
|
TRPCClientIncomingMessage,
|
|
4
5
|
TRPCClientIncomingRequest,
|
|
5
|
-
|
|
6
|
-
|
|
6
|
+
TRPCClientOutgoingMessage,
|
|
7
|
+
TRPCRequestMessage,
|
|
8
|
+
TRPCResponseMessage,
|
|
7
9
|
} from '@trpc/server/rpc';
|
|
8
|
-
import { retryDelay } from '../internals/retryDelay';
|
|
9
|
-
import { UnsubscribeFn } from '../rx';
|
|
10
|
-
import { observable } from '../rx/observable';
|
|
11
10
|
import { TRPCClientError } from '../TRPCClientError';
|
|
11
|
+
import { retryDelay } from '../internals/retryDelay';
|
|
12
12
|
import { Operation, OperationResultObserver, TRPCLink } from './types';
|
|
13
13
|
|
|
14
14
|
export interface WebSocketClientOptions {
|
|
15
15
|
url: string;
|
|
16
|
-
WebSocket?: WebSocket;
|
|
16
|
+
WebSocket?: typeof WebSocket;
|
|
17
17
|
retryDelayMs?: typeof retryDelay;
|
|
18
18
|
}
|
|
19
19
|
export function createWSClient(opts: WebSocketClientOptions) {
|
|
@@ -31,7 +31,7 @@ export function createWSClient(opts: WebSocketClientOptions) {
|
|
|
31
31
|
/**
|
|
32
32
|
* outgoing messages buffer whilst not open
|
|
33
33
|
*/
|
|
34
|
-
let outgoing:
|
|
34
|
+
let outgoing: TRPCClientOutgoingMessage[] = [];
|
|
35
35
|
/**
|
|
36
36
|
* pending outgoing requests that are awaiting callback
|
|
37
37
|
*/
|
|
@@ -112,7 +112,7 @@ export function createWSClient(opts: WebSocketClientOptions) {
|
|
|
112
112
|
}
|
|
113
113
|
|
|
114
114
|
function createWS() {
|
|
115
|
-
const conn = new
|
|
115
|
+
const conn = new WebSocketImpl(url);
|
|
116
116
|
clearTimeout(connectTimer as any);
|
|
117
117
|
connectTimer = null;
|
|
118
118
|
|
|
@@ -141,7 +141,7 @@ export function createWSClient(opts: WebSocketClientOptions) {
|
|
|
141
141
|
}
|
|
142
142
|
}
|
|
143
143
|
};
|
|
144
|
-
const handleIncomingResponse = (data:
|
|
144
|
+
const handleIncomingResponse = (data: TRPCResponseMessage) => {
|
|
145
145
|
const req = data.id !== null && pendingRequests[data.id];
|
|
146
146
|
if (!req) {
|
|
147
147
|
// do something?
|
|
@@ -208,9 +208,8 @@ export function createWSClient(opts: WebSocketClientOptions) {
|
|
|
208
208
|
|
|
209
209
|
function request(op: Operation, callbacks: TCallbacks): UnsubscribeFn {
|
|
210
210
|
const { type, input, path, id } = op;
|
|
211
|
-
const envelope:
|
|
211
|
+
const envelope: TRPCRequestMessage = {
|
|
212
212
|
id,
|
|
213
|
-
jsonrpc: '2.0',
|
|
214
213
|
method: type,
|
|
215
214
|
params: {
|
|
216
215
|
input,
|
|
@@ -238,7 +237,6 @@ export function createWSClient(opts: WebSocketClientOptions) {
|
|
|
238
237
|
outgoing.push({
|
|
239
238
|
id,
|
|
240
239
|
method: 'subscription.stop',
|
|
241
|
-
params: undefined,
|
|
242
240
|
});
|
|
243
241
|
dispatch();
|
|
244
242
|
}
|
|
@@ -248,6 +246,8 @@ export function createWSClient(opts: WebSocketClientOptions) {
|
|
|
248
246
|
close: () => {
|
|
249
247
|
state = 'closed';
|
|
250
248
|
closeIfNoPending(activeConnection);
|
|
249
|
+
clearTimeout(connectTimer as any);
|
|
250
|
+
connectTimer = null;
|
|
251
251
|
},
|
|
252
252
|
request,
|
|
253
253
|
getConnection() {
|
|
@@ -279,11 +279,13 @@ class TRPCSubscriptionEndedError extends Error {
|
|
|
279
279
|
export function wsLink<TRouter extends AnyRouter>(
|
|
280
280
|
opts: WebSocketLinkOptions,
|
|
281
281
|
): TRPCLink<TRouter> {
|
|
282
|
-
return () => {
|
|
282
|
+
return (runtime) => {
|
|
283
283
|
const { client } = opts;
|
|
284
284
|
return ({ op }) => {
|
|
285
285
|
return observable((observer) => {
|
|
286
|
-
const { type,
|
|
286
|
+
const { type, path, id, context } = op;
|
|
287
|
+
|
|
288
|
+
const input = runtime.transformer.serialize(op.input);
|
|
287
289
|
|
|
288
290
|
let isDone = false;
|
|
289
291
|
const unsub = client.request(
|