Skip to content

Commit

Permalink
✨ Add seq.chain fix #4 (#10)
Browse files Browse the repository at this point in the history
  • Loading branch information
nlepage committed Apr 27, 2017
1 parent 061edde commit 91884db
Show file tree
Hide file tree
Showing 24 changed files with 425 additions and 56 deletions.
3 changes: 2 additions & 1 deletion .babelrc
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
"presets": [
["env", {
"modules": "umd"
}]
}],
["stage-0"]
]
}
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@ yarn-error.log
/core/
/lang/
/math/
/seq/
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@
"main": "index.js",
"devDependencies": {
"babel-cli": "^6.24.1",
"babel-eslint": "^7.2.3",
"babel-preset-env": "^1.4.0",
"babel-preset-stage-0": "^6.24.1",
"chai": "^3.5.0",
"eslint": "^3.19.0",
"mocha": "^3.2.0"
Expand Down
147 changes: 120 additions & 27 deletions src/.eslintrc.json
Original file line number Diff line number Diff line change
@@ -1,29 +1,122 @@
{
"env": {
"browser": true,
"es6": true,
"node": true
},
"extends": "eslint:recommended",
"parserOptions": {
"sourceType": "module"
},
"rules": {
"indent": [
"error",
2
],
"linebreak-style": [
"error",
"unix"
],
"quotes": [
"error",
"single"
],
"semi": [
"error",
"never"
]
}
"env": {
"browser": true,
"es6": true,
"node": true
},
"extends": "eslint:recommended",
"parser": "babel-eslint",
"parserOptions": {
"sourceType": "module"
},
"rules": {
"array-bracket-spacing": "error",
"array-callback-return": "error",
"arrow-spacing": "error",
"block-scoped-var": "error",
"block-spacing": "error",
"brace-style": ["error", "1tbs", {
"allowSingleLine": true
}],
"camelcase": "error",
"comma-dangle": ["error", {
"arrays": "always-multiline",
"objects": "always-multiline",
"imports": "always-multiline",
"exports": "always-multiline",
"functions": "always-multiline"
}],
"comma-spacing": ["error", {
"before": false,
"after": true
}],
"comma-style": "error",
"computed-property-spacing": "error",
"consistent-return": 2,
"curly": ["error", "multi"],
"dot-location": ["error", "property"],
"dot-notation": "error",
"eol-last": "error",
"eqeqeq": "error",
"func-call-spacing": "error",
"indent": ["error", 2],
"key-spacing": "error",
"keyword-spacing": "error",
"linebreak-style": "error",
"no-alert": "error",
"no-caller": "error",
"no-duplicate-imports": "error",
"no-else-return": "error",
"no-empty-function": "error",
"no-eval": 2,
"no-extend-native": 2,
"no-extra-bind": 2,
"no-extra-label": 2,
"no-implicit-coercion": "error",
"no-implicit-globals": "error",
"no-implied-eval": "error",
"no-invalid-this": "error",
"no-iterator": "error",
"no-labels": "error",
"no-lone-blocks": "error",
"no-lonely-if": "error",
"no-loop-func": "error",
"no-multiple-empty-lines": ["error", {
"max": 1,
"maxBOF": 0
}],
"no-multi-spaces": "error",
"no-new": "error",
"no-new-func": "error",
"no-new-wrappers": "error",
"no-param-reassign": "error",
"no-proto": "error",
"no-return-assign": "error",
"no-self-compare": "error",
"no-sequences": "error",
"no-tabs": "error",
"no-throw-literal": "error",
"no-trailing-spaces": "error",
"no-unneeded-ternary": "error",
"no-unused-expressions": "error",
"no-useless-call": "error",
"no-useless-computed-key": "error",
"no-useless-concat": "error",
"no-useless-constructor": "error",
"no-useless-escape": "error",
"no-useless-rename": "error",
"no-useless-return": "error",
"no-var": "error",
"no-void": "error",
"no-whitespace-before-property": "error",
"object-curly-newline": "error",
"object-curly-spacing": ["error", "always"],
"object-property-newline": "error",
"object-shorthand": "error",
"operator-assignment": "error",
"prefer-arrow-callback": "error",
"prefer-const": "error",
"prefer-destructuring": "error",
"prefer-rest-params": "error",
"prefer-spread": "error",
"prefer-template": "error",
"quote-props": ["error", "consistent-as-needed"],
"quotes": ["error", "single"],
"require-await": "error",
"rest-spread-spacing": "error",
"semi": ["error", "never"],
"sort-imports": "error",
"space-before-blocks": "error",
"space-before-function-paren": ["error", {
"anonymous": "never",
"named": "never",
"asyncArrow": "always"
}],
"space-in-parens": "error",
"space-infix-ops": "error",
"spaced-comment": "error",
"template-curly-spacing": "error",
"valid-jsdoc": "error",
"wrap-iife": "error"
}
}
1 change: 0 additions & 1 deletion src/array/push.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import toArray from 'lodash/toArray'

import update from '../core/update'

/**
Expand Down
1 change: 0 additions & 1 deletion src/array/push.spec.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
/* eslint-env node, mocha */
import { expect } from 'chai'

import push from './push'

describe('Push', () => {
Expand Down
3 changes: 1 addition & 2 deletions src/array/xor.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import xor from 'lodash/xor'

import update from '../core/update'
import xor from 'lodash/xor'

export default update(xor)
1 change: 0 additions & 1 deletion src/array/xor.spec.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
/* eslint-env node, mocha */
import { expect } from 'chai'

import xor from './xor'

describe('Xor', () => {
Expand Down
1 change: 0 additions & 1 deletion src/core/set.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import fpSet from 'lodash/fp/set'

import { lodashFpConvertOptions } from './consts'

const set = fpSet.convert(lodashFpConvertOptions)
Expand Down
1 change: 0 additions & 1 deletion src/core/set.spec.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
/* eslint-env node, mocha */
import { expect } from 'chai'

import set from './set'

describe('Set', () => {
Expand Down
1 change: 0 additions & 1 deletion src/core/unset.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import fpUnset from 'lodash/fp/unset'

import { lodashFpConvertOptions } from './consts'

const unset = fpUnset.convert(lodashFpConvertOptions)
Expand Down
1 change: 0 additions & 1 deletion src/core/unset.spec.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
/* eslint-env node, mocha */
import { expect } from 'chai'

import unset from './unset'

describe('Unset', () => {
Expand Down
9 changes: 3 additions & 6 deletions src/core/update.js
Original file line number Diff line number Diff line change
@@ -1,17 +1,14 @@
import fpUpdate from 'lodash/fp/update'
import isFunction from 'lodash/isFunction'

import { lodashFpConvertOptions } from './consts'

const rawUpdate = fpUpdate.convert(lodashFpConvertOptions)

const updatePassingArgs = (obj, path, fn, ...args) => rawUpdate(obj, path, v => fn(v, ...args))

const update = (...args) => {
if (args.length === 1 && isFunction(args[0])) {
export default (...args) => {
if (args.length === 1 && isFunction(args[0]))
return (obj, path, ...rest) => updatePassingArgs(obj, path, args[0], ...rest)
}

return updatePassingArgs(...args)
}

export default update
1 change: 0 additions & 1 deletion src/core/update.spec.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
/* eslint-env node, mocha */
import { expect } from 'chai'

import update from './update'

describe('Update', () => {
Expand Down
1 change: 1 addition & 0 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ export * from './collection'
export * from './core'
export * from './lang'
export * from './math'
export * from './seq'
4 changes: 1 addition & 3 deletions src/lang/toggle.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import update from '../core/update'

const toggle = update(v => !v)

export default toggle
export default update(v => !v)
1 change: 0 additions & 1 deletion src/lang/toggle.spec.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
/* eslint-env node, mocha */
import { expect } from 'chai'

import toggle from './toggle'

describe('Toggle', () => {
Expand Down
1 change: 0 additions & 1 deletion src/math/add.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import add from 'lodash/add'

import update from '../core/update'

/**
Expand Down
3 changes: 1 addition & 2 deletions src/math/add.spec.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
/* eslint-env node, mocha */
import { expect } from 'chai'

import add from './add'
import { expect } from 'chai'

describe('Add', () => {

Expand Down
73 changes: 73 additions & 0 deletions src/seq/ChainWrapper.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import * as array from '../array'
import * as collection from '../collection'
import * as core from '../core'
import * as lang from '../lang'
import * as math from '../math'

import flow from 'lodash/flow'
import mapValues from 'lodash/mapValues'

/**
* Wrapper allowing to make sequences of immutadot functions calls on a value.
* Instances are created by calling {@link chain}.
* The result of such sequences must be unwrapped with {@link ChainWrapper#value}.
* @memberof seq
* @see {@link chain} for more information.
* @since 0.1.8
*/
class ChainWrapper {

/**
* This constructor should not be called directly.
* Instances are created by calling {@link chain}.
* @param {*} value The value to wrap.
* @protected
* @see {@link chain} for more information.
* @since 0.1.8
*/
constructor(value) {
this._value = value
this._flow = []
}

/**
* Add a function call to the sequence.
* @param {Function} fn The function to call.
* @param {...*} args The arguments for the function call.
* @returns {ChainWrapper} The wrapper instance.
* @private
* @since 0.1.8
*/
_call(fn, args) {
this._flow.push(value => fn(value, ...args))
return this
}

/**
* Executes the chain sequence to resolve the unwrapped value.
* @returns {Object} Returns the resolved unwrapped value.
* @since 0.1.8
*/
value() {
return flow(this._flow)(this._value)
}
}

// Add namespaces functions to the ChainWrapper prototpye
[
array,
collection,
core,
lang,
math,
].forEach(namespace => Object.assign(
ChainWrapper.prototype,
mapValues(
namespace,
fn => function(...args) {
return this._call(fn, args) // eslint-disable-line no-invalid-this
},
),
))

export default ChainWrapper
13 changes: 13 additions & 0 deletions src/seq/chain.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import ChainWrapper from './ChainWrapper'

/**
* Creates an immutadot wrapper instance that wraps value allowing to make sequences of immutadot functions calls on it.
* The result of such sequences must be unwrapped with {@link ChainWrapper#value}
* @function chain
* @memberof seq
* @param {*} value The value to wrap.
* @return {ChainWrapper} Returns the new immutadot wrapper instance.
* @see {@link ChainWrapper} for more information
* @since 0.1.8
*/
export default value => new ChainWrapper(value)

0 comments on commit 91884db

Please sign in to comment.