@floegence/flowersec-core 0.19.6 → 0.19.7

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.
@@ -116,18 +116,19 @@ async function uninstallConflictingServiceWorkers(targetWindow, conflicts) {
116
116
  }
117
117
  }
118
118
  }
119
- function triggerRepairNavigation(navigationWindow, repair) {
119
+ function triggerRepairNavigation(navigationWindow, repair, attempt) {
120
120
  const queryKey = String(repair?.queryKey ?? "_flowersec_sw_repair").trim() || "_flowersec_sw_repair";
121
121
  const maxAttempts = Math.max(0, Math.floor(repair?.maxAttempts ?? 2));
122
122
  const strategy = repair?.strategy ?? "replace";
123
- const attempt = parseRepairAttemptFromHref(navigationWindow.location.href, queryKey);
124
- if (attempt >= maxAttempts)
123
+ const hrefAttempt = parseRepairAttemptFromHref(navigationWindow.location.href, queryKey);
124
+ const effectiveAttempt = Math.max(attempt, hrefAttempt);
125
+ if (effectiveAttempt >= maxAttempts)
125
126
  return false;
126
127
  if (strategy === "reload") {
127
128
  navigationWindow.location.reload();
128
129
  return true;
129
130
  }
130
- const next = buildHrefWithRepairAttempt(navigationWindow.location.href, queryKey, attempt + 1);
131
+ const next = buildHrefWithRepairAttempt(navigationWindow.location.href, queryKey, effectiveAttempt + 1);
131
132
  navigationWindow.location.replace(next);
132
133
  return true;
133
134
  }
@@ -144,6 +145,7 @@ export function createServiceWorkerControllerGuard(opts) {
144
145
  let disposed = false;
145
146
  let monitorHandler = null;
146
147
  let lastMonitorRepairAt = 0;
148
+ let repairAttempts = 0;
147
149
  const handleMismatch = async (stage) => {
148
150
  const actualScriptURL = String(getServiceWorker(targetWindow)?.controller?.scriptURL ?? "").trim();
149
151
  const ctx = {
@@ -155,7 +157,10 @@ export function createServiceWorkerControllerGuard(opts) {
155
157
  if (action === "ignore")
156
158
  return "ignored";
157
159
  await uninstallConflictingServiceWorkers(targetWindow, opts.conflicts);
158
- return triggerRepairNavigation(navigationWindow, opts.repair) ? "repaired" : "skipped";
160
+ const repaired = triggerRepairNavigation(navigationWindow, opts.repair, repairAttempts);
161
+ if (repaired)
162
+ repairAttempts += 1;
163
+ return repaired ? "repaired" : "skipped";
159
164
  };
160
165
  const attachMonitor = () => {
161
166
  if (!monitorEnabled || monitorHandler != null)
@@ -1,4 +1,4 @@
1
- import { withObserverContext } from "../observability/observer.js";
1
+ import { emitObserverDiagnostic, withObserverContext } from "../observability/observer.js";
2
2
  function normalizeAutoReconnect(cfg) {
3
3
  if (!cfg?.enabled) {
4
4
  return {
@@ -178,6 +178,13 @@ export function createReconnectManager() {
178
178
  return;
179
179
  attempts += 1;
180
180
  attemptSeq += 1;
181
+ emitObserverDiagnostic(withObserverContext(cfg.observer, { attemptSeq }), {
182
+ path: "auto",
183
+ stage: "reconnect",
184
+ code_domain: "event",
185
+ code: attempts === 1 ? "reconnect_attempt" : "reconnect_retry_attempt",
186
+ result: "retry",
187
+ });
181
188
  try {
182
189
  const client = await connectOnce(t, cfg, attemptSeq);
183
190
  if (t !== token) {
@@ -199,6 +206,13 @@ export function createReconnectManager() {
199
206
  return;
200
207
  }
201
208
  setState({ status: "connected", client, error: null });
209
+ emitObserverDiagnostic(withObserverContext(cfg.observer, { attemptSeq }), {
210
+ path: "auto",
211
+ stage: "reconnect",
212
+ code_domain: "event",
213
+ code: "reconnect_connected",
214
+ result: "ok",
215
+ });
202
216
  return;
203
217
  }
204
218
  catch (err) {
@@ -210,10 +224,24 @@ export function createReconnectManager() {
210
224
  const canRetry = ar.enabled && attempts < ar.maxAttempts;
211
225
  if (!canRetry) {
212
226
  setState({ status: "error", error: e, client: null });
227
+ emitObserverDiagnostic(withObserverContext(cfg.observer, { attemptSeq }), {
228
+ path: "auto",
229
+ stage: "reconnect",
230
+ code_domain: "event",
231
+ code: "reconnect_exhausted",
232
+ result: "fail",
233
+ });
213
234
  throw e;
214
235
  }
215
236
  setState({ status: "connecting", error: e, client: null });
216
237
  const delay = backoffDelayMs(attempts - 1, ar);
238
+ emitObserverDiagnostic(withObserverContext(cfg.observer, { attemptSeq }), {
239
+ path: "auto",
240
+ stage: "reconnect",
241
+ code_domain: "event",
242
+ code: "reconnect_scheduled",
243
+ result: "retry",
244
+ });
217
245
  await sleep(delay);
218
246
  }
219
247
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@floegence/flowersec-core",
3
- "version": "0.19.6",
3
+ "version": "0.19.7",
4
4
  "description": "Flowersec core TypeScript library (browser-friendly E2EE + multiplexing over WebSocket).",
5
5
  "license": "MIT",
6
6
  "repository": {