Code Monkey home page Code Monkey logo

ddp-redux's Introduction

ddp

Build Status

ddp-redux is a brand new ddp client that will allow you to fetch resources from your ddp server in a completely declarative way. Subscriptions/ methods (queries) parameters are evaluated by selectors and all you need to do is to extract collection data from the redux store. This approach was highly inspired by apollo-client, but the DDP protocol is the first class citizen in our case.

An example is worth a thousand words

import ddp from 'ddp-connector';

const TodoList = ddp({
  subscriptions: (state, props) => [{
    name: 'api.collections.TodoLists.details',
    params: [{
      listId: props.listId,
    }],
  }, {
    name: 'api.collections.Todos.all',
    params: [{
      listId: props.listId,
    }],
  }],
  selectors: ({ from, prop }) => ({
    todoList: from('TodoLists').select.one('listId'),
    todos: from('Todos').select.where(
      createSelector(
        prop('listId'),
        listId => todo => todo.listId === listId,
      ),
    ),
  }),
})(({ todoList, todos }) => (
  <div>
    <h1>{todoList.name}</h1>
    <ul>
      {todos.map(todo => (<li key={todo._id}>{todo.title}</li>))}
    </ul>
  </div>
))

Most typical DDP "commands" are accessible by simply dispatching a redux action, e.g.

import { callMethod } from 'ddp-redux';

// ...

store.dispatch(
  callMethod(
    'myTestMethod',
    param1,
    param2,
    param3,
  ))
  .then(/* ... */)
  .catch(/* ... */)
);

Disclaimer

The project is still in a pretty early stage and it does not have proper documentation yet, as some parts of the api are very likely to change, e.g. documents selectors.

Running example app

Assuming yoy have [email protected] installed you only need to run

cd example
./start.sh

If you want to play with the code and need to ensure that the libraries are rebuilding automatically use

./start-develop.sh

Installation

npm install --save ddp-redux ddp-connector

If you don't have them already please install the following peer dependencies

npm install --save react redux react-redux

Minimal configuration

import { createStore, combineReducers, applyMiddleware } from 'redux';
import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import DDPClient from 'ddp-redux';

const ddpClient = new DDPClient({
  endpoint: 'ws://localhost:3000/websocket',
  SocketConstructor: WebSocket,
});

const reducer = combineReducers({
  ddp: DDPClient.reducer(),
});

const store = createStore(
  reducer,
  {},
  applyMiddleware(
    ddpClient.middleware(),
  ),
);

ReactDOM.render(
  <Provider store={store}>
    // ...
  </Provider>
  document.getElementById('root'),
);

Features

  • Supports Meteor standard authentication methods
  • Meteor subscriptions
  • Fetch data via meteor methods
  • Aggregate data from multiple ddp connections
  • Basic support for optimistic updates
  • Sync local ids generator with server
  • Out-of-the-box support for client-side joins
  • Offline first

ddp-redux's People

Contributors

apendua avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

Forkers

bacancy-suresh

ddp-redux's Issues

Clarify how entities should be extracted from query result

Probably the easiest way is to assume that the result will come in some predefined format, e.g.

{
   entities: {
     users: {
       1: { name: 'user1' },
       // ...
     },
  },
}

but it may not be acceptable for someone who is trying to connect to an existing ddp server. Instead we should probably have a flexible solution that allows user to provide their own algorithm.

Allow rendering loader as overlay

Currently, loader always replaces the real content. But sometimes it's useful to render it as an overlay. It can be easily done by simply checking subscriptionsReady prop.

Add plugins system to allow custom queries

Currently, a query always call a ddp method, but it does need to be the case. We should abstract a query result producer and allow users to define their custom producers.

Add helpers to build messaging pipelines

E.g. if a new user was created in the system, reload all queries that returned information about users collection:

ddp({
   messages: {
      'message.user.created': ({ dispatch }) =>
         () => dispatch(reloadQueries({ collection: 'users' })),
   },
})

Simplify optimistic results

This is already possible for side-effects, but it requires manually attaching a special meta key to the dispatched action. It's not an ideal solution though.

We will also need to provide the original Random.id() generator to ensure optimistic ids are in sync with what meteor generates server-side.

Implement offline mode

Of course, calling methods should be disabled in offline in general, but sometimes offline is caused by a temporary problem with internet connection, so we need to be careful about that.

Another thing is that in offline mode we should not remove any cached data, add allow resolving cached subscriptions with a disclaimer that the data may not be up-to-date. But offline should not break the ability to preview the data that's already cached.

Another thing is that the current state of redux store should be saved in some kind of persistent storage, so even if user reloads the page, they can still see the same cached version of the data.

Add ability to short-circuit a method call

E.g.

  1. When a method parameters validator returns an error, we can throw immediately instead of sending a message to the server. This is already doable manually, but it would be nice to have a native support for such behavior.
  2. Sometimes we may want to simulate a successful method call, e.g. when we want to debounce the final server call, but still have all intermediate state updated in redux store. This is especially useful in all types of editors.

Add option to save resume tokens in redux store

For components that need to use session token to perform custom requests, e.g. upload a file, it may be more natural to grab the token from redux store rather than access another type of storage.

Ensure outdated documents are removed when subscription is restored

When ddp connection is lost and a document is removed on the server before we re-connect the corresponding message will not reach the client. So when connection is re-established and we attempt to restore our subscriptions we need to flag all cached data that is bound to the broken socket as "obsolete" and replace it with new data once all subscriptions are restored.

Add helpers for creating "join" selectors

E.g.

ddp({
   selectors: ({ from }) => ({
     // return all books and add author field
     books: from('books').select.all().join('users').via('authorId', 'author'),
   }),
})

Implement method "wait" mode

Currently we only have methods priorities, which is good enough for most scenarios, e.g. ensure that login always happens before a regular method. But sometimes a more explicit control may be required.

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.