Skip to content
This repository has been archived by the owner on Oct 11, 2019. It is now read-only.

Commit

Permalink
Add better subscriptions client for auto-reconnect
Browse files Browse the repository at this point in the history
  • Loading branch information
lunchboxer committed Apr 12, 2019
1 parent 608f1f6 commit ebb22c3
Show file tree
Hide file tree
Showing 14 changed files with 292 additions and 81 deletions.
3 changes: 2 additions & 1 deletion .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ module.exports = {
plugins: ['svelte3'],
rules: {
"unicorn/filename-case": 0,
"no-labels": 0
"no-labels": 0,
"import/first": 0
}
}
5 changes: 5 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@
"files.associations": {
"*.svelte": "html"
},
"files.watcherExclude": {
"public/bundle": true
},
"editor.formatOnType": true,
"javascript.format.insertSpaceBeforeFunctionParenthesis": true,
"eslint.autoFixOnSave": true,
"eslint.validate": [
"javascript",
Expand Down
9 changes: 7 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@
"scripts": {
"build": "npm run clean && rollup -c",
"clean": "rm -rf public/bundle",
"dev": "rollup -c -w",
"start": "sirv public --single"
"start": "sirv public --single",
"autobuild": "rollup -c -w",
"dev": "run-p start:dev autobuild",
"start:dev": "sirv public --dev --single"
},
"devDependencies": {
"bulma": "^0.7.4",
Expand All @@ -17,6 +19,7 @@
"eslint-plugin-svelte3": "^0.4.7",
"eslint-plugin-unicorn": "^8.0.1",
"node-sass": "^4.11.0",
"npm-run-all": "^4.1.5",
"rollup": "^1.9.0",
"rollup-plugin-commonjs": "^9.2.0",
"rollup-plugin-commonjs-alternate": "0.0.5",
Expand All @@ -34,7 +37,9 @@
"dependencies": {
"@fortawesome/fontawesome-free": "^5.8.1",
"date-fns": "^2.0.0-alpha.27",
"eslint-plugin-import": "^2.16.0",
"flatpickr": "^4.5.7",
"graphql-subscriptions-client": "^0.10.0",
"navaid": "^1.0.0"
}
}
16 changes: 8 additions & 8 deletions rollup.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,14 +33,14 @@ module.exports = [{
}),
resolve(),
commonjs(),
!production && serve({
contentBase: 'public',
historyApiFallback: true,
port: 5050
}),
!production && livereload({
watch: 'public'
}),
// !production && serve({
// contentBase: 'public',
// historyApiFallback: true,
// port: 5050
// }),
// !production && livereload({
// watch: 'public'
// }),
notify(),

// If we're building for production (npm run build
Expand Down
1 change: 0 additions & 1 deletion src/components/GroupSelect.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
}
})
$: console.log(groups)
function checkValidity () {
error = !selectElement.validity.valid && selectElement.validationMessage
? selectElement.validationMessage
Expand Down
53 changes: 2 additions & 51 deletions src/components/dashboard/Dashboard.svelte
Original file line number Diff line number Diff line change
@@ -1,56 +1,7 @@
<script>
import { subRequest } from '../../data/ws-client'
import { request } from '../../data/fetch-client'
import { GET_SESSIONS } from '../sessions/queries'
import { onMount } from 'svelte'
import { todaysSessions } from '../sessions/data'
let sessions = []
onMount(async () => {
const response = await request(GET_SESSIONS)
sessions = response.classSessions
})
const query = `
subscription {
classSessions {
mutation
updatedFields
previousValues{
id
stage
startsAt
endsAt
}
node {
id
stage
startsAt
endsAt
number
group {
id
name
}
}
}
}`
subRequest(query, null, function (data) {
const { mutation, node, previousValues } = data.classSessions
if (mutation === 'CREATED') {
sessions = [...sessions, node]
} else if (mutation === 'UPDATED') {
sessions = sessions.map(s => {
if (s.id === node.id) return s
return node
})
} else if (mutation === 'DELETED') {
sessions = sessions.filter(s => s.id !== previousValues.id)
}
})
$: console.log(sessions)
$: console.log($todaysSessions)
</script>
<svelte:head>
Expand Down
2 changes: 1 addition & 1 deletion src/components/sessions/EditSession.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
input.endsAt = new Date(input.endsAt).toISOString()
loading = true
try {
const updatedSession = await sessions.update(id, input, groupId)
const updatedSession = await sessions.patch(id, input, groupId)
const date = formatRelative(new Date(input.startsAt), new Date(), { addSuffix: true })
notifications.add({ text: `Update session to ${date} with ${updatedSession.group.name} class`, type: 'success' })
reset()
Expand Down
13 changes: 13 additions & 0 deletions src/components/sessions/Sessions.svelte
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
<script>
import { onMount, onDestroy } from 'svelte'
import { sessions, sessionsFilter } from './data'
import Upcoming from './UpcomingSessions.svelte'
import SessionsList from './SessionsList.svelte'
Expand All @@ -7,6 +8,16 @@
let activeComponent = Upcoming
let active = 'upcoming'
let refetch
onMount(() => {
sessions.get()
refetch = setInterval(sessions.get, 5 * 6e+4)
})
onDestroy(() => {
refetch && clearInterval(refetch)
})
const switchTab = (tab) => {
let where = null
Expand Down Expand Up @@ -41,6 +52,8 @@

<AddSession />

<button class="button" on:click={sessions.get}><i class="fas fa-sync"></i></button>

<nav class="buttons has-addons is-centered">
<button class="button is-link" class:is-outlined={active!=='upcoming' } on:click={()=>
switchTab('upcoming')}>
Expand Down
55 changes: 38 additions & 17 deletions src/components/sessions/data.js
Original file line number Diff line number Diff line change
@@ -1,18 +1,20 @@
import { writable, readable, get } from 'svelte/store'
import { writable, get, readable } from 'svelte/store'
import { request } from '../../data/fetch-client'
import { GET_SESSIONS, GET_TODAYS_SESSIONS } from './queries'
import { GET_SESSIONS, SESSIONS_SUB, GET_TODAYS_SESSIONS } from './queries'
import { CREATE_SESSION, DELETE_SESSION, UPDATE_SESSION } from './mutations'
import { ws } from '../../data/ws-client2'

export const semester = writable()

const createSessionsStore = () => {
const { subscribe, set } = writable()
const { subscribe, set, update } = writable()
return {
subscribe,
update,
get: async () => {
const where = (get(sessionsFilter))
const getres = await request(GET_SESSIONS, { where })
set(getres.classSessions)
const response = await request(GET_SESSIONS, { where })
set(response.classSessions)
},
create: async (input, groupId) => {
const response = await request(CREATE_SESSION, { input, groupId })
Expand All @@ -24,7 +26,7 @@ const createSessionsStore = () => {
sessions.get()
return response.deleteClassSession
},
update: async (id, input, groupId) => {
patch: async (id, input, groupId) => {
const response = await request(UPDATE_SESSION, { id, input, groupId })
sessions.get()
return response.updateClassSession
Expand All @@ -36,14 +38,8 @@ export const sessionsFilter = writable()

export const sessions = createSessionsStore()

const fetchTodaysSessions = async () => {
const now = new Date()
const latest = new Date(now.getTime() + 24 * 3.6e+6)
const response = await request(GET_TODAYS_SESSIONS, { now, latest })
return response.classSessions
}

const sortSessions = (sessions) => {
if (!sessions) return
const time = new Date()
const in15Min = new Date(time.getTime() + 15 * 60000).toISOString()
const in24hrs = new Date(time.getTime() + 24 * 3.6e+6).toISOString()
Expand All @@ -59,6 +55,19 @@ const sortSessions = (sessions) => {
return { now, soon, later }
}

const fetchTodaysSessions = async () => {
const now = new Date()
const latest = new Date(now.getTime() + 24 * 3.6e+6)
const response = await request(GET_TODAYS_SESSIONS, { now, latest })
return response.classSessions
}

// get the initial sessions list from today
// then resort that list every 15 seconds
// listen to a subscription on all sessions
// the new or the old value was within 24 hours, refetch.
// also automatically refetch if data is stale

export const todaysSessions = readable(null, set => {
// get the initial data
let updatedAt = new Date()
Expand All @@ -67,11 +76,20 @@ export const todaysSessions = readable(null, set => {
sessions = result
set({ ...sortSessions(result), updatedAt })
})

const subscription = ws.request({ query: SESSIONS_SUB }).subscribe({
next (message) {
if (message.data && message.data.classSessions) {
fetchTodaysSessions().then(result => {
sessions = result
set({ ...sortSessions(result), updatedAt: new Date() })
})
}
}
})
const interval = setInterval(() => {
// refetch data every 5 minutes
// refetch data periodically
const now = new Date()
const expiry = new Date(now - 5 * 60000)
const expiry = new Date(now - 3.6e+6)
if (updatedAt < expiry) {
fetchTodaysSessions().then(result => {
sessions = result
Expand All @@ -83,5 +101,8 @@ export const todaysSessions = readable(null, set => {
}
}, 15000)

return () => clearInterval(interval)
return () => {
subscription && subscription.unsubscribe()
clearInterval(interval)
}
})
50 changes: 50 additions & 0 deletions src/components/sessions/queries.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,3 +48,53 @@ query todaysSessions($now: DateTime, $latest: DateTime){
}
}
}`

export const SESSIONS_SUB = /* GraphQL */`
subscription {
classSessions {
mutation
updatedFields
previousValues{
id
stage
startsAt
endsAt
}
node {
id
stage
startsAt
endsAt
number
group {
id
name
}
}
}
}`

export const TODAYS_SESSIONS_SUB = /* GraphQL */`
subscription {
classSessions {
mutation
updatedFields
previousValues {
id
stage
startsAt
endsAt
}
node {
id
stage
startsAt
endsAt
number
group {
id
name
}
}
}
}`
8 changes: 8 additions & 0 deletions src/data/timer.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,11 @@ export const time = readable(new Date(), set => {

return () => clearInterval(interval)
})

export const everyMinute = readable(new Date(), set => {
const interval = setInterval(() => {
set(new Date())
}, 6e+4)

return () => clearInterval(interval)
})
32 changes: 32 additions & 0 deletions src/data/ws-client.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,10 @@ const formatRequest = (query, variables, id) => {
}

export const subRequest = (query, variables, callback) => {
console.log(variables)
const id = randomId()
const request = formatRequest(query, variables, id)
console.log('request:', request)
if (ws.readyState === 1) {
ws.send(request)
} else {
Expand Down Expand Up @@ -75,3 +77,33 @@ export const wsQueryRequest = (query, variables) => {
}
})
}

export const subscribeToMore = (query, variables, store) => {
const pattern = /{\n?\s*(\w+)/
const dataName = query.match(pattern)[1]
console.log(store)
subRequest(query, variables, function (data) {
console.log('subscribe to more got something')
if (!data) return
const { mutation, node, previousValues } = data[dataName]
if (mutation === 'CREATED') {
console.log('CREATED')
store.update(previous => {
return [...previous, node]
})
} else if (mutation === 'UPDATED') {
console.log('UPDATED')
store.update(previous => {
return previous.map(item => {
if (item.id !== node.id) return item
return node
})
})
} else if (mutation === 'DELETED') {
console.log('DELETED')
store.update(previous => {
return previous.filter(item => item.id !== previousValues.id)
})
}
})
}
Loading

0 comments on commit ebb22c3

Please sign in to comment.