export interface JSONSerializableMountInit{ readonly on?: CSSMatch, readonly outside?: CSSMatch, readonly observedAttrsWhenMounted?: (string | ObservedSourceOfTruthAttribute)[], readonly whereAttr?: WhereAttr, readonly whereElementIntersectsWith?: IntersectionObserverInit, readonly whereMediaMatches?: MediaQuery, readonly import?: ImportString | [ImportString, ImportAssertions] | PipelineProcessor, } export interface ObservedSourceOfTruthAttribute { name: string, mapsTo?: keyof TProps & string, valIfNull?: any, valIfFalsy?: any, instanceOf?: any, customParser?: (newValue: string | null, oldValue: string | null, instance: Element) => any } export type Assigner = (target: any, source: any) => Promise | void; export interface MountInit extends JSONSerializableMountInit{ readonly withTargetShadowRoot?: ShadowRoot, readonly whereInstanceOf?: Array<{new(): Element}>, readonly whereSatisfies?: PipelineProcessor, readonly do?: MountObserverCallbacks, readonly assigner?: Assigner, readonly idleTimeout?: number // /** // * Purpose -- there are scenarios where we may only want to affect changes that occur after the initial // * server rendering, so we only want to mount elements that appear // */ // readonly ignoreInitialMatches?: boolean, } export interface MountObserverOptions{ leaveBreadcrumb?: boolean, } export interface MountObserverCallbacks{ readonly mount?: PipelineProcessor, readonly dismount?: PipelineProcessor, readonly disconnect?: PipelineProcessor, readonly reconfirm?: PipelineProcessor, readonly exit?: PipelineProcessor, } export interface RootCnfg{ start: string, context: 'BuiltIn' | 'CustomElement' | 'Both' } //export type RootAttrOptions = Array; export type delimiter = string; export interface WhereAttr{ hasBase?: string | [delimiter, string], hasBranchIn?: Array | [delimiter, Array], hasRootIn?: Array, /** * Used by consumers to track the universal meaning of this combination * regardless of how the actual name values may be changed. */ metadata?: any, } type CSSMatch = string; type ImportString = string; type MediaQuery = string; export interface AttribMatch{ names: string[], //for boolean, support true/false/mixed // type?: 'number' | 'string' | 'date' | 'json-object' | 'boolean', // valConverter?: (s: string) => any, // validator?: (v: any) => boolean; } export interface WeakDual{ weakSet: WeakSet, setWeak: Set> } export interface IMountObserver extends EventTarget { // readonly mountInit: MountInit, // readonly mountedRefs: WeakRef[], // readonly dismountedRefs: WeakRef[], observe(within: Node): void; disconnect(within: Node): void; module?: any; mountedElements: WeakDual; readAttrs(match: Element, branchIndexes?: Set) : AttrChangeInfo[]; observedAttrs(): Promise | undefined>; } export interface MountContext{ stage?: PipelineStage, initializing?: boolean, } type PipelineStage = 'Inspecting' | 'PreImport' | 'PostImport' | 'Import' export type PipelineProcessor = (matchingElement: Element, observer: IMountObserver, ctx: MountContext) => Promise | ReturnType; //#region mutation event export type mutationEventName = 'mutation-event'; export interface MutationEvent{ mutationRecords: Array } export type mutationEventHandler = (e: MutationEvent) => void; export interface AddMutationEventListener { addEventListener(eventName: mutationEventName, handler: mutationEventHandler, options?: AddEventListenerOptions): void; } //#endregion interface AttrParts{ name: string, root?: string, base?: string, branch?: string, branchIdx: number, leaf?: string, //TODO leafIdx?: number, //TODO rootCnfg?: RootCnfg, metadata?: any, } interface AttrChangeInfo{ oldValue: string | null, newValue: string | null, isSOfTAttr: boolean, idx?: number, name: string, parts?: AttrParts, mapsTo?: string, } //#region mount event export type mountEventName = 'mount'; export interface IMountEvent extends Event{ mountedElement: Element, } export type mountEventHandler = (e: IMountEvent) => void; export interface AddMountEventListener { addEventListener(eventName: mountEventName, handler: mountEventHandler, options?: AddEventListenerOptions): void; } //#endregion //#region dismount event export type dismountEventName = 'dismount'; export interface IDismountEvent { dismountedElement: Element } export type dismountEventHandler = (e: IDismountEvent) => void; export interface AddDismountEventListener { addEventListener(eventName: dismountEventName, handler: dismountEventHandler, options?: AddEventListenerOptions): void; } //#endregion //#region disconnected event export type disconnectedEventName = 'disconnect'; export interface IDisconnectEvent { disconnectedElement: Element } export type disconnectedEventHandler = (e: IDisconnectEvent) => void; export interface AddDisconnectEventListener { addEventListener(eventName: disconnectedEventName, handler: disconnectedEventHandler, options?: AddEventListenerOptions): void; } //endregion //#region attribute change event export type attrChangeEventName = 'attrChange'; export interface IAttrChangeEvent extends IMountEvent { attrChangeInfos: Array, } export type attrChangeEventHandler = (e: IAttrChangeEvent) => void; export interface AddAttrChangeEventListener{ addEventListener(eventName: attrChangeEventName, handler: attrChangeEventHandler, options?: AddEventListenerOptions): void; } //#endregion //#region load event export type loadEventName = 'load'; export interface ILoadEvent { clone: DocumentFragment } export type loadEventHandler = (e: ILoadEvent) => void; export interface AddLoadEventListener{ addEventListener(eventName: loadEventName, handler: loadEventHandler, options?: AddEventListenerOptions): void } //#endregion //#region MountObserver Script Element export interface MOSEAddedProps{ init: JSONSerializableMountInit; observer: IMountObserver; do: MountObserverCallbacks; synConfig: TSynConfig; } export interface MOSE extends HTMLScriptElement, MOSEAddedProps{ } export interface BindishOptions{ assigner?: Assigner, //waitFor?: string, /** * If derived from a template, set to true * to indicate that the initial */ csr?: boolean, ctr?: IshCtr, initPropVals?: any, } //TODO: move to mount observer export interface HasIsh { ish: any; } export interface Ishcycle{ ''?(self: Ishcycle, el: Element & HasIsh, options: BindishOptions): Promise; //''?(self: IshFace, el: Element): Promise; ''?(self: Ishcycle, el: Element & HasIsh, options: BindishOptions): Promise; 'arr=>'?(self: Ishcycle, arr: any[] | undefined, el: Element & HasIsh, options: BindishOptions): Promise; //''?(self: IshFace, el: Element): Promise; } export type IshCtr = ({new() : Ishcycle}) | (() => Promise<{new() : Ishcycle}>); //#endregion export type RefType = '#' | '!'; export interface TemplateWithRemoteContent extends HTMLTemplateElement { remoteContent?: DocumentFragment, }