expo-sqlite 16.0.0 → 16.0.2

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 (53) hide show
  1. package/CHANGELOG.md +9 -0
  2. package/android/build.gradle +2 -2
  3. package/build/Storage.d.ts +16 -0
  4. package/build/Storage.d.ts.map +1 -1
  5. package/build/Storage.js +43 -0
  6. package/build/Storage.js.map +1 -1
  7. package/build/WebStorage.d.ts +22 -0
  8. package/build/WebStorage.d.ts.map +1 -0
  9. package/build/WebStorage.js +84 -0
  10. package/build/WebStorage.js.map +1 -0
  11. package/build/paramUtils.d.ts +6 -0
  12. package/build/paramUtils.d.ts.map +1 -1
  13. package/build/paramUtils.js +20 -0
  14. package/build/paramUtils.js.map +1 -1
  15. package/expo-module.config.json +1 -1
  16. package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/{16.0.0/expo.modules.sqlite-16.0.0.module → 16.0.2/expo.modules.sqlite-16.0.2.module} +7 -7
  17. package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/16.0.2/expo.modules.sqlite-16.0.2.module.md5 +1 -0
  18. package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/16.0.2/expo.modules.sqlite-16.0.2.module.sha1 +1 -0
  19. package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/16.0.2/expo.modules.sqlite-16.0.2.module.sha256 +1 -0
  20. package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/16.0.2/expo.modules.sqlite-16.0.2.module.sha512 +1 -0
  21. package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/{16.0.0/expo.modules.sqlite-16.0.0.pom → 16.0.2/expo.modules.sqlite-16.0.2.pom} +1 -1
  22. package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/16.0.2/expo.modules.sqlite-16.0.2.pom.md5 +1 -0
  23. package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/16.0.2/expo.modules.sqlite-16.0.2.pom.sha1 +1 -0
  24. package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/16.0.2/expo.modules.sqlite-16.0.2.pom.sha256 +1 -0
  25. package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/16.0.2/expo.modules.sqlite-16.0.2.pom.sha512 +1 -0
  26. package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/maven-metadata.xml +4 -4
  27. package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/maven-metadata.xml.md5 +1 -1
  28. package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/maven-metadata.xml.sha1 +1 -1
  29. package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/maven-metadata.xml.sha256 +1 -1
  30. package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/maven-metadata.xml.sha512 +1 -1
  31. package/localStorage/install.js +4 -0
  32. package/package.json +10 -5
  33. package/src/Storage.ts +47 -1
  34. package/src/WebStorage.ts +94 -0
  35. package/src/paramUtils.ts +22 -0
  36. package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/16.0.0/expo.modules.sqlite-16.0.0.module.md5 +0 -1
  37. package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/16.0.0/expo.modules.sqlite-16.0.0.module.sha1 +0 -1
  38. package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/16.0.0/expo.modules.sqlite-16.0.0.module.sha256 +0 -1
  39. package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/16.0.0/expo.modules.sqlite-16.0.0.module.sha512 +0 -1
  40. package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/16.0.0/expo.modules.sqlite-16.0.0.pom.md5 +0 -1
  41. package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/16.0.0/expo.modules.sqlite-16.0.0.pom.sha1 +0 -1
  42. package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/16.0.0/expo.modules.sqlite-16.0.0.pom.sha256 +0 -1
  43. package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/16.0.0/expo.modules.sqlite-16.0.0.pom.sha512 +0 -1
  44. /package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/{16.0.0/expo.modules.sqlite-16.0.0-sources.jar → 16.0.2/expo.modules.sqlite-16.0.2-sources.jar} +0 -0
  45. /package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/{16.0.0/expo.modules.sqlite-16.0.0-sources.jar.md5 → 16.0.2/expo.modules.sqlite-16.0.2-sources.jar.md5} +0 -0
  46. /package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/{16.0.0/expo.modules.sqlite-16.0.0-sources.jar.sha1 → 16.0.2/expo.modules.sqlite-16.0.2-sources.jar.sha1} +0 -0
  47. /package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/{16.0.0/expo.modules.sqlite-16.0.0-sources.jar.sha256 → 16.0.2/expo.modules.sqlite-16.0.2-sources.jar.sha256} +0 -0
  48. /package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/{16.0.0/expo.modules.sqlite-16.0.0-sources.jar.sha512 → 16.0.2/expo.modules.sqlite-16.0.2-sources.jar.sha512} +0 -0
  49. /package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/{16.0.0/expo.modules.sqlite-16.0.0.aar → 16.0.2/expo.modules.sqlite-16.0.2.aar} +0 -0
  50. /package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/{16.0.0/expo.modules.sqlite-16.0.0.aar.md5 → 16.0.2/expo.modules.sqlite-16.0.2.aar.md5} +0 -0
  51. /package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/{16.0.0/expo.modules.sqlite-16.0.0.aar.sha1 → 16.0.2/expo.modules.sqlite-16.0.2.aar.sha1} +0 -0
  52. /package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/{16.0.0/expo.modules.sqlite-16.0.0.aar.sha256 → 16.0.2/expo.modules.sqlite-16.0.2.aar.sha256} +0 -0
  53. /package/local-maven-repo/host/exp/exponent/expo.modules.sqlite/{16.0.0/expo.modules.sqlite-16.0.0.aar.sha512 → 16.0.2/expo.modules.sqlite-16.0.2.aar.sha512} +0 -0
package/CHANGELOG.md CHANGED
@@ -10,12 +10,21 @@
10
10
 
11
11
  ### 💡 Others
12
12
 
13
+ ## 16.0.2 — 2025-08-16
14
+
15
+ _This version does not introduce any user-facing changes._
16
+
17
+ ## 16.0.1 — 2025-08-15
18
+
19
+ _This version does not introduce any user-facing changes._
20
+
13
21
  ## 16.0.0 — 2025-08-13
14
22
 
15
23
  ### 🎉 New features
16
24
 
