Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
jalal246 committed Sep 14, 2023
1 parent ff45c8b commit 1cb5ff0
Show file tree
Hide file tree
Showing 3 changed files with 110 additions and 61 deletions.
31 changes: 20 additions & 11 deletions packages/dflex-dnd/src/LayoutManager/DFlexDnDStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -778,32 +778,41 @@ class DFlexDnDStore extends DFlexBaseStore {
return scroll;
}

getContainerByID(id: string): DFlexParentContainer {
getContainerByID(id: string): DFlexParentContainer | undefined {
const SK = this.getSKByID(id);

if (__DEV__) {
if (!this.containers.has(SK)) {
throw new Error(`Container with key '${SK}' is not found.`);
// eslint-disable-next-line no-console
console.warn(
`Container with key '${SK}' is not found. Ignore this warning If this element '${id}' is a parent.`,
);
}
}

const container = this.containers.get(SK)!;
const container = this.containers.get(SK);

return container;
}

getParentByElmID(id: string): [string, HTMLElement] {
const { id: parentID } = this.getContainerByID(id);
getParentByElmID(id: string): [string, HTMLElement] | undefined {
const container = this.getContainerByID(id);

if (__DEV__) {
if (!this.interactiveDOM.has(id)) {
throw new Error(`DOM element for ID '${id}' is not found.`);
if (container) {
const { id: parentID } = container;

if (__DEV__) {
if (!this.interactiveDOM.has(id)) {
throw new Error(`DOM element for ID '${id}' is not found.`);
}
}
}

const parentDOM = this.interactiveDOM.get(id)!;
const parentDOM = this.interactiveDOM.get(id)!;

return [parentID, parentDOM];
}

return [parentID, parentDOM];
return undefined;
}

deleteSiblings(SK: string, BK: string, depth: number): void {
Expand Down
127 changes: 89 additions & 38 deletions packages/dflex-dnd/src/Mutation/DFlexIDGarbageCollector.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import type DFlexDnDStore from "../LayoutManager/DFlexDnDStore";

export type TerminatedDOMiDs = Set<string>;

const enableParentCleanup = false;

function recomposeSiblings(
store: DFlexDnDStore,
terminatedDOMiDs: TerminatedDOMiDs,
Expand Down Expand Up @@ -49,72 +51,121 @@ function recomposeSiblings(

store.DOMGen.mutateSiblings(SK, connectedNodesID);
} else {
// If the siblings are entirely gone. Then validate the parent.

store.deleteSiblings(SK, BK, depth);
}
}

type SiblingKeyVal = { BK: string; depth: number };
type SKeysMap = Map<string, SiblingKeyVal>;

function groupIDsBySK(store: DFlexDnDStore, SKeys: SKeysMap, id: string): void {
const [dflexElm, DOM] = store.getElmWithDOM(id, false);

// hasAlreadyBeenRemoved
if (!DOM || !dflexElm) {
if (featureFlags.enableMutationDebugger) {
// eslint-disable-next-line no-console
console.log(
`Element with id: (${id}) has already been removed from registry`,
);
}

return;
}

const {
keys: { SK, BK },
depth,
} = dflexElm;

// This function handles calls from two sources: the observer and unregister.
// To prevent triggering the process twice, we check if it's the first time
// or if it's already been deleted.
const hasAlreadyBeenRemoved = store.deletedDOM.has(DOM);

if (!hasAlreadyBeenRemoved) {
if (__DEV__) {
if (featureFlags.enableMutationDebugger) {
// eslint-disable-next-line no-console
console.log(`Queue ${id} to be removed from registry`);
}
}

if (!SKeys.has(SK)) {
SKeys.set(SK, { BK, depth });
}
} else if (__DEV__) {
if (featureFlags.enableMutationDebugger) {
// eslint-disable-next-line no-console
console.log(
`Element with id: (${id}) has already been removed from registry`,
);
}
}
}

function DFlexIDGarbageCollector(
store: DFlexDnDStore,
terminatedDOMiDs: TerminatedDOMiDs,
): void {
const SKeys = new Map<string, SiblingKeyVal>();

terminatedDOMiDs.forEach((id) => {
const [dflexElm, DOM] = store.getElmWithDOM(id, false);
const group = (id: string) => groupIDsBySK(store, SKeys, id);

// hasAlreadyBeenRemoved
if (!DOM || !dflexElm) {
if (featureFlags.enableMutationDebugger) {
// eslint-disable-next-line no-console
console.log(
`Element with id: (${id}) has already been removed from registry`,
);
}
terminatedDOMiDs.forEach(group);

return;
if (SKeys.size === 0) {
if (featureFlags.enableMutationDebugger) {
// eslint-disable-next-line no-console
console.log(`Nothing to unregister.`);
}

const {
keys: { SK, BK },
depth,
} = dflexElm;
return;
}

SKeys.forEach((_, SK) => {
const siblings = store.getElmSiblingsByKey(SK);

const id = siblings[0];

// This function handles calls from two sources: the observer and unregister.
// To prevent triggering the process twice, we check if it's the first time
// or if it's already been deleted.
const hasAlreadyBeenRemoved = store.deletedDOM.has(DOM);
const parent = store.getParentByElmID(id);

if (!hasAlreadyBeenRemoved) {
store.deleteFromRegistry(id);
if (enableParentCleanup && parent) {
const [parentID, parentDOM] = parent;

if (__DEV__) {
if (!parentDOM.isConnected) {
if (featureFlags.enableMutationDebugger) {
// eslint-disable-next-line no-console
console.log(`DFlexIdGC: removing ${id} from registry`);
console.log(
`Parent with id: (${parentID}) will be removed from registry`,
);
}
}

if (!SKeys.has(SK)) {
SKeys.set(SK, { BK, depth });
}
} else if (__DEV__) {
if (featureFlags.enableMutationDebugger) {
// eslint-disable-next-line no-console
console.log(
`Element with id: (${id}) has already been removed from registry`,
);
siblings.forEach((eID) => {
store.deleteFromRegistry(eID);
terminatedDOMiDs.delete(eID);
});

DFlexIDGarbageCollector(store, new Set([parentID]));
}
}
});

const recomposeFromKys = (v: SiblingKeyVal, k: string) =>
recomposeSiblings(store, terminatedDOMiDs, v, k);
terminatedDOMiDs.forEach((id) => {
store.deleteFromRegistry(id);
});

if (terminatedDOMiDs.size > 0) {
const recompose = (v: SiblingKeyVal, k: string) =>
recomposeSiblings(store, terminatedDOMiDs, v, k);

SKeys.forEach(recomposeFromKys);
SKeys.forEach(recompose);
} else if (__DEV__) {
if (featureFlags.enableMutationDebugger) {
// eslint-disable-next-line no-console
console.log(`Nothing to unregister.`);
}
}
}

export default DFlexIDGarbageCollector;
13 changes: 1 addition & 12 deletions packages/dflex-dom-gen/src/Generator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -555,22 +555,11 @@ class Generator {
* @param cb - Callback function.
* @returns
*/
destroySiblings(
SK: string,
BK: string,
depth: number,
cb?: ((elmID: string) => void) | null,
): void {
destroySiblings(SK: string, BK: string, depth: number): void {
if (!this._hasSK(SK)) {
return;
}

if (typeof cb === "function") {
while (this._siblings[SK].length) {
cb(this._siblings[SK].pop()!);
}
}

delete this._siblings[SK];

this._removeSKFromDepth(SK, depth);
Expand Down

0 comments on commit 1cb5ff0

Please sign in to comment.