Improve performance by limiting renders
This commit is contained in:
		
							parent
							
								
									cf47b79052
								
							
						
					
					
						commit
						7330ebf9f2
					
				
							
								
								
									
										29
									
								
								memory.ts
									
									
									
									
									
								
							
							
						
						
									
										29
									
								
								memory.ts
									
									
									
									
									
								
							@ -5,7 +5,7 @@ import { RequestCluster } from './request-cluster';
 | 
			
		||||
 | 
			
		||||
export default class Memory extends EventEmitter {
 | 
			
		||||
    origin_to_history = {} as Record<string, Record<string, RequestCluster>>;
 | 
			
		||||
    private throttle = makeThrottle(200);
 | 
			
		||||
    private throttle = makeThrottle(100);
 | 
			
		||||
    async register(request: ExtendedRequest) {
 | 
			
		||||
        await request.init();
 | 
			
		||||
        if (!request.isThirdParty()) {
 | 
			
		||||
@ -20,7 +20,7 @@ export default class Memory extends EventEmitter {
 | 
			
		||||
            this.origin_to_history[request.origin][shorthost] = cluster;
 | 
			
		||||
        }
 | 
			
		||||
        this.origin_to_history[request.origin][shorthost].add(request);
 | 
			
		||||
        this.emit('change');
 | 
			
		||||
        this.emit('change', false, shorthost, 'registered request(shorthost emit)');
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    constructor() {
 | 
			
		||||
@ -35,9 +35,9 @@ export default class Memory extends EventEmitter {
 | 
			
		||||
        );
 | 
			
		||||
        browser.webRequest.onBeforeSendHeaders.addListener(
 | 
			
		||||
            async (request) => {
 | 
			
		||||
                const extendedRequest = ExtendedRequest.by_id[
 | 
			
		||||
                    request.requestId
 | 
			
		||||
                ].addHeaders(request.requestHeaders || []);
 | 
			
		||||
                const extendedRequest = ExtendedRequest.by_id[request.requestId].addHeaders(
 | 
			
		||||
                    request.requestHeaders || []
 | 
			
		||||
                );
 | 
			
		||||
                this.register(extendedRequest);
 | 
			
		||||
            },
 | 
			
		||||
            { urls: ['<all_urls>'] },
 | 
			
		||||
@ -45,13 +45,16 @@ export default class Memory extends EventEmitter {
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    emit(eventName: string, immediate = false) {
 | 
			
		||||
    emit(eventName: string, immediate = false, data = 'any', reason: string) {
 | 
			
		||||
        console.log('emitting!', eventName, data, reason);
 | 
			
		||||
        setTimeout(() => super.emit(eventName, data), 0);
 | 
			
		||||
        return;
 | 
			
		||||
        try {
 | 
			
		||||
            if (immediate) {
 | 
			
		||||
                super.emit(eventName);
 | 
			
		||||
                super.emit(eventName, data);
 | 
			
		||||
                return;
 | 
			
		||||
            } else {
 | 
			
		||||
                this.throttle(() => super.emit(eventName));
 | 
			
		||||
                this.throttle(() => super.emit(eventName, data));
 | 
			
		||||
            }
 | 
			
		||||
            return true;
 | 
			
		||||
        } catch (e) {
 | 
			
		||||
@ -68,12 +71,7 @@ export default class Memory extends EventEmitter {
 | 
			
		||||
        if (shorthost) {
 | 
			
		||||
            const cookies = await browser.cookies.getAll({ domain: shorthost });
 | 
			
		||||
            for (const cookie of cookies) {
 | 
			
		||||
                console.log(
 | 
			
		||||
                    'removing cookie',
 | 
			
		||||
                    cookie.name,
 | 
			
		||||
                    'from',
 | 
			
		||||
                    cookie.domain
 | 
			
		||||
                );
 | 
			
		||||
                console.log('removing cookie', cookie.name, 'from', cookie.domain);
 | 
			
		||||
                await browser.cookies.remove({
 | 
			
		||||
                    name: cookie.name,
 | 
			
		||||
                    url: `https://${cookie.domain}`,
 | 
			
		||||
@ -102,6 +100,5 @@ export function init() {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export function getMemory(): Memory {
 | 
			
		||||
    return (browser.extension.getBackgroundPage().window as any)
 | 
			
		||||
        .memory as Memory;
 | 
			
		||||
    return (browser.extension.getBackgroundPage().window as any).memory as Memory;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -2,7 +2,7 @@ import React from 'react';
 | 
			
		||||
import ReactDOM from 'react-dom';
 | 
			
		||||
import Options from '../options';
 | 
			
		||||
import { StolenData } from './stolen-data';
 | 
			
		||||
import { useEmitter } from '../util';
 | 
			
		||||
import { getshorthost, useEmitter } from '../util';
 | 
			
		||||
import { getMemory } from '../memory';
 | 
			
		||||
 | 
			
		||||
async function getCurrentTab() {
 | 
			
		||||
@ -26,7 +26,7 @@ const Sidebar = () => {
 | 
			
		||||
    const [cookiesOnly, setCookiesOnly] = React.useState<boolean>(false);
 | 
			
		||||
    const [stolenDataView, setStolenDataView] = React.useState<boolean>(true);
 | 
			
		||||
    const [cookiesOrOriginOnly, setCookiesOrOriginOnly] = React.useState<boolean>(false);
 | 
			
		||||
    const [counter, setCounter] = useEmitter(getMemory());
 | 
			
		||||
    const [eventCounts, setEventCounts] = useEmitter(getMemory());
 | 
			
		||||
    const [marksOccurrence, setMarksOccurrence] = React.useState<boolean>(false);
 | 
			
		||||
    const [warningDataDialogAck, setWarningDataDialogAck] = React.useState<boolean>(
 | 
			
		||||
        localStorage.getItem('warningDataDialogAck') === null
 | 
			
		||||
@ -44,7 +44,7 @@ const Sidebar = () => {
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    React.useEffect(() => {
 | 
			
		||||
        const listener = async (data: any) => {
 | 
			
		||||
        const listener = async () => {
 | 
			
		||||
            console.log('tab change!');
 | 
			
		||||
            const tab = await getCurrentTab();
 | 
			
		||||
            const url = new URL(tab.url);
 | 
			
		||||
@ -66,7 +66,7 @@ const Sidebar = () => {
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return setMarksOccurrence(false);
 | 
			
		||||
    }, [counter, origin]);
 | 
			
		||||
    }, [eventCounts['*'], origin]);
 | 
			
		||||
 | 
			
		||||
    return (
 | 
			
		||||
        <div className="sidebar">
 | 
			
		||||
@ -112,7 +112,7 @@ const Sidebar = () => {
 | 
			
		||||
                    <button
 | 
			
		||||
                        onClick={() => {
 | 
			
		||||
                            getMemory().removeRequestsFor(origin);
 | 
			
		||||
                            setCounter((c) => c + 1);
 | 
			
		||||
                            getMemory().emit('change', false, origin, 'clicked trash');
 | 
			
		||||
                            setMarksOccurrence(false);
 | 
			
		||||
                        }}
 | 
			
		||||
                    >
 | 
			
		||||
@ -122,7 +122,7 @@ const Sidebar = () => {
 | 
			
		||||
                    <button
 | 
			
		||||
                        onClick={() => {
 | 
			
		||||
                            getMemory().removeCookiesFor(origin);
 | 
			
		||||
                            setCounter((c) => c + 1);
 | 
			
		||||
                            getMemory().emit('change', false, origin, 'clicked clear cookies');
 | 
			
		||||
                            setMarksOccurrence(false);
 | 
			
		||||
                        }}
 | 
			
		||||
                    >
 | 
			
		||||
@ -193,8 +193,7 @@ const Sidebar = () => {
 | 
			
		||||
                        ) : null}
 | 
			
		||||
                        <StolenData
 | 
			
		||||
                            origin={origin}
 | 
			
		||||
                            refreshToken={counter}
 | 
			
		||||
                            refresh={() => setCounter((c) => c + 1)}
 | 
			
		||||
                            eventCounts={eventCounts}
 | 
			
		||||
                            minValueLength={minValueLength}
 | 
			
		||||
                            cookiesOnly={cookiesOnly}
 | 
			
		||||
                            cookiesOrOriginOnly={cookiesOrOriginOnly}
 | 
			
		||||
 | 
			
		||||
@ -8,23 +8,14 @@ import './stolen-data-cluster.scss';
 | 
			
		||||
 | 
			
		||||
const MAX_STRING_VALUE_LENGTH = 100;
 | 
			
		||||
 | 
			
		||||
function StolenDataValue({
 | 
			
		||||
    entry,
 | 
			
		||||
    refresh,
 | 
			
		||||
}: {
 | 
			
		||||
    entry: StolenDataEntry;
 | 
			
		||||
    refresh: Function;
 | 
			
		||||
    prefixKey?: string;
 | 
			
		||||
}) {
 | 
			
		||||
function StolenDataValue({ entry }: { entry: StolenDataEntry; prefixKey?: string }) {
 | 
			
		||||
    const [version] = useEmitter(entry);
 | 
			
		||||
    let body = null;
 | 
			
		||||
    if (!entry.value) {
 | 
			
		||||
        body = <></>;
 | 
			
		||||
    } else {
 | 
			
		||||
        body = (
 | 
			
		||||
            <div data-version={version}>
 | 
			
		||||
                {maskString(entry.value, 1, MAX_STRING_VALUE_LENGTH)}
 | 
			
		||||
            </div>
 | 
			
		||||
            <div data-version={version}>{maskString(entry.value, 1, MAX_STRING_VALUE_LENGTH)}</div>
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
    return (
 | 
			
		||||
@ -32,7 +23,7 @@ function StolenDataValue({
 | 
			
		||||
            className="value"
 | 
			
		||||
            onClick={(e) => {
 | 
			
		||||
                entry.toggleMark();
 | 
			
		||||
                refresh();
 | 
			
		||||
                getMemory().emit('change', false, entry.request.shorthost, 'clicked value');
 | 
			
		||||
                e.stopPropagation();
 | 
			
		||||
            }}
 | 
			
		||||
            title={maskString(entry.value, 1, MAX_STRING_VALUE_LENGTH)}
 | 
			
		||||
@ -42,13 +33,7 @@ function StolenDataValue({
 | 
			
		||||
    );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function StolenDataRow({
 | 
			
		||||
    entry,
 | 
			
		||||
    refresh,
 | 
			
		||||
}: {
 | 
			
		||||
    entry: StolenDataEntry;
 | 
			
		||||
    refresh: Function;
 | 
			
		||||
}) {
 | 
			
		||||
function StolenDataRow({ entry }: { entry: StolenDataEntry }) {
 | 
			
		||||
    const [version] = useEmitter(entry);
 | 
			
		||||
    return (
 | 
			
		||||
        <tr
 | 
			
		||||
@ -62,7 +47,12 @@ function StolenDataRow({
 | 
			
		||||
                    checked={entry.isMarked}
 | 
			
		||||
                    onChange={() => {
 | 
			
		||||
                        entry.toggleMark();
 | 
			
		||||
                        refresh();
 | 
			
		||||
                        getMemory().emit(
 | 
			
		||||
                            'change',
 | 
			
		||||
                            false,
 | 
			
		||||
                            entry.request.shorthost,
 | 
			
		||||
                            'clicked checkbox'
 | 
			
		||||
                        );
 | 
			
		||||
                    }}
 | 
			
		||||
                />
 | 
			
		||||
            </td>
 | 
			
		||||
@ -70,7 +60,12 @@ function StolenDataRow({
 | 
			
		||||
                title={`Nazwa: ${entry.name}\nŹródło: ${entry.source}`}
 | 
			
		||||
                onClick={() => {
 | 
			
		||||
                    entry.toggleMark();
 | 
			
		||||
                    refresh();
 | 
			
		||||
                    getMemory().emit(
 | 
			
		||||
                        'change',
 | 
			
		||||
                        false,
 | 
			
		||||
                        entry.request.shorthost,
 | 
			
		||||
                        'Clicked entry name'
 | 
			
		||||
                    );
 | 
			
		||||
                }}
 | 
			
		||||
            >
 | 
			
		||||
                {entry.name}
 | 
			
		||||
@ -86,10 +81,7 @@ function StolenDataRow({
 | 
			
		||||
                        />
 | 
			
		||||
                    </span>
 | 
			
		||||
                ) : entry.request.hasCookie() ? (
 | 
			
		||||
                    <span
 | 
			
		||||
                        title="Wysłane w zapytaniu opatrzonym Cookies"
 | 
			
		||||
                        style={{ opacity: 0.25 }}
 | 
			
		||||
                    >
 | 
			
		||||
                    <span title="Wysłane w zapytaniu opatrzonym Cookies" style={{ opacity: 0.25 }}>
 | 
			
		||||
                        <img
 | 
			
		||||
                            src="/assets/icons/cookie.svg"
 | 
			
		||||
                            height={16}
 | 
			
		||||
@ -121,7 +113,7 @@ function StolenDataRow({
 | 
			
		||||
                    </span>
 | 
			
		||||
                ) : null}
 | 
			
		||||
            </td>
 | 
			
		||||
            <StolenDataValue refresh={refresh} entry={entry} />
 | 
			
		||||
            <StolenDataValue entry={entry} />
 | 
			
		||||
        </tr>
 | 
			
		||||
    );
 | 
			
		||||
}
 | 
			
		||||
@ -130,21 +122,22 @@ export default function StolenDataCluster({
 | 
			
		||||
    origin,
 | 
			
		||||
    shorthost,
 | 
			
		||||
    minValueLength,
 | 
			
		||||
    refresh,
 | 
			
		||||
    cookiesOnly,
 | 
			
		||||
    refreshToken,
 | 
			
		||||
    cookiesOrOriginOnly,
 | 
			
		||||
}: {
 | 
			
		||||
    origin: string;
 | 
			
		||||
    shorthost: string;
 | 
			
		||||
    refreshToken: number;
 | 
			
		||||
    minValueLength: number;
 | 
			
		||||
    refresh: Function;
 | 
			
		||||
    cookiesOnly: boolean;
 | 
			
		||||
    cookiesOrOriginOnly: boolean;
 | 
			
		||||
}) {
 | 
			
		||||
    const cluster = getMemory().getClustersForOrigin(origin)[shorthost];
 | 
			
		||||
    const fullHosts = cluster.getFullHosts();
 | 
			
		||||
 | 
			
		||||
    /* console.log('Stolen data cluster!', shorthost, refreshToken); */
 | 
			
		||||
 | 
			
		||||
    return (
 | 
			
		||||
        <div className="stolen-data-cluster-container">
 | 
			
		||||
            <header className="domains-container">
 | 
			
		||||
@ -153,13 +146,8 @@ export default function StolenDataCluster({
 | 
			
		||||
                </a>
 | 
			
		||||
                <div className="subdomains-container">
 | 
			
		||||
                    {fullHosts.map((host, index) => (
 | 
			
		||||
                        <a
 | 
			
		||||
                            className="subdomain"
 | 
			
		||||
                            key={host}
 | 
			
		||||
                            href={`https://${host}`}
 | 
			
		||||
                        >
 | 
			
		||||
                            {host}{' '}
 | 
			
		||||
                            {`${fullHosts.length - 1 !== index ? '· ' : ''}`}
 | 
			
		||||
                        <a className="subdomain" key={host} href={`https://${host}`}>
 | 
			
		||||
                            {host} {`${fullHosts.length - 1 !== index ? '· ' : ''}`}
 | 
			
		||||
                        </a>
 | 
			
		||||
                    ))}
 | 
			
		||||
                </div>
 | 
			
		||||
@ -182,7 +170,6 @@ export default function StolenDataCluster({
 | 
			
		||||
                            })
 | 
			
		||||
                            .map((entry) => (
 | 
			
		||||
                                <StolenDataRow
 | 
			
		||||
                                    refresh={refresh}
 | 
			
		||||
                                    {...{
 | 
			
		||||
                                        entry,
 | 
			
		||||
                                        key: entry.id,
 | 
			
		||||
 | 
			
		||||
@ -1,23 +1,19 @@
 | 
			
		||||
import React from 'react';
 | 
			
		||||
import { getMemory } from '../memory';
 | 
			
		||||
import { RequestCluster } from '../request-cluster';
 | 
			
		||||
 | 
			
		||||
import StolenDataCluster from './stolen-data-cluster';
 | 
			
		||||
import { getshorthost } from '../util';
 | 
			
		||||
import { getMemory } from '../memory';
 | 
			
		||||
 | 
			
		||||
import './stolen-data.scss';
 | 
			
		||||
 | 
			
		||||
export function StolenData({
 | 
			
		||||
    origin,
 | 
			
		||||
    minValueLength,
 | 
			
		||||
    refreshToken,
 | 
			
		||||
    refresh,
 | 
			
		||||
    eventCounts,
 | 
			
		||||
    cookiesOnly,
 | 
			
		||||
    cookiesOrOriginOnly,
 | 
			
		||||
}: {
 | 
			
		||||
    origin: string;
 | 
			
		||||
    refreshToken: number;
 | 
			
		||||
    refresh: () => void;
 | 
			
		||||
    eventCounts: Record<string, number>;
 | 
			
		||||
    minValueLength: number;
 | 
			
		||||
    cookiesOnly: boolean;
 | 
			
		||||
    cookiesOrOriginOnly: boolean;
 | 
			
		||||
@ -33,10 +29,7 @@ export function StolenData({
 | 
			
		||||
        .sort(RequestCluster.sortCompare)
 | 
			
		||||
        .filter((cluster) => !cookiesOnly || cluster.hasCookies())
 | 
			
		||||
        .filter(
 | 
			
		||||
            (cluster) =>
 | 
			
		||||
                !cookiesOrOriginOnly ||
 | 
			
		||||
                cluster.hasCookies() ||
 | 
			
		||||
                cluster.exposesOrigin()
 | 
			
		||||
            (cluster) => !cookiesOrOriginOnly || cluster.hasCookies() || cluster.exposesOrigin()
 | 
			
		||||
        );
 | 
			
		||||
    return (
 | 
			
		||||
        <div className="stolen-data-container">
 | 
			
		||||
@ -48,8 +41,7 @@ export function StolenData({
 | 
			
		||||
                        origin={origin}
 | 
			
		||||
                        shorthost={cluster.id}
 | 
			
		||||
                        key={cluster.id + origin}
 | 
			
		||||
                        refresh={refresh}
 | 
			
		||||
                        refreshToken={refreshToken}
 | 
			
		||||
                        refreshToken={eventCounts[cluster.id]}
 | 
			
		||||
                        minValueLength={minValueLength}
 | 
			
		||||
                        cookiesOnly={cookiesOnly}
 | 
			
		||||
                        cookiesOrOriginOnly={cookiesOrOriginOnly}
 | 
			
		||||
 | 
			
		||||
@ -12,12 +12,7 @@ import {
 | 
			
		||||
    safeDecodeURIComponent,
 | 
			
		||||
} from './util';
 | 
			
		||||
 | 
			
		||||
export type Sources =
 | 
			
		||||
    | 'cookie'
 | 
			
		||||
    | 'pathname'
 | 
			
		||||
    | 'queryparams'
 | 
			
		||||
    | 'header'
 | 
			
		||||
    | 'request_body';
 | 
			
		||||
export type Sources = 'cookie' | 'pathname' | 'queryparams' | 'header' | 'request_body';
 | 
			
		||||
 | 
			
		||||
export const Classifications = <const>{
 | 
			
		||||
    id: 'Identyfikator internetowy',
 | 
			
		||||
@ -123,10 +118,7 @@ export class StolenDataEntry extends EventEmitter {
 | 
			
		||||
                    }
 | 
			
		||||
                ).entries()
 | 
			
		||||
            );
 | 
			
		||||
            if (
 | 
			
		||||
                typeof hash !== 'object' &&
 | 
			
		||||
                Object.keys(searchParams).length === 0
 | 
			
		||||
            ) {
 | 
			
		||||
            if (typeof hash !== 'object' && Object.keys(searchParams).length === 0) {
 | 
			
		||||
                return value; // just a string;
 | 
			
		||||
            }
 | 
			
		||||
            const object = {
 | 
			
		||||
@ -134,11 +126,7 @@ export class StolenDataEntry extends EventEmitter {
 | 
			
		||||
                host: url.host,
 | 
			
		||||
                path: url.pathname,
 | 
			
		||||
                searchParams,
 | 
			
		||||
                ...(hash === ''
 | 
			
		||||
                    ? {}
 | 
			
		||||
                    : typeof hash === 'string'
 | 
			
		||||
                    ? { hash }
 | 
			
		||||
                    : hash),
 | 
			
		||||
                ...(hash === '' ? {} : typeof hash === 'string' ? { hash } : hash),
 | 
			
		||||
            };
 | 
			
		||||
            return object;
 | 
			
		||||
        } else if (value === null) {
 | 
			
		||||
@ -148,16 +136,12 @@ export class StolenDataEntry extends EventEmitter {
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    getParsedValue(
 | 
			
		||||
        key_path: string
 | 
			
		||||
    ): string | Record<string | symbol, unknown> {
 | 
			
		||||
    getParsedValue(key_path: string): string | Record<string | symbol, unknown> {
 | 
			
		||||
        let object = StolenDataEntry.parseValue(this.value);
 | 
			
		||||
        for (const key of key_path.split('.')) {
 | 
			
		||||
            if (key === '') continue;
 | 
			
		||||
            if (typeof key === 'string') {
 | 
			
		||||
                throw new Error(
 | 
			
		||||
                    'something went wrong when parsing ' + key_path
 | 
			
		||||
                );
 | 
			
		||||
                throw new Error('something went wrong when parsing ' + key_path);
 | 
			
		||||
            }
 | 
			
		||||
            object = StolenDataEntry.parseValue(object[key]);
 | 
			
		||||
        }
 | 
			
		||||
@ -176,7 +160,7 @@ export class StolenDataEntry extends EventEmitter {
 | 
			
		||||
        const had_been_marked_before = this.marked;
 | 
			
		||||
        this.marked = false;
 | 
			
		||||
        if (had_been_marked_before) {
 | 
			
		||||
            this.emit('change');
 | 
			
		||||
            this.emit('change', this.request.origin);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -199,9 +183,7 @@ export class StolenDataEntry extends EventEmitter {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    isRelatedToID() {
 | 
			
		||||
        return this.request.stolenData.some(
 | 
			
		||||
            (entry) => entry.classification == 'id'
 | 
			
		||||
        );
 | 
			
		||||
        return this.request.stolenData.some((entry) => entry.classification == 'id');
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    matchesHAREntry(har: HAREntry): boolean {
 | 
			
		||||
@ -216,10 +198,7 @@ export class StolenDataEntry extends EventEmitter {
 | 
			
		||||
                : value.toString();
 | 
			
		||||
        if (typeof value !== 'object' && this.classification == 'id') {
 | 
			
		||||
            return maskString(value, 1 / 3, ID_PREVIEW_MAX_LENGTH);
 | 
			
		||||
        } else if (
 | 
			
		||||
            typeof value === 'object' &&
 | 
			
		||||
            value[Symbol.for('originalString')]
 | 
			
		||||
        ) {
 | 
			
		||||
        } else if (typeof value === 'object' && value[Symbol.for('originalString')]) {
 | 
			
		||||
            return value[Symbol.for('originalString')] as string;
 | 
			
		||||
        } else {
 | 
			
		||||
            return str;
 | 
			
		||||
@ -267,8 +246,8 @@ export class StolenDataEntry extends EventEmitter {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    exposesHost() {
 | 
			
		||||
        return [this.value, safeDecodeURIComponent(this.value)].some(
 | 
			
		||||
            (haystack) => haystack.includes(getshorthost(this.request.origin))
 | 
			
		||||
        return [this.value, safeDecodeURIComponent(this.value)].some((haystack) =>
 | 
			
		||||
            haystack.includes(getshorthost(this.request.origin))
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										26
									
								
								util.ts
									
									
									
									
									
								
							
							
						
						
									
										26
									
								
								util.ts
									
									
									
									
									
								
							@ -47,18 +47,34 @@ export function getshorthost(host: string) {
 | 
			
		||||
 | 
			
		||||
export function useEmitter(
 | 
			
		||||
    e: EventEmitter
 | 
			
		||||
): [number, React.Dispatch<React.SetStateAction<number>>] {
 | 
			
		||||
    const [counter, setCounter] = React.useState<number>(0);
 | 
			
		||||
): [
 | 
			
		||||
    Record<string, number | undefined>,
 | 
			
		||||
    React.Dispatch<React.SetStateAction<Record<string, number | undefined>>>
 | 
			
		||||
] {
 | 
			
		||||
    const [eventCounts, setEventCounts] = React.useState<Record<string, number | undefined>>({
 | 
			
		||||
        '*': 0,
 | 
			
		||||
    });
 | 
			
		||||
    React.useEffect(() => {
 | 
			
		||||
        const callback = () => {
 | 
			
		||||
            setCounter((counter) => counter + 1);
 | 
			
		||||
        const callback = (eventSubtype: string) => {
 | 
			
		||||
            setEventCounts((eventCounts) => {
 | 
			
		||||
                console.log({
 | 
			
		||||
                    ...eventCounts,
 | 
			
		||||
                    ...{ [eventSubtype]: (eventCounts[eventSubtype] || 0) + 1 },
 | 
			
		||||
                    ...{ '*': (eventCounts['*'] === undefined ? 0 : eventCounts['*']) + 1 },
 | 
			
		||||
                });
 | 
			
		||||
                return {
 | 
			
		||||
                    ...eventCounts,
 | 
			
		||||
                    ...{ [eventSubtype]: (eventCounts[eventSubtype] || 0) + 1 },
 | 
			
		||||
                    ...{ '*': (eventCounts['*'] === undefined ? 0 : eventCounts['*']) + 1 },
 | 
			
		||||
                };
 | 
			
		||||
            });
 | 
			
		||||
        };
 | 
			
		||||
        e.on('change', callback);
 | 
			
		||||
        return () => {
 | 
			
		||||
            e.removeListener('change', callback);
 | 
			
		||||
        };
 | 
			
		||||
    }, []);
 | 
			
		||||
    return [counter, setCounter];
 | 
			
		||||
    return [eventCounts, setEventCounts];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export function parseCookie(cookie: string): Record<string, string> {
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user