Skip to content

Commit b3c5268

Browse files
committed
feat: compression for web ui local storage
1 parent 03a44d8 commit b3c5268

File tree

1 file changed

+46
-2
lines changed

1 file changed

+46
-2
lines changed

examples/server/webui/src/main.js

Lines changed: 46 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,11 @@ import daisyuiThemes from 'daisyui/src/theming/themes';
1515
// ponyfill for missing ReadableStream asyncIterator on Safari
1616
import { asyncIterator } from '@sec-ant/readable-stream/ponyfill/asyncIterator';
1717

18-
const isDev = import.meta.env.MODE === 'development';
18+
// compression library
19+
import pako from "pako";
20+
21+
const isDev = import.meta.env.MODE === "development";
22+
const useCompression = true; // set to true if you want to use gzip compression for local storage
1923

2024
// utility functions
2125
const isString = (x) => !!x.toLowerCase;
@@ -38,6 +42,45 @@ const copyStr = (textToCopy) => {
3842
document.execCommand('copy');
3943
}
4044
};
45+
const compressedStorage = {
46+
getItem(key) {
47+
const compressed = window.localStorage.getItem(key);
48+
try {
49+
const bytes = Uint8Array.from(atob(compressed), (c) => c.charCodeAt(0));
50+
return new TextDecoder().decode(this.decompress(bytes));
51+
} catch (error) {
52+
return compressed;
53+
}
54+
},
55+
setItem(key, value) {
56+
const compressed = this.compress(new TextEncoder().encode(value));
57+
const compressedHex = btoa(this.uintToString(compressed));
58+
window.localStorage.setItem(key, compressedHex);
59+
},
60+
removeItem: (key) => window.localStorage.removeItem(key),
61+
clear: () => window.localStorage.clear(),
62+
key: (index) => window.localStorage.key(index),
63+
length: window.localStorage.length,
64+
[Symbol.iterator]: function* () {
65+
for (let i = 0; i < window.localStorage.length; i++) {
66+
yield window.localStorage.key(i);
67+
}
68+
},
69+
uintToString(bytes) {
70+
const chunkSize = 0x8000;
71+
let result = "";
72+
for (let i = 0; i < bytes.length; i += chunkSize) {
73+
result += String.fromCharCode.apply(
74+
null,
75+
bytes.subarray(i, i + chunkSize)
76+
);
77+
}
78+
return result;
79+
},
80+
compress: (encoded) => pako.gzip(encoded, { level: 9 }),
81+
decompress: (bytes) => pako.ungzip(bytes),
82+
};
83+
const localStorage = useCompression ? compressedStorage : window.localStorage;
4184

4285
// constants
4386
const BASE_URL = isDev
@@ -211,7 +254,8 @@ const StorageUtils = {
211254
// manage conversations
212255
getAllConversations() {
213256
const res = [];
214-
for (const key in localStorage) {
257+
const storage = useCompression ? localStorage : Object.keys(localStorage);
258+
for (const key of storage) {
215259
if (key.startsWith('conv-')) {
216260
res.push(JSON.parse(localStorage.getItem(key)));
217261
}

0 commit comments

Comments
 (0)