npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

vuex-saga-ts

v0.20.2

Published

Nothing but a simple plugin connecting redux-saga in ts with some utils

Downloads

7

Readme

Vuex Saga Plugin in TS

version license

vuex-saga-ts just was a vuex plugin connecting redux-saga and it also provided some utils which might help some especially for a project in typescript. My new project called for some complicated-side-effect controls in Vuex, and I missed redux-saga a lot. Thus I created this to simplify my life. Meanwhile hope it could also help some others as well.

Setup

  • First of all, we have to install it
    
    yarn add vuex-saga-ts

#    or

    npm install vuex-saga-ts
  • Then init and inject it with the root saga function as one vuex plugin when you create vuex. And leave the work to the root saga to clear.

  • If needed, we can set dispatchSagaAction to true at the second argument option to dispatch saga actions into mutations, like VuexSagaPlugin(rootSaga, {dispatchSagaAction:true}), by default it is disabled.

src/store/index.ts

import Vue from 'vue'
import Vuex, { Store } from 'vuex'
import { VuexSagaPlugin } from 'vuex-saga-ts';
import rootSaga from './sagas';

Vue.use(Vuex);
const store:Store<any> = new Vuex.Store({
  state:{
    version: '1.0.0',
  },
  plugins:[
    VuexSagaPlugin(rootSaga )
  ],
  modules:{
  }
});

export default store;
  • Since veux-saga-ts extends the default Store type of vuex, a type definition file is suggested created at your project root to extends vuex store types. Along with it, the temp composition api extension definition are also suggested.

src/vuex-saga-ts.d.ts

import Vue from 'vue';
import {SagaDispatchActionFun, SagaDispatchFun} from "vuex-saga-ts";

declare module '@vue/composition-api/dist/component/component' {
    interface SetupContext {
        readonly refs: { [key: string]: Vue | Element | Vue[] | Element[] };
    }
}

declare module 'vuex' {
    interface Store<S>{
        sagaDispatch:SagaDispatchFun;
        sagaDispatchAction:SagaDispatchActionFun;
    }
}

Usage

Action Creators

We provide an action creator createAction

import { createAction } from 'vuex-saga-ts'

export const SagaActions = {
    start:createAction<void>('APPLICATION_START')
}
  • createAction can take two parameters, the first, a required action type string, and then the second optional payload creator
  • The first generic type of createAction is the payload type, and the rest will be input parameter types of the payload creator function; four subsequent types at most after the payload type
  • The return type of createAction is a function whose toString will always return the type string

Use mapSagaActions to map into methods

<template>
    <button @click="APPLICATION_START()">Start</button>

</template>
<script>
import Vue from 'vue'
import {mapSagaActions} from 'vuex-saga-ts'
export const SampleComp = Vue.extend({
    methods:{
        ...mapSagaActions(['APPLICATION_START']),    
    }
})
</script>

Use Composition Api instead to inject

At my early stage of learning Vue.js, the feature I missed the most is hook-api from react world; thus, with due respect, I will call vue's composition apis into hook apis for short.

Using hooks, components do not need to map methods and passing them around any more. Hooks are the ideal wrapper to encapsulate the connection to vuex.

vuex-saga-ts extends the store of vuex with two additional functions

    interface Store<S>{
        sagaDispatch:(type:string,payload:any) => void;
        sagaDispatchAction:(action:Action) => void;
    }

As you can tell by the type, they are used to dispatch action into saga chanel. Therefore we could easily wrapper these action creators into a hook.

src/composables/compzApplicatoinCtx.ts

import { reactive, toRefs } from '@vue/composition-api';

import { SagaActions } from '@/store/application'

import { mainStoreInjector } from './MainStore'
import {IApplicationState} from "@/store/application/types";

interface IApplicaitonCtx {
    state:IApplicationState,
    actions:{
        start:()=>void;
    }
}

export function compzApplicatoinCtx():IApplicaitonCtx{
    const {store} = mainStoreInjector();

    const applicationsState = reactive(store.state.application);

    return {
        // @ts-ignore
        state:toRefs(applicationsState),
        actions:{
            start: ()=>{store.sagaDispatchAction(SagaActions.start())}
        }
    };

}

src/views/Home.vue

<template>
  <div class="home">
    <img
            :class="['animated', 'infinite', {
              'flash': loading,
              'tada' : !loading,
            }]"
            alt="Vue logo" src="../assets/logo.png">

    <h4 v-if="loading">Loading..</h4>
    <h4 v-else>Loaded~</h4>

    <HelloWorld msg="Welcome to Your Vue.js App"/>

  </div>
</template>

<script>
import { onMounted ,createComponent } from '@vue/composition-api';
import { compzApplicatoinCtx } from '@/composables/compzApplicatoinCtx';
import HelloWorld from '@/components/HelloWorld.vue'

export default createComponent({
  name:'home',
  components:{
    HelloWorld
  },
  setup(){
    const {
      loading,
      actions:{start}
    } = compzApplicatoinCtx();

    onMounted(()=>{
      start()
    });

    return {
      loading
    }

  }
})
</script>

Sample Project

This short markdown might not explain all details suggested, thus checking out the sample project in the sample folder should bring the gist of using this plugin.

Credits

This plugin is nothing but a connector. Great thanks to redux-saga for rescuing me from the crisis of handling changing requirements in my previous projects.