@equinor/fusion-framework-module-analytics 0.1.1

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 (102) hide show
  1. package/CHANGELOG.md +21 -0
  2. package/LICENSE +21 -0
  3. package/README.md +248 -0
  4. package/dist/esm/AnalyticsConfigurator.interface.js +2 -0
  5. package/dist/esm/AnalyticsConfigurator.interface.js.map +1 -0
  6. package/dist/esm/AnalyticsConfigurator.js +61 -0
  7. package/dist/esm/AnalyticsConfigurator.js.map +1 -0
  8. package/dist/esm/AnalyticsProvider.interface.js +2 -0
  9. package/dist/esm/AnalyticsProvider.interface.js.map +1 -0
  10. package/dist/esm/AnalyticsProvider.js +92 -0
  11. package/dist/esm/AnalyticsProvider.js.map +1 -0
  12. package/dist/esm/adapters/AnalyticsAdapter.interface.js +2 -0
  13. package/dist/esm/adapters/AnalyticsAdapter.interface.js.map +1 -0
  14. package/dist/esm/adapters/ConsoleAnalyticsAdapter.js +12 -0
  15. package/dist/esm/adapters/ConsoleAnalyticsAdapter.js.map +1 -0
  16. package/dist/esm/adapters/FusionAnalyticsAdapter.js +42 -0
  17. package/dist/esm/adapters/FusionAnalyticsAdapter.js.map +1 -0
  18. package/dist/esm/adapters/index.js +3 -0
  19. package/dist/esm/adapters/index.js.map +1 -0
  20. package/dist/esm/collectors/AnalyticsCollector.interface.js +2 -0
  21. package/dist/esm/collectors/AnalyticsCollector.interface.js.map +1 -0
  22. package/dist/esm/collectors/AppLoadedCollector.js +42 -0
  23. package/dist/esm/collectors/AppLoadedCollector.js.map +1 -0
  24. package/dist/esm/collectors/AppSelectedCollector.js +32 -0
  25. package/dist/esm/collectors/AppSelectedCollector.js.map +1 -0
  26. package/dist/esm/collectors/BaseCollector.js +40 -0
  27. package/dist/esm/collectors/BaseCollector.js.map +1 -0
  28. package/dist/esm/collectors/ContextSelectedCollector.js +36 -0
  29. package/dist/esm/collectors/ContextSelectedCollector.js.map +1 -0
  30. package/dist/esm/collectors/index.js +4 -0
  31. package/dist/esm/collectors/index.js.map +1 -0
  32. package/dist/esm/collectors/utils/extractAppMetadata.js +37 -0
  33. package/dist/esm/collectors/utils/extractAppMetadata.js.map +1 -0
  34. package/dist/esm/collectors/utils/extractContextMetadata.js +23 -0
  35. package/dist/esm/collectors/utils/extractContextMetadata.js.map +1 -0
  36. package/dist/esm/enable-analytics.js +20 -0
  37. package/dist/esm/enable-analytics.js.map +1 -0
  38. package/dist/esm/index.js +5 -0
  39. package/dist/esm/index.js.map +1 -0
  40. package/dist/esm/logExporters/fusionOTLPLogExporter/FusionOTLPLogExporter.js +22 -0
  41. package/dist/esm/logExporters/fusionOTLPLogExporter/FusionOTLPLogExporter.js.map +1 -0
  42. package/dist/esm/logExporters/fusionOTLPLogExporter/HttpClientExporterTransport.js +84 -0
  43. package/dist/esm/logExporters/fusionOTLPLogExporter/HttpClientExporterTransport.js.map +1 -0
  44. package/dist/esm/logExporters/index.js +3 -0
  45. package/dist/esm/logExporters/index.js.map +1 -0
  46. package/dist/esm/module.js +28 -0
  47. package/dist/esm/module.js.map +1 -0
  48. package/dist/esm/types.js +2 -0
  49. package/dist/esm/types.js.map +1 -0
  50. package/dist/esm/version.js +3 -0
  51. package/dist/esm/version.js.map +1 -0
  52. package/dist/tsconfig.tsbuildinfo +1 -0
  53. package/dist/types/AnalyticsConfigurator.d.ts +39 -0
  54. package/dist/types/AnalyticsConfigurator.interface.d.ts +39 -0
  55. package/dist/types/AnalyticsProvider.d.ts +45 -0
  56. package/dist/types/AnalyticsProvider.interface.d.ts +20 -0
  57. package/dist/types/adapters/AnalyticsAdapter.interface.d.ts +21 -0
  58. package/dist/types/adapters/ConsoleAnalyticsAdapter.d.ts +9 -0
  59. package/dist/types/adapters/FusionAnalyticsAdapter.d.ts +19 -0
  60. package/dist/types/adapters/index.d.ts +3 -0
  61. package/dist/types/collectors/AnalyticsCollector.interface.d.ts +16 -0
  62. package/dist/types/collectors/AppLoadedCollector.d.ts +23 -0
  63. package/dist/types/collectors/AppSelectedCollector.d.ts +21 -0
  64. package/dist/types/collectors/BaseCollector.d.ts +27 -0
  65. package/dist/types/collectors/ContextSelectedCollector.d.ts +21 -0
  66. package/dist/types/collectors/index.d.ts +4 -0
  67. package/dist/types/collectors/utils/extractAppMetadata.d.ts +17 -0
  68. package/dist/types/collectors/utils/extractContextMetadata.d.ts +11 -0
  69. package/dist/types/enable-analytics.d.ts +11 -0
  70. package/dist/types/index.d.ts +7 -0
  71. package/dist/types/logExporters/fusionOTLPLogExporter/FusionOTLPLogExporter.d.ts +11 -0
  72. package/dist/types/logExporters/fusionOTLPLogExporter/HttpClientExporterTransport.d.ts +12 -0
  73. package/dist/types/logExporters/index.d.ts +2 -0
  74. package/dist/types/module.d.ts +44 -0
  75. package/dist/types/types.d.ts +22 -0
  76. package/dist/types/version.d.ts +1 -0
  77. package/package.json +72 -0
  78. package/src/AnalyticsConfigurator.interface.ts +48 -0
  79. package/src/AnalyticsConfigurator.ts +116 -0
  80. package/src/AnalyticsProvider.interface.ts +22 -0
  81. package/src/AnalyticsProvider.ts +118 -0
  82. package/src/adapters/AnalyticsAdapter.interface.ts +23 -0
  83. package/src/adapters/ConsoleAnalyticsAdapter.ts +17 -0
  84. package/src/adapters/FusionAnalyticsAdapter.ts +61 -0
  85. package/src/adapters/index.ts +3 -0
  86. package/src/collectors/AnalyticsCollector.interface.ts +18 -0
  87. package/src/collectors/AppLoadedCollector.ts +74 -0
  88. package/src/collectors/AppSelectedCollector.ts +53 -0
  89. package/src/collectors/BaseCollector.ts +65 -0
  90. package/src/collectors/ContextSelectedCollector.ts +56 -0
  91. package/src/collectors/index.ts +4 -0
  92. package/src/collectors/utils/extractAppMetadata.ts +45 -0
  93. package/src/collectors/utils/extractContextMetadata.ts +27 -0
  94. package/src/enable-analytics.ts +27 -0
  95. package/src/index.ts +11 -0
  96. package/src/logExporters/fusionOTLPLogExporter/FusionOTLPLogExporter.ts +41 -0
  97. package/src/logExporters/fusionOTLPLogExporter/HttpClientExporterTransport.ts +89 -0
  98. package/src/logExporters/index.ts +2 -0
  99. package/src/module.ts +59 -0
  100. package/src/types.ts +29 -0
  101. package/src/version.ts +2 -0
  102. package/tsconfig.json +29 -0
