Full Code of WebReflection/workway for AI

master 0b7ce7706199 cached
47 files
83.3 KB
23.3k tokens
93 symbols
1 requests
Download .txt
Repository: WebReflection/workway
Branch: master
Commit: 0b7ce7706199
Files: 47
Total size: 83.3 KB

Directory structure:
gitextract_vwqyj7po/

├── .gitignore
├── .npmignore
├── .travis.yml
├── LICENSE
├── README.md
├── cjs/
│   ├── index.js
│   └── remoted.js
├── esm/
│   ├── index.js
│   └── remoted.js
├── examples/
│   ├── workway-node/
│   │   ├── README.md
│   │   ├── index.js
│   │   ├── package.json
│   │   ├── workers/
│   │   │   └── os.js
│   │   └── www/
│   │       ├── index.html
│   │       └── js/
│   │           ├── 3rd/
│   │           │   ├── hyperhtml.js
│   │           │   └── workway.js
│   │           ├── index.js
│   │           └── poly/
│   │               ├── es6-promise.js
│   │               ├── event-targe.js
│   │               └── poorlyfills.js
│   └── workway-promise-reject/
│       ├── README.md
│       ├── index.html
│       ├── index.js
│       ├── package.json
│       └── workers/
│           └── index.js
├── index.js
├── min.js
├── node/
│   ├── client.js
│   └── index.js
├── package.json
├── partial/
│   └── worker.js
├── remoted.js
├── test/
│   ├── background.js
│   ├── circular/
│   │   ├── analyzer.js
│   │   └── index.html
│   ├── client.js
│   ├── foo.html
│   ├── foo.js
│   ├── index.html
│   ├── index.js
│   ├── node.html
│   ├── node.js
│   ├── webworker.js
│   └── workers/
│       ├── foo.js
│       ├── other.js
│       └── test.js
└── worker.js

================================================
FILE CONTENTS
================================================

================================================
FILE: .gitignore
================================================
.DS_Store
node_modules/
package-lock.json
^worker.js


================================================
FILE: .npmignore
================================================
node_modules/*
examples/*
partial/*
test/*
.DS_Store
.gitignore
.travis.yml
package-lock.json


================================================
FILE: .travis.yml
================================================
language: node_js
node_js:
  - stable
git:
  depth: 1
branches:
  only:
    - master


================================================
FILE: LICENSE
================================================
ISC License

Copyright (c) 2018, Andrea Giammarchi, @WebReflection

Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.

THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.


================================================
FILE: README.md
================================================
# workway DEPRECATED - See [coincident](https://github.com/WebReflection/coincident#coincidentserver)

A general purpose, Web Worker driven, remote namespace with classes and methods.


- - -

## Announcement: Meet proxied-worker & proxied-node

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](https://github.com/WebReflection/proxied-worker#readme).

It has [a NodeJS counterpart module](https://github.com/WebReflection/proxied-node#readme) too!

The main difference with these projects is:

  * classes have a working constructor
  * heap is automatically cleaned on both client/server
  * it uses *Proxy* and *FinalizationRegistry* so these are not as compatible as *workway* is with legacy browsers

- - -


## Key Features

  * no eval at all, no scope issues, 100% CSP friendly
  * no Proxy at all neither, compatible with IE 10, iOS 8, Android 4.4, BB OS 10, and [every other browser](https://webreflection.github.io/workway/test/)
  * 100LOC client squeezed in about 0.5K once compressed
  * you expose non blocking namespaces to the main thread, not the other way around
  * it **works on NodeJS** too 🎉



## Example <sup><sub>(client side only)</sub></sup>
A basic **firebase.js** client to show the user name.
```js
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.
```js
// 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);
};
```

## Example <sup><sub>(NodeJS)</sub></sup>

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.

```html
<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.
```js
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.

```html
<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.
```js
// note: you require a facade here via 'workway'
var workway = require('workway');
workway(require('os'));
```

An express / node based bootstrap.
```js
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);
```

### NodeJS extra features & gotchas

  * exact same API (actually exact same code) of the real Web Worker based client side
  * circular objects are supported out of the box via [flatted](https://github.com/WebReflection/flatted#flatted) on both ways
  * the `self` global (but sandboxed) variable points at the global
  * the `self.workway` method is already there, feel free to use it instead of requiring it from workers
  * the `self.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 expected


## The RemoteClass convention

Classes exposed through `workway` namespace must follow these rules:

  * no constructor arguments; use methods to eventually forward extra details from the client
  * methods can accept only serializable arguments and can return either a serializable value or a promise that will resolve as serializable data
  * properties set on the **client** side must be serializable and will be **reflected** into related worker instances whenever methods are invoked
  * properties set in the **worker** will **not** be **reflected** on the client side so that what's defined in the worker, stays in the worker
  * every method invocation returns a Promise, even if the method returned value is not
  * multiple methods invocation at once are possible, but there is no guarantee of the order. Use promises features or `await` each call if sequential methods calls depend on previous results.



## Compatibility

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](https://webreflection.github.io/workway/test/index.html)**.

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:

```html
<!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.
```js
// 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 ... 
```



## About Recursive data

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.

```js
// 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](https://webreflection.github.io/workway/test/circular/).



### Extra Info

  * the client side of this package fits in just 100 LOC
  * the client side of this project weights 0.5K via brotli, 0.6K via gzip
  * the client side source of truth of this project is its root `./index.js`
  * the only worker related code is in `./worker.js` root file
  * the ESM version of this module is in `esm/index.js`
  * the CJS version of this module is in `cjs/index.js`
  * the browser version of this module is in `min.js`


================================================
FILE: cjs/index.js
================================================
function workway(file) {'use strict';
  /*! (c) 2018 Andrea Giammarchi (ISC) */
  return new Promise(function (res) {
    function uid() { return ++i + Math.random(); }
    var i = 0;
    var channel = uid();
    var messages = {};
    var worker = typeof file === 'string' ? new Worker(file) : file;
    worker.addEventListener('message', function (event) {
      if (event.data.channel !== channel) return;
      event.stopImmediatePropagation();
      var namespace = event.data.namespace;
      if (namespace) {
        var Class = function (info) {
          var path = info.path;
          var methods = info.methods;
          var statics = info.statics;
          var wm = new WeakMap;
          function RemoteClass() { wm.set(this, uid()); }
          methods.forEach(function (method) {
            RemoteClass.prototype[method] = function () {
              return send({
                args: slice.call(arguments),
                path: path,
                method: method,
                object: {
                  id: wm.get(this),
                  value: this
                }
              });
            };
          });
          statics.methods.forEach(function (method) {
            RemoteClass[method] = function () {
              return send({
                args: slice.call(arguments),
                path: path,
                method: method
              });
            };
          });
          statics.values.forEach(function (pair) {
            RemoteClass[pair[0]] = pair[1];
          });
          return RemoteClass;
        };
        var callback = function (path) {
          return function remoteCallback() {
            return send({
              args: slice.call(arguments),
              path: path
            });
          };
        };
        var send = function (message) {
          var resolve, reject;
          var promise = new Promise(function (res, rej) {
            resolve = res;
            reject = rej;
          });
          promise.resolve = resolve;
          promise.reject = reject;
          messages[message.id = uid()] = promise;
          worker.postMessage({
            channel: channel,
            message: message
          });
          return promise;
        };
        var slice = [].slice;
        (function update(namespace) {
          Object.keys(namespace).forEach(function (key) {
            var info = namespace[key];
            switch (info.type) {
              case 'class': namespace[key] = Class(info); break;
              case 'function': namespace[key] = callback(info.path); break;
              case 'object': update(namespace[key] = info.value); break;
              default: namespace[key] = info.value;
            }
          });
        }(namespace));
        res({
          worker: worker,
          namespace: namespace
        });
      } else {
        var message = event.data.message;
        var id = message.id;
        var promise = messages[id];
        delete messages[id];
        if (message.hasOwnProperty('error')) {
          var error, facade = message.error;
          if (facade.hasOwnProperty('source'))
            error = facade.source;
          else {
            error = new Error(facade.message);
            error.stack = facade.stack;
          }
          promise.reject(error);
        }
        else
          promise.resolve(message.result);
      }
    });
    worker.postMessage({channel: channel});
  });
}
module.exports = workway;


================================================
FILE: cjs/remoted.js
================================================
function remoted(object) {
  return function $(object, current, remote) {
    Object.keys(object).forEach(function (key) {
      var value = object[key];
      var path = current.concat(key);
      if (typeof value === 'function') {
        remote[key] = /^[A-Z]/.test(key) ?
          {
            type: 'class',
            path: path,
            methods: Object.getOwnPropertyNames(value.prototype)
                            .filter(no(['constructor']))
                            .concat('destroy'),
            statics: Object.getOwnPropertyNames(value)
                            .filter(no([
                              'arguments', 'callee', 'caller',
                              'length', 'name', 'prototype'
                            ]))
                            .reduce(
                              function (info, key) {
                                if (typeof value[key] === 'function') {
                                  info.methods.push(key);
                                } else {
                                  info.values.push([key, value[key]]);
                                }
                                return info;
                              },
                              {
                                methods: [],
                                values: []
                              }
                            )
          } :
          {
            type: 'function',
            path: path
          };
      } else if (remote.toString.call(value) === '[object Object]') {
        remote[key] = {
          type: 'object',
          path: path,
          value: {}
        };
        $(value, path, remote[key].value);
      } else if (value !== void 0) {
        remote[key] = {
          type: 'any',
          path: path,
          value: value
        };
      }
    });
    return remote;
  }(object, [], {});
  function no(within) {
    return function (what) {
      return within.indexOf(what) < 0;
    };
  }
}
module.exports = remoted;


================================================
FILE: esm/index.js
================================================
function workway(file) {'use strict';
  /*! (c) 2018 Andrea Giammarchi (ISC) */
  return new Promise(function (res) {
    function uid() { return ++i + Math.random(); }
    var i = 0;
    var channel = uid();
    var messages = {};
    var worker = typeof file === 'string' ? new Worker(file) : file;
    worker.addEventListener('message', function (event) {
      if (event.data.channel !== channel) return;
      event.stopImmediatePropagation();
      var namespace = event.data.namespace;
      if (namespace) {
        var Class = function (info) {
          var path = info.path;
          var methods = info.methods;
          var statics = info.statics;
          var wm = new WeakMap;
          function RemoteClass() { wm.set(this, uid()); }
          methods.forEach(function (method) {
            RemoteClass.prototype[method] = function () {
              return send({
                args: slice.call(arguments),
                path: path,
                method: method,
                object: {
                  id: wm.get(this),
                  value: this
                }
              });
            };
          });
          statics.methods.forEach(function (method) {
            RemoteClass[method] = function () {
              return send({
                args: slice.call(arguments),
                path: path,
                method: method
              });
            };
          });
          statics.values.forEach(function (pair) {
            RemoteClass[pair[0]] = pair[1];
          });
          return RemoteClass;
        };
        var callback = function (path) {
          return function remoteCallback() {
            return send({
              args: slice.call(arguments),
              path: path
            });
          };
        };
        var send = function (message) {
          var resolve, reject;
          var promise = new Promise(function (res, rej) {
            resolve = res;
            reject = rej;
          });
          promise.resolve = resolve;
          promise.reject = reject;
          messages[message.id = uid()] = promise;
          worker.postMessage({
            channel: channel,
            message: message
          });
          return promise;
        };
        var slice = [].slice;
        (function update(namespace) {
          Object.keys(namespace).forEach(function (key) {
            var info = namespace[key];
            switch (info.type) {
              case 'class': namespace[key] = Class(info); break;
              case 'function': namespace[key] = callback(info.path); break;
              case 'object': update(namespace[key] = info.value); break;
              default: namespace[key] = info.value;
            }
          });
        }(namespace));
        res({
          worker: worker,
          namespace: namespace
        });
      } else {
        var message = event.data.message;
        var id = message.id;
        var promise = messages[id];
        delete messages[id];
        if (message.hasOwnProperty('error')) {
          var error, facade = message.error;
          if (facade.hasOwnProperty('source'))
            error = facade.source;
          else {
            error = new Error(facade.message);
            error.stack = facade.stack;
          }
          promise.reject(error);
        }
        else
          promise.resolve(message.result);
      }
    });
    worker.postMessage({channel: channel});
  });
}
export default workway;


