From 022ecda6bf60f3ccb1719a0d1580bd897a52e7a2 Mon Sep 17 00:00:00 2001 From: Thomas Davis Date: Mon, 9 Feb 2026 19:17:21 +1000 Subject: [PATCH] fix: render Isoflow in iframe to avoid React 19 incompatibility Isoflow bundles React 18 internally and crashes with React 19's changed internals (ReactCurrentOwner). Solved by loading Isoflow in a standalone HTML page via esm.sh (React 18) and embedding it as an iframe. Also simplified the diagram to 16 key nodes for better readability. Co-Authored-By: Claude Opus 4.6 --- apps/web/package.json | 2 - apps/web/public/isoflow-embed.html | 147 ++++ apps/web/src/components/tech/TechDiagram.tsx | 88 +-- .../src/components/tech/techDiagramData.ts | 424 ----------- pnpm-lock.yaml | 673 +----------------- 5 files changed, 186 insertions(+), 1148 deletions(-) create mode 100644 apps/web/public/isoflow-embed.html delete mode 100644 apps/web/src/components/tech/techDiagramData.ts diff --git a/apps/web/package.json b/apps/web/package.json index a75337d..7fb84c6 100644 --- a/apps/web/package.json +++ b/apps/web/package.json @@ -26,7 +26,6 @@ "@ai-sdk/groq": "^3.0.4", "@ai-sdk/mistral": "^3.0.5", "@ai-sdk/openai": "3.0.7", - "@isoflow/isopacks": "^0.0.10", "@modelcontextprotocol/sdk": "^1.25.2", "@prisma/client": "^6.19.1", "@react-three/drei": "^10.7.7", @@ -51,7 +50,6 @@ "better-auth": "^1.4.10", "bm25": "^0.1.1", "d3": "^7.9.0", - "isoflow": "^1.1.1", "next": "^16.1.1", "next-themes": "^0.4.6", "openai": "^6.15.0", diff --git a/apps/web/public/isoflow-embed.html b/apps/web/public/isoflow-embed.html new file mode 100644 index 0000000..907c6e4 --- /dev/null +++ b/apps/web/public/isoflow-embed.html @@ -0,0 +1,147 @@ + + + + + +TPMJS Architecture + + + +
Loading diagram...
+ + + + diff --git a/apps/web/src/components/tech/TechDiagram.tsx b/apps/web/src/components/tech/TechDiagram.tsx index 6cc187e..c0fde99 100644 --- a/apps/web/src/components/tech/TechDiagram.tsx +++ b/apps/web/src/components/tech/TechDiagram.tsx @@ -1,63 +1,43 @@ 'use client'; +import { useState } from 'react'; import { Spinner } from '@tpmjs/ui/Spinner/Spinner'; -import dynamic from 'next/dynamic'; -import { Component, type ReactNode } from 'react'; -import { techDiagramData } from './techDiagramData'; -// Isoflow uses canvas/paper.js and must be loaded client-side only -const Isoflow = dynamic(() => import('isoflow'), { - ssr: false, - loading: () => ( -
- -
- ), -}); - -// ── Error Boundary ────────────────────────────────────────────────── -interface ErrorBoundaryState { - hasError: boolean; -} - -class DiagramErrorBoundary extends Component<{ children: ReactNode }, ErrorBoundaryState> { - constructor(props: { children: ReactNode }) { - super(props); - this.state = { hasError: false }; - } - - static getDerivedStateFromError(): ErrorBoundaryState { - return { hasError: true }; - } - - render() { - if (this.state.hasError) { - return ( -
-

The interactive diagram failed to load.

- - View the alternative architecture diagram → - -
- ); - } - return this.props.children; - } -} - -// ── Main Component ────────────────────────────────────────────────── export function TechDiagram() { + const [isLoading, setIsLoading] = useState(true); + const [hasError, setHasError] = useState(false); + + if (hasError) { + return ( +
+

+ The interactive diagram failed to load. +

+ + View the alternative architecture diagram → + +
+ ); + } + return ( -
- - - +
+ {isLoading && ( +
+ +
+ )} +