mirror of
https://github.com/SPLURT-Station/S.P.L.U.R.T-Station-13.git
synced 2025-12-11 10:22:13 +00:00
tguichat and tgui4.1?
This commit is contained in:
@@ -6,71 +6,152 @@
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
export const STORAGE_NONE = 0;
|
||||
export const STORAGE_LOCAL_STORAGE = 1;
|
||||
export const STORAGE_INDEXED_DB = 2;
|
||||
export const IMPL_MEMORY = 0;
|
||||
export const IMPL_LOCAL_STORAGE = 1;
|
||||
export const IMPL_INDEXED_DB = 2;
|
||||
|
||||
const createMock = () => {
|
||||
let storage = {};
|
||||
const get = key => storage[key];
|
||||
const set = (key, value) => {
|
||||
storage[key] = value;
|
||||
};
|
||||
const remove = key => {
|
||||
storage[key] = undefined;
|
||||
};
|
||||
const clear = () => {
|
||||
// NOTE: On IE8, this will probably leak memory if used often.
|
||||
storage = {};
|
||||
};
|
||||
return {
|
||||
get,
|
||||
set,
|
||||
remove,
|
||||
clear,
|
||||
engine: STORAGE_NONE,
|
||||
};
|
||||
};
|
||||
const INDEXED_DB_VERSION = 1;
|
||||
const INDEXED_DB_NAME = 'tgui';
|
||||
const INDEXED_DB_STORE_NAME = 'storage-v1';
|
||||
|
||||
const createLocalStorage = () => {
|
||||
const get = key => {
|
||||
const value = localStorage.getItem(key);
|
||||
if (typeof value !== 'string') {
|
||||
return;
|
||||
}
|
||||
return JSON.parse(value);
|
||||
};
|
||||
const set = (key, value) => {
|
||||
localStorage.setItem(key, JSON.stringify(value));
|
||||
};
|
||||
const remove = key => {
|
||||
localStorage.removeItem(key);
|
||||
};
|
||||
const clear = () => {
|
||||
localStorage.clear();
|
||||
};
|
||||
return {
|
||||
get,
|
||||
set,
|
||||
remove,
|
||||
clear,
|
||||
engine: STORAGE_LOCAL_STORAGE,
|
||||
};
|
||||
};
|
||||
const READ_ONLY = 'readonly';
|
||||
const READ_WRITE = 'readwrite';
|
||||
|
||||
const testLocalStorage = () => {
|
||||
// Localstorage can sometimes throw an error, even if DOM storage is not
|
||||
// disabled in IE11 settings.
|
||||
// See: https://superuser.com/questions/1080011
|
||||
const testGeneric = testFn => () => {
|
||||
try {
|
||||
return Boolean(window.localStorage && window.localStorage.getItem);
|
||||
return Boolean(testFn());
|
||||
}
|
||||
catch {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
// Localstorage can sometimes throw an error, even if DOM storage is not
|
||||
// disabled in IE11 settings.
|
||||
// See: https://superuser.com/questions/1080011
|
||||
const testLocalStorage = testGeneric(() => (
|
||||
window.localStorage && window.localStorage.getItem
|
||||
));
|
||||
|
||||
const testIndexedDb = testGeneric(() => (
|
||||
(window.indexedDB || window.msIndexedDB)
|
||||
&& (window.IDBTransaction || window.msIDBTransaction)
|
||||
));
|
||||
|
||||
class MemoryBackend {
|
||||
constructor() {
|
||||
this.impl = IMPL_MEMORY;
|
||||
this.store = {};
|
||||
}
|
||||
|
||||
async get(key) {
|
||||
return this.store[key];
|
||||
}
|
||||
|
||||
async set(key, value) {
|
||||
this.store[key] = value;
|
||||
}
|
||||
|
||||
async remove(key) {
|
||||
this.store[key] = undefined;
|
||||
}
|
||||
|
||||
async clear() {
|
||||
this.store = {};
|
||||
}
|
||||
}
|
||||
|
||||
class LocalStorageBackend {
|
||||
constructor() {
|
||||
this.impl = IMPL_LOCAL_STORAGE;
|
||||
this.store = {};
|
||||
}
|
||||
|
||||
async get(key) {
|
||||
const value = localStorage.getItem(key);
|
||||
if (typeof value === 'string') {
|
||||
return JSON.parse(value);
|
||||
}
|
||||
}
|
||||
|
||||
async set(key, value) {
|
||||
localStorage.setItem(key, JSON.stringify(value));
|
||||
}
|
||||
|
||||
async remove(key) {
|
||||
localStorage.removeItem(key);
|
||||
}
|
||||
|
||||
async clear() {
|
||||
localStorage.clear();
|
||||
}
|
||||
}
|
||||
|
||||
class IndexedDbBackend {
|
||||
constructor() {
|
||||
this.impl = IMPL_INDEXED_DB;
|
||||
/** @type {Promise<IDBDatabase>} */
|
||||
this.dbPromise = new Promise((resolve, reject) => {
|
||||
const indexedDB = window.indexedDB || window.msIndexedDB;
|
||||
const req = indexedDB.open(INDEXED_DB_NAME, INDEXED_DB_VERSION);
|
||||
req.onupgradeneeded = () => {
|
||||
try {
|
||||
req.result.createObjectStore(INDEXED_DB_STORE_NAME);
|
||||
}
|
||||
catch (err) {
|
||||
reject(new Error('Failed to upgrade IDB: ' + req.error));
|
||||
}
|
||||
};
|
||||
req.onsuccess = () => resolve(req.result);
|
||||
req.onerror = () => {
|
||||
reject(new Error('Failed to open IDB: ' + req.error));
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
getStore(mode) {
|
||||
return this.dbPromise.then(db => db
|
||||
.transaction(INDEXED_DB_STORE_NAME, mode)
|
||||
.objectStore(INDEXED_DB_STORE_NAME));
|
||||
}
|
||||
|
||||
async get(key) {
|
||||
const store = await this.getStore(READ_ONLY);
|
||||
return new Promise((resolve, reject) => {
|
||||
const req = store.get(key);
|
||||
req.onsuccess = () => resolve(req.result);
|
||||
req.onerror = () => reject(req.error);
|
||||
});
|
||||
}
|
||||
|
||||
async set(key, value) {
|
||||
// The reason we don't _save_ null is because IE 10 does
|
||||
// not support saving the `null` type in IndexedDB. How
|
||||
// ironic, given the bug below!
|
||||
// See: https://github.com/mozilla/localForage/issues/161
|
||||
if (value === null) {
|
||||
value = undefined;
|
||||
}
|
||||
// NOTE: We deliberately make this operation transactionless
|
||||
const store = await this.getStore(READ_WRITE);
|
||||
store.put(value, key);
|
||||
}
|
||||
|
||||
async remove(key) {
|
||||
// NOTE: We deliberately make this operation transactionless
|
||||
const store = await this.getStore(READ_WRITE);
|
||||
store.delete(key);
|
||||
}
|
||||
|
||||
async clear() {
|
||||
// NOTE: We deliberately make this operation transactionless
|
||||
const store = await this.getStore(READ_WRITE);
|
||||
store.clear();
|
||||
}
|
||||
}
|
||||
|
||||
export const storage = (
|
||||
testLocalStorage() && createLocalStorage()
|
||||
|| createMock()
|
||||
testIndexedDb() && new IndexedDbBackend()
|
||||
|| testLocalStorage() && new LocalStorageBackend()
|
||||
|| new MemoryBackend()
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user