Javascript Syntax Sugar for Higher-Order Messaging
Jewell leverages the power of ES6 Proxy to provide syntax sugar, allowing you to write cleaner code.
The best way to showcase Jewell is through code samples:
import {jewellPrototype} from 'jewell';
jewellPrototype(Array);
const diamonds = [...];
// Get price: [2k, 100k, 300k]
diamonds.map.price; // 💎
diamonds.map(diamond => diamond.price); // Traditional
// Buy all pink diamonds
diamonds.filter.pink.forEach.buy(); // 💎
diamonds.filter(diamond => diamond.pink).forEach(diamond => diamond.buy()); // Traditional
npm install jewell --save
And to import:
import jewell, {jewellPrototype} from 'jewell';
Note: You may need an ES6 Proxy
polyfill to support older browsers.
jewell(object: object, propertyName: string)
: Proxies function property. Bear in mind the property must already exist.jewellPrototype(class: object, except: string[])
: Proxies all functions with zero or one argument in a class prototype.._fn
: After proxying, the original method can be accessed through ._fn
.âš Warning: Be aware that jewell(...)
and jewellPrototype(...)
replace the original methods with proxies.
This package was created for experimental purposes, but if you decide to use it in production, make sure you're not creating unintendend behaviors or performance issues.
This means only a single instance will be jewelled.
const object = [{name: 'John'}, {name: 'Jane'}];
jewell(object, 'map');
This means all instances of a class will the property jewelled.
jewell(Array.prototype, 'map');
jewellPrototype(Array, ['shift']); // Proxy functions with one or zero args except 'shift
The examples below expect jewellPrototype(Array)
to have been called.
const fruits = [{name: 'Apple'}, {name: 'Grape'}];
fruits.map.name; // ['Apple', 'Grape']
Equivalent to fruits.map(fruit => fruit.name)
.
const photos = [...];
photos.map.crop(0, 0, 50, 50);
Equivalent to photos.map(photo => photo.crop(0, 0, 50, 50))
const diamonds = [...];
diamonds.forEach.sell();
Equivalent to diamonds.forEach(diamond => diamond.sell())
const kittens = [...];
kittens.forEach.feed('fish', 3);
Equivalent to kittens.forEach(kitten => kitten.feed('fish', 3))
const employees = [...];
employees.filter.retired;
const employees = [...];
employees.filter.compliesTo('rule');
Equivalent to employees.filter(employee => employee.compliesTo('rule'))
const animals = [...];
animals.filter.friendly.map.name;
Equivalent to animals.filter(animal => animal.friendly).map(animal => animal.name)
const employees = [...];
employees.every.retired; // true or false
Equivalent to employees.every(employee => employee.retired)
jewell(array, 'shift');
array.shift._fn // Original method
If you have some other cool examples, you're very welcome to open a PR.
The logo was created by Xicons.co and can be found here.
Jewell is inspired by @franzliedke's implementation of higher-order messaging for Laravel and by Nat Pryce's article on higher-order messaging with Ruby.
Ultimately it would be very nice to have higher-order messaging implemented as a native Javascript feature, but until then, there's Jewell.