Giter Site home page Giter Site logo

mobx-sync's People

Contributors

acrazing avatar dependabot[bot] avatar emilyemorehouse avatar fossabot avatar guoxiaoyang avatar todorone 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  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  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  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

mobx-sync's Issues

MobX should be declared in peerDependencies section

I found that mobx-sync requires mobx in dependencies section. In my case I use mobx 4.8 but mobx-sync installed 5.8 (because of "mobx": "*"). So I cannot use it with IE11.

I think that mobx should be declared in peerDependencies section something like this:

"peerDependencies": {
  "mobx": "^4.3.1 || ^5.0.0"
},

Inverted behaviour

Is it possible to achieve the inverted behaviour when only specifically decorated properties will be synced with the storage, but all others will not sync by default?

How the fallback works? And errors question

Just found this! I was writing my own mobx persistent lib, but this one will save me some time.

If the data isn't locally found, it will keep the initial value?

Also, if there is an error during the save/load, will there be any Error throw?

re-hyrdate/de-serialise JS Date or custom type

Hi, thanks for the lib!

Any guidance on how to rehydrate an object property of type JS Date or a custom type e.g. a Moment date. They persist fine to a string value as they implement the native JS serialisation interface i.e. toJSON(). But just need a way to run when re-hyrdating the save state to call a custom function with code like new Moment(value).

I saw this todo comment in the source code about this requirement.

The @serlizer lib has an @date decorator and a custom decorator.

no releases?

this code has no releases on github and no changelog..

Example of how to use without decorators?

I am new to this library, but my project is based without decorators because create-react-app does not support them. And the workarounds for supporting decorators could be detrimental to performance/stability.

How do I use this without decorators?

Handling actions on classes.

I'm using mobx-sync in a React application to persist state for an offline mode. One issue I am facing is that when persisting a store that has an array of objects where those objects have actions for modifying their state, when initialized from storage the JS objects in the store know nothing about the methods that were on the object when it was first added. I can see what, and why the problem is occurring, but at a loss to what would be the best way to address it.

So if I have a ProfileStore that contains a set of Options and ProfileStore has actions to add an option, that is fine. But if Option has an action to update state, after loading that store and it's Options, the loaded Option throws "... is not a function" exceptions. Obviously the array of Option state is not "typed" to the Option class that is defined. I'm left wondering if there is a way to deserialize them in a way that is recognized as that type, or a best practice to alter the structure so that the actions don't rely on the state. I would like options to live under a profile store rather than trying to juggle separate stores for loosely coupled objects.

Computed property not working after hydration

I have something like this:

import { observable, computed } from "mobx";

export class EnvironmentModel {
  @observable public id: string;
  @observable public name: string;

  constructor(id: string, name: string) {
    this.id = id;
    this.name = name;
  }

   @computed get initials() {
     let tokens = this.name.split(" ");
     let res = "blah";
     if (tokens.length === 1) {
       res = tokens[0].slice(0, 2);
     } else {
       res = tokens[0][0] + tokens[1][0];
     }

     return res;
   }

}
import { EnvironmentModel } from "../model";
import { RootStore } from "./Root.store";
import { observable, action } from "mobx";
import { ignore } from "mobx-sync";

let localEnv = new EnvironmentModel("local", "Local Environment");

export class EnvironmentStore {
  @ignore root: RootStore;

  @observable.shallow public current: EnvironmentModel = localEnv;
  @observable.shallow
  public environments: EnvironmentModel[] = observable.array([localEnv]);

  constructor(root: RootStore) {
    this.root = root;
  }

  // TODO: Placeholder function
  @action
  public loginToEnvironment(envName: string, email: string, password: string) {
    let newEnv = new EnvironmentModel(envName, envName);
    this.environments.push(newEnv);
    this.switchEnvironment(newEnv.id);
  }

