diff --git a/src/reconcile.ts b/src/reconcile.ts index 7102ff2c..52d5babe 100644 --- a/src/reconcile.ts +++ b/src/reconcile.ts @@ -2,7 +2,6 @@ import { IFiber, FreElement, FC, - Attributes, HTMLElementEx, FreNode, HookEffect, @@ -23,10 +22,10 @@ export const enum TAG { SVG = 1 << 4, DIRTY = 1 << 5, MOVE = 1 << 6, - REPLACE = 1 << 7 + REPLACE = 1 << 7, } -export const render = (vnode: FreElement, node: Node): void => { +export const render = (vnode: FreElement, node: Node) => { rootFiber = { node, props: { children: vnode }, @@ -41,23 +40,24 @@ export const update = (fiber?: IFiber) => { } } -const reconcile = (fiber?: IFiber): boolean => { +const reconcile = (fiber?: IFiber) => { while (fiber && !shouldYield()) fiber = capture(fiber) - if (fiber) return reconcile.bind(null, fiber) + if (fiber) return reconcile.bind(null, fiber) as typeof reconcile return null } -const memo = (fiber) => { +const memo = (fiber: IFiber) => { if ((fiber.type as FC).memo && fiber.old?.props) { let scu = (fiber.type as FC).shouldUpdate || shouldUpdate - if (!scu(fiber.props, fiber.old.props)) { // fast-fix + if (!scu(fiber.props, fiber.old.props)) { + // fast-fix return getSibling(fiber) } } return null } -const capture = (fiber: IFiber): IFiber | undefined => { +const capture = (fiber: IFiber) => { fiber.isComp = isFn(fiber.type) if (fiber.isComp) { const memoFiber = memo(fiber) @@ -73,7 +73,7 @@ const capture = (fiber: IFiber): IFiber | undefined => { return sibling } -const getSibling = (fiber) => { +const getSibling = (fiber?: IFiber) => { while (fiber) { bubble(fiber) if (fiber.dirty) { @@ -87,7 +87,7 @@ const getSibling = (fiber) => { return null } -const bubble = fiber => { +const bubble = (fiber: IFiber) => { if (fiber.isComp) { if (fiber.hooks) { side(fiber.hooks.layout) @@ -96,24 +96,26 @@ const bubble = fiber => { } } - -const shouldUpdate = (a, b) => { +const shouldUpdate = ( + a: Record, + b: Record +) => { for (let i in a) if (!(i in b)) return true for (let i in b) if (a[i] !== b[i]) return true } -const updateHook =

(fiber: IFiber): any => { +const updateHook = (fiber: IFiber) => { resetCursor() currentFiber = fiber - let children = (fiber.type as FC

)(fiber.props) + let children = (fiber.type as FC)(fiber.props) reconcileChidren(fiber, simpleVnode(children)) } -const updateHost = (fiber: IFiber): void => { - fiber.parentNode = (getParentNode(fiber) as any) || {} +const updateHost = (fiber: IFiber) => { + fiber.parentNode = getParentNode(fiber) || {} if (!fiber.node) { if (fiber.type === 'svg') fiber.lane |= TAG.SVG - fiber.node = createElement(fiber) as HTMLElementEx + fiber.node = createElement(fiber) } reconcileChidren(fiber, fiber.props.children) } @@ -121,15 +123,15 @@ const updateHost = (fiber: IFiber): void => { const simpleVnode = (type: any) => isStr(type) ? createText(type as string) : type -const getParentNode = (fiber: IFiber): HTMLElement | undefined => { +const getParentNode = (fiber: IFiber) => { while ((fiber = fiber.parent)) { if (!fiber.isComp) return fiber.node } } -const reconcileChidren = (fiber: any, children: FreNode): void => { +const reconcileChidren = (fiber: IFiber, children: FreNode) => { let aCh = fiber.kids || [], - bCh = (fiber.kids = arrayfy(children) as any) + bCh = (fiber.kids = arrayfy(children)) const actions = diff(aCh, bCh) for (let i = 0, prev = null, len = bCh.length; i < len; i++) { @@ -156,11 +158,11 @@ function clone(a, b) { b.old = a } -export const arrayfy = arr => (!arr ? [] : isArr(arr) ? arr : [arr]) +export const arrayfy = (arr: unknown) => (!arr ? [] : isArr(arr) ? arr : [arr]) -const side = (effects: HookEffect[]): void => { - effects.forEach(e => e[2] && e[2]()) - effects.forEach(e => (e[2] = e[0]())) +const side = (effects: HookEffect[]) => { + effects.forEach((e) => e[2] && e[2]()) + effects.forEach((e) => (e[2] = e[0]())) effects.length = 0 } @@ -168,34 +170,37 @@ const diff = function (a, b) { var actions = [], aIdx = {}, bIdx = {}, - key = v => v.key + v.type, - i, j; + key = (v) => v.key + v.type, + i, + j for (i = 0; i < a.length; i++) { - aIdx[key(a[i])] = i; + aIdx[key(a[i])] = i } for (i = 0; i < b.length; i++) { - bIdx[key(b[i])] = i; + bIdx[key(b[i])] = i } - for (i = j = 0; i !== a.length || j !== b.length;) { - var aElm = a[i], bElm = b[j]; + for (i = j = 0; i !== a.length || j !== b.length; ) { + var aElm = a[i], + bElm = b[j] if (aElm === null) { - i++; + i++ } else if (b.length <= j) { removeElement(a[i]) - i++; + i++ } else if (a.length <= i) { actions.push({ op: TAG.INSERT, elm: bElm, before: a[i] }) - j++; + j++ } else if (key(aElm) === key(bElm)) { clone(aElm, bElm) actions.push({ op: TAG.UPDATE }) - i++; j++; + i++ + j++ } else { var curElmInNew = bIdx[key(aElm)] var wantedElmInOld = aIdx[key(bElm)] if (curElmInNew === undefined) { removeElement(a[i]) - i++; + i++ } else if (wantedElmInOld === undefined) { actions.push({ op: TAG.INSERT, elm: bElm, before: a[i] }) j++ @@ -211,6 +216,6 @@ const diff = function (a, b) { } export const getCurrentFiber = () => currentFiber || null -export const isFn = (x: any): x is Function => typeof x === 'function' -export const isStr = (s: any): s is number | string => - typeof s === 'number' || typeof s === 'string' \ No newline at end of file +export const isFn = (x: unknown): x is Function => typeof x === 'function' +export const isStr = (s: unknown): s is number | string => + typeof s === 'number' || typeof s === 'string' diff --git a/src/type.ts b/src/type.ts index c900e4c0..7a3e3c36 100644 --- a/src/type.ts +++ b/src/type.ts @@ -28,8 +28,6 @@ export interface FreElement

{ key: string } -export type HookTypes = 'list' | 'effect' | 'layout' - export interface Hooks { list: HookList[] layout: HookEffect[] @@ -47,7 +45,7 @@ export type HookReducer = [value: V, dispatch: Dispatch] export interface IFiber

{ key?: string type: string | FC

- parentNode: HTMLElementEx + parentNode: HTMLElementEx | {} node: HTMLElementEx kids?: any dirty: boolean @@ -55,6 +53,7 @@ export interface IFiber

{ sibling?: IFiber

child?: IFiber

ref?: Ref + old?: IFiber hooks?: Hooks action: any props: P @@ -62,7 +61,7 @@ export interface IFiber

{ isComp: boolean } -export type HTMLElementEx = HTMLElement & { last: IFiber | null } +export type HTMLElementEx = HTMLElement | Text | SVGElement export type FreText = string | number export type FreNode =