node-opcua-address-space 2.86.0 → 2.87.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 (69) hide show
  1. package/dist/source/address_space_ts.d.ts +3 -3
  2. package/dist/source/address_space_ts.js +3 -3
  3. package/dist/source/address_space_ts.js.map +1 -1
  4. package/dist/source/helpers/call_helpers.d.ts +1 -1
  5. package/dist/source/helpers/multiform_func.d.ts +8 -8
  6. package/dist/source/index.d.ts +1 -0
  7. package/dist/source/index.js +1 -0
  8. package/dist/source/index.js.map +1 -1
  9. package/dist/source/interfaces/alarms_and_conditions/ua_condition_ex.d.ts +1 -1
  10. package/dist/source/interfaces/extension_object_constructor.d.ts +1 -1
  11. package/dist/source/interfaces/state_machine/ua_state_machine_type.d.ts +2 -2
  12. package/dist/source/loader/generateAddressSpaceRaw.d.ts +2 -2
  13. package/dist/source/loader/make_xml_extension_object_parser.d.ts +1 -1
  14. package/dist/source/loader/namespace_post_step.d.ts +1 -1
  15. package/dist/source/session_context.d.ts +1 -1
  16. package/dist/src/address_space.js +11 -11
  17. package/dist/src/address_space.js.map +1 -1
  18. package/dist/src/apply_condition_refresh.d.ts +1 -1
  19. package/dist/src/base_node_impl.js +44 -44
  20. package/dist/src/base_node_impl.js.map +1 -1
  21. package/dist/src/base_node_private.js +7 -6
  22. package/dist/src/base_node_private.js.map +1 -1
  23. package/dist/src/event_data.d.ts +2 -2
  24. package/dist/src/index_current.d.ts +1 -0
  25. package/dist/src/index_current.js +1 -0
  26. package/dist/src/index_current.js.map +1 -1
  27. package/dist/src/namespace_impl.js +7 -4
  28. package/dist/src/namespace_impl.js.map +1 -1
  29. package/dist/src/nodeid_manager.d.ts +8 -8
  30. package/dist/src/nodeid_manager.js +71 -97
  31. package/dist/src/nodeid_manager.js.map +1 -1
  32. package/dist/src/nodeset_tools/construct_namespace_dependency.d.ts +14 -0
  33. package/dist/src/nodeset_tools/construct_namespace_dependency.js +21 -1
  34. package/dist/src/nodeset_tools/construct_namespace_dependency.js.map +1 -1
  35. package/dist/src/nodeset_tools/nodeset_to_xml.d.ts +2 -4
  36. package/dist/src/nodeset_tools/nodeset_to_xml.js +24 -10
  37. package/dist/src/nodeset_tools/nodeset_to_xml.js.map +1 -1
  38. package/dist/src/private_namespace.d.ts +5 -0
  39. package/dist/src/private_namespace.js +20 -0
  40. package/dist/src/private_namespace.js.map +1 -0
  41. package/dist/src/reference_impl.js +6 -6
  42. package/dist/src/reference_impl.js.map +1 -1
  43. package/dist/src/tool_isSupertypeOf.d.ts +4 -4
  44. package/dist/src/ua_data_type_impl.js +12 -12
  45. package/dist/src/ua_data_type_impl.js.map +1 -1
  46. package/dist/src/ua_method_impl.js +6 -6
  47. package/dist/src/ua_method_impl.js.map +1 -1
  48. package/dist/src/ua_object_impl.js +7 -7
  49. package/dist/src/ua_object_impl.js.map +1 -1
  50. package/dist/src/ua_object_type_impl.js +6 -6
  51. package/dist/src/ua_object_type_impl.js.map +1 -1
  52. package/dist/src/ua_reference_type_impl.d.ts +1 -1
  53. package/dist/src/ua_reference_type_impl.js +6 -6
  54. package/dist/src/ua_reference_type_impl.js.map +1 -1
  55. package/dist/src/ua_variable_impl.js +10 -10
  56. package/dist/src/ua_variable_impl.js.map +1 -1
  57. package/dist/src/ua_variable_type_impl.js +6 -6
  58. package/dist/src/ua_variable_type_impl.js.map +1 -1
  59. package/dist/src/ua_view_impl.js +3 -3
  60. package/dist/src/ua_view_impl.js.map +1 -1
  61. package/package.json +24 -24
  62. package/source/index.ts +1 -0
  63. package/src/base_node_private.ts +52 -48
  64. package/src/index_current.ts +1 -0
  65. package/src/namespace_impl.ts +23 -20
  66. package/src/nodeid_manager.ts +84 -100
  67. package/src/nodeset_tools/construct_namespace_dependency.ts +30 -9
  68. package/src/nodeset_tools/nodeset_to_xml.ts +30 -14
  69. package/src/private_namespace.ts +18 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "node-opcua-address-space",