  @action switchEnvironment(envId: string) {
    let env = this.environments.find(e => e.id === envId);
    if (!env) {
      // do something a toast or w/e
      return;
    }

    this.current = env;
  }
}

Everything works fine the first time when the objects are created on runtime, but once my store is rehydrated upon application load, the computed initials is no longer working and returns undefined.

Any idea why this might be happening? Am I doing something wrong?

Not working for arrays

Storing objects is working fine but when it's an array it's not persisted.

@observable list = [{a: '1', b: '2'}];

@format @date decorators broken for nested items in observable array

Both work on the parent store:

export class TodoListStore {
  @date date2:any
  @format((value) => new moment(value)) date:any

  @observable todos: TodoItem[] = []
}

But do not work on the sub-classes.

export class TodoItem {
   @ignore id: string;

  @date date2:any
  @format((value) => new moment(value)) date:any
}

@ignore works on the subclass - the serialise logic is good, but the de-serialise logic is broken.

When I debug parse-store.ts, the todos observable hits this line only and does not recursively then call parseStore() on the nested object

else if (mobx_1.isObservableArray(storeValue)) {
                // mobx array
                store[key] = mobx_1.observable.array(dataValue);
            }

Maybe this gives a clue?

Incredibly slow refresh times

Often on a dev server, I will want to refresh the page. However, using this library, refreshes can take 10-15 seconds. Is this normal, or is it specific to my setup?

Using formatters with TS interface

I have a simple interface

interface Todo {
  title: string;
  deadline: Date;
}

And it persists correctly.
But is there a way for rehydrating Date object without rewriting this to class? I know, that this would be simple class, it's just I don't want to use one when it's not needed.

mjs modules aren't compatible with react-create-app

This looks to be related to issue #14, but running a React application with mobx-sync results in import errors. Even the most basic example results in the error:
Can't import the named export '__assign' from non EcmaScript module (only default export is available)

I can see from issue #14 that the suggested fix is a webpack change, however with react-create-app this would require ejecting the configuration to try and tweak the webpack settings, which I would like to avoid since it isn't reversible. Is there a way that I can rebuild the mobx-sync package to be ECMAScript compatible, or otherwise reference it in a way that the module shaker will understand?

Project maintenance

I just wanted to reach out and check if this project is still being (or will be) maintained.

