@ai-matrx/content-ir-react 0.9.3 → 0.10.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/CHANGELOG.md CHANGED
@@ -1,5 +1,25 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.10.0 — 2026-08-31
4
+
5
+ - **A failed list load is not truth — retry, then settle.** 0.9.0's posture
6
+ ("a failed load still settles") met the auth-hydration race and lost: a
7
+ fresh tab's first `ensureWarm` fires before the Supabase session restores,
8
+ the read runs as `anon`, RLS answers 42501, and settling on that failure
9
+ declared an EMPTY resolver to be the loaded state of the world — every kind
10
+ on the page stamped "unregistered" while the rows sat one authenticated
11
+ retry away. `ensureWarm` now retries with backoff (1s / 5s / 15s), stays
12
+ UNSETTLED across failures (the route keeps holding — no verdict from a
13
+ failure), resets the counter on success, and settles only when the retries
14
+ are exhausted — a genuinely dead backend still ends at the announced
15
+ generic-floor stand-in, never an eternal hold. A success or `replaceDbRows`
16
+ cancels any pending retry.
17
+
18
+ Live case: /chat on a fresh tab rendered `agent_mandate_specification` as a
19
+ raw JSON fence forever; the identical conversation in an already-warm window
20
+ panel rendered its workbench component. Pinned by two new tests (the race
21
+ with recovery, and the dead-backend bound).
22
+
3
23
  ## 0.9.3 — 2026-08-31
4
24
 
5
25
  - **Dependency chase — carries `@ai-matrx/content-ir` 0.10.3** (inline objects
package/dist/index.cjs CHANGED
@@ -126,11 +126,15 @@ function errorFields(error) {
126
126
  ...error.stack === void 0 ? {} : { stack: error.stack }
127
127
  };
128
128
  }
129
+ var WARM_RETRY_DELAYS_MS = [1e3, 5e3, 15e3];
129
130
  var ComponentResolver = class {
130
131
  compiled = null;
131
132
  db = /* @__PURE__ */ new Map();
132
133
  warmPromise = null;
133
134
  warmFailureLogged = false;
135
+ /** Consecutive warm-load failures — indexes WARM_RETRY_DELAYS_MS. */
136
+ warmFailures = 0;
137
+ warmRetryTimer = null;
134
138
  /**
135
139
  * True once a list load has RUN TO COMPLETION (success or failure), or once
136
140
  * any rows have been ingested by any tier. Until then `resolve()` answering
@@ -397,6 +401,11 @@ var ComponentResolver = class {
397
401
  this.warmPromise = loadAll().then((rows) => {
398
402
  this.ingestDbRows(rows);
399
403
  this.settled = true;
404
+ this.warmFailures = 0;
405
+ if (this.warmRetryTimer) {
406
+ clearTimeout(this.warmRetryTimer);
407
+ this.warmRetryTimer = null;
408
+ }
400
409
  }).catch((error) => {
401
410
  const message = `component-resolver warm load failed (compiled bootstrap still serving): ${describe(error)}`;
402
411
  if (!this.warmFailureLogged) {
@@ -409,8 +418,17 @@ var ComponentResolver = class {
409
418
  ...errorFields(error),
410
419
  raw: error
411
420
  });
412
- this.settled = true;
413
421
  this.warmPromise = null;
422
+ this.warmFailures += 1;
423
+ const delay = WARM_RETRY_DELAYS_MS[this.warmFailures - 1] ?? null;
424
+ if (delay === null) {
425
+ this.settled = true;
426
+ } else if (!this.warmRetryTimer) {
427
+ this.warmRetryTimer = setTimeout(() => {
428
+ this.warmRetryTimer = null;
429
+ void this.ensureWarm();
430
+ }, delay);
431
+ }
414
432
  });
415
433
  }
416
434
  return this.warmPromise;