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 Blob URL Integration and Bundling Parameter

(function() {
  'use strict';

  /**
   * Global configuration object for Cat.js
   * Developers can set CatConfig.bundleAll before loading components.
   */
  window.CatConfig = window.CatConfig || {
      bundleAll: false // Default: Per-Component Blob Files
  };

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

      return {
          /**
           * Checks if a file has already been loaded.
           * @param {string} path - The path to the file.
           * @returns {boolean} - True if the file is loaded, else false.
           */
          isFileLoaded: (path) => loadedFiles.has(path),

          /**
           * Marks a file as loaded to prevent redundant loading.
           * @param {string} path - The path to the file.
           */
          markFileAsLoaded: (path) => loadedFiles.add(path),
      };
  })();

  /**
   * Compiler module for generating and registering component classes using Blob URLs.
   */
  const Compiler = (function() {
      // Array to store compiled component codes in bundling mode
      let bundledCode = '';
      // Flag to indicate if bundling script has been injected
      let bundleScriptInjected = false;

      /**
       * Compiles a single component's template and script into a 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>.
       * @returns {string} - The compiled class code as a string.
       */
      function compileComponentCode(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;

          /**
           * Processes a DOM node to generate corresponding JavaScript code.
           * @param {Node} node - The DOM node to process.
           * @param {string} parentVarName - The variable name of the parent element in the generated code.
           */
          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 (['button', 'input', 'div', 'span', 'p', 'a'].includes(nodeName)) {
                      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 and function definitions

          /**
           * Extracts function definitions and remaining code from the script content.
           * @param {string} scriptContent - The script content to parse.
           * @returns {object} - An object containing arrays of function definitions and remaining code.
           */
          function extractFunctionDefinitions(scriptContent) {
              const functionDefinitions = [];
              const nonFunctionLines = [];

              let lines = scriptContent.split('\n');
              let insideFunction = false;
              let currentFunctionLines = [];
              let braceLevel = 0;

              for (let line of lines) {
                  // Include the line in the function or non-function code
                  if (!insideFunction) {
                      if (line.trim().startsWith('function ')) {
                          insideFunction = true;
                          braceLevel = (line.match(/\{/g) || []).length - (line.match(/\}/g) || []).length;
                          currentFunctionLines.push(line);
                      } else {
                          // Collect initial property assignments
                          const propInitMatch = line.trim().match(/^this\.(\w+)\s*=\s*(.*);$/);
                          if (propInitMatch) {
                              const propName = propInitMatch[1];
                              const propValue = propInitMatch[2];
                              initialProperties[propName] = propValue;
                          } else if (line.trim() !== '') {
                              nonFunctionLines.push(line);
                          }
                      }
                  } else {
                      currentFunctionLines.push(line);
                      braceLevel += (line.match(/\{/g) || []).length;
                      braceLevel -= (line.match(/\}/g) || []).length;
                      if (braceLevel === 0) {
                          insideFunction = false;
                          functionDefinitions.push(currentFunctionLines.join('\n'));
                          currentFunctionLines = [];
                      }
                  }
              }

              return {
                  functionDefinitions,
                  remainingCode: nonFunctionLines.join('\n')
              };
          }

          const { functionDefinitions, remainingCode } = extractFunctionDefinitions(scriptContent);

          // Collect function names
          const functionNames = [];
          let classMethodsCode = '';

          // Process each function definition
          for (let funcDef of functionDefinitions) {
              // Extract function name, parameters, body
              const funcMatch = /^function\s+(\w+)\s*\(([^)]*)\)\s*\{([\s\S]*?)\}\s*$/m.exec(funcDef.trim());
              if (funcMatch) {
                  const funcName = funcMatch[1];
                  const funcParams = funcMatch[2];
                  let funcBody = funcMatch[3];

                  // Replace 'component.' with 'this.'
                  funcBody = funcBody.replace(/\bcomponent\./g, 'this.');

                  // Add to class methods
                  classMethodsCode += `
      ${funcName}(${funcParams}) {
          ${funcBody}
      }
      `;

                  // Collect function names
                  functionNames.push(funcName);
              }
          }

          // Initialize properties not assigned in scriptContent
          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}
      }
      `;
          }

          // Adjust constructor code to bind methods
          let constructorCode = remainingCode;

          // Prepend 'const functionName = this.functionName.bind(this);'
          let bindingCode = '';
          for (let funcName of functionNames) {
              bindingCode += `const ${funcName} = this.${funcName}.bind(this);\n`;
          }

          // Prepend binding code to constructor code
          constructorCode = bindingCode + constructorCode;

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

      ${getterSetterCode}

      ${classMethodsCode}

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

          return classCode;
      }

      /**
       * Compiles and registers multiple components in bundling mode.
       * @param {Array} components - Array of component class codes.
       */
      function compileAndRegisterBundle(components) {
          if (bundleScriptInjected) return;
          bundleScriptInjected = true;

          // Combine all component codes into one string
          bundledCode = components.join('\n');

          // Create a Blob from the bundled code
          const blob = new Blob([bundledCode], { type: 'application/javascript' });
          const blobURL = URL.createObjectURL(blob);

          // Create a script element
          const script = document.createElement('script');
          script.src = blobURL;
          script.type = 'module'; // Use module type for modern JavaScript features
          script.onload = () => {
              console.log(`All components loaded and registered as a bundle.`);
              // Revoke the Blob URL after the script has been loaded to free memory
              URL.revokeObjectURL(blobURL);
          };
          script.onerror = (error) => {
              console.error(`Error loading component bundle:`, error);
              // Revoke the Blob URL on error to free memory
              URL.revokeObjectURL(blobURL);
          };

          // Append the script to the document head
          document.head.appendChild(script);
      }

      /**
       * Compiles and registers a single component or accumulates for bundling based on configuration.
       * @param {string} name - The name of the component.
       * @param {string} templateContent - The template content.
       * @param {string} scriptContent - The script content.
       */
      function compileAndRegister(name, templateContent, scriptContent) {
          const classCode = compileComponentCode(name, templateContent, scriptContent);

          if (window.CatConfig.bundleAll) {
              // Bundling mode: accumulate component codes
              compiledComponents.push(classCode);
          } else {
              // Per-Component mode: compile and register immediately
              compileAndRegisterComponent(name, classCode);
          }
      }

      /**
       * Finalizes the bundling process by injecting the bundled script.
       * Should be called after all components have been loaded.
       */
      function finalizeBundle() {
          if (window.CatConfig.bundleAll && compiledComponents.length > 0) {
              compileAndRegisterBundle(compiledComponents);
              compiledComponents = []; // Reset after bundling
          }
      }

      /**
       * Compiles and registers the component using Blob URLs.
       * @param {string} name - The name of the component.
       * @param {string} code - The compiled JavaScript class code.
       */
      function compileAndRegisterComponent(name, code) {
          // Create a Blob from the code
          const blob = new Blob([code], { type: 'application/javascript' });
          const blobURL = URL.createObjectURL(blob);

          // Create a script element
          const script = document.createElement('script');
          script.src = blobURL;
          script.type = 'module'; // Use module type for modern JavaScript features
          script.onload = () => {
              console.log(`Component ${name} loaded and registered.`);
              // Revoke the Blob URL after the script has been loaded to free memory
              URL.revokeObjectURL(blobURL);
          };
          script.onerror = (error) => {
              console.error(`Error loading component ${name}:`, error);
              // Revoke the Blob URL on error to free memory
              URL.revokeObjectURL(blobURL);
          };

          // Append the script to the document head
          document.head.appendChild(script);
      }

      // Array to store compiled component codes in bundling mode
      let compiledComponents = [];

      return {
          /**
           * Compiles and registers a component based on bundling configuration.
           * @param {string} name - The name of the component.
           * @param {string} templateContent - The template content.
           * @param {string} scriptContent - The script content.
           */
          compileComponent: compileAndRegister,

          /**
           * Finalizes the bundling process by injecting the bundled script.
           * Should be called when all components have been loaded.
           */
          finalizeBundle: finalizeBundle,
      };
  })();

  /**
   * 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 prepared for registration: ${componentName}`);

              // If bundling mode is enabled, finalize the bundle after all components are loaded
              if (window.CatConfig.bundleAll) {
                  // Check if all components are loaded; in this simple implementation, we assume that
                  // finalizeBundle is called externally after all load calls
                  // Alternatively, implement a more sophisticated tracking mechanism
                  // For simplicity, we'll use a timeout to finalize after a brief delay
                  setTimeout(() => {
                      Compiler.finalizeBundle();
                  }, 0);
              }

          } catch (error) {
              console.error(`Error loading component from ${path}: ${error.message}`);
          }
      })();
  };

})();

```

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 task it's implement an efficient logic that search for all the load declarations recursively, fetching the files, looking inside for the load declaration, if so, fetching the file and keep the search until all the load declarations are found. Once, then compile each one of these components and parse it into the blob file, weather it's by component or a single file, depending the user's configuration. In this way we guarantee that all the components are registered and ready to use when the DOM loads.

Do a deep research understanding how can implement such logic in an efficient wat that match our criteria and browser runtime.