@syncular/server 0.0.6-96 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (597) hide show
  1. package/README.md +1 -2
  2. package/dist/auth-leases.d.ts +85 -0
  3. package/dist/auth-leases.d.ts.map +1 -0
  4. package/dist/auth-leases.js +368 -0
  5. package/dist/auth-leases.js.map +1 -0
  6. package/dist/better-sqlite3.d.ts +22 -0
  7. package/dist/better-sqlite3.d.ts.map +1 -0
  8. package/dist/better-sqlite3.js +16 -0
  9. package/dist/better-sqlite3.js.map +1 -0
  10. package/dist/blobs/access.d.ts +35 -0
  11. package/dist/blobs/access.d.ts.map +1 -0
  12. package/dist/blobs/access.js +149 -0
  13. package/dist/blobs/access.js.map +1 -0
  14. package/dist/blobs/adapters/database.d.ts +26 -9
  15. package/dist/blobs/adapters/database.d.ts.map +1 -1
  16. package/dist/blobs/adapters/database.js +68 -23
  17. package/dist/blobs/adapters/database.js.map +1 -1
  18. package/dist/blobs/index.d.ts +1 -0
  19. package/dist/blobs/index.d.ts.map +1 -1
  20. package/dist/blobs/index.js +1 -0
  21. package/dist/blobs/index.js.map +1 -1
  22. package/dist/blobs/manager.d.ts +69 -44
  23. package/dist/blobs/manager.d.ts.map +1 -1
  24. package/dist/blobs/manager.js +250 -65
  25. package/dist/blobs/manager.js.map +1 -1
  26. package/dist/blobs/migrate.d.ts.map +1 -1
  27. package/dist/blobs/migrate.js +16 -8
  28. package/dist/blobs/migrate.js.map +1 -1
  29. package/dist/blobs/types.d.ts +4 -0
  30. package/dist/blobs/types.d.ts.map +1 -1
  31. package/dist/bun-sqlite.d.ts +19 -0
  32. package/dist/bun-sqlite.d.ts.map +1 -0
  33. package/dist/bun-sqlite.js +19 -0
  34. package/dist/bun-sqlite.js.map +1 -0
  35. package/dist/clients.d.ts +1 -0
  36. package/dist/clients.d.ts.map +1 -1
  37. package/dist/clients.js.map +1 -1
  38. package/dist/cloudflare/durable-object.d.ts +93 -0
  39. package/dist/cloudflare/durable-object.d.ts.map +1 -0
  40. package/dist/cloudflare/durable-object.js +210 -0
  41. package/dist/cloudflare/durable-object.js.map +1 -0
  42. package/dist/cloudflare/index.d.ts +22 -0
  43. package/dist/cloudflare/index.d.ts.map +1 -0
  44. package/dist/cloudflare/index.js +22 -0
  45. package/dist/cloudflare/index.js.map +1 -0
  46. package/dist/cloudflare/r2.d.ts +180 -0
  47. package/dist/cloudflare/r2.d.ts.map +1 -0
  48. package/dist/cloudflare/r2.js +258 -0
  49. package/dist/cloudflare/r2.js.map +1 -0
  50. package/dist/cloudflare/scope-cache.d.ts +54 -0
  51. package/dist/cloudflare/scope-cache.d.ts.map +1 -0
  52. package/dist/cloudflare/scope-cache.js +223 -0
  53. package/dist/cloudflare/scope-cache.js.map +1 -0
  54. package/dist/cloudflare/sentry.d.ts +47 -0
  55. package/dist/cloudflare/sentry.d.ts.map +1 -0
  56. package/dist/cloudflare/sentry.js +163 -0
  57. package/dist/cloudflare/sentry.js.map +1 -0
  58. package/dist/cloudflare/worker.d.ts +46 -0
  59. package/dist/cloudflare/worker.d.ts.map +1 -0
  60. package/dist/cloudflare/worker.js +63 -0
  61. package/dist/cloudflare/worker.js.map +1 -0
  62. package/dist/commit-integrity.d.ts +38 -0
  63. package/dist/commit-integrity.d.ts.map +1 -0
  64. package/dist/commit-integrity.js +260 -0
  65. package/dist/commit-integrity.js.map +1 -0
  66. package/dist/compaction.js.map +1 -1
  67. package/dist/crdt-yjs/index.d.ts +99 -0
  68. package/dist/crdt-yjs/index.d.ts.map +1 -0
  69. package/dist/crdt-yjs/index.js +629 -0
  70. package/dist/crdt-yjs/index.js.map +1 -0
  71. package/dist/d1.d.ts +13 -0
  72. package/dist/d1.d.ts.map +1 -0
  73. package/dist/d1.js +14 -0
  74. package/dist/d1.js.map +1 -0
  75. package/dist/dialect/base.d.ts +11 -1
  76. package/dist/dialect/base.d.ts.map +1 -1
  77. package/dist/dialect/base.js +42 -5
  78. package/dist/dialect/base.js.map +1 -1
  79. package/dist/dialect/helpers.d.ts +6 -0
  80. package/dist/dialect/helpers.d.ts.map +1 -1
  81. package/dist/dialect/helpers.js +24 -0
  82. package/dist/dialect/helpers.js.map +1 -1
  83. package/dist/dialect/types.d.ts +40 -0
  84. package/dist/dialect/types.d.ts.map +1 -1
  85. package/dist/encrypted-crdt.d.ts +67 -0
  86. package/dist/encrypted-crdt.d.ts.map +1 -0
  87. package/dist/encrypted-crdt.js +426 -0
  88. package/dist/encrypted-crdt.js.map +1 -0
  89. package/dist/errors.d.ts +10 -0
  90. package/dist/errors.d.ts.map +1 -0
  91. package/dist/errors.js +13 -0
  92. package/dist/errors.js.map +1 -0
  93. package/dist/filesystem/index.d.ts +44 -0
  94. package/dist/filesystem/index.d.ts.map +1 -0
  95. package/dist/filesystem/index.js +164 -0
  96. package/dist/filesystem/index.js.map +1 -0
  97. package/dist/handlers/collection.d.ts +11 -3
  98. package/dist/handlers/collection.d.ts.map +1 -1
  99. package/dist/handlers/collection.js +34 -56
  100. package/dist/handlers/collection.js.map +1 -1
  101. package/dist/handlers/create-handler.d.ts +31 -7
  102. package/dist/handlers/create-handler.d.ts.map +1 -1
  103. package/dist/handlers/create-handler.js +332 -115
  104. package/dist/handlers/create-handler.js.map +1 -1
  105. package/dist/handlers/types.d.ts +86 -1
  106. package/dist/handlers/types.d.ts.map +1 -1
  107. package/dist/helpers/conflict.js.map +1 -1
  108. package/dist/helpers/emitted-change.js.map +1 -1
  109. package/dist/helpers/index.d.ts +2 -0
  110. package/dist/helpers/index.d.ts.map +1 -1
  111. package/dist/helpers/index.js +2 -0
  112. package/dist/helpers/index.js.map +1 -1
  113. package/dist/helpers/paginate.js.map +1 -1
  114. package/dist/helpers/scope-authorization.d.ts +7 -0
  115. package/dist/helpers/scope-authorization.d.ts.map +1 -0
  116. package/dist/helpers/scope-authorization.js +19 -0
  117. package/dist/helpers/scope-authorization.js.map +1 -0
  118. package/dist/helpers/scope-commit-index.d.ts +12 -0
  119. package/dist/helpers/scope-commit-index.d.ts.map +1 -0
  120. package/dist/helpers/scope-commit-index.js +35 -0
  121. package/dist/helpers/scope-commit-index.js.map +1 -0
  122. package/dist/helpers/scope-strings.js.map +1 -1
  123. package/dist/hono/api-key-auth.d.ts +49 -0
  124. package/dist/hono/api-key-auth.d.ts.map +1 -0
  125. package/dist/hono/api-key-auth.js +108 -0
  126. package/dist/hono/api-key-auth.js.map +1 -0
  127. package/dist/hono/audit-redaction.d.ts +20 -0
  128. package/dist/hono/audit-redaction.d.ts.map +1 -0
  129. package/dist/hono/audit-redaction.js +85 -0
  130. package/dist/hono/audit-redaction.js.map +1 -0
  131. package/dist/hono/blobs.d.ts +75 -0
  132. package/dist/hono/blobs.d.ts.map +1 -0
  133. package/dist/hono/blobs.js +586 -0
  134. package/dist/hono/blobs.js.map +1 -0
  135. package/dist/hono/console/gateway.d.ts +42 -0
  136. package/dist/hono/console/gateway.d.ts.map +1 -0
  137. package/dist/hono/console/gateway.js +2158 -0
  138. package/dist/hono/console/gateway.js.map +1 -0
  139. package/dist/hono/console/live-auth.d.ts +7 -0
  140. package/dist/hono/console/live-auth.d.ts.map +1 -0
  141. package/dist/hono/console/live-auth.js +39 -0
  142. package/dist/hono/console/live-auth.js.map +1 -0
  143. package/dist/hono/console/route-descriptor.d.ts +6 -0
  144. package/dist/hono/console/route-descriptor.d.ts.map +1 -0
  145. package/dist/hono/console/route-descriptor.js +16 -0
  146. package/dist/hono/console/route-descriptor.js.map +1 -0
  147. package/dist/hono/console/routes/api-keys.d.ts +8 -0
  148. package/dist/hono/console/routes/api-keys.d.ts.map +1 -0
  149. package/dist/hono/console/routes/api-keys.js +575 -0
  150. package/dist/hono/console/routes/api-keys.js.map +1 -0
  151. package/dist/hono/console/routes/clients.d.ts +8 -0
  152. package/dist/hono/console/routes/clients.d.ts.map +1 -0
  153. package/dist/hono/console/routes/clients.js +322 -0
  154. package/dist/hono/console/routes/clients.js.map +1 -0
  155. package/dist/hono/console/routes/commits.d.ts +8 -0
  156. package/dist/hono/console/routes/commits.d.ts.map +1 -0
  157. package/dist/hono/console/routes/commits.js +882 -0
  158. package/dist/hono/console/routes/commits.js.map +1 -0
  159. package/dist/hono/console/routes/context.d.ts +188 -0
  160. package/dist/hono/console/routes/context.d.ts.map +1 -0
  161. package/dist/hono/console/routes/context.js +633 -0
  162. package/dist/hono/console/routes/context.js.map +1 -0
  163. package/dist/hono/console/routes/events.d.ts +8 -0
  164. package/dist/hono/console/routes/events.d.ts.map +1 -0
  165. package/dist/hono/console/routes/events.js +501 -0
  166. package/dist/hono/console/routes/events.js.map +1 -0
  167. package/dist/hono/console/routes/maintenance.d.ts +8 -0
  168. package/dist/hono/console/routes/maintenance.d.ts.map +1 -0
  169. package/dist/hono/console/routes/maintenance.js +341 -0
  170. package/dist/hono/console/routes/maintenance.js.map +1 -0
  171. package/dist/hono/console/routes/shared.d.ts +174 -0
  172. package/dist/hono/console/routes/shared.d.ts.map +1 -0
  173. package/dist/hono/console/routes/shared.js +583 -0
  174. package/dist/hono/console/routes/shared.js.map +1 -0
  175. package/dist/hono/console/routes/stats.d.ts +8 -0
  176. package/dist/hono/console/routes/stats.d.ts.map +1 -0
  177. package/dist/hono/console/routes/stats.js +295 -0
  178. package/dist/hono/console/routes/stats.js.map +1 -0
  179. package/dist/hono/console/routes/storage.d.ts +8 -0
  180. package/dist/hono/console/routes/storage.d.ts.map +1 -0
  181. package/dist/hono/console/routes/storage.js +121 -0
  182. package/dist/hono/console/routes/storage.js.map +1 -0
  183. package/dist/hono/console/routes.d.ts +36 -0
  184. package/dist/hono/console/routes.d.ts.map +1 -0
  185. package/dist/hono/console/routes.js +112 -0
  186. package/dist/hono/console/routes.js.map +1 -0
  187. package/dist/hono/console/schema-errors.d.ts +2 -0
  188. package/dist/hono/console/schema-errors.d.ts.map +1 -0
  189. package/dist/hono/console/schema-errors.js +17 -0
  190. package/dist/hono/console/schema-errors.js.map +1 -0
  191. package/dist/hono/console/schemas.d.ts +1515 -0
  192. package/dist/hono/console/schemas.d.ts.map +1 -0
  193. package/dist/hono/console/schemas.js +661 -0
  194. package/dist/hono/console/schemas.js.map +1 -0
  195. package/dist/hono/console/types.d.ts +213 -0
  196. package/dist/hono/console/types.d.ts.map +1 -0
  197. package/dist/hono/console/types.js +2 -0
  198. package/dist/hono/console/types.js.map +1 -0
  199. package/dist/hono/console/ui.d.ts +38 -0
  200. package/dist/hono/console/ui.d.ts.map +1 -0
  201. package/dist/hono/console/ui.js +43 -0
  202. package/dist/hono/console/ui.js.map +1 -0
  203. package/dist/hono/create-server.d.ts +71 -0
  204. package/dist/hono/create-server.d.ts.map +1 -0
  205. package/dist/hono/create-server.js +121 -0
  206. package/dist/hono/create-server.js.map +1 -0
  207. package/dist/hono/errors.d.ts +13 -0
  208. package/dist/hono/errors.d.ts.map +1 -0
  209. package/dist/hono/errors.js +21 -0
  210. package/dist/hono/errors.js.map +1 -0
  211. package/dist/hono/index.d.ts +20 -0
  212. package/dist/hono/index.d.ts.map +1 -0
  213. package/dist/hono/index.js +31 -0
  214. package/dist/hono/index.js.map +1 -0
  215. package/dist/hono/openapi.d.ts +72 -0
  216. package/dist/hono/openapi.d.ts.map +1 -0
  217. package/dist/hono/openapi.js +99 -0
  218. package/dist/hono/openapi.js.map +1 -0
  219. package/dist/hono/proxy/connection-manager.d.ts +78 -0
  220. package/dist/hono/proxy/connection-manager.d.ts.map +1 -0
  221. package/dist/hono/proxy/connection-manager.js +251 -0
  222. package/dist/hono/proxy/connection-manager.js.map +1 -0
  223. package/dist/hono/proxy/index.d.ts +8 -0
  224. package/dist/hono/proxy/index.d.ts.map +1 -0
  225. package/dist/hono/proxy/index.js +8 -0
  226. package/dist/hono/proxy/index.js.map +1 -0
  227. package/dist/hono/proxy/routes.d.ts +86 -0
  228. package/dist/hono/proxy/routes.d.ts.map +1 -0
  229. package/dist/hono/proxy/routes.js +183 -0
  230. package/dist/hono/proxy/routes.js.map +1 -0
  231. package/dist/hono/rate-limit.d.ts +101 -0
  232. package/dist/hono/rate-limit.d.ts.map +1 -0
  233. package/dist/hono/rate-limit.js +184 -0
  234. package/dist/hono/rate-limit.js.map +1 -0
  235. package/dist/hono/realtime-sync-packs.d.ts +43 -0
  236. package/dist/hono/realtime-sync-packs.d.ts.map +1 -0
  237. package/dist/hono/realtime-sync-packs.js +219 -0
  238. package/dist/hono/realtime-sync-packs.js.map +1 -0
  239. package/dist/hono/routes/audit.d.ts +12 -0
  240. package/dist/hono/routes/audit.d.ts.map +1 -0
  241. package/dist/hono/routes/audit.js +385 -0
  242. package/dist/hono/routes/audit.js.map +1 -0
  243. package/dist/hono/routes/auth-leases.d.ts +8 -0
  244. package/dist/hono/routes/auth-leases.d.ts.map +1 -0
  245. package/dist/hono/routes/auth-leases.js +88 -0
  246. package/dist/hono/routes/auth-leases.js.map +1 -0
  247. package/dist/hono/routes/combined.d.ts +8 -0
  248. package/dist/hono/routes/combined.d.ts.map +1 -0
  249. package/dist/hono/routes/combined.js +392 -0
  250. package/dist/hono/routes/combined.js.map +1 -0
  251. package/dist/hono/routes/context.d.ts +314 -0
  252. package/dist/hono/routes/context.d.ts.map +1 -0
  253. package/dist/hono/routes/context.js +1147 -0
  254. package/dist/hono/routes/context.js.map +1 -0
  255. package/dist/hono/routes/health.d.ts +8 -0
  256. package/dist/hono/routes/health.d.ts.map +1 -0
  257. package/dist/hono/routes/health.js +16 -0
  258. package/dist/hono/routes/health.js.map +1 -0
  259. package/dist/hono/routes/realtime.d.ts +9 -0
  260. package/dist/hono/routes/realtime.d.ts.map +1 -0
  261. package/dist/hono/routes/realtime.js +626 -0
  262. package/dist/hono/routes/realtime.js.map +1 -0
  263. package/dist/hono/routes/shared.d.ts +689 -0
  264. package/dist/hono/routes/shared.d.ts.map +1 -0
  265. package/dist/hono/routes/shared.js +972 -0
  266. package/dist/hono/routes/shared.js.map +1 -0
  267. package/dist/hono/routes/snapshots.d.ts +10 -0
  268. package/dist/hono/routes/snapshots.d.ts.map +1 -0
  269. package/dist/hono/routes/snapshots.js +281 -0
  270. package/dist/hono/routes/snapshots.js.map +1 -0
  271. package/dist/hono/routes.d.ts +19 -0
  272. package/dist/hono/routes.d.ts.map +1 -0
  273. package/dist/hono/routes.js +37 -0
  274. package/dist/hono/routes.js.map +1 -0
  275. package/dist/hono/validation.d.ts +5 -0
  276. package/dist/hono/validation.d.ts.map +1 -0
  277. package/dist/hono/validation.js +47 -0
  278. package/dist/hono/validation.js.map +1 -0
  279. package/dist/hono/websocket-origin.d.ts +9 -0
  280. package/dist/hono/websocket-origin.d.ts.map +1 -0
  281. package/dist/hono/websocket-origin.js +96 -0
  282. package/dist/hono/websocket-origin.js.map +1 -0
  283. package/dist/hono/ws.d.ts +341 -0
  284. package/dist/hono/ws.d.ts.map +1 -0
  285. package/dist/hono/ws.js +711 -0
  286. package/dist/hono/ws.js.map +1 -0
  287. package/dist/index.d.ts +6 -0
  288. package/dist/index.d.ts.map +1 -1
  289. package/dist/index.js +6 -0
  290. package/dist/index.js.map +1 -1
  291. package/dist/libsql.d.ts +29 -0
  292. package/dist/libsql.d.ts.map +1 -0
  293. package/dist/libsql.js +25 -0
  294. package/dist/libsql.js.map +1 -0
  295. package/dist/migrate.js.map +1 -1
  296. package/dist/neon.d.ts +21 -0
  297. package/dist/neon.d.ts.map +1 -0
  298. package/dist/neon.js +22 -0
  299. package/dist/neon.js.map +1 -0
  300. package/dist/notify.d.ts +30 -0
  301. package/dist/notify.d.ts.map +1 -1
  302. package/dist/notify.js +160 -41
  303. package/dist/notify.js.map +1 -1
  304. package/dist/pglite.d.ts +37 -0
  305. package/dist/pglite.d.ts.map +1 -0
  306. package/dist/pglite.js +37 -0
  307. package/dist/pglite.js.map +1 -0
  308. package/dist/plugins/index.d.ts +2 -0
  309. package/dist/plugins/index.d.ts.map +1 -0
  310. package/dist/plugins/index.js +2 -0
  311. package/dist/plugins/index.js.map +1 -0
  312. package/dist/plugins/types.d.ts +73 -0
  313. package/dist/plugins/types.d.ts.map +1 -0
  314. package/dist/plugins/types.js +30 -0
  315. package/dist/plugins/types.js.map +1 -0
  316. package/dist/postgres/index.d.ts +68 -0
  317. package/dist/postgres/index.d.ts.map +1 -0
  318. package/dist/postgres/index.js +924 -0
  319. package/dist/postgres/index.js.map +1 -0
  320. package/dist/proxy/collection.d.ts +0 -2
  321. package/dist/proxy/collection.d.ts.map +1 -1
  322. package/dist/proxy/collection.js +2 -17
  323. package/dist/proxy/collection.js.map +1 -1
  324. package/dist/proxy/handler.d.ts +1 -1
  325. package/dist/proxy/handler.d.ts.map +1 -1
  326. package/dist/proxy/handler.js +1 -2
  327. package/dist/proxy/handler.js.map +1 -1
  328. package/dist/proxy/index.d.ts +1 -1
  329. package/dist/proxy/index.d.ts.map +1 -1
  330. package/dist/proxy/index.js +1 -1
  331. package/dist/proxy/index.js.map +1 -1
  332. package/dist/proxy/mutation-detector.js.map +1 -1
  333. package/dist/proxy/oplog.d.ts.map +1 -1
  334. package/dist/proxy/oplog.js +32 -8
  335. package/dist/proxy/oplog.js.map +1 -1
  336. package/dist/prune.d.ts +8 -1
  337. package/dist/prune.d.ts.map +1 -1
  338. package/dist/prune.js +68 -28
  339. package/dist/prune.js.map +1 -1
  340. package/dist/pull.d.ts +31 -0
  341. package/dist/pull.d.ts.map +1 -1
  342. package/dist/pull.js +1011 -471
  343. package/dist/pull.js.map +1 -1
  344. package/dist/push.d.ts +36 -2
  345. package/dist/push.d.ts.map +1 -1
  346. package/dist/push.js +603 -358
  347. package/dist/push.js.map +1 -1
  348. package/dist/realtime/in-memory.js.map +1 -1
  349. package/dist/realtime/index.d.ts +2 -1
  350. package/dist/realtime/index.d.ts.map +1 -1
  351. package/dist/realtime/index.js +1 -0
  352. package/dist/realtime/index.js.map +1 -1
  353. package/dist/realtime/types.d.ts +12 -0
  354. package/dist/realtime/types.d.ts.map +1 -1
  355. package/dist/realtime/types.js +13 -1
  356. package/dist/realtime/types.js.map +1 -1
  357. package/dist/relay/client-role/forward-engine.d.ts +63 -0
  358. package/dist/relay/client-role/forward-engine.d.ts.map +1 -0
  359. package/dist/relay/client-role/forward-engine.js +267 -0
  360. package/dist/relay/client-role/forward-engine.js.map +1 -0
  361. package/dist/relay/client-role/index.d.ts +9 -0
  362. package/dist/relay/client-role/index.d.ts.map +1 -0
  363. package/dist/relay/client-role/index.js +9 -0
  364. package/dist/relay/client-role/index.js.map +1 -0
  365. package/dist/relay/client-role/pull-engine.d.ts +72 -0
  366. package/dist/relay/client-role/pull-engine.d.ts.map +1 -0
  367. package/dist/relay/client-role/pull-engine.js +249 -0
  368. package/dist/relay/client-role/pull-engine.js.map +1 -0
  369. package/dist/relay/client-role/sequence-mapper.d.ts +65 -0
  370. package/dist/relay/client-role/sequence-mapper.d.ts.map +1 -0
  371. package/dist/relay/client-role/sequence-mapper.js +161 -0
  372. package/dist/relay/client-role/sequence-mapper.js.map +1 -0
  373. package/dist/relay/evaluation/relay-paths.d.ts +41 -0
  374. package/dist/relay/evaluation/relay-paths.d.ts.map +1 -0
  375. package/dist/relay/evaluation/relay-paths.js +504 -0
  376. package/dist/relay/evaluation/relay-paths.js.map +1 -0
  377. package/dist/relay/evaluation/rust-boundary.d.ts +47 -0
  378. package/dist/relay/evaluation/rust-boundary.d.ts.map +1 -0
  379. package/dist/relay/evaluation/rust-boundary.js +220 -0
  380. package/dist/relay/evaluation/rust-boundary.js.map +1 -0
  381. package/dist/relay/index.d.ts +37 -0
  382. package/dist/relay/index.d.ts.map +1 -0
  383. package/dist/relay/index.js +44 -0
  384. package/dist/relay/index.js.map +1 -0
  385. package/dist/relay/migrate.d.ts +18 -0
  386. package/dist/relay/migrate.d.ts.map +1 -0
  387. package/dist/relay/migrate.js +99 -0
  388. package/dist/relay/migrate.js.map +1 -0
  389. package/dist/relay/mode-manager.d.ts +60 -0
  390. package/dist/relay/mode-manager.d.ts.map +1 -0
  391. package/dist/relay/mode-manager.js +114 -0
  392. package/dist/relay/mode-manager.js.map +1 -0
  393. package/dist/relay/realtime.d.ts +90 -0
  394. package/dist/relay/realtime.d.ts.map +1 -0
  395. package/dist/relay/realtime.js +147 -0
  396. package/dist/relay/realtime.js.map +1 -0
  397. package/dist/relay/relay.d.ts +190 -0
  398. package/dist/relay/relay.d.ts.map +1 -0
  399. package/dist/relay/relay.js +320 -0
  400. package/dist/relay/relay.js.map +1 -0
  401. package/dist/relay/schema.d.ts +158 -0
  402. package/dist/relay/schema.d.ts.map +1 -0
  403. package/dist/relay/schema.js +7 -0
  404. package/dist/relay/schema.js.map +1 -0
  405. package/dist/relay/server-role/index.d.ts +56 -0
  406. package/dist/relay/server-role/index.d.ts.map +1 -0
  407. package/dist/relay/server-role/index.js +193 -0
  408. package/dist/relay/server-role/index.js.map +1 -0
  409. package/dist/relay/server-role/pull.d.ts +27 -0
  410. package/dist/relay/server-role/pull.d.ts.map +1 -0
  411. package/dist/relay/server-role/pull.js +24 -0
  412. package/dist/relay/server-role/pull.js.map +1 -0
  413. package/dist/relay/server-role/push.d.ts +29 -0
  414. package/dist/relay/server-role/push.d.ts.map +1 -0
  415. package/dist/relay/server-role/push.js +122 -0
  416. package/dist/relay/server-role/push.js.map +1 -0
  417. package/dist/s3/index.d.ts +83 -0
  418. package/dist/s3/index.d.ts.map +1 -0
  419. package/dist/s3/index.js +223 -0
  420. package/dist/s3/index.js.map +1 -0
  421. package/dist/schema.d.ts +137 -1
  422. package/dist/schema.d.ts.map +1 -1
  423. package/dist/schema.js +1 -0
  424. package/dist/schema.js.map +1 -1
  425. package/dist/service-worker/index.d.ts +114 -0
  426. package/dist/service-worker/index.d.ts.map +1 -0
  427. package/dist/service-worker/index.js +487 -0
  428. package/dist/service-worker/index.js.map +1 -0
  429. package/dist/snapshot-artifacts/sqlite-bun.d.ts +15 -0
  430. package/dist/snapshot-artifacts/sqlite-bun.d.ts.map +1 -0
  431. package/dist/snapshot-artifacts/sqlite-bun.js +128 -0
  432. package/dist/snapshot-artifacts/sqlite-bun.js.map +1 -0
  433. package/dist/snapshot-artifacts.d.ts +206 -0
  434. package/dist/snapshot-artifacts.d.ts.map +1 -0
  435. package/dist/snapshot-artifacts.js +545 -0
  436. package/dist/snapshot-artifacts.js.map +1 -0
  437. package/dist/snapshot-chunks/db-metadata.d.ts +18 -0
  438. package/dist/snapshot-chunks/db-metadata.d.ts.map +1 -1
  439. package/dist/snapshot-chunks/db-metadata.js +91 -63
  440. package/dist/snapshot-chunks/db-metadata.js.map +1 -1
  441. package/dist/snapshot-chunks/types.d.ts +2 -0
  442. package/dist/snapshot-chunks/types.d.ts.map +1 -1
  443. package/dist/snapshot-chunks.d.ts +33 -3
  444. package/dist/snapshot-chunks.d.ts.map +1 -1
  445. package/dist/snapshot-chunks.js +136 -55
  446. package/dist/snapshot-chunks.js.map +1 -1
  447. package/dist/sqlite/index.d.ts +53 -0
  448. package/dist/sqlite/index.d.ts.map +1 -0
  449. package/dist/sqlite/index.js +795 -0
  450. package/dist/sqlite/index.js.map +1 -0
  451. package/dist/sqlite3.d.ts +22 -0
  452. package/dist/sqlite3.d.ts.map +1 -0
  453. package/dist/sqlite3.js +99 -0
  454. package/dist/sqlite3.js.map +1 -0
  455. package/dist/stats.d.ts +8 -0
  456. package/dist/stats.d.ts.map +1 -1
  457. package/dist/stats.js +45 -13
  458. package/dist/stats.js.map +1 -1
  459. package/dist/subscriptions/cache.d.ts +3 -0
  460. package/dist/subscriptions/cache.d.ts.map +1 -1
  461. package/dist/subscriptions/cache.js +44 -0
  462. package/dist/subscriptions/cache.js.map +1 -1
  463. package/dist/subscriptions/resolve.d.ts +3 -1
  464. package/dist/subscriptions/resolve.d.ts.map +1 -1
  465. package/dist/subscriptions/resolve.js +90 -51
  466. package/dist/subscriptions/resolve.js.map +1 -1
  467. package/dist/sync.d.ts +3 -0
  468. package/dist/sync.d.ts.map +1 -1
  469. package/dist/sync.js +8 -4
  470. package/dist/sync.js.map +1 -1
  471. package/package.json +296 -7
  472. package/src/auth-leases.ts +649 -0
  473. package/src/better-sqlite3.ts +35 -0
  474. package/src/blobs/access.ts +244 -0
  475. package/src/blobs/adapters/database.ts +125 -43
  476. package/src/blobs/index.ts +1 -0
  477. package/src/blobs/manager.ts +366 -65
  478. package/src/blobs/migrate.ts +16 -8
  479. package/src/blobs/types.ts +4 -0
  480. package/src/bun-sqlite-ambient.d.ts +19 -0
  481. package/src/bun-sqlite.ts +27 -0
  482. package/src/clients.ts +1 -0
  483. package/src/cloudflare/durable-object.ts +289 -0
  484. package/src/cloudflare/index.ts +22 -0
  485. package/src/cloudflare/r2.ts +526 -0
  486. package/src/cloudflare/scope-cache.ts +341 -0
  487. package/src/cloudflare/sentry.ts +230 -0
  488. package/src/cloudflare/worker.ts +77 -0
  489. package/src/commit-integrity.ts +371 -0
  490. package/src/crdt-yjs/index.ts +931 -0
  491. package/src/d1.ts +16 -0
  492. package/src/dialect/base.ts +71 -5
  493. package/src/dialect/helpers.ts +31 -0
  494. package/src/dialect/types.ts +47 -0
  495. package/src/encrypted-crdt.ts +786 -0
  496. package/src/errors.ts +22 -0
  497. package/src/filesystem/index.ts +262 -0
  498. package/src/handlers/collection.ts +78 -78
  499. package/src/handlers/create-handler.ts +540 -147
  500. package/src/handlers/types.ts +116 -0
  501. package/src/helpers/index.ts +2 -0
  502. package/src/helpers/scope-authorization.ts +27 -0
  503. package/src/helpers/scope-commit-index.ts +52 -0
  504. package/src/hono/api-key-auth.ts +177 -0
  505. package/src/hono/audit-redaction.ts +135 -0
  506. package/src/hono/blobs.ts +851 -0
  507. package/src/hono/console/gateway.ts +3046 -0
  508. package/src/hono/console/live-auth.ts +46 -0
  509. package/src/hono/console/route-descriptor.ts +22 -0
  510. package/src/hono/console/routes/api-keys.ts +721 -0
  511. package/src/hono/console/routes/clients.ts +447 -0
  512. package/src/hono/console/routes/commits.ts +1137 -0
  513. package/src/hono/console/routes/context.ts +956 -0
  514. package/src/hono/console/routes/events.ts +669 -0
  515. package/src/hono/console/routes/maintenance.ts +461 -0
  516. package/src/hono/console/routes/shared.ts +816 -0
  517. package/src/hono/console/routes/stats.ts +392 -0
  518. package/src/hono/console/routes/storage.ts +159 -0
  519. package/src/hono/console/routes.ts +146 -0
  520. package/src/hono/console/schema-errors.ts +23 -0
  521. package/src/hono/console/schemas.ts +914 -0
  522. package/src/hono/console/types.ts +223 -0
  523. package/src/hono/console/ui.ts +100 -0
  524. package/src/hono/create-server.ts +230 -0
  525. package/src/hono/errors.ts +50 -0
  526. package/src/hono/index.ts +54 -0
  527. package/src/hono/openapi.ts +139 -0
  528. package/src/hono/proxy/connection-manager.ts +340 -0
  529. package/src/hono/proxy/index.ts +8 -0
  530. package/src/hono/proxy/routes.ts +272 -0
  531. package/src/hono/rate-limit.ts +319 -0
  532. package/src/hono/realtime-sync-packs.ts +354 -0
  533. package/src/hono/routes/audit.ts +499 -0
  534. package/src/hono/routes/auth-leases.ts +119 -0
  535. package/src/hono/routes/combined.ts +583 -0
  536. package/src/hono/routes/context.ts +1629 -0
  537. package/src/hono/routes/health.ts +26 -0
  538. package/src/hono/routes/realtime.ts +808 -0
  539. package/src/hono/routes/shared.ts +1626 -0
  540. package/src/hono/routes/snapshots.ts +345 -0
  541. package/src/hono/routes.ts +68 -0
  542. package/src/hono/validation.ts +81 -0
  543. package/src/hono/websocket-origin.ts +131 -0
  544. package/src/hono/ws.ts +1134 -0
  545. package/src/index.ts +6 -0
  546. package/src/libsql.ts +51 -0
  547. package/src/neon.ts +28 -0
  548. package/src/notify.ts +224 -44
  549. package/src/pglite.ts +68 -0
  550. package/src/plugins/index.ts +1 -0
  551. package/src/plugins/types.ts +144 -0
  552. package/src/postgres/index.ts +1291 -0
  553. package/src/proxy/collection.ts +5 -27
  554. package/src/proxy/handler.ts +2 -2
  555. package/src/proxy/index.ts +0 -2
  556. package/src/proxy/oplog.ts +41 -10
  557. package/src/prune.ts +137 -36
  558. package/src/pull.ts +1504 -591
  559. package/src/push.ts +881 -443
  560. package/src/realtime/index.ts +2 -0
  561. package/src/realtime/types.ts +35 -0
  562. package/src/relay/bun-types.d.ts +50 -0
  563. package/src/relay/client-role/forward-engine.ts +355 -0
  564. package/src/relay/client-role/index.ts +9 -0
  565. package/src/relay/client-role/pull-engine.ts +329 -0
  566. package/src/relay/client-role/sequence-mapper.ts +201 -0
  567. package/src/relay/evaluation/relay-paths.ts +699 -0
  568. package/src/relay/evaluation/rust-boundary.ts +464 -0
  569. package/src/relay/index.ts +50 -0
  570. package/src/relay/migrate.ts +113 -0
  571. package/src/relay/mode-manager.ts +142 -0
  572. package/src/relay/realtime.ts +207 -0
  573. package/src/relay/relay.ts +431 -0
  574. package/src/relay/schema.ts +171 -0
  575. package/src/relay/server-role/index.ts +338 -0
  576. package/src/relay/server-role/pull.ts +43 -0
  577. package/src/relay/server-role/push.ts +164 -0
  578. package/src/s3/index.ts +346 -0
  579. package/src/schema.ts +141 -1
  580. package/src/service-worker/index.ts +773 -0
  581. package/src/snapshot-artifacts/sqlite-bun.ts +168 -0
  582. package/src/snapshot-artifacts.ts +896 -0
  583. package/src/snapshot-chunks/db-metadata.ts +131 -72
  584. package/src/snapshot-chunks/types.ts +2 -0
  585. package/src/snapshot-chunks.ts +194 -70
  586. package/src/sqlite/index.ts +1064 -0
  587. package/src/sqlite3.ts +137 -0
  588. package/src/stats.ts +76 -13
  589. package/src/subscriptions/cache.ts +58 -0
  590. package/src/subscriptions/resolve.ts +99 -58
  591. package/src/sync.ts +16 -6
  592. package/src/blobs/adapters/database.test.ts +0 -67
  593. package/src/notify.test.ts +0 -520
  594. package/src/proxy/handler.test.ts +0 -126
  595. package/src/proxy/mutation-detector.test.ts +0 -71
  596. package/src/snapshot-chunks/db-metadata.test.ts +0 -172
  597. package/src/subscriptions/resolve.test.ts +0 -180
