@syncular/server 0.0.6-96 → 0.1.1

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 (597) hide show
  1. package/README.md +1 -2
  2. package/dist/auth-leases.d.ts +85 -0
  3. package/dist/auth-leases.d.ts.map +1 -0
  4. package/dist/auth-leases.js +368 -0
  5. package/dist/auth-leases.js.map +1 -0
  6. package/dist/better-sqlite3.d.ts +22 -0
  7. package/dist/better-sqlite3.d.ts.map +1 -0
  8. package/dist/better-sqlite3.js +16 -0
  9. package/dist/better-sqlite3.js.map +1 -0
  10. package/dist/blobs/access.d.ts +35 -0
  11. package/dist/blobs/access.d.ts.map +1 -0
  12. package/dist/blobs/access.js +149 -0
  13. package/dist/blobs/access.js.map +1 -0
  14. package/dist/blobs/adapters/database.d.ts +26 -9
  15. package/dist/blobs/adapters/database.d.ts.map +1 -1
  16. package/dist/blobs/adapters/database.js +68 -23
  17. package/dist/blobs/adapters/database.js.map +1 -1
  18. package/dist/blobs/index.d.ts +1 -0
  19. package/dist/blobs/index.d.ts.map +1 -1
  20. package/dist/blobs/index.js +1 -0
  21. package/dist/blobs/index.js.map +1 -1
  22. package/dist/blobs/manager.d.ts +69 -44
  23. package/dist/blobs/manager.d.ts.map +1 -1
  24. package/dist/blobs/manager.js +250 -65
  25. package/dist/blobs/manager.js.map +1 -1
  26. package/dist/blobs/migrate.d.ts.map +1 -1
  27. package/dist/blobs/migrate.js +16 -8
  28. package/dist/blobs/migrate.js.map +1 -1
  29. package/dist/blobs/types.d.ts +4 -0
  30. package/dist/blobs/types.d.ts.map +1 -1
  31. package/dist/bun-sqlite.d.ts +19 -0
  32. package/dist/bun-sqlite.d.ts.map +1 -0
  33. package/dist/bun-sqlite.js +19 -0
  34. package/dist/bun-sqlite.js.map +1 -0
  35. package/dist/clients.d.ts +1 -0
  36. package/dist/clients.d.ts.map +1 -1
  37. package/dist/clients.js.map +1 -1
  38. package/dist/cloudflare/durable-object.d.ts +93 -0
  39. package/dist/cloudflare/durable-object.d.ts.map +1 -0
  40. package/dist/cloudflare/durable-object.js +210 -0
  41. package/dist/cloudflare/durable-object.js.map +1 -0
  42. package/dist/cloudflare/index.d.ts +22 -0
  43. package/dist/cloudflare/index.d.ts.map +1 -0
  44. package/dist/cloudflare/index.js +22 -0
  45. package/dist/cloudflare/index.js.map +1 -0
  46. package/dist/cloudflare/r2.d.ts +180 -0
  47. package/dist/cloudflare/r2.d.ts.map +1 -0
  48. package/dist/cloudflare/r2.js +258 -0
  49. package/dist/cloudflare/r2.js.map +1 -0
  50. package/dist/cloudflare/scope-cache.d.ts +54 -0
  51. package/dist/cloudflare/scope-cache.d.ts.map +1 -0
  52. package/dist/cloudflare/scope-cache.js +223 -0
  53. package/dist/cloudflare/scope-cache.js.map +1 -0
  54. package/dist/cloudflare/sentry.d.ts +47 -0
  55. package/dist/cloudflare/sentry.d.ts.map +1 -0
  56. package/dist/cloudflare/sentry.js +163 -0
  57. package/dist/cloudflare/sentry.js.map +1 -0
  58. package/dist/cloudflare/worker.d.ts +46 -0
  59. package/dist/cloudflare/worker.d.ts.map +1 -0
  60. package/dist/cloudflare/worker.js +63 -0
  61. package/dist/cloudflare/worker.js.map +1 -0
  62. package/dist/commit-integrity.d.ts +38 -0
  63. package/dist/commit-integrity.d.ts.map +1 -0
  64. package/dist/commit-integrity.js +260 -0
  65. package/dist/commit-integrity.js.map +1 -0
  66. package/dist/compaction.js.map +1 -1
  67. package/dist/crdt-yjs/index.d.ts +99 -0
  68. package/dist/crdt-yjs/index.d.ts.map +1 -0
  69. package/dist/crdt-yjs/index.js +629 -0
  70. package/dist/crdt-yjs/index.js.map +1 -0
  71. package/dist/d1.d.ts +13 -0
  72. package/dist/d1.d.ts.map +1 -0
  73. package/dist/d1.js +14 -0
  74. package/dist/d1.js.map +1 -0
  75. package/dist/dialect/base.d.ts +11 -1
  76. package/dist/dialect/base.d.ts.map +1 -1
  77. package/dist/dialect/base.js +42 -5
  78. package/dist/dialect/base.js.map +1 -1
  79. package/dist/dialect/helpers.d.ts +6 -0
  80. package/dist/dialect/helpers.d.ts.map +1 -1
  81. package/dist/dialect/helpers.js +24 -0
  82. package/dist/dialect/helpers.js.map +1 -1
  83. package/dist/dialect/types.d.ts +40 -0
  84. package/dist/dialect/types.d.ts.map +1 -1
  85. package/dist/encrypted-crdt.d.ts +67 -0
  86. package/dist/encrypted-crdt.d.ts.map +1 -0
  87. package/dist/encrypted-crdt.js +426 -0
  88. package/dist/encrypted-crdt.js.map +1 -0
  89. package/dist/errors.d.ts +10 -0
  90. package/dist/errors.d.ts.map +1 -0
  91. package/dist/errors.js +13 -0
  92. package/dist/errors.js.map +1 -0
  93. package/dist/filesystem/index.d.ts +44 -0
  94. package/dist/filesystem/index.d.ts.map +1 -0
  95. package/dist/filesystem/index.js +164 -0
  96. package/dist/filesystem/index.js.map +1 -0
  97. package/dist/handlers/collection.d.ts +11 -3
  98. package/dist/handlers/collection.d.ts.map +1 -1
  99. package/dist/handlers/collection.js +34 -56
  100. package/dist/handlers/collection.js.map +1 -1
  101. package/dist/handlers/create-handler.d.ts +31 -7
  102. package/dist/handlers/create-handler.d.ts.map +1 -1
  103. package/dist/handlers/create-handler.js +332 -115
  104. package/dist/handlers/create-handler.js.map +1 -1
  105. package/dist/handlers/types.d.ts +86 -1
  106. package/dist/handlers/types.d.ts.map +1 -1
  107. package/dist/helpers/conflict.js.map +1 -1
  108. package/dist/helpers/emitted-change.js.map +1 -1
  109. package/dist/helpers/index.d.ts +2 -0
  110. package/dist/helpers/index.d.ts.map +1 -1
  111. package/dist/helpers/index.js +2 -0
  112. package/dist/helpers/index.js.map +1 -1
  113. package/dist/helpers/paginate.js.map +1 -1
  114. package/dist/helpers/scope-authorization.d.ts +7 -0
  115. package/dist/helpers/scope-authorization.d.ts.map +1 -0
  116. package/dist/helpers/scope-authorization.js +19 -0
  117. package/dist/helpers/scope-authorization.js.map +1 -0
  118. package/dist/helpers/scope-commit-index.d.ts +12 -0
  119. package/dist/helpers/scope-commit-index.d.ts.map +1 -0
  120. package/dist/helpers/scope-commit-index.js +35 -0
  121. package/dist/helpers/scope-commit-index.js.map +1 -0
  122. package/dist/helpers/scope-strings.js.map +1 -1
  123. package/dist/hono/api-key-auth.d.ts +49 -0
  124. package/dist/hono/api-key-auth.d.ts.map +1 -0
  125. package/dist/hono/api-key-auth.js +108 -0
  126. package/dist/hono/api-key-auth.js.map +1 -0
  127. package/dist/hono/audit-redaction.d.ts +20 -0
  128. package/dist/hono/audit-redaction.d.ts.map +1 -0
  129. package/dist/hono/audit-redaction.js +85 -0
  130. package/dist/hono/audit-redaction.js.map +1 -0
  131. package/dist/hono/blobs.d.ts +75 -0
  132. package/dist/hono/blobs.d.ts.map +1 -0
  133. package/dist/hono/blobs.js +586 -0
  134. package/dist/hono/blobs.js.map +1 -0
  135. package/dist/hono/console/gateway.d.ts +42 -0
  136. package/dist/hono/console/gateway.d.ts.map +1 -0
  137. package/dist/hono/console/gateway.js +2158 -0
  138. package/dist/hono/console/gateway.js.map +1 -0
  139. package/dist/hono/console/live-auth.d.ts +7 -0
  140. package/dist/hono/console/live-auth.d.ts.map +1 -0
  141. package/dist/hono/console/live-auth.js +39 -0
  142. package/dist/hono/console/live-auth.js.map +1 -0
  143. package/dist/hono/console/route-descriptor.d.ts +6 -0
  144. package/dist/hono/console/route-descriptor.d.ts.map +1 -0
  145. package/dist/hono/console/route-descriptor.js +16 -0
  146. package/dist/hono/console/route-descriptor.js.map +1 -0
  147. package/dist/hono/console/routes/api-keys.d.ts +8 -0
  148. package/dist/hono/console/routes/api-keys.d.ts.map +1 -0
  149. package/dist/hono/console/routes/api-keys.js +575 -0
  150. package/dist/hono/console/routes/api-keys.js.map +1 -0
  151. package/dist/hono/console/routes/clients.d.ts +8 -0
  152. package/dist/hono/console/routes/clients.d.ts.map +1 -0
  153. package/dist/hono/console/routes/clients.js +322 -0
  154. package/dist/hono/console/routes/clients.js.map +1 -0
  155. package/dist/hono/console/routes/commits.d.ts +8 -0
  156. package/dist/hono/console/routes/commits.d.ts.map +1 -0
  157. package/dist/hono/console/routes/commits.js +882 -0
  158. package/dist/hono/console/routes/commits.js.map +1 -0
  159. package/dist/hono/console/routes/context.d.ts +188 -0
  160. package/dist/hono/console/routes/context.d.ts.map +1 -0
  161. package/dist/hono/console/routes/context.js +633 -0
  162. package/dist/hono/console/routes/context.js.map +1 -0
  163. package/dist/hono/console/routes/events.d.ts +8 -0
  164. package/dist/hono/console/routes/events.d.ts.map +1 -0
  165. package/dist/hono/console/routes/events.js +501 -0
  166. package/dist/hono/console/routes/events.js.map +1 -0
  167. package/dist/hono/console/routes/maintenance.d.ts +8 -0
  168. package/dist/hono/console/routes/maintenance.d.ts.map +1 -0
  169. package/dist/hono/console/routes/maintenance.js +341 -0
  170. package/dist/hono/console/routes/maintenance.js.map +1 -0
  171. package/dist/hono/console/routes/shared.d.ts +174 -0
  172. package/dist/hono/console/routes/shared.d.ts.map +1 -0
  173. package/dist/hono/console/routes/shared.js +583 -0
  174. package/dist/hono/console/routes/shared.js.map +1 -0
  175. package/dist/hono/console/routes/stats.d.ts +8 -0
  176. package/dist/hono/console/routes/stats.d.ts.map +1 -0
  177. package/dist/hono/console/routes/stats.js +295 -0
  178. package/dist/hono/console/routes/stats.js.map +1 -0
  179. package/dist/hono/console/routes/storage.d.ts +8 -0
  180. package/dist/hono/console/routes/storage.d.ts.map +1 -0
  181. package/dist/hono/console/routes/storage.js +121 -0
  182. package/dist/hono/console/routes/storage.js.map +1 -0
  183. package/dist/hono/console/routes.d.ts +36 -0
  184. package/dist/hono/console/routes.d.ts.map +1 -0
  185. package/dist/hono/console/routes.js +112 -0
  186. package/dist/hono/console/routes.js.map +1 -0
  187. package/dist/hono/console/schema-errors.d.ts +2 -0
  188. package/dist/hono/console/schema-errors.d.ts.map +1 -0
  189. package/dist/hono/console/schema-errors.js +17 -0
  190. package/dist/hono/console/schema-errors.js.map +1 -0
  191. package/dist/hono/console/schemas.d.ts +1515 -0
  192. package/dist/hono/console/schemas.d.ts.map +1 -0
  193. package/dist/hono/console/schemas.js +661 -0
  194. package/dist/hono/console/schemas.js.map +1 -0
  195. package/dist/hono/console/types.d.ts +213 -0
  196. package/dist/hono/console/types.d.ts.map +1 -0
  197. package/dist/hono/console/types.js +2 -0
  198. package/dist/hono/console/types.js.map +1 -0
  199. package/dist/hono/console/ui.d.ts +38 -0
  200. package/dist/hono/console/ui.d.ts.map +1 -0
  201. package/dist/hono/console/ui.js +43 -0
  202. package/dist/hono/console/ui.js.map +1 -0
  203. package/dist/hono/create-server.d.ts +71 -0
  204. package/dist/hono/create-server.d.ts.map +1 -0
  205. package/dist/hono/create-server.js +121 -0
  206. package/dist/hono/create-server.js.map +1 -0
  207. package/dist/hono/errors.d.ts +13 -0
  208. package/dist/hono/errors.d.ts.map +1 -0
  209. package/dist/hono/errors.js +21 -0
  210. package/dist/hono/errors.js.map +1 -0
  211. package/dist/hono/index.d.ts +20 -0
  212. package/dist/hono/index.d.ts.map +1 -0
  213. package/dist/hono/index.js +31 -0
  214. package/dist/hono/index.js.map +1 -0
  215. package/dist/hono/openapi.d.ts +72 -0
  216. package/dist/hono/openapi.d.ts.map +1 -0
  217. package/dist/hono/openapi.js +99 -0
  218. package/dist/hono/openapi.js.map +1 -0
  219. package/dist/hono/proxy/connection-manager.d.ts +78 -0
  220. package/dist/hono/proxy/connection-manager.d.ts.map +1 -0
  221. package/dist/hono/proxy/connection-manager.js +251 -0
  222. package/dist/hono/proxy/connection-manager.js.map +1 -0
  223. package/dist/hono/proxy/index.d.ts +8 -0
  224. package/dist/hono/proxy/index.d.ts.map +1 -0
  225. package/dist/hono/proxy/index.js +8 -0
  226. package/dist/hono/proxy/index.js.map +1 -0
  227. package/dist/hono/proxy/routes.d.ts +86 -0
  228. package/dist/hono/proxy/routes.d.ts.map +1 -0
  229. package/dist/hono/proxy/routes.js +183 -0
  230. package/dist/hono/proxy/routes.js.map +1 -0
  231. package/dist/hono/rate-limit.d.ts +101 -0
  232. package/dist/hono/rate-limit.d.ts.map +1 -0
  233. package/dist/hono/rate-limit.js +184 -0
  234. package/dist/hono/rate-limit.js.map +1 -0
  235. package/dist/hono/realtime-sync-packs.d.ts +43 -0
  236. package/dist/hono/realtime-sync-packs.d.ts.map +1 -0
  237. package/dist/hono/realtime-sync-packs.js +219 -0
  238. package/dist/hono/realtime-sync-packs.js.map +1 -0
  239. package/dist/hono/routes/audit.d.ts +12 -0
  240. package/dist/hono/routes/audit.d.ts.map +1 -0
  241. package/dist/hono/routes/audit.js +385 -0
  242. package/dist/hono/routes/audit.js.map +1 -0
  243. package/dist/hono/routes/auth-leases.d.ts +8 -0
  244. package/dist/hono/routes/auth-leases.d.ts.map +1 -0
  245. package/dist/hono/routes/auth-leases.js +88 -0
  246. package/dist/hono/routes/auth-leases.js.map +1 -0
  247. package/dist/hono/routes/combined.d.ts +8 -0
  248. package/dist/hono/routes/combined.d.ts.map +1 -0
  249. package/dist/hono/routes/combined.js +392 -0
  250. package/dist/hono/routes/combined.js.map +1 -0
  251. package/dist/hono/routes/context.d.ts +314 -0
  252. package/dist/hono/routes/context.d.ts.map +1 -0
  253. package/dist/hono/routes/context.js +1147 -0
  254. package/dist/hono/routes/context.js.map +1 -0
  255. package/dist/hono/routes/health.d.ts +8 -0
  256. package/dist/hono/routes/health.d.ts.map +1 -0
  257. package/dist/hono/routes/health.js +16 -0
  258. package/dist/hono/routes/health.js.map +1 -0
  259. package/dist/hono/routes/realtime.d.ts +9 -0
  260. package/dist/hono/routes/realtime.d.ts.map +1 -0
  261. package/dist/hono/routes/realtime.js +626 -0
  262. package/dist/hono/routes/realtime.js.map +1 -0
  263. package/dist/hono/routes/shared.d.ts +689 -0
  264. package/dist/hono/routes/shared.d.ts.map +1 -0
  265. package/dist/hono/routes/shared.js +972 -0
  266. package/dist/hono/routes/shared.js.map +1 -0
  267. package/dist/hono/routes/snapshots.d.ts +10 -0
  268. package/dist/hono/routes/snapshots.d.ts.map +1 -0
  269. package/dist/hono/routes/snapshots.js +281 -0
  270. package/dist/hono/routes/snapshots.js.map +1 -0
  271. package/dist/hono/routes.d.ts +19 -0
  272. package/dist/hono/routes.d.ts.map +1 -0
  273. package/dist/hono/routes.js +37 -0
  274. package/dist/hono/routes.js.map +1 -0
  275. package/dist/hono/validation.d.ts +5 -0
  276. package/dist/hono/validation.d.ts.map +1 -0
  277. package/dist/hono/validation.js +47 -0
  278. package/dist/hono/validation.js.map +1 -0
  279. package/dist/hono/websocket-origin.d.ts +9 -0
  280. package/dist/hono/websocket-origin.d.ts.map +1 -0
  281. package/dist/hono/websocket-origin.js +96 -0
  282. package/dist/hono/websocket-origin.js.map +1 -0
  283. package/dist/hono/ws.d.ts +341 -0
  284. package/dist/hono/ws.d.ts.map +1 -0
  285. package/dist/hono/ws.js +711 -0
  286. package/dist/hono/ws.js.map +1 -0
  287. package/dist/index.d.ts +6 -0
  288. package/dist/index.d.ts.map +1 -1
  289. package/dist/index.js +6 -0
  290. package/dist/index.js.map +1 -1
  291. package/dist/libsql.d.ts +29 -0
  292. package/dist/libsql.d.ts.map +1 -0
  293. package/dist/libsql.js +25 -0
  294. package/dist/libsql.js.map +1 -0
  295. package/dist/migrate.js.map +1 -1
  296. package/dist/neon.d.ts +21 -0
  297. package/dist/neon.d.ts.map +1 -0
  298. package/dist/neon.js +22 -0
  299. package/dist/neon.js.map +1 -0
  300. package/dist/notify.d.ts +30 -0
  301. package/dist/notify.d.ts.map +1 -1
  302. package/dist/notify.js +160 -41
  303. package/dist/notify.js.map +1 -1
  304. package/dist/pglite.d.ts +37 -0
  305. package/dist/pglite.d.ts.map +1 -0
  306. package/dist/pglite.js +37 -0
  307. package/dist/pglite.js.map +1 -0
  308. package/dist/plugins/index.d.ts +2 -0
  309. package/dist/plugins/index.d.ts.map +1 -0
  310. package/dist/plugins/index.js +2 -0
  311. package/dist/plugins/index.js.map +1 -0
  312. package/dist/plugins/types.d.ts +73 -0
  313. package/dist/plugins/types.d.ts.map +1 -0
  314. package/dist/plugins/types.js +30 -0
  315. package/dist/plugins/types.js.map +1 -0
  316. package/dist/postgres/index.d.ts +68 -0
  317. package/dist/postgres/index.d.ts.map +1 -0
  318. package/dist/postgres/index.js +924 -0
  319. package/dist/postgres/index.js.map +1 -0
  320. package/dist/proxy/collection.d.ts +0 -2
  321. package/dist/proxy/collection.d.ts.map +1 -1
  322. package/dist/proxy/collection.js +2 -17
  323. package/dist/proxy/collection.js.map +1 -1
  324. package/dist/proxy/handler.d.ts +1 -1
  325. package/dist/proxy/handler.d.ts.map +1 -1
  326. package/dist/proxy/handler.js +1 -2
  327. package/dist/proxy/handler.js.map +1 -1
  328. package/dist/proxy/index.d.ts +1 -1
  329. package/dist/proxy/index.d.ts.map +1 -1
  330. package/dist/proxy/index.js +1 -1
  331. package/dist/proxy/index.js.map +1 -1
  332. package/dist/proxy/mutation-detector.js.map +1 -1
  333. package/dist/proxy/oplog.d.ts.map +1 -1
  334. package/dist/proxy/oplog.js +32 -8
  335. package/dist/proxy/oplog.js.map +1 -1
  336. package/dist/prune.d.ts +8 -1
  337. package/dist/prune.d.ts.map +1 -1
  338. package/dist/prune.js +68 -28
  339. package/dist/prune.js.map +1 -1
  340. package/dist/pull.d.ts +31 -0
  341. package/dist/pull.d.ts.map +1 -1
  342. package/dist/pull.js +1011 -471
  343. package/dist/pull.js.map +1 -1
  344. package/dist/push.d.ts +36 -2
  345. package/dist/push.d.ts.map +1 -1
  346. package/dist/push.js +603 -358
  347. package/dist/push.js.map +1 -1
  348. package/dist/realtime/in-memory.js.map +1 -1
  349. package/dist/realtime/index.d.ts +2 -1
  350. package/dist/realtime/index.d.ts.map +1 -1
  351. package/dist/realtime/index.js +1 -0
  352. package/dist/realtime/index.js.map +1 -1
  353. package/dist/realtime/types.d.ts +12 -0
  354. package/dist/realtime/types.d.ts.map +1 -1
  355. package/dist/realtime/types.js +13 -1
  356. package/dist/realtime/types.js.map +1 -1
  357. package/dist/relay/client-role/forward-engine.d.ts +63 -0
  358. package/dist/relay/client-role/forward-engine.d.ts.map +1 -0
  359. package/dist/relay/client-role/forward-engine.js +267 -0
  360. package/dist/relay/client-role/forward-engine.js.map +1 -0
  361. package/dist/relay/client-role/index.d.ts +9 -0
  362. package/dist/relay/client-role/index.d.ts.map +1 -0
  363. package/dist/relay/client-role/index.js +9 -0
  364. package/dist/relay/client-role/index.js.map +1 -0
  365. package/dist/relay/client-role/pull-engine.d.ts +72 -0
  366. package/dist/relay/client-role/pull-engine.d.ts.map +1 -0
  367. package/dist/relay/client-role/pull-engine.js +249 -0
  368. package/dist/relay/client-role/pull-engine.js.map +1 -0
  369. package/dist/relay/client-role/sequence-mapper.d.ts +65 -0
  370. package/dist/relay/client-role/sequence-mapper.d.ts.map +1 -0
  371. package/dist/relay/client-role/sequence-mapper.js +161 -0
  372. package/dist/relay/client-role/sequence-mapper.js.map +1 -0
  373. package/dist/relay/evaluation/relay-paths.d.ts +41 -0
  374. package/dist/relay/evaluation/relay-paths.d.ts.map +1 -0
  375. package/dist/relay/evaluation/relay-paths.js +504 -0
  376. package/dist/relay/evaluation/relay-paths.js.map +1 -0
  377. package/dist/relay/evaluation/rust-boundary.d.ts +47 -0
  378. package/dist/relay/evaluation/rust-boundary.d.ts.map +1 -0
  379. package/dist/relay/evaluation/rust-boundary.js +220 -0
  380. package/dist/relay/evaluation/rust-boundary.js.map +1 -0
  381. package/dist/relay/index.d.ts +37 -0
  382. package/dist/relay/index.d.ts.map +1 -0
  383. package/dist/relay/index.js +44 -0
  384. package/dist/relay/index.js.map +1 -0
  385. package/dist/relay/migrate.d.ts +18 -0
  386. package/dist/relay/migrate.d.ts.map +1 -0
  387. package/dist/relay/migrate.js +99 -0
  388. package/dist/relay/migrate.js.map +1 -0
  389. package/dist/relay/mode-manager.d.ts +60 -0
  390. package/dist/relay/mode-manager.d.ts.map +1 -0
  391. package/dist/relay/mode-manager.js +114 -0
  392. package/dist/relay/mode-manager.js.map +1 -0
  393. package/dist/relay/realtime.d.ts +90 -0
  394. package/dist/relay/realtime.d.ts.map +1 -0
  395. package/dist/relay/realtime.js +147 -0
  396. package/dist/relay/realtime.js.map +1 -0
  397. package/dist/relay/relay.d.ts +190 -0
  398. package/dist/relay/relay.d.ts.map +1 -0
  399. package/dist/relay/relay.js +320 -0
  400. package/dist/relay/relay.js.map +1 -0
  401. package/dist/relay/schema.d.ts +158 -0
  402. package/dist/relay/schema.d.ts.map +1 -0
  403. package/dist/relay/schema.js +7 -0
  404. package/dist/relay/schema.js.map +1 -0
  405. package/dist/relay/server-role/index.d.ts +56 -0
  406. package/dist/relay/server-role/index.d.ts.map +1 -0
  407. package/dist/relay/server-role/index.js +193 -0
  408. package/dist/relay/server-role/index.js.map +1 -0
  409. package/dist/relay/server-role/pull.d.ts +27 -0
  410. package/dist/relay/server-role/pull.d.ts.map +1 -0
  411. package/dist/relay/server-role/pull.js +24 -0
  412. package/dist/relay/server-role/pull.js.map +1 -0
  413. package/dist/relay/server-role/push.d.ts +29 -0
  414. package/dist/relay/server-role/push.d.ts.map +1 -0
  415. package/dist/relay/server-role/push.js +122 -0
  416. package/dist/relay/server-role/push.js.map +1 -0
  417. package/dist/s3/index.d.ts +83 -0
  418. package/dist/s3/index.d.ts.map +1 -0
  419. package/dist/s3/index.js +223 -0
  420. package/dist/s3/index.js.map +1 -0
  421. package/dist/schema.d.ts +137 -1
  422. package/dist/schema.d.ts.map +1 -1
  423. package/dist/schema.js +1 -0
  424. package/dist/schema.js.map +1 -1
  425. package/dist/service-worker/index.d.ts +114 -0
  426. package/dist/service-worker/index.d.ts.map +1 -0
  427. package/dist/service-worker/index.js +487 -0
  428. package/dist/service-worker/index.js.map +1 -0
  429. package/dist/snapshot-artifacts/sqlite-bun.d.ts +15 -0
  430. package/dist/snapshot-artifacts/sqlite-bun.d.ts.map +1 -0
  431. package/dist/snapshot-artifacts/sqlite-bun.js +128 -0
  432. package/dist/snapshot-artifacts/sqlite-bun.js.map +1 -0
  433. package/dist/snapshot-artifacts.d.ts +206 -0
  434. package/dist/snapshot-artifacts.d.ts.map +1 -0
  435. package/dist/snapshot-artifacts.js +545 -0
  436. package/dist/snapshot-artifacts.js.map +1 -0
  437. package/dist/snapshot-chunks/db-metadata.d.ts +18 -0
  438. package/dist/snapshot-chunks/db-metadata.d.ts.map +1 -1
  439. package/dist/snapshot-chunks/db-metadata.js +91 -63
  440. package/dist/snapshot-chunks/db-metadata.js.map +1 -1
  441. package/dist/snapshot-chunks/types.d.ts +2 -0
  442. package/dist/snapshot-chunks/types.d.ts.map +1 -1
  443. package/dist/snapshot-chunks.d.ts +33 -3
  444. package/dist/snapshot-chunks.d.ts.map +1 -1
  445. package/dist/snapshot-chunks.js +136 -55
  446. package/dist/snapshot-chunks.js.map +1 -1
  447. package/dist/sqlite/index.d.ts +53 -0
  448. package/dist/sqlite/index.d.ts.map +1 -0
  449. package/dist/sqlite/index.js +795 -0
  450. package/dist/sqlite/index.js.map +1 -0
  451. package/dist/sqlite3.d.ts +22 -0
  452. package/dist/sqlite3.d.ts.map +1 -0
  453. package/dist/sqlite3.js +99 -0
  454. package/dist/sqlite3.js.map +1 -0
  455. package/dist/stats.d.ts +8 -0
  456. package/dist/stats.d.ts.map +1 -1
  457. package/dist/stats.js +45 -13
  458. package/dist/stats.js.map +1 -1
  459. package/dist/subscriptions/cache.d.ts +3 -0
  460. package/dist/subscriptions/cache.d.ts.map +1 -1
  461. package/dist/subscriptions/cache.js +44 -0
  462. package/dist/subscriptions/cache.js.map +1 -1
  463. package/dist/subscriptions/resolve.d.ts +3 -1
  464. package/dist/subscriptions/resolve.d.ts.map +1 -1
  465. package/dist/subscriptions/resolve.js +90 -51
  466. package/dist/subscriptions/resolve.js.map +1 -1
  467. package/dist/sync.d.ts +3 -0
  468. package/dist/sync.d.ts.map +1 -1
  469. package/dist/sync.js +8 -4
  470. package/dist/sync.js.map +1 -1
  471. package/package.json +296 -7
  472. package/src/auth-leases.ts +649 -0
  473. package/src/better-sqlite3.ts +35 -0
  474. package/src/blobs/access.ts +244 -0
  475. package/src/blobs/adapters/database.ts +125 -43
  476. package/src/blobs/index.ts +1 -0
  477. package/src/blobs/manager.ts +366 -65
  478. package/src/blobs/migrate.ts +16 -8
  479. package/src/blobs/types.ts +4 -0
  480. package/src/bun-sqlite-ambient.d.ts +19 -0
  481. package/src/bun-sqlite.ts +27 -0
  482. package/src/clients.ts +1 -0
  483. package/src/cloudflare/durable-object.ts +289 -0
  484. package/src/cloudflare/index.ts +22 -0
  485. package/src/cloudflare/r2.ts +526 -0
  486. package/src/cloudflare/scope-cache.ts +341 -0
  487. package/src/cloudflare/sentry.ts +230 -0
  488. package/src/cloudflare/worker.ts +77 -0
  489. package/src/commit-integrity.ts +371 -0
  490. package/src/crdt-yjs/index.ts +931 -0
  491. package/src/d1.ts +16 -0
  492. package/src/dialect/base.ts +71 -5
  493. package/src/dialect/helpers.ts +31 -0
  494. package/src/dialect/types.ts +47 -0
  495. package/src/encrypted-crdt.ts +786 -0
  496. package/src/errors.ts +22 -0
  497. package/src/filesystem/index.ts +262 -0
  498. package/src/handlers/collection.ts +78 -78
  499. package/src/handlers/create-handler.ts +540 -147
  500. package/src/handlers/types.ts +116 -0
  501. package/src/helpers/index.ts +2 -0
  502. package/src/helpers/scope-authorization.ts +27 -0
  503. package/src/helpers/scope-commit-index.ts +52 -0
  504. package/src/hono/api-key-auth.ts +177 -0
  505. package/src/hono/audit-redaction.ts +135 -0
  506. package/src/hono/blobs.ts +851 -0
  507. package/src/hono/console/gateway.ts +3046 -0
  508. package/src/hono/console/live-auth.ts +46 -0
  509. package/src/hono/console/route-descriptor.ts +22 -0
  510. package/src/hono/console/routes/api-keys.ts +721 -0
  511. package/src/hono/console/routes/clients.ts +447 -0
  512. package/src/hono/console/routes/commits.ts +1137 -0
  513. package/src/hono/console/routes/context.ts +956 -0
  514. package/src/hono/console/routes/events.ts +669 -0
  515. package/src/hono/console/routes/maintenance.ts +461 -0
  516. package/src/hono/console/routes/shared.ts +816 -0
  517. package/src/hono/console/routes/stats.ts +392 -0
  518. package/src/hono/console/routes/storage.ts +159 -0
  519. package/src/hono/console/routes.ts +146 -0
  520. package/src/hono/console/schema-errors.ts +23 -0
  521. package/src/hono/console/schemas.ts +914 -0
  522. package/src/hono/console/types.ts +223 -0
  523. package/src/hono/console/ui.ts +100 -0
  524. package/src/hono/create-server.ts +230 -0
  525. package/src/hono/errors.ts +50 -0
  526. package/src/hono/index.ts +54 -0
  527. package/src/hono/openapi.ts +139 -0
  528. package/src/hono/proxy/connection-manager.ts +340 -0
  529. package/src/hono/proxy/index.ts +8 -0
  530. package/src/hono/proxy/routes.ts +272 -0
  531. package/src/hono/rate-limit.ts +319 -0
  532. package/src/hono/realtime-sync-packs.ts +354 -0
  533. package/src/hono/routes/audit.ts +499 -0
  534. package/src/hono/routes/auth-leases.ts +119 -0
  535. package/src/hono/routes/combined.ts +583 -0
  536. package/src/hono/routes/context.ts +1629 -0
  537. package/src/hono/routes/health.ts +26 -0
  538. package/src/hono/routes/realtime.ts +808 -0
  539. package/src/hono/routes/shared.ts +1626 -0
  540. package/src/hono/routes/snapshots.ts +345 -0
  541. package/src/hono/routes.ts +68 -0
  542. package/src/hono/validation.ts +81 -0
  543. package/src/hono/websocket-origin.ts +131 -0
  544. package/src/hono/ws.ts +1134 -0
  545. package/src/index.ts +6 -0
  546. package/src/libsql.ts +51 -0
  547. package/src/neon.ts +28 -0
  548. package/src/notify.ts +224 -44
  549. package/src/pglite.ts +68 -0
  550. package/src/plugins/index.ts +1 -0
  551. package/src/plugins/types.ts +144 -0
  552. package/src/postgres/index.ts +1291 -0
  553. package/src/proxy/collection.ts +5 -27
  554. package/src/proxy/handler.ts +2 -2
  555. package/src/proxy/index.ts +0 -2
  556. package/src/proxy/oplog.ts +41 -10
  557. package/src/prune.ts +137 -36
  558. package/src/pull.ts +1504 -591
  559. package/src/push.ts +881 -443
  560. package/src/realtime/index.ts +2 -0
  561. package/src/realtime/types.ts +35 -0
  562. package/src/relay/bun-types.d.ts +50 -0
  563. package/src/relay/client-role/forward-engine.ts +355 -0
  564. package/src/relay/client-role/index.ts +9 -0
  565. package/src/relay/client-role/pull-engine.ts +329 -0
  566. package/src/relay/client-role/sequence-mapper.ts +201 -0
  567. package/src/relay/evaluation/relay-paths.ts +699 -0
  568. package/src/relay/evaluation/rust-boundary.ts +464 -0
  569. package/src/relay/index.ts +50 -0
  570. package/src/relay/migrate.ts +113 -0
  571. package/src/relay/mode-manager.ts +142 -0
  572. package/src/relay/realtime.ts +207 -0
  573. package/src/relay/relay.ts +431 -0
  574. package/src/relay/schema.ts +171 -0
  575. package/src/relay/server-role/index.ts +338 -0
  576. package/src/relay/server-role/pull.ts +43 -0
  577. package/src/relay/server-role/push.ts +164 -0
  578. package/src/s3/index.ts +346 -0
  579. package/src/schema.ts +141 -1
  580. package/src/service-worker/index.ts +773 -0
  581. package/src/snapshot-artifacts/sqlite-bun.ts +168 -0
  582. package/src/snapshot-artifacts.ts +896 -0
  583. package/src/snapshot-chunks/db-metadata.ts +131 -72
  584. package/src/snapshot-chunks/types.ts +2 -0
  585. package/src/snapshot-chunks.ts +194 -70
  586. package/src/sqlite/index.ts +1064 -0
  587. package/src/sqlite3.ts +137 -0
  588. package/src/stats.ts +76 -13
  589. package/src/subscriptions/cache.ts +58 -0
  590. package/src/subscriptions/resolve.ts +99 -58
  591. package/src/sync.ts +16 -6
  592. package/src/blobs/adapters/database.test.ts +0 -67
  593. package/src/notify.test.ts +0 -520
  594. package/src/proxy/handler.test.ts +0 -126
  595. package/src/proxy/mutation-detector.test.ts +0 -71
  596. package/src/snapshot-chunks/db-metadata.test.ts +0 -172
  597. package/src/subscriptions/resolve.test.ts +0 -180
