@rocicorp/zero 0.25.0-canary.4 → 0.25.0-canary.6

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 (45) hide show
  1. package/out/{chunk-ZZXMKAAG.js → chunk-HCZQVP5R.js} +2 -2
  2. package/out/{chunk-3KJ5OEIB.js → chunk-PFM5IJC4.js} +2 -2
  3. package/out/{chunk-ECUMGQGC.js → chunk-WPAQ4EPM.js} +13 -3
  4. package/out/{chunk-ECUMGQGC.js.map → chunk-WPAQ4EPM.js.map} +2 -2
  5. package/out/{chunk-HE4M4K7Q.js → chunk-WWNKZSEE.js} +7 -4
  6. package/out/chunk-WWNKZSEE.js.map +7 -0
  7. package/out/expo-sqlite.js +2 -2
  8. package/out/op-sqlite.js +1 -1
  9. package/out/react-native.js +2 -2
  10. package/out/react.js +2 -1
  11. package/out/react.js.map +2 -2
  12. package/out/replicache/src/kv/sqlite-store.d.ts.map +1 -1
  13. package/out/shared/src/deep-merge.d.ts +6 -3
  14. package/out/shared/src/deep-merge.d.ts.map +1 -1
  15. package/out/solid.js +2 -2
  16. package/out/sqlite.js +1 -1
  17. package/out/zero/package.json +2 -2
  18. package/out/zero/src/zero-cache-dev.js +57 -40
  19. package/out/zero/src/zero-cache-dev.js.map +1 -1
  20. package/out/zero-cache/src/services/view-syncer/pipeline-driver.d.ts.map +1 -1
  21. package/out/zero-cache/src/services/view-syncer/pipeline-driver.js +2 -24
  22. package/out/zero-cache/src/services/view-syncer/pipeline-driver.js.map +1 -1
  23. package/out/zero-cache/src/services/view-syncer/view-syncer.d.ts.map +1 -1
  24. package/out/zero-cache/src/services/view-syncer/view-syncer.js +4 -29
  25. package/out/zero-cache/src/services/view-syncer/view-syncer.js.map +1 -1
  26. package/out/zero-client/src/client/custom.d.ts +2 -2
  27. package/out/zero-client/src/client/custom.d.ts.map +1 -1
  28. package/out/zero-client/src/client/mutation-tracker.d.ts +2 -2
  29. package/out/zero-client/src/client/mutation-tracker.d.ts.map +1 -1
  30. package/out/zero-client/src/client/mutator-proxy.d.ts.map +1 -1
  31. package/out/zero-client/src/mod.d.ts +1 -1
  32. package/out/zero-client/src/mod.d.ts.map +1 -1
  33. package/out/zero-react/src/mod.d.ts +1 -1
  34. package/out/zero-react/src/mod.d.ts.map +1 -1
  35. package/out/zero-react/src/zero-provider.d.ts +1 -0
  36. package/out/zero-react/src/zero-provider.d.ts.map +1 -1
  37. package/out/zero.js +2 -2
  38. package/out/zql/src/builder/builder.d.ts +1 -1
  39. package/out/zql/src/builder/builder.d.ts.map +1 -1
  40. package/out/zql/src/planner/planner-join.js +1 -1
  41. package/out/zql/src/planner/planner-join.js.map +1 -1
  42. package/package.json +2 -2
  43. package/out/chunk-HE4M4K7Q.js.map +0 -7
  44. /package/out/{chunk-ZZXMKAAG.js.map → chunk-HCZQVP5R.js.map} +0 -0
  45. /package/out/{chunk-3KJ5OEIB.js.map → chunk-PFM5IJC4.js.map} +0 -0
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  SQLiteStore,
3
3
  dropStore
4
- } from "./chunk-ECUMGQGC.js";
4
+ } from "./chunk-WPAQ4EPM.js";
5
5
 
6
6
  // ../replicache/src/kv/expo-sqlite/store.ts
