@symbiote-native/sqlite 0.1.0

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 (128) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +283 -0
  3. package/build/angular/index.d.ts +2 -0
  4. package/build/angular/index.js +2 -0
  5. package/build/angular/sqlite.service.d.ts +41 -0
  6. package/build/angular/sqlite.service.js +127 -0
  7. package/build/core/index.d.ts +10 -0
  8. package/build/core/index.js +6 -0
  9. package/build/core/native-database.d.ts +65 -0
  10. package/build/core/native-database.js +13 -0
  11. package/build/core/native-module.d.ts +25 -0
  12. package/build/core/native-module.js +17 -0
  13. package/build/core/native-session.d.ts +20 -0
  14. package/build/core/native-session.js +1 -0
  15. package/build/core/native-statement.d.ts +45 -0
  16. package/build/core/native-statement.js +6 -0
  17. package/build/core/param-utils.d.ts +28 -0
  18. package/build/core/param-utils.js +126 -0
  19. package/build/core/path-utils.d.ts +6 -0
  20. package/build/core/path-utils.js +29 -0
  21. package/build/core/query-utils.d.ts +17 -0
  22. package/build/core/query-utils.js +37 -0
  23. package/build/core/sqlite-database.d.ts +246 -0
  24. package/build/core/sqlite-database.js +427 -0
  25. package/build/core/sqlite-session.d.ts +84 -0
  26. package/build/core/sqlite-session.js +121 -0
  27. package/build/core/sqlite-statement.d.ts +96 -0
  28. package/build/core/sqlite-statement.js +321 -0
  29. package/build/core/sqlite-tagged-query.d.ts +73 -0
  30. package/build/core/sqlite-tagged-query.js +119 -0
  31. package/build/core/storage.d.ts +107 -0
  32. package/build/core/storage.js +382 -0
  33. package/build/core/types.d.ts +30 -0
  34. package/build/core/types.js +1 -0
  35. package/build/react/index.d.ts +2 -0
  36. package/build/react/index.js +2 -0
  37. package/build/react/sqlite-context.d.ts +25 -0
  38. package/build/react/sqlite-context.js +129 -0
  39. package/build/solid/index.d.ts +2 -0
  40. package/build/solid/index.js +2 -0
  41. package/build/solid/sqlite-context.d.ts +23 -0
  42. package/build/solid/sqlite-context.js +106 -0
  43. package/build/svelte/SQLiteProvider.svelte +88 -0
  44. package/build/svelte/SQLiteProvider.svelte.d.ts +13 -0
  45. package/build/svelte/index.d.ts +3 -0
  46. package/build/svelte/index.js +5 -0
  47. package/build/svelte/sqlite-context.d.ts +11 -0
  48. package/build/svelte/sqlite-context.js +23 -0
  49. package/build/vue/index.d.ts +2 -0
  50. package/build/vue/index.js +2 -0
  51. package/build/vue/sqlite-context.d.ts +21 -0
  52. package/build/vue/sqlite-context.js +69 -0
  53. package/build-ngc/angular/index.d.ts +2 -0
  54. package/build-ngc/angular/index.js +3 -0
  55. package/build-ngc/angular/index.js.map +1 -0
  56. package/build-ngc/angular/sqlite.service.d.ts +44 -0
  57. package/build-ngc/angular/sqlite.service.js +85 -0
  58. package/build-ngc/angular/sqlite.service.js.map +1 -0
  59. package/build-ngc/core/index.d.ts +10 -0
  60. package/build-ngc/core/index.js +7 -0
  61. package/build-ngc/core/index.js.map +1 -0
  62. package/build-ngc/core/native-database.d.ts +65 -0
  63. package/build-ngc/core/native-database.js +14 -0
  64. package/build-ngc/core/native-database.js.map +1 -0
  65. package/build-ngc/core/native-module.d.ts +25 -0
  66. package/build-ngc/core/native-module.js +18 -0
  67. package/build-ngc/core/native-module.js.map +1 -0
  68. package/build-ngc/core/native-session.d.ts +20 -0
  69. package/build-ngc/core/native-session.js +2 -0
  70. package/build-ngc/core/native-session.js.map +1 -0
  71. package/build-ngc/core/native-statement.d.ts +45 -0
  72. package/build-ngc/core/native-statement.js +7 -0
  73. package/build-ngc/core/native-statement.js.map +1 -0
  74. package/build-ngc/core/param-utils.d.ts +28 -0
  75. package/build-ngc/core/param-utils.js +127 -0
  76. package/build-ngc/core/param-utils.js.map +1 -0
  77. package/build-ngc/core/path-utils.d.ts +6 -0
  78. package/build-ngc/core/path-utils.js +30 -0
  79. package/build-ngc/core/path-utils.js.map +1 -0
  80. package/build-ngc/core/query-utils.d.ts +17 -0
  81. package/build-ngc/core/query-utils.js +38 -0
  82. package/build-ngc/core/query-utils.js.map +1 -0
  83. package/build-ngc/core/sqlite-database.d.ts +246 -0
  84. package/build-ngc/core/sqlite-database.js +428 -0
  85. package/build-ngc/core/sqlite-database.js.map +1 -0
  86. package/build-ngc/core/sqlite-session.d.ts +84 -0
  87. package/build-ngc/core/sqlite-session.js +122 -0
  88. package/build-ngc/core/sqlite-session.js.map +1 -0
  89. package/build-ngc/core/sqlite-statement.d.ts +96 -0
  90. package/build-ngc/core/sqlite-statement.js +322 -0
  91. package/build-ngc/core/sqlite-statement.js.map +1 -0
  92. package/build-ngc/core/sqlite-tagged-query.d.ts +73 -0
  93. package/build-ngc/core/sqlite-tagged-query.js +120 -0
  94. package/build-ngc/core/sqlite-tagged-query.js.map +1 -0
  95. package/build-ngc/core/storage.d.ts +107 -0
  96. package/build-ngc/core/storage.js +383 -0
  97. package/build-ngc/core/storage.js.map +1 -0
  98. package/build-ngc/core/types.d.ts +30 -0
  99. package/build-ngc/core/types.js +2 -0
  100. package/build-ngc/core/types.js.map +1 -0
  101. package/native-link.json +12 -0
  102. package/package.json +141 -0
  103. package/src/angular/index.ts +2 -0
  104. package/src/angular/sqlite.service.ts +114 -0
  105. package/src/core/index.ts +40 -0
  106. package/src/core/native-database.ts +118 -0
  107. package/src/core/native-module.ts +57 -0
  108. package/src/core/native-session.ts +64 -0
  109. package/src/core/native-statement.ts +85 -0
  110. package/src/core/param-utils.ts +163 -0
  111. package/src/core/path-utils.ts +38 -0
  112. package/src/core/query-utils.ts +45 -0
  113. package/src/core/sqlite-database.ts +676 -0
  114. package/src/core/sqlite-session.ts +165 -0
  115. package/src/core/sqlite-statement.ts +578 -0
  116. package/src/core/sqlite-tagged-query.ts +160 -0
  117. package/src/core/storage.ts +492 -0
  118. package/src/core/types.ts +33 -0
  119. package/src/react/index.ts +2 -0
  120. package/src/react/sqlite-context.tsx +244 -0
  121. package/src/solid/index.ts +2 -0
  122. package/src/solid/sqlite-context.ts +156 -0
  123. package/src/svelte/SQLiteProvider.svelte +88 -0
  124. package/src/svelte/index.ts +6 -0
  125. package/src/svelte/sqlite-context.ts +32 -0
  126. package/src/svelte/svelte-compile.test-helper.ts +135 -0
  127. package/src/vue/index.ts +2 -0
  128. package/src/vue/sqlite-context.ts +105 -0
