nitropage
Version:
A free and open source, extensible visual page builder based on SolidStart.
76 lines (63 loc) • 1.73 kB
text/typescript
import { produce, reconcile, SetStoreFunction } from "solid-js/store";
import { Element, State } from "../../../../types";
export const prepareElementsForReconcile = (
draft: Record<string, Element>,
nextElements: Record<string, Element>,
) => {
let prevIds = Object.keys(draft);
let nextIds = Object.keys(nextElements);
for (const prevId of prevIds) {
if (nextElements[prevId]) {
nextIds.splice(nextIds.indexOf(prevId), 1);
}
const historyId = draft[prevId].historyId;
if (!historyId) continue;
let nextId: string | undefined = undefined;
let idx = 0;
for (const id of nextIds) {
if (nextElements[id].historyId !== historyId) {
idx++;
continue;
}
nextId = id;
break;
}
if (!nextId) {
continue;
}
nextIds.splice(idx, 1);
draft[nextId] = draft[prevId];
}
};
export const makeStateReconciler = (
state: State,
setState: SetStoreFunction<State>,
) => {
const reconcileElementIds = (nextState: Partial<State>) => {
const prevDate = state.normalizationDate;
const nextDate = nextState.normalizationDate;
if (
prevDate == null ||
nextDate == null ||
new Date(prevDate).getTime() >= new Date(nextDate).getTime()
) {
return;
}
setState(
produce((d) => {
prepareElementsForReconcile(d.elements, nextState.elements!);
}),
);
};
return (nextState: Partial<State>) => {
for (const k of Object.keys(nextState)) {
if (k === "elements") {
reconcileElementIds(nextState);
}
setState(
k as keyof State,
reconcile(nextState[k as keyof State], { key: null, merge: true }),
);
}
};
};