🪖 Moves filecache to own service
This commit is contained in:
+10
-15
@@ -2,13 +2,14 @@
|
|||||||
import { Router, Route } from 'svelte-routing';
|
import { Router, Route } from 'svelte-routing';
|
||||||
import { onMount } from 'svelte';
|
import { onMount } from 'svelte';
|
||||||
import TopBar from './components/TopBar.svelte';
|
import TopBar from './components/TopBar.svelte';
|
||||||
import { connect } from './lib/socket';
|
import { connect } from '$lib/socket';
|
||||||
import Controller from './routes/Controller.svelte';
|
import Controller from './routes/Controller.svelte';
|
||||||
import FileCache from './lib/cache';
|
import FileService from '$lib/services/file-service';
|
||||||
import { socketLocation } from './lib/location';
|
import { socketLocation } from '$lib/location';
|
||||||
import Settings from './routes/Settings.svelte';
|
import Settings from './routes/Settings.svelte';
|
||||||
import { jointNames, model } from './lib/store';
|
import { jointNames, model } from '$lib/store';
|
||||||
import { loadModelAsync } from './lib/modelLoader';
|
import { loadModelAsync } from '$lib/utilities';
|
||||||
|
import type { Result } from '$lib/utilities/result';
|
||||||
|
|
||||||
export let url = window.location.pathname
|
export let url = window.location.pathname
|
||||||
onMount(async () => {
|
onMount(async () => {
|
||||||
@@ -23,16 +24,10 @@
|
|||||||
const { fetch: originalFetch } = window;
|
const { fetch: originalFetch } = window;
|
||||||
window.fetch = async (...args) => {
|
window.fetch = async (...args) => {
|
||||||
const [resource, config] = args;
|
const [resource, config] = args;
|
||||||
await FileCache.openDatabase();
|
let file: Result<Uint8Array | undefined, string>;
|
||||||
let file: BodyInit | Uint8Array | undefined | null;
|
file = await FileService.getFile(resource.toString());
|
||||||
try {
|
return file.isOk()
|
||||||
file = await FileCache.getFile(resource.toString());
|
? new Response(file.inner)
|
||||||
} catch (error) {
|
|
||||||
console.log(error);
|
|
||||||
}
|
|
||||||
|
|
||||||
return file
|
|
||||||
? new Response(file)
|
|
||||||
: originalFetch(resource, config)
|
: originalFetch(resource, config)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import uzip from 'uzip';
|
|||||||
import { model, outControllerData } from '$lib/store';
|
import { model, outControllerData } from '$lib/store';
|
||||||
import { ForwardKinematics } from '$lib/kinematic';
|
import { ForwardKinematics } from '$lib/kinematic';
|
||||||
import location from '$lib/location';
|
import location from '$lib/location';
|
||||||
import FileCache from '$lib/cache';
|
import FileService from '$lib/services/file-service';
|
||||||
import SceneBuilder from '$lib/sceneBuilder';
|
import SceneBuilder from '$lib/sceneBuilder';
|
||||||
|
|
||||||
let sceneManager:SceneBuilder
|
let sceneManager:SceneBuilder
|
||||||
@@ -59,11 +59,11 @@ const cacheModelFiles = async () => {
|
|||||||
let data = await fetch("/stl.zip").then(data => data.arrayBuffer())
|
let data = await fetch("/stl.zip").then(data => data.arrayBuffer())
|
||||||
|
|
||||||
var files = uzip.parse(data);
|
var files = uzip.parse(data);
|
||||||
await FileCache.openDatabase()
|
await FileService.openDatabase()
|
||||||
|
|
||||||
for(const [path, data] of Object.entries(files) as [path:string, data:Uint8Array][]){
|
for(const [path, data] of Object.entries(files) as [path:string, data:Uint8Array][]){
|
||||||
const url = new URL(path, window.location.href)
|
const url = new URL(path, window.location.href)
|
||||||
FileCache.saveFile(url.toString(), data)
|
FileService.saveFile(url.toString(), data)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,102 +0,0 @@
|
|||||||
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<string | IDBValidKey> {
|
|
||||||
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<Uint8Array | null> {
|
|
||||||
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<IDBDatabase> {
|
|
||||||
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();
|
|
||||||
@@ -0,0 +1,72 @@
|
|||||||
|
import { Result } from '$lib/utilities/result';
|
||||||
|
|
||||||
|
class FileService {
|
||||||
|
private dbName = 'fileStorageDB';
|
||||||
|
private dbVersion = 1;
|
||||||
|
private storeName = 'files';
|
||||||
|
private dbPromise: Promise<Result<IDBDatabase, string>>;
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
this.dbPromise = this.openDatabase();
|
||||||
|
}
|
||||||
|
|
||||||
|
private async openDatabase(): Promise<Result<IDBDatabase, string>> {
|
||||||
|
return new Promise((resolve) => {
|
||||||
|
const request = indexedDB.open(this.dbName, this.dbVersion);
|
||||||
|
|
||||||
|
request.onerror = () => resolve(Result.err("Error opening database"));
|
||||||
|
|
||||||
|
request.onsuccess = () => resolve(Result.ok(request.result));
|
||||||
|
|
||||||
|
request.onupgradeneeded = (event) => {
|
||||||
|
const db = request.result;
|
||||||
|
if (!db.objectStoreNames.contains(this.storeName)) {
|
||||||
|
db.createObjectStore(this.storeName);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private async getStore(mode: IDBTransactionMode): Promise<Result<IDBObjectStore, string>> {
|
||||||
|
const dbResult = await this.dbPromise;
|
||||||
|
if (dbResult.isErr()) {
|
||||||
|
return Result.err("Database not initialized properly");
|
||||||
|
}
|
||||||
|
const db = dbResult.inner;
|
||||||
|
const transaction = db.transaction(this.storeName, mode);
|
||||||
|
return Result.ok(transaction.objectStore(this.storeName));
|
||||||
|
}
|
||||||
|
|
||||||
|
public async saveFile(key: string, file: Uint8Array): Promise<Result<IDBValidKey, string>> {
|
||||||
|
const storeResult = await this.getStore("readwrite");
|
||||||
|
if (storeResult.isErr()) {
|
||||||
|
return Result.err("Failed to access object store for writing");
|
||||||
|
}
|
||||||
|
const store = storeResult.inner;
|
||||||
|
|
||||||
|
return new Promise((resolve) => {
|
||||||
|
const request = store.put(file, key);
|
||||||
|
request.onsuccess = () => resolve(Result.ok(request.result));
|
||||||
|
request.onerror = () => resolve(Result.err("Failed to save file"));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public async getFile(key: string): Promise<Result<Uint8Array | undefined, string>> {
|
||||||
|
const storeResult = await this.getStore("readonly");
|
||||||
|
if (storeResult.isErr()) {
|
||||||
|
return Result.err("Failed to access object store for reading");
|
||||||
|
}
|
||||||
|
const store = storeResult.inner;
|
||||||
|
|
||||||
|
return new Promise((resolve) => {
|
||||||
|
const request = store.get(key);
|
||||||
|
|
||||||
|
request.onsuccess = () =>
|
||||||
|
resolve(request.result ? Result.ok(request.result) : Result.err("File content not found"))
|
||||||
|
request.onerror = () =>
|
||||||
|
resolve(Result.err("Failed to retrieve file"));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default new FileService();
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
export * from './file-service'
|
||||||
Reference in New Issue
Block a user