@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.
Files changed (67) hide show
  1. package/README.md +22 -173
  2. package/dist/ForceRetryError-BWLv3UVK.d.mts +6 -0
  3. package/dist/_internal.d.ts +149 -20
  4. package/dist/_internal.js +113 -170
  5. package/dist/chunk-CfYAbeIz.mjs +13 -0
  6. package/dist/common/index.d.ts +29 -9
  7. package/dist/common/index.js +47 -83
  8. package/dist/errorDispatchers-Cl_pa0DT.mjs +105 -0
  9. package/dist/i18n/index.d.ts +2 -21
  10. package/dist/i18n/index.js +344 -341
  11. package/dist/index-DL8CfPXg.d.mts +26 -0
  12. package/dist/index-rPxPv6iu.d.mts +16 -0
  13. package/dist/logger-Cp1Eyk6S.mjs +534 -0
  14. package/dist/retryOrchestrator-DNGIHV2M.mjs +758 -0
  15. package/dist/retryOrchestrator-mn9XcIVu.d.mts +257 -0
  16. package/dist/runtime/debug/index.d.ts +6 -4
  17. package/dist/runtime/debug/index.js +218 -238
  18. package/dist/runtime/index.d.ts +66 -8
  19. package/dist/runtime/index.js +279 -367
  20. package/dist/schema/index.d.ts +2 -13
  21. package/dist/schema/index.js +1 -0
  22. package/dist/schema/parse.d.ts +6 -2
  23. package/dist/schema/parse.js +29 -44
  24. package/dist/spinner-BbZVKZ-6.mjs +60 -0
  25. package/dist/spinner-X23gI09z.d.mts +37 -0
  26. package/dist/state-I20jENMD.mjs +93 -0
  27. package/dist/types-DrN8pgyc.d.mts +107 -0
  28. package/package.json +1 -4
  29. package/dist/chunk-3UJ67DPX.js +0 -98
  30. package/dist/chunk-GE63YJOT.js +0 -865
  31. package/dist/chunk-MLKGABMK.js +0 -9
  32. package/dist/chunk-PERG4557.js +0 -74
  33. package/dist/chunk-VZ2DLGXX.js +0 -111
  34. package/dist/chunk-XIFXSNSD.js +0 -678
  35. package/dist/common/checkVersion.d.ts +0 -5
  36. package/dist/common/constants.d.ts +0 -14
  37. package/dist/common/errors/BeaconError.d.ts +0 -12
  38. package/dist/common/errors/ForceRetryError.d.ts +0 -5
  39. package/dist/common/events/index.d.ts +0 -2
  40. package/dist/common/events/internal.d.ts +0 -13
  41. package/dist/common/events/types.d.ts +0 -104
  42. package/dist/common/fallbackRendering.d.ts +0 -23
  43. package/dist/common/fallbackState.d.ts +0 -3
  44. package/dist/common/handleErrorWithSpaGuard.d.ts +0 -18
  45. package/dist/common/html.generated.d.ts +0 -3
  46. package/dist/common/i18n.d.ts +0 -23
  47. package/dist/common/isChunkError.d.ts +0 -1
  48. package/dist/common/isStaticAssetError.d.ts +0 -3
  49. package/dist/common/lastReloadTime.d.ts +0 -17
  50. package/dist/common/listen/index.d.ts +0 -1
  51. package/dist/common/listen/internal.d.ts +0 -2
  52. package/dist/common/log.d.ts +0 -1
  53. package/dist/common/logger.d.ts +0 -30
  54. package/dist/common/options.d.ts +0 -182
  55. package/dist/common/parseVersion.d.ts +0 -9
  56. package/dist/common/retryImport.d.ts +0 -43
  57. package/dist/common/retryOrchestrator.d.ts +0 -35
  58. package/dist/common/retryState.d.ts +0 -11
  59. package/dist/common/sendBeacon.d.ts +0 -2
  60. package/dist/common/serializeError.d.ts +0 -1
  61. package/dist/common/shouldIgnore.d.ts +0 -13
  62. package/dist/common/spinner.d.ts +0 -8
  63. package/dist/common/staticAssetRecovery.d.ts +0 -2
  64. package/dist/i18n/translations.d.ts +0 -2
  65. package/dist/runtime/debug/errorDispatchers.d.ts +0 -63
  66. package/dist/runtime/recommendedSetup.d.ts +0 -36
  67. package/dist/runtime/state.d.ts +0 -20
