@trestleinc/replicate 1.2.0-preview.1 → 1.2.0-preview.3

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/README.md CHANGED
@@ -145,8 +145,7 @@ export const {
145
145
  mark,
146
146
  compact,
147
147
  sessions,
148
- cursors,
149
- leave,
148
+ presence,
150
149
  } = collection.create<Task>(components.replicate, 'tasks');
151
150
  ```
152
151
 
@@ -160,9 +159,8 @@ export const {
160
159
  - `remove` - Dual-storage delete mutation (auto-compacts when threshold exceeded)
161
160
  - `mark` - Report sync progress to server (peer tracking for safe compaction)
162
161
  - `compact` - Manual compaction trigger (peer-aware, respects active peer sync state)
163
- - `sessions` - Get connected sessions (presence query)
164
- - `cursors` - Get cursor positions for collaborative editing
165
- - `leave` - Explicit disconnect mutation
162
+ - `sessions` - Get connected sessions with cursor positions (presence query)
163
+ - `presence` - Join/leave presence for collaborative editing (with cursor, user, profile)
166
164
 
167
165
  ### Step 4: Define Your Collection
168
166
 
@@ -173,7 +171,7 @@ Create a collection definition using `collection.create()`. This is SSR-safe bec
173
171
  import { collection, persistence } from '@trestleinc/replicate/client';
174
172
  import { ConvexClient } from 'convex/browser';
175
173
  import { api } from '../../convex/_generated/api';
176
- import initSqlJs from 'sql.js';
174
+ import { PGlite } from '@electric-sql/pglite';
177
175
  import { z } from 'zod';
178
176
 
179
177
  // Define your Zod schema (required)
@@ -189,8 +187,8 @@ export type Task = z.infer<typeof taskSchema>;
189
187
  export const tasks = collection.create({
190
188
  // Async factory - only called in browser during init()
191
189
  persistence: async () => {
192
- const SQL = await initSqlJs({ locateFile: (f) => `/${f}` });
193
- return persistence.sqlite.browser(SQL, 'tasks');
190
+ const db = new PGlite('idb://tasks');
191
+ return persistence.pglite(db, 'tasks');
194
192
  },
195
193
  // Sync factory - only called in browser during init()
196
194
  config: () => ({
@@ -483,8 +481,7 @@ export const {
483
481
  mark,
484
482
  compact,
485
483
  sessions,
486
- cursors,
487
- leave,
484
+ presence,
488
485
  } = collection.create<Task>(components.replicate, 'tasks', {
489
486
  // Optional hooks for authorization and lifecycle events
490
487
  hooks: {
@@ -526,10 +523,10 @@ export const {
526
523
 
527
524
  ### Rich Text / Prose Fields
528
525
 
529
- For collaborative rich text editing, use the `schema.prose()` validator and `prose.extract()` function:
526
+ For collaborative rich text editing, use `schema.prose()` on both server and client:
530
527
 
531
528
  ```typescript
532
- // convex/schema.ts
529
+ // convex/schema.ts (server)
533
530
  import { schema } from '@trestleinc/replicate/server';
534
531
 
