From dbbc7b3f4821d746413de4637fbea7193d966715 Mon Sep 17 00:00:00 2001 From: zsviczian Date: Sun, 9 Aug 2026 22:25:25 +0200 Subject: [PATCH] 0.18.120, moved to React 19, fixed mermaid text to diagram history popout menu --- RefactorPlan.md | 5 ++ package-lock.json | 103 ++++++++++++++------------------- package.json | 10 ++-- scripts/reactRuntimeEntry.mjs | 4 +- src/shared/Dialogs/Messages.ts | 2 + 5 files changed, 59 insertions(+), 65 deletions(-) diff --git a/RefactorPlan.md b/RefactorPlan.md index 2ca5e1d7..51974152 100644 --- a/RefactorPlan.md +++ b/RefactorPlan.md @@ -37,6 +37,8 @@ validated, and what remains uncertain. | Compress per-window React payload | Complete | React, ReactDOM, and the official JSX runtimes are inflated before React participates in plugin bootstrap; the decompressed source remains available for private popout-window package creation, and manual testing found no startup or runtime regression | | Replace bundled OpenType metric reader | Complete | A bounds-checked SFNT reader now extracts only the TTF/OTF metrics consumed by Excalidraw; WOFF/WOFF2 fallback behavior is unchanged, `opentype.js` is no longer bundled, and manual testing found no font regression | | Migrate the Excalidraw runtime bundle | Implemented; production and development startup, color picker, runtime Mermaid loading, private npm-entrypoint React, and debugger payload validated | Added an isolated upstream-fork `build:obsidian` that bundles the ESM source graph into one function-evaluable artifact, preserves runtime Mermaid loading, removes the fork's retired UMD/webpack packaging path, and embeds the upstream Assistant UI fonts for offline use. The per-window React runtime is generated from official npm package entrypoints and kept in the plugin's lexical package scope rather than assigned to `window` | +| Upgrade the private React runtime to React 19 | Implemented; awaiting manual validation | Updated the paired React and ReactDOM runtime to stable 19.2.8 with matching React 19 types while retaining private per-window package creation and the official JSX runtime entrypoints | +| Repair text-to-diagram history menu | Implemented; awaiting manual validation | Persistence is working and saved chats are loaded; the body-portaled history dropdown now retains its TTD styling and stacks above the text-to-diagram modal | | Audit and consolidate duplicate logic | In progress | Consolidated `updateFrontmatterInString()`, `arrayToMap()`, `wrapTextAtCharLength()`, `getLinkParts()`/`LinkParts`, `getBinaryFileFromDataURL()`, `svgToBase64()`, `getFontDataURL()`, `cropCanvas()`, `getImageSize()`, `promiseTry()`, `isVersionNewerThanOther()`, `repositionElementsToCursor()`, the internal `cloneElement()`, and `getBoundTextElementId()`; continue one independently testable helper family at a time | | Remaining view phases | In progress | Manually validate the extension renderer checkpoint before choosing between the higher-risk scene-file loader and a mechanical package-aware React-root extraction | @@ -97,6 +99,9 @@ validated, and what remains uncertain. | 2026-08-09 | Restored debugger-grade development payloads | Development Excalidraw and React artifacts are no longer passed through the production-oriented Uglify step. The Excalidraw development build now carries an inline source map with original TS/TSX sources and a stable `sourceURL`, while production remains minified and map-free | The decompressed development payload is readable, contains original Excalidraw sources and an inline source map, and does not publish React or ReactDOM on `window`; the intentional `window.ExcalidrawLib` compatibility API remains. The larger development output is intentional and is not released; manual validation should confirm `obsidian-excalidraw-runtime.development.js` and original Excalidraw sources appear in DevTools | | 2026-08-09 | Removed the redundant development CSS source map | The Excalidraw Obsidian build now strips only the generated development CSS inline map after compilation. Readable CSS and the JavaScript TS/TSX source map remain intact, while the plugin's cssnano pass no longer nests the original CSS map inside a second combined map | `yarn build:obsidian`, plugin production, and plugin development builds passed. Upstream development CSS decreased from 992,360 to 341,778 bytes. Combined development `styles.css` decreased from 2,123,032 to 331,366 bytes and contains no `sourceMappingURL`; development JavaScript retains its inline map, stable debugger source name, and readable original source modules | | 2026-08-09 | Fixed the private React main-window bootstrap | Runtime testing exposed an asymmetry missed by the raw package test: the Rollup bundle still referenced its external `React` binding before the private runtime had created that lexical name, and the main-window Excalidraw evaluation could not see lexical React through a separate `window.eval`. The bootstrap now declares React, ReactDOM, and both JSX runtimes in plugin scope, and the main-window Excalidraw factory receives those exact instances as explicit parameters. Popout package creation remains independent per window, and React is still not assigned to `window` | Production and development builds pass. An emitted-bootstrap JSDOM test executes through the formerly failing React namespace initialization, loads React 18.3.1 and all 106 Excalidraw exports, confirms the package aliases use the same instances, preserves the public `window.ExcalidrawLib`, and confirms `window.React` and `window.ReactDOM` remain unset. Cold startup in Obsidian is the required manual checkpoint | +| 2026-08-09 | Upgraded the plugin-private runtime to React 19.2.8 | Updated the exact paired `react` and `react-dom` dependencies and matching React 19 declaration packages. Preserved the official-package runtime builder, lexical main-window bootstrap, independent popout evaluation, client renderer, and JSX runtime surfaces; no React global was introduced | Dependency resolution deduplicates Excalidraw, Jotai, Radix, and the plugin onto React 19.2.8. Production, development, and library builds passed; an isolated runtime evaluation reported React 19.2.8 with callable `createRoot`, `jsx`, and `jsxDEV`. Manual validation should prioritize cold startup and Excalidraw editing in the main window, then new/restored popouts and moving a leaf between windows; React runtime mismatch is the highest-impact risk | +| 2026-08-09 | Corrected the text-to-diagram persistence diagnosis | Manual inspection confirmed chats are present in the existing main-window IndexedDB store, and the history button proves `savedChats` was loaded. Reverted the view-window persistence-adapter experiment and retained the original main-window adapter | Investigate menu rendering instead: the shared dropdown is body-portaled by `ObsidianRadixPortal`, so the history content can sit behind the modal and lose styles that depended on a TTD ancestor. Validate menu visibility, restore, delete, and popout behavior after the component fix | +| 2026-08-09 | Restored the text-to-diagram history menu above its modal | `DropdownMenu.Content` already uses `ObsidianRadixPortal`; the regression was that its body-level portal escaped both the modal stacking context and the TTD header ancestor used by its styles. Added a TTD-specific class that survives the portal and moved the existing menu rules to that selector with a z-index immediately above the Excalidraw modal | `yarn build:obsidian` passed and emitted the class in JavaScript plus the portal-safe selector in both CSS builds. The plugin production build using the local component artifacts passed with the existing 33 circular dependencies. Validate opening, restoring, and deleting history in the main window first, then repeat in a popout and on mobile; stacking and click-outside behavior are the highest-risk areas | ## Executive recommendation diff --git a/package-lock.json b/package-lock.json index c449260f..1d181ea4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,7 +13,7 @@ "@popperjs/core": "^2.11.8", "@radix-ui/number": "^1.1.2", "@zsviczian/colormaster": "^1.2.2", - "@zsviczian/excalidraw": "0.18.119", + "@zsviczian/excalidraw": "0.18.120", "chroma-js": "^3.1.2", "clsx": "^2.0.0", "es6-promise-pool": "2.5.0", @@ -24,8 +24,8 @@ "pako": "^2.1.0", "points-on-path": "^0.2.1", "polybooljs": "^1.2.0", - "react": "^18.2.0", - "react-dom": "^18.2.0", + "react": "19.2.8", + "react-dom": "19.2.8", "roughjs": "^4.5.2" }, "devDependencies": { @@ -50,8 +50,8 @@ "@types/chroma-js": "^3.1.1", "@types/js-beautify": "^1.14.0", "@types/node": "^22.19.19", - "@types/react": "^18.2.45", - "@types/react-dom": "^18.2.18", + "@types/react": "19.2.18", + "@types/react-dom": "19.2.4", "@zsviczian/excalidraw-extras-api": "^0.0.13", "@zsviczian/rollup-plugin-postprocess": "^1.0.3", "cross-env": "^7.0.3", @@ -2084,31 +2084,31 @@ } }, "node_modules/@floating-ui/core": { - "version": "1.7.5", - "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.7.5.tgz", - "integrity": "sha512-1Ih4WTWyw0+lKyFMcBHGbb5U5FtuHJuujoyyr5zTaWS5EYMeT6Jb2AuDeftsCsEuchO+mM2ij5+q9crhydzLhQ==", + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.8.0.tgz", + "integrity": "sha512-0CIZ5itps/8x7BG8dEIhs53BvCUH2PCoogtakwRTut+Arm58sJooJ0AuZhLw2HJYIR5cMLNPBSS728sPho2khQ==", "license": "MIT", "dependencies": { - "@floating-ui/utils": "^0.2.11" + "@floating-ui/utils": "^0.2.12" } }, "node_modules/@floating-ui/dom": { - "version": "1.7.6", - "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.7.6.tgz", - "integrity": "sha512-9gZSAI5XM36880PPMm//9dfiEngYoC6Am2izES1FF406YFsjvyBMmeJ2g4SAju3xWwtuynNRFL2s9hgxpLI5SQ==", + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.8.0.tgz", + "integrity": "sha512-yXSrzeHZBTZadLOlfyhCkJHNeLJnHRnRInwdZ40L7ZiaAtrBwoYlsDrX3v5zB1Utk7CLfzcOVnVVWoXEky7Ceg==", "license": "MIT", "dependencies": { - "@floating-ui/core": "^1.7.5", - "@floating-ui/utils": "^0.2.11" + "@floating-ui/core": "^1.8.0", + "@floating-ui/utils": "^0.2.12" } }, "node_modules/@floating-ui/react-dom": { - "version": "2.1.8", - "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.1.8.tgz", - "integrity": "sha512-cC52bHwM/n/CxS87FH0yWdngEZrjdtLW/qVruo68qg+prK7ZQ4YGdut2GyDVpoGeAYe/h899rVeOVm6Oi40k2A==", + "version": "2.1.9", + "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.1.9.tgz", + "integrity": "sha512-JDjEFGCpImxDCA7JJKviA0M9+RtmJdj0m/NVU5IMgBK+AmZouAQQ7/+2GLH0GXXY0YMw9oXPB8hKdbPYg5QLYg==", "license": "MIT", "dependencies": { - "@floating-ui/dom": "^1.7.6" + "@floating-ui/dom": "^1.8.0" }, "peerDependencies": { "react": ">=16.8.0", @@ -2116,9 +2116,9 @@ } }, "node_modules/@floating-ui/utils": { - "version": "0.2.11", - "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.11.tgz", - "integrity": "sha512-RiB/yIh78pcIxl6lLMG0CgBXAZ2Y0eVHqMPYugu+9U0AeT6YBeiJpf7lbdJNIugFP5SIjwNRgo4DhR1Qxi26Gg==", + "version": "0.2.12", + "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.12.tgz", + "integrity": "sha512-HpCo8tmWzLVad5s2d19EhAz5zqrrQ6s69qd6moPMQvkOuSwDT1YgRfWSVuc4ennqrgv3OHppiOGMQ7oC13yIww==", "license": "MIT" }, "node_modules/@humanfs/core": { @@ -4887,32 +4887,24 @@ "undici-types": "~6.21.0" } }, - "node_modules/@types/prop-types": { - "version": "15.7.15", - "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.15.tgz", - "integrity": "sha512-F6bEyamV9jKGAFBEmlQnesRPGOQqS2+Uwi0Em15xenOxHaf2hv6L8YCVn3rPdPJOiJfPiCnLIRyvwVaqMY3MIw==", - "devOptional": true, - "license": "MIT" - }, "node_modules/@types/react": { - "version": "18.3.31", - "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.31.tgz", - "integrity": "sha512-vfEqpXTvwT91yhmwdfouStN2hSKwTvyRs8qpLfADyrq/kxDw0hZM7Wk9Ug1FELj8hIby+S/+kQCSRFF32nv2Qw==", + "version": "19.2.18", + "resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.18.tgz", + "integrity": "sha512-AnzbBERsrLKtk2XSfTbYRLjQPdy116Sty4q+T+Bp3IC4l6jNBvreVPAHmpq9qhXQM7CXZPjLVmGMw9sy+hxQ3w==", "devOptional": true, "license": "MIT", "dependencies": { - "@types/prop-types": "*", "csstype": "^3.2.2" } }, "node_modules/@types/react-dom": { - "version": "18.3.7", - "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.3.7.tgz", - "integrity": "sha512-MEe3UeoENYVFXzoXEWsvcpg6ZvlrFNlOQ7EOsvhI3CfAXwzPfO8Qwuxd40nepsYKqyyVQnTdEfv68q91yLcKrQ==", + "version": "19.2.4", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.2.4.tgz", + "integrity": "sha512-Bsc+QHgp+P/F02XDzNCY9jnZNCUuLki36KT7VKrTXXLdHf+vHMNZnW1rVu5DNW/rCK+fya3DATySbLM4yhtKUw==", "devOptional": true, "license": "MIT", "peerDependencies": { - "@types/react": "^18.0.0" + "@types/react": "^19.2.0" } }, "node_modules/@types/resolve": { @@ -5263,9 +5255,9 @@ "license": "MIT" }, "node_modules/@zsviczian/excalidraw": { - "version": "0.18.119", - "resolved": "https://registry.npmjs.org/@zsviczian/excalidraw/-/excalidraw-0.18.119.tgz", - "integrity": "sha512-+ncOL4p1UYjAYz7owwBlvei6vq97tt+jI5Izd2+LVMxGllgm+5rMoR36QygeAz2RjckxyVNePjkqM980cRNrbg==", + "version": "0.18.120", + "resolved": "https://registry.npmjs.org/@zsviczian/excalidraw/-/excalidraw-0.18.120.tgz", + "integrity": "sha512-J0J3pYZZIRabdkWkZ7OH6VsJBE/dfZmNSJtL6X/lRIY/NEV52x3H3PMkx17z9Siu4D2C82qpNibFnltVkZJmow==", "license": "MIT", "dependencies": { "@braintree/sanitize-url": "6.0.2", @@ -9642,6 +9634,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true, "license": "MIT" }, "node_modules/js-yaml": { @@ -9978,6 +9971,7 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "dev": true, "license": "MIT", "dependencies": { "js-tokens": "^3.0.0 || ^4.0.0" @@ -11383,28 +11377,24 @@ } }, "node_modules/react": { - "version": "18.3.1", - "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz", - "integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==", + "version": "19.2.8", + "resolved": "https://registry.npmjs.org/react/-/react-19.2.8.tgz", + "integrity": "sha512-PWaYA1L/q9u2u7xYQi+Y3L3Yfnie7XyLeaJICV1MGD6LprsBxcAqGjYyr0eY3p+QdsA+x/Irkt4Qif8D63+Sbw==", "license": "MIT", - "dependencies": { - "loose-envify": "^1.1.0" - }, "engines": { "node": ">=0.10.0" } }, "node_modules/react-dom": { - "version": "18.3.1", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz", - "integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==", + "version": "19.2.8", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.8.tgz", + "integrity": "sha512-rVprimfGBG3DR+Tq0IQG2DT5PxKth1WIGDmj5yPmlzr4YBe7uyE+Du4oVqTDXZSHGGGXRtTJEGSSePyQCMBglQ==", "license": "MIT", "dependencies": { - "loose-envify": "^1.1.0", - "scheduler": "^0.23.2" + "scheduler": "^0.27.0" }, "peerDependencies": { - "react": "^18.3.1" + "react": "^19.2.8" } }, "node_modules/react-is": { @@ -11985,13 +11975,10 @@ } }, "node_modules/scheduler": { - "version": "0.23.2", - "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz", - "integrity": "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==", - "license": "MIT", - "dependencies": { - "loose-envify": "^1.1.0" - } + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.27.0.tgz", + "integrity": "sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==", + "license": "MIT" }, "node_modules/semver": { "version": "6.3.1", diff --git a/package.json b/package.json index d2d0ab03..e0169b2a 100644 --- a/package.json +++ b/package.json @@ -30,7 +30,7 @@ "@popperjs/core": "^2.11.8", "@radix-ui/number": "^1.1.2", "@zsviczian/colormaster": "^1.2.2", - "@zsviczian/excalidraw": "0.18.119", + "@zsviczian/excalidraw": "0.18.120", "chroma-js": "^3.1.2", "clsx": "^2.0.0", "es6-promise-pool": "2.5.0", @@ -41,8 +41,8 @@ "pako": "^2.1.0", "points-on-path": "^0.2.1", "polybooljs": "^1.2.0", - "react": "^18.2.0", - "react-dom": "^18.2.0", + "react": "19.2.8", + "react-dom": "19.2.8", "roughjs": "^4.5.2" }, "devDependencies": { @@ -67,8 +67,8 @@ "@types/chroma-js": "^3.1.1", "@types/js-beautify": "^1.14.0", "@types/node": "^22.19.19", - "@types/react": "^18.2.45", - "@types/react-dom": "^18.2.18", + "@types/react": "19.2.18", + "@types/react-dom": "19.2.4", "@zsviczian/excalidraw-extras-api": "^0.0.13", "@zsviczian/rollup-plugin-postprocess": "^1.0.3", "cross-env": "^7.0.3", diff --git a/scripts/reactRuntimeEntry.mjs b/scripts/reactRuntimeEntry.mjs index 8dc0ebfe..603ba4a6 100644 --- a/scripts/reactRuntimeEntry.mjs +++ b/scripts/reactRuntimeEntry.mjs @@ -14,8 +14,8 @@ import * as jsxRuntime from "react/jsx-runtime"; const ReactDOM = Object.assign({}, ReactDOMLegacy, ReactDOMClient); const ReactJSXRuntime = jsxRuntime; const ReactJSXDevRuntime = Object.assign({}, jsxDevRuntime, { - // React 18's production entry exposes `jsxDEV` as undefined. Keep the - // callable compatibility surface used by the former runtime shim. + // Keep a callable production fallback for bundles compiled against the + // development JSX runtime entrypoint. jsxDEV: jsxDevRuntime.jsxDEV || jsxRuntime.jsx, }); diff --git a/src/shared/Dialogs/Messages.ts b/src/shared/Dialogs/Messages.ts index 20b09c5a..17decc42 100644 --- a/src/shared/Dialogs/Messages.ts +++ b/src/shared/Dialogs/Messages.ts @@ -21,9 +21,11 @@ I build this plugin as a labor of love. Curious about the philosophy behind it? ## Maintenance - Refactoring the plugin. Removed unused functions, improved code structure and readability. Removed the obsolete Draw.io/Diagram plugin integration (since the other plugin no longer works and is not maintained) and retired the Create DrawIO file script from the script library. - Migrated the embedded Excalidraw runtime from the retired UMD build path to a dedicated ESM-source-based Obsidian package while preserving offline operation, popout windows, and runtime Mermaid loading through Excalidraw Extras. The Assistant UI font is now bundled instead of fetched from the internet, and the plugin-private React runtime is generated from the official npm package entrypoints instead of legacy UMD files. +- Updated the plugin-private React and ReactDOM runtime to React 19. ## Fixed - The Excalidraw color palette now uses its natural height when space is available instead of being unnecessarily limited to a short, vertically scrolling panel. Its native color control also remains aligned with the hex input. +- The text-to-diagram chat history menu is visible again, allowing saved chats to be restored and deleted. `, "2.26.4": `