From aee153ded46ec3a67eaef2dc179b1e965a3ec340 Mon Sep 17 00:00:00 2001 From: Pello Rao Date: Fri, 10 Nov 2023 12:54:28 +0800 Subject: [PATCH 1/8] feat: add custom metadata to the UserComponent that can be brought into Node --- packages/core/src/interfaces/nodes.ts | 2 ++ packages/core/src/utils/createNode.ts | 5 +++++ 2 files changed, 7 insertions(+) diff --git a/packages/core/src/interfaces/nodes.ts b/packages/core/src/interfaces/nodes.ts index ace0ed916..18730e42b 100644 --- a/packages/core/src/interfaces/nodes.ts +++ b/packages/core/src/interfaces/nodes.ts @@ -9,6 +9,7 @@ export type UserComponentConfig = { related: Partial; props: Partial; custom: Record; + customMetadata: Record; isCanvas: boolean; // TODO: Deprecate @@ -26,6 +27,7 @@ export type NodeEventTypes = 'selected' | 'dragged' | 'hovered'; export type Node = { id: NodeId; data: NodeData; + customMetadata: Record; events: Record; dom: HTMLElement | null; related: Record; diff --git a/packages/core/src/utils/createNode.ts b/packages/core/src/utils/createNode.ts index b1e01686d..9a3f371b8 100644 --- a/packages/core/src/utils/createNode.ts +++ b/packages/core/src/utils/createNode.ts @@ -37,6 +37,7 @@ export function createNode( linkedNodes: {}, ...newNode.data, }, + customMetadata: {}, related: {}, events: { selected: false, @@ -136,6 +137,10 @@ export function createNode( ); }); } + + if (userComponentConfig.customMetadata) { + node.customMetadata = userComponentConfig.customMetadata; + } } return node; From 2dac24cb928196fb2f34dc5862b392c41fbafbcf Mon Sep 17 00:00:00 2001 From: Pello Rao Date: Fri, 10 Nov 2023 13:02:15 +0800 Subject: [PATCH 2/8] chore: add changeset --- .changeset/stupid-onions-mate.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/stupid-onions-mate.md diff --git a/.changeset/stupid-onions-mate.md b/.changeset/stupid-onions-mate.md new file mode 100644 index 000000000..4a33cc4cc --- /dev/null +++ b/.changeset/stupid-onions-mate.md @@ -0,0 +1,5 @@ +--- +'@craftjs/core': minor +--- + +Add custom metadata to the UserComponent that can be brought into Node From 6c4eb97ebf2466bad552a4fe09d280a56f9bbaf8 Mon Sep 17 00:00:00 2001 From: Pello Rao Date: Fri, 10 Nov 2023 13:06:11 +0800 Subject: [PATCH 3/8] chore: change the level of the current changeset to patch --- .changeset/stupid-onions-mate.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changeset/stupid-onions-mate.md b/.changeset/stupid-onions-mate.md index 4a33cc4cc..75d46f166 100644 --- a/.changeset/stupid-onions-mate.md +++ b/.changeset/stupid-onions-mate.md @@ -1,5 +1,5 @@ --- -'@craftjs/core': minor +'@craftjs/core': patch --- Add custom metadata to the UserComponent that can be brought into Node From df0bd8dcdbacc4888a1ba9137ff4af9b7776d700 Mon Sep 17 00:00:00 2001 From: Pello Rao Date: Mon, 19 Feb 2024 18:49:11 +0800 Subject: [PATCH 4/8] refactor: change UserComponentConfig.customMetadata to UserComponentConfig.info --- .changeset/stupid-onions-mate.md | 2 +- packages/core/src/interfaces/nodes.ts | 4 ++-- packages/core/src/utils/createNode.ts | 6 +++--- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.changeset/stupid-onions-mate.md b/.changeset/stupid-onions-mate.md index 75d46f166..0faec8127 100644 --- a/.changeset/stupid-onions-mate.md +++ b/.changeset/stupid-onions-mate.md @@ -2,4 +2,4 @@ '@craftjs/core': patch --- -Add custom metadata to the UserComponent that can be brought into Node +Add a property `info` to `UserComponent`, which will be copied to `Node`, but will not be serialized. diff --git a/packages/core/src/interfaces/nodes.ts b/packages/core/src/interfaces/nodes.ts index 18730e42b..aa47c7938 100644 --- a/packages/core/src/interfaces/nodes.ts +++ b/packages/core/src/interfaces/nodes.ts @@ -9,7 +9,7 @@ export type UserComponentConfig = { related: Partial; props: Partial; custom: Record; - customMetadata: Record; + info: Record; isCanvas: boolean; // TODO: Deprecate @@ -27,7 +27,7 @@ export type NodeEventTypes = 'selected' | 'dragged' | 'hovered'; export type Node = { id: NodeId; data: NodeData; - customMetadata: Record; + info: Record; events: Record; dom: HTMLElement | null; related: Record; diff --git a/packages/core/src/utils/createNode.ts b/packages/core/src/utils/createNode.ts index 9a3f371b8..4321a5a91 100644 --- a/packages/core/src/utils/createNode.ts +++ b/packages/core/src/utils/createNode.ts @@ -37,7 +37,7 @@ export function createNode( linkedNodes: {}, ...newNode.data, }, - customMetadata: {}, + info: {}, related: {}, events: { selected: false, @@ -138,8 +138,8 @@ export function createNode( }); } - if (userComponentConfig.customMetadata) { - node.customMetadata = userComponentConfig.customMetadata; + if (userComponentConfig.info) { + node.info = userComponentConfig.info; } } From fd99f4f855d1e1e46669e572ab22ea03b99b8fc0 Mon Sep 17 00:00:00 2001 From: Pello Rao Date: Mon, 25 Mar 2024 12:00:37 +0800 Subject: [PATCH 5/8] fix: resolve performance issue within resolveComponent --- .changeset/fluffy-days-act.md | 5 +++ .changeset/stupid-onions-mate.md | 5 --- packages/core/src/utils/resolveComponent.ts | 50 ++++++++++++--------- 3 files changed, 34 insertions(+), 26 deletions(-) create mode 100644 .changeset/fluffy-days-act.md delete mode 100644 .changeset/stupid-onions-mate.md diff --git a/.changeset/fluffy-days-act.md b/.changeset/fluffy-days-act.md new file mode 100644 index 000000000..b36fbf11f --- /dev/null +++ b/.changeset/fluffy-days-act.md @@ -0,0 +1,5 @@ +--- +'@craftjs/core': minor +--- + +Resolve performance issue within resolveComponent. diff --git a/.changeset/stupid-onions-mate.md b/.changeset/stupid-onions-mate.md deleted file mode 100644 index 0faec8127..000000000 --- a/.changeset/stupid-onions-mate.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@craftjs/core': patch ---- - -Add a property `info` to `UserComponent`, which will be copied to `Node`, but will not be serialized. diff --git a/packages/core/src/utils/resolveComponent.ts b/packages/core/src/utils/resolveComponent.ts index 1d54c876f..772df896a 100644 --- a/packages/core/src/utils/resolveComponent.ts +++ b/packages/core/src/utils/resolveComponent.ts @@ -1,34 +1,20 @@ import { ERROR_NOT_IN_RESOLVER } from '@craftjs/utils'; +import React from 'react'; import invariant from 'tiny-invariant'; import { Resolver } from '../interfaces'; +let currResolver: Resolver | undefined = undefined; +const reversedResolver = new Map(); + export const resolveComponent = ( resolver: Resolver, comp: React.ElementType | string ) => { const componentName = (comp as any).name || (comp as any).displayName; - - const getNameInResolver = () => { - if (resolver[componentName]) { - return componentName; - } - - for (let i = 0; i < Object.keys(resolver).length; i++) { - const name = Object.keys(resolver)[i]; - const fn = resolver[name]; - - if (fn === comp) { - return name; - } - } - - if (typeof comp === 'string') { - return comp; - } - }; - - const resolvedName = getNameInResolver(); + const resolvedName = resolver[componentName] + ? componentName + : searchComponentInResolver(resolver, comp); invariant( resolvedName, @@ -37,3 +23,25 @@ export const resolveComponent = ( return resolvedName; }; + +const searchComponentInResolver = ( + resolver: Resolver, + comp: React.ElementType | string +): string | undefined => { + if (currResolver !== resolver) updateReversedResolver(resolver); + + const name = reversedResolver.get(comp); + if (name !== undefined) return name; + + if (typeof comp === 'string') return comp; + + return undefined; +}; + +const updateReversedResolver = (resolver: Resolver): void => { + currResolver = resolver; + reversedResolver.clear(); + for (const [name, comp] of Object.entries(resolver)) { + reversedResolver.set(comp, name); + } +}; From aaac3300f62891fc555cd39eb38a08b23d0b8ef6 Mon Sep 17 00:00:00 2001 From: "pellorao@gmail.com" Date: Thu, 16 May 2024 16:00:32 +0800 Subject: [PATCH 6/8] refactor: optimize the logic of resolveComponent() --- packages/core/src/utils/resolveComponent.ts | 77 +++++++++++++-------- 1 file changed, 48 insertions(+), 29 deletions(-) diff --git a/packages/core/src/utils/resolveComponent.ts b/packages/core/src/utils/resolveComponent.ts index 772df896a..b0eae5f64 100644 --- a/packages/core/src/utils/resolveComponent.ts +++ b/packages/core/src/utils/resolveComponent.ts @@ -4,44 +4,63 @@ import invariant from 'tiny-invariant'; import { Resolver } from '../interfaces'; -let currResolver: Resolver | undefined = undefined; -const reversedResolver = new Map(); +type ReversedResolver = Map; -export const resolveComponent = ( - resolver: Resolver, - comp: React.ElementType | string -) => { - const componentName = (comp as any).name || (comp as any).displayName; - const resolvedName = resolver[componentName] - ? componentName - : searchComponentInResolver(resolver, comp); +type CachedResolverData = { + resolver: Resolver; + reversed: ReversedResolver; +}; - invariant( - resolvedName, - ERROR_NOT_IN_RESOLVER.replace('%node_type%', componentName) - ); +let CACHED_RESOLVER_DATA: CachedResolverData | null = null; - return resolvedName; +const getReversedResolver = (resolver: Resolver): ReversedResolver => { + if (CACHED_RESOLVER_DATA && CACHED_RESOLVER_DATA.resolver === resolver) { + return CACHED_RESOLVER_DATA.reversed; + } + + CACHED_RESOLVER_DATA = { + resolver, + reversed: new Map(), + }; + + for (const [name, comp] of Object.entries(resolver)) { + CACHED_RESOLVER_DATA.reversed.set(comp, name); + } + + return CACHED_RESOLVER_DATA.reversed; +}; + +const getComponentName = (component: React.ElementType): string | undefined => { + return (component as any).name || (component as any).displayName; }; const searchComponentInResolver = ( resolver: Resolver, - comp: React.ElementType | string -): string | undefined => { - if (currResolver !== resolver) updateReversedResolver(resolver); - - const name = reversedResolver.get(comp); - if (name !== undefined) return name; - - if (typeof comp === 'string') return comp; + comp: React.ElementType +): string | null => { + const componentName = getComponentName(comp); + if (Object.hasOwn(resolver, componentName)) { + return componentName; + } - return undefined; + const name = getReversedResolver(resolver).get(comp); + return name !== undefined ? name : null; }; -const updateReversedResolver = (resolver: Resolver): void => { - currResolver = resolver; - reversedResolver.clear(); - for (const [name, comp] of Object.entries(resolver)) { - reversedResolver.set(comp, name); +export const resolveComponent = ( + resolver: Resolver, + comp: React.ElementType | string +): string => { + if (typeof comp === 'string') { + return comp; } + + const resolvedName = searchComponentInResolver(resolver, comp); + + invariant( + resolvedName, + ERROR_NOT_IN_RESOLVER.replace('%node_type%', getComponentName(comp)) + ); + + return resolvedName; }; From fea783cce64359c9485d6c1a1de2962332e1c841 Mon Sep 17 00:00:00 2001 From: "pellorao@gmail.com" Date: Thu, 16 May 2024 18:18:43 +0800 Subject: [PATCH 7/8] refactor(resolver): remove the logic for checking the existence of a component by its name --- packages/core/src/utils/resolveComponent.ts | 5 ----- 1 file changed, 5 deletions(-) diff --git a/packages/core/src/utils/resolveComponent.ts b/packages/core/src/utils/resolveComponent.ts index b0eae5f64..edb9919e2 100644 --- a/packages/core/src/utils/resolveComponent.ts +++ b/packages/core/src/utils/resolveComponent.ts @@ -38,11 +38,6 @@ const searchComponentInResolver = ( resolver: Resolver, comp: React.ElementType ): string | null => { - const componentName = getComponentName(comp); - if (Object.hasOwn(resolver, componentName)) { - return componentName; - } - const name = getReversedResolver(resolver).get(comp); return name !== undefined ? name : null; }; From 722ab3b8906f722410635c14ae9988ceb2b02267 Mon Sep 17 00:00:00 2001 From: Prev Wong Date: Thu, 16 May 2024 18:56:26 +0800 Subject: [PATCH 8/8] Update fluffy-days-act.md --- .changeset/fluffy-days-act.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changeset/fluffy-days-act.md b/.changeset/fluffy-days-act.md index b36fbf11f..dd20f7036 100644 --- a/.changeset/fluffy-days-act.md +++ b/.changeset/fluffy-days-act.md @@ -2,4 +2,4 @@ '@craftjs/core': minor --- -Resolve performance issue within resolveComponent. +Improve resolver performance