• Stars
    star
    3,059
  • Rank 14,731 (Top 0.3 %)
  • Language
    JavaScript
  • Created about 9 years ago
  • Updated over 6 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

πŸ” like meteor, but meatier πŸ”

Join the chat at https://gitter.im/mattkrick/meatier Circle CI XO code style

Meteor is awesome! But after 3 years, it's starting to show its age. This project is designed to showcase the exact same functionality as Meteor, but without the monolithic structure. It trades a little simplicity for a lot of flexibility.

Some of my chief complaints with Meteor

  • Built on Node 0.10, and that ain't changing anytime soon
  • Build system doesn't allow for code splitting (the opposite, in fact)
  • Global scope (namespacing doesn't count)
  • Goes Oprah-Christmas-special with websockets (not every person/page needs one)
  • Can't handle css-modules (CSS is all handled behind the scenes)
  • Tied to MongoDB for official support
Problem Meteor's solution My solution Result
Database MongoDB RethinkDB Built in reactivity, but you can use any DB you like
Database schema Simple Schema GraphQL Can't have a hipster webapp without GraphQL!
Client validation Simple Schema Joi Clean API for client validation, although the package is HUGE
Database hooks Collections2 GraphQL GraphQL is overkill for small apps (then again, so is meatier)
Forms AutoForm redux-form state tracking awesomeness that works beautifully with react
Client-side cache Minimongo redux Bonus logging, time traveling, and undo functionality
Socket server DDP-server socketcluster super easy scaling, pubsub, auth, middleware
Authentication Meteor accounts JWTs JWTs can also serve to authorize actions, too
Auth-transport DDP GraphQL (via HTTP) Don't use sockets until you need to
Front-end Blaze React Vdom, server-side rendering, async router, etc.
Build system meteor webpack using webpack inside meteor is very limited
CSS magically bundle & serve css-modules component-scoped css with variables available in a file or embedded
Optimistic UI latency compensation redux-optimistic-ui written by yours truly
Testing Velocity (or nothing at all) AVA awesome es2016 concurrent testing
Linting Your choice xo no dotfiles, fixes errors
Routing FlowRouter react-router-redux stick the route in the state, react-router SSR, async routes
Server Node 0.10.41 Node 5 Faster, maintained, not a dinosaur...

##Installation

  • brew install rethinkdb
  • make sure you are using [email protected] (not a v1 installed globally)
  • rethinkdb (in second terminal window)
  • git clone this repo
  • cd meatier
  • npm install
  • npm run quickstart

##Client-side development

Rebuilds the client code in-memory & uses hot module reload so you can develop super fast! On my 2013 MBA an initial build takes about 8 seconds and updates usually take 800ms

##Server-side development

  • npm run prod
  • http://localhost:3000
  • If you edit any client or universal files, run npm run bs to rebuild & serve the bundle

This mode is great because you can make changes to the server without having to recompile the client code That means you only wait for the server to restart! GAME CHANGER!

##Database development

  • http://localhost:8080 for RethinkDB
  • All tables are managed in ./src/server/setupDB.js. Just add your tables & indices to that file and rerun
  • A standard ORM would check for tables & ensure indices at least once per build, doing it this way keeps your build times down
  • http://localhost:3000/graphql for testing out new queries/mutations

##Webpack configs ####Development config When the page is opened, a basic HTML layout is sent to the client along with a stringified redux store and a request for the common chunk of the JS. The client then injects the redux store & router to create the page. The redux devtools & logger are also loaded so you track your every state-changing action. The routes are loaded async, check your networks tab in chrome devtools and you'll see funny js files load now & again. If this isn't crazy amazing to you, then go away.

####Production config Builds the website & saves it to the build folder. Maps the styles to the components, but uses the prerendered CSS from the server config (below) Separates the vendor packages and the app packages for a super quick, cachable second visit. Creates a webpack manifest to enable longterm caching (eg can push new vendor.js without pushing a new app.js) Optimizes the number of chunks, sometimes it's better to have the modules of 2 routes in the same chunk if they're small

####Server config A webpack config builds the entire contents of the routes on the server side. This is required because node doesn't know how to require .css. When a request is sent to the server, react-router matches the url to the correct route & sends it to the client. Any browser dependency is ignored & uglified away. To test this, disable javascript in the browser. You'll see the site & css loads without a FOUC.

##How it works When the page loads, it checks your localStorage for Meatier.token & will automatically log you in if the token is legit. If not, just head to the 'Sign up' page. The 'Sign up' page uses redux-form, which handles all errors, schema validation, and submissions. Your credentials are set as variables in a GraphQL mutation & sent to the GraphQL endpoint and a user document (similar to Meteor's) and authToken is returned to your state.

The 'Kanban' app requires a login & websocket, so when you enter, your token will be used to authenticate a websocket. That token is stored on the server so it is only sent during the handshake (very similar to DDP). Socket state is managed by redux-socket-cluster, just clicking socket in the devtools let's you explore its current state.

When you enter the route, reducers are lazily loaded to the redux store and the redux-optimistic-ui reducer enhancer is applied to the store to enable an optimistic UI. To work, it requires some middleware that scans each redux action for an isOptimistic prop and reverts actions that fail server side.

When the kanban component loads, it subscribes to lanes & notes, which starts your personalized changefeed. When you do something that changes the persisted state (eg add a kanban lane) that action is executed optimistically on the client & emitted to the server where it is validated & sent to the database. The database then emits a changefeed doc to all subscribed viewers. Since the DB doesn't know which client made the mutation, it always sends a changefeed to the server. The server is smart enough to ignore sending that document back to the originator, but it does send an acknowledgement.

The kanban lane titles & notes are really basic, you click them & they turn into input fields. The notes can be dragged from lane to lane. This is to showcase a local state change that doesn't affect the persisted state. When the note is dropped to its new location, the change is persisted.

##Tutorials (not for beginners...but then again, neither is meatier)

##Similar Projects

##In Action I don't know of any place that hosts RethinkDB for free...so here's a gif. Meatier

##Contributing

  • Pull requests welcomed!
  • Use the gitter for any questions
  • No donations necessary (but if you know of any jobs that'll let me move back to San Diego, let me know πŸ˜‰)

##Changelog

  • 0.10

  • Use the redux devtools chrome extension

  • Update just about all the deps

  • Make deployments more configurable (deployment strategy coming soon)

  • 0.9

  • Upgraded to [email protected]

  • Now you can do cool things like time travel through routes!

  • 0.8

  • Move auth & mutations to GraphQL (changefeeds still go through WS subs)

  • Make the rest of the state.auth immutable

  • Add graphiql (http://localhost:3000/graphql) as a component & pattern to create an admin site

  • Break out auth, landing page, kanban page, and admin into 4 separate modules in the folder hierarchy

##License MIT

More Repositories

1

redux-optimistic-ui

a reducer enhancer to enable type-agnostic optimistic updates
JavaScript
693
star
2

cashay

πŸ’° Relay for the rest of us πŸ’°
JavaScript
453
star
3

trebuchet-client

A friendly siege weapon to get 2-way communication through tough firewalls and bad mobile networks
TypeScript
177
star
4

redux-operations

Solves challenging redux problems in a clean, understandable, debuggable fasion.
JavaScript
125
star
5

fast-rtc-swarm

A full-mesh WebRTC swarm built on top of fast-rtc-peer
TypeScript
101
star
6

lolliclock

A material design timepicker based on clockpicker
JavaScript
40
star
7

fast-rtc-peer

a small RTC client for connecting 2 peers
TypeScript
34
star
8

fast-bitset

A fast bitset with some nice methods
JavaScript
34
star
9

cashay-playground

The playground for exploring what's possible with Cashay
JavaScript
33
star
10

EdmondsBlossom

Edmond's maximum weighted matching algorithm (Blossom algorithm) in O(n^3)
JavaScript
30
star
11

redux-socket-cluster

A socket-cluster state snatcher
JavaScript
30
star
12

dataloader-warehouse

A class for sharing dataloaders across GraphQL subscriptions
TypeScript
29
star
13

rich

A decentralized collaborative rich text editor powered by DOM mutations, CRDT, and WebRTC
TypeScript
22
star
14

sanitize-svg

a small script to prevent stored XSS attacks and detect script tags in SVGs
TypeScript
19
star
15

redux-operations-counter-example

An example of solving current redux shortcoming using redux-operations
JavaScript
16
star
16

graphql-trebuchet-client

A graphql client to get your subscriptions through tough firewalls and unreliable mobile networks
TypeScript
14
star
17

react-portal-hoc

A stupid HOC to make a stupid portal so you can make stupid modals
JavaScript
14
star
18

event-source-polyfill

A minimum immplementation of EventSource for IE11 and Edge
TypeScript
13
star
19

react-githubish-mentions

A wrapper for a textarea to offers autocomplete suggestions when triggered by @ or # or whatever
JavaScript
13
star
20

json-deduper

Compress JSON trees by deduplicating nested objects, strings, and numbers
TypeScript
11
star
21

react-hotkey-hoc

mousetrap wrapper for react
JavaScript
10
star
22

dynamic-serializer

crawls a JSON tree replacing dynamic values with a deterministic integer
JavaScript
9
star
23

react-async-hoc

a hoc for async globals
JavaScript
6
star
24

meteor-leaflet-maps

Leaflet, now with lazy loading & namespacing!
JavaScript
6
star
25

relay-linear-publish-queue

Publish changes in the order they're received.
TypeScript
4
star
26

surviveJS-redux

A redux version of the awesome surviveJS tutorial for react & webpack.
JavaScript
3
star
27

hungarian-on3

The hungarian (Kuhn-Munkres) algorithm solved in O(n^3) time
JavaScript
3
star
28

rethinkdb-ts-migrate

Migrations for rethinkdb-ts
TypeScript
3
star
29

meteor-vital-signs

JavaScript
2
star
30

meteorTooltips

Meteor tooltips that turn any template into a tooltip
JavaScript
2
star
31

visage

Signaling + SFU for turnkey WRTC (WIP)
TypeScript
2
star
32

event-target-polyfill

EventTarget polyfill for IE11 and Edge from https://developer.mozilla.org/en-US/docs/Web/API/EventTarget#Example
TypeScript
2
star
33

hepha

Aphrodite for global styles
JavaScript
1
star
34

performant-material-input

A feature-rich material design input box with hardware acceleration
CSS
1
star
35

todo-modern-subs

JavaScript
1
star