jotai-location
Version:
82 lines (81 loc) • 3.39 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.setHashWithReplace = exports.setHashWithPush = void 0;
exports.atomWithHash = atomWithHash;
const vanilla_1 = require("jotai/vanilla");
const utils_1 = require("jotai/vanilla/utils");
const safeJSONParse = (initialValue) => (str) => {
try {
return JSON.parse(str);
}
catch (_a) {
return initialValue;
}
};
const setHashWithPush = (searchParams) => {
const newUrl = `${window.location.pathname}${window.location.search}${searchParams ? `#${searchParams}` : ''}`;
window.history.pushState(window.history.state, '', newUrl);
};
exports.setHashWithPush = setHashWithPush;
const setHashWithReplace = (searchParams) => {
const newUrl = `${window.location.pathname}${window.location.search}${searchParams ? `#${searchParams}` : ''}`;
window.history.replaceState(window.history.state, '', newUrl);
};
exports.setHashWithReplace = setHashWithReplace;
function getSetHashFn(setHashOption) {
if (setHashOption === 'replaceState') {
return exports.setHashWithReplace;
}
if (typeof setHashOption === 'function') {
return setHashOption;
}
return exports.setHashWithPush;
}
function atomWithHash(key, initialValue, options) {
const serialize = (options === null || options === void 0 ? void 0 : options.serialize) || JSON.stringify;
const deserialize = (options === null || options === void 0 ? void 0 : options.deserialize) || safeJSONParse(initialValue);
const subscribe = (options === null || options === void 0 ? void 0 : options.subscribe) ||
((callback) => {
window.addEventListener('hashchange', callback);
return () => {
window.removeEventListener('hashchange', callback);
};
});
const isLocationAvailable = typeof window !== 'undefined' && !!window.location;
const strAtom = (0, vanilla_1.atom)(isLocationAvailable
? new URLSearchParams(window.location.hash.slice(1)).get(key)
: null);
strAtom.onMount = (setAtom) => {
if (!isLocationAvailable) {
return undefined;
}
const callback = () => {
setAtom(new URLSearchParams(window.location.hash.slice(1)).get(key));
};
const unsubscribe = subscribe(callback);
callback();
return unsubscribe;
};
const valueAtom = (0, vanilla_1.atom)((get) => {
const str = get(strAtom);
return str === null ? initialValue : deserialize(str);
});
return (0, vanilla_1.atom)((get) => get(valueAtom), (get, set, update, setOptions) => {
var _a;
const nextValue = typeof update === 'function'
? update(get(valueAtom))
: update;
const searchParams = new URLSearchParams(window.location.hash.slice(1));
if (nextValue === utils_1.RESET) {
set(strAtom, null);
searchParams.delete(key);
}
else {
const str = serialize(nextValue);
set(strAtom, str);
searchParams.set(key, str);
}
const setHash = getSetHashFn((_a = setOptions === null || setOptions === void 0 ? void 0 : setOptions.setHash) !== null && _a !== void 0 ? _a : options === null || options === void 0 ? void 0 : options.setHash);
setHash(searchParams.toString());
});
}