webui: fix Monaco editor initialization parentNode errors in diff view

Add proper Lit component lifecycle validation to ensure Monaco editor container
is connected to the document before initialization, preventing 'undefined parentNode'
errors during diff view loading.

The fix uses await this.updateComplete and validates both component and container
connection state, eliminating race conditions between component rendering and
Monaco API calls without using timeouts or retries.

Co-Authored-By: sketch <hello@sketch.dev>
Change-ID: s85d1738b85a64745k
diff --git a/webui/src/web-components/sketch-monaco-view.ts b/webui/src/web-components/sketch-monaco-view.ts
index 03b6744..4b46c0e 100644
--- a/webui/src/web-components/sketch-monaco-view.ts
+++ b/webui/src/web-components/sketch-monaco-view.ts
@@ -672,8 +672,15 @@
 
       // First time initialization
       if (!this.editor) {
+        // Ensure the container ref is available
+        if (!this.container.value) {
+          throw new Error(
+            "Container element not available - component may not be fully rendered",
+          );
+        }
+
         // Create the diff editor with auto-sizing configuration
-        this.editor = monaco.editor.createDiffEditor(this.container.value!, {
+        this.editor = monaco.editor.createDiffEditor(this.container.value, {
           automaticLayout: false, // We'll resize manually
           readOnly: true,
           theme: "vs", // Always use light mode
@@ -1171,7 +1178,8 @@
         }, 100);
       } else {
         // If the editor isn't initialized yet but we received content,
-        // initialize it now
+        // ensure we're connected before initializing
+        await this.ensureConnectedToDocument();
         await this.initializeEditor();
       }
     }
@@ -1275,6 +1283,9 @@
 
   // Add resize observer to ensure editor resizes when container changes
   async firstUpdated() {
+    // Ensure we're connected to the document before Monaco initialization
+    await this.ensureConnectedToDocument();
+
     // Initialize the editor
     await this.initializeEditor();
 
@@ -1293,6 +1304,30 @@
     }
   }
 
+  /**
+   * Ensure this component and its container are properly connected to the document.
+   * Monaco editor requires the container to be in the document for proper initialization.
+   */
+  private async ensureConnectedToDocument(): Promise<void> {
+    // Wait for our own render to complete
+    await this.updateComplete;
+
+    // Verify the container ref is available
+    if (!this.container.value) {
+      throw new Error("Container element not available after updateComplete");
+    }
+
+    // Check if we're connected to the document
+    if (!this.isConnected) {
+      throw new Error("Component is not connected to the document");
+    }
+
+    // Verify the container is also in the document
+    if (!this.container.value.isConnected) {
+      throw new Error("Container element is not connected to the document");
+    }
+  }
+
   private _resizeObserver: ResizeObserver | null = null;
   private _windowResizeHandler: (() => void) | null = null;