@johngw/stream
Version:
Reactive programming tools using the WHATWG Streams API.
72 lines (71 loc) • 2.82 kB
text/typescript
import { StateReducerInput, StateReducerOutput, StateReducers } from '@johngw/stream/transformers/stateReducer';
import { Subject, SubjectOptions } from '@johngw/stream/subjects/Subject';
import { ControllableStream } from '@johngw/stream/sources/ControllableStream';
/**
* The constructor options for a {@link StatefulSubject}.
*
* @group Subjects
*/
interface StatefulSubjectOptions<Actions extends Record<string, unknown>, State> extends Omit<SubjectOptions<StateReducerInput<Actions>, StateReducerOutput<Actions, State>>, 'forkable' | 'transform'> {
pipeThroughOptions?: StreamPipeOptions;
}
/**
* Another form of the {@link Subject:class} that reduces a piece
* of state with actions and queues changes to the stream.
*
* It's important to note that if the result of an action does not change
* the state then nothing is queued to the stream.
*
* @group Subjects
* @see {@link stateReducer:function}
* @example
* ```
* // The State will be the type of data you want to manipulate.
* interface State {
* authors: string[]
* }
*
* // The Actions are a record of "action name" to a parameter.
* // If the action doesn't require a parameter, use `void`.
* type Actions = {
* 'add author': string
* 'action that doesnt need a parameter': void
* }
*
* // To get the best out of this API, pass the Actions type and State
* // during construction.
* const subject = new StatefulSubject<Actions, State>(
* {
* __INIT__: () => ({ authors: [] }),
*
* 'add author': (state, author) => state.authors.includes(author) ? state : {
* ...state,
* authors: [...state.authors, author],
* },
*
* 'action that doesnt need a parameter': (state) => state
* }
* )
*
* subject.fork().pipeTo(write(console.info))
* // { action: '__INIT__', state: { authors: [] } }
*
* subject.dispatch('add author', 'Jane Austin')
* // { action: 'add author', param: 'Jane Austin', state: { authors: ['Jane Austin'] } }
*
* subject.dispatch('add author', 'Jane Austin')
* // **Nothing will be queued as the state did not change.**
* ```
*/
export declare class StatefulSubject<Actions extends Record<string, unknown>, State> extends Subject<StateReducerInput<Actions>, StateReducerOutput<Actions, State>> {
constructor(reducers: StateReducers<Actions, State>, options?: StatefulSubjectOptions<Actions, State>);
/**
* Returns a new {@link StatefulControllableStream}. Once all controllers
* have been closed, then the source is also closed.
*/
control(): StatefulSubjectController<Actions>;
}
export interface StatefulSubjectController<Actions extends Record<string, unknown>> extends ControllableStream<StateReducerInput<Actions>> {
dispatch<Action extends keyof Actions>(action: Action, param?: Actions[Action]): void;
}
export {};