1import type { VNode } from 'preact';
2import type { AnyVariables } from '@urql/core';
3
4import type {
5 UseSubscriptionArgs,
6 UseSubscriptionState,
7 UseSubscriptionExecute,
8 SubscriptionHandler,
9} from '../hooks';
10import { useSubscription } from '../hooks';
11
12/** Props accepted by {@link Subscription}.
13 *
14 * @remarks
15 * `SubscriptionProps` are the props accepted by the {@link Subscription} component,
16 * which is identical to {@link UseSubscriptionArgs} with an added
17 * {@link SubscriptionProps.handler} prop, which {@link useSubscription} usually
18 * accepts as an additional argument.
19 *
20 * The result, the {@link SubscriptionState} object, will be passed to
21 * a {@link SubscriptionProps.children} function, passed as children
22 * to the `Subscription` component.
23 */
24export type SubscriptionProps<
25 Data = any,
26 Result = Data,
27 Variables extends AnyVariables = AnyVariables,
28> = UseSubscriptionArgs<Variables, Data> & {
29 /** Accepts the {@link SubscriptionHandler} as a prop. */
30 handler?: SubscriptionHandler<Data, Result>;
31 children(arg: SubscriptionState<Result, Variables>): VNode<any>;
32};
33
34/** Object that {@link SubscriptionProps.children} is called with.
35 *
36 * @remarks
37 * This is an extented {@link UseSubscriptionState} with an added
38 * {@link SubscriptionState.executeSubscription} method, which is usually
39 * part of a tuple returned by {@link useSubscription}.
40 */
41export interface SubscriptionState<
42 Data = any,
43 Variables extends AnyVariables = AnyVariables,
44> extends UseSubscriptionState<Data, Variables> {
45 /** Alias to {@link useSubscription}’s `executeMutation` function. */
46 executeSubscription: UseSubscriptionExecute;
47}
48
49/** Component Wrapper around {@link useSubscription} to run a GraphQL subscription.
50 *
51 * @remarks
52 * `Subscription` is a component wrapper around the {@link useSubscription} hook
53 * that calls the {@link SubscriptionProps.children} prop, as a function,
54 * with the {@link SubscriptionState} object.
55 */
56export function Subscription<
57 Data = any,
58 Result = Data,
59 Variables extends AnyVariables = AnyVariables,
60>(props: SubscriptionProps<Data, Result, Variables>): VNode<any> {
61 const subscription = useSubscription<Data, Result, Variables>(
62 props,
63 props.handler
64 );
65
66 return props.children({
67 ...subscription[0],
68 executeSubscription: subscription[1],
69 });
70}