diff --git a/frontend/sync-client/src/index.ts b/frontend/sync-client/src/index.ts index e7476470..88a47698 100644 --- a/frontend/sync-client/src/index.ts +++ b/frontend/sync-client/src/index.ts @@ -21,12 +21,15 @@ export { export { Logger, LogLevel, LogLine } from "./tracing/logger"; export { type SyncSettings, DEFAULT_SETTINGS } from "./persistence/settings"; export { rateLimit } from "./utils/rate-limit"; -export type { RelativePath, StoredDatabase } from "./persistence/database"; export type { - FileSystemOperations, - FileSnapshot -} from "./file-operations/filesystem-operations"; -export type { PersistenceProvider } from "./persistence/persistence"; + DocumentId, + RelativePath, + StoredDatabase, + VaultUpdateId +} from "./persistence/database"; +export type { FileSystemOperations } from "./file-operations/filesystem-operations"; +export type { FileSnapshot } from "./snapshot"; +export type { MetadataPersistenceProvider as PersistenceProvider } from "./persistence/metadata-persistence-provider"; export type { CursorSpan } from "./services/types/CursorSpan"; export type { ClientCursors } from "./services/types/ClientCursors"; export type { NetworkConnectionStatus } from "./types/network-connection-status"; @@ -36,7 +39,7 @@ export type { } from "./errors/errors"; export type { MaybeOutdatedClientCursors } from "./types/maybe-outdated-client-cursors"; export { DocumentSyncStatus } from "./types/document-sync-status"; -export { SyncClient } from "./sync-client"; +export { SyncClient, type StoredClient } from "./sync-client"; export type { TextWithCursors, CursorPosition } from "reconcile-text"; export const debugging = { diff --git a/frontend/sync-client/src/persistence/settings.ts b/frontend/sync-client/src/persistence/settings.ts index 1b592d65..c3575548 100644 --- a/frontend/sync-client/src/persistence/settings.ts +++ b/frontend/sync-client/src/persistence/settings.ts @@ -1,3 +1,4 @@ +import type { RelativePath } from "./database"; import type { Logger } from "../tracing/logger"; import { globsToRegexes } from "../utils/globs-to-regexes"; import { isInternalPath } from "../utils/portable-path"; @@ -68,7 +69,7 @@ export class Settings { ); } - public isIgnored(path: string): boolean { + public isIgnored(path: RelativePath): boolean { return ( isInternalPath(path) || this.ignorePatterns.some((pattern) => pattern.test(path)) @@ -111,17 +112,20 @@ export class Settings { await this.saveData(next); this.settings = next; - if (update.ignorePatterns !== undefined) + if (update.ignorePatterns !== undefined) { this.ignorePatterns = globsToRegexes( next.ignorePatterns, this.logger ); + } return [this.getSettings(), oldSettings] as const; }); // Listeners can themselves update settings. Never await them while // holding a lock needed by the operation they invoke. - if (notify) await this.onSettingsChanged.triggerAsync(...change); + if (notify) { + await this.onSettingsChanged.triggerAsync(...change); + } } } diff --git a/frontend/sync-client/src/services/types/EventBatch.ts b/frontend/sync-client/src/services/types/EventBatch.ts index a3bfb573..feb7ef59 100644 --- a/frontend/sync-client/src/services/types/EventBatch.ts +++ b/frontend/sync-client/src/services/types/EventBatch.ts @@ -5,4 +5,4 @@ export type EventBatch = { headEventId: number, /** * Last event in this page; `head_event_id` is the vault's current head. */ -endEventId?: number, events: Array, }; +endEventId: number, events: Array, }; diff --git a/frontend/sync-client/src/services/types/PingResponse.ts b/frontend/sync-client/src/services/types/PingResponse.ts index c38845d2..1bd35bb5 100644 --- a/frontend/sync-client/src/services/types/PingResponse.ts +++ b/frontend/sync-client/src/services/types/PingResponse.ts @@ -18,7 +18,7 @@ isAuthenticated: boolean, */ mergeableFileExtensions: Array, /** - * API version ensuring backwards & forwards compatibility between the client + * API version that must match exactly between the client * and server. */ supportedApiVersion: number, }; diff --git a/frontend/sync-client/src/snapshot.ts b/frontend/sync-client/src/snapshot.ts new file mode 100644 index 00000000..f2802233 --- /dev/null +++ b/frontend/sync-client/src/snapshot.ts @@ -0,0 +1,20 @@ +import type { CursorPosition } from "reconcile-text"; +import { hash } from "./utils/hash"; + +export interface FileSnapshot { + content: Uint8Array; + cursors?: CursorPosition[]; +} + +export interface HashedSnapshot extends FileSnapshot { + hash: string; +} + +export async function hashSnapshot( + snapshot: FileSnapshot +): Promise { + // Own the bytes so later adapter mutations cannot invalidate the hash + const content = new Uint8Array(snapshot.content); + + return { content, cursors: snapshot.cursors, hash: await hash(content) }; +} diff --git a/frontend/sync-client/src/tracing/sync-history.ts b/frontend/sync-client/src/tracing/sync-history.ts index 31f77283..a0e0b348 100644 --- a/frontend/sync-client/src/tracing/sync-history.ts +++ b/frontend/sync-client/src/tracing/sync-history.ts @@ -88,11 +88,11 @@ export class SyncHistory { } /** - * Insert the entry at the beginning of the history list. If the entry - * already in the list, it will get moved to the beginning and updated. - * - * If the entry list is too long, the oldest entry will be removed. - */ + * Insert the entry at the beginning of the history list. If the entry + * already in the list, it will get moved to the beginning and updated. + * + * If the entry list is too long, the oldest entry will be removed. + */ public addHistoryEntry(entry: CommonHistoryEntry): void { const historyEntry = { ...entry, diff --git a/frontend/sync-client/src/types/file-manifest-entries.ts b/frontend/sync-client/src/types/file-manifest-entries.ts index 1e23dd06..c9acccf9 100644 --- a/frontend/sync-client/src/types/file-manifest-entries.ts +++ b/frontend/sync-client/src/types/file-manifest-entries.ts @@ -1,3 +1,3 @@ -import type { FileManifest } from "../services/types/FileManifest"; +import type { DocumentId, RelativePath } from "../persistence/database"; -export type FileManifestEntries = FileManifest["entries"]; +export type FileManifestEntries = Record;