import { TinyEmitter } from 'tiny-emitter';
import { Chunk } from '@rechunk/api-client';

/**
 * Represents the valid entries for chunks in the `importChunk` function.
 *
 * This type is updated dynamically during the `typegen` command execution.
 * Initially, it is set to `null`, but it will be replaced with a union type of valid chunk names
 * (e.g., `'card' | 'home' | 'stack'`).
 *
 * @example
 * ```typescript
 * type ReChunkEntries = 'card' | 'home' | 'stack';
 * ```
 */
type ReChunkEntries = null;
/**
 * Validates if a given chunk ID is part of the recognized `ReChunkEntries`.
 *
 * If the chunk ID is not valid, it produces a detailed error message prompting
 * the user to regenerate types using the `typegen` command.
 *
 * @template T - The chunk ID to validate.
 * @example
 * ```typescript
 * type ValidChunk = ValidateReChunkEntry<'card'>; // Resolves to 'card'
 * type InvalidChunk = ValidateReChunkEntry<'invalid'>;
 * // Resolves to:
 * // "Invalid ReChunk entry: 'invalid' is not a recognized chunk ID. Please regenerate types using the `typegen` command."
 * ```
 */
type ValidateReChunkEntry<T extends string> = T extends ReChunkEntries ? T : `Error: '${T}' is not a valid ReChunk entry. To access chunks dynamically, use the 'use rechunk' directive in your component or function module.`;
/**
 * Makes all properties of a type and its nested types required recursively.
 *
 * @template T - The type to make all properties required for.
 */
type DeepRequired<T> = Required<{
    [K in keyof T]: T[K] extends Required<T[K]> ? T[K] : DeepRequired<T[K]>;
}>;
/**
 * Represents a function that resolves a chunk ID to a chunk string asynchronously.
 * @param {string} chunkId - The ID of the chunk to resolve.
 * @returns {Promise<string>} A promise resolving to the chunk string.
 */
type ResolverFunction = (chunkId: string) => Promise<DeepRequired<Chunk>>;
type Configuration = {
    resolver?: ResolverFunction;
    publicKey?: string;
    verify?: boolean;
};

/**
 * This polyfill file adds support for the global `btoa` and `atob` methods
 * if they are not already defined in the environment.
 */

/**
 * Asynchronously imports a chunk using the shared ChunkManager instance.
 * @param {string} chunkId - The ID of the chunk to import.
 * @returns {Promise<*>} A promise resolving to the imported JavaScript component.
 */
declare function importChunk<T extends string>(chunkId: ValidateReChunkEntry<T>): Promise<any>;
/**
 * Adds configuration settings to the ChunkManager.
 * This function is used to configure the ChunkManager with specified settings such as public key, resolver function, verification flag, and global object.
 * @param {Configuration} config - The configuration object for ChunkManager.
 */
declare function addConfiguration(config: Configuration): void;
/**
 * Registers an event listener with the specified event name and callback function.
 * Optionally, you can provide a context object (`ctx`) to bind `this` when the callback is invoked.
 * @param {string} event - The name of the event to listen for.
 * @param {Function} callback - The function to be invoked when the event is emitted.
 * @param {any} [ctx] - (Optional) The context to bind to the callback function.
 * @returns {TinyEmitter} - The `TinyEmitter` instance for chaining purposes.
 */
declare function on(event: string, callback: Function, ctx?: any): TinyEmitter;
/**
 * Exports the addResolver function under the default namespace,
 * making it accessible under the ReChunk namespace.
 */
declare const _default: {
    addConfiguration: typeof addConfiguration;
};

export { type Configuration, type DeepRequired, type ReChunkEntries, type ResolverFunction, type ValidateReChunkEntry, _default as default, importChunk, on };
