MCPcopy Index your code
hub / github.com/coder/mux / MemoryFileEditor

Function MemoryFileEditor

src/browser/features/Memory/MemoryFileEditor.tsx:26–153  ·  view source on GitHub ↗
(props: MemoryFileEditorProps)

Source from the content-addressed store, hash-verified

24 * silently overwrites the other writer's changes).
25 */
26export function MemoryFileEditor(props: MemoryFileEditorProps) {
27 const { api } = useAPI();
28 const [loaded, setLoaded] = useState<{ content: string; sha256: string } | null>(null);
29 const [draft, setDraft] = useState("");
30 const [loadError, setLoadError] = useState<string | null>(null);
31 const [saveError, setSaveError] = useState<MemorySaveError | null>(null);
32 const [saving, setSaving] = useState(false);
33 const [reloadTick, setReloadTick] = useState(0);
34 // Read the live DOM value at save time (same pattern as
35 // WorkspaceHeartbeatModal): controlled-textarea onChange does not fire in
36 // happy-dom, and the DOM is authoritative for what the user typed anyway.
37 const textareaRef = useRef<HTMLTextAreaElement | null>(null);
38
39 useEffect(() => {
40 if (!api) return;
41 const controller = new AbortController();
42 api.memory
43 .read({ workspaceId: props.workspaceId, path: props.path }, { signal: controller.signal })
44 .then((result) => {
45 if (controller.signal.aborted) return;
46 if (result.success) {
47 setLoaded(result.data);
48 setDraft(result.data.content);
49 setLoadError(null);
50 } else {
51 setLoadError(result.error);
52 }
53 })
54 .catch((err: unknown) => {
55 if (isAbortError(err) || controller.signal.aborted) return;
56 setLoadError(getErrorMessage(err));
57 });
58 return () => controller.abort();
59 }, [api, props.workspaceId, props.path, reloadTick]);
60
61 const handleSave = async () => {
62 if (!api || loaded === null || saving) return;
63 const content = textareaRef.current?.value ?? draft;
64 setSaving(true);
65 try {
66 const result = await api.memory.save({
67 workspaceId: props.workspaceId,
68 path: props.path,
69 content,
70 expectedSha256: loaded.sha256,
71 });
72 if (result.success) {
73 setLoaded({ content, sha256: result.data.sha256 });
74 setDraft(content);
75 setSaveError(null);
76 } else {
77 setSaveError(result.error);
78 }
79 } catch (err) {
80 setSaveError({ kind: "error", message: getErrorMessage(err) });
81 } finally {
82 setSaving(false);
83 }

Callers

nothing calls this directly

Calls 8

useAPIFunction · 0.90
isAbortErrorFunction · 0.90
getErrorMessageFunction · 0.90
cnFunction · 0.90
matchesKeybindFunction · 0.90
handleSaveFunction · 0.70
abortMethod · 0.65
readMethod · 0.45

Tested by

no test coverage detected