zangetsu
v0.2.1
Published
Object Sword
Downloads
2
Readme
Zangetsu (斬月, Slaying Moon) is a sword used by the character Ichigo Kurosaki in the Bleach series.
$ yarn add zangetsu
Mutable & Immutable
This library exposes two namespaces: Mutable
and Immutable
.
Use Immutable
if you need to produce a new object.
Mutable
- to modify existing one.
import { Immutable } from 'zangetsu';
...
let foo = {foo: 'Foo'};
let bar = {bar: 'Bar'};
let fooBar = Immutable.compose(foo).append(bar);
assert(fooBar !== foo); // different objects
import { Mutable } from 'zangetsu';
...
let foo = {foo: 'Foo'};
let bar = {bar: 'Bar'};
let fooBar = Mutable.compose(foo).append(bar);
assert(fooBar === foo); // fooBar and foo hold same reference. In other words foo is not { foo: 'Foo' } any more.
console.log(foo); // will print out { foo: 'Foo', bar: 'Bar' }
Declarative Syntax
This library can extend objects with additional fields, remove fields with projection operator $
and do it as a part of logical branching (if
, elseif
and else
):
import { Immutable } from 'zangetsu';
...
Immutable
// compose a new object
.compose({
hello: 'World!'
})
// extend with another object
.append({
alice: 'Alice'
})
// extend if condition is satisfied
.if(hasFoo && hasBar, {
foo: 'Foo',
bar: 'Bar'
})
// or if another condition is satisfied
.elseif(hasFoo, {
foo: 'Foo'
})
// the chain could be long and it will stay readable
.elseif(hasBar, {
bar: 'Bar'
})
.else({
noFooNoBar: 'NoFooNoBar'
})
// build projections to filter fields
.$({
hello: false,
alice: false,
foo: true,
bar: true,
noFooNoBar: true
})
// return the result
.val();
| hasFoo \ hasBar
| true
| false
|
| --------------- | --------------------------- | ------------------------------ |
| true | { foo: 'Foo', bar: 'Bar'
}| { foo: 'Foo' } |
| false | { bar: 'Bar'
} | { noFooNoBar: 'NoFooNoBar' } |
Real Life Example
Suppose you need to compose an HTTP request to upload a file to a server. You decided to set content type based on a file extension and apply gzip for javascript and css files.
import { Immutable } from 'zangetsu';
...
const createRequest = (payload: any, fileExt: string) =>
Immutable
.compose({
body: { ...payload }
}).if(fileExt === 'js', {
contentType: 'text/javascript'
}).elseif(fileExt === 'css', {
contentType: 'text/css'
}).else({
contentType: 'application/octet-stream'
}).if(['js', 'css'].includes(fileExt), {
encoding: 'gzip'
}).val();
API
| Method | Description |
| -------------------- | ------------- |
| compose(a) | Creates a wrapper for a given object a
. |
| append(b) | Appends an object b
to the context a
. |
| if(condition, b) | Appends a given object b
to the context a if and only if the condition is satisfied. |
| elseif(condition, c) | Appends a given object
cto the context
aif and only if the condition is satisfied and all previous conditions were falsy. |
| else(d) | Appends a given object
dto the context
aif all previous conditions were falsy. |
| $(projection) | Creates a projection of a context object
aand returns only
truefields. |
| val() | Simply returns the context object
a`. |
export interface IComposer<A> {
append<B>(b: B): IComposer<A & B>;
if<B>(condition: boolean, b: B): IComposer<A | (A & B)>;
elseif<C>(condition: boolean, c: C): IComposer<A | (A & C)>
else<D>(d: D): IComposer<A | (A & D)>;
$(projection: {[K in keyof A]: Boolean}): IComposer<{[K in keyof A]: A[K] }>;
val(): A;
}
License
MIT