From 1215bf33c3b8158d1c6ab87f86234cc648866042 Mon Sep 17 00:00:00 2001 From: Jonathan Hefner Date: Tue, 27 Jan 2026 12:56:28 -0600 Subject: [PATCH] Fix extractRegion() matching region names that are substrings of others MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The `extractRegion()` function in `sync-snippets.ts` used `indexOf()` to find region markers like `//#region persistData`. This caused incorrect matching when one region name was a prefix of another—searching for `persistData` would match `//#region persistDataServer` first if it appeared earlier in the file. The fix detects the file's line ending style and appends it to region markers, ensuring exact matches: - `//#region persistData\n` no longer matches `//#region persistDataServer\n` This corrects `docs/patterns.md` where the `persistData` code fence was incorrectly showing server-side code instead of client-side localStorage helpers. Co-Authored-By: Claude Opus 4.5 --- docs/patterns.md | 46 ++++++++++++++++++++++++++++++++++------ scripts/sync-snippets.ts | 5 +++-- 2 files changed, 42 insertions(+), 9 deletions(-) diff --git a/docs/patterns.md b/docs/patterns.md index 43d7519..f55d807 100644 --- a/docs/patterns.md +++ b/docs/patterns.md @@ -345,14 +345,46 @@ return { ```tsx source="./patterns.tsx#persistData" -// In your tool callback, include viewUUID in the result metadata. -return { - content: [{ type: "text", text: `Displaying PDF viewer for "${title}"` }], - structuredContent: { url, title, pageCount, initialPage: 1 }, - _meta: { - viewUUID: randomUUID(), - }, +// Store the viewUUID received from the server +let viewUUID: string | undefined; + +// Helper to save state to localStorage +function saveState(state: T): void { + if (!viewUUID) return; + try { + localStorage.setItem(viewUUID, JSON.stringify(state)); + } catch (err) { + console.error("Failed to save view state:", err); + } +} + +// Helper to load state from localStorage +function loadState(): T | null { + if (!viewUUID) return null; + try { + const saved = localStorage.getItem(viewUUID); + return saved ? (JSON.parse(saved) as T) : null; + } catch (err) { + console.error("Failed to load view state:", err); + return null; + } +} + +// Receive viewUUID from the tool result +app.ontoolresult = (result) => { + viewUUID = result._meta?.viewUUID + ? String(result._meta.viewUUID) + : undefined; + + // Restore any previously saved state + const savedState = loadState<{ currentPage: number }>(); + if (savedState) { + // Apply restored state to your UI... + } }; + +// Call saveState() whenever your view state changes +// e.g., saveState({ currentPage: 5 }); ``` _See [`examples/map-server/`](https://github.com/modelcontextprotocol/ext-apps/tree/main/examples/map-server) for a full implementation of this pattern._ diff --git a/scripts/sync-snippets.ts b/scripts/sync-snippets.ts index 4e9cfa8..ee81d79 100644 --- a/scripts/sync-snippets.ts +++ b/scripts/sync-snippets.ts @@ -254,8 +254,9 @@ function extractRegion( ); } - const regionStart = `//#region ${regionName}`; - const regionEnd = `//#endregion ${regionName}`; + const lineEnding = exampleContent.includes("\r\n") ? "\r\n" : "\n"; + const regionStart = `//#region ${regionName}${lineEnding}`; + const regionEnd = `//#endregion ${regionName}${lineEnding}`; const startIndex = exampleContent.indexOf(regionStart); if (startIndex === -1) {