Skip to content

Commit bb3ff42

Browse files
committed
Fix ordering of root nodes
1 parent 5dec0f5 commit bb3ff42

File tree

2 files changed

+36
-9
lines changed

2 files changed

+36
-9
lines changed

src/nested.ts

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,13 @@ import {
2121
} from "./types.js";
2222
import {
2323
asJoinedKey,
24+
asSplitKey,
2425
flatten,
2526
isNestedKey,
2627
isNestedValue,
2728
isSisterKey,
2829
isSubkey,
30+
parentKey,
2931
splitKey,
3032
toNested,
3133
} from "./utils.js";
@@ -103,31 +105,38 @@ Nested.type = type;
103105
export const NestedApi = ({ database }: { database: InternalDatabase }) => {
104106
const putEntry = async (
105107
key: NestedKey,
106-
value: DagCborEncodable,
108+
value?: DagCborEncodable,
107109
position?: number,
108110
): Promise<string> => {
109-
const entries = (await itAll(iterator())).filter((entry) =>
111+
const entries = await itAll(iterator());
112+
const sisterEntries = (entries).filter((entry) =>
110113
isSisterKey(entry.key, key),
111114
);
112115
key = asJoinedKey(key);
113116

117+
const parent = parentKey(key)
118+
if (parent && !entries.find(e=>e.key === parent))
119+
await putEntry(parent)
120+
114121
// Avoid overwriting existing position; default to end of list
115122
let scaledPosition: number | undefined = undefined;
116123
if (position === undefined) {
117-
scaledPosition = entries.find((e) => e.key === key)?.position;
124+
scaledPosition = sisterEntries.find((e) => e.key === key)?.position;
118125
}
119126
if (scaledPosition === undefined) {
120127
scaledPosition = await getScalePosition({
121-
entries,
128+
entries: sisterEntries,
122129
key,
123130
position: position ?? -1,
124131
});
125132
}
126133

134+
const entryValue: {value?: DagCborEncodable, position: number} = { position: scaledPosition };
135+
if (value !== undefined) entryValue.value = value
127136
return database.addOperation({
128137
op: "PUT",
129138
key,
130-
value: { value, position: scaledPosition },
139+
value: entryValue,
131140
});
132141
};
133142

@@ -163,8 +172,10 @@ export const NestedApi = ({ database }: { database: InternalDatabase }) => {
163172
if (k === joinedKey || isSubkey(k, joinedKey))
164173
relevantKeyValues.push({ key: k, value });
165174
}
175+
166176
let nested: PossiblyNestedValueMap | undefined =
167177
toNested(relevantKeyValues);
178+
168179
for (const k of splitKey(joinedKey)) {
169180
try {
170181
nested = (nested as NestedValueMap).get(k);
@@ -287,7 +298,12 @@ export const NestedApi = ({ database }: { database: InternalDatabase }) => {
287298
for await (const entry of iterator()) {
288299
values.unshift(entry);
289300
}
290-
const sorted = values.toSorted((a, b) => a.position - b.position);
301+
302+
const sorted = values.toSorted((a, b) => {
303+
const lengthDif = asSplitKey(a.key).length - asSplitKey(b.key).length
304+
305+
return lengthDif || (a.position - b.position)
306+
});
291307

292308
return toNested(sorted);
293309
};

src/utils.ts

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,12 @@ export const asSplitKey = (key: NestedKey): string[] =>
1919
export const asJoinedKey = (key: NestedKey): string =>
2020
typeof key === "string" ? key : joinKey(key);
2121

22+
export const parentKey = (key: NestedKey): string | undefined => {
23+
const keyComponents = asSplitKey(key);
24+
if (keyComponents.length > 1) return asJoinedKey(keyComponents.slice(0, -1));
25+
return undefined;
26+
}
27+
2228
export const isSubkey = (subkey: string, key: string): boolean => {
2329
const subkeyComponents = splitKey(subkey);
2430
const keyComponents = splitKey(key);
@@ -102,7 +108,7 @@ export const flatten = (
102108
};
103109

104110
export const toNested = (
105-
x: { key: string; value: DagCborEncodable }[],
111+
x: { key: string; value?: DagCborEncodable }[],
106112
): NestedValueMap => {
107113
const nested = new Map<string, unknown>() as NestedValueMap;
108114

@@ -118,8 +124,13 @@ export const toNested = (
118124
}
119125
const finalKeyComponent = keyComponents.pop();
120126
if (finalKeyComponent) {
121-
const finalValue = isNestedValueObject(value) ? toMap(value) : value;
122-
root.set(finalKeyComponent, finalValue as PossiblyNestedValueMap);
127+
if (value === undefined) {
128+
if (root.get(finalKeyComponent) === undefined)
129+
root.set(finalKeyComponent, new Map())
130+
} else {
131+
const finalValue = (isNestedValueObject(value) ? toMap(value) : value);
132+
root.set(finalKeyComponent, finalValue as PossiblyNestedValueMap);
133+
}
123134
}
124135
}
125136
return nested;

0 commit comments

Comments
 (0)