@syncular/server 0.1.2 → 0.2.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 (758) hide show
  1. package/README.md +773 -13
  2. package/dist/admin.d.ts +136 -0
  3. package/dist/admin.js +168 -0
  4. package/dist/blob-handlers.d.ts +69 -0
  5. package/dist/blob-handlers.js +245 -0
  6. package/dist/blob-store.d.ts +111 -0
  7. package/dist/blob-store.js +0 -0
  8. package/dist/content-encoding.d.ts +27 -0
  9. package/dist/content-encoding.js +69 -0
  10. package/dist/context.d.ts +151 -0
  11. package/dist/context.js +21 -0
  12. package/dist/crdt-merger.d.ts +28 -0
  13. package/dist/crdt-merger.js +11 -0
  14. package/dist/d1-storage.d.ts +50 -0
  15. package/dist/d1-storage.js +0 -0
  16. package/dist/errors.d.ts +35 -9
  17. package/dist/errors.js +220 -11
  18. package/dist/events-ring.d.ts +55 -0
  19. package/dist/events-ring.js +96 -0
  20. package/dist/events.d.ts +231 -0
  21. package/dist/events.js +22 -0
  22. package/dist/frame-bytes.d.ts +20 -0
  23. package/dist/frame-bytes.js +75 -0
  24. package/dist/handler.d.ts +9 -0
  25. package/dist/handler.js +490 -0
  26. package/dist/index.d.ts +42 -33
  27. package/dist/index.js +45 -27
  28. package/dist/lease-store.d.ts +50 -0
  29. package/dist/lease-store.js +0 -0
  30. package/dist/pg-executor-pglite.d.ts +27 -0
  31. package/dist/pg-executor-pglite.js +33 -0
  32. package/dist/pg-executor.d.ts +67 -0
  33. package/dist/pg-executor.js +56 -0
  34. package/dist/postgres-fanout.d.ts +83 -0
  35. package/dist/postgres-fanout.js +71 -0
  36. package/dist/postgres-storage.d.ts +69 -0
  37. package/dist/postgres-storage.js +766 -0
  38. package/dist/prune.d.ts +24 -39
  39. package/dist/prune.js +44 -146
  40. package/dist/pull.d.ts +42 -67
  41. package/dist/pull.js +387 -1187
  42. package/dist/push.d.ts +31 -66
  43. package/dist/push.js +406 -655
  44. package/dist/realtime.d.ts +197 -0
  45. package/dist/realtime.js +848 -0
  46. package/dist/relational-rows.d.ts +229 -0
  47. package/dist/relational-rows.js +514 -0
  48. package/dist/s3-blob-store.d.ts +142 -0
  49. package/dist/s3-blob-store.js +458 -0
  50. package/dist/s3-segment-store.d.ts +95 -0
  51. package/dist/s3-segment-store.js +380 -0
  52. package/dist/schema.d.ts +82 -286
  53. package/dist/schema.js +133 -9
  54. package/dist/scopes.d.ts +48 -0
  55. package/dist/scopes.js +98 -0
  56. package/dist/segment-download.d.ts +14 -0
  57. package/dist/segment-download.js +125 -0
  58. package/dist/segment-store.d.ts +81 -0
  59. package/dist/segment-store.js +63 -0
  60. package/dist/signed-url.d.ts +139 -0
  61. package/dist/signed-url.js +143 -0
  62. package/dist/sigv4.d.ts +97 -0
  63. package/dist/sigv4.js +161 -0
  64. package/dist/sqlite-blob-store.d.ts +22 -0
  65. package/dist/sqlite-blob-store.js +86 -0
  66. package/dist/sqlite-dialect.d.ts +101 -0
  67. package/dist/sqlite-dialect.js +250 -0
  68. package/dist/sqlite-image.d.ts +27 -0
  69. package/dist/sqlite-image.js +83 -0
  70. package/dist/sqlite-lease-store.d.ts +21 -0
  71. package/dist/sqlite-lease-store.js +94 -0
  72. package/dist/sqlite-segment-store.d.ts +25 -0
  73. package/dist/sqlite-segment-store.js +115 -0
  74. package/dist/sqlite-storage.d.ts +47 -0
  75. package/dist/sqlite-storage.js +477 -0
  76. package/dist/storage.d.ts +252 -0
  77. package/dist/storage.js +1 -0
  78. package/dist/validate.d.ts +83 -0
  79. package/dist/validate.js +44 -0
  80. package/package.json +17 -325
  81. package/src/admin.ts +312 -0
  82. package/src/blob-handlers.ts +340 -0
  83. package/src/blob-store.ts +0 -0
  84. package/src/content-encoding.ts +94 -0
  85. package/src/context.ts +176 -0
  86. package/src/crdt-merger.ts +33 -0
  87. package/src/d1-storage.ts +0 -0
  88. package/src/errors.ts +241 -19
  89. package/src/events-ring.ts +116 -0
  90. package/src/events.ts +291 -0
  91. package/src/frame-bytes.ts +94 -0
  92. package/src/handler.ts +678 -0
  93. package/src/index.ts +44 -27
  94. package/src/lease-store.ts +0 -0
  95. package/src/pg-executor-pglite.ts +63 -0
  96. package/src/pg-executor.ts +87 -0
  97. package/src/postgres-fanout.ts +143 -0
  98. package/src/postgres-storage.ts +1182 -0
  99. package/src/prune.ts +63 -289
  100. package/src/pull.ts +505 -1805
  101. package/src/push.ts +623 -1006
  102. package/src/realtime.ts +1082 -0
  103. package/src/relational-rows.ts +633 -0
  104. package/src/s3-blob-store.ts +616 -0
  105. package/src/s3-segment-store.ts +519 -0
  106. package/src/schema.ts +242 -281
  107. package/src/scopes.ts +127 -0
  108. package/src/segment-download.ts +169 -0
  109. package/src/segment-store.ts +154 -0
  110. package/src/signed-url.ts +308 -0
  111. package/src/sigv4.ts +267 -0
  112. package/src/sqlite-blob-store.ts +125 -0
  113. package/src/sqlite-dialect.ts +337 -0
  114. package/src/sqlite-image.ts +124 -0
  115. package/src/sqlite-lease-store.ts +144 -0
  116. package/src/sqlite-segment-store.ts +204 -0
  117. package/src/sqlite-storage.ts +792 -0
  118. package/src/storage.ts +316 -0
  119. package/src/validate.ts +123 -0
  120. package/dist/auth-leases.d.ts +0 -85
  121. package/dist/auth-leases.d.ts.map +0 -1
  122. package/dist/auth-leases.js +0 -368
  123. package/dist/auth-leases.js.map +0 -1
  124. package/dist/better-sqlite3.d.ts +0 -22
  125. package/dist/better-sqlite3.d.ts.map +0 -1
  126. package/dist/better-sqlite3.js +0 -16
  127. package/dist/better-sqlite3.js.map +0 -1
  128. package/dist/blobs/access.d.ts +0 -35
  129. package/dist/blobs/access.d.ts.map +0 -1
  130. package/dist/blobs/access.js +0 -149
  131. package/dist/blobs/access.js.map +0 -1
  132. package/dist/blobs/adapters/database.d.ts +0 -100
  133. package/dist/blobs/adapters/database.d.ts.map +0 -1
  134. package/dist/blobs/adapters/database.js +0 -247
  135. package/dist/blobs/adapters/database.js.map +0 -1
  136. package/dist/blobs/index.d.ts +0 -9
  137. package/dist/blobs/index.d.ts.map +0 -1
  138. package/dist/blobs/index.js +0 -9
  139. package/dist/blobs/index.js.map +0 -1
  140. package/dist/blobs/manager.d.ts +0 -220
  141. package/dist/blobs/manager.d.ts.map +0 -1
  142. package/dist/blobs/manager.js +0 -625
  143. package/dist/blobs/manager.js.map +0 -1
  144. package/dist/blobs/migrate.d.ts +0 -27
  145. package/dist/blobs/migrate.d.ts.map +0 -1
  146. package/dist/blobs/migrate.js +0 -127
  147. package/dist/blobs/migrate.js.map +0 -1
  148. package/dist/blobs/types.d.ts +0 -58
  149. package/dist/blobs/types.d.ts.map +0 -1
  150. package/dist/blobs/types.js +0 -5
  151. package/dist/blobs/types.js.map +0 -1
  152. package/dist/bun-sqlite.d.ts +0 -19
  153. package/dist/bun-sqlite.d.ts.map +0 -1
  154. package/dist/bun-sqlite.js +0 -19
  155. package/dist/bun-sqlite.js.map +0 -1
  156. package/dist/clients.d.ts +0 -15
  157. package/dist/clients.d.ts.map +0 -1
  158. package/dist/clients.js +0 -7
  159. package/dist/clients.js.map +0 -1
  160. package/dist/cloudflare/durable-object.d.ts +0 -93
  161. package/dist/cloudflare/durable-object.d.ts.map +0 -1
  162. package/dist/cloudflare/durable-object.js +0 -210
  163. package/dist/cloudflare/durable-object.js.map +0 -1
  164. package/dist/cloudflare/index.d.ts +0 -22
  165. package/dist/cloudflare/index.d.ts.map +0 -1
  166. package/dist/cloudflare/index.js +0 -22
  167. package/dist/cloudflare/index.js.map +0 -1
  168. package/dist/cloudflare/r2.d.ts +0 -180
  169. package/dist/cloudflare/r2.d.ts.map +0 -1
  170. package/dist/cloudflare/r2.js +0 -258
  171. package/dist/cloudflare/r2.js.map +0 -1
  172. package/dist/cloudflare/scope-cache.d.ts +0 -54
  173. package/dist/cloudflare/scope-cache.d.ts.map +0 -1
  174. package/dist/cloudflare/scope-cache.js +0 -223
  175. package/dist/cloudflare/scope-cache.js.map +0 -1
  176. package/dist/cloudflare/sentry.d.ts +0 -47
  177. package/dist/cloudflare/sentry.d.ts.map +0 -1
  178. package/dist/cloudflare/sentry.js +0 -163
  179. package/dist/cloudflare/sentry.js.map +0 -1
  180. package/dist/cloudflare/worker.d.ts +0 -46
  181. package/dist/cloudflare/worker.d.ts.map +0 -1
  182. package/dist/cloudflare/worker.js +0 -63
  183. package/dist/cloudflare/worker.js.map +0 -1
  184. package/dist/commit-integrity.d.ts +0 -38
  185. package/dist/commit-integrity.d.ts.map +0 -1
  186. package/dist/commit-integrity.js +0 -260
  187. package/dist/commit-integrity.js.map +0 -1
  188. package/dist/compaction.d.ts +0 -27
  189. package/dist/compaction.d.ts.map +0 -1
  190. package/dist/compaction.js +0 -49
  191. package/dist/compaction.js.map +0 -1
  192. package/dist/crdt-yjs/index.d.ts +0 -99
  193. package/dist/crdt-yjs/index.d.ts.map +0 -1
  194. package/dist/crdt-yjs/index.js +0 -629
  195. package/dist/crdt-yjs/index.js.map +0 -1
  196. package/dist/d1.d.ts +0 -13
  197. package/dist/d1.d.ts.map +0 -1
  198. package/dist/d1.js +0 -14
  199. package/dist/d1.js.map +0 -1
  200. package/dist/dialect/base.d.ts +0 -93
  201. package/dist/dialect/base.d.ts.map +0 -1
  202. package/dist/dialect/base.js +0 -181
  203. package/dist/dialect/base.js.map +0 -1
  204. package/dist/dialect/helpers.d.ts +0 -16
  205. package/dist/dialect/helpers.d.ts.map +0 -1
  206. package/dist/dialect/helpers.js +0 -83
  207. package/dist/dialect/helpers.js.map +0 -1
  208. package/dist/dialect/index.d.ts +0 -7
  209. package/dist/dialect/index.d.ts.map +0 -1
  210. package/dist/dialect/index.js +0 -7
  211. package/dist/dialect/index.js.map +0 -1
  212. package/dist/dialect/types.d.ts +0 -187
  213. package/dist/dialect/types.d.ts.map +0 -1
  214. package/dist/dialect/types.js +0 -8
  215. package/dist/dialect/types.js.map +0 -1
  216. package/dist/encrypted-crdt.d.ts +0 -67
  217. package/dist/encrypted-crdt.d.ts.map +0 -1
  218. package/dist/encrypted-crdt.js +0 -426
  219. package/dist/encrypted-crdt.js.map +0 -1
  220. package/dist/errors.d.ts.map +0 -1
  221. package/dist/errors.js.map +0 -1
  222. package/dist/filesystem/index.d.ts +0 -44
  223. package/dist/filesystem/index.d.ts.map +0 -1
  224. package/dist/filesystem/index.js +0 -164
  225. package/dist/filesystem/index.js.map +0 -1
  226. package/dist/handlers/collection.d.ts +0 -20
  227. package/dist/handlers/collection.d.ts.map +0 -1
  228. package/dist/handlers/collection.js +0 -42
  229. package/dist/handlers/collection.js.map +0 -1
  230. package/dist/handlers/create-handler.d.ts +0 -156
  231. package/dist/handlers/create-handler.d.ts.map +0 -1
  232. package/dist/handlers/create-handler.js +0 -626
  233. package/dist/handlers/create-handler.js.map +0 -1
  234. package/dist/handlers/index.d.ts +0 -4
  235. package/dist/handlers/index.d.ts.map +0 -1
  236. package/dist/handlers/index.js +0 -4
  237. package/dist/handlers/index.js.map +0 -1
  238. package/dist/handlers/types.d.ts +0 -295
  239. package/dist/handlers/types.d.ts.map +0 -1
  240. package/dist/handlers/types.js +0 -2
  241. package/dist/handlers/types.js.map +0 -1
  242. package/dist/helpers/conflict.d.ts +0 -52
  243. package/dist/helpers/conflict.d.ts.map +0 -1
  244. package/dist/helpers/conflict.js +0 -49
  245. package/dist/helpers/conflict.js.map +0 -1
  246. package/dist/helpers/emitted-change.d.ts +0 -56
  247. package/dist/helpers/emitted-change.d.ts.map +0 -1
  248. package/dist/helpers/emitted-change.js +0 -46
  249. package/dist/helpers/emitted-change.js.map +0 -1
  250. package/dist/helpers/index.d.ts +0 -12
  251. package/dist/helpers/index.d.ts.map +0 -1
  252. package/dist/helpers/index.js +0 -12
  253. package/dist/helpers/index.js.map +0 -1
  254. package/dist/helpers/paginate.d.ts +0 -49
  255. package/dist/helpers/paginate.d.ts.map +0 -1
  256. package/dist/helpers/paginate.js +0 -54
  257. package/dist/helpers/paginate.js.map +0 -1
  258. package/dist/helpers/scope-authorization.d.ts +0 -7
  259. package/dist/helpers/scope-authorization.d.ts.map +0 -1
  260. package/dist/helpers/scope-authorization.js +0 -19
  261. package/dist/helpers/scope-authorization.js.map +0 -1
  262. package/dist/helpers/scope-commit-index.d.ts +0 -12
  263. package/dist/helpers/scope-commit-index.d.ts.map +0 -1
  264. package/dist/helpers/scope-commit-index.js +0 -35
  265. package/dist/helpers/scope-commit-index.js.map +0 -1
  266. package/dist/helpers/scope-strings.d.ts +0 -74
  267. package/dist/helpers/scope-strings.d.ts.map +0 -1
  268. package/dist/helpers/scope-strings.js +0 -82
  269. package/dist/helpers/scope-strings.js.map +0 -1
  270. package/dist/hono/api-key-auth.d.ts +0 -49
  271. package/dist/hono/api-key-auth.d.ts.map +0 -1
  272. package/dist/hono/api-key-auth.js +0 -108
  273. package/dist/hono/api-key-auth.js.map +0 -1
  274. package/dist/hono/audit-redaction.d.ts +0 -20
  275. package/dist/hono/audit-redaction.d.ts.map +0 -1
  276. package/dist/hono/audit-redaction.js +0 -85
  277. package/dist/hono/audit-redaction.js.map +0 -1
  278. package/dist/hono/blobs.d.ts +0 -75
  279. package/dist/hono/blobs.d.ts.map +0 -1
  280. package/dist/hono/blobs.js +0 -586
  281. package/dist/hono/blobs.js.map +0 -1
  282. package/dist/hono/console/gateway.d.ts +0 -42
  283. package/dist/hono/console/gateway.d.ts.map +0 -1
  284. package/dist/hono/console/gateway.js +0 -2158
  285. package/dist/hono/console/gateway.js.map +0 -1
  286. package/dist/hono/console/live-auth.d.ts +0 -7
  287. package/dist/hono/console/live-auth.d.ts.map +0 -1
  288. package/dist/hono/console/live-auth.js +0 -39
  289. package/dist/hono/console/live-auth.js.map +0 -1
  290. package/dist/hono/console/route-descriptor.d.ts +0 -6
  291. package/dist/hono/console/route-descriptor.d.ts.map +0 -1
  292. package/dist/hono/console/route-descriptor.js +0 -16
  293. package/dist/hono/console/route-descriptor.js.map +0 -1
  294. package/dist/hono/console/routes/api-keys.d.ts +0 -8
  295. package/dist/hono/console/routes/api-keys.d.ts.map +0 -1
  296. package/dist/hono/console/routes/api-keys.js +0 -575
  297. package/dist/hono/console/routes/api-keys.js.map +0 -1
  298. package/dist/hono/console/routes/clients.d.ts +0 -8
  299. package/dist/hono/console/routes/clients.d.ts.map +0 -1
  300. package/dist/hono/console/routes/clients.js +0 -322
  301. package/dist/hono/console/routes/clients.js.map +0 -1
  302. package/dist/hono/console/routes/commits.d.ts +0 -8
  303. package/dist/hono/console/routes/commits.d.ts.map +0 -1
  304. package/dist/hono/console/routes/commits.js +0 -882
  305. package/dist/hono/console/routes/commits.js.map +0 -1
  306. package/dist/hono/console/routes/context.d.ts +0 -188
  307. package/dist/hono/console/routes/context.d.ts.map +0 -1
  308. package/dist/hono/console/routes/context.js +0 -633
  309. package/dist/hono/console/routes/context.js.map +0 -1
  310. package/dist/hono/console/routes/events.d.ts +0 -8
  311. package/dist/hono/console/routes/events.d.ts.map +0 -1
  312. package/dist/hono/console/routes/events.js +0 -501
  313. package/dist/hono/console/routes/events.js.map +0 -1
  314. package/dist/hono/console/routes/maintenance.d.ts +0 -8
  315. package/dist/hono/console/routes/maintenance.d.ts.map +0 -1
  316. package/dist/hono/console/routes/maintenance.js +0 -341
  317. package/dist/hono/console/routes/maintenance.js.map +0 -1
  318. package/dist/hono/console/routes/shared.d.ts +0 -174
  319. package/dist/hono/console/routes/shared.d.ts.map +0 -1
  320. package/dist/hono/console/routes/shared.js +0 -583
  321. package/dist/hono/console/routes/shared.js.map +0 -1
  322. package/dist/hono/console/routes/stats.d.ts +0 -8
  323. package/dist/hono/console/routes/stats.d.ts.map +0 -1
  324. package/dist/hono/console/routes/stats.js +0 -295
  325. package/dist/hono/console/routes/stats.js.map +0 -1
  326. package/dist/hono/console/routes/storage.d.ts +0 -8
  327. package/dist/hono/console/routes/storage.d.ts.map +0 -1
  328. package/dist/hono/console/routes/storage.js +0 -121
  329. package/dist/hono/console/routes/storage.js.map +0 -1
  330. package/dist/hono/console/routes.d.ts +0 -36
  331. package/dist/hono/console/routes.d.ts.map +0 -1
  332. package/dist/hono/console/routes.js +0 -112
  333. package/dist/hono/console/routes.js.map +0 -1
  334. package/dist/hono/console/schema-errors.d.ts +0 -2
  335. package/dist/hono/console/schema-errors.d.ts.map +0 -1
  336. package/dist/hono/console/schema-errors.js +0 -17
  337. package/dist/hono/console/schema-errors.js.map +0 -1
  338. package/dist/hono/console/schemas.d.ts +0 -1515
  339. package/dist/hono/console/schemas.d.ts.map +0 -1
  340. package/dist/hono/console/schemas.js +0 -661
  341. package/dist/hono/console/schemas.js.map +0 -1
  342. package/dist/hono/console/types.d.ts +0 -213
  343. package/dist/hono/console/types.d.ts.map +0 -1
  344. package/dist/hono/console/types.js +0 -2
  345. package/dist/hono/console/types.js.map +0 -1
  346. package/dist/hono/console/ui.d.ts +0 -38
  347. package/dist/hono/console/ui.d.ts.map +0 -1
  348. package/dist/hono/console/ui.js +0 -43
  349. package/dist/hono/console/ui.js.map +0 -1
  350. package/dist/hono/create-server.d.ts +0 -71
  351. package/dist/hono/create-server.d.ts.map +0 -1
  352. package/dist/hono/create-server.js +0 -121
  353. package/dist/hono/create-server.js.map +0 -1
  354. package/dist/hono/errors.d.ts +0 -13
  355. package/dist/hono/errors.d.ts.map +0 -1
  356. package/dist/hono/errors.js +0 -21
  357. package/dist/hono/errors.js.map +0 -1
  358. package/dist/hono/index.d.ts +0 -20
  359. package/dist/hono/index.d.ts.map +0 -1
  360. package/dist/hono/index.js +0 -31
  361. package/dist/hono/index.js.map +0 -1
  362. package/dist/hono/openapi.d.ts +0 -72
  363. package/dist/hono/openapi.d.ts.map +0 -1
  364. package/dist/hono/openapi.js +0 -99
  365. package/dist/hono/openapi.js.map +0 -1
  366. package/dist/hono/proxy/connection-manager.d.ts +0 -78
  367. package/dist/hono/proxy/connection-manager.d.ts.map +0 -1
  368. package/dist/hono/proxy/connection-manager.js +0 -251
  369. package/dist/hono/proxy/connection-manager.js.map +0 -1
  370. package/dist/hono/proxy/index.d.ts +0 -8
  371. package/dist/hono/proxy/index.d.ts.map +0 -1
  372. package/dist/hono/proxy/index.js +0 -8
  373. package/dist/hono/proxy/index.js.map +0 -1
  374. package/dist/hono/proxy/routes.d.ts +0 -86
  375. package/dist/hono/proxy/routes.d.ts.map +0 -1
  376. package/dist/hono/proxy/routes.js +0 -183
  377. package/dist/hono/proxy/routes.js.map +0 -1
  378. package/dist/hono/rate-limit.d.ts +0 -101
  379. package/dist/hono/rate-limit.d.ts.map +0 -1
  380. package/dist/hono/rate-limit.js +0 -184
  381. package/dist/hono/rate-limit.js.map +0 -1
  382. package/dist/hono/realtime-sync-packs.d.ts +0 -43
  383. package/dist/hono/realtime-sync-packs.d.ts.map +0 -1
  384. package/dist/hono/realtime-sync-packs.js +0 -219
  385. package/dist/hono/realtime-sync-packs.js.map +0 -1
  386. package/dist/hono/routes/audit.d.ts +0 -12
  387. package/dist/hono/routes/audit.d.ts.map +0 -1
  388. package/dist/hono/routes/audit.js +0 -385
  389. package/dist/hono/routes/audit.js.map +0 -1
  390. package/dist/hono/routes/auth-leases.d.ts +0 -8
  391. package/dist/hono/routes/auth-leases.d.ts.map +0 -1
  392. package/dist/hono/routes/auth-leases.js +0 -88
  393. package/dist/hono/routes/auth-leases.js.map +0 -1
  394. package/dist/hono/routes/combined.d.ts +0 -8
  395. package/dist/hono/routes/combined.d.ts.map +0 -1
  396. package/dist/hono/routes/combined.js +0 -392
  397. package/dist/hono/routes/combined.js.map +0 -1
  398. package/dist/hono/routes/context.d.ts +0 -314
  399. package/dist/hono/routes/context.d.ts.map +0 -1
  400. package/dist/hono/routes/context.js +0 -1147
  401. package/dist/hono/routes/context.js.map +0 -1
  402. package/dist/hono/routes/health.d.ts +0 -8
  403. package/dist/hono/routes/health.d.ts.map +0 -1
  404. package/dist/hono/routes/health.js +0 -16
  405. package/dist/hono/routes/health.js.map +0 -1
  406. package/dist/hono/routes/realtime.d.ts +0 -9
  407. package/dist/hono/routes/realtime.d.ts.map +0 -1
  408. package/dist/hono/routes/realtime.js +0 -626
  409. package/dist/hono/routes/realtime.js.map +0 -1
  410. package/dist/hono/routes/shared.d.ts +0 -689
  411. package/dist/hono/routes/shared.d.ts.map +0 -1
  412. package/dist/hono/routes/shared.js +0 -972
  413. package/dist/hono/routes/shared.js.map +0 -1
  414. package/dist/hono/routes/snapshots.d.ts +0 -10
  415. package/dist/hono/routes/snapshots.d.ts.map +0 -1
  416. package/dist/hono/routes/snapshots.js +0 -281
  417. package/dist/hono/routes/snapshots.js.map +0 -1
  418. package/dist/hono/routes.d.ts +0 -19
  419. package/dist/hono/routes.d.ts.map +0 -1
  420. package/dist/hono/routes.js +0 -37
  421. package/dist/hono/routes.js.map +0 -1
  422. package/dist/hono/validation.d.ts +0 -5
  423. package/dist/hono/validation.d.ts.map +0 -1
  424. package/dist/hono/validation.js +0 -47
  425. package/dist/hono/validation.js.map +0 -1
  426. package/dist/hono/websocket-origin.d.ts +0 -9
  427. package/dist/hono/websocket-origin.d.ts.map +0 -1
  428. package/dist/hono/websocket-origin.js +0 -96
  429. package/dist/hono/websocket-origin.js.map +0 -1
  430. package/dist/hono/ws.d.ts +0 -341
  431. package/dist/hono/ws.d.ts.map +0 -1
  432. package/dist/hono/ws.js +0 -711
  433. package/dist/hono/ws.js.map +0 -1
  434. package/dist/index.d.ts.map +0 -1
  435. package/dist/index.js.map +0 -1
  436. package/dist/libsql.d.ts +0 -29
  437. package/dist/libsql.d.ts.map +0 -1
  438. package/dist/libsql.js +0 -25
  439. package/dist/libsql.js.map +0 -1
  440. package/dist/migrate.d.ts +0 -14
  441. package/dist/migrate.d.ts.map +0 -1
  442. package/dist/migrate.js +0 -13
  443. package/dist/migrate.js.map +0 -1
  444. package/dist/neon.d.ts +0 -21
  445. package/dist/neon.d.ts.map +0 -1
  446. package/dist/neon.js +0 -22
  447. package/dist/neon.js.map +0 -1
  448. package/dist/notify.d.ts +0 -77
  449. package/dist/notify.d.ts.map +0 -1
  450. package/dist/notify.js +0 -233
  451. package/dist/notify.js.map +0 -1
  452. package/dist/pglite.d.ts +0 -37
  453. package/dist/pglite.d.ts.map +0 -1
  454. package/dist/pglite.js +0 -37
  455. package/dist/pglite.js.map +0 -1
  456. package/dist/plugins/index.d.ts +0 -2
  457. package/dist/plugins/index.d.ts.map +0 -1
  458. package/dist/plugins/index.js +0 -2
  459. package/dist/plugins/index.js.map +0 -1
  460. package/dist/plugins/types.d.ts +0 -73
  461. package/dist/plugins/types.d.ts.map +0 -1
  462. package/dist/plugins/types.js +0 -30
  463. package/dist/plugins/types.js.map +0 -1
  464. package/dist/postgres/index.d.ts +0 -68
  465. package/dist/postgres/index.d.ts.map +0 -1
  466. package/dist/postgres/index.js +0 -924
  467. package/dist/postgres/index.js.map +0 -1
  468. package/dist/proxy/collection.d.ts +0 -7
  469. package/dist/proxy/collection.d.ts.map +0 -1
  470. package/dist/proxy/collection.js +0 -6
  471. package/dist/proxy/collection.js.map +0 -1
  472. package/dist/proxy/handler.d.ts +0 -42
  473. package/dist/proxy/handler.d.ts.map +0 -1
  474. package/dist/proxy/handler.js +0 -102
  475. package/dist/proxy/handler.js.map +0 -1
  476. package/dist/proxy/index.d.ts +0 -9
  477. package/dist/proxy/index.d.ts.map +0 -1
  478. package/dist/proxy/index.js +0 -14
  479. package/dist/proxy/index.js.map +0 -1
  480. package/dist/proxy/mutation-detector.d.ts +0 -35
  481. package/dist/proxy/mutation-detector.d.ts.map +0 -1
  482. package/dist/proxy/mutation-detector.js +0 -246
  483. package/dist/proxy/mutation-detector.js.map +0 -1
  484. package/dist/proxy/oplog.d.ts +0 -30
  485. package/dist/proxy/oplog.d.ts.map +0 -1
  486. package/dist/proxy/oplog.js +0 -137
  487. package/dist/proxy/oplog.js.map +0 -1
  488. package/dist/proxy/types.d.ts +0 -44
  489. package/dist/proxy/types.d.ts.map +0 -1
  490. package/dist/proxy/types.js +0 -7
  491. package/dist/proxy/types.js.map +0 -1
  492. package/dist/prune.d.ts.map +0 -1
  493. package/dist/prune.js.map +0 -1
  494. package/dist/pull.d.ts.map +0 -1
  495. package/dist/pull.js.map +0 -1
  496. package/dist/push.d.ts.map +0 -1
  497. package/dist/push.js.map +0 -1
  498. package/dist/realtime/in-memory.d.ts +0 -13
  499. package/dist/realtime/in-memory.d.ts.map +0 -1
  500. package/dist/realtime/in-memory.js +0 -28
  501. package/dist/realtime/in-memory.js.map +0 -1
  502. package/dist/realtime/index.d.ts +0 -4
  503. package/dist/realtime/index.d.ts.map +0 -1
  504. package/dist/realtime/index.js +0 -3
  505. package/dist/realtime/index.js.map +0 -1
  506. package/dist/realtime/types.d.ts +0 -62
  507. package/dist/realtime/types.d.ts.map +0 -1
  508. package/dist/realtime/types.js +0 -19
  509. package/dist/realtime/types.js.map +0 -1
  510. package/dist/relay/client-role/forward-engine.d.ts +0 -63
  511. package/dist/relay/client-role/forward-engine.d.ts.map +0 -1
  512. package/dist/relay/client-role/forward-engine.js +0 -267
  513. package/dist/relay/client-role/forward-engine.js.map +0 -1
  514. package/dist/relay/client-role/index.d.ts +0 -9
  515. package/dist/relay/client-role/index.d.ts.map +0 -1
  516. package/dist/relay/client-role/index.js +0 -9
  517. package/dist/relay/client-role/index.js.map +0 -1
  518. package/dist/relay/client-role/pull-engine.d.ts +0 -72
  519. package/dist/relay/client-role/pull-engine.d.ts.map +0 -1
  520. package/dist/relay/client-role/pull-engine.js +0 -249
  521. package/dist/relay/client-role/pull-engine.js.map +0 -1
  522. package/dist/relay/client-role/sequence-mapper.d.ts +0 -65
  523. package/dist/relay/client-role/sequence-mapper.d.ts.map +0 -1
  524. package/dist/relay/client-role/sequence-mapper.js +0 -161
  525. package/dist/relay/client-role/sequence-mapper.js.map +0 -1
  526. package/dist/relay/evaluation/relay-paths.d.ts +0 -41
  527. package/dist/relay/evaluation/relay-paths.d.ts.map +0 -1
  528. package/dist/relay/evaluation/relay-paths.js +0 -504
  529. package/dist/relay/evaluation/relay-paths.js.map +0 -1
  530. package/dist/relay/evaluation/rust-boundary.d.ts +0 -47
  531. package/dist/relay/evaluation/rust-boundary.d.ts.map +0 -1
  532. package/dist/relay/evaluation/rust-boundary.js +0 -220
  533. package/dist/relay/evaluation/rust-boundary.js.map +0 -1
  534. package/dist/relay/index.d.ts +0 -37
  535. package/dist/relay/index.d.ts.map +0 -1
  536. package/dist/relay/index.js +0 -44
  537. package/dist/relay/index.js.map +0 -1
  538. package/dist/relay/migrate.d.ts +0 -18
  539. package/dist/relay/migrate.d.ts.map +0 -1
  540. package/dist/relay/migrate.js +0 -99
  541. package/dist/relay/migrate.js.map +0 -1
  542. package/dist/relay/mode-manager.d.ts +0 -60
  543. package/dist/relay/mode-manager.d.ts.map +0 -1
  544. package/dist/relay/mode-manager.js +0 -114
  545. package/dist/relay/mode-manager.js.map +0 -1
  546. package/dist/relay/realtime.d.ts +0 -90
  547. package/dist/relay/realtime.d.ts.map +0 -1
  548. package/dist/relay/realtime.js +0 -147
  549. package/dist/relay/realtime.js.map +0 -1
  550. package/dist/relay/relay.d.ts +0 -190
  551. package/dist/relay/relay.d.ts.map +0 -1
  552. package/dist/relay/relay.js +0 -320
  553. package/dist/relay/relay.js.map +0 -1
  554. package/dist/relay/schema.d.ts +0 -158
  555. package/dist/relay/schema.d.ts.map +0 -1
  556. package/dist/relay/schema.js +0 -7
  557. package/dist/relay/schema.js.map +0 -1
  558. package/dist/relay/server-role/index.d.ts +0 -56
  559. package/dist/relay/server-role/index.d.ts.map +0 -1
  560. package/dist/relay/server-role/index.js +0 -193
  561. package/dist/relay/server-role/index.js.map +0 -1
  562. package/dist/relay/server-role/pull.d.ts +0 -27
  563. package/dist/relay/server-role/pull.d.ts.map +0 -1
  564. package/dist/relay/server-role/pull.js +0 -24
  565. package/dist/relay/server-role/pull.js.map +0 -1
  566. package/dist/relay/server-role/push.d.ts +0 -29
  567. package/dist/relay/server-role/push.d.ts.map +0 -1
  568. package/dist/relay/server-role/push.js +0 -122
  569. package/dist/relay/server-role/push.js.map +0 -1
  570. package/dist/s3/index.d.ts +0 -83
  571. package/dist/s3/index.d.ts.map +0 -1
  572. package/dist/s3/index.js +0 -223
  573. package/dist/s3/index.js.map +0 -1
  574. package/dist/schema.d.ts.map +0 -1
  575. package/dist/schema.js.map +0 -1
  576. package/dist/service-worker/index.d.ts +0 -114
  577. package/dist/service-worker/index.d.ts.map +0 -1
  578. package/dist/service-worker/index.js +0 -487
  579. package/dist/service-worker/index.js.map +0 -1
  580. package/dist/snapshot-artifacts/sqlite-bun.d.ts +0 -15
  581. package/dist/snapshot-artifacts/sqlite-bun.d.ts.map +0 -1
  582. package/dist/snapshot-artifacts/sqlite-bun.js +0 -128
  583. package/dist/snapshot-artifacts/sqlite-bun.js.map +0 -1
  584. package/dist/snapshot-artifacts.d.ts +0 -206
  585. package/dist/snapshot-artifacts.d.ts.map +0 -1
  586. package/dist/snapshot-artifacts.js +0 -545
  587. package/dist/snapshot-artifacts.js.map +0 -1
  588. package/dist/snapshot-chunks/db-metadata.d.ts +0 -56
  589. package/dist/snapshot-chunks/db-metadata.d.ts.map +0 -1
  590. package/dist/snapshot-chunks/db-metadata.js +0 -360
  591. package/dist/snapshot-chunks/db-metadata.js.map +0 -1
  592. package/dist/snapshot-chunks/index.d.ts +0 -8
  593. package/dist/snapshot-chunks/index.d.ts.map +0 -1
  594. package/dist/snapshot-chunks/index.js +0 -8
  595. package/dist/snapshot-chunks/index.js.map +0 -1
  596. package/dist/snapshot-chunks/types.d.ts +0 -80
  597. package/dist/snapshot-chunks/types.d.ts.map +0 -1
  598. package/dist/snapshot-chunks/types.js +0 -8
  599. package/dist/snapshot-chunks/types.js.map +0 -1
  600. package/dist/snapshot-chunks.d.ts +0 -90
  601. package/dist/snapshot-chunks.d.ts.map +0 -1
  602. package/dist/snapshot-chunks.js +0 -304
  603. package/dist/snapshot-chunks.js.map +0 -1
  604. package/dist/sqlite/index.d.ts +0 -53
  605. package/dist/sqlite/index.d.ts.map +0 -1
  606. package/dist/sqlite/index.js +0 -795
  607. package/dist/sqlite/index.js.map +0 -1
  608. package/dist/sqlite3.d.ts +0 -22
  609. package/dist/sqlite3.d.ts.map +0 -1
  610. package/dist/sqlite3.js +0 -99
  611. package/dist/sqlite3.js.map +0 -1
  612. package/dist/stats.d.ts +0 -28
  613. package/dist/stats.d.ts.map +0 -1
  614. package/dist/stats.js +0 -93
  615. package/dist/stats.js.map +0 -1
  616. package/dist/subscriptions/cache.d.ts +0 -58
  617. package/dist/subscriptions/cache.d.ts.map +0 -1
  618. package/dist/subscriptions/cache.js +0 -250
  619. package/dist/subscriptions/cache.js.map +0 -1
  620. package/dist/subscriptions/index.d.ts +0 -3
  621. package/dist/subscriptions/index.d.ts.map +0 -1
  622. package/dist/subscriptions/index.js +0 -3
  623. package/dist/subscriptions/index.js.map +0 -1
  624. package/dist/subscriptions/resolve.d.ts +0 -40
  625. package/dist/subscriptions/resolve.d.ts.map +0 -1
  626. package/dist/subscriptions/resolve.js +0 -275
  627. package/dist/subscriptions/resolve.js.map +0 -1
  628. package/dist/sync.d.ts +0 -24
  629. package/dist/sync.d.ts.map +0 -1
  630. package/dist/sync.js +0 -27
  631. package/dist/sync.js.map +0 -1
  632. package/src/auth-leases.ts +0 -649
  633. package/src/better-sqlite3.ts +0 -35
  634. package/src/blobs/access.ts +0 -244
  635. package/src/blobs/adapters/database.ts +0 -397
  636. package/src/blobs/index.ts +0 -9
  637. package/src/blobs/manager.ts +0 -901
  638. package/src/blobs/migrate.ts +0 -158
  639. package/src/blobs/types.ts +0 -74
  640. package/src/bun-sqlite-ambient.d.ts +0 -19
  641. package/src/bun-sqlite.ts +0 -27
  642. package/src/clients.ts +0 -22
  643. package/src/cloudflare/durable-object.ts +0 -289
  644. package/src/cloudflare/index.ts +0 -22
  645. package/src/cloudflare/r2.ts +0 -526
  646. package/src/cloudflare/scope-cache.ts +0 -341
  647. package/src/cloudflare/sentry.ts +0 -230
  648. package/src/cloudflare/worker.ts +0 -77
  649. package/src/commit-integrity.ts +0 -371
  650. package/src/compaction.ts +0 -77
  651. package/src/crdt-yjs/index.ts +0 -931
  652. package/src/d1.ts +0 -16
  653. package/src/dialect/base.ts +0 -360
  654. package/src/dialect/helpers.ts +0 -92
  655. package/src/dialect/index.ts +0 -7
  656. package/src/dialect/types.ts +0 -247
  657. package/src/encrypted-crdt.ts +0 -786
  658. package/src/filesystem/index.ts +0 -262
  659. package/src/handlers/collection.ts +0 -121
  660. package/src/handlers/create-handler.ts +0 -1134
  661. package/src/handlers/index.ts +0 -3
  662. package/src/handlers/types.ts +0 -403
  663. package/src/helpers/conflict.ts +0 -64
  664. package/src/helpers/emitted-change.ts +0 -69
  665. package/src/helpers/index.ts +0 -12
  666. package/src/helpers/paginate.ts +0 -82
  667. package/src/helpers/scope-authorization.ts +0 -27
  668. package/src/helpers/scope-commit-index.ts +0 -52
  669. package/src/helpers/scope-strings.ts +0 -101
  670. package/src/hono/api-key-auth.ts +0 -177
  671. package/src/hono/audit-redaction.ts +0 -135
  672. package/src/hono/blobs.ts +0 -851
  673. package/src/hono/console/gateway.ts +0 -3046
  674. package/src/hono/console/live-auth.ts +0 -46
  675. package/src/hono/console/route-descriptor.ts +0 -22
  676. package/src/hono/console/routes/api-keys.ts +0 -721
  677. package/src/hono/console/routes/clients.ts +0 -447
  678. package/src/hono/console/routes/commits.ts +0 -1137
  679. package/src/hono/console/routes/context.ts +0 -956
  680. package/src/hono/console/routes/events.ts +0 -669
  681. package/src/hono/console/routes/maintenance.ts +0 -461
  682. package/src/hono/console/routes/shared.ts +0 -816
  683. package/src/hono/console/routes/stats.ts +0 -392
  684. package/src/hono/console/routes/storage.ts +0 -159
  685. package/src/hono/console/routes.ts +0 -146
  686. package/src/hono/console/schema-errors.ts +0 -23
  687. package/src/hono/console/schemas.ts +0 -914
  688. package/src/hono/console/types.ts +0 -223
  689. package/src/hono/console/ui.ts +0 -100
  690. package/src/hono/create-server.ts +0 -230
  691. package/src/hono/errors.ts +0 -50
  692. package/src/hono/index.ts +0 -54
  693. package/src/hono/openapi.ts +0 -139
  694. package/src/hono/proxy/connection-manager.ts +0 -340
  695. package/src/hono/proxy/index.ts +0 -8
  696. package/src/hono/proxy/routes.ts +0 -272
  697. package/src/hono/rate-limit.ts +0 -319
  698. package/src/hono/realtime-sync-packs.ts +0 -354
  699. package/src/hono/routes/audit.ts +0 -499
  700. package/src/hono/routes/auth-leases.ts +0 -119
  701. package/src/hono/routes/combined.ts +0 -583
  702. package/src/hono/routes/context.ts +0 -1629
  703. package/src/hono/routes/health.ts +0 -26
  704. package/src/hono/routes/realtime.ts +0 -808
  705. package/src/hono/routes/shared.ts +0 -1626
  706. package/src/hono/routes/snapshots.ts +0 -345
  707. package/src/hono/routes.ts +0 -68
  708. package/src/hono/validation.ts +0 -81
  709. package/src/hono/websocket-origin.ts +0 -131
  710. package/src/hono/ws.ts +0 -1134
  711. package/src/libsql.ts +0 -51
  712. package/src/migrate.ts +0 -20
  713. package/src/neon.ts +0 -28
  714. package/src/notify.ts +0 -341
  715. package/src/pglite.ts +0 -68
  716. package/src/plugins/index.ts +0 -1
  717. package/src/plugins/types.ts +0 -144
  718. package/src/postgres/index.ts +0 -1291
  719. package/src/proxy/collection.ts +0 -17
  720. package/src/proxy/handler.ts +0 -159
  721. package/src/proxy/index.ts +0 -21
  722. package/src/proxy/mutation-detector.ts +0 -281
  723. package/src/proxy/oplog.ts +0 -181
  724. package/src/proxy/types.ts +0 -46
  725. package/src/realtime/in-memory.ts +0 -33
  726. package/src/realtime/index.ts +0 -7
  727. package/src/realtime/types.ts +0 -90
  728. package/src/relay/bun-types.d.ts +0 -50
  729. package/src/relay/client-role/forward-engine.ts +0 -355
  730. package/src/relay/client-role/index.ts +0 -9
  731. package/src/relay/client-role/pull-engine.ts +0 -329
  732. package/src/relay/client-role/sequence-mapper.ts +0 -201
  733. package/src/relay/evaluation/relay-paths.ts +0 -699
  734. package/src/relay/evaluation/rust-boundary.ts +0 -464
  735. package/src/relay/index.ts +0 -50
  736. package/src/relay/migrate.ts +0 -113
  737. package/src/relay/mode-manager.ts +0 -142
  738. package/src/relay/realtime.ts +0 -207
  739. package/src/relay/relay.ts +0 -431
  740. package/src/relay/schema.ts +0 -171
  741. package/src/relay/server-role/index.ts +0 -338
  742. package/src/relay/server-role/pull.ts +0 -43
  743. package/src/relay/server-role/push.ts +0 -164
  744. package/src/s3/index.ts +0 -346
  745. package/src/service-worker/index.ts +0 -773
  746. package/src/snapshot-artifacts/sqlite-bun.ts +0 -168
  747. package/src/snapshot-artifacts.ts +0 -896
  748. package/src/snapshot-chunks/db-metadata.ts +0 -537
  749. package/src/snapshot-chunks/index.ts +0 -8
  750. package/src/snapshot-chunks/types.ts +0 -105
  751. package/src/snapshot-chunks.ts +0 -453
  752. package/src/sqlite/index.ts +0 -1064
  753. package/src/sqlite3.ts +0 -137
  754. package/src/stats.ts +0 -180
  755. package/src/subscriptions/cache.ts +0 -376
  756. package/src/subscriptions/index.ts +0 -2
  757. package/src/subscriptions/resolve.ts +0 -357
  758. package/src/sync.ts +0 -111
