@rocicorp/zero 0.23.2025082700 → 0.23.2025082901
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.
- package/out/{chunk-3I7CRZJP.js → chunk-G442PJSB.js} +469 -462
- package/out/chunk-G442PJSB.js.map +7 -0
- package/out/{chunk-JYTPHCUA.js → chunk-MRT7XNEQ.js} +3135 -3133
- package/out/chunk-MRT7XNEQ.js.map +7 -0
- package/out/{chunk-J6KXBJIV.js → chunk-YBQT4PQG.js} +3 -3
- package/out/{inspector-UIWB2MYC.js → inspector-4ALIZXAU.js} +2 -2
- package/out/react-native.js +21 -19
- package/out/react-native.js.map +3 -3
- package/out/react.js +85 -10
- package/out/react.js.map +2 -2
- package/out/replicache/src/expo/store.d.ts +5 -0
- package/out/replicache/src/expo/store.d.ts.map +1 -0
- package/out/replicache/src/get-kv-store-provider.d.ts +4 -0
- package/out/replicache/src/get-kv-store-provider.d.ts.map +1 -0
- package/out/replicache/src/http-status-unauthorized.d.ts +2 -0
- package/out/replicache/src/http-status-unauthorized.d.ts.map +1 -0
- package/out/replicache/src/make-idb-name.d.ts +10 -0
- package/out/replicache/src/make-idb-name.d.ts.map +1 -0
- package/out/replicache/src/persist/collect-idb-databases.d.ts.map +1 -1
- package/out/replicache/src/replicache-impl.d.ts.map +1 -1
- package/out/replicache/src/replicache-options.d.ts +3 -3
- package/out/replicache/src/replicache-options.d.ts.map +1 -1
- package/out/replicache/src/report-error.d.ts +6 -0
- package/out/replicache/src/report-error.d.ts.map +1 -0
- package/out/solid.js +6 -5
- package/out/solid.js.map +2 -2
- package/out/zero/package.json +1 -1
- package/out/zero-client/src/client/zero.d.ts.map +1 -1
- package/out/zero-client/src/mod.d.ts +2 -2
- package/out/zero-client/src/mod.d.ts.map +1 -1
- package/out/zero-react/src/mod.d.ts +1 -1
- package/out/zero-react/src/mod.d.ts.map +1 -1
- package/out/zero-react/src/use-query.d.ts +20 -0
- package/out/zero-react/src/use-query.d.ts.map +1 -1
- package/out/zero-react-native/src/mod.d.ts +2 -1
- package/out/zero-react-native/src/mod.d.ts.map +1 -1
- package/out/zero-solid/src/use-query.d.ts.map +1 -1
- package/out/zero.js +3 -3
- package/out/zql/src/query/query-impl.d.ts +4 -1
- package/out/zql/src/query/query-impl.d.ts.map +1 -1
- package/out/zql/src/query/query-impl.js +12 -0
- package/out/zql/src/query/query-impl.js.map +1 -1
- package/package.json +1 -1
- package/out/chunk-3I7CRZJP.js.map +0 -7
- package/out/chunk-JYTPHCUA.js.map +0 -7
- package/out/replicache/src/replicache.d.ts +0 -298
- package/out/replicache/src/replicache.d.ts.map +0 -1
- package/out/zero-react-native/src/store.d.ts +0 -4
- package/out/zero-react-native/src/store.d.ts.map +0 -1
- /package/out/{chunk-J6KXBJIV.js.map → chunk-YBQT4PQG.js.map} +0 -0
- /package/out/{inspector-UIWB2MYC.js.map → inspector-4ALIZXAU.js.map} +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
clientToServer
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-MRT7XNEQ.js";
|
|
4
4
|
import {
|
|
5
5
|
AbstractQuery,
|
|
6
6
|
ExpressionBuilder,
|
|
@@ -10,7 +10,7 @@ import {
|
|
|
10
10
|
newQuerySymbol,
|
|
11
11
|
staticParam,
|
|
12
12
|
toStaticParam
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-G442PJSB.js";
|
|
14
14
|
import {
|
|
15
15
|
assert
|
|
16
16
|
} from "./chunk-SGW2EIVJ.js";
|
|
@@ -346,4 +346,4 @@ export {
|
|
|
346
346
|
withValidation,
|
|
347
347
|
createBuilder
|
|
348
348
|
};
|
|
349
|
-
//# sourceMappingURL=chunk-
|
|
349
|
+
//# sourceMappingURL=chunk-YBQT4PQG.js.map
|
|
@@ -17,7 +17,7 @@ import {
|
|
|
17
17
|
test,
|
|
18
18
|
valita_exports,
|
|
19
19
|
withRead
|
|
20
|
-
} from "./chunk-
|
|
20
|
+
} from "./chunk-G442PJSB.js";
|
|
21
21
|
import {
|
|
22
22
|
assert,
|
|
23
23
|
unreachable
|
|
@@ -485,4 +485,4 @@ function convertServerMetrics(metrics) {
|
|
|
485
485
|
export {
|
|
486
486
|
newInspector
|
|
487
487
|
};
|
|
488
|
-
//# sourceMappingURL=inspector-
|
|
488
|
+
//# sourceMappingURL=inspector-4ALIZXAU.js.map
|
package/out/react-native.js
CHANGED
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
} from "./chunk-SGW2EIVJ.js";
|
|
8
8
|
import "./chunk-424PT5DM.js";
|
|
9
9
|
|
|
10
|
-
// ../
|
|
10
|
+
// ../replicache/src/expo/store.ts
|
|
11
11
|
import {
|
|
12
12
|
deleteDatabaseSync,
|
|
13
13
|
openDatabaseSync
|
|
@@ -306,7 +306,7 @@ var SQLiteDatabaseManager = class {
|
|
|
306
306
|
}
|
|
307
307
|
};
|
|
308
308
|
|
|
309
|
-
// ../
|
|
309
|
+
// ../replicache/src/expo/store.ts
|
|
310
310
|
var expoDbManagerInstance = new SQLiteDatabaseManager({
|
|
311
311
|
open: (fileName) => {
|
|
312
312
|
const db = openDatabaseSync(fileName);
|
|
@@ -333,23 +333,25 @@ var expoDbManagerInstance = new SQLiteDatabaseManager({
|
|
|
333
333
|
return genericDb;
|
|
334
334
|
}
|
|
335
335
|
});
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
}
|
|
336
|
+
function expoSQLiteStoreProvider(opts) {
|
|
337
|
+
return {
|
|
338
|
+
create: (name) => createSQLiteStore(expoDbManagerInstance)(name, {
|
|
339
|
+
// we default to 3 read connections for mobile devices
|
|
340
|
+
readPoolSize: 3,
|
|
341
|
+
busyTimeout: 200,
|
|
342
|
+
synchronous: "NORMAL",
|
|
343
|
+
readUncommitted: false,
|
|
344
|
+
...opts,
|
|
345
|
+
// we override the journal mode to undefined because
|
|
346
|
+
// setting it to WAL causes hanging COMMITs on Expo
|
|
347
|
+
journalMode: void 0
|
|
348
|
+
}),
|
|
349
|
+
drop: (name) => {
|
|
350
|
+
expoDbManagerInstance.destroy(name);
|
|
351
|
+
return Promise.resolve();
|
|
352
|
+
}
|
|
353
|
+
};
|
|
354
|
+
}
|
|
353
355
|
export {
|
|
354
356
|
expoSQLiteStoreProvider
|
|
355
357
|
};
|
package/out/react-native.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
|
-
"sources": ["../../
|
|
4
|
-
"sourcesContent": ["import {\n deleteDatabaseSync,\n openDatabaseSync,\n type SQLiteBindParams,\n} from 'expo-sqlite';\nimport {\n createSQLiteStore,\n SQLiteDatabaseManager,\n type SQLiteDatabase,\n type SQLiteDatabaseManagerOptions,\n} from '../../replicache/src/kv/sqlite-store.ts';\nimport type {StoreProvider} from '../../replicache/src/kv/store.ts';\nimport {promiseVoid} from '../../shared/src/resolved-promises.ts';\n\nconst expoDbManagerInstance = new SQLiteDatabaseManager({\n open: fileName => {\n const db = openDatabaseSync(fileName);\n\n const genericDb: SQLiteDatabase = {\n close: () => db.closeSync(),\n destroy: () => {\n db.closeSync();\n deleteDatabaseSync(fileName);\n },\n prepare: (sql: string) => {\n const stmt = db.prepareSync(sql);\n return {\n run: (...params: unknown[]): void => {\n stmt.executeSync(params as SQLiteBindParams);\n },\n all: <T>(...params: unknown[]): T[] => {\n const result = stmt.executeSync(params as SQLiteBindParams);\n return result.getAllSync() as unknown as T[];\n },\n finalize: () => stmt.finalizeSync(),\n };\n },\n };\n\n return genericDb;\n },\n});\n\nexport const expoSQLiteStoreProvider = (\n opts?: Partial<Omit<SQLiteDatabaseManagerOptions, 'journalMode'>>,\n): StoreProvider => ({\n create: (name: string) =>\n createSQLiteStore(expoDbManagerInstance)(name, {\n // we default to 3 read connections for mobile devices\n readPoolSize: 3,\n busyTimeout: 200,\n synchronous: 'NORMAL',\n readUncommitted: false,\n ...opts,\n // we override the journal mode to undefined because\n // setting it to WAL causes hanging COMMITs on Expo\n journalMode: undefined,\n }),\n drop: (name: string) => {\n expoDbManagerInstance.destroy(name);\n\n return promiseVoid;\n },\n});\n", "import {Lock, RWLock} from '@rocicorp/lock';\nimport type {ReadonlyJSONValue} from '../../../shared/src/json.ts';\nimport {\n promiseUndefined,\n promiseVoid,\n} from '../../../shared/src/resolved-promises.ts';\nimport {deepFreeze} from '../frozen-json.ts';\nimport type {Read, Store, Write} from './store.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 run(...params: unknown[]): void;\n all<T>(...params: unknown[]): T[];\n finalize(): 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\ntype SQLiteTransactionPreparedStatements = {\n begin: PreparedStatement;\n beginImmediate: PreparedStatement;\n commit: PreparedStatement;\n rollback: PreparedStatement;\n};\n\nconst getTransactionPreparedStatements = (\n db: SQLiteDatabase,\n): SQLiteTransactionPreparedStatements => ({\n begin: db.prepare('BEGIN'),\n beginImmediate: db.prepare('BEGIN IMMEDIATE'),\n commit: db.prepare('COMMIT'),\n rollback: db.prepare('ROLLBACK'),\n});\n\ntype SQLiteRWPreparedStatements = {\n get: PreparedStatement;\n put: PreparedStatement;\n del: PreparedStatement;\n};\n\nconst getRWPreparedStatements = (\n db: SQLiteDatabase,\n): SQLiteRWPreparedStatements => ({\n get: db.prepare('SELECT value FROM entry WHERE key = ?'),\n put: db.prepare('INSERT OR REPLACE INTO entry (key, value) VALUES (?, ?)'),\n del: db.prepare('DELETE FROM entry WHERE key = ?'),\n});\n\ntype SQLitePreparedStatements = SQLiteTransactionPreparedStatements &\n SQLiteRWPreparedStatements;\n\ninterface SQLiteConnectionManager {\n acquire(): Promise<{\n preparedStatements: SQLitePreparedStatements;\n release: () => void;\n }>;\n close(): void;\n}\n\ntype SQLitePreparedStatementPoolEntry = {\n db: SQLiteDatabase;\n lock: Lock;\n preparedStatements: SQLitePreparedStatements;\n};\n\n/**\n * Manages a pool of read-only SQLite connections.\n *\n * Each connection in the pool is protected by its own `Lock` instance which\n * guarantees that it is held by at most one reader at a time. Consumers call\n * {@link acquire} to get access to a set of prepared statements for a\n * connection and must invoke the provided `release` callback when they are\n * finished.\n *\n * The pool eagerly creates the configured number of connections up-front so\n * that the first `acquire` call never has to pay the connection setup cost.\n */\nclass SQLiteReadConnectionManager implements SQLiteConnectionManager {\n #pool: SQLitePreparedStatementPoolEntry[] = [];\n #nextIndex = 0;\n readonly #rwLock: RWLock;\n\n constructor(\n name: string,\n manager: SQLiteDatabaseManager,\n rwLock: RWLock,\n opts: SQLiteDatabaseManagerOptions,\n ) {\n if (opts.readPoolSize <= 1) {\n throw new Error('readPoolSize must be greater than 1');\n }\n\n this.#rwLock = rwLock;\n\n for (let i = 0; i < opts.readPoolSize; i++) {\n // create a new readonly SQLiteDatabase for each instance in the pool\n const {db, preparedStatements} = manager.open(name, opts);\n this.#pool.push({\n db,\n lock: new Lock(),\n preparedStatements,\n });\n }\n }\n\n /**\n * Acquire a round-robin read connection from the pool.\n *\n * The returned `release` callback **must** be invoked once the caller is done\n * using the prepared statements, otherwise other readers may be blocked\n * indefinitely.\n */\n async acquire(): Promise<{\n preparedStatements: SQLitePreparedStatements;\n release: () => void;\n }> {\n const slot = this.#nextIndex;\n this.#nextIndex = (this.#nextIndex + 1) % this.#pool.length;\n\n const entry = this.#pool[slot];\n\n // we have two levels of locking\n // 1. the RWLock to prevent concurrent read operations while a write is in progress\n // 2. the Lock to prevent concurrent read operations on the same connection\n const releaseRWLock = await this.#rwLock.read();\n const releaseLock = await entry.lock.lock();\n\n return {\n preparedStatements: entry.preparedStatements,\n release: () => {\n releaseRWLock();\n releaseLock();\n },\n };\n }\n\n /**\n * Finalizes all prepared statements and closes the underlying connections.\n * After calling this method the manager can no longer be used.\n */\n close(): void {\n for (const entry of this.#pool) {\n for (const stmt of Object.values(entry.preparedStatements)) {\n stmt.finalize();\n }\n entry.db.close();\n }\n this.#pool = [];\n }\n}\n\n/**\n * Manages a single write connection with an external RWLock.\n */\nclass SQLiteWriteConnectionManager implements SQLiteConnectionManager {\n readonly #rwLock: RWLock;\n readonly #preparedStatements: SQLitePreparedStatements;\n readonly #db: SQLiteDatabase;\n\n constructor(\n name: string,\n manager: SQLiteDatabaseManager,\n rwLock: RWLock,\n opts: SQLiteDatabaseManagerOptions,\n ) {\n const {db, preparedStatements} = manager.open(name, opts);\n this.#preparedStatements = preparedStatements;\n this.#db = db;\n this.#rwLock = rwLock;\n }\n\n async acquire(): Promise<{\n preparedStatements: SQLitePreparedStatements;\n release: () => void;\n }> {\n const release = await this.#rwLock.write();\n return {preparedStatements: this.#preparedStatements, release};\n }\n\n close(): void {\n for (const stmt of Object.values(this.#preparedStatements)) {\n stmt.finalize();\n }\n this.#db.close();\n }\n}\n\n/**\n * A SQLite-based Store implementation.\n *\n * This store provides a generic SQLite implementation that can be used with different\n * SQLite providers (expo-sqlite, better-sqlite3, etc). It implements the Store\n * interface using a single 'entry' table with key-value pairs.\n *\n * The store uses a single RWLock to prevent concurrent read and write operations.\n *\n * The store also uses a pool of read connections to allow concurrent reads with separate transactions.\n */\nexport class SQLiteStore implements Store {\n readonly #name: string;\n readonly #dbm: SQLiteDatabaseManager;\n readonly #writeConnectionManager: SQLiteConnectionManager;\n readonly #readConnectionManager: SQLiteConnectionManager;\n readonly #rwLock = new RWLock();\n\n #closed = false;\n\n constructor(\n name: string,\n dbm: SQLiteDatabaseManager,\n opts: SQLiteDatabaseManagerOptions,\n ) {\n this.#name = name;\n this.#dbm = dbm;\n\n this.#writeConnectionManager = new SQLiteWriteConnectionManager(\n name,\n dbm,\n this.#rwLock,\n opts,\n );\n this.#readConnectionManager = new SQLiteReadConnectionManager(\n name,\n dbm,\n this.#rwLock,\n opts,\n );\n }\n\n async read(): Promise<Read> {\n const {preparedStatements, release} =\n await this.#readConnectionManager.acquire();\n return new SQLiteStoreRead(preparedStatements, release);\n }\n\n async write(): Promise<Write> {\n const {preparedStatements, release} =\n await this.#writeConnectionManager.acquire();\n return new SQLiteStoreWrite(preparedStatements, release);\n }\n\n close(): Promise<void> {\n this.#writeConnectionManager.close();\n this.#readConnectionManager.close();\n this.#dbm.close(this.#name);\n this.#closed = true;\n\n return promiseVoid;\n }\n\n get closed(): boolean {\n return this.#closed;\n }\n}\n\nclass SQLiteStoreRWBase {\n protected readonly _preparedStatements: SQLitePreparedStatements;\n readonly #release: () => void;\n #closed = false;\n\n constructor(\n preparedStatements: SQLitePreparedStatements,\n release: () => void,\n ) {\n this._preparedStatements = preparedStatements;\n this.#release = release;\n }\n\n has(key: string): Promise<boolean> {\n const unsafeValue = this.#getSql(key);\n return Promise.resolve(unsafeValue !== undefined);\n }\n\n get(key: string): Promise<ReadonlyJSONValue | undefined> {\n const unsafeValue = this.#getSql(key);\n if (unsafeValue === undefined) return promiseUndefined;\n const parsedValue = JSON.parse(unsafeValue) as ReadonlyJSONValue;\n const frozenValue = deepFreeze(parsedValue);\n return Promise.resolve(frozenValue);\n }\n\n #getSql(key: string): string | undefined {\n const rows = this._preparedStatements.get.all<{value: string}>(key);\n if (rows.length === 0) return undefined;\n return rows[0].value;\n }\n\n protected _release(): void {\n this.#closed = true;\n this.#release();\n }\n\n get closed(): boolean {\n return this.#closed;\n }\n}\n\nexport class SQLiteStoreRead extends SQLiteStoreRWBase implements Read {\n constructor(\n preparedStatements: SQLitePreparedStatements,\n release: () => void,\n ) {\n super(preparedStatements, release);\n\n // BEGIN\n this._preparedStatements.begin.run();\n }\n\n release(): void {\n // COMMIT\n this._preparedStatements.commit.run();\n\n this._release();\n }\n}\n\nexport class SQLiteStoreWrite extends SQLiteStoreRWBase implements Write {\n #committed = false;\n\n constructor(\n preparedStatements: SQLitePreparedStatements,\n release: () => void,\n ) {\n super(preparedStatements, release);\n\n // BEGIN IMMEDIATE grabs a RESERVED lock\n this._preparedStatements.beginImmediate.run();\n }\n\n put(key: string, value: ReadonlyJSONValue): Promise<void> {\n this._preparedStatements.put.run(key, JSON.stringify(value));\n return promiseVoid;\n }\n\n del(key: string): Promise<void> {\n this._preparedStatements.del.run(key);\n return promiseVoid;\n }\n\n commit(): Promise<void> {\n // COMMIT\n this._preparedStatements.commit.run();\n this.#committed = true;\n return promiseVoid;\n }\n\n release(): void {\n if (!this.#committed) {\n // ROLLBACK if not committed\n this._preparedStatements.rollback.run();\n }\n\n this._release();\n }\n}\n\nexport interface GenericSQLiteDatabaseManager {\n open(fileName: string): SQLiteDatabase;\n}\n\n// we replace non-alphanumeric characters with underscores\n// because SQLite doesn't allow them in database names\nconst safeFilename = (name: string) => name.replace(/[^a-zA-Z0-9]/g, '_');\n\n/**\n * Creates a function that returns new SQLite store instances.\n * This is the main entry point for using the SQLite store implementation.\n *\n * @param dbm The SQLite database manager implementation\n * @returns A function that creates new store instances\n */\nexport function createSQLiteStore(dbm: SQLiteDatabaseManager) {\n return (name: string, opts: SQLiteDatabaseManagerOptions) =>\n new SQLiteStore(name, dbm, opts);\n}\n\nexport type SQLiteDatabaseManagerOptions = {\n /**\n * The number of read connections to keep open.\n *\n * This must be greater than 1 to support concurrent reads.\n */\n readPoolSize: number;\n\n busyTimeout?: number | undefined;\n journalMode?: 'WAL' | 'DELETE' | undefined;\n synchronous?: 'NORMAL' | 'FULL' | undefined;\n readUncommitted?: boolean | undefined;\n};\n\nexport class SQLiteDatabaseManager {\n readonly #dbm: GenericSQLiteDatabaseManager;\n readonly #dbInstances = new Map<\n string,\n {\n instances: {\n db: SQLiteDatabase;\n preparedStatements: SQLitePreparedStatements;\n }[];\n }\n >();\n\n constructor(dbm: GenericSQLiteDatabaseManager) {\n this.#dbm = dbm;\n }\n\n clearAllStoresForTesting(): void {\n for (const [name] of this.#dbInstances) {\n this.destroy(name);\n }\n }\n\n open(\n name: string,\n opts: Omit<SQLiteDatabaseManagerOptions, 'poolSize'>,\n ): {db: SQLiteDatabase; preparedStatements: SQLitePreparedStatements} {\n const dbInstance = this.#dbInstances.get(name);\n\n const fileName = safeFilename(name);\n const newDb = this.#dbm.open(fileName);\n\n const txPreparedStatements = getTransactionPreparedStatements(newDb);\n\n const exec = (sql: string) => {\n const statement = newDb.prepare(sql);\n statement.run();\n statement.finalize();\n };\n\n if (!dbInstance) {\n // we only ensure the schema for the first open\n // the schema is the same for all connections\n this.#ensureSchema(exec, txPreparedStatements);\n }\n\n if (opts.busyTimeout !== undefined) {\n // we set a busy timeout to wait for write locks to be released\n exec(`PRAGMA busy_timeout = ${opts.busyTimeout}`);\n }\n if (opts.journalMode !== undefined) {\n // WAL allows concurrent readers (improves write throughput ~15x and read throughput ~1.5x)\n // but does not work on all platforms (e.g. Expo)\n exec(`PRAGMA journal_mode = ${opts.journalMode}`);\n }\n if (opts.synchronous !== undefined) {\n exec(`PRAGMA synchronous = ${opts.synchronous}`);\n }\n if (opts.readUncommitted !== undefined) {\n exec(\n `PRAGMA read_uncommitted = ${opts.readUncommitted ? 'true' : 'false'}`,\n );\n }\n\n // we prepare these after the schema is created\n const rwPreparedStatements = getRWPreparedStatements(newDb);\n\n const preparedStatements = {\n ...txPreparedStatements,\n ...rwPreparedStatements,\n };\n\n this.#dbInstances.set(name, {\n instances: [\n ...(dbInstance?.instances ?? []),\n {db: newDb, preparedStatements},\n ],\n });\n\n return {\n db: newDb,\n preparedStatements,\n };\n }\n\n close(name: string) {\n const dbInstance = this.#dbInstances.get(name);\n if (!dbInstance) return;\n\n for (const instance of dbInstance.instances) {\n for (const stmt of Object.values(instance.preparedStatements)) {\n stmt.finalize();\n }\n instance.db.close();\n }\n }\n\n destroy(name: string): void {\n const dbInstance = this.#dbInstances.get(name);\n if (!dbInstance) return;\n\n // we close all databases first before destroying\n for (const instance of dbInstance.instances) {\n for (const stmt of Object.values(instance.preparedStatements)) {\n stmt.finalize();\n }\n instance.db.close();\n }\n for (const instance of dbInstance.instances) {\n instance.db.destroy();\n }\n this.#dbInstances.delete(name);\n }\n\n #ensureSchema(\n exec: (sql: string) => void,\n preparedStatements: SQLiteTransactionPreparedStatements,\n ): void {\n preparedStatements.begin.run();\n\n try {\n // WITHOUT ROWID increases write throughput\n exec(\n 'CREATE TABLE IF NOT EXISTS entry (key TEXT PRIMARY KEY, value TEXT NOT NULL) WITHOUT ROWID',\n );\n preparedStatements.commit.run();\n } catch (e) {\n preparedStatements.rollback.run();\n throw e;\n }\n }\n}\n"],
|
|
5
|
-
"mappings": "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
|
|
3
|
+
"sources": ["../../replicache/src/expo/store.ts", "../../replicache/src/kv/sqlite-store.ts"],
|
|
4
|
+
"sourcesContent": ["import {\n deleteDatabaseSync,\n openDatabaseSync,\n type SQLiteBindParams,\n} from 'expo-sqlite';\nimport {\n createSQLiteStore,\n SQLiteDatabaseManager,\n type SQLiteDatabase,\n type SQLiteDatabaseManagerOptions,\n} from '../kv/sqlite-store.ts';\nimport type {StoreProvider} from '../kv/store.ts';\n\nexport const expoDbManagerInstance = new SQLiteDatabaseManager({\n open: fileName => {\n const db = openDatabaseSync(fileName);\n\n const genericDb: SQLiteDatabase = {\n close: () => db.closeSync(),\n destroy: () => {\n db.closeSync();\n deleteDatabaseSync(fileName);\n },\n prepare: (sql: string) => {\n const stmt = db.prepareSync(sql);\n return {\n run: (...params: unknown[]): void => {\n stmt.executeSync(params as SQLiteBindParams);\n },\n all: <T>(...params: unknown[]): T[] => {\n const result = stmt.executeSync(params as SQLiteBindParams);\n return result.getAllSync() as unknown as T[];\n },\n finalize: () => stmt.finalizeSync(),\n };\n },\n };\n\n return genericDb;\n },\n});\n\nexport function expoSQLiteStoreProvider(\n opts?: Partial<Omit<SQLiteDatabaseManagerOptions, 'journalMode'>>,\n): StoreProvider {\n return {\n create: (name: string) =>\n createSQLiteStore(expoDbManagerInstance)(name, {\n // we default to 3 read connections for mobile devices\n readPoolSize: 3,\n busyTimeout: 200,\n synchronous: 'NORMAL',\n readUncommitted: false,\n ...opts,\n // we override the journal mode to undefined because\n // setting it to WAL causes hanging COMMITs on Expo\n journalMode: undefined,\n }),\n drop: (name: string) => {\n expoDbManagerInstance.destroy(name);\n\n return Promise.resolve();\n },\n };\n}\n", "import {Lock, RWLock} from '@rocicorp/lock';\nimport type {ReadonlyJSONValue} from '../../../shared/src/json.ts';\nimport {\n promiseUndefined,\n promiseVoid,\n} from '../../../shared/src/resolved-promises.ts';\nimport {deepFreeze} from '../frozen-json.ts';\nimport type {Read, Store, Write} from './store.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 run(...params: unknown[]): void;\n all<T>(...params: unknown[]): T[];\n finalize(): 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\ntype SQLiteTransactionPreparedStatements = {\n begin: PreparedStatement;\n beginImmediate: PreparedStatement;\n commit: PreparedStatement;\n rollback: PreparedStatement;\n};\n\nconst getTransactionPreparedStatements = (\n db: SQLiteDatabase,\n): SQLiteTransactionPreparedStatements => ({\n begin: db.prepare('BEGIN'),\n beginImmediate: db.prepare('BEGIN IMMEDIATE'),\n commit: db.prepare('COMMIT'),\n rollback: db.prepare('ROLLBACK'),\n});\n\ntype SQLiteRWPreparedStatements = {\n get: PreparedStatement;\n put: PreparedStatement;\n del: PreparedStatement;\n};\n\nconst getRWPreparedStatements = (\n db: SQLiteDatabase,\n): SQLiteRWPreparedStatements => ({\n get: db.prepare('SELECT value FROM entry WHERE key = ?'),\n put: db.prepare('INSERT OR REPLACE INTO entry (key, value) VALUES (?, ?)'),\n del: db.prepare('DELETE FROM entry WHERE key = ?'),\n});\n\ntype SQLitePreparedStatements = SQLiteTransactionPreparedStatements &\n SQLiteRWPreparedStatements;\n\ninterface SQLiteConnectionManager {\n acquire(): Promise<{\n preparedStatements: SQLitePreparedStatements;\n release: () => void;\n }>;\n close(): void;\n}\n\ntype SQLitePreparedStatementPoolEntry = {\n db: SQLiteDatabase;\n lock: Lock;\n preparedStatements: SQLitePreparedStatements;\n};\n\n/**\n * Manages a pool of read-only SQLite connections.\n *\n * Each connection in the pool is protected by its own `Lock` instance which\n * guarantees that it is held by at most one reader at a time. Consumers call\n * {@link acquire} to get access to a set of prepared statements for a\n * connection and must invoke the provided `release` callback when they are\n * finished.\n *\n * The pool eagerly creates the configured number of connections up-front so\n * that the first `acquire` call never has to pay the connection setup cost.\n */\nclass SQLiteReadConnectionManager implements SQLiteConnectionManager {\n #pool: SQLitePreparedStatementPoolEntry[] = [];\n #nextIndex = 0;\n readonly #rwLock: RWLock;\n\n constructor(\n name: string,\n manager: SQLiteDatabaseManager,\n rwLock: RWLock,\n opts: SQLiteDatabaseManagerOptions,\n ) {\n if (opts.readPoolSize <= 1) {\n throw new Error('readPoolSize must be greater than 1');\n }\n\n this.#rwLock = rwLock;\n\n for (let i = 0; i < opts.readPoolSize; i++) {\n // create a new readonly SQLiteDatabase for each instance in the pool\n const {db, preparedStatements} = manager.open(name, opts);\n this.#pool.push({\n db,\n lock: new Lock(),\n preparedStatements,\n });\n }\n }\n\n /**\n * Acquire a round-robin read connection from the pool.\n *\n * The returned `release` callback **must** be invoked once the caller is done\n * using the prepared statements, otherwise other readers may be blocked\n * indefinitely.\n */\n async acquire(): Promise<{\n preparedStatements: SQLitePreparedStatements;\n release: () => void;\n }> {\n const slot = this.#nextIndex;\n this.#nextIndex = (this.#nextIndex + 1) % this.#pool.length;\n\n const entry = this.#pool[slot];\n\n // we have two levels of locking\n // 1. the RWLock to prevent concurrent read operations while a write is in progress\n // 2. the Lock to prevent concurrent read operations on the same connection\n const releaseRWLock = await this.#rwLock.read();\n const releaseLock = await entry.lock.lock();\n\n return {\n preparedStatements: entry.preparedStatements,\n release: () => {\n releaseRWLock();\n releaseLock();\n },\n };\n }\n\n /**\n * Finalizes all prepared statements and closes the underlying connections.\n * After calling this method the manager can no longer be used.\n */\n close(): void {\n for (const entry of this.#pool) {\n for (const stmt of Object.values(entry.preparedStatements)) {\n stmt.finalize();\n }\n entry.db.close();\n }\n this.#pool = [];\n }\n}\n\n/**\n * Manages a single write connection with an external RWLock.\n */\nclass SQLiteWriteConnectionManager implements SQLiteConnectionManager {\n readonly #rwLock: RWLock;\n readonly #preparedStatements: SQLitePreparedStatements;\n readonly #db: SQLiteDatabase;\n\n constructor(\n name: string,\n manager: SQLiteDatabaseManager,\n rwLock: RWLock,\n opts: SQLiteDatabaseManagerOptions,\n ) {\n const {db, preparedStatements} = manager.open(name, opts);\n this.#preparedStatements = preparedStatements;\n this.#db = db;\n this.#rwLock = rwLock;\n }\n\n async acquire(): Promise<{\n preparedStatements: SQLitePreparedStatements;\n release: () => void;\n }> {\n const release = await this.#rwLock.write();\n return {preparedStatements: this.#preparedStatements, release};\n }\n\n close(): void {\n for (const stmt of Object.values(this.#preparedStatements)) {\n stmt.finalize();\n }\n this.#db.close();\n }\n}\n\n/**\n * A SQLite-based Store implementation.\n *\n * This store provides a generic SQLite implementation that can be used with different\n * SQLite providers (expo-sqlite, better-sqlite3, etc). It implements the Store\n * interface using a single 'entry' table with key-value pairs.\n *\n * The store uses a single RWLock to prevent concurrent read and write operations.\n *\n * The store also uses a pool of read connections to allow concurrent reads with separate transactions.\n */\nexport class SQLiteStore implements Store {\n readonly #name: string;\n readonly #dbm: SQLiteDatabaseManager;\n readonly #writeConnectionManager: SQLiteConnectionManager;\n readonly #readConnectionManager: SQLiteConnectionManager;\n readonly #rwLock = new RWLock();\n\n #closed = false;\n\n constructor(\n name: string,\n dbm: SQLiteDatabaseManager,\n opts: SQLiteDatabaseManagerOptions,\n ) {\n this.#name = name;\n this.#dbm = dbm;\n\n this.#writeConnectionManager = new SQLiteWriteConnectionManager(\n name,\n dbm,\n this.#rwLock,\n opts,\n );\n this.#readConnectionManager = new SQLiteReadConnectionManager(\n name,\n dbm,\n this.#rwLock,\n opts,\n );\n }\n\n async read(): Promise<Read> {\n const {preparedStatements, release} =\n await this.#readConnectionManager.acquire();\n return new SQLiteStoreRead(preparedStatements, release);\n }\n\n async write(): Promise<Write> {\n const {preparedStatements, release} =\n await this.#writeConnectionManager.acquire();\n return new SQLiteStoreWrite(preparedStatements, release);\n }\n\n close(): Promise<void> {\n this.#writeConnectionManager.close();\n this.#readConnectionManager.close();\n this.#dbm.close(this.#name);\n this.#closed = true;\n\n return promiseVoid;\n }\n\n get closed(): boolean {\n return this.#closed;\n }\n}\n\nclass SQLiteStoreRWBase {\n protected readonly _preparedStatements: SQLitePreparedStatements;\n readonly #release: () => void;\n #closed = false;\n\n constructor(\n preparedStatements: SQLitePreparedStatements,\n release: () => void,\n ) {\n this._preparedStatements = preparedStatements;\n this.#release = release;\n }\n\n has(key: string): Promise<boolean> {\n const unsafeValue = this.#getSql(key);\n return Promise.resolve(unsafeValue !== undefined);\n }\n\n get(key: string): Promise<ReadonlyJSONValue | undefined> {\n const unsafeValue = this.#getSql(key);\n if (unsafeValue === undefined) return promiseUndefined;\n const parsedValue = JSON.parse(unsafeValue) as ReadonlyJSONValue;\n const frozenValue = deepFreeze(parsedValue);\n return Promise.resolve(frozenValue);\n }\n\n #getSql(key: string): string | undefined {\n const rows = this._preparedStatements.get.all<{value: string}>(key);\n if (rows.length === 0) return undefined;\n return rows[0].value;\n }\n\n protected _release(): void {\n this.#closed = true;\n this.#release();\n }\n\n get closed(): boolean {\n return this.#closed;\n }\n}\n\nexport class SQLiteStoreRead extends SQLiteStoreRWBase implements Read {\n constructor(\n preparedStatements: SQLitePreparedStatements,\n release: () => void,\n ) {\n super(preparedStatements, release);\n\n // BEGIN\n this._preparedStatements.begin.run();\n }\n\n release(): void {\n // COMMIT\n this._preparedStatements.commit.run();\n\n this._release();\n }\n}\n\nexport class SQLiteStoreWrite extends SQLiteStoreRWBase implements Write {\n #committed = false;\n\n constructor(\n preparedStatements: SQLitePreparedStatements,\n release: () => void,\n ) {\n super(preparedStatements, release);\n\n // BEGIN IMMEDIATE grabs a RESERVED lock\n this._preparedStatements.beginImmediate.run();\n }\n\n put(key: string, value: ReadonlyJSONValue): Promise<void> {\n this._preparedStatements.put.run(key, JSON.stringify(value));\n return promiseVoid;\n }\n\n del(key: string): Promise<void> {\n this._preparedStatements.del.run(key);\n return promiseVoid;\n }\n\n commit(): Promise<void> {\n // COMMIT\n this._preparedStatements.commit.run();\n this.#committed = true;\n return promiseVoid;\n }\n\n release(): void {\n if (!this.#committed) {\n // ROLLBACK if not committed\n this._preparedStatements.rollback.run();\n }\n\n this._release();\n }\n}\n\nexport interface GenericSQLiteDatabaseManager {\n open(fileName: string): SQLiteDatabase;\n}\n\n// we replace non-alphanumeric characters with underscores\n// because SQLite doesn't allow them in database names\nconst safeFilename = (name: string) => name.replace(/[^a-zA-Z0-9]/g, '_');\n\n/**\n * Creates a function that returns new SQLite store instances.\n * This is the main entry point for using the SQLite store implementation.\n *\n * @param dbm The SQLite database manager implementation\n * @returns A function that creates new store instances\n */\nexport function createSQLiteStore(dbm: SQLiteDatabaseManager) {\n return (name: string, opts: SQLiteDatabaseManagerOptions) =>\n new SQLiteStore(name, dbm, opts);\n}\n\nexport type SQLiteDatabaseManagerOptions = {\n /**\n * The number of read connections to keep open.\n *\n * This must be greater than 1 to support concurrent reads.\n */\n readPoolSize: number;\n\n busyTimeout?: number | undefined;\n journalMode?: 'WAL' | 'DELETE' | undefined;\n synchronous?: 'NORMAL' | 'FULL' | undefined;\n readUncommitted?: boolean | undefined;\n};\n\nexport class SQLiteDatabaseManager {\n readonly #dbm: GenericSQLiteDatabaseManager;\n readonly #dbInstances = new Map<\n string,\n {\n instances: {\n db: SQLiteDatabase;\n preparedStatements: SQLitePreparedStatements;\n }[];\n }\n >();\n\n constructor(dbm: GenericSQLiteDatabaseManager) {\n this.#dbm = dbm;\n }\n\n clearAllStoresForTesting(): void {\n for (const [name] of this.#dbInstances) {\n this.destroy(name);\n }\n }\n\n open(\n name: string,\n opts: Omit<SQLiteDatabaseManagerOptions, 'poolSize'>,\n ): {db: SQLiteDatabase; preparedStatements: SQLitePreparedStatements} {\n const dbInstance = this.#dbInstances.get(name);\n\n const fileName = safeFilename(name);\n const newDb = this.#dbm.open(fileName);\n\n const txPreparedStatements = getTransactionPreparedStatements(newDb);\n\n const exec = (sql: string) => {\n const statement = newDb.prepare(sql);\n statement.run();\n statement.finalize();\n };\n\n if (!dbInstance) {\n // we only ensure the schema for the first open\n // the schema is the same for all connections\n this.#ensureSchema(exec, txPreparedStatements);\n }\n\n if (opts.busyTimeout !== undefined) {\n // we set a busy timeout to wait for write locks to be released\n exec(`PRAGMA busy_timeout = ${opts.busyTimeout}`);\n }\n if (opts.journalMode !== undefined) {\n // WAL allows concurrent readers (improves write throughput ~15x and read throughput ~1.5x)\n // but does not work on all platforms (e.g. Expo)\n exec(`PRAGMA journal_mode = ${opts.journalMode}`);\n }\n if (opts.synchronous !== undefined) {\n exec(`PRAGMA synchronous = ${opts.synchronous}`);\n }\n if (opts.readUncommitted !== undefined) {\n exec(\n `PRAGMA read_uncommitted = ${opts.readUncommitted ? 'true' : 'false'}`,\n );\n }\n\n // we prepare these after the schema is created\n const rwPreparedStatements = getRWPreparedStatements(newDb);\n\n const preparedStatements = {\n ...txPreparedStatements,\n ...rwPreparedStatements,\n };\n\n this.#dbInstances.set(name, {\n instances: [\n ...(dbInstance?.instances ?? []),\n {db: newDb, preparedStatements},\n ],\n });\n\n return {\n db: newDb,\n preparedStatements,\n };\n }\n\n close(name: string) {\n const dbInstance = this.#dbInstances.get(name);\n if (!dbInstance) return;\n\n for (const instance of dbInstance.instances) {\n for (const stmt of Object.values(instance.preparedStatements)) {\n stmt.finalize();\n }\n instance.db.close();\n }\n }\n\n destroy(name: string): void {\n const dbInstance = this.#dbInstances.get(name);\n if (!dbInstance) return;\n\n // we close all databases first before destroying\n for (const instance of dbInstance.instances) {\n for (const stmt of Object.values(instance.preparedStatements)) {\n stmt.finalize();\n }\n instance.db.close();\n }\n for (const instance of dbInstance.instances) {\n instance.db.destroy();\n }\n this.#dbInstances.delete(name);\n }\n\n #ensureSchema(\n exec: (sql: string) => void,\n preparedStatements: SQLiteTransactionPreparedStatements,\n ): void {\n preparedStatements.begin.run();\n\n try {\n // WITHOUT ROWID increases write throughput\n exec(\n 'CREATE TABLE IF NOT EXISTS entry (key TEXT PRIMARY KEY, value TEXT NOT NULL) WITHOUT ROWID',\n );\n preparedStatements.commit.run();\n } catch (e) {\n preparedStatements.rollback.run();\n throw e;\n }\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/out/react.js
CHANGED
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
import {
|
|
2
2
|
Zero
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-MRT7XNEQ.js";
|
|
4
4
|
import "./chunk-MKB4RXL3.js";
|
|
5
5
|
import {
|
|
6
|
-
DEFAULT_TTL_MS
|
|
7
|
-
|
|
8
|
-
} from "./chunk-3I7CRZJP.js";
|
|
6
|
+
DEFAULT_TTL_MS
|
|
7
|
+
} from "./chunk-G442PJSB.js";
|
|
9
8
|
import {
|
|
10
9
|
hasOwn
|
|
11
10
|
} from "./chunk-SGW2EIVJ.js";
|
|
@@ -56,7 +55,8 @@ function ZeroInspector({ zero }) {
|
|
|
56
55
|
}
|
|
57
56
|
|
|
58
57
|
// ../zero-react/src/use-query.tsx
|
|
59
|
-
import { useSyncExternalStore } from "react";
|
|
58
|
+
import React, { useSyncExternalStore } from "react";
|
|
59
|
+
import { resolver } from "@rocicorp/resolver";
|
|
60
60
|
|
|
61
61
|
// ../shared/src/deep-clone.ts
|
|
62
62
|
function deepClone(value) {
|
|
@@ -140,6 +140,10 @@ function ZeroProvider({ children, init, ...props }) {
|
|
|
140
140
|
}
|
|
141
141
|
|
|
142
142
|
// ../zero-react/src/use-query.tsx
|
|
143
|
+
var reactUse = React.use;
|
|
144
|
+
var suspend = reactUse ? reactUse : (p) => {
|
|
145
|
+
throw p;
|
|
146
|
+
};
|
|
143
147
|
function useQuery(query, options) {
|
|
144
148
|
let enabled = true;
|
|
145
149
|
let ttl = DEFAULT_TTL_MS;
|
|
@@ -160,6 +164,40 @@ function useQuery(query, options) {
|
|
|
160
164
|
view.getSnapshot
|
|
161
165
|
);
|
|
162
166
|
}
|
|
167
|
+
function useSuspenseQuery(query, options) {
|
|
168
|
+
let enabled = true;
|
|
169
|
+
let ttl = DEFAULT_TTL_MS;
|
|
170
|
+
let suspendUntil = "partial";
|
|
171
|
+
if (typeof options === "boolean") {
|
|
172
|
+
enabled = options;
|
|
173
|
+
} else if (options) {
|
|
174
|
+
({
|
|
175
|
+
enabled = true,
|
|
176
|
+
ttl = DEFAULT_TTL_MS,
|
|
177
|
+
suspendUntil = "complete"
|
|
178
|
+
} = options);
|
|
179
|
+
}
|
|
180
|
+
const view = viewStore.getView(
|
|
181
|
+
useZero(),
|
|
182
|
+
query,
|
|
183
|
+
enabled,
|
|
184
|
+
ttl
|
|
185
|
+
);
|
|
186
|
+
const snapshot = useSyncExternalStore(
|
|
187
|
+
view.subscribeReactInternals,
|
|
188
|
+
view.getSnapshot,
|
|
189
|
+
view.getSnapshot
|
|
190
|
+
);
|
|
191
|
+
if (enabled) {
|
|
192
|
+
if (suspendUntil === "complete" && !view.complete) {
|
|
193
|
+
suspend(view.waitForComplete());
|
|
194
|
+
}
|
|
195
|
+
if (suspendUntil === "partial" && !view.nonEmpty) {
|
|
196
|
+
suspend(view.waitForNonEmpty());
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
return snapshot;
|
|
200
|
+
}
|
|
163
201
|
var emptyArray = [];
|
|
164
202
|
var disabledSubscriber = () => () => {
|
|
165
203
|
};
|
|
@@ -198,14 +236,18 @@ var ViewStore = class {
|
|
|
198
236
|
getSnapshot: () => getDefaultSnapshot(format.singular),
|
|
199
237
|
subscribeReactInternals: disabledSubscriber,
|
|
200
238
|
updateTTL: () => {
|
|
201
|
-
}
|
|
239
|
+
},
|
|
240
|
+
waitForComplete: () => Promise.resolve(),
|
|
241
|
+
waitForNonEmpty: () => Promise.resolve(),
|
|
242
|
+
complete: false,
|
|
243
|
+
nonEmpty: false
|
|
202
244
|
};
|
|
203
245
|
}
|
|
204
246
|
const hash = query.hash() + zero.clientID;
|
|
205
247
|
let existing = this.#views.get(hash);
|
|
206
248
|
if (!existing) {
|
|
207
|
-
query = query[delegateSymbol](zero.queryDelegate);
|
|
208
249
|
existing = new ViewWrapper(
|
|
250
|
+
zero,
|
|
209
251
|
query,
|
|
210
252
|
format,
|
|
211
253
|
ttl,
|
|
@@ -229,6 +271,7 @@ var ViewStore = class {
|
|
|
229
271
|
};
|
|
230
272
|
var viewStore = new ViewStore();
|
|
231
273
|
var ViewWrapper = class {
|
|
274
|
+
#zero;
|
|
232
275
|
#view;
|
|
233
276
|
#onDematerialized;
|
|
234
277
|
#onMaterialized;
|
|
@@ -237,7 +280,12 @@ var ViewWrapper = class {
|
|
|
237
280
|
#snapshot;
|
|
238
281
|
#reactInternals;
|
|
239
282
|
#ttl;
|
|
240
|
-
|
|
283
|
+
#complete = false;
|
|
284
|
+
#completeResolver = resolver();
|
|
285
|
+
#nonEmpty = false;
|
|
286
|
+
#nonEmptyResolver = resolver();
|
|
287
|
+
constructor(zero, query, format, ttl, onMaterialized, onDematerialized) {
|
|
288
|
+
this.#zero = zero;
|
|
241
289
|
this.#query = query;
|
|
242
290
|
this.#format = format;
|
|
243
291
|
this.#ttl = ttl;
|
|
@@ -250,6 +298,16 @@ var ViewWrapper = class {
|
|
|
250
298
|
#onData = (snap, resultType) => {
|
|
251
299
|
const data = snap === void 0 ? snap : deepClone(snap);
|
|
252
300
|
this.#snapshot = getSnapshot(this.#format.singular, data, resultType);
|
|
301
|
+
if (resultType === "complete") {
|
|
302
|
+
this.#complete = true;
|
|
303
|
+
this.#completeResolver.resolve();
|
|
304
|
+
this.#nonEmpty = true;
|
|
305
|
+
this.#nonEmptyResolver.resolve();
|
|
306
|
+
}
|
|
307
|
+
if (this.#format.singular ? this.#snapshot[0] !== void 0 : this.#snapshot[0].length !== 0) {
|
|
308
|
+
this.#nonEmpty = true;
|
|
309
|
+
this.#nonEmptyResolver.resolve();
|
|
310
|
+
}
|
|
253
311
|
for (const internals of this.#reactInternals) {
|
|
254
312
|
internals();
|
|
255
313
|
}
|
|
@@ -258,7 +316,7 @@ var ViewWrapper = class {
|
|
|
258
316
|
if (this.#view) {
|
|
259
317
|
return;
|
|
260
318
|
}
|
|
261
|
-
this.#view = this.#
|
|
319
|
+
this.#view = this.#zero.materialize(this.#query, { ttl: this.#ttl });
|
|
262
320
|
this.#view.addListener(this.#onData);
|
|
263
321
|
this.#onMaterialized(this);
|
|
264
322
|
};
|
|
@@ -276,8 +334,12 @@ var ViewWrapper = class {
|
|
|
276
334
|
if (this.#view === void 0) {
|
|
277
335
|
return;
|
|
278
336
|
}
|
|
279
|
-
this.#view
|
|
337
|
+
this.#view.destroy();
|
|
280
338
|
this.#view = void 0;
|
|
339
|
+
this.#complete = false;
|
|
340
|
+
this.#completeResolver = resolver();
|
|
341
|
+
this.#nonEmpty = false;
|
|
342
|
+
this.#nonEmptyResolver = resolver();
|
|
281
343
|
this.#onDematerialized();
|
|
282
344
|
}, 10);
|
|
283
345
|
}
|
|
@@ -287,6 +349,18 @@ var ViewWrapper = class {
|
|
|
287
349
|
this.#ttl = ttl;
|
|
288
350
|
this.#view?.updateTTL(ttl);
|
|
289
351
|
}
|
|
352
|
+
get complete() {
|
|
353
|
+
return this.#complete;
|
|
354
|
+
}
|
|
355
|
+
waitForComplete() {
|
|
356
|
+
return this.#completeResolver.promise;
|
|
357
|
+
}
|
|
358
|
+
get nonEmpty() {
|
|
359
|
+
return this.#nonEmpty;
|
|
360
|
+
}
|
|
361
|
+
waitForNonEmpty() {
|
|
362
|
+
return this.#nonEmptyResolver.promise;
|
|
363
|
+
}
|
|
290
364
|
};
|
|
291
365
|
|
|
292
366
|
// ../zero-react/src/use-zero-online.tsx
|
|
@@ -304,6 +378,7 @@ export {
|
|
|
304
378
|
ZeroProvider,
|
|
305
379
|
createUseZero,
|
|
306
380
|
useQuery,
|
|
381
|
+
useSuspenseQuery,
|
|
307
382
|
useZero,
|
|
308
383
|
useZeroOnline
|
|
309
384
|
};
|
package/out/react.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../zero-react/src/components/zero-inspector.tsx", "../../zero-react/src/use-query.tsx", "../../shared/src/deep-clone.ts", "../../zero-react/src/zero-provider.tsx", "../../zero-react/src/use-zero-online.tsx"],
|
|
4
|
-
"sourcesContent": ["import {lazy, Suspense, useState} from 'react';\nimport type {CustomMutatorDefs} from '../../../zero-client/src/client/custom.ts';\nimport type {Zero} from '../../../zero-client/src/client/zero.ts';\nimport type {Schema} from '../../../zero-schema/src/builder/schema-builder.ts';\nimport {MarkIcon} from './mark-icon.tsx';\n\n// eslint-disable-next-line @typescript-eslint/naming-convention\nconst Inspector = lazy(() => import('./inspector.tsx'));\n\nexport function ZeroInspector<\n S extends Schema,\n MD extends CustomMutatorDefs | undefined = undefined,\n>({zero}: {zero: Zero<S, MD>}): JSX.Element {\n const [show, setShow] = useState(false);\n return show ? (\n <Suspense fallback={<div>Loading Inspector...</div>}>\n <Inspector\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n zero={zero as any}\n onClose={() => setShow(false)}\n />\n </Suspense>\n ) : (\n <button\n onClick={() => setShow(!show)}\n style={{\n position: 'fixed',\n bottom: 0,\n right: 0,\n zIndex: 1000,\n padding: '5px',\n color: 'white',\n backgroundColor: '#333',\n borderTopLeftRadius: '8px',\n opacity: 0.95,\n }}\n >\n <MarkIcon\n style={{\n width: '20px',\n height: '20px',\n fill: 'currentColor',\n }}\n />\n </button>\n );\n}\n", "import {useSyncExternalStore} from 'react';\nimport {deepClone} from '../../shared/src/deep-clone.ts';\nimport type {Immutable} from '../../shared/src/immutable.ts';\nimport type {ReadonlyJSONValue} from '../../shared/src/json.ts';\nimport {Zero} from '../../zero-client/src/client/zero.ts';\nimport type {Schema} from '../../zero-schema/src/builder/schema-builder.ts';\nimport type {Format} from '../../zql/src/ivm/view.ts';\nimport {AbstractQuery} from '../../zql/src/query/query-impl.ts';\nimport {\n delegateSymbol,\n type HumanReadable,\n type Query,\n} from '../../zql/src/query/query.ts';\nimport {DEFAULT_TTL_MS, type TTL} from '../../zql/src/query/ttl.ts';\nimport type {ResultType, TypedView} from '../../zql/src/query/typed-view.ts';\nimport {useZero} from './zero-provider.tsx';\n\nexport type QueryResultDetails = Readonly<{\n type: ResultType;\n}>;\n\nexport type QueryResult<TReturn> = readonly [\n HumanReadable<TReturn>,\n QueryResultDetails,\n];\n\nexport type UseQueryOptions = {\n enabled?: boolean | undefined;\n /**\n * Time to live (TTL) in seconds. Controls how long query results are cached\n * after the query is removed. During this time, Zero continues to sync the query.\n * Default is 'never'.\n */\n ttl?: TTL | undefined;\n};\n\nexport function useQuery<\n TSchema extends Schema,\n TTable extends keyof TSchema['tables'] & string,\n TReturn,\n>(\n query: Query<TSchema, TTable, TReturn>,\n options?: UseQueryOptions | boolean,\n): QueryResult<TReturn> {\n let enabled = true;\n let ttl: TTL = DEFAULT_TTL_MS;\n if (typeof options === 'boolean') {\n enabled = options;\n } else if (options) {\n ({enabled = true, ttl = DEFAULT_TTL_MS} = options);\n }\n\n const view = viewStore.getView(\n useZero(),\n query as AbstractQuery<TSchema, TTable, TReturn>,\n enabled,\n ttl,\n );\n // https://react.dev/reference/react/useSyncExternalStore\n return useSyncExternalStore(\n view.subscribeReactInternals,\n view.getSnapshot,\n view.getSnapshot,\n );\n}\n\nconst emptyArray: unknown[] = [];\nconst disabledSubscriber = () => () => {};\n\nconst resultTypeUnknown = {type: 'unknown'} as const;\nconst resultTypeComplete = {type: 'complete'} as const;\n\nconst emptySnapshotSingularUnknown = [undefined, resultTypeUnknown] as const;\nconst emptySnapshotSingularComplete = [undefined, resultTypeComplete] as const;\nconst emptySnapshotPluralUnknown = [emptyArray, resultTypeUnknown] as const;\nconst emptySnapshotPluralComplete = [emptyArray, resultTypeComplete] as const;\n\nfunction getDefaultSnapshot<TReturn>(singular: boolean): QueryResult<TReturn> {\n return (\n singular ? emptySnapshotSingularUnknown : emptySnapshotPluralUnknown\n ) as QueryResult<TReturn>;\n}\n\n/**\n * Returns a new snapshot or one of the empty predefined ones. Returning the\n * predefined ones is important to prevent unnecessary re-renders in React.\n */\nfunction getSnapshot<TReturn>(\n singular: boolean,\n data: HumanReadable<TReturn>,\n resultType: string,\n): QueryResult<TReturn> {\n if (singular && data === undefined) {\n return (resultType === 'complete'\n ? emptySnapshotSingularComplete\n : emptySnapshotSingularUnknown) as unknown as QueryResult<TReturn>;\n }\n\n if (!singular && (data as unknown[]).length === 0) {\n return (\n resultType === 'complete'\n ? emptySnapshotPluralComplete\n : emptySnapshotPluralUnknown\n ) as QueryResult<TReturn>;\n }\n\n return [\n data,\n resultType === 'complete' ? resultTypeComplete : resultTypeUnknown,\n ];\n}\n\ndeclare const TESTING: boolean;\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype ViewWrapperAny = ViewWrapper<any, any, any>;\n\nconst allViews = new WeakMap<ViewStore, Map<string, ViewWrapperAny>>();\n\nexport function getAllViewsSizeForTesting(store: ViewStore): number {\n if (TESTING) {\n return allViews.get(store)?.size ?? 0;\n }\n return 0;\n}\n\n/**\n * A global store of all active views.\n *\n * React subscribes and unsubscribes to these views\n * via `useSyncExternalStore`.\n *\n * Managing views through `useEffect` or `useLayoutEffect` causes\n * inconsistencies because effects run after render.\n *\n * For example, if useQuery used use*Effect in the component below:\n * ```ts\n * function Foo({issueID}) {\n * const issue = useQuery(z.query.issue.where('id', issueID).one());\n * if (issue?.id !== undefined && issue.id !== issueID) {\n * console.log('MISMATCH!', issue.id, issueID);\n * }\n * }\n * ```\n *\n * `MISMATCH` will be printed whenever the `issueID` prop changes.\n *\n * This is because the component will render once with\n * the old state returned from `useQuery`. Then the effect inside\n * `useQuery` will run. The component will render again with the new\n * state. This inconsistent transition can cause unexpected results.\n *\n * Emulating `useEffect` via `useState` and `if` causes resource leaks.\n * That is:\n *\n * ```ts\n * function useQuery(q) {\n * const [oldHash, setOldHash] = useState();\n * if (hash(q) !== oldHash) {\n * // make new view\n * }\n *\n * useEffect(() => {\n * return () => view.destroy();\n * }, []);\n * }\n * ```\n *\n * I'm not sure why but in strict mode the cleanup function\n * fails to be called for the first instance of the view and only\n * cleans up later instances.\n *\n * Swapping `useState` to `useRef` has similar problems.\n */\nexport class ViewStore {\n #views = new Map<string, ViewWrapperAny>();\n\n constructor() {\n if (TESTING) {\n allViews.set(this, this.#views);\n }\n }\n\n getView<\n TSchema extends Schema,\n TTable extends keyof TSchema['tables'] & string,\n TReturn,\n >(\n zero: Zero<TSchema>,\n query: Query<TSchema, TTable, TReturn>,\n enabled: boolean,\n ttl: TTL,\n ): {\n getSnapshot: () => QueryResult<TReturn>;\n subscribeReactInternals: (internals: () => void) => () => void;\n updateTTL: (ttl: TTL) => void;\n } {\n const {format} = query;\n if (!enabled) {\n return {\n getSnapshot: () => getDefaultSnapshot(format.singular),\n subscribeReactInternals: disabledSubscriber,\n updateTTL: () => {},\n };\n }\n\n const hash = query.hash() + zero.clientID;\n let existing = this.#views.get(hash);\n if (!existing) {\n query = query[delegateSymbol](zero.queryDelegate);\n existing = new ViewWrapper(\n query,\n format,\n ttl,\n view => {\n const lastView = this.#views.get(hash);\n // I don't think this can happen\n // but lets guard against it so we don't\n // leak resources.\n if (lastView && lastView !== view) {\n throw new Error('View already exists');\n }\n this.#views.set(hash, view);\n },\n () => {\n this.#views.delete(hash);\n },\n ) as ViewWrapper<TSchema, TTable, TReturn>;\n this.#views.set(hash, existing);\n } else {\n existing.updateTTL(ttl);\n }\n return existing as ViewWrapper<TSchema, TTable, TReturn>;\n }\n}\n\nconst viewStore = new ViewStore();\n\n/**\n * This wraps and ref counts a view.\n *\n * The only signal we have from React as to whether or not it is\n * done with a view is when it calls `unsubscribe`.\n *\n * In non-strict-mode we can clean up the view as soon\n * as the listener count goes to 0.\n *\n * In strict-mode, the listener count will go to 0 then a\n * new listener for the same view is immediately added back.\n *\n * This is why the `onMaterialized` and `onDematerialized` callbacks exist --\n * they allow a view which React is still referencing to be added\n * back into the store when React re-subscribes to it.\n *\n * This wrapper also exists to deal with the various\n * `useSyncExternalStore` caveats that cause excessive\n * re-renders and materializations.\n *\n * See: https://react.dev/reference/react/useSyncExternalStore#caveats\n * Especially:\n * 1. The store snapshot returned by getSnapshot must be immutable. If the underlying store has mutable data, return a new immutable snapshot if the data has changed. Otherwise, return a cached last snapshot.\n * 2. If a different subscribe function is passed during a re-render, React will re-subscribe to the store using the newly passed subscribe function. You can prevent this by declaring subscribe outside the component.\n */\nclass ViewWrapper<\n TSchema extends Schema,\n TTable extends keyof TSchema['tables'] & string,\n TReturn,\n> {\n #view: TypedView<HumanReadable<TReturn>> | undefined;\n readonly #onDematerialized;\n readonly #onMaterialized;\n readonly #query: Query<TSchema, TTable, TReturn>;\n readonly #format: Format;\n #snapshot: QueryResult<TReturn>;\n #reactInternals: Set<() => void>;\n #ttl: TTL;\n\n constructor(\n query: Query<TSchema, TTable, TReturn>,\n format: Format,\n ttl: TTL,\n onMaterialized: (view: ViewWrapper<TSchema, TTable, TReturn>) => void,\n onDematerialized: () => void,\n ) {\n this.#query = query;\n this.#format = format;\n this.#ttl = ttl;\n this.#onMaterialized = onMaterialized;\n this.#onDematerialized = onDematerialized;\n this.#snapshot = getDefaultSnapshot(format.singular);\n this.#reactInternals = new Set();\n this.#materializeIfNeeded();\n }\n\n #onData = (\n snap: Immutable<HumanReadable<TReturn>>,\n resultType: ResultType,\n ) => {\n const data =\n snap === undefined\n ? snap\n : (deepClone(snap as ReadonlyJSONValue) as HumanReadable<TReturn>);\n this.#snapshot = getSnapshot(this.#format.singular, data, resultType);\n for (const internals of this.#reactInternals) {\n internals();\n }\n };\n\n #materializeIfNeeded = () => {\n if (this.#view) {\n return;\n }\n\n this.#view = this.#query.materialize(this.#ttl);\n this.#view.addListener(this.#onData);\n\n this.#onMaterialized(this);\n };\n\n getSnapshot = () => this.#snapshot;\n\n subscribeReactInternals = (internals: () => void): (() => void) => {\n this.#reactInternals.add(internals);\n this.#materializeIfNeeded();\n return () => {\n this.#reactInternals.delete(internals);\n\n // only schedule a cleanup task if we have no listeners left\n if (this.#reactInternals.size === 0) {\n setTimeout(() => {\n // Someone re-registered a listener on this view before the timeout elapsed.\n // This happens often in strict-mode which forces a component\n // to mount, unmount, remount.\n if (this.#reactInternals.size > 0) {\n return;\n }\n // We already destroyed the view\n if (this.#view === undefined) {\n return;\n }\n this.#view?.destroy();\n this.#view = undefined;\n this.#onDematerialized();\n }, 10);\n }\n };\n };\n\n updateTTL(ttl: TTL): void {\n this.#ttl = ttl;\n this.#view?.updateTTL(ttl);\n }\n}\n", "import {hasOwn} from './has-own.ts';\nimport type {JSONValue, ReadonlyJSONValue} from './json.ts';\n\nexport function deepClone(value: ReadonlyJSONValue): JSONValue {\n const seen: Array<ReadonlyJSONValue> = [];\n return internalDeepClone(value, seen);\n}\n\nexport function internalDeepClone(\n value: ReadonlyJSONValue,\n seen: Array<ReadonlyJSONValue>,\n): JSONValue {\n switch (typeof value) {\n case 'boolean':\n case 'number':\n case 'string':\n case 'undefined':\n return value;\n case 'object': {\n if (value === null) {\n return null;\n }\n if (seen.includes(value)) {\n throw new Error('Cyclic object');\n }\n seen.push(value);\n if (Array.isArray(value)) {\n const rv = value.map(v => internalDeepClone(v, seen));\n seen.pop();\n return rv;\n }\n\n const obj: JSONValue = {};\n\n for (const k in value) {\n if (hasOwn(value, k)) {\n const v = (value as Record<string, ReadonlyJSONValue>)[k];\n if (v !== undefined) {\n obj[k] = internalDeepClone(v, seen);\n }\n }\n }\n seen.pop();\n return obj;\n }\n\n default:\n throw new Error(`Invalid type: ${typeof value}`);\n }\n}\n", "import {\n createContext,\n useContext,\n useEffect,\n useState,\n type ReactNode,\n} from 'react';\nimport {Zero} from '../../zero-client/src/client/zero.ts';\nimport type {Schema} from '../../zero-schema/src/builder/schema-builder.ts';\nimport type {CustomMutatorDefs} from '../../zero-client/src/client/custom.ts';\nimport type {ZeroOptions} from '../../zero-client/src/client/options.ts';\n\n// eslint-disable-next-line @typescript-eslint/naming-convention\nconst ZeroContext = createContext<unknown | undefined>(undefined);\n\nexport function useZero<\n S extends Schema,\n MD extends CustomMutatorDefs | undefined = undefined,\n>(): Zero<S, MD> {\n const zero = useContext(ZeroContext);\n if (zero === undefined) {\n throw new Error('useZero must be used within a ZeroProvider');\n }\n return zero as Zero<S, MD>;\n}\n\nexport function createUseZero<\n S extends Schema,\n MD extends CustomMutatorDefs | undefined = undefined,\n>() {\n return () => useZero<S, MD>();\n}\n\nexport type ZeroProviderProps<\n S extends Schema,\n MD extends CustomMutatorDefs | undefined = undefined,\n> = (ZeroOptions<S, MD> | {zero: Zero<S, MD>}) & {\n init?: (zero: Zero<S, MD>) => void;\n children: ReactNode;\n};\n\nexport function ZeroProvider<\n S extends Schema,\n MD extends CustomMutatorDefs | undefined = undefined,\n>({children, init, ...props}: ZeroProviderProps<S, MD>) {\n const [zero, setZero] = useState<Zero<S, MD> | undefined>(\n 'zero' in props ? props.zero : undefined,\n );\n\n // If Zero is not passed in, we construct it, but only client-side.\n // Zero doesn't really work SSR today so this is usually the right thing.\n // When we support Zero SSR this will either become a breaking change or\n // more likely server support will be opt-in with a new prop on this\n // component.\n useEffect(() => {\n if ('zero' in props) {\n setZero(props.zero);\n return;\n }\n\n const z = new Zero(props);\n init?.(z);\n setZero(z);\n\n return () => {\n void z.close();\n setZero(undefined);\n };\n }, [init, ...Object.values(props)]);\n\n return (\n zero && <ZeroContext.Provider value={zero}>{children}</ZeroContext.Provider>\n );\n}\n", "import {useSyncExternalStore} from 'react';\nimport {useZero} from './zero-provider.tsx';\n\n/**\n * Hook to subscribe to the online status of the Zero instance.\n *\n * This is useful when you want to update state based on the online status.\n *\n * @returns The online status of the Zero instance.\n */\nexport function useZeroOnline(): boolean {\n const zero = useZero();\n return useSyncExternalStore(\n zero.onOnline,\n () => zero.online,\n () => zero.online,\n );\n}\n"],
|
|
5
|
-
"mappings": "
|
|
4
|
+
"sourcesContent": ["import {lazy, Suspense, useState} from 'react';\nimport type {CustomMutatorDefs} from '../../../zero-client/src/client/custom.ts';\nimport type {Zero} from '../../../zero-client/src/client/zero.ts';\nimport type {Schema} from '../../../zero-schema/src/builder/schema-builder.ts';\nimport {MarkIcon} from './mark-icon.tsx';\n\n// eslint-disable-next-line @typescript-eslint/naming-convention\nconst Inspector = lazy(() => import('./inspector.tsx'));\n\nexport function ZeroInspector<\n S extends Schema,\n MD extends CustomMutatorDefs | undefined = undefined,\n>({zero}: {zero: Zero<S, MD>}): JSX.Element {\n const [show, setShow] = useState(false);\n return show ? (\n <Suspense fallback={<div>Loading Inspector...</div>}>\n <Inspector\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n zero={zero as any}\n onClose={() => setShow(false)}\n />\n </Suspense>\n ) : (\n <button\n onClick={() => setShow(!show)}\n style={{\n position: 'fixed',\n bottom: 0,\n right: 0,\n zIndex: 1000,\n padding: '5px',\n color: 'white',\n backgroundColor: '#333',\n borderTopLeftRadius: '8px',\n opacity: 0.95,\n }}\n >\n <MarkIcon\n style={{\n width: '20px',\n height: '20px',\n fill: 'currentColor',\n }}\n />\n </button>\n );\n}\n", "import React, {useSyncExternalStore} from 'react';\nimport {resolver} from '@rocicorp/resolver';\nimport {deepClone} from '../../shared/src/deep-clone.ts';\nimport type {Immutable} from '../../shared/src/immutable.ts';\nimport type {ReadonlyJSONValue} from '../../shared/src/json.ts';\nimport {Zero} from '../../zero-client/src/client/zero.ts';\nimport type {Schema} from '../../zero-schema/src/builder/schema-builder.ts';\nimport type {Format} from '../../zql/src/ivm/view.ts';\nimport {AbstractQuery} from '../../zql/src/query/query-impl.ts';\nimport {type HumanReadable, type Query} from '../../zql/src/query/query.ts';\nimport {DEFAULT_TTL_MS, type TTL} from '../../zql/src/query/ttl.ts';\nimport type {ResultType, TypedView} from '../../zql/src/query/typed-view.ts';\nimport {useZero} from './zero-provider.tsx';\n\nexport type QueryResultDetails = Readonly<{\n type: ResultType;\n}>;\n\nexport type QueryResult<TReturn> = readonly [\n HumanReadable<TReturn>,\n QueryResultDetails,\n];\n\nexport type UseQueryOptions = {\n enabled?: boolean | undefined;\n /**\n * Time to live (TTL) in seconds. Controls how long query results are cached\n * after the query is removed. During this time, Zero continues to sync the query.\n * Default is 'never'.\n */\n ttl?: TTL | undefined;\n};\n\nexport type UseSuspenseQueryOptions = UseQueryOptions & {\n /**\n * Whether to suspend until:\n * - 'partial': the query has partial results (partial array or defined\n * value for singular results) which may be of result type 'unknown',\n * or the query result type is 'complete' (in which case results may be\n * empty). This is useful for suspending until there are partial\n * optimistic local results, or the query has completed loading from the\n * server.\n * - 'complete': the query result type is 'complete'.\n *\n * Default is 'partial'.\n */\n suspendUntil?: 'complete' | 'partial';\n};\n\n// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion\nconst reactUse = (React as unknown as {use?: (p: Promise<unknown>) => void})\n .use;\nconst suspend: (p: Promise<unknown>) => void = reactUse\n ? reactUse\n : p => {\n throw p;\n };\n\nexport function useQuery<\n TSchema extends Schema,\n TTable extends keyof TSchema['tables'] & string,\n TReturn,\n>(\n query: Query<TSchema, TTable, TReturn>,\n options?: UseQueryOptions | boolean,\n): QueryResult<TReturn> {\n let enabled = true;\n let ttl: TTL = DEFAULT_TTL_MS;\n if (typeof options === 'boolean') {\n enabled = options;\n } else if (options) {\n ({enabled = true, ttl = DEFAULT_TTL_MS} = options);\n }\n\n const view = viewStore.getView(\n useZero(),\n query as AbstractQuery<TSchema, TTable, TReturn>,\n enabled,\n ttl,\n );\n // https://react.dev/reference/react/useSyncExternalStore\n return useSyncExternalStore(\n view.subscribeReactInternals,\n view.getSnapshot,\n view.getSnapshot,\n );\n}\n\nexport function useSuspenseQuery<\n TSchema extends Schema,\n TTable extends keyof TSchema['tables'] & string,\n TReturn,\n>(\n query: Query<TSchema, TTable, TReturn>,\n options?: UseSuspenseQueryOptions | boolean,\n): QueryResult<TReturn> {\n let enabled = true;\n let ttl: TTL = DEFAULT_TTL_MS;\n let suspendUntil: 'complete' | 'partial' = 'partial';\n if (typeof options === 'boolean') {\n enabled = options;\n } else if (options) {\n ({\n enabled = true,\n ttl = DEFAULT_TTL_MS,\n suspendUntil = 'complete',\n } = options);\n }\n\n const view = viewStore.getView(\n useZero(),\n query as AbstractQuery<TSchema, TTable, TReturn>,\n enabled,\n ttl,\n );\n // https://react.dev/reference/react/useSyncExternalStore\n const snapshot = useSyncExternalStore(\n view.subscribeReactInternals,\n view.getSnapshot,\n view.getSnapshot,\n );\n\n if (enabled) {\n if (suspendUntil === 'complete' && !view.complete) {\n suspend(view.waitForComplete());\n }\n\n if (suspendUntil === 'partial' && !view.nonEmpty) {\n suspend(view.waitForNonEmpty());\n }\n }\n\n return snapshot;\n}\n\nconst emptyArray: unknown[] = [];\nconst disabledSubscriber = () => () => {};\n\nconst resultTypeUnknown = {type: 'unknown'} as const;\nconst resultTypeComplete = {type: 'complete'} as const;\n\nconst emptySnapshotSingularUnknown = [undefined, resultTypeUnknown] as const;\nconst emptySnapshotSingularComplete = [undefined, resultTypeComplete] as const;\nconst emptySnapshotPluralUnknown = [emptyArray, resultTypeUnknown] as const;\nconst emptySnapshotPluralComplete = [emptyArray, resultTypeComplete] as const;\n\nfunction getDefaultSnapshot<TReturn>(singular: boolean): QueryResult<TReturn> {\n return (\n singular ? emptySnapshotSingularUnknown : emptySnapshotPluralUnknown\n ) as QueryResult<TReturn>;\n}\n\n/**\n * Returns a new snapshot or one of the empty predefined ones. Returning the\n * predefined ones is important to prevent unnecessary re-renders in React.\n */\nfunction getSnapshot<TReturn>(\n singular: boolean,\n data: HumanReadable<TReturn>,\n resultType: string,\n): QueryResult<TReturn> {\n if (singular && data === undefined) {\n return (resultType === 'complete'\n ? emptySnapshotSingularComplete\n : emptySnapshotSingularUnknown) as unknown as QueryResult<TReturn>;\n }\n\n if (!singular && (data as unknown[]).length === 0) {\n return (\n resultType === 'complete'\n ? emptySnapshotPluralComplete\n : emptySnapshotPluralUnknown\n ) as QueryResult<TReturn>;\n }\n\n return [\n data,\n resultType === 'complete' ? resultTypeComplete : resultTypeUnknown,\n ];\n}\n\ndeclare const TESTING: boolean;\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype ViewWrapperAny = ViewWrapper<any, any, any>;\n\nconst allViews = new WeakMap<ViewStore, Map<string, ViewWrapperAny>>();\n\nexport function getAllViewsSizeForTesting(store: ViewStore): number {\n if (TESTING) {\n return allViews.get(store)?.size ?? 0;\n }\n return 0;\n}\n\n/**\n * A global store of all active views.\n *\n * React subscribes and unsubscribes to these views\n * via `useSyncExternalStore`.\n *\n * Managing views through `useEffect` or `useLayoutEffect` causes\n * inconsistencies because effects run after render.\n *\n * For example, if useQuery used use*Effect in the component below:\n * ```ts\n * function Foo({issueID}) {\n * const issue = useQuery(z.query.issue.where('id', issueID).one());\n * if (issue?.id !== undefined && issue.id !== issueID) {\n * console.log('MISMATCH!', issue.id, issueID);\n * }\n * }\n * ```\n *\n * `MISMATCH` will be printed whenever the `issueID` prop changes.\n *\n * This is because the component will render once with\n * the old state returned from `useQuery`. Then the effect inside\n * `useQuery` will run. The component will render again with the new\n * state. This inconsistent transition can cause unexpected results.\n *\n * Emulating `useEffect` via `useState` and `if` causes resource leaks.\n * That is:\n *\n * ```ts\n * function useQuery(q) {\n * const [oldHash, setOldHash] = useState();\n * if (hash(q) !== oldHash) {\n * // make new view\n * }\n *\n * useEffect(() => {\n * return () => view.destroy();\n * }, []);\n * }\n * ```\n *\n * I'm not sure why but in strict mode the cleanup function\n * fails to be called for the first instance of the view and only\n * cleans up later instances.\n *\n * Swapping `useState` to `useRef` has similar problems.\n */\nexport class ViewStore {\n #views = new Map<string, ViewWrapperAny>();\n\n constructor() {\n if (TESTING) {\n allViews.set(this, this.#views);\n }\n }\n\n getView<\n TSchema extends Schema,\n TTable extends keyof TSchema['tables'] & string,\n TReturn,\n >(\n zero: Zero<TSchema>,\n query: Query<TSchema, TTable, TReturn>,\n enabled: boolean,\n ttl: TTL,\n ): {\n getSnapshot: () => QueryResult<TReturn>;\n subscribeReactInternals: (internals: () => void) => () => void;\n updateTTL: (ttl: TTL) => void;\n waitForComplete: () => Promise<void>;\n waitForNonEmpty: () => Promise<void>;\n complete: boolean;\n nonEmpty: boolean;\n } {\n const {format} = query;\n if (!enabled) {\n return {\n getSnapshot: () => getDefaultSnapshot(format.singular),\n subscribeReactInternals: disabledSubscriber,\n updateTTL: () => {},\n waitForComplete: () => Promise.resolve(),\n waitForNonEmpty: () => Promise.resolve(),\n complete: false,\n nonEmpty: false,\n };\n }\n\n const hash = query.hash() + zero.clientID;\n let existing = this.#views.get(hash);\n if (!existing) {\n existing = new ViewWrapper(\n zero,\n query,\n format,\n ttl,\n view => {\n const lastView = this.#views.get(hash);\n // I don't think this can happen\n // but lets guard against it so we don't\n // leak resources.\n if (lastView && lastView !== view) {\n throw new Error('View already exists');\n }\n this.#views.set(hash, view);\n },\n () => {\n this.#views.delete(hash);\n },\n );\n this.#views.set(hash, existing);\n } else {\n existing.updateTTL(ttl);\n }\n return existing as ViewWrapper<TSchema, TTable, TReturn>;\n }\n}\n\nconst viewStore = new ViewStore();\n\n/**\n * This wraps and ref counts a view.\n *\n * The only signal we have from React as to whether or not it is\n * done with a view is when it calls `unsubscribe`.\n *\n * In non-strict-mode we can clean up the view as soon\n * as the listener count goes to 0.\n *\n * In strict-mode, the listener count will go to 0 then a\n * new listener for the same view is immediately added back.\n *\n * This is why the `onMaterialized` and `onDematerialized` callbacks exist --\n * they allow a view which React is still referencing to be added\n * back into the store when React re-subscribes to it.\n *\n * This wrapper also exists to deal with the various\n * `useSyncExternalStore` caveats that cause excessive\n * re-renders and materializations.\n *\n * See: https://react.dev/reference/react/useSyncExternalStore#caveats\n * Especially:\n * 1. The store snapshot returned by getSnapshot must be immutable. If the underlying store has mutable data, return a new immutable snapshot if the data has changed. Otherwise, return a cached last snapshot.\n * 2. If a different subscribe function is passed during a re-render, React will re-subscribe to the store using the newly passed subscribe function. You can prevent this by declaring subscribe outside the component.\n */\nclass ViewWrapper<\n TSchema extends Schema,\n TTable extends keyof TSchema['tables'] & string,\n TReturn,\n> {\n #zero: Zero<TSchema>;\n #view: TypedView<HumanReadable<TReturn>> | undefined;\n readonly #onDematerialized;\n readonly #onMaterialized;\n readonly #query: Query<TSchema, TTable, TReturn>;\n readonly #format: Format;\n #snapshot: QueryResult<TReturn>;\n #reactInternals: Set<() => void>;\n #ttl: TTL;\n #complete = false;\n #completeResolver = resolver<void>();\n #nonEmpty = false;\n #nonEmptyResolver = resolver<void>();\n\n constructor(\n zero: Zero<TSchema>,\n query: Query<TSchema, TTable, TReturn>,\n format: Format,\n ttl: TTL,\n onMaterialized: (view: ViewWrapper<TSchema, TTable, TReturn>) => void,\n onDematerialized: () => void,\n ) {\n this.#zero = zero;\n this.#query = query;\n this.#format = format;\n this.#ttl = ttl;\n this.#onMaterialized = onMaterialized;\n this.#onDematerialized = onDematerialized;\n this.#snapshot = getDefaultSnapshot(format.singular);\n this.#reactInternals = new Set();\n this.#materializeIfNeeded();\n }\n\n #onData = (\n snap: Immutable<HumanReadable<TReturn>>,\n resultType: ResultType,\n ) => {\n const data =\n snap === undefined\n ? snap\n : (deepClone(snap as ReadonlyJSONValue) as HumanReadable<TReturn>);\n this.#snapshot = getSnapshot(this.#format.singular, data, resultType);\n if (resultType === 'complete') {\n this.#complete = true;\n this.#completeResolver.resolve();\n this.#nonEmpty = true;\n this.#nonEmptyResolver.resolve();\n }\n\n if (\n this.#format.singular\n ? this.#snapshot[0] !== undefined\n : (this.#snapshot[0] as unknown[]).length !== 0\n ) {\n this.#nonEmpty = true;\n this.#nonEmptyResolver.resolve();\n }\n\n for (const internals of this.#reactInternals) {\n internals();\n }\n };\n\n #materializeIfNeeded = () => {\n if (this.#view) {\n return;\n }\n\n this.#view = this.#zero.materialize(this.#query, {ttl: this.#ttl});\n this.#view.addListener(this.#onData);\n\n this.#onMaterialized(this);\n };\n\n getSnapshot = () => this.#snapshot;\n\n subscribeReactInternals = (internals: () => void): (() => void) => {\n this.#reactInternals.add(internals);\n this.#materializeIfNeeded();\n return () => {\n this.#reactInternals.delete(internals);\n\n // only schedule a cleanup task if we have no listeners left\n if (this.#reactInternals.size === 0) {\n setTimeout(() => {\n // Someone re-registered a listener on this view before the timeout elapsed.\n // This happens often in strict-mode which forces a component\n // to mount, unmount, remount.\n if (this.#reactInternals.size > 0) {\n return;\n }\n // We already destroyed the view\n if (this.#view === undefined) {\n return;\n }\n this.#view.destroy();\n this.#view = undefined;\n this.#complete = false;\n this.#completeResolver = resolver();\n this.#nonEmpty = false;\n this.#nonEmptyResolver = resolver();\n this.#onDematerialized();\n }, 10);\n }\n };\n };\n\n updateTTL(ttl: TTL): void {\n this.#ttl = ttl;\n this.#view?.updateTTL(ttl);\n }\n\n get complete() {\n return this.#complete;\n }\n\n waitForComplete(): Promise<void> {\n return this.#completeResolver.promise;\n }\n\n get nonEmpty() {\n return this.#nonEmpty;\n }\n\n waitForNonEmpty(): Promise<void> {\n return this.#nonEmptyResolver.promise;\n }\n}\n", "import {hasOwn} from './has-own.ts';\nimport type {JSONValue, ReadonlyJSONValue} from './json.ts';\n\nexport function deepClone(value: ReadonlyJSONValue): JSONValue {\n const seen: Array<ReadonlyJSONValue> = [];\n return internalDeepClone(value, seen);\n}\n\nexport function internalDeepClone(\n value: ReadonlyJSONValue,\n seen: Array<ReadonlyJSONValue>,\n): JSONValue {\n switch (typeof value) {\n case 'boolean':\n case 'number':\n case 'string':\n case 'undefined':\n return value;\n case 'object': {\n if (value === null) {\n return null;\n }\n if (seen.includes(value)) {\n throw new Error('Cyclic object');\n }\n seen.push(value);\n if (Array.isArray(value)) {\n const rv = value.map(v => internalDeepClone(v, seen));\n seen.pop();\n return rv;\n }\n\n const obj: JSONValue = {};\n\n for (const k in value) {\n if (hasOwn(value, k)) {\n const v = (value as Record<string, ReadonlyJSONValue>)[k];\n if (v !== undefined) {\n obj[k] = internalDeepClone(v, seen);\n }\n }\n }\n seen.pop();\n return obj;\n }\n\n default:\n throw new Error(`Invalid type: ${typeof value}`);\n }\n}\n", "import {\n createContext,\n useContext,\n useEffect,\n useState,\n type ReactNode,\n} from 'react';\nimport {Zero} from '../../zero-client/src/client/zero.ts';\nimport type {Schema} from '../../zero-schema/src/builder/schema-builder.ts';\nimport type {CustomMutatorDefs} from '../../zero-client/src/client/custom.ts';\nimport type {ZeroOptions} from '../../zero-client/src/client/options.ts';\n\n// eslint-disable-next-line @typescript-eslint/naming-convention\nconst ZeroContext = createContext<unknown | undefined>(undefined);\n\nexport function useZero<\n S extends Schema,\n MD extends CustomMutatorDefs | undefined = undefined,\n>(): Zero<S, MD> {\n const zero = useContext(ZeroContext);\n if (zero === undefined) {\n throw new Error('useZero must be used within a ZeroProvider');\n }\n return zero as Zero<S, MD>;\n}\n\nexport function createUseZero<\n S extends Schema,\n MD extends CustomMutatorDefs | undefined = undefined,\n>() {\n return () => useZero<S, MD>();\n}\n\nexport type ZeroProviderProps<\n S extends Schema,\n MD extends CustomMutatorDefs | undefined = undefined,\n> = (ZeroOptions<S, MD> | {zero: Zero<S, MD>}) & {\n init?: (zero: Zero<S, MD>) => void;\n children: ReactNode;\n};\n\nexport function ZeroProvider<\n S extends Schema,\n MD extends CustomMutatorDefs | undefined = undefined,\n>({children, init, ...props}: ZeroProviderProps<S, MD>) {\n const [zero, setZero] = useState<Zero<S, MD> | undefined>(\n 'zero' in props ? props.zero : undefined,\n );\n\n // If Zero is not passed in, we construct it, but only client-side.\n // Zero doesn't really work SSR today so this is usually the right thing.\n // When we support Zero SSR this will either become a breaking change or\n // more likely server support will be opt-in with a new prop on this\n // component.\n useEffect(() => {\n if ('zero' in props) {\n setZero(props.zero);\n return;\n }\n\n const z = new Zero(props);\n init?.(z);\n setZero(z);\n\n return () => {\n void z.close();\n setZero(undefined);\n };\n }, [init, ...Object.values(props)]);\n\n return (\n zero && <ZeroContext.Provider value={zero}>{children}</ZeroContext.Provider>\n );\n}\n", "import {useSyncExternalStore} from 'react';\nimport {useZero} from './zero-provider.tsx';\n\n/**\n * Hook to subscribe to the online status of the Zero instance.\n *\n * This is useful when you want to update state based on the online status.\n *\n * @returns The online status of the Zero instance.\n */\nexport function useZeroOnline(): boolean {\n const zero = useZero();\n return useSyncExternalStore(\n zero.onOnline,\n () => zero.online,\n () => zero.online,\n );\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["useState", "jsx", "useState", "useSyncExternalStore", "useSyncExternalStore"]
|
|
7
7
|
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { SQLiteDatabaseManager, type SQLiteDatabaseManagerOptions } from '../kv/sqlite-store.ts';
|
|
2
|
+
import type { StoreProvider } from '../kv/store.ts';
|
|
3
|
+
export declare const expoDbManagerInstance: SQLiteDatabaseManager;
|
|
4
|
+
export declare function expoSQLiteStoreProvider(opts?: Partial<Omit<SQLiteDatabaseManagerOptions, 'journalMode'>>): StoreProvider;
|
|
5
|
+
//# sourceMappingURL=store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../../../../replicache/src/expo/store.ts"],"names":[],"mappings":"AAKA,OAAO,EAEL,qBAAqB,EAErB,KAAK,4BAA4B,EAClC,MAAM,uBAAuB,CAAC;AAC/B,OAAO,KAAK,EAAC,aAAa,EAAC,MAAM,gBAAgB,CAAC;AAElD,eAAO,MAAM,qBAAqB,uBA2BhC,CAAC;AAEH,wBAAgB,uBAAuB,CACrC,IAAI,CAAC,EAAE,OAAO,CAAC,IAAI,CAAC,4BAA4B,EAAE,aAAa,CAAC,CAAC,GAChE,aAAa,CAoBf"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { LogContext } from '@rocicorp/logger';
|
|
2
|
+
import type { StoreProvider } from './kv/store.ts';
|
|
3
|
+
export declare function getKVStoreProvider(lc: LogContext, kvStore: 'mem' | 'idb' | StoreProvider | undefined): StoreProvider;
|
|
4
|
+
//# sourceMappingURL=get-kv-store-provider.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"get-kv-store-provider.d.ts","sourceRoot":"","sources":["../../../../replicache/src/get-kv-store-provider.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,UAAU,EAAC,MAAM,kBAAkB,CAAC;AAMjD,OAAO,KAAK,EAAC,aAAa,EAAC,MAAM,eAAe,CAAC;AAEjD,wBAAgB,kBAAkB,CAChC,EAAE,EAAE,UAAU,EACd,OAAO,EAAE,KAAK,GAAG,KAAK,GAAG,aAAa,GAAG,SAAS,GACjD,aAAa,CAgBf"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"http-status-unauthorized.d.ts","sourceRoot":"","sources":["../../../../replicache/src/http-status-unauthorized.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,sBAAsB,MAAM,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Returns the name of the IDB database that will be used for a particular Replicache instance.
|
|
3
|
+
* @param name The name of the Replicache instance (i.e., the `name` field of `ReplicacheOptions`).
|
|
4
|
+
* @param schemaVersion The schema version of the database (i.e., the `schemaVersion` field of `ReplicacheOptions`).
|
|
5
|
+
* @returns
|
|
6
|
+
*/
|
|
7
|
+
export declare function makeIDBName(name: string, schemaVersion?: string): string;
|
|
8
|
+
declare function makeIDBNameInternal(name: string, schemaVersion: string | undefined, formatVersion: number): string;
|
|
9
|
+
export { makeIDBNameInternal as makeIDBNameForTesting };
|
|
10
|
+
//# sourceMappingURL=make-idb-name.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"make-idb-name.d.ts","sourceRoot":"","sources":["../../../../replicache/src/make-idb-name.ts"],"names":[],"mappings":"AAEA;;;;;GAKG;AAEH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,aAAa,CAAC,EAAE,MAAM,GAAG,MAAM,CAExE;AAED,iBAAS,mBAAmB,CAC1B,IAAI,EAAE,MAAM,EACZ,aAAa,EAAE,MAAM,GAAG,SAAS,EACjC,aAAa,EAAE,MAAM,GACpB,MAAM,CAGR;AAED,OAAO,EAAC,mBAAmB,IAAI,qBAAqB,EAAC,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"collect-idb-databases.d.ts","sourceRoot":"","sources":["../../../../../replicache/src/persist/collect-idb-databases.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,UAAU,EAAE,QAAQ,EAAE,OAAO,EAAC,MAAM,kBAAkB,CAAC;AAKpE,OAAO,KAAK,EAAC,KAAK,EAAC,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"collect-idb-databases.d.ts","sourceRoot":"","sources":["../../../../../replicache/src/persist/collect-idb-databases.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,UAAU,EAAE,QAAQ,EAAE,OAAO,EAAC,MAAM,kBAAkB,CAAC;AAKpE,OAAO,KAAK,EAAC,KAAK,EAAC,MAAM,iBAAiB,CAAC;AAU3C,OAAO,KAAK,EAAC,SAAS,EAAE,aAAa,EAAC,MAAM,gBAAgB,CAAC;AAQ7D,OAAO,KAAK,EAAC,gBAAgB,EAAC,MAAM,cAAc,CAAC;AAGnD,OAAO,EAAC,iBAAiB,EAAC,MAAM,0BAA0B,CAAC;AAE3D;;GAEG;AACH,eAAO,MAAM,oBAAoB,QAAsB,CAAC;AAExD;;GAEG;AACH,eAAO,MAAM,yBAAyB,QAAgB,CAAC;AAEvD,wBAAgB,uBAAuB,CACrC,iBAAiB,EAAE,iBAAiB,EACpC,WAAW,EAAE,SAAS,EACtB,eAAe,EAAE,MAAM,EACvB,mBAAmB,EAAE,MAAM,EAC3B,MAAM,EAAE,MAAM,EACd,sBAAsB,EAAE,OAAO,EAC/B,gBAAgB,EAAE,gBAAgB,EAClC,EAAE,EAAE,UAAU,EACd,MAAM,EAAE,WAAW,GAClB,IAAI,CAwBN;AAED;;GAEG;AACH,wBAAsB,mBAAmB,CACvC,iBAAiB,EAAE,iBAAiB,EACpC,GAAG,EAAE,MAAM,EACX,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,SAAS,EACtB,sBAAsB,EAAE,OAAO,EAC/B,gBAAgB,EAAE,gBAAgB,EAClC,WAAW,4BAAqB,GAC/B,OAAO,CAAC,IAAI,CAAC,CAoEf;AAsCD,iBAAS,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,KAAK,CAG/C;AA8CD;;GAEG;AACH,MAAM,MAAM,mBAAmB,GAAG;IAChC;;;OAGG;IACH,OAAO,CAAC,EAAE,KAAK,GAAG,KAAK,GAAG,aAAa,GAAG,SAAS,CAAC;IACpD;;;;;;OAMG;IACH,QAAQ,CAAC,EAAE,QAAQ,GAAG,SAAS,CAAC;IAChC;;;;;;;;;;;;;;OAcG;IACH,QAAQ,CAAC,EAAE,OAAO,EAAE,GAAG,SAAS,CAAC;CAClC,CAAC;AAEF;;;;GAIG;AACH,wBAAsB,YAAY,CAChC,MAAM,EAAE,MAAM,EACd,IAAI,CAAC,EAAE,mBAAmB,GAAG,SAAS,iBAWvC;AAED;;;;;GAKG;AACH,wBAAsB,gBAAgB,CACpC,IAAI,CAAC,EAAE,mBAAmB,GAAG,SAAS,GACrC,OAAO,CAAC;IACT,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,MAAM,EAAE,OAAO,EAAE,CAAC;CACnB,CAAC,CAUD;AAED;;;;;;;GAOG;AACH,wBAAgB,uBAAuB,CACrC,IAAI,CAAC,EAAE,mBAAmB,GAAG,SAAS;aAvB7B,MAAM,EAAE;YACT,OAAO,EAAE;GAyBlB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"replicache-impl.d.ts","sourceRoot":"","sources":["../../../../replicache/src/replicache-impl.ts"],"names":[],"mappings":"AACA,OAAO,EAAiB,UAAU,EAAC,MAAM,kBAAkB,CAAC;AAO5D,OAAO,KAAK,EAAC,YAAY,EAAC,MAAM,2BAA2B,CAAC;AAG5D,OAAO,EAAe,KAAK,MAAM,EAAC,MAAM,cAAc,CAAC;AACvD,OAAO,EAAC,SAAS,EAAC,MAAM,qBAAqB,CAAC;AAE9C,OAAO,EAAsC,KAAK,KAAK,EAAC,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"replicache-impl.d.ts","sourceRoot":"","sources":["../../../../replicache/src/replicache-impl.ts"],"names":[],"mappings":"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"}
|