fastify#EventMessage TypeScript Examples

The following examples show how to use fastify#EventMessage. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: utils.ts    From fastify-sse-v2 with MIT License 7 votes vote down vote up
export async function getFastifyServer(source: AsyncIterable<EventMessage>): Promise<FastifyInstance> {
  const server = fastify();
  server.register(FastifySSEPlugin);
  server.get("/", function (req, res) {
    res.header("x-test-header2", "test2");
    res.sse(source);
  });
  await server.ready();
  await new Promise<void>((resolve, reject) => {
    server.listen(0, "127.0.0.1", (err) => {
      if(err) {
        return reject(err);
      }
      resolve();
    });
  });
  return server;
}
Example #2
Source File: plugin.ts    From fastify-sse-v2 with MIT License 6 votes vote down vote up
plugin: FastifyPluginAsync<SsePluginOptions> =
    async function (instance, options): Promise<void> {
      instance.decorateReply(
        "sse",
        function (this: FastifyReply, source: AsyncIterable<EventMessage>): void {
          Object.entries(this.getHeaders()).forEach(([key, value]) => {
            this.raw.setHeader(key, value);
          });
          this.raw.setHeader("Content-Type","text/event-stream");
          this.raw.setHeader("Connection", "keep-alive");
          this.raw.setHeader("Cache-Control", "no-cache,no-transform");
          this.raw.setHeader("x-no-compression", 1);
          this.raw.write(serializeSSEEvent({retry: options.retryDelay || 3000}));
          toStream(transformAsyncIterable(source)).pipe(this.raw);
        });
    }
Example #3
Source File: sse.ts    From fastify-sse-v2 with MIT License 6 votes vote down vote up
export function serializeSSEEvent(chunk: EventMessage): string {
  let payload = "";
  if(chunk.id) {
    payload += `id: ${chunk.id}\n`;
  }
  if(chunk.event) {
    payload += `event: ${chunk.event}\n`;
  }
  if(chunk.data) {
    payload += `data: ${chunk.data}\n`;
  }
  if(chunk.retry) {
    payload += `retry: ${chunk.retry}\n`;
  }
  if(!payload) {
    return "";
  }
  payload += "\n";
  return payload;
}
Example #4
Source File: sse.ts    From fastify-sse-v2 with MIT License 5 votes vote down vote up
export async function* transformAsyncIterable(source: AsyncIterable<EventMessage>): AsyncIterable<string> {
  for await (const message of source) {
    yield serializeSSEEvent(message);
  }
  yield serializeSSEEvent({event: "end", data: "Stream closed"});
}
Example #5
Source File: index.spec.ts    From fastify-sse-v2 with MIT License 4 votes vote down vote up
describe("Test SSE plugin", function () {

  let server: FastifyInstance;
  let source: Pushable<EventMessage>;
  
  beforeEach(async function () {
    source = pushable<EventMessage>();
    server = await getFastifyServer(source);
  });
  
  afterEach(async function () {
    source.end();
    if(server) {
      await server.close(); 
    }
  });
  
  it("should open event stream", function (done) {
    const eventsource = getEventSource(server);
    eventsource.addEventListener("open", function () {
      expect(eventsource.readyState).to.equal(eventsource.OPEN);
      eventsource.close();
      done();
    });
  });
  
  it("should set plugin headers", function (done) {
    try {
      get(getBaseUrl(server), {timeout: 100}, (res) => {
        expect(res.headers["x-test-header2"]).to.be.deep.equal("test2");
        res.destroy();
        done();
      });
    } catch(e) {
      done(e);
    }
  });

  it("should set retry", function (done) {
    const eventsource = getEventSource(server);
    eventsource.addEventListener("open", function () {
      source.end();
    });
    eventsource.addEventListener("error", function () {
      // @ts-ignore
      expect(eventsource.reconnectInterval).to.be.equal(3000);
      eventsource.close();
      done();
    });
  });

  it("should end client", function (done) {
    const eventsource = getEventSource(server);
    eventsource.addEventListener("open", function () {
      source.end();
    });
    eventsource.addEventListener("message", function () {
      eventsource.close();
      throw "shouldn't be called";
    });
    eventsource.addEventListener("end", function (e: Event) {
      expect(e.type).to.be.equal("end");
      // @ts-ignore
      expect(e.data).to.be.equal("Stream closed");
      eventsource.close();
      done();
    });
  });

  it("should send single event", function (done) {
    const eventsource = getEventSource(server);
    source.push({id: "1", event: "message", data: "Something"});
    eventsource.onmessage = (evt => {
      expect(evt.data).equal("Something");
      expect(evt.type).equal("message");
      expect(evt.lastEventId).equal("1");
      eventsource.close();
      done();
    });

  });

  it("should send multiple events", function (done) {
    const eventsource = getEventSource(server);
    source.push({id: "1", event: "message", data: "Something"});
    source.push({id: "2", event: "message", data: "Something"});
    source.end();
    const spy = sinon.spy();
    eventsource.onmessage = (() => spy());
    eventsource.onerror = (() => {
      expect(spy.callCount).to.be.equal(2);
      eventsource.close();
      done();
    });

  });

});