package/CHANGELOG.md ADDED
@@ -0,0 +1,21 @@
1
+ # @equinor/fusion-framework-module-analytics
2
+
3
+ ## 0.1.1
4
+
5
+ ### Patch Changes
6
+
7
+ - [#3845](https://github.com/equinor/fusion-framework/pull/3845) [`5114ac4`](https://github.com/equinor/fusion-framework/commit/5114ac4f71a60935d0194b9b2766f95adff0ba1e) Thanks [@asbjornhaland](https://github.com/asbjornhaland)! - Fix tsconfig references
8
+
9
+ - Updated dependencies [[`5114ac4`](https://github.com/equinor/fusion-framework/commit/5114ac4f71a60935d0194b9b2766f95adff0ba1e)]:
10
+ - @equinor/fusion-framework-module-app@7.2.1
11
+
12
+ ## 0.1.0
13
+
14
+ ### Minor Changes
15
+
16
+ - [#3842](https://github.com/equinor/fusion-framework/pull/3842) [`d38cd60`](https://github.com/equinor/fusion-framework/commit/d38cd60472380d60282c2a5672dc6e3bba3e7ca9) Thanks [@asbjornhaland](https://github.com/asbjornhaland)! - Add module fusion-framework-module-analytics
17
+
18
+ ### Patch Changes
19
+
20
+ - Updated dependencies [[`d38cd60`](https://github.com/equinor/fusion-framework/commit/d38cd60472380d60282c2a5672dc6e3bba3e7ca9)]:
21
+ - @equinor/fusion-framework-module-app@7.2.0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2022 Equinor
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,248 @@
1
+ # Analytics Module
2
+
3
+ The Fusion Framework Analytics Module provides an unified way to track analytics.
4
+ It offers a consistent API for logging analytics data while supporting multiple
5
+ adapters and collectors.
6
+
7
+ When a collector emits a event, it will be sent to all adapters.
8
+
9
+ ## Configuration
10
+
11
+ To configure the analytics module, you need to provide a function that specifies
12
+ the adapters and collectors you want to use. The configuration can be done in
13
+ your portal entry file or wherever you initialize the Fusion Framework.
14
+
15
+ ```typescript
16
+ import { enableAnalytics } from '@equinor/fusion-framework-module-analytics';
17
+
18
+ const configure = (configurator: IModulesConfigurator<any, any>) => {
19
+ enableAnalytics(configurator, (builder) => {
20
+ // configure the analytics module
21
+
22
+ builder.setAdapter('console', async () => {
23
+ return new ConsoleAnalyticsAdapter();
24
+ });
25
+
26
+ builder.setCollector('context-selected', async (args) => {
27
+ const contextProvider = await args.requireInstance('context');
28
+ return new ContextSelectedCollector(contextProvider);
29
+ });
30
+ });
31
+ }
32
+ ```
33
+
34
+ ## Initialization
35
+
36
+ The analytics module supports asynchronous initialization of adapters and
37
+ collectors. The provider exposes an `initialize()` method that should be called
38
+ to set up all configured adapters and collectors:
39
+
40
+ ```typescript
41
+ // Get the analytics provider from modules
42
+ const provider = modules.analytics;
43
+
44
+ // Initialize adapters and collectors (required before use)
45
+ await provider.initialize();
46
+
47
+ // Check if provider is initialized
48
+ if (provider.initialized) {
49
+ // Provider is ready for use
50
+ }
51
+ ```
52
+
53
+ > [!NOTE]
54
+ > The analytics module will automatically initialize when used within the
55
+ > Fusion Framework module system. Manual initialization is only required when
56
+ > accessing the provider directly.
57
+
58
+ ## Adapters
59
+
60
+ Adapters are responsible for processing and sending telemetry data to their
61
+ respective destinations. All adapters support asynchronous initialization and
62
+ will automatically be initialized when the analytics provider initializes.
63
+
64
+ ### Using `setAdapter`
65
+
66
+ The `AnalyticsConfigurator` provides a method for adding adapters: `setAdapter`
67
+ for pre-instantiated adapters.
68
+
69
+ #### Simple `setAdapter` Example
70
+
71
+ ```typescript
72
+ import { enableAnalytics } from '@equinor/fusion-framework-module-analytics';
73
+ import { ConsoleAnalyticsAdapter } from '@equinor/fusion-framework-module-analytics/adapters';
74
+
75
+ const configure = (configurator: IModulesConfigurator<any, any>) => {
76
+ enableAnalytics(configurator, (builder) => {
77
+ builder.setAdapter('console', async () => {
78
+ return new ConsoleAnalyticsAdapter();
79
+ });
80
+ });
81
+ }
82
+ ```
83
+
84
+ ### Console Adapter
85
+
86
+ The `ConsoleAnalyticsAdapter` provides a simple way to log analytics data to the
87
+ console, useful for development and debugging.
88
+
89
+ #### Installation
90
+
91
+ The Console Adapter is included with the analytics module and doesn't require
92
+ additional installation.
93
+
94
+ #### Configuration
95
+
96
+ The Console Adapter does not require any configuration.
97
+
98
+ ### Fusion Analytics Adapter
99
+
100
+ The `FusionAnalyticsAdapter` provides a way to log analytics data to a service
101
+ using the OpenTelemetry Logs pattern.
102
+
103
+ #### Installation
104
+
105
+ The Fusion Analytics Adapter is included with the analytics module and doesn't
106
+ require additional installation.
107
+
108
+ #### Configuration
109
+
110
+ The Fusion Analytics Adapter support the following configuration options:
111
+
112
+ - `portalId`: The portal Id to be included in log records.
113
+
114
+ - `logExporter`: The exporter to use. We bundle `OTLPLogExporter` and `FusionOTLPLogExporter` - see below.
115
+
116
+ ##### Example configuration
117
+
118
+ ```typescript
119
+ // OTLPLogExporter
120
+ import { OTLPLogExporter } from '@equinor/fusion-framework-module-analytics/logExporters';
121
+
122
+ builder.setAdapter('fusion-log', async () => {
123
+ const logExporter = new OTLPLogExporter({
124
+ url: 'URL_TO_POST_TO',
125
+ headers: {
126
+ 'Content-Type': 'application/json',
127
+ },
128
+ });
129
+
130
+ return new FusionAnalyticsAdapter({
131
+ portalId: 'PORTAL_ID',
132
+ logExporter,
133
+ });
134
+ });
135
+
136
+ // FusionOTLPLogExporter with httpClient
137
+ import { FusionOTLPLogExporter } from '@equinor/fusion-framework-module-analytics/logExporters';
138
+
139
+ builder.setAdapter('fusion', async (args) => {
140
+ if (args.hasModule('serviceDiscovery')) {
141
+ const serviceDiscovery = await args.requireInstance<ServiceDiscoveryProvider>(
142
+ 'serviceDiscovery'
143
+ );
144
+ const httpClient = await serviceDiscovery.createClient('SERVICE_DISCOVERY_NAME');
145
+
146
+ const logExporter = new FusionOTLPLogExporter(httpClient);
147
+
148
+ return new FusionAnalyticsAdapter({
149
+ portalId: 'PORTAL_ID',
150
+ logExporter,
151
+ });
152
+ }
153
+ console.error('Could not instanziate monitor http client from service-discovery');
154
+ });
155
+ ```
156
+
157
+ ### Creating Custom Adapters
158
+
159
+ You can create custom analytics adapters by implementing the `IAnalyticsAdapter`
160
+ interface and add it in configuration.
161
+
162
+ ## Collectors
163
+
164
+ Collectors are responsible for sending events that adapters can pick up. All
165
+ collectors support asynchronous initialization and will automatically be
166
+ initialized when the analytics provider initializes.
167
+
168
+ ### Using `setCollector`
169
+
170
+ The `AnalyticsConfigurator` provides a method for adding collectors:
171
+ `setCollector` for pre-instantiated collectors.
172
+
173
+ ### Simple `setCollector` Example
174
+
175
+ ```typescript
176
+ import { enableAnalytics } from '@equinor/fusion-framework-module-analytics';
177
+ import { ContextSelectedCollector } from '@equinor/fusion-framework-module-analytics/collectors';
178
+
179
+ const configure = (configurator: IModulesConfigurator<any, any>) => {
180
+ enableAnalytics(configurator, (builder) => {
181
+ builder.setCollector('context-selected', async (args) => {
182
+ const contextProvider = await args.requireInstance('context');
183
+ return new ContextSelectedCollector(contextProvider);
184
+ });
185
+ });
186
+ }
187
+ ```
188
+
189
+ ### Context Selected Collector
190
+
191
+ The `ContextSelectedCollector` listens for selection in the context module and emits
192
+ the new and optional previous context.
193
+
194
+ #### Installation
195
+
196
+ The Context Selected Collector is included with the analytics module and doesn't
197
+ require additional installation.
198
+
199
+ #### Configuration
200
+
201
+ The Context Selected Collector needs the context provider.
202
+
203
+ ##### Example configuration
204
+
205
+ ```typescript
206
+ import { enableAnalytics } from '@equinor/fusion-framework-module-analytics';
207
+ import { ContextSelectedCollector } from '@equinor/fusion-framework-module-analytics/collectors';
208
+
209
+ const configure = (configurator: IModulesConfigurator<any, any>) => {
210
+ enableAnalytics(configurator, (builder) => {
211
+ builder.setCollector('context-selected', async (args) => {
212
+ const contextProvider = await args.requireInstance('context');
213
+ return new ContextSelectedCollector(contextProvider);
214
+ });
215
+ });
216
+ }
217
+ ```
218
+
219
+ ### Creating Custom Collectors
220
+
221
+ You can create custom analytics collector by extending the `BaseCollector` class,
222
+ or implement the `IAnalyticsCollector` interface and add it in configuration.
223
+
224
+ #### Example Custom Collector
225
+
226
+ ```typescript
227
+ import { type AnalyticsEvent, enableAnalytics } from '@equinor/fusion-framework-module-analytics';
228
+
229
+ const configure = (configurator: IModulesConfigurator<any, any>) => {
230
+ enableAnalytics(configurator, (builder) => {
231
+ builder.setCollector('click-test', async () => {
232
+ const subject = new Subject<AnalyticsEvent>();
233
+ window.addEventListener('click', (e) => {
234
+ subject.next({
235
+ name: 'window-clicker',
236
+ value: 42,
237
+ });
238
+ });
239
+
240
+ return {
241
+ subscribe: (subscriber) => {
242
+ return subject.subscribe(subscriber);
243
+ },
244
+ };
245
+ });
246
+ });
247
+ }
248
+ ```
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=AnalyticsConfigurator.interface.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AnalyticsConfigurator.interface.js","sourceRoot":"","sources":["../../src/AnalyticsConfigurator.interface.ts"],"names":[],"mappings":""}
@@ -0,0 +1,61 @@
1
+ import { BaseConfigBuilder, } from '@equinor/fusion-framework-module';
2
+ import { from } from 'rxjs';
3
+ import { map, scan, filter, defaultIfEmpty, shareReplay, mergeMap } from 'rxjs/operators';
4
+ /**
5
+ * Configures analytics settings for the module.
6
+ *
7
+ * The `AnalyticsConfigurator` class extends `BaseConfigBuilder` to provide a fluent API for
8
+ * setting up analytics adapters and collectors.
9
+ *
10
+ * @remarks
11
+ * - Adapters are managed internally and can be set using `setAdapter`.
12
+ * - Collectors are managed internally and can be set using `setCollector`.
13
+ * - All setter methods return `this` for method chaining.
14
+ *
15
+ * @see BaseConfigBuilder
16
+ * @see IAnalyticsConfigurator
17
+ */
18
+ export class AnalyticsConfigurator extends BaseConfigBuilder {
19
+ #collectorCallbacks = {};
20
+ #adapterCallbacks = {};
21
+ constructor() {
22
+ super();
23
+ // Configure async collectors resolution using mergeMap to handle Promise/Observable collector factories
24
+ this._set('collectors', (args) => {
25
+ return from(Object.entries(this.#collectorCallbacks)).pipe(mergeMap(([identifier, collectorFn]) => from(collectorFn(args)).pipe(filter((collector) => !!collector), map((collector) => [identifier, collector]))), scan((acc, [identifier, collector]) => {
26
+ acc[identifier] = collector;
27
+ return acc;
28
+ }, {}), defaultIfEmpty({}), shareReplay({ bufferSize: 1, refCount: true }));
29
+ });
30
+ // Configure async adapters resolution using mergeMap to handle Promise/Observable adapter factories
31
+ this._set('adapters', (args) => {
32
+ return from(Object.entries(this.#adapterCallbacks)).pipe(mergeMap(([identifier, adapterFn]) => from(adapterFn(args)).pipe(filter((adapter) => !!adapter), map((adapter) => [identifier, adapter]))), scan((acc, [identifier, adapter]) => {
33
+ acc[identifier] = adapter;
34
+ return acc;
35
+ }, {}), defaultIfEmpty({}), shareReplay({ bufferSize: 1, refCount: true }));
36
+ });
37
+ }
38
+ /**
39
+ * Registers a analytics collector with the configurator.
40
+ *
41
+ * @param identifier - The name of the collector
42
+ * @param callback - A callback function that returns an analytics collector instance
43
+ * @returns The current instance for method chaining
44
+ */
45
+ setCollector(identifier, callback) {
46
+ this.#collectorCallbacks[identifier] = callback;
47
+ return this;
48
+ }
49
+ /**
50
+ * Registers a analytics adapter with the configurator.
51
+ *
52
+ * @param identifier - The name of the adapter
53
+ * @param callback - A callback function that returns an analytics adapter instance
54
+ * @returns The current instance for method chaining
55
+ */
56
+ setAdapter(identifier, callback) {
57
+ this.#adapterCallbacks[identifier] = callback;
58
+ return this;
59
+ }
60
+ }
61
+ //# sourceMappingURL=AnalyticsConfigurator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AnalyticsConfigurator.js","sourceRoot":"","sources":["../../src/AnalyticsConfigurator.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,iBAAiB,GAGlB,MAAM,kCAAkC,CAAC;AAK1C,OAAO,EAAE,IAAI,EAAwB,MAAM,MAAM,CAAC;AAElD,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,EAAE,cAAc,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAE1F;;;;;;;;;;;;;GAaG;AACH,MAAM,OAAO,qBACX,SAAQ,iBAAkC;IAG1C,mBAAmB,GAA+D,EAAE,CAAC;IACrF,iBAAiB,GAA6D,EAAE,CAAC;IAEjF;QACE,KAAK,EAAE,CAAC;QAER,wGAAwG;QACxG,IAAI,CAAC,IAAI,CACP,YAAY,EACZ,CAAC,IAA+B,EAAwD,EAAE;YACxF,OAAO,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC,CAAC,IAAI,CACxD,QAAQ,CAAC,CAAC,CAAC,UAAU,EAAE,WAAW,CAAC,EAAE,EAAE,CACrC,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAC1B,MAAM,CAAC,CAAC,SAAS,EAAoC,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,EACpE,GAAG,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC,UAAU,EAAE,SAAS,CAAU,CAAC,CACrD,CACF,EACD,IAAI,CACF,CAAC,GAAG,EAAE,CAAC,UAAU,EAAE,SAAS,CAAC,EAAE,EAAE;gBAC/B,GAAG,CAAC,UAAU,CAAC,GAAG,SAAS,CAAC;gBAC5B,OAAO,GAAG,CAAC;YACb,CAAC,EACD,EAAyC,CAC1C,EACD,cAAc,CAAC,EAAE,CAAC,EAClB,WAAW,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAC/C,CAAC;QACJ,CAAC,CACF,CAAC;QAEF,oGAAoG;QACpG,IAAI,CAAC,IAAI,CACP,UAAU,EACV,CAAC,IAA+B,EAAsD,EAAE;YACtF,OAAO,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC,CAAC,IAAI,CACtD,QAAQ,CAAC,CAAC,CAAC,UAAU,EAAE,SAAS,CAAC,EAAE,EAAE,CACnC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CACxB,MAAM,CAAC,CAAC,OAAO,EAAgC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,EAC5D,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,UAAU,EAAE,OAAO,CAAU,CAAC,CACjD,CACF,EACD,IAAI,CACF,CAAC,GAAG,EAAE,CAAC,UAAU,EAAE,OAAO,CAAC,EAAE,EAAE;gBAC7B,GAAG,CAAC,UAAU,CAAC,GAAG,OAAO,CAAC;gBAC1B,OAAO,GAAG,CAAC;YACb,CAAC,EACD,EAAuC,CACxC,EACD,cAAc,CAAC,EAAE,CAAC,EAClB,WAAW,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAC/C,CAAC;QACJ,CAAC,CACF,CAAC;IACJ,CAAC;IAED;;;;;;OAMG;IACH,YAAY,CACV,UAAkB,EAClB,QAAuD;QAEvD,IAAI,CAAC,mBAAmB,CAAC,UAAU,CAAC,GAAG,QAAQ,CAAC;QAChD,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;;;;;OAMG;IACH,UAAU,CACR,UAAkB,EAClB,QAAqD;QAErD,IAAI,CAAC,iBAAiB,CAAC,UAAU,CAAC,GAAG,QAAQ,CAAC;QAC9C,OAAO,IAAI,CAAC;IACd,CAAC;CACF"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=AnalyticsProvider.interface.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AnalyticsProvider.interface.js","sourceRoot":"","sources":["../../src/AnalyticsProvider.interface.ts"],"names":[],"mappings":""}
@@ -0,0 +1,92 @@
1
+ import { BaseModuleProvider } from '@equinor/fusion-framework-module/provider';
2
+ import { version } from './version.js';
3
+ import { from, Subject, Subscription } from 'rxjs';
4
+ class DisposableSubscription extends Subscription {
5
+ constructor(subscription) {
6
+ super(subscription.unsubscribe);
7
+ }
8
+ [Symbol.dispose] = () => {
9
+ this.unsubscribe();
10
+ };
11
+ }
12
+ /**
13
+ * Provides analytics tracking, adapters integration and collectors for application instrumentation.
14
+ *
15
+ * The `AnalyticsProvider` class is responsible for collecting, processing and relaying analytics
16
+ * data to the adapters. The events are collected with collectors.
17
+ *
18
+ * @typeParam AnalyticsConfig - The configuration type for analytics.
19
+ * @implements IAnalyticsProvider
20
+ * @extends BaseModuleProvider<AnalyticsConfig>
21
+ */
22
+ export class AnalyticsProvider extends BaseModuleProvider {
23
+ #analytics;
24
+ #collectors;
25
+ #adapters;
26
+ constructor(config) {
27
+ super({ version, config });
28
+ this.#analytics = new Subject();
29
+ this.#collectors = config.collectors;
30
+ this.#adapters = config.adapters;
31
+ }
32
+ /**
33
+ * Initializes the analytics provider with adapters and collectors.
34
+ *
35
+ * This method sets up the provider for operation by:
36
+ * 1. Storing the provided adapters
37
+ * 2. Initializing all adapters
38
+ * 3. Storing the provided collectors
39
+ * 4. Initializing all collectors
40
+ * 5. Setting up subscription for analytics processing
41
+ *
42
+ * @returns A promise that resolves when initialization is complete
43
+ */
44
+ async initialize() {
45
+ const initializedCollectors = Object.values(this.#collectors).map((collector) => Promise.resolve(collector.initialize?.()));
46
+ const initializedAdapters = Object.values(this.#adapters).map((adapters) => Promise.resolve(adapters.initialize?.()));
47
+ await Promise.allSettled(initializedCollectors);
48
+ await Promise.allSettled(initializedAdapters);
49
+ for (const collector of Object.values(this.#collectors)) {
50
+ const subscription = collector.subscribe({
51
+ next: (event) => {
52
+ this.#analytics.next(event);
53
+ },
54
+ });
55
+ this._addTeardown(subscription);
56
+ }
57
+ const adapterSubscription = this.#analytics.subscribe({
58
+ next: (event) => {
59
+ for (const adapter of Object.values(this.#adapters)) {
60
+ adapter.registerAnalytic(event);
61
+ }
62
+ },
63
+ });
64
+ this._addTeardown(adapterSubscription);
65
+ }
66
+ /**
67
+ * Tracks an analytics event
68
+ *
69
+ * @param event - The analytics event to track
70
+ */
71
+ trackAnalytic(event) {
72
+ // @TODO: Validate AnalyticsEvent includes name, value and attributes
73
+ this.#analytics.next(event);
74
+ }
75
+ /**
76
+ * Uses a analytics stream and returns both Disposable and Subscription for cleanup.
77
+ *
78
+ * @param analytic$ - Observable input stream of analytic events.
79
+ * @returns Object containing both Disposable and Subscription for proper cleanup.
80
+ */
81
+ trackAnalytic$(analytic$) {
82
+ const subscription = from(analytic$)
83
+ // @TODO: Validate AnalyticsEvent includes name, value and attributes
84
+ .subscribe({
85
+ next: (event) => {
86
+ this.#analytics.next(event);
87
+ },
88
+ });
89
+ return new DisposableSubscription(subscription);
90
+ }
91
+ }
92
+ //# sourceMappingURL=AnalyticsProvider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AnalyticsProvider.js","sourceRoot":"","sources":["../../src/AnalyticsProvider.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=AnalyticsAdapter.interface.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AnalyticsAdapter.interface.js","sourceRoot":"","sources":["../../../src/adapters/AnalyticsAdapter.interface.ts"],"names":[],"mappings":""}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * An analytics adapter printing the events to the console.
3
+ */
4
+ export class ConsoleAnalyticsAdapter {
5
+ registerAnalytic(event) {
6
+ console.log('Analytics::Adapter::Console', event);
7
+ }
8
+ [Symbol.dispose]() {
9
+ // no-op
10
+ }
11
+ }
12
+ //# sourceMappingURL=ConsoleAnalyticsAdapter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ConsoleAnalyticsAdapter.js","sourceRoot":"","sources":["../../../src/adapters/ConsoleAnalyticsAdapter.ts"],"names":[],"mappings":"AAGA;;GAEG;AACH,MAAM,OAAO,uBAAuB;IAGlC,gBAAgB,CAAC,KAAQ;QACvB,OAAO,CAAC,GAAG,CAAC,6BAA6B,EAAE,KAAK,CAAC,CAAC;IACpD,CAAC;IAED,CAAC,MAAM,CAAC,OAAO,CAAC;QACd,QAAQ;IACV,CAAC;CACF"}
@@ -0,0 +1,42 @@
1
+ import { LoggerProvider, SimpleLogRecordProcessor, } from '@opentelemetry/sdk-logs';
2
+ import { SeverityNumber, } from '@opentelemetry/api-logs';
3
+ import { resourceFromAttributes } from '@opentelemetry/resources';
4
+ import { version } from '../version.js';
5
+ import { v7 as uuid } from 'uuid';
6
+ /**
7
+ * An analytics adapter for sending events to the log exporter for handling.
8
+ *
9
+ * The exporter is a Open Telemetry exporter.
10
+ * @see OTLPExporterBase
11
+ */
12
+ export class FusionAnalyticsAdapter {
13
+ #logExporter;
14
+ #loggerProvider;
15
+ #logger;
16
+ constructor(args) {
17
+ this.#logExporter = args.logExporter;
18
+ this.#loggerProvider = new LoggerProvider({
19
+ processors: [new SimpleLogRecordProcessor(this.#logExporter)],
20
+ resource: resourceFromAttributes({
21
+ 'module.version': version,
22
+ 'session.id': uuid(),
23
+ 'portal.id': args.portalId,
24
+ }),
25
+ });
26
+ this.#logger = this.#loggerProvider.getLogger('fusion');
27
+ }
28
+ registerAnalytic(event) {
29
+ const logRecord = {
30
+ eventName: event.name,
31
+ attributes: event.attributes,
32
+ body: event.value,
33
+ severityNumber: SeverityNumber.INFO,
34
+ };
35
+ this.#logger.emit(logRecord);
36
+ }
37
+ [Symbol.dispose]() {
38
+ this.#logExporter.shutdown();
39
+ this.#loggerProvider.shutdown();
40
+ }
41
+ }
42
+ //# sourceMappingURL=FusionAnalyticsAdapter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FusionAnalyticsAdapter.js","sourceRoot":"","sources":["../../../src/adapters/FusionAnalyticsAdapter.ts"],"names":[],"mappings":"AAGA,OAAO,EACL,cAAc,EACd,wBAAwB,GAEzB,MAAM,yBAAyB,CAAC;AAEjC,OAAO,EACL,cAAc,GAIf,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;AAClE,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AACxC,OAAO,EAAE,EAAE,IAAI,IAAI,EAAE,MAAM,MAAM,CAAC;AAElC;;;;;GAKG;AACH,MAAM,OAAO,sBAAsB;IAGjC,YAAY,CAAwC;IACpD,eAAe,CAAiB;IAChC,OAAO,CAAS;IAEhB,YAAY,IAA8E;QACxF,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,WAAW,CAAC;QAErC,IAAI,CAAC,eAAe,GAAG,IAAI,cAAc,CAAC;YACxC,UAAU,EAAE,CAAC,IAAI,wBAAwB,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;YAC7D,QAAQ,EAAE,sBAAsB,CAAC;gBAC/B,gBAAgB,EAAE,OAAO;gBACzB,YAAY,EAAE,IAAI,EAAE;gBACpB,WAAW,EAAE,IAAI,CAAC,QAAQ;aAC3B,CAAC;SACH,CAAC,CAAC;QACH,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,eAAe,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;IAC1D,CAAC;IAED,gBAAgB,CAAC,KAAQ;QACvB,MAAM,SAAS,GAAuB;YACpC,SAAS,EAAE,KAAK,CAAC,IAAI;YACrB,UAAU,EAAE,KAAK,CAAC,UAA2B;YAC7C,IAAI,EAAE,KAAK,CAAC,KAAK;YACjB,cAAc,EAAE,cAAc,CAAC,IAAI;SACpC,CAAC;QACF,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IAC/B,CAAC;IAED,CAAC,MAAM,CAAC,OAAO,CAAC;QACd,IAAI,CAAC,YAAY,CAAC,QAAQ,EAAE,CAAC;QAC7B,IAAI,CAAC,eAAe,CAAC,QAAQ,EAAE,CAAC;IAClC,CAAC;CACF"}
@@ -0,0 +1,3 @@
1
+ export { ConsoleAnalyticsAdapter } from './ConsoleAnalyticsAdapter.js';
2
+ export { FusionAnalyticsAdapter } from './FusionAnalyticsAdapter.js';
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/adapters/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,uBAAuB,EAAE,MAAM,8BAA8B,CAAC;AACvE,OAAO,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=AnalyticsCollector.interface.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AnalyticsCollector.interface.js","sourceRoot":"","sources":["../../../src/collectors/AnalyticsCollector.interface.ts"],"names":[],"mappings":""}
@@ -0,0 +1,42 @@
1
+ import { BaseCollector, createSchema } from './BaseCollector.js';
2
+ import { appSchema, extractAppMetadata } from './utils/extractAppMetadata.js';
3
+ import { contextSchema, extractContextMetadata, } from './utils/extractContextMetadata.js';
4
+ import { Subject } from 'rxjs';
5
+ import { z } from 'zod';
6
+ const EVENT_NAME = 'onAppModulesLoaded';
7
+ /**
8
+ * The schema of the data to be sent.
9
+ */
10
+ const eventSchema = createSchema(appSchema, z.object({ context: contextSchema }));
11
+ /**
12
+ * Collector to listen for app loaded and add values and attributes for
13
+ * further processing by adapters.
14
+ */
15
+ export class AppLoadedCollector extends BaseCollector {
16
+ #eventProvider;
17
+ #appProvider;
18
+ constructor(eventProvider, appProvider) {
19
+ super('app-loaded', eventSchema);
20
+ this.#eventProvider = eventProvider;
21
+ this.#appProvider = appProvider;
22
+ }
23
+ _initialize() {
24
+ const subject = new Subject();
25
+ this.#eventProvider.addEventListener(EVENT_NAME, (event) => {
26
+ // Fallback to appProvider for manifest if app is not updated with latest
27
+ // payload for onAppModulesLoaded (missing manifest).
28
+ const manifest = event.detail.manifest ?? this.#appProvider.current?.manifest;
29
+ const modules = event.detail.modules;
30
+ const data = {
31
+ value: manifest && extractAppMetadata(manifest),
32
+ attributes: {
33
+ context: modules.context?.currentContext &&
34
+ extractContextMetadata(modules.context.currentContext),
35
+ },
36
+ };
37
+ subject.next(data);
38
+ });
39
+ return subject;
40
+ }
41
+ }
42
+ //# sourceMappingURL=AppLoadedCollector.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AppLoadedCollector.js","sourceRoot":"","sources":["../../../src/collectors/AppLoadedCollector.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AACjE,OAAO,EAAoB,SAAS,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;AAChG,OAAO,EAEL,aAAa,EACb,sBAAsB,GACvB,MAAM,mCAAmC,CAAC;AAU3C,OAAO,EAAwB,OAAO,EAAE,MAAM,MAAM,CAAC;AACrD,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,MAAM,UAAU,GAAG,oBAAoB,CAAC;AAExC;;GAEG;AACH,MAAM,WAAW,GAAG,YAAY,CAAC,SAAS,EAAE,CAAC,CAAC,MAAM,CAAC,EAAE,OAAO,EAAE,aAAa,EAAE,CAAC,CAAC,CAAC;AAElF;;;GAGG;AACH,MAAM,OAAO,kBACX,SAAQ,aAAyD;IAGjE,cAAc,CAAuB;IACrC,YAAY,CAAoB;IAEhC,YAAY,aAAmC,EAAE,WAA8B;QAC7E,KAAK,CAAC,YAAY,EAAE,WAAW,CAAC,CAAC;QACjC,IAAI,CAAC,cAAc,GAAG,aAAa,CAAC;QACpC,IAAI,CAAC,YAAY,GAAG,WAAW,CAAC;IAClC,CAAC;IAED,WAAW;QAIT,MAAM,OAAO,GAAG,IAAI,OAAO,EAGvB,CAAC;QACL,IAAI,CAAC,cAAc,CAAC,gBAAgB,CAAC,UAAU,EAAE,CAAC,KAAK,EAAE,EAAE;YACzD,yEAAyE;YACzE,qDAAqD;YACrD,MAAM,QAAQ,GACX,KAAK,CAAC,MAAM,CAAC,QAAwB,IAAI,IAAI,CAAC,YAAY,CAAC,OAAO,EAAE,QAAQ,CAAC;YAChF,MAAM,OAAO,GAAG,KAAK,CAAC,MAAM,CAAC,OAA8C,CAAC;YAE5E,MAAM,IAAI,GAAG;gBACX,KAAK,EAAE,QAAQ,IAAI,kBAAkB,CAAC,QAAQ,CAAC;gBAC/C,UAAU,EAAE;oBACV,OAAO,EACL,OAAO,CAAC,OAAO,EAAE,cAAc;wBAC/B,sBAAsB,CAAC,OAAO,CAAC,OAAO,CAAC,cAAc,CAAC;iBACzD;aACF,CAAC;YAEF,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACrB,CAAC,CAAC,CAAC;QAEH,OAAO,OAAO,CAAC;IACjB,CAAC;CACF"}
@@ -0,0 +1,32 @@
1
+ import { map, pairwise } from 'rxjs';
2
+ import { BaseCollector, createSchema } from './BaseCollector.js';
3
+ import { appKeySchema, extractAppKeyMetadata, } from './utils/extractAppMetadata.js';
4
+ import { z } from 'zod';
5
+ /**
6
+ * The schema of the data to be sent.
7
+ */
8
+ const eventSchema = createSchema(appKeySchema, z.object({ previous: appKeySchema }));
9
+ /**
10
+ * Collector to listen for app selection and add values and attributes for
11
+ * further processing by adapters.
12
+ */
13
+ export class AppSelectedCollector extends BaseCollector {
14
+ #appProvider;
15
+ constructor(appProvider) {
16
+ super('app-selected', eventSchema);
17
+ this.#appProvider = appProvider;
18
+ }
19
+ _initialize() {
20
+ const appSelected$ = this.#appProvider.current$.pipe(pairwise());
21
+ const data$ = appSelected$.pipe(map(([prev, next]) => {
22
+ return {
23
+ value: extractAppKeyMetadata(next),
24
+ attributes: {
25
+ previous: prev && extractAppKeyMetadata(prev),
26
+ },
27
+ };
28
+ }));
29
+ return data$;
30
+ }
31
+ }
32
+ //# sourceMappingURL=AppSelectedCollector.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AppSelectedCollector.js","sourceRoot":"","sources":["../../../src/collectors/AppSelectedCollector.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAwB,QAAQ,EAAE,MAAM,MAAM,CAAC;AAE3D,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AACjE,OAAO,EAEL,YAAY,EACZ,qBAAqB,GACtB,MAAM,+BAA+B,CAAC;AAIvC,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB;;GAEG;AACH,MAAM,WAAW,GAAG,YAAY,CAAC,YAAY,EAAE,CAAC,CAAC,MAAM,CAAC,EAAE,QAAQ,EAAE,YAAY,EAAE,CAAC,CAAC,CAAC;AAErF;;;GAGG;AACH,MAAM,OAAO,oBACX,SAAQ,aAAoD;IAG5D,YAAY,CAAoB;IAEhC,YAAY,WAA8B;QACxC,KAAK,CAAC,cAAc,EAAE,WAAW,CAAC,CAAC;QACnC,IAAI,CAAC,YAAY,GAAG,WAAW,CAAC;IAClC,CAAC;IAED,WAAW;QAIT,MAAM,YAAY,GAAG,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC;QAEjE,MAAM,KAAK,GAAG,YAAY,CAAC,IAAI,CAC7B,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE,EAAE;YACnB,OAAO;gBACL,KAAK,EAAE,qBAAqB,CAAC,IAAI,CAAC;gBAClC,UAAU,EAAE;oBACV,QAAQ,EAAE,IAAI,IAAI,qBAAqB,CAAC,IAAI,CAAC;iBAC9C;aACF,CAAC;QACJ,CAAC,CAAC,CACH,CAAC;QAEF,OAAO,KAAK,CAAC;IACf,CAAC;CACF"}