Added types to Emitters (#20819)

pull/20597/head^2
Guilherme Gazzo 5 years ago committed by GitHub
parent 9ad2335c66
commit 93869f475a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 8
      client/contexts/AuthorizationContext.ts
  2. 5
      client/lib/banners.ts
  3. 4
      client/lib/createValueSubscription.ts
  4. 42
      client/lib/presence.ts
  5. 1
      client/views/room/contexts/RoomContext.ts
  6. 8
      client/views/room/lib/Toolbox/ToolboxContext.tsx
  7. 18
      client/views/room/lib/Toolbox/generator.tsx
  8. 4
      client/views/room/lib/Toolbox/index.tsx
  9. 5
      client/views/room/providers/ToolboxProvider.tsx
  10. 55
      package-lock.json
  11. 6
      package.json

@ -1,13 +1,15 @@
import { createContext, useContext, useMemo, useCallback } from 'react';
import { useSubscription, Subscription, Unsubscribe } from 'use-subscription';
import { Emitter, Handler } from '@rocket.chat/emitter';
import { Emitter } from '@rocket.chat/emitter';
import { IRole } from '../../definition/IUser';
type IRoles = { [_id: string]: IRole }
export class RoleStore extends Emitter {
export class RoleStore extends Emitter<{
change: IRoles;
}> {
roles: IRoles = {};
}
@ -91,7 +93,7 @@ export const useRolesDescription = (): (ids: Array<string>) => [string] => {
const subscription = useMemo(
() => ({
getCurrentValue: (): IRoles => roleStore.roles,
subscribe: (callback: Handler): () => void => {
subscribe: (callback: () => void): () => void => {
roleStore.on('change', callback);
return (): void => {
roleStore.off('change', callback);

@ -22,7 +22,10 @@ type BannerPayload = LegacyBannerPayload | UiKitBannerPayload;
export const isLegacyPayload = (payload: BannerPayload): payload is LegacyBannerPayload => !('blocks' in payload);
const queue: BannerPayload[] = [];
const emitter = new Emitter();
const emitter = new Emitter<{
update: undefined;
'update-first': undefined;
}>();
export const firstSubscription: Subscription<BannerPayload | null> = {
getCurrentValue: () => queue[0] ?? null,

@ -7,7 +7,9 @@ type ValueSubscription<T> = Subscription<T> & {
export const createValueSubscription = <T>(initialValue: T): ValueSubscription<T> => {
let value: T = initialValue;
const emitter = new Emitter();
const emitter = new Emitter<{
update: undefined;
}>();
return {
getCurrentValue: (): T => value,

@ -1,9 +1,22 @@
import { Emitter, EventType, Handler } from '@rocket.chat/emitter';
import { Emitter, EventHandlerOf } from '@rocket.chat/emitter';
import { APIClient } from '../../app/utils/client';
import { IUser } from '../../definition/IUser';
import { USER_STATUS } from '../../definition/UserStatus';
const emitter = new Emitter();
type InternalEvents = {
remove: IUser['_id'];
reset: undefined;
restart: undefined;
};
type ExternalEvents = {
[key: string]: UserPresence | undefined;
};
type Events = InternalEvents & ExternalEvents;
const emitter = new Emitter<Events>();
const store = new Map<string, UserPresence>();
@ -14,7 +27,7 @@ type UsersPresencePayload = {
full: boolean;
};
const isUid = (eventType: EventType): eventType is UserPresence['_id'] =>
const isUid = (eventType: keyof Events): eventType is UserPresence['_id'] =>
Boolean(eventType) && typeof eventType === 'string' && !['reset', 'restart', 'remove'].includes(eventType);
const uids = new Set<UserPresence['_id']>();
@ -41,7 +54,7 @@ const getPresence = ((): ((uid: UserPresence['_id']) => void) => {
});
currentUids.forEach((uid) => {
emitter.emit(uid, { _id: uid, status: 'offline' });
emitter.emit(uid, { _id: uid, status: USER_STATUS.OFFLINE });
});
currentUids.clear();
@ -68,6 +81,10 @@ const getPresence = ((): ((uid: UserPresence['_id']) => void) => {
emitter.on('reset', () => {
store.clear();
emitter.events()
.filter(isUid).forEach((uid) => {
emitter.emit(uid, undefined);
});
emitter.once('restart', () => {
emitter.events()
.filter(isUid)
@ -78,36 +95,35 @@ const getPresence = ((): ((uid: UserPresence['_id']) => void) => {
return get;
})();
const update: Handler<UserPresence> = (update) => {
const update: EventHandlerOf<ExternalEvents, string> = (update) => {
if (update?._id) {
store.set(update._id, update);
uids.delete(update._id);
}
};
const listen = (uid: UserPresence['_id'], handler: Handler<UserPresence>): void => {
const listen = (uid: UserPresence['_id'], handler: EventHandlerOf<ExternalEvents, UserPresence['_id']> | (() => void)): void => {
emitter.on(uid, update);
emitter.on(uid, handler);
emitter.on('reset', handler);
if (store.has(uid)) {
return handler(store.get(uid));
const user = store.has(uid) && store.get(uid);
if (user) {
return handler(user);
}
getPresence(uid);
};
const stop = (uid: UserPresence['_id'], handler: Handler<UserPresence>): void => {
const stop = (uid: UserPresence['_id'], handler: EventHandlerOf<ExternalEvents, UserPresence['_id']> | (() => void)): void => {
setTimeout(() => {
emitter.off(uid, handler);
emitter.off(uid, update);
emitter.off('reset', handler);
emitter.emit('remove', uid);
}, 5000);
};
const reset = (): void => {
emitter.emit('reset', {});
emitter.emit('reset');
store.clear();
};
@ -126,7 +142,7 @@ const notify = (update: UserPresence): void => {
};
const get = async (uid: UserPresence['_id']): Promise<UserPresence | undefined> => new Promise((resolve) => {
const callback: Handler<UserPresence> = (args): void => {
const callback: EventHandlerOf<ExternalEvents, UserPresence['_id']> = (args): void => {
resolve(args);
stop(uid, callback);
};

@ -1,5 +1,4 @@
import { createContext } from 'react';
// import { Handler } from '@rocket.chat/emitter';
import { IRoom } from '../../../../definition/IRoom';

@ -1,13 +1,15 @@
import { createContext } from 'react';
import { Handler } from '@rocket.chat/emitter';
import { EventHandlerOf } from '@rocket.chat/emitter';
import { actions, listen, ToolboxActionConfig, ToolboxAction } from '.';
import { actions, listen, ToolboxActionConfig, ToolboxAction, Events } from '.';
import './defaultActions';
export type ToolboxEventHandler = (handler: EventHandlerOf<Events, 'change'>) => Function;
export type ChannelContextValue = {
actions: Map<ToolboxActionConfig['id'], ToolboxAction>;
listen: (handler: Handler) => Function;
listen: ToolboxEventHandler;
tabBar?: any;
context?: any;
open: Function;

@ -1,18 +1,22 @@
import { Emitter, Handler } from '@rocket.chat/emitter';
import { Emitter, EventHandlerOf } from '@rocket.chat/emitter';
export type Store<T> = Map<string, T>;
export const generator = function generator<T>(name?: string):
{
export type Events<T> = {
change: Store<T>;
};
export const generator = function generator<T>(name?: string): ({
store: Store<T>;
add: (id: string, action: T) => Store<T>;
remove: (id: string) => boolean;
listen: (handler: Handler) => Function;
listen: (handler: EventHandlerOf<Events<T>, 'change'>) => Function;
name: string | undefined;
} {
}) {
const store: Store<T> = new Map();
const emitter = new Emitter();
const emitter = new Emitter<Events<T>>();
const add = (id: string, action: T): Store<T> => {
store.set(id, action);
@ -26,7 +30,7 @@ export const generator = function generator<T>(name?: string):
return result;
};
const listen = (handler: Handler): Function => emitter.on('change', handler);
const listen = (handler: EventHandlerOf<Events<T>, 'change'>): Function => emitter.on('change', handler);
return Object.freeze({
store,

@ -2,7 +2,7 @@ import { FC, LazyExoticComponent, ReactNode, MouseEvent } from 'react';
import { BoxProps, OptionProps } from '@rocket.chat/fuselage';
import { IRoom } from '../../../../../definition/IRoom';
import { generator } from './generator';
import { generator, Events as GeneratorEvents } from './generator';
type ToolboxHook = ({ room }: { room: IRoom }) => ToolboxActionConfig | null
@ -38,4 +38,6 @@ export type ToolboxAction = ToolboxHook | ToolboxActionConfig;
const { listen, add: addAction, remove: deleteAction, store: actions } = generator<ToolboxAction>();
export type Events = GeneratorEvents<ToolboxAction>;
export { listen, addAction, deleteAction, actions };

@ -1,8 +1,7 @@
import React, { ReactNode, useContext, useMemo, useState, useCallback, useLayoutEffect } from 'react';
import { useDebouncedState, useMutableCallback, useSafely } from '@rocket.chat/fuselage-hooks';
import { Handler } from '@rocket.chat/emitter';
import { ToolboxContext } from '../lib/Toolbox/ToolboxContext';
import { ToolboxContext, ToolboxEventHandler } from '../lib/Toolbox/ToolboxContext';
import { ToolboxAction, ToolboxActionConfig } from '../lib/Toolbox/index';
import { IRoom } from '../../../../definition/IRoom';
import { useCurrentRoute, useRoute } from '../../../contexts/RouterContext';
@ -37,7 +36,7 @@ const VirtualAction = React.memo(({ handleChange, room, action, id }: { id: stri
return null;
});
const useToolboxActions = (room: IRoom): { listen: (handler: Handler<any>) => Function; actions: Array<[string, ToolboxAction]> } => {
const useToolboxActions = (room: IRoom): { listen: ToolboxEventHandler; actions: Array<[string, ToolboxAction]> } => {
const { listen, actions } = useContext(ToolboxContext);
const [state, setState] = useState<Array<[string, ToolboxAction]>>(Array.from(actions.entries()));

55
package-lock.json generated

@ -5920,11 +5920,12 @@
}
},
"@rocket.chat/css-in-js": {
"version": "0.6.3-dev.178",
"resolved": "https://registry.npmjs.org/@rocket.chat/css-in-js/-/css-in-js-0.6.3-dev.178.tgz",
"integrity": "sha512-4cnyJx8TbZ8zKWfl1gYGfWZBtf9RWWbaDQpKClkN5myCAXE07QG/tP0z/A0nnGCiU0qSZDrsl/wcdxYwG47tEA==",
"version": "0.6.3-dev.180",
"resolved": "https://registry.npmjs.org/@rocket.chat/css-in-js/-/css-in-js-0.6.3-dev.180.tgz",
"integrity": "sha512-j34Yv+O7J0h7vG0wNe3zjteaCz3ZNJ4fyNldte5+ByiqS/LanQpQYA08+Srvtb2LCI177E9pJHQ4o0UBxIhPUg==",
"requires": {
"@emotion/hash": "^0.8.0",
"@rocket.chat/memo": "^0.6.3-dev.180+2425c045",
"stylis": "^4.0.6"
},
"dependencies": {
@ -5936,9 +5937,9 @@
}
},
"@rocket.chat/emitter": {
"version": "0.6.3-dev.178",
"resolved": "https://registry.npmjs.org/@rocket.chat/emitter/-/emitter-0.6.3-dev.178.tgz",
"integrity": "sha512-wgmr7Yg6Hx7hPVpFhlOoQha8I/mLpSUb273y1MYQOItBBF58VOYwdC2r6gvBZRRbziGOZL95eOmP1N6odP4RCg=="
"version": "0.6.3-dev.185",
"resolved": "https://registry.npmjs.org/@rocket.chat/emitter/-/emitter-0.6.3-dev.185.tgz",
"integrity": "sha512-23TNzv+sS8cDT1MQl402QVsI4OEcnChtOhru6TyQqCndfpvBBObmiATgxFnClA6HQA5pXt8qMGxUl/UXDXKs0A=="
},
"@rocket.chat/eslint-config": {
"version": "0.3.0",
@ -6012,9 +6013,9 @@
"integrity": "sha512-gVzQHhUsZSLbIkwGi8f1KpsTepkmtwHs7hl1gGr0HrnI4eYhBWpMOEjdiH3czhPuoF/O4C8QjdpDrktIuwkVNQ=="
},
"@rocket.chat/fuselage-ui-kit": {
"version": "0.6.3-dev.179",
"resolved": "https://registry.npmjs.org/@rocket.chat/fuselage-ui-kit/-/fuselage-ui-kit-0.6.3-dev.179.tgz",
"integrity": "sha512-xQpxwvpiZwTnANdNkaxRASsCZuP0yftHtz/Lq/K0CW9VQc3Ml+mkOp+FV1XImZlyv31bwfxW78SsdaQNmDkTAQ==",
"version": "0.6.3-dev.184",
"resolved": "https://registry.npmjs.org/@rocket.chat/fuselage-ui-kit/-/fuselage-ui-kit-0.6.3-dev.184.tgz",
"integrity": "sha512-xO1FuY9bCKTOKOANbRi189Uq0j6+pVSKaV3E5C3TYvWuMhwE2Lfq4gbiH/uEn5cnrVdR1HOJaaskCxkraGqTVg==",
"requires": {
"@rocket.chat/fuselage-polyfills": "^0.21.0"
},
@ -19928,7 +19929,7 @@
},
"chownr": {
"version": "1.1.1",
"resolved": "",
"resolved": false,
"integrity": "sha512-j38EvO5+LHX84jlo6h4UzmOwi0UgW61WRyPtJz4qaadK5eY3BTS5TY/S1Stc3Uk2lIM6TPevAlULiEJwie860g==",
"dev": true,
"optional": true
@ -19963,7 +19964,7 @@
},
"debug": {
"version": "4.1.1",
"resolved": "",
"resolved": false,
"integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
"dev": true,
"optional": true,
@ -19994,7 +19995,7 @@
},
"fs-minipass": {
"version": "1.2.5",
"resolved": "",
"resolved": false,
"integrity": "sha512-JhBl0skXjUPCFH7x6x61gQxrKyXsxB5gcgePLZCwfyCGGsTISMoIeObbrvVeP6Xmyaudw4TT43qV2Gz+iyd2oQ==",
"dev": true,
"optional": true,
@ -20028,7 +20029,7 @@
},
"glob": {
"version": "7.1.3",
"resolved": "",
"resolved": false,
"integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==",
"dev": true,
"optional": true,
@ -20060,7 +20061,7 @@
},
"ignore-walk": {
"version": "3.0.1",
"resolved": "",
"resolved": false,
"integrity": "sha512-DTVlMx3IYPe0/JJcYP7Gxg7ttZZu3IInhuEhbchuqneY9wWe5Ojy2mXLBaQFUQmo0AW2r3qG7m1mg86js+gnlQ==",
"dev": true,
"optional": true,
@ -20081,7 +20082,7 @@
},
"inherits": {
"version": "2.0.3",
"resolved": "",
"resolved": false,
"integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=",
"dev": true,
"optional": true
@ -20129,7 +20130,7 @@
},
"minipass": {
"version": "2.3.5",
"resolved": "",
"resolved": false,
"integrity": "sha512-Gi1W4k059gyRbyVUZQ4mEqLm0YIUiGYfvxhF6SIlk3ui1WVxMTGfGdQ2SInh3PDrRTVvPKgULkpJtT4RH10+VA==",
"dev": true,
"optional": true,
@ -20140,7 +20141,7 @@
},
"minizlib": {
"version": "1.2.1",
"resolved": "",
"resolved": false,
"integrity": "sha512-7+4oTUOWKg7AuL3vloEWekXY2/D20cevzsrNT2kGWm+39J9hGTCBv8VI5Pm5lXZ/o3/mdR4f8rflAPhnQb8mPA==",
"dev": true,
"optional": true,
@ -20160,7 +20161,7 @@
},
"ms": {
"version": "2.1.1",
"resolved": "",
"resolved": false,
"integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==",
"dev": true,
"optional": true
@ -20174,7 +20175,7 @@
},
"needle": {
"version": "2.3.0",
"resolved": "",
"resolved": false,
"integrity": "sha512-QBZu7aAFR0522EyaXZM0FZ9GLpq6lvQ3uq8gteiDUp7wKdy0lSd2hPlgFwVuW1CBkfEs9PfDQsQzZghLs/psdg==",
"dev": true,
"optional": true,
@ -20186,7 +20187,7 @@
},
"node-pre-gyp": {
"version": "0.12.0",
"resolved": "",
"resolved": false,
"integrity": "sha512-4KghwV8vH5k+g2ylT+sLTjy5wmUOb9vPhnM8NHvRf9dHmnW/CndrFXy2aRPaPST6dugXSdHXfeaHQm77PIz/1A==",
"dev": true,
"optional": true,
@ -20216,14 +20217,14 @@
},
"npm-bundled": {
"version": "1.0.6",
"resolved": "",
"resolved": false,
"integrity": "sha512-8/JCaftHwbd//k6y2rEWp6k1wxVfpFzB6t1p825+cUb7Ym2XQfhwIC5KwhrvzZRJu+LtDE585zVaS32+CGtf0g==",
"dev": true,
"optional": true
},
"npm-packlist": {
"version": "1.4.1",
"resolved": "",
"resolved": false,
"integrity": "sha512-+TcdO7HJJ8peiiYhvPxsEDhF3PJFGUGRcFsGve3vxvxdcpO2Z4Z7rkosRM0kWj6LfbK/P0gu3dzk5RU1ffvFcw==",
"dev": true,
"optional": true,
@ -20303,7 +20304,7 @@
},
"process-nextick-args": {
"version": "2.0.0",
"resolved": "",
"resolved": false,
"integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==",
"dev": true,
"optional": true
@ -20348,7 +20349,7 @@
},
"rimraf": {
"version": "2.6.3",
"resolved": "",
"resolved": false,
"integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==",
"dev": true,
"optional": true,
@ -20379,7 +20380,7 @@
},
"semver": {
"version": "5.7.0",
"resolved": "",
"resolved": false,
"integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==",
"dev": true,
"optional": true
@ -20439,7 +20440,7 @@
},
"tar": {
"version": "4.4.8",
"resolved": "",
"resolved": false,
"integrity": "sha512-LzHF64s5chPQQS0IYBn9IN5h3i98c12bo4NCO7e0sGM2llXQ3p2FGC5sdENN4cTW48O915Sh+x+EXx7XW96xYQ==",
"dev": true,
"optional": true,
@ -20479,7 +20480,7 @@
},
"yallist": {
"version": "3.0.3",
"resolved": "",
"resolved": false,
"integrity": "sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A==",
"dev": true,
"optional": true

@ -135,13 +135,13 @@
"@nivo/line": "^0.61.1",
"@nivo/pie": "^0.61.1",
"@rocket.chat/apps-engine": "1.23.0-alpha.4655",
"@rocket.chat/css-in-js": "^0.6.3-dev.178",
"@rocket.chat/emitter": "^0.6.3-dev.178",
"@rocket.chat/css-in-js": "^0.6.3-dev.180",
"@rocket.chat/emitter": "^0.6.3-dev.185",
"@rocket.chat/fuselage": "^0.6.3-dev.188",
"@rocket.chat/fuselage-hooks": "^0.6.3-dev.178",
"@rocket.chat/fuselage-polyfills": "^0.6.3-dev.181",
"@rocket.chat/fuselage-tokens": "^0.21.0",
"@rocket.chat/fuselage-ui-kit": "^0.6.3-dev.179",
"@rocket.chat/fuselage-ui-kit": "^0.6.3-dev.184",
"@rocket.chat/icons": "^0.6.3-dev.179",
"@rocket.chat/mp3-encoder": "^0.6.3-dev.178",
"@rocket.chat/ui-kit": "^0.6.3-dev.178",

Loading…
Cancel
Save