npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

safety-lens

v1.5.0

Published

Type-safe, functional lens library supporting Immutable.js

Downloads

39

Readme

safety-lens

Join the chat at https://gitter.im/hallettj/safety-lens

Type-safe, functional lens library in JavaScript. This is basically a port of some of the concepts from the Haskell lens library. Safety-lens goes best with Flow, and pairs well with Immutable.

A lens is used to focus in on a specific piece of a data structure. Using a lens, that piece can be read or updated. For example:

import { get, set } from 'safety-lens'
import { prop } from 'safety-lens/es2015'

let obj = { foo: 1, bar: 2 }

// Get a value
assert( get(prop('bar'), obj) === 2 )

obj = set(prop('bar'), 3, obj)

// Set a value
assert( get(prop('bar'), obj) === 3 )

The function call prop('bar') creates a lens that focuses on the bar property of any object.

get takes a lens and an object, and returns a reference to the focused piece of the object. So get(prop('bar'), obj) returns 2.

set takes a lens, a new value, and an object, and replaces the focused piece of the object with the new value. Or to be more precise, set creates a copy of the object in which the focused piece has been replaced with the new value. In the example above, set(prop('bar'), 3, obj) creates a new object that sets the bar property to 3, and keeps the foo property set to 1.

This is obviously more complicated than writing the equivalent expressions obj.bar or obj.bar = 3. But lenses do come with several advantages:

  • Lenses perform immutable updates: you get an updated copy of a data structure, while the original is untouched. This means that lenses pair nicely with immutable data libraries like Immutable or Mori.

  • Lenses can be composed to focus on deeply nested pieces of a data structure. Updating a deeply-nested, immutable data structure by hand is painful - but lenses make it easy.

  • Lenses provide type safety. Immutable has methods getIn, setIn; and Mori has equivalent functions. These are invaluable for working with deeply nested data structures. But there is no type checker available today that can check the type of a value returned from one of these functions, or that can check that appropriate types are used in updates. Lenses do the same job, but with dependable type-checking using Flow.

  • Lenses provide encapsulation. When writing a library or module, you can export lenses, but keep the details of your data structures hidden.

Documentation

Please refer to these topics for more information:

Install

npm install --save safety-lens

Building from source

Run:

$ npm install

That invokes the prepublish npm script, which runs the type checker, transpiles code, and runs tests. Requires GNU Make.

Examples of usage

Getting and setting nested values

import { get, set } from 'safety-lens'
import { prop } from 'safety-lens/es2015'

let obj = { foo: 1, bar: 2 }

// Get a value
assert( get(prop('bar'), obj) === 2 )

obj = set(prop('bar'), 3, obj)

// Set a value
assert( get(prop('bar'), obj) === 3 )

Transforming nested values with a function

import { over } from 'safety-lens'
import { prop } from 'safety-lens/es2015'

let obj = { foo: 1, bar: 2 }

obj = over(prop('bar'), x => x * 2, obj)

assert( obj.bar === 4 )

Composing lenses

Imagine a program with values of this type:

import { List } from 'immutable'

type Calendar = List<{ date: Date, title: string }>

const events = List.of(
  { date: new Date(), title: 'get coffee' },
  { date: new Date(), title: 'plan day' }
)

To construct a lens that can focus on the title of the first event in a calendar list:

import { compose, lookup } from 'safety-lens'
import { index } from 'safety-lens/immutable'
import { prop } from 'safety-lens/es2015'

const firstEventLens = index(0)
const titleLens = prop('title')

const firstEventTitleLens = compose(firstEventLens, titleLens)

assert( lookup(firstEventTitleLens, events) === 'get coffee' )

A lens might focus on multiple pieces within a data structure simultaneously. To operate on all events in a calendar:

import { over } from 'safety-lens'
import { traverse } from 'safety-lens/immutable'

const dateLens = prop('date')

const allDatesLens = compose(traverse, dateLens)

// Moves all events forward by one day.
const rescheduled = over(
  allDatesLens,
  date => new Date(Number(date) + 24 * 60 * 60 * 1000),
  events
)