Files
tolaria/src/utils/pulledVaultRefresh.ts

78 lines
2.5 KiB
TypeScript
Raw Normal View History

2026-04-20 14:43:52 +02:00
import type { VaultEntry } from '../types'
interface PulledVaultRefreshOptions {
activeTabPath: string | null
getActiveTabPath?: () => string | null
2026-04-20 14:43:52 +02:00
closeAllTabs: () => void
hasUnsavedChanges: (path: string) => boolean
reloadFolders: () => Promise<unknown> | unknown
reloadVault: () => Promise<VaultEntry[]>
reloadViews: () => Promise<unknown> | unknown
replaceActiveTab: (entry: VaultEntry) => Promise<void>
updatedFiles: string[]
vaultPath: string
}
function normalizePath(path: string): string {
return path
.replaceAll('\\', '/')
.replace(/^\/private\/tmp(?=\/|$)/u, '/tmp')
.replace(/\/+$/u, '')
}
function resolveUpdatedFilePath(path: string, vaultPath: string): string {
if (path.startsWith('/')) return normalizePath(path)
return normalizePath(`${vaultPath}/${path}`)
}
function didPullUpdateActiveNote(updatedFiles: string[], vaultPath: string, activeTabPath: string): boolean {
const normalizedActivePath = normalizePath(activeTabPath)
return updatedFiles.some((path) => resolveUpdatedFilePath(path, vaultPath) === normalizedActivePath)
}
function didActivePathChange(initialPath: string, latestPath: string): boolean {
return normalizePath(initialPath) !== normalizePath(latestPath)
}
2026-04-20 14:43:52 +02:00
export async function refreshPulledVaultState(options: PulledVaultRefreshOptions): Promise<VaultEntry[]> {
const {
activeTabPath,
closeAllTabs,
getActiveTabPath,
2026-04-20 14:43:52 +02:00
hasUnsavedChanges,
reloadFolders,
reloadVault,
reloadViews,
replaceActiveTab,
updatedFiles,
vaultPath,
2026-04-20 14:43:52 +02:00
} = options
const [entries] = await Promise.all([
reloadVault(),
Promise.resolve(reloadFolders()),
Promise.resolve(reloadViews()),
])
const latestActiveTabPath = getActiveTabPath?.() ?? activeTabPath
if (!activeTabPath || !latestActiveTabPath) return entries
if (didActivePathChange(activeTabPath, latestActiveTabPath)) return entries
if (hasUnsavedChanges(latestActiveTabPath)) return entries
2026-04-20 14:43:52 +02:00
const refreshedEntry = entries.find(entry => normalizePath(entry.path) === normalizePath(latestActiveTabPath))
2026-04-20 14:43:52 +02:00
if (!refreshedEntry) {
closeAllTabs()
return entries
}
// Native BlockNote can keep rendering the previous document after a pull that
// changes the active file in place. Dropping the tab first forces a full
// reopen for that specific case without affecting unrelated pull updates.
if (didPullUpdateActiveNote(updatedFiles, vaultPath, latestActiveTabPath)) {
closeAllTabs()
}
2026-04-20 14:43:52 +02:00
await replaceActiveTab(refreshedEntry)
return entries
}