I think you read a thread of me suggesting to Duane that he should not use a top-level data structure. In his case, he stored millions of different keys in a single top-level map. For a small file system (with probably less than 10k files) it won’t make a difference.
I did indeed - this is good to know. I’ll experiment with a couple of different structures to see what works best. Checking this out next, will let ya know where I end up. Now I’ve moved down the POC checklist to the “branching” item - this one seems like it should be pretty straightforward with yjs, fingers crossed.
BTW below is where I ended up re moving items within a parent - what you shared is working like a charm with some small tweaks . Built on the ideas in this article to create an index (the
generateKeyBetween
func used but not defined in example below) that would scale to work with most realistic situations - Implementing Fractional Indexing / David Greenspan | Observable.
// the array is ordered using "pos" markers. They represent the order of the items
// this function returns the sorted array
export const getArrayContent = (arr: Y.Array<Y.Map<any>>) =>
arr
.toArray()
.sort((a, b) =>
a.get('pos') < b.get('pos') ? -1 : a.get('pos') > b.get('pos') ? 1 : 0,
const insertMap = (
arr: Y.Array<Y.Map<any>>,
map: Y.Map<any>,
index: number,
) => {
moveMap(arr, map, index);
// always appended, since sort order is not reliant on array order
arr.push([map]);
};
export const moveMap = (
arr: Y.Array<Y.Map<any>>,
map: Y.Map<any>,
index: number,
) => {
const sortedArray = getArrayContent(arr);
const currentIndex = sortedArray.findIndex((i) => i === map);
let left: Y.Map<any> | null;
let right: Y.Map<any> | null;
if (currentIndex >= 0 && currentIndex < index) {
// we're moving an item down in the list
left = sortedArray[index] || null;
right = sortedArray[index + 1] || null;
} else {
// we're adding an item for first time, or moving up in list
left = sortedArray[index - 1] || null;
right = sortedArray[index] || null;
}
const leftIndex = left ? (left.get('pos') as string) : null;
const rightIndex = right ? (right.get('pos') as string) : null;
map.set('pos', generateKeyBetween(leftIndex, rightIndex));
};