@trpc/server 10.0.0-alpha.21 → 10.0.0-alpha.22
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/adapters/express/dist/trpc-server-adapters-express.cjs.dev.js +3 -3
- package/adapters/express/dist/trpc-server-adapters-express.cjs.prod.js +3 -3
- package/adapters/express/dist/trpc-server-adapters-express.esm.js +3 -3
- package/adapters/fastify/dist/trpc-server-adapters-fastify.cjs.dev.js +2 -2
- package/adapters/fastify/dist/trpc-server-adapters-fastify.cjs.prod.js +2 -2
- package/adapters/fastify/dist/trpc-server-adapters-fastify.esm.js +2 -2
- package/adapters/fastify/index.js +1 -1
- package/adapters/fetch/index.d.ts +1 -0
- package/adapters/fetch/index.js +1 -0
- package/adapters/next/dist/trpc-server-adapters-next.cjs.dev.js +3 -3
- package/adapters/next/dist/trpc-server-adapters-next.cjs.prod.js +3 -3
- package/adapters/next/dist/trpc-server-adapters-next.esm.js +3 -3
- package/adapters/node-http/dist/trpc-server-adapters-node-http.cjs.dev.js +3 -3
- package/adapters/node-http/dist/trpc-server-adapters-node-http.cjs.prod.js +3 -3
- package/adapters/node-http/dist/trpc-server-adapters-node-http.esm.js +3 -3
- package/adapters/standalone/dist/trpc-server-adapters-standalone.cjs.dev.js +3 -3
- package/adapters/standalone/dist/trpc-server-adapters-standalone.cjs.prod.js +3 -3
- package/adapters/standalone/dist/trpc-server-adapters-standalone.esm.js +3 -3
- package/dist/{transformTRPCResponse-9fdeecca.mjs → TRPCError-7971540a.mjs} +1 -53
- package/dist/{transformTRPCResponse-a57d3226.js → TRPCError-ddec3395.js} +0 -54
- package/dist/adapters/express.js +5 -4
- package/dist/adapters/express.mjs +5 -4
- package/dist/adapters/fastify/index.js +5 -5
- package/dist/adapters/fastify/index.mjs +5 -5
- package/dist/adapters/fetch/fetchRequestHandler.d.ts +8 -0
- package/dist/adapters/fetch/fetchRequestHandler.d.ts.map +1 -0
- package/dist/adapters/fetch/index.d.ts +3 -0
- package/dist/adapters/fetch/index.d.ts.map +1 -0
- package/dist/adapters/fetch/index.js +69 -0
- package/dist/adapters/fetch/index.mjs +65 -0
- package/dist/adapters/fetch/index.ts.js +1 -0
- package/dist/adapters/fetch/types.d.ts +21 -0
- package/dist/adapters/fetch/types.d.ts.map +1 -0
- package/dist/adapters/next.d.ts.map +1 -1
- package/dist/adapters/next.js +9 -9
- package/dist/adapters/next.mjs +8 -8
- package/dist/adapters/node-http/index.js +5 -4
- package/dist/adapters/node-http/index.mjs +5 -4
- package/dist/adapters/node-http/types.d.ts +1 -2
- package/dist/adapters/node-http/types.d.ts.map +1 -1
- package/dist/adapters/standalone.js +5 -4
- package/dist/adapters/standalone.mjs +5 -4
- package/dist/adapters/ws.d.ts.map +1 -1
- package/dist/adapters/ws.js +117 -80
- package/dist/adapters/ws.mjs +111 -74
- package/dist/{codes-6c13cf43.mjs → envelopes-1deb2fa7.mjs} +17 -1
- package/dist/{codes-4e4d55a9.js → envelopes-a953b930.js} +16 -0
- package/dist/http/resolveHTTPResponse.d.ts.map +1 -1
- package/dist/index.d.ts +0 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +37 -51
- package/dist/index.mjs +30 -42
- package/dist/internals/callProcedure.d.ts +2 -2
- package/dist/internals/callProcedure.d.ts.map +1 -1
- package/dist/internals/procedure.d.ts +4 -3
- package/dist/internals/procedure.d.ts.map +1 -1
- package/dist/internals/transformTRPCResponse.d.ts +4 -2
- package/dist/internals/transformTRPCResponse.d.ts.map +1 -1
- package/dist/{nodeHTTPRequestHandler-13c4bded.mjs → nodeHTTPRequestHandler-1cdb6383.mjs} +2 -2
- package/dist/{nodeHTTPRequestHandler-745e43e5.js → nodeHTTPRequestHandler-848f07b5.js} +3 -3
- package/dist/observable/index.d.ts +5 -0
- package/dist/observable/index.d.ts.map +1 -0
- package/dist/observable/index.js +204 -0
- package/dist/observable/index.mjs +195 -0
- package/dist/observable/index.ts.js +1 -0
- package/dist/observable/internals/identity.d.ts +2 -0
- package/dist/observable/internals/identity.d.ts.map +1 -0
- package/dist/observable/internals/observableToPromise.d.ts +10 -0
- package/dist/observable/internals/observableToPromise.d.ts.map +1 -0
- package/dist/observable/internals/pipe.d.ts +4 -0
- package/dist/observable/internals/pipe.d.ts.map +1 -0
- package/dist/observable/observable.d.ts +5 -0
- package/dist/observable/observable.d.ts.map +1 -0
- package/dist/observable/operators/index.d.ts +4 -0
- package/dist/observable/operators/index.d.ts.map +1 -0
- package/dist/observable/operators/map.d.ts +3 -0
- package/dist/observable/operators/map.d.ts.map +1 -0
- package/dist/observable/operators/share.d.ts +6 -0
- package/dist/observable/operators/share.d.ts.map +1 -0
- package/dist/observable/operators/tap.d.ts +3 -0
- package/dist/observable/operators/tap.d.ts.map +1 -0
- package/dist/observable/types.d.ts +29 -0
- package/dist/observable/types.d.ts.map +1 -0
- package/dist/observable-137ea1bd.mjs +105 -0
- package/dist/observable-3aa4d911.js +108 -0
- package/dist/{resolveHTTPResponse-de40fda7.mjs → resolveHTTPResponse-54a79e6c.mjs} +14 -20
- package/dist/{resolveHTTPResponse-b1167b6a.js → resolveHTTPResponse-ec3dccaa.js} +21 -27
- package/dist/router.d.ts +6 -6
- package/dist/router.d.ts.map +1 -1
- package/dist/rpc/envelopes.d.ts +61 -39
- package/dist/rpc/envelopes.d.ts.map +1 -1
- package/dist/rpc/index.js +7 -3
- package/dist/rpc/index.mjs +1 -1
- package/dist/subscription.d.ts +3 -52
- package/dist/subscription.d.ts.map +1 -1
- package/dist/subscription.js +44 -0
- package/dist/subscription.mjs +40 -0
- package/dist/subscription.ts.js +1 -0
- package/dist/transformTRPCResponse-333bed6c.js +56 -0
- package/dist/transformTRPCResponse-e0cba527.mjs +53 -0
- package/dist/types.d.ts +8 -0
- package/dist/types.d.ts.map +1 -1
- package/observable/index.d.ts +1 -0
- package/observable/index.js +1 -0
- package/package.json +24 -7
- package/rpc/dist/trpc-server-rpc.cjs.dev.js +1 -1
- package/rpc/dist/trpc-server-rpc.cjs.prod.js +1 -1
- package/rpc/dist/trpc-server-rpc.esm.js +1 -1
- package/src/adapters/fetch/fetchRequestHandler.ts +61 -0
- package/src/adapters/fetch/index.ts +2 -0
- package/src/adapters/fetch/types.ts +28 -0
- package/src/adapters/next.ts +3 -5
- package/src/adapters/node-http/types.ts +1 -2
- package/src/adapters/ws.ts +109 -71
- package/src/http/resolveHTTPResponse.ts +16 -20
- package/src/index.ts +0 -1
- package/src/internals/callProcedure.ts +6 -3
- package/src/internals/procedure.ts +40 -27
- package/src/internals/transformTRPCResponse.ts +20 -15
- package/src/observable/index.ts +4 -0
- package/src/observable/internals/identity.ts +3 -0
- package/src/observable/internals/observableToPromise.ts +49 -0
- package/src/observable/internals/pipe.ts +22 -0
- package/src/observable/observable.test.ts +101 -0
- package/src/observable/observable.ts +75 -0
- package/src/observable/operators/index.ts +3 -0
- package/src/observable/operators/map.test.ts +92 -0
- package/src/observable/operators/map.ts +25 -0
- package/src/observable/operators/share.test.ts +60 -0
- package/src/observable/operators/share.ts +67 -0
- package/src/observable/operators/tap.ts +26 -0
- package/src/observable/types.ts +69 -0
- package/src/router.ts +7 -9
- package/src/rpc/envelopes.ts +87 -68
- package/src/subscription.ts +5 -123
- package/src/types.ts +7 -0
- package/dist/internals/wrapCallSafe.d.ts +0 -16
- package/dist/internals/wrapCallSafe.d.ts.map +0 -1
- package/dist/subscription-4b936ba3.js +0 -136
- package/dist/subscription-8a85f253.mjs +0 -133
- package/src/internals/wrapCallSafe.ts +0 -19
- package/ws/dist/trpc-server-ws.cjs.d.ts +0 -1
- package/ws/dist/trpc-server-ws.cjs.dev.js +0 -15
- package/ws/dist/trpc-server-ws.cjs.js +0 -7
- package/ws/dist/trpc-server-ws.cjs.prod.js +0 -15
- package/ws/dist/trpc-server-ws.esm.js +0 -11
- package/ws/index.d.ts +0 -1
- package/ws/index.js +0 -1
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-empty-function */
|
|
2
|
+
import { observable, share, tap } from '.';
|
|
3
|
+
|
|
4
|
+
test('vanilla observable - complete()', () => {
|
|
5
|
+
const obs = observable<number, Error>((observer) => {
|
|
6
|
+
observer.next(1);
|
|
7
|
+
observer.complete();
|
|
8
|
+
});
|
|
9
|
+
|
|
10
|
+
const next = jest.fn();
|
|
11
|
+
const error = jest.fn();
|
|
12
|
+
const complete = jest.fn();
|
|
13
|
+
obs.subscribe({
|
|
14
|
+
next,
|
|
15
|
+
error,
|
|
16
|
+
complete,
|
|
17
|
+
});
|
|
18
|
+
expect(next.mock.calls).toHaveLength(1);
|
|
19
|
+
expect(complete.mock.calls).toHaveLength(1);
|
|
20
|
+
expect(error.mock.calls).toHaveLength(0);
|
|
21
|
+
expect(next.mock.calls[0][0]).toBe(1);
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
test('vanilla observable - unsubscribe()', () => {
|
|
25
|
+
const obs$ = observable<number, Error>((observer) => {
|
|
26
|
+
observer.next(1);
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
const next = jest.fn();
|
|
30
|
+
const error = jest.fn();
|
|
31
|
+
const complete = jest.fn();
|
|
32
|
+
const sub = obs$.subscribe({
|
|
33
|
+
next,
|
|
34
|
+
error,
|
|
35
|
+
complete,
|
|
36
|
+
});
|
|
37
|
+
sub.unsubscribe();
|
|
38
|
+
expect(next.mock.calls).toHaveLength(1);
|
|
39
|
+
expect(complete.mock.calls).toHaveLength(0);
|
|
40
|
+
expect(error.mock.calls).toHaveLength(0);
|
|
41
|
+
expect(next.mock.calls[0][0]).toBe(1);
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
test('pipe - combine operators', () => {
|
|
45
|
+
const taps = {
|
|
46
|
+
next: jest.fn(),
|
|
47
|
+
complete: jest.fn(),
|
|
48
|
+
error: jest.fn(),
|
|
49
|
+
};
|
|
50
|
+
const obs = observable<number, Error>((observer) => {
|
|
51
|
+
observer.next(1);
|
|
52
|
+
}).pipe(
|
|
53
|
+
// operators:
|
|
54
|
+
share(),
|
|
55
|
+
tap(taps),
|
|
56
|
+
);
|
|
57
|
+
{
|
|
58
|
+
const next = jest.fn();
|
|
59
|
+
const error = jest.fn();
|
|
60
|
+
const complete = jest.fn();
|
|
61
|
+
obs.subscribe({
|
|
62
|
+
next,
|
|
63
|
+
error,
|
|
64
|
+
complete,
|
|
65
|
+
});
|
|
66
|
+
expect(next.mock.calls).toHaveLength(1);
|
|
67
|
+
expect(complete.mock.calls).toHaveLength(0);
|
|
68
|
+
expect(error.mock.calls).toHaveLength(0);
|
|
69
|
+
expect(next.mock.calls[0][0]).toBe(1);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
{
|
|
73
|
+
const next = jest.fn();
|
|
74
|
+
const error = jest.fn();
|
|
75
|
+
const complete = jest.fn();
|
|
76
|
+
obs.subscribe({
|
|
77
|
+
next,
|
|
78
|
+
error,
|
|
79
|
+
complete,
|
|
80
|
+
});
|
|
81
|
+
expect(next.mock.calls).toHaveLength(0);
|
|
82
|
+
expect(complete.mock.calls).toHaveLength(0);
|
|
83
|
+
expect(error.mock.calls).toHaveLength(0);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
expect({
|
|
87
|
+
next: taps.next.mock.calls,
|
|
88
|
+
error: taps.error.mock.calls,
|
|
89
|
+
complete: taps.complete.mock.calls,
|
|
90
|
+
}).toMatchInlineSnapshot(`
|
|
91
|
+
Object {
|
|
92
|
+
"complete": Array [],
|
|
93
|
+
"error": Array [],
|
|
94
|
+
"next": Array [
|
|
95
|
+
Array [
|
|
96
|
+
1,
|
|
97
|
+
],
|
|
98
|
+
],
|
|
99
|
+
}
|
|
100
|
+
`);
|
|
101
|
+
});
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { pipeFromArray } from './internals/pipe';
|
|
2
|
+
import { Observable, Observer, OperatorFunction, TeardownLogic } from './types';
|
|
3
|
+
|
|
4
|
+
export type inferObservableValue<
|
|
5
|
+
TObservable extends Observable<unknown, unknown>,
|
|
6
|
+
> = TObservable extends Observable<infer TValue, unknown> ? TValue : never;
|
|
7
|
+
|
|
8
|
+
export function isObservable(x: unknown): x is Observable<unknown, unknown> {
|
|
9
|
+
return typeof x === 'object' && x !== null && 'subscribe' in x;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export function observable<TValue, TError = unknown>(
|
|
13
|
+
subscribe: (observer: Observer<TValue, TError>) => TeardownLogic,
|
|
14
|
+
): Observable<TValue, TError> {
|
|
15
|
+
const self: Observable<TValue, TError> = {
|
|
16
|
+
subscribe(observer) {
|
|
17
|
+
let teardownRef: TeardownLogic | null = null;
|
|
18
|
+
let isDone = false;
|
|
19
|
+
let unsubscribed = false;
|
|
20
|
+
let teardownImmediately = false;
|
|
21
|
+
function unsubscribe() {
|
|
22
|
+
if (teardownRef === null) {
|
|
23
|
+
teardownImmediately = true;
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
if (unsubscribed) {
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
unsubscribed = true;
|
|
30
|
+
|
|
31
|
+
if (typeof teardownRef === 'function') {
|
|
32
|
+
teardownRef();
|
|
33
|
+
} else if (teardownRef) {
|
|
34
|
+
teardownRef.unsubscribe();
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
teardownRef = subscribe({
|
|
38
|
+
next(value) {
|
|
39
|
+
if (isDone) {
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
observer.next?.(value);
|
|
43
|
+
},
|
|
44
|
+
error(err) {
|
|
45
|
+
if (isDone) {
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
isDone = true;
|
|
49
|
+
observer.error?.(err);
|
|
50
|
+
unsubscribe();
|
|
51
|
+
},
|
|
52
|
+
complete() {
|
|
53
|
+
if (isDone) {
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
isDone = true;
|
|
57
|
+
observer.complete?.();
|
|
58
|
+
unsubscribe();
|
|
59
|
+
},
|
|
60
|
+
});
|
|
61
|
+
if (teardownImmediately) {
|
|
62
|
+
unsubscribe();
|
|
63
|
+
}
|
|
64
|
+
return {
|
|
65
|
+
unsubscribe,
|
|
66
|
+
};
|
|
67
|
+
},
|
|
68
|
+
pipe(
|
|
69
|
+
...operations: OperatorFunction<any, any, any, any>[]
|
|
70
|
+
): Observable<any, any> {
|
|
71
|
+
return pipeFromArray(operations)(self) as any;
|
|
72
|
+
},
|
|
73
|
+
};
|
|
74
|
+
return self;
|
|
75
|
+
}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { EventEmitter } from 'events';
|
|
2
|
+
import { expectTypeOf } from 'expect-type';
|
|
3
|
+
import { map } from '.';
|
|
4
|
+
import { observable } from '../observable';
|
|
5
|
+
|
|
6
|
+
interface SubscriptionEvents<TOutput> {
|
|
7
|
+
data: (data: TOutput) => void;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
declare interface CustomEventEmitter<TOutput> {
|
|
11
|
+
on<U extends keyof SubscriptionEvents<TOutput>>(
|
|
12
|
+
event: U,
|
|
13
|
+
listener: SubscriptionEvents<TOutput>[U],
|
|
14
|
+
): this;
|
|
15
|
+
|
|
16
|
+
once<U extends keyof SubscriptionEvents<TOutput>>(
|
|
17
|
+
event: U,
|
|
18
|
+
listener: SubscriptionEvents<TOutput>[U],
|
|
19
|
+
): this;
|
|
20
|
+
|
|
21
|
+
emit<U extends keyof SubscriptionEvents<TOutput>>(
|
|
22
|
+
event: U,
|
|
23
|
+
...args: Parameters<SubscriptionEvents<TOutput>[U]>
|
|
24
|
+
): boolean;
|
|
25
|
+
}
|
|
26
|
+
class CustomEventEmitter<TOutput>
|
|
27
|
+
extends EventEmitter
|
|
28
|
+
implements CustomEventEmitter<TOutput> {}
|
|
29
|
+
test('map', () => {
|
|
30
|
+
type EventShape = { num: number };
|
|
31
|
+
const ee = new CustomEventEmitter<EventShape>();
|
|
32
|
+
const eventObservable = observable<EventShape, unknown>((observer) => {
|
|
33
|
+
const callback = (data: EventShape) => {
|
|
34
|
+
observer.next(data);
|
|
35
|
+
};
|
|
36
|
+
ee.on('data', callback);
|
|
37
|
+
|
|
38
|
+
return () => {
|
|
39
|
+
ee.off('data', callback);
|
|
40
|
+
};
|
|
41
|
+
});
|
|
42
|
+
const pipeCalls = jest.fn();
|
|
43
|
+
const piped = eventObservable.pipe(
|
|
44
|
+
map((...args) => {
|
|
45
|
+
pipeCalls(...args);
|
|
46
|
+
const [value] = args;
|
|
47
|
+
return value.num;
|
|
48
|
+
}),
|
|
49
|
+
);
|
|
50
|
+
|
|
51
|
+
const next = jest.fn();
|
|
52
|
+
const subscription = piped.subscribe({
|
|
53
|
+
next(value) {
|
|
54
|
+
expectTypeOf<number>(value);
|
|
55
|
+
next(value);
|
|
56
|
+
},
|
|
57
|
+
});
|
|
58
|
+
expect(next).not.toHaveBeenCalled();
|
|
59
|
+
ee.emit('data', { num: 1 });
|
|
60
|
+
ee.emit('data', { num: 2 });
|
|
61
|
+
expect(next).toHaveBeenCalledTimes(2);
|
|
62
|
+
expect(next.mock.calls).toMatchInlineSnapshot(`
|
|
63
|
+
Array [
|
|
64
|
+
Array [
|
|
65
|
+
1,
|
|
66
|
+
],
|
|
67
|
+
Array [
|
|
68
|
+
2,
|
|
69
|
+
],
|
|
70
|
+
]
|
|
71
|
+
`);
|
|
72
|
+
expect(pipeCalls.mock.calls).toMatchInlineSnapshot(`
|
|
73
|
+
Array [
|
|
74
|
+
Array [
|
|
75
|
+
Object {
|
|
76
|
+
"num": 1,
|
|
77
|
+
},
|
|
78
|
+
0,
|
|
79
|
+
],
|
|
80
|
+
Array [
|
|
81
|
+
Object {
|
|
82
|
+
"num": 2,
|
|
83
|
+
},
|
|
84
|
+
1,
|
|
85
|
+
],
|
|
86
|
+
]
|
|
87
|
+
`);
|
|
88
|
+
|
|
89
|
+
expect(ee.listeners('data')).toHaveLength(1);
|
|
90
|
+
subscription.unsubscribe();
|
|
91
|
+
expect(ee.listeners('data')).toHaveLength(0);
|
|
92
|
+
});
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { OperatorFunction } from '../types';
|
|
2
|
+
|
|
3
|
+
export function map<TValueBefore, TError, TValueAfter>(
|
|
4
|
+
project: (value: TValueBefore, index: number) => TValueAfter,
|
|
5
|
+
): OperatorFunction<TValueBefore, TError, TValueAfter, TError> {
|
|
6
|
+
return (originalObserver) => {
|
|
7
|
+
return {
|
|
8
|
+
subscribe(observer) {
|
|
9
|
+
let index = 0;
|
|
10
|
+
const subscription = originalObserver.subscribe({
|
|
11
|
+
next(value) {
|
|
12
|
+
observer.next?.(project(value, index++));
|
|
13
|
+
},
|
|
14
|
+
error(error) {
|
|
15
|
+
observer.error?.(error);
|
|
16
|
+
},
|
|
17
|
+
complete() {
|
|
18
|
+
observer.complete?.();
|
|
19
|
+
},
|
|
20
|
+
});
|
|
21
|
+
return subscription;
|
|
22
|
+
},
|
|
23
|
+
};
|
|
24
|
+
};
|
|
25
|
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/* eslint-disable no-var */
|
|
2
|
+
import { observable } from '../observable';
|
|
3
|
+
import { share } from './share';
|
|
4
|
+
|
|
5
|
+
test('share', () => {
|
|
6
|
+
const obs = share()(
|
|
7
|
+
observable<number, Error>((observer) => {
|
|
8
|
+
observer.next(1);
|
|
9
|
+
}),
|
|
10
|
+
);
|
|
11
|
+
|
|
12
|
+
{
|
|
13
|
+
const next = jest.fn();
|
|
14
|
+
const error = jest.fn();
|
|
15
|
+
const complete = jest.fn();
|
|
16
|
+
var subscription1 = obs.subscribe({
|
|
17
|
+
next,
|
|
18
|
+
error,
|
|
19
|
+
complete,
|
|
20
|
+
});
|
|
21
|
+
expect(next.mock.calls).toHaveLength(1);
|
|
22
|
+
expect(complete.mock.calls).toHaveLength(0);
|
|
23
|
+
expect(error.mock.calls).toHaveLength(0);
|
|
24
|
+
expect(next.mock.calls[0][0]).toBe(1);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
{
|
|
28
|
+
// subscribe again - it's shared so should not propagate any results
|
|
29
|
+
const next = jest.fn();
|
|
30
|
+
const error = jest.fn();
|
|
31
|
+
const complete = jest.fn();
|
|
32
|
+
var subscription2 = obs.subscribe({
|
|
33
|
+
next,
|
|
34
|
+
error,
|
|
35
|
+
complete,
|
|
36
|
+
});
|
|
37
|
+
expect(next.mock.calls).toHaveLength(0);
|
|
38
|
+
expect(complete.mock.calls).toHaveLength(0);
|
|
39
|
+
expect(error.mock.calls).toHaveLength(0);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
subscription1.unsubscribe();
|
|
43
|
+
subscription2.unsubscribe();
|
|
44
|
+
// now it should be reset so we can do a new subscription
|
|
45
|
+
{
|
|
46
|
+
const next = jest.fn();
|
|
47
|
+
const error = jest.fn();
|
|
48
|
+
const complete = jest.fn();
|
|
49
|
+
var subscription3 = obs.subscribe({
|
|
50
|
+
next,
|
|
51
|
+
error,
|
|
52
|
+
complete,
|
|
53
|
+
});
|
|
54
|
+
expect(next.mock.calls).toHaveLength(1);
|
|
55
|
+
expect(complete.mock.calls).toHaveLength(0);
|
|
56
|
+
expect(error.mock.calls).toHaveLength(0);
|
|
57
|
+
expect(next.mock.calls[0][0]).toBe(1);
|
|
58
|
+
subscription3.unsubscribe();
|
|
59
|
+
}
|
|
60
|
+
});
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { MonoTypeOperatorFunction, Observer, Unsubscribable } from '../types';
|
|
2
|
+
|
|
3
|
+
/* eslint-disable @typescript-eslint/no-empty-interface */
|
|
4
|
+
interface ShareConfig {}
|
|
5
|
+
export function share<TValue, TError>(
|
|
6
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
7
|
+
_opts?: ShareConfig,
|
|
8
|
+
): MonoTypeOperatorFunction<TValue, TError> {
|
|
9
|
+
return (originalObserver) => {
|
|
10
|
+
let refCount = 0;
|
|
11
|
+
|
|
12
|
+
let subscription: Unsubscribable | null = null;
|
|
13
|
+
const observers: Partial<Observer<TValue, TError>>[] = [];
|
|
14
|
+
|
|
15
|
+
function startIfNeeded() {
|
|
16
|
+
if (subscription) {
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
subscription = originalObserver.subscribe({
|
|
20
|
+
next(value) {
|
|
21
|
+
for (const observer of observers) {
|
|
22
|
+
observer.next?.(value);
|
|
23
|
+
}
|
|
24
|
+
},
|
|
25
|
+
error(error) {
|
|
26
|
+
for (const observer of observers) {
|
|
27
|
+
observer.error?.(error);
|
|
28
|
+
}
|
|
29
|
+
},
|
|
30
|
+
complete() {
|
|
31
|
+
for (const observer of observers) {
|
|
32
|
+
observer.complete?.();
|
|
33
|
+
}
|
|
34
|
+
},
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
function resetIfNeeded() {
|
|
38
|
+
// "resetOnRefCountZero"
|
|
39
|
+
if (refCount === 0 && subscription) {
|
|
40
|
+
const _sub = subscription;
|
|
41
|
+
subscription = null;
|
|
42
|
+
_sub.unsubscribe();
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
return {
|
|
47
|
+
subscribe(observer) {
|
|
48
|
+
refCount++;
|
|
49
|
+
|
|
50
|
+
observers.push(observer);
|
|
51
|
+
startIfNeeded();
|
|
52
|
+
return {
|
|
53
|
+
unsubscribe() {
|
|
54
|
+
refCount--;
|
|
55
|
+
resetIfNeeded();
|
|
56
|
+
|
|
57
|
+
const index = observers.findIndex((v) => v === observer);
|
|
58
|
+
|
|
59
|
+
if (index > -1) {
|
|
60
|
+
observers.splice(index, 1);
|
|
61
|
+
}
|
|
62
|
+
},
|
|
63
|
+
};
|
|
64
|
+
},
|
|
65
|
+
};
|
|
66
|
+
};
|
|
67
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { MonoTypeOperatorFunction, Observer } from '../types';
|
|
2
|
+
|
|
3
|
+
export function tap<TValue, TError>(
|
|
4
|
+
observer: Partial<Observer<TValue, TError>>,
|
|
5
|
+
): MonoTypeOperatorFunction<TValue, TError> {
|
|
6
|
+
return (originalObserver) => {
|
|
7
|
+
return {
|
|
8
|
+
subscribe(observer2) {
|
|
9
|
+
return originalObserver.subscribe({
|
|
10
|
+
next(v) {
|
|
11
|
+
observer.next?.(v);
|
|
12
|
+
observer2.next?.(v);
|
|
13
|
+
},
|
|
14
|
+
error(v) {
|
|
15
|
+
observer.error?.(v);
|
|
16
|
+
observer2.error?.(v);
|
|
17
|
+
},
|
|
18
|
+
complete() {
|
|
19
|
+
observer.complete?.();
|
|
20
|
+
observer2.complete?.();
|
|
21
|
+
},
|
|
22
|
+
});
|
|
23
|
+
},
|
|
24
|
+
};
|
|
25
|
+
};
|
|
26
|
+
}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
export interface Unsubscribable {
|
|
2
|
+
unsubscribe(): void;
|
|
3
|
+
}
|
|
4
|
+
export type UnsubscribeFn = () => void;
|
|
5
|
+
export interface Subscribable<TValue, TError> {
|
|
6
|
+
subscribe(observer: Partial<Observer<TValue, TError>>): Unsubscribable;
|
|
7
|
+
}
|
|
8
|
+
export interface Observable<TValue, TError>
|
|
9
|
+
extends Subscribable<TValue, TError> {
|
|
10
|
+
pipe(): Observable<TValue, TError>;
|
|
11
|
+
pipe<V1, E1>(
|
|
12
|
+
op1: OperatorFunction<TValue, TError, V1, E1>,
|
|
13
|
+
): Observable<V1, E1>;
|
|
14
|
+
pipe<V1, E1, V2, E2>(
|
|
15
|
+
op1: OperatorFunction<TValue, TError, V1, E1>,
|
|
16
|
+
op2: OperatorFunction<V1, E1, V2, E2>,
|
|
17
|
+
): Observable<V2, E2>;
|
|
18
|
+
pipe<V1, E1, V2, E2, V3, E3>(
|
|
19
|
+
op1: OperatorFunction<TValue, TError, V1, E1>,
|
|
20
|
+
op2: OperatorFunction<V1, E1, V2, E2>,
|
|
21
|
+
op3: OperatorFunction<V2, E2, V3, E3>,
|
|
22
|
+
): Observable<V2, E2>;
|
|
23
|
+
pipe<V1, E1, V2, E2, V3, E3, V4, E4>(
|
|
24
|
+
op1: OperatorFunction<TValue, TError, V1, E1>,
|
|
25
|
+
op2: OperatorFunction<V1, E1, V2, E2>,
|
|
26
|
+
op3: OperatorFunction<V2, E2, V3, E3>,
|
|
27
|
+
op4: OperatorFunction<V3, E3, V4, E4>,
|
|
28
|
+
): Observable<V2, E2>;
|
|
29
|
+
pipe<V1, E1, V2, E2, V3, E3, V4, E4, V5, E5>(
|
|
30
|
+
op1: OperatorFunction<TValue, TError, V1, E1>,
|
|
31
|
+
op2: OperatorFunction<V1, E1, V2, E2>,
|
|
32
|
+
op3: OperatorFunction<V2, E2, V3, E3>,
|
|
33
|
+
op4: OperatorFunction<V3, E3, V4, E4>,
|
|
34
|
+
op5: OperatorFunction<V4, E4, V5, E5>,
|
|
35
|
+
): Observable<V2, E2>;
|
|
36
|
+
}
|
|
37
|
+
export interface SubscriptionLike extends Unsubscribable {
|
|
38
|
+
unsubscribe(): void;
|
|
39
|
+
readonly closed: boolean;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export interface Observer<TValue, TError> {
|
|
43
|
+
next: (value: TValue) => void;
|
|
44
|
+
error: (err: TError) => void;
|
|
45
|
+
complete: () => void;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export type TeardownLogic =
|
|
49
|
+
// | SubscriptionLike
|
|
50
|
+
Unsubscribable | UnsubscribeFn | void;
|
|
51
|
+
|
|
52
|
+
export type UnaryFunction<T, R> = (source: T) => R;
|
|
53
|
+
|
|
54
|
+
export type OperatorFunction<
|
|
55
|
+
TValueBefore,
|
|
56
|
+
TErrorBefore,
|
|
57
|
+
TValueAfter,
|
|
58
|
+
TErrorAfter,
|
|
59
|
+
> = UnaryFunction<
|
|
60
|
+
Subscribable<TValueBefore, TErrorBefore>,
|
|
61
|
+
Subscribable<TValueAfter, TErrorAfter>
|
|
62
|
+
>;
|
|
63
|
+
|
|
64
|
+
export type MonoTypeOperatorFunction<TValue, TError> = OperatorFunction<
|
|
65
|
+
TValue,
|
|
66
|
+
TError,
|
|
67
|
+
TValue,
|
|
68
|
+
TError
|
|
69
|
+
>;
|
package/src/router.ts
CHANGED
|
@@ -15,13 +15,13 @@ import {
|
|
|
15
15
|
createProcedure,
|
|
16
16
|
inferProcedureFromOptions,
|
|
17
17
|
} from './internals/procedure';
|
|
18
|
+
import { Observable, inferObservableValue } from './observable';
|
|
18
19
|
import {
|
|
19
20
|
TRPCErrorShape,
|
|
20
21
|
TRPC_ERROR_CODES_BY_KEY,
|
|
21
22
|
TRPC_ERROR_CODE_KEY,
|
|
22
23
|
TRPC_ERROR_CODE_NUMBER,
|
|
23
24
|
} from './rpc';
|
|
24
|
-
import { Subscription } from './subscription';
|
|
25
25
|
import { CombinedDataTransformer, DataTransformerOptions } from './transformer';
|
|
26
26
|
import { Prefixer, ThenArg, flatten } from './types';
|
|
27
27
|
|
|
@@ -87,10 +87,8 @@ export type inferProcedureOutput<
|
|
|
87
87
|
export type inferSubscriptionOutput<
|
|
88
88
|
TRouter extends AnyRouter,
|
|
89
89
|
TPath extends keyof TRouter['_def']['subscriptions'],
|
|
90
|
-
> =
|
|
91
|
-
inferAsyncReturnType<
|
|
92
|
-
TRouter['_def']['subscriptions'][TPath]['call']
|
|
93
|
-
>['output']
|
|
90
|
+
> = inferObservableValue<
|
|
91
|
+
inferAsyncReturnType<TRouter['_def']['subscriptions'][TPath]['call']>
|
|
94
92
|
>;
|
|
95
93
|
|
|
96
94
|
function getDataTransformer(
|
|
@@ -292,7 +290,7 @@ export class Router<
|
|
|
292
290
|
TContext,
|
|
293
291
|
unknown,
|
|
294
292
|
unknown,
|
|
295
|
-
|
|
293
|
+
Observable<unknown, unknown>,
|
|
296
294
|
unknown,
|
|
297
295
|
unknown
|
|
298
296
|
>,
|
|
@@ -489,7 +487,7 @@ export class Router<
|
|
|
489
487
|
TPath extends string,
|
|
490
488
|
TInput,
|
|
491
489
|
TParsedInput,
|
|
492
|
-
TOutput extends
|
|
490
|
+
TOutput extends Observable<unknown, unknown>,
|
|
493
491
|
>(
|
|
494
492
|
path: TPath,
|
|
495
493
|
procedure: Omit<
|
|
@@ -520,7 +518,7 @@ export class Router<
|
|
|
520
518
|
public subscription<
|
|
521
519
|
TPath extends string,
|
|
522
520
|
TInput,
|
|
523
|
-
TOutput extends
|
|
521
|
+
TOutput extends Observable<unknown, unknown>,
|
|
524
522
|
>(
|
|
525
523
|
path: TPath,
|
|
526
524
|
procedure: Omit<
|
|
@@ -543,7 +541,7 @@ export class Router<
|
|
|
543
541
|
*/
|
|
544
542
|
public subscription<
|
|
545
543
|
TPath extends string,
|
|
546
|
-
TOutput extends
|
|
544
|
+
TOutput extends Observable<unknown, unknown>,
|
|
547
545
|
>(
|
|
548
546
|
path: TPath,
|
|
549
547
|
procedure: Omit<
|