@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.
- package/LICENSE.md +139 -3873
- package/README.md +3 -3
- package/docs/html/assets/main.js +4 -3
- package/docs/html/assets/navigation.js +1 -0
- package/docs/html/assets/search.js +1 -1
- package/docs/html/assets/style.css +72 -25
- package/docs/html/classes/CameraKit.html +11 -196
- package/docs/html/classes/CameraKitSession.html +43 -366
- package/docs/html/classes/CameraKitSource.html +14 -223
- package/docs/html/classes/LensPerformanceMeasurement.html +9 -184
- package/docs/html/classes/LensPerformanceMetrics.html +7 -148
- package/docs/html/classes/LensRepository.html +17 -234
- package/docs/html/classes/Transform2D.html +7 -176
- package/docs/html/classes/TypedCustomEvent.html +4 -178
- package/docs/html/classes/TypedEventTarget.html +4 -209
- package/docs/html/enums/Lens_CameraFacing.html +5 -0
- package/docs/html/enums/UserData_Zodiac.html +15 -0
- package/docs/html/functions/ConcatInjectable.html +10 -193
- package/docs/html/functions/Injectable.html +9 -192
- package/docs/html/functions/bootstrapCameraKit.html +6 -147
- package/docs/html/functions/createExtension.html +6 -123
- package/docs/html/functions/createImageSource.html +4 -130
- package/docs/html/functions/createMediaStreamSource.html +4 -130
- package/docs/html/functions/createVideoSource.html +4 -130
- package/docs/html/functions/estimateLensPerformance.html +3 -120
- package/docs/html/functions/lensSourcesFactory.html +6 -127
- package/docs/html/functions/remoteApiServicesFactory.html +3 -121
- package/docs/html/hierarchy.html +1 -0
- package/docs/html/index.html +8 -165
- package/docs/html/interfaces/CameraKitBootstrapConfiguration.html +11 -192
- package/docs/html/interfaces/CameraKitDeviceOptions.html +11 -0
- package/docs/html/interfaces/CameraKitSourceInfo.html +9 -0
- package/docs/html/interfaces/CameraKitSourceSubscriber.html +3 -194
- package/docs/html/interfaces/ComputedFrameMetrics.html +2 -150
- package/docs/html/interfaces/CreateSessionOptions.html +5 -148
- package/docs/html/interfaces/EstimatedLensPerformance.html +3 -146
- package/docs/html/interfaces/FunctionSourceOptions.html +7 -0
- package/docs/html/interfaces/Lens.html +12 -205
- package/docs/html/interfaces/LensCreator.html +3 -0
- package/docs/html/interfaces/LensLaunchData.html +3 -179
- package/docs/html/interfaces/LensSource.html +3 -172
- package/docs/html/interfaces/LoadAssetRequest.html +13 -0
- package/docs/html/interfaces/MediaStreamSourceOptions.html +16 -138
- package/docs/html/interfaces/Preview.html +4 -141
- package/docs/html/interfaces/RemoteApiRequest.html +7 -162
- package/docs/html/interfaces/RemoteApiResponse.html +6 -155
- package/docs/html/interfaces/RemoteApiService.html +9 -171
- package/docs/html/interfaces/Snapcode.html +5 -148
- package/docs/html/interfaces/UriCancelRequest.html +2 -138
- package/docs/html/interfaces/UriRequest.html +2 -154
- package/docs/html/interfaces/UriResponse.html +2 -150
- package/docs/html/interfaces/VideoSourceOptions.html +15 -134
- package/docs/html/modules.html +57 -175
- package/docs/html/types/AssetLoader.html +5 -132
- package/docs/html/types/AssetResponse.html +1 -0
- package/docs/html/types/AssetTiming.html +2 -115
- package/docs/html/types/BenchmarkError.html +1 -112
- package/docs/html/types/BootstrapError.html +2 -115
- package/docs/html/types/CacheKeyNotFoundError.html +1 -112
- package/docs/html/types/CameraKitSessionEventListener.html +2 -115
- package/docs/html/types/CameraKitSessionEvents.html +2 -122
- package/docs/html/types/CameraKitSourceError.html +1 -112
- package/docs/html/types/ConfigurationError.html +2 -115
- package/docs/html/types/FetchHandler.html +1 -0
- package/docs/html/types/Keyboard.html +14 -194
- package/docs/html/types/KeyboardEvents.html +2 -124
- package/docs/html/types/LegalError.html +1 -112
- package/docs/html/types/LensAbortError.html +2 -115
- package/docs/html/types/LensAssetError.html +2 -115
- package/docs/html/types/LensContentValidationError.html +1 -112
- package/docs/html/types/LensError.html +1 -112
- package/docs/html/types/LensExecutionError.html +2 -115
- package/docs/html/types/LensImagePickerError.html +2 -115
- package/docs/html/types/LensLaunchParams.html +2 -0
- package/docs/html/types/LensMetricsEvents.html +2 -115
- package/docs/html/types/LensPerformanceCluster.html +1 -113
- package/docs/html/types/LensView.html +2 -115
- package/docs/html/types/LensWait.html +2 -115
- package/docs/html/types/Matrix.html +3 -0
- package/docs/html/types/PersistentStoreError.html +2 -115
- package/docs/html/types/PlatformNotSupportedError.html +2 -115
- package/docs/html/types/PublicContainer.html +2 -115
- package/docs/html/types/PublicServices.html +2 -0
- package/docs/html/types/RemoteApiCancelRequestHandler.html +2 -0
- package/docs/html/types/RemoteApiRequestHandler.html +2 -139
- package/docs/html/types/RemoteApiServices.html +1 -112
- package/docs/html/types/RemoteApiStatus.html +2 -115
- package/docs/html/types/RenderTarget.html +2 -115
- package/docs/html/types/Uri.html +1 -112
- package/docs/html/types/WebGLError.html +1 -112
- package/docs/html/variables/extensionRequestContext.html +2 -115
- package/docs/md/README.md +3 -3
- package/docs/md/classes/CameraKit.md +15 -15
- package/docs/md/classes/CameraKitSession.md +38 -38
- package/docs/md/classes/CameraKitSource.md +22 -30
- package/docs/md/classes/LensPerformanceMeasurement.md +10 -6
- package/docs/md/classes/LensPerformanceMetrics.md +2 -2
- package/docs/md/classes/LensRepository.md +18 -18
- package/docs/md/classes/Transform2D.md +7 -3
- package/docs/md/classes/TypedCustomEvent.md +10 -6
- package/docs/md/classes/TypedEventTarget.md +12 -8
- package/docs/md/enums/Lens_CameraFacing.md +36 -0
- package/docs/md/enums/UserData_Zodiac.md +106 -0
- package/docs/md/interfaces/CameraKitBootstrapConfiguration.md +2 -2
- package/docs/md/interfaces/CameraKitDeviceOptions.md +41 -0
- package/docs/md/interfaces/CameraKitSourceInfo.md +43 -0
- package/docs/md/interfaces/CameraKitSourceSubscriber.md +7 -7
- package/docs/md/interfaces/ComputedFrameMetrics.md +1 -1
- package/docs/md/interfaces/CreateSessionOptions.md +1 -1
- package/docs/md/interfaces/EstimatedLensPerformance.md +1 -1
- package/docs/md/interfaces/FunctionSourceOptions.md +22 -0
- package/docs/md/interfaces/Lens.md +4 -4
- package/docs/md/interfaces/LensCreator.md +17 -0
- package/docs/md/interfaces/LensLaunchData.md +6 -6
- package/docs/md/interfaces/LensSource.md +5 -5
- package/docs/md/interfaces/LoadAssetRequest.md +49 -0
- package/docs/md/interfaces/MediaStreamSourceOptions.md +46 -1
- package/docs/md/interfaces/Preview.md +1 -1
- package/docs/md/interfaces/RemoteApiRequest.md +2 -2
- package/docs/md/interfaces/RemoteApiResponse.md +2 -2
- package/docs/md/interfaces/RemoteApiService.md +1 -1
- package/docs/md/interfaces/Snapcode.md +1 -1
- package/docs/md/interfaces/UriCancelRequest.md +2 -2
- package/docs/md/interfaces/UriRequest.md +3 -3
- package/docs/md/interfaces/UriResponse.md +2 -2
- package/docs/md/interfaces/VideoSourceOptions.md +44 -1
- package/docs/md/modules.md +183 -201
- package/lib/CameraKit.d.ts +108 -108
- package/lib/CameraKit.js +1 -1
- package/lib/CameraKit.js.map +1 -1
- package/lib/bootstrapCameraKit.d.ts +4 -4
- package/lib/bootstrapCameraKit.js +21 -20
- package/lib/bootstrapCameraKit.js.map +1 -1
- package/lib/clients/createTsProtoClient.d.ts +5 -12
- package/lib/clients/createTsProtoClient.js +1 -2
- package/lib/clients/createTsProtoClient.js.map +1 -1
- package/lib/clients/grpcHandler.d.ts +7 -4
- package/lib/clients/grpcHandler.js +8 -5
- package/lib/clients/grpcHandler.js.map +1 -1
- package/lib/clients/lensesClient.d.ts +3 -3
- package/lib/clients/lensesClient.js +2 -2
- package/lib/clients/lensesClient.js.map +1 -1
- package/lib/clients/metricsClient.d.ts +26 -0
- package/lib/clients/metricsClient.js +120 -0
- package/lib/clients/metricsClient.js.map +1 -0
- package/lib/configuration.js +1 -1
- package/lib/configuration.js.map +1 -1
- package/lib/dependency-injection/Container.d.ts +1 -1
- package/lib/dependency-injection/Container.js +1 -1
- package/lib/dependency-injection/Container.js.map +1 -1
- package/lib/dependency-injection/Injectable.d.ts +6 -6
- package/lib/dependency-injection/Injectable.js.map +1 -1
- package/lib/dependency-injection/RootServices.d.ts +7 -8
- package/lib/dependency-injection/RootServices.js.map +1 -1
- package/lib/environment.d.ts +4 -0
- package/lib/environment.js +2 -0
- package/lib/environment.js.map +1 -0
- package/lib/extensions/RemoteApiServices.d.ts +2 -2
- package/lib/extensions/RemoteApiServices.js +11 -6
- package/lib/extensions/RemoteApiServices.js.map +1 -1
- package/lib/extensions/uriHandlersRegister.d.ts +4 -4
- package/lib/extensions/uriHandlersRegister.js +6 -6
- package/lib/extensions/uriHandlersRegister.js.map +1 -1
- package/lib/generated-proto/blizzard/cameraKitEvents.d.ts +4330 -678
- package/lib/generated-proto/blizzard/cameraKitEvents.js +515 -72
- package/lib/generated-proto/blizzard/cameraKitEvents.js.map +1 -1
- package/lib/generated-proto/pb_schema/camera_kit/v3/business_events.d.ts +3 -11
- package/lib/generated-proto/pb_schema/camera_kit/v3/business_events.js +6 -156
- package/lib/generated-proto/pb_schema/camera_kit/v3/business_events.js.map +1 -1
- package/lib/generated-proto/pb_schema/camera_kit/v3/export.d.ts +19 -19
- package/lib/generated-proto/pb_schema/camera_kit/v3/export.js +13 -27
- package/lib/generated-proto/pb_schema/camera_kit/v3/export.js.map +1 -1
- package/lib/generated-proto/pb_schema/camera_kit/v3/legal_prompt.d.ts +0 -6
- package/lib/generated-proto/pb_schema/camera_kit/v3/legal_prompt.js +2 -83
- package/lib/generated-proto/pb_schema/camera_kit/v3/legal_prompt.js.map +1 -1
- package/lib/generated-proto/pb_schema/camera_kit/v3/lens.d.ts +0 -22
- package/lib/generated-proto/pb_schema/camera_kit/v3/lens.js +0 -263
- package/lib/generated-proto/pb_schema/camera_kit/v3/lens.js.map +1 -1
- package/lib/generated-proto/pb_schema/camera_kit/v3/operational_metrics.d.ts +30 -34
- package/lib/generated-proto/pb_schema/camera_kit/v3/operational_metrics.js +7 -73
- package/lib/generated-proto/pb_schema/camera_kit/v3/operational_metrics.js.map +1 -1
- package/lib/generated-proto/pb_schema/camera_kit/v3/ranking.d.ts +0 -6
- package/lib/generated-proto/pb_schema/camera_kit/v3/ranking.js +0 -110
- package/lib/generated-proto/pb_schema/camera_kit/v3/ranking.js.map +1 -1
- package/lib/generated-proto/pb_schema/camera_kit/v3/service.d.ts +48 -114
- package/lib/generated-proto/pb_schema/camera_kit/v3/service.js +0 -225
- package/lib/generated-proto/pb_schema/camera_kit/v3/service.js.map +1 -1
- package/lib/generated-proto/pb_schema/cdp/cof/benchmark.d.ts +6 -6
- package/lib/generated-proto/pb_schema/cdp/cof/benchmark.js +5 -19
- package/lib/generated-proto/pb_schema/cdp/cof/benchmark.js.map +1 -1
- package/lib/generated-proto/pb_schema/cdp/cof/circumstance_service.d.ts +1422 -1422
- package/lib/generated-proto/pb_schema/cdp/cof/config_request.d.ts +12 -12
- package/lib/generated-proto/pb_schema/cdp/cof/config_request.js +10 -24
- package/lib/generated-proto/pb_schema/cdp/cof/config_request.js.map +1 -1
- package/lib/generated-proto/pb_schema/cdp/cof/config_response.d.ts +207 -207
- package/lib/generated-proto/pb_schema/cdp/cof/config_result.d.ts +530 -530
- package/lib/generated-proto/pb_schema/cdp/cof/config_result.js +10 -24
- package/lib/generated-proto/pb_schema/cdp/cof/config_result.js.map +1 -1
- package/lib/generated-proto/pb_schema/common/value.d.ts +6 -6
- package/lib/generated-proto/pb_schema/common/value.js +4 -18
- package/lib/generated-proto/pb_schema/common/value.js.map +1 -1
- package/lib/generated-proto/pb_schema/google/api/http.d.ts +0 -6
- package/lib/generated-proto/pb_schema/google/api/http.js +0 -77
- package/lib/generated-proto/pb_schema/google/api/http.js.map +1 -1
- package/lib/generated-proto/pb_schema/google/protobuf/any.d.ts +0 -2
- package/lib/generated-proto/pb_schema/google/protobuf/any.js +0 -44
- package/lib/generated-proto/pb_schema/google/protobuf/any.js.map +1 -1
- package/lib/generated-proto/pb_schema/google/protobuf/descriptor.d.ts +4830 -4896
- package/lib/generated-proto/pb_schema/google/protobuf/descriptor.js +10 -997
- package/lib/generated-proto/pb_schema/google/protobuf/descriptor.js.map +1 -1
- package/lib/generated-proto/pb_schema/google/protobuf/timestamp.d.ts +3 -5
- package/lib/generated-proto/pb_schema/google/protobuf/timestamp.js +6 -35
- package/lib/generated-proto/pb_schema/google/protobuf/timestamp.js.map +1 -1
- package/lib/generated-proto/pb_schema/google/protobuf/wrappers.d.ts +6 -6
- package/lib/generated-proto/pb_schema/google/protobuf/wrappers.js +10 -24
- package/lib/generated-proto/pb_schema/google/protobuf/wrappers.js.map +1 -1
- package/lib/generated-proto/pb_schema/lenses/launchdata.d.ts +9 -9
- package/lib/generated-proto/pb_schema/lenses/remote_api/remote_api_service.d.ts +11 -11
- package/lib/generated-proto/pb_schema/lenses/remote_api/remote_api_service.js +6 -20
- package/lib/generated-proto/pb_schema/lenses/remote_api/remote_api_service.js.map +1 -1
- package/lib/generated-proto/pb_schema/lenses/snappable.d.ts +42 -42
- package/lib/generated-proto/pb_schema/lenses/snappable.js +14 -28
- package/lib/generated-proto/pb_schema/lenses/snappable.js.map +1 -1
- package/lib/generated-proto/pb_schema/lenses/user_data.d.ts +8 -8
- package/lib/generated-proto/pb_schema/lenses/user_data.js +8 -22
- package/lib/generated-proto/pb_schema/lenses/user_data.js.map +1 -1
- package/lib/handlers/defaultFetchHandler.d.ts +1 -1
- package/lib/handlers/defaultFetchHandler.js.map +1 -1
- package/lib/handlers/requestStateEmittingHandler.d.ts +5 -6
- package/lib/handlers/requestStateEmittingHandler.js +6 -8
- package/lib/handlers/requestStateEmittingHandler.js.map +1 -1
- package/lib/handlers/responseCachingHandler.d.ts +9 -10
- package/lib/handlers/responseCachingHandler.js +9 -3
- package/lib/handlers/responseCachingHandler.js.map +1 -1
- package/lib/handlers/utils.d.ts +12 -0
- package/lib/handlers/utils.js +19 -0
- package/lib/handlers/utils.js.map +1 -0
- package/lib/index.d.ts +21 -15
- package/lib/index.js +17 -12
- package/lib/index.js.map +1 -1
- package/lib/lens/Lens.d.ts +12 -2
- package/lib/lens/Lens.js +5 -0
- package/lib/lens/Lens.js.map +1 -1
- package/lib/lens/LensLaunchData.d.ts +6 -3
- package/lib/lens/LensLaunchData.js +2 -0
- package/lib/lens/LensLaunchData.js.map +1 -1
- package/lib/lens/LensPersistenceStore.d.ts +1 -1
- package/lib/lens/LensPersistenceStore.js +1 -1
- package/lib/lens/LensPersistenceStore.js.map +1 -1
- package/lib/lens/LensRepository.d.ts +5 -1
- package/lib/lens/LensRepository.js +9 -5
- package/lib/lens/LensRepository.js.map +1 -1
- package/lib/lens/LensSource.d.ts +2 -2
- package/lib/lens/LensSource.js +4 -4
- package/lib/lens/LensSource.js.map +1 -1
- package/lib/lens/assets/LensAssetRepository.d.ts +35 -4
- package/lib/lens/assets/LensAssetRepository.js +9 -9
- package/lib/lens/assets/LensAssetRepository.js.map +1 -1
- package/lib/lens/assets/LensAssetsProvider.d.ts +1 -1
- package/lib/lens/assets/LensAssetsProvider.js +9 -4
- package/lib/lens/assets/LensAssetsProvider.js.map +1 -1
- package/lib/lens/assets/deviceDependentAssetLoader.js +3 -2
- package/lib/lens/assets/deviceDependentAssetLoader.js.map +1 -1
- package/lib/lens/assets/remoteMediaAssetLoaderFactory.js +4 -3
- package/lib/lens/assets/remoteMediaAssetLoaderFactory.js.map +1 -1
- package/lib/lens/assets/staticAssetLoader.js +5 -4
- package/lib/lens/assets/staticAssetLoader.js.map +1 -1
- package/lib/lens/cameraKitLensSource.d.ts +3 -2
- package/lib/lens/cameraKitLensSource.js +87 -42
- package/lib/lens/cameraKitLensSource.js.map +1 -1
- package/lib/lens/fetchWatermarkLens.d.ts +11 -0
- package/lib/lens/fetchWatermarkLens.js +27 -0
- package/lib/lens/fetchWatermarkLens.js.map +1 -0
- package/lib/lens-client-interface/imagePicker.d.ts +2 -1
- package/lib/lens-client-interface/imagePicker.js.map +1 -1
- package/lib/lens-client-interface/lensClientInterface.d.ts +1 -1
- package/lib/lens-client-interface/lensClientInterface.js +1 -1
- package/lib/lens-client-interface/lensClientInterface.js.map +1 -1
- package/lib/lens-core-module/lensCore.d.ts +2 -1
- package/lib/lens-core-module/lensCore.js.map +1 -1
- package/lib/lens-core-module/loader/bootstrapURLs.d.ts +12 -0
- package/lib/lens-core-module/loader/bootstrapURLs.js +48 -0
- package/lib/lens-core-module/loader/bootstrapURLs.js.map +1 -0
- package/lib/lens-core-module/loader/lensCoreFactory.d.ts +0 -12
- package/lib/lens-core-module/loader/lensCoreFactory.js +4 -49
- package/lib/lens-core-module/loader/lensCoreFactory.js.map +1 -1
- package/lib/lensCoreWasmVersions.d.ts +6 -0
- package/lib/lensCoreWasmVersions.js +6 -0
- package/lib/lensCoreWasmVersions.js.map +1 -0
- package/lib/media-sources/CameraKitSource.d.ts +39 -17
- package/lib/media-sources/CameraKitSource.js +8 -2
- package/lib/media-sources/CameraKitSource.js.map +1 -1
- package/lib/media-sources/FunctionSource.d.ts +15 -4
- package/lib/media-sources/FunctionSource.js +1 -2
- package/lib/media-sources/FunctionSource.js.map +1 -1
- package/lib/media-sources/ImageSource.d.ts +3 -5
- package/lib/media-sources/ImageSource.js +1 -3
- package/lib/media-sources/ImageSource.js.map +1 -1
- package/lib/media-sources/MediaStreamSource.d.ts +17 -33
- package/lib/media-sources/MediaStreamSource.js +6 -41
- package/lib/media-sources/MediaStreamSource.js.map +1 -1
- package/lib/media-sources/VideoSource.d.ts +14 -10
- package/lib/media-sources/VideoSource.js +5 -11
- package/lib/media-sources/VideoSource.js.map +1 -1
- package/lib/metrics/businessEventsReporter.d.ts +3 -4
- package/lib/metrics/businessEventsReporter.js +11 -55
- package/lib/metrics/businessEventsReporter.js.map +1 -1
- package/lib/metrics/operational/Count.d.ts +2 -0
- package/lib/metrics/operational/Count.js +6 -1
- package/lib/metrics/operational/Count.js.map +1 -1
- package/lib/metrics/operational/Histogram.d.ts +1 -1
- package/lib/metrics/operational/Histogram.js +7 -3
- package/lib/metrics/operational/Histogram.js.map +1 -1
- package/lib/metrics/operational/Metric.js +2 -0
- package/lib/metrics/operational/Metric.js.map +1 -1
- package/lib/metrics/operational/Timer.d.ts +9 -6
- package/lib/metrics/operational/Timer.js +12 -26
- package/lib/metrics/operational/Timer.js.map +1 -1
- package/lib/metrics/reporters/reportBenchmarks.d.ts +3 -3
- package/lib/metrics/reporters/reportBenchmarks.js +6 -5
- package/lib/metrics/reporters/reportBenchmarks.js.map +1 -1
- package/lib/metrics/reporters/reportGlobalException.d.ts +4 -4
- package/lib/metrics/reporters/reportGlobalException.js +13 -11
- package/lib/metrics/reporters/reportGlobalException.js.map +1 -1
- package/lib/metrics/reporters/reportHttpMetrics.d.ts +3 -3
- package/lib/metrics/reporters/reportHttpMetrics.js +19 -16
- package/lib/metrics/reporters/reportHttpMetrics.js.map +1 -1
- package/lib/metrics/reporters/reportLegalState.d.ts +3 -3
- package/lib/metrics/reporters/reportLegalState.js +7 -9
- package/lib/metrics/reporters/reportLegalState.js.map +1 -1
- package/lib/metrics/reporters/reportLensAndAssetDownload.d.ts +3 -3
- package/lib/metrics/reporters/reportLensAndAssetDownload.js +12 -12
- package/lib/metrics/reporters/reportLensAndAssetDownload.js.map +1 -1
- package/lib/metrics/reporters/reportLensView.d.ts +3 -3
- package/lib/metrics/reporters/reportLensView.js +6 -6
- package/lib/metrics/reporters/reportLensView.js.map +1 -1
- package/lib/metrics/reporters/reportLensWait.d.ts +2 -3
- package/lib/metrics/reporters/reportLensWait.js +1 -3
- package/lib/metrics/reporters/reportLensWait.js.map +1 -1
- package/lib/metrics/reporters/reportPlatformCapabilities.d.ts +3 -3
- package/lib/metrics/reporters/reportPlatformCapabilities.js +6 -5
- package/lib/metrics/reporters/reportPlatformCapabilities.js.map +1 -1
- package/lib/metrics/reporters/reportUserSession.js +3 -3
- package/lib/metrics/reporters/reportUserSession.js.map +1 -1
- package/lib/metrics/reporters/reporters.d.ts +2 -2
- package/lib/namedErrors.d.ts +1 -1
- package/lib/namedErrors.js +1 -1
- package/lib/namedErrors.js.map +1 -1
- package/lib/observable-operators/unsubscribed.d.ts +1 -1
- package/lib/observable-operators/unsubscribed.js +1 -1
- package/lib/observable-operators/unsubscribed.js.map +1 -1
- package/lib/platform/platformCapabilities.d.ts +1 -1
- package/lib/platform/platformCapabilities.js +9 -3
- package/lib/platform/platformCapabilities.js.map +1 -1
- package/lib/platform/platformInfo.d.ts +1 -0
- package/lib/platform/platformInfo.js +3 -3
- package/lib/platform/platformInfo.js.map +1 -1
- package/lib/remote-configuration/cofHandler.d.ts +3 -3
- package/lib/remote-configuration/cofHandler.js +6 -4
- package/lib/remote-configuration/cofHandler.js.map +1 -1
- package/lib/remote-configuration/preloadConfiguration.d.ts +1 -1
- package/lib/remote-configuration/preloadConfiguration.js +9 -4
- package/lib/remote-configuration/preloadConfiguration.js.map +1 -1
- package/lib/remote-configuration/remoteConfiguration.d.ts +7 -6
- package/lib/remote-configuration/remoteConfiguration.js +18 -15
- package/lib/remote-configuration/remoteConfiguration.js.map +1 -1
- package/lib/session/CameraKitSession.d.ts +8 -8
- package/lib/session/CameraKitSession.js +11 -9
- package/lib/session/CameraKitSession.js.map +1 -1
- package/lib/session/LensKeyboard.d.ts +1 -7
- package/lib/session/LensKeyboard.js.map +1 -1
- package/lib/session/LensPerformanceMeasurement.d.ts +1 -1
- package/lib/session/LensPerformanceMeasurement.js +3 -3
- package/lib/session/LensPerformanceMeasurement.js.map +1 -1
- package/lib/session/LensPerformanceMetrics.d.ts +1 -1
- package/lib/session/LensPerformanceMetrics.js.map +1 -1
- package/lib/session/lensState.d.ts +5 -4
- package/lib/session/lensState.js +80 -57
- package/lib/session/lensState.js.map +1 -1
- package/lib/transforms/Transform2D.d.ts +8 -3
- package/lib/transforms/Transform2D.js +1 -1
- package/lib/transforms/Transform2D.js.map +1 -1
- package/lib/utils.d.ts +3 -0
- package/lib/utils.js +4 -0
- package/lib/utils.js.map +1 -0
- package/package.json +27 -6
- package/docs/html/functions/createUserMediaSource.html +0 -138
- package/docs/html/functions/getRequiredBootstrapURLs.html +0 -130
- package/docs/html/types/CameraKitDeviceInfo.html +0 -125
- package/docs/html/types/CameraKitDeviceOptions.html +0 -120
- package/docs/html/types/CameraKitSourceInfo.html +0 -112
- package/docs/html/types/CameraKitSourceOptions.html +0 -118
- package/lib/common/index.d.ts +0 -2
- package/lib/common/index.js +0 -3
- package/lib/common/index.js.map +0 -1
- package/lib/environment.json +0 -1
- package/lib/handlers/index.d.ts +0 -2
- package/lib/handlers/index.js +0 -3
- package/lib/handlers/index.js.map +0 -1
- package/lib/lens-core-module/index.d.ts +0 -3
- package/lib/lens-core-module/index.js +0 -4
- package/lib/lens-core-module/index.js.map +0 -1
- package/lib/lens-core-module/loader/index.d.ts +0 -1
- package/lib/lens-core-module/loader/index.js +0 -2
- package/lib/lens-core-module/loader/index.js.map +0 -1
- package/lib/lensCoreWasmVersions.json +0 -5
- package/lib/metrics/metricsHandler.d.ts +0 -10
- package/lib/metrics/metricsHandler.js +0 -13
- package/lib/metrics/metricsHandler.js.map +0 -1
- package/lib/metrics/operational/operationalMetricsReporter.d.ts +0 -64
- package/lib/metrics/operational/operationalMetricsReporter.js +0 -144
- package/lib/metrics/operational/operationalMetricsReporter.js.map +0 -1
- package/lib/session/index.d.ts +0 -1
- package/lib/session/index.js +0 -2
- package/lib/session/index.js.map +0 -1
- package/lib/transforms/index.d.ts +0 -1
- package/lib/transforms/index.js +0 -2
- 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,
|
|
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
|
-
* [
|
|
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
|
-
* [
|
|
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,
|
|
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
|
|
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 {
|
|
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
|
|
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
|
|
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 {
|
|
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 @@
|
|
|
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 {
|
|
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,
|
|
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,
|
|
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 =
|
|
113
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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:
|
|
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", "
|
|
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 {
|
|
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
|
-
|
|
26
|
-
], (lensCore, lensState, userHandlers, lensKeyboard, remoteApiServices, lensRepository, sessionState,
|
|
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,
|
|
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":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;
|
|
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\";\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"]}
|