@snap/camera-kit 0.11.0 → 0.12.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.
Files changed (226) hide show
  1. package/README.md +242 -67
  2. package/docs/html/assets/search.js +1 -1
  3. package/docs/html/classes/CameraKit.html +3 -3
  4. package/docs/html/classes/CameraKitSession.html +3 -3
  5. package/docs/html/classes/CameraKitSource.html +3 -3
  6. package/docs/html/classes/LensPerformanceMeasurement.html +3 -3
  7. package/docs/html/classes/LensPerformanceMetrics.html +3 -3
  8. package/docs/html/classes/LensRepository.html +3 -3
  9. package/docs/html/classes/LensSources.html +3 -3
  10. package/docs/html/classes/Transform2D.html +3 -3
  11. package/docs/html/classes/TypedCustomEvent.html +3 -3
  12. package/docs/html/classes/TypedEventTarget.html +3 -3
  13. package/docs/html/functions/Injectable.html +3 -3
  14. package/docs/html/functions/bootstrapCameraKit.html +3 -3
  15. package/docs/html/functions/createExtension.html +3 -3
  16. package/docs/html/functions/createImageSource.html +3 -3
  17. package/docs/html/functions/createMediaStreamSource.html +3 -3
  18. package/docs/html/functions/createUserMediaSource.html +3 -3
  19. package/docs/html/functions/createVideoSource.html +3 -3
  20. package/docs/html/functions/estimateLensPerformance.html +3 -3
  21. package/docs/html/functions/getRequiredBootstrapURLs.html +3 -3
  22. package/docs/html/functions/lensSourcesFactory.html +3 -3
  23. package/docs/html/functions/uriHandlersFactory.html +3 -3
  24. package/docs/html/index.html +162 -46
  25. package/docs/html/interfaces/CameraKitBootstrapConfiguration.html +3 -3
  26. package/docs/html/interfaces/CameraKitSourceSubscriber.html +3 -3
  27. package/docs/html/interfaces/ComputedFrameMetrics.html +3 -3
  28. package/docs/html/interfaces/CreateSessionOptions.html +3 -3
  29. package/docs/html/interfaces/EstimatedLensPerformance.html +3 -3
  30. package/docs/html/interfaces/Lens.html +3 -3
  31. package/docs/html/interfaces/LensSource.html +3 -3
  32. package/docs/html/interfaces/MediaStreamSourceOptions.html +3 -3
  33. package/docs/html/interfaces/Preview.html +3 -3
  34. package/docs/html/interfaces/Snapcode.html +3 -3
  35. package/docs/html/interfaces/UriCancelRequest.html +3 -3
  36. package/docs/html/interfaces/UriHandler.html +3 -3
  37. package/docs/html/interfaces/UriRequest.html +10 -5
  38. package/docs/html/interfaces/UriResponse.html +3 -3
  39. package/docs/html/interfaces/VideoSourceOptions.html +3 -3
  40. package/docs/html/modules.html +4 -4
  41. package/docs/html/types/AssetLoader.html +3 -3
  42. package/docs/html/types/AssetTiming.html +3 -3
  43. package/docs/html/types/BenchmarkError.html +3 -3
  44. package/docs/html/types/BootstrapError.html +3 -3
  45. package/docs/html/types/CacheKeyNotFoundError.html +3 -3
  46. package/docs/html/types/CameraKitDeviceInfo.html +3 -3
  47. package/docs/html/types/CameraKitSessionEventListener.html +3 -3
  48. package/docs/html/types/CameraKitSessionEvents.html +3 -3
  49. package/docs/html/types/CameraKitSourceError.html +3 -3
  50. package/docs/html/types/CameraKitSourceInfo.html +3 -3
  51. package/docs/html/types/CameraKitSourceOptions.html +3 -3
  52. package/docs/html/types/ConfigurationError.html +3 -3
  53. package/docs/html/types/Keyboard.html +3 -3
  54. package/docs/html/types/KeyboardEvents.html +3 -3
  55. package/docs/html/types/LegalError.html +3 -3
  56. package/docs/html/types/LensAssetError.html +3 -3
  57. package/docs/html/types/LensContentValidationError.html +3 -3
  58. package/docs/html/types/LensError.html +3 -3
  59. package/docs/html/types/LensExecutionError.html +3 -3
  60. package/docs/html/types/LensImagePickerError.html +3 -3
  61. package/docs/html/types/LensLaunchParams.html +3 -3
  62. package/docs/html/types/LensMetricsEvents.html +3 -3
  63. package/docs/html/types/LensPerformanceCluster.html +3 -3
  64. package/docs/html/types/LensView.html +3 -3
  65. package/docs/html/types/LensWait.html +3 -3
  66. package/docs/html/types/PersistentStoreError.html +3 -3
  67. package/docs/html/types/PlatformNotSupportedError.html +3 -3
  68. package/docs/html/types/PublicContainer.html +3 -3
  69. package/docs/html/types/RenderTarget.html +3 -3
  70. package/docs/html/types/Uri.html +3 -3
  71. package/docs/html/types/UriHandlers.html +3 -3
  72. package/docs/html/types/WebGLError.html +3 -3
  73. package/docs/html/variables/extensionRequestContext.html +3 -3
  74. package/docs/md/README.md +242 -67
  75. package/docs/md/classes/CameraKit.md +1 -1
  76. package/docs/md/classes/CameraKitSession.md +1 -1
  77. package/docs/md/classes/CameraKitSource.md +1 -1
  78. package/docs/md/classes/LensPerformanceMeasurement.md +1 -1
  79. package/docs/md/classes/LensPerformanceMetrics.md +1 -1
  80. package/docs/md/classes/LensRepository.md +1 -1
  81. package/docs/md/classes/LensSources.md +1 -1
  82. package/docs/md/classes/Transform2D.md +1 -1
  83. package/docs/md/classes/TypedCustomEvent.md +1 -1
  84. package/docs/md/classes/TypedEventTarget.md +1 -1
  85. package/docs/md/interfaces/CameraKitBootstrapConfiguration.md +1 -1
  86. package/docs/md/interfaces/CameraKitSourceSubscriber.md +1 -1
  87. package/docs/md/interfaces/ComputedFrameMetrics.md +1 -1
  88. package/docs/md/interfaces/CreateSessionOptions.md +1 -1
  89. package/docs/md/interfaces/EstimatedLensPerformance.md +1 -1
  90. package/docs/md/interfaces/Lens.md +1 -1
  91. package/docs/md/interfaces/LensSource.md +1 -1
  92. package/docs/md/interfaces/MediaStreamSourceOptions.md +1 -1
  93. package/docs/md/interfaces/Preview.md +1 -1
  94. package/docs/md/interfaces/Snapcode.md +1 -1
  95. package/docs/md/interfaces/UriCancelRequest.md +1 -1
  96. package/docs/md/interfaces/UriHandler.md +1 -1
  97. package/docs/md/interfaces/UriRequest.md +8 -1
  98. package/docs/md/interfaces/UriResponse.md +1 -1
  99. package/docs/md/interfaces/VideoSourceOptions.md +1 -1
  100. package/docs/md/modules.md +2 -2
  101. package/lib/CameraKit.d.ts +16 -6
  102. package/lib/assertPlatformSupported.d.ts +3 -1
  103. package/lib/assertPlatformSupported.js +13 -2
  104. package/lib/assertPlatformSupported.js.map +1 -1
  105. package/lib/bootstrapCameraKit.js +2 -0
  106. package/lib/bootstrapCameraKit.js.map +1 -1
  107. package/lib/common/cameraKitUserAgent.js +17 -2
  108. package/lib/common/cameraKitUserAgent.js.map +1 -1
  109. package/lib/common/dialog.d.ts +43 -0
  110. package/lib/common/dialog.js +26 -12
  111. package/lib/common/dialog.js.map +1 -1
  112. package/lib/configuration.d.ts +2 -0
  113. package/lib/configuration.js +1 -0
  114. package/lib/configuration.js.map +1 -1
  115. package/lib/dependency-injection/RootServices.d.ts +2 -0
  116. package/lib/dependency-injection/RootServices.js.map +1 -1
  117. package/lib/environment.json +1 -1
  118. package/lib/generated-proto/blizzard/cameraKitEvents.js.map +1 -1
  119. package/lib/generated-proto/pb_schema/camera_kit/v3/business_events.d.ts +0 -26
  120. package/lib/generated-proto/pb_schema/camera_kit/v3/business_events.js +0 -15
  121. package/lib/generated-proto/pb_schema/camera_kit/v3/business_events.js.map +1 -1
  122. package/lib/generated-proto/pb_schema/camera_kit/v3/export.d.ts +0 -59
  123. package/lib/generated-proto/pb_schema/camera_kit/v3/export.js +0 -10
  124. package/lib/generated-proto/pb_schema/camera_kit/v3/export.js.map +1 -1
  125. package/lib/generated-proto/pb_schema/camera_kit/v3/legal_prompt.d.ts +0 -13
  126. package/lib/generated-proto/pb_schema/camera_kit/v3/legal_prompt.js +0 -7
  127. package/lib/generated-proto/pb_schema/camera_kit/v3/legal_prompt.js.map +1 -1
  128. package/lib/generated-proto/pb_schema/camera_kit/v3/lens.d.ts +0 -55
  129. package/lib/generated-proto/pb_schema/camera_kit/v3/lens.js +0 -12
  130. package/lib/generated-proto/pb_schema/camera_kit/v3/lens.js.map +1 -1
  131. package/lib/generated-proto/pb_schema/camera_kit/v3/operational_metrics.d.ts +0 -5
  132. package/lib/generated-proto/pb_schema/camera_kit/v3/operational_metrics.js +0 -7
  133. package/lib/generated-proto/pb_schema/camera_kit/v3/operational_metrics.js.map +1 -1
  134. package/lib/generated-proto/pb_schema/camera_kit/v3/ranking.d.ts +0 -23
  135. package/lib/generated-proto/pb_schema/camera_kit/v3/ranking.js +0 -15
  136. package/lib/generated-proto/pb_schema/camera_kit/v3/ranking.js.map +1 -1
  137. package/lib/generated-proto/pb_schema/camera_kit/v3/service.d.ts +0 -62
  138. package/lib/generated-proto/pb_schema/camera_kit/v3/service.js +0 -1
  139. package/lib/generated-proto/pb_schema/camera_kit/v3/service.js.map +1 -1
  140. package/lib/generated-proto/pb_schema/cdp/cof/benchmark.d.ts +0 -8
  141. package/lib/generated-proto/pb_schema/cdp/cof/benchmark.js +0 -1
  142. package/lib/generated-proto/pb_schema/cdp/cof/benchmark.js.map +1 -1
  143. package/lib/generated-proto/pb_schema/cdp/cof/benchmark_name.d.ts +0 -45
  144. package/lib/generated-proto/pb_schema/cdp/cof/benchmark_name.js +0 -46
  145. package/lib/generated-proto/pb_schema/cdp/cof/benchmark_name.js.map +1 -1
  146. package/lib/generated-proto/pb_schema/cdp/cof/circumstance_service.d.ts +0 -104
  147. package/lib/generated-proto/pb_schema/cdp/cof/circumstance_service.js +0 -1
  148. package/lib/generated-proto/pb_schema/cdp/cof/circumstance_service.js.map +1 -1
  149. package/lib/generated-proto/pb_schema/cdp/cof/config_request.d.ts +0 -129
  150. package/lib/generated-proto/pb_schema/cdp/cof/config_request.js +0 -24
  151. package/lib/generated-proto/pb_schema/cdp/cof/config_request.js.map +1 -1
  152. package/lib/generated-proto/pb_schema/cdp/cof/config_response.d.ts +0 -22
  153. package/lib/generated-proto/pb_schema/cdp/cof/config_response.js +0 -1
  154. package/lib/generated-proto/pb_schema/cdp/cof/config_response.js.map +1 -1
  155. package/lib/generated-proto/pb_schema/cdp/cof/config_result.d.ts +0 -510
  156. package/lib/generated-proto/pb_schema/cdp/cof/config_result.js +0 -415
  157. package/lib/generated-proto/pb_schema/cdp/cof/config_result.js.map +1 -1
  158. package/lib/generated-proto/pb_schema/cdp/cof/debug_info.d.ts +0 -9
  159. package/lib/generated-proto/pb_schema/cdp/cof/debug_info.js +0 -3
  160. package/lib/generated-proto/pb_schema/cdp/cof/debug_info.js.map +1 -1
  161. package/lib/generated-proto/pb_schema/cdp/cof/namespace.d.ts +0 -1
  162. package/lib/generated-proto/pb_schema/cdp/cof/namespace.js +0 -2
  163. package/lib/generated-proto/pb_schema/cdp/cof/namespace.js.map +1 -1
  164. package/lib/generated-proto/pb_schema/common/ruid.d.ts +0 -27
  165. package/lib/generated-proto/pb_schema/common/ruid.js +0 -20
  166. package/lib/generated-proto/pb_schema/common/ruid.js.map +1 -1
  167. package/lib/generated-proto/pb_schema/common/value.d.ts +0 -9
  168. package/lib/generated-proto/pb_schema/common/value.js +0 -1
  169. package/lib/generated-proto/pb_schema/common/value.js.map +1 -1
  170. package/lib/generated-proto/pb_schema/google/protobuf/any.d.ts +0 -105
  171. package/lib/generated-proto/pb_schema/google/protobuf/any.js +0 -1
  172. package/lib/generated-proto/pb_schema/google/protobuf/any.js.map +1 -1
  173. package/lib/generated-proto/pb_schema/google/protobuf/timestamp.d.ts +0 -64
  174. package/lib/generated-proto/pb_schema/google/protobuf/timestamp.js +0 -1
  175. package/lib/generated-proto/pb_schema/google/protobuf/timestamp.js.map +1 -1
  176. package/lib/generated-proto/pb_schema/google/protobuf/wrappers.d.ts +0 -54
  177. package/lib/generated-proto/pb_schema/google/protobuf/wrappers.js +0 -1
  178. package/lib/generated-proto/pb_schema/google/protobuf/wrappers.js.map +1 -1
  179. package/lib/generated-proto/pb_schema/lenses/geocircle.js +0 -1
  180. package/lib/generated-proto/pb_schema/lenses/geocircle.js.map +1 -1
  181. package/lib/generated-proto/pb_schema/lenses/geopoint.js +0 -1
  182. package/lib/generated-proto/pb_schema/lenses/geopoint.js.map +1 -1
  183. package/lib/generated-proto/pb_schema/lenses/launch_params.js +0 -1
  184. package/lib/generated-proto/pb_schema/lenses/launch_params.js.map +1 -1
  185. package/lib/generated-proto/pb_schema/lenses/launchdata.d.ts +0 -2
  186. package/lib/generated-proto/pb_schema/lenses/launchdata.js +0 -3
  187. package/lib/generated-proto/pb_schema/lenses/launchdata.js.map +1 -1
  188. package/lib/generated-proto/pb_schema/lenses/lures.d.ts +0 -2
  189. package/lib/generated-proto/pb_schema/lenses/lures.js +0 -1
  190. package/lib/generated-proto/pb_schema/lenses/lures.js.map +1 -1
  191. package/lib/generated-proto/pb_schema/lenses/persistent_store.js +0 -1
  192. package/lib/generated-proto/pb_schema/lenses/persistent_store.js.map +1 -1
  193. package/lib/generated-proto/pb_schema/lenses/snappable.d.ts +0 -19
  194. package/lib/generated-proto/pb_schema/lenses/snappable.js +0 -2
  195. package/lib/generated-proto/pb_schema/lenses/snappable.js.map +1 -1
  196. package/lib/generated-proto/pb_schema/lenses/user_data.d.ts +0 -18
  197. package/lib/generated-proto/pb_schema/lenses/user_data.js +0 -1
  198. package/lib/generated-proto/pb_schema/lenses/user_data.js.map +1 -1
  199. package/lib/legal/legalPrompt.js +29 -27
  200. package/lib/legal/legalPrompt.js.map +1 -1
  201. package/lib/lens/LensRepository.d.ts +5 -3
  202. package/lib/lens/LensRepository.js +8 -5
  203. package/lib/lens/LensRepository.js.map +1 -1
  204. package/lib/lens/assets/LensAssetsProvider.js +18 -3
  205. package/lib/lens/assets/LensAssetsProvider.js.map +1 -1
  206. package/lib/lens/lensHttpUtil.d.ts +3 -2
  207. package/lib/lens/lensHttpUtil.js +5 -5
  208. package/lib/lens/lensHttpUtil.js.map +1 -1
  209. package/lib/lens-core-module/generated-types.d.ts +21 -0
  210. package/lib/lens-core-module/generated-types.js.map +1 -1
  211. package/lib/lensCoreWasmVersions.json +3 -3
  212. package/lib/media-sources/MediaStreamSource.js +4 -0
  213. package/lib/media-sources/MediaStreamSource.js.map +1 -1
  214. package/lib/metrics/businessEventsReporter.d.ts +3 -2
  215. package/lib/metrics/businessEventsReporter.js +13 -7
  216. package/lib/metrics/businessEventsReporter.js.map +1 -1
  217. package/lib/metrics/operational/operationalMetricsReporter.d.ts +3 -2
  218. package/lib/metrics/operational/operationalMetricsReporter.js +8 -6
  219. package/lib/metrics/operational/operationalMetricsReporter.js.map +1 -1
  220. package/lib/remote-configuration/cofHandler.d.ts +10 -6
  221. package/lib/remote-configuration/cofHandler.js +77 -67
  222. package/lib/remote-configuration/cofHandler.js.map +1 -1
  223. package/lib/remote-configuration/remoteConfiguration.d.ts +9 -6
  224. package/lib/remote-configuration/remoteConfiguration.js +5 -13
  225. package/lib/remote-configuration/remoteConfiguration.js.map +1 -1
  226. package/package.json +1 -1