@@ -0,0 +1,338 @@
1
+ /**
2
+ * @syncular/server/relay - Server Role
3
+ *
4
+ * Hono routes for serving local clients.
5
+ */
6
+
7
+ import type { SyncPullRequest, SyncPushRequest } from '@syncular/core';
8
+ import {
9
+ createSyncTimer,
10
+ createSyncularErrorResponse,
11
+ isRecord,
12
+ logSyncEvent,
13
+ ScopeValuesSchema,
14
+ SyncBootstrapStateSchema,
15
+ SyncPullRequestSchema,
16
+ SyncPushRequestSchema,
17
+ } from '@syncular/core';
18
+ import type {
19
+ ServerHandlerCollection,
20
+ ServerSyncDialect,
21
+ SyncServerAuth,
22
+ } from '@syncular/server';
23
+ import { recordClientCursor } from '@syncular/server';
24
+ import type { Context } from 'hono';
25
+ import { Hono } from 'hono';
26
+ import type { Kysely } from 'kysely';
27
+ import type { RelayRealtime } from '../realtime';
28
+ import type { RelayDatabase } from '../schema';
29
+ import { relayPull } from './pull';
30
+ import { relayPushCommit } from './push';
31
+
32
+ type RelayAuth = SyncServerAuth;
33
+
34
+ /**
35
+ * Options for creating relay routes.
36
+ */
37
+ export interface CreateRelayRoutesOptions<
38
+ DB extends RelayDatabase = RelayDatabase,
39
+ > {
40
+ db: Kysely<DB>;
41
+ dialect: ServerSyncDialect;
42
+ handlers: ServerHandlerCollection<DB, RelayAuth>;
43
+ realtime: RelayRealtime;
44
+ /**
45
+ * Called after a commit is successfully applied locally.
46
+ * Use this to trigger forwarding and notify local clients.
47
+ */
48
+ onCommit?: (
49
+ localCommitSeq: number,
50
+ affectedTables: string[]
51
+ ) => Promise<void>;
52
+ /**
53
+ * Optional: authenticate requests. Return actor ID or null for unauthorized.
54
+ * If not provided, all requests are allowed with actor ID 'anonymous'.
55
+ */
56
+ authenticate?: (c: Context) => Promise<{ actorId: string } | null>;
57
+ /**
58
+ * Max operations per pushed commit (default: 200).
59
+ */
60
+ maxOperationsPerPush?: number;
61
+ /**
62
+ * Max subscriptions per pull request (default: 200).
63
+ */
64
+ maxSubscriptionsPerPull?: number;
65
+ /**
66
+ * Max commits per pull request (default: 100).
67
+ */
68
+ maxPullLimitCommits?: number;
69
+ }
70
+
71
+ function clampInt(value: number, min: number, max: number): number {
72
+ return Math.max(min, Math.min(max, value));
73
+ }
74
+
75
+ function relayError(
76
+ c: Context,
77
+ status: 400 | 401,
78
+ code:
79
+ | 'sync.auth_required'
80
+ | 'sync.invalid_request'
81
+ | 'sync.too_many_operations',
82
+ message?: string,
83
+ details?: Record<string, unknown>
84
+ ): Response {
85
+ return c.json(
86
+ createSyncularErrorResponse(code, {
87
+ ...(message ? { message } : {}),
88
+ ...(details ? { details } : {}),
89
+ }),
90
+ status
91
+ );
92
+ }
93
+
94
+ function invalidRelayRequest(
95
+ c: Context,
96
+ message: string,
97
+ details?: Record<string, unknown>
98
+ ): Response {
99
+ return relayError(c, 400, 'sync.invalid_request', message, details);
100
+ }
101
+
102
+ /**
103
+ * Create Hono routes for relay server-role endpoints.
104
+ *
105
+ * Provides:
106
+ * - POST /pull (commit stream + optional bootstrap snapshots)
107
+ * - POST /push (commit ingestion)
108
+ * - GET /realtime (WebSocket wake-up notifications)
109
+ */
110
+ export function createRelayRoutes<DB extends RelayDatabase = RelayDatabase>(
111
+ options: CreateRelayRoutesOptions<DB>
112
+ ): Hono {
113
+ const routes = new Hono();
114
+ const maxOperationsPerPush = options.maxOperationsPerPush ?? 200;
115
+ const maxSubscriptionsPerPull = options.maxSubscriptionsPerPull ?? 200;
116
+ const maxPullLimitCommits = options.maxPullLimitCommits ?? 100;
117
+
118
+ const authenticate =
119
+ options.authenticate ?? (async () => ({ actorId: 'anonymous' }));
120
+
121
+ // POST /pull
122
+ routes.post('/pull', async (c) => {
123
+ const auth = await authenticate(c);
124
+ if (!auth) return relayError(c, 401, 'sync.auth_required');
125
+
126
+ const rawBody: unknown = await c.req.json();
127
+ const timer = createSyncTimer();
128
+
129
+ if (!isRecord(rawBody)) {
130
+ return invalidRelayRequest(c, 'Invalid JSON body');
131
+ }
132
+
133
+ if (!rawBody.clientId || typeof rawBody.clientId !== 'string') {
134
+ return invalidRelayRequest(c, 'clientId is required');
135
+ }
136
+
137
+ if (!Array.isArray(rawBody.subscriptions)) {
138
+ return invalidRelayRequest(c, 'subscriptions array is required');
139
+ }
140
+
141
+ if (rawBody.subscriptions.length > maxSubscriptionsPerPull) {
142
+ return invalidRelayRequest(
143
+ c,
144
+ `Too many subscriptions (max ${maxSubscriptionsPerPull})`
145
+ );
146
+ }
147
+
148
+ const subscriptions: SyncPullRequest['subscriptions'] = [];
149
+ for (const subValue of rawBody.subscriptions) {
150
+ if (!isRecord(subValue)) {
151
+ return invalidRelayRequest(c, 'Invalid subscription entry');
152
+ }
153
+
154
+ const id = typeof subValue.id === 'string' ? subValue.id : null;
155
+ const table = typeof subValue.table === 'string' ? subValue.table : null;
156
+ if (!id || !table) {
157
+ return invalidRelayRequest(c, 'Subscription id/table required');
158
+ }
159
+
160
+ const scopesParsed = ScopeValuesSchema.safeParse(subValue.scopes);
161
+ if (!scopesParsed.success) {
162
+ return invalidRelayRequest(c, 'Invalid subscription scopes');
163
+ }
164
+
165
+ const rawParams = subValue.params;
166
+ if (rawParams !== undefined && !isRecord(rawParams)) {
167
+ return invalidRelayRequest(c, 'Invalid subscription params');
168
+ }
169
+
170
+ const cursor =
171
+ typeof subValue.cursor === 'number' && Number.isInteger(subValue.cursor)
172
+ ? Math.max(-1, subValue.cursor)
173
+ : -1;
174
+
175
+ const rawBootstrapState = subValue.bootstrapState;
176
+ const bootstrapState =
177
+ rawBootstrapState === undefined || rawBootstrapState === null
178
+ ? null
179
+ : (() => {
180
+ const parsed =
181
+ SyncBootstrapStateSchema.safeParse(rawBootstrapState);
182
+ if (!parsed.success) return null;
183
+ return parsed.data;
184
+ })();
185
+
186
+ if (
187
+ rawBootstrapState !== undefined &&
188
+ rawBootstrapState !== null &&
189
+ bootstrapState === null
190
+ ) {
191
+ return invalidRelayRequest(c, 'Invalid subscription bootstrapState');
192
+ }
193
+
194
+ subscriptions.push({
195
+ id,
196
+ table,
197
+ scopes: scopesParsed.data,
198
+ params: rawParams,
199
+ cursor,
200
+ bootstrapState,
201
+ crdtStateVectors: [],
202
+ });
203
+ }
204
+
205
+ const request: SyncPullRequest = {
206
+ clientId: rawBody.clientId,
207
+ schemaVersion:
208
+ typeof rawBody.schemaVersion === 'number' &&
209
+ Number.isInteger(rawBody.schemaVersion)
210
+ ? rawBody.schemaVersion
211
+ : Number.NaN,
212
+ limitCommits: clampInt(
213
+ typeof rawBody.limitCommits === 'number' &&
214
+ Number.isInteger(rawBody.limitCommits)
215
+ ? rawBody.limitCommits
216
+ : 50,
217
+ 1,
218
+ maxPullLimitCommits
219
+ ),
220
+ limitSnapshotRows: clampInt(
221
+ typeof rawBody.limitSnapshotRows === 'number' &&
222
+ Number.isInteger(rawBody.limitSnapshotRows)
223
+ ? rawBody.limitSnapshotRows
224
+ : 1000,
225
+ 1,
226
+ 5000
227
+ ),
228
+ maxSnapshotPages: clampInt(
229
+ typeof rawBody.maxSnapshotPages === 'number' &&
230
+ Number.isInteger(rawBody.maxSnapshotPages)
231
+ ? rawBody.maxSnapshotPages
232
+ : 4,
233
+ 1,
234
+ 10
235
+ ),
236
+ dedupeRows:
237
+ typeof rawBody.dedupeRows === 'boolean'
238
+ ? rawBody.dedupeRows
239
+ : undefined,
240
+ subscriptions,
241
+ };
242
+
243
+ const validatedRequest = SyncPullRequestSchema.safeParse(request);
244
+ if (!validatedRequest.success) {
245
+ return invalidRelayRequest(c, 'Invalid pull request');
246
+ }
247
+
248
+ const pullResult = await relayPull({
249
+ db: options.db,
250
+ dialect: options.dialect,
251
+ handlers: options.handlers,
252
+ auth,
253
+ request: validatedRequest.data,
254
+ });
255
+
256
+ await recordClientCursor(options.db, options.dialect, {
257
+ clientId: validatedRequest.data.clientId,
258
+ actorId: auth.actorId,
259
+ cursor: pullResult.clientCursor,
260
+ effectiveScopes: pullResult.effectiveScopes,
261
+ });
262
+
263
+ // Notify realtime about updated scope values
264
+ options.realtime.updateClientScopeKeys(
265
+ request.clientId,
266
+ Object.keys(pullResult.effectiveScopes)
267
+ );
268
+
269
+ logSyncEvent({
270
+ event: 'relay.pull',
271
+ userId: auth.actorId,
272
+ durationMs: timer(),
273
+ subscriptionCount: pullResult.response.subscriptions.length,
274
+ clientCursor: pullResult.clientCursor,
275
+ });
276
+
277
+ return c.json(pullResult.response);
278
+ });
279
+
280
+ // POST /push
281
+ routes.post('/push', async (c) => {
282
+ const auth = await authenticate(c);
283
+ if (!auth) return relayError(c, 401, 'sync.auth_required');
284
+
285
+ const rawBody: unknown = await c.req.json();
286
+ const parsed = SyncPushRequestSchema.safeParse(rawBody);
287
+ if (!parsed.success) {
288
+ return invalidRelayRequest(c, 'Invalid push request');
289
+ }
290
+
291
+ const body: SyncPushRequest = parsed.data;
292
+
293
+ if (body.operations.length > maxOperationsPerPush) {
294
+ return relayError(
295
+ c,
296
+ 400,
297
+ 'sync.too_many_operations',
298
+ `Maximum ${maxOperationsPerPush} operations per push`
299
+ );
300
+ }
301
+
302
+ const timer = createSyncTimer();
303
+
304
+ const pushed = await relayPushCommit({
305
+ db: options.db,
306
+ dialect: options.dialect,
307
+ handlers: options.handlers,
308
+ auth,
309
+ request: body,
310
+ });
311
+
312
+ logSyncEvent({
313
+ event: 'relay.push',
314
+ userId: auth.actorId,
315
+ durationMs: timer(),
316
+ operationCount: body.operations.length,
317
+ status: pushed.response.status,
318
+ commitSeq: pushed.response.commitSeq,
319
+ });
320
+
321
+ // Notify about the commit
322
+ if (
323
+ pushed.response.ok === true &&
324
+ pushed.response.status === 'applied' &&
325
+ typeof pushed.response.commitSeq === 'number' &&
326
+ pushed.affectedTables.length > 0
327
+ ) {
328
+ await options.onCommit?.(
329
+ pushed.response.commitSeq,
330
+ pushed.affectedTables
331
+ );
332
+ }
333
+
334
+ return c.json(pushed.response);
335
+ });
336
+
337
+ return routes;
338
+ }
@@ -0,0 +1,43 @@
1
+ /**
2
+ * @syncular/server/relay - Server Role Pull Handler
3
+ *
4
+ * Handles pulls from local clients, serving changes stored locally
5
+ * on the relay.
6
+ */
7
+
8
+ import type { SyncPullRequest } from '@syncular/core';
9
+ import type {
10
+ ServerHandlerCollection,
11
+ ServerSyncDialect,
12
+ SyncServerAuth,
13
+ } from '@syncular/server';
14
+ import { type PullResult, pull } from '@syncular/server';
15
+ import type { Kysely } from 'kysely';
16
+ import type { RelayDatabase } from '../schema';
17
+
18
+ type RelayAuth = SyncServerAuth;
19
+
20
+ /**
21
+ * Pull commits for a local client from the relay.
22
+ *
23
+ * This wraps the standard server pull with relay-specific logic:
24
+ * - Restricts scopes to those the relay subscribes to
25
+ */
26
+ export async function relayPull<
27
+ DB extends RelayDatabase = RelayDatabase,
28
+ >(args: {
29
+ db: Kysely<DB>;
30
+ dialect: ServerSyncDialect;
31
+ handlers: ServerHandlerCollection<DB, RelayAuth>;
32
+ auth: RelayAuth;
33
+ request: SyncPullRequest;
34
+ }): Promise<PullResult> {
35
+ // Use the standard pull - scope authorization is handled by handlers
36
+ return pull({
37
+ db: args.db,
38
+ dialect: args.dialect,
39
+ handlers: args.handlers,
40
+ auth: args.auth,
41
+ request: args.request,
42
+ });
43
+ }
@@ -0,0 +1,164 @@
1
+ /**
2
+ * @syncular/server/relay - Server Role Push Handler
3
+ *
4
+ * Handles pushes from local clients, storing them locally and
5
+ * queueing them for forwarding to the main server.
6
+ */
7
+
8
+ import type { SyncPushRequest } from '@syncular/core';
9
+ import { randomId } from '@syncular/core';
10
+ import type {
11
+ ServerHandlerCollection,
12
+ ServerSyncDialect,
13
+ SyncServerAuth,
14
+ } from '@syncular/server';
15
+ import { type PushCommitResult, pushCommit } from '@syncular/server';
16
+ import { type Kysely, sql } from 'kysely';
17
+ import type { RelayDatabase } from '../schema';
18
+
19
+ type RelayAuth = SyncServerAuth;
20
+
21
+ /**
22
+ * Push a commit from a local client to the relay.
23
+ *
24
+ * This wraps the standard server pushCommit with relay-specific logic:
25
+ * 1. Validates that operations are within the relay's scope
26
+ * 2. Stores the commit locally
27
+ * 3. Enqueues the commit for forwarding to the main server
28
+ */
29
+ export async function relayPushCommit<
30
+ DB extends RelayDatabase = RelayDatabase,
31
+ >(args: {
32
+ db: Kysely<DB>;
33
+ dialect: ServerSyncDialect;
34
+ handlers: ServerHandlerCollection<DB, RelayAuth>;
35
+ auth: RelayAuth;
36
+ request: SyncPushRequest;
37
+ }): Promise<PushCommitResult> {
38
+ const { request } = args;
39
+
40
+ return args.db.transaction().execute(async (trx) => {
41
+ // Use the standard pushCommit - scope authorization is handled by handlers
42
+ const result = await pushCommit({
43
+ db: trx,
44
+ dialect: args.dialect,
45
+ handlers: args.handlers,
46
+ auth: args.auth,
47
+ request,
48
+ });
49
+
50
+ // If the commit was applied, enqueue it for forwarding to main server
51
+ if (
52
+ result.response.ok === true &&
53
+ result.response.status === 'applied' &&
54
+ typeof result.response.commitSeq === 'number'
55
+ ) {
56
+ try {
57
+ await enqueueForForwarding(trx, {
58
+ localCommitSeq: result.response.commitSeq,
59
+ clientId: request.clientId,
60
+ clientCommitId: request.clientCommitId,
61
+ operations: request.operations,
62
+ schemaVersion: request.schemaVersion,
63
+ });
64
+ } catch (error) {
65
+ await rollbackLocalCommit(trx, result.response.commitSeq);
66
+ throw error;
67
+ }
68
+ }
69
+
70
+ return result;
71
+ });
72
+ }
73
+
74
+ /**
75
+ * Enqueue a locally-committed change for forwarding to the main server.
76
+ */
77
+ async function enqueueForForwarding<DB extends RelayDatabase>(
78
+ db: Kysely<DB>,
79
+ args: {
80
+ localCommitSeq: number;
81
+ clientId: string;
82
+ clientCommitId: string;
83
+ operations: SyncPushRequest['operations'];
84
+ schemaVersion: number;
85
+ }
86
+ ): Promise<void> {
87
+ const now = Date.now();
88
+
89
+ await sql`
90
+ insert into ${sql.table('relay_forward_outbox')} (
91
+ id,
92
+ local_commit_seq,
93
+ client_id,
94
+ client_commit_id,
95
+ operations_json,
96
+ schema_version,
97
+ status,
98
+ main_commit_seq,
99
+ error,
100
+ last_response_json,
101
+ created_at,
102
+ updated_at,
103
+ attempt_count
104
+ )
105
+ values (
106
+ ${randomId()},
107
+ ${args.localCommitSeq},
108
+ ${args.clientId},
109
+ ${args.clientCommitId},
110
+ ${JSON.stringify(args.operations)},
111
+ ${args.schemaVersion},
112
+ 'pending',
113
+ ${null},
114
+ ${null},
115
+ ${null},
116
+ ${now},
117
+ ${now},
118
+ ${0}
119
+ )
120
+ `.execute(db);
121
+
122
+ // Also create a sequence map entry for this commit
123
+ await sql`
124
+ insert into ${sql.table('relay_sequence_map')} (
125
+ local_commit_seq,
126
+ main_commit_seq,
127
+ status,
128
+ created_at,
129
+ updated_at
130
+ )
131
+ values (${args.localCommitSeq}, ${null}, 'pending', ${now}, ${now})
132
+ on conflict (local_commit_seq) do nothing
133
+ `.execute(db);
134
+ }
135
+
136
+ async function rollbackLocalCommit<DB extends RelayDatabase>(
137
+ db: Kysely<DB>,
138
+ commitSeq: number
139
+ ): Promise<void> {
140
+ await sql`
141
+ delete from ${sql.table('relay_sequence_map')}
142
+ where ${sql.ref('local_commit_seq')} = ${commitSeq}
143
+ `.execute(db);
144
+
145
+ await sql`
146
+ delete from ${sql.table('relay_forward_outbox')}
147
+ where ${sql.ref('local_commit_seq')} = ${commitSeq}
148
+ `.execute(db);
149
+
150
+ await sql`
151
+ delete from ${sql.table('sync_table_commits')}
152
+ where ${sql.ref('commit_seq')} = ${commitSeq}
153
+ `.execute(db);
154
+
155
+ await sql`
156
+ delete from ${sql.table('sync_changes')}
157
+ where ${sql.ref('commit_seq')} = ${commitSeq}
158
+ `.execute(db);
159
+
160
+ await sql`
161
+ delete from ${sql.table('sync_commits')}
162
+ where ${sql.ref('commit_seq')} = ${commitSeq}
163
+ `.execute(db);
164
+ }