All Projects β†’ tomasdeml β†’ lenticular.ts

tomasdeml / lenticular.ts

Licence: MIT license
(Yet another) implementation of functional lenses in JavaScript/TypeScript.

Programming Languages

typescript
32286 projects
javascript
184084 projects - #8 most used programming language

Projects that are alternatives of or similar to lenticular.ts

Prolens
πŸ‘“ Profunctor based lightweight implementation of Lenses
Stars: ✭ 63 (+117.24%)
Mutual labels:  lenses, lens
Elm Monocle
Functional abstractions to manipulate complex records in Elm - Iso, Prism, Lens, Optional, Traversal.
Stars: ✭ 137 (+372.41%)
Mutual labels:  lenses, lens
Python Lenses
A python lens library for manipulating deeply nested immutable structures
Stars: ✭ 179 (+517.24%)
Mutual labels:  lenses, lens
putting-lenses-to-work
A presentation for BayHac 2017 on how I uses lenses at work
Stars: ✭ 73 (+151.72%)
Mutual labels:  lenses, lens
Frunk
Funktional generic type-level programming in Rust: HList, Coproduct, Generic, LabelledGeneric, Validated, Monoid and friends.
Stars: ✭ 725 (+2400%)
Mutual labels:  lenses
Lambda
Functional patterns for Java
Stars: ✭ 737 (+2441.38%)
Mutual labels:  lenses
Monocle Ts
Functional optics: a (partial) porting of Scala monocle
Stars: ✭ 657 (+2165.52%)
Mutual labels:  lenses
Focal
Program user interfaces the FRP way.
Stars: ✭ 613 (+2013.79%)
Mutual labels:  lenses
xml-lens
XML Optics library for Scala
Stars: ✭ 32 (+10.34%)
Mutual labels:  lenses
Focus
Lightweight Elixir lenses
Stars: ✭ 224 (+672.41%)
Mutual labels:  lenses
Lens Regex Pcre
Text lenses using PCRE regexes
Stars: ✭ 116 (+300%)
Mutual labels:  lenses
Dart functional data
Simple and non-intrusive code generator for lenses and boilerplate of data types
Stars: ✭ 39 (+34.48%)
Mutual labels:  lenses
Sauron
Yet another Scala lens macro
Stars: ✭ 166 (+472.41%)
Mutual labels:  lenses
Microlens
A lightweight (but compatible with β€˜lens’) lenses library
Stars: ✭ 254 (+775.86%)
Mutual labels:  lenses
Datum
pure functional and generic programming for Erlang
Stars: ✭ 111 (+282.76%)
Mutual labels:  lenses
To.ml
OCaml library for TOML
Stars: ✭ 68 (+134.48%)
Mutual labels:  lenses
Quicklens
Modify deeply nested case class fields
Stars: ✭ 641 (+2110.34%)
Mutual labels:  lenses
Typed
The TypeScript Standard Library
Stars: ✭ 124 (+327.59%)
Mutual labels:  lenses
lentes
Functional references for Clojure and ClojureScript
Stars: ✭ 80 (+175.86%)
Mutual labels:  lenses
AssetLens
Asset Lens : Unity asset reference management utility working in background. 에디터 λ°±κ·ΈλΌμš΄λ“œμ—μ„œ κ΄€λ¦¬λ˜λŠ” μœ λ‹ˆν‹° 에셋 파일 레퍼런슀 데이터 도ꡬ.
Stars: ✭ 47 (+62.07%)
Mutual labels:  lens

lenticular.ts

Lenses are functions that provide reusable views into deep data structures. Lenses can be composed to get or set arbitrary data within a deeply-nested, immutable data structure.

The novelty of lenticular.ts lies in strongly-typed composition of lenses for deeply-nested views. Instead of hard-coding names of object properties, lenticular.ts allows you to define the view path using a function expression. Because the expression can be checked by the TypeScript compiler, whole class of runtime errors is mitigated beforehand.

Lenticular.ts supports both object and array-typed properties with fallback in case of a null/undefined values in the path.

Example Usage

import { pathFromExpression, lensFromPath } from 'lenticular-ts';

interface IState {
    list: IListState;
}

interface IListState {
    items: IItem[];
}

interface IItem {
    name: string;
    attributes?: string[];
}

const state: IState = {
    list: {
        items: [
            { name: 'First Item Name' },
            { name: 'Second Item Name', attributes: ['Attribute 1', 'Attribute 2'] }
        ]
    }
};

// Create a path for lens from passed expression
const nameOfItemAtIndex = pathFromExpression((s: IState, i) => s.list.items[i].name); 
// Create a lens from the path with variable array indexes being replaced with values from the passed array
const nameOfSecondItem = lensFromPath(nameOfItemAtIndex, [1]); 
// Return 'Second Item Name'
const name = nameOfSecondItem.get(state);
// Return a shallow copy of state with second item having updated name
const newState = nameOfSecondItem.set(state, 'Updated Item Name'); 
// Invoke a callback by passing it ***the current value*** of the expression and using its return value for a set() call
const newState2 = nameOfSecondItem.modify(state, name => name + ' modified'); 

See page.ts in sample application for a complete example.

Expression Format

The path expression should be defined with an function containing a single return expression (currently the expression must be contained in a function with a return keyword). The expression must start with a reference to the root object and must end with a reference to the property to get/set/modify. The expression can contain variable array indexes (e.g. [i], [j] etc.), static indexes (e.g. 1,3 etc.). If the expression contains variable array indexes, all their values must be provided when creating a lens from the path in the order that matches declaration of the indexes in function arguments.

Examples of Supported Expression Formats

// Path defined with an arrow function (that must be currently transpiled by TSC to an ordinary function)
const expression1 = (s: IState) => s.list; 
// Path defined with an ordinary function
const expression2 = function(s: IState) { return s.list; }; 
// Will not be checked by TypeScript compiler as there are no type information available
const expression3 = s => s.list; 
// Contains static array index pointing to the first item
const expression4 = (s: IState) => s.list.items[0].name; 
// Contains static array index pointing to a non-existent item in the array - the item will be created during lens.set() invocation
const expression5 = (s: IState) => s.list.items[10].name; 
// Contains two variable array indexes
const expression6 = (s: IState, i, j) => s.list.items[i].attributes[j]; 
// Defines path to non-existent properties that will be initialized during lens.set() invocation
const expression7 = s => s.missingProperty.anotherMissingProperty; 

How To Build

  1. Install gulp globally:
npm i gulp -g
  1. Restore npm packages in lenticular.ts:
npm i
  1. Build lenticular.ts with gulp:
gulp
  1. Navigate to ._package for build output
Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].