@lunarhue/expo-wa-sqlite 0.0.1

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 (224) hide show
  1. package/.claude/settings.local.json +9 -0
  2. package/.lovely-docs.yaml +11 -0
  3. package/LICENSE +21 -0
  4. package/demo/next.config.mjs +17 -0
  5. package/demo/package.json +26 -0
  6. package/demo/scripts/copy-wasm.mjs +14 -0
  7. package/demo/src/app/layout.tsx +16 -0
  8. package/demo/src/app/page.tsx +16 -0
  9. package/demo/src/app/todos.tsx +118 -0
  10. package/demo/src/db/schema.ts +7 -0
  11. package/demo/tsconfig.json +18 -0
  12. package/lovely-docs/drizzle-orm/arktype.md +113 -0
  13. package/lovely-docs/drizzle-orm/batch-api.md +35 -0
  14. package/lovely-docs/drizzle-orm/cache.md +145 -0
  15. package/lovely-docs/drizzle-orm/check-migrations.md +52 -0
  16. package/lovely-docs/drizzle-orm/column_types/mysql-column-types.md +76 -0
  17. package/lovely-docs/drizzle-orm/column_types/postgresql_column_types.md +314 -0
  18. package/lovely-docs/drizzle-orm/column_types/singlestore-column-types.md +171 -0
  19. package/lovely-docs/drizzle-orm/column_types/sqlite_column_types.md +132 -0
  20. package/lovely-docs/drizzle-orm/column_types.md +76 -0
  21. package/lovely-docs/drizzle-orm/common_patterns_&_recipes/case-insensitive-unique-email.md +113 -0
  22. package/lovely-docs/drizzle-orm/common_patterns_&_recipes/conditional-filters-in-query.md +69 -0
  23. package/lovely-docs/drizzle-orm/common_patterns_&_recipes/count-rows.md +76 -0
  24. package/lovely-docs/drizzle-orm/common_patterns_&_recipes/cursor-based-pagination.md +142 -0
  25. package/lovely-docs/drizzle-orm/common_patterns_&_recipes/d1_http_api_configuration.md +49 -0
  26. package/lovely-docs/drizzle-orm/common_patterns_&_recipes/decrementing-a-value.md +36 -0
  27. package/lovely-docs/drizzle-orm/common_patterns_&_recipes/empty-array-default-value.md +43 -0
  28. package/lovely-docs/drizzle-orm/common_patterns_&_recipes/full-text-search-with-generated-columns.md +73 -0
  29. package/lovely-docs/drizzle-orm/common_patterns_&_recipes/gel-auth-extension.md +89 -0
  30. package/lovely-docs/drizzle-orm/common_patterns_&_recipes/include-or-exclude-columns.md +51 -0
  31. package/lovely-docs/drizzle-orm/common_patterns_&_recipes/incrementing-a-value.md +36 -0
  32. package/lovely-docs/drizzle-orm/common_patterns_&_recipes/limit-offset-pagination.md +104 -0
  33. package/lovely-docs/drizzle-orm/common_patterns_&_recipes/mysql-local-setup.md +55 -0
  34. package/lovely-docs/drizzle-orm/common_patterns_&_recipes/point-datatype-psql.md +79 -0
  35. package/lovely-docs/drizzle-orm/common_patterns_&_recipes/postgis-geometry-point.md +115 -0
  36. package/lovely-docs/drizzle-orm/common_patterns_&_recipes/postgresql-full-text-search.md +150 -0
  37. package/lovely-docs/drizzle-orm/common_patterns_&_recipes/postgresql-local-setup.md +55 -0
  38. package/lovely-docs/drizzle-orm/common_patterns_&_recipes/seeding-with-option.md +69 -0
  39. package/lovely-docs/drizzle-orm/common_patterns_&_recipes/seeding-with-partially-exposed-schema.md +60 -0
  40. package/lovely-docs/drizzle-orm/common_patterns_&_recipes/select-parent-rows-with-at-least-one-related-child-row.md +74 -0
  41. package/lovely-docs/drizzle-orm/common_patterns_&_recipes/timestamp-default-value.md +93 -0
  42. package/lovely-docs/drizzle-orm/common_patterns_&_recipes/toggling-a-boolean-field.md +20 -0
  43. package/lovely-docs/drizzle-orm/common_patterns_&_recipes/update-many-with-different-values.md +50 -0
  44. package/lovely-docs/drizzle-orm/common_patterns_&_recipes/upsert.md +169 -0
  45. package/lovely-docs/drizzle-orm/common_patterns_&_recipes/vector-similarity-search.md +79 -0
  46. package/lovely-docs/drizzle-orm/common_patterns_&_recipes.md +787 -0
  47. package/lovely-docs/drizzle-orm/connect-aws-data-api-pg.md +47 -0
  48. package/lovely-docs/drizzle-orm/connect-bun-sql.md +35 -0
  49. package/lovely-docs/drizzle-orm/connect-bun-sqlite.md +42 -0
  50. package/lovely-docs/drizzle-orm/connect-cloudflare-d1.md +61 -0
  51. package/lovely-docs/drizzle-orm/connect-cloudflare-do.md +86 -0
  52. package/lovely-docs/drizzle-orm/connect-neon.md +72 -0
  53. package/lovely-docs/drizzle-orm/connect-nile.md +84 -0
  54. package/lovely-docs/drizzle-orm/connect-pglite.md +39 -0
  55. package/lovely-docs/drizzle-orm/connect-planetscale.md +37 -0
  56. package/lovely-docs/drizzle-orm/connect-prisma-postgres.md +48 -0
  57. package/lovely-docs/drizzle-orm/connect-sqlite-cloud.md +29 -0
  58. package/lovely-docs/drizzle-orm/connect-supabase.md +45 -0
  59. package/lovely-docs/drizzle-orm/connect-tidb-serverless.md +35 -0
  60. package/lovely-docs/drizzle-orm/connect-turso-database.md +28 -0
  61. package/lovely-docs/drizzle-orm/connect-turso.md +60 -0
  62. package/lovely-docs/drizzle-orm/connect-vercel-postgres.md +37 -0
  63. package/lovely-docs/drizzle-orm/connect-xata.md +29 -0
  64. package/lovely-docs/drizzle-orm/custom-migrations.md +40 -0
  65. package/lovely-docs/drizzle-orm/custom-types.md +137 -0
  66. package/lovely-docs/drizzle-orm/database-connection-overview.md +89 -0
  67. package/lovely-docs/drizzle-orm/database_setup_guides/bun-sql-existing.md +59 -0
  68. package/lovely-docs/drizzle-orm/database_setup_guides/bun-sqlite-existing.md +48 -0
  69. package/lovely-docs/drizzle-orm/database_setup_guides/bun-sqlite-new.md +34 -0
  70. package/lovely-docs/drizzle-orm/database_setup_guides/d1-new.md +74 -0
  71. package/lovely-docs/drizzle-orm/database_setup_guides/expo-sqlite-setup.md +169 -0
  72. package/lovely-docs/drizzle-orm/database_setup_guides/gel-existing-project.md +81 -0
  73. package/lovely-docs/drizzle-orm/database_setup_guides/get-started-bun-sql.md +29 -0
  74. package/lovely-docs/drizzle-orm/database_setup_guides/getting_started_with_gel.md +85 -0
  75. package/lovely-docs/drizzle-orm/database_setup_guides/mysql-existing-project.md +32 -0
  76. package/lovely-docs/drizzle-orm/database_setup_guides/mysql-setup.md +43 -0
  77. package/lovely-docs/drizzle-orm/database_setup_guides/neon-existing-project.md +39 -0
  78. package/lovely-docs/drizzle-orm/database_setup_guides/neon-setup.md +45 -0
  79. package/lovely-docs/drizzle-orm/database_setup_guides/nile-existing-project.md +66 -0
  80. package/lovely-docs/drizzle-orm/database_setup_guides/nile-setup.md +59 -0
  81. package/lovely-docs/drizzle-orm/database_setup_guides/op-sqlite_setup_guide.md +135 -0
  82. package/lovely-docs/drizzle-orm/database_setup_guides/pglite-existing-project.md +67 -0
  83. package/lovely-docs/drizzle-orm/database_setup_guides/pglite-setup.md +33 -0
  84. package/lovely-docs/drizzle-orm/database_setup_guides/planetscale-existing-project.md +70 -0
  85. package/lovely-docs/drizzle-orm/database_setup_guides/planetscale-setup.md +46 -0
  86. package/lovely-docs/drizzle-orm/database_setup_guides/postgresql-existing-project.md +57 -0
  87. package/lovely-docs/drizzle-orm/database_setup_guides/postgresql-setup.md +44 -0
  88. package/lovely-docs/drizzle-orm/database_setup_guides/singlestore-existing-project.md +22 -0
  89. package/lovely-docs/drizzle-orm/database_setup_guides/singlestore-setup.md +37 -0
  90. package/lovely-docs/drizzle-orm/database_setup_guides/sqlite-cloud-existing-project.md +52 -0
  91. package/lovely-docs/drizzle-orm/database_setup_guides/sqlite-cloud-setup.md +53 -0
  92. package/lovely-docs/drizzle-orm/database_setup_guides/sqlite-durable-objects-setup.md +163 -0
  93. package/lovely-docs/drizzle-orm/database_setup_guides/sqlite-existing-project.md +36 -0
  94. package/lovely-docs/drizzle-orm/database_setup_guides/sqlite-new.md +28 -0
  95. package/lovely-docs/drizzle-orm/database_setup_guides/supabase-existing-project.md +32 -0
  96. package/lovely-docs/drizzle-orm/database_setup_guides/tidb-existing-project.md +25 -0
  97. package/lovely-docs/drizzle-orm/database_setup_guides/tidb-serverless-setup.md +41 -0
  98. package/lovely-docs/drizzle-orm/database_setup_guides/turso-database-existing.md +61 -0
  99. package/lovely-docs/drizzle-orm/database_setup_guides/turso-database-setup.md +60 -0
  100. package/lovely-docs/drizzle-orm/database_setup_guides/turso-existing.md +74 -0
  101. package/lovely-docs/drizzle-orm/database_setup_guides/turso-new.md +78 -0
  102. package/lovely-docs/drizzle-orm/database_setup_guides/vercel-postgres-existing-project.md +71 -0
  103. package/lovely-docs/drizzle-orm/database_setup_guides/vercel-postgres-setup.md +46 -0
  104. package/lovely-docs/drizzle-orm/database_setup_guides/xata-existing-project.md +32 -0
  105. package/lovely-docs/drizzle-orm/database_setup_guides/xata-new.md +30 -0
  106. package/lovely-docs/drizzle-orm/database_setup_guides.md +144 -0
  107. package/lovely-docs/drizzle-orm/delete.md +57 -0
  108. package/lovely-docs/drizzle-orm/drizzle-config-file.md +252 -0
  109. package/lovely-docs/drizzle-orm/drizzle-kit-up.md +43 -0
  110. package/lovely-docs/drizzle-orm/dynamic-query-building.md +68 -0
  111. package/lovely-docs/drizzle-orm/eslint-plugin.md +76 -0
  112. package/lovely-docs/drizzle-orm/expo-sqlite.md +101 -0
  113. package/lovely-docs/drizzle-orm/export.md +88 -0
  114. package/lovely-docs/drizzle-orm/faq.md +28 -0
  115. package/lovely-docs/drizzle-orm/filter-and-conditional-operators.md +169 -0
  116. package/lovely-docs/drizzle-orm/gel-setup.md +37 -0
  117. package/lovely-docs/drizzle-orm/generate.md +119 -0
  118. package/lovely-docs/drizzle-orm/generated-columns.md +128 -0
  119. package/lovely-docs/drizzle-orm/getting_started/database_integrations/drizzle-with-turso.md +159 -0
  120. package/lovely-docs/drizzle-orm/getting_started/database_integrations/drizzle_with_nile_database.md +195 -0
  121. package/lovely-docs/drizzle-orm/getting_started/database_integrations/neon_postgres_integration.md +157 -0
  122. package/lovely-docs/drizzle-orm/getting_started/database_integrations/supabase_integration.md +150 -0
  123. package/lovely-docs/drizzle-orm/getting_started/database_integrations/vercel-postgres-setup.md +152 -0
  124. package/lovely-docs/drizzle-orm/getting_started/database_integrations/xata_integration.md +143 -0
  125. package/lovely-docs/drizzle-orm/getting_started/database_integrations.md +117 -0
  126. package/lovely-docs/drizzle-orm/getting_started/edge_functions_integration/drizzle_with_vercel_edge_functions.md +220 -0
  127. package/lovely-docs/drizzle-orm/getting_started/edge_functions_integration/netlify_edge_functions_with_neon_postgres.md +120 -0
  128. package/lovely-docs/drizzle-orm/getting_started/edge_functions_integration/netlify_edge_functions_with_supabase.md +94 -0
  129. package/lovely-docs/drizzle-orm/getting_started/edge_functions_integration/supabase_edge_functions_integration.md +116 -0
  130. package/lovely-docs/drizzle-orm/getting_started/edge_functions_integration.md +63 -0
  131. package/lovely-docs/drizzle-orm/getting_started/todo_app_with_neon_postgres.md +323 -0
  132. package/lovely-docs/drizzle-orm/getting_started.md +443 -0
  133. package/lovely-docs/drizzle-orm/graphql.md +107 -0
  134. package/lovely-docs/drizzle-orm/http-proxy-driver.md +138 -0
  135. package/lovely-docs/drizzle-orm/indexes-constraints.md +135 -0
  136. package/lovely-docs/drizzle-orm/insert.mdx.md +118 -0
  137. package/lovely-docs/drizzle-orm/joins.md +145 -0
  138. package/lovely-docs/drizzle-orm/kit-overview.md +81 -0
  139. package/lovely-docs/drizzle-orm/migrate.md +54 -0
  140. package/lovely-docs/drizzle-orm/migration_guides/migrate-from-sequelize.md +335 -0
  141. package/lovely-docs/drizzle-orm/migration_guides/migrate-from-typeorm.md +317 -0
  142. package/lovely-docs/drizzle-orm/migration_guides/migrate_from_prisma_to_drizzle.md +258 -0
  143. package/lovely-docs/drizzle-orm/migration_guides.md +201 -0
  144. package/lovely-docs/drizzle-orm/migrations.md +50 -0
  145. package/lovely-docs/drizzle-orm/mysql-setup.md +51 -0
  146. package/lovely-docs/drizzle-orm/op-sqlite-setup.md +80 -0
  147. package/lovely-docs/drizzle-orm/overview.md +69 -0
  148. package/lovely-docs/drizzle-orm/postgresql-setup.md +71 -0
  149. package/lovely-docs/drizzle-orm/postgresql_extensions.md +93 -0
  150. package/lovely-docs/drizzle-orm/prepared-statements.md +77 -0
  151. package/lovely-docs/drizzle-orm/prisma-extension.md +46 -0
  152. package/lovely-docs/drizzle-orm/pull.md +134 -0
  153. package/lovely-docs/drizzle-orm/push.md +129 -0
  154. package/lovely-docs/drizzle-orm/queries-and-crud.md +72 -0
  155. package/lovely-docs/drizzle-orm/quick-start.md +63 -0
  156. package/lovely-docs/drizzle-orm/react-native-sqlite-setup.md +1 -0
  157. package/lovely-docs/drizzle-orm/read-replicas.md +66 -0
  158. package/lovely-docs/drizzle-orm/relational-queries.md +271 -0
  159. package/lovely-docs/drizzle-orm/relations.md +194 -0
  160. package/lovely-docs/drizzle-orm/release_notes/live-queries.md +27 -0
  161. package/lovely-docs/drizzle-orm/release_notes/pglite_driver_support.md +14 -0
  162. package/lovely-docs/drizzle-orm/release_notes/v0.11.0_release.md +139 -0
  163. package/lovely-docs/drizzle-orm/release_notes/v0.16.2_release_notes.md +86 -0
  164. package/lovely-docs/drizzle-orm/release_notes/v0.23.2_release.md +5 -0
  165. package/lovely-docs/drizzle-orm/release_notes/v0.27.2_-_unique_constraints_support.md +66 -0
  166. package/lovely-docs/drizzle-orm/release_notes/v0.28.0_release_notes.md +80 -0
  167. package/lovely-docs/drizzle-orm/release_notes/v0.28.1_release.md +7 -0
  168. package/lovely-docs/drizzle-orm/release_notes/v0.28.2_release_notes.md +18 -0
  169. package/lovely-docs/drizzle-orm/release_notes/v0.28.3_release_notes.md +48 -0
  170. package/lovely-docs/drizzle-orm/release_notes/v0.28.4_release.md +8 -0
  171. package/lovely-docs/drizzle-orm/release_notes/v0.28.5_release_notes.md +7 -0
  172. package/lovely-docs/drizzle-orm/release_notes/v0.28.6_release_notes.md +54 -0
  173. package/lovely-docs/drizzle-orm/release_notes/v0.29.0_release_notes.md +143 -0
  174. package/lovely-docs/drizzle-orm/release_notes/v0.29.1_release_notes.md +72 -0
  175. package/lovely-docs/drizzle-orm/release_notes/v0.29.2_release_notes.md +95 -0
  176. package/lovely-docs/drizzle-orm/release_notes/v0.29.3_release.md +7 -0
  177. package/lovely-docs/drizzle-orm/release_notes/v0.29.4_release_notes.md +40 -0
  178. package/lovely-docs/drizzle-orm/release_notes/v0.29.5_release_notes.md +69 -0
  179. package/lovely-docs/drizzle-orm/release_notes/v0.30.0_release_notes.md +31 -0
  180. package/lovely-docs/drizzle-orm/release_notes/v0.30.10_release.md +18 -0
  181. package/lovely-docs/drizzle-orm/release_notes/v0.30.1_release_notes.md +16 -0
  182. package/lovely-docs/drizzle-orm/release_notes/v0.30.2_release_notes.md +7 -0
  183. package/lovely-docs/drizzle-orm/release_notes/v0.30.3_release_notes.md +8 -0
  184. package/lovely-docs/drizzle-orm/release_notes/v0.30.5_release_notes.md +20 -0
  185. package/lovely-docs/drizzle-orm/release_notes/v0.30.7_release.md +5 -0
  186. package/lovely-docs/drizzle-orm/release_notes/v0.30.8_release_notes.md +36 -0
  187. package/lovely-docs/drizzle-orm/release_notes/v0.30.9_release.md +29 -0
  188. package/lovely-docs/drizzle-orm/release_notes/v0.31.0_release_notes.md +186 -0
  189. package/lovely-docs/drizzle-orm/release_notes/v0.31.2_tidb_cloud_serverless_support.md +16 -0
  190. package/lovely-docs/drizzle-orm/release_notes/v0.31.3_release.md +19 -0
  191. package/lovely-docs/drizzle-orm/release_notes/v0.31.4_release.md +1 -0
  192. package/lovely-docs/drizzle-orm/release_notes/v0.32.0_release_notes.md +136 -0
  193. package/lovely-docs/drizzle-orm/release_notes/v0.32.1_release_notes.md +15 -0
  194. package/lovely-docs/drizzle-orm/release_notes/v0.32.2_release.md +13 -0
  195. package/lovely-docs/drizzle-orm/release_notes/xata-http-driver-support.md +27 -0
  196. package/lovely-docs/drizzle-orm/release_notes.md +25 -0
  197. package/lovely-docs/drizzle-orm/rls.mdx.md +385 -0
  198. package/lovely-docs/drizzle-orm/schema-declaration.md +239 -0
  199. package/lovely-docs/drizzle-orm/schemas.md +63 -0
  200. package/lovely-docs/drizzle-orm/seed-generators.md +220 -0
  201. package/lovely-docs/drizzle-orm/seed-limitations.md +3 -0
  202. package/lovely-docs/drizzle-orm/seed-overview.md +155 -0
  203. package/lovely-docs/drizzle-orm/seed-versioning.md +85 -0
  204. package/lovely-docs/drizzle-orm/select.md +411 -0
  205. package/lovely-docs/drizzle-orm/sequences.md +62 -0
  206. package/lovely-docs/drizzle-orm/serverless-performance.md +21 -0
  207. package/lovely-docs/drizzle-orm/set-operations.md +127 -0
  208. package/lovely-docs/drizzle-orm/singlestore-setup.md +57 -0
  209. package/lovely-docs/drizzle-orm/sql-template.md +127 -0
  210. package/lovely-docs/drizzle-orm/sqlite-setup.md +65 -0
  211. package/lovely-docs/drizzle-orm/studio.md +47 -0
  212. package/lovely-docs/drizzle-orm/transactions.md +83 -0
  213. package/lovely-docs/drizzle-orm/type-helpers-and-utilities.md +160 -0
  214. package/lovely-docs/drizzle-orm/typebox.md +110 -0
  215. package/lovely-docs/drizzle-orm/update.md +79 -0
  216. package/lovely-docs/drizzle-orm/upgrade-to-0.21.0.md +40 -0
  217. package/lovely-docs/drizzle-orm/valibot.md +115 -0
  218. package/lovely-docs/drizzle-orm/views.md +135 -0
  219. package/lovely-docs/drizzle-orm/why-drizzle.md +66 -0
  220. package/lovely-docs/drizzle-orm/zod.md +113 -0
  221. package/lovely-docs/drizzle-orm.md +60 -0
  222. package/package.json +24 -0
  223. package/src/index.ts +186 -0
  224. package/tsconfig.json +14 -0
