@rocicorp/zero 0.24.2025093001 → 0.24.2025100800

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 (55) hide show
  1. package/out/{chunk-QCPDXNFF.js → chunk-ASFIXQH7.js} +2 -4
  2. package/out/chunk-ASFIXQH7.js.map +7 -0
  3. package/out/{chunk-L2ZHMO4E.js → chunk-QROPZW7G.js} +2 -2
  4. package/out/chunk-X7SAVR5O.js +220 -0
  5. package/out/chunk-X7SAVR5O.js.map +7 -0
  6. package/out/react-native.js +5 -208
  7. package/out/react-native.js.map +3 -3
  8. package/out/react.js +1 -1
  9. package/out/replicache/src/sqlite.d.ts +3 -0
  10. package/out/replicache/src/sqlite.d.ts.map +1 -0
  11. package/out/solid.js +2 -2
  12. package/out/sqlite.js +14 -0
  13. package/out/sqlite.js.map +7 -0
  14. package/out/zero/package.json +14 -10
  15. package/out/zero/src/adapters/drizzle.d.ts +2 -0
  16. package/out/zero/src/adapters/drizzle.d.ts.map +1 -0
  17. package/out/zero/src/adapters/drizzle.js +2 -0
  18. package/out/zero/src/adapters/drizzle.js.map +1 -0
  19. package/out/zero/src/adapters/pg.d.ts +2 -0
  20. package/out/zero/src/adapters/pg.d.ts.map +1 -0
  21. package/out/zero/src/adapters/pg.js +2 -0
  22. package/out/zero/src/adapters/pg.js.map +1 -0
  23. package/out/zero/src/sqlite.d.ts +2 -0
  24. package/out/zero/src/sqlite.d.ts.map +1 -0
  25. package/out/zero/src/zero-cache-dev.js +10 -4
  26. package/out/zero/src/zero-cache-dev.js.map +1 -1
  27. package/out/zero-cache/src/scripts/deploy-permissions.js +1 -1
  28. package/out/zero-cache/src/services/change-source/pg/logical-replication/stream.d.ts.map +1 -1
  29. package/out/zero-cache/src/services/change-source/pg/logical-replication/stream.js +15 -14
  30. package/out/zero-cache/src/services/change-source/pg/logical-replication/stream.js.map +1 -1
  31. package/out/zero-client/src/client/zero.d.ts.map +1 -1
  32. package/out/zero-server/src/adapters/drizzle.d.ts +64 -0
  33. package/out/zero-server/src/adapters/drizzle.d.ts.map +1 -0
  34. package/out/zero-server/src/adapters/drizzle.js +109 -0
  35. package/out/zero-server/src/adapters/drizzle.js.map +1 -0
  36. package/out/zero-server/src/adapters/pg.d.ts +53 -0
  37. package/out/zero-server/src/adapters/pg.d.ts.map +1 -0
  38. package/out/zero-server/src/adapters/pg.js +79 -0
  39. package/out/zero-server/src/adapters/pg.js.map +1 -0
  40. package/out/zero-server/src/adapters/postgresjs.d.ts +41 -12
  41. package/out/zero-server/src/adapters/postgresjs.d.ts.map +1 -1
  42. package/out/zero-server/src/adapters/postgresjs.js +27 -10
  43. package/out/zero-server/src/adapters/postgresjs.js.map +1 -1
  44. package/out/zero.js +2 -2
  45. package/package.json +14 -10
  46. package/out/chunk-QCPDXNFF.js.map +0 -7
  47. package/out/zero/src/adapters/drizzle-pg.d.ts +0 -2
  48. package/out/zero/src/adapters/drizzle-pg.d.ts.map +0 -1
  49. package/out/zero/src/adapters/drizzle-pg.js +0 -2
  50. package/out/zero/src/adapters/drizzle-pg.js.map +0 -1
  51. package/out/zero-server/src/adapters/drizzle-pg.d.ts +0 -22
  52. package/out/zero-server/src/adapters/drizzle-pg.d.ts.map +0 -1
  53. package/out/zero-server/src/adapters/drizzle-pg.js +0 -39
  54. package/out/zero-server/src/adapters/drizzle-pg.js.map +0 -1
  55. /package/out/{chunk-L2ZHMO4E.js.map → chunk-QROPZW7G.js.map} +0 -0
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  clientToServer
3
- } from "./chunk-QCPDXNFF.js";
3
+ } from "./chunk-ASFIXQH7.js";
4
4
  import {
5
5
  AbstractQuery,
6
6
  ExpressionBuilder,
@@ -346,4 +346,4 @@ export {
346
346
  withValidation,
347
347
  createBuilder
348
348
  };
349
- //# sourceMappingURL=chunk-L2ZHMO4E.js.map
349
+ //# sourceMappingURL=chunk-QROPZW7G.js.map
@@ -0,0 +1,220 @@
1
+ import {
2
+ throwIfStoreClosed,
3
+ throwIfTransactionClosed
4
+ } from "./chunk-ASRS2LFV.js";
5
+ import {
6
+ deepFreeze
7
+ } from "./chunk-SGW2EIVJ.js";
8
+
9
+ // ../replicache/src/kv/sqlite-store.ts
10
+ import { RWLock } from "@rocicorp/lock";
11
+ var SQLiteStore = class {
12
+ #filename;
13
+ #entry;
14
+ #closed = false;
15
+ constructor(name, create, opts) {
16
+ this.#filename = safeFilename(name);
17
+ this.#entry = getOrCreateEntry(name, create, opts);
18
+ }
19
+ async read() {
20
+ throwIfStoreClosed(this);
21
+ const entry = this.#entry;
22
+ const { db, lock, preparedStatements } = entry;
23
+ const release = await lock.read();
24
+ if (entry.activeReaders === 0) {
25
+ db.execSync("BEGIN");
26
+ }
27
+ entry.activeReaders++;
28
+ return new SQLiteStoreRead(() => {
29
+ entry.activeReaders--;
30
+ if (entry.activeReaders === 0) {
31
+ db.execSync("COMMIT");
32
+ }
33
+ release();
34
+ }, preparedStatements);
35
+ }
36
+ async write() {
37
+ throwIfStoreClosed(this);
38
+ const { lock, db, preparedStatements } = this.#entry;
39
+ const release = await lock.write();
40
+ db.execSync("BEGIN IMMEDIATE");
41
+ return new SQLiteWrite(release, db, preparedStatements);
42
+ }
43
+ async close() {
44
+ if (this.#closed) {
45
+ return;
46
+ }
47
+ const { lock, db } = this.#entry;
48
+ const writeRelease = await lock.write();
49
+ decrementStoreRefCount(this.#filename, db);
50
+ this.#closed = true;
51
+ writeRelease();
52
+ }
53
+ get closed() {
54
+ return this.#closed;
55
+ }
56
+ };
57
+ function safeFilename(name) {
58
+ return name.replace(/[^a-zA-Z0-9]/g, "_");
59
+ }
60
+ function setupDatabase(delegate, opts) {
61
+ delegate.execSync(`PRAGMA busy_timeout = ${opts?.busyTimeout ?? 200}`);
62
+ delegate.execSync(`PRAGMA journal_mode = '${opts?.journalMode ?? "WAL"}'`);
63
+ delegate.execSync(`PRAGMA synchronous = '${opts?.synchronous ?? "NORMAL"}'`);
64
+ delegate.execSync(
65
+ `PRAGMA read_uncommitted = ${Boolean(opts?.readUncommitted)}`
66
+ );
67
+ delegate.execSync(`
68
+ CREATE TABLE IF NOT EXISTS entry (
69
+ key TEXT PRIMARY KEY,
70
+ value TEXT NOT NULL
71
+ ) WITHOUT ROWID
72
+ `);
73
+ return {
74
+ has: delegate.prepare(`SELECT 1 FROM entry WHERE key = ? LIMIT 1`),
75
+ get: delegate.prepare("SELECT value FROM entry WHERE key = ?"),
76
+ put: delegate.prepare(
77
+ "INSERT OR REPLACE INTO entry (key, value) VALUES (?, ?)"
78
+ ),
79
+ del: delegate.prepare("DELETE FROM entry WHERE key = ?")
80
+ };
81
+ }
82
+ var SQLiteStoreRead = class {
83
+ #release;
84
+ #closed = false;
85
+ #preparedStatements;
86
+ constructor(release, preparedStatements) {
87
+ this.#release = release;
88
+ this.#preparedStatements = preparedStatements;
89
+ }
90
+ async has(key) {
91
+ throwIfTransactionClosed(this);
92
+ const value = await this.#preparedStatements.has.firstValue([key]);
93
+ return value !== void 0;
94
+ }
95
+ async get(key) {
96
+ throwIfTransactionClosed(this);
97
+ const value = await this.#preparedStatements.get.firstValue([key]);
98
+ if (!value) {
99
+ return void 0;
100
+ }
101
+ const parsedValue = JSON.parse(value);
102
+ return deepFreeze(parsedValue);
103
+ }
104
+ release() {
105
+ if (!this.#closed) {
106
+ this.#closed = true;
107
+ this.#release();
108
+ }
109
+ }
110
+ get closed() {
111
+ return this.#closed;
112
+ }
113
+ };
114
+ var SQLiteWrite = class {
115
+ #release;
116
+ #dbDelegate;
117
+ #preparedStatements;
118
+ #committed = false;
119
+ #closed = false;
120
+ constructor(release, dbDelegate, preparedStatements) {
121
+ this.#release = release;
122
+ this.#dbDelegate = dbDelegate;
123
+ this.#preparedStatements = preparedStatements;
124
+ }
125
+ async has(key) {
126
+ throwIfTransactionClosed(this);
127
+ const value = await this.#preparedStatements.has.firstValue([key]);
128
+ return value !== void 0;
129
+ }
130
+ async get(key) {
131
+ throwIfTransactionClosed(this);
132
+ const value = await this.#preparedStatements.get.firstValue([key]);
133
+ if (!value) {
134
+ return void 0;
135
+ }
136
+ const parsedValue = JSON.parse(value);
137
+ return deepFreeze(parsedValue);
138
+ }
139
+ async put(key, value) {
140
+ throwIfTransactionClosed(this);
141
+ await this.#preparedStatements.put.exec([key, JSON.stringify(value)]);
142
+ }
143
+ async del(key) {
144
+ throwIfTransactionClosed(this);
145
+ await this.#preparedStatements.del.exec([key]);
146
+ }
147
+ // eslint-disable-next-line require-await
148
+ async commit() {
149
+ throwIfTransactionClosed(this);
150
+ this.#dbDelegate.execSync("COMMIT");
151
+ this.#committed = true;
152
+ }
153
+ release() {
154
+ if (!this.#closed) {
155
+ this.#closed = true;
156
+ if (!this.#committed) {
157
+ this.#dbDelegate.execSync("ROLLBACK");
158
+ }
159
+ this.#release();
160
+ }
161
+ }
162
+ get closed() {
163
+ return this.#closed;
164
+ }
165
+ };
166
+ var stores = /* @__PURE__ */ new Map();
167
+ function getOrCreateEntry(name, create, opts) {
168
+ const filename = safeFilename(name);
169
+ const entry = stores.get(filename);
170
+ if (entry) {
171
+ entry.refCount++;
172
+ return entry;
173
+ }
174
+ const dbDelegate = create(filename, opts);
175
+ const preparedStatements = setupDatabase(dbDelegate, opts);
176
+ const lock = new RWLock();
177
+ const newEntry = {
178
+ lock,
179
+ db: dbDelegate,
180
+ refCount: 1,
181
+ activeReaders: 0,
182
+ preparedStatements
183
+ };
184
+ stores.set(filename, newEntry);
185
+ return newEntry;
186
+ }
187
+ function decrementStoreRefCount(filename, dbDelegate) {
188
+ const entry = stores.get(filename);
189
+ if (entry) {
190
+ entry.refCount--;
191
+ if (entry.refCount <= 0) {
192
+ dbDelegate.close();
193
+ stores.delete(filename);
194
+ }
195
+ }
196
+ }
197
+ function clearAllNamedStoresForTesting() {
198
+ for (const entry of stores.values()) {
199
+ entry.db.close();
200
+ }
201
+ stores.clear();
202
+ }
203
+ function dropStore(name, createDelegate) {
204
+ const filename = safeFilename(name);
205
+ const entry = stores.get(filename);
206
+ if (entry) {
207
+ entry.db.close();
208
+ stores.delete(filename);
209
+ }
210
+ const tempDelegate = createDelegate(filename);
211
+ tempDelegate.destroy();
212
+ return Promise.resolve();
213
+ }
214
+
215
+ export {
216
+ SQLiteStore,
217
+ clearAllNamedStoresForTesting,
218
+ dropStore
219
+ };
220
+ //# sourceMappingURL=chunk-X7SAVR5O.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../replicache/src/kv/sqlite-store.ts"],
4
+ "sourcesContent": ["import {RWLock} from '@rocicorp/lock';\nimport type {ReadonlyJSONValue} from '../../../shared/src/json.ts';\nimport {deepFreeze} from '../frozen-json.ts';\nimport type {Read, Store, Write} from './store.ts';\nimport {\n throwIfStoreClosed,\n throwIfTransactionClosed,\n} from './throw-if-closed.ts';\n\n/**\n * A SQLite prepared statement.\n *\n * `run` executes the statement with optional parameters.\n * `all` executes the statement and returns the result rows.\n * `finalize` releases the statement.\n */\nexport interface PreparedStatement {\n firstValue(params: string[]): Promise<unknown>;\n exec(params: string[]): Promise<void>;\n}\n\nexport interface SQLiteDatabase {\n /**\n * Close the database connection.\n */\n close(): void;\n\n /**\n * Destroy or delete the database (e.g. delete file).\n */\n destroy(): void;\n\n /**\n * Prepare a SQL string, returning a statement you can execute.\n * E.g. `const stmt = db.prepare(\"SELECT * FROM todos WHERE id=?\");`\n */\n prepare(sql: string): PreparedStatement;\n\n // for PRAGMA statements, schema creation and transaction control.\n execSync(sql: string): void;\n}\n\nexport type CreateSQLiteDatabase = (\n filename: string,\n opts?: SQLiteStoreOptions,\n) => SQLiteDatabase;\n\n/**\n * SQLite-based implementation of the Store interface using a configurable delegate.\n * Supports shared connections between multiple store instances with the same name,\n * providing efficient resource utilization and proper transaction isolation.\n * Uses parameterized queries for safety and performance.\n */\nexport class SQLiteStore implements Store {\n readonly #filename: string;\n readonly #entry: StoreEntry;\n\n #closed = false;\n\n constructor(\n name: string,\n create: CreateSQLiteDatabase,\n opts?: SQLiteStoreOptions,\n ) {\n this.#filename = safeFilename(name);\n this.#entry = getOrCreateEntry(name, create, opts);\n }\n\n async read(): Promise<Read> {\n throwIfStoreClosed(this);\n\n const entry = this.#entry;\n const {db, lock, preparedStatements} = entry;\n const release = await lock.read();\n\n // Start shared read transaction if this is the first reader\n // This ensures consistent reads across all concurrent readers\n if (entry.activeReaders === 0) {\n db.execSync('BEGIN');\n }\n entry.activeReaders++;\n\n return new SQLiteStoreRead(() => {\n entry.activeReaders--;\n // Commit shared read transaction when last reader finishes\n if (entry.activeReaders === 0) {\n db.execSync('COMMIT');\n }\n release();\n }, preparedStatements);\n }\n\n async write(): Promise<Write> {\n throwIfStoreClosed(this);\n\n const {lock, db, preparedStatements} = this.#entry;\n const release = await lock.write();\n\n // At this point, RWLock guarantees no active readers\n // The last reader would have already committed the shared transaction\n\n db.execSync('BEGIN IMMEDIATE');\n\n return new SQLiteWrite(release, db, preparedStatements);\n }\n\n async close(): Promise<void> {\n if (this.#closed) {\n return;\n }\n\n const {lock, db} = this.#entry;\n // Wait for all readers and writers to finish.\n const writeRelease = await lock.write();\n\n // Handle reference counting for shared stores - only close database\n // when this is the last store instance using it\n decrementStoreRefCount(this.#filename, db);\n\n this.#closed = true;\n writeRelease();\n }\n\n get closed(): boolean {\n return this.#closed;\n }\n}\n\nexport function safeFilename(name: string): string {\n return name.replace(/[^a-zA-Z0-9]/g, '_');\n}\n\nexport type PreparedStatements = {\n has: PreparedStatement;\n get: PreparedStatement;\n put: PreparedStatement;\n del: PreparedStatement;\n};\n\nexport interface SQLiteStoreOptions {\n // Common options\n busyTimeout?: number;\n journalMode?: 'WAL' | 'DELETE';\n synchronous?: 'NORMAL' | 'FULL';\n readUncommitted?: boolean;\n}\n\n/**\n * Common database setup logic shared between expo-sqlite and op-sqlite implementations.\n * Configures SQLite pragmas, creates the entry table, and prepares common statements.\n */\n\nexport function setupDatabase(\n delegate: SQLiteDatabase,\n opts?: SQLiteStoreOptions,\n): PreparedStatements {\n // Configure SQLite pragmas for optimal performance\n delegate.execSync(`PRAGMA busy_timeout = ${opts?.busyTimeout ?? 200}`);\n delegate.execSync(`PRAGMA journal_mode = '${opts?.journalMode ?? 'WAL'}'`);\n delegate.execSync(`PRAGMA synchronous = '${opts?.synchronous ?? 'NORMAL'}'`);\n delegate.execSync(\n `PRAGMA read_uncommitted = ${Boolean(opts?.readUncommitted)}`,\n );\n\n // Create the entry table\n delegate.execSync(`\n CREATE TABLE IF NOT EXISTS entry (\n key TEXT PRIMARY KEY, \n value TEXT NOT NULL\n ) WITHOUT ROWID\n `);\n\n // Prepare common statements\n return {\n has: delegate.prepare(`SELECT 1 FROM entry WHERE key = ? LIMIT 1`),\n get: delegate.prepare('SELECT value FROM entry WHERE key = ?'),\n put: delegate.prepare(\n 'INSERT OR REPLACE INTO entry (key, value) VALUES (?, ?)',\n ),\n del: delegate.prepare('DELETE FROM entry WHERE key = ?'),\n };\n}\n\nexport class SQLiteStoreRead implements Read {\n #release: () => void;\n #closed = false;\n #preparedStatements: PreparedStatements;\n\n constructor(release: () => void, preparedStatements: PreparedStatements) {\n this.#release = release;\n this.#preparedStatements = preparedStatements;\n }\n\n async has(key: string): Promise<boolean> {\n throwIfTransactionClosed(this);\n const value = await this.#preparedStatements.has.firstValue([key]);\n return value !== undefined;\n }\n\n async get(key: string): Promise<ReadonlyJSONValue | undefined> {\n throwIfTransactionClosed(this);\n const value = await this.#preparedStatements.get.firstValue([key]);\n if (!value) {\n return undefined;\n }\n\n const parsedValue = JSON.parse(value as string) as ReadonlyJSONValue;\n return deepFreeze(parsedValue);\n }\n\n release(): void {\n if (!this.#closed) {\n this.#closed = true;\n this.#release();\n }\n }\n\n get closed(): boolean {\n return this.#closed;\n }\n}\n\nexport class SQLiteWrite implements Write {\n readonly #release: () => void;\n readonly #dbDelegate: SQLiteDatabase;\n readonly #preparedStatements: PreparedStatements;\n #committed = false;\n #closed = false;\n\n constructor(\n release: () => void,\n dbDelegate: SQLiteDatabase,\n preparedStatements: PreparedStatements,\n ) {\n this.#release = release;\n this.#dbDelegate = dbDelegate;\n this.#preparedStatements = preparedStatements;\n }\n\n async has(key: string): Promise<boolean> {\n throwIfTransactionClosed(this);\n const value = await this.#preparedStatements.has.firstValue([key]);\n return value !== undefined;\n }\n\n async get(key: string): Promise<ReadonlyJSONValue | undefined> {\n throwIfTransactionClosed(this);\n const value = await this.#preparedStatements.get.firstValue([key]);\n if (!value) {\n return undefined;\n }\n\n const parsedValue = JSON.parse(value as string) as ReadonlyJSONValue;\n return deepFreeze(parsedValue);\n }\n\n async put(key: string, value: ReadonlyJSONValue): Promise<void> {\n throwIfTransactionClosed(this);\n await this.#preparedStatements.put.exec([key, JSON.stringify(value)]);\n }\n\n async del(key: string): Promise<void> {\n throwIfTransactionClosed(this);\n await this.#preparedStatements.del.exec([key]);\n }\n\n // eslint-disable-next-line require-await\n async commit(): Promise<void> {\n throwIfTransactionClosed(this);\n this.#dbDelegate.execSync('COMMIT');\n this.#committed = true;\n }\n\n release(): void {\n if (!this.#closed) {\n this.#closed = true;\n\n if (!this.#committed) {\n this.#dbDelegate.execSync('ROLLBACK');\n }\n\n this.#release();\n }\n }\n\n get closed(): boolean {\n return this.#closed;\n }\n}\n\ntype StoreEntry = {\n readonly lock: RWLock;\n readonly db: SQLiteDatabase;\n refCount: number;\n activeReaders: number;\n preparedStatements: PreparedStatements;\n};\n\n// Global map to share database connections between multiple store instances with the same name\nconst stores = new Map<string, StoreEntry>();\n\n/**\n * Gets an existing store entry or creates a new one if it doesn't exist.\n * This implements the shared connection pattern where multiple stores with the same\n * name share the same database connection, lock, and delegate.\n */\nfunction getOrCreateEntry(\n name: string,\n create: (filename: string, opts?: SQLiteStoreOptions) => SQLiteDatabase,\n opts?: SQLiteStoreOptions,\n): StoreEntry {\n const filename = safeFilename(name);\n const entry = stores.get(filename);\n\n if (entry) {\n entry.refCount++;\n return entry;\n }\n\n const dbDelegate = create(filename, opts);\n const preparedStatements = setupDatabase(dbDelegate, opts);\n\n const lock = new RWLock();\n\n const newEntry: StoreEntry = {\n lock,\n db: dbDelegate,\n refCount: 1,\n activeReaders: 0,\n preparedStatements,\n };\n stores.set(filename, newEntry);\n return newEntry;\n}\n\n/**\n * Decrements the reference count for a shared store and cleans up resources\n * when the last reference is released.\n */\n\nfunction decrementStoreRefCount(\n filename: string,\n dbDelegate: SQLiteDatabase,\n): void {\n const entry = stores.get(filename);\n if (entry) {\n entry.refCount--;\n if (entry.refCount <= 0) {\n dbDelegate.close();\n stores.delete(filename);\n }\n }\n}\nexport function clearAllNamedStoresForTesting(): void {\n for (const entry of stores.values()) {\n entry.db.close();\n }\n stores.clear();\n}\n\nexport function dropStore(\n name: string,\n createDelegate: (\n filename: string,\n opts?: SQLiteStoreOptions,\n ) => SQLiteDatabase,\n): Promise<void> {\n const filename = safeFilename(name);\n const entry = stores.get(filename);\n if (entry) {\n entry.db.close();\n stores.delete(filename);\n }\n\n // Create a temporary delegate to handle database deletion\n const tempDelegate = createDelegate(filename);\n tempDelegate.destroy();\n\n return Promise.resolve();\n}\n"],
5
+ "mappings": ";;;;;;;;;AAAA,SAAQ,cAAa;AAqDd,IAAM,cAAN,MAAmC;AAAA,EAC/B;AAAA,EACA;AAAA,EAET,UAAU;AAAA,EAEV,YACE,MACA,QACA,MACA;AACA,SAAK,YAAY,aAAa,IAAI;AAClC,SAAK,SAAS,iBAAiB,MAAM,QAAQ,IAAI;AAAA,EACnD;AAAA,EAEA,MAAM,OAAsB;AAC1B,uBAAmB,IAAI;AAEvB,UAAM,QAAQ,KAAK;AACnB,UAAM,EAAC,IAAI,MAAM,mBAAkB,IAAI;AACvC,UAAM,UAAU,MAAM,KAAK,KAAK;AAIhC,QAAI,MAAM,kBAAkB,GAAG;AAC7B,SAAG,SAAS,OAAO;AAAA,IACrB;AACA,UAAM;AAEN,WAAO,IAAI,gBAAgB,MAAM;AAC/B,YAAM;AAEN,UAAI,MAAM,kBAAkB,GAAG;AAC7B,WAAG,SAAS,QAAQ;AAAA,MACtB;AACA,cAAQ;AAAA,IACV,GAAG,kBAAkB;AAAA,EACvB;AAAA,EAEA,MAAM,QAAwB;AAC5B,uBAAmB,IAAI;AAEvB,UAAM,EAAC,MAAM,IAAI,mBAAkB,IAAI,KAAK;AAC5C,UAAM,UAAU,MAAM,KAAK,MAAM;AAKjC,OAAG,SAAS,iBAAiB;AAE7B,WAAO,IAAI,YAAY,SAAS,IAAI,kBAAkB;AAAA,EACxD;AAAA,EAEA,MAAM,QAAuB;AAC3B,QAAI,KAAK,SAAS;AAChB;AAAA,IACF;AAEA,UAAM,EAAC,MAAM,GAAE,IAAI,KAAK;AAExB,UAAM,eAAe,MAAM,KAAK,MAAM;AAItC,2BAAuB,KAAK,WAAW,EAAE;AAEzC,SAAK,UAAU;AACf,iBAAa;AAAA,EACf;AAAA,EAEA,IAAI,SAAkB;AACpB,WAAO,KAAK;AAAA,EACd;AACF;AAEO,SAAS,aAAa,MAAsB;AACjD,SAAO,KAAK,QAAQ,iBAAiB,GAAG;AAC1C;AAsBO,SAAS,cACd,UACA,MACoB;AAEpB,WAAS,SAAS,yBAAyB,MAAM,eAAe,GAAG,EAAE;AACrE,WAAS,SAAS,0BAA0B,MAAM,eAAe,KAAK,GAAG;AACzE,WAAS,SAAS,yBAAyB,MAAM,eAAe,QAAQ,GAAG;AAC3E,WAAS;AAAA,IACP,6BAA6B,QAAQ,MAAM,eAAe,CAAC;AAAA,EAC7D;AAGA,WAAS,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA,GAKjB;AAGD,SAAO;AAAA,IACL,KAAK,SAAS,QAAQ,2CAA2C;AAAA,IACjE,KAAK,SAAS,QAAQ,uCAAuC;AAAA,IAC7D,KAAK,SAAS;AAAA,MACZ;AAAA,IACF;AAAA,IACA,KAAK,SAAS,QAAQ,iCAAiC;AAAA,EACzD;AACF;AAEO,IAAM,kBAAN,MAAsC;AAAA,EAC3C;AAAA,EACA,UAAU;AAAA,EACV;AAAA,EAEA,YAAY,SAAqB,oBAAwC;AACvE,SAAK,WAAW;AAChB,SAAK,sBAAsB;AAAA,EAC7B;AAAA,EAEA,MAAM,IAAI,KAA+B;AACvC,6BAAyB,IAAI;AAC7B,UAAM,QAAQ,MAAM,KAAK,oBAAoB,IAAI,WAAW,CAAC,GAAG,CAAC;AACjE,WAAO,UAAU;AAAA,EACnB;AAAA,EAEA,MAAM,IAAI,KAAqD;AAC7D,6BAAyB,IAAI;AAC7B,UAAM,QAAQ,MAAM,KAAK,oBAAoB,IAAI,WAAW,CAAC,GAAG,CAAC;AACjE,QAAI,CAAC,OAAO;AACV,aAAO;AAAA,IACT;AAEA,UAAM,cAAc,KAAK,MAAM,KAAe;AAC9C,WAAO,WAAW,WAAW;AAAA,EAC/B;AAAA,EAEA,UAAgB;AACd,QAAI,CAAC,KAAK,SAAS;AACjB,WAAK,UAAU;AACf,WAAK,SAAS;AAAA,IAChB;AAAA,EACF;AAAA,EAEA,IAAI,SAAkB;AACpB,WAAO,KAAK;AAAA,EACd;AACF;AAEO,IAAM,cAAN,MAAmC;AAAA,EAC/B;AAAA,EACA;AAAA,EACA;AAAA,EACT,aAAa;AAAA,EACb,UAAU;AAAA,EAEV,YACE,SACA,YACA,oBACA;AACA,SAAK,WAAW;AAChB,SAAK,cAAc;AACnB,SAAK,sBAAsB;AAAA,EAC7B;AAAA,EAEA,MAAM,IAAI,KAA+B;AACvC,6BAAyB,IAAI;AAC7B,UAAM,QAAQ,MAAM,KAAK,oBAAoB,IAAI,WAAW,CAAC,GAAG,CAAC;AACjE,WAAO,UAAU;AAAA,EACnB;AAAA,EAEA,MAAM,IAAI,KAAqD;AAC7D,6BAAyB,IAAI;AAC7B,UAAM,QAAQ,MAAM,KAAK,oBAAoB,IAAI,WAAW,CAAC,GAAG,CAAC;AACjE,QAAI,CAAC,OAAO;AACV,aAAO;AAAA,IACT;AAEA,UAAM,cAAc,KAAK,MAAM,KAAe;AAC9C,WAAO,WAAW,WAAW;AAAA,EAC/B;AAAA,EAEA,MAAM,IAAI,KAAa,OAAyC;AAC9D,6BAAyB,IAAI;AAC7B,UAAM,KAAK,oBAAoB,IAAI,KAAK,CAAC,KAAK,KAAK,UAAU,KAAK,CAAC,CAAC;AAAA,EACtE;AAAA,EAEA,MAAM,IAAI,KAA4B;AACpC,6BAAyB,IAAI;AAC7B,UAAM,KAAK,oBAAoB,IAAI,KAAK,CAAC,GAAG,CAAC;AAAA,EAC/C;AAAA;AAAA,EAGA,MAAM,SAAwB;AAC5B,6BAAyB,IAAI;AAC7B,SAAK,YAAY,SAAS,QAAQ;AAClC,SAAK,aAAa;AAAA,EACpB;AAAA,EAEA,UAAgB;AACd,QAAI,CAAC,KAAK,SAAS;AACjB,WAAK,UAAU;AAEf,UAAI,CAAC,KAAK,YAAY;AACpB,aAAK,YAAY,SAAS,UAAU;AAAA,MACtC;AAEA,WAAK,SAAS;AAAA,IAChB;AAAA,EACF;AAAA,EAEA,IAAI,SAAkB;AACpB,WAAO,KAAK;AAAA,EACd;AACF;AAWA,IAAM,SAAS,oBAAI,IAAwB;AAO3C,SAAS,iBACP,MACA,QACA,MACY;AACZ,QAAM,WAAW,aAAa,IAAI;AAClC,QAAM,QAAQ,OAAO,IAAI,QAAQ;AAEjC,MAAI,OAAO;AACT,UAAM;AACN,WAAO;AAAA,EACT;AAEA,QAAM,aAAa,OAAO,UAAU,IAAI;AACxC,QAAM,qBAAqB,cAAc,YAAY,IAAI;AAEzD,QAAM,OAAO,IAAI,OAAO;AAExB,QAAM,WAAuB;AAAA,IAC3B;AAAA,IACA,IAAI;AAAA,IACJ,UAAU;AAAA,IACV,eAAe;AAAA,IACf;AAAA,EACF;AACA,SAAO,IAAI,UAAU,QAAQ;AAC7B,SAAO;AACT;AAOA,SAAS,uBACP,UACA,YACM;AACN,QAAM,QAAQ,OAAO,IAAI,QAAQ;AACjC,MAAI,OAAO;AACT,UAAM;AACN,QAAI,MAAM,YAAY,GAAG;AACvB,iBAAW,MAAM;AACjB,aAAO,OAAO,QAAQ;AAAA,IACxB;AAAA,EACF;AACF;AACO,SAAS,gCAAsC;AACpD,aAAW,SAAS,OAAO,OAAO,GAAG;AACnC,UAAM,GAAG,MAAM;AAAA,EACjB;AACA,SAAO,MAAM;AACf;AAEO,SAAS,UACd,MACA,gBAIe;AACf,QAAM,WAAW,aAAa,IAAI;AAClC,QAAM,QAAQ,OAAO,IAAI,QAAQ;AACjC,MAAI,OAAO;AACT,UAAM,GAAG,MAAM;AACf,WAAO,OAAO,QAAQ;AAAA,EACxB;AAGA,QAAM,eAAe,eAAe,QAAQ;AAC5C,eAAa,QAAQ;AAErB,SAAO,QAAQ,QAAQ;AACzB;",
6
+ "names": []
7
+ }
@@ -1,10 +1,9 @@
1
1
  import {
2
- throwIfStoreClosed,
3
- throwIfTransactionClosed
4
- } from "./chunk-ASRS2LFV.js";
5
- import {
6
- deepFreeze
7
- } from "./chunk-SGW2EIVJ.js";
2
+ SQLiteStore,
3
+ dropStore
4
+ } from "./chunk-X7SAVR5O.js";
5
+ import "./chunk-ASRS2LFV.js";
6
+ import "./chunk-SGW2EIVJ.js";
8
7
  import "./chunk-424PT5DM.js";