@@ -0,0 +1,795 @@
1
+ /**
2
+ * @syncular/server/sqlite - SQLite Server Sync Dialect
3
+ *
4
+ * SQLite adaptation of the commit-log based sync system.
5
+ * Works with SQLite-compatible Kysely dialects such as bun:sqlite, better-sqlite3, and sqlite3.
6
+ *
7
+ * Key differences from Postgres:
8
+ * - No bigserial → INTEGER PRIMARY KEY AUTOINCREMENT
9
+ * - No JSONB → JSON stored as TEXT (with json_extract for filtering)
10
+ * - No array && overlap → JSON object key matching
11
+ * - No timestamptz → TEXT with ISO format
12
+ * - No GIN index → regular index + manual filtering
13
+ * - REPEATABLE READ → no-op (SQLite uses serializable by default)
14
+ */
15
+ import { BaseServerSyncDialect, coerceIsoString, coerceNumber, createSavepointName, isActiveTransaction, parseScopes, } from '@syncular/server';
16
+ import { sql } from 'kysely';
17
+ function parseJsonValue(value) {
18
+ if (value === null || value === undefined)
19
+ return null;
20
+ if (typeof value === 'object')
21
+ return value;
22
+ if (typeof value === 'string') {
23
+ try {
24
+ return JSON.parse(value);
25
+ }
26
+ catch {
27
+ return value;
28
+ }
29
+ }
30
+ return value;
31
+ }
32
+ function toStringArray(value) {
33
+ if (Array.isArray(value)) {
34
+ return value.filter((k) => typeof k === 'string');
35
+ }
36
+ if (typeof value === 'string') {
37
+ try {
38
+ const parsed = JSON.parse(value);
39
+ if (Array.isArray(parsed)) {
40
+ return parsed.filter((k) => typeof k === 'string');
41
+ }
42
+ }
43
+ catch {
44
+ // ignore
45
+ }
46
+ }
47
+ return [];
48
+ }
49
+ /**
50
+ * Build a safe SQLite JSON path for a scope key.
51
+ */
52
+ function toSqliteJsonPath(scopeKey) {
53
+ if (/^[A-Za-z_][A-Za-z0-9_]*$/.test(scopeKey)) {
54
+ return `$.${scopeKey}`;
55
+ }
56
+ const escaped = scopeKey
57
+ .replaceAll('\\', '\\\\')
58
+ .replaceAll('"', '\\"')
59
+ .replaceAll("'", "\\'");
60
+ return `$."${escaped}"`;
61
+ }
62
+ /**
63
+ * Build scope filter SQL for a JSON scopes column.
64
+ * Returns `0 = 1` when a requested array scope is empty.
65
+ */
66
+ function buildScopeFilterSql(scopes, scopeColumnSql) {
67
+ const conditions = [];
68
+ for (const [scopeKey, requested] of Object.entries(scopes)) {
69
+ const jsonPath = toSqliteJsonPath(scopeKey);
70
+ if (Array.isArray(requested)) {
71
+ const values = requested.filter((value) => typeof value === 'string');
72
+ if (values.length === 0) {
73
+ return sql `0 = 1`;
74
+ }
75
+ const valuesSql = sql.join(values.map((value) => sql `${value}`), sql `, `);
76
+ conditions.push(sql `json_extract(${sql.raw(scopeColumnSql)}, ${jsonPath}) IN (${valuesSql})`);
77
+ continue;
78
+ }
79
+ conditions.push(sql `json_extract(${sql.raw(scopeColumnSql)}, ${jsonPath}) = ${requested}`);
80
+ }
81
+ if (conditions.length === 0) {
82
+ return sql `1 = 1`;
83
+ }
84
+ return sql.join(conditions, sql ` AND `);
85
+ }
86
+ async function ensurePartitionColumn(db, table) {
87
+ try {
88
+ await sql
89
+ .raw(`ALTER TABLE ${table} ADD COLUMN partition_id TEXT NOT NULL DEFAULT 'default'`)
90
+ .execute(db);
91
+ }
92
+ catch {
93
+ // Ignore when column already exists (or table is immutable in the current backend).
94
+ }
95
+ }
96
+ async function ensureCommitVerificationColumns(db) {
97
+ const alterStatements = [
98
+ 'ALTER TABLE sync_commits ADD COLUMN commit_digest TEXT',
99
+ 'ALTER TABLE sync_commits ADD COLUMN commit_chain_root TEXT',
100
+ ];
101
+ for (const statement of alterStatements) {
102
+ try {
103
+ await sql.raw(statement).execute(db);
104
+ }
105
+ catch {
106
+ // Ignore when column already exists.
107
+ }
108
+ }
109
+ }
110
+ async function ensureConsoleEventColumns(db) {
111
+ const alterStatements = [
112
+ "ALTER TABLE sync_request_events ADD COLUMN partition_id TEXT NOT NULL DEFAULT 'default'",
113
+ 'ALTER TABLE sync_request_events ADD COLUMN request_id TEXT',
114
+ 'ALTER TABLE sync_request_events ADD COLUMN trace_id TEXT',
115
+ 'ALTER TABLE sync_request_events ADD COLUMN span_id TEXT',
116
+ "ALTER TABLE sync_request_events ADD COLUMN transport_path TEXT NOT NULL DEFAULT 'direct'",
117
+ "ALTER TABLE sync_request_events ADD COLUMN sync_path TEXT NOT NULL DEFAULT 'http-combined'",
118
+ "ALTER TABLE sync_request_events ADD COLUMN response_status TEXT NOT NULL DEFAULT 'unknown'",
119
+ 'ALTER TABLE sync_request_events ADD COLUMN error_code TEXT',
120
+ 'ALTER TABLE sync_request_events ADD COLUMN subscription_count INTEGER',
121
+ 'ALTER TABLE sync_request_events ADD COLUMN scopes_summary TEXT',
122
+ 'ALTER TABLE sync_request_events ADD COLUMN response_summary TEXT',
123
+ 'ALTER TABLE sync_request_events ADD COLUMN payload_ref TEXT',
124
+ ];
125
+ for (const statement of alterStatements) {
126
+ try {
127
+ await sql.raw(statement).execute(db);
128
+ }
129
+ catch {
130
+ // Ignore when column already exists (or table is immutable in the current backend).
131
+ }
132
+ }
133
+ }
134
+ async function ensureSnapshotChunkContinuationColumns(db) {
135
+ const alterStatements = [
136
+ 'ALTER TABLE sync_snapshot_chunks ADD COLUMN next_row_cursor TEXT',
137
+ 'ALTER TABLE sync_snapshot_chunks ADD COLUMN is_last_page INTEGER NOT NULL DEFAULT 0',
138
+ ];
139
+ for (const statement of alterStatements) {
140
+ try {
141
+ await sql.raw(statement).execute(db);
142
+ }
143
+ catch {
144
+ // Ignore when column already exists.
145
+ }
146
+ }
147
+ }
148
+ export class SqliteServerSyncDialect extends BaseServerSyncDialect {
149
+ family = 'sqlite';
150
+ supportsForUpdate = false;
151
+ supportsSavepoints;
152
+ supportsInsertReturning = false;
153
+ _supportsTransactions;
154
+ constructor(options) {
155
+ super();
156
+ this._supportsTransactions = options?.supportsTransactions ?? true;
157
+ this.supportsSavepoints = this._supportsTransactions;
158
+ }
159
+ // ===========================================================================
160
+ // SQL Fragment Hooks
161
+ // ===========================================================================
162
+ buildNumberListFilter(values) {
163
+ const list = sql.join(values.map((v) => sql `${v}`), sql `, `);
164
+ return sql `IN (${list})`;
165
+ }
166
+ buildStringListFilter(values) {
167
+ const list = sql.join(values.map((v) => sql `${v}`), sql `, `);
168
+ return sql `IN (${list})`;
169
+ }
170
+ // ===========================================================================
171
+ // Schema Setup
172
+ // ===========================================================================
173
+ async ensureSyncSchema(db) {
174
+ await sql `PRAGMA foreign_keys = ON`.execute(db);
175
+ const nowIso = sql `(strftime('%Y-%m-%dT%H:%M:%fZ','now'))`;
176
+ // sync_commits table
177
+ await db.schema
178
+ .createTable('sync_commits')
179
+ .ifNotExists()
180
+ .addColumn('commit_seq', 'integer', (col) => col.primaryKey().autoIncrement())
181
+ .addColumn('partition_id', 'text', (col) => col.notNull().defaultTo('default'))
182
+ .addColumn('actor_id', 'text', (col) => col.notNull())
183
+ .addColumn('client_id', 'text', (col) => col.notNull())
184
+ .addColumn('client_commit_id', 'text', (col) => col.notNull())
185
+ .addColumn('created_at', 'text', (col) => col.notNull().defaultTo(nowIso))
186
+ .addColumn('meta', 'json')
187
+ .addColumn('result_json', 'json')
188
+ .addColumn('change_count', 'integer', (col) => col.notNull().defaultTo(0))
189
+ .addColumn('commit_digest', 'text')
190
+ .addColumn('commit_chain_root', 'text')
191
+ .addColumn('affected_tables', 'text', (col) => col.notNull().defaultTo('[]'))
192
+ .execute();
193
+ await ensurePartitionColumn(db, 'sync_commits');
194
+ await ensureCommitVerificationColumns(db);
195
+ await sql `DROP INDEX IF EXISTS idx_sync_commits_client_commit`.execute(db);
196
+ await sql `CREATE UNIQUE INDEX IF NOT EXISTS idx_sync_commits_client_commit
197
+ ON sync_commits(partition_id, client_id, client_commit_id)`.execute(db);
198
+ await sql `CREATE INDEX IF NOT EXISTS idx_sync_commits_partition_client_commit_seq
199
+ ON sync_commits(partition_id, client_id, commit_seq)`.execute(db);
200
+ // sync_table_commits table (index of which commits affect which tables)
201
+ await db.schema
202
+ .createTable('sync_table_commits')
203
+ .ifNotExists()
204
+ .addColumn('partition_id', 'text', (col) => col.notNull().defaultTo('default'))
205
+ .addColumn('table', 'text', (col) => col.notNull())
206
+ .addColumn('commit_seq', 'integer', (col) => col.notNull().references('sync_commits.commit_seq').onDelete('cascade'))
207
+ .addPrimaryKeyConstraint('sync_table_commits_pk', [
208
+ 'partition_id',
209
+ 'table',
210
+ 'commit_seq',
211
+ ])
212
+ .execute();
213
+ await ensurePartitionColumn(db, 'sync_table_commits');
214
+ // Ensure unique index matches ON CONFLICT clause in push.ts
215
+ // (needed when migrating from old schema where PK was only (table, commit_seq))
216
+ await sql `CREATE UNIQUE INDEX IF NOT EXISTS idx_sync_table_commits_partition_pk
217
+ ON sync_table_commits(partition_id, "table", commit_seq)`.execute(db);
218
+ await sql `CREATE INDEX IF NOT EXISTS idx_sync_table_commits_commit_seq
219
+ ON sync_table_commits(partition_id, commit_seq)`.execute(db);
220
+ // sync_scope_commits table (index of which commits affect table/scope routes)
221
+ await db.schema
222
+ .createTable('sync_scope_commits')
223
+ .ifNotExists()
224
+ .addColumn('partition_id', 'text', (col) => col.notNull().defaultTo('default'))
225
+ .addColumn('table', 'text', (col) => col.notNull())
226
+ .addColumn('scope_key', 'text', (col) => col.notNull())
227
+ .addColumn('commit_seq', 'integer', (col) => col.notNull().references('sync_commits.commit_seq').onDelete('cascade'))
228
+ .addPrimaryKeyConstraint('sync_scope_commits_pk', [
229
+ 'partition_id',
230
+ 'table',
231
+ 'scope_key',
232
+ 'commit_seq',
233
+ ])
234
+ .execute();
235
+ await ensurePartitionColumn(db, 'sync_scope_commits');
236
+ await sql `CREATE UNIQUE INDEX IF NOT EXISTS idx_sync_scope_commits_partition_pk
237
+ ON sync_scope_commits(partition_id, "table", scope_key, commit_seq)`.execute(db);
238
+ await sql `CREATE INDEX IF NOT EXISTS idx_sync_scope_commits_commit_seq
239
+ ON sync_scope_commits(partition_id, commit_seq)`.execute(db);
240
+ // sync_changes table - uses JSON for scopes
241
+ await db.schema
242
+ .createTable('sync_changes')
243
+ .ifNotExists()
244
+ .addColumn('change_id', 'integer', (col) => col.primaryKey().autoIncrement())
245
+ .addColumn('partition_id', 'text', (col) => col.notNull().defaultTo('default'))
246
+ .addColumn('commit_seq', 'integer', (col) => col.notNull().references('sync_commits.commit_seq').onDelete('cascade'))
247
+ .addColumn('table', 'text', (col) => col.notNull())
248
+ .addColumn('row_id', 'text', (col) => col.notNull())
249
+ .addColumn('op', 'text', (col) => col.notNull())
250
+ .addColumn('row_json', 'json')
251
+ .addColumn('row_version', 'integer')
252
+ .addColumn('scopes', 'json', (col) => col.notNull())
253
+ .execute();
254
+ await ensurePartitionColumn(db, 'sync_changes');
255
+ await sql `CREATE INDEX IF NOT EXISTS idx_sync_changes_commit_seq
256
+ ON sync_changes(partition_id, commit_seq)`.execute(db);
257
+ await sql `CREATE INDEX IF NOT EXISTS idx_sync_changes_table
258
+ ON sync_changes(partition_id, "table")`.execute(db);
259
+ await sql `CREATE INDEX IF NOT EXISTS idx_sync_changes_table_commit_seq_change_id
260
+ ON sync_changes(partition_id, "table", commit_seq, change_id)`.execute(db);
261
+ // sync_client_cursors table
262
+ await db.schema
263
+ .createTable('sync_client_cursors')
264
+ .ifNotExists()
265
+ .addColumn('partition_id', 'text', (col) => col.notNull().defaultTo('default'))
266
+ .addColumn('client_id', 'text', (col) => col.notNull())
267
+ .addColumn('actor_id', 'text', (col) => col.notNull())
268
+ .addColumn('cursor', 'integer', (col) => col.notNull().defaultTo(0))
269
+ .addColumn('effective_scopes', 'json', (col) => col.notNull().defaultTo('{}'))
270
+ .addColumn('realtime_subscriptions', 'json')
271
+ .addColumn('updated_at', 'text', (col) => col.notNull().defaultTo(nowIso))
272
+ .addPrimaryKeyConstraint('sync_client_cursors_pk', [
273
+ 'partition_id',
274
+ 'client_id',
275
+ ])
276
+ .execute();
277
+ await ensurePartitionColumn(db, 'sync_client_cursors');
278
+ try {
279
+ await sql `ALTER TABLE sync_client_cursors ADD COLUMN realtime_subscriptions json`.execute(db);
280
+ }
281
+ catch {
282
+ // Ignore when column already exists.
283
+ }
284
+ // Ensure unique index matches ON CONFLICT clause in recordClientCursor
285
+ // (needed when migrating from old schema where PK was only (client_id))
286
+ await sql `CREATE UNIQUE INDEX IF NOT EXISTS idx_sync_client_cursors_partition_pk
287
+ ON sync_client_cursors(partition_id, client_id)`.execute(db);
288
+ await sql `CREATE INDEX IF NOT EXISTS idx_sync_client_cursors_updated_at
289
+ ON sync_client_cursors(updated_at)`.execute(db);
290
+ // sync_snapshot_chunks table
291
+ await db.schema
292
+ .createTable('sync_snapshot_chunks')
293
+ .ifNotExists()
294
+ .addColumn('chunk_id', 'text', (col) => col.primaryKey())
295
+ .addColumn('partition_id', 'text', (col) => col.notNull().defaultTo('default'))
296
+ .addColumn('scope_key', 'text', (col) => col.notNull())
297
+ .addColumn('scope', 'text', (col) => col.notNull())
298
+ .addColumn('as_of_commit_seq', 'integer', (col) => col.notNull())
299
+ .addColumn('row_cursor', 'text', (col) => col.notNull().defaultTo(''))
300
+ .addColumn('row_limit', 'integer', (col) => col.notNull())
301
+ .addColumn('next_row_cursor', 'text')
302
+ .addColumn('is_last_page', 'integer', (col) => col.notNull().defaultTo(0))
303
+ .addColumn('encoding', 'text', (col) => col.notNull())
304
+ .addColumn('compression', 'text', (col) => col.notNull())
305
+ .addColumn('sha256', 'text', (col) => col.notNull())
306
+ .addColumn('byte_length', 'integer', (col) => col.notNull())
307
+ .addColumn('blob_hash', 'text', (col) => col.notNull().defaultTo(''))
308
+ .addColumn('body', 'blob') // Deprecated: use blob storage
309
+ .addColumn('created_at', 'text', (col) => col.notNull().defaultTo(nowIso))
310
+ .addColumn('expires_at', 'text', (col) => col.notNull())
311
+ .execute();
312
+ await ensurePartitionColumn(db, 'sync_snapshot_chunks');
313
+ await ensureSnapshotChunkContinuationColumns(db);
314
+ await sql `CREATE INDEX IF NOT EXISTS idx_sync_snapshot_chunks_expires_at
315
+ ON sync_snapshot_chunks(expires_at)`.execute(db);
316
+ await sql `CREATE UNIQUE INDEX IF NOT EXISTS idx_sync_snapshot_chunks_page_key
317
+ ON sync_snapshot_chunks(partition_id, scope_key, scope, as_of_commit_seq, row_cursor, row_limit, encoding, compression)`.execute(db);
318
+ // sync_snapshot_artifacts table. Artifact bodies live in object storage;
319
+ // this table owns scoped eligibility and manifest metadata.
320
+ await db.schema
321
+ .createTable('sync_snapshot_artifacts')
322
+ .ifNotExists()
323
+ .addColumn('artifact_id', 'text', (col) => col.primaryKey())
324
+ .addColumn('partition_id', 'text', (col) => col.notNull().defaultTo('default'))
325
+ .addColumn('scope_key', 'text', (col) => col.notNull())
326
+ .addColumn('subscription_id', 'text', (col) => col.notNull())
327
+ .addColumn('table', 'text', (col) => col.notNull())
328
+ .addColumn('artifact_kind', 'text', (col) => col.notNull())
329
+ .addColumn('schema_version', 'text', (col) => col.notNull())
330
+ .addColumn('as_of_commit_seq', 'integer', (col) => col.notNull())
331
+ .addColumn('row_cursor', 'text', (col) => col.notNull().defaultTo(''))
332
+ .addColumn('row_limit', 'integer', (col) => col.notNull())
333
+ .addColumn('row_count', 'integer', (col) => col.notNull())
334
+ .addColumn('next_row_cursor', 'text')
335
+ .addColumn('is_first_page', 'integer', (col) => col.notNull().defaultTo(0))
336
+ .addColumn('is_last_page', 'integer', (col) => col.notNull().defaultTo(0))
337
+ .addColumn('compression', 'text', (col) => col.notNull())
338
+ .addColumn('sha256', 'text', (col) => col.notNull())
339
+ .addColumn('byte_length', 'integer', (col) => col.notNull())
340
+ .addColumn('manifest_digest', 'text', (col) => col.notNull())
341
+ .addColumn('feature_set_json', 'text', (col) => col.notNull())
342
+ .addColumn('manifest_json', 'text', (col) => col.notNull())
343
+ .addColumn('blob_hash', 'text', (col) => col.notNull())
344
+ .addColumn('created_at', 'text', (col) => col.notNull().defaultTo(nowIso))
345
+ .addColumn('expires_at', 'text', (col) => col.notNull())
346
+ .execute();
347
+ await sql `CREATE INDEX IF NOT EXISTS idx_sync_snapshot_artifacts_expires_at
348
+ ON sync_snapshot_artifacts(expires_at)`.execute(db);
349
+ await sql `CREATE UNIQUE INDEX IF NOT EXISTS idx_sync_snapshot_artifacts_page_key
350
+ ON sync_snapshot_artifacts(partition_id, scope_key, subscription_id, "table", as_of_commit_seq, row_cursor, row_limit, artifact_kind, schema_version, compression)`.execute(db);
351
+ // Encrypted CRDT system tables. These are shared by all encrypted CRDT
352
+ // fields and are exposed through hidden handlers, not app query builders.
353
+ await db.schema
354
+ .createTable('sync_crdt_updates')
355
+ .ifNotExists()
356
+ .addColumn('seq', 'integer', (col) => col.primaryKey().autoIncrement())
357
+ .addColumn('partition_id', 'text', (col) => col.notNull().defaultTo('default'))
358
+ .addColumn('stream_id', 'text', (col) => col.notNull())
359
+ .addColumn('app_table', 'text', (col) => col.notNull())
360
+ .addColumn('row_id', 'text', (col) => col.notNull())
361
+ .addColumn('field_name', 'text', (col) => col.notNull())
362
+ .addColumn('update_id', 'text', (col) => col.notNull())
363
+ .addColumn('actor_id', 'text')
364
+ .addColumn('client_id', 'text')
365
+ .addColumn('key_id', 'text', (col) => col.notNull())
366
+ .addColumn('ciphertext', 'text', (col) => col.notNull())
367
+ .addColumn('scopes', 'json', (col) => col.notNull().defaultTo('{}'))
368
+ .addColumn('created_at', 'text', (col) => col.notNull().defaultTo(nowIso))
369
+ .execute();
370
+ await ensurePartitionColumn(db, 'sync_crdt_updates');
371
+ await sql `CREATE UNIQUE INDEX IF NOT EXISTS idx_sync_crdt_updates_update_id
372
+ ON sync_crdt_updates(partition_id, update_id)`.execute(db);
373
+ await sql `CREATE INDEX IF NOT EXISTS idx_sync_crdt_updates_stream_seq
374
+ ON sync_crdt_updates(partition_id, stream_id, seq)`.execute(db);
375
+ await sql `CREATE INDEX IF NOT EXISTS idx_sync_crdt_updates_scope_table
376
+ ON sync_crdt_updates(partition_id, app_table, row_id, field_name)`.execute(db);
377
+ await db.schema
378
+ .createTable('sync_crdt_checkpoints')
379
+ .ifNotExists()
380
+ .addColumn('seq', 'integer', (col) => col.primaryKey().autoIncrement())
381
+ .addColumn('partition_id', 'text', (col) => col.notNull().defaultTo('default'))
382
+ .addColumn('stream_id', 'text', (col) => col.notNull())
383
+ .addColumn('app_table', 'text', (col) => col.notNull())
384
+ .addColumn('row_id', 'text', (col) => col.notNull())
385
+ .addColumn('field_name', 'text', (col) => col.notNull())
386
+ .addColumn('checkpoint_id', 'text', (col) => col.notNull())
387
+ .addColumn('covers_seq', 'integer', (col) => col.notNull())
388
+ .addColumn('actor_id', 'text')
389
+ .addColumn('client_id', 'text')
390
+ .addColumn('key_id', 'text', (col) => col.notNull())
391
+ .addColumn('ciphertext', 'text', (col) => col.notNull())
392
+ .addColumn('scopes', 'json', (col) => col.notNull().defaultTo('{}'))
393
+ .addColumn('created_at', 'text', (col) => col.notNull().defaultTo(nowIso))
394
+ .execute();
395
+ await ensurePartitionColumn(db, 'sync_crdt_checkpoints');
396
+ await sql `CREATE UNIQUE INDEX IF NOT EXISTS idx_sync_crdt_checkpoints_checkpoint_id
397
+ ON sync_crdt_checkpoints(partition_id, checkpoint_id)`.execute(db);
398
+ await sql `CREATE INDEX IF NOT EXISTS idx_sync_crdt_checkpoints_stream_covers
399
+ ON sync_crdt_checkpoints(partition_id, stream_id, covers_seq)`.execute(db);
400
+ await sql `CREATE INDEX IF NOT EXISTS idx_sync_crdt_checkpoints_scope_table
401
+ ON sync_crdt_checkpoints(partition_id, app_table, row_id, field_name)`.execute(db);
402
+ // Cleanup orphaned rows
403
+ await sql `
404
+ DELETE FROM sync_table_commits
405
+ WHERE commit_seq NOT IN (SELECT commit_seq FROM sync_commits)
406
+ `.execute(db);
407
+ await sql `
408
+ DELETE FROM sync_changes
409
+ WHERE commit_seq NOT IN (SELECT commit_seq FROM sync_commits)
410
+ `.execute(db);
411
+ }
412
+ // ===========================================================================
413
+ // Transaction Control
414
+ // ===========================================================================
415
+ async executeInTransaction(db, fn) {
416
+ if (isActiveTransaction(db)) {
417
+ if (!this._supportsTransactions) {
418
+ return fn(db);
419
+ }
420
+ const savepoint = createSavepointName();
421
+ await sql.raw(`SAVEPOINT ${savepoint}`).execute(db);
422
+ try {
423
+ const result = await fn(db);
424
+ await sql.raw(`RELEASE SAVEPOINT ${savepoint}`).execute(db);
425
+ return result;
426
+ }
427
+ catch (error) {
428
+ await sql.raw(`ROLLBACK TO SAVEPOINT ${savepoint}`).execute(db);
429
+ await sql.raw(`RELEASE SAVEPOINT ${savepoint}`).execute(db);
430
+ throw error;
431
+ }
432
+ }
433
+ if (this._supportsTransactions) {
434
+ return db.transaction().execute(fn);
435
+ }
436
+ return fn(db);
437
+ }
438
+ async setRepeatableRead(_trx) {
439
+ // SQLite uses serializable isolation by default in WAL mode.
440
+ }
441
+ // ===========================================================================
442
+ // Commit/Change Log Queries (dialect-specific)
443
+ // ===========================================================================
444
+ async readChangesForCommits(db, args) {
445
+ const partitionId = args.partitionId ?? 'default';
446
+ if (args.commitSeqs.length === 0)
447
+ return [];
448
+ const scopeFilter = buildScopeFilterSql(args.scopes, 'scopes');
449
+ const commitSeqsIn = sql.join(args.commitSeqs.map((seq) => sql `${seq}`), sql `, `);
450
+ // Fetch all changes for the table and commit sequences
451
+ const res = await sql `
452
+ SELECT commit_seq, "table", row_id, op, row_json, row_version, scopes
453
+ FROM sync_changes
454
+ WHERE commit_seq IN (${commitSeqsIn})
455
+ AND partition_id = ${partitionId}
456
+ AND "table" = ${args.table}
457
+ AND (${scopeFilter})
458
+ ORDER BY commit_seq ASC, change_id ASC
459
+ `.execute(db);
460
+ return res.rows.map((row) => ({
461
+ commit_seq: coerceNumber(row.commit_seq) ?? 0,
462
+ table: row.table,
463
+ row_id: row.row_id,
464
+ op: row.op,
465
+ row_json: parseJsonValue(row.row_json),
466
+ row_version: coerceNumber(row.row_version),
467
+ scopes: parseScopes(row.scopes),
468
+ }));
469
+ }
470
+ async readAuditRowHistory(db, args) {
471
+ const partitionId = args.partitionId ?? 'default';
472
+ const scopeFilter = buildScopeFilterSql(args.scopes, 'c.scopes');
473
+ const limit = Math.max(1, Math.min(200, args.limit));
474
+ const whereClauses = [
475
+ sql `c.partition_id = ${partitionId}`,
476
+ sql `cm.partition_id = ${partitionId}`,
477
+ sql `c."table" = ${args.table}`,
478
+ sql `c.row_id = ${args.rowId}`,
479
+ sql `(${scopeFilter})`,
480
+ ];
481
+ if (args.beforeCommitSeq !== undefined) {
482
+ whereClauses.push(sql `c.commit_seq < ${args.beforeCommitSeq}`);
483
+ }
484
+ if (args.afterCommitSeq !== undefined) {
485
+ whereClauses.push(sql `c.commit_seq >= ${args.afterCommitSeq}`);
486
+ }
487
+ const res = await sql `
488
+ SELECT
489
+ c.commit_seq,
490
+ cm.actor_id,
491
+ cm.client_id,
492
+ cm.client_commit_id,
493
+ cm.created_at,
494
+ c.change_id,
495
+ c."table",
496
+ c.row_id,
497
+ c.op,
498
+ c.row_json,
499
+ c.row_version,
500
+ c.scopes
501
+ FROM sync_changes c
502
+ JOIN sync_commits cm
503
+ ON cm.partition_id = c.partition_id
504
+ AND cm.commit_seq = c.commit_seq
505
+ WHERE ${sql.join(whereClauses, sql ` AND `)}
506
+ ORDER BY c.commit_seq DESC, c.change_id DESC
507
+ LIMIT ${limit + 1}
508
+ `.execute(db);
509
+ return res.rows.map((row) => ({
510
+ commit_seq: coerceNumber(row.commit_seq) ?? 0,
511
+ actor_id: row.actor_id,
512
+ client_id: row.client_id,
513
+ client_commit_id: row.client_commit_id,
514
+ created_at: coerceIsoString(row.created_at),
515
+ change_id: coerceNumber(row.change_id) ?? 0,
516
+ table: row.table,
517
+ row_id: row.row_id,
518
+ op: row.op,
519
+ row_json: parseJsonValue(row.row_json),
520
+ row_version: coerceNumber(row.row_version),
521
+ scopes: parseScopes(row.scopes),
522
+ }));
523
+ }
524
+ async readIncrementalPullRowsBatch(db, args) {
525
+ const partitionId = args.partitionId ?? 'default';
526
+ const limitCommits = Math.max(1, Math.min(1000, args.limitCommits));
527
+ const scopeFilter = buildScopeFilterSql(args.scopes, 'c.scopes');
528
+ const commitSeqs = await this.readScopeIndexedCommitSeqsForPull(db, {
529
+ partitionId,
530
+ table: args.table,
531
+ scopes: args.scopes,
532
+ cursor: args.cursor,
533
+ limitCommits,
534
+ });
535
+ if (commitSeqs.length === 0)
536
+ return [];
537
+ const scannedMaxCommitSeq = commitSeqs[commitSeqs.length - 1] ?? args.cursor;
538
+ const commitSeqsIn = sql.join(commitSeqs.map((seq) => sql `${seq}`), sql `, `);
539
+ // Get commits and changes for these commit_seqs
540
+ const changesRes = await sql `
541
+ SELECT
542
+ cm.commit_seq,
543
+ cm.actor_id,
544
+ cm.created_at,
545
+ cm.commit_digest,
546
+ cm.commit_chain_root,
547
+ c.change_id,
548
+ c."table",
549
+ c.row_id,
550
+ c.op,
551
+ c.row_json,
552
+ c.row_version,
553
+ c.scopes
554
+ FROM sync_commits cm
555
+ JOIN sync_changes c ON c.commit_seq = cm.commit_seq
556
+ WHERE cm.commit_seq IN (${commitSeqsIn})
557
+ AND cm.partition_id = ${partitionId}
558
+ AND c.partition_id = ${partitionId}
559
+ AND c."table" = ${args.table}
560
+ AND (${scopeFilter})
561
+ ORDER BY cm.commit_seq ASC, c.change_id ASC
562
+ `.execute(db);
563
+ return changesRes.rows.map((row) => ({
564
+ commit_seq: coerceNumber(row.commit_seq) ?? 0,
565
+ scanned_max_commit_seq: scannedMaxCommitSeq,
566
+ actor_id: row.actor_id,
567
+ created_at: coerceIsoString(row.created_at),
568
+ commit_digest: row.commit_digest ?? null,
569
+ commit_chain_root: row.commit_chain_root ?? null,
570
+ change_id: coerceNumber(row.change_id) ?? 0,
571
+ table: row.table,
572
+ row_id: row.row_id,
573
+ op: row.op,
574
+ row_json: parseJsonValue(row.row_json),
575
+ row_version: coerceNumber(row.row_version),
576
+ scopes: parseScopes(row.scopes),
577
+ }));
578
+ }
579
+ async compactChanges(db, args) {
580
+ const cutoffIso = new Date(Date.now() - args.fullHistoryHours * 60 * 60 * 1000).toISOString();
581
+ const res = await sql `
582
+ WITH ranked AS (
583
+ SELECT
584
+ c.change_id,
585
+ row_number() OVER (
586
+ PARTITION BY c.partition_id, c."table", c.row_id, c.scopes
587
+ ORDER BY c.commit_seq DESC, c.change_id DESC
588
+ ) AS rn
589
+ FROM sync_changes c
590
+ JOIN sync_commits cm ON cm.commit_seq = c.commit_seq
591
+ WHERE cm.created_at < ${cutoffIso}
592
+ )
593
+ DELETE FROM sync_changes
594
+ WHERE change_id IN (SELECT change_id FROM ranked WHERE rn > 1)
595
+ `.execute(db);
596
+ const deleted = Number(res.numAffectedRows ?? 0);
597
+ // Remove routing index entries that no longer have any remaining changes
598
+ await sql `
599
+ DELETE FROM sync_scope_commits
600
+ WHERE commit_seq IN (
601
+ SELECT commit_seq
602
+ FROM sync_commits
603
+ WHERE created_at < ${cutoffIso}
604
+ AND partition_id = sync_scope_commits.partition_id
605
+ )
606
+ AND NOT EXISTS (
607
+ SELECT 1
608
+ FROM sync_changes c
609
+ WHERE c.commit_seq = sync_scope_commits.commit_seq
610
+ AND c.partition_id = sync_scope_commits.partition_id
611
+ AND c."table" = sync_scope_commits."table"
612
+ )
613
+ `.execute(db);
614
+ await sql `
615
+ DELETE FROM sync_table_commits
616
+ WHERE commit_seq IN (
617
+ SELECT commit_seq
618
+ FROM sync_commits
619
+ WHERE created_at < ${cutoffIso}
620
+ AND partition_id = sync_table_commits.partition_id
621
+ )
622
+ AND NOT EXISTS (
623
+ SELECT 1
624
+ FROM sync_changes c
625
+ WHERE c.commit_seq = sync_table_commits.commit_seq
626
+ AND c.partition_id = sync_table_commits.partition_id
627
+ AND c."table" = sync_table_commits."table"
628
+ )
629
+ `.execute(db);
630
+ return deleted;
631
+ }
632
+ // ===========================================================================
633
+ // Scope Conversion Helpers
634
+ // ===========================================================================
635
+ scopesToDb(scopes) {
636
+ return JSON.stringify(scopes);
637
+ }
638
+ dbToArray(value) {
639
+ return toStringArray(value);
640
+ }
641
+ arrayToDb(values) {
642
+ return JSON.stringify(values.filter((v) => v.length > 0));
643
+ }
644
+ // ===========================================================================
645
+ // Console Schema (Request Events)
646
+ // ===========================================================================
647
+ async ensureConsoleSchema(db) {
648
+ const nowIso = sql `(strftime('%Y-%m-%dT%H:%M:%fZ','now'))`;
649
+ await db.schema
650
+ .createTable('sync_request_events')
651
+ .ifNotExists()
652
+ .addColumn('event_id', 'integer', (col) => col.primaryKey().autoIncrement())
653
+ .addColumn('partition_id', 'text', (col) => col.notNull().defaultTo('default'))
654
+ .addColumn('request_id', 'text')
655
+ .addColumn('trace_id', 'text')
656
+ .addColumn('span_id', 'text')
657
+ .addColumn('event_type', 'text', (col) => col.notNull())
658
+ .addColumn('actor_id', 'text', (col) => col.notNull())
659
+ .addColumn('client_id', 'text', (col) => col.notNull())
660
+ .addColumn('transport_path', 'text', (col) => col.notNull().defaultTo('direct'))
661
+ .addColumn('sync_path', 'text', (col) => col.notNull().defaultTo('http-combined'))
662
+ .addColumn('status_code', 'integer', (col) => col.notNull())
663
+ .addColumn('outcome', 'text', (col) => col.notNull())
664
+ .addColumn('response_status', 'text', (col) => col.notNull().defaultTo('unknown'))
665
+ .addColumn('error_code', 'text')
666
+ .addColumn('duration_ms', 'integer', (col) => col.notNull())
667
+ .addColumn('commit_seq', 'integer')
668
+ .addColumn('operation_count', 'integer')
669
+ .addColumn('row_count', 'integer')
670
+ .addColumn('subscription_count', 'integer')
671
+ .addColumn('scopes_summary', 'text')
672
+ .addColumn('response_summary', 'text')
673
+ .addColumn('tables', 'text', (col) => col.notNull().defaultTo('[]'))
674
+ .addColumn('error_message', 'text')
675
+ .addColumn('payload_ref', 'text')
676
+ .addColumn('created_at', 'text', (col) => col.notNull().defaultTo(nowIso))
677
+ .execute();
678
+ await ensureConsoleEventColumns(db);
679
+ await sql `CREATE INDEX IF NOT EXISTS idx_sync_request_events_created_at
680
+ ON sync_request_events(created_at DESC)`.execute(db);
681
+ await sql `CREATE INDEX IF NOT EXISTS idx_sync_request_events_event_type
682
+ ON sync_request_events(event_type)`.execute(db);
683
+ await sql `CREATE INDEX IF NOT EXISTS idx_sync_request_events_client_id
684
+ ON sync_request_events(client_id)`.execute(db);
685
+ await sql `CREATE INDEX IF NOT EXISTS idx_sync_request_events_request_id
686
+ ON sync_request_events(request_id)`.execute(db);
687
+ await sql `CREATE INDEX IF NOT EXISTS idx_sync_request_events_trace_id
688
+ ON sync_request_events(trace_id)`.execute(db);
689
+ await sql `CREATE INDEX IF NOT EXISTS idx_sync_request_events_partition_created_at
690
+ ON sync_request_events(partition_id, created_at DESC)`.execute(db);
691
+ await db.schema
692
+ .createTable('sync_request_payloads')
693
+ .ifNotExists()
694
+ .addColumn('payload_ref', 'text', (col) => col.primaryKey())
695
+ .addColumn('partition_id', 'text', (col) => col.notNull().defaultTo('default'))
696
+ .addColumn('request_payload', 'text', (col) => col.notNull())
697
+ .addColumn('response_payload', 'text')
698
+ .addColumn('created_at', 'text', (col) => col.notNull().defaultTo(nowIso))
699
+ .execute();
700
+ await sql `CREATE INDEX IF NOT EXISTS idx_sync_request_payloads_created_at
701
+ ON sync_request_payloads(created_at DESC)`.execute(db);
702
+ await sql `CREATE INDEX IF NOT EXISTS idx_sync_request_payloads_partition_created_at
703
+ ON sync_request_payloads(partition_id, created_at DESC)`.execute(db);
704
+ await db.schema
705
+ .createTable('sync_operation_events')
706
+ .ifNotExists()
707
+ .addColumn('operation_id', 'integer', (col) => col.primaryKey().autoIncrement())
708
+ .addColumn('operation_type', 'text', (col) => col.notNull())
709
+ .addColumn('console_user_id', 'text')
710
+ .addColumn('partition_id', 'text')
711
+ .addColumn('target_client_id', 'text')
712
+ .addColumn('request_payload', 'text')
713
+ .addColumn('result_payload', 'text')
714
+ .addColumn('created_at', 'text', (col) => col.notNull().defaultTo(nowIso))
715
+ .execute();
716
+ await sql `CREATE INDEX IF NOT EXISTS idx_sync_operation_events_created_at
717
+ ON sync_operation_events(created_at DESC)`.execute(db);
718
+ await sql `CREATE INDEX IF NOT EXISTS idx_sync_operation_events_type
719
+ ON sync_operation_events(operation_type)`.execute(db);
720
+ await db.schema
721
+ .createTable('sync_realtime_events')
722
+ .ifNotExists()
723
+ .addColumn('event_id', 'integer', (col) => col.primaryKey().autoIncrement())
724
+ .addColumn('partition_id', 'text', (col) => col.notNull().defaultTo('default'))
725
+ .addColumn('actor_id', 'text', (col) => col.notNull())
726
+ .addColumn('client_id', 'text', (col) => col.notNull())
727
+ .addColumn('transport_path', 'text', (col) => col.notNull().defaultTo('direct'))
728
+ .addColumn('event_type', 'text', (col) => col.notNull())
729
+ .addColumn('reason', 'text')
730
+ .addColumn('cursor', 'integer')
731
+ .addColumn('latest_cursor', 'integer')
732
+ .addColumn('commit_seq', 'integer')
733
+ .addColumn('scope_count', 'integer')
734
+ .addColumn('skipped_count', 'integer')
735
+ .addColumn('sync_pack_encoding', 'text')
736
+ .addColumn('created_at', 'text', (col) => col.notNull().defaultTo(nowIso))
737
+ .execute();
738
+ await sql `CREATE INDEX IF NOT EXISTS idx_sync_realtime_events_created_at
739
+ ON sync_realtime_events(created_at DESC)`.execute(db);
740
+ await sql `CREATE INDEX IF NOT EXISTS idx_sync_realtime_events_partition_client_created_at
741
+ ON sync_realtime_events(partition_id, client_id, created_at DESC)`.execute(db);
742
+ await db.schema
743
+ .createTable('sync_client_diagnostic_snapshots')
744
+ .ifNotExists()
745
+ .addColumn('snapshot_id', 'integer', (col) => col.primaryKey().autoIncrement())
746
+ .addColumn('partition_id', 'text', (col) => col.notNull().defaultTo('default'))
747
+ .addColumn('client_id', 'text', (col) => col.notNull())
748
+ .addColumn('actor_id', 'text')
749
+ .addColumn('runtime_kind', 'text')
750
+ .addColumn('runtime_version', 'text')
751
+ .addColumn('schema_version', 'integer')
752
+ .addColumn('reported_at', 'text', (col) => col.notNull())
753
+ .addColumn('received_at', 'text', (col) => col.notNull().defaultTo(nowIso))
754
+ .addColumn('lifecycle_phase', 'text')
755
+ .addColumn('connection_state', 'text')
756
+ .addColumn('freshness_state', 'text', (col) => col.notNull())
757
+ .addColumn('health_max_severity', 'text')
758
+ .addColumn('diagnostic_codes_summary', 'text')
759
+ .addColumn('queue_summary', 'text')
760
+ .addColumn('timing_summary', 'text')
761
+ .addColumn('redaction_summary', 'text')
762
+ .addColumn('snapshot_json', 'text', (col) => col.notNull())
763
+ .execute();
764
+ await sql `CREATE INDEX IF NOT EXISTS idx_sync_client_diagnostic_snapshots_received_at
765
+ ON sync_client_diagnostic_snapshots(received_at DESC)`.execute(db);
766
+ await sql `CREATE INDEX IF NOT EXISTS idx_sync_client_diagnostic_snapshots_latest
767
+ ON sync_client_diagnostic_snapshots(partition_id, client_id, received_at DESC)`.execute(db);
768
+ await sql `CREATE INDEX IF NOT EXISTS idx_sync_client_diagnostic_snapshots_health
769
+ ON sync_client_diagnostic_snapshots(partition_id, health_max_severity, received_at DESC)`.execute(db);
770
+ // API Keys table
771
+ await db.schema
772
+ .createTable('sync_api_keys')
773
+ .ifNotExists()
774
+ .addColumn('key_id', 'text', (col) => col.primaryKey())
775
+ .addColumn('key_hash', 'text', (col) => col.notNull())
776
+ .addColumn('key_prefix', 'text', (col) => col.notNull())
777
+ .addColumn('name', 'text', (col) => col.notNull())
778
+ .addColumn('key_type', 'text', (col) => col.notNull())
779
+ .addColumn('scope_keys', 'text', (col) => col.defaultTo('[]'))
780
+ .addColumn('actor_id', 'text')
781
+ .addColumn('created_at', 'text', (col) => col.notNull().defaultTo(nowIso))
782
+ .addColumn('expires_at', 'text')
783
+ .addColumn('last_used_at', 'text')
784
+ .addColumn('revoked_at', 'text')
785
+ .execute();
786
+ await sql `CREATE INDEX IF NOT EXISTS idx_sync_api_keys_key_hash
787
+ ON sync_api_keys(key_hash)`.execute(db);
788
+ await sql `CREATE INDEX IF NOT EXISTS idx_sync_api_keys_key_type
789
+ ON sync_api_keys(key_type)`.execute(db);
790
+ }
791
+ }
792
+ export function createSqliteServerDialect(options) {
793
+ return new SqliteServerSyncDialect(options);
794
+ }
795
+ //# sourceMappingURL=index.js.map