/// import { Cell, computed, Default, handler, ifElse, lift, NAME, navigateTo, recipe, toSchema, UI, } from "commontools"; type Charm = { [NAME]: string; [UI]: string; [key: string]: any; }; // Define interfaces for type safety interface AddCharmState { charm: any; cellRef: Cell; isInitialized: Cell; } const AddCharmSchema = toSchema(); // Simple charm that will be instantiated multiple times const SimpleRecipe = recipe<{ id: string }>(({ id }) => ({ [NAME]: computed(() => `SimpleRecipe: ${id}`), [UI]:
Simple Recipe id {id}
, })); // Lift that adds a charm to the array and navigates to it. // The isInitialized flag prevents duplicate additions: // - Without it: lift runs → adds to array → array changes → lift runs again → duplicate // - With it: lift runs once → sets isInitialized → subsequent runs skip const addCharmAndNavigate = lift( AddCharmSchema, undefined, ({ charm, cellRef, isInitialized }) => { if (!isInitialized.get()) { if (cellRef) { cellRef.push(charm); isInitialized.set(true); return navigateTo(charm); } else { console.log("addCharmAndNavigate undefined cellRef"); } } return undefined; }, ); // Handler that creates a new charm instance and adds it to the array. // Each invocation creates its own isInitialized cell for tracking. const createSimpleRecipe = handler }>( (_, { cellRef }) => { // Create isInitialized cell for this charm addition const isInitialized = Cell.of(false); // Create a random 5-digit ID const randomId = Math.floor(10000 + Math.random() * 90000).toString(); // Create the charm with unique ID const charm = SimpleRecipe({ id: randomId }); // Store the charm in the array and navigate return addCharmAndNavigate({ charm, cellRef, isInitialized }); }, ); // Handler to navigate to a specific charm from the list const goToCharm = handler( (_, { charm }) => { console.log("goToCharm clicked"); return navigateTo(charm); }, ); // Recipe input/output type type RecipeInOutput = { cellRef: Default; }; // Main recipe that manages an array of charm references export default recipe( "Charms Launcher", ({ cellRef }) => { return { [NAME]: "Charms Launcher", [UI]: (

Stored Charms:

{ifElse( !cellRef?.length,
No charms created yet
,
    {cellRef.map((charm: any, index: number) => (
  • Go to Charm {computed(() => index + 1)} Charm {computed(() => index + 1)}:{" "} {charm[NAME] || "Unnamed"}
  • ))}
, )} Create New Charm
), cellRef, }; }, );