From cbf5ddec1c0400f49a70702814babd406de687c5 Mon Sep 17 00:00:00 2001 From: Rune Harlyk Date: Tue, 1 Aug 2023 03:08:42 +0200 Subject: [PATCH] =?UTF-8?q?=F0=9F=93=BC=20Updates=20reponse=20cache=20to?= =?UTF-8?q?=20use=20indexedDB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/App.svelte | 14 ++- app/src/components/Model/ModelView.svelte | 9 +- app/src/lib/cache.ts | 102 ++++++++++++++++++++++ 3 files changed, 118 insertions(+), 7 deletions(-) create mode 100644 app/src/lib/cache.ts diff --git a/app/src/App.svelte b/app/src/App.svelte index 34de4a2..0de1362 100644 --- a/app/src/App.svelte +++ b/app/src/App.svelte @@ -8,6 +8,7 @@ import Health from './routes/SystemHealth.svelte'; import location from './lib/location'; import Sidebar from './components/Sidebar.svelte'; + import FileCache from './lib/cache'; export let url = window.location.pathname; onMount(() => { @@ -18,9 +19,18 @@ const registerFetchIntercept = () => { const { fetch: originalFetch } = window; window.fetch = async (...args) => { - const cache = await caches.open("files") const [resource, config] = args; - return await cache.match(resource) ?? originalFetch(resource, config) + await FileCache.openDatabase(); + let file; + try { + file = await FileCache.getFile(resource.url); + } catch (error) { + console.log(error); + } + + return file + ? new Response(file) + : originalFetch(resource, config) }; } diff --git a/app/src/components/Model/ModelView.svelte b/app/src/components/Model/ModelView.svelte index 18446d7..8e9bafe 100644 --- a/app/src/components/Model/ModelView.svelte +++ b/app/src/components/Model/ModelView.svelte @@ -29,6 +29,7 @@ import uzip from 'uzip'; import { outControllerData } from '../../lib/store'; import Kinematic from '../../lib/kinematic'; import location from '../../lib/location'; +import FileCache from '../../lib/cache'; let canvas: HTMLCanvasElement, streamCanvas: HTMLCanvasElement, stream: HTMLImageElement, scene: Scene, camera: Camera, renderer: WebGLRenderer, controls: OrbitControls, robot, isLoaded = false; @@ -124,17 +125,15 @@ onMount(async () => { }); const cacheModelFiles = async () => { - const cacheKey = "files" - const cache = await caches.open(cacheKey) - let data = await fetch("/stl.zip").then(data => data.arrayBuffer()) var files = uzip.parse(data); + await FileCache.openDatabase() for(const [path, data] of Object.entries(files) as [path:string, data:Uint8Array][]){ const url = new URL(path, window.location.href) - cache.put(url, new Response(data)); - } + FileCache.saveFile(url.toString(), data) + } } const loadModel = () => { diff --git a/app/src/lib/cache.ts b/app/src/lib/cache.ts new file mode 100644 index 0000000..e298621 --- /dev/null +++ b/app/src/lib/cache.ts @@ -0,0 +1,102 @@ +class FileCache { + private request: IDBOpenDBRequest; + private db: IDBDatabase | null = null; + private store: IDBObjectStore | null = null; + + dbName = 'fileStorageDB'; + dbVersion = 1; + storeName = 'files'; + constructor() { + this.request = indexedDB.open(this.dbName, this.dbVersion); + this.request.onerror = (event) => { + console.error("An error occurred with IndexedDB", event); + }; + + this.request.onupgradeneeded = () => { + this.db = this.request.result; + this.store = this.db.createObjectStore(this.storeName); + }; + + this.request.onsuccess = () => { + this.db = this.request.result; + const transaction = this.db.transaction(this.storeName, "readwrite"); + this.store = transaction.objectStore(this.storeName); + } + } + + public isOpen(): boolean { + return this.db !== null; + } + + public async saveFile(key:string, file: Uint8Array): Promise { + return new Promise((resolve, reject) => { + if(!this.db) { + reject("Database not open") + return; + } + const transaction = this.db.transaction(this.storeName, "readwrite"); + const store = transaction.objectStore(this.storeName); + const request = store.put(file, key); + if(!request) { + reject("Request not created") + return + } + request.onsuccess = () => { + resolve(request.result); + }; + request.onerror = () => { + reject(request.error); + }; + }); + } + + public async getFile(key:string): Promise { + return new Promise((resolve, reject) => { + if(!key) { + reject("Key was not defined") + return; + } + if(!this.db) { + reject("Database not open") + return; + } + const transaction = this.db.transaction(this.storeName, "readwrite"); + const store = transaction.objectStore(this.storeName); + + const request = store.get(key); + if(!request) { + reject("Request not created") + return + } + request.onsuccess = () => { + resolve(request.result); + }; + request.onerror = () => { + reject(request.error); + }; + }); + } + + public async openDatabase(): Promise { + return new Promise((resolve, reject) => { + const request = indexedDB.open(this.dbName, this.dbVersion); + + request.onerror = (event) => { + reject('Error opening database'); + }; + + request.onsuccess = (event) => { + const db = event.target?.result; + this.db = db; + resolve(db); + }; + + request.onupgradeneeded = (event) => { + this.db = event.target?.result; + this.db?.createObjectStore('files', { autoIncrement: true }); + }; + }); + } +} + +export default new FileCache(); \ No newline at end of file