node-opcua-address-space 2.87.0 → 2.89.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 (61) hide show
  1. package/LICENSE +1 -1
  2. package/dist/source/address_space_ts.d.ts +4 -4
  3. package/dist/source/address_space_ts.js +3 -3
  4. package/dist/source/address_space_ts.js.map +1 -1
  5. package/dist/source/helpers/argument_list.js +8 -12
  6. package/dist/source/helpers/argument_list.js.map +1 -1
  7. package/dist/source/helpers/call_helpers.d.ts +1 -1
  8. package/dist/source/helpers/multiform_func.d.ts +8 -8
  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/event_data.d.ts +2 -2
  22. package/dist/src/extension_object_array_node.d.ts +3 -41
  23. package/dist/src/extension_object_array_node.js +20 -54
  24. package/dist/src/extension_object_array_node.js.map +1 -1
  25. package/dist/src/idx_iterator.d.ts +8 -0
  26. package/dist/src/idx_iterator.js +51 -0
  27. package/dist/src/idx_iterator.js.map +1 -0
  28. package/dist/src/nodeid_manager.d.ts +3 -3
  29. package/dist/src/nodeset_tools/nodeset_to_xml.d.ts +1 -1
  30. package/dist/src/reference_impl.js +6 -6
  31. package/dist/src/reference_impl.js.map +1 -1
  32. package/dist/src/tool_isSupertypeOf.d.ts +4 -4
  33. package/dist/src/ua_data_type_impl.js +12 -12
  34. package/dist/src/ua_data_type_impl.js.map +1 -1
  35. package/dist/src/ua_method_impl.js +6 -6
  36. package/dist/src/ua_method_impl.js.map +1 -1
  37. package/dist/src/ua_object_impl.js +7 -7
  38. package/dist/src/ua_object_impl.js.map +1 -1
  39. package/dist/src/ua_object_type_impl.js +6 -6
  40. package/dist/src/ua_object_type_impl.js.map +1 -1
  41. package/dist/src/ua_reference_type_impl.d.ts +1 -1
  42. package/dist/src/ua_reference_type_impl.js +6 -6
  43. package/dist/src/ua_reference_type_impl.js.map +1 -1
  44. package/dist/src/ua_variable_impl.d.ts +15 -9
  45. package/dist/src/ua_variable_impl.js +57 -50
  46. package/dist/src/ua_variable_impl.js.map +1 -1
  47. package/dist/src/ua_variable_impl_ext_obj.d.ts +10 -6
  48. package/dist/src/ua_variable_impl_ext_obj.js +368 -189
  49. package/dist/src/ua_variable_impl_ext_obj.js.map +1 -1
  50. package/dist/src/ua_variable_type_impl.js +7 -7
  51. package/dist/src/ua_variable_type_impl.js.map +1 -1
  52. package/dist/src/ua_view_impl.js +3 -3
  53. package/dist/src/ua_view_impl.js.map +1 -1
  54. package/package.json +40 -40
  55. package/source/address_space_ts.ts +1 -1
  56. package/source/helpers/argument_list.ts +26 -26
  57. package/src/extension_object_array_node.ts +25 -63
  58. package/src/idx_iterator.ts +52 -0
  59. package/src/ua_variable_impl.ts +65 -55
  60. package/src/ua_variable_impl_ext_obj.ts +429 -231
  61. package/src/ua_variable_type_impl.ts +4 -4
@@ -13,6 +13,7 @@ import { VariantArrayType } from "node-opcua-variant";
13
13
  import { ExtensionObject } from "node-opcua-extension-object";
14
14
  import { UADataType, UADynamicVariableArray, UAObject, UAReferenceType, UAVariable } from "node-opcua-address-space-base";
15
15
  import { UAVariableImpl } from "./ua_variable_impl";
16
+ import { getProxyTarget } from "./ua_variable_impl_ext_obj";
16
17
 
17
18
  const doDebug = checkDebugFlag(__filename);
18
19
  const debugLog = make_debugLog(__filename);
@@ -23,7 +24,7 @@ const errorLog = make_errorLog(__filename);
23
24
  *
24
25
  */
25
26
 
