├── .meteor ├── .finished-upgraders ├── .gitignore ├── .id ├── packages ├── platforms ├── release └── versions ├── packages └── rethinkdb │ ├── .npm │ └── package │ │ ├── .gitignore │ │ ├── README │ │ └── npm-shrinkwrap.json │ ├── package.js │ └── rethinkdb.js ├── readme.md └── server ├── 0_init.js ├── 2_types.js ├── 3_mutations.js ├── 4_queries.js └── 5_schema.js /.meteor/.finished-upgraders: -------------------------------------------------------------------------------- 1 | # This file contains information which helps Meteor properly upgrade your 2 | # app when you run 'meteor update'. You should check it into version control 3 | # with your project. 4 | 5 | notices-for-0.9.0 6 | notices-for-0.9.1 7 | 0.9.4-platform-file 8 | notices-for-facebook-graph-api-2 9 | 1.2.0-standard-minifiers-package 10 | 1.2.0-meteor-platform-split 11 | 1.2.0-cordova-changes 12 | 1.2.0-breaking-changes 13 | -------------------------------------------------------------------------------- /.meteor/.gitignore: -------------------------------------------------------------------------------- 1 | local 2 | -------------------------------------------------------------------------------- /.meteor/.id: -------------------------------------------------------------------------------- 1 | # This file contains a token that is unique to your project. 2 | # Check it into your repository along with the rest of this directory. 3 | # It can be used for purposes such as: 4 | # - ensuring you don't accidentally deploy one app on top of another 5 | # - providing package authors with aggregated statistics 6 | 7 | 136m87lyl842x1uqyvx5 8 | -------------------------------------------------------------------------------- /.meteor/packages: -------------------------------------------------------------------------------- 1 | # Meteor packages used by this project, one per line. 2 | # Check this file (and the other files in this directory) into your repository. 3 | # 4 | # 'meteor add' and 'meteor remove' will edit this file for you, 5 | # but you can also edit it by hand. 6 | 7 | meteor-base # Packages every Meteor app needs to have 8 | mobile-experience # Packages for a great mobile UX 9 | mongo # The database Meteor supports right now 10 | blaze-html-templates # Compile .html files into Meteor Blaze views 11 | session # Client-side reactive dictionary for your app 12 | jquery # Helpful client-side library 13 | tracker # Meteor's client-side reactive programming library 14 | 15 | standard-minifiers # JS/CSS minifiers run for production mode 16 | es5-shim # ECMAScript 5 compatibility for older browsers. 17 | ecmascript # Enable ECMAScript2015+ syntax in app code 18 | 19 | autopublish # Publish all data to the clients (for prototyping) 20 | insecure # Allow all DB writes from clients (for prototyping) 21 | 22 | kadira:graphql 23 | promise 24 | rethinkdb 25 | random 26 | -------------------------------------------------------------------------------- /.meteor/platforms: -------------------------------------------------------------------------------- 1 | server 2 | browser 3 | -------------------------------------------------------------------------------- /.meteor/release: -------------------------------------------------------------------------------- 1 | METEOR@1.2.1 2 | -------------------------------------------------------------------------------- /.meteor/versions: -------------------------------------------------------------------------------- 1 | autopublish@1.0.4 2 | autoupdate@1.2.4 3 | babel-compiler@5.8.24_1 4 | babel-runtime@0.1.4 5 | base64@1.0.4 6 | binary-heap@1.0.4 7 | blaze@2.1.3 8 | blaze-html-templates@1.0.1 9 | blaze-tools@1.0.4 10 | boilerplate-generator@1.0.4 11 | caching-compiler@1.0.0 12 | caching-html-compiler@1.0.2 13 | callback-hook@1.0.4 14 | check@1.1.0 15 | coffeescript@1.0.11 16 | cosmos:browserify@0.9.3 17 | ddp@1.2.2 18 | ddp-client@1.2.1 19 | ddp-common@1.2.2 20 | ddp-server@1.2.2 21 | deps@1.0.9 22 | diff-sequence@1.0.1 23 | ecmascript@0.1.6 24 | ecmascript-runtime@0.2.6 25 | ejson@1.0.7 26 | es5-shim@4.1.14 27 | fastclick@1.0.7 28 | geojson-utils@1.0.4 29 | hot-code-push@1.0.0 30 | html-tools@1.0.5 31 | htmljs@1.0.5 32 | http@1.1.1 33 | id-map@1.0.4 34 | insecure@1.0.4 35 | jquery@1.11.4 36 | jsx@0.2.3 37 | kadira:graphql@1.2.3 38 | kadira:runtime-dev@0.0.1 39 | launch-screen@1.0.4 40 | livedata@1.0.15 41 | logging@1.0.8 42 | meteor@1.1.10 43 | meteor-base@1.0.1 44 | meteorhacks:picker@1.0.3 45 | minifiers@1.1.7 46 | minimongo@1.0.10 47 | mobile-experience@1.0.1 48 | mobile-status-bar@1.0.6 49 | mongo@1.1.3 50 | mongo-id@1.0.1 51 | npm-mongo@1.4.39_1 52 | observe-sequence@1.0.7 53 | ordered-dict@1.0.4 54 | promise@0.5.1 55 | random@1.0.5 56 | react@0.14.3 57 | react-meteor-data@0.2.4 58 | react-runtime@0.14.4 59 | react-runtime-dev@0.14.4 60 | react-runtime-prod@0.14.4 61 | reactive-dict@1.1.3 62 | reactive-var@1.0.6 63 | reload@1.1.4 64 | rethinkdb@0.0.1 65 | retry@1.0.4 66 | routepolicy@1.0.6 67 | session@1.1.1 68 | spacebars@1.0.7 69 | spacebars-compiler@1.0.7 70 | standard-minifiers@1.0.2 71 | templating@1.1.5 72 | templating-tools@1.0.0 73 | tracker@1.0.9 74 | ui@1.0.8 75 | underscore@1.0.4 76 | url@1.0.5 77 | webapp@1.2.3 78 | webapp-hashing@1.0.5 79 | -------------------------------------------------------------------------------- /packages/rethinkdb/.npm/package/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | -------------------------------------------------------------------------------- /packages/rethinkdb/.npm/package/README: -------------------------------------------------------------------------------- 1 | This directory and the files immediately inside it are automatically generated 2 | when you change this package's NPM dependencies. Commit the files in this 3 | directory (npm-shrinkwrap.json, .gitignore, and this README) to source control 4 | so that others run the same versions of sub-dependencies. 5 | 6 | You should NOT check in the node_modules directory that Meteor automatically 7 | creates; if you are using git, the .gitignore file tells git to ignore it. 8 | -------------------------------------------------------------------------------- /packages/rethinkdb/.npm/package/npm-shrinkwrap.json: -------------------------------------------------------------------------------- 1 | { 2 | "dependencies": { 3 | "rethinkdbdash": { 4 | "version": "2.2.15", 5 | "dependencies": { 6 | "bluebird": { 7 | "version": "3.1.1" 8 | } 9 | } 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /packages/rethinkdb/package.js: -------------------------------------------------------------------------------- 1 | Package.describe({ 2 | name: 'rethinkdb', 3 | version: '0.0.1', 4 | // Brief, one-line summary of the package. 5 | summary: '', 6 | // URL to the Git repository containing the source code for this package. 7 | git: '', 8 | // By default, Meteor will default to using README.md for documentation. 9 | // To avoid submitting documentation, set this field to null. 10 | documentation: 'README.md' 11 | }); 12 | 13 | Npm.depends({ 14 | rethinkdbdash: "2.2.15", 15 | }); 16 | 17 | Package.onUse(function(api) { 18 | api.versionsFrom('1.2.1'); 19 | api.addFiles('rethinkdb.js', 'server'); 20 | api.export('r', 'server') 21 | }); 22 | -------------------------------------------------------------------------------- /packages/rethinkdb/rethinkdb.js: -------------------------------------------------------------------------------- 1 | // Write your package code here! 2 | r = Npm.require('rethinkdbdash')(); 3 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # Meteor RethinkDB 2 | 3 | Currently Meteor doesn't support RethinkDB. However, GraphQL does and we can use any promise based database with the Promise polyfill. GraphQL doesn't support realtime (yet) so this example will not update like Meteor publications will. 4 | 5 | Note, no UI is shown here but you can look at [kadira-samples/meteor-graphql-demo](https://github.com/kadira-samples/meteor-graphql-demo) for the same blog with UI & Mongo 6 | 7 | Also, this demo does not use RethinkDB joins but you could (and should) use them in production. This would mean one database call for `posts` instead of several calls. 8 | 9 | 10 | ## Usage 11 | 12 | - install RethinkDB (`brew install rethinkdb` on the Mac) 13 | - `rethinkdb` *(run in another terminal)* 14 | - Add the following tables to `test` db: `posts comments authors` 15 | - `meteor run` *(fixtures will create fake data)* 16 | - visit [localhost:3000/graphql](http://localhost:3000/graphql) 17 | 18 | ### To start your own project just add these packages: 19 | 20 | ```text 21 | meteor add kadira:graphql 22 | meteor add promise 23 | meteor create --package rethinkdb 24 | # manually add from Npm like example 25 | meteor add rethinkdb 26 | ``` 27 | -------------------------------------------------------------------------------- /server/0_init.js: -------------------------------------------------------------------------------- 1 | // Bootstrap with some dummy data, it will complain in the console 2 | // about not returning the promise but we don't care for this fake data 3 | 4 | r.table('authors').run().then(function(authors) { 5 | if(authors.length) return; 6 | resetBlog(); 7 | }); 8 | 9 | // we'll use this in the reset mutation in schema 10 | resetBlog = function () { 11 | console.log("Resetting Data") 12 | r.table('authors').insert({id: 'arunoda', name: 'Arunoda Susiripala'}).run() 13 | r.table('authors').insert({id: 'tom', name: 'Tom Moodi'}).run() 14 | 15 | _.range(5).forEach(i => { 16 | const postId = Random.id(); 17 | 18 | r.table('posts').insert({ 19 | id: postId, 20 | title: `Post Title: ${i}`, 21 | content: `Post content: ${i}`, 22 | author: 'arunoda' 23 | }).run() 24 | 25 | const commentId = Random.id(); 26 | r.table('comments').insert({ 27 | id: commentId, 28 | text: `Post ${i} is awesome`, 29 | postId, 30 | author: 'tom' 31 | }).run() 32 | }) 33 | } 34 | -------------------------------------------------------------------------------- /server/2_types.js: -------------------------------------------------------------------------------- 1 | const { GraphQLObjectType, GraphQLString, GraphQLList } = GraphQL.types; 2 | 3 | Author = new GraphQLObjectType({ 4 | name: 'Author', 5 | fields: () => ({ 6 | id: {type: GraphQLString}, 7 | name: {type: GraphQLString}, 8 | }) 9 | }); 10 | 11 | 12 | BlogPost = new GraphQLObjectType({ 13 | name: 'BlogPost', 14 | fields: () => ({ 15 | id: {type: GraphQLString}, 16 | title: {type: GraphQLString}, 17 | content: {type: GraphQLString}, 18 | author: { 19 | type: Author, 20 | resolve(post) { 21 | console.log('post', post) 22 | return r.table('authors').get(post.author); 23 | } 24 | }, 25 | comments: { 26 | type: new GraphQLList(Comment), 27 | resolve(post) { 28 | return r.table('comments').filter({postId: post.id }).run(); 29 | } 30 | } 31 | }) 32 | }); 33 | 34 | 35 | Comment = new GraphQLObjectType({ 36 | name: 'Comment', 37 | fields: () => ({ 38 | id: {type: GraphQLString}, 39 | text: {type: GraphQLString}, 40 | author: { 41 | type: Author, 42 | resolve(comment) { 43 | return r.table('comments').get(comment.author).run(); 44 | } 45 | }, 46 | postId: {type: GraphQLString} 47 | }) 48 | }) 49 | -------------------------------------------------------------------------------- /server/3_mutations.js: -------------------------------------------------------------------------------- 1 | const { GraphQLObjectType, GraphQLString, GraphQLNonNull } = GraphQL.types; 2 | 3 | // this allows us to make mutations like Meteor's RPC calls 4 | Mutations = new GraphQLObjectType({ 5 | name: 'BlogMutations', 6 | fields: () => ({ 7 | addPost: { 8 | type: BlogPost, 9 | args: { 10 | id: {type: new GraphQLNonNull(GraphQLString)}, 11 | title: {type: new GraphQLNonNull(GraphQLString)}, 12 | content: {type: new GraphQLNonNull(GraphQLString)}, 13 | author: {type: new GraphQLNonNull(GraphQLString)} 14 | }, 15 | resolve(root, args) { 16 | return r.table('posts').insert(args, {returnChanges: true}) 17 | .then((info) => { 18 | if (info.first_error) throw new Error(info.first_error) 19 | return info.changes[0].new_val; 20 | }) 21 | } 22 | }, 23 | 24 | reset: { 25 | type: GraphQLString, 26 | resolve(root, args, {rootValue}) { 27 | console.log(rootValue) 28 | //if (!rootValue.userId) { // if this is not a loggedIn user 29 | //throw new Error("Unauthorized"); 30 | //} 31 | return r.table('posts').delete({}).run() 32 | .then(() => r.table('comments').delete({}).run()) 33 | .then(() => r.table('authors').delete({}).run()) 34 | .then(resetBlog) 35 | } 36 | } 37 | }) 38 | }); 39 | -------------------------------------------------------------------------------- /server/4_queries.js: -------------------------------------------------------------------------------- 1 | const {GraphQLObjectType, GraphQLString, GraphQLList, GraphQLNonNull } = GraphQL.types; 2 | 3 | BlogQuery = new GraphQLObjectType({ 4 | name: 'BlogQueries', 5 | fields: () => ({ 6 | posts: { 7 | type: new GraphQLList(BlogPost), 8 | resolve: () => r.table('posts').run() 9 | }, 10 | 11 | recentPost: { 12 | type: BlogPost, 13 | resolve() { 14 | return r.table('posts').limit(1) 15 | .then(docs => docs[0]) 16 | } 17 | }, 18 | 19 | post: { 20 | type: BlogPost, 21 | // limit how we can query a post, otherwise we need to use an index 22 | args: { 23 | id: {type: new GraphQLNonNull(GraphQLString)} 24 | }, 25 | resolve(root, args) { 26 | return r.table('posts').get(args.id); 27 | } 28 | } 29 | }) 30 | }); 31 | -------------------------------------------------------------------------------- /server/5_schema.js: -------------------------------------------------------------------------------- 1 | const { GraphQLSchema } = GraphQL.types; 2 | 3 | const schema = new GraphQLSchema({ 4 | query: BlogQuery, 5 | mutation: Mutations 6 | }); 7 | 8 | GraphQL.registerSchema('Blog', schema); 9 | --------------------------------------------------------------------------------