svelte-realtime 0.6.0-next.1 → 0.6.0-next.2
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/client.js +36 -3
- package/package.json +1 -1
package/client.js
CHANGED
|
@@ -253,13 +253,37 @@ const _healthStore = writable(/** @type {'healthy' | 'degraded'} */ ('healthy'))
|
|
|
253
253
|
/** @type {(() => void) | null} */
|
|
254
254
|
let _healthUnsub = null;
|
|
255
255
|
|
|
256
|
+
// Two independent inputs OR into the single health state: a server-pushed
|
|
257
|
+
// degraded/recovered event on the system topic, and the connection's local
|
|
258
|
+
// internal flow-control pressure (a queued/refused flow-controlled send).
|
|
259
|
+
// Tracked separately so neither input clobbers the other - health is degraded
|
|
260
|
+
// while EITHER is degraded, healthy only when BOTH are clear.
|
|
261
|
+
let _healthServerDegraded = false;
|
|
262
|
+
let _healthFlowDegraded = false;
|
|
263
|
+
|
|
264
|
+
function _recomputeHealth() {
|
|
265
|
+
_healthStore.set(_healthServerDegraded || _healthFlowDegraded ? 'degraded' : 'healthy');
|
|
266
|
+
}
|
|
267
|
+
|
|
256
268
|
function _ensureHealthSubscription() {
|
|
257
269
|
if (_healthUnsub) return;
|
|
258
|
-
|
|
270
|
+
const offTopic = on(_HEALTH_TOPIC).subscribe((envelope) => {
|
|
259
271
|
if (!envelope) return;
|
|
260
|
-
if (envelope.event === 'degraded')
|
|
261
|
-
else if (envelope.event === 'recovered')
|
|
272
|
+
if (envelope.event === 'degraded') { _healthServerDegraded = true; _recomputeHealth(); }
|
|
273
|
+
else if (envelope.event === 'recovered') { _healthServerDegraded = false; _recomputeHealth(); }
|
|
262
274
|
});
|
|
275
|
+
// Fold the connection's internal flow-control health in as a second,
|
|
276
|
+
// OR-ed input. A boolean is the only thing that crosses this accessor;
|
|
277
|
+
// no internal accounting value surfaces. Older adapter connections that
|
|
278
|
+
// predate the accessor simply do not contribute this input.
|
|
279
|
+
let offFlow = () => {};
|
|
280
|
+
try {
|
|
281
|
+
const conn = _connect();
|
|
282
|
+
if (conn && typeof conn._onLeaseDegraded === 'function') {
|
|
283
|
+
offFlow = conn._onLeaseDegraded((d) => { _healthFlowDegraded = !!d; _recomputeHealth(); });
|
|
284
|
+
}
|
|
285
|
+
} catch { /* connection not configured yet; flow health stays clear */ }
|
|
286
|
+
_healthUnsub = () => { offTopic(); offFlow(); };
|
|
263
287
|
}
|
|
264
288
|
|
|
265
289
|
/**
|
|
@@ -297,9 +321,18 @@ export function _resetHealth() {
|
|
|
297
321
|
_healthUnsub();
|
|
298
322
|
_healthUnsub = null;
|
|
299
323
|
}
|
|
324
|
+
_healthServerDegraded = false;
|
|
325
|
+
_healthFlowDegraded = false;
|
|
300
326
|
_healthStore.set('healthy');
|
|
301
327
|
}
|
|
302
328
|
|
|
329
|
+
// Flow control is owned end to end by the adapter connection's send gate: it
|
|
330
|
+
// advertises the capability, paces its own flow-controlled sends against the
|
|
331
|
+
// server's window, and reports a single degraded boolean. The realtime layer
|
|
332
|
+
// consumes that boolean through conn._onLeaseDegraded in
|
|
333
|
+
// _ensureHealthSubscription above and ORs it into realtime.health. There is no
|
|
334
|
+
// realtime-owned mirror of the gate - a second copy would only drift.
|
|
335
|
+
|
|
303
336
|
function _registerTopicErrorSetter(topic, setError) {
|
|
304
337
|
let set = _streamErrorByTopic.get(topic);
|
|
305
338
|
if (!set) { set = new Set(); _streamErrorByTopic.set(topic, set); }
|