@contember/bindx 0.1.45 → 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 +121 -17
  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
@@ -17,6 +17,14 @@ import type { RootRegistry } from './RootRegistry.js';
17
17
  * The graph is read from {@link RelationStore} (the source of truth for live
18
18
  * relation membership), never from the subscription parent-child registry,
19
19
  * which is append-mostly for notifications and does not reflect disconnects.
20
+ *
21
+ * The walk is O(E+R) and runs on every dirty check and post-persist sweep, so
22
+ * its result is memoized. Each sub-store the walk reads exposes a monotonic
23
+ * `getMutationVersion()` that bumps only when graph-relevant state changes
24
+ * (entity key set, `existsOnServer`/`isPersisting`, roots, relation edges).
25
+ * Their sum is a cache key: it is strictly increasing, so an unchanged sum
26
+ * proves nothing relevant changed and the cached set can be returned. Pure
27
+ * field edits do not bump any counter, keeping the cache warm on the hot path.
20
28
  */
21
29
  export declare class ReachabilityAnalyzer {
22
30
  private readonly entitySnapshots;
@@ -24,10 +32,21 @@ export declare class ReachabilityAnalyzer {
24
32
  private readonly relations;
25
33
  private readonly roots;
26
34
  constructor(entitySnapshots: EntitySnapshotStore, meta: EntityMetaStore, relations: RelationStore, roots: RootRegistry);
35
+ private cache;
27
36
  /**
28
37
  * Returns the set of entity keys ("entityType:id") for created
29
38
  * (never-persisted) entities reachable from a root through live relations.
39
+ *
40
+ * The returned set is the cached instance and is owned by the analyzer —
41
+ * callers must treat it as read-only (the current consumers only call
42
+ * `.has(...)` on it).
30
43
  */
31
44
  computeReachableCreated(): Set<string>;
45
+ /**
46
+ * Sum of the graph-relevant mutation counters across the sub-stores the walk
47
+ * reads. Monotonic, so an unchanged value means no relevant mutation happened.
48
+ */
49
+ private graphVersion;
50
+ private walk;
32
51
  }
33
52
  //# sourceMappingURL=ReachabilityAnalyzer.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ReachabilityAnalyzer.d.ts","sourceRoot":"","sources":["../../src/store/ReachabilityAnalyzer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAA;AACnE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAA;AAC3D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAA;AACvD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAErD;;;;;;;;;;;;;;;GAeG;AACH,qBAAa,oBAAoB;IAE/B,OAAO,CAAC,QAAQ,CAAC,eAAe;IAChC,OAAO,CAAC,QAAQ,CAAC,IAAI;IACrB,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,KAAK;gBAHL,eAAe,EAAE,mBAAmB,EACpC,IAAI,EAAE,eAAe,EACrB,SAAS,EAAE,aAAa,EACxB,KAAK,EAAE,YAAY;IAGrC;;;OAGG;IACH,uBAAuB,IAAI,GAAG,CAAC,MAAM,CAAC;CA0DtC"}
1
+ {"version":3,"file":"ReachabilityAnalyzer.d.ts","sourceRoot":"","sources":["../../src/store/ReachabilityAnalyzer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAA;AACnE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAA;AAC3D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAA;AACvD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAErD;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,qBAAa,oBAAoB;IAE/B,OAAO,CAAC,QAAQ,CAAC,eAAe;IAChC,OAAO,CAAC,QAAQ,CAAC,IAAI;IACrB,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,KAAK;gBAHL,eAAe,EAAE,mBAAmB,EACpC,IAAI,EAAE,eAAe,EACrB,SAAS,EAAE,aAAa,EACxB,KAAK,EAAE,YAAY;IAGrC,OAAO,CAAC,KAAK,CAAwD;IAErE;;;;;;;OAOG;IACH,uBAAuB,IAAI,GAAG,CAAC,MAAM,CAAC;IAYtC;;;OAGG;IACH,OAAO,CAAC,YAAY;IAOpB,OAAO,CAAC,IAAI;CA0DZ"}
@@ -0,0 +1,76 @@
1
+ /**
2
+ * Describes a single temp→persisted rekey in every shape the participating
3
+ * sub-stores need (full key, owner prefix, bare id).
4
+ */
5
+ export interface RekeyContext {
6
+ /** Old composite key, "entityType:tempId". */
7
+ readonly oldKey: string;
8
+ /** New composite key, "entityType:persistedId". */
9
+ readonly newKey: string;
10
+ /** Old owner prefix, "entityType:tempId:". */
11
+ readonly oldKeyPrefix: string;
12
+ /** New owner prefix, "entityType:persistedId:". */
13
+ readonly newKeyPrefix: string;
14
+ /** The temp id being replaced. */
15
+ readonly oldId: string;
16
+ /** The server-assigned id. */
17
+ readonly newId: string;
18
+ }
19
+ /**
20
+ * A store that owns per-entity state keyed (directly or by prefix) on an entity
21
+ * id and can migrate it from a temp id to its persisted id.
22
+ */
23
+ export interface Rekeyable {
24
+ rekey(ctx: RekeyContext): void;
25
+ }
26
+ /**
27
+ * Single source of temp→persisted identity, and the one place the rekey fan-out
28
+ * is sequenced.
29
+ *
30
+ * Owns the only id-redirect map: "entityType:tempId" → persistedId. Both key
31
+ * resolution ({@link resolveKey}/{@link resolveId}) and persisted-id queries
32
+ * ({@link getPersistedId}/{@link isNewEntity}) derive from it, so there is no
33
+ * second copy to keep in sync — the former `SnapshotStore.rekeyedEntities` and
34
+ * `EntityMetaStore.tempToPersistedId` are both gone. `SubscriptionManager` keeps
35
+ * its own closure-redirect chain, which tracks relation-key prefixes and stale
36
+ * unsubscribe closures rather than entity identity, so it stays internal there.
37
+ */
38
+ export declare class RekeyOrchestrator {
39
+ /** "entityType:tempId" → persistedId. The single identity-redirect map. */
40
+ private readonly tempToPersisted;
41
+ private readonly participants;
42
+ private readonly participantSet;
43
+ /**
44
+ * @param participants the sub-stores to migrate, in the exact order
45
+ * {@link rekey} must visit them (the order is load-bearing — see rekey()).
46
+ */
47
+ constructor(participants: readonly Rekeyable[]);
48
+ /** Adds a participant once, preserving registration order. */
49
+ registerParticipant(participant: Rekeyable): void;
50
+ /** Resolves an entity key, following a temp→persisted redirect if present. */
51
+ resolveKey(entityType: string, id: string): string;
52
+ /** Resolves an entity id to its persisted id if it has been rekeyed. */
53
+ resolveId(entityType: string, id: string): string;
54
+ /** The persisted id for an entity, or null if it has none yet. */
55
+ getPersistedId(entityType: string, id: string): string | null;
56
+ /** Whether an entity has never been persisted (no server-assigned id yet). */
57
+ isNewEntity(entityType: string, id: string): boolean;
58
+ /**
59
+ * Migrates an entity from its temp id to its server-assigned id across every
60
+ * participating store.
61
+ *
62
+ * Ordering contract (do not reorder — each step relies on the previous):
63
+ * 0. register the redirect, so any resolveKey/resolveId during the fan-out
64
+ * already sees the persisted key;
65
+ * 1. roots — keep the root registry aligned;
66
+ * 2. entity snapshot — move data, rewrite the id field and id index;
67
+ * 3. meta — move metadata/load/persisting, then mark exists-on-server;
68
+ * 4. subscriptions — move entity + relation subscribers and parent links;
69
+ * 5. relations — rekey owned relation keys, then replace value references;
70
+ * 6. errors / touched / propagation — move the remaining per-entity state.
71
+ * The caller performs the final notification on the new key.
72
+ */
73
+ rekey(entityType: string, tempId: string, persistedId: string): void;
74
+ clear(): void;
75
+ }
76
+ //# sourceMappingURL=RekeyOrchestrator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RekeyOrchestrator.d.ts","sourceRoot":"","sources":["../../src/store/RekeyOrchestrator.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,MAAM,WAAW,YAAY;IAC5B,8CAA8C;IAC9C,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,mDAAmD;IACnD,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,8CAA8C;IAC9C,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAA;IAC7B,mDAAmD;IACnD,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAA;IAC7B,kCAAkC;IAClC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,8BAA8B;IAC9B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;CACtB;AAED;;;GAGG;AACH,MAAM,WAAW,SAAS;IACzB,KAAK,CAAC,GAAG,EAAE,YAAY,GAAG,IAAI,CAAA;CAC9B;AAED;;;;;;;;;;;GAWG;AACH,qBAAa,iBAAiB;IAC7B,2EAA2E;IAC3E,OAAO,CAAC,QAAQ,CAAC,eAAe,CAA4B;IAC5D,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAkB;IAC/C,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAuB;IAEtD;;;OAGG;gBACS,YAAY,EAAE,SAAS,SAAS,EAAE;IAI9C,8DAA8D;IAC9D,mBAAmB,CAAC,WAAW,EAAE,SAAS,GAAG,IAAI;IAMjD,8EAA8E;IAC9E,UAAU,CAAC,UAAU,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,MAAM;IAKlD,wEAAwE;IACxE,SAAS,CAAC,UAAU,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,MAAM;IAIjD,kEAAkE;IAClE,cAAc,CAAC,UAAU,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAM7D,8EAA8E;IAC9E,WAAW,CAAC,UAAU,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO;IAMpD;;;;;;;;;;;;;;OAcG;IACH,KAAK,CAAC,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,IAAI;IAiBpE,KAAK,IAAI,IAAI;CAGb"}
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Bidirectional index of LIVE relation edges between a parent entity
3
+ * ("parentType:parentId") and a child entity id (a bare id).
4
+ *
5
+ * Both directions are updated together by {@link addEdge}/{@link removeEdge}, so
6
+ * the forward query ({@link collectChildren}) and the reverse query
7
+ * ({@link collectParents}) can never disagree — that was the failure mode of the
8
+ * old append-only `childToParents` map, which was updated on connect but not on
9
+ * disconnect. Both queries are O(degree), not O(total edges).
10
+ *
11
+ * Edges are reference-counted: one parent entity may reach the same child through
12
+ * more than one relation field (e.g. `author` and `coauthor`, or two has-many
13
+ * fields), so an edge survives until the last field that contributes it drops it.
14
+ *
15
+ * The index stores only the LIVE edge set; turning relation state (server ids,
16
+ * planned additions/removals, has-one state) into that set is the owning
17
+ * sub-store's job, done once per write by diffing the previous against the next
18
+ * live set (see {@link HasOneStore}/{@link HasManyStore}). The index itself knows
19
+ * nothing about liveness rules.
20
+ */
21
+ export declare class RelationEdgeIndex {
22
+ /** parentKey ("parentType:parentId") → childId → refcount */
23
+ private readonly forward;
24
+ /** childId → parentKey → refcount */
25
+ private readonly reverse;
26
+ addEdge(parentKey: string, childId: string): void;
27
+ removeEdge(parentKey: string, childId: string): void;
28
+ /** Adds the live child ids of {@link parentKey} to {@link out}. */
29
+ collectChildren(parentKey: string, out: Set<string>): void;
30
+ /** Adds the parent keys that hold a live edge to {@link childId} to {@link out}. */
31
+ collectParents(childId: string, out: Set<string>): void;
32
+ clear(): void;
33
+ }
34
+ //# sourceMappingURL=RelationEdgeIndex.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RelationEdgeIndex.d.ts","sourceRoot":"","sources":["../../src/store/RelationEdgeIndex.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AACH,qBAAa,iBAAiB;IAC7B,6DAA6D;IAC7D,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAyC;IACjE,qCAAqC;IACrC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAyC;IAEjE,OAAO,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI;IAKjD,UAAU,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI;IAKpD,mEAAmE;IACnE,eAAe,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,EAAE,GAAG,CAAC,MAAM,CAAC,GAAG,IAAI;IAO1D,oFAAoF;IACpF,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,GAAG,CAAC,MAAM,CAAC,GAAG,IAAI;IAOvD,KAAK,IAAI,IAAI;CAIb"}
@@ -1,189 +1,131 @@
1
- import type { HasOneRelationState } from '../handles/types.js';
2
1
  import type { EntitySnapshot } from './snapshots.js';
3
- /**
4
- * Removal type for has-many items
5
- */
6
- export type HasManyRemovalType = 'disconnect' | 'delete';
7
- /**
8
- * Has-many list state stored in SnapshotStore
9
- */
10
- export interface StoredHasManyState {
11
- /** IDs of items from server */
12
- serverIds: Set<string>;
13
- /** Explicit ordered list of item IDs, null means use default order (serverIds + plannedConnections) */
14
- orderedIds: string[] | null;
15
- /** Planned removals (disconnect or delete) keyed by entity ID */
16
- plannedRemovals: Map<string, HasManyRemovalType>;
17
- /** Planned connections (IDs to add to the list) */
18
- plannedConnections: Set<string>;
19
- /** Entity IDs created via add() - tracked for proper remove() semantics and mutation generation */
20
- createdEntities: Set<string>;
21
- version: number;
22
- }
23
- /**
24
- * Relation state stored in SnapshotStore
25
- */
26
- export interface StoredRelationState {
27
- currentId: string | null;
28
- serverId: string | null;
29
- state: HasOneRelationState;
30
- serverState: HasOneRelationState;
31
- placeholderData: Record<string, unknown>;
32
- version: number;
33
- }
2
+ import type { RekeyContext, Rekeyable } from './RekeyOrchestrator.js';
3
+ import { type SentHasOneTransition, type StoredRelationState } from './HasOneStore.js';
4
+ import { type HasManyRemovalType, type SentHasManyDelta, type StoredHasManyState } from './HasManyStore.js';
5
+ export type { StoredRelationState } from './HasOneStore.js';
6
+ export type { SentHasOneTransition } from './HasOneStore.js';
7
+ export type { HasManyAdditionKind, HasManyRemovalType, SentHasManyAddition, SentHasManyDelta, SentHasManyRemoval, StoredHasManyState, } from './HasManyStore.js';
8
+ export { computeDefaultOrderedIds } from './HasManyStore.js';
9
+ export type RelationReconciliationResult = 'applied' | 'conflict';
34
10
  /**
35
11
  * Manages has-one and has-many relation state.
36
12
  *
37
13
  * Relation keys use the format "parentType:parentId:fieldName".
38
14
  * Notification is handled by callers via callback returns.
15
+ *
16
+ * Thin facade composing a {@link HasOneStore} and a {@link HasManyStore}: each
17
+ * sub-store owns its own state map and write helper, and the facade merges the
18
+ * cross-cutting queries (mutation version sum; live-child/parent-key unions;
19
+ * dirty union) and fans out the cross-cutting mutations (rekey, removeOwned,
20
+ * clear) to both.
39
21
  */
40
- export declare class RelationStore {
41
- /** Relation states keyed by "parentType:parentId:fieldName" */
42
- private readonly relationStates;
43
- /** Has-many list states keyed by "parentType:parentId:fieldName" */
44
- private readonly hasManyStates;
45
- /**
46
- * Gets or creates relation state.
47
- */
22
+ export declare class RelationStore implements Rekeyable {
23
+ private readonly hasOne;
24
+ private readonly hasMany;
25
+ /**
26
+ * Increases whenever EITHER sub-store mutates. Used by {@link ReachabilityAnalyzer}
27
+ * to memoize its walk; only monotonic-increase-on-mutation matters, so the sum
28
+ * of the two per-store counters is sufficient.
29
+ */
30
+ getMutationVersion(): number;
31
+ /** Editable-layer has-one write counter — read by the undo write-guard. */
32
+ getEditableHasOneWriteVersion(): number;
33
+ /** Editable-layer has-many write counter — read by the undo write-guard. */
34
+ getEditableHasManyWriteVersion(): number;
48
35
  getOrCreateRelation(key: string, initial: Omit<StoredRelationState, 'version'>): StoredRelationState;
49
- /**
50
- * Gets relation state.
51
- */
52
36
  getRelation(key: string): StoredRelationState | undefined;
53
- /**
54
- * Updates relation state.
55
- * If the relation state doesn't exist, creates it using entity snapshot for server data.
56
- */
57
37
  setRelation(key: string, updates: Partial<Omit<StoredRelationState, 'version'>>, entitySnapshot: EntitySnapshot | undefined, fieldName: string): void;
58
- /**
59
- * Commits relation state (server = current).
60
- */
61
38
  commitRelation(key: string): void;
62
- /**
63
- * Resets relation to server state.
64
- */
39
+ reconcileSentRelation(key: string, transition: SentHasOneTransition): RelationReconciliationResult;
65
40
  resetRelation(key: string): void;
66
- /**
67
- * Gets or creates has-many list state.
68
- */
69
41
  getOrCreateHasMany(key: string, serverIds?: string[]): StoredHasManyState;
70
- /**
71
- * Gets has-many list state.
72
- */
73
42
  getHasMany(key: string): StoredHasManyState | undefined;
74
- /**
75
- * Sets server IDs for a has-many relation.
76
- */
77
43
  setHasManyServerIds(key: string, serverIds: string[]): void;
78
- /**
79
- * Plans a removal for a has-many item.
80
- */
81
44
  planHasManyRemoval(key: string, itemId: string, type: HasManyRemovalType): void;
82
- /**
83
- * Plans a connection for a has-many item.
84
- */
85
45
  planHasManyConnection(key: string, itemId: string): void;
86
- /**
87
- * Commits has-many state after successful persist.
88
- */
89
46
  commitHasMany(key: string, newServerIds: string[]): void;
90
- /**
91
- * Resets has-many state to server state (clears planned operations).
92
- */
47
+ reconcileSentHasMany(key: string, delta: SentHasManyDelta): RelationReconciliationResult;
93
48
  resetHasMany(key: string): void;
94
- /**
95
- * Adds a newly created entity to a has-many relation.
96
- * Used by HasManyListHandle.add() for inline entity creation.
97
- */
98
49
  addToHasMany(key: string, itemId: string): void;
99
- /**
100
- * Connects an existing (persisted) entity to a has-many relation.
101
- * Unlike addToHasMany, does NOT add to createdEntities — used for
102
- * materializing embedded connect references to existing entities.
103
- */
104
50
  connectExistingToHasMany(key: string, itemId: string): void;
105
- /**
106
- * Removes an entity from a has-many relation.
107
- * For newly created entities (via add()), cancels the connection.
108
- * For existing server entities, plans the specified removal type.
109
- * Returns true if the state changed (caller should notify), false if it was a no-op.
110
- */
111
51
  removeFromHasMany(key: string, itemId: string, removalType: HasManyRemovalType): boolean;
52
+ moveInHasMany(key: string, fromIndex: number, toIndex: number): void;
53
+ getHasManyOrderedIds(key: string): string[];
112
54
  /**
113
55
  * Collects the ids of child entities currently reachable through an entity's
114
- * LIVE relations (key prefix "parentType:parentId:"). Used by reachability-based
115
- * create detection to walk the relation graph from roots.
116
- *
117
- * Live edges are:
118
- * - has-one: currentId, when the relation is not disconnected/deleted
119
- * (a disconnected relation has a null currentId; a 'deleted' relation is
120
- * removing its target, so the target is not anchored by it).
121
- * - has-many: effective members = (serverIds ∪ plannedConnections ∪
122
- * createdEntities) minus plannedRemovals.
56
+ * LIVE relations (key prefix "parentType:parentId:"). Unions the live has-one
57
+ * edges with the live has-many members.
123
58
  */
124
59
  getLiveChildIds(keyPrefix: string): string[];
125
60
  /**
126
- * Removes all relation and has-many state owned by an entity (keys under the
127
- * given owner prefix). Called by removeEntity so a removed entity leaves no
128
- * stale relation state behind.
61
+ * Collects the composite keys ("parentType:parentId") of every entity that
62
+ * currently has a LIVE relation edge pointing at {@link childId} — the reverse
63
+ * of {@link getLiveChildIds}. Unions both sub-stores' results, scanning the
64
+ * same live edges the forward query reads so the two never disagree.
65
+ *
66
+ * {@link childId} is a BARE entity id (no type): relation state records child ids
67
+ * without their type, so the match is by id alone. This deliberately relies on
68
+ * the store-wide invariant that entity ids are globally unique across types
69
+ * (server UUIDs / minted temp ids — the same invariant behind
70
+ * EntitySnapshotStore's idIndex / keyForId), so a bare id resolves to exactly one
71
+ * entity. The forward reachability walk matches on the same bare ids, so making
72
+ * this type-aware in isolation would only diverge the two halves of one query.
129
73
  */
130
- removeOwnedRelations(keyPrefix: string): void;
74
+ getParentKeysForChild(childId: string): Set<string>;
131
75
  /**
132
- * Moves an item within a has-many relation from one index to another.
76
+ * Keys of every has-one relation owned by an entity (owner prefix
77
+ * "parentType:parentId:"). Used by the journal's entry-closure to enumerate a
78
+ * detached created entity's own relation cells.
133
79
  */
134
- moveInHasMany(key: string, fromIndex: number, toIndex: number): void;
80
+ getOwnedRelationKeys(keyPrefix: string): string[];
135
81
  /**
136
- * Gets the ordered list of item IDs for a has-many relation.
82
+ * Keys of every has-many list owned by an entity (owner prefix
83
+ * "parentType:parentId:"). Counterpart of {@link getOwnedRelationKeys}.
137
84
  */
138
- getHasManyOrderedIds(key: string): string[];
85
+ getOwnedHasManyKeys(keyPrefix: string): string[];
139
86
  /**
140
- * Restores a has-many state from a captured snapshot.
141
- * Used in pessimistic mode after successful server confirmation.
87
+ * Removes a single has-one relation state by key (undo restore of an
88
+ * absent-before-the-gesture relation).
142
89
  */
143
- restoreHasManyState(key: string, state: StoredHasManyState): void;
90
+ removeRelationState(key: string): void;
144
91
  /**
145
- * Commits all relations (hasOne and hasMany) for an entity.
92
+ * Removes a single has-many list state by key (undo restore of an
93
+ * absent-before-the-gesture list).
146
94
  */
147
- commitAllRelations(keyPrefix: string): void;
95
+ removeHasManyState(key: string): void;
148
96
  /**
149
- * Resets all relations (hasOne and hasMany) for an entity to server state.
97
+ * Removes all relation and has-many state owned by an entity (keys under the
98
+ * given owner prefix). Called by removeEntity so a removed entity leaves no
99
+ * stale relation state behind.
150
100
  */
151
- resetAllRelations(keyPrefix: string): void;
101
+ removeOwnedRelations(keyPrefix: string): void;
152
102
  /**
153
- * Gets all relation states for an entity.
103
+ * Commits all relations (hasOne and hasMany) for an entity.
154
104
  */
155
- getAllRelationsForEntity(keyPrefix: string): Map<string, StoredRelationState>;
105
+ commitAllRelations(keyPrefix: string, pendingItems?: ReadonlyMap<string, ReadonlySet<string>>): void;
156
106
  /**
157
- * Gets all has-many states for an entity.
107
+ * Resets all relations (hasOne and hasMany) for an entity to server state.
158
108
  */
159
- getAllHasManyForEntity(keyPrefix: string): Map<string, StoredHasManyState>;
109
+ resetAllRelations(keyPrefix: string): void;
160
110
  /**
161
- * Gets the list of dirty relations for an entity.
111
+ * Gets the list of dirty relations (has-one and has-many) for an entity.
162
112
  */
163
113
  getDirtyRelations(keyPrefix: string): string[];
164
- /**
165
- * Exports relation states for given keys.
166
- */
167
114
  exportRelationStates(keys: string[]): Map<string, StoredRelationState>;
168
- /**
169
- * Exports has-many states for given keys.
170
- */
171
115
  exportHasManyStates(keys: string[]): Map<string, StoredHasManyState>;
172
- /**
173
- * Imports relation states from a snapshot.
174
- * Returns the keys that were imported for notification.
175
- */
176
116
  importRelationStates(states: Map<string, StoredRelationState>): string[];
177
- /**
178
- * Imports has-many states from a snapshot.
179
- * Returns the keys that were imported for notification.
180
- */
181
117
  importHasManyStates(states: Map<string, StoredHasManyState>): string[];
182
118
  /**
183
119
  * Replaces all occurrences of oldId with newId across relation and hasMany states.
184
120
  * Used after persist to rekey temp IDs to server-assigned IDs.
185
121
  */
186
122
  replaceEntityId(oldId: string, newId: string): void;
123
+ /**
124
+ * Migrates an entity's relation state for a temp→persisted rekey: first the
125
+ * relation/has-many keys it owns (the parent id in the key), then every value
126
+ * reference to its id from other entities' relations.
127
+ */
128
+ rekey(ctx: RekeyContext): void;
187
129
  /**
188
130
  * Rekeys relation/hasMany entries owned by an entity (changes the parent ID in the key).
189
131
  */
@@ -193,9 +135,4 @@ export declare class RelationStore {
193
135
  */
194
136
  clear(): void;
195
137
  }
196
- /**
197
- * Computes the default ordered IDs for a has-many relation.
198
- * Order is: serverIds (minus removals) + plannedConnections
199
- */
200
- export declare function computeDefaultOrderedIds(state: StoredHasManyState): string[];
201
138
  //# sourceMappingURL=RelationStore.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"RelationStore.d.ts","sourceRoot":"","sources":["../../src/store/RelationStore.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"RelationStore.d.ts","sourceRoot":"","sources":["../../src/store/RelationStore.ts"],"names":[],"mappings":"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"}
@@ -13,16 +13,37 @@
13
13
  *
14
14
  * Keys use the same composite format as the rest of the store: "entityType:id".
15
15
  */
16
- export declare class RootRegistry {
16
+ import type { RekeyContext, Rekeyable } from './RekeyOrchestrator.js';
17
+ export declare class RootRegistry implements Rekeyable {
17
18
  private readonly roots;
19
+ /**
20
+ * Monotonic counter bumped whenever the root set actually changes. Used by
21
+ * {@link ReachabilityAnalyzer} to memoize the reachability walk. Bumps happen
22
+ * only on a real change so the per-render `registerParentChild` → `unregister`
23
+ * call (almost always a no-op for an already-anchored child) does not
24
+ * needlessly invalidate the cache.
25
+ */
26
+ private mutationVersion;
27
+ /**
28
+ * Monotonic counter bumped on EDITABLE-layer root changes — the create-root
29
+ * register/unregister that back an undoable gesture (createEntity,
30
+ * registerParentChild). The persist rekey and full clear deliberately do NOT
31
+ * bump it. Read by the undo write-guard (see UndoJournal). The unjournaled
32
+ * register/unregister callers (undo restore, memory sweep, unmount cleanup) all
33
+ * run outside a journal transaction, so counting them here is harmless.
34
+ */
35
+ private editableWriteVersion;
18
36
  register(key: string): void;
19
37
  unregister(key: string): void;
38
+ getEditableWriteVersion(): number;
20
39
  keys(): IterableIterator<string>;
40
+ has(key: string): boolean;
21
41
  /**
22
- * Moves a root entry from oldKey to newKey (used after persist rekeys a temp
23
- * id to a server-assigned id).
42
+ * Moves a root entry from the temp key to the persisted key (used after
43
+ * persist rekeys a temp id to a server-assigned id).
24
44
  */
25
- rekey(oldKey: string, newKey: string): void;
45
+ rekey(ctx: RekeyContext): void;
26
46
  clear(): void;
47
+ getMutationVersion(): number;
27
48
  }
28
49
  //# sourceMappingURL=RootRegistry.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"RootRegistry.d.ts","sourceRoot":"","sources":["../../src/store/RootRegistry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH,qBAAa,YAAY;IACxB,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAoB;IAE1C,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAI3B,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAI7B,IAAI,IAAI,gBAAgB,CAAC,MAAM,CAAC;IAIhC;;;OAGG;IACH,KAAK,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI;IAM3C,KAAK,IAAI,IAAI;CAGb"}
1
+ {"version":3,"file":"RootRegistry.d.ts","sourceRoot":"","sources":["../../src/store/RootRegistry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH,OAAO,KAAK,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAA;AAErE,qBAAa,YAAa,YAAW,SAAS;IAC7C,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAoB;IAE1C;;;;;;OAMG;IACH,OAAO,CAAC,eAAe,CAAI;IAE3B;;;;;;;OAOG;IACH,OAAO,CAAC,oBAAoB,CAAI;IAEhC,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAQ3B,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAO7B,uBAAuB,IAAI,MAAM;IAIjC,IAAI,IAAI,gBAAgB,CAAC,MAAM,CAAC;IAIhC,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IAIzB;;;OAGG;IACH,KAAK,CAAC,GAAG,EAAE,YAAY,GAAG,IAAI;IAO9B,KAAK,IAAI,IAAI;IAKb,kBAAkB,IAAI,MAAM;CAG5B"}