Skip to content

Instantly share code, notes, and snippets.

@spencercarli
Created February 3, 2017 15:21
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save spencercarli/44a20bf23953e5e50f8c725f05137055 to your computer and use it in GitHub Desktop.
Save spencercarli/44a20bf23953e5e50f8c725f05137055 to your computer and use it in GitHub Desktop.
react-native-meteor-offline
import Meteor from 'react-native-meteor';
import { AsyncStorage } from 'react-native';
import { createStore, applyMiddleware } from 'redux';
import createLogger from 'redux-logger';
import { persistStore, autoRehydrate } from 'redux-persist';
import _ from 'lodash';
import reducer from './reducer';
// Actions
export const ADDED = 'ddp/added';
export const CHANGED = 'ddp/changed';
export const REMOVED = 'ddp/removed';
const onRehydration = (store) => {
const data = Meteor.getData();
const db = data && data.db;
if (db) {
_.each(store.getState(), (collectionData, collectionName) => {
if (!db[collectionName]){
db.addCollection(collectionName);
}
const collectionArr = _.map(collectionData, (doc, _id) => {
doc._id = _id;
return doc;
});
db[collectionName].upsert(collectionArr)
});
}
};
export const initializeMeteorOffline = (opts = {}) => {
// Store
const logger = createLogger({ predicate: () => opts.log || false });
const store = createStore(reducer, applyMiddleware(logger), autoRehydrate());
persistStore(store, {
storage: AsyncStorage,
keyPrefix: 'react-native-meteor-offline:',
debounce: opts.log || 1000,
}, () => onRehydration(store));
// Listeners
Meteor.ddp.on('added', (payload) => {
store.dispatch({ type: ADDED, payload });
});
Meteor.ddp.on('changed', (payload) => {
store.dispatch({ type: CHANGED, payload });
});
Meteor.ddp.on('removed', (payload) => {
store.dispatch({ type: REMOVED, payload });
});
};
import _ from 'lodash';
import { ADDED, CHANGED, REMOVED } from './index';
import { REHYDRATE } from 'redux-persist/constants'
const add = (state, action) => {
const { collection, id, fields } = action.payload;
if (!state[collection]) {
state[collection] = {};
return {
...state,
[collection]: {
[id]: fields,
},
};
} else if (!state[collection][id]) {
return {
...state,
[collection]: {
...state[collection],
[id]: fields,
},
}
} else {
return {
...state,
[collection]: {
...state[collection],
[id]: { ...fields, ...state[collection][id] },
}
};
}
};
const change = (state, action) => {
const { collection, id, fields } = action.payload;
return {
...state,
[collection]: {
...state[collection],
[id]: _.merge(state[collection][id], fields),
},
};
};
const remove = (state, action) => {
const { collection, id } = action.payload;
if (state[collection] && state[collection][id]) {
return {
...state,
[collection]: _.omit(state[collection], id),
};
}
};
export default (state = {}, action) => {
switch (action.type) {
case ADDED:
return add(state, action);
case CHANGED:
return change(state, action);
case REMOVED:
return remove(state, action);
case REHYDRATE:
return action.payload;
default:
return state;
}
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment