UNPKG

create-nexaui-electron

Version:

Create Nexa App - Tool untuk membuat aplikasi Nexa Electron

821 lines (738 loc) 23.9 kB
export class classIndexDB { constructor(dbName = "Database", dbVersion = 1, storeName = "Data") { this.dbName = dbName; this.dbVersion = dbVersion; this.storeName = storeName; this.encryptionKey = "Nexa2025"; // You should use a more secure key in production } openDB() { return new Promise((resolve, reject) => { const request = indexedDB.open(this.dbName, this.dbVersion); request.onerror = (event) => reject("Error membuka database: " + event.target.error); request.onsuccess = (event) => resolve(event.target.result); request.onupgradeneeded = (event) => { const db = event.target.result; const objectStore = db.createObjectStore(this.storeName, { keyPath: "key", }); objectStore.createIndex("updated_at", "updated_at", { unique: false }); }; }); } async encrypt(data) { // Simple encryption using Base64 and XOR const text = JSON.stringify(data); const key = this.encryptionKey; // Convert text to Base64 const base64 = btoa(text); // XOR encryption let encrypted = ""; for (let i = 0; i < base64.length; i++) { const charCode = base64.charCodeAt(i) ^ key.charCodeAt(i % key.length); encrypted += String.fromCharCode(charCode); } return { encrypted: btoa(encrypted), iv: null, // No IV needed for this simple encryption }; } async decrypt(encryptedData) { // Simple decryption using Base64 and XOR const key = this.encryptionKey; // Decode Base64 const encrypted = atob(encryptedData); // XOR decryption let decrypted = ""; for (let i = 0; i < encrypted.length; i++) { const charCode = encrypted.charCodeAt(i) ^ key.charCodeAt(i % key.length); decrypted += String.fromCharCode(charCode); } // Decode Base64 and parse JSON return JSON.parse(atob(decrypted)); } async saveData(key, data, updated_at) { const db = await this.openDB(); return new Promise(async (resolve, reject) => { try { const transaction = db.transaction([this.storeName], "readwrite"); const store = transaction.objectStore(this.storeName); const getRequest = store.get(key); getRequest.onsuccess = async (event) => { const existingData = event.target.result; if (existingData && existingData.updated_at >= updated_at) { resolve("Data sudah yang terbaru"); } else { const encryptedData = await this.encrypt(data); const updateRequest = store.put({ key: key, data: encryptedData.encrypted, updated_at: updated_at, }); updateRequest.onsuccess = () => resolve("Data berhasil disimpan/diperbarui"); updateRequest.onerror = (event) => reject("Error menyimpan/memperbarui data: " + event.target.error); } }; getRequest.onerror = (event) => reject("Error memeriksa data: " + event.target.error); } catch (error) { reject("Encryption error: " + error); } }); } async getData(key) { const db = await this.openDB(); return new Promise(async (resolve, reject) => { try { const transaction = db.transaction([this.storeName], "readonly"); const store = transaction.objectStore(this.storeName); const request = store.get(key); request.onsuccess = async (event) => { const result = event.target.result; if (result) { const decryptedData = await this.decrypt(result.data); resolve({ key: result.key, data: decryptedData, updated_at: result.updated_at, }); } else { resolve(null); } }; request.onerror = (event) => reject("Error mengambil data: " + event.target.error); } catch (error) { reject("Decryption error: " + error); } }); } async deleteData(key) { const db = await this.openDB(); return new Promise((resolve, reject) => { const transaction = db.transaction([this.storeName], "readwrite"); const store = transaction.objectStore(this.storeName); const request = store.delete(key); request.onsuccess = () => resolve("Data berhasil dihapus"); request.onerror = (event) => reject("Error menghapus data: " + event.target.error); }); } async getAllData() { const db = await this.openDB(); return new Promise((resolve, reject) => { const transaction = db.transaction([this.storeName], "readonly"); const store = transaction.objectStore(this.storeName); const request = store.getAll(); request.onsuccess = (event) => resolve(event.target.result); request.onerror = (event) => reject("Error mengambil semua data: " + event.target.error); }); } async updateData(key, newData) { const db = await this.openDB(); return new Promise((resolve, reject) => { const transaction = db.transaction([this.storeName], "readwrite"); const store = transaction.objectStore(this.storeName); const getRequest = store.get(key); getRequest.onsuccess = (event) => { const existingData = event.target.result; if (!existingData) { reject("Data tidak ditemukan"); return; } const updatedObject = { key: key, data: { ...existingData.data, ...newData }, updated_at: Date.now(), }; const updateRequest = store.put(updatedObject); updateRequest.onsuccess = () => resolve("Data berhasil diupdate"); updateRequest.onerror = (event) => reject("Error mengupdate data: " + event.target.error); }; getRequest.onerror = (event) => reject("Error memeriksa data: " + event.target.error); }); } async getLatestData() { const db = await this.openDB(); return new Promise((resolve, reject) => { const transaction = db.transaction([this.storeName], "readonly"); const store = transaction.objectStore(this.storeName); const index = store.index("updated_at"); const request = index.openCursor(null, "prev"); request.onsuccess = (event) => { const cursor = event.target.result; if (cursor) { resolve(cursor.value); } else { resolve(null); } }; request.onerror = (event) => reject("Error mengambil data terbaru: " + event.target.error); }); } } export class classLocalStorage { constructor(prefix = "") { this.prefix = prefix; } saveData(key, data, updated_at) { return new Promise((resolve) => { const fullKey = this.prefix + key; const existingData = localStorage.getItem(fullKey); if (existingData) { const parsed = JSON.parse(existingData); if (parsed.updated_at >= updated_at) { resolve("Data sudah yang terbaru"); return; } } const saveObject = { key: key, data: data, updated_at: updated_at, }; localStorage.setItem(fullKey, JSON.stringify(saveObject)); resolve("Data berhasil disimpan/diperbarui"); }); } getData(key) { return new Promise((resolve) => { const data = localStorage.getItem(this.prefix + key); resolve(data ? JSON.parse(data) : null); }); } deleteData(key) { return new Promise((resolve) => { localStorage.removeItem(this.prefix + key); resolve("Data berhasil dihapus"); }); } getAllData() { return new Promise((resolve) => { const allData = []; for (let i = 0; i < localStorage.length; i++) { const key = localStorage.key(i); if (key.startsWith(this.prefix)) { const data = JSON.parse(localStorage.getItem(key)); allData.push(data); } } resolve(allData); }); } updateData(key, newData) { return new Promise((resolve, reject) => { const fullKey = this.prefix + key; const existingData = localStorage.getItem(fullKey); if (!existingData) { reject("Data tidak ditemukan"); return; } const parsed = JSON.parse(existingData); const updatedObject = { key: key, data: { ...parsed.data, ...newData }, updated_at: Date.now(), }; localStorage.setItem(fullKey, JSON.stringify(updatedObject)); resolve("Data berhasil diupdate"); }); } async getLatestData() { return new Promise((resolve) => { let latestData = null; let latestTimestamp = 0; for (let i = 0; i < localStorage.length; i++) { const key = localStorage.key(i); if (key.startsWith(this.prefix)) { const data = JSON.parse(localStorage.getItem(key)); if (data.updated_at > latestTimestamp) { latestTimestamp = data.updated_at; latestData = data; } } } resolve(latestData); }); } } export class classCookies { constructor(prefix = "app_") { this.prefix = prefix; } saveData(key, data, updated_at, options = {}) { return new Promise((resolve) => { const fullKey = this.prefix + key; const existingData = this.getCookie(fullKey); if (existingData) { const parsed = JSON.parse(existingData); if (parsed.updated_at >= updated_at) { resolve("Data sudah yang terbaru"); return; } } const saveObject = { key: key, data: data, updated_at: updated_at, }; // Default options const defaultOptions = { expires: 365, // hari path: "/", secure: false, sameSite: "Lax", }; const cookieOptions = { ...defaultOptions, ...options }; // Set expires let expires = ""; if (cookieOptions.expires) { const date = new Date(); date.setTime( date.getTime() + cookieOptions.expires * 24 * 60 * 60 * 1000 ); expires = `expires=${date.toUTCString()};`; } // Build cookie string let cookieString = `${fullKey}=${encodeURIComponent( JSON.stringify(saveObject) )};${expires}`; cookieString += `path=${cookieOptions.path};`; if (cookieOptions.secure) cookieString += "secure;"; if (cookieOptions.sameSite) cookieString += `sameSite=${cookieOptions.sameSite};`; document.cookie = cookieString; resolve("Data berhasil disimpan/diperbarui"); }); } getCookie(key) { const name = this.prefix + key + "="; const decodedCookie = decodeURIComponent(document.cookie); const cookieArray = decodedCookie.split(";"); for (let i = 0; i < cookieArray.length; i++) { let cookie = cookieArray[i].trim(); if (cookie.indexOf(name) === 0) { return cookie.substring(name.length); } } return null; } getData(key) { return new Promise((resolve) => { const data = this.getCookie(key); resolve(data ? JSON.parse(data) : null); }); } deleteData(key, options = {}) { return new Promise((resolve) => { const fullKey = this.prefix + key; const defaultOptions = { path: "/", secure: false, sameSite: "Lax", }; const cookieOptions = { ...defaultOptions, ...options }; // Set expired date to past document.cookie = `${fullKey}=;expires=Thu, 01 Jan 1970 00:00:00 GMT;path=${cookieOptions.path}`; resolve("Data berhasil dihapus"); }); } getAllData() { return new Promise((resolve) => { const allData = []; const decodedCookie = decodeURIComponent(document.cookie); const cookieArray = decodedCookie.split(";"); for (let i = 0; i < cookieArray.length; i++) { const cookie = cookieArray[i].trim(); if (cookie.indexOf(this.prefix) === 0) { const equalPos = cookie.indexOf("="); const value = cookie.substring(equalPos + 1); try { const data = JSON.parse(value); allData.push(data); } catch (e) { console.error("Error parsing cookie:", e); } } } resolve(allData); }); } updateData(key, newData, options = {}) { return new Promise(async (resolve, reject) => { const existingData = await this.getData(key); if (!existingData) { reject("Data tidak ditemukan"); return; } const updatedObject = { key: key, data: { ...existingData.data, ...newData }, updated_at: Date.now(), }; await this.saveData( key, updatedObject.data, updatedObject.updated_at, options ); resolve("Data berhasil diupdate"); }); } async getLatestData() { return new Promise((resolve) => { let latestData = null; let latestTimestamp = 0; const decodedCookie = decodeURIComponent(document.cookie); const cookieArray = decodedCookie.split(";"); for (let i = 0; i < cookieArray.length; i++) { const cookie = cookieArray[i].trim(); if (cookie.indexOf(this.prefix) === 0) { const equalPos = cookie.indexOf("="); const value = cookie.substring(equalPos + 1); try { const data = JSON.parse(value); if (data.updated_at > latestTimestamp) { latestTimestamp = data.updated_at; latestData = data; } } catch (e) { console.error("Error parsing cookie:", e); } } } resolve(latestData); }); } } export class classSessionStorage { constructor(prefix = "app_") { this.prefix = prefix; } saveData(key, data, updated_at) { return new Promise((resolve) => { const fullKey = this.prefix + key; const existingData = sessionStorage.getItem(fullKey); if (existingData) { const parsed = JSON.parse(existingData); if (parsed.updated_at >= updated_at) { resolve("Data sudah yang terbaru"); return; } } const saveObject = { key: key, data: data, updated_at: updated_at, }; sessionStorage.setItem(fullKey, JSON.stringify(saveObject)); resolve("Data berhasil disimpan/diperbarui"); }); } getData(key) { return new Promise((resolve) => { const data = sessionStorage.getItem(this.prefix + key); resolve(data ? JSON.parse(data) : null); }); } deleteData(key) { return new Promise((resolve) => { sessionStorage.removeItem(this.prefix + key); resolve("Data berhasil dihapus"); }); } getAllData() { return new Promise((resolve) => { const allData = []; for (let i = 0; i < sessionStorage.length; i++) { const key = sessionStorage.key(i); if (key.startsWith(this.prefix)) { const data = JSON.parse(sessionStorage.getItem(key)); allData.push(data); } } resolve(allData); }); } updateData(key, newData) { return new Promise((resolve, reject) => { const fullKey = this.prefix + key; const existingData = sessionStorage.getItem(fullKey); if (!existingData) { reject("Data tidak ditemukan"); return; } const parsed = JSON.parse(existingData); const updatedObject = { key: key, data: { ...parsed.data, ...newData }, updated_at: Date.now(), }; sessionStorage.setItem(fullKey, JSON.stringify(updatedObject)); resolve("Data berhasil diupdate"); }); } async getLatestData() { return new Promise((resolve) => { let latestData = null; let latestTimestamp = 0; for (let i = 0; i < sessionStorage.length; i++) { const key = sessionStorage.key(i); if (key.startsWith(this.prefix)) { const data = JSON.parse(sessionStorage.getItem(key)); if (data.updated_at > latestTimestamp) { latestTimestamp = data.updated_at; latestData = data; } } } resolve(latestData); }); } } export class NexaStorage { constructor() { this.indexDB = new classIndexDB(); this.localStorage = new classLocalStorage(); this.cookies = new classCookies(); this.sessionStorage = new classSessionStorage(); } getIndexDB() { const db = this.indexDB; return { add: async function (row) { try { const key = row.key; const data = row.data; const timestamp = Date.now(); const hasil = await db.saveData(key, data, timestamp); const tersimpan = await db.getData(key); return tersimpan; } catch (error) { console.error("Error:", error); } }, get: async function (key) { try { const data = await db.getData(key); return data; } catch (error) { console.error("Error:", error); } }, ref: async function () { try { const allData = await db.getAllData(); return allData; } catch (error) { console.error("Error:", error); } }, up: async function (key, newData) { try { await db.updateData(key, newData); const updatedData = await db.getData(key); return updatedData; } catch (error) { console.error("Error:", error); } }, del: async function (key) { try { const result = await db.deleteData(key); return result; } catch (error) { console.error("Error:", error); } }, latest: async function () { try { const latestData = await db.getLatestData(); return latestData; } catch (error) { console.error("Error:", error); } }, }; } getLocalStorage() { const storage = this.localStorage; return { add: async function (row) { try { const key = row.key; const data = row.data; const timestamp = Date.now(); await storage.saveData(key, data, timestamp); const tersimpan = await storage.getData(key); return tersimpan; } catch (error) { console.error("Error:", error); } }, get: async function (key) { try { const data = await storage.getData(key); return data; } catch (error) { console.error("Error:", error); } }, ref: async function () { try { const allData = await storage.getAllData(); return allData; } catch (error) { console.error("Error:", error); } }, up: async function (key, newData) { try { await storage.updateData(key, newData); const updatedData = await storage.getData(key); return updatedData; } catch (error) { console.error("Error:", error); } }, del: async function (key) { try { const result = await storage.deleteData(key); return result; } catch (error) { console.error("Error:", error); } }, latest: async function () { try { const latestData = await storage.getLatestData(); return latestData; } catch (error) { console.error("Error:", error); } }, }; } getCookies() { const storage = this.cookies; return { add: async function (row, options = {}) { try { const key = row.key; const data = row.data; const timestamp = Date.now(); await storage.saveData(key, data, timestamp, options); const tersimpan = await storage.getData(key); return tersimpan; } catch (error) { console.error("Error:", error); } }, get: async function (key) { try { const data = await storage.getData(key); return data; } catch (error) { console.error("Error:", error); } }, ref: async function () { try { const allData = await storage.getAllData(); return allData; } catch (error) { console.error("Error:", error); } }, up: async function (key, newData, options = {}) { try { await storage.updateData(key, newData, options); const updatedData = await storage.getData(key); return updatedData; } catch (error) { console.error("Error:", error); } }, del: async function (key, options = {}) { try { const result = await storage.deleteData(key, options); return result; } catch (error) { console.error("Error:", error); } }, latest: async function () { try { const latestData = await storage.getLatestData(); return latestData; } catch (error) { console.error("Error:", error); } }, }; } getSessionStorage() { const storage = this.sessionStorage; return { add: async function (row) { try { const key = row.key; const data = row.data; const timestamp = Date.now(); await storage.saveData(key, data, timestamp); const tersimpan = await storage.getData(key); return tersimpan; } catch (error) { console.error("Error:", error); } }, get: async function (key) { try { const data = await storage.getData(key); return data; } catch (error) { console.error("Error:", error); } }, ref: async function () { try { const allData = await storage.getAllData(); return allData; } catch (error) { console.error("Error:", error); } }, up: async function (key, newData) { try { await storage.updateData(key, newData); const updatedData = await storage.getData(key); return updatedData; } catch (error) { console.error("Error:", error); } }, del: async function (key) { try { const result = await storage.deleteData(key); return result; } catch (error) { console.error("Error:", error); } }, latest: async function () { try { const latestData = await storage.getLatestData(); return latestData; } catch (error) { console.error("Error:", error); } }, }; } }