@ovineko/spa-guard 0.0.1-alpha-1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. package/README.md +695 -0
  2. package/dist/chunk-BL4EG6R7.js +14 -0
  3. package/dist/chunk-MLKGABMK.js +9 -0
  4. package/dist/chunk-VWV6L4Q2.js +51 -0
  5. package/dist/chunk-W65YKSMF.js +6 -0
  6. package/dist/chunk-XV2YCVOR.js +12 -0
  7. package/dist/common/constants.d.ts +5 -0
  8. package/dist/common/events/index.d.ts +2 -0
  9. package/dist/common/events/internal.d.ts +4 -0
  10. package/dist/common/events/types.d.ts +8 -0
  11. package/dist/common/fallbackHtml.generated.d.ts +1 -0
  12. package/dist/common/index.d.ts +3 -0
  13. package/dist/common/index.js +358 -0
  14. package/dist/common/isChunkError.d.ts +1 -0
  15. package/dist/common/listen/index.d.ts +1 -0
  16. package/dist/common/listen/internal.d.ts +1 -0
  17. package/dist/common/log.d.ts +1 -0
  18. package/dist/common/options.d.ts +12 -0
  19. package/dist/common/reload.d.ts +1 -0
  20. package/dist/common/sendBeacon.d.ts +2 -0
  21. package/dist/common/serializeError.d.ts +1 -0
  22. package/dist/fastify/index.d.ts +45 -0
  23. package/dist/fastify/index.js +66 -0
  24. package/dist/inline/index.d.ts +1 -0
  25. package/dist/react/index.d.ts +1 -0
  26. package/dist/react/index.js +0 -0
  27. package/dist/react-error-boundary/index.d.ts +1 -0
  28. package/dist/react-error-boundary/index.js +7 -0
  29. package/dist/react-router/index.d.ts +1 -0
  30. package/dist/react-router/index.js +12 -0
  31. package/dist/schema/index.d.ts +8 -0
  32. package/dist/schema/index.js +7 -0
  33. package/dist/schema/parse.d.ts +6 -0
  34. package/dist/schema/parse.js +8 -0
  35. package/dist/vite-plugin/index.d.ts +6 -0
  36. package/dist/vite-plugin/index.js +38 -0
  37. package/dist-inline/index.js +1 -0
  38. package/dist-inline-trace/index.js +360 -0
  39. package/package.json +86 -0
