Skip to content

Commit

Permalink
Merge pull request #166 from fortunejs/constructor-changes
Browse files Browse the repository at this point in the history
Constructor changes
  • Loading branch information
0x8890 committed Jan 25, 2016
2 parents 329526b + d7377e8 commit 6b590a4
Show file tree
Hide file tree
Showing 14 changed files with 385 additions and 455 deletions.
33 changes: 14 additions & 19 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,37 +29,32 @@ The `Serializer` abstraction allows for multiple serialization formats, includin
The only necessary input is record type definitions. Record types in Fortune.js are the basic means of modelling data. Let's model a subset of Twitter's functionality:

```js
// store.js
const fortune = require('fortune')

module.exports = fortune()
const store = fortune({
user: {
name: { type: String },

.defineType('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 },

// 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 },

// Many-to-one relationship of user posts to post author.
posts: { link: 'post', inverse: 'author', isArray: true }
})

.defineType('post', {
message: { type: String },

// One-to-many relationship of post author to user posts.
author: { link: 'user', inverse: 'posts' }
// 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](https://github.com/fortunejs/fortune-mongodb), [Postgres](https://github.com/fortunejs/fortune-postgres), and [NeDB](https://github.com/fortunejs/fortune-nedb). Then let's add a HTTP server:

```js
// server.js
const http = require('http')
const fortune = require('fortune')
const store = require('./store')

// The `fortune.net.http` helper function returns a listener function which
// does content negotiation, and maps the internal response to a HTTP response.
Expand Down
5 changes: 5 additions & 0 deletions doc/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
# Changelog


##### 2.0.0 (2016-01-25)
- Breaking change: constructor argument now contains all configuration.
- Breaking change: removed `defineType`, `transform`, `transformInput`, `transformOutput`, and static `create` methods. Deprecated in favor of new constructor object.


##### 1.12.0 (2016-01-24)
- Feature: include entire payloads in change event.
- Fix: update objects should show resulting operations.
Expand Down
33 changes: 17 additions & 16 deletions doc/GETTING_STARTED.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,27 +10,28 @@ Then create an empty `index.js` file adjacent to the `node_modules` folder, and

```js
const fortune = require('fortune')
const store = fortune()
const store = fortune({ ... })
```

The `fortune` function returns a new instance of Fortune, and accepts a configuration object as an argument. We don't need to pass any arguments to the constructor for now, the defaults should work.
The `fortune` function returns a new instance of Fortune, and accepts a configuration object as an argument.


## Record Types

The only necessary input is record type definitions. Let's start with a basic example:
The only necessary input is type definitions. Let's start with a basic example:

```js
store.defineType('user', {
username: { type: String },
key: { type: Buffer },
salt: { type: Buffer },
group: { link: 'group', inverse: 'users', isArray: true }
})

store.defineType('group', {
name: { type: String },
users: { link: 'user', inverse: 'group', isArray: true }
fortune({
user: {
username: { type: String },
key: { type: Buffer },
salt: { type: Buffer },
group: { link: 'group', inverse: 'users', isArray: true }
},
group: {
name: { type: String },
users: { link: 'user', inverse: 'group', isArray: true }
}
})
```

Expand Down Expand Up @@ -74,7 +75,7 @@ This is a pretty basic implementation using the `crypto` module provided by Node
```js
const methods = fortune.methods, errors = fortune.errors

store.transformInput('user', (context, record, update) => {
function input (context, record, update) {
const request = context.request,
method = request.method,
type = request.type,
Expand Down Expand Up @@ -115,15 +116,15 @@ store.transformInput('user', (context, record, update) => {
return update
})
})
})
}
```

Input transform functions are run before anything gets persisted, so it is safe to throw errors. They may either synchronously return a value, or return a Promise. Note that the `password` field on the record is not defined in the record type, arbitrary fields are not persisted. Updating the password in this example requires a field in the `meta.headers` object, for example `Authorization: "Zm9vYmFyYmF6cXV4"` where the value is the base64 encoded old password.

It may be required to transform outputs as well. In this example, we don't want expose the salt and the key publicly:

```js
store.transformOutput('user', (context, record) => {
function output (context, record) {
// Hide sensitive fields.
delete record.salt
delete record.key
Expand Down
2 changes: 1 addition & 1 deletion lib/adapter/adapters/indexeddb/worker.js
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ function worker () {
var version = (db.version || 1) + 1

db.close()
request = indexedDB.open(name, version)
request = indexedDB.open(data.name, version)
request.onerror = errorReconnection
request.onupgradeneeded = handleUpgrade
request.onsuccess = function (event) {
Expand Down
23 changes: 9 additions & 14 deletions lib/browser.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,9 @@ var hasCreateObjectURL = 'URL' in globalObject && 'createObjectURL' in URL
* This class just extends Core with some default serializers and static
* properties.
*/
function Fortune (options) {
if (!(this instanceof Fortune)) return new Fortune(options)
function Fortune (recordTypes, options) {
if (!(this instanceof Fortune)) return new Fortune(recordTypes, options)

if (options === void 0) options = {}

// Try to use IndexedDB first, fall back to memory adapter.
Expand All @@ -51,26 +52,20 @@ function Fortune (options) {
/* eslint-enable no-console */
}

if (!('enforceLinks' in options))
options.enforceLinks = false
if (!('settings' in options))
options.settings = {}

if (!('enforceLinks' in options.settings))
options.settings.enforceLinks = false

this.constructor(options)
this.constructor(recordTypes, options)
}


Fortune.prototype = Object.create(Core.prototype)
assign(Fortune, Core)


Fortune.create = function (options) {
/* eslint-disable no-console */
console.warn('The "Fortune.create" method will be deprecated in future ' +
'major versions.')
/* eslint-enable no-console */
return new Fortune(options)
}


// Assigning the Promise implementation.
Object.defineProperty(Fortune, 'Promise', {
enumerable: true,
Expand Down
Loading

0 comments on commit 6b590a4

Please sign in to comment.