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

khan-structured

v0.1.2

Published

Simple interface for checking structure of JS code against a template, backed by Esprima.

Downloads

39

Readme

structured.js is a Javascript library that provides a simple interface for verifying the structure of Javascript code, backed by the abstract syntax tree generated by Esprima. It is particularly useful in checking beginner code to provide feedback as part of Khan Academy's CS curriculum.

Structured.js works in-browser <script src='structured.js'></script>, or as a standalone npm module.

A structure is any valid Javascript code which contains blanks ( _ characters) and stand-ins ($str) to match values. The structure is sensitive to nesting and ordering. The matcher only requires that code contain the structure -- extra code has no effect.

Demo

Try structured.js yourself to see it in action.

Also check out the pretty display demo for more user-friendly structures.

Examples

var structure = function() {
  if (_) {
    _ += _;
    for (var $a = _; $a < $b; $a += _) {
        _($a, $b, 30, 30);
    }
  }
};

var code = "/* some code */";

var result = Structured.match(code, structure);

Returns true for the code:

if (y > 30 && x > 13) {
   x += y;
   for (var i = 0; i < 100; i += 1) {
     rect(i, 100, 30, 30);
     bar();
   }
}

Check out the demo for more, or look at the tests.

Advanced -- Variable Callbacks

To allow tighter control over what exactly is allowed to match your $variable, you may provide a mapping from variable names to function callbacks. These callbacks can enable NOT, OR, and AND functionality on the wildcard variables, for example.

Callback parameters should be the same as the name of the wildcard variables they are matching. The callback takes in a proposed value for the variable and accepts/rejects it by returning a boolean. The callback may instead return an object such as {failure: "failure message"} as well if you'd like to explain exactly why this value is not allowed.

For instance, say we want to check the value we assign to a var -- check that it is really big, and that it is bigger than whatever we increment it by. It would look like this:

var structure = function() {var _ = $num; $num += $incr; };
var code = "var foo = 400; foo += 3;";
var varCallbacks = [
  function($num) {
    return num.value > 100;  // Just return true/false
  },
  function($num, $incr) {
    if (num.value <= incr.value) {
      // Return the failure message
      return {failure: "The increment must be smaller than the number."};
    }
    return true;
  }
];
var match = Structured.match(code, structure, {varCallbacks: varCallbacks});
if (!match) {
  // varCallbacks.failure contains the error message, if any.
  console.log("The problem is: " + varCallbacks.failure);
}

Note that the callbacks receive objects that contain a subtree of the Esprima parse tree, not a raw value. Also note that the callbacks run statically, not dynamically -- so, you will only be able to directly check literal values (i.e., 48), not computed values (24*2, myVar, etc). The callbacks also ignore any variable callbacks for variables that do not actually appear in the structure you've passed in.

Go to the demo to try it out.

Tests

Run structured.js tests with npm test or by opening browser-test/index.html.

Dependencies

Esprima and UnderscoreJS for the framework, QUnit for the test suite, RainbowJS for prettified structures.