All Projects → aikoven → Typescript Fsa

aikoven / Typescript Fsa

Licence: mit
Type-safe action creator utilities

Programming Languages

typescript
32286 projects

Labels

Projects that are alternatives of or similar to Typescript Fsa

Vueflux
♻️ Unidirectional State Management Architecture for Swift - Inspired by Vuex and Flux
Stars: ✭ 315 (-46.43%)
Mutual labels:  flux
Gank
干货集中营 app 安卓实现,基于 RxFlux 架构使用了 RxJava、Retrofit、Glide、Koin等
Stars: ✭ 444 (-24.49%)
Mutual labels:  flux
Redux Api
Flux REST API for redux infrastructure
Stars: ✭ 502 (-14.63%)
Mutual labels:  flux
Fluxor
Fluxor is a zero boilerplate Flux/Redux library for Microsoft .NET and Blazor.
Stars: ✭ 338 (-42.52%)
Mutual labels:  flux
Reactjs101
從零開始學 ReactJS(ReactJS 101)是一本希望讓初學者一看就懂的 React 中文入門教學書,由淺入深學習 ReactJS 生態系 (Flux, Redux, React Router, ImmutableJS, React Native, Relay/GraphQL etc.)。
Stars: ✭ 4,004 (+580.95%)
Mutual labels:  flux
React Starter Kit
React Starter Kit — front-end starter kit using React, Relay, GraphQL, and JAM stack architecture
Stars: ✭ 21,060 (+3481.63%)
Mutual labels:  flux
Fluorine
[UNMAINTAINED] Reactive state and side effect management for React using a single stream of actions
Stars: ✭ 287 (-51.19%)
Mutual labels:  flux
Model Zoo
Please do not feed the models
Stars: ✭ 580 (-1.36%)
Mutual labels:  flux
React Native Train
I use this book to train my team, help them to know how to build React-native app in the right way.
Stars: ✭ 407 (-30.78%)
Mutual labels:  flux
Microcosm
Flux with actions at center stage. Write optimistic updates, cancel requests, and track changes with ease.
Stars: ✭ 484 (-17.69%)
Mutual labels:  flux
Reactor Core
Non-Blocking Reactive Foundation for the JVM
Stars: ✭ 3,891 (+561.73%)
Mutual labels:  flux
Dutier
The immutable, async and hybrid state management solution for Javascript applications.
Stars: ✭ 401 (-31.8%)
Mutual labels:  flux
Nylas Mail
💌 An extensible desktop mail app built on the modern web.
Stars: ✭ 473 (-19.56%)
Mutual labels:  flux
Grox
Grox helps to maintain the state of Java / Android apps.
Stars: ✭ 336 (-42.86%)
Mutual labels:  flux
Reatom
State manager with a focus of all needs
Stars: ✭ 567 (-3.57%)
Mutual labels:  flux
Kunidirectional
The goal of this sample app is to show how we can implement unidirectional data flow architecture based on Flux and Redux on Android... using Kotlin 😉
Stars: ✭ 303 (-48.47%)
Mutual labels:  flux
Normalizr
Normalizes nested JSON according to a schema
Stars: ✭ 20,721 (+3423.98%)
Mutual labels:  flux
Beauty Vuejs Boilerplate
❤️ Real world base Vue.js app. Access/refresh tokens auth, api services, http client, vuex modules
Stars: ✭ 583 (-0.85%)
Mutual labels:  flux
React Native Nw React Calculator
Mobile, desktop and website Apps with the same code
Stars: ✭ 5,116 (+770.07%)
Mutual labels:  flux
Almin
Client-side DDD/CQRS for JavaScript.
Stars: ✭ 477 (-18.88%)
Mutual labels:  flux

TypeScript FSA npm version Build Status

Action Creator library for TypeScript. Its goal is to provide type-safe experience with Flux actions with minimum boilerplate. Created actions are FSA-compliant:

interface Action<Payload> {
  type: string;
  payload: Payload;
  error?: boolean;
  meta?: Object;
}

Installation

npm install --save typescript-fsa

Usage

Basic

import actionCreatorFactory from 'typescript-fsa';

const actionCreator = actionCreatorFactory();

// Specify payload shape as generic type argument.
const somethingHappened = actionCreator<{foo: string}>('SOMETHING_HAPPENED');

// Get action creator type.
console.log(somethingHappened.type);  // SOMETHING_HAPPENED

// Create action.
const action = somethingHappened({foo: 'bar'});
console.log(action);  // {type: 'SOMETHING_HAPPENED', payload: {foo: 'bar'}}

Async Action Creators

Async Action Creators are objects with properties started, done and failed whose values are action creators. There is a number of Companion Packages that help with binding Async Action Creators to async processes.

import actionCreatorFactory from 'typescript-fsa';

const actionCreator = actionCreatorFactory();

// specify parameters and result shapes as generic type arguments
const doSomething =
  actionCreator.async<{foo: string},   // parameter type
                      {bar: number},   // success type
                      {code: number}   // error type
                     >('DO_SOMETHING');

console.log(doSomething.started({foo: 'lol'}));
// {type: 'DO_SOMETHING_STARTED', payload: {foo: 'lol'}}