================================================
FILE: esm/remoted.js
================================================
function remoted(object) {
  return function $(object, current, remote) {
    Object.keys(object).forEach(function (key) {
      var value = object[key];
      var path = current.concat(key);
      if (typeof value === 'function') {
        remote[key] = /^[A-Z]/.test(key) ?
          {
            type: 'class',
            path: path,
            methods: Object.getOwnPropertyNames(value.prototype)
                            .filter(no(['constructor']))
                            .concat('destroy'),
            statics: Object.getOwnPropertyNames(value)
                            .filter(no([
                              'arguments', 'callee', 'caller',
                              'length', 'name', 'prototype'
                            ]))
                            .reduce(
                              function (info, key) {
                                if (typeof value[key] === 'function') {
                                  info.methods.push(key);
                                } else {
                                  info.values.push([key, value[key]]);
                                }
                                return info;
                              },
                              {
                                methods: [],
                                values: []
                              }
                            )
          } :
          {
            type: 'function',
            path: path
          };
      } else if (remote.toString.call(value) === '[object Object]') {
        remote[key] = {
          type: 'object',
          path: path,
          value: {}
        };
        $(value, path, remote[key].value);
      } else if (value !== void 0) {
        remote[key] = {
          type: 'any',
          path: path,
          value: value
        };
      }
    });
    return remote;
  }(object, [], {});
  function no(within) {
    return function (what) {
      return within.indexOf(what) < 0;
    };
  }
}
export default remoted;


================================================
FILE: examples/workway-node/README.md
================================================
# Node.js workway demo

This demo shows CPUs and current memory consumption.

```sh
npm install
# now open that localhost page
```


================================================
FILE: examples/workway-node/index.js
================================================
const path = require('path');
const express = require('express');
const workway = require('workway/node');

// which folder should be reachable from the Web ?
workway.authorize(path.join(__dirname, 'workers'));

// create an app through workway
const app = workway.app(express());
app.use(express.static(path.join(__dirname, 'www')));
app.listen(process.env.PORT || 8080, function () {
  console.log(`http://localhost:${this.address().port}/`);
});


================================================
FILE: examples/workway-node/package.json
================================================
{
  "private": true,
  "description": "A basic workway driven NodeJS example",
  "scripts": {
    "postinstall": "npm start",
    "start": "node index.js"
  },
  "author": "Andrea Giammarchi",
  "license": "ISC",
  "dependencies": {
    "express": "^4.16.3",
    "workway": "^0.5.2"
  }
}


================================================
FILE: examples/workway-node/workers/os.js
================================================
const workway = require('workway');

// export any namespace or even modules
workway(require('os'));


================================================
FILE: examples/workway-node/www/index.html
================================================
<!doctype html>
<html>
  <head>
    <title>workway meets NodeJS</title>
    <style>body { font-family: sans-serif; }</style>
    <script>
    if(!this.Promise)document.write('<script src="/js/poly/es6-promise.js"><'+'/script>');
    if(!this.WeakMap)document.write('<script src="/js/poly/poorlyfills.js"><'+'/script>');
    try{new EventTarget}catch(e){document.write('<script src="/js/poly/event-target.js"><'+'/script>')}
    </script>
    <script src="/js/3rd/hyperhtml.js"></script>
    <script src="/js/3rd/workway.js"></script>
    <script src="/pocket.io/pocket.io.js"></script>
    <script src="/workway@node.js"></script>
    <script src="/js/index.js"></script>
  </head>
  <body></body>
</html>

