UNPKG

1.79 kBPlain TextView Raw
1import { VNode, VNodeData } from "./vnode";
2import { h, addNS } from "./h";
3
4export interface ThunkData extends VNodeData {
5 fn: () => VNode;
6 args: any[];
7}
8
9export interface Thunk extends VNode {
10 data: ThunkData;
11}
12
13export interface ThunkFn {
14 (sel: string, fn: (...args: any[]) => any, args: any[]): Thunk;
15 (sel: string, key: any, fn: (...args: any[]) => any, args: any[]): Thunk;
16}
17
18function copyToThunk(vnode: VNode, thunk: VNode): void {
19 const ns = thunk.data?.ns;
20 (vnode.data as VNodeData).fn = (thunk.data as VNodeData).fn;
21 (vnode.data as VNodeData).args = (thunk.data as VNodeData).args;
22 thunk.data = vnode.data;
23 thunk.children = vnode.children;
24 thunk.text = vnode.text;
25 thunk.elm = vnode.elm;
26 if (ns) addNS(thunk.data, thunk.children, thunk.sel);
27}
28
29function init(thunk: VNode): void {
30 const cur = thunk.data as VNodeData;
31 const vnode = (cur.fn as any)(...cur.args!);
32 copyToThunk(vnode, thunk);
33}
34
35function prepatch(oldVnode: VNode, thunk: VNode): void {
36 let i: number;
37 const old = oldVnode.data as VNodeData;
38 const cur = thunk.data as VNodeData;
39 const oldArgs = old.args;
40 const args = cur.args;
41 if (old.fn !== cur.fn || (oldArgs as any).length !== (args as any).length) {
42 copyToThunk((cur.fn as any)(...args!), thunk);
43 return;
44 }
45 for (i = 0; i < (args as any).length; ++i) {
46 if ((oldArgs as any)[i] !== (args as any)[i]) {
47 copyToThunk((cur.fn as any)(...args!), thunk);
48 return;
49 }
50 }
51 copyToThunk(oldVnode, thunk);
52}
53
54export const thunk = function thunk(
55 sel: string,
56 key?: any,
57 fn?: any,
58 args?: any
59): VNode {
60 if (args === undefined) {
61 args = fn;
62 fn = key;
63 key = undefined;
64 }
65 return h(sel, {
66 key: key,
67 hook: { init, prepatch },
68 fn: fn,
69 args: args,
70 });
71} as ThunkFn;