I quite like it, but have noticed a few issues lately with compatibility of dependencies. The biggest being that it seems this library is incompatible with mobx 6. Also it seems the library only supports the deprecated version of the AsyncStorage library in React Native (https://reactnative.dev/docs/asyncstorage).

Thanks for all your work here!

ReactJs TypeScript - AsyncTrunk is not a constructor

I had issues on mobx-persist and I saw that this package would fit my needs. However, following the tutorial.. I am already getting an error I am stuck at:

Uncaught TypeError: mobx_sync__WEBPACK_IMPORTED_MODULE_9__.AsyncTrunk is not a constructor
at Module.eval (main.tsx?5177:15)
at eval (main.tsx:67)
at Module../main.tsx (app.856980a5f3b10010e12e.js:625)
at webpack_require (856980a5f3b10010e12e.js:785)
at fn (856980a5f3b10010e12e.js:151)
at Object.0 (app.856980a5f3b10010e12e.js:638)
at webpack_require (856980a5f3b10010e12e.js:785)
at checkDeferredModules (856980a5f3b10010e12e.js:46)
at Array.webpackJsonpCallback [as push] (856980a5f3b10010e12e.js:33)
at app.856980a5f3b10010e12e.js:1

import * as React from 'react';
import * as ReactDOM from 'react-dom';
import {Provider} from 'mobx-react';
import {RootStores} from 'app/stores';
import {App} from 'app';
import {createBrowserHistory} from "history";
import {AsyncTrunk} from "mobx-sync";

// prepare MobX stores
const history = createBrowserHistory();
const stores = new RootStores(history).getStoresInstances();
const trunk = new AsyncTrunk(stores, {
    /**
     * @desc custom storage: built in storage is supported
     *  - localStorage
     *  - sessionStorage
     *  - ReactNative.AsyncStorage
     */
    storage: localStorage as any,
    /**
     * @desc custom storage key, the default is `__mobx_sync__`
     */
    storageKey: '__persist_mobx_stores__',
});

trunk.init().then(() => {
    // render react DOM
    console.log("// render react DOM");
    ReactDOM.render(
        <Provider {...stores}>
            <App history={history}/>
        </Provider>,
        document.getElementById('root')
    );
});

tons of import errors

in my code, i import like this:

import {AsyncTrunk} from "mobx-sync";

results in:

ERROR in ./node_modules/mobx-sync/lib/index.mjs 10:0-37
Can't reexport the named export 'AsyncTrunk' from non EcmaScript module (only default export is available)
 @ ./src/main.tsx
 @ multi (webpack)-dev-server/client?http://localhost:8082 ./src/main.tsx

ERROR in ./node_modules/mobx-sync/lib/index.mjs 13:0-35
Can't reexport the named export 'SyncTrunk' from non EcmaScript module (only default export is available)
 @ ./src/main.tsx
 @ multi (webpack)-dev-server/client?http://localhost:8082 ./src/main.tsx

ERROR in ./node_modules/mobx-sync/lib/index.mjs 14:0-34
Can't reexport the named export 'config' from non EcmaScript module (only default export is available)
 @ ./src/main.tsx
 @ multi (webpack)-dev-server/client?http://localhost:8082 ./src/main.tsx

ERROR in ./node_modules/mobx-sync/lib/index.mjs 11:0-70
Can't reexport the named export 'date' from non EcmaScript module (only default export is available)
 @ ./src/main.tsx
 @ multi (webpack)-dev-server/client?http://localhost:8082 ./src/main.tsx

ERROR in ./node_modules/mobx-sync/lib/index.mjs 11:0-70
Can't reexport the named export 'format' from non EcmaScript module (only default export is available)
 @ ./src/main.tsx
 @ multi (webpack)-dev-server/client?http://localhost:8082 ./src/main.tsx

Failed to compile. Can't import the named export '__awaiter' from non EcmaScript module

I'm using new create-react-app app with typescript. Everything was installed correctly.

Error:

Failed to compile.

/Users/alder/node_modules/mobx-sync/lib/async.mjs
Can't import the named export '__awaiter' from non EcmaScript module (only default export is available)

Code:

import { AsyncTrunk } from 'mobx-sync/lib/async'
import { rootStore } from './stores';

const trunk = new AsyncTrunk(rootStore, { storage: localStorage })
trunk.init().then(() => {
    ReactDOM.render(<App />, document.getElementById('root'));    
})

packages.json:

  "dependencies": {
    "@material-ui/core": "^4.0.0-alpha.8",
    "axios": "^0.19.0-beta.1",
    "crypto-ts": "^1.0.2",
    "formik": "^1.5.4",
    "history": "^4.9.0",
    "lodash": "^4.17.11",
    "mobx": "^5.9.4",
    "mobx-react": "beta",
    "mobx-state-router": "^4.0.5",
    "react": "^16.8.6",
    "react-dom": "^16.8.6",
    "react-input-mask": "^2.0.4",
    "react-scripts": "^3.0.0",
    "styled-components": "^4.2.0",
    "yup": "^0.27.0"
  },
  "devDependencies": {
    "@types/history": "^4.7.2",
    "@types/lodash": "^4.14.123",
    "@types/material-ui": "^0.21.6",
    "@types/react": "^16.8.14",
    "@types/react-dom": "^16.8.4",
    "@types/react-input-mask": "^2.0.1",
    "@types/styled-components": "^4.1.14",
    "@types/yup": "^0.26.12",
    "@typescript-eslint/eslint-plugin": "^1.7.0",
    "eslint-config-prettier": "^4.2.0",
    "eslint-config-typescript": "^2.0.0",
    "eslint-plugin-react": "^7.12.4",
    "husky": "^2.1.0",
    "lint-staged": "^8.1.5",
    "prettier": "^1.17.0",
    "typescript": "^3.4.5"
  },

No types?

Hey im getting a bunch of errors when trying to use this in my Typescript project.

Im using the version from npm yarn add mobx-sync but it tells me that its missing the type definitions for the module?

I also get runtime errors saying that there are multiple versions of mobx running at once? Perhaps the mobx dependency needs to be peer?

Any way to handle persistence exceptions?

Local storage is not unlimited, so persistence can sometimes result in failure. Is there any way to detect and respond to this happening when using mobx-sync?

An example of an error that can show up on the console log,
cycle reference occurred > Array [] sync.js:30

Can't get @ignore to work

Hi, thanks for the lib, really liking it so far :)

