New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

nisp

Package Overview
Dependencies
Maintainers
2
Versions
57
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

nisp

A language that for easily build cross-language language

  • 0.13.8
  • latest
  • Source
  • npm
  • Socket score

Version published
Weekly downloads
4.3K
increased by17.46%
Maintainers
2
Weekly downloads
 
Created
Source

nisp

NPM version Build Status Deps Up to Date

The interesting part is that nisp is designed to be Turing incomplete.

You have the full control of the vm and ast, you can decide what the language will have, or how lazy the expression will be. for example, if you don't expose the if exp the user can never express if logic.

By default nisp only presents the meta data of the program itself. So by default it is used to exchange plain data.

You may ask what it really does? Yes, it does nothing. And that is exactly what a composable permission protocol needs. I use it to expose composable api.

The ast of nisp is plain JSON, the js implementation is only around 50 lines of code, so it will be very easy to port nisp to other languages. No closure or complex data type is required, even plain C can implement nisp easily.

Everything inside nisp is just function, so it's very easy to keep everything type safe, and with the composable nature, nisp is an ideal middle layer to carry query or RPC. Such as the Websocket RPC lib based on nisp: https://github.com/ysmood/nisper.

Quick Start

For more examples, read the unit test of this project.

Try it online: https://runkit.com/ysmood/nisp-demo

Implementaions

Define your own function

For a simple example, here you can use it as a sum-only-calculator.

import nisp from 'nisp'

var sandbox = {
    '+': (a, b) => a + b
};

var exp = ['+', 1, ['+', 1, 1]];

nisp(exp, sandbox); // => 3

Encode and escape data

Sometimes you may want to separate nisp code and raw data, Here we provide encode function to reduce the pain of typing quotes and commas. The grammar is a subset of lisp.

import nisp from 'nisp'
import encode from 'nisp/lib/encode'
import $ from 'nisp/lib/$'

var sandbox = {
    $, // raw data
    "+": ns => ns.reduce((a, b) => a + b),
    "++": ns => ns.map(a => a + 1)
};

var data = [1, 2, 3]

var exp = encode`(+ (++ ${data}))`

nisp(exp, sandbox); // => 9

Composable RPC and safe by design

Commonly used RPC libs such as json-rpc, thrift and GRPC can only handle function per call, if you want to handle large amount of data with two procedures, you have to load all of them on each procedure, that is a big waste. With nisp, you can seamlessly compose multiple functions into one remote call.

We even used nisp to create a simple db query language, and it automatically helps us defense insertion attach by its nature.

import nisp, { error } from 'nisp'

var sandbox = {
    concat (...args) {
        return args.reduce((a, b) => a.concat(b));
    },

    getAnimals () {
        if (this.env.isZooKeeper)
            return ['cat', 'dog'];
        else
            error(this, "Not Allowed"); // it will log error stacks
    },

    getFruits () {
        return ['apple', 'banana'];
    }
};

var session = {
    user: 'Jack',
    isZooKeeper: true
}

var exp = ["concat", ["getAnimals"], ["getFruits"]];

nisp(exp, sandbox, session);

Full control the ast with macro

Here we implementation a if expression The if expression is very special, it cannot be achieved without ast manipulation.

import nisp from 'nisp'
import encode from 'nisp/lib/encode'
import $ from 'nisp/lib/$'
import args from 'nisp/lib/args'
import $do from 'nisp/lib/do'

var sandbox = {
    $,

    // Most times you don't want to use it.
    "non-lazy-if": (cond, a, b) => cond ? a : b,

    // Full lazy.
    if: args(v => v(0) ? v(1) : v(2)),

    // Even half lazy, you have the full control to how lazy the program will be.
    // No matter v(0) is true or false, v(1) will be calculated.
    "half-lazy-if": args(function (v) {
        var v1 = v(1);
        return v(0) ? v1 : v(2);
    }),

    do: $do,

    "+" (...args) {
        console.log('calc:', args);
        return args.reduce(function (s, n) { return s + n; });
    })
};

var exp = encode`(do
    (if           true  (+ 1 1) (+ 2 2))
    (non-lazy-if  false (+ 1 1) (+ 2 2))
    (half-lazy-if true  (+ 1 1) (+ 2 2))
)`;

nisp(exp, sandbox);

Make a complete async language

var nisp = require("nisp");
var async = require("nisp/lib/async");

function waitNumber (val) {
    return new Promise(function (r) {
        return setTimeout((function () {
            return r(val);
        }), 1000);
    });
};

var sandbox = {
    download: async(() => waitNumber(1))

    "+": async((a, b) => a + b)
};

// Here we can write async code a sync way.
var exp = ["+", ["download"], ["download"]];

nisp(exp, sandbox).then(function (out) {
    // It will take about 1 seconds to log out.
    console.log(out) // => 2
});

API

The project is written in typescript, all main APIs are typed and commented.

Keywords

FAQs

Package last updated on 25 Jun 2019

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