7
7
  import {
@@ -61,4 +61,4 @@ var ExpoSQLiteDatabase = class {
61
61
  export {
62
62
  expoSQLiteStoreProvider
63
63
  };
64
- //# sourceMappingURL=chunk-ZZXMKAAG.js.map
64
+ //# sourceMappingURL=chunk-HCZQVP5R.js.map
@@ -4,7 +4,7 @@ import {
4
4
  clientToServer,
5
5
  defaultFormat,
6
6
  queryWithContext
7
- } from "./chunk-HE4M4K7Q.js";
7
+ } from "./chunk-WWNKZSEE.js";
8
8
  import {
9
9
  mapCondition,
10
10
  toStaticParam
@@ -492,4 +492,4 @@ export {
492
492
  defineQueryWithContextType,
493
493
  escapeLike
494
494
  };
495
- //# sourceMappingURL=chunk-3KJ5OEIB.js.map
495
+ //# sourceMappingURL=chunk-PFM5IJC4.js.map
@@ -204,11 +204,21 @@ function dropStore(name, createDelegate) {
204
204
  const filename = safeFilename(name);
205
205
  const entry = stores.get(filename);
206
206
  if (entry) {
207
- entry.db.close();
207
+ try {
208
+ entry.db.close();
209
+ } catch {
210
+ }
208
211
  stores.delete(filename);
209
212
  }
210
213
  const tempDelegate = createDelegate(filename);
211
- tempDelegate.destroy();
214
+ try {
215
+ tempDelegate.close();
216
+ } catch {
217
+ }
218
+ try {
219
+ tempDelegate.destroy();
220
+ } catch {
221
+ }
212
222
  return Promise.resolve();
213
223
  }
214
224
 
@@ -217,4 +227,4 @@ export {
217
227
  clearAllNamedStoresForTesting,
218
228
  dropStore
219
229
  };
220
- //# sourceMappingURL=chunk-ECUMGQGC.js.map
230
+ //# sourceMappingURL=chunk-WPAQ4EPM.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
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 // oxlint-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": "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",
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 // oxlint-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 try {\n entry.db.close();\n } catch {\n // Ignore close errors\n }\n stores.delete(filename);\n }\n\n // Create a temporary delegate to handle database deletion\n const tempDelegate = createDelegate(filename);\n try {\n // we close the db before destroying it - this\n // caused an issue with expo-sqlite since it requires this\n tempDelegate.close();\n } catch {\n // Ignore close errors\n }\n try {\n tempDelegate.destroy();\n } catch {\n // Destroy errors shouldn't be fatal; the file may already be gone or locked\n }\n\n return Promise.resolve();\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -5909,7 +5909,7 @@ var PlannerJoin = class {
5909
5909
  } else {
5910
5910
  costEstimate = {
5911
5911
  startupCost: child.startupCost,
5912
- scanEst: parent.limit === void 0 ? parent.returnedRows : Math.min(
5912
+ scanEst: parent.limit === void 0 ? parent.returnedRows * child.returnedRows : Math.min(
5913
5913
  parent.returnedRows * child.returnedRows,
5914
5914
  parent.limit / downstreamChildSelectivity
5915
5915
  ),
@@ -15343,7 +15343,7 @@ function makeMessage(message, context, logLevel) {
15343
15343
  }
15344
15344
 
15345
15345
  // ../zero-client/src/client/version.ts
15346
- var version2 = "0.25.0-canary.4";
15346
+ var version2 = "0.25.0-canary.6";
15347
15347
 
15348
15348
  // ../zero-client/src/client/log-options.ts
15349
15349
  var LevelFilterLogSink = class {
@@ -16112,7 +16112,10 @@ var MutatorProxy = class {
16112
16112
  };
16113
16113
  }
16114
16114
  #normalizeResultPromise(promise, wrapError) {
16115
- return promise.then(successResult, wrapError);
16115
+ return promise.then(
16116
+ successResult,
16117
+ wrapError
16118
+ );
16116
16119
  }
16117
16120
  #makeZeroErrorResultDetails(zeroError) {
16118
16121
  const { message, ...errorBody } = zeroError.errorBody;
@@ -18851,4 +18854,4 @@ export {
18851
18854
  update_needed_reason_type_enum_exports,
18852
18855
  Zero
18853
18856
  };
18854
- //# sourceMappingURL=chunk-HE4M4K7Q.js.map
18857
+ //# sourceMappingURL=chunk-WWNKZSEE.js.map