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

will-mutate

v1.3.0

Published

Runtime test to that detects mutations to objects

Downloads

9

Readme

Will Mutate

Runtime test to that detects mutations to objects

npm version check status license: MIT

Description

Detect when and where mutations occur in your code. It may seem cool, but it's not a replacement for strict typings or tests. It is currently a proof-of-concept and a debugging tool.

Why did this property change?! I didn't do that!!!

Features

  • Detect any proxy-compatible mutation as it happens
  • Throws a stack trace of the code that caused the mutation
  • Includes a property path to the mutation in the object

Usage as a Utility Function

Installation

npm install will-mutate

Code

const proxify = require("will-mutate/proxify");

function foo () {
    // Setup
    const target = {
        array: [],
    };
    const targetProxy = proxify(target, {deep: true});
    // Mutation
    targetProxy.array.push("Test");
}
// Run
foo();

Run this example on RunKit

Errors

The below error is taken from running the above code snippet. You can see that the array property was pushed to.

The native code for .push() assigns "Test" to the first index, so we see an error from the set (assignment operator) trap inside the foo function in the foo.js module.

Error: Mutation assertion failed. `set` trap triggered on `target.array[0]`.
    at Object.handler.<computed> [as set] (proxify.js:152:10)
    at Proxy.push (<anonymous>)
    at Object.handler.<computed> [as apply] (proxify.js:175:24)
    at foo (foo.js:10:20)
    at Object.<anonymous> (foo.js:13:1)

API

proxyify(target, [options])

Create a Will Mutate mutation proxy for a target object.

Returns: Proxy - The function or object passed as target but as an ES6 Proxy

| Parameter | Type | Description | | --------- | --------------------------------- | ----------------------------------------------------------- | | target | Function | Object | Array | Function, array, or other object to watch mutations on | | [options] | Object | Options that controls how the proxy acts and when it errors |

options

| Option | Type | Default | Description | | --------- | --------- | ------- | ----------------------------------------------------------- | | deep | boolean | false | If the proxy should recursively wrap the entire object | | prototype | boolean | false | If the proxy should recursively wrap the object's prototype |

Usage as a Babel Plugin

Installation

npm install will-mutate @babel/core@^7.0.0 --save-dev

Code

Add the $shouldNotMutate function call directly above any function declaration or expression with the name of any variable in-scope at the beginning of the function body.

// In this example, we're asserting that the argument `foo` will not mutate
$shouldNotMutate(["foo"]);
function bar (foo, other) {
    foo.prop = "Test";
    other.prop = "Don't change me";
}

Errors

The below error is taken from running the above code snippet with node ./bar.js after compilation with Babel. You can see that the prop property was changed using set (assignment operator) inside the bar function in the bar.js module.

Error: Mutation assertion failed. `set` trap triggered on `target.prop`.
    at Object.handler.<computed> [as set] (bar.js:148:13)
    at bar (bar.js:194:31)
    at Object.<anonymous> (bar.js:211:1)

Babel Config

You must also add Will Mutate to your Babel config. If you intend to leave the functions in your codebase you can use noop to run whenever you do not want runtime errors (e.g. production).

babel.config.js

module.exports = {
    plugins: [
        process.env.NODE_ENV === "development"
            ? "will-mutate"
            : "will-mutate/noop",
    ],
};

Understanding Traps

If you see a trap you do not understand, MDN has a list of proxy traps where you can understand the conditions it will trigger under. Every trap related to mutations is implemented.

Alternatives

License

Copyright Evelyn Hathaway and Corbin Crutchley, MIT License