node-opcua-client-dynamic-extension-object
Advanced tools
Comparing version 2.70.0 to 2.70.1
@@ -43,7 +43,109 @@ "use strict"; | ||
exports.readDataTypeDefinitionAndBuildType = readDataTypeDefinitionAndBuildType; | ||
class TaskMan { | ||
constructor() { | ||
this.taskList = []; | ||
this._runningTask = false; | ||
this._resolve = undefined; | ||
} | ||
flushTaskList() { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
const firstTask = this.taskList.shift(); | ||
this._runningTask = true; | ||
yield firstTask(); | ||
this._runningTask = false; | ||
if (this.taskList.length > 0) { | ||
setImmediate(() => __awaiter(this, void 0, void 0, function* () { | ||
yield this.flushTaskList(); | ||
})); | ||
} | ||
else { | ||
if (this._resolve) { | ||
const tmpResolve = this._resolve; | ||
this._resolve = undefined; | ||
tmpResolve(); | ||
} | ||
} | ||
}); | ||
} | ||
/** | ||
* | ||
* a little async task queue that gets executed sequentially | ||
* outside the main loop | ||
*/ | ||
registerTask(taskFunc) { | ||
this.taskList.push(taskFunc); | ||
if (this.taskList.length === 1 && !this._runningTask) { | ||
this.flushTaskList(); | ||
} | ||
} | ||
waitForCompletion() { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
if (this._resolve !== undefined) { | ||
throw new Error("already waiting"); | ||
} | ||
yield new Promise((resolve) => { | ||
this._resolve = resolve; | ||
}); | ||
}); | ||
} | ||
} | ||
function applyOnReferenceRecursively(session, nodeId, browseDescriptionTemplate, action) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
const taskMan = new TaskMan(); | ||
let pendingNodesToBrowse = []; | ||
let pendingContinuationPoints = []; | ||
function processBrowseResult(browseResults) { | ||
for (const result of browseResults) { | ||
if (result.statusCode === node_opcua_status_code_1.StatusCodes.Good) { | ||
if (result.continuationPoint) { | ||
pendingContinuationPoints.push(result.continuationPoint); | ||
taskMan.registerTask(flushBrowse); | ||
} | ||
for (const r of result.references || []) { | ||
taskMan.registerTask(() => __awaiter(this, void 0, void 0, function* () { | ||
yield action(r); | ||
})); | ||
// also explore sub types | ||
browseSubDataTypeRecursively(r.nodeId); | ||
} | ||
} | ||
} | ||
} | ||
function flushBrowse() { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
if (pendingContinuationPoints.length) { | ||
const continuationPoints = pendingContinuationPoints; | ||
pendingContinuationPoints = []; | ||
taskMan.registerTask(() => __awaiter(this, void 0, void 0, function* () { | ||
const browseResults = yield session.browseNext(continuationPoints, false); | ||
processBrowseResult(browseResults); | ||
})); | ||
} | ||
else if (pendingNodesToBrowse.length) { | ||
const nodesToBrowse = pendingNodesToBrowse; | ||
pendingNodesToBrowse = []; | ||
taskMan.registerTask(() => __awaiter(this, void 0, void 0, function* () { | ||
const browseResults = yield session.browse(nodesToBrowse); | ||
processBrowseResult(browseResults); | ||
})); | ||
} | ||
}); | ||
} | ||
function browseSubDataTypeRecursively(nodeId) { | ||
const nodeToBrowse = Object.assign(Object.assign({}, browseDescriptionTemplate), { nodeId }); | ||
pendingNodesToBrowse.push(nodeToBrowse); | ||
taskMan.registerTask(() => __awaiter(this, void 0, void 0, function* () { | ||
flushBrowse(); | ||
})); | ||
} | ||
browseSubDataTypeRecursively(nodeId); | ||
yield taskMan.waitForCompletion(); | ||
}); | ||
} | ||
function populateDataTypeManager104(session, dataTypeManager) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
const cache = {}; | ||
function withDataType(dataTypeNodeId, r) { | ||
function withDataType(r) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
const dataTypeNodeId = r.nodeId; | ||
try { | ||
@@ -70,76 +172,11 @@ const dataTypeFactory = dataTypeManager.getDataTypeFactory(dataTypeNodeId.namespace); | ||
} | ||
function performAction(done) { | ||
let pendingNodesToBrowse = []; | ||
let pendingContinuationPoints = []; | ||
function triggerFutureBrowse() { | ||
if (pendingNodesToBrowse.length + pendingContinuationPoints.length === 1) { | ||
fencedAction(() => __awaiter(this, void 0, void 0, function* () { | ||
flushBrowse(); | ||
})); | ||
} | ||
} | ||
let busyCount = 0; | ||
function processBrowseResult(browseResults) { | ||
for (const result of browseResults) { | ||
if (result.statusCode === node_opcua_status_code_1.StatusCodes.Good) { | ||
if (result.continuationPoint) { | ||
pendingContinuationPoints.push(result.continuationPoint); | ||
triggerFutureBrowse(); | ||
} | ||
for (const r of result.references || []) { | ||
const dataTypeNodeId = r.nodeId; | ||
fencedAction(() => __awaiter(this, void 0, void 0, function* () { | ||
yield withDataType(dataTypeNodeId, r); | ||
})); | ||
// also explore sub types | ||
browseSubDataTypeRecursively(dataTypeNodeId); | ||
} | ||
} | ||
} | ||
} | ||
function fencedAction(lambda) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
busyCount += 1; | ||
yield lambda(); | ||
busyCount -= 1; | ||
flushBrowse(); | ||
}); | ||
} | ||
function flushBrowse() { | ||
(0, node_opcua_assert_1.assert)(busyCount >= 0); | ||
if (pendingContinuationPoints.length) { | ||
const continuationPoints = pendingContinuationPoints; | ||
pendingContinuationPoints = []; | ||
fencedAction(() => __awaiter(this, void 0, void 0, function* () { | ||
const browseResults = yield session.browseNext(continuationPoints, false); | ||
processBrowseResult(browseResults); | ||
})); | ||
} | ||
else if (pendingNodesToBrowse.length) { | ||
const nodesToBrowse = pendingNodesToBrowse; | ||
pendingNodesToBrowse = []; | ||
fencedAction(() => __awaiter(this, void 0, void 0, function* () { | ||
const browseResults = yield session.browse(nodesToBrowse); | ||
processBrowseResult(browseResults); | ||
})); | ||
} | ||
else if (pendingContinuationPoints.length + pendingNodesToBrowse.length === 0 && busyCount === 0) { | ||
done(); | ||
} | ||
} | ||
function browseSubDataTypeRecursively(nodeId) { | ||
const nodeToBrowse = { | ||
nodeId, | ||
includeSubtypes: true, | ||
browseDirection: node_opcua_data_model_1.BrowseDirection.Forward, | ||
nodeClassMask: 0xff, | ||
referenceTypeId: (0, node_opcua_nodeid_1.resolveNodeId)("HasSubtype"), | ||
resultMask: 0xff | ||
}; | ||
pendingNodesToBrowse.push(nodeToBrowse); | ||
triggerFutureBrowse(); | ||
} | ||
browseSubDataTypeRecursively((0, node_opcua_nodeid_1.resolveNodeId)("Structure")); | ||
} | ||
yield new Promise((resolve) => performAction(resolve)); | ||
const nodeToBrowse = { | ||
nodeId: node_opcua_nodeid_1.NodeId.nullNodeId, | ||
includeSubtypes: true, | ||
browseDirection: node_opcua_data_model_1.BrowseDirection.Forward, | ||
nodeClassMask: 0xff, | ||
referenceTypeId: (0, node_opcua_nodeid_1.resolveNodeId)("HasSubtype"), | ||
resultMask: 0xff | ||
}; | ||
yield applyOnReferenceRecursively(session, (0, node_opcua_nodeid_1.resolveNodeId)("Structure"), nodeToBrowse, withDataType); | ||
}); | ||
@@ -146,0 +183,0 @@ } |
{ | ||
"name": "node-opcua-client-dynamic-extension-object", | ||
"version": "2.70.0", | ||
"version": "2.70.1", | ||
"description": "pure nodejs OPCUA SDK - module client-dynamic-extension-object", | ||
@@ -46,3 +46,3 @@ "main": "./dist/index.js", | ||
"homepage": "http://node-opcua.github.io/", | ||
"gitHead": "3b692ffb3e2ef0542da32f349fb0c76b3acc75ce" | ||
"gitHead": "5671bd283471b729838fb582bb2a705d5a4d528c" | ||
} |
@@ -5,7 +5,7 @@ import { assert } from "node-opcua-assert"; | ||
import { DataTypeFactory } from "node-opcua-factory"; | ||
import { NodeId, resolveNodeId } from "node-opcua-nodeid"; | ||
import { NodeId, NodeIdLike, resolveNodeId } from "node-opcua-nodeid"; | ||
import { IBasicSession, BrowseDescriptionLike } from "node-opcua-pseudo-session"; | ||
import { createDynamicObjectConstructor } from "node-opcua-schemas"; | ||
import { StatusCodes } from "node-opcua-status-code"; | ||
import { ReferenceDescription, BrowseResult } from "node-opcua-types"; | ||
import { ReferenceDescription, BrowseResult, BrowseDescriptionOptions } from "node-opcua-types"; | ||
@@ -19,3 +19,3 @@ // | ||
const errorLog = make_errorLog(__filename); | ||
const debugLog =make_debugLog(__filename); | ||
const debugLog = make_debugLog(__filename); | ||
@@ -27,3 +27,3 @@ export async function readDataTypeDefinitionAndBuildType( | ||
dataTypeFactory: DataTypeFactory, | ||
cache: { [key: string]: CacheForFieldResolution } | ||
cache: { [key: string]: CacheForFieldResolution } | ||
) { | ||
@@ -56,7 +56,109 @@ try { | ||
class TaskMan { | ||
private readonly taskList: (() => Promise<void>)[] = []; | ||
private _runningTask = false; | ||
private _resolve: (() => void) | undefined = undefined; | ||
async flushTaskList() { | ||
const firstTask = this.taskList.shift()!; | ||
this._runningTask = true; | ||
await firstTask(); | ||
this._runningTask = false; | ||
if (this.taskList.length > 0) { | ||
setImmediate(async () => { | ||
await this.flushTaskList(); | ||
}); | ||
} else { | ||
if (this._resolve) { | ||
const tmpResolve = this._resolve; | ||
this._resolve = undefined; | ||
tmpResolve(); | ||
} | ||
} | ||
} | ||
/** | ||
* | ||
* a little async task queue that gets executed sequentially | ||
* outside the main loop | ||
*/ | ||
public registerTask(taskFunc: () => Promise<void>) { | ||
this.taskList.push(taskFunc); | ||
if (this.taskList.length === 1 && !this._runningTask) { | ||
this.flushTaskList(); | ||
} | ||
} | ||
public async waitForCompletion() { | ||
if (this._resolve !== undefined) { | ||
throw new Error("already waiting"); | ||
} | ||
await new Promise<void>((resolve) => { | ||
this._resolve = resolve; | ||
}); | ||
} | ||
} | ||
async function applyOnReferenceRecursively( | ||
session: IBasicSession, | ||
nodeId: NodeId, | ||
browseDescriptionTemplate: BrowseDescriptionOptions, | ||
action: (ref: ReferenceDescription) => Promise<void> | ||
): Promise<void> { | ||
const taskMan = new TaskMan(); | ||
let pendingNodesToBrowse: BrowseDescriptionLike[] = []; | ||
let pendingContinuationPoints: Buffer[] = []; | ||
function processBrowseResult(browseResults: BrowseResult[]) { | ||
for (const result of browseResults) { | ||
if (result.statusCode === StatusCodes.Good) { | ||
if (result.continuationPoint) { | ||
pendingContinuationPoints.push(result.continuationPoint); | ||
taskMan.registerTask(flushBrowse); | ||
} | ||
for (const r of result.references || []) { | ||
taskMan.registerTask(async () => { | ||
await action(r); | ||
}); | ||
// also explore sub types | ||
browseSubDataTypeRecursively(r.nodeId); | ||
} | ||
} | ||
} | ||
} | ||
async function flushBrowse() { | ||
if (pendingContinuationPoints.length) { | ||
const continuationPoints = pendingContinuationPoints; | ||
pendingContinuationPoints = []; | ||
taskMan.registerTask(async () => { | ||
const browseResults = await session.browseNext(continuationPoints, false); | ||
processBrowseResult(browseResults); | ||
}); | ||
} else if (pendingNodesToBrowse.length) { | ||
const nodesToBrowse = pendingNodesToBrowse; | ||
pendingNodesToBrowse = []; | ||
taskMan.registerTask(async () => { | ||
const browseResults = await session.browse(nodesToBrowse); | ||
processBrowseResult(browseResults); | ||
}); | ||
} | ||
} | ||
function browseSubDataTypeRecursively(nodeId: NodeId): void { | ||
const nodeToBrowse: BrowseDescriptionOptions = { | ||
...browseDescriptionTemplate, | ||
nodeId | ||
}; | ||
pendingNodesToBrowse.push(nodeToBrowse); | ||
taskMan.registerTask(async () => { | ||
flushBrowse(); | ||
}); | ||
} | ||
browseSubDataTypeRecursively(nodeId); | ||
await taskMan.waitForCompletion(); | ||
} | ||
export async function populateDataTypeManager104(session: IBasicSession, dataTypeManager: ExtraDataTypeManager): Promise<void> { | ||
const cache: { [key: string]: CacheForFieldResolution } = {}; | ||
const cache: { [key: string]: CacheForFieldResolution } = {}; | ||
async function withDataType(dataTypeNodeId: NodeId, r: ReferenceDescription): Promise<void> { | ||
async function withDataType(r: ReferenceDescription): Promise<void> { | ||
const dataTypeNodeId = r.nodeId; | ||
try { | ||
@@ -82,78 +184,11 @@ const dataTypeFactory = dataTypeManager.getDataTypeFactory(dataTypeNodeId.namespace); | ||
function performAction(done: () => void) { | ||
let pendingNodesToBrowse: BrowseDescriptionLike[] = []; | ||
let pendingContinuationPoints: Buffer[] = []; | ||
function triggerFutureBrowse() { | ||
if (pendingNodesToBrowse.length + pendingContinuationPoints.length === 1) { | ||
fencedAction(async ()=>{ | ||
flushBrowse(); | ||
}); | ||
} | ||
} | ||
let busyCount = 0; | ||
function processBrowseResult(browseResults: BrowseResult[]) { | ||
for (const result of browseResults) { | ||
if (result.statusCode === StatusCodes.Good) { | ||
if (result.continuationPoint) { | ||
pendingContinuationPoints.push(result.continuationPoint); | ||
triggerFutureBrowse(); | ||
} | ||
for (const r of result.references || []) { | ||
const dataTypeNodeId = r.nodeId; | ||
fencedAction(async ()=>{ | ||
await withDataType(dataTypeNodeId, r); | ||
}); | ||
// also explore sub types | ||
browseSubDataTypeRecursively(dataTypeNodeId); | ||
} | ||
} | ||
} | ||
} | ||
async function fencedAction(lambda: () => Promise<void>): Promise<void> { | ||
busyCount += 1; | ||
await lambda(); | ||
busyCount -= 1; | ||
flushBrowse(); | ||
} | ||
function flushBrowse() { | ||
assert(busyCount >= 0); | ||
if (pendingContinuationPoints.length) { | ||
const continuationPoints = pendingContinuationPoints; | ||
pendingContinuationPoints = []; | ||
fencedAction(async () => { | ||
const browseResults = await session.browseNext(continuationPoints, false); | ||
processBrowseResult(browseResults); | ||
}); | ||
} else if (pendingNodesToBrowse.length) { | ||
const nodesToBrowse = pendingNodesToBrowse; | ||
pendingNodesToBrowse = []; | ||
fencedAction(async () => { | ||
const browseResults = await session.browse(nodesToBrowse); | ||
processBrowseResult(browseResults); | ||
}); | ||
} else if (pendingContinuationPoints.length + pendingNodesToBrowse.length === 0 && busyCount === 0) { | ||
done(); | ||
} | ||
} | ||
function browseSubDataTypeRecursively(nodeId: NodeId): void { | ||
const nodeToBrowse: BrowseDescriptionLike = { | ||
nodeId, | ||
includeSubtypes: true, | ||
browseDirection: BrowseDirection.Forward, | ||
nodeClassMask: 0xff, | ||
referenceTypeId: resolveNodeId("HasSubtype"), | ||
resultMask: 0xff | ||
}; | ||
pendingNodesToBrowse.push(nodeToBrowse); | ||
triggerFutureBrowse(); | ||
} | ||
browseSubDataTypeRecursively(resolveNodeId("Structure")); | ||
} | ||
await new Promise<void>((resolve) => performAction(resolve)); | ||
const nodeToBrowse: BrowseDescriptionOptions = { | ||
nodeId: NodeId.nullNodeId, // to be replaced | ||
includeSubtypes: true, | ||
browseDirection: BrowseDirection.Forward, | ||
nodeClassMask: 0xff, | ||
referenceTypeId: resolveNodeId("HasSubtype"), | ||
resultMask: 0xff | ||
}; | ||
await applyOnReferenceRecursively(session, resolveNodeId("Structure"), nodeToBrowse, withDataType); | ||
} |
Sorry, the diff of this file is not supported yet
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
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
210676
3233