diff --git a/README.md b/README.md
index 0370fb76c7..7b7924972e 100644
--- a/README.md
+++ b/README.md
@@ -122,7 +122,7 @@ The Appsmith platform is available under the [Apache License 2.0](https://www.ap
 Adam 💻 |
-  Sumanth Yedoti 🔧 💻 |
+  Sumanth Yedoti 💻 |
diff --git a/app/client/src/actions/pageActions.tsx b/app/client/src/actions/pageActions.tsx
index f240ce802f..b18509dde1 100644
--- a/app/client/src/actions/pageActions.tsx
+++ b/app/client/src/actions/pageActions.tsx
@@ -2,6 +2,7 @@ import { FetchPageRequest, SavePageResponse } from "api/PageApi";
import { WidgetOperation, WidgetProps } from "widgets/BaseWidget";
import { WidgetType } from "constants/WidgetConstants";
import {
+ EvaluationReduxAction,
ReduxAction,
ReduxActionTypes,
UpdateCanvasPayload,
@@ -46,9 +47,13 @@ export const fetchPublishedPage = (pageId: string, bustCache = false) => ({
},
});
-export const fetchPageSuccess = () => {
+export const fetchPageSuccess = (
+ postEvalActions: ReduxAction[],
+): EvaluationReduxAction => {
return {
type: ReduxActionTypes.FETCH_PAGE_SUCCESS,
+ payload: {},
+ postEvalActions,
};
};
@@ -60,9 +65,11 @@ export type FetchPublishedPageSuccessPayload = {
export const fetchPublishedPageSuccess = (
payload: FetchPublishedPageSuccessPayload,
-) => ({
+ postEvalActions: ReduxAction[],
+): EvaluationReduxAction => ({
type: ReduxActionTypes.FETCH_PUBLISHED_PAGE_SUCCESS,
payload,
+ postEvalActions,
});
export const updateCurrentPage = (id: string) => ({
diff --git a/app/client/src/actions/widgetActions.tsx b/app/client/src/actions/widgetActions.tsx
index c617e85f35..e75b83e9c0 100644
--- a/app/client/src/actions/widgetActions.tsx
+++ b/app/client/src/actions/widgetActions.tsx
@@ -30,11 +30,10 @@ export const executeActionError = (
export const executePageLoadActions = (
payload: PageAction[][],
-): BatchAction =>
- batchAction({
- type: ReduxActionTypes.EXECUTE_PAGE_LOAD_ACTIONS,
- payload,
- });
+): ReduxAction => ({
+ type: ReduxActionTypes.EXECUTE_PAGE_LOAD_ACTIONS,
+ payload,
+});
export const disableDragAction = (
isDraggingDisabled: boolean,
diff --git a/app/client/src/constants/ReduxActionConstants.tsx b/app/client/src/constants/ReduxActionConstants.tsx
index 692b88d1be..ffd5ae511c 100644
--- a/app/client/src/constants/ReduxActionConstants.tsx
+++ b/app/client/src/constants/ReduxActionConstants.tsx
@@ -410,6 +410,11 @@ export type ReduxActionWithoutPayload = Pick, "type">;
export interface ReduxActionWithMeta extends ReduxAction {
meta: M;
}
+
+export interface EvaluationReduxAction extends ReduxAction {
+ postEvalActions?: ReduxAction[];
+}
+
export interface PromisePayload {
reject: any;
resolve: any;
diff --git a/app/client/src/sagas/PageSagas.tsx b/app/client/src/sagas/PageSagas.tsx
index 3dd72719fd..04ef3fa647 100644
--- a/app/client/src/sagas/PageSagas.tsx
+++ b/app/client/src/sagas/PageSagas.tsx
@@ -43,6 +43,7 @@ import {
select,
takeLatest,
takeLeading,
+ take,
} from "redux-saga/effects";
import history from "utils/history";
import { BUILDER_PAGE_URL } from "constants/routes";
@@ -173,9 +174,12 @@ export function* fetchPageSaga(
// set current page
yield put(updateCurrentPage(id));
// dispatch fetch page success
- yield put(fetchPageSuccess());
- // Execute page load actions
- yield put(executePageLoadActions(canvasWidgetsPayload.pageActions));
+ yield put(
+ fetchPageSuccess([
+ // Execute page load actions after evaluation of fetch page
+ executePageLoadActions(canvasWidgetsPayload.pageActions),
+ ]),
+ );
// Add this to the page DSLs for entity explorer
yield put({
@@ -237,17 +241,19 @@ export function* fetchPublishedPageSaga(
yield put(updateCurrentPage(pageId));
// dispatch fetch page success
yield put(
- fetchPublishedPageSuccess({
- dsl: response.data.layouts[0].dsl,
- pageId: request.pageId,
- pageWidgetId: canvasWidgetsPayload.pageWidgetId,
- }),
+ fetchPublishedPageSuccess(
+ {
+ dsl: response.data.layouts[0].dsl,
+ pageId: request.pageId,
+ pageWidgetId: canvasWidgetsPayload.pageWidgetId,
+ },
+ // Execute page load actions post published page eval
+ [executePageLoadActions(canvasWidgetsPayload.pageActions)],
+ ),
);
- // Execute page load actions
PerformanceTracker.stopAsyncTracking(
PerformanceTransactionName.FETCH_PAGE_API,
);
- yield put(executePageLoadActions(canvasWidgetsPayload.pageActions));
}
} catch (error) {
PerformanceTracker.stopAsyncTracking(
diff --git a/app/client/src/sagas/evaluationsSaga.ts b/app/client/src/sagas/evaluationsSaga.ts
index a5d0ac953f..105edc071a 100644
--- a/app/client/src/sagas/evaluationsSaga.ts
+++ b/app/client/src/sagas/evaluationsSaga.ts
@@ -9,11 +9,15 @@ import {
} from "redux-saga/effects";
import { eventChannel, EventChannel } from "redux-saga";
import {
+ EvaluationReduxAction,
ReduxAction,
ReduxActionErrorTypes,
ReduxActionTypes,
} from "constants/ReduxActionConstants";
-import { getUnevaluatedDataTree } from "selectors/dataTreeSelectors";
+import {
+ getDataTree,
+ getUnevaluatedDataTree,
+} from "selectors/dataTreeSelectors";
import WidgetFactory, { WidgetTypeConfigMap } from "../utils/WidgetFactory";
import Worker from "worker-loader!../workers/evaluation.worker";
import {
@@ -27,12 +31,19 @@ import log from "loglevel";
import _ from "lodash";
import { WidgetType } from "../constants/WidgetConstants";
import { WidgetProps } from "../widgets/BaseWidget";
+import PerformanceTracker, {
+ PerformanceTransactionName,
+} from "../utils/PerformanceTracker";
let evaluationWorker: Worker;
let workerChannel: EventChannel;
let widgetTypeConfigMap: WidgetTypeConfigMap;
const initEvaluationWorkers = () => {
+ // If an old worker exists, terminate it
+ if (evaluationWorker) {
+ evaluationWorker.terminate();
+ }
widgetTypeConfigMap = WidgetFactory.getWidgetTypeConfigMap();
evaluationWorker = new Worker();
workerChannel = eventChannel(emitter => {
@@ -56,7 +67,16 @@ const evalErrorHandler = (errors: EvalError[]) => {
});
};
-function* evaluateTreeSaga() {
+function* postEvalActionDispatcher(actions: ReduxAction[]) {
+ for (const action of actions) {
+ yield put(action);
+ }
+}
+
+function* evaluateTreeSaga(postEvalActions?: ReduxAction[]) {
+ PerformanceTracker.startAsyncTracking(
+ PerformanceTransactionName.DATA_TREE_EVALUATION,
+ );
const unEvalTree = yield select(getUnevaluatedDataTree);
log.debug({ unEvalTree });
evaluationWorker.postMessage({
@@ -73,14 +93,20 @@ function* evaluateTreeSaga() {
type: ReduxActionTypes.SET_EVALUATED_TREE,
payload: parsedDataTree,
});
+ PerformanceTracker.stopAsyncTracking(
+ PerformanceTransactionName.DATA_TREE_EVALUATION,
+ );
+ if (postEvalActions && postEvalActions.length) {
+ yield call(postEvalActionDispatcher, postEvalActions);
+ }
}
export function* evaluateSingleValue(binding: string) {
if (evaluationWorker) {
- const unEvalTree = yield select(getUnevaluatedDataTree);
+ const dataTree = yield select(getDataTree);
evaluationWorker.postMessage({
action: EVAL_WORKER_ACTIONS.EVAL_SINGLE,
- dataTree: unEvalTree,
+ dataTree,
binding,
});
const workerResponse = yield take(workerChannel);
@@ -190,14 +216,19 @@ const EVALUATE_REDUX_ACTIONS = [
function* evaluationChangeListenerSaga() {
initEvaluationWorkers();
- yield call(evaluateTreeSaga);
+ yield fork(evaluateTreeSaga);
while (true) {
- const action: ReduxAction = yield take(EVALUATE_REDUX_ACTIONS);
+ const action: EvaluationReduxAction = yield take(
+ EVALUATE_REDUX_ACTIONS,
+ );
// When batching success action happens, we need to only evaluate
// if the batch had any action we need to evaluate properties for
- if (action.type === ReduxActionTypes.BATCH_UPDATES_SUCCESS) {
+ if (
+ action.type === ReduxActionTypes.BATCH_UPDATES_SUCCESS &&
+ Array.isArray(action.payload)
+ ) {
const batchedActionTypes = action.payload.map(
- (batchedAction: ReduxAction) => batchedAction.type,
+ (batchedAction: ReduxAction) => batchedAction.type,
);
if (
_.intersection(EVALUATE_REDUX_ACTIONS, batchedActionTypes).length === 0
@@ -206,7 +237,7 @@ function* evaluationChangeListenerSaga() {
}
}
log.debug(`Evaluating`, { action });
- yield fork(evaluateTreeSaga);
+ yield fork(evaluateTreeSaga, action.postEvalActions);
}
// TODO(hetu) need an action to stop listening and evaluate (exit app)
}
diff --git a/app/client/src/selectors/dataTreeSelectors.ts b/app/client/src/selectors/dataTreeSelectors.ts
index eabc38fe13..4980b443c1 100644
--- a/app/client/src/selectors/dataTreeSelectors.ts
+++ b/app/client/src/selectors/dataTreeSelectors.ts
@@ -3,7 +3,6 @@ import { getActionsForCurrentPage, getAppData } from "./entitiesSelector";
import { ActionDataState } from "reducers/entityReducers/actionsReducer";
import { DataTree, DataTreeFactory } from "entities/DataTree/dataTreeFactory";
import { getWidgets, getWidgetsMeta } from "sagas/selectors";
-import * as log from "loglevel";
import "url-search-params-polyfill";
import { getPageList } from "./appViewSelectors";
import PerformanceTracker, {
diff --git a/app/client/src/workers/evaluation.worker.ts b/app/client/src/workers/evaluation.worker.ts
index 8d0337d295..76f1cbd31a 100644
--- a/app/client/src/workers/evaluation.worker.ts
+++ b/app/client/src/workers/evaluation.worker.ts
@@ -63,8 +63,7 @@ ctx.addEventListener("message", e => {
}
case EVAL_WORKER_ACTIONS.EVAL_SINGLE: {
const { binding, dataTree } = rest;
- const evalTree = getEvaluatedDataTree(dataTree);
- const withFunctions = addFunctions(evalTree);
+ const withFunctions = addFunctions(dataTree);
const value = getDynamicValue(binding, withFunctions, false);
ctx.postMessage({ value, errors: ERRORS });
ERRORS = [];