router-primitives
Version:
A cross-platform application router. Declarative routing by way of layout primitives
213 lines (212 loc) • 15.7 kB
TypeScript
import { IRouterBase } from '../types/router_base';
import { IManager } from '../types/manager';
import { IRouterStateStore } from '../types/router_state';
import { IRouterCache } from '../types/router_cache';
import { ISerializedStateStore } from '../types/serialized_state';
import { DefaultTemplates } from '../types/router_templates';
import { ITracerThing } from '../tracer';
export declare type Constructable<T = {}> = new (...args: any[]) => T;
export interface IInputSearch {
[key: string]: string | string[] | number | number[] | boolean | undefined;
}
export interface IOutputSearch {
[key: string]: string | string[] | number | number[] | boolean | undefined;
}
export interface ILocationOptions {
replaceLocation?: boolean;
}
export interface IRouterActionOptions<CustomState> {
data?: CustomState;
pathData?: Record<string, unknown>;
disableCaching?: boolean;
replaceLocation?: boolean;
dryRun?: boolean;
addCacheToLocation?: boolean;
}
export interface LinkOptions<CustomState> {
data?: CustomState;
pathData?: Record<string, unknown>;
addCacheToLocation?: boolean;
}
export declare type Pathname = string[];
export interface IOutputLocation {
pathname: Pathname;
search: IOutputSearch;
}
export interface IInputLocation {
pathname: Pathname;
search: IInputSearch;
options?: ILocationOptions;
}
export interface ILocationActionContext<CustomTemplates extends IRouterTemplates, Name extends NarrowRouterTypeName<keyof AllTemplates<CustomTemplates>>> {
disableCaching?: boolean;
addingDefaults?: boolean;
callDirection?: 'up' | 'down' | 'lateral' | undefined;
activatedByChildType?: string;
tracer?: ITracerThing;
actionName: string;
actionFn?: RouterActionFn<CustomTemplates, Name>;
dryRun?: boolean;
pathData?: Record<string, unknown>;
routerIsMissingData?: string[];
}
export declare type ReducerContext<CustomTemplates extends IRouterTemplates, Name extends NarrowRouterTypeName<keyof AllTemplates<CustomTemplates>>> = Omit<ILocationActionContext<CustomTemplates, Name>, 'actionName' | 'actionFn'>;
export declare type ActionStep = <CustomTemplates extends IRouterTemplates, Name extends NarrowRouterTypeName<keyof AllTemplates<CustomTemplates>>>(_options: IRouterActionOptions<RouterCustomStateFromTemplates<AllTemplates<CustomTemplates>>>, existingLocation: IInputLocation, routerInstance: RouterInstance<CustomTemplates, Name>, ctx: ILocationActionContext<CustomTemplates, Name>) => {
location: IInputLocation;
ctx: ILocationActionContext<CustomTemplates, Name>;
};
export interface DefaultRouterActions<CustomTemplates extends IRouterTemplates<unknown>, RouterTypeName extends NarrowRouterTypeName<keyof AllTemplates<CustomTemplates>>> {
show: RouterActionFn<CustomTemplates, RouterTypeName>;
hide: RouterActionFn<CustomTemplates, RouterTypeName>;
}
export declare type IntersectUnionedActions<T, CustomTemplates extends IRouterTemplates<undefined>, RouterTypeName extends NarrowRouterTypeName<keyof AllTemplates<CustomTemplates>>> = (T extends any ? (x: T) => 0 : never) extends (x: infer R) => 0 ? R : DefaultRouterActions<CustomTemplates, RouterTypeName>;
export declare type Actions<CustomActionNames extends string | null, CustomTemplates extends IRouterTemplates<undefined>, RouterTypeName extends NarrowRouterTypeName<keyof AllTemplates<CustomTemplates>>> = IntersectUnionedActions<ActionsWithCustomUnioned<CustomActionNames, CustomTemplates, RouterTypeName>, CustomTemplates, RouterTypeName> & DefaultRouterActions<CustomTemplates, RouterTypeName>;
export declare type ActionsWithCustomUnioned<CustomActionNames extends string | null, CustomTemplates extends IRouterTemplates<undefined>, RouterTypeName extends NarrowRouterTypeName<keyof AllTemplates<CustomTemplates>>> = CustomActionNames extends null ? DefaultRouterActions<CustomTemplates, RouterTypeName> : {
[actionName in CustomActionNames]: RouterActionFn<CustomTemplates, RouterTypeName>;
} & DefaultRouterActions<CustomTemplates, RouterTypeName>;
export declare type Reducer<CustomTemplates extends IRouterTemplates<unknown>, RouterTypeName extends NarrowRouterTypeName<keyof AllTemplates<CustomTemplates>>> = {
reducer: RouterReducerFn<CustomTemplates, RouterTypeName>;
};
export declare type RouterActionFn<CustomTemplates extends IRouterTemplates, RouterTypeName extends NarrowRouterTypeName<keyof AllTemplates<CustomTemplates>>> = (options?: IRouterActionOptions<RouterCustomStateFromTemplates<AllTemplates<CustomTemplates>>>, existingLocation?: IOutputLocation, routerInstance?: RouterInstance<CustomTemplates, RouterTypeName>, ctx?: ILocationActionContext<CustomTemplates, RouterTypeName>) => IInputLocation;
export declare type RouterReducerFn<CustomTemplates extends IRouterTemplates<unknown>, RouterTypeName extends NarrowRouterTypeName<keyof AllTemplates<CustomTemplates>>> = (location: IInputLocation, router: RouterInstance<CustomTemplates, RouterTypeName>, ctx: ReducerContext<CustomTemplates, RouterTypeName>) => RouterCurrentState<ExtractCustomStateFromTemplate<AllTemplates<CustomTemplates>[RouterTypeName]>>;
export declare type TemplateReducer<CustomState = undefined, CustomActionNames extends string = undefined> = (location: IInputLocation, router: TemplateRouter<CustomState, CustomActionNames>, ctx: ReducerContext<any, any>) => RouterCurrentState<CustomState>;
export declare type TemplateAction<CustomState = undefined, CustomActionNames extends string = undefined> = (options?: IRouterActionOptions<CustomState>, existingLocation?: IOutputLocation, routerInstance?: TemplateRouter<CustomState, CustomActionNames>, ctx?: ILocationActionContext<any, any>) => IInputLocation;
export declare type TemplateRouter<CustomState = undefined, CustomActionNames extends string = undefined> = RouterInstance<{
template: IRouterTemplate<CustomState, CustomActionNames>;
}, 'template'>;
export declare type NarrowRouterTypeName<Names extends string | number | symbol> = Names extends string ? Names : never;
export declare type NarrowActionNames<Actions extends {}, ActionNames extends string | number | symbol = keyof Actions> = ActionNames extends string ? ActionNames : never;
export declare type Parent<CustomTemplates extends IRouterTemplates<unknown>> = {
[RouterType in keyof AllTemplates<CustomTemplates>]: RouterInstance<CustomTemplates, NarrowRouterTypeName<RouterType>>;
}[keyof AllTemplates<CustomTemplates>];
export declare type Root<CustomTemplates extends IRouterTemplates<unknown>, Name extends string = 'root'> = Name extends NarrowRouterTypeName<keyof AllTemplates<CustomTemplates>> ? RouterInstance<CustomTemplates, Name> : never;
export declare type Childs<CustomTemplates extends IRouterTemplates<unknown>> = {
[RouterType in NarrowRouterTypeName<keyof AllTemplates<CustomTemplates>>]?: Array<RouterInstance<CustomTemplates, NarrowRouterTypeName<RouterType>>>;
};
export declare type RefineTypeName<Templates extends IRouterTemplates, Name extends string | NarrowRouterTypeName<keyof Templates>> = Name extends NarrowRouterTypeName<keyof Templates> ? Name : NarrowRouterTypeName<keyof Templates>;
export declare type RouterInstance<CustomTemplates extends IRouterTemplates<unknown>, RouterTypeName extends NarrowRouterTypeName<keyof AllTemplates<CustomTemplates>> | string = NarrowRouterTypeName<keyof AllTemplates<CustomTemplates>>> = RouterTypeName extends NarrowRouterTypeName<keyof AllTemplates<CustomTemplates>> ? Actions<ExtractCustomActionNamesFromTemplate<AllTemplates<CustomTemplates>[RouterTypeName]>, CustomTemplates, RouterTypeName> & Reducer<CustomTemplates, RouterTypeName> & IRouterBase<CustomTemplates, RouterTypeName> : {
[rType in NarrowRouterTypeName<keyof AllTemplates<CustomTemplates>>]: Actions<ExtractCustomActionNamesFromTemplate<AllTemplates<CustomTemplates>[rType]>, CustomTemplates, rType> & Reducer<CustomTemplates, rType> & IRouterBase<CustomTemplates, rType>;
}[NarrowRouterTypeName<keyof AllTemplates<CustomTemplates>>];
export declare type RouterClass<CustomTemplates extends IRouterTemplates<unknown>, RouterTypeName extends NarrowRouterTypeName<keyof AllTemplates<CustomTemplates>>> = {
new (args: IRouterInitArgs<CustomTemplates, NarrowRouterTypeName<RouterTypeName>>): RouterInstance<CustomTemplates, RouterTypeName>;
};
export declare type IRouterTemplates<CustomState = undefined, CustomActionNames extends string = null> = {
[name: string]: IRouterTemplate<CustomState, CustomActionNames>;
};
export interface IRouterTemplate<CustomState = undefined, CustomActionNames extends string = null> {
actions: Actions<CustomActionNames, {
template: IRouterTemplate<CustomState, CustomActionNames>;
}, 'template'>;
reducer: RouterReducerFn<{
template: IRouterTemplate<CustomState, CustomActionNames>;
}, 'template'>;
config: IRouterTemplateConfig;
}
export interface IRouterTemplateConfig {
canBePathRouter?: boolean;
isPathRouter?: boolean;
shouldInverselyActivate?: boolean;
disableCaching?: boolean;
shouldParentTryToActivateSiblings?: boolean;
isDependentOnExternalData?: boolean;
}
export declare type RouterTemplateUnion<T extends IRouterTemplates<unknown>> = T[keyof T];
export declare type ExtractCustomStateFromTemplate<T extends IRouterTemplate<unknown>> = T extends IRouterTemplate<infer S> ? S : never;
export declare type ExtractCustomActionNamesFromTemplate<T extends IRouterTemplate<unknown>> = T extends IRouterTemplate<any, infer A> ? A : never;
export declare type RouterCurrentState<CustomState = undefined> = {
visible: boolean;
data?: CustomState;
actionCount?: number;
};
export declare type RouterHistoricalState<CustomState> = RouterCurrentState<CustomState>[];
export interface IRouterCurrentAndHistoricalState<CustomState> {
current: RouterCurrentState<CustomState>;
historical: RouterHistoricalState<CustomState>;
}
export interface ISerializeOptions {
showDefaults?: boolean;
showType?: boolean;
alwaysShowRouteKey?: boolean;
showParentName?: boolean;
}
export interface IRouterDeclaration<Templates extends IRouterTemplates<unknown>> {
name: string;
children?: Record<string, IRouterDeclaration<Templates>[]>;
routeKey?: string;
type?: NarrowRouterTypeName<keyof Templates>;
parentName?: string;
isPathRouter?: boolean;
shouldInverselyActivate?: boolean;
disableCaching?: boolean;
defaultAction?: [string] | [string, RouterCustomStateFromTemplates<Templates>] | [];
}
export interface IRouterInitArgs<CustomTemplates extends IRouterTemplates<unknown>, RouterTypeName extends NarrowRouterTypeName<keyof AllTemplates<CustomTemplates>>> {
name: string;
type: RouterTypeName;
manager: IManager<CustomTemplates>;
config: IRouterConfig<ExtractCustomStateFromTemplate<AllTemplates<CustomTemplates>[RouterTypeName]>>;
parent?: Parent<CustomTemplates>;
children?: Childs<CustomTemplates>;
root: Root<CustomTemplates>;
getState?: () => IRouterCurrentAndHistoricalState<ExtractCustomStateFromTemplate<AllTemplates<CustomTemplates>[RouterTypeName]>>;
subscribe?: (observer: Observer<ExtractCustomStateFromTemplate<AllTemplates<CustomTemplates>[RouterTypeName]>>) => void;
actions: (keyof AllTemplates<CustomTemplates>[RouterTypeName]['actions'])[];
}
export interface IRouterCreationInfo<CustomTemplates extends IRouterTemplates<unknown>, RouterTypeName extends NarrowRouterTypeName<keyof AllTemplates<CustomTemplates>>> {
name: string;
config: IRouterConfig<RouterCustomStateFromTemplates<AllTemplates<CustomTemplates>>>;
type: RouterTypeName;
parentName?: string;
}
export interface IRouterConfig<CustomState> {
routeKey: string;
isPathRouter: boolean;
shouldInverselyActivate: boolean;
disableCaching: boolean;
defaultAction: [string, CustomState] | [string] | [];
shouldParentTryToActivateSiblings: boolean;
isDependentOnExternalData: boolean;
}
export interface CacheClass<RouterCache extends IRouterCache<unknown>> {
new (): RouterCache;
}
export declare type NeighborsOfType<CustomTemplates extends IRouterTemplates<unknown>, N extends NarrowRouterTypeName<keyof AllTemplates<CustomTemplates>>> = Array<{
[RouterType in Exclude<keyof AllTemplates<CustomTemplates>, N>]?: RouterInstance<CustomTemplates, NarrowRouterTypeName<RouterType>>;
}[Exclude<keyof AllTemplates<CustomTemplates>, N>]>;
export declare type ActionWraperFnDecorator<CustomTemplates extends IRouterTemplates, Name extends NarrowRouterTypeName<keyof AllTemplates<CustomTemplates>>> = (fn: RouterActionFn<CustomTemplates, Name>) => RouterActionFn<CustomTemplates, Name>;
export declare type AllTemplates<CustomTemplates extends IRouterTemplates<unknown> | null | unknown = null> = CustomTemplates extends IRouterTemplates<unknown> ? Spread<DefaultTemplates, CustomTemplates> : DefaultTemplates;
export interface IManagerInit<CustomTemplates extends IRouterTemplates<unknown>> {
printTraceResults?: boolean;
routerDeclaration?: IRouterDeclaration<AllTemplates<CustomTemplates>>;
serializedStateStore?: ISerializedStateStore;
routerStateStore?: IRouterStateStore<RouterCustomStateFromTemplates<AllTemplates<CustomTemplates>>>;
router?: RouterClass<CustomTemplates, NarrowRouterTypeName<keyof AllTemplates<CustomTemplates>>>;
customTemplates?: CustomTemplates;
routerCacheClass?: CacheClass<IRouterCache<ExtractCustomStateFromTemplate<RouterTemplateUnion<AllTemplates<CustomTemplates>>>>>;
cacheKey?: string;
removeCacheAfterRehydration?: boolean;
errorWhenMissingData?: boolean;
}
export declare type RouterCustomStateFromTemplates<Templates extends IRouterTemplates<unknown>> = ExtractCustomStateFromTemplate<RouterTemplateUnion<Templates>>;
export declare type RouterCurrentStateFromTemplates<Templates extends IRouterTemplates<unknown>> = RouterCurrentState<ExtractCustomStateFromTemplate<RouterTemplateUnion<Templates>>>;
export declare type ManagerRouterTypes<CustomTemplates extends IRouterTemplates<unknown>> = {
[RouterType in keyof AllTemplates<CustomTemplates>]: RouterClass<CustomTemplates, NarrowRouterTypeName<RouterType>>;
};
export declare type StateObserver = (state: IOutputLocation) => any;
export declare type Observer<CustomState> = (state: IRouterCurrentAndHistoricalState<CustomState>) => unknown;
export declare type RouterStateObserver<CustomState> = (fn: Observer<CustomState>) => void;
export declare type RouterStateObservers<CustomState> = Record<string, Array<Observer<CustomState>>>;
export interface IRouterStateStoreConfig {
historySize?: number;
}
export declare type RouterStateStoreStore<CustomState> = Record<string, IRouterCurrentAndHistoricalState<CustomState>>;
export declare type Diff<T, U> = T extends U ? never : T;
export declare type OptionalPropertyNames<T> = {
[K in keyof T]: undefined extends T[K] ? K : never;
}[keyof T];
export declare type SpreadProperties<L, R, K extends keyof L & keyof R> = {
[P in K]: L[P] | Diff<R[P], undefined>;
};
export declare type Spread<L, R> = Pick<L, Diff<keyof L, keyof R>> & Pick<R, Diff<keyof R, OptionalPropertyNames<R>>> & Pick<R, Diff<OptionalPropertyNames<R>, keyof L>> & SpreadProperties<L, R, OptionalPropertyNames<R> & keyof L>;
export declare type Unpacked<T> = T extends (infer U)[] ? U : T extends (...args: any[]) => infer U ? U : T extends Promise<infer U> ? U : T;
export declare type ValueOf<T extends object> = T[keyof T];