@syncular/server 0.0.6-96 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (601) 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 +5 -4
  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 +43 -6
  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/index.js +3 -3
  84. package/dist/dialect/types.d.ts +40 -0
  85. package/dist/dialect/types.d.ts.map +1 -1
  86. package/dist/encrypted-crdt.d.ts +67 -0
  87. package/dist/encrypted-crdt.d.ts.map +1 -0
  88. package/dist/encrypted-crdt.js +426 -0
  89. package/dist/encrypted-crdt.js.map +1 -0
  90. package/dist/errors.d.ts +10 -0
  91. package/dist/errors.d.ts.map +1 -0
  92. package/dist/errors.js +13 -0
  93. package/dist/errors.js.map +1 -0
  94. package/dist/filesystem/index.d.ts +44 -0
  95. package/dist/filesystem/index.d.ts.map +1 -0
  96. package/dist/filesystem/index.js +164 -0
  97. package/dist/filesystem/index.js.map +1 -0
  98. package/dist/handlers/collection.d.ts +11 -3
  99. package/dist/handlers/collection.d.ts.map +1 -1
  100. package/dist/handlers/collection.js +34 -56
  101. package/dist/handlers/collection.js.map +1 -1
  102. package/dist/handlers/create-handler.d.ts +31 -7
  103. package/dist/handlers/create-handler.d.ts.map +1 -1
  104. package/dist/handlers/create-handler.js +332 -115
  105. package/dist/handlers/create-handler.js.map +1 -1
  106. package/dist/handlers/index.js +3 -3
  107. package/dist/handlers/types.d.ts +86 -1
  108. package/dist/handlers/types.d.ts.map +1 -1
  109. package/dist/helpers/conflict.js.map +1 -1
  110. package/dist/helpers/emitted-change.js.map +1 -1
  111. package/dist/helpers/index.d.ts +2 -0
  112. package/dist/helpers/index.d.ts.map +1 -1
  113. package/dist/helpers/index.js +6 -4
  114. package/dist/helpers/index.js.map +1 -1
  115. package/dist/helpers/paginate.js.map +1 -1
  116. package/dist/helpers/scope-authorization.d.ts +7 -0
  117. package/dist/helpers/scope-authorization.d.ts.map +1 -0
  118. package/dist/helpers/scope-authorization.js +19 -0
  119. package/dist/helpers/scope-authorization.js.map +1 -0
  120. package/dist/helpers/scope-commit-index.d.ts +12 -0
  121. package/dist/helpers/scope-commit-index.d.ts.map +1 -0
  122. package/dist/helpers/scope-commit-index.js +35 -0
  123. package/dist/helpers/scope-commit-index.js.map +1 -0
  124. package/dist/helpers/scope-strings.js.map +1 -1
  125. package/dist/hono/api-key-auth.d.ts +49 -0
  126. package/dist/hono/api-key-auth.d.ts.map +1 -0
  127. package/dist/hono/api-key-auth.js +108 -0
  128. package/dist/hono/api-key-auth.js.map +1 -0
  129. package/dist/hono/audit-redaction.d.ts +20 -0
  130. package/dist/hono/audit-redaction.d.ts.map +1 -0
  131. package/dist/hono/audit-redaction.js +85 -0
  132. package/dist/hono/audit-redaction.js.map +1 -0
  133. package/dist/hono/blobs.d.ts +75 -0
  134. package/dist/hono/blobs.d.ts.map +1 -0
  135. package/dist/hono/blobs.js +586 -0
  136. package/dist/hono/blobs.js.map +1 -0
  137. package/dist/hono/console/gateway.d.ts +42 -0
  138. package/dist/hono/console/gateway.d.ts.map +1 -0
  139. package/dist/hono/console/gateway.js +2158 -0
  140. package/dist/hono/console/gateway.js.map +1 -0
  141. package/dist/hono/console/live-auth.d.ts +7 -0
  142. package/dist/hono/console/live-auth.d.ts.map +1 -0
  143. package/dist/hono/console/live-auth.js +39 -0
  144. package/dist/hono/console/live-auth.js.map +1 -0
  145. package/dist/hono/console/route-descriptor.d.ts +6 -0
  146. package/dist/hono/console/route-descriptor.d.ts.map +1 -0
  147. package/dist/hono/console/route-descriptor.js +16 -0
  148. package/dist/hono/console/route-descriptor.js.map +1 -0
  149. package/dist/hono/console/routes/api-keys.d.ts +8 -0
  150. package/dist/hono/console/routes/api-keys.d.ts.map +1 -0
  151. package/dist/hono/console/routes/api-keys.js +575 -0
  152. package/dist/hono/console/routes/api-keys.js.map +1 -0
  153. package/dist/hono/console/routes/clients.d.ts +8 -0
  154. package/dist/hono/console/routes/clients.d.ts.map +1 -0
  155. package/dist/hono/console/routes/clients.js +322 -0
  156. package/dist/hono/console/routes/clients.js.map +1 -0
  157. package/dist/hono/console/routes/commits.d.ts +8 -0
  158. package/dist/hono/console/routes/commits.d.ts.map +1 -0
  159. package/dist/hono/console/routes/commits.js +882 -0
  160. package/dist/hono/console/routes/commits.js.map +1 -0
  161. package/dist/hono/console/routes/context.d.ts +188 -0
  162. package/dist/hono/console/routes/context.d.ts.map +1 -0
  163. package/dist/hono/console/routes/context.js +633 -0
  164. package/dist/hono/console/routes/context.js.map +1 -0
  165. package/dist/hono/console/routes/events.d.ts +8 -0
  166. package/dist/hono/console/routes/events.d.ts.map +1 -0
  167. package/dist/hono/console/routes/events.js +501 -0
  168. package/dist/hono/console/routes/events.js.map +1 -0
  169. package/dist/hono/console/routes/maintenance.d.ts +8 -0
  170. package/dist/hono/console/routes/maintenance.d.ts.map +1 -0
  171. package/dist/hono/console/routes/maintenance.js +341 -0
  172. package/dist/hono/console/routes/maintenance.js.map +1 -0
  173. package/dist/hono/console/routes/shared.d.ts +174 -0
  174. package/dist/hono/console/routes/shared.d.ts.map +1 -0
  175. package/dist/hono/console/routes/shared.js +583 -0
  176. package/dist/hono/console/routes/shared.js.map +1 -0
  177. package/dist/hono/console/routes/stats.d.ts +8 -0
  178. package/dist/hono/console/routes/stats.d.ts.map +1 -0
  179. package/dist/hono/console/routes/stats.js +295 -0
  180. package/dist/hono/console/routes/stats.js.map +1 -0
  181. package/dist/hono/console/routes/storage.d.ts +8 -0
  182. package/dist/hono/console/routes/storage.d.ts.map +1 -0
  183. package/dist/hono/console/routes/storage.js +121 -0
  184. package/dist/hono/console/routes/storage.js.map +1 -0
  185. package/dist/hono/console/routes.d.ts +36 -0
  186. package/dist/hono/console/routes.d.ts.map +1 -0
  187. package/dist/hono/console/routes.js +112 -0
  188. package/dist/hono/console/routes.js.map +1 -0
  189. package/dist/hono/console/schema-errors.d.ts +2 -0
  190. package/dist/hono/console/schema-errors.d.ts.map +1 -0
  191. package/dist/hono/console/schema-errors.js +17 -0
  192. package/dist/hono/console/schema-errors.js.map +1 -0
  193. package/dist/hono/console/schemas.d.ts +1515 -0
  194. package/dist/hono/console/schemas.d.ts.map +1 -0
  195. package/dist/hono/console/schemas.js +661 -0
  196. package/dist/hono/console/schemas.js.map +1 -0
  197. package/dist/hono/console/types.d.ts +213 -0
  198. package/dist/hono/console/types.d.ts.map +1 -0
  199. package/dist/hono/console/types.js +2 -0
  200. package/dist/hono/console/types.js.map +1 -0
  201. package/dist/hono/console/ui.d.ts +38 -0
  202. package/dist/hono/console/ui.d.ts.map +1 -0
  203. package/dist/hono/console/ui.js +43 -0
  204. package/dist/hono/console/ui.js.map +1 -0
  205. package/dist/hono/create-server.d.ts +71 -0
  206. package/dist/hono/create-server.d.ts.map +1 -0
  207. package/dist/hono/create-server.js +121 -0
  208. package/dist/hono/create-server.js.map +1 -0
  209. package/dist/hono/errors.d.ts +13 -0
  210. package/dist/hono/errors.d.ts.map +1 -0
  211. package/dist/hono/errors.js +21 -0
  212. package/dist/hono/errors.js.map +1 -0
  213. package/dist/hono/index.d.ts +20 -0
  214. package/dist/hono/index.d.ts.map +1 -0
  215. package/dist/hono/index.js +31 -0
  216. package/dist/hono/index.js.map +1 -0
  217. package/dist/hono/openapi.d.ts +72 -0
  218. package/dist/hono/openapi.d.ts.map +1 -0
  219. package/dist/hono/openapi.js +99 -0
  220. package/dist/hono/openapi.js.map +1 -0
  221. package/dist/hono/proxy/connection-manager.d.ts +78 -0
  222. package/dist/hono/proxy/connection-manager.d.ts.map +1 -0
  223. package/dist/hono/proxy/connection-manager.js +251 -0
  224. package/dist/hono/proxy/connection-manager.js.map +1 -0
  225. package/dist/hono/proxy/index.d.ts +8 -0
  226. package/dist/hono/proxy/index.d.ts.map +1 -0
  227. package/dist/hono/proxy/index.js +8 -0
  228. package/dist/hono/proxy/index.js.map +1 -0
  229. package/dist/hono/proxy/routes.d.ts +86 -0
  230. package/dist/hono/proxy/routes.d.ts.map +1 -0
  231. package/dist/hono/proxy/routes.js +183 -0
  232. package/dist/hono/proxy/routes.js.map +1 -0
  233. package/dist/hono/rate-limit.d.ts +101 -0
  234. package/dist/hono/rate-limit.d.ts.map +1 -0
  235. package/dist/hono/rate-limit.js +184 -0
  236. package/dist/hono/rate-limit.js.map +1 -0
  237. package/dist/hono/realtime-sync-packs.d.ts +43 -0
  238. package/dist/hono/realtime-sync-packs.d.ts.map +1 -0
  239. package/dist/hono/realtime-sync-packs.js +219 -0
  240. package/dist/hono/realtime-sync-packs.js.map +1 -0
  241. package/dist/hono/routes/audit.d.ts +12 -0
  242. package/dist/hono/routes/audit.d.ts.map +1 -0
  243. package/dist/hono/routes/audit.js +385 -0
  244. package/dist/hono/routes/audit.js.map +1 -0
  245. package/dist/hono/routes/auth-leases.d.ts +8 -0
  246. package/dist/hono/routes/auth-leases.d.ts.map +1 -0
  247. package/dist/hono/routes/auth-leases.js +88 -0
  248. package/dist/hono/routes/auth-leases.js.map +1 -0
  249. package/dist/hono/routes/combined.d.ts +8 -0
  250. package/dist/hono/routes/combined.d.ts.map +1 -0
  251. package/dist/hono/routes/combined.js +392 -0
  252. package/dist/hono/routes/combined.js.map +1 -0
  253. package/dist/hono/routes/context.d.ts +314 -0
  254. package/dist/hono/routes/context.d.ts.map +1 -0
  255. package/dist/hono/routes/context.js +1147 -0
  256. package/dist/hono/routes/context.js.map +1 -0
  257. package/dist/hono/routes/health.d.ts +8 -0
  258. package/dist/hono/routes/health.d.ts.map +1 -0
  259. package/dist/hono/routes/health.js +16 -0
  260. package/dist/hono/routes/health.js.map +1 -0
  261. package/dist/hono/routes/realtime.d.ts +9 -0
  262. package/dist/hono/routes/realtime.d.ts.map +1 -0
  263. package/dist/hono/routes/realtime.js +626 -0
  264. package/dist/hono/routes/realtime.js.map +1 -0
  265. package/dist/hono/routes/shared.d.ts +689 -0
  266. package/dist/hono/routes/shared.d.ts.map +1 -0
  267. package/dist/hono/routes/shared.js +972 -0
  268. package/dist/hono/routes/shared.js.map +1 -0
  269. package/dist/hono/routes/snapshots.d.ts +10 -0
  270. package/dist/hono/routes/snapshots.d.ts.map +1 -0
  271. package/dist/hono/routes/snapshots.js +281 -0
  272. package/dist/hono/routes/snapshots.js.map +1 -0
  273. package/dist/hono/routes.d.ts +19 -0
  274. package/dist/hono/routes.d.ts.map +1 -0
  275. package/dist/hono/routes.js +37 -0
  276. package/dist/hono/routes.js.map +1 -0
  277. package/dist/hono/validation.d.ts +5 -0
  278. package/dist/hono/validation.d.ts.map +1 -0
  279. package/dist/hono/validation.js +47 -0
  280. package/dist/hono/validation.js.map +1 -0
  281. package/dist/hono/websocket-origin.d.ts +9 -0
  282. package/dist/hono/websocket-origin.d.ts.map +1 -0
  283. package/dist/hono/websocket-origin.js +96 -0
  284. package/dist/hono/websocket-origin.js.map +1 -0
  285. package/dist/hono/ws.d.ts +341 -0
  286. package/dist/hono/ws.d.ts.map +1 -0
  287. package/dist/hono/ws.js +711 -0
  288. package/dist/hono/ws.js.map +1 -0
  289. package/dist/index.d.ts +6 -0
  290. package/dist/index.d.ts.map +1 -1
  291. package/dist/index.js +24 -18
  292. package/dist/index.js.map +1 -1
  293. package/dist/libsql.d.ts +29 -0
  294. package/dist/libsql.d.ts.map +1 -0
  295. package/dist/libsql.js +25 -0
  296. package/dist/libsql.js.map +1 -0
  297. package/dist/migrate.js.map +1 -1
  298. package/dist/neon.d.ts +21 -0
  299. package/dist/neon.d.ts.map +1 -0
  300. package/dist/neon.js +22 -0
  301. package/dist/neon.js.map +1 -0
  302. package/dist/notify.d.ts +30 -0
  303. package/dist/notify.d.ts.map +1 -1
  304. package/dist/notify.js +160 -41
  305. package/dist/notify.js.map +1 -1
  306. package/dist/pglite.d.ts +37 -0
  307. package/dist/pglite.d.ts.map +1 -0
  308. package/dist/pglite.js +37 -0
  309. package/dist/pglite.js.map +1 -0
  310. package/dist/plugins/index.d.ts +2 -0
  311. package/dist/plugins/index.d.ts.map +1 -0
  312. package/dist/plugins/index.js +2 -0
  313. package/dist/plugins/index.js.map +1 -0
  314. package/dist/plugins/types.d.ts +73 -0
  315. package/dist/plugins/types.d.ts.map +1 -0
  316. package/dist/plugins/types.js +30 -0
  317. package/dist/plugins/types.js.map +1 -0
  318. package/dist/postgres/index.d.ts +68 -0
  319. package/dist/postgres/index.d.ts.map +1 -0
  320. package/dist/postgres/index.js +924 -0
  321. package/dist/postgres/index.js.map +1 -0
  322. package/dist/proxy/collection.d.ts +0 -2
  323. package/dist/proxy/collection.d.ts.map +1 -1
  324. package/dist/proxy/collection.js +2 -17
  325. package/dist/proxy/collection.js.map +1 -1
  326. package/dist/proxy/handler.d.ts +1 -1
  327. package/dist/proxy/handler.d.ts.map +1 -1
  328. package/dist/proxy/handler.js +3 -4
  329. package/dist/proxy/handler.js.map +1 -1
  330. package/dist/proxy/index.d.ts +1 -1
  331. package/dist/proxy/index.d.ts.map +1 -1
  332. package/dist/proxy/index.js +3 -3
  333. package/dist/proxy/index.js.map +1 -1
  334. package/dist/proxy/mutation-detector.js.map +1 -1
  335. package/dist/proxy/oplog.d.ts.map +1 -1
  336. package/dist/proxy/oplog.js +32 -8
  337. package/dist/proxy/oplog.js.map +1 -1
  338. package/dist/prune.d.ts +8 -1
  339. package/dist/prune.d.ts.map +1 -1
  340. package/dist/prune.js +68 -28
  341. package/dist/prune.js.map +1 -1
  342. package/dist/pull.d.ts +31 -0
  343. package/dist/pull.d.ts.map +1 -1
  344. package/dist/pull.js +1014 -474
  345. package/dist/pull.js.map +1 -1
  346. package/dist/push.d.ts +36 -2
  347. package/dist/push.d.ts.map +1 -1
  348. package/dist/push.js +603 -358
  349. package/dist/push.js.map +1 -1
  350. package/dist/realtime/in-memory.js.map +1 -1
  351. package/dist/realtime/index.d.ts +2 -1
  352. package/dist/realtime/index.d.ts.map +1 -1
  353. package/dist/realtime/index.js +2 -1
  354. package/dist/realtime/index.js.map +1 -1
  355. package/dist/realtime/types.d.ts +12 -0
  356. package/dist/realtime/types.d.ts.map +1 -1
  357. package/dist/realtime/types.js +13 -1
  358. package/dist/realtime/types.js.map +1 -1
  359. package/dist/relay/client-role/forward-engine.d.ts +63 -0
  360. package/dist/relay/client-role/forward-engine.d.ts.map +1 -0
  361. package/dist/relay/client-role/forward-engine.js +267 -0
  362. package/dist/relay/client-role/forward-engine.js.map +1 -0
  363. package/dist/relay/client-role/index.d.ts +9 -0
  364. package/dist/relay/client-role/index.d.ts.map +1 -0
  365. package/dist/relay/client-role/index.js +9 -0
  366. package/dist/relay/client-role/index.js.map +1 -0
  367. package/dist/relay/client-role/pull-engine.d.ts +72 -0
  368. package/dist/relay/client-role/pull-engine.d.ts.map +1 -0
  369. package/dist/relay/client-role/pull-engine.js +249 -0
  370. package/dist/relay/client-role/pull-engine.js.map +1 -0
  371. package/dist/relay/client-role/sequence-mapper.d.ts +65 -0
  372. package/dist/relay/client-role/sequence-mapper.d.ts.map +1 -0
  373. package/dist/relay/client-role/sequence-mapper.js +161 -0
  374. package/dist/relay/client-role/sequence-mapper.js.map +1 -0
  375. package/dist/relay/evaluation/relay-paths.d.ts +41 -0
  376. package/dist/relay/evaluation/relay-paths.d.ts.map +1 -0
  377. package/dist/relay/evaluation/relay-paths.js +504 -0
  378. package/dist/relay/evaluation/relay-paths.js.map +1 -0
  379. package/dist/relay/evaluation/rust-boundary.d.ts +47 -0
  380. package/dist/relay/evaluation/rust-boundary.d.ts.map +1 -0
  381. package/dist/relay/evaluation/rust-boundary.js +220 -0
  382. package/dist/relay/evaluation/rust-boundary.js.map +1 -0
  383. package/dist/relay/index.d.ts +37 -0
  384. package/dist/relay/index.d.ts.map +1 -0
  385. package/dist/relay/index.js +44 -0
  386. package/dist/relay/index.js.map +1 -0
  387. package/dist/relay/migrate.d.ts +18 -0
  388. package/dist/relay/migrate.d.ts.map +1 -0
  389. package/dist/relay/migrate.js +99 -0
  390. package/dist/relay/migrate.js.map +1 -0
  391. package/dist/relay/mode-manager.d.ts +60 -0
  392. package/dist/relay/mode-manager.d.ts.map +1 -0
  393. package/dist/relay/mode-manager.js +114 -0
  394. package/dist/relay/mode-manager.js.map +1 -0
  395. package/dist/relay/realtime.d.ts +90 -0
  396. package/dist/relay/realtime.d.ts.map +1 -0
  397. package/dist/relay/realtime.js +147 -0
  398. package/dist/relay/realtime.js.map +1 -0
  399. package/dist/relay/relay.d.ts +190 -0
  400. package/dist/relay/relay.d.ts.map +1 -0
  401. package/dist/relay/relay.js +320 -0
  402. package/dist/relay/relay.js.map +1 -0
  403. package/dist/relay/schema.d.ts +158 -0
  404. package/dist/relay/schema.d.ts.map +1 -0
  405. package/dist/relay/schema.js +7 -0
  406. package/dist/relay/schema.js.map +1 -0
  407. package/dist/relay/server-role/index.d.ts +56 -0
  408. package/dist/relay/server-role/index.d.ts.map +1 -0
  409. package/dist/relay/server-role/index.js +193 -0
  410. package/dist/relay/server-role/index.js.map +1 -0
  411. package/dist/relay/server-role/pull.d.ts +27 -0
  412. package/dist/relay/server-role/pull.d.ts.map +1 -0
  413. package/dist/relay/server-role/pull.js +24 -0
  414. package/dist/relay/server-role/pull.js.map +1 -0
  415. package/dist/relay/server-role/push.d.ts +29 -0
  416. package/dist/relay/server-role/push.d.ts.map +1 -0
  417. package/dist/relay/server-role/push.js +122 -0
  418. package/dist/relay/server-role/push.js.map +1 -0
  419. package/dist/s3/index.d.ts +83 -0
  420. package/dist/s3/index.d.ts.map +1 -0
  421. package/dist/s3/index.js +223 -0
  422. package/dist/s3/index.js.map +1 -0
  423. package/dist/schema.d.ts +137 -1
  424. package/dist/schema.d.ts.map +1 -1
  425. package/dist/schema.js +1 -0
  426. package/dist/schema.js.map +1 -1
  427. package/dist/service-worker/index.d.ts +114 -0
  428. package/dist/service-worker/index.d.ts.map +1 -0
  429. package/dist/service-worker/index.js +487 -0
  430. package/dist/service-worker/index.js.map +1 -0
  431. package/dist/snapshot-artifacts/sqlite-bun.d.ts +15 -0
  432. package/dist/snapshot-artifacts/sqlite-bun.d.ts.map +1 -0
  433. package/dist/snapshot-artifacts/sqlite-bun.js +128 -0
  434. package/dist/snapshot-artifacts/sqlite-bun.js.map +1 -0
  435. package/dist/snapshot-artifacts.d.ts +206 -0
  436. package/dist/snapshot-artifacts.d.ts.map +1 -0
  437. package/dist/snapshot-artifacts.js +545 -0
  438. package/dist/snapshot-artifacts.js.map +1 -0
  439. package/dist/snapshot-chunks/db-metadata.d.ts +18 -0
  440. package/dist/snapshot-chunks/db-metadata.d.ts.map +1 -1
  441. package/dist/snapshot-chunks/db-metadata.js +91 -63
  442. package/dist/snapshot-chunks/db-metadata.js.map +1 -1
  443. package/dist/snapshot-chunks/index.js +2 -2
  444. package/dist/snapshot-chunks/types.d.ts +2 -0
  445. package/dist/snapshot-chunks/types.d.ts.map +1 -1
  446. package/dist/snapshot-chunks.d.ts +33 -3
  447. package/dist/snapshot-chunks.d.ts.map +1 -1
  448. package/dist/snapshot-chunks.js +136 -55
  449. package/dist/snapshot-chunks.js.map +1 -1
  450. package/dist/sqlite/index.d.ts +53 -0
  451. package/dist/sqlite/index.d.ts.map +1 -0
  452. package/dist/sqlite/index.js +795 -0
  453. package/dist/sqlite/index.js.map +1 -0
  454. package/dist/sqlite3.d.ts +22 -0
  455. package/dist/sqlite3.d.ts.map +1 -0
  456. package/dist/sqlite3.js +99 -0
  457. package/dist/sqlite3.js.map +1 -0
  458. package/dist/stats.d.ts +8 -0
  459. package/dist/stats.d.ts.map +1 -1
  460. package/dist/stats.js +45 -13
  461. package/dist/stats.js.map +1 -1
  462. package/dist/subscriptions/cache.d.ts +3 -0
  463. package/dist/subscriptions/cache.d.ts.map +1 -1
  464. package/dist/subscriptions/cache.js +44 -0
  465. package/dist/subscriptions/cache.js.map +1 -1
  466. package/dist/subscriptions/index.js +2 -2
  467. package/dist/subscriptions/resolve.d.ts +3 -1
  468. package/dist/subscriptions/resolve.d.ts.map +1 -1
  469. package/dist/subscriptions/resolve.js +91 -52
  470. package/dist/subscriptions/resolve.js.map +1 -1
  471. package/dist/sync.d.ts +3 -0
  472. package/dist/sync.d.ts.map +1 -1
  473. package/dist/sync.js +9 -5
  474. package/dist/sync.js.map +1 -1
  475. package/package.json +297 -8
  476. package/src/auth-leases.ts +649 -0
  477. package/src/better-sqlite3.ts +35 -0
  478. package/src/blobs/access.ts +244 -0
  479. package/src/blobs/adapters/database.ts +125 -43
  480. package/src/blobs/index.ts +1 -0
  481. package/src/blobs/manager.ts +366 -65
  482. package/src/blobs/migrate.ts +16 -8
  483. package/src/blobs/types.ts +4 -0
  484. package/src/bun-sqlite-ambient.d.ts +19 -0
  485. package/src/bun-sqlite.ts +27 -0
  486. package/src/clients.ts +1 -0
  487. package/src/cloudflare/durable-object.ts +289 -0
  488. package/src/cloudflare/index.ts +22 -0
  489. package/src/cloudflare/r2.ts +526 -0
  490. package/src/cloudflare/scope-cache.ts +341 -0
  491. package/src/cloudflare/sentry.ts +230 -0
  492. package/src/cloudflare/worker.ts +77 -0
  493. package/src/commit-integrity.ts +371 -0
  494. package/src/crdt-yjs/index.ts +931 -0
  495. package/src/d1.ts +16 -0
  496. package/src/dialect/base.ts +71 -5
  497. package/src/dialect/helpers.ts +31 -0
  498. package/src/dialect/types.ts +47 -0
  499. package/src/encrypted-crdt.ts +786 -0
  500. package/src/errors.ts +22 -0
  501. package/src/filesystem/index.ts +262 -0
  502. package/src/handlers/collection.ts +78 -78
  503. package/src/handlers/create-handler.ts +540 -147
  504. package/src/handlers/types.ts +116 -0
  505. package/src/helpers/index.ts +2 -0
  506. package/src/helpers/scope-authorization.ts +27 -0
  507. package/src/helpers/scope-commit-index.ts +52 -0
  508. package/src/hono/api-key-auth.ts +177 -0
  509. package/src/hono/audit-redaction.ts +135 -0
  510. package/src/hono/blobs.ts +851 -0
  511. package/src/hono/console/gateway.ts +3046 -0
  512. package/src/hono/console/live-auth.ts +46 -0
  513. package/src/hono/console/route-descriptor.ts +22 -0
  514. package/src/hono/console/routes/api-keys.ts +721 -0
  515. package/src/hono/console/routes/clients.ts +447 -0
  516. package/src/hono/console/routes/commits.ts +1137 -0
  517. package/src/hono/console/routes/context.ts +956 -0
  518. package/src/hono/console/routes/events.ts +669 -0
  519. package/src/hono/console/routes/maintenance.ts +461 -0
  520. package/src/hono/console/routes/shared.ts +816 -0
  521. package/src/hono/console/routes/stats.ts +392 -0
  522. package/src/hono/console/routes/storage.ts +159 -0
  523. package/src/hono/console/routes.ts +146 -0
  524. package/src/hono/console/schema-errors.ts +23 -0
  525. package/src/hono/console/schemas.ts +914 -0
  526. package/src/hono/console/types.ts +223 -0
  527. package/src/hono/console/ui.ts +100 -0
  528. package/src/hono/create-server.ts +230 -0
  529. package/src/hono/errors.ts +50 -0
  530. package/src/hono/index.ts +54 -0
  531. package/src/hono/openapi.ts +139 -0
  532. package/src/hono/proxy/connection-manager.ts +340 -0
  533. package/src/hono/proxy/index.ts +8 -0
  534. package/src/hono/proxy/routes.ts +272 -0
  535. package/src/hono/rate-limit.ts +319 -0
  536. package/src/hono/realtime-sync-packs.ts +354 -0
  537. package/src/hono/routes/audit.ts +499 -0
  538. package/src/hono/routes/auth-leases.ts +119 -0
  539. package/src/hono/routes/combined.ts +583 -0
  540. package/src/hono/routes/context.ts +1629 -0
  541. package/src/hono/routes/health.ts +26 -0
  542. package/src/hono/routes/realtime.ts +808 -0
  543. package/src/hono/routes/shared.ts +1626 -0
  544. package/src/hono/routes/snapshots.ts +345 -0
  545. package/src/hono/routes.ts +68 -0
  546. package/src/hono/validation.ts +81 -0
  547. package/src/hono/websocket-origin.ts +131 -0
  548. package/src/hono/ws.ts +1134 -0
  549. package/src/index.ts +6 -0
  550. package/src/libsql.ts +51 -0
  551. package/src/neon.ts +28 -0
  552. package/src/notify.ts +224 -44
  553. package/src/pglite.ts +68 -0
  554. package/src/plugins/index.ts +1 -0
  555. package/src/plugins/types.ts +144 -0
  556. package/src/postgres/index.ts +1291 -0
  557. package/src/proxy/collection.ts +5 -27
  558. package/src/proxy/handler.ts +2 -2
  559. package/src/proxy/index.ts +0 -2
  560. package/src/proxy/oplog.ts +41 -10
  561. package/src/prune.ts +137 -36
  562. package/src/pull.ts +1504 -591
  563. package/src/push.ts +881 -443
  564. package/src/realtime/index.ts +2 -0
  565. package/src/realtime/types.ts +35 -0
  566. package/src/relay/bun-types.d.ts +50 -0
  567. package/src/relay/client-role/forward-engine.ts +355 -0
  568. package/src/relay/client-role/index.ts +9 -0
  569. package/src/relay/client-role/pull-engine.ts +329 -0
  570. package/src/relay/client-role/sequence-mapper.ts +201 -0
  571. package/src/relay/evaluation/relay-paths.ts +699 -0
  572. package/src/relay/evaluation/rust-boundary.ts +464 -0
  573. package/src/relay/index.ts +50 -0
  574. package/src/relay/migrate.ts +113 -0
  575. package/src/relay/mode-manager.ts +142 -0
  576. package/src/relay/realtime.ts +207 -0
  577. package/src/relay/relay.ts +431 -0
  578. package/src/relay/schema.ts +171 -0
  579. package/src/relay/server-role/index.ts +338 -0
  580. package/src/relay/server-role/pull.ts +43 -0
  581. package/src/relay/server-role/push.ts +164 -0
  582. package/src/s3/index.ts +346 -0
  583. package/src/schema.ts +141 -1
  584. package/src/service-worker/index.ts +773 -0
  585. package/src/snapshot-artifacts/sqlite-bun.ts +168 -0
  586. package/src/snapshot-artifacts.ts +896 -0
  587. package/src/snapshot-chunks/db-metadata.ts +131 -72
  588. package/src/snapshot-chunks/types.ts +2 -0
  589. package/src/snapshot-chunks.ts +194 -70
  590. package/src/sqlite/index.ts +1064 -0
  591. package/src/sqlite3.ts +137 -0
  592. package/src/stats.ts +76 -13
  593. package/src/subscriptions/cache.ts +58 -0
  594. package/src/subscriptions/resolve.ts +99 -58
  595. package/src/sync.ts +16 -6
  596. package/src/blobs/adapters/database.test.ts +0 -67
  597. package/src/notify.test.ts +0 -520
  598. package/src/proxy/handler.test.ts +0 -126
  599. package/src/proxy/mutation-detector.test.ts +0 -71
  600. package/src/snapshot-chunks/db-metadata.test.ts +0 -172
  601. package/src/subscriptions/resolve.test.ts +0 -180
