@@ -21,11 +21,13 @@ import {
2121} from "./types.js" ;
2222import {
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;
103105export 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 } ;
0 commit comments