orpc-fn 0.8.0 → 0.9.0

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.
Files changed (144) hide show
  1. package/README.md +66 -28
  2. package/dist/assemble-procedure.d.ts.map +1 -1
  3. package/dist/assemble-procedure.js +3 -1
  4. package/dist/assemble-procedure.js.map +1 -1
  5. package/dist/client.d.ts +13 -3
  6. package/dist/client.d.ts.map +1 -1
  7. package/dist/client.js +21 -1
  8. package/dist/client.js.map +1 -1
  9. package/dist/create-fn.d.ts +63 -5
  10. package/dist/create-fn.d.ts.map +1 -1
  11. package/dist/create-fn.js +45 -16
  12. package/dist/create-fn.js.map +1 -1
  13. package/dist/expected-client-error.d.ts +6 -0
  14. package/dist/expected-client-error.d.ts.map +1 -1
  15. package/dist/expected-client-error.js +16 -0
  16. package/dist/expected-client-error.js.map +1 -1
  17. package/dist/hono.d.ts +44 -22
  18. package/dist/hono.d.ts.map +1 -1
  19. package/dist/hono.js +51 -20
  20. package/dist/hono.js.map +1 -1
  21. package/dist/index.d.ts +1 -2
  22. package/dist/index.d.ts.map +1 -1
  23. package/dist/index.js +0 -1
  24. package/dist/index.js.map +1 -1
  25. package/dist/issues.d.ts +12 -0
  26. package/dist/issues.d.ts.map +1 -0
  27. package/dist/issues.js +22 -0
  28. package/dist/issues.js.map +1 -0
  29. package/dist/json-schema.d.ts +3 -6
  30. package/dist/json-schema.d.ts.map +1 -1
  31. package/dist/json-schema.js +12 -7
  32. package/dist/json-schema.js.map +1 -1
  33. package/dist/live/codec.d.ts +2 -0
  34. package/dist/live/codec.d.ts.map +1 -1
  35. package/dist/live/codec.js +21 -16
  36. package/dist/live/codec.js.map +1 -1
  37. package/dist/live/fn-live.d.ts +6 -19
  38. package/dist/live/fn-live.d.ts.map +1 -1
  39. package/dist/live/fn-live.js +15 -23
  40. package/dist/live/fn-live.js.map +1 -1
  41. package/dist/live/index.d.ts +2 -2
  42. package/dist/live/index.d.ts.map +1 -1
  43. package/dist/live/index.js +1 -1
  44. package/dist/live/index.js.map +1 -1
  45. package/dist/live/memory.d.ts +11 -1
  46. package/dist/live/memory.d.ts.map +1 -1
  47. package/dist/live/memory.js +14 -1
  48. package/dist/live/memory.js.map +1 -1
  49. package/dist/live/pub-sub.d.ts +50 -8
  50. package/dist/live/pub-sub.d.ts.map +1 -1
  51. package/dist/live/pub-sub.js +79 -26
  52. package/dist/live/pub-sub.js.map +1 -1
  53. package/dist/live/redis-bun.d.ts +6 -1
  54. package/dist/live/redis-bun.d.ts.map +1 -1
  55. package/dist/live/redis-bun.js +10 -1
  56. package/dist/live/redis-bun.js.map +1 -1
  57. package/dist/live/scoped-change-bus.d.ts +3 -1
  58. package/dist/live/scoped-change-bus.d.ts.map +1 -1
  59. package/dist/live/scoped-change-bus.js +3 -0
  60. package/dist/live/scoped-change-bus.js.map +1 -1
  61. package/dist/mastra.d.ts +8 -3
  62. package/dist/mastra.d.ts.map +1 -1
  63. package/dist/mastra.js +8 -1
  64. package/dist/mastra.js.map +1 -1
  65. package/dist/mcp/core.d.ts +31 -14
  66. package/dist/mcp/core.d.ts.map +1 -1
  67. package/dist/mcp/core.js +39 -20
  68. package/dist/mcp/core.js.map +1 -1
  69. package/dist/mcp/sdk.d.ts +6 -2
  70. package/dist/mcp/sdk.d.ts.map +1 -1
  71. package/dist/mcp/sdk.js +9 -3
  72. package/dist/mcp/sdk.js.map +1 -1
  73. package/dist/mcp/server.d.ts +6 -2
  74. package/dist/mcp/server.d.ts.map +1 -1
  75. package/dist/mcp/server.js +9 -3
  76. package/dist/mcp/server.js.map +1 -1
  77. package/dist/mcp.d.ts +3 -7
  78. package/dist/mcp.d.ts.map +1 -1
  79. package/dist/mcp.js +4 -6
  80. package/dist/mcp.js.map +1 -1
  81. package/dist/meta.d.ts +14 -2
  82. package/dist/meta.d.ts.map +1 -1
  83. package/dist/meta.js +6 -2
  84. package/dist/meta.js.map +1 -1
  85. package/dist/otel.d.ts +16 -4
  86. package/dist/otel.d.ts.map +1 -1
  87. package/dist/otel.js +40 -10
  88. package/dist/otel.js.map +1 -1
  89. package/dist/react.d.ts +6 -1
  90. package/dist/react.d.ts.map +1 -1
  91. package/dist/react.js +5 -1
  92. package/dist/react.js.map +1 -1
  93. package/dist/route-options.d.ts.map +1 -1
  94. package/dist/route-options.js +4 -0
  95. package/dist/route-options.js.map +1 -1
  96. package/dist/stream-call.d.ts +15 -0
  97. package/dist/stream-call.d.ts.map +1 -0
  98. package/dist/stream-call.js +13 -0
  99. package/dist/stream-call.js.map +1 -0
  100. package/dist/timing.d.ts +2 -0
  101. package/dist/timing.d.ts.map +1 -1
  102. package/dist/timing.js +2 -0
  103. package/dist/timing.js.map +1 -1
  104. package/dist/tool-errors.d.ts +24 -0
  105. package/dist/tool-errors.d.ts.map +1 -0
  106. package/dist/tool-errors.js +36 -0
  107. package/dist/tool-errors.js.map +1 -0
  108. package/dist/types.d.ts +2 -0
  109. package/dist/types.d.ts.map +1 -1
  110. package/dist/types.js.map +1 -1
  111. package/dist/vue.d.ts +47 -4
  112. package/dist/vue.d.ts.map +1 -1
  113. package/dist/vue.js +39 -9
  114. package/dist/vue.js.map +1 -1
  115. package/package.json +1 -1
  116. package/src/assemble-procedure.ts +3 -1
  117. package/src/client.ts +26 -2
  118. package/src/create-fn.ts +149 -19
  119. package/src/expected-client-error.ts +19 -0
  120. package/src/hono.ts +120 -41
  121. package/src/index.ts +3 -2
  122. package/src/issues.ts +35 -0
  123. package/src/json-schema.ts +16 -10
  124. package/src/live/codec.ts +21 -19
  125. package/src/live/fn-live.ts +18 -36
  126. package/src/live/index.ts +2 -2
  127. package/src/live/memory.ts +22 -1
  128. package/src/live/pub-sub.ts +142 -37
  129. package/src/live/redis-bun.ts +23 -2
  130. package/src/live/scoped-change-bus.ts +10 -1
  131. package/src/mastra.ts +10 -4
  132. package/src/mcp/core.ts +76 -29
  133. package/src/mcp/sdk.ts +27 -2
  134. package/src/mcp/server.ts +27 -2
  135. package/src/mcp.ts +5 -16
  136. package/src/meta.ts +28 -4
  137. package/src/otel.ts +41 -9
  138. package/src/react.ts +10 -3
  139. package/src/route-options.ts +8 -0
  140. package/src/stream-call.ts +15 -0
  141. package/src/timing.ts +3 -0
  142. package/src/tool-errors.ts +52 -0
  143. package/src/types.ts +2 -0
  144. package/src/vue.ts +92 -19
