.
This commit is contained in:
parent
4c002f9acd
commit
b07aa589ff
3 changed files with 728 additions and 530 deletions
|
|
@ -1,20 +1,15 @@
|
|||
import { reconcile } from "reconcile-text";
|
||||
import type {
|
||||
FileSnapshot,
|
||||
FileSystemOperations
|
||||
} from "./filesystem-operations";
|
||||
import type {
|
||||
Database,
|
||||
EngineState,
|
||||
StoredSnapshot
|
||||
} from "../persistence/database";
|
||||
import { isInternalPath } from "../utils/portable-path";
|
||||
import { FilePaths } from "./file-paths";
|
||||
import type { FileSystemOperations } from "./filesystem-operations";
|
||||
import type { Database, EngineState } from "../persistence/database";
|
||||
import {
|
||||
fromStoredSnapshot,
|
||||
toStoredSnapshot,
|
||||
mergeContent
|
||||
} from "../sync-operations/content";
|
||||
type FileSnapshot,
|
||||
type StoredSnapshot
|
||||
} from "../snapshot";
|
||||
import { isInternalPath } from "../utils/portable-path";
|
||||
import { FilePaths } from "./file-paths";
|
||||
import { mergeContent } from "../sync-operations/content";
|
||||
import { hash } from "../utils/hash";
|
||||
import { isBinary } from "../utils/is-binary";
|
||||
import { isFileTypeMergeable } from "../utils/is-file-type-mergeable";
|
||||
|
|
@ -89,7 +84,7 @@ export class FileOperations {
|
|||
): Promise<void> {
|
||||
const state = structuredClone(this.applying ?? this.database.state);
|
||||
|
||||
if (!state.initialized) return;
|
||||
if (state.lastSeenUpdateId === undefined) return;
|
||||
|
||||
for (const pending of unappliedChanges(state, previous))
|
||||
applyLocalChange(state, pending, () => false);
|
||||
|
|
@ -118,7 +113,7 @@ export class FileOperations {
|
|||
};
|
||||
guard();
|
||||
const current = structuredClone(this.database.state);
|
||||
current.initialized = next.initialized;
|
||||
current.lastSeenUpdateId = next.lastSeenUpdateId;
|
||||
this.applying = current;
|
||||
const paths = new Set<string>();
|
||||
const observeChanges = async (): Promise<void> => {
|
||||
|
|
@ -145,7 +140,7 @@ export class FileOperations {
|
|||
...Object.keys(next.local)
|
||||
])) {
|
||||
await observeChanges();
|
||||
let from = current.documents[id]?.materialized
|
||||
let from = current.documents[id]?.observedHash !== undefined
|
||||
? current.local[id]
|
||||
: undefined;
|
||||
let to = next.local[id];
|
||||
|
|
@ -166,7 +161,6 @@ export class FileOperations {
|
|||
);
|
||||
(next.excluded ??= {})[id] =
|
||||
current.fileManifest.entries[id] ?? null;
|
||||
(next.protectedPaths ??= []).push(from);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
|
@ -187,7 +181,7 @@ export class FileOperations {
|
|||
mutate
|
||||
);
|
||||
next.local[id] = to;
|
||||
from = current.documents[id]?.materialized
|
||||
from = current.documents[id]?.observedHash !== undefined
|
||||
? current.local[id]
|
||||
: undefined;
|
||||
if (from !== undefined) {
|
||||
|
|
@ -211,7 +205,7 @@ export class FileOperations {
|
|||
.mergeableFileExtensions;
|
||||
await mutate(async () => {
|
||||
current.local[id] = to;
|
||||
current.documents[id] = { materialized: true };
|
||||
current.documents[id] = { observedHash: "" };
|
||||
next.documents[id].observedHash =
|
||||
await this.updateContent(
|
||||
to,
|
||||
|
|
@ -222,7 +216,6 @@ export class FileOperations {
|
|||
});
|
||||
}
|
||||
paths.add(to);
|
||||
next.documents[id].materialized = true;
|
||||
current.local[id] = to;
|
||||
current.documents[id] = structuredClone(next.documents[id]);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,13 +29,12 @@ export class FilePaths {
|
|||
for (const child of children) {
|
||||
const occupant = Object.keys(current.local).find(
|
||||
(key) =>
|
||||
current.documents[key]?.materialized &&
|
||||
current.documents[key]?.observedHash !== undefined &&
|
||||
current.local[key] === child
|
||||
);
|
||||
const info = await this.fs.stat(child);
|
||||
if (
|
||||
!info ||
|
||||
next.protectedPaths?.includes(child) ||
|
||||
this.isProtectedFile(child, info.size) ||
|
||||
(obstruction.kind === "directory" &&
|
||||
(occupant === undefined ||
|
||||
|
|
@ -59,8 +58,8 @@ export class FilePaths {
|
|||
await this.fs.rename(occupant.path, displaced);
|
||||
});
|
||||
if (!current.documents[occupant.id]) {
|
||||
current.documents[occupant.id] = { materialized: true };
|
||||
next.documents[occupant.id] = { materialized: true };
|
||||
current.documents[occupant.id] = { observedHash: "" };
|
||||
next.documents[occupant.id] = { observedHash: "" };
|
||||
next.local[occupant.id] = displaced;
|
||||
} else if (next.local[occupant.id] === occupant.path)
|
||||
next.local[occupant.id] = displaced;
|
||||
|
|
|
|||
|
|
@ -1,11 +1,6 @@
|
|||
import type { CursorPosition, TextWithCursors } from "reconcile-text";
|
||||
import type { TextWithCursors } from "reconcile-text";
|
||||
import type { RelativePath } from "../persistence/database";
|
||||
|
||||
export interface FileSnapshot {
|
||||
content: Uint8Array;
|
||||
/** Optional editor selections, moved with the file and applied with its bytes. */
|
||||
cursors?: CursorPosition[];
|
||||
}
|
||||
import type { FileSnapshot } from "../snapshot";
|
||||
|
||||
/** Filesystem operations act on the current user-owned namespace.
|
||||
* Paths are vault-relative. Never follow symlinks (including ancestor symlinks).
|
||||
|
|
|
|||
Loading…
Reference in a new issue