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

actstore

v0.0.39

Published

Just global store solution using react hooks, context and fetchier

Downloads

62

Readme

ActStore

Just global store solution using react hooks and fetchier. Works with ReactNative and ReactWeb

Install

  • npm install actstore

Getting Started

STEP 1 - Initiating the store.

actstore is using subscription concept to handle global state, each use of useActStore() in a React component will subscribe that component to the global store on component mounted and will be unsubscribed when that component is unmounted.

import React from 'react'
import Actstore from 'actstore'
import AsyncStorage from '@react-native-community/async-storage' //for react native
import JSCookies from 'js-cookie' //for react web

const Cookies = JSCookies || {
	set: AsyncStorage.setItem,
	get: AsyncStorage.getItem,
	clear: AsyncStorage.clear
}

export default () => {
  // Initiates actstore and returns `store` and `act` arguments
  const { store, act } = Actstore({ actions, configs, Cookies }, ['ready'])
  // Trigger init action
  useEffect(() => { act('APP_INIT') }, [])
  // Render Views
  return (</>)
}

// Actions can be used using act or action
const actions = ({ store }) => ({
  APP_INIT: async () => {
    await store.set({ count: 1, ready: true })
  }
})

// Config
import { version } from '../package.json';
const CFG = process.env

const DOMAIN = CFG.DOMAIN || 'test.project.com'
const API_URL = 'https://'+ DOMAIN +'/api'

const configs = {
  ENV: CFG.env || CFG.NODE_ENV,
  GQL_URL: 'https://' + DOMAIN + '/v1alpha1/graphql',
  WSS_URL: 'wss://' + DOMAIN + '/v1alpha1/graphql',
  endpoints: {
    areas: API_URL + '/areas/',
    upload: API_URL + '/upload',
    qr: API_URL + '/qr',
    login: API_URL + '/login'
  },
  routes: {
    index: { link: '/', title: 'Home', icon: 'home' },
    login: { link: '/login', title: 'Login' },
    register: { link: '/register', title: 'Register' }
  },
  ver: CFG.npm_package_version || version
}

STEP 2 - Use global store and actions in Component.

actstore has convenience React hooks useActStore() which can get and set store actions to global store.
You can use act() method to execute specified action. We have a bunch of default actions from fetchier like GQL, POST, GET, OPEN, CLOSE, PUT, SUB, UNSUB
Actions have access to act and store to perform other actions inside the actions.
You can set the global store value in action by triggering store.set({ newState })

import React from 'react'
import useActStore from 'actstore';
import { Card } from 'src/elems'

export default props => {
  const { act, store } = useActStore(actions)
  const { socket, stats } = store.get('socket')
  useEffect(() => { socket && act('STATS_FETCH') }, [socket])

  return (
    <div>
      {stats && stats.map(item => <Card key={item.label} {...item} />)}
    </div>
  );
};

const actions = ({ act, store }) => ({
  STATS_FETCH: () =>
    !store.get('stats') &&
    act('GQL', {
      query: `
        fetchStatistic {
          consumersOverall: Consumer_aggregate{ aggregate{ count } }
          comsumersPending: Consumer_aggregate(where: { status: { _eq: 0}}){ aggregate{ count } }
          comsumersActive: Consumer_aggregate(where: { status: { _eq: 1}}){ aggregate{ count } }
          comsumersDeclined: Consumer_aggregate(where: { status: { _eq: 8}}){ aggregate{ count } }

          merchantsOverall: Merchant_aggregate{ aggregate{ count } }
          merchantsPending: Merchant_aggregate(where: { status: { _eq: "0"}}){ aggregate{ count } }
          merchantsActive: Merchant_aggregate(where: { status: { _eq: "1"}}){ aggregate{ count } }
          merchantsDeclined: Merchant_aggregate(where: { status: { _eq: "8"}}){ aggregate{ count } }
        }
      `
    })
      .then(stats => {
        const data = Object.keys(stats).reduce(
          (obj, key) => ({ ...obj, [key]: stats[key].aggregate.count }),
          {}
        );

        return {stats: [
          {
            label: 'consumers',
            total: data.consumersOverall,
            pendingNumber: data.comsumersPending,
            activatedNumber: data.comsumersActive,
            declinedNumber: data.comsumersDeclined
          },
          {
            label: 'merchants',
            total: data.merchantsOverall,
            pendingNumber: data.merchantsPending,
            activatedNumber: data.merchantsActive,
            declinedNumber: data.merchantsDeclined
          }
        ]}
      })
      .then(store.set)
});