import { Container, PartialContainer } from "@snap/ts-inject";
import type { CameraKitBootstrapConfiguration } from "./configuration";
import type { PublicServices } from "./RootServices";
import type { CameraKit } from "./CameraKit";
/**
 * For more advanced use-cases, this DI Container holds services for which a custom implementation may be provided by
 * the application.
 *
 * @category Bootstrapping and Configuration
 */
export type PublicContainer = Container<PublicServices>;
/**
 * Bootstrap CameraKit. This will download the WebAssembly code which powers CameraKit's rendering engine, and return
 * an instance of {@link CameraKit}.
 *
 * CameraKit must be provided with some configuration (the application's API token), and there are some additional
 * configurations which are optional.
 *
 * Descriptions of the available configurations can be found in the documentation for
 * {@link CameraKitBootstrapConfiguration}
 *
 * ---
 *
 * There is also a second, more advanced way to modify CameraKit to provide greater flexibility to support less common
 * use cases.
 *
 * This requires some knowledge of CameraKit's dependency injection system, and allows applications to provide their
 * own custom implementations of certain CameraKit components. This functionality will only be needed by applications
 * with very specific, more advanced requirements.
 *
 * @example
 * ```ts
 * // The most common way to bootstrap:
 * const cameraKit = await bootstrapCameraKit({ apiToken: myApiToken })
 *
 * // For special advanced use-cases, it is possible to provide custom implementations for certain CameraKit components.
 * const cameraKit = await bootstrapCameraKit(config, (container) => {
 *   return container.provides(myCustomRemoteMediaAssetLoaderFactory)
 * })
 * ```
 *
 * @param configuration Configure CameraKit with e.g. credentials, global resource endpoints, etc.
 * @param provide Optional function that can make modifications to CameraKit's root DI container.
 * @returns A {@link CameraKit} instance, which is the entry point to CameraKit's API.
 *
 * @throws
 *  - {@link ConfigurationError} when provided configuration object is invalid
 *  - {@link PlatformNotSupportedError} when current platform is not supported by CameraKit
 *  - {@link BootstrapError} when a failure occurs while initializing CameraKit and downloading the render engine
 * WebAssembly binary.
 *
 * @category Bootstrapping and Configuration
 */
export declare function bootstrapCameraKit(configuration: CameraKitBootstrapConfiguration, provide?: (c: PublicContainer) => PublicContainer): Promise<CameraKit>;
/**
 * Extensions offer a way to provide custom implementations of certain parts of the CameraKit SDK.
 *
 * This enables more advanced use-cases, in which the default behavior of the SDK is substantially altered. For example,
 * replacing the default implementation that loads remote lens assets with a custom implementation that returns
 * different assets based on some business logic within the application.
 *
 * An extension is implemented as a {@link PartialContainer} – a collection of factory functions, each with its own
 * dependencies, which each provide some "Service". A Service can be of any type, and the CameraKit SDK defines its
 * own Services, some of which can be overridden by providing a custom implementation of the type via an extension.
 *
 * Here's an example of how extensions might be used:
 * ```ts
 * import { bootstrapCameraKit, createExtension, remoteMediaAssetLoaderFactory } from '@snap/camera-kit'
 *
 * const myCustomRemoteAssetLoader = Injectable(
 *   remoteMediaAssetLoaderFactory.token,
 *   [remoteMediaAssetLoaderFactory.token] as const,
 *   (defaultLoader: AssetLoader): AssetLoader => {
 *     return async (asset, lens) => {
 *       if (lens?.id === MY_SPECIAL_LENS) {
 *         return (await fetch('my/asset.glb')).arrayBuffer()
 *       }
 *       return defaultLoader(asset, lens)
 *     }
 *   },
 * )
 *
 * const myExtension = createExtension().provides(myCustomRemoteAssetLoader);
 * const cameraKit = bootstrapCameraKit(config, container => container.provides(myExtension));
 * ```
 *
 * This also enables greater modularity – the person/team creating the extension can do so in their own package, which
 * could be shared by many applications that all require the same functionality.
 *
 * @returns A {@link PartialContainer} which can be used to create a collection of Services, and can later be provided
 * to CameraKit's DI container during {@link bootstrapCameraKit}.
 *
 * @category Bootstrapping and Configuration
 */
export declare function createExtension(): PartialContainer;
//# sourceMappingURL=bootstrapCameraKit.d.ts.map