@@ -130,13 +130,23 @@ export declare const cameraKitFactory: {
130
130
  token: "cameraKitServiceFetchHandler";
131
131
  dependencies: readonly ["configuration", "defaultFetchHandler"];
132
132
  }, {
133
- (args_0: import("./configuration").CameraKitConfiguration, args_1: import("./handlers/requestStateEmittingHandler").RequestStateEventTarget, args_2: import("./metrics/operational/operationalMetricsReporter").OperationalMetricsReporter, args_3: import("./handlers").FetchHandler): import("./remote-configuration/remoteConfiguration").RemoteConfiguration;
133
+ (args_0: import("./configuration").CameraKitConfiguration, args_1: import("./handlers/requestStateEmittingHandler").RequestStateEventTarget, args_2: import("./metrics/operational/operationalMetricsReporter").OperationalMetricsReporter): import("./handlers/HandlerChainBuilder").Handler<Partial<import("./generated-proto/pb_schema/cdp/cof/config_request").ConfigTargetingRequest>, import("./generated-proto/pb_schema/cdp/cof/config_response").ConfigTargetingResponse, import("./remote-configuration/cofHandler").Metadata & {
134
+ signal?: AbortSignal | null | undefined;
135
+ isSideEffect?: boolean | undefined;
136
+ }>;
137
+ token: "cofHandler";
138
+ dependencies: readonly ["configuration", "requestStateEventTarget", "operationalMetricsReporter"];
139
+ }, {
140
+ (args_0: import("./configuration").CameraKitConfiguration, args_1: import("./handlers/HandlerChainBuilder").Handler<Partial<import("./generated-proto/pb_schema/cdp/cof/config_request").ConfigTargetingRequest>, import("./generated-proto/pb_schema/cdp/cof/config_response").ConfigTargetingResponse, import("./remote-configuration/cofHandler").Metadata & {
141
+ signal?: AbortSignal | null | undefined;
142
+ isSideEffect?: boolean | undefined;
143
+ }>, args_2: import("./handlers").FetchHandler): import("./remote-configuration/remoteConfiguration").RemoteConfiguration;
134
144
  token: "remoteConfiguration";
135
- dependencies: readonly ["configuration", "requestStateEventTarget", "operationalMetricsReporter", "cameraKitServiceFetchHandler"];
145
+ dependencies: readonly ["configuration", "cofHandler", "cameraKitServiceFetchHandler"];
136
146
  }, {
137
- (args_0: import("./handlers/requestStateEmittingHandler").RequestStateEventTarget, args_1: import("./handlers").FetchHandler, args_2: import("./handlers").FetchHandler, args_3: import("./lens").LensSources, args_4: import("./lens").LensAssetRepository): LensRepository;
147
+ (args_0: import("./handlers/requestStateEmittingHandler").RequestStateEventTarget, args_1: import("./handlers").FetchHandler, args_2: import("./handlers").FetchHandler, args_3: import("./lens").LensSources, args_4: import("./lens").LensAssetRepository, args_5: import("./configuration").CameraKitConfiguration): LensRepository;
138
148
  token: "LensRepository";
139
- dependencies: readonly ["requestStateEventTarget", "cameraKitServiceFetchHandler", "defaultFetchHandler", "lensSources", "lensAssetRepository"];
149
+ dependencies: readonly ["requestStateEventTarget", "cameraKitServiceFetchHandler", "defaultFetchHandler", "lensSources", "lensAssetRepository", "configuration"];
140
150
  }, {
141
151
  (args_0: LensCoreModule): import("./persistence/IndexedDBPersistence").IndexedDBPersistence<ArrayBuffer>;
142
152
  token: "lensPersistenceStore";
@@ -146,9 +156,9 @@ export declare const cameraKitFactory: {
146
156
  token: "metricsHandler";
147
157
  dependencies: readonly ["cameraKitServiceFetchHandler", "pageVisibility"];
148
158
  }, {
149
- (args_0: import("./handlers").FetchHandler, args_1: PageVisibility): import("./metrics/operational/operationalMetricsReporter").OperationalMetricsReporter;
159
+ (args_0: import("./handlers").FetchHandler, args_1: PageVisibility, args_2: import("./configuration").CameraKitConfiguration): import("./metrics/operational/operationalMetricsReporter").OperationalMetricsReporter;
150
160
  token: "operationalMetricsReporter";
151
- dependencies: readonly ["metricsHandler", "pageVisibility"];
161
+ dependencies: readonly ["metricsHandler", "pageVisibility", "configuration"];
152
162
  }, {
153
163
  (args_0: LensCoreModule, args_1: import("./lens").AssetLoader, args_2: import("./lens").AssetLoader, args_3: import("./lens").AssetLoader, args_4: MetricsEventTarget, args_5: import("./handlers/requestStateEmittingHandler").RequestStateEventTarget): import("./lens").LensAssetRepository;
154
164
  token: "lensAssetRepository";
@@ -1,4 +1,6 @@
1
1
  /**
2
- * Assert current platform is supported.
2
+ * Assert that the current platform supports the necessary WebGL features.
3
+ * Specifically, it checks for WebGL or WebGL2 support and ensures that
4
+ * the maximum texture size is at least 1024.
3
5
  */
4
6
  export declare function assertPlatformSupported(): void;
@@ -1,10 +1,21 @@
1
1
  import { assert } from "./common/assertions";
2
2
  import { platformNotSupportedError } from "./namedErrors";
3
+ const minTextureSize = 1024;
3
4
  /**
4
- * Assert current platform is supported.
5
+ * Assert that the current platform supports the necessary WebGL features.
6
+ * Specifically, it checks for WebGL or WebGL2 support and ensures that
7
+ * the maximum texture size is at least 1024.
5
8
  */
6
9
  export function assertPlatformSupported() {
7
10
  const canvas = document.createElement("canvas");
8
- assert(!!canvas.getContext("webgl2") || !!canvas.getContext("webgl"), platformNotSupportedError("Camera Kit cannot be bootstrapped because the browser does not support WebGL canvas rendering context."));
11
+ const webglContext = canvas.getContext("webgl2") || canvas.getContext("webgl");
12
+ const maxTextureSize = webglContext === null || webglContext === void 0 ? void 0 : webglContext.getParameter(webglContext.MAX_TEXTURE_SIZE);
13
+ assert(!!webglContext, platformNotSupportedError("Camera Kit cannot be bootstrapped because the browser does not support WebGL canvas rendering context."));
14
+ // Assert that the maximum texture size supported by WebGL is at least 1024.
15
+ // This is based on the information available at https://web3dsurvey.com/webgl/parameters/MAX_TEXTURE_SIZE
16
+ // and ensures that the application avoids future errors due to incompatibility with smaller texture sizes.
17
+ assert(maxTextureSize >= minTextureSize, platformNotSupportedError(
18
+ // eslint-disable-next-line max-len
19
+ `Camera Kit cannot be bootstrapped because this browser's WebGL MAX_TEXTURE_SIZE is ${maxTextureSize}, which is below the minimum requirement of ${minTextureSize}.`));
9
20
  }
10
21
  //# sourceMappingURL=assertPlatformSupported.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"assertPlatformSupported.js","sourceRoot":"","sources":["../src/assertPlatformSupported.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAC7C,OAAO,EAAE,yBAAyB,EAAE,MAAM,eAAe,CAAC;AAE1D;;GAEG;AACH,MAAM,UAAU,uBAAuB;IACnC,MAAM,MAAM,GAAG,QAAQ,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;IAChD,MAAM,CACF,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC,OAAO,CAAC,EAC7D,yBAAyB,CACrB,wGAAwG,CAC3G,CACJ,CAAC;AACN,CAAC","sourcesContent":["import { assert } from \"./common/assertions\";\nimport { platformNotSupportedError } from \"./namedErrors\";\n\n/**\n * Assert current platform is supported.\n */\nexport function assertPlatformSupported() {\n const canvas = document.createElement(\"canvas\");\n assert(\n !!canvas.getContext(\"webgl2\") || !!canvas.getContext(\"webgl\"),\n platformNotSupportedError(\n \"Camera Kit cannot be bootstrapped because the browser does not support WebGL canvas rendering context.\"\n )\n );\n}\n"]}
1
+ {"version":3,"file":"assertPlatformSupported.js","sourceRoot":"","sources":["../src/assertPlatformSupported.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAC7C,OAAO,EAAE,yBAAyB,EAAE,MAAM,eAAe,CAAC;AAE1D,MAAM,cAAc,GAAG,IAAI,CAAC;AAE5B;;;;GAIG;AACH,MAAM,UAAU,uBAAuB;IACnC,MAAM,MAAM,GAAG,QAAQ,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;IAChD,MAAM,YAAY,GAAG,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,IAAI,MAAM,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;IAC/E,MAAM,cAAc,GAAG,YAAY,aAAZ,YAAY,uBAAZ,YAAY,CAAE,YAAY,CAAC,YAAY,CAAC,gBAAgB,CAAC,CAAC;IAEjF,MAAM,CACF,CAAC,CAAC,YAAY,EACd,yBAAyB,CACrB,wGAAwG,CAC3G,CACJ,CAAC;IAEF,4EAA4E;IAC5E,0GAA0G;IAC1G,2GAA2G;IAC3G,MAAM,CACF,cAAc,IAAI,cAAc,EAChC,yBAAyB;IACrB,mCAAmC;IACnC,sFAAsF,cAAc,+CAA+C,cAAc,GAAG,CACvK,CACJ,CAAC;AACN,CAAC","sourcesContent":["import { assert } from \"./common/assertions\";\nimport { platformNotSupportedError } from \"./namedErrors\";\n\nconst minTextureSize = 1024;\n\n/**\n * Assert that the current platform supports the necessary WebGL features.\n * Specifically, it checks for WebGL or WebGL2 support and ensures that\n * the maximum texture size is at least 1024.\n */\nexport function assertPlatformSupported() {\n const canvas = document.createElement(\"canvas\");\n const webglContext = canvas.getContext(\"webgl2\") || canvas.getContext(\"webgl\");\n const maxTextureSize = webglContext?.getParameter(webglContext.MAX_TEXTURE_SIZE);\n\n assert(\n !!webglContext,\n platformNotSupportedError(\n \"Camera Kit cannot be bootstrapped because the browser does not support WebGL canvas rendering context.\"\n )\n );\n\n // Assert that the maximum texture size supported by WebGL is at least 1024.\n // This is based on the information available at https://web3dsurvey.com/webgl/parameters/MAX_TEXTURE_SIZE\n // and ensures that the application avoids future errors due to incompatibility with smaller texture sizes.\n assert(\n maxTextureSize >= minTextureSize,\n platformNotSupportedError(\n // eslint-disable-next-line max-len\n `Camera Kit cannot be bootstrapped because this browser's WebGL MAX_TEXTURE_SIZE is ${maxTextureSize}, which is below the minimum requirement of ${minTextureSize}.`\n )\n );\n}\n"]}
@@ -33,6 +33,7 @@ import { reportGlobalException } from "./metrics/reporters/reportGlobalException
33
33
  import { registerLogEntriesSubscriber } from "./logger/registerLogEntriesSubscriber";
34
34
  import { requestStateEventTargetFactory } from "./handlers/requestStateEmittingHandler";
35
35
  import { pageVisibilityFactory } from "./common/pageVisibility";
36
+ import { cofHandlerFactory } from "./remote-configuration/cofHandler";
36
37
  const logger = getLogger("bootstrapCameraKit");
37
38
  // The following errors are not wrapped with BootstrapError and bubble up as is.
38
39
  const nonWrappableErrors = [
@@ -133,6 +134,7 @@ export function bootstrapCameraKit(configuration, provide) {
133
134
  const lensCore = yield telemetryContainer.provides(lensCoreFactory).get(lensCoreFactory.token);
134
135
  const container = telemetryContainer
135
136
  .provides(Injectable(lensCoreFactory.token, () => lensCore))
137
+ .provides(cofHandlerFactory)
136
138
  .provides(remoteConfigurationFactory)
137
139
  .provides(lensPersistenceStoreFactory)
138
140
  .provides(deviceDependentAssetLoaderFactory)
@@ -1 +1 @@
1
- {"version":3,"file":"bootstrapCameraKit.js","sourceRoot":"","sources":["../src/bootstrapCameraKit.ts"],"names":[],"mappings":"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","sourcesContent":["import { lensRepositoryFactory } from \"./lens/LensRepository\";\nimport { Container } from \"./dependency-injection/Container\";\nimport { CameraKit, cameraKitFactory } from \"./CameraKit\";\nimport { lensCoreFactory } from \"./lens-core-module/loader/lensCoreFactory\";\nimport { Injectable } from \"./dependency-injection/Injectable\";\nimport { remoteMediaAssetLoaderFactory } from \"./lens/assets/remoteMediaAssetLoaderFactory\";\nimport { deviceDependentAssetLoaderFactory } from \"./lens/assets/deviceDependentAssetLoader\";\nimport { staticAssetLoaderFactory } from \"./lens/assets/staticAssetLoader\";\nimport { defaultFetchHandlerFactory } from \"./handlers/defaultFetchHandler\";\nimport { cameraKitServiceFetchHandlerFactory } from \"./handlers/cameraKitServiceFetchHandlerFactory\";\nimport { CameraKitBootstrapConfiguration, createCameraKitConfigurationFactory } from \"./configuration\";\nimport { PublicServices } from \"./dependency-injection/RootServices\";\nimport { PartialContainer } from \"./dependency-injection/PartialContainer\";\nimport { metricsHandlerFactory } from \"./metrics/metricsHandler\";\nimport { operationalMetricReporterFactory } from \"./metrics/operational/operationalMetricsReporter\";\nimport { lensSourcesFactory } from \"./extensions/LensSources\";\nimport { uriHandlersFactory } from \"./extensions/UriHandlers\";\nimport { assert } from \"./common/assertions\";\nimport { isSafeString } from \"./common/typeguards\";\nimport { metricsEventTargetFactory } from \"./metrics/metricsEventTarget\";\nimport { reportGloballyScopedMetrics } from \"./metrics/reporters/reporters\";\nimport { getLogger } from \"./logger/logger\";\nimport { logEntriesFactory } from \"./logger/logEntries\";\nimport { assertPlatformSupported } from \"./assertPlatformSupported\";\nimport { lensPersistenceStoreFactory } from \"./lens/LensPersistenceStore\";\nimport { remoteConfigurationFactory } from \"./remote-configuration/remoteConfiguration\";\nimport { lensAssetRepositoryFactory } from \"./lens/assets/LensAssetRepository\";\nimport { legalStateFactory } from \"./legal/legalState\";\nimport { legalPromptFactory } from \"./legal/legalPrompt\";\nimport { bootstrapError, ConfigurationError, configurationError, PlatformNotSupportedError } from \"./namedErrors\";\nimport { businessEventsReporterFactory } from \"./metrics/businessEventsReporter\";\nimport { reportGlobalException } from \"./metrics/reporters/reportGlobalException\";\nimport { registerLogEntriesSubscriber } from \"./logger/registerLogEntriesSubscriber\";\nimport { requestStateEventTargetFactory } from \"./handlers/requestStateEmittingHandler\";\nimport { pageVisibilityFactory } from \"./common/pageVisibility\";\n\nconst logger = getLogger(\"bootstrapCameraKit\");\n\n// The following errors are not wrapped with BootstrapError and bubble up as is.\nconst nonWrappableErrors: [ConfigurationError[\"name\"], PlatformNotSupportedError[\"name\"]] = [\n \"ConfigurationError\",\n \"PlatformNotSupportedError\",\n];\n\n/**\n * Returns true if given error has to be wrapped with BoostrapError.\n */\nfunction shouldWrapError(error: unknown): boolean {\n if (error instanceof Error) {\n return !nonWrappableErrors.some((name) => error.name === name);\n }\n return true;\n}\n\n/**\n * For more advanced use-cases, this DI Container holds services for which a custom implementation may be provided by\n * the application.\n *\n * @category Bootstrapping and Configuration\n */\nexport type PublicContainer = Container<PublicServices>;\n\n/**\n * Bootstrap CameraKit. This will download the WebAssembly code which powers CameraKit's rendering engine, and return\n * an instance of {@link CameraKit}.\n *\n * CameraKit must be provided with some configuration (the application's API token), and there are some additional\n * configurations which are optional.\n *\n * Descriptions of the available configurations can be found in the documentation for\n * {@link CameraKitBootstrapConfiguration}\n *\n * ---\n *\n * There is also a second, more advanced way to modify CameraKit to provide greater flexibility to support less common\n * use cases.\n *\n * This requires some knowledge of CameraKit's dependency injection system, and allows applications to provide their\n * own custom implementations of certain CameraKit components. This functionality will only be needed by applications\n * with very specific, more advanced requirements.\n *\n * @example\n * ```ts\n * // The most common way to bootstrap:\n * const cameraKit = await bootstrapCameraKit({ apiToken: myApiToken })\n *\n * // For special advanced use-cases, it is possible to provide custom implementations for certain CameraKit components.\n * const cameraKit = await bootstrapCameraKit(config, (container) => {\n * return container.provides(myCustomRemoteMediaAssetLoaderFactory)\n * })\n * ```\n *\n * @param configuration Configure CameraKit with e.g. credentials, global resource endpoints, etc.\n * @param provide Optional function that can make modifications to CameraKit's root DI container.\n * @returns A {@link CameraKit} instance, which is the entry point to CameraKit's API.\n *\n * @throws\n * - {@link ConfigurationError} when provided configuration object is invalid\n * - {@link PlatformNotSupportedError} when current platform is not supported by CameraKit\n * - {@link BootstrapError} when a failure occurs while initializing CameraKit and downloading the render engine\n * WebAssembly binary.\n *\n * @category Bootstrapping and Configuration\n */\nexport async function bootstrapCameraKit(\n configuration: CameraKitBootstrapConfiguration,\n provide?: (c: PublicContainer) => PublicContainer\n): Promise<CameraKit> {\n try {\n const startTimeMs = performance.now();\n\n assert(isSafeString(configuration.apiToken), configurationError(\"Invalid or unsafe apiToken provided.\"));\n\n const configurationFactory = createCameraKitConfigurationFactory(configuration);\n\n // Public container holds services which applications can overwrite with their own implementations.\n const defaultPublicContainer = Container.provides(configurationFactory)\n .provides(pageVisibilityFactory)\n .provides(defaultFetchHandlerFactory)\n .provides(remoteMediaAssetLoaderFactory)\n .provides(lensSourcesFactory)\n .provides(uriHandlersFactory);\n\n const publicContainer = provide ? provide(defaultPublicContainer) : defaultPublicContainer;\n\n // Now that the client's provide() function has completed and the configuration override is ready,\n // we create another container to initialize the logger. This ensures that logging is available\n // as we continue bootstrapping. We don't initialize the logger as part of the defaultPublicContainer\n // because we don't want applications to provide their own logger implementations,\n // and we're not interested in errors thrown by their provide() function.\n // Below is the minimum required container to report errors to Blizzard.\n const telemetryContainer = Container.provides(publicContainer)\n .provides(logEntriesFactory)\n .run(registerLogEntriesSubscriber)\n .provides(cameraKitServiceFetchHandlerFactory)\n .provides(requestStateEventTargetFactory)\n .provides(metricsEventTargetFactory)\n .provides(metricsHandlerFactory)\n .provides(operationalMetricReporterFactory)\n .provides(reportGlobalException)\n .run(businessEventsReporterFactory);\n\n // Run the exception logger so that it can subscribe to log events -- we can't use `Container.run()` because\n // reportGlobalException is also used as a dependency by other Services (and run does not provide Services,\n // it just runs them once).\n telemetryContainer.get(reportGlobalException.token);\n\n // At this point, logger is configured to report to console and Blizzard.\n\n assertPlatformSupported();\n\n // LensCore is a foundational component which must be created asynchronously.\n // But it's annoying for every consumer of LensCore to have to wait on Promise<LensCore>\n // (which means they become async themselves). So we'll create a DI container which provides Promise<LensCore>,\n // wait for that promise once here, then create a new DI container that just contains LensCore.\n const lensCore = await telemetryContainer.provides(lensCoreFactory).get(lensCoreFactory.token);\n\n const container = telemetryContainer\n .provides(Injectable(lensCoreFactory.token, () => lensCore))\n .provides(remoteConfigurationFactory)\n .provides(lensPersistenceStoreFactory)\n .provides(deviceDependentAssetLoaderFactory)\n .provides(staticAssetLoaderFactory)\n .provides(lensAssetRepositoryFactory)\n .provides(lensRepositoryFactory)\n .provides(legalPromptFactory)\n .provides(legalStateFactory)\n .provides(cameraKitFactory)\n // We'll run a PartialContainer containing reporters for globally-scoped metrics. Running this container\n // allows each metric reporter to initialize itself (e.g. by adding event listeners to detect when certain\n // actions occur). This PartialContainer also includes the service which listens to locally-reported metrics\n // and sends them to our backend.\n .run(reportGloballyScopedMetrics);\n\n const cameraKit = container.get(cameraKitFactory.token);\n\n const bootstrapTimeMs = performance.now() - startTimeMs;\n const reporter = container.get(operationalMetricReporterFactory.token);\n reporter.timer(\"bootstrap_time\", bootstrapTimeMs);\n\n return cameraKit;\n } catch (error) {\n if (shouldWrapError(error)) {\n error = bootstrapError(\"Error occurred during Camera Kit bootstrapping.\", error);\n }\n logger.error(error);\n throw error;\n }\n}\n\n/**\n * Extensions offer a way to provide custom implementations of certain parts of the CameraKit SDK.\n *\n * This enables more advanced use-cases, in which the default behavior of the SDK is substantially altered. For example,\n * replacing the default implementation that loads remote lens assets with a custom implementation that returns\n * different assets based on some business logic within the application.\n *\n * An extension is implemented as a [PartialContainer] – a collection of factory functions, each with its own\n * dependencies, which each provide some \"Service.\" A Service can be of any type, and the CameraKit SDK defines its\n * own Services, some of which can be overridden by providing a custom implementation of the type via an extension.\n *\n * Here's an example of how extensions might be used:\n * ```ts\n * import { bootstrapCameraKit, createExtension, remoteMediaAssetLoaderFactory } from '@snap/camera-kit'\n *\n * const myCustomRemoteAssetLoader = Injectable(\n * remoteMediaAssetLoaderFactory.token,\n * [remoteMediaAssetLoaderFactory.token] as const,\n * (defaultLoader: AssetLoader): AssetLoader => {\n * return async (asset, lens) => {\n * if (lens?.id === MY_SPECIAL_LENS) {\n * return (await fetch('my/asset.glb')).arrayBuffer()\n * }\n * return defaultLoader(asset, lens)\n * }\n * },\n * )\n *\n * const myExtension = createExtension().provides(myCustomeRemoteAssetLoader)\n * const cameraKit = bootstrapCameraKit(config, container => container.provides(myExtension))\n * ```\n *\n * This also enables greater modularity – the person/team creating the extension can do so in their own package, which\n * could be shared by many applications that all require the same functionality.\n *\n * @returns A {@link PartialContainer} which can be used to create a collection of Services, and can later be provided\n * to CameraKit's DI container during {@link bootstrapCameraKit}.\n *\n * @category Bootstrapping and Configuration\n */\nexport function createExtension(): PartialContainer {\n return new PartialContainer({});\n}\n"]}
1
+ {"version":3,"file":"bootstrapCameraKit.js","sourceRoot":"","sources":["../src/bootstrapCameraKit.ts"],"names":[],"mappings":"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","sourcesContent":["import { lensRepositoryFactory } from \"./lens/LensRepository\";\nimport { Container } from \"./dependency-injection/Container\";\nimport { CameraKit, cameraKitFactory } from \"./CameraKit\";\nimport { lensCoreFactory } from \"./lens-core-module/loader/lensCoreFactory\";\nimport { Injectable } from \"./dependency-injection/Injectable\";\nimport { remoteMediaAssetLoaderFactory } from \"./lens/assets/remoteMediaAssetLoaderFactory\";\nimport { deviceDependentAssetLoaderFactory } from \"./lens/assets/deviceDependentAssetLoader\";\nimport { staticAssetLoaderFactory } from \"./lens/assets/staticAssetLoader\";\nimport { defaultFetchHandlerFactory } from \"./handlers/defaultFetchHandler\";\nimport { cameraKitServiceFetchHandlerFactory } from \"./handlers/cameraKitServiceFetchHandlerFactory\";\nimport { CameraKitBootstrapConfiguration, createCameraKitConfigurationFactory } from \"./configuration\";\nimport { PublicServices } from \"./dependency-injection/RootServices\";\nimport { PartialContainer } from \"./dependency-injection/PartialContainer\";\nimport { metricsHandlerFactory } from \"./metrics/metricsHandler\";\nimport { operationalMetricReporterFactory } from \"./metrics/operational/operationalMetricsReporter\";\nimport { lensSourcesFactory } from \"./extensions/LensSources\";\nimport { uriHandlersFactory } from \"./extensions/UriHandlers\";\nimport { assert } from \"./common/assertions\";\nimport { isSafeString } from \"./common/typeguards\";\nimport { metricsEventTargetFactory } from \"./metrics/metricsEventTarget\";\nimport { reportGloballyScopedMetrics } from \"./metrics/reporters/reporters\";\nimport { getLogger } from \"./logger/logger\";\nimport { logEntriesFactory } from \"./logger/logEntries\";\nimport { assertPlatformSupported } from \"./assertPlatformSupported\";\nimport { lensPersistenceStoreFactory } from \"./lens/LensPersistenceStore\";\nimport { remoteConfigurationFactory } from \"./remote-configuration/remoteConfiguration\";\nimport { lensAssetRepositoryFactory } from \"./lens/assets/LensAssetRepository\";\nimport { legalStateFactory } from \"./legal/legalState\";\nimport { legalPromptFactory } from \"./legal/legalPrompt\";\nimport { bootstrapError, ConfigurationError, configurationError, PlatformNotSupportedError } from \"./namedErrors\";\nimport { businessEventsReporterFactory } from \"./metrics/businessEventsReporter\";\nimport { reportGlobalException } from \"./metrics/reporters/reportGlobalException\";\nimport { registerLogEntriesSubscriber } from \"./logger/registerLogEntriesSubscriber\";\nimport { requestStateEventTargetFactory } from \"./handlers/requestStateEmittingHandler\";\nimport { pageVisibilityFactory } from \"./common/pageVisibility\";\nimport { cofHandlerFactory } from \"./remote-configuration/cofHandler\";\n\nconst logger = getLogger(\"bootstrapCameraKit\");\n\n// The following errors are not wrapped with BootstrapError and bubble up as is.\nconst nonWrappableErrors: [ConfigurationError[\"name\"], PlatformNotSupportedError[\"name\"]] = [\n \"ConfigurationError\",\n \"PlatformNotSupportedError\",\n];\n\n/**\n * Returns true if given error has to be wrapped with BoostrapError.\n */\nfunction shouldWrapError(error: unknown): boolean {\n if (error instanceof Error) {\n return !nonWrappableErrors.some((name) => error.name === name);\n }\n return true;\n}\n\n/**\n * For more advanced use-cases, this DI Container holds services for which a custom implementation may be provided by\n * the application.\n *\n * @category Bootstrapping and Configuration\n */\nexport type PublicContainer = Container<PublicServices>;\n\n/**\n * Bootstrap CameraKit. This will download the WebAssembly code which powers CameraKit's rendering engine, and return\n * an instance of {@link CameraKit}.\n *\n * CameraKit must be provided with some configuration (the application's API token), and there are some additional\n * configurations which are optional.\n *\n * Descriptions of the available configurations can be found in the documentation for\n * {@link CameraKitBootstrapConfiguration}\n *\n * ---\n *\n * There is also a second, more advanced way to modify CameraKit to provide greater flexibility to support less common\n * use cases.\n *\n * This requires some knowledge of CameraKit's dependency injection system, and allows applications to provide their\n * own custom implementations of certain CameraKit components. This functionality will only be needed by applications\n * with very specific, more advanced requirements.\n *\n * @example\n * ```ts\n * // The most common way to bootstrap:\n * const cameraKit = await bootstrapCameraKit({ apiToken: myApiToken })\n *\n * // For special advanced use-cases, it is possible to provide custom implementations for certain CameraKit components.\n * const cameraKit = await bootstrapCameraKit(config, (container) => {\n * return container.provides(myCustomRemoteMediaAssetLoaderFactory)\n * })\n * ```\n *\n * @param configuration Configure CameraKit with e.g. credentials, global resource endpoints, etc.\n * @param provide Optional function that can make modifications to CameraKit's root DI container.\n * @returns A {@link CameraKit} instance, which is the entry point to CameraKit's API.\n *\n * @throws\n * - {@link ConfigurationError} when provided configuration object is invalid\n * - {@link PlatformNotSupportedError} when current platform is not supported by CameraKit\n * - {@link BootstrapError} when a failure occurs while initializing CameraKit and downloading the render engine\n * WebAssembly binary.\n *\n * @category Bootstrapping and Configuration\n */\nexport async function bootstrapCameraKit(\n configuration: CameraKitBootstrapConfiguration,\n provide?: (c: PublicContainer) => PublicContainer\n): Promise<CameraKit> {\n try {\n const startTimeMs = performance.now();\n\n assert(isSafeString(configuration.apiToken), configurationError(\"Invalid or unsafe apiToken provided.\"));\n\n const configurationFactory = createCameraKitConfigurationFactory(configuration);\n\n // Public container holds services which applications can overwrite with their own implementations.\n const defaultPublicContainer = Container.provides(configurationFactory)\n .provides(pageVisibilityFactory)\n .provides(defaultFetchHandlerFactory)\n .provides(remoteMediaAssetLoaderFactory)\n .provides(lensSourcesFactory)\n .provides(uriHandlersFactory);\n\n const publicContainer = provide ? provide(defaultPublicContainer) : defaultPublicContainer;\n\n // Now that the client's provide() function has completed and the configuration override is ready,\n // we create another container to initialize the logger. This ensures that logging is available\n // as we continue bootstrapping. We don't initialize the logger as part of the defaultPublicContainer\n // because we don't want applications to provide their own logger implementations,\n // and we're not interested in errors thrown by their provide() function.\n // Below is the minimum required container to report errors to Blizzard.\n const telemetryContainer = Container.provides(publicContainer)\n .provides(logEntriesFactory)\n .run(registerLogEntriesSubscriber)\n .provides(cameraKitServiceFetchHandlerFactory)\n .provides(requestStateEventTargetFactory)\n .provides(metricsEventTargetFactory)\n .provides(metricsHandlerFactory)\n .provides(operationalMetricReporterFactory)\n .provides(reportGlobalException)\n .run(businessEventsReporterFactory);\n\n // Run the exception logger so that it can subscribe to log events -- we can't use `Container.run()` because\n // reportGlobalException is also used as a dependency by other Services (and run does not provide Services,\n // it just runs them once).\n telemetryContainer.get(reportGlobalException.token);\n\n // At this point, logger is configured to report to console and Blizzard.\n\n assertPlatformSupported();\n\n // LensCore is a foundational component which must be created asynchronously.\n // But it's annoying for every consumer of LensCore to have to wait on Promise<LensCore>\n // (which means they become async themselves). So we'll create a DI container which provides Promise<LensCore>,\n // wait for that promise once here, then create a new DI container that just contains LensCore.\n const lensCore = await telemetryContainer.provides(lensCoreFactory).get(lensCoreFactory.token);\n\n const container = telemetryContainer\n .provides(Injectable(lensCoreFactory.token, () => lensCore))\n .provides(cofHandlerFactory)\n .provides(remoteConfigurationFactory)\n .provides(lensPersistenceStoreFactory)\n .provides(deviceDependentAssetLoaderFactory)\n .provides(staticAssetLoaderFactory)\n .provides(lensAssetRepositoryFactory)\n .provides(lensRepositoryFactory)\n .provides(legalPromptFactory)\n .provides(legalStateFactory)\n .provides(cameraKitFactory)\n // We'll run a PartialContainer containing reporters for globally-scoped metrics. Running this container\n // allows each metric reporter to initialize itself (e.g. by adding event listeners to detect when certain\n // actions occur). This PartialContainer also includes the service which listens to locally-reported metrics\n // and sends them to our backend.\n .run(reportGloballyScopedMetrics);\n\n const cameraKit = container.get(cameraKitFactory.token);\n\n const bootstrapTimeMs = performance.now() - startTimeMs;\n const reporter = container.get(operationalMetricReporterFactory.token);\n reporter.timer(\"bootstrap_time\", bootstrapTimeMs);\n\n return cameraKit;\n } catch (error) {\n if (shouldWrapError(error)) {\n error = bootstrapError(\"Error occurred during Camera Kit bootstrapping.\", error);\n }\n logger.error(error);\n throw error;\n }\n}\n\n/**\n * Extensions offer a way to provide custom implementations of certain parts of the CameraKit SDK.\n *\n * This enables more advanced use-cases, in which the default behavior of the SDK is substantially altered. For example,\n * replacing the default implementation that loads remote lens assets with a custom implementation that returns\n * different assets based on some business logic within the application.\n *\n * An extension is implemented as a [PartialContainer] – a collection of factory functions, each with its own\n * dependencies, which each provide some \"Service.\" A Service can be of any type, and the CameraKit SDK defines its\n * own Services, some of which can be overridden by providing a custom implementation of the type via an extension.\n *\n * Here's an example of how extensions might be used:\n * ```ts\n * import { bootstrapCameraKit, createExtension, remoteMediaAssetLoaderFactory } from '@snap/camera-kit'\n *\n * const myCustomRemoteAssetLoader = Injectable(\n * remoteMediaAssetLoaderFactory.token,\n * [remoteMediaAssetLoaderFactory.token] as const,\n * (defaultLoader: AssetLoader): AssetLoader => {\n * return async (asset, lens) => {\n * if (lens?.id === MY_SPECIAL_LENS) {\n * return (await fetch('my/asset.glb')).arrayBuffer()\n * }\n * return defaultLoader(asset, lens)\n * }\n * },\n * )\n *\n * const myExtension = createExtension().provides(myCustomeRemoteAssetLoader)\n * const cameraKit = bootstrapCameraKit(config, container => container.provides(myExtension))\n * ```\n *\n * This also enables greater modularity – the person/team creating the extension can do so in their own package, which\n * could be shared by many applications that all require the same functionality.\n *\n * @returns A {@link PartialContainer} which can be used to create a collection of Services, and can later be provided\n * to CameraKit's DI container during {@link bootstrapCameraKit}.\n *\n * @category Bootstrapping and Configuration\n */\nexport function createExtension(): PartialContainer {\n return new PartialContainer({});\n}\n"]}
@@ -1,6 +1,20 @@
1
1
  import environment from "../environment.json";
2
2
  import lensCoreWasm from "../lensCoreWasmVersions.json";
3
3
  import { locale } from "./locale";
4
+ import { isRecord } from "./typeguards";
5
+ /**
6
+ * Some user agents may not properly implement the NavigatorUAData interface, so we have to do our own validation here
7
+ * to make sure we're dealing with a well-formed value.
8
+ */
9
+ function isNavigatorUAData(value) {
10
+ return (isRecord(value) &&
11
+ Array.isArray(value["brands"]) &&
12
+ value["brands"].every((brand) => {
13
+ return isRecord(brand) && typeof brand["brand"] === "string" && typeof brand["version"] === "string";
14
+ }) &&
15
+ typeof value["mobile"] === "boolean" &&
16
+ typeof value["platform"] === "string");
17
+ }
4
18
  /**
5
19
  * Parse the platform (i.e. OS) version.
6
20
  *
@@ -169,11 +183,12 @@ function parseApplicationOrigin() {
169
183
  return origin;
170
184
  }
171
185
  function getCameraKitUserAgent() {
172
- const userAgent = navigator.userAgent;
186
+ var _a;
187
+ const userAgent = (_a = navigator.userAgent) !== null && _a !== void 0 ? _a : "";
173
188
  // [NavigatorUAData](https://developer.mozilla.org/en-US/docs/Web/API/NavigatorUAData) is currently only
174
189
  // available on Chromium-based browsers – it's nice because it gives us clear, well-documented information. But
175
190
  // we'll have to fallback to parsing the userAgent string when it's not available.
176
- const userAgentData = navigator.userAgentData !== undefined
191
+ const userAgentData = isNavigatorUAData(navigator.userAgentData)
177
192
  ? normalizeUserAgentData(navigator.userAgentData)
178
193
  : parseUserAgentData(userAgent);
179
194
  const platformVersion = parsePlatformVersion(userAgent);
@@ -1 +1 @@
1
- {"version":3,"file":"cameraKitUserAgent.js","sourceRoot":"","sources":["../../src/common/cameraKitUserAgent.ts"],"names":[],"mappings":"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","sourcesContent":["import environment from \"../environment.json\";\nimport lensCoreWasm from \"../lensCoreWasmVersions.json\";\nimport { locale } from \"./locale\";\n\ntype BrandArray = Array<{ brand: string; version: string }>;\n\ninterface NavigatorUAData {\n brands: BrandArray;\n mobile: boolean;\n platform: string;\n}\n\ndeclare global {\n interface Navigator {\n userAgentData?: NavigatorUAData;\n }\n}\n\n/**\n * Parse the platform (i.e. OS) version.\n *\n * From limited testing, this seems to often produce incorrect results – the userAgent string does not typically include\n * the actual OS version.\n *\n * Better results could be obtained from [NavigatorUAData.getHighEntropyValues]\n * (https://developer.mozilla.org/en-US/docs/Web/API/NavigatorUAData/getHighEntropyValues), but this presents two\n * problems: 1) it's currently only supported on Chrome and 2) browsers may prompt the user for permission to share\n * this information.\n *\n * So, at least for now, we'll be satisfied with the incorrect version number.\n */\nfunction parsePlatformVersion(userAgent: string) {\n // possible platform version values inside of user agent string\n // \" 11;\"\n // \" 10_15_7)\"\n // \" 13_5_1 \"\n // \" 10.0;\"\n // \" 15_1 \"\n const versionMatch = userAgent.match(/\\s([\\d][\\d_.]*[\\d])(;|\\)|\\s)/);\n\n if (versionMatch != null) {\n return versionMatch[1].replace(/_/g, \".\");\n }\n\n return \"\";\n}\n\n/**\n * In the future, we may invest in more robust device-detection (e.g. a UA string database), but for now this will give\n * us some sense of device usage.\n */\nfunction parseDeviceModel(userAgent: string) {\n // from user agent like \"(Linux; Android 11; Pixel 2)\" extact \"Pixel 2\"\n const userAgentWithModel = userAgent.match(/;[^;]+?;([^\\)]+?)\\)/);\n\n if (userAgentWithModel) {\n return userAgentWithModel[1].trim();\n }\n\n // from user agent like \"... (iPad; CPU OS 15_1 like Mac OS X) ...\" extract \"IPad\"\n const userAgentWithModel2 = userAgent.match(/\\(([^;]+);/);\n\n if (userAgentWithModel2) {\n return userAgentWithModel2[1].trim();\n }\n\n return \"unknown\";\n}\n\n/**\n * Some browsers (e.g. Safari) do not support the `Navigator.userAgentData` API. We'll attempt a sort of polyfill by\n * parsing the data found in [NavigatorUAData](https://developer.mozilla.org/en-US/docs/Web/API/NavigatorUAData) from\n * the raw user agent string.\n */\nfunction parseUserAgentData(userAgent: string): NavigatorUAData {\n let brand: BrandArray[number];\n\n // Parse UA string for Chromium-based browsers (e.g. Chrome, Edge)\n if (/Chrome/.test(userAgent)) {\n const versionMatch = userAgent.match(/Chrome\\/([\\d.]+)/);\n brand = {\n brand: \"Chrome\",\n version: versionMatch !== null ? versionMatch[1] : \"unknown\",\n };\n }\n\n // Parse UA string for Safari (very important for this to only be done if Chrome is not found – Chrome userAgent\n // strings will contain \"Safari\")\n else if (/Safari/.test(userAgent)) {\n let versionMatch = userAgent.match(/Version\\/([\\d.]+)/);\n if (versionMatch === null) versionMatch = userAgent.match(/Safari\\/([\\d.]+)/);\n brand = {\n brand: \"Safari\",\n version: versionMatch !== null ? versionMatch[1] : \"unknown\",\n };\n }\n\n // Parse UA for unknown browser.\n // TODO: will be changed, default value support should be added on a COF server side.\n else {\n brand = {\n brand: \"Firefox\",\n version: \"0\",\n };\n }\n\n // We're not using `mobile` for anything, and we have no consistent way to determine this from the UA string.\n // We'll set it to false, but this should not be used – instead, we'll need to rely on more sophisticated methods\n // (e.g. a userAgent database) to determine actual device.\n const mobile = false;\n const platform = parsePlaftformName(userAgent);\n\n return {\n brands: [brand],\n mobile,\n platform,\n };\n}\n\n/* eslint-disable max-len */\n/**\n * The `brands` array found in [NavigatorUAData](https://developer.mozilla.org/en-US/docs/Web/API/NavigatorUAData) is\n * intentionally designed to discourage standardized processing. This method of extracting brand information will be\n * inherently brittle, and it relies on us matching some well-known brands.\n *\n * For more detail from the spec:\n * See https://wicg.github.io/ua-client-hints/#monkeypatch-html-windoworworkerglobalscope\n * And https://wicg.github.io/ua-client-hints/#grease\n *\n * We also must match the list of known brands allowed by the backend, defined here:\n * https://github.sc-corp.net/Snapchat/useragent/blob/9333afe7cc6ac00503ad46cb234bcf94006dff98/java/useragent/src/main/java/snapchat/client/UserAgent.java#L124\n */\n/* eslint-enable */\ntype KnownBrand = \"Chrome\" | \"Safari\" | \"Firefox\";\nfunction normalizeBrands(brands: BrandArray): BrandArray {\n const knownBrands = new Map<string, KnownBrand>([\n [\"Chrome\", \"Chrome\"],\n [\"Chromium\", \"Chrome\"],\n [\"Firefox\", \"Firefox\"],\n [\"Microsoft Edge\", \"Chrome\"],\n [\"Safari\", \"Safari\"],\n ]);\n\n const normalizedBrands = brands\n .filter(({ brand }) => knownBrands.has(brand))\n .map((brand) => {\n return {\n // Safety: we've filtered out brands which do not appear as keys in `knownBrands`, so this cannot return\n // undefined.\n brand: knownBrands.get(brand.brand)!,\n version: brand.version,\n };\n });\n\n // TODO: default \"unknown\" value should be added on COF server side. For now we'll use Firefox.\n if (normalizedBrands.length === 0) return [{ brand: \"Firefox\", version: \"0\" }];\n return normalizedBrands;\n}\n\n/* eslint-disable max-len */\n/**\n * We must ensure the data we get from `navigator.userAgentData` is normalized to match what our backend expects to\n * see in our custom CameraKitWeb userAgent string.\n *\n * This string is defined here:\n * https://github.sc-corp.net/Snapchat/useragent/blob/9333afe7cc6ac00503ad46cb234bcf94006dff98/java/useragent/src/main/java/snapchat/client/UserAgent.java#L124\n */\n/* eslint-enable */\nfunction normalizeUserAgentData(userAgentData: NavigatorUAData): NavigatorUAData {\n return {\n brands: normalizeBrands(userAgentData.brands),\n mobile: userAgentData.mobile,\n platform: parsePlaftformName(userAgentData.platform),\n };\n}\n\n/* eslint-disable max-len */\n/**\n * The backend defines the allowed list of known platforms which will pass their RegEx test when found in our custom\n * CameraKitWeb userAgent string.\n *\n * See https://github.sc-corp.net/Snapchat/useragent/blob/9333afe7cc6ac00503ad46cb234bcf94006dff98/java/useragent/src/main/java/snapchat/client/UserAgent.java#L124\n */\n/* eslint-enable */\ntype KnownPlatform = \"macos\" | \"windows\" | \"linux\" | \"android\" | \"ios\" | \"ipados\" | \"unknown\";\nfunction parsePlaftformName(userAgent: string): KnownPlatform {\n const knownPlatforms = new Map<string, KnownPlatform>([\n [\"android\", \"android\"],\n [\"linux\", \"linux\"],\n [\"iphone os\", \"ios\"],\n [\"ipad\", \"ipados\"],\n [\"mac os\", \"macos\"],\n [\"macos\", \"macos\"],\n [\"windows\", \"windows\"],\n ]);\n\n const normalizedUserAgent = userAgent.toLowerCase();\n for (const [match, platform] of knownPlatforms.entries()) {\n if (normalizedUserAgent.includes(match)) return platform;\n }\n return \"unknown\";\n}\n\n/**\n * We'll use the application's origin as an identifier – this isn't used for any kind of authentication, but it may be\n * useful metadata to have in the future.\n *\n * We also need to handle cases in which the SDK is used in a child browsing context (e.g. an iframe), which may not\n * have a hostname – in this case we'll check each ancestor context until we find a valid hostname.\n */\nfunction parseApplicationOrigin(): string {\n let origin = location.hostname;\n // Firefox does not implement ancestorOrigins, so we need a fallback.\n // Context here: https://github.com/whatwg/html/issues/1918\n const ancestorOrigins =\n location.ancestorOrigins === undefined\n ? typeof window !== \"undefined\"\n ? [window.parent.origin, window.top?.origin ?? \"\"]\n : []\n : Array.from(location.ancestorOrigins ?? []);\n\n while (origin === \"\" && ancestorOrigins.length > 0) {\n // Safety: ancestorOrigins must contain at least one element, so shift() will always be defined.\n origin = new URL(ancestorOrigins.shift()!).hostname;\n }\n return origin;\n}\n\nfunction getCameraKitUserAgent(): CameraKitUserAgent {\n const userAgent = navigator.userAgent;\n // [NavigatorUAData](https://developer.mozilla.org/en-US/docs/Web/API/NavigatorUAData) is currently only\n // available on Chromium-based browsers – it's nice because it gives us clear, well-documented information. But\n // we'll have to fallback to parsing the userAgent string when it's not available.\n const userAgentData =\n navigator.userAgentData !== undefined\n ? normalizeUserAgentData(navigator.userAgentData)\n : parseUserAgentData(userAgent);\n\n const platformVersion = parsePlatformVersion(userAgent);\n const deviceModel = parseDeviceModel(userAgent);\n\n // In cases where we've parsed the userAgent string to find the brand, there will only ever be a single brand –\n // in browsers which support NavigatorUAData there could be more than one (e.g. Chrome and Chromium), but they\n // should be equivalent for our purposes.\n const browser = userAgentData.brands[0];\n const origin = parseApplicationOrigin();\n\n const sdkLongVersion = environment.PACKAGE_VERSION;\n // Remove any `-prerelease` or `+buildmetadata` portions from the semver string.\n const sdkShortVersion = sdkLongVersion.replace(/[-+]\\S+$/, \"\");\n\n // Set this to `debug` manually while testing / root-causing.\n const flavor: \"release\" | \"debug\" = \"release\";\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 const cameraKitUserAgent =\n `CameraKitWeb/${sdkShortVersion} ` +\n `${flavor === \"release\" ? \"\" : \"DEBUG\"}` +\n `(${deviceModel}; ${userAgentData.platform} ${platformVersion}) ` +\n `${browser.brand}/${browser.version} ` +\n `Core/${lensCoreWasm.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 return {\n osType: userAgentData.platform,\n osVersion: platformVersion,\n locale,\n sdkShortVersion,\n sdkLongVersion,\n flavor,\n lensCoreVersion: `${lensCoreWasm.version}`,\n deviceModel,\n browser,\n origin,\n userAgent: cameraKitUserAgent,\n };\n}\n\n/** @internal */\nexport interface CameraKitUserAgent {\n osType: string;\n osVersion: string;\n locale: string;\n sdkShortVersion: string;\n sdkLongVersion: string;\n flavor: \"release\" | \"debug\";\n lensCoreVersion: string;\n deviceModel: string;\n browser: { brand: string; version: string };\n origin: string;\n userAgent: string;\n}\n\n/** @internal */\nexport const cameraKitUserAgent = getCameraKitUserAgent();\n"]}
1
+ {"version":3,"file":"cameraKitUserAgent.js","sourceRoot":"","sources":["../../src/common/cameraKitUserAgent.ts"],"names":[],"mappings":"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","sourcesContent":["import environment from \"../environment.json\";\nimport lensCoreWasm from \"../lensCoreWasmVersions.json\";\nimport { locale } from \"./locale\";\nimport { isRecord } from \"./typeguards\";\n\ntype BrandArray = Array<{ brand: string; version: string }>;\n\ninterface NavigatorUAData {\n brands: BrandArray;\n mobile: boolean;\n platform: string;\n}\n\ndeclare global {\n interface Navigator {\n userAgentData?: NavigatorUAData;\n }\n}\n\n/**\n * Some user agents may not properly implement the NavigatorUAData interface, so we have to do our own validation here\n * to make sure we're dealing with a well-formed value.\n */\nfunction isNavigatorUAData(value: unknown): value is NavigatorUAData {\n return (\n isRecord(value) &&\n Array.isArray(value[\"brands\"]) &&\n value[\"brands\"].every((brand) => {\n return isRecord(brand) && typeof brand[\"brand\"] === \"string\" && typeof brand[\"version\"] === \"string\";\n }) &&\n typeof value[\"mobile\"] === \"boolean\" &&\n typeof value[\"platform\"] === \"string\"\n );\n}\n\n/**\n * Parse the platform (i.e. OS) version.\n *\n * From limited testing, this seems to often produce incorrect results – the userAgent string does not typically include\n * the actual OS version.\n *\n * Better results could be obtained from [NavigatorUAData.getHighEntropyValues]\n * (https://developer.mozilla.org/en-US/docs/Web/API/NavigatorUAData/getHighEntropyValues), but this presents two\n * problems: 1) it's currently only supported on Chrome and 2) browsers may prompt the user for permission to share\n * this information.\n *\n * So, at least for now, we'll be satisfied with the incorrect version number.\n */\nfunction parsePlatformVersion(userAgent: string) {\n // possible platform version values inside of user agent string\n // \" 11;\"\n // \" 10_15_7)\"\n // \" 13_5_1 \"\n // \" 10.0;\"\n // \" 15_1 \"\n const versionMatch = userAgent.match(/\\s([\\d][\\d_.]*[\\d])(;|\\)|\\s)/);\n\n if (versionMatch != null) {\n return versionMatch[1].replace(/_/g, \".\");\n }\n\n return \"\";\n}\n\n/**\n * In the future, we may invest in more robust device-detection (e.g. a UA string database), but for now this will give\n * us some sense of device usage.\n */\nfunction parseDeviceModel(userAgent: string) {\n // from user agent like \"(Linux; Android 11; Pixel 2)\" extact \"Pixel 2\"\n const userAgentWithModel = userAgent.match(/;[^;]+?;([^\\)]+?)\\)/);\n\n if (userAgentWithModel) {\n return userAgentWithModel[1].trim();\n }\n\n // from user agent like \"... (iPad; CPU OS 15_1 like Mac OS X) ...\" extract \"IPad\"\n const userAgentWithModel2 = userAgent.match(/\\(([^;]+);/);\n\n if (userAgentWithModel2) {\n return userAgentWithModel2[1].trim();\n }\n\n return \"unknown\";\n}\n\n/**\n * Some browsers (e.g. Safari) do not support the `Navigator.userAgentData` API. We'll attempt a sort of polyfill by\n * parsing the data found in [NavigatorUAData](https://developer.mozilla.org/en-US/docs/Web/API/NavigatorUAData) from\n * the raw user agent string.\n */\nfunction parseUserAgentData(userAgent: string): NavigatorUAData {\n let brand: BrandArray[number];\n\n // Parse UA string for Chromium-based browsers (e.g. Chrome, Edge)\n if (/Chrome/.test(userAgent)) {\n const versionMatch = userAgent.match(/Chrome\\/([\\d.]+)/);\n brand = {\n brand: \"Chrome\",\n version: versionMatch !== null ? versionMatch[1] : \"unknown\",\n };\n }\n\n // Parse UA string for Safari (very important for this to only be done if Chrome is not found – Chrome userAgent\n // strings will contain \"Safari\")\n else if (/Safari/.test(userAgent)) {\n let versionMatch = userAgent.match(/Version\\/([\\d.]+)/);\n if (versionMatch === null) versionMatch = userAgent.match(/Safari\\/([\\d.]+)/);\n brand = {\n brand: \"Safari\",\n version: versionMatch !== null ? versionMatch[1] : \"unknown\",\n };\n }\n\n // Parse UA for unknown browser.\n // TODO: will be changed, default value support should be added on a COF server side.\n else {\n brand = {\n brand: \"Firefox\",\n version: \"0\",\n };\n }\n\n // We're not using `mobile` for anything, and we have no consistent way to determine this from the UA string.\n // We'll set it to false, but this should not be used – instead, we'll need to rely on more sophisticated methods\n // (e.g. a userAgent database) to determine actual device.\n const mobile = false;\n const platform = parsePlaftformName(userAgent);\n\n return {\n brands: [brand],\n mobile,\n platform,\n };\n}\n\n/* eslint-disable max-len */\n/**\n * The `brands` array found in [NavigatorUAData](https://developer.mozilla.org/en-US/docs/Web/API/NavigatorUAData) is\n * intentionally designed to discourage standardized processing. This method of extracting brand information will be\n * inherently brittle, and it relies on us matching some well-known brands.\n *\n * For more detail from the spec:\n * See https://wicg.github.io/ua-client-hints/#monkeypatch-html-windoworworkerglobalscope\n * And https://wicg.github.io/ua-client-hints/#grease\n *\n * We also must match the list of known brands allowed by the backend, defined here:\n * https://github.sc-corp.net/Snapchat/useragent/blob/9333afe7cc6ac00503ad46cb234bcf94006dff98/java/useragent/src/main/java/snapchat/client/UserAgent.java#L124\n */\n/* eslint-enable */\ntype KnownBrand = \"Chrome\" | \"Safari\" | \"Firefox\";\nfunction normalizeBrands(brands: BrandArray): BrandArray {\n const knownBrands = new Map<string, KnownBrand>([\n [\"Chrome\", \"Chrome\"],\n [\"Chromium\", \"Chrome\"],\n [\"Firefox\", \"Firefox\"],\n [\"Microsoft Edge\", \"Chrome\"],\n [\"Safari\", \"Safari\"],\n ]);\n\n const normalizedBrands = brands\n .filter(({ brand }) => knownBrands.has(brand))\n .map((brand) => {\n return {\n // Safety: we've filtered out brands which do not appear as keys in `knownBrands`, so this cannot return\n // undefined.\n brand: knownBrands.get(brand.brand)!,\n version: brand.version,\n };\n });\n\n // TODO: default \"unknown\" value should be added on COF server side. For now we'll use Firefox.\n if (normalizedBrands.length === 0) return [{ brand: \"Firefox\", version: \"0\" }];\n return normalizedBrands;\n}\n\n/* eslint-disable max-len */\n/**\n * We must ensure the data we get from `navigator.userAgentData` is normalized to match what our backend expects to\n * see in our custom CameraKitWeb userAgent string.\n *\n * This string is defined here:\n * https://github.sc-corp.net/Snapchat/useragent/blob/9333afe7cc6ac00503ad46cb234bcf94006dff98/java/useragent/src/main/java/snapchat/client/UserAgent.java#L124\n */\n/* eslint-enable */\nfunction normalizeUserAgentData(userAgentData: NavigatorUAData): NavigatorUAData {\n return {\n brands: normalizeBrands(userAgentData.brands),\n mobile: userAgentData.mobile,\n platform: parsePlaftformName(userAgentData.platform),\n };\n}\n\n/* eslint-disable max-len */\n/**\n * The backend defines the allowed list of known platforms which will pass their RegEx test when found in our custom\n * CameraKitWeb userAgent string.\n *\n * See https://github.sc-corp.net/Snapchat/useragent/blob/9333afe7cc6ac00503ad46cb234bcf94006dff98/java/useragent/src/main/java/snapchat/client/UserAgent.java#L124\n */\n/* eslint-enable */\ntype KnownPlatform = \"macos\" | \"windows\" | \"linux\" | \"android\" | \"ios\" | \"ipados\" | \"unknown\";\nfunction parsePlaftformName(userAgent: string): KnownPlatform {\n const knownPlatforms = new Map<string, KnownPlatform>([\n [\"android\", \"android\"],\n [\"linux\", \"linux\"],\n [\"iphone os\", \"ios\"],\n [\"ipad\", \"ipados\"],\n [\"mac os\", \"macos\"],\n [\"macos\", \"macos\"],\n [\"windows\", \"windows\"],\n ]);\n\n const normalizedUserAgent = userAgent.toLowerCase();\n for (const [match, platform] of knownPlatforms.entries()) {\n if (normalizedUserAgent.includes(match)) return platform;\n }\n return \"unknown\";\n}\n\n/**\n * We'll use the application's origin as an identifier – this isn't used for any kind of authentication, but it may be\n * useful metadata to have in the future.\n *\n * We also need to handle cases in which the SDK is used in a child browsing context (e.g. an iframe), which may not\n * have a hostname – in this case we'll check each ancestor context until we find a valid hostname.\n */\nfunction parseApplicationOrigin(): string {\n let origin = location.hostname;\n // Firefox does not implement ancestorOrigins, so we need a fallback.\n // Context here: https://github.com/whatwg/html/issues/1918\n const ancestorOrigins =\n location.ancestorOrigins === undefined\n ? typeof window !== \"undefined\"\n ? [window.parent.origin, window.top?.origin ?? \"\"]\n : []\n : Array.from(location.ancestorOrigins ?? []);\n\n while (origin === \"\" && ancestorOrigins.length > 0) {\n // Safety: ancestorOrigins must contain at least one element, so shift() will always be defined.\n origin = new URL(ancestorOrigins.shift()!).hostname;\n }\n return origin;\n}\n\nfunction getCameraKitUserAgent(): CameraKitUserAgent {\n const userAgent = navigator.userAgent ?? \"\";\n // [NavigatorUAData](https://developer.mozilla.org/en-US/docs/Web/API/NavigatorUAData) is currently only\n // available on Chromium-based browsers – it's nice because it gives us clear, well-documented information. But\n // we'll have to fallback to parsing the userAgent string when it's not available.\n const userAgentData = isNavigatorUAData(navigator.userAgentData)\n ? normalizeUserAgentData(navigator.userAgentData)\n : parseUserAgentData(userAgent);\n\n const platformVersion = parsePlatformVersion(userAgent);\n const deviceModel = parseDeviceModel(userAgent);\n\n // In cases where we've parsed the userAgent string to find the brand, there will only ever be a single brand –\n // in browsers which support NavigatorUAData there could be more than one (e.g. Chrome and Chromium), but they\n // should be equivalent for our purposes.\n const browser = userAgentData.brands[0];\n const origin = parseApplicationOrigin();\n\n const sdkLongVersion = environment.PACKAGE_VERSION;\n // Remove any `-prerelease` or `+buildmetadata` portions from the semver string.\n const sdkShortVersion = sdkLongVersion.replace(/[-+]\\S+$/, \"\");\n\n // Set this to `debug` manually while testing / root-causing.\n const flavor: \"release\" | \"debug\" = \"release\";\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 const cameraKitUserAgent =\n `CameraKitWeb/${sdkShortVersion} ` +\n `${flavor === \"release\" ? \"\" : \"DEBUG\"}` +\n `(${deviceModel}; ${userAgentData.platform} ${platformVersion}) ` +\n `${browser.brand}/${browser.version} ` +\n `Core/${lensCoreWasm.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 return {\n osType: userAgentData.platform,\n osVersion: platformVersion,\n locale,\n sdkShortVersion,\n sdkLongVersion,\n flavor,\n lensCoreVersion: `${lensCoreWasm.version}`,\n deviceModel,\n browser,\n origin,\n userAgent: cameraKitUserAgent,\n };\n}\n\n/** @internal */\nexport interface CameraKitUserAgent {\n osType: string;\n osVersion: string;\n locale: string;\n sdkShortVersion: string;\n sdkLongVersion: string;\n flavor: \"release\" | \"debug\";\n lensCoreVersion: string;\n deviceModel: string;\n browser: { brand: string; version: string };\n origin: string;\n userAgent: string;\n}\n\n/** @internal */\nexport const cameraKitUserAgent = getCameraKitUserAgent();\n"]}
@@ -1,14 +1,57 @@
1
+ /**
2
+ * Dialog options.
3
+ */
1
4
  interface DialogOptions<Keys extends string> {
5
+ /**
6
+ * Element to attach the dialgo to.
7
+ */
2
8
  container: HTMLElement;
9
+ /**
10
+ * Body content string. Can be HTML string.
11
+ */
3
12
  body?: string;
13
+ /**
14
+ * Title string to render. Can be HTML string.
15
+ */
4
16
  title?: string;
17
+ /**
18
+ * Accessible dialog title text,
19
+ * especially useful for voice-over features when the title field is an image.
20
+ */
21
+ titleText?: string;
22
+ /**
23
+ * "data-testid" attribute for testing purposes.
24
+ */
5
25
  dataTestId?: string;
26
+ /**
27
+ * Use the lang field to set "lang" attribute on the dialog if that should be different from the parent page.
28
+ */
29
+ lang?: string;
30
+ /**
31
+ * Accessbile text of dismiss (X) button,
32
+ * especially useful for voice-over features when the title field is an image.
33
+ */
6
34
  dismissButtonText?: string;
35
+ /**
36
+ * Buttons to display at the bottom of the dialog.
37
+ */
7
38
  buttons?: DialogButton<Keys>[];
8
39
  }
40
+ /**
41
+ * Dialog button.
42
+ */
9
43
  interface DialogButton<Key extends string> {
44
+ /**
45
+ * Button text.
46
+ */
10
47
  text: string;
48
+ /**
49
+ * Value returned by the {@link showDialog} function after the button is clicked.
50
+ */
11
51
  key: Key;
52
+ /**
53
+ * Whether to apply "secondary" styles on the button.
54
+ */
12
55
  isSecondary?: boolean;
13
56
  }
14
57
  type DismissKey = "dismiss";
@@ -60,6 +60,10 @@ button.dismiss {
60
60
  border: 0;
61
61
  }
62
62
 
63
+ button.dismiss svg {
64
+ fill: black;
65
+ }
66
+
63
67
  .buttons {
64
68
  margin-top: 8px;
65
69
  padding: 0 32px;
@@ -85,29 +89,33 @@ button.dismiss {
85
89
  background-color: transparent;
86
90
  color: #656D78;
87
91
  }
92
+
93
+ // Proper filling of X button in High Contrast themes
94
+ @media (forced-colors: active) {
95
+ button.dismiss svg {
96
+ fill: ButtonText;
97
+ }
98
+ }
88
99
  `;
89
100
  function getDismissButtonHtml(button) {
90
101
  /* eslint-disable max-len */
91
102
  return `
92
103
  <button class="dismiss" autofocus data-key=${button.key}>
93
- <svg width="36" height="36" viewBox="0 0 36 36" fill="none" xmlns="http://www.w3.org/2000/svg">
104
+ <svg xmlns="http://www.w3.org/2000/svg" role="img" width="36" height="36" viewBox="0 0 36 36">
94
105
  <title>${button.text}</title>
95
- <path fill-rule="evenodd" clip-rule="evenodd" d="M12.6763 11.2621C12.2858 10.8716 11.6527 10.8716 11.2621 11.2621C10.8716 11.6527 10.8716 12.2858 11.2621 12.6763L16.5858 18L11.2621 23.3237C10.8716 23.7142 10.8716 24.3474 11.2621 24.7379C11.6527 25.1284 12.2858 25.1284 12.6764 24.7379L18 19.4142L23.3237 24.7379C23.7142 25.1284 24.3474 25.1284 24.7379 24.7379C25.1284 24.3474 25.1284 23.7142 24.7379 23.3237L19.4142 18L24.7379 12.6763C25.1284 12.2858 25.1284 11.6527 24.7379 11.2621C24.3474 10.8716 23.7142 10.8716 23.3237 11.2621L18 16.5858L12.6763 11.2621Z" fill="black" fill-opacity="0.4"/>
106
+ <path fill-rule="evenodd" clip-rule="evenodd" d="M12.6763 11.2621C12.2858 10.8716 11.6527 10.8716 11.2621 11.2621C10.8716 11.6527 10.8716 12.2858 11.2621 12.6763L16.5858 18L11.2621 23.3237C10.8716 23.7142 10.8716 24.3474 11.2621 24.7379C11.6527 25.1284 12.2858 25.1284 12.6764 24.7379L18 19.4142L23.3237 24.7379C23.7142 25.1284 24.3474 25.1284 24.7379 24.7379C25.1284 24.3474 25.1284 23.7142 24.7379 23.3237L19.4142 18L24.7379 12.6763C25.1284 12.2858 25.1284 11.6527 24.7379 11.2621C24.3474 10.8716 23.7142 10.8716 23.3237 11.2621L18 16.5858L12.6763 11.2621Z" fill-opacity="0.4"/>
96
107
  </svg>
97
108
  </button>`;
98
109
  /* eslint-enable */
99
110
  }
100
111
  function getTitleHtml(title) {
101
- return title ? `<div class="title">${title}</div>` : "";
112
+ return title ? `<div class="title" role="heading">${title}</div>` : "";
102
113
  }
103
114
  function getBodyHtml(body) {
104
115
  return body ? `<div class="body">${body}</div>` : "";
105
116
  }
106
117
  function getButtonHtml(button) {
107
- return `
108
- <button data-key="${button.key}" class="${button.isSecondary ? "secondary" : ""}">
109
- ${button.text}
110
- </button>`;
118
+ return `<button data-key="${button.key}"${button.isSecondary ? ` class="secondary"` : ""}>${button.text}</button>`;
111
119
  }
112
120
  function getButtonsHtml(buttons) {
113
121
  if (buttons.length === 0)
@@ -117,23 +125,29 @@ function getButtonsHtml(buttons) {
117
125
  ${buttons.map((b) => getButtonHtml(b)).join("\n")}
118
126
  </div>`;
119
127
  }
128
+ function setAttribute(element, attr, value) {
129
+ if (value)
130
+ element.setAttribute(attr, value);
131
+ }
120
132
  export function showDialog(options) {
121
133
  return new Promise((res) => {
122
- var _a, _b;
134
+ var _a, _b, _c;
123
135
  const element = document.createElement("div");
124
- if (options.dataTestId)
125
- element.setAttribute("data-testid", options.dataTestId);
136
+ setAttribute(element, "data-testid", options.dataTestId);
126
137
  const shadow = element.attachShadow({ mode: "open" });
127
138
  const style = document.createElement("style");
128
139
  shadow.appendChild(style);
129
140
  style.innerHTML = stylesCss;
130
141
  const prompt = document.createElement("dialog");
142
+ setAttribute(prompt, "aria-label", (_a = options.titleText) !== null && _a !== void 0 ? _a : options.title);
143
+ setAttribute(prompt, "lang", options.lang);
144
+ setAttribute(prompt, "dir", "auto");
131
145
  shadow.appendChild(prompt);
132
146
  prompt.innerHTML = `
133
- ${getDismissButtonHtml({ key: "dismiss", text: (_a = options.dismissButtonText) !== null && _a !== void 0 ? _a : "Dismiss" })}
147
+ ${getDismissButtonHtml({ key: "dismiss", text: (_b = options.dismissButtonText) !== null && _b !== void 0 ? _b : "Dismiss" })}
134
148
  ${getTitleHtml(options.title)}
135
149
  ${getBodyHtml(options.body)}
136
- ${getButtonsHtml((_b = options.buttons) !== null && _b !== void 0 ? _b : [])}
150
+ ${getButtonsHtml((_c = options.buttons) !== null && _c !== void 0 ? _c : [])}
137
151
  `;
138
152
  const buttonsElements = Array.from(prompt.querySelectorAll("button"));
139
153
  merge(...buttonsElements.map((b) => fromEvent(b, "click").pipe(map(() => b.dataset.key))), fromEvent(prompt, "cancel").pipe(map(() => "dismiss")))
@@ -1 +1 @@
1
- {"version":3,"file":"dialog.js","sourceRoot":"","sources":["../../src/common/dialog.ts"],"names":[],"mappings":"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","sourcesContent":["import { fromEvent, map, merge, take } from \"rxjs\";\n\ninterface DialogOptions<Keys extends string> {\n container: HTMLElement;\n body?: string;\n title?: string;\n dataTestId?: string;\n dismissButtonText?: string;\n buttons?: DialogButton<Keys>[];\n}\n\ninterface DialogButton<Key extends string> {\n text: string;\n key: Key;\n isSecondary?: boolean;\n}\n\ntype DismissKey = \"dismiss\";\n\nconst stylesCss = `\ndialog {\n display: flex;\n flex-direction: column;\n\n background-color: #fff;\n border: #efefef 1px solid;\n border-radius: 20px;\n box-shadow: 0px 10px 20px rgba(0, 0, 0, 0.3);\n\n max-width: 80vw;\n max-height: 80vh;\n padding: 44px 0 24px 0;\n\n font-size: 16px;\n font-family: sans-serif;\n font-style: normal;\n font-weight: 600;\n line-height: 24px;\n}\n\ndialog::backdrop {\n background-color: rgba(0, 0, 0, 0.4);\n}\n\n.title {\n color: #16191C;\n padding: 0 32px;\n text-align: center;\n}\n\n.body {\n color: #656D78;\n font-size: 14px;\n font-weight: 500;\n margin-top: 16px;\n max-width: 350px;\n padding: 0 32px;\n overflow: auto;\n}\n\na {\n color: rgb(78, 171, 248);\n}\n\nbutton {\n cursor: pointer;\n}\n\nbutton.dismiss {\n position: absolute;\n top: 7px;\n right: 7px;\n padding: 0;\n height: 36px;\n width: 36px;\n margin: 0;\n background-color: transparent;\n border: 0;\n}\n\n.buttons {\n margin-top: 8px;\n padding: 0 32px;\n}\n\n.buttons button {\n background: #0FADFF;\n border: 0;\n border-radius: 25px;\n\n width: 100%;\n padding: 1rem;\n margin-top: 8px;\n\n color: #fff;\n font-weight: inherit;\n font-family: inherit;\n font-size: inherit;\n font-style: inherit;\n}\n\n.buttons button.secondary {\n background-color: transparent;\n color: #656D78;\n}\n`;\n\nfunction getDismissButtonHtml(button: DialogButton<DismissKey>) {\n /* eslint-disable max-len */\n return `\n <button class=\"dismiss\" autofocus data-key=${button.key}>\n <svg width=\"36\" height=\"36\" viewBox=\"0 0 36 36\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <title>${button.text}</title>\n <path fill-rule=\"evenodd\" clip-rule=\"evenodd\" d=\"M12.6763 11.2621C12.2858 10.8716 11.6527 10.8716 11.2621 11.2621C10.8716 11.6527 10.8716 12.2858 11.2621 12.6763L16.5858 18L11.2621 23.3237C10.8716 23.7142 10.8716 24.3474 11.2621 24.7379C11.6527 25.1284 12.2858 25.1284 12.6764 24.7379L18 19.4142L23.3237 24.7379C23.7142 25.1284 24.3474 25.1284 24.7379 24.7379C25.1284 24.3474 25.1284 23.7142 24.7379 23.3237L19.4142 18L24.7379 12.6763C25.1284 12.2858 25.1284 11.6527 24.7379 11.2621C24.3474 10.8716 23.7142 10.8716 23.3237 11.2621L18 16.5858L12.6763 11.2621Z\" fill=\"black\" fill-opacity=\"0.4\"/>\n </svg>\n </button>`;\n /* eslint-enable */\n}\n\nfunction getTitleHtml(title: string | undefined) {\n return title ? `<div class=\"title\">${title}</div>` : \"\";\n}\n\nfunction getBodyHtml(body: string | undefined) {\n return body ? `<div class=\"body\">${body}</div>` : \"\";\n}\n\nfunction getButtonHtml<Key extends string>(button: DialogButton<Key>) {\n return `\n <button data-key=\"${button.key}\" class=\"${button.isSecondary ? \"secondary\" : \"\"}\">\n ${button.text}\n </button>`;\n}\n\nfunction getButtonsHtml<Key extends string>(buttons: DialogButton<Key>[]) {\n if (buttons.length === 0) return \"\";\n return `\n <div class=\"buttons\">\n ${buttons.map((b) => getButtonHtml(b)).join(\"\\n\")}\n </div>`;\n}\n\nexport function showDialog<Keys extends string>(options: DialogOptions<Keys>): Promise<Keys | DismissKey> {\n return new Promise((res) => {\n const element = document.createElement(\"div\");\n if (options.dataTestId) element.setAttribute(\"data-testid\", options.dataTestId);\n const shadow = element.attachShadow({ mode: \"open\" });\n\n const style = document.createElement(\"style\");\n shadow.appendChild(style);\n style.innerHTML = stylesCss;\n\n const prompt = document.createElement(\"dialog\");\n shadow.appendChild(prompt);\n\n prompt.innerHTML = `\n ${getDismissButtonHtml({ key: \"dismiss\", text: options.dismissButtonText ?? \"Dismiss\" })}\n ${getTitleHtml(options.title)}\n ${getBodyHtml(options.body)}\n ${getButtonsHtml(options.buttons ?? [])}\n `;\n\n const buttonsElements = Array.from(prompt.querySelectorAll(\"button\"));\n merge(\n ...buttonsElements.map((b) => fromEvent(b, \"click\").pipe(map(() => b.dataset.key as Keys))),\n fromEvent(prompt, \"cancel\").pipe(map(() => \"dismiss\" as const))\n )\n .pipe(take(1))\n .subscribe({ next: res, complete: () => element.remove() });\n options.container.appendChild(element);\n prompt.showModal();\n });\n}\n"]}
1
+ {"version":3,"file":"dialog.js","sourceRoot":"","sources":["../../src/common/dialog.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AA8DnD,MAAM,SAAS,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAiGjB,CAAC;AAEF,SAAS,oBAAoB,CAAC,MAAgC;IAC1D,4BAA4B;IAC5B,OAAO;qDAC0C,MAAM,CAAC,GAAG;;yBAEtC,MAAM,CAAC,IAAI;;;kBAGlB,CAAC;IACf,mBAAmB;AACvB,CAAC;AAED,SAAS,YAAY,CAAC,KAAyB;IAC3C,OAAO,KAAK,CAAC,CAAC,CAAC,qCAAqC,KAAK,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC;AAC3E,CAAC;AAED,SAAS,WAAW,CAAC,IAAwB;IACzC,OAAO,IAAI,CAAC,CAAC,CAAC,qBAAqB,IAAI,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC;AACzD,CAAC;AAED,SAAS,aAAa,CAAqB,MAAyB;IAChE,OAAO,qBAAqB,MAAM,CAAC,GAAG,IAAI,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC,oBAAoB,CAAC,CAAC,CAAC,EAAE,IAAI,MAAM,CAAC,IAAI,WAAW,CAAC;AACvH,CAAC;AAED,SAAS,cAAc,CAAqB,OAA4B;IACpE,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IACpC,OAAO;;UAED,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;eAC1C,CAAC;AAChB,CAAC;AAED,SAAS,YAAY,CAAC,OAAoB,EAAE,IAAY,EAAE,KAAyB;IAC/E,IAAI,KAAK;QAAE,OAAO,CAAC,YAAY,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;AACjD,CAAC;AAED,MAAM,UAAU,UAAU,CAAsB,OAA4B;IACxE,OAAO,IAAI,OAAO,CAAC,CAAC,GAAG,EAAE,EAAE;;QACvB,MAAM,OAAO,GAAG,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;QAC9C,YAAY,CAAC,OAAO,EAAE,aAAa,EAAE,OAAO,CAAC,UAAU,CAAC,CAAC;QACzD,MAAM,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC;QAEtD,MAAM,KAAK,GAAG,QAAQ,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;QAC9C,MAAM,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;QAC1B,KAAK,CAAC,SAAS,GAAG,SAAS,CAAC;QAE5B,MAAM,MAAM,GAAG,QAAQ,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;QAChD,YAAY,CAAC,MAAM,EAAE,YAAY,EAAE,MAAA,OAAO,CAAC,SAAS,mCAAI,OAAO,CAAC,KAAK,CAAC,CAAC;QACvE,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;QAC3C,YAAY,CAAC,MAAM,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;QACpC,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;QAE3B,MAAM,CAAC,SAAS,GAAG;cACb,oBAAoB,CAAC,EAAE,GAAG,EAAE,SAAS,EAAE,IAAI,EAAE,MAAA,OAAO,CAAC,iBAAiB,mCAAI,SAAS,EAAE,CAAC;cACtF,YAAY,CAAC,OAAO,CAAC,KAAK,CAAC;cAC3B,WAAW,CAAC,OAAO,CAAC,IAAI,CAAC;cACzB,cAAc,CAAC,MAAA,OAAO,CAAC,OAAO,mCAAI,EAAE,CAAC;SAC1C,CAAC;QAEF,MAAM,eAAe,GAAG,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,gBAAgB,CAAC,QAAQ,CAAC,CAAC,CAAC;QACtE,KAAK,CACD,GAAG,eAAe,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,SAAS,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,GAAW,CAAC,CAAC,CAAC,EAC3F,SAAS,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,SAAkB,CAAC,CAAC,CAClE;aACI,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;aACb,SAAS,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,QAAQ,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;QAChE,OAAO,CAAC,SAAS,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;QACvC,MAAM,CAAC,SAAS,EAAE,CAAC;IACvB,CAAC,CAAC,CAAC;AACP,CAAC","sourcesContent":["import { fromEvent, map, merge, take } from \"rxjs\";\n\n/**\n * Dialog options.\n */\ninterface DialogOptions<Keys extends string> {\n /**\n * Element to attach the dialgo to.\n */\n container: HTMLElement;\n /**\n * Body content string. Can be HTML string.\n */\n body?: string;\n /**\n * Title string to render. Can be HTML string.\n */\n title?: string;\n /**\n * Accessible dialog title text,\n * especially useful for voice-over features when the title field is an image.\n */\n titleText?: string;\n /**\n * \"data-testid\" attribute for testing purposes.\n */\n dataTestId?: string;\n /**\n * Use the lang field to set \"lang\" attribute on the dialog if that should be different from the parent page.\n */\n lang?: string;\n /**\n * Accessbile text of dismiss (X) button,\n * especially useful for voice-over features when the title field is an image.\n */\n dismissButtonText?: string;\n /**\n * Buttons to display at the bottom of the dialog.\n */\n buttons?: DialogButton<Keys>[];\n}\n\n/**\n * Dialog button.\n */\ninterface DialogButton<Key extends string> {\n /**\n * Button text.\n */\n text: string;\n /**\n * Value returned by the {@link showDialog} function after the button is clicked.\n */\n key: Key;\n /**\n * Whether to apply \"secondary\" styles on the button.\n */\n isSecondary?: boolean;\n}\n\ntype DismissKey = \"dismiss\";\n\nconst stylesCss = `\ndialog {\n display: flex;\n flex-direction: column;\n\n background-color: #fff;\n border: #efefef 1px solid;\n border-radius: 20px;\n box-shadow: 0px 10px 20px rgba(0, 0, 0, 0.3);\n\n max-width: 80vw;\n max-height: 80vh;\n padding: 44px 0 24px 0;\n\n font-size: 16px;\n font-family: sans-serif;\n font-style: normal;\n font-weight: 600;\n line-height: 24px;\n}\n\ndialog::backdrop {\n background-color: rgba(0, 0, 0, 0.4);\n}\n\n.title {\n color: #16191C;\n padding: 0 32px;\n text-align: center;\n}\n\n.body {\n color: #656D78;\n font-size: 14px;\n font-weight: 500;\n margin-top: 16px;\n max-width: 350px;\n padding: 0 32px;\n overflow: auto;\n}\n\na {\n color: rgb(78, 171, 248);\n}\n\nbutton {\n cursor: pointer;\n}\n\nbutton.dismiss {\n position: absolute;\n top: 7px;\n right: 7px;\n padding: 0;\n height: 36px;\n width: 36px;\n margin: 0;\n background-color: transparent;\n border: 0;\n}\n\nbutton.dismiss svg {\n fill: black;\n}\n\n.buttons {\n margin-top: 8px;\n padding: 0 32px;\n}\n\n.buttons button {\n background: #0FADFF;\n border: 0;\n border-radius: 25px;\n\n width: 100%;\n padding: 1rem;\n margin-top: 8px;\n\n color: #fff;\n font-weight: inherit;\n font-family: inherit;\n font-size: inherit;\n font-style: inherit;\n}\n\n.buttons button.secondary {\n background-color: transparent;\n color: #656D78;\n}\n\n// Proper filling of X button in High Contrast themes\n@media (forced-colors: active) {\n button.dismiss svg {\n fill: ButtonText;\n }\n}\n`;\n\nfunction getDismissButtonHtml(button: DialogButton<DismissKey>) {\n /* eslint-disable max-len */\n return `\n <button class=\"dismiss\" autofocus data-key=${button.key}>\n <svg xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" width=\"36\" height=\"36\" viewBox=\"0 0 36 36\">\n <title>${button.text}</title>\n <path fill-rule=\"evenodd\" clip-rule=\"evenodd\" d=\"M12.6763 11.2621C12.2858 10.8716 11.6527 10.8716 11.2621 11.2621C10.8716 11.6527 10.8716 12.2858 11.2621 12.6763L16.5858 18L11.2621 23.3237C10.8716 23.7142 10.8716 24.3474 11.2621 24.7379C11.6527 25.1284 12.2858 25.1284 12.6764 24.7379L18 19.4142L23.3237 24.7379C23.7142 25.1284 24.3474 25.1284 24.7379 24.7379C25.1284 24.3474 25.1284 23.7142 24.7379 23.3237L19.4142 18L24.7379 12.6763C25.1284 12.2858 25.1284 11.6527 24.7379 11.2621C24.3474 10.8716 23.7142 10.8716 23.3237 11.2621L18 16.5858L12.6763 11.2621Z\" fill-opacity=\"0.4\"/>\n </svg>\n </button>`;\n /* eslint-enable */\n}\n\nfunction getTitleHtml(title: string | undefined) {\n return title ? `<div class=\"title\" role=\"heading\">${title}</div>` : \"\";\n}\n\nfunction getBodyHtml(body: string | undefined) {\n return body ? `<div class=\"body\">${body}</div>` : \"\";\n}\n\nfunction getButtonHtml<Key extends string>(button: DialogButton<Key>) {\n return `<button data-key=\"${button.key}\"${button.isSecondary ? ` class=\"secondary\"` : \"\"}>${button.text}</button>`;\n}\n\nfunction getButtonsHtml<Key extends string>(buttons: DialogButton<Key>[]) {\n if (buttons.length === 0) return \"\";\n return `\n <div class=\"buttons\">\n ${buttons.map((b) => getButtonHtml(b)).join(\"\\n\")}\n </div>`;\n}\n\nfunction setAttribute(element: HTMLElement, attr: string, value: string | undefined) {\n if (value) element.setAttribute(attr, value);\n}\n\nexport function showDialog<Keys extends string>(options: DialogOptions<Keys>): Promise<Keys | DismissKey> {\n return new Promise((res) => {\n const element = document.createElement(\"div\");\n setAttribute(element, \"data-testid\", options.dataTestId);\n const shadow = element.attachShadow({ mode: \"open\" });\n\n const style = document.createElement(\"style\");\n shadow.appendChild(style);\n style.innerHTML = stylesCss;\n\n const prompt = document.createElement(\"dialog\");\n setAttribute(prompt, \"aria-label\", options.titleText ?? options.title);\n setAttribute(prompt, \"lang\", options.lang);\n setAttribute(prompt, \"dir\", \"auto\");\n shadow.appendChild(prompt);\n\n prompt.innerHTML = `\n ${getDismissButtonHtml({ key: \"dismiss\", text: options.dismissButtonText ?? \"Dismiss\" })}\n ${getTitleHtml(options.title)}\n ${getBodyHtml(options.body)}\n ${getButtonsHtml(options.buttons ?? [])}\n `;\n\n const buttonsElements = Array.from(prompt.querySelectorAll(\"button\"));\n merge(\n ...buttonsElements.map((b) => fromEvent(b, \"click\").pipe(map(() => b.dataset.key as Keys))),\n fromEvent(prompt, \"cancel\").pipe(map(() => \"dismiss\" as const))\n )\n .pipe(take(1))\n .subscribe({ next: res, complete: () => element.remove() });\n options.container.appendChild(element);\n prompt.showModal();\n });\n}\n"]}
@@ -5,7 +5,9 @@ interface CameraKitRuntimeConfiguration {
5
5
  logger: "noop" | "console";
6
6
  logLevel: LogLevelName;
7
7
  shouldUseWorker: boolean;
8
+ apiHostname: CameraKitApiHostname;
8
9
  }
10
+ export type CameraKitApiHostname = "camera-kit-api.snapar.com" | "api-kit.snapchat.com";
9
11
  /**
10
12
  * Configuration which must be provided when calling {@link bootstrapCameraKit}. These values are used to create various
11
13
  * CameraKit components.
@@ -13,6 +13,7 @@ const defaultConfiguration = {
13
13
  logger: "noop",
14
14
  logLevel: "info",
15
15
  shouldUseWorker: true,
16
+ apiHostname: "camera-kit-api.snapar.com",
16
17
  };
17
18
  /** @internal */
18
19
  export const configurationToken = "configuration";
@@ -1 +1 @@
1
- {"version":3,"file":"configuration.js","sourceRoot":"","sources":["../src/configuration.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,qBAAqB,EAAE,MAAM,gCAAgC,CAAC;AACvE,OAAO,EAAE,yBAAyB,EAAE,MAAM,0BAA0B,CAAC;AACrE,OAAO,EAAE,UAAU,EAAE,MAAM,mCAAmC,CAAC;AAU/D;;;GAGG;AACH,MAAM,oBAAoB,GAAmF;IACzG,mHAAmH;IACnH,6GAA6G;IAC7G,qFAAqF;IACrF,eAAe,EAAE,EAAE,OAAO,EAAE,CAAC,EAAE,UAAU,EAAE,EAAE,EAAE,iBAAiB,EAAE,SAAS,EAAE;IAC7E,MAAM,EAAE,MAAM;IACd,QAAQ,EAAE,MAAM;IAChB,eAAe,EAAE,IAAI;CACxB,CAAC;AAwFF,gBAAgB;AAChB,MAAM,CAAC,MAAM,kBAAkB,GAAG,eAAe,CAAC;AAElD,gBAAgB;AAChB,MAAM,CAAC,MAAM,mCAAmC,GAAG,CAAC,aAA8C,EAAE,EAAE;IAClG,6DAA6D;IAC7D,MAAM,SAAS,GAAG,yBAAyB,EAAE,CAAC;IAC9C,IAAI,SAAS,EAAE;QACX,OAAO,CAAC,IAAI,CAAC,iCAAiC,EAAE,SAAS,CAAC,CAAC;KAC9D;IACD,OAAO,UAAU,CAAC,kBAAkB,EAAE,GAA2B,EAAE;QAC/D,uGAAuG;QACvG,kFAAkF;QAClF,MAAM,UAAU,mCACT,aAAa,KAChB,eAAe,EACX,aAAa,CAAC,eAAe,YAAY,OAAO;gBAC5C,CAAC,CAAC,kFAAkF;oBAClF,aAAa,CAAC,eAAe,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,oBAAoB,CAAC,eAAgB,CAAC;gBAClF,CAAC,CAAC,aAAa,CAAC,eAAe,GAC1C,CAAC;QACF,qDACO,oBAAoB,GACpB,qBAAqB,CAAC,UAAU,CAAC,GACjC,qBAAqB,CAAC,SAAS,aAAT,SAAS,cAAT,SAAS,GAAI,EAAE,CAAC,EAC3C;IACN,CAAC,CAAC,CAAC;AACP,CAAC,CAAC","sourcesContent":["import { EstimatedLensPerformance } from \"./benchmark/estimateLensPerformanceCluster\";\nimport { copyDefinedProperties } from \"./common/copyDefinedProperties\";\nimport { getConfigurationOverrides } from \"./configurationOverrides\";\nimport { Injectable } from \"./dependency-injection/Injectable\";\nimport { LogLevelName } from \"./logger/logger\";\n\n/**\n * From T, pick the set of properties whose values are optional. Create a new type containing only those properties.\n */\ntype PickOptionals<T> = {\n [K in keyof T as T[K] extends Exclude<T[K], undefined> ? never : K]: T[K];\n};\n\n/**\n * Defaults are provided for runtime configuration and any optional bootstrap configuration properties which require\n * defaults.\n */\nconst defaultConfiguration: CameraKitRuntimeConfiguration & PickOptionals<CameraKitBootstrapConfiguration> = {\n // If the applications doesn't provide performance data (e.g. via estimateLensPerformance), we'll use 0 to indicate\n // no performance estimation occurred. This is indicative of typical performance-targeting logic, which often\n // defaults to the lowest-tier experience in the absense of performance cluster data.\n lensPerformance: { cluster: 0, benchmarks: [], webglRendererInfo: \"unknown\" },\n logger: \"noop\",\n logLevel: \"info\",\n shouldUseWorker: true,\n};\n\ninterface CameraKitRuntimeConfiguration {\n lensPerformance: EstimatedLensPerformance | Promise<EstimatedLensPerformance>;\n logger: \"noop\" | \"console\";\n logLevel: LogLevelName;\n shouldUseWorker: boolean;\n}\n\n/**\n * Configuration which must be provided when calling {@link bootstrapCameraKit}. These values are used to create various\n * CameraKit components.\n *\n * @category Bootstrapping and Configuration\n */\nexport interface CameraKitBootstrapConfiguration {\n /**\n * Long-lived token granting your application access to CameraKit APIs. This is found in the SnapKit Dev Portal,\n * where it's called the API Token.\n */\n apiToken: string;\n\n /**\n * Determine where to print CameraKit log messages. By default no logs will be printed.\n *\n * CameraKit emits log messages to help diagnose and root cause issues that may occur during the development of a\n * host application. The printing of these can be controlled via the following\n * options:\n * - `noop`: log messages are ignored.\n * - `console`: log messages are printed to console.\n */\n logger?: \"noop\" | \"console\";\n\n /**\n * Log only if a logged entry level is greater than or equal to this level. Here is the order of levels:\n * error > warn > log = info > debug. Default value is \"info\".\n */\n logLevel?: LogLevelName;\n\n /**\n * Some lenses may decide to modify their behavior based on the performance of the current environment. If you are\n * using such lenses, providing an estimation of lens performance may lead to better user experience (especially on\n * low-performance devices).\n *\n * Running the {@link estimateLensPerformance} function will run benchmarks and estimate an appropriate lens\n * performance cluster (i.e. a performance rating) based on the current environment.\n *\n * Lower cluster = worse expected performance capability.\n *\n * @example\n * ```ts\n * import { bootstrapCameraKit, estimateLensPerformance } from '@snap/camera-kit`\n *\n * const cameraKit = await bootstrapCameraKit({\n * apiToken: '...',\n * lensPerformance: estimateLensPerformance(),\n * })\n * ```\n */\n lensPerformance?: EstimatedLensPerformance | Promise<EstimatedLensPerformance>;\n\n /**\n * In recommended production deployments, the WebAssembly assets required by CameraKit will be downloaded from an\n * optimized CDN. But sometimes (e.g. during development or within a CI pipeline), it may be necessary to download\n * these assets from somewhere else.\n *\n * This configuration option allows the application to specify URLs to be used for both the WebAssembly and JS glue\n * file that are used to run and interact with CameraKit's rendering engine.\n */\n lensCoreOverrideUrls?: { wasm: string; js: string };\n\n /**\n * In recommended production deployments, the WebAssembly assets required by CameraKit will be downloaded from an\n * optimized CDN. But sometimes during development or within a CI pipeline, it may be necessary to download these\n * assets from somewhere else. With a provided `wasmEndpointOverride`, asset URLs will be automatically generated\n * based on this root endpoint.\n */\n wasmEndpointOverride?: string;\n}\n\n/**\n * This type represents the result of merging user-supplied config with default config -- as such, it has no nullable\n * fields, making it a more convenient type for other components to use.\n *\n * @internal\n */\nexport type CameraKitConfiguration = CameraKitRuntimeConfiguration & CameraKitBootstrapConfiguration;\n\n/** @internal */\nexport const configurationToken = \"configuration\";\n\n/** @internal */\nexport const createCameraKitConfigurationFactory = (configuration: CameraKitBootstrapConfiguration) => {\n // always leave debug mode warning about overrides in console\n const overrides = getConfigurationOverrides();\n if (overrides) {\n console.warn(\"Configuration overrides applied\", overrides);\n }\n return Injectable(configurationToken, (): CameraKitConfiguration => {\n // We'll ensure that we handle errors on any Promises passed as config values, otherwise we either must\n // handle them separately wherever they're used, or rejections would go unhandled.\n const safeConfig: CameraKitBootstrapConfiguration = {\n ...configuration,\n lensPerformance:\n configuration.lensPerformance instanceof Promise\n ? // Safety: defaultConfiguration.lensPerformance is defined (it's hardcoded above).\n configuration.lensPerformance.catch(() => defaultConfiguration.lensPerformance!)\n : configuration.lensPerformance,\n };\n return {\n ...defaultConfiguration,\n ...copyDefinedProperties(safeConfig),\n ...copyDefinedProperties(overrides ?? {}),\n };\n });\n};\n"]}
1
+ {"version":3,"file":"configuration.js","sourceRoot":"","sources":["../src/configuration.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,qBAAqB,EAAE,MAAM,gCAAgC,CAAC;AACvE,OAAO,EAAE,yBAAyB,EAAE,MAAM,0BAA0B,CAAC;AACrE,OAAO,EAAE,UAAU,EAAE,MAAM,mCAAmC,CAAC;AAU/D;;;GAGG;AACH,MAAM,oBAAoB,GAAmF;IACzG,mHAAmH;IACnH,6GAA6G;IAC7G,qFAAqF;IACrF,eAAe,EAAE,EAAE,OAAO,EAAE,CAAC,EAAE,UAAU,EAAE,EAAE,EAAE,iBAAiB,EAAE,SAAS,EAAE;IAC7E,MAAM,EAAE,MAAM;IACd,QAAQ,EAAE,MAAM;IAChB,eAAe,EAAE,IAAI;IACrB,WAAW,EAAE,2BAA2B;CAC3C,CAAC;AA2FF,gBAAgB;AAChB,MAAM,CAAC,MAAM,kBAAkB,GAAG,eAAe,CAAC;AAElD,gBAAgB;AAChB,MAAM,CAAC,MAAM,mCAAmC,GAAG,CAAC,aAA8C,EAAE,EAAE;IAClG,6DAA6D;IAC7D,MAAM,SAAS,GAAG,yBAAyB,EAAE,CAAC;IAC9C,IAAI,SAAS,EAAE;QACX,OAAO,CAAC,IAAI,CAAC,iCAAiC,EAAE,SAAS,CAAC,CAAC;KAC9D;IACD,OAAO,UAAU,CAAC,kBAAkB,EAAE,GAA2B,EAAE;QAC/D,uGAAuG;QACvG,kFAAkF;QAClF,MAAM,UAAU,mCACT,aAAa,KAChB,eAAe,EACX,aAAa,CAAC,eAAe,YAAY,OAAO;gBAC5C,CAAC,CAAC,kFAAkF;oBAClF,aAAa,CAAC,eAAe,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,oBAAoB,CAAC,eAAgB,CAAC;gBAClF,CAAC,CAAC,aAAa,CAAC,eAAe,GAC1C,CAAC;QACF,qDACO,oBAAoB,GACpB,qBAAqB,CAAC,UAAU,CAAC,GACjC,qBAAqB,CAAC,SAAS,aAAT,SAAS,cAAT,SAAS,GAAI,EAAE,CAAC,EAC3C;IACN,CAAC,CAAC,CAAC;AACP,CAAC,CAAC","sourcesContent":["import { EstimatedLensPerformance } from \"./benchmark/estimateLensPerformanceCluster\";\nimport { copyDefinedProperties } from \"./common/copyDefinedProperties\";\nimport { getConfigurationOverrides } from \"./configurationOverrides\";\nimport { Injectable } from \"./dependency-injection/Injectable\";\nimport { LogLevelName } from \"./logger/logger\";\n\n/**\n * From T, pick the set of properties whose values are optional. Create a new type containing only those properties.\n */\ntype PickOptionals<T> = {\n [K in keyof T as T[K] extends Exclude<T[K], undefined> ? never : K]: T[K];\n};\n\n/**\n * Defaults are provided for runtime configuration and any optional bootstrap configuration properties which require\n * defaults.\n */\nconst defaultConfiguration: CameraKitRuntimeConfiguration & PickOptionals<CameraKitBootstrapConfiguration> = {\n // If the applications doesn't provide performance data (e.g. via estimateLensPerformance), we'll use 0 to indicate\n // no performance estimation occurred. This is indicative of typical performance-targeting logic, which often\n // defaults to the lowest-tier experience in the absense of performance cluster data.\n lensPerformance: { cluster: 0, benchmarks: [], webglRendererInfo: \"unknown\" },\n logger: \"noop\",\n logLevel: \"info\",\n shouldUseWorker: true,\n apiHostname: \"camera-kit-api.snapar.com\",\n};\n\ninterface CameraKitRuntimeConfiguration {\n lensPerformance: EstimatedLensPerformance | Promise<EstimatedLensPerformance>;\n logger: \"noop\" | \"console\";\n logLevel: LogLevelName;\n shouldUseWorker: boolean;\n apiHostname: CameraKitApiHostname;\n}\n\nexport type CameraKitApiHostname = \"camera-kit-api.snapar.com\" | \"api-kit.snapchat.com\";\n\n/**\n * Configuration which must be provided when calling {@link bootstrapCameraKit}. These values are used to create various\n * CameraKit components.\n *\n * @category Bootstrapping and Configuration\n */\nexport interface CameraKitBootstrapConfiguration {\n /**\n * Long-lived token granting your application access to CameraKit APIs. This is found in the SnapKit Dev Portal,\n * where it's called the API Token.\n */\n apiToken: string;\n\n /**\n * Determine where to print CameraKit log messages. By default no logs will be printed.\n *\n * CameraKit emits log messages to help diagnose and root cause issues that may occur during the development of a\n * host application. The printing of these can be controlled via the following\n * options:\n * - `noop`: log messages are ignored.\n * - `console`: log messages are printed to console.\n */\n logger?: \"noop\" | \"console\";\n\n /**\n * Log only if a logged entry level is greater than or equal to this level. Here is the order of levels:\n * error > warn > log = info > debug. Default value is \"info\".\n */\n logLevel?: LogLevelName;\n\n /**\n * Some lenses may decide to modify their behavior based on the performance of the current environment. If you are\n * using such lenses, providing an estimation of lens performance may lead to better user experience (especially on\n * low-performance devices).\n *\n * Running the {@link estimateLensPerformance} function will run benchmarks and estimate an appropriate lens\n * performance cluster (i.e. a performance rating) based on the current environment.\n *\n * Lower cluster = worse expected performance capability.\n *\n * @example\n * ```ts\n * import { bootstrapCameraKit, estimateLensPerformance } from '@snap/camera-kit`\n *\n * const cameraKit = await bootstrapCameraKit({\n * apiToken: '...',\n * lensPerformance: estimateLensPerformance(),\n * })\n * ```\n */\n lensPerformance?: EstimatedLensPerformance | Promise<EstimatedLensPerformance>;\n\n /**\n * In recommended production deployments, the WebAssembly assets required by CameraKit will be downloaded from an\n * optimized CDN. But sometimes (e.g. during development or within a CI pipeline), it may be necessary to download\n * these assets from somewhere else.\n *\n * This configuration option allows the application to specify URLs to be used for both the WebAssembly and JS glue\n * file that are used to run and interact with CameraKit's rendering engine.\n */\n lensCoreOverrideUrls?: { wasm: string; js: string };\n\n /**\n * In recommended production deployments, the WebAssembly assets required by CameraKit will be downloaded from an\n * optimized CDN. But sometimes during development or within a CI pipeline, it may be necessary to download these\n * assets from somewhere else. With a provided `wasmEndpointOverride`, asset URLs will be automatically generated\n * based on this root endpoint.\n */\n wasmEndpointOverride?: string;\n}\n\n/**\n * This type represents the result of merging user-supplied config with default config -- as such, it has no nullable\n * fields, making it a more convenient type for other components to use.\n *\n * @internal\n */\nexport type CameraKitConfiguration = CameraKitRuntimeConfiguration & CameraKitBootstrapConfiguration;\n\n/** @internal */\nexport const configurationToken = \"configuration\";\n\n/** @internal */\nexport const createCameraKitConfigurationFactory = (configuration: CameraKitBootstrapConfiguration) => {\n // always leave debug mode warning about overrides in console\n const overrides = getConfigurationOverrides();\n if (overrides) {\n console.warn(\"Configuration overrides applied\", overrides);\n }\n return Injectable(configurationToken, (): CameraKitConfiguration => {\n // We'll ensure that we handle errors on any Promises passed as config values, otherwise we either must\n // handle them separately wherever they're used, or rejections would go unhandled.\n const safeConfig: CameraKitBootstrapConfiguration = {\n ...configuration,\n lensPerformance:\n configuration.lensPerformance instanceof Promise\n ? // Safety: defaultConfiguration.lensPerformance is defined (it's hardcoded above).\n configuration.lensPerformance.catch(() => defaultConfiguration.lensPerformance!)\n : configuration.lensPerformance,\n };\n return {\n ...defaultConfiguration,\n ...copyDefinedProperties(safeConfig),\n ...copyDefinedProperties(overrides ?? {}),\n };\n });\n};\n"]}
@@ -13,6 +13,7 @@ import { operationalMetricReporterFactory } from "../metrics/operational/operati
13
13
  import { lensSourcesFactory } from "../extensions/LensSources";
14
14
  import { uriHandlersFactory } from "../extensions/UriHandlers";
15
15
  import { lensPersistenceStoreFactory } from "../lens/LensPersistenceStore";
16
+ import { cofHandlerFactory } from "../remote-configuration/cofHandler";
16
17
  import { remoteConfigurationFactory } from "../remote-configuration/remoteConfiguration";
17
18
  import { lensAssetRepositoryFactory } from "../lens/assets/LensAssetRepository";
18
19
  import { legalStateFactory } from "../legal/legalState";
@@ -51,6 +52,7 @@ export type RootServices = {
51
52
  typeof metricsEventTargetFactory,
52
53
  typeof requestStateEventTargetFactory,
53
54
  typeof cameraKitServiceFetchHandlerFactory,
55
+ typeof cofHandlerFactory,
54
56
  typeof remoteConfigurationFactory,
55
57
  typeof lensRepositoryFactory,
56
58
  typeof lensPersistenceStoreFactory,