26
- function getExtObjArrayNodeValue<T extends ExtensionObject>(this: UADynamicVariableArray<T>) {
27
+ function getExtObjArrayNodeValue<T extends ExtensionObject>(this: UADynamicVariableArray<T>) {
27
28
  return new Variant({
28
29
  arrayType: VariantArrayType.Array,
29
30
  dataType: DataType.ExtensionObject,
@@ -38,7 +39,7 @@ function removeElementByIndex<T extends ExtensionObject>(uaArrayVariableNode: UA
38
39
 
39
40
  const addressSpace = uaArrayVariableNode.addressSpace;
40
41
  const extObj = _array[elementIndex];
41
- const browseName = uaArrayVariableNode.$$getElementBrowseName(extObj);
42
+ const browseName = uaArrayVariableNode.$$getElementBrowseName(extObj, elementIndex);
42
43
 
43
44
  // remove element from global array (inefficient)
44
45
  uaArrayVariableNode.$$extensionObjectArray.splice(elementIndex, 1);
@@ -68,14 +69,6 @@ function removeElementByIndex<T extends ExtensionObject>(uaArrayVariableNode: UA
68
69
  /**
69
70
  *
70
71
  * create a node Variable that contains a array of ExtensionObject of a given type
71
- * @method createExtObjArrayNode
72
- * @param parentFolder
73
- * @param options
74
- * @param options.browseName
75
- * @param options.complexVariableType
76
- * @param options.variableType the type of Extension objects stored in the array.
77
- * @param options.indexPropertyName
78
- * @return {Object|UAVariable}
79
72
  */
80
73
  export function createExtObjArrayNode<T extends ExtensionObject>(parentFolder: UAObject, options: any): UADynamicVariableArray<T> {
81
74
  assert(typeof options.variableType === "string");
@@ -126,7 +119,9 @@ export function createExtObjArrayNode<T extends ExtensionObject>(parentFolder: U
126
119
 
127
120
  return uaArrayVariableNode;
128
121
  }
129
- function _getElementBrowseName<T extends ExtensionObject>(this: UADynamicVariableArray<T>, extObj: ExtensionObject) {
122
+
123
+ function _getElementBrowseName<T extends ExtensionObject>
124
+ (this: UADynamicVariableArray<T>, extObj: ExtensionObject, index: number | number[]) {
130
125
  const indexPropertyName1 = this.$$indexPropertyName;
131
126
 
132
127
  if (!Object.prototype.hasOwnProperty.call(extObj, indexPropertyName1)) {
@@ -137,13 +132,7 @@ function _getElementBrowseName<T extends ExtensionObject>(this: UADynamicVariabl
137
132
  const browseName = (extObj as any)[indexPropertyName1].toString();
138
133
  return browseName;
139
134
  };
140
- /**
141
- * @method bindExtObjArrayNode
142
- * @param uaArrayVariableNode
143
- * @param variableTypeNodeId
144
- * @param indexPropertyName
145
- * @return
146
- */
135
+
147
136
  export function bindExtObjArrayNode<T extends ExtensionObject>(
148
137
  uaArrayVariableNode: UADynamicVariableArray<T>,
149
138
  variableTypeNodeId: string | NodeId,
@@ -155,26 +144,23 @@ export function bindExtObjArrayNode<T extends ExtensionObject>(
155
144
  const addressSpace = uaArrayVariableNode.addressSpace;
156
145
 
157
146
  const variableType = addressSpace.findVariableType(variableTypeNodeId);
158
-
159
147
  // istanbul ignore next
160
148
  if (!variableType || variableType.nodeId.isEmpty()) {
161
149
  throw new Error("Cannot find VariableType " + variableTypeNodeId.toString());
162
150
  }
163
151
 
164
152
  const structure = addressSpace.findDataType("Structure");
165
-
166
153
  // istanbul ignore next
167
154
  if (!structure) {
168
155
  throw new Error("Structure Type not found: please check your nodeset file");
169
156
  }
170
157
 
171
158
  let dataType = addressSpace.findDataType(variableType.dataType);
172
-
173
159
  // istanbul ignore next
174
160
  if (!dataType) {
175
161
  throw new Error("Cannot find DataType " + variableType.dataType.toString());
176
162
  }
177
-
163
+
178
164
  assert(dataType.isSupertypeOf(structure), "expecting a structure (= ExtensionObject) here ");
179
165
 
180
166
  assert(!uaArrayVariableNode.$$variableType, "uaArrayVariableNode has already been bound !");
@@ -197,7 +183,6 @@ export function bindExtObjArrayNode<T extends ExtensionObject>(
197
183
  };
198
184
  // bind the readonly
199
185
  uaArrayVariableNode.bindVariable(bindOptions, true);
200
-
201
186
  return uaArrayVariableNode;
202
187
  }
203
188
 
@@ -208,20 +193,9 @@ export function bindExtObjArrayNode<T extends ExtensionObject>(
208
193
  * @param uaArrayVariableNode {UAVariable}
209
194
  * @return {UAVariable}
210
195
  *
211
- * @method addElement
212
- * add a new element in a ExtensionObject Array variable
213
- * @param nodeVariable a variable already exposing an extension objects
214
- * @param uaArrayVariableNode {UAVariable}
215
- * @return {UAVariable}
216
- *
217
- * @method addElement
218
- * add a new element in a ExtensionObject Array variable
219
- * @param constructor constructor of the extension object to create
220
- * @param uaArrayVariableNode {UAVariable}
221
- * @return {UAVariable}
222
196
  */
223
197
  export function addElement<T extends ExtensionObject>(
224
- options: any /* ExtensionObjectConstructor | ExtensionObject | UAVariable*/,
198
+ options: UAVariableImpl | ExtensionObject | Record<string, unknown>,
225
199
  uaArrayVariableNode: UADynamicVariableArray<T>
226
200
  ): UAVariable {
227
201
  assert(uaArrayVariableNode, " must provide an UAVariable containing the array");
@@ -256,20 +230,20 @@ export function addElement<T extends ExtensionObject>(
256
230
  });
257
231
  // xx elVar.bindExtensionObject();
258
232
  } else {
259
- if (options instanceof Constructor) {
233
+ if (options instanceof ExtensionObject) {
260
234
  // extension object has already been created
261
235
  extensionObject = options as T;
262
236
  } else {
263
237
  extensionObject = addressSpace.constructExtensionObject(uaArrayVariableNode.$$dataType, options) as T;
264
238
  }
265
- browseName = uaArrayVariableNode.$$getElementBrowseName(extensionObject);
239
+ const index = uaArrayVariableNode.$$extensionObjectArray?.length || 0;
240
+ browseName = uaArrayVariableNode.$$getElementBrowseName(extensionObject, index);
266
241
  elVar = uaArrayVariableNode.$$variableType.instantiate({
267
242
  browseName,
268
243
  componentOf: uaArrayVariableNode.nodeId,
269
244
  value: { dataType: DataType.ExtensionObject, value: extensionObject }
270
245
  }) as UAVariableImpl;
271
- elVar.bindExtensionObject(extensionObject, { force: true });
272
- elVar.$extensionObject = extensionObject;
246
+ elVar.bindExtensionObject(extensionObject, { force: true });
273
247
  }
274
248
 
275
249
  // also add the value inside
@@ -279,24 +253,11 @@ export function addElement<T extends ExtensionObject>(
279
253
  }
280
254
 
281
255
  /**
282
- *
283
- * @method removeElement
284
- * @param uaArrayVariableNode {UAVariable}
285
- * @param element {number} index of element to remove in array
286
- *
287
- *
288
- * @method removeElement
289
- * @param uaArrayVariableNode {UAVariable}
290
- * @param element {UAVariable} node of element to remove in array
291
- *
292
- * @method removeElement
293
- * @param uaArrayVariableNode {UAVariable}
294
- * @param element {ExtensionObject} extension object of the node of element to remove in array
295
256
  *
296
257
  */
297
258
  export function removeElement<T extends ExtensionObject>(
298
259
  uaArrayVariableNode: UADynamicVariableArray<T>,
299
- element: any /* number | UAVariable | (a any) => boolean | ExtensionObject */
260
+ element: number | UAVariable | ((a: T) => boolean)
300
261
  ): void {
301
262
  assert(element, "removeElement: element must exist");
302
263
  const _array = uaArrayVariableNode.$$extensionObjectArray;
@@ -305,29 +266,30 @@ export function removeElement<T extends ExtensionObject>(
305
266
  if (_array.length === 0) {
306
267
  throw new Error(" cannot remove an element from an empty array ");
307
268
  }
308
-
309
269
  let elementIndex = -1;
310
-
311
270
  if (typeof element === "number") {
312
271
  // find element by index
313
272
  elementIndex = element;
314
273
  assert(elementIndex >= 0 && elementIndex < _array.length);
274
+ } else if (typeof element === "function") {
275
+ // find element by functor
276
+ elementIndex = _array.findIndex(element);
315
277
  } else if (element && element.nodeClass) {
316
278
  // find element by name
317
279
  const browseNameToFind = element.browseName.name!.toString();
318
280
  elementIndex = _array.findIndex((obj: any, i: number) => {
319
- const browseName = uaArrayVariableNode.$$getElementBrowseName(obj).toString();
281
+ const browseName = uaArrayVariableNode.$$getElementBrowseName(obj, elementIndex).toString();
320
282
  return browseName === browseNameToFind;
321
283
  });
322
- } else if (typeof element === "function") {
323
- // find element by functor
324
- elementIndex = _array.findIndex(element);
325
284
  } else {
326
- // find element by inner extension object
327
- assert(_array[0].constructor.name === (element as any).constructor.name, "element must match");
328
- elementIndex = _array.findIndex((x: any) => x === element);
285
+ throw new Error("Unsupported anymore!!! please use a functor instead");
286
+ // // find element by inner extension object
287
+ // assert(_array[0].constructor.name === (element as any).constructor.name, "element must match");
288
+ // // let unproxyfy
289
+ // const elementTarget = getProxyTarget(element);
290
+ // elementIndex = _array.findIndex((x: any) => getProxyTarget(x) === elementTarget);
329
291
  }
330
-
292
+
331
293
  // istanbul ignore next
332
294
  if (elementIndex < 0) {
333
295
  throw new Error("removeElement: cannot find element matching " + element.toString());
@@ -0,0 +1,52 @@
1
+
2
+
3
+
4
+
5
+ export class IndexIterator {
6
+
7
+ public current: number[] | null = null;
8
+ constructor(private limits: number[]) {
9
+ this.reset();
10
+ }
11
+ public reset() {
12
+ this.current = [];
13
+ for (let i = 0; i < this.limits.length; i++) {
14
+ this.current[i] = 0;
15
+ }
16
+ }
17
+ public increment() {
18
+ if (!this.current) return;
19
+
20
+
21
+ const increase = (n: number): boolean => {
22
+ if (n < 0) {
23
+ return false;
24
+ }
25
+ if (!this.current) return false;
26
+ if (this.current[n] + 1 >= this.limits[n]) {
27
+ if (n==0) {
28
+ this.current = null;
29
+ return false;
30
+ }
31
+ this.current[n] = 0;
32
+ return increase(n - 1);
33
+ }
34
+ this.current[n] = this.current[n] + 1;
35
+ return true;
36
+ }
37
+ const n = this.limits.length - 1;
38
+ if (!increase(n)) {
39
+ this.current = null;
40
+ }
41
+ }
42
+ public next(): number[] {
43
+ if (!this.current) {
44
+ throw new Error("Outof bond");
45
+ }
46
+ const r = [... this.current];
47
+ this.increment();
48
+ return r;
49
+ }
50
+
51
+
52
+ }
@@ -28,7 +28,8 @@ import {
28
28
  AccessLevelFlag,
29
29
  makeAccessLevelFlag,
30
30
  AttributeIds,
31
- isDataEncoding
31
+ isDataEncoding,
32
+ QualifiedName
32
33
  } from "node-opcua-data-model";
33
34
  import { extractRange, sameDataValue, DataValue, DataValueLike, DataValueT } from "node-opcua-data-value";
34
35
  import { coerceClock, getCurrentClock, PreciseClock } from "node-opcua-date-time";
@@ -84,11 +85,12 @@ import { EnumerationInfo, IEnumItem, UADataTypeImpl } from "./ua_data_type_impl"
84
85
  import { apply_condition_refresh, ConditionRefreshCache } from "./apply_condition_refresh";
85
86
  import {
86
87
  extractPartialData,
88
+ incrementElement,
87
89
  propagateTouchValueUpward,
88
- setExtensionObjectValue,
90
+ setExtensionObjectPartialValue,
89
91
  _bindExtensionObject,
92
+ _bindExtensionObjectArrayOrMatrix,
90
93
  _installExtensionObjectBindingOnProperties,
91
- _setExtensionObject,
92
94
  _touchValue
93
95
  } from "./ua_variable_impl_ext_obj";
94
96
 
@@ -482,8 +484,11 @@ export class UAVariableImpl extends BaseNodeImpl implements UAVariable {
482
484
  if (this._timestamped_get_func.length === 0) {
483
485
  const dataValueOrPromise = (this._timestamped_get_func as VariableDataValueGetterSync)();
484
486
  if (!Object.prototype.hasOwnProperty.call(dataValueOrPromise, "then")) {
485
- this.$dataValue = dataValueOrPromise as DataValue;
486
- this.verifyVariantCompatibility(this.$dataValue.value);
487
+ if (dataValueOrPromise !== this.$dataValue) {
488
+ // TO DO : is this necessary ? this may interfere with current use of $dataValue
489
+ this.$dataValue = dataValueOrPromise as DataValue;
490
+ this.verifyVariantCompatibility(this.$dataValue.value);
491
+ }
487
492
  } else {
488
493
  errorLog("Unsupported: _timestamped_get_func returns a Promise !");
489
494
  }
@@ -819,8 +824,8 @@ export class UAVariableImpl extends BaseNodeImpl implements UAVariable {
819
824
  if (this.$extensionObject) {
820
825
  // we have an extension object already bound to this node
821
826
  // the client is asking us to replace the object entierly by a new one
822
- const ext = dataValue.value.value;
823
- _setExtensionObject(this, ext);
827
+ // const ext = dataValue.value.value;
828
+ this._internal_set_dataValue(dataValue);
824
829
  return;
825
830
  }
826
831
  } else {
@@ -1457,49 +1462,62 @@ export class UAVariableImpl extends BaseNodeImpl implements UAVariable {
1457
1462
  */
1458
1463
  public installExtensionObjectVariables(): void {
1459
1464
  _installExtensionObjectBindingOnProperties(this, { createMissingProp: true });
1460
- // now recursively install extension object on children
1461
- for (const child of this.getComponents()) {
1462
- if (child.nodeClass === NodeClass.Variable && child instanceof UAVariableImpl) {
1463
- if (child.isExtensionObject()) {
1464
- child.installExtensionObjectVariables();
1465
- }
1466
- }
1467
- }
1468
1465
  }
1469
1466
  /**
1470
1467
  * @method bindExtensionObject
1471
1468
  * @return {ExtensionObject}
1472
1469
  */
1473
1470
  public bindExtensionObjectScalar(
1474
- optionalExtensionObject: ExtensionObject,
1471
+ optionalExtensionObject?: ExtensionObject,
1475
1472
  options?: BindExtensionObjectOptions
1476
1473
  ): ExtensionObject | null {
1477
- return this.bindExtensionObject(optionalExtensionObject, options) as ExtensionObject | null;
1474
+ assert(this.valueRank === -1, "expecting an Scalar variable here");
1475
+ return _bindExtensionObject(this, optionalExtensionObject, options) as ExtensionObject;
1478
1476
  }
1479
1477
 
1480
1478
  public bindExtensionObjectArray(
1481
- optionalExtensionObject: ExtensionObject[],
1479
+ optionalExtensionObject?: ExtensionObject[],
1482
1480
  options?: BindExtensionObjectOptions
1483
1481
  ): ExtensionObject[] | null {
1484
- return this.bindExtensionObject(optionalExtensionObject, options) as ExtensionObject[] | null;
1482
+ assert(this.valueRank >= 1, "expecting an Array or a Matrix variable here");
1483
+ return _bindExtensionObjectArrayOrMatrix(this, optionalExtensionObject, options);
1485
1484
  }
1486
1485
 
1487
1486
  public bindExtensionObject(
1488
1487
  optionalExtensionObject?: ExtensionObject | ExtensionObject[],
1489
1488
  options?: BindExtensionObjectOptions
1490
1489
  ): ExtensionObject | ExtensionObject[] | null {
1491
- return _bindExtensionObject(this, optionalExtensionObject, options);
1490
+ if (optionalExtensionObject) {
1491
+ if (optionalExtensionObject instanceof Array) {
1492
+ assert(this.valueRank >= 1, "expecting an Array of Matrix variable here");
1493
+ return _bindExtensionObjectArrayOrMatrix(this, optionalExtensionObject, options);
1494
+ } else {
1495
+ assert(this.valueRank === -1, "expecting an Scalar variable here");
1496
+ return _bindExtensionObject(this, optionalExtensionObject, options) as ExtensionObject;
1497
+ }
1498
+ }
1499
+ assert(optionalExtensionObject === undefined);
1500
+ if (this.valueRank === -1) {
1501
+ return _bindExtensionObject(this, undefined, options) as ExtensionObject;
1502
+ } else if (this.valueRank === 1) {
1503
+ return _bindExtensionObjectArrayOrMatrix(this, undefined, options);
1504
+ } else if (this.valueRank > 1) {
1505
+ return _bindExtensionObjectArrayOrMatrix(this, undefined, options);
1506
+ }
1507
+ // unsupported case ...
1508
+ return null;
1492
1509
  }
1493
1510
 
1494
1511
  public updateExtensionObjectPartial(partialExtensionObject?: { [key: string]: any }): ExtensionObject {
1495
- setExtensionObjectValue(this, partialExtensionObject);
1512
+ setExtensionObjectPartialValue(this, partialExtensionObject);
1496
1513
  return this.$extensionObject;
1497
1514
  }
1498
1515
 
1499
1516
  public incrementExtensionObjectPartial(path: string | string[]): void {
1500
1517
  const extensionObject = this.readValue().value.value as ExtensionObject;
1501
1518
  const partialData = extractPartialData(path, extensionObject);
1502
- setExtensionObjectValue(this, partialData);
1519
+ incrementElement(path, partialData);
1520
+ setExtensionObjectPartialValue(this, partialData);
1503
1521
  }
1504
1522
 
1505
1523
  public toString(): string {
@@ -1665,10 +1683,14 @@ export class UAVariableImpl extends BaseNodeImpl implements UAVariable {
1665
1683
  assert(dataValue !== this.$dataValue, "expecting dataValue to be different from previous DataValue instance");
1666
1684
 
1667
1685
  const addressSpace = this.addressSpace;
1686
+
1687
+ // istanbul ignore next
1668
1688
  if (!addressSpace) {
1669
1689
  warningLog("UAVariable#_internal_set_dataValue : no addressSpace ! may be node has already been deleted ?");
1670
1690
  return;
1671
1691
  }
1692
+
1693
+ // istanbul ignore next
1672
1694
  if (dataValue.value.arrayType === VariantArrayType.Matrix) {
1673
1695
  if (!dataValue.value.dimensions) {
1674
1696
  throw new Error("missing dimensions: a Matrix Variant needs a dimension");
@@ -1681,31 +1703,25 @@ export class UAVariableImpl extends BaseNodeImpl implements UAVariable {
1681
1703
  );
1682
1704
  }
1683
1705
  }
1706
+
1707
+ // istanbul ignore next
1684
1708
  if (dataValue.value.dataType === DataType.ExtensionObject) {
1709
+ // istanbul ignore next
1685
1710
  if (!this.checkExtensionObjectIsCorrect(dataValue.value.value)) {
1686
1711
  warningLog(dataValue.toString());
1687
1712
  throw new Error("Invalid Extension Object on nodeId =" + this.nodeId.toString());
1688
1713
  }
1689
- // ----------------------------------
1690
- // if (this.$extensionObject) {
1691
- // // we have an extension object already bound to this node
1692
- // // the client is asking us to replace the object entierly by a new one
1693
- // const ext = dataValue.value.value;
1694
- // _setExtensionObject(this, ext);
1695
- // return;
1696
- // }
1697
1714
  }
1698
- // // istanbul ignore next
1699
- // if (this.dataType.namespace === 0) {
1700
- // if (this.dataType.value === DataType.LocalizedText && dataValue.value.dataType !== DataType.LocalizedText) {
1701
- // const message = "Invalid dataValue provided (expecting a LocalizedText) but got " + dataValue.toString();
1702
- // errorLog(message);
1703
- // // throw new Error(message);
1704
- // }
1705
- // }
1706
-
1715
+
1707
1716
  this.verifyVariantCompatibility(dataValue.value);
1708
1717
 
1718
+ this._inner_replace_dataValue(dataValue, indexRange);
1719
+ }
1720
+
1721
+ /**
1722
+ * @private
1723
+ */
1724
+ public _inner_replace_dataValue(dataValue: DataValue, indexRange?: NumericRange | null) {
1709
1725
  const old_dataValue = this.$dataValue;
1710
1726
 
1711
1727
  this.$dataValue = dataValue;
@@ -1830,14 +1846,15 @@ UAVariableImpl.prototype.writeAttribute = thenify.withCallback(UAVariableImpl.pr
1830
1846
  UAVariableImpl.prototype.historyRead = thenify.withCallback(UAVariableImpl.prototype.historyRead);
1831
1847
  UAVariableImpl.prototype.readValueAsync = thenify.withCallback(UAVariableImpl.prototype.readValueAsync);
1832
1848
 
1833
- export interface UAVariableImpl {
1834
- $$variableType?: any;
1835
- $$dataType?: any;
1836
- $$getElementBrowseName: any;
1837
- $$extensionObjectArray: any;
1838
- $$indexPropertyName: any;
1849
+ export interface UAVariableImplExtArray {
1850
+ $$variableType?: UAVariableType;
1851
+ $$dataType: UADataType;
1852
+ $$getElementBrowseName: (extObject: ExtensionObject, index: number | number[]) => QualifiedName;
1853
+ $$extensionObjectArray: ExtensionObject[];
1854
+ $$indexPropertyName: string;
1855
+ }
1856
+ export interface UAVariableImpl extends UAVariableImplExtArray {
1839
1857
  }
1840
-
1841
1858
  function check_valid_array(dataType: DataType, array: any): boolean {
1842
1859
  if (Array.isArray(array)) {
1843
1860
  return true;
@@ -1978,9 +1995,6 @@ function _Variable_bind_with_async_refresh(this: UAVariableImpl, options: any) {
1978
1995
 
1979
1996
  this.refreshFunc = options.refreshFunc;
1980
1997
 
1981
- // assert(this.readValue().statusCode.equals(StatusCodes.BadNodeIdUnknown));
1982
- this.$dataValue.statusCode = StatusCodes.UncertainInitialValue;
1983
-
1984
1998
  // TO DO : REVISIT THIS ASSUMPTION
1985
1999
  if (false && this.minimumSamplingInterval === 0) {
1986
2000
  // when a getter /timestamped_getter or async_getter is provided
@@ -2119,10 +2133,9 @@ function _Variable_bind_with_timestamped_set(
2119
2133
  set: undefined;
2120
2134
  }
2121
2135
  ) {
2122
- assert(typeof options.timestamped_set === "function");
2123
2136
  assert(
2124
- options.timestamped_set.length === 2,
2125
- "timestamped_set must have 2 parameters timestamped_set: function(dataValue,callback){}"
2137
+ options.timestamped_set.length === 2 || options.timestamped_set.length === 1,
2138
+ "timestamped_set must have 2 parameters timestamped_set: function(dataValue,callback){} or one paramater timestamped_set: function(dataValue): Promise<StatusCode>{}"
2126
2139
  );
2127
2140
  assert(!options.set, "should not specify set when timestamped_set_func exists ");
2128
2141
  this._timestamped_set_func = convertToCallbackFunction1<StatusCode, DataValue, UAVariable>(options.timestamped_set);
@@ -2221,6 +2234,3 @@ export interface UAVariableImplT<T, DT extends DataType> extends UAVariableImpl,
2221
2234
  writeValue(context: ISessionContext, dataValue: DataValueT<T, DT>, indexRange?: NumericRange | null): Promise<StatusCode>;
2222
2235
  }
2223
2236
  export class UAVariableImplT<T, DT extends DataType> extends UAVariableImpl { }
2224
- // x TO DO
2225
- // require("./data_access/ua_variable_data_access");
2226
- // require("./historical_access/ua_variable_history");