Restore metadata cache from database or portable backup #95
Labels
No labels
abandoned
active
audit
blocked
data-safety
difficulty:easy
difficulty:hard
difficulty:high
difficulty:medium
docs
done
duplicate
notebook-v0
open
priority:high
ready
release-critical
safe-mode
spec
spec-backlog
subsystem:api
subsystem:backlog
subsystem:bases
subsystem:ci
subsystem:command
subsystem:configuration
subsystem:consolidate
subsystem:dependencies
subsystem:desktop-electron
subsystem:diffmerge
subsystem:docker
subsystem:docs
subsystem:fuzzy
subsystem:graph
subsystem:hotkeys
subsystem:lapis
subsystem:maint
subsystem:maintenance
subsystem:markdown
subsystem:markdown-lint
subsystem:md018
subsystem:notebook
subsystem:notifications
subsystem:opfs
subsystem:package
subsystem:plugin-markdown
subsystem:plugin-tasks
subsystem:plugins
subsystem:registry
subsystem:release
subsystem:renovate
subsystem:restore
subsystem:scripts
subsystem:search
subsystem:settings
subsystem:spec
subsystem:tasks
subsystem:testing
subsystem:ui
subsystem:web
subsystem:workspace
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
lapis-notes/lapis#95
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Fix desktop cold boot metadata restore so existing vaults do not appear to rebuild metadata every startup and restored graph views show data after opening a vault.
Problem
Desktop startup currently appears to repeatedly rebuild or refresh the metadata cache. A cold boot from an existing vault can also leave Graph view empty until metadata work finishes or is manually rebuilt.
The existing spec says
MetadataCache.load()should restore fromAppDatabase, fall back to legacy snapshots, and only rebuild when needed. The observed behavior suggests the restore path is incomplete for desktop native generated state, missing portable metadata backup support, or both.Imported/copied vaults also need a way to hydrate generated metadata when the host-owned app database does not exist for the new machine/profile.
Goal
Implement a deterministic metadata restore order:
.lapis/cache/metadata-cache.jsonand hydrate the app database from it.Scope
.lapis/cache/metadata-cache.json.metadataCache.loaded.Non-goals
Implementation Details
Metadata restore order
Update
MetadataCache.load()so it:app.appDatabase.loadMetadataSnapshot().fileCache,metadataCache,resolvedLinks, andunresolvedLinks.loaded..lapis/cache/metadata-cache.jsonthroughapp.vault.adapter.AppDatabaseby saving the snapshot and upserting indexed file records derived from the snapshot.loaded.metadataCache.rebuild()after first open.loadedonly after that rebuild completes.Backup schema
Create an internal backup shape:
Rules:
sourceVaultIdis informational only and must not block restore for imported/copied vaults.Snapshot persistence
Replace the current debounced-only metadata persistence path with explicit helpers:
saveSnapshotNow():AppDatabase.scheduleSnapshotSave():flushSnapshotSave():Continue saving metadata changes after create/modify/delete/rename.
Filesystem watch ignore
Update workspace filesystem watching so changes under
.lapis/cache/metadata-cache.jsondo not cause vault reloads or metadata reprocessing.Prefer a narrow ignore helper, e.g.:
Use it in native and polling file-watch event handling before
reloadVault().Electron native DB behavior
Update Electron main-process generated-state helpers:
desktop_db_load_statemust returnnullwithout creatingvault-state/<vaultId>.sqlite3when no SQLite DB or legacy JSON state exists.Graph cold boot behavior
No public graph API change.
Verify that:
metadataCache.loaded.If needed, add a graph view guard so the first
requestAnimationFrame()rebuild does not permanently win with an empty cache beforemetadataCache.loaded.Acceptance Criteria
metadataCache.loaded..lapis/cache/metadata-cache.jsonhydrates metadata and recreates app database state..lapis/cache/metadata-cache.jsoneven when the host user-data DB does not exist.Suggested Files or Specs To Inspect
packages/api/src/lib/cache.svelte.tspackages/api/src/lib/storage/app-database.tspackages/api/src/lib/storage/desktop-native.tspackages/api/src/lib/storage/vault-session.tspackages/workspace/src/lib/components/app/App.sveltepackages/workspace/src/lib/hooks/watch-vault.svelte.tspackages/plugins/plugin-graph/src/graph-view.tspackages/plugins/plugin-graph/src/graph-data.tspackages/desktop-electron/src-electron/main.tspackages/desktop-electron/src-electron/preload.tspackages/desktop-electron/e2e/metadata-rebuild.spec.tsspec/src/30-cross-package-contracts/storage-metadata-search.mdspec/src/20-packages/api/index.mdspec/src/20-packages/workspace/index.mdspec/src/20-packages/desktop-electron/index.mdspec/src/20-packages/plugins/graph/index.mdTest Plan
API unit tests
MetadataCache.load()applies an app-database snapshot and does not rebuild.MetadataCache.load()restores from.lapis/cache/metadata-cache.jsonwhen DB snapshot is absent.AppDatabase.Desktop/native tests
desktop_db_load_statedoes not create a SQLite file when no state exists.vault-state/<vaultId>.sqlite3.Graph/desktop e2e
userDataDir, assert graph restores with nodes/links and no full rebuild progress..lapis/cache/metadata-cache.json, relaunch, assert graph hydrates and DB state is recreated.Validation Commands
pnpm --filter @lapis-notes/api checkpnpm --filter @lapis-notes/workspace checkpnpm --filter @lapis-notes/desktop-electron checkpnpm --filter @lapis-notes/graph checkmake spec-lintmdbook build specpnpm test:smokeFollow-up Tasks
.lapis/cache/metadata-cache.json.Implementation Summary
Implemented deterministic metadata restore from app database, portable .lapis/cache/metadata-cache.json backup hydration, legacy fallback, first-open rebuild, throttled/forced backup persistence, generated-backup watch ignores, Electron no-create state load probing, and focused regression coverage.