preact-missing-hooks 3.0.0 → 4.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (79) hide show
  1. package/.husky/pre-commit +1 -0
  2. package/.husky/pre-push +1 -0
  3. package/.prettierignore +3 -0
  4. package/.prettierrc +6 -0
  5. package/Readme.md +179 -131
  6. package/dist/entry.cjs +21 -0
  7. package/dist/entry.js +2 -0
  8. package/dist/entry.js.map +1 -0
  9. package/dist/entry.modern.mjs +2 -0
  10. package/dist/entry.modern.mjs.map +1 -0
  11. package/dist/entry.module.js +2 -0
  12. package/dist/entry.module.js.map +1 -0
  13. package/dist/entry.umd.js +2 -0
  14. package/dist/entry.umd.js.map +1 -0
  15. package/dist/index.d.ts +13 -12
  16. package/dist/index.js +1 -1
  17. package/dist/index.js.map +1 -1
  18. package/dist/index.modern.mjs +2 -0
  19. package/dist/index.modern.mjs.map +1 -0
  20. package/dist/index.module.js +1 -1
  21. package/dist/index.module.js.map +1 -1
  22. package/dist/index.umd.js +1 -1
  23. package/dist/index.umd.js.map +1 -1
  24. package/dist/indexedDB/dbController.d.ts +2 -2
  25. package/dist/indexedDB/index.d.ts +6 -6
  26. package/dist/indexedDB/openDB.d.ts +1 -1
  27. package/dist/indexedDB/tableController.d.ts +1 -1
  28. package/dist/indexedDB/types.d.ts +1 -2
  29. package/dist/react.js +1 -0
  30. package/dist/react.modern.mjs +1 -0
  31. package/dist/react.module.js +1 -0
  32. package/dist/react.umd.js +1 -0
  33. package/dist/useEventBus.d.ts +1 -1
  34. package/dist/useIndexedDB.d.ts +3 -3
  35. package/dist/useMutationObserver.d.ts +1 -1
  36. package/dist/useNetworkState.d.ts +3 -3
  37. package/dist/usePreferredTheme.d.ts +1 -1
  38. package/dist/useRageClick.d.ts +1 -1
  39. package/dist/useThreadedWorker.d.ts +1 -1
  40. package/dist/useTransition.d.ts +4 -1
  41. package/dist/useWorkerNotifications.d.ts +57 -0
  42. package/dist/useWrappedChildren.d.ts +3 -3
  43. package/{demo → docs}/index.html +56 -0
  44. package/{demo → docs}/main.js +437 -312
  45. package/eslint.config.mjs +10 -0
  46. package/package.json +65 -6
  47. package/scripts/generate-entry.cjs +34 -0
  48. package/src/index.ts +13 -12
  49. package/src/indexedDB/dbController.ts +101 -92
  50. package/src/indexedDB/index.ts +16 -11
  51. package/src/indexedDB/openDB.ts +49 -49
  52. package/src/indexedDB/requestToPromise.ts +17 -16
  53. package/src/indexedDB/tableController.ts +331 -257
  54. package/src/indexedDB/types.ts +35 -35
  55. package/src/useClipboard.ts +99 -97
  56. package/src/useEventBus.ts +39 -36
  57. package/src/useIndexedDB.ts +111 -111
  58. package/src/useMutationObserver.ts +26 -26
  59. package/src/useNetworkState.ts +124 -122
  60. package/src/usePreferredTheme.ts +68 -68
  61. package/src/useRageClick.ts +103 -103
  62. package/src/useThreadedWorker.ts +165 -165
  63. package/src/useTransition.ts +22 -19
  64. package/src/useWasmCompute.ts +209 -204
  65. package/src/useWebRTCIP.ts +181 -176
  66. package/src/useWorkerNotifications.ts +203 -0
  67. package/src/useWrappedChildren.ts +72 -58
  68. package/tests/react-adapter.tsx +12 -0
  69. package/tests/setup-react.ts +4 -0
  70. package/tests/useClipboard.test.tsx +4 -2
  71. package/tests/useThreadedWorker.test.tsx +3 -1
  72. package/tests/useWasmCompute.test.tsx +1 -1
  73. package/tests/useWebRTCIP.test.tsx +3 -1
  74. package/tests/useWorkerNotifications.test.tsx +170 -0
  75. package/vite.config.ts +11 -4
  76. package/vitest.config.preact.ts +20 -0
  77. package/vitest.config.react.ts +36 -0
  78. package/vitest.workspace.ts +6 -0
  79. /package/{demo → docs}/add.wasm +0 -0
