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 initialization order 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 (['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

      // Extract function definitions and remaining code from scriptContent
      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;

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

  ${getterSetterCode}

  ${classMethodsCode}

}
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}`);
      }
    })();
  };
})();


```

Our compiler already works pretty well, recently we added the capacity of optimize get, set and custom component's JavaScript into body class, rather than constructor in order to avoid duplication of logic, and have the same memory allocation for multiple instances of the same component. Now, we need to integrate into our compiler the connect and disconnect callback, that targets component's instance individually.