index.js 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. const init = vm => {
  2. const bindings = vm.$options.pouchdb
  3. if (!bindings) {
  4. return
  5. }
  6. ensureRef(vm)
  7. for (const key in bindings) {
  8. makeReactive(vm, key, bindings[key])
  9. bind(vm, key, bindings[key])
  10. }
  11. }
  12. const ensureRef = vm => {
  13. if (!vm.$pouchdbRefs) {
  14. vm.$pouchdbRefs = Object.create(null)
  15. }
  16. }
  17. const bind = (vm, key, source) => {
  18. const localDB = new PouchDB(source.localDB)
  19. initDB(vm, key, localDB)
  20. vm.$pouchdbRefs[key] = Object.create(null)
  21. attachMethods(vm, key, localDB)
  22. if (!source.remoteURL) {
  23. return
  24. }
  25. const remoteDB = new PouchDB(source.remoteURL)
  26. syncDB(vm, key, localDB, remoteDB)
  27. }
  28. const makeReactive = (vm, key, val) => {
  29. if (key in vm) {
  30. return
  31. }
  32. Vue.util.defineReactive(vm, key, val)
  33. }
  34. function initDB(vm, key, localDB) {
  35. localDB.allDocs({
  36. include_docs: true,
  37. descending: true
  38. }).then(function (doc) {
  39. var objs = {}
  40. doc.rows.forEach(function (d) {
  41. objs[d.id] = d.doc
  42. })
  43. let uniques = [...new Set(Object.keys(objs).map(item => objs[item].doctype))]
  44. vm.$options.pouchdb.uniques = uniques
  45. let data = []
  46. Object.keys(objs).forEach(item => {
  47. uniques.forEach(unique => {
  48. if (objs[item].doctype === unique) {
  49. if (!vm[key][unique]) {
  50. Vue.set(vm[key], unique, Object.create(null))
  51. }
  52. Vue.set(vm[key][unique], item, objs[item])
  53. }
  54. })
  55. })
  56. })
  57. }
  58. function syncDB(vm, key, localDB, remoteDB) {
  59. localDB.sync(remoteDB, {
  60. live: true,
  61. retry: true,
  62. include_docs: true
  63. }).on('change', change => {
  64. handleChanges(vm, key, change)
  65. })
  66. }
  67. const handleChanges = (vm, key, change) => {
  68. const { docs } = change.change
  69. docs.forEach(function (doc) {
  70. if (doc['_deleted']) {
  71. vm.$options.pouchdb.uniques.forEach(unique => {
  72. if (vm[key][unique][doc['_id']]) {
  73. Vue.delete(vm[key][unique], doc['_id'])
  74. }
  75. })
  76. return
  77. }
  78. vm[key][doc['doctype']][doc['_id']] = doc
  79. })
  80. }
  81. const attachMethods = (vm, key, localDB) => {
  82. vm.$pouchdbRefs[key] = Object.create(null)
  83. vm.$pouchdbRefs[key].put = put.bind({
  84. localDB,
  85. vm,
  86. key
  87. })
  88. vm.$pouchdbRefs[key].get = get.bind({
  89. localDB,
  90. vm,
  91. key
  92. })
  93. vm.$pouchdbRefs[key].update = update.bind({
  94. localDB,
  95. vm,
  96. key
  97. })
  98. vm.$pouchdbRefs[key].remove = remove.bind({
  99. localDB,
  100. vm,
  101. key
  102. })
  103. }
  104. function put(docName, data) {
  105. data['_id'] = new Date().toISOString()
  106. data['doctype'] = docName
  107. const {
  108. localDB,
  109. vm,
  110. key
  111. } = this
  112. if (!vm[key][docName]) {
  113. Vue.set(vm[key], [docName], Object.create(null))
  114. }
  115. localDB.put(data).then(doc => {
  116. data['rev'] = doc['rev']
  117. Vue.set(vm[key][docName], [data['_id']], data)
  118. })
  119. }
  120. function get(docName, options) {
  121. }
  122. function update(doc) {
  123. const { localDB, key, vm } = this
  124. return localDB.put(doc)
  125. }
  126. function remove(doc) {
  127. const { localDB, key, vm } = this
  128. return localDB.remove(doc)
  129. }
  130. Vue.mixin({
  131. created() {
  132. init(this)
  133. }
  134. })