Skip to content

Commit

Permalink
fix: improve resolver performance (#623)
Browse files Browse the repository at this point in the history
  • Loading branch information
Traveller23 authored and prevwong committed May 17, 2024
1 parent b25469e commit 4fa9b46
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 23 deletions.
5 changes: 5 additions & 0 deletions .changeset/fluffy-days-act.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@craftjs/core': patch
---

Improve resolver performance
68 changes: 45 additions & 23 deletions packages/core/src/utils/resolveComponent.ts
Original file line number Diff line number Diff line change
@@ -1,38 +1,60 @@
import { ERROR_NOT_IN_RESOLVER } from '@craftjs/utils';
import React from 'react';
import invariant from 'tiny-invariant';

import { Resolver } from '../interfaces';

type ReversedResolver = Map<React.ComponentType | string, string>;

type CachedResolverData = {
resolver: Resolver;
reversed: ReversedResolver;
};

let CACHED_RESOLVER_DATA: CachedResolverData | null = null;

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 | null => {
const name = getReversedResolver(resolver).get(comp);
return name !== undefined ? name : null;
};

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;
}
};
): string => {
if (typeof comp === 'string') {
return comp;
}

const resolvedName = getNameInResolver();
const resolvedName = searchComponentInResolver(resolver, comp);

invariant(
resolvedName,
ERROR_NOT_IN_RESOLVER.replace('%node_type%', componentName)
ERROR_NOT_IN_RESOLVER.replace('%node_type%', getComponentName(comp))
);

return resolvedName;
Expand Down

0 comments on commit 4fa9b46

Please sign in to comment.