diff --git a/src/event-source.ts b/src/event-source.ts index ef384da..53029f1 100644 --- a/src/event-source.ts +++ b/src/event-source.ts @@ -3,14 +3,17 @@ import {Status, PartialStatus} from './state/status'; import {empty} from 'rxjs/observable/empty'; import {of} from 'rxjs/observable/of'; import {IncomingMessage} from './state/message'; -import {Channel} from './state/channel'; -import {InstantMessage} from './state/ims'; +import {Channel, isChannel} from './state/channel'; +import {InstantMessage, isInstantMessage} from './state/ims'; import {findOne} from './util/map' type O = Observable; +type BothPS = PartialStatus | IncomingMessage>; +type ChanPS = PartialStatus>; +type IMPS = PartialStatus>; export class EventSource { - private _message$: O | IncomingMessage>>; + private _message$: O; constructor(_status$: Observable) { const [, message$] = _status$.partition(status => typeof status.event === 'string'); @@ -19,7 +22,7 @@ export class EventSource { } selectByChannelName(name: string): Observable> { - return this._message$.mergeMap(({event, channels}) => { + return this._message$.filter((ps: BothPS): ps is ChanPS => isChannel(ps.event.channel)).mergeMap(({event, channels}) => { const channel = findOne(channel => name === channel.name, channels); if (channel && !event.user.is_bot) { return of(event); @@ -30,7 +33,7 @@ export class EventSource { } selectByUserName(name: string): Observable> { - return this._message$.mergeMap(({users, event, ims}) => { + return this._message$.filter((ps: BothPS): ps is IMPS => isInstantMessage(ps.event.channel)).mergeMap(({users, event, ims}) => { const user = findOne(user => name === user.name, users); if (!user) { return empty(); diff --git a/src/state/channel.ts b/src/state/channel.ts index 2fc237d..9c3223d 100644 --- a/src/state/channel.ts +++ b/src/state/channel.ts @@ -1,4 +1,4 @@ -import {where, is, pick, assoc} from 'ramda'; +import {pick, assoc} from 'ramda'; export type Channel = { id: string; @@ -9,14 +9,16 @@ export type Channel = { creator: string; } -export const isChannel = where({ - id: is(String), - name: is(String), - is_member: is(Boolean), - is_archived: is(Boolean), - created: is(Number), - creator: is(String) -}); +export function isChannel(x: any): x is Channel { + return typeof x === 'object' && + x !== null && + typeof x.id === 'string' && + typeof x.name === 'string' && + typeof x.is_member === 'boolean' && + typeof x.is_archived === 'boolean' && + typeof x.created === 'number' && + typeof x.creator === 'string'; +}; const channelKeyList: Array = [ 'id', diff --git a/src/state/ims.ts b/src/state/ims.ts index 2b9f848..0df283b 100644 --- a/src/state/ims.ts +++ b/src/state/ims.ts @@ -1,4 +1,4 @@ -import {where, is, pick} from 'ramda'; +import {pick} from 'ramda'; export type InstantMessage = { id: string; @@ -7,12 +7,14 @@ export type InstantMessage = { created: number; } -export const isInstantMessage = where({ - id: is(String), - user: is(String), - is_open: is(Boolean), - created: is(Number) -}); +export function isInstantMessage(x: any): x is InstantMessage { + return typeof x === 'object' && + x !== null && + typeof x.id === 'string' && + typeof x.user === 'string' && + typeof x.is_open === 'boolean' && + typeof x.created === 'number'; +}; const imKeyList: Array = [ 'id', diff --git a/src/state/status.ts b/src/state/status.ts index b1f8e35..5998f43 100644 --- a/src/state/status.ts +++ b/src/state/status.ts @@ -53,7 +53,7 @@ export function updateChannel(key: string, project: (x: Channel) => Channel): Ac } export function deleteChannel(key: string): Action { - return curryDel(key); + return over(lensProp('channels'), curryDel(key)); } export function updateUser(key: string, project: (x: User) => User): Action {