17
25
  - [iOS] Support Apple TV. ([#38475](https://github.com/expo/expo/pull/38475) by [@douglowder](https://github.com/douglowder))
18
26
  - Added `loadExtensionAsync` / `loadExtensionSync` APIs and pre-bundled [sqlite-vec](https://github.com/asg017/sqlite-vec) extension. ([#38693](https://github.com/expo/expo/pull/38693) by [@kudo](https://github.com/kudo))
27
+ - Added `expo-sqlite/localStorage/install` for [`localStorage`](https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage) drop-in replacement API. ([#38699](https://github.com/expo/expo/pull/38699) by [@kudo](https://github.com/kudo))
19
28
 
20
29
  ### 🐛 Bug fixes
21
30
 
@@ -46,13 +46,13 @@ def reactNativeArchitectures() {
46
46
  }
47
47
 
48
48
  group = 'host.exp.exponent'
49
- version = '16.0.0'
49
+ version = '16.0.2'
50
50
 
51
51
  android {
52
52
  namespace "expo.modules.sqlite"
53
53
  defaultConfig {
54
54
  versionCode 18
55
- versionName "16.0.0"
55
+ versionName "16.0.2"
56
56
  buildConfigField "boolean", "USE_LIBSQL", project.ext.USE_LIBSQL.toString()
57
57
  buildConfigField "boolean", "WITH_SQLITE_VEC", project.ext.WITH_SQLITE_VEC.toString()
58
58
 
@@ -37,6 +37,14 @@ export declare class SQLiteStorage {
37
37
  * Closes the database connection asynchronously.
38
38
  */
39
39
  closeAsync(): Promise<void>;
40
+ /**
41
+ * Retrieves the number of key-value pairs stored in the storage asynchronously.
42
+ */
43
+ getLengthAsync(): Promise<number>;
44
+ /**
45
+ * Retrieves the key at the given index asynchronously.
46
+ */
47
+ getKeyByIndexAsync(index: number): Promise<string | null>;
40
48
  /**
41
49
  * Retrieves the value associated with the given key synchronously.
42
50
  */
@@ -62,6 +70,14 @@ export declare class SQLiteStorage {
62
70
  * Closes the database connection synchronously.
63
71
  */
64
72
  closeSync(): void;
73
+ /**
74
+ * Retrieves the number of key-value pairs stored in the storage synchronously.
75
+ */
76
+ getLengthSync(): number;
77
+ /**
78
+ * Retrieves the key at the given index synchronously.
79
+ */
80
+ getKeyByIndexSync(index: number): string | null;
65
81
  /**
66
82
  * Alias for [`getItemAsync()`](#getitemasynckey) method.
67
83
  */
@@ -1 +1 @@
1
- {"version":3,"file":"Storage.d.ts","sourceRoot":"","sources":["../src/Storage.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"Storage.d.ts","sourceRoot":"","sources":["../src/Storage.ts"],"names":[],"mappings":"AAKA;;;;GAIG;AACH,MAAM,MAAM,kCAAkC,GAAG,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,KAAK,MAAM,CAAC;AAetF;;GAEG;AACH,qBAAa,aAAa;IAIZ,OAAO,CAAC,QAAQ,CAAC,YAAY;IAHzC,OAAO,CAAC,EAAE,CAA+B;IACzC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAmB;gBAEhB,YAAY,EAAE,MAAM;IAIjD;;OAEG;IACG,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAOvD;;;OAGG;IACG,YAAY,CAChB,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,MAAM,GAAG,kCAAkC,GACjD,OAAO,CAAC,IAAI,CAAC;IAkBhB;;OAEG;IACG,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAOpD;;OAEG;IACG,eAAe,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;IAM1C;;OAEG;IACG,UAAU,IAAI,OAAO,CAAC,OAAO,CAAC;IAMpC;;OAEG;IACG,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAYjC;;OAEG;IACG,cAAc,IAAI,OAAO,CAAC,MAAM,CAAC;IAMvC;;OAEG;IACG,kBAAkB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAc/D;;OAEG;IACH,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAOvC;;;OAGG;IACH,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,kCAAkC,GAAG,IAAI;IAkBlF;;OAEG;IACH,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IAOpC;;OAEG;IACH,cAAc,IAAI,MAAM,EAAE;IAM1B;;OAEG;IACH,SAAS,IAAI,OAAO;IAMpB;;OAEG;IACH,SAAS,IAAI,IAAI;IAOjB;;OAEG;IACH,aAAa,IAAI,MAAM;IAMvB;;OAEG;IACH,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAc/C;;OAEG;IACG,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAIlD;;OAEG;IACG,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,kCAAkC,GAAG,OAAO,CAAC,IAAI,CAAC;IAI7F;;OAEG;IACG,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAI5C;;OAEG;IACG,UAAU,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;IAIrC;;OAEG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAI5B;;;OAGG;IACG,SAAS,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAa1D;;OAEG;IACG,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC,EAAE,CAAC;IASlE;;OAEG;IACG,QAAQ,CAAC,aAAa,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAUhE;;OAEG;IACG,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAUhD;;;OAGG;IACG,UAAU,CAAC,aAAa,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAkBlE;;OAEG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;YAQd,UAAU;IAcxB,OAAO,CAAC,SAAS;IASjB,OAAO,CAAC,mBAAmB;IAe3B,OAAO,CAAC,kBAAkB;IAe1B;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,SAAS;IA2BxB,OAAO,CAAC,eAAe;CAgBxB;AAED;;GAEG;AACH,eAAO,MAAM,YAAY,eAAyC,CAAC;AAEnE,eAAe,YAAY,CAAC;AAE5B;;GAEG;AACH,eAAO,MAAM,OAAO,eAAe,CAAC"}
package/build/Storage.js CHANGED
@@ -1,11 +1,14 @@
1
1
  import AwaitLock from 'await-lock';
2
2
  import { openDatabaseAsync, openDatabaseSync } from './index';
3
+ import { normalizeStorageIndex } from './paramUtils';
3
4
  const DATABASE_VERSION = 1;
4
5
  const STATEMENT_GET = 'SELECT value FROM storage WHERE key = ?;';
5
6
  const STATEMENT_SET = 'INSERT INTO storage (key, value) VALUES (?, ?) ON CONFLICT(key) DO UPDATE SET value = excluded.value;';
6
7
  const STATEMENT_REMOVE = 'DELETE FROM storage WHERE key = ?;';
7
8
  const STATEMENT_GET_ALL_KEYS = 'SELECT key FROM storage;';
8
9
  const STATEMENT_CLEAR = 'DELETE FROM storage;';
10
+ const STATEMENT_LENGTH = 'SELECT COUNT(*) as count FROM storage;';
11
+ const STATEMENT_GET_KEY_BY_INDEX = 'SELECT key FROM storage LIMIT 1 OFFSET ?;';
9
12
  const MIGRATION_STATEMENT_0 = 'CREATE TABLE IF NOT EXISTS storage (key TEXT PRIMARY KEY NOT NULL, value TEXT);';
10
13
  /**
11
14
  * Key-value store backed by SQLite. This class accepts a `databaseName` parameter in its constructor, which is the name of the database file to use for the storage.
@@ -86,6 +89,26 @@ export class SQLiteStorage {
86
89
  this.awaitLock.release();
87
90
  }
88
91
  }
92
+ /**
93
+ * Retrieves the number of key-value pairs stored in the storage asynchronously.
94
+ */
95
+ async getLengthAsync() {
96
+ const db = await this.getDbAsync();
97
+ const result = await db.getFirstAsync(STATEMENT_LENGTH);
98
+ return result?.count ?? 0;
99
+ }
100
+ /**
101
+ * Retrieves the key at the given index asynchronously.
102
+ */
103
+ async getKeyByIndexAsync(index) {
104
+ const db = await this.getDbAsync();
105
+ const offset = normalizeStorageIndex(index);
106
+ if (offset == null) {
107
+ return null;
108
+ }
109
+ const result = await db.getFirstAsync(STATEMENT_GET_KEY_BY_INDEX, offset);
110
+ return result?.key ?? null;
111
+ }
89
112
  //#endregion
90
113
  //#region Synchronous API
91
114
  /**
@@ -150,6 +173,26 @@ export class SQLiteStorage {
150
173
  this.db = null;
151
174
  }
152
175
  }
176
+ /**
177
+ * Retrieves the number of key-value pairs stored in the storage synchronously.
178
+ */
179
+ getLengthSync() {
180
+ const db = this.getDbSync();
181
+ const result = db.getFirstSync(STATEMENT_LENGTH);
182
+ return result.count ?? 0;
183
+ }
184
+ /**
185
+ * Retrieves the key at the given index synchronously.
186
+ */
187
+ getKeyByIndexSync(index) {
188
+ const db = this.getDbSync();
189
+ const offset = normalizeStorageIndex(index);
190
+ if (offset == null) {
191
+ return null;
192
+ }
193
+ const result = db.getFirstSync(STATEMENT_GET_KEY_BY_INDEX, offset);
194
+ return result?.key ?? null;
195
+ }
153
196
  //#endregion
154
197
  //#region react-native-async-storage compatible API
155
198
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"Storage.js","sourceRoot":"","sources":["../src/Storage.ts"],"names":[],"mappings":"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","sourcesContent":["import AwaitLock from 'await-lock';\n\nimport { openDatabaseAsync, openDatabaseSync, type SQLiteDatabase } from './index';\n\n/**\n * Update function for the [`setItemAsync()`](#setitemasynckey-value) or [`setItemSync()`](#setitemsynckey-value) method. It computes the new value based on the previous value. The function returns the new value to set for the key.\n * @param prevValue The previous value associated with the key, or `null` if the key was not set.\n * @returns The new value to set for the key.\n */\nexport type SQLiteStorageSetItemUpdateFunction = (prevValue: string | null) => string;\n\nconst DATABASE_VERSION = 1;\nconst STATEMENT_GET = 'SELECT value FROM storage WHERE key = ?;';\nconst STATEMENT_SET =\n 'INSERT INTO storage (key, value) VALUES (?, ?) ON CONFLICT(key) DO UPDATE SET value = excluded.value;';\nconst STATEMENT_REMOVE = 'DELETE FROM storage WHERE key = ?;';\nconst STATEMENT_GET_ALL_KEYS = 'SELECT key FROM storage;';\nconst STATEMENT_CLEAR = 'DELETE FROM storage;';\n\nconst MIGRATION_STATEMENT_0 =\n 'CREATE TABLE IF NOT EXISTS storage (key TEXT PRIMARY KEY NOT NULL, value TEXT);';\n\n/**\n * Key-value store backed by SQLite. This class accepts a `databaseName` parameter in its constructor, which is the name of the database file to use for the storage.\n */\nexport class SQLiteStorage {\n private db: SQLiteDatabase | null = null;\n private readonly awaitLock = new AwaitLock();\n\n constructor(private readonly databaseName: string) {}\n\n //#region Asynchronous API\n\n /**\n * Retrieves the value associated with the given key asynchronously.\n */\n async getItemAsync(key: string): Promise<string | null> {\n this.checkValidInput(key);\n const db = await this.getDbAsync();\n const result = await db.getFirstAsync<{ value: string }>(STATEMENT_GET, key);\n return result?.value ?? null;\n }\n\n /**\n * Sets the value for the given key asynchronously.\n * If a function is provided, it computes the new value based on the previous value.\n */\n async setItemAsync(\n key: string,\n value: string | SQLiteStorageSetItemUpdateFunction\n ): Promise<void> {\n this.checkValidInput(key, value);\n const db = await this.getDbAsync();\n\n if (typeof value === 'function') {\n await db.withExclusiveTransactionAsync(async (tx) => {\n const prevResult = await tx.getFirstAsync<{ value: string }>(STATEMENT_GET, key);\n const prevValue = prevResult?.value ?? null;\n const nextValue = value(prevValue);\n this.checkValidInput(key, nextValue);\n await tx.runAsync(STATEMENT_SET, key, nextValue);\n });\n return;\n }\n\n await db.runAsync(STATEMENT_SET, key, value);\n }\n\n /**\n * Removes the value associated with the given key asynchronously.\n */\n async removeItemAsync(key: string): Promise<boolean> {\n this.checkValidInput(key);\n const db = await this.getDbAsync();\n const result = await db.runAsync(STATEMENT_REMOVE, key);\n return result.changes > 0;\n }\n\n /**\n * Retrieves all keys stored in the storage asynchronously.\n */\n async getAllKeysAsync(): Promise<string[]> {\n const db = await this.getDbAsync();\n const result = await db.getAllAsync<{ key: string }>(STATEMENT_GET_ALL_KEYS);\n return result.map(({ key }) => key);\n }\n\n /**\n * Clears all key-value pairs from the storage asynchronously.\n */\n async clearAsync(): Promise<boolean> {\n const db = await this.getDbAsync();\n const result = await db.runAsync(STATEMENT_CLEAR);\n return result.changes > 0;\n }\n\n /**\n * Closes the database connection asynchronously.\n */\n async closeAsync(): Promise<void> {\n await this.awaitLock.acquireAsync();\n try {\n if (this.db) {\n await this.db.closeAsync();\n this.db = null;\n }\n } finally {\n this.awaitLock.release();\n }\n }\n\n //#endregion\n\n //#region Synchronous API\n\n /**\n * Retrieves the value associated with the given key synchronously.\n */\n getItemSync(key: string): string | null {\n this.checkValidInput(key);\n const db = this.getDbSync();\n const result = db.getFirstSync<{ value: string }>(STATEMENT_GET, key);\n return result?.value ?? null;\n }\n\n /**\n * Sets the value for the given key synchronously.\n * If a function is provided, it computes the new value based on the previous value.\n */\n setItemSync(key: string, value: string | SQLiteStorageSetItemUpdateFunction): void {\n this.checkValidInput(key, value);\n const db = this.getDbSync();\n\n if (typeof value === 'function') {\n db.withTransactionSync(() => {\n const prevResult = db.getFirstSync<{ value: string }>(STATEMENT_GET, key);\n const prevValue = prevResult?.value ?? null;\n const nextValue = value(prevValue);\n this.checkValidInput(key, nextValue);\n db.runSync(STATEMENT_SET, key, nextValue);\n });\n return;\n }\n\n db.runSync(STATEMENT_SET, key, value);\n }\n\n /**\n * Removes the value associated with the given key synchronously.\n */\n removeItemSync(key: string): boolean {\n this.checkValidInput(key);\n const db = this.getDbSync();\n const result = db.runSync(STATEMENT_REMOVE, key);\n return result.changes > 0;\n }\n\n /**\n * Retrieves all keys stored in the storage synchronously.\n */\n getAllKeysSync(): string[] {\n const db = this.getDbSync();\n const result = db.getAllSync<{ key: string }>(STATEMENT_GET_ALL_KEYS);\n return result.map(({ key }) => key);\n }\n\n /**\n * Clears all key-value pairs from the storage synchronously.\n */\n clearSync(): boolean {\n const db = this.getDbSync();\n const result = db.runSync(STATEMENT_CLEAR);\n return result.changes > 0;\n }\n\n /**\n * Closes the database connection synchronously.\n */\n closeSync(): void {\n if (this.db) {\n this.db.closeSync();\n this.db = null;\n }\n }\n\n //#endregion\n\n //#region react-native-async-storage compatible API\n\n /**\n * Alias for [`getItemAsync()`](#getitemasynckey) method.\n */\n async getItem(key: string): Promise<string | null> {\n return this.getItemAsync(key);\n }\n\n /**\n * Alias for [`setItemAsync()`](#setitemasynckey-value).\n */\n async setItem(key: string, value: string | SQLiteStorageSetItemUpdateFunction): Promise<void> {\n await this.setItemAsync(key, value);\n }\n\n /**\n * Alias for [`removeItemAsync()`](#removeitemasynckey) method.\n */\n async removeItem(key: string): Promise<void> {\n await this.removeItemAsync(key);\n }\n\n /**\n * Alias for [`getAllKeysAsync()`](#getallkeysasync) method.\n */\n async getAllKeys(): Promise<string[]> {\n return this.getAllKeysAsync();\n }\n\n /**\n * Alias for [`clearAsync()`](#clearasync) method.\n */\n async clear(): Promise<void> {\n await this.clearAsync();\n }\n\n /**\n * Merges the given value with the existing value for the given key asynchronously.\n * If the existing value is a JSON object, performs a deep merge.\n */\n async mergeItem(key: string, value: string): Promise<void> {\n this.checkValidInput(key, value);\n await this.setItemAsync(key, (prevValue) => {\n if (prevValue == null) {\n return value;\n }\n const prevJSON = JSON.parse(prevValue);\n const newJSON = JSON.parse(value);\n const mergedJSON = SQLiteStorage.mergeDeep(prevJSON, newJSON);\n return JSON.stringify(mergedJSON);\n });\n }\n\n /**\n * Retrieves the values associated with the given keys asynchronously.\n */\n async multiGet(keys: string[]): Promise<[string, string | null][]> {\n return Promise.all(\n keys.map(async (key): Promise<[string, string | null]> => {\n this.checkValidInput(key);\n return [key, await this.getItemAsync(key)];\n })\n );\n }\n\n /**\n * Sets multiple key-value pairs asynchronously.\n */\n async multiSet(keyValuePairs: [string, string][]): Promise<void> {\n const db = await this.getDbAsync();\n await db.withExclusiveTransactionAsync(async (tx) => {\n for (const [key, value] of keyValuePairs) {\n this.checkValidInput(key, value);\n await tx.runAsync(STATEMENT_SET, key, value);\n }\n });\n }\n\n /**\n * Removes the values associated with the given keys asynchronously.\n */\n async multiRemove(keys: string[]): Promise<void> {\n const db = await this.getDbAsync();\n await db.withExclusiveTransactionAsync(async (tx) => {\n for (const key of keys) {\n this.checkValidInput(key);\n await tx.runAsync(STATEMENT_REMOVE, key);\n }\n });\n }\n\n /**\n * Merges multiple key-value pairs asynchronously.\n * If existing values are JSON objects, performs a deep merge.\n */\n async multiMerge(keyValuePairs: [string, string][]): Promise<void> {\n const db = await this.getDbAsync();\n await db.withExclusiveTransactionAsync(async (tx) => {\n for (const [key, value] of keyValuePairs) {\n this.checkValidInput(key, value);\n const prevValue = await tx.getFirstAsync<{ value: string }>(STATEMENT_GET, key);\n if (prevValue == null) {\n await tx.runAsync(STATEMENT_SET, key, value);\n continue;\n }\n const prevJSON = JSON.parse(prevValue.value);\n const newJSON = JSON.parse(value);\n const mergedJSON = SQLiteStorage.mergeDeep(prevJSON, newJSON);\n await tx.runAsync(STATEMENT_SET, key, JSON.stringify(mergedJSON));\n }\n });\n }\n\n /**\n * Alias for [`closeAsync()`](#closeasync-1) method.\n */\n async close(): Promise<void> {\n await this.closeAsync();\n }\n\n //#endregion\n\n //#region Internals\n\n private async getDbAsync(): Promise<SQLiteDatabase> {\n await this.awaitLock.acquireAsync();\n try {\n if (!this.db) {\n const db = await openDatabaseAsync(this.databaseName);\n await this.maybeMigrateDbAsync(db);\n this.db = db;\n }\n } finally {\n this.awaitLock.release();\n }\n return this.db;\n }\n\n private getDbSync(): SQLiteDatabase {\n if (!this.db) {\n const db = openDatabaseSync(this.databaseName);\n this.maybeMigrateDbSync(db);\n this.db = db;\n }\n return this.db;\n }\n\n private maybeMigrateDbAsync(db: SQLiteDatabase) {\n return db.withTransactionAsync(async () => {\n const result = await db.getFirstAsync<{ user_version: number }>('PRAGMA user_version');\n let currentDbVersion = result?.user_version ?? 0;\n if (currentDbVersion >= DATABASE_VERSION) {\n return;\n }\n if (currentDbVersion === 0) {\n await db.execAsync(MIGRATION_STATEMENT_0);\n currentDbVersion = 1;\n }\n await db.execAsync(`PRAGMA user_version = ${DATABASE_VERSION}`);\n });\n }\n\n private maybeMigrateDbSync(db: SQLiteDatabase) {\n db.withTransactionSync(() => {\n const result = db.getFirstSync<{ user_version: number }>('PRAGMA user_version');\n let currentDbVersion = result?.user_version ?? 0;\n if (currentDbVersion >= DATABASE_VERSION) {\n return;\n }\n if (currentDbVersion === 0) {\n db.execSync(MIGRATION_STATEMENT_0);\n currentDbVersion = 1;\n }\n db.execSync(`PRAGMA user_version = ${DATABASE_VERSION}`);\n });\n }\n\n /**\n * Recursively merge two JSON objects.\n */\n private static mergeDeep(target: any, source: any): any {\n if (typeof target !== 'object' || target === null) {\n return source;\n }\n\n if (typeof source !== 'object' || source === null) {\n return target;\n }\n\n const output = { ...target };\n\n for (const key of Object.keys(source)) {\n if (source[key] instanceof Array) {\n if (!output[key]) {\n output[key] = [];\n }\n output[key] = output[key].concat(source[key]);\n } else if (typeof source[key] === 'object') {\n output[key] = this.mergeDeep(target[key], source[key]);\n } else {\n output[key] = source[key];\n }\n }\n\n return output;\n }\n\n private checkValidInput(...input: unknown[]) {\n const [key, value] = input;\n\n if (typeof key !== 'string') {\n throw new Error(\n `[SQLiteStorage] Using ${typeof key} type for key is not supported. Use string instead. Key passed: ${key}`\n );\n }\n\n if (input.length > 1 && typeof value !== 'string' && typeof value !== 'function') {\n throw new Error(\n `[SQLiteStorage] Using ${typeof value} type for value is not supported. Use string instead. Key passed: ${key}. Value passed : ${value}`\n );\n }\n }\n\n //#endregion\n}\n\n/**\n * This default instance of the [`SQLiteStorage`](#sqlitestorage-1) class is used as a drop-in replacement for the `AsyncStorage` module from [`@react-native-async-storage/async-storage`](https://github.com/react-native-async-storage/async-storage).\n */\nexport const AsyncStorage = new SQLiteStorage('ExpoSQLiteStorage');\n\nexport default AsyncStorage;\n\n/**\n * Alias for [`AsyncStorage`](#sqliteasyncstorage), given the storage not only offers asynchronous methods.\n */\nexport const Storage = AsyncStorage;\n"]}
1
+ {"version":3,"file":"Storage.js","sourceRoot":"","sources":["../src/Storage.ts"],"names":[],"mappings":"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","sourcesContent":["import AwaitLock from 'await-lock';\n\nimport { openDatabaseAsync, openDatabaseSync, type SQLiteDatabase } from './index';\nimport { normalizeStorageIndex } from './paramUtils';\n\n/**\n * Update function for the [`setItemAsync()`](#setitemasynckey-value) or [`setItemSync()`](#setitemsynckey-value) method. It computes the new value based on the previous value. The function returns the new value to set for the key.\n * @param prevValue The previous value associated with the key, or `null` if the key was not set.\n * @returns The new value to set for the key.\n */\nexport type SQLiteStorageSetItemUpdateFunction = (prevValue: string | null) => string;\n\nconst DATABASE_VERSION = 1;\nconst STATEMENT_GET = 'SELECT value FROM storage WHERE key = ?;';\nconst STATEMENT_SET =\n 'INSERT INTO storage (key, value) VALUES (?, ?) ON CONFLICT(key) DO UPDATE SET value = excluded.value;';\nconst STATEMENT_REMOVE = 'DELETE FROM storage WHERE key = ?;';\nconst STATEMENT_GET_ALL_KEYS = 'SELECT key FROM storage;';\nconst STATEMENT_CLEAR = 'DELETE FROM storage;';\nconst STATEMENT_LENGTH = 'SELECT COUNT(*) as count FROM storage;';\nconst STATEMENT_GET_KEY_BY_INDEX = 'SELECT key FROM storage LIMIT 1 OFFSET ?;';\n\nconst MIGRATION_STATEMENT_0 =\n 'CREATE TABLE IF NOT EXISTS storage (key TEXT PRIMARY KEY NOT NULL, value TEXT);';\n\n/**\n * Key-value store backed by SQLite. This class accepts a `databaseName` parameter in its constructor, which is the name of the database file to use for the storage.\n */\nexport class SQLiteStorage {\n private db: SQLiteDatabase | null = null;\n private readonly awaitLock = new AwaitLock();\n\n constructor(private readonly databaseName: string) {}\n\n //#region Asynchronous API\n\n /**\n * Retrieves the value associated with the given key asynchronously.\n */\n async getItemAsync(key: string): Promise<string | null> {\n this.checkValidInput(key);\n const db = await this.getDbAsync();\n const result = await db.getFirstAsync<{ value: string }>(STATEMENT_GET, key);\n return result?.value ?? null;\n }\n\n /**\n * Sets the value for the given key asynchronously.\n * If a function is provided, it computes the new value based on the previous value.\n */\n async setItemAsync(\n key: string,\n value: string | SQLiteStorageSetItemUpdateFunction\n ): Promise<void> {\n this.checkValidInput(key, value);\n const db = await this.getDbAsync();\n\n if (typeof value === 'function') {\n await db.withExclusiveTransactionAsync(async (tx) => {\n const prevResult = await tx.getFirstAsync<{ value: string }>(STATEMENT_GET, key);\n const prevValue = prevResult?.value ?? null;\n const nextValue = value(prevValue);\n this.checkValidInput(key, nextValue);\n await tx.runAsync(STATEMENT_SET, key, nextValue);\n });\n return;\n }\n\n await db.runAsync(STATEMENT_SET, key, value);\n }\n\n /**\n * Removes the value associated with the given key asynchronously.\n */\n async removeItemAsync(key: string): Promise<boolean> {\n this.checkValidInput(key);\n const db = await this.getDbAsync();\n const result = await db.runAsync(STATEMENT_REMOVE, key);\n return result.changes > 0;\n }\n\n /**\n * Retrieves all keys stored in the storage asynchronously.\n */\n async getAllKeysAsync(): Promise<string[]> {\n const db = await this.getDbAsync();\n const result = await db.getAllAsync<{ key: string }>(STATEMENT_GET_ALL_KEYS);\n return result.map(({ key }) => key);\n }\n\n /**\n * Clears all key-value pairs from the storage asynchronously.\n */\n async clearAsync(): Promise<boolean> {\n const db = await this.getDbAsync();\n const result = await db.runAsync(STATEMENT_CLEAR);\n return result.changes > 0;\n }\n\n /**\n * Closes the database connection asynchronously.\n */\n async closeAsync(): Promise<void> {\n await this.awaitLock.acquireAsync();\n try {\n if (this.db) {\n await this.db.closeAsync();\n this.db = null;\n }\n } finally {\n this.awaitLock.release();\n }\n }\n\n /**\n * Retrieves the number of key-value pairs stored in the storage asynchronously.\n */\n async getLengthAsync(): Promise<number> {\n const db = await this.getDbAsync();\n const result = await db.getFirstAsync<{ count: number }>(STATEMENT_LENGTH);\n return result?.count ?? 0;\n }\n\n /**\n * Retrieves the key at the given index asynchronously.\n */\n async getKeyByIndexAsync(index: number): Promise<string | null> {\n const db = await this.getDbAsync();\n const offset = normalizeStorageIndex(index);\n if (offset == null) {\n return null;\n }\n const result = await db.getFirstAsync<{ key: string }>(STATEMENT_GET_KEY_BY_INDEX, offset);\n return result?.key ?? null;\n }\n\n //#endregion\n\n //#region Synchronous API\n\n /**\n * Retrieves the value associated with the given key synchronously.\n */\n getItemSync(key: string): string | null {\n this.checkValidInput(key);\n const db = this.getDbSync();\n const result = db.getFirstSync<{ value: string }>(STATEMENT_GET, key);\n return result?.value ?? null;\n }\n\n /**\n * Sets the value for the given key synchronously.\n * If a function is provided, it computes the new value based on the previous value.\n */\n setItemSync(key: string, value: string | SQLiteStorageSetItemUpdateFunction): void {\n this.checkValidInput(key, value);\n const db = this.getDbSync();\n\n if (typeof value === 'function') {\n db.withTransactionSync(() => {\n const prevResult = db.getFirstSync<{ value: string }>(STATEMENT_GET, key);\n const prevValue = prevResult?.value ?? null;\n const nextValue = value(prevValue);\n this.checkValidInput(key, nextValue);\n db.runSync(STATEMENT_SET, key, nextValue);\n });\n return;\n }\n\n db.runSync(STATEMENT_SET, key, value);\n }\n\n /**\n * Removes the value associated with the given key synchronously.\n */\n removeItemSync(key: string): boolean {\n this.checkValidInput(key);\n const db = this.getDbSync();\n const result = db.runSync(STATEMENT_REMOVE, key);\n return result.changes > 0;\n }\n\n /**\n * Retrieves all keys stored in the storage synchronously.\n */\n getAllKeysSync(): string[] {\n const db = this.getDbSync();\n const result = db.getAllSync<{ key: string }>(STATEMENT_GET_ALL_KEYS);\n return result.map(({ key }) => key);\n }\n\n /**\n * Clears all key-value pairs from the storage synchronously.\n */\n clearSync(): boolean {\n const db = this.getDbSync();\n const result = db.runSync(STATEMENT_CLEAR);\n return result.changes > 0;\n }\n\n /**\n * Closes the database connection synchronously.\n */\n closeSync(): void {\n if (this.db) {\n this.db.closeSync();\n this.db = null;\n }\n }\n\n /**\n * Retrieves the number of key-value pairs stored in the storage synchronously.\n */\n getLengthSync(): number {\n const db = this.getDbSync();\n const result = db.getFirstSync<{ count: number }>(STATEMENT_LENGTH);\n return result!.count ?? 0;\n }\n\n /**\n * Retrieves the key at the given index synchronously.\n */\n getKeyByIndexSync(index: number): string | null {\n const db = this.getDbSync();\n const offset = normalizeStorageIndex(index);\n if (offset == null) {\n return null;\n }\n const result = db.getFirstSync<{ key: string }>(STATEMENT_GET_KEY_BY_INDEX, offset);\n return result?.key ?? null;\n }\n\n //#endregion\n\n //#region react-native-async-storage compatible API\n\n /**\n * Alias for [`getItemAsync()`](#getitemasynckey) method.\n */\n async getItem(key: string): Promise<string | null> {\n return this.getItemAsync(key);\n }\n\n /**\n * Alias for [`setItemAsync()`](#setitemasynckey-value).\n */\n async setItem(key: string, value: string | SQLiteStorageSetItemUpdateFunction): Promise<void> {\n await this.setItemAsync(key, value);\n }\n\n /**\n * Alias for [`removeItemAsync()`](#removeitemasynckey) method.\n */\n async removeItem(key: string): Promise<void> {\n await this.removeItemAsync(key);\n }\n\n /**\n * Alias for [`getAllKeysAsync()`](#getallkeysasync) method.\n */\n async getAllKeys(): Promise<string[]> {\n return this.getAllKeysAsync();\n }\n\n /**\n * Alias for [`clearAsync()`](#clearasync) method.\n */\n async clear(): Promise<void> {\n await this.clearAsync();\n }\n\n /**\n * Merges the given value with the existing value for the given key asynchronously.\n * If the existing value is a JSON object, performs a deep merge.\n */\n async mergeItem(key: string, value: string): Promise<void> {\n this.checkValidInput(key, value);\n await this.setItemAsync(key, (prevValue) => {\n if (prevValue == null) {\n return value;\n }\n const prevJSON = JSON.parse(prevValue);\n const newJSON = JSON.parse(value);\n const mergedJSON = SQLiteStorage.mergeDeep(prevJSON, newJSON);\n return JSON.stringify(mergedJSON);\n });\n }\n\n /**\n * Retrieves the values associated with the given keys asynchronously.\n */\n async multiGet(keys: string[]): Promise<[string, string | null][]> {\n return Promise.all(\n keys.map(async (key): Promise<[string, string | null]> => {\n this.checkValidInput(key);\n return [key, await this.getItemAsync(key)];\n })\n );\n }\n\n /**\n * Sets multiple key-value pairs asynchronously.\n */\n async multiSet(keyValuePairs: [string, string][]): Promise<void> {\n const db = await this.getDbAsync();\n await db.withExclusiveTransactionAsync(async (tx) => {\n for (const [key, value] of keyValuePairs) {\n this.checkValidInput(key, value);\n await tx.runAsync(STATEMENT_SET, key, value);\n }\n });\n }\n\n /**\n * Removes the values associated with the given keys asynchronously.\n */\n async multiRemove(keys: string[]): Promise<void> {\n const db = await this.getDbAsync();\n await db.withExclusiveTransactionAsync(async (tx) => {\n for (const key of keys) {\n this.checkValidInput(key);\n await tx.runAsync(STATEMENT_REMOVE, key);\n }\n });\n }\n\n /**\n * Merges multiple key-value pairs asynchronously.\n * If existing values are JSON objects, performs a deep merge.\n */\n async multiMerge(keyValuePairs: [string, string][]): Promise<void> {\n const db = await this.getDbAsync();\n await db.withExclusiveTransactionAsync(async (tx) => {\n for (const [key, value] of keyValuePairs) {\n this.checkValidInput(key, value);\n const prevValue = await tx.getFirstAsync<{ value: string }>(STATEMENT_GET, key);\n if (prevValue == null) {\n await tx.runAsync(STATEMENT_SET, key, value);\n continue;\n }\n const prevJSON = JSON.parse(prevValue.value);\n const newJSON = JSON.parse(value);\n const mergedJSON = SQLiteStorage.mergeDeep(prevJSON, newJSON);\n await tx.runAsync(STATEMENT_SET, key, JSON.stringify(mergedJSON));\n }\n });\n }\n\n /**\n * Alias for [`closeAsync()`](#closeasync-1) method.\n */\n async close(): Promise<void> {\n await this.closeAsync();\n }\n\n //#endregion\n\n //#region Internals\n\n private async getDbAsync(): Promise<SQLiteDatabase> {\n await this.awaitLock.acquireAsync();\n try {\n if (!this.db) {\n const db = await openDatabaseAsync(this.databaseName);\n await this.maybeMigrateDbAsync(db);\n this.db = db;\n }\n } finally {\n this.awaitLock.release();\n }\n return this.db;\n }\n\n private getDbSync(): SQLiteDatabase {\n if (!this.db) {\n const db = openDatabaseSync(this.databaseName);\n this.maybeMigrateDbSync(db);\n this.db = db;\n }\n return this.db;\n }\n\n private maybeMigrateDbAsync(db: SQLiteDatabase) {\n return db.withTransactionAsync(async () => {\n const result = await db.getFirstAsync<{ user_version: number }>('PRAGMA user_version');\n let currentDbVersion = result?.user_version ?? 0;\n if (currentDbVersion >= DATABASE_VERSION) {\n return;\n }\n if (currentDbVersion === 0) {\n await db.execAsync(MIGRATION_STATEMENT_0);\n currentDbVersion = 1;\n }\n await db.execAsync(`PRAGMA user_version = ${DATABASE_VERSION}`);\n });\n }\n\n private maybeMigrateDbSync(db: SQLiteDatabase) {\n db.withTransactionSync(() => {\n const result = db.getFirstSync<{ user_version: number }>('PRAGMA user_version');\n let currentDbVersion = result?.user_version ?? 0;\n if (currentDbVersion >= DATABASE_VERSION) {\n return;\n }\n if (currentDbVersion === 0) {\n db.execSync(MIGRATION_STATEMENT_0);\n currentDbVersion = 1;\n }\n db.execSync(`PRAGMA user_version = ${DATABASE_VERSION}`);\n });\n }\n\n /**\n * Recursively merge two JSON objects.\n */\n private static mergeDeep(target: any, source: any): any {\n if (typeof target !== 'object' || target === null) {\n return source;\n }\n\n if (typeof source !== 'object' || source === null) {\n return target;\n }\n\n const output = { ...target };\n\n for (const key of Object.keys(source)) {\n if (source[key] instanceof Array) {\n if (!output[key]) {\n output[key] = [];\n }\n output[key] = output[key].concat(source[key]);\n } else if (typeof source[key] === 'object') {\n output[key] = this.mergeDeep(target[key], source[key]);\n } else {\n output[key] = source[key];\n }\n }\n\n return output;\n }\n\n private checkValidInput(...input: unknown[]) {\n const [key, value] = input;\n\n if (typeof key !== 'string') {\n throw new Error(\n `[SQLiteStorage] Using ${typeof key} type for key is not supported. Use string instead. Key passed: ${key}`\n );\n }\n\n if (input.length > 1 && typeof value !== 'string' && typeof value !== 'function') {\n throw new Error(\n `[SQLiteStorage] Using ${typeof value} type for value is not supported. Use string instead. Key passed: ${key}. Value passed : ${value}`\n );\n }\n }\n //#endregion\n}\n\n/**\n * This default instance of the [`SQLiteStorage`](#sqlitestorage-1) class is used as a drop-in replacement for the `AsyncStorage` module from [`@react-native-async-storage/async-storage`](https://github.com/react-native-async-storage/async-storage).\n */\nexport const AsyncStorage = new SQLiteStorage('ExpoSQLiteStorage');\n\nexport default AsyncStorage;\n\n/**\n * Alias for [`AsyncStorage`](#sqliteasyncstorage), given the storage not only offers asynchronous methods.\n */\nexport const Storage = AsyncStorage;\n"]}
@@ -0,0 +1,22 @@
1
+ import { type SQLiteStorage } from './Storage';
2
+ declare class Storage {
3
+ private readonly storage;
4
+ constructor(storage: SQLiteStorage);
5
+ clear(): void;
6
+ getItem(key: string): string | null;
7
+ key(index: number): string | null;
8
+ removeItem(key: string): void;
9
+ setItem(key: string, value: string): void;
10
+ get length(): number;
11
+ toString(): string;
12
+ }
13
+ /**
14
+ * The default instance of the [`SQLiteStorage`](#sqlitestorage-1) class is used as a drop-in implementation for the [`localStorage`](https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage) object from the Web.
15
+ */
16
+ export declare const localStorage: Storage & Record<string, string | undefined>;
17
+ /**
18
+ * Install the `localStorage` on the `globalThis` object.
19
+ */
20
+ export declare function installGlobal(): void;
21
+ export {};
22
+ //# sourceMappingURL=WebStorage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"WebStorage.d.ts","sourceRoot":"","sources":["../src/WebStorage.ts"],"names":[],"mappings":"AAEA,OAAO,EAAwB,KAAK,aAAa,EAAE,MAAM,WAAW,CAAC;AAErE,cAAM,OAAO;IACC,OAAO,CAAC,QAAQ,CAAC,OAAO;gBAAP,OAAO,EAAE,aAAa;IAEnD,KAAK,IAAI,IAAI;IAIb,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAInC,GAAG,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAIjC,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAI7B,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI;IAIzC,IAAI,MAAM,IAAI,MAAM,CAEnB;IAED,QAAQ,IAAI,MAAM;CAGnB;AAiDD;;GAEG;AACH,eAAO,MAAM,YAAY,8CAAgD,CAAC;AAE1E;;GAEG;AACH,wBAAgB,aAAa,SAE5B"}
@@ -0,0 +1,84 @@
1
+ import { installGlobal as install } from 'expo/internal/install-global';
2
+ import { Storage as KVStorage } from './Storage';
3
+ class Storage {
4
+ storage;
5
+ constructor(storage) {
6
+ this.storage = storage;
7
+ }
8
+ clear() {
9
+ this.storage.clearSync();
10
+ }
11
+ getItem(key) {
12
+ return this.storage.getItemSync(key);
13
+ }
14
+ key(index) {
15
+ return this.storage.getKeyByIndexSync(index);
16
+ }
17
+ removeItem(key) {
18
+ this.storage.removeItemSync(key);
19
+ }
20
+ setItem(key, value) {
21
+ this.storage.setItemSync(key, String(value));
22
+ }
23
+ get length() {
24
+ return this.storage.getLengthSync();
25
+ }
26
+ toString() {
27
+ return '[object Storage]';
28
+ }
29
+ }
30
+ /**
31
+ * A Proxy wrapper that allows property accessors to be used on the `WebStorageWrapper` object.
32
+ */
33
+ function withPropertyAccessors(obj) {
34
+ if (typeof Proxy !== 'function') {
35
+ return obj;
36
+ }
37
+ const builtin = new Set();
38
+ let proto = obj;
39
+ while (proto) {
40
+ Object.getOwnPropertyNames(proto).forEach((name) => builtin.add(name));
41
+ proto = Object.getPrototypeOf(proto);
42
+ }
43
+ return new Proxy(obj, {
44
+ get(target, prop, receiver) {
45
+ if (typeof prop !== 'string' || builtin.has(prop)) {
46
+ return Reflect.get(target, prop, receiver);
47
+ }
48
+ // Values are always converted to strings so getItem returns null only when there is no value
49
+ const value = target.getItem(prop);
50
+ return value === null ? undefined : value;
51
+ },
52
+ set(target, prop, value, receiver) {
53
+ if (typeof prop !== 'string' || builtin.has(prop)) {
54
+ return Reflect.set(target, prop, value, receiver);
55
+ }
56
+ target.setItem(prop, String(value));
57
+ return true;
58
+ },
59
+ deleteProperty(target, prop) {
60
+ if (typeof prop !== 'string' || Reflect.ownKeys(target).includes(prop)) {
61
+ return Reflect.deleteProperty(target, prop);
62
+ }
63
+ target.removeItem(prop);
64
+ return true;
65
+ },
66
+ has(target, prop) {
67
+ if (typeof prop !== 'string' || builtin.has(prop)) {
68
+ return Reflect.has(target, prop);
69
+ }
70
+ return target.getItem(prop) !== null;
71
+ },
72
+ });
73
+ }
74
+ /**
75
+ * The default instance of the [`SQLiteStorage`](#sqlitestorage-1) class is used as a drop-in implementation for the [`localStorage`](https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage) object from the Web.
76
+ */
77
+ export const localStorage = withPropertyAccessors(new Storage(KVStorage));
78
+ /**
79
+ * Install the `localStorage` on the `globalThis` object.
80
+ */
81
+ export function installGlobal() {
82
+ install('localStorage', () => localStorage);
83
+ }
84
+ //# sourceMappingURL=WebStorage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"WebStorage.js","sourceRoot":"","sources":["../src/WebStorage.ts"],"names":[],"mappings":"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","sourcesContent":["import { installGlobal as install } from 'expo/internal/install-global';\n\nimport { Storage as KVStorage, type SQLiteStorage } from './Storage';\n\nclass Storage {\n constructor(private readonly storage: SQLiteStorage) {}\n\n clear(): void {\n this.storage.clearSync();\n }\n\n getItem(key: string): string | null {\n return this.storage.getItemSync(key);\n }\n\n key(index: number): string | null {\n return this.storage.getKeyByIndexSync(index);\n }\n\n removeItem(key: string): void {\n this.storage.removeItemSync(key);\n }\n\n setItem(key: string, value: string): void {\n this.storage.setItemSync(key, String(value));\n }\n\n get length(): number {\n return this.storage.getLengthSync();\n }\n\n toString(): string {\n return '[object Storage]';\n }\n}\n\n/**\n * A Proxy wrapper that allows property accessors to be used on the `WebStorageWrapper` object.\n */\nfunction withPropertyAccessors(obj: Storage): Storage & Record<string, string | undefined> {\n if (typeof Proxy !== 'function') {\n return obj as Storage & Record<string, string | undefined>;\n }\n\n const builtin = new Set();\n let proto = obj;\n while (proto) {\n Object.getOwnPropertyNames(proto).forEach((name) => builtin.add(name));\n proto = Object.getPrototypeOf(proto);\n }\n\n return new Proxy(obj as Storage & Record<string, string | undefined>, {\n get(target, prop, receiver) {\n if (typeof prop !== 'string' || builtin.has(prop)) {\n return Reflect.get(target, prop, receiver);\n }\n // Values are always converted to strings so getItem returns null only when there is no value\n const value = target.getItem(prop);\n return value === null ? undefined : value;\n },\n set(target, prop, value, receiver) {\n if (typeof prop !== 'string' || builtin.has(prop)) {\n return Reflect.set(target, prop, value, receiver);\n }\n target.setItem(prop, String(value));\n return true;\n },\n deleteProperty(target, prop) {\n if (typeof prop !== 'string' || Reflect.ownKeys(target).includes(prop)) {\n return Reflect.deleteProperty(target, prop);\n }\n target.removeItem(prop);\n return true;\n },\n has(target, prop) {\n if (typeof prop !== 'string' || builtin.has(prop)) {\n return Reflect.has(target, prop);\n }\n return target.getItem(prop) !== null;\n },\n });\n}\n\n/**\n * The default instance of the [`SQLiteStorage`](#sqlitestorage-1) class is used as a drop-in implementation for the [`localStorage`](https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage) object from the Web.\n */\nexport const localStorage = withPropertyAccessors(new Storage(KVStorage));\n\n/**\n * Install the `localStorage` on the `globalThis` object.\n */\nexport function installGlobal() {\n install('localStorage', () => localStorage);\n}\n"]}
@@ -15,4 +15,10 @@ export declare function composeRow<T>(columnNames: SQLiteColumnNames, columnValu
15
15
  * @hidden
16
16
  */
17
17
  export declare function composeRows<T>(columnNames: SQLiteColumnNames, columnValuesList: SQLiteColumnValues[]): T[];
18
+ /**
19
+ * Normalize the index for the Storage.getKeyByIndexSync and Storage.getKeyByIndexAsync methods.
20
+ * @returns The normalized index or `null` if the index is out of bounds.
21
+ * @hidden
22
+ */
23
+ export declare function normalizeStorageIndex(index: any): number | null;
18
24
  //# sourceMappingURL=paramUtils.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"paramUtils.d.ts","sourceRoot":"","sources":["../src/paramUtils.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,oBAAoB,EAEpB,yBAAyB,EAEzB,KAAK,iBAAiB,EACtB,KAAK,kBAAkB,EACxB,MAAM,mBAAmB,CAAC;AAE3B;;;;GAIG;AACH,wBAAgB,eAAe,CAC7B,GAAG,MAAM,EAAE,GAAG,EAAE,GACf,CAAC,yBAAyB,EAAE,oBAAoB,EAAE,OAAO,CAAC,CAgC5D;AAED;;;GAGG;AACH,wBAAgB,UAAU,CAAC,CAAC,EAAE,WAAW,EAAE,iBAAiB,EAAE,YAAY,EAAE,kBAAkB,GAAG,CAAC,CAYjG;AAED;;;GAGG;AACH,wBAAgB,WAAW,CAAC,CAAC,EAC3B,WAAW,EAAE,iBAAiB,EAC9B,gBAAgB,EAAE,kBAAkB,EAAE,GACrC,CAAC,EAAE,CAoBL"}
1
+ {"version":3,"file":"paramUtils.d.ts","sourceRoot":"","sources":["../src/paramUtils.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,oBAAoB,EAEpB,yBAAyB,EAEzB,KAAK,iBAAiB,EACtB,KAAK,kBAAkB,EACxB,MAAM,mBAAmB,CAAC;AAE3B;;;;GAIG;AACH,wBAAgB,eAAe,CAC7B,GAAG,MAAM,EAAE,GAAG,EAAE,GACf,CAAC,yBAAyB,EAAE,oBAAoB,EAAE,OAAO,CAAC,CAgC5D;AAED;;;GAGG;AACH,wBAAgB,UAAU,CAAC,CAAC,EAAE,WAAW,EAAE,iBAAiB,EAAE,YAAY,EAAE,kBAAkB,GAAG,CAAC,CAYjG;AAED;;;GAGG;AACH,wBAAgB,WAAW,CAAC,CAAC,EAC3B,WAAW,EAAE,iBAAiB,EAC9B,gBAAgB,EAAE,kBAAkB,EAAE,GACrC,CAAC,EAAE,CAoBL;AAED;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,GAAG,GAAG,MAAM,GAAG,IAAI,CAe/D"}
@@ -71,4 +71,24 @@ export function composeRows(columnNames, columnValuesList) {
71
71
  }
72
72
  return results;
73
73
  }
74
+ /**
75
+ * Normalize the index for the Storage.getKeyByIndexSync and Storage.getKeyByIndexAsync methods.
76
+ * @returns The normalized index or `null` if the index is out of bounds.
77
+ * @hidden
78
+ */
79
+ export function normalizeStorageIndex(index) {
80
+ const value = Math.floor(Number(index));
81
+ // Boundary checks
82
+ if (Object.is(value, -0)) {
83
+ return 0;
84
+ }
85
+ if (!Number.isSafeInteger(value)) {
86
+ // Chromium uses zero index when the index is out of bounds
87
+ return 0;
88
+ }
89
+ if (value < 0) {
90
+ return null;
91
+ }
92
+ return value;
93
+ }
74
94
  //# sourceMappingURL=paramUtils.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"paramUtils.js","sourceRoot":"","sources":["../src/paramUtils.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n SQLiteBindBlobParams,\n SQLiteBindParams,\n SQLiteBindPrimitiveParams,\n SQLiteBindValue,\n type SQLiteColumnNames,\n type SQLiteColumnValues,\n} from './NativeStatement';\n\n/**\n * Normalize the bind params to data structure that can be passed to native module.\n * The data structure is a tuple of [primitiveParams, blobParams, shouldPassAsArray].\n * @hidden\n */\nexport function normalizeParams(\n ...params: any[]\n): [SQLiteBindPrimitiveParams, SQLiteBindBlobParams, boolean] {\n let bindParams = params.length > 1 ? params : (params[0] as SQLiteBindParams);\n if (bindParams == null) {\n bindParams = [];\n }\n if (\n typeof bindParams !== 'object' ||\n bindParams instanceof ArrayBuffer ||\n ArrayBuffer.isView(bindParams)\n ) {\n bindParams = [bindParams];\n }\n const shouldPassAsArray = Array.isArray(bindParams);\n if (Array.isArray(bindParams)) {\n bindParams = bindParams.reduce<Record<string, SQLiteBindValue>>((acc, value, index) => {\n acc[index] = value;\n return acc;\n }, {});\n }\n\n const primitiveParams: SQLiteBindPrimitiveParams = {};\n const blobParams: SQLiteBindBlobParams = {};\n for (const key in bindParams) {\n const value = bindParams[key];\n if (value instanceof Uint8Array) {\n blobParams[key] = value;\n } else {\n primitiveParams[key] = value;\n }\n }\n\n return [primitiveParams, blobParams, shouldPassAsArray];\n}\n\n/**\n * Compose `columnNames` and `columnValues` to an row object.\n * @hidden\n */\nexport function composeRow<T>(columnNames: SQLiteColumnNames, columnValues: SQLiteColumnValues): T {\n // TODO(cedric): make these types more generic and tighten the returned object type based on provided column names/values\n const row: { [key in SQLiteColumnNames[number]]: SQLiteColumnValues[number] } = {};\n if (columnNames.length !== columnValues.length) {\n throw new Error(\n `Column names and values count mismatch. Names: ${columnNames.length}, Values: ${columnValues.length}`\n );\n }\n for (let i = 0; i < columnNames.length; i++) {\n row[columnNames[i]] = columnValues[i];\n }\n return row as T;\n}\n\n/**\n * Compose `columnNames` and `columnValuesList` to an array of row objects.\n * @hidden\n */\nexport function composeRows<T>(\n columnNames: SQLiteColumnNames,\n columnValuesList: SQLiteColumnValues[]\n): T[] {\n if (columnValuesList.length === 0) {\n return [];\n }\n if (columnNames.length !== columnValuesList[0].length) {\n // We only check the first row because SQLite returns the same column count for all rows.\n throw new Error(\n `Column names and values count mismatch. Names: ${columnNames.length}, Values: ${columnValuesList[0].length}`\n );\n }\n const results: T[] = [];\n for (const columnValues of columnValuesList) {\n // TODO(cedric): make these types more generic and tighten the returned object type based on provided column names/values\n const row: { [key in SQLiteColumnNames[number]]: SQLiteColumnValues[number] } = {};\n for (let i = 0; i < columnNames.length; i++) {\n row[columnNames[i]] = columnValues[i];\n }\n results.push(row as T);\n }\n return results;\n}\n"]}
1
+ {"version":3,"file":"paramUtils.js","sourceRoot":"","sources":["../src/paramUtils.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n SQLiteBindBlobParams,\n SQLiteBindParams,\n SQLiteBindPrimitiveParams,\n SQLiteBindValue,\n type SQLiteColumnNames,\n type SQLiteColumnValues,\n} from './NativeStatement';\n\n/**\n * Normalize the bind params to data structure that can be passed to native module.\n * The data structure is a tuple of [primitiveParams, blobParams, shouldPassAsArray].\n * @hidden\n */\nexport function normalizeParams(\n ...params: any[]\n): [SQLiteBindPrimitiveParams, SQLiteBindBlobParams, boolean] {\n let bindParams = params.length > 1 ? params : (params[0] as SQLiteBindParams);\n if (bindParams == null) {\n bindParams = [];\n }\n if (\n typeof bindParams !== 'object' ||\n bindParams instanceof ArrayBuffer ||\n ArrayBuffer.isView(bindParams)\n ) {\n bindParams = [bindParams];\n }\n const shouldPassAsArray = Array.isArray(bindParams);\n if (Array.isArray(bindParams)) {\n bindParams = bindParams.reduce<Record<string, SQLiteBindValue>>((acc, value, index) => {\n acc[index] = value;\n return acc;\n }, {});\n }\n\n const primitiveParams: SQLiteBindPrimitiveParams = {};\n const blobParams: SQLiteBindBlobParams = {};\n for (const key in bindParams) {\n const value = bindParams[key];\n if (value instanceof Uint8Array) {\n blobParams[key] = value;\n } else {\n primitiveParams[key] = value;\n }\n }\n\n return [primitiveParams, blobParams, shouldPassAsArray];\n}\n\n/**\n * Compose `columnNames` and `columnValues` to an row object.\n * @hidden\n */\nexport function composeRow<T>(columnNames: SQLiteColumnNames, columnValues: SQLiteColumnValues): T {\n // TODO(cedric): make these types more generic and tighten the returned object type based on provided column names/values\n const row: { [key in SQLiteColumnNames[number]]: SQLiteColumnValues[number] } = {};\n if (columnNames.length !== columnValues.length) {\n throw new Error(\n `Column names and values count mismatch. Names: ${columnNames.length}, Values: ${columnValues.length}`\n );\n }\n for (let i = 0; i < columnNames.length; i++) {\n row[columnNames[i]] = columnValues[i];\n }\n return row as T;\n}\n\n/**\n * Compose `columnNames` and `columnValuesList` to an array of row objects.\n * @hidden\n */\nexport function composeRows<T>(\n columnNames: SQLiteColumnNames,\n columnValuesList: SQLiteColumnValues[]\n): T[] {\n if (columnValuesList.length === 0) {\n return [];\n }\n if (columnNames.length !== columnValuesList[0].length) {\n // We only check the first row because SQLite returns the same column count for all rows.\n throw new Error(\n `Column names and values count mismatch. Names: ${columnNames.length}, Values: ${columnValuesList[0].length}`\n );\n }\n const results: T[] = [];\n for (const columnValues of columnValuesList) {\n // TODO(cedric): make these types more generic and tighten the returned object type based on provided column names/values\n const row: { [key in SQLiteColumnNames[number]]: SQLiteColumnValues[number] } = {};\n for (let i = 0; i < columnNames.length; i++) {\n row[columnNames[i]] = columnValues[i];\n }\n results.push(row as T);\n }\n return results;\n}\n\n/**\n * Normalize the index for the Storage.getKeyByIndexSync and Storage.getKeyByIndexAsync methods.\n * @returns The normalized index or `null` if the index is out of bounds.\n * @hidden\n */\nexport function normalizeStorageIndex(index: any): number | null {\n const value = Math.floor(Number(index));\n\n // Boundary checks\n if (Object.is(value, -0)) {\n return 0;\n }\n if (!Number.isSafeInteger(value)) {\n // Chromium uses zero index when the index is out of bounds\n return 0;\n }\n if (value < 0) {\n return null;\n }\n return value;\n}\n"]}
@@ -9,7 +9,7 @@
9
9
  "publication": {
10
10
  "groupId": "host.exp.exponent",
11
11
  "artifactId": "expo.modules.sqlite",
12
- "version": "16.0.0",
12
+ "version": "16.0.2",
13
13
  "repository": "local-maven-repo"
14
14
  }
15
15
  }
@@ -3,7 +3,7 @@
3
3
  "component": {
4
4
  "group": "host.exp.exponent",
5
5
  "module": "expo.modules.sqlite",
6
- "version": "16.0.0",
6
+ "version": "16.0.2",
7
7
  "attributes": {
8
8
  "org.gradle.status": "release"
9
9
  }
@@ -24,8 +24,8 @@
24
24
  },
25
25
  "files": [
26
26
  {
27
- "name": "expo.modules.sqlite-16.0.0.aar",
28
- "url": "expo.modules.sqlite-16.0.0.aar",
27
+ "name": "expo.modules.sqlite-16.0.2.aar",
28
+ "url": "expo.modules.sqlite-16.0.2.aar",
29
29
  "size": 3777634,
30
30
  "sha512": "32ce43d8c0a4f43095cadaad5098b53c56169bb0ac70a158f3efab2347e3a7652015bd3c7239ff97767578e0aa487ac7e17af733c08acfbb9a6c41ad21afe878",
31
31
  "sha256": "f793ac07721eddffbe4bae471c3e3230e723689f9f33f2d1467508196ae364d8",
@@ -53,8 +53,8 @@
53
53
  ],
54
54
  "files": [
55
55
  {
56
- "name": "expo.modules.sqlite-16.0.0.aar",
57
- "url": "expo.modules.sqlite-16.0.0.aar",
56
+ "name": "expo.modules.sqlite-16.0.2.aar",
57
+ "url": "expo.modules.sqlite-16.0.2.aar",
58
58
  "size": 3777634,
59
59
  "sha512": "32ce43d8c0a4f43095cadaad5098b53c56169bb0ac70a158f3efab2347e3a7652015bd3c7239ff97767578e0aa487ac7e17af733c08acfbb9a6c41ad21afe878",
60
60
  "sha256": "f793ac07721eddffbe4bae471c3e3230e723689f9f33f2d1467508196ae364d8",
@@ -73,8 +73,8 @@
73
73
  },
74
74
  "files": [
75
75
  {
76
- "name": "expo.modules.sqlite-16.0.0-sources.jar",
77
- "url": "expo.modules.sqlite-16.0.0-sources.jar",
76
+ "name": "expo.modules.sqlite-16.0.2-sources.jar",
77
+ "url": "expo.modules.sqlite-16.0.2-sources.jar",
78
78
  "size": 11345,
79
79
  "sha512": "7b8496846da3f6beda4f6eb348c803dd4873dd422cdd4f37705b074c5aaa6f36565622c45c6504ecac5ba833cd461951a2d1efb6d515c9a0d2d716a2777b1fc4",
80
80
  "sha256": "440b3474772cf69de4c88b7a597b4c2c8207f27d7b401149ecb8f45588570af1",
@@ -0,0 +1 @@
1
+ 6357fbfad476765b1c5a2b733cc48cde845b2d2511f65148342ccab8f1af8cc9
@@ -0,0 +1 @@
1
+ dbd34caeb84b202025bd94a665a22876877430186d2c65ebcbdf2dfa6123665c080ac1154c68953ad345c4291f5f98adc6898aa327fdb44309d2e87e92d68f00
@@ -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>16.0.0</version>
12
+ <version>16.0.2</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
+ dd615fa860f6a8adabb768c6729a74c20d68a3f5eae4cfc411e7e36dcbeae117
@@ -0,0 +1 @@
1
+ 22d7c38b143caeaf5dc7c9b8bd37a617d42a31346dee268836d01f34f101db52aa8963214e2099c0f83569aa75d9aa1fcd8061a6fd0cd5f8f65cfef54b61afc4
@@ -3,11 +3,11 @@
3
3
  <groupId>host.exp.exponent</groupId>
4
4
  <artifactId>expo.modules.sqlite</artifactId>
5
5
  <versioning>
6
- <latest>16.0.0</latest>
7
- <release>16.0.0</release>
6
+ <latest>16.0.2</latest>
7
+ <release>16.0.2</release>
8
8
  <versions>
9
- <version>16.0.0</version>
9
+ <version>16.0.2</version>
10
10
  </versions>
11
- <lastUpdated>20250813165921</lastUpdated>
11
+ <lastUpdated>20250817001226</lastUpdated>
12
12
  </versioning>
13
13
  </metadata>
@@ -1 +1 @@
1
- 0bebbae77f21fa5624cf05a0d56b078c
1
+ e318833e39c5c78a2849ca1a9fad5fbb
@@ -1 +1 @@
1
- 6fa2863a11b4ee468d75ad5306ea1a33a786bdc2
1
+ 3276b2e4ec3ef31838e3f02c81638c78bf541544
@@ -1 +1 @@
1
- ef7bd4b44da68a12772f026f6f644fc88bb660c2a63d5247d6d45945be99e637
1
+ 1ec6953becb6dd445f669ef3f81639f259dd73fc4f92caa0d0131318f449aa67
@@ -1 +1 @@
1
- 8636bc31049fbf9238e0468a9a274712da38b432699d3bae682d3fd747dff1b03684e839c5e45075448609aac47955c52977bdb1d5d3a258f0460f6467c6647e
1
+ 17e76a895fded221edada71fecca460c37a4375956890b249a3f1313e344aedb8b35b70b885fb2f2eb6b07c498ea46d652b5f0f193ac92142ba3c388890944ad
@@ -0,0 +1,4 @@
1
+ if (process.env.EXPO_OS !== 'web') {
2
+ const { installGlobal } = require('../build/WebStorage');
3
+ installGlobal();
4
+ }
package/package.json CHANGED
@@ -1,10 +1,12 @@
1
1
  {
2
2
  "name": "expo-sqlite",
3
- "version": "16.0.0",
3
+ "version": "16.0.2",
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
  "main": "build/index.js",
6
6
  "types": "build/index.d.ts",
7
- "sideEffects": false,
7
+ "sideEffects": [
8
+ "./localStorage/install.js"
9
+ ],
8
10
  "exports": {
9
11
  "./package.json": "./package.json",
10
12
  ".": {
@@ -15,6 +17,9 @@
15
17
  "default": "./kv-store.js",
16
18
  "types": "./kv-store.d.ts"
17
19
  },
20
+ "./localStorage/install": {
21
+ "default": "./localStorage/install.js"
22
+ },
18
23
  "./app.plugin.js": "./app.plugin.js"
19
24
  },
20
25
  "scripts": {
@@ -52,10 +57,10 @@
52
57
  "await-lock": "^2.2.2"
53
58
  },
54
59
  "devDependencies": {
55
- "@testing-library/react-native": "^13.1.0",
60
+ "@testing-library/react-native": "^13.2.0",
56
61
  "@types/better-sqlite3": "^7.6.6",
57
62
  "better-sqlite3": "^11.6.0",
58
- "expo-module-scripts": "^5.0.0",
63
+ "expo-module-scripts": "^5.0.2",
59
64
  "react-error-boundary": "^4.0.11"
60
65
  },
61
66
  "peerDependencies": {
@@ -63,5 +68,5 @@
63
68
  "react": "*",
64
69
  "react-native": "*"
65
70
  },
66
- "gitHead": "cb7062e2c17d1fb09522834aaaac0e19b766df62"
71
+ "gitHead": "eaa9b645058cf2233fbb27bb21a19bc605c90a88"
67
72
  }
package/src/Storage.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  import AwaitLock from 'await-lock';
2
2
 
3
3
  import { openDatabaseAsync, openDatabaseSync, type SQLiteDatabase } from './index';
4
+ import { normalizeStorageIndex } from './paramUtils';
4
5
 
5
6
  /**
6
7
  * Update function for the [`setItemAsync()`](#setitemasynckey-value) or [`setItemSync()`](#setitemsynckey-value) method. It computes the new value based on the previous value. The function returns the new value to set for the key.
@@ -16,6 +17,8 @@ const STATEMENT_SET =
16
17
  const STATEMENT_REMOVE = 'DELETE FROM storage WHERE key = ?;';
17
18
  const STATEMENT_GET_ALL_KEYS = 'SELECT key FROM storage;';
18
19
  const STATEMENT_CLEAR = 'DELETE FROM storage;';
20
+ const STATEMENT_LENGTH = 'SELECT COUNT(*) as count FROM storage;';
21
+ const STATEMENT_GET_KEY_BY_INDEX = 'SELECT key FROM storage LIMIT 1 OFFSET ?;';
19
22
 
20
23
  const MIGRATION_STATEMENT_0 =
21
24
  'CREATE TABLE IF NOT EXISTS storage (key TEXT PRIMARY KEY NOT NULL, value TEXT);';
@@ -109,6 +112,28 @@ export class SQLiteStorage {
109
112
  }
110
113
  }
111
114
 
115
+ /**
116
+ * Retrieves the number of key-value pairs stored in the storage asynchronously.
117
+ */
118
+ async getLengthAsync(): Promise<number> {
119
+ const db = await this.getDbAsync();
120
+ const result = await db.getFirstAsync<{ count: number }>(STATEMENT_LENGTH);
121
+ return result?.count ?? 0;
122
+ }
123
+
124
+ /**
125
+ * Retrieves the key at the given index asynchronously.
126
+ */
127
+ async getKeyByIndexAsync(index: number): Promise<string | null> {
128
+ const db = await this.getDbAsync();
129
+ const offset = normalizeStorageIndex(index);
130
+ if (offset == null) {
131
+ return null;
132
+ }
133
+ const result = await db.getFirstAsync<{ key: string }>(STATEMENT_GET_KEY_BY_INDEX, offset);
134
+ return result?.key ?? null;
135
+ }
136
+
112
137
  //#endregion
113
138
 
114
139
  //#region Synchronous API
@@ -183,6 +208,28 @@ export class SQLiteStorage {
183
208
  }
184
209
  }
185
210
 
211
+ /**
212
+ * Retrieves the number of key-value pairs stored in the storage synchronously.
213
+ */
214
+ getLengthSync(): number {
215
+ const db = this.getDbSync();
216
+ const result = db.getFirstSync<{ count: number }>(STATEMENT_LENGTH);
217
+ return result!.count ?? 0;
218
+ }
219
+
220
+ /**
221
+ * Retrieves the key at the given index synchronously.
222
+ */
223
+ getKeyByIndexSync(index: number): string | null {
224
+ const db = this.getDbSync();
225
+ const offset = normalizeStorageIndex(index);
226
+ if (offset == null) {
227
+ return null;
228
+ }
229
+ const result = db.getFirstSync<{ key: string }>(STATEMENT_GET_KEY_BY_INDEX, offset);
230
+ return result?.key ?? null;
231
+ }
232
+
186
233
  //#endregion
187
234
 
188
235
  //#region react-native-async-storage compatible API
@@ -408,7 +455,6 @@ export class SQLiteStorage {
408
455
  );
409
456
  }
410
457
  }
411
-
412
458
  //#endregion
413
459
  }
414
460
 
@@ -0,0 +1,94 @@
1
+ import { installGlobal as install } from 'expo/internal/install-global';
2
+
3
+ import { Storage as KVStorage, type SQLiteStorage } from './Storage';
4
+
5
+ class Storage {
6
+ constructor(private readonly storage: SQLiteStorage) {}
7
+
8
+ clear(): void {
9
+ this.storage.clearSync();
10
+ }
11
+
12
+ getItem(key: string): string | null {
13
+ return this.storage.getItemSync(key);
14
+ }
15
+
16
+ key(index: number): string | null {
17
+ return this.storage.getKeyByIndexSync(index);
18
+ }
19
+
20
+ removeItem(key: string): void {
21
+ this.storage.removeItemSync(key);
22
+ }
23
+
24
+ setItem(key: string, value: string): void {
25
+ this.storage.setItemSync(key, String(value));
26
+ }
27
+
28
+ get length(): number {
29
+ return this.storage.getLengthSync();
30
+ }
31
+
32
+ toString(): string {
33
+ return '[object Storage]';
34
+ }
35
+ }
36
+
37
+ /**
38
+ * A Proxy wrapper that allows property accessors to be used on the `WebStorageWrapper` object.
39
+ */
40
+ function withPropertyAccessors(obj: Storage): Storage & Record<string, string | undefined> {
41
+ if (typeof Proxy !== 'function') {
42
+ return obj as Storage & Record<string, string | undefined>;
43
+ }
44
+
45
+ const builtin = new Set();
46
+ let proto = obj;
47
+ while (proto) {
48
+ Object.getOwnPropertyNames(proto).forEach((name) => builtin.add(name));
49
+ proto = Object.getPrototypeOf(proto);
50
+ }
51
+
52
+ return new Proxy(obj as Storage & Record<string, string | undefined>, {
53
+ get(target, prop, receiver) {
54
+ if (typeof prop !== 'string' || builtin.has(prop)) {
55
+ return Reflect.get(target, prop, receiver);
56
+ }
57
+ // Values are always converted to strings so getItem returns null only when there is no value
58
+ const value = target.getItem(prop);
59
+ return value === null ? undefined : value;
60
+ },
61
+ set(target, prop, value, receiver) {
62
+ if (typeof prop !== 'string' || builtin.has(prop)) {
63
+ return Reflect.set(target, prop, value, receiver);
64
+ }
65
+ target.setItem(prop, String(value));
66
+ return true;
67
+ },
68
+ deleteProperty(target, prop) {
69
+ if (typeof prop !== 'string' || Reflect.ownKeys(target).includes(prop)) {
70
+ return Reflect.deleteProperty(target, prop);
71
+ }
72
+ target.removeItem(prop);
73
+ return true;
74
+ },
75
+ has(target, prop) {
76
+ if (typeof prop !== 'string' || builtin.has(prop)) {
77
+ return Reflect.has(target, prop);
78
+ }
79
+ return target.getItem(prop) !== null;
80
+ },
81
+ });
82
+ }
83
+
84
+ /**
85
+ * The default instance of the [`SQLiteStorage`](#sqlitestorage-1) class is used as a drop-in implementation for the [`localStorage`](https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage) object from the Web.
86
+ */
87
+ export const localStorage = withPropertyAccessors(new Storage(KVStorage));
88
+
89
+ /**
90
+ * Install the `localStorage` on the `globalThis` object.
91
+ */
92
+ export function installGlobal() {
93
+ install('localStorage', () => localStorage);
94
+ }
package/src/paramUtils.ts CHANGED
@@ -94,3 +94,25 @@ export function composeRows<T>(
94
94
  }
95
95
  return results;
96
96
  }
97
+
98
+ /**
99
+ * Normalize the index for the Storage.getKeyByIndexSync and Storage.getKeyByIndexAsync methods.
100
+ * @returns The normalized index or `null` if the index is out of bounds.
101
+ * @hidden
102
+ */
103
+ export function normalizeStorageIndex(index: any): number | null {
104
+ const value = Math.floor(Number(index));
105
+
106
+ // Boundary checks
107
+ if (Object.is(value, -0)) {
108
+ return 0;
109
+ }
110
+ if (!Number.isSafeInteger(value)) {
111
+ // Chromium uses zero index when the index is out of bounds
112
+ return 0;
113
+ }
114
+ if (value < 0) {
115
+ return null;
116
+ }
117
+ return value;
118
+ }
@@ -1 +0,0 @@
1
- c4e42a1f695b5cbe0f206e48e9241861d9f8d75e0443d8d22cab031489f16e0a
@@ -1 +0,0 @@
1
- d23110417e00363596cfc0a4a706292f573f571defb17af18ef359308ef2736f554bbcf98713f943694ebd00a8b337612ecb8c16457e968e50b03201d029d99e
@@ -1 +0,0 @@
1
- 6e1db66013b3e3a2d8fa028bd2befb14d9f42c8d
@@ -1 +0,0 @@
1
- 94fde014d9cfb89ec24bd52e70e202152554a47a96cef4adf45f5fab7b60a831
@@ -1 +0,0 @@
1
- 9282adcf701150bd035778ecd34a9f69f8550d5bad4f27d5c6d82e26902e34d0bd2aa6174cd0020a2c098c251d7df0b253cfd27fe0ce08da0bf2c84106ebbc94