import * as Y from "yjs";
import { HttpError } from "../errors";
import { withStore } from "../git/store";
import type { GitStore } from "../git/store";
import { MAX_POINTER_BYTES, parseLfsPointer } from "../lfs/pointer";
import { loadRepoById } from "../repos";
import { readBounded } from "./blob-read";
import { FILES_MAP, textKey } from "~/lib/editor-protocol";
import type { ChangeStatus, FileKind, FileMeta } from "~/lib/editor-protocol";
export const MAX_ROOM_FILES = 300;
export const MAX_TEXT_BYTES = 1024 * 1024;
const EVICT_TARGET = 0.8;
const decoder = new TextDecoder();
export type RoomSql = SqlStorage;
export type HeadFile = { kind: FileKind; size: number; text: string | null } | null;
export function filesMap(doc: Y.Doc): Y.Map<FileMeta> {
return doc.getMap<FileMeta>(FILES_MAP);
}
export function textOf(doc: Y.Doc, path: string): Y.Text {
return doc.getText(textKey(path));
}
/** Rewrites a Y.Text to `next` touching only the differing middle, so remote cursors stay put. */
export function replaceText(text: Y.Text, next: string): void {
const current = text.toString();
if (current === next) return;
let start = 0;
while (start < current.length && start < next.length && current[start] === next[start]) start++;
let end = 0;
while (
end < current.length - start &&
end < next.length - start &&
current[current.length - 1 - end] === next[next.length - 1 - end]
) {
end++;