@syncular/server 0.0.1-60

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 (211) hide show
  1. package/dist/blobs/adapters/database.d.ts +83 -0
  2. package/dist/blobs/adapters/database.d.ts.map +1 -0
  3. package/dist/blobs/adapters/database.js +180 -0
  4. package/dist/blobs/adapters/database.js.map +1 -0
  5. package/dist/blobs/adapters/s3.d.ts +82 -0
  6. package/dist/blobs/adapters/s3.d.ts.map +1 -0
  7. package/dist/blobs/adapters/s3.js +170 -0
  8. package/dist/blobs/adapters/s3.js.map +1 -0
  9. package/dist/blobs/index.d.ts +9 -0
  10. package/dist/blobs/index.d.ts.map +1 -0
  11. package/dist/blobs/index.js +9 -0
  12. package/dist/blobs/index.js.map +1 -0
  13. package/dist/blobs/manager.d.ts +195 -0
  14. package/dist/blobs/manager.d.ts.map +1 -0
  15. package/dist/blobs/manager.js +440 -0
  16. package/dist/blobs/manager.js.map +1 -0
  17. package/dist/blobs/migrate.d.ts +27 -0
  18. package/dist/blobs/migrate.d.ts.map +1 -0
  19. package/dist/blobs/migrate.js +119 -0
  20. package/dist/blobs/migrate.js.map +1 -0
  21. package/dist/blobs/types.d.ts +54 -0
  22. package/dist/blobs/types.d.ts.map +1 -0
  23. package/dist/blobs/types.js +5 -0
  24. package/dist/blobs/types.js.map +1 -0
  25. package/dist/clients.d.ts +14 -0
  26. package/dist/clients.d.ts.map +1 -0
  27. package/dist/clients.js +7 -0
  28. package/dist/clients.js.map +1 -0
  29. package/dist/compaction.d.ts +27 -0
  30. package/dist/compaction.d.ts.map +1 -0
  31. package/dist/compaction.js +49 -0
  32. package/dist/compaction.js.map +1 -0
  33. package/dist/dialect/index.d.ts +5 -0
  34. package/dist/dialect/index.d.ts.map +1 -0
  35. package/dist/dialect/index.js +5 -0
  36. package/dist/dialect/index.js.map +1 -0
  37. package/dist/dialect/types.d.ts +170 -0
  38. package/dist/dialect/types.d.ts.map +1 -0
  39. package/dist/dialect/types.js +8 -0
  40. package/dist/dialect/types.js.map +1 -0
  41. package/dist/helpers/conflict.d.ts +52 -0
  42. package/dist/helpers/conflict.d.ts.map +1 -0
  43. package/dist/helpers/conflict.js +49 -0
  44. package/dist/helpers/conflict.js.map +1 -0
  45. package/dist/helpers/emitted-change.d.ts +56 -0
  46. package/dist/helpers/emitted-change.d.ts.map +1 -0
  47. package/dist/helpers/emitted-change.js +46 -0
  48. package/dist/helpers/emitted-change.js.map +1 -0
  49. package/dist/helpers/index.d.ts +10 -0
  50. package/dist/helpers/index.d.ts.map +1 -0
  51. package/dist/helpers/index.js +10 -0
  52. package/dist/helpers/index.js.map +1 -0
  53. package/dist/helpers/paginate.d.ts +49 -0
  54. package/dist/helpers/paginate.d.ts.map +1 -0
  55. package/dist/helpers/paginate.js +54 -0
  56. package/dist/helpers/paginate.js.map +1 -0
  57. package/dist/helpers/scope-strings.d.ts +74 -0
  58. package/dist/helpers/scope-strings.d.ts.map +1 -0
  59. package/dist/helpers/scope-strings.js +82 -0
  60. package/dist/helpers/scope-strings.js.map +1 -0
  61. package/dist/index.d.ts +28 -0
  62. package/dist/index.d.ts.map +1 -0
  63. package/dist/index.js +27 -0
  64. package/dist/index.js.map +1 -0
  65. package/dist/migrate.d.ts +14 -0
  66. package/dist/migrate.d.ts.map +1 -0
  67. package/dist/migrate.js +13 -0
  68. package/dist/migrate.js.map +1 -0
  69. package/dist/proxy/handler.d.ts +42 -0
  70. package/dist/proxy/handler.d.ts.map +1 -0
  71. package/dist/proxy/handler.js +99 -0
  72. package/dist/proxy/handler.js.map +1 -0
  73. package/dist/proxy/index.d.ts +9 -0
  74. package/dist/proxy/index.d.ts.map +1 -0
  75. package/dist/proxy/index.js +14 -0
  76. package/dist/proxy/index.js.map +1 -0
  77. package/dist/proxy/mutation-detector.d.ts +31 -0
  78. package/dist/proxy/mutation-detector.d.ts.map +1 -0
  79. package/dist/proxy/mutation-detector.js +61 -0
  80. package/dist/proxy/mutation-detector.js.map +1 -0
  81. package/dist/proxy/oplog.d.ts +30 -0
  82. package/dist/proxy/oplog.d.ts.map +1 -0
  83. package/dist/proxy/oplog.js +110 -0
  84. package/dist/proxy/oplog.js.map +1 -0
  85. package/dist/proxy/registry.d.ts +35 -0
  86. package/dist/proxy/registry.d.ts.map +1 -0
  87. package/dist/proxy/registry.js +49 -0
  88. package/dist/proxy/registry.js.map +1 -0
  89. package/dist/proxy/types.d.ts +44 -0
  90. package/dist/proxy/types.d.ts.map +1 -0
  91. package/dist/proxy/types.js +7 -0
  92. package/dist/proxy/types.js.map +1 -0
  93. package/dist/prune.d.ts +37 -0
  94. package/dist/prune.d.ts.map +1 -0
  95. package/dist/prune.js +112 -0
  96. package/dist/prune.js.map +1 -0
  97. package/dist/pull.d.ts +31 -0
  98. package/dist/pull.d.ts.map +1 -0
  99. package/dist/pull.js +414 -0
  100. package/dist/pull.js.map +1 -0
  101. package/dist/push.d.ts +33 -0
  102. package/dist/push.d.ts.map +1 -0
  103. package/dist/push.js +329 -0
  104. package/dist/push.js.map +1 -0
  105. package/dist/realtime/in-memory.d.ts +13 -0
  106. package/dist/realtime/in-memory.d.ts.map +1 -0
  107. package/dist/realtime/in-memory.js +28 -0
  108. package/dist/realtime/in-memory.js.map +1 -0
  109. package/dist/realtime/index.d.ts +3 -0
  110. package/dist/realtime/index.d.ts.map +1 -0
  111. package/dist/realtime/index.js +2 -0
  112. package/dist/realtime/index.js.map +1 -0
  113. package/dist/realtime/types.d.ts +50 -0
  114. package/dist/realtime/types.d.ts.map +1 -0
  115. package/dist/realtime/types.js +7 -0
  116. package/dist/realtime/types.js.map +1 -0
  117. package/dist/schema.d.ts +164 -0
  118. package/dist/schema.d.ts.map +1 -0
  119. package/dist/schema.js +10 -0
  120. package/dist/schema.js.map +1 -0
  121. package/dist/shapes/create-handler.d.ts +119 -0
  122. package/dist/shapes/create-handler.d.ts.map +1 -0
  123. package/dist/shapes/create-handler.js +327 -0
  124. package/dist/shapes/create-handler.js.map +1 -0
  125. package/dist/shapes/index.d.ts +4 -0
  126. package/dist/shapes/index.d.ts.map +1 -0
  127. package/dist/shapes/index.js +4 -0
  128. package/dist/shapes/index.js.map +1 -0
  129. package/dist/shapes/registry.d.ts +20 -0
  130. package/dist/shapes/registry.d.ts.map +1 -0
  131. package/dist/shapes/registry.js +88 -0
  132. package/dist/shapes/registry.js.map +1 -0
  133. package/dist/shapes/types.d.ts +204 -0
  134. package/dist/shapes/types.d.ts.map +1 -0
  135. package/dist/shapes/types.js +2 -0
  136. package/dist/shapes/types.js.map +1 -0
  137. package/dist/snapshot-chunks/adapters/s3.d.ts +63 -0
  138. package/dist/snapshot-chunks/adapters/s3.d.ts.map +1 -0
  139. package/dist/snapshot-chunks/adapters/s3.js +50 -0
  140. package/dist/snapshot-chunks/adapters/s3.js.map +1 -0
  141. package/dist/snapshot-chunks/db-metadata.d.ts +33 -0
  142. package/dist/snapshot-chunks/db-metadata.d.ts.map +1 -0
  143. package/dist/snapshot-chunks/db-metadata.js +169 -0
  144. package/dist/snapshot-chunks/db-metadata.js.map +1 -0
  145. package/dist/snapshot-chunks/index.d.ts +9 -0
  146. package/dist/snapshot-chunks/index.d.ts.map +1 -0
  147. package/dist/snapshot-chunks/index.js +9 -0
  148. package/dist/snapshot-chunks/index.js.map +1 -0
  149. package/dist/snapshot-chunks/types.d.ts +65 -0
  150. package/dist/snapshot-chunks/types.d.ts.map +1 -0
  151. package/dist/snapshot-chunks/types.js +8 -0
  152. package/dist/snapshot-chunks/types.js.map +1 -0
  153. package/dist/snapshot-chunks.d.ts +59 -0
  154. package/dist/snapshot-chunks.d.ts.map +1 -0
  155. package/dist/snapshot-chunks.js +202 -0
  156. package/dist/snapshot-chunks.js.map +1 -0
  157. package/dist/stats.d.ts +19 -0
  158. package/dist/stats.d.ts.map +1 -0
  159. package/dist/stats.js +57 -0
  160. package/dist/stats.js.map +1 -0
  161. package/dist/subscriptions/index.d.ts +2 -0
  162. package/dist/subscriptions/index.d.ts.map +1 -0
  163. package/dist/subscriptions/index.js +2 -0
  164. package/dist/subscriptions/index.js.map +1 -0
  165. package/dist/subscriptions/resolve.d.ts +35 -0
  166. package/dist/subscriptions/resolve.d.ts.map +1 -0
  167. package/dist/subscriptions/resolve.js +134 -0
  168. package/dist/subscriptions/resolve.js.map +1 -0
  169. package/package.json +80 -0
  170. package/src/blobs/adapters/database.ts +290 -0
  171. package/src/blobs/adapters/s3.ts +271 -0
  172. package/src/blobs/index.ts +9 -0
  173. package/src/blobs/manager.ts +600 -0
  174. package/src/blobs/migrate.ts +150 -0
  175. package/src/blobs/types.ts +70 -0
  176. package/src/clients.ts +21 -0
  177. package/src/compaction.ts +77 -0
  178. package/src/dialect/index.ts +5 -0
  179. package/src/dialect/types.ts +222 -0
  180. package/src/helpers/conflict.ts +64 -0
  181. package/src/helpers/emitted-change.ts +69 -0
  182. package/src/helpers/index.ts +10 -0
  183. package/src/helpers/paginate.ts +82 -0
  184. package/src/helpers/scope-strings.ts +101 -0
  185. package/src/index.ts +28 -0
  186. package/src/migrate.ts +20 -0
  187. package/src/proxy/handler.ts +152 -0
  188. package/src/proxy/index.ts +18 -0
  189. package/src/proxy/mutation-detector.ts +83 -0
  190. package/src/proxy/oplog.ts +144 -0
  191. package/src/proxy/registry.ts +56 -0
  192. package/src/proxy/types.ts +46 -0
  193. package/src/prune.ts +200 -0
  194. package/src/pull.ts +551 -0
  195. package/src/push.ts +457 -0
  196. package/src/realtime/in-memory.ts +33 -0
  197. package/src/realtime/index.ts +5 -0
  198. package/src/realtime/types.ts +55 -0
  199. package/src/schema.ts +172 -0
  200. package/src/shapes/create-handler.ts +590 -0
  201. package/src/shapes/index.ts +3 -0
  202. package/src/shapes/registry.ts +109 -0
  203. package/src/shapes/types.ts +267 -0
  204. package/src/snapshot-chunks/adapters/s3.ts +68 -0
  205. package/src/snapshot-chunks/db-metadata.ts +238 -0
  206. package/src/snapshot-chunks/index.ts +9 -0
  207. package/src/snapshot-chunks/types.ts +79 -0
  208. package/src/snapshot-chunks.ts +301 -0
  209. package/src/stats.ts +104 -0
  210. package/src/subscriptions/index.ts +1 -0
  211. package/src/subscriptions/resolve.ts +185 -0
