@snap/camera-kit 0.15.1 → 0.17.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 (418) hide show
  1. package/LICENSE.md +139 -3873
  2. package/README.md +3 -3
  3. package/docs/html/assets/main.js +4 -3
  4. package/docs/html/assets/navigation.js +1 -0
  5. package/docs/html/assets/search.js +1 -1
  6. package/docs/html/assets/style.css +72 -25
  7. package/docs/html/classes/CameraKit.html +11 -196
  8. package/docs/html/classes/CameraKitSession.html +43 -366
  9. package/docs/html/classes/CameraKitSource.html +14 -223
  10. package/docs/html/classes/LensPerformanceMeasurement.html +9 -184
  11. package/docs/html/classes/LensPerformanceMetrics.html +7 -148
  12. package/docs/html/classes/LensRepository.html +17 -234
  13. package/docs/html/classes/Transform2D.html +7 -176
  14. package/docs/html/classes/TypedCustomEvent.html +4 -178
  15. package/docs/html/classes/TypedEventTarget.html +4 -209
  16. package/docs/html/enums/Lens_CameraFacing.html +5 -0
  17. package/docs/html/enums/UserData_Zodiac.html +15 -0
  18. package/docs/html/functions/ConcatInjectable.html +10 -193
  19. package/docs/html/functions/Injectable.html +9 -192
  20. package/docs/html/functions/bootstrapCameraKit.html +6 -147
  21. package/docs/html/functions/createExtension.html +6 -123
  22. package/docs/html/functions/createImageSource.html +4 -130
  23. package/docs/html/functions/createMediaStreamSource.html +4 -130
  24. package/docs/html/functions/createVideoSource.html +4 -130
  25. package/docs/html/functions/estimateLensPerformance.html +3 -120
  26. package/docs/html/functions/lensSourcesFactory.html +6 -127
  27. package/docs/html/functions/remoteApiServicesFactory.html +3 -121
  28. package/docs/html/hierarchy.html +1 -0
  29. package/docs/html/index.html +8 -165
  30. package/docs/html/interfaces/CameraKitBootstrapConfiguration.html +11 -192
  31. package/docs/html/interfaces/CameraKitDeviceOptions.html +11 -0
  32. package/docs/html/interfaces/CameraKitSourceInfo.html +9 -0
  33. package/docs/html/interfaces/CameraKitSourceSubscriber.html +3 -194
  34. package/docs/html/interfaces/ComputedFrameMetrics.html +2 -150
  35. package/docs/html/interfaces/CreateSessionOptions.html +5 -148
  36. package/docs/html/interfaces/EstimatedLensPerformance.html +3 -146
  37. package/docs/html/interfaces/FunctionSourceOptions.html +7 -0
  38. package/docs/html/interfaces/Lens.html +12 -205
  39. package/docs/html/interfaces/LensCreator.html +3 -0
  40. package/docs/html/interfaces/LensLaunchData.html +3 -179
  41. package/docs/html/interfaces/LensSource.html +3 -172
  42. package/docs/html/interfaces/LoadAssetRequest.html +13 -0
  43. package/docs/html/interfaces/MediaStreamSourceOptions.html +16 -138
  44. package/docs/html/interfaces/Preview.html +4 -141
  45. package/docs/html/interfaces/RemoteApiRequest.html +7 -162
  46. package/docs/html/interfaces/RemoteApiResponse.html +6 -155
  47. package/docs/html/interfaces/RemoteApiService.html +9 -171
  48. package/docs/html/interfaces/Snapcode.html +5 -148
  49. package/docs/html/interfaces/UriCancelRequest.html +2 -138
  50. package/docs/html/interfaces/UriRequest.html +2 -154
  51. package/docs/html/interfaces/UriResponse.html +2 -150
  52. package/docs/html/interfaces/VideoSourceOptions.html +15 -134
  53. package/docs/html/modules.html +57 -175
  54. package/docs/html/types/AssetLoader.html +5 -132
  55. package/docs/html/types/AssetResponse.html +1 -0
  56. package/docs/html/types/AssetTiming.html +2 -115
  57. package/docs/html/types/BenchmarkError.html +1 -112
  58. package/docs/html/types/BootstrapError.html +2 -115
  59. package/docs/html/types/CacheKeyNotFoundError.html +1 -112
  60. package/docs/html/types/CameraKitSessionEventListener.html +2 -115
  61. package/docs/html/types/CameraKitSessionEvents.html +2 -122
  62. package/docs/html/types/CameraKitSourceError.html +1 -112
  63. package/docs/html/types/ConfigurationError.html +2 -115
  64. package/docs/html/types/FetchHandler.html +1 -0
  65. package/docs/html/types/Keyboard.html +14 -194
  66. package/docs/html/types/KeyboardEvents.html +2 -124
  67. package/docs/html/types/LegalError.html +1 -112
  68. package/docs/html/types/LensAbortError.html +2 -115
  69. package/docs/html/types/LensAssetError.html +2 -115
  70. package/docs/html/types/LensContentValidationError.html +1 -112
  71. package/docs/html/types/LensError.html +1 -112
  72. package/docs/html/types/LensExecutionError.html +2 -115
  73. package/docs/html/types/LensImagePickerError.html +2 -115
  74. package/docs/html/types/LensLaunchParams.html +2 -0
  75. package/docs/html/types/LensMetricsEvents.html +2 -115
  76. package/docs/html/types/LensPerformanceCluster.html +1 -113
  77. package/docs/html/types/LensView.html +2 -115
  78. package/docs/html/types/LensWait.html +2 -115
  79. package/docs/html/types/Matrix.html +3 -0
  80. package/docs/html/types/PersistentStoreError.html +2 -115
  81. package/docs/html/types/PlatformNotSupportedError.html +2 -115
  82. package/docs/html/types/PublicContainer.html +2 -115
  83. package/docs/html/types/PublicServices.html +2 -0
  84. package/docs/html/types/RemoteApiCancelRequestHandler.html +2 -0
  85. package/docs/html/types/RemoteApiRequestHandler.html +2 -139
  86. package/docs/html/types/RemoteApiServices.html +1 -112
  87. package/docs/html/types/RemoteApiStatus.html +2 -115
  88. package/docs/html/types/RenderTarget.html +2 -115
  89. package/docs/html/types/Uri.html +1 -112
  90. package/docs/html/types/WebGLError.html +1 -112
  91. package/docs/html/variables/extensionRequestContext.html +2 -115
  92. package/docs/md/README.md +3 -3
  93. package/docs/md/classes/CameraKit.md +15 -15
  94. package/docs/md/classes/CameraKitSession.md +38 -38
  95. package/docs/md/classes/CameraKitSource.md +22 -30
  96. package/docs/md/classes/LensPerformanceMeasurement.md +10 -6
  97. package/docs/md/classes/LensPerformanceMetrics.md +2 -2
  98. package/docs/md/classes/LensRepository.md +18 -18
  99. package/docs/md/classes/Transform2D.md +7 -3
  100. package/docs/md/classes/TypedCustomEvent.md +10 -6
  101. package/docs/md/classes/TypedEventTarget.md +12 -8
  102. package/docs/md/enums/Lens_CameraFacing.md +36 -0
  103. package/docs/md/enums/UserData_Zodiac.md +106 -0
  104. package/docs/md/interfaces/CameraKitBootstrapConfiguration.md +2 -2
  105. package/docs/md/interfaces/CameraKitDeviceOptions.md +41 -0
  106. package/docs/md/interfaces/CameraKitSourceInfo.md +43 -0
  107. package/docs/md/interfaces/CameraKitSourceSubscriber.md +7 -7
  108. package/docs/md/interfaces/ComputedFrameMetrics.md +1 -1
  109. package/docs/md/interfaces/CreateSessionOptions.md +1 -1
  110. package/docs/md/interfaces/EstimatedLensPerformance.md +1 -1
  111. package/docs/md/interfaces/FunctionSourceOptions.md +22 -0
  112. package/docs/md/interfaces/Lens.md +4 -4
  113. package/docs/md/interfaces/LensCreator.md +17 -0
  114. package/docs/md/interfaces/LensLaunchData.md +6 -6
  115. package/docs/md/interfaces/LensSource.md +5 -5
  116. package/docs/md/interfaces/LoadAssetRequest.md +49 -0
  117. package/docs/md/interfaces/MediaStreamSourceOptions.md +46 -1
  118. package/docs/md/interfaces/Preview.md +1 -1
  119. package/docs/md/interfaces/RemoteApiRequest.md +2 -2
  120. package/docs/md/interfaces/RemoteApiResponse.md +2 -2
  121. package/docs/md/interfaces/RemoteApiService.md +1 -1
  122. package/docs/md/interfaces/Snapcode.md +1 -1
  123. package/docs/md/interfaces/UriCancelRequest.md +2 -2
  124. package/docs/md/interfaces/UriRequest.md +3 -3
  125. package/docs/md/interfaces/UriResponse.md +2 -2
  126. package/docs/md/interfaces/VideoSourceOptions.md +44 -1
  127. package/docs/md/modules.md +183 -201
  128. package/lib/CameraKit.d.ts +108 -108
  129. package/lib/CameraKit.js +1 -1
  130. package/lib/CameraKit.js.map +1 -1
  131. package/lib/bootstrapCameraKit.d.ts +4 -4
  132. package/lib/bootstrapCameraKit.js +21 -20
  133. package/lib/bootstrapCameraKit.js.map +1 -1
  134. package/lib/clients/createTsProtoClient.d.ts +5 -12
  135. package/lib/clients/createTsProtoClient.js +1 -2
  136. package/lib/clients/createTsProtoClient.js.map +1 -1
  137. package/lib/clients/grpcHandler.d.ts +7 -4
  138. package/lib/clients/grpcHandler.js +8 -5
  139. package/lib/clients/grpcHandler.js.map +1 -1
  140. package/lib/clients/lensesClient.d.ts +3 -3
  141. package/lib/clients/lensesClient.js +2 -2
  142. package/lib/clients/lensesClient.js.map +1 -1
  143. package/lib/clients/metricsClient.d.ts +26 -0
  144. package/lib/clients/metricsClient.js +120 -0
  145. package/lib/clients/metricsClient.js.map +1 -0
  146. package/lib/configuration.js +1 -1
  147. package/lib/configuration.js.map +1 -1
  148. package/lib/dependency-injection/Container.d.ts +1 -1
  149. package/lib/dependency-injection/Container.js +1 -1
  150. package/lib/dependency-injection/Container.js.map +1 -1
  151. package/lib/dependency-injection/Injectable.d.ts +6 -6
  152. package/lib/dependency-injection/Injectable.js.map +1 -1
  153. package/lib/dependency-injection/RootServices.d.ts +7 -8
  154. package/lib/dependency-injection/RootServices.js.map +1 -1
  155. package/lib/environment.d.ts +4 -0
  156. package/lib/environment.js +2 -0
  157. package/lib/environment.js.map +1 -0
  158. package/lib/extensions/RemoteApiServices.d.ts +2 -2
  159. package/lib/extensions/RemoteApiServices.js +11 -6
  160. package/lib/extensions/RemoteApiServices.js.map +1 -1
  161. package/lib/extensions/uriHandlersRegister.d.ts +4 -4
  162. package/lib/extensions/uriHandlersRegister.js +6 -6
  163. package/lib/extensions/uriHandlersRegister.js.map +1 -1
  164. package/lib/generated-proto/blizzard/cameraKitEvents.d.ts +4330 -678
  165. package/lib/generated-proto/blizzard/cameraKitEvents.js +515 -72
  166. package/lib/generated-proto/blizzard/cameraKitEvents.js.map +1 -1
  167. package/lib/generated-proto/pb_schema/camera_kit/v3/business_events.d.ts +3 -11
  168. package/lib/generated-proto/pb_schema/camera_kit/v3/business_events.js +6 -156
  169. package/lib/generated-proto/pb_schema/camera_kit/v3/business_events.js.map +1 -1
  170. package/lib/generated-proto/pb_schema/camera_kit/v3/export.d.ts +19 -19
  171. package/lib/generated-proto/pb_schema/camera_kit/v3/export.js +13 -27
  172. package/lib/generated-proto/pb_schema/camera_kit/v3/export.js.map +1 -1
  173. package/lib/generated-proto/pb_schema/camera_kit/v3/legal_prompt.d.ts +0 -6
  174. package/lib/generated-proto/pb_schema/camera_kit/v3/legal_prompt.js +2 -83
  175. package/lib/generated-proto/pb_schema/camera_kit/v3/legal_prompt.js.map +1 -1
  176. package/lib/generated-proto/pb_schema/camera_kit/v3/lens.d.ts +0 -22
  177. package/lib/generated-proto/pb_schema/camera_kit/v3/lens.js +0 -263
  178. package/lib/generated-proto/pb_schema/camera_kit/v3/lens.js.map +1 -1
  179. package/lib/generated-proto/pb_schema/camera_kit/v3/operational_metrics.d.ts +30 -34
  180. package/lib/generated-proto/pb_schema/camera_kit/v3/operational_metrics.js +7 -73
  181. package/lib/generated-proto/pb_schema/camera_kit/v3/operational_metrics.js.map +1 -1
  182. package/lib/generated-proto/pb_schema/camera_kit/v3/ranking.d.ts +0 -6
  183. package/lib/generated-proto/pb_schema/camera_kit/v3/ranking.js +0 -110
  184. package/lib/generated-proto/pb_schema/camera_kit/v3/ranking.js.map +1 -1
  185. package/lib/generated-proto/pb_schema/camera_kit/v3/service.d.ts +48 -114
  186. package/lib/generated-proto/pb_schema/camera_kit/v3/service.js +0 -225
  187. package/lib/generated-proto/pb_schema/camera_kit/v3/service.js.map +1 -1
  188. package/lib/generated-proto/pb_schema/cdp/cof/benchmark.d.ts +6 -6
  189. package/lib/generated-proto/pb_schema/cdp/cof/benchmark.js +5 -19
  190. package/lib/generated-proto/pb_schema/cdp/cof/benchmark.js.map +1 -1
  191. package/lib/generated-proto/pb_schema/cdp/cof/circumstance_service.d.ts +1422 -1422
  192. package/lib/generated-proto/pb_schema/cdp/cof/config_request.d.ts +12 -12
  193. package/lib/generated-proto/pb_schema/cdp/cof/config_request.js +10 -24
  194. package/lib/generated-proto/pb_schema/cdp/cof/config_request.js.map +1 -1
  195. package/lib/generated-proto/pb_schema/cdp/cof/config_response.d.ts +207 -207
  196. package/lib/generated-proto/pb_schema/cdp/cof/config_result.d.ts +530 -530
  197. package/lib/generated-proto/pb_schema/cdp/cof/config_result.js +10 -24
  198. package/lib/generated-proto/pb_schema/cdp/cof/config_result.js.map +1 -1
  199. package/lib/generated-proto/pb_schema/common/value.d.ts +6 -6
  200. package/lib/generated-proto/pb_schema/common/value.js +4 -18
  201. package/lib/generated-proto/pb_schema/common/value.js.map +1 -1
  202. package/lib/generated-proto/pb_schema/google/api/http.d.ts +0 -6
  203. package/lib/generated-proto/pb_schema/google/api/http.js +0 -77
  204. package/lib/generated-proto/pb_schema/google/api/http.js.map +1 -1
  205. package/lib/generated-proto/pb_schema/google/protobuf/any.d.ts +0 -2
  206. package/lib/generated-proto/pb_schema/google/protobuf/any.js +0 -44
  207. package/lib/generated-proto/pb_schema/google/protobuf/any.js.map +1 -1
  208. package/lib/generated-proto/pb_schema/google/protobuf/descriptor.d.ts +4830 -4896
  209. package/lib/generated-proto/pb_schema/google/protobuf/descriptor.js +10 -997
  210. package/lib/generated-proto/pb_schema/google/protobuf/descriptor.js.map +1 -1
  211. package/lib/generated-proto/pb_schema/google/protobuf/timestamp.d.ts +3 -5
  212. package/lib/generated-proto/pb_schema/google/protobuf/timestamp.js +6 -35
  213. package/lib/generated-proto/pb_schema/google/protobuf/timestamp.js.map +1 -1
  214. package/lib/generated-proto/pb_schema/google/protobuf/wrappers.d.ts +6 -6
  215. package/lib/generated-proto/pb_schema/google/protobuf/wrappers.js +10 -24
  216. package/lib/generated-proto/pb_schema/google/protobuf/wrappers.js.map +1 -1
  217. package/lib/generated-proto/pb_schema/lenses/launchdata.d.ts +9 -9
  218. package/lib/generated-proto/pb_schema/lenses/remote_api/remote_api_service.d.ts +11 -11
  219. package/lib/generated-proto/pb_schema/lenses/remote_api/remote_api_service.js +6 -20
  220. package/lib/generated-proto/pb_schema/lenses/remote_api/remote_api_service.js.map +1 -1
  221. package/lib/generated-proto/pb_schema/lenses/snappable.d.ts +42 -42
  222. package/lib/generated-proto/pb_schema/lenses/snappable.js +14 -28
  223. package/lib/generated-proto/pb_schema/lenses/snappable.js.map +1 -1
  224. package/lib/generated-proto/pb_schema/lenses/user_data.d.ts +8 -8
  225. package/lib/generated-proto/pb_schema/lenses/user_data.js +8 -22
  226. package/lib/generated-proto/pb_schema/lenses/user_data.js.map +1 -1
  227. package/lib/handlers/defaultFetchHandler.d.ts +1 -1
  228. package/lib/handlers/defaultFetchHandler.js.map +1 -1
  229. package/lib/handlers/requestStateEmittingHandler.d.ts +5 -6
  230. package/lib/handlers/requestStateEmittingHandler.js +6 -8
  231. package/lib/handlers/requestStateEmittingHandler.js.map +1 -1
  232. package/lib/handlers/responseCachingHandler.d.ts +9 -10
  233. package/lib/handlers/responseCachingHandler.js +9 -3
  234. package/lib/handlers/responseCachingHandler.js.map +1 -1
  235. package/lib/handlers/utils.d.ts +12 -0
  236. package/lib/handlers/utils.js +19 -0
  237. package/lib/handlers/utils.js.map +1 -0
  238. package/lib/index.d.ts +21 -15
  239. package/lib/index.js +17 -12
  240. package/lib/index.js.map +1 -1
  241. package/lib/lens/Lens.d.ts +12 -2
  242. package/lib/lens/Lens.js +5 -0
  243. package/lib/lens/Lens.js.map +1 -1
  244. package/lib/lens/LensLaunchData.d.ts +6 -3
  245. package/lib/lens/LensLaunchData.js +2 -0
  246. package/lib/lens/LensLaunchData.js.map +1 -1
  247. package/lib/lens/LensPersistenceStore.d.ts +1 -1
  248. package/lib/lens/LensPersistenceStore.js +1 -1
  249. package/lib/lens/LensPersistenceStore.js.map +1 -1
  250. package/lib/lens/LensRepository.d.ts +5 -1
  251. package/lib/lens/LensRepository.js +9 -5
  252. package/lib/lens/LensRepository.js.map +1 -1
  253. package/lib/lens/LensSource.d.ts +2 -2
  254. package/lib/lens/LensSource.js +4 -4
  255. package/lib/lens/LensSource.js.map +1 -1
  256. package/lib/lens/assets/LensAssetRepository.d.ts +35 -4
  257. package/lib/lens/assets/LensAssetRepository.js +9 -9
  258. package/lib/lens/assets/LensAssetRepository.js.map +1 -1
  259. package/lib/lens/assets/LensAssetsProvider.d.ts +1 -1
  260. package/lib/lens/assets/LensAssetsProvider.js +9 -4
  261. package/lib/lens/assets/LensAssetsProvider.js.map +1 -1
  262. package/lib/lens/assets/deviceDependentAssetLoader.js +3 -2
  263. package/lib/lens/assets/deviceDependentAssetLoader.js.map +1 -1
  264. package/lib/lens/assets/remoteMediaAssetLoaderFactory.js +4 -3
  265. package/lib/lens/assets/remoteMediaAssetLoaderFactory.js.map +1 -1
  266. package/lib/lens/assets/staticAssetLoader.js +5 -4
  267. package/lib/lens/assets/staticAssetLoader.js.map +1 -1
  268. package/lib/lens/cameraKitLensSource.d.ts +3 -2
  269. package/lib/lens/cameraKitLensSource.js +87 -42
  270. package/lib/lens/cameraKitLensSource.js.map +1 -1
  271. package/lib/lens/fetchWatermarkLens.d.ts +11 -0
  272. package/lib/lens/fetchWatermarkLens.js +27 -0
  273. package/lib/lens/fetchWatermarkLens.js.map +1 -0
  274. package/lib/lens-client-interface/imagePicker.d.ts +2 -1
  275. package/lib/lens-client-interface/imagePicker.js.map +1 -1
  276. package/lib/lens-client-interface/lensClientInterface.d.ts +1 -1
  277. package/lib/lens-client-interface/lensClientInterface.js +1 -1
  278. package/lib/lens-client-interface/lensClientInterface.js.map +1 -1
  279. package/lib/lens-core-module/lensCore.d.ts +2 -1
  280. package/lib/lens-core-module/lensCore.js.map +1 -1
  281. package/lib/lens-core-module/loader/bootstrapURLs.d.ts +12 -0
  282. package/lib/lens-core-module/loader/bootstrapURLs.js +48 -0
  283. package/lib/lens-core-module/loader/bootstrapURLs.js.map +1 -0
  284. package/lib/lens-core-module/loader/lensCoreFactory.d.ts +0 -12
  285. package/lib/lens-core-module/loader/lensCoreFactory.js +4 -49
  286. package/lib/lens-core-module/loader/lensCoreFactory.js.map +1 -1
  287. package/lib/lensCoreWasmVersions.d.ts +6 -0
  288. package/lib/lensCoreWasmVersions.js +6 -0
  289. package/lib/lensCoreWasmVersions.js.map +1 -0
  290. package/lib/media-sources/CameraKitSource.d.ts +39 -17
  291. package/lib/media-sources/CameraKitSource.js +8 -2
  292. package/lib/media-sources/CameraKitSource.js.map +1 -1
  293. package/lib/media-sources/FunctionSource.d.ts +15 -4
  294. package/lib/media-sources/FunctionSource.js +1 -2
  295. package/lib/media-sources/FunctionSource.js.map +1 -1
  296. package/lib/media-sources/ImageSource.d.ts +3 -5
  297. package/lib/media-sources/ImageSource.js +1 -3
  298. package/lib/media-sources/ImageSource.js.map +1 -1
  299. package/lib/media-sources/MediaStreamSource.d.ts +17 -33
  300. package/lib/media-sources/MediaStreamSource.js +6 -41
  301. package/lib/media-sources/MediaStreamSource.js.map +1 -1
  302. package/lib/media-sources/VideoSource.d.ts +14 -10
  303. package/lib/media-sources/VideoSource.js +5 -11
  304. package/lib/media-sources/VideoSource.js.map +1 -1
  305. package/lib/metrics/businessEventsReporter.d.ts +3 -4
  306. package/lib/metrics/businessEventsReporter.js +11 -55
  307. package/lib/metrics/businessEventsReporter.js.map +1 -1
  308. package/lib/metrics/operational/Count.d.ts +2 -0
  309. package/lib/metrics/operational/Count.js +6 -1
  310. package/lib/metrics/operational/Count.js.map +1 -1
  311. package/lib/metrics/operational/Histogram.d.ts +1 -1
  312. package/lib/metrics/operational/Histogram.js +7 -3
  313. package/lib/metrics/operational/Histogram.js.map +1 -1
  314. package/lib/metrics/operational/Metric.js +2 -0
  315. package/lib/metrics/operational/Metric.js.map +1 -1
  316. package/lib/metrics/operational/Timer.d.ts +9 -6
  317. package/lib/metrics/operational/Timer.js +12 -26
  318. package/lib/metrics/operational/Timer.js.map +1 -1
  319. package/lib/metrics/reporters/reportBenchmarks.d.ts +3 -3
  320. package/lib/metrics/reporters/reportBenchmarks.js +6 -5
  321. package/lib/metrics/reporters/reportBenchmarks.js.map +1 -1
  322. package/lib/metrics/reporters/reportGlobalException.d.ts +4 -4
  323. package/lib/metrics/reporters/reportGlobalException.js +13 -11
  324. package/lib/metrics/reporters/reportGlobalException.js.map +1 -1
  325. package/lib/metrics/reporters/reportHttpMetrics.d.ts +3 -3
  326. package/lib/metrics/reporters/reportHttpMetrics.js +19 -16
  327. package/lib/metrics/reporters/reportHttpMetrics.js.map +1 -1
  328. package/lib/metrics/reporters/reportLegalState.d.ts +3 -3
  329. package/lib/metrics/reporters/reportLegalState.js +7 -9
  330. package/lib/metrics/reporters/reportLegalState.js.map +1 -1
  331. package/lib/metrics/reporters/reportLensAndAssetDownload.d.ts +3 -3
  332. package/lib/metrics/reporters/reportLensAndAssetDownload.js +12 -12
  333. package/lib/metrics/reporters/reportLensAndAssetDownload.js.map +1 -1
  334. package/lib/metrics/reporters/reportLensView.d.ts +3 -3
  335. package/lib/metrics/reporters/reportLensView.js +6 -6
  336. package/lib/metrics/reporters/reportLensView.js.map +1 -1
  337. package/lib/metrics/reporters/reportLensWait.d.ts +2 -3
  338. package/lib/metrics/reporters/reportLensWait.js +1 -3
  339. package/lib/metrics/reporters/reportLensWait.js.map +1 -1
  340. package/lib/metrics/reporters/reportPlatformCapabilities.d.ts +3 -3
  341. package/lib/metrics/reporters/reportPlatformCapabilities.js +6 -5
  342. package/lib/metrics/reporters/reportPlatformCapabilities.js.map +1 -1
  343. package/lib/metrics/reporters/reportUserSession.js +3 -3
  344. package/lib/metrics/reporters/reportUserSession.js.map +1 -1
  345. package/lib/metrics/reporters/reporters.d.ts +2 -2
  346. package/lib/namedErrors.d.ts +1 -1
  347. package/lib/namedErrors.js +1 -1
  348. package/lib/namedErrors.js.map +1 -1
  349. package/lib/observable-operators/unsubscribed.d.ts +1 -1
  350. package/lib/observable-operators/unsubscribed.js +1 -1
  351. package/lib/observable-operators/unsubscribed.js.map +1 -1
  352. package/lib/platform/platformCapabilities.d.ts +1 -1
  353. package/lib/platform/platformCapabilities.js +9 -3
  354. package/lib/platform/platformCapabilities.js.map +1 -1
  355. package/lib/platform/platformInfo.d.ts +1 -0
  356. package/lib/platform/platformInfo.js +3 -3
  357. package/lib/platform/platformInfo.js.map +1 -1
  358. package/lib/remote-configuration/cofHandler.d.ts +3 -3
  359. package/lib/remote-configuration/cofHandler.js +6 -4
  360. package/lib/remote-configuration/cofHandler.js.map +1 -1
  361. package/lib/remote-configuration/preloadConfiguration.d.ts +1 -1
  362. package/lib/remote-configuration/preloadConfiguration.js +9 -4
  363. package/lib/remote-configuration/preloadConfiguration.js.map +1 -1
  364. package/lib/remote-configuration/remoteConfiguration.d.ts +7 -6
  365. package/lib/remote-configuration/remoteConfiguration.js +18 -15
  366. package/lib/remote-configuration/remoteConfiguration.js.map +1 -1
  367. package/lib/session/CameraKitSession.d.ts +8 -8
  368. package/lib/session/CameraKitSession.js +11 -9
  369. package/lib/session/CameraKitSession.js.map +1 -1
  370. package/lib/session/LensKeyboard.d.ts +1 -7
  371. package/lib/session/LensKeyboard.js.map +1 -1
  372. package/lib/session/LensPerformanceMeasurement.d.ts +1 -1
  373. package/lib/session/LensPerformanceMeasurement.js +3 -3
  374. package/lib/session/LensPerformanceMeasurement.js.map +1 -1
  375. package/lib/session/LensPerformanceMetrics.d.ts +1 -1
  376. package/lib/session/LensPerformanceMetrics.js.map +1 -1
  377. package/lib/session/lensState.d.ts +5 -4
  378. package/lib/session/lensState.js +80 -57
  379. package/lib/session/lensState.js.map +1 -1
  380. package/lib/transforms/Transform2D.d.ts +8 -3
  381. package/lib/transforms/Transform2D.js +1 -1
  382. package/lib/transforms/Transform2D.js.map +1 -1
  383. package/lib/utils.d.ts +3 -0
  384. package/lib/utils.js +4 -0
  385. package/lib/utils.js.map +1 -0
  386. package/package.json +27 -6
  387. package/docs/html/functions/createUserMediaSource.html +0 -138
  388. package/docs/html/functions/getRequiredBootstrapURLs.html +0 -130
  389. package/docs/html/types/CameraKitDeviceInfo.html +0 -125
  390. package/docs/html/types/CameraKitDeviceOptions.html +0 -120
  391. package/docs/html/types/CameraKitSourceInfo.html +0 -112
  392. package/docs/html/types/CameraKitSourceOptions.html +0 -118
  393. package/lib/common/index.d.ts +0 -2
  394. package/lib/common/index.js +0 -3
  395. package/lib/common/index.js.map +0 -1
  396. package/lib/environment.json +0 -1
  397. package/lib/handlers/index.d.ts +0 -2
  398. package/lib/handlers/index.js +0 -3
  399. package/lib/handlers/index.js.map +0 -1
  400. package/lib/lens-core-module/index.d.ts +0 -3
  401. package/lib/lens-core-module/index.js +0 -4
  402. package/lib/lens-core-module/index.js.map +0 -1
  403. package/lib/lens-core-module/loader/index.d.ts +0 -1
  404. package/lib/lens-core-module/loader/index.js +0 -2
  405. package/lib/lens-core-module/loader/index.js.map +0 -1
  406. package/lib/lensCoreWasmVersions.json +0 -5
  407. package/lib/metrics/metricsHandler.d.ts +0 -10
  408. package/lib/metrics/metricsHandler.js +0 -13
  409. package/lib/metrics/metricsHandler.js.map +0 -1
  410. package/lib/metrics/operational/operationalMetricsReporter.d.ts +0 -64
  411. package/lib/metrics/operational/operationalMetricsReporter.js +0 -144
  412. package/lib/metrics/operational/operationalMetricsReporter.js.map +0 -1
  413. package/lib/session/index.d.ts +0 -1
  414. package/lib/session/index.js +0 -2
  415. package/lib/session/index.js.map +0 -1
  416. package/lib/transforms/index.d.ts +0 -1
  417. package/lib/transforms/index.js +0 -2
  418. package/lib/transforms/index.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"Container.js","sourceRoot":"","sources":["../../src/dependency-injection/Container.ts"],"names":[],"mappings":"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","sourcesContent":["import { isMemoized, memoize, Memoized } from \"../common/memoize\";\nimport { PartialContainer } from \"./PartialContainer\";\nimport { AddService, InjectableFunction, ValidTokens } from \"./types\";\n\ntype MaybeMemoizedFactories<Services> = {\n [K in keyof Services]:\n | ((c: Container<Services>) => Services[K])\n | Memoized<(c: Container<Services>) => Services[K]>;\n};\n\nexport type Factories<Services> = {\n [K in keyof Services]: Memoized<(c: Container<Services>) => Services[K]>;\n};\n\nexport const CONTAINER = \"$container\";\nexport type ContainerToken = typeof CONTAINER;\n\n/**\n * A Container of values, indexed each by a unique token, which can be used throughout CameraKit. This is how CameraKit\n * implements simple dependency injection.\n *\n * Dependency injection is a way to decouple the *use* of a dependency from the *creation* of that dependency. This\n * improves modularity and re-usability, since components only care about the *interfaces* of dependencies (since that\n * determines their use) and not about their concrete creation. New implementations of a particular dependency may be\n * provided without the need to change any of the consumers of that dependency.\n *\n * There are a few commonly-used terms used when talking about dependency injection:\n *\n * - Container (or Injector): Maintains a registry of all available Services and understands how to create them.\n * - Service: Anything that can be provided by the Container is called a Service – this can be a value of any type.\n * - Token: Each Service is associated with a unique name, or Token. In order to obtain a Service from the Container,\n * the consumer must provide the Token corresponding to that Service.\n * - InjectableFunction: Services are created by InjectableFunctions. When adding a Service to a Container, the\n * Service provider gives the Container a InjectableFunction which, when called will return the Service. These\n * InjectableFunctions may themselves use other Services, which will be passed to them as arguments.\n *\n * Services are, by default, singletons – that is, each call to `get()` a particular Service will return a reference\n * to the same value. In other words, InjectableFunctions are only invoked once. If multiple instances of a Service are\n * desired, a new Container can be created using the `copy([Token])` method – passing a Token to this method forces the\n * new Container to recreate the corresponding Service (the InjectableFunction will be invoked again). We say that the\n * Service is then \"scoped\" to the new Container.\n *\n *\n * One common downside of many dependency injection implementations is that the dependency graph formed by the various\n * Services can only be validated at runtime. That is, if a dependency is missing or a circular dependency is found, the\n * developer must wait until runtime to discover the error. These errors can often be confusing and hard to debug.\n *\n * This implementation eliminates this issue by moving these sorts of errors to compile time. If an unknown dependency\n * is used in a InjectableFunction, for example, the code simply won't compile.\n *\n * To achieve this, we do lose the ability to implicitly define the dependency graph, as is common with many dependency\n * injection frameworks that employ decorators to define Services and their dependencies. Instead, the dependency graph\n * must be constructed explicitly, step-by-step, via successive calls to the `provide()` method. This is a suitable\n * trade-off for CameraKit, as there are a relatively small number of Services.\n *\n * Here's a simple example of Container usage:\n * ```ts\n * const fooFactory = Injectable('Foo', () => new Foo())\n * const barFactory = Injectable('Bar', ['Foo'] as const, (foo: Foo) => new Bar(foo))\n * const container = Container.empy()\n * .provide(fooFactory)\n * .provide(barFactory)\n *\n * const bar: Bar = container.get('Bar')\n * ```\n */\n/** @internal */\nexport class Container<Services = {}> {\n /**\n * Create a new [Container] by providing a [PartialContainer] that has no dependencies.\n */\n static provides<Services>(container: PartialContainer<Services, {}> | Container<Services>): Container<Services>;\n\n /**\n * Create a new [Container] by providing a Service that has no dependencies.\n */\n static provides<Token extends string, Service>(\n fn: InjectableFunction<{}, [], Token, Service>\n ): Container<AddService<{}, Token, Service>>;\n\n static provides(\n fnOrContainer: InjectableFunction<{}, [], string, any> | PartialContainer<any, {}> | Container<any>\n ): Container<any> {\n // Although the `provides` method has overloads that match both members of the union type separately, it does\n // not match the union type itself, so the compiler forces us to branch and handle each type within the union\n // separately. (Maybe in the future the compiler will decide to infer this, but for now this is necessary.)\n if (fnOrContainer instanceof PartialContainer) return new Container({}).provides(fnOrContainer);\n if (fnOrContainer instanceof Container) return new Container({}).provides(fnOrContainer);\n return new Container({}).provides(fnOrContainer);\n }\n\n private readonly factories: Factories<Services>;\n\n constructor(factories: MaybeMemoizedFactories<Services>) {\n this.factories = {} as Factories<Services>;\n for (const k in factories) {\n const fn = factories[k];\n if (isMemoized(fn)) this.factories[k] = fn;\n else this.factories[k] = memoize(fn);\n }\n }\n\n /**\n * Create a copy of this Container, optionally providing a list of Services which will be scoped to the copy.\n *\n * This can be useful, for example, if different parts of an application wish to use the same Service interface, but\n * do not want to share a reference to same Service instance.\n *\n * Say we have a Service which manages a list of Users. Our application wishes to display two lists of Users, which\n * may be edited independently. In this case it may be desirable to create a Container for each list component, with\n * the UserList Service scoped to those Containers – that way, each list component gets a unique copy of the\n * UserList Service that can be edited independently of the other.\n *\n * @param scopedServices A list of Tokens identifying Services which will be scoped to the new Container – that is,\n * if those Services had already been created by the source Container, they will be re-created by their Factory\n * functions when provided by the new Container.\n * @returns A new copy of this Container, sharing all of this Container's Services. Services corresponding to any\n * Tokens passed to this method will be re-created by the new Container (i.e. they become \"scoped\" to the new\n * Container).\n */\n copy<Tokens extends readonly (keyof Services)[]>(scopedServices?: Tokens): Container<Services> {\n const factories: MaybeMemoizedFactories<Services> = { ...this.factories };\n\n // We \"un-memoize\" scoped Service InjectableFunctions so they will create a new copy of their Service when\n // provided by the new Container – we re-memoize them so the new Container will itself only create one Service\n // instance.\n (scopedServices || []).forEach((token: keyof Services) => {\n factories[token] = this.factories[token].delegate;\n });\n return new Container(factories);\n }\n\n /**\n * Gets a reference to this Container.\n *\n * @param token The CONTAINER token.\n * @returns This Container.\n */\n get(token: ContainerToken): this;\n\n /**\n * Get a specific Service provided by this Container.\n *\n * @param token A unique string corresponding to a Service\n * @returns A Service corresponding to the given Token.\n */\n get<Token extends keyof Services>(token: Token): Services[Token];\n\n get(token: ContainerToken | keyof Services): this | Services[keyof Services] {\n if (token === CONTAINER) return this;\n const factory = this.factories[token];\n if (!factory) {\n throw new Error(\n `[Container::get] Could not find Service for Token \"${String(token)}\". This should've caused a ` +\n \"compile-time error. If the Token is 'undefined', check all your calls to the Injectable \" +\n \"function. Make sure you define dependencies using string literals or string constants that are \" +\n \"definitely initialized before the call to Injectable.\"\n );\n }\n return factory(this);\n }\n\n /**\n * Run the services in this [PartialContainer]. \"Run\" simply means that [Container::get] will be called for each\n * Service, which invokes that Service's factory function, creating the Service.\n *\n * This may be useful e.g. if services need to initialize themselves, since generally a Service factory is only\n * invoked when the Service is needed.\n *\n * Note this method cannot be used to add services to a Container. – that is, calling this method does not provide\n * the services in a new Container.\n *\n * @param container Optionally provide a [PartialContainer], which will be used as a filter – the only services\n * from *this* container that will run are those with a token that is also present in this PartialContainer.\n * @returns No mutation is done to the Container, it is returned as-is (convenient for chaining).\n */\n run<AdditionalServices, Dependencies, FulfilledDependencies extends Dependencies>(\n // FullfilledDependencies is assignable to Dependencies -- by specifying Container<FulfilledDependencies> as the\n // `this` type, we ensure this Container can provide all the Dependencies required by the PartialContainer.\n this: Container<FulfilledDependencies>,\n container: PartialContainer<AdditionalServices, Dependencies>\n ): this;\n\n /**\n * Run the given Service. \"Run\" simply means that [Container::get] will be called for this Service, which invokes\n * the Service's factory function, creating the Service.\n *\n * This may be useful e.g. if services need to initialize themselves, since generally a Service factory is only\n * invoked when the Service is needed.\n *\n * Note this method cannot be used to add services to a Container. – that is, calling this method does not provide\n * the services in a new Container.\n *\n * @param fn Optionally provide an [InjectableFunction], which will be used as a filter – the only services\n * from *this* container that will run are those with a token that is also present in this PartialContainer.\n * @returns No mutation is done to the Container, it is returned as-is (convenient for chaining).\n */\n run<Token extends string, Tokens extends readonly ValidTokens<Services>[], Service>(\n fn: InjectableFunction<Services, Tokens, Token, Service>\n ): this;\n\n run<Token extends string, Tokens extends readonly ValidTokens<Services>[], Service, AdditionalServices>(\n fnOrContainer:\n | InjectableFunction<Services, Tokens, Token, Service>\n | PartialContainer<AdditionalServices, Services>\n ): this {\n if (fnOrContainer instanceof PartialContainer) {\n const runnableContainer = this.provides(fnOrContainer);\n for (const token of fnOrContainer.getTokens()) {\n runnableContainer.get(token);\n }\n } else {\n this.provides(fnOrContainer).get(fnOrContainer.token);\n }\n return this;\n }\n\n /**\n * Create a new Container from this Container with additional services from a given [PartialContainer].\n *\n * Services in the provided PartialContainer take precedence if there are service token conflicts.\n *\n * Services from the provided PartialContainer become scoped to the new Container – that is, if PartialContainer A\n * is provided to Container X and Container Y, each resultant Container will contain its own copy of the services\n * from PartialContainer A.\n *\n * @param container A [PartialContainer] providing additional services.\n */\n provides<AdditionalServices, Dependencies, FulfilledDependencies extends Dependencies>(\n // FullfilledDependencies is assignable to Dependencies -- by specifying Container<FulfilledDependencies> as the\n // `this` type, we ensure this Container can provide all the Dependencies required by the PartialContainer.\n this: Container<FulfilledDependencies>,\n container: PartialContainer<AdditionalServices, Dependencies>\n ): Container<Services & AdditionalServices>;\n\n /**\n * Creates a new Container from this Container with additional services from another Container.\n *\n * Services in the provided PartialContainer take precedence if there are service token conflicts.\n *\n * Services from the provided Container become scoped to both Containers (the one from which they were provided\n * and the new Container returned by this method) - that is, if Container A is provided to Container B,\n * they will share the same instances of any Services provided by Container A.\n * If Container B should re-create new instances of the Services from Container A,\n * Container A must first be copied before providing it here.\n *\n * @param container A [Container] providing additional services.\n */\n provides<AdditionalServices>(container: Container<AdditionalServices>): Container<Services & AdditionalServices>;\n\n /**\n * Create a new Container which provides a Service created by the given [InjectableFunction].\n *\n * The InjectableFunction contains metadata specifying the Token by which the created Service will be known, as well\n * as an ordered list of Tokens to be resolved and provided to the InjectableFunction as arguments.\n *\n * If any of these required dependencies are missing from the Container (or if there is a mismatch between the types\n * of those dependencies and the arguments of the InjectableFunction), a compiler error will be raised.\n *\n * @param fn A factory function, taking dependencies as arguments, which returns the Service.\n */\n provides<Token extends string, Tokens extends readonly ValidTokens<Services>[], Service>(\n fn: InjectableFunction<Services, Tokens, Token, Service>\n ): Container<AddService<Services, Token, Service>>;\n\n provides<Token extends string, Tokens extends readonly ValidTokens<Services>[], Service, AdditionalServices>(\n fnOrContainer:\n | InjectableFunction<Services, Tokens, Token, Service>\n | PartialContainer<AdditionalServices, Services>\n | Container<AdditionalServices>\n ): Container<any> {\n if (fnOrContainer instanceof PartialContainer || fnOrContainer instanceof Container) {\n const factories =\n fnOrContainer instanceof PartialContainer ? fnOrContainer.getFactories(this) : fnOrContainer.factories;\n // Safety: `this.factories` and `factories` are both properly type checked, so merging them produces\n // a Factories object with keys from both Services and AdditionalServices. The compiler is unable to\n // infer that Factories<A> & Factories<B> == Factories<A & B>, so the cast is required.\n return new Container({\n ...this.factories,\n ...factories,\n } as unknown as MaybeMemoizedFactories<Services & AdditionalServices>);\n }\n return this.providesService(fnOrContainer);\n }\n\n private providesService<Token extends string, Tokens extends readonly ValidTokens<Services>[], Service>(\n fn: InjectableFunction<Services, Tokens, Token, Service>\n ): Container<AddService<Services, Token, Service>> {\n const token = fn.token;\n const dependencies: readonly any[] = fn.dependencies;\n\n const factory = memoize((container: Container<Services>) => {\n return fn(\n ...(dependencies.map((t) => {\n // To support overwriting an already-existing service with a new implementation, it should be\n // possibleto do `provide(A, [A], a => createNewServiceFromOld(a))` – that is, inject a dependency\n // with the same token as this service's token.\n //\n // To avoid a circular dependency (in which the factory for service A depends on itself), we always\n // use the service defined in the *parent* container (i.e. this) when injecting a dependency with\n // the same token as the service we're providing. If we did not do this, calling `container.get(t)`\n // would result in an infinite loop.\n return t === token ? this.get(t) : container.get(t);\n }) as any)\n );\n });\n\n // Safety: `token` and `factory` are property type checked, so extending `this.factories` produces a\n // MaybeMemoizedFactories object with the expected set of services – but when using the spread operation to\n // merge two objects, the compiler widens the Token type to string. So we must re-narrow via casting.\n const factories = { ...this.factories, [token]: factory };\n return new Container(factories as unknown as MaybeMemoizedFactories<AddService<Services, Token, Service>>);\n }\n}\n"]}
