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.
290 lines
5.5 KiB
290 lines
5.5 KiB
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;
|
|
|