@rpcbase/client 0.465.0 → 0.466.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rpcbase/client",
3
- "version": "0.465.0",
3
+ "version": "0.466.0",
4
4
  "type": "module",
5
5
  "files": [
6
6
  "dist"
@@ -1,18 +0,0 @@
1
- let reporter;
2
- const setClientExceptionReporter = (next) => {
3
- reporter = next;
4
- };
5
- const reportClientException = (error, context = {}) => {
6
- if (!error) return;
7
- const err = error instanceof Error ? error : new Error(String(error));
8
- try {
9
- reporter?.(err, context);
10
- } catch (reportError) {
11
- console.error("[rb/client] exception reporter failed", reportError);
12
- }
13
- };
14
- export {
15
- reportClientException as r,
16
- setClientExceptionReporter as s
17
- };
18
- //# sourceMappingURL=errorReporting-CVoUUKxW.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"errorReporting-CVoUUKxW.js","sources":["../src/errorReporting.ts"],"sourcesContent":["export type ClientExceptionContext = {\n reactContext?: \"uncaught\" | \"caught\" | \"recoverable\"\n componentStack?: string\n}\n\nexport type ClientExceptionReporter = (error: Error, context: ClientExceptionContext) => void\n\nlet reporter: ClientExceptionReporter | undefined\n\nexport const setClientExceptionReporter = (next: ClientExceptionReporter | undefined) => {\n reporter = next\n}\n\nexport const reportClientException = (error: unknown, context: ClientExceptionContext = {}) => {\n if (!error) return\n\n const err = error instanceof Error ? error : new Error(String(error))\n\n try {\n reporter?.(err, context)\n } catch (reportError) {\n console.error(\"[rb/client] exception reporter failed\", reportError)\n }\n}\n\n"],"names":["reporter","setClientExceptionReporter","next","reportClientException","error","context","err","Error","String","reportError","console"],"mappings":"AAOA,IAAIA;AAEG,MAAMC,6BAA6BA,CAACC,SAA8C;AACvFF,aAAWE;AACb;AAEO,MAAMC,wBAAwBA,CAACC,OAAgBC,UAAkC,OAAO;AAC7F,MAAI,CAACD,MAAO;AAEZ,QAAME,MAAMF,iBAAiBG,QAAQH,QAAQ,IAAIG,MAAMC,OAAOJ,KAAK,CAAC;AAEpE,MAAI;AACFJ,eAAWM,KAAKD,OAAO;AAAA,EACzB,SAASI,aAAa;AACpBC,YAAQN,MAAM,yCAAyCK,WAAW;AAAA,EACpE;AACF;"}
@@ -1,192 +0,0 @@
1
- const getServerApiClient = async (app) => {
2
- const isCtx = (value) => {
3
- if (!value || typeof value !== "object") return false;
4
- return "req" in value && "res" in value;
5
- };
6
- const createAbortError = () => {
7
- const error = new Error("The operation was aborted.");
8
- error.name = "AbortError";
9
- return error;
10
- };
11
- const callRoute = async (app2, method, matchPath, requestUrl, req, res) => {
12
- return new Promise((resolve, reject) => {
13
- let isEnded = false;
14
- let timeoutId = null;
15
- const resolveRequest = (data) => {
16
- if (isEnded) return;
17
- isEnded = true;
18
- if (timeoutId) clearTimeout(timeoutId);
19
- resolve(data);
20
- };
21
- const rejectRequest = (error) => {
22
- if (isEnded) return;
23
- isEnded = true;
24
- if (timeoutId) clearTimeout(timeoutId);
25
- reject(error);
26
- };
27
- const mockReq = {
28
- ...req,
29
- method: method.toUpperCase(),
30
- url: requestUrl
31
- };
32
- const mockRes = {
33
- ...res,
34
- json: (data) => {
35
- resolveRequest(data);
36
- },
37
- status: (statusCode) => {
38
- console.log("Status:", statusCode, mockReq.method, mockReq.url);
39
- return mockRes;
40
- }
41
- };
42
- const routerStack = app2.router.stack;
43
- const firstApiMiddlewareIndex = routerStack.findIndex((layer) => layer.name === "__FIRST_API_MIDDLEWARE__");
44
- if (!(firstApiMiddlewareIndex > -1)) {
45
- throw new Error("middleware: __FIRST_API_MIDDLEWARE__ was not found in stack");
46
- }
47
- const apiStack = routerStack.slice(firstApiMiddlewareIndex + 1);
48
- const processLayer = async (index) => {
49
- if (index >= apiStack.length || isEnded) return;
50
- const layer = apiStack[index];
51
- const isNonMatchingLayer = !layer.match(matchPath);
52
- if (isNonMatchingLayer) {
53
- await processLayer(index + 1);
54
- return;
55
- }
56
- const runHandler = async (handler) => new Promise((resolveMiddleware, rejectMiddleware) => {
57
- handler(mockReq, mockRes, (err) => {
58
- if (err) {
59
- console.error("Middleware error:", err);
60
- rejectMiddleware(err);
61
- return;
62
- }
63
- resolveMiddleware();
64
- });
65
- });
66
- if (layer.route) {
67
- if (!layer.route.methods[method.toLowerCase()]) {
68
- await processLayer(index + 1);
69
- return;
70
- }
71
- if (layer.route.stack.length !== 1) {
72
- throw new Error(`expected only one handler per route for route: ${layer.route.path}`);
73
- }
74
- await runHandler(layer.route.stack[0].handle);
75
- } else {
76
- await runHandler(layer.handle);
77
- }
78
- if (!isEnded) {
79
- await processLayer(index + 1);
80
- }
81
- };
82
- void processLayer(0).catch((err) => {
83
- rejectRequest(err);
84
- });
85
- timeoutId = setTimeout(() => {
86
- rejectRequest(new Error("Route handler timed out"));
87
- }, 3e4);
88
- });
89
- };
90
- const mergeQueryValues = (target, key, value) => {
91
- const existing = target[key];
92
- if (Array.isArray(existing)) {
93
- existing.push(value);
94
- return;
95
- }
96
- if (typeof existing === "string") {
97
- target[key] = [existing, value];
98
- return;
99
- }
100
- target[key] = value;
101
- };
102
- const toQueryValue = (value) => {
103
- if (typeof value === "string") return value;
104
- if (typeof value === "number") return Number.isFinite(value) ? String(value) : null;
105
- if (typeof value === "boolean") return value ? "true" : "false";
106
- if (typeof value === "bigint") return String(value);
107
- if (value instanceof Date) return value.toISOString();
108
- return null;
109
- };
110
- const buildQuery = (path, payload) => {
111
- const url = new URL(path, "http://localhost");
112
- const query = {};
113
- for (const [key, value] of url.searchParams) {
114
- mergeQueryValues(query, key, value);
115
- }
116
- for (const [key, rawValue] of Object.entries(payload)) {
117
- if (!key) continue;
118
- if (Array.isArray(rawValue)) {
119
- for (const item of rawValue) {
120
- const converted2 = toQueryValue(item);
121
- if (converted2 !== null) mergeQueryValues(query, key, converted2);
122
- }
123
- continue;
124
- }
125
- const converted = toQueryValue(rawValue);
126
- if (converted !== null) mergeQueryValues(query, key, converted);
127
- }
128
- const searchParams = new URLSearchParams();
129
- for (const [key, rawValue] of Object.entries(query)) {
130
- if (Array.isArray(rawValue)) {
131
- for (const value of rawValue) {
132
- searchParams.append(key, value);
133
- }
134
- continue;
135
- }
136
- searchParams.append(key, rawValue);
137
- }
138
- const matchPath = url.pathname;
139
- const requestUrl = `${matchPath}${searchParams.toString() ? `?${searchParams.toString()}` : ""}`;
140
- return {
141
- matchPath,
142
- requestUrl,
143
- query
144
- };
145
- };
146
- const createMethod = (method) => {
147
- return async (path, payload, ctxOrOptions, options) => {
148
- const ctx = isCtx(ctxOrOptions) ? ctxOrOptions : void 0;
149
- const requestOptions = isCtx(ctxOrOptions) ? options : ctxOrOptions;
150
- if (!ctx) {
151
- throw new Error("Context must be provided in SSR mode");
152
- }
153
- if (requestOptions?.signal?.aborted) {
154
- throw createAbortError();
155
- }
156
- const normalizedMethod = method.toLowerCase();
157
- if (normalizedMethod === "get") {
158
- const {
159
- matchPath: matchPath2,
160
- requestUrl: requestUrl2,
161
- query: query2
162
- } = buildQuery(path, payload);
163
- return callRoute(app, method, matchPath2, requestUrl2, {
164
- ...ctx.req,
165
- body: {},
166
- query: query2
167
- }, ctx.res);
168
- }
169
- const {
170
- matchPath,
171
- requestUrl,
172
- query
173
- } = buildQuery(path, {});
174
- return callRoute(app, method, matchPath, requestUrl, {
175
- ...ctx.req,
176
- body: payload,
177
- query
178
- }, ctx.res);
179
- };
180
- };
181
- const apiClient = {
182
- get: createMethod("get"),
183
- post: createMethod("post"),
184
- put: createMethod("put"),
185
- delete: createMethod("delete")
186
- };
187
- return apiClient;
188
- };
189
- export {
190
- getServerApiClient
191
- };
192
- //# sourceMappingURL=getServerApiClient-DnG8591C.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"getServerApiClient-DnG8591C.js","sources":["../src/apiClient/getServerApiClient.ts"],"sourcesContent":["import { Application, IRouter, Request, Response } from \"express\"\nimport type { Ctx } from \"@rpcbase/api\"\n\n\ntype NextMiddleware = (err?: unknown) => void\ntype LayerHandler = (req: Request, res: Response, next: NextMiddleware) => void\ntype ApiClientRequestOptions = {\n signal?: AbortSignal\n}\n\ntype RouterLayer = {\n name: string\n match: (path: string) => boolean\n handle: LayerHandler\n route?: {\n methods: Record<string, boolean | undefined>\n path: string\n stack: Array<{ handle: LayerHandler }>\n }\n}\n\n\nexport const getServerApiClient = async(app: Application) => {\n const isCtx = (value: unknown): value is Ctx => {\n if (!value || typeof value !== \"object\") return false\n return \"req\" in value && \"res\" in value\n }\n\n const createAbortError = () => {\n const error = new Error(\"The operation was aborted.\")\n error.name = \"AbortError\"\n return error\n }\n\n const callRoute = async <TResponse = Record<string, unknown>>(\n app: Application,\n method: string,\n matchPath: string,\n requestUrl: string,\n req: Partial<Request>,\n res: Partial<Response>\n ): Promise<TResponse> => {\n return new Promise((resolve, reject) => {\n let isEnded = false\n let timeoutId: ReturnType<typeof setTimeout> | null = null\n\n const resolveRequest = (data: TResponse) => {\n if (isEnded) return\n isEnded = true\n if (timeoutId) clearTimeout(timeoutId)\n resolve(data)\n }\n\n const rejectRequest = (error: unknown) => {\n if (isEnded) return\n isEnded = true\n if (timeoutId) clearTimeout(timeoutId)\n reject(error)\n }\n\n const mockReq = {\n ...req,\n method: method.toUpperCase(),\n url: requestUrl\n } as Request\n\n const mockRes = {\n ...res,\n json: (data: unknown) => {\n resolveRequest(data as TResponse)\n },\n status: (statusCode: number) => {\n console.log(\"Status:\", statusCode, mockReq.method, mockReq.url)\n return mockRes\n },\n } as Response\n\n const routerStack = (app.router as unknown as IRouter).stack as unknown as RouterLayer[]\n\n const firstApiMiddlewareIndex = routerStack.findIndex((layer) => layer.name === \"__FIRST_API_MIDDLEWARE__\")\n if (!(firstApiMiddlewareIndex > -1)) {\n throw new Error(\"middleware: __FIRST_API_MIDDLEWARE__ was not found in stack\")\n }\n\n const apiStack = routerStack.slice(firstApiMiddlewareIndex + 1)\n\n const processLayer = async (index: number) => {\n if (index >= apiStack.length || isEnded) return\n\n const layer = apiStack[index]\n\n const isNonMatchingLayer = !layer.match(matchPath)\n if (isNonMatchingLayer) {\n // console.log(\"not machthing route:\", matchPath, \"to layer:\", index, layer.name, layer, \"reason: \", {isNonMatchingLayer})\n await processLayer(index + 1)\n return\n }\n\n const runHandler = async(handler: LayerHandler) => new Promise<void>((resolveMiddleware, rejectMiddleware) => {\n handler(mockReq, mockRes, (err?: unknown) => {\n if (err) {\n console.error(\"Middleware error:\", err)\n rejectMiddleware(err)\n return\n }\n resolveMiddleware()\n })\n })\n\n if (layer.route) {\n if (!layer.route.methods[method.toLowerCase()]) {\n // console.log(\"not machthing route:\", matchPath, \"to route layer:\", index, layer.name, layer, \"reason: method not matching\")\n await processLayer(index + 1)\n return\n }\n\n if (layer.route.stack.length !== 1) {\n throw new Error(`expected only one handler per route for route: ${layer.route.path}`)\n }\n\n await runHandler(layer.route.stack[0].handle)\n\n } else {\n await runHandler(layer.handle)\n }\n\n if (!isEnded) {\n await processLayer(index + 1)\n }\n }\n\n void processLayer(0).catch((err) => {\n rejectRequest(err)\n })\n\n // Set a timeout to prevent hanging\n timeoutId = setTimeout(() => {\n rejectRequest(new Error(\"Route handler timed out\"))\n }, 30000)\n })\n }\n\n const mergeQueryValues = (target: Record<string, string | string[]>, key: string, value: string) => {\n const existing = target[key]\n if (Array.isArray(existing)) {\n existing.push(value)\n return\n }\n\n if (typeof existing === \"string\") {\n target[key] = [existing, value]\n return\n }\n\n target[key] = value\n }\n\n const toQueryValue = (value: unknown): string | null => {\n if (typeof value === \"string\") return value\n if (typeof value === \"number\") return Number.isFinite(value) ? String(value) : null\n if (typeof value === \"boolean\") return value ? \"true\" : \"false\"\n if (typeof value === \"bigint\") return String(value)\n if (value instanceof Date) return value.toISOString()\n return null\n }\n\n const buildQuery = (path: string, payload: Record<string, unknown>) => {\n const url = new URL(path, \"http://localhost\")\n\n const query: Record<string, string | string[]> = {}\n for (const [key, value] of url.searchParams) {\n mergeQueryValues(query, key, value)\n }\n\n for (const [key, rawValue] of Object.entries(payload)) {\n if (!key) continue\n\n if (Array.isArray(rawValue)) {\n for (const item of rawValue) {\n const converted = toQueryValue(item)\n if (converted !== null) mergeQueryValues(query, key, converted)\n }\n continue\n }\n\n const converted = toQueryValue(rawValue)\n if (converted !== null) mergeQueryValues(query, key, converted)\n }\n\n const searchParams = new URLSearchParams()\n for (const [key, rawValue] of Object.entries(query)) {\n if (Array.isArray(rawValue)) {\n for (const value of rawValue) {\n searchParams.append(key, value)\n }\n continue\n }\n\n searchParams.append(key, rawValue)\n }\n\n const matchPath = url.pathname\n const requestUrl = `${matchPath}${searchParams.toString() ? `?${searchParams.toString()}` : \"\"}`\n\n return { matchPath, requestUrl, query }\n }\n\n const createMethod = (method: string) => {\n return async <TResponse = Record<string, unknown>>(\n path: string,\n payload: Record<string, unknown>,\n ctxOrOptions?: Ctx | ApiClientRequestOptions,\n options?: ApiClientRequestOptions,\n ): Promise<TResponse> => {\n const ctx = isCtx(ctxOrOptions) ? ctxOrOptions : undefined\n const requestOptions = isCtx(ctxOrOptions) ? options : ctxOrOptions\n if (!ctx) {\n throw new Error(\"Context must be provided in SSR mode\")\n }\n if (requestOptions?.signal?.aborted) {\n throw createAbortError()\n }\n\n const normalizedMethod = method.toLowerCase()\n\n if (normalizedMethod === \"get\") {\n const { matchPath, requestUrl, query } = buildQuery(path, payload)\n return callRoute<TResponse>(app, method, matchPath, requestUrl, { ...ctx.req, body: {}, query }, ctx.res)\n }\n\n const { matchPath, requestUrl, query } = buildQuery(path, {})\n return callRoute<TResponse>(app, method, matchPath, requestUrl, { ...ctx.req, body: payload, query }, ctx.res)\n }\n }\n\n const apiClient = {\n get: createMethod(\"get\"),\n post: createMethod(\"post\"),\n put: createMethod(\"put\"),\n delete: createMethod(\"delete\")\n }\n\n return apiClient\n}\n\nexport default getServerApiClient\n"],"names":["getServerApiClient","app","isCtx","value","createAbortError","error","Error","name","callRoute","method","matchPath","requestUrl","req","res","Promise","resolve","reject","isEnded","timeoutId","resolveRequest","data","rejectRequest","mockReq","toUpperCase","url","mockRes","json","status","statusCode","console","log","routerStack","router","stack","firstApiMiddlewareIndex","findIndex","layer","apiStack","slice","processLayer","index","length","isNonMatchingLayer","match","runHandler","handler","resolveMiddleware","rejectMiddleware","err","route","methods","toLowerCase","path","handle","catch","setTimeout","mergeQueryValues","target","key","existing","Array","isArray","push","toQueryValue","Number","isFinite","String","Date","toISOString","buildQuery","payload","URL","query","searchParams","rawValue","Object","entries","item","converted","URLSearchParams","append","pathname","toString","createMethod","ctxOrOptions","options","ctx","undefined","requestOptions","signal","aborted","normalizedMethod","body","apiClient","get","post","put","delete"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","sources":["../../src/rts/useCountQuery.ts","../../src/rts/useRtsConnection.ts"],"sourcesContent":["import { useEffect, useMemo, useRef, useState } from \"react\"\n\nimport type { RtsModelName } from \"./modelTypes\"\nimport { computeRtsQueryKey, serializeRtsQueryValue } from \"./queryKey\"\nimport { consumeHydratedRtsCount, peekHydratedRtsCount, useRtsSsrRuntime } from \"./ssrHydration\"\nimport { registerCount, type RtsCountContext, type RtsCountQueryOptions } from \"./wsClient\"\n\n\ntype JsonObject = Record<string, unknown>\n\nconst normalizeCount = (value: unknown): number | undefined => {\n if (typeof value !== \"number\") return undefined\n if (!Number.isFinite(value) || value < 0) return undefined\n return Math.floor(value)\n}\n\nexport type UseRtsCountQueryOptions = {\n key?: string\n enabled?: boolean\n ssr?: \"auto\" | boolean\n refreshOnMount?: boolean\n}\n\nexport type UseRtsCountQueryResult = {\n count: number | undefined\n source: \"cache\" | RtsCountContext[\"source\"] | undefined\n error: unknown | undefined\n loading: boolean\n}\n\nexport const useCountQuery = (\n modelName: RtsModelName,\n query: JsonObject = {},\n options: UseRtsCountQueryOptions = {},\n): UseRtsCountQueryResult => {\n if (typeof modelName !== \"string\" || modelName.trim().length === 0) {\n throw new Error(\"useCountQuery: modelName must be a non-empty string\")\n }\n\n const enabled = options.enabled ?? true\n const ssrEnabled = options.ssr !== false\n const refreshOnMount = options.refreshOnMount === true\n const key = options.key\n const queryJson = serializeRtsQueryValue(query)\n const runtimeOptions = useMemo<RtsCountQueryOptions>(() => (key ? { key } : {}), [key])\n const queryKey = computeRtsQueryKey(query, runtimeOptions)\n\n const ssrRuntime = useRtsSsrRuntime()\n if (enabled && ssrEnabled && ssrRuntime) {\n ssrRuntime.registerCount({\n modelName,\n query,\n options: runtimeOptions,\n queryKey,\n })\n }\n\n const seedCountRaw = useMemo(\n () => (\n enabled && ssrEnabled\n ? ssrRuntime\n ? ssrRuntime.getCount(modelName, queryKey)\n : peekHydratedRtsCount(modelName, queryKey)\n : undefined\n ),\n [enabled, ssrEnabled, ssrRuntime, modelName, queryKey],\n )\n\n const seedCount = normalizeCount(seedCountRaw)\n const seedCountStr = seedCount !== undefined ? String(seedCount) : \"\"\n const hasSeedCount = seedCount !== undefined\n\n const [count, setCount] = useState<number | undefined>(() => seedCount)\n const [source, setSource] = useState<\"cache\" | RtsCountContext[\"source\"] | undefined>(() => (hasSeedCount ? \"cache\" : undefined))\n const [error, setError] = useState<unknown | undefined>(undefined)\n const [loading, setLoading] = useState<boolean>(enabled && !hasSeedCount)\n\n const lastCountRef = useRef<number | undefined>(seedCount)\n\n useEffect(() => {\n if (!ssrRuntime && enabled && ssrEnabled && hasSeedCount) {\n consumeHydratedRtsCount(modelName, queryKey)\n }\n\n lastCountRef.current = seedCount\n setError(undefined)\n\n if (!enabled) {\n setCount(undefined)\n setSource(undefined)\n setLoading(false)\n return\n }\n\n if (hasSeedCount) {\n setCount(seedCount)\n setSource(\"cache\")\n setLoading(false)\n return\n }\n\n setCount(undefined)\n setSource(undefined)\n setLoading(true)\n }, [enabled, ssrEnabled, ssrRuntime, modelName, queryKey, hasSeedCount, seedCount, seedCountStr])\n\n useEffect(() => {\n if (!enabled) return\n\n const unsubscribe = registerCount(\n modelName,\n query,\n runtimeOptions,\n (err, nextCount, context) => {\n if (context.source === \"cache\" && context.reset) {\n lastCountRef.current = undefined\n setCount(undefined)\n setSource(undefined)\n setError(undefined)\n setLoading(true)\n return\n }\n\n setLoading(false)\n\n if (err) {\n setError(err)\n return\n }\n\n if (nextCount === undefined) return\n setError(undefined)\n if (lastCountRef.current === nextCount) {\n setSource(context.source)\n return\n }\n\n lastCountRef.current = nextCount\n setCount(nextCount)\n setSource(context.source)\n },\n {\n runInitialNetworkQuery: refreshOnMount || !hasSeedCount,\n forceRefreshOnMount: refreshOnMount,\n ...(hasSeedCount\n ? {\n seedSnapshot: {\n error: null,\n count: seedCount,\n context: { source: \"cache\" },\n },\n }\n : {}),\n },\n )\n\n return () => {\n unsubscribe?.()\n }\n }, [\n enabled,\n modelName,\n queryJson,\n queryKey,\n runtimeOptions,\n hasSeedCount,\n refreshOnMount,\n ])\n\n return useMemo(\n () => ({\n count,\n source,\n error,\n loading,\n }),\n [count, error, loading, source],\n )\n}\n","import { useEffect, useRef } from \"react\"\n\nimport { serializeRtsQueryValue } from \"./queryKey\"\nimport { disconnect, reconnect, type RtsConnectOptions } from \"./wsClient\"\n\n\nlet activeConsumers = 0\nlet connectedKey: string | null = null\nlet pendingDisconnectTimer: ReturnType<typeof setTimeout> | null = null\n\nconst cancelPendingDisconnect = () => {\n if (pendingDisconnectTimer !== null) {\n clearTimeout(pendingDisconnectTimer)\n pendingDisconnectTimer = null\n }\n}\n\nexport const useRtsConnection = (\n tenantId: string | null | undefined,\n uid: string | null | undefined,\n options: RtsConnectOptions = {},\n): void => {\n const tenantIdValue = typeof tenantId === \"string\" ? tenantId.trim() : \"\"\n const uidValue = typeof uid === \"string\" ? uid.trim() : \"\"\n const optionsJson = serializeRtsQueryValue(options)\n\n const optionsRef = useRef(options)\n optionsRef.current = options\n\n useEffect(() => {\n if (typeof window === \"undefined\") return\n if (!tenantIdValue || !uidValue) return\n\n activeConsumers += 1\n cancelPendingDisconnect()\n\n const key = `${tenantIdValue}::${uidValue}::${optionsJson}`\n if (connectedKey !== key) {\n connectedKey = key\n void reconnect(tenantIdValue, uidValue, optionsRef.current).catch((error) => {\n connectedKey = null\n console.error(\"RTS connection failed\", error)\n })\n }\n\n return () => {\n activeConsumers -= 1\n if (activeConsumers > 0) return\n // Defer so a Strict Mode remount (or a credentials swap) can cancel the\n // teardown before it closes the connection shared by other consumers.\n pendingDisconnectTimer = setTimeout(() => {\n pendingDisconnectTimer = null\n if (activeConsumers > 0) return\n connectedKey = null\n disconnect()\n }, 0)\n }\n }, [tenantIdValue, uidValue, optionsJson])\n}\n"],"names":["normalizeCount","value","undefined","Number","isFinite","Math","floor","useCountQuery","modelName","t0","t1","$","_c","query","t2","options","trim","length","Error","enabled","ssrEnabled","ssr","refreshOnMount","key","queryJson","serializeRtsQueryValue","t3","runtimeOptions","queryKey","computeRtsQueryKey","ssrRuntime","useRtsSsrRuntime","registerCount","t4","getCount","peekHydratedRtsCount","seedCountRaw","t5","seedCount","seedCountStr","String","hasSeedCount","t6","count","setCount","useState","t7","source","setSource","error","setError","loading","setLoading","lastCountRef","useRef","t8","consumeHydratedRtsCount","current","t9","useEffect","t10","unsubscribe","err","nextCount","context","reset","runInitialNetworkQuery","forceRefreshOnMount","seedSnapshot","t11","t12","activeConsumers","connectedKey","pendingDisconnectTimer","cancelPendingDisconnect","clearTimeout","useRtsConnection","tenantId","uid","tenantIdValue","uidValue","optionsJson","optionsRef","window","reconnect","catch","console","setTimeout","disconnect"],"mappings":"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"}