@@ -55,15 +55,15 @@ function openDatabase(dbName: string, version: number, storeName: string): Promi
5555}
5656
5757const request = indexedDB . open ( dbName , version ) ;
58-
58+
5959request . onerror = ( ) => {
6060reject ( new Error ( `Failed to open database "${ dbName } ":${ request . error ?. message } ` ) ) ;
6161} ;
62-
62+
6363request . onsuccess = ( ) => {
6464resolve ( request . result ) ;
6565} ;
66-
66+
6767request . onupgradeneeded = ( ) => {
6868const db = request . result ;
6969if ( ! db . objectStoreNames . contains ( storeName ) ) {
@@ -82,27 +82,27 @@ function openDatabase(dbName: string, version: number, storeName: string): Promi
8282 *@returns Promise that resolves to the value or null if not found
8383 */
8484async function getValueFromIndexedDB < T > (
85- dbName :string ,
86- storeName :string ,
87- key :string ,
85+ dbName :string ,
86+ storeName :string ,
87+ key :string ,
8888version :number
8989) :Promise < T | null > {
9090try {
9191const db = await openDatabase ( dbName , version , storeName ) ;
92-
92+
9393return new Promise ( ( resolve , reject ) => {
9494const transaction = db . transaction ( [ storeName ] , 'readonly' ) ;
9595const store = transaction . objectStore ( storeName ) ;
9696const request = store . get ( key ) ;
97-
97+
9898request . onerror = ( ) => {
9999reject ( new Error ( `Failed to get value for key "${ key } ":${ request . error ?. message } ` ) ) ;
100100} ;
101-
101+
102102request . onsuccess = ( ) => {
103103resolve ( request . result ?? null ) ;
104104} ;
105-
105+
106106transaction . oncomplete = ( ) => {
107107db . close ( ) ;
108108} ;
@@ -122,28 +122,28 @@ async function getValueFromIndexedDB<T>(
122122 *@param version - The database version
123123 */
124124async function saveValueToIndexedDB < T > (
125- dbName :string ,
126- storeName :string ,
127- key :string ,
128- value :T ,
125+ dbName :string ,
126+ storeName :string ,
127+ key :string ,
128+ value :T ,
129129version :number
130130) :Promise < void > {
131131try {
132132const db = await openDatabase ( dbName , version , storeName ) ;
133-
133+
134134return new Promise ( ( resolve , reject ) => {
135135const transaction = db . transaction ( [ storeName ] , 'readwrite' ) ;
136136const store = transaction . objectStore ( storeName ) ;
137137const request = store . put ( value , key ) ;
138-
138+
139139request . onerror = ( ) => {
140140reject ( new Error ( `Failed to save value for key "${ key } ":${ request . error ?. message } ` ) ) ;
141141} ;
142-
142+
143143request . onsuccess = ( ) => {
144144resolve ( ) ;
145145} ;
146-
146+
147147transaction . oncomplete = ( ) => {
148148db . close ( ) ;
149149} ;
@@ -162,27 +162,27 @@ async function saveValueToIndexedDB<T>(
162162 *@param version - The database version
163163 */
164164async function removeValueFromIndexedDB (
165- dbName :string ,
166- storeName :string ,
167- key :string ,
165+ dbName :string ,
166+ storeName :string ,
167+ key :string ,
168168version :number
169169) :Promise < void > {
170170try {
171171const db = await openDatabase ( dbName , version , storeName ) ;
172-
172+
173173return new Promise ( ( resolve , reject ) => {
174174const transaction = db . transaction ( [ storeName ] , 'readwrite' ) ;
175175const store = transaction . objectStore ( storeName ) ;
176176const request = store . delete ( key ) ;
177-
177+
178178request . onerror = ( ) => {
179179reject ( new Error ( `Failed to remove value for key "${ key } ":${ request . error ?. message } ` ) ) ;
180180} ;
181-
181+
182182request . onsuccess = ( ) => {
183183resolve ( ) ;
184184} ;
185-
185+
186186transaction . oncomplete = ( ) => {
187187db . close ( ) ;
188188} ;
@@ -234,13 +234,13 @@ interface UseSuspenseIndexedDBStateControls<T> {
234234 *@returns The current state value
235235 */
236236getItem :( ) => T ;
237-
237+
238238/**
239239 * Set a new value in IndexedDB and update state
240240 *@param value - The new value to set
241241 */
242242setItem :( value :T ) => Promise < void > ;
243-
243+
244244/**
245245 * Delete the item from IndexedDB and reset to initial value
246246 */
@@ -275,13 +275,13 @@ interface IndexedDBConfig {
275275 *@default "rooks-db"
276276 */
277277dbName ?:string ;
278-
278+
279279/**
280280 * The object store name within the database
281281 *@default "state"
282282 */
283283storeName ?:string ;
284-
284+
285285/**
286286 * The database version
287287 *@default 1
@@ -345,7 +345,7 @@ function useSuspenseIndexedDBState<T>(
345345
346346// Create a unique cache key combining database info and key
347347const cacheKey = `${ dbName } :${ storeName } :${ key } :${ version } ` ;
348-
348+
349349// Check if we already have a cache entry for this key
350350let cacheEntry = cache . get ( cacheKey ) as CacheEntry < T > | undefined ;
351351
@@ -410,7 +410,7 @@ function useSuspenseIndexedDBState<T>(
410410const handleBroadcastMessage = useCallback (
411411( event :MessageEvent < BroadcastMessage < T > > ) => {
412412const { type, key :messageKey , value :messageValue , dbName :msgDbName , storeName :msgStoreName } = event . data ;
413-
413+
414414// Only handle messages for the same database, store, and key
415415if ( msgDbName === dbName && msgStoreName === storeName && messageKey === key ) {
416416try {
@@ -452,14 +452,23 @@ function useSuspenseIndexedDBState<T>(
452452const broadcastChange = useCallback (
453453( type :'SET' | 'DELETE' , newValue ?:T ) => {
454454if ( broadcastChannel ) {
455- const message :BroadcastMessage < T > = {
456- type,
457- key,
458- value :newValue ,
459- dbName,
460- storeName
461- } ;
462- broadcastChannel . postMessage ( message ) ;
455+ try {
456+ const message :BroadcastMessage < T > = {
457+ type,
458+ key,
459+ value :newValue ,
460+ dbName,
461+ storeName
462+ } ;
463+ broadcastChannel . postMessage ( message ) ;
464+ } catch ( error ) {
465+ // Channel might be closed, ignore the error
466+ if ( error instanceof Error && error . name === 'InvalidStateError' ) {
467+ console . warn ( `BroadcastChannel is closed, cannot send message for key "${ key } "` ) ;
468+ } else {
469+ console . error ( `Failed to broadcast message for key "${ key } ":` , error ) ;
470+ }
471+ }
463472}
464473} ,
465474[ broadcastChannel , key , dbName , storeName ]
@@ -468,7 +477,7 @@ function useSuspenseIndexedDBState<T>(
468477// Control methods
469478const controls = useMemo < UseSuspenseIndexedDBStateControls < T > > ( ( ) => ( {
470479getItem :( ) => value ,
471-
480+
472481setItem :async ( newValue :T ) => {
473482try {
474483await saveValueToIndexedDB ( dbName , storeName , key , newValue , version ) ;
@@ -479,7 +488,7 @@ function useSuspenseIndexedDBState<T>(
479488throw error ;
480489}
481490} ,
482-
491+
483492deleteItem :async ( ) => {
484493try {
485494await removeValueFromIndexedDB ( dbName , storeName , key , version ) ;