================================================
FILE: examples/workway-node/www/js/3rd/hyperhtml.js
================================================
/*! (c) Andrea Giammarchi (ISC) */var hyperHTML=function(e){"use strict";var t=document.defaultView,r=/^area|base|br|col|embed|hr|img|input|keygen|link|menuitem|meta|param|source|track|wbr$/i,l="ownerSVGElement",c="http://www.w3.org/2000/svg",s="connected",f="dis"+s,d=/^style|textarea$/i,b="_hyper: "+(Math.random()*new Date|0)+";",h="\x3c!--"+b+"--\x3e",v=t.Event;try{new v("Event")}catch(e){v=function(e){var t=document.createEvent("Event");return t.initEvent(e,!1,!1),t}}var n,i=t.Map||function(){var n=[],r=[];return{get:function(e){return r[n.indexOf(e)]},set:function(e,t){r[n.push(e)-1]=t}}},o=0,p=t.WeakMap||function(){var n=b+o++;return{get:function(e){return e[n]},set:function(e,t){Object.defineProperty(e,n,{configurable:!0,value:t})}}},a=t.WeakSet||function(){var t=new p;return{add:function(e){t.set(e,!0)},has:function(e){return!0===t.get(e)}}},u=Array.isArray||(n={}.toString,function(e){return"[object Array]"===n.call(e)}),m=b.trim||function(){return this.replace(/^\s+|\s+$/g,"")};function g(){return this}var w=function(e,t){var n="_"+e+"$";return{get:function(){return this[n]||(this[e]=t.call(this,e))},set:function(e){Object.defineProperty(this,n,{configurable:!0,value:e})}}},y={},N=[],x=y.hasOwnProperty,E=0,C=function(e,t){e in y||(E=N.push(e)),y[e]=t},j=function(e,t){for(var n=0;n<E;n++){var r=N[n];if(x.call(e,r))return y[r](e[r],t)}},A=function(e,t){return S(e).createElement(t)},S=function(e){return e.ownerDocument||e},T=function(e){return S(e).createDocumentFragment()},L=function(e,t){return S(e).createTextNode(t)},O=" \\f\\n\\r\\t",k="[^ "+O+"\\/>\"'=]+",M="[ "+O+"]+"+k,D="<([A-Za-z]+[A-Za-z0-9:_-]*)((?:",$="(?:=(?:'[^']*?'|\"[^\"]*?\"|<[^>]*?>|"+k+"))?)",P=new RegExp(D+M+$+"+)([ "+O+"]*/?>)","g"),B=new RegExp(D+M+$+"*)([ "+O+"]*/>)","g"),R=T(document),H="append"in R,_="content"in A(document,"template");R.appendChild(L(R,"g")),R.appendChild(L(R,""));var z=1===R.cloneNode(!0).childNodes.length,F="importNode"in document,Z=H?function(e,t){e.append.apply(e,t)}:function(e,t){for(var n=t.length,r=0;r<n;r++)e.appendChild(t[r])},I=new RegExp("("+M+"=)(['\"]?)"+h+"\\2","gi"),V=function(e,t,n,r){return"<"+t+n.replace(I,W)+r},W=function(e,t,n){return t+(n||'"')+b+(n||'"')},q=function(e,t){return(l in e?Y:X)(e,t.replace(P,V))},G=z?function(e){for(var t=e.cloneNode(),n=e.childNodes||[],r=n.length,i=0;i<r;i++)t.appendChild(G(n[i]));return t}:function(e){return e.cloneNode(!0)},J=F?function(e,t){return e.importNode(t,!0)}:function(e,t){return G(t)},K=[].slice,Q=function(e){return U(e)},U=function(e){if(e.propertyIsEnumerable("raw")||/Firefox\/(\d+)/.test((t.navigator||{}).userAgent)&&parseFloat(RegExp.$1)<55){var n={};U=function(e){var t="^"+e.join("^");return n[t]||(n[t]=e)}}else U=function(e){return e};return U(e)},X=_?function(e,t){var n=A(e,"template");return n.innerHTML=t,n.content}:function(e,t){var n=A(e,"template"),r=T(e);if(/^[^\S]*?<(col(?:group)?|t(?:head|body|foot|r|d|h))/i.test(t)){var i=RegExp.$1;n.innerHTML="<table>"+t+"</table>",Z(r,K.call(n.querySelectorAll(i)))}else n.innerHTML=t,Z(r,K.call(n.childNodes));return r},Y=_?function(e,t){var n=T(e),r=S(e).createElementNS(c,"svg");return r.innerHTML=t,Z(n,K.call(r.childNodes)),n}:function(e,t){var n=T(e),r=A(e,"div");return r.innerHTML='<svg xmlns="'+c+'">'+t+"</svg>",Z(n,K.call(r.firstChild.childNodes)),n};function ee(e){this.childNodes=e,this.length=e.length,this.first=e[0],this.last=e[this.length-1]}ee.prototype.insert=function(){var e=T(this.first);return Z(e,this.childNodes),e},ee.prototype.remove=function(){var e=this.first,t=this.last;if(2===this.length)t.parentNode.removeChild(t);else{var n=S(e).createRange();n.setStartBefore(this.childNodes[1]),n.setEndAfter(t),n.deleteContents()}return e};var te=function(e,t,n){e.unshift(e.indexOf.call(t.childNodes,n))},ne=function(e,t,n){return{type:e,name:n,node:t,path:function(e){var t=[],n=void 0;switch(e.nodeType){case 1:case 11:n=e;break;case 8:n=e.parentNode,te(t,n,e);break;default:n=e.ownerElement}for(e=n;n=n.parentNode;e=n)te(t,n,e);return t}(t)}},re=function(e,t){for(var n=t.length,r=0;r<n;r++)e=e.childNodes[t[r]];return e},ie=/acit|ex(?:s|g|n|p|$)|rph|ows|mnc|ntw|ine[ch]|zoo|^ord/i,oe=function(o,a){var u=void 0,l=void 0;return function(e){switch(typeof e){case"object":if(e){if("object"===u){if(!a&&l!==e)for(var t in l)t in e||(o[t]="")}else a?o.value="":o.cssText="";var n=a?{}:o;for(var r in e){var i=e[r];n[r]="number"!=typeof i||ie.test(r)?i:i+"px"}u="object",a?o.value=le(l=n):l=e;break}default:l!=e&&(u="string",l=e,a?o.value=e||"":o.cssText=e||"")}}},ae=/([^A-Z])([A-Z]+)/g,ue=function(e,t,n){return t+"-"+n.toLowerCase()},le=function(e){var t=[];for(var n in e)t.push(n.replace(ae,ue),":",e[n],";");return t.join("")},ce=function(e){return e},se=function(e,t,n,r){if(null==r)t.removeChild(e(n,-1));else{var i=t.ownerDocument.createRange();i.setStartBefore(e(n,-1)),i.setEndAfter(e(r,-1)),i.deleteContents()}},fe=function(e,t,n,r,i){for(var o=r||ce,a=null==i?null:o(i,0),u=0,l=0,c=t.length-1,s=t[0],f=t[c],d=n.length-1,h=n[0],v=n[d];u<=c&&l<=d;)if(null==s)s=t[++u];else if(null==f)f=t[--c];else if(null==h)h=n[++l];else if(null==v)v=n[--d];else if(s==h)s=t[++u],h=n[++l];else if(f==v)f=t[--c],v=n[--d];else if(s==v)e.insertBefore(o(s,1),o(f,-0).nextSibling),s=t[++u],v=n[--d];else if(f==h)e.insertBefore(o(f,1),o(s,0)),f=t[--c],h=n[++l];else{var p=t.indexOf(h);if(p<0)e.insertBefore(o(h,1),o(s,0)),h=n[++l];else{for(var m=p,g=l;m<=c&&g<=d&&t[m]===n[g];)m++,g++;if(1<m-p)--p===u?e.removeChild(o(s,-1)):se(o,e,s,t[p]),l=g,s=t[u=m],h=n[g];else{var b=t[p];t[p]=null,e.insertBefore(o(b,1),o(s,0)),h=n[++l]}}}if(u<=c||l<=d)if(c<u){var w=n[d+1],y=null==w?a:o(w,0);if(l===d)e.insertBefore(o(n[l],1),y);else{for(var N=e.ownerDocument.createDocumentFragment();l<=d;)N.appendChild(o(n[l++],1));e.insertBefore(N,y)}}else null==t[u]&&u++,u===c?e.removeChild(o(t[u],-1)):se(o,e,t[u],t[c]);return n},de=new a;function he(){}he.prototype=Object.create(null);var ve=function(e){return{html:e}},pe=function e(t,n){return"ELEMENT_NODE"in t?t:t.constructor===ee?1/n<0?n?t.remove():t.last:n?t.insert():t.first:e(t.render(),n)},me=function(e,t,n){for(var r=new he,i=e.attributes,o=K.call(i),a=[],u=o.length,l=0;l<u;l++){var c=o[l];if(c.value===b){var s=c.name;if(!(s in r)){var f=n.shift().replace(/^(?:|[\S\s]*?\s)(\S+?)=['"]?$/,"$1");r[s]=i[f]||i[f.toLowerCase()],t.push(ne("attr",r[s],f))}a.push(c)}}for(var d=a.length,h=0;h<d;h++){var v=a[h];/^id$/i.test(v.name)?e.removeAttribute(v.name):e.removeAttributeNode(a[h])}var p=e.nodeName;if(/^script$/i.test(p)){for(var m=document.createElement(p),g=0;g<i.length;g++)m.setAttributeNode(i[g].cloneNode(!0));m.textContent=e.textContent,e.parentNode.replaceChild(m,e)}},ge=function(e,t){t(e.placeholder),"text"in e?Promise.resolve(e.text).then(String).then(t):"any"in e?Promise.resolve(e.any).then(t):"html"in e?Promise.resolve(e.html).then(ve).then(t):Promise.resolve(j(e,t)).then(t)},be=function(e){return null!=e&&"then"in e},we=function(r,i){var o=!1,a=void 0;return function e(t){switch(typeof t){case"string":case"number":case"boolean":o?a!==t&&(a=t,i[0].textContent=t):(o=!0,a=t,i=fe(r.parentNode,i,[L(r,t)],pe,r));break;case"object":case"undefined":if(null==t){o=!1,i=fe(r.parentNode,i,[],pe,r);break}default:if(o=!1,u(a=t))if(0===t.length)i.length&&(i=fe(r.parentNode,i,[],pe,r));else switch(typeof t[0]){case"string":case"number":case"boolean":e({html:t});break;case"object":if(u(t[0])&&(t=t.concat.apply([],t)),be(t[0])){Promise.all(t).then(e);break}default:i=fe(r.parentNode,i,t,pe,r)}else"ELEMENT_NODE"in(n=t)||n instanceof ee||n instanceof g?i=fe(r.parentNode,i,11===t.nodeType?K.call(t.childNodes):[t],pe,r):be(t)?t.then(e):"placeholder"in t?ge(t,e):"text"in t?e(String(t.text)):"any"in t?e(t.any):"html"in t?i=fe(r.parentNode,i,K.call(q(r,[].concat(t.html).join("")).childNodes),pe,r):e("length"in t?K.call(t):j(t,e))}var n}},ye=function(t,n,e){var r=l in t,i=void 0;if("style"===n)return function(e,t,n){if(n){var r=t.cloneNode(!0);return r.value="",e.setAttributeNode(r),oe(r,n)}return oe(e.style,n)}(t,e,r);if(/^on/.test(n)){var o=n.slice(2);return o===s||o===f?(Ee&&(Ee=!1,function(){var i=function(e,t){for(var n=new v(t),r=e.length,i=0;i<r;i++){var o=e[i];1===o.nodeType&&a(o,n)}},a=function e(t,n){de.has(t)&&t.dispatchEvent(n);for(var r=t.children,i=r.length,o=0;o<i;o++)e(r[o],n)};try{new MutationObserver(function(e){for(var t=e.length,n=0;n<t;n++){var r=e[n];i(r.removedNodes,f),i(r.addedNodes,s)}}).observe(document,{subtree:!0,childList:!0})}catch(e){document.addEventListener("DOMNodeRemoved",function(e){i([e.target],f)},!1),document.addEventListener("DOMNodeInserted",function(e){i([e.target],s)},!1)}}()),de.add(t)):n.toLowerCase()in t&&(o=o.toLowerCase()),function(e){i!==e&&(i&&t.removeEventListener(o,i,!1),(i=e)&&t.addEventListener(o,e,!1))}}if("data"===n||!r&&n in t)return function(e){i!==e&&(i=e,t[n]!==e&&null==(t[n]=e)&&t.removeAttribute(n))};var a=!1,u=e.cloneNode(!0);return function(e){i!==e&&(i=e,u.value!==e&&(null==e?(a&&(a=!1,t.removeAttributeNode(u)),u.value=e):(u.value=e,a||(a=!0,t.setAttributeNode(u)))))}},Ne=function(n){var r=void 0;return function e(t){r!==t&&("object"==typeof(r=t)&&t?be(t)?t.then(e):"placeholder"in t?ge(t,e):e("text"in t?String(t.text):"any"in t?t.any:"html"in t?[].concat(t.html).join(""):"length"in t?K.call(t).join(""):j(t,e)):n.textContent=null==t?"":t)}},xe={create:function(e,t){for(var n=[],r=t.length,i=0;i<r;i++){var o=t[i],a=re(e,o.path);switch(o.type){case"any":n.push(we(a,[]));break;case"attr":n.push(ye(a,o.name,o.node));break;case"text":n.push(Ne(a)),a.textContent=""}}return n},find:function e(t,n,r){for(var i=t.childNodes,o=i.length,a=0;a<o;a++){var u=i[a];switch(u.nodeType){case 1:me(u,n,r),e(u,n,r);break;case 8:u.textContent===b&&(r.shift(),n.push(d.test(t.nodeName)?ne("text",t):ne("any",u)));break;case 3:d.test(t.nodeName)&&m.call(u.textContent)===h&&(r.shift(),n.push(ne("text",t)))}}}},Ee=!0;var Ce=new p,je=function(){try{var e=new p,t=Object.freeze([]);if(e.set(t,!0),!e.get(t))throw t;return e}catch(t){return new i}}();function Ae(e){var t=Ce.get(this);return t&&t.template===Q(e)?Se.apply(t.updates,arguments):function(e){e=Q(e);var t=je.get(e)||function(e){var t=[],n=e.join(h).replace(Me,De),r=q(this,n);xe.find(r,t,e.slice());var i={fragment:r,paths:t};return je.set(e,i),i}.call(this,e),n=J(this.ownerDocument,t.fragment),r=xe.create(n,t.paths);Ce.set(this,{template:e,updates:r}),Se.apply(r,arguments),this.textContent="",this.appendChild(n)}.apply(this,arguments),this}function Se(){for(var e=arguments.length,t=1;t<e;t++)this[t-1](arguments[t])}var Te,Le,Oe,ke,Me=B,De=function(e,t,n){return r.test(t)?e:"<"+t+n+"></"+t+">"},$e=new p,Pe=function(n){var r=void 0,i=void 0,o=void 0,a=void 0,u=void 0;return function(e){e=Q(e);var t=a!==e;return t&&(a=e,o=T(document),i="svg"===n?document.createElementNS(c,"svg"):o,u=Ae.bind(i)),u.apply(null,arguments),t&&("svg"===n&&Z(o,K.call(i.childNodes)),r=Re(o)),r}},Be=function(e,t){var n=t.indexOf(":"),r=$e.get(e),i=t;return-1<n&&(i=t.slice(n+1),t=t.slice(0,n)||"html"),r||$e.set(e,r={}),r[i]||(r[i]=Pe(t))},Re=function(e){for(var t=e.childNodes,n=t.length,r=[],i=0;i<n;i++){var o=t[i];1!==o.nodeType&&0===m.call(o.textContent).length||r.push(o)}return 1===r.length?r[0]:new ee(r)},He=C;function _e(e){return arguments.length<2?null==e?Pe("html"):"string"==typeof e?_e.wire(null,e):"raw"in e?Pe("html")(e):"nodeType"in e?_e.bind(e):Be(e,"html"):("raw"in e?Pe("html"):_e.wire).apply(null,arguments)}return _e.Component=g,_e.bind=function(e){return Ae.bind(e)},_e.define=He,_e.diff=fe,(_e.hyper=_e).wire=function(e,t){return null==e?Pe(t||"html"):Be(e,t||"html")},Te=Pe,Le=new p,Oe=Object.create,ke=function(e,t){var n={w:null,p:null};return t.set(e,n),n},Object.defineProperties(g,{for:{configurable:!0,value:function(e,t){return function(e,t,n,r){var i,o,a,u=t.get(e)||ke(e,t);switch(typeof r){case"object":case"function":var l=u.w||(u.w=new p);return l.get(r)||(i=l,o=r,a=new e(n),i.set(o,a),a);default:var c=u.p||(u.p=Oe(null));return c[r]||(c[r]=new e(n))}}(this,Le.get(e)||(n=e,r=new i,Le.set(n,r),r),e,null==t?"default":t);var n,r}}}),Object.defineProperties(g.prototype,{handleEvent:{value:function(e){var t=e.currentTarget;this["getAttribute"in t&&t.getAttribute("data-call")||"on"+e.type](e)}},html:w("html",Te),svg:w("svg",Te),state:w("state",function(){return this.defaultState}),defaultState:{get:function(){return{}}},setState:{value:function(e,t){var n=this.state,r="function"==typeof e?e.call(this,n):e;for(var i in r)n[i]=r[i];return!1!==t&&this.render(),this}}}),_e}(window);

================================================
FILE: examples/workway-node/www/js/3rd/workway.js
================================================
function workway(a){"use strict";
/*! (c) 2018 Andrea Giammarchi (ISC) */return new Promise(function(u,e){function f(){return++t+Math.random()}var t=0,h=f(),l={},p=new Worker(a);p.addEventListener("message",function(e){if(e.data.channel===h){e.stopImmediatePropagation();var t=e.data.namespace;if(t){var o=function(e){var a,r,t=new Promise(function(e,t){a=e,r=t});return t.resolve=a,t.reject=r,l[e.id=f()]=t,p.postMessage({channel:h,message:e}),t},c=[].slice;!function r(n){Object.keys(n).forEach(function(e){var t,a=n[e];switch(a.type){case"class":n[e]=function(e){var t=e.path,a=e.methods,r=e.statics,n=new WeakMap;function s(){n.set(this,f())}return a.forEach(function(e){s.prototype[e]=function(){return o({args:c.call(arguments),path:t,method:e,object:{id:n.get(this),value:this}})}}),r.methods.forEach(function(e){s[e]=function(){return o({args:c.call(arguments),path:t,method:e})}}),r.values.forEach(function(e){s[e[0]]=e[1]}),s}(a);break;case"function":n[e]=(t=a.path,function(){return o({args:c.call(arguments),path:t})});break;case"object":r(n[e]=a.value);break;default:n[e]=a.value}})}(t),u({worker:p,namespace:t})}else{var a=e.data.message,r=a.id,n=l[r];if(delete l[r],a.hasOwnProperty("error")){var s,i=a.error;i.hasOwnProperty("source")?s=i.source:(s=new Error(i.message)).stack=i.stack,n.reject(s)}else n.resolve(a.result)}}}),p.postMessage({channel:h})})}

================================================
FILE: examples/workway-node/www/js/index.js
================================================
workway('node://os.js').then(async ({worker, namespace:os}) => {
  // cpus are not going to change (not the showed part)
  const cpus = await os.cpus();
  // grab other info and render the view
  grabAndShow();
  function grabAndShow() {
    Promise.all([
      os.freemem(),
      os.totalmem()
    ]).then(render);
  }
  // show all the details
  function render([freemem, totalmem]) {
    hyperHTML(document.body)`
    <strong>Summary of ${cpus.length}
            CPU${cpus.length === 1 ? '' : 's'}</strong>
    <ul>
      ${cpus.map(cpu => hyperHTML(cpu)`
      <li>${cpu.model}</li>`)}
    </ul>
    <hr>
    <p>Using ${
      ((100 * (totalmem - freemem)) / totalmem).toFixed(2)
    }% of memory</p>`;
    // update the same view in a second
    setTimeout(grabAndShow, 1000);
  }
});

================================================
FILE: examples/workway-node/www/js/poly/es6-promise.js
================================================
!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):t.ES6Promise=e()}(this,function(){"use strict";function t(t){var e=typeof t;return null!==t&&("object"===e||"function"===e)}function e(t){return"function"==typeof t}function n(t){B=t}function r(t){G=t}function o(){return function(){return process.nextTick(a)}}function i(){return"undefined"!=typeof z?function(){z(a)}:c()}function s(){var t=0,e=new J(a),n=document.createTextNode("");return e.observe(n,{characterData:!0}),function(){n.data=t=++t%2}}function u(){var t=new MessageChannel;return t.port1.onmessage=a,function(){return t.port2.postMessage(0)}}function c(){var t=setTimeout;return function(){return t(a,1)}}function a(){for(var t=0;t<W;t+=2){var e=V[t],n=V[t+1];e(n),V[t]=void 0,V[t+1]=void 0}W=0}function f(){try{var t=Function("return this")().require("vertx");return z=t.runOnLoop||t.runOnContext,i()}catch(e){return c()}}function l(t,e){var n=this,r=new this.constructor(p);void 0===r[Z]&&O(r);var o=n._state;if(o){var i=arguments[o-1];G(function(){return P(o,r,i,n._result)})}else E(n,r,t,e);return r}function h(t){var e=this;if(t&&"object"==typeof t&&t.constructor===e)return t;var n=new e(p);return g(n,t),n}function p(){}function v(){return new TypeError("You cannot resolve a promise with itself")}function d(){return new TypeError("A promises callback cannot return that same promise.")}function _(t){try{return t.then}catch(e){return nt.error=e,nt}}function y(t,e,n,r){try{t.call(e,n,r)}catch(o){return o}}function m(t,e,n){G(function(t){var r=!1,o=y(n,e,function(n){r||(r=!0,e!==n?g(t,n):S(t,n))},function(e){r||(r=!0,j(t,e))},"Settle: "+(t._label||" unknown promise"));!r&&o&&(r=!0,j(t,o))},t)}function b(t,e){e._state===tt?S(t,e._result):e._state===et?j(t,e._result):E(e,void 0,function(e){return g(t,e)},function(e){return j(t,e)})}function w(t,n,r){n.constructor===t.constructor&&r===l&&n.constructor.resolve===h?b(t,n):r===nt?(j(t,nt.error),nt.error=null):void 0===r?S(t,n):e(r)?m(t,n,r):S(t,n)}function g(e,n){e===n?j(e,v()):t(n)?w(e,n,_(n)):S(e,n)}function A(t){t._onerror&&t._onerror(t._result),T(t)}function S(t,e){t._state===$&&(t._result=e,t._state=tt,0!==t._subscribers.length&&G(T,t))}function j(t,e){t._state===$&&(t._state=et,t._result=e,G(A,t))}function E(t,e,n,r){var o=t._subscribers,i=o.length;t._onerror=null,o[i]=e,o[i+tt]=n,o[i+et]=r,0===i&&t._state&&G(T,t)}function T(t){var e=t._subscribers,n=t._state;if(0!==e.length){for(var r=void 0,o=void 0,i=t._result,s=0;s<e.length;s+=3)r=e[s],o=e[s+n],r?P(n,r,o,i):o(i);t._subscribers.length=0}}function M(t,e){try{return t(e)}catch(n){return nt.error=n,nt}}function P(t,n,r,o){var i=e(r),s=void 0,u=void 0,c=void 0,a=void 0;if(i){if(s=M(r,o),s===nt?(a=!0,u=s.error,s.error=null):c=!0,n===s)return void j(n,d())}else s=o,c=!0;n._state!==$||(i&&c?g(n,s):a?j(n,u):t===tt?S(n,s):t===et&&j(n,s))}function x(t,e){try{e(function(e){g(t,e)},function(e){j(t,e)})}catch(n){j(t,n)}}function C(){return rt++}function O(t){t[Z]=rt++,t._state=void 0,t._result=void 0,t._subscribers=[]}function k(){return new Error("Array Methods must be provided an Array")}function F(t){return new ot(this,t).promise}function Y(t){var e=this;return new e(U(t)?function(n,r){for(var o=t.length,i=0;i<o;i++)e.resolve(t[i]).then(n,r)}:function(t,e){return e(new TypeError("You must pass an array to race."))})}function q(t){var e=this,n=new e(p);return j(n,t),n}function D(){throw new TypeError("You must pass a resolver function as the first argument to the promise constructor")}function K(){throw new TypeError("Failed to construct 'Promise': Please use the 'new' operator, this object constructor cannot be called as a function.")}function L(){var t=void 0;if("undefined"!=typeof global)t=global;else if("undefined"!=typeof self)t=self;else try{t=Function("return this")()}catch(e){throw new Error("polyfill failed because global object is unavailable in this environment")}var n=t.Promise;if(n){var r=null;try{r=Object.prototype.toString.call(n.resolve())}catch(e){}if("[object Promise]"===r&&!n.cast)return}t.Promise=it}var N=void 0;N=Array.isArray?Array.isArray:function(t){return"[object Array]"===Object.prototype.toString.call(t)};var U=N,W=0,z=void 0,B=void 0,G=function(t,e){V[W]=t,V[W+1]=e,W+=2,2===W&&(B?B(a):X())},H="undefined"!=typeof window?window:void 0,I=H||{},J=I.MutationObserver||I.WebKitMutationObserver,Q="undefined"==typeof self&&"undefined"!=typeof process&&"[object process]"==={}.toString.call(process),R="undefined"!=typeof Uint8ClampedArray&&"undefined"!=typeof importScripts&&"undefined"!=typeof MessageChannel,V=new Array(1e3),X=void 0;X=Q?o():J?s():R?u():void 0===H&&"function"==typeof require?f():c();var Z=Math.random().toString(36).substring(2),$=void 0,tt=1,et=2,nt={error:null},rt=0,ot=function(){function t(t,e){this._instanceConstructor=t,this.promise=new t(p),this.promise[Z]||O(this.promise),U(e)?(this.length=e.length,this._remaining=e.length,this._result=new Array(this.length),0===this.length?S(this.promise,this._result):(this.length=this.length||0,this._enumerate(e),0===this._remaining&&S(this.promise,this._result))):j(this.promise,k())}return t.prototype._enumerate=function(t){for(var e=0;this._state===$&&e<t.length;e++)this._eachEntry(t[e],e)},t.prototype._eachEntry=function(t,e){var n=this._instanceConstructor,r=n.resolve;if(r===h){var o=_(t);if(o===l&&t._state!==$)this._settledAt(t._state,e,t._result);else if("function"!=typeof o)this._remaining--,this._result[e]=t;else if(n===it){var i=new n(p);w(i,t,o),this._willSettleAt(i,e)}else this._willSettleAt(new n(function(e){return e(t)}),e)}else this._willSettleAt(r(t),e)},t.prototype._settledAt=function(t,e,n){var r=this.promise;r._state===$&&(this._remaining--,t===et?j(r,n):this._result[e]=n),0===this._remaining&&S(r,this._result)},t.prototype._willSettleAt=function(t,e){var n=this;E(t,void 0,function(t){return n._settledAt(tt,e,t)},function(t){return n._settledAt(et,e,t)})},t}(),it=function(){function t(e){this[Z]=C(),this._result=this._state=void 0,this._subscribers=[],p!==e&&("function"!=typeof e&&D(),this instanceof t?x(this,e):K())}return t.prototype["catch"]=function(t){return this.then(null,t)},t.prototype["finally"]=function(t){var e=this,n=e.constructor;return e.then(function(e){return n.resolve(t()).then(function(){return e})},function(e){return n.resolve(t()).then(function(){throw e})})},t}();return it.prototype.then=l,it.all=F,it.race=Y,it.resolve=h,it.reject=q,it._setScheduler=n,it._setAsap=r,it._asap=G,it.polyfill=L,it.Promise=it,it.polyfill(),it});

================================================
FILE: examples/workway-node/www/js/poly/event-targe.js
================================================
/*! (c) 2017 Andrea Giammarchi (ISC) */
var EventTarget=function(){"use strict";var t="object"==typeof global?global:self,e=[].findIndex||function(t,e){for(var n=this.length;n--;)if(t.call(e,this[n]))return n;return n},n=Object.defineProperty,r="__event-target__"+Math.random(),i=t.WeakMap||function(){return{get:function(t){return t[r]},set:function(t,e){n(t,r,{configurable:!0,value:e})}}},a=t.EventTarget;try{new a}catch(o){a=function(){function t(){}function r(t){var e=t.options;e&&e.once&&u.call(t.target,this.type,t.listener,t.options),"function"==typeof t.listener?t.listener.call(t.target,this):t.listener.handleEvent(this)}function a(t){return this===t.listener}function o(t,n,r){var i=f(this),o=i[t]||(i[t]=[]);e.call(o,a,n)<0&&o.push({target:this,listener:n,options:r})}function c(t){var e=f(this),n=e[t.type];return n&&(h(t,{currentTarget:this,target:this}),n.forEach(r,t),delete t.currentTarget,delete t.target),!0}function u(t,n,r){var i=f(this),o=i[t];if(o){var c=e.call(o,a,n);-1<c&&o.splice(c,1)}}function l(){}var s=new i,f=function(t){return s.get(t)||v(t)},v=function(t){var e=new l;return s.set(t,e),e},h=function(t,e){for(var r in e)n(t,r,{configurable:!0,value:e[r]})};return h(t.prototype,{addEventListener:o,dispatchEvent:c,removeEventListener:u}),l.prototype=Object.create(null),t}()}return a}();

================================================
FILE: examples/workway-node/www/js/poly/poorlyfills.js
================================================
"use strict";!function(e){/*! (c) 2017 Andrea Giammarchi @WebReflection, (ISC) */
e.Map=e.Map||function(){var e=void 0,t=void 0,n=void 0,r=function(){t=[],n=[]},u=function(n){return-1<(e=t.indexOf(n))};return r(),{get size(){return t.length},has:u,clear:r,get:function(e){return n[t.indexOf(e)]},keys:function(){return t.slice()},values:function(){return n.slice()},entries:function(){return t.map(function(e,t){return[e,n[t]]})},delete:function(r){return u(r)&&t.splice(e,1)&&!!n.splice(e,1)},forEach:function(e,r){var u=this;n.forEach(function(n,i){return e.call(r,n,t[i],u)})},set:function(r,i){return u(r)?n[e]=i:n[t.push(r)-1]=i,this}}},e.Set=e.Set||function(){var t=new e.Map,n=t.set;return delete t.get,delete t.set,t.add=function(e){return n.call(t,e,e)},t};var t=0,n={}.hasOwnProperty;e.WeakMap=e.WeakMap||function(){var e="__"+[t++,Math.random()],r=function(t){return n.call(t,e)};return{has:r,get:function(t){return t[e]},delete:function(t){return r(t)&&delete t[e]},set:function(t,n){return Object.defineProperty(t,e,{configurable:!0,value:n}),this}}},e.WeakSet=e.WeakSet||function(){var t=new e.WeakMap;return{has:function(e){return!0===t.get(e)},delete:t.delete,add:function(e){return t.set(e,!0),this}}}}(this);

================================================
FILE: examples/workway-promise-reject/README.md
================================================
# Promise reject from Node.js

This demo shows results when a Promise fails.

```sh
npm install
# now open that localhost page
```


================================================
FILE: examples/workway-promise-reject/index.html
================================================
<!doctype html>
<meta name="viewport" content="width=device-width,initial-scale=1">
<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>
<script src="https://unpkg.com/workway"></script>
<script src="/pocket.io/pocket.io.js"></script>
<script src="/workway@node.js"></script>
<script>
workway('node://index.js').then(async ({worker, namespace:foo}) => {
  foo.fooPromisified("unused")
    .then(res => console.log("then", res))
    .catch(err => console.log("catch", err));
});
</script>


================================================
FILE: examples/workway-promise-reject/index.js
================================================
var PORT = process.env.PORT || 3000;

var path = require('path');
var express = require('express');
var workway = require('workway/node').authorize(
  path.resolve(__dirname, 'workers')
);

var app = workway.app(express());
app.get('/', function (req, res) {
  res.writeHead(200, 'OK', {
    'Content-Type': 'text/html; charset=utf-8'
  });
  res.end(require('fs').readFileSync(path.resolve(__dirname, 'index.html')));
});
app.listen(PORT, () => {
  console.log('listening on http://localhost:' + PORT);
});


================================================
FILE: examples/workway-promise-reject/package.json
================================================
{
  "name": "workway-demo",
  "private": true,
  "dependencies": {
    "express": "^4.16.3",
    "workway": "^0.5.2"
  },
  "scripts": {
    "start": "node index.js",
    "postinstall": "npm start"
  },
  "author": "Andrea Giammarchi",
  "license": "ISC"
}


================================================
FILE: examples/workway-promise-reject/workers/index.js
================================================
const util = require('util');

const workway = require('workway');

function foo(message, callback) {
    callback(42); // forcing always an error
}

const fooPromisified = util.promisify(foo);

workway({
    fooPromisified
});


================================================
FILE: index.js
================================================
function workway(file) {'use strict';
  /*! (c) 2018 Andrea Giammarchi (ISC) */
  return new Promise(function (res) {
    function uid() { return ++i + Math.random(); }
    var i = 0;
    var channel = uid();
    var messages = {};
    var worker = typeof file === 'string' ? new Worker(file) : file;
    worker.addEventListener('message', function (event) {
      if (event.data.channel !== channel) return;
      event.stopImmediatePropagation();
      var namespace = event.data.namespace;
      if (namespace) {
        var Class = function (info) {
          var path = info.path;
          var methods = info.methods;
          var statics = info.statics;
          var wm = new WeakMap;
          function RemoteClass() { wm.set(this, uid()); }
          methods.forEach(function (method) {
            RemoteClass.prototype[method] = function () {
              return send({
                args: slice.call(arguments),
                path: path,
                method: method,
                object: {
                  id: wm.get(this),
                  value: this
                }
              });
            };
          });
          statics.methods.forEach(function (method) {
            RemoteClass[method] = function () {
              return send({
                args: slice.call(arguments),
                path: path,
                method: method
              });
            };
          });
          statics.values.forEach(function (pair) {
            RemoteClass[pair[0]] = pair[1];
          });
          return RemoteClass;
        };
        var callback = function (path) {
          return function remoteCallback() {
            return send({
              args: slice.call(arguments),
              path: path
            });
          };
        };
        var send = function (message) {
          var resolve, reject;
          var promise = new Promise(function (res, rej) {
            resolve = res;
            reject = rej;
          });
          promise.resolve = resolve;
          promise.reject = reject;
          messages[message.id = uid()] = promise;
          worker.postMessage({
            channel: channel,
            message: message
          });
          return promise;
        };
        var slice = [].slice;
        (function update(namespace) {
          Object.keys(namespace).forEach(function (key) {
            var info = namespace[key];
            switch (info.type) {
              case 'class': namespace[key] = Class(info); break;
              case 'function': namespace[key] = callback(info.path); break;
              case 'object': update(namespace[key] = info.value); break;
              default: namespace[key] = info.value;
            }
          });
        }(namespace));
        res({
          worker: worker,
          namespace: namespace
        });
      } else {
        var message = event.data.message;
        var id = message.id;
        var promise = messages[id];
        delete messages[id];
        if (message.hasOwnProperty('error')) {
          var error, facade = message.error;
          if (facade.hasOwnProperty('source'))
            error = facade.source;
          else {
            error = new Error(facade.message);
            error.stack = facade.stack;
          }
          promise.reject(error);
        }
        else
          promise.resolve(message.result);
      }
    });
    worker.postMessage({channel: channel});
  });
}


================================================
FILE: min.js
================================================
function workway(t){"use strict";
/*! (c) 2018 Andrea Giammarchi (ISC) */return new Promise(function(u){function f(){return++e+Math.random()}var e=0,h=f(),l={},p="string"==typeof t?new Worker(t):t;p.addEventListener("message",function(e){if(e.data.channel===h){e.stopImmediatePropagation();var t=e.data.namespace;if(t){var o=function(e){var a,r,t=new Promise(function(e,t){a=e,r=t});return t.resolve=a,t.reject=r,l[e.id=f()]=t,p.postMessage({channel:h,message:e}),t},c=[].slice;!function a(r){Object.keys(r).forEach(function(e){var t=r[e];switch(t.type){case"class":r[e]=function(e){var t=e.path,a=e.methods,r=e.statics,n=new WeakMap;function s(){n.set(this,f())}return a.forEach(function(e){s.prototype[e]=function(){return o({args:c.call(arguments),path:t,method:e,object:{id:n.get(this),value:this}})}}),r.methods.forEach(function(e){s[e]=function(){return o({args:c.call(arguments),path:t,method:e})}}),r.values.forEach(function(e){s[e[0]]=e[1]}),s}(t);break;case"function":r[e]=function(e){return function(){return o({args:c.call(arguments),path:e})}}(t.path);break;case"object":a(r[e]=t.value);break;default:r[e]=t.value}})}(t),u({worker:p,namespace:t})}else{var a=e.data.message,r=a.id,n=l[r];if(delete l[r],a.hasOwnProperty("error")){var s,i=a.error;i.hasOwnProperty("source")?s=i.source:(s=new Error(i.message)).stack=i.stack,n.reject(s)}else n.resolve(a.result)}}}),p.postMessage({channel:h})})}

================================================
FILE: node/client.js
================================================
window.workway = (function (Worker, workway, SECRET) {

  /*! Copyright 2018 Andrea Giammarchi - @WebReflection
   *
   * Permission to use, copy, modify, and/or distribute this software
   * for any purpose with or without fee is hereby granted,
   * provided that the above copyright notice
   * and this permission notice appear in all copies.
   * 
   * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS
   * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING
   * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
   * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL,
   * DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR
   * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
   * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
   * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
   * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
   */

  // ${JSON}

  var instances = [];
  var sockets = new WeakMap();

  addEventListener(
    'beforeunload',
    function () {
      while (instances.length) instances[0].terminate();
    },
    false
  );

  function NodeWorker(ep) {
    var socket = io({JSON: Flatted});
    var self = new EventTarget;
    self.postMessage = this.postMessage;
    self.terminate = this.terminate;
    instances.push(self);
    sockets.set(self, socket);
    socket.on(SECRET + ':error', this.onerror.bind(self));
    socket.on(SECRET + ':message', this.onmessage.bind(self));
    socket.emit(SECRET + ':setup', ep);
    return self;
  }

  function createEvent(type) {
    var event = document.createEvent('Event');
    event.initEvent(type, false, true);
    event.stopImmediatePropagation = event.stopImmediatePropagation ||
                                      event.stopPropagation;
    return event;
  }

  NodeWorker.prototype = {

    onerror: function (error) {
      var event = createEvent('error');
      event.message = error.message;
      event.stack = error.stack;
      this.dispatchEvent(event);
      if (this.onerror) this.onerror(event);
    },

    onmessage: function (data) {
      var event = createEvent('message');
      event.data = data;
      this.dispatchEvent(event);
      if (this.onmessage) this.onmessage(event);
    },

    postMessage: function (message) {
      sockets.get(this).emit(SECRET, message);
    },

    terminate: function () {
      instances.splice(instances.indexOf(this), 1);
      sockets.get(this).disconnect();
    }

  };

  return function (file) {
    if (/^node:\/\/([\w._-]+)/.test(file)) {
      file = RegExp.$1;
      window.Worker = NodeWorker;
      var promise = workway(file);
      window.Worker = Worker;
      return promise;
    } else
      return workway(file);
  };

}(Worker, workway, '${SECRET}'));


================================================
FILE: node/index.js
================================================
"use strict";

// used core modules
var EventEmitter = require('events').EventEmitter;
var crypto = require('crypto');
var fs = require('fs');
var http = require('http');
var path = require('path');
var vm = require('vm');

// extra dependencies
var Flatted = require('flatted');
var pocketIO = require('pocket.io');
var workerjs = fs.readFileSync(
  path.resolve(__dirname, '..', 'worker.js')
).toString();

// used as communication channel
var SECRET = crypto.randomBytes(32).toString('hex');

// the client side is enriched at runtime
var jsContent = fs.readFileSync(path.join(__dirname, 'client.js'))
                  .toString()
                  .replace(
                    /\$\{(SECRET|JSON)\}/g,
                    function ($0, $1) { return this[$1]; }.bind({
                      SECRET: SECRET,
                      JSON: fs.readFileSync(require.resolve('flatted/min.js')).toString()
                    })
                  );

var workers = '';

process.on('unhandledRejection', uncaught);
process.on('uncaughtException', uncaught);

// return a new Worker sandbox
function createSandbox(filename, socket) {
  var self = new EventEmitter;
  var listeners = new WeakMap;
  self.addEventListener = function (type, listener) {
    if (!listeners.has(listener)) {
      var facade = function (event) {
        if (!event.canceled) listener.apply(this, arguments);
      };
      listeners.set(listener, facade);
      self.on(type, facade);
    }
  };
  self.removeEventListener = function (type, listener) {
    self.removeListener(type, listeners.get(listener));
  };
  self.__filename = filename;
  self.__dirname = path.dirname(filename);
  self.postMessage = function postMessage(data) { message(socket, data); };
  self.console = console;
  self.process = process;
  self.Buffer = Buffer;
  self.clearImmediate = clearImmediate;
  self.clearInterval = clearInterval;
  self.clearTimeout = clearTimeout;
  self.setImmediate = setImmediate;
  self.setInterval = setInterval;
  self.setTimeout = setTimeout;
  self.module = module;
  self.global = self;
  self.self = self;
  self.require = function (file) {
    switch (true) {
      case file === 'workway':
        return self.workway;
      case /^[./]/.test(file):
        file = path.resolve(self.__dirname, file);
      default:
        return require(file);
    }
  };
  return self;
}

function cleanedStack(stack) {
  return ''.replace.call(stack, /:uid-\d+-[a-f0-9]{16}/g, '');
}

// notify the socket there was an error
function error(socket, err) {
  socket.emit(SECRET + ':error', {
    message: err.message,
    stack: cleanedStack(err.stack)
  });
}

// send serialized data to the client
function message(socket, data) {
  socket.emit(SECRET + ':message', data);
}

// used to send /node-worker.js client file
function responder(request, response, next) {
  response.writeHead(200, 'OK', {
    'Content-Type': 'application/javascript'
  });
  response.end(jsContent);
  if (next) next();
}

uid.i = 0;
uid.map = Object.create(null);
uid.delete = function (sandbox) {
  Object.keys(uid.map).some(function (key) {
    var found = uid.map[key] === sandbox;
    if (found) delete uid.map[key];
    return found;
  });
};

function uid(filename, socket) {
  var id = filename + ':uid-'.concat(++uid.i, '-', crypto.randomBytes(8).toString('hex'));
  uid.map[id] = socket;
  return id;
}

function uncaught(err) {
  console.error(err);
  if (/([\S]+?(:uid-\d+-[a-f0-9]{16}))/.test(err.stack)) {
    var socket = uid.map[RegExp.$1];
    if (socket) error(socket, err);
  }
}

function Event(data) {
  this.canceled = false;
  this.data = data;
}

Event.prototype.stopImmediatePropagation = function () {
  this.canceled = true;
};

module.exports = {
  authorize: function (folder) {
    if (workers.length) throw new Error('workway already authorized');
    workers = folder;
    return this;
  },
  app: function (app) {
    var io;
    var native = app instanceof http.Server;
    if (native) {
      io = pocketIO(app, {JSON: Flatted});
      var request = app._events.request;
      app._events.request = function (req) {
        return /^\/workway@node\.js(?:\?|$)/.test(req.url) ?
          responder.apply(this, arguments) :
          request.apply(this, arguments);
      };
    } else {
      var wrap = http.Server(app);
      io = pocketIO(wrap, {JSON: Flatted});
      app.get('/workway@node.js', responder);
      Object.defineProperty(app, 'listen', {
        configurable: true,
        value: function () {
          wrap.listen.apply(wrap, arguments);
          return app;
        }
      });
    }
    io.on('connection', function (socket) {
      var sandbox;
      var queue = [];
      function message(data) {
        if (sandbox) {
          try {
            var event = new Event(data);
            sandbox.emit('message', event);
            if ('onmessage' in sandbox && !event.canceled) {
              sandbox.onmessage(event);
            }
          } catch(err) {
            error(socket, err);
          }
        }
        else queue.push(data);
      }
      socket.on(SECRET, message);
      socket.on(SECRET + ':setup', function (worker) {
        var filename = path.resolve(path.join(workers, worker));
        if (filename.indexOf(workers)) {
          error(socket, {
            message: 'Unauthorized worker: ' + worker,
            stack: ''
          });
        } else {
          fs.readFile(filename, function (err, content) {
            if (err) {
              error(socket, {
                message: 'Worker not found: ' + worker,
                stack: err.stack
              });
            } else {
              sandbox = createSandbox(filename, socket);
              vm.createContext(sandbox);
              vm.runInContext(workerjs, sandbox);
              vm.runInContext(content, sandbox, {
                filename: uid(worker, socket),
                displayErrors: true
              });
              while (queue.length) {
                setTimeout(message, queue.length * 100, queue.pop());
              }
            }
          });
        }
      });
      socket.on('disconnect', function () {
        uid.delete(socket);
        sandbox = null;
      });
    });
    return app;
  }
};


================================================
FILE: package.json
================================================
{
  "name": "workway",
  "version": "0.5.5",
  "description": "A general purpose, Web Worker driven, remote namespace with classes and methods.",
  "unpkg": "min.js",
  "main": "cjs/index.js",
  "module": "esm/index.js",
  "scripts": {
    "$": "npm-dollar",
    "build": "npm-dollar build",
    "bundle": "npm-dollar bundle",
    "size": "npm-dollar size",
    "test": "npm-dollar test"
  },
  "$": {
    "build": [
      "$ remoted",
      "$ bundle",
      "$ test",
      "$ size"
    ],
    "bundle": {
      "cjs": [
        "cp index.js cjs/",
        "echo 'module.exports = workway;' >> cjs/index.js"
      ],
      "esm": [
        "cp index.js esm/",
        "echo 'export default workway;' >> esm/index.js"
      ],
      "min": "uglifyjs index.js --comments=/^!/ -m -c -o min.js",
      "node": [
        [
          "node -e 'fs.writeFileSync(\"worker.js\",",
          "fs.readFileSync(\"partial/worker.js\").toString().replace(/^(\\s*)\\/\\/js:(\\w+)/gm,",
          "(o,s,k)=>fs.readFileSync(k+\".js\").toString().trim().replace(/^/gm,s)))'"
        ]
      ]
    },
    "remoted": {
      "cjs": [
        "cp remoted.js cjs/",
        "echo 'module.exports = remoted;' >> cjs/remoted.js"
      ],
      "esm": [
        "cp remoted.js esm/",
        "echo 'export default remoted;' >> esm/remoted.js"
      ]
    },
    "size": [
      [
        "cat index.js |",
        "wc -c;cat min.js |",
        "wc -c;gzip -c9 min.js |",
        "wc -c;cat min.js |",
        "brotli |",
        "wc -c && rm -f min.js.br"
      ]
    ],
    "test": [
      "cd test",
      "node index.js",
      "echo $(tput bold)OK$(tput sgr0)"
    ]
  },
  "author": "Andrea Giammarchi",
  "license": "ISC",
  "devDependencies": {
    "express": "^4.17.1",
    "npm-dollar": "^2.2.1",
    "uglify-js": "^3.6.0"
  },
  "repository": {
    "type": "git",
    "url": "git+https://github.com/WebReflection/workway.git"
  },
  "keywords": [
    "web",
    "worker",
    "remote",
    "namespace",
    "driven"
  ],
  "bugs": {
    "url": "https://github.com/WebReflection/workway/issues"
  },
  "homepage": "https://github.com/WebReflection/workway#readme",
  "dependencies": {
    "flatted": "^2.0.0",
    "pocket.io": "^0.1.4"
  }
}


================================================
FILE: partial/worker.js
================================================
(function () {'use strict';
  /*! (c) 2018 Andrea Giammarchi (ISC) */
  function walkThrough(O, K) { return O[K]; }
  var namespace;
  var channels = {};
  var instances = {};
  var onceExposed = new Promise(function (resolve) {
    self.workway = function workway(exposed) {
      return Promise.resolve(exposed).then(function (result) {
        namespace = result;
        resolve(remoted(result));
      });
    };
    //js:remoted
  });
  self.addEventListener('message', function (event) {
    var method;
    var data = event.data;
    var channel = data.channel;
    var message = data.message;
    if (channels[channel]) {
      event.stopImmediatePropagation();
      var id = message.id;
      var path = message.path;
      var args = message.args;
      var resolved = function (result) { send({result: result}); };
      var rejected = function (error) {
        if (
          error != null &&
          typeof error === 'object' &&
          'message' in error
        )
          send({error: {
            stack: error.stack,
            message: error.message
          }});
        else
          send({error: {source: error}});
      };
      var send = function (message) {
        message.id = id;
        self.postMessage({
          channel: channel,
          message: message
        });
      };
      try {
        if (message.hasOwnProperty('method')) {
          method = message.method;
          var Class = path.reduce(walkThrough, namespace);
          if (!Class)
            return rejected('Unknown Class ' + path.join('.'));
          if (message.hasOwnProperty('object')) {
            var object = message.object;
            var instance = instances[object.id] ||
                            (instances[object.id] = new Class);
            if (method === 'destroy')
              delete instances[object.id];
            else {
              Object.keys(object.value)
                    .forEach(function (key) {
                      instance[key] = object.value[key];
                    });
              Promise.resolve(instance[method].apply(instance, args))
                      .then(resolved, rejected);
            }
          } else {
            Promise.resolve(Class[method].apply(Class, args))
                    .then(resolved, rejected);
          }
        } else {
          var context = path.slice(0, -1).reduce(walkThrough, namespace);
          if (!context)
            return rejected('Unknown namespace ' + path.slice(0, -1).join('.'));
          method = path[path.length - 1];
          if (typeof context[method] !== 'function')
            return rejected('Unknown method ' + path.join('.'));
          Promise.resolve(context[method].apply(context, args))
                  .then(resolved, rejected);
        }
      } catch(error) {
        rejected(error);
      }
    } else if (/^(-?\d+\.\d+)$/.test(channel)) {
      channels[channel] = true;
      event.stopImmediatePropagation();
      onceExposed.then(function (namespace) {
        self.postMessage({
          channel: channel,
          namespace: namespace
        });
      });
    }
  });
}());


================================================
FILE: remoted.js
================================================
function remoted(object) {
  return function $(object, current, remote) {
    Object.keys(object).forEach(function (key) {
      var value = object[key];
      var path = current.concat(key);
      if (typeof value === 'function') {
        remote[key] = /^[A-Z]/.test(key) ?
          {
            type: 'class',
            path: path,
            methods: Object.getOwnPropertyNames(value.prototype)
                            .filter(no(['constructor']))
                            .concat('destroy'),
            statics: Object.getOwnPropertyNames(value)
                            .filter(no([
                              'arguments', 'callee', 'caller',
                              'length', 'name', 'prototype'
                            ]))
                            .reduce(
                              function (info, key) {
                                if (typeof value[key] === 'function') {
                                  info.methods.push(key);
                                } else {
                                  info.values.push([key, value[key]]);
                                }
                                return info;
                              },
                              {
                                methods: [],
                                values: []
                              }
                            )
          } :
          {
            type: 'function',
            path: path
          };
      } else if (remote.toString.call(value) === '[object Object]') {
        remote[key] = {
          type: 'object',
          path: path,
          value: {}
        };
        $(value, path, remote[key].value);
      } else if (value !== void 0) {
        remote[key] = {
          type: 'any',
          path: path,
          value: value
        };
      }
    });
    return remote;
  }(object, [], {});
  function no(within) {
    return function (what) {
      return within.indexOf(what) < 0;
    };
  }
}


================================================
FILE: test/background.js
================================================
// a Blackberry gotcha, no console in workers
if (!self.console) self.console = {log: function () {}, error: function () {}};
// import the polyfill you prefer for 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');

// to avoid any possible issue with messages
// import the remote utility n the top of your worker
importScripts('../worker.js');

// ES2015 classes would work too
// ( not using class for IE11 tests )
function Test() {}
Test.method = function () {
  console.log('Test.method');
  console.log('arguments', [].slice.call(arguments));
  return Math.random();
};
Test.prototype.method = function () {
  console.log('Test.prototype.method');
  console.log('instance', JSON.stringify(this));
  console.log('arguments', [].slice.call(arguments));
  return Math.random();
};

// expose a namespace with serializable data
// but also classes and utilities as methods/functions
workway({
  test: 123,
  array: [1, 2, 3],
  object: {a: 'a'},
  nested: {
    method: function () {
      console.log('method');
      console.log('arguments', [].slice.call(arguments));
      return Math.random();
    },
    Test: Test
  }
});

// you can regularly post any sort of message, or listen
// to anything you want to
self.addEventListener('message', function (event) {
  console.log(event.type, event.data);
  if (event.data.hasOwnProperty('echo'))
    self.postMessage(event.data.echo);
});


================================================
FILE: test/circular/analyzer.js
================================================
importScripts('https://unpkg.com/workway/worker.js');

workway({
  analyze(circular) {
    return circular;
  }
});


================================================
FILE: test/circular/index.html
================================================
<!doctype html>
<meta name="viewport" content="width=device-width,initial-scale=1">
<script type="module">
import workway from 'https://unpkg.com/workway/esm';

workway('analyzer.js').then(({namespace}) => {
  const data = {arr: []};
  data.arr.push(data);
  data.data = data;
  namespace.analyze(data)
            .then(
              data => {
                if (
                  data &&
                  data.arr &&
                  data.arr[0] === data &&
                  data.arr.length === 1 &&
                  data.data === data
                )
                  document.body.textContent = 'it works 🎉';
                else
                  throw new Error('unable to solve recursion');
              },
              console.error
            );
});
</script>


================================================
FILE: test/client.js
================================================
workway('./background.js').then(function (info) {
  // {worker, namespace}
  var worker = info.worker;
  var namespace = info.namespace;

  // you can either use addEventListener
  // or onmessage and onerror and
  // these will never receive remote events,
  // only user messages, and same goes if you post messages
  // the remote logic won't ever be affected
  worker.onmessage = function (event) { showData(event.data); };
  worker.addEventListener('message', console.log.bind(console));

  // you can also send regular messages
  // without affecting namespace operations
  worker.postMessage({echo: 'hello remote'});

  // classes can have static methods
  // static values, and regular prototypal methods
  // however there are few limitations such inheritance
  // and constructor arguments, which is always, and only
  // the unique identifier used to pair local/remote instances
  var instance = new namespace.nested.Test;

  // properties can be added, as long as these are serializable
  instance.test = Math.random();

  // and every method of the class returns a Promise
  // that will resolve once the instance has been updated
  // (properties) and the method invoked,
  // with serializable arguments
  instance.method(1, 2, 3)
          .then(showData, console.error.bind(console))
          .then(function () { instance.destroy(); });

  function showData(data) {
    document.body.appendChild(
      document.createElement('pre')
    ).textContent = JSON.stringify(data, null, '  ');
  }

});


================================================
FILE: test/foo.html
================================================
<!doctype html>
<meta name="viewport" content="width=device-width,initial-scale=1">
<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>
<script src="/workway.js"></script>
<script src="/pocket.io/pocket.io.js"></script>
<script src="/workway@node.js"></script>
<script>
workway('node://foo.js').then(async ({worker, namespace:foo}) => {
  foo.fooPromisified("unused")
    .then(console.info, console.error);
});
</script>

================================================
FILE: test/foo.js
================================================
var PORT = process.env.PORT || 3000;

var path = require('path');
var express = require('express');
var workway = require('../node').authorize(
  path.resolve(__dirname, 'workers')
);

var app = workway.app(express());
app.get('/', function (req, res) {
  res.writeHead(200, 'OK', {
    'Content-Type': 'text/html; charset=utf-8'
  });
  res.end(require('fs').readFileSync(path.resolve(__dirname, 'foo.html')));
});
app.get('/workway.js', function (req, res) {
  res.writeHead(200, 'OK', {
    'Content-Type': 'application/javascript; charset=utf-8'
  });
  res.end(require('fs').readFileSync(path.resolve(__dirname, '..', 'min.js')));
});
app.listen(PORT, () => {
  console.log('listening on http://localhost:' + PORT);
});


================================================
FILE: test/index.html
================================================
<!doctype html>
<meta name="viewport" content="width=device-width,initial-scale=1">
<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>');
</script>
<script src="../index.js"></script>
<script src="./client.js"></script>


================================================
FILE: test/index.js
================================================
require('./webworker');
global.workway = require('../cjs/index');
require('./client');


================================================
FILE: test/node.html
================================================
<!doctype html>
<meta name="viewport" content="width=device-width,initial-scale=1">
<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>
<script src="/workway.js"></script>
<script src="/pocket.io/pocket.io.js"></script>
<script src="/workway@node.js"></script>
<script>
// handy protocol to differentiate between client-side workers
// and NodeJS driven workers (must be authorized on nodejs side)
workway('node://test.js').then(({worker, namespace}) => {
  // workers have regular methods
  worker.addEventListener('message', event => {
    console.info(event.data);
  });
  worker.addEventListener('error', event => {
    console.error(event.message);
    console.error(event.stack);
  });
  // here I have exported require('os') directly
  namespace.os.platform().then(console.log);
  // but also some other custom method
  namespace.ping();
  // workers on the NodeJS side can listen too
  worker.postMessage('hello from the Web');
});
</script>

================================================
FILE: test/node.js
================================================
var PORT = process.env.PORT || 3000;

var path = require('path');
var express = require('express');
var workway = require('../node').authorize(
  path.resolve(__dirname, 'workers')
);

var app = workway.app(express());
app.get('/', function (req, res) {
  res.writeHead(200, 'OK', {
    'Content-Type': 'text/html; charset=utf-8'
  });
  res.end(require('fs').readFileSync(path.resolve(__dirname, 'node.html')));
});
app.get('/workway.js', function (req, res) {
  res.writeHead(200, 'OK', {
    'Content-Type': 'application/javascript; charset=utf-8'
  });
  res.end(require('fs').readFileSync(path.resolve(__dirname, '..', 'index.js')));
});
app.listen(PORT, () => {
  console.log('listening on http://localhost:' + PORT);
});


================================================
FILE: test/webworker.js
================================================
const workers = [];

class Event {
  constructor(data) {
    this._stopImmediatePropagation = false;
    this.type = 'message';
    this.data = data;
  }
  stopImmediatePropagation() {
    this._stopImmediatePropagation = true;
  }
}

global.Worker = class Worker extends require('events').EventEmitter {
  constructor(file) {
    workers.push(super());
    require(file);
  }
  addEventListener(type, listener) {
    this.on(type, listener);
  }
  postMessage(data) {
    process.emit('message', new Event(data));
  }
};

global.document = {
  body: {
    appendChild: Object
  },
  createElement() {
    return {set textContent(value) {
      console.log(value);
    }};
  }
};
global.importScripts = require;
global.self = new Proxy(
  {
    addEventListener(type, listener) {
      process.on(type, listener);
    },
    postMessage(data) {
      workers.forEach(worker => worker.emit('message', new Event(data)));
    }
  },
  {
    get: (self, key) => self[key] || global[key],
    set: (self, key, value) => {
      global[key] = value;
      return true;
    }
  }
);


================================================
FILE: test/workers/foo.js
================================================
const util = require('util');

const workway = require('workway');

function foo(message, callback) {
    callback(42); // forcing always an error
}

const fooPromisified = util.promisify(foo);

workway({
    fooPromisified
});

================================================
FILE: test/workers/other.js
================================================
console.log(__filename);


================================================
FILE: test/workers/test.js
================================================
var workway = require('workway');

// require('./other');

workway({
  os: require('os'),
  ping: function () {
    self.postMessage('pong');
  }
});

self.addEventListener('message', function (event) {
  console.log(event.data);
});


================================================
FILE: worker.js
================================================
(function () {'use strict';
  /*! (c) 2018 Andrea Giammarchi (ISC) */
  function walkThrough(O, K) { return O[K]; }
  var namespace;
  var channels = {};
  var instances = {};
  var onceExposed = new Promise(function (resolve) {
    self.workway = function workway(exposed) {
      return Promise.resolve(exposed).then(function (result) {
        namespace = result;
        resolve(remoted(result));
      });
    };
    function remoted(object) {
      return function $(object, current, remote) {
        Object.keys(object).forEach(function (key) {
          var value = object[key];
          var path = current.concat(key);
          if (typeof value === 'function') {
            remote[key] = /^[A-Z]/.test(key) ?
              {
                type: 'class',
                path: path,
                methods: Object.getOwnPropertyNames(value.prototype)
                                .filter(no(['constructor']))
                                .concat('destroy'),
                statics: Object.getOwnPropertyNames(value)
                                .filter(no([
                                  'arguments', 'callee', 'caller',
                                  'length', 'name', 'prototype'
                                ]))
                                .reduce(
                                  function (info, key) {
                                    if (typeof value[key] === 'function') {
                                      info.methods.push(key);
                                    } else {
                                      info.values.push([key, value[key]]);
                                    }
                                    return info;
                                  },
                                  {
                                    methods: [],
                                    values: []
                                  }
                                )
              } :
              {
                type: 'function',
                path: path
              };
          } else if (remote.toString.call(value) === '[object Object]') {
            remote[key] = {
              type: 'object',
              path: path,
              value: {}
            };
            $(value, path, remote[key].value);
          } else if (value !== void 0) {
            remote[key] = {
              type: 'any',
              path: path,
              value: value
            };
          }
        });
        return remote;
      }(object, [], {});
      function no(within) {
        return function (what) {
          return within.indexOf(what) < 0;
        };
      }
    }
  });
  self.addEventListener('message', function (event) {
    var method;
    var data = event.data;
    var channel = data.channel;
    var message = data.message;
    if (channels[channel]) {
      event.stopImmediatePropagation();
      var id = message.id;
      var path = message.path;
      var args = message.args;
      var resolved = function (result) { send({result: result}); };
      var rejected = function (error) {
        if (
          error != null &&
          typeof error === 'object' &&
          'message' in error
        )
          send({error: {
            stack: error.stack,
            message: error.message
          }});
        else
          send({error: {source: error}});
      };
      var send = function (message) {
        message.id = id;
        self.postMessage({
          channel: channel,
          message: message
        });
      };
      try {
        if (message.hasOwnProperty('method')) {
          method = message.method;
          var Class = path.reduce(walkThrough, namespace);
          if (!Class)
            return rejected('Unknown Class ' + path.join('.'));
          if (message.hasOwnProperty('object')) {
            var object = message.object;
            var instance = instances[object.id] ||
                            (instances[object.id] = new Class);
            if (method === 'destroy')
              delete instances[object.id];
            else {
              Object.keys(object.value)
                    .forEach(function (key) {
                      instance[key] = object.value[key];
                    });
              Promise.resolve(instance[method].apply(instance, args))
                      .then(resolved, rejected);
            }
          } else {
            Promise.resolve(Class[method].apply(Class, args))
                    .then(resolved, rejected);
          }
        } else {
          var context = path.slice(0, -1).reduce(walkThrough, namespace);
          if (!context)
            return rejected('Unknown namespace ' + path.slice(0, -1).join('.'));
          method = path[path.length - 1];
          if (typeof context[method] !== 'function')
            return rejected('Unknown method ' + path.join('.'));
          Promise.resolve(context[method].apply(context, args))
                  .then(resolved, rejected);
        }
      } catch(error) {
        rejected(error);
      }
    } else if (/^(-?\d+\.\d+)$/.test(channel)) {
      channels[channel] = true;
      event.stopImmediatePropagation();
      onceExposed.then(function (namespace) {
        self.postMessage({
          channel: channel,
          namespace: namespace
        });
      });
    }
  });
}());
Download .txt
gitextract_vwqyj7po/

├── .gitignore
├── .npmignore
├── .travis.yml
├── LICENSE
├── README.md
├── cjs/
│   ├── index.js
│   └── remoted.js
├── esm/
│   ├── index.js
│   └── remoted.js
├── examples/
│   ├── workway-node/
│   │   ├── README.md
│   │   ├── index.js
│   │   ├── package.json
│   │   ├── workers/
│   │   │   └── os.js
│   │   └── www/
│   │       ├── index.html
│   │       └── js/
│   │           ├── 3rd/
│   │           │   ├── hyperhtml.js
│   │           │   └── workway.js
│   │           ├── index.js
│   │           └── poly/
│   │               ├── es6-promise.js
│   │               ├── event-targe.js
│   │               └── poorlyfills.js
│   └── workway-promise-reject/
│       ├── README.md
│       ├── index.html
│       ├── index.js
│       ├── package.json
│       └── workers/
│           └── index.js
├── index.js
├── min.js
├── node/
│   ├── client.js
│   └── index.js
├── package.json
├── partial/
│   └── worker.js
├── remoted.js
├── test/
│   ├── background.js
│   ├── circular/
│   │   ├── analyzer.js
│   │   └── index.html
│   ├── client.js
│   ├── foo.html
│   ├── foo.js
│   ├── index.html
│   ├── index.js
│   ├── node.html
│   ├── node.js
│   ├── webworker.js
│   └── workers/
│       ├── foo.js
│       ├── other.js
│       └── test.js
└── worker.js
Download .txt
SYMBOL INDEX (93 symbols across 23 files)

FILE: cjs/index.js
  function workway (line 1) | function workway(file) {'use strict';

FILE: cjs/remoted.js
  function remoted (line 1) | function remoted(object) {

FILE: esm/index.js
  function workway (line 1) | function workway(file) {'use strict';

FILE: esm/remoted.js
  function remoted (line 1) | function remoted(object) {

FILE: examples/workway-node/www/js/3rd/hyperhtml.js
  function g (line 1) | function g(){return this}
  function ee (line 1) | function ee(e){this.childNodes=e,this.length=e.length,this.first=e[0],th...
  function he (line 1) | function he(){}
  function Ae (line 1) | function Ae(e){var t=Ce.get(this);return t&&t.template===Q(e)?Se.apply(t...
  function Se (line 1) | function Se(){for(var e=arguments.length,t=1;t<e;t++)this[t-1](arguments...
  function _e (line 1) | function _e(e){return arguments.length<2?null==e?Pe("html"):"string"==ty...

FILE: examples/workway-node/www/js/3rd/workway.js
  function workway (line 1) | function workway(a){"use strict";

FILE: examples/workway-node/www/js/index.js
  function grabAndShow (line 6) | function grabAndShow() {
  function render (line 13) | function render([freemem, totalmem]) {

FILE: examples/workway-node/www/js/poly/es6-promise.js
  function t (line 1) | function t(t){var e=typeof t;return null!==t&&("object"===e||"function"=...
  function e (line 1) | function e(t){return"function"==typeof t}
  function n (line 1) | function n(t){B=t}
  function r (line 1) | function r(t){G=t}
  function o (line 1) | function o(){return function(){return process.nextTick(a)}}
  function i (line 1) | function i(){return"undefined"!=typeof z?function(){z(a)}:c()}
  function s (line 1) | function s(){var t=0,e=new J(a),n=document.createTextNode("");return e.o...
  function u (line 1) | function u(){var t=new MessageChannel;return t.port1.onmessage=a,functio...
  function c (line 1) | function c(){var t=setTimeout;return function(){return t(a,1)}}
  function a (line 1) | function a(){for(var t=0;t<W;t+=2){var e=V[t],n=V[t+1];e(n),V[t]=void 0,...
  function f (line 1) | function f(){try{var t=Function("return this")().require("vertx");return...
  function l (line 1) | function l(t,e){var n=this,r=new this.constructor(p);void 0===r[Z]&&O(r)...
  function h (line 1) | function h(t){var e=this;if(t&&"object"==typeof t&&t.constructor===e)ret...
  function p (line 1) | function p(){}
  function v (line 1) | function v(){return new TypeError("You cannot resolve a promise with its...
  function d (line 1) | function d(){return new TypeError("A promises callback cannot return tha...
  function _ (line 1) | function _(t){try{return t.then}catch(e){return nt.error=e,nt}}
  function y (line 1) | function y(t,e,n,r){try{t.call(e,n,r)}catch(o){return o}}
  function m (line 1) | function m(t,e,n){G(function(t){var r=!1,o=y(n,e,function(n){r||(r=!0,e!...
  function b (line 1) | function b(t,e){e._state===tt?S(t,e._result):e._state===et?j(t,e._result...
  function w (line 1) | function w(t,n,r){n.constructor===t.constructor&&r===l&&n.constructor.re...
  function g (line 1) | function g(e,n){e===n?j(e,v()):t(n)?w(e,n,_(n)):S(e,n)}
  function A (line 1) | function A(t){t._onerror&&t._onerror(t._result),T(t)}
  function S (line 1) | function S(t,e){t._state===$&&(t._result=e,t._state=tt,0!==t._subscriber...
  function j (line 1) | function j(t,e){t._state===$&&(t._state=et,t._result=e,G(A,t))}
  function E (line 1) | function E(t,e,n,r){var o=t._subscribers,i=o.length;t._onerror=null,o[i]...
  function T (line 1) | function T(t){var e=t._subscribers,n=t._state;if(0!==e.length){for(var r...
  function M (line 1) | function M(t,e){try{return t(e)}catch(n){return nt.error=n,nt}}
  function P (line 1) | function P(t,n,r,o){var i=e(r),s=void 0,u=void 0,c=void 0,a=void 0;if(i)...
  function x (line 1) | function x(t,e){try{e(function(e){g(t,e)},function(e){j(t,e)})}catch(n){...
  function C (line 1) | function C(){return rt++}
  function O (line 1) | function O(t){t[Z]=rt++,t._state=void 0,t._result=void 0,t._subscribers=[]}
  function k (line 1) | function k(){return new Error("Array Methods must be provided an Array")}
  function F (line 1) | function F(t){return new ot(this,t).promise}
  function Y (line 1) | function Y(t){var e=this;return new e(U(t)?function(n,r){for(var o=t.len...
  function q (line 1) | function q(t){var e=this,n=new e(p);return j(n,t),n}
  function D (line 1) | function D(){throw new TypeError("You must pass a resolver function as t...
  function K (line 1) | function K(){throw new TypeError("Failed to construct 'Promise': Please ...
  function L (line 1) | function L(){var t=void 0;if("undefined"!=typeof global)t=global;else if...
  function t (line 1) | function t(t,e){this._instanceConstructor=t,this.promise=new t(p),this.p...
  function t (line 1) | function t(e){this[Z]=C(),this._result=this._state=void 0,this._subscrib...

FILE: examples/workway-node/www/js/poly/event-targe.js
  function t (line 2) | function t(){}
  function r (line 2) | function r(t){var e=t.options;e&&e.once&&u.call(t.target,this.type,t.lis...
  function a (line 2) | function a(t){return this===t.listener}
  function o (line 2) | function o(t,n,r){var i=f(this),o=i[t]||(i[t]=[]);e.call(o,a,n)<0&&o.pus...
  function c (line 2) | function c(t){var e=f(this),n=e[t.type];return n&&(h(t,{currentTarget:th...
  function u (line 2) | function u(t,n,r){var i=f(this),o=i[t];if(o){var c=e.call(o,a,n);-1<c&&o...
  function l (line 2) | function l(){}

FILE: examples/workway-node/www/js/poly/poorlyfills.js
  method size (line 2) | get size(){return t.length}

FILE: examples/workway-promise-reject/workers/index.js
  function foo (line 5) | function foo(message, callback) {

FILE: index.js
  function workway (line 1) | function workway(file) {'use strict';

FILE: min.js
  function workway (line 1) | function workway(t){"use strict";

FILE: node/client.js
  function NodeWorker (line 34) | function NodeWorker(ep) {
  function createEvent (line 47) | function createEvent(type) {

FILE: node/index.js
  function createSandbox (line 38) | function createSandbox(filename, socket) {
  function cleanedStack (line 81) | function cleanedStack(stack) {
  function error (line 86) | function error(socket, err) {
  function message (line 94) | function message(socket, data) {
  function responder (line 99) | function responder(request, response, next) {
  function uid (line 117) | function uid(filename, socket) {
  function uncaught (line 123) | function uncaught(err) {
  function Event (line 131) | function Event(data) {
  function message (line 172) | function message(data) {

FILE: partial/worker.js
  function walkThrough (line 3) | function walkThrough(O, K) { return O[K]; }

FILE: remoted.js
  function remoted (line 1) | function remoted(object) {

FILE: test/background.js
  function Test (line 13) | function Test() {}

FILE: test/circular/analyzer.js
  method analyze (line 4) | analyze(circular) {

FILE: test/client.js
  function showData (line 36) | function showData(data) {

FILE: test/webworker.js
  class Event (line 3) | class Event {
    method constructor (line 4) | constructor(data) {
    method stopImmediatePropagation (line 9) | stopImmediatePropagation() {
  method constructor (line 15) | constructor(file) {
  method addEventListener (line 19) | addEventListener(type, listener) {
  method postMessage (line 22) | postMessage(data) {
  method createElement (line 31) | createElement() {
  method addEventListener (line 40) | addEventListener(type, listener) {
  method postMessage (line 43) | postMessage(data) {

FILE: test/workers/foo.js
  function foo (line 5) | function foo(message, callback) {

FILE: worker.js
  function walkThrough (line 3) | function walkThrough(O, K) { return O[K]; }
  function remoted (line 14) | function remoted(object) {
Condensed preview — 47 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (91K chars).
[
  {
    "path": ".gitignore",
    "chars": 53,
    "preview": ".DS_Store\nnode_modules/\npackage-lock.json\n^worker.js\n"
  },
  {
    "path": ".npmignore",
    "chars": 94,
    "preview": "node_modules/*\nexamples/*\npartial/*\ntest/*\n.DS_Store\n.gitignore\n.travis.yml\npackage-lock.json\n"
  },
  {
    "path": ".travis.yml",
    "chars": 85,
    "preview": "language: node_js\nnode_js:\n  - stable\ngit:\n  depth: 1\nbranches:\n  only:\n    - master\n"
  },
  {
    "path": "LICENSE",
    "chars": 765,
    "preview": "ISC License\n\nCopyright (c) 2018, Andrea Giammarchi, @WebReflection\n\nPermission to use, copy, modify, and/or distribute t"
  },
  {
    "path": "README.md",
    "chars": 9759,
    "preview": "# workway DEPRECATED - See [coincident](https://github.com/WebReflection/coincident#coincidentserver)\n\nA general purpose"
  },
  {
    "path": "cjs/index.js",
    "chars": 3488,
    "preview": "function workway(file) {'use strict';\n  /*! (c) 2018 Andrea Giammarchi (ISC) */\n  return new Promise(function (res) {\n  "
  },
  {
    "path": "cjs/remoted.js",
    "chars": 2021,
    "preview": "function remoted(object) {\n  return function $(object, current, remote) {\n    Object.keys(object).forEach(function (key)"
  },
  {
    "path": "esm/index.js",
    "chars": 3486,
    "preview": "function workway(file) {'use strict';\n  /*! (c) 2018 Andrea Giammarchi (ISC) */\n  return new Promise(function (res) {\n  "
  },
  {
    "path": "esm/remoted.js",
    "chars": 2019,
    "preview": "function remoted(object) {\n  return function $(object, current, remote) {\n    Object.keys(object).forEach(function (key)"
  },
  {
    "path": "examples/workway-node/README.md",
    "chars": 131,
    "preview": "# Node.js workway demo\n\nThis demo shows CPUs and current memory consumption.\n\n```sh\nnpm install\n# now open that localhos"
  },
  {
    "path": "examples/workway-node/index.js",
    "chars": 449,
    "preview": "const path = require('path');\nconst express = require('express');\nconst workway = require('workway/node');\n\n// which fol"
  },
  {
    "path": "examples/workway-node/package.json",
    "chars": 289,
    "preview": "{\n  \"private\": true,\n  \"description\": \"A basic workway driven NodeJS example\",\n  \"scripts\": {\n    \"postinstall\": \"npm st"
  },
  {
    "path": "examples/workway-node/workers/os.js",
    "chars": 101,
    "preview": "const workway = require('workway');\n\n// export any namespace or even modules\nworkway(require('os'));\n"
  },
  {
    "path": "examples/workway-node/www/index.html",
    "chars": 705,
    "preview": "<!doctype html>\n<html>\n  <head>\n    <title>workway meets NodeJS</title>\n    <style>body { font-family: sans-serif; }</st"
  },
  {
    "path": "examples/workway-node/www/js/3rd/hyperhtml.js",
    "chars": 12570,
    "preview": "/*! (c) Andrea Giammarchi (ISC) */var hyperHTML=function(e){\"use strict\";var t=document.defaultView,r=/^area|base|br|col"
  },
  {
    "path": "examples/workway-node/www/js/3rd/workway.js",
    "chars": 1371,
    "preview": "function workway(a){\"use strict\";\n/*! (c) 2018 Andrea Giammarchi (ISC) */return new Promise(function(u,e){function f(){r"
  },
  {
    "path": "examples/workway-node/www/js/index.js",
    "chars": 791,
    "preview": "workway('node://os.js').then(async ({worker, namespace:os}) => {\n  // cpus are not going to change (not the showed part)"
  },
  {
    "path": "examples/workway-node/www/js/poly/es6-promise.js",
    "chars": 6584,
    "preview": "!function(t,e){\"object\"==typeof exports&&\"undefined\"!=typeof module?module.exports=e():\"function\"==typeof define&&define"
  },
  {
    "path": "examples/workway-node/www/js/poly/event-targe.js",
    "chars": 1323,
    "preview": "/*! (c) 2017 Andrea Giammarchi (ISC) */\nvar EventTarget=function(){\"use strict\";var t=\"object\"==typeof global?global:sel"
  },
  {
    "path": "examples/workway-node/www/js/poly/poorlyfills.js",
    "chars": 1226,
    "preview": "\"use strict\";!function(e){/*! (c) 2017 Andrea Giammarchi @WebReflection, (ISC) */\ne.Map=e.Map||function(){var e=void 0,t"
  },
  {
    "path": "examples/workway-promise-reject/README.md",
    "chars": 131,
    "preview": "# Promise reject from Node.js\n\nThis demo shows results when a Promise fails.\n\n```sh\nnpm install\n# now open that localhos"
  },
  {
    "path": "examples/workway-promise-reject/index.html",
    "chars": 814,
    "preview": "<!doctype html>\n<meta name=\"viewport\" content=\"width=device-width,initial-scale=1\">\n<script>\nif(!this.Promise)document.w"
  },
  {
    "path": "examples/workway-promise-reject/index.js",
    "chars": 508,
    "preview": "var PORT = process.env.PORT || 3000;\n\nvar path = require('path');\nvar express = require('express');\nvar workway = requir"
  },
  {
    "path": "examples/workway-promise-reject/package.json",
    "chars": 257,
    "preview": "{\n  \"name\": \"workway-demo\",\n  \"private\": true,\n  \"dependencies\": {\n    \"express\": \"^4.16.3\",\n    \"workway\": \"^0.5.2\"\n  }"
  },
  {
    "path": "examples/workway-promise-reject/workers/index.js",
    "chars": 228,
    "preview": "const util = require('util');\n\nconst workway = require('workway');\n\nfunction foo(message, callback) {\n    callback(42); "
  },
  {
    "path": "index.js",
    "chars": 3462,
    "preview": "function workway(file) {'use strict';\n  /*! (c) 2018 Andrea Giammarchi (ISC) */\n  return new Promise(function (res) {\n  "
  },
  {
    "path": "min.js",
    "chars": 1405,
    "preview": "function workway(t){\"use strict\";\n/*! (c) 2018 Andrea Giammarchi (ISC) */return new Promise(function(u){function f(){ret"
  },
  {
    "path": "node/client.js",
    "chars": 2754,
    "preview": "window.workway = (function (Worker, workway, SECRET) {\n\n  /*! Copyright 2018 Andrea Giammarchi - @WebReflection\n   *\n   "
  },
  {
    "path": "node/index.js",
    "chars": 6243,
    "preview": "\"use strict\";\n\n// used core modules\nvar EventEmitter = require('events').EventEmitter;\nvar crypto = require('crypto');\nv"
  },
  {
    "path": "package.json",
    "chars": 2228,
    "preview": "{\n  \"name\": \"workway\",\n  \"version\": \"0.5.5\",\n  \"description\": \"A general purpose, Web Worker driven, remote namespace wi"
  },
  {
    "path": "partial/worker.js",
    "chars": 3133,
    "preview": "(function () {'use strict';\n  /*! (c) 2018 Andrea Giammarchi (ISC) */\n  function walkThrough(O, K) { return O[K]; }\n  va"
  },
  {
    "path": "remoted.js",
    "chars": 1995,
    "preview": "function remoted(object) {\n  return function $(object, current, remote) {\n    Object.keys(object).forEach(function (key)"
  },
  {
    "path": "test/background.js",
    "chars": 1542,
    "preview": "// a Blackberry gotcha, no console in workers\nif (!self.console) self.console = {log: function () {}, error: function ()"
  },
  {
    "path": "test/circular/analyzer.js",
    "chars": 116,
    "preview": "importScripts('https://unpkg.com/workway/worker.js');\n\nworkway({\n  analyze(circular) {\n    return circular;\n  }\n});\n"
  },
  {
    "path": "test/circular/index.html",
    "chars": 782,
    "preview": "<!doctype html>\n<meta name=\"viewport\" content=\"width=device-width,initial-scale=1\">\n<script type=\"module\">\nimport workwa"
  },
  {
    "path": "test/client.js",
    "chars": 1514,
    "preview": "workway('./background.js').then(function (info) {\n  // {worker, namespace}\n  var worker = info.worker;\n  var namespace ="
  },
  {
    "path": "test/foo.html",
    "chars": 748,
    "preview": "<!doctype html>\n<meta name=\"viewport\" content=\"width=device-width,initial-scale=1\">\n<script>\nif(!this.Promise)document.w"
  },
  {
    "path": "test/foo.js",
    "chars": 725,
    "preview": "var PORT = process.env.PORT || 3000;\n\nvar path = require('path');\nvar express = require('express');\nvar workway = requir"
  },
  {
    "path": "test/index.html",
    "chars": 416,
    "preview": "<!doctype html>\n<meta name=\"viewport\" content=\"width=device-width,initial-scale=1\">\n<script>\nif(!this.Promise)document.w"
  },
  {
    "path": "test/index.js",
    "chars": 87,
    "preview": "require('./webworker');\nglobal.workway = require('../cjs/index');\nrequire('./client');\n"
  },
  {
    "path": "test/node.html",
    "chars": 1276,
    "preview": "<!doctype html>\n<meta name=\"viewport\" content=\"width=device-width,initial-scale=1\">\n<script>\nif(!this.Promise)document.w"
  },
  {
    "path": "test/node.js",
    "chars": 728,
    "preview": "var PORT = process.env.PORT || 3000;\n\nvar path = require('path');\nvar express = require('express');\nvar workway = requir"
  },
  {
    "path": "test/webworker.js",
    "chars": 1076,
    "preview": "const workers = [];\n\nclass Event {\n  constructor(data) {\n    this._stopImmediatePropagation = false;\n    this.type = 'me"
  },
  {
    "path": "test/workers/foo.js",
    "chars": 227,
    "preview": "const util = require('util');\n\nconst workway = require('workway');\n\nfunction foo(message, callback) {\n    callback(42); "
  },
  {
    "path": "test/workers/other.js",
    "chars": 25,
    "preview": "console.log(__filename);\n"
  },
  {
    "path": "test/workers/test.js",
    "chars": 234,
    "preview": "var workway = require('workway');\n\n// require('./other');\n\nworkway({\n  os: require('os'),\n  ping: function () {\n    self"
  },
  {
    "path": "worker.js",
    "chars": 5351,
    "preview": "(function () {'use strict';\n  /*! (c) 2018 Andrea Giammarchi (ISC) */\n  function walkThrough(O, K) { return O[K]; }\n  va"
  }
]

About this extraction

This page contains the full source code of the WebReflection/workway GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 47 files (83.3 KB), approximately 23.3k tokens, and a symbol index with 93 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!