Last active
September 17, 2018 20:52
-
-
Save nolanlawson/3e096160b848689f1058 to your computer and use it in GitHub Desktop.
Keep an in-memory array in sync with a PouchDB
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<html> | |
<head> | |
<title>Reactive PouchDB demo</title> | |
<style> | |
h1, p, ul, li, button { | |
font-family: Helvetica, Arial, sans-serif; | |
} | |
button { | |
font-size: 16px; | |
padding: 10px; | |
cursor: pointer; | |
} | |
body { | |
max-width: 800px; | |
margin: 0 auto; | |
padding: 20px; | |
} | |
li { | |
list-style: none; | |
} | |
</style> | |
</head> | |
<body> | |
<h1>My list of docs</h1> | |
<div> | |
<button type="button" onclick="insertRandomDoc()">Add a doc</button> | |
<button type="button" onclick="updateRandomDoc()">Update a doc</button> | |
<button type="button" onclick="deleteRandomDoc()">Remove a doc</button> | |
</div> | |
<ul id="the-list"></ul> | |
<script src="//cdn.jsdelivr.net/pouchdb/latest/pouchdb.js"></script> | |
<script src="script.js"></script> | |
</body> | |
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
'use strict'; | |
// this array will always be kept up-to-date with PouchDB | |
var docs = []; | |
var db = new PouchDB('somedb'); | |
function binarySearch(arr, docId) { | |
var low = 0, high = arr.length, mid; | |
while (low < high) { | |
mid = (low + high) >>> 1; // faster version of Math.floor((low + high) / 2) | |
arr[mid]._id < docId ? low = mid + 1 : high = mid | |
} | |
return low; | |
} | |
function onDeleted(id) { | |
var index = binarySearch(docs, id); | |
var doc = docs[index]; | |
if (doc && doc._id === id) { | |
docs.splice(index, 1); | |
} | |
} | |
function onUpdatedOrInserted(newDoc) { | |
var index = binarySearch(docs, newDoc._id); | |
var doc = docs[index]; | |
if (doc && doc._id === newDoc._id) { // update | |
docs[index] = newDoc; | |
} else { // insert | |
docs.splice(index, 0, newDoc); | |
} | |
} | |
function fetchInitialDocs() { | |
return db.allDocs({include_docs: true}).then(function (res) { | |
docs = res.rows.map(function (row) { return row.doc; }); | |
renderDocs(); | |
}); | |
} | |
function reactToChanges() { | |
db.changes({live: true, since: 'now', include_docs: true}).on('change', function (change) { | |
if (change.deleted) { | |
// change.id holds the deleted id | |
onDeleted(change.id); | |
} else { // updated/inserted | |
// change.doc holds the new doc | |
onUpdatedOrInserted(change.doc); | |
} | |
renderDocs(); | |
}).on('error', console.log.bind(console)); | |
} | |
function renderDocs() { | |
// this is a naive way to render documents. presumably | |
// your framework of choice (React, Angular, etc.) would have | |
// a more efficient way of doing this. | |
var ul = document.getElementById('the-list'); | |
ul.innerHTML = docs.map(function (doc) { | |
return '<li><pre>' + JSON.stringify(doc, undefined, ' ') + '</pre></li>' | |
}).join(''); | |
} | |
function insertRandomDoc() { | |
db.put({_id: Date.now().toString()}).catch(console.log.bind(console)); | |
} | |
function updateRandomDoc() { | |
if (!docs.length) { | |
return; | |
} | |
var randomDoc = docs[Math.floor(Math.random() * docs.length)]; | |
db.get(randomDoc._id).then(function (doc) { | |
if (!doc.updatedCount) { | |
doc.updatedCount = 0; | |
} | |
doc.updatedCount++; | |
return db.put(doc); | |
}).catch(console.log.bind(console)); | |
} | |
function deleteRandomDoc() { | |
if (!docs.length) { | |
return; | |
} | |
var randomDoc = docs[Math.floor(Math.random() * docs.length)]; | |
db.get(randomDoc._id).then(function (doc) { | |
return db.remove(doc); | |
}).catch(console.log.bind(console)); | |
} | |
fetchInitialDocs().then(reactToChanges).catch(console.log.bind(console)); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment