@contember/bindx 0.1.51 → 0.1.53
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/core/ActionDispatcher.d.ts.map +1 -1
- package/dist/core/EntityLoader.d.ts +7 -0
- package/dist/core/EntityLoader.d.ts.map +1 -1
- package/dist/core/actions.d.ts +1 -2
- package/dist/core/actions.d.ts.map +1 -1
- package/dist/dataview/types.d.ts +6 -6
- package/dist/dataview/types.d.ts.map +1 -1
- package/dist/handles/EntityHandle.d.ts.map +1 -1
- package/dist/handles/HasManyListHandle.d.ts +8 -0
- package/dist/handles/HasManyListHandle.d.ts.map +1 -1
- package/dist/handles/HasOneHandle.d.ts.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/persistence/BatchPersister.d.ts.map +1 -1
- package/dist/store/HasManyStore.d.ts +94 -78
- package/dist/store/HasManyStore.d.ts.map +1 -1
- package/dist/store/RelationStore.d.ts +21 -12
- package/dist/store/RelationStore.d.ts.map +1 -1
- package/dist/store/ResponseOccurrenceIndex.d.ts +65 -0
- package/dist/store/ResponseOccurrenceIndex.d.ts.map +1 -0
- package/dist/store/SnapshotStore.d.ts +53 -15
- package/dist/store/SnapshotStore.d.ts.map +1 -1
- package/dist/store/SubscriptionManager.d.ts +19 -4
- package/dist/store/SubscriptionManager.d.ts.map +1 -1
- package/dist/store/hasManyState.d.ts +164 -0
- package/dist/store/hasManyState.d.ts.map +1 -0
- package/dist/store/relationKey.d.ts +11 -0
- package/dist/store/relationKey.d.ts.map +1 -1
- package/dist/undo/UndoJournal.d.ts.map +1 -1
- package/dist/undo/rekeyJournalEntry.d.ts +4 -4
- package/dist/undo/rekeyJournalEntry.d.ts.map +1 -1
- package/dist/utils/aliasGenerator.d.ts +1 -1
- package/dist/utils/aliasGenerator.d.ts.map +1 -1
- package/package.json +2 -2
- package/src/core/ActionDispatcher.ts +0 -1
- package/src/core/EntityLoader.ts +13 -6
- package/src/core/actions.ts +1 -3
- package/src/dataview/types.ts +6 -6
- package/src/handles/EntityHandle.ts +11 -0
- package/src/handles/HasManyListHandle.ts +15 -17
- package/src/handles/HasOneHandle.ts +4 -2
- package/src/index.ts +6 -0
- package/src/persistence/BatchPersister.ts +15 -11
- package/src/store/HasManyStore.ts +312 -488
- package/src/store/RelationStore.ts +60 -24
- package/src/store/ResponseOccurrenceIndex.ts +224 -0
- package/src/store/SnapshotStore.ts +183 -109
- package/src/store/SubscriptionManager.ts +116 -58
- package/src/store/hasManyState.ts +408 -0
- package/src/store/relationKey.ts +17 -0
- package/src/undo/UndoJournal.ts +3 -1
- package/src/undo/UndoManager.ts +1 -1
- package/src/undo/rekeyJournalEntry.ts +31 -43
- package/src/utils/aliasGenerator.ts +1 -1
package/src/store/relationKey.ts
CHANGED
|
@@ -9,6 +9,23 @@ export function parentKeyFromRelationKey(relationKey: string): string {
|
|
|
9
9
|
return relationKey.slice(0, lastSeparator)
|
|
10
10
|
}
|
|
11
11
|
|
|
12
|
+
/**
|
|
13
|
+
* Derives the parent entity type from a relation key ("parentType:parentId:fieldName").
|
|
14
|
+
* Entity type names never contain ':', so the type is everything before the first separator.
|
|
15
|
+
*/
|
|
16
|
+
export function entityTypeFromRelationKey(relationKey: string): string {
|
|
17
|
+
return relationKey.slice(0, relationKey.indexOf(':'))
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Derives the field name from a relation key ("parentType:parentId:fieldName").
|
|
22
|
+
* The counterpart of {@link parentKeyFromRelationKey}: entity ids and field names
|
|
23
|
+
* never contain ':', so the field is everything after the last separator.
|
|
24
|
+
*/
|
|
25
|
+
export function fieldFromRelationKey(relationKey: string): string {
|
|
26
|
+
return relationKey.slice(relationKey.lastIndexOf(':') + 1)
|
|
27
|
+
}
|
|
28
|
+
|
|
12
29
|
/**
|
|
13
30
|
* Derives the parent composite key ("parentType:parentId") from an owner key
|
|
14
31
|
* prefix ("parentType:parentId:") by dropping the trailing separator. Callers
|
package/src/undo/UndoJournal.ts
CHANGED
|
@@ -113,7 +113,9 @@ function collectDetachedSeedIds(active: Map<string, JournalCellImage>): Set<stri
|
|
|
113
113
|
if (image.kind === 'relation') {
|
|
114
114
|
if (image.state?.currentId) ids.add(image.state.currentId)
|
|
115
115
|
} else if (image.kind === 'hasMany' && image.state) {
|
|
116
|
-
|
|
116
|
+
for (const view of image.state.views.values()) {
|
|
117
|
+
if (view.orderedIds) for (const id of view.orderedIds) ids.add(id)
|
|
118
|
+
}
|
|
117
119
|
for (const id of image.state.plannedAdditions.keys()) ids.add(id)
|
|
118
120
|
for (const id of image.state.plannedRemovals.keys()) ids.add(id)
|
|
119
121
|
}
|
package/src/undo/UndoManager.ts
CHANGED
|
@@ -214,7 +214,7 @@ export class UndoManager {
|
|
|
214
214
|
* so stored cells keep valid keys / id references (and sealed creates drop out).
|
|
215
215
|
*/
|
|
216
216
|
private rekeyStacks(ctx: RekeyContext): void {
|
|
217
|
-
const liveServerIds = (key: string):
|
|
217
|
+
const liveServerIds = (key: string): ReadonlyMap<string, ReadonlySet<string>> => this.store.getLiveHasManyServerIds(key)
|
|
218
218
|
const undoCount = this.undoStack.length
|
|
219
219
|
const redoCount = this.redoStack.length
|
|
220
220
|
const hadPending = this.pending !== null && this.pending.size > 0
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { RekeyContext } from '../store/RekeyOrchestrator.js'
|
|
2
2
|
import { createEntitySnapshot } from '../store/snapshots.js'
|
|
3
3
|
import type { EntitySnapshot } from '../store/snapshots.js'
|
|
4
|
-
import type
|
|
4
|
+
import { cloneHasManyState, type StoredHasManyState } from '../store/hasManyState.js'
|
|
5
5
|
import type { JournalEntry, JournalCellImage } from './UndoJournal.js'
|
|
6
6
|
|
|
7
7
|
/**
|
|
@@ -15,11 +15,11 @@ import type { JournalEntry, JournalCellImage } from './UndoJournal.js'
|
|
|
15
15
|
* server-backed row — only later edits to it remain undoable.
|
|
16
16
|
*/
|
|
17
17
|
/**
|
|
18
|
-
* Looks up the live server-member ids of a has-many
|
|
19
|
-
* rekey rebase a pre-image when the just-persisted create has
|
|
20
|
-
* member of that list.
|
|
18
|
+
* Looks up the live server-member ids of a has-many relation by its key, per
|
|
19
|
+
* args-view. Lets the rekey rebase a pre-image when the just-persisted create has
|
|
20
|
+
* become a permanent member of that list.
|
|
21
21
|
*/
|
|
22
|
-
export type LiveServerIdsLookup = (relationKey: string) =>
|
|
22
|
+
export type LiveServerIdsLookup = (relationKey: string) => ReadonlyMap<string, ReadonlySet<string>>
|
|
23
23
|
|
|
24
24
|
export function rekeyJournalEntry(
|
|
25
25
|
entry: JournalEntry,
|
|
@@ -77,19 +77,19 @@ function rekeyCell(
|
|
|
77
77
|
|
|
78
78
|
const key = rekeyKey(cell.key, ctx)
|
|
79
79
|
if (!cell.state) return { ...cell, key }
|
|
80
|
-
|
|
80
|
+
const state = rekeyHasManyState(cell.state, ctx)
|
|
81
81
|
// Membership rebase: when the just-persisted create became a permanent member of
|
|
82
|
-
//
|
|
83
|
-
// dropping it. Default order picks it up automatically; an explicit
|
|
84
|
-
// the id appended.
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
82
|
+
// a live view, fold it into the (older) pre-image of that view so undo keeps it
|
|
83
|
+
// instead of dropping it. Default order picks it up automatically; an explicit
|
|
84
|
+
// order needs the id appended. Views born after the gesture are left alone —
|
|
85
|
+
// the pre-image says nothing about them.
|
|
86
|
+
const live = liveServerIds(key)
|
|
87
|
+
for (const [alias, view] of state.views) {
|
|
88
|
+
if (!live.get(alias)?.has(ctx.newId) || view.serverIds.has(ctx.newId)) continue
|
|
89
|
+
view.serverIds.add(ctx.newId)
|
|
90
|
+
if (view.orderedIds && !view.orderedIds.includes(ctx.newId)) {
|
|
91
|
+
view.orderedIds = [...view.orderedIds, ctx.newId]
|
|
91
92
|
}
|
|
92
|
-
state = { ...state, serverIds, orderedIds }
|
|
93
93
|
}
|
|
94
94
|
return { ...cell, key, state }
|
|
95
95
|
}
|
|
@@ -105,41 +105,29 @@ function rekeySnapshotId(snapshot: EntitySnapshot, ctx: RekeyContext): EntitySna
|
|
|
105
105
|
)
|
|
106
106
|
}
|
|
107
107
|
|
|
108
|
-
|
|
109
|
-
if (!set.has(oldId)) return set
|
|
110
|
-
const next = new Set(set)
|
|
111
|
-
next.delete(oldId)
|
|
112
|
-
next.add(newId)
|
|
113
|
-
return next
|
|
114
|
-
}
|
|
115
|
-
|
|
108
|
+
/** Returns a deep copy with oldId swapped for newId everywhere it appears. */
|
|
116
109
|
function rekeyHasManyState(state: StoredHasManyState, ctx: RekeyContext): StoredHasManyState {
|
|
117
|
-
const
|
|
110
|
+
const next = cloneHasManyState(state)
|
|
118
111
|
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
orderedIds =
|
|
124
|
-
orderedIds[idx] = ctx.newId
|
|
112
|
+
for (const view of next.views.values()) {
|
|
113
|
+
if (view.serverIds.delete(ctx.oldId)) view.serverIds.add(ctx.newId)
|
|
114
|
+
if (view.orderedIds) {
|
|
115
|
+
const idx = view.orderedIds.indexOf(ctx.oldId)
|
|
116
|
+
if (idx !== -1) view.orderedIds[idx] = ctx.newId
|
|
125
117
|
}
|
|
126
118
|
}
|
|
127
119
|
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
plannedAdditions
|
|
132
|
-
plannedAdditions.delete(ctx.oldId)
|
|
133
|
-
plannedAdditions.set(ctx.newId, additionKind)
|
|
120
|
+
const addition = next.plannedAdditions.get(ctx.oldId)
|
|
121
|
+
if (addition) {
|
|
122
|
+
next.plannedAdditions.delete(ctx.oldId)
|
|
123
|
+
next.plannedAdditions.set(ctx.newId, addition)
|
|
134
124
|
}
|
|
135
125
|
|
|
136
|
-
|
|
137
|
-
const removalType = plannedRemovals.get(ctx.oldId)
|
|
126
|
+
const removalType = next.plannedRemovals.get(ctx.oldId)
|
|
138
127
|
if (removalType !== undefined) {
|
|
139
|
-
plannedRemovals
|
|
140
|
-
plannedRemovals.
|
|
141
|
-
plannedRemovals.set(ctx.newId, removalType)
|
|
128
|
+
next.plannedRemovals.delete(ctx.oldId)
|
|
129
|
+
next.plannedRemovals.set(ctx.newId, removalType)
|
|
142
130
|
}
|
|
143
131
|
|
|
144
|
-
return
|
|
132
|
+
return next
|
|
145
133
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export { generateHasManyAlias } from '@contember/bindx-client'
|
|
1
|
+
export { canHasManyParamsExcludeMembers, generateHasManyAlias } from '@contember/bindx-client'
|