From 92b0dbdfb138ef935086aa154c74db72d5b667d2 Mon Sep 17 00:00:00 2001 From: Debankan Roy Date: Wed, 19 Aug 2026 19:45:00 +0530 Subject: [PATCH 01/11] feat: Added interface, function for autosave int settings --- packages/core/src/settings/schema.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/core/src/settings/schema.ts b/packages/core/src/settings/schema.ts index 18b6453..feca24f 100644 --- a/packages/core/src/settings/schema.ts +++ b/packages/core/src/settings/schema.ts @@ -4,6 +4,7 @@ export interface Settings { editor: { fontSize: number; lineWrapping: boolean; + autoSaveInterval: number; }; } @@ -13,6 +14,7 @@ export const DEFAULT_SETTINGS: Settings = { editor: { fontSize: 14, lineWrapping: true, + autoSaveInterval: 1000, }, }; @@ -26,6 +28,7 @@ export function isSettings(value: unknown): value is Settings { typeof editor === "object" && editor !== null && typeof editor.fontSize === "number" && - typeof editor.lineWrapping === "boolean" + typeof editor.lineWrapping === "boolean" && + typeof editor.autoSaveInterval === "number" ); } From 7c1d723c56197a9845a1332389c901cfe4316b7d Mon Sep 17 00:00:00 2001 From: Debankan Roy Date: Wed, 19 Aug 2026 20:39:34 +0530 Subject: [PATCH 02/11] feat: Updated Home page to fix the update, save, refresh. Also updated the backlinkpane view --- apps/desktop/src/routes/Home.tsx | 129 ++++++++++++++++++++----------- 1 file changed, 85 insertions(+), 44 deletions(-) diff --git a/apps/desktop/src/routes/Home.tsx b/apps/desktop/src/routes/Home.tsx index 7325f04..e3b1032 100644 --- a/apps/desktop/src/routes/Home.tsx +++ b/apps/desktop/src/routes/Home.tsx @@ -1,4 +1,4 @@ -import { useEffect, useMemo, useState } from "react"; +import { useEffect, useMemo, useState, useRef, useCallback } from "react"; import { CodeMirrorEditor } from "@trachyte/editor"; import { DiskAdapter, @@ -26,16 +26,23 @@ export default function Home() { const [content, setContent] = useState(""); const [indexer, setIndexer] = useState(null); + type SaveStatus = "idle" | "saving" | "saved" | "error"; + const [saveStatus, setSaveStatus] = useState("idle"); + const manager = useMemo(() => new VaultManager(new DiskAdapter(tauriDriver)), []); const reloader = useMemo(() => new ExternalChangeReloader(manager.events, 100), [manager]); const [doctorOpen, setDoctorOpen] = useState(false); const [paletteOpen, setPaletteOpen] = useState(false); const [scrollToPos, setScrollToPos] = useState<{ from: number; to: number } | null>(null); + const saveTimeoutRef = useRef | null>(null); + const lastSavedContentRef = useRef(content); + const linkIndex = useMemo( () => new Map(notes.map((n) => [n.replace(/\.md$/i, ""), `Notes/${n}`])), [notes], ); + async function openVault() { const raw = inputPath.trim(); if (!raw) return; @@ -53,6 +60,7 @@ export default function Home() { } setCurrentRel(null); setContent(""); + lastSavedContentRef.current = ""; const idx = new Indexer({ fs: manager.getAdapter(), index: tauriIndexDriver, @@ -69,6 +77,7 @@ export default function Home() { setCurrentRel(rel); const text = await manager.getAdapter().readFile(joinPath(openedVault, rel)); setContent(text); + lastSavedContentRef.current = text; reloader.watch(rel); if (blockId) { @@ -83,6 +92,50 @@ export default function Home() { } } + const save = useCallback(async () => { + if (!openedVault || !currentRel) return; + setSaveStatus("saving"); + try { + await manager.getAdapter().writeFile(joinPath(openedVault, currentRel), content); + lastSavedContentRef.current = content; + setSaveStatus("saved"); + setTimeout(() => setSaveStatus("idle"), 2000); + } catch { + setSaveStatus("error"); + } + }, [openedVault, currentRel, content, manager]); + + useEffect(() => { + if (!openedVault || !currentRel) return; + const interval = 1000; + if (interval <= 0) return; + if (content !== lastSavedContentRef.current) { + if (saveTimeoutRef.current) clearTimeout(saveTimeoutRef.current); + setSaveStatus("saving"); + saveTimeoutRef.current = setTimeout(save, interval); + } + return () => { + if (saveTimeoutRef.current) clearTimeout(saveTimeoutRef.current); + }; + }, [content, openedVault, currentRel, save]); + + useEffect(() => { + if (!openedVault) return; + const unsubscribe = manager.events.on((event) => { + if ( + event.type === "file:created" || + event.type === "file:deleted" || + event.type === "file:renamed" + ) { + void (async () => { + const list = await manager.list(); + setNotes(list); + })(); + } + }); + return () => unsubscribe(); + }, [manager, openedVault]); + useEffect(() => { let disposed = false; let unlisten: (() => void) | null = null; @@ -109,6 +162,7 @@ export default function Home() { if (rel !== currentRel) return; const text = await manager.getAdapter().readFile(joinPath(openedVault, rel)); setContent(text); + lastSavedContentRef.current = text; }); }, [reloader, manager, openedVault, currentRel]); @@ -117,6 +171,7 @@ export default function Home() { return () => reloader.dispose(); }, [reloader]); + // Global keydown: Ctrl+Shift+D (doctor), Ctrl+Shift+F (search), Ctrl+S (save) useEffect(() => { function onKeyDown(e: KeyboardEvent) { if (e.ctrlKey && e.shiftKey && e.key.toLowerCase() === "d") { @@ -127,41 +182,19 @@ export default function Home() { e.preventDefault(); setPaletteOpen((v) => !v); } + if (e.ctrlKey && e.key.toLowerCase() === "s") { + e.preventDefault(); + void save(); + } } window.addEventListener("keydown", onKeyDown); return () => window.removeEventListener("keydown", onKeyDown); - }, []); - - // useEffect(() => { - // function onKeyDown(e: KeyboardEvent) { - // if (e.ctrlKey && e.shiftKey && e.key.toLowerCase() === "d") { - // e.preventDefault(); - // setDoctorOpen((v) => !v); - // } - // } - // window.addEventListener("keydown", onKeyDown); - // return () => window.removeEventListener("keydown", onKeyDown); - // }, []); + }, [save]); useEffect(() => { return () => indexer?.dispose(); }, [indexer]); - // useEffect(() => { - // function onKeyDown(e: KeyboardEvent) { - // if (e.ctrlKey && e.shiftKey && e.key.toLowerCase() === "d") { - // e.preventDefault(); - // setDoctorOpen((v) => !v); - // } - // if (e.ctrlKey && e.shiftKey && e.key.toLowerCase() === "f") { - // e.preventDefault(); - // setPaletteOpen((v) => !v); - // } - // } - // window.addEventListener("keydown", onKeyDown); - // return () => window.removeEventListener("keydown", onKeyDown); - // }, []); - return (
-
+
{currentRel === null ? ( -
+
Open a note to start editing
) : ( - void openNote(path, blockId)} - scrollToPos={scrollToPos} - /> - )} - {currentRel && ( - void openNote(path)} - /> + <> +
+ void openNote(path, blockId)} + scrollToPos={scrollToPos} + /> + {/* Save status indicator */} +
+ {saveStatus === "saving" && "Saving…"} + {saveStatus === "saved" && "Saved"} + {saveStatus === "error" && Save failed} +
+
+ void openNote(path)} + /> + )}
{doctorOpen && openedVault !== null && ( From 91535df03ba95628288a9db98e01091ac74bf834 Mon Sep 17 00:00:00 2001 From: Debankan Roy Date: Wed, 19 Aug 2026 20:42:02 +0530 Subject: [PATCH 03/11] feat: Updated settings tests to account for autosave --- .../core/src/settings/__tests__/settings.spec.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/core/src/settings/__tests__/settings.spec.ts b/packages/core/src/settings/__tests__/settings.spec.ts index dd1e4d3..d940d95 100644 --- a/packages/core/src/settings/__tests__/settings.spec.ts +++ b/packages/core/src/settings/__tests__/settings.spec.ts @@ -12,7 +12,7 @@ describe("SettingsService", () => { const custom: Settings = { schema_version: "1", theme: "light", - editor: { fontSize: 18, lineWrapping: false }, + editor: { fontSize: 18, lineWrapping: false, autoSaveInterval: 1000 }, }; await service.save(custom); @@ -29,12 +29,12 @@ describe("SettingsService", () => { const first: Settings = { schema_version: "1", theme: "dark", - editor: { fontSize: 14, lineWrapping: true }, + editor: { fontSize: 14, lineWrapping: true, autoSaveInterval: 1000 }, }; const second: Settings = { schema_version: "1", theme: "light", - editor: { fontSize: 16, lineWrapping: false }, + editor: { fontSize: 16, lineWrapping: false, autoSaveInterval: 1000 }, }; await service.save(first); @@ -56,7 +56,7 @@ describe("SettingsService", () => { const good: Settings = { schema_version: "1", theme: "light", - editor: { fontSize: 20, lineWrapping: true }, + editor: { fontSize: 20, lineWrapping: true, autoSaveInterval: 1000 }, }; await adapter.writeFile("/vault/.trachyte/settings.json.bak", JSON.stringify(good, null, 2)); await adapter.writeFile("/vault/.trachyte/settings.json", "{ not json !!"); @@ -128,7 +128,7 @@ describe("SettingsService", () => { const custom: Settings = { schema_version: "1", theme: "dark", - editor: { fontSize: 14, lineWrapping: true }, + editor: { fontSize: 14, lineWrapping: true, autoSaveInterval: 1000 }, }; await service.save(custom); @@ -153,7 +153,7 @@ describe("SettingsService", () => { const custom: Settings = { schema_version: "1", theme: "light", - editor: { fontSize: 12, lineWrapping: false }, + editor: { fontSize: 12, lineWrapping: false, autoSaveInterval: 1000 }, }; await service.save(custom); From a39b300914f5a3db568db01314e23af7eb946b59 Mon Sep 17 00:00:00 2001 From: Debankan Roy Date: Wed, 19 Aug 2026 20:46:24 +0530 Subject: [PATCH 04/11] feat: Updated settings to account for autosave, added auto save fields to doctor --- packages/core/src/doctor/__tests__/doctor.spec.ts | 4 ++-- packages/core/src/settings/settings.ts | 6 ++++++ 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/packages/core/src/doctor/__tests__/doctor.spec.ts b/packages/core/src/doctor/__tests__/doctor.spec.ts index 16190dc..2c9a0e6 100644 --- a/packages/core/src/doctor/__tests__/doctor.spec.ts +++ b/packages/core/src/doctor/__tests__/doctor.spec.ts @@ -31,7 +31,7 @@ describe("settingsValidity", () => { const raw = JSON.stringify({ schema_version: "1", theme: "light", - editor: { fontSize: 14, lineWrapping: true }, + editor: { fontSize: 14, lineWrapping: true, autoSaveInterval: 1000 }, }); expect(settingsValidity(raw)).toEqual({ exists: true, valid: true, schemaVersion: "1" }); }); @@ -60,7 +60,7 @@ describe("buildDoctorReport", () => { JSON.stringify({ schema_version: "1", theme: "dark", - editor: { fontSize: 14, lineWrapping: true }, + editor: { fontSize: 14, lineWrapping: true, autoSaveInterval: 1000 }, }), ); expect(report.schemaVersion).toBeNull(); diff --git a/packages/core/src/settings/settings.ts b/packages/core/src/settings/settings.ts index 26cbd59..6c16761 100644 --- a/packages/core/src/settings/settings.ts +++ b/packages/core/src/settings/settings.ts @@ -73,6 +73,12 @@ function normalizeSettings(value: unknown): Settings | null { if (record.schema_version === undefined) { record.schema_version = DEFAULT_SETTINGS.schema_version; } + const editor = record.editor as Record | undefined; + if (editor) { + if (editor.autoSaveInterval === undefined) { + editor.autoSaveInterval = DEFAULT_SETTINGS.editor.autoSaveInterval; + } + } if (!isSettings(record)) return null; if (record.schema_version !== DEFAULT_SETTINGS.schema_version) return null; return record; From ca9d02c1453e2fec138e50269ee8ff5bdc234281 Mon Sep 17 00:00:00 2001 From: Debankan Roy Date: Wed, 19 Aug 2026 21:26:22 +0530 Subject: [PATCH 05/11] feat: Updated Home, Backlinks panel to fix the render of the backlinks pane --- apps/desktop/src/features/editor/BacklinksPane.tsx | 2 +- apps/desktop/src/routes/Home.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/desktop/src/features/editor/BacklinksPane.tsx b/apps/desktop/src/features/editor/BacklinksPane.tsx index a2c5122..2b80e2f 100644 --- a/apps/desktop/src/features/editor/BacklinksPane.tsx +++ b/apps/desktop/src/features/editor/BacklinksPane.tsx @@ -35,7 +35,7 @@ export default function BacklinksPane({ vaultPath, targetRelPath, onOpenNote }: return ( -
+
{currentRel === null ? (
Open a note to start editing From 3b167d104d0e08ceff38472c8a59f260b4dba008 Mon Sep 17 00:00:00 2001 From: Debankan Roy Date: Wed, 19 Aug 2026 21:42:08 +0530 Subject: [PATCH 06/11] feat: Updated doctor, settings for doctor validation --- packages/core/src/doctor/doctor.ts | 9 ++++++--- packages/core/src/settings/settings.ts | 2 ++ 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/packages/core/src/doctor/doctor.ts b/packages/core/src/doctor/doctor.ts index c5abff0..7c29d35 100644 --- a/packages/core/src/doctor/doctor.ts +++ b/packages/core/src/doctor/doctor.ts @@ -1,4 +1,5 @@ -import { DEFAULT_SETTINGS, isSettings } from "../settings/schema.js"; +import { DEFAULT_SETTINGS } from "../settings/schema.js"; +import { normalizeSettings } from "../settings/settings.js"; import type { DoctorSettingsValidity, DoctorReport, DoctorVaultReport } from "./types.js"; export function settingsValidity(raw: string | null): DoctorSettingsValidity { @@ -11,10 +12,12 @@ export function settingsValidity(raw: string | null): DoctorSettingsValidity { } catch { return { exists: true, valid: false }; } - if (!isSettings(parsed) || parsed.schema_version !== DEFAULT_SETTINGS.schema_version) { + // Normalize first - adds missing editor.autoSaveInterval from defaults + const normalized = normalizeSettings(parsed); + if (!normalized || normalized.schema_version !== DEFAULT_SETTINGS.schema_version) { return { exists: true, valid: false }; } - return { exists: true, valid: true, schemaVersion: parsed.schema_version }; + return { exists: true, valid: true, schemaVersion: normalized.schema_version }; } export function buildDoctorReport( diff --git a/packages/core/src/settings/settings.ts b/packages/core/src/settings/settings.ts index 6c16761..70eb96a 100644 --- a/packages/core/src/settings/settings.ts +++ b/packages/core/src/settings/settings.ts @@ -83,3 +83,5 @@ function normalizeSettings(value: unknown): Settings | null { if (record.schema_version !== DEFAULT_SETTINGS.schema_version) return null; return record; } + +export { normalizeSettings }; From 181029e8649895dd46456654c9d5016d07c30ec7 Mon Sep 17 00:00:00 2001 From: Debankan Roy Date: Wed, 19 Aug 2026 22:46:38 +0530 Subject: [PATCH 07/11] feat: Updated list() method to normalize paths inside the vaults --- packages/core/src/vault/manager.ts | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/packages/core/src/vault/manager.ts b/packages/core/src/vault/manager.ts index 19f5f55..b37b5a8 100644 --- a/packages/core/src/vault/manager.ts +++ b/packages/core/src/vault/manager.ts @@ -84,7 +84,12 @@ export class VaultManager { if (this.currentVault === null) { throw new VaultError("No vault open"); } - const entries = await this.adapter.listFiles(joinPath(this.currentVault, "Notes")); - return entries.filter((e) => e.endsWith(".md")).sort(); + const notesDir = joinPath(this.currentVault, "Notes"); + const entries = await this.adapter.listFiles(notesDir); + const mdFiles = entries.filter((e) => e.endsWith(".md")).sort(); + return mdFiles.map((fullPath) => { + const relative = fullPath.replace(notesDir + "/", ""); + return `Notes/${relative}`; + }); } } From 27df376bcae65ae16e2877787db0f4beee4d58ca Mon Sep 17 00:00:00 2001 From: Debankan Roy Date: Wed, 19 Aug 2026 22:53:44 +0530 Subject: [PATCH 08/11] feat: Updated onclick methods for sidebar to use normalized paths --- apps/desktop/src/routes/Home.tsx | 45 +++++++++++++++++++++++--------- 1 file changed, 33 insertions(+), 12 deletions(-) diff --git a/apps/desktop/src/routes/Home.tsx b/apps/desktop/src/routes/Home.tsx index 52a1063..107e56e 100644 --- a/apps/desktop/src/routes/Home.tsx +++ b/apps/desktop/src/routes/Home.tsx @@ -50,6 +50,7 @@ export default function Home() { await manager.create(path); setOpenedVault(path); const list = await manager.list(); + console.log("[DEBUG] manager.list() returned:", list); if (list.length === 0) { await manager .getAdapter() @@ -73,22 +74,34 @@ export default function Home() { } async function openNote(rel: string, blockId?: string) { - if (openedVault === null) return; + console.log("[DEBUG] openNote entry", { rel, openedVault, currentRel, blockId }); + if (openedVault === null) { + console.log("[DEBUG] openedVault is null"); + return; + } setCurrentRel(rel); - const text = await manager.getAdapter().readFile(joinPath(openedVault, rel)); - setContent(text); - lastSavedContentRef.current = text; - reloader.watch(rel); + const fullPath = joinPath(openedVault, rel); + console.log("[DEBUG] reading file at", fullPath); + try { + const text = await manager.getAdapter().readFile(fullPath); + console.log("[DEBUG] readFile success, length:", text.length); + setContent(text); + lastSavedContentRef.current = text; + reloader.watch(rel); - if (blockId) { - const pos = findBlockPosition(text, blockId); - if (pos !== null) { - setScrollToPos({ from: pos, to: pos }); + if (blockId) { + const pos = findBlockPosition(text, blockId); + if (pos !== null) { + setScrollToPos({ from: pos, to: pos }); + } else { + setScrollToPos(null); + } } else { setScrollToPos(null); } - } else { - setScrollToPos(null); + } catch (e) { + console.error("[DEBUG] readFile error:", e); + throw e; } } @@ -232,7 +245,15 @@ export default function Home() { className={`w-full rounded px-2 py-1 text-left text-sm hover:bg-gray-800 ${ currentRel === `Notes/${name}` ? "bg-gray-800 text-blue-300" : "text-gray-200" }`} - onClick={() => void openNote(`Notes/${name}`)} + onClick={() => { + console.log("[DEBUG] sidebar click", { + name, + path: `Notes/${name}`, + openedVault, + currentRel, + }); + void openNote(name); + }} > {name} From f17ff119c732e007a87ad38a4e2bd1ae628ad11d Mon Sep 17 00:00:00 2001 From: Debankan Roy Date: Wed, 19 Aug 2026 22:58:09 +0530 Subject: [PATCH 09/11] Removed the console logs --- apps/desktop/src/routes/Home.tsx | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/apps/desktop/src/routes/Home.tsx b/apps/desktop/src/routes/Home.tsx index 107e56e..778e813 100644 --- a/apps/desktop/src/routes/Home.tsx +++ b/apps/desktop/src/routes/Home.tsx @@ -50,7 +50,6 @@ export default function Home() { await manager.create(path); setOpenedVault(path); const list = await manager.list(); - console.log("[DEBUG] manager.list() returned:", list); if (list.length === 0) { await manager .getAdapter() @@ -74,17 +73,13 @@ export default function Home() { } async function openNote(rel: string, blockId?: string) { - console.log("[DEBUG] openNote entry", { rel, openedVault, currentRel, blockId }); if (openedVault === null) { - console.log("[DEBUG] openedVault is null"); return; } setCurrentRel(rel); const fullPath = joinPath(openedVault, rel); - console.log("[DEBUG] reading file at", fullPath); try { const text = await manager.getAdapter().readFile(fullPath); - console.log("[DEBUG] readFile success, length:", text.length); setContent(text); lastSavedContentRef.current = text; reloader.watch(rel); @@ -246,12 +241,6 @@ export default function Home() { currentRel === `Notes/${name}` ? "bg-gray-800 text-blue-300" : "text-gray-200" }`} onClick={() => { - console.log("[DEBUG] sidebar click", { - name, - path: `Notes/${name}`, - openedVault, - currentRel, - }); void openNote(name); }} > From a299771a2ce9c559c3d97ecbdde2093d45f76aea Mon Sep 17 00:00:00 2001 From: Debankan Roy Date: Wed, 19 Aug 2026 23:05:56 +0530 Subject: [PATCH 10/11] Updated manager tests to match new paths --- packages/core/src/vault/__tests__/manager.spec.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/core/src/vault/__tests__/manager.spec.ts b/packages/core/src/vault/__tests__/manager.spec.ts index d4a3191..53d83a0 100644 --- a/packages/core/src/vault/__tests__/manager.spec.ts +++ b/packages/core/src/vault/__tests__/manager.spec.ts @@ -65,7 +65,7 @@ describe("VaultManager", () => { await adapter.writeFile("/vault/Notes/a.md", "a"); await adapter.writeFile("/vault/Notes/readme.txt", "txt"); - expect(await manager.list()).toEqual(["/vault/Notes/a.md", "/vault/Notes/b.md"]); + expect(await manager.list()).toEqual(["Notes/a.md", "Notes/b.md"]); }); it("list() throws VaultError when no vault is open", async () => { @@ -99,6 +99,6 @@ describe("VaultManager", () => { await manager.create("/vault"); await store.writeFile("/vault/Notes/welcome.md", "# Hello"); - expect(await manager.list()).toEqual(["/vault/Notes/welcome.md"]); + expect(await manager.list()).toEqual(["Notes/welcome.md"]); }); }); From 18c7d9b5e0e3e46d179206b699e5eefab37d1bf3 Mon Sep 17 00:00:00 2001 From: Debankan Roy Date: Thu, 20 Aug 2026 15:55:31 +0530 Subject: [PATCH 11/11] Fix: Updated update ref so the cusor doesn't jump to 0 after each save --- packages/editor/src/CodeMirrorEditor.tsx | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/packages/editor/src/CodeMirrorEditor.tsx b/packages/editor/src/CodeMirrorEditor.tsx index e5e1981..51677a1 100644 --- a/packages/editor/src/CodeMirrorEditor.tsx +++ b/packages/editor/src/CodeMirrorEditor.tsx @@ -20,6 +20,7 @@ export function CodeMirrorEditor({ value, onChange, links, onOpenLink, scrollToP const onChangeRef = useRef(onChange); const linksRef = useRef(links ?? new Map()); const onOpenLinkRef = useRef(onOpenLink); + const isInternalChangeRef = useRef(false); useEffect(() => { onChangeRef.current = onChange; @@ -49,7 +50,12 @@ export function CodeMirrorEditor({ value, onChange, links, onOpenLink, scrollToP blockRefs(), EditorView.updateListener.of((update: ViewUpdate) => { if (update.docChanged) { + isInternalChangeRef.current = true; onChangeRef.current?.(update.state.doc.toString()); + + setTimeout(() => { + isInternalChangeRef.current = false; + }, 0); } }), ], @@ -68,17 +74,20 @@ export function CodeMirrorEditor({ value, onChange, links, onOpenLink, scrollToP useEffect(() => { const view = viewRef.current; - if (view && value !== view.state.doc.toString()) { + + if (!view) return; + if (isInternalChangeRef.current) return; + + if (value !== view.state.doc.toString()) { view.dispatch({ changes: { from: 0, to: view.state.doc.length, insert: value } }); } - // NEW: handle scrollTo after content is set - if (view && scrollToPosRef.current) { + if (scrollToPosRef.current) { view.dispatch({ selection: { anchor: scrollToPosRef.current.from, head: scrollToPosRef.current.to }, scrollIntoView: true, }); } - }, [value]); + }, [value, scrollToPos]); return
; }