moduleManager.js

7.30 KB
12/10/2025 04:52
JS
moduleManager.js
/**
 * Module Manager - จัดการโมดูลต่างๆ ในตัวแก้ไข
 */
(function(global) {
  'use strict';

  /**
   * คลาส ModuleManager
   * จัดการการโหลดและเริ่มต้นโมดูลต่างๆ
   */
  class ModuleManager {
    constructor(editor) {
      this.editor = editor;
      this.modules = {};
      this.moduleOrder = [];
      this.loadedModules = new Set();
      this.initializedModules = new Set();
    }

    /**
     * ลงทะเบียนโมดูล
     * @param {string} name - ชื่อโมดูล
     * @param {Object} module - ออบเจกต์โมดูล
     * @param {Array} dependencies - โมดูลที่ต้องการ (optional)
     */
    register(name, module, dependencies = []) {
      if (this.modules[name]) {
        console.warn(`Module '${name}' is already registered`);
        return;
      }

      this.modules[name] = {
        instance: null,
        moduleClass: module,
        dependencies,
        loaded: false,
        initialized: false
      };

      // เพิ่มในลำดับโหลดหากยังไม่มี
      if (!this.moduleOrder.includes(name)) {
        this.moduleOrder.push(name);
      }
    }

    /**
     * โหลดโมดูล
     * @param {string} name - ชื่อโมดูล
     */
    load(name) {
      if (!this.modules[name]) {
        console.error(`Module '${name}' is not registered`);
        return false;
      }

      if (this.loadedModules.has(name)) {
        console.warn(`Module '${name}' is already loaded`);
        return true;
      }

      const moduleInfo = this.modules[name];

      // ตรวจสอบการพึ่งพา
      for (const dep of moduleInfo.dependencies) {
        if (!this.loadedModules.has(dep)) {
          if (!this.load(dep)) {
            console.error(`Failed to load dependency '${dep}' for module '${name}'`);
            return false;
          }
        }
      }

      try {
        // สร้างอินสแตนซ์โมดูล
        moduleInfo.instance = new moduleInfo.moduleClass(this.editor);
        moduleInfo.loaded = true;
        this.loadedModules.add(name);

        // ส่งเหตุการณ์
        this.editor.emit('module:loaded', {name});

        if (this.editor.config.debug) {
          console.log(`Module loaded: ${name}`);
        }

        return true;
      } catch (error) {
        console.error(`Failed to load module '${name}':`, error);
        return false;
      }
    }

    /**
     * เริ่มต้นโมดูล
     * @param {string} name - ชื่อโมดูล
     */
    init(name) {
      if (!this.modules[name]) {
        console.error(`Module '${name}' is not registered`);
        return false;
      }

      if (!this.loadedModules.has(name)) {
        if (!this.load(name)) {
          return false;
        }
      }

      if (this.initializedModules.has(name)) {
        console.warn(`Module '${name}' is already initialized`);
        return true;
      }

      const moduleInfo = this.modules[name];

      try {
        // เรียกเมธอด init ถ้ามี
        if (typeof moduleInfo.instance.init === 'function') {
          moduleInfo.instance.init();
        }

        moduleInfo.initialized = true;
        this.initializedModules.add(name);

        // ส่งเหตุการณ์
        this.editor.emit('module:initialized', {name});

        if (this.editor.config.debug) {
          console.log(`Module initialized: ${name}`);
        }

        return true;
      } catch (error) {
        console.error(`Failed to initialize module '${name}':`, error);
        return false;
      }
    }

    /**
     * โหลดและเริ่มต้นโมดูลทั้งหมด
     */
    loadAll() {
      for (const name of this.moduleOrder) {
        this.load(name);
      }
    }

    /**
     * เริ่มต้นโมดูลทั้งหมด
     */
    initAll() {
      for (const name of this.moduleOrder) {
        this.init(name);
      }
    }

    /**
     * รับอินสแตนซ์โมดูล
     * @param {string} name - ชื่อโมดูล
     * @returns {Object} อินสแตนซ์โมดูล
     */
    get(name) {
      if (!this.modules[name]) {
        console.error(`Module '${name}' is not registered`);
        return null;
      }

      return this.modules[name].instance;
    }

    /**
     * ตรวจสอบว่าโมดูลถูกโหลดแล้วหรือไม่
     * @param {string} name - ชื่อโมดูล
     * @returns {boolean} ถูกโหลดแล้วหรือไม่
     */
    isLoaded(name) {
      return this.loadedModules.has(name);
    }

    /**
     * ตรวจสอบว่าโมดูลถูกเริ่มต้นแล้วหรือไม่
     * @param {string} name - ชื่อโมดูล
     * @returns {boolean} ถูกเริ่มต้นแล้วหรือไม่
     */
    isInitialized(name) {
      return this.initializedModules.has(name);
    }

    /**
     * ถอนการโหลดโมดูล
     * @param {string} name - ชื่อโมดูล
     */
    unload(name) {
      if (!this.modules[name]) {
        console.error(`Module '${name}' is not registered`);
        return false;
      }

      if (!this.loadedModules.has(name)) {
        console.warn(`Module '${name}' is not loaded`);
        return true;
      }

      const moduleInfo = this.modules[name];

      try {
        // เรียกเมธอด destroy ถ้ามี
        if (moduleInfo.instance && typeof moduleInfo.instance.destroy === 'function') {
          moduleInfo.instance.destroy();
        }

        moduleInfo.instance = null;
        moduleInfo.loaded = false;
        moduleInfo.initialized = false;

        this.loadedModules.delete(name);
        this.initializedModules.delete(name);

        // ส่งเหตุการณ์
        this.editor.emit('module:unloaded', {name});

        if (this.editor.config.debug) {
          console.log(`Module unloaded: ${name}`);
        }

        return true;
      } catch (error) {
        console.error(`Failed to unload module '${name}':`, error);
        return false;
      }
    }

    /**
     * รับชื่อโมดูลทั้งหมด
     * @returns {Array} ชื่อโมดูลทั้งหมด
     */
    getModuleNames() {
      return [...this.moduleOrder];
    }

    /**
     * รับข้อมูลโมดูลทั้งหมด
     * @returns {Object} ข้อมูลโมดูลทั้งหมด
     */
    getModulesInfo() {
      const info = {};

      for (const name of this.moduleOrder) {
        const moduleInfo = this.modules[name];
        info[name] = {
          loaded: this.loadedModules.has(name),
          initialized: this.initializedModules.has(name),
          dependencies: moduleInfo.dependencies
        };
      }

      return info;
    }
  }

  // เปิดเผยคลาส ModuleManager ทั่วโลก
  global.ModuleManager = ModuleManager;

})(typeof window !== 'undefined' ? window : this);