noflo
Version:
Flow-Based Programming environment for JavaScript
160 lines (159 loc) • 4.96 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.normalizePortName = exports.OutPorts = exports.InPorts = void 0;
/* eslint-disable max-classes-per-file */
// NoFlo - Flow-Based Programming for JavaScript
// (c) 2014-2017 Flowhub UG
// NoFlo may be freely distributed under the MIT license
const events_1 = require("events");
const InPort_1 = require("./InPort");
const OutPort_1 = require("./OutPort");
/**
* @typedef {import("./BasePort").BaseOptions} PortOptions
*/
// NoFlo ports collections
//
// Ports collection classes for NoFlo components. These are
// used to hold a set of input or output ports of a component.
class Ports extends events_1.EventEmitter {
/**
* @param {Object<string, import("./BasePort").default|PortOptions>} ports
* @param {typeof import("./BasePort").default} model
*/
constructor(ports, model) {
super();
this.model = model;
/** @type {Object<string, import("./BasePort").default>} */
this.ports = {};
if (!ports) {
return;
}
Object.keys(ports).forEach((name) => {
const options = ports[name];
this.add(name, options);
});
}
/**
* @param {string} name
* @param {Object|import("./BasePort").default|PortOptions} [options]
*/
add(name, options = {}) {
if ((name === 'add') || (name === 'remove')) {
throw new Error('Add and remove are restricted port names');
}
/* eslint-disable no-useless-escape */
if (!name.match(/^[a-z0-9_\.\/]+$/)) {
throw new Error(`Port names can only contain lowercase alphanumeric characters and underscores. '${name}' not allowed`);
}
// Remove previous implementation
if (this.ports[name]) {
this.remove(name);
}
const maybePort = /** @type {import("./BasePort").default} */ (options);
if ((typeof maybePort === 'object') && maybePort.canAttach) {
this.ports[name] = maybePort;
}
else {
const Model = this.model;
this.ports[name] = new Model(options);
}
this[name] = this.ports[name];
this.emit('add', name);
return this; // chainable
}
/**
* @param {string} name
*/
remove(name) {
if (!this.ports[name]) {
throw new Error(`Port ${name} not defined`);
}
delete this.ports[name];
delete this[name];
this.emit('remove', name);
return this; // chainable
}
}
/**
* @typedef {{ [key: string]: InPort|import("./InPort").PortOptions }} InPortsOptions
*/
class InPorts extends Ports {
/**
* @param {InPortsOptions} [ports]
*/
constructor(ports = {}) {
super(ports, InPort_1.default);
}
}
exports.InPorts = InPorts;
/**
* @typedef {{ [key: string]: OutPort|import("./OutPort").PortOptions }} OutPortsOptions
*/
class OutPorts extends Ports {
/**
* @param {OutPortsOptions} [ports]
*/
constructor(ports = {}) {
super(ports, OutPort_1.default);
}
connect(name, socketId) {
const port = /** @type {OutPort} */ (this.ports[name]);
if (!port) {
throw new Error(`Port ${name} not available`);
}
port.connect(socketId);
}
beginGroup(name, group, socketId) {
const port = /** @type {OutPort} */ (this.ports[name]);
if (!port) {
throw new Error(`Port ${name} not available`);
}
port.beginGroup(group, socketId);
}
send(name, data, socketId) {
const port = /** @type {OutPort} */ (this.ports[name]);
if (!port) {
throw new Error(`Port ${name} not available`);
}
port.send(data, socketId);
}
endGroup(name, socketId) {
const port = /** @type {OutPort} */ (this.ports[name]);
if (!port) {
throw new Error(`Port ${name} not available`);
}
port.endGroup(socketId);
}
disconnect(name, socketId) {
const port = /** @type {OutPort} */ (this.ports[name]);
if (!port) {
throw new Error(`Port ${name} not available`);
}
port.disconnect(socketId);
}
}
exports.OutPorts = OutPorts;
// Port name normalization:
// returns object containing keys name and index for ports names in
// format `portname` or `portname[index]`.
/**
* @param {string} name
* @returns {{ name: string, index?: string }}
*/
function normalizePortName(name) {
const port = { name };
// Regular port
if (name.indexOf('[') === -1) {
return port;
}
// Addressable port with index
const matched = name.match(/(.*)\[([0-9]+)\]/);
if (!matched || matched.length < 3) {
return port;
}
return {
name: matched[1],
index: matched[2],
};
}
exports.normalizePortName = normalizePortName;