Skip to main content
The destroy event is fired when the playground instance is destroyed and all resources are cleaned up.

Event Payload

This event does not pass any data to the callback function.

When It Fires

  • When playground.destroy() method is called
  • When the playground is being removed from the DOM
  • Before the playground is completely cleaned up

Usage Example

import { createPlayground } from "livecodes";

createPlayground("#container").then((playground) => {
  // Listen for destroy event
  const destroyWatcher = playground.watch("destroy", () => {
    console.log("Playground is being destroyed");
    // Perform cleanup operations
  });

  // Later, destroy the playground
  playground.destroy();
  // The destroy event will fire before cleanup completes
});

Common Use Cases

Cleanup External Resources

let externalInterval;

playground.watch("destroy", () => {
  // Clean up timers
  if (externalInterval) {
    clearInterval(externalInterval);
    console.log("Cleaned up external interval");
  }
  
  // Close connections
  websocket?.close();
  
  // Remove event listeners
  document.removeEventListener("keydown", handleKeydown);
});

Save State Before Destruction

playground.watch("destroy", async () => {
  console.log("Saving state before destruction...");
  
  // Get current state
  const config = await playground.getConfig();
  const code = await playground.getCode();
  
  // Save to localStorage
  localStorage.setItem("playground-backup", JSON.stringify({ config, code }));
  
  console.log("State saved!");
});

Analytics and Tracking

const createdAt = Date.now();

playground.watch("destroy", () => {
  const sessionDuration = Date.now() - createdAt;
  
  // Track session duration
  analytics.track("playground_session_ended", {
    duration: sessionDuration,
    durationMinutes: Math.round(sessionDuration / 1000 / 60),
  });
  
  console.log(`Session lasted ${sessionDuration}ms`);
});

Notify Users

playground.watch("destroy", () => {
  showNotification({
    type: "info",
    message: "Playground session ended",
  });
});

Release Memory

let largeDataCache = {};
let observers = [];

playground.watch("destroy", () => {
  // Clear large data structures
  largeDataCache = null;
  
  // Disconnect observers
  observers.forEach(observer => observer.disconnect());
  observers = [];
  
  console.log("Memory released");
});

Coordinate Multiple Playgrounds

const playgroundRegistry = new Set();

function createTrackedPlayground(container, options) {
  return createPlayground(container, options).then((playground) => {
    playgroundRegistry.add(playground);
    
    playground.watch("destroy", () => {
      playgroundRegistry.delete(playground);
      console.log(`Active playgrounds: ${playgroundRegistry.size}`);
    });
    
    return playground;
  });
}

Prevent Accidental Destruction

let hasUnsavedChanges = false;

playground.watch("code", () => {
  hasUnsavedChanges = true;
});

playground.watch("destroy", () => {
  if (hasUnsavedChanges) {
    console.warn("Playground destroyed with unsaved changes!");
    // In a real app, you might want to prevent destruction
    // or prompt the user, but this would need to be done
    // before calling destroy()
  }
});

Log Destruction

const playgroundId = `playground-${Date.now()}`;

playground.watch("destroy", () => {
  console.log(`[${playgroundId}] Playground destroyed at ${new Date().toISOString()}`);
  
  // Send to logging service
  logToServer({
    event: "playground_destroyed",
    playgroundId: playgroundId,
    timestamp: Date.now(),
  });
});

Cleanup UI Elements

const statusBar = document.createElement("div");
statusBar.className = "playground-status";
document.body.appendChild(statusBar);

playground.watch("destroy", () => {
  // Remove related UI elements
  statusBar.remove();
  
  // Clear related state
  document.body.classList.remove("playground-active");
  
  console.log("UI cleaned up");
});

Important Notes

After the playground is destroyed, all SDK methods will throw an error. Make sure to perform any necessary operations before calling destroy().
playground.watch("destroy", () => {
  console.log("Destroying...");
});

await playground.destroy();

// ❌ This will throw an error
try {
  await playground.run();
} catch (error) {
  console.error(error); // "Cannot call API methods after calling `destroy()`."
}

Removing the Watcher

Typically, you don’t need to manually remove a destroy watcher since the playground is being destroyed anyway. However, if needed:
const watcher = playground.watch("destroy", () => {
  console.log("Destroying");
});

// Remove the watcher (if needed before destruction)
watcher.remove();

Build docs developers (and LLMs) love