instantiate instead of closure for storing elements

This commit is contained in:
Aakansha Doshi 2023-08-02 21:32:26 +05:30
parent 93008d6a8d
commit 685ece4b3a

View file

@ -224,6 +224,7 @@ const bindTextToContainer = (
const bindLinearElementToElement = ( const bindLinearElementToElement = (
linearElement: ValidLinearElement, linearElement: ValidLinearElement,
elementStore: ElementStore,
): { ): {
linearElement: ExcalidrawLinearElement; linearElement: ExcalidrawLinearElement;
startBoundElement?: ExcalidrawElement; startBoundElement?: ExcalidrawElement;
@ -264,7 +265,7 @@ const bindLinearElementToElement = (
let existingElement; let existingElement;
if (start.id) { if (start.id) {
existingElement = excalidrawElements existingElement = elementStore
.get() .get()
.find((ele) => ele?.id === start.id) as Exclude< .find((ele) => ele?.id === start.id) as Exclude<
ExcalidrawBindableElement, ExcalidrawBindableElement,
@ -331,7 +332,7 @@ const bindLinearElementToElement = (
let existingElement; let existingElement;
if (end.id) { if (end.id) {
existingElement = excalidrawElements existingElement = elementStore
.get() .get()
.find((ele) => ele?.id === end.id) as Exclude< .find((ele) => ele?.id === end.id) as Exclude<
ExcalidrawBindableElement, ExcalidrawBindableElement,
@ -398,50 +399,39 @@ const bindLinearElementToElement = (
}; };
}; };
const excalidrawElements = (() => { class ElementStore {
const res: ExcalidrawElement[] = []; res: ExcalidrawElement[] = [];
const elementMap = new Map<string, number>(); elementMap = new Map<string, number>();
const add = (ele?: ExcalidrawElement) => { add = (ele?: ExcalidrawElement) => {
if (!ele) { if (!ele) {
return; return;
} }
const index = elementMap.get(ele.id); const index = this.elementMap.get(ele.id);
if (index !== undefined && index >= 0) { if (index !== undefined && index >= 0) {
res[index] = ele; this.res[index] = ele;
} else { } else {
res.push(ele); this.res.push(ele);
const index = res.length - 1; const index = this.res.length - 1;
elementMap.set(ele.id, index); this.elementMap.set(ele.id, index);
} }
}; };
const clear = () => { get = () => {
res.length = 0; return this.res;
elementMap.clear();
}; };
const get = () => { hasElementWithId = (id: string) => {
return res; const index = this.elementMap.get(id);
};
const hasElementWithId = (id: string) => {
const index = elementMap.get(id);
return index !== undefined && index >= 0; return index !== undefined && index >= 0;
}; };
return { }
add,
clear,
get,
hasElementWithId,
};
})();
export const convertToExcalidrawElements = ( export const convertToExcalidrawElements = (
elements: ExcalidrawProgrammaticAPI["elements"], elements: ExcalidrawProgrammaticAPI["elements"],
): ExcalidrawElement[] => { ): ExcalidrawElement[] => {
excalidrawElements.clear();
if (!elements) { if (!elements) {
return []; return [];
} }
const elementStore = new ElementStore();
// Push all elements to array as there could be cases where element id // Push all elements to array as there could be cases where element id
// is referenced before element is created // is referenced before element is created
elements.forEach((element) => { elements.forEach((element) => {
@ -450,15 +440,15 @@ export const convertToExcalidrawElements = (
// To make sure every element has a unique id since regenerateId appends // To make sure every element has a unique id since regenerateId appends
// _copy to the original id and if it exists we need to generate again // _copy to the original id and if it exists we need to generate again
// hence a loop // hence a loop
while (excalidrawElements.hasElementWithId(elementId)) { while (elementStore.hasElementWithId(elementId)) {
elementId = regenerateId(elementId); elementId = regenerateId(elementId);
} }
const elementWithId = { ...element, id: elementId }; const elementWithId = { ...element, id: elementId };
excalidrawElements.add(elementWithId as ExcalidrawElement); elementStore.add(elementWithId as ExcalidrawElement);
}); });
const pushedElements = const pushedElements =
excalidrawElements.get() as readonly ExcalidrawProgrammaticElement[]; elementStore.get() as readonly ExcalidrawProgrammaticElement[];
pushedElements.forEach((element) => { pushedElements.forEach((element) => {
const elementWithId = { ...element }; const elementWithId = { ...element };
@ -477,8 +467,8 @@ export const convertToExcalidrawElements = (
} & ValidLinearElement), } & ValidLinearElement),
elementWithId?.label, elementWithId?.label,
); );
excalidrawElements.add(container); elementStore.add(container);
excalidrawElements.add(text); elementStore.add(text);
if (container.type === "arrow") { if (container.type === "arrow") {
const originalStart = const originalStart =
@ -486,15 +476,18 @@ export const convertToExcalidrawElements = (
const originalEnd = const originalEnd =
elementWithId.type === "arrow" ? elementWithId?.end : undefined; elementWithId.type === "arrow" ? elementWithId?.end : undefined;
const { linearElement, startBoundElement, endBoundElement } = const { linearElement, startBoundElement, endBoundElement } =
bindLinearElementToElement({ bindLinearElementToElement(
...container, {
start: originalStart, ...container,
end: originalEnd, start: originalStart,
}); end: originalEnd,
},
elementStore,
);
container = linearElement; container = linearElement;
excalidrawElements.add(linearElement); elementStore.add(linearElement);
excalidrawElements.add(startBoundElement); elementStore.add(startBoundElement);
excalidrawElements.add(endBoundElement); elementStore.add(endBoundElement);
} }
} else { } else {
let excalidrawElement; let excalidrawElement;
@ -518,13 +511,13 @@ export const convertToExcalidrawElements = (
...elementWithId, ...elementWithId,
}; };
excalidrawElements.add(excalidrawElement as ExcalidrawTextElement); elementStore.add(excalidrawElement as ExcalidrawTextElement);
} else if (elementWithId.type === "arrow") { } else if (elementWithId.type === "arrow") {
const { linearElement, startBoundElement, endBoundElement } = const { linearElement, startBoundElement, endBoundElement } =
bindLinearElementToElement(elementWithId); bindLinearElementToElement(elementWithId, elementStore);
excalidrawElements.add(linearElement); elementStore.add(linearElement);
excalidrawElements.add(startBoundElement); elementStore.add(startBoundElement);
excalidrawElements.add(endBoundElement); elementStore.add(endBoundElement);
} else if (elementWithId.type === "line") { } else if (elementWithId.type === "line") {
const width = elementWithId.width || DEFAULT_LINEAR_ELEMENT_PROPS.width; const width = elementWithId.width || DEFAULT_LINEAR_ELEMENT_PROPS.width;
const height = const height =
@ -538,23 +531,23 @@ export const convertToExcalidrawElements = (
], ],
...elementWithId, ...elementWithId,
}); });
excalidrawElements.add(lineElement); elementStore.add(lineElement);
} else if (elementWithId.type === "image") { } else if (elementWithId.type === "image") {
const imageElement = newImageElement({ const imageElement = newImageElement({
width: elementWithId?.width || DEFAULT_DIMENSION, width: elementWithId?.width || DEFAULT_DIMENSION,
height: elementWithId?.height || DEFAULT_DIMENSION, height: elementWithId?.height || DEFAULT_DIMENSION,
...elementWithId, ...elementWithId,
}); });
excalidrawElements.add(imageElement); elementStore.add(imageElement);
} else { } else {
excalidrawElement = { excalidrawElement = {
...elementWithId, ...elementWithId,
width: elementWithId?.width || DEFAULT_DIMENSION, width: elementWithId?.width || DEFAULT_DIMENSION,
height: elementWithId?.height || DEFAULT_DIMENSION, height: elementWithId?.height || DEFAULT_DIMENSION,
} as ExcalidrawGenericElement; } as ExcalidrawGenericElement;
excalidrawElements.add(excalidrawElement); elementStore.add(excalidrawElement);
} }
} }
}); });
return excalidrawElements.get(); return elementStore.get();
}; };