index.js 3.4 KB

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