import { Database, emptyState, type StoredDatabase } from "../sync-client/src/persistence/database"; import { Settings } from "../sync-client/src/persistence/settings"; import { FileOperations } from "../sync-client/src/file-operations/file-operations"; import { Syncer } from "../sync-client/src/sync-operations/syncer"; import { toStoredSnapshot } from "../sync-client/src/sync-operations/content"; import { Logger } from "../sync-client/src/tracing/logger"; import { SyncHistory } from "../sync-client/src/tracing/sync-history"; import { FixedSizeDocumentCache } from "../sync-client/src/utils/data-structures/fix-sized-cache"; import { EventListeners } from "../sync-client/src/utils/data-structures/event-listeners"; import type { ServerConfig } from "../sync-client/src/services/server-config"; import type { SyncService } from "../sync-client/src/services/sync-service"; import type { WebSocketManager } from "../sync-client/src/services/websocket-manager"; import { MemoryDisk, MemoryPersistence } from "./storage"; import type { LocalChange } from "../sync-client/src/sync-operations/local-changes"; export const bytes = (text: string) => new TextEncoder().encode(text); export const head = (id: string, version: number, content: string) => ({ documentId: id, vaultUpdateId: version, contentSize: bytes(content).length, updatedDate: "2026-09-19T00:00:00Z", userId: "user", deviceId: "device" }); export async function fixture( contents: Record = { "a.md": "local" }, service: Partial = {}, recovered?: { disk: MemoryDisk; persistence: MemoryPersistence } ) { const disk = recovered?.disk ?? new MemoryDisk(); const initial = recovered ? (recovered.persistence.snapshot().database as StoredDatabase) : emptyState("test"); if (!recovered) { initial.initialized = true; for (const [path, content] of Object.entries(contents)) { await disk.userWrite(path, bytes(content)); const id = path.split(".")[0]; initial.local[id] = path; initial.documents[id] = { materialized: true, observedHash: ( await toStoredSnapshot({ content: bytes(content) }) ).hash }; } initial.fileManifest = { fileManifestId: 1, entries: { ...initial.local } }; } const persistence = recovered?.persistence ?? new MemoryPersistence({ database: initial }); const logger = new Logger(); const database = new Database( initial, async (next) => persistence.save({ database: next }), "test", async () => (await persistence.load()).database as StoredDatabase ); const config = { initialize: async () => {}, getConfig: async () => ({ mergeableFileExtensions: ["md"] }), reset: () => {} } as unknown as ServerConfig; const settings = new Settings( logger, { syncIntervalMs: 0 }, async () => {} ); const changes: LocalChange[] = []; const files = new FileOperations( disk.session(), database, config, undefined, { entries: () => changes, flush: async () => {} }, (path, size) => settings.isIgnored(path) || settings.isOversized(size) ); const websocket = { onWebSocketStatusChanged: new EventListeners(), onRemoteVaultUpdateReceived: new EventListeners() } as unknown as WebSocketManager; const contentCache = new FixedSizeDocumentCache(1024); const syncer = new Syncer( "device", logger, database, settings, service as SyncService, websocket, files, config, new SyncHistory(logger), contentCache, { entries: changes, save: async () => {} } ); const internals = syncer as unknown as { finishPending: () => Promise; preparePush: () => Promise; scan: ( initial?: import("../sync-client/src/services/types/VaultSnapshot").VaultSnapshot ) => Promise; incorporateEventBatch: ( batch: import("../sync-client/src/services/types/EventBatch").EventBatch ) => Promise; stopped: boolean; incorporateFileManifest: (remote: { fileManifestId: number; entries: Record; }) => Promise; incorporateContent: (remote: ReturnType) => Promise; }; return { disk, database, files, settings, syncer, internals, persistence, changes, contentCache }; }