@typescript-tea/core
Version:
The Elm Architecture for typescript
56 lines (50 loc) • 2.06 kB
text/typescript
/**
* **Note:** TEA has **managed effects**, meaning that things like HTTP
* requests or writing to disk are all treated as *data* in TEA. When this
* data is given to the TEA runtime system, it can do some “query optimization”
* before actually performing the effect. Perhaps unexpectedly, this managed
* effects idea is the heart of why TEA is so nice for testing, reuse,
* reproducibility, etc.
*
* TEA has two kinds of managed effects: commands and subscriptions.
* @packageDocumentation
*/
import { batchEffects, mapEffect } from "./effect";
// -- COMMANDS
/**
* A command is a way of telling an EffectManager, “Hey, I want you to do this thing!”
* So if you want to send an HTTP request, you would need to command an EffectManager to do it.
* Or if you wanted to ask for geolocation, you would need to command an EffectManager to go
* get it.
* Every `Cmd` specifies (1) which effects you need access to and (2) the type of
* messages that will come back into your application.
* @category Commands
*/
export type Cmd<Action, Home = string> = {
readonly home: Home;
readonly type: string;
/**
* This field is only needed in order to preserve the generic type paramter Action
* @ignore
*/
readonly __$$dummy_tag?: Action;
};
/**
* When you need the runtime system to perform a couple commands, you
* can batch them together. Each is handed to the runtime at the same time,
* and since each can perform arbitrary operations in the world, there are
* no ordering guarantees about the results.
* @category Commands
*/
export function batch<A>(cmds: ReadonlyArray<Cmd<A> | undefined>): Cmd<A> {
return batchEffects(cmds);
}
/**
* If you are using a fractal approach where a Cmd can come from
* a child's update function, you need to map the command in order for it
* to produce an action that can be routed back to the child.
* @category Fancy Stuff
*/
export function map<A1, A2>(actionMapper: (a1: A1) => A2, cmd: Cmd<A1> | undefined): Cmd<A2> | undefined {
return mapEffect(actionMapper, cmd);
}