@genesislcap/foundation-comms 14.187.1 → 14.188.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 (156) hide show
  1. package/dist/dts/connect/connect.d.ts +11 -6
  2. package/dist/dts/connect/connect.d.ts.map +1 -1
  3. package/dist/dts/connect/http.connect.d.ts +2 -2
  4. package/dist/dts/connect/http.connect.d.ts.map +1 -1
  5. package/dist/dts/connect/message.d.ts +11 -0
  6. package/dist/dts/connect/message.d.ts.map +1 -1
  7. package/dist/dts/connect/socket.d.ts +6 -2
  8. package/dist/dts/connect/socket.d.ts.map +1 -1
  9. package/dist/dts/datasource/datasource.config.d.ts +44 -0
  10. package/dist/dts/datasource/datasource.config.d.ts.map +1 -0
  11. package/dist/dts/datasource/datasource.d.ts +49 -19
  12. package/dist/dts/datasource/datasource.d.ts.map +1 -1
  13. package/dist/dts/datasource/datasource.mixins.d.ts +367 -0
  14. package/dist/dts/datasource/datasource.mixins.d.ts.map +1 -0
  15. package/dist/dts/datasource/datasource.types.d.ts +14 -22
  16. package/dist/dts/datasource/datasource.types.d.ts.map +1 -1
  17. package/dist/dts/datasource/entityDatasource.d.ts +5 -8
  18. package/dist/dts/datasource/entityDatasource.d.ts.map +1 -1
  19. package/dist/dts/datasource/index.d.ts +2 -0
  20. package/dist/dts/datasource/index.d.ts.map +1 -1
  21. package/dist/dts/index.d.ts +1 -0
  22. package/dist/dts/index.d.ts.map +1 -1
  23. package/dist/dts/resources/genesis/config.d.ts +81 -0
  24. package/dist/dts/resources/genesis/config.d.ts.map +1 -0
  25. package/dist/dts/resources/genesis/genesis.d.ts +69 -0
  26. package/dist/dts/resources/genesis/genesis.d.ts.map +1 -0
  27. package/dist/dts/resources/genesis/index.d.ts +4 -0
  28. package/dist/dts/resources/genesis/index.d.ts.map +1 -0
  29. package/dist/dts/resources/genesis/types.d.ts +19 -0
  30. package/dist/dts/resources/genesis/types.d.ts.map +1 -0
  31. package/dist/dts/resources/index.d.ts +2 -0
  32. package/dist/dts/resources/index.d.ts.map +1 -0
  33. package/dist/dts/testing/mocks/auth/auth.d.ts +3 -0
  34. package/dist/dts/testing/mocks/auth/auth.d.ts.map +1 -1
  35. package/dist/dts/testing/mocks/connect/connect.d.ts +3 -2
  36. package/dist/dts/testing/mocks/connect/connect.d.ts.map +1 -1
  37. package/dist/dts/testing/mocks/connect/socket.d.ts +1 -0
  38. package/dist/dts/testing/mocks/connect/socket.d.ts.map +1 -1
  39. package/dist/dts/testing/mocks/datasource/datasource.d.ts +22 -4
  40. package/dist/dts/testing/mocks/datasource/datasource.d.ts.map +1 -1
  41. package/dist/dts/testing/mocks/index.d.ts +1 -0
  42. package/dist/dts/testing/mocks/index.d.ts.map +1 -1
  43. package/dist/dts/testing/mocks/resources/genesis/genesis.d.ts +16 -0
  44. package/dist/dts/testing/mocks/resources/genesis/genesis.d.ts.map +1 -0
  45. package/dist/dts/testing/mocks/resources/genesis/index.d.ts +2 -0
  46. package/dist/dts/testing/mocks/resources/genesis/index.d.ts.map +1 -0
  47. package/dist/dts/testing/mocks/resources/index.d.ts +2 -0
  48. package/dist/dts/testing/mocks/resources/index.d.ts.map +1 -0
  49. package/dist/esm/connect/connect.js +12 -15
  50. package/dist/esm/connect/http.connect.js +5 -3
  51. package/dist/esm/connect/message.js +2 -0
  52. package/dist/esm/connect/socket.js +19 -6
  53. package/dist/esm/datasource/datasource.config.js +41 -0
  54. package/dist/esm/datasource/datasource.js +133 -58
  55. package/dist/esm/datasource/datasource.mixins.js +86 -0
  56. package/dist/esm/datasource/datasource.types.js +2 -18
  57. package/dist/esm/datasource/entityDatasource.js +6 -0
  58. package/dist/esm/datasource/index.js +2 -0
  59. package/dist/esm/index.js +1 -0
  60. package/dist/esm/resources/genesis/config.js +51 -0
  61. package/dist/esm/resources/genesis/genesis.js +114 -0
  62. package/dist/esm/resources/genesis/index.js +3 -0
  63. package/dist/esm/resources/genesis/types.js +4 -0
  64. package/dist/esm/resources/index.js +1 -0
  65. package/dist/esm/testing/mocks/auth/auth.js +10 -0
  66. package/dist/esm/testing/mocks/connect/connect.js +9 -2
  67. package/dist/esm/testing/mocks/connect/socket.js +2 -0
  68. package/dist/esm/testing/mocks/datasource/datasource.js +59 -0
  69. package/dist/esm/testing/mocks/index.js +1 -0
  70. package/dist/esm/testing/mocks/resources/genesis/genesis.js +25 -0
  71. package/dist/esm/testing/mocks/resources/genesis/index.js +1 -0
  72. package/dist/esm/testing/mocks/resources/index.js +1 -0
  73. package/dist/foundation-comms.api.json +11047 -6292
  74. package/dist/foundation-comms.d.ts +696 -37
  75. package/docs/api/foundation-comms.connect.connect.md +2 -2
  76. package/docs/api/foundation-comms.connect.getavailableresources.md +2 -2
  77. package/docs/api/foundation-comms.connect.host.md +11 -0
  78. package/docs/api/foundation-comms.connect.md +1 -0
  79. package/docs/api/foundation-comms.datasource.init.md +2 -2
  80. package/docs/api/foundation-comms.datasource.md +3 -2
  81. package/docs/api/{foundation-comms.datasource.fieldmetadata.md → foundation-comms.datasource.status.md} +3 -4
  82. package/docs/api/foundation-comms.datasourceconfig.eventemitter.md +18 -0
  83. package/docs/api/foundation-comms.datasourceconfig.md +2 -1
  84. package/docs/api/foundation-comms.datasourceeventhandler.md +353 -0
  85. package/docs/api/foundation-comms.datasourcemetadata.availableindexes.md +11 -0
  86. package/docs/api/foundation-comms.datasourcemetadata.fetchmetadatarequired.md +11 -0
  87. package/docs/api/foundation-comms.datasourcemetadata.fieldmetadata.md +11 -0
  88. package/docs/api/foundation-comms.datasourcemetadata.md +24 -0
  89. package/docs/api/foundation-comms.datasourcemetadata.originalfielddef.md +11 -0
  90. package/docs/api/foundation-comms.datasourcemetadata.requestfields.md +11 -0
  91. package/docs/api/foundation-comms.datasourcestatus.md +21 -0
  92. package/docs/api/foundation-comms.datasourcestatuschanged.md +13 -0
  93. package/docs/api/foundation-comms.datasourcestatuschangedevent.md +15 -0
  94. package/docs/api/foundation-comms.defaultconnect.connect.md +2 -2
  95. package/docs/api/foundation-comms.defaultconnect.getavailableresources.md +2 -2
  96. package/docs/api/foundation-comms.defaultconnect.host.md +11 -0
  97. package/docs/api/foundation-comms.defaultconnect.md +1 -0
  98. package/docs/api/foundation-comms.defaultdatasource._constructor_.md +3 -2
  99. package/docs/api/foundation-comms.defaultdatasource.availableindexes.md +2 -1
  100. package/docs/api/foundation-comms.defaultdatasource.fetchandapplymetadata.md +22 -0
  101. package/docs/api/{foundation-comms.defaultdatasource._stream.md → foundation-comms.defaultdatasource.fetchmetadatarequired.md} +4 -3
  102. package/docs/api/foundation-comms.defaultdatasource.fieldmetadata.md +1 -0
  103. package/docs/api/foundation-comms.defaultdatasource.initialized.md +3 -1
  104. package/docs/api/foundation-comms.defaultdatasource.md +10 -7
  105. package/docs/api/foundation-comms.defaultdatasource.originalfielddef.md +2 -1
  106. package/docs/api/foundation-comms.defaultdatasource.requestfields.md +2 -1
  107. package/docs/api/foundation-comms.defaultdatasource.resources.md +11 -0
  108. package/docs/api/foundation-comms.defaultdatasource.status.md +12 -0
  109. package/docs/api/foundation-comms.defaultdatasource.stream.md +1 -1
  110. package/docs/api/foundation-comms.defaultdatasource.validresourcename.md +5 -0
  111. package/docs/api/foundation-comms.defaultdatasourceconfig.md +1 -1
  112. package/docs/api/foundation-comms.defaultgenesisresources._constructor_.md +21 -0
  113. package/docs/api/foundation-comms.defaultgenesisresources.config.md +11 -0
  114. package/docs/api/foundation-comms.defaultgenesisresources.connect.md +11 -0
  115. package/docs/api/foundation-comms.defaultgenesisresources.destroy.md +17 -0
  116. package/docs/api/foundation-comms.defaultgenesisresources.getresources.md +15 -0
  117. package/docs/api/foundation-comms.defaultgenesisresources.getresourcetypefor.md +24 -0
  118. package/docs/api/foundation-comms.defaultgenesisresources.isvalidresource.md +24 -0
  119. package/docs/api/foundation-comms.defaultgenesisresources.md +40 -0
  120. package/docs/api/foundation-comms.defaultgenesisresources.postloadedmessage.md +15 -0
  121. package/docs/api/foundation-comms.defaultgenesisresources.resources.md +11 -0
  122. package/docs/api/foundation-comms.defaultgenesisresources.resourcespromise.md +11 -0
  123. package/docs/api/foundation-comms.defaultgenesisresourcesconfig.md +13 -0
  124. package/docs/api/foundation-comms.defaulthttpconnect.getavailableresources.md +2 -2
  125. package/docs/api/foundation-comms.defaultsocket._constructor_.md +2 -1
  126. package/docs/api/foundation-comms.defaultsocket.config.md +11 -0
  127. package/docs/api/foundation-comms.defaultsocket.connect.md +2 -2
  128. package/docs/api/foundation-comms.defaultsocket.host.md +11 -0
  129. package/docs/api/foundation-comms.defaultsocket.md +3 -1
  130. package/docs/api/foundation-comms.eventmessagetype.md +2 -0
  131. package/docs/api/foundation-comms.genesisresources.destroy.md +13 -0
  132. package/docs/api/foundation-comms.genesisresources.getresourcetypefor.md +13 -0
  133. package/docs/api/foundation-comms.genesisresources.isvalidresource.md +13 -0
  134. package/docs/api/foundation-comms.genesisresources.md +26 -0
  135. package/docs/api/foundation-comms.genesisresourceschannel.md +33 -0
  136. package/docs/api/foundation-comms.genesisresourceschannelid.md +12 -0
  137. package/docs/api/foundation-comms.genesisresourcesconfig.md +21 -0
  138. package/docs/api/foundation-comms.genesisresourcesconfig.throwwhenunavailable.md +13 -0
  139. package/docs/api/foundation-comms.genesisresourcesconfig.throwwhenunknown.md +13 -0
  140. package/docs/api/foundation-comms.genesisresourcesevents.md +17 -0
  141. package/docs/api/foundation-comms.genesisresourcesmock.destroy.md +15 -0
  142. package/docs/api/foundation-comms.genesisresourcesmock.getresourcetypefor.md +24 -0
  143. package/docs/api/foundation-comms.genesisresourcesmock.isvalidresource.md +24 -0
  144. package/docs/api/foundation-comms.genesisresourcesmock.md +30 -0
  145. package/docs/api/foundation-comms.genesisresourcesmock.nextisvalidresourceresponse.md +11 -0
  146. package/docs/api/foundation-comms.genesisresourcesmock.nextresourcetypeforresponse.md +11 -0
  147. package/docs/api/foundation-comms.genesisresourcesmock.resources.md +11 -0
  148. package/docs/api/foundation-comms.getgenesisresources.md +30 -0
  149. package/docs/api/foundation-comms.getgenesisresourceschannel.md +39 -0
  150. package/docs/api/foundation-comms.md +19 -2
  151. package/docs/api/foundation-comms.resourceitem.md +15 -0
  152. package/docs/api/foundation-comms.resourcesmessage.md +18 -0
  153. package/docs/api/foundation-comms.socket.host.md +11 -0
  154. package/docs/api/foundation-comms.socket.md +6 -0
  155. package/docs/api-report.md +550 -25
  156. package/package.json +13 -12
