An open API service indexing awesome lists of open source software.

https://github.com/momsfriendlydevco/chainable

Tiny, zero-dependency chainable object wrapper
https://github.com/momsfriendlydevco/chainable

Last synced: 6 months ago
JSON representation

Tiny, zero-dependency chainable object wrapper

Awesome Lists containing this project

README

          

@MomsFriendlyDevCo/Chainable
============================
Make any JavaScript object a chainable, functional interface.

This library is _intentionally_ tiny and dependency free. The entire library, minified is less than 1kb!

**Make the tiny Mitt event library chainable**

```javascript
import chainable from '../lib/chainable.js';
import mitt from 'mitt';

let emitter = chainable(mitt)
.on('blarp', ()=> { /* Handle blarp emit */ })
.on('flonk', ()=> { /* Handle flonk emit */ })
.emit('blarp')
.value() // Get original unwrapped emitter
```

**Make a browser DOM element chainable**
```javascript
import chainable from '@momsfriendlydevco/chainable';

// Make a chainable DOM object
chainable(document.createElement('div'));
.addEventListener('click', ()=> { /* Handle clicks */ })
.set('style.position', 'absolute') // Set a deeply nested property
.value() // Output the original object (if needed)
```

Why?
----
This library exists this because handling chainability in some non-chainable interfaces gets repetitive.

```javascript
// Horrible

setup using the native DOM
let widget = document.createElement('div');
widget.addEventListener('click', ()=> { /* Handle click */ });
widget.style.position = 'absolute';
widget.style.top = '0px';
widget.style.left = '0px';
widget.classList.add('red');

document.body.append(widget);
```

```javascript
// Equivalent using chainable
document.append(
chainable(document.createElement('div'));
.addEventListener('click', ()=> { /* Handle clicks */ })
.set('style.position', 'absolute') // Set a deeply nested property
.set('style.top', '0px')
.set('style.left', '0px')
.call('classList.add', 'red')
.value() // Output the original raw DOMElement
);
```

API
===

chainable(object)
-----------------
Create a new chainable instance.
This also sets `$source` to the original object.

chainable.$source
-----------------
Also available as `chainable.source` if there isn't any conflict with the name.
The chainable source object.
Generally you don't want to access this directly.

chainable.$call(name, ...args)
------------------------------
Also available as `chainable.call(name, ...args)` if there isn't any conflict with the name.
As with `.$get` the name can be in dotted notation or array notation for deeply nested methods.
Call a method on source but ignore the response and return the chainable instance.

chainable.$set(key, val)
------------------------
Also available as `chainable.set(key, val)` if there isn't any conflict with the name.
Set one or more properties within a source object.
Can be called as a simple key/val setter - `chainable.$set(keyName, value)` - or as an object - `chainable.$set({key1: val1, key2: val2})`
The key can also use dotted notation (e.g. `this.is.a.nested.key`) or an array notation (e.g. `['this', 'is', 'a', 'nested', 'key']`) to set deeply nested properties.
Returns the chainable instance.

chainable.$get(path)
--------------------
Also available as `chainable.get(path)` if there isn't any conflict with the name.
Fetch a value from the source object, returning it.
The path can also use dotted notation (e.g. `this.is.a.nested.key`) or an array notation (e.g. `['this', 'is', 'a', 'nested', 'key']`) to get deeply nested properties.
Returns the value found at the path or undefined if none.

chainable.$value()
------------------
Also available as `chainable.value()` if there isn't any conflict with the name.
Return the original source object - i.e. unwrap the original.

chainable.$tap(callback)
------------------------
Also available as `chainable.tap(callback)` if there isn't any conflict with the name.
Run a callback inline as `(chainable) => { /* handler */ }`, ignore the result and return the chainable instance.

chainable.$thru(callback)
-------------------------
Also available as `chainable.tap(callback)` if there isn't any conflict with the name.
Run a callback inline as `(chainable) => { /* handler */ }`, take the returned value as the new `$source` and and return the chainable instance.

chainable.$replace(newState)
----------------------------
Replace the target item if it looks like an object
This is really only used when overwriting internal state or possibly replacing the state object due to a `$thru()` or `$call` return.
Returns the chainable instance.