node-opcua-address-space 2.81.0 → 2.83.0

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.
Files changed (57) hide show
  1. package/dist/source/loader/ensure_datatype_extracted.js +1 -1
  2. package/dist/source/loader/ensure_datatype_extracted.js.map +1 -1
  3. package/dist/source/loader/load_nodeset2.js +9 -22
  4. package/dist/source/loader/load_nodeset2.js.map +1 -1
  5. package/dist/source/xml_writer.d.ts +5 -1
  6. package/dist/src/address_space.js +1 -1
  7. package/dist/src/address_space.js.map +1 -1
  8. package/dist/src/apply_condition_refresh.d.ts +1 -1
  9. package/dist/src/apply_condition_refresh.js +5 -5
  10. package/dist/src/apply_condition_refresh.js.map +1 -1
  11. package/dist/src/base_node_impl.d.ts +1 -0
  12. package/dist/src/base_node_impl.js +83 -54
  13. package/dist/src/base_node_impl.js.map +1 -1
  14. package/dist/src/base_node_private.d.ts +23 -3
  15. package/dist/src/base_node_private.js +3 -2
  16. package/dist/src/base_node_private.js.map +1 -1
  17. package/dist/src/index_current.d.ts +1 -1
  18. package/dist/src/index_current.js +2 -3
  19. package/dist/src/index_current.js.map +1 -1
  20. package/dist/src/namespace_impl.d.ts +4 -1
  21. package/dist/src/namespace_impl.js +10 -2
  22. package/dist/src/namespace_impl.js.map +1 -1
  23. package/dist/src/namespace_private.d.ts +2 -1
  24. package/dist/src/namespace_private.js.map +1 -1
  25. package/dist/src/nodeset_tools/construct_namespace_dependency.d.ts +3 -1
  26. package/dist/src/nodeset_tools/construct_namespace_dependency.js +35 -5
  27. package/dist/src/nodeset_tools/construct_namespace_dependency.js.map +1 -1
  28. package/dist/src/nodeset_tools/nodeset_to_xml.d.ts +4 -2
  29. package/dist/src/nodeset_tools/nodeset_to_xml.js +44 -59
  30. package/dist/src/nodeset_tools/nodeset_to_xml.js.map +1 -1
  31. package/dist/src/ua_data_type_impl.d.ts +2 -0
  32. package/dist/src/ua_data_type_impl.js +10 -15
  33. package/dist/src/ua_data_type_impl.js.map +1 -1
  34. package/dist/src/ua_reference_type_impl.d.ts +1 -1
  35. package/dist/src/ua_reference_type_impl.js +1 -1
  36. package/dist/src/ua_reference_type_impl.js.map +1 -1
  37. package/dist/src/ua_variable_impl.d.ts +2 -0
  38. package/dist/src/ua_variable_impl.js +49 -11
  39. package/dist/src/ua_variable_impl.js.map +1 -1
  40. package/package.json +40 -40
  41. package/source/loader/ensure_datatype_extracted.ts +1 -1
  42. package/source/loader/load_nodeset2.ts +22 -36
  43. package/source/xml_writer.ts +5 -1
  44. package/src/address_space.ts +1 -2
  45. package/src/apply_condition_refresh.ts +5 -5
  46. package/src/base_node_impl.ts +86 -59
  47. package/src/base_node_private.ts +26 -10
  48. package/src/index_current.ts +1 -1
  49. package/src/namespace_impl.ts +13 -3
  50. package/src/namespace_private.ts +7 -1
  51. package/src/nodeset_tools/construct_namespace_dependency.ts +42 -5
  52. package/src/nodeset_tools/nodeset_to_xml.ts +57 -84
  53. package/src/ua_data_type_impl.ts +12 -15
  54. package/src/ua_reference_type_impl.ts +2 -2
  55. package/src/ua_variable_impl.ts +74 -31
  56. package/test_helpers/test_fixtures/dataType_with_union.xml +90 -1
  57. package/test_helpers/test_fixtures/datatype_as_per_1.04.xml +38 -10