@@ -0,0 +1,10 @@
1
+ import eslint from "@eslint/js";
2
+ import { defineConfig } from "eslint/config";
3
+ import tseslint from "typescript-eslint";
4
+ import prettier from "eslint-config-prettier";
5
+
6
+ export default defineConfig(
7
+ eslint.configs.recommended,
8
+ tseslint.configs.recommended,
9
+ prettier
10
+ );
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "preact-missing-hooks",
3
- "version": "3.0.0",
3
+ "version": "4.0.0",
4
4
  "description": "A lightweight, extendable collection of missing React-like hooks for Preact — plus fresh, powerful new ones designed specifically for modern Preact apps.",
5
5
  "author": "Prakhar Dubey",
6
6
  "license": "MIT",
@@ -11,8 +11,11 @@
11
11
  "exports": {
12
12
  ".": {
13
13
  "types": "./dist/index.d.ts",
14
- "import": "./dist/index.module.js",
15
- "require": "./dist/index.js"
14
+ "import": {
15
+ "react": "./dist/react.module.js",
16
+ "default": "./dist/index.module.js"
17
+ },
18
+ "require": "./dist/entry.cjs"
16
19
  },
17
20
  "./useTransition": {
18
21
  "types": "./dist/useTransition.d.ts",
@@ -73,16 +76,52 @@
73
76
  "types": "./dist/useWasmCompute.d.ts",
74
77
  "import": "./dist/useWasmCompute.module.js",
75
78
  "require": "./dist/useWasmCompute.js"
79
+ },
80
+ "./useWorkerNotifications": {
81
+ "types": "./dist/useWorkerNotifications.d.ts",
82
+ "import": "./dist/useWorkerNotifications.module.js",
83
+ "require": "./dist/useWorkerNotifications.js"
84
+ },
85
+ "./react": {
86
+ "types": "./dist/index.d.ts",
87
+ "import": "./dist/react.module.js",
88
+ "require": "./dist/react.js"
76
89
  }
77
90
  },
78
91
  "scripts": {
79
- "build": "microbundle",
92
+ "build": "microbundle && npm run build:react && node scripts/generate-entry.cjs",
93
+ "build:react": "microbundle -i src/index.ts -o dist/react.js --alias preact=react,preact/hooks=react --no-sourcemap",
80
94
  "dev": "microbundle watch",
81
95
  "prepublishOnly": "npm run build",
82
96
  "test": "vitest run",
97
+ "test:preact": "vitest run --project preact",
98
+ "test:react": "vitest run --project react",
83
99
  "type-check": "tsc --noEmit",
84
- "demo": "npx serve -l 5000"
100
+ "demo": "npx serve -l 5000",
101
+ "lint": "eslint src",
102
+ "format": "prettier --write \"src/**/*.{ts,tsx,json,md}\"",
103
+ "format:check": "prettier --check \"src/**/*.{ts,tsx,json,md}\"",
104
+ "prepare": "husky",
105
+ "size": "npm run build && size-limit"
85
106
  },
107
+ "size-limit": [
108
+ {
109
+ "path": "dist/index.module.js",
110
+ "limit": "20 KB"
111
+ },
112
+ {
113
+ "path": "dist/index.js",
114
+ "limit": "20 KB"
115
+ },
116
+ {
117
+ "path": "dist/react.module.js",
118
+ "limit": "20 KB"
119
+ },
120
+ {
121
+ "path": "dist/react.js",
122
+ "limit": "20 KB"
123
+ }
124
+ ],
86
125
  "keywords": [
87
126
  "preact",
88
127
  "hooks",
@@ -109,16 +148,36 @@
109
148
  "preact": ">=10.0.0"
110
149
  },
111
150
  "devDependencies": {
151
+ "@eslint/js": "^9.15.0",
152
+ "@size-limit/file": "^11.2.0",
112
153
  "@testing-library/jest-dom": "^6.6.3",
113
154
  "@testing-library/preact": "^3.2.4",
155
+ "@testing-library/react": "^16.0.1",
114
156
  "@types/jest": "^29.5.14",
157
+ "eslint": "^9.15.0",
158
+ "eslint-config-prettier": "^9.1.0",
115
159
  "fake-indexeddb": "^6.0.2",
160
+ "husky": "^9.1.7",
116
161
  "jsdom": "^26.1.0",
117
162
  "microbundle": "^0.15.1",
163
+ "prettier": "^3.3.3",
164
+ "react": "^18.3.1",
165
+ "react-dom": "^18.3.1",
166
+ "size-limit": "^11.2.0",
118
167
  "typescript": "^5.8.3",
168
+ "typescript-eslint": "^8.15.0",
119
169
  "vitest": "^3.1.4"
120
170
  },
