|
|
|
|
import { onError } from "@apollo/client/link/error";
|
|
|
|
|
import { WebSocketLink } from "@apollo/client/link/ws";
|
|
|
|
|
import {
|
|
|
|
|
ApolloClient,
|
|
|
|
|
InMemoryCache,
|
|
|
|
|
gql,
|
|
|
|
|
ApolloLink,
|
|
|
|
|
HttpLink,
|
|
|
|
|
split,
|
|
|
|
|
} from "@apollo/client";
|
|
|
|
|
import { getMainDefinition } from "@apollo/client/utilities";
|
|
|
|
|
|
|
|
|
|
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: {
|
|
|
|
|
Query: {
|
|
|
|
|
fields: {
|
|
|
|
|
device(_, { toReference, args }) {
|
|
|
|
|
return toReference({ __typename: "Device", id: args.id });
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
}),
|
|
|
|
|
resolvers: {
|
|
|
|
|
Device: {
|
|
|
|
|
messages() {
|
|
|
|
|
return [];
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
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
|
|
|
|
|
properties {
|
|
|
|
|
id
|
|
|
|
|
name
|
|
|
|
|
...PropertyVector
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
${deviceInfoFragment}
|
|
|
|
|
${propertyVectorFragment}
|
|
|
|
|
`;
|
|
|
|
|
|
|
|
|
|
const GETDEVICE = gql`
|
|
|
|
|
query device($id: String!) {
|
|
|
|
|
device(id: $id) {
|
|
|
|
|
id
|
|
|
|
|
...DeviceInfo
|
|
|
|
|
messages @client
|
|
|
|
|
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 = [];
|
|
|
|
|
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,
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
export default client;
|