Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

fastener

Package Overview
Dependencies
Maintainers
1
Versions
11
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

fastener

Zipper for manipulating JSON

  • 0.2.1
  • Source
  • npm
  • Socket score

Version published
Weekly downloads
8
decreased by-27.27%
Maintainers
1
Weekly downloads
 
Created
Source

[ Tutorial | Reference | Related Work ]

Zippers are a powerful abstraction for implementing arbitrary queries and transforms on immutable data structures and for step-by-step navigation and modification of data structures. This library implements a simple zipper designed for manipulating JSON data.

npm version Build Status

Tutorial

Reference

The zipper combinators are available as named imports. Typically one just imports the library as:

import * as F from "fastener"

In the following examples we will make use of the function

const seq = (x, ...fs) => R.reduce((x, f) => f(x), x, fs)

written using reduce that allows one to express a sequence of operations to perform starting from a given value.

Introduction and Elimination

F.toZipper(json)

F.toZipper(json) creates a new zipper that is focused on the root of the given JSON object.

For example:

seq(F.toZipper([1,2,3]),
    F.downHead,
    F.modify(x => x + 1),
    F.fromZipper)
// [ 2, 2, 3 ]
F.fromZipper(zipper)

F.fromZipper(zipper) extracts the modified JSON object from the given zipper.

For example:

seq(F.toZipper([1,2,3]),
    F.downHead,
    F.modify(x => x + 1),
    F.fromZipper)
// [ 2, 2, 3 ]

Focus

Focus combinators allow one to inspect and modify the element that a zipper is focused on.

F.get(zipper)

F.get(zipper) returns the element that the zipper is focused on.

For example:

seq(F.toZipper(1), F.get)
// 1
seq(F.toZipper(["a","b","c"]),
    F.downTo(2),
    F.get)
// 'c'
F.modify(fn, zipper)

F.modify(fn, zipper) is equivalent to F.set(fn(F.get(zipper)), zipper) and replaces the element that the zipper is focused on with the value returned by the given function for the element.

For example:

seq(F.toZipper(["a","b","c"]),
    F.downTo(2),
    F.modify(x => x + x),
    F.fromZipper)
// [ 'a', 'b', 'cc' ]
F.set(json, zipper)

F.set(json, zipper) replaces the element that the zipper is focused on with the given value.

For example:

seq(F.toZipper(["a","b","c"]),
    F.downTo(1),
    F.set('lol'),
    F.fromZipper)
// [ 'a', 'lol', 'c' ]

Movement

Movement combinators can be applied to any zipper, but they return undefined in case of illegal moves.

Parent-Child movement

Parent-Child movement is moving the focus between that parent object or array and a child element of said parent.

F.downHead(zipper)

F.downHead(zipper) moves the focus to the leftmost element of the object or array that the zipper is focused on.

F.downLast(zipper)

F.downLast(zipper) moves the focus to the rightmost element of the object or array that the zipper is focused on.

F.downTo(key, zipper)

F.downTo(key, zipper) moves the focus to the specified object property or array index of the object or array that the zipper is focused on.

F.keyOf(zipper)

F.keyOf(zipper) returns the object property name or the array index that the zipper is currently focused on.

F.up(zipper)

F.up(zipper) moves the focus from an array element or object property to the containing array or object.

Sibling movement

Sibling movement is moving the focus between the elements of an array or an object.

F.head(zipper)

F.head(zipper) moves the focus to the leftmost sibling of the current focus.

F.last(zipper)

F.last(zipper) moves the focus to the rightmost sibling of the current focus.

F.left(zipper)

F.left(zipper) moves the focus to the element on the left of the current focus.

F.right(zipper)

F.right(zipper) moves the focus to the element on the right of the current focus.

Queries

F.queryMove(move, default, fn, zipper)

F.queryMove(move, default, fn, zipper) applies the given function fn to the zipper focused on after the given movement and returns the result unless the move was illegal in which case the given default value is returned instead.

For example:

seq(F.toZipper({x: 1}),
    F.queryMove(F.downTo('y'), false, () => true))
// false
seq(F.toZipper({y: 1}),
    F.queryMove(F.downTo('y'), false, () => true))
// true

Transforms

F.transformMove(move, fn, zipper)

F.transformMove(move, fn, zipper) applies the given function to the zipper focused on after the given movement. The function must the return a zipper focused on the same element that it was given. Then the focus is moved back to the element that the zipper was originall focused on. Nothing is done in case of an illegal move.

For example:

seq(F.toZipper({y: 1}),
    F.transformMove(F.downTo('y'), F.modify(x => x + 1)),
    F.fromZipper)
// { y: 2 }
seq(F.toZipper({x: 1}),
    F.transformMove(F.downTo('y'), F.modify(x => x + 1)),
    F.fromZipper)
// { x: 1 }
F.everywhere(fn, zipper)

F.everywhere(fn, zipper) performs a transform of the focused element by modifying each possible focus of the element with a bottom-up traversal.

For example:

seq(F.toZipper({foo: 1,
                bar: [{lol: "bal", example: 2}]}),
    F.everywhere(x => typeof x === "number" ? x + 1 : x),
    F.fromZipper)
// { foo: 2, bar: [ { lol: 'bal', example: 3 } ] }

While the implementation is very different, the choice of combinators is based on Michael D. Adams' paper Scrap Your Zippers.

Keywords

FAQs

Package last updated on 25 Apr 2016

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc