BasePort API
NoFlo - Flow-Based Programming for JavaScript
(c) 2014-2017 Flowhub UG
NoFlo may be freely distributed under the MIT license
import { EventEmitter } from 'events';
NoFlo Port Base class
Base port type used for options normalization. Both inports and outports extend this class.
The list of valid datatypes for ports.
const validTypes = [
'all',
'string',
'number',
'int',
'object',
'array',
'boolean',
'color',
'date',
'bang',
'function',
'buffer',
'stream',
];
/**
* @typedef {Object} BaseOptions - Options for configuring all types of ports
* @property {string} [description='']
* @property {string} [datatype='all']
* @property {string} [schema=null]
* @property {string} [type=null]
* @property {boolean} [required=false]
* @property {boolean} [scoped=true]
*/
/**
* @template {BaseOptions} BaseportOptions
* @param {BaseportOptions} options
* @return {BaseportOptions}
*/
function handleOptions(options) {
We default to the all
type if no explicit datatype
was provided
let datatype = options.datatype || 'all';
Normalize the legacy integer
type to int
.
if (datatype === 'integer') { datatype = 'int'; }
By default ports are not required for graph execution
const required = options.required || false;
Ensure datatype defined for the port is valid
if (validTypes.indexOf(datatype) === -1) {
throw new Error(`Invalid port datatype '${datatype}' specified, valid are ${validTypes.join(', ')}`);
}
Ensure schema defined for the port is valid
const schema = options.schema || options.type;
if (schema && (schema.indexOf('/') === -1)) {
throw new Error(`Invalid port schema '${schema}' specified. Should be URL or MIME type`);
}
Scoping
const scoped = (typeof options.scoped === 'boolean') ? options.scoped : true;
Description
const description = options.description || '';
/* eslint-disable prefer-object-spread */
return Object.assign({}, options, {
description,
datatype,
required,
schema,
scoped,
});
}
export default class BasePort extends EventEmitter {
constructor(options) {
super();
Options holds all options of the current port
this.options = handleOptions(options);
Sockets list contains all currently attached connections to the port
/** @type {Array<import("./InternalSocket").InternalSocket>} */
this.sockets = [];
Name of the graph node this port is in
/** @type {string|null} */
this.node = null;
/** @type {import("./Component").Component|null} */
this.nodeInstance = null;
Name of the port
/** @type {string|null} */
this.name = null;
}
getId() {
if (!this.node || !this.name) {
return 'Port';
}
return `${this.node} ${this.name.toUpperCase()}`;
}
getDataType() { return this.options.datatype; }
getSchema() { return this.options.schema || null; }
getDescription() { return this.options.description; }
attach(socket, index = null) {
let idx = index;
if (!this.isAddressable() || (index === null)) {
idx = this.sockets.length;
}
this.sockets[idx] = socket;
this.attachSocket(socket, idx);
if (this.isAddressable()) {
this.emit('attach', socket, idx);
return;
}
this.emit('attach', socket);
}
eslint-disable-next-line class-methods-use-this,no-unused-vars
attachSocket(socket, index = null) { }
detach(socket) {
const index = this.sockets.indexOf(socket);
if (index === -1) {
return;
}
this.sockets[index] = undefined;
if (this.isAddressable()) {
this.emit('detach', socket, index);
return;
}
this.emit('detach', socket);
}
isAddressable() {
if (this.options.addressable) { return true; }
return false;
}
isBuffered() {
if (this.options.buffered) { return true; }
return false;
}
isRequired() {
if (this.options.required) { return true; }
return false;
}
isAttached(socketId = null) {
if (this.isAddressable() && (socketId !== null)) {
if (this.sockets[socketId]) { return true; }
return false;
}
if (this.sockets.length) { return true; }
return false;
}
listAttached() {
const attached = [];
for (let idx = 0; idx < this.sockets.length; idx += 1) {
const socket = this.sockets[idx];
if (socket) { attached.push(idx); }
}
return attached;
}
isConnected(socketId = null) {
if (this.isAddressable()) {
if (socketId === null) { throw new Error(`${this.getId()}: Socket ID required`); }
if (!this.sockets[socketId]) { throw new Error(`${this.getId()}: Socket ${socketId} not available`); }
return this.sockets[socketId].isConnected();
}
let connected = false;
this.sockets.forEach((socket) => {
if (!socket) { return; }
if (socket.isConnected()) {
connected = true;
}
});
return connected;
}
/* eslint-disable class-methods-use-this */
canAttach() { return true; }
}
This page contains documentation generated automatically from NoFlo's BasePort.js file.