Giter Club home page Giter Club logo

mst-async-storage's Introduction

mst-async-storage

A mobx-state-tree extension granting your models React Native's AsyncStorage powers of persistance.

Requirements

  • mobx-state-tree 2.x or 3.x
  • react-native >= 0.56
  • @react-native-async-storage/async-storage >= 1.x.x

Installing

yarn add mst-async-storage

Usage

The following async actions are added:

import { types } from "mobx-state-tree"
import { withAsyncStorage } from "mst-async-storage"

export const NiceThingsModel = types
  .model("NiceThings")
  .props({
    unicorns: true,
    dragons: true,
    cake: true,
    spiders: false,
    nickleback: false,
  })
  .actions(self => ({
    setSpiders(value: boolean) {
      self.spiders = value
    },
  }))
  .extend(withAsyncStorage({ key: "nice.things" })) // <-- ๐ŸŽ‰

Now you can load it:

async demo () {
  // create your model as usual
  const happy = NiceThingsModel.create()

  // now load the data from async storage
  await happy.load()

  // and when you change something
  happy.setSpiders(true)

  // it will automatically save back to async storage!
}

You can also intercept the snapshot after it is loaded and before it is saved with onLoad and onSave.

import { types } from "mobx-state-tree"
import { withAsyncStorage } from "mst-async-storage"

export const NiceThingsModel = types
  .model("NiceThings")
  .props({
    unicorns: true,
    dragons: true,
    cake: true,
    spiders: false,
    nickleback: false,
  })
  .actions(self => ({
    setSpiders(value: boolean) {
      self.spiders = value
    },
  }))
  .extend(
    withAsyncStorage({
      key: "nice.things",
      // always ensures that nickelback is loaded into MST as `false` here
      onLoad: snapshot => {
        return {
          ...snapshot,
          nickleback: false,
        }
      },
      // always ensures that nickelback is saved to AsyncStorage as `false` here
      onSave: snapshot => {
        return {
          ...snapshot,
          nickelback: false,
        }
      },
    }),
  )

Options

withAsyncStorage() accepts an optional object as a parameter with these keys:

key type what it does
key string The key to use when saving to AsyncStorage (default: the model type name)
autoSave boolean Should we automatically save when any values change on the model? (default: true)
only string, string[] will only include the keys with these names
except string, string[] will omit keys with these names
onLoad (snapshot) => any Will be called after state is loaded from AsyncStorage. Return snapshot to change it.
onSave (snapshot) => any Will be called before AsyncStorage, allowing you to modify the snapshot by returning it.

Contributing?

Yes plz!

Fork it, Clone it, Branch it, Yarn it
Build it, Test it, Push it, PR it

To run the tests, I like to open two shells yarn test:compile:watch and yarn test --watch. If you run ava manually, make sure to add -s to run the tests serially because I fail mocking (because the mocks are shared state and bleed into each other).

mst-async-storage's People

Contributors

danstepanov avatar jamonholmgren avatar semantic-release-bot avatar skellock avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

mst-async-storage's Issues

Load/save hooks

We would like to add a feature that allows app-level code to intercept load/save so that we can do "graceful" migrations as schemas change. I notice, though, that this project seems low activity. Would you like some extra hands? We are heavy users of this extension in the GasBuddy app, which is about to launch (rebuilt in RN) and would be happy to help maintain.

As for the content of this issue, I can make a PR that adds these hooks, unless there's some other way to make migrations work.

Load overrides defaultState

Thanks for the great work.
I have an issue with the package in that it overrides defaultState that I specify in create(). I tried except and only, but both don't seem to work.

export const RootStore = types.model('RootStore', {
    products: types.array(Product),
    boxes: types.array(Box),
    user: types.maybeNull(User)
}).extend(withAsyncStorage({
    key: "MyRootStore",
    only: [
        'user'
    ]
}))

const defaultState = {
    products: [
        {
            id: 1,
            name: 'Red Apple',
            price: 50,
            image: "https://supermart.ae/modules/advancedslider/images/2f49fa65f2818000aed5efe61aaa1418.jpg",
            numberInCart: 1
        }
    ],
    boxes: [
        {
            id: 1,
            name: "Ramadan Box"
        },
    ]
} // This is the default state