@@ -0,0 +1,14 @@
1
+ /** Flattens `ISQLiteOpenOptions` into the shape the native module expects. */
2
+ export function flattenOpenOptions(options) {
3
+ const { libSQLOptions, ...restOptions } = options;
4
+ const result = { ...restOptions };
5
+ if (libSQLOptions) {
6
+ Object.assign(result, {
7
+ libSQLUrl: libSQLOptions.url,
8
+ libSQLAuthToken: libSQLOptions.authToken,
9
+ libSQLRemoteOnly: libSQLOptions.remoteOnly,
10
+ });
11
+ }
12
+ return result;
13
+ }
14
+ //# sourceMappingURL=native-database.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"native-database.js","sourceRoot":"","sources":["../../src/core/native-database.ts"],"names":[],"mappings":"AAuGA,8EAA8E;AAC9E,MAAM,UAAU,kBAAkB,CAChC,OAA2B;IAE3B,MAAM,EAAE,aAAa,EAAE,GAAG,WAAW,EAAE,GAAG,OAAO,CAAC;IAClD,MAAM,MAAM,GAA0B,EAAE,GAAG,WAAW,EAAE,CAAC;IACzD,IAAI,aAAa,EAAE,CAAC;QAClB,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE;YACpB,SAAS,EAAE,aAAa,CAAC,GAAG;YAC5B,eAAe,EAAE,aAAa,CAAC,SAAS;YACxC,gBAAgB,EAAE,aAAa,CAAC,UAAU;SAC3C,CAAC,CAAC;IACL,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC"}
@@ -0,0 +1,25 @@
1
+ import type { EventSubscription } from 'expo-modules-core';
2
+ import { NativeDatabase } from './native-database';
3
+ import { NativeSession } from './native-session';
4
+ import { NativeStatement } from './native-statement';
5
+ import type { IDatabaseChangeEvent } from './types';
6
+ export type INativeSQLiteModule = {
7
+ readonly NativeDatabase: typeof NativeDatabase;
8
+ readonly NativeStatement: typeof NativeStatement;
9
+ readonly NativeSession: typeof NativeSession;
10
+ /** The directory new databases are created in when no explicit directory is given. */
11
+ readonly defaultDatabaseDirectory: string;
12
+ /** Pre-bundled SQLite extensions (e.g. `sqlite-vec`), keyed by extension name. */
13
+ readonly bundledExtensions: Record<string, {
14
+ libPath: string;
15
+ entryPoint: string;
16
+ } | undefined>;
17
+ ensureDatabasePathExistsAsync(databasePath: string): Promise<void>;
18
+ ensureDatabasePathExistsSync(databasePath: string): void;
19
+ deleteDatabaseAsync(databasePath: string): Promise<void>;
20
+ deleteDatabaseSync(databasePath: string): void;
21
+ backupDatabaseAsync(destDatabase: NativeDatabase, destDatabaseName: string, sourceDatabase: NativeDatabase, sourceDatabaseName: string): Promise<void>;
22
+ backupDatabaseSync(destDatabase: NativeDatabase, destDatabaseName: string, sourceDatabase: NativeDatabase, sourceDatabaseName: string): void;
23
+ addListener(eventName: 'onDatabaseChange', listener: (event: IDatabaseChangeEvent) => void): EventSubscription;
24
+ };
25
+ export declare const expoSQLite: INativeSQLiteModule;
@@ -0,0 +1,18 @@
1
+ // Resolves expo-sqlite's native module by the same name its own `ExpoSQLite.ts` one-liner uses
2
+ // (`.vendors/expo` @ origin/sdk-57, packages/expo-sqlite/src/ExpoSQLite.ts:
3
+ // `requireNativeModule('ExpoSQLite')`) — through `expo-modules-core` directly, never the `expo`
4
+ // meta-package (root CLAUDE.md's dependency-scope invariant). Verified against the Android
5
+ // module's `Name("ExpoSQLite")` declaration
6
+ // (packages/expo-sqlite/android/.../SQLiteModule.kt) — see this package's `native-link.json`.
7
+ //
8
+ // `NativeDatabase`/`NativeStatement`/`NativeSession` are plain constructors exposed as CLASS
9
+ // PROPERTIES on the native module (`new ExpoSQLite.NativeDatabase(...)`), not `SharedObject`
10
+ // subclasses — see native-database.ts's header for why that makes this simpler than
11
+ // `@symbiote-native/audio`'s port.
12
+ import { requireNativeModule } from 'expo-modules-core';
13
+ import { NativeDatabase } from './native-database';
14
+ import { NativeSession } from './native-session';
15
+ import { NativeStatement } from './native-statement';
16
+ const EXPO_SQLITE_MODULE_NAME = 'ExpoSQLite';
17
+ export const expoSQLite = requireNativeModule(EXPO_SQLITE_MODULE_NAME);
18
+ //# sourceMappingURL=native-module.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"native-module.js","sourceRoot":"","sources":["../../src/core/native-module.ts"],"names":[],"mappings":"AAAA,+FAA+F;AAC/F,4EAA4E;AAC5E,gGAAgG;AAChG,2FAA2F;AAC3F,4CAA4C;AAC5C,8FAA8F;AAC9F,EAAE;AACF,6FAA6F;AAC7F,6FAA6F;AAC7F,oFAAoF;AACpF,mCAAmC;AACnC,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAGxD,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACnD,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACjD,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAGrD,MAAM,uBAAuB,GAAG,YAAY,CAAC;AAmC7C,MAAM,CAAC,MAAM,UAAU,GAAG,mBAAmB,CAC3C,uBAAuB,CACxB,CAAC"}
@@ -0,0 +1,20 @@
1
+ import type { ISQLiteAnyDatabase } from './native-statement';
2
+ /** A changeset produced by the session extension. */
3
+ export type IChangeset = Uint8Array;
4
+ export type INativeChangeset = ArrayBuffer;
5
+ export declare class NativeSession {
6
+ attachAsync(database: ISQLiteAnyDatabase, table: string | null): Promise<void>;
7
+ enableAsync(database: ISQLiteAnyDatabase, enabled: boolean): Promise<void>;
8
+ closeAsync(database: ISQLiteAnyDatabase): Promise<void>;
9
+ createChangesetAsync(database: ISQLiteAnyDatabase): Promise<INativeChangeset>;
10
+ createInvertedChangesetAsync(database: ISQLiteAnyDatabase): Promise<INativeChangeset>;
11
+ applyChangesetAsync(database: ISQLiteAnyDatabase, changeset: IChangeset | INativeChangeset): Promise<void>;
12
+ invertChangesetAsync(database: ISQLiteAnyDatabase, changeset: IChangeset | INativeChangeset): Promise<INativeChangeset>;
13
+ attachSync(database: ISQLiteAnyDatabase, table: string | null): void;
14
+ enableSync(database: ISQLiteAnyDatabase, enabled: boolean): void;
15
+ closeSync(database: ISQLiteAnyDatabase): void;
16
+ createChangesetSync(database: ISQLiteAnyDatabase): INativeChangeset;
17
+ createInvertedChangesetSync(database: ISQLiteAnyDatabase): INativeChangeset;
18
+ applyChangesetSync(database: ISQLiteAnyDatabase, changeset: IChangeset | INativeChangeset): void;
19
+ invertChangesetSync(database: ISQLiteAnyDatabase, changeset: IChangeset | INativeChangeset): INativeChangeset;
20
+ }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=native-session.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"native-session.js","sourceRoot":"","sources":["../../src/core/native-session.ts"],"names":[],"mappings":""}
@@ -0,0 +1,45 @@
1
+ /** A result returned by `SQLiteStatement.executeAsync()`/`executeSync()`. */
2
+ export type ISQLiteRunResult = {
3
+ /**
4
+ * The last inserted row ID, from
5
+ * [`sqlite3_last_insert_rowid()`](https://www.sqlite.org/c3ref/last_insert_rowid.html).
6
+ */
7
+ lastInsertRowId: number;
8
+ /**
9
+ * The number of rows affected, from
10
+ * [`sqlite3_changes()`](https://www.sqlite.org/c3ref/changes.html).
11
+ */
12
+ changes: number;
13
+ };
14
+ /**
15
+ * Bind parameters to a prepared statement — a single array/variadic args for unnamed
16
+ * parameters (`?`), or a single object for named parameters (`:VVV`, `@VVV`, `$VVV`).
17
+ */
18
+ export type ISQLiteBindValue = string | number | null | boolean | ISQLiteBindBlobValue;
19
+ export type ISQLiteBindParams = Record<string, ISQLiteBindValue> | ISQLiteBindValue[];
20
+ export type ISQLiteVariadicBindParams = ISQLiteBindValue[];
21
+ export type ISQLiteBindBlobValue = Uint8Array | ArrayBuffer;
22
+ export type ISQLiteBindPrimitiveParams = Record<string, Exclude<ISQLiteBindValue, ISQLiteBindBlobValue>>;
23
+ export type ISQLiteBindBlobParams = Record<string, ISQLiteBindBlobValue>;
24
+ export type ISQLiteColumnNames = string[];
25
+ export type ISQLiteColumnValues = any[];
26
+ export type ISQLiteAnyDatabase = any;
27
+ /** An instance of a prepared SQLite statement. */
28
+ export declare class NativeStatement {
29
+ runAsync(database: ISQLiteAnyDatabase, bindParams: ISQLiteBindPrimitiveParams, bindBlobParams: ISQLiteBindBlobParams, shouldPassAsArray: boolean): Promise<ISQLiteRunResult & {
30
+ firstRowValues: ISQLiteColumnValues;
31
+ }>;
32
+ stepAsync(database: ISQLiteAnyDatabase): Promise<ISQLiteColumnValues | null | undefined>;
33
+ getAllAsync(database: ISQLiteAnyDatabase): Promise<ISQLiteColumnValues[]>;
34
+ resetAsync(database: ISQLiteAnyDatabase): Promise<void>;
35
+ getColumnNamesAsync(): Promise<ISQLiteColumnNames>;
36
+ finalizeAsync(database: ISQLiteAnyDatabase): Promise<void>;
37
+ runSync(database: ISQLiteAnyDatabase, bindParams: ISQLiteBindPrimitiveParams, bindBlobParams: ISQLiteBindBlobParams, shouldPassAsArray: boolean): ISQLiteRunResult & {
38
+ firstRowValues: ISQLiteColumnValues;
39
+ };
40
+ stepSync(database: ISQLiteAnyDatabase): ISQLiteColumnValues | null | undefined;
41
+ getAllSync(database: ISQLiteAnyDatabase): ISQLiteColumnValues[];
42
+ resetSync(database: ISQLiteAnyDatabase): void;
43
+ getColumnNamesSync(): string[];
44
+ finalizeSync(database: ISQLiteAnyDatabase): void;
45
+ }
@@ -0,0 +1,7 @@
1
+ // Ported from expo-sqlite's NativeStatement.ts (.vendors/expo @ origin/sdk-57,
2
+ // packages/expo-sqlite/src/NativeStatement.ts), renamed with this repo's `I`-prefix convention.
3
+ //
4
+ // A plain native class, instantiated directly (`new ExpoSQLite.NativeStatement()`) and then
5
+ // mutated in place by `NativeDatabase.prepareAsync`/`prepareSync` — see `sqlite-database.ts`.
6
+ export {};
7
+ //# sourceMappingURL=native-statement.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"native-statement.js","sourceRoot":"","sources":["../../src/core/native-statement.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E,gGAAgG;AAChG,EAAE;AACF,4FAA4F;AAC5F,8FAA8F"}
@@ -0,0 +1,28 @@
1
+ import type { ISQLiteBindBlobParams, ISQLiteBindPrimitiveParams, ISQLiteColumnNames, ISQLiteColumnValues } from './native-statement';
2
+ /**
3
+ * Normalizes bind params into `[primitiveParams, blobParams, shouldPassAsArray]` for the
4
+ * native module. `params` is untyped because the public overloads
5
+ * (`ISQLiteBindParams` vs. variadic `ISQLiteVariadicBindParams`) already constrain what a
6
+ * type-checked caller can pass here — this only has to survive a caller that bypasses them.
7
+ * @hidden
8
+ */
9
+ export declare function normalizeParams(...params: unknown[]): [ISQLiteBindPrimitiveParams, ISQLiteBindBlobParams, boolean];
10
+ /**
11
+ * Composes `columnNames` and `columnValues` into a row object.
12
+ * @hidden
13
+ */
14
+ export declare function composeRow<T>(columnNames: ISQLiteColumnNames, columnValues: ISQLiteColumnValues): T;
15
+ /**
16
+ * Composes `columnNames` and `columnValuesList` into an array of row objects.
17
+ * @hidden
18
+ */
19
+ export declare function composeRows<T>(columnNames: ISQLiteColumnNames, columnValuesList: ISQLiteColumnValues[]): T[];
20
+ /**
21
+ * Normalizes the index for `SQLiteStorage.getKeyByIndexAsync`/`getKeyByIndexSync`. `index` is
22
+ * `unknown` (upstream types it `any`) because the function coerces defensively via `Number()` —
23
+ * a caller reaching this from untyped host data (e.g. a `web` `Storage` polyfill) may hand it
24
+ * anything.
25
+ * @returns The normalized index, or `null` when out of bounds.
26
+ * @hidden
27
+ */
28
+ export declare function normalizeStorageIndex(index: unknown): number | null;
@@ -0,0 +1,127 @@
1
+ function isPlainRecord(value) {
2
+ return typeof value === 'object' && value !== null && !Array.isArray(value);
3
+ }
4
+ /**
5
+ * Normalizes bind params into `[primitiveParams, blobParams, shouldPassAsArray]` for the
6
+ * native module. `params` is untyped because the public overloads
7
+ * (`ISQLiteBindParams` vs. variadic `ISQLiteVariadicBindParams`) already constrain what a
8
+ * type-checked caller can pass here — this only has to survive a caller that bypasses them.
9
+ * @hidden
10
+ */
11
+ export function normalizeParams(...params) {
12
+ const rawParams = params.length > 1 ? params : params[0];
13
+ let bindParams = rawParams ?? [];
14
+ if (typeof bindParams !== 'object' ||
15
+ bindParams === null ||
16
+ bindParams instanceof ArrayBuffer ||
17
+ ArrayBuffer.isView(bindParams)) {
18
+ bindParams = [bindParams];
19
+ }
20
+ const shouldPassAsArray = Array.isArray(bindParams);
21
+ const entries = Array.isArray(bindParams)
22
+ ? bindParams.map((value, index) => [
23
+ String(index),
24
+ value,
25
+ ])
26
+ : isPlainRecord(bindParams)
27
+ ? Object.entries(bindParams)
28
+ : [];
29
+ const primitiveParams = {};
30
+ const blobParams = {};
31
+ for (const [key, value] of entries) {
32
+ if (value instanceof Uint8Array || value instanceof ArrayBuffer) {
33
+ blobParams[key] = value;
34
+ }
35
+ else if (typeof value === 'boolean') {
36
+ primitiveParams[key] = value ? 1 : 0;
37
+ }
38
+ else if (value === null ||
39
+ typeof value === 'string' ||
40
+ typeof value === 'number') {
41
+ primitiveParams[key] = value;
42
+ }
43
+ else {
44
+ // Not a recognized ISQLiteBindValue at this point (undefined, an object, an array, a
45
+ // function...) — keep it as-is, matching upstream's `value ?? null`, which only guards
46
+ // null/undefined and otherwise passes the value through untouched. Binding an invalid
47
+ // value is the native bridge's problem at bind time; this function only reshapes params.
48
+ // I/O edge: `value` is genuinely unknown here — a caller that bypassed the public
49
+ // `ISQLiteBindParams` overloads is the only way to reach this branch.
50
+ primitiveParams[key] = (value ?? null);
51
+ }
52
+ }
53
+ return [primitiveParams, blobParams, shouldPassAsArray];
54
+ }
55
+ /**
56
+ * Composes `columnNames` and `columnValues` into a row object.
57
+ * @hidden
58
+ */
59
+ export function composeRow(columnNames, columnValues) {
60
+ const row = {};
61
+ if (columnNames.length !== columnValues.length) {
62
+ throw new Error(`Column names and values count mismatch. Names: ${columnNames.length}, Values: ${columnValues.length}`);
63
+ }
64
+ for (let i = 0; i < columnNames.length; i++) {
65
+ const columnName = columnNames[i];
66
+ if (columnName != null) {
67
+ row[columnName] = columnValues[i];
68
+ }
69
+ }
70
+ // I/O edge: T is the caller-specified row shape (SQLiteStatement.executeAsync<T>, etc.) — the
71
+ // native bridge has no way to describe it, so it is asserted here, at the narrowest point
72
+ // native data enters the type system.
73
+ return row;
74
+ }
75
+ /**
76
+ * Composes `columnNames` and `columnValuesList` into an array of row objects.
77
+ * @hidden
78
+ */
79
+ export function composeRows(columnNames, columnValuesList) {
80
+ const firstRow = columnValuesList[0];
81
+ if (firstRow == null) {
82
+ return [];
83
+ }
84
+ if (columnNames.length !== firstRow.length) {
85
+ // Only the first row is checked — SQLite returns the same column count for every row. A
86
+ // shorter LATER row is not an error case (unlike composeRow's own check, which this
87
+ // deliberately does NOT delegate to) — a missing trailing value just composes as
88
+ // `undefined`, matching upstream's inline (non-composeRow) row construction here.
89
+ throw new Error(`Column names and values count mismatch. Names: ${columnNames.length}, Values: ${firstRow.length}`);
90
+ }
91
+ const results = [];
92
+ for (const columnValues of columnValuesList) {
93
+ const row = {};
94
+ for (let i = 0; i < columnNames.length; i++) {
95
+ const columnName = columnNames[i];
96
+ if (columnName != null) {
97
+ row[columnName] = columnValues[i];
98
+ }
99
+ }
100
+ // I/O edge, same as composeRow above.
101
+ results.push(row);
102
+ }
103
+ return results;
104
+ }
105
+ /**
106
+ * Normalizes the index for `SQLiteStorage.getKeyByIndexAsync`/`getKeyByIndexSync`. `index` is
107
+ * `unknown` (upstream types it `any`) because the function coerces defensively via `Number()` —
108
+ * a caller reaching this from untyped host data (e.g. a `web` `Storage` polyfill) may hand it
109
+ * anything.
110
+ * @returns The normalized index, or `null` when out of bounds.
111
+ * @hidden
112
+ */
113
+ export function normalizeStorageIndex(index) {
114
+ const value = Math.floor(Number(index));
115
+ if (Object.is(value, -0)) {
116
+ return 0;
117
+ }
118
+ if (!Number.isSafeInteger(value)) {
119
+ // Chromium uses a zero index when the index is out of bounds.
120
+ return 0;
121
+ }
122
+ if (value < 0) {
123
+ return null;
124
+ }
125
+ return value;
126
+ }
127
+ //# sourceMappingURL=param-utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"param-utils.js","sourceRoot":"","sources":["../../src/core/param-utils.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Creates a normalized database path by combining the directory and database name — no
3
+ * trailing slash on the directory, no leading slash on the name, so the join never doubles up.
4
+ */
5
+ export declare function createDatabasePath(databaseName: string, directory?: string): string;
6
+ export declare function basename(path: string): string;
@@ -0,0 +1,30 @@
1
+ // Ported verbatim (logic unchanged) from expo-sqlite's pathUtils.ts (.vendors/expo @
2
+ // origin/sdk-57, packages/expo-sqlite/src/pathUtils.ts).
3
+ import { expoSQLite } from './native-module';
4
+ function resolveDbDirectory(directory) {
5
+ const resolvedDirectory = directory ?? expoSQLite.defaultDatabaseDirectory;
6
+ if (resolvedDirectory == null) {
7
+ throw new Error('Both provided directory and defaultDatabaseDirectory are null.');
8
+ }
9
+ return resolvedDirectory;
10
+ }
11
+ /**
12
+ * Creates a normalized database path by combining the directory and database name — no
13
+ * trailing slash on the directory, no leading slash on the name, so the join never doubles up.
14
+ */
15
+ export function createDatabasePath(databaseName, directory) {
16
+ if (databaseName === ':memory:')
17
+ return databaseName;
18
+ const resolvedDirectory = resolveDbDirectory(directory);
19
+ function removeTrailingSlash(path) {
20
+ return path.replace(/\/*$/, '');
21
+ }
22
+ function removeLeadingSlash(path) {
23
+ return path.replace(/^\/+/, '');
24
+ }
25
+ return `${removeTrailingSlash(resolvedDirectory)}/${removeLeadingSlash(databaseName)}`;
26
+ }
27
+ export function basename(path) {
28
+ return path.substring(path.lastIndexOf('/') + 1);
29
+ }
30
+ //# sourceMappingURL=path-utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"path-utils.js","sourceRoot":"","sources":["../../src/core/path-utils.ts"],"names":[],"mappings":"AAAA,qFAAqF;AACrF,yDAAyD;AACzD,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAE7C,SAAS,kBAAkB,CAAC,SAA6B;IACvD,MAAM,iBAAiB,GAAG,SAAS,IAAI,UAAU,CAAC,wBAAwB,CAAC;IAC3E,IAAI,iBAAiB,IAAI,IAAI,EAAE,CAAC;QAC9B,MAAM,IAAI,KAAK,CACb,gEAAgE,CACjE,CAAC;IACJ,CAAC;IACD,OAAO,iBAAiB,CAAC;AAC3B,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,kBAAkB,CAChC,YAAoB,EACpB,SAAkB;IAElB,IAAI,YAAY,KAAK,UAAU;QAAE,OAAO,YAAY,CAAC;IACrD,MAAM,iBAAiB,GAAG,kBAAkB,CAAC,SAAS,CAAC,CAAC;IAExD,SAAS,mBAAmB,CAAC,IAAY;QACvC,OAAO,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IAClC,CAAC;IACD,SAAS,kBAAkB,CAAC,IAAY;QACtC,OAAO,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IAClC,CAAC;IAED,OAAO,GAAG,mBAAmB,CAAC,iBAAiB,CAAC,IAAI,kBAAkB,CAAC,YAAY,CAAC,EAAE,CAAC;AACzF,CAAC;AAED,MAAM,UAAU,QAAQ,CAAC,IAAY;IACnC,OAAO,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;AACnD,CAAC"}
@@ -0,0 +1,17 @@
1
+ /** Information about a parsed SQL query. */
2
+ export type ISQLParsedInfo = {
3
+ canReturnRows: boolean;
4
+ };
5
+ /**
6
+ * Parses a SQL query to determine whether it can return rows, using a priority-based approach:
7
+ * `RETURNING` always returns rows; a bare mutation keyword never does; a query keyword does;
8
+ * anything else does not.
9
+ *
10
+ * @example
11
+ * ```ts
12
+ * parseSQLQuery('SELECT * FROM users') // { canReturnRows: true }
13
+ * parseSQLQuery('INSERT INTO users VALUES (1)') // { canReturnRows: false }
14
+ * parseSQLQuery('INSERT INTO users VALUES (1) RETURNING *') // { canReturnRows: true }
15
+ * ```
16
+ */
17
+ export declare function parseSQLQuery(query: string): ISQLParsedInfo;
@@ -0,0 +1,38 @@
1
+ // Ported verbatim (logic unchanged) from expo-sqlite's queryUtils.ts (.vendors/expo @
2
+ // origin/sdk-57, packages/expo-sqlite/src/queryUtils.ts), renamed with this repo's `I`-prefix
3
+ // convention. A reimplementation of Bun's SQLite query parser (credited upstream).
4
+ const SINGLE_QUOTED_STRING = /'(?:[^']|'')*'/g;
5
+ const DOUBLE_QUOTED_STRING = /"(?:[^"]|"")*"/g;
6
+ const RETURNING_KEYWORD = /\bRETURNING\b/i;
7
+ const MUTATION_KEYWORDS = /\b(INSERT|UPDATE|DELETE|CREATE|ALTER|DROP)\b/i;
8
+ const QUERY_KEYWORDS = /\b(SELECT|PRAGMA|WITH|EXPLAIN)\b/i;
9
+ /**
10
+ * Parses a SQL query to determine whether it can return rows, using a priority-based approach:
11
+ * `RETURNING` always returns rows; a bare mutation keyword never does; a query keyword does;
12
+ * anything else does not.
13
+ *
14
+ * @example
15
+ * ```ts
16
+ * parseSQLQuery('SELECT * FROM users') // { canReturnRows: true }
17
+ * parseSQLQuery('INSERT INTO users VALUES (1)') // { canReturnRows: false }
18
+ * parseSQLQuery('INSERT INTO users VALUES (1) RETURNING *') // { canReturnRows: true }
19
+ * ```
20
+ */
21
+ export function parseSQLQuery(query) {
22
+ // SQLite doubles quotes to escape them ('don''t', "test""quote") — strip quoted strings first
23
+ // so a keyword INSIDE a string literal can't produce a false positive.
24
+ const cleaned = query
25
+ .replace(SINGLE_QUOTED_STRING, "''")
26
+ .replace(DOUBLE_QUOTED_STRING, '""');
27
+ if (RETURNING_KEYWORD.test(cleaned)) {
28
+ return { canReturnRows: true };
29
+ }
30
+ if (MUTATION_KEYWORDS.test(cleaned)) {
31
+ return { canReturnRows: false };
32
+ }
33
+ if (QUERY_KEYWORDS.test(cleaned)) {
34
+ return { canReturnRows: true };
35
+ }
36
+ return { canReturnRows: false };
37
+ }
38
+ //# sourceMappingURL=query-utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"query-utils.js","sourceRoot":"","sources":["../../src/core/query-utils.ts"],"names":[],"mappings":"AAAA,sFAAsF;AACtF,8FAA8F;AAC9F,mFAAmF;AAOnF,MAAM,oBAAoB,GAAG,iBAAiB,CAAC;AAC/C,MAAM,oBAAoB,GAAG,iBAAiB,CAAC;AAC/C,MAAM,iBAAiB,GAAG,gBAAgB,CAAC;AAC3C,MAAM,iBAAiB,GAAG,+CAA+C,CAAC;AAC1E,MAAM,cAAc,GAAG,mCAAmC,CAAC;AAE3D;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,aAAa,CAAC,KAAa;IACzC,8FAA8F;IAC9F,uEAAuE;IACvE,MAAM,OAAO,GAAG,KAAK;SAClB,OAAO,CAAC,oBAAoB,EAAE,IAAI,CAAC;SACnC,OAAO,CAAC,oBAAoB,EAAE,IAAI,CAAC,CAAC;IAEvC,IAAI,iBAAiB,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;QACpC,OAAO,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC;IACjC,CAAC;IACD,IAAI,iBAAiB,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;QACpC,OAAO,EAAE,aAAa,EAAE,KAAK,EAAE,CAAC;IAClC,CAAC;IACD,IAAI,cAAc,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;QACjC,OAAO,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC;IACjC,CAAC;IACD,OAAO,EAAE,aAAa,EAAE,KAAK,EAAE,CAAC;AAClC,CAAC"}