QueueStore.js 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. /*
  2. Copyright 2018 Google LLC
  3. Use of this source code is governed by an MIT-style
  4. license that can be found in the LICENSE file or at
  5. https://opensource.org/licenses/MIT.
  6. */
  7. import { assert } from 'workbox-core/_private/assert.js';
  8. import { QueueDb, } from './QueueDb.js';
  9. import '../_version.js';
  10. /**
  11. * A class to manage storing requests from a Queue in IndexedDB,
  12. * indexed by their queue name for easier access.
  13. *
  14. * Most developers will not need to access this class directly;
  15. * it is exposed for advanced use cases.
  16. */
  17. export class QueueStore {
  18. /**
  19. * Associates this instance with a Queue instance, so entries added can be
  20. * identified by their queue name.
  21. *
  22. * @param {string} queueName
  23. */
  24. constructor(queueName) {
  25. this._queueName = queueName;
  26. this._queueDb = new QueueDb();
  27. }
  28. /**
  29. * Append an entry last in the queue.
  30. *
  31. * @param {Object} entry
  32. * @param {Object} entry.requestData
  33. * @param {number} [entry.timestamp]
  34. * @param {Object} [entry.metadata]
  35. */
  36. async pushEntry(entry) {
  37. if (process.env.NODE_ENV !== 'production') {
  38. assert.isType(entry, 'object', {
  39. moduleName: 'workbox-background-sync',
  40. className: 'QueueStore',
  41. funcName: 'pushEntry',
  42. paramName: 'entry',
  43. });
  44. assert.isType(entry.requestData, 'object', {
  45. moduleName: 'workbox-background-sync',
  46. className: 'QueueStore',
  47. funcName: 'pushEntry',
  48. paramName: 'entry.requestData',
  49. });
  50. }
  51. // Don't specify an ID since one is automatically generated.
  52. delete entry.id;
  53. entry.queueName = this._queueName;
  54. await this._queueDb.addEntry(entry);
  55. }
  56. /**
  57. * Prepend an entry first in the queue.
  58. *
  59. * @param {Object} entry
  60. * @param {Object} entry.requestData
  61. * @param {number} [entry.timestamp]
  62. * @param {Object} [entry.metadata]
  63. */
  64. async unshiftEntry(entry) {
  65. if (process.env.NODE_ENV !== 'production') {
  66. assert.isType(entry, 'object', {
  67. moduleName: 'workbox-background-sync',
  68. className: 'QueueStore',
  69. funcName: 'unshiftEntry',
  70. paramName: 'entry',
  71. });
  72. assert.isType(entry.requestData, 'object', {
  73. moduleName: 'workbox-background-sync',
  74. className: 'QueueStore',
  75. funcName: 'unshiftEntry',
  76. paramName: 'entry.requestData',
  77. });
  78. }
  79. const firstId = await this._queueDb.getFirstEntryId();
  80. if (firstId) {
  81. // Pick an ID one less than the lowest ID in the object store.
  82. entry.id = firstId - 1;
  83. }
  84. else {
  85. // Otherwise let the auto-incrementor assign the ID.
  86. delete entry.id;
  87. }
  88. entry.queueName = this._queueName;
  89. await this._queueDb.addEntry(entry);
  90. }
  91. /**
  92. * Removes and returns the last entry in the queue matching the `queueName`.
  93. *
  94. * @return {Promise<QueueStoreEntry|undefined>}
  95. */
  96. async popEntry() {
  97. return this._removeEntry(await this._queueDb.getLastEntryByQueueName(this._queueName));
  98. }
  99. /**
  100. * Removes and returns the first entry in the queue matching the `queueName`.
  101. *
  102. * @return {Promise<QueueStoreEntry|undefined>}
  103. */
  104. async shiftEntry() {
  105. return this._removeEntry(await this._queueDb.getFirstEntryByQueueName(this._queueName));
  106. }
  107. /**
  108. * Returns all entries in the store matching the `queueName`.
  109. *
  110. * @param {Object} options See {@link workbox-background-sync.Queue~getAll}
  111. * @return {Promise<Array<Object>>}
  112. */
  113. async getAll() {
  114. return await this._queueDb.getAllEntriesByQueueName(this._queueName);
  115. }
  116. /**
  117. * Returns the number of entries in the store matching the `queueName`.
  118. *
  119. * @param {Object} options See {@link workbox-background-sync.Queue~size}
  120. * @return {Promise<number>}
  121. */
  122. async size() {
  123. return await this._queueDb.getEntryCountByQueueName(this._queueName);
  124. }
  125. /**
  126. * Deletes the entry for the given ID.
  127. *
  128. * WARNING: this method does not ensure the deleted entry belongs to this
  129. * queue (i.e. matches the `queueName`). But this limitation is acceptable
  130. * as this class is not publicly exposed. An additional check would make
  131. * this method slower than it needs to be.
  132. *
  133. * @param {number} id
  134. */
  135. async deleteEntry(id) {
  136. await this._queueDb.deleteEntry(id);
  137. }
  138. /**
  139. * Removes and returns the first or last entry in the queue (based on the
  140. * `direction` argument) matching the `queueName`.
  141. *
  142. * @return {Promise<QueueStoreEntry|undefined>}
  143. * @private
  144. */
  145. async _removeEntry(entry) {
  146. if (entry) {
  147. await this.deleteEntry(entry.id);
  148. }
  149. return entry;
  150. }
  151. }