@@ -1,266 +1,246 @@
1
- import {
2
- dispatchAsyncRuntimeError,
3
- dispatchChunkLoadError,
4
- dispatchFinallyError,
5
- dispatchForceRetryError,
6
- dispatchNetworkTimeout,
7
- dispatchRetryExhausted,
8
- dispatchStaticAsset404,
9
- dispatchSyncRuntimeError,
10
- dispatchUnhandledRejection
11
- } from "../../chunk-PERG4557.js";
12
- import {
13
- subscribeToState
14
- } from "../../chunk-VZ2DLGXX.js";
15
- import {
16
- subscribe
17
- } from "../../chunk-GE63YJOT.js";
18
- import "../../chunk-MLKGABMK.js";
19
-
20
- // src/runtime/debug/index.ts
21
- var SCENARIOS = [
22
- { dispatch: dispatchChunkLoadError, key: "chunk-load-error", label: "ChunkLoadError" },
23
- { dispatch: () => dispatchNetworkTimeout(100), key: "network-timeout", label: "Network Timeout" },
24
- { dispatch: dispatchSyncRuntimeError, key: "sync-runtime-error", label: "Sync Runtime Error" },
25
- { dispatch: dispatchAsyncRuntimeError, key: "async-runtime-error", label: "Async Runtime Error" },
26
- { dispatch: dispatchFinallyError, key: "finally-error", label: "Finally Error" },
27
- { dispatch: dispatchForceRetryError, key: "force-retry-error", label: "ForceRetry Error" },
28
- {
29
- dispatch: dispatchUnhandledRejection,
30
- key: "unhandled-rejection",
31
- label: "Unhandled Rejection"
32
- },
33
- { dispatch: dispatchRetryExhausted, key: "exhaust-retries", label: "Exhaust Retries" },
34
- { dispatch: dispatchStaticAsset404, key: "static-asset-404", label: "Static Asset 404" }
1
+ import { M as subscribe } from "../../retryOrchestrator-DNGIHV2M.mjs";
2
+ import { a as dispatchNetworkTimeout, c as dispatchSyncRuntimeError, i as dispatchForceRetryError, l as dispatchUnhandledRejection, n as dispatchChunkLoadError, o as dispatchRetryExhausted, r as dispatchFinallyError, s as dispatchStaticAsset404, t as dispatchAsyncRuntimeError } from "../../errorDispatchers-Cl_pa0DT.mjs";
3
+ import { n as subscribeToState } from "../../state-I20jENMD.mjs";
4
+ //#region src/runtime/debug/index.ts
5
+ const SCENARIOS = [
6
+ {
7
+ dispatch: dispatchChunkLoadError,
8
+ key: "chunk-load-error",
9
+ label: "ChunkLoadError"
10
+ },
11
+ {
12
+ dispatch: () => dispatchNetworkTimeout(100),
13
+ key: "network-timeout",
14
+ label: "Network Timeout"
15
+ },
16
+ {
17
+ dispatch: dispatchSyncRuntimeError,
18
+ key: "sync-runtime-error",
19
+ label: "Sync Runtime Error"
20
+ },
21
+ {
22
+ dispatch: dispatchAsyncRuntimeError,
23
+ key: "async-runtime-error",
24
+ label: "Async Runtime Error"
25
+ },
26
+ {
27
+ dispatch: dispatchFinallyError,
28
+ key: "finally-error",
29
+ label: "Finally Error"
30
+ },
31
+ {
32
+ dispatch: dispatchForceRetryError,
33
+ key: "force-retry-error",
34
+ label: "ForceRetry Error"
35
+ },
36
+ {
37
+ dispatch: dispatchUnhandledRejection,
38
+ key: "unhandled-rejection",
39
+ label: "Unhandled Rejection"
40
+ },
41
+ {
42
+ dispatch: dispatchRetryExhausted,
43
+ key: "exhaust-retries",
44
+ label: "Exhaust Retries"
45
+ },
46
+ {
47
+ dispatch: dispatchStaticAsset404,
48
+ key: "static-asset-404",
49
+ label: "Static Asset 404"
50
+ }
35
51
  ];
36
- var POSITION_MAP = {
37
- "bottom-left": "bottom:16px;left:16px;",
38
- "bottom-right": "bottom:16px;right:16px;",
39
- "top-left": "top:16px;left:16px;",
40
- "top-right": "top:16px;right:16px;"
52
+ const POSITION_MAP = {
53
+ "bottom-left": "bottom:16px;left:16px;",
54
+ "bottom-right": "bottom:16px;right:16px;",
55
+ "top-left": "top:16px;left:16px;",
56
+ "top-right": "top:16px;right:16px;"
41
57
  };
42
- var MAX_EVENT_HISTORY = 100;
43
- var activeInstance = null;
58
+ const MAX_EVENT_HISTORY = 100;
59
+ let activeInstance = null;
60
+ /**
61
+ * Creates a debug panel for spa-guard that displays state, events,
62
+ * and provides error simulation buttons.
63
+ *
64
+ * Returns a cleanup function that removes the panel and unsubscribes all listeners.
65
+ */
44
66
  function createDebugger(options) {
45
- if (activeInstance) {
46
- console.warn("[spa-guard] Debug panel already exists. Returning existing cleanup function.");
47
- return activeInstance;
48
- }
49
- if (!document.body) {
50
- console.warn("[spa-guard] document.body is not available. Debug panel cannot be mounted.");
51
- return () => {
52
- };
53
- }
54
- let isOpen = options?.defaultOpen ?? true;
55
- const unsubscribers = [];
56
- const panel = el(
57
- "div",
58
- `background:#1e1e2e;border-radius:8px;box-shadow:0 4px 12px rgba(0,0,0,0.3);color:#cdd6f4;font-family:monospace;font-size:13px;max-width:320px;min-width:260px;padding:12px;position:fixed;z-index:99999;${POSITION_MAP[options?.position ?? "bottom-right"]}`,
59
- "spa-guard-debug-panel"
60
- );
61
- const { arrow, header } = createHeader(isOpen);
62
- const content = buildContent(unsubscribers);
63
- panel.append(header);
64
- header.addEventListener("click", () => {
65
- isOpen = !isOpen;
66
- arrow.textContent = isOpen ? "\u25B2" : "\u25BC";
67
- if (isOpen) {
68
- panel.append(content);
69
- } else {
70
- content.remove();
71
- }
72
- });
73
- if (isOpen) {
74
- panel.append(content);
75
- }
76
- document.body.append(panel);
77
- const destroy = () => {
78
- for (const unsub of unsubscribers) {
79
- unsub();
80
- }
81
- panel.remove();
82
- activeInstance = null;
83
- };
84
- activeInstance = destroy;
85
- return destroy;
67
+ if (activeInstance) {
68
+ console.warn("[spa-guard] Debug panel already exists. Returning existing cleanup function.");
69
+ return activeInstance;
70
+ }
71
+ if (!document.body) {
72
+ console.warn("[spa-guard] document.body is not available. Debug panel cannot be mounted.");
73
+ return () => {};
74
+ }
75
+ let isOpen = options?.defaultOpen ?? true;
76
+ const unsubscribers = [];
77
+ const panel = el("div", `background:#1e1e2e;border-radius:8px;box-shadow:0 4px 12px rgba(0,0,0,0.3);color:#cdd6f4;font-family:monospace;font-size:13px;max-width:320px;min-width:260px;padding:12px;position:fixed;z-index:99999;${POSITION_MAP[options?.position ?? "bottom-right"]}`, "spa-guard-debug-panel");
78
+ const { arrow, header } = createHeader(isOpen);
79
+ const content = buildContent(unsubscribers);
80
+ panel.append(header);
81
+ header.addEventListener("click", () => {
82
+ isOpen = !isOpen;
83
+ arrow.textContent = isOpen ? "▲" : "▼";
84
+ if (isOpen) panel.append(content);
85
+ else content.remove();
86
+ });
87
+ if (isOpen) panel.append(content);
88
+ document.body.append(panel);
89
+ const destroy = () => {
90
+ for (const unsub of unsubscribers) unsub();
91
+ panel.remove();
92
+ activeInstance = null;
93
+ };
94
+ activeInstance = destroy;
95
+ return destroy;
86
96
  }
87
97
  function buildContent(unsubscribers) {
88
- const content = el("div", "margin-top:10px;", "debug-panel-content");
89
- createButtons(content);
90
- content.append(createStateSection(unsubscribers), createEventsSection(unsubscribers));
91
- return content;
98
+ const content = el("div", "margin-top:10px;", "debug-panel-content");
99
+ createButtons(content);
100
+ content.append(createStateSection(unsubscribers), createEventsSection(unsubscribers));
101
+ return content;
92
102
  }
93
103
  function createButtons(content) {
94
- const label = el("div", "color:#a6adc8;font-size:11px;margin-bottom:4px;");
95
- label.textContent = "Error Scenarios";
96
- content.append(label);
97
- for (const scenario of SCENARIOS) {
98
- const btn = el("button", getButtonCss("default"), `debug-btn-${scenario.key}`);
99
- btn.setAttribute("type", "button");
100
- btn.textContent = scenario.label;
101
- btn.addEventListener("click", () => {
102
- btn.textContent = getButtonLabel(scenario.label, "loading");
103
- btn.setAttribute("style", getButtonCss("loading"));
104
- btn.disabled = true;
105
- scenario.dispatch();
106
- void Promise.resolve().then(() => {
107
- btn.textContent = getButtonLabel(scenario.label, "triggered");
108
- btn.setAttribute("style", getButtonCss("triggered"));
109
- btn.disabled = false;
110
- });
111
- });
112
- content.append(btn);
113
- }
104
+ const label = el("div", "color:#a6adc8;font-size:11px;margin-bottom:4px;");
105
+ label.textContent = "Error Scenarios";
106
+ content.append(label);
107
+ for (const scenario of SCENARIOS) {
108
+ const btn = el("button", getButtonCss("default"), `debug-btn-${scenario.key}`);
109
+ btn.setAttribute("type", "button");
110
+ btn.textContent = scenario.label;
111
+ btn.addEventListener("click", () => {
112
+ btn.textContent = getButtonLabel(scenario.label, "loading");
113
+ btn.setAttribute("style", getButtonCss("loading"));
114
+ btn.disabled = true;
115
+ scenario.dispatch();
116
+ Promise.resolve().then(() => {
117
+ btn.textContent = getButtonLabel(scenario.label, "triggered");
118
+ btn.setAttribute("style", getButtonCss("triggered"));
119
+ btn.disabled = false;
120
+ });
121
+ });
122
+ content.append(btn);
123
+ }
114
124
  }
115
125
  function createEventListHeader() {
116
- const headerContainer = el(
117
- "div",
118
- "color:#a6adc8;font-size:11px;margin-bottom:4px;align-items:center;display:flex;justify-content:space-between;"
119
- );
120
- const countSpan = document.createElement("span");
121
- countSpan.textContent = "Event History (0)";
122
- const clearBtn = el(
123
- "button",
124
- "background:none;border:none;color:#a6adc8;cursor:pointer;font-family:monospace;font-size:11px;padding:0;",
125
- "debug-clear-history"
126
- );
127
- clearBtn.setAttribute("type", "button");
128
- clearBtn.textContent = "clear";
129
- headerContainer.append(countSpan, clearBtn);
130
- return { clearBtn, countSpan, headerContainer };
126
+ const headerContainer = el("div", "color:#a6adc8;font-size:11px;margin-bottom:4px;align-items:center;display:flex;justify-content:space-between;");
127
+ const countSpan = document.createElement("span");
128
+ countSpan.textContent = "Event History (0)";
129
+ const clearBtn = el("button", "background:none;border:none;color:#a6adc8;cursor:pointer;font-family:monospace;font-size:11px;padding:0;", "debug-clear-history");
130
+ clearBtn.setAttribute("type", "button");
131
+ clearBtn.textContent = "clear";
132
+ headerContainer.append(countSpan, clearBtn);
133
+ return {
134
+ clearBtn,
135
+ countSpan,
136
+ headerContainer
137
+ };
131
138
  }
132
139
  function createEventsSection(unsubscribers) {
133
- const section = el(
134
- "div",
135
- "border-top:1px solid #45475a;margin-top:10px;padding-top:8px;",
136
- "debug-events-section"
137
- );
138
- const { clearBtn, countSpan, headerContainer } = createEventListHeader();
139
- section.append(headerContainer);
140
- const eventList = el(
141
- "div",
142
- "font-size:11px;max-height:120px;overflow-y:auto;",
143
- "debug-event-list"
144
- );
145
- section.append(eventList);
146
- wireEventSubscription({ clearBtn, countSpan, eventList, unsubscribers });
147
- return section;
140
+ const section = el("div", "border-top:1px solid #45475a;margin-top:10px;padding-top:8px;", "debug-events-section");
141
+ const { clearBtn, countSpan, headerContainer } = createEventListHeader();
142
+ section.append(headerContainer);
143
+ const eventList = el("div", "font-size:11px;max-height:120px;overflow-y:auto;", "debug-event-list");
144
+ section.append(eventList);
145
+ wireEventSubscription({
146
+ clearBtn,
147
+ countSpan,
148
+ eventList,
149
+ unsubscribers
150
+ });
151
+ return section;
148
152
  }
149
153
  function createHeader(isOpen) {
150
- const header = el(
151
- "button",
152
- "align-items:center;background:none;border:none;color:inherit;cursor:pointer;display:flex;font-family:inherit;font-size:inherit;justify-content:space-between;padding:0;user-select:none;width:100%;",
153
- "debug-panel-header"
154
- );
155
- header.setAttribute("type", "button");
156
- const label = document.createElement("span");
157
- label.textContent = "spa-guard debug";
158
- const arrow = document.createElement("span");
159
- arrow.textContent = isOpen ? "\u25B2" : "\u25BC";
160
- header.append(label, arrow);
161
- return { arrow, header };
154
+ const header = el("button", "align-items:center;background:none;border:none;color:inherit;cursor:pointer;display:flex;font-family:inherit;font-size:inherit;justify-content:space-between;padding:0;user-select:none;width:100%;", "debug-panel-header");
155
+ header.setAttribute("type", "button");
156
+ const label = document.createElement("span");
157
+ label.textContent = "spa-guard debug";
158
+ const arrow = document.createElement("span");
159
+ arrow.textContent = isOpen ? "" : "";
160
+ header.append(label, arrow);
161
+ return {
162
+ arrow,
163
+ header
164
+ };
162
165
  }
163
166
  function createStateRow(testId, labelText) {
164
- const row = el(
165
- "div",
166
- "display:flex;font-size:11px;justify-content:space-between;margin-top:2px;",
167
- testId
168
- );
169
- const label = document.createElement("span");
170
- label.textContent = labelText;
171
- const value = el("span", "color:#f9e2af;");
172
- row.append(label, value);
173
- return { row, value };
167
+ const row = el("div", "display:flex;font-size:11px;justify-content:space-between;margin-top:2px;", testId);
168
+ const label = document.createElement("span");
169
+ label.textContent = labelText;
170
+ const value = el("span", "color:#f9e2af;");
171
+ row.append(label, value);
172
+ return {
173
+ row,
174
+ value
175
+ };
174
176
  }
175
177
  function createStateSection(unsubscribers) {
176
- const section = el(
177
- "div",
178
- "border-top:1px solid #45475a;margin-top:10px;padding-top:8px;",
179
- "debug-state-section"
180
- );
181
- const label = el("div", "color:#a6adc8;font-size:11px;margin-bottom:4px;");
182
- label.textContent = "State";
183
- const attempt = createStateRow("debug-state-attempt", "attempt");
184
- const waiting = createStateRow("debug-state-waiting", "isWaiting");
185
- const fallback = createStateRow("debug-state-fallback", "isFallbackShown");
186
- section.append(label, attempt.row, waiting.row, fallback.row);
187
- unsubscribers.push(
188
- subscribeToState((state) => {
189
- attempt.value.textContent = String(state.currentAttempt);
190
- waiting.value.textContent = String(state.isWaiting);
191
- fallback.value.textContent = String(state.isFallbackShown);
192
- })
193
- );
194
- return section;
178
+ const section = el("div", "border-top:1px solid #45475a;margin-top:10px;padding-top:8px;", "debug-state-section");
179
+ const label = el("div", "color:#a6adc8;font-size:11px;margin-bottom:4px;");
180
+ label.textContent = "State";
181
+ const attempt = createStateRow("debug-state-attempt", "attempt");
182
+ const waiting = createStateRow("debug-state-waiting", "isWaiting");
183
+ const fallback = createStateRow("debug-state-fallback", "isFallbackShown");
184
+ section.append(label, attempt.row, waiting.row, fallback.row);
185
+ unsubscribers.push(subscribeToState((state) => {
186
+ attempt.value.textContent = String(state.currentAttempt);
187
+ waiting.value.textContent = String(state.isWaiting);
188
+ fallback.value.textContent = String(state.isFallbackShown);
189
+ }));
190
+ return section;
195
191
  }
196
192
  function el(tag, css, testId) {
197
- const e = document.createElement(tag);
198
- e.setAttribute("style", css);
199
- if (testId) {
200
- e.dataset.testid = testId;
201
- }
202
- return e;
193
+ const e = document.createElement(tag);
194
+ e.setAttribute("style", css);
195
+ if (testId) e.dataset.testid = testId;
196
+ return e;
203
197
  }
204
198
  function formatTime(timestamp) {
205
- return new Date(timestamp).toLocaleTimeString();
199
+ return new Date(timestamp).toLocaleTimeString();
206
200
  }
207
201
  function getButtonCss(status) {
208
- const base = "border:1px solid #45475a;border-radius:4px;color:#cdd6f4;cursor:pointer;font-family:monospace;font-size:12px;margin-top:6px;padding:6px 10px;text-align:left;width:100%;";
209
- switch (status) {
210
- case "loading": {
211
- return base + "background:#585b70;opacity:0.7;";
212
- }
213
- case "triggered": {
214
- return base + "background:#a6e3a1;color:#1e1e2e;";
215
- }
216
- default: {
217
- return base + "background:#313244;";
218
- }
219
- }
202
+ const base = "border:1px solid #45475a;border-radius:4px;color:#cdd6f4;cursor:pointer;font-family:monospace;font-size:12px;margin-top:6px;padding:6px 10px;text-align:left;width:100%;";
203
+ switch (status) {
204
+ case "loading": return base + "background:#585b70;opacity:0.7;";
205
+ case "triggered": return base + "background:#a6e3a1;color:#1e1e2e;";
206
+ default: return base + "background:#313244;";
207
+ }
220
208
  }
221
209
  function getButtonLabel(label, status) {
222
- switch (status) {
223
- case "loading": {
224
- return `${label}...`;
225
- }
226
- case "triggered": {
227
- return `${label} \u2713`;
228
- }
229
- default: {
230
- return label;
231
- }
232
- }
210
+ switch (status) {
211
+ case "loading": return `${label}...`;
212
+ case "triggered": return `${label} \u2713`;
213
+ default: return label;
214
+ }
233
215
  }
234
216
  function wireEventSubscription(params) {
235
- const { clearBtn, countSpan, eventList, unsubscribers } = params;
236
- let history = [];
237
- function render() {
238
- countSpan.textContent = `Event History (${String(history.length)})`;
239
- eventList.innerHTML = "";
240
- for (const entry of history) {
241
- const row = el("div", "border-bottom:1px solid #313244;padding:3px 0;", "debug-event-entry");
242
- const time = el("span", "color:#585b70;margin-right:6px;");
243
- time.textContent = formatTime(entry.timestamp);
244
- const name = el("span", "color:#89b4fa;");
245
- name.textContent = entry.event.name;
246
- row.append(time, name);
247
- eventList.append(row);
248
- }
249
- }
250
- clearBtn.addEventListener("click", () => {
251
- history = [];
252
- render();
253
- });
254
- unsubscribers.push(
255
- subscribe((event) => {
256
- history = [...history, { event, timestamp: Date.now() }];
257
- if (history.length > MAX_EVENT_HISTORY) {
258
- history = history.slice(-MAX_EVENT_HISTORY);
259
- }
260
- render();
261
- })
262
- );
217
+ const { clearBtn, countSpan, eventList, unsubscribers } = params;
218
+ let history = [];
219
+ function render() {
220
+ countSpan.textContent = `Event History (${String(history.length)})`;
221
+ eventList.innerHTML = "";
222
+ for (const entry of history) {
223
+ const row = el("div", "border-bottom:1px solid #313244;padding:3px 0;", "debug-event-entry");
224
+ const time = el("span", "color:#585b70;margin-right:6px;");
225
+ time.textContent = formatTime(entry.timestamp);
226
+ const name = el("span", "color:#89b4fa;");
227
+ name.textContent = entry.event.name;
228
+ row.append(time, name);
229
+ eventList.append(row);
230
+ }
231
+ }
232
+ clearBtn.addEventListener("click", () => {
233
+ history = [];
234
+ render();
235
+ });
236
+ unsubscribers.push(subscribe((event) => {
237
+ history = [...history, {
238
+ event,
239
+ timestamp: Date.now()
240
+ }];
241
+ if (history.length > MAX_EVENT_HISTORY) history = history.slice(-MAX_EVENT_HISTORY);
242
+ render();
243
+ }));
263
244
  }
264
- export {
265
- createDebugger
266
- };
245
+ //#endregion
246
+ export { createDebugger };
@@ -1,8 +1,66 @@
1
- export { startVersionCheck, stopVersionCheck } from "../common/checkVersion";
2
- export { ForceRetryError } from "../common/errors/ForceRetryError";
3
- export { setTranslations } from "../common/i18n";
4
- export { dismissSpinner, getSpinnerHtml, showSpinner } from "../common/spinner";
5
- export { recommendedSetup } from "./recommendedSetup";
6
- export type { RecommendedSetupOptions } from "./recommendedSetup";
7
- export { getState, subscribeToState } from "./state";
8
- export type { SpaGuardState } from "./state";
1
+ import { g as UnsubscribeFn } from "../types-DrN8pgyc.mjs";
2
+ import { i as getSpinnerHtml, l as setTranslations, o as showSpinner, r as dismissSpinner } from "../spinner-X23gI09z.mjs";
3
+ import { t as ForceRetryError } from "../ForceRetryError-BWLv3UVK.mjs";
4
+
5
+ //#region src/common/checkVersion.d.ts
6
+ declare const startVersionCheck: () => void;
7
+ declare const stopVersionCheck: () => void;
8
+ //#endregion
9
+ //#region src/runtime/recommendedSetup.d.ts
10
+ interface RecommendedSetupOptions {
11
+ /**
12
+ * Healthy boot handling strategy.
13
+ *
14
+ * - `"auto"` (default): if retry URL params are present, mark healthy boot
15
+ * after a grace period and only when orchestrator is still idle.
16
+ * - `"manual"`: never auto-mark; call `markRetryHealthyBoot()` yourself.
17
+ * - `"off"` / `false`: disable healthy boot handling.
18
+ */
19
+ healthyBoot?: RecommendedSetupHealthyBoot;
20
+ /**
21
+ * Whether to start version checking.
22
+ * @default true
23
+ */
24
+ versionCheck?: boolean;
25
+ }
26
+ interface HealthyBootAutoConfig {
27
+ /**
28
+ * Delay before auto-marking healthy boot when retry params are present in URL.
29
+ * @default dynamic:
30
+ * max(5000, max(reloadDelays)+1000, sum(lazyRetry.retryDelays)+1000)
31
+ */
32
+ graceMs?: number;
33
+ /**
34
+ * Explicit mode for object config.
35
+ * @default "auto"
36
+ */
37
+ mode?: "auto";
38
+ }
39
+ type RecommendedSetupHealthyBoot = "auto" | "manual" | "off" | false | HealthyBootAutoConfig;
40
+ /**
41
+ * Enable recommended runtime features with sensible defaults.
42
+ * Returns a cleanup function that tears down all started features.
43
+ */
44
+ declare const recommendedSetup: (overrides?: RecommendedSetupOptions) => (() => void);
45
+ //#endregion
46
+ //#region src/runtime/state.d.ts
47
+ interface SpaGuardState {
48
+ currentAttempt: number;
49
+ isFallbackShown: boolean;
50
+ isWaiting: boolean;
51
+ /**
52
+ * ID of the previous retry cycle before reset.
53
+ * Undefined if no reset has occurred yet.
54
+ */
55
+ lastResetRetryId?: string;
56
+ /**
57
+ * Timestamp of the last retry cycle reset.
58
+ * Undefined if no reset has occurred yet.
59
+ */
60
+ lastRetryResetTime?: number;
61
+ }
62
+ type StateSubscriber = (state: SpaGuardState) => void;
63
+ declare const getState: () => SpaGuardState;
64
+ declare const subscribeToState: (cb: StateSubscriber) => UnsubscribeFn;
65
+ //#endregion
66
+ export { ForceRetryError, type RecommendedSetupOptions, type SpaGuardState, dismissSpinner, getSpinnerHtml, getState, recommendedSetup, setTranslations, showSpinner, startVersionCheck, stopVersionCheck, subscribeToState };