@equinor/fusion-framework-module-analytics 1.0.2 → 2.0.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.
- package/CHANGELOG.md +34 -0
- package/README.md +147 -130
- package/dist/esm/AnalyticsConfigurator.js +22 -17
- package/dist/esm/AnalyticsConfigurator.js.map +1 -1
- package/dist/esm/AnalyticsProvider.js +39 -18
- package/dist/esm/AnalyticsProvider.js.map +1 -1
- package/dist/esm/adapters/ConsoleAnalyticsAdapter.js +15 -1
- package/dist/esm/adapters/ConsoleAnalyticsAdapter.js.map +1 -1
- package/dist/esm/adapters/FusionAnalyticsAdapter.js +32 -3
- package/dist/esm/adapters/FusionAnalyticsAdapter.js.map +1 -1
- package/dist/esm/adapters/index.js.map +1 -1
- package/dist/esm/collectors/AppLoadedCollector.js +21 -5
- package/dist/esm/collectors/AppLoadedCollector.js.map +1 -1
- package/dist/esm/collectors/AppSelectedCollector.js +17 -5
- package/dist/esm/collectors/AppSelectedCollector.js.map +1 -1
- package/dist/esm/collectors/BaseCollector.js +48 -3
- package/dist/esm/collectors/BaseCollector.js.map +1 -1
- package/dist/esm/collectors/ContextSelectedCollector.js +20 -5
- package/dist/esm/collectors/ContextSelectedCollector.js.map +1 -1
- package/dist/esm/collectors/index.js.map +1 -1
- package/dist/esm/collectors/utils/extractAppMetadata.js +25 -4
- package/dist/esm/collectors/utils/extractAppMetadata.js.map +1 -1
- package/dist/esm/collectors/utils/extractContextMetadata.js +13 -2
- package/dist/esm/collectors/utils/extractContextMetadata.js.map +1 -1
- package/dist/esm/enable-analytics.js +18 -3
- package/dist/esm/enable-analytics.js.map +1 -1
- package/dist/esm/index.js +18 -0
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/logExporters/fusionOTLPLogExporter/FusionOTLPLogExporter.js +26 -4
- package/dist/esm/logExporters/fusionOTLPLogExporter/FusionOTLPLogExporter.js.map +1 -1
- package/dist/esm/logExporters/fusionOTLPLogExporter/HttpClientExporterTransport.js +36 -7
- package/dist/esm/logExporters/fusionOTLPLogExporter/HttpClientExporterTransport.js.map +1 -1
- package/dist/esm/logExporters/index.js +8 -0
- package/dist/esm/logExporters/index.js.map +1 -1
- package/dist/esm/module.js +8 -8
- package/dist/esm/version.js +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/types/AnalyticsConfigurator.d.ts +22 -17
- package/dist/types/AnalyticsConfigurator.interface.d.ts +41 -12
- package/dist/types/AnalyticsProvider.d.ts +32 -18
- package/dist/types/AnalyticsProvider.interface.d.ts +28 -6
- package/dist/types/adapters/AnalyticsAdapter.interface.d.ts +15 -2
- package/dist/types/adapters/ConsoleAnalyticsAdapter.d.ts +15 -1
- package/dist/types/adapters/FusionAnalyticsAdapter.d.ts +32 -3
- package/dist/types/adapters/index.d.ts +8 -0
- package/dist/types/collectors/AnalyticsCollector.interface.d.ts +11 -2
- package/dist/types/collectors/AppLoadedCollector.d.ts +20 -2
- package/dist/types/collectors/AppSelectedCollector.d.ts +16 -2
- package/dist/types/collectors/BaseCollector.d.ts +58 -3
- package/dist/types/collectors/ContextSelectedCollector.d.ts +19 -2
- package/dist/types/collectors/index.d.ts +8 -0
- package/dist/types/collectors/utils/extractAppMetadata.d.ts +27 -0
- package/dist/types/collectors/utils/extractContextMetadata.d.ts +14 -0
- package/dist/types/enable-analytics.d.ts +19 -3
- package/dist/types/index.d.ts +18 -0
- package/dist/types/logExporters/fusionOTLPLogExporter/FusionOTLPLogExporter.d.ts +21 -3
- package/dist/types/logExporters/fusionOTLPLogExporter/HttpClientExporterTransport.d.ts +24 -1
- package/dist/types/logExporters/index.d.ts +8 -0
- package/dist/types/module.d.ts +15 -15
- package/dist/types/types.d.ts +38 -7
- package/dist/types/version.d.ts +1 -1
- package/package.json +11 -11
- package/src/AnalyticsConfigurator.interface.ts +41 -12
- package/src/AnalyticsConfigurator.ts +22 -17
- package/src/AnalyticsProvider.interface.ts +28 -6
- package/src/AnalyticsProvider.ts +39 -18
- package/src/adapters/AnalyticsAdapter.interface.ts +15 -2
- package/src/adapters/ConsoleAnalyticsAdapter.ts +15 -1
- package/src/adapters/FusionAnalyticsAdapter.ts +32 -3
- package/src/adapters/index.ts +8 -0
- package/src/collectors/AnalyticsCollector.interface.ts +11 -2
- package/src/collectors/AppLoadedCollector.ts +21 -5
- package/src/collectors/AppSelectedCollector.ts +17 -5
- package/src/collectors/BaseCollector.ts +58 -3
- package/src/collectors/ContextSelectedCollector.ts +20 -5
- package/src/collectors/index.ts +8 -0
- package/src/collectors/utils/extractAppMetadata.ts +27 -4
- package/src/collectors/utils/extractContextMetadata.ts +14 -2
- package/src/enable-analytics.ts +19 -3
- package/src/index.ts +19 -0
- package/src/logExporters/fusionOTLPLogExporter/FusionOTLPLogExporter.ts +26 -4
- package/src/logExporters/fusionOTLPLogExporter/HttpClientExporterTransport.ts +36 -7
- package/src/logExporters/index.ts +8 -0
- package/src/module.ts +15 -15
- package/src/types.ts +39 -8
- package/src/version.ts +1 -1
|
@@ -4,15 +4,42 @@ import { resourceFromAttributes } from '@opentelemetry/resources';
|
|
|
4
4
|
import { version } from '../version.js';
|
|
5
5
|
import { v7 as uuid } from 'uuid';
|
|
6
6
|
/**
|
|
7
|
-
*
|
|
7
|
+
* Analytics adapter that forwards events to an OpenTelemetry log exporter.
|
|
8
8
|
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
9
|
+
* @remarks
|
|
10
|
+
* Uses `@opentelemetry/sdk-logs` to batch and export log records through the
|
|
11
|
+
* provided {@link OTLPExporterBase} transport. Each analytics event is mapped
|
|
12
|
+
* to an OTLP `LogRecord` with severity `INFO`.
|
|
13
|
+
*
|
|
14
|
+
* Resource attributes automatically include the module version, a unique
|
|
15
|
+
* session ID (UUIDv7), and the portal ID supplied at construction time.
|
|
16
|
+
*
|
|
17
|
+
* @template T - Analytics event type, defaults to {@link AnalyticsEvent}.
|
|
18
|
+
*
|
|
19
|
+
* @example
|
|
20
|
+
* ```ts
|
|
21
|
+
* import { FusionAnalyticsAdapter } from '@equinor/fusion-framework-module-analytics/adapters';
|
|
22
|
+
* import { OTLPLogExporter } from '@equinor/fusion-framework-module-analytics/logExporters';
|
|
23
|
+
*
|
|
24
|
+
* builder.setAdapter('fusion-log', async () => {
|
|
25
|
+
* const logExporter = new OTLPLogExporter({ url: '/v1/logs' });
|
|
26
|
+
* return new FusionAnalyticsAdapter({ portalId: 'my-portal', logExporter });
|
|
27
|
+
* });
|
|
28
|
+
* ```
|
|
29
|
+
*
|
|
30
|
+
* @see {@link OTLPExporterBase}
|
|
11
31
|
*/
|
|
12
32
|
export class FusionAnalyticsAdapter {
|
|
13
33
|
#logExporter;
|
|
14
34
|
#loggerProvider;
|
|
15
35
|
#logger;
|
|
36
|
+
/**
|
|
37
|
+
* Creates a new `FusionAnalyticsAdapter`.
|
|
38
|
+
*
|
|
39
|
+
* @param args - Construction options.
|
|
40
|
+
* @param args.portalId - Portal identifier attached to every exported log record.
|
|
41
|
+
* @param args.logExporter - An OTLP-compatible log exporter for transport.
|
|
42
|
+
*/
|
|
16
43
|
constructor(args) {
|
|
17
44
|
this.#logExporter = args.logExporter;
|
|
18
45
|
this.#loggerProvider = new LoggerProvider({
|
|
@@ -25,6 +52,7 @@ export class FusionAnalyticsAdapter {
|
|
|
25
52
|
});
|
|
26
53
|
this.#logger = this.#loggerProvider.getLogger('fusion');
|
|
27
54
|
}
|
|
55
|
+
/** Maps an analytics event to an OTLP `LogRecord` and emits it via the logger. */
|
|
28
56
|
registerAnalytic(event) {
|
|
29
57
|
const logRecord = {
|
|
30
58
|
eventName: event.name,
|
|
@@ -34,6 +62,7 @@ export class FusionAnalyticsAdapter {
|
|
|
34
62
|
};
|
|
35
63
|
this.#logger.emit(logRecord);
|
|
36
64
|
}
|
|
65
|
+
/** Shuts down the log exporter and logger provider, flushing remaining records. */
|
|
37
66
|
[Symbol.dispose]() {
|
|
38
67
|
this.#logExporter.shutdown();
|
|
39
68
|
this.#loggerProvider.shutdown();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FusionAnalyticsAdapter.js","sourceRoot":"","sources":["../../../src/adapters/FusionAnalyticsAdapter.ts"],"names":[],"mappings":"AAGA,OAAO,EACL,cAAc,EACd,uBAAuB,GAExB,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
|
|
1
|
+
{"version":3,"file":"FusionAnalyticsAdapter.js","sourceRoot":"","sources":["../../../src/adapters/FusionAnalyticsAdapter.ts"],"names":[],"mappings":"AAGA,OAAO,EACL,cAAc,EACd,uBAAuB,GAExB,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;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,MAAM,OAAO,sBAAsB;IAGjC,YAAY,CAAwC;IACpD,eAAe,CAAiB;IAChC,OAAO,CAAS;IAEhB;;;;;;OAMG;IACH,YAAY,IAA8E;QACxF,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,WAAW,CAAC;QAErC,IAAI,CAAC,eAAe,GAAG,IAAI,cAAc,CAAC;YACxC,UAAU,EAAE,CAAC,IAAI,uBAAuB,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;YAC5D,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,kFAAkF;IAClF,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,mFAAmF;IACnF,CAAC,MAAM,CAAC,OAAO,CAAC;QACd,IAAI,CAAC,YAAY,CAAC,QAAQ,EAAE,CAAC;QAC7B,IAAI,CAAC,eAAe,CAAC,QAAQ,EAAE,CAAC;IAClC,CAAC;CACF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/adapters/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/adapters/index.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,uBAAuB,EAAE,MAAM,8BAA8B,CAAC;AACvE,OAAO,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC"}
|
|
@@ -4,17 +4,33 @@ import { contextSchema, extractContextMetadata, } from './utils/extractContextMe
|
|
|
4
4
|
import { Subject } from 'rxjs';
|
|
5
5
|
import { z } from 'zod';
|
|
6
6
|
const EVENT_NAME = 'onAppModulesLoaded';
|
|
7
|
-
/**
|
|
8
|
-
* The schema of the data to be sent.
|
|
9
|
-
*/
|
|
7
|
+
/** Zod schema for the `app-loaded` event (value + attributes). */
|
|
10
8
|
const eventSchema = createSchema(appSchema, z.object({ context: contextSchema }));
|
|
11
9
|
/**
|
|
12
|
-
* Collector
|
|
13
|
-
*
|
|
10
|
+
* Collector that emits an analytics event whenever an application’s modules
|
|
11
|
+
* finish loading.
|
|
12
|
+
*
|
|
13
|
+
* @remarks
|
|
14
|
+
* Listens to the framework `onAppModulesLoaded` event, extracts application
|
|
15
|
+
* manifest metadata, and includes the current context (if available) in the
|
|
16
|
+
* event attributes.
|
|
17
|
+
*
|
|
18
|
+
* Register via:
|
|
19
|
+
* ```ts
|
|
20
|
+
* builder.setCollector('app-loaded', async (args) => {
|
|
21
|
+
* const event = await args.requireInstance('event');
|
|
22
|
+
* const app = await args.requireInstance('app');
|
|
23
|
+
* return new AppLoadedCollector(event, app);
|
|
24
|
+
* });
|
|
25
|
+
* ```
|
|
14
26
|
*/
|
|
15
27
|
export class AppLoadedCollector extends BaseCollector {
|
|
16
28
|
#eventProvider;
|
|
17
29
|
#appProvider;
|
|
30
|
+
/**
|
|
31
|
+
* @param eventProvider - Fusion event module provider to listen for app-loaded events.
|
|
32
|
+
* @param appProvider - Fusion app module provider for fallback manifest data.
|
|
33
|
+
*/
|
|
18
34
|
constructor(eventProvider, appProvider) {
|
|
19
35
|
super('app-loaded', eventSchema);
|
|
20
36
|
this.#eventProvider = eventProvider;
|
|
@@ -1 +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
|
|
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,kEAAkE;AAClE,MAAM,WAAW,GAAG,YAAY,CAAC,SAAS,EAAE,CAAC,CAAC,MAAM,CAAC,EAAE,OAAO,EAAE,aAAa,EAAE,CAAC,CAAC,CAAC;AAElF;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,OAAO,kBACX,SAAQ,aAAyD;IAGjE,cAAc,CAAuB;IACrC,YAAY,CAAoB;IAEhC;;;OAGG;IACH,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"}
|
|
@@ -2,16 +2,28 @@ import { map, pairwise } from 'rxjs';
|
|
|
2
2
|
import { BaseCollector, createSchema } from './BaseCollector.js';
|
|
3
3
|
import { appKeySchema, extractAppKeyMetadata, } from './utils/extractAppMetadata.js';
|
|
4
4
|
import { z } from 'zod';
|
|
5
|
-
/**
|
|
6
|
-
* The schema of the data to be sent.
|
|
7
|
-
*/
|
|
5
|
+
/** Zod schema for the `app-selected` event (value + attributes). */
|
|
8
6
|
const eventSchema = createSchema(appKeySchema, z.object({ previous: appKeySchema }));
|
|
9
7
|
/**
|
|
10
|
-
* Collector
|
|
11
|
-
*
|
|
8
|
+
* Collector that emits an analytics event whenever the active Fusion application changes.
|
|
9
|
+
*
|
|
10
|
+
* @remarks
|
|
11
|
+
* Listens to `AppModuleProvider.current$`, pairs consecutive values, and emits
|
|
12
|
+
* both the new and previous app key metadata.
|
|
13
|
+
*
|
|
14
|
+
* Register via:
|
|
15
|
+
* ```ts
|
|
16
|
+
* builder.setCollector('app-selected', async (args) => {
|
|
17
|
+
* const app = await args.requireInstance('app');
|
|
18
|
+
* return new AppSelectedCollector(app);
|
|
19
|
+
* });
|
|
20
|
+
* ```
|
|
12
21
|
*/
|
|
13
22
|
export class AppSelectedCollector extends BaseCollector {
|
|
14
23
|
#appProvider;
|
|
24
|
+
/**
|
|
25
|
+
* @param appProvider - Fusion app module provider to observe.
|
|
26
|
+
*/
|
|
15
27
|
constructor(appProvider) {
|
|
16
28
|
super('app-selected', eventSchema);
|
|
17
29
|
this.#appProvider = appProvider;
|
|
@@ -1 +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
|
|
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,oEAAoE;AACpE,MAAM,WAAW,GAAG,YAAY,CAAC,YAAY,EAAE,CAAC,CAAC,MAAM,CAAC,EAAE,QAAQ,EAAE,YAAY,EAAE,CAAC,CAAC,CAAC;AAErF;;;;;;;;;;;;;;GAcG;AACH,MAAM,OAAO,oBACX,SAAQ,aAAoD;IAG5D,YAAY,CAAoB;IAEhC;;OAEG;IACH,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"}
|
|
@@ -1,7 +1,14 @@
|
|
|
1
1
|
import { from, map, Subject } from 'rxjs';
|
|
2
2
|
import { z } from 'zod';
|
|
3
3
|
/**
|
|
4
|
-
*
|
|
4
|
+
* Creates a Zod schema for validating {@link AnalyticsEvent} instances with
|
|
5
|
+
* typed value and attributes.
|
|
6
|
+
*
|
|
7
|
+
* @template TValue - Schema type for the event body.
|
|
8
|
+
* @template TAttr - Schema type for the event attributes.
|
|
9
|
+
* @param value - Zod schema validating the event body.
|
|
10
|
+
* @param attributes - Zod schema validating the event attributes.
|
|
11
|
+
* @returns A Zod object schema matching `{ name, value, attributes? }`.
|
|
5
12
|
*/
|
|
6
13
|
export const createSchema = (value, attributes) => {
|
|
7
14
|
return z.object({
|
|
@@ -11,17 +18,49 @@ export const createSchema = (value, attributes) => {
|
|
|
11
18
|
});
|
|
12
19
|
};
|
|
13
20
|
/**
|
|
14
|
-
*
|
|
15
|
-
* emitting.
|
|
21
|
+
* Abstract base class for analytics collectors that validates events against a
|
|
22
|
+
* Zod schema before emitting.
|
|
23
|
+
*
|
|
24
|
+
* @remarks
|
|
25
|
+
* Subclasses implement {@link BaseCollector._initialize | _initialize} to return
|
|
26
|
+
* an observable of raw `{ value, attributes }` objects. `BaseCollector` wraps
|
|
27
|
+
* each emission with the collector name, validates it against the supplied schema,
|
|
28
|
+
* and publishes through an internal `Subject`.
|
|
29
|
+
*
|
|
30
|
+
* @template TValue - The event body type.
|
|
31
|
+
* @template TAttr - The event attributes type.
|
|
32
|
+
*
|
|
33
|
+
* @example
|
|
34
|
+
* ```ts
|
|
35
|
+
* class MyCollector extends BaseCollector<string, { page: string }> {
|
|
36
|
+
* constructor() {
|
|
37
|
+
* super('my-event', createSchema(z.string(), z.object({ page: z.string() })));
|
|
38
|
+
* }
|
|
39
|
+
* _initialize() {
|
|
40
|
+
* return of({ value: 'hello', attributes: { page: '/home' } });
|
|
41
|
+
* }
|
|
42
|
+
* }
|
|
43
|
+
* ```
|
|
16
44
|
*/
|
|
17
45
|
export class BaseCollector {
|
|
18
46
|
#schema;
|
|
19
47
|
#name;
|
|
20
48
|
#subject = new Subject();
|
|
49
|
+
/**
|
|
50
|
+
* Creates a new `BaseCollector`.
|
|
51
|
+
*
|
|
52
|
+
* @param name - Event name assigned to every emission (e.g. `'context-selected'`).
|
|
53
|
+
* @param schema - Zod schema used to validate each event before publishing.
|
|
54
|
+
*/
|
|
21
55
|
constructor(name, schema) {
|
|
22
56
|
this.#name = name;
|
|
23
57
|
this.#schema = schema;
|
|
24
58
|
}
|
|
59
|
+
/**
|
|
60
|
+
* Subscribes to the source returned by {@link BaseCollector._initialize},
|
|
61
|
+
* validates each emission with the Zod schema, and publishes through the
|
|
62
|
+
* internal subject.
|
|
63
|
+
*/
|
|
25
64
|
initialize() {
|
|
26
65
|
from(this._initialize())
|
|
27
66
|
.pipe(map(({ value, attributes }) => {
|
|
@@ -33,6 +72,12 @@ export class BaseCollector {
|
|
|
33
72
|
}), map((x) => this.#schema.parse(x)))
|
|
34
73
|
.subscribe(this.#subject);
|
|
35
74
|
}
|
|
75
|
+
/**
|
|
76
|
+
* Subscribes an observer to the validated event stream.
|
|
77
|
+
*
|
|
78
|
+
* @param observer - Partial observer receiving validated events.
|
|
79
|
+
* @returns An `Unsubscribable` handle.
|
|
80
|
+
*/
|
|
36
81
|
subscribe(observer) {
|
|
37
82
|
return this.#subject.subscribe(observer);
|
|
38
83
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BaseCollector.js","sourceRoot":"","sources":["../../../src/collectors/BaseCollector.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,IAAI,EAAE,GAAG,EAAwB,OAAO,EAAsC,MAAM,MAAM,CAAC;AACpG,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB
|
|
1
|
+
{"version":3,"file":"BaseCollector.js","sourceRoot":"","sources":["../../../src/collectors/BaseCollector.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,IAAI,EAAE,GAAG,EAAwB,OAAO,EAAsC,MAAM,MAAM,CAAC;AACpG,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG,CAC1B,KAA0B,EAC1B,UAA8B,EAC9B,EAAE;IACF,OAAO,CAAC,CAAC,MAAM,CAAC;QACd,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE;QAChB,KAAK,EAAE,KAAK;QACZ,UAAU,EAAE,UAAU,CAAC,QAAQ,EAAE;KAClC,CAAC,CAAC;AACL,CAAC,CAAC;AAOF;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,MAAM,OAAgB,aAAa;IAKjC,OAAO,CAAiC;IACxC,KAAK,CAAS;IACd,QAAQ,GAAqD,IAAI,OAAO,EAErE,CAAC;IAEJ;;;;;OAKG;IACH,YAAY,IAAY,EAAE,MAAsC;QAC9D,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC;QAClB,IAAI,CAAC,OAAO,GAAG,MAAM,CAAC;IACxB,CAAC;IAaD;;;;OAIG;IACH,UAAU;QACR,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;aACrB,IAAI,CACH,GAAG,CAAC,CAAC,EAAE,KAAK,EAAE,UAAU,EAAE,EAAE,EAAE;YAC5B,OAAO;gBACL,IAAI,EAAE,IAAI,CAAC,KAAK;gBAChB,KAAK,EAAE,KAAK;gBACZ,UAAU,EAAE,UAAU;aACvB,CAAC;QACJ,CAAC,CAAC,EACF,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAClC;aACA,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAC9B,CAAC;IAED;;;;;OAKG;IACH,SAAS,CAAC,QAAoE;QAC5E,OAAO,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;IAC3C,CAAC;CACF"}
|
|
@@ -2,17 +2,32 @@ import { distinctUntilChanged, map, pairwise } from 'rxjs';
|
|
|
2
2
|
import { z } from 'zod';
|
|
3
3
|
import { BaseCollector, createSchema } from './BaseCollector.js';
|
|
4
4
|
import { contextSchema, extractContextMetadata, } from './utils/extractContextMetadata.js';
|
|
5
|
-
/**
|
|
6
|
-
* The schema of the data to be sent.
|
|
7
|
-
*/
|
|
5
|
+
/** Zod schema for the `context-selected` event (value + attributes). */
|
|
8
6
|
const eventSchema = createSchema(contextSchema, z.object({ previous: contextSchema, appKey: z.string().optional() }));
|
|
9
7
|
/**
|
|
10
|
-
* Collector
|
|
11
|
-
*
|
|
8
|
+
* Collector that emits an analytics event whenever the active Fusion context changes.
|
|
9
|
+
*
|
|
10
|
+
* @remarks
|
|
11
|
+
* Listens to `IContextProvider.currentContext$`, de-duplicates by context ID,
|
|
12
|
+
* pairs consecutive values, and emits both the new and previous context
|
|
13
|
+
* metadata. The current application key is included in attributes.
|
|
14
|
+
*
|
|
15
|
+
* Register via:
|
|
16
|
+
* ```ts
|
|
17
|
+
* builder.setCollector('context-selected', async (args) => {
|
|
18
|
+
* const ctx = await args.requireInstance('context');
|
|
19
|
+
* const app = await args.requireInstance('app');
|
|
20
|
+
* return new ContextSelectedCollector(ctx, app);
|
|
21
|
+
* });
|
|
22
|
+
* ```
|
|
12
23
|
*/
|
|
13
24
|
export class ContextSelectedCollector extends BaseCollector {
|
|
14
25
|
#contextProvider;
|
|
15
26
|
#appProvider;
|
|
27
|
+
/**
|
|
28
|
+
* @param contextProvider - Fusion context module provider to observe.
|
|
29
|
+
* @param appProvider - Fusion app module provider for the current app key.
|
|
30
|
+
*/
|
|
16
31
|
constructor(contextProvider, appProvider) {
|
|
17
32
|
super('context-selected', eventSchema);
|
|
18
33
|
this.#contextProvider = contextProvider;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ContextSelectedCollector.js","sourceRoot":"","sources":["../../../src/collectors/ContextSelectedCollector.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,GAAG,EAAwB,QAAQ,EAAE,MAAM,MAAM,CAAC;AAIjF,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AACjE,OAAO,EAEL,aAAa,EACb,sBAAsB,GACvB,MAAM,mCAAmC,CAAC;AAE3C
|
|
1
|
+
{"version":3,"file":"ContextSelectedCollector.js","sourceRoot":"","sources":["../../../src/collectors/ContextSelectedCollector.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,GAAG,EAAwB,QAAQ,EAAE,MAAM,MAAM,CAAC;AAIjF,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AACjE,OAAO,EAEL,aAAa,EACb,sBAAsB,GACvB,MAAM,mCAAmC,CAAC;AAE3C,wEAAwE;AACxE,MAAM,WAAW,GAAG,YAAY,CAC9B,aAAa,EACb,CAAC,CAAC,MAAM,CAAC,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,EAAE,CAAC,CACrE,CAAC;AAEF;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,OAAO,wBACX,SAAQ,aAA+E;IAGvF,gBAAgB,CAAmB;IACnC,YAAY,CAAoB;IAEhC;;;OAGG;IACH,YAAY,eAAiC,EAAE,WAA8B;QAC3E,KAAK,CAAC,kBAAkB,EAAE,WAAW,CAAC,CAAC;QACvC,IAAI,CAAC,gBAAgB,GAAG,eAAe,CAAC;QACxC,IAAI,CAAC,YAAY,GAAG,WAAW,CAAC;IAClC,CAAC;IAED,WAAW;QAIT,MAAM,gBAAgB,GAAG,IAAI,CAAC,gBAAgB,CAAC,eAAe,CAAC,IAAI;QACjE,gDAAgD;QAChD,oBAAoB,CAAC,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE,CAAC,IAAI,EAAE,EAAE,KAAK,IAAI,EAAE,EAAE,CAAC;QAC3D,0CAA0C;QAC1C,QAAQ,EAAE,CACX,CAAC;QAEF,MAAM,KAAK,GAAG,gBAAgB,CAAC,IAAI,CACjC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE,EAAE;YACnB,OAAO;gBACL,KAAK,EAAE,IAAI,IAAI,sBAAsB,CAAC,IAAI,CAAC;gBAC3C,UAAU,EAAE;oBACV,QAAQ,EAAE,IAAI,IAAI,sBAAsB,CAAC,IAAI,CAAC;oBAC9C,MAAM,EAAE,IAAI,CAAC,YAAY,CAAC,OAAO,EAAE,MAAM;iBAC1C;aACF,CAAC;QACJ,CAAC,CAAC,CACH,CAAC;QAEF,OAAO,KAAK,CAAC;IACf,CAAC;CACF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/collectors/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/collectors/index.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,wBAAwB,EAAE,MAAM,+BAA+B,CAAC;AACzE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AACjE,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC"}
|
|
@@ -1,14 +1,23 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
-
|
|
3
|
-
|
|
2
|
+
/**
|
|
3
|
+
* Zod schema for an object containing an optional `appKey` string.
|
|
4
|
+
*
|
|
5
|
+
* @remarks
|
|
6
|
+
* Used by {@link AppSelectedCollector} to validate the event body.
|
|
7
|
+
*/
|
|
4
8
|
export const appKeySchema = z
|
|
5
9
|
.object({
|
|
6
10
|
appKey: z.string().optional(),
|
|
7
11
|
})
|
|
8
12
|
.optional()
|
|
9
13
|
.nullable();
|
|
10
|
-
|
|
11
|
-
|
|
14
|
+
/**
|
|
15
|
+
* Zod schema for a Fusion application metadata object.
|
|
16
|
+
*
|
|
17
|
+
* @remarks
|
|
18
|
+
* Validates core app fields (appKey, displayName, type) and optional build
|
|
19
|
+
* and category information. Used by {@link AppLoadedCollector}.
|
|
20
|
+
*/
|
|
12
21
|
export const appSchema = z
|
|
13
22
|
.object({
|
|
14
23
|
appKey: z.string(),
|
|
@@ -19,11 +28,23 @@ export const appSchema = z
|
|
|
19
28
|
buildTag: z.string().optional().nullable(),
|
|
20
29
|
})
|
|
21
30
|
.optional();
|
|
31
|
+
/**
|
|
32
|
+
* Extracts app-key metadata from a `CurrentApp` instance.
|
|
33
|
+
*
|
|
34
|
+
* @param app - The current app object.
|
|
35
|
+
* @returns An object containing the optional `appKey`.
|
|
36
|
+
*/
|
|
22
37
|
export const extractAppKeyMetadata = (app) => {
|
|
23
38
|
return {
|
|
24
39
|
appKey: app?.appKey,
|
|
25
40
|
};
|
|
26
41
|
};
|
|
42
|
+
/**
|
|
43
|
+
* Extracts detailed app metadata from an `AppManifest` for analytics events.
|
|
44
|
+
*
|
|
45
|
+
* @param app - The application manifest.
|
|
46
|
+
* @returns An object with appKey, displayName, type, and optional build/category info.
|
|
47
|
+
*/
|
|
27
48
|
export const extractAppMetadata = (app) => {
|
|
28
49
|
return {
|
|
29
50
|
appKey: app.appKey,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"extractAppMetadata.js","sourceRoot":"","sources":["../../../../src/collectors/utils/extractAppMetadata.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB
|
|
1
|
+
{"version":3,"file":"extractAppMetadata.js","sourceRoot":"","sources":["../../../../src/collectors/utils/extractAppMetadata.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB;;;;;GAKG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC;KAC1B,MAAM,CAAC;IACN,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;CAC9B,CAAC;KACD,QAAQ,EAAE;KACV,QAAQ,EAAE,CAAC;AAEd;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC;KACvB,MAAM,CAAC;IACN,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE;IAClB,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE;IACvB,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE;IAChB,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IACnC,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IACnC,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE;CAC3C,CAAC;KACD,QAAQ,EAAE,CAAC;AAQd;;;;;GAKG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,GAAe,EAAgC,EAAE;IACrF,OAAO;QACL,MAAM,EAAE,GAAG,EAAE,MAAM;KACpB,CAAC;AACJ,CAAC,CAAC;AAEF;;;;;GAKG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,GAAgB,EAA6B,EAAE;IAChF,OAAO;QACL,MAAM,EAAE,GAAG,CAAC,MAAM;QAClB,WAAW,EAAE,GAAG,CAAC,WAAW;QAC5B,IAAI,EAAE,GAAG,CAAC,IAAI;QACd,YAAY,EAAE,GAAG,CAAC,QAAQ,EAAE,IAAI;QAChC,YAAY,EAAE,GAAG,CAAC,KAAK,EAAE,OAAO;QAChC,QAAQ,EAAE,GAAG,CAAC,KAAK,EAAE,GAAG;KACzB,CAAC;AACJ,CAAC,CAAC"}
|
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
-
|
|
3
|
-
|
|
2
|
+
/**
|
|
3
|
+
* Zod schema for a Fusion context metadata object.
|
|
4
|
+
*
|
|
5
|
+
* @remarks
|
|
6
|
+
* Validates core context fields (id, type) and optional title, externalId,
|
|
7
|
+
* and source. Used by {@link ContextSelectedCollector} and {@link AppLoadedCollector}.
|
|
8
|
+
*/
|
|
4
9
|
export const contextSchema = z
|
|
5
10
|
.object({
|
|
6
11
|
id: z.string(),
|
|
@@ -11,6 +16,12 @@ export const contextSchema = z
|
|
|
11
16
|
})
|
|
12
17
|
.optional()
|
|
13
18
|
.nullable();
|
|
19
|
+
/**
|
|
20
|
+
* Extracts context metadata from a `ContextItem` for analytics events.
|
|
21
|
+
*
|
|
22
|
+
* @param context - The Fusion context item.
|
|
23
|
+
* @returns An object with id, type, and optional title, externalId, and source.
|
|
24
|
+
*/
|
|
14
25
|
export const extractContextMetadata = (context) => {
|
|
15
26
|
return {
|
|
16
27
|
id: context.id,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"extractContextMetadata.js","sourceRoot":"","sources":["../../../../src/collectors/utils/extractContextMetadata.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB
|
|
1
|
+
{"version":3,"file":"extractContextMetadata.js","sourceRoot":"","sources":["../../../../src/collectors/utils/extractContextMetadata.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC;KAC3B,MAAM,CAAC;IACN,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE;IACd,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE;IAChB,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC5B,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IACjC,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;CAC9B,CAAC;KACD,QAAQ,EAAE;KACV,QAAQ,EAAE,CAAC;AAKd;;;;;GAKG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAG,CAAC,OAAoB,EAAiC,EAAE;IAC5F,OAAO;QACL,EAAE,EAAE,OAAO,CAAC,EAAE;QACd,UAAU,EAAE,OAAO,CAAC,UAAU,IAAI,SAAS;QAC3C,KAAK,EAAE,OAAO,CAAC,KAAK,IAAI,SAAS;QACjC,IAAI,EAAE,OAAO,CAAC,IAAI,CAAC,EAAE;QACrB,MAAM,EAAE,OAAO,CAAC,MAAM,IAAI,SAAS;KACpC,CAAC;AACJ,CAAC,CAAC"}
|
|
@@ -1,9 +1,24 @@
|
|
|
1
1
|
import { module } from './module.js';
|
|
2
2
|
/**
|
|
3
|
-
* Enables analytics
|
|
3
|
+
* Enables the analytics module on a Fusion Framework module configurator.
|
|
4
4
|
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
5
|
+
* Call this helper during application or portal configuration to register
|
|
6
|
+
* adapters and collectors for analytics tracking.
|
|
7
|
+
*
|
|
8
|
+
* @param configurator - The module configurator instance to attach analytics to.
|
|
9
|
+
* @param callback - Optional callback to register adapters and collectors on the analytics builder.
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```ts
|
|
13
|
+
* import { enableAnalytics } from '@equinor/fusion-framework-module-analytics';
|
|
14
|
+
* import { ConsoleAnalyticsAdapter } from '@equinor/fusion-framework-module-analytics/adapters';
|
|
15
|
+
*
|
|
16
|
+
* const configure = (configurator) => {
|
|
17
|
+
* enableAnalytics(configurator, (builder) => {
|
|
18
|
+
* builder.setAdapter('console', async () => new ConsoleAnalyticsAdapter());
|
|
19
|
+
* });
|
|
20
|
+
* };
|
|
21
|
+
* ```
|
|
7
22
|
*/
|
|
8
23
|
export const enableAnalytics = (
|
|
9
24
|
// biome-ignore lint/suspicious/noExplicitAny: must be any to support all module types
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"enable-analytics.js","sourceRoot":"","sources":["../../src/enable-analytics.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"enable-analytics.js","sourceRoot":"","sources":["../../src/enable-analytics.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAMrC;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG;AAC7B,sFAAsF;AACtF,YAA4C,EAC5C,QAAmC,EAC7B,EAAE;IACR,YAAY,CAAC,SAAS,CAAC;QACrB,MAAM;QACN,SAAS,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE;YAC3B,IAAI,QAAQ,EAAE,CAAC;gBACb,MAAM,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC;YAC3C,CAAC;QACH,CAAC;KACF,CAAC,CAAC;AACL,CAAC,CAAC"}
|
package/dist/esm/index.js
CHANGED
|
@@ -1,3 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `@equinor/fusion-framework-module-analytics` — Fusion Framework module for
|
|
3
|
+
* collecting and exporting application analytics using OpenTelemetry standards.
|
|
4
|
+
*
|
|
5
|
+
* @remarks
|
|
6
|
+
* This package provides a pluggable adapter/collector architecture:
|
|
7
|
+
*
|
|
8
|
+
* - **Adapters** receive analytics events and forward them to a backend
|
|
9
|
+
* (e.g. console, OTLP endpoint).
|
|
10
|
+
* - **Collectors** observe application state (context changes, app loads) and
|
|
11
|
+
* emit structured {@link AnalyticsEvent} instances.
|
|
12
|
+
*
|
|
13
|
+
* Import adapters from `'@equinor/fusion-framework-module-analytics/adapters'`,
|
|
14
|
+
* collectors from `'@equinor/fusion-framework-module-analytics/collectors'`,
|
|
15
|
+
* and log exporters from `'@equinor/fusion-framework-module-analytics/logExporters'`.
|
|
16
|
+
*
|
|
17
|
+
* @packageDocumentation
|
|
18
|
+
*/
|
|
1
19
|
export { module as analyticsModule } from './module.js';
|
|
2
20
|
export { AnalyticsProvider } from './AnalyticsProvider.js';
|
|
3
21
|
export { AnalyticsConfigurator } from './AnalyticsConfigurator.js';
|
package/dist/esm/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,IAAI,eAAe,EAAmB,MAAM,aAAa,CAAC;AAIzE,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAI3D,OAAO,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;AAEnE,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,EAAE,MAAM,IAAI,eAAe,EAAmB,MAAM,aAAa,CAAC;AAIzE,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAI3D,OAAO,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;AAEnE,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC"}
|
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
import { JsonLogsSerializer } from '@opentelemetry/otlp-transformer';
|
|
2
2
|
import { createOtlpNetworkExportDelegate, OTLPExporterBase, } from '@opentelemetry/otlp-exporter-base';
|
|
3
3
|
import { HttpClientExporterTransport } from './HttpClientExporterTransport.js';
|
|
4
|
-
|
|
4
|
+
/**
|
|
5
|
+
* Returns shared default OTLP exporter configuration values.
|
|
6
|
+
*
|
|
7
|
+
* @returns Default timeout, concurrency limit, and compression settings.
|
|
8
|
+
*/
|
|
5
9
|
function getSharedConfigurationDefaults() {
|
|
6
10
|
return {
|
|
7
11
|
timeoutMillis: 10000,
|
|
@@ -10,11 +14,29 @@ function getSharedConfigurationDefaults() {
|
|
|
10
14
|
};
|
|
11
15
|
}
|
|
12
16
|
/**
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
17
|
+
* OTLP log exporter that uses a Fusion `IHttpClient` as its HTTP transport.
|
|
18
|
+
*
|
|
19
|
+
* @remarks
|
|
20
|
+
* Extends `OTLPExporterBase` and substitutes the default `fetch`-based transport
|
|
21
|
+
* with {@link HttpClientExporterTransport}, routing log record payloads
|
|
22
|
+
* through the Fusion HTTP module’s configured client (which may include
|
|
23
|
+
* authentication headers, interceptors, and service‑discovery routing).
|
|
24
|
+
*
|
|
25
|
+
* Typically used with {@link FusionAnalyticsAdapter} when the portal provides
|
|
26
|
+
* an HTTP client via service discovery.
|
|
27
|
+
*
|
|
28
|
+
* @example
|
|
29
|
+
* ```ts
|
|
30
|
+
* import { FusionOTLPLogExporter } from '@equinor/fusion-framework-module-analytics/logExporters';
|
|
31
|
+
*
|
|
32
|
+
* const httpClient = await serviceDiscovery.createClient('analytics');
|
|
33
|
+
* const exporter = new FusionOTLPLogExporter(httpClient);
|
|
34
|
+
* ```
|
|
16
35
|
*/
|
|
17
36
|
export class FusionOTLPLogExporter extends OTLPExporterBase {
|
|
37
|
+
/**
|
|
38
|
+
* @param httpClient - A Fusion `IHttpClient` used for outbound HTTP transport.
|
|
39
|
+
*/
|
|
18
40
|
constructor(httpClient) {
|
|
19
41
|
super(createOtlpNetworkExportDelegate(getSharedConfigurationDefaults(), JsonLogsSerializer, new HttpClientExporterTransport(httpClient)));
|
|
20
42
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FusionOTLPLogExporter.js","sourceRoot":"","sources":["../../../../src/logExporters/fusionOTLPLogExporter/FusionOTLPLogExporter.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,kBAAkB,EAAE,MAAM,iCAAiC,CAAC;AAErE,OAAO,EACL,+BAA+B,EAC/B,gBAAgB,GAEjB,MAAM,mCAAmC,CAAC;AAG3C,OAAO,EAAE,2BAA2B,EAAE,MAAM,kCAAkC,CAAC;AAE/E
|
|
1
|
+
{"version":3,"file":"FusionOTLPLogExporter.js","sourceRoot":"","sources":["../../../../src/logExporters/fusionOTLPLogExporter/FusionOTLPLogExporter.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,kBAAkB,EAAE,MAAM,iCAAiC,CAAC;AAErE,OAAO,EACL,+BAA+B,EAC/B,gBAAgB,GAEjB,MAAM,mCAAmC,CAAC;AAG3C,OAAO,EAAE,2BAA2B,EAAE,MAAM,kCAAkC,CAAC;AAE/E;;;;GAIG;AACH,SAAS,8BAA8B;IACrC,OAAO;QACL,aAAa,EAAE,KAAK;QACpB,gBAAgB,EAAE,EAAE;QACpB,WAAW,EAAE,MAAM;KACpB,CAAC;AACJ,CAAC;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,OAAO,qBACX,SAAQ,gBAAqC;IAG7C;;OAEG;IACH,YAAY,UAAuB;QACjC,KAAK,CACH,+BAA+B,CAC7B,8BAA8B,EAAE,EAChC,kBAAkB,EAClB,IAAI,2BAA2B,CAAC,UAAU,CAAC,CAC5C,CACF,CAAC;IACJ,CAAC;CACF"}
|
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Checks whether a failed HTTP status code is eligible for automatic retry.
|
|
3
|
+
*
|
|
4
|
+
* @param statusCode - HTTP response status code.
|
|
5
|
+
* @returns `true` for 429, 502, 503, and 504.
|
|
6
|
+
*/
|
|
1
7
|
function isExportRetryable(statusCode) {
|
|
2
8
|
// Status codes of when we should consider retrying.
|
|
3
9
|
// 429 Too Many Requests
|
|
@@ -7,7 +13,12 @@ function isExportRetryable(statusCode) {
|
|
|
7
13
|
const retryCodes = [429, 502, 503, 504];
|
|
8
14
|
return retryCodes.includes(statusCode);
|
|
9
15
|
}
|
|
10
|
-
|
|
16
|
+
/**
|
|
17
|
+
* Parses an HTTP `Retry-After` header value into milliseconds.
|
|
18
|
+
*
|
|
19
|
+
* @param retryAfter - Raw header value (integer seconds or HTTP-date).
|
|
20
|
+
* @returns Delay in milliseconds, `-1` for non-positive integers, or `undefined` if absent.
|
|
21
|
+
*/
|
|
11
22
|
function parseRetryAfterToMills(retryAfter) {
|
|
12
23
|
if (retryAfter == null) {
|
|
13
24
|
return undefined;
|
|
@@ -24,20 +35,37 @@ function parseRetryAfterToMills(retryAfter) {
|
|
|
24
35
|
return 0;
|
|
25
36
|
}
|
|
26
37
|
/**
|
|
27
|
-
*
|
|
38
|
+
* OpenTelemetry exporter transport that posts serialised log records using a
|
|
39
|
+
* Fusion `IHttpClient`.
|
|
40
|
+
*
|
|
41
|
+
* @remarks
|
|
42
|
+
* Implements `IExporterTransport` from `@opentelemetry/otlp-exporter-base`.
|
|
43
|
+
* The transport honours the exporter’s timeout via `AbortController` and
|
|
44
|
+
* inspects response status codes to report retryable failures (429, 502–504).
|
|
45
|
+
*
|
|
46
|
+
* @example
|
|
47
|
+
* ```ts
|
|
48
|
+
* const transport = new HttpClientExporterTransport(httpClient, '/v1/logs');
|
|
49
|
+
* ```
|
|
28
50
|
*/
|
|
29
51
|
export class HttpClientExporterTransport {
|
|
30
52
|
httpClient;
|
|
31
53
|
path;
|
|
54
|
+
/**
|
|
55
|
+
* @param httpClient - Fusion HTTP client for outgoing requests.
|
|
56
|
+
* @param path - URL path appended to the client’s base URL (default `'/v1/logs'`).
|
|
57
|
+
*/
|
|
32
58
|
constructor(httpClient, path = '/v1/logs') {
|
|
33
59
|
this.httpClient = httpClient;
|
|
34
60
|
this.path = path;
|
|
35
61
|
}
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
62
|
+
/**
|
|
63
|
+
* Sends serialised log record data to the configured endpoint.
|
|
64
|
+
*
|
|
65
|
+
* @param data - Serialised OTLP payload as a `Uint8Array`.
|
|
66
|
+
* @param timeoutMillis - Maximum time in milliseconds before the request is aborted.
|
|
67
|
+
* @returns An `ExportResponse` indicating success, retryable failure, or permanent failure.
|
|
68
|
+
*/
|
|
41
69
|
async send(data, timeoutMillis) {
|
|
42
70
|
const abortController = new AbortController();
|
|
43
71
|
const timeout = setTimeout(() => abortController.abort(), timeoutMillis);
|
|
@@ -77,6 +105,7 @@ export class HttpClientExporterTransport {
|
|
|
77
105
|
clearTimeout(timeout);
|
|
78
106
|
}
|
|
79
107
|
}
|
|
108
|
+
/** No-op; the HTTP client does not hold persistent connections. */
|
|
80
109
|
shutdown() {
|
|
81
110
|
// intentionally left empty, nothing to do.
|
|
82
111
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"HttpClientExporterTransport.js","sourceRoot":"","sources":["../../../../src/logExporters/fusionOTLPLogExporter/HttpClientExporterTransport.ts"],"names":[],"mappings":"AAIA,SAAS,iBAAiB,CAAC,UAAkB;IAC3C,oDAAoD;IACpD,wBAAwB;IACxB,kBAAkB;IAClB,0BAA0B;IAC1B,sBAAsB;IACtB,MAAM,UAAU,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;IACxC,OAAO,UAAU,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC;AACzC,CAAC;AAED
|
|
1
|
+
{"version":3,"file":"HttpClientExporterTransport.js","sourceRoot":"","sources":["../../../../src/logExporters/fusionOTLPLogExporter/HttpClientExporterTransport.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,3 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Re-exports for OTLP log exporters used by analytics adapters.
|
|
3
|
+
*
|
|
4
|
+
* @remarks
|
|
5
|
+
* Import from `'@equinor/fusion-framework-module-analytics/logExporters'`.
|
|
6
|
+
*
|
|
7
|
+
* @packageDocumentation
|
|
8
|
+
*/
|
|
1
9
|
export { FusionOTLPLogExporter } from './fusionOTLPLogExporter/FusionOTLPLogExporter.js';
|
|
2
10
|
export { OTLPLogExporter } from '@opentelemetry/exporter-logs-otlp-http';
|
|
3
11
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/logExporters/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,MAAM,kDAAkD,CAAC;AACzF,OAAO,EAAE,eAAe,EAAE,MAAM,wCAAwC,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/logExporters/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EAAE,qBAAqB,EAAE,MAAM,kDAAkD,CAAC;AACzF,OAAO,EAAE,eAAe,EAAE,MAAM,wCAAwC,CAAC"}
|