Skip to content

Commit

Permalink
Merge b8176ed into cd77019
Browse files Browse the repository at this point in the history
  • Loading branch information
raingerber committed Mar 6, 2018
2 parents cd77019 + b8176ed commit f9bd967
Show file tree
Hide file tree
Showing 10 changed files with 197 additions and 21 deletions.
68 changes: 68 additions & 0 deletions packages/data-point/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ npm install --save data-point
- [withDefault](#reducer-default)
- [Entities](#entities)
- [dataPoint.addEntities](#api-data-point-add-entities)
- [Entity factories](#entity-factories)
- [Built-in entities](#built-in-entities)
- [Reducer / Transform](#reducer-entity)
- [Model](#model-entity)
Expand Down Expand Up @@ -1354,6 +1355,73 @@ dataPoint.addEntities({
| *EntityType* | `string` | valid entity type to associate with the EntityObject |
| *EntityId* | `string` | unique entity ID associated with the EntityObject |

### <a name="entity-factories">Entity factories</a>

Entities can be defined with object literals, *or* with factories that DataPoint exposes. Each entity type has a corresponding factory:

```js
const {
Entry,
Model,
Reducer,
Collection,
Hash,
Request,
Control,
Schema
} = require('data-point').entityFactories
```

The following examples are equivalent:

**Example #1 (with object literal)**

```js
// object literal version
dataPoint.addEntities({
'hash:hello-world': {
value: input => ({
hello: 'world'
})
}
})
```

**Example #2 (with factory and assignment)**

```js
const { Hash } = DataPoint.entityFactories

const hash = Hash({
value: input => ({
hello: 'world'
})
})

const entities = {}

entities[hash.id] = hash.spec

dataPoint.addEntities(entities)
```

**Example #3 (with factory and spread syntax)**

```js
const { Hash } = DataPoint.entityFactories

const hash = Hash({
value: input => ({
hello: 'world'
})
})

const entities = { ...hash }

dataPoint.addEntities(entities)
```


### <a name="built-in-entities">Built-in Entities</a>

DataPoint comes with the following built-in entities:
Expand Down
10 changes: 10 additions & 0 deletions packages/data-point/lib/__snapshots__/index.test.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,16 @@ Object {
"create": [Function],
"createEntity": [Function],
"createReducerResolver": [Function],
"entityFactories": Object {
"Collection": [Function],
"Control": [Function],
"Entry": [Function],
"Hash": [Function],
"Model": [Function],
"Reducer": [Function],
"Request": [Function],
"Schema": [Function],
},
"helpers": Object {
"assign": [Function],
"constant": [Function],
Expand Down
29 changes: 8 additions & 21 deletions packages/data-point/lib/core/core.js
Original file line number Diff line number Diff line change
@@ -1,22 +1,14 @@
const _ = require('lodash')

const normalizeEntities = require('./normalize-entities')
const Transform = require('./transform')
const normalizeEntities = require('./normalize-entities')
const entities = require('../entity-types').definitions

const storeValues = require('../stores/values')
const storeEntities = require('../stores/entities')
const storeEntityTypes = require('../stores/entity-types')
const storeMiddleware = require('../stores/middleware')

const EntityTransform = require('../entity-types/entity-transform')
const EntityEntry = require('../entity-types/entity-entry')
const EntityHash = require('../entity-types/entity-hash')
const EntityModel = require('../entity-types/entity-model')
const EntityCollection = require('../entity-types/entity-collection')
const EntityRequest = require('../entity-types/entity-request')
const EntityControl = require('../entity-types/entity-control')
const EntitySchema = require('../entity-types/entity-schema')

/**
* @param {Object} store
* @param {Object} items
Expand Down Expand Up @@ -72,18 +64,13 @@ function create (spec) {
manager.addEntities = _.partial(addEntitiesToStore, manager.entities)

// built-in entity types
manager.addEntityType('reducer', EntityTransform)
manager.addEntityType('entry', EntityEntry)
// alias to entry, may be used to process any object type
manager.addEntityType('model', EntityModel)
manager.addEntityType('hash', EntityHash)
manager.addEntityType('collection', EntityCollection)
manager.addEntityType('request', EntityRequest)
_.forOwn(entities, (definition, key) => {
manager.addEntityType(key.toLowerCase(), definition)
})

// for backwards compatibility
manager.addEntityType('transform', EntityTransform)
manager.addEntityType('source', EntityRequest)
manager.addEntityType('control', EntityControl)
manager.addEntityType('schema', EntitySchema)
manager.addEntityType('transform', entities.Reducer)
manager.addEntityType('source', entities.Request)

addToStore(manager.values, options.values, true)

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`creating a model with createEntityFactory should create an entity factory that returns an object with the expected shape 1`] = `
Object {
"model:nuts": Object {
"value": [Function],
},
}
`;
29 changes: 29 additions & 0 deletions packages/data-point/lib/entity-types/factory.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/**
* @param {String} _type
* @return {Function}
*/
function createEntityFactory (_type) {
const type = _type.toLowerCase()
/**
* @param {String} name
* @param {Object} spec
* @return {Object}
*/
function Factory (name, spec) {
const id = `${type}:${name}`
const result = { [id]: spec }
// these properties are non-enumerable
// so that we can do nifty things like:
// dataPoint.create({ entities: { ...Hash('name', spec) } })
Object.defineProperty(result, 'id', { value: id })
Object.defineProperty(result, 'type', { value: type })
Object.defineProperty(result, 'name', { value: name })
Object.defineProperty(result, 'spec', { value: spec })
return result
}

Factory.type = type
return Factory
}

module.exports.createEntityFactory = createEntityFactory
39 changes: 39 additions & 0 deletions packages/data-point/lib/entity-types/factory.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/* eslint-env jest */

const { createEntityFactory } = require('./factory')

describe('creating a model with createEntityFactory', () => {
const factory = createEntityFactory('model')
const spec = { value: input => input }
const instance = factory('nuts', spec)

test('createEntityFactory return value should be a function', () => {
expect(createEntityFactory).toBeInstanceOf(Function)
})

test('createEntityFactory return value should have the correct "type" property', () => {
expect(factory.type).toBe('model')
})

test('should create an entity factory that returns an object with the expected shape', () => {
// the 'model:nuts' key should appear in this snapshot,
// but other keys shouldn't because they're non-enumerable
expect(instance).toMatchSnapshot()
})

test('model should have the correct "id" property', () => {
expect(instance.id).toBe('model:nuts')
})

test('model should have the correct "type" property', () => {
expect(instance.type).toBe('model')
})

test('model should have the correct "name" property', () => {
expect(instance.name).toBe('nuts')
})

test('model should have the correct "spec" property', () => {
expect(instance.spec).toEqual(spec)
})
})
21 changes: 21 additions & 0 deletions packages/data-point/lib/entity-types/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
const mapValues = require('lodash/mapValues')

const { createEntityFactory } = require('./factory')

const definitions = {
Entry: require('./entity-entry'),
Model: require('./entity-model'),
Reducer: require('./entity-transform'),
Collection: require('./entity-collection'),
Hash: require('./entity-hash'),
Request: require('./entity-request'),
Control: require('./entity-control'),
Schema: require('./entity-schema')
}

module.exports = {
definitions,
factories: mapValues(definitions, (value, key) => {
return createEntityFactory(key.toLowerCase())
})
}
10 changes: 10 additions & 0 deletions packages/data-point/lib/helpers/__snapshots__/helpers.test.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,16 @@ Object {
"createEntity": [Function],
"createReducer": [Function],
"createReducerResolver": [Function],
"entityFactories": Object {
"Collection": [Function],
"Control": [Function],
"Entry": [Function],
"Hash": [Function],
"Model": [Function],
"Reducer": [Function],
"Request": [Function],
"Schema": [Function],
},
"helpers": Object {
"assign": [Function],
"constant": [Function],
Expand Down
2 changes: 2 additions & 0 deletions packages/data-point/lib/helpers/helpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ module.exports.helpers = {
withDefault: stubFactories.withDefault
}

module.exports.entityFactories = require('../entity-types').factories

module.exports.isReducer = require('../reducer-types').isReducer

module.exports.createReducer = require('../reducer-types').create
Expand Down
1 change: 1 addition & 0 deletions packages/data-point/lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ module.exports = {
helpers: helpers.helpers,
createEntity: helpers.createEntity,
resolveEntity: helpers.resolveEntity,
entityFactories: helpers.entityFactories,
reducify: helpers.reducify,
reducifyAll: helpers.reducifyAll,
createReducerResolver: helpers.reducifyAll
Expand Down

0 comments on commit f9bd967

Please sign in to comment.