Skip to content

Commit

Permalink
split up arguments
Browse files Browse the repository at this point in the history
  • Loading branch information
0x8890 committed Jan 25, 2016
1 parent 3bbc96e commit d7377e8
Show file tree
Hide file tree
Showing 7 changed files with 123 additions and 135 deletions.
32 changes: 15 additions & 17 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,23 +32,21 @@ The only necessary input is record type definitions. Record types in Fortune.js
const fortune = require('fortune')

const store = fortune({
recordTypes: {
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' }
}
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' }
}
})
```
Expand Down
22 changes: 10 additions & 12 deletions doc/GETTING_STARTED.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ Then create an empty `index.js` file adjacent to the `node_modules` folder, and

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

The `fortune` function returns a new instance of Fortune, and accepts a configuration object as an argument.
Expand All @@ -22,17 +22,15 @@ The only necessary input is type definitions. Let's start with a basic example:

```js
fortune({
recordTypes: {
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 }
}
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
9 changes: 4 additions & 5 deletions lib/browser.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,10 @@ 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 (typeof options !== 'object') throw new Error(
'Options argument must be an object.')
if (options === void 0) options = {}

// Try to use IndexedDB first, fall back to memory adapter.
if (!('adapter' in options) &&
Expand Down Expand Up @@ -59,7 +58,7 @@ function Fortune (options) {
if (!('enforceLinks' in options.settings))
options.settings.enforceLinks = false

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


Expand Down
100 changes: 48 additions & 52 deletions lib/core.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,49 @@ Fortune.prototype = Object.create(EventLite.prototype)


/**
* Create a new instance. The options object must at least specify one type,
* and may contain the following keys:
* Create a new instance, the only required input is record type definitions.
* The first argument must be an object keyed by name, valued by definition
* objects. Here are some example field definitions:
*
* ```js
* {
* // A singular value.
* name: { type: String },
*
* // An array containing values of a single type.
* luckyNumbers: { type: Number, isArray: true },
*
* // Creates a to-many link to `animal` record type. If the field `owner`
* // on the `animal` record type is not an array, this is a many-to-one
* // relationship, otherwise it is many-to-many.
* pets: { link: 'animal', isArray: true, inverse: 'owner' },
*
* // The `min` and `max` keys are open to interpretation by the specific
* // adapter or serializer, which may introspect the field definition.
* thing: { type: Number, min: 0, max: 100 },
*
* // Nested field definitions are invalid. Use `Object` type instead.
* nested: { thing: { ... } } // Will throw an error.
* }
* ```
*
* The allowed native types are `String`, `Number`, `Boolean`, `Date`,
* `Object`, and `Buffer`. Note that the `Object` type should be a JSON
* serializable object that may be persisted. The only other allowed type is
* a `Function`, which may be used to define custom types.
*
* A type function should accept one argument, the value, and return a
* boolean based on whether the value is valid for the type or not. It may
* optionally have properties `sort` and `equal`, which should be valued as
* functions.
*
* - `compare`: same signature as comparing with `Array.prototype.sort`.
* - `equal`: return a boolean value if the two arguments are equal.
*
* These optional functions are used for the memory adapter and web browser
* adapters, but may not be run by other adapters.
*
* The options object may contain the following keys:
*
* - `adapter`: configuration object for the adapter. The default type is the
* memory adapter.
Expand Down Expand Up @@ -93,49 +134,6 @@ Fortune.prototype = Object.create(EventLite.prototype)
* }]
* ```
*
* - `recordTypes`: an object keyed by name, valued by fields object. Here are
* some example field definitions:
*
* ```js
* {
* // A singular value.
* name: { type: String },
*
* // An array containing values of a single type.
* luckyNumbers: { type: Number, isArray: true },
*
* // Creates a to-many link to `animal` record type. If the field `owner`
* // on the `animal` record type is not an array, this is a many-to-one
* // relationship, otherwise it is many-to-many.
* pets: { link: 'animal', isArray: true, inverse: 'owner' },
*
* // The `min` and `max` keys are open to interpretation by the specific
* // adapter or serializer, which may introspect the field definition.
* thing: { type: Number, min: 0, max: 100 },
*
* // Nested field definitions are invalid. Use `Object` type instead.
* nested: { thing: { ... } } // Will throw an error.
* }
* ```
*
* The allowed native types are `String`, `Number`, `Boolean`, `Date`,
* `Object`, and `Buffer`. Note that the `Object` type should be a JSON
* serializable object that may be persisted. The only other allowed type is
* a `Function`, which may be used to define custom types.
*
* A type function should accept one argument, the value, and return a
* boolean based on whether the value is valid for the type or not. It may
* optionally have properties `sort` and `equal`, which should be valued as
* functions.
*
* - `compare`: same signature as comparing with `Array.prototype.sort`.
* - `equal`: return a boolean value if the two arguments are equal.
*
* These optional functions are used for the memory adapter and web browser
* adapters, but may not be run by other adapters.
*
* - `transforms`: keyed by type name, valued by an object containing at least
* an `input` or `output` key, valued as a function.
*
Expand Down Expand Up @@ -202,16 +200,15 @@ Fortune.prototype = Object.create(EventLite.prototype)
*
* The return value of the constructor is the instance itself.
*
* @param {Object} options
* @param {Object} recordTypes
* @param {Object} [options]
* @return {Fortune}
*/
Fortune.prototype.constructor = function (options) {
Fortune.prototype.constructor = function (recordTypes, options) {
var self = this
var i, adapter, serializer, method, stack, flows,
type, recordTypes, transforms
var i, adapter, serializer, method, stack, flows, type, transforms

if (typeof options.recordTypes !== 'object' ||
!Object.keys(options.recordTypes).length)
if (typeof recordTypes !== 'object' || !Object.keys(recordTypes).length)
throw new Error('At least one type must be specified.')

if (!('adapter' in options)) options.adapter = { type: memoryAdapter }
Expand All @@ -231,7 +228,6 @@ Fortune.prototype.constructor = function (options) {
flows[methods[method]] = stack
}

recordTypes = options.recordTypes
transforms = options.transforms

// Validate transforms.
Expand Down
9 changes: 4 additions & 5 deletions lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,18 +35,17 @@ var net = {
* 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 (typeof options !== 'object') throw new Error(
'Options argument must be an object.')
if (options === void 0) options = {}

if (!('serializers' in options))
options.serializers = map(Object.keys(serializers), function (name) {
return { type: serializers[name] }
})

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


Expand Down
11 changes: 5 additions & 6 deletions test/browser.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,14 @@ require('./integration/adapters/indexeddb')
run(function () {
var timestamp
var store = fortune({
model: {
name: { type: String },
junk: { type: Object }
}
}, {
adapter: {
type: fortune.adapters.indexedDB,
options: { name: 'fortune_test' }
},
recordTypes: {
model: {
name: { type: String },
junk: { type: Object }
}
}
})

Expand Down
75 changes: 37 additions & 38 deletions test/integration/test_instance.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,48 +12,47 @@ const methods = fortune.methods


module.exports = options => {
const store = fortune(assign(options || {}, {
recordTypes: {
user: {
name: { type: String },
camelCaseField: { type: String },
birthday: { type: Date },
picture: { type: Buffer },
createdAt: { type: Date },
lastModified: { type: Date },
nicknames: { type: String, isArray: true },

// Many to many
friends: { link: 'user', inverse: 'friends', isArray: true },

// Many to many, denormalized inverse
enemies: { link: 'user', isArray: true },

// One to one
spouse: { link: 'user', inverse: 'spouse' },

// Many to one
ownedPets: { link: 'animal', inverse: 'owner', isArray: true }
},
animal: {
name: { type: String },
const store = fortune({
user: {
name: { type: String },
camelCaseField: { type: String },
birthday: { type: Date },
picture: { type: Buffer },
createdAt: { type: Date },
lastModified: { type: Date },
nicknames: { type: String, isArray: true },

// Many to many
friends: { link: 'user', inverse: 'friends', isArray: true },

// Many to many, denormalized inverse
enemies: { link: 'user', isArray: true },

// One to one
spouse: { link: 'user', inverse: 'spouse' },

// Many to one
ownedPets: { link: 'animal', inverse: 'owner', isArray: true }
},
animal: {
name: { type: String },

// Implementations may have problems with this reserved word.
type: { type: String },
// Implementations may have problems with this reserved word.
type: { type: String },

favoriteFood: { type: String },
favoriteFood: { type: String },

birthday: { type: Date },
createdAt: { type: Date },
lastModified: { type: Date },
picture: { type: Buffer },
nicknames: { type: String, isArray: true },
birthday: { type: Date },
createdAt: { type: Date },
lastModified: { type: Date },
picture: { type: Buffer },
nicknames: { type: String, isArray: true },

// One to many
owner: { link: 'user', inverse: 'ownedPets' }
},
'☯': {}
// One to many
owner: { link: 'user', inverse: 'ownedPets' }
},
'☯': {}
}, assign({
transforms: {
user: {
input (context, record, update) {
Expand Down Expand Up @@ -102,7 +101,7 @@ module.exports = options => {
}
}
}
}))
}, options))

store.on(change, data => {
for (let symbol of Object.getOwnPropertySymbols(data))
Expand Down

0 comments on commit d7377e8

Please sign in to comment.