@snap/camera-kit 0.10.0 → 0.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/docs/html/assets/search.js +1 -1
- package/docs/html/classes/CameraKit.html +116 -100
- package/docs/html/classes/CameraKitSession.html +175 -153
- package/docs/html/classes/CameraKitSource.html +109 -101
- package/docs/html/classes/LensPerformanceMeasurement.html +98 -94
- package/docs/html/classes/LensPerformanceMetrics.html +83 -81
- package/docs/html/classes/LensRepository.html +120 -109
- package/docs/html/classes/LensSources.html +86 -82
- package/docs/html/classes/Transform2D.html +98 -94
- package/docs/html/classes/TypedCustomEvent.html +83 -82
- package/docs/html/classes/TypedEventTarget.html +92 -91
- package/docs/html/functions/Injectable.html +87 -80
- package/docs/html/functions/bootstrapCameraKit.html +89 -86
- package/docs/html/functions/createExtension.html +76 -75
- package/docs/html/functions/createImageSource.html +80 -77
- package/docs/html/functions/createMediaStreamSource.html +80 -77
- package/docs/html/functions/createUserMediaSource.html +84 -81
- package/docs/html/functions/createVideoSource.html +80 -77
- package/docs/html/functions/estimateLensPerformance.html +76 -75
- package/docs/html/functions/getRequiredBootstrapURLs.html +78 -76
- package/docs/html/functions/lensSourcesFactory.html +74 -74
- package/docs/html/functions/uriHandlersFactory.html +76 -75
- package/docs/html/index.html +75 -75
- package/docs/html/interfaces/CameraKitBootstrapConfiguration.html +107 -100
- package/docs/html/interfaces/CameraKitSourceSubscriber.html +82 -81
- package/docs/html/interfaces/ComputedFrameMetrics.html +94 -84
- package/docs/html/interfaces/CreateSessionOptions.html +86 -83
- package/docs/html/interfaces/EstimatedLensPerformance.html +85 -84
- package/docs/html/interfaces/Lens.html +114 -106
- package/docs/html/interfaces/LensSource.html +102 -94
- package/docs/html/interfaces/MediaStreamSourceOptions.html +80 -80
- package/docs/html/interfaces/Preview.html +81 -79
- package/docs/html/interfaces/Snapcode.html +86 -83
- package/docs/html/interfaces/UriCancelRequest.html +80 -80
- package/docs/html/interfaces/UriHandler.html +102 -93
- package/docs/html/interfaces/UriRequest.html +89 -89
- package/docs/html/interfaces/UriResponse.html +89 -89
- package/docs/html/interfaces/VideoSourceOptions.html +77 -77
- package/docs/html/modules.html +153 -153
- package/docs/html/types/AssetLoader.html +75 -74
- package/docs/html/types/AssetTiming.html +75 -74
- package/docs/html/types/BenchmarkError.html +73 -73
- package/docs/html/types/BootstrapError.html +75 -74
- package/docs/html/types/CacheKeyNotFoundError.html +73 -73
- package/docs/html/types/CameraKitDeviceInfo.html +75 -74
- package/docs/html/types/CameraKitSessionEventListener.html +75 -74
- package/docs/html/types/CameraKitSessionEvents.html +82 -74
- package/docs/html/types/CameraKitSourceError.html +73 -73
- package/docs/html/types/CameraKitSourceInfo.html +73 -73
- package/docs/html/types/CameraKitSourceOptions.html +75 -74
- package/docs/html/types/ConfigurationError.html +75 -74
- package/docs/html/types/Keyboard.html +85 -80
- package/docs/html/types/KeyboardEvents.html +84 -74
- package/docs/html/types/LegalError.html +73 -73
- package/docs/html/types/LensAssetError.html +75 -74
- package/docs/html/types/LensContentValidationError.html +73 -73
- package/docs/html/types/LensError.html +73 -73
- package/docs/html/types/LensExecutionError.html +75 -74
- package/docs/html/types/LensImagePickerError.html +75 -74
- package/docs/html/types/LensLaunchParams.html +75 -74
- package/docs/html/types/LensMetricsEvents.html +75 -74
- package/docs/html/types/LensPerformanceCluster.html +75 -74
- package/docs/html/types/LensView.html +75 -74
- package/docs/html/types/LensWait.html +75 -74
- package/docs/html/types/PersistentStoreError.html +75 -74
- package/docs/html/types/PlatformNotSupportedError.html +75 -74
- package/docs/html/types/PublicContainer.html +75 -74
- package/docs/html/types/RenderTarget.html +75 -74
- package/docs/html/types/Uri.html +73 -73
- package/docs/html/types/UriHandlers.html +75 -74
- package/docs/html/types/WebGLError.html +73 -73
- package/docs/html/variables/extensionRequestContext.html +75 -74
- package/docs/md/classes/CameraKit.md +14 -1
- package/docs/md/classes/CameraKitSession.md +1 -1
- package/docs/md/classes/CameraKitSource.md +1 -1
- package/docs/md/classes/LensPerformanceMeasurement.md +1 -1
- package/docs/md/classes/LensPerformanceMetrics.md +1 -1
- package/docs/md/classes/LensRepository.md +1 -1
- package/docs/md/classes/LensSources.md +1 -1
- package/docs/md/classes/Transform2D.md +1 -1
- package/docs/md/classes/TypedCustomEvent.md +1 -1
- package/docs/md/classes/TypedEventTarget.md +1 -1
- package/docs/md/interfaces/CameraKitBootstrapConfiguration.md +1 -1
- package/docs/md/interfaces/CameraKitSourceSubscriber.md +1 -1
- package/docs/md/interfaces/ComputedFrameMetrics.md +15 -1
- package/docs/md/interfaces/CreateSessionOptions.md +1 -1
- package/docs/md/interfaces/EstimatedLensPerformance.md +1 -1
- package/docs/md/interfaces/Lens.md +1 -1
- package/docs/md/interfaces/LensSource.md +1 -1
- package/docs/md/interfaces/MediaStreamSourceOptions.md +1 -1
- package/docs/md/interfaces/Preview.md +1 -1
- package/docs/md/interfaces/Snapcode.md +1 -1
- package/docs/md/interfaces/UriCancelRequest.md +1 -1
- package/docs/md/interfaces/UriHandler.md +1 -1
- package/docs/md/interfaces/UriRequest.md +1 -1
- package/docs/md/interfaces/UriResponse.md +1 -1
- package/docs/md/interfaces/VideoSourceOptions.md +1 -1
- package/docs/md/modules.md +2 -2
- package/lib/CameraKit.d.ts +21 -12
- package/lib/CameraKit.js +32 -4
- package/lib/CameraKit.js.map +1 -1
- package/lib/bootstrapCameraKit.js +5 -3
- package/lib/bootstrapCameraKit.js.map +1 -1
- package/lib/common/__mocks__/loadScript.d.ts +1 -1
- package/lib/common/__mocks__/loadScript.js +1 -1
- package/lib/common/__mocks__/loadScript.js.map +1 -1
- package/lib/common/dialog.d.ts +16 -0
- package/lib/common/dialog.js +146 -0
- package/lib/common/dialog.js.map +1 -0
- package/lib/common/hash.d.ts +5 -0
- package/lib/common/hash.js +17 -0
- package/lib/common/hash.js.map +1 -0
- package/lib/common/loadScript.d.ts +6 -1
- package/lib/common/loadScript.js +9 -2
- package/lib/common/loadScript.js.map +1 -1
- package/lib/common/localization.d.ts +17 -10
- package/lib/common/localization.js +653 -18
- package/lib/common/localization.js.map +1 -1
- package/lib/common/pageVisibility.d.ts +34 -20
- package/lib/common/pageVisibility.js +57 -48
- package/lib/common/pageVisibility.js.map +1 -1
- package/lib/dependency-injection/Container.d.ts +2 -2
- package/lib/dependency-injection/Container.js +10 -10
- package/lib/dependency-injection/Container.js.map +1 -1
- package/lib/dependency-injection/RootServices.d.ts +3 -1
- package/lib/dependency-injection/RootServices.js.map +1 -1
- package/lib/environment.json +1 -1
- package/lib/extensions/LensSources.d.ts +5 -5
- package/lib/extensions/LensSources.js +9 -9
- package/lib/extensions/LensSources.js.map +1 -1
- package/lib/extensions/UriHandlers.d.ts +1 -1
- package/lib/generated-proto/pb_schema/camera_kit/v3/legal_prompt.d.ts +5 -0
- package/lib/generated-proto/pb_schema/camera_kit/v3/legal_prompt.js +61 -0
- package/lib/generated-proto/pb_schema/camera_kit/v3/legal_prompt.js.map +1 -1
- package/lib/generated-proto/pb_schema/camera_kit/v3/service.d.ts +49 -0
- package/lib/generated-proto/pb_schema/camera_kit/v3/service.js +17 -1
- package/lib/generated-proto/pb_schema/camera_kit/v3/service.js.map +1 -1
- package/lib/generated-proto/pb_schema/cdp/cof/circumstance_service.d.ts +578 -0
- package/lib/generated-proto/pb_schema/cdp/cof/config_response.d.ts +84 -0
- package/lib/generated-proto/pb_schema/cdp/cof/config_result.d.ts +222 -1
- package/lib/generated-proto/pb_schema/cdp/cof/config_result.js +98 -2
- package/lib/generated-proto/pb_schema/cdp/cof/config_result.js.map +1 -1
- package/lib/handlers/HandlerChainBuilder.js +7 -2
- package/lib/handlers/HandlerChainBuilder.js.map +1 -1
- package/lib/handlers/batchingHandler.d.ts +8 -2
- package/lib/handlers/batchingHandler.js +5 -8
- package/lib/handlers/batchingHandler.js.map +1 -1
- package/lib/handlers/mappingHandler.d.ts +5 -1
- package/lib/handlers/mappingHandler.js +6 -4
- package/lib/handlers/mappingHandler.js.map +1 -1
- package/lib/handlers/rateLimitingHandler.d.ts +5 -1
- package/lib/handlers/rateLimitingHandler.js +6 -4
- package/lib/handlers/rateLimitingHandler.js.map +1 -1
- package/lib/handlers/responseCachingHandler.d.ts +1 -1
- package/lib/handlers/responseCachingHandler.js.map +1 -1
- package/lib/handlers/retryingHandler.d.ts +5 -1
- package/lib/handlers/retryingHandler.js +13 -9
- package/lib/handlers/retryingHandler.js.map +1 -1
- package/lib/legal/legalPrompt.d.ts +7 -4
- package/lib/legal/legalPrompt.js +122 -133
- package/lib/legal/legalPrompt.js.map +1 -1
- package/lib/legal/legalState.d.ts +2 -2
- package/lib/legal/legalState.js +52 -38
- package/lib/legal/legalState.js.map +1 -1
- package/lib/lens-core-module/loader/lensCoreFactory.js +3 -1
- package/lib/lens-core-module/loader/lensCoreFactory.js.map +1 -1
- package/lib/lensCoreWasmVersions.json +3 -3
- package/lib/logger/logEntries.d.ts +1 -1
- package/lib/logger/logEntries.js +3 -3
- package/lib/logger/logEntries.js.map +1 -1
- package/lib/logger/logger.d.ts +7 -2
- package/lib/logger/logger.js +9 -4
- package/lib/logger/logger.js.map +1 -1
- package/lib/media-sources/MediaStreamSource.js +9 -4
- package/lib/media-sources/MediaStreamSource.js.map +1 -1
- package/lib/metrics/businessEventsReporter.d.ts +3 -2
- package/lib/metrics/businessEventsReporter.js +16 -9
- package/lib/metrics/businessEventsReporter.js.map +1 -1
- package/lib/metrics/metricsHandler.d.ts +3 -2
- package/lib/metrics/metricsHandler.js +3 -3
- package/lib/metrics/metricsHandler.js.map +1 -1
- package/lib/metrics/operational/Count.d.ts +17 -0
- package/lib/metrics/operational/Count.js +28 -0
- package/lib/metrics/operational/Count.js.map +1 -0
- package/lib/metrics/operational/Histogram.d.ts +17 -0
- package/lib/metrics/operational/Histogram.js +23 -0
- package/lib/metrics/operational/Histogram.js.map +1 -0
- package/lib/metrics/operational/Metric.d.ts +20 -0
- package/lib/metrics/operational/Metric.js +26 -0
- package/lib/metrics/operational/Metric.js.map +1 -0
- package/lib/metrics/operational/Timer.d.ts +91 -0
- package/lib/metrics/operational/Timer.js +122 -0
- package/lib/metrics/operational/Timer.js.map +1 -0
- package/lib/metrics/{operationalMetricsReporter.d.ts → operational/operationalMetricsReporter.d.ts} +15 -4
- package/lib/metrics/{operationalMetricsReporter.js → operational/operationalMetricsReporter.js} +24 -8
- package/lib/metrics/operational/operationalMetricsReporter.js.map +1 -0
- package/lib/metrics/reporters/reportBenchmarks.d.ts +1 -1
- package/lib/metrics/reporters/reportBenchmarks.js +1 -1
- package/lib/metrics/reporters/reportBenchmarks.js.map +1 -1
- package/lib/metrics/reporters/reportGlobalException.d.ts +1 -1
- package/lib/metrics/reporters/reportGlobalException.js +1 -1
- package/lib/metrics/reporters/reportGlobalException.js.map +1 -1
- package/lib/metrics/reporters/reportHttpMetrics.d.ts +1 -1
- package/lib/metrics/reporters/reportHttpMetrics.js +1 -1
- package/lib/metrics/reporters/reportHttpMetrics.js.map +1 -1
- package/lib/metrics/reporters/reportLegalState.d.ts +1 -1
- package/lib/metrics/reporters/reportLegalState.js +1 -1
- package/lib/metrics/reporters/reportLegalState.js.map +1 -1
- package/lib/metrics/reporters/reportLensAndAssetDownload.d.ts +1 -1
- package/lib/metrics/reporters/reportLensAndAssetDownload.js +1 -1
- package/lib/metrics/reporters/reportLensAndAssetDownload.js.map +1 -1
- package/lib/metrics/reporters/reportLensValidationFailed.d.ts +1 -1
- package/lib/metrics/reporters/reportLensView.d.ts +2 -2
- package/lib/metrics/reporters/reportLensView.js +23 -17
- package/lib/metrics/reporters/reportLensView.js.map +1 -1
- package/lib/metrics/reporters/reportLensWait.d.ts +2 -2
- package/lib/metrics/reporters/reportLensWait.js +1 -1
- package/lib/metrics/reporters/reportLensWait.js.map +1 -1
- package/lib/metrics/reporters/reportSessionException.d.ts +1 -1
- package/lib/metrics/reporters/reporters.d.ts +6 -6
- package/lib/metrics/reporters/reporters.js +3 -3
- package/lib/metrics/reporters/reporters.js.map +1 -1
- package/lib/observable-operators/unsubscribed.d.ts +12 -0
- package/lib/observable-operators/unsubscribed.js +27 -0
- package/lib/observable-operators/unsubscribed.js.map +1 -0
- package/lib/remote-configuration/cofHandler.d.ts +1 -1
- package/lib/remote-configuration/cofHandler.js.map +1 -1
- package/lib/remote-configuration/remoteConfiguration.d.ts +15 -4
- package/lib/remote-configuration/remoteConfiguration.js +30 -5
- package/lib/remote-configuration/remoteConfiguration.js.map +1 -1
- package/lib/session/CameraKitSession.d.ts +4 -3
- package/lib/session/CameraKitSession.js +6 -5
- package/lib/session/CameraKitSession.js.map +1 -1
- package/lib/session/LensKeyboard.d.ts +1 -1
- package/lib/session/LensPerformanceMeasurement.d.ts +2 -0
- package/lib/session/LensPerformanceMeasurement.js +27 -4
- package/lib/session/LensPerformanceMeasurement.js.map +1 -1
- package/lib/session/lensState.d.ts +5 -4
- package/lib/session/lensState.js +94 -39
- package/lib/session/lensState.js.map +1 -1
- package/package.json +12 -12
- package/lib/metrics/operationalMetricsReporter.js.map +0 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { MakeTaggedBusinessEvent } from "../businessEventsReporter";
|
|
2
2
|
import { MetricsEventTarget } from "../metricsEventTarget";
|
|
3
|
-
import { OperationalMetricsReporter } from "../operationalMetricsReporter";
|
|
3
|
+
import { OperationalMetricsReporter } from "../operational/operationalMetricsReporter";
|
|
4
4
|
/**
|
|
5
5
|
* The LegalPrompt metric reports each time a BIPA legal prompt is shown.
|
|
6
6
|
*/
|
|
@@ -5,7 +5,7 @@ import { TypedCustomEvent } from "../../events/TypedCustomEvent";
|
|
|
5
5
|
import { CameraKitLegalPromptResult } from "../../generated-proto/blizzard/cameraKitEvents";
|
|
6
6
|
import { legalStateFactory } from "../../legal/legalState";
|
|
7
7
|
import { metricsEventTargetFactory } from "../metricsEventTarget";
|
|
8
|
-
import { operationalMetricReporterFactory } from "../operationalMetricsReporter";
|
|
8
|
+
import { operationalMetricReporterFactory, } from "../operational/operationalMetricsReporter";
|
|
9
9
|
/**
|
|
10
10
|
* @internal
|
|
11
11
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reportLegalState.js","sourceRoot":"","sources":["../../../src/metrics/reporters/reportLegalState.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AACpD,OAAO,EAAE,GAAG,EAAE,MAAM,MAAM,CAAC;AAC3B,OAAO,EAAE,UAAU,EAAE,MAAM,uCAAuC,CAAC;AACnE,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AACjE,OAAO,EAAE,0BAA0B,EAAE,MAAM,gDAAgD,CAAC;AAC5F,OAAO,EAAc,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAEvE,OAAO,EAAsB,yBAAyB,EAAE,MAAM,uBAAuB,CAAC;AACtF,OAAO,
|
|
1
|
+
{"version":3,"file":"reportLegalState.js","sourceRoot":"","sources":["../../../src/metrics/reporters/reportLegalState.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AACpD,OAAO,EAAE,GAAG,EAAE,MAAM,MAAM,CAAC;AAC3B,OAAO,EAAE,UAAU,EAAE,MAAM,uCAAuC,CAAC;AACnE,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AACjE,OAAO,EAAE,0BAA0B,EAAE,MAAM,gDAAgD,CAAC;AAC5F,OAAO,EAAc,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAEvE,OAAO,EAAsB,yBAAyB,EAAE,MAAM,uBAAuB,CAAC;AACtF,OAAO,EACH,gCAAgC,GAEnC,MAAM,2CAA2C,CAAC;AAOnD;;GAEG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,UAAU,CACtC,kBAAkB,EAClB,CAAC,iBAAiB,CAAC,KAAK,EAAE,yBAAyB,CAAC,KAAK,EAAE,gCAAgC,CAAC,KAAK,CAAU,EAC3G,CACI,UAAsB,EACtB,kBAAsC,EACtC,0BAAsD,EACxD,EAAE;IACA,UAAU,CAAC,MAAM;SACZ,IAAI,CACD,UAAU,CAAC,QAAQ,EAAE,QAAQ,CAAC,EAC9B,GAAG,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC;QACvB,IAAI,EAAE,aAAsB;QAC5B,aAAa,EAAE,IAAI;QACnB,iBAAiB,EACb,IAAI,KAAK,QAAQ;YACb,CAAC,CAAC,0BAA0B,CAAC,gCAAgC;YAC7D,CAAC,CAAC,0BAA0B,CAAC,iCAAiC;KACzE,CAAC,CAAC,CACN;SACA,SAAS,CAAC;QACP,IAAI,EAAE,CAAC,gBAAgB,EAAE,EAAE;YACvB,kBAAkB,CAAC,aAAa,CAAC,IAAI,gBAAgB,CAAC,aAAa,EAAE,gBAAgB,CAAC,CAAC,CAAC;YACxF,0BAA0B,CAAC,KAAK,CAC5B,0BAA0B,EAC1B,CAAC,EACD,IAAI,GAAG,CAAC;gBACJ;oBACI,UAAU;oBACV,CACI,gBAAgB,CAAC,iBAAiB;wBAClC,0BAA0B,CAAC,gCAAgC,CAC9D,CAAC,QAAQ,EAAE;iBACf;aACJ,CAAC,CACL,CAAC;QACN,CAAC;KACJ,CAAC,CAAC;AACX,CAAC,CACJ,CAAC","sourcesContent":["import { forActions } from \"@snap/state-management\";\nimport { map } from \"rxjs\";\nimport { Injectable } from \"../../dependency-injection/Injectable\";\nimport { TypedCustomEvent } from \"../../events/TypedCustomEvent\";\nimport { CameraKitLegalPromptResult } from \"../../generated-proto/blizzard/cameraKitEvents\";\nimport { LegalState, legalStateFactory } from \"../../legal/legalState\";\nimport { MakeTaggedBusinessEvent } from \"../businessEventsReporter\";\nimport { MetricsEventTarget, metricsEventTargetFactory } from \"../metricsEventTarget\";\nimport {\n operationalMetricReporterFactory,\n OperationalMetricsReporter,\n} from \"../operational/operationalMetricsReporter\";\n\n/**\n * The LegalPrompt metric reports each time a BIPA legal prompt is shown.\n */\nexport type LegalPrompt = MakeTaggedBusinessEvent<\"legalPrompt\">;\n\n/**\n * @internal\n */\nexport const reportLegalState = Injectable(\n \"reportLegalState\",\n [legalStateFactory.token, metricsEventTargetFactory.token, operationalMetricReporterFactory.token] as const,\n (\n legalState: LegalState,\n metricsEventTarget: MetricsEventTarget,\n operationalMetricsReporter: OperationalMetricsReporter\n ) => {\n legalState.events\n .pipe(\n forActions(\"accept\", \"reject\"),\n map(([{ data, name }]) => ({\n name: \"legalPrompt\" as const,\n legalPromptId: data,\n legalPromptResult:\n name === \"accept\"\n ? CameraKitLegalPromptResult.CAMERA_KIT_LEGAL_PROMPT_ACCEPTED\n : CameraKitLegalPromptResult.CAMERA_KIT_LEGAL_PROMPT_DISMISSED,\n }))\n )\n .subscribe({\n next: (legalPromptEvent) => {\n metricsEventTarget.dispatchEvent(new TypedCustomEvent(\"legalPrompt\", legalPromptEvent));\n operationalMetricsReporter.count(\n \"legal_prompt_interaction\",\n 1,\n new Map([\n [\n \"accepted\",\n (\n legalPromptEvent.legalPromptResult ===\n CameraKitLegalPromptResult.CAMERA_KIT_LEGAL_PROMPT_ACCEPTED\n ).toString(),\n ],\n ])\n );\n },\n });\n }\n);\n"]}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Dimensions, RequestStateEventTarget } from "../../handlers/requestStateEmittingHandler";
|
|
2
2
|
import { MakeTaggedBusinessEvent } from "../businessEventsReporter";
|
|
3
3
|
import { MetricsEventTarget } from "../metricsEventTarget";
|
|
4
|
-
import { OperationalMetricsReporter } from "../operationalMetricsReporter";
|
|
4
|
+
import { OperationalMetricsReporter } from "../operational/operationalMetricsReporter";
|
|
5
5
|
export declare const isLensOrAssetRequest: (value: Dimensions) => value is AssetDownloadDimensions | LensDownloadDimensions;
|
|
6
6
|
/**
|
|
7
7
|
* The LensDownload metric is triggered by any download of lens content.
|
|
@@ -5,7 +5,7 @@ import { scan } from "../../events/scan";
|
|
|
5
5
|
import { TypedCustomEvent } from "../../events/TypedCustomEvent";
|
|
6
6
|
import { requestStateEventTargetFactory, } from "../../handlers/requestStateEmittingHandler";
|
|
7
7
|
import { metricsEventTargetFactory } from "../metricsEventTarget";
|
|
8
|
-
import { operationalMetricReporterFactory } from "../operationalMetricsReporter";
|
|
8
|
+
import { operationalMetricReporterFactory, } from "../operational/operationalMetricsReporter";
|
|
9
9
|
const relevantRequestTypes = ["lens_content", "asset"];
|
|
10
10
|
export const isLensOrAssetRequest = (value) => {
|
|
11
11
|
const requestType = value["requestType"];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reportLensAndAssetDownload.js","sourceRoot":"","sources":["../../../src/metrics/reporters/reportLensAndAssetDownload.ts"],"names":[],"mappings":"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","sourcesContent":["import { assertUnreachable } from \"../../common/assertions\";\nimport { stringifyError } from \"../../common/errorHelpers\";\nimport { Injectable } from \"../../dependency-injection/Injectable\";\nimport { scan } from \"../../events/scan\";\nimport { TypedCustomEvent } from \"../../events/TypedCustomEvent\";\nimport {\n Dimensions,\n RequestStateEventTarget,\n requestStateEventTargetFactory,\n} from \"../../handlers/requestStateEmittingHandler\";\nimport { MakeTaggedBusinessEvent } from \"../businessEventsReporter\";\nimport { CameraKitMetricEvents, MetricsEventTarget, metricsEventTargetFactory } from \"../metricsEventTarget\";\nimport { operationalMetricReporterFactory, OperationalMetricsReporter } from \"../operationalMetricsReporter\";\n\ntype InProgressMap = Map<number, { startTimeMs: number }>;\ninterface InProgress {\n name: \"inProgress\";\n inProgress: InProgressMap;\n}\ninterface Completed {\n name: \"completed\";\n inProgress: InProgressMap;\n event: CameraKitMetricEvents;\n}\ntype RequestState = InProgress | Completed;\n\nconst relevantRequestTypes = [\"lens_content\", \"asset\"] as const;\nexport const isLensOrAssetRequest = (value: Dimensions): value is LensDownloadDimensions | AssetDownloadDimensions => {\n const requestType = value[\"requestType\"];\n // Safety: the cast makes the type less specific so we can check if any string is present in the tuple.\n return typeof requestType === \"string\" && (relevantRequestTypes as readonly string[]).includes(requestType);\n};\n\n/**\n * The LensDownload metric is triggered by any download of lens content.\n *\n * It contains download stats, which lens was requested, and whether prefetch was used.\n *\n * It corresponds to the internal CameraKitLensDownload event, described here:\n * https://docs.google.com/document/d/1-kSzFWCWw9Qo3D08FR1_cqeHTsUtk9p3p3uOptzWDTY/edit#heading=h.stqom49qs91t\n */\nexport type LensDownload = MakeTaggedBusinessEvent<\"lensDownload\">;\nexport type LensDownloadDimensions = { requestType: \"lens_content\"; lensId: string };\n\n/**\n * The AssetDownload metric is triggered by any type of asset download.\n *\n * It contains download stats, which asset was requested, and whether prefetch was used.\n *\n * It corresponds to the internal CameraKitAssetDownload event, described here:\n * https://docs.google.com/document/d/1-kSzFWCWw9Qo3D08FR1_cqeHTsUtk9p3p3uOptzWDTY/edit#heading=h.vlormd1724fp\n */\nexport type AssetDownload = MakeTaggedBusinessEvent<\"assetDownload\">;\nexport type AssetDownloadDimensions = { requestType: \"asset\"; assetType: string; assetId: string; lensId: string };\n\nexport const reportLensAndAssetDownload = Injectable(\n \"reportLensAndAssetDownload\",\n [\n metricsEventTargetFactory.token,\n operationalMetricReporterFactory.token,\n requestStateEventTargetFactory.token,\n ] as const,\n (\n metricsEventTarget: MetricsEventTarget,\n reporter: OperationalMetricsReporter,\n requestStateEventTarget: RequestStateEventTarget\n ) => {\n scan<RequestState>({ name: \"inProgress\", inProgress: new Map() })(\n requestStateEventTarget,\n [\"started\", \"completed\", \"errored\"],\n (state, event) => {\n const { inProgress } = state;\n const { dimensions, requestId, timeMs } = event.detail;\n\n if (!isLensOrAssetRequest(dimensions)) return state;\n\n switch (event.type) {\n case \"started\":\n inProgress.set(requestId, { startTimeMs: timeMs });\n return { name: \"inProgress\", inProgress };\n case \"completed\":\n const completedRequest = inProgress.get(requestId);\n if (!completedRequest) return state;\n inProgress.delete(requestId);\n\n const downloadTimeSec = (timeMs - completedRequest.startTimeMs) / 1000;\n const { sizeByte } = event.detail;\n\n switch (dimensions.requestType) {\n case \"lens_content\":\n return {\n name: \"completed\",\n inProgress,\n event: new TypedCustomEvent(\"lensDownload\", {\n name: \"lensDownload\",\n lensId: dimensions.lensId,\n automaticDownload: false,\n sizeByte,\n downloadTimeSec,\n }),\n };\n case \"asset\":\n return {\n name: \"completed\",\n inProgress,\n event: new TypedCustomEvent(\"assetDownload\", {\n name: \"assetDownload\",\n assetId: dimensions.assetId,\n automaticDownload: false,\n sizeByte,\n downloadTimeSec,\n }),\n };\n default:\n assertUnreachable(dimensions);\n }\n case \"errored\":\n const erroredRequest = inProgress.get(requestId);\n if (!erroredRequest) return state;\n inProgress.delete(requestId);\n const error = event.detail.error;\n return {\n name: \"completed\",\n inProgress,\n event: new TypedCustomEvent(\"exception\", {\n name: \"exception\",\n lensId: dimensions.lensId,\n type: dimensions.requestType === \"lens_content\" ? \"lens\" : \"asset\",\n reason: stringifyError(error),\n }),\n };\n default:\n assertUnreachable(event);\n }\n }\n ).addEventListener(\"state\", ({ detail: state }) => {\n if (state.name !== \"completed\") return;\n metricsEventTarget.dispatchEvent(state.event);\n if (state.event.detail.name === \"exception\") {\n reporter.count(\"handled_exception\", 1, new Map([[\"type\", state.event.detail.type]]));\n }\n });\n }\n);\n"]}
|
|
1
|
+
{"version":3,"file":"reportLensAndAssetDownload.js","sourceRoot":"","sources":["../../../src/metrics/reporters/reportLensAndAssetDownload.ts"],"names":[],"mappings":"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","sourcesContent":["import { assertUnreachable } from \"../../common/assertions\";\nimport { stringifyError } from \"../../common/errorHelpers\";\nimport { Injectable } from \"../../dependency-injection/Injectable\";\nimport { scan } from \"../../events/scan\";\nimport { TypedCustomEvent } from \"../../events/TypedCustomEvent\";\nimport {\n Dimensions,\n RequestStateEventTarget,\n requestStateEventTargetFactory,\n} from \"../../handlers/requestStateEmittingHandler\";\nimport { MakeTaggedBusinessEvent } from \"../businessEventsReporter\";\nimport { CameraKitMetricEvents, MetricsEventTarget, metricsEventTargetFactory } from \"../metricsEventTarget\";\nimport {\n operationalMetricReporterFactory,\n OperationalMetricsReporter,\n} from \"../operational/operationalMetricsReporter\";\n\ntype InProgressMap = Map<number, { startTimeMs: number }>;\ninterface InProgress {\n name: \"inProgress\";\n inProgress: InProgressMap;\n}\ninterface Completed {\n name: \"completed\";\n inProgress: InProgressMap;\n event: CameraKitMetricEvents;\n}\ntype RequestState = InProgress | Completed;\n\nconst relevantRequestTypes = [\"lens_content\", \"asset\"] as const;\nexport const isLensOrAssetRequest = (value: Dimensions): value is LensDownloadDimensions | AssetDownloadDimensions => {\n const requestType = value[\"requestType\"];\n // Safety: the cast makes the type less specific so we can check if any string is present in the tuple.\n return typeof requestType === \"string\" && (relevantRequestTypes as readonly string[]).includes(requestType);\n};\n\n/**\n * The LensDownload metric is triggered by any download of lens content.\n *\n * It contains download stats, which lens was requested, and whether prefetch was used.\n *\n * It corresponds to the internal CameraKitLensDownload event, described here:\n * https://docs.google.com/document/d/1-kSzFWCWw9Qo3D08FR1_cqeHTsUtk9p3p3uOptzWDTY/edit#heading=h.stqom49qs91t\n */\nexport type LensDownload = MakeTaggedBusinessEvent<\"lensDownload\">;\nexport type LensDownloadDimensions = { requestType: \"lens_content\"; lensId: string };\n\n/**\n * The AssetDownload metric is triggered by any type of asset download.\n *\n * It contains download stats, which asset was requested, and whether prefetch was used.\n *\n * It corresponds to the internal CameraKitAssetDownload event, described here:\n * https://docs.google.com/document/d/1-kSzFWCWw9Qo3D08FR1_cqeHTsUtk9p3p3uOptzWDTY/edit#heading=h.vlormd1724fp\n */\nexport type AssetDownload = MakeTaggedBusinessEvent<\"assetDownload\">;\nexport type AssetDownloadDimensions = { requestType: \"asset\"; assetType: string; assetId: string; lensId: string };\n\nexport const reportLensAndAssetDownload = Injectable(\n \"reportLensAndAssetDownload\",\n [\n metricsEventTargetFactory.token,\n operationalMetricReporterFactory.token,\n requestStateEventTargetFactory.token,\n ] as const,\n (\n metricsEventTarget: MetricsEventTarget,\n reporter: OperationalMetricsReporter,\n requestStateEventTarget: RequestStateEventTarget\n ) => {\n scan<RequestState>({ name: \"inProgress\", inProgress: new Map() })(\n requestStateEventTarget,\n [\"started\", \"completed\", \"errored\"],\n (state, event) => {\n const { inProgress } = state;\n const { dimensions, requestId, timeMs } = event.detail;\n\n if (!isLensOrAssetRequest(dimensions)) return state;\n\n switch (event.type) {\n case \"started\":\n inProgress.set(requestId, { startTimeMs: timeMs });\n return { name: \"inProgress\", inProgress };\n case \"completed\":\n const completedRequest = inProgress.get(requestId);\n if (!completedRequest) return state;\n inProgress.delete(requestId);\n\n const downloadTimeSec = (timeMs - completedRequest.startTimeMs) / 1000;\n const { sizeByte } = event.detail;\n\n switch (dimensions.requestType) {\n case \"lens_content\":\n return {\n name: \"completed\",\n inProgress,\n event: new TypedCustomEvent(\"lensDownload\", {\n name: \"lensDownload\",\n lensId: dimensions.lensId,\n automaticDownload: false,\n sizeByte,\n downloadTimeSec,\n }),\n };\n case \"asset\":\n return {\n name: \"completed\",\n inProgress,\n event: new TypedCustomEvent(\"assetDownload\", {\n name: \"assetDownload\",\n assetId: dimensions.assetId,\n automaticDownload: false,\n sizeByte,\n downloadTimeSec,\n }),\n };\n default:\n assertUnreachable(dimensions);\n }\n case \"errored\":\n const erroredRequest = inProgress.get(requestId);\n if (!erroredRequest) return state;\n inProgress.delete(requestId);\n const error = event.detail.error;\n return {\n name: \"completed\",\n inProgress,\n event: new TypedCustomEvent(\"exception\", {\n name: \"exception\",\n lensId: dimensions.lensId,\n type: dimensions.requestType === \"lens_content\" ? \"lens\" : \"asset\",\n reason: stringifyError(error),\n }),\n };\n default:\n assertUnreachable(event);\n }\n }\n ).addEventListener(\"state\", ({ detail: state }) => {\n if (state.name !== \"completed\") return;\n metricsEventTarget.dispatchEvent(state.event);\n if (state.event.detail.name === \"exception\") {\n reporter.count(\"handled_exception\", 1, new Map([[\"type\", state.event.detail.type]]));\n }\n });\n }\n);\n"]}
|
|
@@ -14,7 +14,7 @@ export declare const reportLensValidationFailed: {
|
|
|
14
14
|
}> | import("@snap/state-management").Action<"downloadComplete", import("../..").Lens> | import("@snap/state-management").Action<"turnedOn", import("../..").Lens> | import("@snap/state-management").Action<"resourcesLoaded", import("../..").Lens> | import("@snap/state-management").Action<"firstFrameProcessed", import("../..").Lens> | import("@snap/state-management").Action<"applyLensComplete", import("../..").Lens> | import("@snap/state-management").Action<"applyLensFailed", {
|
|
15
15
|
error: import("../../session/lensState").LensErrors;
|
|
16
16
|
lens: import("../..").Lens;
|
|
17
|
-
}> | import("@snap/state-management").Action<"removeLens", undefined> | import("@snap/state-management").Action<"turnedOff", import("../..").Lens> | import("@snap/state-management").Action<"removeLensComplete", undefined> | import("@snap/state-management").Action<"removeLensFailed", Error>, import("@snap/state-management").State<"noLensApplied", undefined> | import("@snap/state-management").State<"applyingLens", import("../..").Lens> | import("@snap/state-management").State<"lensApplied", import("../..").Lens>>, args_1: MetricsEventTarget): void;
|
|
17
|
+
}> | import("@snap/state-management").Action<"applyLensAborted", import("../..").Lens> | import("@snap/state-management").Action<"removeLens", undefined> | import("@snap/state-management").Action<"turnedOff", import("../..").Lens> | import("@snap/state-management").Action<"removeLensComplete", undefined> | import("@snap/state-management").Action<"removeLensFailed", Error>, import("@snap/state-management").State<"noLensApplied", undefined> | import("@snap/state-management").State<"applyingLens", import("../..").Lens> | import("@snap/state-management").State<"lensApplied", import("../..").Lens>>, args_1: MetricsEventTarget): void;
|
|
18
18
|
token: "reportLensValidationFailed";
|
|
19
19
|
dependencies: readonly ["lensState", "metricsEventTarget"];
|
|
20
20
|
};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { MetricsEventTarget } from "../metricsEventTarget";
|
|
2
2
|
import { CameraKitSession } from "../../session/CameraKitSession";
|
|
3
3
|
import { MakeTaggedBusinessEvent } from "../businessEventsReporter";
|
|
4
|
-
import { OperationalMetricsReporter } from "../operationalMetricsReporter";
|
|
4
|
+
import { OperationalMetricsReporter } from "../operational/operationalMetricsReporter";
|
|
5
5
|
import { CameraKitConfiguration } from "../../configuration";
|
|
6
6
|
/**
|
|
7
7
|
* The LensView metric is emitted after a lens has been viewed (for longer than 100ms), when the lens is turned off.
|
|
@@ -30,7 +30,7 @@ export declare const reportLensView: {
|
|
|
30
30
|
}> | import("@snap/state-management").Action<"downloadComplete", import("../..").Lens> | import("@snap/state-management").Action<"turnedOn", import("../..").Lens> | import("@snap/state-management").Action<"resourcesLoaded", import("../..").Lens> | import("@snap/state-management").Action<"firstFrameProcessed", import("../..").Lens> | import("@snap/state-management").Action<"applyLensComplete", import("../..").Lens> | import("@snap/state-management").Action<"applyLensFailed", {
|
|
31
31
|
error: import("../../session/lensState").LensErrors;
|
|
32
32
|
lens: import("../..").Lens;
|
|
33
|
-
}> | import("@snap/state-management").Action<"removeLens", undefined> | import("@snap/state-management").Action<"turnedOff", import("../..").Lens> | import("@snap/state-management").Action<"removeLensComplete", undefined> | import("@snap/state-management").Action<"removeLensFailed", Error>, import("@snap/state-management").State<"noLensApplied", undefined> | import("@snap/state-management").State<"applyingLens", import("../..").Lens> | import("@snap/state-management").State<"lensApplied", import("../..").Lens>>, args_2: import("@snap/state-management").StateMachine<import("@snap/state-management").Action<"suspend", CameraKitSession> | import("@snap/state-management").Action<"resume", CameraKitSession>, import("@snap/state-management").State<"inactive", undefined> | import("@snap/state-management").State<"active", CameraKitSession>>, args_3: MetricsEventTarget, args_4: OperationalMetricsReporter, args_5: CameraKitConfiguration): void
|
|
33
|
+
}> | import("@snap/state-management").Action<"applyLensAborted", import("../..").Lens> | import("@snap/state-management").Action<"removeLens", undefined> | import("@snap/state-management").Action<"turnedOff", import("../..").Lens> | import("@snap/state-management").Action<"removeLensComplete", undefined> | import("@snap/state-management").Action<"removeLensFailed", Error>, import("@snap/state-management").State<"noLensApplied", undefined> | import("@snap/state-management").State<"applyingLens", import("../..").Lens> | import("@snap/state-management").State<"lensApplied", import("../..").Lens>>, args_2: import("@snap/state-management").StateMachine<import("@snap/state-management").Action<"suspend", CameraKitSession> | import("@snap/state-management").Action<"resume", CameraKitSession>, import("@snap/state-management").State<"inactive", undefined> | import("@snap/state-management").State<"active", CameraKitSession>>, args_3: MetricsEventTarget, args_4: OperationalMetricsReporter, args_5: CameraKitConfiguration): Promise<void>;
|
|
34
34
|
token: "reportLensView";
|
|
35
35
|
dependencies: readonly ["CameraKitSession", "lensState", "sessionState", "metricsEventTarget", "operationalMetricsReporter", "configuration"];
|
|
36
36
|
};
|
|
@@ -6,10 +6,11 @@ import { TypedCustomEvent } from "../../events/TypedCustomEvent";
|
|
|
6
6
|
import { metricsEventTargetFactory } from "../metricsEventTarget";
|
|
7
7
|
import { cameraKitSessionFactory } from "../../session/CameraKitSession";
|
|
8
8
|
import { getTimeMs } from "../../common/time";
|
|
9
|
-
import { operationalMetricReporterFactory } from "../operationalMetricsReporter";
|
|
9
|
+
import { operationalMetricReporterFactory, } from "../operational/operationalMetricsReporter";
|
|
10
10
|
import { configurationToken } from "../../configuration";
|
|
11
11
|
import { lensStateFactory } from "../../session/lensState";
|
|
12
12
|
import { sessionStateFactory } from "../../session/sessionState";
|
|
13
|
+
import { Histogram } from "../operational/Histogram";
|
|
13
14
|
// We ignore short-duration lens views.
|
|
14
15
|
//
|
|
15
16
|
// The value is documented here:
|
|
@@ -25,7 +26,16 @@ export const reportLensView = Injectable("reportLensView", [
|
|
|
25
26
|
metricsEventTargetFactory.token,
|
|
26
27
|
operationalMetricReporterFactory.token,
|
|
27
28
|
configurationToken,
|
|
28
|
-
], (session, lensState, sessionState, metricsEventTarget, operationalMetricsReporter, configuration) => {
|
|
29
|
+
], (session, lensState, sessionState, metricsEventTarget, operationalMetricsReporter, configuration) => __awaiter(void 0, void 0, void 0, function* () {
|
|
30
|
+
var _a;
|
|
31
|
+
// We need to do this await up front so that it won't interrupt reporting the metric when the session is
|
|
32
|
+
// suspended -- suspension could happen because the tab is closing, in which case we cannot perform await a
|
|
33
|
+
// Promise, because in the case of a tab close the browser will not schedule any work for future turns of the
|
|
34
|
+
// event loop.
|
|
35
|
+
const { cluster: performanceCluster, webglRendererInfo } = (_a = (yield configuration.lensPerformance)) !== null && _a !== void 0 ? _a : {
|
|
36
|
+
cluster: 0,
|
|
37
|
+
webglRendererInfo: "unknown",
|
|
38
|
+
};
|
|
29
39
|
merge(
|
|
30
40
|
// Begin measuring LensCore apply time once the lens has finished downloading and we actually add the lens
|
|
31
41
|
// to LensCore (LensWait measures the full download + LensCore apply time i.e. perceived UX latency).
|
|
@@ -60,14 +70,9 @@ export const reportLensView = Injectable("reportLensView", [
|
|
|
60
70
|
lensId }, viewMetrics))));
|
|
61
71
|
}))
|
|
62
72
|
.subscribe({
|
|
63
|
-
next: ({ applyDelaySec, lensId, viewTimeSec, avgFps, lensFrameProcessingTimeMsAvg, lensFrameProcessingTimeMsStd, }) => __awaiter(void 0, void 0, void 0, function* () {
|
|
64
|
-
var _a;
|
|
73
|
+
next: ({ applyDelaySec, lensId, viewTimeSec, avgFps, lensFrameProcessingTimeMsAvg, lensFrameProcessingTimeMsStd, lensFrameProcessingTimeMsMedian, lensFrameProcessingN, }) => __awaiter(void 0, void 0, void 0, function* () {
|
|
65
74
|
if (viewTimeSec < viewTimeThresholdSec)
|
|
66
75
|
return;
|
|
67
|
-
const { cluster: performanceCluster, webglRendererInfo } = (_a = (yield configuration.lensPerformance)) !== null && _a !== void 0 ? _a : {
|
|
68
|
-
cluster: 0,
|
|
69
|
-
webglRendererInfo: "unknown",
|
|
70
|
-
};
|
|
71
76
|
const lensView = {
|
|
72
77
|
name: "lensView",
|
|
73
78
|
applyDelaySec,
|
|
@@ -87,15 +92,16 @@ export const reportLensView = Injectable("reportLensView", [
|
|
|
87
92
|
webglRendererInfo,
|
|
88
93
|
};
|
|
89
94
|
metricsEventTarget.dispatchEvent(new TypedCustomEvent("lensView", lensView));
|
|
90
|
-
|
|
91
|
-
//
|
|
92
|
-
//
|
|
93
|
-
//
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
95
|
+
operationalMetricsReporter.report(Histogram.level("lens_view", viewTimeSec * 1000));
|
|
96
|
+
// The first few frames will typically take much longer to process (as they might involve requesting
|
|
97
|
+
// remote assets to be downloaded, or other high-latency initialization steps) -- so we'll skip
|
|
98
|
+
// reporting views with a very small number of frames.
|
|
99
|
+
if (lensFrameProcessingN >= 30) {
|
|
100
|
+
operationalMetricsReporter.report(Histogram.level("lens_view_frame-processing-time", lensFrameProcessingTimeMsMedian, {
|
|
101
|
+
performance_cluster: performanceCluster.toString(),
|
|
102
|
+
}));
|
|
103
|
+
}
|
|
98
104
|
}),
|
|
99
105
|
});
|
|
100
|
-
});
|
|
106
|
+
}));
|
|
101
107
|
//# sourceMappingURL=reportLensView.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reportLensView.js","sourceRoot":"","sources":["../../../src/metrics/reporters/reportLensView.ts"],"names":[],"mappings":"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","sourcesContent":["import { combineLatestWith, filter, map, merge, mergeMap, of, raceWith, switchMap, take, takeUntil } from \"rxjs\";\nimport { forActions, inStates, isState } from \"@snap/state-management\";\nimport { Injectable } from \"../../dependency-injection/Injectable\";\nimport { TypedCustomEvent } from \"../../events/TypedCustomEvent\";\nimport { MetricsEventTarget, metricsEventTargetFactory } from \"../metricsEventTarget\";\nimport { CameraKitSession, cameraKitSessionFactory } from \"../../session/CameraKitSession\";\nimport { MakeTaggedBusinessEvent } from \"../businessEventsReporter\";\nimport { getTimeMs } from \"../../common/time\";\nimport { operationalMetricReporterFactory, OperationalMetricsReporter } from \"../operationalMetricsReporter\";\nimport { CameraKitConfiguration, configurationToken } from \"../../configuration\";\nimport { lensStateFactory, LensState } from \"../../session/lensState\";\nimport { SessionState, sessionStateFactory } from \"../../session/sessionState\";\n\n// We ignore short-duration lens views.\n//\n// The value is documented here:\n// https://docs.google.com/document/d/1-kSzFWCWw9Qo3D08FR1_cqeHTsUtk9p3p3uOptzWDTY/edit#heading=h.q5liip76r9lt\nconst viewTimeThresholdSec = 0.1;\n\n/**\n * The LensView metric is emitted after a lens has been viewed (for longer than 100ms), when the lens is turned off.\n *\n * It contains information about rendering performance.\n *\n * Notes:\n * - If the page is hidden (e.g. user switches to a different tab, or application, or closes the tab, or closes the\n * browser, navigates to a new page, refreshes, etc.) this metric will be emitted at that time. This is to ensure\n * we don't lose the metric if the page is closed.\n * - If the page is hidden and then made visible again later (e.g. user switches to a different tab, then back), we\n * will begin measuring a new LensView. That is, we will not capture the time when the page is hidden even if the\n * lens is still rendering in the background.\n *\n * @category Lenses\n * @category Metrics\n */\n// This type corresponds to the internal CameraKitLensSwipe event, described here:\n// https://docs.google.com/document/d/1-kSzFWCWw9Qo3D08FR1_cqeHTsUtk9p3p3uOptzWDTY#heading=h.q5liip76r9lt\nexport type LensView = MakeTaggedBusinessEvent<\"lensView\">;\n\n/**\n * @internal\n */\nexport const reportLensView = Injectable(\n \"reportLensView\",\n [\n cameraKitSessionFactory.token,\n lensStateFactory.token,\n sessionStateFactory.token,\n metricsEventTargetFactory.token,\n operationalMetricReporterFactory.token,\n configurationToken,\n ] as const,\n (\n session: CameraKitSession,\n lensState: LensState,\n sessionState: SessionState,\n metricsEventTarget: MetricsEventTarget,\n operationalMetricsReporter: OperationalMetricsReporter,\n configuration: CameraKitConfiguration\n ): void => {\n merge(\n // Begin measuring LensCore apply time once the lens has finished downloading and we actually add the lens\n // to LensCore (LensWait measures the full download + LensCore apply time i.e. perceived UX latency).\n lensState.events.pipe(\n forActions(\"downloadComplete\"),\n map(([a]) => a.data)\n ),\n\n // If the session is resumed (e.g. user returns to this tab while a lens is on), we count this as a new\n // LensView (and applyDelaySec will be 0).\n lensState.events.pipe(\n inStates(\"lensApplied\"),\n switchMap(([, s]) =>\n sessionState.events.pipe(\n forActions(\"resume\"),\n takeUntil(lensState.events.pipe(forActions(\"removeLens\"))),\n map(() => s.data)\n )\n )\n )\n )\n .pipe(\n map((lens): [number, string] => [getTimeMs(), lens.id]),\n mergeMap(([applyLensStartTime, lensId]) => {\n const alreadyOn = isState(lensState.getState(), \"lensApplied\");\n\n const applyDelay = alreadyOn\n ? of(0)\n : lensState.events.pipe(\n forActions(\"resourcesLoaded\"),\n filter(([a]) => a.data.id === lensId),\n // Applying a new lens may happen before removing the old one, so if we kept taking events\n // we would get the lensResourcesLoaded for the next lens, too.\n take(1),\n map(() => (getTimeMs() - applyLensStartTime) / 1000)\n );\n\n const viewMetrics = (\n alreadyOn\n ? of([getTimeMs(), session.metrics.beginMeasurement()] as const)\n : lensState.events.pipe(\n forActions(\"turnedOn\"),\n filter(([a]) => a.data.id === lensId),\n map(() => [getTimeMs(), session.metrics.beginMeasurement()] as const)\n )\n ).pipe(\n take(1),\n mergeMap(([lensTurnedOnTime, metricsMeasurement]) =>\n lensState.events.pipe(\n forActions(\"turnedOff\"),\n // Applying a new lens may happen before removing the old one, so we'll get a\n // lensTurnedOff for the prior lens (if one was applied), which we must filter out.\n filter(([a]) => a.data.id === lensId),\n // If the session is suspended, we'll count that as the lens turning off.\n raceWith(sessionState.events.pipe(forActions(\"suspend\"))),\n map(() => {\n metricsMeasurement.end();\n return {\n viewTimeSec: (getTimeMs() - lensTurnedOnTime) / 1000,\n ...metricsMeasurement.measure(),\n };\n })\n )\n )\n );\n\n return applyDelay.pipe(\n combineLatestWith(viewMetrics),\n // This lens should always receive the lensTurnedOff action *before* the next lens is turned on.\n // But just in case that assumption is violated, we'll clean up (and not report) if another lens\n // turns on before our lens is turned off.\n takeUntil(\n lensState.events.pipe(\n forActions(\"turnedOn\"),\n filter(([a]) => a.data.id !== lensId)\n )\n ),\n take(1),\n map(([applyDelaySec, viewMetrics]) => ({\n applyDelaySec,\n lensId,\n ...viewMetrics,\n }))\n );\n })\n )\n .subscribe({\n next: async ({\n applyDelaySec,\n lensId,\n viewTimeSec,\n avgFps,\n lensFrameProcessingTimeMsAvg,\n lensFrameProcessingTimeMsStd,\n }) => {\n if (viewTimeSec < viewTimeThresholdSec) return;\n const { cluster: performanceCluster, webglRendererInfo } =\n (await configuration.lensPerformance) ?? {\n cluster: 0,\n webglRendererInfo: \"unknown\",\n };\n const lensView: LensView = {\n name: \"lensView\",\n applyDelaySec,\n avgFps,\n lensId,\n lensFrameProcessingTimeMsAvg,\n lensFrameProcessingTimeMsStd,\n // We don't support recording video, but applications may do this without our knowledge.\n recordingTimeSec: 0,\n viewTimeSec,\n // TODO: if we want to support these fields, we'll need some persistence to keep track of the\n // date of last application per lens.\n // https://jira.sc-corp.net/browse/CAMKIT-3050\n isLensFirstWithinDay: false,\n isLensFirstWithinMonth: false,\n performanceCluster,\n webglRendererInfo,\n };\n\n metricsEventTarget.dispatchEvent(new TypedCustomEvent(\"lensView\", lensView));\n\n // Reporting operational metrics described here:\n // https://docs.google.com/document/d/1g4PncAmKdyrLEFVp8ODp58oer2UJu9PIetRW035nnTo\n //\n // We ignore if applyDelaySec is 0, which will be the case if the session was suspended and then\n // resumed - we only care about this metric when a new lens has been loaded.\n if (applyDelaySec > 0)\n operationalMetricsReporter.timer(\"lens.core_loading_latency\", applyDelaySec * 1000);\n operationalMetricsReporter.timer(\n \"lens.processing_time\",\n lensFrameProcessingTimeMsAvg,\n new Map([[\"performance_cluster\", performanceCluster.toString()]])\n );\n },\n });\n }\n);\n"]}
|
|
1
|
+
{"version":3,"file":"reportLensView.js","sourceRoot":"","sources":["../../../src/metrics/reporters/reportLensView.ts"],"names":[],"mappings":"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","sourcesContent":["import { combineLatestWith, filter, map, merge, mergeMap, of, raceWith, switchMap, take, takeUntil } from \"rxjs\";\nimport { forActions, inStates, isState } from \"@snap/state-management\";\nimport { Injectable } from \"../../dependency-injection/Injectable\";\nimport { TypedCustomEvent } from \"../../events/TypedCustomEvent\";\nimport { MetricsEventTarget, metricsEventTargetFactory } from \"../metricsEventTarget\";\nimport { CameraKitSession, cameraKitSessionFactory } from \"../../session/CameraKitSession\";\nimport { MakeTaggedBusinessEvent } from \"../businessEventsReporter\";\nimport { getTimeMs } from \"../../common/time\";\nimport {\n operationalMetricReporterFactory,\n OperationalMetricsReporter,\n} from \"../operational/operationalMetricsReporter\";\nimport { CameraKitConfiguration, configurationToken } from \"../../configuration\";\nimport { lensStateFactory, LensState } from \"../../session/lensState\";\nimport { SessionState, sessionStateFactory } from \"../../session/sessionState\";\nimport { Histogram } from \"../operational/Histogram\";\n\n// We ignore short-duration lens views.\n//\n// The value is documented here:\n// https://docs.google.com/document/d/1-kSzFWCWw9Qo3D08FR1_cqeHTsUtk9p3p3uOptzWDTY/edit#heading=h.q5liip76r9lt\nconst viewTimeThresholdSec = 0.1;\n\n/**\n * The LensView metric is emitted after a lens has been viewed (for longer than 100ms), when the lens is turned off.\n *\n * It contains information about rendering performance.\n *\n * Notes:\n * - If the page is hidden (e.g. user switches to a different tab, or application, or closes the tab, or closes the\n * browser, navigates to a new page, refreshes, etc.) this metric will be emitted at that time. This is to ensure\n * we don't lose the metric if the page is closed.\n * - If the page is hidden and then made visible again later (e.g. user switches to a different tab, then back), we\n * will begin measuring a new LensView. That is, we will not capture the time when the page is hidden even if the\n * lens is still rendering in the background.\n *\n * @category Lenses\n * @category Metrics\n */\n// This type corresponds to the internal CameraKitLensSwipe event, described here:\n// https://docs.google.com/document/d/1-kSzFWCWw9Qo3D08FR1_cqeHTsUtk9p3p3uOptzWDTY#heading=h.q5liip76r9lt\nexport type LensView = MakeTaggedBusinessEvent<\"lensView\">;\n\n/**\n * @internal\n */\nexport const reportLensView = Injectable(\n \"reportLensView\",\n [\n cameraKitSessionFactory.token,\n lensStateFactory.token,\n sessionStateFactory.token,\n metricsEventTargetFactory.token,\n operationalMetricReporterFactory.token,\n configurationToken,\n ] as const,\n async (\n session: CameraKitSession,\n lensState: LensState,\n sessionState: SessionState,\n metricsEventTarget: MetricsEventTarget,\n operationalMetricsReporter: OperationalMetricsReporter,\n configuration: CameraKitConfiguration\n ): Promise<void> => {\n // We need to do this await up front so that it won't interrupt reporting the metric when the session is\n // suspended -- suspension could happen because the tab is closing, in which case we cannot perform await a\n // Promise, because in the case of a tab close the browser will not schedule any work for future turns of the\n // event loop.\n const { cluster: performanceCluster, webglRendererInfo } = (await configuration.lensPerformance) ?? {\n cluster: 0,\n webglRendererInfo: \"unknown\",\n };\n\n merge(\n // Begin measuring LensCore apply time once the lens has finished downloading and we actually add the lens\n // to LensCore (LensWait measures the full download + LensCore apply time i.e. perceived UX latency).\n lensState.events.pipe(\n forActions(\"downloadComplete\"),\n map(([a]) => a.data)\n ),\n\n // If the session is resumed (e.g. user returns to this tab while a lens is on), we count this as a new\n // LensView (and applyDelaySec will be 0).\n lensState.events.pipe(\n inStates(\"lensApplied\"),\n switchMap(([, s]) =>\n sessionState.events.pipe(\n forActions(\"resume\"),\n takeUntil(lensState.events.pipe(forActions(\"removeLens\"))),\n map(() => s.data)\n )\n )\n )\n )\n .pipe(\n map((lens): [number, string] => [getTimeMs(), lens.id]),\n mergeMap(([applyLensStartTime, lensId]) => {\n const alreadyOn = isState(lensState.getState(), \"lensApplied\");\n\n const applyDelay = alreadyOn\n ? of(0)\n : lensState.events.pipe(\n forActions(\"resourcesLoaded\"),\n filter(([a]) => a.data.id === lensId),\n // Applying a new lens may happen before removing the old one, so if we kept taking events\n // we would get the lensResourcesLoaded for the next lens, too.\n take(1),\n map(() => (getTimeMs() - applyLensStartTime) / 1000)\n );\n\n const viewMetrics = (\n alreadyOn\n ? of([getTimeMs(), session.metrics.beginMeasurement()] as const)\n : lensState.events.pipe(\n forActions(\"turnedOn\"),\n filter(([a]) => a.data.id === lensId),\n map(() => [getTimeMs(), session.metrics.beginMeasurement()] as const)\n )\n ).pipe(\n take(1),\n mergeMap(([lensTurnedOnTime, metricsMeasurement]) =>\n lensState.events.pipe(\n forActions(\"turnedOff\"),\n // Applying a new lens may happen before removing the old one, so we'll get a\n // lensTurnedOff for the prior lens (if one was applied), which we must filter out.\n filter(([a]) => a.data.id === lensId),\n // If the session is suspended, we'll count that as the lens turning off.\n raceWith(sessionState.events.pipe(forActions(\"suspend\"))),\n map(() => {\n metricsMeasurement.end();\n return {\n viewTimeSec: (getTimeMs() - lensTurnedOnTime) / 1000,\n ...metricsMeasurement.measure(),\n };\n })\n )\n )\n );\n\n return applyDelay.pipe(\n combineLatestWith(viewMetrics),\n // This lens should always receive the lensTurnedOff action *before* the next lens is turned on.\n // But just in case that assumption is violated, we'll clean up (and not report) if another lens\n // turns on before our lens is turned off.\n takeUntil(\n lensState.events.pipe(\n forActions(\"turnedOn\"),\n filter(([a]) => a.data.id !== lensId)\n )\n ),\n take(1),\n map(([applyDelaySec, viewMetrics]) => ({\n applyDelaySec,\n lensId,\n ...viewMetrics,\n }))\n );\n })\n )\n .subscribe({\n next: async ({\n applyDelaySec,\n lensId,\n viewTimeSec,\n avgFps,\n lensFrameProcessingTimeMsAvg,\n lensFrameProcessingTimeMsStd,\n lensFrameProcessingTimeMsMedian,\n lensFrameProcessingN,\n }) => {\n if (viewTimeSec < viewTimeThresholdSec) return;\n\n const lensView: LensView = {\n name: \"lensView\",\n applyDelaySec,\n avgFps,\n lensId,\n lensFrameProcessingTimeMsAvg,\n lensFrameProcessingTimeMsStd,\n // We don't support recording video, but applications may do this without our knowledge.\n recordingTimeSec: 0,\n viewTimeSec,\n // TODO: if we want to support these fields, we'll need some persistence to keep track of the\n // date of last application per lens.\n // https://jira.sc-corp.net/browse/CAMKIT-3050\n isLensFirstWithinDay: false,\n isLensFirstWithinMonth: false,\n performanceCluster,\n webglRendererInfo,\n };\n\n metricsEventTarget.dispatchEvent(new TypedCustomEvent(\"lensView\", lensView));\n operationalMetricsReporter.report(Histogram.level(\"lens_view\", viewTimeSec * 1000));\n\n // The first few frames will typically take much longer to process (as they might involve requesting\n // remote assets to be downloaded, or other high-latency initialization steps) -- so we'll skip\n // reporting views with a very small number of frames.\n if (lensFrameProcessingN >= 30) {\n operationalMetricsReporter.report(\n Histogram.level(\"lens_view_frame-processing-time\", lensFrameProcessingTimeMsMedian, {\n performance_cluster: performanceCluster.toString(),\n })\n );\n }\n },\n });\n }\n);\n"]}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { MakeTaggedBusinessEvent } from "../businessEventsReporter";
|
|
2
2
|
import { MetricsEventTarget } from "../metricsEventTarget";
|
|
3
|
-
import { OperationalMetricsReporter } from "../operationalMetricsReporter";
|
|
3
|
+
import { OperationalMetricsReporter } from "../operational/operationalMetricsReporter";
|
|
4
4
|
/**
|
|
5
5
|
* The LensWait metric measures the time spent downloading the lens content and required assets. It gives an indication
|
|
6
6
|
* of the real UX impact of download latency. If lens content and assets are pre-loaded, the latency measured here
|
|
@@ -27,7 +27,7 @@ export declare const reportLensWait: {
|
|
|
27
27
|
}> | import("@snap/state-management").Action<"downloadComplete", import("../..").Lens> | import("@snap/state-management").Action<"turnedOn", import("../..").Lens> | import("@snap/state-management").Action<"resourcesLoaded", import("../..").Lens> | import("@snap/state-management").Action<"firstFrameProcessed", import("../..").Lens> | import("@snap/state-management").Action<"applyLensComplete", import("../..").Lens> | import("@snap/state-management").Action<"applyLensFailed", {
|
|
28
28
|
error: import("../../session/lensState").LensErrors;
|
|
29
29
|
lens: import("../..").Lens;
|
|
30
|
-
}> | import("@snap/state-management").Action<"removeLens", undefined> | import("@snap/state-management").Action<"turnedOff", import("../..").Lens> | import("@snap/state-management").Action<"removeLensComplete", undefined> | import("@snap/state-management").Action<"removeLensFailed", Error>, import("@snap/state-management").State<"noLensApplied", undefined> | import("@snap/state-management").State<"applyingLens", import("../..").Lens> | import("@snap/state-management").State<"lensApplied", import("../..").Lens>>, args_1: MetricsEventTarget, args_2: OperationalMetricsReporter): void;
|
|
30
|
+
}> | import("@snap/state-management").Action<"applyLensAborted", import("../..").Lens> | import("@snap/state-management").Action<"removeLens", undefined> | import("@snap/state-management").Action<"turnedOff", import("../..").Lens> | import("@snap/state-management").Action<"removeLensComplete", undefined> | import("@snap/state-management").Action<"removeLensFailed", Error>, import("@snap/state-management").State<"noLensApplied", undefined> | import("@snap/state-management").State<"applyingLens", import("../..").Lens> | import("@snap/state-management").State<"lensApplied", import("../..").Lens>>, args_1: MetricsEventTarget, args_2: OperationalMetricsReporter): void;
|
|
31
31
|
token: "reportLensWait";
|
|
32
32
|
dependencies: readonly ["lensState", "metricsEventTarget", "operationalMetricsReporter"];
|
|
33
33
|
};
|
|
@@ -5,7 +5,7 @@ import { Injectable } from "../../dependency-injection/Injectable";
|
|
|
5
5
|
import { TypedCustomEvent } from "../../events/TypedCustomEvent";
|
|
6
6
|
import { lensStateFactory } from "../../session/lensState";
|
|
7
7
|
import { metricsEventTargetFactory } from "../metricsEventTarget";
|
|
8
|
-
import { operationalMetricReporterFactory } from "../operationalMetricsReporter";
|
|
8
|
+
import { operationalMetricReporterFactory, } from "../operational/operationalMetricsReporter";
|
|
9
9
|
// We ignore short-duration lens waits.
|
|
10
10
|
//
|
|
11
11
|
// The value is documented here:
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reportLensWait.js","sourceRoot":"","sources":["../../../src/metrics/reporters/reportLensWait.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AACpD,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC3C,OAAO,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAC9C,OAAO,EAAE,UAAU,EAAE,MAAM,uCAAuC,CAAC;AACnE,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AACjE,OAAO,EAAE,gBAAgB,EAAa,MAAM,yBAAyB,CAAC;AAEtE,OAAO,EAAsB,yBAAyB,EAAE,MAAM,uBAAuB,CAAC;AACtF,OAAO,
|
|
1
|
+
{"version":3,"file":"reportLensWait.js","sourceRoot":"","sources":["../../../src/metrics/reporters/reportLensWait.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AACpD,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC3C,OAAO,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAC9C,OAAO,EAAE,UAAU,EAAE,MAAM,uCAAuC,CAAC;AACnE,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AACjE,OAAO,EAAE,gBAAgB,EAAa,MAAM,yBAAyB,CAAC;AAEtE,OAAO,EAAsB,yBAAyB,EAAE,MAAM,uBAAuB,CAAC;AACtF,OAAO,EACH,gCAAgC,GAEnC,MAAM,2CAA2C,CAAC;AAEnD,uCAAuC;AACvC,EAAE;AACF,gCAAgC;AAChC,8GAA8G;AAC9G,MAAM,oBAAoB,GAAG,GAAG,CAAC;AAcjC;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,UAAU,CACpC,gBAAgB,EAChB,CAAC,gBAAgB,CAAC,KAAK,EAAE,yBAAyB,CAAC,KAAK,EAAE,gCAAgC,CAAC,KAAK,CAAU,EAC1G,CAAC,SAAoB,EAAE,kBAAsC,EAAE,QAAoC,EAAE,EAAE;IACnG,SAAS,CAAC,MAAM;SACX,IAAI,CACD,UAAU,CAAC,WAAW,CAAC,EACvB,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE;QACb,MAAM,MAAM,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;QAC9B,MAAM,kBAAkB,GAAG,SAAS,EAAE,CAAC;QACvC,OAAO,SAAS,CAAC,MAAM,CAAC,IAAI;QACxB,0FAA0F;QAC1F,sEAAsE;QACtE,EAAE;QACF,8FAA8F;QAC9F,gGAAgG;QAChG,6FAA6F;QAC7F,kDAAkD;QAClD,EAAE;QACF,8FAA8F;QAC9F,kDAAkD;QAClD,UAAU,CAAC,qBAAqB,EAAE,WAAW,CAAC,EAC9C,IAAI,CAAC,CAAC,CAAC,EACP,GAAG,CAAC,GAAqB,EAAE,CAAC,CAAC,CAAC,SAAS,EAAE,GAAG,kBAAkB,CAAC,GAAG,IAAI,EAAE,MAAM,CAAC,CAAC,CACnF,CAAC;IACN,CAAC,CAAC,CACL;SACA,SAAS,CAAC;QACP,IAAI,EAAE,CAAC,CAAC,WAAW,EAAE,MAAM,CAAC,EAAE,EAAE;YAC5B,IAAI,WAAW,GAAG,oBAAoB;gBAAE,OAAO;YAE/C,MAAM,QAAQ,GAAa;gBACvB,IAAI,EAAE,UAAU;gBAChB,MAAM;gBACN,WAAW;aACd,CAAC;YACF,kBAAkB,CAAC,aAAa,CAAC,IAAI,gBAAgB,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC,CAAC;YAC7E,QAAQ,CAAC,KAAK,CAAC,yBAAyB,EAAE,WAAW,GAAG,IAAI,CAAC,CAAC;QAClE,CAAC;KACJ,CAAC,CAAC;AACX,CAAC,CACJ,CAAC","sourcesContent":["import { forActions } from \"@snap/state-management\";\nimport { map, mergeMap, take } from \"rxjs\";\nimport { getTimeMs } from \"../../common/time\";\nimport { Injectable } from \"../../dependency-injection/Injectable\";\nimport { TypedCustomEvent } from \"../../events/TypedCustomEvent\";\nimport { lensStateFactory, LensState } from \"../../session/lensState\";\nimport { MakeTaggedBusinessEvent } from \"../businessEventsReporter\";\nimport { MetricsEventTarget, metricsEventTargetFactory } from \"../metricsEventTarget\";\nimport {\n operationalMetricReporterFactory,\n OperationalMetricsReporter,\n} from \"../operational/operationalMetricsReporter\";\n\n// We ignore short-duration lens waits.\n//\n// The value is documented here:\n// https://docs.google.com/document/d/1-kSzFWCWw9Qo3D08FR1_cqeHTsUtk9p3p3uOptzWDTY/edit#heading=h.q5liip76r9lt\nconst viewTimeThresholdSec = 0.1;\n\n/**\n * The LensWait metric measures the time spent downloading the lens content and required assets. It gives an indication\n * of the real UX impact of download latency. If lens content and assets are pre-loaded, the latency measured here\n * should decrease – we measure between the request to apply a lens and when the lens is ready to render.\n *\n * @category Lenses\n * @category Metrics\n */\n// This type corresponds to the internal CameraKitLensSpin event, described here:\n// https://docs.google.com/document/d/1-kSzFWCWw9Qo3D08FR1_cqeHTsUtk9p3p3uOptzWDTY#heading=h.q5liip76r9lt\nexport type LensWait = MakeTaggedBusinessEvent<\"lensWait\">;\n\n/**\n * Each time a lens is applied, we measure the duration until the lens is fully loaded by LensCore. This\n * includes any time spent downloading the lens content and required assets from the lens manifest.\n *\n * The intention of this event is to measure the experienced UX latency between a user requesting a lens and\n * the lens rendering. Of course, the application may call `applyLens` at any time, and may hide/show the\n * rendered result at any time – but this should give us a good baseline for how much UX latency could be seen.\n *\n * @internal\n */\nexport const reportLensWait = Injectable(\n \"reportLensWait\",\n [lensStateFactory.token, metricsEventTargetFactory.token, operationalMetricReporterFactory.token] as const,\n (lensState: LensState, metricsEventTarget: MetricsEventTarget, reporter: OperationalMetricsReporter) => {\n lensState.events\n .pipe(\n forActions(\"applyLens\"),\n mergeMap(([a]) => {\n const lensId = a.data.lens.id;\n const applyLensStartTime = getTimeMs();\n return lensState.events.pipe(\n // We'll measure the time until either the requested lens was rendered, or a new applyLens\n // request was made (in both cases, we're done waiting for this lens).\n //\n // This does have the side-effect that if a user rapidly switches between lenses, we'll record\n // many low-duration lensWait events that are measuring user behavior instead of system latency.\n // But this is a good trade-off so that we can capture those long-duration lensWaits that are\n // terminated by the user trying a different lens.\n //\n // (This effect can be mitigated by increasing the viewtimeThresholdSec to ignore low-duration\n // waits that are likely caused by user behavior).\n forActions(\"firstFrameProcessed\", \"applyLens\"),\n take(1),\n map((): [number, string] => [(getTimeMs() - applyLensStartTime) / 1000, lensId])\n );\n })\n )\n .subscribe({\n next: ([viewTimeSec, lensId]) => {\n if (viewTimeSec < viewTimeThresholdSec) return;\n\n const lensWait: LensWait = {\n name: \"lensWait\",\n lensId,\n viewTimeSec,\n };\n metricsEventTarget.dispatchEvent(new TypedCustomEvent(\"lensWait\", lensWait));\n reporter.timer(\"lens.apply_lens_latency\", viewTimeSec * 1000);\n },\n });\n }\n);\n"]}
|
|
@@ -11,7 +11,7 @@ export declare const reportSessionException: {
|
|
|
11
11
|
}> | import("@snap/state-management").Action<"downloadComplete", import("../..").Lens> | import("@snap/state-management").Action<"turnedOn", import("../..").Lens> | import("@snap/state-management").Action<"resourcesLoaded", import("../..").Lens> | import("@snap/state-management").Action<"firstFrameProcessed", import("../..").Lens> | import("@snap/state-management").Action<"applyLensComplete", import("../..").Lens> | import("@snap/state-management").Action<"applyLensFailed", {
|
|
12
12
|
error: import("../../session/lensState").LensErrors;
|
|
13
13
|
lens: import("../..").Lens;
|
|
14
|
-
}> | import("@snap/state-management").Action<"removeLens", undefined> | import("@snap/state-management").Action<"turnedOff", import("../..").Lens> | import("@snap/state-management").Action<"removeLensComplete", undefined> | import("@snap/state-management").Action<"removeLensFailed", Error>, import("@snap/state-management").State<"noLensApplied", undefined> | import("@snap/state-management").State<"applyingLens", import("../..").Lens> | import("@snap/state-management").State<"lensApplied", import("../..").Lens>>): void;
|
|
14
|
+
}> | import("@snap/state-management").Action<"applyLensAborted", import("../..").Lens> | import("@snap/state-management").Action<"removeLens", undefined> | import("@snap/state-management").Action<"turnedOff", import("../..").Lens> | import("@snap/state-management").Action<"removeLensComplete", undefined> | import("@snap/state-management").Action<"removeLensFailed", Error>, import("@snap/state-management").State<"noLensApplied", undefined> | import("@snap/state-management").State<"applyingLens", import("../..").Lens> | import("@snap/state-management").State<"lensApplied", import("../..").Lens>>): void;
|
|
15
15
|
token: "reportSessionException";
|
|
16
16
|
dependencies: readonly ["reportGlobalException", "lensState"];
|
|
17
17
|
};
|
|
@@ -8,13 +8,15 @@ import { PartialContainer } from "../../dependency-injection/PartialContainer";
|
|
|
8
8
|
*/
|
|
9
9
|
export declare const reportGloballyScopedMetrics: PartialContainer<{
|
|
10
10
|
reportBenchmarks: Promise<void>;
|
|
11
|
+
reportLegalState: void;
|
|
11
12
|
reportLensAndAssetDownload: void;
|
|
12
13
|
reportHttpMetrics: void;
|
|
13
14
|
}, {
|
|
14
15
|
configuration: import("../..").CameraKitConfiguration;
|
|
15
16
|
requestStateEventTarget: import("../../handlers/requestStateEmittingHandler").RequestStateEventTarget;
|
|
16
|
-
operationalMetricsReporter: import("../operationalMetricsReporter").OperationalMetricsReporter;
|
|
17
|
+
operationalMetricsReporter: import("../operational/operationalMetricsReporter").OperationalMetricsReporter;
|
|
17
18
|
metricsEventTarget: import("../metricsEventTarget").MetricsEventTarget;
|
|
19
|
+
legalState: import("@snap/state-management").StateMachine<import("@snap/state-management").Action<"requestLegalPrompt", undefined> | import("@snap/state-management").Action<"accept", string> | import("@snap/state-management").Action<"reject", string>, import("@snap/state-management").State<"unknown", undefined> | import("@snap/state-management").State<"accepted", undefined> | import("@snap/state-management").State<"rejected", undefined>>;
|
|
18
20
|
}>;
|
|
19
21
|
/**
|
|
20
22
|
* These metrics reporters must be run once for each CameraKitSession DI container created. They may depend on services
|
|
@@ -22,23 +24,21 @@ export declare const reportGloballyScopedMetrics: PartialContainer<{
|
|
|
22
24
|
*/
|
|
23
25
|
export declare const reportSessionScopedMetrics: PartialContainer<{
|
|
24
26
|
reportLensValidationFailed: void;
|
|
25
|
-
reportLensView: void
|
|
27
|
+
reportLensView: Promise<void>;
|
|
26
28
|
reportLensWait: void;
|
|
27
29
|
reportUserSession: Promise<void>;
|
|
28
|
-
reportLegalState: void;
|
|
29
30
|
reportSessionException: void;
|
|
30
31
|
}, {
|
|
31
32
|
configuration: import("../..").CameraKitConfiguration;
|
|
32
|
-
operationalMetricsReporter: import("../operationalMetricsReporter").OperationalMetricsReporter;
|
|
33
|
+
operationalMetricsReporter: import("../operational/operationalMetricsReporter").OperationalMetricsReporter;
|
|
33
34
|
metricsEventTarget: import("../metricsEventTarget").MetricsEventTarget;
|
|
34
|
-
legalState: import("@snap/state-management").StateMachine<import("@snap/state-management").Action<"requestLegalPrompt", undefined> | import("@snap/state-management").Action<"accept", string> | import("@snap/state-management").Action<"reject", string>, import("@snap/state-management").State<"unknown", undefined> | import("@snap/state-management").State<"accepted", undefined> | import("@snap/state-management").State<"rejected", undefined>>;
|
|
35
35
|
lensState: import("@snap/state-management").StateMachine<import("@snap/state-management").Action<"applyLens", {
|
|
36
36
|
lens: import("../..").Lens;
|
|
37
37
|
launchParams?: import("../..").LensLaunchParams | undefined;
|
|
38
38
|
}> | import("@snap/state-management").Action<"downloadComplete", import("../..").Lens> | import("@snap/state-management").Action<"turnedOn", import("../..").Lens> | import("@snap/state-management").Action<"resourcesLoaded", import("../..").Lens> | import("@snap/state-management").Action<"firstFrameProcessed", import("../..").Lens> | import("@snap/state-management").Action<"applyLensComplete", import("../..").Lens> | import("@snap/state-management").Action<"applyLensFailed", {
|
|
39
39
|
error: import("../../session/lensState").LensErrors;
|
|
40
40
|
lens: import("../..").Lens;
|
|
41
|
-
}> | import("@snap/state-management").Action<"removeLens", undefined> | import("@snap/state-management").Action<"turnedOff", import("../..").Lens> | import("@snap/state-management").Action<"removeLensComplete", undefined> | import("@snap/state-management").Action<"removeLensFailed", Error>, import("@snap/state-management").State<"noLensApplied", undefined> | import("@snap/state-management").State<"applyingLens", import("../..").Lens> | import("@snap/state-management").State<"lensApplied", import("../..").Lens>>;
|
|
41
|
+
}> | import("@snap/state-management").Action<"applyLensAborted", import("../..").Lens> | import("@snap/state-management").Action<"removeLens", undefined> | import("@snap/state-management").Action<"turnedOff", import("../..").Lens> | import("@snap/state-management").Action<"removeLensComplete", undefined> | import("@snap/state-management").Action<"removeLensFailed", Error>, import("@snap/state-management").State<"noLensApplied", undefined> | import("@snap/state-management").State<"applyingLens", import("../..").Lens> | import("@snap/state-management").State<"lensApplied", import("../..").Lens>>;
|
|
42
42
|
sessionState: import("@snap/state-management").StateMachine<import("@snap/state-management").Action<"suspend", import("../..").CameraKitSession> | import("@snap/state-management").Action<"resume", import("../..").CameraKitSession>, import("@snap/state-management").State<"inactive", undefined> | import("@snap/state-management").State<"active", import("../..").CameraKitSession>>;
|
|
43
43
|
CameraKitSession: import("../..").CameraKitSession;
|
|
44
44
|
reportGlobalException: import("./reportGlobalException").GlobalExceptionReporter;
|
|
@@ -18,7 +18,8 @@ import { reportUserSession } from "./reportUserSession";
|
|
|
18
18
|
export const reportGloballyScopedMetrics = new PartialContainer({})
|
|
19
19
|
.provides(reportHttpMetrics)
|
|
20
20
|
.provides(reportBenchmarks)
|
|
21
|
-
.provides(reportLensAndAssetDownload)
|
|
21
|
+
.provides(reportLensAndAssetDownload)
|
|
22
|
+
.provides(reportLegalState);
|
|
22
23
|
/**
|
|
23
24
|
* These metrics reporters must be run once for each CameraKitSession DI container created. They may depend on services
|
|
24
25
|
* which are only available at the session scope (e.g. the CameraKitSession itself).
|
|
@@ -28,6 +29,5 @@ export const reportSessionScopedMetrics = new PartialContainer({})
|
|
|
28
29
|
.provides(reportLensView)
|
|
29
30
|
.provides(reportLensWait)
|
|
30
31
|
.provides(reportSessionException)
|
|
31
|
-
.provides(reportLensValidationFailed)
|
|
32
|
-
.provides(reportLegalState);
|
|
32
|
+
.provides(reportLensValidationFailed);
|
|
33
33
|
//# sourceMappingURL=reporters.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reporters.js","sourceRoot":"","sources":["../../../src/metrics/reporters/reporters.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,6CAA6C,CAAC;AAC/E,OAAO,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;AAClE,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EAAE,0BAA0B,EAAE,MAAM,8BAA8B,CAAC;AAC1E,OAAO,EAAE,0BAA0B,EAAE,MAAM,8BAA8B,CAAC;AAC1E,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAExD;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,2BAA2B,GAAG,IAAI,gBAAgB,CAAC,EAAE,CAAC;KAC9D,QAAQ,CAAC,iBAAiB,CAAC;KAC3B,QAAQ,CAAC,gBAAgB,CAAC;KAC1B,QAAQ,CAAC,0BAA0B,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"reporters.js","sourceRoot":"","sources":["../../../src/metrics/reporters/reporters.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,6CAA6C,CAAC;AAC/E,OAAO,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;AAClE,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EAAE,0BAA0B,EAAE,MAAM,8BAA8B,CAAC;AAC1E,OAAO,EAAE,0BAA0B,EAAE,MAAM,8BAA8B,CAAC;AAC1E,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAExD;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,2BAA2B,GAAG,IAAI,gBAAgB,CAAC,EAAE,CAAC;KAC9D,QAAQ,CAAC,iBAAiB,CAAC;KAC3B,QAAQ,CAAC,gBAAgB,CAAC;KAC1B,QAAQ,CAAC,0BAA0B,CAAC;KACpC,QAAQ,CAAC,gBAAgB,CAAC,CAAC;AAEhC;;;GAGG;AACH,MAAM,CAAC,MAAM,0BAA0B,GAAG,IAAI,gBAAgB,CAAC,EAAE,CAAC;KAC7D,QAAQ,CAAC,iBAAiB,CAAC;KAC3B,QAAQ,CAAC,cAAc,CAAC;KACxB,QAAQ,CAAC,cAAc,CAAC;KACxB,QAAQ,CAAC,sBAAsB,CAAC;KAChC,QAAQ,CAAC,0BAA0B,CAAC,CAAC","sourcesContent":["import { PartialContainer } from \"../../dependency-injection/PartialContainer\";\nimport { reportSessionException } from \"./reportSessionException\";\nimport { reportBenchmarks } from \"./reportBenchmarks\";\nimport { reportHttpMetrics } from \"./reportHttpMetrics\";\nimport { reportLegalState } from \"./reportLegalState\";\nimport { reportLensAndAssetDownload } from \"./reportLensAndAssetDownload\";\nimport { reportLensValidationFailed } from \"./reportLensValidationFailed\";\nimport { reportLensView } from \"./reportLensView\";\nimport { reportLensWait } from \"./reportLensWait\";\nimport { reportUserSession } from \"./reportUserSession\";\n\n/**\n * These metrics reporters must be run once in the top-level DI container. They only depend on globally-available\n * services.\n *\n * The businessEventsReporter is special, it doesn't create any of its own metrics, it simply listens to the global\n * metricsEventTarget and reports metrics emitted there to our backend.\n */\nexport const reportGloballyScopedMetrics = new PartialContainer({})\n .provides(reportHttpMetrics)\n .provides(reportBenchmarks)\n .provides(reportLensAndAssetDownload)\n .provides(reportLegalState);\n\n/**\n * These metrics reporters must be run once for each CameraKitSession DI container created. They may depend on services\n * which are only available at the session scope (e.g. the CameraKitSession itself).\n */\nexport const reportSessionScopedMetrics = new PartialContainer({})\n .provides(reportUserSession)\n .provides(reportLensView)\n .provides(reportLensWait)\n .provides(reportSessionException)\n .provides(reportLensValidationFailed);\n"]}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { MonoTypeOperatorFunction } from "rxjs";
|
|
2
|
+
/**
|
|
3
|
+
* Returns an Observable that mirrors the source Observable, but will call a specified function when the source has no
|
|
4
|
+
* more subscribers.
|
|
5
|
+
*
|
|
6
|
+
* This is exactly like the `finalize` operator, exept that the specified function will be called only when the source
|
|
7
|
+
* is explicitly unsubscribed.
|
|
8
|
+
*
|
|
9
|
+
* @param callback Called when the source Observable has no more subscribers.
|
|
10
|
+
* @returns
|
|
11
|
+
*/
|
|
12
|
+
export declare function unsubscribed<T>(callback: () => void): MonoTypeOperatorFunction<T>;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { defer, finalize, tap } from "rxjs";
|
|
2
|
+
/**
|
|
3
|
+
* Returns an Observable that mirrors the source Observable, but will call a specified function when the source has no
|
|
4
|
+
* more subscribers.
|
|
5
|
+
*
|
|
6
|
+
* This is exactly like the `finalize` operator, exept that the specified function will be called only when the source
|
|
7
|
+
* is explicitly unsubscribed.
|
|
8
|
+
*
|
|
9
|
+
* @param callback Called when the source Observable has no more subscribers.
|
|
10
|
+
* @returns
|
|
11
|
+
*/
|
|
12
|
+
export function unsubscribed(callback) {
|
|
13
|
+
return (source) => defer(() => {
|
|
14
|
+
// We can tell if the source is completed or errored -- if neither has happened, we know the source is being
|
|
15
|
+
// finalized because all subscribers have left.
|
|
16
|
+
let completedOrErrored = false;
|
|
17
|
+
return source.pipe(tap({
|
|
18
|
+
complete: () => (completedOrErrored = true),
|
|
19
|
+
error: () => (completedOrErrored = true),
|
|
20
|
+
}), finalize(() => {
|
|
21
|
+
if (completedOrErrored)
|
|
22
|
+
return;
|
|
23
|
+
callback();
|
|
24
|
+
}));
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=unsubscribed.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"unsubscribed.js","sourceRoot":"","sources":["../../src/observable-operators/unsubscribed.ts"],"names":[],"mappings":"AAAA,OAAO,EAA4B,KAAK,EAAE,QAAQ,EAAE,GAAG,EAAE,MAAM,MAAM,CAAC;AAEtE;;;;;;;;;GASG;AACH,MAAM,UAAU,YAAY,CAAI,QAAoB;IAChD,OAAO,CAAC,MAAM,EAAE,EAAE,CACd,KAAK,CAAC,GAAG,EAAE;QACP,4GAA4G;QAC5G,+CAA+C;QAC/C,IAAI,kBAAkB,GAAG,KAAK,CAAC;QAC/B,OAAO,MAAM,CAAC,IAAI,CACd,GAAG,CAAC;YACA,QAAQ,EAAE,GAAG,EAAE,CAAC,CAAC,kBAAkB,GAAG,IAAI,CAAC;YAC3C,KAAK,EAAE,GAAG,EAAE,CAAC,CAAC,kBAAkB,GAAG,IAAI,CAAC;SAC3C,CAAC,EACF,QAAQ,CAAC,GAAG,EAAE;YACV,IAAI,kBAAkB;gBAAE,OAAO;YAC/B,QAAQ,EAAE,CAAC;QACf,CAAC,CAAC,CACL,CAAC;IACN,CAAC,CAAC,CAAC;AACX,CAAC","sourcesContent":["import { MonoTypeOperatorFunction, defer, finalize, tap } from \"rxjs\";\n\n/**\n * Returns an Observable that mirrors the source Observable, but will call a specified function when the source has no\n * more subscribers.\n *\n * This is exactly like the `finalize` operator, exept that the specified function will be called only when the source\n * is explicitly unsubscribed.\n *\n * @param callback Called when the source Observable has no more subscribers.\n * @returns\n */\nexport function unsubscribed<T>(callback: () => void): MonoTypeOperatorFunction<T> {\n return (source) =>\n defer(() => {\n // We can tell if the source is completed or errored -- if neither has happened, we know the source is being\n // finalized because all subscribers have left.\n let completedOrErrored = false;\n return source.pipe(\n tap({\n complete: () => (completedOrErrored = true),\n error: () => (completedOrErrored = true),\n }),\n finalize(() => {\n if (completedOrErrored) return;\n callback();\n })\n );\n });\n}\n"]}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { ConfigTargetingRequest } from "../generated-proto/pb_schema/cdp/cof/config_request";
|
|
2
2
|
import { ConfigTargetingResponse } from "../generated-proto/pb_schema/cdp/cof/config_response";
|
|
3
3
|
import { RequestStateEventTarget } from "../handlers/requestStateEmittingHandler";
|
|
4
|
-
import { OperationalMetricsReporter } from "../metrics/operationalMetricsReporter";
|
|
4
|
+
import { OperationalMetricsReporter } from "../metrics/operational/operationalMetricsReporter";
|
|
5
5
|
interface Metadata {
|
|
6
6
|
[key: string]: string;
|
|
7
7
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cofHandler.js","sourceRoot":"","sources":["../../src/remote-configuration/cofHandler.ts"],"names":[],"mappings":"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","sourcesContent":["import { BrowserHeaders } from \"browser-headers\";\nimport { cameraKitUserAgent } from \"../common/cameraKitUserAgent\";\nimport { ensureError } from \"../common/errorHelpers\";\nimport { CircumstancesServiceClientImpl, GrpcWebImpl } from \"../generated-proto/pb_schema/cdp/cof/circumstance_service\";\nimport { ConfigTargetingRequest } from \"../generated-proto/pb_schema/cdp/cof/config_request\";\nimport { ConfigTargetingResponse } from \"../generated-proto/pb_schema/cdp/cof/config_response\";\nimport { ChainableHandler, HandlerChainBuilder, RequestMetadata } from \"../handlers/HandlerChainBuilder\";\nimport {\n RequestStateEventTarget,\n dispatchRequestCompleted,\n dispatchRequestErrored,\n dispatchRequestStarted,\n} from \"../handlers/requestStateEmittingHandler\";\nimport { createResponseCachingHandler, staleWhileRevalidateStrategy } from \"../handlers/responseCachingHandler\";\nimport { createRetryingHandler } from \"../handlers/retryingHandler\";\nimport { createTimeoutHandler } from \"../handlers/timeoutHandler\";\nimport { ExpiringPersistence } from \"../persistence/ExpiringPersistence\";\nimport { IndexedDBPersistence } from \"../persistence/IndexedDBPersistence\";\nimport { OperationalMetricsReporter } from \"../metrics/operationalMetricsReporter\";\n\ninterface Metadata {\n [key: string]: string;\n}\n\nconst id = <Req, Res, Meta extends RequestMetadata>(h: ChainableHandler<Req, Res, Req, Res, Meta>) => h;\n\n// We need to wrap `targetingQuery` to create a usable Handler – the main issue is that HandlerChainBuilder always adds\n// a `signal` property to the metadata argument (second argument of the Handler), but `targetingQuery` expects the\n// second argument to only contain headers.\nconst createTargetingQueryHandler =\n (apiToken: string) =>\n async (\n request: Partial<ConfigTargetingRequest>,\n { signal, isSideEffect: _, ...metadata }: Metadata & RequestMetadata\n ) => {\n const rpc = new GrpcWebImpl(\"https://api-kit.snapchat.com\", {});\n const client = new CircumstancesServiceClientImpl(rpc);\n return new Promise<ConfigTargetingResponse>((resolve, reject) => {\n if (signal) {\n signal.addEventListener(\"abort\", () => reject(new Error(\"COF request aborted by handler chain.\")));\n }\n client\n .targetingQuery(\n request,\n new BrowserHeaders({\n authorization: `Bearer ${apiToken}`,\n \"x-snap-client-user-agent\": cameraKitUserAgent.userAgent,\n ...metadata,\n })\n )\n .then((response) => {\n // NOTE: in order for cache persistance to work, we need to make the object cloneable,\n // i.e. with no methods (it appears targetingQuery() attaches toObject() to response object).\n // Safety: We have to cast response object to a type that has toObject defined, because that is\n // indeed what generated code has:\n // eslint-disable-next-line max-len\n // https://github.sc-corp.net/Snapchat/camera-kit-web-sdk/blob/8d6b4e8bfa3717b376ab197a49972a1e410851f7/packages/web-sdk/src/generated-proto/pb_schema/cdp/cof/circumstance_service.ts#L1459\n delete (response as any).toObject;\n resolve(response);\n })\n .catch(reject);\n });\n };\n\nexport const COF_REQUEST_TYPE = \"cof\";\n\nexport type CofDimensions = { requestType: typeof COF_REQUEST_TYPE };\n\n/**\n * Handler chain used to make COF requests. Uses the COF client to perform the\n * requests, with retries, timeout, and caching.\n *\n * The handler will first attempt to retrieve the COF response from cache. If it is found, the result is returned\n * immediately and the cache is updated in the background. If no response is found, a COF request is made. This request\n * will retry (with exponential backoff + jitter) for 5 seconds before returning an error to the caller.\n */\nexport const cofHandlerFactory = (\n requestStateEventTarget: RequestStateEventTarget,\n apiToken: string,\n reporter: OperationalMetricsReporter\n) =>\n new HandlerChainBuilder(createTargetingQueryHandler(apiToken))\n .map(\n id((next) => async (request, metadata) => {\n const dimensions: CofDimensions = { requestType: COF_REQUEST_TYPE };\n const { requestId } = dispatchRequestStarted(requestStateEventTarget, { dimensions });\n try {\n const response = await next(request, metadata);\n // TODO: We hardcode status code and sizeByte values because we do not have access to underlying\n // transport of configs-web.\n // When this ticket is done https://jira.sc-corp.net/browse/CAMKIT-2840,\n // we will remove this handler and benefit from existing ones.\n const status = 200;\n let sizeByte = 0;\n try {\n sizeByte = new TextEncoder().encode(JSON.stringify(response)).byteLength;\n } finally {\n dispatchRequestCompleted(requestStateEventTarget, { requestId, dimensions, status, sizeByte });\n return response;\n }\n } catch (error) {\n dispatchRequestErrored(requestStateEventTarget, {\n requestId,\n dimensions,\n error: ensureError(error),\n });\n throw error;\n }\n })\n )\n // targetingQuery() always converts failed responses into errors (unlike fetch()), so we need a custom\n // retryPredicate that retries all errors. We'll keep retrying (with backoff) for 20 seconds total elapsed\n // time before we return an error back up the chain.\n .map(createRetryingHandler({ retryPredicate: (r) => r instanceof Error }))\n // API gateway has 15 seconds timeout, so we rely on that first\n .map(createTimeoutHandler({ timeout: 20 * 1000 }))\n .map(\n createResponseCachingHandler(\n // COF responses will be removed from cache after 1 week. Keep in mind that the staleWhileRevalidate\n // strategy will update the cache each time COF is requested – this expiration comes into play only if\n // e.g. a user doesn't load the page for more than a week.\n new ExpiringPersistence<ConfigTargetingResponse>(\n () => 7 * 24 * 60 * 60,\n new IndexedDBPersistence({ databaseName: \"COFCache\" })\n ),\n (r: Partial<ConfigTargetingRequest>) => JSON.stringify(r),\n\n // If we have a matching response already in cache, we'll return it immediately and then update the\n // cache in the background.\n staleWhileRevalidateStrategy({ requestType: \"cof\", reporter })\n )\n ).handler;\n"]}
|
|
1
|
+
{"version":3,"file":"cofHandler.js","sourceRoot":"","sources":["../../src/remote-configuration/cofHandler.ts"],"names":[],"mappings":"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","sourcesContent":["import { BrowserHeaders } from \"browser-headers\";\nimport { cameraKitUserAgent } from \"../common/cameraKitUserAgent\";\nimport { ensureError } from \"../common/errorHelpers\";\nimport { CircumstancesServiceClientImpl, GrpcWebImpl } from \"../generated-proto/pb_schema/cdp/cof/circumstance_service\";\nimport { ConfigTargetingRequest } from \"../generated-proto/pb_schema/cdp/cof/config_request\";\nimport { ConfigTargetingResponse } from \"../generated-proto/pb_schema/cdp/cof/config_response\";\nimport { ChainableHandler, HandlerChainBuilder, RequestMetadata } from \"../handlers/HandlerChainBuilder\";\nimport {\n RequestStateEventTarget,\n dispatchRequestCompleted,\n dispatchRequestErrored,\n dispatchRequestStarted,\n} from \"../handlers/requestStateEmittingHandler\";\nimport { createResponseCachingHandler, staleWhileRevalidateStrategy } from \"../handlers/responseCachingHandler\";\nimport { createRetryingHandler } from \"../handlers/retryingHandler\";\nimport { createTimeoutHandler } from \"../handlers/timeoutHandler\";\nimport { ExpiringPersistence } from \"../persistence/ExpiringPersistence\";\nimport { IndexedDBPersistence } from \"../persistence/IndexedDBPersistence\";\nimport { OperationalMetricsReporter } from \"../metrics/operational/operationalMetricsReporter\";\n\ninterface Metadata {\n [key: string]: string;\n}\n\nconst id = <Req, Res, Meta extends RequestMetadata>(h: ChainableHandler<Req, Res, Req, Res, Meta>) => h;\n\n// We need to wrap `targetingQuery` to create a usable Handler – the main issue is that HandlerChainBuilder always adds\n// a `signal` property to the metadata argument (second argument of the Handler), but `targetingQuery` expects the\n// second argument to only contain headers.\nconst createTargetingQueryHandler =\n (apiToken: string) =>\n async (\n request: Partial<ConfigTargetingRequest>,\n { signal, isSideEffect: _, ...metadata }: Metadata & RequestMetadata\n ) => {\n const rpc = new GrpcWebImpl(\"https://api-kit.snapchat.com\", {});\n const client = new CircumstancesServiceClientImpl(rpc);\n return new Promise<ConfigTargetingResponse>((resolve, reject) => {\n if (signal) {\n signal.addEventListener(\"abort\", () => reject(new Error(\"COF request aborted by handler chain.\")));\n }\n client\n .targetingQuery(\n request,\n new BrowserHeaders({\n authorization: `Bearer ${apiToken}`,\n \"x-snap-client-user-agent\": cameraKitUserAgent.userAgent,\n ...metadata,\n })\n )\n .then((response) => {\n // NOTE: in order for cache persistance to work, we need to make the object cloneable,\n // i.e. with no methods (it appears targetingQuery() attaches toObject() to response object).\n // Safety: We have to cast response object to a type that has toObject defined, because that is\n // indeed what generated code has:\n // eslint-disable-next-line max-len\n // https://github.sc-corp.net/Snapchat/camera-kit-web-sdk/blob/8d6b4e8bfa3717b376ab197a49972a1e410851f7/packages/web-sdk/src/generated-proto/pb_schema/cdp/cof/circumstance_service.ts#L1459\n delete (response as any).toObject;\n resolve(response);\n })\n .catch(reject);\n });\n };\n\nexport const COF_REQUEST_TYPE = \"cof\";\n\nexport type CofDimensions = { requestType: typeof COF_REQUEST_TYPE };\n\n/**\n * Handler chain used to make COF requests. Uses the COF client to perform the\n * requests, with retries, timeout, and caching.\n *\n * The handler will first attempt to retrieve the COF response from cache. If it is found, the result is returned\n * immediately and the cache is updated in the background. If no response is found, a COF request is made. This request\n * will retry (with exponential backoff + jitter) for 5 seconds before returning an error to the caller.\n */\nexport const cofHandlerFactory = (\n requestStateEventTarget: RequestStateEventTarget,\n apiToken: string,\n reporter: OperationalMetricsReporter\n) =>\n new HandlerChainBuilder(createTargetingQueryHandler(apiToken))\n .map(\n id((next) => async (request, metadata) => {\n const dimensions: CofDimensions = { requestType: COF_REQUEST_TYPE };\n const { requestId } = dispatchRequestStarted(requestStateEventTarget, { dimensions });\n try {\n const response = await next(request, metadata);\n // TODO: We hardcode status code and sizeByte values because we do not have access to underlying\n // transport of configs-web.\n // When this ticket is done https://jira.sc-corp.net/browse/CAMKIT-2840,\n // we will remove this handler and benefit from existing ones.\n const status = 200;\n let sizeByte = 0;\n try {\n sizeByte = new TextEncoder().encode(JSON.stringify(response)).byteLength;\n } finally {\n dispatchRequestCompleted(requestStateEventTarget, { requestId, dimensions, status, sizeByte });\n return response;\n }\n } catch (error) {\n dispatchRequestErrored(requestStateEventTarget, {\n requestId,\n dimensions,\n error: ensureError(error),\n });\n throw error;\n }\n })\n )\n // targetingQuery() always converts failed responses into errors (unlike fetch()), so we need a custom\n // retryPredicate that retries all errors. We'll keep retrying (with backoff) for 20 seconds total elapsed\n // time before we return an error back up the chain.\n .map(createRetryingHandler({ retryPredicate: (r) => r instanceof Error }))\n // API gateway has 15 seconds timeout, so we rely on that first\n .map(createTimeoutHandler({ timeout: 20 * 1000 }))\n .map(\n createResponseCachingHandler(\n // COF responses will be removed from cache after 1 week. Keep in mind that the staleWhileRevalidate\n // strategy will update the cache each time COF is requested – this expiration comes into play only if\n // e.g. a user doesn't load the page for more than a week.\n new ExpiringPersistence<ConfigTargetingResponse>(\n () => 7 * 24 * 60 * 60,\n new IndexedDBPersistence({ databaseName: \"COFCache\" })\n ),\n (r: Partial<ConfigTargetingRequest>) => JSON.stringify(r),\n\n // If we have a matching response already in cache, we'll return it immediately and then update the\n // cache in the background.\n staleWhileRevalidateStrategy({ requestType: \"cof\", reporter })\n )\n ).handler;\n"]}
|