Skip to content

Commit

Permalink
feat(*): add the sseHub() middleware and the Hub class
Browse files Browse the repository at this point in the history
  • Loading branch information
toverux committed May 28, 2017
1 parent 1d6c99b commit 2e7e812
Show file tree
Hide file tree
Showing 4 changed files with 91 additions and 0 deletions.
26 changes: 26 additions & 0 deletions src/hub.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import * as fmt from './sse_formatter';
import { ISseFunctions } from './sse_middleware';

export class Hub {
private clients = new Set<ISseFunctions>();

public register(funcs: ISseFunctions): void {
this.clients.add(funcs);
}

public unregister(funcs: ISseFunctions): void {
this.clients.delete(funcs);
}

public data(data: fmt.SSEValue, id?: string): void {
this.clients.forEach(client => client.data(data, id));
}

public event(event: string, data: fmt.SSEValue, id?: string): void {
this.clients.forEach(client => client.event(event, data, id));
}

public comment(comment: string): void {
this.clients.forEach(client => client.comment(comment));
}
}
2 changes: 2 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
export * from './hub';
export { ISseMiddlewareOptions } from './sse_handler_middleware';
export * from './sse_middleware';
export * from './sse_hub_middleware';
export { sse as default } from './sse_middleware';
58 changes: 58 additions & 0 deletions src/sse_hub_middleware.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import { compose } from 'compose-middleware';
import { Handler, NextFunction, Request, Response } from 'express';
import { Hub } from './hub';
import { ISseMiddlewareOptions } from './sse_handler_middleware';
import { ISseFunctions, ISseResponse, sse } from './sse_middleware';

export interface ISseHubFunctions extends ISseFunctions {
/**
* Holds the broadcasting variants of the normal SSE functions.
*/
broadcast: ISseFunctions;
}

/**
* An ISseHubResponse is an augmented ISseResponse that contains a `sse.broadcast` property that contains the normal
* SSE functions, except that they will send messages to every client connected to the hub.
*
* Example:
* res.sse.event('myevent', data'); // send to the client that originated the request.
* res.sse.broadcast.event('myevent', 'data'); // send to every client that passed through the middleware.
*/
export interface ISseHubResponse extends Response {
sse: ISseHubFunctions;
}

export interface ISseHubMiddlewareOptions extends ISseMiddlewareOptions {
hub: Hub;
}

/**
* SSE middleware that configures an Express response for an SSE session, installs `sse.*` functions on the Response
* object, as well as the `sse.broadcast.*` variants.
*
* @param options An ISseMiddlewareOptions to configure the middleware's behaviour.
*/
export function sseHub(options: Partial<ISseHubMiddlewareOptions> = {}): Handler {
const { hub = new Hub() } = options;

function middleware(req: Request, res: ISseResponse, next: NextFunction): void {
//=> Register the SSE functions of that client on the hub
hub.register(res.sse);

//=> Unregister the user from the hub when its connection gets closed
res.once('close', () => hub.unregister(res.sse));

//=> Make hub's functions available on the response
(res as ISseHubResponse).sse.broadcast = {
data: hub.data.bind(hub),
event: hub.event.bind(hub),
comment: hub.comment.bind(hub),
};

//=> Done
next();
}

return compose(sse(options), middleware);
}
5 changes: 5 additions & 0 deletions test/index.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { expect } from 'chai';
import * as index from '../src/index';
import * as sseHubMiddleware from '../src/sse_hub_middleware';
import * as sseMiddleware from '../src/sse_middleware';

describe('index', () => {
Expand All @@ -8,5 +9,9 @@ describe('index', () => {
expect(index.sse).to.equal(sseMiddleware.sse);
expect(index.default).to.equal(sseMiddleware.sse);
});

it('exports { sseHub }', () => {
expect(index.sseHub).to.equal(sseHubMiddleware.sseHub);
});
});
});

0 comments on commit 2e7e812

Please sign in to comment.