Skip to content

What about additionalKey? #213

@Lavshyak

Description

@Lavshyak
export type CoolerMittEventsBase = {
    [key: string]: {
        additionalKey?: string;
        payload?: unknown;
    };
};

export function coolerMitt<Events extends CoolerMittEventsBase>() {
    const handlers = new Map<string, ((payload: unknown) => void)[]>();

    function makeKey(key: string, additionalKey: string | undefined): string {
        return additionalKey ? `${key}?${additionalKey}` : key;
    }

    return {
        on<K extends keyof Events>(
            params: Events[K]["additionalKey"] extends string
                ? { key: K; additionalKey: Events[K]["additionalKey"] }
                : { key: K },
            handler: (payload: Events[K]["payload"]) => void
        ) {
            const key = makeKey(params.key as string, "additionalKey" in params ? params.additionalKey : undefined);
            const list = handlers.get(key) ?? [];
            list.push(handler);
            handlers.set(key, list);
        },

        off<K extends keyof Events>(
            params: Events[K]["additionalKey"] extends string
                ? { key: K; additionalKey: Events[K]["additionalKey"] }
                : { key: K },
            handler: (payload: Events[K]["payload"]) => void
        ) {
            const key = makeKey(params.key as string, "additionalKey" in params ? params.additionalKey : undefined);
            const list = handlers.get(key);
            if(!list)
                return
            const updated = list.filter(h => h !== handler);
            handlers.set(key, updated);
        },

        emit<K extends keyof Events>(
            params: Events[K]["additionalKey"] extends string
                ? { key: K; additionalKey: Events[K]["additionalKey"] }
                : { key: K },
            payload: Events[K]["payload"]
        ) {
            const key = makeKey(params.key as string, "additionalKey" in params ? params.additionalKey : undefined);
            const list = handlers.get(key);
            list?.forEach((h) => h(payload));
        },
    };
}


{
    type MyEvents = {
        entityChanged: {
            additionalKey: string;
            payload: string;
        };
        entitiesArrayChanged: {
            additionalKey: undefined;
            payload: undefined;
        };
    };

    const bus = coolerMitt<MyEvents>()

    bus.emit({key: "entityChanged", additionalKey: "123"}, "stateee")

    bus.on({key: "entityChanged", additionalKey: "334"}, payload => console.log(payload))

    bus.emit({key: "entitiesArrayChanged"}, undefined)

    bus.on({key: "entitiesArrayChanged"}, () => console.log())
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions