Scenario
Conceptually, Scenario
is a sequence of events, that are described by a piece of promise-based code. It is designed to simplify state management and asynchronous control flow in your application.
Scenario may start instantly or may be triggered by promise-like objects.
type Trigger<T> = PromiseLike<T> | (() => PromiseLike<T>);
type Callback<T, R> = (value: T) => R;
interface Config {
id: string;
tags: [];
strategy: 'fork' | 'cyclic' | 'once';
}
function scenario<T, R>(callback: Callback<T, R>, config?: Partial<Config>): Scenario<T, R>;
function scenario<T, R>(trigger: Trigger<T>, callback: Callback<T, R>, config?: Partial<Config>): Scenario<T, R>;
Strategies
- fork - runs scenarios in parallel
- cyclic - runs scenario only if previous one is completed
- once - run scenario only one time
Default strategy
By default instant scenarios use cyclic
strategy, whereas scenarios with trigger use fork
strategy.
Examples
Scenario of writing every counter change into sessionStorage
scenario(counter.events.changed, (value) => {
sessionStorage.setItem('counter', value);
});
Scenario that re-fetches data every N seconds or by clicking a refresh button
// Trigger may be a function returning a promise.
// This makes it possible to combine multiple promise-likes.
const dataRevalidateScenario = scenario(
() => Promise.any([delay(REFETCH_INTERVAL), refresh.events.invoked]),
async () => {
const data = await fetchData();
dataState.set(data);
},
{ strategy: 'cyclic' }
);
Scenario has its events, which may be used to trigger another scenario
scenario(dataRevalidateScenario.events.completed, () => {
console.log('Data revalidated')
});
Other types
Other types
export interface CompletedEvent<T, R> {
event: T;
result: R;
config: Config;
}
export interface StartedEvent<T> {
event: T;
config: Config;
}
export interface Scenario<T, R> {
events: {
completed: AwaiEvent<CompletedEvent<T, R>>;
failed: AwaiEvent<unknown>;
started: AwaiEvent<StartedEvent<T>>;
};
}