@trpc/client
Advanced tools
| const require_chunk = require('./chunk-DWy1uDak.cjs'); | ||
| const require_objectSpread2$1 = require('./objectSpread2-Bsvh_OqM.cjs'); | ||
| const require_TRPCClientError = require('./TRPCClientError-CQrTQLrk.cjs'); | ||
| const require_httpUtils = require('./httpUtils-CjSUiDDG.cjs'); | ||
| const __trpc_server_observable = require_chunk.__toESM(require("@trpc/server/observable")); | ||
| const __trpc_server_unstable_core_do_not_import = require_chunk.__toESM(require("@trpc/server/unstable-core-do-not-import")); | ||
| //#region src/internals/dataLoader.ts | ||
| /** | ||
| * A function that should never be called unless we messed something up. | ||
| */ | ||
| const throwFatalError = () => { | ||
| throw new Error("Something went wrong. Please submit an issue at https://github.com/trpc/trpc/issues/new"); | ||
| }; | ||
| /** | ||
| * Dataloader that's very inspired by https://github.com/graphql/dataloader | ||
| * Less configuration, no caching, and allows you to cancel requests | ||
| * When cancelling a single fetch the whole batch will be cancelled only when _all_ items are cancelled | ||
| */ | ||
| function dataLoader(batchLoader) { | ||
| let pendingItems = null; | ||
| let dispatchTimer = null; | ||
| const destroyTimerAndPendingItems = () => { | ||
| clearTimeout(dispatchTimer); | ||
| dispatchTimer = null; | ||
| pendingItems = null; | ||
| }; | ||
| /** | ||
| * Iterate through the items and split them into groups based on the `batchLoader`'s validate function | ||
| */ | ||
| function groupItems(items) { | ||
| const groupedItems = [[]]; | ||
| let index = 0; | ||
| while (true) { | ||
| const item = items[index]; | ||
| if (!item) break; | ||
| const lastGroup = groupedItems[groupedItems.length - 1]; | ||
| if (item.aborted) { | ||
| var _item$reject; | ||
| (_item$reject = item.reject) === null || _item$reject === void 0 || _item$reject.call(item, new Error("Aborted")); | ||
| index++; | ||
| continue; | ||
| } | ||
| const isValid = batchLoader.validate(lastGroup.concat(item).map((it) => it.key)); | ||
| if (isValid) { | ||
| lastGroup.push(item); | ||
| index++; | ||
| continue; | ||
| } | ||
| if (lastGroup.length === 0) { | ||
| var _item$reject2; | ||
| (_item$reject2 = item.reject) === null || _item$reject2 === void 0 || _item$reject2.call(item, new Error("Input is too big for a single dispatch")); | ||
| index++; | ||
| continue; | ||
| } | ||
| groupedItems.push([]); | ||
| } | ||
| return groupedItems; | ||
| } | ||
| function dispatch() { | ||
| const groupedItems = groupItems(pendingItems); | ||
| destroyTimerAndPendingItems(); | ||
| for (const items of groupedItems) { | ||
| if (!items.length) continue; | ||
| const batch = { items }; | ||
| for (const item of items) item.batch = batch; | ||
| const promise = batchLoader.fetch(batch.items.map((_item) => _item.key)); | ||
| promise.then(async (result) => { | ||
| await Promise.all(result.map(async (valueOrPromise, index) => { | ||
| const item = batch.items[index]; | ||
| try { | ||
| var _item$resolve; | ||
| const value = await Promise.resolve(valueOrPromise); | ||
| (_item$resolve = item.resolve) === null || _item$resolve === void 0 || _item$resolve.call(item, value); | ||
| } catch (cause) { | ||
| var _item$reject3; | ||
| (_item$reject3 = item.reject) === null || _item$reject3 === void 0 || _item$reject3.call(item, cause); | ||
| } | ||
| item.batch = null; | ||
| item.reject = null; | ||
| item.resolve = null; | ||
| })); | ||
| for (const item of batch.items) { | ||
| var _item$reject4; | ||
| (_item$reject4 = item.reject) === null || _item$reject4 === void 0 || _item$reject4.call(item, new Error("Missing result")); | ||
| item.batch = null; | ||
| } | ||
| }).catch((cause) => { | ||
| for (const item of batch.items) { | ||
| var _item$reject5; | ||
| (_item$reject5 = item.reject) === null || _item$reject5 === void 0 || _item$reject5.call(item, cause); | ||
| item.batch = null; | ||
| } | ||
| }); | ||
| } | ||
| } | ||
| function load(key) { | ||
| var _dispatchTimer; | ||
| const item = { | ||
| aborted: false, | ||
| key, | ||
| batch: null, | ||
| resolve: throwFatalError, | ||
| reject: throwFatalError | ||
| }; | ||
| const promise = new Promise((resolve, reject) => { | ||
| var _pendingItems; | ||
| item.reject = reject; | ||
| item.resolve = resolve; | ||
| (_pendingItems = pendingItems) !== null && _pendingItems !== void 0 || (pendingItems = []); | ||
| pendingItems.push(item); | ||
| }); | ||
| (_dispatchTimer = dispatchTimer) !== null && _dispatchTimer !== void 0 || (dispatchTimer = setTimeout(dispatch)); | ||
| return promise; | ||
| } | ||
| return { load }; | ||
| } | ||
| //#endregion | ||
| //#region src/internals/signals.ts | ||
| /** | ||
| * Like `Promise.all()` but for abort signals | ||
| * - When all signals have been aborted, the merged signal will be aborted | ||
| * - If one signal is `null`, no signal will be aborted | ||
| */ | ||
| function allAbortSignals(...signals) { | ||
| const ac = new AbortController(); | ||
| const count = signals.length; | ||
| let abortedCount = 0; | ||
| const onAbort = () => { | ||
| if (++abortedCount === count) ac.abort(); | ||
| }; | ||
| for (const signal of signals) if (signal === null || signal === void 0 ? void 0 : signal.aborted) onAbort(); | ||
| else signal === null || signal === void 0 || signal.addEventListener("abort", onAbort, { once: true }); | ||
| return ac.signal; | ||
| } | ||
| /** | ||
| * Like `Promise.race` but for abort signals | ||
| * | ||
| * Basically, a ponyfill for | ||
| * [`AbortSignal.any`](https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal/any_static). | ||
| */ | ||
| function raceAbortSignals(...signals) { | ||
| const ac = new AbortController(); | ||
| for (const signal of signals) if (signal === null || signal === void 0 ? void 0 : signal.aborted) ac.abort(); | ||
| else signal === null || signal === void 0 || signal.addEventListener("abort", () => ac.abort(), { once: true }); | ||
| return ac.signal; | ||
| } | ||
| function abortSignalToPromise(signal) { | ||
| return new Promise((_, reject) => { | ||
| if (signal.aborted) { | ||
| reject(signal.reason); | ||
| return; | ||
| } | ||
| signal.addEventListener("abort", () => { | ||
| reject(signal.reason); | ||
| }, { once: true }); | ||
| }); | ||
| } | ||
| //#endregion | ||
| //#region src/links/httpBatchLink.ts | ||
| var import_objectSpread2 = require_chunk.__toESM(require_objectSpread2$1.require_objectSpread2(), 1); | ||
| /** | ||
| * @see https://trpc.io/docs/client/links/httpBatchLink | ||
| */ | ||
| function httpBatchLink(opts) { | ||
| var _opts$maxURLLength, _opts$maxItems; | ||
| const resolvedOpts = require_httpUtils.resolveHTTPLinkOptions(opts); | ||
| const maxURLLength = (_opts$maxURLLength = opts.maxURLLength) !== null && _opts$maxURLLength !== void 0 ? _opts$maxURLLength : Infinity; | ||
| const maxItems = (_opts$maxItems = opts.maxItems) !== null && _opts$maxItems !== void 0 ? _opts$maxItems : Infinity; | ||
| return () => { | ||
| const batchLoader = (type) => { | ||
| return { | ||
| validate(batchOps) { | ||
| if (maxURLLength === Infinity && maxItems === Infinity) return true; | ||
| if (batchOps.length > maxItems) return false; | ||
| const path = batchOps.map((op) => op.path).join(","); | ||
| const inputs = batchOps.map((op) => op.input); | ||
| const url = require_httpUtils.getUrl((0, import_objectSpread2.default)((0, import_objectSpread2.default)({}, resolvedOpts), {}, { | ||
| type, | ||
| path, | ||
| inputs, | ||
| signal: null | ||
| })); | ||
| return url.length <= maxURLLength; | ||
| }, | ||
| async fetch(batchOps) { | ||
| const path = batchOps.map((op) => op.path).join(","); | ||
| const inputs = batchOps.map((op) => op.input); | ||
| const signal = allAbortSignals(...batchOps.map((op) => op.signal)); | ||
| const res = await require_httpUtils.jsonHttpRequester((0, import_objectSpread2.default)((0, import_objectSpread2.default)({}, resolvedOpts), {}, { | ||
| path, | ||
| inputs, | ||
| type, | ||
| headers() { | ||
| if (!opts.headers) return {}; | ||
| if (typeof opts.headers === "function") return opts.headers({ opList: batchOps }); | ||
| return opts.headers; | ||
| }, | ||
| signal | ||
| })); | ||
| const resJSON = Array.isArray(res.json) ? res.json : batchOps.map(() => res.json); | ||
| const result = resJSON.map((item) => ({ | ||
| meta: res.meta, | ||
| json: item | ||
| })); | ||
| return result; | ||
| } | ||
| }; | ||
| }; | ||
| const query = dataLoader(batchLoader("query")); | ||
| const mutation = dataLoader(batchLoader("mutation")); | ||
| const loaders = { | ||
| query, | ||
| mutation | ||
| }; | ||
| return ({ op }) => { | ||
| return (0, __trpc_server_observable.observable)((observer) => { | ||
| /* istanbul ignore if -- @preserve */ | ||
| if (op.type === "subscription") throw new Error("Subscriptions are unsupported by `httpLink` - use `httpSubscriptionLink` or `wsLink`"); | ||
| const loader = loaders[op.type]; | ||
| const promise = loader.load(op); | ||
| let _res = void 0; | ||
| promise.then((res) => { | ||
| _res = res; | ||
| const transformed = (0, __trpc_server_unstable_core_do_not_import.transformResult)(res.json, resolvedOpts.transformer.output); | ||
| if (!transformed.ok) { | ||
| observer.error(require_TRPCClientError.TRPCClientError.from(transformed.error, { meta: res.meta })); | ||
| return; | ||
| } | ||
| observer.next({ | ||
| context: res.meta, | ||
| result: transformed.result | ||
| }); | ||
| observer.complete(); | ||
| }).catch((err) => { | ||
| observer.error(require_TRPCClientError.TRPCClientError.from(err, { meta: _res === null || _res === void 0 ? void 0 : _res.meta })); | ||
| }); | ||
| return () => {}; | ||
| }); | ||
| }; | ||
| }; | ||
| } | ||
| //#endregion | ||
| Object.defineProperty(exports, 'abortSignalToPromise', { | ||
| enumerable: true, | ||
| get: function () { | ||
| return abortSignalToPromise; | ||
| } | ||
| }); | ||
| Object.defineProperty(exports, 'allAbortSignals', { | ||
| enumerable: true, | ||
| get: function () { | ||
| return allAbortSignals; | ||
| } | ||
| }); | ||
| Object.defineProperty(exports, 'dataLoader', { | ||
| enumerable: true, | ||
| get: function () { | ||
| return dataLoader; | ||
| } | ||
| }); | ||
| Object.defineProperty(exports, 'httpBatchLink', { | ||
| enumerable: true, | ||
| get: function () { | ||
| return httpBatchLink; | ||
| } | ||
| }); | ||
| Object.defineProperty(exports, 'raceAbortSignals', { | ||
| enumerable: true, | ||
| get: function () { | ||
| return raceAbortSignals; | ||
| } | ||
| }); |
| import { __toESM, require_objectSpread2 } from "./objectSpread2-BvkFp-_Y.mjs"; | ||
| import { TRPCClientError } from "./TRPCClientError-apv8gw59.mjs"; | ||
| import { getUrl, jsonHttpRequester, resolveHTTPLinkOptions } from "./httpUtils-Dv57hbOd.mjs"; | ||
| import { observable } from "@trpc/server/observable"; | ||
| import { transformResult } from "@trpc/server/unstable-core-do-not-import"; | ||
| //#region src/internals/dataLoader.ts | ||
| /** | ||
| * A function that should never be called unless we messed something up. | ||
| */ | ||
| const throwFatalError = () => { | ||
| throw new Error("Something went wrong. Please submit an issue at https://github.com/trpc/trpc/issues/new"); | ||
| }; | ||
| /** | ||
| * Dataloader that's very inspired by https://github.com/graphql/dataloader | ||
| * Less configuration, no caching, and allows you to cancel requests | ||
| * When cancelling a single fetch the whole batch will be cancelled only when _all_ items are cancelled | ||
| */ | ||
| function dataLoader(batchLoader) { | ||
| let pendingItems = null; | ||
| let dispatchTimer = null; | ||
| const destroyTimerAndPendingItems = () => { | ||
| clearTimeout(dispatchTimer); | ||
| dispatchTimer = null; | ||
| pendingItems = null; | ||
| }; | ||
| /** | ||
| * Iterate through the items and split them into groups based on the `batchLoader`'s validate function | ||
| */ | ||
| function groupItems(items) { | ||
| const groupedItems = [[]]; | ||
| let index = 0; | ||
| while (true) { | ||
| const item = items[index]; | ||
| if (!item) break; | ||
| const lastGroup = groupedItems[groupedItems.length - 1]; | ||
| if (item.aborted) { | ||
| var _item$reject; | ||
| (_item$reject = item.reject) === null || _item$reject === void 0 || _item$reject.call(item, new Error("Aborted")); | ||
| index++; | ||
| continue; | ||
| } | ||
| const isValid = batchLoader.validate(lastGroup.concat(item).map((it) => it.key)); | ||
| if (isValid) { | ||
| lastGroup.push(item); | ||
| index++; | ||
| continue; | ||
| } | ||
| if (lastGroup.length === 0) { | ||
| var _item$reject2; | ||
| (_item$reject2 = item.reject) === null || _item$reject2 === void 0 || _item$reject2.call(item, new Error("Input is too big for a single dispatch")); | ||
| index++; | ||
| continue; | ||
| } | ||
| groupedItems.push([]); | ||
| } | ||
| return groupedItems; | ||
| } | ||
| function dispatch() { | ||
| const groupedItems = groupItems(pendingItems); | ||
| destroyTimerAndPendingItems(); | ||
| for (const items of groupedItems) { | ||
| if (!items.length) continue; | ||
| const batch = { items }; | ||
| for (const item of items) item.batch = batch; | ||
| const promise = batchLoader.fetch(batch.items.map((_item) => _item.key)); | ||
| promise.then(async (result) => { | ||
| await Promise.all(result.map(async (valueOrPromise, index) => { | ||
| const item = batch.items[index]; | ||
| try { | ||
| var _item$resolve; | ||
| const value = await Promise.resolve(valueOrPromise); | ||
| (_item$resolve = item.resolve) === null || _item$resolve === void 0 || _item$resolve.call(item, value); | ||
| } catch (cause) { | ||
| var _item$reject3; | ||
| (_item$reject3 = item.reject) === null || _item$reject3 === void 0 || _item$reject3.call(item, cause); | ||
| } | ||
| item.batch = null; | ||
| item.reject = null; | ||
| item.resolve = null; | ||
| })); | ||
| for (const item of batch.items) { | ||
| var _item$reject4; | ||
| (_item$reject4 = item.reject) === null || _item$reject4 === void 0 || _item$reject4.call(item, new Error("Missing result")); | ||
| item.batch = null; | ||
| } | ||
| }).catch((cause) => { | ||
| for (const item of batch.items) { | ||
| var _item$reject5; | ||
| (_item$reject5 = item.reject) === null || _item$reject5 === void 0 || _item$reject5.call(item, cause); | ||
| item.batch = null; | ||
| } | ||
| }); | ||
| } | ||
| } | ||
| function load(key) { | ||
| var _dispatchTimer; | ||
| const item = { | ||
| aborted: false, | ||
| key, | ||
| batch: null, | ||
| resolve: throwFatalError, | ||
| reject: throwFatalError | ||
| }; | ||
| const promise = new Promise((resolve, reject) => { | ||
| var _pendingItems; | ||
| item.reject = reject; | ||
| item.resolve = resolve; | ||
| (_pendingItems = pendingItems) !== null && _pendingItems !== void 0 || (pendingItems = []); | ||
| pendingItems.push(item); | ||
| }); | ||
| (_dispatchTimer = dispatchTimer) !== null && _dispatchTimer !== void 0 || (dispatchTimer = setTimeout(dispatch)); | ||
| return promise; | ||
| } | ||
| return { load }; | ||
| } | ||
| //#endregion | ||
| //#region src/internals/signals.ts | ||
| /** | ||
| * Like `Promise.all()` but for abort signals | ||
| * - When all signals have been aborted, the merged signal will be aborted | ||
| * - If one signal is `null`, no signal will be aborted | ||
| */ | ||
| function allAbortSignals(...signals) { | ||
| const ac = new AbortController(); | ||
| const count = signals.length; | ||
| let abortedCount = 0; | ||
| const onAbort = () => { | ||
| if (++abortedCount === count) ac.abort(); | ||
| }; | ||
| for (const signal of signals) if (signal === null || signal === void 0 ? void 0 : signal.aborted) onAbort(); | ||
| else signal === null || signal === void 0 || signal.addEventListener("abort", onAbort, { once: true }); | ||
| return ac.signal; | ||
| } | ||
| /** | ||
| * Like `Promise.race` but for abort signals | ||
| * | ||
| * Basically, a ponyfill for | ||
| * [`AbortSignal.any`](https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal/any_static). | ||
| */ | ||
| function raceAbortSignals(...signals) { | ||
| const ac = new AbortController(); | ||
| for (const signal of signals) if (signal === null || signal === void 0 ? void 0 : signal.aborted) ac.abort(); | ||
| else signal === null || signal === void 0 || signal.addEventListener("abort", () => ac.abort(), { once: true }); | ||
| return ac.signal; | ||
| } | ||
| function abortSignalToPromise(signal) { | ||
| return new Promise((_, reject) => { | ||
| if (signal.aborted) { | ||
| reject(signal.reason); | ||
| return; | ||
| } | ||
| signal.addEventListener("abort", () => { | ||
| reject(signal.reason); | ||
| }, { once: true }); | ||
| }); | ||
| } | ||
| //#endregion | ||
| //#region src/links/httpBatchLink.ts | ||
| var import_objectSpread2 = __toESM(require_objectSpread2(), 1); | ||
| /** | ||
| * @see https://trpc.io/docs/client/links/httpBatchLink | ||
| */ | ||
| function httpBatchLink(opts) { | ||
| var _opts$maxURLLength, _opts$maxItems; | ||
| const resolvedOpts = resolveHTTPLinkOptions(opts); | ||
| const maxURLLength = (_opts$maxURLLength = opts.maxURLLength) !== null && _opts$maxURLLength !== void 0 ? _opts$maxURLLength : Infinity; | ||
| const maxItems = (_opts$maxItems = opts.maxItems) !== null && _opts$maxItems !== void 0 ? _opts$maxItems : Infinity; | ||
| return () => { | ||
| const batchLoader = (type) => { | ||
| return { | ||
| validate(batchOps) { | ||
| if (maxURLLength === Infinity && maxItems === Infinity) return true; | ||
| if (batchOps.length > maxItems) return false; | ||
| const path = batchOps.map((op) => op.path).join(","); | ||
| const inputs = batchOps.map((op) => op.input); | ||
| const url = getUrl((0, import_objectSpread2.default)((0, import_objectSpread2.default)({}, resolvedOpts), {}, { | ||
| type, | ||
| path, | ||
| inputs, | ||
| signal: null | ||
| })); | ||
| return url.length <= maxURLLength; | ||
| }, | ||
| async fetch(batchOps) { | ||
| const path = batchOps.map((op) => op.path).join(","); | ||
| const inputs = batchOps.map((op) => op.input); | ||
| const signal = allAbortSignals(...batchOps.map((op) => op.signal)); | ||
| const res = await jsonHttpRequester((0, import_objectSpread2.default)((0, import_objectSpread2.default)({}, resolvedOpts), {}, { | ||
| path, | ||
| inputs, | ||
| type, | ||
| headers() { | ||
| if (!opts.headers) return {}; | ||
| if (typeof opts.headers === "function") return opts.headers({ opList: batchOps }); | ||
| return opts.headers; | ||
| }, | ||
| signal | ||
| })); | ||
| const resJSON = Array.isArray(res.json) ? res.json : batchOps.map(() => res.json); | ||
| const result = resJSON.map((item) => ({ | ||
| meta: res.meta, | ||
| json: item | ||
| })); | ||
| return result; | ||
| } | ||
| }; | ||
| }; | ||
| const query = dataLoader(batchLoader("query")); | ||
| const mutation = dataLoader(batchLoader("mutation")); | ||
| const loaders = { | ||
| query, | ||
| mutation | ||
| }; | ||
| return ({ op }) => { | ||
| return observable((observer) => { | ||
| /* istanbul ignore if -- @preserve */ | ||
| if (op.type === "subscription") throw new Error("Subscriptions are unsupported by `httpLink` - use `httpSubscriptionLink` or `wsLink`"); | ||
| const loader = loaders[op.type]; | ||
| const promise = loader.load(op); | ||
| let _res = void 0; | ||
| promise.then((res) => { | ||
| _res = res; | ||
| const transformed = transformResult(res.json, resolvedOpts.transformer.output); | ||
| if (!transformed.ok) { | ||
| observer.error(TRPCClientError.from(transformed.error, { meta: res.meta })); | ||
| return; | ||
| } | ||
| observer.next({ | ||
| context: res.meta, | ||
| result: transformed.result | ||
| }); | ||
| observer.complete(); | ||
| }).catch((err) => { | ||
| observer.error(TRPCClientError.from(err, { meta: _res === null || _res === void 0 ? void 0 : _res.meta })); | ||
| }); | ||
| return () => {}; | ||
| }); | ||
| }; | ||
| }; | ||
| } | ||
| //#endregion | ||
| export { abortSignalToPromise, allAbortSignals, dataLoader, httpBatchLink, raceAbortSignals }; | ||
| //# sourceMappingURL=httpBatchLink-fQ1NAi-e.mjs.map |
| {"version":3,"file":"httpBatchLink-fQ1NAi-e.mjs","names":["batchLoader: BatchLoader<TKey, TValue>","pendingItems: BatchItem<TKey, TValue>[] | null","dispatchTimer: ReturnType<typeof setTimeout> | null","items: BatchItem<TKey, TValue>[]","groupedItems: BatchItem<TKey, TValue>[][]","batch: Batch<TKey, TValue>","key: TKey","item: BatchItem<TKey, TValue>","signal: AbortSignal","opts: HTTPBatchLinkOptions<TRouter['_def']['_config']['$types']>","type: ProcedureType"],"sources":["../src/internals/dataLoader.ts","../src/internals/signals.ts","../src/links/httpBatchLink.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-non-null-assertion */\n\ntype BatchItem<TKey, TValue> = {\n aborted: boolean;\n key: TKey;\n resolve: ((value: TValue) => void) | null;\n reject: ((error: Error) => void) | null;\n batch: Batch<TKey, TValue> | null;\n};\ntype Batch<TKey, TValue> = {\n items: BatchItem<TKey, TValue>[];\n};\nexport type BatchLoader<TKey, TValue> = {\n validate: (keys: TKey[]) => boolean;\n fetch: (keys: TKey[]) => Promise<TValue[] | Promise<TValue>[]>;\n};\n\n/**\n * A function that should never be called unless we messed something up.\n */\nconst throwFatalError = () => {\n throw new Error(\n 'Something went wrong. Please submit an issue at https://github.com/trpc/trpc/issues/new',\n );\n};\n\n/**\n * Dataloader that's very inspired by https://github.com/graphql/dataloader\n * Less configuration, no caching, and allows you to cancel requests\n * When cancelling a single fetch the whole batch will be cancelled only when _all_ items are cancelled\n */\nexport function dataLoader<TKey, TValue>(\n batchLoader: BatchLoader<TKey, TValue>,\n) {\n let pendingItems: BatchItem<TKey, TValue>[] | null = null;\n let dispatchTimer: ReturnType<typeof setTimeout> | null = null;\n\n const destroyTimerAndPendingItems = () => {\n clearTimeout(dispatchTimer as any);\n dispatchTimer = null;\n pendingItems = null;\n };\n\n /**\n * Iterate through the items and split them into groups based on the `batchLoader`'s validate function\n */\n function groupItems(items: BatchItem<TKey, TValue>[]) {\n const groupedItems: BatchItem<TKey, TValue>[][] = [[]];\n let index = 0;\n while (true) {\n const item = items[index];\n if (!item) {\n // we're done\n break;\n }\n const lastGroup = groupedItems[groupedItems.length - 1]!;\n\n if (item.aborted) {\n // Item was aborted before it was dispatched\n item.reject?.(new Error('Aborted'));\n index++;\n continue;\n }\n\n const isValid = batchLoader.validate(\n lastGroup.concat(item).map((it) => it.key),\n );\n\n if (isValid) {\n lastGroup.push(item);\n index++;\n continue;\n }\n\n if (lastGroup.length === 0) {\n item.reject?.(new Error('Input is too big for a single dispatch'));\n index++;\n continue;\n }\n // Create new group, next iteration will try to add the item to that\n groupedItems.push([]);\n }\n return groupedItems;\n }\n\n function dispatch() {\n const groupedItems = groupItems(pendingItems!);\n destroyTimerAndPendingItems();\n\n // Create batches for each group of items\n for (const items of groupedItems) {\n if (!items.length) {\n continue;\n }\n const batch: Batch<TKey, TValue> = {\n items,\n };\n for (const item of items) {\n item.batch = batch;\n }\n const promise = batchLoader.fetch(batch.items.map((_item) => _item.key));\n\n promise\n .then(async (result) => {\n await Promise.all(\n result.map(async (valueOrPromise, index) => {\n const item = batch.items[index]!;\n try {\n const value = await Promise.resolve(valueOrPromise);\n\n item.resolve?.(value);\n } catch (cause) {\n item.reject?.(cause as Error);\n }\n\n item.batch = null;\n item.reject = null;\n item.resolve = null;\n }),\n );\n\n for (const item of batch.items) {\n item.reject?.(new Error('Missing result'));\n item.batch = null;\n }\n })\n .catch((cause) => {\n for (const item of batch.items) {\n item.reject?.(cause);\n item.batch = null;\n }\n });\n }\n }\n function load(key: TKey): Promise<TValue> {\n const item: BatchItem<TKey, TValue> = {\n aborted: false,\n key,\n batch: null,\n resolve: throwFatalError,\n reject: throwFatalError,\n };\n\n const promise = new Promise<TValue>((resolve, reject) => {\n item.reject = reject;\n item.resolve = resolve;\n\n pendingItems ??= [];\n pendingItems.push(item);\n });\n\n dispatchTimer ??= setTimeout(dispatch);\n\n return promise;\n }\n\n return {\n load,\n };\n}\n","import type { Maybe } from '@trpc/server/unstable-core-do-not-import';\n\n/**\n * Like `Promise.all()` but for abort signals\n * - When all signals have been aborted, the merged signal will be aborted\n * - If one signal is `null`, no signal will be aborted\n */\nexport function allAbortSignals(...signals: Maybe<AbortSignal>[]): AbortSignal {\n const ac = new AbortController();\n\n const count = signals.length;\n\n let abortedCount = 0;\n\n const onAbort = () => {\n if (++abortedCount === count) {\n ac.abort();\n }\n };\n\n for (const signal of signals) {\n if (signal?.aborted) {\n onAbort();\n } else {\n signal?.addEventListener('abort', onAbort, {\n once: true,\n });\n }\n }\n\n return ac.signal;\n}\n\n/**\n * Like `Promise.race` but for abort signals\n *\n * Basically, a ponyfill for\n * [`AbortSignal.any`](https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal/any_static).\n */\nexport function raceAbortSignals(\n ...signals: Maybe<AbortSignal>[]\n): AbortSignal {\n const ac = new AbortController();\n\n for (const signal of signals) {\n if (signal?.aborted) {\n ac.abort();\n } else {\n signal?.addEventListener('abort', () => ac.abort(), { once: true });\n }\n }\n\n return ac.signal;\n}\n\nexport function abortSignalToPromise(signal: AbortSignal): Promise<never> {\n return new Promise((_, reject) => {\n if (signal.aborted) {\n reject(signal.reason);\n return;\n }\n signal.addEventListener(\n 'abort',\n () => {\n reject(signal.reason);\n },\n { once: true },\n );\n });\n}\n","import type { AnyRouter, ProcedureType } from '@trpc/server';\nimport { observable } from '@trpc/server/observable';\nimport { transformResult } from '@trpc/server/unstable-core-do-not-import';\nimport type { BatchLoader } from '../internals/dataLoader';\nimport { dataLoader } from '../internals/dataLoader';\nimport { allAbortSignals } from '../internals/signals';\nimport type { NonEmptyArray } from '../internals/types';\nimport { TRPCClientError } from '../TRPCClientError';\nimport type { HTTPBatchLinkOptions } from './HTTPBatchLinkOptions';\nimport type { HTTPResult } from './internals/httpUtils';\nimport {\n getUrl,\n jsonHttpRequester,\n resolveHTTPLinkOptions,\n} from './internals/httpUtils';\nimport type { Operation, TRPCLink } from './types';\n\n/**\n * @see https://trpc.io/docs/client/links/httpBatchLink\n */\nexport function httpBatchLink<TRouter extends AnyRouter>(\n opts: HTTPBatchLinkOptions<TRouter['_def']['_config']['$types']>,\n): TRPCLink<TRouter> {\n const resolvedOpts = resolveHTTPLinkOptions(opts);\n const maxURLLength = opts.maxURLLength ?? Infinity;\n const maxItems = opts.maxItems ?? Infinity;\n\n return () => {\n const batchLoader = (\n type: ProcedureType,\n ): BatchLoader<Operation, HTTPResult> => {\n return {\n validate(batchOps) {\n if (maxURLLength === Infinity && maxItems === Infinity) {\n // escape hatch for quick calcs\n return true;\n }\n if (batchOps.length > maxItems) {\n return false;\n }\n const path = batchOps.map((op) => op.path).join(',');\n const inputs = batchOps.map((op) => op.input);\n\n const url = getUrl({\n ...resolvedOpts,\n type,\n path,\n inputs,\n signal: null,\n });\n\n return url.length <= maxURLLength;\n },\n async fetch(batchOps) {\n const path = batchOps.map((op) => op.path).join(',');\n const inputs = batchOps.map((op) => op.input);\n const signal = allAbortSignals(...batchOps.map((op) => op.signal));\n\n const res = await jsonHttpRequester({\n ...resolvedOpts,\n path,\n inputs,\n type,\n headers() {\n if (!opts.headers) {\n return {};\n }\n if (typeof opts.headers === 'function') {\n return opts.headers({\n opList: batchOps as NonEmptyArray<Operation>,\n });\n }\n return opts.headers;\n },\n signal,\n });\n const resJSON = Array.isArray(res.json)\n ? res.json\n : batchOps.map(() => res.json);\n const result = resJSON.map((item) => ({\n meta: res.meta,\n json: item,\n }));\n return result;\n },\n };\n };\n\n const query = dataLoader(batchLoader('query'));\n const mutation = dataLoader(batchLoader('mutation'));\n\n const loaders = { query, mutation };\n return ({ op }) => {\n return observable((observer) => {\n /* istanbul ignore if -- @preserve */\n if (op.type === 'subscription') {\n throw new Error(\n 'Subscriptions are unsupported by `httpLink` - use `httpSubscriptionLink` or `wsLink`',\n );\n }\n const loader = loaders[op.type];\n const promise = loader.load(op);\n\n let _res = undefined as HTTPResult | undefined;\n promise\n .then((res) => {\n _res = res;\n const transformed = transformResult(\n res.json,\n resolvedOpts.transformer.output,\n );\n\n if (!transformed.ok) {\n observer.error(\n TRPCClientError.from(transformed.error, {\n meta: res.meta,\n }),\n );\n return;\n }\n observer.next({\n context: res.meta,\n result: transformed.result,\n });\n observer.complete();\n })\n .catch((err) => {\n observer.error(\n TRPCClientError.from(err, {\n meta: _res?.meta,\n }),\n );\n });\n\n return () => {\n // noop\n };\n });\n };\n };\n}\n"],"mappings":"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"} |
| import { HTTPHeaders, NonEmptyArray, Operation, TRPCLink } from "./types.d-Cs0iOdcD.cjs"; | ||
| import { HTTPLinkBaseOptions } from "./httpUtils.d-CQqkjORQ.cjs"; | ||
| import { AnyClientTypes } from "@trpc/server/unstable-core-do-not-import"; | ||
| import { AnyRouter as AnyRouter$1 } from "@trpc/server"; | ||
| //#region src/links/HTTPBatchLinkOptions.d.ts | ||
| type HTTPBatchLinkOptions<TRoot extends AnyClientTypes> = HTTPLinkBaseOptions<TRoot> & { | ||
| maxURLLength?: number; | ||
| /** | ||
| * Headers to be set on outgoing requests or a callback that of said headers | ||
| * @see http://trpc.io/docs/client/headers | ||
| */ | ||
| headers?: HTTPHeaders | ((opts: { | ||
| opList: NonEmptyArray<Operation>; | ||
| }) => HTTPHeaders | Promise<HTTPHeaders>); | ||
| /** | ||
| * Maximum number of calls in a single batch request | ||
| * @default Infinity | ||
| */ | ||
| maxItems?: number; | ||
| }; | ||
| //# sourceMappingURL=HTTPBatchLinkOptions.d.ts.map | ||
| //#endregion | ||
| //#region src/links/httpBatchLink.d.ts | ||
| /** | ||
| * @see https://trpc.io/docs/client/links/httpBatchLink | ||
| */ | ||
| declare function httpBatchLink<TRouter extends AnyRouter$1>(opts: HTTPBatchLinkOptions<TRouter['_def']['_config']['$types']>): TRPCLink<TRouter>; | ||
| //# sourceMappingURL=httpBatchLink.d.ts.map | ||
| //#endregion | ||
| export { HTTPBatchLinkOptions, httpBatchLink }; | ||
| //# sourceMappingURL=httpBatchLink.d-H0e7Upz2.d.cts.map |
| {"version":3,"file":"httpBatchLink.d-H0e7Upz2.d.cts","names":[],"sources":["../src/links/HTTPBatchLinkOptions.ts","../src/links/httpBatchLink.ts"],"sourcesContent":[],"mappings":";;;;;;KAKY,mCAAmC,kBAC7C,oBAAoB;;EADV;;;;EACe,OAAzB,CAAA,EAOM,WAPN,GAAA,CAAA,CAAA,IAAA,EAAA;IAOM,MAAA,EAEU,aAFV,CAEwB,SAFxB,CAAA;EAAW,CAAA,EAEa,GAClB,WADkB,GACJ,OADI,CACI,WADJ,CAAA,CAAA;EAAS;;;;EACN,QAAA,CAAA,EAAA,MAAA;;;;;;;;AAXvB,iBCeI,aDfgB,CAAA,gBCec,WDfd,CAAA,CAAA,IAAA,ECgBxB,oBDhBwB,CCgBH,ODhBG,CAAA,MAAA,CAAA,CAAA,SAAA,CAAA,CAAA,QAAA,CAAA,CAAA,CAAA,ECiB7B,QDjB6B,CCiBpB,ODjBoB,CAAA"} |
| import { HTTPHeaders, NonEmptyArray, Operation, TRPCLink } from "./types.d-CdPnK6XH.mjs"; | ||
| import { HTTPLinkBaseOptions } from "./httpUtils.d-Cz21EQQV.mjs"; | ||
| import { AnyClientTypes } from "@trpc/server/unstable-core-do-not-import"; | ||
| import { AnyRouter as AnyRouter$1 } from "@trpc/server"; | ||
| //#region src/links/HTTPBatchLinkOptions.d.ts | ||
| type HTTPBatchLinkOptions<TRoot extends AnyClientTypes> = HTTPLinkBaseOptions<TRoot> & { | ||
| maxURLLength?: number; | ||
| /** | ||
| * Headers to be set on outgoing requests or a callback that of said headers | ||
| * @see http://trpc.io/docs/client/headers | ||
| */ | ||
| headers?: HTTPHeaders | ((opts: { | ||
| opList: NonEmptyArray<Operation>; | ||
| }) => HTTPHeaders | Promise<HTTPHeaders>); | ||
| /** | ||
| * Maximum number of calls in a single batch request | ||
| * @default Infinity | ||
| */ | ||
| maxItems?: number; | ||
| }; | ||
| //# sourceMappingURL=HTTPBatchLinkOptions.d.ts.map | ||
| //#endregion | ||
| //#region src/links/httpBatchLink.d.ts | ||
| /** | ||
| * @see https://trpc.io/docs/client/links/httpBatchLink | ||
| */ | ||
| declare function httpBatchLink<TRouter extends AnyRouter$1>(opts: HTTPBatchLinkOptions<TRouter['_def']['_config']['$types']>): TRPCLink<TRouter>; | ||
| //# sourceMappingURL=httpBatchLink.d.ts.map | ||
| //#endregion | ||
| export { HTTPBatchLinkOptions, httpBatchLink }; | ||
| //# sourceMappingURL=httpBatchLink.d-k3ADoD20.d.mts.map |
| {"version":3,"file":"httpBatchLink.d-k3ADoD20.d.mts","names":[],"sources":["../src/links/HTTPBatchLinkOptions.ts","../src/links/httpBatchLink.ts"],"sourcesContent":[],"mappings":";;;;;;KAKY,mCAAmC,kBAC7C,oBAAoB;;EADV;;;;EACe,OAAzB,CAAA,EAOM,WAPN,GAAA,CAAA,CAAA,IAAA,EAAA;IAOM,MAAA,EAEU,aAFV,CAEwB,SAFxB,CAAA;EAAW,CAAA,EAEa,GAClB,WADkB,GACJ,OADI,CACI,WADJ,CAAA,CAAA;EAAS;;;;EACN,QAAA,CAAA,EAAA,MAAA;;;;;;;;AAXvB,iBCeI,aDfgB,CAAA,gBCec,WDfd,CAAA,CAAA,IAAA,ECgBxB,oBDhBwB,CCgBH,ODhBG,CAAA,MAAA,CAAA,CAAA,SAAA,CAAA,CAAA,QAAA,CAAA,CAAA,CAAA,ECiB7B,QDjB6B,CCiBpB,ODjBoB,CAAA"} |
| import { __toESM, require_objectSpread2 } from "./objectSpread2-BvkFp-_Y.mjs"; | ||
| import { TRPCClientError } from "./TRPCClientError-apv8gw59.mjs"; | ||
| import { getUrl, httpRequest, jsonHttpRequester, resolveHTTPLinkOptions } from "./httpUtils-Dv57hbOd.mjs"; | ||
| import { observable } from "@trpc/server/observable"; | ||
| import { transformResult } from "@trpc/server/unstable-core-do-not-import"; | ||
| //#region src/links/internals/contentTypes.ts | ||
| function isOctetType(input) { | ||
| return input instanceof Uint8Array || input instanceof Blob; | ||
| } | ||
| function isFormData(input) { | ||
| return input instanceof FormData; | ||
| } | ||
| function isNonJsonSerializable(input) { | ||
| return isOctetType(input) || isFormData(input); | ||
| } | ||
| //#endregion | ||
| //#region src/links/httpLink.ts | ||
| var import_objectSpread2 = __toESM(require_objectSpread2(), 1); | ||
| const universalRequester = (opts) => { | ||
| if ("input" in opts) { | ||
| const { input } = opts; | ||
| if (isFormData(input)) { | ||
| if (opts.type !== "mutation" && opts.methodOverride !== "POST") throw new Error("FormData is only supported for mutations"); | ||
| return httpRequest((0, import_objectSpread2.default)((0, import_objectSpread2.default)({}, opts), {}, { | ||
| contentTypeHeader: void 0, | ||
| getUrl, | ||
| getBody: () => input | ||
| })); | ||
| } | ||
| if (isOctetType(input)) { | ||
| if (opts.type !== "mutation" && opts.methodOverride !== "POST") throw new Error("Octet type input is only supported for mutations"); | ||
| return httpRequest((0, import_objectSpread2.default)((0, import_objectSpread2.default)({}, opts), {}, { | ||
| contentTypeHeader: "application/octet-stream", | ||
| getUrl, | ||
| getBody: () => input | ||
| })); | ||
| } | ||
| } | ||
| return jsonHttpRequester(opts); | ||
| }; | ||
| /** | ||
| * @see https://trpc.io/docs/client/links/httpLink | ||
| */ | ||
| function httpLink(opts) { | ||
| const resolvedOpts = resolveHTTPLinkOptions(opts); | ||
| return () => { | ||
| return (operationOpts) => { | ||
| const { op } = operationOpts; | ||
| return observable((observer) => { | ||
| const { path, input, type } = op; | ||
| /* istanbul ignore if -- @preserve */ | ||
| if (type === "subscription") throw new Error("Subscriptions are unsupported by `httpLink` - use `httpSubscriptionLink` or `wsLink`"); | ||
| const request = universalRequester((0, import_objectSpread2.default)((0, import_objectSpread2.default)({}, resolvedOpts), {}, { | ||
| type, | ||
| path, | ||
| input, | ||
| signal: op.signal, | ||
| headers() { | ||
| if (!opts.headers) return {}; | ||
| if (typeof opts.headers === "function") return opts.headers({ op }); | ||
| return opts.headers; | ||
| } | ||
| })); | ||
| let meta = void 0; | ||
| request.then((res) => { | ||
| meta = res.meta; | ||
| const transformed = transformResult(res.json, resolvedOpts.transformer.output); | ||
| if (!transformed.ok) { | ||
| observer.error(TRPCClientError.from(transformed.error, { meta })); | ||
| return; | ||
| } | ||
| observer.next({ | ||
| context: res.meta, | ||
| result: transformed.result | ||
| }); | ||
| observer.complete(); | ||
| }).catch((cause) => { | ||
| observer.error(TRPCClientError.from(cause, { meta })); | ||
| }); | ||
| return () => {}; | ||
| }); | ||
| }; | ||
| }; | ||
| } | ||
| //#endregion | ||
| export { httpLink, isFormData, isNonJsonSerializable, isOctetType }; | ||
| //# sourceMappingURL=httpLink-Cz9h1Qgh.mjs.map |
| {"version":3,"file":"httpLink-Cz9h1Qgh.mjs","names":["input: unknown","universalRequester: Requester","opts: HTTPLinkOptions<TRouter['_def']['_config']['$types']>","meta: HTTPResult['meta'] | undefined"],"sources":["../src/links/internals/contentTypes.ts","../src/links/httpLink.ts"],"sourcesContent":["export function isOctetType(\n input: unknown,\n): input is Uint8Array<ArrayBuffer> | Blob {\n return (\n input instanceof Uint8Array ||\n // File extends from Blob but is only available in nodejs from v20\n input instanceof Blob\n );\n}\n\nexport function isFormData(input: unknown) {\n return input instanceof FormData;\n}\n\nexport function isNonJsonSerializable(input: unknown) {\n return isOctetType(input) || isFormData(input);\n}\n","import { observable } from '@trpc/server/observable';\nimport type {\n AnyClientTypes,\n AnyRouter,\n} from '@trpc/server/unstable-core-do-not-import';\nimport { transformResult } from '@trpc/server/unstable-core-do-not-import';\nimport { TRPCClientError } from '../TRPCClientError';\nimport type {\n HTTPLinkBaseOptions,\n HTTPResult,\n Requester,\n} from './internals/httpUtils';\nimport {\n getUrl,\n httpRequest,\n jsonHttpRequester,\n resolveHTTPLinkOptions,\n} from './internals/httpUtils';\nimport {\n isFormData,\n isOctetType,\n type HTTPHeaders,\n type Operation,\n type TRPCLink,\n} from './types';\n\nexport type HTTPLinkOptions<TRoot extends AnyClientTypes> =\n HTTPLinkBaseOptions<TRoot> & {\n /**\n * Headers to be set on outgoing requests or a callback that of said headers\n * @see http://trpc.io/docs/client/headers\n */\n headers?:\n | HTTPHeaders\n | ((opts: { op: Operation }) => HTTPHeaders | Promise<HTTPHeaders>);\n };\n\nconst universalRequester: Requester = (opts) => {\n if ('input' in opts) {\n const { input } = opts;\n if (isFormData(input)) {\n if (opts.type !== 'mutation' && opts.methodOverride !== 'POST') {\n throw new Error('FormData is only supported for mutations');\n }\n\n return httpRequest({\n ...opts,\n // The browser will set this automatically and include the boundary= in it\n contentTypeHeader: undefined,\n getUrl,\n getBody: () => input,\n });\n }\n\n if (isOctetType(input)) {\n if (opts.type !== 'mutation' && opts.methodOverride !== 'POST') {\n throw new Error('Octet type input is only supported for mutations');\n }\n\n return httpRequest({\n ...opts,\n contentTypeHeader: 'application/octet-stream',\n getUrl,\n getBody: () => input,\n });\n }\n }\n\n return jsonHttpRequester(opts);\n};\n\n/**\n * @see https://trpc.io/docs/client/links/httpLink\n */\nexport function httpLink<TRouter extends AnyRouter = AnyRouter>(\n opts: HTTPLinkOptions<TRouter['_def']['_config']['$types']>,\n): TRPCLink<TRouter> {\n const resolvedOpts = resolveHTTPLinkOptions(opts);\n return () => {\n return (operationOpts) => {\n const { op } = operationOpts;\n return observable((observer) => {\n const { path, input, type } = op;\n /* istanbul ignore if -- @preserve */\n if (type === 'subscription') {\n throw new Error(\n 'Subscriptions are unsupported by `httpLink` - use `httpSubscriptionLink` or `wsLink`',\n );\n }\n\n const request = universalRequester({\n ...resolvedOpts,\n type,\n path,\n input,\n signal: op.signal,\n headers() {\n if (!opts.headers) {\n return {};\n }\n if (typeof opts.headers === 'function') {\n return opts.headers({\n op,\n });\n }\n return opts.headers;\n },\n });\n let meta: HTTPResult['meta'] | undefined = undefined;\n request\n .then((res) => {\n meta = res.meta;\n const transformed = transformResult(\n res.json,\n resolvedOpts.transformer.output,\n );\n\n if (!transformed.ok) {\n observer.error(\n TRPCClientError.from(transformed.error, {\n meta,\n }),\n );\n return;\n }\n observer.next({\n context: res.meta,\n result: transformed.result,\n });\n observer.complete();\n })\n .catch((cause) => {\n observer.error(TRPCClientError.from(cause, { meta }));\n });\n\n return () => {\n // noop\n };\n });\n };\n };\n}\n"],"mappings":";;;;;;;AAAA,SAAgB,YACdA,OACyC;AACzC,QACE,iBAAiB,cAEjB,iBAAiB;AAEpB;AAED,SAAgB,WAAWA,OAAgB;AACzC,QAAO,iBAAiB;AACzB;AAED,SAAgB,sBAAsBA,OAAgB;AACpD,QAAO,YAAY,MAAM,IAAI,WAAW,MAAM;AAC/C;;;;;ACqBD,MAAMC,qBAAgC,CAAC,SAAS;AAC9C,KAAI,WAAW,MAAM;EACnB,MAAM,EAAE,OAAO,GAAG;AAClB,MAAI,WAAW,MAAM,EAAE;AACrB,OAAI,KAAK,SAAS,cAAc,KAAK,mBAAmB,OACtD,OAAM,IAAI,MAAM;AAGlB,UAAO,oFACF;IAEH;IACA;IACA,SAAS,MAAM;MACf;EACH;AAED,MAAI,YAAY,MAAM,EAAE;AACtB,OAAI,KAAK,SAAS,cAAc,KAAK,mBAAmB,OACtD,OAAM,IAAI,MAAM;AAGlB,UAAO,oFACF;IACH,mBAAmB;IACnB;IACA,SAAS,MAAM;MACf;EACH;CACF;AAED,QAAO,kBAAkB,KAAK;AAC/B;;;;AAKD,SAAgB,SACdC,MACmB;CACnB,MAAM,eAAe,uBAAuB,KAAK;AACjD,QAAO,MAAM;AACX,SAAO,CAAC,kBAAkB;GACxB,MAAM,EAAE,IAAI,GAAG;AACf,UAAO,WAAW,CAAC,aAAa;IAC9B,MAAM,EAAE,MAAM,OAAO,MAAM,GAAG;;AAE9B,QAAI,SAAS,eACX,OAAM,IAAI,MACR;IAIJ,MAAM,UAAU,2FACX;KACH;KACA;KACA;KACA,QAAQ,GAAG;KACX,UAAU;AACR,WAAK,KAAK,QACR,QAAO,CAAE;AAEX,iBAAW,KAAK,YAAY,WAC1B,QAAO,KAAK,QAAQ,EAClB,GACD,EAAC;AAEJ,aAAO,KAAK;KACb;OACD;IACF,IAAIC;AACJ,YACG,KAAK,CAAC,QAAQ;AACb,YAAO,IAAI;KACX,MAAM,cAAc,gBAClB,IAAI,MACJ,aAAa,YAAY,OAC1B;AAED,UAAK,YAAY,IAAI;AACnB,eAAS,MACP,gBAAgB,KAAK,YAAY,OAAO,EACtC,KACD,EAAC,CACH;AACD;KACD;AACD,cAAS,KAAK;MACZ,SAAS,IAAI;MACb,QAAQ,YAAY;KACrB,EAAC;AACF,cAAS,UAAU;IACpB,EAAC,CACD,MAAM,CAAC,UAAU;AAChB,cAAS,MAAM,gBAAgB,KAAK,OAAO,EAAE,KAAM,EAAC,CAAC;IACtD,EAAC;AAEJ,WAAO,MAAM,CAEZ;GACF,EAAC;EACH;CACF;AACF"} |
| const require_chunk = require('./chunk-DWy1uDak.cjs'); | ||
| const require_objectSpread2$1 = require('./objectSpread2-Bsvh_OqM.cjs'); | ||
| const require_TRPCClientError = require('./TRPCClientError-CQrTQLrk.cjs'); | ||
| const require_httpUtils = require('./httpUtils-CjSUiDDG.cjs'); | ||
| const __trpc_server_observable = require_chunk.__toESM(require("@trpc/server/observable")); | ||
| const __trpc_server_unstable_core_do_not_import = require_chunk.__toESM(require("@trpc/server/unstable-core-do-not-import")); | ||
| //#region src/links/internals/contentTypes.ts | ||
| function isOctetType(input) { | ||
| return input instanceof Uint8Array || input instanceof Blob; | ||
| } | ||
| function isFormData(input) { | ||
| return input instanceof FormData; | ||
| } | ||
| function isNonJsonSerializable(input) { | ||
| return isOctetType(input) || isFormData(input); | ||
| } | ||
| //#endregion | ||
| //#region src/links/httpLink.ts | ||
| var import_objectSpread2 = require_chunk.__toESM(require_objectSpread2$1.require_objectSpread2(), 1); | ||
| const universalRequester = (opts) => { | ||
| if ("input" in opts) { | ||
| const { input } = opts; | ||
| if (isFormData(input)) { | ||
| if (opts.type !== "mutation" && opts.methodOverride !== "POST") throw new Error("FormData is only supported for mutations"); | ||
| return require_httpUtils.httpRequest((0, import_objectSpread2.default)((0, import_objectSpread2.default)({}, opts), {}, { | ||
| contentTypeHeader: void 0, | ||
| getUrl: require_httpUtils.getUrl, | ||
| getBody: () => input | ||
| })); | ||
| } | ||
| if (isOctetType(input)) { | ||
| if (opts.type !== "mutation" && opts.methodOverride !== "POST") throw new Error("Octet type input is only supported for mutations"); | ||
| return require_httpUtils.httpRequest((0, import_objectSpread2.default)((0, import_objectSpread2.default)({}, opts), {}, { | ||
| contentTypeHeader: "application/octet-stream", | ||
| getUrl: require_httpUtils.getUrl, | ||
| getBody: () => input | ||
| })); | ||
| } | ||
| } | ||
| return require_httpUtils.jsonHttpRequester(opts); | ||
| }; | ||
| /** | ||
| * @see https://trpc.io/docs/client/links/httpLink | ||
| */ | ||
| function httpLink(opts) { | ||
| const resolvedOpts = require_httpUtils.resolveHTTPLinkOptions(opts); | ||
| return () => { | ||
| return (operationOpts) => { | ||
| const { op } = operationOpts; | ||
| return (0, __trpc_server_observable.observable)((observer) => { | ||
| const { path, input, type } = op; | ||
| /* istanbul ignore if -- @preserve */ | ||
| if (type === "subscription") throw new Error("Subscriptions are unsupported by `httpLink` - use `httpSubscriptionLink` or `wsLink`"); | ||
| const request = universalRequester((0, import_objectSpread2.default)((0, import_objectSpread2.default)({}, resolvedOpts), {}, { | ||
| type, | ||
| path, | ||
| input, | ||
| signal: op.signal, | ||
| headers() { | ||
| if (!opts.headers) return {}; | ||
| if (typeof opts.headers === "function") return opts.headers({ op }); | ||
| return opts.headers; | ||
| } | ||
| })); | ||
| let meta = void 0; | ||
| request.then((res) => { | ||
| meta = res.meta; | ||
| const transformed = (0, __trpc_server_unstable_core_do_not_import.transformResult)(res.json, resolvedOpts.transformer.output); | ||
| if (!transformed.ok) { | ||
| observer.error(require_TRPCClientError.TRPCClientError.from(transformed.error, { meta })); | ||
| return; | ||
| } | ||
| observer.next({ | ||
| context: res.meta, | ||
| result: transformed.result | ||
| }); | ||
| observer.complete(); | ||
| }).catch((cause) => { | ||
| observer.error(require_TRPCClientError.TRPCClientError.from(cause, { meta })); | ||
| }); | ||
| return () => {}; | ||
| }); | ||
| }; | ||
| }; | ||
| } | ||
| //#endregion | ||
| Object.defineProperty(exports, 'httpLink', { | ||
| enumerable: true, | ||
| get: function () { | ||
| return httpLink; | ||
| } | ||
| }); | ||
| Object.defineProperty(exports, 'isFormData', { | ||
| enumerable: true, | ||
| get: function () { | ||
| return isFormData; | ||
| } | ||
| }); | ||
| Object.defineProperty(exports, 'isNonJsonSerializable', { | ||
| enumerable: true, | ||
| get: function () { | ||
| return isNonJsonSerializable; | ||
| } | ||
| }); | ||
| Object.defineProperty(exports, 'isOctetType', { | ||
| enumerable: true, | ||
| get: function () { | ||
| return isOctetType; | ||
| } | ||
| }); |
| import { HTTPHeaders, Operation, TRPCLink } from "./types.d-CdPnK6XH.mjs"; | ||
| import { HTTPLinkBaseOptions } from "./httpUtils.d-Cz21EQQV.mjs"; | ||
| import { AnyClientTypes, AnyRouter } from "@trpc/server/unstable-core-do-not-import"; | ||
| //#region src/links/httpLink.d.ts | ||
| type HTTPLinkOptions<TRoot extends AnyClientTypes> = HTTPLinkBaseOptions<TRoot> & { | ||
| /** | ||
| * Headers to be set on outgoing requests or a callback that of said headers | ||
| * @see http://trpc.io/docs/client/headers | ||
| */ | ||
| headers?: HTTPHeaders | ((opts: { | ||
| op: Operation; | ||
| }) => HTTPHeaders | Promise<HTTPHeaders>); | ||
| }; | ||
| /** | ||
| * @see https://trpc.io/docs/client/links/httpLink | ||
| */ | ||
| declare function httpLink<TRouter extends AnyRouter = AnyRouter>(opts: HTTPLinkOptions<TRouter['_def']['_config']['$types']>): TRPCLink<TRouter>; | ||
| //# sourceMappingURL=httpLink.d.ts.map | ||
| //#endregion | ||
| export { HTTPLinkOptions, httpLink }; | ||
| //# sourceMappingURL=httpLink.d-BbSanXCY.d.mts.map |
| {"version":3,"file":"httpLink.d-BbSanXCY.d.mts","names":[],"sources":["../src/links/httpLink.ts"],"sourcesContent":[],"mappings":";;;;;KA0BY,8BAA8B,kBACxC,oBAAoB;;AADtB;;;EAAwD,OAClC,CAAA,EAMd,WANc,GAAA,CAAA,CAAA,IAAA,EAAA;IAApB,EAAA,EAOoB,SAPpB;EAAmB,CAAA,EAMb,GAC8B,WAD9B,GAC4C,OAD5C,CACoD,WADpD,CAAA,CAAA;CAAW;;;;AACwC,iBAwC3C,QAxC2C,CAAA,gBAwClB,SAxCkB,GAwCN,SAxCM,CAAA,CAAA,IAAA,EAyCnD,eAzCmD,CAyCnC,OAzCmC,CAAA,MAAA,CAAA,CAAA,SAAA,CAAA,CAAA,QAAA,CAAA,CAAA,CAAA,EA0CxD,QA1CwD,CA0C/C,OA1C+C,CAAA;AAwC3D"} |
| import { HTTPHeaders, Operation, TRPCLink } from "./types.d-Cs0iOdcD.cjs"; | ||
| import { HTTPLinkBaseOptions } from "./httpUtils.d-CQqkjORQ.cjs"; | ||
| import { AnyClientTypes, AnyRouter } from "@trpc/server/unstable-core-do-not-import"; | ||
| //#region src/links/httpLink.d.ts | ||
| type HTTPLinkOptions<TRoot extends AnyClientTypes> = HTTPLinkBaseOptions<TRoot> & { | ||
| /** | ||
| * Headers to be set on outgoing requests or a callback that of said headers | ||
| * @see http://trpc.io/docs/client/headers | ||
| */ | ||
| headers?: HTTPHeaders | ((opts: { | ||
| op: Operation; | ||
| }) => HTTPHeaders | Promise<HTTPHeaders>); | ||
| }; | ||
| /** | ||
| * @see https://trpc.io/docs/client/links/httpLink | ||
| */ | ||
| declare function httpLink<TRouter extends AnyRouter = AnyRouter>(opts: HTTPLinkOptions<TRouter['_def']['_config']['$types']>): TRPCLink<TRouter>; | ||
| //# sourceMappingURL=httpLink.d.ts.map | ||
| //#endregion | ||
| export { HTTPLinkOptions, httpLink }; | ||
| //# sourceMappingURL=httpLink.d-BOoWOn2d.d.cts.map |
| {"version":3,"file":"httpLink.d-BOoWOn2d.d.cts","names":[],"sources":["../src/links/httpLink.ts"],"sourcesContent":[],"mappings":";;;;;KA0BY,8BAA8B,kBACxC,oBAAoB;;AADtB;;;EAAwD,OAClC,CAAA,EAMd,WANc,GAAA,CAAA,CAAA,IAAA,EAAA;IAApB,EAAA,EAOoB,SAPpB;EAAmB,CAAA,EAMb,GAC8B,WAD9B,GAC4C,OAD5C,CACoD,WADpD,CAAA,CAAA;CAAW;;;;AACwC,iBAwC3C,QAxC2C,CAAA,gBAwClB,SAxCkB,GAwCN,SAxCM,CAAA,CAAA,IAAA,EAyCnD,eAzCmD,CAyCnC,OAzCmC,CAAA,MAAA,CAAA,CAAA,SAAA,CAAA,CAAA,QAAA,CAAA,CAAA,CAAA,EA0CxD,QA1CwD,CA0C/C,OA1C+C,CAAA;AAwC3D"} |
| import { FetchEsque } from "./types.d-Cs0iOdcD.cjs"; | ||
| import { TransformerOptions } from "./unstable-internals.d-kWsZTlQq.cjs"; | ||
| import { AnyClientTypes, CombinedDataTransformer, Maybe, ProcedureType } from "@trpc/server/unstable-core-do-not-import"; | ||
| //#region src/links/internals/httpUtils.d.ts | ||
| /** | ||
| * @internal | ||
| */ | ||
| type HTTPLinkBaseOptions<TRoot extends Pick<AnyClientTypes, 'transformer'>> = { | ||
| url: string | URL; | ||
| /** | ||
| * Add ponyfill for fetch | ||
| */ | ||
| fetch?: FetchEsque; | ||
| /** | ||
| * Send all requests `as POST`s requests regardless of the procedure type | ||
| * The HTTP handler must separately allow overriding the method. See: | ||
| * @see https://trpc.io/docs/rpc | ||
| */ | ||
| methodOverride?: 'POST'; | ||
| } & TransformerOptions<TRoot>; | ||
| //#endregion | ||
| export { HTTPLinkBaseOptions }; | ||
| //# sourceMappingURL=httpUtils.d-CQqkjORQ.d.cts.map |
| {"version":3,"file":"httpUtils.d-CQqkjORQ.d.cts","names":[],"sources":["../src/links/internals/httpUtils.ts"],"sourcesContent":[],"mappings":";;;;;;;AAqBA;;AACqB,KADT,mBACS,CAAA,cAAL,IAAK,CAAA,cAAA,EAAA,aAAA,CAAA,CAAA,GAAA;EAAc,GAAnB,EAAA,MAAA,GAEA,GAFA;EAAI;;;EAaQ,KAAxB,CAAA,EAPM,UAON;EAAkB;;;;;;IAAlB,mBAAmB"} |
| import { FetchEsque } from "./types.d-CdPnK6XH.mjs"; | ||
| import { TransformerOptions } from "./unstable-internals.d-BOmV7EK1.mjs"; | ||
| import { AnyClientTypes, CombinedDataTransformer, Maybe, ProcedureType } from "@trpc/server/unstable-core-do-not-import"; | ||
| //#region src/links/internals/httpUtils.d.ts | ||
| /** | ||
| * @internal | ||
| */ | ||
| type HTTPLinkBaseOptions<TRoot extends Pick<AnyClientTypes, 'transformer'>> = { | ||
| url: string | URL; | ||
| /** | ||
| * Add ponyfill for fetch | ||
| */ | ||
| fetch?: FetchEsque; | ||
| /** | ||
| * Send all requests `as POST`s requests regardless of the procedure type | ||
| * The HTTP handler must separately allow overriding the method. See: | ||
| * @see https://trpc.io/docs/rpc | ||
| */ | ||
| methodOverride?: 'POST'; | ||
| } & TransformerOptions<TRoot>; | ||
| //#endregion | ||
| export { HTTPLinkBaseOptions }; | ||
| //# sourceMappingURL=httpUtils.d-Cz21EQQV.d.mts.map |
| {"version":3,"file":"httpUtils.d-Cz21EQQV.d.mts","names":[],"sources":["../src/links/internals/httpUtils.ts"],"sourcesContent":[],"mappings":";;;;;;;AAqBA;;AACqB,KADT,mBACS,CAAA,cAAL,IAAK,CAAA,cAAA,EAAA,aAAA,CAAA,CAAA,GAAA;EAAc,GAAnB,EAAA,MAAA,GAEA,GAFA;EAAI;;;EAaQ,KAAxB,CAAA,EAPM,UAON;EAAkB;;;;;;IAAlB,mBAAmB"} |
| import { Operation, OperationResultEnvelope, TRPCClientError, TRPCLink } from "./types.d-CdPnK6XH.mjs"; | ||
| import { AnyRouter, InferrableClientTypes } from "@trpc/server/unstable-core-do-not-import"; | ||
| //#region src/links/loggerLink.d.ts | ||
| type ConsoleEsque = { | ||
| log: (...args: any[]) => void; | ||
| error: (...args: any[]) => void; | ||
| }; | ||
| type EnableFnOptions<TRouter extends InferrableClientTypes> = { | ||
| direction: 'down'; | ||
| result: OperationResultEnvelope<unknown, TRPCClientError<TRouter>> | TRPCClientError<TRouter>; | ||
| } | (Operation & { | ||
| direction: 'up'; | ||
| }); | ||
| type EnabledFn<TRouter extends AnyRouter> = (opts: EnableFnOptions<TRouter>) => boolean; | ||
| type LoggerLinkFnOptions<TRouter extends AnyRouter> = Operation & ({ | ||
| /** | ||
| * Request result | ||
| */ | ||
| direction: 'down'; | ||
| result: OperationResultEnvelope<unknown, TRPCClientError<TRouter>> | TRPCClientError<TRouter>; | ||
| elapsedMs: number; | ||
| } | { | ||
| /** | ||
| * Request was just initialized | ||
| */ | ||
| direction: 'up'; | ||
| }); | ||
| type LoggerLinkFn<TRouter extends AnyRouter> = (opts: LoggerLinkFnOptions<TRouter>) => void; | ||
| type ColorMode = 'ansi' | 'css' | 'none'; | ||
| interface LoggerLinkOptions<TRouter extends AnyRouter> { | ||
| logger?: LoggerLinkFn<TRouter>; | ||
| enabled?: EnabledFn<TRouter>; | ||
| /** | ||
| * Used in the built-in defaultLogger | ||
| */ | ||
| console?: ConsoleEsque; | ||
| /** | ||
| * Color mode | ||
| * @default typeof window === 'undefined' ? 'ansi' : 'css' | ||
| */ | ||
| colorMode?: ColorMode; | ||
| /** | ||
| * Include context in the log - defaults to false unless `colorMode` is 'css' | ||
| */ | ||
| withContext?: boolean; | ||
| } | ||
| /** | ||
| * @see https://trpc.io/docs/v11/client/links/loggerLink | ||
| */ | ||
| declare function loggerLink<TRouter extends AnyRouter = AnyRouter>(opts?: LoggerLinkOptions<TRouter>): TRPCLink<TRouter>; | ||
| //#endregion | ||
| export { LoggerLinkOptions, loggerLink }; | ||
| //# sourceMappingURL=loggerLink.d-BaScF_VD.d.mts.map |
| {"version":3,"file":"loggerLink.d-BaScF_VD.d.mts","names":[],"sources":["../src/links/loggerLink.ts"],"sourcesContent":[],"mappings":";;;;KAeK,YAAA;EAAA,GAAA,EAAA,CAAA,GAAA,IAAA,EAAY,GAAA,EAAA,EAAA,GAAA,IAAA;EAKZ,KAAA,EAAA,CAAA,GAAA,IAAA,EAAA,GAAe,EAAA,EAAA,GAAA,IAAA;CAAA;KAAf,eAAgC,CAAA,gBAAA,qBAAA,CAAA,GAAA;EAAqB,SAIC,EAAA,MAAA;EAAO,MAAvB,EAAjC,uBAAiC,CAAA,OAAA,EAAA,eAAA,CAAgB,OAAhB,CAAA,CAAA,GACjC,eADiC,CACjB,OADiB,CAAA;CAAe,GAAA,CAGrD,SAHK,GAAA;EAAuB,SACP,EAAA,IAAA;CAAO,CAAA;KAK5B,SAHA,CAAA,gBAG0B,SAH1B,CAAA,GAAA,CAAA,IAAA,EAIG,eAJH,CAImB,OAJnB,CAAA,EAAA,GAAA,OAAA;AAAS,KAOT,mBAPS,CAAA,gBAO2B,SAP3B,CAAA,GAOwC,SAPxC,GAAA,CAAA;EAGT;;;EAAmC,SAChB,EAAA,MAAA;EAAO,MAAvB,EAWI,uBAXJ,CAAA,OAAA,EAWqC,eAXrC,CAWqD,OAXrD,CAAA,CAAA,GAYI,eAZJ,CAYoB,OAZpB,CAAA;EAAe,SAAA,EAAA,MAAA;AAAA,CAAA,GAGlB;EAAmB;;;EAAuC,SAQF,EAAA,IAAA;CAAO,CAAA;KAY/D,YAZO,CAAA,gBAYsB,SAZtB,CAAA,GAAA,CAAA,IAAA,EAaJ,mBAbI,CAagB,OAbhB,CAAA,EAAA,GAAA,IAAA;KAgBP,SAAA,GAfuB,MAAA,GAAA,KAAA,GAAA,MAAA;AAAhB,UAiBK,iBAjBL,CAAA,gBAiBuC,SAjBvC,CAAA,CAAA;EAAe,MAAA,CAAA,EAkBhB,YAlBgB,CAkBH,OAlBG,CAAA;EAWtB,OAAA,CAAA,EAQO,SARK,CAQK,OARL,CAAA;EAAA;;;EACkB,OAA3B,CAAA,EAWI,YAXJ;EAAmB;AAAA;AAK3B;;EAAkC,SAAiB,CAAA,EAWrC,SAXqC;EAAS;;;EAE/B,WAAjB,CAAA,EAAA,OAAA;;;AASW;AA8IvB;AAA0B,iBAAV,UAAU,CAAA,gBAAiB,SAAjB,GAA6B,SAA7B,CAAA,CAAA,IAAA,CAAA,EAClB,iBADkB,CACA,OADA,CAAA,CAAA,EAEvB,QAFuB,CAEd,OAFc,CAAA"} |
| import { Operation, OperationResultEnvelope, TRPCClientError, TRPCLink } from "./types.d-Cs0iOdcD.cjs"; | ||
| import { AnyRouter, InferrableClientTypes } from "@trpc/server/unstable-core-do-not-import"; | ||
| //#region src/links/loggerLink.d.ts | ||
| type ConsoleEsque = { | ||
| log: (...args: any[]) => void; | ||
| error: (...args: any[]) => void; | ||
| }; | ||
| type EnableFnOptions<TRouter extends InferrableClientTypes> = { | ||
| direction: 'down'; | ||
| result: OperationResultEnvelope<unknown, TRPCClientError<TRouter>> | TRPCClientError<TRouter>; | ||
| } | (Operation & { | ||
| direction: 'up'; | ||
| }); | ||
| type EnabledFn<TRouter extends AnyRouter> = (opts: EnableFnOptions<TRouter>) => boolean; | ||
| type LoggerLinkFnOptions<TRouter extends AnyRouter> = Operation & ({ | ||
| /** | ||
| * Request result | ||
| */ | ||
| direction: 'down'; | ||
| result: OperationResultEnvelope<unknown, TRPCClientError<TRouter>> | TRPCClientError<TRouter>; | ||
| elapsedMs: number; | ||
| } | { | ||
| /** | ||
| * Request was just initialized | ||
| */ | ||
| direction: 'up'; | ||
| }); | ||
| type LoggerLinkFn<TRouter extends AnyRouter> = (opts: LoggerLinkFnOptions<TRouter>) => void; | ||
| type ColorMode = 'ansi' | 'css' | 'none'; | ||
| interface LoggerLinkOptions<TRouter extends AnyRouter> { | ||
| logger?: LoggerLinkFn<TRouter>; | ||
| enabled?: EnabledFn<TRouter>; | ||
| /** | ||
| * Used in the built-in defaultLogger | ||
| */ | ||
| console?: ConsoleEsque; | ||
| /** | ||
| * Color mode | ||
| * @default typeof window === 'undefined' ? 'ansi' : 'css' | ||
| */ | ||
| colorMode?: ColorMode; | ||
| /** | ||
| * Include context in the log - defaults to false unless `colorMode` is 'css' | ||
| */ | ||
| withContext?: boolean; | ||
| } | ||
| /** | ||
| * @see https://trpc.io/docs/v11/client/links/loggerLink | ||
| */ | ||
| declare function loggerLink<TRouter extends AnyRouter = AnyRouter>(opts?: LoggerLinkOptions<TRouter>): TRPCLink<TRouter>; | ||
| //#endregion | ||
| export { LoggerLinkOptions, loggerLink }; | ||
| //# sourceMappingURL=loggerLink.d-y4L2ytT2.d.cts.map |
| {"version":3,"file":"loggerLink.d-y4L2ytT2.d.cts","names":[],"sources":["../src/links/loggerLink.ts"],"sourcesContent":[],"mappings":";;;;KAeK,YAAA;EAAA,GAAA,EAAA,CAAA,GAAA,IAAA,EAAY,GAAA,EAAA,EAAA,GAAA,IAAA;EAKZ,KAAA,EAAA,CAAA,GAAA,IAAA,EAAA,GAAe,EAAA,EAAA,GAAA,IAAA;CAAA;KAAf,eAAgC,CAAA,gBAAA,qBAAA,CAAA,GAAA;EAAqB,SAIC,EAAA,MAAA;EAAO,MAAvB,EAAjC,uBAAiC,CAAA,OAAA,EAAA,eAAA,CAAgB,OAAhB,CAAA,CAAA,GACjC,eADiC,CACjB,OADiB,CAAA;CAAe,GAAA,CAGrD,SAHK,GAAA;EAAuB,SACP,EAAA,IAAA;CAAO,CAAA;KAK5B,SAHA,CAAA,gBAG0B,SAH1B,CAAA,GAAA,CAAA,IAAA,EAIG,eAJH,CAImB,OAJnB,CAAA,EAAA,GAAA,OAAA;AAAS,KAOT,mBAPS,CAAA,gBAO2B,SAP3B,CAAA,GAOwC,SAPxC,GAAA,CAAA;EAGT;;;EAAmC,SAChB,EAAA,MAAA;EAAO,MAAvB,EAWI,uBAXJ,CAAA,OAAA,EAWqC,eAXrC,CAWqD,OAXrD,CAAA,CAAA,GAYI,eAZJ,CAYoB,OAZpB,CAAA;EAAe,SAAA,EAAA,MAAA;AAAA,CAAA,GAGlB;EAAmB;;;EAAuC,SAQF,EAAA,IAAA;CAAO,CAAA;KAY/D,YAZO,CAAA,gBAYsB,SAZtB,CAAA,GAAA,CAAA,IAAA,EAaJ,mBAbI,CAagB,OAbhB,CAAA,EAAA,GAAA,IAAA;KAgBP,SAAA,GAfuB,MAAA,GAAA,KAAA,GAAA,MAAA;AAAhB,UAiBK,iBAjBL,CAAA,gBAiBuC,SAjBvC,CAAA,CAAA;EAAe,MAAA,CAAA,EAkBhB,YAlBgB,CAkBH,OAlBG,CAAA;EAWtB,OAAA,CAAA,EAQO,SARK,CAQK,OARL,CAAA;EAAA;;;EACkB,OAA3B,CAAA,EAWI,YAXJ;EAAmB;AAAA;AAK3B;;EAAkC,SAAiB,CAAA,EAWrC,SAXqC;EAAS;;;EAE/B,WAAjB,CAAA,EAAA,OAAA;;;AASW;AA8IvB;AAA0B,iBAAV,UAAU,CAAA,gBAAiB,SAAjB,GAA6B,SAA7B,CAAA,CAAA,IAAA,CAAA,EAClB,iBADkB,CACA,OADA,CAAA,CAAA,EAEvB,QAFuB,CAEd,OAFc,CAAA"} |
| import { Operation, TRPCLink } from "./types.d-Cs0iOdcD.cjs"; | ||
| import { AnyRouter } from "@trpc/server/unstable-core-do-not-import"; | ||
| //#region src/links/splitLink.d.ts | ||
| declare function splitLink<TRouter extends AnyRouter = AnyRouter>(opts: { | ||
| condition: (op: Operation) => boolean; | ||
| /** | ||
| * The link to execute next if the test function returns `true`. | ||
| */ | ||
| true: TRPCLink<TRouter> | TRPCLink<TRouter>[]; | ||
| /** | ||
| * The link to execute next if the test function returns `false`. | ||
| */ | ||
| false: TRPCLink<TRouter> | TRPCLink<TRouter>[]; | ||
| }): TRPCLink<TRouter>; | ||
| //# sourceMappingURL=splitLink.d.ts.map | ||
| //#endregion | ||
| export { splitLink }; | ||
| //# sourceMappingURL=splitLink.d-BhJriRAU.d.cts.map |
| {"version":3,"file":"splitLink.d-BhJriRAU.d.cts","names":[],"sources":["../src/links/splitLink.ts"],"sourcesContent":[],"mappings":";;;;iBAQgB,0BAA0B,YAAY;kBACpC;EADF;;;EAAmC,IAAG,EAK9C,QAL8C,CAKrC,OALqC,CAAA,GAK1B,QAL0B,CAKjB,OALiB,CAAA,EAAA;EAAS;;;EAK/C,KAAqB,EAI5B,QAJ4B,CAInB,OAJmB,CAAA,GAIR,QAJQ,CAIC,OAJD,CAAA,EAAA;CAAO,CAAA,EAKxC,QALwB,CAKf,OALe,CAAA"} |
| import { Operation, TRPCLink } from "./types.d-CdPnK6XH.mjs"; | ||
| import { AnyRouter } from "@trpc/server/unstable-core-do-not-import"; | ||
| //#region src/links/splitLink.d.ts | ||
| declare function splitLink<TRouter extends AnyRouter = AnyRouter>(opts: { | ||
| condition: (op: Operation) => boolean; | ||
| /** | ||
| * The link to execute next if the test function returns `true`. | ||
| */ | ||
| true: TRPCLink<TRouter> | TRPCLink<TRouter>[]; | ||
| /** | ||
| * The link to execute next if the test function returns `false`. | ||
| */ | ||
| false: TRPCLink<TRouter> | TRPCLink<TRouter>[]; | ||
| }): TRPCLink<TRouter>; | ||
| //# sourceMappingURL=splitLink.d.ts.map | ||
| //#endregion | ||
| export { splitLink }; | ||
| //# sourceMappingURL=splitLink.d-W7NPZOyY.d.mts.map |
| {"version":3,"file":"splitLink.d-W7NPZOyY.d.mts","names":[],"sources":["../src/links/splitLink.ts"],"sourcesContent":[],"mappings":";;;;iBAQgB,0BAA0B,YAAY;kBACpC;EADF;;;EAAmC,IAAG,EAK9C,QAL8C,CAKrC,OALqC,CAAA,GAK1B,QAL0B,CAKjB,OALiB,CAAA,EAAA;EAAS;;;EAK/C,KAAqB,EAI5B,QAJ4B,CAInB,OAJmB,CAAA,GAIR,QAJQ,CAIC,OAJD,CAAA,EAAA;CAAO,CAAA,EAKxC,QALwB,CAKf,OALe,CAAA"} |
| import { __toESM, require_defineProperty, require_objectSpread2 } from "./objectSpread2-BvkFp-_Y.mjs"; | ||
| import { isObject } from "@trpc/server/unstable-core-do-not-import"; | ||
| //#region src/TRPCClientError.ts | ||
| var import_defineProperty = __toESM(require_defineProperty(), 1); | ||
| var import_objectSpread2 = __toESM(require_objectSpread2(), 1); | ||
| function isTRPCClientError(cause) { | ||
| return cause instanceof TRPCClientError; | ||
| } | ||
| function isTRPCErrorResponse(obj) { | ||
| return isObject(obj) && isObject(obj["error"]) && typeof obj["error"]["code"] === "number" && typeof obj["error"]["message"] === "string"; | ||
| } | ||
| function getMessageFromUnknownError(err, fallback) { | ||
| if (typeof err === "string") return err; | ||
| if (isObject(err) && typeof err["message"] === "string") return err["message"]; | ||
| return fallback; | ||
| } | ||
| var TRPCClientError = class TRPCClientError extends Error { | ||
| constructor(message, opts) { | ||
| var _opts$result, _opts$result2; | ||
| const cause = opts === null || opts === void 0 ? void 0 : opts.cause; | ||
| super(message, { cause }); | ||
| (0, import_defineProperty.default)(this, "cause", void 0); | ||
| (0, import_defineProperty.default)(this, "shape", void 0); | ||
| (0, import_defineProperty.default)(this, "data", void 0); | ||
| (0, import_defineProperty.default)(this, "meta", void 0); | ||
| this.meta = opts === null || opts === void 0 ? void 0 : opts.meta; | ||
| this.cause = cause; | ||
| this.shape = opts === null || opts === void 0 || (_opts$result = opts.result) === null || _opts$result === void 0 ? void 0 : _opts$result.error; | ||
| this.data = opts === null || opts === void 0 || (_opts$result2 = opts.result) === null || _opts$result2 === void 0 ? void 0 : _opts$result2.error.data; | ||
| this.name = "TRPCClientError"; | ||
| Object.setPrototypeOf(this, TRPCClientError.prototype); | ||
| } | ||
| static from(_cause, opts = {}) { | ||
| const cause = _cause; | ||
| if (isTRPCClientError(cause)) { | ||
| if (opts.meta) cause.meta = (0, import_objectSpread2.default)((0, import_objectSpread2.default)({}, cause.meta), opts.meta); | ||
| return cause; | ||
| } | ||
| if (isTRPCErrorResponse(cause)) return new TRPCClientError(cause.error.message, (0, import_objectSpread2.default)((0, import_objectSpread2.default)({}, opts), {}, { | ||
| result: cause, | ||
| cause: opts.cause | ||
| })); | ||
| return new TRPCClientError(getMessageFromUnknownError(cause, "Unknown error"), (0, import_objectSpread2.default)((0, import_objectSpread2.default)({}, opts), {}, { cause })); | ||
| } | ||
| }; | ||
| //#endregion | ||
| export { TRPCClientError, isTRPCClientError }; | ||
| //# sourceMappingURL=TRPCClientError-apv8gw59.mjs.map |
| {"version":3,"file":"TRPCClientError-apv8gw59.mjs","names":["cause: unknown","obj: unknown","err: unknown","fallback: string","message: string","opts?: {\n result?: Maybe<TRPCErrorResponse<inferErrorShape<TRouterOrProcedure>>>;\n cause?: Error;\n meta?: Record<string, unknown>;\n }","_cause: Error | TRPCErrorResponse<any> | object","opts: { meta?: Record<string, unknown>; cause?: Error }"],"sources":["../src/TRPCClientError.ts"],"sourcesContent":["import type {\n inferClientTypes,\n InferrableClientTypes,\n Maybe,\n TRPCErrorResponse,\n} from '@trpc/server/unstable-core-do-not-import';\nimport {\n isObject,\n type DefaultErrorShape,\n} from '@trpc/server/unstable-core-do-not-import';\n\ntype inferErrorShape<TInferrable extends InferrableClientTypes> =\n inferClientTypes<TInferrable>['errorShape'];\nexport interface TRPCClientErrorBase<TShape extends DefaultErrorShape> {\n readonly message: string;\n readonly shape: Maybe<TShape>;\n readonly data: Maybe<TShape['data']>;\n}\nexport type TRPCClientErrorLike<TInferrable extends InferrableClientTypes> =\n TRPCClientErrorBase<inferErrorShape<TInferrable>>;\n\nexport function isTRPCClientError<TInferrable extends InferrableClientTypes>(\n cause: unknown,\n): cause is TRPCClientError<TInferrable> {\n return cause instanceof TRPCClientError;\n}\n\nfunction isTRPCErrorResponse(obj: unknown): obj is TRPCErrorResponse<any> {\n return (\n isObject(obj) &&\n isObject(obj['error']) &&\n typeof obj['error']['code'] === 'number' &&\n typeof obj['error']['message'] === 'string'\n );\n}\n\nfunction getMessageFromUnknownError(err: unknown, fallback: string): string {\n if (typeof err === 'string') {\n return err;\n }\n if (isObject(err) && typeof err['message'] === 'string') {\n return err['message'];\n }\n return fallback;\n}\n\nexport class TRPCClientError<TRouterOrProcedure extends InferrableClientTypes>\n extends Error\n implements TRPCClientErrorBase<inferErrorShape<TRouterOrProcedure>>\n{\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore override doesn't work in all environments due to \"This member cannot have an 'override' modifier because it is not declared in the base class 'Error'\"\n public override readonly cause;\n public readonly shape: Maybe<inferErrorShape<TRouterOrProcedure>>;\n public readonly data: Maybe<inferErrorShape<TRouterOrProcedure>['data']>;\n\n /**\n * Additional meta data about the error\n * In the case of HTTP-errors, we'll have `response` and potentially `responseJSON` here\n */\n public meta;\n\n constructor(\n message: string,\n opts?: {\n result?: Maybe<TRPCErrorResponse<inferErrorShape<TRouterOrProcedure>>>;\n cause?: Error;\n meta?: Record<string, unknown>;\n },\n ) {\n const cause = opts?.cause;\n\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore https://github.com/tc39/proposal-error-cause\n super(message, { cause });\n\n this.meta = opts?.meta;\n\n this.cause = cause;\n this.shape = opts?.result?.error;\n this.data = opts?.result?.error.data;\n this.name = 'TRPCClientError';\n\n Object.setPrototypeOf(this, TRPCClientError.prototype);\n }\n\n public static from<TRouterOrProcedure extends InferrableClientTypes>(\n _cause: Error | TRPCErrorResponse<any> | object,\n opts: { meta?: Record<string, unknown>; cause?: Error } = {},\n ): TRPCClientError<TRouterOrProcedure> {\n const cause = _cause as unknown;\n\n if (isTRPCClientError(cause)) {\n if (opts.meta) {\n // Decorate with meta error data\n cause.meta = {\n ...cause.meta,\n ...opts.meta,\n };\n }\n return cause;\n }\n if (isTRPCErrorResponse(cause)) {\n return new TRPCClientError(cause.error.message, {\n ...opts,\n result: cause,\n cause: opts.cause,\n });\n }\n return new TRPCClientError(\n getMessageFromUnknownError(cause, 'Unknown error'),\n {\n ...opts,\n cause: cause as any,\n },\n );\n }\n}\n"],"mappings":";;;;;;AAqBA,SAAgB,kBACdA,OACuC;AACvC,QAAO,iBAAiB;AACzB;AAED,SAAS,oBAAoBC,KAA6C;AACxE,QACE,SAAS,IAAI,IACb,SAAS,IAAI,SAAS,WACf,IAAI,SAAS,YAAY,mBACzB,IAAI,SAAS,eAAe;AAEtC;AAED,SAAS,2BAA2BC,KAAcC,UAA0B;AAC1E,YAAW,QAAQ,SACjB,QAAO;AAET,KAAI,SAAS,IAAI,WAAW,IAAI,eAAe,SAC7C,QAAO,IAAI;AAEb,QAAO;AACR;AAED,IAAa,kBAAb,MAAa,wBACH,MAEV;CAaE,YACEC,SACAC,MAKA;;EACA,MAAM,oDAAQ,KAAM;AAIpB,QAAM,SAAS,EAAE,MAAO,EAAC;qCA4C1B,MAlEwB;qCAkEvB,MAjEc;qCAiEb,MAhEa;qCAgEZ,MA1DG;AAgBL,OAAK,mDAAO,KAAM;AAElB,OAAK,QAAQ;AACb,OAAK,4DAAQ,KAAM,oEAAQ;AAC3B,OAAK,4DAAO,KAAM,sEAAQ,MAAM;AAChC,OAAK,OAAO;AAEZ,SAAO,eAAe,MAAM,gBAAgB,UAAU;CACvD;CAED,OAAc,KACZC,QACAC,OAA0D,CAAE,GACvB;EACrC,MAAM,QAAQ;AAEd,MAAI,kBAAkB,MAAM,EAAE;AAC5B,OAAI,KAAK,KAEP,OAAM,+EACD,MAAM,OACN,KAAK;AAGZ,UAAO;EACR;AACD,MAAI,oBAAoB,MAAM,CAC5B,QAAO,IAAI,gBAAgB,MAAM,MAAM,iFAClC;GACH,QAAQ;GACR,OAAO,KAAK;;AAGhB,SAAO,IAAI,gBACT,2BAA2B,OAAO,gBAAgB,0EAE7C,aACI;CAGZ;AACF"} |
| const require_chunk = require('./chunk-DWy1uDak.cjs'); | ||
| const require_objectSpread2$1 = require('./objectSpread2-Bsvh_OqM.cjs'); | ||
| const __trpc_server_unstable_core_do_not_import = require_chunk.__toESM(require("@trpc/server/unstable-core-do-not-import")); | ||
| //#region src/TRPCClientError.ts | ||
| var import_defineProperty = require_chunk.__toESM(require_objectSpread2$1.require_defineProperty(), 1); | ||
| var import_objectSpread2 = require_chunk.__toESM(require_objectSpread2$1.require_objectSpread2(), 1); | ||
| function isTRPCClientError(cause) { | ||
| return cause instanceof TRPCClientError; | ||
| } | ||
| function isTRPCErrorResponse(obj) { | ||
| return (0, __trpc_server_unstable_core_do_not_import.isObject)(obj) && (0, __trpc_server_unstable_core_do_not_import.isObject)(obj["error"]) && typeof obj["error"]["code"] === "number" && typeof obj["error"]["message"] === "string"; | ||
| } | ||
| function getMessageFromUnknownError(err, fallback) { | ||
| if (typeof err === "string") return err; | ||
| if ((0, __trpc_server_unstable_core_do_not_import.isObject)(err) && typeof err["message"] === "string") return err["message"]; | ||
| return fallback; | ||
| } | ||
| var TRPCClientError = class TRPCClientError extends Error { | ||
| constructor(message, opts) { | ||
| var _opts$result, _opts$result2; | ||
| const cause = opts === null || opts === void 0 ? void 0 : opts.cause; | ||
| super(message, { cause }); | ||
| (0, import_defineProperty.default)(this, "cause", void 0); | ||
| (0, import_defineProperty.default)(this, "shape", void 0); | ||
| (0, import_defineProperty.default)(this, "data", void 0); | ||
| (0, import_defineProperty.default)(this, "meta", void 0); | ||
| this.meta = opts === null || opts === void 0 ? void 0 : opts.meta; | ||
| this.cause = cause; | ||
| this.shape = opts === null || opts === void 0 || (_opts$result = opts.result) === null || _opts$result === void 0 ? void 0 : _opts$result.error; | ||
| this.data = opts === null || opts === void 0 || (_opts$result2 = opts.result) === null || _opts$result2 === void 0 ? void 0 : _opts$result2.error.data; | ||
| this.name = "TRPCClientError"; | ||
| Object.setPrototypeOf(this, TRPCClientError.prototype); | ||
| } | ||
| static from(_cause, opts = {}) { | ||
| const cause = _cause; | ||
| if (isTRPCClientError(cause)) { | ||
| if (opts.meta) cause.meta = (0, import_objectSpread2.default)((0, import_objectSpread2.default)({}, cause.meta), opts.meta); | ||
| return cause; | ||
| } | ||
| if (isTRPCErrorResponse(cause)) return new TRPCClientError(cause.error.message, (0, import_objectSpread2.default)((0, import_objectSpread2.default)({}, opts), {}, { | ||
| result: cause, | ||
| cause: opts.cause | ||
| })); | ||
| return new TRPCClientError(getMessageFromUnknownError(cause, "Unknown error"), (0, import_objectSpread2.default)((0, import_objectSpread2.default)({}, opts), {}, { cause })); | ||
| } | ||
| }; | ||
| //#endregion | ||
| Object.defineProperty(exports, 'TRPCClientError', { | ||
| enumerable: true, | ||
| get: function () { | ||
| return TRPCClientError; | ||
| } | ||
| }); | ||
| Object.defineProperty(exports, 'isTRPCClientError', { | ||
| enumerable: true, | ||
| get: function () { | ||
| return isTRPCClientError; | ||
| } | ||
| }); |
| import { TRPCConnectionState } from "./subscriptions.d-Dlr1nWGD.mjs"; | ||
| import { Observable, Observer } from "@trpc/server/observable"; | ||
| import { DefaultErrorShape, InferrableClientTypes, Maybe, TRPCErrorResponse, TRPCResultMessage, TRPCSuccessResponse, inferClientTypes } from "@trpc/server/unstable-core-do-not-import"; | ||
| //#region src/internals/types.d.ts | ||
| /** | ||
| * A subset of the standard fetch function type needed by tRPC internally. | ||
| * @see fetch from lib.dom.d.ts | ||
| * @remarks | ||
| * If you need a property that you know exists but doesn't exist on this | ||
| * interface, go ahead and add it. | ||
| */ | ||
| type FetchEsque = (input: RequestInfo | URL | string, init?: RequestInit | RequestInitEsque) => Promise<ResponseEsque>; | ||
| /** | ||
| * A simpler version of the native fetch function's type for packages with | ||
| * their own fetch types, such as undici and node-fetch. | ||
| */ | ||
| type NativeFetchEsque = (url: URL | string, init?: NodeFetchRequestInitEsque) => Promise<ResponseEsque>; | ||
| interface NodeFetchRequestInitEsque { | ||
| body?: string; | ||
| } | ||
| /** | ||
| * A subset of the standard RequestInit properties needed by tRPC internally. | ||
| * @see RequestInit from lib.dom.d.ts | ||
| * @remarks | ||
| * If you need a property that you know exists but doesn't exist on this | ||
| * interface, go ahead and add it. | ||
| */ | ||
| interface RequestInitEsque { | ||
| /** | ||
| * Sets the request's body. | ||
| */ | ||
| body?: FormData | string | null | Uint8Array<ArrayBuffer> | Blob | File; | ||
| /** | ||
| * Sets the request's associated headers. | ||
| */ | ||
| headers?: [string, string][] | Record<string, string>; | ||
| /** | ||
| * The request's HTTP-style method. | ||
| */ | ||
| method?: string; | ||
| /** | ||
| * Sets the request's signal. | ||
| */ | ||
| signal?: AbortSignal | undefined; | ||
| } | ||
| /** | ||
| * A subset of the standard ReadableStream properties needed by tRPC internally. | ||
| * @see ReadableStream from lib.dom.d.ts | ||
| */ | ||
| type WebReadableStreamEsque = { | ||
| getReader: () => ReadableStreamDefaultReader<Uint8Array>; | ||
| }; | ||
| type NodeJSReadableStreamEsque = { | ||
| on(eventName: string | symbol, listener: (...args: any[]) => void): NodeJSReadableStreamEsque; | ||
| }; | ||
| /** | ||
| * A subset of the standard Response properties needed by tRPC internally. | ||
| * @see Response from lib.dom.d.ts | ||
| */ | ||
| interface ResponseEsque { | ||
| readonly body?: NodeJSReadableStreamEsque | WebReadableStreamEsque | null; | ||
| /** | ||
| * @remarks | ||
| * The built-in Response::json() method returns Promise<any>, but | ||
| * that's not as type-safe as unknown. We use unknown because we're | ||
| * more type-safe. You do want more type safety, right? 😉 | ||
| */ | ||
| json(): Promise<unknown>; | ||
| } | ||
| /** | ||
| * @internal | ||
| */ | ||
| type NonEmptyArray<TItem> = [TItem, ...TItem[]]; | ||
| type ClientContext = Record<string, unknown>; | ||
| /** | ||
| * @public | ||
| */ | ||
| interface TRPCProcedureOptions { | ||
| /** | ||
| * Client-side context | ||
| */ | ||
| context?: ClientContext; | ||
| signal?: AbortSignal; | ||
| } | ||
| //#endregion | ||
| //#region src/TRPCClientError.d.ts | ||
| type inferErrorShape<TInferrable extends InferrableClientTypes> = inferClientTypes<TInferrable>['errorShape']; | ||
| interface TRPCClientErrorBase<TShape extends DefaultErrorShape> { | ||
| readonly message: string; | ||
| readonly shape: Maybe<TShape>; | ||
| readonly data: Maybe<TShape['data']>; | ||
| } | ||
| type TRPCClientErrorLike<TInferrable extends InferrableClientTypes> = TRPCClientErrorBase<inferErrorShape<TInferrable>>; | ||
| declare function isTRPCClientError<TInferrable extends InferrableClientTypes>(cause: unknown): cause is TRPCClientError<TInferrable>; | ||
| declare class TRPCClientError<TRouterOrProcedure extends InferrableClientTypes> extends Error implements TRPCClientErrorBase<inferErrorShape<TRouterOrProcedure>> { | ||
| readonly cause: Error | undefined; | ||
| readonly shape: Maybe<inferErrorShape<TRouterOrProcedure>>; | ||
| readonly data: Maybe<inferErrorShape<TRouterOrProcedure>['data']>; | ||
| /** | ||
| * Additional meta data about the error | ||
| * In the case of HTTP-errors, we'll have `response` and potentially `responseJSON` here | ||
| */ | ||
| meta: Record<string, unknown> | undefined; | ||
| constructor(message: string, opts?: { | ||
| result?: Maybe<TRPCErrorResponse<inferErrorShape<TRouterOrProcedure>>>; | ||
| cause?: Error; | ||
| meta?: Record<string, unknown>; | ||
| }); | ||
| static from<TRouterOrProcedure extends InferrableClientTypes>(_cause: Error | TRPCErrorResponse<any> | object, opts?: { | ||
| meta?: Record<string, unknown>; | ||
| cause?: Error; | ||
| }): TRPCClientError<TRouterOrProcedure>; | ||
| } | ||
| //#endregion | ||
| //#region src/links/internals/contentTypes.d.ts | ||
| declare function isOctetType(input: unknown): input is Uint8Array<ArrayBuffer> | Blob; | ||
| declare function isFormData(input: unknown): input is FormData; | ||
| declare function isNonJsonSerializable(input: unknown): input is FormData | Uint8Array<ArrayBuffer> | Blob; | ||
| //# sourceMappingURL=contentTypes.d.ts.map | ||
| //#endregion | ||
| //#region src/links/types.d.ts | ||
| /** | ||
| * @internal | ||
| */ | ||
| interface OperationContext extends Record<string, unknown> {} | ||
| /** | ||
| * @internal | ||
| */ | ||
| type Operation<TInput = unknown> = { | ||
| id: number; | ||
| type: 'mutation' | 'query' | 'subscription'; | ||
| input: TInput; | ||
| path: string; | ||
| context: OperationContext; | ||
| signal: Maybe<AbortSignal>; | ||
| }; | ||
| interface HeadersInitEsque { | ||
| [Symbol.iterator](): IterableIterator<[string, string]>; | ||
| } | ||
| /** | ||
| * @internal | ||
| */ | ||
| type HTTPHeaders = HeadersInitEsque | Record<string, string[] | string | undefined>; | ||
| /** | ||
| * The default `fetch` implementation has an overloaded signature. By convention this library | ||
| * only uses the overload taking a string and options object. | ||
| */ | ||
| type TRPCFetch = (url: string, options?: RequestInit) => Promise<ResponseEsque>; | ||
| interface TRPCClientRuntime {} | ||
| /** | ||
| * @internal | ||
| */ | ||
| interface OperationResultEnvelope<TOutput, TError> { | ||
| result: TRPCResultMessage<TOutput>['result'] | TRPCSuccessResponse<TOutput>['result'] | TRPCConnectionState<TError>; | ||
| context?: OperationContext; | ||
| } | ||
| /** | ||
| * @internal | ||
| */ | ||
| type OperationResultObservable<TInferrable extends InferrableClientTypes, TOutput> = Observable<OperationResultEnvelope<TOutput, TRPCClientError<TInferrable>>, TRPCClientError<TInferrable>>; | ||
| /** | ||
| * @internal | ||
| */ | ||
| type OperationResultObserver<TInferrable extends InferrableClientTypes, TOutput> = Observer<OperationResultEnvelope<TOutput, TRPCClientError<TInferrable>>, TRPCClientError<TInferrable>>; | ||
| /** | ||
| * @internal | ||
| */ | ||
| type OperationLink<TInferrable extends InferrableClientTypes, TInput = unknown, TOutput = unknown> = (opts: { | ||
| op: Operation<TInput>; | ||
| next: (op: Operation<TInput>) => OperationResultObservable<TInferrable, TOutput>; | ||
| }) => OperationResultObservable<TInferrable, TOutput>; | ||
| /** | ||
| * @public | ||
| */ | ||
| type TRPCLink<TInferrable extends InferrableClientTypes> = (opts: TRPCClientRuntime) => OperationLink<TInferrable>; | ||
| //# sourceMappingURL=types.d.ts.map | ||
| //#endregion | ||
| export { FetchEsque, HTTPHeaders, NativeFetchEsque, NonEmptyArray, Operation, OperationContext, OperationLink, OperationResultEnvelope, OperationResultObservable, OperationResultObserver, TRPCClientError, TRPCClientErrorBase, TRPCClientErrorLike, TRPCClientRuntime, TRPCFetch, TRPCLink, TRPCProcedureOptions, isFormData, isNonJsonSerializable, isOctetType, isTRPCClientError }; | ||
| //# sourceMappingURL=types.d-CdPnK6XH.d.mts.map |
| {"version":3,"file":"types.d-CdPnK6XH.d.mts","names":[],"sources":["../src/internals/types.ts","../src/TRPCClientError.ts","../src/links/internals/contentTypes.ts","../src/links/types.ts"],"sourcesContent":[],"mappings":"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"} |
| import { TRPCConnectionState } from "./subscriptions.d-Ciljg_dH.cjs"; | ||
| import { DefaultErrorShape, InferrableClientTypes, Maybe, TRPCErrorResponse, TRPCResultMessage, TRPCSuccessResponse, inferClientTypes } from "@trpc/server/unstable-core-do-not-import"; | ||
| import { Observable, Observer } from "@trpc/server/observable"; | ||
| //#region src/internals/types.d.ts | ||
| /** | ||
| * A subset of the standard fetch function type needed by tRPC internally. | ||
| * @see fetch from lib.dom.d.ts | ||
| * @remarks | ||
| * If you need a property that you know exists but doesn't exist on this | ||
| * interface, go ahead and add it. | ||
| */ | ||
| type FetchEsque = (input: RequestInfo | URL | string, init?: RequestInit | RequestInitEsque) => Promise<ResponseEsque>; | ||
| /** | ||
| * A simpler version of the native fetch function's type for packages with | ||
| * their own fetch types, such as undici and node-fetch. | ||
| */ | ||
| type NativeFetchEsque = (url: URL | string, init?: NodeFetchRequestInitEsque) => Promise<ResponseEsque>; | ||
| interface NodeFetchRequestInitEsque { | ||
| body?: string; | ||
| } | ||
| /** | ||
| * A subset of the standard RequestInit properties needed by tRPC internally. | ||
| * @see RequestInit from lib.dom.d.ts | ||
| * @remarks | ||
| * If you need a property that you know exists but doesn't exist on this | ||
| * interface, go ahead and add it. | ||
| */ | ||
| interface RequestInitEsque { | ||
| /** | ||
| * Sets the request's body. | ||
| */ | ||
| body?: FormData | string | null | Uint8Array<ArrayBuffer> | Blob | File; | ||
| /** | ||
| * Sets the request's associated headers. | ||
| */ | ||
| headers?: [string, string][] | Record<string, string>; | ||
| /** | ||
| * The request's HTTP-style method. | ||
| */ | ||
| method?: string; | ||
| /** | ||
| * Sets the request's signal. | ||
| */ | ||
| signal?: AbortSignal | undefined; | ||
| } | ||
| /** | ||
| * A subset of the standard ReadableStream properties needed by tRPC internally. | ||
| * @see ReadableStream from lib.dom.d.ts | ||
| */ | ||
| type WebReadableStreamEsque = { | ||
| getReader: () => ReadableStreamDefaultReader<Uint8Array>; | ||
| }; | ||
| type NodeJSReadableStreamEsque = { | ||
| on(eventName: string | symbol, listener: (...args: any[]) => void): NodeJSReadableStreamEsque; | ||
| }; | ||
| /** | ||
| * A subset of the standard Response properties needed by tRPC internally. | ||
| * @see Response from lib.dom.d.ts | ||
| */ | ||
| interface ResponseEsque { | ||
| readonly body?: NodeJSReadableStreamEsque | WebReadableStreamEsque | null; | ||
| /** | ||
| * @remarks | ||
| * The built-in Response::json() method returns Promise<any>, but | ||
| * that's not as type-safe as unknown. We use unknown because we're | ||
| * more type-safe. You do want more type safety, right? 😉 | ||
| */ | ||
| json(): Promise<unknown>; | ||
| } | ||
| /** | ||
| * @internal | ||
| */ | ||
| type NonEmptyArray<TItem> = [TItem, ...TItem[]]; | ||
| type ClientContext = Record<string, unknown>; | ||
| /** | ||
| * @public | ||
| */ | ||
| interface TRPCProcedureOptions { | ||
| /** | ||
| * Client-side context | ||
| */ | ||
| context?: ClientContext; | ||
| signal?: AbortSignal; | ||
| } | ||
| //#endregion | ||
| //#region src/TRPCClientError.d.ts | ||
| type inferErrorShape<TInferrable extends InferrableClientTypes> = inferClientTypes<TInferrable>['errorShape']; | ||
| interface TRPCClientErrorBase<TShape extends DefaultErrorShape> { | ||
| readonly message: string; | ||
| readonly shape: Maybe<TShape>; | ||
| readonly data: Maybe<TShape['data']>; | ||
| } | ||
| type TRPCClientErrorLike<TInferrable extends InferrableClientTypes> = TRPCClientErrorBase<inferErrorShape<TInferrable>>; | ||
| declare function isTRPCClientError<TInferrable extends InferrableClientTypes>(cause: unknown): cause is TRPCClientError<TInferrable>; | ||
| declare class TRPCClientError<TRouterOrProcedure extends InferrableClientTypes> extends Error implements TRPCClientErrorBase<inferErrorShape<TRouterOrProcedure>> { | ||
| readonly cause: Error | undefined; | ||
| readonly shape: Maybe<inferErrorShape<TRouterOrProcedure>>; | ||
| readonly data: Maybe<inferErrorShape<TRouterOrProcedure>['data']>; | ||
| /** | ||
| * Additional meta data about the error | ||
| * In the case of HTTP-errors, we'll have `response` and potentially `responseJSON` here | ||
| */ | ||
| meta: Record<string, unknown> | undefined; | ||
| constructor(message: string, opts?: { | ||
| result?: Maybe<TRPCErrorResponse<inferErrorShape<TRouterOrProcedure>>>; | ||
| cause?: Error; | ||
| meta?: Record<string, unknown>; | ||
| }); | ||
| static from<TRouterOrProcedure extends InferrableClientTypes>(_cause: Error | TRPCErrorResponse<any> | object, opts?: { | ||
| meta?: Record<string, unknown>; | ||
| cause?: Error; | ||
| }): TRPCClientError<TRouterOrProcedure>; | ||
| } | ||
| //#endregion | ||
| //#region src/links/internals/contentTypes.d.ts | ||
| declare function isOctetType(input: unknown): input is Uint8Array<ArrayBuffer> | Blob; | ||
| declare function isFormData(input: unknown): input is FormData; | ||
| declare function isNonJsonSerializable(input: unknown): input is Blob | FormData | Uint8Array<ArrayBuffer>; | ||
| //# sourceMappingURL=contentTypes.d.ts.map | ||
| //#endregion | ||
| //#region src/links/types.d.ts | ||
| /** | ||
| * @internal | ||
| */ | ||
| interface OperationContext extends Record<string, unknown> {} | ||
| /** | ||
| * @internal | ||
| */ | ||
| type Operation<TInput = unknown> = { | ||
| id: number; | ||
| type: 'mutation' | 'query' | 'subscription'; | ||
| input: TInput; | ||
| path: string; | ||
| context: OperationContext; | ||
| signal: Maybe<AbortSignal>; | ||
| }; | ||
| interface HeadersInitEsque { | ||
| [Symbol.iterator](): IterableIterator<[string, string]>; | ||
| } | ||
| /** | ||
| * @internal | ||
| */ | ||
| type HTTPHeaders = HeadersInitEsque | Record<string, string[] | string | undefined>; | ||
| /** | ||
| * The default `fetch` implementation has an overloaded signature. By convention this library | ||
| * only uses the overload taking a string and options object. | ||
| */ | ||
| type TRPCFetch = (url: string, options?: RequestInit) => Promise<ResponseEsque>; | ||
| interface TRPCClientRuntime {} | ||
| /** | ||
| * @internal | ||
| */ | ||
| interface OperationResultEnvelope<TOutput, TError> { | ||
| result: TRPCResultMessage<TOutput>['result'] | TRPCSuccessResponse<TOutput>['result'] | TRPCConnectionState<TError>; | ||
| context?: OperationContext; | ||
| } | ||
| /** | ||
| * @internal | ||
| */ | ||
| type OperationResultObservable<TInferrable extends InferrableClientTypes, TOutput> = Observable<OperationResultEnvelope<TOutput, TRPCClientError<TInferrable>>, TRPCClientError<TInferrable>>; | ||
| /** | ||
| * @internal | ||
| */ | ||
| type OperationResultObserver<TInferrable extends InferrableClientTypes, TOutput> = Observer<OperationResultEnvelope<TOutput, TRPCClientError<TInferrable>>, TRPCClientError<TInferrable>>; | ||
| /** | ||
| * @internal | ||
| */ | ||
| type OperationLink<TInferrable extends InferrableClientTypes, TInput = unknown, TOutput = unknown> = (opts: { | ||
| op: Operation<TInput>; | ||
| next: (op: Operation<TInput>) => OperationResultObservable<TInferrable, TOutput>; | ||
| }) => OperationResultObservable<TInferrable, TOutput>; | ||
| /** | ||
| * @public | ||
| */ | ||
| type TRPCLink<TInferrable extends InferrableClientTypes> = (opts: TRPCClientRuntime) => OperationLink<TInferrable>; | ||
| //# sourceMappingURL=types.d.ts.map | ||
| //#endregion | ||
| export { FetchEsque, HTTPHeaders, NativeFetchEsque, NonEmptyArray, Operation, OperationContext, OperationLink, OperationResultEnvelope, OperationResultObservable, OperationResultObserver, TRPCClientError, TRPCClientErrorBase, TRPCClientErrorLike, TRPCClientRuntime, TRPCFetch, TRPCLink, TRPCProcedureOptions, isFormData, isNonJsonSerializable, isOctetType, isTRPCClientError }; | ||
| //# sourceMappingURL=types.d-Cs0iOdcD.d.cts.map |
| {"version":3,"file":"types.d-Cs0iOdcD.d.cts","names":[],"sources":["../src/internals/types.ts","../src/TRPCClientError.ts","../src/links/internals/contentTypes.ts","../src/links/types.ts"],"sourcesContent":[],"mappings":"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"} |
| import { __toESM, require_defineProperty, require_objectSpread2 } from "./objectSpread2-BvkFp-_Y.mjs"; | ||
| import { TRPCClientError } from "./TRPCClientError-apv8gw59.mjs"; | ||
| import { getTransformer } from "./unstable-internals-Bg7n9BBj.mjs"; | ||
| import { behaviorSubject, observable } from "@trpc/server/observable"; | ||
| import { run, sleep, transformResult } from "@trpc/server/unstable-core-do-not-import"; | ||
| //#region src/links/wsLink/wsClient/encoder.ts | ||
| const jsonEncoder = { | ||
| encode: (data) => JSON.stringify(data), | ||
| decode: (data) => { | ||
| if (typeof data !== "string") throw new Error("jsonEncoder received binary data. JSON uses text frames. Use a binary encoder for binary data."); | ||
| return JSON.parse(data); | ||
| } | ||
| }; | ||
| //#endregion | ||
| //#region src/links/wsLink/wsClient/options.ts | ||
| const lazyDefaults = { | ||
| enabled: false, | ||
| closeMs: 0 | ||
| }; | ||
| const keepAliveDefaults = { | ||
| enabled: false, | ||
| pongTimeoutMs: 1e3, | ||
| intervalMs: 5e3 | ||
| }; | ||
| /** | ||
| * Calculates a delay for exponential backoff based on the retry attempt index. | ||
| * The delay starts at 0 for the first attempt and doubles for each subsequent attempt, | ||
| * capped at 30 seconds. | ||
| */ | ||
| const exponentialBackoff = (attemptIndex) => { | ||
| return attemptIndex === 0 ? 0 : Math.min(1e3 * 2 ** attemptIndex, 3e4); | ||
| }; | ||
| //#endregion | ||
| //#region src/links/internals/urlWithConnectionParams.ts | ||
| /** | ||
| * Get the result of a value or function that returns a value | ||
| * It also optionally accepts typesafe arguments for the function | ||
| */ | ||
| const resultOf = (value, ...args) => { | ||
| return typeof value === "function" ? value(...args) : value; | ||
| }; | ||
| //#endregion | ||
| //#region src/links/wsLink/wsClient/utils.ts | ||
| var import_defineProperty$3 = __toESM(require_defineProperty(), 1); | ||
| var TRPCWebSocketClosedError = class TRPCWebSocketClosedError extends Error { | ||
| constructor(opts) { | ||
| super(opts.message, { cause: opts.cause }); | ||
| this.name = "TRPCWebSocketClosedError"; | ||
| Object.setPrototypeOf(this, TRPCWebSocketClosedError.prototype); | ||
| } | ||
| }; | ||
| /** | ||
| * Utility class for managing a timeout that can be started, stopped, and reset. | ||
| * Useful for scenarios where the timeout duration is reset dynamically based on events. | ||
| */ | ||
| var ResettableTimeout = class { | ||
| constructor(onTimeout, timeoutMs) { | ||
| this.onTimeout = onTimeout; | ||
| this.timeoutMs = timeoutMs; | ||
| (0, import_defineProperty$3.default)(this, "timeout", void 0); | ||
| } | ||
| /** | ||
| * Resets the current timeout, restarting it with the same duration. | ||
| * Does nothing if no timeout is active. | ||
| */ | ||
| reset() { | ||
| if (!this.timeout) return; | ||
| clearTimeout(this.timeout); | ||
| this.timeout = setTimeout(this.onTimeout, this.timeoutMs); | ||
| } | ||
| start() { | ||
| clearTimeout(this.timeout); | ||
| this.timeout = setTimeout(this.onTimeout, this.timeoutMs); | ||
| } | ||
| stop() { | ||
| clearTimeout(this.timeout); | ||
| this.timeout = void 0; | ||
| } | ||
| }; | ||
| function withResolvers() { | ||
| let resolve; | ||
| let reject; | ||
| const promise = new Promise((res, rej) => { | ||
| resolve = res; | ||
| reject = rej; | ||
| }); | ||
| return { | ||
| promise, | ||
| resolve, | ||
| reject | ||
| }; | ||
| } | ||
| /** | ||
| * Resolves a WebSocket URL and optionally appends connection parameters. | ||
| * | ||
| * If connectionParams are provided, appends 'connectionParams=1' query parameter. | ||
| */ | ||
| async function prepareUrl(urlOptions) { | ||
| const url = await resultOf(urlOptions.url); | ||
| if (!urlOptions.connectionParams) return url; | ||
| const prefix = url.includes("?") ? "&" : "?"; | ||
| const connectionParams = `${prefix}connectionParams=1`; | ||
| return url + connectionParams; | ||
| } | ||
| async function buildConnectionMessage(connectionParams) { | ||
| const message = { | ||
| method: "connectionParams", | ||
| data: await resultOf(connectionParams) | ||
| }; | ||
| return JSON.stringify(message); | ||
| } | ||
| //#endregion | ||
| //#region src/links/wsLink/wsClient/requestManager.ts | ||
| var import_defineProperty$2 = __toESM(require_defineProperty(), 1); | ||
| /** | ||
| * Manages WebSocket requests, tracking their lifecycle and providing utility methods | ||
| * for handling outgoing and pending requests. | ||
| * | ||
| * - **Outgoing requests**: Requests that are queued and waiting to be sent. | ||
| * - **Pending requests**: Requests that have been sent and are in flight awaiting a response. | ||
| * For subscriptions, multiple responses may be received until the subscription is closed. | ||
| */ | ||
| var RequestManager = class { | ||
| constructor() { | ||
| (0, import_defineProperty$2.default)(this, "outgoingRequests", new Array()); | ||
| (0, import_defineProperty$2.default)(this, "pendingRequests", {}); | ||
| } | ||
| /** | ||
| * Registers a new request by adding it to the outgoing queue and setting up | ||
| * callbacks for lifecycle events such as completion or error. | ||
| * | ||
| * @param message - The outgoing message to be sent. | ||
| * @param callbacks - Callback functions to observe the request's state. | ||
| * @returns A cleanup function to manually remove the request. | ||
| */ | ||
| register(message, callbacks) { | ||
| const { promise: end, resolve } = withResolvers(); | ||
| this.outgoingRequests.push({ | ||
| id: String(message.id), | ||
| message, | ||
| end, | ||
| callbacks: { | ||
| next: callbacks.next, | ||
| complete: () => { | ||
| callbacks.complete(); | ||
| resolve(); | ||
| }, | ||
| error: (e) => { | ||
| callbacks.error(e); | ||
| resolve(); | ||
| } | ||
| } | ||
| }); | ||
| return () => { | ||
| this.delete(message.id); | ||
| callbacks.complete(); | ||
| resolve(); | ||
| }; | ||
| } | ||
| /** | ||
| * Deletes a request from both the outgoing and pending collections, if it exists. | ||
| */ | ||
| delete(messageId) { | ||
| if (messageId === null) return; | ||
| this.outgoingRequests = this.outgoingRequests.filter(({ id }) => id !== String(messageId)); | ||
| delete this.pendingRequests[String(messageId)]; | ||
| } | ||
| /** | ||
| * Moves all outgoing requests to the pending state and clears the outgoing queue. | ||
| * | ||
| * The caller is expected to handle the actual sending of the requests | ||
| * (e.g., sending them over the network) after this method is called. | ||
| * | ||
| * @returns The list of requests that were transitioned to the pending state. | ||
| */ | ||
| flush() { | ||
| const requests = this.outgoingRequests; | ||
| this.outgoingRequests = []; | ||
| for (const request of requests) this.pendingRequests[request.id] = request; | ||
| return requests; | ||
| } | ||
| /** | ||
| * Retrieves all currently pending requests, which are in flight awaiting responses | ||
| * or handling ongoing subscriptions. | ||
| */ | ||
| getPendingRequests() { | ||
| return Object.values(this.pendingRequests); | ||
| } | ||
| /** | ||
| * Retrieves a specific pending request by its message ID. | ||
| */ | ||
| getPendingRequest(messageId) { | ||
| if (messageId === null) return null; | ||
| return this.pendingRequests[String(messageId)]; | ||
| } | ||
| /** | ||
| * Retrieves all outgoing requests, which are waiting to be sent. | ||
| */ | ||
| getOutgoingRequests() { | ||
| return this.outgoingRequests; | ||
| } | ||
| /** | ||
| * Retrieves all requests, both outgoing and pending, with their respective states. | ||
| * | ||
| * @returns An array of all requests with their state ("outgoing" or "pending"). | ||
| */ | ||
| getRequests() { | ||
| return [...this.getOutgoingRequests().map((request) => ({ | ||
| state: "outgoing", | ||
| message: request.message, | ||
| end: request.end, | ||
| callbacks: request.callbacks | ||
| })), ...this.getPendingRequests().map((request) => ({ | ||
| state: "pending", | ||
| message: request.message, | ||
| end: request.end, | ||
| callbacks: request.callbacks | ||
| }))]; | ||
| } | ||
| /** | ||
| * Checks if there are any pending requests, including ongoing subscriptions. | ||
| */ | ||
| hasPendingRequests() { | ||
| return this.getPendingRequests().length > 0; | ||
| } | ||
| /** | ||
| * Checks if there are any pending subscriptions | ||
| */ | ||
| hasPendingSubscriptions() { | ||
| return this.getPendingRequests().some((request) => request.message.method === "subscription"); | ||
| } | ||
| /** | ||
| * Checks if there are any outgoing requests waiting to be sent. | ||
| */ | ||
| hasOutgoingRequests() { | ||
| return this.outgoingRequests.length > 0; | ||
| } | ||
| }; | ||
| //#endregion | ||
| //#region src/links/wsLink/wsClient/wsConnection.ts | ||
| var import_defineProperty$1 = __toESM(require_defineProperty(), 1); | ||
| /** | ||
| * Opens a WebSocket connection asynchronously and returns a promise | ||
| * that resolves when the connection is successfully established. | ||
| * The promise rejects if an error occurs during the connection attempt. | ||
| */ | ||
| function asyncWsOpen(ws) { | ||
| const { promise, resolve, reject } = withResolvers(); | ||
| ws.addEventListener("open", () => { | ||
| ws.removeEventListener("error", reject); | ||
| resolve(); | ||
| }); | ||
| ws.addEventListener("error", reject); | ||
| return promise; | ||
| } | ||
| /** | ||
| * Sets up a periodic ping-pong mechanism to keep the WebSocket connection alive. | ||
| * | ||
| * - Sends "PING" messages at regular intervals defined by `intervalMs`. | ||
| * - If a "PONG" response is not received within the `pongTimeoutMs`, the WebSocket is closed. | ||
| * - The ping timer resets upon receiving any message to maintain activity. | ||
| * - Automatically starts the ping process when the WebSocket connection is opened. | ||
| * - Cleans up timers when the WebSocket is closed. | ||
| * | ||
| * @param ws - The WebSocket instance to manage. | ||
| * @param options - Configuration options for ping-pong intervals and timeouts. | ||
| */ | ||
| function setupPingInterval(ws, { intervalMs, pongTimeoutMs }) { | ||
| let pingTimeout; | ||
| let pongTimeout; | ||
| function start() { | ||
| pingTimeout = setTimeout(() => { | ||
| ws.send("PING"); | ||
| pongTimeout = setTimeout(() => { | ||
| ws.close(); | ||
| }, pongTimeoutMs); | ||
| }, intervalMs); | ||
| } | ||
| function reset() { | ||
| clearTimeout(pingTimeout); | ||
| start(); | ||
| } | ||
| function pong() { | ||
| clearTimeout(pongTimeout); | ||
| reset(); | ||
| } | ||
| ws.addEventListener("open", start); | ||
| ws.addEventListener("message", ({ data }) => { | ||
| clearTimeout(pingTimeout); | ||
| start(); | ||
| if (data === "PONG") pong(); | ||
| }); | ||
| ws.addEventListener("close", () => { | ||
| clearTimeout(pingTimeout); | ||
| clearTimeout(pongTimeout); | ||
| }); | ||
| } | ||
| /** | ||
| * Manages a WebSocket connection with support for reconnection, keep-alive mechanisms, | ||
| * and observable state tracking. | ||
| */ | ||
| var WsConnection = class WsConnection { | ||
| constructor(opts) { | ||
| var _opts$WebSocketPonyfi; | ||
| (0, import_defineProperty$1.default)(this, "id", ++WsConnection.connectCount); | ||
| (0, import_defineProperty$1.default)(this, "WebSocketPonyfill", void 0); | ||
| (0, import_defineProperty$1.default)(this, "urlOptions", void 0); | ||
| (0, import_defineProperty$1.default)(this, "keepAliveOpts", void 0); | ||
| (0, import_defineProperty$1.default)(this, "wsObservable", behaviorSubject(null)); | ||
| (0, import_defineProperty$1.default)(this, "openPromise", null); | ||
| this.WebSocketPonyfill = (_opts$WebSocketPonyfi = opts.WebSocketPonyfill) !== null && _opts$WebSocketPonyfi !== void 0 ? _opts$WebSocketPonyfi : WebSocket; | ||
| if (!this.WebSocketPonyfill) throw new Error("No WebSocket implementation found - you probably don't want to use this on the server, but if you do you need to pass a `WebSocket`-ponyfill"); | ||
| this.urlOptions = opts.urlOptions; | ||
| this.keepAliveOpts = opts.keepAlive; | ||
| } | ||
| get ws() { | ||
| return this.wsObservable.get(); | ||
| } | ||
| set ws(ws) { | ||
| this.wsObservable.next(ws); | ||
| } | ||
| /** | ||
| * Checks if the WebSocket connection is open and ready to communicate. | ||
| */ | ||
| isOpen() { | ||
| return !!this.ws && this.ws.readyState === this.WebSocketPonyfill.OPEN && !this.openPromise; | ||
| } | ||
| /** | ||
| * Checks if the WebSocket connection is closed or in the process of closing. | ||
| */ | ||
| isClosed() { | ||
| return !!this.ws && (this.ws.readyState === this.WebSocketPonyfill.CLOSING || this.ws.readyState === this.WebSocketPonyfill.CLOSED); | ||
| } | ||
| async open() { | ||
| var _this = this; | ||
| if (_this.openPromise) return _this.openPromise; | ||
| _this.id = ++WsConnection.connectCount; | ||
| const wsPromise = prepareUrl(_this.urlOptions).then((url) => new _this.WebSocketPonyfill(url)); | ||
| _this.openPromise = wsPromise.then(async (ws) => { | ||
| _this.ws = ws; | ||
| ws.binaryType = "arraybuffer"; | ||
| ws.addEventListener("message", function({ data }) { | ||
| if (data === "PING") this.send("PONG"); | ||
| }); | ||
| if (_this.keepAliveOpts.enabled) setupPingInterval(ws, _this.keepAliveOpts); | ||
| ws.addEventListener("close", () => { | ||
| if (_this.ws === ws) _this.ws = null; | ||
| }); | ||
| await asyncWsOpen(ws); | ||
| if (_this.urlOptions.connectionParams) ws.send(await buildConnectionMessage(_this.urlOptions.connectionParams)); | ||
| }); | ||
| try { | ||
| await _this.openPromise; | ||
| } finally { | ||
| _this.openPromise = null; | ||
| } | ||
| } | ||
| /** | ||
| * Closes the WebSocket connection gracefully. | ||
| * Waits for any ongoing open operation to complete before closing. | ||
| */ | ||
| async close() { | ||
| var _this2 = this; | ||
| try { | ||
| await _this2.openPromise; | ||
| } finally { | ||
| var _this$ws; | ||
| (_this$ws = _this2.ws) === null || _this$ws === void 0 || _this$ws.close(); | ||
| } | ||
| } | ||
| }; | ||
| (0, import_defineProperty$1.default)(WsConnection, "connectCount", 0); | ||
| /** | ||
| * Provides a backward-compatible representation of the connection state. | ||
| */ | ||
| function backwardCompatibility(connection) { | ||
| if (connection.isOpen()) return { | ||
| id: connection.id, | ||
| state: "open", | ||
| ws: connection.ws | ||
| }; | ||
| if (connection.isClosed()) return { | ||
| id: connection.id, | ||
| state: "closed", | ||
| ws: connection.ws | ||
| }; | ||
| if (!connection.ws) return null; | ||
| return { | ||
| id: connection.id, | ||
| state: "connecting", | ||
| ws: connection.ws | ||
| }; | ||
| } | ||
| //#endregion | ||
| //#region src/links/wsLink/wsClient/wsClient.ts | ||
| var import_defineProperty = __toESM(require_defineProperty(), 1); | ||
| var import_objectSpread2 = __toESM(require_objectSpread2(), 1); | ||
| /** | ||
| * A WebSocket client for managing TRPC operations, supporting lazy initialization, | ||
| * reconnection, keep-alive, and request management. | ||
| */ | ||
| var WsClient = class { | ||
| constructor(opts) { | ||
| var _opts$experimental_en, _opts$retryDelayMs; | ||
| (0, import_defineProperty.default)(this, "connectionState", void 0); | ||
| (0, import_defineProperty.default)(this, "allowReconnect", false); | ||
| (0, import_defineProperty.default)(this, "requestManager", new RequestManager()); | ||
| (0, import_defineProperty.default)(this, "activeConnection", void 0); | ||
| (0, import_defineProperty.default)(this, "reconnectRetryDelay", void 0); | ||
| (0, import_defineProperty.default)(this, "inactivityTimeout", void 0); | ||
| (0, import_defineProperty.default)(this, "callbacks", void 0); | ||
| (0, import_defineProperty.default)(this, "lazyMode", void 0); | ||
| (0, import_defineProperty.default)(this, "encoder", void 0); | ||
| (0, import_defineProperty.default)(this, "reconnecting", null); | ||
| this.encoder = (_opts$experimental_en = opts.experimental_encoder) !== null && _opts$experimental_en !== void 0 ? _opts$experimental_en : jsonEncoder; | ||
| this.callbacks = { | ||
| onOpen: opts.onOpen, | ||
| onClose: opts.onClose, | ||
| onError: opts.onError | ||
| }; | ||
| const lazyOptions = (0, import_objectSpread2.default)((0, import_objectSpread2.default)({}, lazyDefaults), opts.lazy); | ||
| this.inactivityTimeout = new ResettableTimeout(() => { | ||
| if (this.requestManager.hasOutgoingRequests() || this.requestManager.hasPendingRequests()) { | ||
| this.inactivityTimeout.reset(); | ||
| return; | ||
| } | ||
| this.close().catch(() => null); | ||
| }, lazyOptions.closeMs); | ||
| this.activeConnection = new WsConnection({ | ||
| WebSocketPonyfill: opts.WebSocket, | ||
| urlOptions: opts, | ||
| keepAlive: (0, import_objectSpread2.default)((0, import_objectSpread2.default)({}, keepAliveDefaults), opts.keepAlive) | ||
| }); | ||
| this.activeConnection.wsObservable.subscribe({ next: (ws) => { | ||
| if (!ws) return; | ||
| this.setupWebSocketListeners(ws); | ||
| } }); | ||
| this.reconnectRetryDelay = (_opts$retryDelayMs = opts.retryDelayMs) !== null && _opts$retryDelayMs !== void 0 ? _opts$retryDelayMs : exponentialBackoff; | ||
| this.lazyMode = lazyOptions.enabled; | ||
| this.connectionState = behaviorSubject({ | ||
| type: "state", | ||
| state: lazyOptions.enabled ? "idle" : "connecting", | ||
| error: null | ||
| }); | ||
| if (!this.lazyMode) this.open().catch(() => null); | ||
| } | ||
| /** | ||
| * Opens the WebSocket connection. Handles reconnection attempts and updates | ||
| * the connection state accordingly. | ||
| */ | ||
| async open() { | ||
| var _this = this; | ||
| _this.allowReconnect = true; | ||
| if (_this.connectionState.get().state === "idle") _this.connectionState.next({ | ||
| type: "state", | ||
| state: "connecting", | ||
| error: null | ||
| }); | ||
| try { | ||
| await _this.activeConnection.open(); | ||
| } catch (error) { | ||
| _this.reconnect(new TRPCWebSocketClosedError({ | ||
| message: "Initialization error", | ||
| cause: error | ||
| })); | ||
| return _this.reconnecting; | ||
| } | ||
| } | ||
| /** | ||
| * Closes the WebSocket connection and stops managing requests. | ||
| * Ensures all outgoing and pending requests are properly finalized. | ||
| */ | ||
| async close() { | ||
| var _this2 = this; | ||
| _this2.allowReconnect = false; | ||
| _this2.inactivityTimeout.stop(); | ||
| const requestsToAwait = []; | ||
| for (const request of _this2.requestManager.getRequests()) if (request.message.method === "subscription") request.callbacks.complete(); | ||
| else if (request.state === "outgoing") request.callbacks.error(TRPCClientError.from(new TRPCWebSocketClosedError({ message: "Closed before connection was established" }))); | ||
| else requestsToAwait.push(request.end); | ||
| await Promise.all(requestsToAwait).catch(() => null); | ||
| await _this2.activeConnection.close().catch(() => null); | ||
| _this2.connectionState.next({ | ||
| type: "state", | ||
| state: "idle", | ||
| error: null | ||
| }); | ||
| } | ||
| /** | ||
| * Method to request the server. | ||
| * Handles data transformation, batching of requests, and subscription lifecycle. | ||
| * | ||
| * @param op - The operation details including id, type, path, input and signal | ||
| * @param transformer - Data transformer for serializing requests and deserializing responses | ||
| * @param lastEventId - Optional ID of the last received event for subscriptions | ||
| * | ||
| * @returns An observable that emits operation results and handles cleanup | ||
| */ | ||
| request({ op: { id, type, path, input, signal }, transformer, lastEventId }) { | ||
| return observable((observer) => { | ||
| const abort = this.batchSend({ | ||
| id, | ||
| method: type, | ||
| params: { | ||
| input: transformer.input.serialize(input), | ||
| path, | ||
| lastEventId | ||
| } | ||
| }, (0, import_objectSpread2.default)((0, import_objectSpread2.default)({}, observer), {}, { next(event) { | ||
| const transformed = transformResult(event, transformer.output); | ||
| if (!transformed.ok) { | ||
| observer.error(TRPCClientError.from(transformed.error)); | ||
| return; | ||
| } | ||
| observer.next({ result: transformed.result }); | ||
| } })); | ||
| return () => { | ||
| abort(); | ||
| if (type === "subscription" && this.activeConnection.isOpen()) this.send({ | ||
| id, | ||
| method: "subscription.stop" | ||
| }); | ||
| signal === null || signal === void 0 || signal.removeEventListener("abort", abort); | ||
| }; | ||
| }); | ||
| } | ||
| get connection() { | ||
| return backwardCompatibility(this.activeConnection); | ||
| } | ||
| reconnect(closedError) { | ||
| var _this3 = this; | ||
| this.connectionState.next({ | ||
| type: "state", | ||
| state: "connecting", | ||
| error: TRPCClientError.from(closedError) | ||
| }); | ||
| if (this.reconnecting) return; | ||
| const tryReconnect = async (attemptIndex) => { | ||
| try { | ||
| await sleep(_this3.reconnectRetryDelay(attemptIndex)); | ||
| if (_this3.allowReconnect) { | ||
| await _this3.activeConnection.close(); | ||
| await _this3.activeConnection.open(); | ||
| if (_this3.requestManager.hasPendingRequests()) _this3.send(_this3.requestManager.getPendingRequests().map(({ message }) => message)); | ||
| } | ||
| _this3.reconnecting = null; | ||
| } catch (_unused) { | ||
| await tryReconnect(attemptIndex + 1); | ||
| } | ||
| }; | ||
| this.reconnecting = tryReconnect(0); | ||
| } | ||
| setupWebSocketListeners(ws) { | ||
| var _this4 = this; | ||
| const handleCloseOrError = (cause) => { | ||
| const reqs = this.requestManager.getPendingRequests(); | ||
| for (const { message, callbacks } of reqs) { | ||
| if (message.method === "subscription") continue; | ||
| callbacks.error(TRPCClientError.from(cause !== null && cause !== void 0 ? cause : new TRPCWebSocketClosedError({ | ||
| message: "WebSocket closed", | ||
| cause | ||
| }))); | ||
| this.requestManager.delete(message.id); | ||
| } | ||
| }; | ||
| ws.addEventListener("open", () => { | ||
| run(async () => { | ||
| var _this$callbacks$onOpe, _this$callbacks; | ||
| if (_this4.lazyMode) _this4.inactivityTimeout.start(); | ||
| (_this$callbacks$onOpe = (_this$callbacks = _this4.callbacks).onOpen) === null || _this$callbacks$onOpe === void 0 || _this$callbacks$onOpe.call(_this$callbacks); | ||
| _this4.connectionState.next({ | ||
| type: "state", | ||
| state: "pending", | ||
| error: null | ||
| }); | ||
| }).catch((error) => { | ||
| ws.close(3e3); | ||
| handleCloseOrError(error); | ||
| }); | ||
| }); | ||
| ws.addEventListener("message", ({ data }) => { | ||
| this.inactivityTimeout.reset(); | ||
| if (["PING", "PONG"].includes(data)) return; | ||
| const incomingMessage = this.encoder.decode(data); | ||
| if ("method" in incomingMessage) { | ||
| this.handleIncomingRequest(incomingMessage); | ||
| return; | ||
| } | ||
| this.handleResponseMessage(incomingMessage); | ||
| }); | ||
| ws.addEventListener("close", (event) => { | ||
| var _this$callbacks$onClo, _this$callbacks2; | ||
| handleCloseOrError(event); | ||
| (_this$callbacks$onClo = (_this$callbacks2 = this.callbacks).onClose) === null || _this$callbacks$onClo === void 0 || _this$callbacks$onClo.call(_this$callbacks2, event); | ||
| if (!this.lazyMode || this.requestManager.hasPendingSubscriptions()) this.reconnect(new TRPCWebSocketClosedError({ | ||
| message: "WebSocket closed", | ||
| cause: event | ||
| })); | ||
| }); | ||
| ws.addEventListener("error", (event) => { | ||
| var _this$callbacks$onErr, _this$callbacks3; | ||
| handleCloseOrError(event); | ||
| (_this$callbacks$onErr = (_this$callbacks3 = this.callbacks).onError) === null || _this$callbacks$onErr === void 0 || _this$callbacks$onErr.call(_this$callbacks3, event); | ||
| this.reconnect(new TRPCWebSocketClosedError({ | ||
| message: "WebSocket closed", | ||
| cause: event | ||
| })); | ||
| }); | ||
| } | ||
| handleResponseMessage(message) { | ||
| const request = this.requestManager.getPendingRequest(message.id); | ||
| if (!request) return; | ||
| request.callbacks.next(message); | ||
| let completed = true; | ||
| if ("result" in message && request.message.method === "subscription") { | ||
| if (message.result.type === "data") request.message.params.lastEventId = message.result.id; | ||
| if (message.result.type !== "stopped") completed = false; | ||
| } | ||
| if (completed) { | ||
| request.callbacks.complete(); | ||
| this.requestManager.delete(message.id); | ||
| } | ||
| } | ||
| handleIncomingRequest(message) { | ||
| if (message.method === "reconnect") this.reconnect(new TRPCWebSocketClosedError({ message: "Server requested reconnect" })); | ||
| } | ||
| /** | ||
| * Sends a message or batch of messages directly to the server. | ||
| */ | ||
| send(messageOrMessages) { | ||
| if (!this.activeConnection.isOpen()) throw new Error("Active connection is not open"); | ||
| const messages = messageOrMessages instanceof Array ? messageOrMessages : [messageOrMessages]; | ||
| this.activeConnection.ws.send(this.encoder.encode(messages.length === 1 ? messages[0] : messages)); | ||
| } | ||
| /** | ||
| * Groups requests for batch sending. | ||
| * | ||
| * @returns A function to abort the batched request. | ||
| */ | ||
| batchSend(message, callbacks) { | ||
| var _this5 = this; | ||
| this.inactivityTimeout.reset(); | ||
| run(async () => { | ||
| if (!_this5.activeConnection.isOpen()) await _this5.open(); | ||
| await sleep(0); | ||
| if (!_this5.requestManager.hasOutgoingRequests()) return; | ||
| _this5.send(_this5.requestManager.flush().map(({ message: message$1 }) => message$1)); | ||
| }).catch((err) => { | ||
| this.requestManager.delete(message.id); | ||
| callbacks.error(TRPCClientError.from(err)); | ||
| }); | ||
| return this.requestManager.register(message, callbacks); | ||
| } | ||
| }; | ||
| //#endregion | ||
| //#region src/links/wsLink/createWsClient.ts | ||
| function createWSClient(opts) { | ||
| return new WsClient(opts); | ||
| } | ||
| //#endregion | ||
| //#region src/links/wsLink/wsLink.ts | ||
| function wsLink(opts) { | ||
| const { client } = opts; | ||
| const transformer = getTransformer(opts.transformer); | ||
| return () => { | ||
| return ({ op }) => { | ||
| return observable((observer) => { | ||
| const connStateSubscription = op.type === "subscription" ? client.connectionState.subscribe({ next(result) { | ||
| observer.next({ | ||
| result, | ||
| context: op.context | ||
| }); | ||
| } }) : null; | ||
| const requestSubscription = client.request({ | ||
| op, | ||
| transformer | ||
| }).subscribe(observer); | ||
| return () => { | ||
| requestSubscription.unsubscribe(); | ||
| connStateSubscription === null || connStateSubscription === void 0 || connStateSubscription.unsubscribe(); | ||
| }; | ||
| }); | ||
| }; | ||
| }; | ||
| } | ||
| //#endregion | ||
| export { createWSClient, jsonEncoder, resultOf, wsLink }; | ||
| //# sourceMappingURL=wsLink-Cq6tvTu7.mjs.map |
| {"version":3,"file":"wsLink-Cq6tvTu7.mjs","names":["jsonEncoder: Encoder","lazyDefaults: LazyOptions","keepAliveDefaults: KeepAliveOptions","attemptIndex: number","value: T | ((...args: TArgs) => T)","opts: { message: string; cause?: unknown }","onTimeout: () => void","timeoutMs: number","resolve: (value: T | PromiseLike<T>) => void","reject: (reason?: any) => void","urlOptions: UrlOptionsWithConnectionParams","connectionParams: CallbackOrValue<TRPCRequestInfo['connectionParams']>","message: TRPCConnectionParamsMessage","message: TRPCClientOutgoingMessage","callbacks: TCallbacks","messageId: MessageIdLike","ws: WebSocket","pingTimeout: ReturnType<typeof setTimeout> | undefined","pongTimeout: ReturnType<typeof setTimeout> | undefined","opts: WebSocketConnectionOptions","this","connection: WsConnection","opts: WebSocketClientOptions","this","requestsToAwait: Promise<void>[]","closedError: TRPCWebSocketClosedError","attemptIndex: number","ws: WebSocket","cause: unknown","message: TRPCResponseMessage","message: TRPCClientIncomingRequest","messageOrMessages: TRPCClientOutgoingMessage | TRPCClientOutgoingMessage[]","message: TRPCClientOutgoingMessage","callbacks: TCallbacks","message","opts: WebSocketClientOptions","opts: WebSocketLinkOptions<TRouter>"],"sources":["../src/links/wsLink/wsClient/encoder.ts","../src/links/wsLink/wsClient/options.ts","../src/links/internals/urlWithConnectionParams.ts","../src/links/wsLink/wsClient/utils.ts","../src/links/wsLink/wsClient/requestManager.ts","../src/links/wsLink/wsClient/wsConnection.ts","../src/links/wsLink/wsClient/wsClient.ts","../src/links/wsLink/createWsClient.ts","../src/links/wsLink/wsLink.ts"],"sourcesContent":["import type { Encoder } from '@trpc/server/adapters/ws';\n\nexport type { Encoder };\n\nexport const jsonEncoder: Encoder = {\n encode: (data) => JSON.stringify(data),\n decode: (data) => {\n if (typeof data !== 'string') {\n throw new Error(\n 'jsonEncoder received binary data. JSON uses text frames. ' +\n 'Use a binary encoder for binary data.',\n );\n }\n return JSON.parse(data);\n },\n};\n","import type { UrlOptionsWithConnectionParams } from '../../internals/urlWithConnectionParams';\nimport type { Encoder } from './encoder';\n\nexport interface WebSocketClientOptions extends UrlOptionsWithConnectionParams {\n /**\n * Ponyfill which WebSocket implementation to use\n */\n WebSocket?: typeof WebSocket;\n /**\n * The number of milliseconds before a reconnect is attempted.\n * @default {@link exponentialBackoff}\n */\n retryDelayMs?: (attemptIndex: number) => number;\n /**\n * Triggered when a WebSocket connection is established\n */\n onOpen?: () => void;\n /**\n * Triggered when a WebSocket connection encounters an error\n */\n onError?: (evt?: Event) => void;\n /**\n * Triggered when a WebSocket connection is closed\n */\n onClose?: (cause?: { code?: number }) => void;\n /**\n * Lazy mode will close the WebSocket automatically after a period of inactivity (no messages sent or received and no pending requests)\n */\n lazy?: {\n /**\n * Enable lazy mode\n * @default false\n */\n enabled: boolean;\n /**\n * Close the WebSocket after this many milliseconds\n * @default 0\n */\n closeMs: number;\n };\n /**\n * Send ping messages to the server and kill the connection if no pong message is returned\n */\n keepAlive?: {\n /**\n * @default false\n */\n enabled: boolean;\n /**\n * Send a ping message every this many milliseconds\n * @default 5_000\n */\n intervalMs?: number;\n /**\n * Close the WebSocket after this many milliseconds if the server does not respond\n * @default 1_000\n */\n pongTimeoutMs?: number;\n };\n /**\n * Custom encoder for wire encoding (e.g. custom binary formats)\n * @default jsonEncoder\n */\n experimental_encoder?: Encoder;\n}\n\n/**\n * Default options for lazy WebSocket connections.\n * Determines whether the connection should be established lazily and defines the delay before closure.\n */\nexport type LazyOptions = Required<NonNullable<WebSocketClientOptions['lazy']>>;\nexport const lazyDefaults: LazyOptions = {\n enabled: false,\n closeMs: 0,\n};\n\n/**\n * Default options for the WebSocket keep-alive mechanism.\n * Configures whether keep-alive is enabled and specifies the timeout and interval for ping-pong messages.\n */\nexport type KeepAliveOptions = Required<\n NonNullable<WebSocketClientOptions['keepAlive']>\n>;\nexport const keepAliveDefaults: KeepAliveOptions = {\n enabled: false,\n pongTimeoutMs: 1_000,\n intervalMs: 5_000,\n};\n\n/**\n * Calculates a delay for exponential backoff based on the retry attempt index.\n * The delay starts at 0 for the first attempt and doubles for each subsequent attempt,\n * capped at 30 seconds.\n */\nexport const exponentialBackoff = (attemptIndex: number) => {\n return attemptIndex === 0 ? 0 : Math.min(1000 * 2 ** attemptIndex, 30000);\n};\n","import { type TRPCRequestInfo } from '@trpc/server/http';\n\n/**\n * Get the result of a value or function that returns a value\n * It also optionally accepts typesafe arguments for the function\n */\nexport const resultOf = <T, TArgs extends any[]>(\n value: T | ((...args: TArgs) => T),\n ...args: TArgs\n): T => {\n return typeof value === 'function'\n ? (value as (...args: TArgs) => T)(...args)\n : value;\n};\n\n/**\n * A value that can be wrapped in callback\n */\nexport type CallbackOrValue<T> = T | (() => T | Promise<T>);\n\nexport interface UrlOptionsWithConnectionParams {\n /**\n * The URL to connect to (can be a function that returns a URL)\n */\n url: CallbackOrValue<string>;\n\n /**\n * Connection params that are available in `createContext()`\n * - For `wsLink`/`wsClient`, these are sent as the first message\n * - For `httpSubscriptionLink`, these are serialized as part of the URL under the `connectionParams` query\n */\n connectionParams?: CallbackOrValue<TRPCRequestInfo['connectionParams']>;\n}\n","import type {\n TRPCConnectionParamsMessage,\n TRPCRequestInfo,\n} from '@trpc/server/unstable-core-do-not-import';\nimport type {\n CallbackOrValue,\n UrlOptionsWithConnectionParams,\n} from '../../internals/urlWithConnectionParams';\nimport { resultOf } from '../../internals/urlWithConnectionParams';\n\nexport class TRPCWebSocketClosedError extends Error {\n constructor(opts: { message: string; cause?: unknown }) {\n super(opts.message, {\n cause: opts.cause,\n });\n this.name = 'TRPCWebSocketClosedError';\n Object.setPrototypeOf(this, TRPCWebSocketClosedError.prototype);\n }\n}\n\n/**\n * Utility class for managing a timeout that can be started, stopped, and reset.\n * Useful for scenarios where the timeout duration is reset dynamically based on events.\n */\nexport class ResettableTimeout {\n private timeout: ReturnType<typeof setTimeout> | undefined;\n\n constructor(\n private readonly onTimeout: () => void,\n private readonly timeoutMs: number,\n ) {}\n\n /**\n * Resets the current timeout, restarting it with the same duration.\n * Does nothing if no timeout is active.\n */\n public reset() {\n if (!this.timeout) return;\n\n clearTimeout(this.timeout);\n this.timeout = setTimeout(this.onTimeout, this.timeoutMs);\n }\n\n public start() {\n clearTimeout(this.timeout);\n this.timeout = setTimeout(this.onTimeout, this.timeoutMs);\n }\n\n public stop() {\n clearTimeout(this.timeout);\n this.timeout = undefined;\n }\n}\n\n// Ponyfill for Promise.withResolvers https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/withResolvers\nexport function withResolvers<T>() {\n let resolve: (value: T | PromiseLike<T>) => void;\n let reject: (reason?: any) => void;\n const promise = new Promise<T>((res, rej) => {\n resolve = res;\n reject = rej;\n });\n\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n return { promise, resolve: resolve!, reject: reject! };\n}\n\n/**\n * Resolves a WebSocket URL and optionally appends connection parameters.\n *\n * If connectionParams are provided, appends 'connectionParams=1' query parameter.\n */\nexport async function prepareUrl(urlOptions: UrlOptionsWithConnectionParams) {\n const url = await resultOf(urlOptions.url);\n\n if (!urlOptions.connectionParams) return url;\n\n // append `?connectionParams=1` when connection params are used\n const prefix = url.includes('?') ? '&' : '?';\n const connectionParams = `${prefix}connectionParams=1`;\n\n return url + connectionParams;\n}\n\nexport async function buildConnectionMessage(\n connectionParams: CallbackOrValue<TRPCRequestInfo['connectionParams']>,\n) {\n const message: TRPCConnectionParamsMessage = {\n method: 'connectionParams',\n data: await resultOf(connectionParams),\n };\n\n return JSON.stringify(message);\n}\n","import type { AnyTRPCRouter, inferRouterError } from '@trpc/server';\nimport type { Observer } from '@trpc/server/observable';\nimport type {\n TRPCClientOutgoingMessage,\n TRPCResponseMessage,\n} from '@trpc/server/unstable-core-do-not-import';\nimport type { TRPCClientError } from '../../../TRPCClientError';\nimport { withResolvers } from './utils';\n\nexport type TCallbacks = Observer<\n TRPCResponseMessage<unknown, inferRouterError<AnyTRPCRouter>>,\n TRPCClientError<AnyTRPCRouter>\n>;\n\ntype MessageId = string;\ntype MessageIdLike = string | number | null;\n\n/**\n * Represents a WebSocket request managed by the RequestManager.\n * Combines the network message, a utility promise (`end`) that mirrors the lifecycle\n * handled by `callbacks`, and a set of state monitoring callbacks.\n */\ninterface Request {\n message: TRPCClientOutgoingMessage;\n end: Promise<void>;\n callbacks: TCallbacks;\n}\n\n/**\n * Manages WebSocket requests, tracking their lifecycle and providing utility methods\n * for handling outgoing and pending requests.\n *\n * - **Outgoing requests**: Requests that are queued and waiting to be sent.\n * - **Pending requests**: Requests that have been sent and are in flight awaiting a response.\n * For subscriptions, multiple responses may be received until the subscription is closed.\n */\nexport class RequestManager {\n /**\n * Stores requests that are outgoing, meaning they are registered but not yet sent over the WebSocket.\n */\n private outgoingRequests = new Array<Request & { id: MessageId }>();\n\n /**\n * Stores requests that are pending (in flight), meaning they have been sent over the WebSocket\n * and are awaiting responses. For subscriptions, this includes requests\n * that may receive multiple responses.\n */\n private pendingRequests: Record<MessageId, Request> = {};\n\n /**\n * Registers a new request by adding it to the outgoing queue and setting up\n * callbacks for lifecycle events such as completion or error.\n *\n * @param message - The outgoing message to be sent.\n * @param callbacks - Callback functions to observe the request's state.\n * @returns A cleanup function to manually remove the request.\n */\n public register(message: TRPCClientOutgoingMessage, callbacks: TCallbacks) {\n const { promise: end, resolve } = withResolvers<void>();\n\n this.outgoingRequests.push({\n id: String(message.id),\n message,\n end,\n callbacks: {\n next: callbacks.next,\n complete: () => {\n callbacks.complete();\n resolve();\n },\n error: (e) => {\n callbacks.error(e);\n resolve();\n },\n },\n });\n\n return () => {\n this.delete(message.id);\n callbacks.complete();\n resolve();\n };\n }\n\n /**\n * Deletes a request from both the outgoing and pending collections, if it exists.\n */\n public delete(messageId: MessageIdLike) {\n if (messageId === null) return;\n\n this.outgoingRequests = this.outgoingRequests.filter(\n ({ id }) => id !== String(messageId),\n );\n delete this.pendingRequests[String(messageId)];\n }\n\n /**\n * Moves all outgoing requests to the pending state and clears the outgoing queue.\n *\n * The caller is expected to handle the actual sending of the requests\n * (e.g., sending them over the network) after this method is called.\n *\n * @returns The list of requests that were transitioned to the pending state.\n */\n public flush() {\n const requests = this.outgoingRequests;\n this.outgoingRequests = [];\n\n for (const request of requests) {\n this.pendingRequests[request.id] = request;\n }\n return requests;\n }\n\n /**\n * Retrieves all currently pending requests, which are in flight awaiting responses\n * or handling ongoing subscriptions.\n */\n public getPendingRequests() {\n return Object.values(this.pendingRequests);\n }\n\n /**\n * Retrieves a specific pending request by its message ID.\n */\n public getPendingRequest(messageId: MessageIdLike) {\n if (messageId === null) return null;\n\n return this.pendingRequests[String(messageId)];\n }\n\n /**\n * Retrieves all outgoing requests, which are waiting to be sent.\n */\n public getOutgoingRequests() {\n return this.outgoingRequests;\n }\n\n /**\n * Retrieves all requests, both outgoing and pending, with their respective states.\n *\n * @returns An array of all requests with their state (\"outgoing\" or \"pending\").\n */\n public getRequests() {\n return [\n ...this.getOutgoingRequests().map((request) => ({\n state: 'outgoing' as const,\n message: request.message,\n end: request.end,\n callbacks: request.callbacks,\n })),\n ...this.getPendingRequests().map((request) => ({\n state: 'pending' as const,\n message: request.message,\n end: request.end,\n callbacks: request.callbacks,\n })),\n ];\n }\n\n /**\n * Checks if there are any pending requests, including ongoing subscriptions.\n */\n public hasPendingRequests() {\n return this.getPendingRequests().length > 0;\n }\n\n /**\n * Checks if there are any pending subscriptions\n */\n public hasPendingSubscriptions() {\n return this.getPendingRequests().some(\n (request) => request.message.method === 'subscription',\n );\n }\n\n /**\n * Checks if there are any outgoing requests waiting to be sent.\n */\n public hasOutgoingRequests() {\n return this.outgoingRequests.length > 0;\n }\n}\n","import { behaviorSubject } from '@trpc/server/observable';\nimport type { UrlOptionsWithConnectionParams } from '../../internals/urlWithConnectionParams';\nimport { buildConnectionMessage, prepareUrl, withResolvers } from './utils';\n\n/**\n * Opens a WebSocket connection asynchronously and returns a promise\n * that resolves when the connection is successfully established.\n * The promise rejects if an error occurs during the connection attempt.\n */\nfunction asyncWsOpen(ws: WebSocket) {\n const { promise, resolve, reject } = withResolvers<void>();\n\n ws.addEventListener('open', () => {\n ws.removeEventListener('error', reject);\n resolve();\n });\n ws.addEventListener('error', reject);\n\n return promise;\n}\n\ninterface PingPongOptions {\n /**\n * The interval (in milliseconds) between \"PING\" messages.\n */\n intervalMs: number;\n\n /**\n * The timeout (in milliseconds) to wait for a \"PONG\" response before closing the connection.\n */\n pongTimeoutMs: number;\n}\n\n/**\n * Sets up a periodic ping-pong mechanism to keep the WebSocket connection alive.\n *\n * - Sends \"PING\" messages at regular intervals defined by `intervalMs`.\n * - If a \"PONG\" response is not received within the `pongTimeoutMs`, the WebSocket is closed.\n * - The ping timer resets upon receiving any message to maintain activity.\n * - Automatically starts the ping process when the WebSocket connection is opened.\n * - Cleans up timers when the WebSocket is closed.\n *\n * @param ws - The WebSocket instance to manage.\n * @param options - Configuration options for ping-pong intervals and timeouts.\n */\nfunction setupPingInterval(\n ws: WebSocket,\n { intervalMs, pongTimeoutMs }: PingPongOptions,\n) {\n let pingTimeout: ReturnType<typeof setTimeout> | undefined;\n let pongTimeout: ReturnType<typeof setTimeout> | undefined;\n\n function start() {\n pingTimeout = setTimeout(() => {\n ws.send('PING');\n pongTimeout = setTimeout(() => {\n ws.close();\n }, pongTimeoutMs);\n }, intervalMs);\n }\n\n function reset() {\n clearTimeout(pingTimeout);\n start();\n }\n\n function pong() {\n clearTimeout(pongTimeout);\n reset();\n }\n\n ws.addEventListener('open', start);\n ws.addEventListener('message', ({ data }) => {\n clearTimeout(pingTimeout);\n start();\n\n if (data === 'PONG') {\n pong();\n }\n });\n ws.addEventListener('close', () => {\n clearTimeout(pingTimeout);\n clearTimeout(pongTimeout);\n });\n}\n\nexport interface WebSocketConnectionOptions {\n WebSocketPonyfill?: typeof WebSocket;\n urlOptions: UrlOptionsWithConnectionParams;\n keepAlive: PingPongOptions & {\n enabled: boolean;\n };\n}\n\n/**\n * Manages a WebSocket connection with support for reconnection, keep-alive mechanisms,\n * and observable state tracking.\n */\nexport class WsConnection {\n static connectCount = 0;\n public id = ++WsConnection.connectCount;\n\n private readonly WebSocketPonyfill: typeof WebSocket;\n private readonly urlOptions: UrlOptionsWithConnectionParams;\n private readonly keepAliveOpts: WebSocketConnectionOptions['keepAlive'];\n public readonly wsObservable = behaviorSubject<WebSocket | null>(null);\n\n constructor(opts: WebSocketConnectionOptions) {\n this.WebSocketPonyfill = opts.WebSocketPonyfill ?? WebSocket;\n if (!this.WebSocketPonyfill) {\n throw new Error(\n \"No WebSocket implementation found - you probably don't want to use this on the server, but if you do you need to pass a `WebSocket`-ponyfill\",\n );\n }\n\n this.urlOptions = opts.urlOptions;\n this.keepAliveOpts = opts.keepAlive;\n }\n\n public get ws() {\n return this.wsObservable.get();\n }\n\n private set ws(ws) {\n this.wsObservable.next(ws);\n }\n\n /**\n * Checks if the WebSocket connection is open and ready to communicate.\n */\n public isOpen(): this is { ws: WebSocket } {\n return (\n !!this.ws &&\n this.ws.readyState === this.WebSocketPonyfill.OPEN &&\n !this.openPromise\n );\n }\n\n /**\n * Checks if the WebSocket connection is closed or in the process of closing.\n */\n public isClosed(): this is { ws: WebSocket } {\n return (\n !!this.ws &&\n (this.ws.readyState === this.WebSocketPonyfill.CLOSING ||\n this.ws.readyState === this.WebSocketPonyfill.CLOSED)\n );\n }\n\n /**\n * Manages the WebSocket opening process, ensuring that only one open operation\n * occurs at a time. Tracks the ongoing operation with `openPromise` to avoid\n * redundant calls and ensure proper synchronization.\n *\n * Sets up the keep-alive mechanism and necessary event listeners for the connection.\n *\n * @returns A promise that resolves once the WebSocket connection is successfully opened.\n */\n private openPromise: Promise<void> | null = null;\n public async open() {\n if (this.openPromise) return this.openPromise;\n\n this.id = ++WsConnection.connectCount;\n const wsPromise = prepareUrl(this.urlOptions).then(\n (url) => new this.WebSocketPonyfill(url),\n );\n this.openPromise = wsPromise.then(async (ws) => {\n this.ws = ws;\n\n // Set binaryType to handle both text and binary messages consistently\n ws.binaryType = 'arraybuffer';\n\n // Setup ping listener\n ws.addEventListener('message', function ({ data }) {\n if (data === 'PING') {\n this.send('PONG');\n }\n });\n\n if (this.keepAliveOpts.enabled) {\n setupPingInterval(ws, this.keepAliveOpts);\n }\n\n ws.addEventListener('close', () => {\n if (this.ws === ws) {\n this.ws = null;\n }\n });\n\n await asyncWsOpen(ws);\n\n if (this.urlOptions.connectionParams) {\n ws.send(await buildConnectionMessage(this.urlOptions.connectionParams));\n }\n });\n\n try {\n await this.openPromise;\n } finally {\n this.openPromise = null;\n }\n }\n\n /**\n * Closes the WebSocket connection gracefully.\n * Waits for any ongoing open operation to complete before closing.\n */\n public async close() {\n try {\n await this.openPromise;\n } finally {\n this.ws?.close();\n }\n }\n}\n\n/**\n * Provides a backward-compatible representation of the connection state.\n */\nexport function backwardCompatibility(connection: WsConnection) {\n if (connection.isOpen()) {\n return {\n id: connection.id,\n state: 'open',\n ws: connection.ws,\n } as const;\n }\n\n if (connection.isClosed()) {\n return {\n id: connection.id,\n state: 'closed',\n ws: connection.ws,\n } as const;\n }\n\n if (!connection.ws) {\n return null;\n }\n\n return {\n id: connection.id,\n state: 'connecting',\n ws: connection.ws,\n } as const;\n}\n","import type { AnyTRPCRouter } from '@trpc/server';\nimport type { BehaviorSubject } from '@trpc/server/observable';\nimport { behaviorSubject, observable } from '@trpc/server/observable';\nimport type {\n CombinedDataTransformer,\n TRPCClientIncomingMessage,\n TRPCClientIncomingRequest,\n TRPCClientOutgoingMessage,\n TRPCResponseMessage,\n} from '@trpc/server/unstable-core-do-not-import';\nimport {\n run,\n sleep,\n transformResult,\n} from '@trpc/server/unstable-core-do-not-import';\nimport { TRPCClientError } from '../../../TRPCClientError';\nimport type { TRPCConnectionState } from '../../internals/subscriptions';\nimport type { Operation, OperationResultEnvelope } from '../../types';\nimport type { Encoder } from './encoder';\nimport { jsonEncoder } from './encoder';\nimport type { WebSocketClientOptions } from './options';\nimport { exponentialBackoff, keepAliveDefaults, lazyDefaults } from './options';\nimport type { TCallbacks } from './requestManager';\nimport { RequestManager } from './requestManager';\nimport { ResettableTimeout, TRPCWebSocketClosedError } from './utils';\nimport { backwardCompatibility, WsConnection } from './wsConnection';\n\n/**\n * A WebSocket client for managing TRPC operations, supporting lazy initialization,\n * reconnection, keep-alive, and request management.\n */\nexport class WsClient {\n /**\n * Observable tracking the current connection state, including errors.\n */\n public readonly connectionState: BehaviorSubject<\n TRPCConnectionState<TRPCClientError<AnyTRPCRouter>>\n >;\n\n private allowReconnect = false;\n private requestManager = new RequestManager();\n private readonly activeConnection: WsConnection;\n private readonly reconnectRetryDelay: (attemptIndex: number) => number;\n private inactivityTimeout: ResettableTimeout;\n private readonly callbacks: Pick<\n WebSocketClientOptions,\n 'onOpen' | 'onClose' | 'onError'\n >;\n private readonly lazyMode: boolean;\n private readonly encoder: Encoder;\n\n constructor(opts: WebSocketClientOptions) {\n this.encoder = opts.experimental_encoder ?? jsonEncoder;\n // Initialize callbacks, connection parameters, and options.\n this.callbacks = {\n onOpen: opts.onOpen,\n onClose: opts.onClose,\n onError: opts.onError,\n };\n\n const lazyOptions = {\n ...lazyDefaults,\n ...opts.lazy,\n };\n\n // Set up inactivity timeout for lazy connections.\n this.inactivityTimeout = new ResettableTimeout(() => {\n if (\n this.requestManager.hasOutgoingRequests() ||\n this.requestManager.hasPendingRequests()\n ) {\n this.inactivityTimeout.reset();\n return;\n }\n\n this.close().catch(() => null);\n }, lazyOptions.closeMs);\n\n // Initialize the WebSocket connection.\n this.activeConnection = new WsConnection({\n WebSocketPonyfill: opts.WebSocket,\n urlOptions: opts,\n keepAlive: {\n ...keepAliveDefaults,\n ...opts.keepAlive,\n },\n });\n this.activeConnection.wsObservable.subscribe({\n next: (ws) => {\n if (!ws) return;\n this.setupWebSocketListeners(ws);\n },\n });\n this.reconnectRetryDelay = opts.retryDelayMs ?? exponentialBackoff;\n\n this.lazyMode = lazyOptions.enabled;\n\n this.connectionState = behaviorSubject<\n TRPCConnectionState<TRPCClientError<AnyTRPCRouter>>\n >({\n type: 'state',\n state: lazyOptions.enabled ? 'idle' : 'connecting',\n error: null,\n });\n\n // Automatically open the connection if lazy mode is disabled.\n if (!this.lazyMode) {\n this.open().catch(() => null);\n }\n }\n\n /**\n * Opens the WebSocket connection. Handles reconnection attempts and updates\n * the connection state accordingly.\n */\n private async open() {\n this.allowReconnect = true;\n if (this.connectionState.get().state === 'idle') {\n this.connectionState.next({\n type: 'state',\n state: 'connecting',\n error: null,\n });\n }\n\n try {\n await this.activeConnection.open();\n } catch (error) {\n this.reconnect(\n new TRPCWebSocketClosedError({\n message: 'Initialization error',\n cause: error,\n }),\n );\n return this.reconnecting;\n }\n }\n\n /**\n * Closes the WebSocket connection and stops managing requests.\n * Ensures all outgoing and pending requests are properly finalized.\n */\n public async close() {\n this.allowReconnect = false;\n this.inactivityTimeout.stop();\n\n const requestsToAwait: Promise<void>[] = [];\n for (const request of this.requestManager.getRequests()) {\n if (request.message.method === 'subscription') {\n request.callbacks.complete();\n } else if (request.state === 'outgoing') {\n request.callbacks.error(\n TRPCClientError.from(\n new TRPCWebSocketClosedError({\n message: 'Closed before connection was established',\n }),\n ),\n );\n } else {\n requestsToAwait.push(request.end);\n }\n }\n\n await Promise.all(requestsToAwait).catch(() => null);\n await this.activeConnection.close().catch(() => null);\n\n this.connectionState.next({\n type: 'state',\n state: 'idle',\n error: null,\n });\n }\n\n /**\n * Method to request the server.\n * Handles data transformation, batching of requests, and subscription lifecycle.\n *\n * @param op - The operation details including id, type, path, input and signal\n * @param transformer - Data transformer for serializing requests and deserializing responses\n * @param lastEventId - Optional ID of the last received event for subscriptions\n *\n * @returns An observable that emits operation results and handles cleanup\n */\n public request({\n op: { id, type, path, input, signal },\n transformer,\n lastEventId,\n }: {\n op: Pick<Operation, 'id' | 'type' | 'path' | 'input' | 'signal'>;\n transformer: CombinedDataTransformer;\n lastEventId?: string;\n }) {\n return observable<\n OperationResultEnvelope<unknown, TRPCClientError<AnyTRPCRouter>>,\n TRPCClientError<AnyTRPCRouter>\n >((observer) => {\n const abort = this.batchSend(\n {\n id,\n method: type,\n params: {\n input: transformer.input.serialize(input),\n path,\n lastEventId,\n },\n },\n {\n ...observer,\n next(event) {\n const transformed = transformResult(event, transformer.output);\n\n if (!transformed.ok) {\n observer.error(TRPCClientError.from(transformed.error));\n return;\n }\n\n observer.next({\n result: transformed.result,\n });\n },\n },\n );\n\n return () => {\n abort();\n\n if (type === 'subscription' && this.activeConnection.isOpen()) {\n this.send({\n id,\n method: 'subscription.stop',\n });\n }\n\n signal?.removeEventListener('abort', abort);\n };\n });\n }\n\n public get connection() {\n return backwardCompatibility(this.activeConnection);\n }\n\n /**\n * Manages the reconnection process for the WebSocket using retry logic.\n * Ensures that only one reconnection attempt is active at a time by tracking the current\n * reconnection state in the `reconnecting` promise.\n */\n private reconnecting: Promise<void> | null = null;\n private reconnect(closedError: TRPCWebSocketClosedError) {\n this.connectionState.next({\n type: 'state',\n state: 'connecting',\n error: TRPCClientError.from(closedError),\n });\n if (this.reconnecting) return;\n\n const tryReconnect = async (attemptIndex: number) => {\n try {\n await sleep(this.reconnectRetryDelay(attemptIndex));\n if (this.allowReconnect) {\n await this.activeConnection.close();\n await this.activeConnection.open();\n\n if (this.requestManager.hasPendingRequests()) {\n this.send(\n this.requestManager\n .getPendingRequests()\n .map(({ message }) => message),\n );\n }\n }\n this.reconnecting = null;\n } catch {\n await tryReconnect(attemptIndex + 1);\n }\n };\n\n this.reconnecting = tryReconnect(0);\n }\n\n private setupWebSocketListeners(ws: WebSocket) {\n const handleCloseOrError = (cause: unknown) => {\n const reqs = this.requestManager.getPendingRequests();\n for (const { message, callbacks } of reqs) {\n if (message.method === 'subscription') continue;\n\n callbacks.error(\n TRPCClientError.from(\n cause ??\n new TRPCWebSocketClosedError({\n message: 'WebSocket closed',\n cause,\n }),\n ),\n );\n this.requestManager.delete(message.id);\n }\n };\n\n ws.addEventListener('open', () => {\n run(async () => {\n if (this.lazyMode) {\n this.inactivityTimeout.start();\n }\n\n this.callbacks.onOpen?.();\n\n this.connectionState.next({\n type: 'state',\n state: 'pending',\n error: null,\n });\n }).catch((error) => {\n ws.close(3000);\n handleCloseOrError(error);\n });\n });\n\n ws.addEventListener('message', ({ data }) => {\n this.inactivityTimeout.reset();\n\n // Handle PING/PONG as text regardless of encoder\n if (['PING', 'PONG'].includes(data)) return;\n\n const incomingMessage = this.encoder.decode(\n data,\n ) as TRPCClientIncomingMessage;\n if ('method' in incomingMessage) {\n this.handleIncomingRequest(incomingMessage);\n return;\n }\n\n this.handleResponseMessage(incomingMessage);\n });\n\n ws.addEventListener('close', (event) => {\n handleCloseOrError(event);\n this.callbacks.onClose?.(event);\n\n if (!this.lazyMode || this.requestManager.hasPendingSubscriptions()) {\n this.reconnect(\n new TRPCWebSocketClosedError({\n message: 'WebSocket closed',\n cause: event,\n }),\n );\n }\n });\n\n ws.addEventListener('error', (event) => {\n handleCloseOrError(event);\n this.callbacks.onError?.(event);\n\n this.reconnect(\n new TRPCWebSocketClosedError({\n message: 'WebSocket closed',\n cause: event,\n }),\n );\n });\n }\n\n private handleResponseMessage(message: TRPCResponseMessage) {\n const request = this.requestManager.getPendingRequest(message.id);\n if (!request) return;\n\n request.callbacks.next(message);\n\n let completed = true;\n if ('result' in message && request.message.method === 'subscription') {\n if (message.result.type === 'data') {\n request.message.params.lastEventId = message.result.id;\n }\n\n if (message.result.type !== 'stopped') {\n completed = false;\n }\n }\n\n if (completed) {\n request.callbacks.complete();\n this.requestManager.delete(message.id);\n }\n }\n\n private handleIncomingRequest(message: TRPCClientIncomingRequest) {\n if (message.method === 'reconnect') {\n this.reconnect(\n new TRPCWebSocketClosedError({\n message: 'Server requested reconnect',\n }),\n );\n }\n }\n\n /**\n * Sends a message or batch of messages directly to the server.\n */\n private send(\n messageOrMessages: TRPCClientOutgoingMessage | TRPCClientOutgoingMessage[],\n ) {\n if (!this.activeConnection.isOpen()) {\n throw new Error('Active connection is not open');\n }\n\n const messages =\n messageOrMessages instanceof Array\n ? messageOrMessages\n : [messageOrMessages];\n this.activeConnection.ws.send(\n this.encoder.encode(messages.length === 1 ? messages[0] : messages),\n );\n }\n\n /**\n * Groups requests for batch sending.\n *\n * @returns A function to abort the batched request.\n */\n private batchSend(message: TRPCClientOutgoingMessage, callbacks: TCallbacks) {\n this.inactivityTimeout.reset();\n\n run(async () => {\n if (!this.activeConnection.isOpen()) {\n await this.open();\n }\n await sleep(0);\n\n if (!this.requestManager.hasOutgoingRequests()) return;\n\n this.send(this.requestManager.flush().map(({ message }) => message));\n }).catch((err) => {\n this.requestManager.delete(message.id);\n callbacks.error(TRPCClientError.from(err));\n });\n\n return this.requestManager.register(message, callbacks);\n }\n}\n","import type { Encoder } from './wsClient/encoder';\nimport { jsonEncoder } from './wsClient/encoder';\nimport type { WebSocketClientOptions } from './wsClient/options';\nimport { WsClient } from './wsClient/wsClient';\n\nexport function createWSClient(opts: WebSocketClientOptions) {\n return new WsClient(opts);\n}\n\nexport type TRPCWebSocketClient = ReturnType<typeof createWSClient>;\n\nexport { jsonEncoder, type Encoder, type WebSocketClientOptions };\n","import { observable } from '@trpc/server/observable';\nimport type {\n AnyRouter,\n inferClientTypes,\n} from '@trpc/server/unstable-core-do-not-import';\nimport type { TransformerOptions } from '../../unstable-internals';\nimport { getTransformer } from '../../unstable-internals';\nimport type { TRPCLink } from '../types';\nimport type {\n Encoder,\n TRPCWebSocketClient,\n WebSocketClientOptions,\n} from './createWsClient';\nimport { createWSClient, jsonEncoder } from './createWsClient';\n\nexport type WebSocketLinkOptions<TRouter extends AnyRouter> = {\n client: TRPCWebSocketClient;\n} & TransformerOptions<inferClientTypes<TRouter>>;\n\nexport function wsLink<TRouter extends AnyRouter>(\n opts: WebSocketLinkOptions<TRouter>,\n): TRPCLink<TRouter> {\n const { client } = opts;\n const transformer = getTransformer(opts.transformer);\n return () => {\n return ({ op }) => {\n return observable((observer) => {\n const connStateSubscription =\n op.type === 'subscription'\n ? client.connectionState.subscribe({\n next(result) {\n observer.next({\n result,\n context: op.context,\n });\n },\n })\n : null;\n\n const requestSubscription = client\n .request({\n op,\n transformer,\n })\n .subscribe(observer);\n\n return () => {\n requestSubscription.unsubscribe();\n connStateSubscription?.unsubscribe();\n };\n });\n };\n };\n}\n\nexport {\n createWSClient,\n jsonEncoder,\n type Encoder,\n type TRPCWebSocketClient,\n type WebSocketClientOptions,\n};\n"],"mappings":"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"} |
| const require_chunk = require('./chunk-DWy1uDak.cjs'); | ||
| const require_objectSpread2$1 = require('./objectSpread2-Bsvh_OqM.cjs'); | ||
| const require_TRPCClientError = require('./TRPCClientError-CQrTQLrk.cjs'); | ||
| const require_unstable_internals = require('./unstable-internals-M84gUQCV.cjs'); | ||
| const __trpc_server_observable = require_chunk.__toESM(require("@trpc/server/observable")); | ||
| const __trpc_server_unstable_core_do_not_import = require_chunk.__toESM(require("@trpc/server/unstable-core-do-not-import")); | ||
| //#region src/links/wsLink/wsClient/encoder.ts | ||
| const jsonEncoder = { | ||
| encode: (data) => JSON.stringify(data), | ||
| decode: (data) => { | ||
| if (typeof data !== "string") throw new Error("jsonEncoder received binary data. JSON uses text frames. Use a binary encoder for binary data."); | ||
| return JSON.parse(data); | ||
| } | ||
| }; | ||
| //#endregion | ||
| //#region src/links/wsLink/wsClient/options.ts | ||
| const lazyDefaults = { | ||
| enabled: false, | ||
| closeMs: 0 | ||
| }; | ||
| const keepAliveDefaults = { | ||
| enabled: false, | ||
| pongTimeoutMs: 1e3, | ||
| intervalMs: 5e3 | ||
| }; | ||
| /** | ||
| * Calculates a delay for exponential backoff based on the retry attempt index. | ||
| * The delay starts at 0 for the first attempt and doubles for each subsequent attempt, | ||
| * capped at 30 seconds. | ||
| */ | ||
| const exponentialBackoff = (attemptIndex) => { | ||
| return attemptIndex === 0 ? 0 : Math.min(1e3 * 2 ** attemptIndex, 3e4); | ||
| }; | ||
| //#endregion | ||
| //#region src/links/internals/urlWithConnectionParams.ts | ||
| /** | ||
| * Get the result of a value or function that returns a value | ||
| * It also optionally accepts typesafe arguments for the function | ||
| */ | ||
| const resultOf = (value, ...args) => { | ||
| return typeof value === "function" ? value(...args) : value; | ||
| }; | ||
| //#endregion | ||
| //#region src/links/wsLink/wsClient/utils.ts | ||
| var import_defineProperty$3 = require_chunk.__toESM(require_objectSpread2$1.require_defineProperty(), 1); | ||
| var TRPCWebSocketClosedError = class TRPCWebSocketClosedError extends Error { | ||
| constructor(opts) { | ||
| super(opts.message, { cause: opts.cause }); | ||
| this.name = "TRPCWebSocketClosedError"; | ||
| Object.setPrototypeOf(this, TRPCWebSocketClosedError.prototype); | ||
| } | ||
| }; | ||
| /** | ||
| * Utility class for managing a timeout that can be started, stopped, and reset. | ||
| * Useful for scenarios where the timeout duration is reset dynamically based on events. | ||
| */ | ||
| var ResettableTimeout = class { | ||
| constructor(onTimeout, timeoutMs) { | ||
| this.onTimeout = onTimeout; | ||
| this.timeoutMs = timeoutMs; | ||
| (0, import_defineProperty$3.default)(this, "timeout", void 0); | ||
| } | ||
| /** | ||
| * Resets the current timeout, restarting it with the same duration. | ||
| * Does nothing if no timeout is active. | ||
| */ | ||
| reset() { | ||
| if (!this.timeout) return; | ||
| clearTimeout(this.timeout); | ||
| this.timeout = setTimeout(this.onTimeout, this.timeoutMs); | ||
| } | ||
| start() { | ||
| clearTimeout(this.timeout); | ||
| this.timeout = setTimeout(this.onTimeout, this.timeoutMs); | ||
| } | ||
| stop() { | ||
| clearTimeout(this.timeout); | ||
| this.timeout = void 0; | ||
| } | ||
| }; | ||
| function withResolvers() { | ||
| let resolve; | ||
| let reject; | ||
| const promise = new Promise((res, rej) => { | ||
| resolve = res; | ||
| reject = rej; | ||
| }); | ||
| return { | ||
| promise, | ||
| resolve, | ||
| reject | ||
| }; | ||
| } | ||
| /** | ||
| * Resolves a WebSocket URL and optionally appends connection parameters. | ||
| * | ||
| * If connectionParams are provided, appends 'connectionParams=1' query parameter. | ||
| */ | ||
| async function prepareUrl(urlOptions) { | ||
| const url = await resultOf(urlOptions.url); | ||
| if (!urlOptions.connectionParams) return url; | ||
| const prefix = url.includes("?") ? "&" : "?"; | ||
| const connectionParams = `${prefix}connectionParams=1`; | ||
| return url + connectionParams; | ||
| } | ||
| async function buildConnectionMessage(connectionParams) { | ||
| const message = { | ||
| method: "connectionParams", | ||
| data: await resultOf(connectionParams) | ||
| }; | ||
| return JSON.stringify(message); | ||
| } | ||
| //#endregion | ||
| //#region src/links/wsLink/wsClient/requestManager.ts | ||
| var import_defineProperty$2 = require_chunk.__toESM(require_objectSpread2$1.require_defineProperty(), 1); | ||
| /** | ||
| * Manages WebSocket requests, tracking their lifecycle and providing utility methods | ||
| * for handling outgoing and pending requests. | ||
| * | ||
| * - **Outgoing requests**: Requests that are queued and waiting to be sent. | ||
| * - **Pending requests**: Requests that have been sent and are in flight awaiting a response. | ||
| * For subscriptions, multiple responses may be received until the subscription is closed. | ||
| */ | ||
| var RequestManager = class { | ||
| constructor() { | ||
| (0, import_defineProperty$2.default)(this, "outgoingRequests", new Array()); | ||
| (0, import_defineProperty$2.default)(this, "pendingRequests", {}); | ||
| } | ||
| /** | ||
| * Registers a new request by adding it to the outgoing queue and setting up | ||
| * callbacks for lifecycle events such as completion or error. | ||
| * | ||
| * @param message - The outgoing message to be sent. | ||
| * @param callbacks - Callback functions to observe the request's state. | ||
| * @returns A cleanup function to manually remove the request. | ||
| */ | ||
| register(message, callbacks) { | ||
| const { promise: end, resolve } = withResolvers(); | ||
| this.outgoingRequests.push({ | ||
| id: String(message.id), | ||
| message, | ||
| end, | ||
| callbacks: { | ||
| next: callbacks.next, | ||
| complete: () => { | ||
| callbacks.complete(); | ||
| resolve(); | ||
| }, | ||
| error: (e) => { | ||
| callbacks.error(e); | ||
| resolve(); | ||
| } | ||
| } | ||
| }); | ||
| return () => { | ||
| this.delete(message.id); | ||
| callbacks.complete(); | ||
| resolve(); | ||
| }; | ||
| } | ||
| /** | ||
| * Deletes a request from both the outgoing and pending collections, if it exists. | ||
| */ | ||
| delete(messageId) { | ||
| if (messageId === null) return; | ||
| this.outgoingRequests = this.outgoingRequests.filter(({ id }) => id !== String(messageId)); | ||
| delete this.pendingRequests[String(messageId)]; | ||
| } | ||
| /** | ||
| * Moves all outgoing requests to the pending state and clears the outgoing queue. | ||
| * | ||
| * The caller is expected to handle the actual sending of the requests | ||
| * (e.g., sending them over the network) after this method is called. | ||
| * | ||
| * @returns The list of requests that were transitioned to the pending state. | ||
| */ | ||
| flush() { | ||
| const requests = this.outgoingRequests; | ||
| this.outgoingRequests = []; | ||
| for (const request of requests) this.pendingRequests[request.id] = request; | ||
| return requests; | ||
| } | ||
| /** | ||
| * Retrieves all currently pending requests, which are in flight awaiting responses | ||
| * or handling ongoing subscriptions. | ||
| */ | ||
| getPendingRequests() { | ||
| return Object.values(this.pendingRequests); | ||
| } | ||
| /** | ||
| * Retrieves a specific pending request by its message ID. | ||
| */ | ||
| getPendingRequest(messageId) { | ||
| if (messageId === null) return null; | ||
| return this.pendingRequests[String(messageId)]; | ||
| } | ||
| /** | ||
| * Retrieves all outgoing requests, which are waiting to be sent. | ||
| */ | ||
| getOutgoingRequests() { | ||
| return this.outgoingRequests; | ||
| } | ||
| /** | ||
| * Retrieves all requests, both outgoing and pending, with their respective states. | ||
| * | ||
| * @returns An array of all requests with their state ("outgoing" or "pending"). | ||
| */ | ||
| getRequests() { | ||
| return [...this.getOutgoingRequests().map((request) => ({ | ||
| state: "outgoing", | ||
| message: request.message, | ||
| end: request.end, | ||
| callbacks: request.callbacks | ||
| })), ...this.getPendingRequests().map((request) => ({ | ||
| state: "pending", | ||
| message: request.message, | ||
| end: request.end, | ||
| callbacks: request.callbacks | ||
| }))]; | ||
| } | ||
| /** | ||
| * Checks if there are any pending requests, including ongoing subscriptions. | ||
| */ | ||
| hasPendingRequests() { | ||
| return this.getPendingRequests().length > 0; | ||
| } | ||
| /** | ||
| * Checks if there are any pending subscriptions | ||
| */ | ||
| hasPendingSubscriptions() { | ||
| return this.getPendingRequests().some((request) => request.message.method === "subscription"); | ||
| } | ||
| /** | ||
| * Checks if there are any outgoing requests waiting to be sent. | ||
| */ | ||
| hasOutgoingRequests() { | ||
| return this.outgoingRequests.length > 0; | ||
| } | ||
| }; | ||
| //#endregion | ||
| //#region src/links/wsLink/wsClient/wsConnection.ts | ||
| var import_defineProperty$1 = require_chunk.__toESM(require_objectSpread2$1.require_defineProperty(), 1); | ||
| /** | ||
| * Opens a WebSocket connection asynchronously and returns a promise | ||
| * that resolves when the connection is successfully established. | ||
| * The promise rejects if an error occurs during the connection attempt. | ||
| */ | ||
| function asyncWsOpen(ws) { | ||
| const { promise, resolve, reject } = withResolvers(); | ||
| ws.addEventListener("open", () => { | ||
| ws.removeEventListener("error", reject); | ||
| resolve(); | ||
| }); | ||
| ws.addEventListener("error", reject); | ||
| return promise; | ||
| } | ||
| /** | ||
| * Sets up a periodic ping-pong mechanism to keep the WebSocket connection alive. | ||
| * | ||
| * - Sends "PING" messages at regular intervals defined by `intervalMs`. | ||
| * - If a "PONG" response is not received within the `pongTimeoutMs`, the WebSocket is closed. | ||
| * - The ping timer resets upon receiving any message to maintain activity. | ||
| * - Automatically starts the ping process when the WebSocket connection is opened. | ||
| * - Cleans up timers when the WebSocket is closed. | ||
| * | ||
| * @param ws - The WebSocket instance to manage. | ||
| * @param options - Configuration options for ping-pong intervals and timeouts. | ||
| */ | ||
| function setupPingInterval(ws, { intervalMs, pongTimeoutMs }) { | ||
| let pingTimeout; | ||
| let pongTimeout; | ||
| function start() { | ||
| pingTimeout = setTimeout(() => { | ||
| ws.send("PING"); | ||
| pongTimeout = setTimeout(() => { | ||
| ws.close(); | ||
| }, pongTimeoutMs); | ||
| }, intervalMs); | ||
| } | ||
| function reset() { | ||
| clearTimeout(pingTimeout); | ||
| start(); | ||
| } | ||
| function pong() { | ||
| clearTimeout(pongTimeout); | ||
| reset(); | ||
| } | ||
| ws.addEventListener("open", start); | ||
| ws.addEventListener("message", ({ data }) => { | ||
| clearTimeout(pingTimeout); | ||
| start(); | ||
| if (data === "PONG") pong(); | ||
| }); | ||
| ws.addEventListener("close", () => { | ||
| clearTimeout(pingTimeout); | ||
| clearTimeout(pongTimeout); | ||
| }); | ||
| } | ||
| /** | ||
| * Manages a WebSocket connection with support for reconnection, keep-alive mechanisms, | ||
| * and observable state tracking. | ||
| */ | ||
| var WsConnection = class WsConnection { | ||
| constructor(opts) { | ||
| var _opts$WebSocketPonyfi; | ||
| (0, import_defineProperty$1.default)(this, "id", ++WsConnection.connectCount); | ||
| (0, import_defineProperty$1.default)(this, "WebSocketPonyfill", void 0); | ||
| (0, import_defineProperty$1.default)(this, "urlOptions", void 0); | ||
| (0, import_defineProperty$1.default)(this, "keepAliveOpts", void 0); | ||
| (0, import_defineProperty$1.default)(this, "wsObservable", (0, __trpc_server_observable.behaviorSubject)(null)); | ||
| (0, import_defineProperty$1.default)(this, "openPromise", null); | ||
| this.WebSocketPonyfill = (_opts$WebSocketPonyfi = opts.WebSocketPonyfill) !== null && _opts$WebSocketPonyfi !== void 0 ? _opts$WebSocketPonyfi : WebSocket; | ||
| if (!this.WebSocketPonyfill) throw new Error("No WebSocket implementation found - you probably don't want to use this on the server, but if you do you need to pass a `WebSocket`-ponyfill"); | ||
| this.urlOptions = opts.urlOptions; | ||
| this.keepAliveOpts = opts.keepAlive; | ||
| } | ||
| get ws() { | ||
| return this.wsObservable.get(); | ||
| } | ||
| set ws(ws) { | ||
| this.wsObservable.next(ws); | ||
| } | ||
| /** | ||
| * Checks if the WebSocket connection is open and ready to communicate. | ||
| */ | ||
| isOpen() { | ||
| return !!this.ws && this.ws.readyState === this.WebSocketPonyfill.OPEN && !this.openPromise; | ||
| } | ||
| /** | ||
| * Checks if the WebSocket connection is closed or in the process of closing. | ||
| */ | ||
| isClosed() { | ||
| return !!this.ws && (this.ws.readyState === this.WebSocketPonyfill.CLOSING || this.ws.readyState === this.WebSocketPonyfill.CLOSED); | ||
| } | ||
| async open() { | ||
| var _this = this; | ||
| if (_this.openPromise) return _this.openPromise; | ||
| _this.id = ++WsConnection.connectCount; | ||
| const wsPromise = prepareUrl(_this.urlOptions).then((url) => new _this.WebSocketPonyfill(url)); | ||
| _this.openPromise = wsPromise.then(async (ws) => { | ||
| _this.ws = ws; | ||
| ws.binaryType = "arraybuffer"; | ||
| ws.addEventListener("message", function({ data }) { | ||
| if (data === "PING") this.send("PONG"); | ||
| }); | ||
| if (_this.keepAliveOpts.enabled) setupPingInterval(ws, _this.keepAliveOpts); | ||
| ws.addEventListener("close", () => { | ||
| if (_this.ws === ws) _this.ws = null; | ||
| }); | ||
| await asyncWsOpen(ws); | ||
| if (_this.urlOptions.connectionParams) ws.send(await buildConnectionMessage(_this.urlOptions.connectionParams)); | ||
| }); | ||
| try { | ||
| await _this.openPromise; | ||
| } finally { | ||
| _this.openPromise = null; | ||
| } | ||
| } | ||
| /** | ||
| * Closes the WebSocket connection gracefully. | ||
| * Waits for any ongoing open operation to complete before closing. | ||
| */ | ||
| async close() { | ||
| var _this2 = this; | ||
| try { | ||
| await _this2.openPromise; | ||
| } finally { | ||
| var _this$ws; | ||
| (_this$ws = _this2.ws) === null || _this$ws === void 0 || _this$ws.close(); | ||
| } | ||
| } | ||
| }; | ||
| (0, import_defineProperty$1.default)(WsConnection, "connectCount", 0); | ||
| /** | ||
| * Provides a backward-compatible representation of the connection state. | ||
| */ | ||
| function backwardCompatibility(connection) { | ||
| if (connection.isOpen()) return { | ||
| id: connection.id, | ||
| state: "open", | ||
| ws: connection.ws | ||
| }; | ||
| if (connection.isClosed()) return { | ||
| id: connection.id, | ||
| state: "closed", | ||
| ws: connection.ws | ||
| }; | ||
| if (!connection.ws) return null; | ||
| return { | ||
| id: connection.id, | ||
| state: "connecting", | ||
| ws: connection.ws | ||
| }; | ||
| } | ||
| //#endregion | ||
| //#region src/links/wsLink/wsClient/wsClient.ts | ||
| var import_defineProperty = require_chunk.__toESM(require_objectSpread2$1.require_defineProperty(), 1); | ||
| var import_objectSpread2 = require_chunk.__toESM(require_objectSpread2$1.require_objectSpread2(), 1); | ||
| /** | ||
| * A WebSocket client for managing TRPC operations, supporting lazy initialization, | ||
| * reconnection, keep-alive, and request management. | ||
| */ | ||
| var WsClient = class { | ||
| constructor(opts) { | ||
| var _opts$experimental_en, _opts$retryDelayMs; | ||
| (0, import_defineProperty.default)(this, "connectionState", void 0); | ||
| (0, import_defineProperty.default)(this, "allowReconnect", false); | ||
| (0, import_defineProperty.default)(this, "requestManager", new RequestManager()); | ||
| (0, import_defineProperty.default)(this, "activeConnection", void 0); | ||
| (0, import_defineProperty.default)(this, "reconnectRetryDelay", void 0); | ||
| (0, import_defineProperty.default)(this, "inactivityTimeout", void 0); | ||
| (0, import_defineProperty.default)(this, "callbacks", void 0); | ||
| (0, import_defineProperty.default)(this, "lazyMode", void 0); | ||
| (0, import_defineProperty.default)(this, "encoder", void 0); | ||
| (0, import_defineProperty.default)(this, "reconnecting", null); | ||
| this.encoder = (_opts$experimental_en = opts.experimental_encoder) !== null && _opts$experimental_en !== void 0 ? _opts$experimental_en : jsonEncoder; | ||
| this.callbacks = { | ||
| onOpen: opts.onOpen, | ||
| onClose: opts.onClose, | ||
| onError: opts.onError | ||
| }; | ||
| const lazyOptions = (0, import_objectSpread2.default)((0, import_objectSpread2.default)({}, lazyDefaults), opts.lazy); | ||
| this.inactivityTimeout = new ResettableTimeout(() => { | ||
| if (this.requestManager.hasOutgoingRequests() || this.requestManager.hasPendingRequests()) { | ||
| this.inactivityTimeout.reset(); | ||
| return; | ||
| } | ||
| this.close().catch(() => null); | ||
| }, lazyOptions.closeMs); | ||
| this.activeConnection = new WsConnection({ | ||
| WebSocketPonyfill: opts.WebSocket, | ||
| urlOptions: opts, | ||
| keepAlive: (0, import_objectSpread2.default)((0, import_objectSpread2.default)({}, keepAliveDefaults), opts.keepAlive) | ||
| }); | ||
| this.activeConnection.wsObservable.subscribe({ next: (ws) => { | ||
| if (!ws) return; | ||
| this.setupWebSocketListeners(ws); | ||
| } }); | ||
| this.reconnectRetryDelay = (_opts$retryDelayMs = opts.retryDelayMs) !== null && _opts$retryDelayMs !== void 0 ? _opts$retryDelayMs : exponentialBackoff; | ||
| this.lazyMode = lazyOptions.enabled; | ||
| this.connectionState = (0, __trpc_server_observable.behaviorSubject)({ | ||
| type: "state", | ||
| state: lazyOptions.enabled ? "idle" : "connecting", | ||
| error: null | ||
| }); | ||
| if (!this.lazyMode) this.open().catch(() => null); | ||
| } | ||
| /** | ||
| * Opens the WebSocket connection. Handles reconnection attempts and updates | ||
| * the connection state accordingly. | ||
| */ | ||
| async open() { | ||
| var _this = this; | ||
| _this.allowReconnect = true; | ||
| if (_this.connectionState.get().state === "idle") _this.connectionState.next({ | ||
| type: "state", | ||
| state: "connecting", | ||
| error: null | ||
| }); | ||
| try { | ||
| await _this.activeConnection.open(); | ||
| } catch (error) { | ||
| _this.reconnect(new TRPCWebSocketClosedError({ | ||
| message: "Initialization error", | ||
| cause: error | ||
| })); | ||
| return _this.reconnecting; | ||
| } | ||
| } | ||
| /** | ||
| * Closes the WebSocket connection and stops managing requests. | ||
| * Ensures all outgoing and pending requests are properly finalized. | ||
| */ | ||
| async close() { | ||
| var _this2 = this; | ||
| _this2.allowReconnect = false; | ||
| _this2.inactivityTimeout.stop(); | ||
| const requestsToAwait = []; | ||
| for (const request of _this2.requestManager.getRequests()) if (request.message.method === "subscription") request.callbacks.complete(); | ||
| else if (request.state === "outgoing") request.callbacks.error(require_TRPCClientError.TRPCClientError.from(new TRPCWebSocketClosedError({ message: "Closed before connection was established" }))); | ||
| else requestsToAwait.push(request.end); | ||
| await Promise.all(requestsToAwait).catch(() => null); | ||
| await _this2.activeConnection.close().catch(() => null); | ||
| _this2.connectionState.next({ | ||
| type: "state", | ||
| state: "idle", | ||
| error: null | ||
| }); | ||
| } | ||
| /** | ||
| * Method to request the server. | ||
| * Handles data transformation, batching of requests, and subscription lifecycle. | ||
| * | ||
| * @param op - The operation details including id, type, path, input and signal | ||
| * @param transformer - Data transformer for serializing requests and deserializing responses | ||
| * @param lastEventId - Optional ID of the last received event for subscriptions | ||
| * | ||
| * @returns An observable that emits operation results and handles cleanup | ||
| */ | ||
| request({ op: { id, type, path, input, signal }, transformer, lastEventId }) { | ||
| return (0, __trpc_server_observable.observable)((observer) => { | ||
| const abort = this.batchSend({ | ||
| id, | ||
| method: type, | ||
| params: { | ||
| input: transformer.input.serialize(input), | ||
| path, | ||
| lastEventId | ||
| } | ||
| }, (0, import_objectSpread2.default)((0, import_objectSpread2.default)({}, observer), {}, { next(event) { | ||
| const transformed = (0, __trpc_server_unstable_core_do_not_import.transformResult)(event, transformer.output); | ||
| if (!transformed.ok) { | ||
| observer.error(require_TRPCClientError.TRPCClientError.from(transformed.error)); | ||
| return; | ||
| } | ||
| observer.next({ result: transformed.result }); | ||
| } })); | ||
| return () => { | ||
| abort(); | ||
| if (type === "subscription" && this.activeConnection.isOpen()) this.send({ | ||
| id, | ||
| method: "subscription.stop" | ||
| }); | ||
| signal === null || signal === void 0 || signal.removeEventListener("abort", abort); | ||
| }; | ||
| }); | ||
| } | ||
| get connection() { | ||
| return backwardCompatibility(this.activeConnection); | ||
| } | ||
| reconnect(closedError) { | ||
| var _this3 = this; | ||
| this.connectionState.next({ | ||
| type: "state", | ||
| state: "connecting", | ||
| error: require_TRPCClientError.TRPCClientError.from(closedError) | ||
| }); | ||
| if (this.reconnecting) return; | ||
| const tryReconnect = async (attemptIndex) => { | ||
| try { | ||
| await (0, __trpc_server_unstable_core_do_not_import.sleep)(_this3.reconnectRetryDelay(attemptIndex)); | ||
| if (_this3.allowReconnect) { | ||
| await _this3.activeConnection.close(); | ||
| await _this3.activeConnection.open(); | ||
| if (_this3.requestManager.hasPendingRequests()) _this3.send(_this3.requestManager.getPendingRequests().map(({ message }) => message)); | ||
| } | ||
| _this3.reconnecting = null; | ||
| } catch (_unused) { | ||
| await tryReconnect(attemptIndex + 1); | ||
| } | ||
| }; | ||
| this.reconnecting = tryReconnect(0); | ||
| } | ||
| setupWebSocketListeners(ws) { | ||
| var _this4 = this; | ||
| const handleCloseOrError = (cause) => { | ||
| const reqs = this.requestManager.getPendingRequests(); | ||
| for (const { message, callbacks } of reqs) { | ||
| if (message.method === "subscription") continue; | ||
| callbacks.error(require_TRPCClientError.TRPCClientError.from(cause !== null && cause !== void 0 ? cause : new TRPCWebSocketClosedError({ | ||
| message: "WebSocket closed", | ||
| cause | ||
| }))); | ||
| this.requestManager.delete(message.id); | ||
| } | ||
| }; | ||
| ws.addEventListener("open", () => { | ||
| (0, __trpc_server_unstable_core_do_not_import.run)(async () => { | ||
| var _this$callbacks$onOpe, _this$callbacks; | ||
| if (_this4.lazyMode) _this4.inactivityTimeout.start(); | ||
| (_this$callbacks$onOpe = (_this$callbacks = _this4.callbacks).onOpen) === null || _this$callbacks$onOpe === void 0 || _this$callbacks$onOpe.call(_this$callbacks); | ||
| _this4.connectionState.next({ | ||
| type: "state", | ||
| state: "pending", | ||
| error: null | ||
| }); | ||
| }).catch((error) => { | ||
| ws.close(3e3); | ||
| handleCloseOrError(error); | ||
| }); | ||
| }); | ||
| ws.addEventListener("message", ({ data }) => { | ||
| this.inactivityTimeout.reset(); | ||
| if (["PING", "PONG"].includes(data)) return; | ||
| const incomingMessage = this.encoder.decode(data); | ||
| if ("method" in incomingMessage) { | ||
| this.handleIncomingRequest(incomingMessage); | ||
| return; | ||
| } | ||
| this.handleResponseMessage(incomingMessage); | ||
| }); | ||
| ws.addEventListener("close", (event) => { | ||
| var _this$callbacks$onClo, _this$callbacks2; | ||
| handleCloseOrError(event); | ||
| (_this$callbacks$onClo = (_this$callbacks2 = this.callbacks).onClose) === null || _this$callbacks$onClo === void 0 || _this$callbacks$onClo.call(_this$callbacks2, event); | ||
| if (!this.lazyMode || this.requestManager.hasPendingSubscriptions()) this.reconnect(new TRPCWebSocketClosedError({ | ||
| message: "WebSocket closed", | ||
| cause: event | ||
| })); | ||
| }); | ||
| ws.addEventListener("error", (event) => { | ||
| var _this$callbacks$onErr, _this$callbacks3; | ||
| handleCloseOrError(event); | ||
| (_this$callbacks$onErr = (_this$callbacks3 = this.callbacks).onError) === null || _this$callbacks$onErr === void 0 || _this$callbacks$onErr.call(_this$callbacks3, event); | ||
| this.reconnect(new TRPCWebSocketClosedError({ | ||
| message: "WebSocket closed", | ||
| cause: event | ||
| })); | ||
| }); | ||
| } | ||
| handleResponseMessage(message) { | ||
| const request = this.requestManager.getPendingRequest(message.id); | ||
| if (!request) return; | ||
| request.callbacks.next(message); | ||
| let completed = true; | ||
| if ("result" in message && request.message.method === "subscription") { | ||
| if (message.result.type === "data") request.message.params.lastEventId = message.result.id; | ||
| if (message.result.type !== "stopped") completed = false; | ||
| } | ||
| if (completed) { | ||
| request.callbacks.complete(); | ||
| this.requestManager.delete(message.id); | ||
| } | ||
| } | ||
| handleIncomingRequest(message) { | ||
| if (message.method === "reconnect") this.reconnect(new TRPCWebSocketClosedError({ message: "Server requested reconnect" })); | ||
| } | ||
| /** | ||
| * Sends a message or batch of messages directly to the server. | ||
| */ | ||
| send(messageOrMessages) { | ||
| if (!this.activeConnection.isOpen()) throw new Error("Active connection is not open"); | ||
| const messages = messageOrMessages instanceof Array ? messageOrMessages : [messageOrMessages]; | ||
| this.activeConnection.ws.send(this.encoder.encode(messages.length === 1 ? messages[0] : messages)); | ||
| } | ||
| /** | ||
| * Groups requests for batch sending. | ||
| * | ||
| * @returns A function to abort the batched request. | ||
| */ | ||
| batchSend(message, callbacks) { | ||
| var _this5 = this; | ||
| this.inactivityTimeout.reset(); | ||
| (0, __trpc_server_unstable_core_do_not_import.run)(async () => { | ||
| if (!_this5.activeConnection.isOpen()) await _this5.open(); | ||
| await (0, __trpc_server_unstable_core_do_not_import.sleep)(0); | ||
| if (!_this5.requestManager.hasOutgoingRequests()) return; | ||
| _this5.send(_this5.requestManager.flush().map(({ message: message$1 }) => message$1)); | ||
| }).catch((err) => { | ||
| this.requestManager.delete(message.id); | ||
| callbacks.error(require_TRPCClientError.TRPCClientError.from(err)); | ||
| }); | ||
| return this.requestManager.register(message, callbacks); | ||
| } | ||
| }; | ||
| //#endregion | ||
| //#region src/links/wsLink/createWsClient.ts | ||
| function createWSClient(opts) { | ||
| return new WsClient(opts); | ||
| } | ||
| //#endregion | ||
| //#region src/links/wsLink/wsLink.ts | ||
| function wsLink(opts) { | ||
| const { client } = opts; | ||
| const transformer = require_unstable_internals.getTransformer(opts.transformer); | ||
| return () => { | ||
| return ({ op }) => { | ||
| return (0, __trpc_server_observable.observable)((observer) => { | ||
| const connStateSubscription = op.type === "subscription" ? client.connectionState.subscribe({ next(result) { | ||
| observer.next({ | ||
| result, | ||
| context: op.context | ||
| }); | ||
| } }) : null; | ||
| const requestSubscription = client.request({ | ||
| op, | ||
| transformer | ||
| }).subscribe(observer); | ||
| return () => { | ||
| requestSubscription.unsubscribe(); | ||
| connStateSubscription === null || connStateSubscription === void 0 || connStateSubscription.unsubscribe(); | ||
| }; | ||
| }); | ||
| }; | ||
| }; | ||
| } | ||
| //#endregion | ||
| Object.defineProperty(exports, 'createWSClient', { | ||
| enumerable: true, | ||
| get: function () { | ||
| return createWSClient; | ||
| } | ||
| }); | ||
| Object.defineProperty(exports, 'jsonEncoder', { | ||
| enumerable: true, | ||
| get: function () { | ||
| return jsonEncoder; | ||
| } | ||
| }); | ||
| Object.defineProperty(exports, 'resultOf', { | ||
| enumerable: true, | ||
| get: function () { | ||
| return resultOf; | ||
| } | ||
| }); | ||
| Object.defineProperty(exports, 'wsLink', { | ||
| enumerable: true, | ||
| get: function () { | ||
| return wsLink; | ||
| } | ||
| }); |
| import { TRPCConnectionState } from "./subscriptions.d-Dlr1nWGD.mjs"; | ||
| import { Operation, OperationResultEnvelope, TRPCClientError, TRPCLink } from "./types.d-CdPnK6XH.mjs"; | ||
| import { TransformerOptions } from "./unstable-internals.d-BOmV7EK1.mjs"; | ||
| import * as _trpc_server_observable0 from "@trpc/server/observable"; | ||
| import { BehaviorSubject } from "@trpc/server/observable"; | ||
| import { AnyRouter, CombinedDataTransformer, inferClientTypes } from "@trpc/server/unstable-core-do-not-import"; | ||
| import { AnyTRPCRouter } from "@trpc/server"; | ||
| import { Encoder } from "@trpc/server/adapters/ws"; | ||
| import { TRPCRequestInfo } from "@trpc/server/http"; | ||
| //#region src/links/wsLink/wsClient/encoder.d.ts | ||
| declare const jsonEncoder: Encoder; | ||
| //# sourceMappingURL=encoder.d.ts.map | ||
| //#endregion | ||
| //#region src/links/internals/urlWithConnectionParams.d.ts | ||
| /** | ||
| * A value that can be wrapped in callback | ||
| */ | ||
| type CallbackOrValue<T> = T | (() => T | Promise<T>); | ||
| interface UrlOptionsWithConnectionParams { | ||
| /** | ||
| * The URL to connect to (can be a function that returns a URL) | ||
| */ | ||
| url: CallbackOrValue<string>; | ||
| /** | ||
| * Connection params that are available in `createContext()` | ||
| * - For `wsLink`/`wsClient`, these are sent as the first message | ||
| * - For `httpSubscriptionLink`, these are serialized as part of the URL under the `connectionParams` query | ||
| */ | ||
| connectionParams?: CallbackOrValue<TRPCRequestInfo['connectionParams']>; | ||
| } | ||
| //# sourceMappingURL=urlWithConnectionParams.d.ts.map | ||
| //#endregion | ||
| //#region src/links/wsLink/wsClient/options.d.ts | ||
| interface WebSocketClientOptions extends UrlOptionsWithConnectionParams { | ||
| /** | ||
| * Ponyfill which WebSocket implementation to use | ||
| */ | ||
| WebSocket?: typeof WebSocket; | ||
| /** | ||
| * The number of milliseconds before a reconnect is attempted. | ||
| * @default {@link exponentialBackoff} | ||
| */ | ||
| retryDelayMs?: (attemptIndex: number) => number; | ||
| /** | ||
| * Triggered when a WebSocket connection is established | ||
| */ | ||
| onOpen?: () => void; | ||
| /** | ||
| * Triggered when a WebSocket connection encounters an error | ||
| */ | ||
| onError?: (evt?: Event) => void; | ||
| /** | ||
| * Triggered when a WebSocket connection is closed | ||
| */ | ||
| onClose?: (cause?: { | ||
| code?: number; | ||
| }) => void; | ||
| /** | ||
| * Lazy mode will close the WebSocket automatically after a period of inactivity (no messages sent or received and no pending requests) | ||
| */ | ||
| lazy?: { | ||
| /** | ||
| * Enable lazy mode | ||
| * @default false | ||
| */ | ||
| enabled: boolean; | ||
| /** | ||
| * Close the WebSocket after this many milliseconds | ||
| * @default 0 | ||
| */ | ||
| closeMs: number; | ||
| }; | ||
| /** | ||
| * Send ping messages to the server and kill the connection if no pong message is returned | ||
| */ | ||
| keepAlive?: { | ||
| /** | ||
| * @default false | ||
| */ | ||
| enabled: boolean; | ||
| /** | ||
| * Send a ping message every this many milliseconds | ||
| * @default 5_000 | ||
| */ | ||
| intervalMs?: number; | ||
| /** | ||
| * Close the WebSocket after this many milliseconds if the server does not respond | ||
| * @default 1_000 | ||
| */ | ||
| pongTimeoutMs?: number; | ||
| }; | ||
| /** | ||
| * Custom encoder for wire encoding (e.g. custom binary formats) | ||
| * @default jsonEncoder | ||
| */ | ||
| experimental_encoder?: Encoder; | ||
| } | ||
| /** | ||
| * Default options for lazy WebSocket connections. | ||
| * Determines whether the connection should be established lazily and defines the delay before closure. | ||
| */ | ||
| //#endregion | ||
| //#region src/links/wsLink/wsClient/wsClient.d.ts | ||
| /** | ||
| * A WebSocket client for managing TRPC operations, supporting lazy initialization, | ||
| * reconnection, keep-alive, and request management. | ||
| */ | ||
| declare class WsClient { | ||
| /** | ||
| * Observable tracking the current connection state, including errors. | ||
| */ | ||
| readonly connectionState: BehaviorSubject<TRPCConnectionState<TRPCClientError<AnyTRPCRouter>>>; | ||
| private allowReconnect; | ||
| private requestManager; | ||
| private readonly activeConnection; | ||
| private readonly reconnectRetryDelay; | ||
| private inactivityTimeout; | ||
| private readonly callbacks; | ||
| private readonly lazyMode; | ||
| private readonly encoder; | ||
| constructor(opts: WebSocketClientOptions); | ||
| /** | ||
| * Opens the WebSocket connection. Handles reconnection attempts and updates | ||
| * the connection state accordingly. | ||
| */ | ||
| private open; | ||
| /** | ||
| * Closes the WebSocket connection and stops managing requests. | ||
| * Ensures all outgoing and pending requests are properly finalized. | ||
| */ | ||
| close(): Promise<void>; | ||
| /** | ||
| * Method to request the server. | ||
| * Handles data transformation, batching of requests, and subscription lifecycle. | ||
| * | ||
| * @param op - The operation details including id, type, path, input and signal | ||
| * @param transformer - Data transformer for serializing requests and deserializing responses | ||
| * @param lastEventId - Optional ID of the last received event for subscriptions | ||
| * | ||
| * @returns An observable that emits operation results and handles cleanup | ||
| */ | ||
| request({ | ||
| op: { | ||
| id, | ||
| type, | ||
| path, | ||
| input, | ||
| signal | ||
| }, | ||
| transformer, | ||
| lastEventId | ||
| }: { | ||
| op: Pick<Operation, 'id' | 'type' | 'path' | 'input' | 'signal'>; | ||
| transformer: CombinedDataTransformer; | ||
| lastEventId?: string; | ||
| }): _trpc_server_observable0.Observable<OperationResultEnvelope<unknown, TRPCClientError<AnyTRPCRouter>>, TRPCClientError<AnyTRPCRouter>>; | ||
| get connection(): { | ||
| readonly id: number; | ||
| readonly state: "open"; | ||
| readonly ws: WebSocket; | ||
| } | { | ||
| readonly id: number; | ||
| readonly state: "closed"; | ||
| readonly ws: WebSocket; | ||
| } | { | ||
| readonly id: number; | ||
| readonly state: "connecting"; | ||
| readonly ws: WebSocket; | ||
| } | null; | ||
| /** | ||
| * Manages the reconnection process for the WebSocket using retry logic. | ||
| * Ensures that only one reconnection attempt is active at a time by tracking the current | ||
| * reconnection state in the `reconnecting` promise. | ||
| */ | ||
| private reconnecting; | ||
| private reconnect; | ||
| private setupWebSocketListeners; | ||
| private handleResponseMessage; | ||
| private handleIncomingRequest; | ||
| /** | ||
| * Sends a message or batch of messages directly to the server. | ||
| */ | ||
| private send; | ||
| /** | ||
| * Groups requests for batch sending. | ||
| * | ||
| * @returns A function to abort the batched request. | ||
| */ | ||
| private batchSend; | ||
| } | ||
| //# sourceMappingURL=wsClient.d.ts.map | ||
| //#endregion | ||
| //#region src/links/wsLink/createWsClient.d.ts | ||
| declare function createWSClient(opts: WebSocketClientOptions): WsClient; | ||
| type TRPCWebSocketClient = ReturnType<typeof createWSClient>; | ||
| //#endregion | ||
| //#region src/links/wsLink/wsLink.d.ts | ||
| type WebSocketLinkOptions<TRouter extends AnyRouter> = { | ||
| client: TRPCWebSocketClient; | ||
| } & TransformerOptions<inferClientTypes<TRouter>>; | ||
| declare function wsLink<TRouter extends AnyRouter>(opts: WebSocketLinkOptions<TRouter>): TRPCLink<TRouter>; | ||
| //#endregion | ||
| export { Encoder, TRPCWebSocketClient, UrlOptionsWithConnectionParams, WebSocketClientOptions, WebSocketLinkOptions, createWSClient, jsonEncoder, wsLink }; | ||
| //# sourceMappingURL=wsLink.d-CwxAK-4Z.d.mts.map |
| {"version":3,"file":"wsLink.d-CwxAK-4Z.d.mts","names":[],"sources":["../src/links/wsLink/wsClient/encoder.ts","../src/links/internals/urlWithConnectionParams.ts","../src/links/wsLink/wsClient/options.ts","../src/links/wsLink/wsClient/wsClient.ts","../src/links/wsLink/createWsClient.ts","../src/links/wsLink/wsLink.ts"],"sourcesContent":[],"mappings":";;;;;;;;;;;cAIa,aAAa;;;;;;;;KCcd,qBAAqB,WAAW,IAAI,QAAQ;UAEvC,8BAAA;EDhBJ;;;OCoBN;EANK;;;;;EAA6C,gBAAT,CAAA,EAa3B,eAb2B,CAaX,eAbW,CAAA,kBAAA,CAAA,CAAA;AAAO;AAEvD;;;UCjBiB,sBAAA,SAA+B;;;;qBAI3B;;;;;EFHR,YAAA,CAAA,EAWZ,CAAA,YAXyB,EAAA,MAWzB,EAAA,GAAA,MAAA;;;;ECGW,MAAA,CAAA,EAAA,GAAA,GAAA,IAAe;EAAA;;;EAAkB,OAAW,CAAA,EAAA,CAAA,GAAA,CAAA,ECErC,KDFqC,EAAA,GAAA,IAAA;EAAC;AAAF;AAEvD;EAA+C,OAAA,CAAA,EAAA,CAAA,KAIzB,CAJyB,EAAA;IAIxC,IAAA,CAAA,EAAA,MAAA;EAAe,CAAA,EAOe,GAAA,IAAA;EAAe;AAAhB;;;;AC5BpC;;;IAiBmB,OAAA,EAAA,OAAA;IA2CM;;AA5DqD;;;;EC4BjE;;;EAKwC,SAA7B,CAAA,EAAA;IAApB;;;IA0GgB,OAAA,EAAA,OAAA;IA0CV;;;;IAAuB,UAAA,CAAA,EAAA,MAAA;IAC7B;;;;IAIa,aAAA,CAAA,EAAA,MAAA;EAAuB,CAAA;EAErC;;;;EAAA,oBAAA,CAAA,EDhIsB,OCgItB;;;;;;;;;;;;AH3LU,cG2BA,QAAA,CH3Ba;;;;ECcd,SAAA,eAAe,EEiBQ,eFjBR,CEkBvB,mBFlBuB,CEkBH,eFlBG,CEkBa,aFlBb,CAAA,CAAA,CAAA;EAAA,QAAA,cAAA;EAAA,QAAM,cAAA;EAAC,iBAAU,gBAAA;EAAC,iBAAW,mBAAA;EAAC,QAAT,iBAAA;EAAO,iBAAA,SAAA;EAEtC,iBAAA,QAAA;EAA8B,iBAAA,OAAA;EAAA,WAIxC,CAAA,IAAA,EE2Ba,sBF3Bb;EAAe;;AAOc;;;;AC5BpC;;;EAI8B,KAaX,CAAA,CAAA,EC0HC,OD1HD,CAAA,IAAA,CAAA;EAAK;;AAjBsD;;;;AC4B9E;;;;EAKuC,OAAnC,CAAA;IAAA,EAAA,EAAA;MAAA,EAAA;MAAA,IAAA;MAAA,IAAA;MAAA,KAAA;MAAA;IAAA,CAAA;IAAA,WAAA;IAAA;EA0GgB,CA1GhB,EAAA;IAD+B,EAAA,EAyJ3B,IAzJ2B,CAyJtB,SAzJsB,EAAA,IAAA,GAAA,MAAA,GAAA,MAAA,GAAA,OAAA,GAAA,QAAA,CAAA;IAgBf,WAAA,EA0IH,uBA1IG;IA2FA,WAAA,CAAA,EAAA,MAAA;EAAA,CAAA,CAAA,EAiDjB,wBAAA,CAAA,UAPO,CAOP,uBAPO,CAAA,OAAA,EAOP,eAPO,CAOP,aAPO,CAAA,CAAA,EAOP,eAPO,CAOP,aAPO,CAAA,CAAA;EAAE,IAAE,UAAA,CAAA,CAAA,EAAA;IAAM,SAAA,EAAA,EAAA,MAAA;IAAM,SAAA,KAAA,EAAA,MAAA;IAAO,SAAA,EAAA,EAO9B,SAP8B;EAAM,CAAA,GACnC;IACA,SAAA,EAAA,EAAA,MAAA;IAES,SAAA,KAAA,EAAA,QAAA;IAAL,SAAA,EAAA,WAAA;EAAI,CAAA,GACK;IAEd,SAAA,EAAA,EAAA,MAAA;IAAA,SAAA,KAAA,EAAA,YAAA;IAAA,SAAA,EAAA,WAAA;EAAA,CAAA,GAAA,IAAA;EAAA;;;;;;;;;EC1La,QAAA,qBAAc;EAAA;;;EAA6B,QAAA,IAAA;EAI/C;;;;AAAgC;;;;;;iBAJ5B,cAAA,OAAqB,yBAAsB;KAI/C,mBAAA,GAAsB,kBAAkB;;;KCMxC,qCAAqC;UACvC;IACN,mBAAmB,iBAAiB;iBAExB,uBAAuB,iBAC/B,qBAAqB,WAC1B,SAAS"} |
| import { TRPCConnectionState } from "./subscriptions.d-Ciljg_dH.cjs"; | ||
| import { Operation, OperationResultEnvelope, TRPCClientError, TRPCLink } from "./types.d-Cs0iOdcD.cjs"; | ||
| import { TransformerOptions } from "./unstable-internals.d-kWsZTlQq.cjs"; | ||
| import { AnyRouter, CombinedDataTransformer, inferClientTypes } from "@trpc/server/unstable-core-do-not-import"; | ||
| import * as _trpc_server_observable0 from "@trpc/server/observable"; | ||
| import { BehaviorSubject } from "@trpc/server/observable"; | ||
| import { AnyTRPCRouter } from "@trpc/server"; | ||
| import { Encoder } from "@trpc/server/adapters/ws"; | ||
| import { TRPCRequestInfo } from "@trpc/server/http"; | ||
| //#region src/links/wsLink/wsClient/encoder.d.ts | ||
| declare const jsonEncoder: Encoder; | ||
| //# sourceMappingURL=encoder.d.ts.map | ||
| //#endregion | ||
| //#region src/links/internals/urlWithConnectionParams.d.ts | ||
| /** | ||
| * A value that can be wrapped in callback | ||
| */ | ||
| type CallbackOrValue<T> = T | (() => T | Promise<T>); | ||
| interface UrlOptionsWithConnectionParams { | ||
| /** | ||
| * The URL to connect to (can be a function that returns a URL) | ||
| */ | ||
| url: CallbackOrValue<string>; | ||
| /** | ||
| * Connection params that are available in `createContext()` | ||
| * - For `wsLink`/`wsClient`, these are sent as the first message | ||
| * - For `httpSubscriptionLink`, these are serialized as part of the URL under the `connectionParams` query | ||
| */ | ||
| connectionParams?: CallbackOrValue<TRPCRequestInfo['connectionParams']>; | ||
| } | ||
| //# sourceMappingURL=urlWithConnectionParams.d.ts.map | ||
| //#endregion | ||
| //#region src/links/wsLink/wsClient/options.d.ts | ||
| interface WebSocketClientOptions extends UrlOptionsWithConnectionParams { | ||
| /** | ||
| * Ponyfill which WebSocket implementation to use | ||
| */ | ||
| WebSocket?: typeof WebSocket; | ||
| /** | ||
| * The number of milliseconds before a reconnect is attempted. | ||
| * @default {@link exponentialBackoff} | ||
| */ | ||
| retryDelayMs?: (attemptIndex: number) => number; | ||
| /** | ||
| * Triggered when a WebSocket connection is established | ||
| */ | ||
| onOpen?: () => void; | ||
| /** | ||
| * Triggered when a WebSocket connection encounters an error | ||
| */ | ||
| onError?: (evt?: Event) => void; | ||
| /** | ||
| * Triggered when a WebSocket connection is closed | ||
| */ | ||
| onClose?: (cause?: { | ||
| code?: number; | ||
| }) => void; | ||
| /** | ||
| * Lazy mode will close the WebSocket automatically after a period of inactivity (no messages sent or received and no pending requests) | ||
| */ | ||
| lazy?: { | ||
| /** | ||
| * Enable lazy mode | ||
| * @default false | ||
| */ | ||
| enabled: boolean; | ||
| /** | ||
| * Close the WebSocket after this many milliseconds | ||
| * @default 0 | ||
| */ | ||
| closeMs: number; | ||
| }; | ||
| /** | ||
| * Send ping messages to the server and kill the connection if no pong message is returned | ||
| */ | ||
| keepAlive?: { | ||
| /** | ||
| * @default false | ||
| */ | ||
| enabled: boolean; | ||
| /** | ||
| * Send a ping message every this many milliseconds | ||
| * @default 5_000 | ||
| */ | ||
| intervalMs?: number; | ||
| /** | ||
| * Close the WebSocket after this many milliseconds if the server does not respond | ||
| * @default 1_000 | ||
| */ | ||
| pongTimeoutMs?: number; | ||
| }; | ||
| /** | ||
| * Custom encoder for wire encoding (e.g. custom binary formats) | ||
| * @default jsonEncoder | ||
| */ | ||
| experimental_encoder?: Encoder; | ||
| } | ||
| /** | ||
| * Default options for lazy WebSocket connections. | ||
| * Determines whether the connection should be established lazily and defines the delay before closure. | ||
| */ | ||
| //#endregion | ||
| //#region src/links/wsLink/wsClient/wsClient.d.ts | ||
| /** | ||
| * A WebSocket client for managing TRPC operations, supporting lazy initialization, | ||
| * reconnection, keep-alive, and request management. | ||
| */ | ||
| declare class WsClient { | ||
| /** | ||
| * Observable tracking the current connection state, including errors. | ||
| */ | ||
| readonly connectionState: BehaviorSubject<TRPCConnectionState<TRPCClientError<AnyTRPCRouter>>>; | ||
| private allowReconnect; | ||
| private requestManager; | ||
| private readonly activeConnection; | ||
| private readonly reconnectRetryDelay; | ||
| private inactivityTimeout; | ||
| private readonly callbacks; | ||
| private readonly lazyMode; | ||
| private readonly encoder; | ||
| constructor(opts: WebSocketClientOptions); | ||
| /** | ||
| * Opens the WebSocket connection. Handles reconnection attempts and updates | ||
| * the connection state accordingly. | ||
| */ | ||
| private open; | ||
| /** | ||
| * Closes the WebSocket connection and stops managing requests. | ||
| * Ensures all outgoing and pending requests are properly finalized. | ||
| */ | ||
| close(): Promise<void>; | ||
| /** | ||
| * Method to request the server. | ||
| * Handles data transformation, batching of requests, and subscription lifecycle. | ||
| * | ||
| * @param op - The operation details including id, type, path, input and signal | ||
| * @param transformer - Data transformer for serializing requests and deserializing responses | ||
| * @param lastEventId - Optional ID of the last received event for subscriptions | ||
| * | ||
| * @returns An observable that emits operation results and handles cleanup | ||
| */ | ||
| request({ | ||
| op: { | ||
| id, | ||
| type, | ||
| path, | ||
| input, | ||
| signal | ||
| }, | ||
| transformer, | ||
| lastEventId | ||
| }: { | ||
| op: Pick<Operation, 'id' | 'type' | 'path' | 'input' | 'signal'>; | ||
| transformer: CombinedDataTransformer; | ||
| lastEventId?: string; | ||
| }): _trpc_server_observable0.Observable<OperationResultEnvelope<unknown, TRPCClientError<AnyTRPCRouter>>, TRPCClientError<AnyTRPCRouter>>; | ||
| get connection(): { | ||
| readonly id: number; | ||
| readonly state: "open"; | ||
| readonly ws: WebSocket; | ||
| } | { | ||
| readonly id: number; | ||
| readonly state: "closed"; | ||
| readonly ws: WebSocket; | ||
| } | { | ||
| readonly id: number; | ||
| readonly state: "connecting"; | ||
| readonly ws: WebSocket; | ||
| } | null; | ||
| /** | ||
| * Manages the reconnection process for the WebSocket using retry logic. | ||
| * Ensures that only one reconnection attempt is active at a time by tracking the current | ||
| * reconnection state in the `reconnecting` promise. | ||
| */ | ||
| private reconnecting; | ||
| private reconnect; | ||
| private setupWebSocketListeners; | ||
| private handleResponseMessage; | ||
| private handleIncomingRequest; | ||
| /** | ||
| * Sends a message or batch of messages directly to the server. | ||
| */ | ||
| private send; | ||
| /** | ||
| * Groups requests for batch sending. | ||
| * | ||
| * @returns A function to abort the batched request. | ||
| */ | ||
| private batchSend; | ||
| } | ||
| //# sourceMappingURL=wsClient.d.ts.map | ||
| //#endregion | ||
| //#region src/links/wsLink/createWsClient.d.ts | ||
| declare function createWSClient(opts: WebSocketClientOptions): WsClient; | ||
| type TRPCWebSocketClient = ReturnType<typeof createWSClient>; | ||
| //#endregion | ||
| //#region src/links/wsLink/wsLink.d.ts | ||
| type WebSocketLinkOptions<TRouter extends AnyRouter> = { | ||
| client: TRPCWebSocketClient; | ||
| } & TransformerOptions<inferClientTypes<TRouter>>; | ||
| declare function wsLink<TRouter extends AnyRouter>(opts: WebSocketLinkOptions<TRouter>): TRPCLink<TRouter>; | ||
| //#endregion | ||
| export { Encoder, TRPCWebSocketClient, UrlOptionsWithConnectionParams, WebSocketClientOptions, WebSocketLinkOptions, createWSClient, jsonEncoder, wsLink }; | ||
| //# sourceMappingURL=wsLink.d-DcIkru0s.d.cts.map |
| {"version":3,"file":"wsLink.d-DcIkru0s.d.cts","names":[],"sources":["../src/links/wsLink/wsClient/encoder.ts","../src/links/internals/urlWithConnectionParams.ts","../src/links/wsLink/wsClient/options.ts","../src/links/wsLink/wsClient/wsClient.ts","../src/links/wsLink/createWsClient.ts","../src/links/wsLink/wsLink.ts"],"sourcesContent":[],"mappings":";;;;;;;;;;;cAIa,aAAa;;;;;;;;KCcd,qBAAqB,WAAW,IAAI,QAAQ;UAEvC,8BAAA;EDhBJ;;;OCoBN;EANK;;;;;EAA6C,gBAAT,CAAA,EAa3B,eAb2B,CAaX,eAbW,CAAA,kBAAA,CAAA,CAAA;AAAO;AAEvD;;;UCjBiB,sBAAA,SAA+B;;;;qBAI3B;;;;;EFHR,YAAA,CAAA,EAWZ,CAAA,YAXyB,EAAA,MAWzB,EAAA,GAAA,MAAA;;;;ECGW,MAAA,CAAA,EAAA,GAAA,GAAA,IAAe;EAAA;;;EAAkB,OAAW,CAAA,EAAA,CAAA,GAAA,CAAA,ECErC,KDFqC,EAAA,GAAA,IAAA;EAAC;AAAF;AAEvD;EAA+C,OAAA,CAAA,EAAA,CAAA,KAIzB,CAJyB,EAAA;IAIxC,IAAA,CAAA,EAAA,MAAA;EAAe,CAAA,EAOe,GAAA,IAAA;EAAe;AAAhB;;;;AC5BpC;;;IAiBmB,OAAA,EAAA,OAAA;IA2CM;;AA5DqD;;;;EC4BjE;;;EAKwC,SAA7B,CAAA,EAAA;IAApB;;;IA0GgB,OAAA,EAAA,OAAA;IA0CV;;;;IAAuB,UAAA,CAAA,EAAA,MAAA;IAC7B;;;;IAIa,aAAA,CAAA,EAAA,MAAA;EAAuB,CAAA;EAErC;;;;EAAA,oBAAA,CAAA,EDhIsB,OCgItB;;;;;;;;;;;;AH3LU,cG2BA,QAAA,CH3Ba;;;;ECcd,SAAA,eAAe,EEiBQ,eFjBR,CEkBvB,mBFlBuB,CEkBH,eFlBG,CEkBa,aFlBb,CAAA,CAAA,CAAA;EAAA,QAAA,cAAA;EAAA,QAAM,cAAA;EAAC,iBAAU,gBAAA;EAAC,iBAAW,mBAAA;EAAC,QAAT,iBAAA;EAAO,iBAAA,SAAA;EAEtC,iBAAA,QAAA;EAA8B,iBAAA,OAAA;EAAA,WAIxC,CAAA,IAAA,EE2Ba,sBF3Bb;EAAe;;AAOc;;;;AC5BpC;;;EAI8B,KAaX,CAAA,CAAA,EC0HC,OD1HD,CAAA,IAAA,CAAA;EAAK;;AAjBsD;;;;AC4B9E;;;;EAKuC,OAAnC,CAAA;IAAA,EAAA,EAAA;MAAA,EAAA;MAAA,IAAA;MAAA,IAAA;MAAA,KAAA;MAAA;IAAA,CAAA;IAAA,WAAA;IAAA;EA0GgB,CA1GhB,EAAA;IAD+B,EAAA,EAyJ3B,IAzJ2B,CAyJtB,SAzJsB,EAAA,IAAA,GAAA,MAAA,GAAA,MAAA,GAAA,OAAA,GAAA,QAAA,CAAA;IAgBf,WAAA,EA0IH,uBA1IG;IA2FA,WAAA,CAAA,EAAA,MAAA;EAAA,CAAA,CAAA,EAiDjB,wBAAA,CAAA,UAPO,CAOP,uBAPO,CAAA,OAAA,EAOP,eAPO,CAOP,aAPO,CAAA,CAAA,EAOP,eAPO,CAOP,aAPO,CAAA,CAAA;EAAE,IAAE,UAAA,CAAA,CAAA,EAAA;IAAM,SAAA,EAAA,EAAA,MAAA;IAAM,SAAA,KAAA,EAAA,MAAA;IAAO,SAAA,EAAA,EAO9B,SAP8B;EAAM,CAAA,GACnC;IACA,SAAA,EAAA,EAAA,MAAA;IAES,SAAA,KAAA,EAAA,QAAA;IAAL,SAAA,EAAA,WAAA;EAAI,CAAA,GACK;IAEd,SAAA,EAAA,EAAA,MAAA;IAAA,SAAA,KAAA,EAAA,YAAA;IAAA,SAAA,EAAA,WAAA;EAAA,CAAA,GAAA,IAAA;EAAA;;;;;;;;;EC1La,QAAA,qBAAc;EAAA;;;EAA6B,QAAA,IAAA;EAI/C;;;;AAAgC;;;;;;iBAJ5B,cAAA,OAAqB,yBAAsB;KAI/C,mBAAA,GAAsB,kBAAkB;;;KCMxC,qCAAqC;UACvC;IACN,mBAAmB,iBAAiB;iBAExB,uBAAuB,iBAC/B,qBAAqB,WAC1B,SAAS"} |
+5
-5
| const require_chunk = require('./chunk-DWy1uDak.cjs'); | ||
| const require_splitLink = require('./splitLink-BMgxggng.cjs'); | ||
| const require_objectSpread2$1 = require('./objectSpread2-Bsvh_OqM.cjs'); | ||
| const require_TRPCClientError = require('./TRPCClientError-Dey88Uiy.cjs'); | ||
| const require_TRPCClientError = require('./TRPCClientError-CQrTQLrk.cjs'); | ||
| const require_httpUtils = require('./httpUtils-CjSUiDDG.cjs'); | ||
| const require_httpLink = require('./httpLink-BkXejzP0.cjs'); | ||
| const require_httpBatchLink = require('./httpBatchLink-B7er-zFa.cjs'); | ||
| const require_httpLink = require('./httpLink-ldcEDSeb.cjs'); | ||
| const require_httpBatchLink = require('./httpBatchLink-cNDaD5bT.cjs'); | ||
| const require_unstable_internals = require('./unstable-internals-M84gUQCV.cjs'); | ||
| const require_loggerLink = require('./loggerLink-CuYvRzyH.cjs'); | ||
| const require_wsLink = require('./wsLink-CFFDLi4T.cjs'); | ||
| const require_wsLink = require('./wsLink-CYTFr-OS.cjs'); | ||
| const __trpc_server_observable = require_chunk.__toESM(require("@trpc/server/observable")); | ||
@@ -750,3 +750,3 @@ const __trpc_server_unstable_core_do_not_import = require_chunk.__toESM(require("@trpc/server/unstable-core-do-not-import")); | ||
| }); | ||
| return require_TRPCClientError.TRPCClientError.from({ error: transformChunk(shape) }); | ||
| return require_TRPCClientError.TRPCClientError.from({ error: transformChunk(shape) }, { cause: cause instanceof Error ? cause : void 0 }); | ||
| } | ||
@@ -753,0 +753,0 @@ (0, __trpc_server_unstable_core_do_not_import.run)(async () => { |
+7
-7
| import { TRPCConnectionState } from "./subscriptions.d-Ciljg_dH.cjs"; | ||
| import { FetchEsque, HTTPHeaders, NativeFetchEsque, Operation, OperationContext, OperationLink, OperationResultEnvelope, OperationResultObservable, OperationResultObserver, TRPCClientError, TRPCClientErrorBase, TRPCClientErrorLike, TRPCClientRuntime, TRPCFetch, TRPCLink, TRPCProcedureOptions, isFormData, isNonJsonSerializable, isOctetType, isTRPCClientError } from "./types.d-B2PuQAdV.cjs"; | ||
| import { FetchEsque, HTTPHeaders, NativeFetchEsque, Operation, OperationContext, OperationLink, OperationResultEnvelope, OperationResultObservable, OperationResultObserver, TRPCClientError, TRPCClientErrorBase, TRPCClientErrorLike, TRPCClientRuntime, TRPCFetch, TRPCLink, TRPCProcedureOptions, isFormData, isNonJsonSerializable, isOctetType, isTRPCClientError } from "./types.d-Cs0iOdcD.cjs"; | ||
| import { TransformerOptions } from "./unstable-internals.d-kWsZTlQq.cjs"; | ||
| import "./httpUtils.d-e55oH-rp.cjs"; | ||
| import { HTTPBatchLinkOptions, httpBatchLink } from "./httpBatchLink.d-CJdYzcjI.cjs"; | ||
| import { HTTPLinkOptions, httpLink } from "./httpLink.d-CYzMvM3c.cjs"; | ||
| import { LoggerLinkOptions, loggerLink } from "./loggerLink.d-3BnyPZWQ.cjs"; | ||
| import { splitLink } from "./splitLink.d-3ZZnmg7h.cjs"; | ||
| import { Encoder, TRPCWebSocketClient, UrlOptionsWithConnectionParams, WebSocketClientOptions, WebSocketLinkOptions, createWSClient, jsonEncoder, wsLink } from "./wsLink.d-DSgoRR08.cjs"; | ||
| import "./httpUtils.d-CQqkjORQ.cjs"; | ||
| import { HTTPBatchLinkOptions, httpBatchLink } from "./httpBatchLink.d-H0e7Upz2.cjs"; | ||
| import { HTTPLinkOptions, httpLink } from "./httpLink.d-BOoWOn2d.cjs"; | ||
| import { LoggerLinkOptions, loggerLink } from "./loggerLink.d-y4L2ytT2.cjs"; | ||
| import { splitLink } from "./splitLink.d-BhJriRAU.cjs"; | ||
| import { Encoder, TRPCWebSocketClient, UrlOptionsWithConnectionParams, WebSocketClientOptions, WebSocketLinkOptions, createWSClient, jsonEncoder, wsLink } from "./wsLink.d-DcIkru0s.cjs"; | ||
| import { AnyClientTypes, AnyProcedure, AnyRouter, ErrorHandlerOptions, EventSourceLike, InferrableClientTypes, ProcedureType, RouterRecord, TypeError, inferAsyncIterableYield, inferClientTypes, inferProcedureInput, inferRouterContext, inferTransformedProcedureOutput } from "@trpc/server/unstable-core-do-not-import"; | ||
@@ -11,0 +11,0 @@ import { Unsubscribable } from "@trpc/server/observable"; |
+7
-7
| import { TRPCConnectionState } from "./subscriptions.d-Dlr1nWGD.mjs"; | ||
| import { FetchEsque, HTTPHeaders, NativeFetchEsque, Operation, OperationContext, OperationLink, OperationResultEnvelope, OperationResultObservable, OperationResultObserver, TRPCClientError, TRPCClientErrorBase, TRPCClientErrorLike, TRPCClientRuntime, TRPCFetch, TRPCLink, TRPCProcedureOptions, isFormData, isNonJsonSerializable, isOctetType, isTRPCClientError } from "./types.d-CAt1zKAY.mjs"; | ||
| import { FetchEsque, HTTPHeaders, NativeFetchEsque, Operation, OperationContext, OperationLink, OperationResultEnvelope, OperationResultObservable, OperationResultObserver, TRPCClientError, TRPCClientErrorBase, TRPCClientErrorLike, TRPCClientRuntime, TRPCFetch, TRPCLink, TRPCProcedureOptions, isFormData, isNonJsonSerializable, isOctetType, isTRPCClientError } from "./types.d-CdPnK6XH.mjs"; | ||
| import { TransformerOptions } from "./unstable-internals.d-BOmV7EK1.mjs"; | ||
| import "./httpUtils.d-akze5l4u.mjs"; | ||
| import { HTTPBatchLinkOptions, httpBatchLink } from "./httpBatchLink.d-B0jS5RCU.mjs"; | ||
| import { HTTPLinkOptions, httpLink } from "./httpLink.d-BEC5B7OH.mjs"; | ||
| import { LoggerLinkOptions, loggerLink } from "./loggerLink.d-B_ylo7O3.mjs"; | ||
| import { splitLink } from "./splitLink.d-Df2gT0RV.mjs"; | ||
| import { Encoder, TRPCWebSocketClient, UrlOptionsWithConnectionParams, WebSocketClientOptions, WebSocketLinkOptions, createWSClient, jsonEncoder, wsLink } from "./wsLink.d-CDi0tYE2.mjs"; | ||
| import "./httpUtils.d-Cz21EQQV.mjs"; | ||
| import { HTTPBatchLinkOptions, httpBatchLink } from "./httpBatchLink.d-k3ADoD20.mjs"; | ||
| import { HTTPLinkOptions, httpLink } from "./httpLink.d-BbSanXCY.mjs"; | ||
| import { LoggerLinkOptions, loggerLink } from "./loggerLink.d-BaScF_VD.mjs"; | ||
| import { splitLink } from "./splitLink.d-W7NPZOyY.mjs"; | ||
| import { Encoder, TRPCWebSocketClient, UrlOptionsWithConnectionParams, WebSocketClientOptions, WebSocketLinkOptions, createWSClient, jsonEncoder, wsLink } from "./wsLink.d-CwxAK-4Z.mjs"; | ||
| import { Unsubscribable } from "@trpc/server/observable"; | ||
@@ -11,0 +11,0 @@ import { AnyClientTypes, AnyProcedure, AnyRouter, ErrorHandlerOptions, EventSourceLike, InferrableClientTypes, ProcedureType, RouterRecord, TypeError, inferAsyncIterableYield, inferClientTypes, inferProcedureInput, inferRouterContext, inferTransformedProcedureOutput } from "@trpc/server/unstable-core-do-not-import"; |
+5
-5
| import { __commonJS, __toESM, require_defineProperty, require_objectSpread2 } from "./objectSpread2-BvkFp-_Y.mjs"; | ||
| import { createChain, splitLink } from "./splitLink-B7Cuf2c_.mjs"; | ||
| import { TRPCClientError, isTRPCClientError } from "./TRPCClientError-CjKyS10w.mjs"; | ||
| import { TRPCClientError, isTRPCClientError } from "./TRPCClientError-apv8gw59.mjs"; | ||
| import { fetchHTTPResponse, getBody, getFetch, getUrl, resolveHTTPLinkOptions } from "./httpUtils-Dv57hbOd.mjs"; | ||
| import { httpLink, isFormData, isNonJsonSerializable, isOctetType } from "./httpLink-DCFpUmZF.mjs"; | ||
| import { abortSignalToPromise, allAbortSignals, dataLoader, httpBatchLink, raceAbortSignals } from "./httpBatchLink-BOe5aCcR.mjs"; | ||
| import { httpLink, isFormData, isNonJsonSerializable, isOctetType } from "./httpLink-Cz9h1Qgh.mjs"; | ||
| import { abortSignalToPromise, allAbortSignals, dataLoader, httpBatchLink, raceAbortSignals } from "./httpBatchLink-fQ1NAi-e.mjs"; | ||
| import { getTransformer } from "./unstable-internals-Bg7n9BBj.mjs"; | ||
| import { loggerLink } from "./loggerLink-ineCN1PO.mjs"; | ||
| import { createWSClient, jsonEncoder, resultOf, wsLink } from "./wsLink-DVm7B-YP.mjs"; | ||
| import { createWSClient, jsonEncoder, resultOf, wsLink } from "./wsLink-Cq6tvTu7.mjs"; | ||
| import { behaviorSubject, observable, observableToPromise, share } from "@trpc/server/observable"; | ||
@@ -749,3 +749,3 @@ import { callProcedure, createFlatProxy, createRecursiveProxy, isAbortError, isAsyncIterable, iteratorResource, jsonlStreamConsumer, makeResource, retryableRpcCodes, run, sseStreamConsumer } from "@trpc/server/unstable-core-do-not-import"; | ||
| }); | ||
| return TRPCClientError.from({ error: transformChunk(shape) }); | ||
| return TRPCClientError.from({ error: transformChunk(shape) }, { cause: cause instanceof Error ? cause : void 0 }); | ||
| } | ||
@@ -752,0 +752,0 @@ run(async () => { |
| require('../objectSpread2-Bsvh_OqM.cjs'); | ||
| require('../TRPCClientError-Dey88Uiy.cjs'); | ||
| require('../TRPCClientError-CQrTQLrk.cjs'); | ||
| require('../httpUtils-CjSUiDDG.cjs'); | ||
| const require_httpBatchLink = require('../httpBatchLink-B7er-zFa.cjs'); | ||
| const require_httpBatchLink = require('../httpBatchLink-cNDaD5bT.cjs'); | ||
| require('../unstable-internals-M84gUQCV.cjs'); | ||
| exports.httpBatchLink = require_httpBatchLink.httpBatchLink; |
| import "../subscriptions.d-Ciljg_dH.cjs"; | ||
| import "../types.d-B2PuQAdV.cjs"; | ||
| import "../types.d-Cs0iOdcD.cjs"; | ||
| import "../unstable-internals.d-kWsZTlQq.cjs"; | ||
| import "../httpUtils.d-e55oH-rp.cjs"; | ||
| import { httpBatchLink } from "../httpBatchLink.d-CJdYzcjI.cjs"; | ||
| import "../httpUtils.d-CQqkjORQ.cjs"; | ||
| import { httpBatchLink } from "../httpBatchLink.d-H0e7Upz2.cjs"; | ||
| export { httpBatchLink }; |
| import "../subscriptions.d-Dlr1nWGD.mjs"; | ||
| import "../types.d-CAt1zKAY.mjs"; | ||
| import "../types.d-CdPnK6XH.mjs"; | ||
| import "../unstable-internals.d-BOmV7EK1.mjs"; | ||
| import "../httpUtils.d-akze5l4u.mjs"; | ||
| import { httpBatchLink } from "../httpBatchLink.d-B0jS5RCU.mjs"; | ||
| import "../httpUtils.d-Cz21EQQV.mjs"; | ||
| import { httpBatchLink } from "../httpBatchLink.d-k3ADoD20.mjs"; | ||
| export { httpBatchLink }; |
| import "../objectSpread2-BvkFp-_Y.mjs"; | ||
| import "../TRPCClientError-CjKyS10w.mjs"; | ||
| import "../TRPCClientError-apv8gw59.mjs"; | ||
| import "../httpUtils-Dv57hbOd.mjs"; | ||
| import { httpBatchLink } from "../httpBatchLink-BOe5aCcR.mjs"; | ||
| import { httpBatchLink } from "../httpBatchLink-fQ1NAi-e.mjs"; | ||
| import "../unstable-internals-Bg7n9BBj.mjs"; | ||
| export { httpBatchLink }; |
| require('../objectSpread2-Bsvh_OqM.cjs'); | ||
| require('../TRPCClientError-Dey88Uiy.cjs'); | ||
| require('../TRPCClientError-CQrTQLrk.cjs'); | ||
| require('../httpUtils-CjSUiDDG.cjs'); | ||
| const require_httpLink = require('../httpLink-BkXejzP0.cjs'); | ||
| const require_httpLink = require('../httpLink-ldcEDSeb.cjs'); | ||
| require('../unstable-internals-M84gUQCV.cjs'); | ||
| exports.httpLink = require_httpLink.httpLink; |
| import "../subscriptions.d-Ciljg_dH.cjs"; | ||
| import "../types.d-B2PuQAdV.cjs"; | ||
| import "../types.d-Cs0iOdcD.cjs"; | ||
| import "../unstable-internals.d-kWsZTlQq.cjs"; | ||
| import "../httpUtils.d-e55oH-rp.cjs"; | ||
| import { HTTPLinkOptions, httpLink } from "../httpLink.d-CYzMvM3c.cjs"; | ||
| import "../httpUtils.d-CQqkjORQ.cjs"; | ||
| import { HTTPLinkOptions, httpLink } from "../httpLink.d-BOoWOn2d.cjs"; | ||
| export { HTTPLinkOptions, httpLink }; |
| import "../subscriptions.d-Dlr1nWGD.mjs"; | ||
| import "../types.d-CAt1zKAY.mjs"; | ||
| import "../types.d-CdPnK6XH.mjs"; | ||
| import "../unstable-internals.d-BOmV7EK1.mjs"; | ||
| import "../httpUtils.d-akze5l4u.mjs"; | ||
| import { HTTPLinkOptions, httpLink } from "../httpLink.d-BEC5B7OH.mjs"; | ||
| import "../httpUtils.d-Cz21EQQV.mjs"; | ||
| import { HTTPLinkOptions, httpLink } from "../httpLink.d-BbSanXCY.mjs"; | ||
| export { HTTPLinkOptions, httpLink }; |
| import "../objectSpread2-BvkFp-_Y.mjs"; | ||
| import "../TRPCClientError-CjKyS10w.mjs"; | ||
| import "../TRPCClientError-apv8gw59.mjs"; | ||
| import "../httpUtils-Dv57hbOd.mjs"; | ||
| import { httpLink } from "../httpLink-DCFpUmZF.mjs"; | ||
| import { httpLink } from "../httpLink-Cz9h1Qgh.mjs"; | ||
| import "../unstable-internals-Bg7n9BBj.mjs"; | ||
| export { httpLink }; |
| import "../subscriptions.d-Ciljg_dH.cjs"; | ||
| import "../types.d-B2PuQAdV.cjs"; | ||
| import { LoggerLinkOptions, loggerLink } from "../loggerLink.d-3BnyPZWQ.cjs"; | ||
| import "../types.d-Cs0iOdcD.cjs"; | ||
| import { LoggerLinkOptions, loggerLink } from "../loggerLink.d-y4L2ytT2.cjs"; | ||
| export { LoggerLinkOptions, loggerLink }; |
| import "../subscriptions.d-Dlr1nWGD.mjs"; | ||
| import "../types.d-CAt1zKAY.mjs"; | ||
| import { LoggerLinkOptions, loggerLink } from "../loggerLink.d-B_ylo7O3.mjs"; | ||
| import "../types.d-CdPnK6XH.mjs"; | ||
| import { LoggerLinkOptions, loggerLink } from "../loggerLink.d-BaScF_VD.mjs"; | ||
| export { LoggerLinkOptions, loggerLink }; |
| import "../subscriptions.d-Ciljg_dH.cjs"; | ||
| import "../types.d-B2PuQAdV.cjs"; | ||
| import { splitLink } from "../splitLink.d-3ZZnmg7h.cjs"; | ||
| import "../types.d-Cs0iOdcD.cjs"; | ||
| import { splitLink } from "../splitLink.d-BhJriRAU.cjs"; | ||
| export { splitLink }; |
| import "../subscriptions.d-Dlr1nWGD.mjs"; | ||
| import "../types.d-CAt1zKAY.mjs"; | ||
| import { splitLink } from "../splitLink.d-Df2gT0RV.mjs"; | ||
| import "../types.d-CdPnK6XH.mjs"; | ||
| import { splitLink } from "../splitLink.d-W7NPZOyY.mjs"; | ||
| export { splitLink }; |
| require('../../objectSpread2-Bsvh_OqM.cjs'); | ||
| require('../../TRPCClientError-Dey88Uiy.cjs'); | ||
| require('../../TRPCClientError-CQrTQLrk.cjs'); | ||
| require('../../unstable-internals-M84gUQCV.cjs'); | ||
| const require_wsLink = require('../../wsLink-CFFDLi4T.cjs'); | ||
| const require_wsLink = require('../../wsLink-CYTFr-OS.cjs'); | ||
@@ -6,0 +6,0 @@ exports.createWSClient = require_wsLink.createWSClient; |
| import "../../subscriptions.d-Ciljg_dH.cjs"; | ||
| import "../../types.d-B2PuQAdV.cjs"; | ||
| import "../../types.d-Cs0iOdcD.cjs"; | ||
| import "../../unstable-internals.d-kWsZTlQq.cjs"; | ||
| import { Encoder, TRPCWebSocketClient, WebSocketClientOptions, WebSocketLinkOptions, createWSClient, jsonEncoder, wsLink } from "../../wsLink.d-DSgoRR08.cjs"; | ||
| import { Encoder, TRPCWebSocketClient, WebSocketClientOptions, WebSocketLinkOptions, createWSClient, jsonEncoder, wsLink } from "../../wsLink.d-DcIkru0s.cjs"; | ||
| export { Encoder, TRPCWebSocketClient, WebSocketClientOptions, WebSocketLinkOptions, createWSClient, jsonEncoder, wsLink }; |
| import "../../subscriptions.d-Dlr1nWGD.mjs"; | ||
| import "../../types.d-CAt1zKAY.mjs"; | ||
| import "../../types.d-CdPnK6XH.mjs"; | ||
| import "../../unstable-internals.d-BOmV7EK1.mjs"; | ||
| import { Encoder, TRPCWebSocketClient, WebSocketClientOptions, WebSocketLinkOptions, createWSClient, jsonEncoder, wsLink } from "../../wsLink.d-CDi0tYE2.mjs"; | ||
| import { Encoder, TRPCWebSocketClient, WebSocketClientOptions, WebSocketLinkOptions, createWSClient, jsonEncoder, wsLink } from "../../wsLink.d-CwxAK-4Z.mjs"; | ||
| export { Encoder, TRPCWebSocketClient, WebSocketClientOptions, WebSocketLinkOptions, createWSClient, jsonEncoder, wsLink }; |
| import "../../objectSpread2-BvkFp-_Y.mjs"; | ||
| import "../../TRPCClientError-CjKyS10w.mjs"; | ||
| import "../../TRPCClientError-apv8gw59.mjs"; | ||
| import "../../unstable-internals-Bg7n9BBj.mjs"; | ||
| import { createWSClient, jsonEncoder, wsLink } from "../../wsLink-DVm7B-YP.mjs"; | ||
| import { createWSClient, jsonEncoder, wsLink } from "../../wsLink-Cq6tvTu7.mjs"; | ||
| export { createWSClient, jsonEncoder, wsLink }; |
+4
-4
| { | ||
| "name": "@trpc/client", | ||
| "type": "module", | ||
| "version": "11.9.0", | ||
| "version": "11.9.1-canary.8+9d4b3b975", | ||
| "description": "The tRPC client library", | ||
@@ -115,7 +115,7 @@ "author": "KATT", | ||
| "peerDependencies": { | ||
| "@trpc/server": "11.9.0", | ||
| "@trpc/server": "11.9.1-canary.8+9d4b3b975", | ||
| "typescript": ">=5.7.2" | ||
| }, | ||
| "devDependencies": { | ||
| "@trpc/server": "11.9.0", | ||
| "@trpc/server": "11.9.1-canary.8+9d4b3b975", | ||
| "@types/isomorphic-fetch": "^0.0.39", | ||
@@ -139,3 +139,3 @@ "@types/node": "^22.13.5", | ||
| ], | ||
| "gitHead": "3beb5067de117bad47fcbd8ce4fbcd73817e872a" | ||
| "gitHead": "9d4b3b975197890a71cac20a7a0836ef349c087b" | ||
| } |
@@ -115,5 +115,6 @@ import { | ||
| }); | ||
| return TRPCClientError.from({ | ||
| error: transformChunk(shape), | ||
| }); | ||
| return TRPCClientError.from( | ||
| { error: transformChunk(shape) }, | ||
| { cause: cause instanceof Error ? cause : undefined }, | ||
| ); | ||
| } | ||
@@ -120,0 +121,0 @@ |
@@ -89,3 +89,3 @@ import type { | ||
| _cause: Error | TRPCErrorResponse<any> | object, | ||
| opts: { meta?: Record<string, unknown> } = {}, | ||
| opts: { meta?: Record<string, unknown>; cause?: Error } = {}, | ||
| ): TRPCClientError<TRouterOrProcedure> { | ||
@@ -108,2 +108,3 @@ const cause = _cause as unknown; | ||
| result: cause, | ||
| cause: opts.cause, | ||
| }); | ||
@@ -110,0 +111,0 @@ } |
| const require_chunk = require('./chunk-DWy1uDak.cjs'); | ||
| const require_objectSpread2$1 = require('./objectSpread2-Bsvh_OqM.cjs'); | ||
| const require_TRPCClientError = require('./TRPCClientError-Dey88Uiy.cjs'); | ||
| const require_httpUtils = require('./httpUtils-CjSUiDDG.cjs'); | ||
| const __trpc_server_observable = require_chunk.__toESM(require("@trpc/server/observable")); | ||
| const __trpc_server_unstable_core_do_not_import = require_chunk.__toESM(require("@trpc/server/unstable-core-do-not-import")); | ||
| //#region src/internals/dataLoader.ts | ||
| /** | ||
| * A function that should never be called unless we messed something up. | ||
| */ | ||
| const throwFatalError = () => { | ||
| throw new Error("Something went wrong. Please submit an issue at https://github.com/trpc/trpc/issues/new"); | ||
| }; | ||
| /** | ||
| * Dataloader that's very inspired by https://github.com/graphql/dataloader | ||
| * Less configuration, no caching, and allows you to cancel requests | ||
| * When cancelling a single fetch the whole batch will be cancelled only when _all_ items are cancelled | ||
| */ | ||
| function dataLoader(batchLoader) { | ||
| let pendingItems = null; | ||
| let dispatchTimer = null; | ||
| const destroyTimerAndPendingItems = () => { | ||
| clearTimeout(dispatchTimer); | ||
| dispatchTimer = null; | ||
| pendingItems = null; | ||
| }; | ||
| /** | ||
| * Iterate through the items and split them into groups based on the `batchLoader`'s validate function | ||
| */ | ||
| function groupItems(items) { | ||
| const groupedItems = [[]]; | ||
| let index = 0; | ||
| while (true) { | ||
| const item = items[index]; | ||
| if (!item) break; | ||
| const lastGroup = groupedItems[groupedItems.length - 1]; | ||
| if (item.aborted) { | ||
| var _item$reject; | ||
| (_item$reject = item.reject) === null || _item$reject === void 0 || _item$reject.call(item, new Error("Aborted")); | ||
| index++; | ||
| continue; | ||
| } | ||
| const isValid = batchLoader.validate(lastGroup.concat(item).map((it) => it.key)); | ||
| if (isValid) { | ||
| lastGroup.push(item); | ||
| index++; | ||
| continue; | ||
| } | ||
| if (lastGroup.length === 0) { | ||
| var _item$reject2; | ||
| (_item$reject2 = item.reject) === null || _item$reject2 === void 0 || _item$reject2.call(item, new Error("Input is too big for a single dispatch")); | ||
| index++; | ||
| continue; | ||
| } | ||
| groupedItems.push([]); | ||
| } | ||
| return groupedItems; | ||
| } | ||
| function dispatch() { | ||
| const groupedItems = groupItems(pendingItems); | ||
| destroyTimerAndPendingItems(); | ||
| for (const items of groupedItems) { | ||
| if (!items.length) continue; | ||
| const batch = { items }; | ||
| for (const item of items) item.batch = batch; | ||
| const promise = batchLoader.fetch(batch.items.map((_item) => _item.key)); | ||
| promise.then(async (result) => { | ||
| await Promise.all(result.map(async (valueOrPromise, index) => { | ||
| const item = batch.items[index]; | ||
| try { | ||
| var _item$resolve; | ||
| const value = await Promise.resolve(valueOrPromise); | ||
| (_item$resolve = item.resolve) === null || _item$resolve === void 0 || _item$resolve.call(item, value); | ||
| } catch (cause) { | ||
| var _item$reject3; | ||
| (_item$reject3 = item.reject) === null || _item$reject3 === void 0 || _item$reject3.call(item, cause); | ||
| } | ||
| item.batch = null; | ||
| item.reject = null; | ||
| item.resolve = null; | ||
| })); | ||
| for (const item of batch.items) { | ||
| var _item$reject4; | ||
| (_item$reject4 = item.reject) === null || _item$reject4 === void 0 || _item$reject4.call(item, new Error("Missing result")); | ||
| item.batch = null; | ||
| } | ||
| }).catch((cause) => { | ||
| for (const item of batch.items) { | ||
| var _item$reject5; | ||
| (_item$reject5 = item.reject) === null || _item$reject5 === void 0 || _item$reject5.call(item, cause); | ||
| item.batch = null; | ||
| } | ||
| }); | ||
| } | ||
| } | ||
| function load(key) { | ||
| var _dispatchTimer; | ||
| const item = { | ||
| aborted: false, | ||
| key, | ||
| batch: null, | ||
| resolve: throwFatalError, | ||
| reject: throwFatalError | ||
| }; | ||
| const promise = new Promise((resolve, reject) => { | ||
| var _pendingItems; | ||
| item.reject = reject; | ||
| item.resolve = resolve; | ||
| (_pendingItems = pendingItems) !== null && _pendingItems !== void 0 || (pendingItems = []); | ||
| pendingItems.push(item); | ||
| }); | ||
| (_dispatchTimer = dispatchTimer) !== null && _dispatchTimer !== void 0 || (dispatchTimer = setTimeout(dispatch)); | ||
| return promise; | ||
| } | ||
| return { load }; | ||
| } | ||
| //#endregion | ||
| //#region src/internals/signals.ts | ||
| /** | ||
| * Like `Promise.all()` but for abort signals | ||
| * - When all signals have been aborted, the merged signal will be aborted | ||
| * - If one signal is `null`, no signal will be aborted | ||
| */ | ||
| function allAbortSignals(...signals) { | ||
| const ac = new AbortController(); | ||
| const count = signals.length; | ||
| let abortedCount = 0; | ||
| const onAbort = () => { | ||
| if (++abortedCount === count) ac.abort(); | ||
| }; | ||
| for (const signal of signals) if (signal === null || signal === void 0 ? void 0 : signal.aborted) onAbort(); | ||
| else signal === null || signal === void 0 || signal.addEventListener("abort", onAbort, { once: true }); | ||
| return ac.signal; | ||
| } | ||
| /** | ||
| * Like `Promise.race` but for abort signals | ||
| * | ||
| * Basically, a ponyfill for | ||
| * [`AbortSignal.any`](https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal/any_static). | ||
| */ | ||
| function raceAbortSignals(...signals) { | ||
| const ac = new AbortController(); | ||
| for (const signal of signals) if (signal === null || signal === void 0 ? void 0 : signal.aborted) ac.abort(); | ||
| else signal === null || signal === void 0 || signal.addEventListener("abort", () => ac.abort(), { once: true }); | ||
| return ac.signal; | ||
| } | ||
| function abortSignalToPromise(signal) { | ||
| return new Promise((_, reject) => { | ||
| if (signal.aborted) { | ||
| reject(signal.reason); | ||
| return; | ||
| } | ||
| signal.addEventListener("abort", () => { | ||
| reject(signal.reason); | ||
| }, { once: true }); | ||
| }); | ||
| } | ||
| //#endregion | ||
| //#region src/links/httpBatchLink.ts | ||
| var import_objectSpread2 = require_chunk.__toESM(require_objectSpread2$1.require_objectSpread2(), 1); | ||
| /** | ||
| * @see https://trpc.io/docs/client/links/httpBatchLink | ||
| */ | ||
| function httpBatchLink(opts) { | ||
| var _opts$maxURLLength, _opts$maxItems; | ||
| const resolvedOpts = require_httpUtils.resolveHTTPLinkOptions(opts); | ||
| const maxURLLength = (_opts$maxURLLength = opts.maxURLLength) !== null && _opts$maxURLLength !== void 0 ? _opts$maxURLLength : Infinity; | ||
| const maxItems = (_opts$maxItems = opts.maxItems) !== null && _opts$maxItems !== void 0 ? _opts$maxItems : Infinity; | ||
| return () => { | ||
| const batchLoader = (type) => { | ||
| return { | ||
| validate(batchOps) { | ||
| if (maxURLLength === Infinity && maxItems === Infinity) return true; | ||
| if (batchOps.length > maxItems) return false; | ||
| const path = batchOps.map((op) => op.path).join(","); | ||
| const inputs = batchOps.map((op) => op.input); | ||
| const url = require_httpUtils.getUrl((0, import_objectSpread2.default)((0, import_objectSpread2.default)({}, resolvedOpts), {}, { | ||
| type, | ||
| path, | ||
| inputs, | ||
| signal: null | ||
| })); | ||
| return url.length <= maxURLLength; | ||
| }, | ||
| async fetch(batchOps) { | ||
| const path = batchOps.map((op) => op.path).join(","); | ||
| const inputs = batchOps.map((op) => op.input); | ||
| const signal = allAbortSignals(...batchOps.map((op) => op.signal)); | ||
| const res = await require_httpUtils.jsonHttpRequester((0, import_objectSpread2.default)((0, import_objectSpread2.default)({}, resolvedOpts), {}, { | ||
| path, | ||
| inputs, | ||
| type, | ||
| headers() { | ||
| if (!opts.headers) return {}; | ||
| if (typeof opts.headers === "function") return opts.headers({ opList: batchOps }); | ||
| return opts.headers; | ||
| }, | ||
| signal | ||
| })); | ||
| const resJSON = Array.isArray(res.json) ? res.json : batchOps.map(() => res.json); | ||
| const result = resJSON.map((item) => ({ | ||
| meta: res.meta, | ||
| json: item | ||
| })); | ||
| return result; | ||
| } | ||
| }; | ||
| }; | ||
| const query = dataLoader(batchLoader("query")); | ||
| const mutation = dataLoader(batchLoader("mutation")); | ||
| const loaders = { | ||
| query, | ||
| mutation | ||
| }; | ||
| return ({ op }) => { | ||
| return (0, __trpc_server_observable.observable)((observer) => { | ||
| /* istanbul ignore if -- @preserve */ | ||
| if (op.type === "subscription") throw new Error("Subscriptions are unsupported by `httpLink` - use `httpSubscriptionLink` or `wsLink`"); | ||
| const loader = loaders[op.type]; | ||
| const promise = loader.load(op); | ||
| let _res = void 0; | ||
| promise.then((res) => { | ||
| _res = res; | ||
| const transformed = (0, __trpc_server_unstable_core_do_not_import.transformResult)(res.json, resolvedOpts.transformer.output); | ||
| if (!transformed.ok) { | ||
| observer.error(require_TRPCClientError.TRPCClientError.from(transformed.error, { meta: res.meta })); | ||
| return; | ||
| } | ||
| observer.next({ | ||
| context: res.meta, | ||
| result: transformed.result | ||
| }); | ||
| observer.complete(); | ||
| }).catch((err) => { | ||
| observer.error(require_TRPCClientError.TRPCClientError.from(err, { meta: _res === null || _res === void 0 ? void 0 : _res.meta })); | ||
| }); | ||
| return () => {}; | ||
| }); | ||
| }; | ||
| }; | ||
| } | ||
| //#endregion | ||
| Object.defineProperty(exports, 'abortSignalToPromise', { | ||
| enumerable: true, | ||
| get: function () { | ||
| return abortSignalToPromise; | ||
| } | ||
| }); | ||
| Object.defineProperty(exports, 'allAbortSignals', { | ||
| enumerable: true, | ||
| get: function () { | ||
| return allAbortSignals; | ||
| } | ||
| }); | ||
| Object.defineProperty(exports, 'dataLoader', { | ||
| enumerable: true, | ||
| get: function () { | ||
| return dataLoader; | ||
| } | ||
| }); | ||
| Object.defineProperty(exports, 'httpBatchLink', { | ||
| enumerable: true, | ||
| get: function () { | ||
| return httpBatchLink; | ||
| } | ||
| }); | ||
| Object.defineProperty(exports, 'raceAbortSignals', { | ||
| enumerable: true, | ||
| get: function () { | ||
| return raceAbortSignals; | ||
| } | ||
| }); |
| import { __toESM, require_objectSpread2 } from "./objectSpread2-BvkFp-_Y.mjs"; | ||
| import { TRPCClientError } from "./TRPCClientError-CjKyS10w.mjs"; | ||
| import { getUrl, jsonHttpRequester, resolveHTTPLinkOptions } from "./httpUtils-Dv57hbOd.mjs"; | ||
| import { observable } from "@trpc/server/observable"; | ||
| import { transformResult } from "@trpc/server/unstable-core-do-not-import"; | ||
| //#region src/internals/dataLoader.ts | ||
| /** | ||
| * A function that should never be called unless we messed something up. | ||
| */ | ||
| const throwFatalError = () => { | ||
| throw new Error("Something went wrong. Please submit an issue at https://github.com/trpc/trpc/issues/new"); | ||
| }; | ||
| /** | ||
| * Dataloader that's very inspired by https://github.com/graphql/dataloader | ||
| * Less configuration, no caching, and allows you to cancel requests | ||
| * When cancelling a single fetch the whole batch will be cancelled only when _all_ items are cancelled | ||
| */ | ||
| function dataLoader(batchLoader) { | ||
| let pendingItems = null; | ||
| let dispatchTimer = null; | ||
| const destroyTimerAndPendingItems = () => { | ||
| clearTimeout(dispatchTimer); | ||
| dispatchTimer = null; | ||
| pendingItems = null; | ||
| }; | ||
| /** | ||
| * Iterate through the items and split them into groups based on the `batchLoader`'s validate function | ||
| */ | ||
| function groupItems(items) { | ||
| const groupedItems = [[]]; | ||
| let index = 0; | ||
| while (true) { | ||
| const item = items[index]; | ||
| if (!item) break; | ||
| const lastGroup = groupedItems[groupedItems.length - 1]; | ||
| if (item.aborted) { | ||
| var _item$reject; | ||
| (_item$reject = item.reject) === null || _item$reject === void 0 || _item$reject.call(item, new Error("Aborted")); | ||
| index++; | ||
| continue; | ||
| } | ||
| const isValid = batchLoader.validate(lastGroup.concat(item).map((it) => it.key)); | ||
| if (isValid) { | ||
| lastGroup.push(item); | ||
| index++; | ||
| continue; | ||
| } | ||
| if (lastGroup.length === 0) { | ||
| var _item$reject2; | ||
| (_item$reject2 = item.reject) === null || _item$reject2 === void 0 || _item$reject2.call(item, new Error("Input is too big for a single dispatch")); | ||
| index++; | ||
| continue; | ||
| } | ||
| groupedItems.push([]); | ||
| } | ||
| return groupedItems; | ||
| } | ||
| function dispatch() { | ||
| const groupedItems = groupItems(pendingItems); | ||
| destroyTimerAndPendingItems(); | ||
| for (const items of groupedItems) { | ||
| if (!items.length) continue; | ||
| const batch = { items }; | ||
| for (const item of items) item.batch = batch; | ||
| const promise = batchLoader.fetch(batch.items.map((_item) => _item.key)); | ||
| promise.then(async (result) => { | ||
| await Promise.all(result.map(async (valueOrPromise, index) => { | ||
| const item = batch.items[index]; | ||
| try { | ||
| var _item$resolve; | ||
| const value = await Promise.resolve(valueOrPromise); | ||
| (_item$resolve = item.resolve) === null || _item$resolve === void 0 || _item$resolve.call(item, value); | ||
| } catch (cause) { | ||
| var _item$reject3; | ||
| (_item$reject3 = item.reject) === null || _item$reject3 === void 0 || _item$reject3.call(item, cause); | ||
| } | ||
| item.batch = null; | ||
| item.reject = null; | ||
| item.resolve = null; | ||
| })); | ||
| for (const item of batch.items) { | ||
| var _item$reject4; | ||
| (_item$reject4 = item.reject) === null || _item$reject4 === void 0 || _item$reject4.call(item, new Error("Missing result")); | ||
| item.batch = null; | ||
| } | ||
| }).catch((cause) => { | ||
| for (const item of batch.items) { | ||
| var _item$reject5; | ||
| (_item$reject5 = item.reject) === null || _item$reject5 === void 0 || _item$reject5.call(item, cause); | ||
| item.batch = null; | ||
| } | ||
| }); | ||
| } | ||
| } | ||
| function load(key) { | ||
| var _dispatchTimer; | ||
| const item = { | ||
| aborted: false, | ||
| key, | ||
| batch: null, | ||
| resolve: throwFatalError, | ||
| reject: throwFatalError | ||
| }; | ||
| const promise = new Promise((resolve, reject) => { | ||
| var _pendingItems; | ||
| item.reject = reject; | ||
| item.resolve = resolve; | ||
| (_pendingItems = pendingItems) !== null && _pendingItems !== void 0 || (pendingItems = []); | ||
| pendingItems.push(item); | ||
| }); | ||
| (_dispatchTimer = dispatchTimer) !== null && _dispatchTimer !== void 0 || (dispatchTimer = setTimeout(dispatch)); | ||
| return promise; | ||
| } | ||
| return { load }; | ||
| } | ||
| //#endregion | ||
| //#region src/internals/signals.ts | ||
| /** | ||
| * Like `Promise.all()` but for abort signals | ||
| * - When all signals have been aborted, the merged signal will be aborted | ||
| * - If one signal is `null`, no signal will be aborted | ||
| */ | ||
| function allAbortSignals(...signals) { | ||
| const ac = new AbortController(); | ||
| const count = signals.length; | ||
| let abortedCount = 0; | ||
| const onAbort = () => { | ||
| if (++abortedCount === count) ac.abort(); | ||
| }; | ||
| for (const signal of signals) if (signal === null || signal === void 0 ? void 0 : signal.aborted) onAbort(); | ||
| else signal === null || signal === void 0 || signal.addEventListener("abort", onAbort, { once: true }); | ||
| return ac.signal; | ||
| } | ||
| /** | ||
| * Like `Promise.race` but for abort signals | ||
| * | ||
| * Basically, a ponyfill for | ||
| * [`AbortSignal.any`](https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal/any_static). | ||
| */ | ||
| function raceAbortSignals(...signals) { | ||
| const ac = new AbortController(); | ||
| for (const signal of signals) if (signal === null || signal === void 0 ? void 0 : signal.aborted) ac.abort(); | ||
| else signal === null || signal === void 0 || signal.addEventListener("abort", () => ac.abort(), { once: true }); | ||
| return ac.signal; | ||
| } | ||
| function abortSignalToPromise(signal) { | ||
| return new Promise((_, reject) => { | ||
| if (signal.aborted) { | ||
| reject(signal.reason); | ||
| return; | ||
| } | ||
| signal.addEventListener("abort", () => { | ||
| reject(signal.reason); | ||
| }, { once: true }); | ||
| }); | ||
| } | ||
| //#endregion | ||
| //#region src/links/httpBatchLink.ts | ||
| var import_objectSpread2 = __toESM(require_objectSpread2(), 1); | ||
| /** | ||
| * @see https://trpc.io/docs/client/links/httpBatchLink | ||
| */ | ||
| function httpBatchLink(opts) { | ||
| var _opts$maxURLLength, _opts$maxItems; | ||
| const resolvedOpts = resolveHTTPLinkOptions(opts); | ||
| const maxURLLength = (_opts$maxURLLength = opts.maxURLLength) !== null && _opts$maxURLLength !== void 0 ? _opts$maxURLLength : Infinity; | ||
| const maxItems = (_opts$maxItems = opts.maxItems) !== null && _opts$maxItems !== void 0 ? _opts$maxItems : Infinity; | ||
| return () => { | ||
| const batchLoader = (type) => { | ||
| return { | ||
| validate(batchOps) { | ||
| if (maxURLLength === Infinity && maxItems === Infinity) return true; | ||
| if (batchOps.length > maxItems) return false; | ||
| const path = batchOps.map((op) => op.path).join(","); | ||
| const inputs = batchOps.map((op) => op.input); | ||
| const url = getUrl((0, import_objectSpread2.default)((0, import_objectSpread2.default)({}, resolvedOpts), {}, { | ||
| type, | ||
| path, | ||
| inputs, | ||
| signal: null | ||
| })); | ||
| return url.length <= maxURLLength; | ||
| }, | ||
| async fetch(batchOps) { | ||
| const path = batchOps.map((op) => op.path).join(","); | ||
| const inputs = batchOps.map((op) => op.input); | ||
| const signal = allAbortSignals(...batchOps.map((op) => op.signal)); | ||
| const res = await jsonHttpRequester((0, import_objectSpread2.default)((0, import_objectSpread2.default)({}, resolvedOpts), {}, { | ||
| path, | ||
| inputs, | ||
| type, | ||
| headers() { | ||
| if (!opts.headers) return {}; | ||
| if (typeof opts.headers === "function") return opts.headers({ opList: batchOps }); | ||
| return opts.headers; | ||
| }, | ||
| signal | ||
| })); | ||
| const resJSON = Array.isArray(res.json) ? res.json : batchOps.map(() => res.json); | ||
| const result = resJSON.map((item) => ({ | ||
| meta: res.meta, | ||
| json: item | ||
| })); | ||
| return result; | ||
| } | ||
| }; | ||
| }; | ||
| const query = dataLoader(batchLoader("query")); | ||
| const mutation = dataLoader(batchLoader("mutation")); | ||
| const loaders = { | ||
| query, | ||
| mutation | ||
| }; | ||
| return ({ op }) => { | ||
| return observable((observer) => { | ||
| /* istanbul ignore if -- @preserve */ | ||
| if (op.type === "subscription") throw new Error("Subscriptions are unsupported by `httpLink` - use `httpSubscriptionLink` or `wsLink`"); | ||
| const loader = loaders[op.type]; | ||
| const promise = loader.load(op); | ||
| let _res = void 0; | ||
| promise.then((res) => { | ||
| _res = res; | ||
| const transformed = transformResult(res.json, resolvedOpts.transformer.output); | ||
| if (!transformed.ok) { | ||
| observer.error(TRPCClientError.from(transformed.error, { meta: res.meta })); | ||
| return; | ||
| } | ||
| observer.next({ | ||
| context: res.meta, | ||
| result: transformed.result | ||
| }); | ||
| observer.complete(); | ||
| }).catch((err) => { | ||
| observer.error(TRPCClientError.from(err, { meta: _res === null || _res === void 0 ? void 0 : _res.meta })); | ||
| }); | ||
| return () => {}; | ||
| }); | ||
| }; | ||
| }; | ||
| } | ||
| //#endregion | ||
| export { abortSignalToPromise, allAbortSignals, dataLoader, httpBatchLink, raceAbortSignals }; | ||
| //# sourceMappingURL=httpBatchLink-BOe5aCcR.mjs.map |
| {"version":3,"file":"httpBatchLink-BOe5aCcR.mjs","names":["batchLoader: BatchLoader<TKey, TValue>","pendingItems: BatchItem<TKey, TValue>[] | null","dispatchTimer: ReturnType<typeof setTimeout> | null","items: BatchItem<TKey, TValue>[]","groupedItems: BatchItem<TKey, TValue>[][]","batch: Batch<TKey, TValue>","key: TKey","item: BatchItem<TKey, TValue>","signal: AbortSignal","opts: HTTPBatchLinkOptions<TRouter['_def']['_config']['$types']>","type: ProcedureType"],"sources":["../src/internals/dataLoader.ts","../src/internals/signals.ts","../src/links/httpBatchLink.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-non-null-assertion */\n\ntype BatchItem<TKey, TValue> = {\n aborted: boolean;\n key: TKey;\n resolve: ((value: TValue) => void) | null;\n reject: ((error: Error) => void) | null;\n batch: Batch<TKey, TValue> | null;\n};\ntype Batch<TKey, TValue> = {\n items: BatchItem<TKey, TValue>[];\n};\nexport type BatchLoader<TKey, TValue> = {\n validate: (keys: TKey[]) => boolean;\n fetch: (keys: TKey[]) => Promise<TValue[] | Promise<TValue>[]>;\n};\n\n/**\n * A function that should never be called unless we messed something up.\n */\nconst throwFatalError = () => {\n throw new Error(\n 'Something went wrong. Please submit an issue at https://github.com/trpc/trpc/issues/new',\n );\n};\n\n/**\n * Dataloader that's very inspired by https://github.com/graphql/dataloader\n * Less configuration, no caching, and allows you to cancel requests\n * When cancelling a single fetch the whole batch will be cancelled only when _all_ items are cancelled\n */\nexport function dataLoader<TKey, TValue>(\n batchLoader: BatchLoader<TKey, TValue>,\n) {\n let pendingItems: BatchItem<TKey, TValue>[] | null = null;\n let dispatchTimer: ReturnType<typeof setTimeout> | null = null;\n\n const destroyTimerAndPendingItems = () => {\n clearTimeout(dispatchTimer as any);\n dispatchTimer = null;\n pendingItems = null;\n };\n\n /**\n * Iterate through the items and split them into groups based on the `batchLoader`'s validate function\n */\n function groupItems(items: BatchItem<TKey, TValue>[]) {\n const groupedItems: BatchItem<TKey, TValue>[][] = [[]];\n let index = 0;\n while (true) {\n const item = items[index];\n if (!item) {\n // we're done\n break;\n }\n const lastGroup = groupedItems[groupedItems.length - 1]!;\n\n if (item.aborted) {\n // Item was aborted before it was dispatched\n item.reject?.(new Error('Aborted'));\n index++;\n continue;\n }\n\n const isValid = batchLoader.validate(\n lastGroup.concat(item).map((it) => it.key),\n );\n\n if (isValid) {\n lastGroup.push(item);\n index++;\n continue;\n }\n\n if (lastGroup.length === 0) {\n item.reject?.(new Error('Input is too big for a single dispatch'));\n index++;\n continue;\n }\n // Create new group, next iteration will try to add the item to that\n groupedItems.push([]);\n }\n return groupedItems;\n }\n\n function dispatch() {\n const groupedItems = groupItems(pendingItems!);\n destroyTimerAndPendingItems();\n\n // Create batches for each group of items\n for (const items of groupedItems) {\n if (!items.length) {\n continue;\n }\n const batch: Batch<TKey, TValue> = {\n items,\n };\n for (const item of items) {\n item.batch = batch;\n }\n const promise = batchLoader.fetch(batch.items.map((_item) => _item.key));\n\n promise\n .then(async (result) => {\n await Promise.all(\n result.map(async (valueOrPromise, index) => {\n const item = batch.items[index]!;\n try {\n const value = await Promise.resolve(valueOrPromise);\n\n item.resolve?.(value);\n } catch (cause) {\n item.reject?.(cause as Error);\n }\n\n item.batch = null;\n item.reject = null;\n item.resolve = null;\n }),\n );\n\n for (const item of batch.items) {\n item.reject?.(new Error('Missing result'));\n item.batch = null;\n }\n })\n .catch((cause) => {\n for (const item of batch.items) {\n item.reject?.(cause);\n item.batch = null;\n }\n });\n }\n }\n function load(key: TKey): Promise<TValue> {\n const item: BatchItem<TKey, TValue> = {\n aborted: false,\n key,\n batch: null,\n resolve: throwFatalError,\n reject: throwFatalError,\n };\n\n const promise = new Promise<TValue>((resolve, reject) => {\n item.reject = reject;\n item.resolve = resolve;\n\n pendingItems ??= [];\n pendingItems.push(item);\n });\n\n dispatchTimer ??= setTimeout(dispatch);\n\n return promise;\n }\n\n return {\n load,\n };\n}\n","import type { Maybe } from '@trpc/server/unstable-core-do-not-import';\n\n/**\n * Like `Promise.all()` but for abort signals\n * - When all signals have been aborted, the merged signal will be aborted\n * - If one signal is `null`, no signal will be aborted\n */\nexport function allAbortSignals(...signals: Maybe<AbortSignal>[]): AbortSignal {\n const ac = new AbortController();\n\n const count = signals.length;\n\n let abortedCount = 0;\n\n const onAbort = () => {\n if (++abortedCount === count) {\n ac.abort();\n }\n };\n\n for (const signal of signals) {\n if (signal?.aborted) {\n onAbort();\n } else {\n signal?.addEventListener('abort', onAbort, {\n once: true,\n });\n }\n }\n\n return ac.signal;\n}\n\n/**\n * Like `Promise.race` but for abort signals\n *\n * Basically, a ponyfill for\n * [`AbortSignal.any`](https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal/any_static).\n */\nexport function raceAbortSignals(\n ...signals: Maybe<AbortSignal>[]\n): AbortSignal {\n const ac = new AbortController();\n\n for (const signal of signals) {\n if (signal?.aborted) {\n ac.abort();\n } else {\n signal?.addEventListener('abort', () => ac.abort(), { once: true });\n }\n }\n\n return ac.signal;\n}\n\nexport function abortSignalToPromise(signal: AbortSignal): Promise<never> {\n return new Promise((_, reject) => {\n if (signal.aborted) {\n reject(signal.reason);\n return;\n }\n signal.addEventListener(\n 'abort',\n () => {\n reject(signal.reason);\n },\n { once: true },\n );\n });\n}\n","import type { AnyRouter, ProcedureType } from '@trpc/server';\nimport { observable } from '@trpc/server/observable';\nimport { transformResult } from '@trpc/server/unstable-core-do-not-import';\nimport type { BatchLoader } from '../internals/dataLoader';\nimport { dataLoader } from '../internals/dataLoader';\nimport { allAbortSignals } from '../internals/signals';\nimport type { NonEmptyArray } from '../internals/types';\nimport { TRPCClientError } from '../TRPCClientError';\nimport type { HTTPBatchLinkOptions } from './HTTPBatchLinkOptions';\nimport type { HTTPResult } from './internals/httpUtils';\nimport {\n getUrl,\n jsonHttpRequester,\n resolveHTTPLinkOptions,\n} from './internals/httpUtils';\nimport type { Operation, TRPCLink } from './types';\n\n/**\n * @see https://trpc.io/docs/client/links/httpBatchLink\n */\nexport function httpBatchLink<TRouter extends AnyRouter>(\n opts: HTTPBatchLinkOptions<TRouter['_def']['_config']['$types']>,\n): TRPCLink<TRouter> {\n const resolvedOpts = resolveHTTPLinkOptions(opts);\n const maxURLLength = opts.maxURLLength ?? Infinity;\n const maxItems = opts.maxItems ?? Infinity;\n\n return () => {\n const batchLoader = (\n type: ProcedureType,\n ): BatchLoader<Operation, HTTPResult> => {\n return {\n validate(batchOps) {\n if (maxURLLength === Infinity && maxItems === Infinity) {\n // escape hatch for quick calcs\n return true;\n }\n if (batchOps.length > maxItems) {\n return false;\n }\n const path = batchOps.map((op) => op.path).join(',');\n const inputs = batchOps.map((op) => op.input);\n\n const url = getUrl({\n ...resolvedOpts,\n type,\n path,\n inputs,\n signal: null,\n });\n\n return url.length <= maxURLLength;\n },\n async fetch(batchOps) {\n const path = batchOps.map((op) => op.path).join(',');\n const inputs = batchOps.map((op) => op.input);\n const signal = allAbortSignals(...batchOps.map((op) => op.signal));\n\n const res = await jsonHttpRequester({\n ...resolvedOpts,\n path,\n inputs,\n type,\n headers() {\n if (!opts.headers) {\n return {};\n }\n if (typeof opts.headers === 'function') {\n return opts.headers({\n opList: batchOps as NonEmptyArray<Operation>,\n });\n }\n return opts.headers;\n },\n signal,\n });\n const resJSON = Array.isArray(res.json)\n ? res.json\n : batchOps.map(() => res.json);\n const result = resJSON.map((item) => ({\n meta: res.meta,\n json: item,\n }));\n return result;\n },\n };\n };\n\n const query = dataLoader(batchLoader('query'));\n const mutation = dataLoader(batchLoader('mutation'));\n\n const loaders = { query, mutation };\n return ({ op }) => {\n return observable((observer) => {\n /* istanbul ignore if -- @preserve */\n if (op.type === 'subscription') {\n throw new Error(\n 'Subscriptions are unsupported by `httpLink` - use `httpSubscriptionLink` or `wsLink`',\n );\n }\n const loader = loaders[op.type];\n const promise = loader.load(op);\n\n let _res = undefined as HTTPResult | undefined;\n promise\n .then((res) => {\n _res = res;\n const transformed = transformResult(\n res.json,\n resolvedOpts.transformer.output,\n );\n\n if (!transformed.ok) {\n observer.error(\n TRPCClientError.from(transformed.error, {\n meta: res.meta,\n }),\n );\n return;\n }\n observer.next({\n context: res.meta,\n result: transformed.result,\n });\n observer.complete();\n })\n .catch((err) => {\n observer.error(\n TRPCClientError.from(err, {\n meta: _res?.meta,\n }),\n );\n });\n\n return () => {\n // noop\n };\n });\n };\n };\n}\n"],"mappings":"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"} |
| import { HTTPHeaders, NonEmptyArray, Operation, TRPCLink } from "./types.d-CAt1zKAY.mjs"; | ||
| import { HTTPLinkBaseOptions } from "./httpUtils.d-akze5l4u.mjs"; | ||
| import { AnyClientTypes } from "@trpc/server/unstable-core-do-not-import"; | ||
| import { AnyRouter as AnyRouter$1 } from "@trpc/server"; | ||
| //#region src/links/HTTPBatchLinkOptions.d.ts | ||
| type HTTPBatchLinkOptions<TRoot extends AnyClientTypes> = HTTPLinkBaseOptions<TRoot> & { | ||
| maxURLLength?: number; | ||
| /** | ||
| * Headers to be set on outgoing requests or a callback that of said headers | ||
| * @see http://trpc.io/docs/client/headers | ||
| */ | ||
| headers?: HTTPHeaders | ((opts: { | ||
| opList: NonEmptyArray<Operation>; | ||
| }) => HTTPHeaders | Promise<HTTPHeaders>); | ||
| /** | ||
| * Maximum number of calls in a single batch request | ||
| * @default Infinity | ||
| */ | ||
| maxItems?: number; | ||
| }; | ||
| //# sourceMappingURL=HTTPBatchLinkOptions.d.ts.map | ||
| //#endregion | ||
| //#region src/links/httpBatchLink.d.ts | ||
| /** | ||
| * @see https://trpc.io/docs/client/links/httpBatchLink | ||
| */ | ||
| declare function httpBatchLink<TRouter extends AnyRouter$1>(opts: HTTPBatchLinkOptions<TRouter['_def']['_config']['$types']>): TRPCLink<TRouter>; | ||
| //# sourceMappingURL=httpBatchLink.d.ts.map | ||
| //#endregion | ||
| export { HTTPBatchLinkOptions, httpBatchLink }; | ||
| //# sourceMappingURL=httpBatchLink.d-B0jS5RCU.d.mts.map |
| {"version":3,"file":"httpBatchLink.d-B0jS5RCU.d.mts","names":[],"sources":["../src/links/HTTPBatchLinkOptions.ts","../src/links/httpBatchLink.ts"],"sourcesContent":[],"mappings":";;;;;;KAKY,mCAAmC,kBAC7C,oBAAoB;;EADV;;;;EACe,OAAzB,CAAA,EAOM,WAPN,GAAA,CAAA,CAAA,IAAA,EAAA;IAOM,MAAA,EAEU,aAFV,CAEwB,SAFxB,CAAA;EAAW,CAAA,EAEa,GAClB,WADkB,GACJ,OADI,CACI,WADJ,CAAA,CAAA;EAAS;;;;EACN,QAAA,CAAA,EAAA,MAAA;;;;;;;;AAXvB,iBCeI,aDfgB,CAAA,gBCec,WDfd,CAAA,CAAA,IAAA,ECgBxB,oBDhBwB,CCgBH,ODhBG,CAAA,MAAA,CAAA,CAAA,SAAA,CAAA,CAAA,QAAA,CAAA,CAAA,CAAA,ECiB7B,QDjB6B,CCiBpB,ODjBoB,CAAA"} |
| import { HTTPHeaders, NonEmptyArray, Operation, TRPCLink } from "./types.d-B2PuQAdV.cjs"; | ||
| import { HTTPLinkBaseOptions } from "./httpUtils.d-e55oH-rp.cjs"; | ||
| import { AnyClientTypes } from "@trpc/server/unstable-core-do-not-import"; | ||
| import { AnyRouter as AnyRouter$1 } from "@trpc/server"; | ||
| //#region src/links/HTTPBatchLinkOptions.d.ts | ||
| type HTTPBatchLinkOptions<TRoot extends AnyClientTypes> = HTTPLinkBaseOptions<TRoot> & { | ||
| maxURLLength?: number; | ||
| /** | ||
| * Headers to be set on outgoing requests or a callback that of said headers | ||
| * @see http://trpc.io/docs/client/headers | ||
| */ | ||
| headers?: HTTPHeaders | ((opts: { | ||
| opList: NonEmptyArray<Operation>; | ||
| }) => HTTPHeaders | Promise<HTTPHeaders>); | ||
| /** | ||
| * Maximum number of calls in a single batch request | ||
| * @default Infinity | ||
| */ | ||
| maxItems?: number; | ||
| }; | ||
| //# sourceMappingURL=HTTPBatchLinkOptions.d.ts.map | ||
| //#endregion | ||
| //#region src/links/httpBatchLink.d.ts | ||
| /** | ||
| * @see https://trpc.io/docs/client/links/httpBatchLink | ||
| */ | ||
| declare function httpBatchLink<TRouter extends AnyRouter$1>(opts: HTTPBatchLinkOptions<TRouter['_def']['_config']['$types']>): TRPCLink<TRouter>; | ||
| //# sourceMappingURL=httpBatchLink.d.ts.map | ||
| //#endregion | ||
| export { HTTPBatchLinkOptions, httpBatchLink }; | ||
| //# sourceMappingURL=httpBatchLink.d-CJdYzcjI.d.cts.map |
| {"version":3,"file":"httpBatchLink.d-CJdYzcjI.d.cts","names":[],"sources":["../src/links/HTTPBatchLinkOptions.ts","../src/links/httpBatchLink.ts"],"sourcesContent":[],"mappings":";;;;;;KAKY,mCAAmC,kBAC7C,oBAAoB;;EADV;;;;EACe,OAAzB,CAAA,EAOM,WAPN,GAAA,CAAA,CAAA,IAAA,EAAA;IAOM,MAAA,EAEU,aAFV,CAEwB,SAFxB,CAAA;EAAW,CAAA,EAEa,GAClB,WADkB,GACJ,OADI,CACI,WADJ,CAAA,CAAA;EAAS;;;;EACN,QAAA,CAAA,EAAA,MAAA;;;;;;;;AAXvB,iBCeI,aDfgB,CAAA,gBCec,WDfd,CAAA,CAAA,IAAA,ECgBxB,oBDhBwB,CCgBH,ODhBG,CAAA,MAAA,CAAA,CAAA,SAAA,CAAA,CAAA,QAAA,CAAA,CAAA,CAAA,ECiB7B,QDjB6B,CCiBpB,ODjBoB,CAAA"} |
| const require_chunk = require('./chunk-DWy1uDak.cjs'); | ||
| const require_objectSpread2$1 = require('./objectSpread2-Bsvh_OqM.cjs'); | ||
| const require_TRPCClientError = require('./TRPCClientError-Dey88Uiy.cjs'); | ||
| const require_httpUtils = require('./httpUtils-CjSUiDDG.cjs'); | ||
| const __trpc_server_observable = require_chunk.__toESM(require("@trpc/server/observable")); | ||
| const __trpc_server_unstable_core_do_not_import = require_chunk.__toESM(require("@trpc/server/unstable-core-do-not-import")); | ||
| //#region src/links/internals/contentTypes.ts | ||
| function isOctetType(input) { | ||
| return input instanceof Uint8Array || input instanceof Blob; | ||
| } | ||
| function isFormData(input) { | ||
| return input instanceof FormData; | ||
| } | ||
| function isNonJsonSerializable(input) { | ||
| return isOctetType(input) || isFormData(input); | ||
| } | ||
| //#endregion | ||
| //#region src/links/httpLink.ts | ||
| var import_objectSpread2 = require_chunk.__toESM(require_objectSpread2$1.require_objectSpread2(), 1); | ||
| const universalRequester = (opts) => { | ||
| if ("input" in opts) { | ||
| const { input } = opts; | ||
| if (isFormData(input)) { | ||
| if (opts.type !== "mutation" && opts.methodOverride !== "POST") throw new Error("FormData is only supported for mutations"); | ||
| return require_httpUtils.httpRequest((0, import_objectSpread2.default)((0, import_objectSpread2.default)({}, opts), {}, { | ||
| contentTypeHeader: void 0, | ||
| getUrl: require_httpUtils.getUrl, | ||
| getBody: () => input | ||
| })); | ||
| } | ||
| if (isOctetType(input)) { | ||
| if (opts.type !== "mutation" && opts.methodOverride !== "POST") throw new Error("Octet type input is only supported for mutations"); | ||
| return require_httpUtils.httpRequest((0, import_objectSpread2.default)((0, import_objectSpread2.default)({}, opts), {}, { | ||
| contentTypeHeader: "application/octet-stream", | ||
| getUrl: require_httpUtils.getUrl, | ||
| getBody: () => input | ||
| })); | ||
| } | ||
| } | ||
| return require_httpUtils.jsonHttpRequester(opts); | ||
| }; | ||
| /** | ||
| * @see https://trpc.io/docs/client/links/httpLink | ||
| */ | ||
| function httpLink(opts) { | ||
| const resolvedOpts = require_httpUtils.resolveHTTPLinkOptions(opts); | ||
| return () => { | ||
| return (operationOpts) => { | ||
| const { op } = operationOpts; | ||
| return (0, __trpc_server_observable.observable)((observer) => { | ||
| const { path, input, type } = op; | ||
| /* istanbul ignore if -- @preserve */ | ||
| if (type === "subscription") throw new Error("Subscriptions are unsupported by `httpLink` - use `httpSubscriptionLink` or `wsLink`"); | ||
| const request = universalRequester((0, import_objectSpread2.default)((0, import_objectSpread2.default)({}, resolvedOpts), {}, { | ||
| type, | ||
| path, | ||
| input, | ||
| signal: op.signal, | ||
| headers() { | ||
| if (!opts.headers) return {}; | ||
| if (typeof opts.headers === "function") return opts.headers({ op }); | ||
| return opts.headers; | ||
| } | ||
| })); | ||
| let meta = void 0; | ||
| request.then((res) => { | ||
| meta = res.meta; | ||
| const transformed = (0, __trpc_server_unstable_core_do_not_import.transformResult)(res.json, resolvedOpts.transformer.output); | ||
| if (!transformed.ok) { | ||
| observer.error(require_TRPCClientError.TRPCClientError.from(transformed.error, { meta })); | ||
| return; | ||
| } | ||
| observer.next({ | ||
| context: res.meta, | ||
| result: transformed.result | ||
| }); | ||
| observer.complete(); | ||
| }).catch((cause) => { | ||
| observer.error(require_TRPCClientError.TRPCClientError.from(cause, { meta })); | ||
| }); | ||
| return () => {}; | ||
| }); | ||
| }; | ||
| }; | ||
| } | ||
| //#endregion | ||
| Object.defineProperty(exports, 'httpLink', { | ||
| enumerable: true, | ||
| get: function () { | ||
| return httpLink; | ||
| } | ||
| }); | ||
| Object.defineProperty(exports, 'isFormData', { | ||
| enumerable: true, | ||
| get: function () { | ||
| return isFormData; | ||
| } | ||
| }); | ||
| Object.defineProperty(exports, 'isNonJsonSerializable', { | ||
| enumerable: true, | ||
| get: function () { | ||
| return isNonJsonSerializable; | ||
| } | ||
| }); | ||
| Object.defineProperty(exports, 'isOctetType', { | ||
| enumerable: true, | ||
| get: function () { | ||
| return isOctetType; | ||
| } | ||
| }); |
| import { __toESM, require_objectSpread2 } from "./objectSpread2-BvkFp-_Y.mjs"; | ||
| import { TRPCClientError } from "./TRPCClientError-CjKyS10w.mjs"; | ||
| import { getUrl, httpRequest, jsonHttpRequester, resolveHTTPLinkOptions } from "./httpUtils-Dv57hbOd.mjs"; | ||
| import { observable } from "@trpc/server/observable"; | ||
| import { transformResult } from "@trpc/server/unstable-core-do-not-import"; | ||
| //#region src/links/internals/contentTypes.ts | ||
| function isOctetType(input) { | ||
| return input instanceof Uint8Array || input instanceof Blob; | ||
| } | ||
| function isFormData(input) { | ||
| return input instanceof FormData; | ||
| } | ||
| function isNonJsonSerializable(input) { | ||
| return isOctetType(input) || isFormData(input); | ||
| } | ||
| //#endregion | ||
| //#region src/links/httpLink.ts | ||
| var import_objectSpread2 = __toESM(require_objectSpread2(), 1); | ||
| const universalRequester = (opts) => { | ||
| if ("input" in opts) { | ||
| const { input } = opts; | ||
| if (isFormData(input)) { | ||
| if (opts.type !== "mutation" && opts.methodOverride !== "POST") throw new Error("FormData is only supported for mutations"); | ||
| return httpRequest((0, import_objectSpread2.default)((0, import_objectSpread2.default)({}, opts), {}, { | ||
| contentTypeHeader: void 0, | ||
| getUrl, | ||
| getBody: () => input | ||
| })); | ||
| } | ||
| if (isOctetType(input)) { | ||
| if (opts.type !== "mutation" && opts.methodOverride !== "POST") throw new Error("Octet type input is only supported for mutations"); | ||
| return httpRequest((0, import_objectSpread2.default)((0, import_objectSpread2.default)({}, opts), {}, { | ||
| contentTypeHeader: "application/octet-stream", | ||
| getUrl, | ||
| getBody: () => input | ||
| })); | ||
| } | ||
| } | ||
| return jsonHttpRequester(opts); | ||
| }; | ||
| /** | ||
| * @see https://trpc.io/docs/client/links/httpLink | ||
| */ | ||
| function httpLink(opts) { | ||
| const resolvedOpts = resolveHTTPLinkOptions(opts); | ||
| return () => { | ||
| return (operationOpts) => { | ||
| const { op } = operationOpts; | ||
| return observable((observer) => { | ||
| const { path, input, type } = op; | ||
| /* istanbul ignore if -- @preserve */ | ||
| if (type === "subscription") throw new Error("Subscriptions are unsupported by `httpLink` - use `httpSubscriptionLink` or `wsLink`"); | ||
| const request = universalRequester((0, import_objectSpread2.default)((0, import_objectSpread2.default)({}, resolvedOpts), {}, { | ||
| type, | ||
| path, | ||
| input, | ||
| signal: op.signal, | ||
| headers() { | ||
| if (!opts.headers) return {}; | ||
| if (typeof opts.headers === "function") return opts.headers({ op }); | ||
| return opts.headers; | ||
| } | ||
| })); | ||
| let meta = void 0; | ||
| request.then((res) => { | ||
| meta = res.meta; | ||
| const transformed = transformResult(res.json, resolvedOpts.transformer.output); | ||
| if (!transformed.ok) { | ||
| observer.error(TRPCClientError.from(transformed.error, { meta })); | ||
| return; | ||
| } | ||
| observer.next({ | ||
| context: res.meta, | ||
| result: transformed.result | ||
| }); | ||
| observer.complete(); | ||
| }).catch((cause) => { | ||
| observer.error(TRPCClientError.from(cause, { meta })); | ||
| }); | ||
| return () => {}; | ||
| }); | ||
| }; | ||
| }; | ||
| } | ||
| //#endregion | ||
| export { httpLink, isFormData, isNonJsonSerializable, isOctetType }; | ||
| //# sourceMappingURL=httpLink-DCFpUmZF.mjs.map |
| {"version":3,"file":"httpLink-DCFpUmZF.mjs","names":["input: unknown","universalRequester: Requester","opts: HTTPLinkOptions<TRouter['_def']['_config']['$types']>","meta: HTTPResult['meta'] | undefined"],"sources":["../src/links/internals/contentTypes.ts","../src/links/httpLink.ts"],"sourcesContent":["export function isOctetType(\n input: unknown,\n): input is Uint8Array<ArrayBuffer> | Blob {\n return (\n input instanceof Uint8Array ||\n // File extends from Blob but is only available in nodejs from v20\n input instanceof Blob\n );\n}\n\nexport function isFormData(input: unknown) {\n return input instanceof FormData;\n}\n\nexport function isNonJsonSerializable(input: unknown) {\n return isOctetType(input) || isFormData(input);\n}\n","import { observable } from '@trpc/server/observable';\nimport type {\n AnyClientTypes,\n AnyRouter,\n} from '@trpc/server/unstable-core-do-not-import';\nimport { transformResult } from '@trpc/server/unstable-core-do-not-import';\nimport { TRPCClientError } from '../TRPCClientError';\nimport type {\n HTTPLinkBaseOptions,\n HTTPResult,\n Requester,\n} from './internals/httpUtils';\nimport {\n getUrl,\n httpRequest,\n jsonHttpRequester,\n resolveHTTPLinkOptions,\n} from './internals/httpUtils';\nimport {\n isFormData,\n isOctetType,\n type HTTPHeaders,\n type Operation,\n type TRPCLink,\n} from './types';\n\nexport type HTTPLinkOptions<TRoot extends AnyClientTypes> =\n HTTPLinkBaseOptions<TRoot> & {\n /**\n * Headers to be set on outgoing requests or a callback that of said headers\n * @see http://trpc.io/docs/client/headers\n */\n headers?:\n | HTTPHeaders\n | ((opts: { op: Operation }) => HTTPHeaders | Promise<HTTPHeaders>);\n };\n\nconst universalRequester: Requester = (opts) => {\n if ('input' in opts) {\n const { input } = opts;\n if (isFormData(input)) {\n if (opts.type !== 'mutation' && opts.methodOverride !== 'POST') {\n throw new Error('FormData is only supported for mutations');\n }\n\n return httpRequest({\n ...opts,\n // The browser will set this automatically and include the boundary= in it\n contentTypeHeader: undefined,\n getUrl,\n getBody: () => input,\n });\n }\n\n if (isOctetType(input)) {\n if (opts.type !== 'mutation' && opts.methodOverride !== 'POST') {\n throw new Error('Octet type input is only supported for mutations');\n }\n\n return httpRequest({\n ...opts,\n contentTypeHeader: 'application/octet-stream',\n getUrl,\n getBody: () => input,\n });\n }\n }\n\n return jsonHttpRequester(opts);\n};\n\n/**\n * @see https://trpc.io/docs/client/links/httpLink\n */\nexport function httpLink<TRouter extends AnyRouter = AnyRouter>(\n opts: HTTPLinkOptions<TRouter['_def']['_config']['$types']>,\n): TRPCLink<TRouter> {\n const resolvedOpts = resolveHTTPLinkOptions(opts);\n return () => {\n return (operationOpts) => {\n const { op } = operationOpts;\n return observable((observer) => {\n const { path, input, type } = op;\n /* istanbul ignore if -- @preserve */\n if (type === 'subscription') {\n throw new Error(\n 'Subscriptions are unsupported by `httpLink` - use `httpSubscriptionLink` or `wsLink`',\n );\n }\n\n const request = universalRequester({\n ...resolvedOpts,\n type,\n path,\n input,\n signal: op.signal,\n headers() {\n if (!opts.headers) {\n return {};\n }\n if (typeof opts.headers === 'function') {\n return opts.headers({\n op,\n });\n }\n return opts.headers;\n },\n });\n let meta: HTTPResult['meta'] | undefined = undefined;\n request\n .then((res) => {\n meta = res.meta;\n const transformed = transformResult(\n res.json,\n resolvedOpts.transformer.output,\n );\n\n if (!transformed.ok) {\n observer.error(\n TRPCClientError.from(transformed.error, {\n meta,\n }),\n );\n return;\n }\n observer.next({\n context: res.meta,\n result: transformed.result,\n });\n observer.complete();\n })\n .catch((cause) => {\n observer.error(TRPCClientError.from(cause, { meta }));\n });\n\n return () => {\n // noop\n };\n });\n };\n };\n}\n"],"mappings":";;;;;;;AAAA,SAAgB,YACdA,OACyC;AACzC,QACE,iBAAiB,cAEjB,iBAAiB;AAEpB;AAED,SAAgB,WAAWA,OAAgB;AACzC,QAAO,iBAAiB;AACzB;AAED,SAAgB,sBAAsBA,OAAgB;AACpD,QAAO,YAAY,MAAM,IAAI,WAAW,MAAM;AAC/C;;;;;ACqBD,MAAMC,qBAAgC,CAAC,SAAS;AAC9C,KAAI,WAAW,MAAM;EACnB,MAAM,EAAE,OAAO,GAAG;AAClB,MAAI,WAAW,MAAM,EAAE;AACrB,OAAI,KAAK,SAAS,cAAc,KAAK,mBAAmB,OACtD,OAAM,IAAI,MAAM;AAGlB,UAAO,oFACF;IAEH;IACA;IACA,SAAS,MAAM;MACf;EACH;AAED,MAAI,YAAY,MAAM,EAAE;AACtB,OAAI,KAAK,SAAS,cAAc,KAAK,mBAAmB,OACtD,OAAM,IAAI,MAAM;AAGlB,UAAO,oFACF;IACH,mBAAmB;IACnB;IACA,SAAS,MAAM;MACf;EACH;CACF;AAED,QAAO,kBAAkB,KAAK;AAC/B;;;;AAKD,SAAgB,SACdC,MACmB;CACnB,MAAM,eAAe,uBAAuB,KAAK;AACjD,QAAO,MAAM;AACX,SAAO,CAAC,kBAAkB;GACxB,MAAM,EAAE,IAAI,GAAG;AACf,UAAO,WAAW,CAAC,aAAa;IAC9B,MAAM,EAAE,MAAM,OAAO,MAAM,GAAG;;AAE9B,QAAI,SAAS,eACX,OAAM,IAAI,MACR;IAIJ,MAAM,UAAU,2FACX;KACH;KACA;KACA;KACA,QAAQ,GAAG;KACX,UAAU;AACR,WAAK,KAAK,QACR,QAAO,CAAE;AAEX,iBAAW,KAAK,YAAY,WAC1B,QAAO,KAAK,QAAQ,EAClB,GACD,EAAC;AAEJ,aAAO,KAAK;KACb;OACD;IACF,IAAIC;AACJ,YACG,KAAK,CAAC,QAAQ;AACb,YAAO,IAAI;KACX,MAAM,cAAc,gBAClB,IAAI,MACJ,aAAa,YAAY,OAC1B;AAED,UAAK,YAAY,IAAI;AACnB,eAAS,MACP,gBAAgB,KAAK,YAAY,OAAO,EACtC,KACD,EAAC,CACH;AACD;KACD;AACD,cAAS,KAAK;MACZ,SAAS,IAAI;MACb,QAAQ,YAAY;KACrB,EAAC;AACF,cAAS,UAAU;IACpB,EAAC,CACD,MAAM,CAAC,UAAU;AAChB,cAAS,MAAM,gBAAgB,KAAK,OAAO,EAAE,KAAM,EAAC,CAAC;IACtD,EAAC;AAEJ,WAAO,MAAM,CAEZ;GACF,EAAC;EACH;CACF;AACF"} |
| import { HTTPHeaders, Operation, TRPCLink } from "./types.d-CAt1zKAY.mjs"; | ||
| import { HTTPLinkBaseOptions } from "./httpUtils.d-akze5l4u.mjs"; | ||
| import { AnyClientTypes, AnyRouter } from "@trpc/server/unstable-core-do-not-import"; | ||
| //#region src/links/httpLink.d.ts | ||
| type HTTPLinkOptions<TRoot extends AnyClientTypes> = HTTPLinkBaseOptions<TRoot> & { | ||
| /** | ||
| * Headers to be set on outgoing requests or a callback that of said headers | ||
| * @see http://trpc.io/docs/client/headers | ||
| */ | ||
| headers?: HTTPHeaders | ((opts: { | ||
| op: Operation; | ||
| }) => HTTPHeaders | Promise<HTTPHeaders>); | ||
| }; | ||
| /** | ||
| * @see https://trpc.io/docs/client/links/httpLink | ||
| */ | ||
| declare function httpLink<TRouter extends AnyRouter = AnyRouter>(opts: HTTPLinkOptions<TRouter['_def']['_config']['$types']>): TRPCLink<TRouter>; | ||
| //# sourceMappingURL=httpLink.d.ts.map | ||
| //#endregion | ||
| export { HTTPLinkOptions, httpLink }; | ||
| //# sourceMappingURL=httpLink.d-BEC5B7OH.d.mts.map |
| {"version":3,"file":"httpLink.d-BEC5B7OH.d.mts","names":[],"sources":["../src/links/httpLink.ts"],"sourcesContent":[],"mappings":";;;;;KA0BY,8BAA8B,kBACxC,oBAAoB;;AADtB;;;EAAwD,OAClC,CAAA,EAMd,WANc,GAAA,CAAA,CAAA,IAAA,EAAA;IAApB,EAAA,EAOoB,SAPpB;EAAmB,CAAA,EAMb,GAC8B,WAD9B,GAC4C,OAD5C,CACoD,WADpD,CAAA,CAAA;CAAW;;;;AACwC,iBAwC3C,QAxC2C,CAAA,gBAwClB,SAxCkB,GAwCN,SAxCM,CAAA,CAAA,IAAA,EAyCnD,eAzCmD,CAyCnC,OAzCmC,CAAA,MAAA,CAAA,CAAA,SAAA,CAAA,CAAA,QAAA,CAAA,CAAA,CAAA,EA0CxD,QA1CwD,CA0C/C,OA1C+C,CAAA;AAwC3D"} |
| import { HTTPHeaders, Operation, TRPCLink } from "./types.d-B2PuQAdV.cjs"; | ||
| import { HTTPLinkBaseOptions } from "./httpUtils.d-e55oH-rp.cjs"; | ||
| import { AnyClientTypes, AnyRouter } from "@trpc/server/unstable-core-do-not-import"; | ||
| //#region src/links/httpLink.d.ts | ||
| type HTTPLinkOptions<TRoot extends AnyClientTypes> = HTTPLinkBaseOptions<TRoot> & { | ||
| /** | ||
| * Headers to be set on outgoing requests or a callback that of said headers | ||
| * @see http://trpc.io/docs/client/headers | ||
| */ | ||
| headers?: HTTPHeaders | ((opts: { | ||
| op: Operation; | ||
| }) => HTTPHeaders | Promise<HTTPHeaders>); | ||
| }; | ||
| /** | ||
| * @see https://trpc.io/docs/client/links/httpLink | ||
| */ | ||
| declare function httpLink<TRouter extends AnyRouter = AnyRouter>(opts: HTTPLinkOptions<TRouter['_def']['_config']['$types']>): TRPCLink<TRouter>; | ||
| //# sourceMappingURL=httpLink.d.ts.map | ||
| //#endregion | ||
| export { HTTPLinkOptions, httpLink }; | ||
| //# sourceMappingURL=httpLink.d-CYzMvM3c.d.cts.map |
| {"version":3,"file":"httpLink.d-CYzMvM3c.d.cts","names":[],"sources":["../src/links/httpLink.ts"],"sourcesContent":[],"mappings":";;;;;KA0BY,8BAA8B,kBACxC,oBAAoB;;AADtB;;;EAAwD,OAClC,CAAA,EAMd,WANc,GAAA,CAAA,CAAA,IAAA,EAAA;IAApB,EAAA,EAOoB,SAPpB;EAAmB,CAAA,EAMb,GAC8B,WAD9B,GAC4C,OAD5C,CACoD,WADpD,CAAA,CAAA;CAAW;;;;AACwC,iBAwC3C,QAxC2C,CAAA,gBAwClB,SAxCkB,GAwCN,SAxCM,CAAA,CAAA,IAAA,EAyCnD,eAzCmD,CAyCnC,OAzCmC,CAAA,MAAA,CAAA,CAAA,SAAA,CAAA,CAAA,QAAA,CAAA,CAAA,CAAA,EA0CxD,QA1CwD,CA0C/C,OA1C+C,CAAA;AAwC3D"} |
| import { FetchEsque } from "./types.d-CAt1zKAY.mjs"; | ||
| import { TransformerOptions } from "./unstable-internals.d-BOmV7EK1.mjs"; | ||
| import { AnyClientTypes, CombinedDataTransformer, Maybe, ProcedureType } from "@trpc/server/unstable-core-do-not-import"; | ||
| //#region src/links/internals/httpUtils.d.ts | ||
| /** | ||
| * @internal | ||
| */ | ||
| type HTTPLinkBaseOptions<TRoot extends Pick<AnyClientTypes, 'transformer'>> = { | ||
| url: string | URL; | ||
| /** | ||
| * Add ponyfill for fetch | ||
| */ | ||
| fetch?: FetchEsque; | ||
| /** | ||
| * Send all requests `as POST`s requests regardless of the procedure type | ||
| * The HTTP handler must separately allow overriding the method. See: | ||
| * @see https://trpc.io/docs/rpc | ||
| */ | ||
| methodOverride?: 'POST'; | ||
| } & TransformerOptions<TRoot>; | ||
| //#endregion | ||
| export { HTTPLinkBaseOptions }; | ||
| //# sourceMappingURL=httpUtils.d-akze5l4u.d.mts.map |
| {"version":3,"file":"httpUtils.d-akze5l4u.d.mts","names":[],"sources":["../src/links/internals/httpUtils.ts"],"sourcesContent":[],"mappings":";;;;;;;AAqBA;;AACqB,KADT,mBACS,CAAA,cAAL,IAAK,CAAA,cAAA,EAAA,aAAA,CAAA,CAAA,GAAA;EAAc,GAAnB,EAAA,MAAA,GAEA,GAFA;EAAI;;;EAaQ,KAAxB,CAAA,EAPM,UAON;EAAkB;;;;;;IAAlB,mBAAmB"} |
| import { FetchEsque } from "./types.d-B2PuQAdV.cjs"; | ||
| import { TransformerOptions } from "./unstable-internals.d-kWsZTlQq.cjs"; | ||
| import { AnyClientTypes, CombinedDataTransformer, Maybe, ProcedureType } from "@trpc/server/unstable-core-do-not-import"; | ||
| //#region src/links/internals/httpUtils.d.ts | ||
| /** | ||
| * @internal | ||
| */ | ||
| type HTTPLinkBaseOptions<TRoot extends Pick<AnyClientTypes, 'transformer'>> = { | ||
| url: string | URL; | ||
| /** | ||
| * Add ponyfill for fetch | ||
| */ | ||
| fetch?: FetchEsque; | ||
| /** | ||
| * Send all requests `as POST`s requests regardless of the procedure type | ||
| * The HTTP handler must separately allow overriding the method. See: | ||
| * @see https://trpc.io/docs/rpc | ||
| */ | ||
| methodOverride?: 'POST'; | ||
| } & TransformerOptions<TRoot>; | ||
| //#endregion | ||
| export { HTTPLinkBaseOptions }; | ||
| //# sourceMappingURL=httpUtils.d-e55oH-rp.d.cts.map |
| {"version":3,"file":"httpUtils.d-e55oH-rp.d.cts","names":[],"sources":["../src/links/internals/httpUtils.ts"],"sourcesContent":[],"mappings":";;;;;;;AAqBA;;AACqB,KADT,mBACS,CAAA,cAAL,IAAK,CAAA,cAAA,EAAA,aAAA,CAAA,CAAA,GAAA;EAAc,GAAnB,EAAA,MAAA,GAEA,GAFA;EAAI;;;EAaQ,KAAxB,CAAA,EAPM,UAON;EAAkB;;;;;;IAAlB,mBAAmB"} |
| import { Operation, OperationResultEnvelope, TRPCClientError, TRPCLink } from "./types.d-B2PuQAdV.cjs"; | ||
| import { AnyRouter, InferrableClientTypes } from "@trpc/server/unstable-core-do-not-import"; | ||
| //#region src/links/loggerLink.d.ts | ||
| type ConsoleEsque = { | ||
| log: (...args: any[]) => void; | ||
| error: (...args: any[]) => void; | ||
| }; | ||
| type EnableFnOptions<TRouter extends InferrableClientTypes> = { | ||
| direction: 'down'; | ||
| result: OperationResultEnvelope<unknown, TRPCClientError<TRouter>> | TRPCClientError<TRouter>; | ||
| } | (Operation & { | ||
| direction: 'up'; | ||
| }); | ||
| type EnabledFn<TRouter extends AnyRouter> = (opts: EnableFnOptions<TRouter>) => boolean; | ||
| type LoggerLinkFnOptions<TRouter extends AnyRouter> = Operation & ({ | ||
| /** | ||
| * Request result | ||
| */ | ||
| direction: 'down'; | ||
| result: OperationResultEnvelope<unknown, TRPCClientError<TRouter>> | TRPCClientError<TRouter>; | ||
| elapsedMs: number; | ||
| } | { | ||
| /** | ||
| * Request was just initialized | ||
| */ | ||
| direction: 'up'; | ||
| }); | ||
| type LoggerLinkFn<TRouter extends AnyRouter> = (opts: LoggerLinkFnOptions<TRouter>) => void; | ||
| type ColorMode = 'ansi' | 'css' | 'none'; | ||
| interface LoggerLinkOptions<TRouter extends AnyRouter> { | ||
| logger?: LoggerLinkFn<TRouter>; | ||
| enabled?: EnabledFn<TRouter>; | ||
| /** | ||
| * Used in the built-in defaultLogger | ||
| */ | ||
| console?: ConsoleEsque; | ||
| /** | ||
| * Color mode | ||
| * @default typeof window === 'undefined' ? 'ansi' : 'css' | ||
| */ | ||
| colorMode?: ColorMode; | ||
| /** | ||
| * Include context in the log - defaults to false unless `colorMode` is 'css' | ||
| */ | ||
| withContext?: boolean; | ||
| } | ||
| /** | ||
| * @see https://trpc.io/docs/v11/client/links/loggerLink | ||
| */ | ||
| declare function loggerLink<TRouter extends AnyRouter = AnyRouter>(opts?: LoggerLinkOptions<TRouter>): TRPCLink<TRouter>; | ||
| //#endregion | ||
| export { LoggerLinkOptions, loggerLink }; | ||
| //# sourceMappingURL=loggerLink.d-3BnyPZWQ.d.cts.map |
| {"version":3,"file":"loggerLink.d-3BnyPZWQ.d.cts","names":[],"sources":["../src/links/loggerLink.ts"],"sourcesContent":[],"mappings":";;;;KAeK,YAAA;EAAA,GAAA,EAAA,CAAA,GAAA,IAAA,EAAY,GAAA,EAAA,EAAA,GAAA,IAAA;EAKZ,KAAA,EAAA,CAAA,GAAA,IAAA,EAAA,GAAe,EAAA,EAAA,GAAA,IAAA;CAAA;KAAf,eAAgC,CAAA,gBAAA,qBAAA,CAAA,GAAA;EAAqB,SAIC,EAAA,MAAA;EAAO,MAAvB,EAAjC,uBAAiC,CAAA,OAAA,EAAA,eAAA,CAAgB,OAAhB,CAAA,CAAA,GACjC,eADiC,CACjB,OADiB,CAAA;CAAe,GAAA,CAGrD,SAHK,GAAA;EAAuB,SACP,EAAA,IAAA;CAAO,CAAA;KAK5B,SAHA,CAAA,gBAG0B,SAH1B,CAAA,GAAA,CAAA,IAAA,EAIG,eAJH,CAImB,OAJnB,CAAA,EAAA,GAAA,OAAA;AAAS,KAOT,mBAPS,CAAA,gBAO2B,SAP3B,CAAA,GAOwC,SAPxC,GAAA,CAAA;EAGT;;;EAAmC,SAChB,EAAA,MAAA;EAAO,MAAvB,EAWI,uBAXJ,CAAA,OAAA,EAWqC,eAXrC,CAWqD,OAXrD,CAAA,CAAA,GAYI,eAZJ,CAYoB,OAZpB,CAAA;EAAe,SAAA,EAAA,MAAA;AAAA,CAAA,GAGlB;EAAmB;;;EAAuC,SAQF,EAAA,IAAA;CAAO,CAAA;KAY/D,YAZO,CAAA,gBAYsB,SAZtB,CAAA,GAAA,CAAA,IAAA,EAaJ,mBAbI,CAagB,OAbhB,CAAA,EAAA,GAAA,IAAA;KAgBP,SAAA,GAfuB,MAAA,GAAA,KAAA,GAAA,MAAA;AAAhB,UAiBK,iBAjBL,CAAA,gBAiBuC,SAjBvC,CAAA,CAAA;EAAe,MAAA,CAAA,EAkBhB,YAlBgB,CAkBH,OAlBG,CAAA;EAWtB,OAAA,CAAA,EAQO,SARK,CAQK,OARL,CAAA;EAAA;;;EACkB,OAA3B,CAAA,EAWI,YAXJ;EAAmB;AAAA;AAK3B;;EAAkC,SAAiB,CAAA,EAWrC,SAXqC;EAAS;;;EAE/B,WAAjB,CAAA,EAAA,OAAA;;;AASW;AA8IvB;AAA0B,iBAAV,UAAU,CAAA,gBAAiB,SAAjB,GAA6B,SAA7B,CAAA,CAAA,IAAA,CAAA,EAClB,iBADkB,CACA,OADA,CAAA,CAAA,EAEvB,QAFuB,CAEd,OAFc,CAAA"} |
| import { Operation, OperationResultEnvelope, TRPCClientError, TRPCLink } from "./types.d-CAt1zKAY.mjs"; | ||
| import { AnyRouter, InferrableClientTypes } from "@trpc/server/unstable-core-do-not-import"; | ||
| //#region src/links/loggerLink.d.ts | ||
| type ConsoleEsque = { | ||
| log: (...args: any[]) => void; | ||
| error: (...args: any[]) => void; | ||
| }; | ||
| type EnableFnOptions<TRouter extends InferrableClientTypes> = { | ||
| direction: 'down'; | ||
| result: OperationResultEnvelope<unknown, TRPCClientError<TRouter>> | TRPCClientError<TRouter>; | ||
| } | (Operation & { | ||
| direction: 'up'; | ||
| }); | ||
| type EnabledFn<TRouter extends AnyRouter> = (opts: EnableFnOptions<TRouter>) => boolean; | ||
| type LoggerLinkFnOptions<TRouter extends AnyRouter> = Operation & ({ | ||
| /** | ||
| * Request result | ||
| */ | ||
| direction: 'down'; | ||
| result: OperationResultEnvelope<unknown, TRPCClientError<TRouter>> | TRPCClientError<TRouter>; | ||
| elapsedMs: number; | ||
| } | { | ||
| /** | ||
| * Request was just initialized | ||
| */ | ||
| direction: 'up'; | ||
| }); | ||
| type LoggerLinkFn<TRouter extends AnyRouter> = (opts: LoggerLinkFnOptions<TRouter>) => void; | ||
| type ColorMode = 'ansi' | 'css' | 'none'; | ||
| interface LoggerLinkOptions<TRouter extends AnyRouter> { | ||
| logger?: LoggerLinkFn<TRouter>; | ||
| enabled?: EnabledFn<TRouter>; | ||
| /** | ||
| * Used in the built-in defaultLogger | ||
| */ | ||
| console?: ConsoleEsque; | ||
| /** | ||
| * Color mode | ||
| * @default typeof window === 'undefined' ? 'ansi' : 'css' | ||
| */ | ||
| colorMode?: ColorMode; | ||
| /** | ||
| * Include context in the log - defaults to false unless `colorMode` is 'css' | ||
| */ | ||
| withContext?: boolean; | ||
| } | ||
| /** | ||
| * @see https://trpc.io/docs/v11/client/links/loggerLink | ||
| */ | ||
| declare function loggerLink<TRouter extends AnyRouter = AnyRouter>(opts?: LoggerLinkOptions<TRouter>): TRPCLink<TRouter>; | ||
| //#endregion | ||
| export { LoggerLinkOptions, loggerLink }; | ||
| //# sourceMappingURL=loggerLink.d-B_ylo7O3.d.mts.map |
| {"version":3,"file":"loggerLink.d-B_ylo7O3.d.mts","names":[],"sources":["../src/links/loggerLink.ts"],"sourcesContent":[],"mappings":";;;;KAeK,YAAA;EAAA,GAAA,EAAA,CAAA,GAAA,IAAA,EAAY,GAAA,EAAA,EAAA,GAAA,IAAA;EAKZ,KAAA,EAAA,CAAA,GAAA,IAAA,EAAA,GAAe,EAAA,EAAA,GAAA,IAAA;CAAA;KAAf,eAAgC,CAAA,gBAAA,qBAAA,CAAA,GAAA;EAAqB,SAIC,EAAA,MAAA;EAAO,MAAvB,EAAjC,uBAAiC,CAAA,OAAA,EAAA,eAAA,CAAgB,OAAhB,CAAA,CAAA,GACjC,eADiC,CACjB,OADiB,CAAA;CAAe,GAAA,CAGrD,SAHK,GAAA;EAAuB,SACP,EAAA,IAAA;CAAO,CAAA;KAK5B,SAHA,CAAA,gBAG0B,SAH1B,CAAA,GAAA,CAAA,IAAA,EAIG,eAJH,CAImB,OAJnB,CAAA,EAAA,GAAA,OAAA;AAAS,KAOT,mBAPS,CAAA,gBAO2B,SAP3B,CAAA,GAOwC,SAPxC,GAAA,CAAA;EAGT;;;EAAmC,SAChB,EAAA,MAAA;EAAO,MAAvB,EAWI,uBAXJ,CAAA,OAAA,EAWqC,eAXrC,CAWqD,OAXrD,CAAA,CAAA,GAYI,eAZJ,CAYoB,OAZpB,CAAA;EAAe,SAAA,EAAA,MAAA;AAAA,CAAA,GAGlB;EAAmB;;;EAAuC,SAQF,EAAA,IAAA;CAAO,CAAA;KAY/D,YAZO,CAAA,gBAYsB,SAZtB,CAAA,GAAA,CAAA,IAAA,EAaJ,mBAbI,CAagB,OAbhB,CAAA,EAAA,GAAA,IAAA;KAgBP,SAAA,GAfuB,MAAA,GAAA,KAAA,GAAA,MAAA;AAAhB,UAiBK,iBAjBL,CAAA,gBAiBuC,SAjBvC,CAAA,CAAA;EAAe,MAAA,CAAA,EAkBhB,YAlBgB,CAkBH,OAlBG,CAAA;EAWtB,OAAA,CAAA,EAQO,SARK,CAQK,OARL,CAAA;EAAA;;;EACkB,OAA3B,CAAA,EAWI,YAXJ;EAAmB;AAAA;AAK3B;;EAAkC,SAAiB,CAAA,EAWrC,SAXqC;EAAS;;;EAE/B,WAAjB,CAAA,EAAA,OAAA;;;AASW;AA8IvB;AAA0B,iBAAV,UAAU,CAAA,gBAAiB,SAAjB,GAA6B,SAA7B,CAAA,CAAA,IAAA,CAAA,EAClB,iBADkB,CACA,OADA,CAAA,CAAA,EAEvB,QAFuB,CAEd,OAFc,CAAA"} |
| import { Operation, TRPCLink } from "./types.d-B2PuQAdV.cjs"; | ||
| import { AnyRouter } from "@trpc/server/unstable-core-do-not-import"; | ||
| //#region src/links/splitLink.d.ts | ||
| declare function splitLink<TRouter extends AnyRouter = AnyRouter>(opts: { | ||
| condition: (op: Operation) => boolean; | ||
| /** | ||
| * The link to execute next if the test function returns `true`. | ||
| */ | ||
| true: TRPCLink<TRouter> | TRPCLink<TRouter>[]; | ||
| /** | ||
| * The link to execute next if the test function returns `false`. | ||
| */ | ||
| false: TRPCLink<TRouter> | TRPCLink<TRouter>[]; | ||
| }): TRPCLink<TRouter>; | ||
| //# sourceMappingURL=splitLink.d.ts.map | ||
| //#endregion | ||
| export { splitLink }; | ||
| //# sourceMappingURL=splitLink.d-3ZZnmg7h.d.cts.map |
| {"version":3,"file":"splitLink.d-3ZZnmg7h.d.cts","names":[],"sources":["../src/links/splitLink.ts"],"sourcesContent":[],"mappings":";;;;iBAQgB,0BAA0B,YAAY;kBACpC;EADF;;;EAAmC,IAAG,EAK9C,QAL8C,CAKrC,OALqC,CAAA,GAK1B,QAL0B,CAKjB,OALiB,CAAA,EAAA;EAAS;;;EAK/C,KAAqB,EAI5B,QAJ4B,CAInB,OAJmB,CAAA,GAIR,QAJQ,CAIC,OAJD,CAAA,EAAA;CAAO,CAAA,EAKxC,QALwB,CAKf,OALe,CAAA"} |
| import { Operation, TRPCLink } from "./types.d-CAt1zKAY.mjs"; | ||
| import { AnyRouter } from "@trpc/server/unstable-core-do-not-import"; | ||
| //#region src/links/splitLink.d.ts | ||
| declare function splitLink<TRouter extends AnyRouter = AnyRouter>(opts: { | ||
| condition: (op: Operation) => boolean; | ||
| /** | ||
| * The link to execute next if the test function returns `true`. | ||
| */ | ||
| true: TRPCLink<TRouter> | TRPCLink<TRouter>[]; | ||
| /** | ||
| * The link to execute next if the test function returns `false`. | ||
| */ | ||
| false: TRPCLink<TRouter> | TRPCLink<TRouter>[]; | ||
| }): TRPCLink<TRouter>; | ||
| //# sourceMappingURL=splitLink.d.ts.map | ||
| //#endregion | ||
| export { splitLink }; | ||
| //# sourceMappingURL=splitLink.d-Df2gT0RV.d.mts.map |
| {"version":3,"file":"splitLink.d-Df2gT0RV.d.mts","names":[],"sources":["../src/links/splitLink.ts"],"sourcesContent":[],"mappings":";;;;iBAQgB,0BAA0B,YAAY;kBACpC;EADF;;;EAAmC,IAAG,EAK9C,QAL8C,CAKrC,OALqC,CAAA,GAK1B,QAL0B,CAKjB,OALiB,CAAA,EAAA;EAAS;;;EAK/C,KAAqB,EAI5B,QAJ4B,CAInB,OAJmB,CAAA,GAIR,QAJQ,CAIC,OAJD,CAAA,EAAA;CAAO,CAAA,EAKxC,QALwB,CAKf,OALe,CAAA"} |
| import { __toESM, require_defineProperty, require_objectSpread2 } from "./objectSpread2-BvkFp-_Y.mjs"; | ||
| import { isObject } from "@trpc/server/unstable-core-do-not-import"; | ||
| //#region src/TRPCClientError.ts | ||
| var import_defineProperty = __toESM(require_defineProperty(), 1); | ||
| var import_objectSpread2 = __toESM(require_objectSpread2(), 1); | ||
| function isTRPCClientError(cause) { | ||
| return cause instanceof TRPCClientError; | ||
| } | ||
| function isTRPCErrorResponse(obj) { | ||
| return isObject(obj) && isObject(obj["error"]) && typeof obj["error"]["code"] === "number" && typeof obj["error"]["message"] === "string"; | ||
| } | ||
| function getMessageFromUnknownError(err, fallback) { | ||
| if (typeof err === "string") return err; | ||
| if (isObject(err) && typeof err["message"] === "string") return err["message"]; | ||
| return fallback; | ||
| } | ||
| var TRPCClientError = class TRPCClientError extends Error { | ||
| constructor(message, opts) { | ||
| var _opts$result, _opts$result2; | ||
| const cause = opts === null || opts === void 0 ? void 0 : opts.cause; | ||
| super(message, { cause }); | ||
| (0, import_defineProperty.default)(this, "cause", void 0); | ||
| (0, import_defineProperty.default)(this, "shape", void 0); | ||
| (0, import_defineProperty.default)(this, "data", void 0); | ||
| (0, import_defineProperty.default)(this, "meta", void 0); | ||
| this.meta = opts === null || opts === void 0 ? void 0 : opts.meta; | ||
| this.cause = cause; | ||
| this.shape = opts === null || opts === void 0 || (_opts$result = opts.result) === null || _opts$result === void 0 ? void 0 : _opts$result.error; | ||
| this.data = opts === null || opts === void 0 || (_opts$result2 = opts.result) === null || _opts$result2 === void 0 ? void 0 : _opts$result2.error.data; | ||
| this.name = "TRPCClientError"; | ||
| Object.setPrototypeOf(this, TRPCClientError.prototype); | ||
| } | ||
| static from(_cause, opts = {}) { | ||
| const cause = _cause; | ||
| if (isTRPCClientError(cause)) { | ||
| if (opts.meta) cause.meta = (0, import_objectSpread2.default)((0, import_objectSpread2.default)({}, cause.meta), opts.meta); | ||
| return cause; | ||
| } | ||
| if (isTRPCErrorResponse(cause)) return new TRPCClientError(cause.error.message, (0, import_objectSpread2.default)((0, import_objectSpread2.default)({}, opts), {}, { result: cause })); | ||
| return new TRPCClientError(getMessageFromUnknownError(cause, "Unknown error"), (0, import_objectSpread2.default)((0, import_objectSpread2.default)({}, opts), {}, { cause })); | ||
| } | ||
| }; | ||
| //#endregion | ||
| export { TRPCClientError, isTRPCClientError }; | ||
| //# sourceMappingURL=TRPCClientError-CjKyS10w.mjs.map |
| {"version":3,"file":"TRPCClientError-CjKyS10w.mjs","names":["cause: unknown","obj: unknown","err: unknown","fallback: string","message: string","opts?: {\n result?: Maybe<TRPCErrorResponse<inferErrorShape<TRouterOrProcedure>>>;\n cause?: Error;\n meta?: Record<string, unknown>;\n }","_cause: Error | TRPCErrorResponse<any> | object","opts: { meta?: Record<string, unknown> }"],"sources":["../src/TRPCClientError.ts"],"sourcesContent":["import type {\n inferClientTypes,\n InferrableClientTypes,\n Maybe,\n TRPCErrorResponse,\n} from '@trpc/server/unstable-core-do-not-import';\nimport {\n isObject,\n type DefaultErrorShape,\n} from '@trpc/server/unstable-core-do-not-import';\n\ntype inferErrorShape<TInferrable extends InferrableClientTypes> =\n inferClientTypes<TInferrable>['errorShape'];\nexport interface TRPCClientErrorBase<TShape extends DefaultErrorShape> {\n readonly message: string;\n readonly shape: Maybe<TShape>;\n readonly data: Maybe<TShape['data']>;\n}\nexport type TRPCClientErrorLike<TInferrable extends InferrableClientTypes> =\n TRPCClientErrorBase<inferErrorShape<TInferrable>>;\n\nexport function isTRPCClientError<TInferrable extends InferrableClientTypes>(\n cause: unknown,\n): cause is TRPCClientError<TInferrable> {\n return cause instanceof TRPCClientError;\n}\n\nfunction isTRPCErrorResponse(obj: unknown): obj is TRPCErrorResponse<any> {\n return (\n isObject(obj) &&\n isObject(obj['error']) &&\n typeof obj['error']['code'] === 'number' &&\n typeof obj['error']['message'] === 'string'\n );\n}\n\nfunction getMessageFromUnknownError(err: unknown, fallback: string): string {\n if (typeof err === 'string') {\n return err;\n }\n if (isObject(err) && typeof err['message'] === 'string') {\n return err['message'];\n }\n return fallback;\n}\n\nexport class TRPCClientError<TRouterOrProcedure extends InferrableClientTypes>\n extends Error\n implements TRPCClientErrorBase<inferErrorShape<TRouterOrProcedure>>\n{\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore override doesn't work in all environments due to \"This member cannot have an 'override' modifier because it is not declared in the base class 'Error'\"\n public override readonly cause;\n public readonly shape: Maybe<inferErrorShape<TRouterOrProcedure>>;\n public readonly data: Maybe<inferErrorShape<TRouterOrProcedure>['data']>;\n\n /**\n * Additional meta data about the error\n * In the case of HTTP-errors, we'll have `response` and potentially `responseJSON` here\n */\n public meta;\n\n constructor(\n message: string,\n opts?: {\n result?: Maybe<TRPCErrorResponse<inferErrorShape<TRouterOrProcedure>>>;\n cause?: Error;\n meta?: Record<string, unknown>;\n },\n ) {\n const cause = opts?.cause;\n\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore https://github.com/tc39/proposal-error-cause\n super(message, { cause });\n\n this.meta = opts?.meta;\n\n this.cause = cause;\n this.shape = opts?.result?.error;\n this.data = opts?.result?.error.data;\n this.name = 'TRPCClientError';\n\n Object.setPrototypeOf(this, TRPCClientError.prototype);\n }\n\n public static from<TRouterOrProcedure extends InferrableClientTypes>(\n _cause: Error | TRPCErrorResponse<any> | object,\n opts: { meta?: Record<string, unknown> } = {},\n ): TRPCClientError<TRouterOrProcedure> {\n const cause = _cause as unknown;\n\n if (isTRPCClientError(cause)) {\n if (opts.meta) {\n // Decorate with meta error data\n cause.meta = {\n ...cause.meta,\n ...opts.meta,\n };\n }\n return cause;\n }\n if (isTRPCErrorResponse(cause)) {\n return new TRPCClientError(cause.error.message, {\n ...opts,\n result: cause,\n });\n }\n return new TRPCClientError(\n getMessageFromUnknownError(cause, 'Unknown error'),\n {\n ...opts,\n cause: cause as any,\n },\n );\n }\n}\n"],"mappings":";;;;;;AAqBA,SAAgB,kBACdA,OACuC;AACvC,QAAO,iBAAiB;AACzB;AAED,SAAS,oBAAoBC,KAA6C;AACxE,QACE,SAAS,IAAI,IACb,SAAS,IAAI,SAAS,WACf,IAAI,SAAS,YAAY,mBACzB,IAAI,SAAS,eAAe;AAEtC;AAED,SAAS,2BAA2BC,KAAcC,UAA0B;AAC1E,YAAW,QAAQ,SACjB,QAAO;AAET,KAAI,SAAS,IAAI,WAAW,IAAI,eAAe,SAC7C,QAAO,IAAI;AAEb,QAAO;AACR;AAED,IAAa,kBAAb,MAAa,wBACH,MAEV;CAaE,YACEC,SACAC,MAKA;;EACA,MAAM,oDAAQ,KAAM;AAIpB,QAAM,SAAS,EAAE,MAAO,EAAC;qCA2C1B,MAjEwB;qCAiEvB,MAhEc;qCAgEb,MA/Da;qCA+DZ,MAzDG;AAgBL,OAAK,mDAAO,KAAM;AAElB,OAAK,QAAQ;AACb,OAAK,4DAAQ,KAAM,oEAAQ;AAC3B,OAAK,4DAAO,KAAM,sEAAQ,MAAM;AAChC,OAAK,OAAO;AAEZ,SAAO,eAAe,MAAM,gBAAgB,UAAU;CACvD;CAED,OAAc,KACZC,QACAC,OAA2C,CAAE,GACR;EACrC,MAAM,QAAQ;AAEd,MAAI,kBAAkB,MAAM,EAAE;AAC5B,OAAI,KAAK,KAEP,OAAM,+EACD,MAAM,OACN,KAAK;AAGZ,UAAO;EACR;AACD,MAAI,oBAAoB,MAAM,CAC5B,QAAO,IAAI,gBAAgB,MAAM,MAAM,iFAClC,aACH,QAAQ;AAGZ,SAAO,IAAI,gBACT,2BAA2B,OAAO,gBAAgB,0EAE7C,aACI;CAGZ;AACF"} |
| const require_chunk = require('./chunk-DWy1uDak.cjs'); | ||
| const require_objectSpread2$1 = require('./objectSpread2-Bsvh_OqM.cjs'); | ||
| const __trpc_server_unstable_core_do_not_import = require_chunk.__toESM(require("@trpc/server/unstable-core-do-not-import")); | ||
| //#region src/TRPCClientError.ts | ||
| var import_defineProperty = require_chunk.__toESM(require_objectSpread2$1.require_defineProperty(), 1); | ||
| var import_objectSpread2 = require_chunk.__toESM(require_objectSpread2$1.require_objectSpread2(), 1); | ||
| function isTRPCClientError(cause) { | ||
| return cause instanceof TRPCClientError; | ||
| } | ||
| function isTRPCErrorResponse(obj) { | ||
| return (0, __trpc_server_unstable_core_do_not_import.isObject)(obj) && (0, __trpc_server_unstable_core_do_not_import.isObject)(obj["error"]) && typeof obj["error"]["code"] === "number" && typeof obj["error"]["message"] === "string"; | ||
| } | ||
| function getMessageFromUnknownError(err, fallback) { | ||
| if (typeof err === "string") return err; | ||
| if ((0, __trpc_server_unstable_core_do_not_import.isObject)(err) && typeof err["message"] === "string") return err["message"]; | ||
| return fallback; | ||
| } | ||
| var TRPCClientError = class TRPCClientError extends Error { | ||
| constructor(message, opts) { | ||
| var _opts$result, _opts$result2; | ||
| const cause = opts === null || opts === void 0 ? void 0 : opts.cause; | ||
| super(message, { cause }); | ||
| (0, import_defineProperty.default)(this, "cause", void 0); | ||
| (0, import_defineProperty.default)(this, "shape", void 0); | ||
| (0, import_defineProperty.default)(this, "data", void 0); | ||
| (0, import_defineProperty.default)(this, "meta", void 0); | ||
| this.meta = opts === null || opts === void 0 ? void 0 : opts.meta; | ||
| this.cause = cause; | ||
| this.shape = opts === null || opts === void 0 || (_opts$result = opts.result) === null || _opts$result === void 0 ? void 0 : _opts$result.error; | ||
| this.data = opts === null || opts === void 0 || (_opts$result2 = opts.result) === null || _opts$result2 === void 0 ? void 0 : _opts$result2.error.data; | ||
| this.name = "TRPCClientError"; | ||
| Object.setPrototypeOf(this, TRPCClientError.prototype); | ||
| } | ||
| static from(_cause, opts = {}) { | ||
| const cause = _cause; | ||
| if (isTRPCClientError(cause)) { | ||
| if (opts.meta) cause.meta = (0, import_objectSpread2.default)((0, import_objectSpread2.default)({}, cause.meta), opts.meta); | ||
| return cause; | ||
| } | ||
| if (isTRPCErrorResponse(cause)) return new TRPCClientError(cause.error.message, (0, import_objectSpread2.default)((0, import_objectSpread2.default)({}, opts), {}, { result: cause })); | ||
| return new TRPCClientError(getMessageFromUnknownError(cause, "Unknown error"), (0, import_objectSpread2.default)((0, import_objectSpread2.default)({}, opts), {}, { cause })); | ||
| } | ||
| }; | ||
| //#endregion | ||
| Object.defineProperty(exports, 'TRPCClientError', { | ||
| enumerable: true, | ||
| get: function () { | ||
| return TRPCClientError; | ||
| } | ||
| }); | ||
| Object.defineProperty(exports, 'isTRPCClientError', { | ||
| enumerable: true, | ||
| get: function () { | ||
| return isTRPCClientError; | ||
| } | ||
| }); |
| import { TRPCConnectionState } from "./subscriptions.d-Ciljg_dH.cjs"; | ||
| import { DefaultErrorShape, InferrableClientTypes, Maybe, TRPCErrorResponse, TRPCResultMessage, TRPCSuccessResponse, inferClientTypes } from "@trpc/server/unstable-core-do-not-import"; | ||
| import { Observable, Observer } from "@trpc/server/observable"; | ||
| //#region src/internals/types.d.ts | ||
| /** | ||
| * A subset of the standard fetch function type needed by tRPC internally. | ||
| * @see fetch from lib.dom.d.ts | ||
| * @remarks | ||
| * If you need a property that you know exists but doesn't exist on this | ||
| * interface, go ahead and add it. | ||
| */ | ||
| type FetchEsque = (input: RequestInfo | URL | string, init?: RequestInit | RequestInitEsque) => Promise<ResponseEsque>; | ||
| /** | ||
| * A simpler version of the native fetch function's type for packages with | ||
| * their own fetch types, such as undici and node-fetch. | ||
| */ | ||
| type NativeFetchEsque = (url: URL | string, init?: NodeFetchRequestInitEsque) => Promise<ResponseEsque>; | ||
| interface NodeFetchRequestInitEsque { | ||
| body?: string; | ||
| } | ||
| /** | ||
| * A subset of the standard RequestInit properties needed by tRPC internally. | ||
| * @see RequestInit from lib.dom.d.ts | ||
| * @remarks | ||
| * If you need a property that you know exists but doesn't exist on this | ||
| * interface, go ahead and add it. | ||
| */ | ||
| interface RequestInitEsque { | ||
| /** | ||
| * Sets the request's body. | ||
| */ | ||
| body?: FormData | string | null | Uint8Array<ArrayBuffer> | Blob | File; | ||
| /** | ||
| * Sets the request's associated headers. | ||
| */ | ||
| headers?: [string, string][] | Record<string, string>; | ||
| /** | ||
| * The request's HTTP-style method. | ||
| */ | ||
| method?: string; | ||
| /** | ||
| * Sets the request's signal. | ||
| */ | ||
| signal?: AbortSignal | undefined; | ||
| } | ||
| /** | ||
| * A subset of the standard ReadableStream properties needed by tRPC internally. | ||
| * @see ReadableStream from lib.dom.d.ts | ||
| */ | ||
| type WebReadableStreamEsque = { | ||
| getReader: () => ReadableStreamDefaultReader<Uint8Array>; | ||
| }; | ||
| type NodeJSReadableStreamEsque = { | ||
| on(eventName: string | symbol, listener: (...args: any[]) => void): NodeJSReadableStreamEsque; | ||
| }; | ||
| /** | ||
| * A subset of the standard Response properties needed by tRPC internally. | ||
| * @see Response from lib.dom.d.ts | ||
| */ | ||
| interface ResponseEsque { | ||
| readonly body?: NodeJSReadableStreamEsque | WebReadableStreamEsque | null; | ||
| /** | ||
| * @remarks | ||
| * The built-in Response::json() method returns Promise<any>, but | ||
| * that's not as type-safe as unknown. We use unknown because we're | ||
| * more type-safe. You do want more type safety, right? 😉 | ||
| */ | ||
| json(): Promise<unknown>; | ||
| } | ||
| /** | ||
| * @internal | ||
| */ | ||
| type NonEmptyArray<TItem> = [TItem, ...TItem[]]; | ||
| type ClientContext = Record<string, unknown>; | ||
| /** | ||
| * @public | ||
| */ | ||
| interface TRPCProcedureOptions { | ||
| /** | ||
| * Client-side context | ||
| */ | ||
| context?: ClientContext; | ||
| signal?: AbortSignal; | ||
| } | ||
| //#endregion | ||
| //#region src/TRPCClientError.d.ts | ||
| type inferErrorShape<TInferrable extends InferrableClientTypes> = inferClientTypes<TInferrable>['errorShape']; | ||
| interface TRPCClientErrorBase<TShape extends DefaultErrorShape> { | ||
| readonly message: string; | ||
| readonly shape: Maybe<TShape>; | ||
| readonly data: Maybe<TShape['data']>; | ||
| } | ||
| type TRPCClientErrorLike<TInferrable extends InferrableClientTypes> = TRPCClientErrorBase<inferErrorShape<TInferrable>>; | ||
| declare function isTRPCClientError<TInferrable extends InferrableClientTypes>(cause: unknown): cause is TRPCClientError<TInferrable>; | ||
| declare class TRPCClientError<TRouterOrProcedure extends InferrableClientTypes> extends Error implements TRPCClientErrorBase<inferErrorShape<TRouterOrProcedure>> { | ||
| readonly cause: Error | undefined; | ||
| readonly shape: Maybe<inferErrorShape<TRouterOrProcedure>>; | ||
| readonly data: Maybe<inferErrorShape<TRouterOrProcedure>['data']>; | ||
| /** | ||
| * Additional meta data about the error | ||
| * In the case of HTTP-errors, we'll have `response` and potentially `responseJSON` here | ||
| */ | ||
| meta: Record<string, unknown> | undefined; | ||
| constructor(message: string, opts?: { | ||
| result?: Maybe<TRPCErrorResponse<inferErrorShape<TRouterOrProcedure>>>; | ||
| cause?: Error; | ||
| meta?: Record<string, unknown>; | ||
| }); | ||
| static from<TRouterOrProcedure extends InferrableClientTypes>(_cause: Error | TRPCErrorResponse<any> | object, opts?: { | ||
| meta?: Record<string, unknown>; | ||
| }): TRPCClientError<TRouterOrProcedure>; | ||
| } | ||
| //#endregion | ||
| //#region src/links/internals/contentTypes.d.ts | ||
| declare function isOctetType(input: unknown): input is Uint8Array<ArrayBuffer> | Blob; | ||
| declare function isFormData(input: unknown): input is FormData; | ||
| declare function isNonJsonSerializable(input: unknown): input is Blob | FormData | Uint8Array<ArrayBuffer>; | ||
| //# sourceMappingURL=contentTypes.d.ts.map | ||
| //#endregion | ||
| //#region src/links/types.d.ts | ||
| /** | ||
| * @internal | ||
| */ | ||
| interface OperationContext extends Record<string, unknown> {} | ||
| /** | ||
| * @internal | ||
| */ | ||
| type Operation<TInput = unknown> = { | ||
| id: number; | ||
| type: 'mutation' | 'query' | 'subscription'; | ||
| input: TInput; | ||
| path: string; | ||
| context: OperationContext; | ||
| signal: Maybe<AbortSignal>; | ||
| }; | ||
| interface HeadersInitEsque { | ||
| [Symbol.iterator](): IterableIterator<[string, string]>; | ||
| } | ||
| /** | ||
| * @internal | ||
| */ | ||
| type HTTPHeaders = HeadersInitEsque | Record<string, string[] | string | undefined>; | ||
| /** | ||
| * The default `fetch` implementation has an overloaded signature. By convention this library | ||
| * only uses the overload taking a string and options object. | ||
| */ | ||
| type TRPCFetch = (url: string, options?: RequestInit) => Promise<ResponseEsque>; | ||
| interface TRPCClientRuntime {} | ||
| /** | ||
| * @internal | ||
| */ | ||
| interface OperationResultEnvelope<TOutput, TError> { | ||
| result: TRPCResultMessage<TOutput>['result'] | TRPCSuccessResponse<TOutput>['result'] | TRPCConnectionState<TError>; | ||
| context?: OperationContext; | ||
| } | ||
| /** | ||
| * @internal | ||
| */ | ||
| type OperationResultObservable<TInferrable extends InferrableClientTypes, TOutput> = Observable<OperationResultEnvelope<TOutput, TRPCClientError<TInferrable>>, TRPCClientError<TInferrable>>; | ||
| /** | ||
| * @internal | ||
| */ | ||
| type OperationResultObserver<TInferrable extends InferrableClientTypes, TOutput> = Observer<OperationResultEnvelope<TOutput, TRPCClientError<TInferrable>>, TRPCClientError<TInferrable>>; | ||
| /** | ||
| * @internal | ||
| */ | ||
| type OperationLink<TInferrable extends InferrableClientTypes, TInput = unknown, TOutput = unknown> = (opts: { | ||
| op: Operation<TInput>; | ||
| next: (op: Operation<TInput>) => OperationResultObservable<TInferrable, TOutput>; | ||
| }) => OperationResultObservable<TInferrable, TOutput>; | ||
| /** | ||
| * @public | ||
| */ | ||
| type TRPCLink<TInferrable extends InferrableClientTypes> = (opts: TRPCClientRuntime) => OperationLink<TInferrable>; | ||
| //# sourceMappingURL=types.d.ts.map | ||
| //#endregion | ||
| export { FetchEsque, HTTPHeaders, NativeFetchEsque, NonEmptyArray, Operation, OperationContext, OperationLink, OperationResultEnvelope, OperationResultObservable, OperationResultObserver, TRPCClientError, TRPCClientErrorBase, TRPCClientErrorLike, TRPCClientRuntime, TRPCFetch, TRPCLink, TRPCProcedureOptions, isFormData, isNonJsonSerializable, isOctetType, isTRPCClientError }; | ||
| //# sourceMappingURL=types.d-B2PuQAdV.d.cts.map |
| {"version":3,"file":"types.d-B2PuQAdV.d.cts","names":[],"sources":["../src/internals/types.ts","../src/TRPCClientError.ts","../src/links/internals/contentTypes.ts","../src/links/types.ts"],"sourcesContent":[],"mappings":"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"} |
| import { TRPCConnectionState } from "./subscriptions.d-Dlr1nWGD.mjs"; | ||
| import { Observable, Observer } from "@trpc/server/observable"; | ||
| import { DefaultErrorShape, InferrableClientTypes, Maybe, TRPCErrorResponse, TRPCResultMessage, TRPCSuccessResponse, inferClientTypes } from "@trpc/server/unstable-core-do-not-import"; | ||
| //#region src/internals/types.d.ts | ||
| /** | ||
| * A subset of the standard fetch function type needed by tRPC internally. | ||
| * @see fetch from lib.dom.d.ts | ||
| * @remarks | ||
| * If you need a property that you know exists but doesn't exist on this | ||
| * interface, go ahead and add it. | ||
| */ | ||
| type FetchEsque = (input: RequestInfo | URL | string, init?: RequestInit | RequestInitEsque) => Promise<ResponseEsque>; | ||
| /** | ||
| * A simpler version of the native fetch function's type for packages with | ||
| * their own fetch types, such as undici and node-fetch. | ||
| */ | ||
| type NativeFetchEsque = (url: URL | string, init?: NodeFetchRequestInitEsque) => Promise<ResponseEsque>; | ||
| interface NodeFetchRequestInitEsque { | ||
| body?: string; | ||
| } | ||
| /** | ||
| * A subset of the standard RequestInit properties needed by tRPC internally. | ||
| * @see RequestInit from lib.dom.d.ts | ||
| * @remarks | ||
| * If you need a property that you know exists but doesn't exist on this | ||
| * interface, go ahead and add it. | ||
| */ | ||
| interface RequestInitEsque { | ||
| /** | ||
| * Sets the request's body. | ||
| */ | ||
| body?: FormData | string | null | Uint8Array<ArrayBuffer> | Blob | File; | ||
| /** | ||
| * Sets the request's associated headers. | ||
| */ | ||
| headers?: [string, string][] | Record<string, string>; | ||
| /** | ||
| * The request's HTTP-style method. | ||
| */ | ||
| method?: string; | ||
| /** | ||
| * Sets the request's signal. | ||
| */ | ||
| signal?: AbortSignal | undefined; | ||
| } | ||
| /** | ||
| * A subset of the standard ReadableStream properties needed by tRPC internally. | ||
| * @see ReadableStream from lib.dom.d.ts | ||
| */ | ||
| type WebReadableStreamEsque = { | ||
| getReader: () => ReadableStreamDefaultReader<Uint8Array>; | ||
| }; | ||
| type NodeJSReadableStreamEsque = { | ||
| on(eventName: string | symbol, listener: (...args: any[]) => void): NodeJSReadableStreamEsque; | ||
| }; | ||
| /** | ||
| * A subset of the standard Response properties needed by tRPC internally. | ||
| * @see Response from lib.dom.d.ts | ||
| */ | ||
| interface ResponseEsque { | ||
| readonly body?: NodeJSReadableStreamEsque | WebReadableStreamEsque | null; | ||
| /** | ||
| * @remarks | ||
| * The built-in Response::json() method returns Promise<any>, but | ||
| * that's not as type-safe as unknown. We use unknown because we're | ||
| * more type-safe. You do want more type safety, right? 😉 | ||
| */ | ||
| json(): Promise<unknown>; | ||
| } | ||
| /** | ||
| * @internal | ||
| */ | ||
| type NonEmptyArray<TItem> = [TItem, ...TItem[]]; | ||
| type ClientContext = Record<string, unknown>; | ||
| /** | ||
| * @public | ||
| */ | ||
| interface TRPCProcedureOptions { | ||
| /** | ||
| * Client-side context | ||
| */ | ||
| context?: ClientContext; | ||
| signal?: AbortSignal; | ||
| } | ||
| //#endregion | ||
| //#region src/TRPCClientError.d.ts | ||
| type inferErrorShape<TInferrable extends InferrableClientTypes> = inferClientTypes<TInferrable>['errorShape']; | ||
| interface TRPCClientErrorBase<TShape extends DefaultErrorShape> { | ||
| readonly message: string; | ||
| readonly shape: Maybe<TShape>; | ||
| readonly data: Maybe<TShape['data']>; | ||
| } | ||
| type TRPCClientErrorLike<TInferrable extends InferrableClientTypes> = TRPCClientErrorBase<inferErrorShape<TInferrable>>; | ||
| declare function isTRPCClientError<TInferrable extends InferrableClientTypes>(cause: unknown): cause is TRPCClientError<TInferrable>; | ||
| declare class TRPCClientError<TRouterOrProcedure extends InferrableClientTypes> extends Error implements TRPCClientErrorBase<inferErrorShape<TRouterOrProcedure>> { | ||
| readonly cause: Error | undefined; | ||
| readonly shape: Maybe<inferErrorShape<TRouterOrProcedure>>; | ||
| readonly data: Maybe<inferErrorShape<TRouterOrProcedure>['data']>; | ||
| /** | ||
| * Additional meta data about the error | ||
| * In the case of HTTP-errors, we'll have `response` and potentially `responseJSON` here | ||
| */ | ||
| meta: Record<string, unknown> | undefined; | ||
| constructor(message: string, opts?: { | ||
| result?: Maybe<TRPCErrorResponse<inferErrorShape<TRouterOrProcedure>>>; | ||
| cause?: Error; | ||
| meta?: Record<string, unknown>; | ||
| }); | ||
| static from<TRouterOrProcedure extends InferrableClientTypes>(_cause: Error | TRPCErrorResponse<any> | object, opts?: { | ||
| meta?: Record<string, unknown>; | ||
| }): TRPCClientError<TRouterOrProcedure>; | ||
| } | ||
| //#endregion | ||
| //#region src/links/internals/contentTypes.d.ts | ||
| declare function isOctetType(input: unknown): input is Uint8Array<ArrayBuffer> | Blob; | ||
| declare function isFormData(input: unknown): input is FormData; | ||
| declare function isNonJsonSerializable(input: unknown): input is Blob | FormData | Uint8Array<ArrayBuffer>; | ||
| //# sourceMappingURL=contentTypes.d.ts.map | ||
| //#endregion | ||
| //#region src/links/types.d.ts | ||
| /** | ||
| * @internal | ||
| */ | ||
| interface OperationContext extends Record<string, unknown> {} | ||
| /** | ||
| * @internal | ||
| */ | ||
| type Operation<TInput = unknown> = { | ||
| id: number; | ||
| type: 'mutation' | 'query' | 'subscription'; | ||
| input: TInput; | ||
| path: string; | ||
| context: OperationContext; | ||
| signal: Maybe<AbortSignal>; | ||
| }; | ||
| interface HeadersInitEsque { | ||
| [Symbol.iterator](): IterableIterator<[string, string]>; | ||
| } | ||
| /** | ||
| * @internal | ||
| */ | ||
| type HTTPHeaders = HeadersInitEsque | Record<string, string[] | string | undefined>; | ||
| /** | ||
| * The default `fetch` implementation has an overloaded signature. By convention this library | ||
| * only uses the overload taking a string and options object. | ||
| */ | ||
| type TRPCFetch = (url: string, options?: RequestInit) => Promise<ResponseEsque>; | ||
| interface TRPCClientRuntime {} | ||
| /** | ||
| * @internal | ||
| */ | ||
| interface OperationResultEnvelope<TOutput, TError> { | ||
| result: TRPCResultMessage<TOutput>['result'] | TRPCSuccessResponse<TOutput>['result'] | TRPCConnectionState<TError>; | ||
| context?: OperationContext; | ||
| } | ||
| /** | ||
| * @internal | ||
| */ | ||
| type OperationResultObservable<TInferrable extends InferrableClientTypes, TOutput> = Observable<OperationResultEnvelope<TOutput, TRPCClientError<TInferrable>>, TRPCClientError<TInferrable>>; | ||
| /** | ||
| * @internal | ||
| */ | ||
| type OperationResultObserver<TInferrable extends InferrableClientTypes, TOutput> = Observer<OperationResultEnvelope<TOutput, TRPCClientError<TInferrable>>, TRPCClientError<TInferrable>>; | ||
| /** | ||
| * @internal | ||
| */ | ||
| type OperationLink<TInferrable extends InferrableClientTypes, TInput = unknown, TOutput = unknown> = (opts: { | ||
| op: Operation<TInput>; | ||
| next: (op: Operation<TInput>) => OperationResultObservable<TInferrable, TOutput>; | ||
| }) => OperationResultObservable<TInferrable, TOutput>; | ||
| /** | ||
| * @public | ||
| */ | ||
| type TRPCLink<TInferrable extends InferrableClientTypes> = (opts: TRPCClientRuntime) => OperationLink<TInferrable>; | ||
| //# sourceMappingURL=types.d.ts.map | ||
| //#endregion | ||
| export { FetchEsque, HTTPHeaders, NativeFetchEsque, NonEmptyArray, Operation, OperationContext, OperationLink, OperationResultEnvelope, OperationResultObservable, OperationResultObserver, TRPCClientError, TRPCClientErrorBase, TRPCClientErrorLike, TRPCClientRuntime, TRPCFetch, TRPCLink, TRPCProcedureOptions, isFormData, isNonJsonSerializable, isOctetType, isTRPCClientError }; | ||
| //# sourceMappingURL=types.d-CAt1zKAY.d.mts.map |
| {"version":3,"file":"types.d-CAt1zKAY.d.mts","names":[],"sources":["../src/internals/types.ts","../src/TRPCClientError.ts","../src/links/internals/contentTypes.ts","../src/links/types.ts"],"sourcesContent":[],"mappings":"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"} |
| const require_chunk = require('./chunk-DWy1uDak.cjs'); | ||
| const require_objectSpread2$1 = require('./objectSpread2-Bsvh_OqM.cjs'); | ||
| const require_TRPCClientError = require('./TRPCClientError-Dey88Uiy.cjs'); | ||
| const require_unstable_internals = require('./unstable-internals-M84gUQCV.cjs'); | ||
| const __trpc_server_observable = require_chunk.__toESM(require("@trpc/server/observable")); | ||
| const __trpc_server_unstable_core_do_not_import = require_chunk.__toESM(require("@trpc/server/unstable-core-do-not-import")); | ||
| //#region src/links/wsLink/wsClient/encoder.ts | ||
| const jsonEncoder = { | ||
| encode: (data) => JSON.stringify(data), | ||
| decode: (data) => { | ||
| if (typeof data !== "string") throw new Error("jsonEncoder received binary data. JSON uses text frames. Use a binary encoder for binary data."); | ||
| return JSON.parse(data); | ||
| } | ||
| }; | ||
| //#endregion | ||
| //#region src/links/wsLink/wsClient/options.ts | ||
| const lazyDefaults = { | ||
| enabled: false, | ||
| closeMs: 0 | ||
| }; | ||
| const keepAliveDefaults = { | ||
| enabled: false, | ||
| pongTimeoutMs: 1e3, | ||
| intervalMs: 5e3 | ||
| }; | ||
| /** | ||
| * Calculates a delay for exponential backoff based on the retry attempt index. | ||
| * The delay starts at 0 for the first attempt and doubles for each subsequent attempt, | ||
| * capped at 30 seconds. | ||
| */ | ||
| const exponentialBackoff = (attemptIndex) => { | ||
| return attemptIndex === 0 ? 0 : Math.min(1e3 * 2 ** attemptIndex, 3e4); | ||
| }; | ||
| //#endregion | ||
| //#region src/links/internals/urlWithConnectionParams.ts | ||
| /** | ||
| * Get the result of a value or function that returns a value | ||
| * It also optionally accepts typesafe arguments for the function | ||
| */ | ||
| const resultOf = (value, ...args) => { | ||
| return typeof value === "function" ? value(...args) : value; | ||
| }; | ||
| //#endregion | ||
| //#region src/links/wsLink/wsClient/utils.ts | ||
| var import_defineProperty$3 = require_chunk.__toESM(require_objectSpread2$1.require_defineProperty(), 1); | ||
| var TRPCWebSocketClosedError = class TRPCWebSocketClosedError extends Error { | ||
| constructor(opts) { | ||
| super(opts.message, { cause: opts.cause }); | ||
| this.name = "TRPCWebSocketClosedError"; | ||
| Object.setPrototypeOf(this, TRPCWebSocketClosedError.prototype); | ||
| } | ||
| }; | ||
| /** | ||
| * Utility class for managing a timeout that can be started, stopped, and reset. | ||
| * Useful for scenarios where the timeout duration is reset dynamically based on events. | ||
| */ | ||
| var ResettableTimeout = class { | ||
| constructor(onTimeout, timeoutMs) { | ||
| this.onTimeout = onTimeout; | ||
| this.timeoutMs = timeoutMs; | ||
| (0, import_defineProperty$3.default)(this, "timeout", void 0); | ||
| } | ||
| /** | ||
| * Resets the current timeout, restarting it with the same duration. | ||
| * Does nothing if no timeout is active. | ||
| */ | ||
| reset() { | ||
| if (!this.timeout) return; | ||
| clearTimeout(this.timeout); | ||
| this.timeout = setTimeout(this.onTimeout, this.timeoutMs); | ||
| } | ||
| start() { | ||
| clearTimeout(this.timeout); | ||
| this.timeout = setTimeout(this.onTimeout, this.timeoutMs); | ||
| } | ||
| stop() { | ||
| clearTimeout(this.timeout); | ||
| this.timeout = void 0; | ||
| } | ||
| }; | ||
| function withResolvers() { | ||
| let resolve; | ||
| let reject; | ||
| const promise = new Promise((res, rej) => { | ||
| resolve = res; | ||
| reject = rej; | ||
| }); | ||
| return { | ||
| promise, | ||
| resolve, | ||
| reject | ||
| }; | ||
| } | ||
| /** | ||
| * Resolves a WebSocket URL and optionally appends connection parameters. | ||
| * | ||
| * If connectionParams are provided, appends 'connectionParams=1' query parameter. | ||
| */ | ||
| async function prepareUrl(urlOptions) { | ||
| const url = await resultOf(urlOptions.url); | ||
| if (!urlOptions.connectionParams) return url; | ||
| const prefix = url.includes("?") ? "&" : "?"; | ||
| const connectionParams = `${prefix}connectionParams=1`; | ||
| return url + connectionParams; | ||
| } | ||
| async function buildConnectionMessage(connectionParams) { | ||
| const message = { | ||
| method: "connectionParams", | ||
| data: await resultOf(connectionParams) | ||
| }; | ||
| return JSON.stringify(message); | ||
| } | ||
| //#endregion | ||
| //#region src/links/wsLink/wsClient/requestManager.ts | ||
| var import_defineProperty$2 = require_chunk.__toESM(require_objectSpread2$1.require_defineProperty(), 1); | ||
| /** | ||
| * Manages WebSocket requests, tracking their lifecycle and providing utility methods | ||
| * for handling outgoing and pending requests. | ||
| * | ||
| * - **Outgoing requests**: Requests that are queued and waiting to be sent. | ||
| * - **Pending requests**: Requests that have been sent and are in flight awaiting a response. | ||
| * For subscriptions, multiple responses may be received until the subscription is closed. | ||
| */ | ||
| var RequestManager = class { | ||
| constructor() { | ||
| (0, import_defineProperty$2.default)(this, "outgoingRequests", new Array()); | ||
| (0, import_defineProperty$2.default)(this, "pendingRequests", {}); | ||
| } | ||
| /** | ||
| * Registers a new request by adding it to the outgoing queue and setting up | ||
| * callbacks for lifecycle events such as completion or error. | ||
| * | ||
| * @param message - The outgoing message to be sent. | ||
| * @param callbacks - Callback functions to observe the request's state. | ||
| * @returns A cleanup function to manually remove the request. | ||
| */ | ||
| register(message, callbacks) { | ||
| const { promise: end, resolve } = withResolvers(); | ||
| this.outgoingRequests.push({ | ||
| id: String(message.id), | ||
| message, | ||
| end, | ||
| callbacks: { | ||
| next: callbacks.next, | ||
| complete: () => { | ||
| callbacks.complete(); | ||
| resolve(); | ||
| }, | ||
| error: (e) => { | ||
| callbacks.error(e); | ||
| resolve(); | ||
| } | ||
| } | ||
| }); | ||
| return () => { | ||
| this.delete(message.id); | ||
| callbacks.complete(); | ||
| resolve(); | ||
| }; | ||
| } | ||
| /** | ||
| * Deletes a request from both the outgoing and pending collections, if it exists. | ||
| */ | ||
| delete(messageId) { | ||
| if (messageId === null) return; | ||
| this.outgoingRequests = this.outgoingRequests.filter(({ id }) => id !== String(messageId)); | ||
| delete this.pendingRequests[String(messageId)]; | ||
| } | ||
| /** | ||
| * Moves all outgoing requests to the pending state and clears the outgoing queue. | ||
| * | ||
| * The caller is expected to handle the actual sending of the requests | ||
| * (e.g., sending them over the network) after this method is called. | ||
| * | ||
| * @returns The list of requests that were transitioned to the pending state. | ||
| */ | ||
| flush() { | ||
| const requests = this.outgoingRequests; | ||
| this.outgoingRequests = []; | ||
| for (const request of requests) this.pendingRequests[request.id] = request; | ||
| return requests; | ||
| } | ||
| /** | ||
| * Retrieves all currently pending requests, which are in flight awaiting responses | ||
| * or handling ongoing subscriptions. | ||
| */ | ||
| getPendingRequests() { | ||
| return Object.values(this.pendingRequests); | ||
| } | ||
| /** | ||
| * Retrieves a specific pending request by its message ID. | ||
| */ | ||
| getPendingRequest(messageId) { | ||
| if (messageId === null) return null; | ||
| return this.pendingRequests[String(messageId)]; | ||
| } | ||
| /** | ||
| * Retrieves all outgoing requests, which are waiting to be sent. | ||
| */ | ||
| getOutgoingRequests() { | ||
| return this.outgoingRequests; | ||
| } | ||
| /** | ||
| * Retrieves all requests, both outgoing and pending, with their respective states. | ||
| * | ||
| * @returns An array of all requests with their state ("outgoing" or "pending"). | ||
| */ | ||
| getRequests() { | ||
| return [...this.getOutgoingRequests().map((request) => ({ | ||
| state: "outgoing", | ||
| message: request.message, | ||
| end: request.end, | ||
| callbacks: request.callbacks | ||
| })), ...this.getPendingRequests().map((request) => ({ | ||
| state: "pending", | ||
| message: request.message, | ||
| end: request.end, | ||
| callbacks: request.callbacks | ||
| }))]; | ||
| } | ||
| /** | ||
| * Checks if there are any pending requests, including ongoing subscriptions. | ||
| */ | ||
| hasPendingRequests() { | ||
| return this.getPendingRequests().length > 0; | ||
| } | ||
| /** | ||
| * Checks if there are any pending subscriptions | ||
| */ | ||
| hasPendingSubscriptions() { | ||
| return this.getPendingRequests().some((request) => request.message.method === "subscription"); | ||
| } | ||
| /** | ||
| * Checks if there are any outgoing requests waiting to be sent. | ||
| */ | ||
| hasOutgoingRequests() { | ||
| return this.outgoingRequests.length > 0; | ||
| } | ||
| }; | ||
| //#endregion | ||
| //#region src/links/wsLink/wsClient/wsConnection.ts | ||
| var import_defineProperty$1 = require_chunk.__toESM(require_objectSpread2$1.require_defineProperty(), 1); | ||
| /** | ||
| * Opens a WebSocket connection asynchronously and returns a promise | ||
| * that resolves when the connection is successfully established. | ||
| * The promise rejects if an error occurs during the connection attempt. | ||
| */ | ||
| function asyncWsOpen(ws) { | ||
| const { promise, resolve, reject } = withResolvers(); | ||
| ws.addEventListener("open", () => { | ||
| ws.removeEventListener("error", reject); | ||
| resolve(); | ||
| }); | ||
| ws.addEventListener("error", reject); | ||
| return promise; | ||
| } | ||
| /** | ||
| * Sets up a periodic ping-pong mechanism to keep the WebSocket connection alive. | ||
| * | ||
| * - Sends "PING" messages at regular intervals defined by `intervalMs`. | ||
| * - If a "PONG" response is not received within the `pongTimeoutMs`, the WebSocket is closed. | ||
| * - The ping timer resets upon receiving any message to maintain activity. | ||
| * - Automatically starts the ping process when the WebSocket connection is opened. | ||
| * - Cleans up timers when the WebSocket is closed. | ||
| * | ||
| * @param ws - The WebSocket instance to manage. | ||
| * @param options - Configuration options for ping-pong intervals and timeouts. | ||
| */ | ||
| function setupPingInterval(ws, { intervalMs, pongTimeoutMs }) { | ||
| let pingTimeout; | ||
| let pongTimeout; | ||
| function start() { | ||
| pingTimeout = setTimeout(() => { | ||
| ws.send("PING"); | ||
| pongTimeout = setTimeout(() => { | ||
| ws.close(); | ||
| }, pongTimeoutMs); | ||
| }, intervalMs); | ||
| } | ||
| function reset() { | ||
| clearTimeout(pingTimeout); | ||
| start(); | ||
| } | ||
| function pong() { | ||
| clearTimeout(pongTimeout); | ||
| reset(); | ||
| } | ||
| ws.addEventListener("open", start); | ||
| ws.addEventListener("message", ({ data }) => { | ||
| clearTimeout(pingTimeout); | ||
| start(); | ||
| if (data === "PONG") pong(); | ||
| }); | ||
| ws.addEventListener("close", () => { | ||
| clearTimeout(pingTimeout); | ||
| clearTimeout(pongTimeout); | ||
| }); | ||
| } | ||
| /** | ||
| * Manages a WebSocket connection with support for reconnection, keep-alive mechanisms, | ||
| * and observable state tracking. | ||
| */ | ||
| var WsConnection = class WsConnection { | ||
| constructor(opts) { | ||
| var _opts$WebSocketPonyfi; | ||
| (0, import_defineProperty$1.default)(this, "id", ++WsConnection.connectCount); | ||
| (0, import_defineProperty$1.default)(this, "WebSocketPonyfill", void 0); | ||
| (0, import_defineProperty$1.default)(this, "urlOptions", void 0); | ||
| (0, import_defineProperty$1.default)(this, "keepAliveOpts", void 0); | ||
| (0, import_defineProperty$1.default)(this, "wsObservable", (0, __trpc_server_observable.behaviorSubject)(null)); | ||
| (0, import_defineProperty$1.default)(this, "openPromise", null); | ||
| this.WebSocketPonyfill = (_opts$WebSocketPonyfi = opts.WebSocketPonyfill) !== null && _opts$WebSocketPonyfi !== void 0 ? _opts$WebSocketPonyfi : WebSocket; | ||
| if (!this.WebSocketPonyfill) throw new Error("No WebSocket implementation found - you probably don't want to use this on the server, but if you do you need to pass a `WebSocket`-ponyfill"); | ||
| this.urlOptions = opts.urlOptions; | ||
| this.keepAliveOpts = opts.keepAlive; | ||
| } | ||
| get ws() { | ||
| return this.wsObservable.get(); | ||
| } | ||
| set ws(ws) { | ||
| this.wsObservable.next(ws); | ||
| } | ||
| /** | ||
| * Checks if the WebSocket connection is open and ready to communicate. | ||
| */ | ||
| isOpen() { | ||
| return !!this.ws && this.ws.readyState === this.WebSocketPonyfill.OPEN && !this.openPromise; | ||
| } | ||
| /** | ||
| * Checks if the WebSocket connection is closed or in the process of closing. | ||
| */ | ||
| isClosed() { | ||
| return !!this.ws && (this.ws.readyState === this.WebSocketPonyfill.CLOSING || this.ws.readyState === this.WebSocketPonyfill.CLOSED); | ||
| } | ||
| async open() { | ||
| var _this = this; | ||
| if (_this.openPromise) return _this.openPromise; | ||
| _this.id = ++WsConnection.connectCount; | ||
| const wsPromise = prepareUrl(_this.urlOptions).then((url) => new _this.WebSocketPonyfill(url)); | ||
| _this.openPromise = wsPromise.then(async (ws) => { | ||
| _this.ws = ws; | ||
| ws.binaryType = "arraybuffer"; | ||
| ws.addEventListener("message", function({ data }) { | ||
| if (data === "PING") this.send("PONG"); | ||
| }); | ||
| if (_this.keepAliveOpts.enabled) setupPingInterval(ws, _this.keepAliveOpts); | ||
| ws.addEventListener("close", () => { | ||
| if (_this.ws === ws) _this.ws = null; | ||
| }); | ||
| await asyncWsOpen(ws); | ||
| if (_this.urlOptions.connectionParams) ws.send(await buildConnectionMessage(_this.urlOptions.connectionParams)); | ||
| }); | ||
| try { | ||
| await _this.openPromise; | ||
| } finally { | ||
| _this.openPromise = null; | ||
| } | ||
| } | ||
| /** | ||
| * Closes the WebSocket connection gracefully. | ||
| * Waits for any ongoing open operation to complete before closing. | ||
| */ | ||
| async close() { | ||
| var _this2 = this; | ||
| try { | ||
| await _this2.openPromise; | ||
| } finally { | ||
| var _this$ws; | ||
| (_this$ws = _this2.ws) === null || _this$ws === void 0 || _this$ws.close(); | ||
| } | ||
| } | ||
| }; | ||
| (0, import_defineProperty$1.default)(WsConnection, "connectCount", 0); | ||
| /** | ||
| * Provides a backward-compatible representation of the connection state. | ||
| */ | ||
| function backwardCompatibility(connection) { | ||
| if (connection.isOpen()) return { | ||
| id: connection.id, | ||
| state: "open", | ||
| ws: connection.ws | ||
| }; | ||
| if (connection.isClosed()) return { | ||
| id: connection.id, | ||
| state: "closed", | ||
| ws: connection.ws | ||
| }; | ||
| if (!connection.ws) return null; | ||
| return { | ||
| id: connection.id, | ||
| state: "connecting", | ||
| ws: connection.ws | ||
| }; | ||
| } | ||
| //#endregion | ||
| //#region src/links/wsLink/wsClient/wsClient.ts | ||
| var import_defineProperty = require_chunk.__toESM(require_objectSpread2$1.require_defineProperty(), 1); | ||
| var import_objectSpread2 = require_chunk.__toESM(require_objectSpread2$1.require_objectSpread2(), 1); | ||
| /** | ||
| * A WebSocket client for managing TRPC operations, supporting lazy initialization, | ||
| * reconnection, keep-alive, and request management. | ||
| */ | ||
| var WsClient = class { | ||
| constructor(opts) { | ||
| var _opts$experimental_en, _opts$retryDelayMs; | ||
| (0, import_defineProperty.default)(this, "connectionState", void 0); | ||
| (0, import_defineProperty.default)(this, "allowReconnect", false); | ||
| (0, import_defineProperty.default)(this, "requestManager", new RequestManager()); | ||
| (0, import_defineProperty.default)(this, "activeConnection", void 0); | ||
| (0, import_defineProperty.default)(this, "reconnectRetryDelay", void 0); | ||
| (0, import_defineProperty.default)(this, "inactivityTimeout", void 0); | ||
| (0, import_defineProperty.default)(this, "callbacks", void 0); | ||
| (0, import_defineProperty.default)(this, "lazyMode", void 0); | ||
| (0, import_defineProperty.default)(this, "encoder", void 0); | ||
| (0, import_defineProperty.default)(this, "reconnecting", null); | ||
| this.encoder = (_opts$experimental_en = opts.experimental_encoder) !== null && _opts$experimental_en !== void 0 ? _opts$experimental_en : jsonEncoder; | ||
| this.callbacks = { | ||
| onOpen: opts.onOpen, | ||
| onClose: opts.onClose, | ||
| onError: opts.onError | ||
| }; | ||
| const lazyOptions = (0, import_objectSpread2.default)((0, import_objectSpread2.default)({}, lazyDefaults), opts.lazy); | ||
| this.inactivityTimeout = new ResettableTimeout(() => { | ||
| if (this.requestManager.hasOutgoingRequests() || this.requestManager.hasPendingRequests()) { | ||
| this.inactivityTimeout.reset(); | ||
| return; | ||
| } | ||
| this.close().catch(() => null); | ||
| }, lazyOptions.closeMs); | ||
| this.activeConnection = new WsConnection({ | ||
| WebSocketPonyfill: opts.WebSocket, | ||
| urlOptions: opts, | ||
| keepAlive: (0, import_objectSpread2.default)((0, import_objectSpread2.default)({}, keepAliveDefaults), opts.keepAlive) | ||
| }); | ||
| this.activeConnection.wsObservable.subscribe({ next: (ws) => { | ||
| if (!ws) return; | ||
| this.setupWebSocketListeners(ws); | ||
| } }); | ||
| this.reconnectRetryDelay = (_opts$retryDelayMs = opts.retryDelayMs) !== null && _opts$retryDelayMs !== void 0 ? _opts$retryDelayMs : exponentialBackoff; | ||
| this.lazyMode = lazyOptions.enabled; | ||
| this.connectionState = (0, __trpc_server_observable.behaviorSubject)({ | ||
| type: "state", | ||
| state: lazyOptions.enabled ? "idle" : "connecting", | ||
| error: null | ||
| }); | ||
| if (!this.lazyMode) this.open().catch(() => null); | ||
| } | ||
| /** | ||
| * Opens the WebSocket connection. Handles reconnection attempts and updates | ||
| * the connection state accordingly. | ||
| */ | ||
| async open() { | ||
| var _this = this; | ||
| _this.allowReconnect = true; | ||
| if (_this.connectionState.get().state === "idle") _this.connectionState.next({ | ||
| type: "state", | ||
| state: "connecting", | ||
| error: null | ||
| }); | ||
| try { | ||
| await _this.activeConnection.open(); | ||
| } catch (error) { | ||
| _this.reconnect(new TRPCWebSocketClosedError({ | ||
| message: "Initialization error", | ||
| cause: error | ||
| })); | ||
| return _this.reconnecting; | ||
| } | ||
| } | ||
| /** | ||
| * Closes the WebSocket connection and stops managing requests. | ||
| * Ensures all outgoing and pending requests are properly finalized. | ||
| */ | ||
| async close() { | ||
| var _this2 = this; | ||
| _this2.allowReconnect = false; | ||
| _this2.inactivityTimeout.stop(); | ||
| const requestsToAwait = []; | ||
| for (const request of _this2.requestManager.getRequests()) if (request.message.method === "subscription") request.callbacks.complete(); | ||
| else if (request.state === "outgoing") request.callbacks.error(require_TRPCClientError.TRPCClientError.from(new TRPCWebSocketClosedError({ message: "Closed before connection was established" }))); | ||
| else requestsToAwait.push(request.end); | ||
| await Promise.all(requestsToAwait).catch(() => null); | ||
| await _this2.activeConnection.close().catch(() => null); | ||
| _this2.connectionState.next({ | ||
| type: "state", | ||
| state: "idle", | ||
| error: null | ||
| }); | ||
| } | ||
| /** | ||
| * Method to request the server. | ||
| * Handles data transformation, batching of requests, and subscription lifecycle. | ||
| * | ||
| * @param op - The operation details including id, type, path, input and signal | ||
| * @param transformer - Data transformer for serializing requests and deserializing responses | ||
| * @param lastEventId - Optional ID of the last received event for subscriptions | ||
| * | ||
| * @returns An observable that emits operation results and handles cleanup | ||
| */ | ||
| request({ op: { id, type, path, input, signal }, transformer, lastEventId }) { | ||
| return (0, __trpc_server_observable.observable)((observer) => { | ||
| const abort = this.batchSend({ | ||
| id, | ||
| method: type, | ||
| params: { | ||
| input: transformer.input.serialize(input), | ||
| path, | ||
| lastEventId | ||
| } | ||
| }, (0, import_objectSpread2.default)((0, import_objectSpread2.default)({}, observer), {}, { next(event) { | ||
| const transformed = (0, __trpc_server_unstable_core_do_not_import.transformResult)(event, transformer.output); | ||
| if (!transformed.ok) { | ||
| observer.error(require_TRPCClientError.TRPCClientError.from(transformed.error)); | ||
| return; | ||
| } | ||
| observer.next({ result: transformed.result }); | ||
| } })); | ||
| return () => { | ||
| abort(); | ||
| if (type === "subscription" && this.activeConnection.isOpen()) this.send({ | ||
| id, | ||
| method: "subscription.stop" | ||
| }); | ||
| signal === null || signal === void 0 || signal.removeEventListener("abort", abort); | ||
| }; | ||
| }); | ||
| } | ||
| get connection() { | ||
| return backwardCompatibility(this.activeConnection); | ||
| } | ||
| reconnect(closedError) { | ||
| var _this3 = this; | ||
| this.connectionState.next({ | ||
| type: "state", | ||
| state: "connecting", | ||
| error: require_TRPCClientError.TRPCClientError.from(closedError) | ||
| }); | ||
| if (this.reconnecting) return; | ||
| const tryReconnect = async (attemptIndex) => { | ||
| try { | ||
| await (0, __trpc_server_unstable_core_do_not_import.sleep)(_this3.reconnectRetryDelay(attemptIndex)); | ||
| if (_this3.allowReconnect) { | ||
| await _this3.activeConnection.close(); | ||
| await _this3.activeConnection.open(); | ||
| if (_this3.requestManager.hasPendingRequests()) _this3.send(_this3.requestManager.getPendingRequests().map(({ message }) => message)); | ||
| } | ||
| _this3.reconnecting = null; | ||
| } catch (_unused) { | ||
| await tryReconnect(attemptIndex + 1); | ||
| } | ||
| }; | ||
| this.reconnecting = tryReconnect(0); | ||
| } | ||
| setupWebSocketListeners(ws) { | ||
| var _this4 = this; | ||
| const handleCloseOrError = (cause) => { | ||
| const reqs = this.requestManager.getPendingRequests(); | ||
| for (const { message, callbacks } of reqs) { | ||
| if (message.method === "subscription") continue; | ||
| callbacks.error(require_TRPCClientError.TRPCClientError.from(cause !== null && cause !== void 0 ? cause : new TRPCWebSocketClosedError({ | ||
| message: "WebSocket closed", | ||
| cause | ||
| }))); | ||
| this.requestManager.delete(message.id); | ||
| } | ||
| }; | ||
| ws.addEventListener("open", () => { | ||
| (0, __trpc_server_unstable_core_do_not_import.run)(async () => { | ||
| var _this$callbacks$onOpe, _this$callbacks; | ||
| if (_this4.lazyMode) _this4.inactivityTimeout.start(); | ||
| (_this$callbacks$onOpe = (_this$callbacks = _this4.callbacks).onOpen) === null || _this$callbacks$onOpe === void 0 || _this$callbacks$onOpe.call(_this$callbacks); | ||
| _this4.connectionState.next({ | ||
| type: "state", | ||
| state: "pending", | ||
| error: null | ||
| }); | ||
| }).catch((error) => { | ||
| ws.close(3e3); | ||
| handleCloseOrError(error); | ||
| }); | ||
| }); | ||
| ws.addEventListener("message", ({ data }) => { | ||
| this.inactivityTimeout.reset(); | ||
| if (["PING", "PONG"].includes(data)) return; | ||
| const incomingMessage = this.encoder.decode(data); | ||
| if ("method" in incomingMessage) { | ||
| this.handleIncomingRequest(incomingMessage); | ||
| return; | ||
| } | ||
| this.handleResponseMessage(incomingMessage); | ||
| }); | ||
| ws.addEventListener("close", (event) => { | ||
| var _this$callbacks$onClo, _this$callbacks2; | ||
| handleCloseOrError(event); | ||
| (_this$callbacks$onClo = (_this$callbacks2 = this.callbacks).onClose) === null || _this$callbacks$onClo === void 0 || _this$callbacks$onClo.call(_this$callbacks2, event); | ||
| if (!this.lazyMode || this.requestManager.hasPendingSubscriptions()) this.reconnect(new TRPCWebSocketClosedError({ | ||
| message: "WebSocket closed", | ||
| cause: event | ||
| })); | ||
| }); | ||
| ws.addEventListener("error", (event) => { | ||
| var _this$callbacks$onErr, _this$callbacks3; | ||
| handleCloseOrError(event); | ||
| (_this$callbacks$onErr = (_this$callbacks3 = this.callbacks).onError) === null || _this$callbacks$onErr === void 0 || _this$callbacks$onErr.call(_this$callbacks3, event); | ||
| this.reconnect(new TRPCWebSocketClosedError({ | ||
| message: "WebSocket closed", | ||
| cause: event | ||
| })); | ||
| }); | ||
| } | ||
| handleResponseMessage(message) { | ||
| const request = this.requestManager.getPendingRequest(message.id); | ||
| if (!request) return; | ||
| request.callbacks.next(message); | ||
| let completed = true; | ||
| if ("result" in message && request.message.method === "subscription") { | ||
| if (message.result.type === "data") request.message.params.lastEventId = message.result.id; | ||
| if (message.result.type !== "stopped") completed = false; | ||
| } | ||
| if (completed) { | ||
| request.callbacks.complete(); | ||
| this.requestManager.delete(message.id); | ||
| } | ||
| } | ||
| handleIncomingRequest(message) { | ||
| if (message.method === "reconnect") this.reconnect(new TRPCWebSocketClosedError({ message: "Server requested reconnect" })); | ||
| } | ||
| /** | ||
| * Sends a message or batch of messages directly to the server. | ||
| */ | ||
| send(messageOrMessages) { | ||
| if (!this.activeConnection.isOpen()) throw new Error("Active connection is not open"); | ||
| const messages = messageOrMessages instanceof Array ? messageOrMessages : [messageOrMessages]; | ||
| this.activeConnection.ws.send(this.encoder.encode(messages.length === 1 ? messages[0] : messages)); | ||
| } | ||
| /** | ||
| * Groups requests for batch sending. | ||
| * | ||
| * @returns A function to abort the batched request. | ||
| */ | ||
| batchSend(message, callbacks) { | ||
| var _this5 = this; | ||
| this.inactivityTimeout.reset(); | ||
| (0, __trpc_server_unstable_core_do_not_import.run)(async () => { | ||
| if (!_this5.activeConnection.isOpen()) await _this5.open(); | ||
| await (0, __trpc_server_unstable_core_do_not_import.sleep)(0); | ||
| if (!_this5.requestManager.hasOutgoingRequests()) return; | ||
| _this5.send(_this5.requestManager.flush().map(({ message: message$1 }) => message$1)); | ||
| }).catch((err) => { | ||
| this.requestManager.delete(message.id); | ||
| callbacks.error(require_TRPCClientError.TRPCClientError.from(err)); | ||
| }); | ||
| return this.requestManager.register(message, callbacks); | ||
| } | ||
| }; | ||
| //#endregion | ||
| //#region src/links/wsLink/createWsClient.ts | ||
| function createWSClient(opts) { | ||
| return new WsClient(opts); | ||
| } | ||
| //#endregion | ||
| //#region src/links/wsLink/wsLink.ts | ||
| function wsLink(opts) { | ||
| const { client } = opts; | ||
| const transformer = require_unstable_internals.getTransformer(opts.transformer); | ||
| return () => { | ||
| return ({ op }) => { | ||
| return (0, __trpc_server_observable.observable)((observer) => { | ||
| const connStateSubscription = op.type === "subscription" ? client.connectionState.subscribe({ next(result) { | ||
| observer.next({ | ||
| result, | ||
| context: op.context | ||
| }); | ||
| } }) : null; | ||
| const requestSubscription = client.request({ | ||
| op, | ||
| transformer | ||
| }).subscribe(observer); | ||
| return () => { | ||
| requestSubscription.unsubscribe(); | ||
| connStateSubscription === null || connStateSubscription === void 0 || connStateSubscription.unsubscribe(); | ||
| }; | ||
| }); | ||
| }; | ||
| }; | ||
| } | ||
| //#endregion | ||
| Object.defineProperty(exports, 'createWSClient', { | ||
| enumerable: true, | ||
| get: function () { | ||
| return createWSClient; | ||
| } | ||
| }); | ||
| Object.defineProperty(exports, 'jsonEncoder', { | ||
| enumerable: true, | ||
| get: function () { | ||
| return jsonEncoder; | ||
| } | ||
| }); | ||
| Object.defineProperty(exports, 'resultOf', { | ||
| enumerable: true, | ||
| get: function () { | ||
| return resultOf; | ||
| } | ||
| }); | ||
| Object.defineProperty(exports, 'wsLink', { | ||
| enumerable: true, | ||
| get: function () { | ||
| return wsLink; | ||
| } | ||
| }); |
| import { __toESM, require_defineProperty, require_objectSpread2 } from "./objectSpread2-BvkFp-_Y.mjs"; | ||
| import { TRPCClientError } from "./TRPCClientError-CjKyS10w.mjs"; | ||
| import { getTransformer } from "./unstable-internals-Bg7n9BBj.mjs"; | ||
| import { behaviorSubject, observable } from "@trpc/server/observable"; | ||
| import { run, sleep, transformResult } from "@trpc/server/unstable-core-do-not-import"; | ||
| //#region src/links/wsLink/wsClient/encoder.ts | ||
| const jsonEncoder = { | ||
| encode: (data) => JSON.stringify(data), | ||
| decode: (data) => { | ||
| if (typeof data !== "string") throw new Error("jsonEncoder received binary data. JSON uses text frames. Use a binary encoder for binary data."); | ||
| return JSON.parse(data); | ||
| } | ||
| }; | ||
| //#endregion | ||
| //#region src/links/wsLink/wsClient/options.ts | ||
| const lazyDefaults = { | ||
| enabled: false, | ||
| closeMs: 0 | ||
| }; | ||
| const keepAliveDefaults = { | ||
| enabled: false, | ||
| pongTimeoutMs: 1e3, | ||
| intervalMs: 5e3 | ||
| }; | ||
| /** | ||
| * Calculates a delay for exponential backoff based on the retry attempt index. | ||
| * The delay starts at 0 for the first attempt and doubles for each subsequent attempt, | ||
| * capped at 30 seconds. | ||
| */ | ||
| const exponentialBackoff = (attemptIndex) => { | ||
| return attemptIndex === 0 ? 0 : Math.min(1e3 * 2 ** attemptIndex, 3e4); | ||
| }; | ||
| //#endregion | ||
| //#region src/links/internals/urlWithConnectionParams.ts | ||
| /** | ||
| * Get the result of a value or function that returns a value | ||
| * It also optionally accepts typesafe arguments for the function | ||
| */ | ||
| const resultOf = (value, ...args) => { | ||
| return typeof value === "function" ? value(...args) : value; | ||
| }; | ||
| //#endregion | ||
| //#region src/links/wsLink/wsClient/utils.ts | ||
| var import_defineProperty$3 = __toESM(require_defineProperty(), 1); | ||
| var TRPCWebSocketClosedError = class TRPCWebSocketClosedError extends Error { | ||
| constructor(opts) { | ||
| super(opts.message, { cause: opts.cause }); | ||
| this.name = "TRPCWebSocketClosedError"; | ||
| Object.setPrototypeOf(this, TRPCWebSocketClosedError.prototype); | ||
| } | ||
| }; | ||
| /** | ||
| * Utility class for managing a timeout that can be started, stopped, and reset. | ||
| * Useful for scenarios where the timeout duration is reset dynamically based on events. | ||
| */ | ||
| var ResettableTimeout = class { | ||
| constructor(onTimeout, timeoutMs) { | ||
| this.onTimeout = onTimeout; | ||
| this.timeoutMs = timeoutMs; | ||
| (0, import_defineProperty$3.default)(this, "timeout", void 0); | ||
| } | ||
| /** | ||
| * Resets the current timeout, restarting it with the same duration. | ||
| * Does nothing if no timeout is active. | ||
| */ | ||
| reset() { | ||
| if (!this.timeout) return; | ||
| clearTimeout(this.timeout); | ||
| this.timeout = setTimeout(this.onTimeout, this.timeoutMs); | ||
| } | ||
| start() { | ||
| clearTimeout(this.timeout); | ||
| this.timeout = setTimeout(this.onTimeout, this.timeoutMs); | ||
| } | ||
| stop() { | ||
| clearTimeout(this.timeout); | ||
| this.timeout = void 0; | ||
| } | ||
| }; | ||
| function withResolvers() { | ||
| let resolve; | ||
| let reject; | ||
| const promise = new Promise((res, rej) => { | ||
| resolve = res; | ||
| reject = rej; | ||
| }); | ||
| return { | ||
| promise, | ||
| resolve, | ||
| reject | ||
| }; | ||
| } | ||
| /** | ||
| * Resolves a WebSocket URL and optionally appends connection parameters. | ||
| * | ||
| * If connectionParams are provided, appends 'connectionParams=1' query parameter. | ||
| */ | ||
| async function prepareUrl(urlOptions) { | ||
| const url = await resultOf(urlOptions.url); | ||
| if (!urlOptions.connectionParams) return url; | ||
| const prefix = url.includes("?") ? "&" : "?"; | ||
| const connectionParams = `${prefix}connectionParams=1`; | ||
| return url + connectionParams; | ||
| } | ||
| async function buildConnectionMessage(connectionParams) { | ||
| const message = { | ||
| method: "connectionParams", | ||
| data: await resultOf(connectionParams) | ||
| }; | ||
| return JSON.stringify(message); | ||
| } | ||
| //#endregion | ||
| //#region src/links/wsLink/wsClient/requestManager.ts | ||
| var import_defineProperty$2 = __toESM(require_defineProperty(), 1); | ||
| /** | ||
| * Manages WebSocket requests, tracking their lifecycle and providing utility methods | ||
| * for handling outgoing and pending requests. | ||
| * | ||
| * - **Outgoing requests**: Requests that are queued and waiting to be sent. | ||
| * - **Pending requests**: Requests that have been sent and are in flight awaiting a response. | ||
| * For subscriptions, multiple responses may be received until the subscription is closed. | ||
| */ | ||
| var RequestManager = class { | ||
| constructor() { | ||
| (0, import_defineProperty$2.default)(this, "outgoingRequests", new Array()); | ||
| (0, import_defineProperty$2.default)(this, "pendingRequests", {}); | ||
| } | ||
| /** | ||
| * Registers a new request by adding it to the outgoing queue and setting up | ||
| * callbacks for lifecycle events such as completion or error. | ||
| * | ||
| * @param message - The outgoing message to be sent. | ||
| * @param callbacks - Callback functions to observe the request's state. | ||
| * @returns A cleanup function to manually remove the request. | ||
| */ | ||
| register(message, callbacks) { | ||
| const { promise: end, resolve } = withResolvers(); | ||
| this.outgoingRequests.push({ | ||
| id: String(message.id), | ||
| message, | ||
| end, | ||
| callbacks: { | ||
| next: callbacks.next, | ||
| complete: () => { | ||
| callbacks.complete(); | ||
| resolve(); | ||
| }, | ||
| error: (e) => { | ||
| callbacks.error(e); | ||
| resolve(); | ||
| } | ||
| } | ||
| }); | ||
| return () => { | ||
| this.delete(message.id); | ||
| callbacks.complete(); | ||
| resolve(); | ||
| }; | ||
| } | ||
| /** | ||
| * Deletes a request from both the outgoing and pending collections, if it exists. | ||
| */ | ||
| delete(messageId) { | ||
| if (messageId === null) return; | ||
| this.outgoingRequests = this.outgoingRequests.filter(({ id }) => id !== String(messageId)); | ||
| delete this.pendingRequests[String(messageId)]; | ||
| } | ||
| /** | ||
| * Moves all outgoing requests to the pending state and clears the outgoing queue. | ||
| * | ||
| * The caller is expected to handle the actual sending of the requests | ||
| * (e.g., sending them over the network) after this method is called. | ||
| * | ||
| * @returns The list of requests that were transitioned to the pending state. | ||
| */ | ||
| flush() { | ||
| const requests = this.outgoingRequests; | ||
| this.outgoingRequests = []; | ||
| for (const request of requests) this.pendingRequests[request.id] = request; | ||
| return requests; | ||
| } | ||
| /** | ||
| * Retrieves all currently pending requests, which are in flight awaiting responses | ||
| * or handling ongoing subscriptions. | ||
| */ | ||
| getPendingRequests() { | ||
| return Object.values(this.pendingRequests); | ||
| } | ||
| /** | ||
| * Retrieves a specific pending request by its message ID. | ||
| */ | ||
| getPendingRequest(messageId) { | ||
| if (messageId === null) return null; | ||
| return this.pendingRequests[String(messageId)]; | ||
| } | ||
| /** | ||
| * Retrieves all outgoing requests, which are waiting to be sent. | ||
| */ | ||
| getOutgoingRequests() { | ||
| return this.outgoingRequests; | ||
| } | ||
| /** | ||
| * Retrieves all requests, both outgoing and pending, with their respective states. | ||
| * | ||
| * @returns An array of all requests with their state ("outgoing" or "pending"). | ||
| */ | ||
| getRequests() { | ||
| return [...this.getOutgoingRequests().map((request) => ({ | ||
| state: "outgoing", | ||
| message: request.message, | ||
| end: request.end, | ||
| callbacks: request.callbacks | ||
| })), ...this.getPendingRequests().map((request) => ({ | ||
| state: "pending", | ||
| message: request.message, | ||
| end: request.end, | ||
| callbacks: request.callbacks | ||
| }))]; | ||
| } | ||
| /** | ||
| * Checks if there are any pending requests, including ongoing subscriptions. | ||
| */ | ||
| hasPendingRequests() { | ||
| return this.getPendingRequests().length > 0; | ||
| } | ||
| /** | ||
| * Checks if there are any pending subscriptions | ||
| */ | ||
| hasPendingSubscriptions() { | ||
| return this.getPendingRequests().some((request) => request.message.method === "subscription"); | ||
| } | ||
| /** | ||
| * Checks if there are any outgoing requests waiting to be sent. | ||
| */ | ||
| hasOutgoingRequests() { | ||
| return this.outgoingRequests.length > 0; | ||
| } | ||
| }; | ||
| //#endregion | ||
| //#region src/links/wsLink/wsClient/wsConnection.ts | ||
| var import_defineProperty$1 = __toESM(require_defineProperty(), 1); | ||
| /** | ||
| * Opens a WebSocket connection asynchronously and returns a promise | ||
| * that resolves when the connection is successfully established. | ||
| * The promise rejects if an error occurs during the connection attempt. | ||
| */ | ||
| function asyncWsOpen(ws) { | ||
| const { promise, resolve, reject } = withResolvers(); | ||
| ws.addEventListener("open", () => { | ||
| ws.removeEventListener("error", reject); | ||
| resolve(); | ||
| }); | ||
| ws.addEventListener("error", reject); | ||
| return promise; | ||
| } | ||
| /** | ||
| * Sets up a periodic ping-pong mechanism to keep the WebSocket connection alive. | ||
| * | ||
| * - Sends "PING" messages at regular intervals defined by `intervalMs`. | ||
| * - If a "PONG" response is not received within the `pongTimeoutMs`, the WebSocket is closed. | ||
| * - The ping timer resets upon receiving any message to maintain activity. | ||
| * - Automatically starts the ping process when the WebSocket connection is opened. | ||
| * - Cleans up timers when the WebSocket is closed. | ||
| * | ||
| * @param ws - The WebSocket instance to manage. | ||
| * @param options - Configuration options for ping-pong intervals and timeouts. | ||
| */ | ||
| function setupPingInterval(ws, { intervalMs, pongTimeoutMs }) { | ||
| let pingTimeout; | ||
| let pongTimeout; | ||
| function start() { | ||
| pingTimeout = setTimeout(() => { | ||
| ws.send("PING"); | ||
| pongTimeout = setTimeout(() => { | ||
| ws.close(); | ||
| }, pongTimeoutMs); | ||
| }, intervalMs); | ||
| } | ||
| function reset() { | ||
| clearTimeout(pingTimeout); | ||
| start(); | ||
| } | ||
| function pong() { | ||
| clearTimeout(pongTimeout); | ||
| reset(); | ||
| } | ||
| ws.addEventListener("open", start); | ||
| ws.addEventListener("message", ({ data }) => { | ||
| clearTimeout(pingTimeout); | ||
| start(); | ||
| if (data === "PONG") pong(); | ||
| }); | ||
| ws.addEventListener("close", () => { | ||
| clearTimeout(pingTimeout); | ||
| clearTimeout(pongTimeout); | ||
| }); | ||
| } | ||
| /** | ||
| * Manages a WebSocket connection with support for reconnection, keep-alive mechanisms, | ||
| * and observable state tracking. | ||
| */ | ||
| var WsConnection = class WsConnection { | ||
| constructor(opts) { | ||
| var _opts$WebSocketPonyfi; | ||
| (0, import_defineProperty$1.default)(this, "id", ++WsConnection.connectCount); | ||
| (0, import_defineProperty$1.default)(this, "WebSocketPonyfill", void 0); | ||
| (0, import_defineProperty$1.default)(this, "urlOptions", void 0); | ||
| (0, import_defineProperty$1.default)(this, "keepAliveOpts", void 0); | ||
| (0, import_defineProperty$1.default)(this, "wsObservable", behaviorSubject(null)); | ||
| (0, import_defineProperty$1.default)(this, "openPromise", null); | ||
| this.WebSocketPonyfill = (_opts$WebSocketPonyfi = opts.WebSocketPonyfill) !== null && _opts$WebSocketPonyfi !== void 0 ? _opts$WebSocketPonyfi : WebSocket; | ||
| if (!this.WebSocketPonyfill) throw new Error("No WebSocket implementation found - you probably don't want to use this on the server, but if you do you need to pass a `WebSocket`-ponyfill"); | ||
| this.urlOptions = opts.urlOptions; | ||
| this.keepAliveOpts = opts.keepAlive; | ||
| } | ||
| get ws() { | ||
| return this.wsObservable.get(); | ||
| } | ||
| set ws(ws) { | ||
| this.wsObservable.next(ws); | ||
| } | ||
| /** | ||
| * Checks if the WebSocket connection is open and ready to communicate. | ||
| */ | ||
| isOpen() { | ||
| return !!this.ws && this.ws.readyState === this.WebSocketPonyfill.OPEN && !this.openPromise; | ||
| } | ||
| /** | ||
| * Checks if the WebSocket connection is closed or in the process of closing. | ||
| */ | ||
| isClosed() { | ||
| return !!this.ws && (this.ws.readyState === this.WebSocketPonyfill.CLOSING || this.ws.readyState === this.WebSocketPonyfill.CLOSED); | ||
| } | ||
| async open() { | ||
| var _this = this; | ||
| if (_this.openPromise) return _this.openPromise; | ||
| _this.id = ++WsConnection.connectCount; | ||
| const wsPromise = prepareUrl(_this.urlOptions).then((url) => new _this.WebSocketPonyfill(url)); | ||
| _this.openPromise = wsPromise.then(async (ws) => { | ||
| _this.ws = ws; | ||
| ws.binaryType = "arraybuffer"; | ||
| ws.addEventListener("message", function({ data }) { | ||
| if (data === "PING") this.send("PONG"); | ||
| }); | ||
| if (_this.keepAliveOpts.enabled) setupPingInterval(ws, _this.keepAliveOpts); | ||
| ws.addEventListener("close", () => { | ||
| if (_this.ws === ws) _this.ws = null; | ||
| }); | ||
| await asyncWsOpen(ws); | ||
| if (_this.urlOptions.connectionParams) ws.send(await buildConnectionMessage(_this.urlOptions.connectionParams)); | ||
| }); | ||
| try { | ||
| await _this.openPromise; | ||
| } finally { | ||
| _this.openPromise = null; | ||
| } | ||
| } | ||
| /** | ||
| * Closes the WebSocket connection gracefully. | ||
| * Waits for any ongoing open operation to complete before closing. | ||
| */ | ||
| async close() { | ||
| var _this2 = this; | ||
| try { | ||
| await _this2.openPromise; | ||
| } finally { | ||
| var _this$ws; | ||
| (_this$ws = _this2.ws) === null || _this$ws === void 0 || _this$ws.close(); | ||
| } | ||
| } | ||
| }; | ||
| (0, import_defineProperty$1.default)(WsConnection, "connectCount", 0); | ||
| /** | ||
| * Provides a backward-compatible representation of the connection state. | ||
| */ | ||
| function backwardCompatibility(connection) { | ||
| if (connection.isOpen()) return { | ||
| id: connection.id, | ||
| state: "open", | ||
| ws: connection.ws | ||
| }; | ||
| if (connection.isClosed()) return { | ||
| id: connection.id, | ||
| state: "closed", | ||
| ws: connection.ws | ||
| }; | ||
| if (!connection.ws) return null; | ||
| return { | ||
| id: connection.id, | ||
| state: "connecting", | ||
| ws: connection.ws | ||
| }; | ||
| } | ||
| //#endregion | ||
| //#region src/links/wsLink/wsClient/wsClient.ts | ||
| var import_defineProperty = __toESM(require_defineProperty(), 1); | ||
| var import_objectSpread2 = __toESM(require_objectSpread2(), 1); | ||
| /** | ||
| * A WebSocket client for managing TRPC operations, supporting lazy initialization, | ||
| * reconnection, keep-alive, and request management. | ||
| */ | ||
| var WsClient = class { | ||
| constructor(opts) { | ||
| var _opts$experimental_en, _opts$retryDelayMs; | ||
| (0, import_defineProperty.default)(this, "connectionState", void 0); | ||
| (0, import_defineProperty.default)(this, "allowReconnect", false); | ||
| (0, import_defineProperty.default)(this, "requestManager", new RequestManager()); | ||
| (0, import_defineProperty.default)(this, "activeConnection", void 0); | ||
| (0, import_defineProperty.default)(this, "reconnectRetryDelay", void 0); | ||
| (0, import_defineProperty.default)(this, "inactivityTimeout", void 0); | ||
| (0, import_defineProperty.default)(this, "callbacks", void 0); | ||
| (0, import_defineProperty.default)(this, "lazyMode", void 0); | ||
| (0, import_defineProperty.default)(this, "encoder", void 0); | ||
| (0, import_defineProperty.default)(this, "reconnecting", null); | ||
| this.encoder = (_opts$experimental_en = opts.experimental_encoder) !== null && _opts$experimental_en !== void 0 ? _opts$experimental_en : jsonEncoder; | ||
| this.callbacks = { | ||
| onOpen: opts.onOpen, | ||
| onClose: opts.onClose, | ||
| onError: opts.onError | ||
| }; | ||
| const lazyOptions = (0, import_objectSpread2.default)((0, import_objectSpread2.default)({}, lazyDefaults), opts.lazy); | ||
| this.inactivityTimeout = new ResettableTimeout(() => { | ||
| if (this.requestManager.hasOutgoingRequests() || this.requestManager.hasPendingRequests()) { | ||
| this.inactivityTimeout.reset(); | ||
| return; | ||
| } | ||
| this.close().catch(() => null); | ||
| }, lazyOptions.closeMs); | ||
| this.activeConnection = new WsConnection({ | ||
| WebSocketPonyfill: opts.WebSocket, | ||
| urlOptions: opts, | ||
| keepAlive: (0, import_objectSpread2.default)((0, import_objectSpread2.default)({}, keepAliveDefaults), opts.keepAlive) | ||
| }); | ||
| this.activeConnection.wsObservable.subscribe({ next: (ws) => { | ||
| if (!ws) return; | ||
| this.setupWebSocketListeners(ws); | ||
| } }); | ||
| this.reconnectRetryDelay = (_opts$retryDelayMs = opts.retryDelayMs) !== null && _opts$retryDelayMs !== void 0 ? _opts$retryDelayMs : exponentialBackoff; | ||
| this.lazyMode = lazyOptions.enabled; | ||
| this.connectionState = behaviorSubject({ | ||
| type: "state", | ||
| state: lazyOptions.enabled ? "idle" : "connecting", | ||
| error: null | ||
| }); | ||
| if (!this.lazyMode) this.open().catch(() => null); | ||
| } | ||
| /** | ||
| * Opens the WebSocket connection. Handles reconnection attempts and updates | ||
| * the connection state accordingly. | ||
| */ | ||
| async open() { | ||
| var _this = this; | ||
| _this.allowReconnect = true; | ||
| if (_this.connectionState.get().state === "idle") _this.connectionState.next({ | ||
| type: "state", | ||
| state: "connecting", | ||
| error: null | ||
| }); | ||
| try { | ||
| await _this.activeConnection.open(); | ||
| } catch (error) { | ||
| _this.reconnect(new TRPCWebSocketClosedError({ | ||
| message: "Initialization error", | ||
| cause: error | ||
| })); | ||
| return _this.reconnecting; | ||
| } | ||
| } | ||
| /** | ||
| * Closes the WebSocket connection and stops managing requests. | ||
| * Ensures all outgoing and pending requests are properly finalized. | ||
| */ | ||
| async close() { | ||
| var _this2 = this; | ||
| _this2.allowReconnect = false; | ||
| _this2.inactivityTimeout.stop(); | ||
| const requestsToAwait = []; | ||
| for (const request of _this2.requestManager.getRequests()) if (request.message.method === "subscription") request.callbacks.complete(); | ||
| else if (request.state === "outgoing") request.callbacks.error(TRPCClientError.from(new TRPCWebSocketClosedError({ message: "Closed before connection was established" }))); | ||
| else requestsToAwait.push(request.end); | ||
| await Promise.all(requestsToAwait).catch(() => null); | ||
| await _this2.activeConnection.close().catch(() => null); | ||
| _this2.connectionState.next({ | ||
| type: "state", | ||
| state: "idle", | ||
| error: null | ||
| }); | ||
| } | ||
| /** | ||
| * Method to request the server. | ||
| * Handles data transformation, batching of requests, and subscription lifecycle. | ||
| * | ||
| * @param op - The operation details including id, type, path, input and signal | ||
| * @param transformer - Data transformer for serializing requests and deserializing responses | ||
| * @param lastEventId - Optional ID of the last received event for subscriptions | ||
| * | ||
| * @returns An observable that emits operation results and handles cleanup | ||
| */ | ||
| request({ op: { id, type, path, input, signal }, transformer, lastEventId }) { | ||
| return observable((observer) => { | ||
| const abort = this.batchSend({ | ||
| id, | ||
| method: type, | ||
| params: { | ||
| input: transformer.input.serialize(input), | ||
| path, | ||
| lastEventId | ||
| } | ||
| }, (0, import_objectSpread2.default)((0, import_objectSpread2.default)({}, observer), {}, { next(event) { | ||
| const transformed = transformResult(event, transformer.output); | ||
| if (!transformed.ok) { | ||
| observer.error(TRPCClientError.from(transformed.error)); | ||
| return; | ||
| } | ||
| observer.next({ result: transformed.result }); | ||
| } })); | ||
| return () => { | ||
| abort(); | ||
| if (type === "subscription" && this.activeConnection.isOpen()) this.send({ | ||
| id, | ||
| method: "subscription.stop" | ||
| }); | ||
| signal === null || signal === void 0 || signal.removeEventListener("abort", abort); | ||
| }; | ||
| }); | ||
| } | ||
| get connection() { | ||
| return backwardCompatibility(this.activeConnection); | ||
| } | ||
| reconnect(closedError) { | ||
| var _this3 = this; | ||
| this.connectionState.next({ | ||
| type: "state", | ||
| state: "connecting", | ||
| error: TRPCClientError.from(closedError) | ||
| }); | ||
| if (this.reconnecting) return; | ||
| const tryReconnect = async (attemptIndex) => { | ||
| try { | ||
| await sleep(_this3.reconnectRetryDelay(attemptIndex)); | ||
| if (_this3.allowReconnect) { | ||
| await _this3.activeConnection.close(); | ||
| await _this3.activeConnection.open(); | ||
| if (_this3.requestManager.hasPendingRequests()) _this3.send(_this3.requestManager.getPendingRequests().map(({ message }) => message)); | ||
| } | ||
| _this3.reconnecting = null; | ||
| } catch (_unused) { | ||
| await tryReconnect(attemptIndex + 1); | ||
| } | ||
| }; | ||
| this.reconnecting = tryReconnect(0); | ||
| } | ||
| setupWebSocketListeners(ws) { | ||
| var _this4 = this; | ||
| const handleCloseOrError = (cause) => { | ||
| const reqs = this.requestManager.getPendingRequests(); | ||
| for (const { message, callbacks } of reqs) { | ||
| if (message.method === "subscription") continue; | ||
| callbacks.error(TRPCClientError.from(cause !== null && cause !== void 0 ? cause : new TRPCWebSocketClosedError({ | ||
| message: "WebSocket closed", | ||
| cause | ||
| }))); | ||
| this.requestManager.delete(message.id); | ||
| } | ||
| }; | ||
| ws.addEventListener("open", () => { | ||
| run(async () => { | ||
| var _this$callbacks$onOpe, _this$callbacks; | ||
| if (_this4.lazyMode) _this4.inactivityTimeout.start(); | ||
| (_this$callbacks$onOpe = (_this$callbacks = _this4.callbacks).onOpen) === null || _this$callbacks$onOpe === void 0 || _this$callbacks$onOpe.call(_this$callbacks); | ||
| _this4.connectionState.next({ | ||
| type: "state", | ||
| state: "pending", | ||
| error: null | ||
| }); | ||
| }).catch((error) => { | ||
| ws.close(3e3); | ||
| handleCloseOrError(error); | ||
| }); | ||
| }); | ||
| ws.addEventListener("message", ({ data }) => { | ||
| this.inactivityTimeout.reset(); | ||
| if (["PING", "PONG"].includes(data)) return; | ||
| const incomingMessage = this.encoder.decode(data); | ||
| if ("method" in incomingMessage) { | ||
| this.handleIncomingRequest(incomingMessage); | ||
| return; | ||
| } | ||
| this.handleResponseMessage(incomingMessage); | ||
| }); | ||
| ws.addEventListener("close", (event) => { | ||
| var _this$callbacks$onClo, _this$callbacks2; | ||
| handleCloseOrError(event); | ||
| (_this$callbacks$onClo = (_this$callbacks2 = this.callbacks).onClose) === null || _this$callbacks$onClo === void 0 || _this$callbacks$onClo.call(_this$callbacks2, event); | ||
| if (!this.lazyMode || this.requestManager.hasPendingSubscriptions()) this.reconnect(new TRPCWebSocketClosedError({ | ||
| message: "WebSocket closed", | ||
| cause: event | ||
| })); | ||
| }); | ||
| ws.addEventListener("error", (event) => { | ||
| var _this$callbacks$onErr, _this$callbacks3; | ||
| handleCloseOrError(event); | ||
| (_this$callbacks$onErr = (_this$callbacks3 = this.callbacks).onError) === null || _this$callbacks$onErr === void 0 || _this$callbacks$onErr.call(_this$callbacks3, event); | ||
| this.reconnect(new TRPCWebSocketClosedError({ | ||
| message: "WebSocket closed", | ||
| cause: event | ||
| })); | ||
| }); | ||
| } | ||
| handleResponseMessage(message) { | ||
| const request = this.requestManager.getPendingRequest(message.id); | ||
| if (!request) return; | ||
| request.callbacks.next(message); | ||
| let completed = true; | ||
| if ("result" in message && request.message.method === "subscription") { | ||
| if (message.result.type === "data") request.message.params.lastEventId = message.result.id; | ||
| if (message.result.type !== "stopped") completed = false; | ||
| } | ||
| if (completed) { | ||
| request.callbacks.complete(); | ||
| this.requestManager.delete(message.id); | ||
| } | ||
| } | ||
| handleIncomingRequest(message) { | ||
| if (message.method === "reconnect") this.reconnect(new TRPCWebSocketClosedError({ message: "Server requested reconnect" })); | ||
| } | ||
| /** | ||
| * Sends a message or batch of messages directly to the server. | ||
| */ | ||
| send(messageOrMessages) { | ||
| if (!this.activeConnection.isOpen()) throw new Error("Active connection is not open"); | ||
| const messages = messageOrMessages instanceof Array ? messageOrMessages : [messageOrMessages]; | ||
| this.activeConnection.ws.send(this.encoder.encode(messages.length === 1 ? messages[0] : messages)); | ||
| } | ||
| /** | ||
| * Groups requests for batch sending. | ||
| * | ||
| * @returns A function to abort the batched request. | ||
| */ | ||
| batchSend(message, callbacks) { | ||
| var _this5 = this; | ||
| this.inactivityTimeout.reset(); | ||
| run(async () => { | ||
| if (!_this5.activeConnection.isOpen()) await _this5.open(); | ||
| await sleep(0); | ||
| if (!_this5.requestManager.hasOutgoingRequests()) return; | ||
| _this5.send(_this5.requestManager.flush().map(({ message: message$1 }) => message$1)); | ||
| }).catch((err) => { | ||
| this.requestManager.delete(message.id); | ||
| callbacks.error(TRPCClientError.from(err)); | ||
| }); | ||
| return this.requestManager.register(message, callbacks); | ||
| } | ||
| }; | ||
| //#endregion | ||
| //#region src/links/wsLink/createWsClient.ts | ||
| function createWSClient(opts) { | ||
| return new WsClient(opts); | ||
| } | ||
| //#endregion | ||
| //#region src/links/wsLink/wsLink.ts | ||
| function wsLink(opts) { | ||
| const { client } = opts; | ||
| const transformer = getTransformer(opts.transformer); | ||
| return () => { | ||
| return ({ op }) => { | ||
| return observable((observer) => { | ||
| const connStateSubscription = op.type === "subscription" ? client.connectionState.subscribe({ next(result) { | ||
| observer.next({ | ||
| result, | ||
| context: op.context | ||
| }); | ||
| } }) : null; | ||
| const requestSubscription = client.request({ | ||
| op, | ||
| transformer | ||
| }).subscribe(observer); | ||
| return () => { | ||
| requestSubscription.unsubscribe(); | ||
| connStateSubscription === null || connStateSubscription === void 0 || connStateSubscription.unsubscribe(); | ||
| }; | ||
| }); | ||
| }; | ||
| }; | ||
| } | ||
| //#endregion | ||
| export { createWSClient, jsonEncoder, resultOf, wsLink }; | ||
| //# sourceMappingURL=wsLink-DVm7B-YP.mjs.map |
| {"version":3,"file":"wsLink-DVm7B-YP.mjs","names":["jsonEncoder: Encoder","lazyDefaults: LazyOptions","keepAliveDefaults: KeepAliveOptions","attemptIndex: number","value: T | ((...args: TArgs) => T)","opts: { message: string; cause?: unknown }","onTimeout: () => void","timeoutMs: number","resolve: (value: T | PromiseLike<T>) => void","reject: (reason?: any) => void","urlOptions: UrlOptionsWithConnectionParams","connectionParams: CallbackOrValue<TRPCRequestInfo['connectionParams']>","message: TRPCConnectionParamsMessage","message: TRPCClientOutgoingMessage","callbacks: TCallbacks","messageId: MessageIdLike","ws: WebSocket","pingTimeout: ReturnType<typeof setTimeout> | undefined","pongTimeout: ReturnType<typeof setTimeout> | undefined","opts: WebSocketConnectionOptions","this","connection: WsConnection","opts: WebSocketClientOptions","this","requestsToAwait: Promise<void>[]","closedError: TRPCWebSocketClosedError","attemptIndex: number","ws: WebSocket","cause: unknown","message: TRPCResponseMessage","message: TRPCClientIncomingRequest","messageOrMessages: TRPCClientOutgoingMessage | TRPCClientOutgoingMessage[]","message: TRPCClientOutgoingMessage","callbacks: TCallbacks","message","opts: WebSocketClientOptions","opts: WebSocketLinkOptions<TRouter>"],"sources":["../src/links/wsLink/wsClient/encoder.ts","../src/links/wsLink/wsClient/options.ts","../src/links/internals/urlWithConnectionParams.ts","../src/links/wsLink/wsClient/utils.ts","../src/links/wsLink/wsClient/requestManager.ts","../src/links/wsLink/wsClient/wsConnection.ts","../src/links/wsLink/wsClient/wsClient.ts","../src/links/wsLink/createWsClient.ts","../src/links/wsLink/wsLink.ts"],"sourcesContent":["import type { Encoder } from '@trpc/server/adapters/ws';\n\nexport type { Encoder };\n\nexport const jsonEncoder: Encoder = {\n encode: (data) => JSON.stringify(data),\n decode: (data) => {\n if (typeof data !== 'string') {\n throw new Error(\n 'jsonEncoder received binary data. JSON uses text frames. ' +\n 'Use a binary encoder for binary data.',\n );\n }\n return JSON.parse(data);\n },\n};\n","import type { UrlOptionsWithConnectionParams } from '../../internals/urlWithConnectionParams';\nimport type { Encoder } from './encoder';\n\nexport interface WebSocketClientOptions extends UrlOptionsWithConnectionParams {\n /**\n * Ponyfill which WebSocket implementation to use\n */\n WebSocket?: typeof WebSocket;\n /**\n * The number of milliseconds before a reconnect is attempted.\n * @default {@link exponentialBackoff}\n */\n retryDelayMs?: (attemptIndex: number) => number;\n /**\n * Triggered when a WebSocket connection is established\n */\n onOpen?: () => void;\n /**\n * Triggered when a WebSocket connection encounters an error\n */\n onError?: (evt?: Event) => void;\n /**\n * Triggered when a WebSocket connection is closed\n */\n onClose?: (cause?: { code?: number }) => void;\n /**\n * Lazy mode will close the WebSocket automatically after a period of inactivity (no messages sent or received and no pending requests)\n */\n lazy?: {\n /**\n * Enable lazy mode\n * @default false\n */\n enabled: boolean;\n /**\n * Close the WebSocket after this many milliseconds\n * @default 0\n */\n closeMs: number;\n };\n /**\n * Send ping messages to the server and kill the connection if no pong message is returned\n */\n keepAlive?: {\n /**\n * @default false\n */\n enabled: boolean;\n /**\n * Send a ping message every this many milliseconds\n * @default 5_000\n */\n intervalMs?: number;\n /**\n * Close the WebSocket after this many milliseconds if the server does not respond\n * @default 1_000\n */\n pongTimeoutMs?: number;\n };\n /**\n * Custom encoder for wire encoding (e.g. custom binary formats)\n * @default jsonEncoder\n */\n experimental_encoder?: Encoder;\n}\n\n/**\n * Default options for lazy WebSocket connections.\n * Determines whether the connection should be established lazily and defines the delay before closure.\n */\nexport type LazyOptions = Required<NonNullable<WebSocketClientOptions['lazy']>>;\nexport const lazyDefaults: LazyOptions = {\n enabled: false,\n closeMs: 0,\n};\n\n/**\n * Default options for the WebSocket keep-alive mechanism.\n * Configures whether keep-alive is enabled and specifies the timeout and interval for ping-pong messages.\n */\nexport type KeepAliveOptions = Required<\n NonNullable<WebSocketClientOptions['keepAlive']>\n>;\nexport const keepAliveDefaults: KeepAliveOptions = {\n enabled: false,\n pongTimeoutMs: 1_000,\n intervalMs: 5_000,\n};\n\n/**\n * Calculates a delay for exponential backoff based on the retry attempt index.\n * The delay starts at 0 for the first attempt and doubles for each subsequent attempt,\n * capped at 30 seconds.\n */\nexport const exponentialBackoff = (attemptIndex: number) => {\n return attemptIndex === 0 ? 0 : Math.min(1000 * 2 ** attemptIndex, 30000);\n};\n","import { type TRPCRequestInfo } from '@trpc/server/http';\n\n/**\n * Get the result of a value or function that returns a value\n * It also optionally accepts typesafe arguments for the function\n */\nexport const resultOf = <T, TArgs extends any[]>(\n value: T | ((...args: TArgs) => T),\n ...args: TArgs\n): T => {\n return typeof value === 'function'\n ? (value as (...args: TArgs) => T)(...args)\n : value;\n};\n\n/**\n * A value that can be wrapped in callback\n */\nexport type CallbackOrValue<T> = T | (() => T | Promise<T>);\n\nexport interface UrlOptionsWithConnectionParams {\n /**\n * The URL to connect to (can be a function that returns a URL)\n */\n url: CallbackOrValue<string>;\n\n /**\n * Connection params that are available in `createContext()`\n * - For `wsLink`/`wsClient`, these are sent as the first message\n * - For `httpSubscriptionLink`, these are serialized as part of the URL under the `connectionParams` query\n */\n connectionParams?: CallbackOrValue<TRPCRequestInfo['connectionParams']>;\n}\n","import type {\n TRPCConnectionParamsMessage,\n TRPCRequestInfo,\n} from '@trpc/server/unstable-core-do-not-import';\nimport type {\n CallbackOrValue,\n UrlOptionsWithConnectionParams,\n} from '../../internals/urlWithConnectionParams';\nimport { resultOf } from '../../internals/urlWithConnectionParams';\n\nexport class TRPCWebSocketClosedError extends Error {\n constructor(opts: { message: string; cause?: unknown }) {\n super(opts.message, {\n cause: opts.cause,\n });\n this.name = 'TRPCWebSocketClosedError';\n Object.setPrototypeOf(this, TRPCWebSocketClosedError.prototype);\n }\n}\n\n/**\n * Utility class for managing a timeout that can be started, stopped, and reset.\n * Useful for scenarios where the timeout duration is reset dynamically based on events.\n */\nexport class ResettableTimeout {\n private timeout: ReturnType<typeof setTimeout> | undefined;\n\n constructor(\n private readonly onTimeout: () => void,\n private readonly timeoutMs: number,\n ) {}\n\n /**\n * Resets the current timeout, restarting it with the same duration.\n * Does nothing if no timeout is active.\n */\n public reset() {\n if (!this.timeout) return;\n\n clearTimeout(this.timeout);\n this.timeout = setTimeout(this.onTimeout, this.timeoutMs);\n }\n\n public start() {\n clearTimeout(this.timeout);\n this.timeout = setTimeout(this.onTimeout, this.timeoutMs);\n }\n\n public stop() {\n clearTimeout(this.timeout);\n this.timeout = undefined;\n }\n}\n\n// Ponyfill for Promise.withResolvers https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/withResolvers\nexport function withResolvers<T>() {\n let resolve: (value: T | PromiseLike<T>) => void;\n let reject: (reason?: any) => void;\n const promise = new Promise<T>((res, rej) => {\n resolve = res;\n reject = rej;\n });\n\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n return { promise, resolve: resolve!, reject: reject! };\n}\n\n/**\n * Resolves a WebSocket URL and optionally appends connection parameters.\n *\n * If connectionParams are provided, appends 'connectionParams=1' query parameter.\n */\nexport async function prepareUrl(urlOptions: UrlOptionsWithConnectionParams) {\n const url = await resultOf(urlOptions.url);\n\n if (!urlOptions.connectionParams) return url;\n\n // append `?connectionParams=1` when connection params are used\n const prefix = url.includes('?') ? '&' : '?';\n const connectionParams = `${prefix}connectionParams=1`;\n\n return url + connectionParams;\n}\n\nexport async function buildConnectionMessage(\n connectionParams: CallbackOrValue<TRPCRequestInfo['connectionParams']>,\n) {\n const message: TRPCConnectionParamsMessage = {\n method: 'connectionParams',\n data: await resultOf(connectionParams),\n };\n\n return JSON.stringify(message);\n}\n","import type { AnyTRPCRouter, inferRouterError } from '@trpc/server';\nimport type { Observer } from '@trpc/server/observable';\nimport type {\n TRPCClientOutgoingMessage,\n TRPCResponseMessage,\n} from '@trpc/server/unstable-core-do-not-import';\nimport type { TRPCClientError } from '../../../TRPCClientError';\nimport { withResolvers } from './utils';\n\nexport type TCallbacks = Observer<\n TRPCResponseMessage<unknown, inferRouterError<AnyTRPCRouter>>,\n TRPCClientError<AnyTRPCRouter>\n>;\n\ntype MessageId = string;\ntype MessageIdLike = string | number | null;\n\n/**\n * Represents a WebSocket request managed by the RequestManager.\n * Combines the network message, a utility promise (`end`) that mirrors the lifecycle\n * handled by `callbacks`, and a set of state monitoring callbacks.\n */\ninterface Request {\n message: TRPCClientOutgoingMessage;\n end: Promise<void>;\n callbacks: TCallbacks;\n}\n\n/**\n * Manages WebSocket requests, tracking their lifecycle and providing utility methods\n * for handling outgoing and pending requests.\n *\n * - **Outgoing requests**: Requests that are queued and waiting to be sent.\n * - **Pending requests**: Requests that have been sent and are in flight awaiting a response.\n * For subscriptions, multiple responses may be received until the subscription is closed.\n */\nexport class RequestManager {\n /**\n * Stores requests that are outgoing, meaning they are registered but not yet sent over the WebSocket.\n */\n private outgoingRequests = new Array<Request & { id: MessageId }>();\n\n /**\n * Stores requests that are pending (in flight), meaning they have been sent over the WebSocket\n * and are awaiting responses. For subscriptions, this includes requests\n * that may receive multiple responses.\n */\n private pendingRequests: Record<MessageId, Request> = {};\n\n /**\n * Registers a new request by adding it to the outgoing queue and setting up\n * callbacks for lifecycle events such as completion or error.\n *\n * @param message - The outgoing message to be sent.\n * @param callbacks - Callback functions to observe the request's state.\n * @returns A cleanup function to manually remove the request.\n */\n public register(message: TRPCClientOutgoingMessage, callbacks: TCallbacks) {\n const { promise: end, resolve } = withResolvers<void>();\n\n this.outgoingRequests.push({\n id: String(message.id),\n message,\n end,\n callbacks: {\n next: callbacks.next,\n complete: () => {\n callbacks.complete();\n resolve();\n },\n error: (e) => {\n callbacks.error(e);\n resolve();\n },\n },\n });\n\n return () => {\n this.delete(message.id);\n callbacks.complete();\n resolve();\n };\n }\n\n /**\n * Deletes a request from both the outgoing and pending collections, if it exists.\n */\n public delete(messageId: MessageIdLike) {\n if (messageId === null) return;\n\n this.outgoingRequests = this.outgoingRequests.filter(\n ({ id }) => id !== String(messageId),\n );\n delete this.pendingRequests[String(messageId)];\n }\n\n /**\n * Moves all outgoing requests to the pending state and clears the outgoing queue.\n *\n * The caller is expected to handle the actual sending of the requests\n * (e.g., sending them over the network) after this method is called.\n *\n * @returns The list of requests that were transitioned to the pending state.\n */\n public flush() {\n const requests = this.outgoingRequests;\n this.outgoingRequests = [];\n\n for (const request of requests) {\n this.pendingRequests[request.id] = request;\n }\n return requests;\n }\n\n /**\n * Retrieves all currently pending requests, which are in flight awaiting responses\n * or handling ongoing subscriptions.\n */\n public getPendingRequests() {\n return Object.values(this.pendingRequests);\n }\n\n /**\n * Retrieves a specific pending request by its message ID.\n */\n public getPendingRequest(messageId: MessageIdLike) {\n if (messageId === null) return null;\n\n return this.pendingRequests[String(messageId)];\n }\n\n /**\n * Retrieves all outgoing requests, which are waiting to be sent.\n */\n public getOutgoingRequests() {\n return this.outgoingRequests;\n }\n\n /**\n * Retrieves all requests, both outgoing and pending, with their respective states.\n *\n * @returns An array of all requests with their state (\"outgoing\" or \"pending\").\n */\n public getRequests() {\n return [\n ...this.getOutgoingRequests().map((request) => ({\n state: 'outgoing' as const,\n message: request.message,\n end: request.end,\n callbacks: request.callbacks,\n })),\n ...this.getPendingRequests().map((request) => ({\n state: 'pending' as const,\n message: request.message,\n end: request.end,\n callbacks: request.callbacks,\n })),\n ];\n }\n\n /**\n * Checks if there are any pending requests, including ongoing subscriptions.\n */\n public hasPendingRequests() {\n return this.getPendingRequests().length > 0;\n }\n\n /**\n * Checks if there are any pending subscriptions\n */\n public hasPendingSubscriptions() {\n return this.getPendingRequests().some(\n (request) => request.message.method === 'subscription',\n );\n }\n\n /**\n * Checks if there are any outgoing requests waiting to be sent.\n */\n public hasOutgoingRequests() {\n return this.outgoingRequests.length > 0;\n }\n}\n","import { behaviorSubject } from '@trpc/server/observable';\nimport type { UrlOptionsWithConnectionParams } from '../../internals/urlWithConnectionParams';\nimport { buildConnectionMessage, prepareUrl, withResolvers } from './utils';\n\n/**\n * Opens a WebSocket connection asynchronously and returns a promise\n * that resolves when the connection is successfully established.\n * The promise rejects if an error occurs during the connection attempt.\n */\nfunction asyncWsOpen(ws: WebSocket) {\n const { promise, resolve, reject } = withResolvers<void>();\n\n ws.addEventListener('open', () => {\n ws.removeEventListener('error', reject);\n resolve();\n });\n ws.addEventListener('error', reject);\n\n return promise;\n}\n\ninterface PingPongOptions {\n /**\n * The interval (in milliseconds) between \"PING\" messages.\n */\n intervalMs: number;\n\n /**\n * The timeout (in milliseconds) to wait for a \"PONG\" response before closing the connection.\n */\n pongTimeoutMs: number;\n}\n\n/**\n * Sets up a periodic ping-pong mechanism to keep the WebSocket connection alive.\n *\n * - Sends \"PING\" messages at regular intervals defined by `intervalMs`.\n * - If a \"PONG\" response is not received within the `pongTimeoutMs`, the WebSocket is closed.\n * - The ping timer resets upon receiving any message to maintain activity.\n * - Automatically starts the ping process when the WebSocket connection is opened.\n * - Cleans up timers when the WebSocket is closed.\n *\n * @param ws - The WebSocket instance to manage.\n * @param options - Configuration options for ping-pong intervals and timeouts.\n */\nfunction setupPingInterval(\n ws: WebSocket,\n { intervalMs, pongTimeoutMs }: PingPongOptions,\n) {\n let pingTimeout: ReturnType<typeof setTimeout> | undefined;\n let pongTimeout: ReturnType<typeof setTimeout> | undefined;\n\n function start() {\n pingTimeout = setTimeout(() => {\n ws.send('PING');\n pongTimeout = setTimeout(() => {\n ws.close();\n }, pongTimeoutMs);\n }, intervalMs);\n }\n\n function reset() {\n clearTimeout(pingTimeout);\n start();\n }\n\n function pong() {\n clearTimeout(pongTimeout);\n reset();\n }\n\n ws.addEventListener('open', start);\n ws.addEventListener('message', ({ data }) => {\n clearTimeout(pingTimeout);\n start();\n\n if (data === 'PONG') {\n pong();\n }\n });\n ws.addEventListener('close', () => {\n clearTimeout(pingTimeout);\n clearTimeout(pongTimeout);\n });\n}\n\nexport interface WebSocketConnectionOptions {\n WebSocketPonyfill?: typeof WebSocket;\n urlOptions: UrlOptionsWithConnectionParams;\n keepAlive: PingPongOptions & {\n enabled: boolean;\n };\n}\n\n/**\n * Manages a WebSocket connection with support for reconnection, keep-alive mechanisms,\n * and observable state tracking.\n */\nexport class WsConnection {\n static connectCount = 0;\n public id = ++WsConnection.connectCount;\n\n private readonly WebSocketPonyfill: typeof WebSocket;\n private readonly urlOptions: UrlOptionsWithConnectionParams;\n private readonly keepAliveOpts: WebSocketConnectionOptions['keepAlive'];\n public readonly wsObservable = behaviorSubject<WebSocket | null>(null);\n\n constructor(opts: WebSocketConnectionOptions) {\n this.WebSocketPonyfill = opts.WebSocketPonyfill ?? WebSocket;\n if (!this.WebSocketPonyfill) {\n throw new Error(\n \"No WebSocket implementation found - you probably don't want to use this on the server, but if you do you need to pass a `WebSocket`-ponyfill\",\n );\n }\n\n this.urlOptions = opts.urlOptions;\n this.keepAliveOpts = opts.keepAlive;\n }\n\n public get ws() {\n return this.wsObservable.get();\n }\n\n private set ws(ws) {\n this.wsObservable.next(ws);\n }\n\n /**\n * Checks if the WebSocket connection is open and ready to communicate.\n */\n public isOpen(): this is { ws: WebSocket } {\n return (\n !!this.ws &&\n this.ws.readyState === this.WebSocketPonyfill.OPEN &&\n !this.openPromise\n );\n }\n\n /**\n * Checks if the WebSocket connection is closed or in the process of closing.\n */\n public isClosed(): this is { ws: WebSocket } {\n return (\n !!this.ws &&\n (this.ws.readyState === this.WebSocketPonyfill.CLOSING ||\n this.ws.readyState === this.WebSocketPonyfill.CLOSED)\n );\n }\n\n /**\n * Manages the WebSocket opening process, ensuring that only one open operation\n * occurs at a time. Tracks the ongoing operation with `openPromise` to avoid\n * redundant calls and ensure proper synchronization.\n *\n * Sets up the keep-alive mechanism and necessary event listeners for the connection.\n *\n * @returns A promise that resolves once the WebSocket connection is successfully opened.\n */\n private openPromise: Promise<void> | null = null;\n public async open() {\n if (this.openPromise) return this.openPromise;\n\n this.id = ++WsConnection.connectCount;\n const wsPromise = prepareUrl(this.urlOptions).then(\n (url) => new this.WebSocketPonyfill(url),\n );\n this.openPromise = wsPromise.then(async (ws) => {\n this.ws = ws;\n\n // Set binaryType to handle both text and binary messages consistently\n ws.binaryType = 'arraybuffer';\n\n // Setup ping listener\n ws.addEventListener('message', function ({ data }) {\n if (data === 'PING') {\n this.send('PONG');\n }\n });\n\n if (this.keepAliveOpts.enabled) {\n setupPingInterval(ws, this.keepAliveOpts);\n }\n\n ws.addEventListener('close', () => {\n if (this.ws === ws) {\n this.ws = null;\n }\n });\n\n await asyncWsOpen(ws);\n\n if (this.urlOptions.connectionParams) {\n ws.send(await buildConnectionMessage(this.urlOptions.connectionParams));\n }\n });\n\n try {\n await this.openPromise;\n } finally {\n this.openPromise = null;\n }\n }\n\n /**\n * Closes the WebSocket connection gracefully.\n * Waits for any ongoing open operation to complete before closing.\n */\n public async close() {\n try {\n await this.openPromise;\n } finally {\n this.ws?.close();\n }\n }\n}\n\n/**\n * Provides a backward-compatible representation of the connection state.\n */\nexport function backwardCompatibility(connection: WsConnection) {\n if (connection.isOpen()) {\n return {\n id: connection.id,\n state: 'open',\n ws: connection.ws,\n } as const;\n }\n\n if (connection.isClosed()) {\n return {\n id: connection.id,\n state: 'closed',\n ws: connection.ws,\n } as const;\n }\n\n if (!connection.ws) {\n return null;\n }\n\n return {\n id: connection.id,\n state: 'connecting',\n ws: connection.ws,\n } as const;\n}\n","import type { AnyTRPCRouter } from '@trpc/server';\nimport type { BehaviorSubject } from '@trpc/server/observable';\nimport { behaviorSubject, observable } from '@trpc/server/observable';\nimport type {\n CombinedDataTransformer,\n TRPCClientIncomingMessage,\n TRPCClientIncomingRequest,\n TRPCClientOutgoingMessage,\n TRPCResponseMessage,\n} from '@trpc/server/unstable-core-do-not-import';\nimport {\n run,\n sleep,\n transformResult,\n} from '@trpc/server/unstable-core-do-not-import';\nimport { TRPCClientError } from '../../../TRPCClientError';\nimport type { TRPCConnectionState } from '../../internals/subscriptions';\nimport type { Operation, OperationResultEnvelope } from '../../types';\nimport type { Encoder } from './encoder';\nimport { jsonEncoder } from './encoder';\nimport type { WebSocketClientOptions } from './options';\nimport { exponentialBackoff, keepAliveDefaults, lazyDefaults } from './options';\nimport type { TCallbacks } from './requestManager';\nimport { RequestManager } from './requestManager';\nimport { ResettableTimeout, TRPCWebSocketClosedError } from './utils';\nimport { backwardCompatibility, WsConnection } from './wsConnection';\n\n/**\n * A WebSocket client for managing TRPC operations, supporting lazy initialization,\n * reconnection, keep-alive, and request management.\n */\nexport class WsClient {\n /**\n * Observable tracking the current connection state, including errors.\n */\n public readonly connectionState: BehaviorSubject<\n TRPCConnectionState<TRPCClientError<AnyTRPCRouter>>\n >;\n\n private allowReconnect = false;\n private requestManager = new RequestManager();\n private readonly activeConnection: WsConnection;\n private readonly reconnectRetryDelay: (attemptIndex: number) => number;\n private inactivityTimeout: ResettableTimeout;\n private readonly callbacks: Pick<\n WebSocketClientOptions,\n 'onOpen' | 'onClose' | 'onError'\n >;\n private readonly lazyMode: boolean;\n private readonly encoder: Encoder;\n\n constructor(opts: WebSocketClientOptions) {\n this.encoder = opts.experimental_encoder ?? jsonEncoder;\n // Initialize callbacks, connection parameters, and options.\n this.callbacks = {\n onOpen: opts.onOpen,\n onClose: opts.onClose,\n onError: opts.onError,\n };\n\n const lazyOptions = {\n ...lazyDefaults,\n ...opts.lazy,\n };\n\n // Set up inactivity timeout for lazy connections.\n this.inactivityTimeout = new ResettableTimeout(() => {\n if (\n this.requestManager.hasOutgoingRequests() ||\n this.requestManager.hasPendingRequests()\n ) {\n this.inactivityTimeout.reset();\n return;\n }\n\n this.close().catch(() => null);\n }, lazyOptions.closeMs);\n\n // Initialize the WebSocket connection.\n this.activeConnection = new WsConnection({\n WebSocketPonyfill: opts.WebSocket,\n urlOptions: opts,\n keepAlive: {\n ...keepAliveDefaults,\n ...opts.keepAlive,\n },\n });\n this.activeConnection.wsObservable.subscribe({\n next: (ws) => {\n if (!ws) return;\n this.setupWebSocketListeners(ws);\n },\n });\n this.reconnectRetryDelay = opts.retryDelayMs ?? exponentialBackoff;\n\n this.lazyMode = lazyOptions.enabled;\n\n this.connectionState = behaviorSubject<\n TRPCConnectionState<TRPCClientError<AnyTRPCRouter>>\n >({\n type: 'state',\n state: lazyOptions.enabled ? 'idle' : 'connecting',\n error: null,\n });\n\n // Automatically open the connection if lazy mode is disabled.\n if (!this.lazyMode) {\n this.open().catch(() => null);\n }\n }\n\n /**\n * Opens the WebSocket connection. Handles reconnection attempts and updates\n * the connection state accordingly.\n */\n private async open() {\n this.allowReconnect = true;\n if (this.connectionState.get().state === 'idle') {\n this.connectionState.next({\n type: 'state',\n state: 'connecting',\n error: null,\n });\n }\n\n try {\n await this.activeConnection.open();\n } catch (error) {\n this.reconnect(\n new TRPCWebSocketClosedError({\n message: 'Initialization error',\n cause: error,\n }),\n );\n return this.reconnecting;\n }\n }\n\n /**\n * Closes the WebSocket connection and stops managing requests.\n * Ensures all outgoing and pending requests are properly finalized.\n */\n public async close() {\n this.allowReconnect = false;\n this.inactivityTimeout.stop();\n\n const requestsToAwait: Promise<void>[] = [];\n for (const request of this.requestManager.getRequests()) {\n if (request.message.method === 'subscription') {\n request.callbacks.complete();\n } else if (request.state === 'outgoing') {\n request.callbacks.error(\n TRPCClientError.from(\n new TRPCWebSocketClosedError({\n message: 'Closed before connection was established',\n }),\n ),\n );\n } else {\n requestsToAwait.push(request.end);\n }\n }\n\n await Promise.all(requestsToAwait).catch(() => null);\n await this.activeConnection.close().catch(() => null);\n\n this.connectionState.next({\n type: 'state',\n state: 'idle',\n error: null,\n });\n }\n\n /**\n * Method to request the server.\n * Handles data transformation, batching of requests, and subscription lifecycle.\n *\n * @param op - The operation details including id, type, path, input and signal\n * @param transformer - Data transformer for serializing requests and deserializing responses\n * @param lastEventId - Optional ID of the last received event for subscriptions\n *\n * @returns An observable that emits operation results and handles cleanup\n */\n public request({\n op: { id, type, path, input, signal },\n transformer,\n lastEventId,\n }: {\n op: Pick<Operation, 'id' | 'type' | 'path' | 'input' | 'signal'>;\n transformer: CombinedDataTransformer;\n lastEventId?: string;\n }) {\n return observable<\n OperationResultEnvelope<unknown, TRPCClientError<AnyTRPCRouter>>,\n TRPCClientError<AnyTRPCRouter>\n >((observer) => {\n const abort = this.batchSend(\n {\n id,\n method: type,\n params: {\n input: transformer.input.serialize(input),\n path,\n lastEventId,\n },\n },\n {\n ...observer,\n next(event) {\n const transformed = transformResult(event, transformer.output);\n\n if (!transformed.ok) {\n observer.error(TRPCClientError.from(transformed.error));\n return;\n }\n\n observer.next({\n result: transformed.result,\n });\n },\n },\n );\n\n return () => {\n abort();\n\n if (type === 'subscription' && this.activeConnection.isOpen()) {\n this.send({\n id,\n method: 'subscription.stop',\n });\n }\n\n signal?.removeEventListener('abort', abort);\n };\n });\n }\n\n public get connection() {\n return backwardCompatibility(this.activeConnection);\n }\n\n /**\n * Manages the reconnection process for the WebSocket using retry logic.\n * Ensures that only one reconnection attempt is active at a time by tracking the current\n * reconnection state in the `reconnecting` promise.\n */\n private reconnecting: Promise<void> | null = null;\n private reconnect(closedError: TRPCWebSocketClosedError) {\n this.connectionState.next({\n type: 'state',\n state: 'connecting',\n error: TRPCClientError.from(closedError),\n });\n if (this.reconnecting) return;\n\n const tryReconnect = async (attemptIndex: number) => {\n try {\n await sleep(this.reconnectRetryDelay(attemptIndex));\n if (this.allowReconnect) {\n await this.activeConnection.close();\n await this.activeConnection.open();\n\n if (this.requestManager.hasPendingRequests()) {\n this.send(\n this.requestManager\n .getPendingRequests()\n .map(({ message }) => message),\n );\n }\n }\n this.reconnecting = null;\n } catch {\n await tryReconnect(attemptIndex + 1);\n }\n };\n\n this.reconnecting = tryReconnect(0);\n }\n\n private setupWebSocketListeners(ws: WebSocket) {\n const handleCloseOrError = (cause: unknown) => {\n const reqs = this.requestManager.getPendingRequests();\n for (const { message, callbacks } of reqs) {\n if (message.method === 'subscription') continue;\n\n callbacks.error(\n TRPCClientError.from(\n cause ??\n new TRPCWebSocketClosedError({\n message: 'WebSocket closed',\n cause,\n }),\n ),\n );\n this.requestManager.delete(message.id);\n }\n };\n\n ws.addEventListener('open', () => {\n run(async () => {\n if (this.lazyMode) {\n this.inactivityTimeout.start();\n }\n\n this.callbacks.onOpen?.();\n\n this.connectionState.next({\n type: 'state',\n state: 'pending',\n error: null,\n });\n }).catch((error) => {\n ws.close(3000);\n handleCloseOrError(error);\n });\n });\n\n ws.addEventListener('message', ({ data }) => {\n this.inactivityTimeout.reset();\n\n // Handle PING/PONG as text regardless of encoder\n if (['PING', 'PONG'].includes(data)) return;\n\n const incomingMessage = this.encoder.decode(\n data,\n ) as TRPCClientIncomingMessage;\n if ('method' in incomingMessage) {\n this.handleIncomingRequest(incomingMessage);\n return;\n }\n\n this.handleResponseMessage(incomingMessage);\n });\n\n ws.addEventListener('close', (event) => {\n handleCloseOrError(event);\n this.callbacks.onClose?.(event);\n\n if (!this.lazyMode || this.requestManager.hasPendingSubscriptions()) {\n this.reconnect(\n new TRPCWebSocketClosedError({\n message: 'WebSocket closed',\n cause: event,\n }),\n );\n }\n });\n\n ws.addEventListener('error', (event) => {\n handleCloseOrError(event);\n this.callbacks.onError?.(event);\n\n this.reconnect(\n new TRPCWebSocketClosedError({\n message: 'WebSocket closed',\n cause: event,\n }),\n );\n });\n }\n\n private handleResponseMessage(message: TRPCResponseMessage) {\n const request = this.requestManager.getPendingRequest(message.id);\n if (!request) return;\n\n request.callbacks.next(message);\n\n let completed = true;\n if ('result' in message && request.message.method === 'subscription') {\n if (message.result.type === 'data') {\n request.message.params.lastEventId = message.result.id;\n }\n\n if (message.result.type !== 'stopped') {\n completed = false;\n }\n }\n\n if (completed) {\n request.callbacks.complete();\n this.requestManager.delete(message.id);\n }\n }\n\n private handleIncomingRequest(message: TRPCClientIncomingRequest) {\n if (message.method === 'reconnect') {\n this.reconnect(\n new TRPCWebSocketClosedError({\n message: 'Server requested reconnect',\n }),\n );\n }\n }\n\n /**\n * Sends a message or batch of messages directly to the server.\n */\n private send(\n messageOrMessages: TRPCClientOutgoingMessage | TRPCClientOutgoingMessage[],\n ) {\n if (!this.activeConnection.isOpen()) {\n throw new Error('Active connection is not open');\n }\n\n const messages =\n messageOrMessages instanceof Array\n ? messageOrMessages\n : [messageOrMessages];\n this.activeConnection.ws.send(\n this.encoder.encode(messages.length === 1 ? messages[0] : messages),\n );\n }\n\n /**\n * Groups requests for batch sending.\n *\n * @returns A function to abort the batched request.\n */\n private batchSend(message: TRPCClientOutgoingMessage, callbacks: TCallbacks) {\n this.inactivityTimeout.reset();\n\n run(async () => {\n if (!this.activeConnection.isOpen()) {\n await this.open();\n }\n await sleep(0);\n\n if (!this.requestManager.hasOutgoingRequests()) return;\n\n this.send(this.requestManager.flush().map(({ message }) => message));\n }).catch((err) => {\n this.requestManager.delete(message.id);\n callbacks.error(TRPCClientError.from(err));\n });\n\n return this.requestManager.register(message, callbacks);\n }\n}\n","import type { Encoder } from './wsClient/encoder';\nimport { jsonEncoder } from './wsClient/encoder';\nimport type { WebSocketClientOptions } from './wsClient/options';\nimport { WsClient } from './wsClient/wsClient';\n\nexport function createWSClient(opts: WebSocketClientOptions) {\n return new WsClient(opts);\n}\n\nexport type TRPCWebSocketClient = ReturnType<typeof createWSClient>;\n\nexport { jsonEncoder, type Encoder, type WebSocketClientOptions };\n","import { observable } from '@trpc/server/observable';\nimport type {\n AnyRouter,\n inferClientTypes,\n} from '@trpc/server/unstable-core-do-not-import';\nimport type { TransformerOptions } from '../../unstable-internals';\nimport { getTransformer } from '../../unstable-internals';\nimport type { TRPCLink } from '../types';\nimport type {\n Encoder,\n TRPCWebSocketClient,\n WebSocketClientOptions,\n} from './createWsClient';\nimport { createWSClient, jsonEncoder } from './createWsClient';\n\nexport type WebSocketLinkOptions<TRouter extends AnyRouter> = {\n client: TRPCWebSocketClient;\n} & TransformerOptions<inferClientTypes<TRouter>>;\n\nexport function wsLink<TRouter extends AnyRouter>(\n opts: WebSocketLinkOptions<TRouter>,\n): TRPCLink<TRouter> {\n const { client } = opts;\n const transformer = getTransformer(opts.transformer);\n return () => {\n return ({ op }) => {\n return observable((observer) => {\n const connStateSubscription =\n op.type === 'subscription'\n ? client.connectionState.subscribe({\n next(result) {\n observer.next({\n result,\n context: op.context,\n });\n },\n })\n : null;\n\n const requestSubscription = client\n .request({\n op,\n transformer,\n })\n .subscribe(observer);\n\n return () => {\n requestSubscription.unsubscribe();\n connStateSubscription?.unsubscribe();\n };\n });\n };\n };\n}\n\nexport {\n createWSClient,\n jsonEncoder,\n type Encoder,\n type TRPCWebSocketClient,\n type WebSocketClientOptions,\n};\n"],"mappings":"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"} |
| import { TRPCConnectionState } from "./subscriptions.d-Dlr1nWGD.mjs"; | ||
| import { Operation, OperationResultEnvelope, TRPCClientError, TRPCLink } from "./types.d-CAt1zKAY.mjs"; | ||
| import { TransformerOptions } from "./unstable-internals.d-BOmV7EK1.mjs"; | ||
| import * as _trpc_server_observable0 from "@trpc/server/observable"; | ||
| import { BehaviorSubject } from "@trpc/server/observable"; | ||
| import { AnyRouter, CombinedDataTransformer, inferClientTypes } from "@trpc/server/unstable-core-do-not-import"; | ||
| import { AnyTRPCRouter } from "@trpc/server"; | ||
| import { Encoder } from "@trpc/server/adapters/ws"; | ||
| import { TRPCRequestInfo } from "@trpc/server/http"; | ||
| //#region src/links/wsLink/wsClient/encoder.d.ts | ||
| declare const jsonEncoder: Encoder; | ||
| //# sourceMappingURL=encoder.d.ts.map | ||
| //#endregion | ||
| //#region src/links/internals/urlWithConnectionParams.d.ts | ||
| /** | ||
| * A value that can be wrapped in callback | ||
| */ | ||
| type CallbackOrValue<T> = T | (() => T | Promise<T>); | ||
| interface UrlOptionsWithConnectionParams { | ||
| /** | ||
| * The URL to connect to (can be a function that returns a URL) | ||
| */ | ||
| url: CallbackOrValue<string>; | ||
| /** | ||
| * Connection params that are available in `createContext()` | ||
| * - For `wsLink`/`wsClient`, these are sent as the first message | ||
| * - For `httpSubscriptionLink`, these are serialized as part of the URL under the `connectionParams` query | ||
| */ | ||
| connectionParams?: CallbackOrValue<TRPCRequestInfo['connectionParams']>; | ||
| } | ||
| //# sourceMappingURL=urlWithConnectionParams.d.ts.map | ||
| //#endregion | ||
| //#region src/links/wsLink/wsClient/options.d.ts | ||
| interface WebSocketClientOptions extends UrlOptionsWithConnectionParams { | ||
| /** | ||
| * Ponyfill which WebSocket implementation to use | ||
| */ | ||
| WebSocket?: typeof WebSocket; | ||
| /** | ||
| * The number of milliseconds before a reconnect is attempted. | ||
| * @default {@link exponentialBackoff} | ||
| */ | ||
| retryDelayMs?: (attemptIndex: number) => number; | ||
| /** | ||
| * Triggered when a WebSocket connection is established | ||
| */ | ||
| onOpen?: () => void; | ||
| /** | ||
| * Triggered when a WebSocket connection encounters an error | ||
| */ | ||
| onError?: (evt?: Event) => void; | ||
| /** | ||
| * Triggered when a WebSocket connection is closed | ||
| */ | ||
| onClose?: (cause?: { | ||
| code?: number; | ||
| }) => void; | ||
| /** | ||
| * Lazy mode will close the WebSocket automatically after a period of inactivity (no messages sent or received and no pending requests) | ||
| */ | ||
| lazy?: { | ||
| /** | ||
| * Enable lazy mode | ||
| * @default false | ||
| */ | ||
| enabled: boolean; | ||
| /** | ||
| * Close the WebSocket after this many milliseconds | ||
| * @default 0 | ||
| */ | ||
| closeMs: number; | ||
| }; | ||
| /** | ||
| * Send ping messages to the server and kill the connection if no pong message is returned | ||
| */ | ||
| keepAlive?: { | ||
| /** | ||
| * @default false | ||
| */ | ||
| enabled: boolean; | ||
| /** | ||
| * Send a ping message every this many milliseconds | ||
| * @default 5_000 | ||
| */ | ||
| intervalMs?: number; | ||
| /** | ||
| * Close the WebSocket after this many milliseconds if the server does not respond | ||
| * @default 1_000 | ||
| */ | ||
| pongTimeoutMs?: number; | ||
| }; | ||
| /** | ||
| * Custom encoder for wire encoding (e.g. custom binary formats) | ||
| * @default jsonEncoder | ||
| */ | ||
| experimental_encoder?: Encoder; | ||
| } | ||
| /** | ||
| * Default options for lazy WebSocket connections. | ||
| * Determines whether the connection should be established lazily and defines the delay before closure. | ||
| */ | ||
| //#endregion | ||
| //#region src/links/wsLink/wsClient/wsClient.d.ts | ||
| /** | ||
| * A WebSocket client for managing TRPC operations, supporting lazy initialization, | ||
| * reconnection, keep-alive, and request management. | ||
| */ | ||
| declare class WsClient { | ||
| /** | ||
| * Observable tracking the current connection state, including errors. | ||
| */ | ||
| readonly connectionState: BehaviorSubject<TRPCConnectionState<TRPCClientError<AnyTRPCRouter>>>; | ||
| private allowReconnect; | ||
| private requestManager; | ||
| private readonly activeConnection; | ||
| private readonly reconnectRetryDelay; | ||
| private inactivityTimeout; | ||
| private readonly callbacks; | ||
| private readonly lazyMode; | ||
| private readonly encoder; | ||
| constructor(opts: WebSocketClientOptions); | ||
| /** | ||
| * Opens the WebSocket connection. Handles reconnection attempts and updates | ||
| * the connection state accordingly. | ||
| */ | ||
| private open; | ||
| /** | ||
| * Closes the WebSocket connection and stops managing requests. | ||
| * Ensures all outgoing and pending requests are properly finalized. | ||
| */ | ||
| close(): Promise<void>; | ||
| /** | ||
| * Method to request the server. | ||
| * Handles data transformation, batching of requests, and subscription lifecycle. | ||
| * | ||
| * @param op - The operation details including id, type, path, input and signal | ||
| * @param transformer - Data transformer for serializing requests and deserializing responses | ||
| * @param lastEventId - Optional ID of the last received event for subscriptions | ||
| * | ||
| * @returns An observable that emits operation results and handles cleanup | ||
| */ | ||
| request({ | ||
| op: { | ||
| id, | ||
| type, | ||
| path, | ||
| input, | ||
| signal | ||
| }, | ||
| transformer, | ||
| lastEventId | ||
| }: { | ||
| op: Pick<Operation, 'id' | 'type' | 'path' | 'input' | 'signal'>; | ||
| transformer: CombinedDataTransformer; | ||
| lastEventId?: string; | ||
| }): _trpc_server_observable0.Observable<OperationResultEnvelope<unknown, TRPCClientError<AnyTRPCRouter>>, TRPCClientError<AnyTRPCRouter>>; | ||
| get connection(): { | ||
| readonly id: number; | ||
| readonly state: "open"; | ||
| readonly ws: WebSocket; | ||
| } | { | ||
| readonly id: number; | ||
| readonly state: "closed"; | ||
| readonly ws: WebSocket; | ||
| } | { | ||
| readonly id: number; | ||
| readonly state: "connecting"; | ||
| readonly ws: WebSocket; | ||
| } | null; | ||
| /** | ||
| * Manages the reconnection process for the WebSocket using retry logic. | ||
| * Ensures that only one reconnection attempt is active at a time by tracking the current | ||
| * reconnection state in the `reconnecting` promise. | ||
| */ | ||
| private reconnecting; | ||
| private reconnect; | ||
| private setupWebSocketListeners; | ||
| private handleResponseMessage; | ||
| private handleIncomingRequest; | ||
| /** | ||
| * Sends a message or batch of messages directly to the server. | ||
| */ | ||
| private send; | ||
| /** | ||
| * Groups requests for batch sending. | ||
| * | ||
| * @returns A function to abort the batched request. | ||
| */ | ||
| private batchSend; | ||
| } | ||
| //# sourceMappingURL=wsClient.d.ts.map | ||
| //#endregion | ||
| //#region src/links/wsLink/createWsClient.d.ts | ||
| declare function createWSClient(opts: WebSocketClientOptions): WsClient; | ||
| type TRPCWebSocketClient = ReturnType<typeof createWSClient>; | ||
| //#endregion | ||
| //#region src/links/wsLink/wsLink.d.ts | ||
| type WebSocketLinkOptions<TRouter extends AnyRouter> = { | ||
| client: TRPCWebSocketClient; | ||
| } & TransformerOptions<inferClientTypes<TRouter>>; | ||
| declare function wsLink<TRouter extends AnyRouter>(opts: WebSocketLinkOptions<TRouter>): TRPCLink<TRouter>; | ||
| //#endregion | ||
| export { Encoder, TRPCWebSocketClient, UrlOptionsWithConnectionParams, WebSocketClientOptions, WebSocketLinkOptions, createWSClient, jsonEncoder, wsLink }; | ||
| //# sourceMappingURL=wsLink.d-CDi0tYE2.d.mts.map |
| {"version":3,"file":"wsLink.d-CDi0tYE2.d.mts","names":[],"sources":["../src/links/wsLink/wsClient/encoder.ts","../src/links/internals/urlWithConnectionParams.ts","../src/links/wsLink/wsClient/options.ts","../src/links/wsLink/wsClient/wsClient.ts","../src/links/wsLink/createWsClient.ts","../src/links/wsLink/wsLink.ts"],"sourcesContent":[],"mappings":";;;;;;;;;;;cAIa,aAAa;;;;;;;;KCcd,qBAAqB,WAAW,IAAI,QAAQ;UAEvC,8BAAA;EDhBJ;;;OCoBN;EANK;;;;;EAA6C,gBAAT,CAAA,EAa3B,eAb2B,CAaX,eAbW,CAAA,kBAAA,CAAA,CAAA;AAAO;AAEvD;;;UCjBiB,sBAAA,SAA+B;;;;qBAI3B;;;;;EFHR,YAAA,CAAA,EAWZ,CAAA,YAXyB,EAAA,MAWzB,EAAA,GAAA,MAAA;;;;ECGW,MAAA,CAAA,EAAA,GAAA,GAAA,IAAe;EAAA;;;EAAkB,OAAW,CAAA,EAAA,CAAA,GAAA,CAAA,ECErC,KDFqC,EAAA,GAAA,IAAA;EAAC;AAAF;AAEvD;EAA+C,OAAA,CAAA,EAAA,CAAA,KAIzB,CAJyB,EAAA;IAIxC,IAAA,CAAA,EAAA,MAAA;EAAe,CAAA,EAOe,GAAA,IAAA;EAAe;AAAhB;;;;AC5BpC;;;IAiBmB,OAAA,EAAA,OAAA;IA2CM;;AA5DqD;;;;EC4BjE;;;EAKwC,SAA7B,CAAA,EAAA;IAApB;;;IA0GgB,OAAA,EAAA,OAAA;IA0CV;;;;IAAuB,UAAA,CAAA,EAAA,MAAA;IAC7B;;;;IAIa,aAAA,CAAA,EAAA,MAAA;EAAuB,CAAA;EAErC;;;;EAAA,oBAAA,CAAA,EDhIsB,OCgItB;;;;;;;;;;;;AH3LU,cG2BA,QAAA,CH3Ba;;;;ECcd,SAAA,eAAe,EEiBQ,eFjBR,CEkBvB,mBFlBuB,CEkBH,eFlBG,CEkBa,aFlBb,CAAA,CAAA,CAAA;EAAA,QAAA,cAAA;EAAA,QAAM,cAAA;EAAC,iBAAU,gBAAA;EAAC,iBAAW,mBAAA;EAAC,QAAT,iBAAA;EAAO,iBAAA,SAAA;EAEtC,iBAAA,QAAA;EAA8B,iBAAA,OAAA;EAAA,WAIxC,CAAA,IAAA,EE2Ba,sBF3Bb;EAAe;;AAOc;;;;AC5BpC;;;EAI8B,KAaX,CAAA,CAAA,EC0HC,OD1HD,CAAA,IAAA,CAAA;EAAK;;AAjBsD;;;;AC4B9E;;;;EAKuC,OAAnC,CAAA;IAAA,EAAA,EAAA;MAAA,EAAA;MAAA,IAAA;MAAA,IAAA;MAAA,KAAA;MAAA;IAAA,CAAA;IAAA,WAAA;IAAA;EA0GgB,CA1GhB,EAAA;IAD+B,EAAA,EAyJ3B,IAzJ2B,CAyJtB,SAzJsB,EAAA,IAAA,GAAA,MAAA,GAAA,MAAA,GAAA,OAAA,GAAA,QAAA,CAAA;IAgBf,WAAA,EA0IH,uBA1IG;IA2FA,WAAA,CAAA,EAAA,MAAA;EAAA,CAAA,CAAA,EAiDjB,wBAAA,CAAA,UAPO,CAOP,uBAPO,CAAA,OAAA,EAOP,eAPO,CAOP,aAPO,CAAA,CAAA,EAOP,eAPO,CAOP,aAPO,CAAA,CAAA;EAAE,IAAE,UAAA,CAAA,CAAA,EAAA;IAAM,SAAA,EAAA,EAAA,MAAA;IAAM,SAAA,KAAA,EAAA,MAAA;IAAO,SAAA,EAAA,EAO9B,SAP8B;EAAM,CAAA,GACnC;IACA,SAAA,EAAA,EAAA,MAAA;IAES,SAAA,KAAA,EAAA,QAAA;IAAL,SAAA,EAAA,WAAA;EAAI,CAAA,GACK;IAEd,SAAA,EAAA,EAAA,MAAA;IAAA,SAAA,KAAA,EAAA,YAAA;IAAA,SAAA,EAAA,WAAA;EAAA,CAAA,GAAA,IAAA;EAAA;;;;;;;;;EC1La,QAAA,qBAAc;EAAA;;;EAA6B,QAAA,IAAA;EAI/C;;;;AAAgC;;;;;;iBAJ5B,cAAA,OAAqB,yBAAsB;KAI/C,mBAAA,GAAsB,kBAAkB;;;KCMxC,qCAAqC;UACvC;IACN,mBAAmB,iBAAiB;iBAExB,uBAAuB,iBAC/B,qBAAqB,WAC1B,SAAS"} |
| import { TRPCConnectionState } from "./subscriptions.d-Ciljg_dH.cjs"; | ||
| import { Operation, OperationResultEnvelope, TRPCClientError, TRPCLink } from "./types.d-B2PuQAdV.cjs"; | ||
| import { TransformerOptions } from "./unstable-internals.d-kWsZTlQq.cjs"; | ||
| import { AnyRouter, CombinedDataTransformer, inferClientTypes } from "@trpc/server/unstable-core-do-not-import"; | ||
| import * as _trpc_server_observable0 from "@trpc/server/observable"; | ||
| import { BehaviorSubject } from "@trpc/server/observable"; | ||
| import { AnyTRPCRouter } from "@trpc/server"; | ||
| import { Encoder } from "@trpc/server/adapters/ws"; | ||
| import { TRPCRequestInfo } from "@trpc/server/http"; | ||
| //#region src/links/wsLink/wsClient/encoder.d.ts | ||
| declare const jsonEncoder: Encoder; | ||
| //# sourceMappingURL=encoder.d.ts.map | ||
| //#endregion | ||
| //#region src/links/internals/urlWithConnectionParams.d.ts | ||
| /** | ||
| * A value that can be wrapped in callback | ||
| */ | ||
| type CallbackOrValue<T> = T | (() => T | Promise<T>); | ||
| interface UrlOptionsWithConnectionParams { | ||
| /** | ||
| * The URL to connect to (can be a function that returns a URL) | ||
| */ | ||
| url: CallbackOrValue<string>; | ||
| /** | ||
| * Connection params that are available in `createContext()` | ||
| * - For `wsLink`/`wsClient`, these are sent as the first message | ||
| * - For `httpSubscriptionLink`, these are serialized as part of the URL under the `connectionParams` query | ||
| */ | ||
| connectionParams?: CallbackOrValue<TRPCRequestInfo['connectionParams']>; | ||
| } | ||
| //# sourceMappingURL=urlWithConnectionParams.d.ts.map | ||
| //#endregion | ||
| //#region src/links/wsLink/wsClient/options.d.ts | ||
| interface WebSocketClientOptions extends UrlOptionsWithConnectionParams { | ||
| /** | ||
| * Ponyfill which WebSocket implementation to use | ||
| */ | ||
| WebSocket?: typeof WebSocket; | ||
| /** | ||
| * The number of milliseconds before a reconnect is attempted. | ||
| * @default {@link exponentialBackoff} | ||
| */ | ||
| retryDelayMs?: (attemptIndex: number) => number; | ||
| /** | ||
| * Triggered when a WebSocket connection is established | ||
| */ | ||
| onOpen?: () => void; | ||
| /** | ||
| * Triggered when a WebSocket connection encounters an error | ||
| */ | ||
| onError?: (evt?: Event) => void; | ||
| /** | ||
| * Triggered when a WebSocket connection is closed | ||
| */ | ||
| onClose?: (cause?: { | ||
| code?: number; | ||
| }) => void; | ||
| /** | ||
| * Lazy mode will close the WebSocket automatically after a period of inactivity (no messages sent or received and no pending requests) | ||
| */ | ||
| lazy?: { | ||
| /** | ||
| * Enable lazy mode | ||
| * @default false | ||
| */ | ||
| enabled: boolean; | ||
| /** | ||
| * Close the WebSocket after this many milliseconds | ||
| * @default 0 | ||
| */ | ||
| closeMs: number; | ||
| }; | ||
| /** | ||
| * Send ping messages to the server and kill the connection if no pong message is returned | ||
| */ | ||
| keepAlive?: { | ||
| /** | ||
| * @default false | ||
| */ | ||
| enabled: boolean; | ||
| /** | ||
| * Send a ping message every this many milliseconds | ||
| * @default 5_000 | ||
| */ | ||
| intervalMs?: number; | ||
| /** | ||
| * Close the WebSocket after this many milliseconds if the server does not respond | ||
| * @default 1_000 | ||
| */ | ||
| pongTimeoutMs?: number; | ||
| }; | ||
| /** | ||
| * Custom encoder for wire encoding (e.g. custom binary formats) | ||
| * @default jsonEncoder | ||
| */ | ||
| experimental_encoder?: Encoder; | ||
| } | ||
| /** | ||
| * Default options for lazy WebSocket connections. | ||
| * Determines whether the connection should be established lazily and defines the delay before closure. | ||
| */ | ||
| //#endregion | ||
| //#region src/links/wsLink/wsClient/wsClient.d.ts | ||
| /** | ||
| * A WebSocket client for managing TRPC operations, supporting lazy initialization, | ||
| * reconnection, keep-alive, and request management. | ||
| */ | ||
| declare class WsClient { | ||
| /** | ||
| * Observable tracking the current connection state, including errors. | ||
| */ | ||
| readonly connectionState: BehaviorSubject<TRPCConnectionState<TRPCClientError<AnyTRPCRouter>>>; | ||
| private allowReconnect; | ||
| private requestManager; | ||
| private readonly activeConnection; | ||
| private readonly reconnectRetryDelay; | ||
| private inactivityTimeout; | ||
| private readonly callbacks; | ||
| private readonly lazyMode; | ||
| private readonly encoder; | ||
| constructor(opts: WebSocketClientOptions); | ||
| /** | ||
| * Opens the WebSocket connection. Handles reconnection attempts and updates | ||
| * the connection state accordingly. | ||
| */ | ||
| private open; | ||
| /** | ||
| * Closes the WebSocket connection and stops managing requests. | ||
| * Ensures all outgoing and pending requests are properly finalized. | ||
| */ | ||
| close(): Promise<void>; | ||
| /** | ||
| * Method to request the server. | ||
| * Handles data transformation, batching of requests, and subscription lifecycle. | ||
| * | ||
| * @param op - The operation details including id, type, path, input and signal | ||
| * @param transformer - Data transformer for serializing requests and deserializing responses | ||
| * @param lastEventId - Optional ID of the last received event for subscriptions | ||
| * | ||
| * @returns An observable that emits operation results and handles cleanup | ||
| */ | ||
| request({ | ||
| op: { | ||
| id, | ||
| type, | ||
| path, | ||
| input, | ||
| signal | ||
| }, | ||
| transformer, | ||
| lastEventId | ||
| }: { | ||
| op: Pick<Operation, 'id' | 'type' | 'path' | 'input' | 'signal'>; | ||
| transformer: CombinedDataTransformer; | ||
| lastEventId?: string; | ||
| }): _trpc_server_observable0.Observable<OperationResultEnvelope<unknown, TRPCClientError<AnyTRPCRouter>>, TRPCClientError<AnyTRPCRouter>>; | ||
| get connection(): { | ||
| readonly id: number; | ||
| readonly state: "open"; | ||
| readonly ws: WebSocket; | ||
| } | { | ||
| readonly id: number; | ||
| readonly state: "closed"; | ||
| readonly ws: WebSocket; | ||
| } | { | ||
| readonly id: number; | ||
| readonly state: "connecting"; | ||
| readonly ws: WebSocket; | ||
| } | null; | ||
| /** | ||
| * Manages the reconnection process for the WebSocket using retry logic. | ||
| * Ensures that only one reconnection attempt is active at a time by tracking the current | ||
| * reconnection state in the `reconnecting` promise. | ||
| */ | ||
| private reconnecting; | ||
| private reconnect; | ||
| private setupWebSocketListeners; | ||
| private handleResponseMessage; | ||
| private handleIncomingRequest; | ||
| /** | ||
| * Sends a message or batch of messages directly to the server. | ||
| */ | ||
| private send; | ||
| /** | ||
| * Groups requests for batch sending. | ||
| * | ||
| * @returns A function to abort the batched request. | ||
| */ | ||
| private batchSend; | ||
| } | ||
| //# sourceMappingURL=wsClient.d.ts.map | ||
| //#endregion | ||
| //#region src/links/wsLink/createWsClient.d.ts | ||
| declare function createWSClient(opts: WebSocketClientOptions): WsClient; | ||
| type TRPCWebSocketClient = ReturnType<typeof createWSClient>; | ||
| //#endregion | ||
| //#region src/links/wsLink/wsLink.d.ts | ||
| type WebSocketLinkOptions<TRouter extends AnyRouter> = { | ||
| client: TRPCWebSocketClient; | ||
| } & TransformerOptions<inferClientTypes<TRouter>>; | ||
| declare function wsLink<TRouter extends AnyRouter>(opts: WebSocketLinkOptions<TRouter>): TRPCLink<TRouter>; | ||
| //#endregion | ||
| export { Encoder, TRPCWebSocketClient, UrlOptionsWithConnectionParams, WebSocketClientOptions, WebSocketLinkOptions, createWSClient, jsonEncoder, wsLink }; | ||
| //# sourceMappingURL=wsLink.d-DSgoRR08.d.cts.map |
| {"version":3,"file":"wsLink.d-DSgoRR08.d.cts","names":[],"sources":["../src/links/wsLink/wsClient/encoder.ts","../src/links/internals/urlWithConnectionParams.ts","../src/links/wsLink/wsClient/options.ts","../src/links/wsLink/wsClient/wsClient.ts","../src/links/wsLink/createWsClient.ts","../src/links/wsLink/wsLink.ts"],"sourcesContent":[],"mappings":";;;;;;;;;;;cAIa,aAAa;;;;;;;;KCcd,qBAAqB,WAAW,IAAI,QAAQ;UAEvC,8BAAA;EDhBJ;;;OCoBN;EANK;;;;;EAA6C,gBAAT,CAAA,EAa3B,eAb2B,CAaX,eAbW,CAAA,kBAAA,CAAA,CAAA;AAAO;AAEvD;;;UCjBiB,sBAAA,SAA+B;;;;qBAI3B;;;;;EFHR,YAAA,CAAA,EAWZ,CAAA,YAXyB,EAAA,MAWzB,EAAA,GAAA,MAAA;;;;ECGW,MAAA,CAAA,EAAA,GAAA,GAAA,IAAe;EAAA;;;EAAkB,OAAW,CAAA,EAAA,CAAA,GAAA,CAAA,ECErC,KDFqC,EAAA,GAAA,IAAA;EAAC;AAAF;AAEvD;EAA+C,OAAA,CAAA,EAAA,CAAA,KAIzB,CAJyB,EAAA;IAIxC,IAAA,CAAA,EAAA,MAAA;EAAe,CAAA,EAOe,GAAA,IAAA;EAAe;AAAhB;;;;AC5BpC;;;IAiBmB,OAAA,EAAA,OAAA;IA2CM;;AA5DqD;;;;EC4BjE;;;EAKwC,SAA7B,CAAA,EAAA;IAApB;;;IA0GgB,OAAA,EAAA,OAAA;IA0CV;;;;IAAuB,UAAA,CAAA,EAAA,MAAA;IAC7B;;;;IAIa,aAAA,CAAA,EAAA,MAAA;EAAuB,CAAA;EAErC;;;;EAAA,oBAAA,CAAA,EDhIsB,OCgItB;;;;;;;;;;;;AH3LU,cG2BA,QAAA,CH3Ba;;;;ECcd,SAAA,eAAe,EEiBQ,eFjBR,CEkBvB,mBFlBuB,CEkBH,eFlBG,CEkBa,aFlBb,CAAA,CAAA,CAAA;EAAA,QAAA,cAAA;EAAA,QAAM,cAAA;EAAC,iBAAU,gBAAA;EAAC,iBAAW,mBAAA;EAAC,QAAT,iBAAA;EAAO,iBAAA,SAAA;EAEtC,iBAAA,QAAA;EAA8B,iBAAA,OAAA;EAAA,WAIxC,CAAA,IAAA,EE2Ba,sBF3Bb;EAAe;;AAOc;;;;AC5BpC;;;EAI8B,KAaX,CAAA,CAAA,EC0HC,OD1HD,CAAA,IAAA,CAAA;EAAK;;AAjBsD;;;;AC4B9E;;;;EAKuC,OAAnC,CAAA;IAAA,EAAA,EAAA;MAAA,EAAA;MAAA,IAAA;MAAA,IAAA;MAAA,KAAA;MAAA;IAAA,CAAA;IAAA,WAAA;IAAA;EA0GgB,CA1GhB,EAAA;IAD+B,EAAA,EAyJ3B,IAzJ2B,CAyJtB,SAzJsB,EAAA,IAAA,GAAA,MAAA,GAAA,MAAA,GAAA,OAAA,GAAA,QAAA,CAAA;IAgBf,WAAA,EA0IH,uBA1IG;IA2FA,WAAA,CAAA,EAAA,MAAA;EAAA,CAAA,CAAA,EAiDjB,wBAAA,CAAA,UAPO,CAOP,uBAPO,CAAA,OAAA,EAOP,eAPO,CAOP,aAPO,CAAA,CAAA,EAOP,eAPO,CAOP,aAPO,CAAA,CAAA;EAAE,IAAE,UAAA,CAAA,CAAA,EAAA;IAAM,SAAA,EAAA,EAAA,MAAA;IAAM,SAAA,KAAA,EAAA,MAAA;IAAO,SAAA,EAAA,EAO9B,SAP8B;EAAM,CAAA,GACnC;IACA,SAAA,EAAA,EAAA,MAAA;IAES,SAAA,KAAA,EAAA,QAAA;IAAL,SAAA,EAAA,WAAA;EAAI,CAAA,GACK;IAEd,SAAA,EAAA,EAAA,MAAA;IAAA,SAAA,KAAA,EAAA,YAAA;IAAA,SAAA,EAAA,WAAA;EAAA,CAAA,GAAA,IAAA;EAAA;;;;;;;;;EC1La,QAAA,qBAAc;EAAA;;;EAA6B,QAAA,IAAA;EAI/C;;;;AAAgC;;;;;;iBAJ5B,cAAA,OAAqB,yBAAsB;KAI/C,mBAAA,GAAsB,kBAAkB;;;KCMxC,qCAAqC;UACvC;IACN,mBAAmB,iBAAiB;iBAExB,uBAAuB,iBAC/B,qBAAqB,WAC1B,SAAS"} |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Manifest confusion
Supply chain riskThis package has inconsistent metadata. This could be malicious or caused by an error when publishing the package.
Found 1 instance in 1 package
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
Found 1 instance in 1 package
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
Found 1 instance in 1 package
560090
0.11%8552
0.09%1
Infinity%2
100%