SSE-Z
A slim, easy-to-use wrapper around SSE.
Installation
npm install sse-z
Usage
import { SSESubscription } from "sse-z";
const subscription = new SSESubscription({
url: "http://localhost:8080/sse",
searchParams: {
foo: "bar",
},
onNext: (type: string, data: string) => {
console.log(type, data);
},
});
subscription.unsubscribe();
Types
class SSESubscription {
eventSource: EventSource;
constructor(options: SSESubscriptionOptions);
unsubscribe(): void;
}
interface SSESubscriptionOptions {
eventSourceOptions?: {
withCredentials?: boolean;
[key: string]: any;
};
keepAlive?: {
eventType?: string;
intervalMs: number;
};
onComplete?: () => void;
onError?: (error: Error) => void;
onNext?: (type: string, data: string) => void;
searchParams?: {
[key: string]: string;
};
url: string;
}
Integration with GraphQL Clients
Relay
import {
Environment,
Network,
Observable,
SubscribeFunction,
} from "relay-runtime";
import { SSESubscription } from "sse-z";
const subscribe: SubscribeFunction = (operation, variables) => {
return Observable.create((sink) => {
return new SSESubscription({
url: 'http://localhost:8080/graphql',
searchParams: {
operationName: operation.name,
query: operation.text,
variables: JSON.stringify(variables),
},
eventSourceOptions: {
withCredentials: true,
},
onNext: (type, data) => {
if (type === 'event') {
sink.next(JSON.parse(data));
}
},
});
});
};
const environment = new Environment({
...
network: Network.create(fetchQuery, subscribe),
});
Apollo Client
import { ApolloLink, Operation, FetchResult, Observable } from "@apollo/client";
import { print } from "graphql";
import { SSESubscription, SSESubscriptionOptions } from "sse-z";
class SSELink extends ApolloLink {
options: SSESubscriptionOptions;
constructor(options: SSESubscriptionOptions) {
super();
this.options = options;
}
public request({
query,
variables,
operationName,
}: Operation): Observable<FetchResult> {
return new Observable((sink) => {
const subscription = new SSESubscription({
...options,
searchParams: {
query: print(operation.query),
variables: JSON.stringify(variables),
operationName,
},
onNext: (type, data) => {
if (type === "event") {
sink.next(JSON.parse(data));
}
},
});
return () => subscription.unsubscribe();
});
}
}
const link = new SSELink({
url: "http://localhost:8080/graphql",
eventSourceOptions: {
withCredentials: true,
},
});