From e42e346d1b1ea28cee85b2bbb626ac91d3c8f8e9 Mon Sep 17 00:00:00 2001 From: Bogdan Chadkin Date: Thu, 13 Apr 2023 13:08:26 +0700 Subject: [PATCH] Drop legacy root instance store (#1441) Ref https://github.com/webstudio-is/webstudio-builder/issues/696 The last piece with denormalized tree. Now we rely only on normalized instances map. --- .../features/props-panel/props-panel.tsx | 8 ++- .../style-panel/shared/use-style-data.ts | 3 +- .../features/style-panel/style-panel.tsx | 4 +- .../selected-instance-connector.ts | 6 +- .../app/shared/nano-states/instances.ts | 62 ++----------------- apps/builder/app/shared/tree-utils.ts | 41 ------------ 6 files changed, 18 insertions(+), 106 deletions(-) diff --git a/apps/builder/app/builder/features/props-panel/props-panel.tsx b/apps/builder/app/builder/features/props-panel/props-panel.tsx index 62dd231187..2d3ae13dcd 100644 --- a/apps/builder/app/builder/features/props-panel/props-panel.tsx +++ b/apps/builder/app/builder/features/props-panel/props-panel.tsx @@ -1,5 +1,9 @@ import store from "immerhin"; -import type { Instance, Prop } from "@webstudio-is/project-build"; +import type { + Instance, + InstancesItem, + Prop, +} from "@webstudio-is/project-build"; import { theme, useCombobox, @@ -272,7 +276,7 @@ export const PropsPanelContainer = ({ publish, }: { publish: Publish; - selectedInstance: Instance; + selectedInstance: InstancesItem; }) => { const propsMeta = getComponentPropsMeta(instance.component); if (propsMeta === undefined) { diff --git a/apps/builder/app/builder/features/style-panel/shared/use-style-data.ts b/apps/builder/app/builder/features/style-panel/shared/use-style-data.ts index 03ce8c099e..7d778b8c7e 100644 --- a/apps/builder/app/builder/features/style-panel/shared/use-style-data.ts +++ b/apps/builder/app/builder/features/style-panel/shared/use-style-data.ts @@ -5,6 +5,7 @@ import warnOnce from "warn-once"; import { type Breakpoint, type Instance, + type InstancesItem, getStyleDeclKey, } from "@webstudio-is/project-build"; import type { StyleProperty, StyleValue } from "@webstudio-is/css-data"; @@ -47,7 +48,7 @@ declare module "~/shared/pubsub" { type UseStyleData = { publish: Publish; - selectedInstance: Instance; + selectedInstance: InstancesItem; }; export type StyleUpdateOptions = { isEphemeral: boolean }; diff --git a/apps/builder/app/builder/features/style-panel/style-panel.tsx b/apps/builder/app/builder/features/style-panel/style-panel.tsx index ed01a032b0..fb48e71980 100644 --- a/apps/builder/app/builder/features/style-panel/style-panel.tsx +++ b/apps/builder/app/builder/features/style-panel/style-panel.tsx @@ -1,5 +1,5 @@ import { theme, Box, ScrollArea } from "@webstudio-is/design-system"; -import type { Instance } from "@webstudio-is/project-build"; +import type { InstancesItem } from "@webstudio-is/project-build"; import type { Publish } from "~/shared/pubsub"; import { useStyleData } from "./shared/use-style-data"; @@ -9,7 +9,7 @@ import { StyleSourcesSection } from "./style-source-section"; type StylePanelProps = { publish: Publish; - selectedInstance: Instance; + selectedInstance: InstancesItem; }; export const StylePanel = ({ selectedInstance, publish }: StylePanelProps) => { diff --git a/apps/builder/app/canvas/features/webstudio-component/selected-instance-connector.ts b/apps/builder/app/canvas/features/webstudio-component/selected-instance-connector.ts index db16e8adf7..09f59bbb7f 100644 --- a/apps/builder/app/canvas/features/webstudio-component/selected-instance-connector.ts +++ b/apps/builder/app/canvas/features/webstudio-component/selected-instance-connector.ts @@ -11,7 +11,7 @@ import { subscribe } from "~/shared/pubsub"; import { subscribeWindowResize } from "~/shared/dom-hooks"; import { isResizingCanvasStore, - rootInstanceContainer, + instancesStore, selectedInstanceBrowserStyleStore, selectedInstanceIntanceToTagStore, selectedInstanceUnitSizesStore, @@ -81,7 +81,7 @@ export const SelectedInstanceConnector = ({ instanceStyles: StyleDecl[]; instanceProps: undefined | Prop[]; }) => { - const rootInstance = useStore(rootInstanceContainer); + const instances = useStore(instancesStore); useEffect(() => { const element = instanceElementRef.current; @@ -188,7 +188,7 @@ export const SelectedInstanceConnector = ({ // instance props may change dom element instanceProps, // update on all changes in the tree in case ResizeObserver does ont work - rootInstance, + instances, ]); return null; diff --git a/apps/builder/app/shared/nano-states/instances.ts b/apps/builder/app/shared/nano-states/instances.ts index 3a1df85b44..a8ce171c94 100644 --- a/apps/builder/app/shared/nano-states/instances.ts +++ b/apps/builder/app/shared/nano-states/instances.ts @@ -1,14 +1,9 @@ import { atom, computed } from "nanostores"; import { getComponentMeta } from "@webstudio-is/react-sdk"; -import type { - Instance, - Instances, - InstancesItem, -} from "@webstudio-is/project-build"; -import { createInstancesIndex, type InstanceSelector } from "../tree-utils"; +import type { InstancesItem } from "@webstudio-is/project-build"; +import type { InstanceSelector } from "../tree-utils"; import { getElementByInstanceSelector } from "../dom-utils"; import { useSyncInitializeOnce } from "../hook-utils"; -import { selectedPageStore } from "./pages"; export const isResizingCanvasStore = atom(false); @@ -75,61 +70,14 @@ export const useSetInstances = ( }); }; -// @todo will be removed soon -const denormalizeTree = ( - instances: Instances, - rootInstanceId: Instance["id"] -): undefined | Instance => { - const convertTree = (instance: InstancesItem) => { - const legacyInstance: Instance = { - type: "instance", - id: instance.id, - component: instance.component, - label: instance.label, - children: [], - }; - for (const child of instance.children) { - if (child.type === "id") { - const childInstance = instances.get(child.value); - if (childInstance) { - legacyInstance.children.push(convertTree(childInstance)); - } - } else { - legacyInstance.children.push(child); - } - } - return legacyInstance; - }; - const rootInstance = instances.get(rootInstanceId); - if (rootInstance === undefined) { - return; - } - return convertTree(rootInstance); -}; - -export const rootInstanceContainer = computed( - [instancesStore, selectedPageStore], - (instances, selectedPage) => { - if (selectedPage === undefined) { - return undefined; - } - return denormalizeTree(instances, selectedPage.rootInstanceId); - } -); - -export const instancesIndexStore = computed( - rootInstanceContainer, - createInstancesIndex -); - export const selectedInstanceStore = computed( - [instancesIndexStore, selectedInstanceSelectorStore], - (instancesIndex, selectedInstanceSelector) => { + [instancesStore, selectedInstanceSelectorStore], + (instances, selectedInstanceSelector) => { if (selectedInstanceSelector === undefined) { return; } const [selectedInstanceId] = selectedInstanceSelector; - return instancesIndex.instancesById.get(selectedInstanceId); + return instances.get(selectedInstanceId); } ); diff --git a/apps/builder/app/shared/tree-utils.ts b/apps/builder/app/shared/tree-utils.ts index def2d2770f..4ff7b074d0 100644 --- a/apps/builder/app/shared/tree-utils.ts +++ b/apps/builder/app/shared/tree-utils.ts @@ -61,47 +61,6 @@ export const createComponentInstance = ( }; }; -const traverseInstances = ( - instance: Instance, - cb: (child: Instance, parent: Instance) => void -) => { - for (const child of instance.children) { - if (child.type === "text") { - continue; - } - if (child.type === "instance") { - cb(child, instance); - traverseInstances(child, cb); - } - } -}; - -export type InstancesIndex = { - rootInstanceId: undefined | Instance["id"]; - instancesById: Map; - parentInstancesById: Map; -}; - -export const createInstancesIndex = ( - rootInstance: undefined | Instance -): InstancesIndex => { - const instancesById = new Map(); - const parentInstancesById = new Map(); - if (rootInstance) { - // traverse skips root without parent - instancesById.set(rootInstance.id, rootInstance); - traverseInstances(rootInstance, (child, parent) => { - parentInstancesById.set(child.id, parent); - instancesById.set(child.id, child); - }); - } - return { - rootInstanceId: rootInstance?.id, - instancesById, - parentInstancesById, - }; -}; - const isInstanceDroppable = (instance: InstancesItem) => { const meta = getComponentMeta(instance.component); return meta?.type === "container";