Skip to content

Commit

Permalink
feat: normalise nodes draft (#136)
Browse files Browse the repository at this point in the history
* feat: patch listener draft

* nit
  • Loading branch information
prevwong authored Nov 6, 2020
1 parent f4db46b commit a00ef33
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 7 deletions.
43 changes: 41 additions & 2 deletions packages/core/src/editor/Editor.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { ERROR_RESOLVER_NOT_AN_OBJECT } from '@craftjs/utils';
import { ERROR_RESOLVER_NOT_AN_OBJECT, HISTORY_ACTIONS } from '@craftjs/utils';
import React, { useEffect } from 'react';
import invariant from 'tiny-invariant';

Expand All @@ -13,6 +13,7 @@ import { Options } from '../interfaces';
*/
export const Editor: React.FC<Partial<Options>> = ({
children,
normalizeNodes,
...options
}) => {
// we do not want to warn the user if no resolver was supplied
Expand All @@ -23,7 +24,45 @@ export const Editor: React.FC<Partial<Options>> = ({
);
}

const context = useEditorStore(options);
const context = useEditorStore(
options,
(_, previousState, actionPerformedWithPatches, query, normalizer) => {
if (!actionPerformedWithPatches) {
return;
}

const { patches, ...actionPerformed } = actionPerformedWithPatches;

for (let i = 0; i < patches.length; i++) {
const { path } = patches[i];
const isModifyingNodeData =
path.length > 2 && path[0] === 'nodes' && path[2] === 'data';

let actionType = actionPerformed.type;

if (
[HISTORY_ACTIONS.IGNORE, HISTORY_ACTIONS.THROTTLE].includes(
actionType
) &&
actionPerformed.params
) {
actionPerformed.type = actionPerformed.params[0];
}

if (
['setState', 'deserialize'].includes(actionPerformed.type) ||
isModifyingNodeData
) {
if (normalizeNodes) {
normalizer((draft) => {
normalizeNodes(draft, previousState, actionPerformed, query);
});
}
break; // we exit the loop as soon as we find a change in node.data
}
}
}
);

useEffect(() => {
if (context && options)
Expand Down
19 changes: 16 additions & 3 deletions packages/core/src/editor/store.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
import { useMethods, SubscriberAndCallbacksFor } from '@craftjs/utils';
import {
useMethods,
SubscriberAndCallbacksFor,
PatchListener,
} from '@craftjs/utils';

import { ActionMethods } from './actions';
import { QueryMethods } from './query';
Expand All @@ -25,6 +29,7 @@ export const editorInitialState: EditorState = {
success: 'rgb(98, 196, 98)',
},
handlers: (store) => new DefaultEventHandlers(store),
normalizeNodes: () => {},
},
};

Expand Down Expand Up @@ -74,7 +79,14 @@ export type EditorStore = SubscriberAndCallbacksFor<
typeof QueryMethods
>;

export const useEditorStore = (options: Partial<Options>): EditorStore => {
export const useEditorStore = (
options: Partial<Options>,
patchListener: PatchListener<
EditorState,
typeof ActionMethodsWithConfig,
typeof QueryMethods
>
): EditorStore => {
return useMethods(
ActionMethodsWithConfig,
{
Expand All @@ -84,6 +96,7 @@ export const useEditorStore = (options: Partial<Options>): EditorStore => {
...options,
},
},
QueryMethods
QueryMethods,
patchListener
) as EditorStore;
};
13 changes: 11 additions & 2 deletions packages/core/src/interfaces/editor.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { QueryCallbacksFor } from '@craftjs/utils';
import { QueryCallbacksFor, Delete, PatchListenerAction } from '@craftjs/utils';

import { Placement } from './events';
import { Nodes, NodeEventTypes, NodeId } from './nodes';

import { QueryMethods } from '../editor/query';
import { EditorStore } from '../editor/store';
import { EditorStore, ActionMethodsWithConfig } from '../editor/store';
import { useInternalEditorReturnType } from '../editor/useInternalEditor';
import { CoreEventHandlers } from '../events';

Expand All @@ -15,6 +15,15 @@ export type Options = {
enabled: boolean;
indicator: Record<'success' | 'error', string>;
handlers: (store: EditorStore) => CoreEventHandlers;
normalizeNodes: (
state: EditorState,
previousState: EditorState,
actionPerformed: Delete<
PatchListenerAction<EditorState, typeof ActionMethodsWithConfig>,
'patches'
>,
query: QueryCallbacksFor<typeof QueryMethods>
) => void;
};

export type Resolver = Record<string, string | React.ElementType>;
Expand Down

0 comments on commit a00ef33

Please sign in to comment.