419 karma · joined November 22, 2011
Author of DerbyJS full-stack, realtime MVC framework: http://derbyjs.com/
By building on ShareJS, DerbyJS uses Operational Transformation for collaborative editing of data in realtime, which means that users can see data updated immediately in their browser even if other users can edit the same thing at the same time. This is the same approached used by Google Docs.
As hiring has gotten increasingly competitive, companies have been finding that the best candidates usually come from a personal connection. The best candidates usually come via a referral from someone's personal network or via sourcing efforts, where the company goes out and finds people that are a really strong fit based on their interests and experience.
Lever has a number of features that specifically make sourcing easier: https://lever.co/features.html. The best is our Chrome Extension for easily creating candidates in Lever from a web profile. We also have really great 2-way email sync that uses IMAP to sync Gmail threads in realtime, so that your company can follow along on what is happening with candidates and make sure that you don't drop the ball.
We send emails as you over Google OAuth and Gmail SMTP. That way, the email literally comes from you and shows up in your sent folder. The advantage to doing this in a shared system like Lever is that everyone else on your team can see the full history among multiple people.
When you send another email in Gmail or the recipient replies, we use IMAP to listen on threads associated with Lever. That way, we capture emails much more reliably and they don't have to come from strange random email address. It is really cool stuff, and it happens just as fast as Gmail can show an email, because we are acting just like a full email client.
Firepad doesn't actually do OT of JSON. In Firepad, a string OT algorithm is used to merge text edits, and the metadata describing rich text is separately managed as span objects, which get modified in accordance with text changes.
Firebase provides conflict resolution of JSON structures using their Transaction primitive, which allows them to create a Software Transactional Memory used to update the journal that powers the text OT in Firepad. ShareJS inside of Derby uses a similar approach to allow multiple servers to access the journal, but it is done in Redis with Lua scripting.
Our initial goal in open sourcing the framework was to get some ideas out there and see what worked well and what didn't. We've learned a lot from this process, and we now have a much better idea of how to build a great system.
We are excited to see all of the innovation coming from Meteor, Firebase, and other new realtime systems. While there are similarities, our teams have different perspectives on what the future of web development looks like, and we believe there is still a great deal to be gained from further development of each of these platforms.
Currently, our changes to Racer will keep a similar API but make Derby apps much more stable and scalable to large production deployments.
For our particular use cases, we think that document stores are a better fit, but I am not arguing that document stores are universally easier or better.
Derby is an npm module, and developers are in control of their own standard Node.js/Express server files. We use Browserify (https://github.com/substack/node-browserify) to bundle up scripts, so you can use any standard npm module on both the server and the client without modification.
We have a long way to go in terms of customizing Derby; however, it is already very flexible in some ways. For example, Derby apps can be rendered and sent to the client from Express routes or via Derby app routes. There's also a method to simply get a blob of rendered HTML or render a static page using the same templates. Derby includes model-view bindings, but it's simple to bind some things and not others or nothing at all.
Much of Derby and Racer is very different from how web apps are written today, and we are focused on iterating quickly to start. As it matures, Derby will become more of a collection of independent modules. That way, most developers could use Derby out of the box, but others could fork the project and customize or use features of the framework independently. It's a ways off, but that's the long term goal.
We understand that authentication and authorization are critical, and we have been ironing our issues with them using the app that we are developing as a first test. Pretty much all of the required code is already in master, and an example is forthcoming.
We just added a lot of functionality to our query system, but it is very much a work in progress. Making it easier to create queries that represent relationships is definitely on our task list.
It's awesome to see that Meteor is now permissively licensed, but I would prefer to see them embrace npm as well.
Knockout is pretty minimal and fast, Ember has not performed very well in update intensive benchmarks. From our testing so far, Derby is somewhere in the middle if you bind everything, but it has granular control of bindings so you can get it to perform about as fast as Knockout.
This is just one small part of synchronizing clients, and Derby takes care of realtime data syncing as well. Synching data with ember requires a lot of manual server implementation. In addition, Ember and Knockout don't have any way of supporting server-side rendering, while Derby automatically renders everything in both the client and on the server.
You are right that you can't partially implement OT. The way that we handle it is by keeping OT operations on defined paths so that they are separately namespaced from other kinds of updates.
We also are big fans of testing, and we will have a better answer to how testing can be done. We currently use Mocha, which is a great test runner for the server and the browser. All of our frameworks are still quickly iterating and adding important features like this.
I believe that the author is arguing that Node.js could reach a similar level of popularity as Rails if there were a framework that provided some of the ease of use for common use cases, such as creating typical CRUD apps. However, he also states that in order to displace Rails, such a framework would also need to offer some distinct advantages, such as better support for realtime.
Backbone, Ember, Knockout, etc. are client-side frameworks. They make it easier to structure complex client code, but they don't include a simple solution for creating a server or synching data among clients and servers.
It's still under active development, but I have been working on a full-stack framework on top of Node.js that is more like what the author was envisioning: http://derbyjs.com
Derby provides server and client rendering, and it automatically synchronizes data in realtime. The idea is to make writing realtime apps so simple that any app can take advantage of advanced realtime features, fast server-rendered page loads, and instant client-rendered page updates.
The reason we started working on Derby, is that none of these frameworks offer a full-stack solution. Backbone and SproutCore will provide better structure and some automation of client-server data syncing. However, they still require manually creating appropriate server routes that handle AJAX requests and communicate with a database. They may provide client-side routing, but these routes are totally different from the server routes, so if you want to use the same URLs, you have to duplicate routing code. SproutCore uses Handlebars, so you might be able to render the same templates on the server for faster page rendering, and non-JavaScript browser or search engine crawler accessibility. However, this will require writing a bunch of custom server code to pull out the right data and render the templates. In addition, none of these frameworks provide tools to deal with data conflicts. Conflicts are inevitable in a multiple users realtime application, especially when supporting offline.
Derby's focus is to unify as much code between server and client and to provide automatic realtime syncing among all models and views. This approach requires less code, delivers faster load times, provides instant client-side rendering from full pages to individual data bindings, and supports offline by default. It's a work in progress, but let us know what you think about it so far.