recoil-sync-next
Version:
recoil-sync stores for Next.js
68 lines (67 loc) • 3.07 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.useSyncHistory = void 0;
const react_1 = require("react");
const recoil_1 = require("recoil");
function useSyncHistory({ storeKey, getHistoryKey, saveItems, loadItems, listenChangeHistory, }) {
var _a;
const historyInfo = (0, react_1.useRef)();
// set current historyInfo by navigation
const historyKey = getHistoryKey();
if (historyKey && historyKey !== ((_a = historyInfo.current) === null || _a === void 0 ? void 0 : _a.historyKey)) {
historyInfo.current = { historyKey, historyItems: {} };
}
const read = (0, react_1.useCallback)((itemKey) => {
var _a;
if (!historyInfo.current) {
return new recoil_1.DefaultValue();
}
const { historyItems } = historyInfo.current;
return (_a = historyItems[itemKey]) !== null && _a !== void 0 ? _a : new recoil_1.DefaultValue();
}, []);
const write = (0, react_1.useCallback)(({ diff }) => {
var _a;
const historyKey = getHistoryKey();
assertString(historyKey);
(_a = historyInfo.current) !== null && _a !== void 0 ? _a : (historyInfo.current = { historyKey, historyItems: {} });
const { historyItems } = historyInfo.current;
for (const [itemKey, itemValue] of diff) {
historyItems[itemKey] = itemValue;
}
}, [getHistoryKey]);
const listen = (0, react_1.useCallback)(({ updateAllKnownItems }) => {
return listenChangeHistory((url) => {
var _a, _b;
// saving previouse history associated items.
if (historyInfo.current) {
const { historyKey, historyItems } = historyInfo.current;
saveItems(historyKey, historyItems);
}
const historyKey = getHistoryKey();
assertString(historyKey);
// history has changed by navigation.
if (historyKey === ((_a = historyInfo.current) === null || _a === void 0 ? void 0 : _a.historyKey)) {
// nothing to do if URL wasn't changed.
if (url === ((_b = globalThis.location) === null || _b === void 0 ? void 0 : _b.pathname)) {
return;
}
// clear history associated items from Recoil store.
historyInfo.current = undefined;
updateAllKnownItems(new Map());
return;
}
// history has changed by forward/backward.
// loading next history associated items from SessionStorage.
const historyItems = loadItems(historyKey);
historyInfo.current = { historyKey, historyItems };
updateAllKnownItems(new Map(Object.entries(historyItems)));
});
}, [getHistoryKey, saveItems, loadItems, listenChangeHistory]);
return { storeKey, read, write, listen };
}
exports.useSyncHistory = useSyncHistory;
function assertString(s) {
if (typeof s !== 'string') {
throw new Error(`${s} must be string`);
}
}