node-opcua-client-dynamic-extension-object 2.70.0 → 2.70.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -40,11 +40,113 @@ function readDataTypeDefinitionAndBuildType(session, dataTypeNodeId, name, dataT
|
|
|
40
40
|
});
|
|
41
41
|
}
|
|
42
42
|
exports.readDataTypeDefinitionAndBuildType = readDataTypeDefinitionAndBuildType;
|
|
43
|
+
class TaskMan {
|
|
44
|
+
constructor() {
|
|
45
|
+
this.taskList = [];
|
|
46
|
+
this._runningTask = false;
|
|
47
|
+
this._resolve = undefined;
|
|
48
|
+
}
|
|
49
|
+
flushTaskList() {
|
|
50
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
51
|
+
const firstTask = this.taskList.shift();
|
|
52
|
+
this._runningTask = true;
|
|
53
|
+
yield firstTask();
|
|
54
|
+
this._runningTask = false;
|
|
55
|
+
if (this.taskList.length > 0) {
|
|
56
|
+
setImmediate(() => __awaiter(this, void 0, void 0, function* () {
|
|
57
|
+
yield this.flushTaskList();
|
|
58
|
+
}));
|
|
59
|
+
}
|
|
60
|
+
else {
|
|
61
|
+
if (this._resolve) {
|
|
62
|
+
const tmpResolve = this._resolve;
|
|
63
|
+
this._resolve = undefined;
|
|
64
|
+
tmpResolve();
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
*
|
|
71
|
+
* a little async task queue that gets executed sequentially
|
|
72
|
+
* outside the main loop
|
|
73
|
+
*/
|
|
74
|
+
registerTask(taskFunc) {
|
|
75
|
+
this.taskList.push(taskFunc);
|
|
76
|
+
if (this.taskList.length === 1 && !this._runningTask) {
|
|
77
|
+
this.flushTaskList();
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
waitForCompletion() {
|
|
81
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
82
|
+
if (this._resolve !== undefined) {
|
|
83
|
+
throw new Error("already waiting");
|
|
84
|
+
}
|
|
85
|
+
yield new Promise((resolve) => {
|
|
86
|
+
this._resolve = resolve;
|
|
87
|
+
});
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
function applyOnReferenceRecursively(session, nodeId, browseDescriptionTemplate, action) {
|
|
92
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
93
|
+
const taskMan = new TaskMan();
|
|
94
|
+
let pendingNodesToBrowse = [];
|
|
95
|
+
let pendingContinuationPoints = [];
|
|
96
|
+
function processBrowseResult(browseResults) {
|
|
97
|
+
for (const result of browseResults) {
|
|
98
|
+
if (result.statusCode === node_opcua_status_code_1.StatusCodes.Good) {
|
|
99
|
+
if (result.continuationPoint) {
|
|
100
|
+
pendingContinuationPoints.push(result.continuationPoint);
|
|
101
|
+
taskMan.registerTask(flushBrowse);
|
|
102
|
+
}
|
|
103
|
+
for (const r of result.references || []) {
|
|
104
|
+
taskMan.registerTask(() => __awaiter(this, void 0, void 0, function* () {
|
|
105
|
+
yield action(r);
|
|
106
|
+
}));
|
|
107
|
+
// also explore sub types
|
|
108
|
+
browseSubDataTypeRecursively(r.nodeId);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
function flushBrowse() {
|
|
114
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
115
|
+
if (pendingContinuationPoints.length) {
|
|
116
|
+
const continuationPoints = pendingContinuationPoints;
|
|
117
|
+
pendingContinuationPoints = [];
|
|
118
|
+
taskMan.registerTask(() => __awaiter(this, void 0, void 0, function* () {
|
|
119
|
+
const browseResults = yield session.browseNext(continuationPoints, false);
|
|
120
|
+
processBrowseResult(browseResults);
|
|
121
|
+
}));
|
|
122
|
+
}
|
|
123
|
+
else if (pendingNodesToBrowse.length) {
|
|
124
|
+
const nodesToBrowse = pendingNodesToBrowse;
|
|
125
|
+
pendingNodesToBrowse = [];
|
|
126
|
+
taskMan.registerTask(() => __awaiter(this, void 0, void 0, function* () {
|
|
127
|
+
const browseResults = yield session.browse(nodesToBrowse);
|
|
128
|
+
processBrowseResult(browseResults);
|
|
129
|
+
}));
|
|
130
|
+
}
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
function browseSubDataTypeRecursively(nodeId) {
|
|
134
|
+
const nodeToBrowse = Object.assign(Object.assign({}, browseDescriptionTemplate), { nodeId });
|
|
135
|
+
pendingNodesToBrowse.push(nodeToBrowse);
|
|
136
|
+
taskMan.registerTask(() => __awaiter(this, void 0, void 0, function* () {
|
|
137
|
+
flushBrowse();
|
|
138
|
+
}));
|
|
139
|
+
}
|
|
140
|
+
browseSubDataTypeRecursively(nodeId);
|
|
141
|
+
yield taskMan.waitForCompletion();
|
|
142
|
+
});
|
|
143
|
+
}
|
|
43
144
|
function populateDataTypeManager104(session, dataTypeManager) {
|
|
44
145
|
return __awaiter(this, void 0, void 0, function* () {
|
|
45
146
|
const cache = {};
|
|
46
|
-
function withDataType(
|
|
147
|
+
function withDataType(r) {
|
|
47
148
|
return __awaiter(this, void 0, void 0, function* () {
|
|
149
|
+
const dataTypeNodeId = r.nodeId;
|
|
48
150
|
try {
|
|
49
151
|
const dataTypeFactory = dataTypeManager.getDataTypeFactory(dataTypeNodeId.namespace);
|
|
50
152
|
if (dataTypeNodeId.namespace === 0) {
|
|
@@ -66,80 +168,15 @@ function populateDataTypeManager104(session, dataTypeManager) {
|
|
|
66
168
|
}
|
|
67
169
|
});
|
|
68
170
|
}
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
}
|
|
79
|
-
let busyCount = 0;
|
|
80
|
-
function processBrowseResult(browseResults) {
|
|
81
|
-
for (const result of browseResults) {
|
|
82
|
-
if (result.statusCode === node_opcua_status_code_1.StatusCodes.Good) {
|
|
83
|
-
if (result.continuationPoint) {
|
|
84
|
-
pendingContinuationPoints.push(result.continuationPoint);
|
|
85
|
-
triggerFutureBrowse();
|
|
86
|
-
}
|
|
87
|
-
for (const r of result.references || []) {
|
|
88
|
-
const dataTypeNodeId = r.nodeId;
|
|
89
|
-
fencedAction(() => __awaiter(this, void 0, void 0, function* () {
|
|
90
|
-
yield withDataType(dataTypeNodeId, r);
|
|
91
|
-
}));
|
|
92
|
-
// also explore sub types
|
|
93
|
-
browseSubDataTypeRecursively(dataTypeNodeId);
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
function fencedAction(lambda) {
|
|
99
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
100
|
-
busyCount += 1;
|
|
101
|
-
yield lambda();
|
|
102
|
-
busyCount -= 1;
|
|
103
|
-
flushBrowse();
|
|
104
|
-
});
|
|
105
|
-
}
|
|
106
|
-
function flushBrowse() {
|
|
107
|
-
(0, node_opcua_assert_1.assert)(busyCount >= 0);
|
|
108
|
-
if (pendingContinuationPoints.length) {
|
|
109
|
-
const continuationPoints = pendingContinuationPoints;
|
|
110
|
-
pendingContinuationPoints = [];
|
|
111
|
-
fencedAction(() => __awaiter(this, void 0, void 0, function* () {
|
|
112
|
-
const browseResults = yield session.browseNext(continuationPoints, false);
|
|
113
|
-
processBrowseResult(browseResults);
|
|
114
|
-
}));
|
|
115
|
-
}
|
|
116
|
-
else if (pendingNodesToBrowse.length) {
|
|
117
|
-
const nodesToBrowse = pendingNodesToBrowse;
|
|
118
|
-
pendingNodesToBrowse = [];
|
|
119
|
-
fencedAction(() => __awaiter(this, void 0, void 0, function* () {
|
|
120
|
-
const browseResults = yield session.browse(nodesToBrowse);
|
|
121
|
-
processBrowseResult(browseResults);
|
|
122
|
-
}));
|
|
123
|
-
}
|
|
124
|
-
else if (pendingContinuationPoints.length + pendingNodesToBrowse.length === 0 && busyCount === 0) {
|
|
125
|
-
done();
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
function browseSubDataTypeRecursively(nodeId) {
|
|
129
|
-
const nodeToBrowse = {
|
|
130
|
-
nodeId,
|
|
131
|
-
includeSubtypes: true,
|
|
132
|
-
browseDirection: node_opcua_data_model_1.BrowseDirection.Forward,
|
|
133
|
-
nodeClassMask: 0xff,
|
|
134
|
-
referenceTypeId: (0, node_opcua_nodeid_1.resolveNodeId)("HasSubtype"),
|
|
135
|
-
resultMask: 0xff
|
|
136
|
-
};
|
|
137
|
-
pendingNodesToBrowse.push(nodeToBrowse);
|
|
138
|
-
triggerFutureBrowse();
|
|
139
|
-
}
|
|
140
|
-
browseSubDataTypeRecursively((0, node_opcua_nodeid_1.resolveNodeId)("Structure"));
|
|
141
|
-
}
|
|
142
|
-
yield new Promise((resolve) => performAction(resolve));
|
|
171
|
+
const nodeToBrowse = {
|
|
172
|
+
nodeId: node_opcua_nodeid_1.NodeId.nullNodeId,
|
|
173
|
+
includeSubtypes: true,
|
|
174
|
+
browseDirection: node_opcua_data_model_1.BrowseDirection.Forward,
|
|
175
|
+
nodeClassMask: 0xff,
|
|
176
|
+
referenceTypeId: (0, node_opcua_nodeid_1.resolveNodeId)("HasSubtype"),
|
|
177
|
+
resultMask: 0xff
|
|
178
|
+
};
|
|
179
|
+
yield applyOnReferenceRecursively(session, (0, node_opcua_nodeid_1.resolveNodeId)("Structure"), nodeToBrowse, withDataType);
|
|
143
180
|
});
|
|
144
181
|
}
|
|
145
182
|
exports.populateDataTypeManager104 = populateDataTypeManager104;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"populate_data_type_manager_104.js","sourceRoot":"","sources":["../../source/private/populate_data_type_manager_104.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,yDAA2C;AAC3C,iEAAsE;AACtE,uDAAgE;AAEhE,
|
|
1
|
+
{"version":3,"file":"populate_data_type_manager_104.js","sourceRoot":"","sources":["../../source/private/populate_data_type_manager_104.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "node-opcua-client-dynamic-extension-object",
|
|
3
|
-
"version": "2.70.
|
|
3
|
+
"version": "2.70.3",
|
|
4
4
|
"description": "pure nodejs OPCUA SDK - module client-dynamic-extension-object",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"types": "./dist/index.d.ts",
|
|
@@ -20,12 +20,12 @@
|
|
|
20
20
|
"node-opcua-extension-object": "2.70.0",
|
|
21
21
|
"node-opcua-factory": "2.70.0",
|
|
22
22
|
"node-opcua-nodeid": "2.70.0",
|
|
23
|
-
"node-opcua-pseudo-session": "2.70.
|
|
24
|
-
"node-opcua-schemas": "2.70.
|
|
25
|
-
"node-opcua-service-browse": "2.70.
|
|
26
|
-
"node-opcua-service-translate-browse-path": "2.70.
|
|
23
|
+
"node-opcua-pseudo-session": "2.70.3",
|
|
24
|
+
"node-opcua-schemas": "2.70.3",
|
|
25
|
+
"node-opcua-service-browse": "2.70.3",
|
|
26
|
+
"node-opcua-service-translate-browse-path": "2.70.3",
|
|
27
27
|
"node-opcua-status-code": "2.70.0",
|
|
28
|
-
"node-opcua-types": "2.70.
|
|
28
|
+
"node-opcua-types": "2.70.3",
|
|
29
29
|
"node-opcua-variant": "2.70.0"
|
|
30
30
|
},
|
|
31
31
|
"author": "Etienne Rossignon",
|
|
@@ -43,5 +43,5 @@
|
|
|
43
43
|
"internet of things"
|
|
44
44
|
],
|
|
45
45
|
"homepage": "http://node-opcua.github.io/",
|
|
46
|
-
"gitHead": "
|
|
46
|
+
"gitHead": "08b5465af631fd010bc48843c951b2e556270de4"
|
|
47
47
|
}
|
|
@@ -2,11 +2,11 @@ import { assert } from "node-opcua-assert";
|
|
|
2
2
|
import { AttributeIds, BrowseDirection } from "node-opcua-data-model";
|
|
3
3
|
import { make_debugLog, make_errorLog } from "node-opcua-debug";
|
|
4
4
|
import { DataTypeFactory } from "node-opcua-factory";
|
|
5
|
-
import { NodeId, resolveNodeId } from "node-opcua-nodeid";
|
|
5
|
+
import { NodeId, NodeIdLike, resolveNodeId } from "node-opcua-nodeid";
|
|
6
6
|
import { IBasicSession, BrowseDescriptionLike } from "node-opcua-pseudo-session";
|
|
7
7
|
import { createDynamicObjectConstructor } from "node-opcua-schemas";
|
|
8
8
|
import { StatusCodes } from "node-opcua-status-code";
|
|
9
|
-
import { ReferenceDescription, BrowseResult } from "node-opcua-types";
|
|
9
|
+
import { ReferenceDescription, BrowseResult, BrowseDescriptionOptions } from "node-opcua-types";
|
|
10
10
|
|
|
11
11
|
//
|
|
12
12
|
import { ExtraDataTypeManager } from "../extra_data_type_manager";
|
|
@@ -15,14 +15,14 @@ import {
|
|
|
15
15
|
convertDataTypeDefinitionToStructureTypeSchema
|
|
16
16
|
} from "../convert_data_type_definition_to_structuretype_schema";
|
|
17
17
|
const errorLog = make_errorLog(__filename);
|
|
18
|
-
const debugLog =make_debugLog(__filename);
|
|
18
|
+
const debugLog = make_debugLog(__filename);
|
|
19
19
|
|
|
20
20
|
export async function readDataTypeDefinitionAndBuildType(
|
|
21
21
|
session: IBasicSession,
|
|
22
22
|
dataTypeNodeId: NodeId,
|
|
23
23
|
name: string,
|
|
24
24
|
dataTypeFactory: DataTypeFactory,
|
|
25
|
-
cache: { [key: string]: CacheForFieldResolution }
|
|
25
|
+
cache: { [key: string]: CacheForFieldResolution }
|
|
26
26
|
) {
|
|
27
27
|
try {
|
|
28
28
|
const dataTypeDefinitionDataValue = await session.read({
|
|
@@ -50,11 +50,113 @@ export async function readDataTypeDefinitionAndBuildType(
|
|
|
50
50
|
}
|
|
51
51
|
}
|
|
52
52
|
|
|
53
|
-
|
|
53
|
+
class TaskMan {
|
|
54
|
+
private readonly taskList: (() => Promise<void>)[] = [];
|
|
55
|
+
private _runningTask = false;
|
|
56
|
+
private _resolve: (() => void) | undefined = undefined;
|
|
57
|
+
|
|
58
|
+
async flushTaskList() {
|
|
59
|
+
const firstTask = this.taskList.shift()!;
|
|
60
|
+
this._runningTask = true;
|
|
61
|
+
await firstTask();
|
|
62
|
+
this._runningTask = false;
|
|
63
|
+
if (this.taskList.length > 0) {
|
|
64
|
+
setImmediate(async () => {
|
|
65
|
+
await this.flushTaskList();
|
|
66
|
+
});
|
|
67
|
+
} else {
|
|
68
|
+
if (this._resolve) {
|
|
69
|
+
const tmpResolve = this._resolve;
|
|
70
|
+
this._resolve = undefined;
|
|
71
|
+
tmpResolve();
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
*
|
|
77
|
+
* a little async task queue that gets executed sequentially
|
|
78
|
+
* outside the main loop
|
|
79
|
+
*/
|
|
80
|
+
public registerTask(taskFunc: () => Promise<void>) {
|
|
81
|
+
this.taskList.push(taskFunc);
|
|
82
|
+
if (this.taskList.length === 1 && !this._runningTask) {
|
|
83
|
+
this.flushTaskList();
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
public async waitForCompletion() {
|
|
87
|
+
if (this._resolve !== undefined) {
|
|
88
|
+
throw new Error("already waiting");
|
|
89
|
+
}
|
|
90
|
+
await new Promise<void>((resolve) => {
|
|
91
|
+
this._resolve = resolve;
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
async function applyOnReferenceRecursively(
|
|
97
|
+
session: IBasicSession,
|
|
98
|
+
nodeId: NodeId,
|
|
99
|
+
browseDescriptionTemplate: BrowseDescriptionOptions,
|
|
100
|
+
action: (ref: ReferenceDescription) => Promise<void>
|
|
101
|
+
): Promise<void> {
|
|
102
|
+
const taskMan = new TaskMan();
|
|
103
|
+
|
|
104
|
+
let pendingNodesToBrowse: BrowseDescriptionLike[] = [];
|
|
105
|
+
let pendingContinuationPoints: Buffer[] = [];
|
|
106
|
+
|
|
107
|
+
function processBrowseResult(browseResults: BrowseResult[]) {
|
|
108
|
+
for (const result of browseResults) {
|
|
109
|
+
if (result.statusCode === StatusCodes.Good) {
|
|
110
|
+
if (result.continuationPoint) {
|
|
111
|
+
pendingContinuationPoints.push(result.continuationPoint);
|
|
112
|
+
taskMan.registerTask(flushBrowse);
|
|
113
|
+
}
|
|
114
|
+
for (const r of result.references || []) {
|
|
115
|
+
taskMan.registerTask(async () => {
|
|
116
|
+
await action(r);
|
|
117
|
+
});
|
|
118
|
+
// also explore sub types
|
|
119
|
+
browseSubDataTypeRecursively(r.nodeId);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
async function flushBrowse() {
|
|
125
|
+
if (pendingContinuationPoints.length) {
|
|
126
|
+
const continuationPoints = pendingContinuationPoints;
|
|
127
|
+
pendingContinuationPoints = [];
|
|
128
|
+
taskMan.registerTask(async () => {
|
|
129
|
+
const browseResults = await session.browseNext(continuationPoints, false);
|
|
130
|
+
processBrowseResult(browseResults);
|
|
131
|
+
});
|
|
132
|
+
} else if (pendingNodesToBrowse.length) {
|
|
133
|
+
const nodesToBrowse = pendingNodesToBrowse;
|
|
134
|
+
pendingNodesToBrowse = [];
|
|
135
|
+
taskMan.registerTask(async () => {
|
|
136
|
+
const browseResults = await session.browse(nodesToBrowse);
|
|
137
|
+
processBrowseResult(browseResults);
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
}
|
|
54
141
|
|
|
142
|
+
function browseSubDataTypeRecursively(nodeId: NodeId): void {
|
|
143
|
+
const nodeToBrowse: BrowseDescriptionOptions = {
|
|
144
|
+
...browseDescriptionTemplate,
|
|
145
|
+
nodeId
|
|
146
|
+
};
|
|
147
|
+
pendingNodesToBrowse.push(nodeToBrowse);
|
|
148
|
+
taskMan.registerTask(async () => {
|
|
149
|
+
flushBrowse();
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
browseSubDataTypeRecursively(nodeId);
|
|
153
|
+
await taskMan.waitForCompletion();
|
|
154
|
+
}
|
|
155
|
+
export async function populateDataTypeManager104(session: IBasicSession, dataTypeManager: ExtraDataTypeManager): Promise<void> {
|
|
55
156
|
const cache: { [key: string]: CacheForFieldResolution } = {};
|
|
56
|
-
|
|
57
|
-
async function withDataType(
|
|
157
|
+
|
|
158
|
+
async function withDataType(r: ReferenceDescription): Promise<void> {
|
|
159
|
+
const dataTypeNodeId = r.nodeId;
|
|
58
160
|
try {
|
|
59
161
|
const dataTypeFactory = dataTypeManager.getDataTypeFactory(dataTypeNodeId.namespace);
|
|
60
162
|
if (dataTypeNodeId.namespace === 0) {
|
|
@@ -75,80 +177,13 @@ export async function populateDataTypeManager104(session: IBasicSession, dataTyp
|
|
|
75
177
|
}
|
|
76
178
|
}
|
|
77
179
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
}
|
|
88
|
-
let busyCount = 0;
|
|
89
|
-
function processBrowseResult(browseResults: BrowseResult[]) {
|
|
90
|
-
|
|
91
|
-
for (const result of browseResults) {
|
|
92
|
-
if (result.statusCode === StatusCodes.Good) {
|
|
93
|
-
if (result.continuationPoint) {
|
|
94
|
-
pendingContinuationPoints.push(result.continuationPoint);
|
|
95
|
-
triggerFutureBrowse();
|
|
96
|
-
}
|
|
97
|
-
for (const r of result.references || []) {
|
|
98
|
-
const dataTypeNodeId = r.nodeId;
|
|
99
|
-
fencedAction(async ()=>{
|
|
100
|
-
await withDataType(dataTypeNodeId, r);
|
|
101
|
-
});
|
|
102
|
-
// also explore sub types
|
|
103
|
-
browseSubDataTypeRecursively(dataTypeNodeId);
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
async function fencedAction(lambda: () => Promise<void>): Promise<void> {
|
|
110
|
-
busyCount += 1;
|
|
111
|
-
await lambda();
|
|
112
|
-
busyCount -= 1;
|
|
113
|
-
flushBrowse();
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
function flushBrowse() {
|
|
117
|
-
assert(busyCount >= 0);
|
|
118
|
-
if (pendingContinuationPoints.length) {
|
|
119
|
-
const continuationPoints = pendingContinuationPoints;
|
|
120
|
-
pendingContinuationPoints = [];
|
|
121
|
-
fencedAction(async () => {
|
|
122
|
-
const browseResults = await session.browseNext(continuationPoints, false);
|
|
123
|
-
processBrowseResult(browseResults);
|
|
124
|
-
});
|
|
125
|
-
} else if (pendingNodesToBrowse.length) {
|
|
126
|
-
const nodesToBrowse = pendingNodesToBrowse;
|
|
127
|
-
pendingNodesToBrowse = [];
|
|
128
|
-
|
|
129
|
-
fencedAction(async () => {
|
|
130
|
-
const browseResults = await session.browse(nodesToBrowse);
|
|
131
|
-
processBrowseResult(browseResults);
|
|
132
|
-
});
|
|
133
|
-
} else if (pendingContinuationPoints.length + pendingNodesToBrowse.length === 0 && busyCount === 0) {
|
|
134
|
-
done();
|
|
135
|
-
}
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
function browseSubDataTypeRecursively(nodeId: NodeId): void {
|
|
139
|
-
const nodeToBrowse: BrowseDescriptionLike = {
|
|
140
|
-
nodeId,
|
|
141
|
-
includeSubtypes: true,
|
|
142
|
-
browseDirection: BrowseDirection.Forward,
|
|
143
|
-
nodeClassMask: 0xff,
|
|
144
|
-
referenceTypeId: resolveNodeId("HasSubtype"),
|
|
145
|
-
resultMask: 0xff
|
|
146
|
-
};
|
|
147
|
-
pendingNodesToBrowse.push(nodeToBrowse);
|
|
148
|
-
triggerFutureBrowse();
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
browseSubDataTypeRecursively(resolveNodeId("Structure"));
|
|
152
|
-
}
|
|
153
|
-
await new Promise<void>((resolve) => performAction(resolve));
|
|
180
|
+
const nodeToBrowse: BrowseDescriptionOptions = {
|
|
181
|
+
nodeId: NodeId.nullNodeId, // to be replaced
|
|
182
|
+
includeSubtypes: true,
|
|
183
|
+
browseDirection: BrowseDirection.Forward,
|
|
184
|
+
nodeClassMask: 0xff,
|
|
185
|
+
referenceTypeId: resolveNodeId("HasSubtype"),
|
|
186
|
+
resultMask: 0xff
|
|
187
|
+
};
|
|
188
|
+
await applyOnReferenceRecursively(session, resolveNodeId("Structure"), nodeToBrowse, withDataType);
|
|
154
189
|
}
|