bookManager.js 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  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. this.books[meta.key] = meta;
  15. }
  16. }
  17. await this.cleanBooks();
  18. }
  19. async cleanBooks() {
  20. while (1) {// eslint-disable-line no-constant-condition
  21. let size = 0;
  22. let min = Date.now();
  23. let toDel = null;
  24. for (let key in this.books) {
  25. let book = this.books[key];
  26. size += (book.length ? book.length : 0);
  27. if (book.addTime < min) {
  28. toDel = book;
  29. min = book.addTime;
  30. }
  31. }
  32. if (size > maxDataSize && toDel) {
  33. await this.delBook(toDel);
  34. } else {
  35. break;
  36. }
  37. }
  38. }
  39. async addBook(newBook, callback) {
  40. if (!this.books)
  41. await this.init();
  42. let meta = {url: newBook.url, path: newBook.path};
  43. meta.key = this.keyFromUrl(meta.url);
  44. meta.addTime = Date.now();
  45. const result = await this.parseBook(meta, newBook.data, callback);
  46. this.books[meta.key] = result;
  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.data) {
  59. result.data = await localForage.getItem(`bmData-${meta.key}`);
  60. this.books[meta.key] = result;
  61. }
  62. if (result && !result.parsed) {
  63. result = await this.parseBook(result, result.data, callback);
  64. this.books[meta.key] = result;
  65. }
  66. return result;
  67. }
  68. async delBook(meta) {
  69. if (!this.books)
  70. await this.init();
  71. await localForage.removeItem(`bmMeta-${meta.key}`);
  72. await localForage.removeItem(`bmData-${meta.key}`);
  73. delete this.books[meta.key];
  74. }
  75. async parseBook(meta, data, callback) {
  76. if (!this.books)
  77. await this.init();
  78. const parsed = new BookParser();
  79. const parsedMeta = await parsed.parse(data, callback);
  80. const result = Object.assign({}, meta, parsedMeta, {length: data.length, data, parsed});
  81. return result;
  82. }
  83. metaOnly(book) {
  84. let result = Object.assign({}, book);
  85. delete result.data;
  86. delete result.parsed;
  87. return result;
  88. }
  89. keyFromUrl(url) {
  90. return utils.stringToHex(url);
  91. }
  92. }
  93. export default new BookManager();