@genesislcap/foundation-comms 14.167.1 → 14.167.3-alpha-b40d1e5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (224) hide show
  1. package/dist/dts/auth/auth.d.ts.map +1 -1
  2. package/dist/dts/connect/connect.d.ts +11 -1
  3. package/dist/dts/connect/connect.d.ts.map +1 -1
  4. package/dist/dts/connect/connect.events.d.ts +173 -0
  5. package/dist/dts/connect/connect.events.d.ts.map +1 -0
  6. package/dist/dts/connect/http.connect.d.ts +1 -0
  7. package/dist/dts/connect/http.connect.d.ts.map +1 -1
  8. package/dist/dts/connect/index.d.ts +2 -0
  9. package/dist/dts/connect/index.d.ts.map +1 -1
  10. package/dist/dts/connect/message.d.ts +51 -0
  11. package/dist/dts/connect/message.d.ts.map +1 -1
  12. package/dist/dts/connect/socket.d.ts +72 -8
  13. package/dist/dts/connect/socket.d.ts.map +1 -1
  14. package/dist/dts/connect/socket.status.d.ts +79 -0
  15. package/dist/dts/connect/socket.status.d.ts.map +1 -0
  16. package/dist/dts/datasource/datasource.d.ts +9 -0
  17. package/dist/dts/datasource/datasource.d.ts.map +1 -1
  18. package/dist/dts/fdc3/fdc3.d.ts +17 -1
  19. package/dist/dts/fdc3/fdc3.d.ts.map +1 -1
  20. package/dist/dts/index.d.ts +1 -0
  21. package/dist/dts/index.d.ts.map +1 -1
  22. package/dist/dts/networkMonitor/config.d.ts +56 -0
  23. package/dist/dts/networkMonitor/config.d.ts.map +1 -0
  24. package/dist/dts/networkMonitor/index.d.ts +4 -0
  25. package/dist/dts/networkMonitor/index.d.ts.map +1 -0
  26. package/dist/dts/networkMonitor/service.d.ts +193 -0
  27. package/dist/dts/networkMonitor/service.d.ts.map +1 -0
  28. package/dist/dts/networkMonitor/types.d.ts +133 -0
  29. package/dist/dts/networkMonitor/types.d.ts.map +1 -0
  30. package/dist/dts/testing/mocks/connect/connect.d.ts +1 -0
  31. package/dist/dts/testing/mocks/connect/connect.d.ts.map +1 -1
  32. package/dist/dts/testing/mocks/connect/socket.d.ts +5 -1
  33. package/dist/dts/testing/mocks/connect/socket.d.ts.map +1 -1
  34. package/dist/dts/testing/mocks/datasource/datasource.d.ts +1 -0
  35. package/dist/dts/testing/mocks/datasource/datasource.d.ts.map +1 -1
  36. package/dist/dts/user/user.d.ts +15 -0
  37. package/dist/dts/user/user.d.ts.map +1 -1
  38. package/dist/esm/auth/auth.js +5 -2
  39. package/dist/esm/connect/connect.events.js +113 -0
  40. package/dist/esm/connect/connect.js +30 -8
  41. package/dist/esm/connect/http.connect.js +6 -0
  42. package/dist/esm/connect/index.js +2 -0
  43. package/dist/esm/connect/message.js +25 -4
  44. package/dist/esm/connect/socket.js +113 -44
  45. package/dist/esm/connect/socket.status.js +119 -0
  46. package/dist/esm/datasource/datasource.js +18 -8
  47. package/dist/esm/fdc3/fdc3.js +4 -4
  48. package/dist/esm/index.js +1 -0
  49. package/dist/esm/networkMonitor/config.js +46 -0
  50. package/dist/esm/networkMonitor/index.js +3 -0
  51. package/dist/esm/networkMonitor/service.js +432 -0
  52. package/dist/esm/networkMonitor/types.js +5 -0
  53. package/dist/esm/testing/mocks/connect/connect.js +3 -0
  54. package/dist/esm/testing/mocks/connect/socket.js +1 -1
  55. package/dist/esm/testing/mocks/datasource/datasource.js +1 -0
  56. package/dist/esm/user/user.js +22 -1
  57. package/dist/foundation-comms.api.json +14711 -8166
  58. package/dist/foundation-comms.d.ts +841 -13
  59. package/docs/api/foundation-comms.commitevent.md +14 -0
  60. package/docs/api/foundation-comms.commiteventdetail.md +17 -0
  61. package/docs/api/foundation-comms.commiteventtype.md +12 -0
  62. package/docs/api/foundation-comms.connect.getmorecolumns.md +26 -0
  63. package/docs/api/foundation-comms.connect.md +1 -0
  64. package/docs/api/foundation-comms.connectevents.addcommitlistener.md +24 -0
  65. package/docs/api/foundation-comms.connectevents.addmetadatalistener.md +24 -0
  66. package/docs/api/foundation-comms.connectevents.addstreamlistener.md +25 -0
  67. package/docs/api/foundation-comms.connectevents.md +22 -0
  68. package/docs/api/foundation-comms.connecteventsemitter.md +24 -0
  69. package/docs/api/foundation-comms.connecteventsemitter.oncommitevent.md +25 -0
  70. package/docs/api/foundation-comms.connecteventsemitter.onmetadataevent.md +26 -0
  71. package/docs/api/foundation-comms.connecteventsemitter.onstreamcompleteevent.md +24 -0
  72. package/docs/api/foundation-comms.connecteventsemitter.onstreamevent.md +27 -0
  73. package/docs/api/foundation-comms.currentuser.md +2 -0
  74. package/docs/api/foundation-comms.currentuser.set.md +22 -0
  75. package/docs/api/foundation-comms.currentuser.unset.md +15 -0
  76. package/docs/api/foundation-comms.datasource.destroy.md +17 -0
  77. package/docs/api/foundation-comms.datasource.md +1 -0
  78. package/docs/api/foundation-comms.defaultconnect._constructor_.md +2 -1
  79. package/docs/api/foundation-comms.defaultconnect.getmorecolumns.md +22 -0
  80. package/docs/api/foundation-comms.defaultconnect.md +2 -1
  81. package/docs/api/foundation-comms.defaultconnectevents.addcommitlistener.md +24 -0
  82. package/docs/api/foundation-comms.defaultconnectevents.addmetadatalistener.md +24 -0
  83. package/docs/api/foundation-comms.defaultconnectevents.addstreamlistener.md +25 -0
  84. package/docs/api/foundation-comms.defaultconnectevents.md +27 -0
  85. package/docs/api/foundation-comms.defaultconnectevents.oncommitevent.md +25 -0
  86. package/docs/api/foundation-comms.defaultconnectevents.onmetadataevent.md +26 -0
  87. package/docs/api/foundation-comms.defaultconnectevents.onstreamcompleteevent.md +24 -0
  88. package/docs/api/foundation-comms.defaultconnectevents.onstreamevent.md +27 -0
  89. package/docs/api/foundation-comms.defaultdatasource.destroy.md +17 -0
  90. package/docs/api/foundation-comms.defaultdatasource.md +1 -0
  91. package/docs/api/foundation-comms.defaulthttpconnect.getmorecolumns.md +22 -0
  92. package/docs/api/foundation-comms.defaulthttpconnect.md +1 -0
  93. package/docs/api/foundation-comms.defaultmessagebuilder._constructor_.md +21 -0
  94. package/docs/api/foundation-comms.defaultmessagebuilder.createchangepasswordmessage.md +24 -0
  95. package/docs/api/foundation-comms.defaultmessagebuilder.createcommitmessage.md +23 -0
  96. package/docs/api/foundation-comms.defaultmessagebuilder.createdatalogoffmessage.md +22 -0
  97. package/docs/api/foundation-comms.defaultmessagebuilder.createdatalogonmessage.md +23 -0
  98. package/docs/api/foundation-comms.defaultmessagebuilder.createforgotpasswordmessage.md +24 -0
  99. package/docs/api/foundation-comms.defaultmessagebuilder.createforgotpasswordtokenmessage.md +25 -0
  100. package/docs/api/foundation-comms.defaultmessagebuilder.createhttpheadersfrommessage.md +23 -0
  101. package/docs/api/foundation-comms.defaultmessagebuilder.createloginmessage.md +22 -0
  102. package/docs/api/foundation-comms.defaultmessagebuilder.createlogoutmessage.md +22 -0
  103. package/docs/api/foundation-comms.defaultmessagebuilder.createmetarequestmessage.md +23 -0
  104. package/docs/api/foundation-comms.defaultmessagebuilder.createmorecolumnsmessage.md +22 -0
  105. package/docs/api/foundation-comms.defaultmessagebuilder.createmorerowsmessage.md +22 -0
  106. package/docs/api/foundation-comms.defaultmessagebuilder.createrefreshtokenmessage.md +15 -0
  107. package/docs/api/foundation-comms.defaultmessagebuilder.createrequestmessage.md +23 -0
  108. package/docs/api/foundation-comms.defaultmessagebuilder.createresourcesmessage.md +22 -0
  109. package/docs/api/foundation-comms.defaultmessagebuilder.md +41 -0
  110. package/docs/api/foundation-comms.defaultnetworkmonitor.addresource.md +23 -0
  111. package/docs/api/foundation-comms.defaultnetworkmonitor.create.md +16 -0
  112. package/docs/api/foundation-comms.defaultnetworkmonitor.destroy.md +16 -0
  113. package/docs/api/foundation-comms.defaultnetworkmonitor.md +31 -0
  114. package/docs/api/foundation-comms.defaultnetworkmonitor.removeresource.md +22 -0
  115. package/docs/api/foundation-comms.defaultnetworkmonitor.runallchecks.md +11 -0
  116. package/docs/api/foundation-comms.defaultnetworkmonitor.status.md +12 -0
  117. package/docs/api/foundation-comms.defaultnetworkmonitorconfig.md +13 -0
  118. package/docs/api/foundation-comms.defaultsocket._constructor_.md +24 -0
  119. package/docs/api/foundation-comms.defaultsocket.connect.md +24 -0
  120. package/docs/api/foundation-comms.defaultsocket.hasvalidsession.md +13 -0
  121. package/docs/api/foundation-comms.defaultsocket.isconfigured.md +11 -0
  122. package/docs/api/foundation-comms.defaultsocket.isconnected.md +11 -0
  123. package/docs/api/foundation-comms.defaultsocket.isconnectedsubject.md +11 -0
  124. package/docs/api/foundation-comms.defaultsocket.isconnecting.md +11 -0
  125. package/docs/api/foundation-comms.defaultsocket.isdisconnected.md +11 -0
  126. package/docs/api/foundation-comms.defaultsocket.isdisconnectedbyserver.md +11 -0
  127. package/docs/api/foundation-comms.defaultsocket.isreconnecting.md +11 -0
  128. package/docs/api/foundation-comms.defaultsocket.md +44 -0
  129. package/docs/api/foundation-comms.defaultsocket.reset.md +15 -0
  130. package/docs/api/foundation-comms.defaultsocket.send.md +23 -0
  131. package/docs/api/foundation-comms.defaultsocket.sendforstream.md +25 -0
  132. package/docs/api/foundation-comms.defaultsocket.socketmessages.md +11 -0
  133. package/docs/api/foundation-comms.defaultsocketstatus.closedclean.md +11 -0
  134. package/docs/api/foundation-comms.defaultsocketstatus.closedcode.md +11 -0
  135. package/docs/api/foundation-comms.defaultsocketstatus.closedreason.md +11 -0
  136. package/docs/api/foundation-comms.defaultsocketstatus.hasvalidsession.md +11 -0
  137. package/docs/api/foundation-comms.defaultsocketstatus.isconfigured.md +11 -0
  138. package/docs/api/foundation-comms.defaultsocketstatus.isconnected.md +11 -0
  139. package/docs/api/foundation-comms.defaultsocketstatus.isconnectedchanged.md +15 -0
  140. package/docs/api/foundation-comms.defaultsocketstatus.isconnectedsubject.md +11 -0
  141. package/docs/api/foundation-comms.defaultsocketstatus.isconnecting.md +11 -0
  142. package/docs/api/foundation-comms.defaultsocketstatus.isdisconnected.md +11 -0
  143. package/docs/api/foundation-comms.defaultsocketstatus.isdisconnectedbyserver.md +11 -0
  144. package/docs/api/foundation-comms.defaultsocketstatus.isreconnecting.md +11 -0
  145. package/docs/api/foundation-comms.defaultsocketstatus.isreconnectingchanged.md +15 -0
  146. package/docs/api/foundation-comms.defaultsocketstatus.md +42 -0
  147. package/docs/api/foundation-comms.defaultsocketstatus.onclose.md +22 -0
  148. package/docs/api/foundation-comms.defaultsocketstatus.reconnectionlimitreached.md +11 -0
  149. package/docs/api/foundation-comms.defaultsocketstatus.resetclosedstate.md +15 -0
  150. package/docs/api/foundation-comms.defaultsocketstatus.serialize.md +15 -0
  151. package/docs/api/foundation-comms.genesisconnectevents.md +18 -0
  152. package/docs/api/foundation-comms.getnetworkmonitor.md +30 -0
  153. package/docs/api/foundation-comms.getsocket.md +30 -0
  154. package/docs/api/foundation-comms.getsocketstatus.md +30 -0
  155. package/docs/api/foundation-comms.md +39 -0
  156. package/docs/api/foundation-comms.messagebuilder.createmorecolumnsmessage.md +30 -0
  157. package/docs/api/foundation-comms.messagebuilder.md +1 -0
  158. package/docs/api/foundation-comms.messagehaserrorcode.md +13 -0
  159. package/docs/api/foundation-comms.messagetype.md +2 -0
  160. package/docs/api/foundation-comms.metadataevent.md +14 -0
  161. package/docs/api/foundation-comms.metadataeventdetail.md +18 -0
  162. package/docs/api/foundation-comms.metadataeventtype.md +12 -0
  163. package/docs/api/foundation-comms.monitoredresource.md +15 -0
  164. package/docs/api/foundation-comms.monitoredresourcechecks.md +15 -0
  165. package/docs/api/foundation-comms.monitoredresourcechecksresult.isconnected.md +11 -0
  166. package/docs/api/foundation-comms.monitoredresourcechecksresult.lastmessage.md +11 -0
  167. package/docs/api/foundation-comms.monitoredresourcechecksresult.lastupdated.md +11 -0
  168. package/docs/api/foundation-comms.monitoredresourcechecksresult.md +23 -0
  169. package/docs/api/foundation-comms.monitoredresourcechecksresult.timeout.md +11 -0
  170. package/docs/api/foundation-comms.monitoredresourcedatalogon.md +15 -0
  171. package/docs/api/foundation-comms.monitoredresourcemetadata.md +15 -0
  172. package/docs/api/foundation-comms.networklogger.md +12 -0
  173. package/docs/api/foundation-comms.networkmonitor.addresource.md +23 -0
  174. package/docs/api/foundation-comms.networkmonitor.create.md +15 -0
  175. package/docs/api/foundation-comms.networkmonitor.destroy.md +15 -0
  176. package/docs/api/foundation-comms.networkmonitor.md +34 -0
  177. package/docs/api/foundation-comms.networkmonitor.removeresource.md +22 -0
  178. package/docs/api/foundation-comms.networkmonitor.runallchecks.md +23 -0
  179. package/docs/api/foundation-comms.networkmonitor.status.md +11 -0
  180. package/docs/api/foundation-comms.networkmonitorconfig.checkinterval.md +13 -0
  181. package/docs/api/foundation-comms.networkmonitorconfig.checktimeout.md +13 -0
  182. package/docs/api/foundation-comms.networkmonitorconfig.documentevents.md +13 -0
  183. package/docs/api/foundation-comms.networkmonitorconfig.eventemitter.md +13 -0
  184. package/docs/api/foundation-comms.networkmonitorconfig.genesisconnectevents.md +13 -0
  185. package/docs/api/foundation-comms.networkmonitorconfig.md +27 -0
  186. package/docs/api/foundation-comms.networkmonitorconfig.resourcechecks.md +13 -0
  187. package/docs/api/foundation-comms.networkmonitorconfig.resourcedatalogon.md +18 -0
  188. package/docs/api/foundation-comms.networkmonitorconfig.windowevents.md +13 -0
  189. package/docs/api/foundation-comms.resourcehealth.md +19 -0
  190. package/docs/api/foundation-comms.serializedsocketstatus.closedclean.md +11 -0
  191. package/docs/api/foundation-comms.serializedsocketstatus.closedcode.md +11 -0
  192. package/docs/api/foundation-comms.serializedsocketstatus.closedreason.md +11 -0
  193. package/docs/api/foundation-comms.serializedsocketstatus.hasvalidsession.md +11 -0
  194. package/docs/api/foundation-comms.serializedsocketstatus.isconfigured.md +13 -0
  195. package/docs/api/foundation-comms.serializedsocketstatus.isconnected.md +11 -0
  196. package/docs/api/foundation-comms.serializedsocketstatus.isconnecting.md +11 -0
  197. package/docs/api/foundation-comms.serializedsocketstatus.isdisconnected.md +11 -0
  198. package/docs/api/foundation-comms.serializedsocketstatus.isdisconnectedbyserver.md +11 -0
  199. package/docs/api/foundation-comms.serializedsocketstatus.isreconnecting.md +11 -0
  200. package/docs/api/foundation-comms.serializedsocketstatus.md +30 -0
  201. package/docs/api/foundation-comms.serializedsocketstatus.reconnectionlimitreached.md +11 -0
  202. package/docs/api/foundation-comms.socket.md +3 -11
  203. package/docs/api/foundation-comms.socket.sendforstream.md +2 -1
  204. package/docs/api/{foundation-comms.socket.isconnectedsubject.md → foundation-comms.socketstatus.isconnectedsubject.md} +2 -2
  205. package/docs/api/foundation-comms.socketstatus.md +28 -0
  206. package/docs/api/foundation-comms.socketstatus.onclose.md +22 -0
  207. package/docs/api/foundation-comms.socketstatus.serialize.md +15 -0
  208. package/docs/api/foundation-comms.streamcompleteevent.md +14 -0
  209. package/docs/api/foundation-comms.streamcompleteeventtype.md +12 -0
  210. package/docs/api/foundation-comms.streamevent.md +14 -0
  211. package/docs/api/foundation-comms.streameventdetail.md +19 -0
  212. package/docs/api/foundation-comms.streameventfunctions.md +19 -0
  213. package/docs/api/foundation-comms.streameventtype.md +12 -0
  214. package/docs/api/foundation-comms.systemhealthchanged.md +13 -0
  215. package/docs/api/foundation-comms.systemhealthchangedevent.md +15 -0
  216. package/docs/api/foundation-comms.systemhealthstatus.md +29 -0
  217. package/docs/api/foundation-comms.user.md +2 -0
  218. package/docs/api/foundation-comms.user.set.md +22 -0
  219. package/docs/api/foundation-comms.user.unset.md +15 -0
  220. package/docs/api-report.md +520 -16
  221. package/package.json +13 -11
  222. package/docs/api/foundation-comms.socket.hasvalidsession.md +0 -11
  223. package/docs/api/foundation-comms.socket.isconnected.md +0 -11
  224. package/docs/api/foundation-comms.socket.isreconnecting.md +0 -11
