@ovineko/spa-guard 0.0.1-alpha-30 → 0.0.2-alpha-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/README.md +59 -4
- package/dist/_internal.js +9 -9
- package/dist/{chunk-DINLBER6.js → chunk-4K3AQHLC.js} +174 -17
- package/dist/{chunk-EFWD2I2Y.js → chunk-IZAXNDHZ.js} +1 -1
- package/dist/{chunk-XRBUBTPZ.js → chunk-LIKSIU75.js} +51 -8
- package/dist/{chunk-A5HF6LY6.js → chunk-ORYUDYHU.js} +1 -1
- package/dist/{chunk-6TP2S7L6.js → chunk-T42DLOQP.js} +1 -1
- package/dist/common/fallbackRendering.d.ts +11 -1
- package/dist/common/index.d.ts +2 -0
- package/dist/common/index.js +10 -4
- package/dist/common/logger.d.ts +0 -3
- package/dist/common/retryOrchestrator.d.ts +2 -0
- package/dist/i18n/index.js +37 -37
- package/dist/runtime/debug/index.js +3 -3
- package/dist/runtime/index.js +111 -7
- package/dist/runtime/recommendedSetup.d.ts +24 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -22,6 +22,36 @@ const cleanup = recommendedSetup();
|
|
|
22
22
|
// optionally call cleanup() to stop background checks
|
|
23
23
|
```
|
|
24
24
|
|
|
25
|
+
`recommendedSetup` is idempotent. Repeated calls return the same cleanup function and do not re-run setup side effects.
|
|
26
|
+
|
|
27
|
+
By default, `recommendedSetup` uses `healthyBoot: "auto"`:
|
|
28
|
+
|
|
29
|
+
- if retry params exist in the URL, it waits a dynamic grace period and calls `markRetryHealthyBoot()` only when the orchestrator phase is still `idle`.
|
|
30
|
+
- if no retry params exist, it does nothing.
|
|
31
|
+
|
|
32
|
+
Auto grace period formula:
|
|
33
|
+
|
|
34
|
+
- `max(5000, max(reloadDelays)+1000, sum(lazyRetry.retryDelays)+1000)`
|
|
35
|
+
|
|
36
|
+
If you want strict control, switch to manual healthy-boot mode and call `markRetryHealthyBoot()` yourself.
|
|
37
|
+
|
|
38
|
+
```ts
|
|
39
|
+
import { markRetryHealthyBoot } from "@ovineko/spa-guard";
|
|
40
|
+
import { recommendedSetup } from "@ovineko/spa-guard/runtime";
|
|
41
|
+
|
|
42
|
+
recommendedSetup();
|
|
43
|
+
|
|
44
|
+
await Promise.all([import("./routes/Home"), import("./routes/Checkout")]);
|
|
45
|
+
|
|
46
|
+
markRetryHealthyBoot();
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
Disable auto healthy boot:
|
|
50
|
+
|
|
51
|
+
```ts
|
|
52
|
+
recommendedSetup({ healthyBoot: "manual" });
|
|
53
|
+
```
|
|
54
|
+
|
|
25
55
|
Disable version checking:
|
|
26
56
|
|
|
27
57
|
```ts
|
|
@@ -47,7 +77,7 @@ When a recoverable error occurs (chunk load error, unhandled rejection, `vite:pr
|
|
|
47
77
|
1. Event listener classifies the event and calls `triggerRetry({ source, error })`.
|
|
48
78
|
2. Orchestrator checks phase — if already `scheduled` or `fallback`, returns immediately without scheduling another reload.
|
|
49
79
|
3. On first trigger: reads `RETRY_ATTEMPT_PARAM` from URL to restore attempt count after a reload.
|
|
50
|
-
4. If attempts remain: increments attempt, sets a timer for `reloadDelays[currentAttempt]`, encodes `retryId` and attempt count into the reload URL, then navigates.
|
|
80
|
+
4. If attempts remain: increments attempt, calls `showLoadingUI(nextAttempt)` to render the loading UI immediately (before the timer fires), sets a timer for `reloadDelays[currentAttempt]`, encodes `retryId` and attempt count into the reload URL, then navigates. Requires `options.html.loading.content` to be configured; if absent, `showLoadingUI` returns silently and the retry still proceeds.
|
|
51
81
|
5. If attempts are exhausted: transitions to `fallback`, calls `setFallbackMode()`, sends a beacon, and renders fallback UI.
|
|
52
82
|
|
|
53
83
|
### URL params
|
|
@@ -58,13 +88,37 @@ The orchestrator serializes state into URL params for cross-reload continuity:
|
|
|
58
88
|
- `RETRY_ID_PARAM` — unique ID for this retry session
|
|
59
89
|
- `CACHE_BUST_PARAM` — timestamp for cache busting (set when `cacheBust: true` is passed, e.g. for static asset errors)
|
|
60
90
|
|
|
91
|
+
### Loading UI during retry delay
|
|
92
|
+
|
|
93
|
+
When `options.html.loading.content` is configured, `showLoadingUI(attempt)` is called before the reload timer fires. It injects the loading HTML into the target element (selector from `options.html.fallback.selector`, defaulting to `body`), reveals the `data-spa-guard-section="retrying"` element, fills attempt numbers into `[data-spa-guard-content="attempt"]` elements, applies i18n via `applyI18n`/`getI18n`, and optionally hides or replaces the spinner based on `options.html.spinner`. If loading content is not configured or the target element is not found, `showLoadingUI` returns silently — the retry still proceeds normally.
|
|
94
|
+
|
|
95
|
+
### Unhandledrejection serialization
|
|
96
|
+
|
|
97
|
+
`serializeError` handles `PromiseRejectionEvent` with strict redaction guardrails. For HTTP-like errors it extracts only safe metadata: `status`, `statusText`, `url`, `method`, `response.type`, and `X-Request-ID` from response headers when present. Response body, request/response payload, and the full headers object are **never** included in serialized output. For request wrappers (`reason.request` / `reason.config`) only `method`, `url`, and `baseURL` are extracted. Deep object traversal is bounded by `MAX_DEPTH=4`, `MAX_KEYS=20`, and `MAX_STRING_LEN=500` to prevent oversized beacons. Circular references are handled via a `WeakSet` visited tracker. The output also includes `isTrusted`, `timeStamp` from the event, and runtime context (`pageUrl`, `constructorName`).
|
|
98
|
+
|
|
61
99
|
### Retry reset
|
|
62
100
|
|
|
63
101
|
If enough time has passed since the last reload (configurable via `minTimeBetweenResets`, default 5000 ms), the orchestrator resets the attempt counter and starts a fresh retry cycle instead of continuing to fallback. This prevents stale URL params from triggering fallback on a clean page load.
|
|
64
102
|
|
|
65
103
|
### Healthy boot
|
|
66
104
|
|
|
67
|
-
After a successful app boot following a retry reload,
|
|
105
|
+
After a successful app boot following a retry reload, `markRetryHealthyBoot()` clears retry URL params, cancels any pending timer, and resets orchestrator state.
|
|
106
|
+
|
|
107
|
+
Default behavior in `recommendedSetup`: auto healthy-boot after a grace period (`healthyBoot: "auto"`).
|
|
108
|
+
Manual override: set `healthyBoot: "manual"` and call `markRetryHealthyBoot()` yourself once critical boot is confirmed.
|
|
109
|
+
|
|
110
|
+
### Avoid false retry loops from app errors
|
|
111
|
+
|
|
112
|
+
By default, regular `unhandledrejection` events also trigger `triggerRetry()` (`handleUnhandledRejections.retry: true`). If your app has non-chunk unhandled rejections, this can look like retry looping even though chunks are healthy. In that case, disable reload-on-unhandled-rejection:
|
|
113
|
+
|
|
114
|
+
```ts
|
|
115
|
+
window.__SPA_GUARD_OPTIONS__ = {
|
|
116
|
+
handleUnhandledRejections: {
|
|
117
|
+
retry: false,
|
|
118
|
+
sendBeacon: true,
|
|
119
|
+
},
|
|
120
|
+
};
|
|
121
|
+
```
|
|
68
122
|
|
|
69
123
|
### Static asset burst coalescing
|
|
70
124
|
|
|
@@ -100,8 +154,9 @@ Only `retryOrchestrator.ts` may schedule reloads, advance retry state, or transi
|
|
|
100
154
|
|
|
101
155
|
### `@ovineko/spa-guard/runtime`
|
|
102
156
|
|
|
103
|
-
- `recommendedSetup(options?)` — enable recommended runtime features; returns cleanup function
|
|
104
|
-
- `RecommendedSetupOptions` — `{ versionCheck?: boolean }`
|
|
157
|
+
- `recommendedSetup(options?)` — enable recommended runtime features; idempotent and returns cleanup function
|
|
158
|
+
- `RecommendedSetupOptions` — `{ versionCheck?: boolean; healthyBoot?: "auto" | "manual" | "off" | false | { mode?: "auto"; graceMs?: number } }`
|
|
159
|
+
- `healthyBoot.graceMs` acts as a lower bound override for auto mode (`max(computedGraceMs, graceMs)`)
|
|
105
160
|
- `startVersionCheck` / `stopVersionCheck` — manual version check control
|
|
106
161
|
- `getState` / `subscribeToState` — runtime state access
|
|
107
162
|
- `SpaGuardState` — state type
|
package/dist/_internal.js
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
import {
|
|
2
|
-
SPINNER_ID,
|
|
3
|
-
defaultSpinnerSvg,
|
|
4
|
-
extractVersionFromHtml,
|
|
5
|
-
sanitizeCssValue
|
|
6
|
-
} from "./chunk-6TP2S7L6.js";
|
|
7
1
|
import {
|
|
8
2
|
createLogger,
|
|
9
3
|
isChunkError,
|
|
10
4
|
listenInternal,
|
|
11
5
|
serializeError
|
|
12
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-4K3AQHLC.js";
|
|
7
|
+
import {
|
|
8
|
+
SPINNER_ID,
|
|
9
|
+
defaultSpinnerSvg,
|
|
10
|
+
extractVersionFromHtml,
|
|
11
|
+
sanitizeCssValue
|
|
12
|
+
} from "./chunk-T42DLOQP.js";
|
|
13
13
|
import {
|
|
14
14
|
dispatchAsyncRuntimeError,
|
|
15
15
|
dispatchChunkLoadError,
|
|
@@ -18,7 +18,7 @@ import {
|
|
|
18
18
|
dispatchNetworkTimeout,
|
|
19
19
|
dispatchSyncRuntimeError,
|
|
20
20
|
dispatchUnhandledRejection
|
|
21
|
-
} from "./chunk-
|
|
21
|
+
} from "./chunk-ORYUDYHU.js";
|
|
22
22
|
import {
|
|
23
23
|
applyI18n,
|
|
24
24
|
debugSyncErrorEventType,
|
|
@@ -40,7 +40,7 @@ import {
|
|
|
40
40
|
shouldIgnoreMessages,
|
|
41
41
|
subscribe,
|
|
42
42
|
triggerRetry
|
|
43
|
-
} from "./chunk-
|
|
43
|
+
} from "./chunk-LIKSIU75.js";
|
|
44
44
|
import "./chunk-MLKGABMK.js";
|
|
45
45
|
|
|
46
46
|
// src/common/handleErrorWithSpaGuard.ts
|
|
@@ -11,7 +11,7 @@ import {
|
|
|
11
11
|
shouldIgnoreMessages,
|
|
12
12
|
staticAssetRecoveryKey,
|
|
13
13
|
triggerRetry
|
|
14
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-LIKSIU75.js";
|
|
15
15
|
|
|
16
16
|
// src/common/isChunkError.ts
|
|
17
17
|
var isChunkError = (error) => {
|
|
@@ -58,6 +58,10 @@ var serializeError = (error) => {
|
|
|
58
58
|
});
|
|
59
59
|
}
|
|
60
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;
|
|
61
65
|
var serializeErrorInternal = (error) => {
|
|
62
66
|
if (error === null || error === void 0) {
|
|
63
67
|
return { type: "null", value: error };
|
|
@@ -69,14 +73,21 @@ var serializeErrorInternal = (error) => {
|
|
|
69
73
|
return {
|
|
70
74
|
message: error.message,
|
|
71
75
|
name: error.name,
|
|
72
|
-
stack: error.stack,
|
|
76
|
+
stack: error.stack ? truncate(error.stack) : void 0,
|
|
73
77
|
type: "Error",
|
|
74
78
|
...extractErrorProperties(error)
|
|
75
79
|
};
|
|
76
80
|
}
|
|
77
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;
|
|
78
85
|
return {
|
|
79
|
-
|
|
86
|
+
constructorName: reason?.constructor?.name,
|
|
87
|
+
isTrusted: evt.isTrusted,
|
|
88
|
+
pageUrl,
|
|
89
|
+
reason: serializeRejectionReason(reason, /* @__PURE__ */ new WeakSet(), 0),
|
|
90
|
+
timeStamp: evt.timeStamp,
|
|
80
91
|
type: "PromiseRejectionEvent"
|
|
81
92
|
};
|
|
82
93
|
}
|
|
@@ -117,14 +128,158 @@ var serializeErrorInternal = (error) => {
|
|
|
117
128
|
value: extractOwnProperties(error)
|
|
118
129
|
};
|
|
119
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
|
+
if (reason instanceof Error) {
|
|
161
|
+
return serializeSafeError(reason, visited, depth);
|
|
162
|
+
}
|
|
163
|
+
const reasonObj = reason;
|
|
164
|
+
if (reasonObj.response != null) {
|
|
165
|
+
const response = reasonObj.response;
|
|
166
|
+
const result = {
|
|
167
|
+
type: "HttpError"
|
|
168
|
+
};
|
|
169
|
+
if (response.status !== void 0) {
|
|
170
|
+
result.status = response.status;
|
|
171
|
+
}
|
|
172
|
+
if (response.statusText !== void 0) {
|
|
173
|
+
result.statusText = typeof response.statusText === "string" ? truncate(response.statusText) : response.statusText;
|
|
174
|
+
}
|
|
175
|
+
if (response.url !== void 0) {
|
|
176
|
+
result.url = typeof response.url === "string" ? truncate(response.url) : response.url;
|
|
177
|
+
}
|
|
178
|
+
if (response.method !== void 0) {
|
|
179
|
+
result.method = response.method;
|
|
180
|
+
}
|
|
181
|
+
if (response.type !== void 0) {
|
|
182
|
+
result.responseType = response.type;
|
|
183
|
+
}
|
|
184
|
+
try {
|
|
185
|
+
const headers = response.headers;
|
|
186
|
+
if (headers) {
|
|
187
|
+
let xRequestId;
|
|
188
|
+
if (typeof headers.get === "function") {
|
|
189
|
+
xRequestId = headers.get("X-Request-ID") ?? headers.get("x-request-id");
|
|
190
|
+
} else if (typeof headers === "object") {
|
|
191
|
+
xRequestId = headers["X-Request-ID"] ?? headers["x-request-id"];
|
|
192
|
+
}
|
|
193
|
+
if (xRequestId) {
|
|
194
|
+
result.xRequestId = truncate(String(xRequestId));
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
} catch {
|
|
198
|
+
}
|
|
199
|
+
const reqSource = reasonObj.config ?? reasonObj.request;
|
|
200
|
+
if (reqSource != null) {
|
|
201
|
+
const req = {};
|
|
202
|
+
if (reqSource.method !== void 0) {
|
|
203
|
+
req.method = reqSource.method;
|
|
204
|
+
}
|
|
205
|
+
if (reqSource.url !== void 0) {
|
|
206
|
+
req.url = typeof reqSource.url === "string" ? truncate(reqSource.url) : reqSource.url;
|
|
207
|
+
}
|
|
208
|
+
if (reqSource.baseURL !== void 0) {
|
|
209
|
+
req.baseURL = typeof reqSource.baseURL === "string" ? truncate(reqSource.baseURL) : reqSource.baseURL;
|
|
210
|
+
}
|
|
211
|
+
result.request = req;
|
|
212
|
+
}
|
|
213
|
+
return result;
|
|
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
|
+
};
|
|
120
265
|
var extractErrorProperties = (error) => {
|
|
121
266
|
const props = {};
|
|
267
|
+
let keyCount = 0;
|
|
122
268
|
for (const key of Object.getOwnPropertyNames(error)) {
|
|
269
|
+
if (keyCount >= MAX_KEYS) {
|
|
270
|
+
break;
|
|
271
|
+
}
|
|
123
272
|
if (!["message", "name", "stack"].includes(key)) {
|
|
124
273
|
try {
|
|
125
|
-
|
|
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
|
+
}
|
|
126
280
|
} catch {
|
|
127
281
|
}
|
|
282
|
+
keyCount++;
|
|
128
283
|
}
|
|
129
284
|
}
|
|
130
285
|
return props;
|
|
@@ -146,12 +301,21 @@ var extractEventTarget = (target) => {
|
|
|
146
301
|
};
|
|
147
302
|
var extractOwnProperties = (obj) => {
|
|
148
303
|
const props = {};
|
|
304
|
+
let keyCount = 0;
|
|
149
305
|
for (const key of Object.keys(obj)) {
|
|
306
|
+
if (keyCount >= MAX_KEYS) {
|
|
307
|
+
break;
|
|
308
|
+
}
|
|
150
309
|
try {
|
|
151
310
|
const value = obj[key];
|
|
152
|
-
|
|
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
|
+
}
|
|
153
316
|
} catch {
|
|
154
317
|
}
|
|
318
|
+
keyCount++;
|
|
155
319
|
}
|
|
156
320
|
return props;
|
|
157
321
|
};
|
|
@@ -247,6 +411,9 @@ var handleStaticAssetFailure = (url) => {
|
|
|
247
411
|
|
|
248
412
|
// src/common/listen/internal.ts
|
|
249
413
|
var listenInternal = (serializeError2, logger) => {
|
|
414
|
+
if (globalThis.window === void 0) {
|
|
415
|
+
return;
|
|
416
|
+
}
|
|
250
417
|
if (isInitialized()) {
|
|
251
418
|
return;
|
|
252
419
|
}
|
|
@@ -254,7 +421,6 @@ var listenInternal = (serializeError2, logger) => {
|
|
|
254
421
|
setLogger(logger);
|
|
255
422
|
}
|
|
256
423
|
markInitialized();
|
|
257
|
-
const options = getOptions();
|
|
258
424
|
const wa = globalThis.window.addEventListener.bind(globalThis.window);
|
|
259
425
|
wa(
|
|
260
426
|
"error",
|
|
@@ -266,7 +432,7 @@ var listenInternal = (serializeError2, logger) => {
|
|
|
266
432
|
}
|
|
267
433
|
event.preventDefault();
|
|
268
434
|
emitEvent({ name: "static-asset-load-failed", url: assetUrl });
|
|
269
|
-
if (
|
|
435
|
+
if (getOptions().staticAssets?.autoRecover !== false) {
|
|
270
436
|
handleStaticAssetFailure(assetUrl);
|
|
271
437
|
}
|
|
272
438
|
return;
|
|
@@ -311,7 +477,7 @@ var listenInternal = (serializeError2, logger) => {
|
|
|
311
477
|
triggerRetry({ error: event.reason, source: "force-retry" });
|
|
312
478
|
return;
|
|
313
479
|
}
|
|
314
|
-
const rejectionConfig =
|
|
480
|
+
const rejectionConfig = getOptions().handleUnhandledRejections;
|
|
315
481
|
if (rejectionConfig?.sendBeacon !== false) {
|
|
316
482
|
const serialized = serializeError2(event);
|
|
317
483
|
sendBeacon({
|
|
@@ -413,9 +579,6 @@ var createLogger = () => ({
|
|
|
413
579
|
capturedError(type, ...args) {
|
|
414
580
|
console.error(`${PREFIX} ${type}:capture:`, ...args);
|
|
415
581
|
},
|
|
416
|
-
clearingRetryState() {
|
|
417
|
-
console.log(`${PREFIX} Clearing retry state from URL to allow clean reload attempt`);
|
|
418
|
-
},
|
|
419
582
|
error(msg, ...args) {
|
|
420
583
|
console.error(`${PREFIX} ${msg}`, ...args);
|
|
421
584
|
},
|
|
@@ -455,17 +618,11 @@ var createLogger = () => ({
|
|
|
455
618
|
retryCycleStarting(retryId, fromAttempt) {
|
|
456
619
|
console.log(`${PREFIX} Retry cycle starting: retryId=${retryId}, fromAttempt=${fromAttempt}`);
|
|
457
620
|
},
|
|
458
|
-
retryLimitExceeded(attempt, max) {
|
|
459
|
-
console.log(`${PREFIX} Retry limit exceeded (${attempt}/${max}), marking as fallback shown`);
|
|
460
|
-
},
|
|
461
621
|
retrySchedulingReload(retryId, attempt, delay) {
|
|
462
622
|
console.log(
|
|
463
623
|
`${PREFIX} Scheduling reload: retryId=${retryId}, attempt=${attempt}, delay=${delay}ms`
|
|
464
624
|
);
|
|
465
625
|
},
|
|
466
|
-
updatedRetryAttempt(attempt) {
|
|
467
|
-
console.log(`${PREFIX} Updated retry attempt to ${attempt} in URL for fallback UI`);
|
|
468
|
-
},
|
|
469
626
|
versionChangeDetected(oldVersion, latestVersion) {
|
|
470
627
|
console.warn(
|
|
471
628
|
`${PREFIX} New version available (${oldVersion ?? "unknown"} \u2192 ${latestVersion}). Please refresh to get the latest version.`
|
|
@@ -327,7 +327,48 @@ var getRetryInfoForBeacon = () => {
|
|
|
327
327
|
};
|
|
328
328
|
|
|
329
329
|
// src/common/fallbackRendering.ts
|
|
330
|
-
var
|
|
330
|
+
var showLoadingUI = (attempt) => {
|
|
331
|
+
const options = getOptions();
|
|
332
|
+
const loadingHtml = options.html?.loading?.content;
|
|
333
|
+
if (!loadingHtml) {
|
|
334
|
+
return;
|
|
335
|
+
}
|
|
336
|
+
const selector = options.html?.fallback?.selector ?? "body";
|
|
337
|
+
try {
|
|
338
|
+
const targetElement = document.querySelector(selector);
|
|
339
|
+
if (!targetElement) {
|
|
340
|
+
return;
|
|
341
|
+
}
|
|
342
|
+
const container = document.createElement("div");
|
|
343
|
+
container.innerHTML = loadingHtml;
|
|
344
|
+
const t = getI18n();
|
|
345
|
+
if (t) {
|
|
346
|
+
applyI18n(container, t);
|
|
347
|
+
}
|
|
348
|
+
targetElement.innerHTML = container.innerHTML;
|
|
349
|
+
const retrySection = targetElement.querySelector('[data-spa-guard-section="retrying"]');
|
|
350
|
+
if (retrySection) {
|
|
351
|
+
const retrySectionEl = retrySection;
|
|
352
|
+
retrySectionEl.style.display = "";
|
|
353
|
+
retrySectionEl.style.visibility = "visible";
|
|
354
|
+
}
|
|
355
|
+
const attemptElements = targetElement.querySelectorAll('[data-spa-guard-content="attempt"]');
|
|
356
|
+
for (const el of attemptElements) {
|
|
357
|
+
el.textContent = String(attempt);
|
|
358
|
+
}
|
|
359
|
+
const spinnerEl = targetElement.querySelector("[data-spa-guard-spinner]");
|
|
360
|
+
if (spinnerEl) {
|
|
361
|
+
const spinnerOptions = options.html?.spinner;
|
|
362
|
+
if (spinnerOptions?.disabled) {
|
|
363
|
+
spinnerEl.style.display = "none";
|
|
364
|
+
} else if (spinnerOptions?.content) {
|
|
365
|
+
spinnerEl.innerHTML = spinnerOptions.content;
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
} catch {
|
|
369
|
+
}
|
|
370
|
+
};
|
|
371
|
+
var showFallbackUI = (override) => {
|
|
331
372
|
const options = getOptions();
|
|
332
373
|
const fallbackHtml = options.html?.fallback?.content;
|
|
333
374
|
const selector = options.html?.fallback?.selector ?? "body";
|
|
@@ -354,11 +395,11 @@ var showFallbackUI = () => {
|
|
|
354
395
|
if (reloadBtn) {
|
|
355
396
|
reloadBtn.addEventListener("click", () => globalThis.window.location.reload());
|
|
356
397
|
}
|
|
357
|
-
const
|
|
358
|
-
if (
|
|
398
|
+
const retryId = override?.retryId ?? getRetryStateFromUrl()?.retryId;
|
|
399
|
+
if (retryId) {
|
|
359
400
|
const retryIdElements = document.getElementsByClassName("spa-guard-retry-id");
|
|
360
401
|
for (const element of retryIdElements) {
|
|
361
|
-
element.textContent =
|
|
402
|
+
element.textContent = retryId;
|
|
362
403
|
}
|
|
363
404
|
}
|
|
364
405
|
emitEvent({
|
|
@@ -703,7 +744,8 @@ var triggerRetry = (input = {}) => {
|
|
|
703
744
|
});
|
|
704
745
|
setState({ attempt: currentAttempt, phase: "fallback", retryId });
|
|
705
746
|
setFallbackMode();
|
|
706
|
-
|
|
747
|
+
clearRetryFromUrl();
|
|
748
|
+
showFallbackUI({ retryId });
|
|
707
749
|
return { status: "fallback" };
|
|
708
750
|
}
|
|
709
751
|
const nextAttempt = currentAttempt + 1;
|
|
@@ -720,6 +762,7 @@ var triggerRetry = (input = {}) => {
|
|
|
720
762
|
);
|
|
721
763
|
getLogger()?.retrySchedulingReload(retryId, nextAttempt, delay);
|
|
722
764
|
setState({ attempt: nextAttempt, retryId });
|
|
765
|
+
showLoadingUI(nextAttempt);
|
|
723
766
|
const timer = setTimeout(() => {
|
|
724
767
|
try {
|
|
725
768
|
if (useRetryId && enableRetryReset) {
|
|
@@ -729,7 +772,7 @@ var triggerRetry = (input = {}) => {
|
|
|
729
772
|
globalThis.window.location.href = reloadUrl;
|
|
730
773
|
} catch (navError) {
|
|
731
774
|
getLogger()?.error("triggerRetry navigation failed", navError);
|
|
732
|
-
setState({ phase: "idle" });
|
|
775
|
+
setState({ phase: "idle", timer: null });
|
|
733
776
|
}
|
|
734
777
|
}, delay);
|
|
735
778
|
setState({ timer });
|
|
@@ -737,7 +780,7 @@ var triggerRetry = (input = {}) => {
|
|
|
737
780
|
} catch (error) {
|
|
738
781
|
getLogger()?.error("triggerRetry internal error", error);
|
|
739
782
|
setState({ lastSource: void 0, lastTriggerTime: void 0, phase: "idle" });
|
|
740
|
-
return {
|
|
783
|
+
return { status: "internal-error" };
|
|
741
784
|
}
|
|
742
785
|
};
|
|
743
786
|
var markRetryHealthyBoot = () => {
|
|
@@ -768,7 +811,7 @@ var setFallbackStateForDebug = () => {
|
|
|
768
811
|
}
|
|
769
812
|
setState({ phase: "fallback", timer: null });
|
|
770
813
|
setFallbackMode();
|
|
771
|
-
showFallbackUI();
|
|
814
|
+
showFallbackUI({ retryId: state.retryId ?? void 0 });
|
|
772
815
|
};
|
|
773
816
|
var resetRetryOrchestratorForTests = () => {
|
|
774
817
|
const state = getState();
|
|
@@ -1,3 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Renders the loading UI into the DOM during a retry delay before reload.
|
|
3
|
+
*
|
|
4
|
+
* Fail-safe: if loading content is not configured or the target element is not
|
|
5
|
+
* found, returns silently with no log, no event, and no side effects.
|
|
6
|
+
* All DOM access is wrapped in try/catch.
|
|
7
|
+
*/
|
|
8
|
+
export declare const showLoadingUI: (attempt: number) => void;
|
|
1
9
|
/**
|
|
2
10
|
* Renders the fallback UI into the DOM.
|
|
3
11
|
*
|
|
@@ -10,4 +18,6 @@
|
|
|
10
18
|
* Fails safely: if fallback HTML is not configured or the target element
|
|
11
19
|
* is not found, logs a warning and returns without side effects or errors.
|
|
12
20
|
*/
|
|
13
|
-
export declare const showFallbackUI: (
|
|
21
|
+
export declare const showFallbackUI: (override?: {
|
|
22
|
+
retryId?: string;
|
|
23
|
+
}) => void;
|
package/dist/common/index.d.ts
CHANGED
|
@@ -5,3 +5,5 @@ export { disableDefaultRetry, enableDefaultRetry, isDefaultRetryEnabled } from "
|
|
|
5
5
|
export { isInFallbackMode, resetFallbackMode } from "./fallbackState";
|
|
6
6
|
export { listen } from "./listen";
|
|
7
7
|
export * as options from "./options";
|
|
8
|
+
export { getRetrySnapshot, markRetryHealthyBoot, triggerRetry } from "./retryOrchestrator";
|
|
9
|
+
export type { RetryPhase, RetrySnapshot, TriggerInput, TriggerResult } from "./retryOrchestrator";
|
package/dist/common/index.js
CHANGED
|
@@ -2,18 +2,21 @@ import {
|
|
|
2
2
|
createLogger,
|
|
3
3
|
listenInternal,
|
|
4
4
|
serializeError
|
|
5
|
-
} from "../chunk-
|
|
5
|
+
} from "../chunk-4K3AQHLC.js";
|
|
6
6
|
import {
|
|
7
7
|
ForceRetryError,
|
|
8
8
|
disableDefaultRetry,
|
|
9
9
|
emitEvent,
|
|
10
10
|
enableDefaultRetry,
|
|
11
|
+
getRetrySnapshot,
|
|
11
12
|
isDefaultRetryEnabled,
|
|
12
13
|
isInFallbackMode,
|
|
14
|
+
markRetryHealthyBoot,
|
|
13
15
|
options_exports,
|
|
14
16
|
resetFallbackMode,
|
|
15
|
-
subscribe
|
|
16
|
-
|
|
17
|
+
subscribe,
|
|
18
|
+
triggerRetry
|
|
19
|
+
} from "../chunk-LIKSIU75.js";
|
|
17
20
|
import {
|
|
18
21
|
__export
|
|
19
22
|
} from "../chunk-MLKGABMK.js";
|
|
@@ -73,9 +76,12 @@ export {
|
|
|
73
76
|
disableDefaultRetry,
|
|
74
77
|
enableDefaultRetry,
|
|
75
78
|
events_exports as events,
|
|
79
|
+
getRetrySnapshot,
|
|
76
80
|
isDefaultRetryEnabled,
|
|
77
81
|
isInFallbackMode,
|
|
78
82
|
listen,
|
|
83
|
+
markRetryHealthyBoot,
|
|
79
84
|
options_exports as options,
|
|
80
|
-
resetFallbackMode
|
|
85
|
+
resetFallbackMode,
|
|
86
|
+
triggerRetry
|
|
81
87
|
};
|
package/dist/common/logger.d.ts
CHANGED
|
@@ -2,7 +2,6 @@ import type { SPAGuardEvent } from "./events/types";
|
|
|
2
2
|
export interface Logger {
|
|
3
3
|
beaconSendFailed(error: unknown): void;
|
|
4
4
|
capturedError(type: string, ...args: unknown[]): void;
|
|
5
|
-
clearingRetryState(): void;
|
|
6
5
|
error(msg: string, ...args: unknown[]): void;
|
|
7
6
|
fallbackAlreadyShown(error: unknown): void;
|
|
8
7
|
fallbackInjectFailed(error: unknown): void;
|
|
@@ -13,9 +12,7 @@ export interface Logger {
|
|
|
13
12
|
noFallbackConfigured(): void;
|
|
14
13
|
reloadAlreadyScheduled(error: unknown): void;
|
|
15
14
|
retryCycleStarting(retryId: string, fromAttempt: number): void;
|
|
16
|
-
retryLimitExceeded(attempt: number, max: number): void;
|
|
17
15
|
retrySchedulingReload(retryId: string, attempt: number, delay: number): void;
|
|
18
|
-
updatedRetryAttempt(attempt: number): void;
|
|
19
16
|
versionChangeDetected(oldVersion: null | string, latestVersion: string): void;
|
|
20
17
|
versionCheckAlreadyRunning(): void;
|
|
21
18
|
versionCheckDisabled(): void;
|
package/dist/i18n/index.js
CHANGED
|
@@ -5,7 +5,7 @@ var translations = {
|
|
|
5
5
|
ar: {
|
|
6
6
|
heading: "\u062D\u062F\u062B \u062E\u0637\u0623 \u0645\u0627",
|
|
7
7
|
loading: "...\u062C\u0627\u0631\u064D \u0627\u0644\u062A\u062D\u0645\u064A\u0644",
|
|
8
|
-
message: "\u064A\u0631\u062C\u0649 \u062A\u062D\u062F\u064A\u062B \u0627\u0644\u0635\u0641\u062D\u0629 \u0644\u0644\u0645\u062A\u0627\u0628\u0639\u0629
|
|
8
|
+
message: "\u064A\u0631\u062C\u0649 \u062A\u062D\u062F\u064A\u062B \u0627\u0644\u0635\u0641\u062D\u0629 \u0644\u0644\u0645\u062A\u0627\u0628\u0639\u0629",
|
|
9
9
|
reload: "\u0625\u0639\u0627\u062F\u0629 \u062A\u062D\u0645\u064A\u0644",
|
|
10
10
|
retrying: "\u0645\u062D\u0627\u0648\u0644\u0629 \u0625\u0639\u0627\u062F\u0629",
|
|
11
11
|
rtl: true,
|
|
@@ -14,7 +14,7 @@ var translations = {
|
|
|
14
14
|
az: {
|
|
15
15
|
heading: "N\u0259s\u0259 s\u0259hv getdi",
|
|
16
16
|
loading: "Y\xFCkl\u0259nir...",
|
|
17
|
-
message: "Davam etm\u0259k \xFC\xE7\xFCn s\u0259hif\u0259ni yenil\u0259yin
|
|
17
|
+
message: "Davam etm\u0259k \xFC\xE7\xFCn s\u0259hif\u0259ni yenil\u0259yin",
|
|
18
18
|
reload: "S\u0259hif\u0259ni yenid\u0259n y\xFCkl\u0259",
|
|
19
19
|
retrying: "Yenid\u0259n c\u0259hd",
|
|
20
20
|
tryAgain: "Yenid\u0259n c\u0259r\u0259b edin"
|
|
@@ -22,7 +22,7 @@ var translations = {
|
|
|
22
22
|
ca: {
|
|
23
23
|
heading: "Alguna cosa ha anat malament",
|
|
24
24
|
loading: "Carregant...",
|
|
25
|
-
message: "Si us plau, actualitzeu la p\xE0gina per continuar
|
|
25
|
+
message: "Si us plau, actualitzeu la p\xE0gina per continuar",
|
|
26
26
|
reload: "Recarrega la p\xE0gina",
|
|
27
27
|
retrying: "Intent de reintent",
|
|
28
28
|
tryAgain: "Torna-ho a provar"
|
|
@@ -30,7 +30,7 @@ var translations = {
|
|
|
30
30
|
cs: {
|
|
31
31
|
heading: "N\u011Bco se pokazilo",
|
|
32
32
|
loading: "Na\u010D\xEDt\xE1n\xED...",
|
|
33
|
-
message: "Obnovte str\xE1nku pros\xEDm pro pokra\u010Dov\xE1n\xED
|
|
33
|
+
message: "Obnovte str\xE1nku pros\xEDm pro pokra\u010Dov\xE1n\xED",
|
|
34
34
|
reload: "Znovu na\u010D\xEDst str\xE1nku",
|
|
35
35
|
retrying: "Pokus o opakov\xE1n\xED",
|
|
36
36
|
tryAgain: "Zkusit znovu"
|
|
@@ -38,7 +38,7 @@ var translations = {
|
|
|
38
38
|
da: {
|
|
39
39
|
heading: "Noget gik galt",
|
|
40
40
|
loading: "Indl\xE6ser...",
|
|
41
|
-
message: "Opdater venligst siden for at forts\xE6tte
|
|
41
|
+
message: "Opdater venligst siden for at forts\xE6tte",
|
|
42
42
|
reload: "Genindl\xE6s side",
|
|
43
43
|
retrying: "Fors\xF8g igen",
|
|
44
44
|
tryAgain: "Pr\xF8v igen"
|
|
@@ -46,7 +46,7 @@ var translations = {
|
|
|
46
46
|
de: {
|
|
47
47
|
heading: "Etwas ist schief gelaufen",
|
|
48
48
|
loading: "L\xE4dt...",
|
|
49
|
-
message: "Bitte aktualisieren Sie die Seite, um fortzufahren
|
|
49
|
+
message: "Bitte aktualisieren Sie die Seite, um fortzufahren",
|
|
50
50
|
reload: "Seite neu laden",
|
|
51
51
|
retrying: "Wiederholungsversuch",
|
|
52
52
|
tryAgain: "Erneut versuchen"
|
|
@@ -54,7 +54,7 @@ var translations = {
|
|
|
54
54
|
el: {
|
|
55
55
|
heading: "\u039A\u03AC\u03C4\u03B9 \u03C0\u03AE\u03B3\u03B5 \u03C3\u03C4\u03C1\u03B1\u03B2\u03AC",
|
|
56
56
|
loading: "\u03A6\u03CC\u03C1\u03C4\u03C9\u03C3\u03B7...",
|
|
57
|
-
message: "\u03A0\u03B1\u03C1\u03B1\u03BA\u03B1\u03BB\u03CE \u03B1\u03BD\u03B1\u03BD\u03B5\u03CE\u03C3\u03C4\u03B5 \u03C4\u03B7 \u03C3\u03B5\u03BB\u03AF\u03B4\u03B1 \u03B3\u03B9\u03B1 \u03BD\u03B1 \u03C3\u03C5\u03BD\u03B5\u03C7\u03AF\u03C3\u03B5\u03C4\u03B5
|
|
57
|
+
message: "\u03A0\u03B1\u03C1\u03B1\u03BA\u03B1\u03BB\u03CE \u03B1\u03BD\u03B1\u03BD\u03B5\u03CE\u03C3\u03C4\u03B5 \u03C4\u03B7 \u03C3\u03B5\u03BB\u03AF\u03B4\u03B1 \u03B3\u03B9\u03B1 \u03BD\u03B1 \u03C3\u03C5\u03BD\u03B5\u03C7\u03AF\u03C3\u03B5\u03C4\u03B5",
|
|
58
58
|
reload: "\u0395\u03C0\u03B1\u03BD\u03B1\u03C6\u03CC\u03C1\u03C4\u03C9\u03C3\u03B7 \u03C3\u03B5\u03BB\u03AF\u03B4\u03B1\u03C2",
|
|
59
59
|
retrying: "\u03A0\u03C1\u03BF\u03C3\u03C0\u03AC\u03B8\u03B5\u03B9\u03B1 \u03B5\u03C0\u03B1\u03BD\u03AC\u03BB\u03B7\u03C8\u03B7\u03C2",
|
|
60
60
|
tryAgain: "\u0394\u03BF\u03BA\u03B9\u03BC\u03AC\u03C3\u03C4\u03B5 \u03BE\u03B1\u03BD\u03AC"
|
|
@@ -62,7 +62,7 @@ var translations = {
|
|
|
62
62
|
en: {
|
|
63
63
|
heading: "Something went wrong",
|
|
64
64
|
loading: "Loading...",
|
|
65
|
-
message: "Please refresh the page to continue
|
|
65
|
+
message: "Please refresh the page to continue",
|
|
66
66
|
reload: "Reload page",
|
|
67
67
|
retrying: "Retry attempt",
|
|
68
68
|
tryAgain: "Try again"
|
|
@@ -70,7 +70,7 @@ var translations = {
|
|
|
70
70
|
es: {
|
|
71
71
|
heading: "Algo sali\xF3 mal",
|
|
72
72
|
loading: "Cargando...",
|
|
73
|
-
message: "Por favor, actualice la p\xE1gina para continuar
|
|
73
|
+
message: "Por favor, actualice la p\xE1gina para continuar",
|
|
74
74
|
reload: "Recargar p\xE1gina",
|
|
75
75
|
retrying: "Intento de reintento",
|
|
76
76
|
tryAgain: "Intentar de nuevo"
|
|
@@ -78,7 +78,7 @@ var translations = {
|
|
|
78
78
|
eu: {
|
|
79
79
|
heading: "Zerbait gaizki joan da",
|
|
80
80
|
loading: "Kargatzen...",
|
|
81
|
-
message: "Mesedez, freskatu orria jarraitzeko
|
|
81
|
+
message: "Mesedez, freskatu orria jarraitzeko",
|
|
82
82
|
reload: "Orria berritu",
|
|
83
83
|
retrying: "Saiakera berri",
|
|
84
84
|
tryAgain: "Saiatu berriro"
|
|
@@ -86,7 +86,7 @@ var translations = {
|
|
|
86
86
|
fa: {
|
|
87
87
|
heading: "\u0645\u0634\u06A9\u0644\u06CC \u067E\u06CC\u0634 \u0622\u0645\u062F",
|
|
88
88
|
loading: "\u062F\u0631 \u062D\u0627\u0644 \u0628\u0627\u0631\u06AF\u0630\u0627\u0631\u06CC...",
|
|
89
|
-
message: "\u0644\u0637\u0641\u0627\u064B \u0635\u0641\u062D\u0647 \u0631\u0627 \u0628\u0631\u0627\u06CC \u0627\u062F\u0627\u0645\u0647 \u062A\u0627\u0632\u0647 \u06A9\u0646\u06CC\u062F
|
|
89
|
+
message: "\u0644\u0637\u0641\u0627\u064B \u0635\u0641\u062D\u0647 \u0631\u0627 \u0628\u0631\u0627\u06CC \u0627\u062F\u0627\u0645\u0647 \u062A\u0627\u0632\u0647 \u06A9\u0646\u06CC\u062F",
|
|
90
90
|
reload: "\u0628\u0627\u0631\u06AF\u0630\u0627\u0631\u06CC \u0645\u062C\u062F\u062F",
|
|
91
91
|
retrying: "\u062A\u0644\u0627\u0634 \u062F\u0648\u0628\u0627\u0631\u0647",
|
|
92
92
|
rtl: true,
|
|
@@ -95,7 +95,7 @@ var translations = {
|
|
|
95
95
|
fi: {
|
|
96
96
|
heading: "Jokin meni pieleen",
|
|
97
97
|
loading: "Ladataan...",
|
|
98
|
-
message: "P\xE4ivit\xE4 sivu jatkaaksesi
|
|
98
|
+
message: "P\xE4ivit\xE4 sivu jatkaaksesi",
|
|
99
99
|
reload: "Lataa sivu uudelleen",
|
|
100
100
|
retrying: "Uudelleenyritys",
|
|
101
101
|
tryAgain: "Yrit\xE4 uudelleen"
|
|
@@ -103,7 +103,7 @@ var translations = {
|
|
|
103
103
|
fr: {
|
|
104
104
|
heading: "Quelque chose s'est mal pass\xE9",
|
|
105
105
|
loading: "Chargement...",
|
|
106
|
-
message: "Veuillez actualiser la page pour continuer
|
|
106
|
+
message: "Veuillez actualiser la page pour continuer",
|
|
107
107
|
reload: "Recharger la page",
|
|
108
108
|
retrying: "Tentative de nouvel essai",
|
|
109
109
|
tryAgain: "R\xE9essayer"
|
|
@@ -111,7 +111,7 @@ var translations = {
|
|
|
111
111
|
he: {
|
|
112
112
|
heading: "\u05DE\u05E9\u05D4\u05D5 \u05D4\u05E9\u05EA\u05D1\u05E9",
|
|
113
113
|
loading: "...\u05D8\u05D5\u05E2\u05DF",
|
|
114
|
-
message: "\u05D0\u05E0\u05D0 \u05E8\u05E2\u05E0\u05DF \u05D0\u05EA \u05D4\u05D3\u05E3 \u05DB\u05D3\u05D9 \u05DC\u05D4\u05DE\u05E9\u05D9\u05DA
|
|
114
|
+
message: "\u05D0\u05E0\u05D0 \u05E8\u05E2\u05E0\u05DF \u05D0\u05EA \u05D4\u05D3\u05E3 \u05DB\u05D3\u05D9 \u05DC\u05D4\u05DE\u05E9\u05D9\u05DA",
|
|
115
115
|
reload: "\u05D8\u05E2\u05DF \u05DE\u05D7\u05D3\u05E9",
|
|
116
116
|
retrying: "\u05E0\u05D9\u05E1\u05D9\u05D5\u05DF \u05D7\u05D5\u05D6\u05E8",
|
|
117
117
|
rtl: true,
|
|
@@ -120,7 +120,7 @@ var translations = {
|
|
|
120
120
|
hr: {
|
|
121
121
|
heading: "Ne\u0161to je po\u0161lo po zlu",
|
|
122
122
|
loading: "U\u010Ditavanje...",
|
|
123
|
-
message: "Molimo osvje\u017Eite stranicu da biste nastavili
|
|
123
|
+
message: "Molimo osvje\u017Eite stranicu da biste nastavili",
|
|
124
124
|
reload: "Ponovno u\u010Ditaj stranicu",
|
|
125
125
|
retrying: "Poku\u0161aj ponovnog poku\u0161aja",
|
|
126
126
|
tryAgain: "Poku\u0161aj ponovo"
|
|
@@ -128,7 +128,7 @@ var translations = {
|
|
|
128
128
|
hu: {
|
|
129
129
|
heading: "Valami hiba t\xF6rt\xE9nt",
|
|
130
130
|
loading: "Bet\xF6lt\xE9s...",
|
|
131
|
-
message: "K\xE9rj\xFCk, friss\xEDtse az oldalt a folytat\xE1shoz
|
|
131
|
+
message: "K\xE9rj\xFCk, friss\xEDtse az oldalt a folytat\xE1shoz",
|
|
132
132
|
reload: "Oldal \xFAjrat\xF6lt\xE9se",
|
|
133
133
|
retrying: "\xDAjrapr\xF3b\xE1lkoz\xE1si k\xEDs\xE9rlet",
|
|
134
134
|
tryAgain: "Pr\xF3b\xE1lja \xFAjra"
|
|
@@ -136,7 +136,7 @@ var translations = {
|
|
|
136
136
|
id: {
|
|
137
137
|
heading: "Terjadi kesalahan",
|
|
138
138
|
loading: "Memuat...",
|
|
139
|
-
message: "Silakan segarkan halaman untuk melanjutkan
|
|
139
|
+
message: "Silakan segarkan halaman untuk melanjutkan",
|
|
140
140
|
reload: "Muat ulang halaman",
|
|
141
141
|
retrying: "Percobaan ulang",
|
|
142
142
|
tryAgain: "Coba lagi"
|
|
@@ -144,7 +144,7 @@ var translations = {
|
|
|
144
144
|
it: {
|
|
145
145
|
heading: "Qualcosa \xE8 andato storto",
|
|
146
146
|
loading: "Caricamento...",
|
|
147
|
-
message: "Aggiorna la pagina per continuare
|
|
147
|
+
message: "Aggiorna la pagina per continuare",
|
|
148
148
|
reload: "Ricarica pagina",
|
|
149
149
|
retrying: "Tentativo di ripetizione",
|
|
150
150
|
tryAgain: "Riprova"
|
|
@@ -152,7 +152,7 @@ var translations = {
|
|
|
152
152
|
ja: {
|
|
153
153
|
heading: "\u554F\u984C\u304C\u767A\u751F\u3057\u307E\u3057\u305F",
|
|
154
154
|
loading: "\u8AAD\u307F\u8FBC\u307F\u4E2D...",
|
|
155
|
-
message: "\u30DA\u30FC\u30B8\u3092\u66F4\u65B0\u3057\u3066\u304F\u3060\u3055\u3044
|
|
155
|
+
message: "\u30DA\u30FC\u30B8\u3092\u66F4\u65B0\u3057\u3066\u304F\u3060\u3055\u3044",
|
|
156
156
|
reload: "\u518D\u8AAD\u307F\u8FBC\u307F",
|
|
157
157
|
retrying: "\u30EA\u30C8\u30E9\u30A4",
|
|
158
158
|
tryAgain: "\u3082\u3046\u4E00\u5EA6\u8A66\u3059"
|
|
@@ -160,7 +160,7 @@ var translations = {
|
|
|
160
160
|
ka: {
|
|
161
161
|
heading: "\u10E0\u10D0\u10E6\u10D0\u10EA \u10D0\u10E0\u10D0\u10E1\u10EC\u10DD\u10E0\u10D0\u10D3 \u10DB\u10DD\u10EE\u10D3\u10D0",
|
|
162
162
|
loading: "\u10D8\u10E2\u10D5\u10D8\u10E0\u10D7\u10D4\u10D1\u10D0...",
|
|
163
|
-
message: "\u10D2\u10D7\u10EE\u10DD\u10D5\u10D7 \u10D2\u10D0\u10DC\u10D0\u10D0\u10EE\u10DA\u10DD\u10D7 \u10D2\u10D5\u10D4\u10E0\u10D3\u10D8 \u10D2\u10D0\u10E1\u10D0\u10D2\u10E0\u10EB\u10D4\u10DA\u10D4\u10D1\u10DA\u10D0\u10D3
|
|
163
|
+
message: "\u10D2\u10D7\u10EE\u10DD\u10D5\u10D7 \u10D2\u10D0\u10DC\u10D0\u10D0\u10EE\u10DA\u10DD\u10D7 \u10D2\u10D5\u10D4\u10E0\u10D3\u10D8 \u10D2\u10D0\u10E1\u10D0\u10D2\u10E0\u10EB\u10D4\u10DA\u10D4\u10D1\u10DA\u10D0\u10D3",
|
|
164
164
|
reload: "\u10D2\u10D5\u10D4\u10E0\u10D3\u10D8\u10E1 \u10D2\u10D0\u10D3\u10D0\u10E2\u10D5\u10D8\u10E0\u10D7\u10D5\u10D0",
|
|
165
165
|
retrying: "\u10D2\u10D0\u10DB\u10D4\u10DD\u10E0\u10D4\u10D1\u10D8\u10E1 \u10DB\u10EA\u10D3\u10D4\u10DA\u10DD\u10D1\u10D0",
|
|
166
166
|
tryAgain: "\u10D9\u10D8\u10D3\u10D4\u10D5 \u10E1\u10EA\u10D0\u10D3\u10D4\u10D7"
|
|
@@ -168,7 +168,7 @@ var translations = {
|
|
|
168
168
|
kk: {
|
|
169
169
|
heading: "\u0411\u0456\u0440\u0434\u0435\u04A3\u0435 \u0434\u04B1\u0440\u044B\u0441 \u0431\u043E\u043B\u043C\u0430\u0434\u044B",
|
|
170
170
|
loading: "\u0416\u04AF\u043A\u0442\u0435\u043B\u0443\u0434\u0435...",
|
|
171
|
-
message: "\u0416\u0430\u043B\u0493\u0430\u0441\u0442\u044B\u0440\u0443 \u04AF\u0448\u0456\u043D \u0431\u0435\u0442\u0442\u0456 \u0436\u0430\u04A3\u0430\u0440\u0442\u044B\u04A3\u044B\u0437
|
|
171
|
+
message: "\u0416\u0430\u043B\u0493\u0430\u0441\u0442\u044B\u0440\u0443 \u04AF\u0448\u0456\u043D \u0431\u0435\u0442\u0442\u0456 \u0436\u0430\u04A3\u0430\u0440\u0442\u044B\u04A3\u044B\u0437",
|
|
172
172
|
reload: "\u0411\u0435\u0442\u0442\u0456 \u049B\u0430\u0439\u0442\u0430 \u0436\u04AF\u043A\u0442\u0435\u0443",
|
|
173
173
|
retrying: "\u049A\u0430\u0439\u0442\u0430\u043B\u0430\u0443 \u04D9\u0440\u0435\u043A\u0435\u0442\u0456",
|
|
174
174
|
tryAgain: "\u049A\u0430\u0439\u0442\u0430\u043B\u0430\u043F \u043A\u04E9\u0440\u0456\u04A3\u0456\u0437"
|
|
@@ -176,7 +176,7 @@ var translations = {
|
|
|
176
176
|
ko: {
|
|
177
177
|
heading: "\uBB38\uC81C\uAC00 \uBC1C\uC0DD\uD588\uC2B5\uB2C8\uB2E4",
|
|
178
178
|
loading: "\uB85C\uB529 \uC911...",
|
|
179
|
-
message: "\uD398\uC774\uC9C0\uB97C \uC0C8\uB85C\uACE0\uCE68\uD574 \uC8FC\uC138\uC694
|
|
179
|
+
message: "\uD398\uC774\uC9C0\uB97C \uC0C8\uB85C\uACE0\uCE68\uD574 \uC8FC\uC138\uC694",
|
|
180
180
|
reload: "\uC0C8\uB85C\uACE0\uCE68",
|
|
181
181
|
retrying: "\uC7AC\uC2DC\uB3C4",
|
|
182
182
|
tryAgain: "\uB2E4\uC2DC \uC2DC\uB3C4"
|
|
@@ -184,7 +184,7 @@ var translations = {
|
|
|
184
184
|
ky: {
|
|
185
185
|
heading: "\u0411\u0438\u0440 \u043D\u0435\u0440\u0441\u0435 \u0442\u0443\u0443\u0440\u0430 \u044D\u043C\u0435\u0441 \u0431\u043E\u043B\u0434\u0443",
|
|
186
186
|
loading: "\u0416\u04AF\u043A\u0442\u04E9\u043B\u04AF\u04AF\u0434\u04E9...",
|
|
187
|
-
message: "\u0423\u043B\u0430\u043D\u0442\u0443\u0443 \u04AF\u0447\u04AF\u043D \u0431\u0430\u0440\u0430\u043A\u0442\u044B \u0436\u0430\u04A3\u044B\u0440\u0442\u044B\u04A3\u044B\u0437
|
|
187
|
+
message: "\u0423\u043B\u0430\u043D\u0442\u0443\u0443 \u04AF\u0447\u04AF\u043D \u0431\u0430\u0440\u0430\u043A\u0442\u044B \u0436\u0430\u04A3\u044B\u0440\u0442\u044B\u04A3\u044B\u0437",
|
|
188
188
|
reload: "\u0411\u0430\u0440\u0430\u043A\u0442\u044B \u043A\u0430\u0439\u0440\u0430 \u0436\u04AF\u043A\u0442\u04E9\u04E9",
|
|
189
189
|
retrying: "\u041A\u0430\u0439\u0442\u0430\u043B\u043E\u043E \u0430\u0440\u0430\u043A\u0435\u0442\u0438",
|
|
190
190
|
tryAgain: "\u041A\u0430\u0439\u0440\u0430 \u0430\u0440\u0430\u043A\u0435\u0442 \u043A\u044B\u043B\u044B\u04A3\u044B\u0437"
|
|
@@ -192,7 +192,7 @@ var translations = {
|
|
|
192
192
|
lt: {
|
|
193
193
|
heading: "Ka\u017Ekas nutiko ne taip",
|
|
194
194
|
loading: "\u012Ekeliama...",
|
|
195
|
-
message: "Pra\u0161ome atnaujinti puslap\u012F, kad t\u0119stum\u0117te
|
|
195
|
+
message: "Pra\u0161ome atnaujinti puslap\u012F, kad t\u0119stum\u0117te",
|
|
196
196
|
reload: "I\u0161 naujo \u012Fkelti puslap\u012F",
|
|
197
197
|
retrying: "Pakartotinis bandymas",
|
|
198
198
|
tryAgain: "Bandyti dar kart\u0105"
|
|
@@ -200,7 +200,7 @@ var translations = {
|
|
|
200
200
|
lv: {
|
|
201
201
|
heading: "Kaut kas nog\u0101ja greizi",
|
|
202
202
|
loading: "Iel\u0101d\u0113...",
|
|
203
|
-
message: "L\u016Bdzu, atsvaidziniet lapu, lai turpin\u0101tu
|
|
203
|
+
message: "L\u016Bdzu, atsvaidziniet lapu, lai turpin\u0101tu",
|
|
204
204
|
reload: "P\u0101rl\u0101d\u0113t lapu",
|
|
205
205
|
retrying: "Atk\u0101rtots m\u0113\u0123in\u0101jums",
|
|
206
206
|
tryAgain: "M\u0113\u0123iniet v\u0113lreiz"
|
|
@@ -208,7 +208,7 @@ var translations = {
|
|
|
208
208
|
nl: {
|
|
209
209
|
heading: "Er is iets misgegaan",
|
|
210
210
|
loading: "Laden...",
|
|
211
|
-
message: "Ververs de pagina om door te gaan
|
|
211
|
+
message: "Ververs de pagina om door te gaan",
|
|
212
212
|
reload: "Pagina herladen",
|
|
213
213
|
retrying: "Opnieuw proberen",
|
|
214
214
|
tryAgain: "Probeer opnieuw"
|
|
@@ -216,7 +216,7 @@ var translations = {
|
|
|
216
216
|
no: {
|
|
217
217
|
heading: "Noe gikk galt",
|
|
218
218
|
loading: "Laster...",
|
|
219
|
-
message: "Vennligst oppdater siden for \xE5 fortsette
|
|
219
|
+
message: "Vennligst oppdater siden for \xE5 fortsette",
|
|
220
220
|
reload: "Last inn siden p\xE5 nytt",
|
|
221
221
|
retrying: "Nytt fors\xF8k",
|
|
222
222
|
tryAgain: "Pr\xF8v igjen"
|
|
@@ -224,7 +224,7 @@ var translations = {
|
|
|
224
224
|
pl: {
|
|
225
225
|
heading: "Co\u015B posz\u0142o nie tak",
|
|
226
226
|
loading: "\u0141adowanie...",
|
|
227
|
-
message: "Od\u015Bwie\u017C stron\u0119, aby kontynuowa\u0107
|
|
227
|
+
message: "Od\u015Bwie\u017C stron\u0119, aby kontynuowa\u0107",
|
|
228
228
|
reload: "Prze\u0142aduj stron\u0119",
|
|
229
229
|
retrying: "Pr\xF3ba ponowienia",
|
|
230
230
|
tryAgain: "Spr\xF3buj ponownie"
|
|
@@ -232,7 +232,7 @@ var translations = {
|
|
|
232
232
|
pt: {
|
|
233
233
|
heading: "Algo deu errado",
|
|
234
234
|
loading: "Carregando...",
|
|
235
|
-
message: "Por favor, atualize a p\xE1gina para continuar
|
|
235
|
+
message: "Por favor, atualize a p\xE1gina para continuar",
|
|
236
236
|
reload: "Recarregar p\xE1gina",
|
|
237
237
|
retrying: "Tentativa de nova tentativa",
|
|
238
238
|
tryAgain: "Tentar novamente"
|
|
@@ -240,7 +240,7 @@ var translations = {
|
|
|
240
240
|
ro: {
|
|
241
241
|
heading: "Ceva nu a mers bine",
|
|
242
242
|
loading: "Se \xEEncarc\u0103...",
|
|
243
|
-
message: "V\u0103 rug\u0103m s\u0103 re\xEEmprosp\u0103ta\u021Bi pagina pentru a continua
|
|
243
|
+
message: "V\u0103 rug\u0103m s\u0103 re\xEEmprosp\u0103ta\u021Bi pagina pentru a continua",
|
|
244
244
|
reload: "Re\xEEncarc\u0103 pagina",
|
|
245
245
|
retrying: "\xCEncercare de re\xEEncercare",
|
|
246
246
|
tryAgain: "\xCEncearc\u0103 din nou"
|
|
@@ -248,7 +248,7 @@ var translations = {
|
|
|
248
248
|
ru: {
|
|
249
249
|
heading: "\u0427\u0442\u043E-\u0442\u043E \u043F\u043E\u0448\u043B\u043E \u043D\u0435 \u0442\u0430\u043A",
|
|
250
250
|
loading: "\u0417\u0430\u0433\u0440\u0443\u0437\u043A\u0430...",
|
|
251
|
-
message: "\u041F\u043E\u0436\u0430\u043B\u0443\u0439\u0441\u0442\u0430, \u043E\u0431\u043D\u043E\u0432\u0438\u0442\u0435 \u0441\u0442\u0440\u0430\u043D\u0438\u0446\u0443, \u0447\u0442\u043E\u0431\u044B \u043F\u0440\u043E\u0434\u043E\u043B\u0436\u0438\u0442\u044C
|
|
251
|
+
message: "\u041F\u043E\u0436\u0430\u043B\u0443\u0439\u0441\u0442\u0430, \u043E\u0431\u043D\u043E\u0432\u0438\u0442\u0435 \u0441\u0442\u0440\u0430\u043D\u0438\u0446\u0443, \u0447\u0442\u043E\u0431\u044B \u043F\u0440\u043E\u0434\u043E\u043B\u0436\u0438\u0442\u044C",
|
|
252
252
|
reload: "\u041F\u0435\u0440\u0435\u0437\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044C \u0441\u0442\u0440\u0430\u043D\u0438\u0446\u0443",
|
|
253
253
|
retrying: "\u041F\u043E\u0432\u0442\u043E\u0440\u043D\u0430\u044F \u043F\u043E\u043F\u044B\u0442\u043A\u0430",
|
|
254
254
|
tryAgain: "\u041F\u043E\u043F\u0440\u043E\u0431\u043E\u0432\u0430\u0442\u044C \u0441\u043D\u043E\u0432\u0430"
|
|
@@ -256,7 +256,7 @@ var translations = {
|
|
|
256
256
|
sk: {
|
|
257
257
|
heading: "Nie\u010Do sa pokazilo",
|
|
258
258
|
loading: "Na\u010D\xEDtava sa...",
|
|
259
|
-
message: "Obnovte str\xE1nku pros\xEDm pre pokra\u010Dovanie
|
|
259
|
+
message: "Obnovte str\xE1nku pros\xEDm pre pokra\u010Dovanie",
|
|
260
260
|
reload: "Znovu na\u010D\xEDta\u0165 str\xE1nku",
|
|
261
261
|
retrying: "Pokus o opakovanie",
|
|
262
262
|
tryAgain: "Sk\xFAsi\u0165 znova"
|
|
@@ -264,7 +264,7 @@ var translations = {
|
|
|
264
264
|
sl: {
|
|
265
265
|
heading: "Nekaj je \u0161lo narobe",
|
|
266
266
|
loading: "Nalaganje...",
|
|
267
|
-
message: "Prosimo, osve\u017Eite stran za nadaljevanje
|
|
267
|
+
message: "Prosimo, osve\u017Eite stran za nadaljevanje",
|
|
268
268
|
reload: "Ponovno nalo\u017Ei stran",
|
|
269
269
|
retrying: "Poskus ponovnega poskusa",
|
|
270
270
|
tryAgain: "Poskusi znova"
|
|
@@ -272,7 +272,7 @@ var translations = {
|
|
|
272
272
|
sv: {
|
|
273
273
|
heading: "N\xE5got gick fel",
|
|
274
274
|
loading: "Laddar...",
|
|
275
|
-
message: "Uppdatera sidan f\xF6r att forts\xE4tta
|
|
275
|
+
message: "Uppdatera sidan f\xF6r att forts\xE4tta",
|
|
276
276
|
reload: "Ladda om sidan",
|
|
277
277
|
retrying: "Nytt f\xF6rs\xF6k",
|
|
278
278
|
tryAgain: "F\xF6rs\xF6k igen"
|
|
@@ -288,7 +288,7 @@ var translations = {
|
|
|
288
288
|
tr: {
|
|
289
289
|
heading: "Bir \u015Feyler ters gitti",
|
|
290
290
|
loading: "Y\xFCkleniyor...",
|
|
291
|
-
message: "Devam etmek i\xE7in l\xFCtfen sayfay\u0131 yenileyin
|
|
291
|
+
message: "Devam etmek i\xE7in l\xFCtfen sayfay\u0131 yenileyin",
|
|
292
292
|
reload: "Sayfay\u0131 yeniden y\xFCkle",
|
|
293
293
|
retrying: "Yeniden deneme giri\u015Fimi",
|
|
294
294
|
tryAgain: "Tekrar dene"
|
|
@@ -296,7 +296,7 @@ var translations = {
|
|
|
296
296
|
uk: {
|
|
297
297
|
heading: "\u0429\u043E\u0441\u044C \u043F\u0456\u0448\u043B\u043E \u043D\u0435 \u0442\u0430\u043A",
|
|
298
298
|
loading: "\u0417\u0430\u0432\u0430\u043D\u0442\u0430\u0436\u0435\u043D\u043D\u044F...",
|
|
299
|
-
message: "\u0411\u0443\u0434\u044C \u043B\u0430\u0441\u043A\u0430, \u043E\u043D\u043E\u0432\u0456\u0442\u044C \u0441\u0442\u043E\u0440\u0456\u043D\u043A\u0443, \u0449\u043E\u0431 \u043F\u0440\u043E\u0434\u043E\u0432\u0436\u0438\u0442\u0438
|
|
299
|
+
message: "\u0411\u0443\u0434\u044C \u043B\u0430\u0441\u043A\u0430, \u043E\u043D\u043E\u0432\u0456\u0442\u044C \u0441\u0442\u043E\u0440\u0456\u043D\u043A\u0443, \u0449\u043E\u0431 \u043F\u0440\u043E\u0434\u043E\u0432\u0436\u0438\u0442\u0438",
|
|
300
300
|
reload: "\u041F\u0435\u0440\u0435\u0437\u0430\u0432\u0430\u043D\u0442\u0430\u0436\u0438\u0442\u0438 \u0441\u0442\u043E\u0440\u0456\u043D\u043A\u0443",
|
|
301
301
|
retrying: "\u041F\u043E\u0432\u0442\u043E\u0440\u043D\u0430 \u0441\u043F\u0440\u043E\u0431\u0430",
|
|
302
302
|
tryAgain: "\u0421\u043F\u0440\u043E\u0431\u0443\u0432\u0430\u0442\u0438 \u0437\u043D\u043E\u0432\u0443"
|
|
@@ -304,7 +304,7 @@ var translations = {
|
|
|
304
304
|
zh: {
|
|
305
305
|
heading: "\u51FA\u4E86\u70B9\u95EE\u9898",
|
|
306
306
|
loading: "\u52A0\u8F7D\u4E2D...",
|
|
307
|
-
message: "\u8BF7\u5237\u65B0\u9875\u9762\u4EE5\u7EE7\u7EED
|
|
307
|
+
message: "\u8BF7\u5237\u65B0\u9875\u9762\u4EE5\u7EE7\u7EED",
|
|
308
308
|
reload: "\u91CD\u65B0\u52A0\u8F7D",
|
|
309
309
|
retrying: "\u91CD\u8BD5\u6B21\u6570",
|
|
310
310
|
tryAgain: "\u91CD\u8BD5"
|
|
@@ -8,13 +8,13 @@ import {
|
|
|
8
8
|
dispatchStaticAsset404,
|
|
9
9
|
dispatchSyncRuntimeError,
|
|
10
10
|
dispatchUnhandledRejection
|
|
11
|
-
} from "../../chunk-
|
|
11
|
+
} from "../../chunk-ORYUDYHU.js";
|
|
12
12
|
import {
|
|
13
13
|
subscribeToState
|
|
14
|
-
} from "../../chunk-
|
|
14
|
+
} from "../../chunk-IZAXNDHZ.js";
|
|
15
15
|
import {
|
|
16
16
|
subscribe
|
|
17
|
-
} from "../../chunk-
|
|
17
|
+
} from "../../chunk-LIKSIU75.js";
|
|
18
18
|
import "../../chunk-MLKGABMK.js";
|
|
19
19
|
|
|
20
20
|
// src/runtime/debug/index.ts
|
package/dist/runtime/index.js
CHANGED
|
@@ -3,19 +3,21 @@ import {
|
|
|
3
3
|
extractVersionFromHtml,
|
|
4
4
|
getSpinnerHtml,
|
|
5
5
|
showSpinner
|
|
6
|
-
} from "../chunk-
|
|
6
|
+
} from "../chunk-T42DLOQP.js";
|
|
7
7
|
import {
|
|
8
8
|
getState,
|
|
9
9
|
subscribeToState
|
|
10
|
-
} from "../chunk-
|
|
10
|
+
} from "../chunk-IZAXNDHZ.js";
|
|
11
11
|
import {
|
|
12
12
|
ForceRetryError,
|
|
13
13
|
getLogger,
|
|
14
14
|
getOptions,
|
|
15
|
+
getRetryAttemptFromUrl,
|
|
16
|
+
getRetrySnapshot,
|
|
15
17
|
markRetryHealthyBoot,
|
|
16
18
|
setTranslations,
|
|
17
19
|
versionCheckStateWindowKey
|
|
18
|
-
} from "../chunk-
|
|
20
|
+
} from "../chunk-LIKSIU75.js";
|
|
19
21
|
import "../chunk-MLKGABMK.js";
|
|
20
22
|
|
|
21
23
|
// src/common/checkVersion.ts
|
|
@@ -255,18 +257,120 @@ var stopVersionCheck = () => {
|
|
|
255
257
|
};
|
|
256
258
|
|
|
257
259
|
// src/runtime/recommendedSetup.ts
|
|
260
|
+
var AUTO_HEALTHY_BOOT_BUFFER_MS = 1e3;
|
|
261
|
+
var MIN_HEALTHY_BOOT_GRACE_MS = 5e3;
|
|
262
|
+
var setupStateWindowKey = "__spa_guard_runtime_recommended_setup_state__";
|
|
263
|
+
var createFreshState = () => ({
|
|
264
|
+
cleanup: () => {
|
|
265
|
+
},
|
|
266
|
+
initialized: false,
|
|
267
|
+
timer: null,
|
|
268
|
+
versionCheckEnabled: false
|
|
269
|
+
});
|
|
270
|
+
var getState3 = () => {
|
|
271
|
+
if (globalThis.window === void 0) {
|
|
272
|
+
return createFreshState();
|
|
273
|
+
}
|
|
274
|
+
const w = globalThis.window;
|
|
275
|
+
if (!w[setupStateWindowKey]) {
|
|
276
|
+
w[setupStateWindowKey] = createFreshState();
|
|
277
|
+
}
|
|
278
|
+
return w[setupStateWindowKey];
|
|
279
|
+
};
|
|
280
|
+
var resolveOptions = (overrides) => {
|
|
281
|
+
const healthyBoot = overrides?.healthyBoot;
|
|
282
|
+
const versionCheck = overrides?.versionCheck ?? true;
|
|
283
|
+
const computedGraceMs = computeAutoHealthyBootGraceMs();
|
|
284
|
+
if (healthyBoot === false || healthyBoot === "off") {
|
|
285
|
+
return {
|
|
286
|
+
healthyBootGraceMs: computedGraceMs,
|
|
287
|
+
healthyBootMode: "off",
|
|
288
|
+
versionCheck
|
|
289
|
+
};
|
|
290
|
+
}
|
|
291
|
+
if (healthyBoot === "manual") {
|
|
292
|
+
return {
|
|
293
|
+
healthyBootGraceMs: computedGraceMs,
|
|
294
|
+
healthyBootMode: "manual",
|
|
295
|
+
versionCheck
|
|
296
|
+
};
|
|
297
|
+
}
|
|
298
|
+
if (healthyBoot && typeof healthyBoot === "object") {
|
|
299
|
+
return {
|
|
300
|
+
healthyBootGraceMs: Math.max(computedGraceMs, healthyBoot.graceMs ?? computedGraceMs),
|
|
301
|
+
healthyBootMode: "auto",
|
|
302
|
+
versionCheck
|
|
303
|
+
};
|
|
304
|
+
}
|
|
305
|
+
return {
|
|
306
|
+
healthyBootGraceMs: computedGraceMs,
|
|
307
|
+
healthyBootMode: "auto",
|
|
308
|
+
versionCheck
|
|
309
|
+
};
|
|
310
|
+
};
|
|
311
|
+
var computeAutoHealthyBootGraceMs = () => {
|
|
312
|
+
const options = getOptions();
|
|
313
|
+
const reloadDelays = options.reloadDelays ?? [1e3, 2e3, 5e3];
|
|
314
|
+
const lazyRetryDelays = options.lazyRetry?.retryDelays ?? [1e3, 2e3];
|
|
315
|
+
const maxReloadDelay = Math.max(...reloadDelays, 0);
|
|
316
|
+
const lazyRetryTotalDelay = lazyRetryDelays.reduce((acc, delay) => acc + delay, 0);
|
|
317
|
+
return Math.max(
|
|
318
|
+
MIN_HEALTHY_BOOT_GRACE_MS,
|
|
319
|
+
maxReloadDelay + AUTO_HEALTHY_BOOT_BUFFER_MS,
|
|
320
|
+
lazyRetryTotalDelay + AUTO_HEALTHY_BOOT_BUFFER_MS
|
|
321
|
+
);
|
|
322
|
+
};
|
|
323
|
+
var scheduleAutoHealthyBoot = (graceMs) => {
|
|
324
|
+
if (globalThis.window === void 0) {
|
|
325
|
+
return null;
|
|
326
|
+
}
|
|
327
|
+
if (getRetryAttemptFromUrl() === null) {
|
|
328
|
+
return null;
|
|
329
|
+
}
|
|
330
|
+
return setTimeout(() => {
|
|
331
|
+
if (getRetryAttemptFromUrl() === null) {
|
|
332
|
+
return;
|
|
333
|
+
}
|
|
334
|
+
const snapshot = getRetrySnapshot();
|
|
335
|
+
if (snapshot.phase !== "idle") {
|
|
336
|
+
return;
|
|
337
|
+
}
|
|
338
|
+
markRetryHealthyBoot();
|
|
339
|
+
}, graceMs);
|
|
340
|
+
};
|
|
258
341
|
var recommendedSetup = (overrides) => {
|
|
342
|
+
const state = getState3();
|
|
343
|
+
if (state.initialized) {
|
|
344
|
+
return state.cleanup;
|
|
345
|
+
}
|
|
259
346
|
dismissSpinner();
|
|
260
|
-
|
|
261
|
-
const options = { versionCheck: true, ...overrides };
|
|
347
|
+
const options = resolveOptions(overrides);
|
|
262
348
|
if (options.versionCheck) {
|
|
263
349
|
startVersionCheck();
|
|
264
350
|
}
|
|
265
|
-
|
|
266
|
-
|
|
351
|
+
const timer = options.healthyBootMode === "auto" ? scheduleAutoHealthyBoot(options.healthyBootGraceMs) : null;
|
|
352
|
+
const cleanup = () => {
|
|
353
|
+
const currentState = getState3();
|
|
354
|
+
if (!currentState.initialized) {
|
|
355
|
+
return;
|
|
356
|
+
}
|
|
357
|
+
if (currentState.timer !== null) {
|
|
358
|
+
clearTimeout(currentState.timer);
|
|
359
|
+
}
|
|
360
|
+
if (currentState.versionCheckEnabled) {
|
|
267
361
|
stopVersionCheck();
|
|
268
362
|
}
|
|
363
|
+
if (globalThis.window !== void 0) {
|
|
364
|
+
globalThis.window[setupStateWindowKey] = createFreshState();
|
|
365
|
+
}
|
|
269
366
|
};
|
|
367
|
+
Object.assign(state, {
|
|
368
|
+
cleanup,
|
|
369
|
+
initialized: true,
|
|
370
|
+
timer,
|
|
371
|
+
versionCheckEnabled: options.versionCheck
|
|
372
|
+
});
|
|
373
|
+
return cleanup;
|
|
270
374
|
};
|
|
271
375
|
export {
|
|
272
376
|
ForceRetryError,
|
|
@@ -1,12 +1,36 @@
|
|
|
1
1
|
export interface RecommendedSetupOptions {
|
|
2
|
+
/**
|
|
3
|
+
* Healthy boot handling strategy.
|
|
4
|
+
*
|
|
5
|
+
* - `"auto"` (default): if retry URL params are present, mark healthy boot
|
|
6
|
+
* after a grace period and only when orchestrator is still idle.
|
|
7
|
+
* - `"manual"`: never auto-mark; call `markRetryHealthyBoot()` yourself.
|
|
8
|
+
* - `"off"` / `false`: disable healthy boot handling.
|
|
9
|
+
*/
|
|
10
|
+
healthyBoot?: RecommendedSetupHealthyBoot;
|
|
2
11
|
/**
|
|
3
12
|
* Whether to start version checking.
|
|
4
13
|
* @default true
|
|
5
14
|
*/
|
|
6
15
|
versionCheck?: boolean;
|
|
7
16
|
}
|
|
17
|
+
interface HealthyBootAutoConfig {
|
|
18
|
+
/**
|
|
19
|
+
* Delay before auto-marking healthy boot when retry params are present in URL.
|
|
20
|
+
* @default dynamic:
|
|
21
|
+
* max(5000, max(reloadDelays)+1000, sum(lazyRetry.retryDelays)+1000)
|
|
22
|
+
*/
|
|
23
|
+
graceMs?: number;
|
|
24
|
+
/**
|
|
25
|
+
* Explicit mode for object config.
|
|
26
|
+
* @default "auto"
|
|
27
|
+
*/
|
|
28
|
+
mode?: "auto";
|
|
29
|
+
}
|
|
30
|
+
type RecommendedSetupHealthyBoot = "auto" | "manual" | "off" | false | HealthyBootAutoConfig;
|
|
8
31
|
/**
|
|
9
32
|
* Enable recommended runtime features with sensible defaults.
|
|
10
33
|
* Returns a cleanup function that tears down all started features.
|
|
11
34
|
*/
|
|
12
35
|
export declare const recommendedSetup: (overrides?: RecommendedSetupOptions) => (() => void);
|
|
36
|
+
export {};
|