expo-sqlite 58.0.7 → 58.0.9

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 (62) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/android/build.gradle +2 -2
  3. package/android/src/main/cpp/NativeDatabaseBinding.cpp +0 -22
  4. package/android/src/main/cpp/NativeDatabaseBinding.h +0 -1
  5. package/android/src/main/cpp/NativeStatementBinding.cpp +3 -1
  6. package/android/src/main/cpp/NativeStatementBinding.h +1 -1
  7. package/android/src/main/java/expo/modules/sqlite/NativeDatabase.kt +5 -0
  8. package/android/src/main/java/expo/modules/sqlite/NativeDatabaseBinding.kt +0 -1
  9. package/android/src/main/java/expo/modules/sqlite/NativeStatement.kt +9 -1
  10. package/android/src/main/java/expo/modules/sqlite/SQLExceptions.kt +7 -1
  11. package/android/src/main/java/expo/modules/sqlite/SQLiteModule.kt +78 -48
  12. package/dev-plugin-dist/+not-found.html +1 -1
  13. package/dev-plugin-dist/_expo/static/js/web/{__common-725582fc6bba7ccfc743bb9aba24f9bc.js → __common-9b94dd2fbdbb825a662f42cf8d2077ee.js} +36 -36
  14. package/dev-plugin-dist/_expo/static/js/web/{_layout-171413bc9bf8452e491f0d7713017a36.js → _layout-b2894030c1dfbd95b717a85901b6c271.js} +22 -22
  15. package/dev-plugin-dist/_expo/static/js/web/{entry-46e748b71acc826f94c91796cdf4bc28.js → entry-04fdb7d857a65c0ed638ef2d774a4b6e.js} +547 -551
  16. package/dev-plugin-dist/_expo/static/js/web/{index-42fa8946372d43a04e2a3d5f7c907da9.js → index-4bf2da199f699eb47a42074d5e183c07.js} +1740 -1740
  17. package/dev-plugin-dist/_expo/static/js/web/{worker-b07a1b17f78db461acd77ea8aa0d302b.js → worker-d51aa6be89e271e571111274ab8e7f5c.js} +17 -17
  18. package/dev-plugin-dist/_sitemap.html +1 -1
  19. package/dev-plugin-dist/index.html +1 -1
  20. package/ios/NativeDatabase.swift +14 -5
  21. package/ios/NativeStatement.swift +23 -15
  22. package/ios/SQLiteModule.swift +46 -45
  23. package/ios/Tests/test_StatementCleanup.swift +84 -0
  24. package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/58.0.9/expo.modules.sqlite-58.0.9-sources.jar +0 -0
  25. package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/58.0.9/expo.modules.sqlite-58.0.9-sources.jar.md5 +1 -0
  26. package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/58.0.9/expo.modules.sqlite-58.0.9-sources.jar.sha1 +1 -0
  27. package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/58.0.9/expo.modules.sqlite-58.0.9-sources.jar.sha256 +1 -0
  28. package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/58.0.9/expo.modules.sqlite-58.0.9-sources.jar.sha512 +1 -0
  29. package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/58.0.9/expo.modules.sqlite-58.0.9.aar +0 -0
  30. package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/58.0.9/expo.modules.sqlite-58.0.9.aar.md5 +1 -0
  31. package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/58.0.9/expo.modules.sqlite-58.0.9.aar.sha1 +1 -0
  32. package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/58.0.9/expo.modules.sqlite-58.0.9.aar.sha256 +1 -0
  33. package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/58.0.9/expo.modules.sqlite-58.0.9.aar.sha512 +1 -0
  34. package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/{58.0.7/expo.modules.sqlite-58.0.7.module → 58.0.9/expo.modules.sqlite-58.0.9.module} +22 -22
  35. package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/58.0.9/expo.modules.sqlite-58.0.9.module.md5 +1 -0
  36. package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/58.0.9/expo.modules.sqlite-58.0.9.module.sha1 +1 -0
  37. package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/58.0.9/expo.modules.sqlite-58.0.9.module.sha256 +1 -0
  38. package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/58.0.9/expo.modules.sqlite-58.0.9.module.sha512 +1 -0
  39. package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/{58.0.7/expo.modules.sqlite-58.0.7.pom → 58.0.9/expo.modules.sqlite-58.0.9.pom} +1 -1
  40. package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/58.0.9/expo.modules.sqlite-58.0.9.pom.md5 +1 -0
  41. package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/58.0.9/expo.modules.sqlite-58.0.9.pom.sha1 +1 -0
  42. package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/58.0.9/expo.modules.sqlite-58.0.9.pom.sha256 +1 -0
  43. package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/58.0.9/expo.modules.sqlite-58.0.9.pom.sha512 +1 -0
  44. package/package.json +5 -5
  45. package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/58.0.7/expo.modules.sqlite-58.0.7-sources.jar +0 -0
  46. package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/58.0.7/expo.modules.sqlite-58.0.7-sources.jar.md5 +0 -1
  47. package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/58.0.7/expo.modules.sqlite-58.0.7-sources.jar.sha1 +0 -1
  48. package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/58.0.7/expo.modules.sqlite-58.0.7-sources.jar.sha256 +0 -1
  49. package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/58.0.7/expo.modules.sqlite-58.0.7-sources.jar.sha512 +0 -1
  50. package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/58.0.7/expo.modules.sqlite-58.0.7.aar +0 -0
  51. package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/58.0.7/expo.modules.sqlite-58.0.7.aar.md5 +0 -1
  52. package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/58.0.7/expo.modules.sqlite-58.0.7.aar.sha1 +0 -1
  53. package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/58.0.7/expo.modules.sqlite-58.0.7.aar.sha256 +0 -1
  54. package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/58.0.7/expo.modules.sqlite-58.0.7.aar.sha512 +0 -1
  55. package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/58.0.7/expo.modules.sqlite-58.0.7.module.md5 +0 -1
  56. package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/58.0.7/expo.modules.sqlite-58.0.7.module.sha1 +0 -1
  57. package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/58.0.7/expo.modules.sqlite-58.0.7.module.sha256 +0 -1
  58. package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/58.0.7/expo.modules.sqlite-58.0.7.module.sha512 +0 -1
  59. package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/58.0.7/expo.modules.sqlite-58.0.7.pom.md5 +0 -1
  60. package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/58.0.7/expo.modules.sqlite-58.0.7.pom.sha1 +0 -1
  61. package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/58.0.7/expo.modules.sqlite-58.0.7.pom.sha256 +0 -1
  62. package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/58.0.7/expo.modules.sqlite-58.0.7.pom.sha512 +0 -1
