@@ -95,14 +95,29 @@ export const OrderedKeyValueApi = ({
9595 const put = async (
9696 key : string ,
9797 value : DagCborEncodable ,
98- position = - 1 ,
98+ position ?: number ,
9999 ) : Promise < string > => {
100100 // Somewhat inefficient, I suppose, but we need to know which entries are already present.
101101 const entries = await itAll ( iterator ( ) ) ;
102- const entryValue : { value : DagCborEncodable ; position : number } = {
102+
103+ // Avoid overwriting existing position; default to end of list (findIndex gives -1)
104+ let scaledPosition : number | undefined = undefined ;
105+ if ( position === undefined ) {
106+ scaledPosition = entries . find ( ( e ) => e . key === key ) ?. position ;
107+ }
108+ if ( scaledPosition === undefined ) {
109+ scaledPosition = await getScalePosition ( {
110+ entries,
111+ key,
112+ position : position ?? - 1 ,
113+ } ) ;
114+ }
115+
116+ const entryValue = {
103117 value,
104- position : await getScalePosition ( { entries , key , position } ) ,
118+ position : scaledPosition ,
105119 } ;
120+
106121 return database . addOperation ( { op : "PUT" , key, value : entryValue } ) ;
107122 } ;
108123
@@ -143,30 +158,33 @@ export const OrderedKeyValueApi = ({
143158 unknown
144159 > {
145160 let count = 0 ;
146- const keys : { [ key : string ] : true } = { } ;
147- const positions : { [ key : string ] : number } = { } ;
161+
162+ // `true` indicates a `PUT` operation; `number` indicates a `MOVE` operation
163+ const keys : { [ key : string ] : true | number } = { } ;
148164
149165 for await ( const entry of database . log . traverse ( ) ) {
150166 const { op, key, value } = entry . payload ;
167+ if ( typeof key !== "string" ) continue ;
151168
152- if ( ! key || keys [ key ] ) continue ;
153-
154- if ( op === "PUT" ) {
169+ if ( op === "PUT" && keys [ key ] !== true ) {
155170 const hash = entry . hash ;
156- const putValue = value as { value : unknown ; position ? : number } ;
171+ const putValue = value as { value : unknown ; position : number } ;
157172
173+ const position =
174+ typeof keys [ key ] === "number"
175+ ? ( keys [ key ] as number )
176+ : putValue . position ;
158177 keys [ key ] = true ;
159178 count ++ ;
160179
161180 yield {
162181 key,
163182 value : putValue . value ,
164- position : positions [ key ] ?? putValue . position ?? - 1 ,
183+ position,
165184 hash,
166185 } ;
167- } else if ( op === "MOVE" ) {
168- if ( positions [ key ] !== undefined || keys [ key ] ) continue ;
169- positions [ key ] = value as number ;
186+ } else if ( op === "MOVE" && ! keys [ key ] ) {
187+ keys [ key ] = value as number ;
170188 } else if ( op === "DEL" ) {
171189 keys [ key ] = true ;
172190 }
0 commit comments