PromucFlow_constructor/app/client/src/sagas/ActionExecution/SetIntervalSaga.ts
Anand Srinivasan db38a64e71
chore: update imports for code split (#19085)
* move actionTriggers.ts

* update imports Explorer/helpers.tsx

* update imports EntityDefinitions.ts

* update imports Evaluation/Actions.ts

* update imports for ActionExecutionSagas

* missed worker types

* missed imports

* update imports for dataTreeUtils

* missed imports

Co-authored-by: Aishwarya UR <aishwarya@appsmith.com>
2022-12-22 12:04:28 +05:30

85 lines
2.4 KiB
TypeScript

import {
ClearIntervalDescription,
SetIntervalDescription,
} from "@appsmith/entities/DataTree/actionTriggers";
import {
executeAppAction,
TriggerMeta,
} from "@appsmith/sagas/ActionExecution/ActionExecutionSagas";
import { call, delay, spawn } from "redux-saga/effects";
import { EventType } from "constants/AppsmithActionConstants/ActionConstants";
import {
logActionExecutionError,
TriggerFailureError,
} from "sagas/ActionExecution/errorUtils";
const TIMER_WITHOUT_ID_KEY = "timerWithoutId";
const activeTimers: Record<string, true | string> = {
[TIMER_WITHOUT_ID_KEY]: true,
};
export function* setIntervalSaga(
payload: SetIntervalDescription["payload"],
eventType: EventType,
triggerMeta: TriggerMeta,
) {
if (payload.id) {
activeTimers[payload.id] = payload.callback;
}
yield spawn(executeInIntervals, payload, eventType, triggerMeta);
}
function* executeInIntervals(
payload: SetIntervalDescription["payload"],
eventType: EventType,
triggerMeta: TriggerMeta,
) {
const { callback, id = TIMER_WITHOUT_ID_KEY, interval } = payload;
while (
// only execute if the id exists in the activeTimers obj
id in activeTimers &&
/*
While editing the callback can change for the same id.
At that time we want only execute the new callback
so end the loop if the callback is not the same as the one this
saga was started
But if no id is provided, it will always run
*/
(activeTimers[id] === callback || id === TIMER_WITHOUT_ID_KEY)
) {
// Even if there is an error, the set interval should still keep
// running. This is according to the spec of setInterval
try {
yield call(executeAppAction, {
dynamicString: `{{${callback}}}`,
// pass empty object to execute it as a callback function
callbackData: [{}],
event: { type: eventType },
triggerPropertyName: triggerMeta.triggerPropertyName,
source: triggerMeta.source,
});
} catch (error) {
logActionExecutionError(
(error as Error).message,
triggerMeta.source,
triggerMeta.triggerPropertyName,
);
}
yield delay(interval);
}
}
export function* clearIntervalSaga(
payload: ClearIntervalDescription["payload"],
) {
if (!(payload.id in activeTimers)) {
throw new TriggerFailureError(
`Failed to clear interval. No timer active with id "${payload.id}"`,
);
}
delete activeTimers[payload.id];
}