expo-sqlite 58.0.11 → 58.0.13
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.
- package/CHANGELOG.md +17 -0
- package/android/build.gradle +2 -2
- package/build/SQLiteStatement.js +2 -0
- package/build/SQLiteStatement.js.map +1 -1
- package/build/WebConfiguration.d.ts +31 -0
- package/build/WebConfiguration.js +21 -0
- package/build/WebConfiguration.js.map +1 -0
- package/build/index.d.ts +1 -0
- package/build/index.js +1 -0
- package/build/index.js.map +1 -1
- package/dev-plugin-dist/+not-found.html +2 -4
- package/dev-plugin-dist/_expo/static/js/web/{__common-8b6d10c7ab64ecfd128d45105ef5590b.js → __common-aee34a717292738ca49ed967d0e796f7.js} +52 -51
- package/dev-plugin-dist/_expo/static/js/web/{_layout-1da259c4109daa50bd04899675f5d333.js → _layout-86170f32fc74b9317908edb66cc872e4.js} +24 -24
- package/dev-plugin-dist/_expo/static/js/web/{entry-5e24130038c41e25d9a78d08664ef6cb.js → entry-fcb74fa73287d6d1c836ce2e81ceecc7.js} +760 -755
- package/dev-plugin-dist/_expo/static/js/web/{index-17ca77580cae7c249688c43b3b3e0949.js → index-4fc1f9d71818eaeb9b6c90440bfe2513.js} +1740 -1740
- package/dev-plugin-dist/_expo/static/js/web/{worker-cc2e40fb110f53b73733dd7e24d9d8f6.js → worker-bd27852eedf51acf238c99b93cee88b1.js} +17 -17
- package/dev-plugin-dist/_sitemap.html +2 -4
- package/dev-plugin-dist/index.html +2 -4
- package/expo-module.config.json +0 -3
- package/ios/DatabaseFileUtils.swift +101 -5
- package/ios/SQLiteModule.swift +8 -2
- package/ios/Tests/DatabaseFileUtilsTests.swift +119 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/58.0.13/expo.modules.sqlite-58.0.13.aar +0 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/58.0.13/expo.modules.sqlite-58.0.13.aar.md5 +1 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/58.0.13/expo.modules.sqlite-58.0.13.aar.sha1 +1 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/58.0.13/expo.modules.sqlite-58.0.13.aar.sha256 +1 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/58.0.13/expo.modules.sqlite-58.0.13.aar.sha512 +1 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/{58.0.11/expo.modules.sqlite-58.0.11.module → 58.0.13/expo.modules.sqlite-58.0.13.module} +17 -17
- package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/58.0.13/expo.modules.sqlite-58.0.13.module.md5 +1 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/58.0.13/expo.modules.sqlite-58.0.13.module.sha1 +1 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/58.0.13/expo.modules.sqlite-58.0.13.module.sha256 +1 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/58.0.13/expo.modules.sqlite-58.0.13.module.sha512 +1 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/{58.0.11/expo.modules.sqlite-58.0.11.pom → 58.0.13/expo.modules.sqlite-58.0.13.pom} +1 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/58.0.13/expo.modules.sqlite-58.0.13.pom.md5 +1 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/58.0.13/expo.modules.sqlite-58.0.13.pom.sha1 +1 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/58.0.13/expo.modules.sqlite-58.0.13.pom.sha256 +1 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/58.0.13/expo.modules.sqlite-58.0.13.pom.sha512 +1 -0
- package/package.json +3 -3
- package/src/SQLiteStatement.ts +2 -0
- package/src/WebConfiguration.ts +36 -0
- package/src/index.ts +1 -0
- package/web/SQLiteModule.ts +16 -0
- package/web/WorkerChannel.ts +17 -9
- package/web/wa-sqlite/sqlite-api.js +4 -1
- package/web/web.types.ts +6 -0
- package/web/worker.ts +50 -38
- package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/58.0.11/expo.modules.sqlite-58.0.11.aar +0 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/58.0.11/expo.modules.sqlite-58.0.11.aar.md5 +0 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/58.0.11/expo.modules.sqlite-58.0.11.aar.sha1 +0 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/58.0.11/expo.modules.sqlite-58.0.11.aar.sha256 +0 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/58.0.11/expo.modules.sqlite-58.0.11.aar.sha512 +0 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/58.0.11/expo.modules.sqlite-58.0.11.module.md5 +0 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/58.0.11/expo.modules.sqlite-58.0.11.module.sha1 +0 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/58.0.11/expo.modules.sqlite-58.0.11.module.sha256 +0 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/58.0.11/expo.modules.sqlite-58.0.11.module.sha512 +0 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/58.0.11/expo.modules.sqlite-58.0.11.pom.md5 +0 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/58.0.11/expo.modules.sqlite-58.0.11.pom.sha1 +0 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/58.0.11/expo.modules.sqlite-58.0.11.pom.sha256 +0 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/58.0.11/expo.modules.sqlite-58.0.11.pom.sha512 +0 -1
- /package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/{58.0.11/expo.modules.sqlite-58.0.11-sources.jar → 58.0.13/expo.modules.sqlite-58.0.13-sources.jar} +0 -0
- /package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/{58.0.11/expo.modules.sqlite-58.0.11-sources.jar.md5 → 58.0.13/expo.modules.sqlite-58.0.13-sources.jar.md5} +0 -0
- /package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/{58.0.11/expo.modules.sqlite-58.0.11-sources.jar.sha1 → 58.0.13/expo.modules.sqlite-58.0.13-sources.jar.sha1} +0 -0
- /package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/{58.0.11/expo.modules.sqlite-58.0.11-sources.jar.sha256 → 58.0.13/expo.modules.sqlite-58.0.13-sources.jar.sha256} +0 -0
- /package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/{58.0.11/expo.modules.sqlite-58.0.11-sources.jar.sha512 → 58.0.13/expo.modules.sqlite-58.0.13-sources.jar.sha512} +0 -0
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
<!DOCTYPE html><html
|
|
1
|
+
<!DOCTYPE html><html lang="en"><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"/><meta http-equiv="X-UA-Compatible" content="IE=edge"/><link rel="preload" href="/_expo/plugins/expo-sqlite/_expo/static/css/global-b1bdf830cdbd0ec4238cc5f230f99460.css" as="style"/><link rel="preload" href="/_expo/plugins/expo-sqlite/_expo/static/js/web/__expo-metro-runtime-8c088df87a31e4e6accd81c554ec290d.js" as="script"/><link rel="preload" href="/_expo/plugins/expo-sqlite/_expo/static/js/web/_layout-86170f32fc74b9317908edb66cc872e4.js" as="script"/><link rel="preload" href="/_expo/plugins/expo-sqlite/_expo/static/js/web/__common-aee34a717292738ca49ed967d0e796f7.js" as="script"/><link rel="preload" href="/_expo/plugins/expo-sqlite/_expo/static/js/web/entry-fcb74fa73287d6d1c836ce2e81ceecc7.js" as="script"/><style id="expo-reset">#root,body,html{height:100%}body{overflow:hidden}#root{display:flex}</style><style id="react-native-stylesheet">[stylesheet-group="0"]{}
|
|
2
2
|
body{margin:0;}
|
|
3
3
|
button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0;}
|
|
4
4
|
html{-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%;-webkit-tap-highlight-color:rgba(0,0,0,0);}
|
|
@@ -313,6 +313,4 @@ input::-webkit-search-cancel-button,input::-webkit-search-decoration,input::-web
|
|
|
313
313
|
@keyframes r-1pzkwqh{0%{transform:translateY(100%);}100%{transform:translateY(0%);}}
|
|
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
|
-
@keyframes r-t2lo5v{0%{opacity:1;}100%{opacity:0;}}</style><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-1da259c4109daa50bd04899675f5d333.js" defer></script><script src="/_expo/plugins/expo-sqlite/_expo/static/js/web/__common-8b6d10c7ab64ecfd128d45105ef5590b.js" defer></script><script src="/_expo/plugins/expo-sqlite/_expo/static/js/web/entry-5e24130038c41e25d9a78d08664ef6cb.js" defer></script>
|
|
318
|
-
</body></html>
|
|
316
|
+
@keyframes r-t2lo5v{0%{opacity:1;}100%{opacity:0;}}</style><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 defer="" src="/_expo/plugins/expo-sqlite/_expo/static/js/web/__expo-metro-runtime-8c088df87a31e4e6accd81c554ec290d.js"></script><script defer="" src="/_expo/plugins/expo-sqlite/_expo/static/js/web/_layout-86170f32fc74b9317908edb66cc872e4.js"></script><script defer="" src="/_expo/plugins/expo-sqlite/_expo/static/js/web/__common-aee34a717292738ca49ed967d0e796f7.js"></script><script defer="" src="/_expo/plugins/expo-sqlite/_expo/static/js/web/entry-fcb74fa73287d6d1c836ce2e81ceecc7.js"></script><script id="_R_">globalThis.__EXPO_ROUTER_HYDRATE__=true;</script></body></html>
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
<!DOCTYPE html><html
|
|
1
|
+
<!DOCTYPE html><html lang="en"><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"/><meta http-equiv="X-UA-Compatible" content="IE=edge"/><link rel="preload" href="/_expo/plugins/expo-sqlite/_expo/static/css/global-b1bdf830cdbd0ec4238cc5f230f99460.css" as="style"/><link rel="preload" href="/_expo/plugins/expo-sqlite/_expo/static/js/web/__expo-metro-runtime-8c088df87a31e4e6accd81c554ec290d.js" as="script"/><link rel="preload" href="/_expo/plugins/expo-sqlite/_expo/static/js/web/_layout-86170f32fc74b9317908edb66cc872e4.js" as="script"/><link rel="preload" href="/_expo/plugins/expo-sqlite/_expo/static/js/web/index-4fc1f9d71818eaeb9b6c90440bfe2513.js" as="script"/><link rel="preload" href="/_expo/plugins/expo-sqlite/_expo/static/js/web/__common-aee34a717292738ca49ed967d0e796f7.js" as="script"/><link rel="preload" href="/_expo/plugins/expo-sqlite/_expo/static/js/web/entry-fcb74fa73287d6d1c836ce2e81ceecc7.js" as="script"/><style id="expo-reset">#root,body,html{height:100%}body{overflow:hidden}#root{display:flex}</style><style id="react-native-stylesheet">[stylesheet-group="0"]{}
|
|
2
2
|
body{margin:0;}
|
|
3
3
|
button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0;}
|
|
4
4
|
html{-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%;-webkit-tap-highlight-color:rgba(0,0,0,0);}
|
|
@@ -313,6 +313,4 @@ input::-webkit-search-cancel-button,input::-webkit-search-decoration,input::-web
|
|
|
313
313
|
@keyframes r-1pzkwqh{0%{transform:translateY(100%);}100%{transform:translateY(0%);}}
|
|
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
|
-
@keyframes r-t2lo5v{0%{opacity:1;}100%{opacity:0;}}</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 [&_svg]:pointer-events-none [&_svg]:size-4 [&_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-1da259c4109daa50bd04899675f5d333.js" defer></script><script src="/_expo/plugins/expo-sqlite/_expo/static/js/web/index-17ca77580cae7c249688c43b3b3e0949.js" defer></script><script src="/_expo/plugins/expo-sqlite/_expo/static/js/web/__common-8b6d10c7ab64ecfd128d45105ef5590b.js" defer></script><script src="/_expo/plugins/expo-sqlite/_expo/static/js/web/entry-5e24130038c41e25d9a78d08664ef6cb.js" defer></script>
|
|
318
|
-
</body></html>
|
|
316
|
+
@keyframes r-t2lo5v{0%{opacity:1;}100%{opacity:0;}}</style><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_jepm_-content-devtools" data-state="active" data-disabled="" disabled="" id="radix-_R_jepm_-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_jepm_-content-upload" data-state="inactive" id="radix-_R_jepm_-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_jepm_-trigger-upload" hidden="" id="radix-_R_jepm_-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_jepm_-trigger-devtools" id="radix-_R_jepm_-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 [&_svg]:pointer-events-none [&_svg]:size-4 [&_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 defer="" src="/_expo/plugins/expo-sqlite/_expo/static/js/web/__expo-metro-runtime-8c088df87a31e4e6accd81c554ec290d.js"></script><script defer="" src="/_expo/plugins/expo-sqlite/_expo/static/js/web/_layout-86170f32fc74b9317908edb66cc872e4.js"></script><script defer="" src="/_expo/plugins/expo-sqlite/_expo/static/js/web/index-4fc1f9d71818eaeb9b6c90440bfe2513.js"></script><script defer="" src="/_expo/plugins/expo-sqlite/_expo/static/js/web/__common-aee34a717292738ca49ed967d0e796f7.js"></script><script defer="" src="/_expo/plugins/expo-sqlite/_expo/static/js/web/entry-fcb74fa73287d6d1c836ce2e81ceecc7.js"></script><script id="_R_">globalThis.__EXPO_ROUTER_HYDRATE__=true;</script></body></html>
|
package/expo-module.config.json
CHANGED
|
@@ -3,6 +3,92 @@
|
|
|
3
3
|
import Foundation
|
|
4
4
|
|
|
5
5
|
internal enum DatabaseFileUtils {
|
|
6
|
+
/// Files SQLite keeps next to the main database and that must travel with it.
|
|
7
|
+
static let sidecarSuffixes = ["-journal", "-wal", "-shm"]
|
|
8
|
+
|
|
9
|
+
private static let migrationLock = NSLock()
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
Resolves the database path JavaScript sends into a `URL`. A `file:` URI is percent-encoded before
|
|
13
|
+
`URL(string:)` so spaces, non-ASCII characters, `#` and `?` survive on every supported OS, and
|
|
14
|
+
escapes that were already present stay as they are. A plain path goes through
|
|
15
|
+
`URL(fileURLWithPath:)`, which never parses the string as a URL.
|
|
16
|
+
*/
|
|
17
|
+
static func fileURL(fromDatabasePath path: String) -> URL? {
|
|
18
|
+
guard path.hasPrefix("file:") else {
|
|
19
|
+
return URL(fileURLWithPath: path)
|
|
20
|
+
}
|
|
21
|
+
var allowed = CharacterSet.urlPathAllowed
|
|
22
|
+
allowed.insert(charactersIn: ":/")
|
|
23
|
+
guard let encoded = path.addingPercentEncoding(withAllowedCharacters: allowed) else {
|
|
24
|
+
return nil
|
|
25
|
+
}
|
|
26
|
+
// `%` is not path-allowed, so an input escape such as `%20` became `%2520`. Restore only escapes
|
|
27
|
+
// followed by two hex digits; a bare `%` in a file name keeps its new `%25`.
|
|
28
|
+
let restored = encoded.replacingOccurrences(
|
|
29
|
+
of: "%25([0-9A-Fa-f]{2})",
|
|
30
|
+
with: "%$1",
|
|
31
|
+
options: .regularExpression
|
|
32
|
+
)
|
|
33
|
+
return URL(string: restored)
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
Returns the path earlier releases passed to SQLite, where `URL(string:)` percent-encoded the input
|
|
38
|
+
on iOS 17 and later. Returns `nil` when it equals `resolvedPath` or is not just its encoded form,
|
|
39
|
+
so a name truncated at `#` or `?` is left alone.
|
|
40
|
+
*/
|
|
41
|
+
static func legacyEncodedPath(forDatabasePath path: String, resolvedPath: String) -> String? {
|
|
42
|
+
guard let oldPath = URL(string: path)?.toFilePath() else {
|
|
43
|
+
return nil
|
|
44
|
+
}
|
|
45
|
+
let legacyPath = URL(fileURLWithPath: oldPath).standardizedFileURL.path
|
|
46
|
+
guard legacyPath != resolvedPath, legacyPath.removingPercentEncoding == resolvedPath else {
|
|
47
|
+
return nil
|
|
48
|
+
}
|
|
49
|
+
return legacyPath
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
Moves a database left under its legacy percent-encoded name, with its sidecar files, to `path`.
|
|
54
|
+
Sidecars move first so a crash leaves the database with its journal and the next open retries.
|
|
55
|
+
*/
|
|
56
|
+
static func migrateLegacyDatabaseFiles(fromPath legacyPath: String, toPath path: String) throws {
|
|
57
|
+
migrationLock.lock()
|
|
58
|
+
defer { migrationLock.unlock() }
|
|
59
|
+
|
|
60
|
+
let fileManager = FileManager.default
|
|
61
|
+
let databaseExists = fileManager.fileExists(atPath: path)
|
|
62
|
+
let legacyDatabaseExists = fileManager.fileExists(atPath: legacyPath)
|
|
63
|
+
// With both databases present the legacy sidecars belong to the other one.
|
|
64
|
+
guard databaseExists != legacyDatabaseExists else {
|
|
65
|
+
return
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
for suffix in ["-journal", "-wal"] {
|
|
69
|
+
let legacySidecar = legacyPath + suffix
|
|
70
|
+
guard fileManager.fileExists(atPath: legacySidecar) else {
|
|
71
|
+
continue
|
|
72
|
+
}
|
|
73
|
+
let sidecar = path + suffix
|
|
74
|
+
if fileManager.fileExists(atPath: sidecar) {
|
|
75
|
+
// The moved database already wrote its own; the stale legacy one is kept, not deleted.
|
|
76
|
+
if databaseExists {
|
|
77
|
+
continue
|
|
78
|
+
}
|
|
79
|
+
try fileManager.removeItem(atPath: sidecar)
|
|
80
|
+
}
|
|
81
|
+
try fileManager.moveItem(atPath: legacySidecar, toPath: sidecar)
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
try? fileManager.removeItem(atPath: legacyPath + "-shm")
|
|
85
|
+
if databaseExists {
|
|
86
|
+
return
|
|
87
|
+
}
|
|
88
|
+
try? fileManager.removeItem(atPath: path + "-shm")
|
|
89
|
+
try fileManager.moveItem(atPath: legacyPath, toPath: path)
|
|
90
|
+
}
|
|
91
|
+
|
|
6
92
|
/**
|
|
7
93
|
Deletes the database file at the given path together with its `-journal`, `-wal` and `-shm`
|
|
8
94
|
sidecar files, mirroring the behavior of Android's `SQLiteDatabase.deleteDatabase()`.
|
|
@@ -19,11 +105,21 @@ internal enum DatabaseFileUtils {
|
|
|
19
105
|
throw DeleteDatabaseFileException(path)
|
|
20
106
|
}
|
|
21
107
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
108
|
+
removeSidecarFiles(atPath: path)
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/// Removes the database file and its sidecar files when present. Missing files are not an error.
|
|
112
|
+
static func removeDatabaseFiles(atPath path: String) {
|
|
113
|
+
if FileManager.default.fileExists(atPath: path) {
|
|
114
|
+
try? FileManager.default.removeItem(atPath: path)
|
|
115
|
+
}
|
|
116
|
+
removeSidecarFiles(atPath: path)
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
private static func removeSidecarFiles(atPath path: String) {
|
|
120
|
+
let fileManager = FileManager.default
|
|
121
|
+
for suffix in sidecarSuffixes where fileManager.fileExists(atPath: path + suffix) {
|
|
122
|
+
try? fileManager.removeItem(atPath: path + suffix)
|
|
27
123
|
}
|
|
28
124
|
}
|
|
29
125
|
}
|
package/ios/SQLiteModule.swift
CHANGED
|
@@ -187,11 +187,17 @@ public final class SQLiteModule: Module, @unchecked Sendable {
|
|
|
187
187
|
throw Exceptions.FileSystemModuleNotFound()
|
|
188
188
|
}
|
|
189
189
|
|
|
190
|
-
guard let pathUrl =
|
|
190
|
+
guard let pathUrl = DatabaseFileUtils.fileURL(fromDatabasePath: path) else {
|
|
191
191
|
throw DatabaseInvalidPathException(path)
|
|
192
192
|
}
|
|
193
|
+
let filePath = pathUrl.toFilePath()
|
|
193
194
|
fileSystem.ensureDirExists(withPath: pathUrl.deletingLastPathComponent().toFilePath())
|
|
194
195
|
|
|
196
|
+
// Installs made on iOS 17+ before this resolution opened a percent-encoded file name.
|
|
197
|
+
if let legacyPath = DatabaseFileUtils.legacyEncodedPath(forDatabasePath: path, resolvedPath: filePath) {
|
|
198
|
+
try DatabaseFileUtils.migrateLegacyDatabaseFiles(fromPath: legacyPath, toPath: filePath)
|
|
199
|
+
}
|
|
200
|
+
|
|
195
201
|
return pathUrl
|
|
196
202
|
}
|
|
197
203
|
|
|
@@ -285,7 +291,7 @@ public final class SQLiteModule: Module, @unchecked Sendable {
|
|
|
285
291
|
fileManager.fileExists(atPath: assetPath) else {
|
|
286
292
|
throw DatabaseNotFoundException(assetDatabasePath)
|
|
287
293
|
}
|
|
288
|
-
|
|
294
|
+
DatabaseFileUtils.removeDatabaseFiles(atPath: path.toFilePath())
|
|
289
295
|
try fileManager.copyItem(atPath: assetPath, toPath: path.toFilePath())
|
|
290
296
|
}
|
|
291
297
|
|
|
@@ -68,4 +68,123 @@ final class DatabaseFileUtilsTests {
|
|
|
68
68
|
try DatabaseFileUtils.deleteDatabaseFiles(atPath: dbPath)
|
|
69
69
|
}
|
|
70
70
|
}
|
|
71
|
+
|
|
72
|
+
@Test
|
|
73
|
+
func `removes database files and sidecars and ignores missing ones`() {
|
|
74
|
+
let dbPath = createFile("test.db")
|
|
75
|
+
let walPath = createFile("test.db-wal")
|
|
76
|
+
let shmPath = createFile("test.db-shm")
|
|
77
|
+
let missingPath = tempDir.appendingPathComponent("missing.db").path
|
|
78
|
+
|
|
79
|
+
DatabaseFileUtils.removeDatabaseFiles(atPath: dbPath)
|
|
80
|
+
DatabaseFileUtils.removeDatabaseFiles(atPath: missingPath)
|
|
81
|
+
|
|
82
|
+
#expect(!FileManager.default.fileExists(atPath: dbPath))
|
|
83
|
+
#expect(!FileManager.default.fileExists(atPath: walPath))
|
|
84
|
+
#expect(!FileManager.default.fileExists(atPath: shmPath))
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
@Test
|
|
88
|
+
func `resolves a plain path with spaces and non-ASCII characters as is`() {
|
|
89
|
+
let path = "/tmp/My Dir/a#b?c データ.db"
|
|
90
|
+
|
|
91
|
+
#expect(DatabaseFileUtils.fileURL(fromDatabasePath: path)?.toFilePath() == path)
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
@Test
|
|
95
|
+
func `resolves a file URI with spaces, non-ASCII characters, hash and question mark`() {
|
|
96
|
+
let url = DatabaseFileUtils.fileURL(fromDatabasePath: "file:///tmp/My Dir/a#b?c データ.db")
|
|
97
|
+
|
|
98
|
+
#expect(url?.isFileURL == true)
|
|
99
|
+
#expect(url?.toFilePath() == "/tmp/My Dir/a#b?c データ.db")
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
@Test
|
|
103
|
+
func `keeps escapes of an already encoded file URI`() {
|
|
104
|
+
let url = DatabaseFileUtils.fileURL(fromDatabasePath: "file:///tmp/My%20Dir/%E3%83%87.db")
|
|
105
|
+
|
|
106
|
+
#expect(url?.toFilePath() == "/tmp/My Dir/デ.db")
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
@Test
|
|
110
|
+
func `reports the legacy percent-encoded path only when it decodes to the resolved path`() {
|
|
111
|
+
guard #available(iOS 17, tvOS 17, macOS 14, *) else {
|
|
112
|
+
return
|
|
113
|
+
}
|
|
114
|
+
let plainPath = "/tmp/My Dir/a.db"
|
|
115
|
+
let legacyPath = DatabaseFileUtils.legacyEncodedPath(forDatabasePath: plainPath, resolvedPath: plainPath)
|
|
116
|
+
|
|
117
|
+
#expect(legacyPath == "/tmp/My%20Dir/a.db")
|
|
118
|
+
#expect(DatabaseFileUtils.legacyEncodedPath(forDatabasePath: "/tmp/dir/a.db", resolvedPath: "/tmp/dir/a.db") == nil)
|
|
119
|
+
#expect(DatabaseFileUtils.legacyEncodedPath(forDatabasePath: "/tmp/dir/a#b.db", resolvedPath: "/tmp/dir/a#b.db") == nil)
|
|
120
|
+
#expect(DatabaseFileUtils.legacyEncodedPath(forDatabasePath: "file:///tmp/My Dir/a.db", resolvedPath: plainPath) == nil)
|
|
121
|
+
#expect(DatabaseFileUtils.legacyEncodedPath(forDatabasePath: "file:///tmp/My%20Dir/my data.db", resolvedPath: "/tmp/My Dir/my data.db") == "/tmp/My%20Dir/my data.db")
|
|
122
|
+
#expect(DatabaseFileUtils.legacyEncodedPath(forDatabasePath: "file:///tmp/dir/a#b.db", resolvedPath: "/tmp/dir/a#b.db") == nil)
|
|
123
|
+
#expect(DatabaseFileUtils.legacyEncodedPath(forDatabasePath: "/tmp/a/../My Dir/n.db", resolvedPath: "/tmp/My Dir/n.db") == "/tmp/My%20Dir/n.db")
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
@Test
|
|
127
|
+
func `moves legacy database files and sidecars to the resolved path`() throws {
|
|
128
|
+
let legacyPath = createFile("legacy.db")
|
|
129
|
+
let legacyWalPath = createFile("legacy.db-wal")
|
|
130
|
+
let path = tempDir.appendingPathComponent("resolved.db").path
|
|
131
|
+
|
|
132
|
+
try DatabaseFileUtils.migrateLegacyDatabaseFiles(fromPath: legacyPath, toPath: path)
|
|
133
|
+
|
|
134
|
+
#expect(FileManager.default.fileExists(atPath: path))
|
|
135
|
+
#expect(FileManager.default.fileExists(atPath: path + "-wal"))
|
|
136
|
+
#expect(!FileManager.default.fileExists(atPath: legacyPath))
|
|
137
|
+
#expect(!FileManager.default.fileExists(atPath: legacyWalPath))
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
@Test
|
|
141
|
+
func `does not migrate when the resolved database already exists`() throws {
|
|
142
|
+
let legacyPath = createFile("legacy.db")
|
|
143
|
+
let legacyWalPath = createFile("legacy.db-wal")
|
|
144
|
+
let path = createFile("resolved.db")
|
|
145
|
+
|
|
146
|
+
try DatabaseFileUtils.migrateLegacyDatabaseFiles(fromPath: legacyPath, toPath: path)
|
|
147
|
+
|
|
148
|
+
#expect(FileManager.default.fileExists(atPath: legacyPath))
|
|
149
|
+
#expect(FileManager.default.fileExists(atPath: legacyWalPath))
|
|
150
|
+
#expect(!FileManager.default.fileExists(atPath: path + "-wal"))
|
|
151
|
+
#expect(String(data: FileManager.default.contents(atPath: path) ?? Data(), encoding: .utf8) == "data")
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
@Test
|
|
155
|
+
func `replaces an orphan resolved wal when the database has not moved yet`() throws {
|
|
156
|
+
let legacyPath = createFile("legacy.db")
|
|
157
|
+
let legacyWalPath = tempDir.appendingPathComponent("legacy.db-wal").path
|
|
158
|
+
FileManager.default.createFile(atPath: legacyWalPath, contents: Data("current".utf8))
|
|
159
|
+
let path = tempDir.appendingPathComponent("resolved.db").path
|
|
160
|
+
FileManager.default.createFile(atPath: path + "-wal", contents: Data("orphan".utf8))
|
|
161
|
+
let shmPath = createFile("resolved.db-shm")
|
|
162
|
+
|
|
163
|
+
try DatabaseFileUtils.migrateLegacyDatabaseFiles(fromPath: legacyPath, toPath: path)
|
|
164
|
+
|
|
165
|
+
#expect(FileManager.default.fileExists(atPath: path))
|
|
166
|
+
#expect(String(data: FileManager.default.contents(atPath: path + "-wal") ?? Data(), encoding: .utf8) == "current")
|
|
167
|
+
#expect(!FileManager.default.fileExists(atPath: legacyPath))
|
|
168
|
+
#expect(!FileManager.default.fileExists(atPath: legacyWalPath))
|
|
169
|
+
#expect(!FileManager.default.fileExists(atPath: shmPath))
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
@Test
|
|
173
|
+
func `moves only the legacy sidecars the moved database is missing`() throws {
|
|
174
|
+
let legacyPath = tempDir.appendingPathComponent("legacy.db").path
|
|
175
|
+
let legacyWalPath = createFile("legacy.db-wal")
|
|
176
|
+
let legacyShmPath = createFile("legacy.db-shm")
|
|
177
|
+
let legacyJournalPath = tempDir.appendingPathComponent("legacy.db-journal").path
|
|
178
|
+
FileManager.default.createFile(atPath: legacyJournalPath, contents: Data("stale".utf8))
|
|
179
|
+
let path = createFile("resolved.db")
|
|
180
|
+
FileManager.default.createFile(atPath: path + "-journal", contents: Data("current".utf8))
|
|
181
|
+
|
|
182
|
+
try DatabaseFileUtils.migrateLegacyDatabaseFiles(fromPath: legacyPath, toPath: path)
|
|
183
|
+
|
|
184
|
+
#expect(FileManager.default.fileExists(atPath: path + "-wal"))
|
|
185
|
+
#expect(!FileManager.default.fileExists(atPath: legacyWalPath))
|
|
186
|
+
#expect(!FileManager.default.fileExists(atPath: legacyShmPath))
|
|
187
|
+
#expect(String(data: FileManager.default.contents(atPath: path + "-journal") ?? Data(), encoding: .utf8) == "current")
|
|
188
|
+
#expect(FileManager.default.fileExists(atPath: legacyJournalPath))
|
|
189
|
+
}
|
|
71
190
|
}
|
|
Binary file
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
1af2148fbaeeb30664bdd0987e032cb5
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
10ea3cf3df5cddca0c574e3f8da6cbe34b328b7f
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
cfc123cf8f0ec710d7e4d3f5e9c0f7731d20bb1e00dec63ee36d6e479420b503
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
11eb4310b2587d91fe724da5b36c3300292fca51df03d1ecd1ef1ab1b8a7831ce5a69b574a0f5501fa712775921cb652b44becf9a8020fb5af5cad6fa79a6789
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"component": {
|
|
4
4
|
"group": "host.exp.exponent",
|
|
5
5
|
"module": "expo.modules.sqlite",
|
|
6
|
-
"version": "58.0.
|
|
6
|
+
"version": "58.0.13",
|
|
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.
|
|
28
|
-
"url": "expo.modules.sqlite-58.0.
|
|
29
|
-
"size":
|
|
30
|
-
"sha512": "
|
|
31
|
-
"sha256": "
|
|
32
|
-
"sha1": "
|
|
33
|
-
"md5": "
|
|
27
|
+
"name": "expo.modules.sqlite-58.0.13.aar",
|
|
28
|
+
"url": "expo.modules.sqlite-58.0.13.aar",
|
|
29
|
+
"size": 3846060,
|
|
30
|
+
"sha512": "11eb4310b2587d91fe724da5b36c3300292fca51df03d1ecd1ef1ab1b8a7831ce5a69b574a0f5501fa712775921cb652b44becf9a8020fb5af5cad6fa79a6789",
|
|
31
|
+
"sha256": "cfc123cf8f0ec710d7e4d3f5e9c0f7731d20bb1e00dec63ee36d6e479420b503",
|
|
32
|
+
"sha1": "10ea3cf3df5cddca0c574e3f8da6cbe34b328b7f",
|
|
33
|
+
"md5": "1af2148fbaeeb30664bdd0987e032cb5"
|
|
34
34
|
}
|
|
35
35
|
]
|
|
36
36
|
},
|
|
@@ -67,13 +67,13 @@
|
|
|
67
67
|
],
|
|
68
68
|
"files": [
|
|
69
69
|
{
|
|
70
|
-
"name": "expo.modules.sqlite-58.0.
|
|
71
|
-
"url": "expo.modules.sqlite-58.0.
|
|
72
|
-
"size":
|
|
73
|
-
"sha512": "
|
|
74
|
-
"sha256": "
|
|
75
|
-
"sha1": "
|
|
76
|
-
"md5": "
|
|
70
|
+
"name": "expo.modules.sqlite-58.0.13.aar",
|
|
71
|
+
"url": "expo.modules.sqlite-58.0.13.aar",
|
|
72
|
+
"size": 3846060,
|
|
73
|
+
"sha512": "11eb4310b2587d91fe724da5b36c3300292fca51df03d1ecd1ef1ab1b8a7831ce5a69b574a0f5501fa712775921cb652b44becf9a8020fb5af5cad6fa79a6789",
|
|
74
|
+
"sha256": "cfc123cf8f0ec710d7e4d3f5e9c0f7731d20bb1e00dec63ee36d6e479420b503",
|
|
75
|
+
"sha1": "10ea3cf3df5cddca0c574e3f8da6cbe34b328b7f",
|
|
76
|
+
"md5": "1af2148fbaeeb30664bdd0987e032cb5"
|
|
77
77
|
}
|
|
78
78
|
]
|
|
79
79
|
},
|
|
@@ -87,8 +87,8 @@
|
|
|
87
87
|
},
|
|
88
88
|
"files": [
|
|
89
89
|
{
|
|
90
|
-
"name": "expo.modules.sqlite-58.0.
|
|
91
|
-
"url": "expo.modules.sqlite-58.0.
|
|
90
|
+
"name": "expo.modules.sqlite-58.0.13-sources.jar",
|
|
91
|
+
"url": "expo.modules.sqlite-58.0.13-sources.jar",
|
|
92
92
|
"size": 14875,
|
|
93
93
|
"sha512": "93ce18d06cc3125618ca50503fd5b7f6d7407b05e931ddf6381fa7e70d8b41c6719c65a433fafa28626a12335b6e9f9a5e4cd05036f715e7a5b01c94047fddf7",
|
|
94
94
|
"sha256": "e4feeb357b13c3da0d6690deff9aab2186a7874185369a06c55fa6da992fdc9c",
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
50d06da680ac3a5a8435d3240fcd82ad
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
ab76e88f709ea60d2dee5aedf259f427362a7fe1
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
c883ea922f3861a7ed3e595056f8ef2352b4565367f3dec8e294ccdddab7490e
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
307d540ca62a1ed0397549fcf5ce754e69163fd15834cf9400c835dbfe9c3cad79d6221d8fae76f8afc72938718020fb35cd26a745d1ebce0d8840120bce0ad9
|
|
@@ -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.
|
|
12
|
+
<version>58.0.13</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
|
+
caf3382b6464ae01e1a2761ea2a11ec2
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
85267a81302c60881ce7473c641c68f802c650a0
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
768c6e8a9c3e6a210b4189ac5c692725b94040316ab6d810486dc992a36c5f05
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
ab5aab66dab5a7ba35f20244e80302ac5ea55f6b0b1a3a06e5f4256265b08a3b3806f7ab968726ca965fbb090e30c68f4bdcb3bd33d41be458582bf84c908aa8
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "expo-sqlite",
|
|
3
|
-
"version": "58.0.
|
|
3
|
+
"version": "58.0.13",
|
|
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",
|
|
@@ -50,13 +50,13 @@
|
|
|
50
50
|
"await-lock": "^2.2.2"
|
|
51
51
|
},
|
|
52
52
|
"devDependencies": {
|
|
53
|
-
"@expo/internal-scripts": "58.0.
|
|
53
|
+
"@expo/internal-scripts": "58.0.2",
|
|
54
54
|
"@expo/spawn-async": "^1.8.0",
|
|
55
55
|
"@testing-library/react-native": "^14.0.1",
|
|
56
56
|
"@types/jest": "^30.0.0",
|
|
57
57
|
"@types/node": "^22.14.0",
|
|
58
58
|
"@types/react": "~19.3.0",
|
|
59
|
-
"expo": "58.0.
|
|
59
|
+
"expo": "58.0.10",
|
|
60
60
|
"react-error-boundary": "^4.0.11",
|
|
61
61
|
"tar": "^7.5.22"
|
|
62
62
|
},
|
package/src/SQLiteStatement.ts
CHANGED
|
@@ -604,6 +604,7 @@ class SQLiteExecuteSyncResultImpl<T> {
|
|
|
604
604
|
'The SQLite cursor has been shifted and is unable to retrieve the first row without being reset. Invoke `resetSync()` to reset the cursor first if you want to retrieve the first row.'
|
|
605
605
|
);
|
|
606
606
|
}
|
|
607
|
+
this.isStepCalled = true;
|
|
607
608
|
const columnNames = this.getColumnNamesSync();
|
|
608
609
|
const firstRowValues = this.popFirstRowValues();
|
|
609
610
|
if (firstRowValues != null) {
|
|
@@ -641,6 +642,7 @@ class SQLiteExecuteSyncResultImpl<T> {
|
|
|
641
642
|
}
|
|
642
643
|
|
|
643
644
|
*generatorSync(): IterableIterator<T> {
|
|
645
|
+
this.isStepCalled = true;
|
|
644
646
|
const columnNames = this.getColumnNamesSync();
|
|
645
647
|
const firstRowValues = this.popFirstRowValues();
|
|
646
648
|
if (firstRowValues != null) {
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import ExpoSQLite from './ExpoSQLite';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Options for [`configureWeb()`](#sqliteconfigureweboptions).
|
|
5
|
+
* @platform web
|
|
6
|
+
*/
|
|
7
|
+
export interface SQLiteWebOptions {
|
|
8
|
+
/**
|
|
9
|
+
* The URL of a custom wa-sqlite WebAssembly build, for example one built with FTS enabled.
|
|
10
|
+
* When omitted, `expo-sqlite` uses its bundled build.
|
|
11
|
+
*
|
|
12
|
+
* The build must come from the [`expo/wa-sqlite`](https://github.com/expo/wa-sqlite) revision that matches your `expo-sqlite` version.
|
|
13
|
+
* A build from another revision may fail to load.
|
|
14
|
+
*/
|
|
15
|
+
wasmURL?: string;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Configures how `expo-sqlite` runs on web.
|
|
20
|
+
* Each call replaces the options from the previous call.
|
|
21
|
+
* It has no effect on Android, iOS, and server rendering.
|
|
22
|
+
*
|
|
23
|
+
* Call it before opening any database.
|
|
24
|
+
* It throws if `wasmURL` changes after a database is opened, because the web worker loads SQLite only once.
|
|
25
|
+
*
|
|
26
|
+
* @example
|
|
27
|
+
* ```ts
|
|
28
|
+
* SQLite.configureWeb({ wasmURL: require('./assets/wa-sqlite-fts.wasm') });
|
|
29
|
+
* const db = await SQLite.openDatabaseAsync('app.db');
|
|
30
|
+
* ```
|
|
31
|
+
*
|
|
32
|
+
* @platform web
|
|
33
|
+
*/
|
|
34
|
+
export function configureWeb(options: SQLiteWebOptions): void {
|
|
35
|
+
ExpoSQLite.configureWeb?.(options);
|
|
36
|
+
}
|
package/src/index.ts
CHANGED
package/web/SQLiteModule.ts
CHANGED
|
@@ -11,9 +11,12 @@ import {
|
|
|
11
11
|
type SQLiteColumnValues,
|
|
12
12
|
type SQLiteRunResult,
|
|
13
13
|
} from '../src/NativeStatement';
|
|
14
|
+
import { type SQLiteWebOptions } from '../src/WebConfiguration';
|
|
14
15
|
import { invokeWorkerAsync, invokeWorkerSync, workerMessageHandler } from './WorkerChannel';
|
|
16
|
+
import { type ConfigureWorkerMessage } from './web.types';
|
|
15
17
|
|
|
16
18
|
let worker: Worker | null = null;
|
|
19
|
+
let webOptions: SQLiteWebOptions = {};
|
|
17
20
|
let nextNativeDatabaseId = 0;
|
|
18
21
|
let nextNativeStatementId = 0;
|
|
19
22
|
let nextNativeSessionId = 0;
|
|
@@ -29,6 +32,7 @@ function getWorker(): Worker {
|
|
|
29
32
|
}
|
|
30
33
|
workerMessageHandler(event);
|
|
31
34
|
});
|
|
35
|
+
worker.postMessage({ type: 'configure', data: webOptions } satisfies ConfigureWorkerMessage);
|
|
32
36
|
}
|
|
33
37
|
return worker;
|
|
34
38
|
}
|
|
@@ -427,6 +431,18 @@ export class SQLiteModule extends NativeModule {
|
|
|
427
431
|
});
|
|
428
432
|
}
|
|
429
433
|
|
|
434
|
+
configureWeb(options: SQLiteWebOptions): void {
|
|
435
|
+
if (worker != null) {
|
|
436
|
+
// Fast Refresh runs the same call again after a database is open.
|
|
437
|
+
if (options.wasmURL === webOptions.wasmURL) return;
|
|
438
|
+
throw new Error(
|
|
439
|
+
'Cannot change the SQLite WebAssembly URL because a database has already been opened, and the web worker loads SQLite only once. ' +
|
|
440
|
+
'Call `configureWeb()` before opening any database, and reload the app after you change `wasmURL`.'
|
|
441
|
+
);
|
|
442
|
+
}
|
|
443
|
+
webOptions = { ...options };
|
|
444
|
+
}
|
|
445
|
+
|
|
430
446
|
async ensureDatabasePathExistsAsync(databasePath: string): Promise<void> {
|
|
431
447
|
// No-op for web
|
|
432
448
|
}
|
package/web/WorkerChannel.ts
CHANGED
|
@@ -33,21 +33,29 @@ export function sendWorkerResult({
|
|
|
33
33
|
resultBuffer: SharedArrayBuffer;
|
|
34
34
|
};
|
|
35
35
|
}) {
|
|
36
|
+
// Send the message as a string. An Error doesn't survive JSON, and `String(error)` keeps it non-empty.
|
|
37
|
+
const errorMessage = error != null ? error.message || String(error) : null;
|
|
36
38
|
if (syncTrait) {
|
|
37
39
|
const { lockBuffer, resultBuffer } = syncTrait;
|
|
38
40
|
const lock = new Int32Array(lockBuffer);
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
41
|
+
let resultBytes = new TextEncoder().encode(
|
|
42
|
+
errorMessage != null ? serialize({ error: errorMessage }) : serialize({ result })
|
|
43
|
+
);
|
|
44
|
+
if (resultBytes.length + 4 > resultBuffer.byteLength) {
|
|
45
|
+
resultBytes = new TextEncoder().encode(
|
|
46
|
+
serialize({
|
|
47
|
+
error: `The synchronous result is ${resultBytes.length} bytes, which is more than the ${resultBuffer.byteLength - 4} bytes that synchronous calls can return on web. Use the async API for large results.`,
|
|
48
|
+
})
|
|
49
|
+
);
|
|
50
|
+
}
|
|
51
|
+
new Uint32Array(resultBuffer, 0, 1)[0] = resultBytes.length;
|
|
52
|
+
new Uint8Array(resultBuffer).set(resultBytes, 4);
|
|
45
53
|
Atomics.store(lock, 0, RESOLVED);
|
|
46
54
|
} else {
|
|
47
|
-
if (
|
|
48
|
-
self.postMessage({ id,
|
|
55
|
+
if (error != null) {
|
|
56
|
+
self.postMessage({ id, error: errorMessage });
|
|
49
57
|
} else {
|
|
50
|
-
self.postMessage({ id,
|
|
58
|
+
self.postMessage({ id, result });
|
|
51
59
|
}
|
|
52
60
|
}
|
|
53
61
|
}
|