Skip to content

Commit

Permalink
feat: better
Browse files Browse the repository at this point in the history
  • Loading branch information
TroyKomodo committed Jul 16, 2023
1 parent 66b626c commit 172e812
Showing 1 changed file with 12 additions and 55 deletions.
67 changes: 12 additions & 55 deletions frontend/website/src/lib/gql.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,65 +75,22 @@ if (typeof window !== "undefined") {

window.SCUFFLE_WS_CLIENT = wsClient;

const wsSink = subscriptionExchange({
enableAllOperations: true,
forwardSubscription: (operation) => ({
subscribe: (sink) => ({
unsubscribe: wsClient.subscribe(operation as SubscribePayload, sink),
exchanges.push(
subscriptionExchange({
enableAllOperations: true,
// this allows us to forward subscriptions to the websocket, if it's open otherwise we use the fetch exchange below.
isSubscriptionOperation: (op) => get(websocketOpen) || op.kind === "subscription",
forwardSubscription: (operation) => ({
subscribe: (sink) => ({
unsubscribe: wsClient.subscribe(operation as SubscribePayload, sink),
}),
}),
}),
});

// This is a bit hard to understand, but it's basically a custom exchange that
// will send all operations to the websocket if it's open, and to the HTTP
// endpoint if it's not. Websockets take some time to connect
// so we dont want to delay the user.
const operationExchange: Exchange = ({ client, dispatchDebug, forward }) => {
const result$ = forward(never);

const httpExchange = fetchExchange({
client,
dispatchDebug,
forward: () => result$,
});

const wsExchange = wsSink({
client,
dispatchDebug,
forward: () => result$,
});

return (ops$) => {
// Here we filter if the websocket is open or if the kind is subscription or teardown.
// We want to use the websocket as much as possible so we send all operations if it is open.
// We also need to forward all teardowns and subscriptions regardless of the websocket state.
const wsPipe$ = pipe(
ops$,
filter((op) => get(websocketOpen) || op.kind === "subscription" || op.kind === "teardown"),
wsExchange,
);

// Here we use it as a fallback if the websocket is not open, however we still need to forward teardowns even if the websocket is open.
const httpPipe$ = pipe(
ops$,
filter(
(op) => (!get(websocketOpen) || op.kind === "teardown") && op.kind !== "subscription",
),
httpExchange,
);

// At the end we need to merge both streams together and return a single result stream.
return merge([wsPipe$, httpPipe$]);
};
};

// We want to switch out the fetchExchange with our custom exchange.
exchanges.push(operationExchange);
} else {
// If we are on the server we just use the fetchExchange. We dont need to worry about websockets.
exchanges.push(fetchExchange);
);
}

exchanges.push(fetchExchange);

const gqlURL =
(typeof window === "undefined" && env.PUBLIC_SSR_GQL_ENDPOINT) || PUBLIC_GQL_ENDPOINT;

Expand Down

0 comments on commit 172e812

Please sign in to comment.