@snap/camera-kit 0.13.1 → 0.14.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 +4 -3
- package/docs/html/classes/CameraKitSession.html +4 -3
- package/docs/html/classes/CameraKitSource.html +4 -3
- package/docs/html/classes/LensPerformanceMeasurement.html +4 -3
- package/docs/html/classes/LensPerformanceMetrics.html +4 -3
- package/docs/html/classes/LensRepository.html +6 -5
- package/docs/html/classes/LensSources.html +4 -3
- package/docs/html/classes/Transform2D.html +4 -3
- package/docs/html/classes/TypedCustomEvent.html +4 -3
- package/docs/html/classes/TypedEventTarget.html +4 -3
- package/docs/html/functions/Injectable.html +4 -3
- package/docs/html/functions/bootstrapCameraKit.html +4 -3
- package/docs/html/functions/createExtension.html +4 -3
- package/docs/html/functions/createImageSource.html +4 -3
- package/docs/html/functions/createMediaStreamSource.html +4 -3
- package/docs/html/functions/createUserMediaSource.html +4 -3
- package/docs/html/functions/createVideoSource.html +4 -3
- package/docs/html/functions/estimateLensPerformance.html +4 -3
- package/docs/html/functions/getRequiredBootstrapURLs.html +4 -3
- package/docs/html/functions/lensSourcesFactory.html +4 -3
- package/docs/html/functions/remoteApiServicesFactory.html +4 -3
- package/docs/html/index.html +5 -4
- package/docs/html/interfaces/CameraKitBootstrapConfiguration.html +16 -5
- package/docs/html/interfaces/CameraKitSourceSubscriber.html +5 -4
- package/docs/html/interfaces/ComputedFrameMetrics.html +4 -3
- package/docs/html/interfaces/CreateSessionOptions.html +4 -3
- package/docs/html/interfaces/EstimatedLensPerformance.html +4 -3
- package/docs/html/interfaces/Lens.html +22 -4
- package/docs/html/interfaces/LensSource.html +4 -3
- package/docs/html/interfaces/MediaStreamSourceOptions.html +4 -3
- package/docs/html/interfaces/Preview.html +4 -3
- package/docs/html/interfaces/RemoteApiRequest.html +4 -3
- package/docs/html/interfaces/RemoteApiResponse.html +4 -3
- package/docs/html/interfaces/RemoteApiService.html +4 -3
- package/docs/html/interfaces/Snapcode.html +4 -3
- package/docs/html/interfaces/UriCancelRequest.html +4 -3
- package/docs/html/interfaces/UriRequest.html +4 -3
- package/docs/html/interfaces/UriResponse.html +4 -3
- package/docs/html/interfaces/VideoSourceOptions.html +4 -3
- package/docs/html/modules.html +6 -4
- package/docs/html/types/AssetLoader.html +4 -3
- package/docs/html/types/AssetTiming.html +4 -3
- package/docs/html/types/BenchmarkError.html +4 -3
- package/docs/html/types/BootstrapError.html +4 -3
- package/docs/html/types/CacheKeyNotFoundError.html +4 -3
- package/docs/html/types/CameraKitDeviceInfo.html +4 -3
- package/docs/html/types/CameraKitDeviceOptions.html +4 -3
- package/docs/html/types/CameraKitSessionEventListener.html +4 -3
- package/docs/html/types/CameraKitSessionEvents.html +6 -5
- package/docs/html/types/CameraKitSourceError.html +4 -3
- package/docs/html/types/CameraKitSourceInfo.html +4 -3
- package/docs/html/types/CameraKitSourceOptions.html +4 -3
- package/docs/html/types/ConfigurationError.html +4 -3
- package/docs/html/types/Keyboard.html +4 -3
- package/docs/html/types/KeyboardEvents.html +4 -3
- package/docs/html/types/LegalError.html +4 -3
- package/docs/html/types/LensAbortError.html +119 -0
- package/docs/html/types/LensAssetError.html +4 -3
- package/docs/html/types/LensContentValidationError.html +4 -3
- package/docs/html/types/LensError.html +4 -3
- package/docs/html/types/LensExecutionError.html +4 -3
- package/docs/html/types/LensImagePickerError.html +4 -3
- package/docs/html/types/LensLaunchParams.html +4 -3
- package/docs/html/types/LensMetricsEvents.html +4 -3
- package/docs/html/types/LensPerformanceCluster.html +4 -3
- package/docs/html/types/LensView.html +4 -3
- package/docs/html/types/LensWait.html +4 -3
- package/docs/html/types/PersistentStoreError.html +4 -3
- package/docs/html/types/PlatformNotSupportedError.html +4 -3
- package/docs/html/types/PublicContainer.html +4 -3
- package/docs/html/types/RemoteApiRequestHandler.html +4 -3
- package/docs/html/types/RemoteApiServices.html +4 -3
- package/docs/html/types/RemoteApiStatus.html +4 -3
- package/docs/html/types/RenderTarget.html +4 -3
- package/docs/html/types/Uri.html +4 -3
- package/docs/html/types/WebGLError.html +4 -3
- package/docs/html/variables/extensionRequestContext.html +4 -3
- package/docs/md/classes/CameraKit.md +1 -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 +3 -3
- 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 +13 -2
- package/docs/md/interfaces/CameraKitSourceSubscriber.md +3 -3
- package/docs/md/interfaces/ComputedFrameMetrics.md +1 -1
- package/docs/md/interfaces/CreateSessionOptions.md +1 -1
- package/docs/md/interfaces/EstimatedLensPerformance.md +1 -1
- package/docs/md/interfaces/Lens.md +20 -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/RemoteApiRequest.md +1 -1
- package/docs/md/interfaces/RemoteApiResponse.md +1 -1
- package/docs/md/interfaces/RemoteApiService.md +1 -1
- package/docs/md/interfaces/Snapcode.md +1 -1
- package/docs/md/interfaces/UriCancelRequest.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 +24 -4
- package/lib/CameraKit.d.ts +139 -7
- package/lib/CameraKit.js +19 -19
- package/lib/CameraKit.js.map +1 -1
- package/lib/__tests__/data.d.ts +9 -4
- package/lib/__tests__/data.js +19 -9
- package/lib/__tests__/data.js.map +1 -1
- package/lib/bootstrapCameraKit.js +2 -2
- package/lib/bootstrapCameraKit.js.map +1 -1
- package/lib/common/any.d.ts +2 -0
- package/lib/common/any.js +23 -6
- package/lib/common/any.js.map +1 -1
- package/lib/common/localization.js +7 -31
- package/lib/common/localization.js.map +1 -1
- package/lib/configuration.d.ts +7 -0
- package/lib/configuration.js +1 -0
- package/lib/configuration.js.map +1 -1
- package/lib/configurationOverrides.d.ts +2 -2
- package/lib/configurationOverrides.js +11 -6
- package/lib/configurationOverrides.js.map +1 -1
- package/lib/dependency-injection/RootServices.d.ts +2 -2
- package/lib/dependency-injection/RootServices.js.map +1 -1
- package/lib/environment.json +1 -1
- package/lib/extensions/extensionRequestContext.js +4 -4
- package/lib/extensions/extensionRequestContext.js.map +1 -1
- package/lib/extensions/uriHandlersRegister.d.ts +2 -2
- package/lib/extensions/uriHandlersRegister.js.map +1 -1
- package/lib/generated-proto/blizzard/cameraKitEvents.d.ts +272 -0
- package/lib/generated-proto/blizzard/cameraKitEvents.js +38 -24
- package/lib/generated-proto/blizzard/cameraKitEvents.js.map +1 -1
- package/lib/generated-proto/pb_schema/camera_kit/v3/export.d.ts +2 -1
- package/lib/generated-proto/pb_schema/camera_kit/v3/export.js +6 -0
- package/lib/generated-proto/pb_schema/camera_kit/v3/export.js.map +1 -1
- package/lib/generated-proto/pb_schema/camera_kit/v3/features/ranking_info.d.ts +34 -0
- package/lib/generated-proto/pb_schema/camera_kit/v3/features/ranking_info.js +43 -0
- package/lib/generated-proto/pb_schema/camera_kit/v3/features/ranking_info.js.map +1 -0
- package/lib/generated-proto/pb_schema/camera_kit/v3/features/remote_api_info.d.ts +0 -2
- package/lib/generated-proto/pb_schema/camera_kit/v3/features/remote_api_info.js +0 -1
- package/lib/generated-proto/pb_schema/camera_kit/v3/features/remote_api_info.js.map +1 -1
- package/lib/generated-proto/pb_schema/cdp/cof/circumstance_service.d.ts +14346 -3145
- package/lib/generated-proto/pb_schema/cdp/cof/config_response.d.ts +1717 -62
- package/lib/generated-proto/pb_schema/cdp/cof/config_result.d.ts +6267 -373
- package/lib/generated-proto/pb_schema/cdp/cof/config_result.js +159 -4
- package/lib/generated-proto/pb_schema/cdp/cof/config_result.js.map +1 -1
- package/lib/generated-proto/pb_schema/common/ruid.d.ts +1 -0
- package/lib/generated-proto/pb_schema/common/ruid.js +1 -0
- package/lib/generated-proto/pb_schema/common/ruid.js.map +1 -1
- package/lib/generated-proto/pb_schema/lenses/launchdata.d.ts +31 -0
- package/lib/generated-proto/pb_schema/lenses/launchdata.js +143 -1
- package/lib/generated-proto/pb_schema/lenses/launchdata.js.map +1 -1
- package/lib/handlers/cameraKitServiceFetchHandlerFactory.js +2 -2
- package/lib/handlers/cameraKitServiceFetchHandlerFactory.js.map +1 -1
- package/lib/index.d.ts +3 -1
- package/lib/index.js +3 -1
- package/lib/index.js.map +1 -1
- package/lib/lens/Lens.d.ts +16 -1
- package/lib/lens/Lens.js +12 -3
- package/lib/lens/Lens.js.map +1 -1
- package/lib/lens/LensPersistenceStore.d.ts +2 -2
- package/lib/lens/LensPersistenceStore.js.map +1 -1
- package/lib/lens/LensRepository.d.ts +2 -2
- package/lib/lens/LensRepository.js +5 -4
- package/lib/lens/LensRepository.js.map +1 -1
- package/lib/lens/assets/LensAssetRepository.d.ts +4 -4
- package/lib/lens/assets/LensAssetRepository.js +1 -3
- package/lib/lens/assets/LensAssetRepository.js.map +1 -1
- package/lib/lens/assets/LensAssetsProvider.d.ts +9 -3
- package/lib/lens/assets/LensAssetsProvider.js +12 -5
- package/lib/lens/assets/LensAssetsProvider.js.map +1 -1
- package/lib/lens-client-interface/imagePicker.d.ts +2 -2
- package/lib/lens-client-interface/imagePicker.js.map +1 -1
- package/lib/lens-client-interface/lensClientInterface.d.ts +2 -2
- package/lib/lens-client-interface/lensClientInterface.js.map +1 -1
- package/lib/lens-core-module/generated-types.d.ts +4 -2
- package/lib/lens-core-module/generated-types.js.map +1 -1
- package/lib/lens-core-module/index.d.ts +1 -0
- package/lib/lens-core-module/index.js +1 -0
- package/lib/lens-core-module/index.js.map +1 -1
- package/lib/lens-core-module/lensCore.d.ts +41 -0
- package/lib/lens-core-module/lensCore.js +54 -0
- package/lib/lens-core-module/lensCore.js.map +1 -0
- package/lib/lens-core-module/lensCoreError.d.ts +15 -0
- package/lib/lens-core-module/lensCoreError.js +43 -0
- package/lib/lens-core-module/lensCoreError.js.map +1 -0
- package/lib/lens-core-module/loader/lensCoreFactory.d.ts +1 -2
- package/lib/lens-core-module/loader/lensCoreFactory.js +24 -26
- package/lib/lens-core-module/loader/lensCoreFactory.js.map +1 -1
- package/lib/lensCoreWasmVersions.json +3 -3
- package/lib/logger/registerLogEntriesSubscriber.js +2 -2
- package/lib/logger/registerLogEntriesSubscriber.js.map +1 -1
- package/lib/media-sources/CameraKitSource.d.ts +3 -3
- package/lib/media-sources/CameraKitSource.js +22 -31
- package/lib/media-sources/CameraKitSource.js.map +1 -1
- package/lib/media-sources/FunctionSource.js +33 -36
- package/lib/media-sources/FunctionSource.js.map +1 -1
- package/lib/media-sources/MediaStreamSource.js +11 -15
- package/lib/media-sources/MediaStreamSource.js.map +1 -1
- package/lib/metrics/businessEventsReporter.js +114 -108
- package/lib/metrics/businessEventsReporter.js.map +1 -1
- package/lib/metrics/reporters/reportGlobalException.js +25 -7
- package/lib/metrics/reporters/reportGlobalException.js.map +1 -1
- package/lib/metrics/reporters/reportHttpMetrics.js +2 -2
- package/lib/metrics/reporters/reportHttpMetrics.js.map +1 -1
- package/lib/metrics/reporters/reportLensView.js +5 -3
- package/lib/metrics/reporters/reportLensView.js.map +1 -1
- package/lib/metrics/reporters/reportLensWait.js +8 -2
- package/lib/metrics/reporters/reportLensWait.js.map +1 -1
- package/lib/metrics/reporters/reportPlatformCapabilities.d.ts +12 -0
- package/lib/metrics/reporters/reportPlatformCapabilities.js +18 -0
- package/lib/metrics/reporters/reportPlatformCapabilities.js.map +1 -0
- package/lib/metrics/reporters/reporters.d.ts +2 -1
- package/lib/metrics/reporters/reporters.js +3 -1
- package/lib/metrics/reporters/reporters.js.map +1 -1
- package/lib/namedErrors.d.ts +17 -0
- package/lib/namedErrors.js +2 -0
- package/lib/namedErrors.js.map +1 -1
- package/lib/platform/assertPlatformSupported.d.ts +4 -0
- package/lib/platform/assertPlatformSupported.js +15 -0
- package/lib/platform/assertPlatformSupported.js.map +1 -0
- package/lib/platform/cameraKitUserAgent.d.ts +2 -0
- package/lib/platform/cameraKitUserAgent.js +20 -0
- package/lib/platform/cameraKitUserAgent.js.map +1 -0
- package/lib/platform/platformCapabilities.d.ts +50 -0
- package/lib/platform/platformCapabilities.js +121 -0
- package/lib/platform/platformCapabilities.js.map +1 -0
- package/lib/{common/cameraKitUserAgent.d.ts → platform/platformInfo.d.ts} +13 -10
- package/lib/{common/cameraKitUserAgent.js → platform/platformInfo.js} +94 -100
- package/lib/platform/platformInfo.js.map +1 -0
- package/lib/remote-configuration/cofHandler.js +2 -2
- package/lib/remote-configuration/cofHandler.js.map +1 -1
- package/lib/remote-configuration/preloadConfiguration.d.ts +2 -2
- package/lib/remote-configuration/preloadConfiguration.js.map +1 -1
- package/lib/session/CameraKitSession.d.ts +3 -3
- package/lib/session/CameraKitSession.js +23 -30
- package/lib/session/CameraKitSession.js.map +1 -1
- package/lib/session/CameraKitSessionEvents.d.ts +7 -3
- package/lib/session/CameraKitSessionEvents.js +17 -0
- package/lib/session/CameraKitSessionEvents.js.map +1 -1
- package/lib/session/LensPerformanceMetrics.d.ts +2 -2
- package/lib/session/LensPerformanceMetrics.js +4 -3
- package/lib/session/LensPerformanceMetrics.js.map +1 -1
- package/lib/session/lensState.d.ts +2 -2
- package/lib/session/lensState.js +36 -37
- package/lib/session/lensState.js.map +1 -1
- package/package.json +2 -2
- package/lib/assertPlatformSupported.d.ts +0 -6
- package/lib/assertPlatformSupported.js +0 -21
- package/lib/assertPlatformSupported.js.map +0 -1
- package/lib/common/cameraKitUserAgent.js.map +0 -1
- package/lib/common/locale.d.ts +0 -2
- package/lib/common/locale.js +0 -11
- package/lib/common/locale.js.map +0 -1
|
@@ -13,23 +13,41 @@ const logMethods = entries(logLevelMap).map(([level]) => level);
|
|
|
13
13
|
const maxBufferedEntries = 15;
|
|
14
14
|
const contextSeparator = "\n\n----------------- Context -----------------\n\n";
|
|
15
15
|
const methodLength = logMethods.reduce((max, method) => Math.max(max, method.length), 0);
|
|
16
|
-
function getContextString(
|
|
16
|
+
function getContextString(logEntries) {
|
|
17
17
|
const result = [];
|
|
18
|
-
for (const entry of
|
|
18
|
+
for (const { entry, count, lastTime } of logEntries) {
|
|
19
19
|
const time = entry.time.toISOString();
|
|
20
20
|
const method = entry.level.padStart(methodLength);
|
|
21
21
|
// TODO: improve pretty printing
|
|
22
22
|
const messages = entry.messages.map((m) => m + "").join(" ");
|
|
23
|
-
|
|
23
|
+
let dupSuffix = count > 1 ? ` (Repeated ${count} times with the last occurrence at ${lastTime.toISOString()})` : "";
|
|
24
|
+
result.push(`${time} [${entry.module}] ${method}: ${messages}${dupSuffix}`);
|
|
24
25
|
}
|
|
25
26
|
return result.join("\n");
|
|
26
27
|
}
|
|
27
28
|
export function reportExceptionToBlizzard(logEntries, metricsEventTarget, reporter, lensState) {
|
|
28
29
|
logEntries
|
|
29
|
-
.pipe(scan((
|
|
30
|
-
entries
|
|
31
|
-
|
|
32
|
-
|
|
30
|
+
.pipe(scan(({ entries }, newEntry) => {
|
|
31
|
+
const lastEntry = entries[entries.length - 1];
|
|
32
|
+
const isNewEntryRepeated = lastEntry &&
|
|
33
|
+
lastEntry.entry.messages.join() === newEntry.messages.join() &&
|
|
34
|
+
lastEntry.entry.level === newEntry.level;
|
|
35
|
+
if (isNewEntryRepeated) {
|
|
36
|
+
lastEntry.count += 1;
|
|
37
|
+
lastEntry.lastTime = newEntry.time;
|
|
38
|
+
}
|
|
39
|
+
else {
|
|
40
|
+
entries.push({
|
|
41
|
+
entry: newEntry,
|
|
42
|
+
count: 1,
|
|
43
|
+
lastTime: newEntry.time,
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
return {
|
|
47
|
+
entries: entries.slice(-maxBufferedEntries),
|
|
48
|
+
recent: newEntry,
|
|
49
|
+
};
|
|
50
|
+
},
|
|
33
51
|
// Start with a dummy recent entry -- it gets overridden each time we handle a log entry.
|
|
34
52
|
{ entries: [], recent: { time: new Date(), module: "any", level: "debug", messages: [] } }), filter(({ recent }) => recent.level === "error"), map(({ entries, recent }) => ({
|
|
35
53
|
context: entries,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reportGlobalException.js","sourceRoot":"","sources":["../../../src/metrics/reporters/reportGlobalException.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AACjD,OAAO,EAAE,MAAM,EAAE,GAAG,EAAc,IAAI,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,MAAM,CAAC;AACzE,OAAO,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAC/C,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAC3D,OAAO,EAAE,UAAU,EAAE,MAAM,uCAAuC,CAAC;AACnE,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AACjE,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,EAAY,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAE5D,OAAO,EAAsB,yBAAyB,EAAE,MAAM,uBAAuB,CAAC;AACtF,OAAO,EACH,gCAAgC,GAEnC,MAAM,2CAA2C,CAAC;AAEnD,MAAM,UAAU,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC;AAEhE,uDAAuD;AACvD,MAAM,kBAAkB,GAAG,EAAE,CAAC;AAC9B,MAAM,gBAAgB,GAAG,qDAAqD,CAAC;AAC/E,MAAM,YAAY,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,MAAM,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"reportGlobalException.js","sourceRoot":"","sources":["../../../src/metrics/reporters/reportGlobalException.ts"],"names":[],"mappings":"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","sourcesContent":["import { isState } from \"@snap/state-management\";\nimport { filter, map, Observable, scan, Subject, takeUntil } from \"rxjs\";\nimport { entries } from \"../../common/entries\";\nimport { stringifyError } from \"../../common/errorHelpers\";\nimport { Injectable } from \"../../dependency-injection/Injectable\";\nimport { TypedCustomEvent } from \"../../events/TypedCustomEvent\";\nimport { logEntriesFactory } from \"../../logger/logEntries\";\nimport { LogEntry, logLevelMap } from \"../../logger/logger\";\nimport { LensState } from \"../../session/lensState\";\nimport { MetricsEventTarget, metricsEventTargetFactory } from \"../metricsEventTarget\";\nimport {\n operationalMetricReporterFactory,\n OperationalMetricsReporter,\n} from \"../operational/operationalMetricsReporter\";\n\nconst logMethods = entries(logLevelMap).map(([level]) => level);\n\n// How many log entries to include as the error context\nconst maxBufferedEntries = 15;\nconst contextSeparator = \"\\n\\n----------------- Context -----------------\\n\\n\";\nconst methodLength = logMethods.reduce((max, method) => Math.max(max, method.length), 0);\n\ninterface RepeatableLogEntry {\n entry: LogEntry;\n count: number;\n lastTime: Date;\n}\n\ninterface EntriesBuffer {\n /**\n * LogEntries grouped by their message.\n */\n entries: RepeatableLogEntry[];\n /**\n * The recent log entry.\n */\n recent: LogEntry;\n}\n\nfunction getContextString(logEntries: RepeatableLogEntry[]) {\n const result = [];\n for (const { entry, count, lastTime } of logEntries) {\n const time = entry.time.toISOString();\n const method = entry.level.padStart(methodLength);\n // TODO: improve pretty printing\n const messages = entry.messages.map((m) => m + \"\").join(\" \");\n let dupSuffix =\n count > 1 ? ` (Repeated ${count} times with the last occurrence at ${lastTime.toISOString()})` : \"\";\n\n result.push(`${time} [${entry.module}] ${method}: ${messages}${dupSuffix}`);\n }\n return result.join(\"\\n\");\n}\n\nexport function reportExceptionToBlizzard(\n logEntries: Observable<LogEntry>,\n metricsEventTarget: MetricsEventTarget,\n reporter: OperationalMetricsReporter,\n lensState?: LensState\n) {\n logEntries\n .pipe(\n scan<LogEntry, EntriesBuffer>(\n ({ entries }, newEntry) => {\n const lastEntry = entries[entries.length - 1];\n const isNewEntryRepeated =\n lastEntry &&\n lastEntry.entry.messages.join() === newEntry.messages.join() &&\n lastEntry.entry.level === newEntry.level;\n if (isNewEntryRepeated) {\n lastEntry.count += 1;\n lastEntry.lastTime = newEntry.time;\n } else {\n entries.push({\n entry: newEntry,\n count: 1,\n lastTime: newEntry.time,\n });\n }\n return {\n entries: entries.slice(-maxBufferedEntries),\n recent: newEntry,\n };\n },\n // Start with a dummy recent entry -- it gets overridden each time we handle a log entry.\n { entries: [], recent: { time: new Date(), module: \"any\", level: \"debug\", messages: [] } }\n ),\n filter(({ recent }) => recent.level === \"error\"),\n map(({ entries, recent }) => ({\n context: entries,\n error: recent.messages.find((e) => e instanceof Error) as Error,\n })),\n filter(({ error }) => !!error)\n )\n .subscribe(({ error, context }) => {\n const currentLensState = lensState?.getState();\n const lensId =\n currentLensState && !isState(currentLensState, \"noLensApplied\") ? currentLensState.data.id : \"none\";\n metricsEventTarget.dispatchEvent(\n new TypedCustomEvent(\"exception\", {\n name: \"exception\",\n lensId,\n type: error.name,\n reason: `${stringifyError(error)}${contextSeparator}${getContextString(context)}`,\n })\n );\n\n reporter.count(\"handled_exception\", 1, new Map([[\"type\", error.name]]));\n });\n}\n\nexport interface GlobalExceptionReporter {\n attachLensContext: (lensState: LensState) => void;\n}\n\n/**\n * Reports log entries to Blizzard when there is no CameraKit session yet.\n *\n * @internal\n */\nexport const reportGlobalException = Injectable(\n \"reportGlobalException\",\n [logEntriesFactory.token, metricsEventTargetFactory.token, operationalMetricReporterFactory.token] as const,\n (\n logEntries: Observable<LogEntry>,\n metricsEventTarget: MetricsEventTarget,\n reporter: OperationalMetricsReporter\n ): GlobalExceptionReporter => {\n // Initially we log exceptions without any lens context\n const cancellationSubject = new Subject<void>();\n reportExceptionToBlizzard(logEntries.pipe(takeUntil(cancellationSubject)), metricsEventTarget, reporter);\n\n // Later session scope reporter triggers cancellation of the global one\n // and initiates exception reporting with a lens context\n return {\n attachLensContext: (lensState: LensState) => {\n cancellationSubject.next();\n reportExceptionToBlizzard(logEntries, metricsEventTarget, reporter, lensState);\n },\n };\n }\n);\n"]}
|
|
@@ -4,7 +4,7 @@ import { scan } from "../../events/scan";
|
|
|
4
4
|
import { COF_REQUEST_TYPE } from "../../remote-configuration/cofHandler";
|
|
5
5
|
import { requestStateEventTargetFactory, } from "../../handlers/requestStateEmittingHandler";
|
|
6
6
|
import { operationalMetricReporterFactory, } from "../operational/operationalMetricsReporter";
|
|
7
|
-
import {
|
|
7
|
+
import { getPlatformInfo } from "../../platform/platformInfo";
|
|
8
8
|
import { isLensOrAssetRequest } from "./reportLensAndAssetDownload";
|
|
9
9
|
const getContentType = (dimensions) => {
|
|
10
10
|
switch (dimensions.requestType) {
|
|
@@ -68,7 +68,7 @@ export const reportHttpMetrics = Injectable("reportHttpMetrics", [operationalMet
|
|
|
68
68
|
const status = getStatus(event);
|
|
69
69
|
const operationalDimensions = new Map([
|
|
70
70
|
["content_type", getContentType(dimensions)],
|
|
71
|
-
["network_type", (_a =
|
|
71
|
+
["network_type", (_a = getPlatformInfo().connectionType) !== null && _a !== void 0 ? _a : "unknown"],
|
|
72
72
|
["status", status],
|
|
73
73
|
]);
|
|
74
74
|
return {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reportHttpMetrics.js","sourceRoot":"","sources":["../../../src/metrics/reporters/reportHttpMetrics.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,EAAE,UAAU,EAAE,MAAM,uCAAuC,CAAC;AACnE,OAAO,EAAE,IAAI,EAAE,MAAM,mBAAmB,CAAC;AACzC,OAAO,EAAiB,gBAAgB,EAAE,MAAM,uCAAuC,CAAC;AACxF,OAAO,EAIH,8BAA8B,GACjC,MAAM,4CAA4C,CAAC;AACpD,OAAO,EACH,gCAAgC,GAEnC,MAAM,2CAA2C,CAAC;AACnD,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"reportHttpMetrics.js","sourceRoot":"","sources":["../../../src/metrics/reporters/reportHttpMetrics.ts"],"names":[],"mappings":"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","sourcesContent":["import { assertUnreachable } from \"../../common/assertions\";\nimport { Injectable } from \"../../dependency-injection/Injectable\";\nimport { scan } from \"../../events/scan\";\nimport { CofDimensions, COF_REQUEST_TYPE } from \"../../remote-configuration/cofHandler\";\nimport {\n Dimensions,\n RequestStateEventTarget,\n RequestStateEvents,\n requestStateEventTargetFactory,\n} from \"../../handlers/requestStateEmittingHandler\";\nimport {\n operationalMetricReporterFactory,\n OperationalMetricsReporter,\n} from \"../operational/operationalMetricsReporter\";\nimport { getPlatformInfo } from \"../../platform/platformInfo\";\nimport { AssetDownloadDimensions, isLensOrAssetRequest, LensDownloadDimensions } from \"./reportLensAndAssetDownload\";\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 dimensions: Map<string, string>;\n downloadTimeMs: number;\n downloadSizeKb: number;\n}\ntype RequestState = InProgress | Completed;\n\nconst getContentType = (dimensions: LensDownloadDimensions | AssetDownloadDimensions | CofDimensions): string => {\n switch (dimensions.requestType) {\n case \"lens_content\":\n return \"lens_content\";\n case \"asset\":\n return dimensions.assetType;\n case COF_REQUEST_TYPE:\n return COF_REQUEST_TYPE;\n default:\n assertUnreachable(dimensions);\n }\n};\n\nconst getSizeKb = (event: RequestStateEvents): number => {\n switch (event.type) {\n case \"started\":\n case \"errored\":\n return 0;\n case \"completed\":\n return event.detail.sizeByte / 1024;\n default:\n assertUnreachable(event);\n }\n};\n\nconst getStatus = (event: RequestStateEvents): string => {\n switch (event.type) {\n case \"started\":\n case \"errored\":\n // We'll use status 0 to indicate that an exception occurred during the request. This is somewhat in keeping\n // with browsers that set the response status to 0 if the request was not able to be made (e.g. CORs\n // preflight failed, or the user canceled the request).\n return \"0\";\n case \"completed\":\n return event.detail.status.toString();\n default:\n assertUnreachable(event);\n }\n};\n\nexport const isRelevantRequest = (\n value: Dimensions\n): value is LensDownloadDimensions | AssetDownloadDimensions | CofDimensions => {\n return isLensOrAssetRequest(value) || value[\"requestType\"] === COF_REQUEST_TYPE;\n};\n\nexport const reportHttpMetrics = Injectable(\n \"reportHttpMetrics\",\n [operationalMetricReporterFactory.token, requestStateEventTargetFactory.token] as const,\n (reporter: OperationalMetricsReporter, requestStateEventTarget: RequestStateEventTarget) => {\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 (!isRelevantRequest(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 case \"errored\":\n const completedRequest = inProgress.get(requestId);\n if (!completedRequest) return state;\n inProgress.delete(requestId);\n\n const downloadTimeMs = timeMs - completedRequest.startTimeMs;\n const downloadSizeKb = getSizeKb(event);\n const status = getStatus(event);\n const operationalDimensions = new Map<string, string>([\n [\"content_type\", getContentType(dimensions)],\n [\"network_type\", getPlatformInfo().connectionType ?? \"unknown\"],\n [\"status\", status],\n ]);\n\n return {\n name: \"completed\",\n inProgress: state.inProgress,\n dimensions: operationalDimensions,\n downloadSizeKb,\n downloadTimeMs,\n };\n default:\n assertUnreachable(event);\n }\n }\n ).addEventListener(\"state\", ({ detail: state }) => {\n if (state.name !== \"completed\") return;\n\n const { dimensions, downloadTimeMs, downloadSizeKb } = state;\n\n reporter.count(\"download_finished\", 1, dimensions);\n reporter.timer(\"download_latency\", downloadTimeMs, dimensions);\n reporter.histogram(\"download_size_kb\", downloadSizeKb, dimensions);\n });\n }\n);\n"]}
|
|
@@ -74,7 +74,7 @@ export const reportLensView = Injectable("reportLensView", [
|
|
|
74
74
|
// If the session is resumed (e.g. user returns to this tab while a lens is on), we count this as a new
|
|
75
75
|
// LensView (and applyDelaySec will be 0).
|
|
76
76
|
lensState.events.pipe(inStates("lensApplied"), switchMap(([, s]) => sessionState.events.pipe(forActions("resume"), takeUntil(lensState.events.pipe(forActions("removeLens"))), map(() => s.data)))))
|
|
77
|
-
.pipe(map((lens) => [getTimeMs(), lens.id]), mergeMap(([applyLensStartTime, lensId]) => {
|
|
77
|
+
.pipe(map((lens) => [getTimeMs(), lens.id, lens.groupId]), mergeMap(([applyLensStartTime, lensId, lensGroupId]) => {
|
|
78
78
|
const alreadyOn = isState(lensState.getState(), "lensApplied");
|
|
79
79
|
const applyDelay = alreadyOn
|
|
80
80
|
? of(0)
|
|
@@ -98,10 +98,11 @@ export const reportLensView = Injectable("reportLensView", [
|
|
|
98
98
|
// turned on. But just in case that assumption is violated, we'll clean up
|
|
99
99
|
// (and not report) if another lens turns on before our lens is turned off.
|
|
100
100
|
takeUntil(lensState.events.pipe(forActions("turnedOn"), filter(([a]) => a.data.id !== lensId))), take(1), map(([applyDelaySec, viewMetrics, isFirstTimeResults]) => (Object.assign(Object.assign({ applyDelaySec,
|
|
101
|
-
lensId
|
|
101
|
+
lensId,
|
|
102
|
+
lensGroupId }, viewMetrics), isFirstTimeResults))));
|
|
102
103
|
}))
|
|
103
104
|
.subscribe({
|
|
104
|
-
next: ({ applyDelaySec, lensId, viewTimeSec, avgFps, lensFrameProcessingTimeMsAvg, lensFrameProcessingTimeMsStd, lensFrameProcessingTimeMsMedian, lensFrameProcessingN, isLensFirstWithinDay, isLensFirstWithinMonth, }) => __awaiter(void 0, void 0, void 0, function* () {
|
|
105
|
+
next: ({ applyDelaySec, lensId, lensGroupId, viewTimeSec, avgFps, lensFrameProcessingTimeMsAvg, lensFrameProcessingTimeMsStd, lensFrameProcessingTimeMsMedian, lensFrameProcessingN, isLensFirstWithinDay, isLensFirstWithinMonth, }) => __awaiter(void 0, void 0, void 0, function* () {
|
|
105
106
|
if (viewTimeSec < viewTimeThresholdSec)
|
|
106
107
|
return;
|
|
107
108
|
const lensView = {
|
|
@@ -109,6 +110,7 @@ export const reportLensView = Injectable("reportLensView", [
|
|
|
109
110
|
applyDelaySec,
|
|
110
111
|
avgFps,
|
|
111
112
|
lensId,
|
|
113
|
+
lensGroupId,
|
|
112
114
|
lensFrameProcessingTimeMsAvg,
|
|
113
115
|
lensFrameProcessingTimeMsStd,
|
|
114
116
|
// We don't support recording video, but applications may do this without our knowledge.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reportLensView.js","sourceRoot":"","sources":["../../../src/metrics/reporters/reportLensView.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE,EAAE,QAAQ,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,MAAM,CAAC;AACvH,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AACvE,OAAO,EAAE,UAAU,EAAE,MAAM,uCAAuC,CAAC;AACnE,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AACjE,OAAO,EAAsB,yBAAyB,EAAE,MAAM,uBAAuB,CAAC;AACtF,OAAO,EAAoB,uBAAuB,EAAE,MAAM,gCAAgC,CAAC;AAE3F,OAAO,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAC9C,OAAO,EACH,gCAAgC,GAEnC,MAAM,2CAA2C,CAAC;AACnD,OAAO,EAA0B,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AACjF,OAAO,EAAE,gBAAgB,EAAa,MAAM,yBAAyB,CAAC;AACtE,OAAO,EAAgB,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AAC/E,OAAO,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AACrD,OAAO,EAAE,oBAAoB,EAAE,MAAM,wCAAwC,CAAC;AAC9E,OAAO,EAAE,mBAAmB,EAAE,MAAM,uCAAuC,CAAC;AAC5E,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAEjE,uCAAuC;AACvC,EAAE;AACF,gCAAgC;AAChC,8GAA8G;AAC9G,MAAM,oBAAoB,GAAG,GAAG,CAAC;AAEjC,SAAe,wBAAwB,CAAC,MAAc,EAAE,WAAsC;;QAC1F,IAAI,oBAAoB,GAAG,KAAK,CAAC;QACjC,IAAI,sBAAsB,GAAG,KAAK,CAAC;QAEnC,IAAI;YACA,MAAM,gBAAgB,GAAG,MAAM,WAAW,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;YAC5D,MAAM,WAAW,GAAG,IAAI,IAAI,EAAE,CAAC;YAE/B,IAAI,CAAC,gBAAgB,EAAE;gBACnB,oBAAoB,GAAG,IAAI,CAAC;gBAC5B,sBAAsB,GAAG,IAAI,CAAC;aACjC;iBAAM;gBACH,oBAAoB,GAAG,YAAY,CAAC,MAAM,CAAC,gBAAgB,CAAC,KAAK,YAAY,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;gBAClG,sBAAsB,GAAG,cAAc,CAAC,MAAM,CAAC,gBAAgB,CAAC,KAAK,cAAc,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;aAC3G;YAED,MAAM,WAAW,CAAC,KAAK,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;SAChD;QAAC,OAAO,KAAK,EAAE;YACZ,OAAO,CAAC,KAAK,CAAC,yCAAyC,MAAM,KAAK,KAAK,EAAE,CAAC,CAAC;YAC3E,oBAAoB,GAAG,KAAK,CAAC;YAC7B,sBAAsB,GAAG,KAAK,CAAC;SAClC;QAED,OAAO,EAAE,oBAAoB,EAAE,sBAAsB,EAAE,CAAC;IAC5D,CAAC;CAAA;AAsBD;;GAEG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,UAAU,CACpC,gBAAgB,EAChB;IACI,uBAAuB,CAAC,KAAK;IAC7B,gBAAgB,CAAC,KAAK;IACtB,mBAAmB,CAAC,KAAK;IACzB,yBAAyB,CAAC,KAAK;IAC/B,gCAAgC,CAAC,KAAK;IACtC,kBAAkB;CACZ,EACV,CACI,OAAyB,EACzB,SAAoB,EACpB,YAA0B,EAC1B,kBAAsC,EACtC,0BAAsD,EACtD,aAAqC,EACxB,EAAE;;IACf,wGAAwG;IACxG,2GAA2G;IAC3G,6GAA6G;IAC7G,cAAc;IACd,MAAM,EAAE,OAAO,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,GAAG,MAAA,CAAC,MAAM,aAAa,CAAC,eAAe,CAAC,mCAAI;QAChG,OAAO,EAAE,CAAC;QACV,iBAAiB,EAAE,SAAS;KAC/B,CAAC;IAEF,MAAM,mBAAmB,GAAG,IAAI,mBAAmB;IAC/C,qBAAqB;IACrB,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,EACvB,IAAI,oBAAoB,CAAC,EAAE,YAAY,EAAE,iBAAiB,EAAE,CAAC,CAChE,CAAC;IAEF,KAAK;IACD,0GAA0G;IAC1G,qGAAqG;IACrG,SAAS,CAAC,MAAM,CAAC,IAAI,CACjB,UAAU,CAAC,kBAAkB,CAAC,EAC9B,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CACvB;IAED,uGAAuG;IACvG,0CAA0C;IAC1C,SAAS,CAAC,MAAM,CAAC,IAAI,CACjB,QAAQ,CAAC,aAAa,CAAC,EACvB,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAChB,YAAY,CAAC,MAAM,CAAC,IAAI,CACpB,UAAU,CAAC,QAAQ,CAAC,EACpB,SAAS,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC,CAAC,EAC1D,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CACpB,CACJ,CACJ,CACJ;SACI,IAAI,CACD,GAAG,CAAC,CAAC,IAAI,EAAoB,EAAE,CAAC,CAAC,SAAS,EAAE,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC,EACvD,QAAQ,CAAC,CAAC,CAAC,kBAAkB,EAAE,MAAM,CAAC,EAAE,EAAE;QACtC,MAAM,SAAS,GAAG,OAAO,CAAC,SAAS,CAAC,QAAQ,EAAE,EAAE,aAAa,CAAC,CAAC;QAE/D,MAAM,UAAU,GAAG,SAAS;YACxB,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;YACP,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,CACjB,UAAU,CAAC,iBAAiB,CAAC,EAC7B,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,MAAM,CAAC;YACrC,0FAA0F;YAC1F,+DAA+D;YAC/D,IAAI,CAAC,CAAC,CAAC,EACP,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC,SAAS,EAAE,GAAG,kBAAkB,CAAC,GAAG,IAAI,CAAC,CACvD,CAAC;QAER,MAAM,WAAW,GAAG,CAChB,SAAS;YACL,CAAC,CAAC,EAAE,CAAC,CAAC,SAAS,EAAE,EAAE,OAAO,CAAC,OAAO,CAAC,gBAAgB,EAAE,CAAU,CAAC;YAChE,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,CACjB,UAAU,CAAC,UAAU,CAAC,EACtB,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,MAAM,CAAC,EACrC,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC,SAAS,EAAE,EAAE,OAAO,CAAC,OAAO,CAAC,gBAAgB,EAAE,CAAU,CAAC,CACxE,CACV,CAAC,IAAI,CACF,IAAI,CAAC,CAAC,CAAC,EACP,QAAQ,CAAC,CAAC,CAAC,gBAAgB,EAAE,kBAAkB,CAAC,EAAE,EAAE,CAChD,SAAS,CAAC,MAAM,CAAC,IAAI,CACjB,UAAU,CAAC,WAAW,CAAC;QACvB,6EAA6E;QAC7E,mFAAmF;QACnF,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,MAAM,CAAC;QACrC,yEAAyE;QACzE,QAAQ,CAAC,YAAY,CAAC,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC,CAAC,EACzD,GAAG,CAAC,GAAG,EAAE;YACL,kBAAkB,CAAC,GAAG,EAAE,CAAC;YACzB,uBACI,WAAW,EAAE,CAAC,SAAS,EAAE,GAAG,gBAAgB,CAAC,GAAG,IAAI,IACjD,kBAAkB,CAAC,OAAO,EAAE,EACjC;QACN,CAAC,CAAC,CACL,CACJ,CACJ,CAAC;QAEF,OAAO,UAAU,CAAC,IAAI,CAClB,iBAAiB,CAAC,WAAW,EAAE,IAAI,CAAC,wBAAwB,CAAC,MAAM,EAAE,mBAAmB,CAAC,CAAC,CAAC;QAC3F,qFAAqF;QACrF,0EAA0E;QAC1E,2EAA2E;QAC3E,SAAS,CACL,SAAS,CAAC,MAAM,CAAC,IAAI,CACjB,UAAU,CAAC,UAAU,CAAC,EACtB,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,MAAM,CAAC,CACxC,CACJ,EACD,IAAI,CAAC,CAAC,CAAC,EACP,GAAG,CAAC,CAAC,CAAC,aAAa,EAAE,WAAW,EAAE,kBAAkB,CAAC,EAAE,EAAE,CAAC,+BACtD,aAAa;YACb,MAAM,IACH,WAAW,GACX,kBAAkB,EACvB,CAAC,CACN,CAAC;IACN,CAAC,CAAC,CACL;SACA,SAAS,CAAC;QACP,IAAI,EAAE,CAAO,EACT,aAAa,EACb,MAAM,EACN,WAAW,EACX,MAAM,EACN,4BAA4B,EAC5B,4BAA4B,EAC5B,+BAA+B,EAC/B,oBAAoB,EACpB,oBAAoB,EACpB,sBAAsB,GACzB,EAAE,EAAE;YACD,IAAI,WAAW,GAAG,oBAAoB;gBAAE,OAAO;YAE/C,MAAM,QAAQ,GAAa;gBACvB,IAAI,EAAE,UAAU;gBAChB,aAAa;gBACb,MAAM;gBACN,MAAM;gBACN,4BAA4B;gBAC5B,4BAA4B;gBAC5B,wFAAwF;gBACxF,gBAAgB,EAAE,CAAC;gBACnB,WAAW;gBACX,oBAAoB;gBACpB,sBAAsB;gBACtB,kBAAkB;gBAClB,iBAAiB;aACpB,CAAC;YAEF,kBAAkB,CAAC,aAAa,CAAC,IAAI,gBAAgB,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC,CAAC;YAC7E,0BAA0B,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,WAAW,EAAE,WAAW,GAAG,IAAI,CAAC,CAAC,CAAC;YAEpF,oGAAoG;YACpG,+FAA+F;YAC/F,sDAAsD;YACtD,IAAI,oBAAoB,IAAI,EAAE,EAAE;gBAC5B,0BAA0B,CAAC,MAAM,CAC7B,SAAS,CAAC,KAAK,CAAC,iCAAiC,EAAE,+BAA+B,EAAE;oBAChF,mBAAmB,EAAE,kBAAkB,CAAC,QAAQ,EAAE;iBACrD,CAAC,CACL,CAAC;aACL;QACL,CAAC,CAAA;KACJ,CAAC,CAAC;AACX,CAAC,CAAA,CACJ,CAAC","sourcesContent":["import { combineLatestWith, filter, from, 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\";\nimport { IndexedDBPersistence } from \"../../persistence/IndexedDBPersistence\";\nimport { ExpiringPersistence } from \"../../persistence/ExpiringPersistence\";\nimport { dayFormatter, monthFormatter } from \"../../common/date\";\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\nasync function isFirstTimeWithinPeriods(lensId: string, persistence: ExpiringPersistence<Date>) {\n let isLensFirstWithinDay = false;\n let isLensFirstWithinMonth = false;\n\n try {\n const lensLastViewDate = await persistence.retrieve(lensId);\n const currentDate = new Date();\n\n if (!lensLastViewDate) {\n isLensFirstWithinDay = true;\n isLensFirstWithinMonth = true;\n } else {\n isLensFirstWithinDay = dayFormatter.format(lensLastViewDate) !== dayFormatter.format(currentDate);\n isLensFirstWithinMonth = monthFormatter.format(lensLastViewDate) !== monthFormatter.format(currentDate);\n }\n\n await persistence.store(lensId, currentDate);\n } catch (error) {\n console.error(`Error handling persistence for lensId ${lensId}: ${error}`);\n isLensFirstWithinDay = false;\n isLensFirstWithinMonth = false;\n }\n\n return { isLensFirstWithinDay, isLensFirstWithinMonth };\n}\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 const lensViewPersistence = new ExpiringPersistence<Date>(\n // 60 days expiration\n () => 60 * 24 * 60 * 60,\n new IndexedDBPersistence({ databaseName: \"recentLensViews\" })\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, from(isFirstTimeWithinPeriods(lensId, lensViewPersistence))),\n // This lens should always receive the lensTurnedOff action *before* the next lens is\n // turned on. But just in case that assumption is violated, we'll clean up\n // (and not report) if another lens 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, isFirstTimeResults]) => ({\n applyDelaySec,\n lensId,\n ...viewMetrics,\n ...isFirstTimeResults,\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 isLensFirstWithinDay,\n isLensFirstWithinMonth,\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 isLensFirstWithinDay,\n isLensFirstWithinMonth,\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
|
+
{"version":3,"file":"reportLensView.js","sourceRoot":"","sources":["../../../src/metrics/reporters/reportLensView.ts"],"names":[],"mappings":"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","sourcesContent":["import { combineLatestWith, filter, from, 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\";\nimport { IndexedDBPersistence } from \"../../persistence/IndexedDBPersistence\";\nimport { ExpiringPersistence } from \"../../persistence/ExpiringPersistence\";\nimport { dayFormatter, monthFormatter } from \"../../common/date\";\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\nasync function isFirstTimeWithinPeriods(lensId: string, persistence: ExpiringPersistence<Date>) {\n let isLensFirstWithinDay = false;\n let isLensFirstWithinMonth = false;\n\n try {\n const lensLastViewDate = await persistence.retrieve(lensId);\n const currentDate = new Date();\n\n if (!lensLastViewDate) {\n isLensFirstWithinDay = true;\n isLensFirstWithinMonth = true;\n } else {\n isLensFirstWithinDay = dayFormatter.format(lensLastViewDate) !== dayFormatter.format(currentDate);\n isLensFirstWithinMonth = monthFormatter.format(lensLastViewDate) !== monthFormatter.format(currentDate);\n }\n\n await persistence.store(lensId, currentDate);\n } catch (error) {\n console.error(`Error handling persistence for lensId ${lensId}: ${error}`);\n isLensFirstWithinDay = false;\n isLensFirstWithinMonth = false;\n }\n\n return { isLensFirstWithinDay, isLensFirstWithinMonth };\n}\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 const lensViewPersistence = new ExpiringPersistence<Date>(\n // 60 days expiration\n () => 60 * 24 * 60 * 60,\n new IndexedDBPersistence({ databaseName: \"recentLensViews\" })\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, string] => [getTimeMs(), lens.id, lens.groupId]),\n mergeMap(([applyLensStartTime, lensId, lensGroupId]) => {\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, from(isFirstTimeWithinPeriods(lensId, lensViewPersistence))),\n // This lens should always receive the lensTurnedOff action *before* the next lens is\n // turned on. But just in case that assumption is violated, we'll clean up\n // (and not report) if another lens 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, isFirstTimeResults]) => ({\n applyDelaySec,\n lensId,\n lensGroupId,\n ...viewMetrics,\n ...isFirstTimeResults,\n }))\n );\n })\n )\n .subscribe({\n next: async ({\n applyDelaySec,\n lensId,\n lensGroupId,\n viewTimeSec,\n avgFps,\n lensFrameProcessingTimeMsAvg,\n lensFrameProcessingTimeMsStd,\n lensFrameProcessingTimeMsMedian,\n lensFrameProcessingN,\n isLensFirstWithinDay,\n isLensFirstWithinMonth,\n }) => {\n if (viewTimeSec < viewTimeThresholdSec) return;\n\n const lensView: LensView = {\n name: \"lensView\",\n applyDelaySec,\n avgFps,\n lensId,\n lensGroupId,\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 isLensFirstWithinDay,\n isLensFirstWithinMonth,\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"]}
|
|
@@ -25,6 +25,7 @@ export const reportLensWait = Injectable("reportLensWait", [lensStateFactory.tok
|
|
|
25
25
|
lensState.events
|
|
26
26
|
.pipe(forActions("applyLens"), mergeMap(([a]) => {
|
|
27
27
|
const lensId = a.data.lens.id;
|
|
28
|
+
const lensGroupId = a.data.lens.groupId;
|
|
28
29
|
const applyLensStartTime = getTimeMs();
|
|
29
30
|
return lensState.events.pipe(
|
|
30
31
|
// We'll measure the time until either the requested lens was rendered, or a new applyLens
|
|
@@ -37,16 +38,21 @@ export const reportLensWait = Injectable("reportLensWait", [lensStateFactory.tok
|
|
|
37
38
|
//
|
|
38
39
|
// (This effect can be mitigated by increasing the viewtimeThresholdSec to ignore low-duration
|
|
39
40
|
// waits that are likely caused by user behavior).
|
|
40
|
-
forActions("firstFrameProcessed", "applyLens"), take(1), map(() => [
|
|
41
|
+
forActions("firstFrameProcessed", "applyLens"), take(1), map(() => [
|
|
42
|
+
(getTimeMs() - applyLensStartTime) / 1000,
|
|
43
|
+
lensId,
|
|
44
|
+
lensGroupId,
|
|
45
|
+
]));
|
|
41
46
|
}))
|
|
42
47
|
.subscribe({
|
|
43
|
-
next: ([viewTimeSec, lensId]) => {
|
|
48
|
+
next: ([viewTimeSec, lensId, lensGroupId]) => {
|
|
44
49
|
if (viewTimeSec < viewTimeThresholdSec)
|
|
45
50
|
return;
|
|
46
51
|
const lensWait = {
|
|
47
52
|
name: "lensWait",
|
|
48
53
|
lensId,
|
|
49
54
|
viewTimeSec,
|
|
55
|
+
lensGroupId,
|
|
50
56
|
};
|
|
51
57
|
metricsEventTarget.dispatchEvent(new TypedCustomEvent("lensWait", lensWait));
|
|
52
58
|
reporter.timer("lens.apply_lens_latency", viewTimeSec * 1000);
|
|
@@ -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,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,
|
|
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,WAAW,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC;QACxC,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,GAA6B,EAAE,CAAC;YAChC,CAAC,SAAS,EAAE,GAAG,kBAAkB,CAAC,GAAG,IAAI;YACzC,MAAM;YACN,WAAW;SACd,CAAC,CACL,CAAC;IACN,CAAC,CAAC,CACL;SACA,SAAS,CAAC;QACP,IAAI,EAAE,CAAC,CAAC,WAAW,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,EAAE;YACzC,IAAI,WAAW,GAAG,oBAAoB;gBAAE,OAAO;YAE/C,MAAM,QAAQ,GAAa;gBACvB,IAAI,EAAE,UAAU;gBAChB,MAAM;gBACN,WAAW;gBACX,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 lensGroupId = a.data.lens.groupId;\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, string] => [\n (getTimeMs() - applyLensStartTime) / 1000,\n lensId,\n lensGroupId,\n ])\n );\n })\n )\n .subscribe({\n next: ([viewTimeSec, lensId, lensGroupId]) => {\n if (viewTimeSec < viewTimeThresholdSec) return;\n\n const lensWait: LensWait = {\n name: \"lensWait\",\n lensId,\n viewTimeSec,\n lensGroupId,\n };\n metricsEventTarget.dispatchEvent(new TypedCustomEvent(\"lensWait\", lensWait));\n reporter.timer(\"lens.apply_lens_latency\", viewTimeSec * 1000);\n },\n });\n }\n);\n"]}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { OperationalMetricsReporter } from "../operational/operationalMetricsReporter";
|
|
2
|
+
/**
|
|
3
|
+
* Report the number of total page loads that have support for various capabilities. By dividing by the total number of
|
|
4
|
+
* data points recorded, we can calculate the percent of page loads with support.
|
|
5
|
+
*
|
|
6
|
+
* @internal
|
|
7
|
+
*/
|
|
8
|
+
export declare const reportPlatformCapabilities: {
|
|
9
|
+
(args_0: OperationalMetricsReporter): Promise<void>;
|
|
10
|
+
token: "reportPlatformCapabilities";
|
|
11
|
+
dependencies: readonly ["operationalMetricsReporter"];
|
|
12
|
+
};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { __awaiter } from "tslib";
|
|
2
|
+
import { Injectable } from "../../dependency-injection/Injectable";
|
|
3
|
+
import { getPlatformCapabilities } from "../../platform/platformCapabilities";
|
|
4
|
+
import { Count } from "../operational/Count";
|
|
5
|
+
import { operationalMetricReporterFactory, } from "../operational/operationalMetricsReporter";
|
|
6
|
+
/**
|
|
7
|
+
* Report the number of total page loads that have support for various capabilities. By dividing by the total number of
|
|
8
|
+
* data points recorded, we can calculate the percent of page loads with support.
|
|
9
|
+
*
|
|
10
|
+
* @internal
|
|
11
|
+
*/
|
|
12
|
+
export const reportPlatformCapabilities = Injectable("reportPlatformCapabilities", [operationalMetricReporterFactory.token], (operationalMetricsReporter) => __awaiter(void 0, void 0, void 0, function* () {
|
|
13
|
+
const { webgl, wasm, webxr } = yield getPlatformCapabilities();
|
|
14
|
+
operationalMetricsReporter.report(Count.count("platform_webgl", webgl.supported ? 1 : 0));
|
|
15
|
+
operationalMetricsReporter.report(Count.count("platform_wasm", wasm.supported ? 1 : 0));
|
|
16
|
+
operationalMetricsReporter.report(Count.count("platform_webxr", webxr.supported ? 1 : 0));
|
|
17
|
+
}));
|
|
18
|
+
//# sourceMappingURL=reportPlatformCapabilities.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reportPlatformCapabilities.js","sourceRoot":"","sources":["../../../src/metrics/reporters/reportPlatformCapabilities.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,uCAAuC,CAAC;AACnE,OAAO,EAAE,uBAAuB,EAAE,MAAM,qCAAqC,CAAC;AAC9E,OAAO,EAAE,KAAK,EAAE,MAAM,sBAAsB,CAAC;AAC7C,OAAO,EAEH,gCAAgC,GACnC,MAAM,2CAA2C,CAAC;AAEnD;;;;;GAKG;AACH,MAAM,CAAC,MAAM,0BAA0B,GAAG,UAAU,CAChD,4BAA4B,EAC5B,CAAC,gCAAgC,CAAC,KAAK,CAAU,EACjD,CAAO,0BAAsD,EAAE,EAAE;IAC7D,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,MAAM,uBAAuB,EAAE,CAAC;IAC/D,0BAA0B,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,gBAAgB,EAAE,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC1F,0BAA0B,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,eAAe,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACxF,0BAA0B,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,gBAAgB,EAAE,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAC9F,CAAC,CAAA,CACJ,CAAC","sourcesContent":["import { Injectable } from \"../../dependency-injection/Injectable\";\nimport { getPlatformCapabilities } from \"../../platform/platformCapabilities\";\nimport { Count } from \"../operational/Count\";\nimport {\n OperationalMetricsReporter,\n operationalMetricReporterFactory,\n} from \"../operational/operationalMetricsReporter\";\n\n/**\n * Report the number of total page loads that have support for various capabilities. By dividing by the total number of\n * data points recorded, we can calculate the percent of page loads with support.\n *\n * @internal\n */\nexport const reportPlatformCapabilities = Injectable(\n \"reportPlatformCapabilities\",\n [operationalMetricReporterFactory.token] as const,\n async (operationalMetricsReporter: OperationalMetricsReporter) => {\n const { webgl, wasm, webxr } = await getPlatformCapabilities();\n operationalMetricsReporter.report(Count.count(\"platform_webgl\", webgl.supported ? 1 : 0));\n operationalMetricsReporter.report(Count.count(\"platform_wasm\", wasm.supported ? 1 : 0));\n operationalMetricsReporter.report(Count.count(\"platform_webxr\", webxr.supported ? 1 : 0));\n }\n);\n"]}
|
|
@@ -11,12 +11,13 @@ export declare const reportGloballyScopedMetrics: PartialContainer<{
|
|
|
11
11
|
reportLegalState: void;
|
|
12
12
|
reportLensAndAssetDownload: void;
|
|
13
13
|
reportHttpMetrics: void;
|
|
14
|
+
reportPlatformCapabilities: Promise<void>;
|
|
14
15
|
}, {
|
|
15
16
|
configuration: import("../..").CameraKitConfiguration;
|
|
16
17
|
requestStateEventTarget: import("../../handlers/requestStateEmittingHandler").RequestStateEventTarget;
|
|
17
18
|
operationalMetricsReporter: import("../operational/operationalMetricsReporter").OperationalMetricsReporter;
|
|
18
|
-
metricsEventTarget: import("../metricsEventTarget").MetricsEventTarget;
|
|
19
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>>;
|
|
20
|
+
metricsEventTarget: import("../metricsEventTarget").MetricsEventTarget;
|
|
20
21
|
}>;
|
|
21
22
|
/**
|
|
22
23
|
* These metrics reporters must be run once for each CameraKitSession DI container created. They may depend on services
|
|
@@ -8,6 +8,7 @@ import { reportLensValidationFailed } from "./reportLensValidationFailed";
|
|
|
8
8
|
import { reportLensView } from "./reportLensView";
|
|
9
9
|
import { reportLensWait } from "./reportLensWait";
|
|
10
10
|
import { reportUserSession } from "./reportUserSession";
|
|
11
|
+
import { reportPlatformCapabilities } from "./reportPlatformCapabilities";
|
|
11
12
|
/**
|
|
12
13
|
* These metrics reporters must be run once in the top-level DI container. They only depend on globally-available
|
|
13
14
|
* services.
|
|
@@ -19,7 +20,8 @@ export const reportGloballyScopedMetrics = new PartialContainer({})
|
|
|
19
20
|
.provides(reportHttpMetrics)
|
|
20
21
|
.provides(reportBenchmarks)
|
|
21
22
|
.provides(reportLensAndAssetDownload)
|
|
22
|
-
.provides(reportLegalState)
|
|
23
|
+
.provides(reportLegalState)
|
|
24
|
+
.provides(reportPlatformCapabilities);
|
|
23
25
|
/**
|
|
24
26
|
* These metrics reporters must be run once for each CameraKitSession DI container created. They may depend on services
|
|
25
27
|
* which are only available at the session scope (e.g. the CameraKitSession itself).
|
|
@@ -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;
|
|
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;AACxD,OAAO,EAAE,0BAA0B,EAAE,MAAM,8BAA8B,CAAC;AAE1E;;;;;;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;KAC1B,QAAQ,CAAC,0BAA0B,CAAC,CAAC;AAE1C;;;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\";\nimport { reportPlatformCapabilities } from \"./reportPlatformCapabilities\";\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 .provides(reportPlatformCapabilities);\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"]}
|
package/lib/namedErrors.d.ts
CHANGED
|
@@ -83,6 +83,23 @@ export declare const platformNotSupportedError: (message: string, cause?: unknow
|
|
|
83
83
|
export type LensExecutionError = NamedError<"LensExecutionError">;
|
|
84
84
|
/** @internal */
|
|
85
85
|
export declare const lensExecutionError: (message: string, cause?: unknown) => LensExecutionError;
|
|
86
|
+
/**
|
|
87
|
+
* This error occurs when a session becomes inoperable.
|
|
88
|
+
*
|
|
89
|
+
* It's always a good idea to handle this error and update the user experience accordingly.
|
|
90
|
+
* For example, you could show a message to a user.
|
|
91
|
+
*
|
|
92
|
+
* ```ts
|
|
93
|
+
* cameraKitSession.events.addEventListener('error', ({ detail }) => {
|
|
94
|
+
* if (detail.error.name === 'LensAbortError') {
|
|
95
|
+
* console.log(`Camera Kit encountered an unrecoverable error and became inoperable. Please refresh the page.`)
|
|
96
|
+
* }
|
|
97
|
+
* })
|
|
98
|
+
* ```
|
|
99
|
+
*/
|
|
100
|
+
export type LensAbortError = NamedError<"LensAbortError">;
|
|
101
|
+
/** @internal */
|
|
102
|
+
export declare const lensAbortError: (message: string, cause?: unknown) => LensAbortError;
|
|
86
103
|
/**
|
|
87
104
|
* Error thrown when LensCore asked to store lens data, but CameraKit failed storing that.
|
|
88
105
|
*/
|
package/lib/namedErrors.js
CHANGED
|
@@ -48,6 +48,8 @@ export const platformNotSupportedError = namedError("PlatformNotSupportedError")
|
|
|
48
48
|
/** @internal */
|
|
49
49
|
export const lensExecutionError = namedError("LensExecutionError");
|
|
50
50
|
/** @internal */
|
|
51
|
+
export const lensAbortError = namedError("LensAbortError");
|
|
52
|
+
/** @internal */
|
|
51
53
|
export const persistentStoreError = namedError("PersistentStoreError");
|
|
52
54
|
/** @internal */
|
|
53
55
|
export const lensAssetError = namedError("LensAssetError");
|
package/lib/namedErrors.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"namedErrors.js","sourceRoot":"","sources":["../src/namedErrors.ts"],"names":[],"mappings":"AAAA,4EAA4E;AAC5E,yFAAyF;AAczF;;GAEG;AACH,SAAS,eAAe,CAAC,KAAa;IAClC,MAAM,CAAC,KAAK,EAAE,CAAC,EAAE,GAAG,IAAI,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC9C,OAAO,CAAC,KAAK,EAAE,GAAG,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACvC,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,UAAU,CAKxB,IAAW;IACT,OAAO,CAAC,OAAe,EAAE,KAAe,EAAU,EAAE;QAChD,MAAM,KAAK,GAAG,IAAI,KAAK,CAAC,OAAO,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC;QAC5C,KAAK,CAAC,IAAI,GAAG,IAAI,CAAC;QAClB,KAAK,CAAC,KAAK,GAAG,KAAK,CAAC,KAAK,IAAI,eAAe,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QAC1D,4EAA4E;QAC5E,OAAO,KAAe,CAAC;IAC3B,CAAC,CAAC;AACN,CAAC;AAGD,gBAAgB;AAChB,MAAM,CAAC,MAAM,UAAU,GAAG,UAAU,CAAa,YAAY,CAAC,CAAC;AAG/D,gBAAgB;AAChB,MAAM,CAAC,MAAM,0BAA0B,GAAG,UAAU,CAA6B,4BAA4B,CAAC,CAAC;AAG/G,gBAAgB;AAChB,MAAM,CAAC,MAAM,SAAS,GAAG,UAAU,CAAY,WAAW,CAAC,CAAC;AAG5D,gBAAgB;AAChB,MAAM,CAAC,MAAM,oBAAoB,GAAG,UAAU,CAAuB,sBAAsB,CAAC,CAAC;AAO7F,gBAAgB;AAChB,MAAM,CAAC,MAAM,oBAAoB,GAAG,UAAU,CAAuB,sBAAsB,CAAC,CAAC;AAG7F,gBAAgB;AAChB,MAAM,CAAC,MAAM,qBAAqB,GAAG,UAAU,CAAwB,uBAAuB,CAAC,CAAC;AAQhG,gBAAgB;AAChB,MAAM,CAAC,MAAM,kBAAkB,GAAG,UAAU,CAAqB,oBAAoB,CAAC,CAAC;AAGvF,gBAAgB;AAChB,MAAM,CAAC,MAAM,UAAU,GAAG,UAAU,CAAa,YAAY,CAAC,CAAC;AAG/D,gBAAgB;AAChB,MAAM,CAAC,MAAM,cAAc,GAAG,UAAU,CAAiB,gBAAgB,CAAC,CAAC;AAU3E,gBAAgB;AAChB,MAAM,CAAC,MAAM,yBAAyB,GAAG,UAAU,CAA4B,2BAA2B,CAAC,CAAC;AAkB5G,gBAAgB;AAChB,MAAM,CAAC,MAAM,kBAAkB,GAAG,UAAU,CAAqB,oBAAoB,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"namedErrors.js","sourceRoot":"","sources":["../src/namedErrors.ts"],"names":[],"mappings":"AAAA,4EAA4E;AAC5E,yFAAyF;AAczF;;GAEG;AACH,SAAS,eAAe,CAAC,KAAa;IAClC,MAAM,CAAC,KAAK,EAAE,CAAC,EAAE,GAAG,IAAI,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC9C,OAAO,CAAC,KAAK,EAAE,GAAG,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACvC,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,UAAU,CAKxB,IAAW;IACT,OAAO,CAAC,OAAe,EAAE,KAAe,EAAU,EAAE;QAChD,MAAM,KAAK,GAAG,IAAI,KAAK,CAAC,OAAO,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC;QAC5C,KAAK,CAAC,IAAI,GAAG,IAAI,CAAC;QAClB,KAAK,CAAC,KAAK,GAAG,KAAK,CAAC,KAAK,IAAI,eAAe,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QAC1D,4EAA4E;QAC5E,OAAO,KAAe,CAAC;IAC3B,CAAC,CAAC;AACN,CAAC;AAGD,gBAAgB;AAChB,MAAM,CAAC,MAAM,UAAU,GAAG,UAAU,CAAa,YAAY,CAAC,CAAC;AAG/D,gBAAgB;AAChB,MAAM,CAAC,MAAM,0BAA0B,GAAG,UAAU,CAA6B,4BAA4B,CAAC,CAAC;AAG/G,gBAAgB;AAChB,MAAM,CAAC,MAAM,SAAS,GAAG,UAAU,CAAY,WAAW,CAAC,CAAC;AAG5D,gBAAgB;AAChB,MAAM,CAAC,MAAM,oBAAoB,GAAG,UAAU,CAAuB,sBAAsB,CAAC,CAAC;AAO7F,gBAAgB;AAChB,MAAM,CAAC,MAAM,oBAAoB,GAAG,UAAU,CAAuB,sBAAsB,CAAC,CAAC;AAG7F,gBAAgB;AAChB,MAAM,CAAC,MAAM,qBAAqB,GAAG,UAAU,CAAwB,uBAAuB,CAAC,CAAC;AAQhG,gBAAgB;AAChB,MAAM,CAAC,MAAM,kBAAkB,GAAG,UAAU,CAAqB,oBAAoB,CAAC,CAAC;AAGvF,gBAAgB;AAChB,MAAM,CAAC,MAAM,UAAU,GAAG,UAAU,CAAa,YAAY,CAAC,CAAC;AAG/D,gBAAgB;AAChB,MAAM,CAAC,MAAM,cAAc,GAAG,UAAU,CAAiB,gBAAgB,CAAC,CAAC;AAU3E,gBAAgB;AAChB,MAAM,CAAC,MAAM,yBAAyB,GAAG,UAAU,CAA4B,2BAA2B,CAAC,CAAC;AAkB5G,gBAAgB;AAChB,MAAM,CAAC,MAAM,kBAAkB,GAAG,UAAU,CAAqB,oBAAoB,CAAC,CAAC;AAiBvF,gBAAgB;AAChB,MAAM,CAAC,MAAM,cAAc,GAAG,UAAU,CAAiB,gBAAgB,CAAC,CAAC;AAM3E,gBAAgB;AAChB,MAAM,CAAC,MAAM,oBAAoB,GAAG,UAAU,CAAuB,sBAAsB,CAAC,CAAC;AAM7F,gBAAgB;AAChB,MAAM,CAAC,MAAM,cAAc,GAAG,UAAU,CAAiB,gBAAgB,CAAC,CAAC;AAS3E,gBAAgB;AAChB,MAAM,CAAC,MAAM,cAAc,GAAG,UAAU,CAAiB,gBAAgB,CAAC,CAAC","sourcesContent":["// NOTE: All errors thrown in the CameraKit package have to be defined here.\n// Error types are not infered from error factories for API doc purposes and consistency.\n\n/**\n * Helper type to extract type generic parameter.\n */\ntype ExtractName<P> = P extends NamedError<infer T> ? T : never;\n\n/**\n * All errors are expected to have \"Error\" suffix.\n */\ntype ErrorName = `${string}Error`;\n\ntype NamedError<Name extends ErrorName> = Error & { name: Name };\n\n/**\n * Removes the top trace line from the stack.\n */\nfunction cleanErrorStack(stack: string): string {\n const [first, _, ...rest] = stack.split(\"\\n\");\n return [first, ...rest].join(\"\\n\");\n}\n\n/**\n * Creates error factory that ensures Error.prototype.name field value.\n *\n * NOTE: exported only for unit tests.\n *\n * @param name Error name.\n * @returns Error factory function.\n * @internal\n */\nexport function namedError<\n // default to never to ensure the type argument is specified\n TError extends NamedError<TName> = never,\n // default to provided error name to make this type argument optional to reduce boilerplate\n TName extends ErrorName = ExtractName<TError>\n>(name: TName) {\n return (message: string, cause?: unknown): TError => {\n const error = new Error(message, { cause });\n error.name = name;\n error.stack = error.stack && cleanErrorStack(error.stack);\n // Safety: we set name above and therefore sure the type of error is correct\n return error as TError;\n };\n}\n\nexport type LegalError = NamedError<\"LegalError\">;\n/** @internal */\nexport const legalError = namedError<LegalError>(\"LegalError\");\n\nexport type LensContentValidationError = NamedError<\"LensContentValidationError\">;\n/** @internal */\nexport const lensContentValidationError = namedError<LensContentValidationError>(\"LensContentValidationError\");\n\nexport type LensError = NamedError<\"LensError\">;\n/** @internal */\nexport const lensError = namedError<LensError>(\"LensError\");\n\nexport type CameraKitSourceError = NamedError<\"CameraKitSourceError\">;\n/** @internal */\nexport const cameraKitSourceError = namedError<CameraKitSourceError>(\"CameraKitSourceError\");\n\n/**\n * The error triggered when a lens prompts the user to select an image, but the image fails to be successfully delivered\n * to the lens.\n */\nexport type LensImagePickerError = NamedError<\"LensImagePickerError\">;\n/** @internal */\nexport const lensImagePickerError = namedError<LensImagePickerError>(\"LensImagePickerError\");\n\nexport type CacheKeyNotFoundError = NamedError<\"CacheKeyNotFoundError\">;\n/** @internal */\nexport const cacheKeyNotFoundError = namedError<CacheKeyNotFoundError>(\"CacheKeyNotFoundError\");\n\n/**\n * Thrown by {@link bootstrapCameraKit} if provided configuration is invalid.\n *\n * @category Bootstrapping and Configuration\n */\nexport type ConfigurationError = NamedError<\"ConfigurationError\">;\n/** @internal */\nexport const configurationError = namedError<ConfigurationError>(\"ConfigurationError\");\n\nexport type WebGLError = NamedError<\"WebGLError\">;\n/** @internal */\nexport const webGLError = namedError<WebGLError>(\"WebGLError\");\n\nexport type BenchmarkError = NamedError<\"BenchmarkError\">;\n/** @internal */\nexport const benchmarkError = namedError<BenchmarkError>(\"BenchmarkError\");\n\n/**\n * Thrown by {@link bootstrapCameraKit} when the current platform is not supported by CameraKit.\n *\n * This can happen if the browser doesn't support a required feature (e.g. WebGL).\n *\n * @category Bootstrapping and Configuration\n */\nexport type PlatformNotSupportedError = NamedError<\"PlatformNotSupportedError\">;\n/** @internal */\nexport const platformNotSupportedError = namedError<PlatformNotSupportedError>(\"PlatformNotSupportedError\");\n\n/**\n * This error occurs if a Lens is unable to continue rendering.\n *\n * If this error occurs, Camera Kit automatically removes the Lens from the session.\n * It's always a good idea to handle this error and update the user experience accordingly.\n * For example, you could remove the faulty Lens from your Lens selection UI.\n *\n * ```ts\n * cameraKitSession.events.addEventListener('error', ({ detail }) => {\n * if (detail.error.name === 'LensExecutionError') {\n * console.log(`Lens ${detail.lens.name} encountered an error and was removed. Please pick a different lens.`)\n * }\n * })\n * ```\n */\nexport type LensExecutionError = NamedError<\"LensExecutionError\">;\n/** @internal */\nexport const lensExecutionError = namedError<LensExecutionError>(\"LensExecutionError\");\n\n/**\n * This error occurs when a session becomes inoperable.\n *\n * It's always a good idea to handle this error and update the user experience accordingly.\n * For example, you could show a message to a user.\n *\n * ```ts\n * cameraKitSession.events.addEventListener('error', ({ detail }) => {\n * if (detail.error.name === 'LensAbortError') {\n * console.log(`Camera Kit encountered an unrecoverable error and became inoperable. Please refresh the page.`)\n * }\n * })\n * ```\n */\nexport type LensAbortError = NamedError<\"LensAbortError\">;\n/** @internal */\nexport const lensAbortError = namedError<LensAbortError>(\"LensAbortError\");\n\n/**\n * Error thrown when LensCore asked to store lens data, but CameraKit failed storing that.\n */\nexport type PersistentStoreError = NamedError<\"PersistentStoreError\">;\n/** @internal */\nexport const persistentStoreError = namedError<PersistentStoreError>(\"PersistentStoreError\");\n\n/**\n * Error thrown when LensCore asked to provide an asset, but CameraKit failed providing that.\n */\nexport type LensAssetError = NamedError<\"LensAssetError\">;\n/** @internal */\nexport const lensAssetError = namedError<LensAssetError>(\"LensAssetError\");\n\n/**\n * Thrown by {@link bootstrapCameraKit} if an error occurs during SDK initializion or while downloading the render\n * engine WebAssembly.\n *\n * @category Bootstrapping and Configuration\n */\nexport type BootstrapError = NamedError<\"BootstrapError\">;\n/** @internal */\nexport const bootstrapError = namedError<BootstrapError>(\"BootstrapError\");\n"]}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { __awaiter } from "tslib";
|
|
2
|
+
import { getPlatformCapabilities } from "./platformCapabilities";
|
|
3
|
+
/**
|
|
4
|
+
* Throw if the current platform is not capable of running Camera Kit.
|
|
5
|
+
*/
|
|
6
|
+
export function assertPlatformSupported() {
|
|
7
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
8
|
+
const { wasm, webgl } = yield getPlatformCapabilities();
|
|
9
|
+
if (!wasm.supported)
|
|
10
|
+
throw wasm.error;
|
|
11
|
+
if (!webgl.supported)
|
|
12
|
+
throw webgl.error;
|
|
13
|
+
});
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=assertPlatformSupported.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"assertPlatformSupported.js","sourceRoot":"","sources":["../../src/platform/assertPlatformSupported.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AAEjE;;GAEG;AACH,MAAM,UAAgB,uBAAuB;;QACzC,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,MAAM,uBAAuB,EAAE,CAAC;QACxD,IAAI,CAAC,IAAI,CAAC,SAAS;YAAE,MAAM,IAAI,CAAC,KAAK,CAAC;QACtC,IAAI,CAAC,KAAK,CAAC,SAAS;YAAE,MAAM,KAAK,CAAC,KAAK,CAAC;IAC5C,CAAC;CAAA","sourcesContent":["import { getPlatformCapabilities } from \"./platformCapabilities\";\n\n/**\n * Throw if the current platform is not capable of running Camera Kit.\n */\nexport async function assertPlatformSupported(): Promise<void> {\n const { wasm, webgl } = await getPlatformCapabilities();\n if (!wasm.supported) throw wasm.error;\n if (!webgl.supported) throw webgl.error;\n}\n"]}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { memoize } from "../common/memoize";
|
|
2
|
+
import { getConfigurationOverrides } from "../configurationOverrides";
|
|
3
|
+
import { getPlatformInfo } from "./platformInfo";
|
|
4
|
+
/** @internal */
|
|
5
|
+
export const getCameraKitUserAgent = memoize(function getCameraKitUserAgent() {
|
|
6
|
+
var _a;
|
|
7
|
+
const { browser, deviceModel, origin, osName, osVersion, sdkShortVersion, lensCore } = getPlatformInfo();
|
|
8
|
+
// Set this to `DEBUG` manually while testing / root-causing.
|
|
9
|
+
const { userAgentFlavor } = (_a = getConfigurationOverrides()) !== null && _a !== void 0 ? _a : { userAgentFlavor: "release" };
|
|
10
|
+
const flavor = userAgentFlavor === "release" ? "" : "DEBUG ";
|
|
11
|
+
// This full string is defined here:
|
|
12
|
+
// eslint-disable-next-line max-len
|
|
13
|
+
// https://github.sc-corp.net/Snapchat/useragent/blob/9333afe7cc6ac00503ad46cb234bcf94006dff98/java/useragent/src/main/java/snapchat/client/UserAgent.java#L124
|
|
14
|
+
return (`CameraKitWeb/${sdkShortVersion} ${flavor}(${deviceModel}; ${osName} ${osVersion}) ` +
|
|
15
|
+
`${browser.brand}/${browser.version} Core/${lensCore.version} ` +
|
|
16
|
+
// We overload appId, using the origin instead of the true appId parsed from the apiToken -- we do this because
|
|
17
|
+
// origin is human-readable, and this is used to populate the appId dimension in operational metrics.
|
|
18
|
+
`AppId/${origin}`);
|
|
19
|
+
});
|
|
20
|
+
//# sourceMappingURL=cameraKitUserAgent.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cameraKitUserAgent.js","sourceRoot":"","sources":["../../src/platform/cameraKitUserAgent.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAC5C,OAAO,EAAE,yBAAyB,EAAE,MAAM,2BAA2B,CAAC;AACtE,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAEjD,gBAAgB;AAChB,MAAM,CAAC,MAAM,qBAAqB,GAAG,OAAO,CAAC,SAAS,qBAAqB;;IACvE,MAAM,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,eAAe,EAAE,QAAQ,EAAE,GAAG,eAAe,EAAE,CAAC;IAEzG,6DAA6D;IAC7D,MAAM,EAAE,eAAe,EAAE,GAAG,MAAA,yBAAyB,EAAE,mCAAI,EAAE,eAAe,EAAE,SAAS,EAAE,CAAC;IAC1F,MAAM,MAAM,GAAkB,eAAe,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC;IAE5E,oCAAoC;IACpC,mCAAmC;IACnC,+JAA+J;IAC/J,OAAO,CACH,gBAAgB,eAAe,IAAI,MAAM,IAAI,WAAW,KAAK,MAAM,IAAI,SAAS,IAAI;QACpF,GAAG,OAAO,CAAC,KAAK,IAAI,OAAO,CAAC,OAAO,SAAS,QAAQ,CAAC,OAAO,GAAG;QAC/D,+GAA+G;QAC/G,qGAAqG;QACrG,SAAS,MAAM,EAAE,CACpB,CAAC;AACN,CAAC,CAAC,CAAC","sourcesContent":["import { memoize } from \"../common/memoize\";\nimport { getConfigurationOverrides } from \"../configurationOverrides\";\nimport { getPlatformInfo } from \"./platformInfo\";\n\n/** @internal */\nexport const getCameraKitUserAgent = memoize(function getCameraKitUserAgent(): string {\n const { browser, deviceModel, origin, osName, osVersion, sdkShortVersion, lensCore } = getPlatformInfo();\n\n // Set this to `DEBUG` manually while testing / root-causing.\n const { userAgentFlavor } = getConfigurationOverrides() ?? { userAgentFlavor: \"release\" };\n const flavor: \"\" | \"DEBUG \" = userAgentFlavor === \"release\" ? \"\" : \"DEBUG \";\n\n // This full string is defined here:\n // eslint-disable-next-line max-len\n // https://github.sc-corp.net/Snapchat/useragent/blob/9333afe7cc6ac00503ad46cb234bcf94006dff98/java/useragent/src/main/java/snapchat/client/UserAgent.java#L124\n return (\n `CameraKitWeb/${sdkShortVersion} ${flavor}(${deviceModel}; ${osName} ${osVersion}) ` +\n `${browser.brand}/${browser.version} Core/${lensCore.version} ` +\n // We overload appId, using the origin instead of the true appId parsed from the apiToken -- we do this because\n // origin is human-readable, and this is used to populate the appId dimension in operational metrics.\n `AppId/${origin}`\n );\n});\n"]}
|