package/dist/schema.d.ts CHANGED
@@ -1,300 +1,96 @@
1
1
  /**
2
- * @syncular/server - database schema types
2
+ * Server schema IR (SPEC.md §2.4, §3.1).
3
3
  *
4
- * Commit-log based sync tables:
5
- * - sync_commits: one row per committed push
6
- * - sync_changes: one row per emitted change, stamped with scopes
7
- * - sync_table_commits: commit routing index for fast pull
8
- * - sync_scope_commits: scope routing index for scoped incremental pull
4
+ * The server is configured with a schema IR: tables, columns with the six
5
+ * §2.4 column types, scope patterns per §3.1, and a schema version. Codegen
6
+ * (B5) will emit this shape later; tests hand-write it.
9
7
  */
10
- import type { SyncOp } from '@syncular/core';
11
- import type { Generated } from 'kysely';
8
+ import type { RowColumn } from '@syncular/core';
9
+ /** `'prefix:{variable}'` shorthand (column name = variable) or explicit. */
10
+ export type ScopePatternSpec = string | {
11
+ pattern: string;
12
+ column: string;
13
+ };
12
14
  /**
13
- * Commit log.
15
+ * A user-declared index (the migration subset's CREATE INDEX). With
16
+ * relational server storage these apply server-side too (DESIGN
17
+ * "user indexes") — the same declaration the client materializes.
14
18
  */