However, I'm not able to make the @ignore decorator work. All of the fields are persisted correctly (and the observer is reacting correctly on updates).

This is a snippet of my store class:

class Store {
  @ignore
  @observable
  movieData: TMovies | null = null;

  ... other observable fields
}

I've tried the @ignore.ssr and @ignore.ssrOnly variations but the movieData is always persisted.

As extra context, I'm using this with mobx-react like:

function createStore() {
  return new Store();
}


export const StoreProvider: FC = ({children}) => {
  const store = useLocalStore(createStore);
  const [storeReady, setStoreReady] = useState(false);

  const trunk = new AsyncTrunk(store, {
    storage: AsyncStorage,
    storageKey: 'key2',
  });

  useEffect(() => {
    trunk.init().then(() => {
      setStoreReady(true);
    });
  }, []);

  return (
    <Context.Provider value={store}>
      {storeReady ? (
        children
      ) : (
          <Loader />
      )}
    </Context.Provider>
  );
};

Am I doing something wrong?

Persist Multiple Stores?

I am attempting to utilize your package to persist multiple mobx stores as per the example here and have my stores setup in a similar fashion to this:

/*   RootStore.js  */
import {UserStore, TodoStore } from './index.js'
import { AsyncTrunk } from 'mobx-sync';
import AsyncStorage from '@react-native-community/async-storage';

class RootStore {
    constructor() {
        this.userStore = new UserStore()
        this.todoStore = new TodoStore()
    }
}

const rootStore = new RootStore();

const trunk = new AsyncTrunk(rootStore, {
  storageKey: 'myAppStore',
  storage: AsyncStorage,
  onError: error => console.error('TRUNK ERROR', error)
});

export { rootStore, RootStore, trunk };

/*  UserStore.js  */
import {rootStore} from './RootStore.js'

class UserStore {
    constructor(rootStore) {
        this.rootStore = rootStore
    }

    getTodos(user) {
        // access todoStore through the root store
        return this.rootStore.todoStore.todos.filter((todo) => todo.author === user)
    }
}

/*  TodoStore.js */
import {rootStore} from './RootStore.js'

class TodoStore {
    @observable todos = []

    constructor(rootStore) {
        this.rootStore = rootStore
    }
}

I then call the following function to hydrate the stores on app start:

const initApp = () => {
  trunk.init().then(() => {
    console.log('hydrate done', rootStore.userStore); //always undefined
  }
}

rootStore.userStore is always undefined, how can I persist multiple stores using this package?

Thanks.

mobx: 5.15.4
react-native: 0.61.5
mobx-sync: 3.0.0
@react-native-community/async-storage: 1.11.0

Can't import @format @date @regexp

I couldn't import the new decorators in v0.6.0 in my app using:
import { format, date, regexp } from 'mobx-sync

I believe you have missed exporting them in index.ts.

I added this line to the file, which fixed the issue:
export { format,date,regexp } from './format';

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.