Skip to content

🏄 Your functional (sync/async) pipe | operator

License

Notifications You must be signed in to change notification settings

aeciolevy/tubo.js

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

74 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

tubo.js

 Travis CI codecov

Tubo works like the pipe operator more common in functional programming languages, like Elixir.

This lib supports sync and async arguments.

If all arguments are sync functions or literal, the pipeline will run as a normal function returning the last value computed. In case one of the arguments is a function that returns a promise or a promise instance (then-able object), a promise will be returned at the end.

Usage

Sync

function double(x) {
  return x * 2
}

function square(x) {
  return x * x
}

var output = tubo(
  2,
  double,
  square
)
console.log(output) // => 16

Async

try {
  const result = await tubo(
    bookingDetails.userId,
    fetchUserById, // async
    JSON.parse
  )
  console.log(result)
} catch (error) {
  console.error(error)
}

Async with Promise

tubo(
  bookingDetails.userId,
  fetchUserById, // async
  JSON.parse
)
  .then(function(result) {
    console.log(result)
  })
  .catch(function(error) {
    console.log(error)
  })

Mixed

It is also possible to mix sync and async arguments. Whenever a function that generates promises or a promise intance is found, the lib switchs to async mode and will return a Promise.

Installation

To use the library, install it through npm

npm install tubo --save

To port it to Browser or any other (non CJS) environment, use your favorite CJS bundler. No favorite yet? Try: Browserify, Webmake or Webpack.

Examples

Validation (sync and async)

// Before
function validateEmail(email) {
  email = trim(email)
  validateEmailTld(email)
  validateEmailFormat(email)
}

// After
function validateEmail(email) {
  return tubo(
    email,
    trim,
    validateEmailTld,
    validateEmailFormat
  )
}

try {
  validateEmail('[email protected]')
} catch (error) {
  console.log(error)
}

Straight-forward Cases

// Before
if (cache && localStorage.getItem(endpoint)) {
  return m.prop( JSON.parse( localStorage.get(endpoint) ) )
}

// After
if (cache && localStorage.getItem(endpoint)) {
  return tubo(
    localStorage.get(endpoint),
    JSON.parse,
    m.prop
  )
}

Usage with const

// Before
let items = base64ToJSON(response.data.content)
items = Array.isArray(items) ? items : [items]

// After
const items = tubo(
  base64ToJSON(response.data.content),
  x => Array.isArray(x) ? x : [x]
)

Functional Updates

// Before
return Event.create(
  Object.assign(attrs, { parent_id: parentId, status: 'draft' })
)

// After
return tubo(
  Object.assign(attrs, { parent_id: parentId, status: 'draft' }),
  Event.create
)

Reference and credits


caiogondim.com  ·  GitHub @caiogondim  ·  Twitter @caio_gondim

About

🏄 Your functional (sync/async) pipe | operator

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages

  • JavaScript 100.0%