@trestleinc/replicate 1.1.1 → 1.1.2-preview.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (91) hide show
  1. package/README.md +395 -146
  2. package/dist/client/index.d.ts +311 -19
  3. package/dist/client/index.js +4027 -0
  4. package/dist/component/_generated/api.d.ts +13 -17
  5. package/dist/component/_generated/api.js +24 -4
  6. package/dist/component/_generated/component.d.ts +79 -77
  7. package/dist/component/_generated/component.js +1 -0
  8. package/dist/component/_generated/dataModel.d.ts +12 -15
  9. package/dist/component/_generated/dataModel.js +1 -0
  10. package/dist/component/_generated/server.d.ts +19 -22
  11. package/dist/component/_generated/server.js +65 -1
  12. package/dist/component/_virtual/rolldown_runtime.js +18 -0
  13. package/dist/component/convex.config.d.ts +6 -2
  14. package/dist/component/convex.config.js +7 -3
  15. package/dist/component/logger.d.ts +10 -6
  16. package/dist/component/logger.js +25 -28
  17. package/dist/component/public.d.ts +70 -61
  18. package/dist/component/public.js +311 -295
  19. package/dist/component/schema.d.ts +53 -45
  20. package/dist/component/schema.js +26 -32
  21. package/dist/component/shared/types.d.ts +9 -0
  22. package/dist/component/shared/types.js +15 -0
  23. package/dist/server/index.d.ts +134 -13
  24. package/dist/server/index.js +368 -0
  25. package/dist/shared/index.d.ts +27 -3
  26. package/dist/shared/index.js +1 -2
  27. package/package.json +34 -29
  28. package/src/client/collection.ts +339 -306
  29. package/src/client/errors.ts +9 -9
  30. package/src/client/index.ts +13 -32
  31. package/src/client/logger.ts +2 -2
  32. package/src/client/merge.ts +37 -34
  33. package/src/client/persistence/custom.ts +84 -0
  34. package/src/client/persistence/index.ts +9 -46
  35. package/src/client/persistence/indexeddb.ts +111 -84
  36. package/src/client/persistence/memory.ts +3 -3
  37. package/src/client/persistence/sqlite/browser.ts +168 -0
  38. package/src/client/persistence/sqlite/native.ts +29 -0
  39. package/src/client/persistence/sqlite/schema.ts +124 -0
  40. package/src/client/persistence/types.ts +32 -28
  41. package/src/client/prose-schema.ts +55 -0
  42. package/src/client/prose.ts +28 -25
  43. package/src/client/replicate.ts +5 -5
  44. package/src/client/services/cursor.ts +109 -0
  45. package/src/component/_generated/component.ts +31 -29
  46. package/src/component/convex.config.ts +2 -2
  47. package/src/component/logger.ts +7 -7
  48. package/src/component/public.ts +225 -237
  49. package/src/component/schema.ts +18 -15
  50. package/src/server/builder.ts +20 -7
  51. package/src/server/index.ts +3 -5
  52. package/src/server/schema.ts +5 -5
  53. package/src/server/storage.ts +113 -59
  54. package/src/shared/index.ts +5 -5
  55. package/src/shared/types.ts +51 -14
  56. package/dist/client/collection.d.ts +0 -96
  57. package/dist/client/errors.d.ts +0 -59
  58. package/dist/client/logger.d.ts +0 -2
  59. package/dist/client/merge.d.ts +0 -77
  60. package/dist/client/persistence/adapters/index.d.ts +0 -8
  61. package/dist/client/persistence/adapters/opsqlite.d.ts +0 -46
  62. package/dist/client/persistence/adapters/sqljs.d.ts +0 -83
  63. package/dist/client/persistence/index.d.ts +0 -49
  64. package/dist/client/persistence/indexeddb.d.ts +0 -17
  65. package/dist/client/persistence/memory.d.ts +0 -16
  66. package/dist/client/persistence/sqlite-browser.d.ts +0 -51
  67. package/dist/client/persistence/sqlite-level.d.ts +0 -63
  68. package/dist/client/persistence/sqlite-rn.d.ts +0 -36
  69. package/dist/client/persistence/sqlite.d.ts +0 -47
  70. package/dist/client/persistence/types.d.ts +0 -42
  71. package/dist/client/prose.d.ts +0 -56
  72. package/dist/client/replicate.d.ts +0 -40
  73. package/dist/client/services/checkpoint.d.ts +0 -18
  74. package/dist/client/services/reconciliation.d.ts +0 -24
  75. package/dist/index.js +0 -1618
  76. package/dist/server/builder.d.ts +0 -94
  77. package/dist/server/schema.d.ts +0 -27
  78. package/dist/server/storage.d.ts +0 -80
  79. package/dist/server.js +0 -281
  80. package/dist/shared/types.d.ts +0 -50
  81. package/dist/shared/types.js +0 -6
  82. package/dist/shared.js +0 -6
  83. package/src/client/persistence/adapters/index.ts +0 -8
  84. package/src/client/persistence/adapters/opsqlite.ts +0 -54
  85. package/src/client/persistence/adapters/sqljs.ts +0 -128
  86. package/src/client/persistence/sqlite-browser.ts +0 -107
  87. package/src/client/persistence/sqlite-level.ts +0 -407
  88. package/src/client/persistence/sqlite-rn.ts +0 -44
  89. package/src/client/persistence/sqlite.ts +0 -160
  90. package/src/client/services/checkpoint.ts +0 -86
  91. package/src/client/services/reconciliation.ts +0 -108
