1. Project Overview
Cat.js is a lightweight, state-of-the-art engine designed to build powerful User Interfaces (UIs). It prioritizes the highest performance and efficiency, based exclusively on modern native browser APIs, primarily Web Components.

- Version: 0.1.0 (as of October 1, 2024)

2. Core Concepts and Principles
- Utilizes modern native browser APIs, especially Web Components
- Focuses on maximum performance and efficiency
- Promotes a lightweight approach to UI development
- Emphasizes simplicity and ease of use

3. Technical Details

Key Features
- Client-Side Compiler (CSC) before loading the DOM
- Attachment through a script:src tag in the head of HTML documents
- Written in vanilla, low-level JavaScript optimized for browser runtime and memory usage
- Beautiful and easy-to-use syntax
- Efficient project tree structure
- Compiles everything on the loading stage, Ahead Of Time (AOT).
- Everything that was compiled it's "0-dependency", neither of cat.js.

Implementation Details
- No Virtual DOM or similar abstractions
- Avoids use of bundlers, Webpack, polyfills, etc.
- Discourages writing HTML or CSS code within JavaScript files
- Eliminates render methods for components and logic that trigger unnecessary reflows and repainting
- Avoid treat Cat.js as a runtime at any cost.

4. Code

```

// Updated cat.js with style tag inclusion fix

(function() {
  'use strict';

  /**
   * Internal module for tracking loaded files.
   */
  const Registry = (function() {
    const loadedFiles = new Set();

    return {
      isFileLoaded: (path) => loadedFiles.has(path),
      markFileAsLoaded: (path) => loadedFiles.add(path),
    };
  })();

  /**
   * Compiler module for generating optimized component classes.
   */
  const Compiler = (function() {
    /**
     * Compiles the component's template and script into an optimized component class definition.
     * @param {string} name - The name of the component (e.g., 'my-component').
     * @param {string} templateContent - The inner HTML of the component's <template>.
     * @param {string} scriptContent - The content of the component's <script>.
     */
    function compileComponent(name, templateContent, scriptContent) {
      // Helper functions
      function componentNameToClassName(name) {
        return name.split('-').map(s => s[0].toUpperCase() + s.slice(1)).join('');
      }
      function extractDynamicExpressions(text) {
        const regex = /\{([^}]+)\}/g;
        let match;
        const expressions = [];
        while ((match = regex.exec(text)) !== null) {
          expressions.push(match[1].trim());
        }
        return expressions;
      }
      function replaceExpressions(text) {
        return text.replace(/\{([^}]+)\}/g, '${this.$1}');
      }

      const className = componentNameToClassName(name);

      // Create a template element and set its innerHTML to the templateContent
      const templateElement = document.createElement('template');
      templateElement.innerHTML = templateContent;
      const templateContentFragment = templateElement.content;

      // Initialize code snippets
      let elementCode = '';
      let propertyInitializations = '';
      let getterSetterCode = '';

      const dynamicProperties = new Set();
      const propertyToUpdateCode = {};
      const initialProperties = {};
      const propertiesHandled = new Set();

      let nodeCounter = 1;

      function processNode(node, parentVarName) {
        if (node.nodeType === Node.ELEMENT_NODE) {
          const nodeName = node.tagName.toLowerCase();

          if (nodeName === 'style') {
            // Create code to create and append style element
            const styleContent = node.textContent;
            if (styleContent.trim()) {
              elementCode += `const style = document.createElement('style');\n`;
              elementCode += `style.textContent = ${JSON.stringify(styleContent)};\n`;
              elementCode += `${parentVarName}.appendChild(style);\n`;
            }
            return;
          }

          // Assign instance variable name
          let nodeVarName;
          if (node.id) {
            nodeVarName = `this.$${node.id}`;
          } else if (nodeName === 'button' || nodeName === 'input' || nodeName === 'div' || nodeName === 'span') {
            nodeVarName = `this._${nodeName}${nodeCounter++}`;
          } else {
            nodeVarName = `node${nodeCounter++}`;
          }

          // Create node
          if (nodeVarName.startsWith('this.')) {
            // Assign to this property without 'const'
            elementCode += `${nodeVarName} = document.createElement('${nodeName}');\n`;
          } else {
            // Local variable with 'const'
            elementCode += `const ${nodeVarName} = document.createElement('${nodeName}');\n`;
          }

          // Process attributes
          for (let attr of node.attributes) {
            const attrName = attr.name;
            const attrValue = attr.value;
            const dynamicExprs = extractDynamicExpressions(attrValue);

            if (dynamicExprs.length > 0) {
              dynamicExprs.forEach(expr => {
                dynamicProperties.add(expr);
                if (!propertyToUpdateCode[expr]) {
                  propertyToUpdateCode[expr] = new Set();
                }
                const updateCode = `${nodeVarName}.setAttribute('${attrName}', \`${replaceExpressions(attrValue)}\`);`;
                propertyToUpdateCode[expr].add(updateCode);
              });

              // Initialize attribute with current property values
              elementCode += `${nodeVarName}.setAttribute('${attrName}', \`${replaceExpressions(attrValue)}\`);\n`;

            } else {
              // Static attribute
              elementCode += `${nodeVarName}.setAttribute('${attrName}', ${JSON.stringify(attrValue)});\n`;
            }
          }

          // Process child nodes
          if (node.childNodes.length > 0) {
            for (let child of node.childNodes) {
              processNode(child, nodeVarName);
            }
          }

          // Append to parent
          elementCode += `${parentVarName}.appendChild(${nodeVarName});\n`;

        } else if (node.nodeType === Node.TEXT_NODE) {
          // Handle text nodes directly under parentVarName
          const textContent = node.nodeValue;
          if (textContent.trim() !== '') {
            const dynamicExprs = extractDynamicExpressions(textContent);

            if (dynamicExprs.length > 0) {
              const textNodeVar = `this._textNode${nodeCounter++}`;
              if (!propertiesHandled.has(textNodeVar)) {
                propertiesHandled.add(textNodeVar);
                if (textNodeVar.startsWith('this.')) {
                  elementCode += `${textNodeVar} = document.createTextNode(\`${replaceExpressions(textContent)}\`);\n`;
                } else {
                  elementCode += `const ${textNodeVar} = document.createTextNode(\`${replaceExpressions(textContent)}\`);\n`;
                }
              }
              elementCode += `${parentVarName}.appendChild(${textNodeVar});\n`;

              dynamicExprs.forEach(expr => {
                dynamicProperties.add(expr);
                if (!propertyToUpdateCode[expr]) {
                  propertyToUpdateCode[expr] = new Set();
                }
                const updateCode = `${textNodeVar}.textContent = \`${replaceExpressions(textContent)}\`;`;
                propertyToUpdateCode[expr].add(updateCode);
              });
            } else {
              const textNodeVar = `document.createTextNode(${JSON.stringify(textContent)})`;
              elementCode += `${parentVarName}.appendChild(${textNodeVar});\n`;
            }
          }
        }
      }

      // Start processing from templateContentFragment
      elementCode += `const shadowRoot = this.attachShadow({ mode: 'open' });\n`;

      // Process child nodes of the template content
      const rootVarName = 'shadowRoot';
      for (let child of templateContentFragment.childNodes) {
        processNode(child, rootVarName);
      }

      // Now process scriptContent to find initial property assignments
      const propertyInitRegex = /this\.(\w+)\s*=\s*(.+?);/g;
      let match;
      while ((match = propertyInitRegex.exec(scriptContent)) !== null) {
        const propName = match[1];
        const propValue = match[2];
        initialProperties[propName] = propValue;
      }

      // For properties not initialized, set default to null
      dynamicProperties.forEach(prop => {
        if (!initialProperties.hasOwnProperty(prop)) {
          initialProperties[prop] = 'null';
        }
      });

      // Build property initializations
      for (let [prop, value] of Object.entries(initialProperties)) {
        propertyInitializations += `this._${prop} = ${value};\n`;
      }

      // Build getters and setters with update code
      for (let prop of dynamicProperties) {
        let updateCode = '';
        if (propertyToUpdateCode[prop]) {
          updateCode = Array.from(propertyToUpdateCode[prop]).join('\n');
        }
        getterSetterCode += `
    get ${prop}() {
      return this._${prop};
    }
    set ${prop}(value) {
      this._${prop} = value;
      ${updateCode}
    }
    `;
      }

      // Generate the full class code
      const classCode = `
class ${className} extends HTMLElement {
  constructor() {
    super();
    ${elementCode}
    ${propertyInitializations}
    ${scriptContent}
  }

  ${getterSetterCode}

}
customElements.define('${name}', ${className});
`;

      // Output the compiled class code
      console.log(`Compiled component class for ${name}:\n${classCode}`);

      // Evaluate the class code
      try {
        eval(classCode);
      } catch (error) {
        console.error(`Error compiling component ${name}: ${error.message}`);
        console.error(error);
        console.log(classCode);
      }
    }

    return {
      compileComponent,
    };
  })();

  /**
   * Internal module for loading and parsing HTML files.
   */
  const Loader = (function() {
    /**
     * Loads an HTML file from the given path.
     * @param {string} path - The path to the HTML file (without .html extension).
     * @returns {Promise<string>} - A promise that resolves to the content of the HTML file.
     */
    async function loadFile(path) {
      const fullPath = `${path}.html`;

      try {
        const response = await fetch(fullPath);
        if (!response.ok) {
          throw new Error(`Failed to load: ${fullPath} (Status: ${response.status})`);
        }
        const content = await response.text();
        return content;
      } catch (error) {
        console.error(error.message);
        throw error;
      }
    }

    /**
     * Parses an HTML string into a Document object.
     * @param {string} htmlString - The HTML string to parse.
     * @returns {Document} - The parsed Document object.
     */
    function parseHTML(htmlString) {
      const parser = new DOMParser();
      const doc = parser.parseFromString(htmlString, 'text/html');
      return doc;
    }

    return {
      loadFile,
      parseHTML,
    };
  })();

  /**
   * Global load function.
   * @param {string} path - The path to the HTML file (without .html extension).
   */
  window.load = function(path) {
    console.log(`Loading: ${path}`);

    if (Registry.isFileLoaded(path)) {
      console.log(`Already loading or loaded: ${path}`);
      return;
    }

    // Mark the file as loaded immediately to prevent race conditions
    Registry.markFileAsLoaded(path);

    (async function() {
      try {
        const responseText = await Loader.loadFile(path);
        const doc = Loader.parseHTML(responseText);

        // Extract the <template> with the 'name' attribute
        const template = doc.querySelector('template[name]');
        if (!template) {
          console.error(`No <template name="..."> found in ${path}.html`);
          return;
        }

        const componentName = template.getAttribute('name');
        const templateContent = template.innerHTML;

        // Extract the <script> content
        const script = doc.querySelector('script');
        const scriptContent = script ? script.textContent : '';

        // Use compiler to generate and define the component
        Compiler.compileComponent(componentName, templateContent, scriptContent);

        console.log(`Component registered: ${componentName}`);
      } catch (error) {
        console.error(`Error loading component from ${path}: ${error.message}`);
        // Optionally, you can remove the path from the Registry to allow retries
        // Registry.removeFile(path);
      }
    })();
  };
})();

```

5. Sample component:

```
<!-- app/comp/counter.html -->
<template name="my-counter">
    <style>
        .on {
            background-color: blue;
        }
        .off {
            background-color: aliceblue;
        }
        .btn {
            padding: 20px;
        }
    </style>

    <button class="{status} btn">Count: {count}</button>
</template>

<script>
    this.count = 0;
    this.status = 'on';
    
    const button = this.shadowRoot.querySelector('button');
    const span = button.querySelector('span');

    const component = this; // To maintain correct context inside functions

    function updateCount() {
        component.count++;

        component.status = component.status === 'on' ? 'off' : 'on';
        // The reactive system will automatically update the DOM elements where {count} and {status} are used
    }

    button.addEventListener('click', updateCount);
</script>
```

Your goal it's update the compiler for avoid duplicating logics and data, allowing a non linear or neither exponential growth of resources and computation when are defined multiple instances of the same component. Reusing everything that can be reused, sharing a single prototype by component when is registered, with all its methods.

Be accurate,  once finished output cat.js with the implementation.