diff --git a/app/client/src/sagas/EvaluationsSaga.test.ts b/app/client/src/sagas/EvaluationsSaga.test.ts index 87686bb4a3a1..734acc1cfa8b 100644 --- a/app/client/src/sagas/EvaluationsSaga.test.ts +++ b/app/client/src/sagas/EvaluationsSaga.test.ts @@ -76,6 +76,7 @@ describe("evaluateTreeSaga", () => { widgetsMeta: {}, shouldRespondWithLogs: true, affectedJSObjects: { ids: [], isAllAffected: false }, + actionDataPayloadConsolidated: undefined, }) .run(); }); @@ -121,6 +122,7 @@ describe("evaluateTreeSaga", () => { widgetsMeta: {}, shouldRespondWithLogs: false, affectedJSObjects: { ids: [], isAllAffected: false }, + actionDataPayloadConsolidated: undefined, }) .run(); }); @@ -175,6 +177,7 @@ describe("evaluateTreeSaga", () => { widgetsMeta: {}, shouldRespondWithLogs: false, affectedJSObjects, + actionDataPayloadConsolidated: undefined, }) .run(); }); diff --git a/app/client/src/sagas/EvaluationsSaga.ts b/app/client/src/sagas/EvaluationsSaga.ts index f0b067526904..1b5b657f72c4 100644 --- a/app/client/src/sagas/EvaluationsSaga.ts +++ b/app/client/src/sagas/EvaluationsSaga.ts @@ -249,6 +249,7 @@ export function* evaluateTreeSaga( forceEvaluation = false, requiresLogging = false, affectedJSObjects: AffectedJSObjects = defaultAffectedJSObjects, + actionDataPayloadConsolidated?: actionDataPayload, ) { const allActionValidationConfig: ReturnType< typeof getAllActionValidationConfig @@ -291,6 +292,7 @@ export function* evaluateTreeSaga( widgetsMeta, shouldRespondWithLogs, affectedJSObjects, + actionDataPayloadConsolidated, }; const workerResponse: EvalTreeResponseData = yield call( @@ -545,7 +547,7 @@ export const defaultAffectedJSObjects: AffectedJSObjects = { interface BUFFERED_ACTION { hasDebouncedHandleUpdate: boolean; hasBufferedAction: boolean; - actionDataPayloadConsolidated: actionDataPayload[]; + actionDataPayloadConsolidated: actionDataPayload; } export function evalQueueBuffer() { @@ -682,11 +684,17 @@ function* evalAndLintingHandler( forceEvaluation: boolean; requiresLogging: boolean; affectedJSObjects: AffectedJSObjects; + actionDataPayloadConsolidated: actionDataPayload; }>, ) { const span = startRootSpan("evalAndLintingHandler"); - const { affectedJSObjects, forceEvaluation, requiresLogging, shouldReplay } = - options; + const { + actionDataPayloadConsolidated, + affectedJSObjects, + forceEvaluation, + requiresLogging, + shouldReplay, + } = options; const requiresLinting = getRequiresLinting(action); @@ -728,6 +736,7 @@ function* evalAndLintingHandler( forceEvaluation, requiresLogging, affectedJSObjects, + actionDataPayloadConsolidated, ), ); } @@ -834,6 +843,21 @@ function* evaluationChangeListenerSaga(): any { hasDebouncedHandleUpdate, } = action as unknown as BUFFERED_ACTION; + // when there are + if (hasDebouncedHandleUpdate && hasBufferedAction) { + const affectedJSObjects = getAffectedJSObjectIdsFromAction(action); + + yield call(evalAndLintingHandler, true, action, { + actionDataPayloadConsolidated, + shouldReplay: get(action, "payload.shouldReplay"), + forceEvaluation: shouldForceEval(action), + requiresLogging: shouldLog(action), + affectedJSObjects, + }); + + continue; + } + if (hasDebouncedHandleUpdate) { yield call( evalWorker.request, diff --git a/app/client/src/workers/Evaluation/handlers/evalTree.ts b/app/client/src/workers/Evaluation/handlers/evalTree.ts index c8e53a4fc9e3..b7b41f93b53a 100644 --- a/app/client/src/workers/Evaluation/handlers/evalTree.ts +++ b/app/client/src/workers/Evaluation/handlers/evalTree.ts @@ -34,6 +34,7 @@ import { import type { CanvasWidgetsReduxState } from "reducers/entityReducers/canvasWidgetsReducer"; import type { MetaWidgetsReduxState } from "reducers/entityReducers/metaWidgetsReducer"; import type { Attributes } from "instrumentation/types"; +import { updateActionsToEvalTree } from "./updateActionData"; // TODO: Fix this the next time the file is edited // eslint-disable-next-line @typescript-eslint/no-explicit-any @@ -70,6 +71,7 @@ export async function evalTree( let isNewWidgetAdded = false; const { + actionDataPayloadConsolidated, affectedJSObjects, allActionValidationConfig, appMode, @@ -190,6 +192,10 @@ export async function evalTree( }); staleMetaIds = dataTreeResponse.staleMetaIds; } else { + const tree = dataTreeEvaluator.getEvalTree(); + + updateActionsToEvalTree(tree, actionDataPayloadConsolidated); + if (dataTreeEvaluator && !isEmpty(allActionValidationConfig)) { dataTreeEvaluator.setAllActionValidationConfig( allActionValidationConfig, @@ -212,6 +218,7 @@ export async function evalTree( configTree, webworkerTelemetry, affectedJSObjects, + actionDataPayloadConsolidated, ), ); diff --git a/app/client/src/workers/Evaluation/handlers/updateActionData.ts b/app/client/src/workers/Evaluation/handlers/updateActionData.ts index dadf1f5654e5..b3c94cc57dc7 100644 --- a/app/client/src/workers/Evaluation/handlers/updateActionData.ts +++ b/app/client/src/workers/Evaluation/handlers/updateActionData.ts @@ -4,6 +4,7 @@ import set from "lodash/set"; import { evalTreeWithChanges } from "../evalTreeWithChanges"; import DataStore from "../dataStore"; import { EVAL_WORKER_SYNC_ACTION } from "ee/workers/Evaluation/evalWorkerActions"; +import type { DataTree } from "entities/DataTree/dataTreeTypes"; export interface UpdateActionProps { entityName: string; @@ -26,6 +27,29 @@ export function handleActionsDataUpdate(actionsToUpdate: UpdateActionProps[]) { const evalTree = dataTreeEvaluator.getEvalTree(); + updateActionsToEvalTree(evalTree, actionsToUpdate); + + const updatedProperties: string[][] = []; + + actionsToUpdate.forEach(({ dataPath, entityName }) => { + updatedProperties.push([entityName, dataPath]); + }); + evalTreeWithChanges({ + data: { + updatedValuePaths: updatedProperties, + metaUpdates: [], + }, + method: EVAL_WORKER_SYNC_ACTION.EVAL_TREE_WITH_CHANGES, + webworkerTelemetry: {}, + }); +} + +export function updateActionsToEvalTree( + evalTree: DataTree, + actionsToUpdate?: UpdateActionProps[], +) { + if (!actionsToUpdate) return; + for (const actionToUpdate of actionsToUpdate) { const { dataPath, dataPathRef, entityName } = actionToUpdate; let { data } = actionToUpdate; @@ -44,18 +68,4 @@ export function handleActionsDataUpdate(actionsToUpdate: UpdateActionProps[]) { DataStore.setActionData(path, data); } - - const updatedProperties: string[][] = []; - - actionsToUpdate.forEach(({ dataPath, entityName }) => { - updatedProperties.push([entityName, dataPath]); - }); - evalTreeWithChanges({ - data: { - updatedValuePaths: updatedProperties, - metaUpdates: [], - }, - method: EVAL_WORKER_SYNC_ACTION.EVAL_TREE_WITH_CHANGES, - webworkerTelemetry: {}, - }); } diff --git a/app/client/src/workers/Evaluation/types.ts b/app/client/src/workers/Evaluation/types.ts index 97adaa6fc2b4..c6b6a777e782 100644 --- a/app/client/src/workers/Evaluation/types.ts +++ b/app/client/src/workers/Evaluation/types.ts @@ -18,6 +18,7 @@ import type { APP_MODE } from "entities/App"; import type { WebworkerSpanData, Attributes } from "instrumentation/types"; import type { ICacheProps } from "../common/AppComputationCache/types"; import type { AffectedJSObjects } from "actions/EvaluationReduxActionTypes"; +import type { actionDataPayload } from "actions/pluginActionActions"; // TODO: Fix this the next time the file is edited // eslint-disable-next-line @typescript-eslint/no-explicit-any @@ -51,6 +52,7 @@ export interface EvalTreeRequestData { widgetsMeta: Record; shouldRespondWithLogs?: boolean; affectedJSObjects: AffectedJSObjects; + actionDataPayloadConsolidated?: actionDataPayload; } export interface EvalTreeResponseData { diff --git a/app/client/src/workers/common/DataTreeEvaluator/index.ts b/app/client/src/workers/common/DataTreeEvaluator/index.ts index 8f2eb2f09557..920814659ae6 100644 --- a/app/client/src/workers/common/DataTreeEvaluator/index.ts +++ b/app/client/src/workers/common/DataTreeEvaluator/index.ts @@ -155,6 +155,7 @@ import { getDataTreeContext } from "ee/workers/Evaluation/Actions"; import { WorkerEnv } from "workers/Evaluation/handlers/workerEnv"; import type { WebworkerSpanData, Attributes } from "instrumentation/types"; import type { AffectedJSObjects } from "actions/EvaluationReduxActionTypes"; +import type { UpdateActionProps } from "workers/Evaluation/handlers/updateActionData"; type SortedDependencies = Array; export interface EvalProps { @@ -637,6 +638,7 @@ export default class DataTreeEvaluator { configTree: ConfigTree, webworkerTelemetry: Record = {}, affectedJSObjects: AffectedJSObjects = { isAllAffected: false, ids: [] }, + actionDataPayloadConsolidated?: UpdateActionProps[], ): { unEvalUpdates: DataTreeDiff[]; evalOrder: string[]; @@ -677,7 +679,7 @@ export default class DataTreeEvaluator { // Since eval tree is listening to possible events that don't cause differences // We want to check if no diffs are present and bail out early - if (differences.length === 0) { + if (differences.length === 0 && !actionDataPayloadConsolidated?.length) { return { removedPaths: [], unEvalUpdates: [], @@ -724,7 +726,12 @@ export default class DataTreeEvaluator { this.dependencies = dependencies; this.inverseDependencies = inverseDependencies; - const pathsChangedSet = new Set(); + const pathsChangedSet = new Set( + actionDataPayloadConsolidated?.map(({ dataPath, entityName }) => [ + entityName, + dataPath, + ]) || [], + ); for (const diff of differences) { if (isArray(diff.path)) { @@ -741,10 +748,18 @@ export default class DataTreeEvaluator { undefined, webworkerTelemetry, () => { + const pathsToSkipFromEval = + actionDataPayloadConsolidated + ?.map(({ dataPath, entityName }) => { + return [entityName, dataPath]; + }) + .map((path: string[]) => path.join(".")) || []; + return this.setupTree(updatedUnEvalTreeJSObjects, updatedValuePaths, { dependenciesOfRemovedPaths, removedPaths, translatedDiffs, + pathsToSkipFromEval, }); }, );