Skip to content

Commit

Permalink
improve type declarations
Browse files Browse the repository at this point in the history
  • Loading branch information
huang2002 committed Jan 30, 2019
1 parent a090095 commit 222c3e7
Show file tree
Hide file tree
Showing 16 changed files with 271 additions and 242 deletions.
343 changes: 171 additions & 172 deletions index.d.ts

Large diffs are not rendered by default.

28 changes: 14 additions & 14 deletions src/core/HNode.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Store, createStore, HandlerMap, PartialHandlers } from "./Store";
import { Store, createStore, PartialHandlers, StoreType, StoreHandlers } from "./Store";
import { _document, _isArray, _Infinity, _Map, _entries, _createTextNode } from "../utils/refCache";
import { toArr, isHNode } from "../utils/helpers";
import { handleProp } from "./handleProp";
Expand Down Expand Up @@ -27,25 +27,25 @@ export type HProps<P extends object = any> = {
children: unknown[];
});

export interface HDesc<P extends object = any, S extends object = any, C extends object = any, SH extends HandlerMap<S> = any, CH extends HandlerMap<C> = any> {
export interface HDesc<P extends object = any, S extends Store = Store, C extends Store = Store> {
defaultProps?: Partial<P>;
defaultStore?: Partial<S>;
storeHandlers?: PartialHandlers<SH, Store<S>>;
state?: Array<keyof S>;
context?: Array<keyof C>;
init?: (this: HNode<P, S, C, SH, CH>, props: HProps<P>, store: Store<S, SH>, context: Store<C, CH>) => void;
render: (this: HNode<P, S, C, SH, CH>, props: HProps<P>, store: Store<S, SH>, context: Store<C, CH>) => unknown;
clear?: (this: HNode<P, S, C, SH, CH>, props: HProps<P>, store: Store<S, SH>, context: Store<C, CH>) => void;
catch?: (this: HNode<P, S, C, SH, CH>, err: any, props: HProps<P>, store: Store<S, SH>, context: Store<C, CH>) => unknown;
defaultStore?: Partial<StoreType<S>>;
storeHandlers?: PartialHandlers<StoreHandlers<S>, S>;
state?: Array<keyof StoreType<S>>;
context?: Array<keyof StoreType<C>>;
init?: (this: HNode<P, S, C>, props: HProps<P>, store: S, context: C) => void;
render: (this: HNode<P, S, C>, props: HProps<P>, store: S, context: C) => unknown;
clear?: (this: HNode<P, S, C>, props: HProps<P>, store: S, context: C) => void;
catch?: (this: HNode<P, S, C>, err: any, props: HProps<P>, store: S, context: C) => unknown;
}

export interface HNode<P extends object = EleProps, S extends object = any, C extends object = any, SH extends HandlerMap<S> = any, CH extends HandlerMap<C> = any> {
export interface HNode<P extends object = EleProps, S extends Store = Store, C extends Store = Store> {
isHN: true;
type: unknown;
desc?: HDesc<P, S, C, SH, CH>;
desc?: HDesc<P, S, C>;
props: HProps<P>;
sto?: Store<S, SH>;
ctx?: Store<C, CH>;
sto?: S;
ctx?: C;
owner?: HNode<any>;
ownNode?: Node;
out?: unknown[];
Expand Down
55 changes: 43 additions & 12 deletions src/core/HUI.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,23 @@
import { HNode, HProps } from "./HNode";
import { registry, define, HType } from "./registry";
import { HProps as _HProps, HDesc as _HDesc, HNode as _HNode } from "./HNode";
import { registry, define, HType as _HType } from "./registry";
import { _assign, _Infinity, _requestAnimationFrame } from "../utils/refCache";
import { createStore, HandlerMap } from "./Store";
import { renderToDOM } from "./render";
import { propHandlers, EleProps } from "./propHandlers";
import { Portal } from "../ext/Portal";
import { Store as _Store, createStore, HandlerMap as _HandlerMap, Setter as _Setter, SetterRecord as _SetterRecord, StoreType as _StoreType, StoreHandlers as _StoreHandlers, PartialHandlers as _PartialHandlers } from "./Store";
import { RenderOptions as _RenderOptions, renderToDOM } from "./render";
import { propHandlers, EleProps as _EleProps, PropHandler as _PropHandler, RefCallback as _RefCallback, AttributeMap as _AttributeMap } from "./propHandlers";
import { EventRecord as _EventRecord, EventMap as _EventMap } from "./events";
import { Portal, PortalProps as _PortalProps, PortalStore as _PortalStore } from "../ext/Portal";
import { Fragment, FragmentProps as _FragmentProps } from "../ext/Fragment";
import { defer } from "../ticker/ticker";
import { compare } from "../utils/cmp";
import { Fragment } from "../ext/Fragment";
import { noCmpProps } from "../ticker/patch";

export const HUI = <P extends object = EleProps, S extends object = any, C extends object = any, SH extends HandlerMap<S> = any, CH extends HandlerMap<C> = any>(
type: HType<P, S, C, SH, CH> | string, props?: P | null, ...children: unknown[]
): HNode<P, S, C, SH, CH> => ({
export const HUI = <P extends object = _EleProps, S extends _Store = _Store, C extends _Store = _Store>(
type: _HType<P, S, C> | string, props?: P | null, ...children: unknown[]
): _HNode<P, S, C> => ({
isHN: true,
type,
desc: registry.get(type),
props: _assign({ children: children.flat(_Infinity) }, props) as unknown as HProps<P>,
desc: registry.get(type as any),
props: _assign({ children: children.flat(_Infinity) }, props) as unknown as _HProps<P>,
active: true
});

Expand All @@ -38,3 +39,33 @@ HUI.Portal = Portal;
HUI.Fragment = Fragment;

HUI.cmp = compare;

export namespace HUI {

export type HProps<P extends object = any> = _HProps<P>;
export type HDesc<P extends object = any, S extends _Store = _Store, C extends _Store = _Store> = _HDesc<P, S, C>;
export type HNode<P extends object = any, S extends _Store = _Store, C extends _Store = _Store> = _HNode<P, S, C>;

export type HType<P extends object = any, S extends _Store = _Store, C extends _Store = _Store> = _HType<P, S, C>;

export type Store<T extends object = any, H extends _HandlerMap = any> = _Store<T, H>;
export type HandlerMap<T extends object = any> = _HandlerMap<T>;
export type Setter<T = unknown> = _Setter<T>;
export type SetterRecord<T = unknown> = _SetterRecord<T>;

export type RenderOptions<C extends Store = Store> = _RenderOptions<C>;

export type EleProps<T extends Element = Element> = _EleProps<T>;
export type PropHandler<T = unknown> = _PropHandler<T>;
export type RefCallback<T extends Element = Element> = _RefCallback<T>;
export type AttributeMap = _AttributeMap;

export type EventRecord = _EventRecord;
export type EventMap = _EventMap;

export type FragmentProps = _FragmentProps;

export type PortalProps = _PortalProps;
export type PortalStore = _PortalStore;

}
11 changes: 7 additions & 4 deletions src/core/Store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,19 +9,22 @@ type MapOf<T> = Map<keyof T, Pick<T, keyof T>>;
type InjectThis<F extends (...args: any[]) => any, T> = (this: T, ...args: Parameters<F>) => ReturnType<F>;

export type Setter<T = unknown> = (value: T) => void;
export type SetterRecord = [Setter | undefined, Setter | undefined];
export type SetterRecord<T = unknown> = [Setter<T> | undefined, Setter<T> | undefined];

export interface HandlerMap<T extends object = any> {
[name: string]: (this: Store<T, HandlerMap<T>>, ...args: any[]) => any;
}

export type PartialHandlers<H extends HandlerMap, T> = { [K in keyof H]?: InjectThis<H[K], T> | null };

export type StoreType<S> = S extends Store<infer T> ? T : never;
export type StoreHandlers<S> = S extends Store<any, infer H> ? H : never;

export interface Store<T extends object = any, H extends HandlerMap<T> = any> {

valueMap: MapOf<T>;
bindingMap: Map<keyof T, HNode<any>[]>;
setterMap: Map<keyof T, SetterRecord>;
setterMap: Map<keyof T, SetterRecord<any>>;
handlerMap: MapOf<H>;

bind(hNode: HNode<any>, subscriptions: Array<keyof T>): this;
Expand Down Expand Up @@ -54,7 +57,7 @@ export const createStore = function crtSto<

const valueMap = new _Map<keyof T, any>(),
bindingMap = new _Map<keyof T, HNode<any>[]>(),
setterMap = new _Map<keyof T, SetterRecord>(),
setterMap = new _Map<keyof T, SetterRecord<any>>(),
handlerMap = new _Map<keyof H, any>();

const store: Store<T, H> = {
Expand Down Expand Up @@ -120,7 +123,7 @@ export const createStore = function crtSto<

const setters = new Array<Setter>();

setterMap.set(key, setters as SetterRecord);
setterMap.set(key, setters as SetterRecord<any>);

return setters[index] = function setter(value: any) {
store.set(key, value, force);
Expand Down
20 changes: 8 additions & 12 deletions src/core/registry.ts
Original file line number Diff line number Diff line change
@@ -1,24 +1,20 @@
import { HDesc } from "./HNode";
import { _Map, _Symbol } from "../utils/refCache";
import { Store, HandlerMap } from "./Store";
import { Store } from "./Store";

export interface HType<P extends object = any, S extends object = any, C extends object = any, SH extends HandlerMap<S> = any, CH extends HandlerMap<C> = any> {
(props: P, store: Store<S, SH>, context: Store<C, CH>): any;
export interface HType<P extends object = any, S extends Store = Store, C extends Store = Store> {
(props: P, store: S, context: C): any;
};

export const registry = new _Map<HType<any> | string, HDesc<any>>();

export const define = function <
P extends object = any,
S extends object = any,
C extends object = any,
SH extends HandlerMap<S> = any,
CH extends HandlerMap<C> = any
>(name: string, desc: HDesc<P, S, C, SH, CH>): HType<P, S, C, SH, CH> {
export const define = function <P extends object = any, S extends Store = Store, C extends Store = Store>(
name: string, desc: HDesc<P, S, C>
): HType<P, S, C> {

const type = _Symbol(name) as unknown as HType<P, S, C, SH, CH>;
const type = _Symbol(name) as unknown as HType<P, S, C>;

registry.set(type, desc);
registry.set(type as any, desc as any);

return type;

Expand Down
18 changes: 9 additions & 9 deletions src/core/render.ts
Original file line number Diff line number Diff line change
@@ -1,27 +1,27 @@
import { toNodeArr, HNode } from "./HNode";
import { _document, _assign, _from } from "../utils/refCache";
import { createStore, Store, HandlerMap, PartialHandlers } from "./Store";
import { createStore, Store, PartialHandlers, StoreType, StoreHandlers } from "./Store";
import { toFrag } from "../utils/helpers";
import { DeferCallback, reqTick, willTick } from "../ticker/ticker";

export const renderCallbacks = new Array<DeferCallback<[]>>();

export interface RenderOptions<C extends object = any, H extends HandlerMap<C> = any> {
export interface RenderOptions<C extends Store = Store> {
clear?: boolean;
context?: Store<C, H>;
defaultContext?: Partial<C>;
contextHandlers?: PartialHandlers<H, Store<C, H>>;
context?: C;
defaultContext?: Partial<StoreType<C>>;
contextHandlers?: PartialHandlers<StoreHandlers<C>, C>;
parent?: Node;
owner?: HNode<any, any, C>;
owner?: HNode<any>;
sync?: boolean;
}

export const renderToDOM = function render<C extends object = any, H extends HandlerMap<C> = any>(
src: any, options: RenderOptions<C, H> = {}
export const renderToDOM = function render<C extends Store = Store>(
src: any, options: RenderOptions<C> = {}
) {

const { parent = _document.body,
clear, owner, context = createStore<C, H>(),
clear, owner, context = createStore<StoreType<C>, StoreHandlers<C>>() as C,
defaultContext, contextHandlers } = options;

if (defaultContext) {
Expand Down
3 changes: 2 additions & 1 deletion src/ext/Fragment.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import { define } from "../core/registry";
import { Store } from "../core/Store";

export interface FragmentProps {
children: unknown;
}

export const Fragment = define<FragmentProps, {}, {}, {}, {}>('HUI.Fragment', {
export const Fragment = define<FragmentProps, Store<{}>, Store<{}>>('HUI.Fragment', {
render: function frag_render(props) {
return props.children;
}
Expand Down
5 changes: 3 additions & 2 deletions src/ext/Portal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { clear } from "../utils/clear";
import { HNode } from "../core/HNode";
import { FragmentProps, Fragment } from "./Fragment";
import { HUI } from "../core/HUI";
import { Store } from "../core/Store";

export interface PortalProps {
parent?: Node;
Expand All @@ -13,10 +14,10 @@ export interface PortalProps {

export interface PortalStore {
p: Node;
f: HNode<FragmentProps, {}, {}, {}, {}>;
f: HNode<FragmentProps, Store<{}>, Store<{}>>;
}

export const Portal = define<PortalProps, PortalStore, {}, {}, {}>('HUI.Portal', {
export const Portal = define<PortalProps, Store<PortalStore>, Store<{}>>('HUI.Portal', {

init: function port_init(props, store) {
store.set('p', props.parent || _document.body);
Expand Down
4 changes: 2 additions & 2 deletions test/src/CatchTest.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@ interface ThrowerProps {
msg: string;
}

const Thrower = HUI.define<ThrowerProps, {}, {}>('Thrower', {
const Thrower = HUI.define<ThrowerProps, HUI.Store<{}>, HUI.Store<{}>>('Thrower', {
render(props) {
throw props.msg;
}
});

const CatchTest = HUI.define<{}, {}, {}>('CatchTest', {
const CatchTest = HUI.define<{}, HUI.Store<{}>, HUI.Store<{}>>('CatchTest', {

render() {
return (
Expand Down
2 changes: 1 addition & 1 deletion test/src/Dialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ type DialogStoreHandlers = {
toggle: () => void;
}

const Dialog = HUI.define<{}, DialogStore, {}, DialogStoreHandlers>('Dialog', {
const Dialog = HUI.define<{}, HUI.Store<DialogStore, DialogStoreHandlers>, HUI.Store<{}>>('Dialog', {

state: ['on'],

Expand Down
6 changes: 3 additions & 3 deletions test/src/Greeting.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ interface GreetingProps {
children: string;
}

const Greeting = HUI.define<GreetingProps, {}, TestContext, {}, TestContextHandlers>('Greeting', {
const Greeting = HUI.define<GreetingProps, HUI.Store<{}>, TestContext>('Greeting', {
context: ['target'],
init(props, store, context) {
context.set('target', props.children[0]);
Expand Down Expand Up @@ -43,7 +43,7 @@ const Greeting = HUI.define<GreetingProps, {}, TestContext, {}, TestContextHandl
}
});

const ShowTarget = HUI.define<{}, {}, TestContext>('ShowTarget', {
const ShowTarget = HUI.define<{}, HUI.Store<{}>, TestContext>('ShowTarget', {
context: ['target'],
render(props, store, context) {
return `context.target: ${context.get('target')}`;
Expand All @@ -55,7 +55,7 @@ interface RefTestStore {
ref?: HTMLParagraphElement;
}

const RefTest = HUI.define<{}, RefTestStore, {}>('RefTest', {
const RefTest = HUI.define<{}, HUI.Store<RefTestStore>, HUI.Store<{}>>('RefTest', {

state: ['msg'],

Expand Down
2 changes: 1 addition & 1 deletion test/src/Inspector.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ interface InspectorProps {
children: unknown;
}

const Inspector = HUI.define<InspectorProps, {}, {}>('Inspector', {
const Inspector = HUI.define<InspectorProps, HUI.Store<{}>, HUI.Store<{}>>('Inspector', {

render(props) {
HUI.defer((self) => {
Expand Down
2 changes: 1 addition & 1 deletion test/src/TestInput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ interface TestInputStore {
value: string;
}

const TestInput = HUI.define<TestInputProps, TestInputStore, {}>('TestInput', {
const TestInput = HUI.define<TestInputProps, HUI.Store<TestInputStore>, HUI.Store<{}>>('TestInput', {

state: ['value'],

Expand Down
2 changes: 1 addition & 1 deletion test/src/ThrowTest.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ interface ThrowTestStore {
msg: string;
}

const ThrowTest = HUI.define<{}, ThrowTestStore, {}>('ThrowTest', {
const ThrowTest = HUI.define<{}, HUI.Store<ThrowTestStore>, HUI.Store<{}>>('ThrowTest', {

state: ['msg'],

Expand Down
2 changes: 1 addition & 1 deletion test/src/Timer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ type TimerStoreHandlers = {
setInterval: (interval: number) => any;
}

const Timer = HUI.define<TimerProps, TimerStore, {}, TimerStoreHandlers, {}>('Timer', {
const Timer = HUI.define<TimerProps, HUI.Store<TimerStore, TimerStoreHandlers>, HUI.Store<{}>>('Timer', {

state: ['time'],

Expand Down
10 changes: 4 additions & 6 deletions test/src/test.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,15 @@
/// <reference types="../.." />

interface TestContext {
type TestContext = HUI.Store<{
target: string;
'greeting-color': string;
}

type TestContextHandlers = {
}, {
changeTarget: (newTarget: string) => string;
};
}>;

const SVG_NS = 'http://www.w3.org/2000/svg';

HUI.render<TestContext, TestContextHandlers>(
HUI.render<TestContext>(
(

<Inspector>
Expand Down

0 comments on commit 222c3e7

Please sign in to comment.