fix(calendar-lab): use local tldraw runtime to avoid react/cdn instance mismatch

This commit is contained in:
Ruslan Bakiev
2026-02-23 19:47:57 +07:00
parent c5d3a90413
commit 6cce211c0b
3 changed files with 3366 additions and 1281 deletions

View File

@@ -1,5 +1,9 @@
<script setup lang="ts"> <script setup lang="ts">
import { computed, onBeforeUnmount, onMounted, ref } from "vue"; import { computed, onBeforeUnmount, onMounted, ref } from "vue";
import { createElement } from "react";
import { createRoot } from "react-dom/client";
import { Tldraw, createShapeId, toRichText } from "tldraw";
import "tldraw/tldraw.css";
type TldrawApi = { type TldrawApi = {
Tldraw: unknown; Tldraw: unknown;
@@ -34,15 +38,6 @@ const debugInfo = computed(() => `${LEVEL_LABELS[activeLevel.value] ?? "year"}:
let reactRoot: { unmount: () => void } | null = null; let reactRoot: { unmount: () => void } | null = null;
let teardown: (() => void) | null = null; let teardown: (() => void) | null = null;
function ensureTldrawCss() {
if (document.querySelector("link[data-tldraw-css='1']")) return;
const link = document.createElement("link");
link.rel = "stylesheet";
link.href = "https://esm.sh/tldraw@4.4.0/tldraw.css";
link.setAttribute("data-tldraw-css", "1");
document.head.append(link);
}
function buildScene(api: TldrawApi) { function buildScene(api: TldrawApi) {
const nodes = new Map<string, ShapeNode>(); const nodes = new Map<string, ShapeNode>();
const children = new Map<string, string[]>(); const children = new Map<string, string[]>();
@@ -271,17 +266,11 @@ onMounted(async () => {
try { try {
if (!hostRef.value) return; if (!hostRef.value) return;
ensureTldrawCss(); const api = {
Tldraw,
const [react, reactDomClient, tldraw] = await Promise.all([ createShapeId,
import(/* @vite-ignore */ "https://esm.sh/react@18.3.1"), toRichText,
import(/* @vite-ignore */ "https://esm.sh/react-dom@18.3.1/client"), } satisfies TldrawApi;
import(/* @vite-ignore */ "https://esm.sh/tldraw@4.4.0?bundle"),
]);
const createElement = (react as any).createElement as (...args: unknown[]) => unknown;
const createRoot = (reactDomClient as any).createRoot as (el: Element) => { render: (node: unknown) => void; unmount: () => void };
const api = tldraw as unknown as TldrawApi;
reactRoot = createRoot(hostRef.value); reactRoot = createRoot(hostRef.value);
reactRoot.render( reactRoot.render(
@@ -294,7 +283,7 @@ onMounted(async () => {
}), }),
); );
} catch (error) { } catch (error) {
status.value = "Failed to load tldraw engine from CDN"; status.value = "Failed to initialize local tldraw engine";
console.error(error); console.error(error);
} }
}); });

File diff suppressed because it is too large Load Diff

View File

@@ -46,7 +46,10 @@
"langfuse": "^3.38.6", "langfuse": "^3.38.6",
"langsmith": "^0.5.4", "langsmith": "^0.5.4",
"nuxt": "^4.3.1", "nuxt": "^4.3.1",
"react": "^19.2.4",
"react-dom": "^19.2.4",
"tailwindcss": "^4.1.18", "tailwindcss": "^4.1.18",
"tldraw": "^4.4.0",
"vue": "^3.5.27", "vue": "^3.5.27",
"wavesurfer.js": "^7.12.1", "wavesurfer.js": "^7.12.1",
"y-prosemirror": "^1.3.7", "y-prosemirror": "^1.3.7",
@@ -66,6 +69,7 @@
"@storybook/vue3-vite": "^8.6.17", "@storybook/vue3-vite": "^8.6.17",
"prisma": "^6.16.1", "prisma": "^6.16.1",
"storybook": "^8.6.17", "storybook": "^8.6.17",
"tsx": "^4.20.5" "tsx": "^4.20.5",
"vite": "^7.3.1"
} }
} }