1- import React , { useRef } from "react" ;
2- import { render } from "@commontools/html" ;
1+ import React , { useMemo , useRef } from "react" ;
2+ import { render , type VNode } from "@commontools/html" ;
33import { UI } from "@commontools/builder" ;
44import { charmSchema , fixItCharm } from "@commontools/charm" ;
55import { useCharmManager } from "@/contexts/CharmManagerContext.tsx" ;
66import { useNavigate } from "react-router-dom" ;
77import { LuX } from "react-icons/lu" ;
88import { DitheredCube } from "@/components/DitherCube.tsx" ;
99import { createPath } from "@/routes.ts" ;
10- import { charmId } from "@/utils/charms.ts" ;
10+ import { Cell , Charm , charmId } from "@/utils/charms.ts" ;
11+
1112interface CharmLoaderProps {
1213 charmImport : ( ) => Promise < any > ;
1314 argument ?: any ;
@@ -16,7 +17,7 @@ interface CharmLoaderProps {
1617}
1718
1819interface CharmRendererProps {
19- charm : any ;
20+ charm : Cell < Charm > ;
2021 argument ?: any ;
2122 className ?: string ;
2223}
@@ -81,18 +82,19 @@ function RawCharmRenderer({ charm, className = "" }: CharmRendererProps) {
8182 const [ runtimeError , setRuntimeError ] = React . useState < Error | null > ( null ) ;
8283 const [ isFixing , setIsFixing ] = React . useState ( false ) ;
8384 const { charmManager, currentReplica } = useCharmManager ( ) ;
85+ const id = useMemo ( ( ) => charmId ( charm ) , [ charm ] ) ;
8486 const navigate = useNavigate ( ) ;
8587
8688 // Store a reference to the current charm to detect changes
87- const prevCharmRef = useRef ( charm ) ;
89+ const prevCharmRef = useRef < Charm | null > ( null ) ;
8890
8991 // Clear error when charm changes
9092 React . useEffect ( ( ) => {
9193 if ( prevCharmRef . current !== charm ) {
9294 setRuntimeError ( null ) ;
9395 prevCharmRef . current = charm ;
9496 }
95- } , [ charm ] ) ;
97+ } , [ id ] ) ;
9698
9799 const handleFixIt = React . useCallback ( async ( ) => {
98100 if ( ! runtimeError || isFixing ) return ;
@@ -111,7 +113,7 @@ function RawCharmRenderer({ charm, className = "" }: CharmRendererProps) {
111113 } finally {
112114 setIsFixing ( false ) ;
113115 }
114- } , [ runtimeError , isFixing , charmManager , charm , currentReplica , navigate ] ) ;
116+ } , [ runtimeError , isFixing , charmManager , id , currentReplica , navigate ] ) ;
115117
116118 React . useEffect ( ( ) => {
117119 const container = containerRef . current ;
@@ -127,7 +129,10 @@ function RawCharmRenderer({ charm, className = "" }: CharmRendererProps) {
127129
128130 container . addEventListener ( "common-iframe-error" , handleIframeError ) ;
129131
130- const cleanup = render ( container , charm . asSchema ( charmSchema ) . key ( UI ) ) ;
132+ const cleanup = render (
133+ container ,
134+ charm . asSchema ( charmSchema ) . key ( UI ) as Cell < VNode > ,
135+ ) ;
131136
132137 return ( ) => {
133138 cleanup ( ) ;
@@ -136,7 +141,7 @@ function RawCharmRenderer({ charm, className = "" }: CharmRendererProps) {
136141 container . innerHTML = "" ;
137142 }
138143 } ;
139- } , [ charm ] ) ;
144+ } , [ id ] ) ;
140145
141146 return (
142147 < >
0 commit comments