SkillAgentSearch skills...

Unction.js

[DEPRECATED] A set of type annotated FP functions that enforce currying and composability

Install / Use

/learn @krainboltgreene/Unction.js
About this skill

Quality Score

0/100

Supported Platforms

Universal

README

DEPRECATED: This library is too large to keep in one repository. I have moved to a multi-repository solution: github.com/unctionjs

@unction/*

A set of very useful function. These functions are bound by these principles:

  1. All functions will have type annotations.
  2. All functions will only take a single argument.
  3. All functions are curried.
  4. All inner functions will be named based on the outer function and it's argument name.
  5. Functions that deal with key values will take KeyChains (a list of keys).
  6. Functions that deal with types will take their string name form.
  7. Functions that mutate the original value, though rare, will have a suffix of M.
  8. Functions that take or return promises will have a suffix of P.
  9. Functions that can work on one type of Iterable can work on another type, covering: - List (Array, Set, WeakSet) - Record (object, Map, WeakMap) - String - Stream (xstream)

![Tests][BADGE_TRAVIS] ![Stability][BADGE_STABILITY] ![Dependencies][BADGE_DEPENDENCY]

using

Each function is a unique package with it's own source, transpiliation, and tests. To get a function simply install:

$ npm install --save-dev @unction/hammer@latest

and then import:

import hammer from "@unction/hammer"

@unction/allObjectP

({[key: KeyType]: any | Promise<any>}) => Promise<{[key: KeyType]: any}>

This takes an object where the values are probably promises and returns a promise that has that same object but with the resolved values.

Here's a good example of this function in use:

function signUp (attributes, slug) {
  return function thunk (dispatch, getState, {client}) {
    return allObjectP({
      loading: startLoading(slug),
      session: pushSession(attributes, client)
    })
      .then(({session}) => {
        return allObjectP({
          merge: mergeResource(session),
          current: storeCurrent(session.id),
          account: pullAccount(session.relationship.account.data.id, client),
        })
      })
      .then(({account}) => {
        return {
          merge: mergeResource(account),
          current: storeCurrent(account.id),
        }
      })
      .then(() => stopLoading(slug))
      .then(() => dispatch({type: "signUp"}))
      .catch(logger.error.bind(error))
  }
}

If we use allP or Promise.all we're getting an array back, but that's annoying to destructure. The allObjectP function gives us the concurrency we want with a named interface for the returned resolutions.

@unction/allP

Array<any | Promise<any>> -> Promise<Array<any>>

A port of the Promise.all() function.

Credit: @keithamus

@unction/always

any -> any -> any

Always returns the value given when called

always(1)() // 1
always(1)(0) // 1

@unction/append

any -> Array<any> -> Array<any>

Takes a value and puts it at the end of the given list

append(4)([5]) // => [5, 4]

@unction/appendM

any -> Array<any> -> Array<any>

Takes an array and an item and returns the combination of both, appended.

NOTE: This mutates the array

const data = [1, 2, 3]

appendM(4)(data)

Would return:

[1, 2, 3, 4]

@unction/applicator

(ValueType -> any) -> any

Takes a function and a value and applies that function to that value.

applicator(inc)(1) // 1

@unction/applicators

Iterable<ValueType -> ValueType> -> Iterable<ValueType> -> Array<ValueType>

Takes a list of functions and a list of values and applies the values to the functions.

applicators([
  recordfrom(["point", "x"]),
  recordfrom(["point", "y"]),
  recordfrom(["point", "z"]),
])([
  40.453,
  2.2,
  423.0,
])

returns

[
  {point: {x: 40.453}},
  {point: {y: 2.2}},
  {point: {z: 423.0}},
]
applicators({
  x: inc,
  y: dec
})({
  x: -1,
  y: 1
})

returns

{
  x: 0,
  y: 0
}

@unction/arrayify

any -> [any] | Array<any>

Takes a value and turns it into an array of that value, unless the value is already an array.

arrayify("a")

returns

["a"]
arrayify(["a"])

returns

["a"]

@unction/aside

Array<(any => any)> -> any -> any

Use this function to do thing aside of a main pipeline.

export default function generateGraph () {
  return pipe(
    aside([format, log]),
    processData
  )
}

@unction/attach

KeyType -> ValueType -> IterableType -> IterableType

A polymorphic way to attach a value to an iterable

attach("hello")("world")({}) // => {hello: "world"}

@unction/cascadingKeyChain

Array<UnfinishedKeyChainType> -> IterableType -> ValueType

Cascades through multiple keychains in order to arrive at a value. Null keys are replaced with the previous keychain's value.

cascadingKeyChain(
  [
    ["ephemeral", "current", "session"],
    ["resources", "sessions", null, "relationships", "account", "data", "id"],
    ["resources", "accounts", null, "attributes", "name"]
  ]
)(
  {
    ephemeral: {current: {session: "1"}},
    resources: {
      sessions: {
        1: {
          id: "1",
          relationships: {account: {data: {id: "2"}}},
        },
      },
      accounts: {
        2: {
          id: "2",
          attributes: {name: "Kurtis Rainbolt-Greene"},
        },
      },
    },
  }
)

returns

"Kurtis Rainbolt-Greene"

@unction/catchP

(any -> any) -> Promise<any> -> Promise<any>

A port of the Promise.prototype.catch() function.

Credit: @keithamus

@unction/compact

Array<any> -> Array<mixed>

Takes a collection (Array or Object) and returns a copy of that value without null or undefined values.

avatarUrls // => [null, "/1.jpg", null, "/3.jpg"]
compact(avatarUrls)  // => ["/1.jpg", "/3.jpg"]

head(users) // {"avatar": null, "name": "Kurtis Rainbolt-Greene"}
compact(head(users)) // {"name": "Kurtis Rainbolt-Greene"}

@unction/computedProp

(IterableType -> any) -> Keychain -> IterableType -> IterableType

Given an object this function will return that object but with a new property, where the value is computed. The computation is given the object you'll be copying.

const computer = ({id, attributes: {username}}) => `${username}#${id}`
const key = "tag"
const payload = {
  id: "1",
  attributes: {
    username: "krainboltgreene"
  }
}

computedProp(computer)(key)(payload)

Would return:

{
  id: "1",
  tag: "krainboltgreene#1",
  attributes: {
    username: "krainboltgreene"
  }
}
const multiKey = ["attributes", "tag"]

computedProp(computer)(key)(payload)

Would return:

{
  id: "1",
  attributes: {
    tag: "krainboltgreene#1",
    username: "krainboltgreene"
  }
}

@unction/couple

any -> any -> [any, any]

Takes any value and then any value and returns an array containing those values.

couple(4)(5) // => [4, 5]

@unction/domEvents

DOMEventsConfigurationType -> DOMEventNameType -> DOMStreamType -> DOMEventStreamType

Takes a configuration, an event name, and a DOM source and returns an observable of that event type

domEvents({})("click")(DOM)

returns

--click--click--click-->

@unction/domEventsMany

domEventsManyConfigurationType -> (string | Array<DOMEventNameType>) -> DOMEventStreamType

Takes many events or * and returns an observable of those events

domEventsMany({})(["click", "input"])(DOM)

returns

--click--input--input--click--input
domEventsMany({})("*")(DOM)

returns

--click--input--hover--change--click-->

@unction/endsWith

string -> string -> boolean

Determines if a given subset of text is at the end of another set of text.

endsWith("!")("Hello, world!") // true

@unction/everyP

(Array<any | Promise<any>>) -> Promise<[ResolvedPromisesType, RejectedPromisesType]>

Returns both resolved and rejected promises as distinct lists.

@unction/flattenTree

((any -> any) -> IterableType -> IterableType) -> (any -> any) -> number -> IterableType -> IterableType

Takes a tree and creates a single object where the root keys are conjoined nested keys.

flattenTree({
  data: {
    profile: {
      name: "Kurtis Rainbolt-Greene"
      age: 24
    },
    metadata: {
      interval: "10s"
    },
    location: "http://api.example.com/profiles/24"
  }
})

Would return:

{
  "data-profile-name": "Kurtis Rainbolt-Greene",
  "data-profile-age": 24,
  "data-interval": "10s",
  "data-location": "Kurtis Rainbolt-Greene"
}

@unction/flip

(any -> any) -> any -> any -> any

Flips a function's first and second arguments.

flip(key)({aaa: "1"})("aaa") // "1"

@unction/forEach

(any -> KeyType -> any) -> IterableType -> IterableType

Takes any kind of iterable object and figures out the best way to iterate over it.

forEach((x) => y)([])
forEach((x) => y)(new Map)
forEach((x) => y)({})

@unction/fresh

IterableType -> IterableType

Takes a iterable and returns an empty fresh version of that iterable.

fresh({aaa: "aaa"}) // {}
fresh(["aaa"]) // []
fresh({}) // {}
fresh([]) // []

@unction/hammer

KeyType -> IterableType -> IterableType

Use this to de-nest a nested object.

const payload = {
  id: 1
  attributes: {
    name: "Kurtis Rainbolt-Greene",
    age: 26
  }
}

hammer("attributes")(payload)

Which returns:

{
  id: 1,
  name: "Kurtis Rainbolt-Greene",
  age: 26
}

@unction/ifThenElse

PredicateType -> (any -> any) -> (any -> any) -> any

Based on a predicate it passes the value to a consequent or alternative fun

View on GitHub
GitHub Stars13
CategoryDevelopment
Updated3y ago
Forks0

Languages

JavaScript

Security Score

80/100

Audited on Jan 28, 2023

No findings