@smkit/ui
Version:
UI Kit of SberMarketing
132 lines (131 loc) • 4.09 kB
JavaScript
import { get, derived, writable } from 'svelte/store';
import { isBrowser } from '../utils';
export const searchTerm = writable('');
export function cachedDerived(stores, callback, settings) {
let oldValue;
let timeout;
const store = derived(stores, ($stores, set, update) => {
if (JSON.stringify(oldValue) === JSON.stringify($stores))
return;
oldValue = structuredClone($stores);
if (settings?.delay) {
clearTimeout(timeout);
timeout = setTimeout(async () => {
callback($stores, set, update);
}, settings.delay);
}
else {
callback($stores, set, update);
}
});
return store;
}
export function storable(data, storeKey) {
const store = writable(data);
const { subscribe, set } = store;
isBrowser &&
localStorage[`storable_${storeKey}`] &&
set(JSON.parse(localStorage[`storable_${storeKey}`]));
return {
subscribe,
set: (n) => {
isBrowser && (localStorage[`storable_${storeKey}`] = JSON.stringify(n));
set(n);
},
update: (cb) => {
const updatedStore = cb(get(store));
isBrowser && (localStorage[`storable_${storeKey}`] = JSON.stringify(updatedStore));
set(updatedStore);
}
};
}
export function overridable(store, onChange) {
const update = (updater, sideEffect) => {
store.update((curr) => {
const next = updater(curr);
let res = next;
if (onChange) {
res = onChange({ curr, next });
}
sideEffect && sideEffect(next);
return res;
});
};
const set = (curr) => {
update(() => curr);
};
return {
...store,
update,
set
};
}
export function debouncedWritable(baseValue, delay) {
const { subscribe, set, update } = writable(baseValue);
let timeout;
function delayedSet(newValue) {
clearTimeout(timeout);
timeout = setTimeout(() => {
set(newValue);
}, delay || 100);
}
return { set: delayedSet, subscribe, update };
}
export function urlParamsWritable(value, key = 'saved', compress = false, delay = 100) {
const getSearchParams = (field, url) => {
let decoded = null;
try {
decoded = url.searchParams.get(field);
if (!decoded)
return null;
decoded = decodeURIComponent(decoded);
if (compress) {
decoded = unzipurl(decoded);
}
if (typeof value === 'object') {
decoded = JSON.parse(decoded);
}
}
catch (e) {
console.error(`Unexpected searchParams value for ${field}: ${e}`);
}
return decoded;
};
const encodeJSON = (data) => {
if (compress) {
return zipurl(JSON.stringify(data));
}
return JSON.stringify(data);
};
const updateSearchParams = (kv) => {
if (!isBrowser || !window)
return;
const url = new URL(window.location.toString());
if (!url)
return;
for (const [k, v] of Object.entries(kv)) {
if (v) {
const encodedValue = typeof value === 'object' ? encodeJSON(v) : v.toString();
url.searchParams.set(encodeURIComponent(k), encodeURIComponent(encodedValue));
}
else {
url.searchParams.delete(k);
}
}
history.pushState({}, `updated ${key}`, url);
};
const saved = isBrowser ? getSearchParams(key, new URL(location.href)) || value : value;
const store = writable(saved);
let timeout;
store.subscribe((v) => {
if (!delay) {
updateSearchParams({ [key]: v });
return;
}
clearTimeout(timeout);
timeout = setTimeout(() => {
updateSearchParams({ [key]: v });
}, delay);
});
return store;
}