<commit_before>import { undefined } from 'spica/global';
import { ObjectKeys, ObjectValues } from 'spica/alias';
import { Elem, El, ElChildren } from './proxy';
import { Factory as BaseFactory, TagNameMap, Attrs, shadow, html, svg, define } from '../util/dom';
import { ExtractProp } from 'spica/type';

export type API<M extends TagNameMap, F extends BaseFactory<M> = BaseFactory<M>> =
  BuilderFunction<Extract<keyof ExtractProp<M, Element>, string>, Element, F> &
  { readonly [P in Extract<keyof ExtractProp<M, Element>, string>]: BuilderMethod<P, Extract<M[P], Element>, F>; };
export function API
  <M extends TagNameMap, F extends BaseFactory<M>>
  (baseFactory: F, formatter: <E extends Element>(el: E) => E | ShadowRoot = el => el)
  : API<M, F> {
  return new Proxy<API<M, F>>((() => undefined) as any, handle(baseFactory, formatter));
}

export const Shadow: API<ShadowHostElementTagNameMap> = API(html, shadow);
export const HTML: API<HTMLElementTagNameMap> = API(html);
export const SVG: API<SVGElementTagNameMap> = API(svg);

type Relax<C extends ElChildren> = C extends ElChildren.Text ? ElChildren.Text : C;

interface BuilderFunction<T extends string, E extends Element, F extends BaseFactory<TagNameMap>> {
                        (tag: T,                            factory?: Factory<F, T, ElChildren.Void, E>): El<T, E, ElChildren.Void>;
  <C extends ElChildren>(tag: T,               children: C, factory?: Factory<F, T, C, E>              ): El<T, E, Relax<C>>;
                        (tag: T, attrs: Attrs,              factory?: Factory<F, T, ElChildren.Void, E>): El<T, E, ElChildren.Void>;
  <C extends ElChildren>(tag: T, attrs: Attrs, children: C, factory?: Factory<F, T, C, E>              ): El<T, E, Relax<C>>;
}

interface BuilderMethod<T extends string, E extends Element, F extends BaseFactory<TagNameMap>> {
                        (                           factory?: Factory<F, T, ElChildren.Void, E>): El<T, E, ElChildren.Void>;
  <C extends ElChildren>(              children: C, factory?: Factory<F, T, C, E>              ): El<T, E, Relax<C>>;
                        (attrs: Attrs,              factory?: Factory<F, T, ElChildren.Void, E>): El<T, E, ElChildren.Void>;
  <C extends ElChildren>(attrs: Attrs, children: C, factory?: Factory<F, T, C, E>              ): El<T, E, Relax<C>>;
}<commit_msg>Refactoring<commit_after>import { undefined } from 'spica/global';
import { ObjectKeys, ObjectValues } from 'spica/alias';
import { Elem, El, ElChildren } from './proxy';
import { Factory as BaseFactory, TagNameMap, Attrs, shadow, html, svg, define } from '../util/dom';
import { ExtractProp } from 'spica/type';

export type API<M extends TagNameMap, F extends BaseFactory<M> = BaseFactory<M>> =
  BuilderFunction<Extract<keyof ExtractProp<M, Element>, string>, Element, F> &
  { readonly [P in Extract<keyof ExtractProp<M, Element>, string>]: BuilderMethod<P, Extract<M[P], Element>, F>; };
export function API
  <M extends TagNameMap, F extends BaseFactory<M>>
  (baseFactory: F, formatter: <E extends Element>(el: E) => E | ShadowRoot = el => el)
  : API<M, F> {
  return new Proxy<API<M, F>>((() => undefined) as any, handle(baseFactory, formatter));
}

export const Shadow: API<ShadowHostElementTagNameMap> = API(html, shadow);
export const HTML: API<HTMLElementTagNameMap> = API(html);
export const SVG: API<SVGElementTagNameMap> = API(svg);

type Adjust<C extends ElChildren> =
  C extends ElChildren.Text ? ElChildren.Text :
  C extends ElChildren.Array ? Readonly<C> :
  C;

interface BuilderFunction<T extends string, E extends Element, F extends BaseFactory<TagNameMap>> {
                        (tag: T,                            factory?: Factory<F, T, ElChildren.Void, E>): El<T, E, ElChildren.Void>;
  <C extends ElChildren>(tag: T,               children: C, factory?: Factory<F, T, C, E>              ): El<T, E, Adjust<C>>;
                        (tag: T, attrs: Attrs,              factory?: Factory<F, T, ElChildren.Void, E>): El<T, E, ElChildren.Void>;
  <C extends ElChildren>(tag: T, attrs: Attrs, children: C, factory?: Factory<F, T, C, E>              ): El<T, E, Adjust<C>>;
}

interface BuilderMethod<T extends string, E extends Element, F extends BaseFactory<TagNameMap>> {
                        (                           factory?: Factory<F, T, ElChildren.Void, E>): El<T, E, ElChildren.Void>;
  <C extends ElChildren>(              children: C, factory?: Factory<F, T, C, E>              ): El<T, E, Adjust<C>>;
                        (attrs: Attrs,              factory?: Factory<F, T, ElChildren.Void, E>): El<T, E, ElChildren.Void>;
  <C extends ElChildren>(attrs: Attrs, children: C, factory?: Factory<F, T, C, E>              ): El<T, E, Adjust<C>>;
}
{'fraction_non_alphanumeric': 0.14753060363022372, 'fraction_numerical': 0.0, 'mean_word_length': 3.1424825174825175, 'pattern_counts': {'":': 0, '<': 100, '<?xml version=': 0, '>': 106, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3469114', 'n_tokens_mistral': 1500, 'n_tokens_neox': 1499, 'n_words': 464}