Fortune.js is a library for managing data in Node.js and web browsers. It consists of a data abstraction layer and networking functions.
View the website for documentation. Get it from npm:
$ npm install fortune --saveFortune.js implements a data abstraction layer, and also includes networking functions, specific for Node.js and web browsers. There are a variety of use cases for Fortune.js, for example:
- A server-side implementation of a web service over HTTP. The included HTTP implementation provides a basis for implementing application-level protocols, including media types such as Micro API and JSON API, and covers standard input formats such as URL encoded and form data.
- A persistence layer in web browsers. Under the hood, it uses IndexedDB, Web Worker, and MessagePack to achieve high performance for persisting structured data.
- An abstraction layer for working with multiple databases. Write the same logic which will work across multiple adapters.
- Real-time web applications. Fortune.js includes its own wire protocol based on WebSocket and MessagePack.
The only required input is record type definitions. Here's a model of a basic micro-blogging service:
const fortune = require('fortune')
const store = fortune({
user: {
name: { type: String },
// Following and followers are inversely related (many-to-many).
following: { link: 'user', inverse: 'followers', isArray: true },
followers: { link: 'user', inverse: 'following', isArray: true },
// Many-to-one relationship of user posts to post author.
posts: { link: 'post', inverse: 'author', isArray: true }
},
post: {
message: { type: String },
// One-to-many relationship of post author to user posts.
author: { link: 'user', inverse: 'posts' }
}
})By default, the data is persisted in memory. There are adapters for databases such as MongoDB, Postgres, and NeDB. To make a request internally:
store.request({
type: 'user',
method: 'create',
payload: [ { name: 'John Doe' }, { name: 'Jane Doe' } ]
})The first call to request will trigger a connection to the data store, and it returns the result as a Promise.
Then let's add a HTTP server:
const http = require('http')
// The `fortune.net.http` helper function returns a listener function which
// does content negotiation, and maps the internal response to a HTTP response.
const server = http.createServer(fortune.net.http(store))
store.connect().then(() => server.listen(1337))This yields an ad hoc JSON over HTTP API. There are serializers for Micro API (JSON-LD) and JSON API, which also accept HTTP parameters. In addition, Fortune.js implements a wire protocol based on WebSocket and MessagePack.
See the plugins page for more details.
- Type validations, with support for custom types.
- Application-level denormalized inverse relationships.
- Dereferencing relationships in a single request.
- Isomorphic, backed by IndexedDB in web browsers, including a built-in wire protocol for data synchronization.
- No active record pattern, just plain data objects.
- No coupling with network protocol, they are treated as external I/O.
Fortune.js is written in ECMAScript 5.1 syntax, with some ECMAScript 6 additions.
- Promise (ES6): not supported in IE, supported in Edge. Bring your own implementation (optional).
- WeakMap (ES6): supported in IE11+, Edge. Polyfills exist, but they have their shortcomings since it must be implemented natively.
This software is licensed under the MIT license.