@@ -1,67 +0,0 @@
1
- import { describe, expect, test } from 'bun:test';
2
- import { createHmacTokenSigner } from './database';
3
-
4
- describe('createHmacTokenSigner', () => {
5
- test('verifies valid signed tokens', async () => {
6
- const signer = createHmacTokenSigner('test-secret');
7
- const payload = {
8
- hash: 'sha256:abc',
9
- action: 'upload' as const,
10
- expiresAt: Date.now() + 60_000,
11
- };
12
-
13
- const token = await signer.sign(payload, 60);
14
- const decoded = await signer.verify(token);
15
-
16
- expect(decoded).toEqual(payload);
17
- });
18
-
19
- test('rejects tampered signatures', async () => {
20
- const signer = createHmacTokenSigner('test-secret');
21
- const payload = {
22
- hash: 'sha256:def',
23
- action: 'download' as const,
24
- expiresAt: Date.now() + 60_000,
25
- };
26
-
27
- const token = await signer.sign(payload, 60);
28
- const [data, sig] = token.split('.');
29
- if (!data || !sig) {
30
- throw new Error('Expected signed token with payload and signature');
31
- }
32
- const replacement = sig.endsWith('0') ? '1' : '0';
33
- const tamperedSig = `${sig.slice(0, -1)}${replacement}`;
34
- const tamperedToken = `${data}.${tamperedSig}`;
35
-
36
- expect(await signer.verify(tamperedToken)).toBeNull();
37
- });
38
-
39
- test('rejects malformed hex signatures', async () => {
40
- const signer = createHmacTokenSigner('test-secret');
41
- const payload = {
42
- hash: 'sha256:ghi',
43
- action: 'upload' as const,
44
- expiresAt: Date.now() + 60_000,
45
- };
46
-
47
- const token = await signer.sign(payload, 60);
48
- const [data] = token.split('.');
49
- if (!data) {
50
- throw new Error('Expected signed token payload segment');
51
- }
52
-
53
- expect(await signer.verify(`${data}.not-hex-signature`)).toBeNull();
54
- });
55
-
56
- test('rejects expired tokens', async () => {
57
- const signer = createHmacTokenSigner('test-secret');
58
- const payload = {
59
- hash: 'sha256:jkl',
60
- action: 'upload' as const,
61
- expiresAt: Date.now() - 1,
62
- };
63
-
64
- const token = await signer.sign(payload, 60);
65
- expect(await signer.verify(token)).toBeNull();
66
- });
67
- });
@@ -1,520 +0,0 @@
1
- import { afterEach, beforeEach, describe, expect, it } from 'bun:test';
2
- import { createDatabase } from '@syncular/core';
3
- import { createBunSqliteDialect } from '../../dialect-bun-sqlite/src';
4
- import { createSqliteServerDialect } from '../../server-dialect-sqlite/src';
5
- import { createServerHandler, createServerHandlerCollection } from './handlers';
6
- import { ensureSyncSchema } from './migrate';
7
- import { EXTERNAL_CLIENT_ID, notifyExternalDataChange } from './notify';
8
- import { pull } from './pull';
9
- import type { SyncCoreDb } from './schema';
10
-
11
- interface TasksTable {
12
- id: string;
13
- user_id: string;
14
- title: string;
15
- server_version: number;
16
- }
17
-
18
- interface CodesTable {
19
- id: string;
20
- catalog_id: string;
21
- code: string;
22
- label: string;
23
- server_version: number;
24
- }
25
-
26
- interface TestDb extends SyncCoreDb {
27
- tasks: TasksTable;
28
- codes: CodesTable;
29
- }
30
-
31
- interface ClientDb {
32
- tasks: TasksTable;
33
- codes: CodesTable;
34
- }
35
-
36
- const dialect = createSqliteServerDialect();
37
-
38
- async function setupDb() {
39
- const db = createDatabase<TestDb>({
40
- dialect: createBunSqliteDialect({ path: ':memory:' }),
41
- family: 'sqlite',
42
- });
43
- await ensureSyncSchema(db, dialect);
44
-
45
- await db.schema
46
- .createTable('tasks')
47
- .addColumn('id', 'text', (col) => col.primaryKey())
48
- .addColumn('user_id', 'text', (col) => col.notNull())
49
- .addColumn('title', 'text', (col) => col.notNull())
50
- .addColumn('server_version', 'integer', (col) => col.notNull().defaultTo(0))
51
- .execute();
52
-
53
- await db.schema
54
- .createTable('codes')
55
- .addColumn('id', 'text', (col) => col.primaryKey())
56
- .addColumn('catalog_id', 'text', (col) => col.notNull())
57
- .addColumn('code', 'text', (col) => col.notNull())
58
- .addColumn('label', 'text', (col) => col.notNull())
59
- .addColumn('server_version', 'integer', (col) => col.notNull().defaultTo(0))
60
- .execute();
61
-
62
- return db;
63
- }
64
-
65
- describe('notifyExternalDataChange', () => {
66
- let db: ReturnType<typeof createBunSqliteDialect<TestDb>>;
67
-
68
- beforeEach(async () => {
69
- db = await setupDb();
70
- });
71
-
72
- afterEach(async () => {
73
- await db.destroy();
74
- });
75
-
76
- it('creates a synthetic commit with __external__ client_id', async () => {
77
- const result = await notifyExternalDataChange({
78
- db,
79
- dialect,
80
- tables: ['codes'],
81
- });
82
-
83
- expect(result.commitSeq).toBeGreaterThan(0);
84
- expect(result.tables).toEqual(['codes']);
85
-
86
- const commit = await db
87
- .selectFrom('sync_commits')
88
- .selectAll()
89
- .where('commit_seq', '=', result.commitSeq)
90
- .executeTakeFirstOrThrow();
91
-
92
- expect(commit.client_id).toBe(EXTERNAL_CLIENT_ID);
93
- expect(commit.actor_id).toBe(EXTERNAL_CLIENT_ID);
94
- expect(commit.change_count).toBe(0);
95
-
96
- const affectedTables = dialect.dbToArray(commit.affected_tables);
97
- expect(affectedTables).toEqual(['codes']);
98
- });
99
-
100
- it('inserts sync_table_commits entries for each table', async () => {
101
- const result = await notifyExternalDataChange({
102
- db,
103
- dialect,
104
- tables: ['codes', 'tasks'],
105
- });
106
-
107
- const tableCommits = await db
108
- .selectFrom('sync_table_commits')
109
- .selectAll()
110
- .where('commit_seq', '=', result.commitSeq)
111
- .execute();
112
-
113
- const tables = tableCommits.map((r) => r.table).sort();
114
- expect(tables).toEqual(['codes', 'tasks']);
115
- });
116
-
117
- it('deletes cached snapshot chunks for affected tables', async () => {
118
- // Insert fake snapshot chunks
119
- await db
120
- .insertInto('sync_snapshot_chunks')
121
- .values({
122
- chunk_id: 'chunk-1',
123
- partition_id: 'default',
124
- scope_key: 'test-key',
125
- scope: 'codes',
126
- as_of_commit_seq: 1,
127
- row_cursor: '',
128
- row_limit: 1000,
129
- encoding: 'json-row-frame-v1',
130
- compression: 'gzip',
131
- sha256: 'abc',
132
- byte_length: 100,
133
- blob_hash: '',
134
- body: new Uint8Array([1, 2, 3]),
135
- expires_at: new Date(Date.now() + 86400000).toISOString(),
136
- })
137
- .execute();
138
-
139
- await db
140
- .insertInto('sync_snapshot_chunks')
141
- .values({
142
- chunk_id: 'chunk-2',
143
- partition_id: 'default',
144
- scope_key: 'test-key',
145
- scope: 'tasks',
146
- as_of_commit_seq: 1,
147
- row_cursor: '',
148
- row_limit: 1000,
149
- encoding: 'json-row-frame-v1',
150
- compression: 'gzip',
151
- sha256: 'def',
152
- byte_length: 200,
153
- blob_hash: '',
154
- body: new Uint8Array([4, 5, 6]),
155
- expires_at: new Date(Date.now() + 86400000).toISOString(),
156
- })
157
- .execute();
158
-
159
- const result = await notifyExternalDataChange({
160
- db,
161
- dialect,
162
- tables: ['codes'],
163
- });
164
-
165
- expect(result.deletedChunks).toBe(1);
166
-
167
- // 'codes' chunk should be deleted, 'tasks' chunk should remain
168
- const remaining = await db
169
- .selectFrom('sync_snapshot_chunks')
170
- .selectAll()
171
- .execute();
172
- expect(remaining.length).toBe(1);
173
- expect(remaining[0]!.scope).toBe('tasks');
174
- });
175
-
176
- it('throws on empty tables array', async () => {
177
- await expect(
178
- notifyExternalDataChange({ db, dialect, tables: [] })
179
- ).rejects.toThrow('tables must not be empty');
180
- });
181
-
182
- it('uses custom partitionId and actorId', async () => {
183
- const result = await notifyExternalDataChange({
184
- db,
185
- dialect,
186
- tables: ['codes'],
187
- partitionId: 'tenant-42',
188
- actorId: 'pipeline-bot',
189
- });
190
-
191
- const commit = await db
192
- .selectFrom('sync_commits')
193
- .selectAll()
194
- .where('commit_seq', '=', result.commitSeq)
195
- .executeTakeFirstOrThrow();
196
-
197
- expect(commit.partition_id).toBe('tenant-42');
198
- expect(commit.actor_id).toBe('pipeline-bot');
199
- expect(commit.client_id).toBe(EXTERNAL_CLIENT_ID);
200
- });
201
- });
202
-
203
- describe('pull re-bootstrap after external data change', () => {
204
- let db: ReturnType<typeof createBunSqliteDialect<TestDb>>;
205
-
206
- beforeEach(async () => {
207
- db = await setupDb();
208
- });
209
-
210
- afterEach(async () => {
211
- await db.destroy();
212
- });
213
-
214
- it('forces re-bootstrap for affected tables after notifyExternalDataChange', async () => {
215
- // Seed some data
216
- await db
217
- .insertInto('codes')
218
- .values({
219
- id: 'c1',
220
- catalog_id: 'icd',
221
- code: 'A00',
222
- label: 'Cholera',
223
- server_version: 1,
224
- })
225
- .execute();
226
-
227
- const codesHandler = createServerHandler<TestDb, ClientDb, 'codes'>({
228
- table: 'codes',
229
- scopes: ['catalog:{catalog_id}'],
230
- resolveScopes: async () => ({ catalog_id: '*' }),
231
- });
232
-
233
- const handlers = createServerHandlerCollection<TestDb>([codesHandler]);
234
-
235
- // 1. Initial bootstrap pull
236
- const firstPull = await pull({
237
- db,
238
- dialect,
239
- handlers,
240
- auth: { actorId: 'u1' },
241
- request: {
242
- clientId: 'client-1',
243
- limitCommits: 10,
244
- limitSnapshotRows: 100,
245
- maxSnapshotPages: 10,
246
- subscriptions: [
247
- {
248
- id: 'sub-codes',
249
- table: 'codes',
250
- scopes: { catalog_id: 'icd' },
251
- cursor: -1,
252
- },
253
- ],
254
- },
255
- });
256
-
257
- const firstSub = firstPull.response.subscriptions[0]!;
258
- expect(firstSub.bootstrap).toBe(true);
259
- const cursorAfterBootstrap = firstSub.nextCursor;
260
- expect(cursorAfterBootstrap).toBeGreaterThanOrEqual(0);
261
-
262
- // 2. Incremental pull (should get no changes)
263
- const incrementalPull = await pull({
264
- db,
265
- dialect,
266
- handlers,
267
- auth: { actorId: 'u1' },
268
- request: {
269
- clientId: 'client-1',
270
- limitCommits: 10,
271
- limitSnapshotRows: 100,
272
- maxSnapshotPages: 10,
273
- subscriptions: [
274
- {
275
- id: 'sub-codes',
276
- table: 'codes',
277
- scopes: { catalog_id: 'icd' },
278
- cursor: cursorAfterBootstrap,
279
- },
280
- ],
281
- },
282
- });
283
-
284
- const incSub = incrementalPull.response.subscriptions[0]!;
285
- expect(incSub.bootstrap).toBe(false);
286
- expect(incSub.commits?.length ?? 0).toBe(0);
287
-
288
- // 3. Notify external data change for 'codes'
289
- const notifyResult = await notifyExternalDataChange({
290
- db,
291
- dialect,
292
- tables: ['codes'],
293
- });
294
- expect(notifyResult.commitSeq).toBeGreaterThan(cursorAfterBootstrap);
295
-
296
- // 4. Pull again with same cursor - should trigger re-bootstrap
297
- const rebootstrapPull = await pull({
298
- db,
299
- dialect,
300
- handlers,
301
- auth: { actorId: 'u1' },
302
- request: {
303
- clientId: 'client-1',
304
- limitCommits: 10,
305
- limitSnapshotRows: 100,
306
- maxSnapshotPages: 10,
307
- subscriptions: [
308
- {
309
- id: 'sub-codes',
310
- table: 'codes',
311
- scopes: { catalog_id: 'icd' },
312
- cursor: cursorAfterBootstrap,
313
- },
314
- ],
315
- },
316
- });
317
-
318
- const rebootSub = rebootstrapPull.response.subscriptions[0]!;
319
- expect(rebootSub.bootstrap).toBe(true);
320
- expect(rebootSub.snapshots?.length).toBeGreaterThan(0);
321
- });
322
-
323
- it('does not force re-bootstrap for unaffected tables', async () => {
324
- await db
325
- .insertInto('tasks')
326
- .values({
327
- id: 't1',
328
- user_id: 'u1',
329
- title: 'My Task',
330
- server_version: 1,
331
- })
332
- .execute();
333
-
334
- const tasksHandler = createServerHandler<TestDb, ClientDb, 'tasks'>({
335
- table: 'tasks',
336
- scopes: ['user:{user_id}'],
337
- resolveScopes: async (ctx) => ({ user_id: [ctx.actorId] }),
338
- });
339
-
340
- const codesHandler = createServerHandler<TestDb, ClientDb, 'codes'>({
341
- table: 'codes',
342
- scopes: ['catalog:{catalog_id}'],
343
- resolveScopes: async () => ({ catalog_id: '*' }),
344
- });
345
-
346
- const handlers = createServerHandlerCollection<TestDb>([
347
- tasksHandler,
348
- codesHandler,
349
- ]);
350
-
351
- // 1. Bootstrap pull for tasks
352
- const firstPull = await pull({
353
- db,
354
- dialect,
355
- handlers,
356
- auth: { actorId: 'u1' },
357
- request: {
358
- clientId: 'client-1',
359
- limitCommits: 10,
360
- limitSnapshotRows: 100,
361
- maxSnapshotPages: 10,
362
- subscriptions: [
363
- {
364
- id: 'sub-tasks',
365
- table: 'tasks',
366
- scopes: { user_id: 'u1' },
367
- cursor: -1,
368
- },
369
- ],
370
- },
371
- });
372
-
373
- const cursorAfterBootstrap =
374
- firstPull.response.subscriptions[0]!.nextCursor;
375
-
376
- // 2. Notify external data change for 'codes' only (not tasks)
377
- await notifyExternalDataChange({
378
- db,
379
- dialect,
380
- tables: ['codes'],
381
- });
382
-
383
- // 3. Pull tasks again - should NOT trigger re-bootstrap
384
- const pullAfterNotify = await pull({
385
- db,
386
- dialect,
387
- handlers,
388
- auth: { actorId: 'u1' },
389
- request: {
390
- clientId: 'client-1',
391
- limitCommits: 10,
392
- limitSnapshotRows: 100,
393
- maxSnapshotPages: 10,
394
- subscriptions: [
395
- {
396
- id: 'sub-tasks',
397
- table: 'tasks',
398
- scopes: { user_id: 'u1' },
399
- cursor: cursorAfterBootstrap,
400
- },
401
- ],
402
- },
403
- });
404
-
405
- const tasksSub = pullAfterNotify.response.subscriptions[0]!;
406
- expect(tasksSub.bootstrap).toBe(false);
407
- });
408
-
409
- it('forces re-bootstrap only for the affected table in a multi-subscription pull', async () => {
410
- await db
411
- .insertInto('tasks')
412
- .values({
413
- id: 't1',
414
- user_id: 'u1',
415
- title: 'My Task',
416
- server_version: 1,
417
- })
418
- .execute();
419
-
420
- await db
421
- .insertInto('codes')
422
- .values({
423
- id: 'c1',
424
- catalog_id: 'icd',
425
- code: 'A00',
426
- label: 'Cholera',
427
- server_version: 1,
428
- })
429
- .execute();
430
-
431
- const tasksHandler = createServerHandler<TestDb, ClientDb, 'tasks'>({
432
- table: 'tasks',
433
- scopes: ['user:{user_id}'],
434
- resolveScopes: async (ctx) => ({ user_id: [ctx.actorId] }),
435
- });
436
-
437
- const codesHandler = createServerHandler<TestDb, ClientDb, 'codes'>({
438
- table: 'codes',
439
- scopes: ['catalog:{catalog_id}'],
440
- resolveScopes: async () => ({ catalog_id: '*' }),
441
- });
442
-
443
- const handlers = createServerHandlerCollection<TestDb>([
444
- tasksHandler,
445
- codesHandler,
446
- ]);
447
-
448
- // 1. Bootstrap both subscriptions
449
- const firstPull = await pull({
450
- db,
451
- dialect,
452
- handlers,
453
- auth: { actorId: 'u1' },
454
- request: {
455
- clientId: 'client-1',
456
- limitCommits: 10,
457
- limitSnapshotRows: 100,
458
- maxSnapshotPages: 10,
459
- subscriptions: [
460
- {
461
- id: 'sub-tasks',
462
- table: 'tasks',
463
- scopes: { user_id: 'u1' },
464
- cursor: -1,
465
- },
466
- {
467
- id: 'sub-codes',
468
- table: 'codes',
469
- scopes: { catalog_id: 'icd' },
470
- cursor: -1,
471
- },
472
- ],
473
- },
474
- });
475
-
476
- const tasksCursor = firstPull.response.subscriptions[0]!.nextCursor;
477
- const codesCursor = firstPull.response.subscriptions[1]!.nextCursor;
478
-
479
- // 2. Notify external data change for 'codes' only
480
- await notifyExternalDataChange({ db, dialect, tables: ['codes'] });
481
-
482
- // 3. Pull both subscriptions
483
- const pullAfter = await pull({
484
- db,
485
- dialect,
486
- handlers,
487
- auth: { actorId: 'u1' },
488
- request: {
489
- clientId: 'client-1',
490
- limitCommits: 10,
491
- limitSnapshotRows: 100,
492
- maxSnapshotPages: 10,
493
- subscriptions: [
494
- {
495
- id: 'sub-tasks',
496
- table: 'tasks',
497
- scopes: { user_id: 'u1' },
498
- cursor: tasksCursor,
499
- },
500
- {
501
- id: 'sub-codes',
502
- table: 'codes',
503
- scopes: { catalog_id: 'icd' },
504
- cursor: codesCursor,
505
- },
506
- ],
507
- },
508
- });
509
-
510
- const tasksSub = pullAfter.response.subscriptions.find(
511
- (s) => s.id === 'sub-tasks'
512
- )!;
513
- const codesSub = pullAfter.response.subscriptions.find(
514
- (s) => s.id === 'sub-codes'
515
- )!;
516
-
517
- expect(tasksSub.bootstrap).toBe(false);
518
- expect(codesSub.bootstrap).toBe(true);
519
- });
520
- });
@@ -1,126 +0,0 @@
1
- import { afterEach, beforeEach, describe, expect, it } from 'bun:test';
2
- import { createDatabase } from '@syncular/core';
3
- import type { Kysely } from 'kysely';
4
- import { createBunSqliteDialect } from '../../../dialect-bun-sqlite/src';
5
- import { createSqliteServerDialect } from '../../../server-dialect-sqlite/src';
6
- import { ensureSyncSchema } from '../migrate';
7
- import type { SyncCoreDb } from '../schema';
8
- import { createProxyHandlerCollection } from './collection';
9
- import { executeProxyQuery } from './handler';
10
-
11
- interface TasksTable {
12
- id: string;
13
- user_id: string;
14
- title: string;
15
- server_version: number;
16
- }
17
-
18
- interface ProxyTestDb extends SyncCoreDb {
19
- tasks: TasksTable;
20
- }
21
-
22
- describe('executeProxyQuery', () => {
23
- let db: Kysely<ProxyTestDb>;
24
- const dialect = createSqliteServerDialect();
25
- const handlers = createProxyHandlerCollection([
26
- {
27
- table: 'tasks',
28
- computeScopes: (row) => ({
29
- user_id: String(row.user_id),
30
- }),
31
- },
32
- ]);
33
-
34
- beforeEach(async () => {
35
- db = createDatabase<ProxyTestDb>({
36
- dialect: createBunSqliteDialect({ path: ':memory:' }),
37
- family: 'sqlite',
38
- });
39
- await ensureSyncSchema(db, dialect);
40
-
41
- await db.schema
42
- .createTable('tasks')
43
- .addColumn('id', 'text', (col) => col.primaryKey())
44
- .addColumn('user_id', 'text', (col) => col.notNull())
45
- .addColumn('title', 'text', (col) => col.notNull())
46
- .addColumn('server_version', 'integer', (col) => col.notNull())
47
- .execute();
48
-
49
- await db
50
- .insertInto('tasks')
51
- .values({
52
- id: 't1',
53
- user_id: 'u1',
54
- title: 'old title',
55
- server_version: 1,
56
- })
57
- .execute();
58
- });
59
-
60
- afterEach(async () => {
61
- await db.destroy();
62
- });
63
-
64
- it('tracks comment-prefixed mutations in the sync oplog', async () => {
65
- const result = await executeProxyQuery({
66
- db,
67
- dialect,
68
- handlers,
69
- ctx: { actorId: 'actor-1', clientId: 'proxy-client-1' },
70
- sqlQuery:
71
- '/* admin */ UPDATE tasks SET title = $1, server_version = server_version + 1 WHERE id = $2',
72
- parameters: ['new title', 't1'],
73
- });
74
-
75
- expect(result.rowCount).toBe(1);
76
- expect(result.commitSeq).toBeGreaterThan(0);
77
-
78
- const commitCount = await db
79
- .selectFrom('sync_commits')
80
- .select(({ fn }) => fn.countAll().as('count'))
81
- .executeTakeFirstOrThrow();
82
- expect(Number(commitCount.count)).toBe(1);
83
-
84
- const changeCount = await db
85
- .selectFrom('sync_changes')
86
- .select(({ fn }) => fn.countAll().as('count'))
87
- .executeTakeFirstOrThrow();
88
- expect(Number(changeCount.count)).toBe(1);
89
-
90
- const updated = await db
91
- .selectFrom('tasks')
92
- .select(['title', 'server_version'])
93
- .where('id', '=', 't1')
94
- .executeTakeFirstOrThrow();
95
- expect(updated.title).toBe('new title');
96
- expect(updated.server_version).toBe(2);
97
- });
98
-
99
- it('rejects non-wildcard RETURNING on synced-table mutations', async () => {
100
- await expect(
101
- executeProxyQuery({
102
- db,
103
- dialect,
104
- handlers,
105
- ctx: { actorId: 'actor-1', clientId: 'proxy-client-1' },
106
- sqlQuery: 'UPDATE tasks SET title = $1 WHERE id = $2 RETURNING id',
107
- parameters: ['blocked title', 't1'],
108
- })
109
- ).rejects.toThrow(
110
- 'Proxy mutation on synced table "tasks" must use RETURNING * (or omit RETURNING)'
111
- );
112
-
113
- const commitCount = await db
114
- .selectFrom('sync_commits')
115
- .select(({ fn }) => fn.countAll().as('count'))
116
- .executeTakeFirstOrThrow();
117
- expect(Number(commitCount.count)).toBe(0);
118
-
119
- const row = await db
120
- .selectFrom('tasks')
121
- .select(['title'])
122
- .where('id', '=', 't1')
123
- .executeTakeFirstOrThrow();
124
- expect(row.title).toBe('old title');
125
- });
126
- });