hop-query-builder
Version:
utility library for HOP queries
648 lines (628 loc) • 24.9 kB
JavaScript
'use strict'
/**
* HOP query builder library
*
*
* @class HopQuerybuilder
* @package HOP-query-builder
* @copyright Copyright (c) 2023 James Littlejohn
* @license http://www.gnu.org/licenses/old-licenses/gpl-3.0.html
* @version $Id$
*/
import EventEmitter from 'events'
import LibComposer from 'librarycomposer'
import util from 'util'
class HopQuerybuilder extends EventEmitter {
constructor() {
super()
this.libComposer = new LibComposer()
this.modulesStart = this.modulesGenesis()
}
/**
* Prepare module contracts for different entry paths
* @method queryPath
*
*/
queryPath = function (beebeeIN, publicLib, fileInfo) {
let formSFquery = {}
if (beebeeIN.action === 'blind') {
formSFquery = this.blindPath(beebeeIN, publicLib, fileInfo)
} else if (beebeeIN.action === 'library') {
formSFquery = this.libraryPath()
} else if (beebeeIN.action === 'future') {
formSFquery = this.futurePath(beebeeIN, publicLib, fileInfo)
}
return formSFquery
}
/**
* Prepare module contracts for different entry paths
* @method blindPath
*
*/
blindPath = function (beebeeIN, publicLib, fileInfo) {
// console.log(util.inspect(beebeeIN, {showHidden: false, depth: null}))
let minStartlist = this.minModulesetup()
// take the genesis and make new instances of the Module Contracts i.e. unique keys
let tempModContracts = this.tempModuleContractsCreate(minStartlist, fileInfo)
// extract data, compute and visualisation ref contracts
let contractsPublic = this.splitMCfromRC(publicLib)
// extract out observaation compute and charting ref contracts, data more work required, need save data and then create new data packaging contract
let extractedRefs = this.extractRefContractsPublicLib(beebeeIN.data.data.input.data, contractsPublic.reference, fileInfo)
// need to make refContract question and data packaging (for blind question input from beebee Done above)
// next assume joined so provide finalised structure for SF-ECS
let tempRefContsSF = this.prepareSafeFlowStucture(tempModContracts, extractedRefs, fileInfo, beebeeIN)
return tempRefContsSF
}
/**
* library query builder
* @method libraryPath
*
*/
libraryPath = function (path, action, data) {
let libraryData = {}
libraryData.data = 'contracts'
libraryData.type = 'peerprivate'
const segmentedRefContracts = this.libComposer.liveRefcontUtility.refcontractSperate(data)
libraryData.referenceContracts = segmentedRefContracts
// need to split for genesis and peer joined NXPs
const nxpSplit = this.libComposer.liveRefcontUtility.experimentSplit(segmentedRefContracts.experiment)
libraryData.splitExperiments = nxpSplit
// look up modules for this experiments
libraryData.networkExpModules = this.libComposer.liveRefcontUtility.expMatchModuleGenesis(libraryData.referenceContracts.module, nxpSplit.genesis)
libraryData.networkPeerExpModules = this.libComposer.liveRefcontUtility.expMatchModuleJoined(libraryData.referenceContracts.module, nxpSplit.joined)
return libraryData
}
/**
* future model prediction query
* @method futurePath
*
*/
futurePath = function (beebeeIN, publicLib, fileInfo) {
// prepare SafeFlow future query i.e. update type with compute contract updated
let futureQuery = {}
// need to replace past compute reference contract with the future linear regression ref. contract.
let nxpKey = Object.keys(beebeeIN.data)
// extract the compute contract and make prediction model e.g. linear regression
let computeContract = {}
for (let mod of beebeeIN.data[nxpKey[0]].modules) {
if (mod.value.style === 'compute') {
computeContract = mod
}
}
let computeRefFuture = computeContract
// let refContractfuture = computeContract.value.info.compute[0].value
let refCdetails = {}
refCdetails.name = 'linear-regression',
refCdetails.description = 'statistical prediction model',
refCdetails.primary = 'yes',
refCdetails.dtprefix = 'f-f491adb5f30b32f078d8dbc235b0e849265cca',
refCdetails.code = 'simple-statistics',
refCdetails.hash = 'gh-12121212112'
computeRefFuture.value.info.compute[0].value.computational = refCdetails
// update time range for future
let futureDate = new Date()
// Add five days to current date
futureDate.setDate(futureDate.getDate() + 30)
futureDate = futureDate.getTime()
let controls = { xaxis: '', yaxis: [ 'blind1234555554321' ], date: computeRefFuture.value.info.controls.date, rangedate: [ computeRefFuture.value.info.controls.date ], sourceTime: [ futureDate ] }
computeRefFuture.value.info.controls = controls
// prepare new compute reference contract
computeRefFuture.key = '2233344455566'
// computeRefFuture.value = computeRefFuture
// replace past compute contract with future
let updatedModules = []
for (let mod of beebeeIN.data[nxpKey[0]].modules) {
if (mod.value.type === 'compute') {
updatedModules.push(computeRefFuture)
} else {
updatedModules.push(mod)
}
}
let updateSF = {}
updateSF.input = 'future'
updateSF.exp = { key: nxpKey[0], value: {} }
updateSF.entityUUID = beebeeIN.data[nxpKey[0]].shellID
updateSF.modules = updatedModules
updateSF.update = 'predict-future'
futureQuery.exp = { key: nxpKey[0], value: {} }
futureQuery.update = updateSF
// futureQuery.modules = beebeeIN.data[nxpKey[0]].modules
return futureQuery
}
/**
* four min modules required to start NXP with
* @method minModulesetup
*
*/
minModulesetup = function (beebeeIN, publicLib, fileInfo) {
let ModulesMinrequired = ['question', 'packaging', 'compute', 'visualise']
let minStartlist = []
for (const mtype of ModulesMinrequired) {
let match = this.modulesStart.data.filter(e => e.style === mtype)
minStartlist.push(match[0])
}
return minStartlist
}
/**
* accept query, start conversation process
* @method queryInputs
*
*/
queryInputs = async function (contractBoth) {
let safeFlowquery = {}
if (contractBoth.action === 'tempmodule') {
// create new temp JOIN modules from network
let prepareJoinStrucutre = this.joinStructurePrep(contractBoth.data)
// make list of Module Contract in array
let moduleList = []
for (let mod of prepareJoinStrucutre) {
moduleList.push(mod.key)
}
let ECSbundle = {}
// npx contract UUID-temp see structure at https://design.penpot.app/#/view/e8b3498a-41f9-8006-8001-7af986efdd68?page-id=279589f6-a428-8012-8001-fee517df51ef§ion=interactions&index=0
// array of expanded modules
// structure NXP to send to HOP
ECSbundle.exp = { key: '1bbeba0fe1723c75447e41a94126d654760537b6', value: {}}
ECSbundle.exp.value.refcontract = "experiment"
ECSbundle.exp.value.computational = {}
ECSbundle.exp.value.concept = { state: 'joined' }
ECSbundle.exp.value.modules = moduleList
ECSbundle.exp.value.space = { concept: 'mind' }
// the modules expanded in an array
ECSbundle.modules = prepareJoinStrucutre
safeFlowquery.type = 'safeflow'
safeFlowquery.reftype = 'ignore'
safeFlowquery.action = 'networkexperiment'
safeFlowquery.data = ECSbundle
} else if (query.action === 'genesis') {
let moduleGenesisList = []
let moduleGenesisExpanded = []
let newModCount = message.data.length
for (let mh of message.data) {
const moduleRefContract = this.liveComposer.moduleComposer(mh, '')
// const moduleRefContractReady = JSON.stringify(moduleRefContract)
const savedFeedback = await this.liveHolepunch.BeeData.savePubliclibrary(moduleRefContract)
moduleGenesisList.push(savedFeedback.key)
// stand key value format or query and get back ref contract double check TODO
let moduleContract = {}
moduleContract.key = savedFeedback.key
moduleContract.value = savedFeedback.contract
moduleGenesisExpanded.push(moduleContract) // .contract)
newModCount--
}
if (newModCount === 0) {
// aggregate all modules into exeriment contract
let genesisRefContract = this.libComposer.experimentComposerGenesis(moduleGenesisList)
// double check they are created
const savedFeedback = await this.liveHolepunch.BeeData.savePubliclibrary(genesisRefContract)
savedFeedback.expanded = moduleGenesisExpanded
}
} else if (contractBoth.action === 'update') {
}
return safeFlowquery
}
/**
* adjust structure for library composer
* @method joinStructurePrep
*
*/
joinStructurePrep = function (contracts) {
let newModCount = 4
let moduleJoinedExpanded = []
let peerModules = {}
for (let mh of contracts.modules) {
// prepare new modules for this peer ledger
if (mh.value.info.moduleinfo.name === 'question') {
peerModules.question = mh.value.info.question
} else if (mh.value.info.moduleinfo.name === 'packaging') {
peerModules.type = 'data'
peerModules.data = mh.value.info
} else if (mh.value.info.moduleinfo.name === 'compute') {
peerModules.type = 'compute'
peerModules.compute = mh.value.info.refcont
peerModules.controls = mh.value.info.option // mh.data.options.compute
peerModules.settings = mh.value.info.option // mh.data.options.visualise
} else if (mh.value.info.moduleinfo.name === 'visualise') {
peerModules.type = 'visualise'
peerModules.visualise = mh.value.info.refcont
peerModules.settings = mh.value.info.option // mh.data.options.visualise
}
let moduleRefContract = this.libComposer.liveComposer.moduleComposer(peerModules, 'join')
// key value structure
let modFormat = {}
modFormat.key = moduleRefContract.data.hash
modFormat.value = moduleRefContract.data.contract
moduleJoinedExpanded.push(modFormat)
newModCount--
}
// check all modules are present and create peers network refcont joined
if (newModCount === 0) {
// aggregate all modules into exeriment contract
// double check they are created
let joinRefContract = this.libComposer.liveComposer.experimentComposerJoin(moduleJoinedExpanded)
}
return moduleJoinedExpanded
}
/**
* Module Contract Available to network
* @method modulesGenesis
*
*/
modulesGenesis = function () {
const moduleContracts = []
const dataCNRLbundle = {}
// CNRL implementation contract e.g. from mobile phone sqlite table structure
dataCNRLbundle.reftype = 'module'
dataCNRLbundle.style = 'question'
dataCNRLbundle.primary = 'genesis'
dataCNRLbundle.description = 'Question for network experiment'
dataCNRLbundle.concept = ''
dataCNRLbundle.grid = []
moduleContracts.push(dataCNRLbundle)
// CNRL implementation contract e.g. from mobile phone sqlite table structure
const dataCNRLbundle2 = {}
dataCNRLbundle2.reftype = 'module'
dataCNRLbundle2.style = 'packaging'
dataCNRLbundle2.primary = 'genesis'
dataCNRLbundle2.description = 'data source(s) for network experiment'
dataCNRLbundle2.grid = []
moduleContracts.push(dataCNRLbundle2)
// CNRL implementation contract e.g. from mobile phone sqlite table structure
/* const dataCNRLbundle3 = {}
dataCNRLbundle3.reftype = 'module'
dataCNRLbundle3.style = 'device'
dataCNRLbundle3.primary = 'genesis'
dataCNRLbundle3.concept = ''
dataCNRLbundle3.grid = []
moduleContracts.push(dataCNRLbundle3) */
// CNRL implementation contract e.g. from mobile phone sqlite table structure
/* const dataCNRLbundle4 = {}
dataCNRLbundle4.reftype = 'module'
dataCNRLbundle4.style = 'mobile'
dataCNRLbundle4.primary = 'genesis'
dataCNRLbundle4.concept = ''
dataCNRLbundle4.grid = []
moduleContracts.push(dataCNRLbundle4) */
// module ref contract utility type
const dataCNRLbundle6 = {}
dataCNRLbundle6.reftype = 'module'
dataCNRLbundle6.style = 'compute'
dataCNRLbundle6.primary = 'genesis'
dataCNRLbundle6.concept = ''
dataCNRLbundle6.grid = []
dataCNRLbundle6.dtcompute = []
dataCNRLbundle6.dtresult = []
dataCNRLbundle6.category = []
dataCNRLbundle6.compute = ''
dataCNRLbundle6.controlpanel = []
dataCNRLbundle6.automation = false
dataCNRLbundle6.time = { realtime: 0, timeseg: [], startperiod: '' }
moduleContracts.push(dataCNRLbundle6)
// CNRL implementation contract e.g. from mobile phone sqlite table structure
const dataCNRLbundle5 = {}
dataCNRLbundle5.reftype = 'module'
dataCNRLbundle5.style = 'visualise'
dataCNRLbundle5.primary = 'genesis'
dataCNRLbundle5.grid = []
moduleContracts.push(dataCNRLbundle5)
// CNRL implementation contract e.g. from mobile phone sqlite table structure
const dataCNRLbundle7 = {}
dataCNRLbundle7.reftype = 'module'
dataCNRLbundle7.style = 'education'
dataCNRLbundle7.primary = 'genesis'
dataCNRLbundle7.concept = ''
dataCNRLbundle7.grid = []
moduleContracts.push(dataCNRLbundle7)
/* const dataCNRLbundle8 = {}
dataCNRLbundle8.reftype = 'module'
dataCNRLbundle8.style = 'lifestyle'
dataCNRLbundle8.primary = 'genesis'
dataCNRLbundle8.concet = ''
dataCNRLbundle8.grid = []
moduleContracts.push(dataCNRLbundle8) */
/* const dataCNRLbundle9 = {}
dataCNRLbundle9.reftype = 'module'
dataCNRLbundle9.style = 'error'
dataCNRLbundle9.primary = 'genesis'
dataCNRLbundle9.concept = ''
dataCNRLbundle9.grid = []
moduleContracts.push(dataCNRLbundle9) */
/* const dataCNRLbundle10 = {}
dataCNRLbundle10.reftype = 'module'
dataCNRLbundle10.style = 'control'
dataCNRLbundle10.primary = 'genesis'
dataCNRLbundle10.concept = ''
dataCNRLbundle10.grid = []
moduleContracts.push(dataCNRLbundle10) */
const dataCNRLbundle11 = {}
dataCNRLbundle11.reftype = 'module'
dataCNRLbundle11.style = 'prescription'
dataCNRLbundle11.primary = 'genesis'
dataCNRLbundle11.concept = ''
dataCNRLbundle11.grid = []
moduleContracts.push(dataCNRLbundle11)
/* const dataCNRLbundle12 = {}
dataCNRLbundle12.reftype = 'module'
dataCNRLbundle12.style = 'communication'
dataCNRLbundle12.primary = 'genesis'
dataCNRLbundle12.concept = ''
dataCNRLbundle12.grid = []
moduleContracts.push(dataCNRLbundle12) */
// CNRL implementation contract e.g. from mobile phone sqlite table structure
/* const dataCNRLbundle13 = {}
dataCNRLbundle13.reftype = 'module'
dataCNRLbundle13.style = 'idea'
dataCNRLbundle13.primary = 'genesis'
dataCNRLbundle13.concept = ''
dataCNRLbundle13.grid = []
moduleContracts.push(dataCNRLbundle13) */
const dataCNRLbundle14 = {}
dataCNRLbundle14.reftype = 'module'
dataCNRLbundle14.style = 'rhino'
dataCNRLbundle14.primary = 'genesis'
dataCNRLbundle14.concept = ''
dataCNRLbundle14.grid = []
moduleContracts.push(dataCNRLbundle14)
const dataCNRLbundle15 = {}
dataCNRLbundle15.reftype = 'module'
dataCNRLbundle15.style = 'pricing'
dataCNRLbundle15.primary = 'genesis'
dataCNRLbundle15.concept = ''
dataCNRLbundle15.grid = []
moduleContracts.push(dataCNRLbundle15)
let genesisModules = {}
genesisModules.action = 'tempmodule'
genesisModules.data = moduleContracts
return genesisModules
}
/**
* Module Contract Available to network
* @method tempModuleContractsCreate
*
*/
tempModuleContractsCreate = function (gMods, file) {
// create new temp modules for new experiment
let modCount = 1
let moduleHolder = []
for (const mc of gMods) {
// make question unique
if (mc.style === 'question') {
mc.description = mc.description + file
}
mc.value = mc.style
const prepareModule = this.libComposer.liveComposer.moduleComposer(mc, '')
let moduleContainer = {}
moduleContainer.name = prepareModule.data.contract.style
moduleContainer.id = modCount
moduleContainer.refcont = prepareModule.data.hash
moduleHolder.push(moduleContainer)
modCount++
}
return moduleHolder
}
/**
* Module Contract Available to network
* @method splitMCfromRC
*
*/
splitMCfromRC = function (publicLib) {
// split into Module Contracts and Reference Contracts
let modContracts = []
let refContracts = []
for (let pubLib of publicLib) {
if (pubLib?.value?.refcontract === 'module') {
modContracts.push(pubLib)
} else {
refContracts.push(pubLib)
}
}
let contractList = {}
contractList.modules = modContracts
contractList.reference = refContracts
return contractList
}
/**
* Build blind reference contracts
* @method extractRefContractsPublicLib
*
*/
extractRefContractsPublicLib = function (computeContext, refContracts, fileName) {
let refBuilds = []
for (let rc of refContracts) {
if (rc?.value?.refcontract === 'compute' && rc?.value?.computational.name === computeContext.compute) {
refBuilds.push(rc)
} else if (rc?.value?.refcontract === 'visualise' || rc?.value?.computational?.name === 'chart.js library') {
refBuilds.push(rc)
}
}
// need to build a custom data packaging ref contract
const newPackagingMap = {}
newPackagingMap.name = fileName
newPackagingMap.description = fileName
newPackagingMap.primary = 'true'
newPackagingMap.api = 'json'
newPackagingMap.path = 'json'
newPackagingMap.apibase = ''
newPackagingMap.apipath = ''
newPackagingMap.filename = fileName + '.json'
newPackagingMap.sqlitetablename = ''
newPackagingMap.tablestructure = []
newPackagingMap.tidy = {}
newPackagingMap.category = {}
newPackagingMap.devicesList = ''
newPackagingMap.deviceColumns = ''
newPackagingMap.devicequery = ''
newPackagingMap.firmwarequery = ''
newPackagingMap.deviceColumnID = ''
// device peer input
let deviceInfo = {}
deviceInfo.id = fileName
deviceInfo.device_name = fileName
deviceInfo.device_manufacturer = ''
deviceInfo.device_mac = fileName
deviceInfo.device_type = 'blind'
deviceInfo.device_model = ''
deviceInfo.query = ''
deviceInfo.location_lat = 0
deviceInfo.location_long = 0
deviceInfo.firmware = ''
deviceInfo.mobileapp = ''
newPackagingMap.device = deviceInfo
// need to match info to reference data types
newPackagingMap.apicolumns = {}
newPackagingMap.apicolHolder = {}
let packagingRef = this.libComposer.liveComposer.packagingRefLive.packagingBlindPrepare(newPackagingMap)
const dtHASH = this.libComposer.liveComposer.cryptoLive.evidenceProof(packagingRef)
let contractData = {}
contractData.key = dtHASH
contractData.value = packagingRef
refBuilds.push(contractData)
// need to create question as blind done via module?
let questionBlind = {}
questionBlind.forum = ''
questionBlind.text = fileName
return refBuilds
}
/**
* prepare blind query for SafeFlow
* @method prepareSafeFlowStucture
*
*/
prepareSafeFlowStucture = function (moduleContracts, refContracts, fileInfo, LLMdata) {
// console.log(util.inspect(refContracts, {showHidden: false, depth: null}))
let safeFlowQuery = {}
let modContracts = []
let modKeys = []
for (let mc of moduleContracts) {
modKeys.push(mc.refcont)
}
// which settings from LLM?
let visStyle = 'line' //LLMdata.data.data.visstyle[0].vis
// form a joined contract, pass in module key only
let formExpmoduleContract = this.libComposer.liveComposer.experimentComposerJoin(modKeys)
safeFlowQuery.exp = {}
safeFlowQuery.exp.key = formExpmoduleContract.data.hash
safeFlowQuery.exp.value = formExpmoduleContract.data.contract
// this needs to be save in Holepunch to update structure to keys
// next need to add reference Contracts to Module Contracts in correct format
let joinStructureMC = {}
joinStructureMC.key = ''
joinStructureMC.value = {info: {}, refcontract: 'module', style: 'packaging'}
// info structure
// let info = {}
// e.g. info.data = { key value } change data for name of contracts (is this good decision???)
// info.type = 'data
// need to form joined modle contract with expaneded to include reference contract
// structure needs to be modIn.type modIn.data = temMC with refcontract embedded
for (let tmc of moduleContracts) {
let inputStructure = {}
if(tmc.name === 'question') {
inputStructure.style = 'question'
let dataMCRC = {}
dataMCRC.question = { forum: '', text: fileInfo }
inputStructure.value = {}
inputStructure.value.style = 'question'
inputStructure.value.info = dataMCRC
} else if(tmc.name === 'packaging') {
let dataMCRC = {}
let extractRC = refContracts.filter(e => e.value.refcontract === 'packaging')
dataMCRC = extractRC[0] // data packaging contract
inputStructure.style = 'packaging'
inputStructure.value = {}
inputStructure.value.style = 'packaging'
inputStructure.value.info = dataMCRC
} else if (tmc.name === 'compute') {
let dataMCRC = {};
let extractRC = refContracts.filter(e =>
e.value.refcontract === 'compute' &&
e.value.computational?.name === LLMdata.data.data.input.data.compute
)
// Create compute contract structure with type
dataMCRC.computational = extractRC[0].value.computational
dataMCRC.compute =
{
key: extractRC[0].key,
value: {
refcontract: 'compute',
concept: extractRC[0].value.concept,
computational: {
name: extractRC[0].value.computational.name,
type: extractRC[0].value.computational.type,
description: extractRC[0].value.computational.description,
code: extractRC[0].value.computational.code,
hash: extractRC[0].value.computational.hash,
mode: extractRC[0].value.computational.mode
}
}
}
// Add settings and controls
let currentQtime = new Date();
const blindDate = currentQtime.getTime();
dataMCRC.controls = {
xaxis: '',
yaxis: ['blind1234555554321'],
date: blindDate,
rangedate: [blindDate],
category: ['none'],
tidy: true
};
dataMCRC.settings = {
devices: [],
data: null,
compute: '',
visualise: visStyle,
category: ['none'],
timeperiod: '',
xaxis: '',
yaxis: ['blind1234555554321'],
resolution: '',
setTimeFormat: ''
};
inputStructure.style = 'compute';
inputStructure.value = {};
inputStructure.value.style = 'compute';
inputStructure.value.info = dataMCRC;
} else if (tmc.name === 'visualise') {
let dataMCRC = {}
let extractRC = refContracts.filter(e => e.value.refcontract === 'visualise')
dataMCRC.visualise = extractRC[0] // vis ref contract
// add default settings
let settings = {
devices: [],
data: null,
compute: '',
visualise: visStyle,
category: ['none'],
timeperiod: '',
xaxis: '',
yaxis: ['blind1234555554321'],
resolution: '',
setTimeFormat: '',
single: true,
multidata: false
}
dataMCRC.settings = settings
inputStructure.style = 'visualise'
inputStructure.value = {}
inputStructure.value.style = 'visualise'
inputStructure.value.info = dataMCRC
}
const prepareModule = this.libComposer.liveComposer.moduleComposer(inputStructure, 'join')
// need to format key value from hash and contract format
let keyStructure = {}
keyStructure.key = prepareModule.data.hash
keyStructure.value = prepareModule.data.contract
modContracts.push(keyStructure)
}
for (let modC of modContracts) {
modKeys.push(modC.key)
}
// console.log(util.inspect(modContracts, {showHidden: false, depth: null}))
// SafeFow Structure
safeFlowQuery.modules = modContracts
safeFlowQuery.reftype = 'ignore'
safeFlowQuery.type = 'safeflow'
return safeFlowQuery
}
}
export default HopQuerybuilder