const MSTStore = RootStore.create(defaultState); // It will overwrite boxes and products

AsyncStorage.setItem is undefined

Expected Behavior

Running this example, should allow you to toggle the value of spiders without any issues.

Actual Behavior

When running this example, clicking the "Toggle Spiders" button triggers a yellow box warning which suggests that AsyncStorage.setItem is undefined. Within the mst-async-storage library, persist.ts is the only place in which AsyncStorage.setItem is called, outside of with-async-storage.test.ts. The example does seem to work despite this yellow box warning. This PR suggests that this has been an issue for a while, however the PR is out-of-date.

Async Storage seems to be utilized properly, via the documentation. It was installed via expo install @react-native-async-storage/async-storage.

IMG_3135

Steps to Recreate

  1. Clone the example
  2. Run the example via yarn start, open in Expo Go
  3. Click "Toggle Spiders"

Additional Notes

When running yarn, the following is the output which seems like it might be relevant.

โžœ  mst-async-storage-test git:(@danstepanov/[email protected]) โœ— yarn
yarn install v1.22.19
[1/4] ๐Ÿ”  Resolving packages...
[2/4] ๐Ÿšš  Fetching packages...
[1/4] ๐Ÿ”  Resolving packages...
[2/4] ๐Ÿšš  Fetching packages...
[3/4] ๐Ÿ”—  Linking dependencies...
warning " > @react-native-async-storage/[email protected]" has unmet peer dependency "react-native@^0.0.0-0 || 0.60 - 0.68 || 1000.0.0".
warning " > [email protected]" has unmet peer dependency "@types/node@*".
warning Workspaces can only be enabled in private projects.
[4/4] ๐Ÿ”จ  Building fresh packages...
success Saved lockfile.
$ yarn compile && yarn build
yarn run v1.22.19
$ yarn tsc
$ /Users/danielstepanov/Library/Caches/Yarn/v6/.tmp/a56f80e44216870cc6b0fbe19fa28c43.22a6fe49bc0787e82d69f0ff070ea7192a9fb526.prepare/node_modules/.bin/tsc
โœจ  Done in 1.64s.
yarn run v1.22.19
$ BABEL_ENV=production rollup -c rollup.config.ts

build/es/mst-async-storage.js โ†’ dist/mst-async-storage.umd.js, dist/mst-async-storage.es5.js...
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                                                โ”‚
โ”‚   Destination: dist/mst-async-storage.umd.js   โ”‚
โ”‚   Bundle Size:  10.75 KB                       โ”‚
โ”‚   Minified Size:  4.54 KB                      โ”‚
โ”‚   Gzipped Size:  1.53 KB                       โ”‚
โ”‚                                                โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                                                โ”‚
โ”‚   Destination: dist/mst-async-storage.es5.js   โ”‚
โ”‚   Bundle Size:  9.34 KB                        โ”‚
โ”‚   Minified Size:  4.38 KB                      โ”‚
โ”‚   Gzipped Size:  1.44 KB                       โ”‚
โ”‚                                                โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
(!) `this` has been rewritten to `undefined`
https://rollupjs.org/guide/en/#error-this-is-undefined
build/es/with-async-storage.js
1: var __assign = (this && this.__assign) || function () {
                   ^
2:     __assign = Object.assign || function(t) {
3:         for (var s, i = 1, n = arguments.length; i < n; i++) {
...and 3 other occurrences
build/es/persist.js
1: var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
                    ^
2:     function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3:     return new (P || (P = Promise))(function (resolve, reject) {
...and 3 other occurrences
(!) Missing global variable names
Use output.globals to specify browser global variable names corresponding to external modules
mobx-state-tree (guessing 'mobxStateTree')
@react-native-async-storage/async-storage (guessing 'AsyncStorage')
created dist/mst-async-storage.umd.js, dist/mst-async-storage.es5.js in 247ms
โœจ  Done in 0.66s.
[3/4] ๐Ÿ”—  Linking dependencies...
warning " > [email protected]" has incorrect peer dependency "[email protected] || 3.x".
warning "react-native > react-native-codegen > [email protected]" has unmet peer dependency "@babel/preset-env@^7.1.6".
[4/4] ๐Ÿ”จ  Building fresh packages...
success Saved lockfile.
โœจ  Done in 11.75s.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.