@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/http.js
ADDED
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HTTP endpoint utilities for dinkd communication.
|
|
3
|
+
*
|
|
4
|
+
* Provides helpers for the /api/dink/applyDelta HTTP endpoint
|
|
5
|
+
* that receives CRDT deltas from edge devices.
|
|
6
|
+
*
|
|
7
|
+
* @module http
|
|
8
|
+
*/
|
|
9
|
+
import * as Y from "yjs";
|
|
10
|
+
/**
|
|
11
|
+
* Validate the Authorization header for applyDelta endpoint.
|
|
12
|
+
*
|
|
13
|
+
* Expects: Authorization: Bearer <appSyncKey>
|
|
14
|
+
*
|
|
15
|
+
* @param header - The Authorization header value
|
|
16
|
+
* @param expectedKey - The expected app sync key
|
|
17
|
+
* @returns Validation result
|
|
18
|
+
*/
|
|
19
|
+
export function validateAuthHeader(header, expectedKey) {
|
|
20
|
+
if (!header || header.trim() === "") {
|
|
21
|
+
return { valid: false, error: "Missing Authorization header" };
|
|
22
|
+
}
|
|
23
|
+
if (!header.startsWith("Bearer ")) {
|
|
24
|
+
return { valid: false, error: "Authorization header must use Bearer scheme" };
|
|
25
|
+
}
|
|
26
|
+
const token = header.slice(7).trim();
|
|
27
|
+
if (!token || token !== expectedKey) {
|
|
28
|
+
return { valid: false, error: "Invalid authorization token" };
|
|
29
|
+
}
|
|
30
|
+
return { valid: true };
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Parse and validate the getSnapshot query parameters.
|
|
34
|
+
*
|
|
35
|
+
* @param params - The query parameters
|
|
36
|
+
* @returns Parsed parameters result
|
|
37
|
+
*/
|
|
38
|
+
export function parseGetSnapshotParams(params) {
|
|
39
|
+
if (!params || typeof params !== "object") {
|
|
40
|
+
return { success: false, error: "Invalid params: expected object" };
|
|
41
|
+
}
|
|
42
|
+
if (typeof params.collection !== "string" || !params.collection) {
|
|
43
|
+
return { success: false, error: "Invalid params: collection is required" };
|
|
44
|
+
}
|
|
45
|
+
if (typeof params.docId !== "string" || !params.docId) {
|
|
46
|
+
return { success: false, error: "Invalid params: docId is required" };
|
|
47
|
+
}
|
|
48
|
+
return {
|
|
49
|
+
success: true,
|
|
50
|
+
data: {
|
|
51
|
+
collection: params.collection,
|
|
52
|
+
docId: params.docId,
|
|
53
|
+
},
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Parse and validate the listDocuments query parameters.
|
|
58
|
+
*
|
|
59
|
+
* @param params - The query parameters
|
|
60
|
+
* @returns Parsed parameters result
|
|
61
|
+
*/
|
|
62
|
+
export function parseListDocumentsParams(params) {
|
|
63
|
+
if (!params || typeof params !== "object") {
|
|
64
|
+
return { success: false, error: "Invalid params: expected object" };
|
|
65
|
+
}
|
|
66
|
+
if (typeof params.collection !== "string" || !params.collection) {
|
|
67
|
+
return { success: false, error: "Invalid params: collection is required" };
|
|
68
|
+
}
|
|
69
|
+
const result = {
|
|
70
|
+
collection: params.collection,
|
|
71
|
+
};
|
|
72
|
+
if (params.cursor !== undefined) {
|
|
73
|
+
result.cursor = params.cursor;
|
|
74
|
+
}
|
|
75
|
+
if (params.limit !== undefined) {
|
|
76
|
+
result.limit = params.limit;
|
|
77
|
+
}
|
|
78
|
+
return {
|
|
79
|
+
success: true,
|
|
80
|
+
data: result,
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Parse and validate the applyDelta request payload.
|
|
85
|
+
*
|
|
86
|
+
* @param payload - The raw request payload
|
|
87
|
+
* @returns Parsed payload result
|
|
88
|
+
*/
|
|
89
|
+
export function parseApplyDeltaPayload(payload) {
|
|
90
|
+
if (!payload || typeof payload !== "object") {
|
|
91
|
+
return { success: false, error: "Invalid payload: expected object" };
|
|
92
|
+
}
|
|
93
|
+
if (typeof payload.collection !== "string" || !payload.collection) {
|
|
94
|
+
return { success: false, error: "Invalid payload: collection is required" };
|
|
95
|
+
}
|
|
96
|
+
if (typeof payload.docId !== "string" || !payload.docId) {
|
|
97
|
+
return { success: false, error: "Invalid payload: docId is required" };
|
|
98
|
+
}
|
|
99
|
+
if (!Array.isArray(payload.bytes)) {
|
|
100
|
+
return { success: false, error: "Invalid payload: bytes must be an array" };
|
|
101
|
+
}
|
|
102
|
+
// Convert number array to Uint8Array
|
|
103
|
+
const bytes = new Uint8Array(payload.bytes);
|
|
104
|
+
// Handle optional edgeId - only include if it's a string
|
|
105
|
+
const edgeId = typeof payload.edgeId === "string" ? payload.edgeId : undefined;
|
|
106
|
+
return {
|
|
107
|
+
success: true,
|
|
108
|
+
data: {
|
|
109
|
+
collection: payload.collection,
|
|
110
|
+
docId: payload.docId,
|
|
111
|
+
bytes,
|
|
112
|
+
edgeId,
|
|
113
|
+
},
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Apply a CRDT delta to an existing document state.
|
|
118
|
+
*
|
|
119
|
+
* Merges the incoming delta with the existing state using Yjs CRDT semantics.
|
|
120
|
+
* This is the core merge function used by the HTTP endpoint.
|
|
121
|
+
*
|
|
122
|
+
* @param delta - The incoming CRDT delta (Yjs update)
|
|
123
|
+
* @param existingState - The existing document state, or null for new document
|
|
124
|
+
* @returns Merged state result with fromEdge flag for skipping outbox
|
|
125
|
+
*/
|
|
126
|
+
export function applyDeltaToDocument(delta, existingState) {
|
|
127
|
+
try {
|
|
128
|
+
const ydoc = new Y.Doc();
|
|
129
|
+
// Apply existing state first if present
|
|
130
|
+
if (existingState) {
|
|
131
|
+
Y.applyUpdate(ydoc, existingState);
|
|
132
|
+
}
|
|
133
|
+
// Apply the incoming delta
|
|
134
|
+
Y.applyUpdate(ydoc, delta);
|
|
135
|
+
// Encode the merged state
|
|
136
|
+
const mergedState = Y.encodeStateAsUpdate(ydoc);
|
|
137
|
+
return {
|
|
138
|
+
success: true,
|
|
139
|
+
mergedState,
|
|
140
|
+
fromEdge: true, // Flag to indicate this came from edge, skip outbox
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
catch (error) {
|
|
144
|
+
const message = error instanceof Error ? error.message : "Unknown error";
|
|
145
|
+
return {
|
|
146
|
+
success: false,
|
|
147
|
+
error: `Failed to apply delta: ${message}`,
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* Create a JSON response with proper headers.
|
|
153
|
+
*
|
|
154
|
+
* @param data - Response data to serialize
|
|
155
|
+
* @param status - HTTP status code
|
|
156
|
+
* @returns Response object
|
|
157
|
+
*/
|
|
158
|
+
export function createJsonResponse(data, status) {
|
|
159
|
+
return new Response(JSON.stringify(data), {
|
|
160
|
+
status,
|
|
161
|
+
headers: {
|
|
162
|
+
"Content-Type": "application/json",
|
|
163
|
+
},
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* Create an error response with proper headers.
|
|
168
|
+
*
|
|
169
|
+
* @param error - Error message
|
|
170
|
+
* @param status - HTTP status code
|
|
171
|
+
* @returns Response object
|
|
172
|
+
*/
|
|
173
|
+
export function createErrorResponse(error, status) {
|
|
174
|
+
return createJsonResponse({ success: false, error }, status);
|
|
175
|
+
}
|
|
176
|
+
// Import serializeValue from crdt module to avoid duplication
|
|
177
|
+
import { serializeValue } from "./crdt.js";
|
|
178
|
+
/**
|
|
179
|
+
* Encode a document's data as a Yjs snapshot.
|
|
180
|
+
*
|
|
181
|
+
* Creates a Yjs document with all fields from the document data,
|
|
182
|
+
* compatible with the edge SDK's YjsDocument format.
|
|
183
|
+
*
|
|
184
|
+
* @param documentData - The document data to encode
|
|
185
|
+
* @returns Encoded snapshot result with Uint8Array bytes
|
|
186
|
+
*
|
|
187
|
+
* @example
|
|
188
|
+
* ```typescript
|
|
189
|
+
* const result = encodeDocumentAsSnapshot({
|
|
190
|
+
* _collection: "tasks",
|
|
191
|
+
* syncId: "sync-123",
|
|
192
|
+
* title: "My Task",
|
|
193
|
+
* completed: false,
|
|
194
|
+
* });
|
|
195
|
+
* ```
|
|
196
|
+
*/
|
|
197
|
+
export function encodeDocumentAsSnapshot(documentData) {
|
|
198
|
+
try {
|
|
199
|
+
const ydoc = new Y.Doc();
|
|
200
|
+
const fields = ydoc.getMap("fields");
|
|
201
|
+
// Add all document fields
|
|
202
|
+
for (const [key, value] of Object.entries(documentData)) {
|
|
203
|
+
if (value !== undefined) {
|
|
204
|
+
fields.set(key, serializeValue(value));
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
// Encode the state as an update (snapshot)
|
|
208
|
+
const bytes = Y.encodeStateAsUpdate(ydoc);
|
|
209
|
+
return {
|
|
210
|
+
success: true,
|
|
211
|
+
bytes,
|
|
212
|
+
};
|
|
213
|
+
}
|
|
214
|
+
catch (error) {
|
|
215
|
+
const message = error instanceof Error ? error.message : "Unknown error";
|
|
216
|
+
return {
|
|
217
|
+
success: false,
|
|
218
|
+
error: `Failed to encode snapshot: ${message}`,
|
|
219
|
+
};
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
//# sourceMappingURL=http.js.map
|
package/dist/http.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"http.js","sourceRoot":"","sources":["../src/http.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,CAAC,MAAM,KAAK,CAAC;AAiIzB;;;;;;;;GAQG;AACH,MAAM,UAAU,kBAAkB,CAChC,MAAqB,EACrB,WAAmB;IAEnB,IAAI,CAAC,MAAM,IAAI,MAAM,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;QACpC,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,8BAA8B,EAAE,CAAC;IACjE,CAAC;IAED,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;QAClC,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,6CAA6C,EAAE,CAAC;IAChF,CAAC;IAED,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;IACrC,IAAI,CAAC,KAAK,IAAI,KAAK,KAAK,WAAW,EAAE,CAAC;QACpC,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,6BAA6B,EAAE,CAAC;IAChE,CAAC;IAED,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;AACzB,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,sBAAsB,CACpC,MAAyB;IAEzB,IAAI,CAAC,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE,CAAC;QAC1C,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,iCAAiC,EAAE,CAAC;IACtE,CAAC;IAED,IAAI,OAAO,MAAM,CAAC,UAAU,KAAK,QAAQ,IAAI,CAAC,MAAM,CAAC,UAAU,EAAE,CAAC;QAChE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,wCAAwC,EAAE,CAAC;IAC7E,CAAC;IAED,IAAI,OAAO,MAAM,CAAC,KAAK,KAAK,QAAQ,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;QACtD,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,mCAAmC,EAAE,CAAC;IACxE,CAAC;IAED,OAAO;QACL,OAAO,EAAE,IAAI;QACb,IAAI,EAAE;YACJ,UAAU,EAAE,MAAM,CAAC,UAAU;YAC7B,KAAK,EAAE,MAAM,CAAC,KAAK;SACpB;KACF,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,wBAAwB,CACtC,MAA2B;IAE3B,IAAI,CAAC,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE,CAAC;QAC1C,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,iCAAiC,EAAE,CAAC;IACtE,CAAC;IAED,IAAI,OAAO,MAAM,CAAC,UAAU,KAAK,QAAQ,IAAI,CAAC,MAAM,CAAC,UAAU,EAAE,CAAC;QAChE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,wCAAwC,EAAE,CAAC;IAC7E,CAAC;IAED,MAAM,MAAM,GAA8B;QACxC,UAAU,EAAE,MAAM,CAAC,UAAU;KAC9B,CAAC;IAEF,IAAI,MAAM,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;QAChC,MAAM,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC;IAChC,CAAC;IAED,IAAI,MAAM,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;QAC/B,MAAM,CAAC,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC;IAC9B,CAAC;IAED,OAAO;QACL,OAAO,EAAE,IAAI;QACb,IAAI,EAAE,MAAM;KACb,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,sBAAsB,CACpC,OAA0B;IAE1B,IAAI,CAAC,OAAO,IAAI,OAAO,OAAO,KAAK,QAAQ,EAAE,CAAC;QAC5C,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,kCAAkC,EAAE,CAAC;IACvE,CAAC;IAED,IAAI,OAAO,OAAO,CAAC,UAAU,KAAK,QAAQ,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,CAAC;QAClE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,yCAAyC,EAAE,CAAC;IAC9E,CAAC;IAED,IAAI,OAAO,OAAO,CAAC,KAAK,KAAK,QAAQ,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;QACxD,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,oCAAoC,EAAE,CAAC;IACzE,CAAC;IAED,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QAClC,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,yCAAyC,EAAE,CAAC;IAC9E,CAAC;IAED,qCAAqC;IACrC,MAAM,KAAK,GAAG,IAAI,UAAU,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;IAE5C,yDAAyD;IACzD,MAAM,MAAM,GAAG,OAAO,OAAO,CAAC,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC;IAE/E,OAAO;QACL,OAAO,EAAE,IAAI;QACb,IAAI,EAAE;YACJ,UAAU,EAAE,OAAO,CAAC,UAAU;YAC9B,KAAK,EAAE,OAAO,CAAC,KAAK;YACpB,KAAK;YACL,MAAM;SACP;KACF,CAAC;AACJ,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,oBAAoB,CAClC,KAAiB,EACjB,aAAgC;IAEhC,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,IAAI,CAAC,CAAC,GAAG,EAAE,CAAC;QAEzB,wCAAwC;QACxC,IAAI,aAAa,EAAE,CAAC;YAClB,CAAC,CAAC,WAAW,CAAC,IAAI,EAAE,aAAa,CAAC,CAAC;QACrC,CAAC;QAED,2BAA2B;QAC3B,CAAC,CAAC,WAAW,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QAE3B,0BAA0B;QAC1B,MAAM,WAAW,GAAG,CAAC,CAAC,mBAAmB,CAAC,IAAI,CAAC,CAAC;QAEhD,OAAO;YACL,OAAO,EAAE,IAAI;YACb,WAAW;YACX,QAAQ,EAAE,IAAI,EAAE,oDAAoD;SACrE,CAAC;IACJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,CAAC;QACzE,OAAO;YACL,OAAO,EAAE,KAAK;YACd,KAAK,EAAE,0BAA0B,OAAO,EAAE;SAC3C,CAAC;IACJ,CAAC;AACH,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,kBAAkB,CAAC,IAAa,EAAE,MAAc;IAC9D,OAAO,IAAI,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE;QACxC,MAAM;QACN,OAAO,EAAE;YACP,cAAc,EAAE,kBAAkB;SACnC;KACF,CAAC,CAAC;AACL,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,mBAAmB,CAAC,KAAa,EAAE,MAAc;IAC/D,OAAO,kBAAkB,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,MAAM,CAAC,CAAC;AAC/D,CAAC;AAED,8DAA8D;AAC9D,OAAO,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAE3C;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,UAAU,wBAAwB,CACtC,YAAqC;IAErC,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,IAAI,CAAC,CAAC,GAAG,EAAE,CAAC;QACzB,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;QAErC,0BAA0B;QAC1B,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC,EAAE,CAAC;YACxD,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;gBACxB,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,cAAc,CAAC,KAAK,CAAC,CAAC,CAAC;YACzC,CAAC;QACH,CAAC;QAED,2CAA2C;QAC3C,MAAM,KAAK,GAAG,CAAC,CAAC,mBAAmB,CAAC,IAAI,CAAC,CAAC;QAE1C,OAAO;YACL,OAAO,EAAE,IAAI;YACb,KAAK;SACN,CAAC;IACJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,CAAC;QACzE,OAAO;YACL,OAAO,EAAE,KAAK;YACd,KAAK,EAAE,8BAA8B,OAAO,EAAE;SAC/C,CAAC;IACJ,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HTTP router factory for simplified @fatagnus/dink-convex setup.
|
|
3
|
+
*
|
|
4
|
+
* @module httpFactory
|
|
5
|
+
*/
|
|
6
|
+
import { httpRouter } from "convex/server";
|
|
7
|
+
/**
|
|
8
|
+
* API type expected by the HTTP router factory.
|
|
9
|
+
*/
|
|
10
|
+
interface SyncApi {
|
|
11
|
+
sync: {
|
|
12
|
+
applyDeltaFromEdge: unknown;
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Create a sync HTTP router with /dink/applyDelta endpoint.
|
|
17
|
+
*
|
|
18
|
+
* This factory creates an HTTP router pre-configured with the
|
|
19
|
+
* /dink/applyDelta endpoint for receiving CRDT deltas from edge devices.
|
|
20
|
+
*
|
|
21
|
+
* @param httpAction - The httpAction function from _generated/server
|
|
22
|
+
* @param api - The api from _generated/api
|
|
23
|
+
* @returns HTTP router to export as default
|
|
24
|
+
*
|
|
25
|
+
* @example
|
|
26
|
+
* ```typescript
|
|
27
|
+
* // convex/http.ts
|
|
28
|
+
* import { createSyncHttpRouter } from "@fatagnus/dink-convex";
|
|
29
|
+
* import { httpAction } from "./_generated/server";
|
|
30
|
+
* import { api } from "./_generated/api";
|
|
31
|
+
*
|
|
32
|
+
* export default createSyncHttpRouter(httpAction, api);
|
|
33
|
+
* ```
|
|
34
|
+
*/
|
|
35
|
+
export declare function createSyncHttpRouter(httpAction: (handler: (ctx: {
|
|
36
|
+
runMutation: (fn: unknown, args: unknown) => Promise<unknown>;
|
|
37
|
+
}, request: Request) => Promise<Response>) => unknown, api: SyncApi): ReturnType<typeof httpRouter>;
|
|
38
|
+
export {};
|
|
39
|
+
//# sourceMappingURL=httpFactory.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"httpFactory.d.ts","sourceRoot":"","sources":["../src/httpFactory.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAE3C;;GAEG;AACH,UAAU,OAAO;IACf,IAAI,EAAE;QACJ,kBAAkB,EAAE,OAAO,CAAC;KAC7B,CAAC;CACH;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,oBAAoB,CAClC,UAAU,EAAE,CACV,OAAO,EAAE,CACP,GAAG,EAAE;IAAE,WAAW,EAAE,CAAC,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,KAAK,OAAO,CAAC,OAAO,CAAC,CAAA;CAAE,EACtE,OAAO,EAAE,OAAO,KACb,OAAO,CAAC,QAAQ,CAAC,KACnB,OAAO,EACZ,GAAG,EAAE,OAAO,GACX,UAAU,CAAC,OAAO,UAAU,CAAC,CAoI/B"}
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HTTP router factory for simplified @fatagnus/dink-convex setup.
|
|
3
|
+
*
|
|
4
|
+
* @module httpFactory
|
|
5
|
+
*/
|
|
6
|
+
import { httpRouter } from "convex/server";
|
|
7
|
+
/**
|
|
8
|
+
* Create a sync HTTP router with /dink/applyDelta endpoint.
|
|
9
|
+
*
|
|
10
|
+
* This factory creates an HTTP router pre-configured with the
|
|
11
|
+
* /dink/applyDelta endpoint for receiving CRDT deltas from edge devices.
|
|
12
|
+
*
|
|
13
|
+
* @param httpAction - The httpAction function from _generated/server
|
|
14
|
+
* @param api - The api from _generated/api
|
|
15
|
+
* @returns HTTP router to export as default
|
|
16
|
+
*
|
|
17
|
+
* @example
|
|
18
|
+
* ```typescript
|
|
19
|
+
* // convex/http.ts
|
|
20
|
+
* import { createSyncHttpRouter } from "@fatagnus/dink-convex";
|
|
21
|
+
* import { httpAction } from "./_generated/server";
|
|
22
|
+
* import { api } from "./_generated/api";
|
|
23
|
+
*
|
|
24
|
+
* export default createSyncHttpRouter(httpAction, api);
|
|
25
|
+
* ```
|
|
26
|
+
*/
|
|
27
|
+
export function createSyncHttpRouter(httpAction, api) {
|
|
28
|
+
const http = httpRouter();
|
|
29
|
+
http.route({
|
|
30
|
+
path: "/dink/applyDelta",
|
|
31
|
+
method: "POST",
|
|
32
|
+
handler: httpAction(async (ctx, request) => {
|
|
33
|
+
// Validate Authorization header
|
|
34
|
+
const authHeader = request.headers.get("Authorization");
|
|
35
|
+
if (!authHeader || !authHeader.startsWith("Bearer ")) {
|
|
36
|
+
return new Response(JSON.stringify({
|
|
37
|
+
success: false,
|
|
38
|
+
error: "Missing or invalid Authorization header",
|
|
39
|
+
}), {
|
|
40
|
+
status: 401,
|
|
41
|
+
headers: { "Content-Type": "application/json" },
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
const token = authHeader.slice(7).trim();
|
|
45
|
+
if (!token) {
|
|
46
|
+
return new Response(JSON.stringify({
|
|
47
|
+
success: false,
|
|
48
|
+
error: "Missing authorization token",
|
|
49
|
+
}), {
|
|
50
|
+
status: 401,
|
|
51
|
+
headers: { "Content-Type": "application/json" },
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
// Parse request body
|
|
55
|
+
let payload;
|
|
56
|
+
try {
|
|
57
|
+
payload = await request.json();
|
|
58
|
+
}
|
|
59
|
+
catch {
|
|
60
|
+
return new Response(JSON.stringify({
|
|
61
|
+
success: false,
|
|
62
|
+
error: "Invalid JSON payload",
|
|
63
|
+
}), {
|
|
64
|
+
status: 400,
|
|
65
|
+
headers: { "Content-Type": "application/json" },
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
// Validate payload
|
|
69
|
+
if (!payload.collection || typeof payload.collection !== "string") {
|
|
70
|
+
return new Response(JSON.stringify({
|
|
71
|
+
success: false,
|
|
72
|
+
error: "Missing or invalid collection field",
|
|
73
|
+
}), {
|
|
74
|
+
status: 400,
|
|
75
|
+
headers: { "Content-Type": "application/json" },
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
if (!payload.docId || typeof payload.docId !== "string") {
|
|
79
|
+
return new Response(JSON.stringify({
|
|
80
|
+
success: false,
|
|
81
|
+
error: "Missing or invalid docId field",
|
|
82
|
+
}), {
|
|
83
|
+
status: 400,
|
|
84
|
+
headers: { "Content-Type": "application/json" },
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
if (!Array.isArray(payload.bytes)) {
|
|
88
|
+
return new Response(JSON.stringify({
|
|
89
|
+
success: false,
|
|
90
|
+
error: "Missing or invalid bytes field",
|
|
91
|
+
}), {
|
|
92
|
+
status: 400,
|
|
93
|
+
headers: { "Content-Type": "application/json" },
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
// Convert bytes array to ArrayBuffer for Convex
|
|
97
|
+
const bytes = new Uint8Array(payload.bytes).buffer;
|
|
98
|
+
try {
|
|
99
|
+
const result = (await ctx.runMutation(api.sync.applyDeltaFromEdge, {
|
|
100
|
+
collection: payload.collection,
|
|
101
|
+
docId: payload.docId,
|
|
102
|
+
bytes,
|
|
103
|
+
authToken: token,
|
|
104
|
+
edgeId: payload.edgeId,
|
|
105
|
+
}));
|
|
106
|
+
return new Response(JSON.stringify({
|
|
107
|
+
success: true,
|
|
108
|
+
seq: result.seq,
|
|
109
|
+
}), {
|
|
110
|
+
status: 200,
|
|
111
|
+
headers: { "Content-Type": "application/json" },
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
catch (error) {
|
|
115
|
+
const message = error instanceof Error ? error.message : "Unknown error";
|
|
116
|
+
return new Response(JSON.stringify({
|
|
117
|
+
success: false,
|
|
118
|
+
error: message,
|
|
119
|
+
}), {
|
|
120
|
+
status: 500,
|
|
121
|
+
headers: { "Content-Type": "application/json" },
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
}),
|
|
125
|
+
});
|
|
126
|
+
return http;
|
|
127
|
+
}
|
|
128
|
+
//# sourceMappingURL=httpFactory.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"httpFactory.js","sourceRoot":"","sources":["../src/httpFactory.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fatagnus/dink-convex - Dink Convex Sync Component
|
|
3
|
+
*
|
|
4
|
+
* Provides bidirectional sync between Convex and edge devices using CRDT deltas.
|
|
5
|
+
* Minimal boilerplate - each user file is just ~5 lines!
|
|
6
|
+
*
|
|
7
|
+
* ## Quick Start
|
|
8
|
+
*
|
|
9
|
+
* 1. Define your schema with syncedTable:
|
|
10
|
+
* ```typescript
|
|
11
|
+
* // convex/schema.ts
|
|
12
|
+
* import { syncedTable, internalSyncSchema } from "@fatagnus/dink-convex";
|
|
13
|
+
* export default defineSchema({
|
|
14
|
+
* tasks: syncedTable({ title: v.string(), completed: v.boolean() }),
|
|
15
|
+
* ...internalSyncSchema,
|
|
16
|
+
* });
|
|
17
|
+
* ```
|
|
18
|
+
*
|
|
19
|
+
* 2. Create sync mutations (5 lines!):
|
|
20
|
+
* ```typescript
|
|
21
|
+
* // convex/sync.ts
|
|
22
|
+
* import { createSyncMutations } from "@fatagnus/dink-convex";
|
|
23
|
+
* import { mutation, query } from "./_generated/server";
|
|
24
|
+
*
|
|
25
|
+
* export const { applyDeltaFromEdge, getDocumentState, listDocuments, listDocumentsPaginated } =
|
|
26
|
+
* createSyncMutations({ mutation, query });
|
|
27
|
+
* ```
|
|
28
|
+
*
|
|
29
|
+
* 3. Create outbox processor (5 lines!):
|
|
30
|
+
* ```typescript
|
|
31
|
+
* // convex/outboxProcessor.ts
|
|
32
|
+
* import { createOutboxProcessor } from "@fatagnus/dink-convex";
|
|
33
|
+
* import { internalAction, internalMutation, internalQuery } from "./_generated/server";
|
|
34
|
+
* import { internal } from "./_generated/api";
|
|
35
|
+
*
|
|
36
|
+
* export const { processOutboxBatch, queryPendingItems, updateItemStatus, scheduleOutboxProcessing } =
|
|
37
|
+
* createOutboxProcessor({ internalAction, internalMutation, internalQuery, internal });
|
|
38
|
+
* ```
|
|
39
|
+
*
|
|
40
|
+
* 4. Create HTTP router (4 lines!):
|
|
41
|
+
* ```typescript
|
|
42
|
+
* // convex/http.ts
|
|
43
|
+
* import { createSyncHttpRouter } from "@fatagnus/dink-convex";
|
|
44
|
+
* import { httpAction } from "./_generated/server";
|
|
45
|
+
* import { api } from "./_generated/api";
|
|
46
|
+
*
|
|
47
|
+
* export default createSyncHttpRouter({ httpAction, api });
|
|
48
|
+
* ```
|
|
49
|
+
*
|
|
50
|
+
* 5. Create crons (4 lines!):
|
|
51
|
+
* ```typescript
|
|
52
|
+
* // convex/crons.ts
|
|
53
|
+
* import { createSyncCrons } from "@fatagnus/dink-convex";
|
|
54
|
+
* import { internal } from "./_generated/api";
|
|
55
|
+
*
|
|
56
|
+
* export default createSyncCrons({ internal });
|
|
57
|
+
* ```
|
|
58
|
+
*
|
|
59
|
+
* @packageDocumentation
|
|
60
|
+
*/
|
|
61
|
+
export { syncedTable, internalSyncSchema, registerSyncedTableName, getRegisteredSyncedTables, clearRegisteredSyncedTables, } from "./schema.js";
|
|
62
|
+
export { generateInsertDelta, generateUpdateDelta, generateDeleteDelta, type DocumentData, } from "./crdt.js";
|
|
63
|
+
export { createSyncMutations, createOutboxProcessor, createSyncHttpRouter, createSyncCrons, type SyncMutationsInput, type SyncMutationsOutput, type OutboxProcessorInput, type OutboxProcessorOutput, type SyncHttpRouterInput, type SyncCronsInput, } from "./syncFactories.js";
|
|
64
|
+
export { createSyncMutation, type SyncCronsConfig } from "./factories.js";
|
|
65
|
+
export { syncTriggers, registerSyncedTable, isSyncedTable, getSyncConfig, createDeltaRecord, createOutboxRecord, createSyncTriggerHandler, createSyncTriggerHandlerAsync, createSyncTriggerHandlerWithScheduling, scheduleImmediateProcessing, getNextSeq, getNextSeqAsync, createSequenceCounter, checkSyncConfigEnabled, createSyncConfigChecker, createConfigAwareSyncTriggerHandler, createSyncTriggers, createSyncTriggersWithHandlers, customMutation, type SequenceCounter, } from "./triggers.js";
|
|
66
|
+
export declare const VERSION = "0.3.0";
|
|
67
|
+
export type { SyncedTableConfig } from "./schema.js";
|
|
68
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2DG;AAGH,OAAO,EACL,WAAW,EACX,kBAAkB,EAClB,uBAAuB,EACvB,yBAAyB,EACzB,2BAA2B,GAC5B,MAAM,aAAa,CAAC;AAGrB,OAAO,EACL,mBAAmB,EACnB,mBAAmB,EACnB,mBAAmB,EACnB,KAAK,YAAY,GAClB,MAAM,WAAW,CAAC;AAGnB,OAAO,EACL,mBAAmB,EACnB,qBAAqB,EACrB,oBAAoB,EACpB,eAAe,EACf,KAAK,kBAAkB,EACvB,KAAK,mBAAmB,EACxB,KAAK,oBAAoB,EACzB,KAAK,qBAAqB,EAC1B,KAAK,mBAAmB,EACxB,KAAK,cAAc,GACpB,MAAM,oBAAoB,CAAC;AAG5B,OAAO,EAAE,kBAAkB,EAAE,KAAK,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAG1E,OAAO,EACL,YAAY,EACZ,mBAAmB,EACnB,aAAa,EACb,aAAa,EACb,iBAAiB,EACjB,kBAAkB,EAClB,wBAAwB,EACxB,6BAA6B,EAC7B,sCAAsC,EACtC,2BAA2B,EAC3B,UAAU,EACV,eAAe,EACf,qBAAqB,EACrB,sBAAsB,EACtB,uBAAuB,EACvB,mCAAmC,EACnC,kBAAkB,EAClB,8BAA8B,EAC9B,cAAc,EACd,KAAK,eAAe,GACrB,MAAM,eAAe,CAAC;AAGvB,eAAO,MAAM,OAAO,UAAU,CAAC;AAG/B,YAAY,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fatagnus/dink-convex - Dink Convex Sync Component
|
|
3
|
+
*
|
|
4
|
+
* Provides bidirectional sync between Convex and edge devices using CRDT deltas.
|
|
5
|
+
* Minimal boilerplate - each user file is just ~5 lines!
|
|
6
|
+
*
|
|
7
|
+
* ## Quick Start
|
|
8
|
+
*
|
|
9
|
+
* 1. Define your schema with syncedTable:
|
|
10
|
+
* ```typescript
|
|
11
|
+
* // convex/schema.ts
|
|
12
|
+
* import { syncedTable, internalSyncSchema } from "@fatagnus/dink-convex";
|
|
13
|
+
* export default defineSchema({
|
|
14
|
+
* tasks: syncedTable({ title: v.string(), completed: v.boolean() }),
|
|
15
|
+
* ...internalSyncSchema,
|
|
16
|
+
* });
|
|
17
|
+
* ```
|
|
18
|
+
*
|
|
19
|
+
* 2. Create sync mutations (5 lines!):
|
|
20
|
+
* ```typescript
|
|
21
|
+
* // convex/sync.ts
|
|
22
|
+
* import { createSyncMutations } from "@fatagnus/dink-convex";
|
|
23
|
+
* import { mutation, query } from "./_generated/server";
|
|
24
|
+
*
|
|
25
|
+
* export const { applyDeltaFromEdge, getDocumentState, listDocuments, listDocumentsPaginated } =
|
|
26
|
+
* createSyncMutations({ mutation, query });
|
|
27
|
+
* ```
|
|
28
|
+
*
|
|
29
|
+
* 3. Create outbox processor (5 lines!):
|
|
30
|
+
* ```typescript
|
|
31
|
+
* // convex/outboxProcessor.ts
|
|
32
|
+
* import { createOutboxProcessor } from "@fatagnus/dink-convex";
|
|
33
|
+
* import { internalAction, internalMutation, internalQuery } from "./_generated/server";
|
|
34
|
+
* import { internal } from "./_generated/api";
|
|
35
|
+
*
|
|
36
|
+
* export const { processOutboxBatch, queryPendingItems, updateItemStatus, scheduleOutboxProcessing } =
|
|
37
|
+
* createOutboxProcessor({ internalAction, internalMutation, internalQuery, internal });
|
|
38
|
+
* ```
|
|
39
|
+
*
|
|
40
|
+
* 4. Create HTTP router (4 lines!):
|
|
41
|
+
* ```typescript
|
|
42
|
+
* // convex/http.ts
|
|
43
|
+
* import { createSyncHttpRouter } from "@fatagnus/dink-convex";
|
|
44
|
+
* import { httpAction } from "./_generated/server";
|
|
45
|
+
* import { api } from "./_generated/api";
|
|
46
|
+
*
|
|
47
|
+
* export default createSyncHttpRouter({ httpAction, api });
|
|
48
|
+
* ```
|
|
49
|
+
*
|
|
50
|
+
* 5. Create crons (4 lines!):
|
|
51
|
+
* ```typescript
|
|
52
|
+
* // convex/crons.ts
|
|
53
|
+
* import { createSyncCrons } from "@fatagnus/dink-convex";
|
|
54
|
+
* import { internal } from "./_generated/api";
|
|
55
|
+
*
|
|
56
|
+
* export default createSyncCrons({ internal });
|
|
57
|
+
* ```
|
|
58
|
+
*
|
|
59
|
+
* @packageDocumentation
|
|
60
|
+
*/
|
|
61
|
+
// Schema helpers
|
|
62
|
+
export { syncedTable, internalSyncSchema, registerSyncedTableName, getRegisteredSyncedTables, clearRegisteredSyncedTables, } from "./schema.js";
|
|
63
|
+
// CRDT utilities
|
|
64
|
+
export { generateInsertDelta, generateUpdateDelta, generateDeleteDelta, } from "./crdt.js";
|
|
65
|
+
// Factory functions for minimal boilerplate DX (object-based API - recommended)
|
|
66
|
+
export { createSyncMutations, createOutboxProcessor, createSyncHttpRouter, createSyncCrons, } from "./syncFactories.js";
|
|
67
|
+
// Sync mutation wrapper for user mutations (wraps with CRDT triggers)
|
|
68
|
+
export { createSyncMutation } from "./factories.js";
|
|
69
|
+
// Legacy triggers exports (for advanced usage)
|
|
70
|
+
export { syncTriggers, registerSyncedTable, isSyncedTable, getSyncConfig, createDeltaRecord, createOutboxRecord, createSyncTriggerHandler, createSyncTriggerHandlerAsync, createSyncTriggerHandlerWithScheduling, scheduleImmediateProcessing, getNextSeq, getNextSeqAsync, createSequenceCounter, checkSyncConfigEnabled, createSyncConfigChecker, createConfigAwareSyncTriggerHandler, createSyncTriggers, createSyncTriggersWithHandlers, customMutation, } from "./triggers.js";
|
|
71
|
+
// Component version
|
|
72
|
+
export const VERSION = "0.3.0";
|
|
73
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2DG;AAEH,iBAAiB;AACjB,OAAO,EACL,WAAW,EACX,kBAAkB,EAClB,uBAAuB,EACvB,yBAAyB,EACzB,2BAA2B,GAC5B,MAAM,aAAa,CAAC;AAErB,iBAAiB;AACjB,OAAO,EACL,mBAAmB,EACnB,mBAAmB,EACnB,mBAAmB,GAEpB,MAAM,WAAW,CAAC;AAEnB,gFAAgF;AAChF,OAAO,EACL,mBAAmB,EACnB,qBAAqB,EACrB,oBAAoB,EACpB,eAAe,GAOhB,MAAM,oBAAoB,CAAC;AAE5B,sEAAsE;AACtE,OAAO,EAAE,kBAAkB,EAAwB,MAAM,gBAAgB,CAAC;AAE1E,+CAA+C;AAC/C,OAAO,EACL,YAAY,EACZ,mBAAmB,EACnB,aAAa,EACb,aAAa,EACb,iBAAiB,EACjB,kBAAkB,EAClB,wBAAwB,EACxB,6BAA6B,EAC7B,sCAAsC,EACtC,2BAA2B,EAC3B,UAAU,EACV,eAAe,EACf,qBAAqB,EACrB,sBAAsB,EACtB,uBAAuB,EACvB,mCAAmC,EACnC,kBAAkB,EAClB,8BAA8B,EAC9B,cAAc,GAEf,MAAM,eAAe,CAAC;AAEvB,oBAAoB;AACpB,MAAM,CAAC,MAAM,OAAO,GAAG,OAAO,CAAC"}
|