1
+ {"version":3,"file":"Container.js","sourceRoot":"","sources":["../../src/dependency-injection/Container.ts"],"names":[],"mappings":"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","sourcesContent":["import { isMemoized, memoize, Memoized } from \"../common/memoize\";\nimport { PartialContainer } from \"./PartialContainer\";\nimport { AddService, InjectableFunction, ValidTokens } from \"./types\";\n\ntype MaybeMemoizedFactories<Services> = {\n [K in keyof Services]:\n | ((c: Container<Services>) => Services[K])\n | Memoized<(c: Container<Services>) => Services[K]>;\n};\n\nexport type Factories<Services> = {\n // We'd like the Container type constructor to be covariant -- if type A ≤ B (that is, if A is more\n // specific than B), we would like Container<A> ≤ Container<B>.\n //\n // But here in this Factories type (which is used to type the `factories` property of Container), we want to use\n // our type variable in *both* a covariant and contravariant position -- we use the keys of Services as the index\n // type (covariant), but we also want to use Container<Services> as the argument of the factory function\n // (contravariant).\n //\n // This would result the Container type (by virtue of containing the `factories` property) being *invariant* -- that\n // is, only if types A and B are each assignable to the other will Container<B> be assignable to Container<A>.\n //\n // To avoid this, we use Container<any> in the contravariant position -- that way the Services type variable is only\n // used in covariant position and our Container type constructor remains covariant.\n //\n // Safety: this does mean that calling the factory function (as is done in `Container.get()`) is not type safe.\n // But we only use this type as a private property of Container, which still type checks the constructor argument\n // used to populate the `factories` property. So there's no way we can end up with a `factories` property containing\n // functions which require Services not provided by the Container.\n [K in keyof Services]: Memoized<(c: Container<any>) => Services[K]>;\n};\n\nexport const CONTAINER = \"$container\";\nexport type ContainerToken = typeof CONTAINER;\n\n/**\n * A Container of values, indexed each by a unique token, which can be used throughout CameraKit. This is how CameraKit\n * implements simple dependency injection.\n *\n * Dependency injection is a way to decouple the *use* of a dependency from the *creation* of that dependency. This\n * improves modularity and re-usability, since components only care about the *interfaces* of dependencies (since that\n * determines their use) and not about their concrete creation. New implementations of a particular dependency may be\n * provided without the need to change any of the consumers of that dependency.\n *\n * There are a few commonly-used terms used when talking about dependency injection:\n *\n * - Container (or Injector): Maintains a registry of all available Services and understands how to create them.\n * - Service: Anything that can be provided by the Container is called a Service – this can be a value of any type.\n * - Token: Each Service is associated with a unique name, or Token. In order to obtain a Service from the Container,\n * the consumer must provide the Token corresponding to that Service.\n * - InjectableFunction: Services are created by InjectableFunctions. When adding a Service to a Container, the\n * Service provider gives the Container a InjectableFunction which, when called will return the Service. These\n * InjectableFunctions may themselves use other Services, which will be passed to them as arguments.\n *\n * Services are, by default, singletons – that is, each call to `get()` a particular Service will return a reference\n * to the same value. In other words, InjectableFunctions are only invoked once. If multiple instances of a Service are\n * desired, a new Container can be created using the `copy([Token])` method – passing a Token to this method forces the\n * new Container to recreate the corresponding Service (the InjectableFunction will be invoked again). We say that the\n * Service is then \"scoped\" to the new Container.\n *\n *\n * One common downside of many dependency injection implementations is that the dependency graph formed by the various\n * Services can only be validated at runtime. That is, if a dependency is missing or a circular dependency is found, the\n * developer must wait until runtime to discover the error. These errors can often be confusing and hard to debug.\n *\n * This implementation eliminates this issue by moving these sorts of errors to compile time. If an unknown dependency\n * is used in a InjectableFunction, for example, the code simply won't compile.\n *\n * To achieve this, we do lose the ability to implicitly define the dependency graph, as is common with many dependency\n * injection frameworks that employ decorators to define Services and their dependencies. Instead, the dependency graph\n * must be constructed explicitly, step-by-step, via successive calls to the `provide()` method. This is a suitable\n * trade-off for CameraKit, as there are a relatively small number of Services.\n *\n * Here's a simple example of Container usage:\n * ```ts\n * const fooFactory = Injectable('Foo', () => new Foo())\n * const barFactory = Injectable('Bar', ['Foo'] as const, (foo: Foo) => new Bar(foo))\n * const container = Container.empy()\n * .provide(fooFactory)\n * .provide(barFactory)\n *\n * const bar: Bar = container.get('Bar')\n * ```\n */\n/** @internal */\nexport class Container<Services = {}> {\n /**\n * Create a new [Container] by providing a [PartialContainer] that has no dependencies.\n */\n static provides<Services>(container: PartialContainer<Services, {}> | Container<Services>): Container<Services>;\n\n /**\n * Create a new [Container] by providing a Service that has no dependencies.\n */\n static provides<Token extends string, Service>(\n fn: InjectableFunction<{}, [], Token, Service>\n ): Container<AddService<{}, Token, Service>>;\n\n static provides(\n fnOrContainer: InjectableFunction<{}, [], string, any> | PartialContainer<any, {}> | Container<any>\n ): Container<any> {\n // Although the `provides` method has overloads that match both members of the union type separately, it does\n // not match the union type itself, so the compiler forces us to branch and handle each type within the union\n // separately. (Maybe in the future the compiler will decide to infer this, but for now this is necessary.)\n if (fnOrContainer instanceof PartialContainer) return new Container({}).provides(fnOrContainer);\n if (fnOrContainer instanceof Container) return new Container({}).provides(fnOrContainer);\n return new Container({}).provides(fnOrContainer);\n }\n\n private readonly factories: Factories<Services>;\n\n constructor(factories: MaybeMemoizedFactories<Services>) {\n this.factories = {} as Factories<Services>;\n for (const k in factories) {\n const fn = factories[k];\n if (isMemoized(fn)) this.factories[k] = fn;\n else this.factories[k] = memoize(fn);\n }\n }\n\n /**\n * Create a copy of this Container, optionally providing a list of Services which will be scoped to the copy.\n *\n * This can be useful, for example, if different parts of an application wish to use the same Service interface, but\n * do not want to share a reference to same Service instance.\n *\n * Say we have a Service which manages a list of Users. Our application wishes to display two lists of Users, which\n * may be edited independently. In this case it may be desirable to create a Container for each list component, with\n * the UserList Service scoped to those Containers – that way, each list component gets a unique copy of the\n * UserList Service that can be edited independently of the other.\n *\n * @param scopedServices A list of Tokens identifying Services which will be scoped to the new Container – that is,\n * if those Services had already been created by the source Container, they will be re-created by their Factory\n * functions when provided by the new Container.\n * @returns A new copy of this Container, sharing all of this Container's Services. Services corresponding to any\n * Tokens passed to this method will be re-created by the new Container (i.e. they become \"scoped\" to the new\n * Container).\n */\n copy<Tokens extends readonly (keyof Services)[]>(scopedServices?: Tokens): Container<Services> {\n const factories: MaybeMemoizedFactories<Services> = { ...this.factories };\n\n // We \"un-memoize\" scoped Service InjectableFunctions so they will create a new copy of their Service when\n // provided by the new Container – we re-memoize them so the new Container will itself only create one Service\n // instance.\n (scopedServices || []).forEach((token: keyof Services) => {\n factories[token] = this.factories[token].delegate;\n });\n return new Container(factories);\n }\n\n /**\n * Gets a reference to this Container.\n *\n * @param token The CONTAINER token.\n * @returns This Container.\n */\n get(token: ContainerToken): this;\n\n /**\n * Get a specific Service provided by this Container.\n *\n * @param token A unique string corresponding to a Service\n * @returns A Service corresponding to the given Token.\n */\n get<Token extends keyof Services>(token: Token): Services[Token];\n\n get(token: ContainerToken | keyof Services): this | Services[keyof Services] {\n if (token === CONTAINER) return this;\n const factory = this.factories[token];\n if (!factory) {\n throw new Error(\n `[Container::get] Could not find Service for Token \"${String(token)}\". This should've caused a ` +\n \"compile-time error. If the Token is 'undefined', check all your calls to the Injectable \" +\n \"function. Make sure you define dependencies using string literals or string constants that are \" +\n \"definitely initialized before the call to Injectable.\"\n );\n }\n return factory(this);\n }\n\n /**\n * Run the services in this [PartialContainer]. \"Run\" simply means that [Container::get] will be called for each\n * Service, which invokes that Service's factory function, creating the Service.\n *\n * This may be useful e.g. if services need to initialize themselves, since generally a Service factory is only\n * invoked when the Service is needed.\n *\n * Note this method cannot be used to add services to a Container. – that is, calling this method does not provide\n * the services in a new Container.\n *\n * @param container Optionally provide a [PartialContainer], which will be used as a filter – the only services\n * from *this* container that will run are those with a token that is also present in this PartialContainer.\n * @returns No mutation is done to the Container, it is returned as-is (convenient for chaining).\n */\n run<AdditionalServices, Dependencies, FulfilledDependencies extends Dependencies>(\n // FullfilledDependencies is assignable to Dependencies -- by specifying Container<FulfilledDependencies> as the\n // `this` type, we ensure this Container can provide all the Dependencies required by the PartialContainer.\n this: Container<FulfilledDependencies>,\n container: PartialContainer<AdditionalServices, Dependencies>\n ): this;\n\n /**\n * Run the given Service. \"Run\" simply means that [Container::get] will be called for this Service, which invokes\n * the Service's factory function, creating the Service.\n *\n * This may be useful e.g. if services need to initialize themselves, since generally a Service factory is only\n * invoked when the Service is needed.\n *\n * Note this method cannot be used to add services to a Container. – that is, calling this method does not provide\n * the services in a new Container.\n *\n * @param fn Optionally provide an [InjectableFunction], which will be used as a filter – the only services\n * from *this* container that will run are those with a token that is also present in this PartialContainer.\n * @returns No mutation is done to the Container, it is returned as-is (convenient for chaining).\n */\n run<Token extends string, Tokens extends readonly ValidTokens<Services>[], Service>(\n fn: InjectableFunction<Services, Tokens, Token, Service>\n ): this;\n\n run<Token extends string, Tokens extends readonly ValidTokens<Services>[], Service, AdditionalServices>(\n fnOrContainer:\n | InjectableFunction<Services, Tokens, Token, Service>\n | PartialContainer<AdditionalServices, Services>\n ): this {\n if (fnOrContainer instanceof PartialContainer) {\n const runnableContainer = this.provides(fnOrContainer);\n for (const token of fnOrContainer.getTokens()) {\n runnableContainer.get(token);\n }\n } else {\n this.provides(fnOrContainer).get(fnOrContainer.token);\n }\n return this;\n }\n\n /**\n * Create a new Container from this Container with additional services from a given [PartialContainer].\n *\n * Services in the provided PartialContainer take precedence if there are service token conflicts.\n *\n * Services from the provided PartialContainer become scoped to the new Container – that is, if PartialContainer A\n * is provided to Container X and Container Y, each resultant Container will contain its own copy of the services\n * from PartialContainer A.\n *\n * @param container A [PartialContainer] providing additional services.\n */\n provides<AdditionalServices, Dependencies, FulfilledDependencies extends Dependencies>(\n // FullfilledDependencies is assignable to Dependencies -- by specifying Container<FulfilledDependencies> as the\n // `this` type, we ensure this Container can provide all the Dependencies required by the PartialContainer.\n this: Container<FulfilledDependencies>,\n container: PartialContainer<AdditionalServices, Dependencies>\n ): Container<Services & AdditionalServices>;\n\n /**\n * Creates a new Container from this Container with additional services from another Container.\n *\n * Services in the provided PartialContainer take precedence if there are service token conflicts.\n *\n * Services from the provided Container become scoped to both Containers (the one from which they were provided\n * and the new Container returned by this method) - that is, if Container A is provided to Container B,\n * they will share the same instances of any Services provided by Container A.\n * If Container B should re-create new instances of the Services from Container A,\n * Container A must first be copied before providing it here.\n *\n * @param container A [Container] providing additional services.\n */\n provides<AdditionalServices>(container: Container<AdditionalServices>): Container<Services & AdditionalServices>;\n\n /**\n * Create a new Container which provides a Service created by the given [InjectableFunction].\n *\n * The InjectableFunction contains metadata specifying the Token by which the created Service will be known, as well\n * as an ordered list of Tokens to be resolved and provided to the InjectableFunction as arguments.\n *\n * If any of these required dependencies are missing from the Container (or if there is a mismatch between the types\n * of those dependencies and the arguments of the InjectableFunction), a compiler error will be raised.\n *\n * @param fn A factory function, taking dependencies as arguments, which returns the Service.\n */\n provides<Token extends string, Tokens extends readonly ValidTokens<Services>[], Service>(\n fn: InjectableFunction<Services, Tokens, Token, Service>\n ): Container<AddService<Services, Token, Service>>;\n\n provides<Token extends string, Tokens extends readonly ValidTokens<Services>[], Service, AdditionalServices>(\n fnOrContainer:\n | InjectableFunction<Services, Tokens, Token, Service>\n | PartialContainer<AdditionalServices, Services>\n | Container<AdditionalServices>\n ): Container<any> {\n if (fnOrContainer instanceof PartialContainer || fnOrContainer instanceof Container) {\n const factories =\n fnOrContainer instanceof PartialContainer ? fnOrContainer.getFactories(this) : fnOrContainer.factories;\n // Safety: `this.factories` and `factories` are both properly type checked, so merging them produces\n // a Factories object with keys from both Services and AdditionalServices. The compiler is unable to\n // infer that Factories<A> & Factories<B> == Factories<A & B>, so the cast is required.\n return new Container({\n ...this.factories,\n ...factories,\n } as unknown as MaybeMemoizedFactories<Services & AdditionalServices>);\n }\n return this.providesService(fnOrContainer);\n }\n\n private providesService<Token extends string, Tokens extends readonly ValidTokens<Services>[], Service>(\n fn: InjectableFunction<Services, Tokens, Token, Service>\n ): Container<AddService<Services, Token, Service>> {\n const token = fn.token;\n const dependencies: readonly any[] = fn.dependencies;\n\n const factory = memoize((container: Container<Services>) => {\n return fn(\n ...(dependencies.map((t) => {\n // To support overwriting an already-existing service with a new implementation, it should be\n // possibleto do `provide(A, [A], a => createNewServiceFromOld(a))` – that is, inject a dependency\n // with the same token as this service's token.\n //\n // To avoid a circular dependency (in which the factory for service A depends on itself), we always\n // use the service defined in the *parent* container (i.e. this) when injecting a dependency with\n // the same token as the service we're providing. If we did not do this, calling `container.get(t)`\n // would result in an infinite loop.\n return t === token ? this.get(t) : container.get(t);\n }) as any)\n );\n });\n\n // Safety: `token` and `factory` are properly type checked, so extending `this.factories` produces a\n // MaybeMemoizedFactories object with the expected set of services – but when using the spread operation to\n // merge two objects, the compiler widens the Token type to string. So we must re-narrow via casting.\n const factories = { ...this.factories, [token]: factory };\n return new Container(factories as unknown as MaybeMemoizedFactories<AddService<Services, Token, Service>>);\n }\n}\n"]}
@@ -24,7 +24,7 @@ export declare function Injectable<Token extends string, Service>(token: Token,
24
24
  * const DependencyB = 'DependencyB'
25
25
  * const createMyService = Injectable(
26
26
  * 'MyService',
27
- * ['DependencyA', DependencyB],
27
+ * ['DependencyA', DependencyB] as const,
28
28
  * (a: A, b: B) => { return ... },
29
29
  * )
30
30
  * ```
@@ -35,7 +35,7 @@ export declare function Injectable<Token extends string, Service>(token: Token,
35
35
  * @param fn A function with arguments matching in type and length to the given list of dependencies. When called, it
36
36
  * must return the Service.
37
37
  */
38
- export declare function Injectable<Token extends string, const Tokens extends readonly string[], Params extends readonly any[], Service>(token: Token, dependencies: Tokens, fn: (...args: Tokens["length"] extends Params["length"] ? Params : void[]) => Service): Tokens["length"] extends Params["length"] ? InjectableFunction<ServicesFromTokenizedParams<Tokens, Params>, Tokens, Token, Service> : never;
38
+ export declare function Injectable<Token extends string, Tokens extends readonly string[], Params extends readonly any[], Service>(token: Token, dependencies: Tokens, fn: (...args: Tokens["length"] extends Params["length"] ? Params : void[]) => Service): Tokens["length"] extends Params["length"] ? InjectableFunction<ServicesFromTokenizedParams<Tokens, Params>, Tokens, Token, Service> : never;
39
39
  /**
40
40
  * Create an Injectable factory function without dependencies (i.e. the factory function has no arguments) that appends
41
41
  * a Service onto an existing array of Services of the same type.
@@ -52,7 +52,7 @@ export declare function Injectable<Token extends string, const Tokens extends re
52
52
  * // Consumers then do:
53
53
  * const myConsumingServiceFactory = Injectable(
54
54
  * 'myConsumingService',
55
- * [ myServiceFactory.token ],
55
+ * [myServiceFactory.token] as const,
56
56
  * (myServices: MyService[]) => { return ... }
57
57
  * )
58
58
  * ```
@@ -74,14 +74,14 @@ export declare function ConcatInjectable<Token extends string, Service>(token: T
74
74
  *
75
75
  * const createMyService = ConcatInjectable(
76
76
  * myServiceFactory.token,
77
- * ['DependencyA', 'DependencyB'],
77
+ * ['DependencyA', 'DependencyB'] as const,
78
78
  * (a: A, b: B): MyService => { return ... },
79
79
  * )
80
80
  *
81
81
  * // Consumers then do:
82
82
  * const myConsumingServiceFactory = Injectable(
83
83
  * 'myConsumingService',
84
- * [ myServiceFactory.token ],
84
+ * [myServiceFactory.token] as const,
85
85
  * (myServices: MyService[]) => { return ... }
86
86
  * )
87
87
  * ```
@@ -92,4 +92,4 @@ export declare function ConcatInjectable<Token extends string, Service>(token: T
92
92
  * will be resolved by the Container to which this Injectable is provided.
93
93
  * @param fn A function with no arguments which returns the Service.
94
94
  */
95
- export declare function ConcatInjectable<Token extends string, const Tokens extends readonly string[], Params extends readonly any[], Service>(token: Token, dependencies: Tokens, fn: (...args: Tokens["length"] extends Params["length"] ? Params : void[]) => Service): InjectableFunction<ServicesFromTokenizedParams<Tokens, Params>, Tokens, Token, Service[]>;
95
+ export declare function ConcatInjectable<Token extends string, Tokens extends readonly string[], Params extends readonly any[], Service>(token: Token, dependencies: Tokens, fn: (...args: Tokens["length"] extends Params["length"] ? Params : void[]) => Service): InjectableFunction<ServicesFromTokenizedParams<Tokens, Params>, Tokens, Token, Service[]>;
@@ -1 +1 @@
1
- {"version":3,"file":"Injectable.js","sourceRoot":"","sources":["../../src/dependency-injection/Injectable.ts"],"names":[],"mappings":"AA0DA,MAAM,UAAU,UAAU,CACtB,KAAa,EACb,gBAAkD,EAClD,OAAiC;IAEjC,MAAM,YAAY,GAAa,KAAK,CAAC,OAAO,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,EAAE,CAAC;IACvF,MAAM,EAAE,GAAG,OAAO,gBAAgB,KAAK,UAAU,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,OAAO,CAAC;IAE/E,IAAI,CAAC,EAAE,EAAE;QACL,MAAM,IAAI,SAAS,CACf,0FAA0F;YACtF,oBAAoB,CAC3B,CAAC;KACL;IAED,IAAI,EAAE,CAAC,MAAM,KAAK,YAAY,CAAC,MAAM,EAAE;QACnC,MAAM,IAAI,SAAS,CACf,4FAA4F;YACxF,GAAG,EAAE,CAAC,MAAM,SAAS,YAAY,CAAC,MAAM,+BAA+B;YACvE,mBAAmB,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC,EAAE,CACxD,CAAC;KACL;IAED,MAAM,OAAO,GAAG,CAAC,GAAG,IAAW,EAAE,EAAE,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,CAAC;IAChD,OAAO,CAAC,KAAK,GAAG,KAAK,CAAC;IACtB,OAAO,CAAC,YAAY,GAAG,YAAY,CAAC;IACpC,OAAO,OAAO,CAAC;AACnB,CAAC;AAuED,MAAM,UAAU,gBAAgB,CAC5B,KAAa,EACb,gBAAkD,EAClD,OAAiC;IAEjC,MAAM,YAAY,GAAa,KAAK,CAAC,OAAO,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,EAAE,CAAC;IACvF,MAAM,EAAE,GAAG,OAAO,gBAAgB,KAAK,UAAU,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,OAAO,CAAC;IAE/E,IAAI,CAAC,EAAE,EAAE;QACL,MAAM,IAAI,SAAS,CACf,gGAAgG;YAC5F,oBAAoB,CAC3B,CAAC;KACL;IAED,IAAI,EAAE,CAAC,MAAM,KAAK,YAAY,CAAC,MAAM,EAAE;QACnC,MAAM,IAAI,SAAS,CACf,4FAA4F;YACxF,GAAG,EAAE,CAAC,MAAM,SAAS,YAAY,CAAC,MAAM,+BAA+B;YACvE,mBAAmB,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC,EAAE,CACxD,CAAC;KACL;IAED,MAAM,OAAO,GAAG,CAAC,KAAY,EAAE,GAAG,IAAW,EAAE,EAAE;QAC7C,OAAO,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC;IACrC,CAAC,CAAC;IACF,OAAO,CAAC,KAAK,GAAG,KAAK,CAAC;IACtB,OAAO,CAAC,YAAY,GAAG,CAAC,KAAK,EAAE,GAAG,YAAY,CAAC,CAAC;IAChD,OAAO,OAAO,CAAC;AACnB,CAAC","sourcesContent":["import { InjectableFunction, ServicesFromTokenizedParams } from \"./types\";\n\n/**\n * Create an Injectable factory function with no dependencies (i.e. the factory function has no arguments).\n *\n * Ex:\n * ```ts\n * const createMyService = Injectable(\n * 'MyService',\n * () => { return ... },\n * )\n * ```\n *\n * @param token A unique string Token which will correspond to the created Service.\n * @param fn A function with no arguments which returns the Service.\n */\nexport function Injectable<Token extends string, Service>(\n token: Token,\n fn: () => Service\n): InjectableFunction<any, [], Token, Service>;\n\n/**\n * Create an Injectable factory function with dependencies (i.e. the factory function has arguments).\n *\n * **Note:** the list of dependencies must contain only string literals or string consts.\n *\n * Ex:\n * ```ts\n * const DependencyB = 'DependencyB'\n * const createMyService = Injectable(\n * 'MyService',\n * ['DependencyA', DependencyB],\n * (a: A, b: B) => { return ... },\n * )\n * ```\n *\n * @param token A unique string Token which will correspond to the created Service.\n * @param dependencies A *readonly* list of Tokens corresponding to dependencies (i.e. arguments to the Factory), which\n * will be resolved by the Container to which this Injectable is provided.\n * @param fn A function with arguments matching in type and length to the given list of dependencies. When called, it\n * must return the Service.\n */\nexport function Injectable<\n Token extends string,\n const Tokens extends readonly string[],\n Params extends readonly any[],\n Service\n>(\n token: Token,\n dependencies: Tokens,\n // The function arity (number of arguments) must match the number of dependencies specified – if they don't, we'll\n // force a compiler error by saying the arguments should be `void[]`. We'll also throw at runtime, so the return\n // type will be `never`.\n fn: (...args: Tokens[\"length\"] extends Params[\"length\"] ? Params : void[]) => Service\n): Tokens[\"length\"] extends Params[\"length\"]\n ? InjectableFunction<ServicesFromTokenizedParams<Tokens, Params>, Tokens, Token, Service>\n : never;\n\nexport function Injectable(\n token: string,\n dependenciesOrFn?: readonly string[] | (() => any),\n maybeFn?: (...args: any[]) => any\n): InjectableFunction<any, readonly string[], string, any> {\n const dependencies: string[] = Array.isArray(dependenciesOrFn) ? dependenciesOrFn : [];\n const fn = typeof dependenciesOrFn === \"function\" ? dependenciesOrFn : maybeFn;\n\n if (!fn) {\n throw new TypeError(\n \"[Injectable] Received invalid arguments. The factory function must be either the second \" +\n \"or third argument.\"\n );\n }\n\n if (fn.length !== dependencies.length) {\n throw new TypeError(\n \"[Injectable] Function arity does not match the number of dependencies. Function has arity \" +\n `${fn.length}, but ${dependencies.length} dependencies were specified.` +\n `\\nDependencies: ${JSON.stringify(dependencies)}`\n );\n }\n\n const factory = (...args: any[]) => fn(...args);\n factory.token = token;\n factory.dependencies = dependencies;\n return factory;\n}\n\n/**\n * Create an Injectable factory function without dependencies (i.e. the factory function has no arguments) that appends\n * a Service onto an existing array of Services of the same type.\n *\n * Ex:\n * ```ts\n * import { myServiceFactory, MyService } from './my-service'\n *\n * const createMyService = ConcatInjectable(\n * myServiceFactory.token,\n * (): MyService => { return ... },\n * )\n *\n * // Consumers then do:\n * const myConsumingServiceFactory = Injectable(\n * 'myConsumingService',\n * [ myServiceFactory.token ],\n * (myServices: MyService[]) => { return ... }\n * )\n * ```\n *\n * @param token A string Token identifying an existing Service that has an Array type, to which will be appended the\n * Service created by this factory function.\n * @param fn A function with no arguments which returns the Service.\n */\nexport function ConcatInjectable<Token extends string, Service>(\n token: Token,\n fn: () => Service\n): InjectableFunction<{ [T in keyof Token]: Service[] }, [], Token, Service[]>;\n\n/**\n * Create an Injectable factory function with dependencies (i.e. the factory function has arguments) that appends\n * a Service onto an existing array of Services of the same type.\n *\n * Ex:\n * ```ts\n * import { myServiceFactory, MyService } from './my-service'\n *\n * const createMyService = ConcatInjectable(\n * myServiceFactory.token,\n * ['DependencyA', 'DependencyB'],\n * (a: A, b: B): MyService => { return ... },\n * )\n *\n * // Consumers then do:\n * const myConsumingServiceFactory = Injectable(\n * 'myConsumingService',\n * [ myServiceFactory.token ],\n * (myServices: MyService[]) => { return ... }\n * )\n * ```\n *\n * @param token A string Token identifying an existing Service that has an Array type, to which will be appended the\n * Service created by this factory function.\n * @param dependencies A *readonly* list of Tokens corresponding to dependencies (i.e. arguments to the Factory), which\n * will be resolved by the Container to which this Injectable is provided.\n * @param fn A function with no arguments which returns the Service.\n */\nexport function ConcatInjectable<\n Token extends string,\n const Tokens extends readonly string[],\n Params extends readonly any[],\n Service\n>(\n token: Token,\n dependencies: Tokens,\n fn: (...args: Tokens[\"length\"] extends Params[\"length\"] ? Params : void[]) => Service\n): InjectableFunction<ServicesFromTokenizedParams<Tokens, Params>, Tokens, Token, Service[]>;\n\nexport function ConcatInjectable(\n token: string,\n dependenciesOrFn?: readonly string[] | (() => any),\n maybeFn?: (...args: any[]) => any\n): InjectableFunction<any, readonly string[], string, any[]> {\n const dependencies: string[] = Array.isArray(dependenciesOrFn) ? dependenciesOrFn : [];\n const fn = typeof dependenciesOrFn === \"function\" ? dependenciesOrFn : maybeFn;\n\n if (!fn) {\n throw new TypeError(\n \"[ConcatInjectable] Received invalid arguments. The factory function must be either the second \" +\n \"or third argument.\"\n );\n }\n\n if (fn.length !== dependencies.length) {\n throw new TypeError(\n \"[Injectable] Function arity does not match the number of dependencies. Function has arity \" +\n `${fn.length}, but ${dependencies.length} dependencies were specified.` +\n `\\nDependencies: ${JSON.stringify(dependencies)}`\n );\n }\n\n const factory = (array: any[], ...args: any[]) => {\n return array.concat(fn(...args));\n };\n factory.token = token;\n factory.dependencies = [token, ...dependencies];\n return factory;\n}\n"]}
1
+ {"version":3,"file":"Injectable.js","sourceRoot":"","sources":["../../src/dependency-injection/Injectable.ts"],"names":[],"mappings":"AA0DA,MAAM,UAAU,UAAU,CACtB,KAAa,EACb,gBAAkD,EAClD,OAAiC;IAEjC,MAAM,YAAY,GAAa,KAAK,CAAC,OAAO,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,EAAE,CAAC;IACvF,MAAM,EAAE,GAAG,OAAO,gBAAgB,KAAK,UAAU,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,OAAO,CAAC;IAE/E,IAAI,CAAC,EAAE,EAAE;QACL,MAAM,IAAI,SAAS,CACf,0FAA0F;YACtF,oBAAoB,CAC3B,CAAC;KACL;IAED,IAAI,EAAE,CAAC,MAAM,KAAK,YAAY,CAAC,MAAM,EAAE;QACnC,MAAM,IAAI,SAAS,CACf,4FAA4F;YACxF,GAAG,EAAE,CAAC,MAAM,SAAS,YAAY,CAAC,MAAM,+BAA+B;YACvE,mBAAmB,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC,EAAE,CACxD,CAAC;KACL;IAED,MAAM,OAAO,GAAG,CAAC,GAAG,IAAW,EAAE,EAAE,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,CAAC;IAChD,OAAO,CAAC,KAAK,GAAG,KAAK,CAAC;IACtB,OAAO,CAAC,YAAY,GAAG,YAAY,CAAC;IACpC,OAAO,OAAO,CAAC;AACnB,CAAC;AAuED,MAAM,UAAU,gBAAgB,CAC5B,KAAa,EACb,gBAAkD,EAClD,OAAiC;IAEjC,MAAM,YAAY,GAAa,KAAK,CAAC,OAAO,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,EAAE,CAAC;IACvF,MAAM,EAAE,GAAG,OAAO,gBAAgB,KAAK,UAAU,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,OAAO,CAAC;IAE/E,IAAI,CAAC,EAAE,EAAE;QACL,MAAM,IAAI,SAAS,CACf,gGAAgG;YAC5F,oBAAoB,CAC3B,CAAC;KACL;IAED,IAAI,EAAE,CAAC,MAAM,KAAK,YAAY,CAAC,MAAM,EAAE;QACnC,MAAM,IAAI,SAAS,CACf,4FAA4F;YACxF,GAAG,EAAE,CAAC,MAAM,SAAS,YAAY,CAAC,MAAM,+BAA+B;YACvE,mBAAmB,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC,EAAE,CACxD,CAAC;KACL;IAED,MAAM,OAAO,GAAG,CAAC,KAAY,EAAE,GAAG,IAAW,EAAE,EAAE;QAC7C,OAAO,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC;IACrC,CAAC,CAAC;IACF,OAAO,CAAC,KAAK,GAAG,KAAK,CAAC;IACtB,OAAO,CAAC,YAAY,GAAG,CAAC,KAAK,EAAE,GAAG,YAAY,CAAC,CAAC;IAChD,OAAO,OAAO,CAAC;AACnB,CAAC","sourcesContent":["import { InjectableFunction, ServicesFromTokenizedParams } from \"./types\";\n\n/**\n * Create an Injectable factory function with no dependencies (i.e. the factory function has no arguments).\n *\n * Ex:\n * ```ts\n * const createMyService = Injectable(\n * 'MyService',\n * () => { return ... },\n * )\n * ```\n *\n * @param token A unique string Token which will correspond to the created Service.\n * @param fn A function with no arguments which returns the Service.\n */\nexport function Injectable<Token extends string, Service>(\n token: Token,\n fn: () => Service\n): InjectableFunction<any, [], Token, Service>;\n\n/**\n * Create an Injectable factory function with dependencies (i.e. the factory function has arguments).\n *\n * **Note:** the list of dependencies must contain only string literals or string consts.\n *\n * Ex:\n * ```ts\n * const DependencyB = 'DependencyB'\n * const createMyService = Injectable(\n * 'MyService',\n * ['DependencyA', DependencyB] as const,\n * (a: A, b: B) => { return ... },\n * )\n * ```\n *\n * @param token A unique string Token which will correspond to the created Service.\n * @param dependencies A *readonly* list of Tokens corresponding to dependencies (i.e. arguments to the Factory), which\n * will be resolved by the Container to which this Injectable is provided.\n * @param fn A function with arguments matching in type and length to the given list of dependencies. When called, it\n * must return the Service.\n */\nexport function Injectable<\n Token extends string,\n Tokens extends readonly string[],\n Params extends readonly any[],\n Service\n>(\n token: Token,\n dependencies: Tokens,\n // The function arity (number of arguments) must match the number of dependencies specified – if they don't, we'll\n // force a compiler error by saying the arguments should be `void[]`. We'll also throw at runtime, so the return\n // type will be `never`.\n fn: (...args: Tokens[\"length\"] extends Params[\"length\"] ? Params : void[]) => Service\n): Tokens[\"length\"] extends Params[\"length\"]\n ? InjectableFunction<ServicesFromTokenizedParams<Tokens, Params>, Tokens, Token, Service>\n : never;\n\nexport function Injectable(\n token: string,\n dependenciesOrFn?: readonly string[] | (() => any),\n maybeFn?: (...args: any[]) => any\n): InjectableFunction<any, readonly string[], string, any> {\n const dependencies: string[] = Array.isArray(dependenciesOrFn) ? dependenciesOrFn : [];\n const fn = typeof dependenciesOrFn === \"function\" ? dependenciesOrFn : maybeFn;\n\n if (!fn) {\n throw new TypeError(\n \"[Injectable] Received invalid arguments. The factory function must be either the second \" +\n \"or third argument.\"\n );\n }\n\n if (fn.length !== dependencies.length) {\n throw new TypeError(\n \"[Injectable] Function arity does not match the number of dependencies. Function has arity \" +\n `${fn.length}, but ${dependencies.length} dependencies were specified.` +\n `\\nDependencies: ${JSON.stringify(dependencies)}`\n );\n }\n\n const factory = (...args: any[]) => fn(...args);\n factory.token = token;\n factory.dependencies = dependencies;\n return factory;\n}\n\n/**\n * Create an Injectable factory function without dependencies (i.e. the factory function has no arguments) that appends\n * a Service onto an existing array of Services of the same type.\n *\n * Ex:\n * ```ts\n * import { myServiceFactory, MyService } from './my-service'\n *\n * const createMyService = ConcatInjectable(\n * myServiceFactory.token,\n * (): MyService => { return ... },\n * )\n *\n * // Consumers then do:\n * const myConsumingServiceFactory = Injectable(\n * 'myConsumingService',\n * [myServiceFactory.token] as const,\n * (myServices: MyService[]) => { return ... }\n * )\n * ```\n *\n * @param token A string Token identifying an existing Service that has an Array type, to which will be appended the\n * Service created by this factory function.\n * @param fn A function with no arguments which returns the Service.\n */\nexport function ConcatInjectable<Token extends string, Service>(\n token: Token,\n fn: () => Service\n): InjectableFunction<{ [T in keyof Token]: Service[] }, [], Token, Service[]>;\n\n/**\n * Create an Injectable factory function with dependencies (i.e. the factory function has arguments) that appends\n * a Service onto an existing array of Services of the same type.\n *\n * Ex:\n * ```ts\n * import { myServiceFactory, MyService } from './my-service'\n *\n * const createMyService = ConcatInjectable(\n * myServiceFactory.token,\n * ['DependencyA', 'DependencyB'] as const,\n * (a: A, b: B): MyService => { return ... },\n * )\n *\n * // Consumers then do:\n * const myConsumingServiceFactory = Injectable(\n * 'myConsumingService',\n * [myServiceFactory.token] as const,\n * (myServices: MyService[]) => { return ... }\n * )\n * ```\n *\n * @param token A string Token identifying an existing Service that has an Array type, to which will be appended the\n * Service created by this factory function.\n * @param dependencies A *readonly* list of Tokens corresponding to dependencies (i.e. arguments to the Factory), which\n * will be resolved by the Container to which this Injectable is provided.\n * @param fn A function with no arguments which returns the Service.\n */\nexport function ConcatInjectable<\n Token extends string,\n Tokens extends readonly string[],\n Params extends readonly any[],\n Service\n>(\n token: Token,\n dependencies: Tokens,\n fn: (...args: Tokens[\"length\"] extends Params[\"length\"] ? Params : void[]) => Service\n): InjectableFunction<ServicesFromTokenizedParams<Tokens, Params>, Tokens, Token, Service[]>;\n\nexport function ConcatInjectable(\n token: string,\n dependenciesOrFn?: readonly string[] | (() => any),\n maybeFn?: (...args: any[]) => any\n): InjectableFunction<any, readonly string[], string, any[]> {\n const dependencies: string[] = Array.isArray(dependenciesOrFn) ? dependenciesOrFn : [];\n const fn = typeof dependenciesOrFn === \"function\" ? dependenciesOrFn : maybeFn;\n\n if (!fn) {\n throw new TypeError(\n \"[ConcatInjectable] Received invalid arguments. The factory function must be either the second \" +\n \"or third argument.\"\n );\n }\n\n if (fn.length !== dependencies.length) {\n throw new TypeError(\n \"[Injectable] Function arity does not match the number of dependencies. Function has arity \" +\n `${fn.length}, but ${dependencies.length} dependencies were specified.` +\n `\\nDependencies: ${JSON.stringify(dependencies)}`\n );\n }\n\n const factory = (array: any[], ...args: any[]) => {\n return array.concat(fn(...args));\n };\n factory.token = token;\n factory.dependencies = [token, ...dependencies];\n return factory;\n}\n"]}
@@ -6,10 +6,9 @@ import { staticAssetLoaderFactory } from "../lens/assets/staticAssetLoader";
6
6
  import { defaultFetchHandlerFactory } from "../handlers/defaultFetchHandler";
7
7
  import { cameraKitServiceFetchHandlerFactory } from "../handlers/cameraKitServiceFetchHandlerFactory";
8
8
  import { createCameraKitConfigurationFactory } from "../configuration";
9
+ import { externalMetricsSubjectFactory, metricsClientFactory } from "../clients/metricsClient";
9
10
  import { LensCore } from "../lens-core-module/lensCore";
10
11
  import { metricsEventTargetFactory } from "../metrics/metricsEventTarget";
11
- import { metricsHandlerFactory } from "../metrics/metricsHandler";
12
- import { operationalMetricReporterFactory } from "../metrics/operational/operationalMetricsReporter";
13
12
  import { lensSourcesFactory } from "../lens/LensSource";
14
13
  import { uriHandlersFactory } from "../extensions/UriHandlers";
15
14
  import { lensPersistenceStoreFactory } from "../lens/LensPersistenceStore";
@@ -24,19 +23,19 @@ import { requestStateEventTargetFactory } from "../handlers/requestStateEmitting
24
23
  import { lensesClientFactory } from "../clients/lensesClient";
25
24
  import { pageVisibilityFactory } from "../common/pageVisibility";
26
25
  import { remoteApiServicesFactory } from "../extensions/RemoteApiServices";
27
- import { gprcHandlerFactory } from "../clients/grpcHandler";
26
+ import { grpcHandlerFactory } from "../clients/grpcHandler";
28
27
  import { ServicesFromInjectables } from "./types";
29
28
  /**
30
29
  * All services available to be customized by client app.
31
30
  */
32
31
  export type PublicServices = ServicesFromInjectables<[
33
32
  ReturnType<typeof createCameraKitConfigurationFactory>,
34
- typeof pageVisibilityFactory,
35
33
  typeof defaultFetchHandlerFactory,
36
34
  typeof remoteMediaAssetLoaderFactory,
37
35
  typeof lensSourcesFactory,
38
36
  typeof remoteApiServicesFactory,
39
- typeof uriHandlersFactory
37
+ typeof uriHandlersFactory,
38
+ typeof externalMetricsSubjectFactory
40
39
  ]>;
41
40
  /**
42
41
  * Define all the Services contained in CameraKit's root dependency injection container.
@@ -53,17 +52,17 @@ export type PublicServices = ServicesFromInjectables<[
53
52
  export type RootServices = {
54
53
  [lensCoreFactory.token]: LensCore;
55
54
  } & PublicServices & ServicesFromInjectables<[
55
+ typeof pageVisibilityFactory,
56
56
  typeof metricsEventTargetFactory,
57
57
  typeof requestStateEventTargetFactory,
58
58
  typeof cameraKitServiceFetchHandlerFactory,
59
- typeof gprcHandlerFactory,
59
+ typeof grpcHandlerFactory,
60
60
  typeof lensesClientFactory,
61
61
  typeof cofHandlerFactory,
62
62
  typeof remoteConfigurationFactory,
63
63
  typeof lensRepositoryFactory,
64
64
  typeof lensPersistenceStoreFactory,
65
- typeof metricsHandlerFactory,
66
- typeof operationalMetricReporterFactory,
65
+ typeof metricsClientFactory,
67
66
  typeof lensAssetRepositoryFactory,
68
67
  typeof deviceDependentAssetLoaderFactory,
69
68
  typeof staticAssetLoaderFactory,
@@ -1 +1 @@
1
- {"version":3,"file":"RootServices.js","sourceRoot":"","sources":["../../src/dependency-injection/RootServices.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,4CAA4C,CAAC","sourcesContent":["import { lensRepositoryFactory } from \"../lens/LensRepository\";\nimport { lensCoreFactory } from \"../lens-core-module/loader/lensCoreFactory\";\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 { createCameraKitConfigurationFactory } from \"../configuration\";\nimport { LensCore } from \"../lens-core-module/lensCore\";\nimport { metricsEventTargetFactory } from \"../metrics/metricsEventTarget\";\nimport { metricsHandlerFactory } from \"../metrics/metricsHandler\";\nimport { operationalMetricReporterFactory } from \"../metrics/operational/operationalMetricsReporter\";\nimport { lensSourcesFactory } from \"../lens/LensSource\";\nimport { uriHandlersFactory } from \"../extensions/UriHandlers\";\nimport { lensPersistenceStoreFactory } from \"../lens/LensPersistenceStore\";\nimport { cofHandlerFactory } from \"../remote-configuration/cofHandler\";\nimport { remoteConfigurationFactory } from \"../remote-configuration/remoteConfiguration\";\nimport { lensAssetRepositoryFactory } from \"../lens/assets/LensAssetRepository\";\nimport { legalStateFactory } from \"../legal/legalState\";\nimport { legalPromptFactory } from \"../legal/legalPrompt\";\nimport { logEntriesFactory } from \"../logger/logEntries\";\nimport { reportGlobalException } from \"../metrics/reporters/reportGlobalException\";\nimport { requestStateEventTargetFactory } from \"../handlers/requestStateEmittingHandler\";\nimport { lensesClientFactory } from \"../clients/lensesClient\";\nimport { pageVisibilityFactory } from \"../common/pageVisibility\";\nimport { remoteApiServicesFactory } from \"../extensions/RemoteApiServices\";\nimport { gprcHandlerFactory } from \"../clients/grpcHandler\";\nimport { ServicesFromInjectables } from \"./types\";\n\n/**\n * All services available to be customized by client app.\n */\nexport type PublicServices = ServicesFromInjectables<\n [\n ReturnType<typeof createCameraKitConfigurationFactory>,\n typeof pageVisibilityFactory,\n typeof defaultFetchHandlerFactory,\n typeof remoteMediaAssetLoaderFactory,\n typeof lensSourcesFactory,\n typeof remoteApiServicesFactory,\n typeof uriHandlersFactory\n ]\n>;\n\n/**\n * Define all the Services contained in CameraKit's root dependency injection container.\n *\n * Note: we do end up defining this list of Services twice (once here to create the type, once when we actually\n * create the Container inside the `bootstrapCameraKit` function). We could avoid doing this and just infer the\n * RootContainer type from the constructed container – but since we can only do that *inside* `bootstrapCameraKit`, it\n * makes it more awkward to provide a type for the `provide` user-supplied function (or use the type elsewhere, like in\n * CameraKitSession).\n *\n * There may be a way to eliminate this extra boilerplate, but for now it's required in order to present a cleaner\n * `bootstrapCameraKit` API to applications.\n */\nexport type RootServices = {\n // bootstrapCameraKit replaces the lensCoreFactory token's value with the resolved LensCore (rather than the\n // Promise of the LensCore), so we need to do the same re-mapping here.\n [lensCoreFactory.token]: LensCore;\n} & PublicServices &\n ServicesFromInjectables<\n [\n typeof metricsEventTargetFactory,\n typeof requestStateEventTargetFactory,\n typeof cameraKitServiceFetchHandlerFactory,\n typeof gprcHandlerFactory,\n typeof lensesClientFactory,\n typeof cofHandlerFactory,\n typeof remoteConfigurationFactory,\n typeof lensRepositoryFactory,\n typeof lensPersistenceStoreFactory,\n typeof metricsHandlerFactory,\n typeof operationalMetricReporterFactory,\n typeof lensAssetRepositoryFactory,\n typeof deviceDependentAssetLoaderFactory,\n typeof staticAssetLoaderFactory,\n typeof legalStateFactory,\n typeof legalPromptFactory,\n typeof logEntriesFactory,\n typeof reportGlobalException\n ]\n >;\n"]}
1
+ {"version":3,"file":"RootServices.js","sourceRoot":"","sources":["../../src/dependency-injection/RootServices.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,4CAA4C,CAAC","sourcesContent":["import { lensRepositoryFactory } from \"../lens/LensRepository\";\nimport { lensCoreFactory } from \"../lens-core-module/loader/lensCoreFactory\";\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 { createCameraKitConfigurationFactory } from \"../configuration\";\nimport { externalMetricsSubjectFactory, metricsClientFactory } from \"../clients/metricsClient\";\nimport { LensCore } from \"../lens-core-module/lensCore\";\nimport { metricsEventTargetFactory } from \"../metrics/metricsEventTarget\";\nimport { lensSourcesFactory } from \"../lens/LensSource\";\nimport { uriHandlersFactory } from \"../extensions/UriHandlers\";\nimport { lensPersistenceStoreFactory } from \"../lens/LensPersistenceStore\";\nimport { cofHandlerFactory } from \"../remote-configuration/cofHandler\";\nimport { remoteConfigurationFactory } from \"../remote-configuration/remoteConfiguration\";\nimport { lensAssetRepositoryFactory } from \"../lens/assets/LensAssetRepository\";\nimport { legalStateFactory } from \"../legal/legalState\";\nimport { legalPromptFactory } from \"../legal/legalPrompt\";\nimport { logEntriesFactory } from \"../logger/logEntries\";\nimport { reportGlobalException } from \"../metrics/reporters/reportGlobalException\";\nimport { requestStateEventTargetFactory } from \"../handlers/requestStateEmittingHandler\";\nimport { lensesClientFactory } from \"../clients/lensesClient\";\nimport { pageVisibilityFactory } from \"../common/pageVisibility\";\nimport { remoteApiServicesFactory } from \"../extensions/RemoteApiServices\";\nimport { grpcHandlerFactory } from \"../clients/grpcHandler\";\nimport { ServicesFromInjectables } from \"./types\";\n\n/**\n * All services available to be customized by client app.\n */\nexport type PublicServices = ServicesFromInjectables<\n [\n ReturnType<typeof createCameraKitConfigurationFactory>,\n typeof defaultFetchHandlerFactory,\n typeof remoteMediaAssetLoaderFactory,\n typeof lensSourcesFactory,\n typeof remoteApiServicesFactory,\n typeof uriHandlersFactory,\n typeof externalMetricsSubjectFactory\n ]\n>;\n\n/**\n * Define all the Services contained in CameraKit's root dependency injection container.\n *\n * Note: we do end up defining this list of Services twice (once here to create the type, once when we actually\n * create the Container inside the `bootstrapCameraKit` function). We could avoid doing this and just infer the\n * RootContainer type from the constructed container – but since we can only do that *inside* `bootstrapCameraKit`, it\n * makes it more awkward to provide a type for the `provide` user-supplied function (or use the type elsewhere, like in\n * CameraKitSession).\n *\n * There may be a way to eliminate this extra boilerplate, but for now it's required in order to present a cleaner\n * `bootstrapCameraKit` API to applications.\n */\nexport type RootServices = {\n // bootstrapCameraKit replaces the lensCoreFactory token's value with the resolved LensCore (rather than the\n // Promise of the LensCore), so we need to do the same re-mapping here.\n [lensCoreFactory.token]: LensCore;\n} & PublicServices &\n ServicesFromInjectables<\n [\n typeof pageVisibilityFactory,\n typeof metricsEventTargetFactory,\n typeof requestStateEventTargetFactory,\n typeof cameraKitServiceFetchHandlerFactory,\n typeof grpcHandlerFactory,\n typeof lensesClientFactory,\n typeof cofHandlerFactory,\n typeof remoteConfigurationFactory,\n typeof lensRepositoryFactory,\n typeof lensPersistenceStoreFactory,\n typeof metricsClientFactory,\n typeof lensAssetRepositoryFactory,\n typeof deviceDependentAssetLoaderFactory,\n typeof staticAssetLoaderFactory,\n typeof legalStateFactory,\n typeof legalPromptFactory,\n typeof logEntriesFactory,\n typeof reportGlobalException\n ]\n >;\n"]}
@@ -0,0 +1,4 @@
1
+ declare const _default: {
2
+ PACKAGE_VERSION: string;
3
+ };
4
+ export default _default;
@@ -0,0 +1,2 @@
1
+ export default { PACKAGE_VERSION: "0.17.0" };
2
+ //# sourceMappingURL=environment.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"environment.js","sourceRoot":"","sources":["../src/environment.ts"],"names":[],"mappings":"AAAA,eAAe,EAAE,eAAe,EAAE,QAAQ,EAAE,CAAC","sourcesContent":["export default { PACKAGE_VERSION: \"0.17.0\" };\n"]}
@@ -3,7 +3,7 @@ import { LensRepository } from "../lens/LensRepository";
3
3
  import { Lens } from "../lens/Lens";
4
4
  import { LensState } from "../session/lensState";
5
5
  import { SessionState } from "../session/sessionState";
6
- import { OperationalMetricsReporter } from "../metrics/operational/operationalMetricsReporter";
6
+ import { MetricsClient } from "../clients/metricsClient";
7
7
  import { UriHandler } from "./UriHandlers";
8
8
  declare const statusToResponseCodeMap: {
9
9
  success: ResponseCode.SUCCESS;
@@ -97,5 +97,5 @@ export declare const remoteApiServicesFactory: {
97
97
  * Provides a URI handler that searches for a match within the provided services to handle Remote API requests,
98
98
  * i.e., those whose URI starts with 'app://remote-api/performApiRequest'.
99
99
  */
100
- export declare function getRemoteApiUriHandler(registeredServices: RemoteApiService[], sessionState: SessionState, lensState: LensState, lensRepository: LensRepository, reporter: OperationalMetricsReporter): UriHandler;
100
+ export declare function getRemoteApiUriHandler(registeredServices: RemoteApiService[], sessionState: SessionState, lensState: LensState, lensRepository: LensRepository, metrics: MetricsClient): UriHandler;
101
101
  export {};
@@ -4,6 +4,8 @@ import { Injectable } from "../dependency-injection/Injectable";
4
4
  import { RemoteApiInfo } from "../generated-proto/pb_schema/camera_kit/v3/features/remote_api_info";
5
5
  import { ResponseCode, responseCodeToNumber } from "../generated-proto/pb_schema/lenses/remote_api/remote_api_service";
6
6
  import { getLogger } from "../logger/logger";
7
+ import { Count } from "../metrics/operational/Count";
8
+ import { joinMetricNames } from "../metrics/operational/Metric";
7
9
  import { extractSchemeAndRoute } from "./UriHandlers";
8
10
  // NOTE: There's potential for overloads when reporting metrics if reporting is triggered on each frame,
9
11
  // (i.e., when the lens sends Remote API requests every frame).
@@ -67,7 +69,7 @@ export const remoteApiServicesFactory = Injectable("remoteApiServices", () => {
67
69
  * Provides a URI handler that searches for a match within the provided services to handle Remote API requests,
68
70
  * i.e., those whose URI starts with 'app://remote-api/performApiRequest'.
69
71
  */
70
- export function getRemoteApiUriHandler(registeredServices, sessionState, lensState, lensRepository, reporter) {
72
+ export function getRemoteApiUriHandler(registeredServices, sessionState, lensState, lensRepository, metrics) {
71
73
  // Groups services by spec ID for faster lookups.
72
74
  const registeredServiceMap = new Map();
73
75
  for (const service of registeredServices) {
@@ -109,8 +111,11 @@ export function getRemoteApiUriHandler(registeredServices, sessionState, lensSta
109
111
  // only handle requests if we have a registered service for it
110
112
  filter(({ specId }) => registeredServiceMap.has(specId)), map(({ uriRequest, specId, endpointId, requestState }) => {
111
113
  var _a;
112
- const dimensions = new Map([["specId", specId]]);
113
- reporter.count("lens_remote-api_requests", 1, dimensions);
114
+ const dimensions = { specId };
115
+ const reportSingleCount = (name) => {
116
+ metrics.setOperationalMetrics(Count.count(joinMetricNames(["lens", "remote-api", name]), 1, dimensions));
117
+ };
118
+ reportSingleCount("requests");
114
119
  const remoteApiRequest = {
115
120
  apiSpecId: specId,
116
121
  body: uriRequest.request.data,
@@ -127,13 +132,13 @@ export function getRemoteApiUriHandler(registeredServices, sessionState, lensSta
127
132
  logger.warn("Client's Remote API request handler factory threw an error.", error);
128
133
  }
129
134
  if (requestHandler) {
130
- reporter.count("lens_remote-api_handled-requests", 1, dimensions);
135
+ reportSingleCount("handled-requests");
131
136
  let cancellationHandler = undefined;
132
137
  try {
133
138
  // Calls client's Remote API handler to process the request.
134
139
  cancellationHandler = requestHandler((response) => {
135
140
  var _a;
136
- reporter.count("lens_remote-api_responses", 1, dimensions);
141
+ reportSingleCount("responses");
137
142
  const responseCode = (_a = statusToResponseCodeMap[response.status]) !== null && _a !== void 0 ? _a : ResponseCode.UNRECOGNIZED;
138
143
  const uriResponse = {
139
144
  code: uriResponseOkCode,
@@ -175,7 +180,7 @@ export function getRemoteApiUriHandler(registeredServices, sessionState, lensSta
175
180
  // because app callbacks are wrapped with try..catch blocks.
176
181
  // Therefore, we would like to report this error.
177
182
  logger.error(error);
178
- reporter.count("lens_remote-api_errors", 1);
183
+ metrics.setOperationalMetrics(Count.count(joinMetricNames(["lens", "remote-api", "errors"]), 1));
179
184
  // Return the source pipe so that we can retry the pipe instead of just completing it.
180
185
  return sourcePipe;
181
186
  }),
@@ -1 +1 @@
1
- {"version":3,"file":"RemoteApiServices.js","sourceRoot":"","sources":["../../src/extensions/RemoteApiServices.ts"],"names":[],"mappings":"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","sourcesContent":["import { Subject, catchError, filter, map, merge, retry, takeUntil, tap } from \"rxjs\";\nimport { forActions } from \"@snap/state-management\";\nimport { Injectable } from \"../dependency-injection/Injectable\";\nimport { RemoteApiInfo } from \"../generated-proto/pb_schema/camera_kit/v3/features/remote_api_info\";\nimport { ResponseCode, responseCodeToNumber } from \"../generated-proto/pb_schema/lenses/remote_api/remote_api_service\";\nimport { LensRepository } from \"../lens/LensRepository\";\nimport { Lens } from \"../lens/Lens\";\nimport { LensState } from \"../session/lensState\";\nimport { SessionState } from \"../session/sessionState\";\nimport { getLogger } from \"../logger/logger\";\nimport { CamelToSnakeCase, SnakeToCamelCase } from \"../common/types\";\nimport { OperationalMetricsReporter } from \"../metrics/operational/operationalMetricsReporter\";\nimport { UriCancelRequest, UriHandler, UriRequest, UriResponse, extractSchemeAndRoute } from \"./UriHandlers\";\n\n// NOTE: There's potential for overloads when reporting metrics if reporting is triggered on each frame,\n// (i.e., when the lens sends Remote API requests every frame).\n// As of now, this isn't a concern because src/metrics/operational/operationalMetricsReporter.ts aggregates\n// \"count\" metrics into a single metric within a batch, and the Remote API service currently\n// reports only \"count\" metrics. For instance, if 30 metrics with the same name are generated per second,\n// given the current bundle size of 100 operational metrics, there will be one metrics report approximately\n// every 3.3 seconds.\n// In the future, if we opt to report \"histogram\" or other metric types, they must be approached with caution:\n// either the operationalMetricsReporter should be enhanced to aggregate such metrics,\n// or the Remote API service should manage it directly.\n// Mobiles ticket: https://jira.sc-corp.net/browse/CAMKIT-3092\n\nconst logger = getLogger(\"RemoteApiServices\");\n\nconst uriResponseOkCode = 200;\nconst apiResponseStatusHeader = \":sc_lens_api_status\";\nconst apiBinaryContentType = \"application/octet-stream\";\nconst remoteApiInfoProtobufTypeUrl = \"type.googleapis.com/com.snap.camerakit.v3.features.RemoteApiInfo\";\n\nconst statusToResponseCodeMap = {\n success: ResponseCode.SUCCESS,\n redirected: ResponseCode.REDIRECTED,\n badRequest: ResponseCode.BAD_REQUEST,\n accessDenied: ResponseCode.ACCESS_DENIED,\n notFound: ResponseCode.NOT_FOUND,\n timeout: ResponseCode.TIMEOUT,\n requestTooLarge: ResponseCode.REQUEST_TOO_LARGE,\n serverError: ResponseCode.SERVER_ERROR,\n cancelled: ResponseCode.CANCELLED,\n proxyError: ResponseCode.PROXY_ERROR,\n} satisfies { [Status in RemoteApiStatusInternal]: Uppercase<CamelToSnakeCase<Status>> };\n\ntype RemoteApiStatusInternal = SnakeToCamelCase<\n Lowercase<Exclude<keyof typeof ResponseCode, \"RESPONSE_CODE_UNSET\" | \"UNRECOGNIZED\">>\n>;\n\ntype LensId = string;\ntype RequestId = string;\n\ntype UriRequestEvent = {\n request: UriRequest;\n reply: (response: UriResponse) => void;\n lens: Lens;\n};\n\ntype UriCancelRequestEvent = {\n request: UriCancelRequest;\n lens: Lens;\n};\n\ninterface LensRequestState {\n cancellationHandlers: Map<RequestId, RemoteApiCancelRequestHandler>;\n supportedSpecIds: Set<string>;\n}\n\n/**\n * Invokes the cancellation handler associated with the provided key and removes it from the collection of handlers.\n */\nfunction callCancellationHandler(\n cancellationHandlers: Map<RequestId, RemoteApiCancelRequestHandler>,\n ...keys: RequestId[]\n) {\n for (const key of keys) {\n cancellationHandlers.get(key)?.();\n cancellationHandlers.delete(key);\n }\n}\n\n/**\n * Removes the specified lenses' metadata from the cache and invokes their cancellation callbacks.\n *\n * @param lensRequestState The state representing the lens cache.\n * @param lensIds An array of lens IDs to be removed from the cache\n * and for which the cancellation callbacks will be invoked.\n */\nfunction handleLensApplicationEnd(lensRequestState: Map<LensId, LensRequestState>, ...lensIds: LensId[]) {\n for (const lensId of lensIds) {\n const state = lensRequestState.get(lensId);\n if (state) {\n callCancellationHandler(state.cancellationHandlers, ...state.cancellationHandlers.keys());\n lensRequestState.delete(lensId);\n }\n }\n}\n\n/**\n * Status of a Remote API response.\n */\nexport type RemoteApiStatus = keyof typeof statusToResponseCodeMap;\n\n/**\n * Remote API request sent by a lens.\n */\nexport interface RemoteApiRequest {\n /**\n * Unique id of the remote API service specification.\n */\n apiSpecId: string;\n /**\n * Unique id of the remote API service endpoint requested by this request.\n */\n endpointId: string;\n /**\n * A map of named parameters associated with the request.\n */\n parameters: Record<string, string>;\n /**\n * Additional binary request payload.\n */\n body: ArrayBuffer;\n}\n\n/**\n * Remote API response to a request sent by a lens.\n */\nexport interface RemoteApiResponse {\n /**\n * Status of the response\n */\n status: RemoteApiStatus;\n /**\n * A map of named metadata associated with the response.\n */\n metadata: Record<string, string>;\n /**\n * Additional binary request payload.\n */\n body: ArrayBuffer;\n}\n\n/**\n * Represents a Remote API request cancellation handler function.\n */\nexport type RemoteApiCancelRequestHandler = () => void;\n\n/**\n * Represents a Remote API request handler function.\n * It is provided with a reply callback that must be invoked to send a response back to the lens.\n * The reply callback can be invoked multiple times if needed.\n * Additionally, the handler can return a cancellation callback, which is triggered when the lens cancels the request.\n */\nexport type RemoteApiRequestHandler = (\n reply: (response: RemoteApiResponse) => void\n) => RemoteApiCancelRequestHandler | void;\n\n/**\n * Service to handle a lens Remote API request.\n */\nexport interface RemoteApiService {\n /**\n * Remote API spec ID(s).\n */\n apiSpecId: string;\n\n /**\n * This method is called by Camera Kit when a lens triggers a Remote API request with a corresponding spec ID.\n * If the service can handle the request, the method returns a request handler; otherwise, it returns nothing.\n * @param request Remote API request object.\n * @param lens Lens that trigges the request.\n * @returns A request handler if applicable.\n */\n getRequestHandler(request: RemoteApiRequest, lens: Lens): RemoteApiRequestHandler | undefined;\n}\n\nexport type RemoteApiServices = RemoteApiService[];\n\nexport const remoteApiServicesFactory = Injectable(\"remoteApiServices\", () => {\n const remoteApiServices: RemoteApiServices = [];\n return remoteApiServices;\n});\n\n/**\n * Provides a URI handler that searches for a match within the provided services to handle Remote API requests,\n * i.e., those whose URI starts with 'app://remote-api/performApiRequest'.\n */\nexport function getRemoteApiUriHandler(\n registeredServices: RemoteApiService[],\n sessionState: SessionState,\n lensState: LensState,\n lensRepository: LensRepository,\n reporter: OperationalMetricsReporter\n): UriHandler {\n // Groups services by spec ID for faster lookups.\n const registeredServiceMap = new Map<string, RemoteApiService[]>();\n for (const service of registeredServices) {\n const existingServices = registeredServiceMap.get(service.apiSpecId) || [];\n registeredServiceMap.set(service.apiSpecId, [...existingServices, service]);\n }\n\n const uriRequests = new Subject<UriRequestEvent>();\n const uriCancelRequests = new Subject<UriCancelRequestEvent>();\n const lensRequestState = new Map<LensId, LensRequestState>();\n\n const lensTurnOffEvents = lensState.events.pipe(\n forActions(\"turnedOff\"),\n\n tap(([action]) => handleLensApplicationEnd(lensRequestState, action.data.id))\n );\n\n const uriRequestEvents = uriRequests.pipe(\n map((uriRequest) => {\n const lensId = uriRequest.lens.id;\n\n if (!lensRequestState.has(lensId)) {\n lensRequestState.set(lensId, {\n // Prepares a collection to store cancellation handlers.\n // A specific handler will be invoked when a cancellation request is issued by the lens.\n // All handlers will be invoked when the lens is replaced with another one or the session\n // is destroyed.\n cancellationHandlers: new Map(),\n // Parse lens metadata to obtain supported Remote API specs.\n supportedSpecIds: new Set(\n (lensRepository.getLensMetadata(lensId)?.featureMetadata ?? [])\n .filter((feature) => feature.typeUrl === remoteApiInfoProtobufTypeUrl)\n .flatMap((any) => RemoteApiInfo.decode(any.value).apiSpecIds)\n ),\n });\n }\n const requestState = lensRequestState.get(lensId)!;\n\n // Extracts the spec ID and endpoint ID from the provided Remote API request URI.\n // The given URI is expected to conform to the following specification:\n // eslint-disable-next-line max-len\n // https://docs.google.com/document/d/18fbGYDhD2N_aMTe4ZLY4QKeCSoMeJuklG28TutDzLZc/edit#bookmark=id.p2y39gwgbm4g\n const { route } = extractSchemeAndRoute(uriRequest.request.uri);\n const [specId, endpointIdWithQuery] = route.split(\"/\").slice(2);\n const [endpointId] = endpointIdWithQuery.split(\"?\");\n\n return { uriRequest, specId, endpointId, requestState };\n }),\n\n // only handle requests for API spec ID that current lens supports\n filter(({ specId, requestState }) => requestState.supportedSpecIds.has(specId)),\n\n // only handle requests if we have a registered service for it\n filter(({ specId }) => registeredServiceMap.has(specId)),\n\n map(({ uriRequest, specId, endpointId, requestState }) => {\n const dimensions = new Map([[\"specId\", specId]]);\n reporter.count(\"lens_remote-api_requests\", 1, dimensions);\n\n const remoteApiRequest: RemoteApiRequest = {\n apiSpecId: specId,\n body: uriRequest.request.data,\n endpointId,\n parameters: uriRequest.request.metadata,\n };\n\n // Looks for the first Remote API request handler.\n for (const service of registeredServiceMap.get(specId) ?? []) {\n let requestHandler: RemoteApiRequestHandler | undefined = undefined;\n try {\n requestHandler = service.getRequestHandler(remoteApiRequest, uriRequest.lens);\n } catch (error) {\n logger.warn(\"Client's Remote API request handler factory threw an error.\", error);\n }\n\n if (requestHandler) {\n reporter.count(\"lens_remote-api_handled-requests\", 1, dimensions);\n\n let cancellationHandler: RemoteApiCancelRequestHandler | void = undefined;\n try {\n // Calls client's Remote API handler to process the request.\n cancellationHandler = requestHandler((response) => {\n reporter.count(\"lens_remote-api_responses\", 1, dimensions);\n\n const responseCode = statusToResponseCodeMap[response.status] ?? ResponseCode.UNRECOGNIZED;\n const uriResponse: UriResponse = {\n code: uriResponseOkCode,\n description: \"\",\n contentType: apiBinaryContentType,\n data: response.body,\n metadata: {\n ...response.metadata,\n [apiResponseStatusHeader]: responseCodeToNumber(responseCode).toString(),\n },\n };\n uriRequest.reply(uriResponse);\n });\n } catch (error) {\n logger.warn(\"Client's Remote API request handler threw an error.\", error);\n }\n\n if (typeof cancellationHandler === \"function\") {\n requestState.cancellationHandlers.set(uriRequest.request.identifier, () => {\n try {\n cancellationHandler!();\n } catch (error) {\n logger.warn(\"Client's Remote API request cancellation handler threw an error.\", error);\n }\n });\n }\n\n break;\n }\n }\n })\n );\n\n const uriCancelRequestEvents = uriCancelRequests.pipe(\n tap((uriRequest) => {\n const cancellationHandlers = lensRequestState.get(uriRequest.lens.id)?.cancellationHandlers;\n if (cancellationHandlers) {\n callCancellationHandler(cancellationHandlers, uriRequest.request.requestId);\n }\n })\n );\n\n merge(lensTurnOffEvents, uriRequestEvents, uriCancelRequestEvents)\n .pipe(\n catchError((error, sourcePipe) => {\n // The expectation is that if an error occurs, it happens in our own implementation,\n // because app callbacks are wrapped with try..catch blocks.\n // Therefore, we would like to report this error.\n logger.error(error);\n reporter.count(\"lens_remote-api_errors\", 1);\n // Return the source pipe so that we can retry the pipe instead of just completing it.\n return sourcePipe;\n }),\n // When the pipe completes due to an error,\n // we want to resubscribe to the original pipe to keep it alive.\n retry(),\n takeUntil(sessionState.events.pipe(forActions(\"destroy\")))\n )\n .subscribe({\n complete: () => handleLensApplicationEnd(lensRequestState, ...lensRequestState.keys()),\n });\n\n return {\n uri: \"app://remote-api/performApiRequest\",\n\n handleRequest(request, reply, lens) {\n uriRequests.next({ request, reply, lens });\n },\n\n cancelRequest(request, lens) {\n uriCancelRequests.next({ request, lens });\n },\n };\n}\n"]}
1
+ {"version":3,"file":"RemoteApiServices.js","sourceRoot":"","sources":["../../src/extensions/RemoteApiServices.ts"],"names":[],"mappings":"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","sourcesContent":["import { Subject, catchError, filter, map, merge, retry, takeUntil, tap } from \"rxjs\";\nimport { forActions } from \"@snap/state-management\";\nimport { Injectable } from \"../dependency-injection/Injectable\";\nimport { RemoteApiInfo } from \"../generated-proto/pb_schema/camera_kit/v3/features/remote_api_info\";\nimport { ResponseCode, responseCodeToNumber } from \"../generated-proto/pb_schema/lenses/remote_api/remote_api_service\";\nimport { LensRepository } from \"../lens/LensRepository\";\nimport { Lens } from \"../lens/Lens\";\nimport { LensState } from \"../session/lensState\";\nimport { SessionState } from \"../session/sessionState\";\nimport { getLogger } from \"../logger/logger\";\nimport { CamelToSnakeCase, SnakeToCamelCase } from \"../common/types\";\nimport { MetricsClient } from \"../clients/metricsClient\";\nimport { Count } from \"../metrics/operational/Count\";\nimport { joinMetricNames } from \"../metrics/operational/Metric\";\nimport { UriCancelRequest, UriHandler, UriRequest, UriResponse, extractSchemeAndRoute } from \"./UriHandlers\";\n\n// NOTE: There's potential for overloads when reporting metrics if reporting is triggered on each frame,\n// (i.e., when the lens sends Remote API requests every frame).\n// As of now, this isn't a concern because src/metrics/operational/operationalMetricsReporter.ts aggregates\n// \"count\" metrics into a single metric within a batch, and the Remote API service currently\n// reports only \"count\" metrics. For instance, if 30 metrics with the same name are generated per second,\n// given the current bundle size of 100 operational metrics, there will be one metrics report approximately\n// every 3.3 seconds.\n// In the future, if we opt to report \"histogram\" or other metric types, they must be approached with caution:\n// either the operationalMetricsReporter should be enhanced to aggregate such metrics,\n// or the Remote API service should manage it directly.\n// Mobiles ticket: https://jira.sc-corp.net/browse/CAMKIT-3092\n\nconst logger = getLogger(\"RemoteApiServices\");\n\nconst uriResponseOkCode = 200;\nconst apiResponseStatusHeader = \":sc_lens_api_status\";\nconst apiBinaryContentType = \"application/octet-stream\";\nconst remoteApiInfoProtobufTypeUrl = \"type.googleapis.com/com.snap.camerakit.v3.features.RemoteApiInfo\";\n\nconst statusToResponseCodeMap = {\n success: ResponseCode.SUCCESS,\n redirected: ResponseCode.REDIRECTED,\n badRequest: ResponseCode.BAD_REQUEST,\n accessDenied: ResponseCode.ACCESS_DENIED,\n notFound: ResponseCode.NOT_FOUND,\n timeout: ResponseCode.TIMEOUT,\n requestTooLarge: ResponseCode.REQUEST_TOO_LARGE,\n serverError: ResponseCode.SERVER_ERROR,\n cancelled: ResponseCode.CANCELLED,\n proxyError: ResponseCode.PROXY_ERROR,\n} satisfies { [Status in RemoteApiStatusInternal]: Uppercase<CamelToSnakeCase<Status>> };\n\ntype RemoteApiStatusInternal = SnakeToCamelCase<\n Lowercase<Exclude<keyof typeof ResponseCode, \"RESPONSE_CODE_UNSET\" | \"UNRECOGNIZED\">>\n>;\n\ntype LensId = string;\ntype RequestId = string;\n\ntype UriRequestEvent = {\n request: UriRequest;\n reply: (response: UriResponse) => void;\n lens: Lens;\n};\n\ntype UriCancelRequestEvent = {\n request: UriCancelRequest;\n lens: Lens;\n};\n\ninterface LensRequestState {\n cancellationHandlers: Map<RequestId, RemoteApiCancelRequestHandler>;\n supportedSpecIds: Set<string>;\n}\n\n/**\n * Invokes the cancellation handler associated with the provided key and removes it from the collection of handlers.\n */\nfunction callCancellationHandler(\n cancellationHandlers: Map<RequestId, RemoteApiCancelRequestHandler>,\n ...keys: RequestId[]\n) {\n for (const key of keys) {\n cancellationHandlers.get(key)?.();\n cancellationHandlers.delete(key);\n }\n}\n\n/**\n * Removes the specified lenses' metadata from the cache and invokes their cancellation callbacks.\n *\n * @param lensRequestState The state representing the lens cache.\n * @param lensIds An array of lens IDs to be removed from the cache\n * and for which the cancellation callbacks will be invoked.\n */\nfunction handleLensApplicationEnd(lensRequestState: Map<LensId, LensRequestState>, ...lensIds: LensId[]) {\n for (const lensId of lensIds) {\n const state = lensRequestState.get(lensId);\n if (state) {\n callCancellationHandler(state.cancellationHandlers, ...state.cancellationHandlers.keys());\n lensRequestState.delete(lensId);\n }\n }\n}\n\n/**\n * Status of a Remote API response.\n */\nexport type RemoteApiStatus = keyof typeof statusToResponseCodeMap;\n\n/**\n * Remote API request sent by a lens.\n */\nexport interface RemoteApiRequest {\n /**\n * Unique id of the remote API service specification.\n */\n apiSpecId: string;\n /**\n * Unique id of the remote API service endpoint requested by this request.\n */\n endpointId: string;\n /**\n * A map of named parameters associated with the request.\n */\n parameters: Record<string, string>;\n /**\n * Additional binary request payload.\n */\n body: ArrayBuffer;\n}\n\n/**\n * Remote API response to a request sent by a lens.\n */\nexport interface RemoteApiResponse {\n /**\n * Status of the response\n */\n status: RemoteApiStatus;\n /**\n * A map of named metadata associated with the response.\n */\n metadata: Record<string, string>;\n /**\n * Additional binary request payload.\n */\n body: ArrayBuffer;\n}\n\n/**\n * Represents a Remote API request cancellation handler function.\n */\nexport type RemoteApiCancelRequestHandler = () => void;\n\n/**\n * Represents a Remote API request handler function.\n * It is provided with a reply callback that must be invoked to send a response back to the lens.\n * The reply callback can be invoked multiple times if needed.\n * Additionally, the handler can return a cancellation callback, which is triggered when the lens cancels the request.\n */\nexport type RemoteApiRequestHandler = (\n reply: (response: RemoteApiResponse) => void\n) => RemoteApiCancelRequestHandler | void;\n\n/**\n * Service to handle a lens Remote API request.\n */\nexport interface RemoteApiService {\n /**\n * Remote API spec ID(s).\n */\n apiSpecId: string;\n\n /**\n * This method is called by Camera Kit when a lens triggers a Remote API request with a corresponding spec ID.\n * If the service can handle the request, the method returns a request handler; otherwise, it returns nothing.\n * @param request Remote API request object.\n * @param lens Lens that trigges the request.\n * @returns A request handler if applicable.\n */\n getRequestHandler(request: RemoteApiRequest, lens: Lens): RemoteApiRequestHandler | undefined;\n}\n\nexport type RemoteApiServices = RemoteApiService[];\n\nexport const remoteApiServicesFactory = Injectable(\"remoteApiServices\", () => {\n const remoteApiServices: RemoteApiServices = [];\n return remoteApiServices;\n});\n\n/**\n * Provides a URI handler that searches for a match within the provided services to handle Remote API requests,\n * i.e., those whose URI starts with 'app://remote-api/performApiRequest'.\n */\nexport function getRemoteApiUriHandler(\n registeredServices: RemoteApiService[],\n sessionState: SessionState,\n lensState: LensState,\n lensRepository: LensRepository,\n metrics: MetricsClient\n): UriHandler {\n // Groups services by spec ID for faster lookups.\n const registeredServiceMap = new Map<string, RemoteApiService[]>();\n for (const service of registeredServices) {\n const existingServices = registeredServiceMap.get(service.apiSpecId) || [];\n registeredServiceMap.set(service.apiSpecId, [...existingServices, service]);\n }\n\n const uriRequests = new Subject<UriRequestEvent>();\n const uriCancelRequests = new Subject<UriCancelRequestEvent>();\n const lensRequestState = new Map<LensId, LensRequestState>();\n\n const lensTurnOffEvents = lensState.events.pipe(\n forActions(\"turnedOff\"),\n\n tap(([action]) => handleLensApplicationEnd(lensRequestState, action.data.id))\n );\n\n const uriRequestEvents = uriRequests.pipe(\n map((uriRequest) => {\n const lensId = uriRequest.lens.id;\n\n if (!lensRequestState.has(lensId)) {\n lensRequestState.set(lensId, {\n // Prepares a collection to store cancellation handlers.\n // A specific handler will be invoked when a cancellation request is issued by the lens.\n // All handlers will be invoked when the lens is replaced with another one or the session\n // is destroyed.\n cancellationHandlers: new Map(),\n // Parse lens metadata to obtain supported Remote API specs.\n supportedSpecIds: new Set(\n (lensRepository.getLensMetadata(lensId)?.featureMetadata ?? [])\n .filter((feature) => feature.typeUrl === remoteApiInfoProtobufTypeUrl)\n .flatMap((any) => RemoteApiInfo.decode(any.value).apiSpecIds)\n ),\n });\n }\n const requestState = lensRequestState.get(lensId)!;\n\n // Extracts the spec ID and endpoint ID from the provided Remote API request URI.\n // The given URI is expected to conform to the following specification:\n // eslint-disable-next-line max-len\n // https://docs.google.com/document/d/18fbGYDhD2N_aMTe4ZLY4QKeCSoMeJuklG28TutDzLZc/edit#bookmark=id.p2y39gwgbm4g\n const { route } = extractSchemeAndRoute(uriRequest.request.uri);\n const [specId, endpointIdWithQuery] = route.split(\"/\").slice(2);\n const [endpointId] = endpointIdWithQuery.split(\"?\");\n\n return { uriRequest, specId, endpointId, requestState };\n }),\n\n // only handle requests for API spec ID that current lens supports\n filter(({ specId, requestState }) => requestState.supportedSpecIds.has(specId)),\n\n // only handle requests if we have a registered service for it\n filter(({ specId }) => registeredServiceMap.has(specId)),\n\n map(({ uriRequest, specId, endpointId, requestState }) => {\n const dimensions = { specId };\n const reportSingleCount = (name: string) => {\n metrics.setOperationalMetrics(\n Count.count(joinMetricNames([\"lens\", \"remote-api\", name]), 1, dimensions)\n );\n };\n\n reportSingleCount(\"requests\");\n\n const remoteApiRequest: RemoteApiRequest = {\n apiSpecId: specId,\n body: uriRequest.request.data,\n endpointId,\n parameters: uriRequest.request.metadata,\n };\n\n // Looks for the first Remote API request handler.\n for (const service of registeredServiceMap.get(specId) ?? []) {\n let requestHandler: RemoteApiRequestHandler | undefined = undefined;\n try {\n requestHandler = service.getRequestHandler(remoteApiRequest, uriRequest.lens);\n } catch (error) {\n logger.warn(\"Client's Remote API request handler factory threw an error.\", error);\n }\n\n if (requestHandler) {\n reportSingleCount(\"handled-requests\");\n\n let cancellationHandler: RemoteApiCancelRequestHandler | void = undefined;\n try {\n // Calls client's Remote API handler to process the request.\n cancellationHandler = requestHandler((response) => {\n reportSingleCount(\"responses\");\n\n const responseCode = statusToResponseCodeMap[response.status] ?? ResponseCode.UNRECOGNIZED;\n const uriResponse: UriResponse = {\n code: uriResponseOkCode,\n description: \"\",\n contentType: apiBinaryContentType,\n data: response.body,\n metadata: {\n ...response.metadata,\n [apiResponseStatusHeader]: responseCodeToNumber(responseCode).toString(),\n },\n };\n uriRequest.reply(uriResponse);\n });\n } catch (error) {\n logger.warn(\"Client's Remote API request handler threw an error.\", error);\n }\n\n if (typeof cancellationHandler === \"function\") {\n requestState.cancellationHandlers.set(uriRequest.request.identifier, () => {\n try {\n cancellationHandler!();\n } catch (error) {\n logger.warn(\"Client's Remote API request cancellation handler threw an error.\", error);\n }\n });\n }\n\n break;\n }\n }\n })\n );\n\n const uriCancelRequestEvents = uriCancelRequests.pipe(\n tap((uriRequest) => {\n const cancellationHandlers = lensRequestState.get(uriRequest.lens.id)?.cancellationHandlers;\n if (cancellationHandlers) {\n callCancellationHandler(cancellationHandlers, uriRequest.request.requestId);\n }\n })\n );\n\n merge(lensTurnOffEvents, uriRequestEvents, uriCancelRequestEvents)\n .pipe(\n catchError((error, sourcePipe) => {\n // The expectation is that if an error occurs, it happens in our own implementation,\n // because app callbacks are wrapped with try..catch blocks.\n // Therefore, we would like to report this error.\n logger.error(error);\n metrics.setOperationalMetrics(Count.count(joinMetricNames([\"lens\", \"remote-api\", \"errors\"]), 1));\n // Return the source pipe so that we can retry the pipe instead of just completing it.\n return sourcePipe;\n }),\n // When the pipe completes due to an error,\n // we want to resubscribe to the original pipe to keep it alive.\n retry(),\n takeUntil(sessionState.events.pipe(forActions(\"destroy\")))\n )\n .subscribe({\n complete: () => handleLensApplicationEnd(lensRequestState, ...lensRequestState.keys()),\n });\n\n return {\n uri: \"app://remote-api/performApiRequest\",\n\n handleRequest(request, reply, lens) {\n uriRequests.next({ request, reply, lens });\n },\n\n cancelRequest(request, lens) {\n uriCancelRequests.next({ request, lens });\n },\n };\n}\n"]}
@@ -1,7 +1,7 @@
1
+ import { MetricsClient } from "../clients/metricsClient";
1
2
  import { LensKeyboard } from "../session/LensKeyboard";
2
3
  import { LensRepository } from "../lens/LensRepository";
3
- import { LensCore } from "../lens-core-module";
4
- import { OperationalMetricsReporter } from "../metrics/operational/operationalMetricsReporter";
4
+ import { LensCore } from "../lens-core-module/lensCore";
5
5
  import { RemoteApiServices } from "./RemoteApiServices";
6
6
  import { UriHandlers } from "./UriHandlers";
7
7
  /**
@@ -15,7 +15,7 @@ export declare const registerUriHandlers: {
15
15
  }> | import("@snap/state-management").Action<"downloadComplete", import("..").Lens> | import("@snap/state-management").Action<"turnedOn", import("..").Lens> | import("@snap/state-management").Action<"resourcesLoaded", import("..").Lens> | import("@snap/state-management").Action<"firstFrameProcessed", import("..").Lens> | import("@snap/state-management").Action<"applyLensComplete", import("..").Lens> | import("@snap/state-management").Action<"applyLensFailed", {
16
16
  error: import("../session/lensState").LensErrors;
17
17
  lens: import("..").Lens;
18
- }> | import("@snap/state-management").Action<"applyLensAborted", import("..").Lens> | import("@snap/state-management").Action<"removeLens", undefined> | import("@snap/state-management").Action<"turnedOff", import("..").Lens> | import("@snap/state-management").Action<"removeLensComplete", undefined> | import("@snap/state-management").Action<"removeLensFailed", Error>, import("@snap/state-management").State<"noLensApplied", undefined> | import("@snap/state-management").State<"applyingLens", import("..").Lens> | import("@snap/state-management").State<"lensApplied", import("..").Lens>>, args_2: UriHandlers, args_3: LensKeyboard, args_4: RemoteApiServices, args_5: LensRepository, args_6: import("@snap/state-management").StateMachine<import("@snap/state-management").Action<"suspend", import("..").CameraKitSession> | import("@snap/state-management").Action<"resume", import("..").CameraKitSession> | import("@snap/state-management").Action<"destroy", undefined>, import("@snap/state-management").State<"inactive", undefined> | import("@snap/state-management").State<"active", import("..").CameraKitSession> | import("@snap/state-management").State<"destroyed", undefined>>, args_7: OperationalMetricsReporter): void;
18
+ }> | import("@snap/state-management").Action<"applyLensAborted", import("..").Lens> | import("@snap/state-management").Action<"removeLens", undefined> | import("@snap/state-management").Action<"turnedOff", import("..").Lens> | import("@snap/state-management").Action<"removeLensComplete", undefined> | import("@snap/state-management").Action<"removeLensFailed", Error>, import("@snap/state-management").State<"noLensApplied", undefined> | import("@snap/state-management").State<"applyingLens", import("..").Lens> | import("@snap/state-management").State<"lensApplied", import("..").Lens>>, args_2: UriHandlers, args_3: LensKeyboard, args_4: RemoteApiServices, args_5: LensRepository, args_6: import("@snap/state-management").StateMachine<import("@snap/state-management").Action<"suspend", import("..").CameraKitSession> | import("@snap/state-management").Action<"resume", import("..").CameraKitSession> | import("@snap/state-management").Action<"destroy", undefined>, import("@snap/state-management").State<"inactive", undefined> | import("@snap/state-management").State<"active", import("..").CameraKitSession> | import("@snap/state-management").State<"destroyed", undefined>>, args_7: MetricsClient): void;
19
19
  token: "registerUriHandlers";
20
- dependencies: readonly ["lensCore", "lensState", "UriHandlers", "lensKeyboard", "remoteApiServices", "LensRepository", "sessionState", "operationalMetricsReporter"];
20
+ dependencies: readonly ["lensCore", "lensState", "UriHandlers", "lensKeyboard", "remoteApiServices", "LensRepository", "sessionState", "metricsClient"];
21
21
  };
@@ -1,14 +1,14 @@
1
1
  import { isState } from "@snap/state-management";
2
+ import { metricsClientFactory } from "../clients/metricsClient";
2
3
  import { Injectable } from "../dependency-injection/Injectable";
3
4
  import { lensKeyboardFactory } from "../session/LensKeyboard";
4
5
  import { lensStateFactory } from "../session/lensState";
5
6
  import { lensRepositoryFactory } from "../lens/LensRepository";
6
7
  import { sessionStateFactory } from "../session/sessionState";
7
- import { lensCoreFactory } from "../lens-core-module";
8
8
  import { getLogger } from "../logger/logger";
9
- import { operationalMetricReporterFactory, } from "../metrics/operational/operationalMetricsReporter";
9
+ import { lensCoreFactory } from "../lens-core-module/loader/lensCoreFactory";
10
10
  import { getRemoteApiUriHandler, remoteApiServicesFactory } from "./RemoteApiServices";
11
- import { extractSchemeAndRoute, isUriHandlers, isUriResponse, uriHandlersFactory } from "./UriHandlers";
11
+ import { extractSchemeAndRoute, isUriHandlers, isUriResponse, uriHandlersFactory, } from "./UriHandlers";
12
12
  const logger = getLogger("uriHandlersRegister");
13
13
  /**
14
14
  * Registers URI handlers within LensCore.
@@ -22,14 +22,14 @@ export const registerUriHandlers = Injectable("registerUriHandlers", [
22
22
  remoteApiServicesFactory.token,
23
23
  lensRepositoryFactory.token,
24
24
  sessionStateFactory.token,
25
- operationalMetricReporterFactory.token,
26
- ], (lensCore, lensState, userHandlers, lensKeyboard, remoteApiServices, lensRepository, sessionState, operationalMetricsReporter) => {
25
+ metricsClientFactory.token,
26
+ ], (lensCore, lensState, userHandlers, lensKeyboard, remoteApiServices, lensRepository, sessionState, metrics) => {
27
27
  if (!isUriHandlers(userHandlers)) {
28
28
  throw new Error("Expected an array of UriHandler objects");
29
29
  }
30
30
  // Users may define UriHandlers using the uriHandlersFactory.token, but we need to add some internally-defined
31
31
  // handlers (lens keyboard and Remote API) before registering handlers with LensCore.
32
- const allHandlers = userHandlers.concat(lensKeyboard.uriHandler, getRemoteApiUriHandler(remoteApiServices, sessionState, lensState, lensRepository, operationalMetricsReporter));
32
+ const allHandlers = userHandlers.concat(lensKeyboard.uriHandler, getRemoteApiUriHandler(remoteApiServices, sessionState, lensState, lensRepository, metrics));
33
33
  for (const { uri, handleRequest, cancelRequest } of allHandlers) {
34
34
  const uris = Array.isArray(uri) ? uri : [uri];
35
35
  for (const { scheme, route } of uris.map(extractSchemeAndRoute)) {
@@ -1 +1 @@
1
- {"version":3,"file":"uriHandlersRegister.js","sourceRoot":"","sources":["../../src/extensions/uriHandlersRegister.ts"],"names":[],"mappings":"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","sourcesContent":["import { isState } from \"@snap/state-management\";\n\nimport { Injectable } from \"../dependency-injection/Injectable\";\nimport { LensKeyboard, lensKeyboardFactory } from \"../session/LensKeyboard\";\nimport { LensState, lensStateFactory } from \"../session/lensState\";\nimport { LensRepository, lensRepositoryFactory } from \"../lens/LensRepository\";\nimport { SessionState, sessionStateFactory } from \"../session/sessionState\";\nimport { LensCore, UriResponse, lensCoreFactory } from \"../lens-core-module\";\nimport { getLogger } from \"../logger/logger\";\nimport {\n OperationalMetricsReporter,\n operationalMetricReporterFactory,\n} from \"../metrics/operational/operationalMetricsReporter\";\nimport { RemoteApiServices, getRemoteApiUriHandler, remoteApiServicesFactory } from \"./RemoteApiServices\";\nimport { UriHandlers, extractSchemeAndRoute, isUriHandlers, isUriResponse, uriHandlersFactory } from \"./UriHandlers\";\n\nconst logger = getLogger(\"uriHandlersRegister\");\n\n/**\n * Registers URI handlers within LensCore.\n * @internal\n */\nexport const registerUriHandlers = Injectable(\n \"registerUriHandlers\",\n [\n lensCoreFactory.token,\n lensStateFactory.token,\n uriHandlersFactory.token,\n lensKeyboardFactory.token,\n remoteApiServicesFactory.token,\n lensRepositoryFactory.token,\n sessionStateFactory.token,\n operationalMetricReporterFactory.token,\n ] as const,\n (\n lensCore: LensCore,\n lensState: LensState,\n userHandlers: UriHandlers,\n lensKeyboard: LensKeyboard,\n remoteApiServices: RemoteApiServices,\n lensRepository: LensRepository,\n sessionState: SessionState,\n operationalMetricsReporter: OperationalMetricsReporter\n ): void => {\n if (!isUriHandlers(userHandlers)) {\n throw new Error(\"Expected an array of UriHandler objects\");\n }\n\n // Users may define UriHandlers using the uriHandlersFactory.token, but we need to add some internally-defined\n // handlers (lens keyboard and Remote API) before registering handlers with LensCore.\n const allHandlers = userHandlers.concat(\n lensKeyboard.uriHandler,\n getRemoteApiUriHandler(\n remoteApiServices,\n sessionState,\n lensState,\n lensRepository,\n operationalMetricsReporter\n )\n );\n\n for (const { uri, handleRequest, cancelRequest } of allHandlers) {\n const uris = Array.isArray(uri) ? uri : [uri];\n for (const { scheme, route } of uris.map(extractSchemeAndRoute)) {\n lensCore.registerUriListener(scheme, route, {\n handleRequest: (request) => {\n const reply = (response: UriResponse) => {\n if (!isUriResponse(response)) {\n throw new Error(\"Expected UriResponse object\");\n }\n lensCore.provideUriResponse(request.identifier, response);\n };\n\n // Since lenses are the only things that make URI requests, we expect to always be in the\n // \"lensApplied\" state – we'll sanity check, though, and log a warning if we're not.\n const state = lensState.getState();\n if (isState(state, \"noLensApplied\")) {\n logger.warn(\n `Got a URI request for ${request.uri}, but there is no active lens. The ` +\n `request will not be processed.`\n );\n return;\n }\n\n // NOTE: we do not handle any error thrown on an extension side when handleRequest() is called.\n // That responsibility is delegated to the extension by design and that is exactly what Android\n // and iOS SDKs do.\n handleRequest(request, reply, state.data);\n },\n cancelRequest: (request) => {\n if (cancelRequest) {\n const state = lensState.getState();\n if (isState(state, \"noLensApplied\")) {\n logger.warn(\n `Got a URI cancel request for ${request.uri}, but there is no active ` +\n `lens. The cancel request will not be processed.`\n );\n return;\n }\n cancelRequest(request, state.data);\n }\n },\n });\n }\n }\n }\n);\n"]}
1
+ {"version":3,"file":"uriHandlersRegister.js","sourceRoot":"","sources":["../../src/extensions/uriHandlersRegister.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AACjD,OAAO,EAAiB,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;AAC/E,OAAO,EAAE,UAAU,EAAE,MAAM,oCAAoC,CAAC;AAChE,OAAO,EAAgB,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAC5E,OAAO,EAAa,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AACnE,OAAO,EAAkB,qBAAqB,EAAE,MAAM,wBAAwB,CAAC;AAC/E,OAAO,EAAgB,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAC5E,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,EAAE,eAAe,EAAE,MAAM,4CAA4C,CAAC;AAE7E,OAAO,EAAqB,sBAAsB,EAAE,wBAAwB,EAAE,MAAM,qBAAqB,CAAC;AAC1G,OAAO,EAGH,qBAAqB,EACrB,aAAa,EACb,aAAa,EACb,kBAAkB,GACrB,MAAM,eAAe,CAAC;AAEvB,MAAM,MAAM,GAAG,SAAS,CAAC,qBAAqB,CAAC,CAAC;AAEhD;;;GAGG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,UAAU,CACzC,qBAAqB,EACrB;IACI,eAAe,CAAC,KAAK;IACrB,gBAAgB,CAAC,KAAK;IACtB,kBAAkB,CAAC,KAAK;IACxB,mBAAmB,CAAC,KAAK;IACzB,wBAAwB,CAAC,KAAK;IAC9B,qBAAqB,CAAC,KAAK;IAC3B,mBAAmB,CAAC,KAAK;IACzB,oBAAoB,CAAC,KAAK;CACpB,EACV,CACI,QAAkB,EAClB,SAAoB,EACpB,YAAyB,EACzB,YAA0B,EAC1B,iBAAoC,EACpC,cAA8B,EAC9B,YAA0B,EAC1B,OAAsB,EAClB,EAAE;IACN,IAAI,CAAC,aAAa,CAAC,YAAY,CAAC,EAAE;QAC9B,MAAM,IAAI,KAAK,CAAC,yCAAyC,CAAC,CAAC;KAC9D;IAED,8GAA8G;IAC9G,qFAAqF;IACrF,MAAM,WAAW,GAAG,YAAY,CAAC,MAAM,CACnC,YAAY,CAAC,UAAU,EACvB,sBAAsB,CAAC,iBAAiB,EAAE,YAAY,EAAE,SAAS,EAAE,cAAc,EAAE,OAAO,CAAC,CAC9F,CAAC;IAEF,KAAK,MAAM,EAAE,GAAG,EAAE,aAAa,EAAE,aAAa,EAAE,IAAI,WAAW,EAAE;QAC7D,MAAM,IAAI,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;QAC9C,KAAK,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,IAAI,CAAC,GAAG,CAAC,qBAAqB,CAAC,EAAE;YAC7D,QAAQ,CAAC,mBAAmB,CAAC,MAAM,EAAE,KAAK,EAAE;gBACxC,aAAa,EAAE,CAAC,OAAO,EAAE,EAAE;oBACvB,MAAM,KAAK,GAAG,CAAC,QAAqB,EAAE,EAAE;wBACpC,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,EAAE;4BAC1B,MAAM,IAAI,KAAK,CAAC,6BAA6B,CAAC,CAAC;yBAClD;wBACD,QAAQ,CAAC,kBAAkB,CAAC,OAAO,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;oBAC9D,CAAC,CAAC;oBAEF,yFAAyF;oBACzF,oFAAoF;oBACpF,MAAM,KAAK,GAAG,SAAS,CAAC,QAAQ,EAAE,CAAC;oBACnC,IAAI,OAAO,CAAC,KAAK,EAAE,eAAe,CAAC,EAAE;wBACjC,MAAM,CAAC,IAAI,CACP,yBAAyB,OAAO,CAAC,GAAG,qCAAqC;4BACrE,gCAAgC,CACvC,CAAC;wBACF,OAAO;qBACV;oBAED,+FAA+F;oBAC/F,+FAA+F;oBAC/F,mBAAmB;oBACnB,aAAa,CAAC,OAAO,EAAE,KAAK,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;gBAC9C,CAAC;gBACD,aAAa,EAAE,CAAC,OAAO,EAAE,EAAE;oBACvB,IAAI,aAAa,EAAE;wBACf,MAAM,KAAK,GAAG,SAAS,CAAC,QAAQ,EAAE,CAAC;wBACnC,IAAI,OAAO,CAAC,KAAK,EAAE,eAAe,CAAC,EAAE;4BACjC,MAAM,CAAC,IAAI,CACP,gCAAgC,OAAO,CAAC,GAAG,2BAA2B;gCAClE,iDAAiD,CACxD,CAAC;4BACF,OAAO;yBACV;wBACD,aAAa,CAAC,OAAO,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;qBACtC;gBACL,CAAC;aACJ,CAAC,CAAC;SACN;KACJ;AACL,CAAC,CACJ,CAAC","sourcesContent":["import { isState } from \"@snap/state-management\";\nimport { MetricsClient, metricsClientFactory } from \"../clients/metricsClient\";\nimport { Injectable } from \"../dependency-injection/Injectable\";\nimport { LensKeyboard, lensKeyboardFactory } from \"../session/LensKeyboard\";\nimport { LensState, lensStateFactory } from \"../session/lensState\";\nimport { LensRepository, lensRepositoryFactory } from \"../lens/LensRepository\";\nimport { SessionState, sessionStateFactory } from \"../session/sessionState\";\nimport { getLogger } from \"../logger/logger\";\nimport { lensCoreFactory } from \"../lens-core-module/loader/lensCoreFactory\";\nimport { LensCore } from \"../lens-core-module/lensCore\";\nimport { RemoteApiServices, getRemoteApiUriHandler, remoteApiServicesFactory } from \"./RemoteApiServices\";\nimport {\n UriHandlers,\n UriResponse,\n extractSchemeAndRoute,\n isUriHandlers,\n isUriResponse,\n uriHandlersFactory,\n} from \"./UriHandlers\";\n\nconst logger = getLogger(\"uriHandlersRegister\");\n\n/**\n * Registers URI handlers within LensCore.\n * @internal\n */\nexport const registerUriHandlers = Injectable(\n \"registerUriHandlers\",\n [\n lensCoreFactory.token,\n lensStateFactory.token,\n uriHandlersFactory.token,\n lensKeyboardFactory.token,\n remoteApiServicesFactory.token,\n lensRepositoryFactory.token,\n sessionStateFactory.token,\n metricsClientFactory.token,\n ] as const,\n (\n lensCore: LensCore,\n lensState: LensState,\n userHandlers: UriHandlers,\n lensKeyboard: LensKeyboard,\n remoteApiServices: RemoteApiServices,\n lensRepository: LensRepository,\n sessionState: SessionState,\n metrics: MetricsClient\n ): void => {\n if (!isUriHandlers(userHandlers)) {\n throw new Error(\"Expected an array of UriHandler objects\");\n }\n\n // Users may define UriHandlers using the uriHandlersFactory.token, but we need to add some internally-defined\n // handlers (lens keyboard and Remote API) before registering handlers with LensCore.\n const allHandlers = userHandlers.concat(\n lensKeyboard.uriHandler,\n getRemoteApiUriHandler(remoteApiServices, sessionState, lensState, lensRepository, metrics)\n );\n\n for (const { uri, handleRequest, cancelRequest } of allHandlers) {\n const uris = Array.isArray(uri) ? uri : [uri];\n for (const { scheme, route } of uris.map(extractSchemeAndRoute)) {\n lensCore.registerUriListener(scheme, route, {\n handleRequest: (request) => {\n const reply = (response: UriResponse) => {\n if (!isUriResponse(response)) {\n throw new Error(\"Expected UriResponse object\");\n }\n lensCore.provideUriResponse(request.identifier, response);\n };\n\n // Since lenses are the only things that make URI requests, we expect to always be in the\n // \"lensApplied\" state – we'll sanity check, though, and log a warning if we're not.\n const state = lensState.getState();\n if (isState(state, \"noLensApplied\")) {\n logger.warn(\n `Got a URI request for ${request.uri}, but there is no active lens. The ` +\n `request will not be processed.`\n );\n return;\n }\n\n // NOTE: we do not handle any error thrown on an extension side when handleRequest() is called.\n // That responsibility is delegated to the extension by design and that is exactly what Android\n // and iOS SDKs do.\n handleRequest(request, reply, state.data);\n },\n cancelRequest: (request) => {\n if (cancelRequest) {\n const state = lensState.getState();\n if (isState(state, \"noLensApplied\")) {\n logger.warn(\n `Got a URI cancel request for ${request.uri}, but there is no active ` +\n `lens. The cancel request will not be processed.`\n );\n return;\n }\n cancelRequest(request, state.data);\n }\n },\n });\n }\n }\n }\n);\n"]}