15
- export interface SyncCommitsTable {
16
- /** Monotonic commit sequence (server-assigned) */
17
- commit_seq: Generated<number>;
18
- /** Logical partition key (tenant / demo / workspace) */
19
- partition_id: string;
20
- /** Actor who produced the commit */
21
- actor_id: string;
22
- /** Client/device identifier */
23
- client_id: string;
24
- /** Client-provided commit idempotency key (unique per client) */
25
- client_commit_id: string;
26
- /** Creation timestamp */
27
- created_at: Generated<string>;
28
- /** Optional metadata */
29
- meta: unknown | null;
30
- /** Cached push response for idempotency */
31
- result_json: unknown | null;
32
- /** Number of emitted changes (denormalized for observability) */
33
- change_count: Generated<number>;
34
- /** Hex SHA-256 digest of the canonical persisted commit payload */
35
- commit_digest: Generated<string | null>;
36
- /** Hex SHA-256 root chaining this commit to the previous partition root */
37
- commit_chain_root: Generated<string | null>;
38
- /**
39
- * Tables affected by this commit (for realtime notifications).
40
- * Array of table names that had changes.
41
- */
42
- affected_tables: Generated<string[]>;
43
- }
44
- /**
45
- * Change log entries (filtered by scopes on pull).
46
- */
47
- export interface SyncChangesTable {
48
- /** Monotonic change id */
49
- change_id: Generated<number>;
50
- /** Logical partition key (tenant / demo / workspace) */
51
- partition_id: string;
52
- /** Commit sequence this change belongs to */
53
- commit_seq: number;
54
- /** Table name being changed */
55
- table: string;
56
- /** Row primary key */
57
- row_id: string;
58
- /** Operation: 'upsert' or 'delete' */
59
- op: SyncOp;
60
- /** Row data as JSON (null for deletes) */
61
- row_json: unknown | null;
62
- /** Optional row version for optimistic concurrency */
63
- row_version: number | null;
64
- /**
65
- * Scope values for routing/filtering (JSONB).
66
- * Example: { "user_id": "U1", "project_id": "P1" }
67
- */
68
- scopes: unknown;
19
+ export interface IndexSchema {
20
+ readonly name: string;
21
+ readonly columns: readonly string[];
22
+ readonly unique?: boolean;
69
23
  }
70
- /**
71
- * Per-client cursor tracking (for pruning + observability).
72
- */
73
- export interface SyncClientCursorsTable {
74
- /** Logical partition key (tenant / demo / workspace) */
75
- partition_id: string;
76
- /** Client/device identifier */
77
- client_id: string;
78
- /** Actor currently associated with the client */
79
- actor_id: string;
80
- /** Last successfully pulled commit_seq */
81
- cursor: number;
82
- /**
83
- * Effective scope values for the client's last pull (JSONB).
84
- * This is the intersection of requested scopes and allowed scopes.
85
- */
86
- effective_scopes: unknown;
24
+ export interface TableSchema {
25
+ readonly name: string;
26
+ /** Columns in schema-IR declaration order (the row-codec order, §2.4). */
27
+ readonly columns: readonly RowColumn[];
28
+ /** Primary-key column; its value renders as the change `rowId` (§2.2). */
29
+ readonly primaryKey: string;
30
+ /** Scope patterns (§3.1). Every synced table declares at least one. */
31
+ readonly scopes: readonly ScopePatternSpec[];
32
+ /** User indexes (optional) created on the server's relational tables. */
33
+ readonly indexes?: readonly IndexSchema[];
87
34
  /**
88
- * Last active realtime subscription snapshot for websocket binary packs.
35
+ * Server-side column materialization (DESIGN-relational-server-storage.md
36
+ * "optional materialization"). When `true` (the usual default) the server's
37
+ * row table carries the app's typed columns as a queryable projection;
38
+ * when `false` it carries only the `_sync_*` meta columns — same storage
39
+ * layout, same serve path, no decode on the push path, but no server-side
40
+ * SQL over the app's columns (and user indexes are skipped).
89
41
  *
90
- * This duplicates the protocol-level subscription id/table/scope/cursor/root
91
- * shape from the latest successful pull so a restarted realtime server can
92
- * rebuild scoped binary notifications before the client performs another
93
- * HTTP pull.
42
+ * Unset defaults to `true`, EXCEPT for tables whose every non-PK,
43
+ * non-scope column is encrypted (§5.11): their projection would be
44
+ * columns of ciphertext, so they default to `false`. Explicit values
45
+ * always win. Changing the value later requires a schemaVersion bump
46
+ * (flipping on backfills the projection from stored payloads).
94
47
  */
95
- realtime_subscriptions: unknown | null;
96
- /** Last update timestamp */
97
- updated_at: Generated<string>;
48
+ readonly materialize?: boolean;
98
49
  }
99
- /**
100
- * Cached bootstrap snapshot chunks (encoded, for large read-only bootstraps).
101
- */
102
- export interface SyncSnapshotChunksTable {
103
- /** Opaque chunk id */
104
- chunk_id: string;
105
- /** Logical partition key (tenant / demo / workspace) */
106
- partition_id: string;
107
- /** Effective scope key this chunk belongs to */
108
- scope_key: string;
109
- /** Scope identifier */
110
- scope: string;
111
- /** Snapshot as-of commit sequence */
112
- as_of_commit_seq: number;
113
- /** Snapshot row cursor key (empty string represents null) */
114
- row_cursor: string;
115
- /** Snapshot row limit used to produce this chunk */
116
- row_limit: number;
117
- /** Cursor after this chunk; null means no next row for this table */
118
- next_row_cursor?: string | null;
119
- /** 1 when this chunk reaches the end of the table snapshot */
120
- is_last_page?: number;
121
- /** Row encoding (e.g. 'binary-table-v1') */
122
- encoding: string;
123
- /** Compression algorithm (e.g. 'gzip') */
124
- compression: string;
125
- /** Hex-encoded sha256 of content */
126
- sha256: string;
127
- /** Byte length of content */
128
- byte_length: number;
129
- /** Reference to blob storage (new field for external storage) */
130
- blob_hash: string;
131
- /** Encoded chunk bytes (deprecated: use blob storage via blob_hash) */
132
- body?: Uint8Array | null;
133
- /** Created timestamp */
134
- created_at: Generated<string>;
135
- /** Expiration timestamp (server may delete after this) */
136
- expires_at: string;
50
+ export interface ServerSchema {
51
+ /** The generated schema version this server serves (§2.4, §9). */
52
+ readonly version: number;
53
+ /** Tables in handler-declared bootstrap order (§4.7). */
54
+ readonly tables: readonly TableSchema[];
137
55
  }
138
- /**
139
- * Cached scoped snapshot artifacts.
140
- *
141
- * Artifacts are larger immutable bootstrap payloads, such as scoped SQLite
142
- * snapshot files, addressed by a verified manifest and stored in object
143
- * storage via blob_hash.
144
- */
145
- export interface SyncSnapshotArtifactsTable {
146
- /** Opaque artifact id */
147
- artifact_id: string;
148
- /** Logical partition key (tenant / demo / workspace) */
149
- partition_id: string;
150
- /** Effective scope key this artifact belongs to */
151
- scope_key: string;
152
- /** Stable subscription id this artifact serves */
153
- subscription_id: string;
154
- /** App table represented by the artifact */
155
- table: string;
156
- /** Artifact format (e.g. 'sqlite-snapshot-v1') */
157
- artifact_kind: string;
158
- /** App schema/cache semantic version */
159
- schema_version: string;
160
- /** Snapshot as-of commit sequence */
161
- as_of_commit_seq: number;
162
- /** Snapshot row cursor key (empty string represents null) */
163
- row_cursor: string;
164
- /** Snapshot row limit used to produce this artifact */
165
- row_limit: number;
166
- /** Number of rows included in the artifact */
167
- row_count: number;
168
- /** Cursor after this artifact; null means no next row for this table */
169
- next_row_cursor?: string | null;
170
- /** 1 when this artifact starts at the table's first page */
171
- is_first_page: number;
172
- /** 1 when this artifact reaches the end of the table snapshot */
173
- is_last_page: number;
174
- /** Artifact compression algorithm */
175
- compression: string;
176
- /** Hex-encoded sha256 of artifact body bytes */
177
- sha256: string;
178
- /** Byte length of artifact body bytes */
179
- byte_length: number;
180
- /** Hex digest of the scoped artifact manifest */
181
- manifest_digest: string;
182
- /** Normalized JSON feature set */
183
- feature_set_json: string;
184
- /** Canonical manifest JSON */
185
- manifest_json: string;
186
- /** Reference to blob storage */
187
- blob_hash: string;
188
- /** Created timestamp */
189
- created_at: Generated<string>;
190
- /** Expiration timestamp (server may delete after this) */
191
- expires_at: string;
56
+ export interface CompiledScopePattern {
57
+ readonly variable: string;
58
+ /** Literal prefix; the scope key is `prefix + ':' + value` (§3.1). */
59
+ readonly prefix: string;
60
+ readonly column: string;
61
+ readonly columnIndex: number;
192
62
  }
193
- /**
194
- * Shared encrypted CRDT update log.
195
- *
196
- * One physical table stores updates for every encrypted CRDT field. The logical
197
- * stream is keyed by partition_id + stream_id, where stream_id is derived from
198
- * app_table + row_id + field_name.
199
- */
200
- export interface SyncCrdtUpdatesTable {
201
- seq: Generated<number>;
202
- partition_id: string;
203
- stream_id: string;
204
- app_table: string;
205
- row_id: string;
206
- field_name: string;
207
- update_id: string;
208
- actor_id: string | null;
209
- client_id: string | null;
210
- key_id: string;
211
- ciphertext: string;
212
- scopes: unknown;
213
- created_at: Generated<string>;
63
+ export interface CompiledTable {
64
+ readonly name: string;
65
+ readonly columns: readonly RowColumn[];
66
+ readonly primaryKeyIndex: number;
67
+ readonly scopePatterns: readonly CompiledScopePattern[];
68
+ /** User indexes (validated: unique names, existing columns). */
69
+ readonly indexes: readonly IndexSchema[];
70
+ /** Resolved materialization (see `TableSchema.materialize`). */
71
+ readonly materialize: boolean;
72
+ readonly columnIndex: ReadonlyMap<string, number>;
73
+ readonly declaredVariables: ReadonlySet<string>;
74
+ /** Column indices declared `blob_ref` (§2.4 tag 7, §5.9) — the columns
75
+ * whose non-NULL values reference blobs (existence check, reference
76
+ * index). */
77
+ readonly blobRefColumnIndices: readonly number[];
78
+ /** `crdt` columns (§2.4 tag 8, §5.10) — index + the `crdtType` name that
79
+ * selects the merger. Empty when the table has no crdt columns. */
80
+ readonly crdtColumns: readonly {
81
+ readonly index: number;
82
+ readonly crdtType: string;
83
+ }[];
84
+ /** §5.11: column indices marked `encrypted`. The server never decrypts;
85
+ * this only excludes the table from sqlite-image eligibility (§5.3) — an
86
+ * image copies ciphertext wholesale with no per-row decrypt pass, so an
87
+ * encrypted table MUST be served via the rows lane. Empty ⇒ no restriction. */
88
+ readonly encryptedColumnIndices: readonly number[];
214
89
  }
215
- /**
216
- * Shared encrypted CRDT checkpoints.
217
- *
218
- * Checkpoints contain encrypted full Yjs/Yrs state snapshots and allow old
219
- * update-log rows to be garbage-collected after retention rules are satisfied.
220
- */
221
- export interface SyncCrdtCheckpointsTable {
222
- seq: Generated<number>;
223
- partition_id: string;
224
- stream_id: string;
225
- app_table: string;
226
- row_id: string;
227
- field_name: string;
228
- checkpoint_id: string;
229
- covers_seq: number;
230
- actor_id: string | null;
231
- client_id: string | null;
232
- key_id: string;
233
- ciphertext: string;
234
- scopes: unknown;
235
- created_at: Generated<string>;
236
- }
237
- /**
238
- * Index table: which commits affect which tables.
239
- *
240
- * Used to efficiently find commit_seq values for a table without scanning
241
- * the (much larger) change log.
242
- */
243
- export interface SyncTableCommitsTable {
244
- /** Logical partition key (tenant / demo / workspace) */
245
- partition_id: string;
246
- table: string;
247
- commit_seq: number;
248
- }
249
- /**
250
- * Index table: which commits affect which table/scope route keys.
251
- *
252
- * Used to avoid scanning table-level commits that cannot match a scoped
253
- * subscription. JSON scope filtering still validates exact multi-scope matches.
254
- */
255
- export interface SyncScopeCommitsTable {
256
- /** Logical partition key (tenant / demo / workspace) */
257
- partition_id: string;
258
- table: string;
259
- scope_key: string;
260
- commit_seq: number;
261
- }
262
- /**
263
- * Database interface for sync infrastructure tables
264
- * Merge this with your app's database interface
265
- */
266
- export interface SyncCoreDb {
267
- sync_commits: SyncCommitsTable;
268
- sync_changes: SyncChangesTable;
269
- sync_client_cursors: SyncClientCursorsTable;
270
- sync_crdt_updates: SyncCrdtUpdatesTable;
271
- sync_crdt_checkpoints: SyncCrdtCheckpointsTable;
272
- sync_table_commits: SyncTableCommitsTable;
273
- sync_scope_commits: SyncScopeCommitsTable;
274
- sync_snapshot_chunks: SyncSnapshotChunksTable;
275
- sync_snapshot_artifacts: SyncSnapshotArtifactsTable;
276
- }
277
- /**
278
- * Commit metadata row for pull responses
279
- */
280
- export interface SyncCommitRow {
281
- commit_seq: number;
282
- actor_id: string;
283
- created_at: string;
284
- result_json: unknown | null;
285
- commit_digest: string | null;
286
- commit_chain_root: string | null;
287
- }
288
- /**
289
- * Change row for pull responses
290
- */
291
- export interface SyncChangeRow {
292
- commit_seq: number;
293
- table: string;
294
- row_id: string;
295
- op: SyncOp;
296
- row_json: unknown | null;
297
- row_version: number | null;
298
- scopes: unknown;
90
+ export interface CompiledSchema {
91
+ readonly version: number;
92
+ readonly tables: ReadonlyMap<string, CompiledTable>;
93
+ /** Union of scope variables declared by any table (§3.2 resolver check). */
94
+ readonly declaredVariables: ReadonlySet<string>;
299
95
  }
300
- //# sourceMappingURL=schema.d.ts.map
96
+ export declare function compileSchema(schema: ServerSchema): CompiledSchema;
package/dist/schema.js CHANGED
@@ -1,11 +1,135 @@
1
+ const PATTERN_RE = /^([^{}]+):\{([^{}:]+)\}$/;
1
2
  /**
2
- * @syncular/server - database schema types
3
- *
4
- * Commit-log based sync tables:
5
- * - sync_commits: one row per committed push
6
- * - sync_changes: one row per emitted change, stamped with scopes
7
- * - sync_table_commits: commit routing index for fast pull
8
- * - sync_scope_commits: scope routing index for scoped incremental pull
3
+ * Identifier rules for relational server storage (DESIGN "current-row
4
+ * tables"): app tables live in the same namespace as the sync
5
+ * infrastructure tables (`sync_*`) and carry `_sync_*` meta columns, so
6
+ * both prefixes are reserved; identifiers over 63 bytes would be silently
7
+ * truncated by Postgres.
9
8
  */
10
- export {};
11
- //# sourceMappingURL=schema.js.map
9
+ function validateIdentifier(kind, name) {
10
+ if (name.length === 0) {
11
+ throw new Error(`${kind} name must not be empty`);
12
+ }
13
+ const lower = name.toLowerCase();
14
+ if (lower.startsWith('sync_') || lower.startsWith('_sync')) {
15
+ throw new Error(`${kind} name ${JSON.stringify(name)} uses a reserved prefix (sync_/_sync are the server storage namespace)`);
16
+ }
17
+ if (new TextEncoder().encode(name).length > 63) {
18
+ throw new Error(`${kind} name ${JSON.stringify(name)} exceeds 63 bytes (Postgres identifier limit)`);
19
+ }
20
+ }
21
+ function compilePattern(table, spec, columnIndex) {
22
+ const pattern = typeof spec === 'string' ? spec : spec.pattern;
23
+ const match = PATTERN_RE.exec(pattern);
24
+ if (match === null || match[1] === undefined || match[2] === undefined) {
25
+ throw new Error(`table ${table.name}: scope pattern ${JSON.stringify(pattern)} must be 'prefix:{variable}' with exactly one variable`);
26
+ }
27
+ const prefix = match[1];
28
+ const variable = match[2];
29
+ const column = typeof spec === 'string' ? variable : spec.column;
30
+ const index = columnIndex.get(column);
31
+ if (index === undefined) {
32
+ throw new Error(`table ${table.name}: scope pattern ${JSON.stringify(pattern)} names unknown column ${JSON.stringify(column)}`);
33
+ }
34
+ return { variable, prefix, column, columnIndex: index };
35
+ }
36
+ const compiledCache = new WeakMap();
37
+ export function compileSchema(schema) {
38
+ const cached = compiledCache.get(schema);
39
+ if (cached !== undefined)
40
+ return cached;
41
+ const tables = new Map();
42
+ const declaredVariables = new Set();
43
+ for (const table of schema.tables) {
44
+ if (tables.has(table.name)) {
45
+ throw new Error(`duplicate table ${JSON.stringify(table.name)}`);
46
+ }
47
+ validateIdentifier('table', table.name);
48
+ const columnIndex = new Map();
49
+ table.columns.forEach((column, index) => {
50
+ if (columnIndex.has(column.name)) {
51
+ throw new Error(`table ${table.name}: duplicate column ${JSON.stringify(column.name)}`);
52
+ }
53
+ validateIdentifier(`table ${table.name}: column`, column.name);
54
+ columnIndex.set(column.name, index);
55
+ });
56
+ const indexes = table.indexes ?? [];
57
+ const indexNames = new Set();
58
+ for (const index of indexes) {
59
+ validateIdentifier(`table ${table.name}: index`, index.name);
60
+ if (indexNames.has(index.name)) {
61
+ throw new Error(`table ${table.name}: duplicate index ${JSON.stringify(index.name)}`);
62
+ }
63
+ indexNames.add(index.name);
64
+ for (const column of index.columns) {
65
+ if (!columnIndex.has(column)) {
66
+ throw new Error(`table ${table.name}: index ${JSON.stringify(index.name)} names unknown column ${JSON.stringify(column)}`);
67
+ }
68
+ }
69
+ }
70
+ const primaryKeyIndex = columnIndex.get(table.primaryKey);
71
+ if (primaryKeyIndex === undefined) {
72
+ throw new Error(`table ${table.name}: primary key ${JSON.stringify(table.primaryKey)} is not a column`);
73
+ }
74
+ if (table.scopes.length === 0) {
75
+ throw new Error(`table ${table.name}: every synced table declares at least one scope pattern (§3.1)`);
76
+ }
77
+ const scopePatterns = table.scopes.map((spec) => compilePattern(table, spec, columnIndex));
78
+ const variables = new Set();
79
+ for (const pattern of scopePatterns) {
80
+ const existing = scopePatterns.find((p) => p.variable === pattern.variable && p.column !== pattern.column);
81
+ if (existing !== undefined) {
82
+ throw new Error(`table ${table.name}: variable ${JSON.stringify(pattern.variable)} maps to two different columns (§3.1)`);
83
+ }
84
+ variables.add(pattern.variable);
85
+ declaredVariables.add(pattern.variable);
86
+ }
87
+ const blobRefColumnIndices = [];
88
+ const crdtColumns = [];
89
+ const encryptedColumnIndices = [];
90
+ table.columns.forEach((column, index) => {
91
+ if (column.type === 'blob_ref')
92
+ blobRefColumnIndices.push(index);
93
+ // §5.11: an encrypted column carries wire type `bytes` + `encrypted`.
94
+ if (column.encrypted === true)
95
+ encryptedColumnIndices.push(index);
96
+ if (column.type === 'crdt') {
97
+ // §5.10.1: a crdt column MUST name a crdtType (schema-compile-time
98
+ // requirement — a crdt column without one is a server bug).
99
+ if (column.crdtType === undefined || column.crdtType.length === 0) {
100
+ throw new Error(`table ${table.name}: crdt column ${JSON.stringify(column.name)} must declare a crdtType (§5.10.1)`);
101
+ }
102
+ crdtColumns.push({ index, crdtType: column.crdtType });
103
+ }
104
+ });
105
+ // Materialization default: explicit wins; otherwise on, unless every
106
+ // non-PK, non-scope column is encrypted — a fully-E2EE table's
107
+ // projection would be pure ciphertext, so it defaults off.
108
+ const scopeColumnIndices = new Set(scopePatterns.map((pattern) => pattern.columnIndex));
109
+ const projectable = table.columns.filter((column, index) => index !== primaryKeyIndex && !scopeColumnIndices.has(index));
110
+ const fullyEncrypted = encryptedColumnIndices.length > 0 &&
111
+ projectable.length > 0 &&
112
+ projectable.every((column) => column.encrypted === true);
113
+ const materialize = table.materialize ?? !fullyEncrypted;
114
+ tables.set(table.name, {
115
+ name: table.name,
116
+ columns: table.columns,
117
+ primaryKeyIndex,
118
+ scopePatterns,
119
+ indexes,
120
+ materialize,
121
+ columnIndex,
122
+ declaredVariables: variables,
123
+ blobRefColumnIndices,
124
+ crdtColumns,
125
+ encryptedColumnIndices,
126
+ });
127
+ }
128
+ const compiled = {
129
+ version: schema.version,
130
+ tables,
131
+ declaredVariables,
132
+ };
133
+ compiledCache.set(schema, compiled);
134
+ return compiled;
135
+ }
@@ -0,0 +1,48 @@
1
+ /**
2
+ * Scope semantics (SPEC.md §3) — requested ∩ allowed intersection,
3
+ * revocation, stored-scope extraction, write-path authorization, and the
4
+ * §3.5 scope digest.
5
+ */
6
+ import { type RowValue, type ScopeMap } from '@syncular/core';
7
+ import type { CompiledTable } from './schema.js';
8
+ export type StoredScopes = Record<string, string>;
9
+ /** Outcome of resolving the host's allowed scopes once per request (§3.4). */
10
+ export type ResolvedScopes = {
11
+ readonly ok: true;
12
+ readonly allowed: ScopeMap;
13
+ } | {
14
+ readonly ok: false;
15
+ };
16
+ export type EffectiveOutcome = {
17
+ readonly status: 'active';
18
+ readonly effective: ScopeMap;
19
+ } | {
20
+ readonly status: 'revoked';
21
+ };
22
+ /**
23
+ * Effective = requested ∩ allowed per §3.2 rules 4–5. Inputs are assumed
24
+ * key-validated (requested keys declared, no `'*'` requested values).
25
+ */
26
+ export declare function computeEffective(requested: ScopeMap, resolved: ResolvedScopes): EffectiveOutcome;
27
+ /** Render a stored scope column value; `undefined` means missing/empty. */
28
+ export declare function renderScopeValue(value: RowValue | undefined): string | undefined;
29
+ /**
30
+ * Extract the stored scopes (§3.1) from a decoded row. Returns the missing
31
+ * variable name when a declared scope column is absent or empty.
32
+ */
33
+ export declare function storedScopesForRow(table: CompiledTable, values: readonly RowValue[]): {
34
+ scopes: StoredScopes;
35
+ } | {
36
+ missing: string;
37
+ };
38
+ /**
39
+ * Write-path authorization (§3.4 steps 2–3): every declared variable's
40
+ * stored value must be present and allowed (or the allowed list holds
41
+ * `'*'`). All declared keys are required — there is no partial pass.
42
+ */
43
+ export declare function authorizeWrite(table: CompiledTable, rowScopes: StoredScopes, resolved: ResolvedScopes): boolean;
44
+ /** Does a change's stored scopes match the effective scopes (§3.2)? */
45
+ export declare function matchesEffective(storedScopes: StoredScopes, effective: ScopeMap): boolean;
46
+ export declare function sha256Hex(bytes: Uint8Array): Promise<string>;
47
+ /** §3.5: SHA-256 over the canonical JSON of the effective-scope map. */
48
+ export declare function scopeDigest(effective: ScopeMap): Promise<string>;
package/dist/scopes.js ADDED
@@ -0,0 +1,98 @@
1
+ /**
2
+ * Scope semantics (SPEC.md §3) — requested ∩ allowed intersection,
3
+ * revocation, stored-scope extraction, write-path authorization, and the
4
+ * §3.5 scope digest.
5
+ */
6
+ import { canonicalScopeJson, } from '@syncular/core';
7
+ /**
8
+ * Effective = requested ∩ allowed per §3.2 rules 4–5. Inputs are assumed
9
+ * key-validated (requested keys declared, no `'*'` requested values).
10
+ */
11
+ export function computeEffective(requested, resolved) {
12
+ if (!resolved.ok)
13
+ return { status: 'revoked' };
14
+ const effective = {};
15
+ const requestedKeys = Object.keys(requested);
16
+ for (const key of requestedKeys) {
17
+ const requestedValues = requested[key] ?? [];
18
+ const allowedValues = resolved.allowed[key];
19
+ if (allowedValues === undefined)
20
+ return { status: 'revoked' };
21
+ let values;
22
+ if (allowedValues.includes('*')) {
23
+ values = [...requestedValues];
24
+ }
25
+ else {
26
+ values = requestedValues.filter((v) => allowedValues.includes(v));
27
+ }
28
+ if (values.length === 0)
29
+ return { status: 'revoked' };
30
+ effective[key] = values;
31
+ }
32
+ if (Object.keys(effective).length === 0)
33
+ return { status: 'revoked' };
34
+ return { status: 'active', effective };
35
+ }
36
+ /** Render a stored scope column value; `undefined` means missing/empty. */
37
+ export function renderScopeValue(value) {
38
+ if (value === null || value === undefined)
39
+ return undefined;
40
+ if (value instanceof Uint8Array)
41
+ return undefined;
42
+ const rendered = typeof value === 'string' ? value : String(value);
43
+ return rendered.length === 0 ? undefined : rendered;
44
+ }
45
+ /**
46
+ * Extract the stored scopes (§3.1) from a decoded row. Returns the missing
47
+ * variable name when a declared scope column is absent or empty.
48
+ */
49
+ export function storedScopesForRow(table, values) {
50
+ const scopes = {};
51
+ for (const pattern of table.scopePatterns) {
52
+ const value = renderScopeValue(values[pattern.columnIndex]);
53
+ if (value === undefined)
54
+ return { missing: pattern.variable };
55
+ scopes[pattern.variable] = value;
56
+ }
57
+ return { scopes };
58
+ }
59
+ /**
60
+ * Write-path authorization (§3.4 steps 2–3): every declared variable's
61
+ * stored value must be present and allowed (or the allowed list holds
62
+ * `'*'`). All declared keys are required — there is no partial pass.
63
+ */
64
+ export function authorizeWrite(table, rowScopes, resolved) {
65
+ if (!resolved.ok)
66
+ return false;
67
+ for (const pattern of table.scopePatterns) {
68
+ const value = rowScopes[pattern.variable];
69
+ if (value === undefined || value.length === 0)
70
+ return false;
71
+ const allowedValues = resolved.allowed[pattern.variable];
72
+ if (allowedValues === undefined)
73
+ return false;
74
+ if (!allowedValues.includes('*') && !allowedValues.includes(value)) {
75
+ return false;
76
+ }
77
+ }
78
+ return true;
79
+ }
80
+ /** Does a change's stored scopes match the effective scopes (§3.2)? */
81
+ export function matchesEffective(storedScopes, effective) {
82
+ for (const [variable, values] of Object.entries(effective)) {
83
+ const stored = storedScopes[variable];
84
+ if (stored === undefined || !values.includes(stored))
85
+ return false;
86
+ }
87
+ return true;
88
+ }
89
+ export async function sha256Hex(bytes) {
90
+ const digest = await crypto.subtle.digest('SHA-256', bytes.slice().buffer);
91
+ return [...new Uint8Array(digest)]
92
+ .map((b) => b.toString(16).padStart(2, '0'))
93
+ .join('');
94
+ }
95
+ /** §3.5: SHA-256 over the canonical JSON of the effective-scope map. */
96
+ export async function scopeDigest(effective) {
97
+ return sha256Hex(new TextEncoder().encode(canonicalScopeJson(effective)));
98
+ }