Catalog npm
Back to packageRELEASE DETAILS

0.1.0

npm

98k

lightweight wrapper based on react, redux and react-router-dom

frameworkfrontendreactredux
Published30 Mar 2018
Direct dependencies5
Transitive dependenciesNot calculated

README

Current package documentation

98k

a lightweight wrapper based on react, redux, redux-saga and react-router-dom, that aims to free you from tedious steps of creating action creators, reducers, sagas etc(inspired by dva).

Install

$ npm install --save 98k

Quick start

index.js

import Kar98k from '98k';
import counter from './counter';

const app = Kar98k();
//app.middleware(middlewares); //apply redux middlewares here

app.module(counter);

app.start('#app');

counter.js

import React from 'react';
import { connect } from '98k';

const Counter = connect(state => state.counter)(({ dispatch, count }) => (
  <div>
    <div>count: {count}</div>
    <button onClick={() => dispatch({
      type    : 'counter/add',
      payload : 1,
    })}>add</button>
  </div>
));

export default {
  namespace : 'counter',
  state     : {
    count: 0,
  },
  reducers: {
    add(state, { payload }) {
      return { ...state, count: state.count + payload };
    },
  },
  routes: {
    '/': { component: Counter },
  },
};

actionType is the key properties of reducers prefixed by namespace.

Options

const app = Kar98k({
  router: 'hash', // 'hash','browser'
  basename: '/',  // the baseUrl used in react-router
});

Asynchronous action

const Counter = connect(state => state.counter)(({ dispatch, count }) => (
  <div>
    <div>count: {count}</div>
    <button onClick={() => dispatch({
      type    : 'counter/asyncAdd',
      payload : 2,
    })}>asyncAdd</button>
  </div>
));

export default {
  namespace : 'counter',
  state     : {
    count: 0,
  },
  effects: {
    *asyncAdd({ payload }, { put, call }, { delay }) {
      yield call(delay, 1000);
      yield put({ type: 'counter/add', payload });
    },
  },
  reducers: {
    add(state, { payload }) {
      return { ...state, count: state.count + payload };
    },
  },
  routes: {
    '/': { component: Counter },
  },
};

Routing

const App = connect(state => state.example)(({ match: { params: { id } } }) => (
  <div>routing example: {id}</div>
));

export default {
  namespace : 'example',
  routes    : {
    '/example/:id': { component: App },
  },
};

Navigate routes programmatically

export default {
  namespace: 'example',
  effects: {
    *redirectToRoutes({ payload }, { call }, { history }) {
      const { data } = call(services.someApi, payload);
      if(data) {
        history.push('/some/routes');
      } else {
        history.push('/other/routes');
      }
    },
  },
};

Error handling

export default {
  namespace : 'counter',
  state     : {
    count: 0,
  },
  effects: {
    *asyncAdd({ payload }, { put, call }, { delay }) {
      yield call(delay, 1000);
      throw 'some error';
      yield put({ type: 'counter/add', payload });
    },
  },
  catch: function*(err, action, { put }) {
    console.log(err);
    console.log(action);
    yield put({ type: 'counter/add', payload });
  },
  reducers: {
    add(state, { payload }) {
      return { ...state, count: state.count + payload };
    },
  },
  routes: {
    '/': { component: Counter },
  },
};

Plugin

you can add plugins via app.use.

index.js

import Kar98k from '98k';
import loading from './loading';
import counter from './counter';

const app = Kar98k();

app.use(loading())
  .module(counter)
  .start('#app');

A plugin is just a function that gets two parameters: injectReducer and injectEffect.

injectReducer is used to add extra reducers.

injectEffect is basically used to add a higher-order function that wraps saga function.

loading.js

export default (injectReducer, injectEffect) => {
  const initialState = {};

  injectReducer({
    loading(state = initialState, { type, payload }) {
      const { namespace } = payload || {};
      switch(type) {
        case '@@98k/show':
          return { 
            ...state, 
            [namespace]: true,
          };
        case '@@98k/hide':
          return { 
            ...state, 
            [namespace]: false,
          };
        default:
          return state;
      }
    },
  });

  injectEffect((saga, module, type, { put, call }, { delay }) => {
    const { namespace } = module;
    return function*(action) {
      yield put({ type: '@@98k/show', payload: { namespace, type } });
      yield saga(action);
      yield call(delay, 1000);
      yield put({ type: '@@98k/hide', payload: { namespace, type } });
    };
  });
}

parameters of injectEffect are:

saga - the current saga function that is being triggered

module - the module object that this saga belongs to

type - type of the current action

and saga helpers.

Downloads & popularity

Awaiting observations

No metric observations yet

Download counts and popularity will appear here as the collector receives them.

Declared dependencies 5

Native requirements
5 direct targetsNot calculated transitive count
Package / targetRequirementRelationship
react
Environment
{
  "local_name": "react",
  "alias": false,
  "peer_metadata": null
}
^16.3.0runtime
react-dom
Environment
{
  "local_name": "react-dom",
  "alias": false,
  "peer_metadata": null
}
^16.3.0runtime
react-redux
Environment
{
  "local_name": "react-redux",
  "alias": false,
  "peer_metadata": null
}
^5.0.7runtime
react-router-dom
Environment
{
  "local_name": "react-router-dom",
  "alias": false,
  "peer_metadata": null
}
^4.2.2runtime
redux
Environment
{
  "local_name": "redux",
  "alias": false,
  "peer_metadata": null
}
^3.7.2runtime

Distribution files

1 collected
Distribution 1

Source distribution

Source file
Checksums from source
{
  "integrity": "sha512-u/CTD7r5H/UXBfZ5SQC8ow13Gl1V/RMyPWYdq6Jiyog+fJxvi0D7UF2p1Z1YRR4d2G5PpJykzSOlapL5aRvCNw==",
  "shasum": "65640bae1f95d21e879350d6ecb69016e630ca67",
  "tarball": "https://registry.npmjs.org/98k/-/98k-0.1.0.tgz",
  "fileCount": 3,
  "unpackedSize": 5726,
  "signatures": [
    {
      "keyid": "SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA",
      "sig": "MEUCIQDoiX/Tcw4qxKxEEXfo2+CtHIYBlca4Vs59sjreQ71q3wIgXHdVqHvIkFOXf/ANOzcotTHXtyfFHM5XYbehBMMF4bw="
    }
  ]
}

Repository

ACCESSIBLE
coiorz/98k

Shared repository data · GitHub

License detected in repository
Not collected
Last push
18 Apr 2018
Archived
No
Contributor identities
— · partial collection

Public sponsor counts have not been collected. These signals belong to the repository owner.

Downloads & popularity

0count
Gauge · observed snapshots22 Oct 2026
10.50
2026-10-22: 0 · observed 2026-10-22T16:06:30.8753448Z
22 Oct22 Oct

github · 1 observations shown. Missing days are unknown.

View observed values
Date / source periodValueObserved at
2026-10-2202026-10-22T16:06:30.8753448Z

Metadata history

Meaningful changes
Current collected state Current

Observed since 20 Oct, 21:33 UTC

No superseded metadata states collected. Unchanged observations do not create new revisions.

Record identity

package_version:447e331743ed67bb03e09ecc0554d897c438fbe9be7b7cea49ebc85857498f29

Other collected versions

0.5.118 Apr0.5.017 Apr0.4.35 Apr0.4.22 Apr0.4.12 Apr0.4.02 AprView all collected versions →