API Documentation

On GitHub

Ports API

/* 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
import { EventEmitter } from 'events';
import InPort from './InPort';
import OutPort from './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 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
 */
export class InPorts extends Ports {
  /**
   * @param {InPortsOptions} [ports]
   */
  constructor(ports = {}) {
    super(ports, InPort);
  }
}

/**
 * @typedef {{ [key: string]: OutPort|import("./OutPort").PortOptions }} OutPortsOptions
 */
export class OutPorts extends Ports {
  /**
   * @param {OutPortsOptions} [ports]
   */
  constructor(ports = {}) {
    super(ports, OutPort);
  }

  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);
  }
}

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 }}
 */
export 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],
  };
}

This page contains documentation generated automatically from NoFlo's Ports.js file.