9
8
 
10
9
  // ../replicache/src/kv/expo-sqlite/store.ts
@@ -12,208 +11,6 @@ import {
12
11
  deleteDatabaseSync,
13
12
  openDatabaseSync
14
13
  } from "expo-sqlite";
15
-
16
- // ../replicache/src/kv/sqlite-store.ts
17
- import { RWLock } from "@rocicorp/lock";
18
- var SQLiteStore = class {
19
- #filename;
20
- #entry;
21
- #closed = false;
22
- constructor(name, create, opts) {
23
- this.#filename = safeFilename(name);
24
- this.#entry = getOrCreateEntry(name, create, opts);
25
- }
26
- async read() {
27
- throwIfStoreClosed(this);
28
- const entry = this.#entry;
29
- const { db, lock, preparedStatements } = entry;
30
- const release = await lock.read();
31
- if (entry.activeReaders === 0) {
32
- db.execSync("BEGIN");
33
- }
34
- entry.activeReaders++;
35
- return new SQLiteStoreRead(() => {
36
- entry.activeReaders--;
37
- if (entry.activeReaders === 0) {
38
- db.execSync("COMMIT");
39
- }
40
- release();
41
- }, preparedStatements);
42
- }
43
- async write() {
44
- throwIfStoreClosed(this);
45
- const { lock, db, preparedStatements } = this.#entry;
46
- const release = await lock.write();
47
- db.execSync("BEGIN IMMEDIATE");
48
- return new SQLiteWrite(release, db, preparedStatements);
49
- }
50
- async close() {
51
- if (this.#closed) {
52
- return;
53
- }
54
- const { lock, db } = this.#entry;
55
- const writeRelease = await lock.write();
56
- decrementStoreRefCount(this.#filename, db);
57
- this.#closed = true;
58
- writeRelease();
59
- }
60
- get closed() {
61
- return this.#closed;
62
- }
63
- };
64
- function safeFilename(name) {
65
- return name.replace(/[^a-zA-Z0-9]/g, "_");
66
- }
67
- function setupDatabase(delegate, opts) {
68
- delegate.execSync(`PRAGMA busy_timeout = ${opts?.busyTimeout ?? 200}`);
69
- delegate.execSync(`PRAGMA journal_mode = '${opts?.journalMode ?? "WAL"}'`);
70
- delegate.execSync(`PRAGMA synchronous = '${opts?.synchronous ?? "NORMAL"}'`);
71
- delegate.execSync(
72
- `PRAGMA read_uncommitted = ${Boolean(opts?.readUncommitted)}`
73
- );
74
- delegate.execSync(`
75
- CREATE TABLE IF NOT EXISTS entry (
76
- key TEXT PRIMARY KEY,
77
- value TEXT NOT NULL
78
- ) WITHOUT ROWID
79
- `);
80
- return {
81
- has: delegate.prepare(`SELECT 1 FROM entry WHERE key = ? LIMIT 1`),
82
- get: delegate.prepare("SELECT value FROM entry WHERE key = ?"),
83
- put: delegate.prepare(
84
- "INSERT OR REPLACE INTO entry (key, value) VALUES (?, ?)"
85
- ),
86
- del: delegate.prepare("DELETE FROM entry WHERE key = ?")
87
- };
88
- }
89
- var SQLiteStoreRead = class {
90
- #release;
91
- #closed = false;
92
- #preparedStatements;
93
- constructor(release, preparedStatements) {
94
- this.#release = release;
95
- this.#preparedStatements = preparedStatements;
96
- }
97
- async has(key) {
98
- throwIfTransactionClosed(this);
99
- const value = await this.#preparedStatements.has.firstValue([key]);
100
- return value !== void 0;
101
- }
102
- async get(key) {
103
- throwIfTransactionClosed(this);
104
- const value = await this.#preparedStatements.get.firstValue([key]);
105
- if (!value) {
106
- return void 0;
107
- }
108
- const parsedValue = JSON.parse(value);
109
- return deepFreeze(parsedValue);
110
- }
111
- release() {
112
- if (!this.#closed) {
113
- this.#closed = true;
114
- this.#release();
115
- }
116
- }
117
- get closed() {
118
- return this.#closed;
119
- }
120
- };
121
- var SQLiteWrite = class {
122
- #release;
123
- #dbDelegate;
124
- #preparedStatements;
125
- #committed = false;
126
- #closed = false;
127
- constructor(release, dbDelegate, preparedStatements) {
128
- this.#release = release;
129
- this.#dbDelegate = dbDelegate;
130
- this.#preparedStatements = preparedStatements;
131
- }
132
- async has(key) {
133
- throwIfTransactionClosed(this);
134
- const value = await this.#preparedStatements.has.firstValue([key]);
135
- return value !== void 0;
136
- }
137
- async get(key) {
138
- throwIfTransactionClosed(this);
139
- const value = await this.#preparedStatements.get.firstValue([key]);
140
- if (!value) {
141
- return void 0;
142
- }
143
- const parsedValue = JSON.parse(value);
144
- return deepFreeze(parsedValue);
145
- }
146
- async put(key, value) {
147
- throwIfTransactionClosed(this);
148
- await this.#preparedStatements.put.exec([key, JSON.stringify(value)]);
149
- }
150
- async del(key) {
151
- throwIfTransactionClosed(this);
152
- await this.#preparedStatements.del.exec([key]);
153
- }
154
- // eslint-disable-next-line require-await
155
- async commit() {
156
- throwIfTransactionClosed(this);
157
- this.#dbDelegate.execSync("COMMIT");
158
- this.#committed = true;
159
- }
160
- release() {
161
- if (!this.#closed) {
162
- this.#closed = true;
163
- if (!this.#committed) {
164
- this.#dbDelegate.execSync("ROLLBACK");
165
- }
166
- this.#release();
167
- }
168
- }
169
- get closed() {
170
- return this.#closed;
171
- }
172
- };
173
- var stores = /* @__PURE__ */ new Map();
174
- function getOrCreateEntry(name, create, opts) {
175
- const filename = safeFilename(name);
176
- const entry = stores.get(filename);
177
- if (entry) {
178
- entry.refCount++;
179
- return entry;
180
- }
181
- const dbDelegate = create(filename, opts);
182
- const preparedStatements = setupDatabase(dbDelegate, opts);
183
- const lock = new RWLock();
184
- const newEntry = {
185
- lock,
186
- db: dbDelegate,
187
- refCount: 1,
188
- activeReaders: 0,
189
- preparedStatements
190
- };
191
- stores.set(filename, newEntry);
192
- return newEntry;
193
- }
194
- function decrementStoreRefCount(filename, dbDelegate) {
195
- const entry = stores.get(filename);
196
- if (entry) {
197
- entry.refCount--;
198
- if (entry.refCount <= 0) {
199
- dbDelegate.close();
200
- stores.delete(filename);
201
- }
202
- }
203
- }
204
- function dropStore(name, createDelegate) {
205
- const filename = safeFilename(name);
206
- const entry = stores.get(filename);
207
- if (entry) {
208
- entry.db.close();
209
- stores.delete(filename);
210
- }
211
- const tempDelegate = createDelegate(filename);
212
- tempDelegate.destroy();
213
- return Promise.resolve();
214
- }
215
-
216
- // ../replicache/src/kv/expo-sqlite/store.ts
217
14
  function dropExpoSQLiteStore(name) {
218
15
  return dropStore(name, (filename) => new ExpoSQLiteDatabase(filename));
219
16
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
- "sources": ["../../replicache/src/kv/expo-sqlite/store.ts", "../../replicache/src/kv/sqlite-store.ts", "../../replicache/src/kv/op-sqlite/types.ts", "../../replicache/src/kv/op-sqlite/store.ts"],
4
- "sourcesContent": ["import {\n deleteDatabaseSync,\n openDatabaseSync,\n type SQLiteDatabase as DB,\n type SQLiteStatement,\n} from 'expo-sqlite';\nimport type {\n PreparedStatement,\n SQLiteDatabase,\n SQLiteStoreOptions,\n} from '../sqlite-store.ts';\nimport {dropStore, SQLiteStore} from '../sqlite-store.ts';\nimport type {StoreProvider} from '../store.ts';\n\nexport type ExpoSQLiteStoreOptions = SQLiteStoreOptions;\n\nexport function dropExpoSQLiteStore(name: string): Promise<void> {\n return dropStore(name, filename => new ExpoSQLiteDatabase(filename));\n}\n\n/**\n * Creates a StoreProvider for SQLite-based stores using expo-sqlite.\n * Supports shared connections between multiple store instances with the same name,\n * providing efficient resource utilization and proper transaction isolation.\n */\nexport function expoSQLiteStoreProvider(\n opts?: ExpoSQLiteStoreOptions,\n): StoreProvider {\n return {\n create: name =>\n new SQLiteStore(name, name => new ExpoSQLiteDatabase(name), opts),\n drop: dropExpoSQLiteStore,\n };\n}\n\nclass ExpoSQLitePreparedStatement implements PreparedStatement {\n readonly #statement: SQLiteStatement;\n\n constructor(statement: SQLiteStatement) {\n this.#statement = statement;\n }\n\n async firstValue(params: string[]): Promise<string | undefined> {\n const result = await this.#statement.executeForRawResultAsync(params);\n const row = await result.getFirstAsync();\n return row === null ? undefined : row[0];\n }\n\n async exec(params: string[]): Promise<void> {\n await this.#statement.executeForRawResultAsync(params);\n }\n}\n\nclass ExpoSQLiteDatabase implements SQLiteDatabase {\n readonly #db: DB;\n readonly #filename: string;\n readonly #statements: Set<SQLiteStatement> = new Set();\n\n constructor(filename: string) {\n this.#filename = filename;\n this.#db = openDatabaseSync(filename);\n }\n\n close(): void {\n for (const stmt of this.#statements) {\n stmt.finalizeSync();\n }\n this.#db.closeSync();\n }\n\n destroy(): void {\n deleteDatabaseSync(this.#filename);\n }\n\n prepare(sql: string): PreparedStatement {\n const statement = this.#db.prepareSync(sql);\n this.#statements.add(statement);\n return new ExpoSQLitePreparedStatement(statement);\n }\n\n execSync(sql: string): void {\n this.#db.execSync(sql);\n }\n}\n", "import {RWLock} from '@rocicorp/lock';\nimport type {ReadonlyJSONValue} from '../../../shared/src/json.ts';\nimport {deepFreeze} from '../frozen-json.ts';\nimport type {Read, Store, Write} from './store.ts';\nimport {\n throwIfStoreClosed,\n throwIfTransactionClosed,\n} from './throw-if-closed.ts';\n\n/**\n * A SQLite prepared statement.\n *\n * `run` executes the statement with optional parameters.\n * `all` executes the statement and returns the result rows.\n * `finalize` releases the statement.\n */\nexport interface PreparedStatement {\n firstValue(params: string[]): Promise<unknown>;\n exec(params: string[]): Promise<void>;\n}\n\nexport interface SQLiteDatabase {\n /**\n * Close the database connection.\n */\n close(): void;\n\n /**\n * Destroy or delete the database (e.g. delete file).\n */\n destroy(): void;\n\n /**\n * Prepare a SQL string, returning a statement you can execute.\n * E.g. `const stmt = db.prepare(\"SELECT * FROM todos WHERE id=?\");`\n */\n prepare(sql: string): PreparedStatement;\n\n // for PRAGMA statements, schema creation and transaction control.\n execSync(sql: string): void;\n}\n\nexport type CreateSQLiteDatabase = (\n filename: string,\n opts?: SQLiteStoreOptions,\n) => SQLiteDatabase;\n\n/**\n * SQLite-based implementation of the Store interface using a configurable delegate.\n * Supports shared connections between multiple store instances with the same name,\n * providing efficient resource utilization and proper transaction isolation.\n * Uses parameterized queries for safety and performance.\n */\nexport class SQLiteStore implements Store {\n readonly #filename: string;\n readonly #entry: StoreEntry;\n\n #closed = false;\n\n constructor(\n name: string,\n create: CreateSQLiteDatabase,\n opts?: SQLiteStoreOptions,\n ) {\n this.#filename = safeFilename(name);\n this.#entry = getOrCreateEntry(name, create, opts);\n }\n\n async read(): Promise<Read> {\n throwIfStoreClosed(this);\n\n const entry = this.#entry;\n const {db, lock, preparedStatements} = entry;\n const release = await lock.read();\n\n // Start shared read transaction if this is the first reader\n // This ensures consistent reads across all concurrent readers\n if (entry.activeReaders === 0) {\n db.execSync('BEGIN');\n }\n entry.activeReaders++;\n\n return new SQLiteStoreRead(() => {\n entry.activeReaders--;\n // Commit shared read transaction when last reader finishes\n if (entry.activeReaders === 0) {\n db.execSync('COMMIT');\n }\n release();\n }, preparedStatements);\n }\n\n async write(): Promise<Write> {\n throwIfStoreClosed(this);\n\n const {lock, db, preparedStatements} = this.#entry;\n const release = await lock.write();\n\n // At this point, RWLock guarantees no active readers\n // The last reader would have already committed the shared transaction\n\n db.execSync('BEGIN IMMEDIATE');\n\n return new SQLiteWrite(release, db, preparedStatements);\n }\n\n async close(): Promise<void> {\n if (this.#closed) {\n return;\n }\n\n const {lock, db} = this.#entry;\n // Wait for all readers and writers to finish.\n const writeRelease = await lock.write();\n\n // Handle reference counting for shared stores - only close database\n // when this is the last store instance using it\n decrementStoreRefCount(this.#filename, db);\n\n this.#closed = true;\n writeRelease();\n }\n\n get closed(): boolean {\n return this.#closed;\n }\n}\n\nexport function safeFilename(name: string): string {\n return name.replace(/[^a-zA-Z0-9]/g, '_');\n}\n\nexport type PreparedStatements = {\n has: PreparedStatement;\n get: PreparedStatement;\n put: PreparedStatement;\n del: PreparedStatement;\n};\n\nexport interface SQLiteStoreOptions {\n // Common options\n busyTimeout?: number;\n journalMode?: 'WAL' | 'DELETE';\n synchronous?: 'NORMAL' | 'FULL';\n readUncommitted?: boolean;\n}\n\n/**\n * Common database setup logic shared between expo-sqlite and op-sqlite implementations.\n * Configures SQLite pragmas, creates the entry table, and prepares common statements.\n */\n\nexport function setupDatabase(\n delegate: SQLiteDatabase,\n opts?: SQLiteStoreOptions,\n): PreparedStatements {\n // Configure SQLite pragmas for optimal performance\n delegate.execSync(`PRAGMA busy_timeout = ${opts?.busyTimeout ?? 200}`);\n delegate.execSync(`PRAGMA journal_mode = '${opts?.journalMode ?? 'WAL'}'`);\n delegate.execSync(`PRAGMA synchronous = '${opts?.synchronous ?? 'NORMAL'}'`);\n delegate.execSync(\n `PRAGMA read_uncommitted = ${Boolean(opts?.readUncommitted)}`,\n );\n\n // Create the entry table\n delegate.execSync(`\n CREATE TABLE IF NOT EXISTS entry (\n key TEXT PRIMARY KEY, \n value TEXT NOT NULL\n ) WITHOUT ROWID\n `);\n\n // Prepare common statements\n return {\n has: delegate.prepare(`SELECT 1 FROM entry WHERE key = ? LIMIT 1`),\n get: delegate.prepare('SELECT value FROM entry WHERE key = ?'),\n put: delegate.prepare(\n 'INSERT OR REPLACE INTO entry (key, value) VALUES (?, ?)',\n ),\n del: delegate.prepare('DELETE FROM entry WHERE key = ?'),\n };\n}\n\nexport class SQLiteStoreRead implements Read {\n #release: () => void;\n #closed = false;\n #preparedStatements: PreparedStatements;\n\n constructor(release: () => void, preparedStatements: PreparedStatements) {\n this.#release = release;\n this.#preparedStatements = preparedStatements;\n }\n\n async has(key: string): Promise<boolean> {\n throwIfTransactionClosed(this);\n const value = await this.#preparedStatements.has.firstValue([key]);\n return value !== undefined;\n }\n\n async get(key: string): Promise<ReadonlyJSONValue | undefined> {\n throwIfTransactionClosed(this);\n const value = await this.#preparedStatements.get.firstValue([key]);\n if (!value) {\n return undefined;\n }\n\n const parsedValue = JSON.parse(value as string) as ReadonlyJSONValue;\n return deepFreeze(parsedValue);\n }\n\n release(): void {\n if (!this.#closed) {\n this.#closed = true;\n this.#release();\n }\n }\n\n get closed(): boolean {\n return this.#closed;\n }\n}\n\nexport class SQLiteWrite implements Write {\n readonly #release: () => void;\n readonly #dbDelegate: SQLiteDatabase;\n readonly #preparedStatements: PreparedStatements;\n #committed = false;\n #closed = false;\n\n constructor(\n release: () => void,\n dbDelegate: SQLiteDatabase,\n preparedStatements: PreparedStatements,\n ) {\n this.#release = release;\n this.#dbDelegate = dbDelegate;\n this.#preparedStatements = preparedStatements;\n }\n\n async has(key: string): Promise<boolean> {\n throwIfTransactionClosed(this);\n const value = await this.#preparedStatements.has.firstValue([key]);\n return value !== undefined;\n }\n\n async get(key: string): Promise<ReadonlyJSONValue | undefined> {\n throwIfTransactionClosed(this);\n const value = await this.#preparedStatements.get.firstValue([key]);\n if (!value) {\n return undefined;\n }\n\n const parsedValue = JSON.parse(value as string) as ReadonlyJSONValue;\n return deepFreeze(parsedValue);\n }\n\n async put(key: string, value: ReadonlyJSONValue): Promise<void> {\n throwIfTransactionClosed(this);\n await this.#preparedStatements.put.exec([key, JSON.stringify(value)]);\n }\n\n async del(key: string): Promise<void> {\n throwIfTransactionClosed(this);\n await this.#preparedStatements.del.exec([key]);\n }\n\n // eslint-disable-next-line require-await\n async commit(): Promise<void> {\n throwIfTransactionClosed(this);\n this.#dbDelegate.execSync('COMMIT');\n this.#committed = true;\n }\n\n release(): void {\n if (!this.#closed) {\n this.#closed = true;\n\n if (!this.#committed) {\n this.#dbDelegate.execSync('ROLLBACK');\n }\n\n this.#release();\n }\n }\n\n get closed(): boolean {\n return this.#closed;\n }\n}\n\ntype StoreEntry = {\n readonly lock: RWLock;\n readonly db: SQLiteDatabase;\n refCount: number;\n activeReaders: number;\n preparedStatements: PreparedStatements;\n};\n\n// Global map to share database connections between multiple store instances with the same name\nconst stores = new Map<string, StoreEntry>();\n\n/**\n * Gets an existing store entry or creates a new one if it doesn't exist.\n * This implements the shared connection pattern where multiple stores with the same\n * name share the same database connection, lock, and delegate.\n */\nfunction getOrCreateEntry(\n name: string,\n create: (filename: string, opts?: SQLiteStoreOptions) => SQLiteDatabase,\n opts?: SQLiteStoreOptions,\n): StoreEntry {\n const filename = safeFilename(name);\n const entry = stores.get(filename);\n\n if (entry) {\n entry.refCount++;\n return entry;\n }\n\n const dbDelegate = create(filename, opts);\n const preparedStatements = setupDatabase(dbDelegate, opts);\n\n const lock = new RWLock();\n\n const newEntry: StoreEntry = {\n lock,\n db: dbDelegate,\n refCount: 1,\n activeReaders: 0,\n preparedStatements,\n };\n stores.set(filename, newEntry);\n return newEntry;\n}\n\n/**\n * Decrements the reference count for a shared store and cleans up resources\n * when the last reference is released.\n */\n\nfunction decrementStoreRefCount(\n filename: string,\n dbDelegate: SQLiteDatabase,\n): void {\n const entry = stores.get(filename);\n if (entry) {\n entry.refCount--;\n if (entry.refCount <= 0) {\n dbDelegate.close();\n stores.delete(filename);\n }\n }\n}\nexport function clearAllNamedStoresForTesting(): void {\n for (const entry of stores.values()) {\n entry.db.close();\n }\n stores.clear();\n}\n\nexport function dropStore(\n name: string,\n createDelegate: (\n filename: string,\n opts?: SQLiteStoreOptions,\n ) => SQLiteDatabase,\n): Promise<void> {\n const filename = safeFilename(name);\n const entry = stores.get(filename);\n if (entry) {\n entry.db.close();\n stores.delete(filename);\n }\n\n // Create a temporary delegate to handle database deletion\n const tempDelegate = createDelegate(filename);\n tempDelegate.destroy();\n\n return Promise.resolve();\n}\n", "// Type definitions and imports for @op-engineering/op-sqlite\n// This file isolates the module resolution workarounds needed for this package\n\n// @ts-expect-error - Module resolution issue with @op-engineering/op-sqlite exports\nimport {open as openDB} from '@op-engineering/op-sqlite';\n\n// Minimal type definitions for @op-engineering/op-sqlite\n// These types are used as fallback since imports have module resolution issues\nexport interface DB {\n close: () => void;\n delete: (location?: string) => void;\n executeRaw: (query: string, params?: string[]) => Promise<string[][]>;\n executeRawSync: (query: string, params?: string[]) => string[][];\n}\n\nexport type OpenFunction = (params: {\n name: string;\n location?: string;\n encryptionKey?: string;\n}) => DB;\n\n// Export the open function with proper typing\nexport const open: OpenFunction = openDB;\n", "import type {\n PreparedStatement,\n SQLiteDatabase,\n SQLiteStoreOptions,\n} from '../sqlite-store.ts';\nimport {dropStore, SQLiteStore} from '../sqlite-store.ts';\nimport type {StoreProvider} from '../store.ts';\nimport {open, type DB} from './types.ts';\n\nexport type OpSQLiteStoreOptions = SQLiteStoreOptions & {\n // OpSQLite-specific options\n location?: 'default' | 'Library' | 'Documents' | 'Temporary';\n encryptionKey?: string;\n};\n\nfunction dropOpSQLiteStore(name: string): Promise<void> {\n return dropStore(\n name,\n (filename, opts) => new OpSQLiteDatabase(filename, opts),\n );\n}\n\n/**\n * Creates a StoreProvider for SQLite-based stores using @op-engineering/op-sqlite.\n * Supports shared connections between multiple store instances with the same name,\n * providing efficient resource utilization and proper transaction isolation.\n * Uses parameterized queries for safety and performance.\n */\nexport function opSQLiteStoreProvider(\n opts?: OpSQLiteStoreOptions,\n): StoreProvider {\n return {\n create: name =>\n new SQLiteStore(\n name,\n (name, options) => new OpSQLiteDatabase(name, options),\n opts,\n ),\n drop: dropOpSQLiteStore,\n };\n}\n\nclass OpSQLitePreparedStatement implements PreparedStatement {\n readonly #db: DB;\n readonly #sql: string;\n\n constructor(db: DB, sql: string) {\n this.#db = db;\n this.#sql = sql;\n }\n\n async firstValue(params: string[]): Promise<string | undefined> {\n const rows = await this.#db.executeRaw(this.#sql, params);\n return rows[0]?.[0];\n }\n\n async exec(params: string[]): Promise<void> {\n await this.#db.executeRaw(this.#sql, params);\n }\n}\n\nclass OpSQLiteDatabase implements SQLiteDatabase {\n readonly #db: DB;\n readonly #filename: string;\n\n constructor(filename: string, opts?: OpSQLiteStoreOptions) {\n this.#filename = filename;\n const openOpts: {\n name: string;\n location?: string;\n encryptionKey?: string;\n } = {name: filename};\n\n if (opts?.location) {\n openOpts.location = opts.location;\n }\n if (opts?.encryptionKey) {\n openOpts.encryptionKey = opts.encryptionKey;\n }\n\n this.#db = open(openOpts);\n }\n\n close(): void {\n this.#db.close();\n }\n\n destroy(): void {\n // OpSQLite uses delete method on the database instance\n // We need to create a temporary connection to delete the database\n try {\n const tempDb = open({name: this.#filename});\n tempDb.delete();\n tempDb.close();\n } catch (_error) {\n // Database might not exist, which is fine\n }\n }\n\n prepare(sql: string): PreparedStatement {\n return new OpSQLitePreparedStatement(this.#db, sql);\n }\n\n execSync(sql: string): void {\n this.#db.executeRawSync(sql, []);\n }\n}\n"],
5
- "mappings": "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",
3
+ "sources": ["../../replicache/src/kv/expo-sqlite/store.ts", "../../replicache/src/kv/op-sqlite/types.ts", "../../replicache/src/kv/op-sqlite/store.ts"],
4
+ "sourcesContent": ["import {\n deleteDatabaseSync,\n openDatabaseSync,\n type SQLiteDatabase as DB,\n type SQLiteStatement,\n} from 'expo-sqlite';\nimport type {\n PreparedStatement,\n SQLiteDatabase,\n SQLiteStoreOptions,\n} from '../sqlite-store.ts';\nimport {dropStore, SQLiteStore} from '../sqlite-store.ts';\nimport type {StoreProvider} from '../store.ts';\n\nexport type ExpoSQLiteStoreOptions = SQLiteStoreOptions;\n\nexport function dropExpoSQLiteStore(name: string): Promise<void> {\n return dropStore(name, filename => new ExpoSQLiteDatabase(filename));\n}\n\n/**\n * Creates a StoreProvider for SQLite-based stores using expo-sqlite.\n * Supports shared connections between multiple store instances with the same name,\n * providing efficient resource utilization and proper transaction isolation.\n */\nexport function expoSQLiteStoreProvider(\n opts?: ExpoSQLiteStoreOptions,\n): StoreProvider {\n return {\n create: name =>\n new SQLiteStore(name, name => new ExpoSQLiteDatabase(name), opts),\n drop: dropExpoSQLiteStore,\n };\n}\n\nclass ExpoSQLitePreparedStatement implements PreparedStatement {\n readonly #statement: SQLiteStatement;\n\n constructor(statement: SQLiteStatement) {\n this.#statement = statement;\n }\n\n async firstValue(params: string[]): Promise<string | undefined> {\n const result = await this.#statement.executeForRawResultAsync(params);\n const row = await result.getFirstAsync();\n return row === null ? undefined : row[0];\n }\n\n async exec(params: string[]): Promise<void> {\n await this.#statement.executeForRawResultAsync(params);\n }\n}\n\nclass ExpoSQLiteDatabase implements SQLiteDatabase {\n readonly #db: DB;\n readonly #filename: string;\n readonly #statements: Set<SQLiteStatement> = new Set();\n\n constructor(filename: string) {\n this.#filename = filename;\n this.#db = openDatabaseSync(filename);\n }\n\n close(): void {\n for (const stmt of this.#statements) {\n stmt.finalizeSync();\n }\n this.#db.closeSync();\n }\n\n destroy(): void {\n deleteDatabaseSync(this.#filename);\n }\n\n prepare(sql: string): PreparedStatement {\n const statement = this.#db.prepareSync(sql);\n this.#statements.add(statement);\n return new ExpoSQLitePreparedStatement(statement);\n }\n\n execSync(sql: string): void {\n this.#db.execSync(sql);\n }\n}\n", "// Type definitions and imports for @op-engineering/op-sqlite\n// This file isolates the module resolution workarounds needed for this package\n\n// @ts-expect-error - Module resolution issue with @op-engineering/op-sqlite exports\nimport {open as openDB} from '@op-engineering/op-sqlite';\n\n// Minimal type definitions for @op-engineering/op-sqlite\n// These types are used as fallback since imports have module resolution issues\nexport interface DB {\n close: () => void;\n delete: (location?: string) => void;\n executeRaw: (query: string, params?: string[]) => Promise<string[][]>;\n executeRawSync: (query: string, params?: string[]) => string[][];\n}\n\nexport type OpenFunction = (params: {\n name: string;\n location?: string;\n encryptionKey?: string;\n}) => DB;\n\n// Export the open function with proper typing\nexport const open: OpenFunction = openDB;\n", "import type {\n PreparedStatement,\n SQLiteDatabase,\n SQLiteStoreOptions,\n} from '../sqlite-store.ts';\nimport {dropStore, SQLiteStore} from '../sqlite-store.ts';\nimport type {StoreProvider} from '../store.ts';\nimport {open, type DB} from './types.ts';\n\nexport type OpSQLiteStoreOptions = SQLiteStoreOptions & {\n // OpSQLite-specific options\n location?: 'default' | 'Library' | 'Documents' | 'Temporary';\n encryptionKey?: string;\n};\n\nfunction dropOpSQLiteStore(name: string): Promise<void> {\n return dropStore(\n name,\n (filename, opts) => new OpSQLiteDatabase(filename, opts),\n );\n}\n\n/**\n * Creates a StoreProvider for SQLite-based stores using @op-engineering/op-sqlite.\n * Supports shared connections between multiple store instances with the same name,\n * providing efficient resource utilization and proper transaction isolation.\n * Uses parameterized queries for safety and performance.\n */\nexport function opSQLiteStoreProvider(\n opts?: OpSQLiteStoreOptions,\n): StoreProvider {\n return {\n create: name =>\n new SQLiteStore(\n name,\n (name, options) => new OpSQLiteDatabase(name, options),\n opts,\n ),\n drop: dropOpSQLiteStore,\n };\n}\n\nclass OpSQLitePreparedStatement implements PreparedStatement {\n readonly #db: DB;\n readonly #sql: string;\n\n constructor(db: DB, sql: string) {\n this.#db = db;\n this.#sql = sql;\n }\n\n async firstValue(params: string[]): Promise<string | undefined> {\n const rows = await this.#db.executeRaw(this.#sql, params);\n return rows[0]?.[0];\n }\n\n async exec(params: string[]): Promise<void> {\n await this.#db.executeRaw(this.#sql, params);\n }\n}\n\nclass OpSQLiteDatabase implements SQLiteDatabase {\n readonly #db: DB;\n readonly #filename: string;\n\n constructor(filename: string, opts?: OpSQLiteStoreOptions) {\n this.#filename = filename;\n const openOpts: {\n name: string;\n location?: string;\n encryptionKey?: string;\n } = {name: filename};\n\n if (opts?.location) {\n openOpts.location = opts.location;\n }\n if (opts?.encryptionKey) {\n openOpts.encryptionKey = opts.encryptionKey;\n }\n\n this.#db = open(openOpts);\n }\n\n close(): void {\n this.#db.close();\n }\n\n destroy(): void {\n // OpSQLite uses delete method on the database instance\n // We need to create a temporary connection to delete the database\n try {\n const tempDb = open({name: this.#filename});\n tempDb.delete();\n tempDb.close();\n } catch (_error) {\n // Database might not exist, which is fine\n }\n }\n\n prepare(sql: string): PreparedStatement {\n return new OpSQLitePreparedStatement(this.#db, sql);\n }\n\n execSync(sql: string): void {\n this.#db.executeRawSync(sql, []);\n }\n}\n"],
5
+ "mappings": ";;;;;;;;;AAAA;AAAA,EACE;AAAA,EACA;AAAA,OAGK;AAWA,SAAS,oBAAoB,MAA6B;AAC/D,SAAO,UAAU,MAAM,cAAY,IAAI,mBAAmB,QAAQ,CAAC;AACrE;AAOO,SAAS,wBACd,MACe;AACf,SAAO;AAAA,IACL,QAAQ,UACN,IAAI,YAAY,MAAM,CAAAA,UAAQ,IAAI,mBAAmBA,KAAI,GAAG,IAAI;AAAA,IAClE,MAAM;AAAA,EACR;AACF;AAEA,IAAM,8BAAN,MAA+D;AAAA,EACpD;AAAA,EAET,YAAY,WAA4B;AACtC,SAAK,aAAa;AAAA,EACpB;AAAA,EAEA,MAAM,WAAW,QAA+C;AAC9D,UAAM,SAAS,MAAM,KAAK,WAAW,yBAAyB,MAAM;AACpE,UAAM,MAAM,MAAM,OAAO,cAAc;AACvC,WAAO,QAAQ,OAAO,SAAY,IAAI,CAAC;AAAA,EACzC;AAAA,EAEA,MAAM,KAAK,QAAiC;AAC1C,UAAM,KAAK,WAAW,yBAAyB,MAAM;AAAA,EACvD;AACF;AAEA,IAAM,qBAAN,MAAmD;AAAA,EACxC;AAAA,EACA;AAAA,EACA,cAAoC,oBAAI,IAAI;AAAA,EAErD,YAAY,UAAkB;AAC5B,SAAK,YAAY;AACjB,SAAK,MAAM,iBAAiB,QAAQ;AAAA,EACtC;AAAA,EAEA,QAAc;AACZ,eAAW,QAAQ,KAAK,aAAa;AACnC,WAAK,aAAa;AAAA,IACpB;AACA,SAAK,IAAI,UAAU;AAAA,EACrB;AAAA,EAEA,UAAgB;AACd,uBAAmB,KAAK,SAAS;AAAA,EACnC;AAAA,EAEA,QAAQ,KAAgC;AACtC,UAAM,YAAY,KAAK,IAAI,YAAY,GAAG;AAC1C,SAAK,YAAY,IAAI,SAAS;AAC9B,WAAO,IAAI,4BAA4B,SAAS;AAAA,EAClD;AAAA,EAEA,SAAS,KAAmB;AAC1B,SAAK,IAAI,SAAS,GAAG;AAAA,EACvB;AACF;;;AC/EA,SAAQ,QAAQ,cAAa;AAkBtB,IAAM,OAAqB;;;ACPlC,SAAS,kBAAkB,MAA6B;AACtD,SAAO;AAAA,IACL;AAAA,IACA,CAAC,UAAU,SAAS,IAAI,iBAAiB,UAAU,IAAI;AAAA,EACzD;AACF;AAQO,SAAS,sBACd,MACe;AACf,SAAO;AAAA,IACL,QAAQ,UACN,IAAI;AAAA,MACF;AAAA,MACA,CAACC,OAAM,YAAY,IAAI,iBAAiBA,OAAM,OAAO;AAAA,MACrD;AAAA,IACF;AAAA,IACF,MAAM;AAAA,EACR;AACF;AAEA,IAAM,4BAAN,MAA6D;AAAA,EAClD;AAAA,EACA;AAAA,EAET,YAAY,IAAQ,KAAa;AAC/B,SAAK,MAAM;AACX,SAAK,OAAO;AAAA,EACd;AAAA,EAEA,MAAM,WAAW,QAA+C;AAC9D,UAAM,OAAO,MAAM,KAAK,IAAI,WAAW,KAAK,MAAM,MAAM;AACxD,WAAO,KAAK,CAAC,IAAI,CAAC;AAAA,EACpB;AAAA,EAEA,MAAM,KAAK,QAAiC;AAC1C,UAAM,KAAK,IAAI,WAAW,KAAK,MAAM,MAAM;AAAA,EAC7C;AACF;AAEA,IAAM,mBAAN,MAAiD;AAAA,EACtC;AAAA,EACA;AAAA,EAET,YAAY,UAAkB,MAA6B;AACzD,SAAK,YAAY;AACjB,UAAM,WAIF,EAAC,MAAM,SAAQ;AAEnB,QAAI,MAAM,UAAU;AAClB,eAAS,WAAW,KAAK;AAAA,IAC3B;AACA,QAAI,MAAM,eAAe;AACvB,eAAS,gBAAgB,KAAK;AAAA,IAChC;AAEA,SAAK,MAAM,KAAK,QAAQ;AAAA,EAC1B;AAAA,EAEA,QAAc;AACZ,SAAK,IAAI,MAAM;AAAA,EACjB;AAAA,EAEA,UAAgB;AAGd,QAAI;AACF,YAAM,SAAS,KAAK,EAAC,MAAM,KAAK,UAAS,CAAC;AAC1C,aAAO,OAAO;AACd,aAAO,MAAM;AAAA,IACf,SAAS,QAAQ;AAAA,IAEjB;AAAA,EACF;AAAA,EAEA,QAAQ,KAAgC;AACtC,WAAO,IAAI,0BAA0B,KAAK,KAAK,GAAG;AAAA,EACpD;AAAA,EAEA,SAAS,KAAmB;AAC1B,SAAK,IAAI,eAAe,KAAK,CAAC,CAAC;AAAA,EACjC;AACF;",
6
6
  "names": ["name", "name"]
7
7
  }
package/out/react.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  Zero
3
- } from "./chunk-QCPDXNFF.js";
3
+ } from "./chunk-ASFIXQH7.js";
4
4
  import "./chunk-ASRS2LFV.js";
