Research
Security News
Malicious npm Packages Inject SSH Backdoors via Typosquatted Libraries
Socket’s threat research team has detected six malicious npm packages typosquatting popular libraries to insert SSH backdoors.
@warpjs/warp
Advanced tools
Warp is an API to run JavaScript functions in parallel: get the most of multi-core systems, shorten response time & intensive computations.
Warp is an API allowing a JavaScript program to easily execute some of its code on servers.
// runs `fnct` on a server
warper.callWithCallback(fnct, <args>, cb);
Warp module is an API and is not providing support for execution. You will need to acquire a Warp runtime to use it.
To add Warp API to your project:
$ npm install @warpjs/warp
Warp offers two main functions to start a warp task: warper.call
and warper.callWithCallback
.
We say that they perform a warp call. By extension, we also say that code
warps a function or that the function is warped.
Here is a very simple illustrative code sample where a CPU intensive function (computePrimeFactorization
)
is executed on a server by a warp call keeping the event loop free for any other processing. If you
want to see complete code, browse the repository.
The first example uses a Promise-based function, whereas the second uses a callback-based function.
const warper = require('@warpjs/warp').defaultWarper;
function computePrimeFactorization(n) {
// Compute `f`
return f;
}
let a = await warper.call(computePrimeFactorization, 9007199254740991);
console.log(`Prime factors of ${a.value} are ${a.factors}`);
Prints out
Prime factors of 9007199254740991 are 6361,69431,20394401
const warper = require('@warpjs/warp').defaultWarper;
function computePrimeFactorization(n, done) {
// Compute `f`
done(f);
}
warper.callWithCallback(computePrimeFactorization, 9007199254740991,
(a) => console.log(`Prime factors of ${a.value} are ${a.factors}`));
Prints out
Prime factors of 9007199254740991 are 6361,69431,20394401
When you warp call a function, the execution context (i.e. everything reachable from the function scope) is captured, then this context and the warped function are sent to a server for execution.
Once the warp task is finished, the server context is captured and sent back to the client. Then, in an event task of the client, the context is updated, and:
call
, the Promise returned by call
is resolved or
rejected with the value or the exception obtained at the end of the server warp task.callWithCallback
, the callback is executed in the main thread, with the arguments
given to the callback on the server.The warped functions can read and modify anything reachable from their scope.
In the following sample, the variable o
is defined as a free variable (outside of the function).
The warped function can read it, and also modify the object. Modifications made to o
on the server are
applied and visible on the client.
const warper = require('@warpjs/warp').defaultWarper;
let o = {};
function computePrimeFactorization(n) {
// Compute `f`
o.result = f;
}
await warper.call(computePrimeFactorization, 9007199254740991);
console.log(`Prime factors of ${o.value} are ${o.factors}`);
Prints out
Prime factors of 9007199254740991 are 6361,69431,20394401
Warp offers no new synchronization or semaphore mechanism. If you need to manage concurrent access to a value, you'll have to keep the modifying code on the client.
In the following example, we compute several prime factorizations in parallel.
const warper = require('@warpjs/warp').defaultWarper;
let primeFactorizations = [];
function computePrimeFactorization(index, n) {
// Compute `f`
primeFactorizations[index] = f;
}
let promises = []
for(let i = 0; i < 8; i++) {
promises.push(warper.call(computePrimeFactorization, i, 9007174991 + i));
}
await Promise.all(promises);
console.log(`Prime factorizations: %j`, primeFactorizations);
Prints out
Prime factorizations: [{"value":9007174991,"factors":[17,131,4044533]},{"value":9007174997,"factors":{"0":59,"1":109,"2":1400587,"value":9007174993,"factors":[12071,746183]}},{"0":59,"1":109,"2":1400587,"value":9007174993,"factors":[12071,746183]},{"0":2,"1":2,"2":2251793749,"value":9007174994,"factors":[2,37,53,2296577]},{"value":9007174995,"factors":[3,5,7,13,41,227,709]},{"value":9007174997,"factors":{"0":59,"1":109,"2":1400587,"value":9007174993,"factors":[12071,746183]}},{"value":9007174997,"factors":{"0":59,"1":109,"2":1400587,"value":9007174993,"factors":[12071,746183]}},{"value":9007174998,"factors":[2,3,3,3,19,43,204161]}]
But you need to be careful about parallel access to shared variables or properties.
For instance, the following example shows bad usage of a shared value causing indetermism. There, you
don't know in which order the additions will be made, but it is guaranteed that each fnct
sees
the initial value of v
as 4
. This means you don't know what the final value of v
will be, you
just know it will be either 7
or 8
.
const warper = require('warp').defaultWarper;
let v = 4;
function fnct(num) {
let inc = num;
v += inc;
return;
}
let promises = []
promises.push(warper.call(fnct, 3));
promises.push(warper.call(fnct, 4));
await Promise.all(promises);
console.log(`Value: ${v}`);
To obtain the correct behavior in this example, you'll need to apply the changes to the shared
variable on the client by using the .then
of the promise.
const warper = require('warp').defaultWarper;
let v = 4;
function fnct(num) {
let inc = num;
return inc;
}
let promises = []
promises.push(warper.call(fnct, 3).then((inc) => v += inc));
promises.push(warper.call(fnct, 4).then((inc) => v += inc));
await Promise.all(promises);
console.log(`Value: ${v}`);
Prints out
Value: 11
This way it'll end up with 11
as the final value.
A warp task is started by a warp call (a call to warper.call
or warper.callWithCallback
).
The task is executed on a server. It starts by executing the given
function and continues until the end of the task is detected.
The end of the task is detected when:
or
If the task was started by warper.call
:
call
has returnedIf the task was started by warper.callWithCallback
callWithCallback
has returned.Note that this doesn't mean that return
was executed, it means that the execution has
returned to its caller. For example in the following code the end is detected during the line
a = await 3
when await
yields and a
is still 2
.
let a = 0;
async function fnct(done) {
a = 1;
done();
a = 2;
a = await 3; // End is here at `await` before assignation of `a`
return;
}
Warning: If the task were to attempt to execute code after the end of execution were detected
(e.g. with a setImmediate
, setTimeout
, ...), then the behavior would be unspecified. This
means that if the function given to callWithCallback
is starting any asynchronous processing, calling
the callback
must be the very last thing done by the task.
An execution context is referring to everything accessible from the scope of the considered function at a given point of the execution. This includes
FAQs
WarpJS is a serverless platform with front-end integration capabilities. You focus on features with one JavaSscript fullStack codebase, WarpJS deals with the back-end for you: communication, routing, API, versioning, error management, deployment, scaling
The npm package @warpjs/warp receives a total of 1 weekly downloads. As such, @warpjs/warp popularity was classified as not popular.
We found that @warpjs/warp demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 2 open source maintainers collaborating on the project.
Did you know?
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.
Research
Security News
Socket’s threat research team has detected six malicious npm packages typosquatting popular libraries to insert SSH backdoors.
Security News
MITRE's 2024 CWE Top 25 highlights critical software vulnerabilities like XSS, SQL Injection, and CSRF, reflecting shifts due to a refined ranking methodology.
Security News
In this segment of the Risky Business podcast, Feross Aboukhadijeh and Patrick Gray discuss the challenges of tracking malware discovered in open source softare.