import {VNode, VNodeData} from './vnode'; import {h} from './h'; export interface ThunkData extends VNodeData { fn: () => VNode; args: Array; } export interface Thunk extends VNode { data: ThunkData; } export interface ThunkFn { (sel: string, fn: Function, args: Array): Thunk; (sel: string, key: any, fn: Function, args: Array): Thunk; } function copyToThunk(vnode: VNode, thunk: VNode): void { thunk.elm = vnode.elm; (vnode.data as VNodeData).fn = (thunk.data as VNodeData).fn; (vnode.data as VNodeData).args = (thunk.data as VNodeData).args; thunk.data = vnode.data; thunk.children = vnode.children; thunk.text = vnode.text; thunk.elm = vnode.elm; } function init(thunk: VNode): void { const cur = thunk.data as VNodeData; const vnode = (cur.fn as any).apply(undefined, cur.args); copyToThunk(vnode, thunk); } function prepatch(oldVnode: VNode, thunk: VNode): void { let i: number, old = oldVnode.data as VNodeData, cur = thunk.data as VNodeData; const oldArgs = old.args, args = cur.args; if (old.fn !== cur.fn || (oldArgs as any).length !== (args as any).length) { copyToThunk((cur.fn as any).apply(undefined, args), thunk); return; } for (i = 0; i < (args as any).length; ++i) { if ((oldArgs as any)[i] !== (args as any)[i]) { copyToThunk((cur.fn as any).apply(undefined, args), thunk); return; } } copyToThunk(oldVnode, thunk); } export const thunk = function thunk(sel: string, key?: any, fn?: any, args?: any): VNode { if (args === undefined) { args = fn; fn = key; key = undefined; } return h(sel, { key: key, hook: {init: init, prepatch: prepatch}, fn: fn, args: args }); } as ThunkFn; export default thunk;