Skip to content

Instantly share code, notes, and snippets.

@svnlto
Last active December 9, 2022 03:53
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save svnlto/975f4432f46ed111012a to your computer and use it in GitHub Desktop.
Save svnlto/975f4432f46ed111012a to your computer and use it in GitHub Desktop.
redux pouchdb middleware
import { POUCHDB } from '../middleware/pouchdb';
export const FETCH_MESSAGES_REQUEST = 'FETCH_MESSAGES_REQUEST';
export const FETCH_MESSAGES_SUCCESS = 'FETCH_MESSAGES_SUCCESS';
export const FETCH_MESSAGES_FAILURE = 'FETCH_MESSAGES_FAILURE';
export function fetchMessages() {
return {
[POUCHDB]: {
types: [FETCH_MESSAGES_REQUEST, FETCH_MESSAGES_SUCCESS, FETCH_MESSAGES_FAILURE],
type: 'messages',
method: 'findAll'
}
};
}
export const FETCH_MESSAGE_REQUEST = 'FETCH_MESSAGE_REQUEST';
export const FETCH_MESSAGE_SUCCESS = 'FETCH_MESSAGE_SUCCESS';
export const FETCH_MESSAGE_FAILURE = 'FETCH_MESSAGE_FAILURE';
export function fetchMessage(id) {
return {
[POUCHDB]: {
types: [FETCH_MESSAGE_REQUEST, FETCH_MESSAGE_SUCCESS, FETCH_MESSAGE_FAILURE],
type: 'messages',
method: 'find',
param: id
}
};
}
export const CREATE_MESSAGE_REQUEST = 'CREATE_MESSAGE_REQUEST';
export const CREATE_MESSAGE_SUCCESS = 'CREATE_MESSAGE_SUCCESS';
export const CREATE_MESSAGE_FAILURE = 'CREATE_MESSAGE_FAILURE';
export function addMessage(payload) {
return {
[POUCHDB]: {
types: [CREATE_MESSAGE_REQUEST, CREATE_MESSAGE_SUCCESS, CREATE_MESSAGE_FAILURE],
type: 'messages',
method: 'create',
param: payload
}
};
}
import PouchDB from 'pouchdb';
import utils from '../utils';
const db = new PouchDB('someDB');
/**
*
*/
const find = (id) => {
return db.get(id)
.then(doc => utils.mapCouchDbDocToObject(doc));
};
/**
*
*/
const findAll = () => {
return db.allDocs({
attachments: true,
include_docs: true
})
.then((docs) => {
return docs.rows.map(row => utils.mapCouchDbDocToObject(row.doc));
});
};
/**
*
*/
const create = (payload) => {
return db.post(utils.attachmentsHelper(payload))
.then(result => find(result.id));
};
/**
*
*/
const update = (payload) => {
return find(payload.id)
.then((result) => {
delete payload._rev;
payload._rev = result._rev;
_.extend(result, payload);
return db.put(utils.mapObjectToCouchDbDoc(result))
.then(doc => find(doc.id));
});
};
/**
*
*/
const del = (id) => {
return find(id)
.then(doc => {
doc._deleted = true;
return db.put(utils.mapObjectToCouchDbDoc(doc));
});
};
/**
*
*/
const delAttachment = (id, att) => {
return find(id)
.then(doc => {
return db.removeAttachment(doc.id, att, doc._rev)
.then((d) => find(d.id));
});
};
export default {
find,
findAll,
create,
update,
del,
delAttachment
};
import {
FETCH_MESSAGES_SUCCESS,
CREATE_MESSAGE_SUCCESS
} from '../actions';
function messages(state = [], action) {
let { type, payload } = action;
switch (type) {
case FETCH_MESSAGES_SUCCESS:
return state.concat(payload);
case CREATE_MESSAGE_SUCCESS:
return Object.assign({}, state, {
messages: [...state, {
...payload
}]
});
default:
return state;
}
}
export default messages;
const service from './connector'
const RESET_LOADING_STATE = 'RESET_LOADING_STATE';
// Action key that carries API call info interpreted by this Redux middleware.
export const POUCHDB = Symbol('Pouchdb');
function pouchdb(type, method, param) {
return service[method](param)
.then(response => response)
.catch(err => err);
}
export default function pouchdbMiddleware() {
return next => action => {
const pouchAPI = action[POUCHDB];
if (typeof pouchAPI === 'undefined') {
return next(action);
}
let { type, method, param } = pouchAPI;
const { types } = pouchAPI;
if (typeof type !== 'string') {
throw new Error('Specify a string endpoint URL.');
}
if (!Array.isArray(types) || types.length !== 3) {
throw new Error('Expected an array of three action types.');
}
if (!types.every(type => typeof type === 'string')) {
throw new Error('Expected action types to be strings.');
}
function actionWith(data) {
const finalAction = Object.assign({}, action, data);
delete finalAction[POUCHDB];
return finalAction;
}
const [requestType, successType, failureType] = types;
next(actionWith({
type: requestType,
isLoading: true
}));
return pouchdb(type, method, param)
.then((payload) => {
next(actionWith({
type: RESET_LOADING_STATE
}));
return next(actionWith({
type: successType,
payload
}));
})
.catch((error) => {
next(actionWith({
type: RESET_LOADING_STATE
}));
return next(actionWith({
type: failureType,
error: error.message || 'Something bad happened'
}));
});
};
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment