Skip to content

Instantly share code, notes, and snippets.

@davidglezz
Created June 30, 2024 18:16
Show Gist options
  • Save davidglezz/19351f5ece2b51b3e1efecbe519c9e03 to your computer and use it in GitHub Desktop.
Save davidglezz/19351f5ece2b51b3e1efecbe519c9e03 to your computer and use it in GitHub Desktop.
/**
* A class for storing and retrieve compressed objects into local storage.
*/
export class CompressedStorage {
async get(key: string) {
const base64 = localStorage.getItem(key);
if (base64 === null) {
return null;
}
const blob = await this.fromBase64Url(base64);
const decompressed = await this.decompress(blob);
return this.fromJsonBlob(decompressed);
}
async set(key: string, value: any) {
const blob = this.toJsonBlob(value);
const compressed = await this.compress(blob);
const base64 = await this.toBase64Url(compressed);
localStorage.setItem(key, base64);
}
private toBase64Url(blob: Blob): Promise<string> {
return new Promise(resolve => {
const reader = new FileReader();
reader.onload = () => resolve(reader.result as string);
reader.readAsDataURL(blob);
});
}
private async fromBase64Url(base64: string): Promise<Blob> {
const response = await fetch(base64);
return response.blob();
}
private toJsonBlob(data: any) {
return new Blob([JSON.stringify(data)], { type: 'application/json' });
}
private async fromJsonBlob(data: Blob): Promise<string> {
return JSON.parse(await data.text());
}
private compress(data: Blob): Promise<Blob> {
const compressedStream = data.stream().pipeThrough(new CompressionStream('gzip'));
const compressedResponse = new Response(compressedStream);
return compressedResponse.blob();
}
private decompress(data: Blob): Promise<Blob> {
const uncompressedStream = data.stream().pipeThrough(new DecompressionStream('gzip'));
const uncompressedResponse = new Response(uncompressedStream);
return uncompressedResponse.blob();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment