import { RootAddedEvent, RootRemovedEvent, TitleChangedEvent } from "../document";
import { ViewManager } from "../core/view_manager";
import { DOMView } from "../core/dom_view";
import { isString } from "../core/util/types";
import { assert } from "../core/util/assert";
// A map from the root model IDs to their views.
export const index = new Proxy(new ViewManager(), {
    get(manager, property) {
        if (isString(property)) {
            const view = manager.get_by_id(property);
            if (view != null) {
                return view;
            }
        }
        return Reflect.get(manager, property);
    },
    has(manager, property) {
        if (isString(property)) {
            const view = manager.get_by_id(property);
            if (view != null) {
                return true;
            }
        }
        return Reflect.has(manager, property);
    },
    ownKeys(manager) {
        return manager.roots.map((root) => root.model.id);
    },
    getOwnPropertyDescriptor(manager, property) {
        if (isString(property)) {
            const view = manager.get_by_id(property);
            if (view != null) {
                return { configurable: true, enumerable: true, writable: false, value: view };
            }
        }
        return Reflect.getOwnPropertyDescriptor(manager, property);
    },
});
export async function add_document_standalone(document, element, roots = [], use_for_title = false) {
    // this is a LOCAL index of views used only by this particular rendering
    // call, so we can remove the views we create.
    assert(document.views_manager == null);
    const views = new ViewManager([], index);
    document.views_manager = views;
    async function render_view(model) {
        const view = await views.build_view(model);
        if (view instanceof DOMView) {
            const i = document.roots().indexOf(model);
            const root_el = roots[i] ?? element;
            view.build(root_el);
        }
        index.add(view);
    }
    async function render_model(model) {
        if (model.default_view != null) {
            await render_view(model);
        }
        else {
            document.notify_idle(model);
        }
    }
    function unrender_model(model) {
        const view = views.get(model);
        view?.remove();
    }
    for (const model of document.roots()) {
        await render_model(model);
    }
    if (use_for_title) {
        window.document.title = document.title();
    }
    document.on_change((event) => {
        if (event instanceof RootAddedEvent) {
            void render_model(event.model);
        }
        else if (event instanceof RootRemovedEvent) {
            unrender_model(event.model);
        }
        else if (use_for_title && event instanceof TitleChangedEvent) {
            window.document.title = event.title;
        }
    });
    return views;
}
//# sourceMappingURL=standalone.js.map