import { Component } from "../component/component"; import type { ComponentNode } from "../component/component_node"; import { xml } from "../tags"; import { Fiber } from "../component/fibers"; export class Memo extends Component { static template = xml``; constructor(props: any, env: any, node: ComponentNode) { super(props, env, node); // prevent patching process conditionally let applyPatch = false; const patchFn = node.patch; node.patch = () => { if (applyPatch) { patchFn.call(node); applyPatch = false; } }; // check props change, and render/apply patch if it changed let prevProps = props; const updateAndRender = node.updateAndRender; node.updateAndRender = function (props: any, parentFiber: Fiber) { const shouldUpdate = !shallowEqual(prevProps, props); if (shouldUpdate) { prevProps = props; updateAndRender.call(node, props, parentFiber); applyPatch = true; } return Promise.resolve(); }; } } /** * we assume that each object have the same set of keys */ function shallowEqual(p1: any, p2: any): boolean { for (let k in p1) { if (p1[k] !== p2[k]) { return false; } } return true; }