3
- "version": "2.86.0",
3
+ "version": "2.87.0",
4
4
  "description": "pure nodejs OPCUA SDK - module -address-space",
5
5
  "main": "./dist/src/index_current.js",
6
6
  "types": "./dist/source/index.d.ts",
@@ -22,35 +22,35 @@
22
22
  "chalk": "4.1.2",
23
23
  "dequeue": "^1.0.5",
24
24
  "lodash": "4.17.21",
25
- "node-opcua-address-space-base": "2.86.0",
25
+ "node-opcua-address-space-base": "2.87.0",
26
26
  "node-opcua-assert": "2.77.0",
27
- "node-opcua-basic-types": "2.86.0",
27
+ "node-opcua-basic-types": "2.86.1",
28
28
  "node-opcua-binary-stream": "2.86.0",
29
- "node-opcua-client-dynamic-extension-object": "2.86.0",
29
+ "node-opcua-client-dynamic-extension-object": "2.87.0",
30
30
  "node-opcua-constants": "2.77.0",
31
31
  "node-opcua-crypto": "^2.1.2",
32
- "node-opcua-data-access": "2.86.0",
33
- "node-opcua-data-model": "2.86.0",
34
- "node-opcua-data-value": "2.86.0",
32
+ "node-opcua-data-access": "2.87.0",
33
+ "node-opcua-data-model": "2.86.1",
34
+ "node-opcua-data-value": "2.87.0",
35
35
  "node-opcua-date-time": "2.86.0",
36
36
  "node-opcua-debug": "2.86.0",
37
37
  "node-opcua-enum": "2.86.0",
38
- "node-opcua-extension-object": "2.86.0",
39
- "node-opcua-factory": "2.86.0",
38
+ "node-opcua-extension-object": "2.86.1",
39
+ "node-opcua-factory": "2.86.1",
40
40
  "node-opcua-nodeid": "2.86.0",
41
- "node-opcua-nodeset-ua": "2.86.0",
42
- "node-opcua-numeric-range": "2.86.0",
41
+ "node-opcua-nodeset-ua": "2.87.0",
42
+ "node-opcua-numeric-range": "2.86.1",
43
43
  "node-opcua-object-registry": "2.86.0",
44
- "node-opcua-pseudo-session": "2.86.0",
45
- "node-opcua-service-browse": "2.86.0",
46
- "node-opcua-service-call": "2.86.0",
47
- "node-opcua-service-history": "2.86.0",
48
- "node-opcua-service-translate-browse-path": "2.86.0",
49
- "node-opcua-service-write": "2.86.0",
50
- "node-opcua-status-code": "2.86.0",
51
- "node-opcua-types": "2.86.0",
44
+ "node-opcua-pseudo-session": "2.87.0",
45
+ "node-opcua-service-browse": "2.87.0",
46
+ "node-opcua-service-call": "2.87.0",
47
+ "node-opcua-service-history": "2.87.0",
48
+ "node-opcua-service-translate-browse-path": "2.87.0",
49
+ "node-opcua-service-write": "2.87.0",
50
+ "node-opcua-status-code": "2.86.1",
51
+ "node-opcua-types": "2.87.0",
52
52
  "node-opcua-utils": "2.86.0",
53
- "node-opcua-variant": "2.86.0",
53
+ "node-opcua-variant": "2.87.0",
54
54
  "node-opcua-xml2json": "2.86.0",
55
55
  "semver": "^7.3.8",
56
56
  "set-prototype-of": "^1.0.0",
@@ -62,9 +62,9 @@
62
62
  "node-opcua-benchmarker": "2.86.0",
63
63
  "node-opcua-leak-detector": "2.86.0",
64
64
  "node-opcua-nodesets": "2.77.0",
65
- "node-opcua-packet-analyzer": "2.86.0",
66
- "node-opcua-service-filter": "2.86.0",
67
- "node-opcua-test-fixtures": "2.86.0",
65
+ "node-opcua-packet-analyzer": "2.86.1",
66
+ "node-opcua-service-filter": "2.87.0",
67
+ "node-opcua-test-fixtures": "2.87.0",
68
68
  "should": "^13.2.3",
69
69
  "sinon": "^14.0.2",
70
70
  "source-map-support": "^0.5.21"
@@ -84,5 +84,5 @@
84
84
  "internet of things"
85
85
  ],
86
86
  "homepage": "http://node-opcua.github.io/",