@@ -314,5 +314,5 @@ input::-webkit-search-cancel-button,input::-webkit-search-decoration,input::-web
314
314
  @keyframes r-imtty0{0%{opacity:0;}100%{opacity:1;}}
315
315
  @keyframes r-q67da2{0%{transform:translateX(-100%);}100%{transform:translateX(400%);}}
316
316
  @keyframes r-t2lo5v{0%{opacity:1;}100%{opacity:0;}}</style><script type="module">globalThis.__EXPO_ROUTER_HYDRATE__=true;</script><link rel="preload" href="/_expo/plugins/expo-sqlite/_expo/static/css/global-b1bdf830cdbd0ec4238cc5f230f99460.css" as="style">
317
- <link rel="stylesheet" href="/_expo/plugins/expo-sqlite/_expo/static/css/global-b1bdf830cdbd0ec4238cc5f230f99460.css"></head><body><div id="root"><div class="css-g5y9jx r-13awgt0"></div></div><script src="/_expo/plugins/expo-sqlite/_expo/static/js/web/__expo-metro-runtime-8c088df87a31e4e6accd81c554ec290d.js" defer></script><script src="/_expo/plugins/expo-sqlite/_expo/static/js/web/_layout-171413bc9bf8452e491f0d7713017a36.js" defer></script><script src="/_expo/plugins/expo-sqlite/_expo/static/js/web/__common-725582fc6bba7ccfc743bb9aba24f9bc.js" defer></script><script src="/_expo/plugins/expo-sqlite/_expo/static/js/web/entry-46e748b71acc826f94c91796cdf4bc28.js" defer></script>
317
+ <link rel="stylesheet" href="/_expo/plugins/expo-sqlite/_expo/static/css/global-b1bdf830cdbd0ec4238cc5f230f99460.css"></head><body><div id="root"><div class="css-g5y9jx r-13awgt0"></div></div><script src="/_expo/plugins/expo-sqlite/_expo/static/js/web/__expo-metro-runtime-8c088df87a31e4e6accd81c554ec290d.js" defer></script><script src="/_expo/plugins/expo-sqlite/_expo/static/js/web/_layout-b2894030c1dfbd95b717a85901b6c271.js" defer></script><script src="/_expo/plugins/expo-sqlite/_expo/static/js/web/__common-9b94dd2fbdbb825a662f42cf8d2077ee.js" defer></script><script src="/_expo/plugins/expo-sqlite/_expo/static/js/web/entry-04fdb7d857a65c0ed638ef2d774a4b6e.js" defer></script>
318
318
  </body></html>
@@ -314,5 +314,5 @@ input::-webkit-search-cancel-button,input::-webkit-search-decoration,input::-web
314
314
  @keyframes r-imtty0{0%{opacity:0;}100%{opacity:1;}}
315
315
  @keyframes r-q67da2{0%{transform:translateX(-100%);}100%{transform:translateX(400%);}}
316
316
  @keyframes r-t2lo5v{0%{opacity:1;}100%{opacity:0;}}</style><script type="module">globalThis.__EXPO_ROUTER_HYDRATE__=true;</script><link rel="preload" href="/_expo/plugins/expo-sqlite/_expo/static/css/global-b1bdf830cdbd0ec4238cc5f230f99460.css" as="style">
