<commit_before>const mitt = require('mitt');
const give = require('xet');
const curry = require('curry');
const DeepMap = require('./deepmap');
const createRenderer = require('./create-renderer');
const noop = () => {};
const instances = new DeepMap();

function defineHooks(emitter, vnode) {
    vnode.data.hook = vnode.data.hook || {};

    const userInsert = vnode.data.hook.insert || noop;
    const userPostpatch = vnode.data.hook.postpatch || noop;

    vnode.data.hook.insert = vnode => {
        vnode.emitter = emitter;
        userInsert(vnode);
    };

    vnode.data.hook.postpatch = (oldVnode, vnode) => {
        if (vnode && vnode.elm.parentElement) {
            const children = vnode.elm.parentElement.vnode.children;
            children[children.indexOf(oldVnode)] = vnode;
            userPostpatch(oldVnode, vnode);
        }
    };

    return vnode;
}

function createComponent(factory, { props = {} }) {
    const render = createRenderer();

    const emitter = mitt();

    emitter.on('self:update', () => {
        render({ view, state, props });
    });

    const { view: userView, store } = factory({ emitter, component: component(emitter), props });

    const view = ({ state, props }) => {
        return defineHooks(emitter, userView({ state, props }));
    };

    const state = store();

    render({ view, state, props });

    return render;
}

const component = curry((emitter, factory, props) => {
    const keys = [emitter, component, props.key];

    const instance = give.call(instances, keys, () => createComponent(factory, { props }));

    return instance.getVnode();
});

exports.defineHooks = defineHooks;
exports.createComponent = createComponent;
exports.component = component;<commit_msg>fixed on destroy remove the component from the graph deepmap<commit_after>const mitt = require('mitt');
const give = require('xet');
const curry = require('curry');
const DeepMap = require('./deepmap');
const createRenderer = require('./create-renderer');
const noop = () => {};
const instances = new DeepMap();

function defineHooks(emitter, vnode) {
    vnode.data.hook = vnode.data.hook || {};

    const userDestroy = vnode.data.hook.destroy || noop;
    const userPostpatch = vnode.data.hook.postpatch || noop;

    vnode.data.hook.destroy = vnode => {
        userDestroy(vnode);
        emitter.emit('self:destroy');
    };

    vnode.data.hook.postpatch = (oldVnode, vnode) => {
        if (vnode && vnode.elm.parentElement) {
            const children = vnode.elm.parentElement.vnode.children;
            children[children.indexOf(oldVnode)] = vnode;
            userPostpatch(oldVnode, vnode);
        }
    };

    vnode.data.emitter = emitter;

    return vnode;
}

function createComponent(factory, { props = {} }) {
    const render = createRenderer();

    const emitter = mitt();

    emitter.on('self:update', () => {
        render({ view, state, props });
    });

    const { view: userView, store } = factory({ emitter, component: component(emitter), props });

    const view = ({ state, props }) => {
        return defineHooks(emitter, userView({ state, props }));
    };

    const state = store();

    render({ view, state, props });

    return render;
}

const component = curry((emitter, factory, props) => {
    const keys = [emitter, factory, props.key];

    const instance = give.call(instances, keys, () => {
        const render = createComponent(factory, { props });
        const emitter = render.getVnode().data.emitter;

        emitter.on('self:destroy', () => {
            instances.delete(keys);
        });

        return render;
    });

    return instance.getVnode();
});

exports.defineHooks = defineHooks;
exports.createComponent = createComponent;
exports.component = component;
{'fraction_non_alphanumeric': 0.1511535401750199, 'fraction_numerical': 0.0, 'mean_word_length': 3.1, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 18, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6369440', 'n_tokens_mistral': 1129, 'n_tokens_neox': 1076, 'n_words': 256}