2024-01-02 18:18:11 +03:00
|
|
|
/** Translation of `yjsModel` types to and from the `fileFormat` representation. */
|
|
|
|
|
|
|
|
import * as json from 'lib0/json'
|
2024-01-24 22:22:05 +03:00
|
|
|
import { ExternalId, IdMap, sourceRangeFromKey } from '../shared/yjsModel'
|
2024-01-02 18:18:11 +03:00
|
|
|
import * as fileFormat from './fileFormat'
|
|
|
|
|
|
|
|
export function deserializeIdMap(idMapJson: string) {
|
|
|
|
const idMapMeta = fileFormat.tryParseIdMapOrFallback(idMapJson)
|
|
|
|
const idMap = new IdMap()
|
|
|
|
for (const [{ index, size }, id] of idMapMeta) {
|
|
|
|
const range = [index.value, index.value + size.value]
|
|
|
|
if (typeof range[0] !== 'number' || typeof range[1] !== 'number') {
|
|
|
|
console.error(`Invalid range for id ${id}:`, range)
|
|
|
|
continue
|
|
|
|
}
|
2024-01-24 22:22:05 +03:00
|
|
|
idMap.insertKnownId([index.value, index.value + size.value], id as ExternalId)
|
2024-01-02 18:18:11 +03:00
|
|
|
}
|
|
|
|
return idMap
|
|
|
|
}
|
|
|
|
|
|
|
|
export function serializeIdMap(map: IdMap): string {
|
|
|
|
map.validate()
|
|
|
|
return json.stringify(idMapToArray(map))
|
|
|
|
}
|
|
|
|
|
|
|
|
function idMapToArray(map: IdMap): fileFormat.IdMapEntry[] {
|
|
|
|
const entries: fileFormat.IdMapEntry[] = []
|
|
|
|
map.entries().forEach(([rangeBuffer, id]) => {
|
2024-01-24 22:22:05 +03:00
|
|
|
const decoded = sourceRangeFromKey(rangeBuffer)
|
2024-01-02 18:18:11 +03:00
|
|
|
const index = decoded[0]
|
|
|
|
const endIndex = decoded[1]
|
|
|
|
if (index == null || endIndex == null) return
|
|
|
|
const size = endIndex - index
|
|
|
|
entries.push([{ index: { value: index }, size: { value: size } }, id])
|
|
|
|
})
|
|
|
|
entries.sort(idMapCmp)
|
|
|
|
return entries
|
|
|
|
}
|
|
|
|
|
|
|
|
function idMapCmp(a: fileFormat.IdMapEntry, b: fileFormat.IdMapEntry) {
|
|
|
|
const val1 = a[0]?.index?.value ?? 0
|
|
|
|
const val2 = b[0]?.index?.value ?? 0
|
|
|
|
if (val1 === val2) {
|
|
|
|
const size1 = a[0]?.size.value ?? 0
|
|
|
|
const size2 = b[0]?.size.value ?? 0
|
|
|
|
return size1 - size2
|
|
|
|
}
|
|
|
|
return val1 - val2
|
|
|
|
}
|