Reorder params and add error

This commit is contained in:
Andras Schmelczer 2026-09-27 22:16:38 +01:00
commit 85bb96a44e
6 changed files with 23 additions and 14 deletions

View file

@ -19,6 +19,13 @@ export class AuthenticationError extends Error {
}
}
export class ConflictingPathError extends Error {
public constructor(path: string) {
super(`Conflicting path: ${path}`);
this.name = "ConflictingPathError";
}
}
export class PermanentSyncError extends Error {}
export class LocalChangesDuringReconciliation extends Error {}

View file

@ -14,10 +14,10 @@ test("current state keeps absent optional fields absent across save and reload",
const restart = (): Database =>
new Database(
saved,
"vault",
async (next) => {
saved = structuredClone(next);
},
"vault",
async () => structuredClone(saved)
);
const db = restart();
@ -36,10 +36,10 @@ test("current reset state is restored after an uncertain save", async () => {
};
const db = new Database(
undefined,
"vault",
async () => {
throw new Error("interrupted");
},
"vault",
async () => structuredClone(saved)
);
await assert.rejects(db.save(), /interrupted/);

View file

@ -73,8 +73,8 @@ export class Database {
public constructor(
initial: StoredDatabase | undefined,
private readonly saveData: (data: StoredDatabase) => Promise<void>,
vaultKey: string,
private readonly saveData: (data: StoredDatabase) => Promise<void>,
private readonly loadData: () => Promise<StoredDatabase | undefined>
) {
const state =

View file

@ -19,12 +19,12 @@ for (const change of ["version", "identity", "path", "delete"] as const) {
const content = new TextEncoder().encode("same bytes");
const digest = await hash(content);
const state = createEmptyDatabase("test");
state.local.a = "a.md";
state.actualFileManifest.a = "a.md";
state.documents.a = { base: { vaultUpdateId: 1, hash: digest } };
const database = new Database(
state,
async () => undefined,
"test",
async () => undefined,
async () => undefined
);
const sent: { documentsWithCursors: DocumentWithCursors[] }[] = [];
@ -39,17 +39,17 @@ for (const change of ["version", "identity", "path", "delete"] as const) {
read: async (): Promise<{ content: Uint8Array }> => {
const current = database.state;
assert.ok(current.documents.a?.base);
assert.ok(current.local.a !== undefined);
assert.ok(current.actualFileManifest.a !== undefined);
if (change === "delete") {
delete current.local.a;
delete current.actualFileManifest.a;
} else if (change === "version") {
current.documents.a.base.vaultUpdateId = 2;
} else if (change === "identity") {
current.local.replacement = current.local.a;
current.actualFileManifest.replacement = current.actualFileManifest.a;
current.documents.replacement = current.documents.a;
delete current.local.a;
delete current.actualFileManifest.a;
} else {
current.local.a = "moved.md";
current.actualFileManifest.a = "moved.md";
}
return { content };

View file

@ -3,6 +3,7 @@ import { spawnSync } from "node:child_process";
import { resolve } from "node:path";
import { pathToFileURL } from "node:url";
import { test } from "node:test";
import { ConflictingPathError } from "../errors/errors";
import {
allocatePortablePath,
validatePortablePaths,
@ -87,7 +88,7 @@ test("shared directories remain distinct from aliases and file ancestors", () =>
]) {
assert.throws(() => {
validatePortablePaths(paths);
}, /Conflicting path/);
}, ConflictingPathError);
}
});
@ -236,13 +237,13 @@ test("allocation resolves both ancestor and leaf collisions without changing sib
);
});
test("manifest conflicts throw TypeError", () => {
test("manifest conflicts throw ConflictingPathError", () => {
assert.throws(
() => {
validatePortablePaths(["a.md", "A.md"]);
},
{
name: "TypeError",
name: "ConflictingPathError",
message: "Conflicting path: A.md"
}
);

View file

@ -1,3 +1,4 @@
import { ConflictingPathError } from "../errors/errors";
import type { DocumentId, RelativePath } from "../persistence/database";
export const INTERNAL_DIRECTORY = ".vault-link-sync";
@ -78,7 +79,7 @@ export function validatePortablePaths(paths: Iterable<RelativePath>): void {
previous &&
(previous.spelling !== spelling || previous.file || file)
) {
throw new TypeError(`Conflicting path: ${path}`);
throw new ConflictingPathError(path);
}
const node = previous ?? { id: nodes.size + 1, spelling, file };