Giter VIP home page Giter VIP logo

tommmyy / ramda-extension Goto Github PK

View Code? Open in Web Editor NEW
165.0 7.0 24.0 9.5 MB

🤘Utility library for functional JavaScript. With ❤️ to Ramda.

Home Page: https://ramda-extension.web.app/

License: Apache License 2.0

JavaScript 21.44% HTML 76.29% CSS 0.01% Handlebars 1.31% Less 0.89% Pug 0.04% Shell 0.02%
ramda ramda-functions utils utilities tools toolset extensions ramda-extension functional-programming pointfree

ramda-extension's Introduction

Ramda!

🤘🤘🤘

Utility library for functional JavaScript.

Library adds utilities functions that are built on the top of marvelous Ramda library.

Play wit Ramda and Ramda-extension in REPL.

See our documentation site.

Github Apache-2.0 Travis Downloads Version

import { cx } from 'ramda-extension';

cx({ box: true, 'box--outline': false }, 'width-100'); // ".box .width-100"

Why to choose ramda-extension over other libraries?

We focus on functional point-free code. Our goal is to keep codebase composed only from ramda functions, not from own code. Basically, we are using only const and ES6 modules from the JavaScript itself.

We have a few functions with side-effects (like log and trace) to support better developer's experience in debugging process. It is only for development purpose and it should not be used in production code.

Installation

$ yarn add ramda ramda-extension

or

$ npm install ramda ramda-extension

Usage

We support CommonJS and ES modules syntax.

Import function as a named export (not recommended without treeshaking):

import { toKebabCase } from 'ramda-extension';
import { flatten } from 'ramda'; // standard ramda function (if needed)

toKebabCase('I wanna eat my kebab.') // "i-wanna-eat-my-kebab"
flatten([1, 2, [3, 4], 5]) // [1, 2, 3, 4, 5]
  • NOTE: standard ramda functions are still accessed via 'ramda'

Alternatively you can import it separately if your environment doesn't support treeshaking (Sse babel-plugin-transform-imports):

import toKebabCase from 'ramda-extension/lib/toKebabCase';

toKebabCase('I wanna eat my kebab.') // "i-wanna-eat-my-kebab"

If you prefer jQuery-style:

import * as R_ from 'ramda-extension'

R_.toKebabCase('I wanna eat my kebab.') // "i-wanna-eat-my-kebab"

NOTE: Ramda itself is not part of bundle, you need to add it manually

CDN

You can use Ramda-extension directly in the browser:

<script src="https://cdn.jsdelivr.net/npm/ramda@latest/dist/ramda.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/ramda-extension@latest/dist/ramda-extension.min.js"></script>

Articles & Resources

Contributing

Most of the functions have its own tests and examples in the JS Doc.

Feel free to either contribute yourself or submit an issue if there is a bug or you have an idea for a new extension.

We are open to all ideas and suggestions, feel free to open an issue or a pull request!

See the contribution guide for guidelines.

License

All packages are distributed under the Apache 2.0 license. See the license here.

ramda-extension's People

Contributors

aizerin avatar bradcomp avatar carina-akaia avatar cglane avatar datenreisender avatar dependabot[bot] avatar drttnk avatar goldhand avatar jbradle avatar jozefe avatar jsdelivrbot avatar lukasduspiva avatar mattcain avatar neerajsingh0101 avatar nfantone avatar spacesuitdiver avatar tommmyy avatar trustedtomato avatar wafflepie avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

ramda-extension's Issues

Build size optimalization

  • use sideEffects: false
  • trace why the es distribution does break tree-shaking
  • create sample repo with R_ and Webpack for easy debugging and experimenting

objOfOver

objOfOver(
    R.lensPath(['a', 'b']),
    (x) => "Hello " + x,
    {
        a: { b: 'foo' },
        c: 'bar',
    }
)
// { a: { b: "Hello foo" } }

dispatchWith

dispatch is great, but sometimes R.isNil is not desirable... see:

const getFirstBirthNumber = path([0, 'birthNumber']);

const getBirthNumber = R_.dispatch([
  o(when(complement(Boolean), R_.noop), R_.headArg),
  compose(getFirstBirthNumber, R_.lastArg)
])

getBirthNumber("x", [{ contract: { birthNumber: "s" } }])

with something like dispatchWith, can be example above simplified to:

const getFirstBirthNumber =path([0,  'birthNumber']);
const firstTruthy = R_.dispatchWith(complement(Boolean));

const getBirthNumber = firstTruthy([R_.headArg, compose(getFirstBirthNumber, R_.lastArg)])

getBirthNumber("x", [{ contract: { birthNumber: "s" } }])

defaultTo*

  • defaultToNull
  • defaultToFalse
  • defaultToTrue
  • defaultToEmptyObject
  • defaultToEmptyArray
  • defaultToEmptyString
  • defaultToZero
  • defaultToOne

Did I missed something?

nthArgs

const firstAndLastArg = R_.nthArgs([0, -1])

const f = (a, b) => [a, b];

firstAndLastArg(f)('first', 'second', 'last') // ['first', 'last']

isPlainObject

		expect(isPlainObject(null)).toBe(false);
		expect(isPlainObject([])).toBe(false);
		expect(isPlainObject(new Date())).toBe(false);
		expect(isPlainObject(new Error())).toBe(false);
		expect(isPlainObject(undefined)).toBe(false);
		expect(isPlainObject('[object Object]')).toBe(false);

		expect(isPlainObject({})).toBe(true);
		expect(isPlainObject(Object.create(null))).toBe(true);
		expect(isPlainObject({ constructor: () => {} })).toBe(true);

