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

n-space

v0.0.1

Published

a n-dimensional tracker

Downloads

4

Readme

N-space -- or, "Angry Bots"

This is a library for moving things around an n-dimensional space. n-dimensional spaces can be one-dimensional (a line), two-dimensional (a plane), three-dimensional(the real world - a cube), or theoretical multidimensional space.

n-space is a node or client side library for managing things in space and time. It has no render method or bias. Its measurement system is abstract, and its coordinate system is integral.

It is ideally suited as the basis for Voxel world management.

Worlds

A World is defined off the global NSPACE variable (or the module export):


var world = new World({i: [0, 10], j: [0, 10]);
var world2 = new World({x: [-5, 5], y: [-5, 5], z: [-15, 15]});

the array values are the min/max range for the dimensional extremes, and are inclusive. for instance the first example [0, 10] would allow for x values of 0, 5, or 10. There are no constraints on dimensions -- thy don't have to be the same size, or have the same range in any way.

Coordinates inside world space are integral; you can't have members with fractional/decimal coordinates.

internally Worlds contain a cells array that is a nested reflection of the coordinate system.

Reflection Methods and Properties

You can get a lot of information about the world and its dimensional systems.

Worlds have two reflection properties:

  • dim (the initial argument you passed in)
  • dimArray ( a more verbose array -- [{name: 'i', min: 0, max: 10}, {name: 'j', min: 0, max: 10}]. This is particularly useful for determining the nesting order of the cells array.
  • dimNames():[{string}] gives you the names in the dimArray (a sugar for plucking names).
  • serialize(): [{registry serialzied}] the current state of the world.

tests and filters for location

  • locInRange(loc):boolean can determine whether a coordinate is within the range of the coordinates.
  • goodLoc(loc):boolean determines whether the location has the reqauired dimensions (and valid coordinate numbers).

Note -- these two tests are mutually exclusive - you can pass goodLoc(l) and fail locInRange(l). calling locInRange(loc, true) calls goodLoc internally first.

Members

A member is anything residing in world space. More than one member can occupy the same coordinates, but there are sensor methods to allow you to pervent/coordinate stacking with application logic.

(Constructor)

The member constructor is new NSPACE.Member(mType {String/Number}, world {NSPACE.World}, loc {Object}, stackLimit {Number});

The member constructor requires only the first two properties at creation.

Properties

A member has the following properties:

  • mid {Number} an incrementing positive number reflecting creation order.
  • loc {Object} (short for location) - a hash of coordinate values like {i: 4, j: 2}.
  • mType {String/Number} the "class" of thing the member is. Members are stored by mType when they are added to the world.
  • stackLimit {Number} the maximum number of this type of members that can be stored in the same world coordinate. default: 1

Methods

  • canStack(loc {Object}): {boolean} determines whether a given cell is "full" of these type of things.
  • addToWorld(loc {Object}, world {NSPACE.World}) sets the location of the member in the world. Both properties are optional and will set the member's loc/world properties. emits 'at':member
  • remove() removes the member from the world. Does not affect location. emits 'removed':member*
  • move(loc {Object}) shorthand for a call to remove() and addToWorld(loc).
  • moveAni(time: {Number (milliseconds)} moves incrementally to a new location. At the end of the animated move, endMoveAni() is called, and the member is actually moved, emitting emit:'move end':member. Overlapping moveAni calls will cancel each other out (casing an 'emit:'move stop':member) As it moves, the member emits 'slide progress':member.
    • slideLoc(): {Object} will give you a fractional locaiton object reflecting the interpolated position of the member. This value is NOT the same as the loc property of the member.
    • progress: {Number 0..1} is a fractional value that increases from 0...1 over the timespan of the move
  • endMoveAni(moveToEnd: {boolean}, noEmit: {boolean}) allows you to cancel or force completion of a current animated move.

Registers

The World is a nested array whose leaf members are instances of Registry created on world instantiateion. The registry is a catalog of members of a given location, organized by mType. N-space is designed to warehouse members in the registry but any thing can be aded to the registry through the add(item {any}, iType {String/Number} method of a Register.

Registers can be got from the world through the world.getRegistry(loc) method.

Methods

  • equals(loc {Object}): {boolean} tests whether the registry is cataloging for a given location.
  • serialize(): {json} a more human-readable description of the registry. Will serialize its' contents that have a serialize method.
  • has(iType {String/Number}): {boolean} tests if the register has one or more member of a given type
  • add(item {any}, iType {String/Number}) adds a member to the register
  • remove(item {any}, iType {String/Number}) removes a member from the register

WanderBots

WanderBots is a template for "Intelligent member management". They can be programmed to move using a basic set of "scan rules".

A scan rule is a rule that takes in a set of neighbors and reduces them to one (or no) eligable registers to which the bot can move. The code below shows how you can create rules that both move the bots forward along axes and respect stacking order.

Bots are built on members that are constructed internally with the given type on construction:

var bot = new NSPACE.WanderBot('myType', world, loc)

Methods

  • loc() {Object} sugar for bot.member.loc
  • addScanRule(dims [{string}], reductor {function}) creates a rule determining a "Legal move" for the bot. The bot will attempt to make a legal move by finding the first ScanRule that provides an "open loc" that the bot can go to.
    • The first argument reduces movemnt to a given set of axes; for instance a rule with dims of ['x'] will reduce the legal moves to 1 + the bot's current 'x' coordinate and 1 - the bots' current 'x' coordinate.
    • The second argument is used as a map-reduce function to winnow down the legal neighbors to a single neighbor (or none).

Note that the NSPACE.WanderBotScanRule has a few 'built in' reductor factories:

  • NSPACE.WanderBotScanRule.forward(dim) returns a function that will move the bot forward in the given dimension.
  • NSPACE.WanderBotScanRule.forwardBackward returns a function that will move the bot forward if possible, or backward along a given dimension.
  • 'NSPACE.WanderBotScanRule.backward(dim)` returns a function that will move the bot backwaard.
  • NSPACE.WanderBotScanRule.backwardForward returns a function that will move the bot backward if possible, or forward along a given dimension.
  • NSPACE.WanderBotScanRule.checkStack(bot, nextReductor {function}) decorates another rule by first removing all candiadates where the bot cannot stack.

Bot Example

This example is in the test_site included in this module.

These bots also create and move a DIV related to their memberid.


    var bot = new NSPACE.WanderBot('bot', world, loc);

    bot.addScanRule(['i'],
        NSPACE.WanderBotScanRule.checkStack(bot, NSPACE.WanderBotScanRule.forward('i', bot))); // move on I -- forward preferred
    bot.addScanRule(['j'],
        NSPACE.WanderBotScanRule.checkStack(bot, NSPACE.WanderBotScanRule.forward('j', bot))); // move on J -- forward preferred

    function moveMember(member) {
        var loc = member.loc;
        var ele = document.getElementById('member-' + member.mid);
        ele.style.left = (loc.i * 50) + 'px';
        ele.style.top = (loc.j * 50) + 'px';
    }

    function slideMember(member) {
        var loc = member.slideLoc();
        var ele = document.getElementById('member-' + member.mid);
        ele.style.left = (loc.i * 50) + 'px';
        ele.style.top = (loc.j * 50) + 'px';
    }

    bot.member.on('at', moveMember);

    bot.member.on('leaving', function (member) {
        var loc = _.clone(member.loc);
        setTimeout(function () {
            var member = new NSPACE.Member('bot', world);
            if (member.canStack(loc)) {
                makeBot(loc);
            } else {
                console.log('cannot add bot into ', loc);
            }
        }, 100);
    });

    bot.member.on('slide progress', function (member, loc) {
        slideMember(member, loc);
    });

    setInterval(function () {
        bot.moveAni(100);
    }, 1000);

    document.body.insertAdjacentHTML('afterend', _div(bot));