@fatagnus/dink-convex 1.0.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.
- package/LICENSE +190 -0
- package/README.md +282 -0
- package/convex/convex.config.ts +23 -0
- package/convex/crons.ts +37 -0
- package/convex/http.ts +421 -0
- package/convex/index.ts +20 -0
- package/convex/install.ts +172 -0
- package/convex/outbox.ts +198 -0
- package/convex/outboxProcessor.ts +240 -0
- package/convex/schema.ts +97 -0
- package/convex/sync.ts +327 -0
- package/dist/component.d.ts +34 -0
- package/dist/component.d.ts.map +1 -0
- package/dist/component.js +35 -0
- package/dist/component.js.map +1 -0
- package/dist/crdt.d.ts +82 -0
- package/dist/crdt.d.ts.map +1 -0
- package/dist/crdt.js +134 -0
- package/dist/crdt.js.map +1 -0
- package/dist/factories.d.ts +80 -0
- package/dist/factories.d.ts.map +1 -0
- package/dist/factories.js +159 -0
- package/dist/factories.js.map +1 -0
- package/dist/http.d.ts +238 -0
- package/dist/http.d.ts.map +1 -0
- package/dist/http.js +222 -0
- package/dist/http.js.map +1 -0
- package/dist/httpFactory.d.ts +39 -0
- package/dist/httpFactory.d.ts.map +1 -0
- package/dist/httpFactory.js +128 -0
- package/dist/httpFactory.js.map +1 -0
- package/dist/index.d.ts +68 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +73 -0
- package/dist/index.js.map +1 -0
- package/dist/schema.d.ts +217 -0
- package/dist/schema.d.ts.map +1 -0
- package/dist/schema.js +195 -0
- package/dist/schema.js.map +1 -0
- package/dist/syncFactories.d.ts +240 -0
- package/dist/syncFactories.d.ts.map +1 -0
- package/dist/syncFactories.js +623 -0
- package/dist/syncFactories.js.map +1 -0
- package/dist/triggers.d.ts +442 -0
- package/dist/triggers.d.ts.map +1 -0
- package/dist/triggers.js +705 -0
- package/dist/triggers.js.map +1 -0
- package/package.json +108 -0
- package/scripts/check-peer-deps.cjs +132 -0
package/dist/schema.d.ts
ADDED
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Schema helpers for defining synced tables.
|
|
3
|
+
*
|
|
4
|
+
* Provides:
|
|
5
|
+
* - `syncedTable` helper that wraps table definitions to enable automatic sync
|
|
6
|
+
* - `internalSyncSchema` that users spread into their schema for internal sync tables
|
|
7
|
+
*
|
|
8
|
+
* @module schema
|
|
9
|
+
*/
|
|
10
|
+
import { defineTable } from "convex/server";
|
|
11
|
+
/**
|
|
12
|
+
* Internal sync tables schema.
|
|
13
|
+
*
|
|
14
|
+
* These tables are required by the @fatagnus/dink-convex sync system.
|
|
15
|
+
* Spread this into your app's schema to include all internal tables:
|
|
16
|
+
*
|
|
17
|
+
* @example
|
|
18
|
+
* ```typescript
|
|
19
|
+
* // convex/schema.ts
|
|
20
|
+
* import { defineSchema } from "convex/server";
|
|
21
|
+
* import { syncedTable, internalSyncSchema } from "@fatagnus/dink-convex";
|
|
22
|
+
*
|
|
23
|
+
* export default defineSchema({
|
|
24
|
+
* // Your synced tables
|
|
25
|
+
* tasks: syncedTable({ title: v.string(), completed: v.boolean() }),
|
|
26
|
+
*
|
|
27
|
+
* // Spread internal sync tables (required)
|
|
28
|
+
* ...internalSyncSchema,
|
|
29
|
+
* });
|
|
30
|
+
* ```
|
|
31
|
+
*
|
|
32
|
+
* ## Why These Tables Are in Your Schema (Not Hidden in the Component)
|
|
33
|
+
*
|
|
34
|
+
* You might wonder why `@fatagnus/dink-convex` requires spreading these tables into your
|
|
35
|
+
* schema rather than hiding them entirely inside the component. This is due to
|
|
36
|
+
* a fundamental Convex constraint:
|
|
37
|
+
*
|
|
38
|
+
* **Convex mutations cannot call `ctx.runMutation()` to invoke other mutations.**
|
|
39
|
+
*
|
|
40
|
+
* This matters because:
|
|
41
|
+
* 1. Sync triggers run inside your mutation context (via convex-helpers Triggers)
|
|
42
|
+
* 2. Triggers must write delta/outbox records atomically in the same transaction
|
|
43
|
+
* 3. Component-internal tables can only be written via component mutations
|
|
44
|
+
* 4. Since triggers can't call component mutations, tables must be in app schema
|
|
45
|
+
*
|
|
46
|
+
* This ensures atomicity: your data changes and sync metadata are written together.
|
|
47
|
+
* If we used actions instead, a failure after your mutation but before recording
|
|
48
|
+
* the delta would leave data that never syncs.
|
|
49
|
+
*
|
|
50
|
+
* The practical impact is minimal - just one spread line in your schema. You never
|
|
51
|
+
* interact with these tables directly; they're managed entirely by the sync system.
|
|
52
|
+
*/
|
|
53
|
+
export declare const internalSyncSchema: {
|
|
54
|
+
/**
|
|
55
|
+
* sync_deltas - Stores CRDT delta updates for sync operations.
|
|
56
|
+
* Each delta represents a change that needs to be synchronized.
|
|
57
|
+
*/
|
|
58
|
+
readonly sync_deltas: import("convex/server").TableDefinition<import("convex/values").VObject<{
|
|
59
|
+
edgeId?: string | undefined;
|
|
60
|
+
bytes: ArrayBuffer;
|
|
61
|
+
collection: string;
|
|
62
|
+
docId: string;
|
|
63
|
+
seq: number;
|
|
64
|
+
timestamp: number;
|
|
65
|
+
}, {
|
|
66
|
+
/** Collection name (user table) */
|
|
67
|
+
collection: import("convex/values").VString<string, "required">;
|
|
68
|
+
/** Document sync ID (syncId from user table) */
|
|
69
|
+
docId: import("convex/values").VString<string, "required">;
|
|
70
|
+
/** CRDT delta bytes (Yjs update) */
|
|
71
|
+
bytes: import("convex/values").VBytes<ArrayBuffer, "required">;
|
|
72
|
+
/** Sequence number for ordering */
|
|
73
|
+
seq: import("convex/values").VFloat64<number, "required">;
|
|
74
|
+
/** Timestamp when delta was created */
|
|
75
|
+
timestamp: import("convex/values").VFloat64<number, "required">;
|
|
76
|
+
/** Edge ID that originated this delta (optional) */
|
|
77
|
+
edgeId: import("convex/values").VString<string | undefined, "optional">;
|
|
78
|
+
}, "required", "bytes" | "collection" | "docId" | "seq" | "timestamp" | "edgeId">, {
|
|
79
|
+
by_collection: ["collection", "_creationTime"];
|
|
80
|
+
by_docId: ["collection", "docId", "_creationTime"];
|
|
81
|
+
by_seq: ["collection", "seq", "_creationTime"];
|
|
82
|
+
}, {}, {}>;
|
|
83
|
+
/**
|
|
84
|
+
* sync_outbox - Queue of deltas pending push to dinkd.
|
|
85
|
+
* Deltas are queued here when triggers fire, then processed by
|
|
86
|
+
* the scheduled outbox processor which pushes them to dinkd.
|
|
87
|
+
*/
|
|
88
|
+
readonly sync_outbox: import("convex/server").TableDefinition<import("convex/values").VObject<{
|
|
89
|
+
lastAttempt?: number | undefined;
|
|
90
|
+
collection: string;
|
|
91
|
+
docId: string;
|
|
92
|
+
seq: number;
|
|
93
|
+
delta: ArrayBuffer;
|
|
94
|
+
status: string;
|
|
95
|
+
retries: number;
|
|
96
|
+
createdAt: number;
|
|
97
|
+
}, {
|
|
98
|
+
/** Collection name (user table) */
|
|
99
|
+
collection: import("convex/values").VString<string, "required">;
|
|
100
|
+
/** Document sync ID (syncId from user table) */
|
|
101
|
+
docId: import("convex/values").VString<string, "required">;
|
|
102
|
+
/** CRDT delta bytes to send */
|
|
103
|
+
delta: import("convex/values").VBytes<ArrayBuffer, "required">;
|
|
104
|
+
/** Sequence number for deduplication */
|
|
105
|
+
seq: import("convex/values").VFloat64<number, "required">;
|
|
106
|
+
/** Status: "pending" | "sent" | "failed" */
|
|
107
|
+
status: import("convex/values").VString<string, "required">;
|
|
108
|
+
/** Number of retry attempts */
|
|
109
|
+
retries: import("convex/values").VFloat64<number, "required">;
|
|
110
|
+
/** Timestamp when item was created */
|
|
111
|
+
createdAt: import("convex/values").VFloat64<number, "required">;
|
|
112
|
+
/** Timestamp of last send attempt (optional) */
|
|
113
|
+
lastAttempt: import("convex/values").VFloat64<number | undefined, "optional">;
|
|
114
|
+
}, "required", "collection" | "docId" | "seq" | "delta" | "status" | "retries" | "createdAt" | "lastAttempt">, {
|
|
115
|
+
by_status: ["status", "_creationTime"];
|
|
116
|
+
by_collection: ["collection", "_creationTime"];
|
|
117
|
+
by_docId_seq: ["docId", "seq", "_creationTime"];
|
|
118
|
+
}, {}, {}>;
|
|
119
|
+
/**
|
|
120
|
+
* sync_sessions - Tracks connected sessions and their sync state.
|
|
121
|
+
*/
|
|
122
|
+
readonly sync_sessions: import("convex/server").TableDefinition<import("convex/values").VObject<{
|
|
123
|
+
collection: string;
|
|
124
|
+
sessionId: string;
|
|
125
|
+
lastSeq: number;
|
|
126
|
+
lastSeen: number;
|
|
127
|
+
}, {
|
|
128
|
+
/** Unique session identifier */
|
|
129
|
+
sessionId: import("convex/values").VString<string, "required">;
|
|
130
|
+
/** Collection being synced */
|
|
131
|
+
collection: import("convex/values").VString<string, "required">;
|
|
132
|
+
/** Last sequence number acknowledged by this session */
|
|
133
|
+
lastSeq: import("convex/values").VFloat64<number, "required">;
|
|
134
|
+
/** Timestamp when session was last active */
|
|
135
|
+
lastSeen: import("convex/values").VFloat64<number, "required">;
|
|
136
|
+
}, "required", "collection" | "sessionId" | "lastSeq" | "lastSeen">, {
|
|
137
|
+
by_sessionId: ["sessionId", "_creationTime"];
|
|
138
|
+
by_collection: ["collection", "_creationTime"];
|
|
139
|
+
}, {}, {}>;
|
|
140
|
+
/**
|
|
141
|
+
* sync_config - Configuration for which tables have sync enabled.
|
|
142
|
+
*/
|
|
143
|
+
readonly sync_config: import("convex/server").TableDefinition<import("convex/values").VObject<{
|
|
144
|
+
collection: string;
|
|
145
|
+
enabled: boolean;
|
|
146
|
+
}, {
|
|
147
|
+
/** Collection name (user table) */
|
|
148
|
+
collection: import("convex/values").VString<string, "required">;
|
|
149
|
+
/** Whether sync is enabled for this collection */
|
|
150
|
+
enabled: import("convex/values").VBoolean<boolean, "required">;
|
|
151
|
+
}, "required", "collection" | "enabled">, {
|
|
152
|
+
by_collection: ["collection", "_creationTime"];
|
|
153
|
+
}, {}, {}>;
|
|
154
|
+
};
|
|
155
|
+
/**
|
|
156
|
+
* Configuration options for syncedTable.
|
|
157
|
+
*/
|
|
158
|
+
export interface SyncedTableConfig {
|
|
159
|
+
/** Optional custom sync ID field name (defaults to syncId) */
|
|
160
|
+
syncIdField?: string;
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* Register a table name as a synced table.
|
|
164
|
+
* Called internally or by developers to track which tables need sync enabled.
|
|
165
|
+
*
|
|
166
|
+
* @param tableName - The name of the table to register
|
|
167
|
+
*/
|
|
168
|
+
export declare function registerSyncedTableName(tableName: string): void;
|
|
169
|
+
/**
|
|
170
|
+
* Get all registered synced table names.
|
|
171
|
+
* Used during installation to auto-enable sync for all registered tables.
|
|
172
|
+
*
|
|
173
|
+
* @returns Array of registered table names
|
|
174
|
+
*/
|
|
175
|
+
export declare function getRegisteredSyncedTables(): string[];
|
|
176
|
+
/**
|
|
177
|
+
* Clear all registered synced tables.
|
|
178
|
+
* Useful for testing.
|
|
179
|
+
*/
|
|
180
|
+
export declare function clearRegisteredSyncedTables(): void;
|
|
181
|
+
/**
|
|
182
|
+
* The return type of defineTable - a table definition that can have indexes added.
|
|
183
|
+
*/
|
|
184
|
+
type TableDefinition = ReturnType<typeof defineTable>;
|
|
185
|
+
/**
|
|
186
|
+
* Field validators type - the object passed to defineTable
|
|
187
|
+
* Using a simple record type since Convex validators are complex
|
|
188
|
+
*/
|
|
189
|
+
type ValidatorFields = Record<string, any>;
|
|
190
|
+
/**
|
|
191
|
+
* Creates a synced Convex table definition with sync-related fields and indexes.
|
|
192
|
+
*
|
|
193
|
+
* This helper automatically adds:
|
|
194
|
+
* - A sync ID field (default: syncId) for tracking document sync state
|
|
195
|
+
* - An index on the sync ID field for efficient sync queries
|
|
196
|
+
*
|
|
197
|
+
* @param fields - The field validators for the table (same as what you'd pass to defineTable)
|
|
198
|
+
* @param config - Optional configuration for sync behavior
|
|
199
|
+
* @returns A table definition with sync fields and indexes included
|
|
200
|
+
*
|
|
201
|
+
* @example
|
|
202
|
+
* ```typescript
|
|
203
|
+
* import { defineSchema } from "convex/server";
|
|
204
|
+
* import { v } from "convex/values";
|
|
205
|
+
* import { syncedTable } from "@fatagnus/dink-convex";
|
|
206
|
+
*
|
|
207
|
+
* export default defineSchema({
|
|
208
|
+
* tasks: syncedTable({
|
|
209
|
+
* text: v.string(),
|
|
210
|
+
* isCompleted: v.boolean(),
|
|
211
|
+
* }),
|
|
212
|
+
* });
|
|
213
|
+
* ```
|
|
214
|
+
*/
|
|
215
|
+
export declare function syncedTable<T extends ValidatorFields>(fields: T, config?: SyncedTableConfig): TableDefinition;
|
|
216
|
+
export {};
|
|
217
|
+
//# sourceMappingURL=schema.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../src/schema.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAG5C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyCG;AACH,eAAO,MAAM,kBAAkB;IAC7B;;;OAGG;;;;;;;;;QAED,mCAAmC;;QAEnC,gDAAgD;;QAEhD,oCAAoC;;QAEpC,mCAAmC;;QAEnC,uCAAuC;;QAEvC,oDAAoD;;;;;;;IAOtD;;;;OAIG;;;;;;;;;;;QAED,mCAAmC;;QAEnC,gDAAgD;;QAEhD,+BAA+B;;QAE/B,wCAAwC;;QAExC,4CAA4C;;QAE5C,+BAA+B;;QAE/B,sCAAsC;;QAEtC,gDAAgD;;;;;;;IAOlD;;OAEG;;;;;;;QAED,gCAAgC;;QAEhC,8BAA8B;;QAE9B,wDAAwD;;QAExD,6CAA6C;;;;;;IAM/C;;OAEG;;;;;QAED,mCAAmC;;QAEnC,kDAAkD;;;;;CAG5C,CAAC;AAEX;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,8DAA8D;IAC9D,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAQD;;;;;GAKG;AACH,wBAAgB,uBAAuB,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAE/D;AAED;;;;;GAKG;AACH,wBAAgB,yBAAyB,IAAI,MAAM,EAAE,CAEpD;AAED;;;GAGG;AACH,wBAAgB,2BAA2B,IAAI,IAAI,CAElD;AAED;;GAEG;AACH,KAAK,eAAe,GAAG,UAAU,CAAC,OAAO,WAAW,CAAC,CAAC;AAEtD;;;GAGG;AAEH,KAAK,eAAe,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;AAE3C;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,WAAW,CAAC,CAAC,SAAS,eAAe,EACnD,MAAM,EAAE,CAAC,EACT,MAAM,CAAC,EAAE,iBAAiB,GACzB,eAAe,CAcjB"}
|
package/dist/schema.js
ADDED
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Schema helpers for defining synced tables.
|
|
3
|
+
*
|
|
4
|
+
* Provides:
|
|
5
|
+
* - `syncedTable` helper that wraps table definitions to enable automatic sync
|
|
6
|
+
* - `internalSyncSchema` that users spread into their schema for internal sync tables
|
|
7
|
+
*
|
|
8
|
+
* @module schema
|
|
9
|
+
*/
|
|
10
|
+
import { defineTable } from "convex/server";
|
|
11
|
+
import { v } from "convex/values";
|
|
12
|
+
/**
|
|
13
|
+
* Internal sync tables schema.
|
|
14
|
+
*
|
|
15
|
+
* These tables are required by the @fatagnus/dink-convex sync system.
|
|
16
|
+
* Spread this into your app's schema to include all internal tables:
|
|
17
|
+
*
|
|
18
|
+
* @example
|
|
19
|
+
* ```typescript
|
|
20
|
+
* // convex/schema.ts
|
|
21
|
+
* import { defineSchema } from "convex/server";
|
|
22
|
+
* import { syncedTable, internalSyncSchema } from "@fatagnus/dink-convex";
|
|
23
|
+
*
|
|
24
|
+
* export default defineSchema({
|
|
25
|
+
* // Your synced tables
|
|
26
|
+
* tasks: syncedTable({ title: v.string(), completed: v.boolean() }),
|
|
27
|
+
*
|
|
28
|
+
* // Spread internal sync tables (required)
|
|
29
|
+
* ...internalSyncSchema,
|
|
30
|
+
* });
|
|
31
|
+
* ```
|
|
32
|
+
*
|
|
33
|
+
* ## Why These Tables Are in Your Schema (Not Hidden in the Component)
|
|
34
|
+
*
|
|
35
|
+
* You might wonder why `@fatagnus/dink-convex` requires spreading these tables into your
|
|
36
|
+
* schema rather than hiding them entirely inside the component. This is due to
|
|
37
|
+
* a fundamental Convex constraint:
|
|
38
|
+
*
|
|
39
|
+
* **Convex mutations cannot call `ctx.runMutation()` to invoke other mutations.**
|
|
40
|
+
*
|
|
41
|
+
* This matters because:
|
|
42
|
+
* 1. Sync triggers run inside your mutation context (via convex-helpers Triggers)
|
|
43
|
+
* 2. Triggers must write delta/outbox records atomically in the same transaction
|
|
44
|
+
* 3. Component-internal tables can only be written via component mutations
|
|
45
|
+
* 4. Since triggers can't call component mutations, tables must be in app schema
|
|
46
|
+
*
|
|
47
|
+
* This ensures atomicity: your data changes and sync metadata are written together.
|
|
48
|
+
* If we used actions instead, a failure after your mutation but before recording
|
|
49
|
+
* the delta would leave data that never syncs.
|
|
50
|
+
*
|
|
51
|
+
* The practical impact is minimal - just one spread line in your schema. You never
|
|
52
|
+
* interact with these tables directly; they're managed entirely by the sync system.
|
|
53
|
+
*/
|
|
54
|
+
export const internalSyncSchema = {
|
|
55
|
+
/**
|
|
56
|
+
* sync_deltas - Stores CRDT delta updates for sync operations.
|
|
57
|
+
* Each delta represents a change that needs to be synchronized.
|
|
58
|
+
*/
|
|
59
|
+
sync_deltas: defineTable({
|
|
60
|
+
/** Collection name (user table) */
|
|
61
|
+
collection: v.string(),
|
|
62
|
+
/** Document sync ID (syncId from user table) */
|
|
63
|
+
docId: v.string(),
|
|
64
|
+
/** CRDT delta bytes (Yjs update) */
|
|
65
|
+
bytes: v.bytes(),
|
|
66
|
+
/** Sequence number for ordering */
|
|
67
|
+
seq: v.number(),
|
|
68
|
+
/** Timestamp when delta was created */
|
|
69
|
+
timestamp: v.number(),
|
|
70
|
+
/** Edge ID that originated this delta (optional) */
|
|
71
|
+
edgeId: v.optional(v.string()),
|
|
72
|
+
})
|
|
73
|
+
.index("by_collection", ["collection"])
|
|
74
|
+
.index("by_docId", ["collection", "docId"])
|
|
75
|
+
.index("by_seq", ["collection", "seq"]),
|
|
76
|
+
/**
|
|
77
|
+
* sync_outbox - Queue of deltas pending push to dinkd.
|
|
78
|
+
* Deltas are queued here when triggers fire, then processed by
|
|
79
|
+
* the scheduled outbox processor which pushes them to dinkd.
|
|
80
|
+
*/
|
|
81
|
+
sync_outbox: defineTable({
|
|
82
|
+
/** Collection name (user table) */
|
|
83
|
+
collection: v.string(),
|
|
84
|
+
/** Document sync ID (syncId from user table) */
|
|
85
|
+
docId: v.string(),
|
|
86
|
+
/** CRDT delta bytes to send */
|
|
87
|
+
delta: v.bytes(),
|
|
88
|
+
/** Sequence number for deduplication */
|
|
89
|
+
seq: v.number(),
|
|
90
|
+
/** Status: "pending" | "sent" | "failed" */
|
|
91
|
+
status: v.string(),
|
|
92
|
+
/** Number of retry attempts */
|
|
93
|
+
retries: v.number(),
|
|
94
|
+
/** Timestamp when item was created */
|
|
95
|
+
createdAt: v.number(),
|
|
96
|
+
/** Timestamp of last send attempt (optional) */
|
|
97
|
+
lastAttempt: v.optional(v.number()),
|
|
98
|
+
})
|
|
99
|
+
.index("by_status", ["status"])
|
|
100
|
+
.index("by_collection", ["collection"])
|
|
101
|
+
.index("by_docId_seq", ["docId", "seq"]),
|
|
102
|
+
/**
|
|
103
|
+
* sync_sessions - Tracks connected sessions and their sync state.
|
|
104
|
+
*/
|
|
105
|
+
sync_sessions: defineTable({
|
|
106
|
+
/** Unique session identifier */
|
|
107
|
+
sessionId: v.string(),
|
|
108
|
+
/** Collection being synced */
|
|
109
|
+
collection: v.string(),
|
|
110
|
+
/** Last sequence number acknowledged by this session */
|
|
111
|
+
lastSeq: v.number(),
|
|
112
|
+
/** Timestamp when session was last active */
|
|
113
|
+
lastSeen: v.number(),
|
|
114
|
+
})
|
|
115
|
+
.index("by_sessionId", ["sessionId"])
|
|
116
|
+
.index("by_collection", ["collection"]),
|
|
117
|
+
/**
|
|
118
|
+
* sync_config - Configuration for which tables have sync enabled.
|
|
119
|
+
*/
|
|
120
|
+
sync_config: defineTable({
|
|
121
|
+
/** Collection name (user table) */
|
|
122
|
+
collection: v.string(),
|
|
123
|
+
/** Whether sync is enabled for this collection */
|
|
124
|
+
enabled: v.boolean(),
|
|
125
|
+
}).index("by_collection", ["collection"]),
|
|
126
|
+
};
|
|
127
|
+
/**
|
|
128
|
+
* Registry of table names that use syncedTable().
|
|
129
|
+
* Used during installation to auto-register collections in _sync_config.
|
|
130
|
+
*/
|
|
131
|
+
const registeredSyncedTables = new Set();
|
|
132
|
+
/**
|
|
133
|
+
* Register a table name as a synced table.
|
|
134
|
+
* Called internally or by developers to track which tables need sync enabled.
|
|
135
|
+
*
|
|
136
|
+
* @param tableName - The name of the table to register
|
|
137
|
+
*/
|
|
138
|
+
export function registerSyncedTableName(tableName) {
|
|
139
|
+
registeredSyncedTables.add(tableName);
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Get all registered synced table names.
|
|
143
|
+
* Used during installation to auto-enable sync for all registered tables.
|
|
144
|
+
*
|
|
145
|
+
* @returns Array of registered table names
|
|
146
|
+
*/
|
|
147
|
+
export function getRegisteredSyncedTables() {
|
|
148
|
+
return Array.from(registeredSyncedTables);
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* Clear all registered synced tables.
|
|
152
|
+
* Useful for testing.
|
|
153
|
+
*/
|
|
154
|
+
export function clearRegisteredSyncedTables() {
|
|
155
|
+
registeredSyncedTables.clear();
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Creates a synced Convex table definition with sync-related fields and indexes.
|
|
159
|
+
*
|
|
160
|
+
* This helper automatically adds:
|
|
161
|
+
* - A sync ID field (default: syncId) for tracking document sync state
|
|
162
|
+
* - An index on the sync ID field for efficient sync queries
|
|
163
|
+
*
|
|
164
|
+
* @param fields - The field validators for the table (same as what you'd pass to defineTable)
|
|
165
|
+
* @param config - Optional configuration for sync behavior
|
|
166
|
+
* @returns A table definition with sync fields and indexes included
|
|
167
|
+
*
|
|
168
|
+
* @example
|
|
169
|
+
* ```typescript
|
|
170
|
+
* import { defineSchema } from "convex/server";
|
|
171
|
+
* import { v } from "convex/values";
|
|
172
|
+
* import { syncedTable } from "@fatagnus/dink-convex";
|
|
173
|
+
*
|
|
174
|
+
* export default defineSchema({
|
|
175
|
+
* tasks: syncedTable({
|
|
176
|
+
* text: v.string(),
|
|
177
|
+
* isCompleted: v.boolean(),
|
|
178
|
+
* }),
|
|
179
|
+
* });
|
|
180
|
+
* ```
|
|
181
|
+
*/
|
|
182
|
+
export function syncedTable(fields, config) {
|
|
183
|
+
// Use "syncId" without underscore prefix since Convex doesn't allow reserved fields in indexes
|
|
184
|
+
const syncIdField = config?.syncIdField ?? "syncId";
|
|
185
|
+
const indexName = `by_${syncIdField}`;
|
|
186
|
+
// Create table with original fields plus sync ID field
|
|
187
|
+
const extendedFields = {
|
|
188
|
+
...fields,
|
|
189
|
+
[syncIdField]: v.optional(v.string()),
|
|
190
|
+
};
|
|
191
|
+
// Create table definition using Convex's defineTable and add the sync index
|
|
192
|
+
// Cast to any to work around strict typing on index fields
|
|
193
|
+
return defineTable(extendedFields).index(indexName, [syncIdField]);
|
|
194
|
+
}
|
|
195
|
+
//# sourceMappingURL=schema.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema.js","sourceRoot":"","sources":["../src/schema.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Sync factories for @fatagnus/dink-convex component.
|
|
3
|
+
*
|
|
4
|
+
* These factories create Convex function definitions using the user's
|
|
5
|
+
* _generated imports, keeping all complex logic in the package while
|
|
6
|
+
* reducing user boilerplate to ~5 lines per file.
|
|
7
|
+
*
|
|
8
|
+
* @module syncFactories
|
|
9
|
+
*/
|
|
10
|
+
import { httpRouter, cronJobs } from "convex/server";
|
|
11
|
+
/**
|
|
12
|
+
* Convex mutation builder type from _generated/server.
|
|
13
|
+
*/
|
|
14
|
+
type MutationBuilder = <Args extends Record<string, unknown>, Returns>(def: {
|
|
15
|
+
args: Record<string, unknown>;
|
|
16
|
+
returns: unknown;
|
|
17
|
+
handler: (ctx: MutationCtx, args: Args) => Promise<Returns>;
|
|
18
|
+
}) => unknown;
|
|
19
|
+
/**
|
|
20
|
+
* Convex query builder type from _generated/server.
|
|
21
|
+
*/
|
|
22
|
+
type QueryBuilder = <Args extends Record<string, unknown>, Returns>(def: {
|
|
23
|
+
args: Record<string, unknown>;
|
|
24
|
+
returns: unknown;
|
|
25
|
+
handler: (ctx: QueryCtx, args: Args) => Promise<Returns>;
|
|
26
|
+
}) => unknown;
|
|
27
|
+
/**
|
|
28
|
+
* Convex internalAction builder type from _generated/server.
|
|
29
|
+
*/
|
|
30
|
+
type InternalActionBuilder = <Args extends Record<string, unknown>, Returns>(def: {
|
|
31
|
+
args: Record<string, unknown>;
|
|
32
|
+
returns: unknown;
|
|
33
|
+
handler: (ctx: ActionCtx, args: Args) => Promise<Returns>;
|
|
34
|
+
}) => unknown;
|
|
35
|
+
/**
|
|
36
|
+
* Convex internalMutation builder type from _generated/server.
|
|
37
|
+
*/
|
|
38
|
+
type InternalMutationBuilder = <Args extends Record<string, unknown>, Returns>(def: {
|
|
39
|
+
args: Record<string, unknown>;
|
|
40
|
+
returns: unknown;
|
|
41
|
+
handler: (ctx: MutationCtx, args: Args) => Promise<Returns>;
|
|
42
|
+
}) => unknown;
|
|
43
|
+
/**
|
|
44
|
+
* Convex internalQuery builder type from _generated/server.
|
|
45
|
+
*/
|
|
46
|
+
type InternalQueryBuilder = <Args extends Record<string, unknown>, Returns>(def: {
|
|
47
|
+
args: Record<string, unknown>;
|
|
48
|
+
returns: unknown;
|
|
49
|
+
handler: (ctx: QueryCtx, args: Args) => Promise<Returns>;
|
|
50
|
+
}) => unknown;
|
|
51
|
+
/**
|
|
52
|
+
* Convex httpAction builder type from _generated/server.
|
|
53
|
+
*/
|
|
54
|
+
type HttpActionBuilder = (handler: (ctx: ActionCtx, request: Request) => Promise<Response>) => unknown;
|
|
55
|
+
/**
|
|
56
|
+
* Mutation context type.
|
|
57
|
+
*/
|
|
58
|
+
interface MutationCtx {
|
|
59
|
+
db: {
|
|
60
|
+
insert: (table: string, doc: Record<string, unknown>) => Promise<string>;
|
|
61
|
+
patch: (id: string, fields: Record<string, unknown>) => Promise<void>;
|
|
62
|
+
delete: (id: string) => Promise<void>;
|
|
63
|
+
query: (table: string) => {
|
|
64
|
+
order: (dir: "asc" | "desc") => {
|
|
65
|
+
first: () => Promise<Record<string, unknown> | null>;
|
|
66
|
+
};
|
|
67
|
+
withIndex: (indexName: string, queryFn: (q: {
|
|
68
|
+
eq: (field: string, value: unknown) => unknown;
|
|
69
|
+
}) => unknown) => {
|
|
70
|
+
first: () => Promise<Record<string, unknown> | null>;
|
|
71
|
+
collect: () => Promise<Array<Record<string, unknown>>>;
|
|
72
|
+
};
|
|
73
|
+
collect: () => Promise<Array<Record<string, unknown>>>;
|
|
74
|
+
};
|
|
75
|
+
};
|
|
76
|
+
scheduler: {
|
|
77
|
+
runAfter: (delay: number, fn: unknown, args: unknown) => Promise<unknown>;
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Query context type.
|
|
82
|
+
*/
|
|
83
|
+
interface QueryCtx {
|
|
84
|
+
db: MutationCtx["db"];
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Action context type.
|
|
88
|
+
*/
|
|
89
|
+
interface ActionCtx {
|
|
90
|
+
runQuery: (fn: unknown, args: unknown) => Promise<unknown>;
|
|
91
|
+
runMutation: (fn: unknown, args: unknown) => Promise<unknown>;
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Input for createSyncMutations factory.
|
|
95
|
+
*/
|
|
96
|
+
export interface SyncMutationsInput {
|
|
97
|
+
/** mutation builder from _generated/server */
|
|
98
|
+
mutation: MutationBuilder;
|
|
99
|
+
/** query builder from _generated/server */
|
|
100
|
+
query: QueryBuilder;
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Output from createSyncMutations factory.
|
|
104
|
+
*/
|
|
105
|
+
export interface SyncMutationsOutput {
|
|
106
|
+
applyDeltaFromEdge: unknown;
|
|
107
|
+
getDocumentState: unknown;
|
|
108
|
+
listDocuments: unknown;
|
|
109
|
+
listDocumentsPaginated: unknown;
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Create sync mutations and queries.
|
|
113
|
+
*
|
|
114
|
+
* Returns the Convex function definitions for handling CRDT delta operations.
|
|
115
|
+
* The applyDeltaFromEdge mutation skips outbox queueing to prevent sync loops.
|
|
116
|
+
*
|
|
117
|
+
* @param input - Object containing mutation and query builders from _generated/server
|
|
118
|
+
* @returns Object with applyDeltaFromEdge, getDocumentState, listDocuments, listDocumentsPaginated
|
|
119
|
+
*
|
|
120
|
+
* @example
|
|
121
|
+
* ```typescript
|
|
122
|
+
* // convex/sync.ts (~5 lines!)
|
|
123
|
+
* import { createSyncMutations } from "@fatagnus/dink-convex";
|
|
124
|
+
* import { mutation, query } from "./_generated/server";
|
|
125
|
+
*
|
|
126
|
+
* export const { applyDeltaFromEdge, getDocumentState, listDocuments, listDocumentsPaginated } =
|
|
127
|
+
* createSyncMutations({ mutation, query });
|
|
128
|
+
* ```
|
|
129
|
+
*/
|
|
130
|
+
export declare function createSyncMutations(input: SyncMutationsInput): SyncMutationsOutput;
|
|
131
|
+
/**
|
|
132
|
+
* Input for createOutboxProcessor factory.
|
|
133
|
+
*/
|
|
134
|
+
export interface OutboxProcessorInput {
|
|
135
|
+
/** internalAction builder from _generated/server */
|
|
136
|
+
internalAction: InternalActionBuilder;
|
|
137
|
+
/** internalMutation builder from _generated/server */
|
|
138
|
+
internalMutation: InternalMutationBuilder;
|
|
139
|
+
/** internalQuery builder from _generated/server */
|
|
140
|
+
internalQuery: InternalQueryBuilder;
|
|
141
|
+
/** internal API from _generated/api */
|
|
142
|
+
internal: {
|
|
143
|
+
outboxProcessor: {
|
|
144
|
+
queryPendingItems: unknown;
|
|
145
|
+
updateItemStatus: unknown;
|
|
146
|
+
processOutboxBatch: unknown;
|
|
147
|
+
};
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* Output from createOutboxProcessor factory.
|
|
152
|
+
*/
|
|
153
|
+
export interface OutboxProcessorOutput {
|
|
154
|
+
processOutboxBatch: unknown;
|
|
155
|
+
queryPendingItems: unknown;
|
|
156
|
+
updateItemStatus: unknown;
|
|
157
|
+
scheduleOutboxProcessing: unknown;
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* Create outbox processor functions.
|
|
161
|
+
*
|
|
162
|
+
* Returns Convex function definitions for processing the sync_outbox table
|
|
163
|
+
* and pushing deltas to dinkd.
|
|
164
|
+
*
|
|
165
|
+
* @param input - Object containing internalAction, internalMutation, internalQuery, and internal API
|
|
166
|
+
* @returns Object with processOutboxBatch, queryPendingItems, updateItemStatus, scheduleOutboxProcessing
|
|
167
|
+
*
|
|
168
|
+
* @example
|
|
169
|
+
* ```typescript
|
|
170
|
+
* // convex/outboxProcessor.ts (~5 lines!)
|
|
171
|
+
* import { createOutboxProcessor } from "@fatagnus/dink-convex";
|
|
172
|
+
* import { internalAction, internalMutation, internalQuery } from "./_generated/server";
|
|
173
|
+
* import { internal } from "./_generated/api";
|
|
174
|
+
*
|
|
175
|
+
* export const { processOutboxBatch, queryPendingItems, updateItemStatus, scheduleOutboxProcessing } =
|
|
176
|
+
* createOutboxProcessor({ internalAction, internalMutation, internalQuery, internal });
|
|
177
|
+
* ```
|
|
178
|
+
*/
|
|
179
|
+
export declare function createOutboxProcessor(input: OutboxProcessorInput): OutboxProcessorOutput;
|
|
180
|
+
/**
|
|
181
|
+
* Input for createSyncHttpRouter factory.
|
|
182
|
+
*/
|
|
183
|
+
export interface SyncHttpRouterInput {
|
|
184
|
+
/** httpAction builder from _generated/server */
|
|
185
|
+
httpAction: HttpActionBuilder;
|
|
186
|
+
/** api from _generated/api */
|
|
187
|
+
api: {
|
|
188
|
+
sync: {
|
|
189
|
+
applyDeltaFromEdge: unknown;
|
|
190
|
+
};
|
|
191
|
+
};
|
|
192
|
+
}
|
|
193
|
+
/**
|
|
194
|
+
* Create sync HTTP router with /dink/applyDelta endpoint.
|
|
195
|
+
*
|
|
196
|
+
* @param input - Object containing httpAction builder and api
|
|
197
|
+
* @returns HTTP router to export as default
|
|
198
|
+
*
|
|
199
|
+
* @example
|
|
200
|
+
* ```typescript
|
|
201
|
+
* // convex/http.ts (~5 lines!)
|
|
202
|
+
* import { createSyncHttpRouter } from "@fatagnus/dink-convex";
|
|
203
|
+
* import { httpAction } from "./_generated/server";
|
|
204
|
+
* import { api } from "./_generated/api";
|
|
205
|
+
*
|
|
206
|
+
* export default createSyncHttpRouter({ httpAction, api });
|
|
207
|
+
* ```
|
|
208
|
+
*/
|
|
209
|
+
export declare function createSyncHttpRouter(input: SyncHttpRouterInput): ReturnType<typeof httpRouter>;
|
|
210
|
+
/**
|
|
211
|
+
* Input for createSyncCrons factory.
|
|
212
|
+
*/
|
|
213
|
+
export interface SyncCronsInput {
|
|
214
|
+
/** internal API from _generated/api */
|
|
215
|
+
internal: {
|
|
216
|
+
outboxProcessor: {
|
|
217
|
+
processOutboxBatch: unknown;
|
|
218
|
+
};
|
|
219
|
+
};
|
|
220
|
+
/** Cron interval in minutes (default: 1) */
|
|
221
|
+
intervalMinutes?: number;
|
|
222
|
+
}
|
|
223
|
+
/**
|
|
224
|
+
* Create sync cron jobs for outbox processing.
|
|
225
|
+
*
|
|
226
|
+
* @param input - Object containing internal API
|
|
227
|
+
* @returns Cron jobs to export as default
|
|
228
|
+
*
|
|
229
|
+
* @example
|
|
230
|
+
* ```typescript
|
|
231
|
+
* // convex/crons.ts (~4 lines!)
|
|
232
|
+
* import { createSyncCrons } from "@fatagnus/dink-convex";
|
|
233
|
+
* import { internal } from "./_generated/api";
|
|
234
|
+
*
|
|
235
|
+
* export default createSyncCrons({ internal });
|
|
236
|
+
* ```
|
|
237
|
+
*/
|
|
238
|
+
export declare function createSyncCrons(input: SyncCronsInput): ReturnType<typeof cronJobs>;
|
|
239
|
+
export {};
|
|
240
|
+
//# sourceMappingURL=syncFactories.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"syncFactories.d.ts","sourceRoot":"","sources":["../src/syncFactories.ts"],"names":[],"mappings":"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"}
|