0.2.0 - Mid migration

This commit is contained in:
Daniel Mason 2022-04-25 14:47:15 +12:00
parent 139e6a915e
commit 7e38fdbd7d
42393 changed files with 5358157 additions and 62 deletions

4
web/node_modules/worker-rpc/.travis.yml generated vendored Normal file
View file

@ -0,0 +1,4 @@
language: node_js
node_js:
- node

21
web/node_modules/worker-rpc/LICENSE generated vendored Normal file
View file

@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2016 Christian Speckner <cnspeckn@googlemail.com>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

180
web/node_modules/worker-rpc/README.md generated vendored Normal file
View file

@ -0,0 +1,180 @@
[![Build Status](https://travis-ci.org/DirtyHairy/worker-rpc.svg?branch=master)](https://travis-ci.org/DirtyHairy/worker-rpc)
[![npm version](https://badge.fury.io/js/worker-rpc.svg)](https://badge.fury.io/js/worker-rpc)
# What is it?
This package provides a simple RPC mechanism on top of any transport that transfers
JSON data. It was initially conceived to provide communication with web workers
(and as such supports transferables), but it can be used on top of many other
different transport channels, i.e. `postMessage` between frames, websockets via
`socket.io` or JSON encoded messages over pipes.
# How to use it?
## Installation
You can install the library into your project via npm
npm install worker-rpc
The library is written in Typescript and will work in any environment that
supports ES5 and ES6-style promises (either native or through a shim).
No external typings are required for using this library with Typescript (version >= 2).
## Web worker example
In this example, we use the library to set up communication with a web worker.
### Web worker
import {RpcProvider} from 'worker-rpc';
const rpcProvider = new RpcProvider(
(message, transfer) => postMessage(message, transfer)
);
onmessage = e => rpcProvider.dispatch(e.data);
rpcProvider.registerRpcHandler('add', ({x, y}) => x + y);
The RPC provider is initialized with a function that dispatches a message.
This function will receive an opaque message object as first argument, and
a list of transferables as second argument. This allows to leverage transfer
of ownership instead of copying between worker and host page.
On incoming messages, `dispatch` is called on the RPC provider in order to
handle the message.
Each registered RPC handler is identified by a message ID (`add` in this example)
and has a handler function that receives the message object and can return a
result either as an immediate value or as a promise.
### Page
import {RpcProvider} from 'worker-rpc';
const worker = new Worker('worker.js'),
rpcProvider = new RpcProvider(
(message, transfer) => worker.postMessage(message, transfer)
);
worker.onmessage = e => rpcProvider.dispatch(e.data);
rpcProvider
.rpc('add', {x: 1, y: 2})
.then(result => console.log(result)); // 3
## Importing
ES5 / CommonJS
var RpcProvider = require('worker-rpc').RpcProvider;
ES6
import {RpcProvider} from 'worker-rpc';
Typescript
import {RpcProvider, RpcProviderInterface} from 'worker-rpc';
## API
The API is built around the `RpcProvider` class. A `RpcProvider` acts both as
client and server for RPC calls and event-like signals. The library uses ES6
promises and can consume any A+ compliant promises.
### Creating a new provider
const rpc = new RpcProvider(dispatcher, timeout);
* `dispatcher`: A function that will be called for dispatching messages. The
first argument will be an opaque message object, and the second argument
an error of `Transferable` objects that are to be passed via ownership
transfer (if supported by the transport).
* `timeout` (optional): The timeout for RPC transactions in milliseconds.
Values of `0` or smaller disable the timeout (this is the default).
### Incoming messages
rpc.dispatch(message);
Similar to message dispatch, `worker-rpc` does not provide a built-in mechanism
for receiving messages. Instead, incoming messages must be relayed to the provider
by invoking `dispatch`.
* `message`: The received message.
### Registering RPC handlers
rpc.registerRpcHandler(id, handler);
Register a handler function for RPC calls with id `id`. Returns the provider instance.
* `id`: RPC call id. Only a single handler can be registered for any id. Ids should
be strings.
* `handler`: The handler function. This function receives the payload object as
its argument and can return its result either as an immediate value or as a
promise.
### Registering signal handlers
rpc.registerSignalHandler(id, handler));
Register a handler function for signals with id `id`. Returns the provider instance.
* `id`: Signal id. The namespace for signal ids is seperate from that of RPC ids,
and multiple handlers my be attached tp a single signal. Ids should be strings
* `handler`: The handler function. This function receives the payload object as
its argument; the result is ignored.
### Dispatching RPC calls
const result = rpc.rpc(id, payload, transfer);
Dispatch a RPC call and returns a promise for its result. The promise is rejected
if the call times out or if no handler is registered (or if the handler rejects
the operation).
* `id`: RPC call id.
* `payload` (optional): RPC call payload.
* `transfer` (optional): List of `Transferables` that will be passed to dispatched
(see above).
### Dispatching signals
rpc.signal(id, payload, transfer);
Dispatch a signal. Returns the provider instance.
* `id`: Signal id.
* `payload` (optional): Signal payload.
* `transfer` (optional): List of `Transferables` that will be passed to dispatched
(see above).
### Deregistering RPC handlers
rpc.deregisterRpcHandler(id, handler);
`id` and `handler` must be the same arguments used for `registerRpcHandler`.
Returns the provider instance.
### Deregistering signal handlers
rpc.deregisterSignalHandler(id, handler);
`id` and `handler` must be the same arguments used for `registerSignalHandler`.
Returns the provider instance.
### Errors
rpc.error.addHandler(errorHandler);
The error event is dispatched if there is either a local or remote communcation
error (timeout, invalid id, etc.). Checkout the
[microevent.ts](https://github.com/DirtyHairy/microevent)
documentation for the event API.
# License
Feel free to use this library under the conditions of the MIT license.

42
web/node_modules/worker-rpc/lib/RpcProvider.d.ts generated vendored Normal file
View file

@ -0,0 +1,42 @@
import { Event } from 'microevent.ts';
import RpcProviderInterface from './RpcProviderInterface';
declare class RpcProvider implements RpcProviderInterface {
private _dispatch;
private _rpcTimeout;
constructor(_dispatch: RpcProvider.Dispatcher, _rpcTimeout?: number);
dispatch(payload: any): void;
rpc<T, U>(id: string, payload?: T, transfer?: any): Promise<U>;
signal<T>(id: string, payload?: T, transfer?: any): this;
registerRpcHandler<T, U>(id: string, handler: RpcProviderInterface.RpcHandler<T, U>): this;
registerSignalHandler<T>(id: string, handler: RpcProviderInterface.SignalHandler<T>): this;
deregisterRpcHandler<T, U>(id: string, handler: RpcProviderInterface.RpcHandler<T, U>): this;
deregisterSignalHandler<T>(id: string, handler: RpcProviderInterface.SignalHandler<T>): this;
private _raiseError;
private _handleSignal;
private _handeRpc;
private _handleInternal;
private _transactionTimeout;
private _clearTransaction;
error: Event<Error>;
private _rpcHandlers;
private _signalHandlers;
private _pendingTransactions;
private _nextTransactionId;
}
declare module RpcProvider {
enum MessageType {
signal = 0,
rpc = 1,
internal = 2
}
interface Dispatcher {
(message: Message, transfer?: Array<any>): void;
}
interface Message {
type: MessageType;
transactionId?: number;
id: string;
payload?: any;
}
}
export default RpcProvider;

166
web/node_modules/worker-rpc/lib/RpcProvider.js generated vendored Normal file
View file

@ -0,0 +1,166 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var microevent_ts_1 = require("microevent.ts");
var MSG_RESOLVE_TRANSACTION = "resolve_transaction", MSG_REJECT_TRANSACTION = "reject_transaction", MSG_ERROR = "error";
var RpcProvider = /** @class */ (function () {
function RpcProvider(_dispatch, _rpcTimeout) {
if (_rpcTimeout === void 0) { _rpcTimeout = 0; }
this._dispatch = _dispatch;
this._rpcTimeout = _rpcTimeout;
this.error = new microevent_ts_1.Event();
this._rpcHandlers = {};
this._signalHandlers = {};
this._pendingTransactions = {};
this._nextTransactionId = 0;
}
RpcProvider.prototype.dispatch = function (payload) {
var message = payload;
switch (message.type) {
case RpcProvider.MessageType.signal:
return this._handleSignal(message);
case RpcProvider.MessageType.rpc:
return this._handeRpc(message);
case RpcProvider.MessageType.internal:
return this._handleInternal(message);
default:
this._raiseError("invalid message type " + message.type);
}
};
RpcProvider.prototype.rpc = function (id, payload, transfer) {
var _this = this;
var transactionId = this._nextTransactionId++;
this._dispatch({
type: RpcProvider.MessageType.rpc,
transactionId: transactionId,
id: id,
payload: payload
}, transfer ? transfer : undefined);
return new Promise(function (resolve, reject) {
var transaction = _this._pendingTransactions[transactionId] = {
id: transactionId,
resolve: resolve,
reject: reject
};
if (_this._rpcTimeout > 0) {
_this._pendingTransactions[transactionId].timeoutHandle =
setTimeout(function () { return _this._transactionTimeout(transaction); }, _this._rpcTimeout);
}
});
};
;
RpcProvider.prototype.signal = function (id, payload, transfer) {
this._dispatch({
type: RpcProvider.MessageType.signal,
id: id,
payload: payload,
}, transfer ? transfer : undefined);
return this;
};
RpcProvider.prototype.registerRpcHandler = function (id, handler) {
if (this._rpcHandlers[id]) {
throw new Error("rpc handler for " + id + " already registered");
}
this._rpcHandlers[id] = handler;
return this;
};
;
RpcProvider.prototype.registerSignalHandler = function (id, handler) {
if (!this._signalHandlers[id]) {
this._signalHandlers[id] = [];
}
this._signalHandlers[id].push(handler);
return this;
};
RpcProvider.prototype.deregisterRpcHandler = function (id, handler) {
if (this._rpcHandlers[id]) {
delete this._rpcHandlers[id];
}
return this;
};
;
RpcProvider.prototype.deregisterSignalHandler = function (id, handler) {
if (this._signalHandlers[id]) {
this._signalHandlers[id] = this._signalHandlers[id].filter(function (h) { return handler !== h; });
}
return this;
};
RpcProvider.prototype._raiseError = function (error) {
this.error.dispatch(new Error(error));
this._dispatch({
type: RpcProvider.MessageType.internal,
id: MSG_ERROR,
payload: error
});
};
RpcProvider.prototype._handleSignal = function (message) {
if (!this._signalHandlers[message.id]) {
return this._raiseError("invalid signal " + message.id);
}
this._signalHandlers[message.id].forEach(function (handler) { return handler(message.payload); });
};
RpcProvider.prototype._handeRpc = function (message) {
var _this = this;
if (!this._rpcHandlers[message.id]) {
return this._raiseError("invalid rpc " + message.id);
}
Promise.resolve(this._rpcHandlers[message.id](message.payload))
.then(function (result) { return _this._dispatch({
type: RpcProvider.MessageType.internal,
id: MSG_RESOLVE_TRANSACTION,
transactionId: message.transactionId,
payload: result
}); }, function (reason) { return _this._dispatch({
type: RpcProvider.MessageType.internal,
id: MSG_REJECT_TRANSACTION,
transactionId: message.transactionId,
payload: reason
}); });
};
RpcProvider.prototype._handleInternal = function (message) {
switch (message.id) {
case MSG_RESOLVE_TRANSACTION:
if (!this._pendingTransactions[message.transactionId]) {
return this._raiseError("no pending transaction with id " + message.transactionId);
}
this._pendingTransactions[message.transactionId].resolve(message.payload);
this._clearTransaction(this._pendingTransactions[message.transactionId]);
break;
case MSG_REJECT_TRANSACTION:
if (!this._pendingTransactions[message.transactionId]) {
return this._raiseError("no pending transaction with id " + message.transactionId);
}
this._pendingTransactions[message.transactionId].reject(message.payload);
this._clearTransaction(this._pendingTransactions[message.transactionId]);
break;
case MSG_ERROR:
this.error.dispatch(new Error("remote error: " + message.payload));
break;
default:
this._raiseError("unhandled internal message " + message.id);
break;
}
};
RpcProvider.prototype._transactionTimeout = function (transaction) {
transaction.reject('transaction timed out');
this._raiseError("transaction " + transaction.id + " timed out");
delete this._pendingTransactions[transaction.id];
return;
};
RpcProvider.prototype._clearTransaction = function (transaction) {
if (typeof (transaction.timeoutHandle) !== 'undefined') {
clearTimeout(transaction.timeoutHandle);
}
delete this._pendingTransactions[transaction.id];
};
return RpcProvider;
}());
(function (RpcProvider) {
var MessageType;
(function (MessageType) {
MessageType[MessageType["signal"] = 0] = "signal";
MessageType[MessageType["rpc"] = 1] = "rpc";
MessageType[MessageType["internal"] = 2] = "internal";
})(MessageType = RpcProvider.MessageType || (RpcProvider.MessageType = {}));
;
})(RpcProvider || (RpcProvider = {}));
exports.default = RpcProvider;

View file

@ -0,0 +1,20 @@
import { EventInterface } from 'microevent.ts';
interface RpcProviderInterface {
dispatch(message: any): void;
rpc<T, U>(id: string, payload?: T, transfer?: Array<any>): Promise<U>;
signal<T>(id: string, payload?: T, transfer?: Array<any>): this;
registerRpcHandler<T, U>(id: string, handler: RpcProviderInterface.RpcHandler<T, U>): this;
registerSignalHandler<T>(id: string, handler: RpcProviderInterface.SignalHandler<T>): this;
deregisterRpcHandler<T, U>(id: string, handler: RpcProviderInterface.RpcHandler<T, U>): this;
deregisterSignalHandler<T>(id: string, handler: RpcProviderInterface.SignalHandler<T>): this;
error: EventInterface<Error>;
}
declare module RpcProviderInterface {
interface RpcHandler<T, U> {
(payload?: T): Promise<U> | U;
}
interface SignalHandler<T> {
(payload?: T): void;
}
}
export default RpcProviderInterface;

View file

@ -0,0 +1,2 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });

2
web/node_modules/worker-rpc/lib/index.d.ts generated vendored Normal file
View file

@ -0,0 +1,2 @@
export { default as RpcProvider } from './RpcProvider';
export { default as RpcProviderInterface } from './RpcProviderInterface';

4
web/node_modules/worker-rpc/lib/index.js generated vendored Normal file
View file

@ -0,0 +1,4 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var RpcProvider_1 = require("./RpcProvider");
exports.RpcProvider = RpcProvider_1.default;

30
web/node_modules/worker-rpc/package.json generated vendored Normal file
View file

@ -0,0 +1,30 @@
{
"name": "worker-rpc",
"version": "0.1.1",
"description": "A simple RPC layer for communicating with web workers and over other transports",
"scripts": {
"prepublish": "tsc",
"pretest": "typings install && tsc -p tsconfig.test.json",
"test": "mocha -R spec -u tdd test"
},
"author": "Christian Speckner <cnspeckn@googlemail.com> (https://github.com/DirtyHairy/)",
"license": "MIT",
"repository": {
"type": "git",
"url": "https://github.com/DirtyHairy/worker-rpc"
},
"keywords": [
"worker",
"rpc"
],
"devDependencies": {
"mocha": "~6.1.4",
"typescript": "~3.4.5",
"typings": "~2.1.1"
},
"main": "lib/index.js",
"types": "lib/index.d.ts",
"dependencies": {
"microevent.ts": "~0.1.1"
}
}

233
web/node_modules/worker-rpc/src/RpcProvider.ts generated vendored Normal file
View file

@ -0,0 +1,233 @@
import {Event} from 'microevent.ts';
import RpcProviderInterface from './RpcProviderInterface';
const MSG_RESOLVE_TRANSACTION = "resolve_transaction",
MSG_REJECT_TRANSACTION = "reject_transaction",
MSG_ERROR = "error";
interface Transaction {
id: number;
timeoutHandle?: any;
resolve(result: any): void;
reject(error: string): void;
}
class RpcProvider implements RpcProviderInterface {
constructor(
private _dispatch: RpcProvider.Dispatcher,
private _rpcTimeout = 0
) {}
dispatch(payload: any): void {
const message = payload as RpcProvider.Message;
switch (message.type) {
case RpcProvider.MessageType.signal:
return this._handleSignal(message);
case RpcProvider.MessageType.rpc:
return this._handeRpc(message);
case RpcProvider.MessageType.internal:
return this._handleInternal(message);
default:
this._raiseError(`invalid message type ${message.type}`);
}
}
rpc<T, U>(id: string, payload?: T, transfer?: any): Promise<U> {
const transactionId = this._nextTransactionId++;
this._dispatch({
type: RpcProvider.MessageType.rpc,
transactionId,
id,
payload
}, transfer ? transfer : undefined);
return new Promise(
(resolve, reject) => {
const transaction = this._pendingTransactions[transactionId] = {
id: transactionId,
resolve,
reject
};
if (this._rpcTimeout > 0) {
this._pendingTransactions[transactionId].timeoutHandle =
setTimeout(() => this._transactionTimeout(transaction), this._rpcTimeout);
}
}
);
};
signal<T>(id: string, payload?: T, transfer?: any): this {
this._dispatch({
type: RpcProvider.MessageType.signal,
id,
payload,
}, transfer ? transfer : undefined);
return this;
}
registerRpcHandler<T, U>(id: string, handler: RpcProviderInterface.RpcHandler<T, U>): this {
if (this._rpcHandlers[id]) {
throw new Error(`rpc handler for ${id} already registered`);
}
this._rpcHandlers[id] = handler;
return this;
};
registerSignalHandler<T>(id: string, handler: RpcProviderInterface.SignalHandler<T>): this {
if (!this._signalHandlers[id]) {
this._signalHandlers[id] = [];
}
this._signalHandlers[id].push(handler);
return this;
}
deregisterRpcHandler<T, U>(id: string, handler: RpcProviderInterface.RpcHandler<T, U>): this {
if (this._rpcHandlers[id]) {
delete this._rpcHandlers[id];
}
return this;
};
deregisterSignalHandler<T>(id: string, handler: RpcProviderInterface.SignalHandler<T>): this {
if (this._signalHandlers[id]) {
this._signalHandlers[id] = this._signalHandlers[id].filter(h => handler !== h);
}
return this;
}
private _raiseError(error: string): void {
this.error.dispatch(new Error(error));
this._dispatch({
type: RpcProvider.MessageType.internal,
id: MSG_ERROR,
payload: error
});
}
private _handleSignal(message: RpcProvider.Message): void {
if (!this._signalHandlers[message.id]) {
return this._raiseError(`invalid signal ${message.id}`);
}
this._signalHandlers[message.id].forEach(handler => handler(message.payload));
}
private _handeRpc(message: RpcProvider.Message): void {
if (!this._rpcHandlers[message.id]) {
return this._raiseError(`invalid rpc ${message.id}`);
}
Promise.resolve(this._rpcHandlers[message.id](message.payload))
.then(
(result: any) => this._dispatch({
type: RpcProvider.MessageType.internal,
id: MSG_RESOLVE_TRANSACTION,
transactionId: message.transactionId,
payload: result
}),
(reason: string) => this._dispatch({
type: RpcProvider.MessageType.internal,
id: MSG_REJECT_TRANSACTION,
transactionId: message.transactionId,
payload: reason
})
);
}
private _handleInternal(message: RpcProvider.Message): void {
switch (message.id) {
case MSG_RESOLVE_TRANSACTION:
if (!this._pendingTransactions[message.transactionId]) {
return this._raiseError(`no pending transaction with id ${message.transactionId}`);
}
this._pendingTransactions[message.transactionId].resolve(message.payload);
this._clearTransaction(this._pendingTransactions[message.transactionId]);
break;
case MSG_REJECT_TRANSACTION:
if (!this._pendingTransactions[message.transactionId]) {
return this._raiseError(`no pending transaction with id ${message.transactionId}`);
}
this._pendingTransactions[message.transactionId].reject(message.payload);
this._clearTransaction(this._pendingTransactions[message.transactionId]);
break;
case MSG_ERROR:
this.error.dispatch(new Error(`remote error: ${message.payload}`));
break;
default:
this._raiseError(`unhandled internal message ${message.id}`);
break;
}
}
private _transactionTimeout(transaction: Transaction): void {
transaction.reject('transaction timed out');
this._raiseError(`transaction ${transaction.id} timed out`);
delete this._pendingTransactions[transaction.id];
return;
}
private _clearTransaction(transaction: Transaction): void {
if (typeof(transaction.timeoutHandle) !== 'undefined') {
clearTimeout(transaction.timeoutHandle);
}
delete this._pendingTransactions[transaction.id];
}
error = new Event<Error>();
private _rpcHandlers: {[id: string]: RpcProviderInterface.RpcHandler<any, any>} = {};
private _signalHandlers: {[id: string]: Array<RpcProviderInterface.SignalHandler<any>>} = {};
private _pendingTransactions: {[id: number]: Transaction} = {};
private _nextTransactionId = 0;
}
module RpcProvider {
export enum MessageType {
signal,
rpc,
internal
};
export interface Dispatcher {
(message: Message, transfer?: Array<any>): void;
}
export interface Message {
type: MessageType;
transactionId?: number;
id: string;
payload?: any;
}
}
export default RpcProvider;

View file

@ -0,0 +1,35 @@
import {EventInterface} from 'microevent.ts';
interface RpcProviderInterface {
dispatch(message: any): void;
rpc<T, U>(id: string, payload?: T, transfer?: Array<any>): Promise<U>;
signal<T>(id: string, payload?: T, transfer?: Array<any>): this;
registerRpcHandler<T, U>(id: string, handler: RpcProviderInterface.RpcHandler<T, U>): this;
registerSignalHandler<T>(id: string, handler: RpcProviderInterface.SignalHandler<T>): this;
deregisterRpcHandler<T, U>(id: string, handler: RpcProviderInterface.RpcHandler<T, U>): this;
deregisterSignalHandler<T>(id: string, handler: RpcProviderInterface.SignalHandler<T>): this;
error: EventInterface<Error>;
}
module RpcProviderInterface {
export interface RpcHandler<T, U> {
(payload?: T): Promise<U>|U;
}
export interface SignalHandler<T> {
(payload?: T): void;
}
}
export default RpcProviderInterface;

2
web/node_modules/worker-rpc/src/index.ts generated vendored Normal file
View file

@ -0,0 +1,2 @@
export {default as RpcProvider} from './RpcProvider';
export {default as RpcProviderInterface} from './RpcProviderInterface';

242
web/node_modules/worker-rpc/test/rpcProvider.ts generated vendored Normal file
View file

@ -0,0 +1,242 @@
/// <reference path="../typings/index.d.ts"/>
import * as assert from 'assert';
import RpcProvider from '../src/RpcProvider';
suite('RPC provider', function() {
let local: RpcProvider,
remote: RpcProvider,
transferLocalToRemote: Array<any>,
transferRemoteToLocal: Array<any>,
errorLocal: Error,
errorRemote: Error;
setup(function() {
local = new RpcProvider(
(message, transfer) => (transferLocalToRemote = transfer, remote.dispatch(message)),
50
);
local.error.addHandler(err => errorLocal = err);
remote = new RpcProvider(
(message, transfer) => (transferRemoteToLocal = transfer, local.dispatch(message)),
50
);
remote.error.addHandler(err => errorRemote = err);
transferLocalToRemote = transferRemoteToLocal = undefined;
errorRemote = errorLocal = undefined
});
suite('signals', function() {
test('Signals are propagated', function() {
let x = -1;
remote.registerSignalHandler('action', (value: number) => x = value);
local.signal('action', 5);
assert(!errorLocal);
assert(!errorRemote);
assert.strictEqual(x, 5);
});
test('Unregistered signals raise an error', function() {
local.signal('action', 10);
assert(errorLocal);
assert(errorRemote);
});
test('Multiple signals do not interfere', function() {
let x = -1, y = -1;
remote.registerSignalHandler('setx', (value: number) => x = value);
remote.registerSignalHandler('sety', (value: number) => y = value);
local.signal('setx', 5);
local.signal('sety', 6);
assert(!errorLocal);
assert(!errorRemote);
assert.strictEqual(x, 5);
assert.strictEqual(y, 6);
});
test('Multiple handlers can be bound to one signal', function() {
let x = -1;
remote.registerSignalHandler('action', (value: number) => x = value);
local.signal('action', 1);
local.signal('action', 2);
assert(!errorLocal);
assert(!errorRemote);
assert.strictEqual(x, 2);
});
test('Handlers can be deregistered', function() {
let x = -1;
const handler = (value: number) => x = value;
remote.registerSignalHandler('action', handler);
remote.deregisterSignalHandler('action', handler);
local.signal('action', 5);
assert(!errorLocal);
assert(!errorRemote);
assert.strictEqual(x, -1);
});
test('Transfer is honored', function() {
let x = -1;
const transfer = [1, 2, 3];
remote.registerSignalHandler('action', (value: number) => x = value);
local.signal('action', 2, transfer);
assert(!errorLocal);
assert(!errorRemote);
assert.strictEqual(x, 2);
assert.strictEqual(transferLocalToRemote, transfer);
assert(!transferRemoteToLocal);
});
});
suite('RPC', function() {
test('RPC handlers can return values', function() {
remote.registerRpcHandler('action', () => 10);
return local
.rpc('action')
.then(result => (
assert.strictEqual(result, 10),
assert(!errorLocal),
assert(!errorRemote)
));
});
test('RPC handlers can return promises', function() {
remote.registerRpcHandler('action', () => new Promise(r => setTimeout(() => r(10), 15)));
return local
.rpc('action')
.then(result => (
assert.strictEqual(result, 10),
assert(!errorLocal),
assert(!errorRemote)
));
})
test('Promise rejection is transferred', function() {
remote.registerRpcHandler('action', () => new Promise((resolve, reject) => setTimeout(() => reject(10), 15)));
return local
.rpc('action')
.then(
() => Promise.reject('should have been rejected'),
result => (
assert.strictEqual(result, 10),
assert(!errorLocal),
assert(!errorRemote)
)
);
});
test('Invalid RPC calls are rejected', function() {
return local
.rpc('action')
.then(
() => Promise.reject('should have been rejected'),
() => undefined
);
});
test('Invalid RPC calls throw on both ends', function() {
return local
.rpc('action')
.then(
() => Promise.reject('should have been rejected'),
() => undefined
)
.then(() => (
assert(errorLocal),
assert(errorRemote)
));
});
test('RPC calls time out', function() {
remote.registerRpcHandler('action', () => new Promise(r => setTimeout(() => r(10), 100)));
return local
.rpc('action')
.then(
() => Promise.reject('should have been rejected'),
() => (assert(errorLocal), new Promise(r => setTimeout(r, 100)))
)
.then(() => assert(errorRemote));
});
test('Multiple RPC handlers do not interfere', function() {
remote.registerRpcHandler('a1', (value: number) => new Promise(r => setTimeout(() => r(value), 30)));
remote.registerRpcHandler('a2', (value: number) => 2 * value);
return Promise
.all([
local.rpc('a1', 10),
local.rpc('a2', 20)
])
.then(([r1, r2]) => (
assert.strictEqual(r1, 10),
assert.strictEqual(r2, 40),
assert(!errorLocal),
assert(!errorRemote)
));
});
test('RPC handler can be deregistered', function() {
const handler = () => 10;
remote.registerRpcHandler('action', handler);
remote.deregisterRpcHandler('action', handler);
return local
.rpc('action')
.then(
() => Promise.reject('should have been rejected'),
() => (
assert(errorLocal),
assert(errorRemote)
)
);
});
test('Transfer is honored', function() {
const transfer = [1, 2, 3];
remote.registerRpcHandler('action', () => 10);
return local
.rpc('action', undefined, transfer)
.then(x => (
assert.strictEqual(transferLocalToRemote, transfer),
assert.strictEqual(x, 10),
assert(!errorLocal),
assert(!errorRemote)
));
});
});
});

15
web/node_modules/worker-rpc/tsconfig.json generated vendored Normal file
View file

@ -0,0 +1,15 @@
{
"compilerOptions": {
"module": "commonjs",
"target": "es5",
"sourceMap": false,
"noImplicitAny": true,
"noImplicitThis": true,
"declaration": true,
"outDir": "lib",
"lib": ["es5", "es6", "dom"],
"esModuleInterop": true
},
"include": ["src/**/*.ts"],
"exclude": ["node_modules"]
}

12
web/node_modules/worker-rpc/tsconfig.test.json generated vendored Normal file
View file

@ -0,0 +1,12 @@
{
"compilerOptions": {
"module": "commonjs",
"target": "es5",
"sourceMap": false,
"noImplicitAny": true,
"noImplicitThis": true,
"lib": ["es5", "es6", "dom"]
},
"include": ["test/**/*.ts"],
"exclude": ["node_modules"]
}

6
web/node_modules/worker-rpc/typings.json generated vendored Normal file
View file

@ -0,0 +1,6 @@
{
"globalDependencies": {
"mocha": "registry:dt/mocha#2.2.5+20160720003353",
"node": "registry:dt/node#6.0.0+20161019125345"
}
}

1789
web/node_modules/worker-rpc/yarn.lock generated vendored Normal file

File diff suppressed because it is too large Load diff