@@ -1,22 +1,314 @@
1
- export { convexCollectionOptions, type ConvexCollection, type EditorBinding, } from '$/client/collection.js';
2
- import { NetworkError, IDBError, IDBWriteError, ReconciliationError, ProseError, CollectionNotReadyError, NonRetriableError } from '$/client/errors.js';
3
- export declare const errors: {
4
- readonly Network: typeof NetworkError;
5
- readonly IDB: typeof IDBError;
6
- readonly IDBWrite: typeof IDBWriteError;
7
- readonly Reconciliation: typeof ReconciliationError;
8
- readonly Prose: typeof ProseError;
9
- readonly CollectionNotReady: typeof CollectionNotReadyError;
10
- readonly NonRetriable: typeof NonRetriableError;
1
+ import * as Y from "yjs";
2
+ import { FunctionReference } from "convex/server";
3
+ import { BaseCollectionConfig, Collection, NonSingleResult } from "@tanstack/db";
4
+ import { Context, Effect, Layer } from "effect";
5
+ import { ConvexClient } from "convex/browser";
6
+ import { StandardSchemaV1 } from "@standard-schema/spec";
7
+ import * as effect_Types0 from "effect/Types";
8
+ import * as effect_Cause0 from "effect/Cause";
9
+ import { z } from "zod";
10
+
11
+ //#region src/client/persistence/types.d.ts
12
+
13
+ /**
14
+ * Low-level storage adapter for custom backends (Chrome extension, localStorage, cloud).
15
+ * For SQLite, use `persistence.sqlite()` directly.
16
+ *
17
+ * @example
18
+ * ```typescript
19
+ * class ChromeStorageAdapter implements StorageAdapter {
20
+ * async get(key: string) {
21
+ * const result = await chrome.storage.local.get(key);
22
+ * return result[key] ? new Uint8Array(result[key]) : undefined;
23
+ * }
24
+ * async set(key: string, value: Uint8Array) {
25
+ * await chrome.storage.local.set({ [key]: Array.from(value) });
26
+ * }
27
+ * async delete(key: string) {
28
+ * await chrome.storage.local.remove(key);
29
+ * }
30
+ * async keys(prefix: string) {
31
+ * const all = await chrome.storage.local.get(null);
32
+ * return Object.keys(all).filter(k => k.startsWith(prefix));
33
+ * }
34
+ * }
35
+ * ```
36
+ */
37
+ interface StorageAdapter {
38
+ get(key: string): Promise<Uint8Array | undefined>;
39
+ set(key: string, value: Uint8Array): Promise<void>;
40
+ delete(key: string): Promise<void>;
41
+ keys(prefix: string): Promise<string[]>;
42
+ close?(): void;
43
+ }
44
+ interface PersistenceProvider {
45
+ readonly whenSynced: Promise<void>;
46
+ destroy(): void;
47
+ }
48
+ /**
49
+ * High-level persistence interface for collections.
50
+ * Create via `persistence.sqlite()`, `persistence.memory()`, or `persistence.custom()`.
51
+ */
52
+ interface Persistence {
53
+ createDocPersistence(collection: string, ydoc: Y.Doc): PersistenceProvider;
54
+ readonly kv: KeyValueStore;
55
+ }
56
+ interface KeyValueStore {
57
+ get<T>(key: string): Promise<T | undefined>;
58
+ set<T>(key: string, value: T): Promise<void>;
59
+ del(key: string): Promise<void>;
60
+ }
61
+ //#endregion
62
+ //#region src/client/errors.d.ts
63
+ declare const NetworkError_base: new <A extends Record<string, any> = {}>(args: effect_Types0.Equals<A, {}> extends true ? void : { readonly [P in keyof A as P extends "_tag" ? never : P]: A[P] }) => effect_Cause0.YieldableError & {
64
+ readonly _tag: "NetworkError";
65
+ } & Readonly<A>;
66
+ declare class NetworkError extends NetworkError_base<{
67
+ readonly cause: unknown;
68
+ readonly retryable: true;
69
+ readonly operation: string;
70
+ }> {}
71
+ declare const IDBError_base: new <A extends Record<string, any> = {}>(args: effect_Types0.Equals<A, {}> extends true ? void : { readonly [P in keyof A as P extends "_tag" ? never : P]: A[P] }) => effect_Cause0.YieldableError & {
72
+ readonly _tag: "IDBError";
73
+ } & Readonly<A>;
74
+ declare class IDBError extends IDBError_base<{
75
+ readonly operation: "get" | "set" | "delete" | "clear";
76
+ readonly store?: string;
77
+ readonly key?: string;
78
+ readonly cause: unknown;
79
+ }> {}
80
+ declare const IDBWriteError_base: new <A extends Record<string, any> = {}>(args: effect_Types0.Equals<A, {}> extends true ? void : { readonly [P in keyof A as P extends "_tag" ? never : P]: A[P] }) => effect_Cause0.YieldableError & {
81
+ readonly _tag: "IDBWriteError";
82
+ } & Readonly<A>;
83
+ declare class IDBWriteError extends IDBWriteError_base<{
84
+ readonly key: string;
85
+ readonly value: unknown;
86
+ readonly cause: unknown;
87
+ }> {}
88
+ declare const ReconciliationError_base: new <A extends Record<string, any> = {}>(args: effect_Types0.Equals<A, {}> extends true ? void : { readonly [P in keyof A as P extends "_tag" ? never : P]: A[P] }) => effect_Cause0.YieldableError & {
89
+ readonly _tag: "ReconciliationError";
90
+ } & Readonly<A>;
91
+ declare class ReconciliationError extends ReconciliationError_base<{
92
+ readonly collection: string;
93
+ readonly reason: string;
94
+ readonly cause?: unknown;
95
+ }> {}
96
+ declare const ProseError_base: new <A extends Record<string, any> = {}>(args: effect_Types0.Equals<A, {}> extends true ? void : { readonly [P in keyof A as P extends "_tag" ? never : P]: A[P] }) => effect_Cause0.YieldableError & {
97
+ readonly _tag: "ProseError";
98
+ } & Readonly<A>;
99
+ declare class ProseError extends ProseError_base<{
100
+ readonly documentId: string;
101
+ readonly field: string;
102
+ readonly collection: string;
103
+ }> {}
104
+ declare const CollectionNotReadyError_base: new <A extends Record<string, any> = {}>(args: effect_Types0.Equals<A, {}> extends true ? void : { readonly [P in keyof A as P extends "_tag" ? never : P]: A[P] }) => effect_Cause0.YieldableError & {
105
+ readonly _tag: "CollectionNotReadyError";
106
+ } & Readonly<A>;
107
+ declare class CollectionNotReadyError extends CollectionNotReadyError_base<{
108
+ readonly collection: string;
109
+ readonly reason: string;
110
+ }> {}
111
+ /** Error that should not be retried (auth failures, validation errors) */
112
+ declare class NonRetriableError extends Error {
113
+ constructor(message: string);
114
+ }
115
+ //#endregion
116
+ //#region src/client/services/cursor.d.ts
117
+ type Cursor = number;
118
+ //#endregion
119
+ //#region src/shared/types.d.ts
120
+ /** ProseMirror-compatible JSON for XmlFragment serialization */
121
+ interface XmlFragmentJSON {
122
+ type: "doc";
123
+ content?: XmlNodeJSON[];
124
+ }
125
+ declare const PROSE_BRAND: unique symbol;
126
+ /**
127
+ * Branded prose type for Zod schemas.
128
+ * Extends XmlFragmentJSON with a unique brand for type-level detection.
129
+ * Use the `prose()` helper from `@trestleinc/replicate/client` to create this type.
130
+ */
131
+ interface ProseValue extends XmlFragmentJSON {
132
+ readonly [PROSE_BRAND]: typeof PROSE_BRAND;
133
+ }
134
+ /** ProseMirror node structure */
135
+ interface XmlNodeJSON {
136
+ type: string;
137
+ attrs?: Record<string, unknown>;
138
+ content?: XmlNodeJSON[];
139
+ text?: string;
140
+ marks?: {
141
+ type: string;
142
+ attrs?: Record<string, unknown>;
143
+ }[];
144
+ }
145
+ /**
146
+ * Extract prose field names from T (fields typed as ProseValue).
147
+ * Used internally for type-safe prose field operations.
148
+ */
149
+ type ProseFields<T> = { [K in keyof T]: T[K] extends ProseValue ? K : never }[keyof T];
150
+ //#endregion
151
+ //#region src/client/collection.d.ts
152
+ /** Server-rendered material data for SSR hydration */
153
+ interface Materialized<T> {
154
+ documents: readonly T[];
155
+ cursor?: Cursor;
156
+ count?: number;
157
+ crdtBytes?: ArrayBuffer;
158
+ }
159
+ /** API object from replicate() */
160
+ interface ConvexCollectionApi {
161
+ stream: FunctionReference<"query">;
162
+ insert: FunctionReference<"mutation">;
163
+ update: FunctionReference<"mutation">;
164
+ remove: FunctionReference<"mutation">;
165
+ recovery: FunctionReference<"query">;
166
+ mark: FunctionReference<"mutation">;
167
+ compact: FunctionReference<"mutation">;
168
+ material?: FunctionReference<"query">;
169
+ }
170
+ interface ConvexCollectionConfig<T extends object = object, TSchema extends StandardSchemaV1 = never, TKey extends string | number = string | number> extends BaseCollectionConfig<T, TKey, TSchema> {
171
+ schema: TSchema;
172
+ convexClient: ConvexClient;
173
+ api: ConvexCollectionApi;
174
+ persistence: Persistence;
175
+ material?: Materialized<T>;
176
+ undoCaptureTimeout?: number;
177
+ }
178
+ /** Editor binding for BlockNote/TipTap collaboration */
179
+ interface EditorBinding {
180
+ /** The Y.XmlFragment bound to the editor */
181
+ readonly fragment: Y.XmlFragment;
182
+ /** Provider stub for BlockNote compatibility */
183
+ readonly provider: {
184
+ readonly awareness: null;
185
+ };
186
+ /** Current sync state - true if unsent changes exist */
187
+ readonly pending: boolean;
188
+ /** Subscribe to pending state changes. Returns unsubscribe function. */
189
+ onPendingChange(callback: (pending: boolean) => void): () => void;
190
+ /** Undo the last content edit */
191
+ undo(): void;
192
+ /** Redo the last undone edit */
193
+ redo(): void;
194
+ /** Check if undo is available */
195
+ canUndo(): boolean;
196
+ /** Check if redo is available */
197
+ canRedo(): boolean;
198
+ }
199
+ /** Utilities exposed on collection.utils */
200
+ interface ConvexCollectionUtils<T extends object> {
201
+ /**
202
+ * Get an editor binding for a prose field.
203
+ * Waits for Y.Doc to be ready (IndexedDB loaded) before returning.
204
+ * @param documentId - The document ID
205
+ * @param field - The prose field name (must be in `prose` config)
206
+ * @returns Promise resolving to EditorBinding
207
+ */
208
+ prose(documentId: string, field: ProseFields<T>): Promise<EditorBinding>;
209
+ }
210
+ type LazyCollectionConfig<TSchema extends z.ZodObject<z.ZodRawShape>> = Omit<ConvexCollectionConfig<z.infer<TSchema>, TSchema, string>, "persistence" | "material">;
211
+ interface LazyCollection<T extends object> {
212
+ init(material?: Materialized<T>): Promise<void>;
213
+ get(): Collection<T, string, ConvexCollectionUtils<T>, any, T> & NonSingleResult;
214
+ }
215
+ type ConvexCollection<T extends object> = Collection<T, any, ConvexCollectionUtils<T>, any, T> & NonSingleResult;
216
+ interface CreateCollectionOptions<TSchema extends z.ZodObject<z.ZodRawShape>> {
217
+ persistence: () => Promise<Persistence>;
218
+ config: () => Omit<LazyCollectionConfig<TSchema>, "material">;
219
+ }
220
+ declare const collection: {
221
+ create<TSchema extends z.ZodObject<z.ZodRawShape>>(options: CreateCollectionOptions<TSchema>): LazyCollection<z.infer<TSchema>>;
11
222
  };
12
- import { extract } from '$/client/merge.js';
13
- export declare const prose: {
14
- readonly extract: typeof extract;
223
+ //#endregion
224
+ //#region src/client/merge.d.ts
225
+ /**
226
+ * Extract plain text from ProseMirror/BlockNote JSON content.
227
+ * Handles various content structures defensively for search and display.
228
+ */
229
+ declare function extract(content: unknown): string;
230
+ //#endregion
231
+ //#region src/client/prose-schema.d.ts
232
+ declare function emptyProse(): ProseValue;
233
+ declare function prose$1(): z.ZodType<ProseValue>;
234
+ declare namespace prose$1 {
235
+ var empty: typeof emptyProse;
236
+ }
237
+ //#endregion
238
+ //#region src/client/persistence/memory.d.ts
239
+ /**
240
+ * Create an in-memory persistence factory.
241
+ *
242
+ * Useful for testing where you don't want IndexedDB side effects.
243
+ *
244
+ * @example
245
+ * ```typescript
246
+ * // In tests
247
+ * convexCollectionOptions<Task>({
248
+ * // ... other options
249
+ * persistence: memoryPersistence(),
250
+ * });
251
+ * ```
252
+ */
253
+ declare function memoryPersistence(): Persistence;
254
+ //#endregion
255
+ //#region src/client/persistence/sqlite/browser.d.ts
256
+ interface SqlJsDatabase {
257
+ run(sql: string, params?: unknown): unknown;
258
+ prepare(sql: string): {
259
+ bind(params?: unknown): void;
260
+ step(): boolean;
261
+ getAsObject(): Record<string, unknown>;
262
+ free(): void;
263
+ };
264
+ export(): Uint8Array;
265
+ close(): void;
266
+ }
267
+ interface SqlJsStatic {
268
+ Database: new (data?: ArrayLike<number> | Buffer | null) => SqlJsDatabase;
269
+ }
270
+ declare function createBrowserSqlitePersistence(SQL: SqlJsStatic, dbName: string): Promise<Persistence>;
271
+ //#endregion
272
+ //#region src/client/persistence/sqlite/native.d.ts
273
+ interface OPSQLiteDatabase {
274
+ execute(sql: string, params?: unknown[]): Promise<{
275
+ rows: Record<string, unknown>[];
276
+ }>;
277
+ close(): void;
278
+ }
279
+ declare function createNativeSqlitePersistence(db: OPSQLiteDatabase, _dbName: string): Promise<Persistence>;
280
+ //#endregion
281
+ //#region src/client/persistence/indexeddb.d.ts
282
+ declare function createIndexedDBPersistence(dbName: string): Promise<Persistence>;
283
+ //#endregion
284
+ //#region src/client/persistence/custom.d.ts
285
+ declare function createCustomPersistence(adapter: StorageAdapter): Persistence;
286
+ //#endregion
287
+ //#region src/client/persistence/index.d.ts
288
+ declare const persistence: {
289
+ readonly memory: typeof memoryPersistence;
290
+ readonly sqlite: {
291
+ readonly browser: typeof createBrowserSqlitePersistence;
292
+ readonly native: typeof createNativeSqlitePersistence;
293
+ };
294
+ readonly indexeddb: typeof createIndexedDBPersistence;
295
+ readonly custom: typeof createCustomPersistence;
15
296
  };
16
- export { persistence, type Persistence, type PersistenceProvider, type KeyValueStore, type SqlitePersistenceOptions, type SqliteAdapter, type SqlJsStatic, } from '$/client/persistence/index.js';
17
- import { SqlJsAdapter, OPSqliteAdapter } from '$/client/persistence/adapters/index.js';
18
- export declare const adapters: {
19
- readonly sqljs: typeof SqlJsAdapter;
20
- readonly opsqlite: typeof OPSqliteAdapter;
297
+ //#endregion
298
+ //#region src/client/index.d.ts
299
+ declare const errors: {
300
+ readonly Network: typeof NetworkError;
301
+ readonly IDB: typeof IDBError;
302
+ readonly IDBWrite: typeof IDBWriteError;
303
+ readonly Reconciliation: typeof ReconciliationError;
304
+ readonly Prose: typeof ProseError;
305
+ readonly CollectionNotReady: typeof CollectionNotReadyError;
306
+ readonly NonRetriable: typeof NonRetriableError;
21
307
  };
22
- export type { SqlJsDatabase, SqlJsAdapterOptions, OPSQLiteDatabase, } from '$/client/persistence/adapters/index.js';
308
+ declare function empty(): ProseValue;
309
+ declare const prose: typeof prose$1 & {
310
+ extract: typeof extract;
311
+ empty: typeof empty;
312
+ };
313
+ //#endregion
314
+ export { type ConvexCollection, type EditorBinding, type Materialized, type Persistence, type StorageAdapter, collection, errors, persistence, prose };