Skip to content

tRPC v12 isn’t on npm yet. The @trpc12/* packages on this site can’t be installed until it’s released. Use v11 today

tRPC

ExperimentalTanStack Query beyond React might change or go away in any release. Stability

Lit

@trpc12/experimental-tanstack-lit-query: a provider element for the client, useTrpc(this) in elements, and createSubscriptionController.

On this page

@trpc12/experimental-tanstack-lit-query re-exports @trpc12/tanstack-query and adds a provider element and @lit/context consumers for a client and its helpers, and a createSubscriptionController. Without a provider, createTrpcQueryUtils({ client }) works in Lit too.

Not on npm yet
pnpm add @trpc12/trpc effect @trpc12/experimental-tanstack-lit-query @tanstack/lit-query @lit/context
npm install @trpc12/trpc effect @trpc12/experimental-tanstack-lit-query @tanstack/lit-query @lit/context
yarn add @trpc12/trpc effect @trpc12/experimental-tanstack-lit-query @tanstack/lit-query @lit/context
bun add @trpc12/trpc effect @trpc12/experimental-tanstack-lit-query @tanstack/lit-query @lit/context

Provide the client

createTrpcContext takes the type of the function that makes the client (or of the client, or the router), so the helpers get what its links declare. Its TrpcProvider element isn't registered: define it under a tag of your choice, as TanStack's QueryClientProvider, and set its client as a property, inside TanStack's provider:

// trpc.ts
const 
const makeClient: () => TrpcClient<{
    post: {
        byId: Procedure<{
            type: "query";
            ctx: Context;
            meta: {};
            input: {
                id: string;
            };
            output: Post;
            errors: TrpcError<"NOT_FOUND", {
                id: string;
            }> | SchemaValidationError<ZodObject<{
                id: ZodString;
            }, $strip>>;
            services: never;
        }>;
        list: Procedure<{
            type: "query";
            ctx: Context;
            meta: {};
            input: undefined;
            output: Post[];
            errors: never;
            services: never;
        }>;
        create: Procedure<{
            type: "mutation";
            ctx: Context;
            meta: {};
            input: {
                title: string;
            };
            output: Post;
            errors: TrpcError<...> | SchemaValidationError<...>;
            services: never;
        }>;
    };
}, {}, undefined, LinksTypes<...>>
makeClient
= () =>
createTrpcClient<RouterType<{
    post: {
        byId: Procedure<{
            type: "query";
            ctx: Context;
            meta: {};
            input: {
                id: string;
            };
            output: Post;
            errors: TrpcError<"NOT_FOUND", {
                id: string;
            }> | SchemaValidationError<ZodObject<{
                id: ZodString;
            }, $strip>>;
            services: never;
        }>;
        list: Procedure<{
            type: "query";
            ctx: Context;
            meta: {};
            input: undefined;
            output: Post[];
            errors: never;
            services: never;
        }>;
        create: Procedure<{
            type: "mutation";
            ctx: Context;
            meta: {};
            input: {
                title: string;
            };
            output: Post;
            errors: TrpcError<...> | SchemaValidationError<...>;
            services: never;
        }>;
    };
}>, readonly [...]>(opts: TypedClientOptions<...>): TrpcClient<...>
createTrpcClient
({
TypedClientOptions<RouterType<{ post: { byId: Procedure<{ type: "query"; ctx: Context; meta: {}; input: { id: string; }; output: Post; errors: TrpcError<"NOT_FOUND", { id: string; }> | SchemaValidationError<ZodObject<{ id: ZodString; }, $strip>>; services: never; }>; list: Procedure<...>; create: Procedure<...>; }; }>, readonly [...]>.router: RouterType<{
    post: {
        byId: Procedure<{
            type: "query";
            ctx: Context;
            meta: {};
            input: {
                id: string;
            };
            output: Post;
            errors: TrpcError<"NOT_FOUND", {
                id: string;
            }> | SchemaValidationError<ZodObject<{
                id: ZodString;
            }, $strip>>;
            services: never;
        }>;
        list: Procedure<{
            type: "query";
            ctx: Context;
            meta: {};
            input: undefined;
            output: Post[];
            errors: never;
            services: never;
        }>;
        create: Procedure<{
            type: "mutation";
            ctx: Context;
            meta: {};
            input: {
                title: string;
            };
            output: Post;
            errors: TrpcError<...> | SchemaValidationError<...>;
            services: never;
        }>;
    };
}>
router
:
routerType<{
    post: {
        byId: Procedure<{
            type: "query";
            ctx: Context;
            meta: {};
            input: {
                id: string;
            };
            output: Post;
            errors: TrpcError<"NOT_FOUND", {
                id: string;
            }> | SchemaValidationError<ZodObject<{
                id: ZodString;
            }, $strip>>;
            services: never;
        }>;
        list: Procedure<{
            type: "query";
            ctx: Context;
            meta: {};
            input: undefined;
            output: Post[];
            errors: never;
            services: never;
        }>;
        create: Procedure<{
            type: "mutation";
            ctx: Context;
            meta: {};
            input: {
                title: string;
            };
            output: Post;
            errors: TrpcError<...> | SchemaValidationError<...>;
            services: never;
        }>;
    };
}>(): RouterType<...>
routerType
<
type AppRouter = {
    post: {
        byId: Procedure<{
            type: "query";
            ctx: Context;
            meta: {};
            input: {
                id: string;
            };
            output: Post;
            errors: TrpcError<"NOT_FOUND", {
                id: string;
            }> | SchemaValidationError<ZodObject<{
                id: ZodString;
            }, $strip>>;
            services: never;
        }>;
        list: Procedure<{
            type: "query";
            ctx: Context;
            meta: {};
            input: undefined;
            output: Post[];
            errors: never;
            services: never;
        }>;
        create: Procedure<{
            type: "mutation";
            ctx: Context;
            meta: {};
            input: {
                title: string;
            };
            output: Post;
            errors: TrpcError<...> | SchemaValidationError<...>;
            services: never;
        }>;
    };
}
AppRouter
>(),
TypedClientOptions<RouterType<{ post: { byId: Procedure<{ type: "query"; ctx: Context; meta: {}; input: { id: string; }; output: Post; errors: TrpcError<"NOT_FOUND", { id: string; }> | SchemaValidationError<ZodObject<{ id: ZodString; }, $strip>>; services: never; }>; list: Procedure<...>; create: Procedure<...>; }; }>, readonly [...]>.links: readonly [TrpcLink<{
    form: JsonForm;
    provides: "response";
    builtinErrors: "NETWORK_ERROR" | "BAD_RESPONSE" | "STREAM_INTERRUPTED";
}, any>]
links
: [
httpLink<{
    url: string;
}>(opts: {
    url: string;
}): TrpcLink<{
    form: JsonForm;
    provides: "response";
    builtinErrors: "NETWORK_ERROR" | "BAD_RESPONSE" | "STREAM_INTERRUPTED";
}, any>
httpLink
({ url: stringurl: '/trpc' })],
}); export const {
const TrpcProvider: new () => TrpcProviderElement<{
    post: {
        byId: Procedure<{
            type: "query";
            ctx: Context;
            meta: {};
            input: {
                id: string;
            };
            output: Post;
            errors: TrpcError<"NOT_FOUND", {
                id: string;
            }> | SchemaValidationError<ZodObject<{
                id: ZodString;
            }, $strip>>;
            services: never;
        }>;
        list: Procedure<{
            type: "query";
            ctx: Context;
            meta: {};
            input: undefined;
            output: Post[];
            errors: never;
            services: never;
        }>;
        create: Procedure<{
            type: "mutation";
            ctx: Context;
            meta: {};
            input: {
                title: string;
            };
            output: Post;
            errors: TrpcError<...> | SchemaValidationError<...>;
            services: never;
        }>;
    };
}, {}, LinksTypes<...>>
TrpcProvider
,
const useTrpc: (host: ReactiveElement) => TrpcQueryUtilsFor<{
    post: {
        byId: Procedure<{
            type: "query";
            ctx: Context;
            meta: {};
            input: {
                id: string;
            };
            output: Post;
            errors: TrpcError<"NOT_FOUND", {
                id: string;
            }> | SchemaValidationError<ZodObject<{
                id: ZodString;
            }, $strip>>;
            services: never;
        }>;
        list: Procedure<{
            type: "query";
            ctx: Context;
            meta: {};
            input: undefined;
            output: Post[];
            errors: never;
            services: never;
        }>;
        create: Procedure<{
            type: "mutation";
            ctx: Context;
            ... 4 more ...;
            services: never;
        }>;
    };
}, {}, LinksTypes<...>>
useTrpc
,
const useTrpcClient: (host: ReactiveElement) => TrpcClient<{
    post: {
        byId: Procedure<{
            type: "query";
            ctx: Context;
            meta: {};
            input: {
                id: string;
            };
            output: Post;
            errors: TrpcError<"NOT_FOUND", {
                id: string;
            }> | SchemaValidationError<ZodObject<{
                id: ZodString;
            }, $strip>>;
            services: never;
        }>;
        list: Procedure<{
            type: "query";
            ctx: Context;
            meta: {};
            input: undefined;
            output: Post[];
            errors: never;
            services: never;
        }>;
        create: Procedure<{
            type: "mutation";
            ctx: Context;
            ... 4 more ...;
            services: never;
        }>;
    };
}, {}, undefined, LinksTypes<...>>
useTrpcClient
} =
createTrpcContext<() => TrpcClient<{
    post: {
        byId: Procedure<{
            type: "query";
            ctx: Context;
            meta: {};
            input: {
                id: string;
            };
            output: Post;
            errors: TrpcError<"NOT_FOUND", {
                id: string;
            }> | SchemaValidationError<ZodObject<{
                id: ZodString;
            }, $strip>>;
            services: never;
        }>;
        list: Procedure<{
            type: "query";
            ctx: Context;
            meta: {};
            input: undefined;
            output: Post[];
            errors: never;
            services: never;
        }>;
        create: Procedure<{
            type: "mutation";
            ctx: Context;
            meta: {};
            input: {
                title: string;
            };
            output: Post;
            errors: TrpcError<...> | SchemaValidationError<...>;
            services: never;
        }>;
    };
}, {}, undefined, LinksTypes<...>>>(opts?: TrpcContextOptions): TrpcLitContext<...>
createTrpcContext
<typeof
const makeClient: () => TrpcClient<{
    post: {
        byId: Procedure<{
            type: "query";
            ctx: Context;
            meta: {};
            input: {
                id: string;
            };
            output: Post;
            errors: TrpcError<"NOT_FOUND", {
                id: string;
            }> | SchemaValidationError<ZodObject<{
                id: ZodString;
            }, $strip>>;
            services: never;
        }>;
        list: Procedure<{
            type: "query";
            ctx: Context;
            meta: {};
            input: undefined;
            output: Post[];
            errors: never;
            services: never;
        }>;
        create: Procedure<{
            type: "mutation";
            ctx: Context;
            meta: {};
            input: {
                title: string;
            };
            output: Post;
            errors: TrpcError<...> | SchemaValidationError<...>;
            services: never;
        }>;
    };
}, {}, undefined, LinksTypes<...>>
makeClient
>();
var customElements: CustomElementRegistrycustomElements.CustomElementRegistry.define(name: string, constructor: CustomElementConstructor, options?: ElementDefinitionOptions): voiddefine('trpc-provider',
const TrpcProvider: new () => TrpcProviderElement<{
    post: {
        byId: Procedure<{
            type: "query";
            ctx: Context;
            meta: {};
            input: {
                id: string;
            };
            output: Post;
            errors: TrpcError<"NOT_FOUND", {
                id: string;
            }> | SchemaValidationError<ZodObject<{
                id: ZodString;
            }, $strip>>;
            services: never;
        }>;
        list: Procedure<{
            type: "query";
            ctx: Context;
            meta: {};
            input: undefined;
            output: Post[];
            errors: never;
            services: never;
        }>;
        create: Procedure<{
            type: "mutation";
            ctx: Context;
            meta: {};
            input: {
                title: string;
            };
            output: Post;
            errors: TrpcError<...> | SchemaValidationError<...>;
            services: never;
        }>;
    };
}, {}, LinksTypes<...>>
TrpcProvider
);
// app.ts var customElements: CustomElementRegistrycustomElements.CustomElementRegistry.define(name: string, constructor: CustomElementConstructor, options?: ElementDefinitionOptions): voiddefine('query-client-provider', class QueryClientProviderQueryClientProvider); const const queryClient: QueryClientqueryClient = new new QueryClient(config?: QueryClientConfig): QueryClientQueryClient(); const
const client: TrpcClient<{
    post: {
        byId: Procedure<{
            type: "query";
            ctx: Context;
            meta: {};
            input: {
                id: string;
            };
            output: Post;
            errors: TrpcError<"NOT_FOUND", {
                id: string;
            }> | SchemaValidationError<ZodObject<{
                id: ZodString;
            }, $strip>>;
            services: never;
        }>;
        list: Procedure<{
            type: "query";
            ctx: Context;
            meta: {};
            input: undefined;
            output: Post[];
            errors: never;
            services: never;
        }>;
        create: Procedure<{
            type: "mutation";
            ctx: Context;
            meta: {};
            input: {
                title: string;
            };
            output: Post;
            errors: TrpcError<...> | SchemaValidationError<...>;
            services: never;
        }>;
    };
}, {}, undefined, LinksTypes<...>>
client
=
const makeClient: () => TrpcClient<{
    post: {
        byId: Procedure<{
            type: "query";
            ctx: Context;
            meta: {};
            input: {
                id: string;
            };
            output: Post;
            errors: TrpcError<"NOT_FOUND", {
                id: string;
            }> | SchemaValidationError<ZodObject<{
                id: ZodString;
            }, $strip>>;
            services: never;
        }>;
        list: Procedure<{
            type: "query";
            ctx: Context;
            meta: {};
            input: undefined;
            output: Post[];
            errors: never;
            services: never;
        }>;
        create: Procedure<{
            type: "mutation";
            ctx: Context;
            meta: {};
            input: {
                title: string;
            };
            output: Post;
            errors: TrpcError<...> | SchemaValidationError<...>;
            services: never;
        }>;
    };
}, {}, undefined, LinksTypes<...>>
makeClient
();
const html: (strings: TemplateStringsArray, ...values: unknown[]) => TemplateResult<1>html`<query-client-provider .client=${const queryClient: QueryClientqueryClient}> <trpc-provider .client=${
const client: TrpcClient<{
    post: {
        byId: Procedure<{
            type: "query";
            ctx: Context;
            meta: {};
            input: {
                id: string;
            };
            output: Post;
            errors: TrpcError<"NOT_FOUND", {
                id: string;
            }> | SchemaValidationError<ZodObject<{
                id: ZodString;
            }, $strip>>;
            services: never;
        }>;
        list: Procedure<{
            type: "query";
            ctx: Context;
            meta: {};
            input: undefined;
            output: Post[];
            errors: never;
            services: never;
        }>;
        create: Procedure<{
            type: "mutation";
            ctx: Context;
            meta: {};
            input: {
                title: string;
            };
            output: Post;
            errors: TrpcError<...> | SchemaValidationError<...>;
            services: never;
        }>;
    };
}, {}, undefined, LinksTypes<...>>
client
}><post-view></post-view></trpc-provider>
</query-client-provider>`;

context is the @lit/context key too, for @consume or a provider of your own.

Queries and mutations

Call useTrpc(this) in a field initializer. It resolves the helpers on first use, so use them once the element is connected: in render or in a controller's options function. Pass a function to createQueryController, so the options are read again on each update; a new input is a new key:

class class PostViewPostView extends class LitElementLitElement {
  static override 
PostView.properties: {
    postId: {};
}
properties
= { postId: {}postId: {} };
declare PostView.postId: stringpostId: string;
PostView.trpc: TrpcQueryUtilsFor<{
    post: {
        byId: Procedure<{
            type: "query";
            ctx: Context;
            meta: {};
            input: {
                id: string;
            };
            output: Post;
            errors: TrpcError<"NOT_FOUND", {
                id: string;
            }> | SchemaValidationError<ZodObject<{
                id: ZodString;
            }, $strip>>;
            services: never;
        }>;
        list: Procedure<{
            type: "query";
            ctx: Context;
            meta: {};
            input: undefined;
            output: Post[];
            errors: never;
            services: never;
        }>;
        create: Procedure<{
            type: "mutation";
            ctx: Context;
            meta: {};
            input: {
                title: string;
            };
            output: Post;
            errors: TrpcError<...> | SchemaValidationError<...>;
            services: never;
        }>;
    };
}, {}, {}>
trpc
=
const useTrpc: (host: ReactiveElement) => TrpcQueryUtilsFor<{
    post: {
        byId: Procedure<{
            type: "query";
            ctx: Context;
            meta: {};
            input: {
                id: string;
            };
            output: Post;
            errors: TrpcError<"NOT_FOUND", {
                id: string;
            }> | SchemaValidationError<ZodObject<{
                id: ZodString;
            }, $strip>>;
            services: never;
        }>;
        list: Procedure<{
            type: "query";
            ctx: Context;
            meta: {};
            input: undefined;
            output: Post[];
            errors: never;
            services: never;
        }>;
        create: Procedure<{
            type: "mutation";
            ctx: Context;
            ... 4 more ...;
            services: never;
        }>;
    };
}, {}, {}>
useTrpc
(this);
PostView.post: QueryResultAccessor<{
    id: string;
    title: string;
    author: string | null;
    createdAt: string;
}, NonNullable<UndeclaredError | (TrpcError<"NOT_FOUND", {
    id: string;
}> & {
    readonly defined: true;
}) | (TrpcError<"BAD_REQUEST", SchemaInputErrorData<ZodObject<{
    id: ZodString;
}, $strip>>> & {
    readonly defined: true;
}) | (TrpcError<"NOT_FOUND", undefined> & {
    readonly defined: false;
}) | (TrpcError<"BAD_REQUEST", undefined> & {
    readonly defined: false;
}) | ... 22 more ... | (TrpcError<...> & {
    readonly defined: false;
})>>
post
=
createQueryController<{
    id: string;
    title: string;
    author: string | null;
    createdAt: string;
}, NonNullable<UndeclaredError | (TrpcError<"NOT_FOUND", {
    id: string;
}> & {
    readonly defined: true;
}) | (TrpcError<"BAD_REQUEST", SchemaInputErrorData<ZodObject<{
    id: ZodString;
}, $strip>>> & {
    readonly defined: true;
}) | (TrpcError<"NOT_FOUND", undefined> & {
    readonly defined: false;
}) | (TrpcError<"BAD_REQUEST", undefined> & {
    readonly defined: false;
}) | ... 22 more ... | (TrpcError<...> & {
    readonly defined: false;
})>, {
    id: string;
    title: string;
    author: string | null;
    createdAt: string;
}, {
    id: string;
    title: string;
    author: string | null;
    createdAt: string;
}, TrpcQueryKey & {
    ...;
}>(host: ReactiveControllerHost, options: Accessor<...>, queryClient?: QueryClient): QueryResultAccessor<...>
createQueryController
(this, () =>
this.
PostView.trpc: TrpcQueryUtilsFor<{
    post: {
        byId: Procedure<{
            type: "query";
            ctx: Context;
            meta: {};
            input: {
                id: string;
            };
            output: Post;
            errors: TrpcError<"NOT_FOUND", {
                id: string;
            }> | SchemaValidationError<ZodObject<{
                id: ZodString;
            }, $strip>>;
            services: never;
        }>;
        list: Procedure<{
            type: "query";
            ctx: Context;
            meta: {};
            input: undefined;
            output: Post[];
            errors: never;
            services: never;
        }>;
        create: Procedure<{
            type: "mutation";
            ctx: Context;
            meta: {};
            input: {
                title: string;
            };
            output: Post;
            errors: TrpcError<...> | SchemaValidationError<...>;
            services: never;
        }>;
    };
}, {}, {}>
trpc
.
post: TrpcQueryUtils<ClientRouter<{
    byId: Procedure<{
        type: "query";
        ctx: Context;
        meta: {};
        input: {
            id: string;
        };
        output: Post;
        errors: TrpcError<"NOT_FOUND", {
            id: string;
        }> | SchemaValidationError<ZodObject<{
            id: ZodString;
        }, $strip>>;
        services: never;
    }>;
    list: Procedure<{
        type: "query";
        ctx: Context;
        meta: {};
        input: undefined;
        output: Post[];
        errors: never;
        services: never;
    }>;
    create: Procedure<{
        type: "mutation";
        ctx: Context;
        meta: {};
        input: {
            title: string;
        };
        output: Post;
        errors: TrpcError<...> | SchemaValidationError<...>;
        services: never;
    }>;
}, {}, undefined, {}>>
post
.
byId: QueryProcedureUtils<{
    id: string;
}, {
    id: string;
    title: string;
    author: string | null;
    createdAt: string;
}, NonNullable<UndeclaredError | (TrpcError<"NOT_FOUND", {
    id: string;
}> & {
    readonly defined: true;
}) | (TrpcError<"BAD_REQUEST", SchemaInputErrorData<ZodObject<{
    id: ZodString;
}, $strip>>> & {
    readonly defined: true;
}) | (TrpcError<"NOT_FOUND", undefined> & {
    readonly defined: false;
}) | (TrpcError<"BAD_REQUEST", undefined> & {
    readonly defined: false;
}) | ... 22 more ... | (TrpcError<...> & {
    readonly defined: false;
})>, Omit<...>>
byId
.
QueryProcedureUtils<{ id: string; }, { id: string; title: string; author: string | null; createdAt: string; }, NonNullable<UndeclaredError | (TrpcError<"NOT_FOUND", { id: string; }> & { ...; }) | ... 25 more ... | (TrpcError<...> & { ...; })>, Omit<...>>.queryOptions<{
    id: string;
    title: string;
    author: string | null;
    createdAt: string;
}>(opts: {
    input: {
        id: string;
    } | unique symbol;
} & ContextBag<Omit<NonNullable<{
    signal?: AbortSignal | undefined;
} & BuiltinCallOptions>, "signal" | "lastEventId">> & QueryOptionsIn<{
    id: string;
    title: string;
    author: string | null;
    createdAt: string;
}, NonNullable<UndeclaredError | (TrpcError<"NOT_FOUND", {
    id: string;
}> & {
    readonly defined: true;
}) | (TrpcError<"BAD_REQUEST", SchemaInputErrorData<ZodObject<{
    id: ZodString;
}, $strip>>> & {
    ...;
}) | ... 24 more ... | (TrpcError<...> & {
    ...;
})>, {
    id: string;
    title: string;
    author: string | null;
    createdAt: string;
}>): QueryOptionsOut<...> (+1 overload)
queryOptions
({
input: {
    id: string;
} | unique symbol
input
: { id: stringid: this.PostView.postId: stringpostId } }),
);
PostView.create: MutationResultAccessor<{
    id: string;
    title: string;
    author: string | null;
    createdAt: string;
}, (TrpcError<"NOT_FOUND", undefined> & {
    readonly defined: false;
}) | (TrpcError<"BAD_REQUEST", undefined> & {
    readonly defined: false;
}) | (TrpcError<"UNAUTHORIZED", undefined> & {
    readonly defined: false;
}) | (TrpcError<"PARSE_ERROR", undefined> & {
    readonly defined: false;
}) | (TrpcError<"UNSUPPORTED_PROTOCOL", undefined> & {
    readonly defined: false;
}) | (TrpcError<"PAYMENT_REQUIRED", undefined> & {
    readonly defined: false;
}) | ... 21 more ... | (TrpcError<...> & {
    ...;
}), {
    ...;
}, undefined>
create
=
createMutationController<{
    id: string;
    title: string;
    author: string | null;
    createdAt: string;
}, (TrpcError<"NOT_FOUND", undefined> & {
    readonly defined: false;
}) | (TrpcError<"BAD_REQUEST", undefined> & {
    readonly defined: false;
}) | (TrpcError<"UNAUTHORIZED", undefined> & {
    readonly defined: false;
}) | (TrpcError<"PARSE_ERROR", undefined> & {
    readonly defined: false;
}) | (TrpcError<"UNSUPPORTED_PROTOCOL", undefined> & {
    readonly defined: false;
}) | (TrpcError<"PAYMENT_REQUIRED", undefined> & {
    readonly defined: false;
}) | ... 21 more ... | (TrpcError<...> & {
    ...;
}), {
    ...;
}, undefined>(host: ReactiveControllerHost, options: Accessor<...>, queryClient?: QueryClient): MutationResultAccessor<...>
createMutationController
(this, () =>
this.
PostView.trpc: TrpcQueryUtilsFor<{
    post: {
        byId: Procedure<{
            type: "query";
            ctx: Context;
            meta: {};
            input: {
                id: string;
            };
            output: Post;
            errors: TrpcError<"NOT_FOUND", {
                id: string;
            }> | SchemaValidationError<ZodObject<{
                id: ZodString;
            }, $strip>>;
            services: never;
        }>;
        list: Procedure<{
            type: "query";
            ctx: Context;
            meta: {};
            input: undefined;
            output: Post[];
            errors: never;
            services: never;
        }>;
        create: Procedure<{
            type: "mutation";
            ctx: Context;
            meta: {};
            input: {
                title: string;
            };
            output: Post;
            errors: TrpcError<...> | SchemaValidationError<...>;
            services: never;
        }>;
    };
}, {}, {}>
trpc
.
post: TrpcQueryUtils<ClientRouter<{
    byId: Procedure<{
        type: "query";
        ctx: Context;
        meta: {};
        input: {
            id: string;
        };
        output: Post;
        errors: TrpcError<"NOT_FOUND", {
            id: string;
        }> | SchemaValidationError<ZodObject<{
            id: ZodString;
        }, $strip>>;
        services: never;
    }>;
    list: Procedure<{
        type: "query";
        ctx: Context;
        meta: {};
        input: undefined;
        output: Post[];
        errors: never;
        services: never;
    }>;
    create: Procedure<{
        type: "mutation";
        ctx: Context;
        meta: {};
        input: {
            title: string;
        };
        output: Post;
        errors: TrpcError<...> | SchemaValidationError<...>;
        services: never;
    }>;
}, {}, undefined, {}>>
post
.
create: MutationProcedureUtils<{
    ...;
}, {
    id: string;
    title: string;
    author: string | null;
    createdAt: string;
}, NonNullable<...>, Omit<...>>
create
.
MutationProcedureUtils<{ title: string; }, { id: string; title: string; author: string | null; createdAt: string; }, NonNullable<UndeclaredError | (TrpcError<"NOT_FOUND", undefined> & { ...; }) | ... 25 more ... | (TrpcError<...> & { ...; })>, Omit<...>>.mutationOptions<undefined>(opts?: (ContextBag<Omit<NonNullable<{
    signal?: AbortSignal | undefined;
} & BuiltinCallOptions>, "signal" | "lastEventId">> & MutationOptionsIn<{
    title: string;
}, {
    id: string;
    title: string;
    author: string | null;
    createdAt: string;
}, NonNullable<UndeclaredError | (TrpcError<"NOT_FOUND", undefined> & {
    readonly defined: false;
}) | (TrpcError<"BAD_REQUEST", undefined> & {
    readonly defined: false;
}) | (TrpcError<"UNAUTHORIZED", undefined> & {
    readonly defined: false;
}) | ... 23 more ... | (TrpcError<...> & {
    ...;
})>, undefined>) | undefined): MutationOptionsOut<...>
mutationOptions
(),
); override PostView.render(): TemplateResult<1>render() { return const html: (strings: TemplateStringsArray, ...values: unknown[]) => TemplateResult<1>html` <h1>${this.
PostView.post: () => QueryObserverResult<{
    id: string;
    title: string;
    author: string | null;
    createdAt: string;
}, NonNullable<UndeclaredError | (TrpcError<"NOT_FOUND", {
    id: string;
}> & {
    readonly defined: true;
}) | (TrpcError<"BAD_REQUEST", SchemaInputErrorData<ZodObject<{
    id: ZodString;
}, $strip>>> & {
    readonly defined: true;
}) | (TrpcError<"NOT_FOUND", undefined> & {
    readonly defined: false;
}) | (TrpcError<"BAD_REQUEST", undefined> & {
    readonly defined: false;
}) | ... 22 more ... | (TrpcError<...> & {
    readonly defined: false;
})>>
post
().
data: {
    id: string;
    title: string;
    author: string | null;
    createdAt: string;
} | undefined
data
?.title: string | undefinedtitle}</h1>
<button @click=${() => this.
PostView.create: () => MutationObserverResult<{
    id: string;
    title: string;
    author: string | null;
    createdAt: string;
}, (TrpcError<"NOT_FOUND", undefined> & {
    readonly defined: false;
}) | (TrpcError<"BAD_REQUEST", undefined> & {
    readonly defined: false;
}) | (TrpcError<"UNAUTHORIZED", undefined> & {
    readonly defined: false;
}) | (TrpcError<"PARSE_ERROR", undefined> & {
    readonly defined: false;
}) | (TrpcError<"UNSUPPORTED_PROTOCOL", undefined> & {
    readonly defined: false;
}) | (TrpcError<"PAYMENT_REQUIRED", undefined> & {
    readonly defined: false;
}) | ... 21 more ... | (TrpcError<...> & {
    ...;
}), {
    ...;
}, undefined>
create
().
MutationObserverBaseResult<TData = unknown, TError = Error, TVariables = void, TOnMutateResult = unknown>.mutate: (variables: {
    title: string;
}, options?: MutateOptions<{
    id: string;
    title: string;
    author: string | null;
    createdAt: string;
}, (TrpcError<"NOT_FOUND", undefined> & {
    readonly defined: false;
}) | (TrpcError<"BAD_REQUEST", undefined> & {
    readonly defined: false;
}) | (TrpcError<"UNAUTHORIZED", undefined> & {
    readonly defined: false;
}) | (TrpcError<"PARSE_ERROR", undefined> & {
    readonly defined: false;
}) | (TrpcError<"UNSUPPORTED_PROTOCOL", undefined> & {
    readonly defined: false;
}) | (TrpcError<"PAYMENT_REQUIRED", undefined> & {
    readonly defined: false;
}) | ... 21 more ... | (TrpcError<...> & {
    ...;
}), {
    title: string;
}, undefined> | undefined) => Promise<...>
mutate
({ title: stringtitle: 'New' })}>
New post </button> `; } } var customElements: CustomElementRegistrycustomElements.CustomElementRegistry.define(name: string, constructor: CustomElementConstructor, options?: ElementDefinitionOptions): voiddefine('post-view', class PostViewPostView);

Subscriptions

createSubscriptionController subscribes while the host is connected, and not during SSR. Call it (or read current) in render for status, data (the latest event) and error; it has reset(), and destroy() removes it from the host. Pass a function so the options are read again on each update, and a new input restarts the subscription:

class class TickerTicker extends class LitElementLitElement {
  static override 
Ticker.properties: {
    from: {};
}
properties
= { from: {}from: {} };
declare Ticker.from: numberfrom: number;
Ticker.trpc: TrpcQueryUtilsFor<{
    clock: {
        ticks: Procedure<{
            type: "subscription";
            ctx: Context;
            meta: {};
            input: {
                from: number;
            };
            output: number;
            errors: SchemaValidationError<z.ZodObject<{
                from: z.ZodNumber;
            }, z.core.$strip>>;
            services: never;
        }>;
    };
}, {}, {}>
trpc
=
const useTrpc: (host: ReactiveElement) => TrpcQueryUtilsFor<{
    clock: {
        ticks: Procedure<{
            type: "subscription";
            ctx: Context;
            meta: {};
            input: {
                from: number;
            };
            output: number;
            errors: SchemaValidationError<z.ZodObject<{
                from: z.ZodNumber;
            }, z.core.$strip>>;
            services: never;
        }>;
    };
}, {}, {}>
useTrpc
(this);
Ticker.ticks: SubscriptionResultAccessor<number, NonNullable<UndeclaredError | (TrpcError<"BAD_REQUEST", SchemaInputErrorData<z.ZodObject<{
    from: z.ZodNumber;
}, z.core.$strip>>> & {
    readonly defined: true;
}) | (TrpcError<"BAD_REQUEST", undefined> & {
    readonly defined: false;
}) | (TrpcError<"PARSE_ERROR", undefined> & {
    readonly defined: false;
}) | (TrpcError<"UNSUPPORTED_PROTOCOL", undefined> & {
    readonly defined: false;
}) | (TrpcError<"UNAUTHORIZED", undefined> & {
    readonly defined: false;
}) | ... 20 more ... | (TrpcError<...> & {
    readonly defined: false;
})>>
ticks
=
createSubscriptionController<number, NonNullable<UndeclaredError | (TrpcError<"BAD_REQUEST", SchemaInputErrorData<z.ZodObject<{
    from: z.ZodNumber;
}, z.core.$strip>>> & {
    readonly defined: true;
}) | (TrpcError<"BAD_REQUEST", undefined> & {
    readonly defined: false;
}) | (TrpcError<"PARSE_ERROR", undefined> & {
    readonly defined: false;
}) | (TrpcError<"UNSUPPORTED_PROTOCOL", undefined> & {
    readonly defined: false;
}) | (TrpcError<"UNAUTHORIZED", undefined> & {
    readonly defined: false;
}) | ... 20 more ... | (TrpcError<...> & {
    readonly defined: false;
})>>(host: ReactiveControllerHost, options: OptionsOrFn<...>): SubscriptionResultAccessor<...>
createSubscriptionController
(this, () =>
this.
Ticker.trpc: TrpcQueryUtilsFor<{
    clock: {
        ticks: Procedure<{
            type: "subscription";
            ctx: Context;
            meta: {};
            input: {
                from: number;
            };
            output: number;
            errors: SchemaValidationError<z.ZodObject<{
                from: z.ZodNumber;
            }, z.core.$strip>>;
            services: never;
        }>;
    };
}, {}, {}>
trpc
.
clock: TrpcQueryUtils<ClientRouter<{
    ticks: Procedure<{
        type: "subscription";
        ctx: Context;
        meta: {};
        input: {
            from: number;
        };
        output: number;
        errors: SchemaValidationError<z.ZodObject<{
            from: z.ZodNumber;
        }, z.core.$strip>>;
        services: never;
    }>;
}, {}, undefined, {}>>
clock
.
ticks: SubscriptionProcedureUtils<{
    from: number;
}, number, NonNullable<UndeclaredError | (TrpcError<"BAD_REQUEST", SchemaInputErrorData<z.ZodObject<{
    from: z.ZodNumber;
}, z.core.$strip>>> & {
    readonly defined: true;
}) | (TrpcError<"BAD_REQUEST", undefined> & {
    readonly defined: false;
}) | (TrpcError<"PARSE_ERROR", undefined> & {
    readonly defined: false;
}) | (TrpcError<"UNSUPPORTED_PROTOCOL", undefined> & {
    readonly defined: false;
}) | (TrpcError<"UNAUTHORIZED", undefined> & {
    readonly defined: false;
}) | ... 20 more ... | (TrpcError<...> & {
    readonly defined: false;
})>, Omit<...>>
ticks
.
SubscriptionProcedureUtils<{ from: number; }, number, NonNullable<UndeclaredError | (TrpcError<"BAD_REQUEST", SchemaInputErrorData<ZodObject<{ from: ZodNumber; }, $strip>>> & { ...; }) | ... 24 more ... | (TrpcError<...> & { ...; })>, Omit<...>>.subscriptionOptions(opts: {
    input: {
        from: number;
    } | unique symbol;
} & ContextBag<Omit<NonNullable<{
    signal?: AbortSignal | undefined;
} & BuiltinCallOptions & {
    lastEventId?: string | undefined;
}>, "signal" | "lastEventId">> & {
    enabled?: boolean | undefined;
} & SubscriptionCallbacks<number, NonNullable<UndeclaredError | (TrpcError<"BAD_REQUEST", SchemaInputErrorData<z.ZodObject<{
    from: z.ZodNumber;
}, z.core.$strip>>> & {
    readonly defined: true;
}) | (TrpcError<"BAD_REQUEST", undefined> & {
    ...;
}) | ... 23 more ... | (TrpcError<...> & {
    ...;
})>>): TrpcSubscriptionOptions<...>
subscriptionOptions
({
input: {
    from: number;
} | unique symbol
input
: { from: numberfrom: this.Ticker.from: numberfrom } }),
); override Ticker.render(): TemplateResult<1>render() { return const html: (strings: TemplateStringsArray, ...values: unknown[]) => TemplateResult<1>html`<p>${this.
Ticker.ticks: () => SubscriptionResult<number, NonNullable<UndeclaredError | (TrpcError<"BAD_REQUEST", SchemaInputErrorData<z.ZodObject<{
    from: z.ZodNumber;
}, z.core.$strip>>> & {
    readonly defined: true;
}) | (TrpcError<"BAD_REQUEST", undefined> & {
    readonly defined: false;
}) | (TrpcError<"PARSE_ERROR", undefined> & {
    readonly defined: false;
}) | (TrpcError<"UNSUPPORTED_PROTOCOL", undefined> & {
    readonly defined: false;
}) | (TrpcError<"UNAUTHORIZED", undefined> & {
    readonly defined: false;
}) | ... 20 more ... | (TrpcError<...> & {
    readonly defined: false;
})>>
ticks
().data: number | undefineddata}</p>`;
} }

What subscriptions share, and the query-cache forms (liveOptions(), streamedOptions()), are in Subscriptions.