
Security News
Attackers Are Hunting High-Impact Node.js Maintainers in a Coordinated Social Engineering Campaign
Multiple high-impact npm maintainers confirm they have been targeted in the same social engineering campaign that compromised Axios.
A general purpose, Web Worker driven, remote namespace with classes and methods.
A general purpose, Web Worker driven, remote namespace with classes and methods.
There is a new, very similar, yet different, project, in case you're looking to simply drive generic Workers instances, or namespaces, from a client/main thread: proxied-worker.
It has a NodeJS counterpart module too!
The main difference with these projects is:
A basic firebase.js client to show the user name.
workway('/workers/firebase.js').then(
async function ({worker, namespace}) {
await namespace.initializeApp({
apiKey: "<API_KEY>",
authDomain: "<PROJECT_ID>.firebaseapp.com",
databaseURL: "https://<DATABASE_NAME>.firebaseio.com",
projectId: "<PROJECT_ID>",
storageBucket: "<BUCKET>.appspot.com",
messagingSenderId: "<SENDER_ID>"
});
const fb = new namespace.FirebaseUser();
const name = await fb.name();
console.log(name); // will log the user name, if any
// the worker can be regularly used like any other worker
worker.postMessage('all good');
}
);
// you can also pass in an existing Worker instance (useful if you're using
// Webpack's worker-loader and don't have access to the output file path):
import Worker from 'worker-loader!./Worker.js';
workway(new Worker()).then(...
The workers/firebase.js worker that exposes some info.
// top import to ensure a transparent communication channel
importScripts('https://unpkg.com/workway/worker.js');
// any other needed import for this worker
importScripts(...[
'app', 'auth', 'database', 'firestore', 'messaging', 'functions'
].map(name => `https://www.gstatic.com/firebasejs/5.0.1/firebase-${name}.js`));
// expose a namespaces as an object
// with any sort of serializable value
// and also methods or classes
workway({
// any serializable data is OK (nested too)
timestamp: Date.now(),
// methods are OK too, each method
// accepts serializable arguments and
// can return a value and/or a promise
initializeApp(config) {
firebase.initializeApp(config);
},
// classes are also fine, as long as
// these respect RemoteClass conventions
FirebaseUser: class FirebaseUser {
constructor() {
this.uid = firebase.auth().currentUser.uid;
}
name() {
return firebase.database()
.ref('/users/' + this.uid)
.once('value')
.then(snapshot => ((
snapshot.val() && snapshot.val().username
) || 'Anonymous'));
}
}
});
// this worker can be regularly used like any other worker
// the passed event will never be one handled by `workway`
self.onmessage = event => {
console.log(event.data);
};
To have NodeJS driven workers you need the regular client side workway.js file, plus /pocket.io/pocket.io.js and /workway@node.js that are both handled by this module.
<script src="/workway.js">/* regular workway client file */</script>
<script src="/pocket.io/pocket.io.js">/* automatically provided by the server */</script>
<script src="/workway@node.js">/* automatically provided by the server */</script>
This is a js/os.js file for the client side.
workway('node://os.js').then(({worker, namespace:os}) => {
os.getNetworkInterfaces().then(console.log);
});
Please note the client file needs EventTarget, Promise, and WeakMap constructors. If your target browsers don't have these features, you can use the following polyfills on top of your HTML file.
<script>
if(!this.Promise)document.write('<script src="https://cdn.jsdelivr.net/npm/es6-promise@4/dist/es6-promise.auto.min.js"><'+'/script>');
if(!this.WeakMap)document.write('<script src="https://unpkg.com/poorlyfills@0.1.1/min.js"><'+'/script>');
try{new EventTarget}catch(e){document.write('<script src="https://unpkg.com/event-target@1.2.2/min.js"><'+'/script>')}
</script>
Following a workers/os.js file to serve via NodeJS.
// note: you require a facade here via 'workway'
var workway = require('workway');
workway(require('os'));
An express / node based bootstrap.
var express = require('express');
// note: you require the real module as 'workway/node'
var workway = require('workway/node');
// authorize / expose a specific folder
// that contains web driven workers
workway.authorize(__dirname + '/workers');
var app = workway.app(express());
app.use(express.static(__dirname + '/www'));
app.listen(8080);
self global (but sandboxed) variable points at the globalself.workway method is already there, feel free to use it instead of requiring it from workersself.addEventListener and self.remoteEventListener are normalized to work like on the front end side: do not use emitter methods directly with your node workers or messages and errors might not be signaled as expectedClasses exposed through workway namespace must follow these rules:
await each call if sequential methods calls depend on previous results.The code is written in a ES5 friendly syntax, and it's guaranteed to work in IE 10 or above, and mostly every mobile browser on platforms such iOS 8+, Android 4.4+, Blackberry OS 10+, or Windows Phone 8+.
You can test live your browser through the live test page.
Please note in IE 10/11 or other old browser cases, you might need to provide polyfills on both client and worker side.
Feel free to choose the polyfill you prefer.
Following just as example:
<!doctype html>
<script>
// needed for IE11
if(!this.Promise)document.write('<script src="https://cdn.jsdelivr.net/npm/es6-promise@4/dist/es6-promise.auto.min.js"><'+'/script>');
// needed for IE10
if(!this.WeakMap)document.write('<script src="https://unpkg.com/poorlyfills@0.1.1/min.js"><'+'/script>');
</script>
<script src="https://unpkg.com/workway"></script>
<script src="firebase.js"></script>
Or on top of your generic worker.
// import the polyfill you prefer for either IE11 or IE10
if (!self.Promise) importScripts('https://cdn.jsdelivr.net/npm/es6-promise@4/dist/es6-promise.auto.min.js');
if (!self.WeakMap) importScripts('https://unpkg.com/poorlyfills@0.1.1/min.js');
// now import workway/worker.js before any other worker script
importScripts('https://unpkg.com/workway/worker.js');
// ... the rest of the code ...
If you need to invoke a method passing an object that might contain recursive data you can serialize it upfront and parse it once received.
// main thread app.js side
import workway from 'https://unpkg.com/workway/esm';
import {stringify} from 'https://unpkg.com/flatted/esm';
workway('analyzer.js').then(({namespace}) => {
const data = {arr: []};
data.arr.push(data);
data.data = data;
namespace.analyze(stringify(data))
.then(
state => document.body.textContent = state,
console.error
);
});
// worker side: analyzer.js
importScripts(
'https://unpkg.com/workway/worker.js',
'https://unpkg.com/flatted'
);
workway({
analyze(circular) {
const data = Flatted.parse(circular);
return 'OK';
}
});
You can test above example right here.
./index.js./worker.js root fileesm/index.jscjs/index.jsmin.jsFAQs
A general purpose, Web Worker driven, remote namespace with classes and methods.
The npm package workway receives a total of 75 weekly downloads. As such, workway popularity was classified as not popular.
We found that workway demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer 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.

Security News
Multiple high-impact npm maintainers confirm they have been targeted in the same social engineering campaign that compromised Axios.

Security News
Axios compromise traced to social engineering, showing how attacks on maintainers can bypass controls and expose the broader software supply chain.

Security News
Node.js has paused its bug bounty program after funding ended, removing payouts for vulnerability reports but keeping its security process unchanged.