fiftyone.pipeline.engines
Advanced tools
Comparing version 4.1.0 to 4.1.1
@@ -7,2 +7,5 @@ { | ||
}, | ||
"plugins": [ | ||
"jsdoc" | ||
], | ||
"extends": [ | ||
@@ -30,4 +33,21 @@ "standard" | ||
"always" | ||
] | ||
], | ||
"jsdoc/check-alignment": 1, | ||
"jsdoc/check-param-names": 1, | ||
"jsdoc/check-tag-names": 1, | ||
"jsdoc/check-types": 1, | ||
"jsdoc/implements-on-classes": 1, | ||
"jsdoc/newline-after-description": 1, | ||
"jsdoc/require-description": 1, | ||
"jsdoc/require-jsdoc": 1, | ||
"jsdoc/require-param": 1, | ||
"jsdoc/require-param-description": 1, | ||
"jsdoc/require-param-name": 1, | ||
"jsdoc/require-param-type": 1, | ||
"jsdoc/require-returns": 1, | ||
"jsdoc/require-returns-check": 1, | ||
"jsdoc/require-returns-description": 1, | ||
"jsdoc/require-returns-type": 1, | ||
"jsdoc/valid-types": 1 | ||
} | ||
} |
@@ -34,9 +34,18 @@ /* ********************************************************************* | ||
/** | ||
* Extension of elementData which allows for a missing property service | ||
* to be called when an accessed property isn't available. | ||
* Engines, an extension of flowElements also allow a restricted | ||
* property list so certain properties can be excluded | ||
**/ | ||
class AspectData extends ElementData { | ||
/** | ||
* Extension of elementData which allows for a missing property service to be called when an accessed property isn't available. engines, an extension of flowElements also allow a restricted property list so certain properties can be excluded | ||
* @param {Object} options | ||
* @param {FlowElement} options.flowElement | ||
* @param {MissingPropertyService} options.missingPropertyService | ||
*/ | ||
* Constructor for AspectData | ||
* | ||
* @param {object} options options object | ||
* @param {FlowElement} options.flowElement FlowElement the data is for | ||
* @param {MissingPropertyService} options.missingPropertyService | ||
* a missing property service to use when the property is in a | ||
* FlowElement's property list but not in the data | ||
*/ | ||
constructor ( | ||
@@ -54,5 +63,13 @@ { | ||
/** | ||
* The aspectData getter runs a series of actions if a property has / has not been found. If it hasn't been found it runs the missing property service if the property is referenced by the flowElement/engine. If the property is found a further check to see if it is restricted by a list passed into the flowElement/engine. | ||
* @param {String} key | ||
*/ | ||
* The aspectData getter runs a series of actions | ||
* if a property has / has not been found. | ||
* If it hasn't been found it runs the missing property | ||
* service if the property is referenced by the | ||
* flowElement/engine. If the property is found a further | ||
* check to see if it is restricted by a list passed | ||
* into the flowElement/engine. | ||
* | ||
* @param {string} key the property key to lookup | ||
* @returns {mixed} result | ||
*/ | ||
get (key) { | ||
@@ -73,3 +90,3 @@ let result; | ||
if (!this.flowElement.restrictedProperties.includes(key)) { | ||
throw 'Property ' + key + ' was excluded from ' + this.flowElement.dataKey; | ||
throw `Property ${key} was excluded from ${this.flowElement.dataKey}`; | ||
} | ||
@@ -76,0 +93,0 @@ } |
@@ -25,10 +25,18 @@ /* ********************************************************************* | ||
/** | ||
* Extension of elementDataDictionary which stores a | ||
* {key,value} dictionary of elements like elementDataDictionary | ||
* but with the additional aspectData extensions | ||
*/ | ||
class AspectDataDictionary extends AspectData { | ||
/** | ||
* Extension of elementDataDictionary which stores a {key,value} dictionary of elements like elementDataDictionary but with the additional aspectData extensions | ||
* @param {Object} options | ||
* @param {FlowElement} options.flowElement | ||
* @param {MissingPropertyService} options.missingPropertyService | ||
* @param {Object} options.contents | ||
*/ | ||
* Constructor for AspectDataDictionary | ||
* | ||
* @param {object} options options object | ||
* @param {FlowElement} options.flowElement FlowElement the data is for | ||
* @param {MissingPropertyService} options.missingPropertyService | ||
a missing property service to use when the property is in a | ||
* FlowElement's property list but not in the data | ||
* @param {object} options.contents the data to store | ||
*/ | ||
constructor ({ flowElement, contents, missingPropertyService }) { | ||
@@ -40,2 +48,14 @@ super(...arguments); | ||
* [Symbol.iterator] () { | ||
for (let i = 0; i < Object.keys(this.contents).length; i += 1) { | ||
yield Object.keys(this.contents)[i]; | ||
} | ||
} | ||
/** | ||
* getInternal retrieves a value from the dictionary | ||
* | ||
* @param {string} key property key | ||
* @returns {Mixed} property value | ||
*/ | ||
getInternal (key) { | ||
@@ -42,0 +62,0 @@ return this.contents[key]; |
@@ -25,4 +25,75 @@ /* ********************************************************************* | ||
/** | ||
* A datafile used by a FlowElement / Engine to get calculate properties values | ||
* | ||
* @param {object} options | ||
* @param {FlowElement} options.flowElement | ||
* The FlowElement using the datafile | ||
* @param {string} options.identifier | ||
* Name of the datafile | ||
* @param {object} options.updateURLParams | ||
* Parameters used to construct the datafile update url | ||
* if autoupdate is set to true | ||
* @param {string} options.tempDataDirectory | ||
* temporary file location (defaults to the operating system defualt) | ||
* @param {boolean} options.createTempDataCopy | ||
* whether to copy datafile to temporary location when updating | ||
* @param {mixed} options.data data, if the file is stored in memory | ||
* @param {string} options.path path to the datafile | ||
* @param {boolean} options.autoUpdate whether to automatically | ||
* update the datafile when required | ||
* @param {boolean} options.fileSystemWatcher | ||
* whether to check the datafile's path for changes and | ||
* update the connected FlowElement's data automatically | ||
* when the file is changed in the operating system | ||
* @param {number} options.pollingInterval How often to poll for | ||
* updates to the datafile (minutes) | ||
* @param {number} options.updateTimeMaximumRandomisation | ||
* Maximum randomisation offset in seconds to polling time interval | ||
* @param {boolean} options.verifyMD5 whether to check a 'content-md5' | ||
* header in the data file update service against the datafile | ||
* to verify its contents | ||
* @param {boolean} options.decompress is the datafile gziped | ||
* when returning from the update service? | ||
* @param {boolean} options.download should the datafile be | ||
* downloaded or stored in memory | ||
* @param {Function} options.getDatePublished function for getting | ||
* the published date of the datafile | ||
* @param {Function} options.getNextUpdate function for getting the | ||
* next available update from the datafile | ||
* @param {boolean} options.verifyIfModifiedSince whether to check | ||
* an "If-Modified-Since" header on the update service against | ||
* the last datafile update date | ||
* @param {boolean} options.updateOnStart whether to update the | ||
* datafile as soon as it is initialised | ||
* @param {boolean} options.isRegistered whether the datafile has already | ||
* been registered with a datafile update service (defaults to false) | ||
* @param {Function} options.refresh callback to call when datafile | ||
* has been updated. Defaults to a refresh method on the attached FlowElement | ||
* | ||
*/ | ||
class DataFile { | ||
constructor ({ flowElement, identifier, updateURLParams, tempDataDirectory = os.tmpdir(), createTempDataCopy = true, data, path, autoUpdate = true, fileSystemWatcher = true, pollingInterval = 30, updateTimeMaximumRandomisation = 10, verifyMD5 = true, decompress = true, download = true, getDatePublished, getNextUpdate, verifyIfModifiedSince = true, updateOnStart = false, isRegistered = false, refresh }) { | ||
constructor ( | ||
{ | ||
flowElement, | ||
identifier, | ||
updateURLParams, | ||
tempDataDirectory = os.tmpdir(), | ||
createTempDataCopy = true, | ||
data, | ||
path, | ||
autoUpdate = true, | ||
fileSystemWatcher = true, | ||
pollingInterval = 30, | ||
updateTimeMaximumRandomisation = 10, | ||
verifyMD5 = true, | ||
decompress = true, | ||
download = true, | ||
getDatePublished, | ||
getNextUpdate, | ||
verifyIfModifiedSince = true, | ||
updateOnStart = false, | ||
isRegistered = false, | ||
refresh | ||
}) { | ||
this.flowElement = flowElement; | ||
@@ -62,2 +133,10 @@ this.identifier = identifier; | ||
/** | ||
* Function called when datafile has been updated. | ||
* Defaults to a refresh method on the attached FlowElement | ||
* Can also be overriden by a refresh paramater in the | ||
* options of the constructor | ||
* | ||
* @param {string} identifier the identifier of the datafile | ||
*/ | ||
refresh (identifier) { | ||
@@ -67,2 +146,7 @@ this.flowElement.refresh(identifier); | ||
/** | ||
* Getter for the update url for the datafile update service to use | ||
* | ||
* @returns {string} url | ||
*/ | ||
get updateUrl () { | ||
@@ -72,2 +156,7 @@ return this.urlFormatter(); | ||
/** | ||
* Function that constructs the url for the datafile update service to use | ||
* | ||
* @returns {string} url | ||
*/ | ||
urlFormatter () { | ||
@@ -74,0 +163,0 @@ // by default just return the url |
@@ -32,3 +32,14 @@ /* ********************************************************************* | ||
/** | ||
* Datafiles attached to FlowElements register with | ||
* the dataFileUpdateService so the datafiles can receive | ||
* automatic updates | ||
**/ | ||
class DataFileUpdateService { | ||
/** | ||
* Constructor for a DataFileUpdateService | ||
* | ||
* @param {Pipeline} pipeline | ||
* pipeline the update service is attached to | ||
**/ | ||
constructor (pipeline) { | ||
@@ -38,2 +49,8 @@ this.pipeline = pipeline; | ||
/** | ||
* Method that updates a datafile when it is due an update | ||
* | ||
* @param {DataFile} dataFile the datafile to update | ||
* @returns {undefined} | ||
*/ | ||
updateDataFile (dataFile) { | ||
@@ -78,16 +95,34 @@ const dataFileUpdateService = this; | ||
case (429): | ||
dataFileUpdateService.pipeline.log('error', "Too many requests to '" + dataFile.updateUrl + "' for engine '" + | ||
dataFile.flowElement.dataKey + "'"); | ||
dataFileUpdateService.pipeline.log( | ||
'error', | ||
"Too many requests to '" + dataFile.updateUrl + | ||
"' for engine '" + | ||
dataFile.flowElement.dataKey + "'" | ||
); | ||
break; | ||
case (304): | ||
dataFileUpdateService.pipeline.log('warn', 'No data update available from ' + dataFile.updateUrl + "' for engine '" + | ||
dataFile.flowElement.dataKey + "'"); | ||
dataFileUpdateService.pipeline.log( | ||
'warn', | ||
'No data update available from ' + | ||
dataFile.updateUrl + | ||
"' for engine '" + | ||
dataFile.flowElement.dataKey + "'"); | ||
break; | ||
case (403): | ||
dataFileUpdateService.pipeline.log('error', 'Access denied from ' + dataFile.updateUrl + "' for engine '" + | ||
dataFile.flowElement.dataKey + "'"); | ||
dataFileUpdateService.pipeline.log('error', | ||
'Access denied from ' + | ||
dataFile.updateUrl + | ||
"' for engine '" + | ||
dataFile.flowElement.dataKey + "'" | ||
); | ||
break; | ||
default: | ||
dataFileUpdateService.pipeline.log('error', 'Error' + response.statusCode + ' from ' + dataFile.updateUrl + "' for engine '" + | ||
dataFile.flowElement.dataKey + "'"); | ||
dataFileUpdateService.pipeline.log( | ||
'error', | ||
'Error' + response.statusCode + | ||
' from ' + | ||
dataFile.updateUrl + | ||
"' for engine '" + | ||
dataFile.flowElement.dataKey + "'" | ||
); | ||
break; | ||
@@ -101,3 +136,5 @@ } | ||
const filename = dataFile.tempDataDirectory + '/' + dataFile.identifier + Date.now(); | ||
const filename = dataFile.tempDataDirectory + | ||
'/' + dataFile.identifier + | ||
Date.now(); | ||
@@ -120,3 +157,9 @@ response.pipe(fs.createWriteStream(filename)); | ||
if (hash.read() !== headerMD5) { | ||
dataFileUpdateService.pipeline.log('error', "MD5 doesn't match from '" + dataFile.updateUrl + "' for engine '" + dataFile.flowElement.dataKey + "'"); | ||
dataFileUpdateService.pipeline.log( | ||
'error', | ||
"MD5 doesn't match from '" + | ||
dataFile.updateUrl + | ||
"' for engine '" + | ||
dataFile.flowElement.dataKey + | ||
"'"); | ||
@@ -138,2 +181,10 @@ dataFile.updating = false; | ||
/** | ||
* Internal method called when the datafile has | ||
* been downloaded and is ready after an update | ||
* | ||
* @param {DataFile} dataFile the datafile that is ready | ||
* @param {string} filename the filename of the updated datafile | ||
* @returns {undefined} | ||
*/ | ||
fileReady (dataFile, filename) { | ||
@@ -168,2 +219,9 @@ const dataFileUpdateService = this; | ||
/** | ||
* Internal method to process the datafile has been downloaded | ||
* Including unzipping if needed | ||
* | ||
* @param {DataFile} dataFile the datafile to processs | ||
* @param {string} filename the filename of the downloaded data | ||
*/ | ||
processFile (dataFile, filename) { | ||
@@ -195,2 +253,8 @@ const dataFileUpdateService = this; | ||
/** | ||
* Internal method to check the next update of a | ||
* datafile at a polling interval set on the datafile | ||
* | ||
* @param {DataFile} dataFile the datafile to check updates for | ||
*/ | ||
checkNextUpdate (dataFile) { | ||
@@ -200,3 +264,8 @@ try { | ||
let interval = minToMs((Math.floor(Math.random() * dataFile.updateTimeMaximumRandomisation) + 1) + dataFile.pollingInterval); | ||
let interval = minToMs( | ||
(Math.floor(Math.random() * | ||
dataFile.updateTimeMaximumRandomisation) + | ||
1) + | ||
dataFile.pollingInterval | ||
); | ||
@@ -220,2 +289,7 @@ interval += dataFile.getNextUpdate().getMilliseconds(); | ||
/** | ||
* Method that registers a datafile with the update service | ||
* | ||
* @param {DataFile} dataFile the datafile to register | ||
*/ | ||
registerDataFile (dataFile) { | ||
@@ -222,0 +296,0 @@ dataFile.registered = true; |
@@ -23,7 +23,12 @@ /* ********************************************************************* | ||
/** | ||
* A simple cache getter that takes a cache key and | ||
* returns an element if it is found in the cache | ||
*/ | ||
class DataKeyedCache { | ||
/** | ||
* A simple cache getter that takes a cache key and returns an element if it is found in the cache | ||
* @param {Object} cachekey | ||
*/ | ||
* Get data out of the cache | ||
* | ||
* @param {Mixed} cachekey key to lookup in the cache | ||
*/ | ||
get (cachekey) { | ||
@@ -34,6 +39,7 @@ | ||
/** | ||
* Add an element to the cache | ||
* @param {Object} cachekey | ||
* @param {any} value | ||
*/ | ||
* Add an element to the cache | ||
* | ||
* @param {Mixed} cachekey key for the cache entry | ||
* @param {any} value value for the cache entry | ||
*/ | ||
put (cachekey, value) { | ||
@@ -40,0 +46,0 @@ |
@@ -35,13 +35,22 @@ /* ********************************************************************* | ||
/** | ||
* An Engine is an extension of a FlowElement which adds | ||
* options such as restricting to a subset of properties | ||
* and a cache and the ability to load property data | ||
* from a datafile of the DataFile class | ||
*/ | ||
class Engine extends FlowElement { | ||
/** | ||
* Constructor for engine class, extends flowElement with extra options | ||
* | ||
* @param {Object} options | ||
* @param {Cache} options.cache instance of a dataKeyedCache | ||
* @param {Array} options.restrictedProperties specific list of properties to fetch elementData for | ||
*/ | ||
* Constructor for an Engine | ||
* | ||
* @param {object} options options for the engine | ||
* @param {Datafile} options.dataFile an optional datafile | ||
* to add to the engine | ||
* @param {Cache} options.cache instance of a DataKeyedCache | ||
* @param {Array} options.restrictedProperties specific list | ||
* of properties to fetch elementData for | ||
*/ | ||
constructor ( | ||
{ | ||
cache, restrictedProperties | ||
cache, restrictedProperties, dataFile | ||
} = {} | ||
@@ -51,2 +60,6 @@ ) { | ||
if (dataFile) { | ||
this.registerDataFile(dataFile); | ||
} | ||
if (cache) { | ||
@@ -62,7 +75,11 @@ this.cache = cache; | ||
/** | ||
* Checks cache and returns cached result if found. | ||
* @param {FlowData} flowData | ||
*/ | ||
* Checks cache and returns cached result if found. | ||
* | ||
* @param {FlowData} flowData checks if a FlowData's evidence | ||
* is already in the cache and processing can be bypassed | ||
* @returns {boolean} whether in cache | ||
*/ | ||
inCache (flowData) { | ||
let keys = this.evidenceKeyFilter.filterEvidence(flowData.evidence.getAll()); | ||
let keys = this.evidenceKeyFilter | ||
.filterEvidence(flowData.evidence.getAll()); | ||
@@ -83,7 +100,11 @@ keys = JSON.stringify(keys); | ||
/** | ||
* An engine's process function checks cache for an item (calling inCache) | ||
* If found it returns the cached object | ||
* If not found it runs the standard processInternal function and adds it to the cache (if a cache is present) | ||
* @param {FlowData} flowData | ||
*/ | ||
* An engine's process function checks cache for an item | ||
* (calling inCache) | ||
* If found it returns the cached object | ||
* If not found it runs the standard processInternal function | ||
* and adds it to the cache (if a cache is present) | ||
* | ||
* @param {FlowData} flowData FlowData to process | ||
* @returns {undefined} result of processing | ||
*/ | ||
process (flowData) { | ||
@@ -100,3 +121,4 @@ const engine = this; | ||
if (engine.cache) { | ||
let keys = engine.evidenceKeyFilter.filterEvidence(flowData.evidence.getAll()); | ||
let keys = engine.evidenceKeyFilter | ||
.filterEvidence(flowData.evidence.getAll()); | ||
@@ -110,2 +132,8 @@ keys = JSON.stringify(keys); | ||
/** | ||
* Callback which runs when an attached DataFile is updated | ||
* Needs to be overriden by a specific engine to do anything | ||
* | ||
* @returns {void} | ||
*/ | ||
refresh () { | ||
@@ -115,2 +143,8 @@ return true; | ||
/** | ||
* Function to attach a DataFile to the engine and | ||
* register it with a DataFileUpdateService if needed | ||
* | ||
* @param {Datafile} dataFile the datafile to register | ||
*/ | ||
registerDataFile (dataFile) { | ||
@@ -117,0 +151,0 @@ this.registrationCallbacks.push(function (pipeline) { |
@@ -26,17 +26,16 @@ /* ********************************************************************* | ||
This example demonstrates how to add a cache to an aspect engine. The fiftyone.pipeline.engines module comes with an implementation of an lru cache. | ||
This example demonstrates how to add a cache to an aspect engine. | ||
The fiftyone.pipeline.engines module comes with an implementation | ||
of a Least Recently Used (lru) cache that can be used in | ||
place of the custom cache created in this example. | ||
To use this cache instead of a custom one use the lruCache class and pass in a size parameter for the size of the cache: | ||
To construct the lru cache pass in a size (in entries) | ||
parameter to its constructor. | ||
``` | ||
const engine = require("fiftyone.pipeline.engines"); | ||
let lruCache = new engine.lruCache(100); | ||
``` | ||
*/ | ||
*/ | ||
const pipeline = require('fiftyone.pipeline.core'); | ||
const pipeline = require('fiftyone.pipeline.core'); | ||
// Note that this example is designed to be run from within the | ||
@@ -59,2 +58,4 @@ // source repository. If this code has been copied to run standalone | ||
if (this.cache[cachekey]) { | ||
// Log out whether something has been fetched | ||
// from cache to demonstrate the example | ||
console.log('Fetched from cache'); | ||
@@ -70,3 +71,5 @@ return this.cache[cachekey]; | ||
// A custom engine to test the caching, note the instance of the evidenceKeyFilter class which is used to determine which evidence is used by the flowElement and in turn the pipeline. | ||
// A custom engine to test the caching, note the instance of the | ||
// evidenceKeyFilter class which is used to determine which evidence | ||
// is used by the flowElement and in turn the pipeline. | ||
@@ -76,3 +79,4 @@ const cacheTest = new engine.Engine({ | ||
cache: new MyCustomCache(), | ||
evidenceKeyFilter: new pipeline.BasicListEvidenceKeyFilter(['cookie.my-user-id']), | ||
evidenceKeyFilter: new pipeline | ||
.BasicListEvidenceKeyFilter(['cookie.my-user-id']), | ||
processInternal: function (flowData) { | ||
@@ -82,3 +86,5 @@ const engine = this; | ||
return new Promise(function (resolve, reject) { | ||
const data = new pipeline.ElementDataDictionary({ flowElement: engine, contents: { hello: 'world' } }); | ||
const data = new pipeline | ||
.ElementDataDictionary( | ||
{ flowElement: engine, contents: { hello: 'world' } }); | ||
@@ -107,6 +113,4 @@ flowData.setElementData(data); | ||
processFlowDataWithUserId('112'); | ||
setTimeout(function () { | ||
processFlowDataWithUserId('112'); | ||
}, 100); | ||
// Run the same evidence through the pipeline twice, | ||
// second time should be fetched from the cache | ||
processFlowDataWithUserId('112').then(() => processFlowDataWithUserId('112')); |
@@ -32,3 +32,3 @@ /* ********************************************************************* | ||
*/ | ||
*/ | ||
@@ -42,3 +42,4 @@ // Require the filesystem module for datafile reading | ||
// Next require the engines extension that extends flowElements to support | ||
// functionality such as auto updating datafiles, caches and missing property services | ||
// functionality such as auto updating datafiles, | ||
// caches and missing property services | ||
@@ -62,7 +63,16 @@ // Note that this example is designed to be run from within the | ||
// starsigns to see it update | ||
this.dataFile = new FiftyOnePipelineEngines.DataFile({ flowElement: this, path: datafile, autoUpdate: false, fileSystemWatcher: true }); | ||
this.dataFile = new FiftyOnePipelineEngines | ||
.DataFile( | ||
{ | ||
flowElement: this, | ||
path: datafile, | ||
autoUpdate: false, | ||
fileSystemWatcher: true | ||
} | ||
); | ||
this.registerDataFile(this.dataFile); | ||
// datakey used to categorise data coming back from this flowElement in a pipeline | ||
// datakey used to categorise data coming back from | ||
// this flowElement in a pipeline | ||
this.dataKey = 'astrology'; | ||
@@ -72,3 +82,4 @@ | ||
// flowElement is interested in, in this case a query string | ||
this.evidenceKeyFilter = new FiftyOnePipelineCore.BasicListEvidenceKeyFilter(['query.dateOfBirth']); | ||
this.evidenceKeyFilter = new FiftyOnePipelineCore | ||
.BasicListEvidenceKeyFilter(['query.dateOfBirth']); | ||
@@ -78,8 +89,5 @@ // Update the datafile | ||
} | ||
//! [constructor] | ||
// A function called when the datafile is updated / refreshed. In this | ||
// case it simply loads the JSON from the file into the engine's memory. | ||
//! [refresh] | ||
refresh () { | ||
@@ -95,3 +103,4 @@ const engine = this; | ||
// Load the datafile into memory and parse it to make it more easily readable | ||
// Load the datafile into memory and parse it to make it | ||
// more easily readable | ||
data = data.map(function (e) { | ||
@@ -101,3 +110,9 @@ const start = e[1].split('/'); | ||
return { starsign: e[0], startMonth: parseInt(start[1]), startDate: parseInt(start[0]), endMonth: parseInt(end[1]), endDate: parseInt(end[0]) }; | ||
return { | ||
starsign: e[0], | ||
startMonth: parseInt(start[1]), | ||
startDate: parseInt(start[0]), | ||
endMonth: parseInt(end[1]), | ||
endDate: parseInt(end[0]) | ||
}; | ||
}); | ||
@@ -108,3 +123,2 @@ | ||
} | ||
//! [refresh] | ||
@@ -150,3 +164,4 @@ // Internal processing function | ||
// Save the data into an extension of the elementData class (in this case a simple dictionary subclass) | ||
// Save the data into an extension of the elementData class | ||
// (in this case a simple dictionary subclass) | ||
const data = new FiftyOnePipelineCore.ElementDataDictionary({ | ||
@@ -160,6 +175,6 @@ flowElement: this, contents: result | ||
} | ||
//! [class] | ||
//! [usage] | ||
const astrologyElement = new Astrology({ datafile: (process.env.directory || __dirname) + '/astrology.json' }); | ||
const astrologyElement = new Astrology( | ||
{ datafile: (process.env.directory || __dirname) + '/astrology.json' } | ||
); | ||
@@ -175,3 +190,4 @@ const http = require('http'); | ||
// Add any information from the request (headers, cookies and additional client side provided information) | ||
// Add any information from the request | ||
// (headers, cookies and additional client side provided information) | ||
flowData.evidence.addFromRequest(req); | ||
@@ -186,5 +202,13 @@ | ||
${flowData.astrology.starSign ? '<p>Your starsign is ' + flowData.astrology.starSign + ' </p>' : '<p>Add your date of birth to get your starsign</p>'} | ||
${flowData.astrology.starSign | ||
? '<p>Your starsign is ' + | ||
flowData.astrology.starSign + ' </p>' | ||
: '<p>Add your date of birth to get your starsign</p>' | ||
} | ||
<form><label for='dateOfBirth'>Date of birth</label><input type='date' name='dateOfBirth' id='dateOfBirth'><input type='submit'></form> | ||
<form> | ||
<label for='dateOfBirth'>Date of birth</label> | ||
<input type='date' name='dateOfBirth' id='dateOfBirth'> | ||
<input type='submit'> | ||
</form> | ||
@@ -202,2 +226,1 @@ `; | ||
server.listen(portNum); | ||
//! [usage] |
@@ -26,3 +26,12 @@ /* ********************************************************************* | ||
/** | ||
* An instance of DataKeyed cache using a least recently used (LRU) method | ||
**/ | ||
class LRUcache extends DataKeyedCache { | ||
/** | ||
* Constructor for LRUcache | ||
* | ||
* @param {object} options options for the lru cache | ||
* @param {number} options.size maximum entries in the cache | ||
*/ | ||
constructor ({ size = 100 }) { | ||
@@ -29,0 +38,0 @@ super(...arguments); |
@@ -23,8 +23,16 @@ /* ********************************************************************* | ||
/** | ||
* Base class for a missing property service that throws | ||
* an error if the property is not available for some reason | ||
**/ | ||
class MissingPropertyService { | ||
/** | ||
* Simple base class for a missing property service that returns an error if the property is not available for some reason | ||
* @param {String} elementData key | ||
* @param {flowElement} flowElement | ||
*/ | ||
* Check is called if a property is requested that exists | ||
* in the FlowElement property list but is not available | ||
* in the AspectData returned by the FlowElement | ||
* | ||
* @param {string} key property key | ||
* @param {flowElement} flowElement flowelement the data | ||
* was requested in | ||
*/ | ||
check (key, flowElement) { | ||
@@ -31,0 +39,0 @@ throw 'Property ' + key + ' not found in ' + flowElement.dataKey; |
{ | ||
"name": "fiftyone.pipeline.engines", | ||
"version": "4.1.0", | ||
"version": "4.1.1", | ||
"description": "Shared base functionality for implementing engines for the 51Degrees Pipeline API", | ||
@@ -5,0 +5,0 @@ "main": "index.js", |
@@ -55,7 +55,13 @@ /* ********************************************************************* | ||
test('caching example', () => { | ||
testExample({ file: __dirname + '/../examples/caching.js' }); | ||
testExample( | ||
{ file: __dirname + '/../examples/caching.js' } | ||
); | ||
}); | ||
test('on premise flow element example', () => { | ||
testExample({ file: __dirname + '/../examples/onPremiseFlowElement.js', portNumber: 3002 }); | ||
testExample( | ||
{ | ||
file: __dirname + '/../examples/onPremiseFlowElement.js', | ||
portNumber: 3002 | ||
}); | ||
}); |
@@ -24,5 +24,11 @@ /* ********************************************************************* | ||
const Engine = require(__dirname + '/../engine'); | ||
const PipelineBuilder = require(__dirname + '/../../fiftyone.pipeline.core/pipelineBuilder'); | ||
const AspectDataDictionary = require(__dirname + '/../aspectDataDictionary'); | ||
const BasicListEvidenceKeyFilter = require(__dirname + '/../../fiftyone.pipeline.core/basicListEvidenceKeyFilter'); | ||
const PipelineBuilder = require( | ||
__dirname + '/../../fiftyone.pipeline.core/pipelineBuilder' | ||
); | ||
const AspectDataDictionary = require( | ||
__dirname + '/../aspectDataDictionary' | ||
); | ||
const BasicListEvidenceKeyFilter = require( | ||
__dirname + '/../../fiftyone.pipeline.core/basicListEvidenceKeyFilter' | ||
); | ||
const LruCache = require(__dirname + '/../lruCache'); | ||
@@ -61,3 +67,5 @@ | ||
const data = new AspectDataDictionary({ flowElement: this, contents: contents }); | ||
const data = new AspectDataDictionary( | ||
{ flowElement: this, contents: contents } | ||
); | ||
@@ -64,0 +72,0 @@ flowData.setElementData(data); |
@@ -25,7 +25,15 @@ /* ********************************************************************* | ||
/** | ||
* A tracker is an instance of datakeyed cache which, | ||
* if a result is found in the cache, calls an additional | ||
* boolean match method | ||
*/ | ||
class Tracker extends DataKeyedCache { | ||
/** | ||
* The track method calls the dataKeyedCache get method, if it receives a result it sends it onto a match function | ||
* @param {Object} cachekey | ||
*/ | ||
* The track method calls the dataKeyedCache get method, | ||
* if it receives a result it sends it onto a match function | ||
* | ||
* @param {mixed} key cache key to run through tracker | ||
* @returns {boolean} result of tracking | ||
*/ | ||
track (key) { | ||
@@ -42,5 +50,7 @@ const result = this.get(key); | ||
/** | ||
* If object is found in cache, the match function is called | ||
* @param {Object} result | ||
*/ | ||
* If object is found in cache, the match function is called | ||
* | ||
* @param {object} result of the track function | ||
* @returns {Boolen} whether a match has been made | ||
*/ | ||
match (result) { | ||
@@ -47,0 +57,0 @@ return true; |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Unidentified License
License(Experimental) Something that seems like a license was found, but its contents could not be matched with a known license.
Found 5 instances in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Unidentified License
License(Experimental) Something that seems like a license was found, but its contents could not be matched with a known license.
Found 1 instance in 1 package
56068
1544
11
60