node-opcua-client 2.123.0 → 2.125.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 (51) hide show
  1. package/dist/alarms_and_conditions/client_alarm_tools.js.map +1 -1
  2. package/dist/alarms_and_conditions/client_tools.js.map +1 -1
  3. package/dist/client_monitored_item_toolbox.js.map +1 -1
  4. package/dist/client_session_keepalive_manager.js.map +1 -1
  5. package/dist/client_utils.js.map +1 -1
  6. package/dist/private/client_base_impl.d.ts +11 -4
  7. package/dist/private/client_base_impl.js +130 -70
  8. package/dist/private/client_base_impl.js.map +1 -1
  9. package/dist/private/client_monitored_item_group_impl.js.map +1 -1
  10. package/dist/private/client_monitored_item_impl.js.map +1 -1
  11. package/dist/private/client_publish_engine.d.ts +9 -4
  12. package/dist/private/client_publish_engine.js +5 -99
  13. package/dist/private/client_publish_engine.js.map +1 -1
  14. package/dist/private/client_session_impl.d.ts +20 -4
  15. package/dist/private/client_session_impl.js +5 -24
  16. package/dist/private/client_session_impl.js.map +1 -1
  17. package/dist/private/client_subscription_impl.d.ts +5 -8
  18. package/dist/private/client_subscription_impl.js +83 -174
  19. package/dist/private/client_subscription_impl.js.map +1 -1
  20. package/dist/private/i_private_client.d.ts +0 -1
  21. package/dist/private/opcua_client_impl.js +1 -1
  22. package/dist/private/opcua_client_impl.js.map +1 -1
  23. package/dist/private/performance.js.map +1 -1
  24. package/dist/private/reconnection/client_publish_engine_reconnection.d.ts +2 -0
  25. package/dist/private/reconnection/client_publish_engine_reconnection.js +118 -0
  26. package/dist/private/reconnection/client_publish_engine_reconnection.js.map +1 -0
  27. package/dist/private/reconnection/client_reconnection.d.ts +2 -0
  28. package/dist/private/reconnection/client_reconnection.js +20 -0
  29. package/dist/private/reconnection/client_reconnection.js.map +1 -0
  30. package/dist/private/reconnection/client_subscription_reconnection.d.ts +7 -0
  31. package/dist/private/reconnection/client_subscription_reconnection.js +124 -0
  32. package/dist/private/reconnection/client_subscription_reconnection.js.map +1 -0
  33. package/dist/private/reconnection/reconnection.d.ts +12 -0
  34. package/dist/private/reconnection/reconnection.js +564 -0
  35. package/dist/private/reconnection/reconnection.js.map +1 -0
  36. package/dist/tools/findservers.js.map +1 -1
  37. package/dist/tools/read_history_server_capabilities.js.map +1 -1
  38. package/dist/verify.js.map +1 -1
  39. package/package.json +43 -43
  40. package/source/index.ts +4 -1
  41. package/source/opcua_client.ts +11 -5
  42. package/source/private/client_base_impl.ts +136 -81
  43. package/source/private/client_publish_engine.ts +13 -129
  44. package/source/private/client_session_impl.ts +56 -78
  45. package/source/private/client_subscription_impl.ts +85 -207
  46. package/source/private/i_private_client.ts +0 -2
  47. package/source/private/opcua_client_impl.ts +16 -149
  48. package/source/private/reconnection/client_publish_engine_reconnection.ts +146 -0
  49. package/source/private/reconnection/client_reconnection.ts +17 -0
  50. package/source/private/reconnection/client_subscription_reconnection.ts +124 -0
  51. package/source/{reconnection.ts → private/reconnection/reconnection.ts} +121 -76
@@ -1,13 +1,11 @@
1
1
  /**
2
2
  * @module node-opcua-client-private
3
3
  */
4
- import { types } from "util";
5
- import async from "async";
6
4
  import chalk from "chalk";
5
+ import { minDate } from "node-opcua-date-time";
7
6
  import { assert } from "node-opcua-assert";
8
7
  import { checkDebugFlag, make_debugLog, make_warningLog } from "node-opcua-debug";
9
- import { PublishRequest, PublishResponse, RepublishRequest, RepublishResponse } from "node-opcua-service-subscription";
10
- import { StatusCodes } from "node-opcua-status-code";
8
+ import { PublishRequest, PublishResponse } from "node-opcua-service-subscription";
11
9
 
