util_datumStreamMetadataRegistry.js
import DatumStreamMetadata from "../domain/datumStreamMetadata.js";
/**
* A registry of datum stream metadata instances for object (node or location) and source ID combinations.
*
* This registry acts like a map of (stream ID) -> metadata as well as (object ID, source ID) -> metadata.
*
* @alias module:util~DatumStreamMetadataRegistry
*/
class DatumStreamMetadataRegistry {
/**
* Constructor.
* @param {DatumStreamMetadata[]} [metas] optional list of metadata to start with
*/
constructor(metas) {
this._metaList = Array.isArray(metas) ? metas : [];
this._metaMap = new Map();
for (const e of this._metaList) {
if (e instanceof DatumStreamMetadata) {
this._metaMap.set(e.streamId, e);
}
}
}
/**
* Add metadata to the registry.
* @param {DatumStreamMetadata} meta the metadata to add to the registry
* @returns {DatumStreamMetadata} this object
*/
addMetadata(meta) {
if (meta instanceof DatumStreamMetadata && meta.streamId) {
this._metaList.push(meta);
this._metaMap.set(meta.streamId, meta);
}
return this;
}
/**
* Get a set of all available stream IDs.
* @returns {Set<string>} all available metadata stream ID values
*/
metadataStreamIds() {
return new Set(this._metaMap.keys());
}
/**
* Get the metadata at a specific index, based on insertion order.
* @param {number} index the index of the metadata to get
* @returns {DatumStreamMetadata} the metadata at the given index, or `undefined`
*/
metadataAt(index) {
return index < this._metaList.length ? this._metaList[index] : undefined;
}
/**
* Get the index of the metadata with a specific stream ID.
* @param {string} streamId the stream ID to get the index of
* @returns {number} the found index, or `-1` if not found
*/
indexOfMetadataStreamId(streamId) {
let i = 0;
for (const meta of this._metaList) {
if (meta.streamId === streamId) {
return i;
}
i += 1;
}
return -1;
}
/**
* Get a list of all available stream IDs in insertion order.
* @returns {string[]} all available metadata stream ID values in the same order as added to this registry
*/
metadataStreamIdsList() {
return this._metaList.map((e) => e.streamId);
}
/**
* Get the metadta for a given stream ID.
* @param {string} streamId the stream ID of the metadata to get
* @returns {DatumStreamMetadata} the associated metadata, or `undefined` if none available
*/
metadataForStreamId(streamId) {
return this._metaMap.get(streamId);
}
/**
* Get the first available metadata for a given object and source ID combination.
* @param {number} objectId the object ID of the metadata to get
* @param {string} sourceId the source ID of the metadata to get
* @returns {DatumStreamMetadata} the associated metadata, or `undefined` if none available
*/
metadataForObjectSource(objectId, sourceId) {
for (const meta of this._metaMap.values()) {
if (meta.objectId === objectId && meta.sourceId == sourceId) {
return meta;
}
}
return undefined;
}
/**
* Get this object as a standard JSON encoded string value.
*
* The returned JSON is an array of the {@link module:domain~DatumStreamMetadata#toJsonEncoding DatumStreamMetadata#toJsonEncoding()} result
* of all metadata in the registry. An example result looks like this:
*
* ```
* [
* {
* "streamId": "7714f762-2361-4ec2-98ab-7e96807b32a6",
* "zone": "Pacific/Auckland",
* "kind": "n",
* "objectId": 123,
* "sourceId": "/power/1",
* "i": ["watts", "current", "voltage", "frequency"],
* "a": ["wattHours"]
* },
* {
* "streamId": "5514f762-2361-4ec2-98ab-7e96807b3255",
* "zone": "America/New_York",
* "kind": "n",
* "objectId": 456,
* "sourceId": "/irradiance/2",
* "i": ["irradiance", "temperature"],
* "a": ["irradianceHours"]
* }
* ]
* ```
*
* @return {string} the JSON encoded string
*/
toJsonEncoding() {
let json = "[";
for (let meta of this._metaList) {
if (json.length > 1) {
json += ",";
}
json += meta.toJsonEncoding();
}
json += "]";
return json;
}
/**
* Parse a JSON string into a {@link module:util~DatumStreamMetadataRegistry DatumStreamMetadataRegistry} instance.
*
* The JSON must be encoded the same way {@link module:util~DatumStreamMetadataRegistry#toJsonEncoding DatumStreamMetadataRegistry#toJsonEncoding()} does.
*
* @param {string} json the JSON to parse
* @returns {module:util~DatumStreamMetadataRegistry} the stream metadata registry instance
*/
static fromJsonEncoding(json) {
if (json) {
return this.fromJsonObject(JSON.parse(json));
}
return undefined;
}
/**
* Create a registry instance from an array parsed from a JSON string of datum stream metadata objects.
*
* The array must be structured in the same way {@link module:util~DatumStreamMetadataRegistry#toJsonEncoding DatumStreamMetadataRegistry#toJsonEncoding()} does.
*
* @param {array} data the array data to parse
* @returns {module:util~DatumStreamMetadataRegistry} the stream metadata registry instance
*/
static fromJsonObject(data) {
if (Array.isArray(data)) {
const reg = new DatumStreamMetadataRegistry();
for (let e of data) {
let meta = DatumStreamMetadata.fromJsonObject(e);
if (meta) {
reg.addMetadata(meta);
}
}
return reg;
}
return undefined;
}
}
export default DatumStreamMetadataRegistry;