@contember/bindx 0.1.46 → 0.1.47

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.
Files changed (118) hide show
  1. package/dist/core/ActionDispatcher.d.ts +4 -1
  2. package/dist/core/ActionDispatcher.d.ts.map +1 -1
  3. package/dist/core/actions.d.ts +7 -1
  4. package/dist/core/actions.d.ts.map +1 -1
  5. package/dist/events/EventEmitter.d.ts +13 -1
  6. package/dist/events/EventEmitter.d.ts.map +1 -1
  7. package/dist/handles/BaseHandle.d.ts +14 -3
  8. package/dist/handles/BaseHandle.d.ts.map +1 -1
  9. package/dist/handles/EntityHandle.d.ts +14 -5
  10. package/dist/handles/EntityHandle.d.ts.map +1 -1
  11. package/dist/handles/FieldHandle.d.ts +11 -4
  12. package/dist/handles/FieldHandle.d.ts.map +1 -1
  13. package/dist/handles/HasManyListHandle.d.ts +36 -2
  14. package/dist/handles/HasManyListHandle.d.ts.map +1 -1
  15. package/dist/handles/HasOneHandle.d.ts +52 -9
  16. package/dist/handles/HasOneHandle.d.ts.map +1 -1
  17. package/dist/handles/PlaceholderHandle.d.ts +25 -13
  18. package/dist/handles/PlaceholderHandle.d.ts.map +1 -1
  19. package/dist/handles/index.d.ts +1 -1
  20. package/dist/handles/index.d.ts.map +1 -1
  21. package/dist/handles/proxyFactory.d.ts +7 -1
  22. package/dist/handles/proxyFactory.d.ts.map +1 -1
  23. package/dist/handles/types.d.ts +33 -0
  24. package/dist/handles/types.d.ts.map +1 -1
  25. package/dist/index.d.ts +3 -3
  26. package/dist/index.d.ts.map +1 -1
  27. package/dist/persistence/BatchPersister.d.ts +53 -37
  28. package/dist/persistence/BatchPersister.d.ts.map +1 -1
  29. package/dist/persistence/ChangeRegistry.d.ts +15 -0
  30. package/dist/persistence/ChangeRegistry.d.ts.map +1 -1
  31. package/dist/persistence/MutationCollector.d.ts +106 -3
  32. package/dist/persistence/MutationCollector.d.ts.map +1 -1
  33. package/dist/persistence/PersistExecution.d.ts +26 -0
  34. package/dist/persistence/PersistExecution.d.ts.map +1 -0
  35. package/dist/persistence/types.d.ts +8 -2
  36. package/dist/persistence/types.d.ts.map +1 -1
  37. package/dist/store/EntityMetaStore.d.ts +32 -10
  38. package/dist/store/EntityMetaStore.d.ts.map +1 -1
  39. package/dist/store/EntitySnapshotStore.d.ts +50 -3
  40. package/dist/store/EntitySnapshotStore.d.ts.map +1 -1
  41. package/dist/store/ErrorStore.d.ts +3 -2
  42. package/dist/store/ErrorStore.d.ts.map +1 -1
  43. package/dist/store/HasManyStore.d.ts +214 -0
  44. package/dist/store/HasManyStore.d.ts.map +1 -0
  45. package/dist/store/HasOneStore.d.ts +159 -0
  46. package/dist/store/HasOneStore.d.ts.map +1 -0
  47. package/dist/store/ReachabilityAnalyzer.d.ts +19 -0
  48. package/dist/store/ReachabilityAnalyzer.d.ts.map +1 -1
  49. package/dist/store/RekeyOrchestrator.d.ts +76 -0
  50. package/dist/store/RekeyOrchestrator.d.ts.map +1 -0
  51. package/dist/store/RelationEdgeIndex.d.ts +34 -0
  52. package/dist/store/RelationEdgeIndex.d.ts.map +1 -0
  53. package/dist/store/RelationStore.d.ts +74 -137
  54. package/dist/store/RelationStore.d.ts.map +1 -1
  55. package/dist/store/RootRegistry.d.ts +25 -4
  56. package/dist/store/RootRegistry.d.ts.map +1 -1
  57. package/dist/store/SnapshotStore.d.ts +137 -13
  58. package/dist/store/SnapshotStore.d.ts.map +1 -1
  59. package/dist/store/SubscriptionManager.d.ts +63 -14
  60. package/dist/store/SubscriptionManager.d.ts.map +1 -1
  61. package/dist/store/TouchedStore.d.ts +3 -2
  62. package/dist/store/TouchedStore.d.ts.map +1 -1
  63. package/dist/store/relationKey.d.ts +15 -0
  64. package/dist/store/relationKey.d.ts.map +1 -0
  65. package/dist/undo/UndoJournal.d.ts +133 -0
  66. package/dist/undo/UndoJournal.d.ts.map +1 -0
  67. package/dist/undo/UndoManager.d.ts +25 -82
  68. package/dist/undo/UndoManager.d.ts.map +1 -1
  69. package/dist/undo/UnrecordedWriteError.d.ts +16 -0
  70. package/dist/undo/UnrecordedWriteError.d.ts.map +1 -0
  71. package/dist/undo/index.d.ts +3 -1
  72. package/dist/undo/index.d.ts.map +1 -1
  73. package/dist/undo/rekeyJournalEntry.d.ts +20 -0
  74. package/dist/undo/rekeyJournalEntry.d.ts.map +1 -0
  75. package/dist/undo/types.d.ts +0 -48
  76. package/dist/undo/types.d.ts.map +1 -1
  77. package/package.json +2 -2
  78. package/src/core/ActionDispatcher.ts +56 -36
  79. package/src/core/actions.ts +8 -1
  80. package/src/events/EventEmitter.ts +78 -24
  81. package/src/handles/BaseHandle.ts +19 -2
  82. package/src/handles/EntityHandle.ts +48 -17
  83. package/src/handles/FieldHandle.ts +36 -10
  84. package/src/handles/HasManyListHandle.ts +120 -16
  85. package/src/handles/HasOneHandle.ts +177 -44
  86. package/src/handles/PlaceholderHandle.ts +184 -36
  87. package/src/handles/index.ts +3 -0
  88. package/src/handles/proxyFactory.ts +27 -0
  89. package/src/handles/types.ts +39 -0
  90. package/src/index.ts +4 -4
  91. package/src/persistence/BatchPersister.ts +810 -446
  92. package/src/persistence/ChangeRegistry.ts +27 -3
  93. package/src/persistence/MutationCollector.ts +265 -31
  94. package/src/persistence/PersistExecution.ts +217 -0
  95. package/src/persistence/types.ts +8 -2
  96. package/src/store/EntityMetaStore.ts +89 -45
  97. package/src/store/EntitySnapshotStore.ts +102 -19
  98. package/src/store/ErrorStore.ts +6 -5
  99. package/src/store/HasManyStore.ts +810 -0
  100. package/src/store/HasOneStore.ts +454 -0
  101. package/src/store/ReachabilityAnalyzer.ts +37 -0
  102. package/src/store/RekeyOrchestrator.ts +123 -0
  103. package/src/store/RelationEdgeIndex.ts +79 -0
  104. package/src/store/RelationStore.ts +176 -725
  105. package/src/store/RootRegistry.ts +50 -8
  106. package/src/store/SnapshotStore.ts +572 -101
  107. package/src/store/SubscriptionManager.ts +122 -75
  108. package/src/store/TouchedStore.ts +5 -2
  109. package/src/store/relationKey.ts +20 -0
  110. package/src/undo/UndoJournal.ts +258 -0
  111. package/src/undo/UndoManager.ts +151 -281
  112. package/src/undo/UnrecordedWriteError.ts +23 -0
  113. package/src/undo/index.ts +8 -7
  114. package/src/undo/rekeyJournalEntry.ts +145 -0
  115. package/src/undo/types.ts +0 -58
  116. package/dist/core/actionClassification.d.ts +0 -48
  117. package/dist/core/actionClassification.d.ts.map +0 -1
  118. package/src/core/actionClassification.ts +0 -199
