@ai-matrx/records 0.86.2 → 0.87.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/dist/index.d.cts CHANGED
@@ -364,40 +364,6 @@ type MergeFieldResolution = {
364
364
  reason: string;
365
365
  };
366
366
 
367
- /**
368
- * THE CLIENT OPERATION LEDGER — how a browser recognises the echo of its own write.
369
- *
370
- * Every private-channel notice the record store broadcasts reaches EVERY browser watching that
371
- * Table, including the one that caused it. Until now the writer had no way to tell its own
372
- * change from a colleague's: the notice carried ids and nothing about who moved them, so
373
- * `recordsRealtimePort.ts` declared `acceptEchoFromSelf: true` and the writer re-read a page it
374
- * had already updated. It was named honestly rather than faked, and this is the other half.
375
- *
376
- * THE SHAPE. Every write through `RecordsClient` mints a uuid, sends it to the store as the
377
- * platform envelope key `_op_id`, and remembers it here. The store lifts that key out before
378
- * storage — it is never written onto the record — carries it on the change-feed row, and puts
379
- * it in the notice as `op_id`. A notice whose `op_id` is in this ledger is this browser's own
380
- * echo and is dropped.
381
- *
382
- * WHY A TIME WINDOW RATHER THAN A DELETE-ON-MATCH. One write can produce MORE THAN ONE notice:
383
- * a record write that also moves a column produces a `record` notice and a `field` notice, and
384
- * a statement touching two Tables produces one per Table. Forgetting an op the first time it
385
- * came back would make the second notice look like somebody else's and cost the re-read this
386
- * exists to avoid. So an op is remembered for a window and expires on its own.
387
- *
388
- * 🚨 THE WINDOW IS A CORRECTNESS BOUNDARY, NOT A TUNING KNOB, AND IT FAILS IN THE SAFE
389
- * DIRECTION BY CONSTRUCTION. Too SHORT and a late echo is treated as a stranger's change: one
390
- * extra read of a page that is already correct — invisible. Too LONG and a stranger's change
391
- * that happened to reuse our uuid would be dropped — which cannot happen, because it is a v4
392
- * uuid nobody else has ever seen. The only real cost of a long window is memory, so it is
393
- * bounded by COUNT as well as by time.
394
- *
395
- * WHAT THIS IS NOT. It is not a replacement for the store's optimistic concurrency, and it
396
- * never decides what is true — a dropped echo means "I already know about this", and every
397
- * path that could be wrong about that (a reconnect, a tab wake, a notice with no `op_id` at
398
- * all) re-reads through the door as it always did.
399
- */
400
-
401
367
  /**
402
368
  * Mint the id for one client operation and remember it as ours.
403
369
  *
package/dist/index.d.ts CHANGED
@@ -364,40 +364,6 @@ type MergeFieldResolution = {
364
364
  reason: string;
365
365
  };
366
366
 
367
- /**
368
- * THE CLIENT OPERATION LEDGER — how a browser recognises the echo of its own write.
369
- *
370
- * Every private-channel notice the record store broadcasts reaches EVERY browser watching that
371
- * Table, including the one that caused it. Until now the writer had no way to tell its own
372
- * change from a colleague's: the notice carried ids and nothing about who moved them, so
373
- * `recordsRealtimePort.ts` declared `acceptEchoFromSelf: true` and the writer re-read a page it
374
- * had already updated. It was named honestly rather than faked, and this is the other half.
375
- *
376
- * THE SHAPE. Every write through `RecordsClient` mints a uuid, sends it to the store as the
377
- * platform envelope key `_op_id`, and remembers it here. The store lifts that key out before
378
- * storage — it is never written onto the record — carries it on the change-feed row, and puts
379
- * it in the notice as `op_id`. A notice whose `op_id` is in this ledger is this browser's own
380
- * echo and is dropped.
381
- *
382
- * WHY A TIME WINDOW RATHER THAN A DELETE-ON-MATCH. One write can produce MORE THAN ONE notice:
383
- * a record write that also moves a column produces a `record` notice and a `field` notice, and
384
- * a statement touching two Tables produces one per Table. Forgetting an op the first time it
385
- * came back would make the second notice look like somebody else's and cost the re-read this
386
- * exists to avoid. So an op is remembered for a window and expires on its own.
387
- *
388
- * 🚨 THE WINDOW IS A CORRECTNESS BOUNDARY, NOT A TUNING KNOB, AND IT FAILS IN THE SAFE
389
- * DIRECTION BY CONSTRUCTION. Too SHORT and a late echo is treated as a stranger's change: one
390
- * extra read of a page that is already correct — invisible. Too LONG and a stranger's change
391
- * that happened to reuse our uuid would be dropped — which cannot happen, because it is a v4
392
- * uuid nobody else has ever seen. The only real cost of a long window is memory, so it is
393
- * bounded by COUNT as well as by time.
394
- *
395
- * WHAT THIS IS NOT. It is not a replacement for the store's optimistic concurrency, and it
396
- * never decides what is true — a dropped echo means "I already know about this", and every
397
- * path that could be wrong about that (a reconnect, a tab wake, a notice with no `op_id` at
398
- * all) re-reads through the door as it always did.
399
- */
400
-
401
367
  /**
402
368
  * Mint the id for one client operation and remember it as ours.
403
369
  *
package/dist/index.js CHANGED
@@ -2151,9 +2151,10 @@ function sourceArchivedOf(value) {
2151
2151
  }
2152
2152
 
2153
2153
  // src/ops.ts
2154
+ import { globalSlot } from "@ai-matrx/kit/global-slot";
2154
2155
  var REMEMBER_MS = 3e4;
2155
2156
  var REMEMBER_MAX = 500;
2156
- var ours = /* @__PURE__ */ new Map();
2157
+ var ours = globalSlot("ai-matrx.records.op-ledger", () => /* @__PURE__ */ new Map());
2157
2158
  function trim(now) {
2158
2159
  for (const [id, at] of ours) {
2159
2160
  if (now - at <= REMEMBER_MS) break;