console.log(doSomething.done({
  params: {foo: 'lol'},
  result: {bar: 42},
}));
// {type: 'DO_SOMETHING_DONE', payload: {
//   params: {foo: 'lol'},
//   result: {bar: 42},
// }}

console.log(doSomething.failed({
  params: {foo: 'lol'},
  error: {code: 42},
}));
// {type: 'DO_SOMETHING_FAILED', payload: {
//   params: {foo: 'lol'},
//   error: {code: 42},
// }, error: true}

Actions With Type Prefix

You can specify a prefix that will be prepended to all action types. This is useful to namespace library actions as well as for large projects where it's convenient to keep actions near the component that dispatches them.

// MyComponent.actions.ts
import actionCreatorFactory from 'typescript-fsa';

const actionCreator = actionCreatorFactory('MyComponent');

const somethingHappened = actionCreator<{foo: string}>('SOMETHING_HAPPENED');

const action = somethingHappened({foo: 'bar'});
console.log(action);
// {type: 'MyComponent/SOMETHING_HAPPENED', payload: {foo: 'bar'}}

Redux

// actions.ts
import actionCreatorFactory from 'typescript-fsa';

const actionCreator = actionCreatorFactory();

export const somethingHappened =
  actionCreator<{foo: string}>('SOMETHING_HAPPENED');
export const somethingAsync =
  actionCreator.async<{foo: string},
                      {bar: string}
                     >('SOMETHING_ASYNC');


// reducer.ts
import {Action} from 'redux';
import {isType} from 'typescript-fsa';
import {somethingHappened, somethingAsync} from './actions';

type State = {bar: string};

export const reducer = (state: State, action: Action): State => {
  if (isType(action, somethingHappened)) {
    // action.payload is inferred as {foo: string};

    action.payload.bar;  // error

    return {bar: action.payload.foo};
  }

  if (isType(action, somethingAsync.started)) {
    return {bar: action.payload.foo};
  }

  if (isType(action, somethingAsync.done)) {
    return {bar: action.payload.result.bar};
  }

  return state;
};

redux-observable

// epic.ts
import {Action} from 'redux';
import {Observable} from 'rxjs';
import {somethingAsync} from './actions';

export const epic = (actions$: Observable<Action>) =>
  actions$.filter(somethingAsync.started.match)
    .delay(2000)
    .map(action => {
      // action.payload is inferred as {foo: string};

      action.payload.bar;  // error

      return somethingAsync.done({
        params: action.payload,
        result: {
          bar: 'bar',
        },
      });
    });

Companion Packages

Resources

API

actionCreatorFactory(prefix?: string, defaultIsError?: Predicate): ActionCreatorFactory

Creates Action Creator factory with optional prefix for action types.

  • prefix?: string: Prefix to be prepended to action types as <prefix>/<type>.
  • defaultIsError?: Predicate: Function that detects whether action is error given the payload. Default is payload => payload instanceof Error.

ActionCreatorFactory<Payload>#(type: string, commonMeta?: object, isError?: boolean): ActionCreator<Payload>

Creates Action Creator that produces actions with given type and payload of type Payload.

  • type: string: Type of created actions.
  • commonMeta?: object: Metadata added to created actions.
  • isError?: boolean: Defines whether created actions are error actions.

ActionCreatorFactory#async<Params, Result, Error>(type: string, commonMeta?: object): AsyncActionCreators<Params, Result, Error>

Creates three Action Creators:

  • started: ActionCreator<Params>
  • done: ActionCreator<{params: Params, result: Result}>
  • failed: ActionCreator<{params: Params, error: Error}>

Useful to wrap asynchronous processes.

  • type: string: Prefix for types of created actions, which will have types ${type}_STARTED, ${type}_DONE and ${type}_FAILED.
  • commonMeta?: object: Metadata added to created actions.

ActionCreator<Payload>#(payload: Payload, meta?: object): Action<Payload>

Creates action with given payload and metadata.

  • payload: Payload: Action payload.
  • meta?: object: Action metadata. Merged with commonMeta of Action Creator.

isType(action: Action, actionCreator: ActionCreator): boolean

Returns true if action has the same type as action creator. Defines Type Guard that lets TypeScript know payload type inside blocks where isType returned true:

const somethingHappened = actionCreator<{foo: string}>('SOMETHING_HAPPENED');

if (isType(action, somethingHappened)) {
  // action.payload has type {foo: string}
}

ActionCreator#match(action: Action): boolean

Identical to isType except it is exposed as a bound method of an action creator. Since it is bound and takes a single argument it is ideal for passing to a filtering function like Array.prototype.filter or RxJS's Observable.prototype.filter.

const somethingHappened = actionCreator<{foo: string}>('SOMETHING_HAPPENED');
const somethingElseHappened =
  actionCreator<{bar: number}>('SOMETHING_ELSE_HAPPENED');

if (somethingHappened.match(action)) {
  // action.payload has type {foo: string}
}

const actionArray = [
  somethingHappened({foo: 'foo'}),
  somethingElseHappened({bar: 5}),
];

// somethingHappenedArray has inferred type Action<{foo: string}>[]
const somethingHappenedArray = actionArray.filter(somethingHappened.match);

For more on using Array.prototype.filter as a type guard, see this github issue.

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].