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

changed.js

v1.0.0

Published

Library for updating JavaScript objects and arrays (directly).

Downloads

5

Readme

changed

NPM version Build Status dependencies Status devDependencies Status Greenkeeper badge semantic-release

NPM Downloads

A tiny (~1.5kb minified+gzipped) and fast, library for updating JavaScript objects and arrays directly.

Supports nested key paths via path arrays or dot-bracket syntax, and all methods are curriable (with placeholder support) for composability. Can support typical changes of view-model attributes by methods has, get, set, remove, add and merge with a small footprint.

Table of contents

Motivation

Objects with nested properties and arrays are used to store application state. Libraries like Backbone provide functions for inspecting and manipulating the state as methods of specialized objects like Backbone.Model. This library provides only such methods without having to include the rest of the functionality of a bigger library. You can use other libraries to make your application complete; for example on-change for property change notifications.

This library has been inspired by unchanged, which has been used for the initial design and imnplementation. On the contrary to the immutable unchanged, this library supports mutable application states.

Installation

You will need node version >= 4 and npm to install and use this module:

npm install changed.js

Browser users will find non-minified and minified UMD-compliant scripts in the dist directory.

Usage

import {has, get, set, remove, add, merge} from 'changed';

const object = {
  foo: 'foo',
  bar: [
    {
      baz: 'quz'
    }
  ]
};

// handle standard properties
const foo = get('foo', object);

// or nested properties
const baz = set('bar[0].baz', 'not quz', object);

// all methods are curriable
const removeBaz = remove('bar[0].baz');
const sansBaz = removeBaz(object);

NOTE: There is no default export, so if you want to import all methods to a single namespace you should use the import * syntax:

import * as c from 'changed';

Methods

has

has(path: (Array<number|string>|number|string), object: (Array<any>|Object)): any

Checks if there is a property defined on the object passed and on the path specified.

const object = {
  foo: [
    {
      bar: 'baz'
    }
  ]
};

console.log(get('foo[0].bar', object)); // baz
console.log(get(['foo', 0, 'bar'], object)); // baz

get

get(path: (Array<number|string>|number|string), object: (Array<any>|Object)): any

Getter function for properties on the object passed and on the path specified.

const object = {
  foo: [
    {
      bar: 'baz'
    }
  ]
};

console.log(get('foo[0].bar', object)); // baz
console.log(get(['foo', 0, 'bar'], object)); // baz

set

set(path: (Array<number|string>|number|string), value: any, object: (Array<any>|object)): (Array<any>|Object)

Returns the object passed, with the value assigned to the final key on the path specified.

const object = {
  foo: [
    {
      bar: 'baz'
    }
  ]
};

console.log(set('foo[0].bar', 'quz', object)); // {foo: [{bar: 'quz'}]}
console.log(set(['foo', 0, 'bar'], 'quz', object)); // {foo: [{bar: 'quz'}]}

remove

remove(path: (Array<number|string>|number|string), object: (Array<any>|object)): (Array<any>|Object)

Returns a new clone of the object passed, with the final key on the path removed if it exists.

const object = {
  foo: [
    {
      bar: 'baz'
    }
  ]
};

console.log(remove('foo[0].bar', object)); // {foo: [{}]}
console.log(remove(['foo', 0, 'bar'], object)); // {foo: [{}]}

add

add(path: (Array<number|string>|number|string), value: any, object: (Array<any>|object)): (Array<any>|Object)

Returns the object passed, with the value added at the path specified. This can have different behavior depending on whether the item is an Object or an Array.

const object = {
  foo: [
    {
      bar: 'baz'
    }
  ]
};

// object
console.log(add('foo', 'added value' object)); // {foo: [{bar: 'baz'}, 'added value']}
console.log(add(['foo'], 'added value', object)); // {foo: [{bar: 'baz'}, 'added value']}

// array
console.log(add('foo[0].quz', 'added value' object)); // {foo: [{bar: 'baz', quz: 'added value'}]}
console.log(add(['foo', 0, 'quz'], 'added value', object)); // {foo: [{bar: 'baz', quz: 'added value'}]}

Notice that the Object usage is idential to the set method, where a key needs to be specified for assignment. In the case of an Array, however, the value is pushed to the array at that key.

NOTE: If you want to add an item to a top-level array, pass null as the key:

const object = ['foo'];

console.log(add(null, 'bar', object)); // ['foo', 'bar']

merge

merge(path: (Array<number|string>|number|string), value: any, object: (Array<any>|object)): (Array<any>|Object)

Returns the object passed, after performing a deep merge with the value (an object) at the path specified.

const object1 = {
  oneSpecific: 'value',
  object: {
    one: 'value1',
    two: 'value2'
  }
};
const object2 = {
  one: 'new value',
  three: 'value3'
};

console.log(merge('object', object2, object1)); // {oneSpecific: 'value', object: {one: 'new value', two: 'value1', three: 'value3'}}

NOTE: If you want to merge the entirety of both objects, pass null as the key:

const object1 = {
  oneSpecific: 'value',
  object: {
    one: 'value1',
    two: 'value2'
  }
};
const object2 = {
  one: 'new value',
  three: 'value3'
};

console.log(merge(null, object2, object1)); // {one: 'new value', oneSpecific: 'value', object: {one: 'value1', two: 'value1'}, three: 'value3'}

Development

Standard stuff, clone the repo and npm install dependencies. The npm scripts available:

  • build => run webpack to build development dist file with NODE_ENV=development
  • build:minified => run webpack to build production dist file with NODE_ENV=production
  • dev => run webpack dev server to run example app / playground
  • dist => runs build and build-minified
  • lint => run ESLint against all files in the src folder
  • prepublish => runs compile-for-publish
  • prepublish:compile => run lint, test:coverage, transpile:es, transpile:lib, dist
  • test => run AVA test functions with NODE_ENV=test
  • test:coverage => run test but with nyc for coverage checker
  • test:watch => run test, but with persistent watcher
  • transpile:lib => run babel against all files in src to create files in lib
  • transpile:es => run babel against all files in src to create files in es, preserving ES2015 modules (for pkg.module)

Contributing

In lieu of a formal style guide, take care to maintain the existing coding style.

License

Copyright (c) 2017 Ferdinand Prantl