mergeDeepLeftAll, mergeDeepRightAll

const mergeDeepRightAll = reduce(mergeDeepRight, {});
const mergeDeepLeftAll = reduce(mergeDeepLeft, {});

mergeDeepRightAll([
     { foo: { bar: 1 } },
     { foo: { bar: 2, a: 1 } },
     { foo: { bar: 3, b: 2 } },
])
// { foo: { bar: 3, a: 1, b: 2 } }

mergeDeepLeftAll([
     { foo: { bar: 1 } },
     { foo: { bar: 2, a: 1 } },
     { foo: { bar: 3, b: 2 } },
])
// { foo: { bar: 1, a: 1, b: 2 } }

`mergeDeepAllWith`

R_.mergeDeepAllWith(R.concat, [
  { a: { b: [1] } },
  { a: { b: [2] } },
  { a: { b: [3] } },
]) // { a: { b: [1, 2, 3] } }

alwaysEmptyObject and alwaysEmptyArray do not always return empty array or object

Output from alwaysEmptyArray and alwaysEmptyObject cannot be trusted to be always empty. Specially if their outputs are being passed around as inputs to third party libraries. This can lead to hard to track bugs and odd behaviors.

R_.alwaysEmptyArray(); // []
R_.alwaysEmptyArray().push(42); 
R_.alwaysEmptyArray(); // [42] <- return value has been changed forever for every other subsequent call

I propose we either:

  • Change the name of the functions to reflect the above fact.
  • Return a R.clone of the emptyArray or emptyObject each time:
const alwaysEmptyArray = () => clone(emptyArray);
  • Leverage the new (unreleased as of yet) R.thunkify function to create a point-free reusable factory of clones and implement other always* functions based off of it.
const alwaysNew = thunkify(clone);
const alwaysEmptyArray = alwaysNew(emptyArray);

DISCLAIMER: I was the author of the thunkify PR.

cx function leaves strings with spaces

Hello,

we use cx as a replacement of classNames lib.

But unfortunatelly it produces final classnames with more spaces than necessary.
For example:

R_.cx(['Table', 'MagicTable '])    // "Table MagicTable "
R_.cx(['Table', '    MagicTable']) // "Table     MagicTable"
R_.cx([' Table', 'MagicTable'])    // " Table MagicTable"

It would be nice if cx remove unnecessary spaces, isn't it?

callIfFunction, applyIfFunction

const ref = { current: null };
const getRef = always(ref);
const createRef = (current) => ({ current });

applyIfFunction(ref, []); // { current: null }
applyIfFunction(getRef, []); // { current: null }
applyIfFunction(createRef, [document.body]); // {"current": [object HTMLBodyElement]}

callIfFunction(ref) // { current: null }
callIfFunction(getRef) // { current: null }
callIfFunction(createRef, document.body) // {"current": [object HTMLBodyElement]}

I ofter use the function in React components.
Sometimes a property is either function (then you need to call it) or just static value.

fork ramda docs

Fork ramda docs and use it same way for the ramda-extension.

must be compatible with github pages.

Docs: Links to source code is not working

Instead of

https://github.com/tommmyy/ramda-extension/tree/0.3.0/packages/ramda-extension/src/isNilOrEmptyString.js

there is:

https://github.com/tommmyy/ramda-extension/tree/0.3.0/src/isNilOrEmptyString.js

sortByProp, sortByPath, sortByDotPath, sortByLens

sortByProp("foo")([{ foo: 2 }, {  foo: -2 }]) 
// [{ foo: -2 }, {  foo: 2 }]

sortByPath(["foo", "bar"])([{ foo: { bar: 2 } }, {  foo: { bar: -2 } }]) 
// [{ foo: { bar: -2 } }, {  foo: { bar: 2 } }]
 
sortByDotPath("foo.bar")([{ foo: { bar: 2 } }, {  foo: { bar: -2 } }]) 
// [{ foo: { bar: -2 } }, {  foo: { bar: 2 } }]

sortByLens(lensPath(["foo", "bar"]))([{ foo: { bar: 2 } }, {  foo: { bar: -2 } }]) 
// [{ foo: { bar: -2 } }, {  foo: { bar: 2 } }]

Implement fulltext search function for an array of objects

it would be nice to have a fulltext search function that is able to search according to given string value in the array of objects values.

And it would be even nicer if that search function could search through an array of deeply nested objects.

Example:
input array:
[
{
"id": 1,
"name": "Exposure time",
"description": "Possible exposure times",
"type": "text",
"language": "en",
"attributes": {
"min": "1/1000 sec",
"max": "30 sec"
},
},
{
"id": 2,
"name": "Durability",
"description": "Durable material",
"type": "text",
"language": "en"
},
{
"id": 3,
"name": "Stabilizer",
"description": "Stabilizer enabled",
"type": "boolean",
"language": "en"
}
]

search string: "sec"
result:
[
{
"id": 1,
"name": "Exposure time",
"description": "Possible exposure times",
"type": "text",
"language": "en",
"attributes": {
"min": "1/1000 sec",
"max": "30 sec"
},
}
]

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.