@syncular/server 0.0.6-95 → 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,17 +1,12 @@
1
1
  /**
2
2
  * @syncular/server - Declarative server handler helper
3
3
  */
4
- import { applyCodecsFromDbRow, applyCodecsToDbRow, extractScopeVars, normalizeScopes, toTableColumnCodecs, } from '@syncular/core';
4
+ import { applyCodecsFromDbRow, applyCodecsToDbRow, createSingleVariableScopeMetadata, createTableColumnCodecsResolver, toTableColumnCodecs, } from '@syncular/core';
5
5
  import { sql } from 'kysely';
6
- function classifyConstraintViolationCode(message) {
7
- const normalized = message.toLowerCase();
8
- if (normalized.includes('not null'))
9
- return 'NOT_NULL_CONSTRAINT';
10
- if (normalized.includes('unique'))
11
- return 'UNIQUE_CONSTRAINT';
12
- if (normalized.includes('foreign key'))
13
- return 'FOREIGN_KEY_CONSTRAINT';
14
- return 'CONSTRAINT_VIOLATION';
6
+ import { coerceNumber } from '../dialect/helpers';
7
+ import { rowScopesAllowed } from '../helpers/scope-authorization';
8
+ function classifyConstraintViolationCode(_message) {
9
+ return 'sync.constraint_violation';
15
10
  }
16
11
  function isConstraintViolationError(message) {
17
12
  const normalized = message.toLowerCase();
@@ -25,6 +20,28 @@ function isMissingColumnReferenceError(message) {
25
20
  return (normalized.includes('no such column') ||
26
21
  (normalized.includes('column') && normalized.includes('does not exist')));
27
22
  }
23
+ function readSafeVersionColumn(row, versionColumn, defaultValue) {
24
+ const value = row[versionColumn];
25
+ if (value === null || value === undefined)
26
+ return defaultValue;
27
+ const version = coerceNumber(value);
28
+ if (version === null || !Number.isSafeInteger(version)) {
29
+ throw new Error(`Version column "${versionColumn}" must be a safe integer`);
30
+ }
31
+ return version;
32
+ }
33
+ function normalizeOutboundVersionColumn(row, versionColumn, version) {
34
+ if (row === null || typeof row !== 'object' || Array.isArray(row)) {
35
+ return row;
36
+ }
37
+ if (!Object.hasOwn(row, versionColumn)) {
38
+ return row;
39
+ }
40
+ return {
41
+ ...row,
42
+ [versionColumn]: version,
43
+ };
44
+ }
28
45
  /**
29
46
  * Create a declarative server table handler with sensible defaults.
30
47
  *
@@ -53,40 +70,17 @@ function isMissingColumnReferenceError(message) {
53
70
  * ```
54
71
  */
55
72
  export function createServerHandler(options) {
56
- const { table, scopes: scopeDefs, primaryKey = 'id', versionColumn = 'server_version', dependsOn, snapshotChunkTtlMs, resolveScopes, transformInbound, transformOutbound, codecs, codecDialect = 'sqlite', authorize, extractScopes: customExtractScopes, } = options;
57
- const codecCache = new Map();
58
- const resolveTableCodecs = (row) => {
59
- if (!codecs)
60
- return {};
61
- const columns = Object.keys(row);
62
- if (columns.length === 0)
63
- return {};
64
- const cacheKey = columns.slice().sort().join('\u0000');
65
- const cached = codecCache.get(cacheKey);
66
- if (cached)
67
- return cached;
68
- const resolved = toTableColumnCodecs(table, codecs, columns, {
69
- dialect: codecDialect,
70
- });
71
- codecCache.set(cacheKey, resolved);
72
- return resolved;
73
- };
74
- // Normalize scopes to pattern map and extract patterns/columns
75
- const scopeColumnMap = normalizeScopes(scopeDefs);
76
- const scopePatterns = Object.keys(scopeColumnMap);
77
- const scopeColumns = {};
78
- for (const [pattern, columnName] of Object.entries(scopeColumnMap)) {
79
- const vars = extractScopeVars(pattern);
80
- if (vars.length !== 1) {
81
- throw new Error(`Scope pattern "${pattern}" must contain exactly one placeholder (got ${vars.length}).`);
82
- }
83
- const varName = vars[0];
84
- const existing = scopeColumns[varName];
85
- if (existing && existing !== columnName) {
86
- throw new Error(`Scope variable "${varName}" is mapped to multiple columns: "${existing}" and "${columnName}".`);
87
- }
88
- scopeColumns[varName] = columnName;
89
- }
73
+ const { table, scopes: scopeDefs, primaryKey = 'id', versionColumn = 'server_version', dependsOn, snapshotChunkTtlMs, snapshotBinaryColumns, snapshotBinaryColumnsForVersion, snapshotBinaryEncoder, snapshotBinaryEncoderForVersion, resolveScopes, transformInbound, transformOutbound, codecs, codecDialect = 'sqlite', authorize, extractScopes: customExtractScopes, } = options;
74
+ const resolveRowCodecs = createTableColumnCodecsResolver(codecs, {
75
+ dialect: codecDialect,
76
+ });
77
+ const primaryKeyColumn = primaryKey;
78
+ const qualifiedVersionRef = `${table}.${versionColumn}`;
79
+ const resolveTableCodecs = (row) => resolveRowCodecs(table, row);
80
+ const usePassthroughInbound = !transformInbound && codecs == null;
81
+ const { scopePatterns, scopeColumnsByVariable: scopeColumns } = createSingleVariableScopeMetadata(scopeDefs);
82
+ const scopeColumnEntries = Object.entries(scopeColumns);
83
+ const requiredScopeKeys = Object.keys(scopeColumns);
90
84
  // Default extractScopes from scope columns
91
85
  const defaultExtractScopes = (row) => {
92
86
  const scopes = {};
@@ -106,12 +100,77 @@ export function createServerHandler(options) {
106
100
  const resolved = await resolveScopes(ctx);
107
101
  const normalized = {};
108
102
  for (const [scopeKey, scopeValue] of Object.entries(resolved)) {
109
- if (typeof scopeValue === 'string' || Array.isArray(scopeValue)) {
103
+ // null/undefined means "no access for this scope" and is skipped.
104
+ if (scopeValue === null || scopeValue === undefined)
105
+ continue;
106
+ if (typeof scopeValue === 'string') {
110
107
  normalized[scopeKey] = scopeValue;
108
+ continue;
109
+ }
110
+ if (Array.isArray(scopeValue)) {
111
+ const invalidIndex = scopeValue.findIndex((entry) => typeof entry !== 'string');
112
+ if (invalidIndex !== -1) {
113
+ throw new Error(`resolveScopes() for table "${table}" returned a non-string entry ` +
114
+ `(${typeof scopeValue[invalidIndex]}) at index ${invalidIndex} of scope "${scopeKey}". ` +
115
+ 'Scope values must be strings or string arrays.');
116
+ }
117
+ normalized[scopeKey] = scopeValue;
118
+ continue;
111
119
  }
120
+ throw new Error(`resolveScopes() for table "${table}" returned an invalid value ` +
121
+ `(${typeof scopeValue}) for scope "${scopeKey}". ` +
122
+ 'Scope values must be strings or string arrays.');
112
123
  }
113
124
  return normalized;
114
125
  };
126
+ const writeScopeCache = new WeakMap();
127
+ const resolveWriteScopes = (ctx) => {
128
+ const cached = writeScopeCache.get(ctx);
129
+ if (cached)
130
+ return cached;
131
+ const loaded = resolveScopesImpl(ctx);
132
+ writeScopeCache.set(ctx, loaded);
133
+ return loaded;
134
+ };
135
+ const authorizeRowScopes = async (ctx, row) => {
136
+ if (requiredScopeKeys.length === 0)
137
+ return true;
138
+ let allowedScopes;
139
+ try {
140
+ allowedScopes = await resolveWriteScopes(ctx);
141
+ }
142
+ catch (resolveErr) {
143
+ console.error(`[resolveScopes] Failed for table ${table} during write authorization:`, resolveErr);
144
+ return {
145
+ error: 'Forbidden',
146
+ code: 'sync.forbidden',
147
+ retriable: false,
148
+ };
149
+ }
150
+ const rowScopes = extractScopesImpl(row);
151
+ if (rowScopesAllowed({
152
+ rowScopes,
153
+ allowedScopes,
154
+ requiredScopeKeys,
155
+ })) {
156
+ return true;
157
+ }
158
+ return {
159
+ error: 'Forbidden',
160
+ code: 'sync.forbidden',
161
+ retriable: false,
162
+ };
163
+ };
164
+ const rejectionResult = (opIndex, rejection) => ({
165
+ result: {
166
+ opIndex,
167
+ status: 'error',
168
+ error: rejection.error,
169
+ code: rejection.code,
170
+ retriable: rejection.retriable ?? false,
171
+ },
172
+ emittedChanges: [],
173
+ });
115
174
  const applyOutboundTransform = (row) => {
116
175
  if (transformOutbound) {
117
176
  return transformOutbound(row);
@@ -121,6 +180,9 @@ export function createServerHandler(options) {
121
180
  return transformed;
122
181
  };
123
182
  const applyInboundTransform = (row, schemaVersion) => {
183
+ if (usePassthroughInbound) {
184
+ return row;
185
+ }
124
186
  if (transformInbound) {
125
187
  return transformInbound(row, {
126
188
  schemaVersion,
@@ -134,25 +196,21 @@ export function createServerHandler(options) {
134
196
  const trx = ctx.db;
135
197
  const { ref } = trx.dynamic;
136
198
  const scopeValues = ctx.scopeValues;
137
- const pageSize = Math.max(1, Math.min(10_000, ctx.limit));
138
- // Build dynamic WHERE conditions
139
- const whereConditions = [];
140
- for (const [varName, columnName] of Object.entries(scopeColumns)) {
199
+ const pageSize = Math.max(1, ctx.limit);
200
+ let q = trx.selectFrom(table);
201
+ q = q.selectAll();
202
+ for (const [varName, columnName] of scopeColumnEntries) {
141
203
  const values = scopeValues[varName];
142
204
  if (values === undefined)
143
205
  continue;
144
206
  const normalized = Array.isArray(values) ? values : [values];
145
207
  if (normalized.length === 0)
146
208
  continue;
147
- whereConditions.push({ column: columnName, values: normalized });
148
- }
149
- let q = trx.selectFrom(table).selectAll();
150
- for (const cond of whereConditions) {
151
- if (cond.values.length === 1) {
152
- q = q.where(ref(cond.column), '=', cond.values[0]);
209
+ if (normalized.length === 1) {
210
+ q = q.where(ref(columnName), '=', normalized[0]);
153
211
  }
154
212
  else {
155
- q = q.where(ref(cond.column), 'in', cond.values);
213
+ q = q.where(ref(columnName), 'in', normalized);
156
214
  }
157
215
  }
158
216
  if (ctx.cursor !== null) {
@@ -168,8 +226,24 @@ export function createServerHandler(options) {
168
226
  const nextCursor = hasMore
169
227
  ? lastRow?.[primaryKey]
170
228
  : null;
171
- // Transform outbound if provided
172
- const outputRows = pageRows.map((r) => applyOutboundTransform(r));
229
+ let outputRows;
230
+ if (transformOutbound) {
231
+ outputRows = pageRows.map((r) => applyOutboundTransform(r));
232
+ }
233
+ else {
234
+ const firstRow = pageRows[0];
235
+ const tableCodecs = firstRow
236
+ ? toTableColumnCodecs(table, codecs, Object.keys(firstRow), {
237
+ dialect: codecDialect,
238
+ })
239
+ : {};
240
+ if (Object.keys(tableCodecs).length === 0) {
241
+ outputRows = pageRows;
242
+ }
243
+ else {
244
+ outputRows = pageRows.map((r) => applyCodecsFromDbRow(r, tableCodecs, codecDialect));
245
+ }
246
+ }
173
247
  return {
174
248
  rows: outputRows,
175
249
  nextCursor: typeof nextCursor === 'string' && nextCursor.length > 0
@@ -186,8 +260,8 @@ export function createServerHandler(options) {
186
260
  result: {
187
261
  opIndex,
188
262
  status: 'error',
189
- error: `UNKNOWN_TABLE:${op.table}`,
190
- code: 'UNKNOWN_TABLE',
263
+ error: `Unknown table: ${op.table}`,
264
+ code: 'sync.unknown_table',
191
265
  retriable: false,
192
266
  },
193
267
  emittedChanges: [],
@@ -211,14 +285,23 @@ export function createServerHandler(options) {
211
285
  }
212
286
  // Handle delete
213
287
  if (op.op === 'delete') {
288
+ const existingRow = (await trx.selectFrom(table).selectAll()
289
+ .where(ref(primaryKey), '=', op.row_id)
290
+ .executeTakeFirst());
291
+ if (!existingRow) {
292
+ return { result: { opIndex, status: 'applied' }, emittedChanges: [] };
293
+ }
294
+ const scopeAuth = await authorizeRowScopes(ctx, existingRow);
295
+ if (scopeAuth !== true) {
296
+ return rejectionResult(opIndex, scopeAuth);
297
+ }
214
298
  const deleted = await trx.deleteFrom(table)
215
299
  .where(ref(primaryKey), '=', op.row_id)
216
300
  .returningAll()
217
301
  .executeTakeFirst();
218
302
  const deletedRow = deleted;
219
- if (!deletedRow) {
303
+ if (!deletedRow)
220
304
  return { result: { opIndex, status: 'applied' }, emittedChanges: [] };
221
- }
222
305
  // Extract scopes from existing row for the delete emission
223
306
  const scopes = extractScopesImpl(deletedRow);
224
307
  const emitted = {
@@ -240,6 +323,18 @@ export function createServerHandler(options) {
240
323
  ? rawPayload
241
324
  : {};
242
325
  const payload = applyInboundTransform(payloadRecord, ctx.schemaVersion);
326
+ const rowForInsertScopeCheck = {
327
+ ...payload,
328
+ [primaryKey]: op.row_id,
329
+ [versionColumn]: 1,
330
+ };
331
+ const existingRowBeforeWrite = (await trx.selectFrom(table).selectAll()
332
+ .where(ref(primaryKey), '=', op.row_id)
333
+ .executeTakeFirst());
334
+ const rowScopeAuth = await authorizeRowScopes(ctx, existingRowBeforeWrite ?? rowForInsertScopeCheck);
335
+ if (rowScopeAuth !== true) {
336
+ return rejectionResult(opIndex, rowScopeAuth);
337
+ }
243
338
  let updated;
244
339
  let constraintError = null;
245
340
  try {
@@ -260,78 +355,84 @@ export function createServerHandler(options) {
260
355
  .returningAll()
261
356
  .executeTakeFirst());
262
357
  if (!updated) {
263
- const conflictRow = await trx.selectFrom(table).selectAll()
358
+ let conflictRow = await trx.selectFrom(table).selectAll()
264
359
  .where(ref(primaryKey), '=', op.row_id)
265
360
  .executeTakeFirst();
266
- if (!conflictRow) {
361
+ if (!conflictRow && expectedVersion === 0) {
362
+ const insertValues = {
363
+ ...payload,
364
+ [primaryKey]: op.row_id,
365
+ [versionColumn]: 1,
366
+ };
367
+ try {
368
+ updated = (await trx.insertInto(table)
369
+ .values(insertValues)
370
+ .returningAll()
371
+ .executeTakeFirst());
372
+ }
373
+ catch (err) {
374
+ const message = err instanceof Error ? err.message : String(err);
375
+ if (!isConstraintViolationError(message)) {
376
+ throw err;
377
+ }
378
+ conflictRow = await trx.selectFrom(table).selectAll()
379
+ .where(ref(primaryKey), '=', op.row_id)
380
+ .executeTakeFirst();
381
+ }
382
+ }
383
+ if (!updated && !conflictRow) {
267
384
  return {
268
385
  result: {
269
386
  opIndex,
270
387
  status: 'error',
271
- error: 'ROW_NOT_FOUND_FOR_BASE_VERSION',
272
- code: 'ROW_MISSING',
388
+ error: 'Row not found for base version',
389
+ code: 'sync.row_missing',
273
390
  retriable: false,
274
391
  },
275
392
  emittedChanges: [],
276
393
  };
277
394
  }
278
- const existingVersion = conflictRow[versionColumn] ?? 0;
279
- return {
280
- result: {
281
- opIndex,
282
- status: 'conflict',
283
- message: `Version conflict: server=${existingVersion}, base=${expectedVersion}`,
284
- server_version: existingVersion,
285
- server_row: applyOutboundTransform(conflictRow),
286
- },
287
- emittedChanges: [],
288
- };
395
+ if (!updated && conflictRow) {
396
+ const conflictScopeAuth = await authorizeRowScopes(ctx, conflictRow);
397
+ if (conflictScopeAuth !== true) {
398
+ return rejectionResult(opIndex, conflictScopeAuth);
399
+ }
400
+ const existingVersion = readSafeVersionColumn(conflictRow, versionColumn, 0);
401
+ return {
402
+ result: {
403
+ opIndex,
404
+ status: 'conflict',
405
+ message: `Version conflict: server=${existingVersion}, base=${expectedVersion}`,
406
+ code: 'sync.version_conflict',
407
+ server_version: existingVersion,
408
+ server_row: normalizeOutboundVersionColumn(applyOutboundTransform(conflictRow), versionColumn, existingVersion),
409
+ },
410
+ emittedChanges: [],
411
+ };
412
+ }
289
413
  }
290
414
  }
291
415
  else {
292
416
  const updateSet = {
293
417
  ...payload,
294
- [versionColumn]: sql `${sql.ref(versionColumn)} + 1`,
418
+ [versionColumn]: sql `${sql.ref(qualifiedVersionRef)} + 1`,
295
419
  };
296
420
  delete updateSet[primaryKey];
297
421
  for (const col of Object.values(scopeColumns)) {
298
422
  delete updateSet[col];
299
423
  }
300
- updated = (await trx.updateTable(table)
301
- .set(updateSet)
302
- .where(ref(primaryKey), '=', op.row_id)
424
+ const insertValues = {
425
+ ...payload,
426
+ [primaryKey]: op.row_id,
427
+ [versionColumn]: 1,
428
+ };
429
+ updated = (await trx.insertInto(table)
430
+ .values(insertValues)
431
+ .onConflict((oc) => oc
432
+ .column(primaryKeyColumn)
433
+ .doUpdateSet(updateSet))
303
434
  .returningAll()
304
435
  .executeTakeFirst());
305
- if (!updated) {
306
- const insertValues = {
307
- ...payload,
308
- [primaryKey]: op.row_id,
309
- [versionColumn]: 1,
310
- };
311
- try {
312
- updated = (await trx.insertInto(table)
313
- .values(insertValues)
314
- .returningAll()
315
- .executeTakeFirst());
316
- }
317
- catch (err) {
318
- const message = err instanceof Error ? err.message : String(err);
319
- if (!isConstraintViolationError(message)) {
320
- throw err;
321
- }
322
- updated = (await trx.updateTable(table)
323
- .set(updateSet)
324
- .where(ref(primaryKey), '=', op.row_id)
325
- .returningAll()
326
- .executeTakeFirst());
327
- if (!updated) {
328
- constraintError = {
329
- message,
330
- code: classifyConstraintViolationCode(message),
331
- };
332
- }
333
- }
334
- }
335
436
  }
336
437
  }
337
438
  catch (err) {
@@ -345,8 +446,8 @@ export function createServerHandler(options) {
345
446
  result: {
346
447
  opIndex,
347
448
  status: 'error',
348
- error: 'ROW_NOT_FOUND_FOR_BASE_VERSION',
349
- code: 'ROW_MISSING',
449
+ error: 'Row not found for base version',
450
+ code: 'sync.row_missing',
350
451
  retriable: false,
351
452
  },
352
453
  emittedChanges: [],
@@ -377,11 +478,11 @@ export function createServerHandler(options) {
377
478
  throw new Error('Updated row is missing after applyOperation');
378
479
  }
379
480
  const updatedRow = updated;
380
- const rowVersion = updatedRow[versionColumn] ?? 1;
481
+ const rowVersion = readSafeVersionColumn(updatedRow, versionColumn, 1);
381
482
  // Extract scopes from updated row
382
483
  const scopes = extractScopesImpl(updatedRow);
383
484
  // Transform outbound for emitted change
384
- const rowJson = applyOutboundTransform(updated);
485
+ const rowJson = normalizeOutboundVersionColumn(applyOutboundTransform(updated), versionColumn, rowVersion);
385
486
  const emitted = {
386
487
  table,
387
488
  row_id: op.row_id,
@@ -395,15 +496,131 @@ export function createServerHandler(options) {
395
496
  emittedChanges: [emitted],
396
497
  };
397
498
  };
499
+ const defaultApplyOperationBatch = async (ctx, operations) => {
500
+ if (operations.length === 0)
501
+ return [];
502
+ const runSequentialFallback = async () => {
503
+ const sequential = [];
504
+ for (const entry of operations) {
505
+ const applied = await defaultApplyOperation(ctx, entry.op, entry.opIndex);
506
+ sequential.push(applied);
507
+ if (applied.result.status !== 'applied') {
508
+ break;
509
+ }
510
+ }
511
+ return sequential;
512
+ };
513
+ if (operations.length === 1 || authorize || requiredScopeKeys.length > 0) {
514
+ return runSequentialFallback();
515
+ }
516
+ const trx = ctx.trx;
517
+ const prepared = [];
518
+ const seenRowIds = new Set();
519
+ const payloadKeySignatures = new Set();
520
+ for (const entry of operations) {
521
+ const op = entry.op;
522
+ if (op.table !== table || op.op !== 'upsert' || op.base_version != null) {
523
+ return runSequentialFallback();
524
+ }
525
+ if (seenRowIds.has(op.row_id)) {
526
+ return runSequentialFallback();
527
+ }
528
+ seenRowIds.add(op.row_id);
529
+ const rawPayload = op.payload ?? {};
530
+ const payloadRecord = rawPayload !== null && typeof rawPayload === 'object'
531
+ ? rawPayload
532
+ : {};
533
+ const payload = applyInboundTransform(payloadRecord, ctx.schemaVersion);
534
+ payloadKeySignatures.add(Object.keys(payload).sort().join('\u0000'));
535
+ const insertValues = {
536
+ ...payload,
537
+ [primaryKey]: op.row_id,
538
+ [versionColumn]: 1,
539
+ };
540
+ prepared.push({
541
+ entry,
542
+ payload,
543
+ insertValues,
544
+ });
545
+ }
546
+ if (prepared.length <= 1 || payloadKeySignatures.size !== 1) {
547
+ return runSequentialFallback();
548
+ }
549
+ const basePayload = prepared[0].payload;
550
+ const updateSet = {
551
+ ...basePayload,
552
+ [versionColumn]: sql `${sql.ref(qualifiedVersionRef)} + 1`,
553
+ };
554
+ delete updateSet[primaryKey];
555
+ for (const col of Object.values(scopeColumns)) {
556
+ delete updateSet[col];
557
+ }
558
+ try {
559
+ const updatedRows = (await trx.insertInto(table)
560
+ .values(prepared.map((item) => item.insertValues))
561
+ .onConflict((oc) => oc.column(primaryKeyColumn).doUpdateSet(updateSet))
562
+ .returningAll()
563
+ .execute());
564
+ const updatedById = new Map();
565
+ for (const row of updatedRows) {
566
+ const rowIdValue = row[primaryKey];
567
+ if (rowIdValue === null || rowIdValue === undefined)
568
+ continue;
569
+ updatedById.set(String(rowIdValue), row);
570
+ }
571
+ const results = [];
572
+ for (const item of prepared) {
573
+ const rowId = item.entry.op.row_id;
574
+ const updated = updatedById.get(rowId);
575
+ if (!updated) {
576
+ return runSequentialFallback();
577
+ }
578
+ const rowVersion = readSafeVersionColumn(updated, versionColumn, 1);
579
+ const scopes = extractScopesImpl(updated);
580
+ const rowJson = normalizeOutboundVersionColumn(applyOutboundTransform(updated), versionColumn, rowVersion);
581
+ results.push({
582
+ result: { opIndex: item.entry.opIndex, status: 'applied' },
583
+ emittedChanges: [
584
+ {
585
+ table,
586
+ row_id: rowId,
587
+ op: 'upsert',
588
+ row_json: rowJson,
589
+ row_version: rowVersion,
590
+ scopes,
591
+ },
592
+ ],
593
+ });
594
+ }
595
+ return results;
596
+ }
597
+ catch (err) {
598
+ const message = err instanceof Error ? err.message : String(err);
599
+ if (isConstraintViolationError(message)) {
600
+ return runSequentialFallback();
601
+ }
602
+ throw err;
603
+ }
604
+ };
398
605
  return {
399
606
  table,
607
+ primaryKeyColumn,
400
608
  scopePatterns,
401
609
  dependsOn,
402
610
  snapshotChunkTtlMs,
611
+ snapshotBinaryColumns,
612
+ snapshotBinaryColumnsForVersion,
613
+ snapshotBinaryEncoder: snapshotBinaryEncoder,
614
+ snapshotBinaryEncoderForVersion: snapshotBinaryEncoderForVersion,
615
+ canRejectSingleOperationWithoutSavepoint: options.canRejectSingleOperationWithoutSavepoint ??
616
+ options.applyOperation === undefined,
403
617
  resolveScopes: resolveScopesImpl,
404
618
  extractScopes: extractScopesImpl,
405
619
  snapshot: options.snapshot ?? defaultSnapshot,
406
620
  applyOperation: options.applyOperation ?? defaultApplyOperation,
621
+ applyOperationBatch: options.applyOperation === undefined
622
+ ? defaultApplyOperationBatch
623
+ : undefined,
407
624
  };
408
625
  }
409
626
  //# sourceMappingURL=create-handler.js.map