You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

291 lines
5.5 KiB

import { onError } from "@apollo/client/link/error";
import { WebSocketLink } from "@apollo/client/link/ws";
6 years ago
import {
ApolloClient,
6 years ago
InMemoryCache,
gql,
ApolloLink,
HttpLink,
split,
} from "@apollo/client";
import { getMainDefinition } from "@apollo/client/utilities";
6 years ago
import {
propertyVectorFragment,
vectorFragment,
deviceInfoFragment,
} from "./graphql/fragment";
import { isConnectedQuery } from "./graphql/query";
// Create an http link:
const httpLink = new HttpLink({
uri: "/graphql",
});
// Create a WebSocket link:
const wsLink = new WebSocketLink({
uri: `ws://${window.location.host}/graphql`,
options: {
reconnect: true,
},
});
const link = split(
// split based on operation type
({ query }) => {
const definition = getMainDefinition(query);
return (
definition.kind === "OperationDefinition" &&
definition.operation === "subscription"
);
},
wsLink,
httpLink
);
const client = new ApolloClient({
link: ApolloLink.from([
onError(({ graphQLErrors, networkError }) => {
if (graphQLErrors)
graphQLErrors.forEach(({ message, locations, path }) =>
console.log(
`[GraphQL error]: Message: ${message}, Location: ${locations}, Path: ${path}`
)
);
if (networkError) console.log(`[Network error]: ${networkError}`);
}),
link,
]),
cache: new InMemoryCache({
possibleTypes: {
Vector: ["NumberVector", "SwitchVector", "TextVector", "LightVector"],
},
typePolicies: {
6 years ago
Query: {
fields: {
device(_, { toReference, args }) {
return toReference({ __typename: "Device", id: args.id });
},
},
6 years ago
},
},
}),
resolvers: {
Device: {
messages() {
return [];
},
},
},
6 years ago
});
const CONNECTED = gql`
subscription connected {
connected
}
`;
client
.subscribe({
query: CONNECTED,
})
.subscribe(({ data }) => {
client.writeQuery({
query: isConnectedQuery,
data: { connected: data.connected },
});
console.log(data);
});
const DISCONNECTED = gql`
subscription disconnected {
disconnected
}
`;
client
.subscribe({
query: DISCONNECTED,
})
.subscribe(({ data }) => {
console.log(data);
});
const NEW_DEVICE = gql`
subscription newDevice {
newDevice {
id
...DeviceInfo
}
}
${deviceInfoFragment}
`;
const GETDEVICES = gql`
query devices {
devices {
id
...DeviceInfo
messages @client
6 years ago
properties {
id
name
...PropertyVector
}
}
}
${deviceInfoFragment}
${propertyVectorFragment}
`;
const GETDEVICE = gql`
query device($id: String!) {
device(id: $id) {
id
...DeviceInfo
messages @client
6 years ago
properties {
id
name
...PropertyVector
}
}
}
${deviceInfoFragment}
${propertyVectorFragment}
`;
client
.subscribe({
query: NEW_DEVICE,
})
.subscribe(({ data }) => {
const res = client.readQuery({ query: GETDEVICES });
data.newDevice.properties = [];
data.newDevice.messages = [];
6 years ago
client.writeQuery({
query: GETDEVICES,
data: { devices: [...res.devices, data.newDevice] },
});
});
const NEW_PROPERTY = gql`
subscription newProperty {
newProperty {
id
name
device
...PropertyVector
}
}
${propertyVectorFragment}
`;
client
.subscribe({
query: NEW_PROPERTY,
})
.subscribe(({ data }) => {
const res = client.readQuery({
query: GETDEVICE,
variables: { id: data.newProperty.device },
});
client.writeQuery({
query: GETDEVICE,
variables: { id: res.device.id },
data: {
device: {
...res.device,
drivers:
data.newProperty.name === "DRIVER_INFO"
? data.newProperty.vector.values[3].text
: res.device.drivers,
connected:
data.newProperty.name === "CONNECTION"
? data.newProperty.vector.values[0].switch
: res.device.connected,
properties: [...res.device.properties, data.newProperty],
},
},
});
});
const NEW_VALUE = gql`
subscription newValue {
newValue {
id
device
...VectorData
}
}
${vectorFragment}
`;
client
.subscribe({
query: NEW_VALUE,
})
.subscribe(({ data }) => {
if (data.newValue.name === "CONNECTION") {
const res = client.readQuery({
query: GETDEVICE,
variables: { id: data.newValue.device },
});
client.writeQuery({
query: GETDEVICE,
variables: { id: res.device.id },
data: {
device: {
...res.device,
connected: data.newValue.values[0].switch,
},
},
});
console.log(res);
}
});
const NEW_MESSAGE = gql`
subscription newMessage {
newMessage {
id
device {
id
}
message
}
}
`;
client
.subscribe({
query: NEW_MESSAGE,
})
.subscribe(({ data }) => {
const res = client.readQuery({
query: GETDEVICE,
variables: { id: data.newMessage.device.id },
});
const messages = res.device.messages
? [data.newMessage.message, ...res.device.messages]
: [data.newMessage.message];
client.writeQuery({
query: GETDEVICE,
variables: { id: res.device.id },
data: {
device: {
...res.device,
messages,
},
},
});
});
6 years ago
export default client;