Giter Club home page Giter Club logo

uber-lens's Introduction

UBER LENS


Immutable data made easy


Have you ever wanted to see the whole picture of your data?

Have you ever wanted to use only immutable data?

Have you ever wanted to do it in a way that is easy to understand?

Have you ever wanted to do it in a way that is easy to use?

Look no further, UBER LENS is here to help you.

Table of Contents

Installation

npm i uber-lens

What is UBER LENS?

It's a library that allows you to create declarative and strongly typed lenses for your data.

Motivations

I love functional programming, and I love declarative programming, and I really likes the shades package.

There is only one problem with then, it's type declarations are a little verbose, to say the least, and with some missing cases.

Uber-lens allows you to create declarative, lodash like and strongly typed lenses for your data with less than 200 lines of library code with all the benefits of powerful type declarations.

The old way

This is a very basic nested data structure

const store = {
    user: 'John',
    posts: [
        {
            title: 'Hello World',
            comments: [
                {
                    user: 'Jane',
                    text: 'Hello John',
                    likes: 10
                },
                {
                    user: 'Über',
                    text: 'Guttentag John',
                    likes: 200
                }
            ]
        }
    ]
}

We want to update Über's comment to be all uppercase in the old way.

// Capitalize Über's comment
const newStore = {
    ...store,
    posts: store.posts.map(post => ({
        ...post,
        comments: post.comments.map(comment => comment.user === 'Über'
            ? { ...comment, text: comment.text.toUpperCase() }
            : comment)
    }))
}

I'm not even sure if this works, and I'm too scared to try it :D

The new way

Let's try it with UBER LENS!

import * as UL from 'uber-lens'

type Store = typeof store

const uberLens = UL.uber<Store>()('posts', 0, 'comments', UL.indexOne({ user: 'Über' }), 'text');

// Now we just have to update the store
const newStore = uberLens.mod(t => t.toUpperCase())(store)

See? It's that easy!


// But we can also just get the value
const uberComment = uberLens.get(store)

// But we can also just set the value
const newStore3 = uberLens.set(store, 'Über is the best')

I'll let you guess if this works as expected, but the tests and the EXTREMELY STRONG TYPE system are here to make sure you don't mess up.


But wait! There is more!

Not only UBER LENS can make your life easier when making simple updates, it can also make your life easier when making complex updates.


Do you want to set/update/get all Über comments to be all uppercase? You can do that with UBER LENS!

import * as UL from 'uber-lens'
const uberCommentsLens = UL.uber<Store>()(
    'posts',
    UL.indexAll,
    'comments',
    UL.indexMany({ user: 'Über' }),
    'text'
);

Do you want to set/update/get only the comments that have more than 10 likes? Done!

import * as UL from 'uber-lens'

const mostLikedCommentsLens = UL.uber<Store>()(
    'posts',
    UL.indexAll,
    'comments',
    UL.indexMany({ likes: (l: number) => l > 10 }),
    'text'
);

Do you want the text of the post with the most comments? Done!

import * as UL from 'uber-lens'

const mostCommentsLens = UL.uber<Store>()(
    'posts',
    UL.maxBy((c: {comments: any[]}) => c.comments.length),
);

Typing

This is the sweetest part, everything is typed! And I mean everything is strongly typed.

If you mess up, and you use the wrong type, you'll get a compile-time error.

The wrong path? Compile time error.

The wrong value? Compile error.

The wrong update function? Compile error.

For instance:

import * as UL from 'uber-lens'

// if you try to update a string with a number, you'll get a compile error.
const titleUpdate = UL.uber<Store>()('posts', 0, 'title').mod(t => t - 1); // Error!

// If you use the wrong path, you'll get a compile error.
const uberLens2 = UL.uber<Store>()('posts', 0, 'titles'); // Error!

Api

uber

// Not the real prototype, but it's the same
export function uber<Obj extends object>(): <P extends Indexer<Obj>[]>(...indexers: P) => {
    get: (obj: Obj) => Get<P, Obj>;
    set: (obj: Obj, value: Get<P, Obj>) => Obj;
    mod: (obj: Obj) => (update: (t: Get<P, Obj>) => Get<P, Obj>) => Obj;
}

indexOne, indexMany, indexAll

export function indexOne: <T>(match: Comparer<T>) => { single: <S extends T>(obj: S) => boolean };
export function indexMany: <T>(match: Comparer<T>) => { multi: <S extends T>(obj: S) => boolean };
export function indexAll: () => { multi: <T>(_: T) => boolean };

maxBy, minBy, maxByProp, minByProp

export function maxBy: <T>(extract: (el: T) => number) => { fold: Index<T[]> };
export function minBy: <T>(extract: (el: T) => number) => { fold: Index<T[]> };

export function maxByProp: <K extends string, T extends Record<K, number>>(prop: K) => { fold: Index<T[]> };
export function minByProp: <K extends string, T extends Record<K, number>>(prop: K) => { fold: Index<T[]> };

uber-lens's People

Contributors

drttnk avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.