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 🙏

© 2026 – Pkg Stats / Ryan Hefner

artemisa

v1.0.4

Published

React/Redux data fetching API

Readme

wercker status codecov

wercker status

ArtemisaJS

React/Redux data fetching library

Description

Artemisa extends React+Redux with the ability to model interaction with the backend (aka fetches) in a declarative way, reducing boilerplate code and providing a framework with (potential) functionality on the local storage and sync of the data with the back (cache).

It is highliy influenced by Apollo, the graphql client (for react specifically).

In the future it can have LRU cache, and also expiration handling, etc

Usage

yarn add artemisa

Or

npm install -S artemisa

Then you must include Artemisa middleware and reducer into Redux store

import { service, reducer as artemisa } from 'artemisa'

const reducers = combineReducers([artemisa, ...yourReducers])
const store = createStore(
  reducers,
  applyMiddleware(service)
)

Then just use it (see next)

How it works

React components declare data fetching needs by using Artemisa "decorator" function.

import { fetchingData, isFetching, isError, isFetched } from 'artemisa'
import { get } from 'artemisa/lib/core/call'

@fetchingData({
   weather: props => get(`/api/weather/${props.city.code}`)
})
class WeatherChannel extends React.Component {

  render() {
    const { weather, city } = this.props             // HERE WE USE A PROP 
    if (isFetching(weather))
        return <div>Loading...</div>

    if (isError(weather))
        return <div><h1>Error while loading data</h1><p>{weather.error}</p></div>

    if (isFetched(weather))
        return (<div>The current temperature at ${city.name} is ${weather.value.temperature}</div>)

     return <div></div>
  }
}

That's it ! No actions needed, no reducer needed, no async code for http requests. That is all handled by Artemisa.

Code Explanined

The @fetchingData() decorates your component with a higher-order component, in the same way as Redux's connect function. The weather key in the options passed to fetchingData specifies the name of the property Artemisa will inject into your component. This must be in sync with your component's code/properties.

The arrow function associated to the key receives the components props (plus optionally the state) and returns an specification of an http call to be performed.

The component then receives a slot or placeholder with the specified property name (here weather). Artemisa provides functions to check the state of the fetch: isFetching, isError, isFetched.

Fetch execution and Cache

Artemisa willl update your component when one of the properties you used for the call is updated. For example the city in the examples.

But a property change not always triggers a new fetch, and that's where Artemisa cache fits in. Artemisa caches the data based on the URLs.

This means that two fetches with the same URL will trigger just one actual server call. This is useful to optimize server calls when:

  • two different components need the same data from the backend
  • the user navigates to another component and then back, having the same "state", then it won't fetch the same data again, and it will have 0 loading time.

Artemisa implements the cache by using Redux store. So you can inspect the cache, by inspecting the state of the store, and redux actions.

Options

Here is a more complete example of the options for fetchingData

export default fetchingData({
  currentWeather: {
    name: 'weatherAtCity', 
    call: ({ cityName }, { cities.codes }) => get(`/api/weather/${cities[cityName].code}`),
  }
})(MyComponent)

The options provided to fetchingData has the following form

{
    "propName1" : "< FetchDescriptor >",
    "propName2": "< FetchDescriptor >"
}

The keys are basically the names of the props you want Artemisa to inject the objects into your component. So later your component expects to receive this.props.propName1 and this.props.propName2

The FetchDescriptor type has the following form

<FetchingDescriptor> :{
    "name": < String >,
    "call": < (ownProps, state) => Call >
}

Where:

  • name (required): is an id that represents the fetch you are doing. Artemisa uses this to uniquely identify this kind of request. It is like "the key" to store the data in the cache. So later if you use the same key in another component they will share the state and the cache.
  • call (required): a function for creating a Call action object.
  • (optionally other properties to be explained later on this doc)

The call function is the most important and it is where you create the call to the backend. As the call could depend on other properties you receive the props and as you could also want something from the state, you also get the state as a second parameter

Optional fetch properties

There are some extra props that you can specify for different scenarios

Transformations

  • transforming: an optional function to transform the data when it arrives, and before injecting it into the component. For example to transform some dates from string to objects, etc.
const MyComponentWithFetches = fetchingData({
  weather: {
    name: 'weather',      // key to use on store for cache, now optional
    call: (props, state) => auth(get(`getWeather?city=${state.city}`)),
    transforming: value => toFahrenheit(value)
  }
})(MyComponent)

on() (Conditional fetch)

A fetch might depend on certain condition, meaning that Artemisa shouldn't try to fetch everytime, but just if a condition is met. This can be expressed with the "on" property function

const MyComponentWithFetches = fetchingData({
  weather: {
    name: 'weather',      // key to use on store for cache, now optional
    on: (props, state) => state.city !== undefined,
    call: (props, state) => auth(get(`getWeather?city=${state.city}`))
  }
})(MyComponent)

So it will only call the fetch if there is a city in the state.

Slot

The slot has the following properties

  • state : FETCHING, FETCHED, ERROR
  • value: if FETCHED the value from the server
  • error: in case it is ERROR

Further work

In the future the reducer could store more than one result, in kind of a LRU cache, to avoid refetching. It could also store timestamps to consider an expiration date on the cache, to refetch.