package/dist/vue.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"vue.js","sourceRoot":"","sources":["../src/vue.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n\ttype DefaultError,\n\ttype FetchQueryOptions,\n\tfocusManager,\n\thashKey,\n\ttype InferDataFromTag,\n\ttype InfiniteData,\n\ttype InvalidateQueryFilters,\n\ttype MutationObserverOptions,\n\ttype UseInfiniteQueryOptions,\n\ttype UseInfiniteQueryReturnType,\n\ttype UseMutationReturnType,\n\ttype UseQueryReturnType,\n\ttype Updater,\n\tkeepPreviousData,\n\ttype QueryKey,\n\ttype UseQueryOptions,\n\tuseInfiniteQuery as useVueInfiniteQuery,\n\tuseMutation as useVueMutation,\n\tuseQuery as useVueQuery,\n\tuseQueryClient\n} from '@tanstack/vue-query'\nimport {\n\ttype App,\n\tcomputed,\n\tgetCurrentScope,\n\thasInjectionContext,\n\ttype InjectionKey,\n\tinject,\n\ttype MaybeRefOrGetter,\n\tonScopeDispose,\n\ttype Ref,\n\tref,\n\tshallowRef,\n\ttoValue,\n\twatch\n} from 'vue'\nimport { userFacingErrorMessage } from './client.js'\nimport {\n\tcreateInvalidationCoordinator,\n\tcreateStreamScope,\n\tcreateSubscriptionRunner,\n\ttype InvalidationStreamOptions,\n\ttype LiveConnectionStatus,\n\tseedQueryFn\n} from './realtime.js'\n\nexport type { InvalidationDomain, LiveConnectionStatus } from './realtime.js'\n\n/**\n * Register your client types once so every composable infers them:\n *\n * ```ts\n * declare module 'orpc-fn/vue' {\n * interface Register { utils: typeof orpc; client: typeof client }\n * }\n * ```\n */\n// biome-ignore lint/suspicious/noEmptyInterface: filled in by app module augmentation\nexport interface Register {}\n\nexport type RegisteredOrpcUtils = Register extends { utils: infer T }\n\t? T\n\t: {\n\t\t\t'orpc-fn/vue: register your utils with `declare module \"orpc-fn/vue\" { interface Register { utils: typeof orpc } }`, or pass `orpc`': never\n\t\t}\nexport type RegisteredOrpcClient = Register extends { client: infer T }\n\t? T\n\t: unknown\n\n/** An explicit `<TData>`, else the data type oRPC tagged on the key. */\ntype CachedData<TData, TKey extends QueryKey> = [TData] extends [never]\n\t? InferDataFromTag<unknown, TKey>\n\t: TData\n\ntype ProvidedOrpc = { client: unknown; utils: unknown }\nconst orpcKey: InjectionKey<ProvidedOrpc> = Symbol('orpc-fn')\n\n/**\n * Make an oRPC client and its TanStack Query utils the app's default. A\n * surface that talks to another API (an embed with its own auth) passes\n * `orpc` to each composable instead and never needs this.\n */\nexport function provideOrpc<TClient, TUtils>(\n\tapp: App,\n\torpc: { client: TClient; utils: TUtils }\n): void {\n\tapp.provide(orpcKey, orpc)\n}\n\nconst missingOrpc = () =>\n\tnew Error(\n\t\t'orpc-fn/vue: no oRPC client provided. Call provideOrpc(app, { client, utils }) or pass `orpc` to the composable.'\n\t)\n\n/** The client and utils from {@link provideOrpc}. */\nexport function useOrpc(): {\n\tclient: RegisteredOrpcClient\n\tutils: RegisteredOrpcUtils\n} {\n\tconst provided = hasInjectionContext() ? inject(orpcKey, null) : null\n\tif (!provided) throw missingOrpc()\n\treturn provided as {\n\t\tclient: RegisteredOrpcClient\n\t\tutils: RegisteredOrpcUtils\n\t}\n}\n\n/** Resolve the provided utils now; fail only when they are needed and missing. */\nfunction useUtilsGetter<TOrpc>(\n\texplicit: MaybeRefOrGetter<TOrpc> | undefined\n): () => TOrpc {\n\tif (explicit) return () => toValue(explicit)\n\tconst provided = hasInjectionContext() ? inject(orpcKey, null) : null\n\treturn () => {\n\t\tif (!provided) throw missingOrpc()\n\t\treturn provided.utils as TOrpc\n\t}\n}\n\nlet documentVisible: Ref<boolean> | null = null\n/**\n * Whether the page is visible, from TanStack's `focusManager` (which follows\n * `visibilitychange` in browsers). Live streams pause while it is false.\n */\nfunction useDocumentVisible(): Ref<boolean> {\n\tif (!documentVisible) {\n\t\tconst visible = ref(focusManager.isFocused())\n\t\tfocusManager.subscribe((focused) => {\n\t\t\tvisible.value = focused\n\t\t})\n\t\tdocumentVisible = visible\n\t}\n\treturn documentVisible\n}\n\nfunction resolveQueryEnabled(enabled: unknown): boolean {\n\tif (enabled === undefined) return true\n\tif (typeof enabled === 'function') return Boolean(enabled())\n\treturn Boolean(toValue(enabled))\n}\n\n/**\n * Picks the stream to open from the utils. A procedure's `call` fits as is:\n * `(o) => o.order.watch.call`. The composable passes the input and an abort signal.\n */\nexport type OrpcSubscribeFn<TInput, TEvent, TOrpc = RegisteredOrpcUtils> = (\n\torpc: TOrpc\n) => (\n\tinput: TInput,\n\toptions: { signal: AbortSignal }\n) => Promise<AsyncIterable<TEvent>>\n\nexport interface UseSubscriptionOptions<TEvent, TOrpc = RegisteredOrpcUtils> {\n\t/** Start the stream on its own (default: true). With false, call `connect()`. */\n\timmediate?: MaybeRefOrGetter<boolean> | undefined\n\tonEvent?: (event: TEvent, meta?: { connectionId: number }) => void\n\tonError?: ((error: Error) => void) | undefined\n\t/** Every successful connect; `connectionId > 1` is a reconnect. */\n\tonConnect?: (connectionId: number) => void\n\tonClose?: () => void\n\t/** Events kept in `events` (default: 100). 1 keeps only `latestEvent`. */\n\tmaxEvents?: number\n\t/** Reconnect when the input changes (default: true). */\n\tautoReconnectOnInputChange?: boolean\n\t/**\n\t * After a connect, reconnect with backoff when the stream ends or errors\n\t * unexpectedly (proxy idle timeout, network blip). Deliberate teardown\n\t * does not retry. Default: true.\n\t */\n\tautoReconnectOnClose?: boolean\n\torpc?: MaybeRefOrGetter<TOrpc> | undefined\n\t/**\n\t * Close the stream while the page is hidden (default: true), so a\n\t * background tab holds no server connection. It reconnects, and a live\n\t * route re-sends its snapshot, when the page is visible again.\n\t */\n\trespectVisibility?: boolean | undefined\n}\n\nexport interface UseSubscriptionReturn<TEvent> {\n\tevents: Ref<TEvent[]>\n\tlatestEvent: Ref<TEvent | undefined>\n\tstatus: Ref<LiveConnectionStatus>\n\terror: Ref<Error | null>\n\tisConnected: Ref<boolean>\n\tconnect: () => Promise<void>\n\tdisconnect: () => Promise<void>\n\tclearEvents: () => void\n}\n\n/**\n * An oRPC event iterator as reactive state, with backoff reconnects and a\n * pause while the page is hidden. Closed when the owning effect scope stops.\n */\nexport function useOrpcSubscription<\n\tTInput,\n\tTEvent,\n\tTOrpc = RegisteredOrpcUtils\n>(\n\tinput: MaybeRefOrGetter<TInput>,\n\tsubscribeFn: OrpcSubscribeFn<TInput, TEvent, TOrpc>,\n\toptions: UseSubscriptionOptions<TEvent, TOrpc> = {}\n): UseSubscriptionReturn<TEvent> {\n\tconst {\n\t\timmediate = true,\n\t\tmaxEvents = 100,\n\t\tautoReconnectOnInputChange = true,\n\t\tautoReconnectOnClose = true,\n\t\trespectVisibility = true\n\t} = options\n\tconst getUtils = useUtilsGetter(options.orpc)\n\tconst visible = useDocumentVisible()\n\n\t// May a stream run at all? This gates a manual connect() too.\n\tconst isStreamAllowed = computed(() => !respectVisibility || visible.value)\n\t// Should it start on its own? That is what `immediate` means.\n\tconst shouldAutoConnect = computed(\n\t\t() => toValue(immediate) && isStreamAllowed.value\n\t)\n\n\t// Shallow: event payloads are replaced, never mutated, so deep proxies are wasted work.\n\tconst events = shallowRef<TEvent[]>([])\n\tconst latestEvent = shallowRef<TEvent | undefined>(undefined)\n\tconst status = ref<LiveConnectionStatus>('idle')\n\tconst error = ref<Error | null>(null)\n\n\tconst runner = createSubscriptionRunner<TEvent>({\n\t\topen: (signal) => subscribeFn(getUtils())(toValue(input), { signal }),\n\t\tcanConnect: () => isStreamAllowed.value,\n\t\tshouldReconnect: () => autoReconnectOnClose && shouldAutoConnect.value,\n\t\tonStatus: (next) => {\n\t\t\tstatus.value = next\n\t\t\tif (next === 'connecting') error.value = null\n\t\t},\n\t\tonEvent: (event, connectionId) => {\n\t\t\tlatestEvent.value = event\n\t\t\tif (maxEvents > 1) {\n\t\t\t\tevents.value = [...events.value.slice(-(maxEvents - 1)), event]\n\t\t\t}\n\t\t\toptions.onEvent?.(event, { connectionId })\n\t\t},\n\t\tonError: (err) => {\n\t\t\terror.value = err\n\t\t\toptions.onError?.(err)\n\t\t},\n\t\tonConnect: options.onConnect,\n\t\tonClose: options.onClose\n\t})\n\n\tfunction clearEvents() {\n\t\tevents.value = []\n\t\tlatestEvent.value = undefined\n\t}\n\n\tif (autoReconnectOnInputChange) {\n\t\twatch(\n\t\t\t() => toValue(input),\n\t\t\tasync () => {\n\t\t\t\tconst wasLive = runner.isLive()\n\t\t\t\tif (runner.getStatus() !== 'idle') {\n\t\t\t\t\tawait runner.disconnect()\n\t\t\t\t\tclearEvents()\n\t\t\t\t}\n\t\t\t\t// Reconnect in auto mode, or in manual mode when it was running.\n\t\t\t\tif (shouldAutoConnect.value || (wasLive && isStreamAllowed.value)) {\n\t\t\t\t\tawait runner.start()\n\t\t\t\t}\n\t\t\t},\n\t\t\t{ deep: true }\n\t\t)\n\t}\n\n\t// Visibility closes the stream in both modes; only the re-open waits for `immediate`.\n\twatch(\n\t\tisStreamAllowed,\n\t\t(allowed) => {\n\t\t\tif (!allowed) void runner.disconnect()\n\t\t\telse if (toValue(immediate)) {\n\t\t\t\terror.value = null\n\t\t\t\tvoid runner.start()\n\t\t\t}\n\t\t},\n\t\t{ immediate: true }\n\t)\n\n\twatch(\n\t\t() => toValue(immediate),\n\t\t(auto) => {\n\t\t\tif (!auto) void runner.disconnect()\n\t\t\telse if (isStreamAllowed.value) {\n\t\t\t\terror.value = null\n\t\t\t\tvoid runner.start()\n\t\t\t}\n\t\t}\n\t)\n\n\t// A detached effect scope may own the stream, not just a component.\n\tif (getCurrentScope()) onScopeDispose(() => void runner.dispose())\n\n\treturn {\n\t\tevents,\n\t\tlatestEvent,\n\t\tstatus,\n\t\terror,\n\t\tisConnected: computed(() => status.value === 'connected'),\n\t\tconnect: runner.connect,\n\t\tdisconnect: runner.disconnect,\n\t\tclearEvents\n\t}\n}\n\n/** What {@link useApiClient} returns, e.g. `ApiClient['invalidate']` for a helper. */\nexport type ApiClient<TOrpc = RegisteredOrpcUtils> = ReturnType<\n\ttypeof useBoundApiClient<TOrpc>\n>\n\n/**\n * TanStack Query composables that receive the oRPC utils, so call sites read\n * `useQuery((o) => o.order.get.queryOptions({ input }))`. Pass `orpc` to bind\n * another client than the provided one.\n */\nexport function useApiClient<TOrpc = RegisteredOrpcUtils>(clientOptions?: {\n\torpc?: MaybeRefOrGetter<TOrpc> | undefined\n}): ApiClient<TOrpc>\n// `ReturnType<typeof useApiClient>` reads the last overload: the registered utils.\nexport function useApiClient(): ApiClient\nexport function useApiClient<TOrpc>(clientOptions?: {\n\torpc?: MaybeRefOrGetter<TOrpc> | undefined\n}): ApiClient<TOrpc> {\n\treturn useBoundApiClient(clientOptions?.orpc)\n}\n\nfunction useBoundApiClient<TOrpc>(orpc: MaybeRefOrGetter<TOrpc> | undefined) {\n\tconst queryClient = useQueryClient()\n\tconst getO = useUtilsGetter(orpc)\n\n\t// Each wrapper forwards TanStack's own generics, so `select`, typed errors,\n\t// page params and oRPC's tagged keys infer exactly as with vue-query itself.\n\tfunction useQuery<TQueryFnData, TError = DefaultError, TData = TQueryFnData>(\n\t\toptionsFn: (\n\t\t\torpc: TOrpc\n\t\t) => UseQueryOptions<TQueryFnData, TError, TData, TQueryFnData>\n\t): UseQueryReturnType<TData, TError> {\n\t\t// A computed is a ref at runtime; TypeScript cannot relate a computed of\n\t\t// the generic options to vue-query's MaybeRef parameter, so it is asserted.\n\t\tconst options = computed(() => optionsFn(getO()))\n\t\treturn useVueQuery<TQueryFnData, TError, TData>(\n\t\t\toptions as unknown as UseQueryOptions<\n\t\t\t\tTQueryFnData,\n\t\t\t\tTError,\n\t\t\t\tTData,\n\t\t\t\tTQueryFnData\n\t\t\t>\n\t\t)\n\t}\n\n\t/** `useInfiniteQuery((o) => o.order.list.infiniteOptions({ input, initialPageParam, getNextPageParam }))` */\n\tfunction useInfiniteQuery<\n\t\tTQueryFnData,\n\t\tTError = DefaultError,\n\t\tTData = InfiniteData<TQueryFnData>,\n\t\tTQueryKey extends QueryKey = QueryKey,\n\t\tTPageParam = unknown\n\t>(\n\t\toptionsFn: (\n\t\t\torpc: TOrpc\n\t\t) => UseInfiniteQueryOptions<\n\t\t\tTQueryFnData,\n\t\t\tTError,\n\t\t\tTData,\n\t\t\tTQueryKey,\n\t\t\tTPageParam\n\t\t>\n\t): UseInfiniteQueryReturnType<TData, TError> {\n\t\tconst options = computed(() => optionsFn(getO()))\n\t\treturn useVueInfiniteQuery<\n\t\t\tTQueryFnData,\n\t\t\tTError,\n\t\t\tTData,\n\t\t\tTQueryKey,\n\t\t\tTPageParam\n\t\t>(\n\t\t\toptions as unknown as UseInfiniteQueryOptions<\n\t\t\t\tTQueryFnData,\n\t\t\t\tTError,\n\t\t\t\tTData,\n\t\t\t\tTQueryKey,\n\t\t\t\tTPageParam\n\t\t\t>\n\t\t)\n\t}\n\n\t/**\n\t * With `initialInput`, also returns `inputData`, a ref that `mutate()` and\n\t * `mutateAsync()` use when called without variables (form state).\n\t */\n\t// The input type comes from the route alone; `initialInput` is only checked\n\t// against it. `unknown`, not `void`, lets `initialInput` pass the first\n\t// inference pass, which runs before the `(o) => ...` callback is read.\n\tfunction useMutation<\n\t\tTData = unknown,\n\t\tTError = DefaultError,\n\t\tTVariables = unknown,\n\t\tTContext = unknown\n\t>(\n\t\toptionsFn: (\n\t\t\torpc: TOrpc\n\t\t) => MutationObserverOptions<TData, TError, TVariables, TContext>,\n\t\tconfig: { initialInput: NoInfer<TVariables> }\n\t): UseMutationReturnType<TData, TError, TVariables, TContext> & {\n\t\tinputData: Ref<TVariables>\n\t\tmutate: (variables?: TVariables) => void\n\t\tmutateAsync: (variables?: TVariables) => Promise<TData>\n\t}\n\tfunction useMutation<\n\t\tTData = unknown,\n\t\tTError = DefaultError,\n\t\tTVariables = void,\n\t\tTContext = unknown\n\t>(\n\t\toptionsFn: (\n\t\t\torpc: TOrpc\n\t\t) => MutationObserverOptions<TData, TError, TVariables, TContext>\n\t): UseMutationReturnType<TData, TError, TVariables, TContext>\n\tfunction useMutation<TData, TError, TVariables, TContext>(\n\t\toptionsFn: (\n\t\t\torpc: TOrpc\n\t\t) => MutationObserverOptions<TData, TError, TVariables, TContext>,\n\t\tconfig?: { initialInput: TVariables }\n\t) {\n\t\tconst mutation = useVueMutation(computed(() => optionsFn(getO())))\n\t\tif (config?.initialInput === undefined) return mutation\n\t\tconst inputData = ref(config.initialInput) as Ref<TVariables>\n\t\treturn {\n\t\t\t...mutation,\n\t\t\tinputData,\n\t\t\tmutate: (variables?: TVariables) =>\n\t\t\t\tmutation.mutate(variables ?? inputData.value),\n\t\t\tmutateAsync: (variables?: TVariables) =>\n\t\t\t\tmutation.mutateAsync(variables ?? inputData.value)\n\t\t}\n\t}\n\n\tfunction useSubscription<TInput, TEvent>(\n\t\tinput: MaybeRefOrGetter<TInput>,\n\t\tsubscribeFn: OrpcSubscribeFn<TInput, TEvent, TOrpc>,\n\t\toptions: UseSubscriptionOptions<TEvent, TOrpc> = {}\n\t) {\n\t\treturn useOrpcSubscription<TInput, TEvent, TOrpc>(input, subscribeFn, {\n\t\t\t...options,\n\t\t\torpc: getO\n\t\t})\n\t}\n\n\tconst keyOf = <TKey extends QueryKey>(keyFn: (orpc: TOrpc) => TKey) =>\n\t\tkeyFn(getO())\n\n\treturn {\n\t\t/** The utils themselves, for `queryClient.fetchQuery(orpc.x.queryOptions(...))` and the like. */\n\t\tget orpc(): TOrpc {\n\t\t\treturn getO()\n\t\t},\n\t\tuseQuery,\n\t\tuseInfiniteQuery,\n\t\tuseMutation,\n\t\tuseSubscription,\n\t\tinvalidate: (\n\t\t\tkeyFn: (orpc: TOrpc) => QueryKey,\n\t\t\tfilters?: Omit<InvalidateQueryFilters, 'queryKey'>\n\t\t) => queryClient.invalidateQueries({ queryKey: keyOf(keyFn), ...filters }),\n\t\t/** Route preloading and hover-to-prefetch. */\n\t\tprefetch: <\n\t\t\tTQueryFnData,\n\t\t\tTError = DefaultError,\n\t\t\tTData = TQueryFnData,\n\t\t\tTQueryKey extends QueryKey = QueryKey\n\t\t>(\n\t\t\toptionsFn: (\n\t\t\t\torpc: TOrpc\n\t\t\t) => FetchQueryOptions<TQueryFnData, TError, TData, TQueryKey>\n\t\t) => queryClient.prefetchQuery(optionsFn(getO())),\n\t\t/** Data is typed from oRPC's tagged key; pass `<TData>` for an untagged one. */\n\t\tgetQueryData: <TData = never, TKey extends QueryKey = QueryKey>(\n\t\t\tkeyFn: (orpc: TOrpc) => TKey\n\t\t): CachedData<TData, TKey> | undefined =>\n\t\t\tqueryClient.getQueryData<CachedData<TData, TKey>>(keyOf(keyFn)),\n\t\t/** Optimistic updates, typed like `getQueryData`. */\n\t\tsetQueryData: <TData = never, TKey extends QueryKey = QueryKey>(\n\t\t\tkeyFn: (orpc: TOrpc) => TKey,\n\t\t\tupdater: Updater<\n\t\t\t\tCachedData<TData, TKey> | undefined,\n\t\t\t\tCachedData<TData, TKey> | undefined\n\t\t\t>\n\t\t) =>\n\t\t\tqueryClient.setQueryData<CachedData<TData, TKey>>(keyOf(keyFn), updater),\n\t\tcancelQueries: (keyFn: (orpc: TOrpc) => QueryKey) =>\n\t\t\tqueryClient.cancelQueries({ queryKey: keyOf(keyFn) }),\n\t\tremoveQueries: (keyFn: (orpc: TOrpc) => QueryKey) =>\n\t\t\tqueryClient.removeQueries({ queryKey: keyOf(keyFn) }),\n\t\tisFetching: (keyFn?: (orpc: TOrpc) => QueryKey) =>\n\t\t\tqueryClient.isFetching(keyFn ? { queryKey: keyOf(keyFn) } : {}),\n\t\tqueryClient\n\t}\n}\n\ntype ApplyEvent<TStreamEvent, TData> = (\n\tevent: TStreamEvent,\n\tprevious: TData | undefined\n) => TData | undefined\n\ntype LiveQueryOptions<\n\tTInput,\n\tTRouteData,\n\tTStreamEvent,\n\tTData,\n\tTOrpc,\n\tTSubscriptionInput\n> = {\n\timmediate?: MaybeRefOrGetter<boolean>\n\torpc?: MaybeRefOrGetter<TOrpc>\n\t/** Input for the stream when it differs from the query's. */\n\tsubscriptionInput?: MaybeRefOrGetter<TSubscriptionInput>\n\t/**\n\t * Convert the route output once at fetch time into a differently typed\n\t * cache; `applyEvent` then reduces stream events into that cache.\n\t */\n\tselect?: (data: TRouteData) => TData\n\t/**\n\t * The raw route output of a seed before `select` drops fields. `input` is\n\t * what the seed was fetched for, so a seed that resolves after the input\n\t * moved on can be told apart.\n\t */\n\tonSeed?: (data: TRouteData, input: TInput) => void\n\t/**\n\t * Fold a stream event into the cached data. Required when the stream sends\n\t * something other than the cached type (an `fnLive` patch route, or a\n\t * `select`ed cache). Return `undefined` to skip the write.\n\t */\n\tapplyEvent?: ApplyEvent<TStreamEvent, NoInfer<TData>>\n\tonEvent?: (event: TStreamEvent, meta?: { connectionId: number }) => void\n\tonError?: (error: Error) => void\n\t/**\n\t * Reconcile a fetched seed with what the stream already wrote. The HTTP\n\t * request can resolve last, so a plain overwrite would drop events that\n\t * arrived while it was in flight. Default: take the fetched value.\n\t */\n\tmergeSeed?: (\n\t\tfetched: NoInfer<TData>,\n\t\tcached: NoInfer<TData> | undefined\n\t) => NoInfer<TData>\n\t/**\n\t * Show the previous key's data while a new key loads (default: true). Pass\n\t * false when the key says which entity is shown, not just how it is\n\t * filtered: another conversation's timeline must not stand in for this one.\n\t */\n\tkeepPreviousData?: boolean\n\t/** Pause the stream while the page is hidden (default: true). */\n\trespectVisibility?: boolean\n}\n\ntype LiveQueryReturn<TData, TError> = ReturnType<\n\ttypeof useVueQuery<TData, TError>\n> & { liveStatus: Ref<LiveConnectionStatus> }\n\n/**\n * The client half of `fnLive`: the HTTP query seeds the cache, and the live\n * route's stream writes each snapshot into the same cache entry. Marked\n * `meta.live`, so invalidation streams leave it alone.\n *\n * One signature, not overloads: TypeScript fixes an untyped callback's\n * parameters at the first overload it tries, which made valid calls fail.\n */\nexport function useLiveQuery<\n\tTInput,\n\tTRouteData,\n\tTStreamEvent,\n\tTData = TRouteData,\n\tTError = Error,\n\tTOrpc = RegisteredOrpcUtils,\n\tTSubscriptionInput = TInput\n>(\n\tinput: MaybeRefOrGetter<TInput>,\n\tqueryOptionsFn: (\n\t\tinput: TInput,\n\t\torpc: TOrpc\n\t) => UseQueryOptions<TRouteData, TError> & { queryKey: QueryKey },\n\tsubscribeFn: OrpcSubscribeFn<\n\t\tNoInfer<TSubscriptionInput>,\n\t\tTStreamEvent,\n\t\tTOrpc\n\t>,\n\t...options: [TStreamEvent] extends [TData]\n\t\t? [\n\t\t\t\toptions?: LiveQueryOptions<\n\t\t\t\t\tTInput,\n\t\t\t\t\tTRouteData,\n\t\t\t\t\tTStreamEvent,\n\t\t\t\t\tTData,\n\t\t\t\t\tTOrpc,\n\t\t\t\t\tTSubscriptionInput\n\t\t\t\t>\n\t\t\t]\n\t\t: [\n\t\t\t\toptions: LiveQueryOptions<\n\t\t\t\t\tTInput,\n\t\t\t\t\tTRouteData,\n\t\t\t\t\tTStreamEvent,\n\t\t\t\t\tTData,\n\t\t\t\t\tTOrpc,\n\t\t\t\t\tTSubscriptionInput\n\t\t\t\t> & { applyEvent: ApplyEvent<TStreamEvent, NoInfer<TData>> }\n\t\t\t]\n): LiveQueryReturn<TData, TError>\nexport function useLiveQuery<\n\tTInput,\n\tTRouteData,\n\tTStreamEvent,\n\tTData,\n\tTError,\n\tTOrpc,\n\tTSubscriptionInput\n>(\n\tinput: MaybeRefOrGetter<TInput>,\n\tqueryOptionsFn: (\n\t\tinput: TInput,\n\t\torpc: TOrpc\n\t) => UseQueryOptions<TRouteData, TError> & { queryKey: QueryKey },\n\tsubscribeFn: OrpcSubscribeFn<TSubscriptionInput, TStreamEvent, TOrpc>,\n\toptions: LiveQueryOptions<\n\t\tTInput,\n\t\tTRouteData,\n\t\tTStreamEvent,\n\t\tTData,\n\t\tTOrpc,\n\t\tTSubscriptionInput\n\t> = {}\n): LiveQueryReturn<TData, TError> {\n\tconst queryClient = useQueryClient()\n\tconst getO = useUtilsGetter(options.orpc)\n\tconst visible = useDocumentVisible()\n\t// Without `applyEvent` the stream event is the cache type (the first overload).\n\tconst applyEvent =\n\t\toptions.applyEvent ?? ((event: TStreamEvent) => event as unknown as TData)\n\t// Recomputed when the input changes, not once per stream event.\n\tconst queryKey = computed(\n\t\t() => queryOptionsFn(toValue(input), getO()).queryKey\n\t)\n\tconst queryHash = computed(() => hashKey(queryKey.value))\n\tconst scope = createStreamScope()\n\n\tconst subscription = useOrpcSubscription(\n\t\tcomputed(\n\t\t\t() =>\n\t\t\t\t(options.subscriptionInput === undefined\n\t\t\t\t\t? toValue(input)\n\t\t\t\t\t: toValue(options.subscriptionInput)) as TSubscriptionInput\n\t\t),\n\t\tsubscribeFn,\n\t\t{\n\t\t\timmediate: options.immediate,\n\t\t\trespectVisibility: options.respectVisibility,\n\t\t\tonError: options.onError,\n\t\t\tmaxEvents: 1,\n\t\t\torpc: getO,\n\t\t\tonConnect: (connectionId) => scope.open(connectionId, queryHash.value),\n\t\t\tonEvent: (event, meta) => {\n\t\t\t\t// The consumer callback must not see an event for a scope no longer shown.\n\t\t\t\tif (!meta || !scope.owns(meta.connectionId, queryHash.value)) return\n\t\t\t\tconst key = queryKey.value\n\t\t\t\tconst next = applyEvent(event, queryClient.getQueryData<TData>(key))\n\t\t\t\tif (next !== undefined) queryClient.setQueryData(key, next)\n\t\t\t\toptions.onEvent?.(event, meta)\n\t\t\t}\n\t\t}\n\t)\n\n\tconst query = useVueQuery<TData, TError>(\n\t\tcomputed(() => {\n\t\t\tconst inputValue = toValue(input)\n\t\t\t// oRPC query options are plain objects at runtime; vue-query's type\n\t\t\t// wraps fields in MaybeRefDeep, so `queryFn` is read through one shape.\n\t\t\tconst raw = queryOptionsFn(inputValue, getO()) as unknown as {\n\t\t\t\tqueryKey: QueryKey\n\t\t\t\tqueryFn?: (context: unknown) => Promise<TRouteData>\n\t\t\t\tenabled?: unknown\n\t\t\t} & Record<string, unknown>\n\t\t\tconst wrapsSeed = options.select || options.mergeSeed\n\t\t\tconst queryFn =\n\t\t\t\traw.queryFn && wrapsSeed\n\t\t\t\t\t? seedQueryFn(raw.queryFn, {\n\t\t\t\t\t\t\tinput: inputValue,\n\t\t\t\t\t\t\treadCache: () => queryClient.getQueryData<TData>(raw.queryKey),\n\t\t\t\t\t\t\tselect: options.select,\n\t\t\t\t\t\t\tonSeed: options.onSeed,\n\t\t\t\t\t\t\tmergeSeed: options.mergeSeed\n\t\t\t\t\t\t})\n\t\t\t\t\t: raw.queryFn\n\t\t\treturn {\n\t\t\t\t...raw,\n\t\t\t\t...(queryFn ? { queryFn } : {}),\n\t\t\t\tenabled: visible.value && resolveQueryEnabled(raw.enabled),\n\t\t\t\t...(options.keepPreviousData === false\n\t\t\t\t\t? {}\n\t\t\t\t\t: { placeholderData: keepPreviousData }),\n\t\t\t\tstaleTime: Number.POSITIVE_INFINITY,\n\t\t\t\tmeta: { live: true }\n\t\t\t} as unknown as UseQueryOptions<TData, TError>\n\t\t})\n\t)\n\n\treturn Object.assign(query, { liveStatus: subscription.status })\n}\n\n/**\n * Treat a stream as a \"something changed\" ping: invalidate `keyFn` on each\n * event. Prefer {@link useLiveQuery} when the stream carries the data itself.\n */\nexport function useSubscriptionInvalidates<\n\tTInput,\n\tTEvent,\n\tTOrpc = RegisteredOrpcUtils\n>(\n\tinput: MaybeRefOrGetter<TInput>,\n\tsubscribeFn: OrpcSubscribeFn<TInput, TEvent, TOrpc>,\n\tkeyFn: (orpc: TOrpc) => QueryKey,\n\toptions: Pick<\n\t\tUseSubscriptionOptions<TEvent, TOrpc>,\n\t\t'immediate' | 'maxEvents' | 'respectVisibility' | 'orpc'\n\t> & {\n\t\tonEvent?: (event: TEvent) => void\n\t\t/** Return false to skip invalidation for this event. */\n\t\tshouldInvalidate?: (event: TEvent) => boolean\n\t} = {}\n): UseSubscriptionReturn<TEvent> {\n\tconst { onEvent, shouldInvalidate, ...subscriptionOptions } = options\n\tconst { useSubscription, invalidate } = useApiClient<TOrpc>({\n\t\torpc: options.orpc\n\t})\n\treturn useSubscription(input, subscribeFn, {\n\t\t...subscriptionOptions,\n\t\tonEvent: (event) => {\n\t\t\tonEvent?.(event)\n\t\t\tif (shouldInvalidate?.(event) === false) return\n\t\t\tvoid invalidate(keyFn)\n\t\t}\n\t})\n}\n\n/**\n * One app-wide stream of `{ domain }` change events that keeps list and count\n * queries fresh: each event invalidates its domain's query keys (debounced),\n * and a reconnect that proves healthy invalidates every domain to cover\n * events lost while it was down. Call once, in the signed-in shell.\n *\n * ```ts\n * useInvalidationStream({}, (o) => o.realtime.subscribeChanges.call, {\n * domains: { order: { debounceMs: 100, queryKeys: [orpc.order.key()] } }\n * })\n * ```\n */\nexport function useInvalidationStream<\n\tTInput,\n\tTEvent extends { domain: string },\n\tTOrpc = RegisteredOrpcUtils\n>(\n\tinput: MaybeRefOrGetter<TInput>,\n\tsubscribe: OrpcSubscribeFn<TInput, TEvent, TOrpc>,\n\toptions: InvalidationStreamOptions<TEvent> &\n\t\tPick<\n\t\t\tUseSubscriptionOptions<TEvent, TOrpc>,\n\t\t\t'immediate' | 'respectVisibility' | 'orpc'\n\t\t>\n): UseSubscriptionReturn<TEvent> {\n\tconst coordinator = createInvalidationCoordinator(useQueryClient(), options)\n\tif (getCurrentScope()) onScopeDispose(coordinator.dispose)\n\treturn useOrpcSubscription<TInput, TEvent, TOrpc>(input, subscribe, {\n\t\timmediate: options.immediate,\n\t\trespectVisibility: options.respectVisibility,\n\t\torpc: options.orpc,\n\t\tmaxEvents: 1,\n\t\tonEvent: coordinator.event,\n\t\tonConnect: coordinator.connect,\n\t\tonError: coordinator.lost,\n\t\tonClose: coordinator.lost\n\t})\n}\n\n/** Localized text for a failed query: your fallback unless the server marked its message user-safe. */\nexport function useQueryErrorMessage(\n\terror: MaybeRefOrGetter<unknown>,\n\tfallback: MaybeRefOrGetter<string>\n) {\n\treturn computed(() => {\n\t\tconst err = toValue(error)\n\t\treturn err ? userFacingErrorMessage(err, toValue(fallback)) : null\n\t})\n}\n"]}
1
+ {"version":3,"file":"vue.js","sourceRoot":"","sources":["../src/vue.ts"],"names":[],"mappings":"AAAA,OAAO,EAGN,YAAY,EACZ,OAAO,EAUP,gBAAgB,EAGhB,gBAAgB,IAAI,mBAAmB,EACvC,WAAW,IAAI,cAAc,EAC7B,QAAQ,IAAI,WAAW,EACvB,cAAc,EACd,MAAM,qBAAqB,CAAA;AAC5B,OAAO,EAEN,QAAQ,EACR,eAAe,EACf,mBAAmB,EAEnB,MAAM,EAEN,cAAc,EAEd,QAAQ,EACR,GAAG,EACH,UAAU,EACV,OAAO,EACP,KAAK,EACL,MAAM,KAAK,CAAA;AACZ,OAAO,EAAE,UAAU,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAA;AAChE,OAAO,EACN,6BAA6B,EAC7B,iBAAiB,EACjB,wBAAwB,EAGxB,WAAW,EACX,MAAM,eAAe,CAAA;AA+BtB,MAAM,OAAO,GAA+B,MAAM,CAAC,SAAS,CAAC,CAAA;AAE7D;;;;GAIG;AACH,MAAM,UAAU,WAAW,CAC1B,GAAQ,EACR,IAAwC;IAExC,GAAG,CAAC,OAAO,CAAC,OAAO,EAAE,IAAI,CAAC,CAAA;AAC3B,CAAC;AAED,MAAM,WAAW,GAAG,GAAG,EAAE,CACxB,IAAI,KAAK,CACR,kHAAkH,CAClH,CAAA;AAaF,MAAM,UAAU,OAAO,CAAC,OAEvB;IACA,MAAM,QAAQ,GAAG,mBAAmB,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAA;IACrE,IAAI,CAAC,QAAQ,IAAI,CAAC,OAAO,EAAE,QAAQ;QAAE,MAAM,WAAW,EAAE,CAAA;IACxD,OAAO,QAAiC,CAAA;AACzC,CAAC;AAED,kFAAkF;AAClF,SAAS,cAAc,CACtB,QAA6C;IAE7C,IAAI,QAAQ;QAAE,OAAO,GAAG,EAAE,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAA;IAC5C,MAAM,QAAQ,GAAG,mBAAmB,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAA;IACrE,OAAO,GAAG,EAAE;QACX,IAAI,CAAC,QAAQ;YAAE,MAAM,WAAW,EAAE,CAAA;QAClC,OAAO,QAAQ,CAAC,KAAc,CAAA;IAC/B,CAAC,CAAA;AACF,CAAC;AAED,IAAI,eAAe,GAAwB,IAAI,CAAA;AAC/C;;;GAGG;AACH,MAAM,UAAU,kBAAkB;IACjC,IAAI,CAAC,eAAe,EAAE,CAAC;QACtB,MAAM,OAAO,GAAG,GAAG,CAAC,YAAY,CAAC,SAAS,EAAE,CAAC,CAAA;QAC7C,YAAY,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE,EAAE;YAClC,OAAO,CAAC,KAAK,GAAG,OAAO,CAAA;QACxB,CAAC,CAAC,CAAA;QACF,eAAe,GAAG,OAAO,CAAA;IAC1B,CAAC;IACD,OAAO,eAAe,CAAA;AACvB,CAAC;AAED,SAAS,mBAAmB,CAAC,OAAgB;IAC5C,IAAI,OAAO,KAAK,SAAS;QAAE,OAAO,IAAI,CAAA;IACtC,IAAI,OAAO,OAAO,KAAK,UAAU;QAAE,OAAO,OAAO,CAAC,OAAO,EAAE,CAAC,CAAA;IAC5D,OAAO,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAA;AACjC,CAAC;AAqDD;;;GAGG;AACH,MAAM,UAAU,mBAAmB,CAKlC,KAA+B,EAC/B,WAAmD,EACnD,OAAO,GAA0C,EAAE;IAEnD,MAAM,EACL,SAAS,GAAG,IAAI,EAChB,SAAS,GAAG,GAAG,EACf,0BAA0B,GAAG,IAAI,EACjC,oBAAoB,GAAG,IAAI,EAC3B,iBAAiB,GAAG,IAAI,EACxB,GAAG,OAAO,CAAA;IACX,MAAM,QAAQ,GAAG,cAAc,CAAC,OAAO,CAAC,IAAI,CAAC,CAAA;IAC7C,MAAM,OAAO,GAAG,kBAAkB,EAAE,CAAA;IAEpC,8DAA8D;IAC9D,MAAM,eAAe,GAAG,QAAQ,CAAC,GAAG,EAAE,CAAC,CAAC,iBAAiB,IAAI,OAAO,CAAC,KAAK,CAAC,CAAA;IAC3E,8DAA8D;IAC9D,MAAM,iBAAiB,GAAG,QAAQ,CACjC,GAAG,EAAE,CAAC,OAAO,CAAC,SAAS,CAAC,IAAI,eAAe,CAAC,KAAK,CACjD,CAAA;IAED,wFAAwF;IACxF,MAAM,MAAM,GAAG,UAAU,CAAW,EAAE,CAAC,CAAA;IACvC,MAAM,WAAW,GAAG,UAAU,CAAqB,SAAS,CAAC,CAAA;IAC7D,MAAM,MAAM,GAAG,GAAG,CAAuB,MAAM,CAAC,CAAA;IAChD,MAAM,KAAK,GAAG,GAAG,CAAe,IAAI,CAAC,CAAA;IAErC,MAAM,MAAM,GAAG,wBAAwB,CAAS;QAC/C,IAAI,EAAE,CAAC,MAAM,EAAE,EAAE,CAChB,WAAW,CAAC,QAAQ,EAAE,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,UAAU,EAAE,CAAC;QACzE,UAAU,EAAE,GAAG,EAAE,CAAC,eAAe,CAAC,KAAK;QACvC,eAAe,EAAE,GAAG,EAAE,CAAC,oBAAoB,IAAI,iBAAiB,CAAC,KAAK;QACtE,QAAQ,EAAE,CAAC,IAAI,EAAE,EAAE;YAClB,MAAM,CAAC,KAAK,GAAG,IAAI,CAAA;YACnB,IAAI,IAAI,KAAK,YAAY;gBAAE,KAAK,CAAC,KAAK,GAAG,IAAI,CAAA;QAC9C,CAAC;QACD,OAAO,EAAE,CAAC,KAAK,EAAE,YAAY,EAAE,EAAE;YAChC,WAAW,CAAC,KAAK,GAAG,KAAK,CAAA;YACzB,IAAI,SAAS,GAAG,CAAC,EAAE,CAAC;gBACnB,MAAM,CAAC,KAAK,GAAG,CAAC,GAAG,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,GAAG,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,CAAA;YAChE,CAAC;YACD,OAAO,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE,YAAY,EAAE,CAAC,CAAA;QAC3C,CAAC;QACD,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE;YAChB,KAAK,CAAC,KAAK,GAAG,GAAG,CAAA;YACjB,OAAO,CAAC,OAAO,EAAE,CAAC,GAAG,CAAC,CAAA;QACvB,CAAC;QACD,SAAS,EAAE,OAAO,CAAC,SAAS;QAC5B,OAAO,EAAE,OAAO,CAAC,OAAO;KACxB,CAAC,CAAA;IAEF,SAAS,WAAW;QACnB,MAAM,CAAC,KAAK,GAAG,EAAE,CAAA;QACjB,WAAW,CAAC,KAAK,GAAG,SAAS,CAAA;IAC9B,CAAC;IAED,IAAI,0BAA0B,EAAE,CAAC;QAChC,KAAK,CACJ,GAAG,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,EACpB,KAAK,IAAI,EAAE;YACV,MAAM,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,CAAA;YAC/B,IAAI,MAAM,CAAC,SAAS,EAAE,KAAK,MAAM,EAAE,CAAC;gBACnC,MAAM,MAAM,CAAC,UAAU,EAAE,CAAA;gBACzB,WAAW,EAAE,CAAA;YACd,CAAC;YACD,iEAAiE;YACjE,IAAI,iBAAiB,CAAC,KAAK,IAAI,CAAC,OAAO,IAAI,eAAe,CAAC,KAAK,CAAC,EAAE,CAAC;gBACnE,MAAM,MAAM,CAAC,KAAK,EAAE,CAAA;YACrB,CAAC;QACF,CAAC,EACD,EAAE,IAAI,EAAE,IAAI,EAAE,CACd,CAAA;IACF,CAAC;IAED,sFAAsF;IACtF,KAAK,CACJ,eAAe,EACf,CAAC,OAAO,EAAE,EAAE;QACX,IAAI,CAAC,OAAO;YAAE,KAAK,MAAM,CAAC,UAAU,EAAE,CAAA;aACjC,IAAI,OAAO,CAAC,SAAS,CAAC,EAAE,CAAC;YAC7B,KAAK,CAAC,KAAK,GAAG,IAAI,CAAA;YAClB,KAAK,MAAM,CAAC,KAAK,EAAE,CAAA;QACpB,CAAC;IACF,CAAC,EACD,EAAE,SAAS,EAAE,IAAI,EAAE,CACnB,CAAA;IAED,KAAK,CACJ,GAAG,EAAE,CAAC,OAAO,CAAC,SAAS,CAAC,EACxB,CAAC,IAAI,EAAE,EAAE;QACR,IAAI,CAAC,IAAI;YAAE,KAAK,MAAM,CAAC,UAAU,EAAE,CAAA;aAC9B,IAAI,eAAe,CAAC,KAAK,EAAE,CAAC;YAChC,KAAK,CAAC,KAAK,GAAG,IAAI,CAAA;YAClB,KAAK,MAAM,CAAC,KAAK,EAAE,CAAA;QACpB,CAAC;IACF,CAAC,CACD,CAAA;IAED,oEAAoE;IACpE,IAAI,eAAe,EAAE;QAAE,cAAc,CAAC,GAAG,EAAE,CAAC,KAAK,MAAM,CAAC,OAAO,EAAE,CAAC,CAAA;IAElE,OAAO;QACN,MAAM;QACN,WAAW;QACX,MAAM;QACN,KAAK;QACL,WAAW,EAAE,QAAQ,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,KAAK,KAAK,WAAW,CAAC;QACzD,OAAO,EAAE,MAAM,CAAC,OAAO;QACvB,UAAU,EAAE,MAAM,CAAC,UAAU;QAC7B,WAAW;KACX,CAAA;AACF,CAAC;AAiBD,MAAM,UAAU,YAAY,CAAQ,aAEnC;IACA,OAAO,iBAAiB,CAAC,aAAa,EAAE,IAAI,CAAC,CAAA;AAC9C,CAAC;AAED,SAAS,iBAAiB,CAAQ,IAAyC;IAC1E,MAAM,WAAW,GAAG,cAAc,EAAE,CAAA;IACpC,MAAM,IAAI,GAAG,cAAc,CAAC,IAAI,CAAC,CAAA;IAEjC,4EAA4E;IAC5E,6EAA6E;IAC7E,SAAS,QAAQ,CAChB,SAE+D;QAE/D,yEAAyE;QACzE,4EAA4E;QAC5E,MAAM,OAAO,GAAG,QAAQ,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC,CAAC,CAAA;QACjD,OAAO,WAAW,CACjB,OAKC,CACD,CAAA;IACF,CAAC;IAED,6GAA6G;IAC7G,SAAS,gBAAgB,CAOxB,SAQC;QAED,MAAM,OAAO,GAAG,QAAQ,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC,CAAC,CAAA;QACjD,OAAO,mBAAmB,CAOzB,OAMC,CACD,CAAA;IACF,CAAC;IAwCD,SAAS,WAAW,CACnB,SAEiE,EACjE,MAGC;QAED,MAAM,WAAW,GAAG,MAAM,EAAE,WAAW,CAAA;QACvC,MAAM,QAAQ,GAAG,cAAc,CAC9B,QAAQ,CAAC,GAAG,EAAE;YACb,MAAM,OAAO,GAAG,SAAS,CAAC,IAAI,EAAE,CAAC,CAAA;YACjC,IAAI,CAAC,WAAW;gBAAE,OAAO,OAAO,CAAA;YAChC,OAAO;gBACN,GAAG,OAAO;gBACV,SAAS,EAAE,KAAK,EACf,GAAG,IAAuD,EACzD,EAAE;oBACH,MAAM,OAAO,CAAC,GAAG,CAChB,WAAW,CAAC,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE,CACpC,WAAW,CAAC,iBAAiB,CAAC,EAAE,QAAQ,EAAE,CAAC,CAC3C,CACD,CAAA;oBACD,OAAO,OAAO,CAAC,SAAS,EAAE,CAAC,GAAG,IAAI,CAAC,CAAA;gBACpC,CAAC;aACD,CAAA;QACF,CAAC,CAAC,CACF,CAAA;QACD,IAAI,MAAM,EAAE,YAAY,KAAK,SAAS;YAAE,OAAO,QAAQ,CAAA;QACvD,MAAM,YAAY,GAAG,MAAM,CAAC,YAAY,CAAA;QACxC,MAAM,SAAS,GAAG,GAAG,CAAC,YAAY,CAAoB,CAAA;QACtD,OAAO;YACN,GAAG,QAAQ;YACX,SAAS;YACT,MAAM,EAAE,CAAC,SAAsB,EAAE,EAAE,CAClC,QAAQ,CAAC,MAAM,CAAC,SAAS,IAAI,SAAS,CAAC,KAAK,CAAC;YAC9C,WAAW,EAAE,CAAC,SAAsB,EAAE,EAAE,CACvC,QAAQ,CAAC,WAAW,CAAC,SAAS,IAAI,SAAS,CAAC,KAAK,CAAC;SACnD,CAAA;IACF,CAAC;IAED,SAAS,eAAe,CACvB,KAA+B,EAC/B,WAAmD,EACnD,OAAO,GAA0C,EAAE;QAEnD,OAAO,mBAAmB,CAAwB,KAAK,EAAE,WAAW,EAAE;YACrE,GAAG,OAAO;YACV,IAAI,EAAE,IAAI;SACV,CAAC,CAAA;IACH,CAAC;IAED,MAAM,KAAK,GAAG,CAAwB,KAA4B,EAAE,EAAE,CACrE,KAAK,CAAC,IAAI,EAAE,CAAC,CAAA;IAEd,OAAO;QACN,iGAAiG;QACjG,IAAI,IAAI;YACP,OAAO,IAAI,EAAE,CAAA;QACd,CAAC;QACD,QAAQ;QACR,gBAAgB;QAChB,WAAW;QACX,eAAe;QACf,UAAU,EAAE,CACX,KAAgC,EAChC,OAAkD,EACjD,EAAE,CAAC,WAAW,CAAC,iBAAiB,CAAC,EAAE,QAAQ,EAAE,KAAK,CAAC,KAAK,CAAC,EAAE,GAAG,OAAO,EAAE,CAAC;QAC1E,8CAA8C;QAC9C,QAAQ,EAAE,CAMT,SAE8D,EAC7D,EAAE,CAAC,WAAW,CAAC,aAAa,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC,CAAC;QACjD,gFAAgF;QAChF,YAAY,EAAE,CACb,KAA4B,EACU,EAAE,CACxC,WAAW,CAAC,YAAY,CAA0B,KAAK,CAAC,KAAK,CAAC,CAAC;QAChE,qDAAqD;QACrD,YAAY,EAAE,CACb,KAA4B,EAC5B,OAGC,EACA,EAAE,CACH,WAAW,CAAC,YAAY,CAA0B,KAAK,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC;QACzE,aAAa,EAAE,CAAC,KAAgC,EAAE,EAAE,CACnD,WAAW,CAAC,aAAa,CAAC,EAAE,QAAQ,EAAE,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC;QACtD,aAAa,EAAE,CAAC,KAAgC,EAAE,EAAE,CACnD,WAAW,CAAC,aAAa,CAAC,EAAE,QAAQ,EAAE,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC;QACtD,UAAU,EAAE,CAAC,KAAiC,EAAE,EAAE,CACjD,WAAW,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAChE,WAAW;KACX,CAAA;AACF,CAAC;AA8GD,MAAM,UAAU,YAAY,CAS3B,KAA+B,EAC/B,cAGiE,EACjE,WAAqE,EACrE,OAAO,GAOH,EAAE;IAEN,MAAM,WAAW,GAAG,cAAc,EAAE,CAAA;IACpC,MAAM,IAAI,GAAG,cAAc,CAAC,OAAO,CAAC,IAAI,CAAC,CAAA;IACzC,MAAM,OAAO,GAAG,kBAAkB,EAAE,CAAA;IACpC,gFAAgF;IAChF,MAAM,UAAU,GACf,OAAO,CAAC,UAAU,IAAI,CAAC,CAAC,KAAmB,EAAE,EAAE,CAAC,KAAyB,CAAC,CAAA;IAC3E,gEAAgE;IAChE,MAAM,QAAQ,GAAG,QAAQ,CACxB,GAAG,EAAE,CAAC,cAAc,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,QAAQ,CACrD,CAAA;IACD,MAAM,SAAS,GAAG,QAAQ,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAA;IACzD,MAAM,KAAK,GAAG,iBAAiB,EAAE,CAAA;IAEjC,MAAM,YAAY,GAAG,mBAAmB,CACvC,QAAQ,CACP,GAAG,EAAE,CACJ,CAAC,OAAO,CAAC,iBAAiB,KAAK,SAAS;QACvC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC;QAChB,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,iBAAiB,CAAC,CAAuB,CAC7D,EACD,WAAW,EACX;QACC,SAAS,EAAE,OAAO,CAAC,SAAS;QAC5B,iBAAiB,EAAE,OAAO,CAAC,iBAAiB;QAC5C,OAAO,EAAE,OAAO,CAAC,OAAO;QACxB,SAAS,EAAE,CAAC;QACZ,IAAI,EAAE,IAAI;QACV,SAAS,EAAE,CAAC,YAAY,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,YAAY,EAAE,SAAS,CAAC,KAAK,CAAC;QACtE,OAAO,EAAE,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE;YACxB,2EAA2E;YAC3E,IAAI,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,SAAS,CAAC,KAAK,CAAC;gBAAE,OAAM;YACpE,MAAM,GAAG,GAAG,QAAQ,CAAC,KAAK,CAAA;YAC1B,MAAM,IAAI,GAAG,UAAU,CAAC,KAAK,EAAE,WAAW,CAAC,YAAY,CAAQ,GAAG,CAAC,CAAC,CAAA;YACpE,IAAI,IAAI,KAAK,SAAS;gBAAE,WAAW,CAAC,YAAY,CAAC,GAAG,EAAE,IAAI,CAAC,CAAA;YAC3D,OAAO,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,IAAI,CAAC,CAAA;QAC/B,CAAC;KACD,CACD,CAAA;IAED,MAAM,KAAK,GAAG,WAAW,CACxB,QAAQ,CAAC,GAAG,EAAE;QACb,MAAM,UAAU,GAAG,OAAO,CAAC,KAAK,CAAC,CAAA;QACjC,oEAAoE;QACpE,wEAAwE;QACxE,MAAM,GAAG,GAAG,cAAc,CAAC,UAAU,EAAE,IAAI,EAAE,CAIlB,CAAA;QAC3B,MAAM,SAAS,GAAG,OAAO,CAAC,MAAM,IAAI,OAAO,CAAC,SAAS,CAAA;QACrD,MAAM,OAAO,GACZ,GAAG,CAAC,OAAO,IAAI,SAAS;YACvB,CAAC,CAAC,WAAW,CAAC,GAAG,CAAC,OAAO,EAAE;gBACzB,KAAK,EAAE,UAAU;gBACjB,SAAS,EAAE,GAAG,EAAE,CAAC,WAAW,CAAC,YAAY,CAAQ,GAAG,CAAC,QAAQ,CAAC;gBAC9D,MAAM,EAAE,OAAO,CAAC,MAAM;gBACtB,MAAM,EAAE,OAAO,CAAC,MAAM;gBACtB,SAAS,EAAE,OAAO,CAAC,SAAS;aAC5B,CAAC;YACH,CAAC,CAAC,GAAG,CAAC,OAAO,CAAA;QACf,OAAO;YACN,GAAG,GAAG;YACN,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAC/B,OAAO,EAAE,OAAO,CAAC,KAAK,IAAI,mBAAmB,CAAC,GAAG,CAAC,OAAO,CAAC;YAC1D,GAAG,CAAC,OAAO,CAAC,gBAAgB,KAAK,KAAK;gBACrC,CAAC,CAAC,EAAE;gBACJ,CAAC,CAAC,EAAE,eAAe,EAAE,gBAAgB,EAAE,CAAC;YACzC,SAAS,EAAE,MAAM,CAAC,iBAAiB;YACnC,IAAI,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE;SACyB,CAAA;IAC/C,CAAC,CAAC,CACF,CAAA;IAED,OAAO,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,EAAE,UAAU,EAAE,YAAY,CAAC,MAAM,EAAE,CAAC,CAAA;AACjE,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,0BAA0B,CAKzC,KAA+B,EAC/B,WAAmD,EACnD,KAAgC,EAChC,OAAO,GAOH,EAAE;IAEN,MAAM,EAAE,OAAO,EAAE,gBAAgB,EAAE,GAAG,mBAAmB,EAAE,GAAG,OAAO,CAAA;IACrE,MAAM,EAAE,eAAe,EAAE,UAAU,EAAE,GAAG,YAAY,CAAQ;QAC3D,IAAI,EAAE,OAAO,CAAC,IAAI;KAClB,CAAC,CAAA;IACF,OAAO,eAAe,CAAC,KAAK,EAAE,WAAW,EAAE;QAC1C,GAAG,mBAAmB;QACtB,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE;YAClB,OAAO,EAAE,CAAC,KAAK,CAAC,CAAA;YAChB,IAAI,gBAAgB,EAAE,CAAC,KAAK,CAAC,KAAK,KAAK;gBAAE,OAAM;YAC/C,KAAK,UAAU,CAAC,KAAK,CAAC,CAAA;QACvB,CAAC;KACD,CAAC,CAAA;AACH,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,qBAAqB,CAKpC,KAA+B,EAC/B,SAAiD,EACjD,OAIE;IAEF,MAAM,WAAW,GAAG,6BAA6B,CAAC,cAAc,EAAE,EAAE,OAAO,CAAC,CAAA;IAC5E,IAAI,eAAe,EAAE;QAAE,cAAc,CAAC,WAAW,CAAC,OAAO,CAAC,CAAA;IAC1D,OAAO,mBAAmB,CAAwB,KAAK,EAAE,SAAS,EAAE;QACnE,SAAS,EAAE,OAAO,CAAC,SAAS;QAC5B,iBAAiB,EAAE,OAAO,CAAC,iBAAiB;QAC5C,IAAI,EAAE,OAAO,CAAC,IAAI;QAClB,SAAS,EAAE,CAAC;QACZ,OAAO,EAAE,WAAW,CAAC,KAAK;QAC1B,SAAS,EAAE,WAAW,CAAC,OAAO;QAC9B,OAAO,EAAE,WAAW,CAAC,IAAI;QACzB,OAAO,EAAE,WAAW,CAAC,IAAI;KACzB,CAAC,CAAA;AACH,CAAC;AAED,uGAAuG;AACvG,MAAM,UAAU,oBAAoB,CACnC,KAAgC,EAChC,QAAkC;IAElC,OAAO,QAAQ,CAAC,GAAG,EAAE;QACpB,MAAM,GAAG,GAAG,OAAO,CAAC,KAAK,CAAC,CAAA;QAC1B,OAAO,GAAG,CAAC,CAAC,CAAC,sBAAsB,CAAC,GAAG,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAA;IACnE,CAAC,CAAC,CAAA;AACH,CAAC;AAWD;;;;GAIG;AACH,MAAM,UAAU,aAAa,CAC5B,KAAuB,EACvB,OAA+C;IAE/C,MAAM,YAAY,GAAG,oBAAoB,CAAC,KAAK,CAAC,KAAK,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAA;IACxE,OAAO,QAAQ,CAAC;QACf,MAAM,EAAE,QAAQ,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC;QAC1C,KAAK,EAAE,QAAQ,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC;QACxC,YAAY;QACZ,UAAU,EAAE,QAAQ,CACnB,GAAG,EAAE,CACJ,KAAK,CAAC,UAAU,CAAC,KAAK;YACtB,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,KAAK,OAAO,IAAI,KAAK,CAAC,YAAY,CAAC,KAAK,GAAG,CAAC,CAAC,CACjE;QACD,KAAK,EAAE,GAAG,EAAE;YACX,KAAK,KAAK,CAAC,OAAO,EAAE,CAAA;QACrB,CAAC;KACD,CAAC,CAAA;AACH,CAAC","sourcesContent":["import {\n\ttype DefaultError,\n\ttype FetchQueryOptions,\n\tfocusManager,\n\thashKey,\n\ttype InferDataFromTag,\n\ttype InfiniteData,\n\ttype InvalidateQueryFilters,\n\ttype MutationObserverOptions,\n\ttype UseInfiniteQueryOptions,\n\ttype UseInfiniteQueryReturnType,\n\ttype UseMutationReturnType,\n\ttype UseQueryReturnType,\n\ttype Updater,\n\tkeepPreviousData,\n\ttype QueryKey,\n\ttype UseQueryOptions,\n\tuseInfiniteQuery as useVueInfiniteQuery,\n\tuseMutation as useVueMutation,\n\tuseQuery as useVueQuery,\n\tuseQueryClient\n} from '@tanstack/vue-query'\nimport {\n\ttype App,\n\tcomputed,\n\tgetCurrentScope,\n\thasInjectionContext,\n\ttype InjectionKey,\n\tinject,\n\ttype MaybeRefOrGetter,\n\tonScopeDispose,\n\ttype Ref,\n\treactive,\n\tref,\n\tshallowRef,\n\ttoValue,\n\twatch\n} from 'vue'\nimport { streamCall, userFacingErrorMessage } from './client.js'\nimport {\n\tcreateInvalidationCoordinator,\n\tcreateStreamScope,\n\tcreateSubscriptionRunner,\n\ttype InvalidationStreamOptions,\n\ttype LiveConnectionStatus,\n\tseedQueryFn\n} from './realtime.js'\n\nexport type { InvalidationDomain, LiveConnectionStatus } from './realtime.js'\n\n/**\n * Register your client types once so every composable infers them:\n *\n * ```ts\n * declare module 'orpc-fn/vue' {\n * interface Register { utils: typeof orpc; client: typeof client }\n * }\n * ```\n */\n// biome-ignore lint/suspicious/noEmptyInterface: filled in by app module augmentation\nexport interface Register {}\n\nexport type RegisteredOrpcUtils = Register extends { utils: infer T }\n\t? T\n\t: {\n\t\t\t'orpc-fn/vue: register your utils with `declare module \"orpc-fn/vue\" { interface Register { utils: typeof orpc } }`, or pass `orpc`': never\n\t\t}\nexport type RegisteredOrpcClient = Register extends { client: infer T }\n\t? T\n\t: unknown\n\n/** An explicit `<TData>`, else the data type oRPC tagged on the key. */\ntype CachedData<TData, TKey extends QueryKey> = [TData] extends [never]\n\t? InferDataFromTag<unknown, TKey>\n\t: TData\n\ntype ProvidedOrpc = { client: unknown; utils: unknown }\nconst orpcKey: InjectionKey<ProvidedOrpc> = Symbol('orpc-fn')\n\n/**\n * Make an oRPC client and its TanStack Query utils the app's default. A\n * surface that talks to another API (an embed with its own auth) passes\n * `orpc` to each composable instead and never needs this.\n */\nexport function provideOrpc<TClient, TUtils>(\n\tapp: App,\n\torpc: { client: TClient; utils: TUtils }\n): void {\n\tapp.provide(orpcKey, orpc)\n}\n\nconst missingOrpc = () =>\n\tnew Error(\n\t\t'orpc-fn/vue: no oRPC client provided. Call provideOrpc(app, { client, utils }) or pass `orpc` to the composable.'\n\t)\n\ntype RegisteredOrpc = {\n\tclient: RegisteredOrpcClient\n\tutils: RegisteredOrpcUtils\n}\n\n/**\n * The client and utils from {@link provideOrpc}. Throws when none was\n * provided, unless `optional`, which returns null instead.\n */\nexport function useOrpc(options: { optional: true }): RegisteredOrpc | null\nexport function useOrpc(options?: { optional?: false }): RegisteredOrpc\nexport function useOrpc(options?: {\n\toptional?: boolean\n}): RegisteredOrpc | null {\n\tconst provided = hasInjectionContext() ? inject(orpcKey, null) : null\n\tif (!provided && !options?.optional) throw missingOrpc()\n\treturn provided as RegisteredOrpc | null\n}\n\n/** Resolve the provided utils now; fail only when they are needed and missing. */\nfunction useUtilsGetter<TOrpc>(\n\texplicit: MaybeRefOrGetter<TOrpc> | undefined\n): () => TOrpc {\n\tif (explicit) return () => toValue(explicit)\n\tconst provided = hasInjectionContext() ? inject(orpcKey, null) : null\n\treturn () => {\n\t\tif (!provided) throw missingOrpc()\n\t\treturn provided.utils as TOrpc\n\t}\n}\n\nlet documentVisible: Ref<boolean> | null = null\n/**\n * Whether the page is visible, from TanStack's `focusManager` (which follows\n * `visibilitychange` in browsers). Live streams pause while it is false.\n */\nexport function useDocumentVisible(): Ref<boolean> {\n\tif (!documentVisible) {\n\t\tconst visible = ref(focusManager.isFocused())\n\t\tfocusManager.subscribe((focused) => {\n\t\t\tvisible.value = focused\n\t\t})\n\t\tdocumentVisible = visible\n\t}\n\treturn documentVisible\n}\n\nfunction resolveQueryEnabled(enabled: unknown): boolean {\n\tif (enabled === undefined) return true\n\tif (typeof enabled === 'function') return Boolean(enabled())\n\treturn Boolean(toValue(enabled))\n}\n\n/**\n * Picks the stream to open from the utils. A procedure's `call` fits as is:\n * `(o) => o.order.watch.call`. The composable passes the input, an abort\n * signal and `streamCall` as the client context, which keeps the call out of\n * `createRpcLink`'s batches.\n */\nexport type OrpcSubscribeFn<TInput, TEvent, TOrpc = RegisteredOrpcUtils> = (\n\torpc: TOrpc\n) => (\n\tinput: TInput,\n\toptions: { signal: AbortSignal; context: typeof streamCall }\n) => Promise<AsyncIterable<TEvent>>\n\nexport interface UseSubscriptionOptions<TEvent, TOrpc = RegisteredOrpcUtils> {\n\t/** Start the stream on its own (default: true). With false, call `connect()`. */\n\timmediate?: MaybeRefOrGetter<boolean> | undefined\n\tonEvent?: (event: TEvent, meta?: { connectionId: number }) => void\n\tonError?: ((error: Error) => void) | undefined\n\t/** Every successful connect; `connectionId > 1` is a reconnect. */\n\tonConnect?: (connectionId: number) => void\n\tonClose?: () => void\n\t/** Events kept in `events` (default: 100). 1 keeps only `latestEvent`. */\n\tmaxEvents?: number\n\t/** Reconnect when the input changes (default: true). */\n\tautoReconnectOnInputChange?: boolean\n\t/**\n\t * After a connect, reconnect with backoff when the stream ends or errors\n\t * unexpectedly (proxy idle timeout, network blip). Deliberate teardown\n\t * does not retry. Default: true.\n\t */\n\tautoReconnectOnClose?: boolean\n\torpc?: MaybeRefOrGetter<TOrpc> | undefined\n\t/**\n\t * Close the stream while the page is hidden (default: true), so a\n\t * background tab holds no server connection. It reconnects, and a live\n\t * route re-sends its snapshot, when the page is visible again.\n\t */\n\trespectVisibility?: boolean | undefined\n}\n\nexport interface UseSubscriptionReturn<TEvent> {\n\tevents: Ref<TEvent[]>\n\tlatestEvent: Ref<TEvent | undefined>\n\tstatus: Ref<LiveConnectionStatus>\n\terror: Ref<Error | null>\n\tisConnected: Ref<boolean>\n\tconnect: () => Promise<void>\n\tdisconnect: () => Promise<void>\n\tclearEvents: () => void\n}\n\n/**\n * An oRPC event iterator as reactive state, with backoff reconnects and a\n * pause while the page is hidden. Closed when the owning effect scope stops.\n */\nexport function useOrpcSubscription<\n\tTInput,\n\tTEvent,\n\tTOrpc = RegisteredOrpcUtils\n>(\n\tinput: MaybeRefOrGetter<TInput>,\n\tsubscribeFn: OrpcSubscribeFn<TInput, TEvent, TOrpc>,\n\toptions: UseSubscriptionOptions<TEvent, TOrpc> = {}\n): UseSubscriptionReturn<TEvent> {\n\tconst {\n\t\timmediate = true,\n\t\tmaxEvents = 100,\n\t\tautoReconnectOnInputChange = true,\n\t\tautoReconnectOnClose = true,\n\t\trespectVisibility = true\n\t} = options\n\tconst getUtils = useUtilsGetter(options.orpc)\n\tconst visible = useDocumentVisible()\n\n\t// May a stream run at all? This gates a manual connect() too.\n\tconst isStreamAllowed = computed(() => !respectVisibility || visible.value)\n\t// Should it start on its own? That is what `immediate` means.\n\tconst shouldAutoConnect = computed(\n\t\t() => toValue(immediate) && isStreamAllowed.value\n\t)\n\n\t// Shallow: event payloads are replaced, never mutated, so deep proxies are wasted work.\n\tconst events = shallowRef<TEvent[]>([])\n\tconst latestEvent = shallowRef<TEvent | undefined>(undefined)\n\tconst status = ref<LiveConnectionStatus>('idle')\n\tconst error = ref<Error | null>(null)\n\n\tconst runner = createSubscriptionRunner<TEvent>({\n\t\topen: (signal) =>\n\t\t\tsubscribeFn(getUtils())(toValue(input), { signal, context: streamCall }),\n\t\tcanConnect: () => isStreamAllowed.value,\n\t\tshouldReconnect: () => autoReconnectOnClose && shouldAutoConnect.value,\n\t\tonStatus: (next) => {\n\t\t\tstatus.value = next\n\t\t\tif (next === 'connecting') error.value = null\n\t\t},\n\t\tonEvent: (event, connectionId) => {\n\t\t\tlatestEvent.value = event\n\t\t\tif (maxEvents > 1) {\n\t\t\t\tevents.value = [...events.value.slice(-(maxEvents - 1)), event]\n\t\t\t}\n\t\t\toptions.onEvent?.(event, { connectionId })\n\t\t},\n\t\tonError: (err) => {\n\t\t\terror.value = err\n\t\t\toptions.onError?.(err)\n\t\t},\n\t\tonConnect: options.onConnect,\n\t\tonClose: options.onClose\n\t})\n\n\tfunction clearEvents() {\n\t\tevents.value = []\n\t\tlatestEvent.value = undefined\n\t}\n\n\tif (autoReconnectOnInputChange) {\n\t\twatch(\n\t\t\t() => toValue(input),\n\t\t\tasync () => {\n\t\t\t\tconst wasLive = runner.isLive()\n\t\t\t\tif (runner.getStatus() !== 'idle') {\n\t\t\t\t\tawait runner.disconnect()\n\t\t\t\t\tclearEvents()\n\t\t\t\t}\n\t\t\t\t// Reconnect in auto mode, or in manual mode when it was running.\n\t\t\t\tif (shouldAutoConnect.value || (wasLive && isStreamAllowed.value)) {\n\t\t\t\t\tawait runner.start()\n\t\t\t\t}\n\t\t\t},\n\t\t\t{ deep: true }\n\t\t)\n\t}\n\n\t// Visibility closes the stream in both modes; only the re-open waits for `immediate`.\n\twatch(\n\t\tisStreamAllowed,\n\t\t(allowed) => {\n\t\t\tif (!allowed) void runner.disconnect()\n\t\t\telse if (toValue(immediate)) {\n\t\t\t\terror.value = null\n\t\t\t\tvoid runner.start()\n\t\t\t}\n\t\t},\n\t\t{ immediate: true }\n\t)\n\n\twatch(\n\t\t() => toValue(immediate),\n\t\t(auto) => {\n\t\t\tif (!auto) void runner.disconnect()\n\t\t\telse if (isStreamAllowed.value) {\n\t\t\t\terror.value = null\n\t\t\t\tvoid runner.start()\n\t\t\t}\n\t\t}\n\t)\n\n\t// A detached effect scope may own the stream, not just a component.\n\tif (getCurrentScope()) onScopeDispose(() => void runner.dispose())\n\n\treturn {\n\t\tevents,\n\t\tlatestEvent,\n\t\tstatus,\n\t\terror,\n\t\tisConnected: computed(() => status.value === 'connected'),\n\t\tconnect: runner.connect,\n\t\tdisconnect: runner.disconnect,\n\t\tclearEvents\n\t}\n}\n\n/** What {@link useApiClient} returns, e.g. `ApiClient['invalidate']` for a helper. */\nexport type ApiClient<TOrpc = RegisteredOrpcUtils> = ReturnType<\n\ttypeof useBoundApiClient<TOrpc>\n>\n\n/**\n * TanStack Query composables that receive the oRPC utils, so call sites read\n * `useQuery((o) => o.order.get.queryOptions({ input }))`. Pass `orpc` to bind\n * another client than the provided one.\n */\nexport function useApiClient<TOrpc = RegisteredOrpcUtils>(clientOptions?: {\n\torpc?: MaybeRefOrGetter<TOrpc> | undefined\n}): ApiClient<TOrpc>\n// `ReturnType<typeof useApiClient>` reads the last overload: the registered utils.\nexport function useApiClient(): ApiClient\nexport function useApiClient<TOrpc>(clientOptions?: {\n\torpc?: MaybeRefOrGetter<TOrpc> | undefined\n}): ApiClient<TOrpc> {\n\treturn useBoundApiClient(clientOptions?.orpc)\n}\n\nfunction useBoundApiClient<TOrpc>(orpc: MaybeRefOrGetter<TOrpc> | undefined) {\n\tconst queryClient = useQueryClient()\n\tconst getO = useUtilsGetter(orpc)\n\n\t// Each wrapper forwards TanStack's own generics, so `select`, typed errors,\n\t// page params and oRPC's tagged keys infer exactly as with vue-query itself.\n\tfunction useQuery<TQueryFnData, TError = DefaultError, TData = TQueryFnData>(\n\t\toptionsFn: (\n\t\t\torpc: TOrpc\n\t\t) => UseQueryOptions<TQueryFnData, TError, TData, TQueryFnData>\n\t): UseQueryReturnType<TData, TError> {\n\t\t// A computed is a ref at runtime; TypeScript cannot relate a computed of\n\t\t// the generic options to vue-query's MaybeRef parameter, so it is asserted.\n\t\tconst options = computed(() => optionsFn(getO()))\n\t\treturn useVueQuery<TQueryFnData, TError, TData>(\n\t\t\toptions as unknown as UseQueryOptions<\n\t\t\t\tTQueryFnData,\n\t\t\t\tTError,\n\t\t\t\tTData,\n\t\t\t\tTQueryFnData\n\t\t\t>\n\t\t)\n\t}\n\n\t/** `useInfiniteQuery((o) => o.order.list.infiniteOptions({ input, initialPageParam, getNextPageParam }))` */\n\tfunction useInfiniteQuery<\n\t\tTQueryFnData,\n\t\tTError = DefaultError,\n\t\tTData = InfiniteData<TQueryFnData>,\n\t\tTQueryKey extends QueryKey = QueryKey,\n\t\tTPageParam = unknown\n\t>(\n\t\toptionsFn: (\n\t\t\torpc: TOrpc\n\t\t) => UseInfiniteQueryOptions<\n\t\t\tTQueryFnData,\n\t\t\tTError,\n\t\t\tTData,\n\t\t\tTQueryKey,\n\t\t\tTPageParam\n\t\t>\n\t): UseInfiniteQueryReturnType<TData, TError> {\n\t\tconst options = computed(() => optionsFn(getO()))\n\t\treturn useVueInfiniteQuery<\n\t\t\tTQueryFnData,\n\t\t\tTError,\n\t\t\tTData,\n\t\t\tTQueryKey,\n\t\t\tTPageParam\n\t\t>(\n\t\t\toptions as unknown as UseInfiniteQueryOptions<\n\t\t\t\tTQueryFnData,\n\t\t\t\tTError,\n\t\t\t\tTData,\n\t\t\t\tTQueryKey,\n\t\t\t\tTPageParam\n\t\t\t>\n\t\t)\n\t}\n\n\t/**\n\t * With `initialInput`, also returns `inputData`, a ref that `mutate()` and\n\t * `mutateAsync()` use when called without variables (form state). With\n\t * `invalidates`, a success invalidates those keys, awaited before the\n\t * options' own `onSuccess`: `{ invalidates: (o) => [o.order.key()] }`.\n\t */\n\t// The input type comes from the route alone; `initialInput` is only checked\n\t// against it. `unknown`, not `void`, lets `initialInput` pass the first\n\t// inference pass, which runs before the `(o) => ...` callback is read.\n\tfunction useMutation<\n\t\tTData = unknown,\n\t\tTError = DefaultError,\n\t\tTVariables = unknown,\n\t\tTContext = unknown\n\t>(\n\t\toptionsFn: (\n\t\t\torpc: TOrpc\n\t\t) => MutationObserverOptions<TData, TError, TVariables, TContext>,\n\t\tconfig: {\n\t\t\tinitialInput: NoInfer<TVariables>\n\t\t\tinvalidates?: (orpc: TOrpc) => readonly QueryKey[]\n\t\t}\n\t): UseMutationReturnType<TData, TError, TVariables, TContext> & {\n\t\tinputData: Ref<TVariables>\n\t\tmutate: (variables?: TVariables) => void\n\t\tmutateAsync: (variables?: TVariables) => Promise<TData>\n\t}\n\tfunction useMutation<\n\t\tTData = unknown,\n\t\tTError = DefaultError,\n\t\tTVariables = void,\n\t\tTContext = unknown\n\t>(\n\t\toptionsFn: (\n\t\t\torpc: TOrpc\n\t\t) => MutationObserverOptions<TData, TError, TVariables, TContext>,\n\t\tconfig?: { invalidates?: (orpc: TOrpc) => readonly QueryKey[] }\n\t): UseMutationReturnType<TData, TError, TVariables, TContext>\n\tfunction useMutation<TData, TError, TVariables, TContext>(\n\t\toptionsFn: (\n\t\t\torpc: TOrpc\n\t\t) => MutationObserverOptions<TData, TError, TVariables, TContext>,\n\t\tconfig?: {\n\t\t\tinitialInput?: TVariables\n\t\t\tinvalidates?: (orpc: TOrpc) => readonly QueryKey[]\n\t\t}\n\t) {\n\t\tconst invalidates = config?.invalidates\n\t\tconst mutation = useVueMutation(\n\t\t\tcomputed(() => {\n\t\t\t\tconst options = optionsFn(getO())\n\t\t\t\tif (!invalidates) return options\n\t\t\t\treturn {\n\t\t\t\t\t...options,\n\t\t\t\t\tonSuccess: async (\n\t\t\t\t\t\t...args: Parameters<NonNullable<typeof options.onSuccess>>\n\t\t\t\t\t) => {\n\t\t\t\t\t\tawait Promise.all(\n\t\t\t\t\t\t\tinvalidates(getO()).map((queryKey) =>\n\t\t\t\t\t\t\t\tqueryClient.invalidateQueries({ queryKey })\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t)\n\t\t\t\t\t\treturn options.onSuccess?.(...args)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t})\n\t\t)\n\t\tif (config?.initialInput === undefined) return mutation\n\t\tconst initialInput = config.initialInput\n\t\tconst inputData = ref(initialInput) as Ref<TVariables>\n\t\treturn {\n\t\t\t...mutation,\n\t\t\tinputData,\n\t\t\tmutate: (variables?: TVariables) =>\n\t\t\t\tmutation.mutate(variables ?? inputData.value),\n\t\t\tmutateAsync: (variables?: TVariables) =>\n\t\t\t\tmutation.mutateAsync(variables ?? inputData.value)\n\t\t}\n\t}\n\n\tfunction useSubscription<TInput, TEvent>(\n\t\tinput: MaybeRefOrGetter<TInput>,\n\t\tsubscribeFn: OrpcSubscribeFn<TInput, TEvent, TOrpc>,\n\t\toptions: UseSubscriptionOptions<TEvent, TOrpc> = {}\n\t) {\n\t\treturn useOrpcSubscription<TInput, TEvent, TOrpc>(input, subscribeFn, {\n\t\t\t...options,\n\t\t\torpc: getO\n\t\t})\n\t}\n\n\tconst keyOf = <TKey extends QueryKey>(keyFn: (orpc: TOrpc) => TKey) =>\n\t\tkeyFn(getO())\n\n\treturn {\n\t\t/** The utils themselves, for `queryClient.fetchQuery(orpc.x.queryOptions(...))` and the like. */\n\t\tget orpc(): TOrpc {\n\t\t\treturn getO()\n\t\t},\n\t\tuseQuery,\n\t\tuseInfiniteQuery,\n\t\tuseMutation,\n\t\tuseSubscription,\n\t\tinvalidate: (\n\t\t\tkeyFn: (orpc: TOrpc) => QueryKey,\n\t\t\tfilters?: Omit<InvalidateQueryFilters, 'queryKey'>\n\t\t) => queryClient.invalidateQueries({ queryKey: keyOf(keyFn), ...filters }),\n\t\t/** Route preloading and hover-to-prefetch. */\n\t\tprefetch: <\n\t\t\tTQueryFnData,\n\t\t\tTError = DefaultError,\n\t\t\tTData = TQueryFnData,\n\t\t\tTQueryKey extends QueryKey = QueryKey\n\t\t>(\n\t\t\toptionsFn: (\n\t\t\t\torpc: TOrpc\n\t\t\t) => FetchQueryOptions<TQueryFnData, TError, TData, TQueryKey>\n\t\t) => queryClient.prefetchQuery(optionsFn(getO())),\n\t\t/** Data is typed from oRPC's tagged key; pass `<TData>` for an untagged one. */\n\t\tgetQueryData: <TData = never, TKey extends QueryKey = QueryKey>(\n\t\t\tkeyFn: (orpc: TOrpc) => TKey\n\t\t): CachedData<TData, TKey> | undefined =>\n\t\t\tqueryClient.getQueryData<CachedData<TData, TKey>>(keyOf(keyFn)),\n\t\t/** Optimistic updates, typed like `getQueryData`. */\n\t\tsetQueryData: <TData = never, TKey extends QueryKey = QueryKey>(\n\t\t\tkeyFn: (orpc: TOrpc) => TKey,\n\t\t\tupdater: Updater<\n\t\t\t\tCachedData<TData, TKey> | undefined,\n\t\t\t\tCachedData<TData, TKey> | undefined\n\t\t\t>\n\t\t) =>\n\t\t\tqueryClient.setQueryData<CachedData<TData, TKey>>(keyOf(keyFn), updater),\n\t\tcancelQueries: (keyFn: (orpc: TOrpc) => QueryKey) =>\n\t\t\tqueryClient.cancelQueries({ queryKey: keyOf(keyFn) }),\n\t\tremoveQueries: (keyFn: (orpc: TOrpc) => QueryKey) =>\n\t\t\tqueryClient.removeQueries({ queryKey: keyOf(keyFn) }),\n\t\tisFetching: (keyFn?: (orpc: TOrpc) => QueryKey) =>\n\t\t\tqueryClient.isFetching(keyFn ? { queryKey: keyOf(keyFn) } : {}),\n\t\tqueryClient\n\t}\n}\n\ntype ApplyEvent<TStreamEvent, TData> = (\n\tevent: TStreamEvent,\n\tprevious: TData | undefined\n) => TData | undefined\n\ntype LiveQueryOptions<\n\tTInput,\n\tTRouteData,\n\tTStreamEvent,\n\tTData,\n\tTOrpc,\n\tTSubscriptionInput\n> = {\n\timmediate?: MaybeRefOrGetter<boolean>\n\torpc?: MaybeRefOrGetter<TOrpc>\n\t/** Input for the stream when it differs from the query's. */\n\tsubscriptionInput?: MaybeRefOrGetter<TSubscriptionInput>\n\t/**\n\t * Convert the route output once at fetch time into a differently typed\n\t * cache; `applyEvent` then reduces stream events into that cache.\n\t */\n\tselect?: (data: TRouteData) => TData\n\t/**\n\t * The raw route output of a seed before `select` drops fields. `input` is\n\t * what the seed was fetched for, so a seed that resolves after the input\n\t * moved on can be told apart.\n\t */\n\tonSeed?: (data: TRouteData, input: TInput) => void\n\t/**\n\t * Fold a stream event into the cached data. Required when the stream sends\n\t * something other than the cached type (an `fnLive` patch route, or a\n\t * `select`ed cache). Return `undefined` to skip the write.\n\t */\n\tapplyEvent?: ApplyEvent<TStreamEvent, NoInfer<TData>>\n\tonEvent?: (event: TStreamEvent, meta?: { connectionId: number }) => void\n\tonError?: (error: Error) => void\n\t/**\n\t * Reconcile a fetched seed with what the stream already wrote. The HTTP\n\t * request can resolve last, so a plain overwrite would drop events that\n\t * arrived while it was in flight. Default: take the fetched value.\n\t */\n\tmergeSeed?: (\n\t\tfetched: NoInfer<TData>,\n\t\tcached: NoInfer<TData> | undefined\n\t) => NoInfer<TData>\n\t/**\n\t * Show the previous key's data while a new key loads (default: true). Pass\n\t * false when the key says which entity is shown, not just how it is\n\t * filtered: another conversation's timeline must not stand in for this one.\n\t */\n\tkeepPreviousData?: boolean\n\t/** Pause the stream while the page is hidden (default: true). */\n\trespectVisibility?: boolean\n}\n\ntype LiveQueryReturn<TData, TError> = ReturnType<\n\ttypeof useVueQuery<TData, TError>\n> & { liveStatus: Ref<LiveConnectionStatus> }\n\n/**\n * The client half of `fnLive`: the HTTP query seeds the cache, and the live\n * route's stream writes each snapshot into the same cache entry. Marked\n * `meta.live`, so invalidation streams leave it alone.\n *\n * One signature, not overloads: TypeScript fixes an untyped callback's\n * parameters at the first overload it tries, which made valid calls fail.\n */\nexport function useLiveQuery<\n\tTInput,\n\tTRouteData,\n\tTStreamEvent,\n\tTData = TRouteData,\n\tTError = Error,\n\tTOrpc = RegisteredOrpcUtils,\n\tTSubscriptionInput = TInput\n>(\n\tinput: MaybeRefOrGetter<TInput>,\n\tqueryOptionsFn: (\n\t\tinput: TInput,\n\t\torpc: TOrpc\n\t) => UseQueryOptions<TRouteData, TError> & { queryKey: QueryKey },\n\tsubscribeFn: OrpcSubscribeFn<\n\t\tNoInfer<TSubscriptionInput>,\n\t\tTStreamEvent,\n\t\tTOrpc\n\t>,\n\t...options: [TStreamEvent] extends [TData]\n\t\t? [\n\t\t\t\toptions?: LiveQueryOptions<\n\t\t\t\t\tTInput,\n\t\t\t\t\tTRouteData,\n\t\t\t\t\tTStreamEvent,\n\t\t\t\t\tTData,\n\t\t\t\t\tTOrpc,\n\t\t\t\t\tTSubscriptionInput\n\t\t\t\t>\n\t\t\t]\n\t\t: [\n\t\t\t\toptions: LiveQueryOptions<\n\t\t\t\t\tTInput,\n\t\t\t\t\tTRouteData,\n\t\t\t\t\tTStreamEvent,\n\t\t\t\t\tTData,\n\t\t\t\t\tTOrpc,\n\t\t\t\t\tTSubscriptionInput\n\t\t\t\t> & { applyEvent: ApplyEvent<TStreamEvent, NoInfer<TData>> }\n\t\t\t]\n): LiveQueryReturn<TData, TError>\nexport function useLiveQuery<\n\tTInput,\n\tTRouteData,\n\tTStreamEvent,\n\tTData,\n\tTError,\n\tTOrpc,\n\tTSubscriptionInput\n>(\n\tinput: MaybeRefOrGetter<TInput>,\n\tqueryOptionsFn: (\n\t\tinput: TInput,\n\t\torpc: TOrpc\n\t) => UseQueryOptions<TRouteData, TError> & { queryKey: QueryKey },\n\tsubscribeFn: OrpcSubscribeFn<TSubscriptionInput, TStreamEvent, TOrpc>,\n\toptions: LiveQueryOptions<\n\t\tTInput,\n\t\tTRouteData,\n\t\tTStreamEvent,\n\t\tTData,\n\t\tTOrpc,\n\t\tTSubscriptionInput\n\t> = {}\n): LiveQueryReturn<TData, TError> {\n\tconst queryClient = useQueryClient()\n\tconst getO = useUtilsGetter(options.orpc)\n\tconst visible = useDocumentVisible()\n\t// Without `applyEvent` the stream event is the cache type (the first overload).\n\tconst applyEvent =\n\t\toptions.applyEvent ?? ((event: TStreamEvent) => event as unknown as TData)\n\t// Recomputed when the input changes, not once per stream event.\n\tconst queryKey = computed(\n\t\t() => queryOptionsFn(toValue(input), getO()).queryKey\n\t)\n\tconst queryHash = computed(() => hashKey(queryKey.value))\n\tconst scope = createStreamScope()\n\n\tconst subscription = useOrpcSubscription(\n\t\tcomputed(\n\t\t\t() =>\n\t\t\t\t(options.subscriptionInput === undefined\n\t\t\t\t\t? toValue(input)\n\t\t\t\t\t: toValue(options.subscriptionInput)) as TSubscriptionInput\n\t\t),\n\t\tsubscribeFn,\n\t\t{\n\t\t\timmediate: options.immediate,\n\t\t\trespectVisibility: options.respectVisibility,\n\t\t\tonError: options.onError,\n\t\t\tmaxEvents: 1,\n\t\t\torpc: getO,\n\t\t\tonConnect: (connectionId) => scope.open(connectionId, queryHash.value),\n\t\t\tonEvent: (event, meta) => {\n\t\t\t\t// The consumer callback must not see an event for a scope no longer shown.\n\t\t\t\tif (!meta || !scope.owns(meta.connectionId, queryHash.value)) return\n\t\t\t\tconst key = queryKey.value\n\t\t\t\tconst next = applyEvent(event, queryClient.getQueryData<TData>(key))\n\t\t\t\tif (next !== undefined) queryClient.setQueryData(key, next)\n\t\t\t\toptions.onEvent?.(event, meta)\n\t\t\t}\n\t\t}\n\t)\n\n\tconst query = useVueQuery<TData, TError>(\n\t\tcomputed(() => {\n\t\t\tconst inputValue = toValue(input)\n\t\t\t// oRPC query options are plain objects at runtime; vue-query's type\n\t\t\t// wraps fields in MaybeRefDeep, so `queryFn` is read through one shape.\n\t\t\tconst raw = queryOptionsFn(inputValue, getO()) as unknown as {\n\t\t\t\tqueryKey: QueryKey\n\t\t\t\tqueryFn?: (context: unknown) => Promise<TRouteData>\n\t\t\t\tenabled?: unknown\n\t\t\t} & Record<string, unknown>\n\t\t\tconst wrapsSeed = options.select || options.mergeSeed\n\t\t\tconst queryFn =\n\t\t\t\traw.queryFn && wrapsSeed\n\t\t\t\t\t? seedQueryFn(raw.queryFn, {\n\t\t\t\t\t\t\tinput: inputValue,\n\t\t\t\t\t\t\treadCache: () => queryClient.getQueryData<TData>(raw.queryKey),\n\t\t\t\t\t\t\tselect: options.select,\n\t\t\t\t\t\t\tonSeed: options.onSeed,\n\t\t\t\t\t\t\tmergeSeed: options.mergeSeed\n\t\t\t\t\t\t})\n\t\t\t\t\t: raw.queryFn\n\t\t\treturn {\n\t\t\t\t...raw,\n\t\t\t\t...(queryFn ? { queryFn } : {}),\n\t\t\t\tenabled: visible.value && resolveQueryEnabled(raw.enabled),\n\t\t\t\t...(options.keepPreviousData === false\n\t\t\t\t\t? {}\n\t\t\t\t\t: { placeholderData: keepPreviousData }),\n\t\t\t\tstaleTime: Number.POSITIVE_INFINITY,\n\t\t\t\tmeta: { live: true }\n\t\t\t} as unknown as UseQueryOptions<TData, TError>\n\t\t})\n\t)\n\n\treturn Object.assign(query, { liveStatus: subscription.status })\n}\n\n/**\n * Treat a stream as a \"something changed\" ping: invalidate `keyFn` on each\n * event. Prefer {@link useLiveQuery} when the stream carries the data itself.\n */\nexport function useSubscriptionInvalidates<\n\tTInput,\n\tTEvent,\n\tTOrpc = RegisteredOrpcUtils\n>(\n\tinput: MaybeRefOrGetter<TInput>,\n\tsubscribeFn: OrpcSubscribeFn<TInput, TEvent, TOrpc>,\n\tkeyFn: (orpc: TOrpc) => QueryKey,\n\toptions: Pick<\n\t\tUseSubscriptionOptions<TEvent, TOrpc>,\n\t\t'immediate' | 'maxEvents' | 'respectVisibility' | 'orpc'\n\t> & {\n\t\tonEvent?: (event: TEvent) => void\n\t\t/** Return false to skip invalidation for this event. */\n\t\tshouldInvalidate?: (event: TEvent) => boolean\n\t} = {}\n): UseSubscriptionReturn<TEvent> {\n\tconst { onEvent, shouldInvalidate, ...subscriptionOptions } = options\n\tconst { useSubscription, invalidate } = useApiClient<TOrpc>({\n\t\torpc: options.orpc\n\t})\n\treturn useSubscription(input, subscribeFn, {\n\t\t...subscriptionOptions,\n\t\tonEvent: (event) => {\n\t\t\tonEvent?.(event)\n\t\t\tif (shouldInvalidate?.(event) === false) return\n\t\t\tvoid invalidate(keyFn)\n\t\t}\n\t})\n}\n\n/**\n * One app-wide stream of `{ domain }` change events that keeps list and count\n * queries fresh: each event invalidates its domain's query keys (debounced),\n * and a reconnect that proves healthy invalidates every domain to cover\n * events lost while it was down. Call once, in the signed-in shell.\n *\n * ```ts\n * useInvalidationStream({}, (o) => o.realtime.subscribeChanges.call, {\n * domains: { order: { debounceMs: 100, queryKeys: [orpc.order.key()] } }\n * })\n * ```\n */\nexport function useInvalidationStream<\n\tTInput,\n\tTEvent extends { domain: string },\n\tTOrpc = RegisteredOrpcUtils\n>(\n\tinput: MaybeRefOrGetter<TInput>,\n\tsubscribe: OrpcSubscribeFn<TInput, TEvent, TOrpc>,\n\toptions: InvalidationStreamOptions<TEvent> &\n\t\tPick<\n\t\t\tUseSubscriptionOptions<TEvent, TOrpc>,\n\t\t\t'immediate' | 'respectVisibility' | 'orpc'\n\t\t>\n): UseSubscriptionReturn<TEvent> {\n\tconst coordinator = createInvalidationCoordinator(useQueryClient(), options)\n\tif (getCurrentScope()) onScopeDispose(coordinator.dispose)\n\treturn useOrpcSubscription<TInput, TEvent, TOrpc>(input, subscribe, {\n\t\timmediate: options.immediate,\n\t\trespectVisibility: options.respectVisibility,\n\t\torpc: options.orpc,\n\t\tmaxEvents: 1,\n\t\tonEvent: coordinator.event,\n\t\tonConnect: coordinator.connect,\n\t\tonError: coordinator.lost,\n\t\tonClose: coordinator.lost\n\t})\n}\n\n/** Localized text for a failed query: your fallback unless the server marked its message user-safe. */\nexport function useQueryErrorMessage(\n\terror: MaybeRefOrGetter<unknown>,\n\tfallback: MaybeRefOrGetter<string>\n) {\n\treturn computed(() => {\n\t\tconst err = toValue(error)\n\t\treturn err ? userFacingErrorMessage(err, toValue(fallback)) : null\n\t})\n}\n\n/** The parts of a query `useQueryState` reads. */\nexport type QueryStateSource = {\n\tstatus: Ref<'pending' | 'error' | 'success'>\n\terror: Ref<unknown>\n\tisFetching: Ref<boolean>\n\tfailureCount: Ref<number>\n\trefetch: () => Promise<unknown>\n}\n\n/**\n * A query as the props a list or loading component takes, in one reactive\n * object: `<ListStates v-bind=\"useQueryState(query, { fallback })\" />`.\n * `errorMessage` follows {@link useQueryErrorMessage}.\n */\nexport function useQueryState(\n\tquery: QueryStateSource,\n\toptions: { fallback: MaybeRefOrGetter<string> }\n) {\n\tconst errorMessage = useQueryErrorMessage(query.error, options.fallback)\n\treturn reactive({\n\t\tstatus: computed(() => query.status.value),\n\t\terror: computed(() => query.error.value),\n\t\terrorMessage,\n\t\tisRetrying: computed(\n\t\t\t() =>\n\t\t\t\tquery.isFetching.value &&\n\t\t\t\t(query.status.value === 'error' || query.failureCount.value > 0)\n\t\t),\n\t\tretry: () => {\n\t\t\tvoid query.refetch()\n\t\t}\n\t})\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "orpc-fn",
3
- "version": "0.8.0",
3
+ "version": "0.9.0",
4
4
  "description": "Define a backend function once: a typed oRPC procedure with tracing, logging, guards, injected handler extras, nested calls and live queries over Redis.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -24,7 +24,9 @@ export function createProcedureAssembler(
24
24
  name: route.name,
25
25
  procedure: key,
26
26
  meta: route.meta,
27
- stream: route.stream ?? false
27
+ stream: route.stream ?? false,
28
+ guards: route.guards ?? {},
29
+ dynamicGuards: route.dynamicGuards ?? []
28
30
  }
29
31
  builder = builder
30
32
  .route({
package/src/client.ts CHANGED
@@ -2,6 +2,10 @@ import { type ClientContext, ORPCError, type ORPCErrorCode } from '@orpc/client'
2
2
  import { RPCLink, type RPCLinkOptions } from '@orpc/client/fetch'
3
3
  import { BatchLinkPlugin } from '@orpc/client/plugins'
4
4
  import { StandardRPCJsonSerializer } from '@orpc/client/standard'
5
+ import { formatIssue, issuesOf } from './issues.js'
6
+ import { isStreamCall } from './stream-call.js'
7
+
8
+ export { STREAM_CALL, streamCall } from './stream-call.js'
5
9
 
6
10
  type BatchOptions<T extends ClientContext> = ConstructorParameters<
7
11
  typeof BatchLinkPlugin<T>
@@ -9,6 +13,12 @@ type BatchOptions<T extends ClientContext> = ConstructorParameters<
9
13
 
10
14
  export type CreateRpcLinkOptions<T extends ClientContext> =
11
15
  RPCLinkOptions<T> & {
16
+ /**
17
+ * Client-safe manifest generated by createStreamManifest(router). Calls
18
+ * opened by the framework helpers, or with `context: streamCall`, are
19
+ * recognised without it.
20
+ */
21
+ streamPaths?: readonly (readonly string[])[]
12
22
  /**
13
23
  * Collapse parallel calls into one HTTP request, matching `mountOrpc`'s
14
24
  * server-side batching. Default: true (25 calls). Pass false to turn off.
@@ -17,8 +27,6 @@ export type CreateRpcLinkOptions<T extends ClientContext> =
17
27
  * default only calls without a client context are batched; pass
18
28
  * `groups` to batch calls that share a context (e.g. a token).
19
29
  */
20
- /** Client-safe manifest generated by createStreamManifest(router). */
21
- streamPaths?: readonly (readonly string[])[]
22
30
  batch?:
23
31
  | boolean
24
32
  | {
@@ -69,6 +77,7 @@ export function createRpcLink<T extends ClientContext = ClientContext>(
69
77
  { condition: () => true, context: {} as T }
70
78
  ],
71
79
  exclude: ({ path, context }) =>
80
+ isStreamCall(context) ||
72
81
  streams.has(JSON.stringify(path)) ||
73
82
  exclude(path) ||
74
83
  (groups === undefined && Object.keys(context).length > 0)
@@ -120,6 +129,21 @@ export function userFacingErrorMessage(
120
129
  return userSafeServerMessage(error) ?? fallback
121
130
  }
122
131
 
132
+ /**
133
+ * Like {@link userFacingErrorMessage}, but a rejected input lists its
134
+ * fields: the server's `userMessage`, else one `path: message` line per
135
+ * validation issue of a BAD_REQUEST, else your fallback.
136
+ */
137
+ export function formatClientError(error: unknown, fallback: string): string {
138
+ const safe = userSafeServerMessage(error)
139
+ if (safe) return safe
140
+ if (error instanceof ORPCError && error.code === 'BAD_REQUEST') {
141
+ const issues = issuesOf(error)
142
+ if (issues.length > 0) return issues.map(formatIssue).join('\n')
143
+ }
144
+ return fallback
145
+ }
146
+
123
147
  const cacheSerializer = new StandardRPCJsonSerializer()
124
148
 
125
149
  /**
package/src/create-fn.ts CHANGED
@@ -7,8 +7,8 @@ import { normalizeRoute } from './route-options.js'
7
7
  import { type AnyProcedure, ORPCError, os } from '@orpc/server'
8
8
  import { procedureDefinition } from './compatibility.js'
9
9
  import { type BoundCall, createBoundCall } from './bound-call.js'
10
- import { isExpectedClientError } from './expected-client-error.js'
11
- import { createFnLive, type FnLive } from './live/fn-live.js'
10
+ import { isExpectedClientError, markExpected } from './expected-client-error.js'
11
+ import { createFnLive, type FnLive, fnLivePatch } from './live/fn-live.js'
12
12
  import {
13
13
  type CreatePublisher,
14
14
  type CreatePubSub,
@@ -21,7 +21,7 @@ import {
21
21
  type FnLogger,
22
22
  type LogAttributes
23
23
  } from './logger.js'
24
- import { readFnMeta } from './meta.js'
24
+ import { type FnMeta, readFnMeta } from './meta.js'
25
25
  import {
26
26
  type AttributeValue,
27
27
  createTracing,
@@ -31,7 +31,12 @@ import {
31
31
  type SpanLike,
32
32
  type SpanOf
33
33
  } from './otel.js'
34
- import { RAW_INPUT, REQUEST_TIMING, type InvocationTiming } from './timing.js'
34
+ import {
35
+ EXTRAS_OVERRIDE,
36
+ RAW_INPUT,
37
+ REQUEST_TIMING,
38
+ type InvocationTiming
39
+ } from './timing.js'
35
40
  import { createRouter } from './router.js'
36
41
  import {
37
42
  type ProcedureHookParams,
@@ -44,6 +49,7 @@ import {
44
49
  type FnCompletedEvent,
45
50
  type FnDefinition,
46
51
  type Guard,
52
+ type GuardOptions,
47
53
  type GuardParams,
48
54
  type MaybePromise,
49
55
  type RejectKeys,
@@ -74,9 +80,29 @@ type RuntimeOptions = {
74
80
  }) => Record<string, AttributeValue | undefined>
75
81
  onCompleted?: (event: FnCompletedEvent) => LogAttributes | undefined
76
82
  isExpectedError?: (error: unknown) => boolean
83
+ errorMessages?: 'all' | 'unexpected'
84
+ routePolicy?: (route: Record<string, unknown>) => void
77
85
  pubsub?: PubSubRuntimeOptions
78
86
  }
79
87
 
88
+ /** What `routePolicy` sees of each route when it is defined. */
89
+ export type RoutePolicyParams<
90
+ TKey extends string = string,
91
+ TGuards = Record<string, unknown>,
92
+ TMeta extends object = Record<string, unknown>,
93
+ TTag extends string = string
94
+ > = {
95
+ name: string
96
+ procedure: TKey
97
+ /** Guard values set on the route itself. */
98
+ guards: GuardOptions<TGuards>
99
+ /** Guards the route decides per call through `guardResolvers`. */
100
+ dynamicGuards: readonly (keyof TGuards & string)[]
101
+ meta: Partial<TMeta>
102
+ stream: boolean
103
+ tags: readonly TTag[]
104
+ }
105
+
80
106
  export type CreateFnOptions<
81
107
  TProcedures extends Record<string, BuilderLike>,
82
108
  TDefault extends keyof TProcedures & string,
@@ -160,8 +186,31 @@ export type CreateFnOptions<
160
186
  event: CompletedHookEvent<TProcedures, SpanOf<TOtel>>
161
187
  // biome-ignore lint/suspicious/noConfusingVoidType: lets hooks that return nothing type-check
162
188
  ) => LogAttributes | undefined | void
163
- /** Errors that are the caller's fault, logged at `warn`. Default: 4xx `ORPCError` or `AbortError`. */
189
+ /**
190
+ * Errors that are the caller's fault: logged at `warn`, and their span keeps
191
+ * an unset status. `mountOrpc` and the tool adapters follow it for errors
192
+ * a route threw. Default: 4xx `ORPCError` or `AbortError`.
193
+ */
164
194
  isExpectedError?: (error: unknown) => boolean
195
+ /**
196
+ * `'unexpected'` leaves the message of expected errors out of `fn.completed`
197
+ * (it was written for the caller and may name what they asked for);
198
+ * `error_code` and `error_type` stay. Default: `'all'`.
199
+ */
200
+ errorMessages?: 'all' | 'unexpected'
201
+ /**
202
+ * Sees every route (`fn`, `fnLive`, pub/sub subscriptions) when it is
203
+ * defined; throw to reject it, e.g. a protected route with no permission:
204
+ * `if (procedure === 'protected' && !('permission' in guards)) throw ...`.
205
+ */
206
+ routePolicy?: (
207
+ route: RoutePolicyParams<
208
+ keyof TProcedures & string,
209
+ NoInfer<TGuards>,
210
+ NoInfer<TMeta>,
211
+ NoInfer<TTag>
212
+ >
213
+ ) => void
165
214
  /** Needed for `fnLive` and `createPubSub`. */
166
215
  pubsub?: PubSubRuntimeOptions
167
216
  }
@@ -191,13 +240,31 @@ type Definition<
191
240
  logger: TLogger
192
241
  }
193
242
 
243
+ /** Extras a test call may replace: any shared or scoped extra. */
244
+ export type TestCallExtras<TDef extends FnDefinition> = Partial<
245
+ TDef['extras']
246
+ > &
247
+ (TDef extends { extrasByProcedure: infer E }
248
+ ? [keyof E] extends [never]
249
+ ? object
250
+ : Partial<NonNullable<E[keyof E]>>
251
+ : object)
252
+
194
253
  export type FnFactory<TDef extends FnDefinition> = {
195
254
  fn: Fn<TDef>
196
255
  fnLive: FnLive<TDef>
256
+ /** Same as `fnLivePatch` from `orpc-fn/live`. */
257
+ fnLivePatch: typeof fnLivePatch
197
258
  createPubSub: CreatePubSub<TDef>
198
259
  createPublisher: CreatePublisher
199
260
  createRouter: typeof createRouter
200
- readMeta: typeof readFnMeta
261
+ /** `readFnMeta`, with guard values typed by this factory's guards. */
262
+ readMeta: <T extends AnyProcedure>(
263
+ procedure: T
264
+ ) => Omit<ReturnType<typeof readFnMeta<T>>, 'guards' | 'dynamicGuards'> & {
265
+ guards: GuardOptions<TDef['guards']>
266
+ dynamicGuards: readonly (keyof TDef['guards'] & string)[]
267
+ }
201
268
  /**
202
269
  * A `call` outside any handler (seeders, scripts, tests), traced with this
203
270
  * instance's OpenTelemetry.
@@ -206,9 +273,26 @@ export type FnFactory<TDef extends FnDefinition> = {
206
273
  context: TContext,
207
274
  signal?: AbortSignal
208
275
  ) => BoundCall<TContext>
276
+ /**
277
+ * `createCall` for tests: middleware, guards and schemas run as in
278
+ * production, and `extras` replace the configured ones (`{ db: fakeDb }`)
279
+ * for this call and the calls it makes.
280
+ */
281
+ createTestCall: <TContext>(
282
+ context: TContext,
283
+ options?: { extras?: TestCallExtras<TDef>; signal?: AbortSignal }
284
+ ) => BoundCall<TContext>
209
285
  /** Terminal, idempotent shutdown: close streams and await owned resources. */
210
286
  shutdown: () => Promise<void>
211
- drainPubSubSubscribers: () => number
287
+ /**
288
+ * End every open subscription and return how many were closed. With
289
+ * `overMs`, spread the closes evenly over that window so clients do not
290
+ * reconnect in one burst; the promise resolves after the last one.
291
+ */
292
+ drainPubSubSubscribers: {
293
+ (): number
294
+ (options: { overMs: number }): Promise<number>
295
+ }
212
296
  activePubSubSubscriberCount: () => number
213
297
  }
214
298
 
@@ -256,7 +340,18 @@ export function createFn<
256
340
  >
257
341
  > {
258
342
  const runtime = options as unknown as RuntimeOptions
259
- const tracing = createTracing(runtime.otel)
343
+ const configuredExpected = runtime.isExpectedError ?? isExpectedClientError
344
+ const isExpectedError = (error: unknown) => {
345
+ let expected: boolean
346
+ try {
347
+ expected = configuredExpected(error)
348
+ } catch {
349
+ expected = isExpectedClientError(error)
350
+ }
351
+ if (expected) markExpected(error)
352
+ return expected
353
+ }
354
+ const tracing = createTracing(runtime.otel, isExpectedError)
260
355
  const defaultLogger = protectLogger(createDefaultLogger('fn'))
261
356
  const createLogger = (
262
357
  scope: string,
@@ -271,7 +366,12 @@ export function createFn<
271
366
  return defaultLogger
272
367
  }
273
368
  }
274
- const isExpectedError = runtime.isExpectedError ?? isExpectedClientError
369
+ if (
370
+ runtime.errorMessages !== undefined &&
371
+ runtime.errorMessages !== 'all' &&
372
+ runtime.errorMessages !== 'unexpected'
373
+ )
374
+ throw new TypeError("orpc-fn: errorMessages must be 'all' or 'unexpected'")
275
375
  const guards = runtime.guards ?? {}
276
376
  const isGuard = (option: string) => Object.hasOwn(guards, option)
277
377
  for (const guard of Object.keys(guards)) {
@@ -334,11 +434,24 @@ export function createFn<
334
434
  guardChecks
335
435
  } = normalizeRoute(routeOptions, isGuard)
336
436
  const key = resolveKey(procedure, name)
437
+ const staticGuards = Object.fromEntries(guardChecks)
438
+ const dynamicGuards = Object.keys(guardResolvers)
439
+ runtime.routePolicy?.({
440
+ name,
441
+ procedure: key,
442
+ guards: staticGuards,
443
+ dynamicGuards,
444
+ meta,
445
+ stream,
446
+ tags: (route.tags as string[] | undefined) ?? []
447
+ })
337
448
  const built = buildProcedure({
338
449
  name,
339
450
  procedure: key,
340
451
  route,
341
452
  meta,
453
+ guards: staticGuards,
454
+ dynamicGuards,
342
455
  input,
343
456
  output,
344
457
  stream,
@@ -346,7 +459,11 @@ export function createFn<
346
459
  handler: async (params) => {
347
460
  const { context, signal } = params
348
461
  const state = context[invocation] as Invocation
349
- const { [invocation]: _invocation, ...observedContext } = context
462
+ const {
463
+ [invocation]: _invocation,
464
+ [EXTRAS_OVERRIDE]: overrides,
465
+ ...observedContext
466
+ } = context
350
467
  state.context = observedContext
351
468
  state.input = params.input
352
469
  state.handlerStarted = true
@@ -398,7 +515,8 @@ export function createFn<
398
515
  const scoped = await runtime.extrasByProcedure?.[key]?.(extraParams)
399
516
  const extras = {
400
517
  ...(shared as object | undefined),
401
- ...(scoped as object | undefined)
518
+ ...(scoped as object | undefined),
519
+ ...(overrides as object | undefined)
402
520
  }
403
521
  if (extras && typeof extras === 'object') {
404
522
  for (const reserved of [
@@ -510,12 +628,7 @@ export function createFn<
510
628
  error: errorMessageOf(hookError)
511
629
  })
512
630
  }
513
- let expected = false
514
- try {
515
- expected = isExpectedError(error)
516
- } catch {
517
- expected = isExpectedClientError(error)
518
- }
631
+ const expected = !success && isExpectedError(error)
519
632
  const level = success ? 'info' : expected ? 'warn' : 'error'
520
633
  logger[level]('fn.completed', {
521
634
  ...extra,
@@ -524,7 +637,12 @@ export function createFn<
524
637
  procedure: event.procedure,
525
638
  duration_ms: event.durationMs,
526
639
  status: success ? 'success' : 'failed',
527
- ...(error === undefined ? {} : errorAttributes(error))
640
+ ...(success
641
+ ? {}
642
+ : errorAttributes(
643
+ error,
644
+ !(expected && runtime.errorMessages === 'unexpected')
645
+ ))
528
646
  })
529
647
  }
530
648
 
@@ -535,6 +653,8 @@ export function createFn<
535
653
  pubsub: runtime.pubsub
536
654
  })
537
655
 
656
+ const readMeta = (procedure: AnyProcedure): FnMeta => readFnMeta(procedure)
657
+
538
658
  // The runtimes are untyped; `Fn`, `FnLive`, `CreatePubSub` and
539
659
  // `CreatePublisher` are their typed surface.
540
660
  return {
@@ -544,12 +664,22 @@ export function createFn<
544
664
  createChannel: live.createChannel,
545
665
  isGuard
546
666
  }),
667
+ fnLivePatch,
547
668
  createPubSub: live.createPubSub,
548
669
  createPublisher: live.createPublisher,
549
670
  createRouter,
550
- readMeta: readFnMeta,
671
+ readMeta,
551
672
  createCall: <TContext>(context: TContext, signal?: AbortSignal) =>
552
673
  createBoundCall(context, signal, tracing),
674
+ createTestCall: <TContext>(
675
+ context: TContext,
676
+ { extras, signal }: { extras?: object; signal?: AbortSignal } = {}
677
+ ) =>
678
+ createBoundCall(
679
+ extras ? { ...context, [EXTRAS_OVERRIDE]: extras } : context,
680
+ signal,
681
+ tracing
682
+ ),
553
683
  shutdown: live.shutdown,
554
684
  drainPubSubSubscribers: live.drainPubSubSubscribers,
555
685
  activePubSubSubscriberCount: live.activePubSubSubscriberCount
@@ -1,5 +1,9 @@
1
1
  import { ORPCError } from '@orpc/server'
2
2
 
3
+ // ponytail: one set per package copy; apps with two installed copies of
4
+ // orpc-fn must still pass isExpectedError to mountOrpc and the tool adapters.
5
+ const classifiedExpected = new WeakSet<object>()
6
+
3
7
  /**
4
8
  * An expected client failure: an `ORPCError` with a 4xx status (validation,
5
9
  * auth, not-found) or an `AbortError` (the client closed the connection, e.g.
@@ -7,13 +11,28 @@ import { ORPCError } from '@orpc/server'
7
11
  * drives, not server defects, so they must not be logged at `error` severity
8
12
  * or reported to error tracking. Only 5xx and unknown failures are defects.
9
13
  *
14
+ * It is also true for any error a `createFn({ isExpectedError })` classified
15
+ * as expected when a route threw it, so `mountOrpc` and the tool adapters
16
+ * follow the factory's rule without being told it again.
17
+ *
10
18
  * This is the default `isExpectedError`; extend it with `createFn({ isExpectedError })`.
11
19
  */
12
20
  export function isExpectedClientError(error: unknown): boolean {
13
21
  if (error instanceof ORPCError && error.status < 500) return true
22
+ if (
23
+ typeof error === 'object' &&
24
+ error !== null &&
25
+ classifiedExpected.has(error)
26
+ )
27
+ return true
14
28
  return isAbortError(error)
15
29
  }
16
30
 
31
+ /** @internal Remembers that the factory's `isExpectedError` accepted `error`. */
32
+ export function markExpected(error: unknown): void {
33
+ if (typeof error === 'object' && error !== null) classifiedExpected.add(error)
34
+ }
35
+
17
36
  function isAbortError(error: unknown): boolean {
18
37
  return (
19
38
  typeof error === 'object' &&