@@ -0,0 +1,9 @@
1
+ {
2
+ "permissions": {
3
+ "allow": [
4
+ "Bash(npx tsc:*)",
5
+ "Bash(pnpm add:*)",
6
+ "Bash(node:*)"
7
+ ]
8
+ }
9
+ }
@@ -0,0 +1,11 @@
1
+ source:
2
+ type: git
3
+ repo: https://github.com/xl0/lovely-docs
4
+ branch: master
5
+ gitCacheDir: /Users/wesleybaldwin/Library/Caches/lovely-docs/github.com/xl0/lovely-docs
6
+ installed:
7
+ - drizzle-orm
8
+ installs: digest
9
+ summaries: true
10
+ llms_map: false
11
+ installDir: lovely-docs
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Roy T. Hashimoto, LunarHUE LLC
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,17 @@
1
+ /** @type {import('next').NextConfig} */
2
+ const nextConfig = {
3
+ // Transpile workspace packages that ship TypeScript source
4
+ transpilePackages: ['@lunarhue/expo-wa-sqlite'],
5
+
6
+ webpack(config) {
7
+ // wa-sqlite-async.mjs is an Emscripten module — tell webpack not to
8
+ // parse it so it can fetch the WASM binary at runtime via locateFile.
9
+ config.module.rules.push({
10
+ test: /wa-sqlite-async\.mjs$/,
11
+ type: 'javascript/auto',
12
+ });
13
+ return config;
14
+ },
15
+ };
16
+
17
+ export default nextConfig;
@@ -0,0 +1,26 @@
1
+ {
2
+ "name": "@lunarhue/expo-wa-sqlite-demo",
3
+ "version": "0.0.1",
4
+ "private": true,
5
+ "type": "module",
6
+ "scripts": {
7
+ "dev": "node scripts/copy-wasm.mjs && next dev",
8
+ "build": "node scripts/copy-wasm.mjs && next build",
9
+ "start": "next start"
10
+ },
11
+ "dependencies": {
12
+ "@lunarhue/expo-wa-sqlite": "workspace:*",
13
+ "@lunarhue/wa-sqlite": "workspace:*",
14
+ "@lunarhue/wa-sqlite-wasm": "workspace:*",
15
+ "drizzle-orm": "^0.43.1",
16
+ "next": "^15.2.3",
17
+ "react": "^19.0.0",
18
+ "react-dom": "^19.0.0"
19
+ },
20
+ "devDependencies": {
21
+ "@types/node": "^22.0.0",
22
+ "@types/react": "^19.0.0",
23
+ "@types/react-dom": "^19.0.0",
24
+ "typescript": "^5.3.3"
25
+ }
26
+ }
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env node
2
+ // Copies the wa-sqlite-async WASM binary into /public so Next.js can serve it.
3
+ import { copyFile } from 'node:fs/promises';
4
+ import { createRequire } from 'node:module';
5
+ import { fileURLToPath } from 'node:url';
6
+ import path from 'node:path';
7
+
8
+ const require = createRequire(import.meta.url);
9
+ const wasmPkg = path.dirname(require.resolve('@lunarhue/wa-sqlite-wasm/wa-sqlite-async.mjs'));
10
+ const src = path.join(wasmPkg, 'wa-sqlite-async.wasm');
11
+ const dest = fileURLToPath(new URL('../public/wa-sqlite-async.wasm', import.meta.url));
12
+
13
+ await copyFile(src, dest);
14
+ console.log('Copied wa-sqlite-async.wasm → public/');
@@ -0,0 +1,16 @@
1
+ import type { Metadata } from 'next';
2
+
3
+ export const metadata: Metadata = {
4
+ title: 'wa-sqlite + Drizzle Demo',
5
+ description: 'IDBBatchAtomicVFS + drizzle-orm in the browser',
6
+ };
7
+
8
+ export default function RootLayout({ children }: { children: React.ReactNode }) {
9
+ return (
10
+ <html lang="en">
11
+ <body style={{ fontFamily: 'system-ui, sans-serif', maxWidth: 640, margin: '3rem auto', padding: '0 1rem' }}>
12
+ {children}
13
+ </body>
14
+ </html>
15
+ );
16
+ }
@@ -0,0 +1,16 @@
1
+ import { Suspense } from 'react';
2
+ import Todos from './todos';
3
+
4
+ export default function Page() {
5
+ return (
6
+ <>
7
+ <h1>wa-sqlite + Drizzle</h1>
8
+ <p style={{ color: '#555' }}>
9
+ Persisted in IndexedDB via <code>IDBBatchAtomicVFS</code>. Reload the page — your todos survive.
10
+ </p>
11
+ <Suspense fallback={<p>Initialising database…</p>}>
12
+ <Todos />
13
+ </Suspense>
14
+ </>
15
+ );
16
+ }
@@ -0,0 +1,118 @@
1
+ 'use client';
2
+
3
+ import { eq } from 'drizzle-orm';
4
+ import { useCallback, useEffect, useRef, useState } from 'react';
5
+ import { useWaSQLiteDB } from '@lunarhue/expo-wa-sqlite';
6
+ import { todos } from '@/db/schema';
7
+
8
+ // The Emscripten module factory — imported at module scope so the singleton
9
+ // in useWaSQLiteDB only ever sees one reference to it.
10
+ // We use a dynamic import so Next.js doesn't try to SSR this module.
11
+ const moduleFactoryPromise =
12
+ typeof window !== 'undefined'
13
+ ? import('@lunarhue/wa-sqlite-wasm/wa-sqlite-async.mjs').then((m) => m.default)
14
+ : Promise.resolve(null as any);
15
+
16
+ type Todo = typeof todos.$inferSelect;
17
+
18
+ export default function Todos() {
19
+ const [moduleFactory, setModuleFactory] = useState<((...args: any[]) => Promise<any>) | null>(null);
20
+
21
+ useEffect(() => {
22
+ moduleFactoryPromise.then(setModuleFactory);
23
+ }, []);
24
+
25
+ if (!moduleFactory) return <p>Loading WASM…</p>;
26
+
27
+ return <TodoApp moduleFactory={moduleFactory} />;
28
+ }
29
+
30
+ function TodoApp({ moduleFactory }: { moduleFactory: (...args: any[]) => Promise<any> }) {
31
+ const { db, isReady, error } = useWaSQLiteDB({
32
+ dbName: 'todos-demo',
33
+ moduleFactory,
34
+ // The WASM binary is copied to /public by the dev/build script.
35
+ wasmUrl: '/wa-sqlite-async.wasm',
36
+ });
37
+
38
+ const [items, setItems] = useState<Todo[]>([]);
39
+ const inputRef = useRef<HTMLInputElement>(null);
40
+
41
+ const refresh = useCallback(async () => {
42
+ if (!db) return;
43
+ setItems(await db.select().from(todos).orderBy(todos.id));
44
+ }, [db]);
45
+
46
+ useEffect(() => {
47
+ if (isReady) refresh();
48
+ }, [isReady, refresh]);
49
+
50
+ const addTodo = async (e: React.FormEvent) => {
51
+ e.preventDefault();
52
+ const text = inputRef.current?.value.trim();
53
+ if (!text || !db) return;
54
+ await db.insert(todos).values({ text, done: false });
55
+ inputRef.current!.value = '';
56
+ refresh();
57
+ };
58
+
59
+ const toggleTodo = async (todo: Todo) => {
60
+ if (!db) return;
61
+ await db.update(todos).set({ done: !todo.done }).where(eq(todos.id, todo.id));
62
+ refresh();
63
+ };
64
+
65
+ const deleteTodo = async (id: number) => {
66
+ if (!db) return;
67
+ await db.delete(todos).where(eq(todos.id, id));
68
+ refresh();
69
+ };
70
+
71
+ if (error) {
72
+ return <p style={{ color: 'red' }}>Error: {error.message}</p>;
73
+ }
74
+
75
+ if (!isReady) {
76
+ return <p>Opening database…</p>;
77
+ }
78
+
79
+ return (
80
+ <div>
81
+ <form onSubmit={addTodo} style={{ display: 'flex', gap: 8, marginBottom: 16 }}>
82
+ <input
83
+ ref={inputRef}
84
+ placeholder="What needs doing?"
85
+ style={{ flex: 1, padding: '6px 10px', fontSize: 16 }}
86
+ />
87
+ <button type="submit" style={{ padding: '6px 16px' }}>Add</button>
88
+ </form>
89
+
90
+ {items.length === 0 && <p style={{ color: '#888' }}>No todos yet.</p>}
91
+
92
+ <ul style={{ listStyle: 'none', padding: 0 }}>
93
+ {items.map((todo) => (
94
+ <li
95
+ key={todo.id}
96
+ style={{ display: 'flex', alignItems: 'center', gap: 8, marginBottom: 8 }}
97
+ >
98
+ <input
99
+ type="checkbox"
100
+ checked={todo.done}
101
+ onChange={() => toggleTodo(todo)}
102
+ />
103
+ <span style={{ flex: 1, textDecoration: todo.done ? 'line-through' : 'none', color: todo.done ? '#aaa' : 'inherit' }}>
104
+ {todo.text}
105
+ </span>
106
+ <button onClick={() => deleteTodo(todo.id)} style={{ color: 'red', background: 'none', border: 'none', cursor: 'pointer' }}>
107
+ ✕
108
+ </button>
109
+ </li>
110
+ ))}
111
+ </ul>
112
+
113
+ <p style={{ marginTop: 24, fontSize: 12, color: '#aaa' }}>
114
+ Storage: IndexedDB · VFS: IDBBatchAtomicVFS · ORM: drizzle-orm
115
+ </p>
116
+ </div>
117
+ );
118
+ }
@@ -0,0 +1,7 @@
1
+ import { int, sqliteTable, text } from 'drizzle-orm/sqlite-core';
2
+
3
+ export const todos = sqliteTable('todos', {
4
+ id: int().primaryKey({ autoIncrement: true }),
5
+ text: text().notNull(),
6
+ done: int({ mode: 'boolean' }).notNull().default(false),
7
+ });
@@ -0,0 +1,18 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2022",
4
+ "lib": ["ES2022", "DOM", "DOM.Iterable"],
5
+ "module": "ESNext",
6
+ "moduleResolution": "bundler",
7
+ "jsx": "preserve",
8
+ "strict": true,
9
+ "skipLibCheck": true,
10
+ "incremental": true,
11
+ "plugins": [{ "name": "next" }],
12
+ "paths": {
13
+ "@/*": ["./src/*"]
14
+ }
15
+ },
16
+ "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
17
+ "exclude": ["node_modules"]
18
+ }
@@ -0,0 +1,113 @@
1
+ ## drizzle-arktype Plugin
2
+
3
+ Plugin for Drizzle ORM that generates Arktype schemas from Drizzle ORM schemas. Requires Drizzle ORM v0.36.0+, Arktype v2.0.0+.
4
+
5
+ ### Select Schema
6
+ Validates data queried from the database (API responses).
7
+
8
+ ```ts
9
+ import { pgTable, text, integer } from 'drizzle-orm/pg-core';
10
+ import { createSelectSchema } from 'drizzle-arktype';
11
+
12
+ const users = pgTable('users', {
13
+ id: integer().generatedAlwaysAsIdentity().primaryKey(),
14
+ name: text().notNull(),
15
+ age: integer().notNull()
16
+ });
17
+
18
+ const userSelectSchema = createSelectSchema(users);
19
+ const rows = await db.select().from(users).limit(1);
20
+ const parsed = userSelectSchema(rows[0]); // validates all fields are present
21
+ ```
22
+
23
+ Supports views and enums:
24
+ ```ts
25
+ const roles = pgEnum('roles', ['admin', 'basic']);
26
+ const rolesSchema = createSelectSchema(roles);
27
+
28
+ const usersView = pgView('users_view').as((qb) => qb.select().from(users).where(gt(users.age, 18)));
29
+ const usersViewSchema = createSelectSchema(usersView);
30
+ ```
31
+
32
+ ### Insert Schema
33
+ Validates data to be inserted into the database (API requests).
34
+
35
+ ```ts
36
+ const userInsertSchema = createInsertSchema(users);
37
+ const user = { name: 'Jane', age: 30 };
38
+ const parsed = userInsertSchema(user); // validates required fields
39
+ await db.insert(users).values(parsed);
40
+ ```
41
+
42
+ ### Update Schema
43
+ Validates data to be updated in the database (API requests). Generated columns cannot be updated.
44
+
45
+ ```ts
46
+ const userUpdateSchema = createUpdateSchema(users);
47
+ const user = { age: 35 };
48
+ const parsed = userUpdateSchema(user); // all fields optional, generated columns rejected
49
+ await db.update(users).set(parsed).where(eq(users.name, 'Jane'));
50
+ ```
51
+
52
+ ### Refinements
53
+ Each create schema function accepts optional refinements parameter to extend, modify, or overwrite field schemas:
54
+
55
+ ```ts
56
+ const userSelectSchema = createSelectSchema(users, {
57
+ name: (schema) => pipe(schema, maxLength(20)), // extends schema
58
+ bio: (schema) => pipe(schema, maxLength(1000)), // extends before nullability
59
+ preferences: object({ theme: string() }) // overwrites field including nullability
60
+ });
61
+ ```
62
+
63
+ ### Data Type Reference
64
+
65
+ Boolean: `pg.boolean()`, `mysql.boolean()`, `sqlite.integer({ mode: 'boolean' })` → `type.boolean`
66
+
67
+ Date: `pg.date({ mode: 'date' })`, `pg.timestamp({ mode: 'date' })`, `mysql.date({ mode: 'date' })`, `mysql.datetime({ mode: 'date' })`, `mysql.timestamp({ mode: 'date' })`, `sqlite.integer({ mode: 'timestamp' })`, `sqlite.integer({ mode: 'timestamp_ms' })` → `type.Date`
68
+
69
+ String: `pg.date({ mode: 'string' })`, `pg.timestamp({ mode: 'string' })`, `pg.cidr()`, `pg.inet()`, `pg.interval()`, `pg.macaddr()`, `pg.macaddr8()`, `pg.numeric()`, `pg.text()`, `pg.sparsevec()`, `pg.time()`, `mysql.binary()`, `mysql.date({ mode: 'string' })`, `mysql.datetime({ mode: 'string' })`, `mysql.decimal()`, `mysql.time()`, `mysql.timestamp({ mode: 'string' })`, `mysql.varbinary()`, `sqlite.numeric()`, `sqlite.text({ mode: 'text' })` → `type.string`
70
+
71
+ Bit: `pg.bit({ dimensions: ... })` → `type(/^[01]{${column.dimensions}}$/)`
72
+
73
+ UUID: `pg.uuid()` → `type(/^[\da-f]{8}(?:-[\da-f]{4}){3}-[\da-f]{12}$/iu)`
74
+
75
+ Char: `pg.char({ length: ... })`, `mysql.char({ length: ... })` → `type.string.exactlyLength(length)`
76
+
77
+ Varchar: `pg.varchar({ length: ... })`, `mysql.varchar({ length: ... })`, `sqlite.text({ mode: 'text', length: ... })` → `type.string.atMostLength(length)`
78
+
79
+ MySQL text variants: `mysql.tinytext()` → `type.string.atMostLength(255)`, `mysql.text()` → `type.string.atMostLength(65_535)`, `mysql.mediumtext()` → `type.string.atMostLength(16_777_215)`, `mysql.longtext()` → `type.string.atMostLength(4_294_967_295)`
80
+
81
+ Enum: `pg.text({ enum: ... })`, `pg.char({ enum: ... })`, `pg.varchar({ enum: ... })`, `mysql.tinytext({ enum: ... })`, `mysql.mediumtext({ enum: ... })`, `mysql.text({ enum: ... })`, `mysql.longtext({ enum: ... })`, `mysql.char({ enum: ... })`, `mysql.varchar({ enum: ... })`, `mysql.mysqlEnum(...)`, `sqlite.text({ mode: 'text', enum: ... })` → `type.enumerated(...enum)`
82
+
83
+ Integer types with ranges:
84
+ - `mysql.tinyint()` → `type.keywords.number.integer.atLeast(-128).atMost(127)`
85
+ - `mysql.tinyint({ unsigned: true })` → `type.keywords.number.integer.atLeast(0).atMost(255)`
86
+ - `pg.smallint()`, `pg.smallserial()`, `mysql.smallint()` → `type.keywords.number.integer.atLeast(-32_768).atMost(32_767)`
87
+ - `mysql.smallint({ unsigned: true })` → `type.keywords.number.integer.atLeast(0).atMost(65_535)`
88
+ - `pg.real()`, `mysql.float()` → `type.number.atLeast(-8_388_608).atMost(8_388_607)`
89
+ - `mysql.mediumint()` → `type.keywords.number.integer.atLeast(-8_388_608).atMost(8_388_607)`
90
+ - `mysql.float({ unsigned: true })` → `type.number.atLeast(0).atMost(16_777_215)`
91
+ - `mysql.mediumint({ unsigned: true })` → `type.keywords.number.integer.atLeast(0).atMost(16_777_215)`
92
+ - `pg.integer()`, `pg.serial()`, `mysql.int()` → `type.keywords.number.integer.atLeast(-2_147_483_648).atMost(2_147_483_647)`
93
+ - `mysql.int({ unsigned: true })` → `type.keywords.number.integer.atLeast(0).atMost(4_294_967_295)`
94
+ - `pg.doublePrecision()`, `mysql.double()`, `mysql.real()`, `sqlite.real()` → `type.number.atLeast(-140_737_488_355_328).atMost(140_737_488_355_327)`
95
+ - `mysql.double({ unsigned: true })` → `type.number.atLeast(0).atMost(281_474_976_710_655)`
96
+ - `pg.bigint({ mode: 'number' })`, `pg.bigserial({ mode: 'number' })`, `mysql.bigint({ mode: 'number' })`, `mysql.bigserial({ mode: 'number' })`, `sqlite.integer({ mode: 'number' })` → `type.keywords.number.integer.atLeast(-9_007_199_254_740_991).atMost(9_007_199_254_740_991)`
97
+ - `mysql.serial()` → `type.keywords.number.integer.atLeast(0).atMost(9_007_199_254_740_991)`
98
+ - `pg.bigint({ mode: 'bigint' })`, `pg.bigserial({ mode: 'bigint' })`, `mysql.bigint({ mode: 'bigint' })`, `sqlite.blob({ mode: 'bigint' })` → `type.bigint.narrow(...)` with 64-bit limits
99
+ - `mysql.bigint({ mode: 'bigint', unsigned: true })` → `type.bigint.narrow(...)` with unsigned 64-bit limits
100
+
101
+ Year: `mysql.year()` → `type.keywords.number.integer.atLeast(1_901).atMost(2_155)`
102
+
103
+ Geometry point: `pg.geometry({ type: 'point', mode: 'tuple' })`, `pg.point({ mode: 'tuple' })` → `type([type.number, type.number])` or `pg.geometry({ type: 'point', mode: 'xy' })`, `pg.point({ mode: 'xy' })` → `type({ x: type.number, y: type.number })`
104
+
105
+ Vectors: `pg.halfvec({ dimensions: ... })`, `pg.vector({ dimensions: ... })` → `type.number.array().exactlyLength(dimensions)`
106
+
107
+ Line: `pg.line({ mode: 'abc' })` → `type({ a: type.number, b: type.number, c: type.number })` or `pg.line({ mode: 'tuple' })` → `type([type.number, type.number, type.number])`
108
+
109
+ JSON: `pg.json()`, `pg.jsonb()`, `mysql.json()`, `sqlite.blob({ mode: 'json' })`, `sqlite.text({ mode: 'json' })` → `type('string | number | boolean | null').or(type('unknown.any[] | Record<string, unknown.any>'))`
110
+
111
+ Buffer: `sqlite.blob({ mode: 'buffer' })` → `type.instanceOf(Buffer)`
112
+
113
+ Arrays: `pg.dataType().array(...)` → `baseDataTypeSchema.array().exactlyLength(size)`
@@ -0,0 +1,35 @@
1
+ ## Batch API
2
+
3
+ Execute multiple SQL statements in a single database call with implicit transaction handling.
4
+
5
+ ### Overview
6
+
7
+ Batch APIs are supported for LibSQL, Neon, and D1 drivers. A batch executes one or more SQL statements in order within an implicit transaction. If all statements succeed, the transaction commits. If any statement fails, the entire transaction rolls back.
8
+
9
+ **LibSQL**: Batch is an implicit transaction controlled by the backend.
10
+
11
+ **D1**: Batching reduces network latency by sending multiple statements in one call. Operates in auto-commit mode. Statements execute sequentially and non-concurrently. If any statement fails, the sequence aborts and rolls back.
12
+
13
+ ### Usage
14
+
15
+ ```ts
16
+ const batchResponse: BatchResponse = await db.batch([
17
+ db.insert(usersTable).values({ id: 1, name: 'John' }).returning({ id: usersTable.id }),
18
+ db.update(usersTable).set({ name: 'Dan' }).where(eq(usersTable.id, 1)),
19
+ db.query.usersTable.findMany({}),
20
+ db.select().from(usersTable).where(eq(usersTable.id, 1)),
21
+ db.select({ id: usersTable.id, invitedBy: usersTable.invitedBy }).from(usersTable),
22
+ ]);
23
+ ```
24
+
25
+ The response is a tuple where each element corresponds to the result of each statement in the batch. Return types vary by driver:
26
+ - **libSQL**: `ResultSet` for mutations
27
+ - **Neon**: `NeonHttpQueryResult` for mutations
28
+ - **D1**: `D1Result` for mutations
29
+
30
+ ### Supported Builders
31
+
32
+ All query builders can be used in `db.batch()`:
33
+ - `db.all()`, `db.get()`, `db.values()`, `db.run()`, `db.execute()`
34
+ - `db.query.<table>.findMany()`, `db.query.<table>.findFirst()`
35
+ - `db.select()`, `db.update()`, `db.delete()`, `db.insert()`
@@ -0,0 +1,145 @@
1
+ ## Overview
2
+ Drizzle sends every query to the database by default with no automatic caching. Caching is opt-in using an `explicit` strategy (`global: false`) by default, or can be enabled globally with `global: true`.
3
+
4
+ ## Upstash Integration
5
+
6
+ Quick setup with automatic environment variable configuration:
7
+ ```ts
8
+ import { upstashCache } from "drizzle-orm/cache/upstash";
9
+ const db = drizzle(process.env.DB_URL!, { cache: upstashCache() });
10
+ ```
11
+
12
+ With explicit credentials and options:
13
+ ```ts
14
+ const db = drizzle(process.env.DB_URL!, {
15
+ cache: upstashCache({
16
+ url: '<UPSTASH_URL>',
17
+ token: '<UPSTASH_TOKEN>',
18
+ global: true, // cache all queries by default
19
+ config: { ex: 60 } // 60 second TTL
20
+ })
21
+ });
22
+ ```
23
+
24
+ ## Cache Config
25
+ ```ts
26
+ type CacheConfig = {
27
+ ex?: number; // expiration in seconds
28
+ hexOptions?: "NX" | "nx" | "XX" | "xx" | "GT" | "gt" | "LT" | "lt"; // HEXPIRE options
29
+ };
30
+ ```
31
+
32
+ ## Usage Examples
33
+
34
+ **With `global: false` (default, opt-in):**
35
+ ```ts
36
+ const db = drizzle(process.env.DB_URL!, { cache: upstashCache({ url: "", token: "" }) });
37
+
38
+ // Won't use cache
39
+ const res = await db.select().from(users);
40
+
41
+ // Use cache with .$withCache()
42
+ const res = await db.select().from(users).$withCache();
43
+
44
+ // Options for .$withCache()
45
+ .$withCache({ config: { ex: 60 } }) // custom TTL
46
+ .$withCache({ tag: 'custom_key' }) // custom cache key
47
+ .$withCache({ autoInvalidate: false }) // disable auto-invalidation for eventual consistency
48
+
49
+ // Mutations still trigger cache invalidation
50
+ await db.insert(users).value({ email: "test@example.com" });
51
+ ```
52
+
53
+ **With `global: true`:**
54
+ ```ts
55
+ const db = drizzle(process.env.DB_URL!, { cache: upstashCache({ url: "", token: "", global: true }) });
56
+
57
+ // All queries use cache by default
58
+ const res = await db.select().from(users);
59
+
60
+ // Disable cache for specific query
61
+ const res = await db.select().from(users).$withCache(false);
62
+
63
+ // Manual invalidation
64
+ await db.$cache.invalidate({ tables: users });
65
+ await db.$cache.invalidate({ tables: [users, posts] });
66
+ await db.$cache.invalidate({ tables: "usersTable" });
67
+ await db.$cache.invalidate({ tags: "custom_key" });
68
+ ```
69
+
70
+ ## Custom Cache Implementation
71
+
72
+ Extend the `Cache` class with `strategy()`, `get()`, `put()`, and `onMutate()` methods:
73
+ ```ts
74
+ import Keyv from "keyv";
75
+
76
+ export class TestGlobalCache extends Cache {
77
+ private globalTtl: number = 1000;
78
+ private usedTablesPerKey: Record<string, string[]> = {};
79
+
80
+ constructor(private kv: Keyv = new Keyv()) {
81
+ super();
82
+ }
83
+
84
+ override strategy(): "explicit" | "all" {
85
+ return "all"; // or "explicit"
86
+ }
87
+
88
+ override async get(key: string): Promise<any[] | undefined> {
89
+ return (await this.kv.get(key)) ?? undefined;
90
+ }
91
+
92
+ override async put(
93
+ key: string,
94
+ response: any,
95
+ tables: string[],
96
+ config?: CacheConfig,
97
+ ): Promise<void> {
98
+ const ttl = config?.px ?? (config?.ex ? config.ex * 1000 : this.globalTtl);
99
+ await this.kv.set(key, response, ttl);
100
+ for (const table of tables) {
101
+ const keys = this.usedTablesPerKey[table];
102
+ if (keys === undefined) {
103
+ this.usedTablesPerKey[table] = [key];
104
+ } else {
105
+ keys.push(key);
106
+ }
107
+ }
108
+ }
109
+
110
+ override async onMutate(params: {
111
+ tags: string | string[];
112
+ tables: string | string[] | Table<any> | Table<any>[];
113
+ }): Promise<void> {
114
+ const tagsArray = Array.isArray(params.tags) ? params.tags : params.tags ? [params.tags] : [];
115
+ const tablesArray = Array.isArray(params.tables) ? params.tables : params.tables ? [params.tables] : [];
116
+ const keysToDelete = new Set<string>();
117
+
118
+ for (const table of tablesArray) {
119
+ const tableName = is(table, Table) ? getTableName(table) : (table as string);
120
+ const keys = this.usedTablesPerKey[tableName] ?? [];
121
+ for (const key of keys) keysToDelete.add(key);
122
+ }
123
+
124
+ for (const tag of tagsArray) {
125
+ await this.kv.delete(tag);
126
+ }
127
+ for (const key of keysToDelete) {
128
+ await this.kv.delete(key);
129
+ }
130
+ }
131
+ }
132
+
133
+ const db = drizzle(process.env.DB_URL!, { cache: new TestGlobalCache() });
134
+ ```
135
+
136
+ ## Limitations
137
+
138
+ **Not supported:**
139
+ - Raw queries: `db.execute(sql\`select 1\`)`
140
+ - Batch operations in d1 and libsql
141
+ - Transactions
142
+ - Relational queries: `db.query.users.findMany()`
143
+ - better-sqlite3, Durable Objects, expo sqlite
144
+ - AWS Data API drivers
145
+ - Views
@@ -0,0 +1,52 @@
1
+ ## Purpose
2
+ `drizzle-kit check` validates consistency of generated SQL migrations history. Essential for teams with multiple developers working on different branches altering the database schema.
3
+
4
+ ## Configuration
5
+ Requires `dialect` and database connection credentials via `drizzle.config.ts` or CLI options.
6
+
7
+ **With config file:**
8
+ ```ts
9
+ // drizzle.config.ts
10
+ import { defineConfig } from "drizzle-kit";
11
+ export default defineConfig({
12
+ dialect: "postgresql",
13
+ });
14
+ ```
15
+ ```shell
16
+ npx drizzle-kit check
17
+ ```
18
+
19
+ **As CLI options:**
20
+ ```shell
21
+ npx drizzle-kit check --dialect=postgresql
22
+ ```
23
+
24
+ ## Multiple Configuration Files
25
+ Support for multiple config files in one project for different database stages:
26
+ ```plaintext
27
+ 📦 <project root>
28
+ ├ 📂 drizzle
29
+ ├ 📂 src
30
+ ├ 📜 .env
31
+ ├ 📜 drizzle-dev.config.ts
32
+ ├ 📜 drizzle-prod.config.ts
33
+ ├ 📜 package.json
34
+ └ 📜 tsconfig.json
35
+ ```
36
+ ```shell
37
+ npx drizzle-kit check --config=drizzle-dev.config.ts
38
+ npx drizzle-kit check --config=drizzle-prod.config.ts
39
+ ```
40
+
41
+ ## CLI Options
42
+ | Option | Required | Description |
43
+ |--------|----------|-------------|
44
+ | `dialect` | yes | Database dialect: `postgresql`, `mysql`, or `sqlite` |
45
+ | `out` | no | Migrations folder, default: `./drizzle` |
46
+ | `config` | no | Config file path, default: `drizzle.config.ts` |
47
+
48
+ **Examples:**
49
+ ```shell
50
+ npx drizzle-kit check --dialect=postgresql
51
+ npx drizzle-kit check --dialect=postgresql --out=./migrations-folder
52
+ ```