317
- <link rel="stylesheet" href="/_expo/plugins/expo-sqlite/_expo/static/css/global-b1bdf830cdbd0ec4238cc5f230f99460.css"></head><body><div id="root"><div class="css-g5y9jx r-13awgt0"><!--$--><!--$--><div class="flex min-h-screen items-center justify-center bg-linear-to-br from-slate-50 to-slate-100 p-4"><div class="rounded-xl border bg-card text-card-foreground shadow w-full max-w-2xl"><div class="flex flex-col space-y-1.5 p-6 text-center"><div class="font-semibold tracking-tight text-3xl">SQLite Database Inspector</div><div class="text-muted-foreground text-base">Upload a database file or connect to your app</div></div><div class="p-6 pt-0"><div dir="ltr" data-orientation="horizontal" class="w-full"><div role="tablist" aria-orientation="horizontal" class="h-9 items-center justify-center rounded-lg bg-muted p-1 text-muted-foreground grid w-full grid-cols-2" tabindex="-1" data-orientation="horizontal" style="outline:none"><button type="button" role="tab" aria-selected="true" aria-controls="radix-_R_jer3_-content-devtools" data-state="active" data-disabled="" disabled="" id="radix-_R_jer3_-trigger-devtools" class="inline-flex items-center justify-center whitespace-nowrap rounded-md px-3 py-1 text-sm font-medium ring-offset-background transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 data-[state=active]:bg-background data-[state=active]:text-foreground data-[state=active]:shadow" tabindex="-1" data-orientation="horizontal" data-radix-collection-item="">From App </button><button type="button" role="tab" aria-selected="false" aria-controls="radix-_R_jer3_-content-upload" data-state="inactive" id="radix-_R_jer3_-trigger-upload" class="inline-flex items-center justify-center whitespace-nowrap rounded-md px-3 py-1 text-sm font-medium ring-offset-background transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 data-[state=active]:bg-background data-[state=active]:text-foreground data-[state=active]:shadow" tabindex="-1" data-orientation="horizontal" data-radix-collection-item="">Upload File</button></div><div data-state="inactive" data-orientation="horizontal" role="tabpanel" aria-labelledby="radix-_R_jer3_-trigger-upload" hidden="" id="radix-_R_jer3_-content-upload" tabindex="0" class="mt-2 ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2"></div><div data-state="active" data-orientation="horizontal" role="tabpanel" aria-labelledby="radix-_R_jer3_-trigger-devtools" id="radix-_R_jer3_-content-devtools" tabindex="0" class="mt-2 ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2" style="animation-duration:0s"><div class="space-y-4"><div class="flex items-center justify-between"><h3 class="text-sm font-medium">Available Databases</h3><button class="inline-flex items-center justify-center gap-2 whitespace-nowrap font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 [&amp;_svg]:pointer-events-none [&amp;_svg]:size-4 [&amp;_svg]:shrink-0 border border-input bg-background shadow-sm hover:bg-accent hover:text-accent-foreground h-8 rounded-md px-3 text-xs"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-refresh-cw h-4 w-4 mr-2" aria-hidden="true"><path d="M3 12a9 9 0 0 1 9-9 9.75 9.75 0 0 1 6.74 2.74L21 8"></path><path d="M21 3v5h-5"></path><path d="M21 12a9 9 0 0 1-9 9 9.75 9.75 0 0 1-6.74-2.74L3 16"></path><path d="M8 16H3v5"></path></svg>Refresh</button></div><div class="text-center p-12 rounded-lg border-2 border-dashed border-muted-foreground/25"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-database h-12 w-12 text-muted-foreground mx-auto mb-4" aria-hidden="true"><ellipse cx="12" cy="5" rx="9" ry="3"></ellipse><path d="M3 5V19A9 3 0 0 0 21 19V5"></path><path d="M3 12A9 3 0 0 0 21 12"></path></svg><p class="text-sm text-muted-foreground">No databases found. Make sure your app is using useSQLiteDevTool.</p></div></div></div></div></div></div></div><section aria-label="Notifications alt+T" tabindex="-1" aria-live="polite" aria-relevant="additions text" aria-atomic="false"></section><!--/$--><!--/$--></div></div><script src="/_expo/plugins/expo-sqlite/_expo/static/js/web/__expo-metro-runtime-8c088df87a31e4e6accd81c554ec290d.js" defer></script><script src="/_expo/plugins/expo-sqlite/_expo/static/js/web/_layout-171413bc9bf8452e491f0d7713017a36.js" defer></script><script src="/_expo/plugins/expo-sqlite/_expo/static/js/web/index-42fa8946372d43a04e2a3d5f7c907da9.js" defer></script><script src="/_expo/plugins/expo-sqlite/_expo/static/js/web/__common-725582fc6bba7ccfc743bb9aba24f9bc.js" defer></script><script src="/_expo/plugins/expo-sqlite/_expo/static/js/web/entry-46e748b71acc826f94c91796cdf4bc28.js" defer></script>
317
+ <link rel="stylesheet" href="/_expo/plugins/expo-sqlite/_expo/static/css/global-b1bdf830cdbd0ec4238cc5f230f99460.css"></head><body><div id="root"><div class="css-g5y9jx r-13awgt0"><!--$--><!--$--><div class="flex min-h-screen items-center justify-center bg-linear-to-br from-slate-50 to-slate-100 p-4"><div class="rounded-xl border bg-card text-card-foreground shadow w-full max-w-2xl"><div class="flex flex-col space-y-1.5 p-6 text-center"><div class="font-semibold tracking-tight text-3xl">SQLite Database Inspector</div><div class="text-muted-foreground text-base">Upload a database file or connect to your app</div></div><div class="p-6 pt-0"><div dir="ltr" data-orientation="horizontal" class="w-full"><div role="tablist" aria-orientation="horizontal" class="h-9 items-center justify-center rounded-lg bg-muted p-1 text-muted-foreground grid w-full grid-cols-2" tabindex="-1" data-orientation="horizontal" style="outline:none"><button type="button" role="tab" aria-selected="true" aria-controls="radix-_R_jer3_-content-devtools" data-state="active" data-disabled="" disabled="" id="radix-_R_jer3_-trigger-devtools" class="inline-flex items-center justify-center whitespace-nowrap rounded-md px-3 py-1 text-sm font-medium ring-offset-background transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 data-[state=active]:bg-background data-[state=active]:text-foreground data-[state=active]:shadow" tabindex="-1" data-orientation="horizontal" data-radix-collection-item="">From App </button><button type="button" role="tab" aria-selected="false" aria-controls="radix-_R_jer3_-content-upload" data-state="inactive" id="radix-_R_jer3_-trigger-upload" class="inline-flex items-center justify-center whitespace-nowrap rounded-md px-3 py-1 text-sm font-medium ring-offset-background transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 data-[state=active]:bg-background data-[state=active]:text-foreground data-[state=active]:shadow" tabindex="-1" data-orientation="horizontal" data-radix-collection-item="">Upload File</button></div><div data-state="inactive" data-orientation="horizontal" role="tabpanel" aria-labelledby="radix-_R_jer3_-trigger-upload" hidden="" id="radix-_R_jer3_-content-upload" tabindex="0" class="mt-2 ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2"></div><div data-state="active" data-orientation="horizontal" role="tabpanel" aria-labelledby="radix-_R_jer3_-trigger-devtools" id="radix-_R_jer3_-content-devtools" tabindex="0" class="mt-2 ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2" style="animation-duration:0s"><div class="space-y-4"><div class="flex items-center justify-between"><h3 class="text-sm font-medium">Available Databases</h3><button class="inline-flex items-center justify-center gap-2 whitespace-nowrap font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 [&amp;_svg]:pointer-events-none [&amp;_svg]:size-4 [&amp;_svg]:shrink-0 border border-input bg-background shadow-sm hover:bg-accent hover:text-accent-foreground h-8 rounded-md px-3 text-xs"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-refresh-cw h-4 w-4 mr-2" aria-hidden="true"><path d="M3 12a9 9 0 0 1 9-9 9.75 9.75 0 0 1 6.74 2.74L21 8"></path><path d="M21 3v5h-5"></path><path d="M21 12a9 9 0 0 1-9 9 9.75 9.75 0 0 1-6.74-2.74L3 16"></path><path d="M8 16H3v5"></path></svg>Refresh</button></div><div class="text-center p-12 rounded-lg border-2 border-dashed border-muted-foreground/25"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-database h-12 w-12 text-muted-foreground mx-auto mb-4" aria-hidden="true"><ellipse cx="12" cy="5" rx="9" ry="3"></ellipse><path d="M3 5V19A9 3 0 0 0 21 19V5"></path><path d="M3 12A9 3 0 0 0 21 12"></path></svg><p class="text-sm text-muted-foreground">No databases found. Make sure your app is using useSQLiteDevTool.</p></div></div></div></div></div></div></div><section aria-label="Notifications alt+T" tabindex="-1" aria-live="polite" aria-relevant="additions text" aria-atomic="false"></section><!--/$--><!--/$--></div></div><script src="/_expo/plugins/expo-sqlite/_expo/static/js/web/__expo-metro-runtime-8c088df87a31e4e6accd81c554ec290d.js" defer></script><script src="/_expo/plugins/expo-sqlite/_expo/static/js/web/_layout-b2894030c1dfbd95b717a85901b6c271.js" defer></script><script src="/_expo/plugins/expo-sqlite/_expo/static/js/web/index-4bf2da199f699eb47a42074d5e183c07.js" defer></script><script src="/_expo/plugins/expo-sqlite/_expo/static/js/web/__common-9b94dd2fbdbb825a662f42cf8d2077ee.js" defer></script><script src="/_expo/plugins/expo-sqlite/_expo/static/js/web/entry-04fdb7d857a65c0ed638ef2d774a4b6e.js" defer></script>
318
318
  </body></html>