535
532
  export default defineSchema({
@@ -541,14 +538,85 @@ export default defineSchema({
541
538
  });
542
539
 
543
540
  // Client: Extract plain text for search
544
- import { prose } from '@trestleinc/replicate/client';
541
+ import { schema } from '@trestleinc/replicate/client';
545
542
 
546
- const plainText = prose.extract(notebook.content);
543
+ const plainText = schema.prose.extract(notebook.content);
547
544
 
548
545
  // Client: Get editor binding for ProseMirror/TipTap
549
546
  const binding = await collection.utils.prose(notebookId, 'content');
550
547
  ```
551
548
 
549
+ **Important:** `collection.utils.prose()` is async and internally waits for the actor system to initialize before observing the Yjs fragment. This ensures the sync infrastructure is ready before collaborative editing begins.
550
+
551
+ ```typescript
552
+ // React: Use useEffect with cleanup
553
+ useEffect(() => {
554
+ let binding: EditorBinding | null = null;
555
+
556
+ collection.utils.prose(docId, 'content').then((b) => {
557
+ binding = b;
558
+ // Initialize your editor with binding.fragment and binding.provider
559
+ });
560
+
561
+ return () => binding?.destroy();
562
+ }, [docId]);
563
+
564
+ // Svelte: Use onMount
565
+ onMount(async () => {
566
+ binding = await collection.utils.prose(docId, 'content');
567
+ // Initialize TipTap with binding.fragment
568
+
569
+ return () => binding?.destroy();
570
+ });
571
+ ```
572
+
573
+ **Prose Options:**
574
+
575
+ ```typescript
576
+ interface ProseOptions {
577
+ user?: UserIdentity; // Collaborative presence identity
578
+ debounceMs?: number; // Sync debounce delay (default: 200ms)
579
+ }
580
+
581
+ interface UserIdentity {
582
+ name?: string; // Display name for cursor labels
583
+ color?: string; // Cursor/selection color (hex, e.g., "#6366f1")
584
+ avatar?: string; // Avatar URL for presence indicators
585
+ }
586
+ ```
587
+
588
+ **Configuration Examples:**
589
+
590
+ ```typescript
591
+ // Minimal: Just get the binding with defaults
592
+ const binding = await collection.utils.prose(docId, 'content');
593
+
594
+ // With user presence for collaborative cursors
595
+ const binding = await collection.utils.prose(docId, 'content', {
596
+ user: {
597
+ name: 'Alice',
598
+ color: '#6366f1',
599
+ avatar: 'https://example.com/alice.jpg',
600
+ },
601
+ });
602
+
603
+ // Custom debounce: 500ms for less frequent syncs
604
+ const binding = await collection.utils.prose(docId, 'content', {
605
+ debounceMs: 500,
606
+ });
607
+
608
+ // Real-time: No debounce (sync on every keystroke)
609
+ const binding = await collection.utils.prose(docId, 'content', {
610
+ debounceMs: 0,
611
+ });
612
+
613
+ // Full configuration
614
+ const binding = await collection.utils.prose(docId, 'content', {
615
+ user: { name: 'Alice', color: '#6366f1' },
616
+ debounceMs: 200,
617
+ });
618
+ ```
619
+
552
620
  ### Persistence Providers
553
621
 
554
622
  Choose the right storage backend for your platform. Persistence is configured in the `persistence` factory of `collection.create()`:
@@ -556,17 +624,38 @@ Choose the right storage backend for your platform. Persistence is configured in
556
624
  ```typescript
557
625
  import { collection, persistence } from '@trestleinc/replicate/client';
558
626
 
559
- // Browser SQLite: Uses sql.js WASM with OPFS persistence
627
+ // Browser: PGlite (PostgreSQL in browser via IndexedDB)
560
628
  export const tasks = collection.create({
561
629
  persistence: async () => {
562
- const initSqlJs = (await import('sql.js')).default;
563
- const SQL = await initSqlJs({ locateFile: (f) => `/${f}` });
564
- return persistence.sqlite.browser(SQL, 'my-app-db');
630
+ const { PGlite } = await import('@electric-sql/pglite');
631
+ const db = new PGlite('idb://my-app-db');
632
+ return persistence.pglite(db, 'tasks');
565
633
  },
566
634
  config: () => ({ /* ... */ }),
567
635
  });
568
636
 
569
- // React Native SQLite: Uses op-sqlite (native SQLite)
637
+ // Browser: PGlite singleton (shared across multiple collections)
638
+ // Use persistence.pglite.once() when you want one database for all collections
639
+ import { persistence } from '@trestleinc/replicate/client';
640
+ import { PGlite } from '@electric-sql/pglite';
641
+
642
+ // Create shared PGlite factory (module level)
643
+ const pglite = async () => {
644
+ const db = new PGlite('idb://my-app-db');
645
+ return persistence.pglite.once(db, 'my-app');
646
+ };
647
+
648
+ export const tasks = collection.create({
649
+ persistence: pglite, // Shared instance
650
+ config: () => ({ /* ... */ }),
651
+ });
652
+
653
+ export const comments = collection.create({
654
+ persistence: pglite, // Same shared instance
655
+ config: () => ({ /* ... */ }),
656
+ });
657
+
658
+ // React Native: Native SQLite (op-sqlite)
570
659
  export const tasks = collection.create({
571
660
  persistence: async () => {
572
661
  const { open } = await import('@op-engineering/op-sqlite');
@@ -589,7 +678,9 @@ export const tasks = collection.create({
589
678
  });
590
679
  ```
591
680
 
592
- **SQLite Browser** - Uses sql.js (SQLite compiled to WASM) with OPFS persistence. You initialize sql.js yourself and pass the SQL object.
681
+ **PGlite** - PostgreSQL compiled to WASM, stored in IndexedDB. Full SQL support with reactive queries. Recommended for web apps.
682
+
683
+ **PGlite Singleton** - Use `persistence.pglite.once()` when multiple collections should share one database. Reference counted for proper cleanup.
593
684
 
594
685
  **SQLite Native** - Uses op-sqlite for React Native. You create the database and pass it.
595
686
 
@@ -666,18 +757,18 @@ Creates a lazy-initialized collection with deferred persistence and config resol
666
757
  ```typescript
667
758
  import { collection, persistence } from '@trestleinc/replicate/client';
668
759
  import { ConvexClient } from 'convex/browser';
669
- import initSqlJs from 'sql.js';
760
+ import { PGlite } from '@electric-sql/pglite';
670
761
 
671
762
  export const tasks = collection.create({
672
763
  persistence: async () => {
673
- const SQL = await initSqlJs({ locateFile: (f) => `/${f}` });
674
- return persistence.sqlite.browser(SQL, 'tasks');
764
+ const db = new PGlite('idb://tasks');
765
+ return persistence.pglite(db, 'tasks');
675
766
  },
676
767
  config: () => ({
677
768
  schema: taskSchema,
769
+ getKey: (task) => task.id,
678
770
  convexClient: new ConvexClient(import.meta.env.VITE_CONVEX_URL),
679
771
  api: api.tasks,
680
- getKey: (task) => task.id,
681
772
  }),
682
773
  });
683
774
 
@@ -726,8 +817,8 @@ interface CollectionConfig<T> {
726
817
  ```typescript
727
818
  export const tasks = collection.create({
728
819
  persistence: async () => {
729
- const SQL = await initSqlJs({ locateFile: (f) => `/${f}` });
730
- return persistence.sqlite.browser(SQL, 'tasks');
820
+ const db = new PGlite('idb://tasks');
821
+ return persistence.pglite(db, 'tasks');
731
822
  },
732
823
  config: () => ({
733
824
  schema: taskSchema,
@@ -738,7 +829,7 @@ export const tasks = collection.create({
738
829
  });
739
830
  ```
740
831
 
741
- #### `prose.extract(proseJson)`
832
+ #### `schema.prose.extract(proseJson)`
742
833
 
743
834
  Extract plain text from ProseMirror JSON.
744
835
 
@@ -749,9 +840,9 @@ Extract plain text from ProseMirror JSON.
749
840
 
750
841
  **Example:**
751
842
  ```typescript
752
- import { prose } from '@trestleinc/replicate/client';
843
+ import { schema } from '@trestleinc/replicate/client';
753
844
 
754
- const plainText = prose.extract(task.content);
845
+ const plainText = schema.prose.extract(task.content);
755
846
  ```
756
847
 
757
848
  #### Persistence Providers
@@ -760,13 +851,16 @@ const plainText = prose.extract(task.content);
760
851
  import { persistence, type StorageAdapter } from '@trestleinc/replicate/client';
761
852
 
762
853
  // Persistence providers (use in collection.create persistence factory)
763
- persistence.sqlite.browser(SQL, name) // Browser: sql.js WASM + OPFS
854
+ persistence.pglite(db, name) // Browser: PGlite (PostgreSQL in IndexedDB)
855
+ persistence.pglite.once(db, name) // Browser: PGlite singleton (shared across collections)
764
856
  persistence.sqlite.native(db, name) // React Native: op-sqlite
765
857
  persistence.memory() // Testing: in-memory (no persistence)
766
858
  persistence.custom(adapter) // Custom: your StorageAdapter implementation
767
859
  ```
768
860
 
769
- **`persistence.sqlite.browser(SQL, name)`** - Browser SQLite using sql.js WASM. You initialize sql.js and pass the SQL object.
861
+ **`persistence.pglite(db, name)`** - Browser persistence using PGlite (PostgreSQL compiled to WASM, stored in IndexedDB).
862
+
863
+ **`persistence.pglite.once(db, name)`** - Singleton PGlite instance for sharing across multiple collections. Reference counted for cleanup.
770
864
 
771
865
  **`persistence.sqlite.native(db, name)`** - React Native SQLite using op-sqlite. You create the database and pass it.
772
866
 
@@ -828,7 +922,7 @@ import { collection } from '@trestleinc/replicate/server';
828
922
  import { components } from './_generated/api';
829
923
 
830
924
  export const {
831
- stream, material, insert, update, remove, recovery, mark, compact, sessions, cursors, leave,
925
+ stream, material, insert, update, remove, recovery, mark, compact, sessions, presence,
832
926
  } = collection.create<Task>(components.replicate, 'tasks');
833
927
  ```
834
928
 
@@ -879,9 +973,8 @@ interface CollectionOptions<T> {
879
973
  - `remove` - Dual-storage delete mutation (auto-compacts when threshold exceeded)
880
974
  - `mark` - Peer sync tracking mutation (reports `syncedSeq` to server)
881
975
  - `compact` - Manual compaction mutation (peer-aware, safe for active clients)
882
- - `sessions` - Get connected sessions (presence query)
883
- - `cursors` - Get cursor positions for collaborative editing
884
- - `leave` - Explicit disconnect mutation
976
+ - `sessions` - Get connected sessions with cursor positions (presence query)
977
+ - `presence` - Join/leave presence mutation (with cursor, user, profile)
885
978
 
886
979
  #### `schema.table(userFields, applyIndexes?)`
887
980
 
@@ -925,7 +1018,7 @@ content: schema.prose() // Validates ProseMirror JSON structure
925
1018
  import type { ProseValue } from '@trestleinc/replicate/shared';
926
1019
 
927
1020
  // ProseValue - branded type for prose fields in Zod schemas
928
- // Use the prose() helper from client to create fields of this type
1021
+ // Use schema.prose() from client to create Zod fields of this type
929
1022
  ```
930
1023
 
931
1024
  ## React Native
@@ -966,11 +1059,11 @@ A full-featured offline-first issue tracker built with Replicate, demonstrating
966
1059
  - [`examples/expo/`](./examples/expo/) - Expo (React Native, mobile)
967
1060
 
968
1061
  **Web features demonstrated:**
969
- - Offline-first with SQLite persistence (sql.js + OPFS)
1062
+ - Offline-first with PGlite persistence (PostgreSQL in IndexedDB)
970
1063
  - Rich text editing with TipTap + Yjs collaboration
971
1064
  - PWA with custom service worker
972
1065
  - Real-time sync across devices
973
- - Search with client-side text extraction (`prose.extract()`)
1066
+ - Search with client-side text extraction (`schema.prose.extract()`)
974
1067
 
975
1068
  **Mobile features demonstrated (Expo):**
976
1069
  - Native SQLite persistence (op-sqlite)
@@ -9,8 +9,39 @@ import * as effect_Types0 from "effect/Types";
9
9
  import * as effect_Cause0 from "effect/Cause";
10
10
  import { z } from "zod";
11
11
 
12
+ //#region src/shared/types.d.ts
13
+ /** ProseMirror-compatible JSON for XmlFragment serialization */
14
+ interface XmlFragmentJSON {
15
+ type: "doc";
16
+ content?: XmlNodeJSON[];
17
+ }
18
+ declare const PROSE_BRAND: unique symbol;
19
+ /**
20
+ * Branded prose type for Zod schemas.
21
+ * Extends XmlFragmentJSON with a unique brand for type-level detection.
22
+ * Use the `prose()` helper from `@trestleinc/replicate/client` to create this type.
23
+ */
24
+ interface ProseValue extends XmlFragmentJSON {
25
+ readonly [PROSE_BRAND]: typeof PROSE_BRAND;
26
+ }
27
+ /** ProseMirror node structure */
28
+ interface XmlNodeJSON {
29
+ type: string;
30
+ attrs?: Record<string, unknown>;
31
+ content?: XmlNodeJSON[];
32
+ text?: string;
33
+ marks?: {
34
+ type: string;
35
+ attrs?: Record<string, unknown>;
36
+ }[];
37
+ }
38
+ /**
39
+ * Extract prose field names from T (fields typed as ProseValue).
40
+ * Used internally for type-safe prose field operations.
41
+ */
42
+ type ProseFields<T> = { [K in keyof T]: T[K] extends ProseValue ? K : never }[keyof T];
43
+ //#endregion
12
44
  //#region src/client/persistence/types.d.ts
13
-
14
45
  /**
15
46
  * Low-level storage adapter for custom backends (Chrome extension, localStorage, cloud).
16
47
  * For SQLite, use `persistence.sqlite()` directly.
@@ -117,37 +148,12 @@ declare class NonRetriableError extends Error {
117
148
  //#region src/client/services/seq.d.ts
118
149
  type Seq = number;
119
150
  //#endregion
120
- //#region src/shared/types.d.ts
121
- /** ProseMirror-compatible JSON for XmlFragment serialization */
122
- interface XmlFragmentJSON {
123
- type: "doc";
124
- content?: XmlNodeJSON[];
151
+ //#region src/client/services/awareness.d.ts
152
+ interface UserIdentity {
153
+ name?: string;
154
+ color?: string;
155
+ avatar?: string;
125
156
  }
126
- declare const PROSE_BRAND: unique symbol;
127
- /**
128
- * Branded prose type for Zod schemas.
129
- * Extends XmlFragmentJSON with a unique brand for type-level detection.
130
- * Use the `prose()` helper from `@trestleinc/replicate/client` to create this type.
131
- */
132
- interface ProseValue extends XmlFragmentJSON {
133
- readonly [PROSE_BRAND]: typeof PROSE_BRAND;
134
- }
135
- /** ProseMirror node structure */
136
- interface XmlNodeJSON {
137
- type: string;
138
- attrs?: Record<string, unknown>;
139
- content?: XmlNodeJSON[];
140
- text?: string;
141
- marks?: {
142
- type: string;
143
- attrs?: Record<string, unknown>;
144
- }[];
145
- }
146
- /**
147
- * Extract prose field names from T (fields typed as ProseValue).
148
- * Used internally for type-safe prose field operations.
149
- */
150
- type ProseFields<T> = { [K in keyof T]: T[K] extends ProseValue ? K : never }[keyof T];
151
157
  //#endregion
152
158
  //#region src/client/collection.d.ts
153
159
  /** Server-rendered material data for SSR hydration */
@@ -171,8 +177,7 @@ interface ConvexCollectionApi {
171
177
  compact: FunctionReference<"mutation">;
172
178
  material?: FunctionReference<"query">;
173
179
  sessions?: FunctionReference<"query">;
174
- cursors?: FunctionReference<"query">;
175
- leave?: FunctionReference<"mutation">;
180
+ presence?: FunctionReference<"mutation">;
176
181
  }
177
182
  interface ConvexCollectionConfig<T extends object = object, TSchema extends StandardSchemaV1 = never, TKey extends string | number = string | number> extends BaseCollectionConfig<T, TKey, TSchema> {
178
183
  schema: TSchema;
@@ -206,16 +211,18 @@ interface EditorBinding {
206
211
  /** Cleanup - call when unmounting editor */
207
212
  destroy(): void;
208
213
  }
209
- /** Utilities exposed on collection.utils */
210
- interface ConvexCollectionUtils<T extends object> {
214
+ interface ProseOptions {
215
+ /** User identity for collaborative presence */
216
+ user?: UserIdentity;
211
217
  /**
212
- * Get an editor binding for a prose field.
213
- * Waits for Y.Doc to be ready (IndexedDB loaded) before returning.
214
- * @param document - The document ID
215
- * @param field - The prose field name (must be in `prose` config)
216
- * @returns Promise resolving to EditorBinding
218
+ * Debounce delay in milliseconds before syncing changes to server.
219
+ * Local changes are batched during this window for efficiency.
220
+ * @default 200
217
221
  */
218
- prose(document: string, field: ProseFields<T>): Promise<EditorBinding>;
222
+ debounceMs?: number;
223
+ }
224
+ interface ConvexCollectionUtils<T extends object> {
225
+ prose(document: string, field: ProseFields<T>, options?: ProseOptions): Promise<EditorBinding>;
219
226
  }
220
227
  type LazyCollectionConfig<TSchema extends z.ZodObject<z.ZodRawShape>> = Omit<ConvexCollectionConfig<z.infer<TSchema>, TSchema, string>, "persistence" | "material">;
221
228
  interface LazyCollection<T extends object> {
@@ -240,8 +247,8 @@ declare function extract(content: unknown): string;
240
247
  //#endregion
241
248
  //#region src/client/prose.d.ts
242
249
  declare function emptyProse(): ProseValue;
243
- declare function prose$1(): z.ZodType<ProseValue>;
244
- declare namespace prose$1 {
250
+ declare function prose(): z.ZodType<ProseValue>;
251
+ declare namespace prose {
245
252
  var empty: typeof emptyProse;
246
253
  }
247
254
  //#endregion
@@ -262,23 +269,6 @@ declare namespace prose$1 {
262
269
  */
263
270
  declare function memoryPersistence(): Persistence;
264
271
  //#endregion
265
- //#region src/client/persistence/sqlite/browser.d.ts
266
- interface SqlJsDatabase {
267
- run(sql: string, params?: unknown): unknown;
268
- prepare(sql: string): {
269
- bind(params?: unknown): void;
270
- step(): boolean;
271
- getAsObject(): Record<string, unknown>;
272
- free(): void;
273
- };
274
- export(): Uint8Array;
275
- close(): void;
276
- }
277
- interface SqlJsStatic {
278
- Database: new (data?: ArrayLike<number> | Buffer | null) => SqlJsDatabase;
279
- }
280
- declare function createBrowserSqlitePersistence(SQL: SqlJsStatic, dbName: string): Promise<Persistence>;
281
- //#endregion
282
272
  //#region src/client/persistence/sqlite/native.d.ts
283
273
  interface OPSQLiteDatabase {
284
274
  execute(sql: string, params?: unknown[]): Promise<{
@@ -288,20 +278,52 @@ interface OPSQLiteDatabase {
288
278
  }
289
279
  declare function createNativeSqlitePersistence(db: OPSQLiteDatabase, _dbName: string): Promise<Persistence>;
290
280
  //#endregion
291
- //#region src/client/persistence/indexeddb.d.ts
292
- declare function createIndexedDBPersistence(dbName: string): Promise<Persistence>;
293
- //#endregion
294
281
  //#region src/client/persistence/custom.d.ts
295
282
  declare function createCustomPersistence(adapter: StorageAdapter): Persistence;
296
283
  //#endregion
284
+ //#region src/client/persistence/pglite.d.ts
285
+ interface PGliteInterface {
286
+ query<T = Record<string, unknown>>(sql: string, params?: unknown[]): Promise<{
287
+ rows: T[];
288
+ }>;
289
+ exec(sql: string): Promise<unknown>;
290
+ close(): Promise<void>;
291
+ }
292
+ declare function createPGlitePersistence(pg: PGliteInterface): Promise<Persistence>;
293
+ /**
294
+ * Creates a singleton PGlite persistence factory.
295
+ * Use this to ensure the PGlite WASM module is only loaded once,
296
+ * even when shared across multiple collections.
297
+ *
298
+ * @example
299
+ * ```typescript
300
+ * // src/lib/pglite.ts
301
+ * import { persistence } from "@trestleinc/replicate/client";
302
+ *
303
+ * export const pglite = persistence.pglite.once(async () => {
304
+ * const { PGlite } = await import("@electric-sql/pglite");
305
+ * const { live } = await import("@electric-sql/pglite/live");
306
+ * return PGlite.create({ dataDir: "idb://app", extensions: { live } });
307
+ * });
308
+ *
309
+ * // src/collections/useIntervals.ts
310
+ * import { pglite } from "$lib/pglite";
311
+ *
312
+ * export const intervals = collection.create({
313
+ * persistence: pglite,
314
+ * config: () => ({ ... }),
315
+ * });
316
+ * ```
317
+ */
318
+ declare function oncePGlitePersistence(factory: () => Promise<PGliteInterface>): () => Promise<Persistence>;
319
+ //#endregion
297
320
  //#region src/client/persistence/index.d.ts
298
321
  declare const persistence: {
299
- readonly memory: typeof memoryPersistence;
300
- readonly sqlite: {
301
- readonly browser: typeof createBrowserSqlitePersistence;
302
- readonly native: typeof createNativeSqlitePersistence;
322
+ readonly pglite: typeof createPGlitePersistence & {
323
+ once: typeof oncePGlitePersistence;
303
324
  };
304
- readonly indexeddb: typeof createIndexedDBPersistence;
325
+ readonly sqlite: typeof createNativeSqlitePersistence;
326
+ readonly memory: typeof memoryPersistence;
305
327
  readonly custom: typeof createCustomPersistence;
306
328
  };
307
329
  //#endregion
@@ -315,8 +337,11 @@ declare const errors: {
315
337
  readonly CollectionNotReady: typeof CollectionNotReadyError;
316
338
  readonly NonRetriable: typeof NonRetriableError;
317
339
  };
318
- declare const prose: typeof prose$1 & {
319
- extract: typeof extract;
340
+ declare const schema: {
341
+ readonly prose: typeof prose & {
342
+ extract: typeof extract;
343
+ empty: () => ProseValue;
344
+ };
320
345
  };
321
346
  //#endregion
322
- export { type ConvexCollection, type EditorBinding, type Materialized, type Persistence, type Seq, type StorageAdapter, collection, errors, persistence, prose };
347
+ export { type ConvexCollection, type EditorBinding, type Materialized, type Persistence, type ProseOptions, type Seq, type StorageAdapter, type UserIdentity, collection, errors, persistence, schema };