Optics: modular data access for JavaScript
npm install optika
> Optics: modular data access




Install the module with: npm install optika
``javascript
var o = require("optika");
var value = {
foo: [
{ bar: 2, baz: 3 },
{ bar: 4, baz: 5 },
]
};
// [2, 4]
o.key("foo").traversed().key("bar").arrayOf(value);
// { foo: [ { bar: 9, baz: 3 }, { bar: 11, baz: 5 } ] }
o.key("foo").traversed().key("bar").over(value, function (x) {
return x + 7;
});
`
Immutable.js is great!
But working with immutable containers & nested records is un-easy:
`javascript`
return data.update("months", months =>
months.map(month =>
month.update("days", days =>
days.map(day => injectAuxData(day, auxiliaryData))
)
)
);
The updateIn isn't powerful enough to make the drilling less boilerplaty
(and less error-prone).
If you are a Haskell programmer, you might know that lenses are a solution
to this problem:
`haskell
data_ & months . traversed . days . traversed %~ \day ->
injectAuxData day auxData
-- or without operators:
over
(months . traversed . days . traversed)
(\day -> injectAuxData day auxData)
data_
`
And with this library you can write similar code in JavaScript:
`javascript`
o.imkey("months").traversed().imkey("days").traversed().over(data, day =>
injectAuxData(day, auxData)
);
There is small amount of run-time validation.
For example, if you try to set over Getter, the exception will be thrown:`javascript`
o.key("foo").to(function (x) { return x[0]; }).set(value, 42);
// throws: Trying to run Traversal operation via Getter
- get(this: Getter, value: S): A
- set(this: Traversal, value: S, b: B): T
- over(this: Traversal, value: S, f: A => B): T
- review(this: Prism, value: B): Treview(this: Iso
- , value: B): T
Construct value thru Prism or Iso.
- affineView(this: Affine, def: A): A
For operation working with Fold, see firstOf.
- reduceOf(this: Fold, value: S, init: I, combine: (I, A) => I): I
Fold starting with initial value init, and combining results with combine,
in the this Fold's order.
- arrayOf(this: Fold, value: S): Array
- sumOf(this: Fold, value: S): number
- lens(getter: S => A, setter: (S, B) => T): Lens
- traversed(): Traversal
Creates traversal for everything with .map and .forEach.
- to(f: S => A): Getter
- key(K: keyof (S & T)): Lens
Works for plain-old-javascriot-objects, i.e. POJOs :)
- idx(i: number)): Lens
- imkey(K: keyof (S & T)): Lens
Works with everyting supporting .get and .set, e.g.
Immutable.
- imidx(i: number)): Lens,List,A,A>
Works with everyting supporting .get and .set, e.g.
Immutable.
Note: doesn't perform bounds check.
- filtered(pred: A => boolean): Prism
Note: The predicate is checked when the value is injected (via Traversal)
or constructed via Prism.
- safeFiltered(pred: A => boolean): Prism
Like filtered but predicate is checked on construction.
Functions which you probably never need to use directly.
.o(this: Optic, other: Optic): Optic
Compose two optics.
.run(this: Optic, p: Profunctor): Profunctor
- README.md is generated from the source with ljs, say make literate.
- optika.standalone.js is also generated by the build process
- Before creating a pull request run make test, yet travis will do it for you.
- 0.0.2 — 2017-04-01 — Neglect for speedups
- 0.0.1 — 2017-03-24 — More features
- 0.0.0 — 2017-03-22 — Initial preview
- pair is represented as two-element array: Pair = [A,B].
- Either is represtented by [boolean, A | B], where
false and true reprsent whether the value is Left or Right respectively.
- Maybe is encoded as the value + some unique value nothing can equal to (think: Symbol).
- See Compiling lenses
for ideas behind Neglect.
- partial.lenses
- ramda-lens
- flunc-optics
The MIT License (MIT)
Copyright (c) 2017 Oleg Grenrus
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.