node-opcua-pseudo-session
Version:
pure nodejs OPCUA SDK - module pseudo-session
106 lines • 5.17 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.browseAll = browseAll;
exports.browseAll2 = browseAll2;
/**
* @module node-opcua-pseudo-session
*/
const node_opcua_assert_1 = require("node-opcua-assert");
const node_opcua_basic_types_1 = require("node-opcua-basic-types");
const node_opcua_constants_1 = require("node-opcua-constants");
const node_opcua_debug_1 = require("node-opcua-debug");
const node_opcua_nodeid_1 = require("node-opcua-nodeid");
const node_opcua_status_code_1 = require("node-opcua-status-code");
const warningLog = (0, node_opcua_debug_1.make_warningLog)(__filename);
const debugLog = (0, node_opcua_debug_1.make_debugLog)(__filename);
async function readLimits(session) {
const dataValues = await session.read([
{ nodeId: node_opcua_constants_1.VariableIds.Server_ServerCapabilities_MaxBrowseContinuationPoints, attributeId: node_opcua_basic_types_1.AttributeIds.Value },
{ nodeId: node_opcua_constants_1.VariableIds.Server_ServerCapabilities_OperationLimits_MaxNodesPerBrowse, attributeId: node_opcua_basic_types_1.AttributeIds.Value }
]);
const maxBrowseContinuationPoints = dataValues[0].value.value || 10;
const maxNodesPerBrowse = dataValues[1].value.value || 10;
return { maxBrowseContinuationPoints, maxNodesPerBrowse };
}
function coerceToBrowseDescription(nodeToBrowse) {
if (typeof nodeToBrowse === "string") {
return {
nodeId: (0, node_opcua_nodeid_1.resolveNodeId)(nodeToBrowse)
};
}
else {
return nodeToBrowse;
}
}
async function browseAll(session, nodesToBrowse) {
if (!(nodesToBrowse instanceof Array)) {
return (await browseAll(session, [nodesToBrowse]))[0];
}
const { maxBrowseContinuationPoints, maxNodesPerBrowse } = await readLimits(session);
const maxNodesToBrowse = Math.min(maxNodesPerBrowse, maxBrowseContinuationPoints);
const tmp = nodesToBrowse.map(coerceToBrowseDescription);
let nodesToBrowse1 = tmp.splice(0, maxNodesToBrowse);
let browseResults = [];
while (nodesToBrowse1.length) {
const partialBrowseResult = await browseAll2(session, nodesToBrowse1);
browseResults = [...browseResults, ...partialBrowseResult];
nodesToBrowse1 = tmp.splice(0, maxNodesToBrowse);
}
(0, node_opcua_assert_1.assert)(browseResults.length === nodesToBrowse.length, "browseResults must have same length as nodesToBrowse");
return browseResults;
}
async function browseAll2(session, nodesToBrowse) {
if (nodesToBrowse.length === 0) {
return [];
}
const browseResults = await session.browse(nodesToBrowse);
const browseToRedo = [];
const browseToContinue = [];
for (let i = 0; i < browseResults.length; i++) {
const result = browseResults[i];
if (result.statusCode.equals(node_opcua_status_code_1.StatusCodes.BadNoContinuationPoints) ||
result.statusCode.equals(node_opcua_status_code_1.StatusCodes.BadContinuationPointInvalid)) {
// there was not enough continuation points
debugLog("There is not enough browse continuation points");
// we will have to re-inject this browse to a new browse command
browseToRedo.push({ index: i, nodeToBrowse: nodesToBrowse[i] });
continue;
}
const continuationPoint = result.continuationPoint;
result.continuationPoint = undefined;
if (continuationPoint && continuationPoint.length > 0) {
browseToContinue.push({ references: result.references || [], continuationPoint });
}
}
// resolve continuationPoints
while (browseToContinue.length) {
const tmp = [...browseToContinue];
const continuationPoints = tmp.map((e) => e.continuationPoint);
browseToContinue.splice(0);
const browseNextResults = await session.browseNext(continuationPoints, false);
(0, node_opcua_assert_1.assert)(continuationPoints.length === browseNextResults.length, "browseNextResults length should eql continuationPoints.length");
for (let i = 0; i < browseNextResults.length; i++) {
const browseResult = browseNextResults[i];
const references = tmp[i].references || [];
if (browseResult.references && browseResult.references.length) {
references.push(...browseResult.references);
}
const continuationPoint = browseResult.continuationPoint;
if (continuationPoint) {
browseToContinue.push({ references, continuationPoint });
}
}
}
// resolve to redo
if (browseToRedo.length && nodesToBrowse.length !== browseToRedo.length) {
const nodesToBrowse2 = browseToRedo.map((e) => e.nodeToBrowse);
const results2 = await browseAll2(session, nodesToBrowse2);
for (let i = 0; i < browseResults.length; i++) {
browseResults[browseToRedo[i].index] = results2[i];
}
browseToRedo.splice(0);
}
browseResults.forEach((b) => (b.continuationPoint = undefined));
return browseResults;
}
//# sourceMappingURL=browse_all.js.map