Source: storage-wallet.js

  1. import DockWallet from './dock-wallet';
  2. /** The Dock Wallet which loads, adds, removes and queries contents in an EDV */
  3. class StorageWallet extends DockWallet {
  4. constructor(id, storageInterface) {
  5. super(id);
  6. this.promises = [];
  7. this.storageInterface = storageInterface;
  8. }
  9. add(content) {
  10. super.add(content);
  11. this.promises.push(this.insertToStorage(content));
  12. }
  13. remove(contentId) {
  14. super.remove(contentId);
  15. this.promises.push(this.removeFromStorage(contentId));
  16. }
  17. update(content) {
  18. super.update(content);
  19. this.promises.push(this.updateInStorage(content));
  20. }
  21. async query(search) {
  22. // tODO: query the in memory contents first and pass flag to not use it, if empty run storage search
  23. // Query storage interface and map into wallet contents
  24. const { documents } = await this.storageInterface.find(search);
  25. return documents.map((document) => document.content);
  26. }
  27. async load() {
  28. // Find all documents, storage interfaces should return all docs when no params supplied
  29. const { documents } = await this.storageInterface.find();
  30. // Format to wallet contents
  31. if (documents) {
  32. documents.forEach((document) => super.add(document.content));
  33. }
  34. return this.contents;
  35. }
  36. async updateInStorage(content) {
  37. const documentResult = await this.getStorageDocument(content);
  38. await this.storageInterface.update({
  39. document: {
  40. ...documentResult,
  41. content,
  42. },
  43. });
  44. }
  45. async insertToStorage(content) {
  46. // Attempt to insert the document to the storage interface
  47. // if the promise fails, then the content will be removed and error re-thrown
  48. try {
  49. await this.storageInterface.insert({
  50. document: {
  51. content,
  52. },
  53. });
  54. } catch (e) {
  55. super.remove(content.id);
  56. throw e;
  57. }
  58. }
  59. async removeFromStorage(id) {
  60. await this.storageInterface.delete({
  61. document: await this.getStorageDocument({ id }),
  62. });
  63. }
  64. async getStorageDocument({ id }) {
  65. // Find the storage document by the content ID
  66. // some interfaces may just return the same document, but some need custom structures
  67. const { documents } = await this.storageInterface.find({
  68. equals: {
  69. 'content.id': id,
  70. },
  71. });
  72. // Delete first result from storage
  73. if (documents.length) {
  74. return documents[0];
  75. } else {
  76. throw new Error(`Unable to find storage document by content.id: ${id}`);
  77. }
  78. }
  79. async sync() {
  80. // A user will call this method to ensure storage interface requests finish
  81. // we do this because wallet doesnt always require blocking operations
  82. // depending on the storage interface used
  83. const { promises } = this;
  84. this.promises = [];
  85. if (promises.length) {
  86. await Promise.all(promises);
  87. }
  88. }
  89. }
  90. export default StorageWallet;