@@ -8,19 +8,23 @@ function _constructNamespaceDependency(
8
8
  namespace: INamespace,
9
9
  dependency: INamespace[],
10
10
  depMap: Set<number>,
11
- _visitedDataType: Set<string>
11
+ _visitedDataType: Set<string>,
12
+ priorityTable: number[]
12
13
  ): void {
13
14
  const addressSpace = namespace.addressSpace;
14
15
  const namespace_ = namespace as NamespacePrivate;
15
16
  // navigate all namespace recursively to
16
17
 
17
18
  function consider(namespaceIndex: number) {
19
+ if (hasHigherPriorityThan(namespaceIndex,namespace.index, priorityTable)) {
20
+ return;
21
+ }
18
22
  if (!depMap.has(namespaceIndex)) {
19
23
  depMap.add(namespaceIndex);
20
24
  const namespace = addressSpace.getNamespace(namespaceIndex);
21
25
  dependency.push(namespace);
22
26
  if (namespaceIndex > 0) {
23
- _constructNamespaceDependency(namespace, dependency, depMap, _visitedDataType);
27
+ _constructNamespaceDependency(namespace, dependency, depMap, _visitedDataType, priorityTable);
24
28
  }
25
29
  }
26
30
  }
@@ -57,7 +61,7 @@ function _constructNamespaceDependency(
57
61
  exploreDataTypes(dataTypeNode);
58
62
  } else {
59
63
  // istanbul ignore next
60
- if (dataTypeNodeId.value!=0) {
64
+ if (dataTypeNodeId.value != 0) {
61
65
  console.log("Internal error: Cannot find dataType", dataTypeNodeId.toString());
62
66
  }
63
67
  }
@@ -74,8 +78,41 @@ function _constructNamespaceDependency(
74
78
  }
75
79
  }
76
80
 
77
- export function constructNamespaceDependency(namespace: INamespace): INamespace[] {
81
+
82
+ export function hasHigherPriorityThan(namespaceIndex1: number, namespaceIndex2: number, priorityTable: number[]) {
83
+ const order1 = priorityTable[namespaceIndex1];
84
+ const order2 = priorityTable[namespaceIndex2];
85
+ return order1 > order2;
86
+ }
87
+
88
+ export function constructNamespacePriorityTable(namespace: INamespace): number[] {
89
+
90
+ // Namespace 0 will always be 0
91
+ // Namespaces with no requiredModel will be considered as instance namespaces and will added at the end
92
+ // in the same order as they appear,
93
+ // Namespace with requiredModels are considered to be companion specification, so already loaded in the correct order
94
+
95
+ const addressSpace = namespace.addressSpace;
96
+ const namespaces = addressSpace.getNamespaceArray();
97
+
98
+ const namespaceWithReq = namespaces.filter((n)=> (n.getRequiredModels() !== undefined) && n.index !==0);
99
+ const namespaceWithoutReq = namespaces.filter((n)=>(n.getRequiredModels() === undefined) && n.index !==0);
100
+
101
+ const priorityList: number[] = [0];
102
+ let counter = 1;
103
+ for (let i = 0; i < namespaceWithReq.length; i++) {
104
+ priorityList[namespaceWithReq[i].index] = counter++;
105
+ }
106
+ for (let i = 0; i < namespaceWithoutReq.length; i++) {
107
+ priorityList[namespaceWithoutReq[i].index] = counter++;
108
+ }
109
+ return priorityList;
110
+ }
111
+
112
+ export function constructNamespaceDependency(namespace: INamespace, priorityTable?: number[]): INamespace[] {
78
113
  const addressSpace = namespace.addressSpace;
114
+
115
+ priorityTable = priorityTable || constructNamespacePriorityTable(namespace);
79
116
 
80
117
  const dependency: INamespace[] = [];
81
118
  const depMap = new Set<number>();
@@ -89,7 +126,7 @@ export function constructNamespaceDependency(namespace: INamespace): INamespace[
89
126
  }
90
127
  const _visitedDataType = new Set<string>();
91
128
 
92
- _constructNamespaceDependency(namespace, dependency, depMap, _visitedDataType);
129
+ _constructNamespaceDependency(namespace, dependency, depMap, _visitedDataType, priorityTable);
93
130
 
94
131
  return dependency;
95
132
  }
@@ -34,7 +34,7 @@ import {
34
34
  import { AttributeIds, Int64, minOPCUADate, StatusCode, StatusCodes } from "node-opcua-basic-types";
35
35
  import { BrowseDescription, EnumDefinition, StructureDefinition, StructureType } from "node-opcua-types";
36
36
 
37
- import { XmlWriter } from "../../source/xml_writer";
37
+ import { ITranslationTable, XmlWriter } from "../../source/xml_writer";
38
38
  import { NamespacePrivate } from "../namespace_private";
39
39
  import { ReferenceImpl } from "../reference_impl";
40
40
  import { BaseNodeImpl, getReferenceType } from "../base_node_impl";
@@ -50,7 +50,7 @@ import { SessionContext } from "../index_current";
50
50
 
51
51
  import { DefinitionMap2, TypeInfo } from "../../source/loader/make_xml_extension_object_parser";
52
52
  import { makeDefinitionMap } from "../../source/loader/decode_xml_extension_object";
53
- import { constructNamespaceDependency } from "./construct_namespace_dependency";
53
+ import { constructNamespaceDependency, constructNamespacePriorityTable, hasHigherPriorityThan } from "./construct_namespace_dependency";
54
54
 
55
55
  // tslint:disable:no-var-requires
56
56
  const XMLWriter = require("xml-writer");
@@ -98,17 +98,20 @@ function b(xw: XmlWriter, browseName: QualifiedName): string {
98
98
  return translateBrowseName(xw, browseName).toString().replace("ns=0;", "");
99
99
  }
100
100
 
101
- function _dumpReverseReferences(xw: XmlWriter, node: BaseNode) {
102
- const addressSpace = node.addressSpace;
103
- const hasSubtypeReferenceType = addressSpace.findReferenceType("HasSubtype")!;
101
+ function _hasHigherPriorityThan(xw: XmlWriter, namespaceIndex1: number, namespaceIndex2: number) {
102
+ assert(xw.priorityTable, "expecting a priorityTable");
103
+ assert(namespaceIndex1 < xw.priorityTable.length);
104
+ assert(namespaceIndex2 < xw.priorityTable.length);
105
+ return hasHigherPriorityThan(namespaceIndex1, namespaceIndex2, xw.priorityTable);
104
106
  }
107
+
105
108
  function _dumpReferences(xw: XmlWriter, node: BaseNode) {
106
109
  xw.startElement("References");
107
110
 
108
111
  const addressSpace = node.addressSpace;
109
112
 
110
113
  const aggregateReferenceType = addressSpace.findReferenceType("Aggregates")!;
111
- const hasChildReferenceType = addressSpace.findReferenceType("HasChild")!;
114
+ // const hasChildReferenceType = addressSpace.findReferenceType("HasChild")!;
112
115
  const hasSubtypeReferenceType = addressSpace.findReferenceType("HasSubtype")!;
113
116
  const hasTypeDefinitionReferenceType = addressSpace.findReferenceType("HasTypeDefinition")!;
114
117
  const nonHierarchicalReferencesType = addressSpace.findReferenceType("NonHierarchicalReferences")!;
@@ -119,6 +122,13 @@ function _dumpReferences(xw: XmlWriter, node: BaseNode) {
119
122
  function referenceToKeep(reference: UAReference): boolean {
120
123
  const referenceType = (reference as ReferenceImpl)._referenceType!;
121
124
 
125
+ const targetedNamespaceIndex = reference.nodeId.namespace;
126
+ if (_hasHigherPriorityThan(xw, targetedNamespaceIndex, node.nodeId.namespace)) {
127
+ // this reference has nothing to do here ! drop it
128
+ // because the target namespace is higher in the hierarchy
129
+ return false;
130
+ }
131
+
122
132
  // get the direct backward reference to a external namespace
123
133
  if (referenceType.isSupertypeOf(aggregateReferenceType) && !reference.isForward) {
124
134
  if (reference.nodeId.namespace !== node.nodeId.namespace) {
@@ -128,7 +138,9 @@ function _dumpReferences(xw: XmlWriter, node: BaseNode) {
128
138
  return true;
129
139
  }
130
140
  }
131
-
141
+ if (referenceType.isSupertypeOf(hasSubtypeReferenceType) && reference.isForward) {
142
+ // return false;
143
+ }
132
144
  // only keep
133
145
  if (referenceType.isSupertypeOf(aggregateReferenceType) && reference.isForward) {
134
146
  return true;
@@ -154,8 +166,6 @@ function _dumpReferences(xw: XmlWriter, node: BaseNode) {
154
166
  if (getReferenceType(reference).browseName.toString() === "HasSubtype" && reference.isForward) {
155
167
  continue;
156
168
  }
157
-
158
- // only output inverse Reference
159
169
  xw.startElement("Reference");
160
170
 
161
171
  xw.writeAttribute("ReferenceType", b(xw, getReferenceType(reference).browseName));
@@ -665,7 +675,6 @@ function _dumpArrayDimensionsAttribute(xw: XmlWriter, node: UAVariableType | UAV
665
675
  }
666
676
 
667
677
  function visitUANode(node: BaseNode, data: DumpData, forward: boolean) {
668
- assert(typeof forward === "boolean");
669
678
 
670
679
  const addressSpace = node.addressSpace;
671
680
 
@@ -772,7 +781,9 @@ function dumpCommonAttributes(xw: XmlWriter, node: BaseNode) {
772
781
 
773
782
  const parentNode = getParent(node);
774
783
  if (parentNode) {
775
- xw.writeAttribute("ParentNodeId", n(xw, parentNode.nodeId));
784
+ if (parentNode.nodeId.namespace <= node.nodeId.namespace) {
785
+ xw.writeAttribute("ParentNodeId", n(xw, parentNode.nodeId));
786
+ }
776
787
  }
777
788
  if (Object.prototype.hasOwnProperty.call(node, "symbolicName")) {
778
789
  xw.writeAttribute("SymbolicName", (node as any).symbolicName);
@@ -788,6 +799,12 @@ function dumpCommonAttributes(xw: XmlWriter, node: BaseNode) {
788
799
  xw.writeAttribute("AccessLevel", (node as UAVariable).accessLevel.toString());
789
800
  }
790
801
  }
802
+ if (Object.prototype.hasOwnProperty.call(node, "minimumSamplingInterval")) {
803
+ const minimumSamplingInterval =(node as UAVariable).minimumSamplingInterval;
804
+ if (minimumSamplingInterval > 0) {
805
+ xw.writeAttribute("MinimumSamplingInterval", minimumSamplingInterval);
806
+ }
807
+ }
791
808
  }
792
809
 
793
810
  function dumpCommonElements(xw: XmlWriter, node: BaseNode) {
@@ -800,11 +817,11 @@ function coerceInt64ToInt32(int64: Int64): number {
800
817
  if (typeof int64 === "number") {
801
818
  return int64 as number;
802
819
  }
803
- if (int64[0] === 4294967295 && int64[1] === 4294967295) {
820
+ if (int64[0] === 0xffffffff && int64[1] === 0xffffffff) {
804
821
  return 0xffffffff;
805
822
  }
806
823
  if (int64[0] !== 0) {
807
- debugLog("coerceInt64ToInt32 , loosing high word in conversion");
824
+ warningLog("coerceInt64ToInt32 , loosing high word in conversion");
808
825
  }
809
826
  return int64[1];
810
827
  }
@@ -831,8 +848,8 @@ function _dumpStructureDefinition(
831
848
  * note: baseDataType and defaultEncodingId are implicit and not stored in the XML file ??
832
849
  *
833
850
  */
834
- const baseDataType = structureDefinition.baseDataType;
835
- const defaultEncodingId = structureDefinition.defaultEncodingId;
851
+ // const baseDataType = structureDefinition.baseDataType;
852
+ // const defaultEncodingId = structureDefinition.defaultEncodingId;
836
853
 
837
854
  // do not repeat elements that are already defined in base structure in the xml ouput!
838
855
  const fields = structureDefinition.fields || [];
@@ -927,9 +944,7 @@ function dumpUADataType(xw: XmlWriter, node: UADataType) {
927
944
  xw.writeAttribute("IsAbstract", node.isAbstract ? "true" : "false");
928
945
  }
929
946
 
930
- _dumpDisplayName(xw, node);
931
-
932
- _dumpReferences(xw, node);
947
+ dumpCommonElements(xw, node);
933
948
 
934
949
  _dumpUADataTypeDefinition(xw, node);
935
950
 
@@ -1015,11 +1030,11 @@ function dumpUAVariableType(xw: XmlWriter, node: UAVariableType) {
1015
1030
  // throw new Error(" cannot find datatype " + node.dataType);
1016
1031
  console.log(
1017
1032
  " cannot find datatype " +
1018
- node.dataType +
1019
- " for node " +
1020
- node.browseName.toString() +
1021
- " id =" +
1022
- node.nodeId.toString()
1033
+ node.dataType +
1034
+ " for node " +
1035
+ node.browseName.toString() +
1036
+ " id =" +
1037
+ node.nodeId.toString()
1023
1038
  );
1024
1039
  } else {
1025
1040
  const dataTypeName = b(xw, resolveDataTypeName(addressSpace, dataTypeNode.nodeId));
@@ -1088,11 +1103,18 @@ function dumpAggregates(xw: XmlWriter, node: BaseNode) {
1088
1103
  // Xx xw.writeComment("Aggregates {{ ");
1089
1104
  const aggregates = node
1090
1105
  .getAggregates()
1091
- .sort((x: BaseNode, y: BaseNode) => (x.browseName.name!.toString() > y.browseName.name!.toString() ? 1 : -1));
1106
+ .sort(sortByBrowseName);
1107
+ // const aggregates = node.findReferencesExAsObject("Aggregates", BrowseDirection.Forward);
1108
+
1092
1109
  for (const aggregate of aggregates.sort(sortByNodeId)) {
1093
1110
  // do not export node that do not belong to our namespace
1094
1111
  if (node.nodeId.namespace !== aggregate.nodeId.namespace) {
1095
- return;
1112
+ continue;
1113
+ }
1114
+ // even further! we should export here the children
1115
+ // that have been added later by a namespace with higher index
1116
+ if (_hasHigherPriorityThan(xw, aggregate.nodeId.namespace, node.nodeId.namespace)) {
1117
+ continue;
1096
1118
  }
1097
1119
  if (!xw.visitedNode[_hash(aggregate)]) {
1098
1120
  (<BaseNodeImpl>aggregate).dumpXML(xw);
@@ -1219,18 +1241,15 @@ function writeAliases(xw: XmlWriter, aliases: Record<string, NodeIdString>) {
1219
1241
  }
1220
1242
  xw.endElement();
1221
1243
  }
1222
- interface ITranslationTable {
1223
- [key: number]: number;
1224
- }
1225
1244
 
1226
- function constructNamespaceTranslationTable(dependency: INamespace[]): ITranslationTable {
1245
+
1246
+ export function constructNamespaceTranslationTable(dependency: INamespace[]): ITranslationTable {
1227
1247
  const translationTable: ITranslationTable = {};
1228
1248
  for (let i = 0; i < dependency.length; i++) {
1229
1249
  translationTable[dependency[i].index] = i;
1230
1250
  }
1231
1251
  return translationTable;
1232
1252
  }
1233
-
1234
1253
  function dumpReferenceType(xw: XmlWriter, referenceType: UAReferenceType) {
1235
1254
  _markAsVisited(xw, referenceType);
1236
1255
 
@@ -1249,7 +1268,7 @@ function dumpReferenceType(xw: XmlWriter, referenceType: UAReferenceType) {
1249
1268
  xw.endElement();
1250
1269
  }
1251
1270
 
1252
- function sortByBrowseName(x: BaseNode, y: BaseNode): number {
1271
+ export function sortByBrowseName(x: BaseNode, y: BaseNode): number {
1253
1272
  const x_str = x.browseName.toString();
1254
1273
  const y_str = y.browseName.toString();
1255
1274
  if (x_str > y_str) {
@@ -1281,56 +1300,6 @@ export interface DumpXMLOptions {
1281
1300
  /** */
1282
1301
  }
1283
1302
 
1284
- export function dumpXml(node: BaseNode, options: DumpXMLOptions): void {
1285
- const namespace = node.namespace as NamespacePrivate;
1286
-
1287
- // make a first visit so that we determine which node to output and in which order
1288
- const data: DumpData = { aliases: {}, aliases_visited: {}, index_el: {}, elements: [] };
1289
-
1290
- const dependency = constructNamespaceDependency(namespace);
1291
- const translationTable = constructNamespaceTranslationTable(dependency);
1292
-
1293
- const xw = new XMLWriter(true);
1294
- xw.translationTable = translationTable;
1295
-
1296
- visitUANode(node, data, false);
1297
-
1298
- xw.startDocument({ encoding: "utf-8" });
1299
- xw.startElement("UANodeSet");
1300
- xw.writeAttribute("xmlns:xs", "http://www.w3.org/2001/XMLSchema-instance");
1301
- xw.writeAttribute("xmlns:xsd", "http://www.w3.org/2001/XMLSchema");
1302
- xw.writeAttribute("Version", "1.02");
1303
- xw.writeAttribute("LastModified", new Date().toISOString());
1304
- xw.writeAttribute("xmlns", "http://opcfoundation.org/UA/2011/03/UANodeSet.xsd");
1305
-
1306
- buildUpAliases(node, xw, data);
1307
- writeAliases(xw, data.aliases);
1308
-
1309
- const xmlNamspace = {
1310
- default: { namespace: "http://opcfoundation.org/UA/2011/03/UANodeSet.xsd" }
1311
- };
1312
-
1313
- xw.startElement("Extensions");
1314
- {
1315
- xw.startElement("Extension");
1316
- {
1317
- xw.startElement("ModelInfo");
1318
- xw.writeAttribute("NodeOPCUA");
1319
- xw.endElement();
1320
- }
1321
- xw.endElement();
1322
- }
1323
- xw.endElement();
1324
-
1325
- for (const el of data.elements!) {
1326
- el.dumpXML(xw);
1327
- }
1328
-
1329
- xw.endElement();
1330
- xw.endDocument();
1331
- return xw.toString();
1332
- }
1333
-
1334
1303
  UAMethodImpl.prototype.dumpXML = function (xw) {
1335
1304
  dumpUAMethod(xw, this);
1336
1305
  };
@@ -1360,17 +1329,21 @@ function makeTypeXsd(namespaceUri: string): string {
1360
1329
 
1361
1330
  // eslint-disable-next-line max-statements
1362
1331
  NamespaceImpl.prototype.toNodeset2XML = function (this: NamespaceImpl) {
1363
- const dependency = constructNamespaceDependency(this);
1364
- const translationTable = constructNamespaceTranslationTable(dependency);
1332
+
1365
1333
 
1366
1334
  const namespaceArrayNode = this.addressSpace.findNode(VariableIds.Server_NamespaceArray);
1367
1335
  const namespaceArray: string[] = namespaceArrayNode
1368
1336
  ? namespaceArrayNode.readAttribute(null, AttributeIds.Value).value.value
1369
1337
  : [];
1370
1338
 
1371
- const xw = new XMLWriter(true);
1339
+ const xw: XmlWriter = new XMLWriter(true);
1340
+
1341
+ xw.priorityTable = constructNamespacePriorityTable(this);
1342
+ const dependency = constructNamespaceDependency(this, xw.priorityTable);
1343
+ const translationTable = constructNamespaceTranslationTable(dependency);
1372
1344
  xw.translationTable = translationTable;
1373
1345
 
1346
+
1374
1347
  xw.startDocument({ encoding: "utf-8", version: "1.0" });
1375
1348
  xw.startElement("UANodeSet");
1376
1349
 
@@ -31,7 +31,6 @@ import { get_subtypeOf } from "./tool_isSupertypeOf";
31
31
  import { get_subtypeOfObj } from "./tool_isSupertypeOf";
32
32
  import { BaseNode_getCache } from "./base_node_private";
33
33
 
34
-
35
34
  export interface UADataTypeImpl {
36
35
  _extensionObjectConstructor: ExtensionObjectConstructorFuncWithSchema;
37
36
  }
@@ -46,6 +45,7 @@ export interface EnumerationInfo {
46
45
  }
47
46
  export interface UADataTypeOptions extends InternalBaseNodeOptions {
48
47
  partialDefinition: StructureFieldOptions[] | EnumFieldOptions[];
48
+ isUnion?: boolean;
49
49
  isAbstract?: boolean;
50
50
  symbolicName?: string;
51
51
  }
@@ -78,6 +78,7 @@ export class UADataTypeImpl extends BaseNodeImpl implements UADataType {
78
78
 
79
79
  public readonly isAbstract: boolean;
80
80
 
81
+ private $isUnion?: boolean;
81
82
  private enumStrings?: any;
82
83
  private enumValues?: any;
83
84
  private $partialDefinition?: StructureFieldOptions[] | EnumFieldOptions[];
@@ -87,6 +88,7 @@ export class UADataTypeImpl extends BaseNodeImpl implements UADataType {
87
88
  super(options);
88
89
  if (options.partialDefinition) {
89
90
  this.$partialDefinition = options.partialDefinition;
91
+ this.$isUnion = options.isUnion;
90
92
  }
91
93
  this.isAbstract = options.isAbstract === undefined || options.isAbstract === null ? false : options.isAbstract;
92
94
  this.symbolicName = options.symbolicName || this.browseName.name!;
@@ -146,8 +148,9 @@ export class UADataTypeImpl extends BaseNodeImpl implements UADataType {
146
148
 
147
149
  public getEncodingNode(encoding_name: string): UAObject | null {
148
150
  const _cache = BaseNode_getCache(this);
151
+ _cache._encoding = _cache._encoding || {};
149
152
  const key = encoding_name + "Node";
150
- if (_cache[key] === undefined) {
153
+ if (_cache._encoding[key] === undefined) {
151
154
  assert(encoding_name === "Default Binary" || encoding_name === "Default XML" || encoding_name === "Default JSON");
152
155
  // could be binary or xml
153
156
  const refs = this.findReferences("HasEncoding", true);
@@ -157,24 +160,18 @@ export class UADataTypeImpl extends BaseNodeImpl implements UADataType {
157
160
  .filter((obj: any) => obj !== null)
158
161
  .filter((obj: any) => obj.browseName.toString() === encoding_name);
159
162
  const node = encoding.length === 0 ? null : (encoding[0] as UAObject);
160
- _cache[key] = node;
163
+ _cache._encoding[key] = node;
161
164
  }
162
- return _cache[key];
165
+ return _cache._encoding[key];
163
166
  }
164
167
 
165
168
  public getEncodingNodeId(encoding_name: string): ExpandedNodeId | null {
166
- const _cache = BaseNode_getCache(this);
167
- const key = encoding_name + "NodeId";
168
- if (_cache[key] === undefined) {
169
- const encoding = this.getEncodingNode(encoding_name);
170
- if (encoding) {
171
- const namespaceUri = this.addressSpace.getNamespaceUri(encoding.nodeId.namespace);
172
- _cache[key] = ExpandedNodeId.fromNodeId(encoding.nodeId, namespaceUri);
173
- } else {
174
- _cache[key] = null;
175
- }
169
+ const encoding = this.getEncodingNode(encoding_name);
170
+ if (!encoding) {
171
+ return null;
176
172
  }
177
- return _cache[key];
173
+ const namespaceUri = this.addressSpace.getNamespaceUri(encoding.nodeId.namespace);
174
+ return ExpandedNodeId.fromNodeId(encoding.nodeId, namespaceUri);
178
175
  }
179
176
  /**
180
177
  * returns the encoding of this node's
@@ -56,7 +56,7 @@ function _getAllSubtypes(ref: UAReferenceType) {
56
56
  function _internal_getSubtypeIndex(referenceType: UAReferenceType): { [key: string]: UAReferenceTypePublic } {
57
57
  const possibleReferenceTypes = _getAllSubtypes(referenceType);
58
58
  // create a index of reference type with browseName as key for faster search
59
- const keys: any = {};
59
+ const keys: Record<string, UAReferenceType> = {};
60
60
  for (const refType of possibleReferenceTypes) {
61
61
  keys[refType.nodeId.toString()] = refType;
62
62
  }
@@ -65,7 +65,7 @@ function _internal_getSubtypeIndex(referenceType: UAReferenceType): { [key: stri
65
65
 
66
66
  function _getSubtypeIndex(referenceType: UAReferenceType): { [key: string]: UAReferenceTypePublic } {
67
67
  const _cache = BaseNode_getCache(referenceType);
68
- if (!_cache._subtype_idx || _cache._subtype_idxVersion < ReferenceTypeCounter.count) {
68
+ if (!_cache._subtype_idx || (_cache._subtype_idxVersion && _cache._subtype_idxVersion < ReferenceTypeCounter.count)) {
69
69
  // the cache need to be invalidated
70
70
  _cache._subtype_idx = null;
71
71
  }