@@ -0,0 +1,99 @@
1
+ /**
2
+ * @syncular/server - Proxy Query Handler
3
+ *
4
+ * Executes proxied queries with automatic oplog generation for mutations.
5
+ */
6
+ import { sql } from 'kysely';
7
+ import { appendReturning, detectMutation, hasReturningClause, } from './mutation-detector';
8
+ import { createOplogEntries } from './oplog';
9
+ /**
10
+ * Build a raw SQL query with parameters using Kysely's sql helper.
11
+ *
12
+ * This converts parameterized SQL (using $1, $2, etc.) to Kysely's format.
13
+ */
14
+ function buildRawQuery(sqlQuery, parameters) {
15
+ // If no parameters, just use sql.raw
16
+ if (parameters.length === 0) {
17
+ return sql.raw(sqlQuery);
18
+ }
19
+ // Parse the SQL and split by parameter placeholders ($1, $2, etc.)
20
+ // Then use sql.join to build the query with proper parameter binding
21
+ const parts = [];
22
+ let lastIndex = 0;
23
+ const paramRegex = /\$(\d+)/g;
24
+ let match;
25
+ while ((match = paramRegex.exec(sqlQuery)) !== null) {
26
+ // Add the SQL before this parameter
27
+ if (match.index > lastIndex) {
28
+ parts.push(sql.raw(sqlQuery.slice(lastIndex, match.index)));
29
+ }
30
+ // Add the parameter value (1-indexed in SQL, 0-indexed in array)
31
+ const paramIndex = Number.parseInt(match[1], 10) - 1;
32
+ if (paramIndex >= 0 && paramIndex < parameters.length) {
33
+ // Use sql.value to create a proper parameter binding
34
+ parts.push(sql.val(parameters[paramIndex]));
35
+ }
36
+ else {
37
+ // Keep the original placeholder if out of bounds (shouldn't happen)
38
+ parts.push(sql.raw(match[0]));
39
+ }
40
+ lastIndex = match.index + match[0].length;
41
+ }
42
+ // Add remaining SQL after last parameter
43
+ if (lastIndex < sqlQuery.length) {
44
+ parts.push(sql.raw(sqlQuery.slice(lastIndex)));
45
+ }
46
+ // Join all parts together
47
+ return sql.join(parts, sql.raw(''));
48
+ }
49
+ /**
50
+ * Execute a proxied query with automatic oplog generation for mutations.
51
+ *
52
+ * - Read queries: Execute directly and return rows
53
+ * - Mutations: Append RETURNING *, execute, create oplog entries
54
+ */
55
+ export async function executeProxyQuery(args) {
56
+ const { db, dialect, shapes, ctx, sqlQuery, parameters } = args;
57
+ const mutation = detectMutation(sqlQuery);
58
+ if (!mutation) {
59
+ // Read query - execute directly
60
+ const result = await buildRawQuery(sqlQuery, parameters).execute(db);
61
+ return { rows: result.rows };
62
+ }
63
+ // Check if this table has a registered shape
64
+ const shape = shapes.get(mutation.tableName);
65
+ if (!shape) {
66
+ // No shape registered - execute without oplog
67
+ // This allows proxy operations on non-synced tables
68
+ const result = await buildRawQuery(sqlQuery, parameters).execute(db);
69
+ return {
70
+ rows: result.rows,
71
+ rowCount: Number(result.numAffectedRows ?? 0),
72
+ };
73
+ }
74
+ // Mutation with registered shape - append RETURNING * and create oplog
75
+ const needsReturning = !hasReturningClause(sqlQuery);
76
+ const finalSql = needsReturning ? appendReturning(sqlQuery) : sqlQuery;
77
+ const result = await buildRawQuery(finalSql, parameters).execute(db);
78
+ const affectedRows = result.rows;
79
+ if (affectedRows.length === 0) {
80
+ return { rowCount: 0 };
81
+ }
82
+ // Create oplog entries
83
+ const { commitSeq, affectedTables } = await createOplogEntries({
84
+ trx: db,
85
+ dialect,
86
+ actorId: ctx.actorId,
87
+ clientId: ctx.clientId,
88
+ partitionId: ctx.partitionId,
89
+ shape,
90
+ operation: mutation.operation,
91
+ rows: affectedRows,
92
+ });
93
+ return {
94
+ rowCount: affectedRows.length,
95
+ commitSeq,
96
+ affectedTables,
97
+ };
98
+ }
99
+ //# sourceMappingURL=handler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"handler.js","sourceRoot":"","sources":["../../src/proxy/handler.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * @syncular/server - Proxy Exports
3
+ *
4
+ * Server-side proxy functionality for database access.
5
+ */
6
+ export { type ExecuteProxyQueryArgs, type ExecuteProxyQueryResult, executeProxyQuery, } from './handler';
7
+ export { type DetectedMutation, detectMutation } from './mutation-detector';
8
+ export { ProxyTableRegistry } from './registry';
9
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/proxy/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EACL,KAAK,qBAAqB,EAC1B,KAAK,uBAAuB,EAC5B,iBAAiB,GAClB,MAAM,WAAW,CAAC;AAEnB,OAAO,EAAE,KAAK,gBAAgB,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAG5E,OAAO,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * @syncular/server - Proxy Exports
3
+ *
4
+ * Server-side proxy functionality for database access.
5
+ */
6
+ // Query execution
7
+ export { executeProxyQuery, } from './handler';
8
+ // Mutation detection
9
+ export { detectMutation } from './mutation-detector';
10
+ // Oplog creation
11
+ // Registry
12
+ export { ProxyTableRegistry } from './registry';
13
+ // Types
14
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/proxy/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,kBAAkB;AAClB,OAAO,EAGL,iBAAiB,GAClB,MAAM,WAAW,CAAC;AACnB,qBAAqB;AACrB,OAAO,EAAyB,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAC5E,iBAAiB;AACjB,WAAW;AACX,OAAO,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAChD,QAAQ"}
@@ -0,0 +1,31 @@
1
+ /**
2
+ * @syncular/server - Mutation Detector
3
+ *
4
+ * Detects whether a SQL query is a mutation (INSERT/UPDATE/DELETE).
5
+ */
6
+ import type { SyncOp } from '@syncular/core';
7
+ export interface DetectedMutation {
8
+ /** Operation type */
9
+ operation: SyncOp;
10
+ /** Table name being modified */
11
+ tableName: string;
12
+ }
13
+ /**
14
+ * Detect if a SQL query is a mutation and extract table info.
15
+ *
16
+ * @param sql - The SQL query string
17
+ * @returns Mutation info if detected, null for read queries
18
+ */
19
+ export declare function detectMutation(sql: string): DetectedMutation | null;
20
+ /**
21
+ * Check if SQL already has a RETURNING clause.
22
+ */
23
+ export declare function hasReturningClause(sql: string): boolean;
24
+ /**
25
+ * Append RETURNING * to a mutation query if not already present.
26
+ *
27
+ * @param sql - The SQL query string
28
+ * @returns Modified SQL with RETURNING *
29
+ */
30
+ export declare function appendReturning(sql: string): string;
31
+ //# sourceMappingURL=mutation-detector.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mutation-detector.d.ts","sourceRoot":"","sources":["../../src/proxy/mutation-detector.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAC;AAE7C,MAAM,WAAW,gBAAgB;IAC/B,qBAAqB;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,gCAAgC;IAChC,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,gBAAgB,GAAG,IAAI,CAqCnE;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAGvD;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAQnD"}
@@ -0,0 +1,61 @@
1
+ /**
2
+ * @syncular/server - Mutation Detector
3
+ *
4
+ * Detects whether a SQL query is a mutation (INSERT/UPDATE/DELETE).
5
+ */
6
+ /**
7
+ * Detect if a SQL query is a mutation and extract table info.
8
+ *
9
+ * @param sql - The SQL query string
10
+ * @returns Mutation info if detected, null for read queries
11
+ */
12
+ export function detectMutation(sql) {
13
+ const trimmed = sql.trim();
14
+ // INSERT INTO [schema.]table
15
+ const insertMatch = trimmed.match(/^\s*INSERT\s+INTO\s+(?:["']?(\w+)["']?\.)?["']?(\w+)["']?/i);
16
+ if (insertMatch) {
17
+ return {
18
+ operation: 'upsert',
19
+ tableName: insertMatch[2],
20
+ };
21
+ }
22
+ // UPDATE [schema.]table
23
+ const updateMatch = trimmed.match(/^\s*UPDATE\s+(?:["']?(\w+)["']?\.)?["']?(\w+)["']?/i);
24
+ if (updateMatch) {
25
+ return {
26
+ operation: 'upsert',
27
+ tableName: updateMatch[2],
28
+ };
29
+ }
30
+ // DELETE FROM [schema.]table
31
+ const deleteMatch = trimmed.match(/^\s*DELETE\s+FROM\s+(?:["']?(\w+)["']?\.)?["']?(\w+)["']?/i);
32
+ if (deleteMatch) {
33
+ return {
34
+ operation: 'delete',
35
+ tableName: deleteMatch[2],
36
+ };
37
+ }
38
+ return null;
39
+ }
40
+ /**
41
+ * Check if SQL already has a RETURNING clause.
42
+ */
43
+ export function hasReturningClause(sql) {
44
+ // Simple check - look for RETURNING keyword not in a string
45
+ return /\bRETURNING\b/i.test(sql);
46
+ }
47
+ /**
48
+ * Append RETURNING * to a mutation query if not already present.
49
+ *
50
+ * @param sql - The SQL query string
51
+ * @returns Modified SQL with RETURNING *
52
+ */
53
+ export function appendReturning(sql) {
54
+ if (hasReturningClause(sql)) {
55
+ return sql;
56
+ }
57
+ // Remove trailing semicolon if present
58
+ const trimmed = sql.trim().replace(/;\s*$/, '');
59
+ return `${trimmed} RETURNING *`;
60
+ }
61
+ //# sourceMappingURL=mutation-detector.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mutation-detector.js","sourceRoot":"","sources":["../../src/proxy/mutation-detector.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAWH;;;;;GAKG;AACH,MAAM,UAAU,cAAc,CAAC,GAAW,EAA2B;IACnE,MAAM,OAAO,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC;IAE3B,6BAA6B;IAC7B,MAAM,WAAW,GAAG,OAAO,CAAC,KAAK,CAC/B,4DAA4D,CAC7D,CAAC;IACF,IAAI,WAAW,EAAE,CAAC;QAChB,OAAO;YACL,SAAS,EAAE,QAAQ;YACnB,SAAS,EAAE,WAAW,CAAC,CAAC,CAAE;SAC3B,CAAC;IACJ,CAAC;IAED,wBAAwB;IACxB,MAAM,WAAW,GAAG,OAAO,CAAC,KAAK,CAC/B,qDAAqD,CACtD,CAAC;IACF,IAAI,WAAW,EAAE,CAAC;QAChB,OAAO;YACL,SAAS,EAAE,QAAQ;YACnB,SAAS,EAAE,WAAW,CAAC,CAAC,CAAE;SAC3B,CAAC;IACJ,CAAC;IAED,6BAA6B;IAC7B,MAAM,WAAW,GAAG,OAAO,CAAC,KAAK,CAC/B,4DAA4D,CAC7D,CAAC;IACF,IAAI,WAAW,EAAE,CAAC;QAChB,OAAO;YACL,SAAS,EAAE,QAAQ;YACnB,SAAS,EAAE,WAAW,CAAC,CAAC,CAAE;SAC3B,CAAC;IACJ,CAAC;IAED,OAAO,IAAI,CAAC;AAAA,CACb;AAED;;GAEG;AACH,MAAM,UAAU,kBAAkB,CAAC,GAAW,EAAW;IACvD,4DAA4D;IAC5D,OAAO,gBAAgB,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAAA,CACnC;AAED;;;;;GAKG;AACH,MAAM,UAAU,eAAe,CAAC,GAAW,EAAU;IACnD,IAAI,kBAAkB,CAAC,GAAG,CAAC,EAAE,CAAC;QAC5B,OAAO,GAAG,CAAC;IACb,CAAC;IAED,uCAAuC;IACvC,MAAM,OAAO,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;IAChD,OAAO,GAAG,OAAO,cAAc,CAAC;AAAA,CACjC"}
@@ -0,0 +1,30 @@
1
+ /**
2
+ * @syncular/server - Oplog Creation
3
+ *
4
+ * Creates sync oplog entries for proxy mutations.
5
+ */
6
+ import type { SyncOp } from '@syncular/core';
7
+ import { type Kysely } from 'kysely';
8
+ import type { ServerSyncDialect } from '../dialect/types';
9
+ import type { SyncCoreDb } from '../schema';
10
+ import type { ProxyTableHandler } from './types';
11
+ /**
12
+ * Create oplog entries for affected rows.
13
+ *
14
+ * This is called after a mutation to record the changes in the sync oplog,
15
+ * making them visible to sync clients.
16
+ */
17
+ export declare function createOplogEntries<DB extends SyncCoreDb>(args: {
18
+ trx: Kysely<DB>;
19
+ dialect: ServerSyncDialect;
20
+ actorId: string;
21
+ clientId: string;
22
+ partitionId?: string;
23
+ shape: ProxyTableHandler;
24
+ operation: SyncOp;
25
+ rows: Record<string, unknown>[];
26
+ }): Promise<{
27
+ commitSeq: number;
28
+ affectedTables: string[];
29
+ }>;
30
+ //# sourceMappingURL=oplog.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"oplog.d.ts","sourceRoot":"","sources":["../../src/proxy/oplog.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAC;AAC7C,OAAO,EAAE,KAAK,MAAM,EAAO,MAAM,QAAQ,CAAC;AAC1C,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAC1D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAC5C,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AASjD;;;;;GAKG;AACH,wBAAsB,kBAAkB,CAAC,EAAE,SAAS,UAAU,EAAE,IAAI,EAAE;IACpE,GAAG,EAAE,MAAM,CAAC,EAAE,CAAC,CAAC;IAChB,OAAO,EAAE,iBAAiB,CAAC;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,iBAAiB,CAAC;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC;CACjC,GAAG,OAAO,CAAC;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,cAAc,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC,CA4G3D"}
@@ -0,0 +1,110 @@
1
+ /**
2
+ * @syncular/server - Oplog Creation
3
+ *
4
+ * Creates sync oplog entries for proxy mutations.
5
+ */
6
+ import { randomUUID } from 'node:crypto';
7
+ import { sql } from 'kysely';
8
+ /**
9
+ * Generate a random ID for commit tracking.
10
+ */
11
+ function generateId() {
12
+ return randomUUID();
13
+ }
14
+ /**
15
+ * Create oplog entries for affected rows.
16
+ *
17
+ * This is called after a mutation to record the changes in the sync oplog,
18
+ * making them visible to sync clients.
19
+ */
20
+ export async function createOplogEntries(args) {
21
+ const { trx, dialect, actorId, clientId, shape, operation, rows } = args;
22
+ const partitionId = args.partitionId ?? 'default';
23
+ if (rows.length === 0) {
24
+ return { commitSeq: 0, affectedTables: [] };
25
+ }
26
+ const pk = shape.primaryKey ?? 'id';
27
+ const versionCol = shape.versionColumn ?? 'server_version';
28
+ // Create commit record
29
+ const commitResult = await sql `
30
+ insert into ${sql.table('sync_commits')} (
31
+ partition_id,
32
+ actor_id,
33
+ client_id,
34
+ client_commit_id,
35
+ meta,
36
+ result_json
37
+ )
38
+ values (
39
+ ${partitionId},
40
+ ${actorId},
41
+ ${clientId},
42
+ ${`proxy:${generateId()}`},
43
+ ${null},
44
+ ${null}
45
+ )
46
+ returning commit_seq
47
+ `.execute(trx);
48
+ const commitRow = commitResult.rows[0];
49
+ if (!commitRow) {
50
+ throw new Error('Failed to insert sync_commits row');
51
+ }
52
+ const commitSeq = Number(commitRow.commit_seq);
53
+ // Compute scopes for all rows and collect changes
54
+ const affectedTablesSet = new Set();
55
+ affectedTablesSet.add(shape.table);
56
+ const changes = rows.map((row) => {
57
+ const scopes = shape.computeScopes(row);
58
+ return {
59
+ commit_seq: commitSeq,
60
+ partition_id: partitionId,
61
+ table: shape.table,
62
+ row_id: String(row[pk]),
63
+ op: operation,
64
+ row_json: operation === 'delete' ? null : row,
65
+ row_version: row[versionCol] != null ? Number(row[versionCol]) : null,
66
+ scopes: dialect.scopesToDb(scopes),
67
+ };
68
+ });
69
+ // Insert changes
70
+ await sql `
71
+ insert into ${sql.table('sync_changes')} (
72
+ commit_seq,
73
+ partition_id,
74
+ "table",
75
+ row_id,
76
+ op,
77
+ row_json,
78
+ row_version,
79
+ scopes
80
+ )
81
+ values ${sql.join(changes.map((c) => sql `(
82
+ ${c.commit_seq},
83
+ ${c.partition_id},
84
+ ${c.table},
85
+ ${c.row_id},
86
+ ${c.op},
87
+ ${c.row_json},
88
+ ${c.row_version},
89
+ ${c.scopes}
90
+ )`), sql `, `)}
91
+ `.execute(trx);
92
+ // Update commit with affected tables
93
+ const affectedTables = Array.from(affectedTablesSet);
94
+ const sortedAffectedTables = affectedTables.sort();
95
+ await sql `
96
+ update ${sql.table('sync_commits')}
97
+ set change_count = ${rows.length}, affected_tables = ${sortedAffectedTables}
98
+ where commit_seq = ${commitSeq}
99
+ `.execute(trx);
100
+ // Insert table commits for subscription filtering
101
+ if (affectedTables.length > 0) {
102
+ await sql `
103
+ insert into ${sql.table('sync_table_commits')} (partition_id, "table", commit_seq)
104
+ values ${sql.join(sortedAffectedTables.map((table) => sql `(${partitionId}, ${table}, ${commitSeq})`), sql `, `)}
105
+ on conflict (partition_id, "table", commit_seq) do nothing
106
+ `.execute(trx);
107
+ }
108
+ return { commitSeq, affectedTables };
109
+ }
110
+ //# sourceMappingURL=oplog.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"oplog.js","sourceRoot":"","sources":["../../src/proxy/oplog.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,35 @@
1
+ /**
2
+ * @syncular/server - Proxy Table Registry
3
+ *
4
+ * Registry for proxy table handlers.
5
+ */
6
+ import type { ProxyTableHandler } from './types';
7
+ /**
8
+ * Registry for proxy table handlers.
9
+ *
10
+ * Maps table names to table handlers for oplog generation.
11
+ */
12
+ export declare class ProxyTableRegistry {
13
+ private handlers;
14
+ /**
15
+ * Register a proxy table handler.
16
+ */
17
+ register(handler: ProxyTableHandler): this;
18
+ /**
19
+ * Get handler by table name.
20
+ */
21
+ get(tableName: string): ProxyTableHandler | undefined;
22
+ /**
23
+ * Get handler by table name or throw.
24
+ */
25
+ getOrThrow(tableName: string): ProxyTableHandler;
26
+ /**
27
+ * Check if a table has a registered handler.
28
+ */
29
+ has(tableName: string): boolean;
30
+ /**
31
+ * Get all registered handlers.
32
+ */
33
+ getAll(): ProxyTableHandler[];
34
+ }
35
+ //# sourceMappingURL=registry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/proxy/registry.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AAEjD;;;;GAIG;AACH,qBAAa,kBAAkB;IAC7B,OAAO,CAAC,QAAQ,CAAwC;IAExD;;OAEG;IACH,QAAQ,CAAC,OAAO,EAAE,iBAAiB,GAAG,IAAI,CAGzC;IAED;;OAEG;IACH,GAAG,CAAC,SAAS,EAAE,MAAM,GAAG,iBAAiB,GAAG,SAAS,CAEpD;IAED;;OAEG;IACH,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,iBAAiB,CAM/C;IAED;;OAEG;IACH,GAAG,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAE9B;IAED;;OAEG;IACH,MAAM,IAAI,iBAAiB,EAAE,CAE5B;CACF"}
@@ -0,0 +1,49 @@
1
+ /**
2
+ * @syncular/server - Proxy Table Registry
3
+ *
4
+ * Registry for proxy table handlers.
5
+ */
6
+ /**
7
+ * Registry for proxy table handlers.
8
+ *
9
+ * Maps table names to table handlers for oplog generation.
10
+ */
11
+ export class ProxyTableRegistry {
12
+ handlers = new Map();
13
+ /**
14
+ * Register a proxy table handler.
15
+ */
16
+ register(handler) {
17
+ this.handlers.set(handler.table, handler);
18
+ return this;
19
+ }
20
+ /**
21
+ * Get handler by table name.
22
+ */
23
+ get(tableName) {
24
+ return this.handlers.get(tableName);
25
+ }
26
+ /**
27
+ * Get handler by table name or throw.
28
+ */
29
+ getOrThrow(tableName) {
30
+ const handler = this.handlers.get(tableName);
31
+ if (!handler) {
32
+ throw new Error(`No proxy table registered for table: ${tableName}`);
33
+ }
34
+ return handler;
35
+ }
36
+ /**
37
+ * Check if a table has a registered handler.
38
+ */
39
+ has(tableName) {
40
+ return this.handlers.has(tableName);
41
+ }
42
+ /**
43
+ * Get all registered handlers.
44
+ */
45
+ getAll() {
46
+ return Array.from(this.handlers.values());
47
+ }
48
+ }
49
+ //# sourceMappingURL=registry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/proxy/registry.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH;;;;GAIG;AACH,MAAM,OAAO,kBAAkB;IACrB,QAAQ,GAAG,IAAI,GAAG,EAA6B,CAAC;IAExD;;OAEG;IACH,QAAQ,CAAC,OAA0B,EAAQ;QACzC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;QAC1C,OAAO,IAAI,CAAC;IAAA,CACb;IAED;;OAEG;IACH,GAAG,CAAC,SAAiB,EAAiC;QACpD,OAAO,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;IAAA,CACrC;IAED;;OAEG;IACH,UAAU,CAAC,SAAiB,EAAqB;QAC/C,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QAC7C,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,MAAM,IAAI,KAAK,CAAC,wCAAwC,SAAS,EAAE,CAAC,CAAC;QACvE,CAAC;QACD,OAAO,OAAO,CAAC;IAAA,CAChB;IAED;;OAEG;IACH,GAAG,CAAC,SAAiB,EAAW;QAC9B,OAAO,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;IAAA,CACrC;IAED;;OAEG;IACH,MAAM,GAAwB;QAC5B,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC;IAAA,CAC3C;CACF"}
@@ -0,0 +1,44 @@
1
+ /**
2
+ * @syncular/server - Proxy Types
3
+ *
4
+ * Types for database proxy with automatic oplog generation.
5
+ */
6
+ import type { StoredScopes } from '@syncular/core';
7
+ /**
8
+ * Proxy table handler for mutations.
9
+ *
10
+ * Defines how to compute scopes for rows affected by proxy operations.
11
+ */
12
+ export interface ProxyTableHandler {
13
+ /** Database table name */
14
+ table: string;
15
+ /** Primary key column name (default: 'id') */
16
+ primaryKey?: string;
17
+ /** Version column name (default: 'server_version') */
18
+ versionColumn?: string;
19
+ /**
20
+ * Compute scope values for a row.
21
+ *
22
+ * This determines which sync subscriptions will see changes to this row.
23
+ * Returns a JSONB-compatible object of scope key-value pairs.
24
+ *
25
+ * @example
26
+ * computeScopes: (row) => ({
27
+ * user_id: String(row.user_id),
28
+ * project_id: String(row.project_id),
29
+ * })
30
+ */
31
+ computeScopes(row: Record<string, unknown>): StoredScopes;
32
+ }
33
+ /**
34
+ * Context for executing a proxied query.
35
+ */
36
+ export interface ProxyQueryContext {
37
+ /** Actor ID for oplog tracking */
38
+ actorId: string;
39
+ /** Client ID for oplog tracking */
40
+ clientId: string;
41
+ /** Logical partition key (default: 'default') */
42
+ partitionId?: string;
43
+ }
44
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/proxy/types.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAEnD;;;;GAIG;AACH,MAAM,WAAW,iBAAiB;IAChC,0BAA0B;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,8CAA8C;IAC9C,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,sDAAsD;IACtD,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;;;;;;;;;;;OAWG;IACH,aAAa,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,YAAY,CAAC;CAC3D;AAED;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,kCAAkC;IAClC,OAAO,EAAE,MAAM,CAAC;IAChB,mCAAmC;IACnC,QAAQ,EAAE,MAAM,CAAC;IACjB,iDAAiD;IACjD,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * @syncular/server - Proxy Types
3
+ *
4
+ * Types for database proxy with automatic oplog generation.
5
+ */
6
+ export {};
7
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/proxy/types.ts"],"names":[],"mappings":"AAAA;;;;GAIG"}
@@ -0,0 +1,37 @@
1
+ /**
2
+ * @syncular/server - Pruning utilities
3
+ *
4
+ * Pruning strategy (initial):
5
+ * - Track per-client cursors in `sync_client_cursors`
6
+ * - Consider a client "active" if it has pulled within `activeWindowMs`
7
+ * - Compute watermark = min(cursor) across active clients (ignoring cursor < 0)
8
+ * - Delete commits with commit_seq <= watermark (cascade deletes changes)
9
+ *
10
+ * Clients behind pruned history will be forced to bootstrap.
11
+ */
12
+ import type { Kysely } from 'kysely';
13
+ import type { SyncCoreDb } from './schema';
14
+ export interface PruneOptions {
15
+ /** Clients with updated_at older than this are ignored for watermark. Default: 14 days. */
16
+ activeWindowMs?: number;
17
+ /**
18
+ * Time-based retention safety cap.
19
+ *
20
+ * The server prunes commits older than this age even if watermark pruning
21
+ * is stuck (e.g. a client never advances).
22
+ * Default: 30 days.
23
+ */
24
+ fallbackMaxAgeMs?: number;
25
+ /** Soft cap: keep at least this many newest commits even if watermark is high. Default: 1000. */
26
+ keepNewestCommits?: number;
27
+ }
28
+ export declare function computePruneWatermarkCommitSeq<DB extends SyncCoreDb>(db: Kysely<DB>, options?: PruneOptions): Promise<number>;
29
+ export declare function pruneSync<DB extends SyncCoreDb>(db: Kysely<DB>, args: {
30
+ watermarkCommitSeq: number;
31
+ keepNewestCommits?: number;
32
+ }): Promise<number>;
33
+ export declare function maybePruneSync<DB extends SyncCoreDb>(db: Kysely<DB>, args: {
34
+ minIntervalMs: number;
35
+ options?: PruneOptions;
36
+ }): Promise<number>;
37
+ //# sourceMappingURL=prune.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prune.d.ts","sourceRoot":"","sources":["../src/prune.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAGV,MAAM,EAGP,MAAM,QAAQ,CAAC;AAEhB,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAgB3C,MAAM,WAAW,YAAY;IAC3B,2FAA2F;IAC3F,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB;;;;;;OAMG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,iGAAiG;IACjG,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED,wBAAsB,8BAA8B,CAAC,EAAE,SAAS,UAAU,EACxE,EAAE,EAAE,MAAM,CAAC,EAAE,CAAC,EACd,OAAO,GAAE,YAAiB,GACzB,OAAO,CAAC,MAAM,CAAC,CAoCjB;AAED,wBAAsB,SAAS,CAAC,EAAE,SAAS,UAAU,EACnD,EAAE,EAAE,MAAM,CAAC,EAAE,CAAC,EACd,IAAI,EAAE;IAAE,kBAAkB,EAAE,MAAM,CAAC;IAAC,iBAAiB,CAAC,EAAE,MAAM,CAAA;CAAE,GAC/D,OAAO,CAAC,MAAM,CAAC,CA0DjB;AAqBD,wBAAsB,cAAc,CAAC,EAAE,SAAS,UAAU,EACxD,EAAE,EAAE,MAAM,CAAC,EAAE,CAAC,EACd,IAAI,EAAE;IAAE,aAAa,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,YAAY,CAAA;CAAE,GACtD,OAAO,CAAC,MAAM,CAAC,CAsBjB"}