@@ -11,6 +11,10 @@ final class NativeDatabase: SharedObject, @unchecked Sendable {
11
11
  let openOptions: OpenDatabaseOptions
12
12
  var isClosed = false
13
13
  let closeLock = NSLock()
14
+ // Protect statement registration and cleanup through the final close attempt.
15
+ // Running statements use their own locks, so interruption need not wait for them.
16
+ let statementLifecycleLock = NSRecursiveLock()
17
+ var statements: [NativeStatement] = []
14
18
  var extraPointer: OpaquePointer?
15
19
  private var refCount = AtomicInteger(1)
16
20
 
@@ -134,11 +138,16 @@ final class NativeDatabase: SharedObject, @unchecked Sendable {
134
138
  }
135
139
 
136
140
  private func prepare(statement: NativeStatement, source: String) throws {
137
- try ensureOpen()
138
- try statement.ensureNotFinalized()
139
- let sourceString = source.cString(using: .utf8)
140
- if exsqlite3_prepare_v2(pointer, sourceString, -1, &statement.pointer, nil) != SQLITE_OK {
141
- throw SQLiteErrorException(lastErrorMessage())
141
+ statementLifecycleLock.lock()
142
+ defer { statementLifecycleLock.unlock() }
143
+ try statement.lock.withLock { _ in
144
+ try statement.ensureNotFinalized()
145
+ try ensureOpen()
146
+ let sourceString = source.cString(using: .utf8)
147
+ if exsqlite3_prepare_v2(pointer, sourceString, -1, &statement.pointer, nil) != SQLITE_OK {
148
+ throw SQLiteErrorException(lastErrorMessage())
149
+ }
150
+ statements.append(statement)
142
151
  }
143
152
  }
144
153
 
@@ -60,10 +60,10 @@ final class NativeStatement: SharedObject, @unchecked Sendable {
60
60
  // MARK: - Implementation shared by the sync and async members
61
61
 
62
62
  private func reset(database: NativeDatabase) throws {
63
- try database.ensureOpen()
64
- try ensureNotFinalized()
65
-
66
63
  try lock.withLock { _ in
64
+ try ensureNotFinalized()
65
+ try database.ensureOpen()
66
+
67
67
  if exsqlite3_reset(pointer) != SQLITE_OK {
68
68
  throw SQLiteErrorException(database.lastErrorMessage())
69
69
  }
@@ -71,24 +71,32 @@ final class NativeStatement: SharedObject, @unchecked Sendable {
71
71
  }
72
72
 
73
73
  private func getColumnNames() throws -> [String] {
74
- try ensureNotFinalized()
75
- let columnCount = Int(exsqlite3_column_count(pointer))
76
- var columnNames: [String] = Array(repeating: "", count: columnCount)
77
- for i in 0..<columnCount {
78
- columnNames[i] = String(cString: exsqlite3_column_name(pointer, Int32(i)))
74
+ return try lock.withLock { _ in
75
+ try ensureNotFinalized()
76
+ let columnCount = Int(exsqlite3_column_count(pointer))
77
+ var columnNames: [String] = Array(repeating: "", count: columnCount)
78
+ for i in 0..<columnCount {
79
+ columnNames[i] = String(cString: exsqlite3_column_name(pointer, Int32(i)))
80
+ }
81
+ return columnNames
79
82
  }
80
- return columnNames
81
83
  }
82
84
 
83
- private func finalize(database: NativeDatabase) throws {
84
- try database.ensureOpen()
85
- try ensureNotFinalized()
86
-
85
+ func finalize(database: NativeDatabase) throws {
86
+ database.statementLifecycleLock.lock()
87
+ defer { database.statementLifecycleLock.unlock() }
87
88
  try lock.withLock { _ in
88
- if exsqlite3_finalize(pointer) != SQLITE_OK {
89
+ try ensureNotFinalized()
90
+ try database.ensureOpen()
91
+
92
+ let ret = exsqlite3_finalize(pointer)
93
+ // SQLite destroys the statement even when returning an earlier execution error.
94
+ isFinalized = true
95
+ pointer = nil
96
+ database.statements.removeAll { $0 === self }
97
+ if ret != SQLITE_OK {
89
98
  throw SQLiteErrorException(database.lastErrorMessage())
90
99
  }
91
- isFinalized = true
92
100
  }
93
101
  }
94
102
  }
@@ -9,7 +9,7 @@ private let MEMORY_DB_NAME = ":memory:"
9
9
  private let moduleQueue = DispatchQueue(label: "expo.module.sqlite.AsyncQueue", qos: .userInitiated, attributes: .concurrent)
10
10
 
11
11
  // `@unchecked Sendable`: the `@JS(.concurrent)` members send the module off the JavaScript thread, which
12
- // Swift 6 mode allows only for a `Sendable` module. The mutable state is either guarded by `lockQueue` or
12
+ // Swift 6 mode allows only for a `Sendable` module. The mutable state is either guarded by `cacheLock` or
13
13
  // only read off the JavaScript thread (`hasListeners`).
14
14
  @ExpoModule("ExpoSQLite")
15
15
  public final class SQLiteModule: Module, @unchecked Sendable {
@@ -17,7 +17,8 @@ public final class SQLiteModule: Module, @unchecked Sendable {
17
17
  // will release the pair when `closeDatabase` is called.
18
18
  private var contextPairs = [Unmanaged<AnyObject>]()
19
19
 
20
- private static let lockQueue = DispatchQueue(label: "expo.modules.sqlite.lockQueue")
20
+ // Closing a cached connection also releases its update-hook context under this lock.
21
+ private static let cacheLock = NSRecursiveLock()
21
22
  private var cachedDatabases = [NativeDatabase]()
22
23
  private(set) var hasListeners = false
23
24
 
@@ -154,10 +155,7 @@ public final class SQLiteModule: Module, @unchecked Sendable {
154
155
  }
155
156
 
156
157
  AsyncFunction("closeAsync") { (database: NativeDatabase) in
157
- try maybeThrowForClosedDatabase(database)
158
- if let db = removeCachedDatabase(of: database) {
159
- try closeDatabase(db)
160
- }
158
+ try closeDatabaseIfNeeded(database)
161
159
  }.runOnQueue(moduleQueue)
162
160
  // Interrupt must reach SQLite immediately, without waiting for the running query's queue.
163
161
  Function("interruptSync") { (database: NativeDatabase) in
@@ -170,10 +168,7 @@ public final class SQLiteModule: Module, @unchecked Sendable {
170
168
  exsqlite3_interrupt(database.pointer)
171
169
  }
172
170
  Function("closeSync") { (database: NativeDatabase) in
173
- try maybeThrowForClosedDatabase(database)
174
- if let db = removeCachedDatabase(of: database) {
175
- try closeDatabase(db)
176
- }
171
+ try closeDatabaseIfNeeded(database)
177
172
  }
178
173
  }
179
174
 
@@ -264,12 +259,12 @@ public final class SQLiteModule: Module, @unchecked Sendable {
264
259
  // swiftlint:disable line_length
265
260
 
266
261
  private func run(statement: NativeStatement, database: NativeDatabase, bindParams: [String: Any], bindBlobParams: [String: any AnyArrayBuffer], shouldPassAsArray: Bool) throws -> [String: Any] {
267
- try maybeThrowForClosedDatabase(database)
268
- try maybeThrowForFinalizedStatement(statement)
269
-
270
262
  // The statement with parameter bindings is stateful,
271
263
  // we have to guard with a critical section for thread safety.
272
264
  return try statement.lock.withLock { _ -> [String: Any] in
265
+ try maybeThrowForFinalizedStatement(statement)
266
+ try maybeThrowForClosedDatabase(database)
267
+
273
268
  exsqlite3_reset(statement.pointer)
274
269
  exsqlite3_clear_bindings(statement.pointer)
275
270
  for (key, param) in bindParams {
@@ -301,11 +296,11 @@ public final class SQLiteModule: Module, @unchecked Sendable {
301
296
  // swiftlint:enable line_length
302
297
 
303
298
  private func step(statement: NativeStatement, database: NativeDatabase) throws -> SQLiteColumnValues? {
304
- try maybeThrowForClosedDatabase(database)
305
- try maybeThrowForFinalizedStatement(statement)
306
-
307
299
  // Guard the stateful statement, see `run` above.
308
300
  return try statement.lock.withLock { _ -> SQLiteColumnValues? in
301
+ try maybeThrowForFinalizedStatement(statement)
302
+ try maybeThrowForClosedDatabase(database)
303
+
309
304
  let ret = exsqlite3_step(statement.pointer)
310
305
  if ret == SQLITE_ROW {
311
306
  return try getColumnValues(statement: statement)
@@ -318,11 +313,11 @@ public final class SQLiteModule: Module, @unchecked Sendable {
318
313
  }
319
314
 
320
315
  private func getAll(statement: NativeStatement, database: NativeDatabase) throws -> [SQLiteColumnValues] {
321
- try maybeThrowForClosedDatabase(database)
322
- try maybeThrowForFinalizedStatement(statement)
323
-
324
316
  // Guard the stateful statement, see `run` above.
325
317
  return try statement.lock.withLock { _ -> [SQLiteColumnValues] in
318
+ try maybeThrowForFinalizedStatement(statement)
319
+ try maybeThrowForClosedDatabase(database)
320
+
326
321
  var columnValuesList: [SQLiteColumnValues] = []
327
322
  while true {
328
323
  let ret = exsqlite3_step(statement.pointer)
@@ -343,16 +338,24 @@ public final class SQLiteModule: Module, @unchecked Sendable {
343
338
  return db.lastErrorMessage()
344
339
  }
345
340
 
346
- private func closeDatabase(_ db: NativeDatabase) throws {
341
+ func closeDatabase(_ db: NativeDatabase) throws {
342
+ Self.cacheLock.lock()
343
+ defer { Self.cacheLock.unlock() }
347
344
  db.closeLock.lock()
348
345
  defer { db.closeLock.unlock() }
349
- try maybeThrowForClosedDatabase(db)
346
+ db.statementLifecycleLock.lock()
347
+ defer { db.statementLifecycleLock.unlock() }
348
+ try db.ensureOpen()
350
349
  try maybeFinalizeAllStatements(db)
351
350
 
352
351
  let ret = exsqlite3_close(db.pointer)
352
+ // SQLITE_BUSY leaves the connection open, including its update hook.
353
+ if ret != SQLITE_OK {
354
+ throw SQLiteErrorException(convertSqlLiteErrorToString(db))
355
+ }
353
356
  db.isClosed = true
354
357
 
355
- Self.lockQueue.sync {
358
+ Self.cacheLock.withLock {
356
359
  if let index = contextPairs.firstIndex(where: {
357
360
  guard let pair = $0.takeUnretainedValue() as? (SQLiteModule, NativeDatabase) else {
358
361
  return false
@@ -366,10 +369,6 @@ public final class SQLiteModule: Module, @unchecked Sendable {
366
369
  contextPairs.remove(at: index)
367
370
  }
368
371
  }
369
-
370
- if ret != SQLITE_OK {
371
- throw SQLiteErrorException(convertSqlLiteErrorToString(db))
372
- }
373
372
  }
374
373
 
375
374
  private func deleteDatabase(databasePath: String) throws {
@@ -412,7 +411,7 @@ public final class SQLiteModule: Module, @unchecked Sendable {
412
411
 
413
412
  private func addUpdateHook(_ database: NativeDatabase) {
414
413
  let contextPair = Unmanaged.passRetained(((self, database) as AnyObject))
415
- Self.lockQueue.sync {
414
+ Self.cacheLock.withLock {
416
415
  contextPairs.append(contextPair)
417
416
  }
418
417
  // swiftlint:disable:next multiline_arguments
@@ -525,27 +524,32 @@ public final class SQLiteModule: Module, @unchecked Sendable {
525
524
  // MARK: - cachedDatabases managements
526
525
 
527
526
  private func addCachedDatabase(_ database: NativeDatabase) {
528
- Self.lockQueue.sync {
527
+ Self.cacheLock.withLock {
529
528
  cachedDatabases.append(database)
530
529
  }
531
530
  }
532
531
 
533
- @discardableResult
534
- private func removeCachedDatabase(of database: NativeDatabase) -> NativeDatabase? {
535
- return Self.lockQueue.sync {
532
+ private func closeDatabaseIfNeeded(_ database: NativeDatabase) throws {
533
+ try Self.cacheLock.withLock {
534
+ try maybeThrowForClosedDatabase(database)
536
535
  if let index = cachedDatabases.firstIndex(of: database) {
537
536
  let db = cachedDatabases[index]
538
537
  if db.release() == 0 {
538
+ do {
539
+ try closeDatabase(db)
540
+ } catch {
541
+ // Keep the connection cached and owned so callers can clean up and retry.
542
+ db.addRef()
543
+ throw error
544
+ }
539
545
  cachedDatabases.remove(at: index)
540
- return db
541
546
  }
542
547
  }
543
- return nil
544
548
  }
545
549
  }
546
550
 
547
551
  private func findCachedDatabase(where predicate: (NativeDatabase) -> Bool) -> NativeDatabase? {
548
- return Self.lockQueue.sync {
552
+ return Self.cacheLock.withLock {
549
553
  if let database = cachedDatabases.first(where: predicate) {
550
554
  return database
551
555
  }
@@ -554,7 +558,7 @@ public final class SQLiteModule: Module, @unchecked Sendable {
554
558
  }
555
559
 
556
560
  private func removeAllCachedDatabases() -> [NativeDatabase] {
557
- return Self.lockQueue.sync {
561
+ return Self.cacheLock.withLock {
558
562
  let databases = cachedDatabases
559
563
  cachedDatabases.removeAll()
560
564
  return databases
@@ -566,17 +570,14 @@ public final class SQLiteModule: Module, @unchecked Sendable {
566
570
  guard database.openOptions.finalizeUnusedStatementsBeforeClosing else {
567
571
  return
568
572
  }
569
- var stmt: OpaquePointer? = exsqlite3_next_stmt(database.pointer, nil)
570
- if stmt == nil {
571
- return
572
- }
573
- while let currentStmt = stmt {
574
- let nextStmt = exsqlite3_next_stmt(database.pointer, currentStmt)
575
- let ret = exsqlite3_finalize(currentStmt)
576
- if ret != SQLITE_OK {
577
- ExpoModulesCore.log.warn("exsqlite3_finalize failed: \(convertSqlLiteErrorToString(database))")
573
+ // Finalize through the wrappers so even a failed close leaves them invalidated.
574
+ // Do not destroy SQLite-internal statements owned by concurrent exec/backup operations.
575
+ for statement in database.statements {
576
+ do {
577
+ try statement.finalize(database: database)
578
+ } catch {
579
+ ExpoModulesCore.log.warn("Finalizing a statement during close failed: \(error)")
578
580
  }
579
- stmt = nextStmt
580
581
  }
581
582
  }
582
583
  }
@@ -0,0 +1,84 @@
1
+ // Copyright 2026-present 650 Industries. All rights reserved.
2
+
3
+ import Testing
4
+
5
+ @testable import ExpoModulesCore
6
+ @testable import ExpoSQLite
7
+
8
+ @Suite("Statement cleanup")
9
+ struct StatementCleanupTests {
10
+ @Test
11
+ @JavaScriptActor
12
+ func `failed close invalidates cleaned up statements and permits retry`() throws {
13
+ let appContext = AppContext.create()
14
+ let module = SQLiteModule(appContext: appContext)
15
+ var pointer: OpaquePointer?
16
+ var destination: OpaquePointer?
17
+ #expect(exsqlite3_open(":memory:", &pointer) == SQLITE_OK)
18
+ #expect(exsqlite3_open(":memory:", &destination) == SQLITE_OK)
19
+ let database = NativeDatabase(pointer, databasePath: ":memory:", openOptions: OpenDatabaseOptions())
20
+ defer {
21
+ if !database.isClosed { try? module.closeDatabase(database) }
22
+ exsqlite3_close(destination)
23
+ }
24
+
25
+ let statement = NativeStatement()
26
+ try database.prepareSync(statement: statement, source: "SELECT 42 AS value")
27
+
28
+ // A pending backup keeps the source connection busy even after every statement is finalized.
29
+ // This reproduces a failed close after cleanup without depending on a thread race.
30
+ let backup = try #require(exsqlite3_backup_init(destination, "main", pointer, "main"))
31
+ do {
32
+ defer { exsqlite3_backup_finish(backup) }
33
+ #expect(throws: SQLiteErrorException.self) { try module.closeDatabase(database) }
34
+ #expect(!database.isClosed)
35
+ try #require(statement.isFinalized)
36
+ #expect(throws: AccessClosedResourceException.self) { try statement.getColumnNamesSync() }
37
+ #expect(throws: AccessClosedResourceException.self) {
38
+ try statement.finalizeSync(database: database)
39
+ }
40
+
41
+ let fresh = NativeStatement()
42
+ try database.prepareSync(statement: fresh, source: "SELECT 1 AS fresh")
43
+ #expect(try fresh.getColumnNamesSync() == ["fresh"])
44
+ try fresh.finalizeSync(database: database)
45
+ }
46
+ try module.closeDatabase(database)
47
+ #expect(database.isClosed)
48
+ }
49
+
50
+ @Test
51
+ func `preparing during close either gets cleaned up or rejects the closed database`() async throws {
52
+ let appContext = AppContext.create()
53
+ let module = SQLiteModule(appContext: appContext)
54
+ for _ in 0..<50 {
55
+ var pointer: OpaquePointer?
56
+ #expect(exsqlite3_open(":memory:", &pointer) == SQLITE_OK)
57
+ let database = NativeDatabase(pointer, databasePath: ":memory:", openOptions: OpenDatabaseOptions())
58
+ defer {
59
+ if !database.isClosed { try? module.closeDatabase(database) }
60
+ }
61
+ let statement = NativeStatement()
62
+ await withTaskGroup(of: Void.self) { group in
63
+ for index in 0..<2 {
64
+ group.addTask {
65
+ do {
66
+ if index == 0 {
67
+ try await database.prepareAsync(statement: statement, source: "SELECT 1")
68
+ } else {
69
+ try module.closeDatabase(database)
70
+ }
71
+ } catch is AccessClosedResourceException {
72
+ #expect(index == 0)
73
+ } catch {
74
+ Issue.record(error)
75
+ }
76
+ }
77
+ }
78
+ }
79
+ #expect(database.isClosed)
80
+ // A prepared statement must have been invalidated by cleanup.
81
+ #expect(statement.pointer == nil)
82
+ }
83
+ }
84
+ }
@@ -0,0 +1 @@
1
+ 67dbdc88a1d7fc60c31092ad150a98a30d93d8ca82bbf869609890965425524d
@@ -0,0 +1 @@
1
+ 47d6b003042ef32b80e19b64fd015ffcfa159bb8f08971459211cd6ab971304da58dee6236c2be5319f606f9062d023530dcaa5c2e530bb17e42ab1465d5b95f
@@ -0,0 +1 @@
1
+ 96b87814356fa93bcc9eb091c5b2f96f243fa661bd70740c352dae65cca23d8f
@@ -0,0 +1 @@
1
+ d3fbb6aad5541429fc0b0c3edb30d9e71f12636e9215617d2cb19750aecb36c4df1efc1bc5f84fb75f816d9db01c4ad9a0f08457d67ae892e2ebb59d3bd26246
@@ -3,7 +3,7 @@
3
3
  "component": {
4
4
  "group": "host.exp.exponent",
5
5
  "module": "expo.modules.sqlite",
6
- "version": "58.0.7",
6
+ "version": "58.0.9",
7
7
  "attributes": {
8
8
  "org.gradle.status": "release"
9
9
  }
@@ -24,13 +24,13 @@
24
24
  },
25
25
  "files": [
26
26
  {
27
- "name": "expo.modules.sqlite-58.0.7.aar",
28
- "url": "expo.modules.sqlite-58.0.7.aar",
29
- "size": 3960730,
30
- "sha512": "d8e00a3051371232e9f2f7bc7320e9089c55aae906bc8f8df09406ce5775b17ed540c1b9a25c2823065205cf210f597cc7f242c70110a4937dfdc1cbd59910f8",
31
- "sha256": "78b46f48418af458641ebe11aa817d720cf8151df9ec6a98b1014c7afaf6b8dd",
32
- "sha1": "d191c3473a6edb27ecae54943add203f7c4293bc",
33
- "md5": "b04cf2c2c4827622110ee74401aa05d7"
27
+ "name": "expo.modules.sqlite-58.0.9.aar",
28
+ "url": "expo.modules.sqlite-58.0.9.aar",
29
+ "size": 3958907,
30
+ "sha512": "d3fbb6aad5541429fc0b0c3edb30d9e71f12636e9215617d2cb19750aecb36c4df1efc1bc5f84fb75f816d9db01c4ad9a0f08457d67ae892e2ebb59d3bd26246",
31
+ "sha256": "96b87814356fa93bcc9eb091c5b2f96f243fa661bd70740c352dae65cca23d8f",
32
+ "sha1": "3ef893dc3f6aec4bda329646065115814fd42d0a",
33
+ "md5": "0c582335d4a9a710a780e9e636dbc73a"
34
34
  }
35
35
  ]
36
36
  },
@@ -67,13 +67,13 @@
67
67
  ],
68
68
  "files": [
69
69
  {
70
- "name": "expo.modules.sqlite-58.0.7.aar",
71
- "url": "expo.modules.sqlite-58.0.7.aar",
72
- "size": 3960730,
73
- "sha512": "d8e00a3051371232e9f2f7bc7320e9089c55aae906bc8f8df09406ce5775b17ed540c1b9a25c2823065205cf210f597cc7f242c70110a4937dfdc1cbd59910f8",
74
- "sha256": "78b46f48418af458641ebe11aa817d720cf8151df9ec6a98b1014c7afaf6b8dd",
75
- "sha1": "d191c3473a6edb27ecae54943add203f7c4293bc",
76
- "md5": "b04cf2c2c4827622110ee74401aa05d7"
70
+ "name": "expo.modules.sqlite-58.0.9.aar",
71
+ "url": "expo.modules.sqlite-58.0.9.aar",
72
+ "size": 3958907,
73
+ "sha512": "d3fbb6aad5541429fc0b0c3edb30d9e71f12636e9215617d2cb19750aecb36c4df1efc1bc5f84fb75f816d9db01c4ad9a0f08457d67ae892e2ebb59d3bd26246",
74
+ "sha256": "96b87814356fa93bcc9eb091c5b2f96f243fa661bd70740c352dae65cca23d8f",
75
+ "sha1": "3ef893dc3f6aec4bda329646065115814fd42d0a",
76
+ "md5": "0c582335d4a9a710a780e9e636dbc73a"
77
77
  }
78
78
  ]
79
79
  },
@@ -87,13 +87,13 @@
87
87
  },
88
88
  "files": [
89
89
  {
90
- "name": "expo.modules.sqlite-58.0.7-sources.jar",
91
- "url": "expo.modules.sqlite-58.0.7-sources.jar",
92
- "size": 11821,
93
- "sha512": "7584658ab5c9dd4f06e3445b056b83007c6fc6162cdda3b3df67bb9b7ec45e17d686903a37feae801ee8b966ed1bd36de9386d739c783bbaec65391dbaa6dc65",
94
- "sha256": "a4b537cf4b334950fc82e5d251599ed7b3bc6d5c2410a3fdca38b81650fe27c2",
95
- "sha1": "1d398068a3b652c5a9392d4115c9b8258adc42ef",
96
- "md5": "d1da3a6df8335c04eb1b803a0b4e73cf"
90
+ "name": "expo.modules.sqlite-58.0.9-sources.jar",
91
+ "url": "expo.modules.sqlite-58.0.9-sources.jar",
92
+ "size": 12434,
93
+ "sha512": "47d6b003042ef32b80e19b64fd015ffcfa159bb8f08971459211cd6ab971304da58dee6236c2be5319f606f9062d023530dcaa5c2e530bb17e42ab1465d5b95f",
94
+ "sha256": "67dbdc88a1d7fc60c31092ad150a98a30d93d8ca82bbf869609890965425524d",
95
+ "sha1": "afa88d36ec945ad0442cc3582e05eb84b07cb9f1",
96
+ "md5": "f9c01cec01c62d6a619fdc69f237e033"
97
97
  }
98
98
  ]
99
99
  }
@@ -0,0 +1 @@
1
+ a1a758d13d8bfa0a508a0e8e76d619145bf6e9fed21e2793b4c3250c747ab0e2
@@ -0,0 +1 @@
1
+ edceb164c582da1e7acbb0d0e0b64074ef17bb2af5a95a63f0d37e2272b93e8be9802bae030c92050f7dc7b357aa14ccbfa864c78d3818301aec13fecb0b04b0
@@ -9,7 +9,7 @@
9
9
  <modelVersion>4.0.0</modelVersion>
10
10
  <groupId>host.exp.exponent</groupId>
11
11
  <artifactId>expo.modules.sqlite</artifactId>
12
- <version>58.0.7</version>
12
+ <version>58.0.9</version>
13
13
  <packaging>aar</packaging>
14
14
  <name>expo.modules.sqlite</name>
15
15
  <url>https://github.com/expo/expo</url>
@@ -0,0 +1 @@
1
+ 2835028ead37c42578edaaa5b9c5f7610643bd86b825c6e099c90cbfdc764bd7
@@ -0,0 +1 @@
1
+ f3a422c4b7869c9b5bc74f3d85670925330e84ea0af7dbc1366e13122238618d5615159ab2db6d2e5d1b6a489ea69c2eee6051a395a64d4b4f6c841dc4c4bc23
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "expo-sqlite",
3
- "version": "58.0.7",
3
+ "version": "58.0.9",
4
4
  "description": "Provides access to a database using SQLite (https://www.sqlite.org/). The database is persisted across restarts of your app.",
5
5
  "keywords": [
6
6
  "async-storage",
@@ -51,12 +51,12 @@
51
51
  },
52
52
  "devDependencies": {
53
53
  "@expo/spawn-async": "^1.8.0",
54
- "@testing-library/react-native": "^13.3.0",
55
- "@types/jest": "^29.2.1",
54
+ "@testing-library/react-native": "^14.0.1",
55
+ "@types/jest": "^30.0.0",
56
56
  "@types/node": "^22.14.0",
57
57
  "@types/react": "~19.3.0",
58
- "expo": "58.0.0",
59
- "expo-module-scripts": "56.0.4",
58
+ "expo": "58.0.3",
59
+ "expo-module-scripts": "56.0.6",
60
60
  "react-error-boundary": "^4.0.11",
61
61
  "tar": "^7.5.22"
62
62
  },
@@ -1 +0,0 @@
1
- a4b537cf4b334950fc82e5d251599ed7b3bc6d5c2410a3fdca38b81650fe27c2
@@ -1 +0,0 @@
1
- 7584658ab5c9dd4f06e3445b056b83007c6fc6162cdda3b3df67bb9b7ec45e17d686903a37feae801ee8b966ed1bd36de9386d739c783bbaec65391dbaa6dc65
@@ -1 +0,0 @@
1
- d191c3473a6edb27ecae54943add203f7c4293bc
@@ -1 +0,0 @@
1
- 78b46f48418af458641ebe11aa817d720cf8151df9ec6a98b1014c7afaf6b8dd
@@ -1 +0,0 @@
1
- d8e00a3051371232e9f2f7bc7320e9089c55aae906bc8f8df09406ce5775b17ed540c1b9a25c2823065205cf210f597cc7f242c70110a4937dfdc1cbd59910f8