@@ -0,0 +1,9 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __export = (target, all) => {
3
+ for (var name in all)
4
+ __defProp(target, name, { get: all[name], enumerable: true });
5
+ };
6
+
7
+ export {
8
+ __export
9
+ };
@@ -0,0 +1,51 @@
1
+ import {
2
+ __export
3
+ } from "./chunk-MLKGABMK.js";
4
+
5
+ // package.json
6
+ var name = "@ovineko/spa-guard";
7
+
8
+ // src/common/constants.ts
9
+ var optionsWindowKey = "__SPA_GUARD_OPTIONS__";
10
+ var eventSubscribersWindowKey = /* @__PURE__ */ Symbol.for(`${name}:event-subscribers`);
11
+ var internalConfigWindowKey = /* @__PURE__ */ Symbol.for(`${name}:internal-config`);
12
+ var RETRY_ID_PARAM = "spaGuardRetryId";
13
+ var RETRY_ATTEMPT_PARAM = "spaGuardRetryAttempt";
14
+
15
+ // src/common/options.ts
16
+ var options_exports = {};
17
+ __export(options_exports, {
18
+ getOptions: () => getOptions,
19
+ optionsWindowKey: () => optionsWindowKey
20
+ });
21
+
22
+ // src/common/fallbackHtml.generated.ts
23
+ var defaultFallbackHtml = `<div style="display:flex;align-items:center;justify-content:center;height:100vh;font-family:sans-serif"><div style="text-align:center"><h1>Something went wrong</h1><p>Please refresh the page to continue.</p><button onclick="location.reload()">Refresh Page</button></div></div>`;
24
+
25
+ // src/common/options.ts
26
+ var defaultOptions = {
27
+ fallbackHtml: defaultFallbackHtml,
28
+ reloadDelays: [1e3, 2e3, 5e3],
29
+ useRetryId: true
30
+ };
31
+ var getOptions = () => {
32
+ const windowOptions = globalThis.window?.[optionsWindowKey];
33
+ return {
34
+ ...defaultOptions,
35
+ ...windowOptions,
36
+ reportBeacon: {
37
+ ...defaultOptions.reportBeacon,
38
+ ...windowOptions?.reportBeacon
39
+ }
40
+ };
41
+ };
42
+
43
+ export {
44
+ name,
45
+ optionsWindowKey,
46
+ eventSubscribersWindowKey,
47
+ RETRY_ID_PARAM,
48
+ RETRY_ATTEMPT_PARAM,
49
+ getOptions,
50
+ options_exports
51
+ };
@@ -0,0 +1,6 @@
1
+ // src/common/log.ts
2
+ var logMessage = (msg) => `[spa-guard] ${msg}`;
3
+
4
+ export {
5
+ logMessage
6
+ };
@@ -0,0 +1,12 @@
1
+ // src/schema/index.ts
2
+ import Type from "typebox";
3
+ var beaconSchema = Type.Object({
4
+ errorMessage: Type.Optional(Type.String()),
5
+ eventMessage: Type.Optional(Type.String()),
6
+ eventName: Type.Optional(Type.String()),
7
+ serialized: Type.Optional(Type.String())
8
+ });
9
+
10
+ export {
11
+ beaconSchema
12
+ };
@@ -0,0 +1,5 @@
1
+ export declare const optionsWindowKey = "__SPA_GUARD_OPTIONS__";
2
+ export declare const eventSubscribersWindowKey: unique symbol;
3
+ export declare const internalConfigWindowKey: unique symbol;
4
+ export declare const RETRY_ID_PARAM = "spaGuardRetryId";
5
+ export declare const RETRY_ATTEMPT_PARAM = "spaGuardRetryAttempt";
@@ -0,0 +1,2 @@
1
+ export { subscribe } from "./internal";
2
+ export * from "./types";
@@ -0,0 +1,4 @@
1
+ import type { SPAGuardEvent, SubscribeFn, UnsubscribeFn } from "./types";
2
+ export declare const subscribers: Set<SubscribeFn>;
3
+ export declare const emitEvent: (event: SPAGuardEvent) => void;
4
+ export declare const subscribe: (cb: SubscribeFn) => UnsubscribeFn;
@@ -0,0 +1,8 @@
1
+ export type SPAGuardEvent = SPAGuardEventTest & {
2
+ name: "test";
3
+ };
4
+ export interface SPAGuardEventTest {
5
+ name: "test";
6
+ }
7
+ export type SubscribeFn = (event: SPAGuardEvent) => void;
8
+ export type UnsubscribeFn = () => void;
@@ -0,0 +1 @@
1
+ export declare const defaultFallbackHtml = "<div style=\"display:flex;align-items:center;justify-content:center;height:100vh;font-family:sans-serif\"><div style=\"text-align:center\"><h1>Something went wrong</h1><p>Please refresh the page to continue.</p><button onclick=\"location.reload()\">Refresh Page</button></div></div>";
@@ -0,0 +1,3 @@
1
+ export * as events from "./events";
2
+ export { listen } from "./listen";
3
+ export * as options from "./options";
@@ -0,0 +1,358 @@
1
+ import {
2
+ logMessage
3
+ } from "../chunk-W65YKSMF.js";
4
+ import {
5
+ RETRY_ATTEMPT_PARAM,
6
+ RETRY_ID_PARAM,
7
+ eventSubscribersWindowKey,
8
+ getOptions,
9
+ options_exports
10
+ } from "../chunk-VWV6L4Q2.js";
11
+ import {
12
+ __export
13
+ } from "../chunk-MLKGABMK.js";
14
+
15
+ // src/common/events/index.ts
16
+ var events_exports = {};
17
+ __export(events_exports, {
18
+ subscribe: () => subscribe
19
+ });
20
+
21
+ // src/common/events/internal.ts
22
+ if (globalThis.window && !globalThis.window[eventSubscribersWindowKey]) {
23
+ globalThis.window[eventSubscribersWindowKey] = /* @__PURE__ */ new Set();
24
+ }
25
+ var subscribers = globalThis.window?.[eventSubscribersWindowKey] ?? /* @__PURE__ */ new Set();
26
+ var emitEvent = (event) => {
27
+ subscribers.forEach((cb) => cb(event));
28
+ };
29
+ var subscribe = (cb) => {
30
+ subscribers.add(cb);
31
+ return () => subscribers.delete(cb);
32
+ };
33
+
34
+ // src/common/isChunkError.ts
35
+ var isChunkError = (error) => {
36
+ const message = getErrorMessage(error);
37
+ if (!message) {
38
+ return false;
39
+ }
40
+ const patterns = [
41
+ /Failed to fetch dynamically imported module/i,
42
+ /Importing a module script failed/i,
43
+ /error loading dynamically imported module/i,
44
+ /Unable to preload CSS/i,
45
+ /Loading chunk \d+ failed/i,
46
+ /Loading CSS chunk \d+ failed/i,
47
+ /ChunkLoadError/i,
48
+ /Failed to fetch/i,
49
+ /NaN/i
50
+ ];
51
+ return patterns.some((pattern) => pattern.test(message));
52
+ };
53
+ var getErrorMessage = (error) => {
54
+ if (error instanceof Error) {
55
+ return error.message;
56
+ }
57
+ if (typeof error === "string") {
58
+ return error;
59
+ }
60
+ if (error && typeof error === "object" && "message" in error) {
61
+ return String(error.message);
62
+ }
63
+ if (error && typeof error === "object" && "reason" in error) {
64
+ return getErrorMessage(error.reason);
65
+ }
66
+ return null;
67
+ };
68
+
69
+ // src/common/sendBeacon.ts
70
+ var sendBeacon = (beacon) => {
71
+ const options = getOptions();
72
+ if (!options.reportBeacon?.endpoint) {
73
+ console.warn(logMessage("Report endpoint is not configured"));
74
+ return;
75
+ }
76
+ const body = JSON.stringify(beacon);
77
+ const isSendBeaconAvailable = typeof globalThis.window?.navigator.sendBeacon === "function";
78
+ const isSentBeacon = isSendBeaconAvailable && navigator.sendBeacon(options.reportBeacon.endpoint, body);
79
+ if (!isSentBeacon) {
80
+ fetch(options.reportBeacon.endpoint, { body, keepalive: true, method: "POST" }).catch(
81
+ (error) => {
82
+ console.error(logMessage("Failed to send beacon:"), error);
83
+ }
84
+ );
85
+ }
86
+ };
87
+
88
+ // src/common/reload.ts
89
+ var getRetryStateFromUrl = () => {
90
+ try {
91
+ const params = new URLSearchParams(window.location.search);
92
+ const retryId = params.get(RETRY_ID_PARAM);
93
+ const retryAttempt = params.get(RETRY_ATTEMPT_PARAM);
94
+ if (retryId && retryAttempt) {
95
+ return {
96
+ retryAttempt: parseInt(retryAttempt, 10),
97
+ retryId
98
+ };
99
+ }
100
+ return null;
101
+ } catch {
102
+ return null;
103
+ }
104
+ };
105
+ var generateRetryId = () => {
106
+ if (typeof crypto !== "undefined" && crypto.randomUUID) {
107
+ return crypto.randomUUID();
108
+ }
109
+ if (typeof crypto !== "undefined" && crypto.getRandomValues) {
110
+ const array = new Uint32Array(2);
111
+ crypto.getRandomValues(array);
112
+ return `${Date.now()}-${array[0].toString(36)}${array[1].toString(36)}`;
113
+ }
114
+ return `${Date.now()}-${Math.random().toString(36).slice(2, 15)}`;
115
+ };
116
+ var buildReloadUrl = (retryId, retryAttempt) => {
117
+ const url = new URL(window.location.href);
118
+ url.searchParams.set(RETRY_ID_PARAM, retryId);
119
+ url.searchParams.set(RETRY_ATTEMPT_PARAM, String(retryAttempt));
120
+ return url.toString();
121
+ };
122
+ var attemptReload = (error) => {
123
+ const options = getOptions();
124
+ const reloadDelays = options.reloadDelays ?? [1e3, 2e3, 5e3];
125
+ const useRetryId = options.useRetryId ?? true;
126
+ const retryState = useRetryId ? getRetryStateFromUrl() : null;
127
+ const currentAttempt = retryState ? retryState.retryAttempt : 0;
128
+ if (currentAttempt >= reloadDelays.length) {
129
+ console.error(logMessage("All reload attempts exhausted"), error);
130
+ sendBeacon({
131
+ errorMessage: "Exceeded maximum reload attempts",
132
+ eventName: "chunk_error_max_reloads",
133
+ serialized: JSON.stringify({
134
+ error: String(error),
135
+ retryAttempt: currentAttempt,
136
+ retryId: retryState?.retryId
137
+ })
138
+ });
139
+ showFallbackUI();
140
+ return;
141
+ }
142
+ const nextAttempt = currentAttempt + 1;
143
+ const retryId = retryState?.retryId ?? generateRetryId();
144
+ const delay = reloadDelays[currentAttempt];
145
+ console.warn(
146
+ logMessage(
147
+ `Reload attempt ${nextAttempt}/${reloadDelays.length} in ${delay}ms (retryId: ${retryId})`
148
+ ),
149
+ error
150
+ );
151
+ setTimeout(() => {
152
+ if (useRetryId) {
153
+ const reloadUrl = buildReloadUrl(retryId, nextAttempt);
154
+ window.location.href = reloadUrl;
155
+ } else {
156
+ window.location.reload();
157
+ }
158
+ }, delay);
159
+ };
160
+ var showFallbackUI = () => {
161
+ const options = getOptions();
162
+ const fallbackHtml = options.fallbackHtml;
163
+ if (!fallbackHtml) {
164
+ console.error(logMessage("No fallback UI configured"));
165
+ return;
166
+ }
167
+ try {
168
+ document.body.innerHTML = fallbackHtml;
169
+ } catch (error) {
170
+ console.error(logMessage("Failed to inject fallback UI"), error);
171
+ }
172
+ };
173
+
174
+ // src/common/serializeError.ts
175
+ var serializeError = (error) => {
176
+ try {
177
+ const serialized = serializeErrorInternal(error);
178
+ return JSON.stringify(serialized, null, 2);
179
+ } catch {
180
+ return JSON.stringify({
181
+ error: "Failed to serialize error",
182
+ fallback: String(error)
183
+ });
184
+ }
185
+ };
186
+ var serializeErrorInternal = (error) => {
187
+ if (error === null || error === void 0) {
188
+ return { type: "null", value: error };
189
+ }
190
+ if (typeof error !== "object") {
191
+ return { type: typeof error, value: error };
192
+ }
193
+ if (error instanceof Error) {
194
+ return {
195
+ message: error.message,
196
+ name: error.name,
197
+ stack: error.stack,
198
+ type: "Error",
199
+ ...extractErrorProperties(error)
200
+ };
201
+ }
202
+ if ("reason" in error && "promise" in error) {
203
+ return {
204
+ reason: serializeErrorInternal(error.reason),
205
+ type: "PromiseRejectionEvent"
206
+ };
207
+ }
208
+ if ("error" in error && "message" in error && "filename" in error) {
209
+ return {
210
+ colno: error.colno,
211
+ error: serializeErrorInternal(error.error),
212
+ filename: error.filename,
213
+ lineno: error.lineno,
214
+ message: error.message,
215
+ type: "ErrorEvent"
216
+ };
217
+ }
218
+ if ("violatedDirective" in error && "blockedURI" in error) {
219
+ const evt = error;
220
+ return {
221
+ blockedURI: evt.blockedURI,
222
+ columnNumber: evt.columnNumber,
223
+ effectiveDirective: evt.effectiveDirective,
224
+ lineNumber: evt.lineNumber,
225
+ originalPolicy: evt.originalPolicy,
226
+ sourceFile: evt.sourceFile,
227
+ type: "SecurityPolicyViolationEvent",
228
+ violatedDirective: evt.violatedDirective
229
+ };
230
+ }
231
+ if ("type" in error && "target" in error) {
232
+ const evt = error;
233
+ return {
234
+ eventType: evt.type,
235
+ target: extractEventTarget(evt.target),
236
+ timeStamp: evt.timeStamp,
237
+ type: "Event"
238
+ };
239
+ }
240
+ return {
241
+ type: "object",
242
+ value: extractOwnProperties(error)
243
+ };
244
+ };
245
+ var extractErrorProperties = (error) => {
246
+ const props = {};
247
+ for (const key of Object.getOwnPropertyNames(error)) {
248
+ if (!["message", "name", "stack"].includes(key)) {
249
+ try {
250
+ props[key] = error[key];
251
+ } catch {
252
+ }
253
+ }
254
+ }
255
+ return props;
256
+ };
257
+ var extractEventTarget = (target) => {
258
+ if (!target) {
259
+ return null;
260
+ }
261
+ if (target instanceof HTMLElement) {
262
+ return {
263
+ className: target.className,
264
+ href: target.href,
265
+ id: target.id,
266
+ src: target.src,
267
+ tagName: target.tagName
268
+ };
269
+ }
270
+ return { type: String(target) };
271
+ };
272
+ var extractOwnProperties = (obj) => {
273
+ const props = {};
274
+ for (const key of Object.keys(obj)) {
275
+ try {
276
+ const value = obj[key];
277
+ props[key] = typeof value === "object" ? String(value) : value;
278
+ } catch {
279
+ }
280
+ }
281
+ return props;
282
+ };
283
+
284
+ // src/common/listen/internal.ts
285
+ var listenInternal = () => {
286
+ emitEvent({ name: "test" });
287
+ const wa = window.addEventListener;
288
+ wa(
289
+ "error",
290
+ (event) => {
291
+ console.error(logMessage("error:capture:"), event);
292
+ if (isChunkError(event)) {
293
+ event.preventDefault();
294
+ attemptReload(event);
295
+ return;
296
+ }
297
+ const serialized = serializeError(event);
298
+ sendBeacon({
299
+ errorMessage: event.message,
300
+ eventName: "error",
301
+ serialized
302
+ });
303
+ },
304
+ true
305
+ );
306
+ wa("error", (event) => {
307
+ console.error(logMessage("error:"), event);
308
+ });
309
+ wa("unhandledrejection", (event) => {
310
+ console.error(logMessage("unhandledrejection:"), event);
311
+ if (isChunkError(event.reason)) {
312
+ event.preventDefault();
313
+ attemptReload(event.reason);
314
+ return;
315
+ }
316
+ const serialized = serializeError(event);
317
+ sendBeacon({
318
+ errorMessage: String(event.reason),
319
+ eventName: "unhandledrejection",
320
+ serialized
321
+ });
322
+ });
323
+ wa("uncaughtException", (event) => {
324
+ console.error(logMessage("uncaughtException:"), event);
325
+ const serialized = serializeError(event);
326
+ sendBeacon({
327
+ eventName: "uncaughtException",
328
+ serialized
329
+ });
330
+ });
331
+ wa("securitypolicyviolation", (event) => {
332
+ console.error(logMessage("CSP violation:"), event.blockedURI, event.violatedDirective);
333
+ const serialized = serializeError(event);
334
+ sendBeacon({
335
+ eventMessage: `${event.violatedDirective}: ${event.blockedURI}`,
336
+ eventName: "securitypolicyviolation",
337
+ serialized
338
+ });
339
+ });
340
+ wa("vite:preloadError", (event) => {
341
+ console.error(logMessage("vite:preloadError:"), event);
342
+ event.preventDefault();
343
+ attemptReload(event);
344
+ });
345
+ };
346
+
347
+ // src/common/listen/index.ts
348
+ var listen = () => {
349
+ if (!globalThis.window) {
350
+ return;
351
+ }
352
+ listenInternal();
353
+ };
354
+ export {
355
+ events_exports as events,
356
+ listen,
357
+ options_exports as options
358
+ };
@@ -0,0 +1 @@
1
+ export declare const isChunkError: (error: unknown) => boolean;
@@ -0,0 +1 @@
1
+ export declare const listen: () => void;
@@ -0,0 +1 @@
1
+ export declare const listenInternal: () => void;
@@ -0,0 +1 @@
1
+ export declare const logMessage: (msg: string) => string;
@@ -0,0 +1,12 @@
1
+ export { optionsWindowKey } from "./constants";
2
+ export interface Options {
3
+ fallbackHtml?: string;
4
+ /** @default [1000, 2000, 5000] */
5
+ reloadDelays?: number[];
6
+ reportBeacon?: {
7
+ endpoint?: string;
8
+ };
9
+ /** @default true */
10
+ useRetryId?: boolean;
11
+ }
12
+ export declare const getOptions: () => Options;
@@ -0,0 +1 @@
1
+ export declare const attemptReload: (error: unknown) => void;
@@ -0,0 +1,2 @@
1
+ import type { BeaconSchema } from "../schema";
2
+ export declare const sendBeacon: (beacon: BeaconSchema) => void;
@@ -0,0 +1 @@
1
+ export declare const serializeError: (error: unknown) => string;
@@ -0,0 +1,45 @@
1
+ import type { BeaconSchema } from "../schema";
2
+ export interface FastifySPAGuardOptions {
3
+ /**
4
+ * Custom handler for beacon data
5
+ * @param beacon - Parsed beacon data
6
+ * @param request - Fastify request object
7
+ */
8
+ onBeacon?: (beacon: BeaconSchema, request: any) => Promise<void> | void;
9
+ /**
10
+ * Custom handler for invalid/unknown beacon data
11
+ * @param body - Raw body data
12
+ * @param request - Fastify request object
13
+ */
14
+ onUnknownBeacon?: (body: unknown, request: any) => Promise<void> | void;
15
+ /**
16
+ * The route path for the beacon endpoint
17
+ * @example "/api/beacon"
18
+ */
19
+ path: string;
20
+ }
21
+ /**
22
+ * SPA Guard plugin for Fastify
23
+ * Registers a POST endpoint to receive beacon data from the client
24
+ *
25
+ * @example
26
+ * ```ts
27
+ * import { fastifySPAGuard } from '@ovineko/spa-guard/fastify';
28
+ *
29
+ * app.register(fastifySPAGuard, {
30
+ * path: '/api/beacon',
31
+ * onBeacon: async (beacon, request) => {
32
+ * // Handle beacon data (e.g., log to Sentry)
33
+ * const error = new Error(beacon.errorMessage || 'Unknown error');
34
+ * Sentry.captureException(error, {
35
+ * extra: {
36
+ * eventName: beacon.eventName,
37
+ * eventMessage: beacon.eventMessage,
38
+ * serialized: beacon.serialized,
39
+ * },
40
+ * });
41
+ * },
42
+ * });
43
+ * ```
44
+ */
45
+ export declare const fastifySPAGuard: (fastify: any, options: FastifySPAGuardOptions) => Promise<void>;
@@ -0,0 +1,66 @@
1
+ import {
2
+ logMessage
3
+ } from "../chunk-W65YKSMF.js";
4
+ import {
5
+ parseBeacon
6
+ } from "../chunk-BL4EG6R7.js";
7
+ import "../chunk-XV2YCVOR.js";
8
+ import "../chunk-MLKGABMK.js";
9
+
10
+ // src/fastify/index.ts
11
+ var parseStringBody = (body) => {
12
+ try {
13
+ return JSON.parse(body);
14
+ } catch {
15
+ return body;
16
+ }
17
+ };
18
+ var handleBeaconRequest = async (body, request, options) => {
19
+ try {
20
+ const beacon = parseBeacon(body);
21
+ if (options.onBeacon) {
22
+ await options.onBeacon(beacon, request);
23
+ } else {
24
+ request.log.info(
25
+ {
26
+ errorMessage: beacon.errorMessage,
27
+ eventMessage: beacon.eventMessage,
28
+ eventName: beacon.eventName,
29
+ serialized: beacon.serialized
30
+ },
31
+ logMessage("Beacon received")
32
+ );
33
+ }
34
+ } catch {
35
+ if (options.onUnknownBeacon) {
36
+ await options.onUnknownBeacon(body, request);
37
+ } else {
38
+ request.log.warn({ body }, logMessage("Unknown beacon format"));
39
+ }
40
+ }
41
+ };
42
+ var fastifySPAGuard = async (fastify, options) => {
43
+ const { onBeacon, onUnknownBeacon, path } = options;
44
+ fastify.post(
45
+ path,
46
+ {
47
+ schema: {
48
+ body: {
49
+ content: {
50
+ "text/plain": {
51
+ schema: { type: "string" }
52
+ }
53
+ }
54
+ }
55
+ }
56
+ },
57
+ async (request, reply) => {
58
+ const body = parseStringBody(request.body);
59
+ await handleBeaconRequest(body, request, { onBeacon, onUnknownBeacon });
60
+ return reply.status(200).send({ success: true });
61
+ }
62
+ );
63
+ };
64
+ export {
65
+ fastifySPAGuard
66
+ };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
File without changes
@@ -0,0 +1 @@
1
+ export { ErrorBoundary } from "react-error-boundary";
@@ -0,0 +1,7 @@
1
+ import "../chunk-MLKGABMK.js";
2
+
3
+ // src/react-error-boundary/index.tsx
4
+ import { ErrorBoundary } from "react-error-boundary";
5
+ export {
6
+ ErrorBoundary
7
+ };
@@ -0,0 +1 @@
1
+ export declare const ErrorBoundaryReactRouter: () => import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,12 @@
1
+ import "../chunk-MLKGABMK.js";
2
+
3
+ // src/react-router/index.tsx
4
+ import { useRouteError } from "react-router";
5
+ import { jsx } from "react/jsx-runtime";
6
+ var ErrorBoundaryReactRouter = () => {
7
+ const error = useRouteError();
8
+ return /* @__PURE__ */ jsx("div", { children: JSON.stringify(error) });
9
+ };
10
+ export {
11
+ ErrorBoundaryReactRouter
12
+ };
@@ -0,0 +1,8 @@
1
+ import Type from "typebox";
2
+ export declare const beaconSchema: Type.TObject<{
3
+ errorMessage: Type.TOptional<Type.TString>;
4
+ eventMessage: Type.TOptional<Type.TString>;
5
+ eventName: Type.TOptional<Type.TString>;
6
+ serialized: Type.TOptional<Type.TString>;
7
+ }>;
8
+ export type BeaconSchema = Type.Static<typeof beaconSchema>;
@@ -0,0 +1,7 @@
1
+ import {
2
+ beaconSchema
3
+ } from "../chunk-XV2YCVOR.js";
4
+ import "../chunk-MLKGABMK.js";
5
+ export {
6
+ beaconSchema
7
+ };