@fluidframework/fluid-telemetry 2.0.0-dev-rc.5.0.0.268409 → 2.0.0-dev-rc.5.0.0.270987

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/biome.jsonc ADDED
@@ -0,0 +1,4 @@
1
+ {
2
+ "$schema": "./node_modules/@biomejs/biome/configuration_schema.json",
3
+ "extends": ["../../../../biome.jsonc"]
4
+ }
@@ -12,6 +12,7 @@ exports.AppInsightsTelemetryConsumer = void 0;
12
12
  * @beta
13
13
  */
14
14
  class AppInsightsTelemetryConsumer {
15
+ appInsightsClient;
15
16
  constructor(appInsightsClient) {
16
17
  this.appInsightsClient = appInsightsClient;
17
18
  }
@@ -1 +1 @@
1
- {"version":3,"file":"appInsightsTelemetryConsumer.js","sourceRoot":"","sources":["../../src/app-insights/appInsightsTelemetryConsumer.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAMH;;;;;GAKG;AACH,MAAa,4BAA4B;IACxC,YAAoC,iBAAsC;QAAtC,sBAAiB,GAAjB,iBAAiB,CAAqB;IAAG,CAAC;IAE9E;;OAEG;IACI,OAAO,CAAC,KAAsB;QACpC,IAAI,CAAC,iBAAiB,CAAC,UAAU,CAAC;YACjC,IAAI,EAAE,KAAK,CAAC,SAAS;YACrB,UAAU,EAAE,KAAK;SACjB,CAAC,CAAC;IACJ,CAAC;CACD;AAZD,oEAYC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { type ApplicationInsights } from \"@microsoft/applicationinsights-web\";\n\nimport type { IFluidTelemetry, ITelemetryConsumer } from \"../common/index.js\";\n\n/**\n * An implementation of {@link ITelemetryConsumer} that routes {@link IFluidTelemetry} to Azure App Insights\n * in a format that is supported by Fluid Framework service offerings such as Cloud dashboards and alarms.\n *\n * @beta\n */\nexport class AppInsightsTelemetryConsumer implements ITelemetryConsumer {\n\tpublic constructor(private readonly appInsightsClient: ApplicationInsights) {}\n\n\t/**\n\t * Takes the incoming {@link IFluidTelemetry} and sends it to Azure App Insights\n\t */\n\tpublic consume(event: IFluidTelemetry): void {\n\t\tthis.appInsightsClient.trackEvent({\n\t\t\tname: event.eventName,\n\t\t\tproperties: event,\n\t\t});\n\t}\n}\n"]}
1
+ {"version":3,"file":"appInsightsTelemetryConsumer.js","sourceRoot":"","sources":["../../src/app-insights/appInsightsTelemetryConsumer.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAMH;;;;;GAKG;AACH,MAAa,4BAA4B;IACJ;IAApC,YAAoC,iBAAsC;QAAtC,sBAAiB,GAAjB,iBAAiB,CAAqB;IAAG,CAAC;IAE9E;;OAEG;IACI,OAAO,CAAC,KAAsB;QACpC,IAAI,CAAC,iBAAiB,CAAC,UAAU,CAAC;YACjC,IAAI,EAAE,KAAK,CAAC,SAAS;YACrB,UAAU,EAAE,KAAK;SACjB,CAAC,CAAC;IACJ,CAAC;CACD;AAZD,oEAYC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { type ApplicationInsights } from \"@microsoft/applicationinsights-web\";\n\nimport type { IFluidTelemetry, ITelemetryConsumer } from \"../common/index.js\";\n\n/**\n * An implementation of {@link ITelemetryConsumer} that routes {@link IFluidTelemetry} to Azure App Insights\n * in a format that is supported by Fluid Framework service offerings such as Cloud dashboards and alarms.\n *\n * @beta\n */\nexport class AppInsightsTelemetryConsumer implements ITelemetryConsumer {\n\tpublic constructor(private readonly appInsightsClient: ApplicationInsights) {}\n\n\t/**\n\t * Takes the incoming {@link IFluidTelemetry} and sends it to Azure App Insights\n\t */\n\tpublic consume(event: IFluidTelemetry): void {\n\t\tthis.appInsightsClient.trackEvent({\n\t\t\tname: event.eventName,\n\t\t\tproperties: event,\n\t\t});\n\t}\n}\n"]}
@@ -13,6 +13,10 @@ const containerSystemEvents_js_1 = require("./containerSystemEvents.js");
13
13
  * to be transformed into {@link IContainerTelemetry} and finally sending them to the provided {@link ITelemetryConsumer}
14
14
  */
15
15
  class ContainerTelemetryManager {
16
+ container;
17
+ telemetryProducer;
18
+ telemetryConsumers;
19
+ static HEARTBEAT_EMISSION_INTERNAL_MS = 60000;
16
20
  constructor(container, telemetryProducer, telemetryConsumers) {
17
21
  this.container = container;
18
22
  this.telemetryProducer = telemetryProducer;
@@ -58,5 +62,4 @@ class ContainerTelemetryManager {
58
62
  }
59
63
  }
60
64
  exports.ContainerTelemetryManager = ContainerTelemetryManager;
61
- ContainerTelemetryManager.HEARTBEAT_EMISSION_INTERNAL_MS = 60000;
62
65
  //# sourceMappingURL=telemetryManager.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"telemetryManager.js","sourceRoot":"","sources":["../../src/container/telemetryManager.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAGH,uEAAmE;AAKnE,yEAGoC;AAIpC;;;;GAIG;AACH,MAAa,yBAAyB;IAGrC,YACkB,SAA0B,EAC1B,iBAAkD,EAClD,kBAAwC;QAFxC,cAAS,GAAT,SAAS,CAAiB;QAC1B,sBAAiB,GAAjB,iBAAiB,CAAiC;QAClD,uBAAkB,GAAlB,kBAAkB,CAAsB;QAEzD,IAAI,CAAC,kBAAkB,EAAE,CAAC;QAC1B,IAAI,CAAC,+BAA+B,EAAE,CAAC;IACxC,CAAC;IAED;;OAEG;IACK,kBAAkB;QACzB,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,0DAA+B,CAAC,SAAS,EAAE,GAAG,EAAE,CACjE,IAAI,CAAC,0BAA0B,CAAC,0DAA+B,CAAC,SAAS,CAAC,CAC1E,CAAC;QACF,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,0DAA+B,CAAC,YAAY,EAAE,GAAG,EAAE,CACpE,IAAI,CAAC,0BAA0B,CAAC,0DAA+B,CAAC,YAAY,CAAC,CAC7E,CAAC;QACF,IAAI,CAAC,SAAS,CAAC,EAAE,CAChB,0DAA+B,CAAC,QAAQ,EACxC,CAAC,KAA+B,EAAE,EAAE,CACnC,IAAI,CAAC,0BAA0B,CAAC,0DAA+B,CAAC,QAAQ,EAAE;YACzE,KAAK;SACL,CAAC,CACH,CAAC;IACH,CAAC;IAED;;;OAGG;IACK,+BAA+B;QACtC,WAAW,CAAC,GAAG,EAAE;YAChB,IAAI,IAAI,CAAC,SAAS,CAAC,eAAe,KAAK,kCAAe,CAAC,SAAS,EAAE,CAAC;gBAClE,MAAM,SAAS,GAAG,IAAI,CAAC,iBAAiB,CAAC,yBAAyB,EAAE,CAAC;gBACrE,KAAK,MAAM,QAAQ,IAAI,IAAI,CAAC,kBAAkB,EAAE,CAAC;oBAChD,QAAQ,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;gBAC7B,CAAC;YACF,CAAC;QACF,CAAC,EAAE,yBAAyB,CAAC,8BAA8B,CAAC,CAAC;IAC9D,CAAC;IAED;;;OAGG;IACK,0BAA0B,CACjC,SAAyC,EACzC,OAAiB;QAEjB,MAAM,SAAS,GACd,IAAI,CAAC,iBAAiB,CAAC,sBAAsB,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;QAEnE,IAAI,SAAS,KAAK,SAAS,EAAE,CAAC;YAC7B,KAAK,MAAM,QAAQ,IAAI,IAAI,CAAC,kBAAkB,EAAE,CAAC;gBAChD,QAAQ,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;YAC7B,CAAC;QACF,CAAC;IACF,CAAC;;AA9DF,8DA+DC;AA9DwB,wDAA8B,GAAG,KAAK,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { type ICriticalContainerError } from \"@fluidframework/container-definitions\";\nimport { ConnectionState } from \"@fluidframework/container-loader\";\nimport type { IFluidContainer } from \"@fluidframework/fluid-static\";\n\nimport { type ITelemetryConsumer } from \"../common/index.js\";\n\nimport {\n\ttype IFluidContainerSystemEventName,\n\tIFluidContainerSystemEventNames,\n} from \"./containerSystemEvents.js\";\nimport { type IContainerTelemetry } from \"./containerTelemetry.js\";\nimport type { ContainerEventTelemetryProducer } from \"./telemetryProducer.js\";\n\n/**\n * This class manages container telemetry intended for customers to consume by wiring together the provided container system events, telemetry producers and consumers together.\n * It manages subcribing to the proper raw container system events, sending them to the {@link ContainerEventTelemetryProducer}\n * to be transformed into {@link IContainerTelemetry} and finally sending them to the provided {@link ITelemetryConsumer}\n */\nexport class ContainerTelemetryManager {\n\tprivate static readonly HEARTBEAT_EMISSION_INTERNAL_MS = 60000;\n\n\tpublic constructor(\n\t\tprivate readonly container: IFluidContainer,\n\t\tprivate readonly telemetryProducer: ContainerEventTelemetryProducer,\n\t\tprivate readonly telemetryConsumers: ITelemetryConsumer[],\n\t) {\n\t\tthis.setupEventHandlers();\n\t\tthis.setupHeartbeatTelemetryEmission();\n\t}\n\n\t/**\n\t * Subscribes to the raw container system events and routes them to telemetry producers.\n\t */\n\tprivate setupEventHandlers(): void {\n\t\tthis.container.on(IFluidContainerSystemEventNames.CONNECTED, () =>\n\t\t\tthis.handleContainerSystemEvent(IFluidContainerSystemEventNames.CONNECTED),\n\t\t);\n\t\tthis.container.on(IFluidContainerSystemEventNames.DISCONNECTED, () =>\n\t\t\tthis.handleContainerSystemEvent(IFluidContainerSystemEventNames.DISCONNECTED),\n\t\t);\n\t\tthis.container.on(\n\t\t\tIFluidContainerSystemEventNames.DISPOSED,\n\t\t\t(error?: ICriticalContainerError) =>\n\t\t\t\tthis.handleContainerSystemEvent(IFluidContainerSystemEventNames.DISPOSED, {\n\t\t\t\t\terror,\n\t\t\t\t}),\n\t\t);\n\t}\n\n\t/**\n\t * Sets up the synthetic telemetry event for the container heartbeat telemetry to be emitted on a given time interval\n\t * if and only if the container is in a \"connected\" state. It is used to keep a pulse check on a live container\n\t */\n\tprivate setupHeartbeatTelemetryEmission(): void {\n\t\tsetInterval(() => {\n\t\t\tif (this.container.connectionState === ConnectionState.Connected) {\n\t\t\t\tconst telemetry = this.telemetryProducer.produceHeartbeatTelemetry();\n\t\t\t\tfor (const consumer of this.telemetryConsumers) {\n\t\t\t\t\tconsumer.consume(telemetry);\n\t\t\t\t}\n\t\t\t}\n\t\t}, ContainerTelemetryManager.HEARTBEAT_EMISSION_INTERNAL_MS);\n\t}\n\n\t/**\n\t * Handles the incoming raw container sysytem event, sending it to the {@link ContainerEventTelemetryProducer} to\n\t * produce {@link IContainerTelemetry} and sending it to the {@link ITelemetryConsumer} to be consumed.\n\t */\n\tprivate handleContainerSystemEvent(\n\t\teventName: IFluidContainerSystemEventName,\n\t\tpayload?: unknown,\n\t): void {\n\t\tconst telemetry: IContainerTelemetry | undefined =\n\t\t\tthis.telemetryProducer.produceFromSystemEvent(eventName, payload);\n\n\t\tif (telemetry !== undefined) {\n\t\t\tfor (const consumer of this.telemetryConsumers) {\n\t\t\t\tconsumer.consume(telemetry);\n\t\t\t}\n\t\t}\n\t}\n}\n"]}
1
+ {"version":3,"file":"telemetryManager.js","sourceRoot":"","sources":["../../src/container/telemetryManager.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAGH,uEAAmE;AAKnE,yEAGoC;AAIpC;;;;GAIG;AACH,MAAa,yBAAyB;IAInB;IACA;IACA;IALV,MAAM,CAAU,8BAA8B,GAAG,KAAK,CAAC;IAE/D,YACkB,SAA0B,EAC1B,iBAAkD,EAClD,kBAAwC;QAFxC,cAAS,GAAT,SAAS,CAAiB;QAC1B,sBAAiB,GAAjB,iBAAiB,CAAiC;QAClD,uBAAkB,GAAlB,kBAAkB,CAAsB;QAEzD,IAAI,CAAC,kBAAkB,EAAE,CAAC;QAC1B,IAAI,CAAC,+BAA+B,EAAE,CAAC;IACxC,CAAC;IAED;;OAEG;IACK,kBAAkB;QACzB,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,0DAA+B,CAAC,SAAS,EAAE,GAAG,EAAE,CACjE,IAAI,CAAC,0BAA0B,CAAC,0DAA+B,CAAC,SAAS,CAAC,CAC1E,CAAC;QACF,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,0DAA+B,CAAC,YAAY,EAAE,GAAG,EAAE,CACpE,IAAI,CAAC,0BAA0B,CAAC,0DAA+B,CAAC,YAAY,CAAC,CAC7E,CAAC;QACF,IAAI,CAAC,SAAS,CAAC,EAAE,CAChB,0DAA+B,CAAC,QAAQ,EACxC,CAAC,KAA+B,EAAE,EAAE,CACnC,IAAI,CAAC,0BAA0B,CAAC,0DAA+B,CAAC,QAAQ,EAAE;YACzE,KAAK;SACL,CAAC,CACH,CAAC;IACH,CAAC;IAED;;;OAGG;IACK,+BAA+B;QACtC,WAAW,CAAC,GAAG,EAAE;YAChB,IAAI,IAAI,CAAC,SAAS,CAAC,eAAe,KAAK,kCAAe,CAAC,SAAS,EAAE,CAAC;gBAClE,MAAM,SAAS,GAAG,IAAI,CAAC,iBAAiB,CAAC,yBAAyB,EAAE,CAAC;gBACrE,KAAK,MAAM,QAAQ,IAAI,IAAI,CAAC,kBAAkB,EAAE,CAAC;oBAChD,QAAQ,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;gBAC7B,CAAC;YACF,CAAC;QACF,CAAC,EAAE,yBAAyB,CAAC,8BAA8B,CAAC,CAAC;IAC9D,CAAC;IAED;;;OAGG;IACK,0BAA0B,CACjC,SAAyC,EACzC,OAAiB;QAEjB,MAAM,SAAS,GACd,IAAI,CAAC,iBAAiB,CAAC,sBAAsB,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;QAEnE,IAAI,SAAS,KAAK,SAAS,EAAE,CAAC;YAC7B,KAAK,MAAM,QAAQ,IAAI,IAAI,CAAC,kBAAkB,EAAE,CAAC;gBAChD,QAAQ,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;YAC7B,CAAC;QACF,CAAC;IACF,CAAC;;AA9DF,8DA+DC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { type ICriticalContainerError } from \"@fluidframework/container-definitions\";\nimport { ConnectionState } from \"@fluidframework/container-loader\";\nimport type { IFluidContainer } from \"@fluidframework/fluid-static\";\n\nimport { type ITelemetryConsumer } from \"../common/index.js\";\n\nimport {\n\ttype IFluidContainerSystemEventName,\n\tIFluidContainerSystemEventNames,\n} from \"./containerSystemEvents.js\";\nimport { type IContainerTelemetry } from \"./containerTelemetry.js\";\nimport type { ContainerEventTelemetryProducer } from \"./telemetryProducer.js\";\n\n/**\n * This class manages container telemetry intended for customers to consume by wiring together the provided container system events, telemetry producers and consumers together.\n * It manages subcribing to the proper raw container system events, sending them to the {@link ContainerEventTelemetryProducer}\n * to be transformed into {@link IContainerTelemetry} and finally sending them to the provided {@link ITelemetryConsumer}\n */\nexport class ContainerTelemetryManager {\n\tprivate static readonly HEARTBEAT_EMISSION_INTERNAL_MS = 60000;\n\n\tpublic constructor(\n\t\tprivate readonly container: IFluidContainer,\n\t\tprivate readonly telemetryProducer: ContainerEventTelemetryProducer,\n\t\tprivate readonly telemetryConsumers: ITelemetryConsumer[],\n\t) {\n\t\tthis.setupEventHandlers();\n\t\tthis.setupHeartbeatTelemetryEmission();\n\t}\n\n\t/**\n\t * Subscribes to the raw container system events and routes them to telemetry producers.\n\t */\n\tprivate setupEventHandlers(): void {\n\t\tthis.container.on(IFluidContainerSystemEventNames.CONNECTED, () =>\n\t\t\tthis.handleContainerSystemEvent(IFluidContainerSystemEventNames.CONNECTED),\n\t\t);\n\t\tthis.container.on(IFluidContainerSystemEventNames.DISCONNECTED, () =>\n\t\t\tthis.handleContainerSystemEvent(IFluidContainerSystemEventNames.DISCONNECTED),\n\t\t);\n\t\tthis.container.on(\n\t\t\tIFluidContainerSystemEventNames.DISPOSED,\n\t\t\t(error?: ICriticalContainerError) =>\n\t\t\t\tthis.handleContainerSystemEvent(IFluidContainerSystemEventNames.DISPOSED, {\n\t\t\t\t\terror,\n\t\t\t\t}),\n\t\t);\n\t}\n\n\t/**\n\t * Sets up the synthetic telemetry event for the container heartbeat telemetry to be emitted on a given time interval\n\t * if and only if the container is in a \"connected\" state. It is used to keep a pulse check on a live container\n\t */\n\tprivate setupHeartbeatTelemetryEmission(): void {\n\t\tsetInterval(() => {\n\t\t\tif (this.container.connectionState === ConnectionState.Connected) {\n\t\t\t\tconst telemetry = this.telemetryProducer.produceHeartbeatTelemetry();\n\t\t\t\tfor (const consumer of this.telemetryConsumers) {\n\t\t\t\t\tconsumer.consume(telemetry);\n\t\t\t\t}\n\t\t\t}\n\t\t}, ContainerTelemetryManager.HEARTBEAT_EMISSION_INTERNAL_MS);\n\t}\n\n\t/**\n\t * Handles the incoming raw container sysytem event, sending it to the {@link ContainerEventTelemetryProducer} to\n\t * produce {@link IContainerTelemetry} and sending it to the {@link ITelemetryConsumer} to be consumed.\n\t */\n\tprivate handleContainerSystemEvent(\n\t\teventName: IFluidContainerSystemEventName,\n\t\tpayload?: unknown,\n\t): void {\n\t\tconst telemetry: IContainerTelemetry | undefined =\n\t\t\tthis.telemetryProducer.produceFromSystemEvent(eventName, payload);\n\n\t\tif (telemetry !== undefined) {\n\t\t\tfor (const consumer of this.telemetryConsumers) {\n\t\t\t\tconsumer.consume(telemetry);\n\t\t\t}\n\t\t}\n\t}\n}\n"]}
@@ -14,37 +14,13 @@ const containerTelemetry_js_1 = require("./containerTelemetry.js");
14
14
  * to produce different {@link IContainerTelemetry}.
15
15
  */
16
16
  class ContainerEventTelemetryProducer {
17
+ containerId;
18
+ /**
19
+ * Unique identifier for the instance of the container that this class is generating telemetry for.
20
+ */
21
+ containerInstanceId = (0, uuid_1.v4)();
17
22
  constructor(containerId) {
18
23
  this.containerId = containerId;
19
- /**
20
- * Unique identifier for the instance of the container that this class is generating telemetry for.
21
- */
22
- this.containerInstanceId = (0, uuid_1.v4)();
23
- this.produceHeartbeatTelemetry = () => {
24
- return {
25
- eventName: "fluidframework.container.heartbeat",
26
- containerId: this.containerId,
27
- containerInstanceId: this.containerInstanceId,
28
- };
29
- };
30
- this.produceBaseContainerTelemetry = (eventName) => {
31
- return {
32
- eventName,
33
- containerId: this.containerId,
34
- containerInstanceId: this.containerInstanceId,
35
- };
36
- };
37
- this.produceDiposedTelemetry = (payload) => {
38
- const telemetry = {
39
- eventName: containerTelemetry_js_1.ContainerTelemetryEventNames.DISPOSED,
40
- containerId: this.containerId,
41
- containerInstanceId: this.containerInstanceId,
42
- };
43
- if (payload?.error !== undefined) {
44
- telemetry.error = payload.error;
45
- }
46
- return telemetry;
47
- };
48
24
  }
49
25
  produceFromSystemEvent(eventName, payload) {
50
26
  switch (eventName) {
@@ -63,6 +39,31 @@ class ContainerEventTelemetryProducer {
63
39
  }
64
40
  }
65
41
  }
42
+ produceHeartbeatTelemetry = () => {
43
+ return {
44
+ eventName: "fluidframework.container.heartbeat",
45
+ containerId: this.containerId,
46
+ containerInstanceId: this.containerInstanceId,
47
+ };
48
+ };
49
+ produceBaseContainerTelemetry = (eventName) => {
50
+ return {
51
+ eventName,
52
+ containerId: this.containerId,
53
+ containerInstanceId: this.containerInstanceId,
54
+ };
55
+ };
56
+ produceDiposedTelemetry = (payload) => {
57
+ const telemetry = {
58
+ eventName: containerTelemetry_js_1.ContainerTelemetryEventNames.DISPOSED,
59
+ containerId: this.containerId,
60
+ containerInstanceId: this.containerInstanceId,
61
+ };
62
+ if (payload?.error !== undefined) {
63
+ telemetry.error = payload.error;
64
+ }
65
+ return telemetry;
66
+ };
66
67
  }
67
68
  exports.ContainerEventTelemetryProducer = ContainerEventTelemetryProducer;
68
69
  //# sourceMappingURL=telemetryProducer.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"telemetryProducer.js","sourceRoot":"","sources":["../../src/container/telemetryProducer.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAGH,+BAAkC;AAIlC,yEAGoC;AACpC,mEAKiC;AAEjC;;;;GAIG;AACH,MAAa,+BAA+B;IAM3C,YAAoC,WAAmB;QAAnB,gBAAW,GAAX,WAAW,CAAQ;QALvD;;WAEG;QACc,wBAAmB,GAAG,IAAA,SAAI,GAAE,CAAC;QA2BvC,8BAAyB,GAAG,GAAoB,EAAE;YACxD,OAAO;gBACN,SAAS,EAAE,oCAAoC;gBAC/C,WAAW,EAAE,IAAI,CAAC,WAAW;gBAC7B,mBAAmB,EAAE,IAAI,CAAC,mBAAmB;aACf,CAAC;QACjC,CAAC,CAAC;QAEe,kCAA6B,GAAG,CAChD,SAAsC,EAChB,EAAE;YACxB,OAAO;gBACN,SAAS;gBACT,WAAW,EAAE,IAAI,CAAC,WAAW;gBAC7B,mBAAmB,EAAE,IAAI,CAAC,mBAAmB;aACf,CAAC;QACjC,CAAC,CAAC;QAEe,4BAAuB,GAAG,CAAC,OAE3C,EAA8B,EAAE;YAChC,MAAM,SAAS,GAA+B;gBAC7C,SAAS,EAAE,oDAA4B,CAAC,QAAQ;gBAChD,WAAW,EAAE,IAAI,CAAC,WAAW;gBAC7B,mBAAmB,EAAE,IAAI,CAAC,mBAAmB;aAC7C,CAAC;YACF,IAAI,OAAO,EAAE,KAAK,KAAK,SAAS,EAAE,CAAC;gBAClC,SAAS,CAAC,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC;YACjC,CAAC;YACD,OAAO,SAAS,CAAC;QAClB,CAAC,CAAC;IAvDwD,CAAC;IAEpD,sBAAsB,CAC5B,SAAyC,EACzC,OAAiB;QAEjB,QAAQ,SAAS,EAAE,CAAC;YACnB,KAAK,0DAA+B,CAAC,SAAS,CAAC,CAAC,CAAC;gBAChD,OAAO,IAAI,CAAC,6BAA6B,CAAC,oDAA4B,CAAC,SAAS,CAAC,CAAC;YACnF,CAAC;YACD,KAAK,0DAA+B,CAAC,YAAY,CAAC,CAAC,CAAC;gBACnD,OAAO,IAAI,CAAC,6BAA6B,CACxC,oDAA4B,CAAC,YAAY,CACzC,CAAC;YACH,CAAC;YACD,KAAK,0DAA+B,CAAC,QAAQ,CAAC,CAAC,CAAC;gBAC/C,MAAM,YAAY,GAAG,OAA8C,CAAC;gBACpE,OAAO,IAAI,CAAC,uBAAuB,CAAC,YAAY,CAAC,CAAC;YACnD,CAAC;YACD,OAAO,CAAC,CAAC,CAAC;gBACT,MAAM;YACP,CAAC;QACF,CAAC;IACF,CAAC;CAiCD;AA9DD,0EA8DC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { type ICriticalContainerError } from \"@fluidframework/container-definitions\";\nimport { v4 as uuid } from \"uuid\";\n\nimport type { IFluidTelemetry } from \"../index.js\";\n\nimport {\n\ttype IFluidContainerSystemEventName,\n\tIFluidContainerSystemEventNames,\n} from \"./containerSystemEvents.js\";\nimport {\n\tContainerTelemetryEventNames,\n\ttype ContainerTelemetryEventName,\n\ttype IContainerTelemetry,\n\ttype ContainerDisposedTelemetry,\n} from \"./containerTelemetry.js\";\n\n/**\n * This class produces {@link IContainerTelemetry} from raw container system events {@link @fluidframework/fluid-static#IFluidContainerEvents}.\n * The class contains different helper methods for simplifying and standardizing logic for adding additional information necessary\n * to produce different {@link IContainerTelemetry}.\n */\nexport class ContainerEventTelemetryProducer {\n\t/**\n\t * Unique identifier for the instance of the container that this class is generating telemetry for.\n\t */\n\tprivate readonly containerInstanceId = uuid();\n\n\tpublic constructor(private readonly containerId: string) {}\n\n\tpublic produceFromSystemEvent(\n\t\teventName: IFluidContainerSystemEventName,\n\t\tpayload?: unknown,\n\t): IContainerTelemetry | undefined {\n\t\tswitch (eventName) {\n\t\t\tcase IFluidContainerSystemEventNames.CONNECTED: {\n\t\t\t\treturn this.produceBaseContainerTelemetry(ContainerTelemetryEventNames.CONNECTED);\n\t\t\t}\n\t\t\tcase IFluidContainerSystemEventNames.DISCONNECTED: {\n\t\t\t\treturn this.produceBaseContainerTelemetry(\n\t\t\t\t\tContainerTelemetryEventNames.DISCONNECTED,\n\t\t\t\t);\n\t\t\t}\n\t\t\tcase IFluidContainerSystemEventNames.DISPOSED: {\n\t\t\t\tconst typedPayload = payload as { error?: ICriticalContainerError };\n\t\t\t\treturn this.produceDiposedTelemetry(typedPayload);\n\t\t\t}\n\t\t\tdefault: {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\n\tpublic produceHeartbeatTelemetry = (): IFluidTelemetry => {\n\t\treturn {\n\t\t\teventName: \"fluidframework.container.heartbeat\",\n\t\t\tcontainerId: this.containerId,\n\t\t\tcontainerInstanceId: this.containerInstanceId,\n\t\t} as unknown as IFluidTelemetry;\n\t};\n\n\tprivate readonly produceBaseContainerTelemetry = (\n\t\teventName: ContainerTelemetryEventName,\n\t): IContainerTelemetry => {\n\t\treturn {\n\t\t\teventName,\n\t\t\tcontainerId: this.containerId,\n\t\t\tcontainerInstanceId: this.containerInstanceId,\n\t\t} satisfies IContainerTelemetry;\n\t};\n\n\tprivate readonly produceDiposedTelemetry = (payload?: {\n\t\terror?: ICriticalContainerError;\n\t}): ContainerDisposedTelemetry => {\n\t\tconst telemetry: ContainerDisposedTelemetry = {\n\t\t\teventName: ContainerTelemetryEventNames.DISPOSED,\n\t\t\tcontainerId: this.containerId,\n\t\t\tcontainerInstanceId: this.containerInstanceId,\n\t\t};\n\t\tif (payload?.error !== undefined) {\n\t\t\ttelemetry.error = payload.error;\n\t\t}\n\t\treturn telemetry;\n\t};\n}\n"]}
1
+ {"version":3,"file":"telemetryProducer.js","sourceRoot":"","sources":["../../src/container/telemetryProducer.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAGH,+BAAkC;AAIlC,yEAGoC;AACpC,mEAKiC;AAEjC;;;;GAIG;AACH,MAAa,+BAA+B;IAMP;IALpC;;OAEG;IACc,mBAAmB,GAAG,IAAA,SAAI,GAAE,CAAC;IAE9C,YAAoC,WAAmB;QAAnB,gBAAW,GAAX,WAAW,CAAQ;IAAG,CAAC;IAEpD,sBAAsB,CAC5B,SAAyC,EACzC,OAAiB;QAEjB,QAAQ,SAAS,EAAE,CAAC;YACnB,KAAK,0DAA+B,CAAC,SAAS,CAAC,CAAC,CAAC;gBAChD,OAAO,IAAI,CAAC,6BAA6B,CAAC,oDAA4B,CAAC,SAAS,CAAC,CAAC;YACnF,CAAC;YACD,KAAK,0DAA+B,CAAC,YAAY,CAAC,CAAC,CAAC;gBACnD,OAAO,IAAI,CAAC,6BAA6B,CACxC,oDAA4B,CAAC,YAAY,CACzC,CAAC;YACH,CAAC;YACD,KAAK,0DAA+B,CAAC,QAAQ,CAAC,CAAC,CAAC;gBAC/C,MAAM,YAAY,GAAG,OAA8C,CAAC;gBACpE,OAAO,IAAI,CAAC,uBAAuB,CAAC,YAAY,CAAC,CAAC;YACnD,CAAC;YACD,OAAO,CAAC,CAAC,CAAC;gBACT,MAAM;YACP,CAAC;QACF,CAAC;IACF,CAAC;IAEM,yBAAyB,GAAG,GAAoB,EAAE;QACxD,OAAO;YACN,SAAS,EAAE,oCAAoC;YAC/C,WAAW,EAAE,IAAI,CAAC,WAAW;YAC7B,mBAAmB,EAAE,IAAI,CAAC,mBAAmB;SACf,CAAC;IACjC,CAAC,CAAC;IAEe,6BAA6B,GAAG,CAChD,SAAsC,EAChB,EAAE;QACxB,OAAO;YACN,SAAS;YACT,WAAW,EAAE,IAAI,CAAC,WAAW;YAC7B,mBAAmB,EAAE,IAAI,CAAC,mBAAmB;SACf,CAAC;IACjC,CAAC,CAAC;IAEe,uBAAuB,GAAG,CAAC,OAE3C,EAA8B,EAAE;QAChC,MAAM,SAAS,GAA+B;YAC7C,SAAS,EAAE,oDAA4B,CAAC,QAAQ;YAChD,WAAW,EAAE,IAAI,CAAC,WAAW;YAC7B,mBAAmB,EAAE,IAAI,CAAC,mBAAmB;SAC7C,CAAC;QACF,IAAI,OAAO,EAAE,KAAK,KAAK,SAAS,EAAE,CAAC;YAClC,SAAS,CAAC,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC;QACjC,CAAC;QACD,OAAO,SAAS,CAAC;IAClB,CAAC,CAAC;CACF;AA9DD,0EA8DC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { type ICriticalContainerError } from \"@fluidframework/container-definitions\";\nimport { v4 as uuid } from \"uuid\";\n\nimport type { IFluidTelemetry } from \"../index.js\";\n\nimport {\n\ttype IFluidContainerSystemEventName,\n\tIFluidContainerSystemEventNames,\n} from \"./containerSystemEvents.js\";\nimport {\n\tContainerTelemetryEventNames,\n\ttype ContainerTelemetryEventName,\n\ttype IContainerTelemetry,\n\ttype ContainerDisposedTelemetry,\n} from \"./containerTelemetry.js\";\n\n/**\n * This class produces {@link IContainerTelemetry} from raw container system events {@link @fluidframework/fluid-static#IFluidContainerEvents}.\n * The class contains different helper methods for simplifying and standardizing logic for adding additional information necessary\n * to produce different {@link IContainerTelemetry}.\n */\nexport class ContainerEventTelemetryProducer {\n\t/**\n\t * Unique identifier for the instance of the container that this class is generating telemetry for.\n\t */\n\tprivate readonly containerInstanceId = uuid();\n\n\tpublic constructor(private readonly containerId: string) {}\n\n\tpublic produceFromSystemEvent(\n\t\teventName: IFluidContainerSystemEventName,\n\t\tpayload?: unknown,\n\t): IContainerTelemetry | undefined {\n\t\tswitch (eventName) {\n\t\t\tcase IFluidContainerSystemEventNames.CONNECTED: {\n\t\t\t\treturn this.produceBaseContainerTelemetry(ContainerTelemetryEventNames.CONNECTED);\n\t\t\t}\n\t\t\tcase IFluidContainerSystemEventNames.DISCONNECTED: {\n\t\t\t\treturn this.produceBaseContainerTelemetry(\n\t\t\t\t\tContainerTelemetryEventNames.DISCONNECTED,\n\t\t\t\t);\n\t\t\t}\n\t\t\tcase IFluidContainerSystemEventNames.DISPOSED: {\n\t\t\t\tconst typedPayload = payload as { error?: ICriticalContainerError };\n\t\t\t\treturn this.produceDiposedTelemetry(typedPayload);\n\t\t\t}\n\t\t\tdefault: {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\n\tpublic produceHeartbeatTelemetry = (): IFluidTelemetry => {\n\t\treturn {\n\t\t\teventName: \"fluidframework.container.heartbeat\",\n\t\t\tcontainerId: this.containerId,\n\t\t\tcontainerInstanceId: this.containerInstanceId,\n\t\t} as unknown as IFluidTelemetry;\n\t};\n\n\tprivate readonly produceBaseContainerTelemetry = (\n\t\teventName: ContainerTelemetryEventName,\n\t): IContainerTelemetry => {\n\t\treturn {\n\t\t\teventName,\n\t\t\tcontainerId: this.containerId,\n\t\t\tcontainerInstanceId: this.containerInstanceId,\n\t\t} satisfies IContainerTelemetry;\n\t};\n\n\tprivate readonly produceDiposedTelemetry = (payload?: {\n\t\terror?: ICriticalContainerError;\n\t}): ContainerDisposedTelemetry => {\n\t\tconst telemetry: ContainerDisposedTelemetry = {\n\t\t\teventName: ContainerTelemetryEventNames.DISPOSED,\n\t\t\tcontainerId: this.containerId,\n\t\t\tcontainerInstanceId: this.containerInstanceId,\n\t\t};\n\t\tif (payload?.error !== undefined) {\n\t\t\ttelemetry.error = payload.error;\n\t\t}\n\t\treturn telemetry;\n\t};\n}\n"]}
package/dist/legacy.d.ts CHANGED
@@ -10,19 +10,5 @@
10
10
 
11
11
  export {
12
12
  // @public APIs
13
- ICriticalContainerError,
14
-
15
- // @beta APIs
16
- AppInsightsTelemetryConsumer,
17
- ContainerConnectedTelemetry,
18
- ContainerDisconnectedTelemetry,
19
- ContainerDisposedTelemetry,
20
- ContainerTelemetryEventName,
21
- ContainerTelemetryEventNames,
22
- FluidTelemetryEventName,
23
- IContainerTelemetry,
24
- IFluidTelemetry,
25
- ITelemetryConsumer,
26
- TelemetryConfig,
27
- startTelemetry
13
+ ICriticalContainerError
28
14
  } from "./index.js";
@@ -9,6 +9,7 @@
9
9
  * @beta
10
10
  */
11
11
  export class AppInsightsTelemetryConsumer {
12
+ appInsightsClient;
12
13
  constructor(appInsightsClient) {
13
14
  this.appInsightsClient = appInsightsClient;
14
15
  }
@@ -1 +1 @@
1
- {"version":3,"file":"appInsightsTelemetryConsumer.js","sourceRoot":"","sources":["../../src/app-insights/appInsightsTelemetryConsumer.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAMH;;;;;GAKG;AACH,MAAM,OAAO,4BAA4B;IACxC,YAAoC,iBAAsC;QAAtC,sBAAiB,GAAjB,iBAAiB,CAAqB;IAAG,CAAC;IAE9E;;OAEG;IACI,OAAO,CAAC,KAAsB;QACpC,IAAI,CAAC,iBAAiB,CAAC,UAAU,CAAC;YACjC,IAAI,EAAE,KAAK,CAAC,SAAS;YACrB,UAAU,EAAE,KAAK;SACjB,CAAC,CAAC;IACJ,CAAC;CACD","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { type ApplicationInsights } from \"@microsoft/applicationinsights-web\";\n\nimport type { IFluidTelemetry, ITelemetryConsumer } from \"../common/index.js\";\n\n/**\n * An implementation of {@link ITelemetryConsumer} that routes {@link IFluidTelemetry} to Azure App Insights\n * in a format that is supported by Fluid Framework service offerings such as Cloud dashboards and alarms.\n *\n * @beta\n */\nexport class AppInsightsTelemetryConsumer implements ITelemetryConsumer {\n\tpublic constructor(private readonly appInsightsClient: ApplicationInsights) {}\n\n\t/**\n\t * Takes the incoming {@link IFluidTelemetry} and sends it to Azure App Insights\n\t */\n\tpublic consume(event: IFluidTelemetry): void {\n\t\tthis.appInsightsClient.trackEvent({\n\t\t\tname: event.eventName,\n\t\t\tproperties: event,\n\t\t});\n\t}\n}\n"]}
1
+ {"version":3,"file":"appInsightsTelemetryConsumer.js","sourceRoot":"","sources":["../../src/app-insights/appInsightsTelemetryConsumer.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAMH;;;;;GAKG;AACH,MAAM,OAAO,4BAA4B;IACJ;IAApC,YAAoC,iBAAsC;QAAtC,sBAAiB,GAAjB,iBAAiB,CAAqB;IAAG,CAAC;IAE9E;;OAEG;IACI,OAAO,CAAC,KAAsB;QACpC,IAAI,CAAC,iBAAiB,CAAC,UAAU,CAAC;YACjC,IAAI,EAAE,KAAK,CAAC,SAAS;YACrB,UAAU,EAAE,KAAK;SACjB,CAAC,CAAC;IACJ,CAAC;CACD","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { type ApplicationInsights } from \"@microsoft/applicationinsights-web\";\n\nimport type { IFluidTelemetry, ITelemetryConsumer } from \"../common/index.js\";\n\n/**\n * An implementation of {@link ITelemetryConsumer} that routes {@link IFluidTelemetry} to Azure App Insights\n * in a format that is supported by Fluid Framework service offerings such as Cloud dashboards and alarms.\n *\n * @beta\n */\nexport class AppInsightsTelemetryConsumer implements ITelemetryConsumer {\n\tpublic constructor(private readonly appInsightsClient: ApplicationInsights) {}\n\n\t/**\n\t * Takes the incoming {@link IFluidTelemetry} and sends it to Azure App Insights\n\t */\n\tpublic consume(event: IFluidTelemetry): void {\n\t\tthis.appInsightsClient.trackEvent({\n\t\t\tname: event.eventName,\n\t\t\tproperties: event,\n\t\t});\n\t}\n}\n"]}
@@ -10,6 +10,10 @@ import { IFluidContainerSystemEventNames, } from "./containerSystemEvents.js";
10
10
  * to be transformed into {@link IContainerTelemetry} and finally sending them to the provided {@link ITelemetryConsumer}
11
11
  */
12
12
  export class ContainerTelemetryManager {
13
+ container;
14
+ telemetryProducer;
15
+ telemetryConsumers;
16
+ static HEARTBEAT_EMISSION_INTERNAL_MS = 60000;
13
17
  constructor(container, telemetryProducer, telemetryConsumers) {
14
18
  this.container = container;
15
19
  this.telemetryProducer = telemetryProducer;
@@ -54,5 +58,4 @@ export class ContainerTelemetryManager {
54
58
  }
55
59
  }
56
60
  }
57
- ContainerTelemetryManager.HEARTBEAT_EMISSION_INTERNAL_MS = 60000;
58
61
  //# sourceMappingURL=telemetryManager.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"telemetryManager.js","sourceRoot":"","sources":["../../src/container/telemetryManager.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,eAAe,EAAE,MAAM,kCAAkC,CAAC;AAKnE,OAAO,EAEN,+BAA+B,GAC/B,MAAM,4BAA4B,CAAC;AAIpC;;;;GAIG;AACH,MAAM,OAAO,yBAAyB;IAGrC,YACkB,SAA0B,EAC1B,iBAAkD,EAClD,kBAAwC;QAFxC,cAAS,GAAT,SAAS,CAAiB;QAC1B,sBAAiB,GAAjB,iBAAiB,CAAiC;QAClD,uBAAkB,GAAlB,kBAAkB,CAAsB;QAEzD,IAAI,CAAC,kBAAkB,EAAE,CAAC;QAC1B,IAAI,CAAC,+BAA+B,EAAE,CAAC;IACxC,CAAC;IAED;;OAEG;IACK,kBAAkB;QACzB,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,+BAA+B,CAAC,SAAS,EAAE,GAAG,EAAE,CACjE,IAAI,CAAC,0BAA0B,CAAC,+BAA+B,CAAC,SAAS,CAAC,CAC1E,CAAC;QACF,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,+BAA+B,CAAC,YAAY,EAAE,GAAG,EAAE,CACpE,IAAI,CAAC,0BAA0B,CAAC,+BAA+B,CAAC,YAAY,CAAC,CAC7E,CAAC;QACF,IAAI,CAAC,SAAS,CAAC,EAAE,CAChB,+BAA+B,CAAC,QAAQ,EACxC,CAAC,KAA+B,EAAE,EAAE,CACnC,IAAI,CAAC,0BAA0B,CAAC,+BAA+B,CAAC,QAAQ,EAAE;YACzE,KAAK;SACL,CAAC,CACH,CAAC;IACH,CAAC;IAED;;;OAGG;IACK,+BAA+B;QACtC,WAAW,CAAC,GAAG,EAAE;YAChB,IAAI,IAAI,CAAC,SAAS,CAAC,eAAe,KAAK,eAAe,CAAC,SAAS,EAAE,CAAC;gBAClE,MAAM,SAAS,GAAG,IAAI,CAAC,iBAAiB,CAAC,yBAAyB,EAAE,CAAC;gBACrE,KAAK,MAAM,QAAQ,IAAI,IAAI,CAAC,kBAAkB,EAAE,CAAC;oBAChD,QAAQ,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;gBAC7B,CAAC;YACF,CAAC;QACF,CAAC,EAAE,yBAAyB,CAAC,8BAA8B,CAAC,CAAC;IAC9D,CAAC;IAED;;;OAGG;IACK,0BAA0B,CACjC,SAAyC,EACzC,OAAiB;QAEjB,MAAM,SAAS,GACd,IAAI,CAAC,iBAAiB,CAAC,sBAAsB,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;QAEnE,IAAI,SAAS,KAAK,SAAS,EAAE,CAAC;YAC7B,KAAK,MAAM,QAAQ,IAAI,IAAI,CAAC,kBAAkB,EAAE,CAAC;gBAChD,QAAQ,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;YAC7B,CAAC;QACF,CAAC;IACF,CAAC;;AA7DuB,wDAA8B,GAAG,KAAK,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { type ICriticalContainerError } from \"@fluidframework/container-definitions\";\nimport { ConnectionState } from \"@fluidframework/container-loader\";\nimport type { IFluidContainer } from \"@fluidframework/fluid-static\";\n\nimport { type ITelemetryConsumer } from \"../common/index.js\";\n\nimport {\n\ttype IFluidContainerSystemEventName,\n\tIFluidContainerSystemEventNames,\n} from \"./containerSystemEvents.js\";\nimport { type IContainerTelemetry } from \"./containerTelemetry.js\";\nimport type { ContainerEventTelemetryProducer } from \"./telemetryProducer.js\";\n\n/**\n * This class manages container telemetry intended for customers to consume by wiring together the provided container system events, telemetry producers and consumers together.\n * It manages subcribing to the proper raw container system events, sending them to the {@link ContainerEventTelemetryProducer}\n * to be transformed into {@link IContainerTelemetry} and finally sending them to the provided {@link ITelemetryConsumer}\n */\nexport class ContainerTelemetryManager {\n\tprivate static readonly HEARTBEAT_EMISSION_INTERNAL_MS = 60000;\n\n\tpublic constructor(\n\t\tprivate readonly container: IFluidContainer,\n\t\tprivate readonly telemetryProducer: ContainerEventTelemetryProducer,\n\t\tprivate readonly telemetryConsumers: ITelemetryConsumer[],\n\t) {\n\t\tthis.setupEventHandlers();\n\t\tthis.setupHeartbeatTelemetryEmission();\n\t}\n\n\t/**\n\t * Subscribes to the raw container system events and routes them to telemetry producers.\n\t */\n\tprivate setupEventHandlers(): void {\n\t\tthis.container.on(IFluidContainerSystemEventNames.CONNECTED, () =>\n\t\t\tthis.handleContainerSystemEvent(IFluidContainerSystemEventNames.CONNECTED),\n\t\t);\n\t\tthis.container.on(IFluidContainerSystemEventNames.DISCONNECTED, () =>\n\t\t\tthis.handleContainerSystemEvent(IFluidContainerSystemEventNames.DISCONNECTED),\n\t\t);\n\t\tthis.container.on(\n\t\t\tIFluidContainerSystemEventNames.DISPOSED,\n\t\t\t(error?: ICriticalContainerError) =>\n\t\t\t\tthis.handleContainerSystemEvent(IFluidContainerSystemEventNames.DISPOSED, {\n\t\t\t\t\terror,\n\t\t\t\t}),\n\t\t);\n\t}\n\n\t/**\n\t * Sets up the synthetic telemetry event for the container heartbeat telemetry to be emitted on a given time interval\n\t * if and only if the container is in a \"connected\" state. It is used to keep a pulse check on a live container\n\t */\n\tprivate setupHeartbeatTelemetryEmission(): void {\n\t\tsetInterval(() => {\n\t\t\tif (this.container.connectionState === ConnectionState.Connected) {\n\t\t\t\tconst telemetry = this.telemetryProducer.produceHeartbeatTelemetry();\n\t\t\t\tfor (const consumer of this.telemetryConsumers) {\n\t\t\t\t\tconsumer.consume(telemetry);\n\t\t\t\t}\n\t\t\t}\n\t\t}, ContainerTelemetryManager.HEARTBEAT_EMISSION_INTERNAL_MS);\n\t}\n\n\t/**\n\t * Handles the incoming raw container sysytem event, sending it to the {@link ContainerEventTelemetryProducer} to\n\t * produce {@link IContainerTelemetry} and sending it to the {@link ITelemetryConsumer} to be consumed.\n\t */\n\tprivate handleContainerSystemEvent(\n\t\teventName: IFluidContainerSystemEventName,\n\t\tpayload?: unknown,\n\t): void {\n\t\tconst telemetry: IContainerTelemetry | undefined =\n\t\t\tthis.telemetryProducer.produceFromSystemEvent(eventName, payload);\n\n\t\tif (telemetry !== undefined) {\n\t\t\tfor (const consumer of this.telemetryConsumers) {\n\t\t\t\tconsumer.consume(telemetry);\n\t\t\t}\n\t\t}\n\t}\n}\n"]}
1
+ {"version":3,"file":"telemetryManager.js","sourceRoot":"","sources":["../../src/container/telemetryManager.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,eAAe,EAAE,MAAM,kCAAkC,CAAC;AAKnE,OAAO,EAEN,+BAA+B,GAC/B,MAAM,4BAA4B,CAAC;AAIpC;;;;GAIG;AACH,MAAM,OAAO,yBAAyB;IAInB;IACA;IACA;IALV,MAAM,CAAU,8BAA8B,GAAG,KAAK,CAAC;IAE/D,YACkB,SAA0B,EAC1B,iBAAkD,EAClD,kBAAwC;QAFxC,cAAS,GAAT,SAAS,CAAiB;QAC1B,sBAAiB,GAAjB,iBAAiB,CAAiC;QAClD,uBAAkB,GAAlB,kBAAkB,CAAsB;QAEzD,IAAI,CAAC,kBAAkB,EAAE,CAAC;QAC1B,IAAI,CAAC,+BAA+B,EAAE,CAAC;IACxC,CAAC;IAED;;OAEG;IACK,kBAAkB;QACzB,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,+BAA+B,CAAC,SAAS,EAAE,GAAG,EAAE,CACjE,IAAI,CAAC,0BAA0B,CAAC,+BAA+B,CAAC,SAAS,CAAC,CAC1E,CAAC;QACF,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,+BAA+B,CAAC,YAAY,EAAE,GAAG,EAAE,CACpE,IAAI,CAAC,0BAA0B,CAAC,+BAA+B,CAAC,YAAY,CAAC,CAC7E,CAAC;QACF,IAAI,CAAC,SAAS,CAAC,EAAE,CAChB,+BAA+B,CAAC,QAAQ,EACxC,CAAC,KAA+B,EAAE,EAAE,CACnC,IAAI,CAAC,0BAA0B,CAAC,+BAA+B,CAAC,QAAQ,EAAE;YACzE,KAAK;SACL,CAAC,CACH,CAAC;IACH,CAAC;IAED;;;OAGG;IACK,+BAA+B;QACtC,WAAW,CAAC,GAAG,EAAE;YAChB,IAAI,IAAI,CAAC,SAAS,CAAC,eAAe,KAAK,eAAe,CAAC,SAAS,EAAE,CAAC;gBAClE,MAAM,SAAS,GAAG,IAAI,CAAC,iBAAiB,CAAC,yBAAyB,EAAE,CAAC;gBACrE,KAAK,MAAM,QAAQ,IAAI,IAAI,CAAC,kBAAkB,EAAE,CAAC;oBAChD,QAAQ,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;gBAC7B,CAAC;YACF,CAAC;QACF,CAAC,EAAE,yBAAyB,CAAC,8BAA8B,CAAC,CAAC;IAC9D,CAAC;IAED;;;OAGG;IACK,0BAA0B,CACjC,SAAyC,EACzC,OAAiB;QAEjB,MAAM,SAAS,GACd,IAAI,CAAC,iBAAiB,CAAC,sBAAsB,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;QAEnE,IAAI,SAAS,KAAK,SAAS,EAAE,CAAC;YAC7B,KAAK,MAAM,QAAQ,IAAI,IAAI,CAAC,kBAAkB,EAAE,CAAC;gBAChD,QAAQ,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;YAC7B,CAAC;QACF,CAAC;IACF,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { type ICriticalContainerError } from \"@fluidframework/container-definitions\";\nimport { ConnectionState } from \"@fluidframework/container-loader\";\nimport type { IFluidContainer } from \"@fluidframework/fluid-static\";\n\nimport { type ITelemetryConsumer } from \"../common/index.js\";\n\nimport {\n\ttype IFluidContainerSystemEventName,\n\tIFluidContainerSystemEventNames,\n} from \"./containerSystemEvents.js\";\nimport { type IContainerTelemetry } from \"./containerTelemetry.js\";\nimport type { ContainerEventTelemetryProducer } from \"./telemetryProducer.js\";\n\n/**\n * This class manages container telemetry intended for customers to consume by wiring together the provided container system events, telemetry producers and consumers together.\n * It manages subcribing to the proper raw container system events, sending them to the {@link ContainerEventTelemetryProducer}\n * to be transformed into {@link IContainerTelemetry} and finally sending them to the provided {@link ITelemetryConsumer}\n */\nexport class ContainerTelemetryManager {\n\tprivate static readonly HEARTBEAT_EMISSION_INTERNAL_MS = 60000;\n\n\tpublic constructor(\n\t\tprivate readonly container: IFluidContainer,\n\t\tprivate readonly telemetryProducer: ContainerEventTelemetryProducer,\n\t\tprivate readonly telemetryConsumers: ITelemetryConsumer[],\n\t) {\n\t\tthis.setupEventHandlers();\n\t\tthis.setupHeartbeatTelemetryEmission();\n\t}\n\n\t/**\n\t * Subscribes to the raw container system events and routes them to telemetry producers.\n\t */\n\tprivate setupEventHandlers(): void {\n\t\tthis.container.on(IFluidContainerSystemEventNames.CONNECTED, () =>\n\t\t\tthis.handleContainerSystemEvent(IFluidContainerSystemEventNames.CONNECTED),\n\t\t);\n\t\tthis.container.on(IFluidContainerSystemEventNames.DISCONNECTED, () =>\n\t\t\tthis.handleContainerSystemEvent(IFluidContainerSystemEventNames.DISCONNECTED),\n\t\t);\n\t\tthis.container.on(\n\t\t\tIFluidContainerSystemEventNames.DISPOSED,\n\t\t\t(error?: ICriticalContainerError) =>\n\t\t\t\tthis.handleContainerSystemEvent(IFluidContainerSystemEventNames.DISPOSED, {\n\t\t\t\t\terror,\n\t\t\t\t}),\n\t\t);\n\t}\n\n\t/**\n\t * Sets up the synthetic telemetry event for the container heartbeat telemetry to be emitted on a given time interval\n\t * if and only if the container is in a \"connected\" state. It is used to keep a pulse check on a live container\n\t */\n\tprivate setupHeartbeatTelemetryEmission(): void {\n\t\tsetInterval(() => {\n\t\t\tif (this.container.connectionState === ConnectionState.Connected) {\n\t\t\t\tconst telemetry = this.telemetryProducer.produceHeartbeatTelemetry();\n\t\t\t\tfor (const consumer of this.telemetryConsumers) {\n\t\t\t\t\tconsumer.consume(telemetry);\n\t\t\t\t}\n\t\t\t}\n\t\t}, ContainerTelemetryManager.HEARTBEAT_EMISSION_INTERNAL_MS);\n\t}\n\n\t/**\n\t * Handles the incoming raw container sysytem event, sending it to the {@link ContainerEventTelemetryProducer} to\n\t * produce {@link IContainerTelemetry} and sending it to the {@link ITelemetryConsumer} to be consumed.\n\t */\n\tprivate handleContainerSystemEvent(\n\t\teventName: IFluidContainerSystemEventName,\n\t\tpayload?: unknown,\n\t): void {\n\t\tconst telemetry: IContainerTelemetry | undefined =\n\t\t\tthis.telemetryProducer.produceFromSystemEvent(eventName, payload);\n\n\t\tif (telemetry !== undefined) {\n\t\t\tfor (const consumer of this.telemetryConsumers) {\n\t\t\t\tconsumer.consume(telemetry);\n\t\t\t}\n\t\t}\n\t}\n}\n"]}
@@ -11,37 +11,13 @@ import { ContainerTelemetryEventNames, } from "./containerTelemetry.js";
11
11
  * to produce different {@link IContainerTelemetry}.
12
12
  */
13
13
  export class ContainerEventTelemetryProducer {
14
+ containerId;
15
+ /**
16
+ * Unique identifier for the instance of the container that this class is generating telemetry for.
17
+ */
18
+ containerInstanceId = uuid();
14
19
  constructor(containerId) {
15
20
  this.containerId = containerId;
16
- /**
17
- * Unique identifier for the instance of the container that this class is generating telemetry for.
18
- */
19
- this.containerInstanceId = uuid();
20
- this.produceHeartbeatTelemetry = () => {
21
- return {
22
- eventName: "fluidframework.container.heartbeat",
23
- containerId: this.containerId,
24
- containerInstanceId: this.containerInstanceId,
25
- };
26
- };
27
- this.produceBaseContainerTelemetry = (eventName) => {
28
- return {
29
- eventName,
30
- containerId: this.containerId,
31
- containerInstanceId: this.containerInstanceId,
32
- };
33
- };
34
- this.produceDiposedTelemetry = (payload) => {
35
- const telemetry = {
36
- eventName: ContainerTelemetryEventNames.DISPOSED,
37
- containerId: this.containerId,
38
- containerInstanceId: this.containerInstanceId,
39
- };
40
- if (payload?.error !== undefined) {
41
- telemetry.error = payload.error;
42
- }
43
- return telemetry;
44
- };
45
21
  }
46
22
  produceFromSystemEvent(eventName, payload) {
47
23
  switch (eventName) {
@@ -60,5 +36,30 @@ export class ContainerEventTelemetryProducer {
60
36
  }
61
37
  }
62
38
  }
39
+ produceHeartbeatTelemetry = () => {
40
+ return {
41
+ eventName: "fluidframework.container.heartbeat",
42
+ containerId: this.containerId,
43
+ containerInstanceId: this.containerInstanceId,
44
+ };
45
+ };
46
+ produceBaseContainerTelemetry = (eventName) => {
47
+ return {
48
+ eventName,
49
+ containerId: this.containerId,
50
+ containerInstanceId: this.containerInstanceId,
51
+ };
52
+ };
53
+ produceDiposedTelemetry = (payload) => {
54
+ const telemetry = {
55
+ eventName: ContainerTelemetryEventNames.DISPOSED,
56
+ containerId: this.containerId,
57
+ containerInstanceId: this.containerInstanceId,
58
+ };
59
+ if (payload?.error !== undefined) {
60
+ telemetry.error = payload.error;
61
+ }
62
+ return telemetry;
63
+ };
63
64
  }
64
65
  //# sourceMappingURL=telemetryProducer.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"telemetryProducer.js","sourceRoot":"","sources":["../../src/container/telemetryProducer.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,EAAE,IAAI,IAAI,EAAE,MAAM,MAAM,CAAC;AAIlC,OAAO,EAEN,+BAA+B,GAC/B,MAAM,4BAA4B,CAAC;AACpC,OAAO,EACN,4BAA4B,GAI5B,MAAM,yBAAyB,CAAC;AAEjC;;;;GAIG;AACH,MAAM,OAAO,+BAA+B;IAM3C,YAAoC,WAAmB;QAAnB,gBAAW,GAAX,WAAW,CAAQ;QALvD;;WAEG;QACc,wBAAmB,GAAG,IAAI,EAAE,CAAC;QA2BvC,8BAAyB,GAAG,GAAoB,EAAE;YACxD,OAAO;gBACN,SAAS,EAAE,oCAAoC;gBAC/C,WAAW,EAAE,IAAI,CAAC,WAAW;gBAC7B,mBAAmB,EAAE,IAAI,CAAC,mBAAmB;aACf,CAAC;QACjC,CAAC,CAAC;QAEe,kCAA6B,GAAG,CAChD,SAAsC,EAChB,EAAE;YACxB,OAAO;gBACN,SAAS;gBACT,WAAW,EAAE,IAAI,CAAC,WAAW;gBAC7B,mBAAmB,EAAE,IAAI,CAAC,mBAAmB;aACf,CAAC;QACjC,CAAC,CAAC;QAEe,4BAAuB,GAAG,CAAC,OAE3C,EAA8B,EAAE;YAChC,MAAM,SAAS,GAA+B;gBAC7C,SAAS,EAAE,4BAA4B,CAAC,QAAQ;gBAChD,WAAW,EAAE,IAAI,CAAC,WAAW;gBAC7B,mBAAmB,EAAE,IAAI,CAAC,mBAAmB;aAC7C,CAAC;YACF,IAAI,OAAO,EAAE,KAAK,KAAK,SAAS,EAAE,CAAC;gBAClC,SAAS,CAAC,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC;YACjC,CAAC;YACD,OAAO,SAAS,CAAC;QAClB,CAAC,CAAC;IAvDwD,CAAC;IAEpD,sBAAsB,CAC5B,SAAyC,EACzC,OAAiB;QAEjB,QAAQ,SAAS,EAAE,CAAC;YACnB,KAAK,+BAA+B,CAAC,SAAS,CAAC,CAAC,CAAC;gBAChD,OAAO,IAAI,CAAC,6BAA6B,CAAC,4BAA4B,CAAC,SAAS,CAAC,CAAC;YACnF,CAAC;YACD,KAAK,+BAA+B,CAAC,YAAY,CAAC,CAAC,CAAC;gBACnD,OAAO,IAAI,CAAC,6BAA6B,CACxC,4BAA4B,CAAC,YAAY,CACzC,CAAC;YACH,CAAC;YACD,KAAK,+BAA+B,CAAC,QAAQ,CAAC,CAAC,CAAC;gBAC/C,MAAM,YAAY,GAAG,OAA8C,CAAC;gBACpE,OAAO,IAAI,CAAC,uBAAuB,CAAC,YAAY,CAAC,CAAC;YACnD,CAAC;YACD,OAAO,CAAC,CAAC,CAAC;gBACT,MAAM;YACP,CAAC;QACF,CAAC;IACF,CAAC;CAiCD","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { type ICriticalContainerError } from \"@fluidframework/container-definitions\";\nimport { v4 as uuid } from \"uuid\";\n\nimport type { IFluidTelemetry } from \"../index.js\";\n\nimport {\n\ttype IFluidContainerSystemEventName,\n\tIFluidContainerSystemEventNames,\n} from \"./containerSystemEvents.js\";\nimport {\n\tContainerTelemetryEventNames,\n\ttype ContainerTelemetryEventName,\n\ttype IContainerTelemetry,\n\ttype ContainerDisposedTelemetry,\n} from \"./containerTelemetry.js\";\n\n/**\n * This class produces {@link IContainerTelemetry} from raw container system events {@link @fluidframework/fluid-static#IFluidContainerEvents}.\n * The class contains different helper methods for simplifying and standardizing logic for adding additional information necessary\n * to produce different {@link IContainerTelemetry}.\n */\nexport class ContainerEventTelemetryProducer {\n\t/**\n\t * Unique identifier for the instance of the container that this class is generating telemetry for.\n\t */\n\tprivate readonly containerInstanceId = uuid();\n\n\tpublic constructor(private readonly containerId: string) {}\n\n\tpublic produceFromSystemEvent(\n\t\teventName: IFluidContainerSystemEventName,\n\t\tpayload?: unknown,\n\t): IContainerTelemetry | undefined {\n\t\tswitch (eventName) {\n\t\t\tcase IFluidContainerSystemEventNames.CONNECTED: {\n\t\t\t\treturn this.produceBaseContainerTelemetry(ContainerTelemetryEventNames.CONNECTED);\n\t\t\t}\n\t\t\tcase IFluidContainerSystemEventNames.DISCONNECTED: {\n\t\t\t\treturn this.produceBaseContainerTelemetry(\n\t\t\t\t\tContainerTelemetryEventNames.DISCONNECTED,\n\t\t\t\t);\n\t\t\t}\n\t\t\tcase IFluidContainerSystemEventNames.DISPOSED: {\n\t\t\t\tconst typedPayload = payload as { error?: ICriticalContainerError };\n\t\t\t\treturn this.produceDiposedTelemetry(typedPayload);\n\t\t\t}\n\t\t\tdefault: {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\n\tpublic produceHeartbeatTelemetry = (): IFluidTelemetry => {\n\t\treturn {\n\t\t\teventName: \"fluidframework.container.heartbeat\",\n\t\t\tcontainerId: this.containerId,\n\t\t\tcontainerInstanceId: this.containerInstanceId,\n\t\t} as unknown as IFluidTelemetry;\n\t};\n\n\tprivate readonly produceBaseContainerTelemetry = (\n\t\teventName: ContainerTelemetryEventName,\n\t): IContainerTelemetry => {\n\t\treturn {\n\t\t\teventName,\n\t\t\tcontainerId: this.containerId,\n\t\t\tcontainerInstanceId: this.containerInstanceId,\n\t\t} satisfies IContainerTelemetry;\n\t};\n\n\tprivate readonly produceDiposedTelemetry = (payload?: {\n\t\terror?: ICriticalContainerError;\n\t}): ContainerDisposedTelemetry => {\n\t\tconst telemetry: ContainerDisposedTelemetry = {\n\t\t\teventName: ContainerTelemetryEventNames.DISPOSED,\n\t\t\tcontainerId: this.containerId,\n\t\t\tcontainerInstanceId: this.containerInstanceId,\n\t\t};\n\t\tif (payload?.error !== undefined) {\n\t\t\ttelemetry.error = payload.error;\n\t\t}\n\t\treturn telemetry;\n\t};\n}\n"]}
1
+ {"version":3,"file":"telemetryProducer.js","sourceRoot":"","sources":["../../src/container/telemetryProducer.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,EAAE,IAAI,IAAI,EAAE,MAAM,MAAM,CAAC;AAIlC,OAAO,EAEN,+BAA+B,GAC/B,MAAM,4BAA4B,CAAC;AACpC,OAAO,EACN,4BAA4B,GAI5B,MAAM,yBAAyB,CAAC;AAEjC;;;;GAIG;AACH,MAAM,OAAO,+BAA+B;IAMP;IALpC;;OAEG;IACc,mBAAmB,GAAG,IAAI,EAAE,CAAC;IAE9C,YAAoC,WAAmB;QAAnB,gBAAW,GAAX,WAAW,CAAQ;IAAG,CAAC;IAEpD,sBAAsB,CAC5B,SAAyC,EACzC,OAAiB;QAEjB,QAAQ,SAAS,EAAE,CAAC;YACnB,KAAK,+BAA+B,CAAC,SAAS,CAAC,CAAC,CAAC;gBAChD,OAAO,IAAI,CAAC,6BAA6B,CAAC,4BAA4B,CAAC,SAAS,CAAC,CAAC;YACnF,CAAC;YACD,KAAK,+BAA+B,CAAC,YAAY,CAAC,CAAC,CAAC;gBACnD,OAAO,IAAI,CAAC,6BAA6B,CACxC,4BAA4B,CAAC,YAAY,CACzC,CAAC;YACH,CAAC;YACD,KAAK,+BAA+B,CAAC,QAAQ,CAAC,CAAC,CAAC;gBAC/C,MAAM,YAAY,GAAG,OAA8C,CAAC;gBACpE,OAAO,IAAI,CAAC,uBAAuB,CAAC,YAAY,CAAC,CAAC;YACnD,CAAC;YACD,OAAO,CAAC,CAAC,CAAC;gBACT,MAAM;YACP,CAAC;QACF,CAAC;IACF,CAAC;IAEM,yBAAyB,GAAG,GAAoB,EAAE;QACxD,OAAO;YACN,SAAS,EAAE,oCAAoC;YAC/C,WAAW,EAAE,IAAI,CAAC,WAAW;YAC7B,mBAAmB,EAAE,IAAI,CAAC,mBAAmB;SACf,CAAC;IACjC,CAAC,CAAC;IAEe,6BAA6B,GAAG,CAChD,SAAsC,EAChB,EAAE;QACxB,OAAO;YACN,SAAS;YACT,WAAW,EAAE,IAAI,CAAC,WAAW;YAC7B,mBAAmB,EAAE,IAAI,CAAC,mBAAmB;SACf,CAAC;IACjC,CAAC,CAAC;IAEe,uBAAuB,GAAG,CAAC,OAE3C,EAA8B,EAAE;QAChC,MAAM,SAAS,GAA+B;YAC7C,SAAS,EAAE,4BAA4B,CAAC,QAAQ;YAChD,WAAW,EAAE,IAAI,CAAC,WAAW;YAC7B,mBAAmB,EAAE,IAAI,CAAC,mBAAmB;SAC7C,CAAC;QACF,IAAI,OAAO,EAAE,KAAK,KAAK,SAAS,EAAE,CAAC;YAClC,SAAS,CAAC,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC;QACjC,CAAC;QACD,OAAO,SAAS,CAAC;IAClB,CAAC,CAAC;CACF","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { type ICriticalContainerError } from \"@fluidframework/container-definitions\";\nimport { v4 as uuid } from \"uuid\";\n\nimport type { IFluidTelemetry } from \"../index.js\";\n\nimport {\n\ttype IFluidContainerSystemEventName,\n\tIFluidContainerSystemEventNames,\n} from \"./containerSystemEvents.js\";\nimport {\n\tContainerTelemetryEventNames,\n\ttype ContainerTelemetryEventName,\n\ttype IContainerTelemetry,\n\ttype ContainerDisposedTelemetry,\n} from \"./containerTelemetry.js\";\n\n/**\n * This class produces {@link IContainerTelemetry} from raw container system events {@link @fluidframework/fluid-static#IFluidContainerEvents}.\n * The class contains different helper methods for simplifying and standardizing logic for adding additional information necessary\n * to produce different {@link IContainerTelemetry}.\n */\nexport class ContainerEventTelemetryProducer {\n\t/**\n\t * Unique identifier for the instance of the container that this class is generating telemetry for.\n\t */\n\tprivate readonly containerInstanceId = uuid();\n\n\tpublic constructor(private readonly containerId: string) {}\n\n\tpublic produceFromSystemEvent(\n\t\teventName: IFluidContainerSystemEventName,\n\t\tpayload?: unknown,\n\t): IContainerTelemetry | undefined {\n\t\tswitch (eventName) {\n\t\t\tcase IFluidContainerSystemEventNames.CONNECTED: {\n\t\t\t\treturn this.produceBaseContainerTelemetry(ContainerTelemetryEventNames.CONNECTED);\n\t\t\t}\n\t\t\tcase IFluidContainerSystemEventNames.DISCONNECTED: {\n\t\t\t\treturn this.produceBaseContainerTelemetry(\n\t\t\t\t\tContainerTelemetryEventNames.DISCONNECTED,\n\t\t\t\t);\n\t\t\t}\n\t\t\tcase IFluidContainerSystemEventNames.DISPOSED: {\n\t\t\t\tconst typedPayload = payload as { error?: ICriticalContainerError };\n\t\t\t\treturn this.produceDiposedTelemetry(typedPayload);\n\t\t\t}\n\t\t\tdefault: {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\n\tpublic produceHeartbeatTelemetry = (): IFluidTelemetry => {\n\t\treturn {\n\t\t\teventName: \"fluidframework.container.heartbeat\",\n\t\t\tcontainerId: this.containerId,\n\t\t\tcontainerInstanceId: this.containerInstanceId,\n\t\t} as unknown as IFluidTelemetry;\n\t};\n\n\tprivate readonly produceBaseContainerTelemetry = (\n\t\teventName: ContainerTelemetryEventName,\n\t): IContainerTelemetry => {\n\t\treturn {\n\t\t\teventName,\n\t\t\tcontainerId: this.containerId,\n\t\t\tcontainerInstanceId: this.containerInstanceId,\n\t\t} satisfies IContainerTelemetry;\n\t};\n\n\tprivate readonly produceDiposedTelemetry = (payload?: {\n\t\terror?: ICriticalContainerError;\n\t}): ContainerDisposedTelemetry => {\n\t\tconst telemetry: ContainerDisposedTelemetry = {\n\t\t\teventName: ContainerTelemetryEventNames.DISPOSED,\n\t\t\tcontainerId: this.containerId,\n\t\t\tcontainerInstanceId: this.containerInstanceId,\n\t\t};\n\t\tif (payload?.error !== undefined) {\n\t\t\ttelemetry.error = payload.error;\n\t\t}\n\t\treturn telemetry;\n\t};\n}\n"]}
package/lib/legacy.d.ts CHANGED
@@ -10,19 +10,5 @@
10
10
 
11
11
  export {
12
12
  // @public APIs
13
- ICriticalContainerError,
14
-
15
- // @beta APIs
16
- AppInsightsTelemetryConsumer,
17
- ContainerConnectedTelemetry,
18
- ContainerDisconnectedTelemetry,
19
- ContainerDisposedTelemetry,
20
- ContainerTelemetryEventName,
21
- ContainerTelemetryEventNames,
22
- FluidTelemetryEventName,
23
- IContainerTelemetry,
24
- IFluidTelemetry,
25
- ITelemetryConsumer,
26
- TelemetryConfig,
27
- startTelemetry
13
+ ICriticalContainerError
28
14
  } from "./index.js";
@@ -8,7 +8,7 @@ import { expect } from "chai";
8
8
  import { spy } from "sinon";
9
9
  import { IFluidContainerSystemEventNames } from "../container/index.js";
10
10
  import { startTelemetry } from "../factory/index.js";
11
- import { ContainerTelemetryEventNames, } from "../index.js";
11
+ import { AppInsightsTelemetryConsumer, ContainerTelemetryEventNames, } from "../index.js";
12
12
  /**
13
13
  * For these unit tests, we are just interested in the event emitter part of the Fluid container.
14
14
  * The rest of the functionality of IFluidContainer is irrelevant.
@@ -40,17 +40,6 @@ describe("container telemetry via", () => {
40
40
  });
41
41
  trackEventSpy = spy(appInsightsClient, "trackEvent");
42
42
  mockFluidContainer = new MockFluidContainer();
43
- class AppInsightsTelemetryConsumer {
44
- constructor(client) {
45
- this.client = client;
46
- }
47
- consume(event) {
48
- this.client.trackEvent({
49
- name: event.eventName,
50
- properties: event,
51
- });
52
- }
53
- }
54
43
  telemetryConfig = {
55
44
  container: mockFluidContainer,
56
45
  containerId: mockContainerId,
@@ -1 +1 @@
1
- {"version":3,"file":"containerTelemetry.spec.js","sourceRoot":"","sources":["../../src/test/containerTelemetry.spec.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { TypedEventEmitter } from \"@fluid-internal/client-utils\";\nimport type { ICriticalContainerError } from \"@fluidframework/container-definitions\";\nimport type { IFluidContainer, IFluidContainerEvents } from \"@fluidframework/fluid-static\";\nimport { ApplicationInsights, type IEventTelemetry } from \"@microsoft/applicationinsights-web\";\nimport { expect } from \"chai\";\nimport { spy } from \"sinon\";\nimport type Sinon from \"sinon\";\n\nimport { IFluidContainerSystemEventNames, type IContainerTelemetry } from \"../container/index.js\";\nimport { startTelemetry, type TelemetryConfig } from \"../factory/index.js\";\nimport {\n\tContainerTelemetryEventNames,\n\ttype ContainerConnectedTelemetry,\n\ttype ContainerDisconnectedTelemetry,\n\ttype ContainerDisposedTelemetry,\n\ttype IFluidTelemetry,\n\ttype ITelemetryConsumer,\n} from \"../index.js\";\n\n/**\n * For these unit tests, we are just interested in the event emitter part of the Fluid container.\n * The rest of the functionality of IFluidContainer is irrelevant.\n */\nclass MockFluidContainer extends TypedEventEmitter<IFluidContainerEvents> {\n\tpublic connect(): void {\n\t\tthis.emit(IFluidContainerSystemEventNames.CONNECTED);\n\t}\n\n\tpublic disconnect(): void {\n\t\tthis.emit(IFluidContainerSystemEventNames.DISCONNECTED);\n\t}\n\n\tpublic dispose(error?: ICriticalContainerError): void {\n\t\tthis.emit(IFluidContainerSystemEventNames.DISPOSED, error);\n\t}\n}\n\ndescribe(\"container telemetry via\", () => {\n\tlet mockFluidContainer: MockFluidContainer;\n\tconst mockContainerId = \"mockContainerId\";\n\tlet appInsightsClient: ApplicationInsights;\n\tlet trackEventSpy: Sinon.SinonSpy;\n\tlet telemetryConfig: TelemetryConfig;\n\n\tbeforeEach(() => {\n\t\tappInsightsClient = new ApplicationInsights({\n\t\t\tconfig: {\n\t\t\t\tconnectionString:\n\t\t\t\t\t// (this is an example string)\n\t\t\t\t\t\"InstrumentationKey=abcdefgh-ijkl-mnop-qrst-uvwxyz6ffd9c;IngestionEndpoint=https://westus2-2.in.applicationinsights.azure.com/;LiveEndpoint=https://westus2.livediagnostics.monitor.azure.com/\",\n\t\t\t},\n\t\t});\n\n\t\ttrackEventSpy = spy(appInsightsClient, \"trackEvent\");\n\t\tmockFluidContainer = new MockFluidContainer();\n\n\t\tclass AppInsightsTelemetryConsumer implements ITelemetryConsumer {\n\t\t\tpublic constructor(private readonly client: ApplicationInsights) {}\n\n\t\t\tpublic consume(event: IFluidTelemetry): void {\n\t\t\t\tthis.client.trackEvent({\n\t\t\t\t\tname: event.eventName,\n\t\t\t\t\tproperties: event,\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\ttelemetryConfig = {\n\t\t\tcontainer: mockFluidContainer as unknown as IFluidContainer,\n\t\t\tcontainerId: mockContainerId,\n\t\t\tconsumers: [new AppInsightsTelemetryConsumer(appInsightsClient)],\n\t\t};\n\t});\n\n\tit(\"Emitting 'connected' container system event produces expected ContainerConnectedTelemetry using Azure App Insights\", () => {\n\t\tstartTelemetry(telemetryConfig);\n\n\t\tmockFluidContainer.connect();\n\n\t\texpect(trackEventSpy.callCount).to.equal(1);\n\n\t\t// Obtain the events from the method that the spy was called with\n\t\tconst actualAppInsightsTelemetry = trackEventSpy.getCall(0).args[0] as IEventTelemetry;\n\t\tconst actualContainerTelemetry =\n\t\t\tactualAppInsightsTelemetry.properties as IContainerTelemetry;\n\n\t\tconst expectedAppInsightsTelemetry: IEventTelemetry = {\n\t\t\tname: ContainerTelemetryEventNames.CONNECTED,\n\t\t\tproperties: {\n\t\t\t\teventName: ContainerTelemetryEventNames.CONNECTED,\n\t\t\t\tcontainerId: mockContainerId,\n\t\t\t\tcontainerInstanceId: actualContainerTelemetry.containerInstanceId,\n\t\t\t} satisfies ContainerConnectedTelemetry,\n\t\t};\n\n\t\texpect(expectedAppInsightsTelemetry).to.deep.equal(actualAppInsightsTelemetry);\n\t\t// We won't know what the container containerInstanceId will be but we can still check that it is defined.\n\t\texpect(actualContainerTelemetry.containerInstanceId).to.be.a(\"string\").with.length.above(0);\n\t});\n\n\tit(\"Emitting 'disconnected' container system event produces expected ContainerDisconnectedTelemetry using Azure App Insights\", () => {\n\t\tstartTelemetry(telemetryConfig);\n\n\t\tmockFluidContainer.disconnect();\n\n\t\texpect(trackEventSpy.callCount).to.equal(1);\n\n\t\t// Obtain the events from the method that the spy was called with\n\t\tconst actualAppInsightsTelemetry = trackEventSpy.getCall(0).args[0] as IEventTelemetry;\n\t\tconst actualContainerTelemetry =\n\t\t\tactualAppInsightsTelemetry.properties as IContainerTelemetry;\n\n\t\tconst expectedAppInsightsTelemetry: IEventTelemetry = {\n\t\t\tname: ContainerTelemetryEventNames.DISCONNECTED,\n\t\t\tproperties: {\n\t\t\t\teventName: ContainerTelemetryEventNames.DISCONNECTED,\n\t\t\t\tcontainerId: mockContainerId,\n\t\t\t\tcontainerInstanceId: actualContainerTelemetry.containerInstanceId,\n\t\t\t} satisfies ContainerDisconnectedTelemetry,\n\t\t};\n\n\t\texpect(expectedAppInsightsTelemetry).to.deep.equal(actualAppInsightsTelemetry);\n\t\t// We won't know what the container containerInstanceId will be but we can still check that it is defined.\n\t\texpect(actualContainerTelemetry.containerInstanceId).to.be.a(\"string\").with.length.above(0);\n\t});\n\n\tit(\"Emitting 'disposed' system event produces expected ContainerDisposedTelemetry using Azure App Insights\", () => {\n\t\tstartTelemetry(telemetryConfig);\n\n\t\tmockFluidContainer.dispose();\n\n\t\texpect(trackEventSpy.callCount).to.equal(1);\n\n\t\t// Obtain the events from the method that the spy was called with\n\t\tconst actualAppInsightsTelemetry = trackEventSpy.getCall(0).args[0] as IEventTelemetry;\n\t\tconst actualContainerTelemetry =\n\t\t\tactualAppInsightsTelemetry.properties as IContainerTelemetry;\n\n\t\tconst expectedAppInsightsTelemetry: IEventTelemetry = {\n\t\t\tname: ContainerTelemetryEventNames.DISPOSED,\n\t\t\tproperties: {\n\t\t\t\teventName: ContainerTelemetryEventNames.DISPOSED,\n\t\t\t\tcontainerId: mockContainerId,\n\t\t\t\tcontainerInstanceId: actualContainerTelemetry.containerInstanceId,\n\t\t\t} satisfies ContainerDisposedTelemetry,\n\t\t};\n\n\t\texpect(expectedAppInsightsTelemetry).to.deep.equal(actualAppInsightsTelemetry);\n\t\t// We won't know what the container containerInstanceId will be but we can still check that it is defined.\n\t\texpect(actualContainerTelemetry.containerInstanceId).to.be.a(\"string\").with.length.above(0);\n\t});\n\n\tit(\"Emitting 'disposed' system event with an error produces expected ContainerDisposedTelemetry using Azure App Insights\", () => {\n\t\tstartTelemetry(telemetryConfig);\n\n\t\tconst containerError: ICriticalContainerError = {\n\t\t\terrorType: \"unknown error\",\n\t\t\tmessage: \"An unknown error occured\",\n\t\t\tstack: \"example stack error at line 52 of Container.ts\",\n\t\t};\n\n\t\tmockFluidContainer.dispose(containerError);\n\n\t\t// Obtain the events from the method that the spy was called with\n\t\tconst actualAppInsightsTelemetry = trackEventSpy.getCall(0).args[0] as IEventTelemetry;\n\t\tconst actualContainerTelemetry =\n\t\t\tactualAppInsightsTelemetry.properties as IContainerTelemetry;\n\n\t\tconst expectedAppInsightsTelemetry: IEventTelemetry = {\n\t\t\tname: ContainerTelemetryEventNames.DISPOSED,\n\t\t\tproperties: {\n\t\t\t\teventName: ContainerTelemetryEventNames.DISPOSED,\n\t\t\t\tcontainerId: mockContainerId,\n\t\t\t\tcontainerInstanceId: actualContainerTelemetry.containerInstanceId,\n\t\t\t\terror: containerError,\n\t\t\t} satisfies ContainerDisposedTelemetry,\n\t\t};\n\n\t\texpect(expectedAppInsightsTelemetry).to.deep.equal(actualAppInsightsTelemetry);\n\t\t// We won't know what the container containerInstanceId will be but we can still check that it is defined.\n\t\texpect(actualContainerTelemetry.containerInstanceId).to.be.a(\"string\").with.length.above(0);\n\t});\n});\n"]}
1
+ {"version":3,"file":"containerTelemetry.spec.js","sourceRoot":"","sources":["../../src/test/containerTelemetry.spec.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { TypedEventEmitter } from \"@fluid-internal/client-utils\";\nimport type { ICriticalContainerError } from \"@fluidframework/container-definitions\";\nimport type { IFluidContainer, IFluidContainerEvents } from \"@fluidframework/fluid-static\";\nimport { ApplicationInsights, type IEventTelemetry } from \"@microsoft/applicationinsights-web\";\nimport { expect } from \"chai\";\nimport { spy } from \"sinon\";\nimport type Sinon from \"sinon\";\n\nimport { IFluidContainerSystemEventNames, type IContainerTelemetry } from \"../container/index.js\";\nimport { startTelemetry, type TelemetryConfig } from \"../factory/index.js\";\nimport {\n\tAppInsightsTelemetryConsumer,\n\tContainerTelemetryEventNames,\n\ttype ContainerConnectedTelemetry,\n\ttype ContainerDisconnectedTelemetry,\n\ttype ContainerDisposedTelemetry,\n} from \"../index.js\";\n\n/**\n * For these unit tests, we are just interested in the event emitter part of the Fluid container.\n * The rest of the functionality of IFluidContainer is irrelevant.\n */\nclass MockFluidContainer extends TypedEventEmitter<IFluidContainerEvents> {\n\tpublic connect(): void {\n\t\tthis.emit(IFluidContainerSystemEventNames.CONNECTED);\n\t}\n\n\tpublic disconnect(): void {\n\t\tthis.emit(IFluidContainerSystemEventNames.DISCONNECTED);\n\t}\n\n\tpublic dispose(error?: ICriticalContainerError): void {\n\t\tthis.emit(IFluidContainerSystemEventNames.DISPOSED, error);\n\t}\n}\n\ndescribe(\"container telemetry via\", () => {\n\tlet mockFluidContainer: MockFluidContainer;\n\tconst mockContainerId = \"mockContainerId\";\n\tlet appInsightsClient: ApplicationInsights;\n\tlet trackEventSpy: Sinon.SinonSpy;\n\tlet telemetryConfig: TelemetryConfig;\n\n\tbeforeEach(() => {\n\t\tappInsightsClient = new ApplicationInsights({\n\t\t\tconfig: {\n\t\t\t\tconnectionString:\n\t\t\t\t\t// (this is an example string)\n\t\t\t\t\t\"InstrumentationKey=abcdefgh-ijkl-mnop-qrst-uvwxyz6ffd9c;IngestionEndpoint=https://westus2-2.in.applicationinsights.azure.com/;LiveEndpoint=https://westus2.livediagnostics.monitor.azure.com/\",\n\t\t\t},\n\t\t});\n\n\t\ttrackEventSpy = spy(appInsightsClient, \"trackEvent\");\n\t\tmockFluidContainer = new MockFluidContainer();\n\n\t\ttelemetryConfig = {\n\t\t\tcontainer: mockFluidContainer as unknown as IFluidContainer,\n\t\t\tcontainerId: mockContainerId,\n\t\t\tconsumers: [new AppInsightsTelemetryConsumer(appInsightsClient)],\n\t\t};\n\t});\n\n\tit(\"Emitting 'connected' container system event produces expected ContainerConnectedTelemetry using Azure App Insights\", () => {\n\t\tstartTelemetry(telemetryConfig);\n\n\t\tmockFluidContainer.connect();\n\n\t\texpect(trackEventSpy.callCount).to.equal(1);\n\n\t\t// Obtain the events from the method that the spy was called with\n\t\tconst actualAppInsightsTelemetry = trackEventSpy.getCall(0).args[0] as IEventTelemetry;\n\t\tconst actualContainerTelemetry =\n\t\t\tactualAppInsightsTelemetry.properties as IContainerTelemetry;\n\n\t\tconst expectedAppInsightsTelemetry: IEventTelemetry = {\n\t\t\tname: ContainerTelemetryEventNames.CONNECTED,\n\t\t\tproperties: {\n\t\t\t\teventName: ContainerTelemetryEventNames.CONNECTED,\n\t\t\t\tcontainerId: mockContainerId,\n\t\t\t\tcontainerInstanceId: actualContainerTelemetry.containerInstanceId,\n\t\t\t} satisfies ContainerConnectedTelemetry,\n\t\t};\n\n\t\texpect(expectedAppInsightsTelemetry).to.deep.equal(actualAppInsightsTelemetry);\n\t\t// We won't know what the container containerInstanceId will be but we can still check that it is defined.\n\t\texpect(actualContainerTelemetry.containerInstanceId).to.be.a(\"string\").with.length.above(0);\n\t});\n\n\tit(\"Emitting 'disconnected' container system event produces expected ContainerDisconnectedTelemetry using Azure App Insights\", () => {\n\t\tstartTelemetry(telemetryConfig);\n\n\t\tmockFluidContainer.disconnect();\n\n\t\texpect(trackEventSpy.callCount).to.equal(1);\n\n\t\t// Obtain the events from the method that the spy was called with\n\t\tconst actualAppInsightsTelemetry = trackEventSpy.getCall(0).args[0] as IEventTelemetry;\n\t\tconst actualContainerTelemetry =\n\t\t\tactualAppInsightsTelemetry.properties as IContainerTelemetry;\n\n\t\tconst expectedAppInsightsTelemetry: IEventTelemetry = {\n\t\t\tname: ContainerTelemetryEventNames.DISCONNECTED,\n\t\t\tproperties: {\n\t\t\t\teventName: ContainerTelemetryEventNames.DISCONNECTED,\n\t\t\t\tcontainerId: mockContainerId,\n\t\t\t\tcontainerInstanceId: actualContainerTelemetry.containerInstanceId,\n\t\t\t} satisfies ContainerDisconnectedTelemetry,\n\t\t};\n\n\t\texpect(expectedAppInsightsTelemetry).to.deep.equal(actualAppInsightsTelemetry);\n\t\t// We won't know what the container containerInstanceId will be but we can still check that it is defined.\n\t\texpect(actualContainerTelemetry.containerInstanceId).to.be.a(\"string\").with.length.above(0);\n\t});\n\n\tit(\"Emitting 'disposed' system event produces expected ContainerDisposedTelemetry using Azure App Insights\", () => {\n\t\tstartTelemetry(telemetryConfig);\n\n\t\tmockFluidContainer.dispose();\n\n\t\texpect(trackEventSpy.callCount).to.equal(1);\n\n\t\t// Obtain the events from the method that the spy was called with\n\t\tconst actualAppInsightsTelemetry = trackEventSpy.getCall(0).args[0] as IEventTelemetry;\n\t\tconst actualContainerTelemetry =\n\t\t\tactualAppInsightsTelemetry.properties as IContainerTelemetry;\n\n\t\tconst expectedAppInsightsTelemetry: IEventTelemetry = {\n\t\t\tname: ContainerTelemetryEventNames.DISPOSED,\n\t\t\tproperties: {\n\t\t\t\teventName: ContainerTelemetryEventNames.DISPOSED,\n\t\t\t\tcontainerId: mockContainerId,\n\t\t\t\tcontainerInstanceId: actualContainerTelemetry.containerInstanceId,\n\t\t\t} satisfies ContainerDisposedTelemetry,\n\t\t};\n\n\t\texpect(expectedAppInsightsTelemetry).to.deep.equal(actualAppInsightsTelemetry);\n\t\t// We won't know what the container containerInstanceId will be but we can still check that it is defined.\n\t\texpect(actualContainerTelemetry.containerInstanceId).to.be.a(\"string\").with.length.above(0);\n\t});\n\n\tit(\"Emitting 'disposed' system event with an error produces expected ContainerDisposedTelemetry using Azure App Insights\", () => {\n\t\tstartTelemetry(telemetryConfig);\n\n\t\tconst containerError: ICriticalContainerError = {\n\t\t\terrorType: \"unknown error\",\n\t\t\tmessage: \"An unknown error occured\",\n\t\t\tstack: \"example stack error at line 52 of Container.ts\",\n\t\t};\n\n\t\tmockFluidContainer.dispose(containerError);\n\n\t\t// Obtain the events from the method that the spy was called with\n\t\tconst actualAppInsightsTelemetry = trackEventSpy.getCall(0).args[0] as IEventTelemetry;\n\t\tconst actualContainerTelemetry =\n\t\t\tactualAppInsightsTelemetry.properties as IContainerTelemetry;\n\n\t\tconst expectedAppInsightsTelemetry: IEventTelemetry = {\n\t\t\tname: ContainerTelemetryEventNames.DISPOSED,\n\t\t\tproperties: {\n\t\t\t\teventName: ContainerTelemetryEventNames.DISPOSED,\n\t\t\t\tcontainerId: mockContainerId,\n\t\t\t\tcontainerInstanceId: actualContainerTelemetry.containerInstanceId,\n\t\t\t\terror: containerError,\n\t\t\t} satisfies ContainerDisposedTelemetry,\n\t\t};\n\n\t\texpect(expectedAppInsightsTelemetry).to.deep.equal(actualAppInsightsTelemetry);\n\t\t// We won't know what the container containerInstanceId will be but we can still check that it is defined.\n\t\texpect(actualContainerTelemetry.containerInstanceId).to.be.a(\"string\").with.length.above(0);\n\t});\n});\n"]}
@@ -0,0 +1,6 @@
1
+ /*!
2
+ * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
+ * Licensed under the MIT License.
4
+ */
5
+ export {};
6
+ //# sourceMappingURL=containerTelemetryEndToEnd.spec.realsvc.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"containerTelemetryEndToEnd.spec.realsvc.d.ts","sourceRoot":"","sources":["../../src/test/containerTelemetryEndToEnd.spec.realsvc.ts"],"names":[],"mappings":"AAAA;;;GAGG"}
@@ -0,0 +1,154 @@
1
+ /*!
2
+ * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
+ * Licensed under the MIT License.
4
+ */
5
+ import { timeoutPromise } from "@fluidframework/test-utils/internal";
6
+ import { TinyliciousClient } from "@fluidframework/tinylicious-client/internal";
7
+ import { SharedTree } from "@fluidframework/tree/internal";
8
+ import { expect } from "chai";
9
+ import { spy } from "sinon";
10
+ import { startTelemetry } from "../factory/index.js";
11
+ import { ContainerTelemetryEventNames, } from "../index.js";
12
+ // This test suite creates an actual IFluidContainer and confirms events are fired with the expected names during the expected events
13
+ describe("container telemetry E2E", () => {
14
+ let schema;
15
+ let tinyliciousClient;
16
+ let telemetryConsumerConsumeSpy;
17
+ let testTelemetryConsumer;
18
+ // Simple test class that will be used as the telemetry consumer.
19
+ class TestTelemetryConsumer {
20
+ consume(event) {
21
+ return;
22
+ }
23
+ }
24
+ before(() => {
25
+ tinyliciousClient = new TinyliciousClient({ connection: { port: 7070 } });
26
+ schema = {
27
+ initialObjects: {
28
+ sharedTree1: SharedTree,
29
+ },
30
+ };
31
+ testTelemetryConsumer = new TestTelemetryConsumer();
32
+ telemetryConsumerConsumeSpy = spy(testTelemetryConsumer, "consume");
33
+ });
34
+ beforeEach(() => {
35
+ // We need to reset the telemetry consumer spy for each test so the trackEvent calls
36
+ // from the last test don't bleed into the next one.
37
+ telemetryConsumerConsumeSpy.resetHistory();
38
+ });
39
+ it("IFluid container's 'connected' system event produces expected ContainerConnectedTelemetry using ITelemetryConsumer", async () => {
40
+ const { container } = await tinyliciousClient.createContainer(schema, "2");
41
+ const containerId = await container.attach();
42
+ startTelemetry({
43
+ container,
44
+ containerId,
45
+ consumers: [testTelemetryConsumer],
46
+ });
47
+ // We don't know exactly when the given container events that we're looking for will fire so we have to
48
+ // wrap the container.on(...) event handler within a promise that will be awaited at the end of the test.
49
+ const { actualContainerTelemetry, expectedContainerTelemetry } = await timeoutPromise((resolve) => {
50
+ container.on("connected", () => {
51
+ // We are making an assumption here that the 'connected' event is the first and only event sent to the ITelemetryConsumer.
52
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
53
+ const containerTelemetryFromSpy = telemetryConsumerConsumeSpy.getCalls()[0]
54
+ .args[0];
55
+ resolve({
56
+ actualContainerTelemetry: containerTelemetryFromSpy,
57
+ expectedContainerTelemetry: {
58
+ eventName: ContainerTelemetryEventNames.CONNECTED,
59
+ containerId,
60
+ // containerInstanceId is a uniquely generated UUID by the fluid-telemetry's ContainerEventTelemetryProducer class.
61
+ // We can't use the underlying container's id because it is not exposed by IFluidContainer.
62
+ containerInstanceId: containerTelemetryFromSpy.containerInstanceId,
63
+ },
64
+ });
65
+ });
66
+ }, { durationMs: 5000, errorMsg: "timeout while waiting for container 'connected' event" });
67
+ expect(expectedContainerTelemetry).to.deep.equal(actualContainerTelemetry);
68
+ // We won't know what the container containerInstanceId will be but we can still check that it is defined.
69
+ expect(actualContainerTelemetry.containerInstanceId).to.be.a("string").with.length.above(0);
70
+ });
71
+ it("IFluid container's 'disconnected' system event produces expected ContainerDisconnectedTelemetry using ITelemetryConsumer", async () => {
72
+ const { container } = await tinyliciousClient.createContainer(schema, "2");
73
+ const containerId = await container.attach();
74
+ startTelemetry({
75
+ container,
76
+ containerId,
77
+ consumers: [testTelemetryConsumer],
78
+ });
79
+ // We don't know exactly when the given container events that we're looking for will fire so we have to
80
+ // wrap the container.on(...) event handler within a promise that will be awaited at the end of the test.
81
+ const { actualContainerTelemetry, expectedContainerTelemetry } = await timeoutPromise((resolve) => {
82
+ // Event handler 1: As soon as the container connects, we're ready to initiate a disconnect.
83
+ container.on("connected", () => {
84
+ container.disconnect();
85
+ });
86
+ container.on("disconnected", () => {
87
+ // We are making an assumption here that the 'disconnected' event is the second sent to the ITelemetryConsumer.
88
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
89
+ const containerTelemetryFromSpy = telemetryConsumerConsumeSpy.getCalls()[1]
90
+ .args[0];
91
+ resolve({
92
+ actualContainerTelemetry: containerTelemetryFromSpy,
93
+ expectedContainerTelemetry: {
94
+ eventName: ContainerTelemetryEventNames.DISCONNECTED,
95
+ containerId,
96
+ // containerInstanceId is a uniquely generated UUID by the fluid-telemetry's ContainerEventTelemetryProducer class.
97
+ // We can't use the underlying container's id because it is not exposed by IFluidContainer.
98
+ containerInstanceId: containerTelemetryFromSpy.containerInstanceId,
99
+ },
100
+ });
101
+ });
102
+ }, {
103
+ durationMs: 5000,
104
+ errorMsg: "timeout while waiting for container 'connected' and/or 'disconnected' event",
105
+ });
106
+ expect(expectedContainerTelemetry).to.deep.equal(actualContainerTelemetry);
107
+ // We won't know what the container containerInstanceId will be but we can still check that it is defined.
108
+ expect(actualContainerTelemetry.containerInstanceId).to.be.a("string").with.length.above(0);
109
+ });
110
+ it("IFluid container's 'disposed' system event produces expected ContainerDisposedTelemetry using ITelemetryConsumer", async () => {
111
+ const { container } = await tinyliciousClient.createContainer(schema, "2");
112
+ const containerId = await container.attach();
113
+ startTelemetry({
114
+ container,
115
+ containerId,
116
+ consumers: [testTelemetryConsumer],
117
+ });
118
+ // We don't know exactly when the given container events that we're looking for will fire so we have to
119
+ // wrap the container.on(...) event handler within a promise that will be awaited at the end of the test.
120
+ const { actualContainerTelemetry, expectedContainerTelemetry } = await timeoutPromise((resolve, reject) => {
121
+ // Event handler 1: As soon as the container connects, we're ready to initiate a disconnect.
122
+ container.on("connected", () => {
123
+ container.disconnect();
124
+ });
125
+ // Event handler 2: As soon as the container disconnects, we're ready to initiate a dispose.
126
+ container.on("disconnected", () => {
127
+ container.dispose();
128
+ });
129
+ container.on("disposed", () => {
130
+ // We are making an assumption here that the 'disposed' event is the third sent to the ITelemetryConsumer.
131
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
132
+ const containerTelemetryFromSpy = telemetryConsumerConsumeSpy.getCalls()[2]
133
+ .args[0];
134
+ resolve({
135
+ actualContainerTelemetry: containerTelemetryFromSpy,
136
+ expectedContainerTelemetry: {
137
+ eventName: ContainerTelemetryEventNames.DISPOSED,
138
+ containerId,
139
+ // containerInstanceId is a uniquely generated UUID by the fluid-telemetry's ContainerEventTelemetryProducer class.
140
+ // We can't use the underlying container's id because it is not exposed by IFluidContainer.
141
+ containerInstanceId: containerTelemetryFromSpy.containerInstanceId,
142
+ },
143
+ });
144
+ });
145
+ }, {
146
+ durationMs: 5000,
147
+ errorMsg: "timeout while waiting for container 'connected' and/or 'disconnected' event",
148
+ });
149
+ expect(expectedContainerTelemetry).to.deep.equal(actualContainerTelemetry);
150
+ // We won't know what the container containerInstanceId will be but we can still check that it is defined.
151
+ expect(actualContainerTelemetry.containerInstanceId).to.be.a("string").with.length.above(0);
152
+ });
153
+ });
154
+ //# sourceMappingURL=containerTelemetryEndToEnd.spec.realsvc.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"containerTelemetryEndToEnd.spec.realsvc.js","sourceRoot":"","sources":["../../src/test/containerTelemetryEndToEnd.spec.realsvc.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport type { ContainerSchema } from \"@fluidframework/fluid-static\";\nimport { timeoutPromise } from \"@fluidframework/test-utils/internal\";\nimport { TinyliciousClient } from \"@fluidframework/tinylicious-client/internal\";\nimport { SharedTree } from \"@fluidframework/tree/internal\";\nimport { expect } from \"chai\";\nimport type Sinon from \"sinon\";\nimport { spy } from \"sinon\";\n\nimport { startTelemetry } from \"../factory/index.js\";\nimport {\n\tContainerTelemetryEventNames,\n\ttype ContainerConnectedTelemetry,\n\ttype ContainerDisconnectedTelemetry,\n\ttype ContainerDisposedTelemetry,\n\ttype IFluidTelemetry,\n\ttype ITelemetryConsumer,\n} from \"../index.js\";\n\n// This test suite creates an actual IFluidContainer and confirms events are fired with the expected names during the expected events\n\ndescribe(\"container telemetry E2E\", () => {\n\tlet schema: ContainerSchema;\n\tlet tinyliciousClient: TinyliciousClient;\n\tlet telemetryConsumerConsumeSpy: Sinon.SinonSpy;\n\tlet testTelemetryConsumer: ITelemetryConsumer;\n\n\t// Simple test class that will be used as the telemetry consumer.\n\tclass TestTelemetryConsumer implements ITelemetryConsumer {\n\t\tpublic consume(event: IFluidTelemetry): void {\n\t\t\treturn;\n\t\t}\n\t}\n\n\tbefore(() => {\n\t\ttinyliciousClient = new TinyliciousClient({ connection: { port: 7070 } });\n\t\tschema = {\n\t\t\tinitialObjects: {\n\t\t\t\tsharedTree1: SharedTree,\n\t\t\t},\n\t\t};\n\n\t\ttestTelemetryConsumer = new TestTelemetryConsumer();\n\t\ttelemetryConsumerConsumeSpy = spy(testTelemetryConsumer, \"consume\");\n\t});\n\n\tbeforeEach(() => {\n\t\t// We need to reset the telemetry consumer spy for each test so the trackEvent calls\n\t\t// from the last test don't bleed into the next one.\n\t\ttelemetryConsumerConsumeSpy.resetHistory();\n\t});\n\n\tit(\"IFluid container's 'connected' system event produces expected ContainerConnectedTelemetry using ITelemetryConsumer\", async () => {\n\t\tconst { container } = await tinyliciousClient.createContainer(schema, \"2\");\n\n\t\tconst containerId = await container.attach();\n\t\tstartTelemetry({\n\t\t\tcontainer,\n\t\t\tcontainerId,\n\t\t\tconsumers: [testTelemetryConsumer],\n\t\t});\n\n\t\t// We don't know exactly when the given container events that we're looking for will fire so we have to\n\t\t// wrap the container.on(...) event handler within a promise that will be awaited at the end of the test.\n\t\tconst { actualContainerTelemetry, expectedContainerTelemetry } = await timeoutPromise<{\n\t\t\tactualContainerTelemetry: ContainerConnectedTelemetry;\n\t\t\texpectedContainerTelemetry: ContainerConnectedTelemetry;\n\t\t}>(\n\t\t\t(resolve) => {\n\t\t\t\tcontainer.on(\"connected\", () => {\n\t\t\t\t\t// We are making an assumption here that the 'connected' event is the first and only event sent to the ITelemetryConsumer.\n\t\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n\t\t\t\t\tconst containerTelemetryFromSpy = telemetryConsumerConsumeSpy.getCalls()[0]!\n\t\t\t\t\t\t.args[0] as ContainerConnectedTelemetry;\n\n\t\t\t\t\tresolve({\n\t\t\t\t\t\tactualContainerTelemetry: containerTelemetryFromSpy,\n\t\t\t\t\t\texpectedContainerTelemetry: {\n\t\t\t\t\t\t\teventName: ContainerTelemetryEventNames.CONNECTED,\n\t\t\t\t\t\t\tcontainerId,\n\t\t\t\t\t\t\t// containerInstanceId is a uniquely generated UUID by the fluid-telemetry's ContainerEventTelemetryProducer class.\n\t\t\t\t\t\t\t// We can't use the underlying container's id because it is not exposed by IFluidContainer.\n\t\t\t\t\t\t\tcontainerInstanceId: containerTelemetryFromSpy.containerInstanceId,\n\t\t\t\t\t\t},\n\t\t\t\t\t});\n\t\t\t\t});\n\t\t\t},\n\t\t\t{ durationMs: 5000, errorMsg: \"timeout while waiting for container 'connected' event\" },\n\t\t);\n\n\t\texpect(expectedContainerTelemetry).to.deep.equal(actualContainerTelemetry);\n\t\t// We won't know what the container containerInstanceId will be but we can still check that it is defined.\n\t\texpect(actualContainerTelemetry.containerInstanceId).to.be.a(\"string\").with.length.above(0);\n\t});\n\n\tit(\"IFluid container's 'disconnected' system event produces expected ContainerDisconnectedTelemetry using ITelemetryConsumer\", async () => {\n\t\tconst { container } = await tinyliciousClient.createContainer(schema, \"2\");\n\n\t\tconst containerId = await container.attach();\n\t\tstartTelemetry({\n\t\t\tcontainer,\n\t\t\tcontainerId,\n\t\t\tconsumers: [testTelemetryConsumer],\n\t\t});\n\n\t\t// We don't know exactly when the given container events that we're looking for will fire so we have to\n\t\t// wrap the container.on(...) event handler within a promise that will be awaited at the end of the test.\n\t\tconst { actualContainerTelemetry, expectedContainerTelemetry } = await timeoutPromise<{\n\t\t\tactualContainerTelemetry: ContainerDisconnectedTelemetry;\n\t\t\texpectedContainerTelemetry: ContainerDisconnectedTelemetry;\n\t\t}>(\n\t\t\t(resolve) => {\n\t\t\t\t// Event handler 1: As soon as the container connects, we're ready to initiate a disconnect.\n\t\t\t\tcontainer.on(\"connected\", () => {\n\t\t\t\t\tcontainer.disconnect();\n\t\t\t\t});\n\n\t\t\t\tcontainer.on(\"disconnected\", () => {\n\t\t\t\t\t// We are making an assumption here that the 'disconnected' event is the second sent to the ITelemetryConsumer.\n\t\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n\t\t\t\t\tconst containerTelemetryFromSpy = telemetryConsumerConsumeSpy.getCalls()[1]!\n\t\t\t\t\t\t.args[0] as ContainerDisconnectedTelemetry;\n\n\t\t\t\t\tresolve({\n\t\t\t\t\t\tactualContainerTelemetry: containerTelemetryFromSpy,\n\t\t\t\t\t\texpectedContainerTelemetry: {\n\t\t\t\t\t\t\teventName: ContainerTelemetryEventNames.DISCONNECTED,\n\t\t\t\t\t\t\tcontainerId,\n\t\t\t\t\t\t\t// containerInstanceId is a uniquely generated UUID by the fluid-telemetry's ContainerEventTelemetryProducer class.\n\t\t\t\t\t\t\t// We can't use the underlying container's id because it is not exposed by IFluidContainer.\n\t\t\t\t\t\t\tcontainerInstanceId: containerTelemetryFromSpy.containerInstanceId,\n\t\t\t\t\t\t},\n\t\t\t\t\t});\n\t\t\t\t});\n\t\t\t},\n\t\t\t{\n\t\t\t\tdurationMs: 5000,\n\t\t\t\terrorMsg:\n\t\t\t\t\t\"timeout while waiting for container 'connected' and/or 'disconnected' event\",\n\t\t\t},\n\t\t);\n\n\t\texpect(expectedContainerTelemetry).to.deep.equal(actualContainerTelemetry);\n\t\t// We won't know what the container containerInstanceId will be but we can still check that it is defined.\n\t\texpect(actualContainerTelemetry.containerInstanceId).to.be.a(\"string\").with.length.above(0);\n\t});\n\n\tit(\"IFluid container's 'disposed' system event produces expected ContainerDisposedTelemetry using ITelemetryConsumer\", async () => {\n\t\tconst { container } = await tinyliciousClient.createContainer(schema, \"2\");\n\n\t\tconst containerId = await container.attach();\n\t\tstartTelemetry({\n\t\t\tcontainer,\n\t\t\tcontainerId,\n\t\t\tconsumers: [testTelemetryConsumer],\n\t\t});\n\n\t\t// We don't know exactly when the given container events that we're looking for will fire so we have to\n\t\t// wrap the container.on(...) event handler within a promise that will be awaited at the end of the test.\n\t\tconst { actualContainerTelemetry, expectedContainerTelemetry } = await timeoutPromise<{\n\t\t\tactualContainerTelemetry: ContainerDisposedTelemetry;\n\t\t\texpectedContainerTelemetry: ContainerDisposedTelemetry;\n\t\t}>(\n\t\t\t(resolve, reject) => {\n\t\t\t\t// Event handler 1: As soon as the container connects, we're ready to initiate a disconnect.\n\t\t\t\tcontainer.on(\"connected\", () => {\n\t\t\t\t\tcontainer.disconnect();\n\t\t\t\t});\n\n\t\t\t\t// Event handler 2: As soon as the container disconnects, we're ready to initiate a dispose.\n\t\t\t\tcontainer.on(\"disconnected\", () => {\n\t\t\t\t\tcontainer.dispose();\n\t\t\t\t});\n\n\t\t\t\tcontainer.on(\"disposed\", () => {\n\t\t\t\t\t// We are making an assumption here that the 'disposed' event is the third sent to the ITelemetryConsumer.\n\t\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n\t\t\t\t\tconst containerTelemetryFromSpy = telemetryConsumerConsumeSpy.getCalls()[2]!\n\t\t\t\t\t\t.args[0] as ContainerDisposedTelemetry;\n\n\t\t\t\t\tresolve({\n\t\t\t\t\t\tactualContainerTelemetry: containerTelemetryFromSpy,\n\t\t\t\t\t\texpectedContainerTelemetry: {\n\t\t\t\t\t\t\teventName: ContainerTelemetryEventNames.DISPOSED,\n\t\t\t\t\t\t\tcontainerId,\n\t\t\t\t\t\t\t// containerInstanceId is a uniquely generated UUID by the fluid-telemetry's ContainerEventTelemetryProducer class.\n\t\t\t\t\t\t\t// We can't use the underlying container's id because it is not exposed by IFluidContainer.\n\t\t\t\t\t\t\tcontainerInstanceId: containerTelemetryFromSpy.containerInstanceId,\n\t\t\t\t\t\t},\n\t\t\t\t\t});\n\t\t\t\t});\n\t\t\t},\n\t\t\t{\n\t\t\t\tdurationMs: 5000,\n\t\t\t\terrorMsg:\n\t\t\t\t\t\"timeout while waiting for container 'connected' and/or 'disconnected' event\",\n\t\t\t},\n\t\t);\n\n\t\texpect(expectedContainerTelemetry).to.deep.equal(actualContainerTelemetry);\n\t\t// We won't know what the container containerInstanceId will be but we can still check that it is defined.\n\t\texpect(actualContainerTelemetry.containerInstanceId).to.be.a(\"string\").with.length.above(0);\n\t});\n});\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fluidframework/fluid-telemetry",
3
- "version": "2.0.0-dev-rc.5.0.0.268409",
3
+ "version": "2.0.0-dev-rc.5.0.0.270987",
4
4
  "description": "Customer facing Fluid telemetry types and classes for both producing and consuming said telemetry",
5
5
  "homepage": "https://fluidframework.com",
6
6
  "repository": {
@@ -57,18 +57,22 @@
57
57
  "main": "lib/index.js",
58
58
  "types": "lib/index.d.ts",
59
59
  "dependencies": {
60
- "@fluidframework/container-definitions": "2.0.0-dev-rc.5.0.0.268409",
61
- "@fluidframework/container-loader": "2.0.0-dev-rc.5.0.0.268409",
62
- "@fluidframework/fluid-static": "2.0.0-dev-rc.5.0.0.268409",
60
+ "@fluidframework/container-definitions": "2.0.0-dev-rc.5.0.0.270987",
61
+ "@fluidframework/container-loader": "2.0.0-dev-rc.5.0.0.270987",
62
+ "@fluidframework/fluid-static": "2.0.0-dev-rc.5.0.0.270987",
63
63
  "@microsoft/applicationinsights-web": "^2.8.11",
64
64
  "uuid": "^9.0.0"
65
65
  },
66
66
  "devDependencies": {
67
67
  "@arethetypeswrong/cli": "^0.15.2",
68
- "@fluid-internal/client-utils": "2.0.0-dev-rc.5.0.0.268409",
69
- "@fluid-internal/mocha-test-setup": "2.0.0-dev-rc.5.0.0.268409",
70
- "@fluid-tools/build-cli": "^0.39.0-264124",
71
- "@fluidframework/build-tools": "^0.39.0-264124",
68
+ "@biomejs/biome": "^1.7.3",
69
+ "@fluid-internal/client-utils": "2.0.0-dev-rc.5.0.0.270987",
70
+ "@fluid-internal/mocha-test-setup": "2.0.0-dev-rc.5.0.0.270987",
71
+ "@fluid-tools/build-cli": "^0.39.0",
72
+ "@fluidframework/build-tools": "^0.39.0",
73
+ "@fluidframework/test-utils": "2.0.0-dev-rc.5.0.0.270987",
74
+ "@fluidframework/tinylicious-client": "2.0.0-dev-rc.5.0.0.270987",
75
+ "@fluidframework/tree": "2.0.0-dev-rc.5.0.0.270987",
72
76
  "@microsoft/api-extractor": "^7.45.1",
73
77
  "@types/chai": "^4.0.0",
74
78
  "@types/mocha": "^9.1.1",
@@ -81,6 +85,8 @@
81
85
  "prettier": "~3.0.3",
82
86
  "rimraf": "^4.4.0",
83
87
  "sinon": "^17.0.1",
88
+ "start-server-and-test": "^2.0.3",
89
+ "tinylicious": "^5.0.0-265463",
84
90
  "tslib": "^1.10.0",
85
91
  "typescript": "~5.4.5"
86
92
  },
@@ -105,21 +111,35 @@
105
111
  "build:docs": "api-extractor run --local",
106
112
  "build:esnext": "tsc --project ./tsconfig.json",
107
113
  "check:are-the-types-wrong": "attw --pack .",
114
+ "check:biome": "biome check . --formatter-enabled=true",
115
+ "check:format": "npm run check:prettier",
116
+ "check:prettier": "prettier --check . --cache --ignore-path ../../../../.prettierignore",
108
117
  "check:release-tags": "api-extractor run --local --config ./api-extractor-lint.json",
109
118
  "ci:build:docs": "api-extractor run",
110
119
  "clean": "rimraf --glob _api-extractor-temp coverage dist lib \"*.d.ts\" nyc \"**/*.tsbuildinfo\" \"**/*.build.log\"",
111
120
  "eslint": "eslint --format stylish src",
112
121
  "eslint:fix": "eslint --format stylish src --fix --fix-type problem,suggestion,layout",
113
- "format": "fluid-build --task format .",
122
+ "format": "npm run format:prettier",
114
123
  "format-and-build": "npm run format && npm run build",
115
124
  "format-and-compile": "npm run format && npm run build:compile",
125
+ "format:biome": "biome check . --formatter-enabled=true --apply",
116
126
  "format:prettier": "prettier --write . --cache --ignore-path ../../../../.prettierignore",
117
127
  "lint": "fluid-build . --task lint",
118
128
  "lint:fix": "fluid-build . --task eslint:fix --task format",
119
- "test": "npm run test:mocha",
120
- "test:mocha": "npm run test:mocha:esm && echo skipping cjs to avoid overhead - npm run test:mocha:cjs",
121
- "test:mocha:cjs": "mocha --recursive \"dist/test/**/*.spec.*js\" --exit",
122
- "test:mocha:esm": "mocha --recursive \"lib/test/**/*.spec.*js\" --exit",
129
+ "start:tinylicious:test": "tinylicious > tinylicious.log 2>&1",
130
+ "test": "start-server-and-test start:tinylicious:test 7070 test:mocha:all",
131
+ "test:mocha": "npm run test:mocha:esm:unit && echo skipping cjs to avoid overhead - npm run test:mocha:cjs:unit",
132
+ "test:mocha:all": "npm run test:mocha:esm:all && echo skipping cjs to avoid overhead - npm run test:mocha:cjs:all",
133
+ "test:mocha:cjs:all": "mocha --recursive \"dist/test/**/*.spec*.js\" --exit",
134
+ "test:mocha:cjs:end-to-end": "mocha --recursive \"dist/test/**/*.spec.realsvc.js\" --exit",
135
+ "test:mocha:cjs:unit": "mocha --recursive \"dist/test/**/*.spec.js\" --exit",
136
+ "test:mocha:end-to-end": "npm run test:mocha:esm:end-to-end && echo skipping cjs to avoid overhead - npm run test:mocha:cjs:end-to-end",
137
+ "test:mocha:esm:all": "mocha --recursive \"lib/test/**/*.spec*.js\" --exit",
138
+ "test:mocha:esm:end-to-end": "mocha --recursive \"lib/test/**/*.spec.realsvc.js\" --exit",
139
+ "test:mocha:esm:unit": "mocha --recursive \"lib/test/**/*.spec.js\" --exit",
140
+ "test:realsvc": "npm run test:realsvc:tinylicious",
141
+ "test:realsvc:tinylicious": "start-server-and-test start:tinylicious:test 7070 test:realsvc:tinylicious:run",
142
+ "test:realsvc:tinylicious:run": "npm run test:mocha:end-to-end",
123
143
  "tsc": "fluid-tsc commonjs --project ./tsconfig.cjs.json && copyfiles -f ../../../../common/build/build-common/src/cjs/package.json ./dist",
124
144
  "typetests:gen": "flub generate typetests --dir . -v --publicFallback",
125
145
  "typetests:prepare": "flub typetests --dir . --reset --previous --normalize"
package/tsconfig.json CHANGED
@@ -8,5 +8,6 @@
8
8
  "rootDir": "src",
9
9
  "outDir": "./lib",
10
10
  "types": ["mocha"],
11
+ "exactOptionalPropertyTypes": false,
11
12
  },
12
13
  }