Skip to content

Commit 6f9bb68

Browse files
committed
feat: Add sse handler
1 parent d53e879 commit 6f9bb68

File tree

4 files changed

+88
-49
lines changed

4 files changed

+88
-49
lines changed

src/db.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
const promise = require('promise')
2+
const Observable = require("zen-observable")
23

34
let adapter
45
const adapterName = `micro-analytics-adapter-${process.env.DB_ADAPTER || 'flat-file-db'}`
@@ -17,10 +18,20 @@ try {
1718
}
1819
}
1920

21+
const observable = new Observable((observer) => {
22+
let timer = setInterval(_ => {
23+
observer.next("hello")
24+
}, 1000)
25+
26+
return _ => clearTimeout(timer)
27+
});
28+
29+
2030
module.exports = {
2131
get: adapter.get,
2232
getAll: adapter.getAll,
2333
put: adapter.put,
2434
has: adapter.has,
2535
keys: adapter.keys,
36+
subscribe: adapter.subscribe,
2637
}

src/handler.js

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
const url = require('url')
2+
const { send, createError, sendError } = require('micro')
3+
4+
const db = require('./db')
5+
const { pushView } = require('./utils')
6+
7+
module.exports = async function (req, res) {
8+
const { pathname, query } = url.parse(req.url, /* parseQueryString */ true)
9+
res.setHeader('Access-Control-Allow-Origin', '*')
10+
// Send all views down if "?all" is true
11+
if (String(query.all) === 'true') {
12+
try {
13+
const data = {
14+
data: await db.getAll({
15+
pathname: pathname,
16+
before: parseInt(query.before, 10),
17+
after: parseInt(query.after, 10),
18+
}),
19+
time: Date.now()
20+
}
21+
send(res, 200, data)
22+
return
23+
} catch (err) {
24+
console.log(err)
25+
throw createError(500, 'Internal server error.')
26+
}
27+
}
28+
// Check that a page is provided
29+
if (pathname.length <= 1) {
30+
throw createError(400, 'Please include a path to a page.')
31+
}
32+
if (req.method !== 'GET' && req.method !== 'POST') {
33+
throw createError(400, 'Please make a GET or a POST request.')
34+
}
35+
const shouldIncrement = String(query.inc) !== 'false'
36+
try {
37+
const currentViews = await db.has(pathname) ? (await db.get(pathname)).views.length : 0
38+
// Add a view and send the total views back to the client
39+
if (shouldIncrement) {
40+
await pushView(pathname, { time: Date.now() })
41+
}
42+
if (req.method === 'GET') {
43+
send(res, 200, { views: shouldIncrement ? currentViews + 1 : currentViews })
44+
} else {
45+
send(res, 200)
46+
}
47+
} catch (err) {
48+
console.log(err)
49+
throw createError(500, 'Internal server error.')
50+
}
51+
}

src/index.js

Lines changed: 9 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1,51 +1,11 @@
1-
const url = require('url')
2-
const { send, createError, sendError } = require('micro')
1+
const micro = require('micro')
2+
const SSE = require('sse')
33

4-
const db = require('./db')
5-
const { pushView } = require('./utils')
4+
const handler = require('./handler')
5+
const sseHandler = require('./sse')
66

7-
module.exports = async function (req, res) {
8-
const { pathname, query } = url.parse(req.url, /* parseQueryString */ true)
9-
res.setHeader('Access-Control-Allow-Origin', '*')
10-
// Send all views down if "?all" is true
11-
if (String(query.all) === 'true') {
12-
try {
13-
const data = {
14-
data: await db.getAll({
15-
pathname: pathname,
16-
before: parseInt(query.before, 10),
17-
after: parseInt(query.after, 10),
18-
}),
19-
time: Date.now()
20-
}
21-
send(res, 200, data)
22-
return
23-
} catch (err) {
24-
console.log(err)
25-
throw createError(500, 'Internal server error.')
26-
}
27-
}
28-
// Check that a page is provided
29-
if (pathname.length <= 1) {
30-
throw createError(400, 'Please include a path to a page.')
31-
}
32-
if (req.method !== 'GET' && req.method !== 'POST') {
33-
throw createError(400, 'Please make a GET or a POST request.')
34-
}
35-
const shouldIncrement = String(query.inc) !== 'false'
36-
try {
37-
const currentViews = await db.has(pathname) ? (await db.get(pathname)).views.length : 0
38-
// Add a view and send the total views back to the client
39-
if (shouldIncrement) {
40-
await pushView(pathname, { time: Date.now() })
41-
}
42-
if (req.method === 'GET') {
43-
send(res, 200, { views: shouldIncrement ? currentViews + 1 : currentViews })
44-
} else {
45-
send(res, 200)
46-
}
47-
} catch (err) {
48-
console.log(err)
49-
throw createError(500, 'Internal server error.')
50-
}
51-
}
7+
const server = micro(handler)
8+
const sse = new SSE(server)
9+
sse.on('connection', sseHandler)
10+
11+
server.listen(3000)

src/sse.js

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
const db = require('./db')
2+
3+
module.exports = function handleSseConnection(connection) {
4+
console.log('new connection')
5+
const subscription = db.subscribe((event) => {
6+
console.log('new event', event)
7+
connection.send({
8+
event: 'new-event',
9+
data: JSON.stringify(event),
10+
})
11+
})
12+
13+
connection.on('close', function () {
14+
console.log('closing connection')
15+
subscription.unsubscribe()
16+
})
17+
}

0 commit comments

Comments
 (0)