index.cjs 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. 'use strict';
  2. Object.defineProperty(exports, '__esModule', { value: true });
  3. var wrapIdbValue = require('./wrap-idb-value.cjs');
  4. /**
  5. * Open a database.
  6. *
  7. * @param name Name of the database.
  8. * @param version Schema version.
  9. * @param callbacks Additional callbacks.
  10. */
  11. function openDB(name, version, { blocked, upgrade, blocking, terminated } = {}) {
  12. const request = indexedDB.open(name, version);
  13. const openPromise = wrapIdbValue.wrap(request);
  14. if (upgrade) {
  15. request.addEventListener('upgradeneeded', (event) => {
  16. upgrade(wrapIdbValue.wrap(request.result), event.oldVersion, event.newVersion, wrapIdbValue.wrap(request.transaction), event);
  17. });
  18. }
  19. if (blocked) {
  20. request.addEventListener('blocked', (event) => blocked(
  21. // Casting due to https://github.com/microsoft/TypeScript-DOM-lib-generator/pull/1405
  22. event.oldVersion, event.newVersion, event));
  23. }
  24. openPromise
  25. .then((db) => {
  26. if (terminated)
  27. db.addEventListener('close', () => terminated());
  28. if (blocking) {
  29. db.addEventListener('versionchange', (event) => blocking(event.oldVersion, event.newVersion, event));
  30. }
  31. })
  32. .catch(() => { });
  33. return openPromise;
  34. }
  35. /**
  36. * Delete a database.
  37. *
  38. * @param name Name of the database.
  39. */
  40. function deleteDB(name, { blocked } = {}) {
  41. const request = indexedDB.deleteDatabase(name);
  42. if (blocked) {
  43. request.addEventListener('blocked', (event) => blocked(
  44. // Casting due to https://github.com/microsoft/TypeScript-DOM-lib-generator/pull/1405
  45. event.oldVersion, event));
  46. }
  47. return wrapIdbValue.wrap(request).then(() => undefined);
  48. }
  49. const readMethods = ['get', 'getKey', 'getAll', 'getAllKeys', 'count'];
  50. const writeMethods = ['put', 'add', 'delete', 'clear'];
  51. const cachedMethods = new Map();
  52. function getMethod(target, prop) {
  53. if (!(target instanceof IDBDatabase &&
  54. !(prop in target) &&
  55. typeof prop === 'string')) {
  56. return;
  57. }
  58. if (cachedMethods.get(prop))
  59. return cachedMethods.get(prop);
  60. const targetFuncName = prop.replace(/FromIndex$/, '');
  61. const useIndex = prop !== targetFuncName;
  62. const isWrite = writeMethods.includes(targetFuncName);
  63. if (
  64. // Bail if the target doesn't exist on the target. Eg, getAll isn't in Edge.
  65. !(targetFuncName in (useIndex ? IDBIndex : IDBObjectStore).prototype) ||
  66. !(isWrite || readMethods.includes(targetFuncName))) {
  67. return;
  68. }
  69. const method = async function (storeName, ...args) {
  70. // isWrite ? 'readwrite' : undefined gzipps better, but fails in Edge :(
  71. const tx = this.transaction(storeName, isWrite ? 'readwrite' : 'readonly');
  72. let target = tx.store;
  73. if (useIndex)
  74. target = target.index(args.shift());
  75. // Must reject if op rejects.
  76. // If it's a write operation, must reject if tx.done rejects.
  77. // Must reject with op rejection first.
  78. // Must resolve with op value.
  79. // Must handle both promises (no unhandled rejections)
  80. return (await Promise.all([
  81. target[targetFuncName](...args),
  82. isWrite && tx.done,
  83. ]))[0];
  84. };
  85. cachedMethods.set(prop, method);
  86. return method;
  87. }
  88. wrapIdbValue.replaceTraps((oldTraps) => ({
  89. ...oldTraps,
  90. get: (target, prop, receiver) => getMethod(target, prop) || oldTraps.get(target, prop, receiver),
  91. has: (target, prop) => !!getMethod(target, prop) || oldTraps.has(target, prop),
  92. }));
  93. exports.unwrap = wrapIdbValue.unwrap;
  94. exports.wrap = wrapIdbValue.wrap;
  95. exports.deleteDB = deleteDB;
  96. exports.openDB = openDB;