import { EntityID, EntityIndex, Component, Schema, Metadata, World } from './types.js';
import 'rxjs';
import './constants.js';
import 'type-fest';

/**
 * Create a new World.
 *
 * @remarks
 * A World is the central object of an ECS application, where all {@link defineComponent Components},
 * {@link registerEntity Entities} and {@link defineSystem Systems} are registerd.
 *
 * @returns A new World
 */
declare function createWorld(): {
    entities: EntityID[];
    entityToIndex: Map<EntityID, EntityIndex>;
    registerEntity: ({ id, idSuffix }?: {
        id?: EntityID | undefined;
        idSuffix?: string | undefined;
    }) => EntityIndex;
    components: Component<Schema, Metadata, undefined>[];
    registerComponent: (component: Component) => void;
    dispose: (namespace?: string) => void;
    registerDisposer: (disposer: () => void, namespace?: string) => void;
    getEntityIndexStrict: (entity: EntityID) => EntityIndex;
    hasEntity: (entity: EntityID) => boolean;
};
/**
 * Create a new namespace from an existing World.
 * The `dispose` method of a namespaced World only calls disposers registered on this namespace.
 *
 * @param world World to create a new namespace for.
 * @param namespace String descriptor of the new namespace.
 * @returns World with a new namespace.
 */
declare function namespaceWorld(world: ReturnType<typeof createWorld>, namespace: string): {
    registerDisposer: (disposer: () => void) => void;
    dispose: () => void;
    entities: EntityID[];
    entityToIndex: Map<EntityID, EntityIndex>;
    registerEntity: ({ id, idSuffix }?: {
        id?: EntityID | undefined;
        idSuffix?: string | undefined;
    }) => EntityIndex;
    components: Component<Schema, Metadata, undefined>[];
    registerComponent: (component: Component<Schema, Metadata, undefined>) => void;
    getEntityIndexStrict: (entity: EntityID) => EntityIndex;
    hasEntity: (entity: EntityID) => boolean;
};
/**
 * Get all components that have a value for the given entity.
 *
 * @dev Design decision: don't store a list of components for each entity but compute it dynamically when needed
 * because there are less components than entities and maintaining a list of components per entity is a large overhead.
 *
 * @param world World object the given entity is registered on.
 * @param entity {@link EntityIndex} of the entity to get the list of components for.
 * @returns Array of components that have a value for the given entity.
 */
declare function getEntityComponents(world: World, entity: EntityIndex): Component[];

export { createWorld, getEntityComponents, namespaceWorld };
