Files
advanced-camera-card/src/card-controller/actions/utils/action-state.ts
T

51 lines
1.5 KiB
TypeScript

import type { ActionContext } from 'action';
import { merge } from 'lodash-es';
import type { Action } from '../types';
const setInProgressForThisTarget = (
targetID: string,
context: ActionContext,
contextKey: keyof ActionContext,
action: Action,
): void => {
merge(context, {
[contextKey]: {
[targetID]: {
inProgressAction: action,
},
},
});
};
// `action` is registered before the stop is awaited, so an action that starts
// for this target meanwhile sees `action`.
export const replaceInProgressForThisTarget = async (
targetID: string,
context: ActionContext,
contextKey: keyof ActionContext,
action: Action,
): Promise<void> => {
const replaced = context[contextKey]?.[targetID]?.inProgressAction;
setInProgressForThisTarget(targetID, context, contextKey, action);
await replaced?.stop();
};
// `matcher` decides whether the in-progress action is one this caller may
// stop; on a mismatch the action is left running. Without a matcher, whatever
// is in progress is stopped. The removal is made before the stop is awaited,
// so an action that registers for this target meanwhile is left in place.
export const clearInProgressForThisTarget = async (
targetID: string,
context: ActionContext,
contextKey: keyof ActionContext,
matcher?: (incumbent: Action) => boolean,
): Promise<void> => {
const stopped = context[contextKey]?.[targetID]?.inProgressAction;
if (!stopped || (matcher && !matcher(stopped))) {
return;
}
delete context[contextKey]?.[targetID];
await stopped.stop();
};