bookManager.js 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. import localForage from 'localforage';
  2. import * as utils from '../../../share/utils';
  3. import BookParser from './BookParser';
  4. const maxDataSize = 100*1024*1024;//chars, not bytes
  5. class BookManager {
  6. async init() {
  7. this.books = {};
  8. const len = await localForage.length();
  9. for (let i = 0; i < len; i++) {
  10. const key = await localForage.key(i);
  11. const keySplit = key.split('-');
  12. if (keySplit.length == 2 && keySplit[0] == 'bmMeta') {
  13. let meta = await localForage.getItem(key);
  14. meta.data = await localForage.getItem(`bmData-${keySplit[1]}`);
  15. this.books[meta.key] = meta;
  16. }
  17. }
  18. await this.cleanBooks();
  19. }
  20. async cleanBooks() {
  21. while (1) {// eslint-disable-line no-constant-condition
  22. let size = 0;
  23. let min = Date.now();
  24. let toDel = null;
  25. for (let key in this.books) {
  26. let book = this.books[key];
  27. size += book.data.length;
  28. if (book.addTime < min) {
  29. toDel = book;
  30. min = book.addTime;
  31. }
  32. }
  33. if (size > maxDataSize && toDel) {
  34. await this.delBook(toDel);
  35. } else {
  36. break;
  37. }
  38. }
  39. }
  40. async addBook(newBook, callback) {
  41. if (!this.books)
  42. await this.init();
  43. let meta = {url: newBook.url, path: newBook.path};
  44. meta.key = this.keyFromUrl(meta.url);
  45. meta.addTime = Date.now();
  46. const result = await this.parseBook(meta, newBook.data, callback);
  47. await localForage.setItem(`bmMeta-${meta.key}`, this.metaOnly(result));
  48. await localForage.setItem(`bmData-${meta.key}`, result.data);
  49. return result;
  50. }
  51. async getBook(meta, callback) {
  52. if (!this.books)
  53. await this.init();
  54. let result = undefined;
  55. if (!meta.key)
  56. meta.key = this.keyFromUrl(meta.url);
  57. result = this.books[meta.key];
  58. if (result && !result.parsed) {
  59. result = await this.parseBook(result, result.data, callback);
  60. }
  61. return result;
  62. }
  63. async delBook(meta) {
  64. if (!this.books)
  65. await this.init();
  66. await localForage.removeItem(`bmMeta-${meta.key}`);
  67. await localForage.removeItem(`bmData-${meta.key}`);
  68. delete this.books[meta.key];
  69. }
  70. async parseBook(meta, data, callback) {
  71. if (!this.books)
  72. await this.init();
  73. const parsed = new BookParser();
  74. const parsedMeta = await parsed.parse(data, callback);
  75. const result = Object.assign({}, meta, parsedMeta, {data, parsed});
  76. this.books[meta.key] = result;
  77. return result;
  78. }
  79. metaOnly(book) {
  80. let result = Object.assign({}, book);
  81. delete result.data;
  82. delete result.parsed;
  83. return result;
  84. }
  85. keyFromUrl(url) {
  86. return utils.stringToHex(url);
  87. }
  88. }
  89. export default new BookManager();