@@ -0,0 +1,432 @@
1
+ var _a;
2
+ import { __awaiter, __decorate } from "tslib";
3
+ import { createLogger, LogLevel } from '@genesislcap/foundation-logger';
4
+ import { formatDateTimeTimestamp, resolveAfter } from '@genesislcap/foundation-utils';
5
+ import { observable } from '@microsoft/fast-element';
6
+ import { DI } from '@microsoft/fast-foundation';
7
+ import Bowser from 'bowser';
8
+ import { StatusCodes } from 'http-status-codes';
9
+ import { ConnectEvents } from '../connect/connect.events';
10
+ import { messageHasErrorCode, MessageType } from '../connect/message';
11
+ import { SocketStatus } from '../connect/socket.status';
12
+ import { User } from '../user/user';
13
+ import { NetworkMonitorConfig } from './config';
14
+ import { SystemHealthChanged, } from './types';
15
+ /**
16
+ * @public
17
+ */
18
+ export const networkLogger = createLogger('network-monitor', { level: LogLevel.Info });
19
+ /**
20
+ * @internal
21
+ */
22
+ const firstUpdated = Date.now();
23
+ /**
24
+ * @internal
25
+ */
26
+ const browserInformation = ((_a = window.navigator) === null || _a === void 0 ? void 0 : _a.userAgent)
27
+ ? Bowser.parse(window.navigator.userAgent)
28
+ : undefined;
29
+ /**
30
+ * Default NetworkMonitor implementation.
31
+ * @public
32
+ */
33
+ export class DefaultNetworkMonitor {
34
+ constructor() {
35
+ /**
36
+ * @internal
37
+ */
38
+ this.unsubscribableObservers = [];
39
+ /**
40
+ * {@inheritDoc NetworkMonitor.runAllChecks}
41
+ */
42
+ this.runAllChecks = (source, force) => __awaiter(this, void 0, void 0, function* () {
43
+ /**
44
+ * Abort if checks are already running and the call is not forced
45
+ */
46
+ if (this.isRunningChecks && !force) {
47
+ return;
48
+ }
49
+ networkLogger.info(`Run health checks, triggered by`, source, `| Active resources`, this.resources.size);
50
+ this.isRunningChecks = true;
51
+ /**
52
+ * Synchronise check interval given this has multiple non-automated triggers
53
+ */
54
+ this.synchroniseCheckInterval();
55
+ let formattedTimestamp = this.getFormattedTimestamp(this.getNowTimestamp());
56
+ const isOnline = yield this.isOnlineCheck();
57
+ if (!isOnline) {
58
+ networkLogger.warn(`Network disconnected at ${formattedTimestamp}`);
59
+ const socket = this.normaliseSerializedSocketStatus(this.socketStatus.serialize(), false);
60
+ const resources = [...this.resources].reduce((output, [_, metadata]) => (Object.assign(Object.assign({}, output), { [metadata.resourceName]: this.normaliseResourceHealth({
61
+ name: metadata.resourceName,
62
+ sourceRef: metadata.message.SOURCE_REF,
63
+ isConnected: metadata.isConnected,
64
+ lastUpdated: metadata.lastUpdated,
65
+ }, false) })), {});
66
+ this.reportSystemHealth({
67
+ isAuthenticated: socket.hasValidSession,
68
+ isOnline: false,
69
+ resources,
70
+ resourcesAllConnected: false,
71
+ socket,
72
+ });
73
+ this.isRunningChecks = false;
74
+ return;
75
+ }
76
+ networkLogger.debug(`Network connected at ${formattedTimestamp}`);
77
+ const socket = this.normaliseSerializedSocketStatus(this.socketStatus.serialize());
78
+ if (socket.isConnecting) {
79
+ networkLogger.debug(`Aborting remaining health checks as socket is still connecting`);
80
+ this.isRunningChecks = false;
81
+ return;
82
+ }
83
+ let resourcesAllConnected = true;
84
+ const allChecks = [];
85
+ this.resources.forEach((meta, resource) => {
86
+ const { resourceName: name, message, functions } = meta;
87
+ const { resourceChecks = this.config.resourceChecks, resourceDataLogon = this.config.resourceDataLogon, } = functions;
88
+ const { SOURCE_REF: sourceRef } = message;
89
+ let isConnected = false;
90
+ let lastUpdated;
91
+ let lastMessage;
92
+ let lastError;
93
+ let timeout;
94
+ let attemptDataLogon;
95
+ const checkEnvelope = () => __awaiter(this, void 0, void 0, function* () {
96
+ var _a;
97
+ try {
98
+ networkLogger.debug(`Running health check against ${name}`);
99
+ const result = yield Promise.race([
100
+ resourceChecks(sourceRef, resource),
101
+ resolveAfter(this.config.checkTimeout, () => ({
102
+ isConnected: false,
103
+ lastUpdated: this.getNowTimestamp(),
104
+ timeout: true,
105
+ })),
106
+ ]);
107
+ isConnected = result.isConnected;
108
+ lastUpdated = result.lastUpdated;
109
+ lastMessage = result.lastMessage;
110
+ timeout = result.timeout;
111
+ attemptDataLogon =
112
+ timeout ||
113
+ (lastMessage === null || lastMessage === void 0 ? void 0 : lastMessage.MESSAGE_TYPE) === MessageType.MSG_NACK ||
114
+ messageHasErrorCode(lastMessage, StatusCodes.NOT_FOUND);
115
+ }
116
+ catch (e) {
117
+ isConnected = false;
118
+ lastUpdated = this.getNowTimestamp();
119
+ lastError = e;
120
+ lastMessage = (_a = e === null || e === void 0 ? void 0 : e.receivedMessage) !== null && _a !== void 0 ? _a : e;
121
+ attemptDataLogon =
122
+ (lastMessage === null || lastMessage === void 0 ? void 0 : lastMessage.MESSAGE_TYPE) === MessageType.MSG_NACK ||
123
+ messageHasErrorCode(lastMessage, StatusCodes.NOT_FOUND);
124
+ }
125
+ formattedTimestamp = this.getFormattedTimestamp(lastUpdated !== null && lastUpdated !== void 0 ? lastUpdated : this.getNowTimestamp());
126
+ if (isConnected) {
127
+ networkLogger.debug(`${name} is healthy at ${formattedTimestamp}`);
128
+ }
129
+ else {
130
+ networkLogger.warn(`${name} is not healthy at ${formattedTimestamp}`);
131
+ }
132
+ if (lastError) {
133
+ networkLogger.error(`${name} errored at ${formattedTimestamp}`, lastError);
134
+ }
135
+ if (attemptDataLogon) {
136
+ networkLogger.error(`${name} timed out at ${formattedTimestamp}. Re-attempting data logon.`);
137
+ resourceDataLogon(meta);
138
+ }
139
+ /**
140
+ * Apply the last resource's isConnected while `resourcesAllConnected` remains true.
141
+ */
142
+ if (resourcesAllConnected) {
143
+ resourcesAllConnected = isConnected;
144
+ }
145
+ /**
146
+ * Return the resource health
147
+ */
148
+ return {
149
+ name,
150
+ sourceRef,
151
+ isConnected,
152
+ lastUpdated,
153
+ lastError,
154
+ };
155
+ });
156
+ allChecks.push(checkEnvelope());
157
+ });
158
+ const results = yield Promise.allSettled(allChecks);
159
+ const resources = results.reduce((prev, curr) => {
160
+ if (curr.status === 'fulfilled') {
161
+ return Object.assign(Object.assign({}, prev), { [curr.value.name]: this.normaliseResourceHealth(curr.value) });
162
+ }
163
+ networkLogger.warn(`Unexpected promise rejection occurred. Please check any custom resourceChecks return MonitoredResourceChecksResult.`);
164
+ return prev;
165
+ }, {});
166
+ this.reportSystemHealth({
167
+ isAuthenticated: socket.hasValidSession,
168
+ isOnline,
169
+ resources,
170
+ resourcesAllConnected,
171
+ socket,
172
+ });
173
+ this.isRunningChecks = false;
174
+ });
175
+ }
176
+ /**
177
+ * {@inheritDoc NetworkMonitor.create}
178
+ */
179
+ create() {
180
+ if (this.resources) {
181
+ networkLogger.warn(`NetworkMonitor already created. If this is intentional, please call NetworkMonitor.destroy first.`);
182
+ return;
183
+ }
184
+ this.addListeners();
185
+ this.resources = new Map();
186
+ this.synchroniseCheckInterval();
187
+ /**
188
+ * Report system health on creation to populate initial status data.
189
+ */
190
+ this.runAllChecks('network monitor create');
191
+ }
192
+ /**
193
+ * {@inheritDoc NetworkMonitor.destroy}
194
+ */
195
+ destroy() {
196
+ this.removeListeners();
197
+ clearInterval(this.internalId);
198
+ this.resources.clear();
199
+ this.resources = undefined;
200
+ this.status = undefined;
201
+ }
202
+ /**
203
+ * @internal
204
+ */
205
+ isOnlineCheck() {
206
+ return Promise.resolve(navigator.onLine);
207
+ }
208
+ /**
209
+ * {@inheritDoc NetworkMonitor.addResource}
210
+ */
211
+ addResource(resource, metadata) {
212
+ if (!this.resources) {
213
+ this.create();
214
+ }
215
+ this.resources.set(resource, metadata);
216
+ }
217
+ /**
218
+ * {@inheritDoc NetworkMonitor.removeResource}
219
+ */
220
+ removeResource(resource) {
221
+ this.resources.delete(resource);
222
+ }
223
+ /**
224
+ * @internal
225
+ */
226
+ addListeners() {
227
+ var _a, _b;
228
+ (_a = this.config.windowEvents) === null || _a === void 0 ? void 0 : _a.forEach((eventName) => window.addEventListener(eventName, this.runAllChecks));
229
+ (_b = this.config.documentEvents) === null || _b === void 0 ? void 0 : _b.forEach((eventName) => document.addEventListener(eventName, this.runAllChecks));
230
+ if (this.config.genesisConnectEvents.includes('stream')) {
231
+ this.unsubscribableObservers.push(this.connectEvents.addStreamListener(({ detail }) => {
232
+ const { functions, message, resourceName, stream } = detail;
233
+ this.addResource(stream, {
234
+ functions,
235
+ message,
236
+ resourceName,
237
+ });
238
+ }, ({ detail }) => {
239
+ this.removeResource(detail);
240
+ }));
241
+ }
242
+ if (this.config.genesisConnectEvents.includes('commit')) {
243
+ this.unsubscribableObservers.push(this.connectEvents.addCommitListener(this.runAllChecks));
244
+ }
245
+ this.unsubscribableObservers.push(this.connectEvents.addMetadataListener(({ detail }) => {
246
+ const { resourceName, error } = detail;
247
+ if (!!error) {
248
+ /**
249
+ * Meta/init failure edge case, data server is already down when the app loads and `connect.getMetadata` fails.
250
+ * In such cases the stream / resource is never actually created, so the `onStreamEvent` is never fired.
251
+ * Meta/init failures are only reported in console logs, however, might be a good idea to show those here.
252
+ */
253
+ networkLogger.error(`${resourceName} had an unrecoverable error at ${this.getFormattedTimestamp(this.getNowTimestamp())}`, `Please check the resource is running.`, error);
254
+ return;
255
+ }
256
+ }));
257
+ }
258
+ /**
259
+ * @internal
260
+ */
261
+ removeListeners() {
262
+ var _a, _b;
263
+ (_a = this.config.windowEvents) === null || _a === void 0 ? void 0 : _a.forEach((eventName) => window.removeEventListener(eventName, this.runAllChecks));
264
+ (_b = this.config.documentEvents) === null || _b === void 0 ? void 0 : _b.forEach((eventName) => document.removeEventListener(eventName, this.runAllChecks));
265
+ this.unsubscribableObservers.forEach((unsubscribe) => unsubscribe());
266
+ this.unsubscribableObservers.length = 0;
267
+ }
268
+ /**
269
+ * @internal
270
+ */
271
+ reportSystemHealth(detail) {
272
+ var _a;
273
+ const eventEmitter = (_a = this.config.eventEmitter) !== null && _a !== void 0 ? _a : document;
274
+ this.status = this.normaliseEventDetail(detail);
275
+ networkLogger.debug(`Dispatching 'system-health-changed'`, this.status);
276
+ eventEmitter === null || eventEmitter === void 0 ? void 0 : eventEmitter.dispatchEvent(new CustomEvent(SystemHealthChanged, {
277
+ detail: this.status,
278
+ bubbles: eventEmitter !== document,
279
+ composed: true,
280
+ }));
281
+ /**
282
+ * Kill the network monitor if the reconnection limit has been reached
283
+ */
284
+ if (this.status.socket.reconnectionLimitReached) {
285
+ networkLogger.debug('Network monitoring no longer required. Please check your network and reload your application.');
286
+ this.destroy();
287
+ }
288
+ }
289
+ /**
290
+ * @internal
291
+ */
292
+ reportStabilityToGenesis(detail) {
293
+ return __awaiter(this, void 0, void 0, function* () {
294
+ networkLogger.debug('User requested report stability to Genesis.');
295
+ networkLogger.info('Please attach this data to your Genesis Support request: \n', JSON.stringify(detail, null, 2));
296
+ return true;
297
+ });
298
+ }
299
+ /**
300
+ * @remarks
301
+ * Deal with false positives.
302
+ *
303
+ * @privateRemarks
304
+ * There's an argument here for and against normalising ResourceHealth. I think it's more useful to consumers like
305
+ * visual overlays if there is no conflicting information. If we're offline and using the cache, then that should be
306
+ * reflected here.
307
+ *
308
+ * @internal
309
+ */
310
+ normaliseResourceHealth(health, isOnline = true) {
311
+ var _a;
312
+ const isConnected = isOnline ? health.isConnected : false;
313
+ const lastUpdated = (_a = health.lastUpdated) !== null && _a !== void 0 ? _a : this.getNowTimestamp();
314
+ return Object.assign(Object.assign({}, health), { isConnected,
315
+ lastUpdated });
316
+ }
317
+ /**
318
+ * @remarks
319
+ * Deal with false positives.
320
+ *
321
+ * @privateRemarks
322
+ * There's an argument here for and against a normalised SerializedSocketStatus. I think it's more useful to consumers
323
+ * like visual overlays if there is no conflicting information. If we're offline and using the cache, then that
324
+ * should be reflected here.
325
+ *
326
+ * @internal
327
+ */
328
+ normaliseSerializedSocketStatus(socketStatus, isOnline = true) {
329
+ const isConnected = isOnline ? socketStatus.isConnected : false;
330
+ const isDisconnected = !isConnected;
331
+ /**
332
+ * I think hasValidSession might be best left as is given there are transient network issues. If we toggle it to
333
+ * false, consumers may try to move the app to the login screen.
334
+ *
335
+ * const hasValidSession = isOnline ? socketStatus.hasValidSession : false;
336
+ */
337
+ return Object.assign(Object.assign({}, socketStatus), { isConnected,
338
+ isDisconnected });
339
+ }
340
+ /**
341
+ * @internal
342
+ */
343
+ normaliseEventDetail(detail) {
344
+ var _a, _b, _c, _d;
345
+ const isHealthy = !!(((_a = detail.socket) === null || _a === void 0 ? void 0 : _a.isConfigured)
346
+ ? detail.isOnline && ((_b = detail.socket) === null || _b === void 0 ? void 0 : _b.isConnected) && detail.resourcesAllConnected
347
+ : detail.isOnline);
348
+ const lastUpdated = (_c = detail.lastUpdated) !== null && _c !== void 0 ? _c : this.getNowTimestamp();
349
+ const nextUpdate = (_d = detail.nextUpdate) !== null && _d !== void 0 ? _d : this.getNextTimestamp();
350
+ const username = detail.isAuthenticated && this.user ? this.user.username : undefined;
351
+ const normalisedDetail = Object.assign(Object.assign({}, detail), { browserInformation,
352
+ username,
353
+ isHealthy,
354
+ lastUpdated,
355
+ nextUpdate,
356
+ firstUpdated, runAllChecks: () => {
357
+ networkLogger.debug('User activated run checks command starting.');
358
+ this.runAllChecks('user requested');
359
+ }, reportStabilityToGenesis: () => {
360
+ return this.reportStabilityToGenesis(normalisedDetail);
361
+ } });
362
+ return normalisedDetail;
363
+ }
364
+ /**
365
+ * @internal
366
+ */
367
+ getFormattedTimestamp(milliseconds) {
368
+ return formatDateTimeTimestamp(milliseconds);
369
+ }
370
+ /**
371
+ * @internal
372
+ */
373
+ getNowTimestamp() {
374
+ return Date.now();
375
+ }
376
+ /**
377
+ * @internal
378
+ */
379
+ getNextTimestamp() {
380
+ const next = new Date(Date.now() + this.config.checkInterval);
381
+ return next.getTime();
382
+ }
383
+ /**
384
+ * @internal
385
+ */
386
+ synchroniseCheckInterval() {
387
+ clearInterval(this.internalId);
388
+ this.internalId = setInterval(() => this.runAllChecks('check interval'), this.config.checkInterval);
389
+ }
390
+ }
391
+ __decorate([
392
+ NetworkMonitorConfig
393
+ ], DefaultNetworkMonitor.prototype, "config", void 0);
394
+ __decorate([
395
+ SocketStatus
396
+ ], DefaultNetworkMonitor.prototype, "socketStatus", void 0);
397
+ __decorate([
398
+ ConnectEvents
399
+ ], DefaultNetworkMonitor.prototype, "connectEvents", void 0);
400
+ __decorate([
401
+ User
402
+ ], DefaultNetworkMonitor.prototype, "user", void 0);
403
+ __decorate([
404
+ observable
405
+ ], DefaultNetworkMonitor.prototype, "status", void 0);
406
+ /**
407
+ * NetworkMonitor DI key.
408
+ *
409
+ * @privateRemarks
410
+ * Marked as internal to stop api-extractor becoming confused cross-linking tokens with the same name.
411
+ *
412
+ * @internal
413
+ */
414
+ export const NetworkMonitor = DI.createInterface((x) => x.singleton(DefaultNetworkMonitor));
415
+ /**
416
+ * Gets NetworkMonitor from the DI container.
417
+ *
418
+ * @remarks
419
+ * A utility method for host applications that are not using decorators or the DI container.
420
+ *
421
+ * @example
422
+ * ```ts
423
+ * import { getNetworkMonitor } from '@genesislcap/foundation-comms';
424
+ * ...
425
+ * private monitor = getNetworkMonitor();
426
+ * ```
427
+ *
428
+ * @public
429
+ */
430
+ export function getNetworkMonitor() {
431
+ return DI.getOrCreateDOMContainer().get(NetworkMonitor);
432
+ }
@@ -0,0 +1,5 @@
1
+ /**
2
+ * SystemHealthChanged.
3
+ * @public
4
+ */
5
+ export const SystemHealthChanged = 'system-health-changed';
@@ -50,6 +50,9 @@ export class ConnectMock {
50
50
  getMoreRows(sourceRef) {
51
51
  return Promise.resolve(this.nextMessage);
52
52
  }
53
+ getMoreColumns(sourceRef) {
54
+ return Promise.resolve(this.nextMessage);
55
+ }
53
56
  dataLogoff(sourceRef) {
54
57
  return Promise.resolve(this.nextMessage);
55
58
  }
@@ -15,7 +15,7 @@ export class SocketMock {
15
15
  send(message) {
16
16
  return Promise.resolve(this.nextMessage);
17
17
  }
18
- sendForStream(message, onMessage, onError) {
18
+ sendForStream(message, onMessage, onError, onComplete) {
19
19
  return from(Promise.resolve(this.nextMessage));
20
20
  }
21
21
  socketMessages() {
@@ -6,6 +6,7 @@ export class DatasourceMock {
6
6
  return Promise.resolve(this.initialized);
7
7
  }
8
8
  deinit() { }
9
+ destroy() { }
9
10
  validResourceName(resourceName) {
10
11
  if (!resourceName)
11
12
  return false;
@@ -1,12 +1,26 @@
1
1
  import { __decorate } from "tslib";
2
2
  import { observable } from '@microsoft/fast-element';
3
+ import { DI } from '@microsoft/fast-foundation';
3
4
  /**
4
5
  * Represents the current user (i.e. the user that is currently logged in).
5
6
  * @public
6
7
  */
7
8
  export class CurrentUser {
8
9
  constructor(options) {
9
- Object.assign(this, options);
10
+ this.set(options);
11
+ }
12
+ set(options) {
13
+ if (!options) {
14
+ return;
15
+ }
16
+ this.permissions = options.permissions;
17
+ this.profiles = options.profiles;
18
+ this.username = options.username;
19
+ }
20
+ unset() {
21
+ this.permissions = undefined;
22
+ this.profiles = undefined;
23
+ this.username = undefined;
10
24
  }
11
25
  hasAdminProfile() {
12
26
  return this.hasProfile('ADMIN');
@@ -43,3 +57,10 @@ __decorate([
43
57
  __decorate([
44
58
  observable
45
59
  ], CurrentUser.prototype, "username", void 0);
60
+ /**
61
+ * User DI key.
62
+ * @privateRemarks
63
+ * Marked as internal to stop api-extractor becoming confused cross-linking tokens with the same name.
64
+ * @internal
65
+ */
66
+ export const User = DI.createInterface((x) => x.singleton(CurrentUser));