Skip to content

Commit

Permalink
refactor: migrate resolveData to app store
Browse files Browse the repository at this point in the history
  • Loading branch information
chrisvxd committed Feb 19, 2025
1 parent 22cee89 commit f261725
Show file tree
Hide file tree
Showing 4 changed files with 90 additions and 73 deletions.
18 changes: 9 additions & 9 deletions packages/core/components/Puck/components/Fields/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -88,17 +88,17 @@ export const Fields = ({ wrapFields = true }: { wrapFields?: boolean }) => {
const dispatch = useAppStore((s) => s.dispatch);
const config = useAppStore((s) => s.config);
const overrides = useAppStore((s) => s.overrides);
// const thisComponentState = useAppStore((s) =>
// s.selectedItem
// ? s.componentState[s.selectedItem.props.id]
// : s.componentState["puck-root"]
// );
const resolveData = (d: any) => {}; //useAppStore((s) => s.resolveData);
// const itemSelector = useAppStore(useShallow((s) => s.state.ui.itemSelector));
const thisComponentState = useAppStore((s) =>
s.selectedItem
? s.componentState[s.selectedItem.props.id]
: s.componentState["puck-root"]
);
const resolveData = useAppStore((s) => s.resolveData);
const itemSelector = useAppStore(useShallow((s) => s.state.ui.itemSelector));

const [fields, fieldsResolving] = useResolvedFields();

const componentResolving = false; //thisComponentState?.loadingCount > 0;
const componentResolving = thisComponentState?.loadingCount > 0;

const isLoading = fieldsResolving || componentResolving;

Expand All @@ -112,7 +112,7 @@ export const Fields = ({ wrapFields = true }: { wrapFields?: boolean }) => {
}}
>
Form {Math.random()}
<Wrapper isLoading={isLoading} itemSelector={null}>
<Wrapper isLoading={isLoading} itemSelector={itemSelector}>
{Object.keys(fields).map((fieldName) => {
const field = fields[fieldName];

Expand Down
49 changes: 38 additions & 11 deletions packages/core/components/Puck/context.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,4 @@
import {
ReactNode,
SetStateAction,
createContext,
useContext,
useEffect,
useState,
} from "react";
import { createContext } from "react";
import {
Config,
IframeConfig,
Expand All @@ -26,8 +19,8 @@ import {
RefreshPermissions,
useResolvedPermissions,
} from "../../lib/use-resolved-permissions";
import { useResolvedData } from "../../lib/use-resolved-data";
import { create } from "zustand";
import { resolveData } from "../../lib/resolve-data";

export const defaultAppState: AppState = {
data: { content: [], root: {} },
Expand Down Expand Up @@ -70,6 +63,9 @@ export type AppContext<
config: UserConfig;
componentState: ComponentState;
setComponentState: (componentState: ComponentState) => void;
setComponentLoading: (id: string) => void;
unsetComponentLoading: (id: string) => void;
resolveDataRuns: number;
resolveData: (newAppState: AppState) => void;
plugins: Plugin[];
overrides: Partial<Overrides>;
Expand All @@ -93,6 +89,9 @@ export const defaultContext: AppContext = {
config: { components: {} },
componentState: {},
setComponentState: () => {},
setComponentLoading: () => {},
unsetComponentLoading: () => {},
resolveDataRuns: 0,
resolveData: () => {},
plugins: [],
overrides: {},
Expand Down Expand Up @@ -207,9 +206,8 @@ export const appContext = createContext<AppContext>(defaultContext);
// );
// };

export const useAppStore = create<AppContext>((set) => ({
export const useAppStore = create<AppContext>((set, get) => ({
...defaultContext,
// TODO move to own store?
dispatch: (action: PuckAction) =>
set((s) => {
const dispatch = createReducer({ config: s.config, record: () => {} });
Expand All @@ -227,6 +225,28 @@ export const useAppStore = create<AppContext>((set) => ({
setZoomConfig: (zoomConfig) => set({ zoomConfig }),
setStatus: (status) => set({ status }),
setComponentState: (componentState) => set({ componentState }),
setComponentLoading: (id: string) => {
const { setComponentState, componentState } = get();

setComponentState({
...componentState,
[id]: {
...componentState[id],
loadingCount: (componentState[id]?.loadingCount || 0) + 1,
},
});
},
unsetComponentLoading: (id: string) => {
const { setComponentState, componentState } = get();

setComponentState({
...componentState,
[id]: {
...componentState[id],
loadingCount: Math.max((componentState[id]?.loadingCount || 0) - 1, 0),
},
});
},
// Helper
setUi: (ui: Partial<UiState>, recordHistory?: boolean) =>
set((s) => {
Expand All @@ -252,6 +272,13 @@ export const useAppStore = create<AppContext>((set) => ({
duplicate: true,
insert: true,
}),
resolveDataRuns: 0,
resolveData: (newAppState) =>
set((s) => {
resolveData(newAppState);

return { ...s, resolveDataRuns: s.resolveDataRuns + 1 };
}),
}));

export function getAppStore<UserConfig extends Config = Config>() {
Expand Down
8 changes: 7 additions & 1 deletion packages/core/components/Puck/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ import { Heading } from "../Heading";
import { IconButton } from "../IconButton/IconButton";
import { PuckAction, createReducer } from "../../reducer";
import getClassNameFactory from "../../lib/get-class-name-factory";
import { defaultAppState, useAppStore } from "./context";
import { defaultAppState, getAppStore, useAppStore } from "./context";
import { MenuBar } from "../MenuBar";
import styles from "./styles.module.css";
import { Fields } from "./components/Fields";
Expand Down Expand Up @@ -433,6 +433,12 @@ export function Puck<

useMonitorNodeIndex();

useEffect(() => {
const { state, resolveData } = getAppStore();

resolveData(state);
}, []);

return (
<div className={`Puck ${getClassName()}`}>
{Math.random()}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,48 +1,44 @@
import { AppState, ComponentData, Config, RootData } from "../types";
import { Dispatch, useCallback, useEffect, useState } from "react";
import { PuckAction } from "../reducer";
import { AppState, ComponentData, RootData } from "../types";
import { resolveComponentData } from "./resolve-component-data";
import { applyDynamicProps } from "./apply-dynamic-props";
import { resolveRootData } from "./resolve-root-data";
import { flattenData } from "./flatten-data";
import { AppContext } from "../components/Puck/context";
import { RefreshPermissions } from "./use-resolved-permissions";

export const useResolvedData = (
appState: AppState,
config: Config,
dispatch: Dispatch<PuckAction>,
setComponentLoading: (id: string) => void,
unsetComponentLoading: (id: string) => void,
refreshPermissions: RefreshPermissions
) => {
const [{ resolverKey, newAppState }, setResolverState] = useState({
resolverKey: 0,
newAppState: appState,
});
import { getAppStore } from "../components/Puck/context";

export const resolveData = (newAppState: AppState) => {
const {
state: appState,
config,
dispatch,
refreshPermissions,
resolveDataRuns,
setComponentLoading,
unsetComponentLoading,
} = getAppStore();

const deferredSetStates: Record<string, NodeJS.Timeout> = {};

const _setComponentLoading = useCallback(
(id: string, loading: boolean, defer: number = 0) => {
if (deferredSetStates[id]) {
clearTimeout(deferredSetStates[id]);

delete deferredSetStates[id];
const _setComponentLoading = (
id: string,
loading: boolean,
defer: number = 0
) => {
if (deferredSetStates[id]) {
clearTimeout(deferredSetStates[id]);

delete deferredSetStates[id];
}

deferredSetStates[id] = setTimeout(() => {
if (loading) {
setComponentLoading(id);
} else {
unsetComponentLoading(id);
}

deferredSetStates[id] = setTimeout(() => {
if (loading) {
setComponentLoading(id);
} else {
unsetComponentLoading(id);
}

delete deferredSetStates[id];
}, defer);
},
[]
);
delete deferredSetStates[id];
}, defer);
};

const runResolvers = async () => {
// Flatten zones
Expand Down Expand Up @@ -74,9 +70,10 @@ export const useResolvedData = (
state: (prev) => ({
...prev,
data: applyDynamicProps(prev.data, dynamicDataMap, dynamicRoot),
ui: resolverKey > 0 ? { ...prev.ui, ...newAppState.ui } : prev.ui,
ui:
resolveDataRuns > 0 ? { ...prev.ui, ...newAppState.ui } : prev.ui,
}),
recordHistory: resolverKey > 0,
recordHistory: resolveDataRuns > 0,
});
}
};
Expand Down Expand Up @@ -124,18 +121,5 @@ export const useResolvedData = (
await Promise.all(promises);
};

useEffect(() => {
runResolvers();
}, [resolverKey]);

const resolveData = useCallback((newAppState: AppState = appState) => {
setResolverState((curr) => ({
resolverKey: curr.resolverKey + 1,
newAppState,
}));
}, []);

return {
resolveData,
};
return runResolvers();
};

0 comments on commit f261725

Please sign in to comment.