87
- "gitHead": "36afc46fe2c91aa5664a8c5418f4db5a354670c3"
87
+ "gitHead": "cf789b56916b6c0974c17337352ef9581d50ddb0"
88
88
  }
package/source/index.ts CHANGED
@@ -63,6 +63,7 @@ export * from "./loader/register_node_promoter";
63
63
 
64
64
  export * from "./namespace";
65
65
  export * from "./namespace_data_access";
66
+ export * from "../src/private_namespace";
66
67
 
67
68
  export { instantiateCertificateExpirationAlarm } from "../src/alarms_and_conditions/ua_certificate_expiration_alarm_impl";
68
69
 
@@ -13,7 +13,7 @@ import {
13
13
  NodeClass,
14
14
  ResultMask
15
15
  } from "node-opcua-data-model";
16
- import { checkDebugFlag, make_warningLog } from "node-opcua-debug";
16
+ import { checkDebugFlag, make_warningLog, make_errorLog } from "node-opcua-debug";
17
17
  import { NodeId, resolveNodeId, sameNodeId } from "node-opcua-nodeid";
18
18
  import { ReferenceDescription } from "node-opcua-types";
19
19
  import {
@@ -43,8 +43,9 @@ import { AddressSpacePrivate } from "./address_space_private";
43
43
  import { wipeMemorizedStuff } from "./tool_isSupertypeOf";
44
44
 
45
45
  // eslint-disable-next-line prefer-const
46
- let doTrace = checkDebugFlag("INSTANTIATE");
47
- const traceLog = console.log.bind(console);
46
+ const errorLog = make_errorLog(__filename);
47
+ const doTrace = checkDebugFlag("INSTANTIATE");
48
+ const traceLog = errorLog;
48
49
 
49
50
  const g_weakMap = new WeakMap();
50
51
 
@@ -189,8 +190,8 @@ export function BaseNode_toString(this: BaseNode, options: ToStringOption): void
189
190
  options.add(options.padding + chalk.yellow(" browseName : ") + this.browseName.toString());
190
191
  options.add(
191
192
  options.padding +
192
- chalk.yellow(" displayName : ") +
193
- this.displayName.map((f) => f.locale + " " + f.text).join(" | ")
193
+ chalk.yellow(" displayName : ") +
194
+ this.displayName.map((f) => f.locale + " " + f.text).join(" | ")
194
195
  );
195
196
 
196
197
  options.add(
@@ -209,9 +210,9 @@ export function BaseNode_References_toString(this: BaseNode, options: ToStringOp
209
210
 
210
211
  options.add(
211
212
  options.padding +
212
- chalk.yellow(" references : ") +
213
- " length =" +
214
- Object.keys(_private._referenceIdx).length
213
+ chalk.yellow(" references : ") +
214
+ " length =" +
215
+ Object.keys(_private._referenceIdx).length
215
216
  );
216
217
 
217
218
  function dump_reference(follow: boolean, reference: UAReference | null) {
@@ -250,12 +251,12 @@ export function BaseNode_References_toString(this: BaseNode, options: ToStringOp
250
251
  })();
251
252
  options.add(
252
253
  options.padding +
253
- chalk.yellow(" +-> ") +
254
- reference.toString(displayOptions) +
255
- " " +
256
- chalk.cyan(name.padEnd(25, " ")) +
257
- " " +
258
- chalk.magentaBright(extra)
254
+ chalk.yellow(" +-> ") +
255
+ reference.toString(displayOptions) +
256
+ " " +
257
+ chalk.cyan(name.padEnd(25, " ")) +
258
+ " " +
259
+ chalk.magentaBright(extra)
259
260
  );
260
261
 
261
262
  // ignore HasTypeDefinition as it has been already handled
@@ -284,10 +285,10 @@ export function BaseNode_References_toString(this: BaseNode, options: ToStringOp
284
285
 
285
286
  options.add(
286
287
  options.padding +
287
- chalk.yellow(" back_references : ") +
288
- chalk.cyan(" length =") +
289
- br.length +
290
- chalk.grey(" ( references held by other nodes involving this node)")
288
+ chalk.yellow(" back_references : ") +
289
+ chalk.cyan(" length =") +
290
+ br.length +
291
+ chalk.grey(" ( references held by other nodes involving this node)")
291
292
  );
292
293
  // backward reference
293
294
  br.forEach(dump_reference.bind(null, false));
@@ -297,11 +298,11 @@ function _UAType_toString(this: UAReferenceType | UADataType | UAObjectType | UA
297
298
  if (this.subtypeOfObj) {
298
299
  options.add(
299
300
  options.padding +
300
- chalk.yellow(" subtypeOf : ") +
301
- this.subtypeOfObj.browseName.toString() +
302
- " (" +
303
- this.subtypeOfObj.nodeId.toString() +
304
- ")"
301
+ chalk.yellow(" subtypeOf : ") +
302
+ this.subtypeOfObj.browseName.toString() +
303
+ " (" +
304
+ this.subtypeOfObj.nodeId.toString() +
305
+ ")"
305
306
  );
306
307
  }
307
308
  }
@@ -310,11 +311,11 @@ function _UAInstance_toString(this: UAVariable | UAMethod | UAObject, options: T
310
311
  if (this.typeDefinitionObj) {
311
312
  options.add(
312
313
  options.padding +
313
- chalk.yellow(" typeDefinition : ") +
314
- this.typeDefinitionObj.browseName.toString() +
315
- " (" +
316
- this.typeDefinitionObj.nodeId.toString() +
317
- ")"
314
+ chalk.yellow(" typeDefinition : ") +
315
+ this.typeDefinitionObj.browseName.toString() +
316
+ " (" +
317
+ this.typeDefinitionObj.nodeId.toString() +
318
+ ")"
318
319
  );
319
320
  }
320
321
  }
@@ -421,9 +422,9 @@ export function VariableOrVariableType_toString(this: UAVariableType | UAVariabl
421
422
  if (_dataValue) {
422
423
  options.add(
423
424
  options.padding +
424
- chalk.yellow(" value : ") +
425
- "\n" +
426
- options.indent(_dataValue.toString(), options.padding + " | ")
425
+ chalk.yellow(" value : ") +
426
+ "\n" +
427
+ options.indent(_dataValue.toString(), options.padding + " | ")
427
428
  );
428
429
  }
429
430
  }
@@ -440,19 +441,19 @@ export function VariableOrVariableType_toString(this: UAVariableType | UAVariabl
440
441
  if (this.minimumSamplingInterval !== undefined) {
441
442
  options.add(
442
443
  options.padding +
443
- chalk.yellow(" minimumSamplingInterval : ") +
444
- " " +
445
- this.minimumSamplingInterval.toString() +
446
- " ms"
444
+ chalk.yellow(" minimumSamplingInterval : ") +
445
+ " " +
446
+ this.minimumSamplingInterval.toString() +
447
+ " ms"
447
448
  );
448
449
  }
449
450
  if (this.arrayDimensions) {
450
451
  options.add(
451
452
  options.padding +
452
- chalk.yellow(" arrayDimension : ") +
453
- " [" +
454
- this.arrayDimensions.join(",").toString() +
455
- " ]"
453
+ chalk.yellow(" arrayDimension : ") +
454
+ " [" +
455
+ this.arrayDimensions.join(",").toString() +
456
+ " ]"
456
457
  );
457
458
  }
458
459
  }
@@ -494,11 +495,11 @@ function _clone_collection_new(
494
495
  // tslint:disable-next-line:no-console
495
496
  warningLog(
496
497
  chalk.red("Warning : cannot clone node ") +
497
- node.browseName.toString() +
498
- " of class " +
499
- NodeClass[node.nodeClass].toString() +
500
- " while cloning " +
501
- newParent.browseName.toString()
498
+ node.browseName.toString() +
499
+ " of class " +
500
+ NodeClass[node.nodeClass].toString() +
501
+ " while cloning " +
502
+ newParent.browseName.toString()
502
503
  );
503
504
  continue;
504
505
  }
@@ -535,6 +536,11 @@ function _clone_collection_new(
535
536
  extraInfo.level += 4;
536
537
  const clone = (node as UAVariable | UAMethod | UAObject).clone(options, optionalFilter, extraInfo);
537
538
  extraInfo.level -= 4;
539
+ doTrace &&
540
+ traceLog(
541
+ extraInfo.pad(),
542
+ "cloning => ", node.browseName.toString(), "nodeId", clone.nodeId.toString()
543
+ );
538
544
 
539
545
  // also clone or instantiate interface members that may be required in the optionals
540
546
  extraInfo.level++;
@@ -610,7 +616,7 @@ function _extractInterfaces2(typeDefinitionNode: UAObjectType | UAVariableType,
610
616
  }
611
617
  const dedupedInterfaces = [...new Set(interfaces)];
612
618
 
613
- doTrace &&
619
+ doTrace && dedupedInterfaces.length &&
614
620
  traceLog(
615
621
  extraInfo.pad(),
616
622
  chalk.yellow("Interface for ", typeDefinitionNode.browseName.toString()),
@@ -693,9 +699,7 @@ function _cloneInterface(
693
699
  }
694
700
  const interfaces = _extractInterfaces2(typeDefinitionNode, extraInfo);
695
701
  if (interfaces.length === 0) {
696
- if (doTrace) {
697
- traceLog(extraInfo.pad(), chalk.yellow("No interface for ", node.browseName.toString(), node.nodeId.toString()));
698
- }
702
+ doTrace && false && traceLog(extraInfo.pad(), chalk.yellow("No interface for ", node.browseName.toString(), node.nodeId.toString()));
699
703
  return;
700
704
  }
701
705
  doTrace && traceLog(extraInfo?.pad(), chalk.green("-------------------- interfaces are ", interfaces.length));
@@ -51,6 +51,7 @@ export * from "./data_access/ua_two_state_discrete_impl";
51
51
 
52
52
  export { VariableHistorian } from "./historical_access/address_space_historical_data_node";
53
53
  export { NodeIdManager } from "../src/nodeid_manager";
54
+ export * from "../src/private_namespace";
54
55
 
55
56
  export * from "./alarms_and_conditions";
56
57
  export * from "./event_data";
@@ -640,7 +640,7 @@ export class NamespaceImpl implements NamespacePrivate {
640
640
  const node = this.internalCreateNode(options) as UADataType;
641
641
 
642
642
  node.propagate_back_references();
643
-
643
+
644
644
  return node;
645
645
  }
646
646
 
@@ -1659,32 +1659,35 @@ export class NamespaceImpl implements NamespacePrivate {
1659
1659
  public _register(node: BaseNode): void {
1660
1660
  assert(node instanceof BaseNodeImpl, "Expecting a instance of BaseNode in _register");
1661
1661
  assert(node.nodeId instanceof NodeId, "Expecting a NodeId");
1662
+ // istanbul ignore next
1662
1663
  if (node.nodeId.namespace !== this.index) {
1663
1664
  throw new Error("node must belongs to this namespace");
1664
1665
  }
1665
1666
  assert(node.nodeId.namespace === this.index, "node must belongs to this namespace");
1666
1667
  assert(Object.prototype.hasOwnProperty.call(node, "browseName"), "Node must have a browseName");
1667
- // assert(node.browseName.namespaceIndex === this.index,"browseName must belongs to this namespace");
1668
1668
 
1669
1669
  const hashKey = _makeHashKey(node.nodeId);
1670
1670
 
1671
1671
  // istanbul ignore next
1672
1672
  if (this._nodeid_index.has(hashKey)) {
1673
+
1674
+ const exstingNode = this.findNode(node.nodeId)!;
1673
1675
  throw new Error(
1674
1676
  "node " +
1675
- node.browseName.toString() +
1676
- "nodeId = " +
1677
- node.nodeId.displayText() +
1678
- " already registered " +
1679
- node.nodeId.toString() +
1680
- "\n" +
1681
- " in namespace " +
1682
- this.namespaceUri +
1683
- " index = " +
1684
- this.index +
1685
- "\n" +
1686
- " browseName = " +
1687
- node.browseName.toString()
1677
+ node.browseName.toString() +
1678
+ " nodeId = " +
1679
+ node.nodeId.displayText() +
1680
+ " already registered " +
1681
+ node.nodeId.toString() +
1682
+ "\n" +
1683
+ " in namespace " +
1684
+ this.namespaceUri +
1685
+ " index = " +
1686
+ this.index +
1687
+ "\n" +
1688
+ "existing node = " +
1689
+ exstingNode.toString() +
1690
+ "this parent : " + node.parentNodeId?.toString()
1688
1691
  );
1689
1692
  }
1690
1693
 
@@ -1747,15 +1750,15 @@ export class NamespaceImpl implements NamespacePrivate {
1747
1750
  errorLog(
1748
1751
  chalk.red.bold(
1749
1752
  "Error: namespace index used at the front of the browseName " +
1750
- indexVerif +
1751
- " do not match the index of the current namespace (" +
1752
- this.index +
1753
- ")"
1753
+ indexVerif +
1754
+ " do not match the index of the current namespace (" +
1755
+ this.index +
1756
+ ")"
1754
1757
  )
1755
1758
  );
1756
1759
  errorLog(
1757
1760
  " Please fix your code so that the created node is inserted in the correct namespace," +
1758
- " please refer to the NodeOPCUA documentation"
1761
+ " please refer to the NodeOPCUA documentation"
1759
1762
  );
1760
1763
  }
1761
1764
  }
@@ -3,12 +3,12 @@
3
3
  import { assert } from "node-opcua-assert";
4
4
  import { NodeClass, QualifiedName } from "node-opcua-data-model";
5
5
  import { makeNodeId, NodeId, NodeIdLike, NodeIdType, resolveNodeId, sameNodeId } from "node-opcua-nodeid";
6
- import { make_debugLog } from "node-opcua-debug";
7
-
6
+ import { make_debugLog, make_warningLog } from "node-opcua-debug";
8
7
  import { BaseNode, UAReference, UAReferenceType } from "node-opcua-address-space-base";
9
8
  import { getReferenceType } from "./base_node_impl";
10
9
 
11
10
  const debugLog = make_debugLog(__filename);
11
+ const warningLog = make_warningLog(__filename);
12
12
 
13
13
  export const NamespaceOptions = {
14
14
  nodeIdNameSeparator: "-"
@@ -21,13 +21,17 @@ const regExp1 = /^(s|i|b|g)=/;
21
21
  const regExp2 = /^ns=[0-9]+;(s|i|b|g)=/;
22
22
  const hasPropertyRefId = resolveNodeId("HasProperty");
23
23
  const hasComponentRefId = resolveNodeId("HasComponent");
24
+ const hasOrderedComponentRefId = resolveNodeId("HasOrderedComponent");
24
25
  const hasEncoding = resolveNodeId("HasEncoding");
25
26
 
26
- function _identifyParentInReference(references: UAReference[]): [NodeId, string] | null {
27
+ type Suffix = string;
28
+
29
+ function _identifyParentInReference(references: UAReference[]): [NodeId, Suffix] | null {
27
30
  const candidates = references.filter((r: UAReference) => {
28
31
  return (
29
32
  !r.isForward &&
30
33
  (sameNodeId(r.referenceType, hasComponentRefId) ||
34
+ sameNodeId(r.referenceType, hasOrderedComponentRefId) ||
31
35
  sameNodeId(r.referenceType, hasPropertyRefId) ||
32
36
  sameNodeId(r.referenceType, hasEncoding))
33
37
  );
@@ -43,6 +47,27 @@ function _identifyParentInReference(references: UAReference[]): [NodeId, string]
43
47
  return [ref.nodeId, ""];
44
48
  }
45
49
 
50
+ function _findParentNodeId(addressSpace: AddressSpacePartial, options: ConstructNodeIdOptions): [NodeId, Suffix] | null {
51
+ if (!options.references) {
52
+ return null;
53
+ }
54
+ for (const ref of options.references) {
55
+ (ref as any)._referenceType = addressSpace.findReferenceType(ref.referenceType);
56
+ /* istanbul ignore next */
57
+ if (!getReferenceType(ref)) {
58
+ throw new Error("Cannot find referenceType " + JSON.stringify(ref));
59
+ }
60
+ (ref as any).referenceType = (ref as any)._referenceType.nodeId;
61
+ }
62
+ // find HasComponent, or has Property reverse
63
+ return _identifyParentInReference(options.references);
64
+ }
65
+
66
+ function prepareName(browseName: QualifiedName): string {
67
+ const m = browseName.name!.toString().replace(/[ ]/g, "").replace(/(<|>)/g, "");
68
+ return m;
69
+ }
70
+
46
71
  export interface AddressSpacePartial {
47
72
  findNode(nodeId: NodeIdLike): BaseNode | null;
48
73
  findReferenceType(refType: NodeIdLike, namespaceIndex?: number): UAReferenceType | null;
@@ -58,8 +83,8 @@ export type NodeEntry = [string, number, NodeClass];
58
83
  export type NodeEntry1 = [string, number, string /*"Object" | "Variable" etc...*/];
59
84
 
60
85
  export class NodeIdManager {
61
- private _cache: { [key: string]: number } = {};
62
- private _reverseCache: { [key: number]: { name: string; nodeClass: NodeClass } } = {};
86
+ private _cacheSymbolicName: { [key: string]: [number,NodeClass] } = {};
87
+ private _cacheSymbolicNameRev: Set<number> = new Set<number>();
63
88
 
64
89
  private _internal_id_counter: number;
65
90
  private namespaceIndex: number;
@@ -71,14 +96,6 @@ export class NodeIdManager {
71
96
  this.addressSpace = addressSpace;
72
97
  }
73
98
 
74
- public setCache(cache: NodeEntry[]): void {
75
- this._cache = {};
76
- this._reverseCache = {};
77
- for (const [key, value, nodeClass] of cache) {
78
- this._addInCache(key, value, nodeClass);
79
- }
80
- }
81
-
82
99
  public setSymbols(symbols: NodeEntry1[]): void {
83
100
  function convertNodeClass(nodeClass: string): NodeClass {
84
101
  return (NodeClass as any)[nodeClass as any] as NodeClass;
@@ -88,13 +105,17 @@ export class NodeIdManager {
88
105
  number,
89
106
  NodeClass
90
107
  ][];
91
- this.setCache(symbols2);
108
+ for (const [name, value, nodeClass] of symbols2) {
109
+ this._cacheSymbolicName[name] = [value, nodeClass];
110
+ this._cacheSymbolicNameRev.add(value);
111
+ }
92
112
  }
93
113
 
94
114
  public getSymbols(): NodeEntry1[] {
95
115
  const line: NodeEntry1[] = [];
96
- for (const [key, value] of Object.entries(this._cache)) {
97
- const nodeClass = NodeClass[this._reverseCache[value].nodeClass];
116
+ for (const [key, [value, nodeClass1]] of Object.entries(this._cacheSymbolicName)) {
117
+ const node = this.addressSpace.findNode(makeNodeId(value, this.namespaceIndex));
118
+ const nodeClass = NodeClass[nodeClass1 || NodeClass.Unspecified];
98
119
  line.push([key, value, nodeClass]);
99
120
  }
100
121
  return line;
@@ -113,18 +134,51 @@ export class NodeIdManager {
113
134
  do {
114
135
  nodeId = makeNodeId(this._internal_id_counter, this.namespaceIndex);
115
136
  this._internal_id_counter += 1;
116
- } while (this.addressSpace.findNode(nodeId) || this._isInCache(nodeId.value as number));
137
+ } while (this.addressSpace.findNode(nodeId) || this._isInCache(nodeId));
117
138
  return nodeId;
118
139
  }
119
140
 
120
141
  public constructNodeId(options: ConstructNodeIdOptions): NodeId {
121
- function prepareName(browseName: QualifiedName): string {
122
- const m = browseName.name!.toString().replace(/[ ]/g, "").replace(/(<|>)/g, "");
123
- return m;
142
+
143
+ const compose = (left: string, right: string) => { return right ? (left ? left + '_' + right : right) : left };
144
+
145
+ const buildUpName2 = (nodeId: NodeId, suffix: string) => {
146
+ const namespaceIndex = nodeId.namespace;
147
+ let name = "";
148
+ let n: BaseNode | null = this.addressSpace.findNode(nodeId);
149
+ while (n && n.nodeId.namespace === namespaceIndex) {
150
+ const e = prepareName(n.browseName) + suffix;
151
+ name = compose(e, name);
152
+ n = n.parentNodeId ? this.addressSpace.findNode(n.parentNodeId) : null;
153
+ }
154
+ return name;
124
155
  }
125
- let nodeId = options.nodeId;
126
- const nodeClass = options.nodeClass;
127
156
 
157
+ if (!options.nodeId && options.registerSymbolicNames) {
158
+ const parentInfo = this.findParentNodeId(options);
159
+ let fullParentName = "";
160
+ if (parentInfo) {
161
+ const [parentNodeId, suffix] = parentInfo;
162
+ fullParentName = buildUpName2(parentNodeId, suffix);
163
+ }
164
+ const fullName = compose(fullParentName, prepareName(options.browseName));
165
+ if (this._cacheSymbolicName[fullName]) {
166
+ return makeNodeId(this._cacheSymbolicName[fullName][0], this.namespaceIndex);
167
+ }
168
+ const nodeId = this._constructNodeId(options);
169
+ if (nodeId.identifierType === NodeIdType.NUMERIC) {
170
+ this._cacheSymbolicName[fullName] = [nodeId.value as number, options.nodeClass];
171
+ this._cacheSymbolicNameRev.add(nodeId.value as number);
172
+ }
173
+ return nodeId;
174
+ }
175
+ return this._constructNodeId(options);
176
+ }
177
+
178
+ private _constructNodeId(options: ConstructNodeIdOptions): NodeId {
179
+
180
+ let nodeId = options.nodeId;
181
+
128
182
  if (!nodeId) {
129
183
  const parentInfo = this.findParentNodeId(options);
130
184
  if (parentInfo) {
@@ -136,41 +190,7 @@ export class NodeIdManager {
136
190
  const childName = parentNodeId.value + NamespaceOptions.nodeIdNameSeparator + name;
137
191
  nodeId = new NodeId(NodeId.NodeIdType.STRING, childName, parentNodeId.namespace);
138
192
  return nodeId;
139
- } else if (parentNodeId.identifierType === NodeId.NodeIdType.NUMERIC) {
140
- //
141
- const baseNameInCache = this._reverseCache[parentNodeId.value as number];
142
- if (baseNameInCache) {
143
- const newName = baseNameInCache.name + linkName + "_" + name;
144
- const nodeIdValueInCache = this._cache[newName];
145
- if (nodeIdValueInCache) {
146
- return new NodeId(NodeIdType.NUMERIC, nodeIdValueInCache, this.namespaceIndex);
147
- } else {
148
- return this._getOrCreateFromName(newName, nodeClass);
149
- }
150
- } else {
151
- if (options.registerSymbolicNames) {
152
- const newName = name;
153
- const nodeIdValueInCache = this._cache[newName];
154
- if (nodeIdValueInCache) {
155
- return new NodeId(NodeIdType.NUMERIC, nodeIdValueInCache, this.namespaceIndex);
156
- } else {
157
- return this._getOrCreateFromName(newName, nodeClass);
158
- }
159
- }
160
- }
161
- }
162
- // }} has parent ...
163
- } else {
164
- const isRootType =
165
- options.nodeClass === NodeClass.DataType ||
166
- options.nodeClass === NodeClass.ObjectType ||
167
- options.nodeClass === NodeClass.ReferenceType ||
168
- options.nodeClass === NodeClass.VariableType;
169
- // try to find
170
- if (isRootType) {
171
- const baseName = options.browseName.name!.toString();
172
- return this._getOrCreateFromName(baseName, nodeClass);
173
- }
193
+ }
174
194
  }
175
195
  } else if (typeof nodeId === "string") {
176
196
  if (this.namespaceIndex !== 0) {
@@ -178,8 +198,8 @@ export class NodeIdManager {
178
198
  // nothing
179
199
  } else if (nodeId.match(regExp1)) {
180
200
  nodeId = "ns=" + this.namespaceIndex + ";" + nodeId;
181
- } else {
182
- nodeId = this._getOrCreateFromName(nodeId, nodeClass);
201
+ // } else {
202
+ // nodeId = this._getOrCreateFromName(nodeId, nodeClass);
183
203
  }
184
204
  }
185
205
  }
@@ -193,48 +213,12 @@ export class NodeIdManager {
193
213
  return nodeId;
194
214
  }
195
215
 
196
- public findParentNodeId(options: ConstructNodeIdOptions): [NodeId, string] | null {
197
- if (!options.references) {
198
- return null;
199
- }
200
- for (const ref of options.references) {
201
- (ref as any)._referenceType = this.addressSpace.findReferenceType(ref.referenceType);
202
- /* istanbul ignore next */
203
- if (!getReferenceType(ref)) {
204
- throw new Error("Cannot find referenceType " + JSON.stringify(ref));
205
- }
206
- (ref as any).referenceType = (ref as any)._referenceType.nodeId;
207
- }
208
- // find HasComponent, or has Property reverse
209
- return _identifyParentInReference(options.references);
210
- }
211
-
212
- private _addInCache(name: string, nodeIdValue: number, nodeClass: NodeClass) {
213
- assert(!name.includes(":"), "Alias name should not contain special characters");
214
- assert(typeof name === "string" && name[0] !== "[");
215
- if (this._isInCache(nodeIdValue) || this._cache[name]) {
216
- throw new Error("Already in Cache !" + name + " " + nodeIdValue + " = " + this._cache[name]);
217
- }
218
- this._cache[name] = nodeIdValue;
219
- this._reverseCache[nodeIdValue] = { name, nodeClass };
220
- }
221
-
222
- private _isInCache(nodeIdValue: number) {
223
- return this._reverseCache[nodeIdValue] ? true : false;
216
+ public findParentNodeId(options: ConstructNodeIdOptions): [NodeId, Suffix] | null {
217
+ return _findParentNodeId(this.addressSpace, options);
224
218
  }
225
219
 
226
- private _getOrCreateFromName(aliasName: string, nodeClass: NodeClass): NodeId {
227
- assert(isValidNodeClass(nodeClass), "invalid node class " + nodeClass);
228
- if (aliasName.includes(":")) {
229
- debugLog("alias name should not contain special characters");
230
- }
231
- assert(!aliasName.includes(":"), "Alias name should not contain special characters");
232
- if (this._cache[aliasName]) {
233
- return new NodeId(NodeIdType.NUMERIC, this._cache[aliasName], this.namespaceIndex);
234
- } else {
235
- const nodeIdResult = this.buildNewNodeId();
236
- this._addInCache(aliasName, nodeIdResult.value as number, nodeClass);
237
- return nodeIdResult;
238
- }
220
+ private _isInCache(nodeId: NodeId): boolean {
221
+ if( nodeId.namespace !== this.namespaceIndex || nodeId.identifierType !== NodeIdType.NUMERIC) return false;
222
+ return this._cacheSymbolicNameRev.has(nodeId.value as number) ? true : false;
239
223
  }
240
224
  }