@@ -1,51 +1,47 @@
1
1
  import { __awaiter, __decorate, __param, __rest } from "tslib";
2
2
  import { observable } from '@microsoft/fast-element';
3
- import { DI, optional } from '@microsoft/fast-foundation';
3
+ import { DI } from '@microsoft/fast-foundation';
4
4
  import { combineLatest, from, timer } from 'rxjs';
5
5
  import { switchMap, takeWhile } from 'rxjs/operators';
6
6
  import { Auth } from '../auth';
7
7
  import { Connect } from '../connect';
8
8
  import { extractFieldDefinitions, toFieldMetadata } from '../metadata/metadata.utils';
9
+ import { GenesisResources } from '../resources';
9
10
  import { logger } from '../utils';
10
- import { criteriaFiltersToFields } from './criteriaFiltersToFields';
11
- import { dataServerResultFilter } from './dataServerResultFilter';
12
- import { DatasourceConfig, DatasourceDefaults, ResourceType } from './datasource.types';
13
- /**
14
- * The default configuration for the Datasource service.
15
- * @public
16
- */
17
- export const defaultDatasourceConfig = {
18
- options: {
19
- criteria: '',
20
- isSnapshot: false,
21
- maxRows: DatasourceDefaults.MAX_ROWS_250,
22
- maxView: DatasourceDefaults.MAX_VIEW_1000,
23
- pollingInterval: DatasourceDefaults.REQ_REP_POLLING_INTERVAL_MS,
24
- movingView: false,
25
- orderBy: '',
26
- resourceName: '',
27
- reverse: false,
28
- },
29
- criteriaToFields: criteriaFiltersToFields,
30
- dataServerResultFilter: dataServerResultFilter,
31
- };
11
+ import { DatasourceConfig } from './datasource.config';
12
+ import { DatasourceStatusChanged, ResourceType } from './datasource.types';
32
13
  /**
33
14
  * The default implementation for the Datasource interface.
34
15
  * @public
35
16
  */
36
17
  let DefaultDatasource = class DefaultDatasource {
37
- constructor(connect, auth, config = defaultDatasourceConfig) {
18
+ /** {@inheritDoc Datasource.initialized} */
19
+ get initialized() {
20
+ var _a;
21
+ return !!((_a = this.status) === null || _a === void 0 ? void 0 : _a.isInitialized);
22
+ }
23
+ constructor(connect, auth, resources, config) {
38
24
  this.connect = connect;
39
25
  this.auth = auth;
26
+ this.resources = resources;
40
27
  this.config = config;
41
- this.initialized = false;
42
- this.readOnly = true;
28
+ /** {@inheritDoc DatasourceMetadata.fetchMetadataRequired} */
29
+ this.fetchMetadataRequired = true;
30
+ /** {@inheritDoc DatasourceMetadata.originalFieldDef} */
43
31
  this.originalFieldDef = [];
44
- this.requestFields = [];
32
+ /** {@inheritDoc DatasourceMetadata.fieldMetadata} */
45
33
  this.fieldMetadata = [];
34
+ /** {@inheritDoc DatasourceMetadata.requestFields} */
35
+ this.requestFields = [];
36
+ /** {@inheritDoc DatasourceMetadata.availableIndexes} */
46
37
  this.availableIndexes = [];
38
+ this.readOnly = true;
47
39
  }
40
+ /**
41
+ * @deprecated - Please use {@link (GenesisResources:interface).isValidResource} instead.
42
+ */
48
43
  validResourceName(resourceName) {
44
+ logger.deprecated('Datasource.validResourceName', 'Use `GenesisResources.isValidResource` instead.');
49
45
  if (!resourceName)
50
46
  return false;
51
47
  if (!resourceName.trim().length)
@@ -53,41 +49,46 @@ let DefaultDatasource = class DefaultDatasource {
53
49
  // additional checks? regex? or maybe we can ask the server if it's a valid resource in the future
54
50
  return true;
55
51
  }
56
- init(options, fetchMeta = true) {
57
- var _a;
52
+ init(options, fetchMeta = this.fetchMetadataRequired) {
58
53
  return __awaiter(this, void 0, void 0, function* () {
59
- if (!this.validResourceName(options === null || options === void 0 ? void 0 : options.resourceName)) {
60
- return false;
61
- }
54
+ this.fetchMetadataRequired = fetchMeta;
62
55
  this.options = Object.assign(Object.assign({}, this.config.options), options);
63
56
  const resourceName = this.options.resourceName;
64
- if (fetchMeta) {
65
- logger.debug(`Initializing ${resourceName} Datasource`);
66
- const meta = yield this.connect
67
- .getMetadata(resourceName)
68
- .catch((e) => logger.error(`Metadata Fetch failed for ${resourceName}:`, e));
69
- if (!meta) {
70
- this.deinit();
71
- return false;
72
- }
73
- this.resourceType = meta.TYPE;
74
- this.availableIndexes = (_a = meta.INDEXES) !== null && _a !== void 0 ? _a : [];
75
- this.originalFieldDef = extractFieldDefinitions(meta);
76
- this.fieldMetadata = toFieldMetadata(this.originalFieldDef);
77
- this.requestFields = meta.REQUEST_FIELD || [];
78
- logger.debug(`Datasource for ${resourceName} is ready`);
57
+ const connected = this.connect.isConnected || (yield this.connect.connect());
58
+ if (!connected) {
59
+ logger.error(`Unable to connect to ${this.connect.host} to get ${resourceName} datasource`);
60
+ this.reportStatus();
61
+ return false;
62
+ }
63
+ const isValidResource = yield this.resources.isValidResource(resourceName);
64
+ if (!isValidResource) {
65
+ logger.error(`${resourceName} datasource does not exist on ${this.connect.host}`);
66
+ this.reportStatus();
67
+ return false;
79
68
  }
69
+ this.resourceType = yield this.resources.getResourceTypeFor(resourceName);
70
+ if (!this.resourceType) {
71
+ logger.error(`Unable to get the resource type for ${resourceName} datasource from ${this.connect.host}`);
72
+ this.reportStatus();
73
+ return false;
74
+ }
75
+ logger.debug(`Initializing ${resourceName} datasource from ${this.connect.host}`);
80
76
  if (!this.options.isSnapshot) {
81
- this._stream = yield this.createStream();
77
+ this.stream = yield this.createStream();
78
+ }
79
+ if (this.fetchMetadataRequired) {
80
+ yield this.fetchAndApplyMetadata(this.options.resourceName);
82
81
  }
83
- this.initialized = true;
82
+ logger.debug(`${resourceName} datasource initialization ${this.initialized ? `success` : 'failed'}`);
83
+ this.reportStatus();
84
84
  return this.initialized;
85
85
  });
86
86
  }
87
87
  deinit() {
88
88
  var _a;
89
89
  logger.debug('Datasource.deinit', (_a = this.options) === null || _a === void 0 ? void 0 : _a.resourceName);
90
- this.initialized = false;
90
+ this.status = undefined;
91
+ this.fetchMetadataRequired = undefined;
91
92
  this.options = {};
92
93
  this.resourceType = undefined;
93
94
  this.availableIndexes = [];
@@ -100,12 +101,11 @@ let DefaultDatasource = class DefaultDatasource {
100
101
  var _a;
101
102
  logger.debug('Datasource.destroy', (_a = this.options) === null || _a === void 0 ? void 0 : _a.resourceName);
102
103
  this.deinit();
103
- delete this._stream;
104
- }
105
- get stream() {
106
- return this._stream;
104
+ delete this.stream;
105
+ this.status = undefined;
107
106
  }
108
107
  get params() {
108
+ var _a;
109
109
  const params = {
110
110
  CRITERIA_MATCH: this.options.criteria,
111
111
  FIELDS: this.options.fields,
@@ -118,7 +118,7 @@ let DefaultDatasource = class DefaultDatasource {
118
118
  REVERSE: this.options.reverse,
119
119
  };
120
120
  if (this.options.orderBy) {
121
- if (this.availableIndexes.findIndex((i) => i.NAME === this.options.orderBy) > -1) {
121
+ if (((_a = this.availableIndexes) === null || _a === void 0 ? void 0 : _a.findIndex((i) => i.NAME === this.options.orderBy)) > -1) {
122
122
  params.ORDER_BY = this.options.orderBy;
123
123
  }
124
124
  else {
@@ -192,20 +192,95 @@ let DefaultDatasource = class DefaultDatasource {
192
192
  switchMap(() => from(this.snapshot())));
193
193
  }));
194
194
  }
195
+ fetchAndApplyMetadata(resourceName) {
196
+ var _a, _b;
197
+ return __awaiter(this, void 0, void 0, function* () {
198
+ try {
199
+ logger.debug(`Requesting metadata for ${this.options.resourceName} Datasource`);
200
+ const meta = yield this.connect.getMetadata(this.options.resourceName);
201
+ if (meta) {
202
+ this.availableIndexes = (_a = meta.INDEXES) !== null && _a !== void 0 ? _a : [];
203
+ this.originalFieldDef = extractFieldDefinitions(meta);
204
+ this.fieldMetadata = toFieldMetadata(this.originalFieldDef);
205
+ this.requestFields = meta.REQUEST_FIELD || [];
206
+ this.fetchMetadataRequired = false;
207
+ }
208
+ this.status = this.normaliseStatus({
209
+ isInitialized: true,
210
+ metadataRequired: true,
211
+ hasMetadata: ((_b = this.fieldMetadata) === null || _b === void 0 ? void 0 : _b.length) > 0,
212
+ });
213
+ }
214
+ catch (e) {
215
+ logger.error(`Metadata Fetch failed for ${resourceName}:`, e);
216
+ this.status = this.normaliseStatus({
217
+ isInitialized: false,
218
+ metadataRequired: true,
219
+ hasMetadata: false,
220
+ });
221
+ }
222
+ });
223
+ }
224
+ /**
225
+ * @internal
226
+ */
227
+ reportStatus(detail = {}) {
228
+ var _a;
229
+ const eventEmitter = (_a = this.config.eventEmitter) !== null && _a !== void 0 ? _a : document;
230
+ this.status = this.normaliseStatus(detail);
231
+ logger.debug(`Dispatching '${DatasourceStatusChanged}'`, this.status);
232
+ eventEmitter === null || eventEmitter === void 0 ? void 0 : eventEmitter.dispatchEvent(new CustomEvent(DatasourceStatusChanged, {
233
+ detail: this.status,
234
+ bubbles: eventEmitter !== document,
235
+ composed: true,
236
+ }));
237
+ }
238
+ /**
239
+ * @internal
240
+ */
241
+ normaliseStatus(status) {
242
+ var _a, _b, _c, _d, _e;
243
+ const isInitialized = (_a = status.isInitialized) !== null && _a !== void 0 ? _a : this.initialized;
244
+ const metadataRequired = (_b = status.metadataRequired) !== null && _b !== void 0 ? _b : this.fetchMetadataRequired;
245
+ const hasMetadata = (_c = status.hasMetadata) !== null && _c !== void 0 ? _c : ((_d = this.fieldMetadata) === null || _d === void 0 ? void 0 : _d.length) > 0;
246
+ return {
247
+ name: (_e = this.options) === null || _e === void 0 ? void 0 : _e.resourceName,
248
+ type: this.resourceType,
249
+ isInitialized,
250
+ metadataRequired,
251
+ hasMetadata,
252
+ };
253
+ }
195
254
  };
196
255
  __decorate([
197
256
  observable
198
- ], DefaultDatasource.prototype, "initialized", void 0);
257
+ ], DefaultDatasource.prototype, "status", void 0);
258
+ __decorate([
259
+ observable
260
+ ], DefaultDatasource.prototype, "fetchMetadataRequired", void 0);
261
+ __decorate([
262
+ observable
263
+ ], DefaultDatasource.prototype, "originalFieldDef", void 0);
264
+ __decorate([
265
+ observable
266
+ ], DefaultDatasource.prototype, "fieldMetadata", void 0);
267
+ __decorate([
268
+ observable
269
+ ], DefaultDatasource.prototype, "requestFields", void 0);
270
+ __decorate([
271
+ observable
272
+ ], DefaultDatasource.prototype, "availableIndexes", void 0);
199
273
  __decorate([
200
274
  observable
201
275
  ], DefaultDatasource.prototype, "readOnly", void 0);
202
276
  __decorate([
203
277
  observable
204
- ], DefaultDatasource.prototype, "_stream", void 0);
278
+ ], DefaultDatasource.prototype, "stream", void 0);
205
279
  DefaultDatasource = __decorate([
206
280
  __param(0, Connect),
207
281
  __param(1, Auth),
208
- __param(2, optional(DatasourceConfig))
282
+ __param(2, GenesisResources),
283
+ __param(3, DatasourceConfig)
209
284
  ], DefaultDatasource);
210
285
  export { DefaultDatasource };
211
286
  /**
@@ -0,0 +1,86 @@
1
+ import { __decorate } from "tslib";
2
+ import { observable } from '@microsoft/fast-element';
3
+ import { logger } from '../utils';
4
+ import { DatasourceStatusChanged, } from './datasource.types';
5
+ /**
6
+ * Datasource event handler mixin for target classes that use or are interested in datasource status changes.
7
+ *
8
+ * @remarks
9
+ * Classes that use the mixin are not required to own the datasource itself, there may be several interested parties.
10
+ *
11
+ * @example
12
+ * ```ts
13
+ * import { DatasourceEventHandler, DatasourceStatus } from '@genesislcap/foundation-comms';
14
+ * ...
15
+ * class MyComponent extends DatasourceEventHandler(FASTElement) {
16
+ * resourceName: string = 'some-resource';
17
+ * ...
18
+ * datasourceStatusChanged(prev: DatasourceStatus, next: DatasourceStatus) {
19
+ * // Respond to changes in the target datasource.
20
+ * }
21
+ * }
22
+ * ```
23
+ *
24
+ * @privateRemarks
25
+ * Unfortunately our datasource ui components do not share a common baseclass. Given datasource ui components contain a
26
+ * Datasource and currently await their `init`, usage is more for example at this point, ie. how could we allow interested
27
+ * parties to monitor and respond to changes, given they will exist at different levels of DOM hierarchy etc. Datasource
28
+ * itself is also transient DI injectable, so each interested party would not have access to the same instance, nor would
29
+ * we necessarily want to expose that via the event to prevent them operating on it to cause unwanted side effects.
30
+ *
31
+ * @param Target - The class to mix the event handler with.
32
+ *
33
+ * @public
34
+ */
35
+ export const DatasourceEventHandler = (Target) => {
36
+ // @ts-ignore
37
+ class Mixin extends Target {
38
+ constructor() {
39
+ super();
40
+ if (!this.hasOwnProperty('onDatasourceStatusChanged')) {
41
+ this.onDatasourceStatusChanged = (event) => {
42
+ var _a;
43
+ if (!this.resourceName) {
44
+ logger.warn(`Target classes must have a resourceName property to use the DatasourceEventHandler mixin.`);
45
+ }
46
+ const next = event.detail;
47
+ if (next.name === this.resourceName) {
48
+ const prev = (_a = this.datasourceStatus) !== null && _a !== void 0 ? _a : {
49
+ isInitialized: false,
50
+ hasMetadata: false,
51
+ };
52
+ const hasChanged = prev.isInitialized !== next.isInitialized ||
53
+ (next.metadataRequired && prev.hasMetadata !== next.hasMetadata);
54
+ if (hasChanged) {
55
+ this.datasourceStatus = next;
56
+ }
57
+ }
58
+ };
59
+ }
60
+ }
61
+ /**
62
+ * @remarks
63
+ * Override this method to respond to changes in the target datasource.
64
+ */
65
+ datasourceStatusChanged(prev, next) {
66
+ logger.debug('Target classes should override the datasourceStatusChanged method of the DatasourceEventHandler mixin to respond to changes in the target datasource.');
67
+ }
68
+ connectedCallback() {
69
+ super.connectedCallback();
70
+ document.addEventListener(DatasourceStatusChanged, this.onDatasourceStatusChanged, {
71
+ passive: true,
72
+ capture: true,
73
+ });
74
+ }
75
+ disconnectedCallback() {
76
+ super.disconnectedCallback();
77
+ document.removeEventListener(DatasourceStatusChanged, this.onDatasourceStatusChanged, {
78
+ capture: true,
79
+ });
80
+ }
81
+ }
82
+ __decorate([
83
+ observable
84
+ ], Mixin.prototype, "datasourceStatus", void 0);
85
+ return Mixin;
86
+ };
@@ -1,4 +1,3 @@
1
- import { DI } from '@microsoft/fast-foundation';
2
1
  /**
3
2
  * Types of Genesis resources.
4
3
  * @public
@@ -10,22 +9,7 @@ export var ResourceType;
10
9
  ResourceType["REQUEST_SERVER"] = "REQUEST_SERVER";
11
10
  })(ResourceType || (ResourceType = {}));
12
11
  /**
13
- * Default values for a DatasourceConfig
12
+ * DatasourceStatusChanged.
14
13
  * @public
15
14
  */
16
- export class DatasourceDefaults {
17
- }
18
- DatasourceDefaults.MAX_ROWS_250 = 250;
19
- DatasourceDefaults.MAX_VIEW_1000 = 1000;
20
- DatasourceDefaults.REQ_REP_POLLING_INTERVAL_MS = 10000;
21
- DatasourceDefaults.DATASERVER_ROW_ID = 'ROW_REF';
22
- DatasourceDefaults.REQUEST_SERVER_ROW_ID = 'RECORD_ID';
23
- /**
24
- * The DI token for the DatasourceConfig interface.
25
- *
26
- * @privateRemarks
27
- * Marked as internal to stop api-extractor becoming confused cross-linking tokens with the same name.
28
- *
29
- * @internal
30
- */
31
- export const DatasourceConfig = DI.createInterface();
15
+ export const DatasourceStatusChanged = 'datasource-status-changed';
@@ -42,6 +42,12 @@ export class DefaultEntityDatasource extends DefaultDatasource {
42
42
  this.entityCache = [];
43
43
  };
44
44
  }
45
+ get initialized() {
46
+ return this._initialized;
47
+ }
48
+ set initialized(value) {
49
+ this._initialized = value;
50
+ }
45
51
  /** {@inheritDoc EntityDatasource.cache} */
46
52
  get cache() {
47
53
  if (!this.initialized) {
@@ -1,5 +1,7 @@
1
1
  export * from './criteriaFiltersToFields';
2
2
  export * from './dataServerResultFilter';
3
+ export * from './datasource.config';
4
+ export * from './datasource.mixins';
3
5
  export * from './datasource';
4
6
  export * from './datasource.types';
5
7
  export * from './entityDatasource';
package/dist/esm/index.js CHANGED
@@ -5,6 +5,7 @@ export * from './credentialManager';
5
5
  export * from './datasource';
6
6
  export * from './metadata';
7
7
  export * from './networkMonitor';
8
+ export * from './resources';
8
9
  export * from './session';
9
10
  export * from './storage';
10
11
  export * from './testing';
@@ -0,0 +1,51 @@
1
+ import { registerTypedBroadcastChannel, } from '@genesislcap/foundation-broadcast-channel';
2
+ import { DI } from '@microsoft/fast-foundation';
3
+ import { GenesisResourcesChannelId } from './types';
4
+ /**
5
+ * Default GenesisResourcesConfig implementation.
6
+ * @public
7
+ */
8
+ export const defaultGenesisResourcesConfig = {
9
+ throwWhenUnavailable: true,
10
+ throwWhenUnknown: false,
11
+ };
12
+ /**
13
+ * GenesisResourcesConfig DI key.
14
+ * @internal
15
+ * @privateRemarks
16
+ * Marked as internal to stop api-extractor becoming confused cross-linking tokens with the same name.
17
+ */
18
+ export const GenesisResourcesConfig = DI.createInterface((x) => x.instance(defaultGenesisResourcesConfig));
19
+ /**
20
+ * GenesisResourcesChannel DI key.
21
+ * @internal
22
+ * @privateRemarks
23
+ * Marked as internal to stop api-extractor becoming confused cross-linking tokens with the same name.
24
+ */
25
+ export const GenesisResourcesChannel = registerTypedBroadcastChannel(GenesisResourcesChannelId);
26
+ /**
27
+ * Gets GenesisResourcesChannel from the DI container.
28
+ *
29
+ * @remarks
30
+ * A utility method for host applications that are not using decorators or the DI container.
31
+ *
32
+ * @example
33
+ * ```ts
34
+ * import { getGenesisResourcesChannel } from '@genesislcap/foundation-comms';
35
+ * ...
36
+ * const channel = getGenesisResourcesChannel();
37
+ * ...
38
+ * channel.onmessage = (e) => {
39
+ * if (channel.isMessageType('resources-loaded', e)) {
40
+ * logger.debug('resources-loaded', e.data.detail);
41
+ * return;
42
+ * }
43
+ * }
44
+ * ...
45
+ * channel.close();
46
+ * ```
47
+ * @public
48
+ */
49
+ export function getGenesisResourcesChannel() {
50
+ return DI.getOrCreateDOMContainer().get(GenesisResourcesChannel);
51
+ }
@@ -0,0 +1,114 @@
1
+ import { __awaiter, __decorate, __param } from "tslib";
2
+ import { DI } from '@microsoft/fast-foundation';
3
+ import { Connect } from '../../connect';
4
+ import { logger } from '../../utils';
5
+ import { GenesisResourcesConfig, getGenesisResourcesChannel } from './config';
6
+ /**
7
+ * Default GenesisResources implementation.
8
+ * @public
9
+ */
10
+ let DefaultGenesisResources = class DefaultGenesisResources {
11
+ constructor(connect, config) {
12
+ this.connect = connect;
13
+ this.config = config;
14
+ }
15
+ /** {@inheritDoc GenesisResources.isValidResource} */
16
+ isValidResource(resourceName) {
17
+ return __awaiter(this, void 0, void 0, function* () {
18
+ resourceName = resourceName === null || resourceName === void 0 ? void 0 : resourceName.trim();
19
+ if (!resourceName) {
20
+ return false;
21
+ }
22
+ yield this.getResources();
23
+ const resourceItem = this.resources.find((item) => item.RESOURCE_NAME === resourceName);
24
+ return !!resourceItem;
25
+ });
26
+ }
27
+ /** {@inheritDoc GenesisResources.getResourceTypeFor} */
28
+ getResourceTypeFor(resourceName) {
29
+ return __awaiter(this, void 0, void 0, function* () {
30
+ yield this.getResources();
31
+ const resourceItem = this.resources.find((item) => item.RESOURCE_NAME === resourceName);
32
+ if (resourceItem) {
33
+ return resourceItem.RESOURCE_TYPE;
34
+ }
35
+ const message = `${resourceName} resource does not exist.`;
36
+ logger.error(message);
37
+ if (this.config.throwWhenUnknown) {
38
+ throw new Error(message);
39
+ }
40
+ });
41
+ }
42
+ /** {@inheritDoc GenesisResources.destroy} */
43
+ destroy() {
44
+ this.resources = undefined;
45
+ this.resourcesPromise = undefined;
46
+ }
47
+ getResources() {
48
+ var _a;
49
+ return __awaiter(this, void 0, void 0, function* () {
50
+ if (!this.resourcesPromise) {
51
+ /**
52
+ * Await a resources request
53
+ */
54
+ this.resourcesPromise = this.connect.getAvailableResources();
55
+ const data = yield this.resourcesPromise;
56
+ this.resources = data === null || data === void 0 ? void 0 : data.RESOURCES;
57
+ if (!((_a = this.resources) === null || _a === void 0 ? void 0 : _a.length)) {
58
+ const message = `Genesis resources unavailable.`;
59
+ logger.error(message);
60
+ if (this.config.throwWhenUnavailable) {
61
+ throw new Error(message);
62
+ }
63
+ }
64
+ this.postLoadedMessage();
65
+ this.resourcesPromise = undefined;
66
+ }
67
+ else {
68
+ /**
69
+ * Await the in-progress resources request
70
+ */
71
+ yield this.resourcesPromise;
72
+ }
73
+ });
74
+ }
75
+ postLoadedMessage() {
76
+ /**
77
+ * Normally we'd inject channels into components and call their `channel.close()` api on `disconnectedCallback`.
78
+ * However, in shared long-lived service instances like this, channels may lead to tests failing to exit as they are
79
+ * not garbage collected by default. Creating and destroying the channel on on-demand poses less risk.
80
+ */
81
+ const channel = getGenesisResourcesChannel();
82
+ channel.postMessage('resources-loaded', this.resources);
83
+ channel.close();
84
+ }
85
+ };
86
+ DefaultGenesisResources = __decorate([
87
+ __param(0, Connect),
88
+ __param(1, GenesisResourcesConfig)
89
+ ], DefaultGenesisResources);
90
+ export { DefaultGenesisResources };
91
+ /**
92
+ * GenesisResources DI key.
93
+ * @internal
94
+ * @privateRemarks
95
+ * Marked as internal to stop api-extractor becoming confused cross-linking tokens with the same name.
96
+ */
97
+ export const GenesisResources = DI.createInterface((x) => x.singleton(DefaultGenesisResources));
98
+ /**
99
+ * Gets GenesisResources from the DI container.
100
+ *
101
+ * @remarks
102
+ * A utility method for host applications that are not using decorators or the DI container.
103
+ *
104
+ * @example
105
+ * ```ts
106
+ * import { getGenesisResources } from '@genesislcap/foundation-comms';
107
+ * ...
108
+ * const genesisResources = getGenesisResources();
109
+ * ```
110
+ * @public
111
+ */
112
+ export function getGenesisResources() {
113
+ return DI.getOrCreateDOMContainer().get(GenesisResources);
114
+ }
@@ -0,0 +1,3 @@
1
+ export * from './config';
2
+ export * from './genesis';
3
+ export * from './types';
@@ -0,0 +1,4 @@
1
+ /**
2
+ * @public
3
+ */
4
+ export const GenesisResourcesChannelId = 'genesis-resources';
@@ -0,0 +1 @@
1
+ export * from './genesis';
@@ -1,4 +1,5 @@
1
1
  import { __awaiter, __decorate } from "tslib";
2
+ import { DefaultUser } from '@genesislcap/foundation-user';
2
3
  import { observable } from '@microsoft/fast-element';
3
4
  /**
4
5
  * @internal
@@ -25,6 +26,15 @@ export class AuthMock {
25
26
  return Promise.resolve(this.nextReAuthResult);
26
27
  });
27
28
  }
29
+ setTestUser(properties = {}) {
30
+ this.currentUser = new DefaultUser();
31
+ this.currentUser.set(Object.assign({ userName: 'JaneDee', profile: ['USER'], permission: ['CreateRules'] }, properties));
32
+ this.isLoggedIn = true;
33
+ }
34
+ resetTestUser() {
35
+ this.currentUser = null;
36
+ this.isLoggedIn = false;
37
+ }
28
38
  }
29
39
  __decorate([
30
40
  observable
@@ -1,3 +1,4 @@
1
+ import { __awaiter } from "tslib";
1
2
  import { from } from 'rxjs';
2
3
  /**
3
4
  * @internal
@@ -7,6 +8,9 @@ export class ConnectMock {
7
8
  this.isConnected = true;
8
9
  this.isWorking = false;
9
10
  }
11
+ get host() {
12
+ return this.socket.host;
13
+ }
10
14
  get isConnectedSubject() {
11
15
  return this.socket.isConnectedSubject;
12
16
  }
@@ -27,6 +31,7 @@ export class ConnectMock {
27
31
  return Promise.resolve(this.nextMessage);
28
32
  }
29
33
  connect(host) {
34
+ this.socket.host = host;
30
35
  return Promise.resolve(this.isConnected);
31
36
  }
32
37
  disconnect() { }
@@ -38,8 +43,10 @@ export class ConnectMock {
38
43
  return Promise.resolve(this.nextMessage);
39
44
  }
40
45
  getAvailableResources(params) {
41
- this.requestParams = params;
42
- return Promise.resolve(this.nextMessage);
46
+ return __awaiter(this, void 0, void 0, function* () {
47
+ this.requestParams = params;
48
+ return Promise.resolve(this.nextMessage);
49
+ });
43
50
  }
44
51
  snapshot(resourceName, params) {
45
52
  return Promise.resolve(this.nextMessage);
@@ -6,9 +6,11 @@ import { SocketSubject } from '../../../connect/socket';
6
6
  export class SocketMock {
7
7
  constructor() {
8
8
  this.isConnectedSubject = new BehaviorSubject(true);
9
+ this.host = 'mock-host';
9
10
  this.socketMessagesSubject = new SocketSubject();
10
11
  }
11
12
  connect(host, options, reconnectOptions) {
13
+ this.host = host;
12
14
  return Promise.resolve(true);
13
15
  }
14
16
  disconnect() { }