Motivation.
I am working in a startup. At first I was the only dev in my company and the best choice in speed and quality was Meteor. We also needed few mobile apps and we choosed Ionic. Working with naked DDP was a hell of the thing especially to non-experienced Meteor developer like me. Projects like Asteroid didn’t provide the proper functionality and documentation for DDP outside the Meteor world and not being maintained for few years. Our team started to grow and frontend developers not familiar with Meteor faced certain issues like learning new framework and build tools (Meteor), connecting their frontend framework with Meteor, pushing updates to UI in production without building the whole project in pipelines etc (and we started to think about client-less Meteor). So I decided to make a simple DDP library that would be something like a starter pack ‘everything you need to start working on a Meteor client outside the Meteor and be productive no matter what js frameworks or libs you use’. That’s how simpleDDP was born.
I built simpleDDP on top of Mondora’s ddp.js lib which I used in first versions of the apps.
SimpleDDP has
Full documentation
Examples for Node.js and Ionic 3 (looking forward to any PR to add more examples)
Plugin system (for now only one plugin for authorization, PR are welcome)
Lots of promises, so you can use async/await with ease.
Collections storage (actual state of all data you have got from your subscriptions)
Built-in change listener for collections and objects inside the collections
SimpleDDP is battle tested in production, is maintained because our team uses it and it will continue to improve. We are going to add more examples and frontend recipes sharing our experience of working with Meteor.
I am using techniques that are included in simpleDDP .
For example you can fetch filtered objects from your collection and get plain js array like so
let myItems = server.collection('somecoll').filter(el=>el.cat=='supercat').fetch();
If you want some storage variable to be reactive you can use onChange
let myStorage;
let a = server.collection('somecoll').filter(el=>el.cat=='supercat');
myStorage = a.fetch();
a.onChange(()=>{
myStorage = a.fetch();
})
There are a lot of things you can do with simpleDDP, checkout readme, examples and docs
P.S. I have updated simpleDDP to v1.1.8 so there will be no error if you use techniques I described above and there is no data inside the collections (or no collection at all).
Several bugs were fixed, new test added and most important changes are:
Shallow copying was replaced with deep cloning js objects
ddpFilter.onChange() triggers even when a next state of an object successfully passes the filter. If prev and next are both not false you can check which passes the filter with new argument predicatePassed . It is an array of two booleans , predicatePassed[0] is for prev and predicatePassed[1] is for next.
@cloudspider I was also inspired by your question so I decided to implement reactive collection fetching and introduce few more important things! It will be in 1.2.0 version which comes out soon.
Awsome! As someone maintaining an Electron app that needs to interact with Meteor, I might switch to this solution because we had problems with every other implementation of this.
@cloudspider@francisbou The would be cool, the more environments we use the better! I will write here when 1.2.0 come out (a few days, I am on finish line) and would appreciate any help in bug detecting, usage examples etc.
After testing out mobile app we have found two bugs in simpleDDP 1.1.9. First one - subscription readiness (both promise and callback) was always true and other bug was with mutating EventEmitter’s message in the first listener, so other listeners on the same event received modified message.
@gregivy I’ve finished the initial steps for the Vue integration package. Its now possible to connect a Vue or Nuxt project easily to Meteor’s DDP system by simply specify a plugin. The plugin options are passed down to the SimpleDDP package and it uses isomorphic-ws by default to simplify the setup
I have plans to implement a Vuex version aswell. This should automatically do the subscription handling, support SSR and makes uses of simple getter functions along the lines of:
@cloudspider Nice work, I’m glad you have started it! It would be super cool if we have such easy solution for vue!
I saw in source that you you such construction:
But it won’t work as you expected, because simpleDDP.sub take a subscription name as a first argument and an array of parameters (optional) for the subscription as a second argument.
However collection.fetch will return you not a promise but a raw js array of what you have in your collection or [ ] (if there is none). So you can’t await it.
This line will guarantee you that you have something inside the collection, and when you fetch it using
this.find('articles');
You will receive a copy of what you have in your collection at the moment of fetching, it is not reactive.
SimpleDDP 1.2.0 is coming out and it will have zero-dependant reactive data source both for the collections, filtered collections and objects, built-in smart sorting, improved subscriptions. So I suggest to use reactive source inside your find function when it came out. I am working on guide right now!
The subscription method uses the spread operator. This means that I can add any kind of second parameter to the api.sub method including an array.
About the find function. Its indeed a non-reactive function. I’m doing this to make it easy to include it as SSR feature. It still needs to be connected to Vue’s reactivity system, but I want to wait with it, because of your next release.
The reactive part will also become a Vuex feature since that store uses convinient methods to pull this off easily.
That said. Not sure if this is the right approach. I’m always open for feedback
About the fetch part. Thanks for that. The example code for find should not have had the await part. I will remove this
I see your point, I am not familiar with Vue.js, but I am going to make reactivity by mutating the returned object. So it will be a plain js array or object anyway, just like now. Is it ok for SSR?
@gregivy Congratulations and thank you very much for this amazing work! I am developing a chrome extension connected to a Meteor back-end and was upset with the DDP clients currently available.
One question I have open is: Since it is not possible to require modules on chrome extensions without a huge workaround, is there a way I can use your DDP directly on my project? (I mean, instead of installing through NPM and then requiring)
What do I need to do to call methods through simpleDDP on my chrome extension’s popup?
Should I import { simpleDDP } from bundle.js on my popup.js file?