// used to append interfaces to omnicore sdk so that created app and AppStudio can use
import API from './ecosystem-base.js';
import {Logger} from './../function/log-helper.js';
import {InfoType, WarningType} from '../information/informationCode.js';
import {ErrorCode} from '../exception/exceptionDesc.js';
import {Rapid, Pending, Success} from '../store/const.js';
import Store from '../store/store.js';
const factoryApiVariableMonitor = function (es) {
const logModule = 'ecosystem-variable';
/**
* The API.VARIABLEMONITOR namespace provides a set of interfaces for easily and quickly adding RAPID variable monitoring and processing transactions
* @alias API.VARIABLEMONITOR
* @namespace
*/
es.VARIABLEMONITOR = new (function () {
const subscribedVariables = {};
const subscribeRes = async function (variable, func) {
if (es.isSubscriptionBlocked) {
Logger.w(
WarningType.RWSSubscriptionBlocked,
'API.VARIABLEMONITOR: Subscription disabled when trying to monitor variable',
);
return;
}
variable.addCallbackOnChanged(func);
await variable.subscribe();
};
this.unsubscribeRes = async function (mappingKey) {
const variableInfo = subscribedVariables[mappingKey];
if (variableInfo && variableInfo.variable) {
variableInfo.variable.unsubscribe();
delete subscribedVariables[mappingKey];
}
};
/**
* Subscribes to a RAPID variable.
* @alias monitorVariable
* @memberof API.VARIABLEMONITOR
* @param {object} [variableObj] The variable attributes including the variable name and other necessary information.
* @param {function} [callback] The callback function that is called when the variable changes.
*
* @example
* API.VARIABLEMONITOR.monitorVariable(
* {type: 'tooldata', task: 'task1', module: 'module1', name: 'Wobj_1'},
* (v)=>{
* console.log(v);
* }
* )
*/
this.monitorVariable = async function (
variableObj = {
type: 'tooldata',
task: 'task1',
module: 'module1',
name: 'Wobj_1',
},
callback = null,
) {
const mappingKey = Store.generateMappingKey(Rapid, [
variableObj.type,
variableObj.task,
variableObj.module,
variableObj.name,
]);
if (es.isFetchControllerBlocked) {
Logger.w(
WarningType.RWSRequestBlocked,
`API.VARIABLEMONITOR: HttpRequest disabled when trying to monitor variable ${mappingKey}`,
);
return;
}
const {state, value} = Store.getNamespace(Rapid).getMapping(mappingKey) || {state: undefined, value: undefined};
// 1.if the variable is not in the store, read its initial value and store it
if (state === undefined) {
try {
Store.getNamespace(Rapid).setMapping(mappingKey, {
state: Pending,
value: undefined,
});
const initialValue = await API.RWS.RAPID.getVariableRawValue(
variableObj.module,
variableObj.name,
variableObj.task,
);
Store.getNamespace(Rapid).setMapping(mappingKey, {
state: Success,
value: initialValue,
});
typeof callback === 'function' && callback(initialValue);
es._events.trigger(mappingKey + '_fetch', initialValue);
} catch (error) {
return API.rejectWithStatus(
`Failed to read variable ${variableObj.name}'s value before subscription.`,
error,
{errorCode: ErrorCode.FailedToGetVariableValue},
);
}
} else if (state === Pending) {
es._events.once(mappingKey + '_fetch', (v) => {
typeof callback === 'function' && callback(v);
});
} else {
typeof callback === 'function' && callback(value);
}
if (es.isSubscriptionBlocked) {
Logger.w(
WarningType.RWSSubscriptionBlocked,
`API.VARIABLEMONITOR: Subscription disabled when trying to monitor variable ${mappingKey}`,
);
return;
}
// 2.if the variable is not subscribed yet, subscribe to it
es._events.on(mappingKey, callback);
if (!subscribedVariables[mappingKey]) {
try {
subscribedVariables[mappingKey] = {
state: Pending,
};
const cbVariable = function (data) {
Store.getNamespace(Rapid).setMapping(mappingKey, {
state: Success,
value: data,
});
es._events.trigger(mappingKey, data);
Logger.i(logModule, `Triggered :${variableObj.name} - ${data}`);
};
const variableData = await RWS.Rapid.getData(variableObj.task, variableObj.module, variableObj.name);
await subscribeRes(variableData, cbVariable.bind(this));
subscribedVariables[mappingKey].state = Success;
subscribedVariables[mappingKey].variable = variableData;
Logger.i(logModule, `Subscribed variable: ${mappingKey}`);
} catch (e) {
return API.rejectWithStatus(`Subscription to ${variableObj.name} failed.`, e, {
errorCode: ErrorCode.FailedToSubscribeVariable,
});
}
}
};
})();
es.constructedVariableMonitor = true;
};
if (typeof API.constructedVariableMonitor === 'undefined') {
factoryApiVariableMonitor(API);
}
export default API;
export {factoryApiVariableMonitor};