js-flock
Collection of neat modular utilities for bumping up development in NODE and Browser.
Including library
Library is modular so you can include only modules that you need/use (recommended way of using library). By default unmodified ES6 code is loaded, optionally you can include transpiled ES5 code (recommended for browser environment).
Transpiled code is wrapped in UMD and can be loaded in Browser as CommonJs, AMD or as global var.
const sort = require('js-flock/sort');
const sort = require('js-flock/es5/sort');
const jsFlock = require('js-flock');
const jsFlock = require('js-flock/es5');
Methods:
last
Get the last element of an array. If condition is provided get the last element of an array that meets provided condition or undefined.
since: v2.2.0
const last = require('js-flock/last');
last([1, 4, 2]);
const persons = [{ id: 1, name: 'john'}, { id: 2, name: 'john'}, { id: 3, name: 'doe'}]
last(persons)
last(persons, (p) => p.name === 'john')
last(persons, (p) => p.name === 'no-name')
empty
Remove all items from 1 or more provided arrays.
since: v3.2.0
const empty = require('js-flock/empty');
const arr = [1, 2, 3];
const emptyArr = empty(arr);
console.log(emptyArr === arr)
empty(arr1, undefined, arr2, 3);
single
Returns the only element of a sequence that satisfies a specified condition, and throws an exception if more than one such element exists.
since: v3.13.0
const single = require('js-flock/single');
single([1]);
single([1, 2]);
single([]);
const users = [
{ email: 'john@doe.com', fullName: 'John Doe 1' },
{ email: 'john@doe.com', fullName: 'John Doe 2' },
{ email: 'mark@johnson.com', fullName: 'Mark Johnson' },
];
single(users, user => user.email === 'mark@johnson.com');
single(users, user => user.email === 'john@doe.com');
single(users, user => user.email === 'no@user.com');
NumberIterator
get next number in sequence.
since: v3.9.0
const NumberIterator = require('js-flock/NumberIterator');
const numberIterator = new NumberIterator();
numberIterator.current()
numberIterator.next()
numberIterator.next()
numberIterator.current()
const numberIterator2 = new NumberIterator({ startFrom: 10 });
numberIterator2.current()
numberIterator2.next()
If iterator reaches Number.MAX_SAFE_INTEGER
the iterator exhausted error will be thrown on next iteration call.
castBoolean
Cast any value to boolean value. castBoolean will return true for true or "true" values
while any other value will be evaluated to false.
since: v3.11.0
const castBoolean = require('js-flock/castBoolean');
castBoolean(true);
castBoolean('true');
castBoolean(undefined)
castBoolean('foo')
toEnum
Convert object or list of strings to enum representation.
Enum representation is immutable (frozen)
const toEnum = require('js-flock/toEnum');
const vehicleType = toEnum({
CAR: 'C',
TRUCK: 'T',
AIRPLANE: 'A',
HELICOPTER: 'H',
canFly(type) {
return type === this.AIRPLANE || type === this.HELICOPTER;
}
});
const vehicle = getVehicle();
if (vehicle.type === vehicleType.TRUCK) {
}
if (vehicleType.canFly(vehicle.type)) {
}
vehicleType.TRUCK = 'boat';
vehicleType.keys();
vehicleType.values();
vehicleType.exists('C');
vehicleType.exists('something');
vehicleType.haveKey('CAR');
vehicleType.haveKey('something');
const gender = toEnum(['MAN', 'WOMEN', 'OTHER']);
gender.keys();
gender.values();
singular
Creates singular function that after is called can't be called again until it finishes with execution.
Singular function injects done function as a first argument of the original function.
When called done indicates that function has finished with execution and that it can be called again.
For example we will use Vue.js and click handler.
<span @click="save()" role="button">Save User</span>
const singular = require('js-flock/singular');
export default {
methods: {
save: singular(function(done) {
UserService.save(this.user)
.then(() => { })
.catch(() => { })
.then(done);
}
};
}
waitFor
Wait for task to complete before executing function. This module is useful when there isn't event
you can hook into to signify that a given task is complete. waitFor returns promise that resolves
after check function returns truthy value.
since: v2.4.0
const waitFor = require('js-flock/waitFor');
const options = {
interval: Number,
timeout: Number,
};
waitFor(() => Db.connection, options)
.then((connection) => { })
.catch(() => { });
waitFor(() => document.getElementById('elId'))
.then(($el) => { })
.catch(() => { });
waitFor((abort) => {
if(componentIsDestroyed) {
abort();
} else {
return document.getElementById('elId');
}
})
.then(($el) => { })
.catch(() => { });
rerun
setInterval on steroids.
since: v3.3.0
rerun(Function)
.every(timeInMilliseconds)
.asLongAs(Function)
.start()
.onStop(Function)
.stop()
const tenMinutesInMs = 10 * 60 * 1000;
const refreshTokenRunner = rerun(refreshAuthToken)
.every(tenMinutesInMs)
.asLongAs(isUserLoggedIn);
eventBus.$on('login', refreshTokenRunner.start);
delay
Delay a promise a specified amount of time. Think of it as setTimeout for async flow
since: v3.8.0
const delay = require('js-flock/delay');
async exampleFunction() {
bar();
await delay(100);
baz();
}
promiseAll
Alias for Promise.all
that works on objects and arrays
since: v3.7.0
const promiseAll = require('js-flock/promiseAll');
const objectResponse = await promiseAll({
users: db.fetchUsers(),
schools: db.fetchSchools(),
});
const arrayResponse = await promiseAll([db.fetchUsers(), db.fetchSchools()]);
promisify
Promisify error first callback function. Instead of taking a callback, the returned function
will return a promise whose fate is decided by the callback behavior of the given node function.
Promisify returns native Promise (requires Promise polyfill on older browser)
const promisify = require('js-flock/promisify');
const readFile = require("fs").readFile;
const readFileAsync = promisify(readFile);
readFile('test.txt', 'utf8', (err, data) => {
if (err) {
console.log(err);
return;
}
console.log(data);
});
readFileAsync('test.txt', 'utf8')
.then((data) => console.log(data))
.catch((err) => console.log(err));
If callback function is called with multiple success values, the fulfillment value will be the
first fulfillment item.
Setting multiArgs options to true means the resulting promise will always fulfill with
an array of the callback's success value(s). This is needed because promises only support a
single success value while some callback API's have multiple success value.
const fun = (cb) => cb(undefined, 'res1', 'res2');
const funAsync = promisify(fun, { multiArgs: true });
funAsync().then(([r1, r2]) => { });
promisify.all
Promisify the entire object by going through the object's properties and creating
an async equivalent of each function on the object.
Promisify.all mutates input object by adding promisified versions to object.
It will never overwrite existing properties of object.
By default promisify.all does not loop over object prototype which can be change by providing
{ proto: true } option.
The promisified method name will be the original method name suffixed with suffix (default = 'Async').
const promisify = require('js-flock/promisify');
const fs = promisify.all(require("fs"));
fs.readFileAsync('test.txt', 'utf8')
.then((data) => console.log(data))
.catch((err) => console.log(err));
const withOptions = promisify.all(test, {
suffix: String,
multiArgs: Boolean,
proto: Boolean,
exclude: [String],
include: [String],
});
collar
Set maximum waiting time for promise to resolve. Reject promise if it's not resolved in that time
const collar = require('js-flock/collar');
const MAX_WAITING_TIME = 500;
collar(Http.get('test-url'), MAX_WAITING_TIME)
.then((response) => { })
.catch((err) => {
if (typeof err === 'object' && err.isStrangled) {
console.log(err.message);
}
});
deepFreeze
Recursively apply Object.freeze
const deepFreeze = require('js-flock/deepFreeze');
const person = {
fullName: 'test person',
dob: new Date(),
address: {
country: 'testiland',
city: 'this one'
}
};
Object.freeze(person);
Object.isFrozen(person);
Object.isFrozen(person.address);
deepFreeze(person);
Object.isFrozen(person);
Object.isFrozen(person.address);
deepFreeze(object, {
proto: Boolean,
exclude: Function,
});
deepFreeze(person, {
exclude(key, context) {
return key === 'address' && context === person;
}
});
deepSeal
Recursively apply Object.seal.
For example of usage reference deepFreeze
deepPreventExtensions
Recursively apply Object.preventExtensions.
For example of usage reference deepFreeze
sort
Source code of sort has been moved to dedicated package https://www.npmjs.com/package/fast-sort and is now just imported here.
For more info on sort please check dedicated package from above.
const sort = require('js-flock/sort');
sort([1, 4, 2]).asc();
sort([1, 4, 2]).desc();
sort(persons).asc(p => p.firstName);
sort(persons).desc([
p => p.firstName
p => p.address.city
]);
sort(persons).by([
{ asc: 'name' }
{ desc: 'age' }
{ asc: p => p.address.city }
]);