import { type GeneralBehavior, type GeneralBehaviorBuilder } from './behavior' import { type Component, type ComponentDefinition, type GeneralComponent } from './component' import { type NormalizedPropertyType } from './data_proxy' import { type ComponentOptions } from './global_options' import { type TraitBehavior } from './trait_behaviors' export type Empty = Record export type IsEmpty = Equal export type NewField = Extract< keyof TObject, TField > extends never ? TValueType : never export type NewFieldList = Extract< keyof TObject, keyof TNewObject > extends never ? TNewObject : never export type Equal = (() => T extends X ? 1 : 2) extends () => T extends Y ? 1 : 2 ? true : false /** * UnionToIntersection<'foo' | 42 | true> = 'foo' & 42 & true * UnionToIntersection<(() => 'foo') | ((i: 42) => true)> = (() => 'foo') & ((i: 42) => true) */ export type UnionToIntersection = (T extends unknown ? (arg: T) => void : never) extends ( args: infer Arg, ) => void ? Arg : never /** * Merge<{ foo: string }, { bar: number }> = { foo: string, bar: number } */ export type Merge = U extends infer T ? { [K in keyof T]: T[K] } : never /** * IsAny = true * IsAny<{}> = false */ export type IsAny = ((S: S) => S extends T ? 1 : 2) extends (R: R) => R extends any ? 1 : 2 ? true : false /** * IsNever = true * IsNever = false * IsNever = false */ export type IsNever = [T] extends [never] ? true : false type SetDataStringPath = [Prefix] extends [never] ? `${K}` : K extends number ? `${Prefix}[${K}]` : `${Prefix}.${K}` type Tuple = 0 extends 1 ? never : Res['length'] extends T ? Res : Tuple type Subtract = Tuple extends [...Tuple, ...infer Rest] ? Rest['length'] : never /** * SetDataSetter<{ name: string; foo: { bar: number } }> = { * name: string, * foo: { bar: number }, * 'foo.bar': number, * } * setDataSetter<{ list: number[], foo: { bar: number }[]}> = { * list: number[], * `list[${number}]`: number, * foo: { bar: number }[], * `foo[${number}]`: { bar: number }[], * `foo[${number}].bar`: number, * } */ export type SetDataSetter< T, Prefix extends string = never, Count extends number = 4, > = Count extends 0 ? Record, T> : IsAny extends true ? Record, T> : UnionToIntersection< T extends any[] ? { [P in keyof T & number]: SetDataSetter< T[P], SetDataStringPath, Subtract > & Record, T[P]> }[keyof T & number] : T extends Record ? { [P in keyof T & (string | number)]: SetDataSetter< T[P], SetDataStringPath, Subtract > & Record, T[P]> }[keyof T & (string | number)] : never > /** * DeepReadonly<{ foo: { bar: number } }> = { * readonly foo: { * readonly bar: number * } * } */ export type DeepReadonly = Count extends 0 ? T : T extends Record ? T extends (...args: any[]) => any ? T : { readonly [P in keyof T]: DeepReadonly> } : T export type PublicFields = { [K in keyof T as K extends `_$${any}` ? never : K]: T[K] } /** * ObjectDataPathStrings<{ name: string; age: number }> = 'name' | 'age' * ObjectDataPathStrings<{ * refCount: number; * person: { name: string; age: number }; * }> = 'refCount' | 'person' | 'person.name' | 'person.age' * ObjectDataPathStrings<{ books: [{ name: string; price: number }] }> = * 'books' | `books[${number}]` | `books[${number}].name` | `books[${number}].price` */ export type ObjectDataPathStrings< T, Prefix extends string = never, Count extends number = 4, > = Count extends 0 ? SetDataStringPath : IsAny extends true ? SetDataStringPath : T extends any[] ? { [P in keyof T & number]: | SetDataStringPath | ObjectDataPathStrings, Subtract> }[keyof T & number] : T extends Record ? { [P in keyof T & (string | number)]: | SetDataStringPath | ObjectDataPathStrings, Subtract> }[keyof T & (string | number)] : Prefix export type ObserverDataPathStrings> = | '**' | S | `${S}.**` /** * GetFromDataPathString<{ name: string; age: number }, 'name'> = string * GetFromDataPathString<{ person: { name: string; age: number } }, 'person.name'> = string * GetFromDataPathString<{ books: [{ name: string; price: number }] }, 'books[0].name'> = string */ export type GetFromDataPathString = P extends keyof T ? T[P] : P extends '' ? T : P extends `[${infer K extends keyof T & number}].${infer R}` ? GetFromDataPathString : P extends `[${infer K extends keyof T & number}]${infer R}` ? GetFromDataPathString : P extends `${infer K extends keyof T & string}[${infer R}` ? GetFromDataPathString : P extends `${infer K extends keyof T & string}.${infer R}` ? GetFromDataPathString : never export type GetFromObserverPathString = P extends '**' ? GetFromDataPathString : P extends `${infer K}.**` ? GetFromDataPathString : GetFromDataPathString /** * GetFromDataPath<{ foo: { bar: number } }, ['foo', 'bar']> = number * GetFromDataPath<{ list: { bar: number }[] }, ['list', 0, 'bar']> = number * GetFromDataPath<{ list: number }, ['nonExists']> = never */ export type GetFromDataPath = K extends [ infer F, ...infer R extends (string | number)[], ] ? F extends keyof T ? GetFromDataPath : never : T declare const TaggedSymbol: unique symbol type Tagged = typeof TaggedSymbol type IfNeverOrAny = [T] extends [never] ? Replacement : 1 extends T & 0 ? Replacement : T type GetTags = B extends { readonly [Tag in Tagged]: infer Tags extends symbol[] } ? Tags : [] type GetTagsWithout> = Tags extends [infer F, ...infer R] ? Equal extends true ? GetTagsWithout : [F, ...GetTagsWithout] : [] type UnTagAll = Tagged extends keyof IfNeverOrAny ? B extends infer Origin & { readonly [Tag in Tagged]: GetTags } ? Origin : B : B export type Tag = [IfNeverOrAny] extends [null | undefined] ? B : UnTagAll & { readonly [Tag in Tagged]: [...GetTags, T] } export type UnTag< B, T extends symbol, Tags = GetTagsWithout, > = Tagged extends keyof IfNeverOrAny ? Tags extends [] ? UnTagAll : UnTagAll & { readonly [Tag in Tagged]: Tags } : B export type HasTag = T extends GetTags[number] ? true : false export type DataList = Record export type PropertyList = Record> export type PropertyType = | null | StringConstructor | NumberConstructor | BooleanConstructor | ArrayConstructor | ObjectConstructor | FunctionConstructor | NormalizedPropertyType /** * PropertyTypeToValueType = any * PropertyTypeToValueType = string * PropertyTypeToValueType = number */ export type PropertyTypeToValueType = T extends null | NormalizedPropertyType.Any ? any : T extends StringConstructor | NormalizedPropertyType.String ? string : T extends NumberConstructor | NormalizedPropertyType.Number ? number : T extends BooleanConstructor | NormalizedPropertyType.Boolean ? boolean : T extends ArrayConstructor | NormalizedPropertyType.Array ? any[] : T extends ObjectConstructor | NormalizedPropertyType.Object ? Record | null : T extends FunctionConstructor | NormalizedPropertyType.Function ? (...args: any[]) => any : never type Satisfy = V extends T ? V : T /** * PropertyTypeToSimpleValueType = 'foo' * PropertyTypeToSimpleValueType = string */ type PropertyTypeToSimpleValueType< T extends PropertyType, V, > = T extends null | NormalizedPropertyType.Any ? V : T extends StringConstructor | NormalizedPropertyType.String ? Satisfy : T extends NumberConstructor | NormalizedPropertyType.Number ? Satisfy : T extends BooleanConstructor | NormalizedPropertyType.Boolean ? Satisfy : T extends ArrayConstructor | NormalizedPropertyType.Array ? Satisfy : T extends ObjectConstructor | NormalizedPropertyType.Object ? Satisfy | null, V> : T extends FunctionConstructor | NormalizedPropertyType.Function ? Satisfy<(...args: any[]) => any, V> : never /** * PropertyValueType = any * PropertyValueType = string * PropertyValueType = string | number * PropertyValueType<{ type: typeof String }> = string * PropertyValueType<{ type: typeof String, optionalTypes: [typeof Number] }> = string | number * PropertyValueType<{ type: typeof String, value: 'foo' }> = 'foo' * PropertyValueType<{ type: typeof String, value: 123 }> = never * PropertyValueType<{ type: typeof String, optionalTypes: [typeof Number], value: 123 }> = * string | 123 */ type PropertyValueType

