@ovineko/spa-guard 0.0.2-alpha-1 → 0.0.4
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/README.md +22 -173
- package/dist/ForceRetryError-BWLv3UVK.d.mts +6 -0
- package/dist/_internal.d.ts +149 -20
- package/dist/_internal.js +113 -170
- package/dist/chunk-CfYAbeIz.mjs +13 -0
- package/dist/common/index.d.ts +29 -9
- package/dist/common/index.js +47 -83
- package/dist/errorDispatchers-Cl_pa0DT.mjs +105 -0
- package/dist/i18n/index.d.ts +2 -21
- package/dist/i18n/index.js +344 -341
- package/dist/index-DL8CfPXg.d.mts +26 -0
- package/dist/index-rPxPv6iu.d.mts +16 -0
- package/dist/logger-Cp1Eyk6S.mjs +534 -0
- package/dist/retryOrchestrator-DNGIHV2M.mjs +758 -0
- package/dist/retryOrchestrator-mn9XcIVu.d.mts +257 -0
- package/dist/runtime/debug/index.d.ts +6 -4
- package/dist/runtime/debug/index.js +218 -238
- package/dist/runtime/index.d.ts +66 -8
- package/dist/runtime/index.js +279 -367
- package/dist/schema/index.d.ts +2 -13
- package/dist/schema/index.js +1 -0
- package/dist/schema/parse.d.ts +6 -2
- package/dist/schema/parse.js +29 -44
- package/dist/spinner-BbZVKZ-6.mjs +60 -0
- package/dist/spinner-X23gI09z.d.mts +37 -0
- package/dist/state-I20jENMD.mjs +93 -0
- package/dist/types-DrN8pgyc.d.mts +107 -0
- package/package.json +1 -4
- package/dist/chunk-3UJ67DPX.js +0 -98
- package/dist/chunk-GE63YJOT.js +0 -865
- package/dist/chunk-MLKGABMK.js +0 -9
- package/dist/chunk-PERG4557.js +0 -74
- package/dist/chunk-VZ2DLGXX.js +0 -111
- package/dist/chunk-XIFXSNSD.js +0 -678
- package/dist/common/checkVersion.d.ts +0 -5
- package/dist/common/constants.d.ts +0 -14
- package/dist/common/errors/BeaconError.d.ts +0 -12
- package/dist/common/errors/ForceRetryError.d.ts +0 -5
- package/dist/common/events/index.d.ts +0 -2
- package/dist/common/events/internal.d.ts +0 -13
- package/dist/common/events/types.d.ts +0 -104
- package/dist/common/fallbackRendering.d.ts +0 -23
- package/dist/common/fallbackState.d.ts +0 -3
- package/dist/common/handleErrorWithSpaGuard.d.ts +0 -18
- package/dist/common/html.generated.d.ts +0 -3
- package/dist/common/i18n.d.ts +0 -23
- package/dist/common/isChunkError.d.ts +0 -1
- package/dist/common/isStaticAssetError.d.ts +0 -3
- package/dist/common/lastReloadTime.d.ts +0 -17
- package/dist/common/listen/index.d.ts +0 -1
- package/dist/common/listen/internal.d.ts +0 -2
- package/dist/common/log.d.ts +0 -1
- package/dist/common/logger.d.ts +0 -30
- package/dist/common/options.d.ts +0 -182
- package/dist/common/parseVersion.d.ts +0 -9
- package/dist/common/retryImport.d.ts +0 -43
- package/dist/common/retryOrchestrator.d.ts +0 -35
- package/dist/common/retryState.d.ts +0 -11
- package/dist/common/sendBeacon.d.ts +0 -2
- package/dist/common/serializeError.d.ts +0 -1
- package/dist/common/shouldIgnore.d.ts +0 -13
- package/dist/common/spinner.d.ts +0 -8
- package/dist/common/staticAssetRecovery.d.ts +0 -2
- package/dist/i18n/translations.d.ts +0 -2
- package/dist/runtime/debug/errorDispatchers.d.ts +0 -63
- package/dist/runtime/recommendedSetup.d.ts +0 -36
- package/dist/runtime/state.d.ts +0 -20
package/dist/chunk-XIFXSNSD.js
DELETED
|
@@ -1,678 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
emitEvent,
|
|
3
|
-
getLogger,
|
|
4
|
-
getOptions,
|
|
5
|
-
getRetryInfoForBeacon,
|
|
6
|
-
isInitialized,
|
|
7
|
-
markInitialized,
|
|
8
|
-
sendBeacon,
|
|
9
|
-
setLogger,
|
|
10
|
-
shouldForceRetry,
|
|
11
|
-
shouldIgnoreMessages,
|
|
12
|
-
staticAssetRecoveryKey,
|
|
13
|
-
triggerRetry
|
|
14
|
-
} from "./chunk-GE63YJOT.js";
|
|
15
|
-
|
|
16
|
-
// src/common/isChunkError.ts
|
|
17
|
-
var isChunkError = (error) => {
|
|
18
|
-
const message = getErrorMessage(error);
|
|
19
|
-
if (!message) {
|
|
20
|
-
return false;
|
|
21
|
-
}
|
|
22
|
-
const patterns = [
|
|
23
|
-
/Failed to fetch dynamically imported module/i,
|
|
24
|
-
/Importing a module script failed/i,
|
|
25
|
-
/error loading dynamically imported module/i,
|
|
26
|
-
/Unable to preload CSS/i,
|
|
27
|
-
/Loading chunk \d+ failed/i,
|
|
28
|
-
/Loading CSS chunk \d+ failed/i,
|
|
29
|
-
/ChunkLoadError/i
|
|
30
|
-
];
|
|
31
|
-
return patterns.some((pattern) => pattern.test(message));
|
|
32
|
-
};
|
|
33
|
-
var getErrorMessage = (error) => {
|
|
34
|
-
if (error instanceof Error) {
|
|
35
|
-
return error.message;
|
|
36
|
-
}
|
|
37
|
-
if (typeof error === "string") {
|
|
38
|
-
return error;
|
|
39
|
-
}
|
|
40
|
-
if (error && typeof error === "object" && "message" in error) {
|
|
41
|
-
return String(error.message);
|
|
42
|
-
}
|
|
43
|
-
if (error && typeof error === "object" && "reason" in error) {
|
|
44
|
-
return getErrorMessage(error.reason);
|
|
45
|
-
}
|
|
46
|
-
return null;
|
|
47
|
-
};
|
|
48
|
-
|
|
49
|
-
// src/common/serializeError.ts
|
|
50
|
-
var serializeError = (error) => {
|
|
51
|
-
try {
|
|
52
|
-
const serialized = serializeErrorInternal(error);
|
|
53
|
-
return JSON.stringify(serialized, null, 2);
|
|
54
|
-
} catch {
|
|
55
|
-
return JSON.stringify({
|
|
56
|
-
error: "Failed to serialize error",
|
|
57
|
-
fallback: String(error)
|
|
58
|
-
});
|
|
59
|
-
}
|
|
60
|
-
};
|
|
61
|
-
var MAX_DEPTH = 4;
|
|
62
|
-
var MAX_KEYS = 20;
|
|
63
|
-
var MAX_STRING_LEN = 500;
|
|
64
|
-
var truncate = (str) => str.length > MAX_STRING_LEN ? str.slice(0, MAX_STRING_LEN) + "\u2026" : str;
|
|
65
|
-
var serializeErrorInternal = (error) => {
|
|
66
|
-
if (error === null || error === void 0) {
|
|
67
|
-
return { type: "null", value: error };
|
|
68
|
-
}
|
|
69
|
-
if (typeof error !== "object") {
|
|
70
|
-
return { type: typeof error, value: error };
|
|
71
|
-
}
|
|
72
|
-
if (error instanceof Error) {
|
|
73
|
-
return {
|
|
74
|
-
message: error.message,
|
|
75
|
-
name: error.name,
|
|
76
|
-
stack: error.stack ? truncate(error.stack) : void 0,
|
|
77
|
-
type: "Error",
|
|
78
|
-
...extractErrorProperties(error)
|
|
79
|
-
};
|
|
80
|
-
}
|
|
81
|
-
if ("reason" in error && "promise" in error) {
|
|
82
|
-
const evt = error;
|
|
83
|
-
const reason = evt.reason;
|
|
84
|
-
const pageUrl = typeof window !== "undefined" && typeof window.location?.href === "string" ? window.location.href : void 0;
|
|
85
|
-
return {
|
|
86
|
-
constructorName: reason?.constructor?.name,
|
|
87
|
-
isTrusted: evt.isTrusted,
|
|
88
|
-
pageUrl,
|
|
89
|
-
reason: serializeRejectionReason(reason, /* @__PURE__ */ new WeakSet(), 0),
|
|
90
|
-
timeStamp: evt.timeStamp,
|
|
91
|
-
type: "PromiseRejectionEvent"
|
|
92
|
-
};
|
|
93
|
-
}
|
|
94
|
-
if ("error" in error && "message" in error && "filename" in error) {
|
|
95
|
-
return {
|
|
96
|
-
colno: error.colno,
|
|
97
|
-
error: serializeErrorInternal(error.error),
|
|
98
|
-
filename: error.filename,
|
|
99
|
-
lineno: error.lineno,
|
|
100
|
-
message: error.message,
|
|
101
|
-
type: "ErrorEvent"
|
|
102
|
-
};
|
|
103
|
-
}
|
|
104
|
-
if ("violatedDirective" in error && "blockedURI" in error) {
|
|
105
|
-
const evt = error;
|
|
106
|
-
return {
|
|
107
|
-
blockedURI: evt.blockedURI,
|
|
108
|
-
columnNumber: evt.columnNumber,
|
|
109
|
-
effectiveDirective: evt.effectiveDirective,
|
|
110
|
-
lineNumber: evt.lineNumber,
|
|
111
|
-
originalPolicy: evt.originalPolicy,
|
|
112
|
-
sourceFile: evt.sourceFile,
|
|
113
|
-
type: "SecurityPolicyViolationEvent",
|
|
114
|
-
violatedDirective: evt.violatedDirective
|
|
115
|
-
};
|
|
116
|
-
}
|
|
117
|
-
if ("type" in error && "target" in error) {
|
|
118
|
-
const evt = error;
|
|
119
|
-
return {
|
|
120
|
-
eventType: evt.type,
|
|
121
|
-
target: extractEventTarget(evt.target),
|
|
122
|
-
timeStamp: evt.timeStamp,
|
|
123
|
-
type: "Event"
|
|
124
|
-
};
|
|
125
|
-
}
|
|
126
|
-
return {
|
|
127
|
-
type: "object",
|
|
128
|
-
value: extractOwnProperties(error)
|
|
129
|
-
};
|
|
130
|
-
};
|
|
131
|
-
var serializeRejectionReason = (reason, visited, depth) => {
|
|
132
|
-
if (reason === null || reason === void 0) {
|
|
133
|
-
return { type: "null", value: reason };
|
|
134
|
-
}
|
|
135
|
-
if (typeof reason !== "object") {
|
|
136
|
-
const val = typeof reason === "string" ? truncate(reason) : reason;
|
|
137
|
-
return { type: typeof reason, value: val };
|
|
138
|
-
}
|
|
139
|
-
if (visited.has(reason)) {
|
|
140
|
-
return { type: "circular" };
|
|
141
|
-
}
|
|
142
|
-
visited.add(reason);
|
|
143
|
-
if (typeof AggregateError !== "undefined" && reason instanceof AggregateError) {
|
|
144
|
-
return {
|
|
145
|
-
errors: reason.errors.slice(0, 3).map((e) => serializeSafeError(e, visited, depth + 1)),
|
|
146
|
-
message: truncate(reason.message),
|
|
147
|
-
name: reason.name,
|
|
148
|
-
stack: reason.stack ? truncate(reason.stack) : void 0,
|
|
149
|
-
type: "Error"
|
|
150
|
-
};
|
|
151
|
-
}
|
|
152
|
-
if (typeof DOMException !== "undefined" && reason instanceof DOMException) {
|
|
153
|
-
return {
|
|
154
|
-
code: reason.code,
|
|
155
|
-
message: truncate(reason.message),
|
|
156
|
-
name: reason.name,
|
|
157
|
-
type: "Error"
|
|
158
|
-
};
|
|
159
|
-
}
|
|
160
|
-
const reasonObj = reason;
|
|
161
|
-
if (reasonObj.response != null) {
|
|
162
|
-
const response = reasonObj.response;
|
|
163
|
-
const result = {
|
|
164
|
-
type: "HttpError"
|
|
165
|
-
};
|
|
166
|
-
if (response.status !== void 0) {
|
|
167
|
-
result.status = response.status;
|
|
168
|
-
}
|
|
169
|
-
if (response.statusText !== void 0) {
|
|
170
|
-
result.statusText = typeof response.statusText === "string" ? truncate(response.statusText) : response.statusText;
|
|
171
|
-
}
|
|
172
|
-
if (response.url !== void 0) {
|
|
173
|
-
result.url = typeof response.url === "string" ? truncate(response.url) : response.url;
|
|
174
|
-
}
|
|
175
|
-
if (response.method !== void 0) {
|
|
176
|
-
result.method = response.method;
|
|
177
|
-
}
|
|
178
|
-
if (response.type !== void 0) {
|
|
179
|
-
result.responseType = response.type;
|
|
180
|
-
}
|
|
181
|
-
try {
|
|
182
|
-
const headers = response.headers;
|
|
183
|
-
if (headers) {
|
|
184
|
-
let xRequestId;
|
|
185
|
-
if (typeof headers.get === "function") {
|
|
186
|
-
xRequestId = headers.get("X-Request-ID") ?? headers.get("x-request-id");
|
|
187
|
-
} else if (typeof headers === "object") {
|
|
188
|
-
xRequestId = headers["X-Request-ID"] ?? headers["x-request-id"];
|
|
189
|
-
}
|
|
190
|
-
if (xRequestId) {
|
|
191
|
-
result.xRequestId = truncate(String(xRequestId));
|
|
192
|
-
}
|
|
193
|
-
}
|
|
194
|
-
} catch {
|
|
195
|
-
}
|
|
196
|
-
const reqSource = reasonObj.config ?? reasonObj.request;
|
|
197
|
-
if (reqSource != null) {
|
|
198
|
-
const req = {};
|
|
199
|
-
if (reqSource.method !== void 0) {
|
|
200
|
-
req.method = reqSource.method;
|
|
201
|
-
}
|
|
202
|
-
if (reqSource.url !== void 0) {
|
|
203
|
-
req.url = typeof reqSource.url === "string" ? truncate(reqSource.url) : reqSource.url;
|
|
204
|
-
}
|
|
205
|
-
if (reqSource.baseURL !== void 0) {
|
|
206
|
-
req.baseURL = typeof reqSource.baseURL === "string" ? truncate(reqSource.baseURL) : reqSource.baseURL;
|
|
207
|
-
}
|
|
208
|
-
result.request = req;
|
|
209
|
-
}
|
|
210
|
-
return result;
|
|
211
|
-
}
|
|
212
|
-
if (reason instanceof Error) {
|
|
213
|
-
return serializeSafeError(reason, visited, depth);
|
|
214
|
-
}
|
|
215
|
-
return {
|
|
216
|
-
type: "object",
|
|
217
|
-
value: extractBoundedObject(reasonObj, visited, depth)
|
|
218
|
-
};
|
|
219
|
-
};
|
|
220
|
-
var serializeSafeError = (error, visited, depth) => {
|
|
221
|
-
if (!(error instanceof Error)) {
|
|
222
|
-
return serializeRejectionReason(error, visited, depth + 1);
|
|
223
|
-
}
|
|
224
|
-
const result = {
|
|
225
|
-
message: truncate(error.message),
|
|
226
|
-
name: error.name,
|
|
227
|
-
stack: error.stack ? truncate(error.stack) : void 0,
|
|
228
|
-
type: "Error"
|
|
229
|
-
};
|
|
230
|
-
if (depth < MAX_DEPTH && error.cause !== void 0) {
|
|
231
|
-
const cause = error.cause;
|
|
232
|
-
if (typeof cause === "object" && cause !== null) {
|
|
233
|
-
if (!visited.has(cause)) {
|
|
234
|
-
result.cause = serializeRejectionReason(cause, visited, depth + 1);
|
|
235
|
-
}
|
|
236
|
-
} else {
|
|
237
|
-
result.cause = cause;
|
|
238
|
-
}
|
|
239
|
-
}
|
|
240
|
-
return result;
|
|
241
|
-
};
|
|
242
|
-
var extractBoundedObject = (obj, visited, depth) => {
|
|
243
|
-
const result = {};
|
|
244
|
-
let keyCount = 0;
|
|
245
|
-
for (const key of Object.keys(obj)) {
|
|
246
|
-
if (keyCount >= MAX_KEYS) {
|
|
247
|
-
break;
|
|
248
|
-
}
|
|
249
|
-
try {
|
|
250
|
-
const value = obj[key];
|
|
251
|
-
if (value === null || value === void 0 || typeof value !== "object") {
|
|
252
|
-
result[key] = typeof value === "string" ? truncate(value) : value;
|
|
253
|
-
} else if (depth < MAX_DEPTH && !visited.has(value)) {
|
|
254
|
-
visited.add(value);
|
|
255
|
-
result[key] = extractBoundedObject(value, visited, depth + 1);
|
|
256
|
-
} else {
|
|
257
|
-
result[key] = "[object]";
|
|
258
|
-
}
|
|
259
|
-
} catch {
|
|
260
|
-
}
|
|
261
|
-
keyCount++;
|
|
262
|
-
}
|
|
263
|
-
return result;
|
|
264
|
-
};
|
|
265
|
-
var extractErrorProperties = (error) => {
|
|
266
|
-
const props = {};
|
|
267
|
-
let keyCount = 0;
|
|
268
|
-
for (const key of Object.getOwnPropertyNames(error)) {
|
|
269
|
-
if (keyCount >= MAX_KEYS) {
|
|
270
|
-
break;
|
|
271
|
-
}
|
|
272
|
-
if (!["message", "name", "stack"].includes(key)) {
|
|
273
|
-
try {
|
|
274
|
-
const value = error[key];
|
|
275
|
-
if (value === null || value === void 0 || typeof value !== "object") {
|
|
276
|
-
props[key] = typeof value === "string" ? truncate(value) : value;
|
|
277
|
-
} else {
|
|
278
|
-
props[key] = "[object]";
|
|
279
|
-
}
|
|
280
|
-
} catch {
|
|
281
|
-
}
|
|
282
|
-
keyCount++;
|
|
283
|
-
}
|
|
284
|
-
}
|
|
285
|
-
return props;
|
|
286
|
-
};
|
|
287
|
-
var extractEventTarget = (target) => {
|
|
288
|
-
if (!target) {
|
|
289
|
-
return null;
|
|
290
|
-
}
|
|
291
|
-
if (target instanceof HTMLElement) {
|
|
292
|
-
return {
|
|
293
|
-
className: target.className,
|
|
294
|
-
href: target.href,
|
|
295
|
-
id: target.id,
|
|
296
|
-
src: target.src,
|
|
297
|
-
tagName: target.tagName
|
|
298
|
-
};
|
|
299
|
-
}
|
|
300
|
-
return { type: String(target) };
|
|
301
|
-
};
|
|
302
|
-
var extractOwnProperties = (obj) => {
|
|
303
|
-
const props = {};
|
|
304
|
-
let keyCount = 0;
|
|
305
|
-
for (const key of Object.keys(obj)) {
|
|
306
|
-
if (keyCount >= MAX_KEYS) {
|
|
307
|
-
break;
|
|
308
|
-
}
|
|
309
|
-
try {
|
|
310
|
-
const value = obj[key];
|
|
311
|
-
if (value === null || value === void 0 || typeof value !== "object") {
|
|
312
|
-
props[key] = typeof value === "string" ? truncate(value) : value;
|
|
313
|
-
} else {
|
|
314
|
-
props[key] = "[object]";
|
|
315
|
-
}
|
|
316
|
-
} catch {
|
|
317
|
-
}
|
|
318
|
-
keyCount++;
|
|
319
|
-
}
|
|
320
|
-
return props;
|
|
321
|
-
};
|
|
322
|
-
|
|
323
|
-
// src/common/isStaticAssetError.ts
|
|
324
|
-
var HASHED_ASSET_RE = /[-._][a-zA-Z0-9]{6,}\.(js|mjs|css)$/i;
|
|
325
|
-
var isHashedAssetUrl = (url) => {
|
|
326
|
-
try {
|
|
327
|
-
const pathname = new URL(url).pathname;
|
|
328
|
-
return HASHED_ASSET_RE.test(pathname);
|
|
329
|
-
} catch {
|
|
330
|
-
return HASHED_ASSET_RE.test(url);
|
|
331
|
-
}
|
|
332
|
-
};
|
|
333
|
-
var isStaticAssetError = (event) => {
|
|
334
|
-
const target = event.target;
|
|
335
|
-
if (target instanceof HTMLScriptElement) {
|
|
336
|
-
return isHashedAssetUrl(target.src);
|
|
337
|
-
}
|
|
338
|
-
if (target instanceof HTMLLinkElement) {
|
|
339
|
-
return isHashedAssetUrl(target.href);
|
|
340
|
-
}
|
|
341
|
-
return false;
|
|
342
|
-
};
|
|
343
|
-
var checkResourceStatus = (url) => {
|
|
344
|
-
if (typeof performance === "undefined" || typeof performance.getEntriesByName !== "function") {
|
|
345
|
-
return true;
|
|
346
|
-
}
|
|
347
|
-
const entries = performance.getEntriesByName(url, "resource");
|
|
348
|
-
if (entries.length === 0) {
|
|
349
|
-
return true;
|
|
350
|
-
}
|
|
351
|
-
const entry = entries.at(-1);
|
|
352
|
-
if (entry.responseStatus >= 400) {
|
|
353
|
-
return true;
|
|
354
|
-
}
|
|
355
|
-
if (entry.transferSize === 0 && entry.decodedBodySize === 0) {
|
|
356
|
-
return true;
|
|
357
|
-
}
|
|
358
|
-
return false;
|
|
359
|
-
};
|
|
360
|
-
var isLikely404 = (url, timeSinceNavMs) => {
|
|
361
|
-
if (url !== void 0) {
|
|
362
|
-
return checkResourceStatus(url);
|
|
363
|
-
}
|
|
364
|
-
const elapsed = timeSinceNavMs ?? (typeof performance === "undefined" ? 0 : performance.now());
|
|
365
|
-
return elapsed > 3e4;
|
|
366
|
-
};
|
|
367
|
-
var getAssetUrl = (event) => {
|
|
368
|
-
const target = event.target;
|
|
369
|
-
if (target instanceof HTMLScriptElement) {
|
|
370
|
-
return target.src;
|
|
371
|
-
}
|
|
372
|
-
if (target instanceof HTMLLinkElement) {
|
|
373
|
-
return target.href;
|
|
374
|
-
}
|
|
375
|
-
return "";
|
|
376
|
-
};
|
|
377
|
-
|
|
378
|
-
// src/common/staticAssetRecovery.ts
|
|
379
|
-
var getState = () => {
|
|
380
|
-
if (globalThis.window === void 0) {
|
|
381
|
-
return { failedAssets: /* @__PURE__ */ new Set(), recoveryTimer: null };
|
|
382
|
-
}
|
|
383
|
-
if (!globalThis.window[staticAssetRecoveryKey]) {
|
|
384
|
-
globalThis.window[staticAssetRecoveryKey] = {
|
|
385
|
-
failedAssets: /* @__PURE__ */ new Set(),
|
|
386
|
-
recoveryTimer: null
|
|
387
|
-
};
|
|
388
|
-
}
|
|
389
|
-
return globalThis.window[staticAssetRecoveryKey];
|
|
390
|
-
};
|
|
391
|
-
var handleStaticAssetFailure = (url) => {
|
|
392
|
-
if (globalThis.window === void 0) {
|
|
393
|
-
return;
|
|
394
|
-
}
|
|
395
|
-
const state = getState();
|
|
396
|
-
state.failedAssets.add(url);
|
|
397
|
-
if (state.recoveryTimer !== null) {
|
|
398
|
-
return;
|
|
399
|
-
}
|
|
400
|
-
const options = getOptions();
|
|
401
|
-
const delay = options.staticAssets?.recoveryDelay ?? 500;
|
|
402
|
-
state.recoveryTimer = setTimeout(() => {
|
|
403
|
-
const s = getState();
|
|
404
|
-
s.recoveryTimer = null;
|
|
405
|
-
const assets = [...s.failedAssets];
|
|
406
|
-
s.failedAssets = /* @__PURE__ */ new Set();
|
|
407
|
-
const error = new Error(`Static asset load failed: ${assets.join(", ")}`);
|
|
408
|
-
triggerRetry({ cacheBust: true, error, source: "static-asset-error" });
|
|
409
|
-
}, delay);
|
|
410
|
-
};
|
|
411
|
-
|
|
412
|
-
// src/common/listen/internal.ts
|
|
413
|
-
var listenInternal = (serializeError2, logger) => {
|
|
414
|
-
if (globalThis.window === void 0) {
|
|
415
|
-
return;
|
|
416
|
-
}
|
|
417
|
-
if (isInitialized()) {
|
|
418
|
-
return;
|
|
419
|
-
}
|
|
420
|
-
if (logger) {
|
|
421
|
-
setLogger(logger);
|
|
422
|
-
}
|
|
423
|
-
markInitialized();
|
|
424
|
-
const wa = globalThis.window.addEventListener.bind(globalThis.window);
|
|
425
|
-
wa(
|
|
426
|
-
"error",
|
|
427
|
-
(event) => {
|
|
428
|
-
const assetUrl = getAssetUrl(event);
|
|
429
|
-
if (isStaticAssetError(event) && isLikely404(assetUrl)) {
|
|
430
|
-
if (shouldIgnoreMessages([assetUrl, event.message])) {
|
|
431
|
-
return;
|
|
432
|
-
}
|
|
433
|
-
event.preventDefault();
|
|
434
|
-
emitEvent({ name: "static-asset-load-failed", url: assetUrl });
|
|
435
|
-
if (getOptions().staticAssets?.autoRecover !== false) {
|
|
436
|
-
handleStaticAssetFailure(assetUrl);
|
|
437
|
-
}
|
|
438
|
-
return;
|
|
439
|
-
}
|
|
440
|
-
if (shouldIgnoreMessages([event.message])) {
|
|
441
|
-
return;
|
|
442
|
-
}
|
|
443
|
-
getLogger()?.capturedError("error", event);
|
|
444
|
-
if (isChunkError(event)) {
|
|
445
|
-
event.preventDefault();
|
|
446
|
-
triggerRetry({ error: event.error ?? event, source: "chunk-error" });
|
|
447
|
-
return;
|
|
448
|
-
}
|
|
449
|
-
if (shouldForceRetry([event.message])) {
|
|
450
|
-
event.preventDefault();
|
|
451
|
-
triggerRetry({ error: event.error ?? event, source: "force-retry" });
|
|
452
|
-
return;
|
|
453
|
-
}
|
|
454
|
-
const serialized = serializeError2(event);
|
|
455
|
-
sendBeacon({
|
|
456
|
-
errorMessage: event.message,
|
|
457
|
-
eventName: "error",
|
|
458
|
-
serialized,
|
|
459
|
-
...getRetryInfoForBeacon()
|
|
460
|
-
});
|
|
461
|
-
},
|
|
462
|
-
true
|
|
463
|
-
);
|
|
464
|
-
wa("unhandledrejection", (event) => {
|
|
465
|
-
const errorMessage = String(event.reason);
|
|
466
|
-
if (shouldIgnoreMessages([errorMessage])) {
|
|
467
|
-
return;
|
|
468
|
-
}
|
|
469
|
-
getLogger()?.capturedError("unhandledrejection", event);
|
|
470
|
-
if (isChunkError(event.reason)) {
|
|
471
|
-
event.preventDefault();
|
|
472
|
-
triggerRetry({ error: event.reason, source: "chunk-error" });
|
|
473
|
-
return;
|
|
474
|
-
}
|
|
475
|
-
if (shouldForceRetry([errorMessage])) {
|
|
476
|
-
event.preventDefault();
|
|
477
|
-
triggerRetry({ error: event.reason, source: "force-retry" });
|
|
478
|
-
return;
|
|
479
|
-
}
|
|
480
|
-
const rejectionConfig = getOptions().handleUnhandledRejections;
|
|
481
|
-
if (rejectionConfig?.sendBeacon !== false) {
|
|
482
|
-
const serialized = serializeError2(event);
|
|
483
|
-
sendBeacon({
|
|
484
|
-
errorMessage,
|
|
485
|
-
eventName: "unhandledrejection",
|
|
486
|
-
serialized,
|
|
487
|
-
...getRetryInfoForBeacon()
|
|
488
|
-
});
|
|
489
|
-
}
|
|
490
|
-
if (rejectionConfig?.retry !== false) {
|
|
491
|
-
event.preventDefault();
|
|
492
|
-
triggerRetry({ error: event.reason, source: "unhandled-rejection" });
|
|
493
|
-
}
|
|
494
|
-
});
|
|
495
|
-
wa("securitypolicyviolation", (event) => {
|
|
496
|
-
const eventMessage = `${event.violatedDirective}: ${event.blockedURI}`;
|
|
497
|
-
if (shouldIgnoreMessages([eventMessage])) {
|
|
498
|
-
return;
|
|
499
|
-
}
|
|
500
|
-
getLogger()?.capturedError("csp", event.blockedURI, event.violatedDirective);
|
|
501
|
-
const serialized = serializeError2(event);
|
|
502
|
-
sendBeacon({
|
|
503
|
-
eventMessage,
|
|
504
|
-
eventName: "securitypolicyviolation",
|
|
505
|
-
serialized,
|
|
506
|
-
...getRetryInfoForBeacon()
|
|
507
|
-
});
|
|
508
|
-
});
|
|
509
|
-
wa("vite:preloadError", (event) => {
|
|
510
|
-
const payload = event?.payload;
|
|
511
|
-
const errorMsg = payload?.message || event?.message;
|
|
512
|
-
if (shouldIgnoreMessages([errorMsg])) {
|
|
513
|
-
return;
|
|
514
|
-
}
|
|
515
|
-
getLogger()?.capturedError("vite:preloadError", event);
|
|
516
|
-
event.preventDefault();
|
|
517
|
-
triggerRetry({ error: payload ?? event, source: "vite:preloadError" });
|
|
518
|
-
});
|
|
519
|
-
};
|
|
520
|
-
|
|
521
|
-
// src/common/logger.ts
|
|
522
|
-
var PREFIX = "[spa-guard]";
|
|
523
|
-
var eventLogConfig = {
|
|
524
|
-
"chunk-error": "error",
|
|
525
|
-
"fallback-ui-not-rendered": "error",
|
|
526
|
-
"fallback-ui-shown": "warn",
|
|
527
|
-
"lazy-retry-attempt": "warn",
|
|
528
|
-
"lazy-retry-exhausted": "error",
|
|
529
|
-
"lazy-retry-start": "log",
|
|
530
|
-
"lazy-retry-success": "log",
|
|
531
|
-
"retry-attempt": "warn",
|
|
532
|
-
"retry-exhausted": "error",
|
|
533
|
-
"retry-reset": "log",
|
|
534
|
-
"static-asset-load-failed": "error"
|
|
535
|
-
};
|
|
536
|
-
var formatEvent = (event) => {
|
|
537
|
-
switch (event.name) {
|
|
538
|
-
case "chunk-error": {
|
|
539
|
-
return `${PREFIX} chunk-error: isRetrying=${event.isRetrying}`;
|
|
540
|
-
}
|
|
541
|
-
case "fallback-ui-not-rendered": {
|
|
542
|
-
const selectorPart = event.selector ? ` selector=${event.selector}` : "";
|
|
543
|
-
return `${PREFIX} fallback-ui-not-rendered: reason=${event.reason}${selectorPart}`;
|
|
544
|
-
}
|
|
545
|
-
case "fallback-ui-shown": {
|
|
546
|
-
return `${PREFIX} fallback-ui-shown`;
|
|
547
|
-
}
|
|
548
|
-
case "lazy-retry-attempt": {
|
|
549
|
-
return `${PREFIX} lazy-retry-attempt: attempt ${event.attempt}/${event.totalAttempts}, delay ${event.delay}ms`;
|
|
550
|
-
}
|
|
551
|
-
case "lazy-retry-exhausted": {
|
|
552
|
-
return `${PREFIX} lazy-retry-exhausted: ${event.totalAttempts} attempts, willReload=${event.willReload}`;
|
|
553
|
-
}
|
|
554
|
-
case "lazy-retry-start": {
|
|
555
|
-
return `${PREFIX} lazy-retry-start: totalAttempts=${event.totalAttempts}`;
|
|
556
|
-
}
|
|
557
|
-
case "lazy-retry-success": {
|
|
558
|
-
const timePart = event.totalTime === void 0 ? "" : `, totalTime=${event.totalTime}ms`;
|
|
559
|
-
return `${PREFIX} lazy-retry-success: succeeded on attempt ${event.attempt}${timePart}`;
|
|
560
|
-
}
|
|
561
|
-
case "retry-attempt": {
|
|
562
|
-
return `${PREFIX} retry-attempt: attempt ${event.attempt} in ${event.delay}ms (retryId: ${event.retryId})`;
|
|
563
|
-
}
|
|
564
|
-
case "retry-exhausted": {
|
|
565
|
-
return `${PREFIX} retry-exhausted: finalAttempt=${event.finalAttempt} (retryId: ${event.retryId})`;
|
|
566
|
-
}
|
|
567
|
-
case "retry-reset": {
|
|
568
|
-
return `${PREFIX} retry-reset: ${event.timeSinceReload}ms since last reload (retryId: ${event.previousRetryId})`;
|
|
569
|
-
}
|
|
570
|
-
case "static-asset-load-failed": {
|
|
571
|
-
return `${PREFIX} static-asset-load-failed: ${event.url}`;
|
|
572
|
-
}
|
|
573
|
-
}
|
|
574
|
-
};
|
|
575
|
-
var createLogger = () => ({
|
|
576
|
-
beaconSendFailed(error) {
|
|
577
|
-
console.error(`${PREFIX} Failed to send beacon:`, error);
|
|
578
|
-
},
|
|
579
|
-
capturedError(type, ...args) {
|
|
580
|
-
console.error(`${PREFIX} ${type}:capture:`, ...args);
|
|
581
|
-
},
|
|
582
|
-
error(msg, ...args) {
|
|
583
|
-
console.error(`${PREFIX} ${msg}`, ...args);
|
|
584
|
-
},
|
|
585
|
-
fallbackAlreadyShown(error) {
|
|
586
|
-
console.error(
|
|
587
|
-
`${PREFIX} Fallback UI was already shown. Not retrying to prevent infinite loop.`,
|
|
588
|
-
error
|
|
589
|
-
);
|
|
590
|
-
},
|
|
591
|
-
fallbackInjectFailed(error) {
|
|
592
|
-
console.error(`${PREFIX} Failed to inject fallback UI`, error);
|
|
593
|
-
},
|
|
594
|
-
fallbackTargetNotFound(selector) {
|
|
595
|
-
console.error(`${PREFIX} Target element not found for selector: ${selector}`);
|
|
596
|
-
},
|
|
597
|
-
log(msg, ...args) {
|
|
598
|
-
console.log(`${PREFIX} ${msg}`, ...args);
|
|
599
|
-
},
|
|
600
|
-
logEvent(event) {
|
|
601
|
-
const level = eventLogConfig[event.name];
|
|
602
|
-
const message = formatEvent(event);
|
|
603
|
-
if (event.name === "chunk-error" || event.name === "lazy-retry-attempt" || event.name === "lazy-retry-exhausted") {
|
|
604
|
-
console[level](message, event.error);
|
|
605
|
-
} else {
|
|
606
|
-
console[level](message);
|
|
607
|
-
}
|
|
608
|
-
},
|
|
609
|
-
noBeaconEndpoint() {
|
|
610
|
-
console.warn(`${PREFIX} Report endpoint is not configured`);
|
|
611
|
-
},
|
|
612
|
-
noFallbackConfigured() {
|
|
613
|
-
console.error(`${PREFIX} No fallback UI configured`);
|
|
614
|
-
},
|
|
615
|
-
reloadAlreadyScheduled(error) {
|
|
616
|
-
console.log(`${PREFIX} Reload already scheduled, ignoring duplicate chunk error:`, error);
|
|
617
|
-
},
|
|
618
|
-
retryCycleStarting(retryId, fromAttempt) {
|
|
619
|
-
console.log(`${PREFIX} Retry cycle starting: retryId=${retryId}, fromAttempt=${fromAttempt}`);
|
|
620
|
-
},
|
|
621
|
-
retrySchedulingReload(retryId, attempt, delay) {
|
|
622
|
-
console.log(
|
|
623
|
-
`${PREFIX} Scheduling reload: retryId=${retryId}, attempt=${attempt}, delay=${delay}ms`
|
|
624
|
-
);
|
|
625
|
-
},
|
|
626
|
-
versionChangeDetected(oldVersion, latestVersion) {
|
|
627
|
-
console.warn(
|
|
628
|
-
`${PREFIX} New version available (${oldVersion ?? "unknown"} \u2192 ${latestVersion}). Please refresh to get the latest version.`
|
|
629
|
-
);
|
|
630
|
-
},
|
|
631
|
-
versionCheckAlreadyRunning() {
|
|
632
|
-
console.warn(`${PREFIX} Version check already running`);
|
|
633
|
-
},
|
|
634
|
-
versionCheckDisabled() {
|
|
635
|
-
console.warn(`${PREFIX} Version checking disabled: no version configured`);
|
|
636
|
-
},
|
|
637
|
-
versionCheckFailed(error) {
|
|
638
|
-
console.error(`${PREFIX} Version check failed`, error);
|
|
639
|
-
},
|
|
640
|
-
versionCheckHttpError(status) {
|
|
641
|
-
console.warn(`${PREFIX} Version check HTTP error: ${status}`);
|
|
642
|
-
},
|
|
643
|
-
versionCheckParseError() {
|
|
644
|
-
console.warn(`${PREFIX} Failed to parse version from HTML`);
|
|
645
|
-
},
|
|
646
|
-
versionCheckPaused() {
|
|
647
|
-
console.log(`${PREFIX} Version check paused (tab hidden)`);
|
|
648
|
-
},
|
|
649
|
-
versionCheckRequiresEndpoint() {
|
|
650
|
-
console.warn(`${PREFIX} JSON version check mode requires endpoint`);
|
|
651
|
-
},
|
|
652
|
-
versionCheckResumed() {
|
|
653
|
-
console.log(`${PREFIX} Version check resumed (tab visible)`);
|
|
654
|
-
},
|
|
655
|
-
versionCheckResumedImmediate() {
|
|
656
|
-
console.log(
|
|
657
|
-
`${PREFIX} Version check resumed with immediate check (tab visible, interval elapsed)`
|
|
658
|
-
);
|
|
659
|
-
},
|
|
660
|
-
versionCheckStarted(mode, interval, version) {
|
|
661
|
-
console.log(
|
|
662
|
-
`${PREFIX} Starting version check (mode: ${mode}, interval: ${interval}ms, current: ${version})`
|
|
663
|
-
);
|
|
664
|
-
},
|
|
665
|
-
versionCheckStopped() {
|
|
666
|
-
console.log(`${PREFIX} Version check stopped`);
|
|
667
|
-
},
|
|
668
|
-
warn(msg, ...args) {
|
|
669
|
-
console.warn(`${PREFIX} ${msg}`, ...args);
|
|
670
|
-
}
|
|
671
|
-
});
|
|
672
|
-
|
|
673
|
-
export {
|
|
674
|
-
isChunkError,
|
|
675
|
-
serializeError,
|
|
676
|
-
listenInternal,
|
|
677
|
-
createLogger
|
|
678
|
-
};
|
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
export declare const fetchRemoteVersion: (mode: "html" | "json") => Promise<null | string>;
|
|
2
|
-
export declare const startVersionCheck: () => void;
|
|
3
|
-
export declare const stopVersionCheck: () => void;
|
|
4
|
-
/** Reset internal state - exported for testing only */
|
|
5
|
-
export declare const _resetForTesting: () => void;
|
|
@@ -1,14 +0,0 @@
|
|
|
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 initializedKey: unique symbol;
|
|
5
|
-
export declare const loggerWindowKey: unique symbol;
|
|
6
|
-
export declare const RETRY_ID_PARAM = "spaGuardRetryId";
|
|
7
|
-
export declare const RETRY_ATTEMPT_PARAM = "spaGuardRetryAttempt";
|
|
8
|
-
export declare const CACHE_BUST_PARAM = "spaGuardCacheBust";
|
|
9
|
-
export declare const versionCheckStateWindowKey: unique symbol;
|
|
10
|
-
export declare const inMemoryLastReloadKey: unique symbol;
|
|
11
|
-
export declare const staticAssetRecoveryKey: unique symbol;
|
|
12
|
-
export declare const debugSyncErrorEventType = "spa-guard:debug-sync-error";
|
|
13
|
-
export declare const spinnerStateWindowKey: unique symbol;
|
|
14
|
-
export declare const fallbackModeKey: unique symbol;
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import type { BeaconSchema } from "../../schema";
|
|
2
|
-
export declare class BeaconError extends Error {
|
|
3
|
-
readonly appName: string | undefined;
|
|
4
|
-
readonly errorMessage: string | undefined;
|
|
5
|
-
readonly eventMessage: string | undefined;
|
|
6
|
-
readonly eventName: string | undefined;
|
|
7
|
-
readonly retryAttempt: number | undefined;
|
|
8
|
-
readonly retryId: string | undefined;
|
|
9
|
-
readonly serialized: string | undefined;
|
|
10
|
-
constructor(beacon: BeaconSchema);
|
|
11
|
-
toJSON(): Record<string, unknown>;
|
|
12
|
-
}
|