@rpcbase/client 0.379.0 → 0.381.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.
@@ -1,5 +1,5 @@
1
1
  import { Application } from 'express';
2
- type Ctx = any;
2
+ import { Ctx } from '@rpcbase/api';
3
3
  export declare const getServerApiClient: (app: Application) => Promise<{
4
4
  get: <TResponse = Record<string, unknown>>(path: string, payload: Record<string, unknown>, ctx?: Ctx) => Promise<TResponse>;
5
5
  post: <TResponse = Record<string, unknown>>(path: string, payload: Record<string, unknown>, ctx?: Ctx) => Promise<TResponse>;
@@ -1 +1 @@
1
- {"version":3,"file":"getServerApiClient.d.ts","sourceRoot":"","sources":["../../src/apiClient/getServerApiClient.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAA8B,MAAM,SAAS,CAAA;AAGjE,KAAK,GAAG,GAAG,GAAG,CAAA;AAGd,eAAO,MAAM,kBAAkB,GAAS,KAAK,WAAW;UA+KtC,SAAS,kCACf,MAAM,WACH,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,QAC1B,GAAG,KACR,OAAO,CAAC,SAAS,CAAC;WAJP,SAAS,kCACf,MAAM,WACH,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,QAC1B,GAAG,KACR,OAAO,CAAC,SAAS,CAAC;UAJP,SAAS,kCACf,MAAM,WACH,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,QAC1B,GAAG,KACR,OAAO,CAAC,SAAS,CAAC;aAJP,SAAS,kCACf,MAAM,WACH,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,QAC1B,GAAG,KACR,OAAO,CAAC,SAAS,CAAC;EAyBxB,CAAA;AAED,eAAe,kBAAkB,CAAA"}
1
+ {"version":3,"file":"getServerApiClient.d.ts","sourceRoot":"","sources":["../../src/apiClient/getServerApiClient.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAA8B,MAAM,SAAS,CAAA;AACjE,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,cAAc,CAAA;AAkBvC,eAAO,MAAM,kBAAkB,GAAS,KAAK,WAAW;UA+KtC,SAAS,kCACf,MAAM,WACH,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,QAC1B,GAAG,KACR,OAAO,CAAC,SAAS,CAAC;WAJP,SAAS,kCACf,MAAM,WACH,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,QAC1B,GAAG,KACR,OAAO,CAAC,SAAS,CAAC;UAJP,SAAS,kCACf,MAAM,WACH,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,QAC1B,GAAG,KACR,OAAO,CAAC,SAAS,CAAC;aAJP,SAAS,kCACf,MAAM,WACH,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,QAC1B,GAAG,KACR,OAAO,CAAC,SAAS,CAAC;EAyBxB,CAAA;AAED,eAAe,kBAAkB,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"getServerApiClient-BYu8h5Zd.js","sources":["../src/apiClient/getServerApiClient.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-explicit-any */\nimport { Application, IRouter, Request, Response } from \"express\"\n\n// import { Ctx } from \"@rpcbase/api\"\ntype Ctx = any\n\n\nexport const getServerApiClient = async(app: Application) => {\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: any) => {\n resolveRequest(data)\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: any[] = (app.router as unknown as IRouter).stack\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: any) => new Promise<void>((resolveMiddleware, rejectMiddleware) => {\n handler(mockReq, mockRes, (err?: any) => {\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 ctx?: Ctx,\n ): Promise<TResponse> => {\n if (!ctx) {\n throw new Error(\"Context must be provided in SSR mode\")\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":["app","converted","matchPath","requestUrl","query"],"mappings":"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"}
1
+ {"version":3,"file":"getServerApiClient-BYu8h5Zd.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\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 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 ctx?: Ctx,\n ): Promise<TResponse> => {\n if (!ctx) {\n throw new Error(\"Context must be provided in SSR mode\")\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":["app","converted","matchPath","requestUrl","query"],"mappings":"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"}
package/dist/index.js CHANGED
@@ -5,8 +5,8 @@ import { getNavigationGuards, createRoutesFromElements, createBrowserRouter, Rou
5
5
  import { hydrateRoot } from "react-dom/client";
6
6
  import { r as reportClientException } from "./errorReporting-CVoUUKxW.js";
7
7
  import { s } from "./errorReporting-CVoUUKxW.js";
8
- import { m as hydrateRtsFromWindow, q as resolveRtsHydrationIdentityFromStaticRouterData, t as useQuery } from "./useQuery-Bz5cpWp4.js";
9
- import { R, S, n, p } from "./useQuery-Bz5cpWp4.js";
8
+ import { m as hydrateRtsFromWindow, q as resolveRtsHydrationIdentityFromStaticRouterData, t as useQuery } from "./useQuery-n0OatV-X.js";
9
+ import { R, S, n, p } from "./useQuery-n0OatV-X.js";
10
10
  const emptyUnsubscribe = () => {
11
11
  };
12
12
  const useMediaQuery = (query) => {
@@ -97,10 +97,11 @@ const startToaster = () => {
97
97
  const ensureReady = () => {
98
98
  if (typeof document === "undefined") startToaster();
99
99
  };
100
+ const buildToastData = (data, id) => data ? { ...data, id } : { id };
100
101
  const toastFn = ((message, data) => {
101
102
  ensureReady();
102
103
  const id = resolveId(data?.id) ?? createToastId();
103
- const nextData = data ? { ...data, id } : { id };
104
+ const nextData = buildToastData(data, id);
104
105
  enqueue((m) => {
105
106
  m.toast(message, nextData);
106
107
  });
@@ -109,7 +110,7 @@ const toastFn = ((message, data) => {
109
110
  const toastSuccess = (message, data) => {
110
111
  ensureReady();
111
112
  const id = resolveId(data?.id) ?? createToastId();
112
- const nextData = data ? { ...data, id } : { id };
113
+ const nextData = buildToastData(data, id);
113
114
  enqueue((m) => {
114
115
  m.toast.success(message, nextData);
115
116
  });
@@ -118,7 +119,7 @@ const toastSuccess = (message, data) => {
118
119
  const toastInfo = (message, data) => {
119
120
  ensureReady();
120
121
  const id = resolveId(data?.id) ?? createToastId();
121
- const nextData = data ? { ...data, id } : { id };
122
+ const nextData = buildToastData(data, id);
122
123
  enqueue((m) => {
123
124
  m.toast.info(message, nextData);
124
125
  });
@@ -127,7 +128,7 @@ const toastInfo = (message, data) => {
127
128
  const toastWarning = (message, data) => {
128
129
  ensureReady();
129
130
  const id = resolveId(data?.id) ?? createToastId();
130
- const nextData = data ? { ...data, id } : { id };
131
+ const nextData = buildToastData(data, id);
131
132
  enqueue((m) => {
132
133
  m.toast.warning(message, nextData);
133
134
  });
@@ -136,7 +137,7 @@ const toastWarning = (message, data) => {
136
137
  const toastError = (message, data) => {
137
138
  ensureReady();
138
139
  const id = resolveId(data?.id) ?? createToastId();
139
- const nextData = data ? { ...data, id } : { id };
140
+ const nextData = buildToastData(data, id);
140
141
  enqueue((m) => {
141
142
  m.toast.error(message, nextData);
142
143
  });
@@ -145,7 +146,7 @@ const toastError = (message, data) => {
145
146
  const toastMessage = (message, data) => {
146
147
  ensureReady();
147
148
  const id = resolveId(data?.id) ?? createToastId();
148
- const nextData = data ? { ...data, id } : { id };
149
+ const nextData = buildToastData(data, id);
149
150
  enqueue((m) => {
150
151
  m.toast.message(message, nextData);
151
152
  });
@@ -154,7 +155,7 @@ const toastMessage = (message, data) => {
154
155
  const toastLoading = (message, data) => {
155
156
  ensureReady();
156
157
  const id = resolveId(data?.id) ?? createToastId();
157
- const nextData = data ? { ...data, id } : { id };
158
+ const nextData = buildToastData(data, id);
158
159
  enqueue((m) => {
159
160
  m.toast.loading(message, nextData);
160
161
  });
@@ -163,7 +164,7 @@ const toastLoading = (message, data) => {
163
164
  const toastCustom = (jsx2, data) => {
164
165
  ensureReady();
165
166
  const id = resolveId(data?.id) ?? createToastId();
166
- const nextData = data ? { ...data, id } : { id };
167
+ const nextData = buildToastData(data, id);
167
168
  enqueue((m) => {
168
169
  m.toast.custom(jsx2, nextData);
169
170
  });
@@ -180,7 +181,7 @@ const toastPromise = (promise, data) => {
180
181
  });
181
182
  return { unwrap };
182
183
  }
183
- const id = resolveId(data?.id) ?? createToastId();
184
+ const id = resolveId(data.id) ?? createToastId();
184
185
  const nextData = { ...data, id };
185
186
  enqueue((m) => {
186
187
  m.toast.promise(startedPromise, nextData);
@@ -247,9 +248,9 @@ const ActiveToaster = () => {
247
248
  swipeDirections: isCoarsePointer ? void 0 : [],
248
249
  style: {
249
250
  pointerEvents: "auto",
250
- ["--toast-close-button-start"]: "unset",
251
- ["--toast-close-button-end"]: "0",
252
- ["--toast-close-button-transform"]: "translate(35%, -35%)"
251
+ "--toast-close-button-start": "unset",
252
+ "--toast-close-button-end": "0",
253
+ "--toast-close-button-transform": "translate(35%, -35%)"
253
254
  },
254
255
  toastOptions: {
255
256
  style: {
@@ -387,12 +388,14 @@ const pickNavigationGuard = (args) => {
387
388
  };
388
389
  const getLocationDedupKey = (location) => location.key ?? `${location.pathname}${location.search}`;
389
390
  const hasUnloadBlockers = () => getNavigationGuards().some((guard) => guard.enabled && guard.shouldBlockUnload);
391
+ const WINDOW_STATE_KEY = "__rpcbaseNavigationGuardWindowState";
392
+ const INSTALLED_ROUTERS_KEY = "__rpcbaseNavigationGuardInstalledRouters";
393
+ const BEFORE_UNLOAD_INSTALLED_KEY = "__rpcbaseBeforeUnloadNavigationGuardInstalled";
390
394
  const getWindowState = () => {
391
395
  if (typeof window === "undefined") return null;
392
- const key = "__rpcbaseNavigationGuardWindowState";
393
- const globalAny = window;
394
- if (globalAny[key]) {
395
- const existing = globalAny[key];
396
+ const globalWindow = window;
397
+ const existing = globalWindow[WINDOW_STATE_KEY];
398
+ if (existing) {
396
399
  if (typeof existing.suppressBeforeUnloadFromKey === "undefined") {
397
400
  existing.suppressBeforeUnloadFromKey = null;
398
401
  }
@@ -402,18 +405,17 @@ const getWindowState = () => {
402
405
  suppressBeforeUnloadFromKey: null,
403
406
  nativePromptActive: false
404
407
  };
405
- globalAny[key] = created;
408
+ globalWindow[WINDOW_STATE_KEY] = created;
406
409
  return created;
407
410
  };
408
411
  const getGlobalGuardWeakSet = () => {
409
- const key = "__rpcbaseNavigationGuardInstalledRouters";
410
- const globalAny = globalThis;
411
- const existing = globalAny[key];
412
+ const globalScope = globalThis;
413
+ const existing = globalScope[INSTALLED_ROUTERS_KEY];
412
414
  if (existing && existing instanceof WeakSet) {
413
415
  return existing;
414
416
  }
415
417
  const created = /* @__PURE__ */ new WeakSet();
416
- globalAny[key] = created;
418
+ globalScope[INSTALLED_ROUTERS_KEY] = created;
417
419
  return created;
418
420
  };
419
421
  const installGlobalNavigationGuard = (router) => {
@@ -434,7 +436,7 @@ const installGlobalNavigationGuard = (router) => {
434
436
  return pickNavigationGuard(args) !== null;
435
437
  });
436
438
  router.subscribe((state) => {
437
- if (windowState?.suppressBeforeUnloadFromKey && state?.location) {
439
+ if (windowState?.suppressBeforeUnloadFromKey) {
438
440
  const currentKey = getLocationDedupKey(state.location);
439
441
  if (currentKey !== windowState.suppressBeforeUnloadFromKey) {
440
442
  windowState.suppressBeforeUnloadFromKey = null;
@@ -477,10 +479,9 @@ const installGlobalNavigationGuard = (router) => {
477
479
  }
478
480
  });
479
481
  if (typeof window !== "undefined") {
480
- const key = "__rpcbaseBeforeUnloadNavigationGuardInstalled";
481
- const globalAny = window;
482
- if (!globalAny[key]) {
483
- globalAny[key] = true;
482
+ const globalWindow = window;
483
+ if (!globalWindow[BEFORE_UNLOAD_INSTALLED_KEY]) {
484
+ globalWindow[BEFORE_UNLOAD_INSTALLED_KEY] = true;
484
485
  window.addEventListener("beforeunload", (event) => {
485
486
  const state = getWindowState();
486
487
  if (state && state.suppressBeforeUnloadFromKey) {
@@ -558,8 +559,9 @@ const showErrorOverlay = (err) => {
558
559
  document.body.appendChild(overlay);
559
560
  };
560
561
  const handleServerErrors = () => {
561
- if (window.__staticRouterHydrationData?.errors) {
562
- const { errors } = window.__staticRouterHydrationData;
562
+ const hydrationData = window.__staticRouterHydrationData;
563
+ if (hydrationData?.errors) {
564
+ const { errors } = hydrationData;
563
565
  Object.values(errors).forEach((error) => {
564
566
  showErrorOverlay({
565
567
  plugin: "ssr-router",
@@ -583,14 +585,14 @@ const wrapLoaderWithTimeout = (loader, routeId) => async (...args) => new Promis
583
585
  });
584
586
  const applyLoaderTimeouts = (routes) => {
585
587
  routes.forEach((route) => {
586
- if (route.loader) {
588
+ if (typeof route.loader === "function") {
587
589
  route.loader = wrapLoaderWithTimeout(route.loader, route.id);
588
590
  }
589
- if (route.lazy) {
591
+ if (typeof route.lazy === "function") {
590
592
  const origLazy = route.lazy;
591
593
  route.lazy = async (...lazyArgs) => {
592
594
  const mod = await origLazy(...lazyArgs);
593
- if (mod?.loader) {
595
+ if (typeof mod.loader === "function") {
594
596
  const origLoader = mod.loader;
595
597
  mod.loader = (...loaderArgs) => wrapLoaderWithTimeout(origLoader, route.id)(...loaderArgs);
596
598
  }