> = P extends PropertyListItem< infer T, infer V > ? unknown extends V ? PropertyTypeToValueType : ((a: T) => void) extends (a: PropertyType) => void ? V : V extends PropertyTypeToValueType ? PropertyTypeToSimpleValueType : never : never export type PropertyOption = { type?: T optionalTypes?: T[] value?: V default?: () => V observer?: ((newValue: V, oldValue: V) => void) | string comparer?: (newValue: V, oldValue: V) => boolean reflectIdPrefix?: boolean } export type PropertyListItem = T | PropertyOption export type PropertyValues

= { [key in keyof P]: PropertyValueType } export type DataWithPropertyValues = TData & PropertyValues export type ComponentMethod = (...args: any[]) => any export type MethodList = Record export const METHOD_TAG = Symbol('method') export type TaggedMethod = Tag export type UnTaggedMethod> = UnTag export type RelationParams = { target?: string | ComponentDefinition | GeneralBehavior | TraitBehavior type: 'ancestor' | 'descendant' | 'parent' | 'child' | 'parent-common-node' | 'child-common-node' linked?: (target: GeneralComponent) => void linkChanged?: (target: GeneralComponent) => void unlinked?: (target: GeneralComponent) => void linkFailed?: (target: GeneralComponent) => void } export type RelationParamsWithKey = { [name: string]: RelationParams } export type TraitRelationParams = { target: TraitBehavior type: 'ancestor' | 'descendant' | 'parent' | 'child' | 'parent-common-node' | 'child-common-node' linked?: (target: GeneralComponent) => void linkChanged?: (target: GeneralComponent) => void unlinked?: (target: GeneralComponent) => void linkFailed?: (target: GeneralComponent) => void } export type ChainingFilterFunc< TAddedFields extends { [key: string]: any }, TRemovedFields extends string = never, > = (chain: GeneralBehaviorBuilder) => Omit & TAddedFields export type ChainingFilterType = { add: { [key: string]: any } remove: string } export type ComponentInstance< TData extends DataList, TProperty extends PropertyList, TMethod extends MethodList, TExtraThisFields extends DataList = Empty, > = Component & { data: Merge> properties: Merge> } & TMethod & TExtraThisFields export type ComponentParams< TData extends DataList, TProperty extends PropertyList, TMethod extends MethodList, > = { is?: string behaviors?: (string | GeneralBehavior)[] using?: { [name: string]: string | ComponentDefinition } generics?: { [name: string]: { default: string | ComponentDefinition } | true } placeholders?: { [name: string]: string } template?: { [key: string]: any } | null externalClasses?: string[] data?: TData | (() => TData) properties?: TProperty methods?: TMethod listeners?: { [name: string]: ComponentMethod | string } relations?: RelationParamsWithKey lifetimes?: { [name: string]: ComponentMethod } created?: () => any attached?: ComponentMethod moved?: ComponentMethod detached?: ComponentMethod ready?: ComponentMethod pageLifetimes?: { [name: string]: ComponentMethod } observers?: | { fields?: string observer: ComponentMethod | string }[] | { [fields: string]: ComponentMethod | string } options?: ComponentOptions }