• Stars
    star
    140
  • Rank 261,473 (Top 6 %)
  • Language
    JavaScript
  • License
    MIT License
  • Created over 7 years ago
  • Updated about 2 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Optics library for JavaScript

Optika

Optics: modular data access

Build Status NPM version Dependency Status devDependency Status

Getting Started

Install the module with: npm install optika

Synopsis

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;
});

Motivation

Immutable.js is great! But working with immutable containers & nested records is un-easy:

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:

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:

o.imkey("months").traversed().imkey("days").traversed().over(data, day =>
  injectAuxData(day, auxData)
);

Documentation

There is small amount of run-time validation. For example, if you try to set over Getter, the exception will be thrown:

o.key("foo").to(function (x) { return x[0]; }).set(value, 42);
// throws: Trying to run Traversal operation via Getter

Operations

  • get(this: Getter<S,A>, value: S): A

  • set(this: Traversal<S,T,A,B>, value: S, b: B): T

  • over(this: Traversal<S,T,A,B>, value: S, f: A => B): T

  • review(this: Prism<S,T,A,B>, value: B): T

  • review(this: Iso<S,T,A,B>, value: B): T

    Construct value thru Prism or Iso.

  • `affineView(this: Affine<S,T,A,B>, def: A): A

    For operation working with Fold, see firstOf.

  • reduceOf(this: Fold<S,T,A,B>, 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<S,T,A,B>, value: S): Array<A>

  • sumOf(this: Fold<S,T,number,B>, value: S): number

Constructors

  • lens(getter: S => A, setter: (S, B) => T): Lens<S,T,A,B>

  • traversed(): Traversal<F<A>,F<B>,A,B>

    Creates traversal for everything with .map and .forEach.

  • to(f: S => A): Getter<S,A>

Convenient optics

  • key(K: keyof (S & T)): Lens<S,T,S[K],T[K]>

    Works for plain-old-javascriot-objects, i.e. POJOs :)

  • idx(i: number)): Lens<Array<A>,Array<A>,A,A>

  • imkey(K: keyof (S & T)): Lens<Record<S>,Record<T>,S[K],T[K]>

    Works with everyting supporting .get and .set, e.g. Immutable.

  • imidx(i: number)): Lens<List<A>,List<A>,A,A>

    Works with everyting supporting .get and .set, e.g. Immutable.

    Note: doesn't perform bounds check.

  • filtered(pred: A => boolean): Prism<A,A,A',A'>

Note: The predicate is checked when the value is injected (via Traversal) or constructed via Prism.

  • safeFiltered(pred: A => boolean): Prism<A,A,A',A'>

Like filtered but predicate is checked on construction.

Internals

Functions which you probably never need to use directly.

.o(this: Optic<S,T,A,B>, other: Optic<A,B,U,V>): Optic<S,T,U,V>

Compose two optics.

.run(this: Optic<S,T,A,B>, p: Profunctor<A,B>): Profunctor<S,T>

Contributing

  • 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.

Release History

  • 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

Implementation details

  • pair is represented as two-element array: Pair<A,B> = [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.

Related work

JavaScript

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.

More Repositories

1

igbinary

Igbinary is a drop in replacement for the standard php serializer. Check https://github.com/igbinary/igbinary for the freshest version
C
258
star
2

cabal-fmt

An experiment of formatting .cabal files
Haskell
95
star
3

typify

Runtime type checking for JavaScript
JavaScript
77
star
4

relaxed-json

Relaxed JSON is strict superset JSON, relaxing strictness of vanilla JSON
JavaScript
73
star
5

cabal-extras

A tool suite to aid Haskell development using `cabal-install`
Haskell
68
star
6

write-yourself-a-typed-functional-language

Write yourself a typed functional language
Haskell
65
star
7

menrva

Ambitious data-flow library
JavaScript
36
star
8

kleene

Kleene algebra, regular expressions
Haskell
31
star
9

docker-haskell-example

How to build Docker image for Haskell web app?
Dockerfile
29
star
10

tdigest

On-line accumulation of rank-based statistics such as quantiles and trimmed means
Haskell
29
star
11

overloaded

Overloaded plugin
Haskell
28
star
12

idioms-plugins

Hack idiom-brackets using GHC Source Plugin (8.6+)
Haskell
24
star
13

vec

Nat, Fin, Vec
Haskell
23
star
14

git-badc0de

Make git commits with pretty hashes
C
22
star
15

topograph

Directed Acyclic Graphs
Haskell
20
star
16

graafi

cycle.js expirement
JavaScript
20
star
17

latex-svg

Render LaTeX math to SVG mages
Haskell
16
star
18

acme-kmett

A collection of Edward Kmett's packages in a single repository
Makefile
15
star
19

staged

Staged Streams and other stuff
Haskell
14
star
20

boring

Boring and Absurd types
Haskell
14
star
21

trampa

Trampolines, to emulate tail-recursion.
JavaScript
13
star
22

bound-extras

ScopeT and ScopeH
Haskell
13
star
23

kleene-type

Regular expressions of types
Haskell
13
star
24

trustee

Hackage Trustee helper tool
Haskell
13
star
25

heroku-docker-haskell-test

Heroku + docker + haskell = ?
Shell
13
star
26

preload-trick

"Preload" Haskell packages to override them
Haskell
12
star
27

language-pts

Pure Type Systems
Haskell
12
star
28

docker-ghc

GHC + Cabal docker image
Dockerfile
12
star
29

aws-lambda-haskell-runtime

Build AWS Lambda's with Haskell
Haskell
11
star
30

hooglite

Alternative and lite implementation of Hoogle
Haskell
11
star
31

insert-ordered-containers

Associative containers retating insertion order for traversals
Haskell
11
star
32

saison

Stream Aeson, fruity, spicy, well carbonated.
Haskell
10
star
33

typify-parser

Type signature parser for typify
JavaScript
9
star
34

gists

Oleg's gists
JetBrains MPS
9
star
35

ljs

Generate docs from your source
JavaScript
9
star
36

lens-laws

Existential Optics: discovering correct lens laws
Coq
9
star
37

zinza

Typed templates with jinja like syntax. Docs on Hackage.
Haskell
9
star
38

cabal-refact

Refactoring tool for .cabal files
Haskell
9
star
39

jsstana

s-expression match patterns for Mozilla Parser AST
JavaScript
8
star
40

npm-freeze

Freeze the node dependencies
JavaScript
8
star
41

generic-lens-lite

Lite version of generic-lens
Haskell
7
star
42

aeson-optics

Law-abiding optics for aeson
Haskell
7
star
43

file-embed-lzma

Use Template Haskell to embed (LZMA compressed) data.
Haskell
7
star
44

base64-bytestring-type

A newtype around ByteString, for base64 encoding.
Haskell
6
star
45

singleton-bool

Type level booleans
Haskell
6
star
46

vec-backpack

Haskell
6
star
47

travis-meta-yaml

.travis.yml preprocessor
Haskell
6
star
48

minicsv

Very minimal csv library
Haskell
6
star
49

sasha

A staged lexer generator
Haskell
6
star
50

docker-stackage

Docker image with stackage config
Haskell
5
star
51

lazy-seq

Lazy sequence for JavaScript
JavaScript
5
star
52

regression-simple

Simple linear and quadratic regression
Haskell
5
star
53

JuicyPixels-scale-dct

Scale JuicyPixels images with DCT
Haskell
5
star
54

rc4

RC4 random number generator
JavaScript
5
star
55

binary-tagged

Tagged binary serialisation
Haskell
5
star
56

ncill

Agda mechanization of cut elimination in Non-Commutative Intuitionistic Linear Logic
Agda
5
star
57

dlist-nonempty

Non-empty difference lists
Haskell
5
star
58

spdx

SPDX license expression language - Haskell implementation
Haskell
5
star
59

range-set-list

Memory efficient sets with continuous ranges of elements. List based implementation.
Haskell
5
star
60

minicurl

Minimal bindings to libcurl
Haskell
4
star
61

servant-tiny

A tiny servant version, to learn and experiment
Haskell
4
star
62

haskell-monad-http

A MonadHTTP type class
Haskell
4
star
63

libperf

Bindings to Linux perf_event_open functionality
Haskell
4
star
64

time-parsers

Date & time parsers
Haskell
4
star
65

sa

Simulated annealing
Haskell
4
star
66

aeson-compat

Compatibility package for aeson
Haskell
4
star
67

aeson-extra

Extra goodies for aeson
Haskell
4
star
68

hkd

"higher-kinded data"
Haskell
4
star
69

regex-applicative-text

regex-applicative on text
Haskell
4
star
70

generics-sop-lens

Lenses for types in generics-sop
Haskell
4
star
71

cabal-env

What cabal-install install --lib could be DEVELOPMENT MOVE TO https://github.com/phadej/cabal-extras
Haskell
4
star
72

mixfix

Mixfix espression parser
JavaScript
4
star
73

dec

Decidable propositions
Haskell
4
star
74

staged-gg

Staged GHC.Generics
Haskell
4
star
75

changelog-d

Changelog from the directory of entries
Haskell
3
star
76

servant-universe

Megarepository for most servant packages
Makefile
3
star
77

representable-fd

Representable functors with FunctionalDependencies
Haskell
3
star
78

end

Evolving non-determinism
Haskell
3
star
79

unsatisfiable

Unsatisfiable type-class
Haskell
3
star
80

ansi-pretty

AnsiPretty type-class for ansi-wl-pprint
Haskell
3
star
81

nucpp

NuCPP is non-standard not-C preprocessor
Haskell
3
star
82

ghcjs-ubuntu

Packaging GHCJS for Ubuntu
Haskell
3
star
83

th-letrec

Implicit (recursive) let insertion
Haskell
3
star
84

crypt-sha512

Pure Haskell implelementation for GNU SHA512 crypt algorithm
C
3
star
85

gentle-introduction

This is not a prelude, this is gentle introduction
Haskell
3
star
86

step-function

Step functions, staircase functions or piecewise constant functions.
Haskell
2
star
87

servant-blaze

http://hackage.haskell.org/package/servant-blaze
Haskell
2
star
88

helhug-types

Presentation hold at Helsinki Haskell User Group, 2015-03-04
HTML
2
star
89

symbolic

Symbolic Floating
Haskell
2
star
90

agda-np

More programming suited version of All and Any, and other tools I keep reimplementing.
Agda
2
star
91

postgresql-simple-url

Heroku helpers for pulmurice server
Haskell
2
star
92

servant-record

Servant API from a record
Haskell
2
star
93

transformers-quantified

How much stuff breaks?
Haskell
2
star
94

boolean-normal-forms

Boolean normal forms: NNF, DNF & CNF
Haskell
2
star
95

servant-cassava

Servant CSV content-type for cassava
Haskell
2
star
96

stackage-extras

Currently: packdeps for everything on Stackage
Haskell
2
star
97

acme-operators

Operators of Haskell, all in one place!
Haskell
2
star
98

metametapost

A Haskell EDSL to write MetaPost programs
Haskell
2
star
99

github-issues

A barebones issues description context dumper, so you can grep them offline
Haskell
2
star
100

servant-lucid

Servant support for lucid
Haskell
2
star