@@ -81,6 +81,12 @@ export interface EntityPersistResult {
81
81
  readonly entityId: string;
82
82
  readonly operation: 'create' | 'update' | 'delete';
83
83
  readonly success: boolean;
84
+ /**
85
+ * The entity was deliberately not sent (vetoed by an `entity:persisting`
86
+ * interceptor). `success` is false, but it counts towards `skippedCount`,
87
+ * not `failedCount`.
88
+ */
89
+ readonly skipped?: true;
84
90
  readonly error?: PersistError;
85
91
  readonly fieldResults?: readonly FieldPersistResult[];
86
92
  /** Server-assigned ID for creates (when tempId was used) */
@@ -103,9 +109,9 @@ export interface PersistenceResult {
103
109
  readonly results: readonly EntityPersistResult[];
104
110
  /** Number of successfully persisted entities */
105
111
  readonly successCount: number;
106
- /** Number of failed entities */
112
+ /** Number of entities the server rejected — results with `success: false` and no `skipped` flag */
107
113
  readonly failedCount: number;
108
- /** Number of entities skipped (e.g., already in-flight) */
114
+ /** Number of entities not sent: already in-flight, or vetoed by an interceptor (listed in `results` with `skipped`) */
109
115
  readonly skippedCount: number;
110
116
  }
111
117
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/persistence/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/persistence/types.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,6 @@
1
1
  import type { LoadStatus } from './snapshots.js';
2
2
  import type { FieldError } from '../errors/types.js';
3
+ import type { RekeyContext, Rekeyable } from './RekeyOrchestrator.js';
3
4
  /**
4
5
  * Entity load state tracking.
5
6
  */
@@ -22,15 +23,36 @@ export interface EntityMeta {
22
23
  * Keys are pre-computed composite strings (e.g., "entityType:id").
23
24
  * Follows the same pattern as ErrorStore and RelationStore.
24
25
  */
25
- export declare class EntityMetaStore {
26
+ export declare class EntityMetaStore implements Rekeyable {
26
27
  /** Load states keyed by "entityType:id" */
27
28
  private readonly loadStates;
28
29
  /** Entity metadata keyed by "entityType:id" */
29
30
  private readonly entityMetas;
30
31
  /** Persisting status keyed by "entityType:id" */
31
32
  private readonly persistingEntities;
32
- /** Mapping from temp ID to persisted ID (keyed by "entityType:tempId") */
33
- private readonly tempToPersistedId;
33
+ /**
34
+ * Entities whose in-flight persist is pessimistic, keyed by "entityType:id".
35
+ * A subset of {@link persistingEntities}. While present, the entity is
36
+ * presented at its server baseline (see SnapshotStore.getPresentationSnapshot)
37
+ * even though its canonical data stays dirty.
38
+ */
39
+ private readonly pessimisticInFlight;
40
+ /**
41
+ * Monotonic counter bumped when reachability-relevant metadata changes —
42
+ * `existsOnServer` and `isPersisting` (which seed the reachability roots) plus
43
+ * entity removal/rekey. Load state and deletion scheduling do NOT bump it.
44
+ * Used by {@link ReachabilityAnalyzer} to memoize its walk.
45
+ */
46
+ private mutationVersion;
47
+ /**
48
+ * Monotonic counter bumped on EDITABLE-layer meta writes — deletion scheduling,
49
+ * the one undoable gesture this store owns. Server-baseline (`setExistsOnServer`),
50
+ * load/persist state, removal, rekey, import and clear deliberately do NOT bump
51
+ * it. Read by the undo write-guard (see UndoJournal).
52
+ */
53
+ private editableWriteVersion;
54
+ getMutationVersion(): number;
55
+ getEditableWriteVersion(): number;
34
56
  getLoadState(key: string): EntityLoadState | undefined;
35
57
  setLoadState(key: string, status: LoadStatus, error?: FieldError): void;
36
58
  clearLoadState(key: string): void;
@@ -41,18 +63,18 @@ export declare class EntityMetaStore {
41
63
  unscheduleForDeletion(key: string): void;
42
64
  isScheduledForDeletion(key: string): boolean;
43
65
  isPersisting(key: string): boolean;
44
- setPersisting(key: string, isPersisting: boolean): void;
45
- mapTempIdToPersistedId(key: string, persistedId: string): void;
46
- getPersistedId(key: string, id: string): string | null;
47
- isNewEntity(key: string, id: string): boolean;
66
+ setPersisting(key: string, isPersisting: boolean, pessimistic?: boolean): void;
67
+ isPessimisticInFlight(key: string): boolean;
48
68
  /**
49
- * Removes all metadata for an entity (load state, meta, persisting, temp mapping).
69
+ * Removes all metadata for an entity (load state, meta, persisting).
50
70
  */
51
71
  remove(key: string): void;
52
72
  /**
53
- * Moves all metadata from oldKey to newKey.
73
+ * Moves all metadata from the temp key to the persisted key. The entity has
74
+ * just been confirmed by the server, so it is also marked as existing there
75
+ * (this replaces the former separate mapTempIdToPersistedId step).
54
76
  */
55
- rekey(oldKey: string, newKey: string): void;
77
+ rekey(ctx: RekeyContext): void;
56
78
  exportMetas(keys: string[]): Map<string, EntityMeta>;
57
79
  importMetas(metas: Map<string, EntityMeta>): void;
58
80
  clear(): void;
@@ -1 +1 @@
1
- {"version":3,"file":"EntityMetaStore.d.ts","sourceRoot":"","sources":["../../src/store/EntityMetaStore.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAA;AAEhD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAA;AAEpD;;GAEG;AACH,MAAM,WAAW,eAAe;IAC/B,MAAM,EAAE,UAAU,CAAA;IAClB,KAAK,CAAC,EAAE,UAAU,CAAA;CAClB;AAED;;GAEG;AACH,MAAM,WAAW,UAAU;IAC1B,8CAA8C;IAC9C,cAAc,EAAE,OAAO,CAAA;IACvB,mDAAmD;IACnD,sBAAsB,EAAE,OAAO,CAAA;CAC/B;AAED;;;;;GAKG;AACH,qBAAa,eAAe;IAC3B,2CAA2C;IAC3C,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAqC;IAEhE,+CAA+C;IAC/C,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAgC;IAE5D,iDAAiD;IACjD,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAAoB;IAEvD,0EAA0E;IAC1E,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAA4B;IAI9D,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,eAAe,GAAG,SAAS;IAItD,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,KAAK,CAAC,EAAE,UAAU,GAAG,IAAI;IAIvE,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAMjC,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,UAAU,GAAG,SAAS;IAIlD,iBAAiB,CAAC,GAAG,EAAE,MAAM,EAAE,cAAc,EAAE,OAAO,GAAG,IAAI;IAK7D,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IAIpC,mBAAmB,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAKtC,qBAAqB,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAKxC,sBAAsB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IAM5C,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IAIlC,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,YAAY,EAAE,OAAO,GAAG,IAAI;IAUvD,sBAAsB,CAAC,GAAG,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,IAAI;IAK9D,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAMtD,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO;IAM7C;;OAEG;IACH,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAOzB;;OAEG;IACH,KAAK,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI;IA4B3C,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC;IAWpD,WAAW,CAAC,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,GAAG,IAAI;IAMjD,KAAK,IAAI,IAAI;CAMb"}
1
+ {"version":3,"file":"EntityMetaStore.d.ts","sourceRoot":"","sources":["../../src/store/EntityMetaStore.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAA;AAChD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAA;AACpD,OAAO,KAAK,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAA;AAErE;;GAEG;AACH,MAAM,WAAW,eAAe;IAC/B,MAAM,EAAE,UAAU,CAAA;IAClB,KAAK,CAAC,EAAE,UAAU,CAAA;CAClB;AAED;;GAEG;AACH,MAAM,WAAW,UAAU;IAC1B,8CAA8C;IAC9C,cAAc,EAAE,OAAO,CAAA;IACvB,mDAAmD;IACnD,sBAAsB,EAAE,OAAO,CAAA;CAC/B;AAED;;;;;GAKG;AACH,qBAAa,eAAgB,YAAW,SAAS;IAChD,2CAA2C;IAC3C,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAqC;IAEhE,+CAA+C;IAC/C,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAgC;IAE5D,iDAAiD;IACjD,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAAoB;IAEvD;;;;;OAKG;IACH,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAoB;IAExD;;;;;OAKG;IACH,OAAO,CAAC,eAAe,CAAI;IAE3B;;;;;OAKG;IACH,OAAO,CAAC,oBAAoB,CAAI;IAEhC,kBAAkB,IAAI,MAAM;IAI5B,uBAAuB,IAAI,MAAM;IAMjC,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,eAAe,GAAG,SAAS;IAItD,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,KAAK,CAAC,EAAE,UAAU,GAAG,IAAI;IAIvE,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAMjC,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,UAAU,GAAG,SAAS;IAIlD,iBAAiB,CAAC,GAAG,EAAE,MAAM,EAAE,cAAc,EAAE,OAAO,GAAG,IAAI;IAY7D,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IAIpC,mBAAmB,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAMtC,qBAAqB,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAMxC,sBAAsB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IAM5C,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IAIlC,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,YAAY,EAAE,OAAO,EAAE,WAAW,GAAE,OAAe,GAAG,IAAI;IAqBrF,qBAAqB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IAI3C;;OAEG;IACH,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAQzB;;;;OAIG;IACH,KAAK,CAAC,GAAG,EAAE,YAAY,GAAG,IAAI;IA6B9B,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC;IAWpD,WAAW,CAAC,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,GAAG,IAAI;IASjD,KAAK,IAAI,IAAI;CAOb"}
@@ -1,4 +1,5 @@
1
1
  import { type EntitySnapshot } from './snapshots.js';
2
+ import type { RekeyContext, Rekeyable } from './RekeyOrchestrator.js';
2
3
  /**
3
4
  * Manages entity snapshots — core CRUD for immutable entity data.
4
5
  *
@@ -8,7 +9,7 @@ import { type EntitySnapshot } from './snapshots.js';
8
9
  * Follows the same sub-store pattern as ErrorStore, RelationStore, etc.
9
10
  * SnapshotStore delegates entity snapshot operations here.
10
11
  */
11
- export declare class EntitySnapshotStore {
12
+ export declare class EntitySnapshotStore implements Rekeyable {
12
13
  private readonly snapshots;
13
14
  /**
14
15
  * Index from entity id to its composite key, so reachability walks can resolve
@@ -17,6 +18,46 @@ export declare class EntitySnapshotStore {
17
18
  * single key per id is unambiguous.
18
19
  */
19
20
  private readonly idIndex;
21
+ /**
22
+ * Monotonic counter bumped only when the set of keys or the id→key index
23
+ * changes (new key, removal, rekey, bulk import, clear). Pure value edits
24
+ * (setFieldValue/updateFields/commit/reset/...) do NOT bump it — they cannot
25
+ * change reachability — so the per-keystroke edit path keeps the
26
+ * {@link ReachabilityAnalyzer} cache warm.
27
+ */
28
+ private mutationVersion;
29
+ /**
30
+ * Monotonic counter bumped on every EDITABLE-layer snapshot write (local
31
+ * setData / updateFields / setFieldValue / reset) — the writes an undo gesture
32
+ * must first record. Server-baseline writes (server setData, refreshServerData,
33
+ * commit, commitFields) and non-write bookkeeping (remove, bumpVersion, import,
34
+ * rekey, clear) deliberately do NOT bump it. Read by the undo write-guard to
35
+ * detect a mutating path that wrote without recording. See UndoJournal.
36
+ */
37
+ private editableWriteVersion;
38
+ /**
39
+ * Monotonic counter bumped on every write that can change a snapshot's `data`
40
+ * or `serverData` — i.e. every write that can change whether the entity is
41
+ * dirty. Unlike the two counters above it spans BOTH layers: `mutationVersion`
42
+ * ignores value edits and `editableWriteVersion` ignores server-baseline writes
43
+ * (refreshServerData/commit/commitFields), so neither alone is a sound dirty
44
+ * key. {@link bumpVersion} is excluded — it rewrites neither side. Read by
45
+ * SnapshotStore.getDirtyVersion() to memoize the full-store dirty scan.
46
+ */
47
+ private dataWriteVersion;
48
+ getMutationVersion(): number;
49
+ getEditableWriteVersion(): number;
50
+ getDataWriteVersion(): number;
51
+ /**
52
+ * The single write chokepoint. Every path that installs a snapshot goes through
53
+ * here, so {@link dataWriteVersion} cannot be forgotten by a new mutating method
54
+ * or a new early-return branch — a stale dirty memo is silent (dead Save button),
55
+ * so the bump must not be hand-maintained per call site. Mirrors
56
+ * HasOneStore.writeRelation / HasManyStore.writeHasMany.
57
+ */
58
+ private writeSnapshot;
59
+ /** The single delete chokepoint — counterpart of {@link writeSnapshot}. */
60
+ private deleteSnapshot;
20
61
  get(key: string): EntitySnapshot | undefined;
21
62
  has(key: string): boolean;
22
63
  /**
@@ -62,6 +103,11 @@ export declare class EntitySnapshotStore {
62
103
  /**
63
104
  * Bumps the version of an entity snapshot without changing data.
64
105
  * Used by SubscriptionManager when child entities change.
106
+ *
107
+ * The ONE deliberate bypass of {@link writeSnapshot}: it reinstalls the very same
108
+ * `data` and `serverData` references under a new version, so it cannot change
109
+ * dirtiness and must not invalidate the dirty memo — it runs once per ancestor on
110
+ * every notification, which would keep the cache permanently cold.
65
111
  */
66
112
  bumpVersion(key: string): void;
67
113
  /**
@@ -78,9 +124,10 @@ export declare class EntitySnapshotStore {
78
124
  */
79
125
  importSnapshots(snapshots: Map<string, EntitySnapshot>): Set<string>;
80
126
  /**
81
- * Moves a snapshot from oldKey to newKey, updating the id in the snapshot data.
127
+ * Moves a snapshot from the temp key to the persisted key, updating the id in
128
+ * the snapshot data.
82
129
  */
83
- rekey(oldKey: string, newKey: string, newId: string): void;
130
+ rekey(ctx: RekeyContext): void;
84
131
  keys(): IterableIterator<string>;
85
132
  /**
86
133
  * Resolves an entity id (without its type) to its composite key in O(1).
@@ -1 +1 @@
1
- {"version":3,"file":"EntitySnapshotStore.d.ts","sourceRoot":"","sources":["../../src/store/EntitySnapshotStore.ts"],"names":[],"mappings":"AAAA,OAAO,EAEN,KAAK,cAAc,EACnB,MAAM,gBAAgB,CAAA;AAEvB;;;;;;;;GAQG;AACH,qBAAa,mBAAmB;IAC/B,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAoC;IAE9D;;;;;OAKG;IACH,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA4B;IAEpD,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,cAAc,GAAG,SAAS;IAI5C,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IAIzB;;;OAGG;IACH,OAAO,CAAC,CAAC,SAAS,MAAM,EACvB,GAAG,EAAE,MAAM,EACX,EAAE,EAAE,MAAM,EACV,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,CAAC,EACP,YAAY,EAAE,OAAO,GACnB,cAAc,CAAC,CAAC,CAAC;IAwBpB;;;;;;;;;;;OAWG;IACH,iBAAiB,CAAC,CAAC,SAAS,MAAM,EACjC,GAAG,EAAE,MAAM,EACX,EAAE,EAAE,MAAM,EACV,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,CAAC,GACL,cAAc,CAAC,CAAC,CAAC;IAiCpB;;;OAGG;IACH,YAAY,CAAC,CAAC,SAAS,MAAM,EAC5B,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,GACjB,cAAc,CAAC,CAAC,CAAC,GAAG,SAAS;IAiBhC;;;OAGG;IACH,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,EAAE,KAAK,EAAE,OAAO,GAAG,OAAO;IAiBxE;;OAEG;IACH,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAezB;;OAEG;IACH,KAAK,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAexB;;OAEG;IACH,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAazB;;;OAGG;IACH,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAe9B;;OAEG;IACH,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,GAAG,IAAI;IAyBrD;;OAEG;IACH,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,GAAG,CAAC,MAAM,EAAE,cAAc,CAAC;IAW5D;;;OAGG;IACH,eAAe,CAAC,SAAS,EAAE,GAAG,CAAC,MAAM,EAAE,cAAc,CAAC,GAAG,GAAG,CAAC,MAAM,CAAC;IAUpE;;OAEG;IACH,KAAK,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI;IAsB1D,IAAI,IAAI,gBAAgB,CAAC,MAAM,CAAC;IAIhC;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAIxC,KAAK,IAAI,IAAI;CAIb"}
1
+ {"version":3,"file":"EntitySnapshotStore.d.ts","sourceRoot":"","sources":["../../src/store/EntitySnapshotStore.ts"],"names":[],"mappings":"AAAA,OAAO,EAEN,KAAK,cAAc,EACnB,MAAM,gBAAgB,CAAA;AACvB,OAAO,KAAK,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAA;AAErE;;;;;;;;GAQG;AACH,qBAAa,mBAAoB,YAAW,SAAS;IACpD,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAoC;IAE9D;;;;;OAKG;IACH,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA4B;IAEpD;;;;;;OAMG;IACH,OAAO,CAAC,eAAe,CAAI;IAE3B;;;;;;;OAOG;IACH,OAAO,CAAC,oBAAoB,CAAI;IAEhC;;;;;;;;OAQG;IACH,OAAO,CAAC,gBAAgB,CAAI;IAE5B,kBAAkB,IAAI,MAAM;IAI5B,uBAAuB,IAAI,MAAM;IAIjC,mBAAmB,IAAI,MAAM;IAI7B;;;;;;OAMG;IACH,OAAO,CAAC,aAAa;IAKrB,2EAA2E;IAC3E,OAAO,CAAC,cAAc;IAMtB,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,cAAc,GAAG,SAAS;IAI5C,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IAIzB;;;OAGG;IACH,OAAO,CAAC,CAAC,SAAS,MAAM,EACvB,GAAG,EAAE,MAAM,EACX,EAAE,EAAE,MAAM,EACV,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,CAAC,EACP,YAAY,EAAE,OAAO,GACnB,cAAc,CAAC,CAAC,CAAC;IA6BpB;;;;;;;;;;;OAWG;IACH,iBAAiB,CAAC,CAAC,SAAS,MAAM,EACjC,GAAG,EAAE,MAAM,EACX,EAAE,EAAE,MAAM,EACV,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,CAAC,GACL,cAAc,CAAC,CAAC,CAAC;IAiCpB;;;OAGG;IACH,YAAY,CAAC,CAAC,SAAS,MAAM,EAC5B,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,GACjB,cAAc,CAAC,CAAC,CAAC,GAAG,SAAS;IAkBhC;;;OAGG;IACH,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,EAAE,KAAK,EAAE,OAAO,GAAG,OAAO;IAkBxE;;OAEG;IACH,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAezB;;OAEG;IACH,KAAK,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAgBxB;;OAEG;IACH,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAczB;;;;;;;;OAQG;IACH,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAe9B;;OAEG;IACH,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,GAAG,IAAI;IAyBrD;;OAEG;IACH,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,GAAG,CAAC,MAAM,EAAE,cAAc,CAAC;IAW5D;;;OAGG;IACH,eAAe,CAAC,SAAS,EAAE,GAAG,CAAC,MAAM,EAAE,cAAc,CAAC,GAAG,GAAG,CAAC,MAAM,CAAC;IAWpE;;;OAGG;IACH,KAAK,CAAC,GAAG,EAAE,YAAY,GAAG,IAAI;IAuB9B,IAAI,IAAI,gBAAgB,CAAC,MAAM,CAAC;IAIhC;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAIxC,KAAK,IAAI,IAAI;CAQb"}
@@ -1,4 +1,5 @@
1
1
  import type { FieldError } from '../errors/types.js';
2
+ import type { RekeyContext, Rekeyable } from './RekeyOrchestrator.js';
2
3
  /**
3
4
  * Manages error state for fields, entities, and relations.
4
5
  *
@@ -7,7 +8,7 @@ import type { FieldError } from '../errors/types.js';
7
8
  * - Entity errors: "entityType:id"
8
9
  * - Relation errors: "entityType:id:relationName"
9
10
  */
10
- export declare class ErrorStore {
11
+ export declare class ErrorStore implements Rekeyable {
11
12
  /** Field errors keyed by "entityType:id:fieldName" */
12
13
  private readonly fieldErrors;
13
14
  /** Entity-level errors keyed by "entityType:id" */
@@ -81,7 +82,7 @@ export declare class ErrorStore {
81
82
  /**
82
83
  * Rekeys all errors from oldKeyPrefix to newKeyPrefix.
83
84
  */
84
- rekey(oldEntityKey: string, newEntityKey: string, oldKeyPrefix: string, newKeyPrefix: string): void;
85
+ rekey(ctx: RekeyContext): void;
85
86
  private rekeyMap;
86
87
  private rekeyByPrefix;
87
88
  }
@@ -1 +1 @@
1
- {"version":3,"file":"ErrorStore.d.ts","sourceRoot":"","sources":["../../src/store/ErrorStore.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAc,UAAU,EAAE,MAAM,oBAAoB,CAAA;AAGhE;;;;;;;GAOG;AACH,qBAAa,UAAU;IACtB,sDAAsD;IACtD,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAgC;IAE5D,mDAAmD;IACnD,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAgC;IAE7D,4DAA4D;IAC5D,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAgC;IAI/D;;OAEG;IACH,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,UAAU,EAAE;IAIvD;;OAEG;IACH,aAAa,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,GAAG,IAAI;IAMxD;;OAEG;IACH,gBAAgB,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,QAAQ,GAAG,QAAQ,GAAG,IAAI;IAgBtE;;;;OAIG;IACH,yBAAyB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO;IAiBpD;;OAEG;IACH,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,SAAS,UAAU,EAAE;IAIzD;;OAEG;IACH,cAAc,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,GAAG,IAAI;IAM1D;;OAEG;IACH,iBAAiB,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,QAAQ,GAAG,QAAQ,GAAG,IAAI;IAkBxE;;OAEG;IACH,iBAAiB,CAAC,WAAW,EAAE,MAAM,GAAG,SAAS,UAAU,EAAE;IAI7D;;OAEG;IACH,gBAAgB,CAAC,WAAW,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,GAAG,IAAI;IAM9D;;OAEG;IACH,mBAAmB,CAAC,WAAW,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,QAAQ,GAAG,QAAQ,GAAG,IAAI;IAkB5E;;;OAGG;IACH,oBAAoB,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI;IAgBhE;;OAEG;IACH,cAAc,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI;IAgB1D;;;OAGG;IACH,eAAe,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO;IAqB9D;;OAEG;IACH,YAAY,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO;IAqB3D;;OAEG;IACH,KAAK,IAAI,IAAI;IAMb;;OAEG;IACH,KAAK,CAAC,YAAY,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,IAAI;IAMnG,OAAO,CAAC,QAAQ;IAQhB,OAAO,CAAC,aAAa;CAYrB"}
1
+ {"version":3,"file":"ErrorStore.d.ts","sourceRoot":"","sources":["../../src/store/ErrorStore.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAc,UAAU,EAAE,MAAM,oBAAoB,CAAA;AAEhE,OAAO,KAAK,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAA;AAErE;;;;;;;GAOG;AACH,qBAAa,UAAW,YAAW,SAAS;IAC3C,sDAAsD;IACtD,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAgC;IAE5D,mDAAmD;IACnD,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAgC;IAE7D,4DAA4D;IAC5D,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAgC;IAI/D;;OAEG;IACH,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,UAAU,EAAE;IAIvD;;OAEG;IACH,aAAa,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,GAAG,IAAI;IAMxD;;OAEG;IACH,gBAAgB,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,QAAQ,GAAG,QAAQ,GAAG,IAAI;IAgBtE;;;;OAIG;IACH,yBAAyB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO;IAiBpD;;OAEG;IACH,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,SAAS,UAAU,EAAE;IAIzD;;OAEG;IACH,cAAc,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,GAAG,IAAI;IAM1D;;OAEG;IACH,iBAAiB,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,QAAQ,GAAG,QAAQ,GAAG,IAAI;IAkBxE;;OAEG;IACH,iBAAiB,CAAC,WAAW,EAAE,MAAM,GAAG,SAAS,UAAU,EAAE;IAI7D;;OAEG;IACH,gBAAgB,CAAC,WAAW,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,GAAG,IAAI;IAM9D;;OAEG;IACH,mBAAmB,CAAC,WAAW,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,QAAQ,GAAG,QAAQ,GAAG,IAAI;IAkB5E;;;OAGG;IACH,oBAAoB,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI;IAgBhE;;OAEG;IACH,cAAc,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI;IAgB1D;;;OAGG;IACH,eAAe,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO;IAqB9D;;OAEG;IACH,YAAY,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO;IAqB3D;;OAEG;IACH,KAAK,IAAI,IAAI;IAMb;;OAEG;IACH,KAAK,CAAC,GAAG,EAAE,YAAY,GAAG,IAAI;IAM9B,OAAO,CAAC,QAAQ;IAQhB,OAAO,CAAC,aAAa;CAYrB"}
@@ -0,0 +1,214 @@
1
+ type ReconciliationResult = 'applied' | 'conflict';
2
+ /**
3
+ * Removal type for has-many items
4
+ */
5
+ export type HasManyRemovalType = 'disconnect' | 'delete';
6
+ /**
7
+ * Kind of a planned has-many addition:
8
+ * - 'created': a newly created entity (via add())
9
+ * - 'connected': an existing persisted entity being connected (via connect())
10
+ */
11
+ export type HasManyAdditionKind = 'created' | 'connected';
12
+ export interface SentHasManyAddition {
13
+ itemId: string;
14
+ kind: HasManyAdditionKind;
15
+ }
16
+ export interface SentHasManyRemoval {
17
+ itemId: string;
18
+ type: HasManyRemovalType;
19
+ }
20
+ export interface SentHasManyDelta {
21
+ additions: readonly SentHasManyAddition[];
22
+ removals: readonly SentHasManyRemoval[];
23
+ }
24
+ /**
25
+ * Has-many list state stored in SnapshotStore
26
+ */
27
+ export interface StoredHasManyState {
28
+ /** IDs of items from server */
29
+ serverIds: Set<string>;
30
+ /** Explicit ordered list of item IDs, null means use default order (serverIds + plannedAdditions) */
31
+ orderedIds: string[] | null;
32
+ /** Planned removals (disconnect or delete) keyed by entity ID */
33
+ plannedRemovals: Map<string, HasManyRemovalType>;
34
+ /**
35
+ * Planned additions (IDs to add to the list) keyed by entity ID, with the
36
+ * value distinguishing newly CREATED entities (add()) from existing PERSISTED
37
+ * entities being CONNECTED (connect()). The keys are exactly the connections;
38
+ * the keys whose value is 'created' are exactly the created entities, so the
39
+ * "created ⊆ connections" invariant is structural.
40
+ */
41
+ plannedAdditions: Map<string, HasManyAdditionKind>;
42
+ version: number;
43
+ }
44
+ /**
45
+ * Computes the default ordered IDs for a has-many relation.
46
+ * Order is: serverIds (minus removals) + plannedAdditions
47
+ */
48
+ export declare function computeDefaultOrderedIds(state: StoredHasManyState): string[];
49
+ /**
50
+ * Owns has-many list state ("parentType:parentId:fieldName" → {@link StoredHasManyState}).
51
+ *
52
+ * Has its own monotonic {@link mutationVersion} bumped on every actual write
53
+ * (funnelled through {@link writeHasMany} plus the delete/clear paths); the
54
+ * facade sums this with the has-one counter for {@link ReachabilityAnalyzer}.
55
+ */
56
+ export declare class HasManyStore {
57
+ /** Has-many list states keyed by "parentType:parentId:fieldName" */
58
+ private readonly hasManyStates;
59
+ /**
60
+ * Bidirectional live-edge index, maintained by {@link writeHasMany} /
61
+ * {@link deleteHasMany} so the parent↔child queries are O(degree) and the two
62
+ * directions stay consistent by construction.
63
+ */
64
+ private readonly edges;
65
+ private mutationVersion;
66
+ /**
67
+ * Monotonic counter bumped on EDITABLE-layer has-many writes (plan add/remove,
68
+ * add, connectExisting, remove, move, reset) — the writes an undo gesture must
69
+ * first record. Server- id ingestion (setHasManyServerIds), materialization
70
+ * (getOrCreateHasMany), post-persist commit, import, replaceEntityId, rekey and
71
+ * delete deliberately do NOT bump it. Read by the undo write-guard (see UndoJournal).
72
+ */
73
+ private editableWriteVersion;
74
+ getMutationVersion(): number;
75
+ getEditableWriteVersion(): number;
76
+ /**
77
+ * The single write chokepoint. Reconciles the edge index by diffing the live
78
+ * members of the previous state against the next, so every state-changing path
79
+ * (server ids / planned add/remove / move / import / replaceEntityId / ...)
80
+ * keeps the index correct without tracking the reverse direction itself.
81
+ */
82
+ private writeHasMany;
83
+ /**
84
+ * The single delete chokepoint — removes an entry and its live edges. Used by
85
+ * the bulk remove and rekey-owner paths so they don't leak edges.
86
+ */
87
+ private deleteHasMany;
88
+ /**
89
+ * Gets or creates has-many list state.
90
+ */
91
+ getOrCreateHasMany(key: string, serverIds?: string[]): StoredHasManyState;
92
+ /**
93
+ * Gets has-many list state.
94
+ */
95
+ getHasMany(key: string): StoredHasManyState | undefined;
96
+ /**
97
+ * Sets server IDs for a has-many relation.
98
+ */
99
+ setHasManyServerIds(key: string, serverIds: string[]): void;
100
+ /**
101
+ * Plans a removal for a has-many item.
102
+ */
103
+ planHasManyRemoval(key: string, itemId: string, type: HasManyRemovalType): void;
104
+ /**
105
+ * Plans a connection for a has-many item.
106
+ */
107
+ planHasManyConnection(key: string, itemId: string): void;
108
+ /**
109
+ * Commits has-many state after successful persist.
110
+ */
111
+ commitHasMany(key: string, newServerIds: string[]): void;
112
+ /**
113
+ * Advances the server baseline by the confirmed sent delta and rebases local
114
+ * edits made after the request started onto that new baseline.
115
+ */
116
+ reconcileSentDelta(key: string, delta: SentHasManyDelta): ReconciliationResult;
117
+ /**
118
+ * Resets has-many state to server state (clears planned operations).
119
+ */
120
+ resetHasMany(key: string): void;
121
+ /**
122
+ * Adds a newly created entity to a has-many relation.
123
+ * Used by HasManyListHandle.add() for inline entity creation.
124
+ */
125
+ addToHasMany(key: string, itemId: string): void;
126
+ /**
127
+ * Connects an existing (persisted) entity to a has-many relation.
128
+ * Unlike addToHasMany, records the addition as 'connected' (not 'created') —
129
+ * used for materializing embedded connect references to existing entities.
130
+ */
131
+ connectExistingToHasMany(key: string, itemId: string): void;
132
+ /**
133
+ * Removes an entity from a has-many relation.
134
+ * For newly created entities (via add()), cancels the connection.
135
+ * For existing server entities, plans the specified removal type.
136
+ * Returns true if the state changed (caller should notify), false if it was a no-op.
137
+ */
138
+ removeFromHasMany(key: string, itemId: string, removalType: HasManyRemovalType): boolean;
139
+ /**
140
+ * Moves an item within a has-many relation from one index to another.
141
+ */
142
+ moveInHasMany(key: string, fromIndex: number, toIndex: number): void;
143
+ /**
144
+ * Gets the ordered list of item IDs for a has-many relation.
145
+ */
146
+ getHasManyOrderedIds(key: string): string[];
147
+ /**
148
+ * Collects the ids of child entities reachable through LIVE has-many edges
149
+ * (key prefix "parentType:parentId:") — an O(degree) read of the edge index.
150
+ */
151
+ collectLiveChildIds(keyPrefix: string, ids: Set<string>): void;
152
+ /**
153
+ * Adds the composite parent keys of every LIVE has-many edge containing
154
+ * {@link childId} — an O(degree) read of the edge index, the exact reverse of
155
+ * {@link collectLiveChildIds}.
156
+ */
157
+ collectParentKeysForChild(childId: string, parents: Set<string>): void;
158
+ /**
159
+ * Collects the keys of every has-many list owned by an entity (keys under the
160
+ * given owner prefix). Mirrors {@link removeOwnedRelations} but only enumerates.
161
+ */
162
+ collectOwnedKeys(keyPrefix: string, keys: string[]): void;
163
+ /**
164
+ * Removes a single has-many list state (and its live edges). Used by undo
165
+ * restore to drop a list that did not exist before the gesture.
166
+ */
167
+ removeHasMany(key: string): void;
168
+ /**
169
+ * Removes all has-many state owned by an entity (keys under the given owner
170
+ * prefix), dropping each entry's edges through {@link deleteHasMany}.
171
+ */
172
+ removeOwnedRelations(keyPrefix: string): void;
173
+ /**
174
+ * Commits all has-many relations for an entity.
175
+ *
176
+ * `pendingItems` (by relation key) names planned additions/removals that were NOT
177
+ * sent — they stay planned instead of being folded into the server baseline.
178
+ */
179
+ commitAllRelations(keyPrefix: string, pendingItems?: ReadonlyMap<string, ReadonlySet<string>>): void;
180
+ /**
181
+ * Resets all has-many relations for an entity to server state.
182
+ */
183
+ resetAllRelations(keyPrefix: string): void;
184
+ /**
185
+ * Collects the field names of dirty has-many relations for an entity.
186
+ */
187
+ collectDirtyRelations(keyPrefix: string, dirtyRelations: string[]): void;
188
+ /**
189
+ * Exports has-many states for given keys.
190
+ */
191
+ exportHasManyStates(keys: string[]): Map<string, StoredHasManyState>;
192
+ /**
193
+ * Imports has-many states from a snapshot.
194
+ * Returns the keys that were imported for notification.
195
+ */
196
+ importHasManyStates(states: Map<string, StoredHasManyState>): string[];
197
+ /**
198
+ * Replaces all occurrences of oldId with newId across has-many states
199
+ * (serverIds, orderedIds, plannedAdditions, plannedRemovals).
200
+ */
201
+ replaceEntityId(oldId: string, newId: string): void;
202
+ /**
203
+ * Rekeys has-many entries owned by an entity (changes the parent ID in the key).
204
+ * Routing through {@link deleteHasMany} + {@link writeHasMany} migrates the edge
205
+ * index from the old parent key to the new one for free.
206
+ */
207
+ rekeyOwner(oldKeyPrefix: string, newKeyPrefix: string): void;
208
+ /**
209
+ * Clears all has-many relation data.
210
+ */
211
+ clear(): void;
212
+ }
213
+ export {};
214
+ //# sourceMappingURL=HasManyStore.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"HasManyStore.d.ts","sourceRoot":"","sources":["../../src/store/HasManyStore.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,159 @@
1
+ import type { HasOneRelationState } from '../handles/types.js';
2
+ import type { EntitySnapshot } from './snapshots.js';
3
+ /**
4
+ * Relation state stored in SnapshotStore
5
+ */
6
+ export interface StoredRelationState {
7
+ currentId: string | null;
8
+ serverId: string | null;
9
+ state: HasOneRelationState;
10
+ serverState: HasOneRelationState;
11
+ placeholderData: Record<string, unknown>;
12
+ version: number;
13
+ }
14
+ type ReconciliationResult = 'applied' | 'conflict';
15
+ export type SentHasOneTransition = {
16
+ operation: 'connect';
17
+ targetId: string;
18
+ } | {
19
+ operation: 'create';
20
+ targetId: string;
21
+ } | {
22
+ operation: 'disconnect';
23
+ targetId: string;
24
+ } | {
25
+ operation: 'delete';
26
+ targetId: string;
27
+ };
28
+ /**
29
+ * Owns has-one relation state ("parentType:parentId:fieldName" → {@link StoredRelationState}).
30
+ *
31
+ * Has its own monotonic {@link mutationVersion} bumped on every actual write
32
+ * (funnelled through {@link writeRelation} plus the delete/clear paths); the
33
+ * facade sums this with the has-many counter for {@link ReachabilityAnalyzer}.
34
+ */
35
+ export declare class HasOneStore {
36
+ /** Relation states keyed by "parentType:parentId:fieldName" */
37
+ private readonly relationStates;
38
+ /**
39
+ * Bidirectional live-edge index, maintained by {@link writeRelation} /
40
+ * {@link deleteRelation} so the parent↔child queries are O(degree) and the two
41
+ * directions stay consistent by construction.
42
+ */
43
+ private readonly edges;
44
+ private mutationVersion;
45
+ /**
46
+ * Monotonic counter bumped on EDITABLE-layer has-one writes (setRelation /
47
+ * resetRelation) — the writes an undo gesture must first record. Materialization
48
+ * (getOrCreateRelation), post-persist commit, import, replaceEntityId, rekey and
49
+ * delete deliberately do NOT bump it. Read by the undo write-guard (see UndoJournal).
50
+ */
51
+ private editableWriteVersion;
52
+ getMutationVersion(): number;
53
+ getEditableWriteVersion(): number;
54
+ /**
55
+ * The single write chokepoint. Reconciles the edge index by diffing the live
56
+ * child of the previous state against the next, so every state-changing path
57
+ * (set/commit/reset/import/replaceEntityId/...) keeps the index correct without
58
+ * tracking the reverse direction itself.
59
+ */
60
+ private writeRelation;
61
+ /**
62
+ * The single delete chokepoint — removes an entry and its live edge. Used by
63
+ * the bulk remove and rekey-owner paths so they don't leak edges.
64
+ */
65
+ private deleteRelation;
66
+ /**
67
+ * Gets or creates relation state.
68
+ */
69
+ getOrCreateRelation(key: string, initial: Omit<StoredRelationState, 'version'>): StoredRelationState;
70
+ /**
71
+ * Gets relation state.
72
+ */
73
+ getRelation(key: string): StoredRelationState | undefined;
74
+ /**
75
+ * Updates relation state.
76
+ * If the relation state doesn't exist, creates it using entity snapshot for server data.
77
+ */
78
+ setRelation(key: string, updates: Partial<Omit<StoredRelationState, 'version'>>, entitySnapshot: EntitySnapshot | undefined, fieldName: string): void;
79
+ /**
80
+ * Commits relation state (server = current).
81
+ */
82
+ commitRelation(key: string): void;
83
+ /**
84
+ * Advances the server baseline by one confirmed sent transition while keeping
85
+ * edits made after the request started as pending local state.
86
+ */
87
+ reconcileSentTransition(key: string, transition: SentHasOneTransition): ReconciliationResult;
88
+ /**
89
+ * Resets relation to server state.
90
+ */
91
+ resetRelation(key: string): void;
92
+ /**
93
+ * Collects the ids of child entities reachable through LIVE has-one edges
94
+ * (key prefix "parentType:parentId:") — an O(degree) read of the edge index.
95
+ */
96
+ collectLiveChildIds(keyPrefix: string, ids: Set<string>): void;
97
+ /**
98
+ * Adds the composite parent keys of every LIVE has-one edge pointing at
99
+ * {@link childId} — an O(degree) read of the edge index, the exact reverse of
100
+ * {@link collectLiveChildIds}.
101
+ */
102
+ collectParentKeysForChild(childId: string, parents: Set<string>): void;
103
+ /**
104
+ * Collects the keys of every has-one relation owned by an entity (keys under the
105
+ * given owner prefix). Mirrors {@link removeOwnedRelations} but only enumerates.
106
+ */
107
+ collectOwnedKeys(keyPrefix: string, keys: string[]): void;
108
+ /**
109
+ * Removes a single has-one relation state (and its live edge). Used by undo
110
+ * restore to drop a relation that did not exist before the gesture.
111
+ */
112
+ removeRelation(key: string): void;
113
+ /**
114
+ * Removes all has-one state owned by an entity (keys under the given owner
115
+ * prefix), dropping each entry's edge through {@link deleteRelation}.
116
+ */
117
+ removeOwnedRelations(keyPrefix: string): void;
118
+ /**
119
+ * Commits all has-one relations for an entity.
120
+ *
121
+ * A relation whose planned op targets an item in `pendingItems` (by relation key)
122
+ * was not sent and is left uncommitted, so the op is retried on the next persist.
123
+ */
124
+ commitAllRelations(keyPrefix: string, pendingItems?: ReadonlyMap<string, ReadonlySet<string>>): void;
125
+ /**
126
+ * Resets all has-one relations for an entity to server state.
127
+ */
128
+ resetAllRelations(keyPrefix: string): void;
129
+ /**
130
+ * Collects the field names of dirty has-one relations for an entity.
131
+ */
132
+ collectDirtyRelations(keyPrefix: string, dirtyRelations: string[]): void;
133
+ /**
134
+ * Exports relation states for given keys.
135
+ */
136
+ exportRelationStates(keys: string[]): Map<string, StoredRelationState>;
137
+ /**
138
+ * Imports relation states from a snapshot.
139
+ * Returns the keys that were imported for notification.
140
+ */
141
+ importRelationStates(states: Map<string, StoredRelationState>): string[];
142
+ /**
143
+ * Replaces all occurrences of oldId with newId across has-one relation states
144
+ * (currentId, serverId).
145
+ */
146
+ replaceEntityId(oldId: string, newId: string): void;
147
+ /**
148
+ * Rekeys has-one entries owned by an entity (changes the parent ID in the key).
149
+ * Routing through {@link deleteRelation} + {@link writeRelation} migrates the
150
+ * edge index from the old parent key to the new one for free.
151
+ */
152
+ rekeyOwner(oldKeyPrefix: string, newKeyPrefix: string): void;
153
+ /**
154
+ * Clears all has-one relation data.
155
+ */
156
+ clear(): void;
157
+ }
158
+ export {};
159
+ //# sourceMappingURL=HasOneStore.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"HasOneStore.d.ts","sourceRoot":"","sources":["../../src/store/HasOneStore.ts"],"names":[],"mappings":"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"}