@lmzhen/dsh-evolution-state-storage 0.3.68 → 0.3.69

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/lib/index.js CHANGED
@@ -180,8 +180,15 @@ const REVIEW_STATE_SESSION_CAP = 500;
180
180
  * approved list and a capability cannot be re-submitted for the same package,
181
181
  * so eviction would make an approved capability permanently unactivatable.
182
182
  * Ordering = oldest `resolvedAt` first; a missing or unparseable timestamp sorts
183
- * LAST (json parity, v16) an unknown time must never make a record the victim,
184
- * and pending/executing rows are live work that is never trimmed.
183
+ * LAST (json parity, v16), and pending/executing rows are live work that is
184
+ * never trimmed. v28 G2.4 (STATE-03) the previous wording promised "an
185
+ * unknown time must never make a record the victim"; that is only true while
186
+ * the overflow fits within the KNOWN-timestamp records. When the overflow
187
+ * exceeds them (corruption-level data: most resolved rows with broken
188
+ * timestamps), `slice` necessarily reaches into the unknown-timestamp tail —
189
+ * the cap must be enforced, so there is no alternative. The guarantee is
190
+ * therefore: unknown-timestamp records are evicted LAST, after every known
191
+ * timestamp, in insertion order among themselves (Array#sort stability).
185
192
  *
186
193
  * @param records - every pending record currently in the live table.
187
194
  * @param cap - how many resolved records may be kept.
@@ -220,6 +227,9 @@ var EvolutionStateStorageRegistry = class extends Service {
220
227
  providers = /* @__PURE__ */ new Map();
221
228
  /** C-7 (v18): per-name dispose, mirroring the evolution-io registry. */
222
229
  disposals = /* @__PURE__ */ new Map();
230
+ /** v28 G3.1 (STATE-04): the multi-provider warn fires once per ambiguous
231
+ * period, not once per state op (provider() runs on every read/write). */
232
+ ambiguousWarned = false;
223
233
  constructor(ctx) {
224
234
  super(ctx, "evolutionStateStorage");
225
235
  }
@@ -252,12 +262,19 @@ var EvolutionStateStorageRegistry = class extends Service {
252
262
  }
253
263
  provider(name) {
254
264
  if (name) {
265
+ this.ambiguousWarned = false;
255
266
  const provider = this.providers.get(name);
256
267
  if (provider) return provider;
257
268
  throw new Error(`evolution state storage provider "${name}" is not registered`);
258
269
  }
259
270
  const first = this.providers.values().next().value;
260
271
  if (!first) throw new Error("no evolution state storage provider registered; mount @lmzhen/dsh-evolution-state-json or @lmzhen/dsh-evolution-state-domain");
272
+ if (this.providers.size > 1) {
273
+ if (!this.ambiguousWarned) {
274
+ this.ambiguousWarned = true;
275
+ this.ctx.logger.warn(`evolution state storage: ${this.providers.size} providers registered (${[...this.providers.keys()].join(", ")}), none pinned — the effective provider is "${first.name}" (registration order). Existing state under the other provider is now invisible. Pin config: { provider: json|domain } on the evolution-state row to make the choice explicit.`);
276
+ }
277
+ } else this.ambiguousWarned = false;
261
278
  return first;
262
279
  }
263
280
  };
@@ -70,8 +70,15 @@ export declare const REVIEW_STATE_SESSION_CAP = 500;
70
70
  * approved list and a capability cannot be re-submitted for the same package,
71
71
  * so eviction would make an approved capability permanently unactivatable.
72
72
  * Ordering = oldest `resolvedAt` first; a missing or unparseable timestamp sorts
73
- * LAST (json parity, v16) an unknown time must never make a record the victim,
74
- * and pending/executing rows are live work that is never trimmed.
73
+ * LAST (json parity, v16), and pending/executing rows are live work that is
74
+ * never trimmed. v28 G2.4 (STATE-03) the previous wording promised "an
75
+ * unknown time must never make a record the victim"; that is only true while
76
+ * the overflow fits within the KNOWN-timestamp records. When the overflow
77
+ * exceeds them (corruption-level data: most resolved rows with broken
78
+ * timestamps), `slice` necessarily reaches into the unknown-timestamp tail —
79
+ * the cap must be enforced, so there is no alternative. The guarantee is
80
+ * therefore: unknown-timestamp records are evicted LAST, after every known
81
+ * timestamp, in insertion order among themselves (Array#sort stability).
75
82
  *
76
83
  * @param records - every pending record currently in the live table.
77
84
  * @param cap - how many resolved records may be kept.
@@ -181,6 +188,9 @@ export declare class EvolutionStateStorageRegistry extends Service {
181
188
  private readonly providers;
182
189
  /** C-7 (v18): per-name dispose, mirroring the evolution-io registry. */
183
190
  private readonly disposals;
191
+ /** v28 G3.1 (STATE-04): the multi-provider warn fires once per ambiguous
192
+ * period, not once per state op (provider() runs on every read/write). */
193
+ private ambiguousWarned;
184
194
  constructor(ctx: Context);
185
195
  /** C-7 (v18): re-registering the IDENTICAL provider object is idempotent and
186
196
  * returns the original dispose (HMR / re-mounted row); a DIFFERENT object
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@lmzhen/dsh-evolution-state-storage",
3
3
  "description": "Provider registry seam for durable evolution state (community build)",
4
- "version": "0.3.68",
4
+ "version": "0.3.69",
5
5
  "publishConfig": {
6
6
  "access": "public"
7
7
  },