12
10
  import { ClientSession, SubscriptionId } from "../client_session";
13
11
  import { ClientSubscription } from "../client_subscription";
@@ -41,7 +39,14 @@ export class ClientSidePublishEngine {
41
39
  public isSuspended: boolean;
42
40
  public session: ClientSession | null;
43
41
  private subscriptionAcknowledgements: any[];
44
- private readonly subscriptionMap: { [key: number]: ClientSubscriptionImpl };
42
+
43
+ /**
44
+ * @internal
45
+ * @private
46
+ */
47
+ readonly subscriptionMap: { [key: number]: ClientSubscriptionImpl };
48
+
49
+ public lastRequestSentTime: Date = minDate;
45
50
 
46
51
  constructor(session: ClientSession) {
47
52
  this.session = session;
@@ -200,31 +205,6 @@ export class ClientSidePublishEngine {
200
205
  return Object.prototype.hasOwnProperty.call(this.subscriptionMap, subscriptionId);
201
206
  }
202
207
 
203
- public republish(callback: () => void): void {
204
- // After re-establishing the connection the Client shall call Republish in a loop, starting with
205
- // the next expected sequence number and incrementing the sequence number until the Server returns
206
- // the status BadMessageNotAvailable.
207
- // After receiving this status, the Client shall start sending Publish requests with the normal Publish
208
- // handling.
209
- // This sequence ensures that the lost NotificationMessages queued in the Server are not overwritten
210
- // by newPublish responses
211
- /**
212
- * call Republish continuously until all Notification messages of
213
- * un-acknowledged notifications are reprocessed.
214
- * @private
215
- */
216
- const repairSubscription = (
217
- subscription: ClientSubscription,
218
- subscriptionId: SubscriptionId | string,
219
- innerCallback: () => void
220
- ) => {
221
- subscriptionId = parseInt(subscriptionId as string, 10);
222
- this.__repairSubscription(subscription, subscriptionId, innerCallback);
223
- };
224
-
225
- async.forEachOf(this.subscriptionMap, repairSubscription, callback);
226
- }
227
-
228
208
  public internalSendPublishRequest(): void {
229
209
  assert(this.session, "ClientSidePublishEngine terminated ?");
230
210
 
@@ -265,7 +245,7 @@ export class ClientSidePublishEngine {
265
245
  // in our case:
266
246
 
267
247
  assert(this.nbPendingPublishRequests > 0);
268
- const calculatedTimeout = Math.min(0x7FFFFFFF, this.nbPendingPublishRequests * this.timeoutHint);
248
+ const calculatedTimeout = Math.min(0x7fffffff, this.nbPendingPublishRequests * this.timeoutHint);
269
249
 
270
250
  const publishRequest = new PublishRequest({
271
251
  requestHeader: { timeoutHint: calculatedTimeout }, // see note
@@ -278,6 +258,8 @@ export class ClientSidePublishEngine {
278
258
  session.publish(publishRequest, (err: Error | null, response?: PublishResponse) => {
279
259
  this.nbPendingPublishRequests -= 1;
280
260
 
261
+ this.lastRequestSentTime = new Date();
262
+
281
263
  if (err) {
282
264
  debugLog(
283
265
  chalk.cyan("ClientSidePublishEngine.prototype.internalSendPublishRequest callback : "),
@@ -403,102 +385,4 @@ export class ClientSidePublishEngine {
403
385
  debugLog(" or because there is no session for the subscription (session terminated ?).");
404
386
  }
405
387
  }
406
-
407
- private _republish(subscription: any, subscriptionId: SubscriptionId, callback: (err?: Error) => void) {
408
- assert(subscription.subscriptionId === +subscriptionId);
409
-
410
- let isDone = false;
411
- const session = this.session as ClientSessionImpl;
412
-
413
- const sendRepublishFunc = (callback2: (err?: Error) => void) => {
414
- assert(isFinite(subscription.lastSequenceNumber) && subscription.lastSequenceNumber + 1 >= 0);
415
-
416
- const request = new RepublishRequest({
417
- retransmitSequenceNumber: subscription.lastSequenceNumber + 1,
418
- subscriptionId: subscription.subscriptionId
419
- });
420
-
421
- // istanbul ignore next
422
- if (doDebug) {
423
- // istanbul ignore next
424
- debugLog(
425
- chalk.bgCyan.yellow.bold(" republish Request for subscription"),
426
- request.subscriptionId,
427
- " retransmitSequenceNumber=",
428
- request.retransmitSequenceNumber
429
- );
430
- }
431
-
432
- if (!session || session!._closeEventHasBeenEmitted) {
433
- debugLog("ClientPublishEngine#_republish aborted ");
434
- // has client been disconnected in the mean time ?
435
- isDone = true;
436
- return callback2();
437
- }
438
- session.republish(request, (err: Error | null, response?: RepublishResponse) => {
439
- const statusCode = err ? StatusCodes.Bad : response!.responseHeader.serviceResult;
440
- if (!err && (statusCode.equals(StatusCodes.Good) || statusCode.equals(StatusCodes.BadMessageNotAvailable))) {
441
- // reprocess notification message and keep going
442
- if (statusCode.equals(StatusCodes.Good)) {
443
- subscription.onNotificationMessage(response!.notificationMessage);
444
- }
445
- } else {
446
- if (!err) {
447
- err = new Error(response!.responseHeader.serviceResult.toString());
448
- }
449
- debugLog(" _send_republish ends with ", err.message);
450
- isDone = true;
451
- }
452
- callback2(err ? err : undefined);
453
- });
454
- };
455
-
456
- setImmediate(() => {
457
- assert(typeof callback === "function");
458
- async.whilst(
459
- (cb: (err: null, truth: boolean) => void) => cb(null, !isDone),
460
- sendRepublishFunc,
461
- ((err?: Error | null): void => {
462
- debugLog("nbPendingPublishRequest = ", this.nbPendingPublishRequests);
463
- debugLog(" _republish ends with ", err ? err.message : "null");
464
- callback(err!);
465
- }) as any // Wait for @type/async bug to be fixed !
466
- );
467
- });
468
- }
469
-
470
- private __repairSubscription(
471
- subscription: ClientSubscription,
472
- subscriptionId: SubscriptionId,
473
- callback: (err?: Error) => void
474
- ) {
475
- debugLog("__repairSubscription for SubscriptionId ", subscriptionId);
476
-
477
- this._republish(subscription, subscriptionId, (err?: Error) => {
478
- assert(!err || types.isNativeError(err));
479
-
480
- debugLog("__repairSubscription--------------------- err =", err ? err.message : null);
481
-
482
- if (err && err.message.match(/BadSessionInvalid/)) {
483
- // _republish failed because session is not valid anymore on server side.
484
- return callback(err);
485
- }
486
- if (err && err.message.match(/SubscriptionIdInvalid/)) {
487
- // _republish failed because subscriptionId is not valid anymore on server side.
488
- //
489
- // This could happen when the subscription has timed out and has been deleted by server
490
- // Subscription may time out if the duration of the connection break exceed the max life time
491
- // of the subscription.
492
- //
493
- // In this case, Client must recreate a subscription and recreate monitored item without altering
494
- // the event handlers
495
- //
496
- debugLog(chalk.bgWhite.red("_republish failed " + " subscriptionId is not valid anymore on server side."));
497
-
498
- const subscriptionI = subscription as ClientSubscriptionImpl;
499
- return subscriptionI.recreateSubscriptionAndMonitoredItem(callback);
500
- }
501
- callback();
502
- });
503
- }
504
388
  }
@@ -29,7 +29,8 @@ import {
29
29
  NodeAttributes,
30
30
  ResponseCallback,
31
31
  BrowseDescriptionLike,
32
- IBasicSessionAsync2
32
+ IBasicSessionAsync2,
33
+ readNamespaceArray
33
34
  } from "node-opcua-pseudo-session";
34
35
  import { AnyConstructorFunc } from "node-opcua-schemas";
35
36
  import { ClientSecureChannelLayer, requestHandleNotSetValue, SignatureData } from "node-opcua-secure-channel";
@@ -124,11 +125,11 @@ import {
124
125
  HistoryReadValueIdOptions2,
125
126
  ExtraReadHistoryValueParameters
126
127
  } from "../client_session";
128
+ import { UserIdentityInfo } from "../user_identity_info";
127
129
  import { ClientSessionKeepAliveManager } from "../client_session_keepalive_manager";
128
130
  import { ClientSubscription } from "../client_subscription";
129
131
  import { Request, Response } from "../common";
130
- import { repair_client_session } from "../reconnection";
131
- import { UserIdentityInfo } from "../user_identity_info";
132
+ import { repair_client_session } from "./reconnection/reconnection";
132
133
 
133
134
  import { ClientSidePublishEngine } from "./client_publish_engine";
134
135
  import { ClientSubscriptionImpl } from "./client_subscription_impl";
@@ -221,7 +222,7 @@ export class ClientSessionImpl extends EventEmitter implements ClientSession {
221
222
  public _closeEventHasBeenEmitted: boolean;
222
223
  private _publishEngine: ClientSidePublishEngine | null;
223
224
  private _keepAliveManager?: ClientSessionKeepAliveManager;
224
- private _namespaceArray?: any;
225
+ private $$namespaceArray?: string[];
225
226
  private recursive_repair_detector = 0;
226
227
 
227
228
  constructor(client: IClientBase) {
@@ -270,6 +271,9 @@ export class ClientSessionImpl extends EventEmitter implements ClientSession {
270
271
  return this._client ? this._client.isReconnecting || this._reconnecting?.reconnecting : false;
271
272
  }
272
273
 
274
+ protected resolveNodeId(nodeId: NodeIdLike): NodeIdLike {
275
+ return resolveNodeId(nodeId);
276
+ }
273
277
  public getPublishEngine(): ClientSidePublishEngine {
274
278
  if (!this._publishEngine) {
275
279
  this._publishEngine = new ClientSidePublishEngine(this);
@@ -406,8 +410,8 @@ export class ClientSessionImpl extends EventEmitter implements ClientSession {
406
410
  if (r.references && r.references.length > this.requestedMaxReferencesPerNode) {
407
411
  warningLog(
408
412
  chalk.yellow("warning") +
409
- " BrowseResponse : the server didn't take into" +
410
- " account our requestedMaxReferencesPerNode "
413
+ " BrowseResponse : the server didn't take into" +
414
+ " account our requestedMaxReferencesPerNode "
411
415
  );
412
416
  warningLog(" this.requestedMaxReferencesPerNode= " + this.requestedMaxReferencesPerNode);
413
417
  warningLog(" got " + r.references.length + "for " + nodesToBrowse[i].nodeId.toString());
@@ -416,7 +420,7 @@ export class ClientSessionImpl extends EventEmitter implements ClientSession {
416
420
  }
417
421
  }
418
422
  for (const r of results) {
419
- r.references = r.references || /* istanbul ignore next */ [];
423
+ r.references = r.references || /* istanbul ignore next */[];
420
424
  }
421
425
  assert(results[0] instanceof BrowseResult);
422
426
  return callback(null, isArray ? results : results[0]);
@@ -652,7 +656,7 @@ export class ClientSessionImpl extends EventEmitter implements ClientSession {
652
656
  continuationPoint: undefined,
653
657
  dataEncoding: undefined, // {namespaceIndex: 0, name: undefined},
654
658
  indexRange: undefined,
655
- nodeId: resolveNodeId(node as NodeIdLike)
659
+ nodeId: this.resolveNodeId(node as NodeIdLike)
656
660
  });
657
661
  } else {
658
662
  nodesToRead.push(node as HistoryReadValueIdOptions);
@@ -715,7 +719,7 @@ export class ClientSessionImpl extends EventEmitter implements ClientSession {
715
719
  return callback(new Error(response.responseHeader.serviceResult.toString()));
716
720
  }
717
721
 
718
- response.results = response.results || /* istanbul ignore next */ [];
722
+ response.results = response.results || /* istanbul ignore next */[];
719
723
  callback(null, response);
720
724
  });
721
725
  }
@@ -847,7 +851,7 @@ export class ClientSessionImpl extends EventEmitter implements ClientSession {
847
851
  return callback(new Error(response.responseHeader.serviceResult.toString()));
848
852
  }
849
853
 
850
- response.results = response.results || /* istanbul ignore next */ [];
854
+ response.results = response.results || /* istanbul ignore next */[];
851
855
 
852
856
  assert(nodesToRead.length === response.results.length);
853
857
 
@@ -990,7 +994,7 @@ export class ClientSessionImpl extends EventEmitter implements ClientSession {
990
994
  if (response.responseHeader.serviceResult.isNot(StatusCodes.Good)) {
991
995
  return callback(new Error(response.responseHeader.serviceResult.toString()));
992
996
  }
993
- response.results = response.results || /* istanbul ignore next */ [];
997
+ response.results = response.results || /* istanbul ignore next */[];
994
998
  assert(nodesToWrite.length === response.results.length);
995
999
  callback(null, isArray ? response.results : response.results[0]);
996
1000
  });
@@ -1012,7 +1016,25 @@ export class ClientSessionImpl extends EventEmitter implements ClientSession {
1012
1016
  * @param value {Variant} - the value to write
1013
1017
  * @return {Promise<StatusCode>} - the status code of the write
1014
1018
  *
1015
- * @deprecated
1019
+ * @deprecated use session.write instead
1020
+ *
1021
+ * @example
1022
+ * // please use session.write instead of session.writeSingleNode
1023
+ * // as follow
1024
+ * const statusCode = await session.write({
1025
+ * nodeId,
1026
+ * attributeId: AttributeIds.Value,
1027
+ * value: {
1028
+ * statusCode: Good,
1029
+ * sourceTimestamp: new Date(), // optional, some server may not accept this
1030
+ * value: {
1031
+ * dataType: opcua.DataType.Double,
1032
+ * value: 100.0
1033
+ * }
1034
+ * }
1035
+ * });
1036
+ *
1037
+ *
1016
1038
  */
1017
1039
  public writeSingleNode(nodeId: NodeIdLike, value: VariantLike, callback: ResponseCallback<StatusCode>): void;
1018
1040
 
@@ -1028,7 +1050,7 @@ export class ClientSessionImpl extends EventEmitter implements ClientSession {
1028
1050
  const nodeToWrite = new WriteValue({
1029
1051
  attributeId: AttributeIds.Value,
1030
1052
  indexRange: undefined,
1031
- nodeId: resolveNodeId(nodeId),
1053
+ nodeId: this.resolveNodeId(nodeId),
1032
1054
  value: new DataValue({ value })
1033
1055
  });
1034
1056
 
@@ -1144,6 +1166,7 @@ export class ClientSessionImpl extends EventEmitter implements ClientSession {
1144
1166
  * @param args
1145
1167
  */
1146
1168
  public read(...args: any[]): any {
1169
+
1147
1170
  if (args.length === 2) {
1148
1171
  return this.read(args[0], 0, args[1]);
1149
1172
  }
@@ -1175,7 +1198,7 @@ export class ClientSessionImpl extends EventEmitter implements ClientSession {
1175
1198
  warningLog(
1176
1199
  chalk.yellow(
1177
1200
  "please make sure to refactor your code and check that " +
1178
- "the second argument of your callback function is named"
1201
+ "the second argument of your callback function is named"
1179
1202
  ),
1180
1203
  chalk.cyan("dataValue" + (isArray ? "s" : ""))
1181
1204
  );
@@ -1186,7 +1209,7 @@ export class ClientSessionImpl extends EventEmitter implements ClientSession {
1186
1209
 
1187
1210
  // coerce nodeIds
1188
1211
  for (const node of nodesToRead) {
1189
- node.nodeId = resolveNodeId(node.nodeId);
1212
+ node.nodeId = this.resolveNodeId(node.nodeId);
1190
1213
  }
1191
1214
 
1192
1215
  const request = new ReadRequest({
@@ -1208,7 +1231,7 @@ export class ClientSessionImpl extends EventEmitter implements ClientSession {
1208
1231
 
1209
1232
  // perform ExtensionObject resolution
1210
1233
  promoteOpaqueStructureWithCallback(this, response.results!, () => {
1211
- response.results = response.results || /* istanbul ignore next */ [];
1234
+ response.results = response.results || /* istanbul ignore next */[];
1212
1235
  return callback(null, isArray ? response.results : response.results[0]);
1213
1236
  });
1214
1237
  });
@@ -1409,7 +1432,7 @@ export class ClientSessionImpl extends EventEmitter implements ClientSession {
1409
1432
  if (!response) {
1410
1433
  return callback(new Error("Internal Error"));
1411
1434
  }
1412
- response.results = response.results || /* istanbul ignore next */ [];
1435
+ response.results = response.results || /* istanbul ignore next */[];
1413
1436
  callback(err, isArray ? response.results : response.results[0]);
1414
1437
  }
1415
1438
  );
@@ -1454,7 +1477,7 @@ export class ClientSessionImpl extends EventEmitter implements ClientSession {
1454
1477
  if (!response || !(response instanceof TranslateBrowsePathsToNodeIdsResponse)) {
1455
1478
  return callback(new Error("Internal Error"));
1456
1479
  }
1457
- response.results = response.results || /* istanbul ignore next */ [];
1480
+ response.results = response.results || /* istanbul ignore next */[];
1458
1481
 
1459
1482
  callback(null, isArray ? response.results : response.results[0]);
1460
1483
  });
@@ -1474,28 +1497,12 @@ export class ClientSessionImpl extends EventEmitter implements ClientSession {
1474
1497
  return this._client !== null && this._client._secureChannel !== null && this._client._secureChannel.isOpened();
1475
1498
  }
1476
1499
 
1477
- private requestReconnection() {
1478
- if (this._client) {
1479
- this._client.requestReconnection();
1480
- assert(this._client.isReconnecting === true, "expecting client to be reconnecting now");
1481
- }
1482
- }
1483
-
1484
1500
  public performMessageTransaction(request: Request, callback: (err: Error | null, response?: Response) => void): void {
1485
1501
  if (!this._client) {
1486
1502
  // session may have been closed by user ... but is still in used !!
1487
1503
  return callback(new Error("Session has been closed and should not be used to perform a transaction anymore"));
1488
1504
  }
1489
1505
 
1490
- // if (!this.isChannelValid()) {
1491
- // // the secure channel is broken, may be the server has crashed or the network cable has been disconnected
1492
- // // for a long time
1493
- // // we may need to queue this transaction, as a secure token may be being reprocessed
1494
- // errorLog(chalk.bgWhite.red("!!! Performing transaction on invalid channel !!! ", request.schema.name));
1495
- // // this.requestReconnection();
1496
- // return callback(new Error("!!! Performing transaction on invalid channel with " + request.schema.name + ": starting reconnection process"));
1497
- // }
1498
-
1499
1506
  this._reconnecting.pendingTransactions = this._reconnecting.pendingTransactions || [];
1500
1507
  this._reconnecting.pendingTransactionsCount = this._reconnecting.pendingTransactionsCount || 0;
1501
1508
 
@@ -1613,9 +1620,9 @@ export class ClientSessionImpl extends EventEmitter implements ClientSession {
1613
1620
  if (response.responseHeader.serviceResult.isNot(StatusCodes.Good)) {
1614
1621
  err = new Error(
1615
1622
  " ServiceResult is " +
1616
- response.responseHeader.serviceResult.toString() +
1617
- " request was " +
1618
- request.constructor.name
1623
+ response.responseHeader.serviceResult.toString() +
1624
+ " request was " +
1625
+ request.constructor.name
1619
1626
  );
1620
1627
 
1621
1628
  if (response && response.responseHeader.serviceDiagnostics) {
@@ -1855,7 +1862,7 @@ export class ClientSessionImpl extends EventEmitter implements ClientSession {
1855
1862
  assert(Array.isArray(nodesToRegister));
1856
1863
 
1857
1864
  const request = new RegisterNodesRequest({
1858
- nodesToRegister: nodesToRegister.map(resolveNodeId)
1865
+ nodesToRegister: nodesToRegister.map((n) => this.resolveNodeId(n))
1859
1866
  });
1860
1867
 
1861
1868
  this.performMessageTransaction(request, (err: Error | null, response?: Response) => {
@@ -1868,7 +1875,7 @@ export class ClientSessionImpl extends EventEmitter implements ClientSession {
1868
1875
  return callback(new Error("Internal Error"));
1869
1876
  }
1870
1877
 
1871
- response.registeredNodeIds = response.registeredNodeIds || /* istanbul ignore next */ [];
1878
+ response.registeredNodeIds = response.registeredNodeIds || /* istanbul ignore next */[];
1872
1879
 
1873
1880
  callback(null, response.registeredNodeIds);
1874
1881
  });
@@ -1884,7 +1891,7 @@ export class ClientSessionImpl extends EventEmitter implements ClientSession {
1884
1891
  assert(Array.isArray(nodesToUnregister));
1885
1892
 
1886
1893
  const request = new UnregisterNodesRequest({
1887
- nodesToUnregister: nodesToUnregister.map(resolveNodeId)
1894
+ nodesToUnregister: nodesToUnregister.map((n) => this.resolveNodeId(n))
1888
1895
  });
1889
1896
 
1890
1897
  this.performMessageTransaction(request, (err: Error | null, response?: Response) => {
@@ -2014,47 +2021,20 @@ export class ClientSessionImpl extends EventEmitter implements ClientSession {
2014
2021
  .catch(callback);
2015
2022
  }
2016
2023
 
2017
- public resumePublishEngine(): void {
2018
- assert(this._publishEngine);
2019
- if (this._publishEngine && this._publishEngine.subscriptionCount > 0) {
2020
- this._publishEngine.replenish_publish_request_queue();
2021
- }
2022
- }
2023
-
2024
2024
  public async readNamespaceArray(): Promise<string[]>;
2025
2025
  public readNamespaceArray(callback: (err: Error | null, namespaceArray?: string[]) => void): void;
2026
2026
  public readNamespaceArray(...args: any[]): any {
2027
2027
  const callback = args[0];
2028
-
2029
- this.read(
2030
- {
2031
- attributeId: AttributeIds.Value,
2032
- nodeId: resolveNodeId("Server_NamespaceArray")
2033
- },
2034
- (err: Error | null, dataValue?: DataValue) => {
2035
- /* istanbul ignore next */
2036
- if (err) {
2037
- return callback(err);
2038
- }
2039
- /* istanbul ignore next */
2040
- if (!dataValue) {
2041
- return callback(new Error("Internal Error"));
2042
- }
2043
-
2044
- /* istanbul ignore next */
2045
- if (dataValue.statusCode.isNotGood()) {
2046
- return callback(new Error("readNamespaceArray : " + dataValue.statusCode.toString()));
2047
- }
2048
- assert(dataValue.value.value instanceof Array);
2049
- this._namespaceArray = dataValue.value.value; // keep a cache
2050
- callback(null, this._namespaceArray);
2051
- }
2052
- );
2028
+ readNamespaceArray(this)
2029
+ .then((namespaceArray) => callback(null, namespaceArray))
2030
+ .catch((err) => {
2031
+ callback(err);
2032
+ });
2053
2033
  }
2054
2034
 
2055
2035
  public getNamespaceIndex(namespaceUri: string): number {
2056
- assert(this._namespaceArray, "please make sure that readNamespaceArray has been called");
2057
- return this._namespaceArray.indexOf(namespaceUri);
2036
+ assert(this.$$namespaceArray, "please make sure that readNamespaceArray has been called");
2037
+ return this.$$namespaceArray!.indexOf(namespaceUri);
2058
2038
  }
2059
2039
 
2060
2040
  // tslint:disable:no-empty
@@ -2205,6 +2185,7 @@ export class ClientSessionImpl extends EventEmitter implements ClientSession {
2205
2185
  request: Request,
2206
2186
  callback: (err: Error | null, response?: Response) => void
2207
2187
  ) {
2188
+ warningLog("attempt to recreate session to reperform a transation ", request.constructor.name);
2208
2189
  if (this.recursive_repair_detector >= 1) {
2209
2190
  // tslint:disable-next-line: no-console
2210
2191
  warningLog("recreate_session_and_reperform_transaction => Already in Progress");
@@ -2230,10 +2211,7 @@ type promoteOpaqueStructure3WithCallbackFunc = (
2230
2211
  callback: ErrorCallback
2231
2212
  ) => void;
2232
2213
 
2233
- async function promoteOpaqueStructure2(
2234
- session: IBasicSessionAsync2,
2235
- callMethodResult: CallMethodResult
2236
- ): Promise<void> {
2214
+ async function promoteOpaqueStructure2(session: IBasicSessionAsync2, callMethodResult: CallMethodResult): Promise<void> {
2237
2215
  if (!callMethodResult || !callMethodResult.outputArguments || callMethodResult.outputArguments.length === 0) {
2238
2216
  return;
2239
2217
  }