5
5
  import {
6
6
  DEFAULT_TTL_MS
@@ -0,0 +1,3 @@
1
+ export { clearAllNamedStoresForTesting, dropStore, SQLiteStore, type PreparedStatement, type SQLiteDatabase, type SQLiteStoreOptions, } from './kv/sqlite-store.ts';
2
+ export type { CreateStore, DropStore, Read, Store, StoreProvider, Write, } from './kv/store.ts';
3
+ //# sourceMappingURL=sqlite.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sqlite.d.ts","sourceRoot":"","sources":["../../../../replicache/src/sqlite.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,6BAA6B,EAC7B,SAAS,EACT,WAAW,EACX,KAAK,iBAAiB,EACtB,KAAK,cAAc,EACnB,KAAK,kBAAkB,GACxB,MAAM,sBAAsB,CAAC;AAC9B,YAAY,EACV,WAAW,EACX,SAAS,EACT,IAAI,EACJ,KAAK,EACL,aAAa,EACb,KAAK,GACN,MAAM,eAAe,CAAC"}
package/out/solid.js CHANGED
@@ -1,7 +1,7 @@
1
- import "./chunk-L2ZHMO4E.js";
1
+ import "./chunk-QROPZW7G.js";
2
2
  import {
3
3
  Zero
4
- } from "./chunk-QCPDXNFF.js";
4
+ } from "./chunk-ASFIXQH7.js";
5
5
  import "./chunk-ASRS2LFV.js";
6
6
  import {
7
7
  DEFAULT_TTL_MS,
package/out/sqlite.js ADDED
@@ -0,0 +1,14 @@
1
+ import {
2
+ SQLiteStore,
3
+ clearAllNamedStoresForTesting,
4
+ dropStore
5
+ } from "./chunk-X7SAVR5O.js";
6
+ import "./chunk-ASRS2LFV.js";
7
+ import "./chunk-SGW2EIVJ.js";
8
+ import "./chunk-424PT5DM.js";
9
+ export {
10
+ SQLiteStore,
11
+ clearAllNamedStoresForTesting,
12
+ dropStore
13
+ };
14
+ //# sourceMappingURL=sqlite.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": [],
4
+ "sourcesContent": [],
5
+ "mappings": "",
6
+ "names": []
7
+ }