121
171
  "peerDependencies": {
122
- "preact": ">=10.0.0"
172
+ "preact": ">=10.0.0",
173
+ "react": ">=17.0.0"
174
+ },
175
+ "peerDependenciesMeta": {
176
+ "preact": {
177
+ "optional": true
178
+ },
179
+ "react": {
180
+ "optional": true
181
+ }
123
182
  }
124
183
  }
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Generates dist/entry.cjs which auto-detects Preact vs React at runtime (CJS only).
3
+ * Run after build so dist/index.js and dist/react.js exist.
4
+ */
5
+ const fs = require("fs");
6
+ const path = require("path");
7
+
8
+ const content = `"use strict";
9
+ /**
10
+ * Auto-detect Preact vs React and re-export the matching build.
11
+ * Used for require('preact-missing-hooks') in Node / CJS bundlers.
12
+ */
13
+ function detect() {
14
+ try {
15
+ require.resolve("preact");
16
+ return require("./index.js");
17
+ } catch (_) {
18
+ try {
19
+ require.resolve("react");
20
+ return require("./react.js");
21
+ } catch (_) {
22
+ throw new Error(
23
+ "preact-missing-hooks: Install either \\"preact\\" or \\"react\\" in your project."
24
+ );
25
+ }
26
+ }
27
+ }
28
+ module.exports = detect();
29
+ `;
30
+
31
+ const outPath = path.join(__dirname, "..", "dist", "entry.cjs");
32
+ fs.mkdirSync(path.dirname(outPath), { recursive: true });
33
+ fs.writeFileSync(outPath, content, "utf8");
34
+ console.log("Generated dist/entry.cjs");
package/src/index.ts CHANGED
@@ -1,12 +1,13 @@
1
- export * from './useTransition'
2
- export * from './useMutationObserver'
3
- export * from './useEventBus'
4
- export * from './useWrappedChildren'
5
- export * from './usePreferredTheme'
6
- export * from './useNetworkState'
7
- export * from './useClipboard'
8
- export * from './useRageClick'
9
- export * from './useThreadedWorker'
10
- export * from './useIndexedDB'
11
- export * from './useWebRTCIP'
12
- export * from './useWasmCompute'
1
+ export * from "./useTransition";
2
+ export * from "./useMutationObserver";
3
+ export * from "./useEventBus";
4
+ export * from "./useWrappedChildren";
5
+ export * from "./usePreferredTheme";
6
+ export * from "./useNetworkState";
7
+ export * from "./useClipboard";
8
+ export * from "./useRageClick";
9
+ export * from "./useThreadedWorker";
10
+ export * from "./useIndexedDB";
11
+ export * from "./useWebRTCIP";
12
+ export * from "./useWasmCompute";
13
+ export * from "./useWorkerNotifications";
@@ -1,92 +1,101 @@
1
- /**
2
- * Database controller: table(name), transaction(storeNames, mode, callback, options).
3
- * @module indexedDB/dbController
4
- */
5
-
6
- import type { IndexedDBConfig, TransactionOptions } from './types';
7
- import type { ITableController } from './tableController';
8
- import { createTableController, createTransactionTableController } from './tableController';
9
-
10
- /** Transaction context passed to the callback: provides table(name) bound to this transaction. */
11
- export interface TransactionContext {
12
- /** Returns a table controller bound to this transaction. Use for all ops inside the callback. */
13
- table: (name: string) => ITableController;
14
- }
15
-
16
- /**
17
- * Database controller built from an open IDBDatabase.
18
- * Exposes table(name) and transaction(...).
19
- */
20
- export interface IDBController {
21
- /** Underlying IDBDatabase (read-only). */
22
- readonly db: IDBDatabase;
23
- /** Returns true if an object store with the given name exists. */
24
- hasTable: (name: string) => boolean;
25
- /** Returns a table controller for the given store (each op opens its own transaction). */
26
- table: (name: string) => ITableController;
27
- /**
28
- * Runs a callback inside a single transaction. All operations in the callback use the same transaction.
29
- * @param storeNames - Object store names to include in the transaction.
30
- * @param mode - 'readonly' | 'readwrite'.
31
- * @param callback - Async or sync function receiving { table(name) }. Return value is ignored; await all ops inside.
32
- * @param options - Optional onSuccess/onError callbacks.
33
- * @returns Promise that resolves when the transaction completes (after all requests and the callback).
34
- */
35
- transaction: <T = void>(
36
- storeNames: string[],
37
- mode: IDBTransactionMode,
38
- callback: (tx: TransactionContext) => T | Promise<T>,
39
- options?: TransactionOptions
40
- ) => Promise<void>;
41
- }
42
-
43
- function withTransactionCallbacks(
44
- promise: Promise<void>,
45
- options?: TransactionOptions
46
- ): Promise<void> {
47
- if (!options) return promise;
48
- return promise
49
- .then(() => options.onSuccess?.())
50
- .catch((err: DOMException) => {
51
- options.onError?.(err);
52
- throw err;
53
- });
54
- }
55
-
56
- /**
57
- * Creates a database controller from an open IDBDatabase instance.
58
- */
59
- export function createDBController(db: IDBDatabase, _config: IndexedDBConfig): IDBController {
60
- return {
61
- get db(): IDBDatabase {
62
- return db;
63
- },
64
-
65
- hasTable(name: string): boolean {
66
- return db.objectStoreNames.contains(name);
67
- },
68
-
69
- table(name: string): ITableController {
70
- return createTableController(db, name);
71
- },
72
-
73
- transaction<T = void>(
74
- storeNames: string[],
75
- mode: IDBTransactionMode,
76
- callback: (tx: TransactionContext) => T | Promise<T>,
77
- options?: TransactionOptions
78
- ): Promise<void> {
79
- const tx = db.transaction(storeNames, mode);
80
- const txContext: TransactionContext = {
81
- table: (tableName: string) => createTransactionTableController(tx, tableName),
82
- };
83
- const txPromise = new Promise<void>((resolve, reject) => {
84
- tx.oncomplete = () => resolve();
85
- tx.onerror = () => reject(tx.error ?? new DOMException('Transaction failed'));
86
- });
87
- const callbackResult = callback(txContext);
88
- const promise = Promise.resolve(callbackResult).then(() => txPromise);
89
- return withTransactionCallbacks(promise, options);
90
- },
91
- };
92
- }
1
+ /**
2
+ * Database controller: table(name), transaction(storeNames, mode, callback, options).
3
+ * @module indexedDB/dbController
4
+ */
5
+
6
+ import type { IndexedDBConfig, TransactionOptions } from "./types";
7
+ import type { ITableController } from "./tableController";
8
+ import {
9
+ createTableController,
10
+ createTransactionTableController,
11
+ } from "./tableController";
12
+
13
+ /** Transaction context passed to the callback: provides table(name) bound to this transaction. */
14
+ export interface TransactionContext {
15
+ /** Returns a table controller bound to this transaction. Use for all ops inside the callback. */
16
+ table: (name: string) => ITableController;
17
+ }
18
+
19
+ /**
20
+ * Database controller built from an open IDBDatabase.
21
+ * Exposes table(name) and transaction(...).
22
+ */
23
+ export interface IDBController {
24
+ /** Underlying IDBDatabase (read-only). */
25
+ readonly db: IDBDatabase;
26
+ /** Returns true if an object store with the given name exists. */
27
+ hasTable: (name: string) => boolean;
28
+ /** Returns a table controller for the given store (each op opens its own transaction). */
29
+ table: (name: string) => ITableController;
30
+ /**
31
+ * Runs a callback inside a single transaction. All operations in the callback use the same transaction.
32
+ * @param storeNames - Object store names to include in the transaction.
33
+ * @param mode - 'readonly' | 'readwrite'.
34
+ * @param callback - Async or sync function receiving { table(name) }. Return value is ignored; await all ops inside.
35
+ * @param options - Optional onSuccess/onError callbacks.
36
+ * @returns Promise that resolves when the transaction completes (after all requests and the callback).
37
+ */
38
+ transaction: <T = void>(
39
+ storeNames: string[],
40
+ mode: IDBTransactionMode,
41
+ callback: (tx: TransactionContext) => T | Promise<T>,
42
+ options?: TransactionOptions
43
+ ) => Promise<void>;
44
+ }
45
+
46
+ function withTransactionCallbacks(
47
+ promise: Promise<void>,
48
+ options?: TransactionOptions
49
+ ): Promise<void> {
50
+ if (!options) return promise;
51
+ return promise
52
+ .then(() => options.onSuccess?.())
53
+ .catch((err: DOMException) => {
54
+ options.onError?.(err);
55
+ throw err;
56
+ });
57
+ }
58
+
59
+ /**
60
+ * Creates a database controller from an open IDBDatabase instance.
61
+ */
62
+ export function createDBController(
63
+ db: IDBDatabase,
64
+ _config: IndexedDBConfig
65
+ ): IDBController {
66
+ void _config; // Reserved for future config options
67
+ return {
68
+ get db(): IDBDatabase {
69
+ return db;
70
+ },
71
+
72
+ hasTable(name: string): boolean {
73
+ return db.objectStoreNames.contains(name);
74
+ },
75
+
76
+ table(name: string): ITableController {
77
+ return createTableController(db, name);
78
+ },
79
+
80
+ transaction<T = void>(
81
+ storeNames: string[],
82
+ mode: IDBTransactionMode,
83
+ callback: (tx: TransactionContext) => T | Promise<T>,
84
+ options?: TransactionOptions
85
+ ): Promise<void> {
86
+ const tx = db.transaction(storeNames, mode);
87
+ const txContext: TransactionContext = {
88
+ table: (tableName: string) =>
89
+ createTransactionTableController(tx, tableName),
90
+ };
91
+ const txPromise = new Promise<void>((resolve, reject) => {
92
+ tx.oncomplete = () => resolve();
93
+ tx.onerror = () =>
94
+ reject(tx.error ?? new DOMException("Transaction failed"));
95
+ });
96
+ const callbackResult = callback(txContext);
97
+ const promise = Promise.resolve(callbackResult).then(() => txPromise);
98
+ return withTransactionCallbacks(promise, options);
99
+ },
100
+ };
101
+ }
@@ -1,11 +1,16 @@
1
- /**
2
- * IndexedDB hook system – public API.
3
- * @module indexedDB
4
- */
5
-
6
- export type { IndexedDBConfig, TableSchema, OperationCallbacks, TransactionOptions } from './types';
7
- export { requestToPromise } from './requestToPromise';
8
- export type { ITableController } from './tableController';
9
- export type { IDBController, TransactionContext } from './dbController';
10
- export { createDBController } from './dbController';
11
- export { openDB } from './openDB';
1
+ /**
2
+ * IndexedDB hook system – public API.
3
+ * @module indexedDB
4
+ */
5
+
6
+ export type {
7
+ IndexedDBConfig,
8
+ TableSchema,
9
+ OperationCallbacks,
10
+ TransactionOptions,
11
+ } from "./types";
12
+ export { requestToPromise } from "./requestToPromise";
13
+ export type { ITableController } from "./tableController";
14
+ export type { IDBController, TransactionContext } from "./dbController";
15
+ export { createDBController } from "./dbController";
16
+ export { openDB } from "./openDB";
@@ -1,49 +1,49 @@
1
- /**
2
- * Opens IndexedDB and runs onupgradeneeded to create stores and indexes.
3
- * Singleton per (name, version).
4
- * @module indexedDB/openDB
5
- */
6
-
7
- import type { IndexedDBConfig, TableSchema } from './types';
8
- import { requestToPromise } from './requestToPromise';
9
-
10
- const connectionCache = new Map<string, Promise<IDBDatabase>>();
11
-
12
- /**
13
- * Opens the database and creates/upgrades object stores and indexes from config.
14
- * Uses a singleton cache per (name, version); repeated calls with the same config reuse the same connection.
15
- */
16
- export function openDB(config: IndexedDBConfig): Promise<IDBDatabase> {
17
- const key = `${config.name}_v${config.version}`;
18
- let promise = connectionCache.get(key);
19
- if (promise) return promise;
20
- promise = _openDB(config);
21
- connectionCache.set(key, promise);
22
- return promise;
23
- }
24
-
25
- function _openDB(config: IndexedDBConfig): Promise<IDBDatabase> {
26
- return new Promise<IDBDatabase>((resolve, reject) => {
27
- const request = indexedDB.open(config.name, config.version);
28
- request.onerror = () => reject(request.error ?? new DOMException('Failed to open database'));
29
- request.onsuccess = () => resolve(request.result);
30
- request.onupgradeneeded = (event: IDBVersionChangeEvent) => {
31
- const db = (event.target as IDBOpenDBRequest).result;
32
- const tables = config.tables;
33
- for (const tableName of Object.keys(tables)) {
34
- const schema = tables[tableName] as TableSchema;
35
- if (!db.objectStoreNames.contains(tableName)) {
36
- const store = db.createObjectStore(tableName, {
37
- keyPath: schema.keyPath,
38
- autoIncrement: schema.autoIncrement ?? false,
39
- });
40
- if (schema.indexes) {
41
- for (const indexName of schema.indexes) {
42
- store.createIndex(indexName, indexName, { unique: false });
43
- }
44
- }
45
- }
46
- }
47
- };
48
- });
49
- }
1
+ /**
2
+ * Opens IndexedDB and runs onupgradeneeded to create stores and indexes.
3
+ * Singleton per (name, version).
4
+ * @module indexedDB/openDB
5
+ */
6
+
7
+ import type { IndexedDBConfig, TableSchema } from "./types";
8
+
9
+ const connectionCache = new Map<string, Promise<IDBDatabase>>();
10
+
11
+ /**
12
+ * Opens the database and creates/upgrades object stores and indexes from config.
13
+ * Uses a singleton cache per (name, version); repeated calls with the same config reuse the same connection.
14
+ */
15
+ export function openDB(config: IndexedDBConfig): Promise<IDBDatabase> {
16
+ const key = `${config.name}_v${config.version}`;
17
+ let promise = connectionCache.get(key);
18
+ if (promise) return promise;
19
+ promise = _openDB(config);
20
+ connectionCache.set(key, promise);
21
+ return promise;
22
+ }
23
+
24
+ function _openDB(config: IndexedDBConfig): Promise<IDBDatabase> {
25
+ return new Promise<IDBDatabase>((resolve, reject) => {
26
+ const request = indexedDB.open(config.name, config.version);
27
+ request.onerror = () =>
28
+ reject(request.error ?? new DOMException("Failed to open database"));
29
+ request.onsuccess = () => resolve(request.result);
30
+ request.onupgradeneeded = (event: IDBVersionChangeEvent) => {
31
+ const db = (event.target as IDBOpenDBRequest).result;
32
+ const tables = config.tables;
33
+ for (const tableName of Object.keys(tables)) {
34
+ const schema = tables[tableName] as TableSchema;
35
+ if (!db.objectStoreNames.contains(tableName)) {
36
+ const store = db.createObjectStore(tableName, {
37
+ keyPath: schema.keyPath,
38
+ autoIncrement: schema.autoIncrement ?? false,
39
+ });
40
+ if (schema.indexes) {
41
+ for (const indexName of schema.indexes) {
42
+ store.createIndex(indexName, indexName, { unique: false });
43
+ }
44
+ }
45
+ }
46
+ }
47
+ };
48
+ });
49
+ }
@@ -1,16 +1,17 @@
1
- /**
2
- * Wraps an IDBRequest in a Promise.
3
- * @module indexedDB/requestToPromise
4
- */
5
-
6
- /**
7
- * Converts an IDBRequest to a Promise. Rejects with the request's error on failure.
8
- * @param request - Native IndexedDB request.
9
- * @returns Promise that resolves with the request result or rejects with DOMException.
10
- */
11
- export function requestToPromise<T>(request: IDBRequest<T>): Promise<T> {
12
- return new Promise<T>((resolve, reject) => {
13
- request.onsuccess = () => resolve(request.result);
14
- request.onerror = () => reject(request.error ?? new DOMException('Unknown IndexedDB error'));
15
- });
16
- }
1
+ /**
2
+ * Wraps an IDBRequest in a Promise.
3
+ * @module indexedDB/requestToPromise
4
+ */
5
+
6
+ /**
7
+ * Converts an IDBRequest to a Promise. Rejects with the request's error on failure.
8
+ * @param request - Native IndexedDB request.
9
+ * @returns Promise that resolves with the request result or rejects with DOMException.
10
+ */
11
+ export function requestToPromise<T>(request: IDBRequest<T>): Promise<T> {
12
+ return new Promise<T>((resolve, reject) => {
13
+ request.onsuccess = () => resolve(request.result);
14
+ request.onerror = () =>
15
+ reject(request.error ?? new DOMException("Unknown IndexedDB error"));
16
+ });
17
+ }