Skip to content

Instantly share code, notes, and snippets.

@oriSomething
Last active August 27, 2020 17:28
Show Gist options
  • Save oriSomething/3dfededc5db046a5a1c729908dcbf584 to your computer and use it in GitHub Desktop.
Save oriSomething/3dfededc5db046a5a1c729908dcbf584 to your computer and use it in GitHub Desktop.
ScopedStorage - Storage API with scope
export class ScopedStorage implements Storage {
[name: string]: any;
#storage: Storage;
#prefix: string;
constructor(storage: Storage, prefix: string) {
this.#storage = storage;
this.#prefix = prefix;
if (prefix === "") {
throw new Error("ScopedStoage - prefix is empty string, which make the usuage of ScopedStoage unneeded");
}
// We don't support `set` or `delete` because it always be buggy, and not really needed in reasonable usuage
return new Proxy(this, {
has(target, key) {
if (typeof key === "string") {
// Prefix key
if (target.getItem(prefix + key) != null) return true;
// If key exist as item it means it's unprefixed key and so we should ignore it
return target.getItem(key) == null;
}
return Reflect.has(target, key);
},
get(target, key, receiver) {
if (typeof key === "string") {
// Prefix key
if (target.getItem(prefix + key) != null) return target.getItem(prefix + key);
// If key exist as item it means it's unprefixed key and so we should ignore it
if (target.getItem(key) != null) return undefined;
}
return Reflect.get(target, key, receiver);
},
ownKeys(target) {
const keys = [];
for (let key of Reflect.ownKeys(target)) {
if (typeof key === "string") {
if (key.startsWith(prefix)) {
keys.push(key.substring(prefix.length));
continue;
}
// If key exist as item it means it's unprefixed key and so we should ignore it
if (target.getItem(key) != null) continue;
}
keys.push(key);
}
return keys;
},
});
}
get length(): number {
let count = 0;
for (let key of Object.keys(this.#storage)) {
if (key.startsWith(this.#prefix)) count++;
}
return count;
}
clear(): void {
let keys = [];
for (let key of Object.keys(this.#storage)) {
if (key.startsWith(this.#prefix)) {
keys.push(key);
}
}
for (let key of keys) {
this.#storage.removeItem(key);
}
}
getItem(key: string): string | null {
return this.#storage.getItem(this.#prefix + key);
}
key(index: number): string | null {
let count = 0;
for (let key of Object.keys(this.#storage)) {
if (key.startsWith(this.#prefix)) {
if (count === index) {
return this.#storage.getItem(key);
}
count++;
}
}
return null;
}
removeItem(key: string): void {
this.#storage.removeItem(this.#prefix + key);
}
setItem(key: string, value: string): void {
this.#storage.setItem(this.#prefix + key, value);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment