@genesislcap/foundation-comms 14.187.1 → 14.188.0-FUI-2012-tabulator.1

Sign up to get free protection for your applications and to get access to all the features.
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() { }