Storage.js

8.51 KB
08/11/2024 16:51
JS
Storage.js
/**
 * ระบบจัดการการจัดเก็บข้อมูล
 * รับผิดชอบการจัดการข้อมูลใน localStorage รวมถึงการบันทึก, โหลด, และจัดการข้อมูลที่มีเวลาหมดอายุ
 */
const Storage = {
  /**
   * บันทึกข้อมูลลง localStorage
   * @param {string} key - คีย์สำหรับจัดเก็บข้อมูล
   * @param {*} value - ข้อมูลที่ต้องการบันทึก
   * @returns {boolean} สถานะการบันทึก
   */
  save(key, value) {
    try {
      const serializedValue = JSON.stringify(value);
      localStorage.setItem(key, serializedValue);
      return true;
    } catch (error) {
      console.error('เกิดข้อผิดพลาดในการบันทึกข้อมูล:', error);
      return false;
    }
  },

  /**
   * โหลดข้อมูลจาก localStorage
   * @param {string} key - คีย์ที่ต้องการโหลด
   * @param {*} defaultValue - ค่าเริ่มต้นหากไม่พบข้อมูล
   * @returns {*} ข้อมูลที่โหลดหรือค่าเริ่มต้น
   */
  load(key, defaultValue = null) {
    try {
      const item = localStorage.getItem(key);
      if (item === null) return defaultValue;
      return JSON.parse(item);
    } catch (error) {
      console.error('เกิดข้อผิดพลาดในการโหลดข้อมูล:', error);
      return defaultValue;
    }
  },

  /**
   * ลบข้อมูลจาก localStorage
   * @param {string} key - คีย์ที่ต้องการลบ
   * @returns {boolean} สถานะการลบ
   */
  remove(key) {
    try {
      localStorage.removeItem(key);
      return true;
    } catch (error) {
      console.error('เกิดข้อผิดพลาดในการลบข้อมูล:', error);
      return false;
    }
  },

  /**
   * ล้างข้อมูลทั้งหมดใน localStorage
   * @returns {boolean} สถานะการล้างข้อมูล
   */
  clear() {
    try {
      localStorage.clear();
      return true;
    } catch (error) {
      console.error('เกิดข้อผิดพลาดในการล้างข้อมูล:', error);
      return false;
    }
  },

  /**
   * ตรวจสอบว่ามีข้อมูลอยู่หรือไม่
   * @param {string} key - คีย์ที่ต้องการตรวจสอบ
   * @returns {boolean} ผลการตรวจสอบ
   */
  has(key) {
    return localStorage.getItem(key) !== null;
  },

  /**
   * บันทึกข้อมูลพร้อมกำหนดเวลาหมดอายุ
   * @param {string} key - คีย์สำหรับจัดเก็บ
   * @param {*} value - ข้อมูลที่ต้องการบันทึก
   * @param {number} ttl - เวลาหมดอายุ (มิลลิวินาที)
   * @returns {boolean} สถานะการบันทึก
   */
  saveWithExpiry(key, value, ttl) {
    const item = {
      value,
      expiry: Date.now() + ttl,
    };
    return this.save(key, item);
  },

  /**
   * โหลดข้อมูลพร้อมตรวจสอบเวลาหมดอายุ
   * @param {string} key - คีย์ที่ต้องการโหลด
   * @param {*} defaultValue - ค่าเริ่มต้นหากไม่พบข้อมูลหรือข้อมูลหมดอายุ
   * @returns {*} ข้อมูลที่โหลดหรือค่าเริ่มต้น
   */
  loadWithExpiry(key, defaultValue = null) {
    const item = this.load(key);

    if (!item) return defaultValue;

    if (Date.now() > item.expiry) {
      this.remove(key);
      return defaultValue;
    }

    return item.value;
  },

  /**
   * นับขนาดการใช้งาน localStorage (ในหน่วยไบต์)
   * @returns {number} ขนาดที่ใช้งาน
   */
  getSize() {
    let size = 0;
    for (let key in localStorage) {
      if (localStorage.hasOwnProperty(key)) {
        size += localStorage[key].length + key.length;
      }
    }
    return size;
  },

  /**
   * ตรวจสอบพื้นที่ว่างใน localStorage
   * @param {number} additionalBytes - จำนวนไบต์ที่ต้องการตรวจสอบเพิ่มเติม
   * @returns {boolean} ผลการตรวจสอบ
   */
  hasSpace(additionalBytes = 0) {
    try {
      const testKey = '___test___';
      const testValue = 'x'.repeat(additionalBytes);
      localStorage.setItem(testKey, testValue);
      localStorage.removeItem(testKey);
      return true;
    } catch (error) {
      return false;
    }
  },

  /**
   * บันทึกข้อมูลหลายรายการพร้อมกัน
   * @param {Object} items - ออบเจ็กต์ที่มี key และ value ที่ต้องการบันทึก
   * @returns {boolean} สถานะการบันทึก
   */
  bulkSave(items) {
    let success = true;
    for (const [key, value] of Object.entries(items)) {
      if (!this.save(key, value)) {
        success = false;
      }
    }
    return success;
  },

  /**
   * โหลดข้อมูลหลายรายการพร้อมกัน
   * @param {Array<string>} keys - รายการคีย์ที่ต้องการโหลด
   * @param {*} defaultValue - ค่าเริ่มต้นหากไม่พบข้อมูล
   * @returns {Object} ออบเจ็กต์ที่มีข้อมูลที่โหลด
   */
  bulkLoad(keys, defaultValue = null) {
    const result = {};
    keys.forEach(key => {
      result[key] = this.load(key, defaultValue);
    });
    return result;
  },

  /**
   * ลบข้อมูลหลายรายการพร้อมกัน
   * @param {Array<string>} keys - รายการคีย์ที่ต้องการลบ
   * @returns {boolean} สถานะการลบ
   */
  bulkRemove(keys) {
    let success = true;
    keys.forEach(key => {
      if (!this.remove(key)) {
        success = false;
      }
    });
    return success;
  },

  /**
   * ลบข้อมูลที่หมดอายุทั้งหมด
   */
  clearExpired() {
    const keys = Object.keys(localStorage);
    keys.forEach(key => {
      const item = this.load(key);
      if (item && item.expiry && Date.now() > item.expiry) {
        this.remove(key);
      }
    });
  },

  /**
   * สร้าง namespace สำหรับจัดการข้อมูลแยกตามหมวดหมู่
   * @param {string} prefix - คำนำหน้าสำหรับ namespace
   * @returns {Object} ออบเจ็กต์ที่มีเมธอดสำหรับจัดการข้อมูลใน namespace
   */
  namespace(prefix) {
    return {
      // บันทึกข้อมูลใน namespace
      save: (key, value) => this.save(`${prefix}_${key}`, value),

      // โหลดข้อมูลจาก namespace
      load: (key, defaultValue) => this.load(`${prefix}_${key}`, defaultValue),

      // ลบข้อมูลจาก namespace
      remove: (key) => this.remove(`${prefix}_${key}`),

      // ล้างข้อมูลทั้งหมดใน namespace
      clear: () => {
        const keys = Object.keys(localStorage)
          .filter(k => k.startsWith(`${prefix}_`));
        return this.bulkRemove(keys);
      },

      // ดึงข้อมูลทั้งหมดใน namespace
      getAll: () => {
        const result = {};
        const keys = Object.keys(localStorage)
          .filter(k => k.startsWith(`${prefix}_`));
        keys.forEach(key => {
          const shortKey = key.replace(`${prefix}_`, '');
          result[shortKey] = this.load(key);
        });
        return result;
      }
    };
  }
};

// ล้างข้อมูลที่หมดอายุอัตโนมัติตามระยะเวลาที่กำหนด
setInterval(() => Storage.clearExpired(), CONFIG.CACHE.CLEANUP_INTERVAL || 3600000);