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 🙏

© 2026 – Pkg Stats / Ryan Hefner

synjs

v1.0.6

Published

Synchronous JavaScript execution

Downloads

17

Readme

Build Status

SynJS

SynJS allows to write and execute javascript code in synchronous manner, so you don't have to fight callback hell with promise hell.

What is it

With SynJS you can write code like this:

var res, i=0;

while(i<5) {

    setTimeout(function() {
        res = 'i='+i;
        SynJS.resume(_synjsContext);
    },1000);
    
    SynJS.wait();
    
    console.log(res, new Date());
    
    i++;
}

It introduces following 2 statements:

  • SynJS.wait(): this operator is used in main logic flow to pause execution of the flow
  • SynJS.resume(_synjsContext): this function is used in callback in order to continue execution from the next statement after SynJS.wait()

When executed, the code above will show following in your console:

i=0 Wed Dec 21 2016 11:45:33 GMT-0700 (Mountain Standard Time)
i=1 Wed Dec 21 2016 11:45:34 GMT-0700 (Mountain Standard Time)
i=2 Wed Dec 21 2016 11:45:35 GMT-0700 (Mountain Standard Time)
i=3 Wed Dec 21 2016 11:45:36 GMT-0700 (Mountain Standard Time)
i=4 Wed Dec 21 2016 11:45:37 GMT-0700 (Mountain Standard Time)

Quick Start

In Node.JS:

npm install synjs

global.SynJS = global.SynJS || require('synjs');

In Browser:

<script src="SynJS.js"></script>

Put your synchronous code into function:

function myTestFunction1(paramA,paramB) {
    var res, i = 0;
    while (i < 5) {
        setTimeout(function () {
            res = 'i=' + i;
            SynJS.resume(_synjsContext);
        }, 1000);

        SynJS.wait();

        console.log(res, new Date());
        i++;
    }
    return "myTestFunction1 finished";
}

Make sure you use SynJS.wait() for synchronizing your main flow with callback flow, and also make sure your callback calls SynJS.resume(_synjsContext) at the end.

Execute your function via SynJS:

SynJS.run(myTestFunction1,null, function (ret) {
    console.log('done all:', ret);
});

The result will look like this:

SynJS Reference

SynJS.run(myTestFunction1,obj, param1, param2 [, param3 etc], callback) (function, to be called to execute function synchronously)

Parameters:

  • myTestFunction1: pointer to a function that needs to be executed synchronously
  • obj: some object that will be accessed via "this" in myTestFunction1 (could be null)
  • param1, param2, etc - any number of parameters
  • callback: some function to call once myTestFunction1 is finished.

Returns:

  • execution context

SynJS.wait() (operator, to be called from main flow) Waits until SynJS.resume() is called, and then continues with the next statement.

SynJS.wait(numeric_expr) (operator, to be called from main flow)

  • numeric_expr: number of milliseconds Waits numeric_expr milliseconds, and then continues with the next statement.

SynJS.wait(non_numeric_expr) (operator, to be called from main flow)

  • non_numeric_expr: condition Waits until SynJS.resume() is called, checks if non_numeric_expr evaluates to true, then continues with the next statement. Otherwise continues waiting.

SynJS.resume(context) (function, to be called from callback)

  • context: execution context, that needs to be resumed. Execution context can be accessed inside myTestFunction1 via _synjsContext variable.

SynJS supports following types of operators:

  • var
  • if ... else
  • while
  • do ... while
  • for(;;)
  • for(var ;;)
  • for(.. in ..)
  • for(var .. in ..)
  • switch
  • break [label]
  • continue [label]
  • return

Following operators are not yet supported:

  • const
  • let
  • for ... of
  • try ... catch

Bonus

SynJS.goto(expr) - evaluates expr into label name and jumps to that label. Label is searched within the scope of current code block and all parent blocks.

How it works

SynJS accepts function pointer as an input parameter, and performs following:

  • It parses code of input function, and builds a few internal structures, such as:
    • an internal tree structure of operators, that represents code of input function
    • hash array with local variables names, that were defined in input function using var statement
  • It "compiles" each operator by
    • modifying source of operator by changing references to local variables
    • creating internal function that contain modified statement code
  • It creates execution context that contains local variables, execution stack with program counters, and other information, that is necessary in order to store the latest state, and to resume execution.
  • It executes structure of operators (code) against execution context (data).

Step 1: Parsing

In the example above SynJS parses code and recognizes 3 statements:

Statement 1:

var res, i=0;

Statement 2:

while(i<5) {
    ...
}

Statement 3:

return "myTestFunction1 finished";

Statement 2 starts with while keyword, so SynJS parses condition and body of the cycle:

Condition:

i<5

Body contains few statements itself, so SynJS parses it recursively:

Body Statement 2.1:

    setTimeout(function() {
        res = 'i='+i;
        SynJS.resume(_synjsContext);
    },1000);

Body Statement 2.2:

    SynJS.wait();

Body Statement 2.3:

    console.log(res, new Date());

Body Statement 2.4:

    i++;

Step 2. Compiling

Once statement cannot be decomposed any further, SynJS "compiles" it by doing 2 things:

  • modifying code of statement and replacing all references to local vars

  • wrapping statement code into internal function:

    function(_synjsContext) { code_of_the_statement }

Hash of local variables is created by parsing all var statements. In our example it would contain 2 names:

  • res
  • i

This array is used in order to replace all references to local vars with reference to local var hash in _synjsContext. Statement 2.3 above is converted and compiled into following internal function:

function(_synjsContext) {
    setTimeout(function() {
         _synjsContext.localVars.res = 'i='+_synjsContext.localVars.i;
         SynJS.resume(_synjsContext);
    },1000);
}

Step 3. Executing