@ovineko/spa-guard 0.0.1-alpha-17 → 0.0.1-alpha-19
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/dist/_internal.d.ts +19 -0
- package/dist/_internal.js +162 -0
- package/dist/{chunk-6C6OARM7.js → chunk-3ISQYZVD.js} +19 -1
- package/dist/chunk-4FKSMB5F.js +695 -0
- package/dist/chunk-74K44EMP.js +50 -0
- package/dist/{chunk-KUC22DET.js → chunk-DOTM7FSY.js} +65 -8
- package/dist/{chunk-MCR7F3CG.js → chunk-SZS6GOPK.js} +1 -1
- package/dist/{chunk-MDTTXXMB.js → chunk-YSKH5K6P.js} +27 -19
- package/dist/common/handleErrorWithSpaGuard.d.ts +6 -1
- package/dist/common/html.generated.d.ts +1 -1
- package/dist/common/i18n.d.ts +8 -0
- package/dist/common/index.js +41 -271
- package/dist/common/retryImport.d.ts +1 -1
- package/dist/i18n/index.js +345 -4
- package/dist/runtime/debug/index.js +11 -43
- package/dist/runtime/index.d.ts +1 -0
- package/dist/runtime/index.js +221 -13
- package/dist/schema/parse.js +32 -3
- package/package.json +20 -83
- package/README.md +0 -2194
- package/dist/chunk-3SCN2UE4.js +0 -38
- package/dist/chunk-66KR5VAA.js +0 -228
- package/dist/chunk-AQ5RZR63.js +0 -182
- package/dist/chunk-EDRTFPCN.js +0 -24
- package/dist/chunk-HLRUA3T2.js +0 -349
- package/dist/chunk-HUAI4DRW.js +0 -113
- package/dist/chunk-Q267YLSE.js +0 -20
- package/dist/chunk-R2J3MNUG.js +0 -379
- package/dist/chunk-RP52SPBK.js +0 -6
- package/dist/chunk-RR4LFTYF.js +0 -156
- package/dist/chunk-SNM6AOFL.js +0 -16
- package/dist/common/DefaultErrorFallback.d.ts +0 -17
- package/dist/eslint/index.d.ts +0 -19
- package/dist/eslint/index.js +0 -152
- package/dist/eslint/rules/no-direct-error-boundary.d.ts +0 -3
- package/dist/eslint/rules/no-direct-lazy.d.ts +0 -3
- package/dist/fastify/index.d.ts +0 -33
- package/dist/fastify/index.js +0 -83
- package/dist/inline/index.d.ts +0 -1
- package/dist/inline-trace/index.d.ts +0 -1
- package/dist/node/index.d.ts +0 -58
- package/dist/node/index.js +0 -141
- package/dist/react/DebugSyncErrorTrigger.d.ts +0 -13
- package/dist/react/Spinner.d.ts +0 -9
- package/dist/react/index.d.ts +0 -9
- package/dist/react/index.js +0 -29
- package/dist/react/lazyWithRetry.d.ts +0 -34
- package/dist/react/types.d.ts +0 -42
- package/dist/react/useSPAGuardChunkError.d.ts +0 -2
- package/dist/react/useSPAGuardEvents.d.ts +0 -2
- package/dist/react-error-boundary/index.d.ts +0 -31
- package/dist/react-error-boundary/index.js +0 -98
- package/dist/react-router/index.d.ts +0 -25
- package/dist/react-router/index.js +0 -71
- package/dist/vite-plugin/index.d.ts +0 -6
- package/dist/vite-plugin/index.js +0 -105
- package/dist-inline/index.js +0 -1
- package/dist-inline-trace/index.js +0 -1
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export { debugSyncErrorEventType } from "./common/constants";
|
|
2
|
+
export { disableDefaultRetry, emitEvent, enableDefaultRetry, isDefaultRetryEnabled, subscribe, } from "./common/events/internal";
|
|
3
|
+
export type { SPAGuardEvent, SPAGuardEventChunkError, UnsubscribeFn } from "./common/events/types";
|
|
4
|
+
export { handleErrorWithSpaGuard } from "./common/handleErrorWithSpaGuard";
|
|
5
|
+
export type { ErrorInfoLike, HandleErrorOptions } from "./common/handleErrorWithSpaGuard";
|
|
6
|
+
export { defaultErrorFallbackHtml, defaultLoadingFallbackHtml } from "./common/html.generated";
|
|
7
|
+
export { applyI18n, getI18n } from "./common/i18n";
|
|
8
|
+
export { isChunkError } from "./common/isChunkError";
|
|
9
|
+
export { listenInternal } from "./common/listen/internal";
|
|
10
|
+
export { logMessage } from "./common/log";
|
|
11
|
+
export { createLogger } from "./common/logger";
|
|
12
|
+
export { getOptions, optionsWindowKey } from "./common/options";
|
|
13
|
+
export type { Options } from "./common/options";
|
|
14
|
+
export { extractVersionFromHtml } from "./common/parseVersion";
|
|
15
|
+
export { attemptReload } from "./common/reload";
|
|
16
|
+
export { retryImport } from "./common/retryImport";
|
|
17
|
+
export { serializeError } from "./common/serializeError";
|
|
18
|
+
export { defaultSpinnerSvg, SPINNER_ID } from "./common/spinner";
|
|
19
|
+
export { dispatchAsyncRuntimeError, dispatchChunkLoadError, dispatchFinallyError, dispatchForceRetryError, dispatchNetworkTimeout, dispatchSyncRuntimeError, dispatchUnhandledRejection, } from "./runtime/debug/errorDispatchers";
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
import {
|
|
2
|
+
attemptReload,
|
|
3
|
+
createLogger,
|
|
4
|
+
isChunkError,
|
|
5
|
+
listenInternal,
|
|
6
|
+
sendBeacon,
|
|
7
|
+
serializeError,
|
|
8
|
+
shouldForceRetry,
|
|
9
|
+
shouldIgnoreMessages
|
|
10
|
+
} from "./chunk-4FKSMB5F.js";
|
|
11
|
+
import {
|
|
12
|
+
SPINNER_ID,
|
|
13
|
+
defaultSpinnerSvg,
|
|
14
|
+
extractVersionFromHtml
|
|
15
|
+
} from "./chunk-3ISQYZVD.js";
|
|
16
|
+
import {
|
|
17
|
+
applyI18n,
|
|
18
|
+
defaultErrorFallbackHtml,
|
|
19
|
+
defaultLoadingFallbackHtml,
|
|
20
|
+
getI18n,
|
|
21
|
+
getOptions
|
|
22
|
+
} from "./chunk-DOTM7FSY.js";
|
|
23
|
+
import {
|
|
24
|
+
dispatchAsyncRuntimeError,
|
|
25
|
+
dispatchChunkLoadError,
|
|
26
|
+
dispatchFinallyError,
|
|
27
|
+
dispatchForceRetryError,
|
|
28
|
+
dispatchNetworkTimeout,
|
|
29
|
+
dispatchSyncRuntimeError,
|
|
30
|
+
dispatchUnhandledRejection
|
|
31
|
+
} from "./chunk-74K44EMP.js";
|
|
32
|
+
import {
|
|
33
|
+
debugSyncErrorEventType,
|
|
34
|
+
disableDefaultRetry,
|
|
35
|
+
emitEvent,
|
|
36
|
+
enableDefaultRetry,
|
|
37
|
+
getRetryInfoForBeacon,
|
|
38
|
+
isDefaultRetryEnabled,
|
|
39
|
+
optionsWindowKey,
|
|
40
|
+
subscribe
|
|
41
|
+
} from "./chunk-YSKH5K6P.js";
|
|
42
|
+
import "./chunk-MLKGABMK.js";
|
|
43
|
+
|
|
44
|
+
// src/common/handleErrorWithSpaGuard.ts
|
|
45
|
+
var handleErrorWithSpaGuard = (error, options) => {
|
|
46
|
+
const {
|
|
47
|
+
autoRetryChunkErrors = true,
|
|
48
|
+
errorInfo,
|
|
49
|
+
eventName,
|
|
50
|
+
onError,
|
|
51
|
+
sendBeaconOnError = true
|
|
52
|
+
} = options;
|
|
53
|
+
try {
|
|
54
|
+
onError?.(error);
|
|
55
|
+
} catch {
|
|
56
|
+
}
|
|
57
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
58
|
+
if (shouldIgnoreMessages([errorMessage])) {
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
const isChunk = isChunkError(error);
|
|
62
|
+
const isForceRetry = shouldForceRetry([errorMessage]);
|
|
63
|
+
if ((isChunk || isForceRetry) && autoRetryChunkErrors) {
|
|
64
|
+
attemptReload(error);
|
|
65
|
+
} else if (sendBeaconOnError) {
|
|
66
|
+
sendBeacon({
|
|
67
|
+
errorMessage: error instanceof Error ? error.message : String(error),
|
|
68
|
+
eventName,
|
|
69
|
+
serialized: serializeError(errorInfo ? { error, errorInfo } : error),
|
|
70
|
+
...getRetryInfoForBeacon()
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
// src/common/log.ts
|
|
76
|
+
var logMessage = (msg) => `[spa-guard] ${msg}`;
|
|
77
|
+
|
|
78
|
+
// src/common/retryImport.ts
|
|
79
|
+
var wait = (ms, signal) => new Promise((resolve, reject) => {
|
|
80
|
+
if (signal?.aborted) {
|
|
81
|
+
reject(signal.reason ?? new DOMException("Aborted", "AbortError"));
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
const onAbort = () => {
|
|
85
|
+
clearTimeout(timeoutId);
|
|
86
|
+
reject(signal.reason ?? new DOMException("Aborted", "AbortError"));
|
|
87
|
+
};
|
|
88
|
+
const timeoutId = setTimeout(() => {
|
|
89
|
+
signal?.removeEventListener("abort", onAbort);
|
|
90
|
+
resolve();
|
|
91
|
+
}, ms);
|
|
92
|
+
signal?.addEventListener("abort", onAbort, { once: true });
|
|
93
|
+
});
|
|
94
|
+
var retryImport = async (importFn, delays, options) => {
|
|
95
|
+
const { callReloadOnFailure, onRetry, signal } = options ?? {};
|
|
96
|
+
let lastError = new Error("Import failed after all retry attempts");
|
|
97
|
+
const totalAttempts = delays.length + 1;
|
|
98
|
+
for (let attempt = 0; attempt < totalAttempts; attempt++) {
|
|
99
|
+
if (signal?.aborted) {
|
|
100
|
+
throw signal.reason ?? new DOMException("Aborted", "AbortError");
|
|
101
|
+
}
|
|
102
|
+
try {
|
|
103
|
+
const result = await importFn();
|
|
104
|
+
if (attempt > 0) {
|
|
105
|
+
emitEvent({ attempt, name: "lazy-retry-success" });
|
|
106
|
+
}
|
|
107
|
+
return result;
|
|
108
|
+
} catch (error) {
|
|
109
|
+
lastError = error instanceof Error ? error : new Error(String(error));
|
|
110
|
+
const currentDelay = delays[attempt];
|
|
111
|
+
if (currentDelay === void 0) {
|
|
112
|
+
break;
|
|
113
|
+
}
|
|
114
|
+
onRetry?.(attempt + 1, currentDelay);
|
|
115
|
+
emitEvent({
|
|
116
|
+
attempt: attempt + 1,
|
|
117
|
+
delay: currentDelay,
|
|
118
|
+
name: "lazy-retry-attempt",
|
|
119
|
+
totalAttempts
|
|
120
|
+
});
|
|
121
|
+
await wait(currentDelay, signal);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
const willReload = callReloadOnFailure === true && isChunkError(lastError) && isDefaultRetryEnabled();
|
|
125
|
+
emitEvent({ name: "lazy-retry-exhausted", totalAttempts, willReload });
|
|
126
|
+
if (willReload) {
|
|
127
|
+
attemptReload(lastError);
|
|
128
|
+
}
|
|
129
|
+
throw lastError;
|
|
130
|
+
};
|
|
131
|
+
export {
|
|
132
|
+
SPINNER_ID,
|
|
133
|
+
applyI18n,
|
|
134
|
+
attemptReload,
|
|
135
|
+
createLogger,
|
|
136
|
+
debugSyncErrorEventType,
|
|
137
|
+
defaultErrorFallbackHtml,
|
|
138
|
+
defaultLoadingFallbackHtml,
|
|
139
|
+
defaultSpinnerSvg,
|
|
140
|
+
disableDefaultRetry,
|
|
141
|
+
dispatchAsyncRuntimeError,
|
|
142
|
+
dispatchChunkLoadError,
|
|
143
|
+
dispatchFinallyError,
|
|
144
|
+
dispatchForceRetryError,
|
|
145
|
+
dispatchNetworkTimeout,
|
|
146
|
+
dispatchSyncRuntimeError,
|
|
147
|
+
dispatchUnhandledRejection,
|
|
148
|
+
emitEvent,
|
|
149
|
+
enableDefaultRetry,
|
|
150
|
+
extractVersionFromHtml,
|
|
151
|
+
getI18n,
|
|
152
|
+
getOptions,
|
|
153
|
+
handleErrorWithSpaGuard,
|
|
154
|
+
isChunkError,
|
|
155
|
+
isDefaultRetryEnabled,
|
|
156
|
+
listenInternal,
|
|
157
|
+
logMessage,
|
|
158
|
+
optionsWindowKey,
|
|
159
|
+
retryImport,
|
|
160
|
+
serializeError,
|
|
161
|
+
subscribe
|
|
162
|
+
};
|
|
@@ -1,7 +1,20 @@
|
|
|
1
1
|
import {
|
|
2
2
|
defaultSpinnerHtml,
|
|
3
3
|
getOptions
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-DOTM7FSY.js";
|
|
5
|
+
|
|
6
|
+
// src/common/parseVersion.ts
|
|
7
|
+
function extractVersionFromHtml(html) {
|
|
8
|
+
const collapsed = html.replaceAll(/[\r\n]+/g, "");
|
|
9
|
+
const versionMatch = collapsed.match(/__SPA_GUARD_VERSION__\s*=\s*"([^"]+)"/);
|
|
10
|
+
if (versionMatch?.[1]) {
|
|
11
|
+
return versionMatch[1];
|
|
12
|
+
}
|
|
13
|
+
const optionsMatch = collapsed.match(
|
|
14
|
+
/__SPA_GUARD_OPTIONS__\s*=\s*\{.*?"?version"?\s*:\s*"([^"]+)"/
|
|
15
|
+
);
|
|
16
|
+
return optionsMatch?.[1] ?? null;
|
|
17
|
+
}
|
|
5
18
|
|
|
6
19
|
// src/common/spinner.ts
|
|
7
20
|
var SPINNER_ID = "__spa-guard-spinner";
|
|
@@ -32,6 +45,10 @@ function getSpinnerHtml(backgroundOverride) {
|
|
|
32
45
|
return `<div id="${SPINNER_ID}" style="position:fixed;inset:0;z-index:2147483647;display:flex;align-items:center;justify-content:center;background:var(--spa-guard-spinner-bg,${bg})">${spinnerContent}</div>`;
|
|
33
46
|
}
|
|
34
47
|
function showSpinner(options) {
|
|
48
|
+
if (typeof document === "undefined") {
|
|
49
|
+
return () => {
|
|
50
|
+
};
|
|
51
|
+
}
|
|
35
52
|
const opts = getOptions();
|
|
36
53
|
if (opts.spinner?.disabled) {
|
|
37
54
|
return () => {
|
|
@@ -58,6 +75,7 @@ function showSpinner(options) {
|
|
|
58
75
|
}
|
|
59
76
|
|
|
60
77
|
export {
|
|
78
|
+
extractVersionFromHtml,
|
|
61
79
|
SPINNER_ID,
|
|
62
80
|
defaultSpinnerSvg,
|
|
63
81
|
dismissSpinner,
|