@abloatai/transaction 0.56.0 → 0.58.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 (769) hide show
  1. package/CONVENTIONS.md +54 -10
  2. package/README.md +3 -1
  3. package/dist/ai-sdk/modelTools.d.ts +3 -3
  4. package/dist/ai-sdk/modelTools.d.ts.map +1 -1
  5. package/dist/ai-sdk/modelTools.js +1 -1
  6. package/dist/ai-sdk/modelTools.js.map +1 -1
  7. package/dist/ai-sdk/updateTool.d.ts +5 -7
  8. package/dist/ai-sdk/updateTool.d.ts.map +1 -1
  9. package/dist/ai-sdk/updateTool.js +3 -5
  10. package/dist/ai-sdk/updateTool.js.map +1 -1
  11. package/dist/auth/capability.d.ts +5 -0
  12. package/dist/auth/capability.d.ts.map +1 -1
  13. package/dist/auth/capability.js +5 -0
  14. package/dist/auth/capability.js.map +1 -1
  15. package/dist/auth/capabilityLifecycle.d.ts +1 -1
  16. package/dist/auth/capabilityLifecycle.d.ts.map +1 -1
  17. package/dist/auth/credentialPolicy.d.ts +1 -1
  18. package/dist/auth/credentialPolicy.d.ts.map +1 -1
  19. package/dist/auth/identity.d.ts +3 -3
  20. package/dist/auth/identity.d.ts.map +1 -1
  21. package/dist/auth/identity.js +5 -5
  22. package/dist/auth/identity.js.map +1 -1
  23. package/dist/auth/index.d.ts +4 -208
  24. package/dist/auth/index.d.ts.map +1 -1
  25. package/dist/auth/index.js +4 -330
  26. package/dist/auth/index.js.map +1 -1
  27. package/dist/auth/runtime.d.ts +218 -0
  28. package/dist/auth/runtime.d.ts.map +1 -0
  29. package/dist/auth/runtime.js +336 -0
  30. package/dist/auth/runtime.js.map +1 -0
  31. package/dist/auth/sessionMint.d.ts +1 -1
  32. package/dist/auth/sessionMint.d.ts.map +1 -1
  33. package/dist/auth/sessionMint.js +2 -1
  34. package/dist/auth/sessionMint.js.map +1 -1
  35. package/dist/branches.d.ts +25 -21
  36. package/dist/branches.d.ts.map +1 -1
  37. package/dist/branches.js +3 -0
  38. package/dist/branches.js.map +1 -1
  39. package/dist/{coordination/awaitClaimGrant.d.ts → claims/awaitGrant.d.ts} +1 -1
  40. package/dist/claims/awaitGrant.d.ts.map +1 -0
  41. package/dist/{coordination/awaitClaimGrant.js → claims/awaitGrant.js} +4 -4
  42. package/dist/claims/awaitGrant.js.map +1 -0
  43. package/dist/{wire/claims.d.ts → claims/contract.d.ts} +1 -1
  44. package/dist/claims/contract.d.ts.map +1 -0
  45. package/dist/{wire/claims.js → claims/contract.js} +2 -2
  46. package/dist/claims/contract.js.map +1 -0
  47. package/dist/{wire/claimEvent.d.ts → claims/eventContract.d.ts} +1 -1
  48. package/dist/claims/eventContract.d.ts.map +1 -0
  49. package/dist/{wire/claimEvent.js → claims/eventContract.js} +1 -1
  50. package/dist/claims/eventContract.js.map +1 -0
  51. package/dist/{coordination → claims}/events.d.ts +7 -11
  52. package/dist/claims/events.d.ts.map +1 -0
  53. package/dist/claims/events.js +8 -0
  54. package/dist/claims/events.js.map +1 -0
  55. package/dist/{coordination/claimHeartbeatLoop.d.ts → claims/heartbeat.d.ts} +1 -1
  56. package/dist/claims/heartbeat.d.ts.map +1 -0
  57. package/dist/{coordination/claimHeartbeatLoop.js → claims/heartbeat.js} +1 -1
  58. package/dist/claims/heartbeat.js.map +1 -0
  59. package/dist/claims/index.d.ts +17 -0
  60. package/dist/claims/index.d.ts.map +1 -0
  61. package/dist/claims/index.js +16 -0
  62. package/dist/claims/index.js.map +1 -0
  63. package/dist/claims/lifetime.d.ts +26 -0
  64. package/dist/claims/lifetime.d.ts.map +1 -0
  65. package/dist/claims/lifetime.js +62 -0
  66. package/dist/claims/lifetime.js.map +1 -0
  67. package/dist/{coordination → claims}/locator.d.ts +1 -1
  68. package/dist/claims/locator.d.ts.map +1 -0
  69. package/dist/{coordination → claims}/locator.js +2 -2
  70. package/dist/claims/locator.js.map +1 -0
  71. package/dist/{coordination/claimMeta.d.ts → claims/meta.d.ts} +1 -1
  72. package/dist/claims/meta.d.ts.map +1 -0
  73. package/dist/{coordination/claimMeta.js → claims/meta.js} +1 -1
  74. package/dist/claims/meta.js.map +1 -0
  75. package/dist/claims/routes.d.ts +59 -0
  76. package/dist/claims/routes.d.ts.map +1 -0
  77. package/dist/claims/routes.js +69 -0
  78. package/dist/claims/routes.js.map +1 -0
  79. package/dist/claims/targetConflict.d.ts.map +1 -0
  80. package/dist/claims/targetConflict.js.map +1 -0
  81. package/dist/{coordination → claims}/trace.d.ts +2 -2
  82. package/dist/claims/trace.d.ts.map +1 -0
  83. package/dist/{coordination → claims}/trace.js +5 -5
  84. package/dist/claims/trace.js.map +1 -0
  85. package/dist/{ablo.d.ts → client/ablo.d.ts} +6 -15
  86. package/dist/client/ablo.d.ts.map +1 -0
  87. package/dist/{ablo.js → client/ablo.js} +2 -2
  88. package/dist/client/ablo.js.map +1 -0
  89. package/dist/{transactionLayer.d.ts → client/contract.d.ts} +12 -14
  90. package/dist/client/contract.d.ts.map +1 -0
  91. package/dist/{transactionLayer.js → client/contract.js} +4 -5
  92. package/dist/client/contract.js.map +1 -0
  93. package/dist/{headlessClient.d.ts → client/headless.d.ts} +4 -4
  94. package/dist/client/headless.d.ts.map +1 -0
  95. package/dist/{headlessClient.js → client/headless.js} +8 -10
  96. package/dist/{headlessClient.js.map → client/headless.js.map} +1 -1
  97. package/dist/client/index.d.ts +11 -0
  98. package/dist/client/index.d.ts.map +1 -0
  99. package/dist/client/index.js +11 -0
  100. package/dist/client/index.js.map +1 -0
  101. package/dist/{resources → client/resources}/functionalUpdate.d.ts +4 -4
  102. package/dist/client/resources/functionalUpdate.d.ts.map +1 -0
  103. package/dist/{resources → client/resources}/functionalUpdate.js +3 -3
  104. package/dist/client/resources/functionalUpdate.js.map +1 -0
  105. package/dist/{resources → client/resources}/httpResources.d.ts +92 -77
  106. package/dist/client/resources/httpResources.d.ts.map +1 -0
  107. package/dist/client/resources/httpResources.js +94 -0
  108. package/dist/client/resources/httpResources.js.map +1 -0
  109. package/dist/client/resources/modelCreate.d.ts +21 -0
  110. package/dist/client/resources/modelCreate.d.ts.map +1 -0
  111. package/dist/client/resources/modelCreate.js +49 -0
  112. package/dist/client/resources/modelCreate.js.map +1 -0
  113. package/dist/{resources → client/resources}/modelOperations.d.ts +57 -51
  114. package/dist/client/resources/modelOperations.d.ts.map +1 -0
  115. package/dist/{resources → client/resources}/modelOperations.js +1 -1
  116. package/dist/client/resources/modelOperations.js.map +1 -0
  117. package/dist/{resources → client/resources}/mutationOptions.d.ts +4 -17
  118. package/dist/client/resources/mutationOptions.d.ts.map +1 -0
  119. package/dist/client/resources/mutationOptions.js.map +1 -0
  120. package/dist/client/resources/where.d.ts.map +1 -0
  121. package/dist/{resources → client/resources}/where.js +1 -1
  122. package/dist/client/resources/where.js.map +1 -0
  123. package/dist/{resources → client/resources}/writeOptionsSchema.d.ts +16 -35
  124. package/dist/client/resources/writeOptionsSchema.d.ts.map +1 -0
  125. package/dist/{resources → client/resources}/writeOptionsSchema.js +25 -18
  126. package/dist/client/resources/writeOptionsSchema.js.map +1 -0
  127. package/dist/{transactions → commit}/confirmation/commitEnvelope.d.ts +1 -37
  128. package/dist/commit/confirmation/commitEnvelope.d.ts.map +1 -0
  129. package/dist/{transactions → commit}/confirmation/commitEnvelope.js +2 -7
  130. package/dist/commit/confirmation/commitEnvelope.js.map +1 -0
  131. package/dist/commit/confirmation/httpCommitEnvelope.d.ts.map +1 -0
  132. package/dist/{transactions → commit}/confirmation/httpCommitEnvelope.js +1 -1
  133. package/dist/commit/confirmation/httpCommitEnvelope.js.map +1 -0
  134. package/dist/commit/confirmation/idempotencyKey.d.ts.map +1 -0
  135. package/dist/commit/confirmation/idempotencyKey.js.map +1 -0
  136. package/dist/{transactions → commit}/confirmation/pendingWrite.d.ts +2 -33
  137. package/dist/commit/confirmation/pendingWrite.d.ts.map +1 -0
  138. package/dist/{transactions → commit}/confirmation/pendingWrite.js +1 -1
  139. package/dist/commit/confirmation/pendingWrite.js.map +1 -0
  140. package/dist/commit/contract.d.ts +1404 -0
  141. package/dist/commit/contract.d.ts.map +1 -0
  142. package/dist/{wire/commit.js → commit/contract.js} +26 -21
  143. package/dist/commit/contract.js.map +1 -0
  144. package/dist/{durableWrites.d.ts → commit/durableWrites.d.ts} +6 -6
  145. package/dist/commit/durableWrites.d.ts.map +1 -0
  146. package/dist/{durableWrites.js → commit/durableWrites.js} +5 -5
  147. package/dist/commit/durableWrites.js.map +1 -0
  148. package/dist/commit/httpRequest.d.ts +45 -0
  149. package/dist/commit/httpRequest.d.ts.map +1 -0
  150. package/dist/commit/httpRequest.js +66 -0
  151. package/dist/commit/httpRequest.js.map +1 -0
  152. package/dist/commit/index.d.ts +17 -0
  153. package/dist/commit/index.d.ts.map +1 -0
  154. package/dist/commit/index.js +17 -0
  155. package/dist/commit/index.js.map +1 -0
  156. package/dist/{readSetContext.d.ts → commit/readSetContext.d.ts} +7 -15
  157. package/dist/commit/readSetContext.d.ts.map +1 -0
  158. package/dist/{readSetContext.js → commit/readSetContext.js} +18 -28
  159. package/dist/commit/readSetContext.js.map +1 -0
  160. package/dist/{commitRecordRuntime.d.ts → commit/recordRuntime.d.ts} +3 -5
  161. package/dist/commit/recordRuntime.d.ts.map +1 -0
  162. package/dist/{commitRecordRuntime.js → commit/recordRuntime.js} +13 -54
  163. package/dist/commit/recordRuntime.js.map +1 -0
  164. package/dist/coordination/index.d.ts +6 -8
  165. package/dist/coordination/index.d.ts.map +1 -1
  166. package/dist/coordination/index.js +3 -9
  167. package/dist/coordination/index.js.map +1 -1
  168. package/dist/coordination/schema.d.ts +11 -466
  169. package/dist/coordination/schema.d.ts.map +1 -1
  170. package/dist/coordination/schema.js +13 -265
  171. package/dist/coordination/schema.js.map +1 -1
  172. package/dist/errorCodes.d.ts +16 -9
  173. package/dist/errorCodes.d.ts.map +1 -1
  174. package/dist/errorCodes.js +14 -6
  175. package/dist/errorCodes.js.map +1 -1
  176. package/dist/errorObservation.d.ts +2 -2
  177. package/dist/errors.d.ts +3 -2
  178. package/dist/errors.d.ts.map +1 -1
  179. package/dist/errors.js +27 -11
  180. package/dist/errors.js.map +1 -1
  181. package/dist/index.d.ts +7 -7
  182. package/dist/index.d.ts.map +1 -1
  183. package/dist/index.js +3 -3
  184. package/dist/index.js.map +1 -1
  185. package/dist/internal/read-set.d.ts +3 -3
  186. package/dist/internal/read-set.d.ts.map +1 -1
  187. package/dist/internal/read-set.js +2 -2
  188. package/dist/internal/read-set.js.map +1 -1
  189. package/dist/observability.d.ts +4 -4
  190. package/dist/observability.d.ts.map +1 -1
  191. package/dist/observability.js +2 -2
  192. package/dist/{wire/delta.d.ts → observation/contract.d.ts} +8 -8
  193. package/dist/observation/contract.d.ts.map +1 -0
  194. package/dist/{wire/delta.js → observation/contract.js} +3 -3
  195. package/dist/observation/contract.js.map +1 -0
  196. package/dist/{wire/feedCursor.d.ts → observation/cursor.d.ts} +1 -1
  197. package/dist/observation/cursor.d.ts.map +1 -0
  198. package/dist/{wire/feedCursor.js → observation/cursor.js} +1 -1
  199. package/dist/observation/cursor.js.map +1 -0
  200. package/dist/{wire/deltaDelivery.d.ts → observation/deliveryContract.d.ts} +1 -1
  201. package/dist/observation/deliveryContract.d.ts.map +1 -0
  202. package/dist/{wire/deltaDelivery.js → observation/deliveryContract.js} +1 -1
  203. package/dist/observation/deliveryContract.js.map +1 -0
  204. package/dist/{wire/feedEvent.d.ts → observation/feedContract.d.ts} +10 -10
  205. package/dist/observation/feedContract.d.ts.map +1 -0
  206. package/dist/{wire/feedEvent.js → observation/feedContract.js} +4 -4
  207. package/dist/observation/feedContract.js.map +1 -0
  208. package/dist/observation/httpFeed.d.ts +4 -0
  209. package/dist/observation/httpFeed.d.ts.map +1 -0
  210. package/dist/{transport → observation}/httpFeed.js +1 -1
  211. package/dist/{transport → observation}/httpFeed.js.map +1 -1
  212. package/dist/observation/index.d.ts +13 -0
  213. package/dist/observation/index.d.ts.map +1 -0
  214. package/dist/observation/index.js +13 -0
  215. package/dist/observation/index.js.map +1 -0
  216. package/dist/{log → observation/persistence}/syncDeltaRow.d.ts +8 -8
  217. package/dist/observation/persistence/syncDeltaRow.d.ts.map +1 -0
  218. package/dist/{log → observation/persistence}/syncDeltaRow.js +4 -4
  219. package/dist/observation/persistence/syncDeltaRow.js.map +1 -0
  220. package/dist/pricing.d.ts +20 -12
  221. package/dist/pricing.d.ts.map +1 -1
  222. package/dist/pricing.js +46 -26
  223. package/dist/pricing.js.map +1 -1
  224. package/dist/schema/audit.d.ts +15 -0
  225. package/dist/schema/audit.d.ts.map +1 -0
  226. package/dist/schema/audit.js +90 -0
  227. package/dist/schema/audit.js.map +1 -0
  228. package/dist/schema/ddl.d.ts.map +1 -1
  229. package/dist/schema/ddl.js +68 -1
  230. package/dist/schema/ddl.js.map +1 -1
  231. package/dist/schema/index.d.ts +7 -6
  232. package/dist/schema/index.d.ts.map +1 -1
  233. package/dist/schema/index.js +6 -7
  234. package/dist/schema/index.js.map +1 -1
  235. package/dist/schema/model.d.ts +14 -27
  236. package/dist/schema/model.d.ts.map +1 -1
  237. package/dist/schema/model.js +2 -2
  238. package/dist/schema/model.js.map +1 -1
  239. package/dist/schema/openapi.d.ts.map +1 -1
  240. package/dist/schema/openapi.js +149 -8
  241. package/dist/schema/openapi.js.map +1 -1
  242. package/dist/schema/roles.d.ts +27 -0
  243. package/dist/schema/roles.d.ts.map +1 -1
  244. package/dist/schema/roles.js +40 -0
  245. package/dist/schema/roles.js.map +1 -1
  246. package/dist/schema/schema.d.ts +34 -7
  247. package/dist/schema/schema.d.ts.map +1 -1
  248. package/dist/schema/schema.js +39 -3
  249. package/dist/schema/schema.js.map +1 -1
  250. package/dist/schema/serialize.d.ts +5 -5
  251. package/dist/schema/serialize.d.ts.map +1 -1
  252. package/dist/schema/serialize.js +5 -5
  253. package/dist/schema/serialize.js.map +1 -1
  254. package/dist/schema/subject.d.ts +18 -0
  255. package/dist/schema/subject.d.ts.map +1 -0
  256. package/dist/schema/subject.js +27 -0
  257. package/dist/schema/subject.js.map +1 -0
  258. package/dist/schema/tenancy.d.ts +1 -1
  259. package/dist/server/adapter.d.ts +3 -1
  260. package/dist/server/adapter.d.ts.map +1 -1
  261. package/dist/server/commit.d.ts +6 -14
  262. package/dist/server/commit.d.ts.map +1 -1
  263. package/dist/server/index.d.ts +1 -1
  264. package/dist/server/index.d.ts.map +1 -1
  265. package/dist/server/index.js +1 -1
  266. package/dist/server/index.js.map +1 -1
  267. package/dist/server/readConfig.d.ts +3 -0
  268. package/dist/server/readConfig.d.ts.map +1 -1
  269. package/dist/server/readConfig.js +0 -21
  270. package/dist/server/readConfig.js.map +1 -1
  271. package/dist/server/storageMode.d.ts +1 -1
  272. package/dist/source/{adapter.d.ts → adapters/adapter.d.ts} +10 -4
  273. package/dist/source/adapters/adapter.d.ts.map +1 -0
  274. package/dist/source/adapters/adapter.js.map +1 -0
  275. package/dist/source/adapters/adapterFactory.d.ts.map +1 -0
  276. package/dist/source/{adapterFactory.js → adapters/adapterFactory.js} +1 -1
  277. package/dist/source/adapters/adapterFactory.js.map +1 -0
  278. package/dist/source/adapters/adapterProfile.d.ts.map +1 -0
  279. package/dist/source/adapters/adapterProfile.js.map +1 -0
  280. package/dist/source/{conformance.d.ts → adapters/conformance.d.ts} +1 -1
  281. package/dist/source/adapters/conformance.d.ts.map +1 -0
  282. package/dist/source/{conformance.js → adapters/conformance.js} +1 -1
  283. package/dist/source/adapters/conformance.js.map +1 -0
  284. package/dist/source/{contract.d.ts → adapters/contract.d.ts} +20 -75
  285. package/dist/source/adapters/contract.d.ts.map +1 -0
  286. package/dist/source/{contract.js → adapters/contract.js} +20 -55
  287. package/dist/source/adapters/contract.js.map +1 -0
  288. package/dist/source/adapters/drizzle.d.ts +1 -1
  289. package/dist/source/adapters/drizzle.d.ts.map +1 -1
  290. package/dist/source/adapters/drizzle.js +54 -25
  291. package/dist/source/adapters/drizzle.js.map +1 -1
  292. package/dist/source/adapters/idempotency.d.ts.map +1 -0
  293. package/dist/source/{idempotency.js → adapters/idempotency.js} +2 -2
  294. package/dist/source/adapters/idempotency.js.map +1 -0
  295. package/dist/source/adapters/index.d.ts +21 -0
  296. package/dist/source/adapters/index.d.ts.map +1 -0
  297. package/dist/source/adapters/index.js +21 -0
  298. package/dist/source/adapters/index.js.map +1 -0
  299. package/dist/source/adapters/kysely.d.ts +3 -1
  300. package/dist/source/adapters/kysely.d.ts.map +1 -1
  301. package/dist/source/adapters/kysely.js +49 -23
  302. package/dist/source/adapters/kysely.js.map +1 -1
  303. package/dist/source/adapters/kyselyMutationCore.d.ts +6 -3
  304. package/dist/source/adapters/kyselyMutationCore.d.ts.map +1 -1
  305. package/dist/source/adapters/kyselyMutationCore.js +17 -8
  306. package/dist/source/adapters/kyselyMutationCore.js.map +1 -1
  307. package/dist/source/adapters/memory.d.ts +3 -3
  308. package/dist/source/adapters/memory.d.ts.map +1 -1
  309. package/dist/source/adapters/memory.js +20 -7
  310. package/dist/source/adapters/memory.js.map +1 -1
  311. package/dist/source/adapters/migration.d.ts +8 -0
  312. package/dist/source/adapters/migration.d.ts.map +1 -0
  313. package/dist/source/adapters/migration.js +9 -0
  314. package/dist/source/adapters/migration.js.map +1 -0
  315. package/dist/source/{migrations.d.ts → adapters/migrations.d.ts} +3 -4
  316. package/dist/source/adapters/migrations.d.ts.map +1 -0
  317. package/dist/source/{migrations.js → adapters/migrations.js} +4 -31
  318. package/dist/source/adapters/migrations.js.map +1 -0
  319. package/dist/source/adapters/prisma.d.ts +1 -1
  320. package/dist/source/adapters/prisma.d.ts.map +1 -1
  321. package/dist/source/adapters/prisma.js +75 -30
  322. package/dist/source/adapters/prisma.js.map +1 -1
  323. package/dist/source/adapters/subjectAuthorization.d.ts +16 -0
  324. package/dist/source/adapters/subjectAuthorization.d.ts.map +1 -0
  325. package/dist/source/adapters/subjectAuthorization.js +126 -0
  326. package/dist/source/adapters/subjectAuthorization.js.map +1 -0
  327. package/dist/source/{connector.d.ts → connector/client.d.ts} +6 -1
  328. package/dist/source/connector/client.d.ts.map +1 -0
  329. package/dist/source/{connector.js → connector/client.js} +28 -11
  330. package/dist/source/connector/client.js.map +1 -0
  331. package/dist/source/connector/index.d.ts +4 -0
  332. package/dist/source/connector/index.d.ts.map +1 -0
  333. package/dist/source/connector/index.js +4 -0
  334. package/dist/source/connector/index.js.map +1 -0
  335. package/dist/source/{connectorProtocol.d.ts → connector/protocol.d.ts} +8 -1
  336. package/dist/source/connector/protocol.d.ts.map +1 -0
  337. package/dist/source/{connectorProtocol.js → connector/protocol.js} +10 -3
  338. package/dist/source/connector/protocol.js.map +1 -0
  339. package/dist/source/delivery/index.d.ts +3 -0
  340. package/dist/source/delivery/index.d.ts.map +1 -0
  341. package/dist/source/delivery/index.js +3 -0
  342. package/dist/source/delivery/index.js.map +1 -0
  343. package/dist/source/{pushQueue.d.ts → delivery/pushQueue.d.ts} +1 -1
  344. package/dist/source/delivery/pushQueue.d.ts.map +1 -0
  345. package/dist/source/{pushQueue.js → delivery/pushQueue.js} +1 -1
  346. package/dist/source/delivery/pushQueue.js.map +1 -0
  347. package/dist/source/{factory.d.ts → endpoint/factory.d.ts} +9 -3
  348. package/dist/source/endpoint/factory.d.ts.map +1 -0
  349. package/dist/source/{factory.js → endpoint/factory.js} +122 -6
  350. package/dist/source/endpoint/factory.js.map +1 -0
  351. package/dist/source/endpoint/index.d.ts +5 -0
  352. package/dist/source/endpoint/index.d.ts.map +1 -0
  353. package/dist/source/endpoint/index.js +5 -0
  354. package/dist/source/endpoint/index.js.map +1 -0
  355. package/dist/source/{next.d.ts → endpoint/next.d.ts} +2 -2
  356. package/dist/source/endpoint/next.d.ts.map +1 -0
  357. package/dist/source/{next.js → endpoint/next.js} +1 -1
  358. package/dist/source/endpoint/next.js.map +1 -0
  359. package/dist/source/{signing.d.ts → endpoint/signing.d.ts} +1 -1
  360. package/dist/source/endpoint/signing.d.ts.map +1 -0
  361. package/dist/source/{signing.js → endpoint/signing.js} +1 -1
  362. package/dist/source/endpoint/signing.js.map +1 -0
  363. package/dist/source/index.d.ts +15 -12
  364. package/dist/source/index.d.ts.map +1 -1
  365. package/dist/source/index.js +13 -10
  366. package/dist/source/index.js.map +1 -1
  367. package/dist/source/outbox/contract.d.ts +50 -0
  368. package/dist/source/outbox/contract.d.ts.map +1 -0
  369. package/dist/source/outbox/contract.js +50 -0
  370. package/dist/source/outbox/contract.js.map +1 -0
  371. package/dist/source/outbox/envelope.d.ts +9 -0
  372. package/dist/source/outbox/envelope.d.ts.map +1 -0
  373. package/dist/source/outbox/envelope.js +36 -0
  374. package/dist/source/outbox/envelope.js.map +1 -0
  375. package/dist/source/outbox/index.d.ts +11 -0
  376. package/dist/source/outbox/index.d.ts.map +1 -0
  377. package/dist/source/outbox/index.js +11 -0
  378. package/dist/source/outbox/index.js.map +1 -0
  379. package/dist/source/outbox/migrations.d.ts +4 -0
  380. package/dist/source/outbox/migrations.d.ts.map +1 -0
  381. package/dist/source/outbox/migrations.js +67 -0
  382. package/dist/source/outbox/migrations.js.map +1 -0
  383. package/dist/source/outbox/retention.d.ts +3 -0
  384. package/dist/source/outbox/retention.d.ts.map +1 -0
  385. package/dist/source/outbox/retention.js +3 -0
  386. package/dist/source/outbox/retention.js.map +1 -0
  387. package/dist/source/types.d.ts +59 -10
  388. package/dist/source/types.d.ts.map +1 -1
  389. package/dist/source/types.js +2 -0
  390. package/dist/source/types.js.map +1 -1
  391. package/dist/syncLog/contract.d.ts +19 -8
  392. package/dist/syncLog/contract.d.ts.map +1 -1
  393. package/dist/syncLog/contract.js +19 -6
  394. package/dist/syncLog/contract.js.map +1 -1
  395. package/dist/testing/fixtures/httpResponses.d.ts +6 -0
  396. package/dist/testing/fixtures/httpResponses.d.ts.map +1 -1
  397. package/dist/testing/fixtures/httpResponses.js +1 -0
  398. package/dist/testing/fixtures/httpResponses.js.map +1 -1
  399. package/dist/transport/{credentialLifecycle.d.ts → connection/credentialLifecycle.d.ts} +3 -3
  400. package/dist/transport/connection/credentialLifecycle.d.ts.map +1 -0
  401. package/dist/transport/{credentialLifecycle.js → connection/credentialLifecycle.js} +2 -2
  402. package/dist/transport/connection/credentialLifecycle.js.map +1 -0
  403. package/dist/transport/connection/index.d.ts +5 -0
  404. package/dist/transport/connection/index.d.ts.map +1 -0
  405. package/dist/transport/connection/index.js +5 -0
  406. package/dist/transport/connection/index.js.map +1 -0
  407. package/dist/transport/{connectionManager.d.ts → connection/manager.d.ts} +13 -5
  408. package/dist/transport/connection/manager.d.ts.map +1 -0
  409. package/dist/transport/{connectionManager.js → connection/manager.js} +6 -4
  410. package/dist/transport/connection/manager.js.map +1 -0
  411. package/dist/transport/{networkProbe.d.ts → connection/networkProbe.d.ts} +2 -2
  412. package/dist/transport/connection/networkProbe.d.ts.map +1 -0
  413. package/dist/transport/{networkProbe.js → connection/networkProbe.js} +4 -4
  414. package/dist/transport/connection/networkProbe.js.map +1 -0
  415. package/dist/transport/{httpClient.d.ts → http/client.d.ts} +32 -44
  416. package/dist/transport/http/client.d.ts.map +1 -0
  417. package/dist/transport/{httpClient.js → http/client.js} +96 -105
  418. package/dist/transport/http/client.js.map +1 -0
  419. package/dist/transport/http/helpers.d.ts +10 -0
  420. package/dist/transport/http/helpers.d.ts.map +1 -0
  421. package/dist/transport/http/helpers.js +46 -0
  422. package/dist/transport/http/helpers.js.map +1 -0
  423. package/dist/transport/http/index.d.ts +6 -0
  424. package/dist/transport/http/index.d.ts.map +1 -0
  425. package/dist/transport/http/index.js +6 -0
  426. package/dist/transport/http/index.js.map +1 -0
  427. package/dist/transport/{httpOptions.d.ts → http/options.d.ts} +7 -7
  428. package/dist/transport/{httpOptions.d.ts.map → http/options.d.ts.map} +1 -1
  429. package/dist/transport/{httpOptions.js → http/options.js} +1 -1
  430. package/dist/transport/http/options.js.map +1 -0
  431. package/dist/transport/http/subscription.d.ts +16 -0
  432. package/dist/transport/http/subscription.d.ts.map +1 -0
  433. package/dist/transport/http/subscription.js +146 -0
  434. package/dist/transport/http/subscription.js.map +1 -0
  435. package/dist/transport/{httpTransport.d.ts → http/transport.d.ts} +9 -6
  436. package/dist/transport/http/transport.d.ts.map +1 -0
  437. package/dist/transport/{httpTransport.js → http/transport.js} +153 -188
  438. package/dist/transport/http/transport.js.map +1 -0
  439. package/dist/transport/index.d.ts +8 -0
  440. package/dist/transport/index.d.ts.map +1 -0
  441. package/dist/transport/index.js +8 -0
  442. package/dist/transport/index.js.map +1 -0
  443. package/dist/transport/{commitFrames.d.ts → websocket/commitFrames.d.ts} +8 -20
  444. package/dist/transport/websocket/commitFrames.d.ts.map +1 -0
  445. package/dist/transport/{commitFrames.js → websocket/commitFrames.js} +6 -25
  446. package/dist/transport/websocket/commitFrames.js.map +1 -0
  447. package/dist/transport/{wsFrameHandlers.d.ts → websocket/frameHandlers.d.ts} +5 -5
  448. package/dist/transport/websocket/frameHandlers.d.ts.map +1 -0
  449. package/dist/transport/{wsFrameHandlers.js → websocket/frameHandlers.js} +10 -51
  450. package/dist/transport/websocket/frameHandlers.js.map +1 -0
  451. package/dist/transport/{heartbeat.d.ts → websocket/heartbeat.d.ts} +1 -1
  452. package/dist/transport/websocket/heartbeat.d.ts.map +1 -0
  453. package/dist/transport/{heartbeat.js → websocket/heartbeat.js} +2 -2
  454. package/dist/transport/websocket/heartbeat.js.map +1 -0
  455. package/dist/transport/websocket/index.d.ts +6 -0
  456. package/dist/transport/websocket/index.d.ts.map +1 -0
  457. package/dist/transport/websocket/index.js +6 -0
  458. package/dist/transport/websocket/index.js.map +1 -0
  459. package/dist/transport/{wsTransport.d.ts → websocket/transport.d.ts} +13 -25
  460. package/dist/transport/websocket/transport.d.ts.map +1 -0
  461. package/dist/transport/{wsTransport.js → websocket/transport.js} +14 -14
  462. package/dist/transport/websocket/transport.js.map +1 -0
  463. package/dist/types/index.d.ts +1 -1
  464. package/dist/types/index.d.ts.map +1 -1
  465. package/dist/types/streams.d.ts +8 -48
  466. package/dist/types/streams.d.ts.map +1 -1
  467. package/dist/types/streams.js +2 -2
  468. package/dist/wire/accountResponses.d.ts +4 -72
  469. package/dist/wire/accountResponses.d.ts.map +1 -1
  470. package/dist/wire/accountResponses.js +2 -10
  471. package/dist/wire/accountResponses.js.map +1 -1
  472. package/dist/wire/apiLifecycle.d.ts +63 -0
  473. package/dist/wire/apiLifecycle.d.ts.map +1 -0
  474. package/dist/wire/apiLifecycle.js +89 -0
  475. package/dist/wire/apiLifecycle.js.map +1 -0
  476. package/dist/wire/frames.d.ts +6 -83
  477. package/dist/wire/frames.d.ts.map +1 -1
  478. package/dist/wire/frames.js +4 -11
  479. package/dist/wire/frames.js.map +1 -1
  480. package/dist/wire/inboundFrames.d.ts +6 -131
  481. package/dist/wire/inboundFrames.d.ts.map +1 -1
  482. package/dist/wire/inboundFrames.js +3 -3
  483. package/dist/wire/inboundFrames.js.map +1 -1
  484. package/dist/wire/index.d.ts +20 -15
  485. package/dist/wire/index.d.ts.map +1 -1
  486. package/dist/wire/index.js +22 -8
  487. package/dist/wire/index.js.map +1 -1
  488. package/dist/wire/modelMutations.d.ts +1 -32
  489. package/dist/wire/modelMutations.d.ts.map +1 -1
  490. package/dist/wire/modelMutations.js +1 -8
  491. package/dist/wire/modelMutations.js.map +1 -1
  492. package/dist/wire/rateLimit.d.ts +82 -0
  493. package/dist/wire/rateLimit.d.ts.map +1 -0
  494. package/dist/wire/rateLimit.js +142 -0
  495. package/dist/wire/rateLimit.js.map +1 -0
  496. package/package.json +130 -10
  497. package/src/ai-sdk/modelTools.ts +5 -5
  498. package/src/ai-sdk/updateTool.ts +5 -7
  499. package/src/auth/capability.ts +5 -0
  500. package/src/auth/capabilityLifecycle.ts +1 -1
  501. package/src/auth/credentialPolicy.ts +1 -1
  502. package/src/auth/identity.ts +7 -7
  503. package/src/auth/index.ts +4 -663
  504. package/src/auth/runtime.ts +669 -0
  505. package/src/auth/sessionMint.ts +3 -2
  506. package/src/branches.ts +3 -0
  507. package/src/{coordination/awaitClaimGrant.ts → claims/awaitGrant.ts} +4 -4
  508. package/src/{wire/claims.ts → claims/contract.ts} +1 -1
  509. package/src/{coordination → claims}/events.ts +7 -11
  510. package/src/claims/index.ts +21 -0
  511. package/src/claims/lifetime.ts +78 -0
  512. package/src/{coordination → claims}/locator.ts +3 -3
  513. package/src/claims/routes.ts +81 -0
  514. package/src/{coordination → claims}/trace.ts +5 -5
  515. package/src/{ablo.ts → client/ablo.ts} +8 -20
  516. package/src/{transactionLayer.ts → client/contract.ts} +11 -13
  517. package/src/{headlessClient.ts → client/headless.ts} +13 -15
  518. package/src/client/index.ts +10 -0
  519. package/src/{resources → client/resources}/functionalUpdate.ts +4 -4
  520. package/src/{resources → client/resources}/httpResources.ts +163 -92
  521. package/src/client/resources/modelCreate.ts +73 -0
  522. package/src/{resources → client/resources}/modelOperations.ts +73 -55
  523. package/src/{resources → client/resources}/mutationOptions.ts +4 -17
  524. package/src/{resources → client/resources}/where.ts +1 -1
  525. package/src/{resources → client/resources}/writeOptionsSchema.ts +35 -27
  526. package/src/{transactions → commit}/confirmation/commitEnvelope.ts +2 -12
  527. package/src/{transactions → commit}/confirmation/httpCommitEnvelope.ts +1 -1
  528. package/src/{transactions → commit}/confirmation/pendingWrite.ts +1 -1
  529. package/src/{wire/commit.ts → commit/contract.ts} +27 -26
  530. package/src/{durableWrites.ts → commit/durableWrites.ts} +7 -7
  531. package/src/commit/httpRequest.ts +103 -0
  532. package/src/commit/index.ts +16 -0
  533. package/src/{readSetContext.ts → commit/readSetContext.ts} +24 -43
  534. package/src/{commitRecordRuntime.ts → commit/recordRuntime.ts} +12 -67
  535. package/src/coordination/index.ts +4 -54
  536. package/src/coordination/schema.ts +15 -309
  537. package/src/errorCodes.ts +62 -10
  538. package/src/errors.ts +32 -10
  539. package/src/index.ts +8 -8
  540. package/src/internal/read-set.ts +3 -6
  541. package/src/observability.ts +4 -4
  542. package/src/{wire/delta.ts → observation/contract.ts} +2 -2
  543. package/src/{wire/feedEvent.ts → observation/feedContract.ts} +3 -4
  544. package/src/{transport → observation}/httpFeed.ts +3 -3
  545. package/src/observation/index.ts +12 -0
  546. package/src/{log → observation/persistence}/syncDeltaRow.ts +6 -7
  547. package/src/pricing.ts +46 -25
  548. package/src/schema/audit.ts +121 -0
  549. package/src/schema/ddl.ts +71 -1
  550. package/src/schema/index.ts +20 -20
  551. package/src/schema/model.ts +17 -33
  552. package/src/schema/openapi.ts +170 -9
  553. package/src/schema/roles.ts +53 -0
  554. package/src/schema/schema.ts +91 -6
  555. package/src/schema/serialize.ts +8 -9
  556. package/src/schema/subject.ts +43 -0
  557. package/src/server/adapter.ts +3 -1
  558. package/src/server/commit.ts +6 -14
  559. package/src/server/index.ts +1 -1
  560. package/src/server/readConfig.ts +4 -0
  561. package/src/source/{adapter.ts → adapters/adapter.ts} +9 -5
  562. package/src/source/{adapterFactory.ts → adapters/adapterFactory.ts} +1 -1
  563. package/src/source/{conformance.ts → adapters/conformance.ts} +1 -1
  564. package/src/source/{contract.ts → adapters/contract.ts} +24 -61
  565. package/src/source/adapters/drizzle.ts +75 -29
  566. package/src/source/{idempotency.ts → adapters/idempotency.ts} +2 -2
  567. package/src/source/adapters/index.ts +20 -0
  568. package/src/source/adapters/kysely.ts +77 -27
  569. package/src/source/adapters/kyselyMutationCore.ts +23 -11
  570. package/src/source/adapters/memory.ts +26 -9
  571. package/src/source/adapters/migration.ts +11 -0
  572. package/src/source/{migrations.ts → adapters/migrations.ts} +6 -33
  573. package/src/source/adapters/prisma.ts +98 -34
  574. package/src/source/adapters/subjectAuthorization.ts +182 -0
  575. package/src/source/{connector.ts → connector/client.ts} +35 -12
  576. package/src/source/connector/index.ts +3 -0
  577. package/src/source/{connectorProtocol.ts → connector/protocol.ts} +10 -2
  578. package/src/source/delivery/index.ts +2 -0
  579. package/src/source/{pushQueue.ts → delivery/pushQueue.ts} +2 -2
  580. package/src/source/{factory.ts → endpoint/factory.ts} +150 -9
  581. package/src/source/endpoint/index.ts +4 -0
  582. package/src/source/{next.ts → endpoint/next.ts} +2 -2
  583. package/src/source/{signing.ts → endpoint/signing.ts} +1 -1
  584. package/src/source/index.ts +27 -18
  585. package/src/source/outbox/contract.ts +56 -0
  586. package/src/source/outbox/envelope.ts +47 -0
  587. package/src/source/outbox/index.ts +15 -0
  588. package/src/source/outbox/migrations.ts +71 -0
  589. package/src/source/outbox/retention.ts +2 -0
  590. package/src/source/types.ts +64 -10
  591. package/src/syncLog/contract.ts +19 -9
  592. package/src/testing/fixtures/httpResponses.ts +7 -0
  593. package/src/transport/{credentialLifecycle.ts → connection/credentialLifecycle.ts} +3 -3
  594. package/src/transport/connection/index.ts +4 -0
  595. package/src/transport/{connectionManager.ts → connection/manager.ts} +13 -4
  596. package/src/transport/{networkProbe.ts → connection/networkProbe.ts} +4 -4
  597. package/src/transport/{httpClient.ts → http/client.ts} +165 -184
  598. package/src/transport/http/helpers.ts +63 -0
  599. package/src/transport/http/index.ts +5 -0
  600. package/src/transport/{httpOptions.ts → http/options.ts} +6 -6
  601. package/src/transport/http/subscription.ts +174 -0
  602. package/src/transport/{httpTransport.ts → http/transport.ts} +210 -246
  603. package/src/transport/index.ts +7 -0
  604. package/src/transport/{commitFrames.ts → websocket/commitFrames.ts} +14 -46
  605. package/src/transport/{wsFrameHandlers.ts → websocket/frameHandlers.ts} +11 -54
  606. package/src/transport/{heartbeat.ts → websocket/heartbeat.ts} +2 -2
  607. package/src/transport/websocket/index.ts +5 -0
  608. package/src/transport/{wsTransport.ts → websocket/transport.ts} +16 -30
  609. package/src/types/index.ts +2 -6
  610. package/src/types/streams.ts +7 -61
  611. package/src/webhooks/events.ts +1 -1
  612. package/src/wire/accountResponses.ts +3 -12
  613. package/src/wire/apiLifecycle.ts +94 -0
  614. package/src/wire/frames.ts +5 -15
  615. package/src/wire/inboundFrames.ts +3 -3
  616. package/src/wire/index.ts +50 -15
  617. package/src/wire/modelMutations.ts +1 -14
  618. package/src/wire/rateLimit.ts +155 -0
  619. package/dist/ablo.d.ts.map +0 -1
  620. package/dist/ablo.js.map +0 -1
  621. package/dist/commitRecordRuntime.d.ts.map +0 -1
  622. package/dist/commitRecordRuntime.js.map +0 -1
  623. package/dist/coordination/awaitClaimGrant.d.ts.map +0 -1
  624. package/dist/coordination/awaitClaimGrant.js.map +0 -1
  625. package/dist/coordination/claimHeartbeatLoop.d.ts.map +0 -1
  626. package/dist/coordination/claimHeartbeatLoop.js.map +0 -1
  627. package/dist/coordination/claimMeta.d.ts.map +0 -1
  628. package/dist/coordination/claimMeta.js.map +0 -1
  629. package/dist/coordination/events.d.ts.map +0 -1
  630. package/dist/coordination/events.js +0 -8
  631. package/dist/coordination/events.js.map +0 -1
  632. package/dist/coordination/locator.d.ts.map +0 -1
  633. package/dist/coordination/locator.js.map +0 -1
  634. package/dist/coordination/targetConflict.d.ts.map +0 -1
  635. package/dist/coordination/targetConflict.js.map +0 -1
  636. package/dist/coordination/trace.d.ts.map +0 -1
  637. package/dist/coordination/trace.js.map +0 -1
  638. package/dist/durableWrites.d.ts.map +0 -1
  639. package/dist/durableWrites.js.map +0 -1
  640. package/dist/headlessClient.d.ts.map +0 -1
  641. package/dist/log/syncDeltaRow.d.ts.map +0 -1
  642. package/dist/log/syncDeltaRow.js.map +0 -1
  643. package/dist/policy/types.d.ts +0 -226
  644. package/dist/policy/types.d.ts.map +0 -1
  645. package/dist/policy/types.js +0 -127
  646. package/dist/policy/types.js.map +0 -1
  647. package/dist/readSetContext.d.ts.map +0 -1
  648. package/dist/readSetContext.js.map +0 -1
  649. package/dist/resources/functionalUpdate.d.ts.map +0 -1
  650. package/dist/resources/functionalUpdate.js.map +0 -1
  651. package/dist/resources/httpResources.d.ts.map +0 -1
  652. package/dist/resources/httpResources.js +0 -17
  653. package/dist/resources/httpResources.js.map +0 -1
  654. package/dist/resources/modelOperations.d.ts.map +0 -1
  655. package/dist/resources/modelOperations.js.map +0 -1
  656. package/dist/resources/mutationOptions.d.ts.map +0 -1
  657. package/dist/resources/mutationOptions.js.map +0 -1
  658. package/dist/resources/where.d.ts.map +0 -1
  659. package/dist/resources/where.js.map +0 -1
  660. package/dist/resources/writeOptionsSchema.d.ts.map +0 -1
  661. package/dist/resources/writeOptionsSchema.js.map +0 -1
  662. package/dist/schema/coordination.d.ts +0 -113
  663. package/dist/schema/coordination.d.ts.map +0 -1
  664. package/dist/schema/coordination.js +0 -134
  665. package/dist/schema/coordination.js.map +0 -1
  666. package/dist/source/adapter.d.ts.map +0 -1
  667. package/dist/source/adapter.js.map +0 -1
  668. package/dist/source/adapterFactory.d.ts.map +0 -1
  669. package/dist/source/adapterFactory.js.map +0 -1
  670. package/dist/source/adapterProfile.d.ts.map +0 -1
  671. package/dist/source/adapterProfile.js.map +0 -1
  672. package/dist/source/conformance.d.ts.map +0 -1
  673. package/dist/source/conformance.js.map +0 -1
  674. package/dist/source/connector.d.ts.map +0 -1
  675. package/dist/source/connector.js.map +0 -1
  676. package/dist/source/connectorProtocol.d.ts.map +0 -1
  677. package/dist/source/connectorProtocol.js.map +0 -1
  678. package/dist/source/contract.d.ts.map +0 -1
  679. package/dist/source/contract.js.map +0 -1
  680. package/dist/source/drizzle.d.ts +0 -2
  681. package/dist/source/drizzle.d.ts.map +0 -1
  682. package/dist/source/drizzle.js +0 -2
  683. package/dist/source/drizzle.js.map +0 -1
  684. package/dist/source/factory.d.ts.map +0 -1
  685. package/dist/source/factory.js.map +0 -1
  686. package/dist/source/idempotency.d.ts.map +0 -1
  687. package/dist/source/idempotency.js.map +0 -1
  688. package/dist/source/kysely.d.ts +0 -3
  689. package/dist/source/kysely.d.ts.map +0 -1
  690. package/dist/source/kysely.js +0 -3
  691. package/dist/source/kysely.js.map +0 -1
  692. package/dist/source/migrations.d.ts.map +0 -1
  693. package/dist/source/migrations.js.map +0 -1
  694. package/dist/source/next.d.ts.map +0 -1
  695. package/dist/source/next.js.map +0 -1
  696. package/dist/source/pushQueue.d.ts.map +0 -1
  697. package/dist/source/pushQueue.js.map +0 -1
  698. package/dist/source/signing.d.ts.map +0 -1
  699. package/dist/source/signing.js.map +0 -1
  700. package/dist/transactionLayer.d.ts.map +0 -1
  701. package/dist/transactionLayer.js.map +0 -1
  702. package/dist/transactions/confirmation/commitEnvelope.d.ts.map +0 -1
  703. package/dist/transactions/confirmation/commitEnvelope.js.map +0 -1
  704. package/dist/transactions/confirmation/httpCommitEnvelope.d.ts.map +0 -1
  705. package/dist/transactions/confirmation/httpCommitEnvelope.js.map +0 -1
  706. package/dist/transactions/confirmation/idempotencyKey.d.ts.map +0 -1
  707. package/dist/transactions/confirmation/idempotencyKey.js.map +0 -1
  708. package/dist/transactions/confirmation/pendingWrite.d.ts.map +0 -1
  709. package/dist/transactions/confirmation/pendingWrite.js.map +0 -1
  710. package/dist/transport/commitFrames.d.ts.map +0 -1
  711. package/dist/transport/commitFrames.js.map +0 -1
  712. package/dist/transport/connectionManager.d.ts.map +0 -1
  713. package/dist/transport/connectionManager.js.map +0 -1
  714. package/dist/transport/credentialLifecycle.d.ts.map +0 -1
  715. package/dist/transport/credentialLifecycle.js.map +0 -1
  716. package/dist/transport/heartbeat.d.ts.map +0 -1
  717. package/dist/transport/heartbeat.js.map +0 -1
  718. package/dist/transport/httpClient.d.ts.map +0 -1
  719. package/dist/transport/httpClient.js.map +0 -1
  720. package/dist/transport/httpFeed.d.ts +0 -4
  721. package/dist/transport/httpFeed.d.ts.map +0 -1
  722. package/dist/transport/httpOptions.js.map +0 -1
  723. package/dist/transport/httpTransport.d.ts.map +0 -1
  724. package/dist/transport/httpTransport.js.map +0 -1
  725. package/dist/transport/networkProbe.d.ts.map +0 -1
  726. package/dist/transport/networkProbe.js.map +0 -1
  727. package/dist/transport/wsFrameHandlers.d.ts.map +0 -1
  728. package/dist/transport/wsFrameHandlers.js.map +0 -1
  729. package/dist/transport/wsTransport.d.ts.map +0 -1
  730. package/dist/transport/wsTransport.js.map +0 -1
  731. package/dist/wire/claimEvent.d.ts.map +0 -1
  732. package/dist/wire/claimEvent.js.map +0 -1
  733. package/dist/wire/claims.d.ts.map +0 -1
  734. package/dist/wire/claims.js.map +0 -1
  735. package/dist/wire/commit.d.ts +0 -2801
  736. package/dist/wire/commit.d.ts.map +0 -1
  737. package/dist/wire/commit.js.map +0 -1
  738. package/dist/wire/delta.d.ts.map +0 -1
  739. package/dist/wire/delta.js.map +0 -1
  740. package/dist/wire/deltaDelivery.d.ts.map +0 -1
  741. package/dist/wire/deltaDelivery.js.map +0 -1
  742. package/dist/wire/feedCursor.d.ts.map +0 -1
  743. package/dist/wire/feedCursor.js.map +0 -1
  744. package/dist/wire/feedEvent.d.ts.map +0 -1
  745. package/dist/wire/feedEvent.js.map +0 -1
  746. package/src/policy/types.ts +0 -300
  747. package/src/schema/coordination.ts +0 -161
  748. package/src/source/drizzle.ts +0 -1
  749. package/src/source/kysely.ts +0 -2
  750. /package/dist/{coordination → claims}/targetConflict.d.ts +0 -0
  751. /package/dist/{coordination → claims}/targetConflict.js +0 -0
  752. /package/dist/{resources → client/resources}/mutationOptions.js +0 -0
  753. /package/dist/{resources → client/resources}/where.d.ts +0 -0
  754. /package/dist/{transactions → commit}/confirmation/httpCommitEnvelope.d.ts +0 -0
  755. /package/dist/{transactions → commit}/confirmation/idempotencyKey.d.ts +0 -0
  756. /package/dist/{transactions → commit}/confirmation/idempotencyKey.js +0 -0
  757. /package/dist/source/{adapter.js → adapters/adapter.js} +0 -0
  758. /package/dist/source/{adapterFactory.d.ts → adapters/adapterFactory.d.ts} +0 -0
  759. /package/dist/source/{adapterProfile.d.ts → adapters/adapterProfile.d.ts} +0 -0
  760. /package/dist/source/{adapterProfile.js → adapters/adapterProfile.js} +0 -0
  761. /package/dist/source/{idempotency.d.ts → adapters/idempotency.d.ts} +0 -0
  762. /package/src/{wire/claimEvent.ts → claims/eventContract.ts} +0 -0
  763. /package/src/{coordination/claimHeartbeatLoop.ts → claims/heartbeat.ts} +0 -0
  764. /package/src/{coordination/claimMeta.ts → claims/meta.ts} +0 -0
  765. /package/src/{coordination → claims}/targetConflict.ts +0 -0
  766. /package/src/{transactions → commit}/confirmation/idempotencyKey.ts +0 -0
  767. /package/src/{wire/feedCursor.ts → observation/cursor.ts} +0 -0
  768. /package/src/{wire/deltaDelivery.ts → observation/deliveryContract.ts} +0 -0
  769. /package/src/source/{adapterProfile.ts → adapters/adapterProfile.ts} +0 -0
@@ -21,6 +21,7 @@
21
21
  import { z } from 'zod';
22
22
  import type { RelationDef } from './relation.js';
23
23
  import type { EntityRole, GroupsInput } from './roles.js';
24
+ import type { SubjectRule } from './subject.js';
24
25
  import { getFieldMeta, inferFieldMetaFromZod, type FieldMeta } from './field.js';
25
26
  // Tenancy lives in `tenancy.ts`. Authoring uses the `policy` option
26
27
  // (`PolicyInput`), which `resolvePolicy` normalizes into the canonical `Tenancy`
@@ -28,11 +29,6 @@ import { getFieldMeta, inferFieldMetaFromZod, type FieldMeta } from './field.js'
28
29
  import { resolvePolicy, type Tenancy, type ScopedViaRef, type PolicyInput } from './tenancy.js';
29
30
  export type { ScopedViaRef, Tenancy, PolicyInput } from './tenancy.js';
30
31
  import { DEFAULT_RESIDENCY, type ModelResidency } from './residency.js';
31
- // The write-conflict disposition. It is plain data (the `onStale` vocabulary) so it
32
- // round-trips through schema serialization, and the engine interprets it when a
33
- // commit is applied.
34
- import type { ConflictAxis } from '../policy/types.js';
35
- export type { ConflictAxis } from '../policy/types.js';
36
32
 
37
33
  /** Normalize the `entityRoles` option (single | array | undefined) to an array. */
38
34
  function normalizeEntityRoles(
@@ -152,6 +148,14 @@ export interface ModelOptions {
152
148
  */
153
149
  policy?: PolicyInput;
154
150
 
151
+ /**
152
+ * Credential-bound row authorization below organization tenancy. The named
153
+ * row field must match a trusted credential group: `{ field: 'workspaceId',
154
+ * group: 'workspace' }` authorizes only rows whose `workspaceId` has a
155
+ * matching `workspace:<id>` group on the request.
156
+ */
157
+ subject?: SubjectRule;
158
+
155
159
  /**
156
160
  * Which database a model's rows live in. `tenant` (the default) is tenant data
157
161
  * that provisioning places in the customer's own database; `control` is Ablo's own
@@ -176,6 +180,8 @@ export interface ModelOptions {
176
180
  * - `roles` — explicit record-to-group roles keyed on a plain field, for routing
177
181
  * that does not follow a relation, such as fanning a message into a recipient's
178
182
  * inbox. Accepts one role or many.
183
+ * - `routingOnly: true` — explicitly acknowledges that these delivery groups
184
+ * are intentionally narrower than the model's independently safe read policy.
179
185
  *
180
186
  * ```ts
181
187
  * // archiveMember: { userId, archiveId }
@@ -186,29 +192,6 @@ export interface ModelOptions {
186
192
  */
187
193
  groups?: GroupsInput;
188
194
 
189
- /**
190
- * Write-conflict disposition, set per committer kind — decides what happens when a
191
- * commit collides with another participant's claim or with a stale snapshot of this
192
- * model. This is independent of {@link policy} (read access) and {@link groups}
193
- * (delta routing). It is a map keyed by the committer's kind (`user`, `agent`, or
194
- * `system`), with these outcomes as values:
195
- *
196
- * - `'overwrite'` — the write wins; that committer is never blocked.
197
- * - `'reject'` — the write is refused; that committer yields.
198
- * - `'notify'` — hold the write and hand the current value back so the committer
199
- * re-reads and re-applies (for stale writes only).
200
- *
201
- * A kind you omit falls back to the engine default: reject, while honoring
202
- * `onStale: 'notify'`. The value is plain data that travels with the schema to the
203
- * server, where the engine interprets it. For example:
204
- *
205
- * ```ts
206
- * // "a human's edit always wins (never blocked); an agent yields"
207
- * conflict: { user: 'overwrite', agent: 'reject' }
208
- * ```
209
- */
210
- conflict?: ConflictAxis;
211
-
212
195
  /**
213
196
  * Whether clients may create, update, and delete this model's rows through the
214
197
  * commit protocol. Defaults to true: declaring a model in your schema is the
@@ -353,6 +336,8 @@ export interface ModelDef<
353
336
  /** The canonical tenancy descriptor for this model, normalized from the `policy`
354
337
  * option at build time. See {@link ModelOptions.policy}. */
355
338
  readonly tenancy: Tenancy;
339
+ /** Credential-bound row authorization. See {@link ModelOptions.subject}. */
340
+ readonly subject?: SubjectRule;
356
341
  /** Which database this model's rows live in — `tenant` (default) can be a
357
342
  * customer's own database; `control` is Ablo's. See {@link ModelOptions.plane}. */
358
343
  readonly plane?: ModelResidency;
@@ -362,9 +347,8 @@ export interface ModelDef<
362
347
  readonly grants?: GrantsRef;
363
348
  /** Explicit record-to-group roles, normalized to an array. See {@link ModelOptions.groups}. */
364
349
  readonly entityRoles?: readonly EntityRole[];
365
- /** The write-conflict disposition per committer kind, carried as plain data. See
366
- * {@link ModelOptions.conflict}. */
367
- readonly conflict?: ConflictAxis;
350
+ /** Explicit acknowledgement that sync groups are routing, not row access. */
351
+ readonly routingOnly?: true;
368
352
  /** Whether wire-level CREATE/UPDATE/DELETE is allowed. See {@link ModelOptions.mutable}. */
369
353
  readonly mutable?: boolean;
370
354
  /** Defer MobX setup until first observer access. See {@link ModelOptions.lazyObservable}. */
@@ -445,13 +429,13 @@ export function model<
445
429
  // Normalize the `policy` option into the canonical tenancy descriptor (defaults
446
430
  // to a row-local organization column).
447
431
  tenancy: resolvePolicy(options?.policy),
432
+ subject: options?.subject,
448
433
  plane: options?.plane ?? DEFAULT_RESIDENCY,
449
434
  // Unpack the `groups` option into the individual routing fields the server reads.
450
435
  scope: options?.groups?.root,
451
436
  grants: options?.groups?.grants,
452
437
  entityRoles: normalizeEntityRoles(options?.groups?.roles),
453
- // The conflict disposition is already plain data, so it passes through unchanged.
454
- conflict: options?.conflict,
438
+ routingOnly: options?.groups?.routingOnly,
455
439
  mutable: options?.mutable ?? true,
456
440
  lazyObservable: options?.lazyObservable,
457
441
  computed: options?.computed,
@@ -25,6 +25,7 @@ import type { FieldMeta } from './field.js';
25
25
  // Pulled from the endpoints module to keep this schema file free of the client's
26
26
  // error-handling and credential dependencies.
27
27
  import { ABLO_HOSTED_HTTP_BASE_URL } from '../auth/hostedEndpoints.js';
28
+ import { docUrlForCode } from '../errors.js';
28
29
  // The commit body is DERIVED from the schema the server validates against —
29
30
  // one definition site, so the documented surface cannot drift from the
30
31
  // enforced one.
@@ -35,7 +36,7 @@ import {
35
36
  commitRecordSchema,
36
37
  commitRecordListSchema,
37
38
  commitRecordWhereSchema,
38
- } from '../wire/commit.js';
39
+ } from '../commit/contract.js';
39
40
  import { CURSOR_PARAM, CURSOR_PARAM_ALIAS } from '../wire/listEnvelope.js';
40
41
  import {
41
42
  claimRequestSchema,
@@ -51,12 +52,26 @@ import {
51
52
  claimReorderRequestSchema,
52
53
  claimReorderReplySchema,
53
54
  claimReleaseReplySchema,
54
- } from '../wire/claims.js';
55
+ } from '../claims/contract.js';
55
56
  import { errorEnvelopeSchema } from '../wire/errorEnvelope.js';
57
+ // The lifecycle promise and the rate-limit fields are contract, not prose about
58
+ // contract: the document renders the same constants the server emits, so the
59
+ // published policy cannot describe a signal the runtime does not send.
60
+ import {
61
+ API_DEPRECATION_HEADER,
62
+ API_LIFECYCLE,
63
+ API_SUNSET_HEADER,
64
+ API_VERSION_HEADER,
65
+ } from '../wire/apiLifecycle.js';
66
+ import {
67
+ RATE_LIMIT_HEADER,
68
+ RATE_LIMIT_POLICY_HEADER,
69
+ RETRY_AFTER_HEADER,
70
+ } from '../wire/rateLimit.js';
56
71
  import { modelReadResponseSchema, modelListResponseSchema } from '../wire/modelResponses.js';
57
72
  import { modelMutationRequestSchema } from '../wire/modelMutations.js';
58
- import { logListResponseSchema, logQuerySchema } from '../wire/feedEvent.js';
59
- import { logDeliveryResponseSchema } from '../wire/deltaDelivery.js';
73
+ import { logListResponseSchema, logQuerySchema } from '../observation/feedContract.js';
74
+ import { logDeliveryResponseSchema } from '../observation/deliveryContract.js';
60
75
  import { schemaReadResponseSchema } from '../wire/accountResponses.js';
61
76
  import {
62
77
  ephemeralKeyRequestSchema,
@@ -400,6 +415,106 @@ const claimIdParam = (): Json => ({
400
415
  */
401
416
  const commitBody = (): Json => jsonBody(derive(commitRequestSchema, 'input'));
402
417
 
418
+ /**
419
+ * The response headers every operation carries, declared once under
420
+ * `components/headers` and referenced from each response.
421
+ *
422
+ * A header a caller is expected to act on has to be IN the document to be
423
+ * actionable: a generated client surfaces what the spec declares and drops what
424
+ * it does not, so an undeclared `RateLimit` is a header the caller never sees
425
+ * and therefore never paces against. Declaring them here rather than at each
426
+ * response is what keeps one description of each — the reason the names are
427
+ * imported rather than typed out.
428
+ */
429
+ const RESPONSE_HEADER_COMPONENTS: Readonly<Record<string, Json>> = {
430
+ AbloVersion: {
431
+ description:
432
+ 'The date-stamped contract version this response was served under. Record ' +
433
+ 'the value your integration was built against; a change means something ' +
434
+ 'observable was added.',
435
+ schema: { type: 'string', examples: ['2026-08-15'] },
436
+ },
437
+ RateLimitPolicy: {
438
+ description:
439
+ 'The standing allowance for this credential kind, as a Structured Fields ' +
440
+ 'List: `"secret";q=600;w=12`. It does not move between responses, so read ' +
441
+ 'it once and pace against it.',
442
+ schema: { type: 'string', examples: ['"secret";q=600;w=12'] },
443
+ },
444
+ RateLimit: {
445
+ description:
446
+ 'This caller\u2019s live position in the allowance: `r` units left, `t` ' +
447
+ 'seconds until they refill. Present once the request is attributed to a ' +
448
+ 'credential.',
449
+ schema: { type: 'string', examples: ['"secret";r=412;t=8'] },
450
+ },
451
+ RetryAfter: {
452
+ description: 'Whole seconds to wait before retrying. Sent with 429 and 503.',
453
+ schema: { type: 'integer', minimum: 1, examples: [8] },
454
+ },
455
+ RequestId: {
456
+ description:
457
+ 'Correlation id for this request, repeated in the error envelope\u2019s ' +
458
+ '`request_id`. Quote it in a support request.',
459
+ schema: { type: 'string', examples: ['req_52bb7f46-17bc-4f2d-9988-89d1398d2990'] },
460
+ },
461
+ Deprecation: {
462
+ description:
463
+ 'Present only on a route being withdrawn: an sf-Date of when the ' +
464
+ 'deprecation took effect (RFC 9745). The route still answers normally.',
465
+ schema: { type: 'string', examples: ['@1774483200'] },
466
+ },
467
+ Sunset: {
468
+ description:
469
+ 'Present only on a route being withdrawn: the HTTP-date it stops ' +
470
+ 'answering (RFC 8594). Never less than the published notice window after ' +
471
+ `\`${API_DEPRECATION_HEADER}\`.`,
472
+ schema: { type: 'string', examples: ['Tue, 08 Sep 2026 00:00:00 GMT'] },
473
+ },
474
+ };
475
+
476
+ const headerRef = (name: string): Json => ({ $ref: `#/components/headers/${name}` });
477
+
478
+ /** Carried by every response, whatever its status. */
479
+ const UNIVERSAL_RESPONSE_HEADERS: Readonly<Record<string, Json>> = {
480
+ [API_VERSION_HEADER]: headerRef('AbloVersion'),
481
+ 'X-Request-Id': headerRef('RequestId'),
482
+ [RATE_LIMIT_POLICY_HEADER]: headerRef('RateLimitPolicy'),
483
+ [RATE_LIMIT_HEADER]: headerRef('RateLimit'),
484
+ [API_DEPRECATION_HEADER]: headerRef('Deprecation'),
485
+ [API_SUNSET_HEADER]: headerRef('Sunset'),
486
+ };
487
+
488
+ /** Statuses where a wait is what resolves the failure, so `Retry-After` is sent. */
489
+ const RETRY_AFTER_STATUSES = new Set(['429', '503']);
490
+
491
+ /**
492
+ * Stamp the documented headers onto every response of every operation.
493
+ *
494
+ * Runs after the responses are built — including the canonical error ones — so
495
+ * a response added later cannot quietly ship without them.
496
+ */
497
+ function attachResponseHeaders(paths: Json): void {
498
+ for (const rawPathItem of Object.values(paths)) {
499
+ const pathItem = rawPathItem as Json;
500
+ for (const [method, rawOperation] of Object.entries(pathItem)) {
501
+ if (!HTTP_METHODS.has(method)) continue;
502
+ const operation = rawOperation as Json;
503
+ const responses = (operation.responses ?? {}) as Json;
504
+ for (const [status, rawResponse] of Object.entries(responses)) {
505
+ const response = rawResponse as Json;
506
+ response.headers = {
507
+ ...UNIVERSAL_RESPONSE_HEADERS,
508
+ ...(RETRY_AFTER_STATUSES.has(status)
509
+ ? { [RETRY_AFTER_HEADER]: headerRef('RetryAfter') }
510
+ : {}),
511
+ ...((response.headers as Json | undefined) ?? {}),
512
+ };
513
+ }
514
+ }
515
+ }
516
+ }
517
+
403
518
  /** The envelope shared by both specs — same server, same auth, same version. */
404
519
  function envelope(options: SchemaToOpenApiOptions, description: string, paths: Json, schemas: Record<string, Json>): Json {
405
520
  return {
@@ -407,18 +522,28 @@ function envelope(options: SchemaToOpenApiOptions, description: string, paths: J
407
522
  info: {
408
523
  title: options.title ?? 'Ablo API',
409
524
  version: options.version ?? 'development',
410
- description,
525
+ // The lifecycle policy travels WITH the routes it governs. An agent
526
+ // deciding whether to integrate needs to know the surface will not move
527
+ // under it, and a policy published somewhere else is one it has to go
528
+ // find — so the document that describes the calls describes the promise.
529
+ description: `${description}\n\n${API_LIFECYCLE}`,
411
530
  license: {
412
531
  name: 'Apache License 2.0',
413
532
  identifier: 'Apache-2.0',
414
533
  },
534
+ contact: {
535
+ name: 'Ablo Support',
536
+ url: 'https://github.com/Abloatai/ablo/issues',
537
+ email: 'support@abloatai.com',
538
+ },
415
539
  },
416
540
  servers: [{ url: options.serverUrl ?? `${ABLO_HOSTED_HTTP_BASE_URL}/api` }],
417
541
  security: [{ bearerAuth: [] }],
418
542
  components: {
419
543
  securitySchemes: {
420
- bearerAuth: { type: 'http', scheme: 'bearer', description: 'Your Ablo API key (sk_ / rk_).' },
544
+ bearerAuth: { type: 'http', scheme: 'bearer', description: 'Your Ablo API key (sk_\u2026 / rk_\u2026).' },
421
545
  },
546
+ headers: { ...RESPONSE_HEADER_COMPONENTS },
422
547
  schemas,
423
548
  },
424
549
  paths,
@@ -436,6 +561,41 @@ const ERROR_RESPONSES: Readonly<Record<string, string>> = {
436
561
  '503': 'A required service is temporarily unavailable.',
437
562
  };
438
563
 
564
+ /**
565
+ * One real instance of the error shape every operation shares.
566
+ *
567
+ * This lives beside the canonical error responses rather than on the schema:
568
+ * OpenAPI consumers select examples from an operation's media type, and an
569
+ * example buried on a component does not tell them which response carries it.
570
+ * Stamping the same representative validation failure on every operation also
571
+ * means a newly added route cannot regress the published example coverage.
572
+ */
573
+ const ERROR_RESPONSE_EXAMPLE: Readonly<Json> = {
574
+ type: 'AbloValidationError',
575
+ code: 'invalid_request',
576
+ param: 'body',
577
+ message: 'The request did not satisfy the published contract.',
578
+ doc_url: docUrlForCode('invalid_request'),
579
+ request_id: 'req_52bb7f46-17bc-4f2d-9988-89d1398d2990',
580
+ };
581
+
582
+ function canonicalErrorResp(description: string): Json {
583
+ return {
584
+ description,
585
+ content: {
586
+ 'application/json': {
587
+ schema: schemaRef('ErrorEnvelope'),
588
+ examples: {
589
+ validation: {
590
+ summary: 'Typed validation failure',
591
+ value: ERROR_RESPONSE_EXAMPLE,
592
+ },
593
+ },
594
+ },
595
+ },
596
+ };
597
+ }
598
+
439
599
  /**
440
600
  * Every route passes failures through the same server error funnel. Publish
441
601
  * that fact on every operation so generated transports decode all HTTP errors
@@ -450,11 +610,10 @@ function attachCanonicalErrors(paths: Json): void {
450
610
  const operation = rawOperation as Json;
451
611
  const responses = { ...(operation.responses as Json | undefined) };
452
612
  for (const [status, description] of Object.entries(ERROR_RESPONSES)) {
453
- responses[status] = namedResp(description, 'ErrorEnvelope');
613
+ responses[status] = canonicalErrorResp(description);
454
614
  }
455
- responses.default = namedResp(
615
+ responses.default = canonicalErrorResp(
456
616
  'An HTTP error not otherwise listed; decoded through the canonical envelope.',
457
- 'ErrorEnvelope',
458
617
  );
459
618
  operation.responses = responses;
460
619
  }
@@ -950,6 +1109,7 @@ export function abloOpenApi(options: SchemaToOpenApiOptions = {}): Json {
950
1109
 
951
1110
  applyOperationIds(paths, ABLO_OPERATION_IDS);
952
1111
  attachCanonicalErrors(paths);
1112
+ attachResponseHeaders(paths);
953
1113
 
954
1114
  return envelope(
955
1115
  options,
@@ -1078,6 +1238,7 @@ export function schemaToOpenApi<S extends SchemaRecord>(
1078
1238
  operationIds['GET /v1/commits/{id}'] = 'getCommit';
1079
1239
  applyOperationIds(paths, operationIds);
1080
1240
  attachCanonicalErrors(paths);
1241
+ attachResponseHeaders(paths);
1081
1242
 
1082
1243
  Object.assign(schemas, abloComponentSchemas());
1083
1244
 
@@ -219,6 +219,8 @@ export const groupsInputSchema = z.object({
219
219
  root: scopeSchema.optional(),
220
220
  grants: grantsRefSchema.optional(),
221
221
  roles: z.union([entityRoleSchema, z.array(entityRoleSchema)]).optional(),
222
+ /** Acknowledge that these groups are delivery routing, not row access. */
223
+ routingOnly: z.literal(true).optional(),
222
224
  });
223
225
  export type GroupsInput = z.infer<typeof groupsInputSchema>;
224
226
 
@@ -314,6 +316,57 @@ export function composeEntitySyncGroups(
314
316
  return Array.from(out);
315
317
  }
316
318
 
319
+ /** The row fields needed to derive its durable delivery groups. */
320
+ export interface RecordSyncGroupSpec {
321
+ readonly subject?: { readonly kind: string; readonly field: string };
322
+ readonly selfKind?: string;
323
+ readonly parents: readonly { readonly kind: string; readonly field: string }[];
324
+ }
325
+
326
+ /** A subject-scoped row cannot be routed safely without its declared subject. */
327
+ export class InvalidRecordSubjectError extends Error {
328
+ readonly field: string;
329
+
330
+ constructor(field: string) {
331
+ super(`Record lacks non-empty subject field "${field}".`);
332
+ this.name = 'InvalidRecordSubjectError';
333
+ this.field = field;
334
+ }
335
+ }
336
+
337
+ /**
338
+ * Derive the exact durable delivery groups for a row.
339
+ *
340
+ * Delivery matching is OR-based, so a declared subject is an exclusive
341
+ * authorization route: self, parent, entity-role, writer, and transitive groups
342
+ * must not become alternate ways to receive the row. Additional groups are
343
+ * accepted here so every producer applies that rule in this one place.
344
+ */
345
+ export function syncGroupsForRow(
346
+ spec: RecordSyncGroupSpec | undefined,
347
+ record: Readonly<Record<string, unknown>>,
348
+ additionalGroups: readonly string[] = [],
349
+ ): string[] {
350
+ if (spec?.subject) {
351
+ const value = record[spec.subject.field];
352
+ if (typeof value !== 'string' || value.length === 0) {
353
+ throw new InvalidRecordSubjectError(spec.subject.field);
354
+ }
355
+ return [syncGroup(spec.subject.kind, value)];
356
+ }
357
+
358
+ const groups = new Set<string>(additionalGroups);
359
+ if (!spec) return [...groups];
360
+ if (spec.selfKind && typeof record.id === 'string' && record.id.length > 0) {
361
+ groups.add(syncGroup(spec.selfKind, record.id));
362
+ }
363
+ for (const parent of spec.parents) {
364
+ const value = record[parent.field];
365
+ if (value) groups.add(syncGroup(parent.kind, String(value)));
366
+ }
367
+ return [...groups];
368
+ }
369
+
317
370
  /**
318
371
  * Narrow a client's requested sync-group set to the groups it is actually
319
372
  * allowed to subscribe to. This helper is fully generic — it never inspects the
@@ -13,11 +13,11 @@
13
13
  * status: z.enum(['todo', 'doing', 'done']).default('todo'),
14
14
  * workspaceId: z.string().optional(),
15
15
  * }, {
16
- * workspace: relation.belongsTo('workspaces', 'workspaceId'),
16
+ * relations: { workspace: relation.belongsTo('workspaces', 'workspaceId') },
17
17
  * }),
18
18
  * });
19
19
  *
20
- * type Item = InferModel<typeof schema, 'items'>;
20
+ * type Item = Model<typeof schema, 'items'>;
21
21
  */
22
22
 
23
23
  import { z } from 'zod';
@@ -27,6 +27,7 @@ import { AbloValidationError } from '../errors.js';
27
27
  import type { IdentityRole } from './roles.js';
28
28
  import { fieldRef, type FieldRef } from './fieldRef.js';
29
29
  import { scopeSchema, grantsRefSchema } from './roles.js';
30
+ import { subjectRuleSchema } from './subject.js';
30
31
 
31
32
  // Sync-group roles (identity and entity) are defined in `./roles.js` and
32
33
  // re-exported here so they can also be imported from this module. See
@@ -49,6 +50,9 @@ export {
49
50
  extractEntityIds,
50
51
  composeIdentitySyncGroups,
51
52
  composeEntitySyncGroups,
53
+ syncGroupsForRow,
54
+ InvalidRecordSubjectError,
55
+ type RecordSyncGroupSpec,
52
56
  intersectRequestedWithAllowed,
53
57
  syncGroup,
54
58
  identityAnchor,
@@ -150,6 +154,7 @@ export const RESERVED_SESSION_SETTINGS: readonly string[] = [
150
154
  'app.current_participant_id',
151
155
  'app.current_participant_kind',
152
156
  'app.current_user_id',
157
+ 'app.current_subject_groups',
153
158
  ];
154
159
 
155
160
  export interface DefineSchemaOptions {
@@ -226,6 +231,13 @@ export const baseFieldsSchema = z.object({
226
231
  /**
227
232
  * The universal model field names. Audit and application metadata is declared
228
233
  * by the application or carried by the commit record, never injected here.
234
+ *
235
+ * This is the runtime spelling of {@link baseFieldsSchema}, and the one every
236
+ * consumer outside this package derives from: the CLI's adopt rule, the MCP
237
+ * schema linter, and the docs that tell an author which names not to declare.
238
+ * It is exported from `@abloatai/transaction/schema` for exactly that reason —
239
+ * when this list last moved (0.52.0, five names down to one) three hand-written
240
+ * copies stayed behind and went on rejecting correct schemas for five releases.
229
241
  */
230
242
  export const BASE_FIELDS = [
231
243
  'id',
@@ -234,6 +246,18 @@ export const BASE_FIELDS = [
234
246
  /** The base fields type — pure data columns. */
235
247
  export type BaseModelFields = z.infer<typeof baseFieldsSchema>;
236
248
 
249
+ // Invariant equality (no runtime, no casts): true only when both are mutually
250
+ // assignable. `ExpectTrue`'s constraint is what turns a mismatch into an error
251
+ // at THIS declaration, so the tuple and the schema cannot move apart — in
252
+ // either direction, a name in one and not the other fails to compile.
253
+ type BaseFieldsEqual<A, B> =
254
+ (<T>() => T extends A ? 1 : 2) extends <T>() => T extends B ? 1 : 2 ? true : false;
255
+ type ExpectTrue<T extends true> = T;
256
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
257
+ type _BaseFieldsExact = ExpectTrue<
258
+ BaseFieldsEqual<(typeof BASE_FIELDS)[number], keyof BaseModelFields & string>
259
+ >;
260
+
237
261
  /**
238
262
  * Methods every model instance carries. These are intersected into
239
263
  * {@link InferModel}, the read-side type, but not into the create or update
@@ -327,7 +351,8 @@ export interface Schema<S extends SchemaRecord = SchemaRecord> {
327
351
 
328
352
  /**
329
353
  * Infer the full model type from a schema.
330
- * Includes base fields (id, createdAt, updatedAt, etc.)
354
+ * Includes the base fields, which today means `id` alone: audit timestamps are
355
+ * ordinary declared fields and appear here only when the model declares them.
331
356
  *
332
357
  * ```ts
333
358
  * type Item = InferModel<typeof schema, 'items'>;
@@ -523,14 +548,34 @@ export type InsertValue<S extends Schema, ModelName extends keyof S['models']> =
523
548
  export type UpsertValue<S extends Schema, ModelName extends keyof S['models']> =
524
549
  InsertValue<S, ModelName>;
525
550
 
551
+ /**
552
+ * A patch over a row's fields: send a field to change it, omit it to leave it,
553
+ * send `null` to CLEAR it.
554
+ *
555
+ * The third of those is why this is a mapped type rather than `Partial`.
556
+ * Omitting a field and clearing a field are different intentions that
557
+ * `Partial` spells the same way, because `undefined` is what an absent key
558
+ * already means: it is dropped from the payload, so a caller who wrote
559
+ * `{ assigneeId: undefined }` to unassign kept the old assignee, and the
560
+ * unassign, the un-project and the cleared due date all did nothing without
561
+ * erroring. `null` is the value that clears, so `null` is what the type has to
562
+ * accept — otherwise the only way to write a working clear is to cast the
563
+ * payload, and a cast is what people reached for.
564
+ *
565
+ * Only a field the schema lets be absent is clearable. A required field cannot
566
+ * be nulled, which is the same rule the column has.
567
+ */
568
+ export type Clearable<T> = {
569
+ [K in keyof T]?: undefined extends T[K] ? T[K] | null : T[K];
570
+ };
571
+
526
572
  /**
527
573
  * The value type for updating an existing row. `id` is required (identifies
528
- * the row to update); all other fields are optional (only provided fields
529
- * are changed).
574
+ * the row to update); every other field is a {@link Clearable} patch.
530
575
  */
531
576
  export type UpdateValue<S extends Schema, ModelName extends keyof S['models']> =
532
577
  S['models'][ModelName] extends ModelDef<infer Shape>
533
- ? { id: string } & Partial<z.input<z.ZodObject<Shape>>>
578
+ ? { id: string } & Clearable<z.input<z.ZodObject<Shape>>>
534
579
  : never;
535
580
 
536
581
  /**
@@ -708,6 +753,7 @@ export function defineSchema<const S extends SchemaRecord>(
708
753
  }
709
754
 
710
755
  validateSyncGroupSchema(resolvedModels);
756
+ validateSubjectSchema(resolvedModels);
711
757
  validateSessionSettings(options?.sessionSettings ?? {});
712
758
 
713
759
  return {
@@ -721,6 +767,45 @@ export function defineSchema<const S extends SchemaRecord>(
721
767
  };
722
768
  }
723
769
 
770
+ function validateSubjectSchema(models: Record<string, ModelDef>): void {
771
+ for (const [name, def] of Object.entries(models)) {
772
+ if (!def.subject) continue;
773
+ const parsed = subjectRuleSchema.safeParse(def.subject);
774
+ if (!parsed.success) {
775
+ throw new AbloValidationError(
776
+ `Model "${name}": subject must be { field, group } with valid identifiers.`,
777
+ { code: 'schema_definition_invalid', param: `${name}.subject` },
778
+ );
779
+ }
780
+ if (!(def.subject.field in def.fields)) {
781
+ throw new AbloValidationError(
782
+ `Model "${name}": subject.field "${def.subject.field}" is not a declared field on this model.`,
783
+ { code: 'schema_definition_invalid', param: `${name}.subject.field` },
784
+ );
785
+ }
786
+ const field = def.shape[def.subject.field];
787
+ const meta = def.fields[def.subject.field];
788
+ if (!field || !meta) {
789
+ throw new AbloValidationError(
790
+ `Model "${name}": subject.field "${def.subject.field}" is not a declared field on this model.`,
791
+ { code: 'schema_definition_invalid', param: `${name}.subject.field` },
792
+ );
793
+ }
794
+ const subjectField = field as z.ZodType;
795
+ const acceptsInvalidValue =
796
+ subjectField.safeParse('').success ||
797
+ subjectField.safeParse(null).success ||
798
+ subjectField.safeParse(undefined).success ||
799
+ subjectField.safeParse(1).success;
800
+ if (!['string', 'enum'].includes(meta.type) || meta.isOptional || acceptsInvalidValue) {
801
+ throw new AbloValidationError(
802
+ `Model "${name}": subject.field "${def.subject.field}" must be a required, non-empty string field.`,
803
+ { code: 'schema_definition_invalid', param: `${name}.subject.field` },
804
+ );
805
+ }
806
+ }
807
+ }
808
+
724
809
  /**
725
810
  * Reject session-setting mappings that couldn't do what the author intends —
726
811
  * caught here at definition time rather than silently dropped on the write path.
@@ -13,7 +13,7 @@
13
13
  * What round-trips:
14
14
  * - all model routing and scoping metadata: typename, tableName, load,
15
15
  * mutable, the `tenancy` descriptor, bootstrap hints, scope, grants,
16
- * entityRoles, the `conflict` disposition map, persist, autoFill,
16
+ * entityRoles, the routing-only acknowledgement, the `conflict` disposition map, persist, autoFill,
17
17
  * requiredFields, and lazyObservable. The authoring shorthands (`policy`
18
18
  * and `groups`) are normalized into these canonical fields when the model
19
19
  * is built, so only the canonical fields cross here.
@@ -33,6 +33,7 @@ import type { FieldMeta } from './field.js';
33
33
  import { buildFieldRefs } from './schema.js';
34
34
  import type { Tenancy } from './tenancy.js';
35
35
  import type { ModelResidency } from './residency.js';
36
+ import type { SubjectRule } from './subject.js';
36
37
  import type {
37
38
  ModelDef,
38
39
  RelationRecord,
@@ -40,7 +41,6 @@ import type {
40
41
  LoadStrategy,
41
42
  PersistOptions,
42
43
  AutoFillRule,
43
- ConflictAxis,
44
44
  } from './model.js';
45
45
  import {
46
46
  relation,
@@ -80,6 +80,7 @@ export interface ModelJSON {
80
80
  readonly typename: string;
81
81
  readonly tableName?: string;
82
82
  readonly tenancy: Tenancy;
83
+ readonly subject?: SubjectRule;
83
84
  /** The database plane the model's rows live in. Optional for backward
84
85
  * compatibility: when absent (an artifact written before this field existed)
85
86
  * it reads as `tenant`, the default. See {@link ModelResidency}. */
@@ -87,9 +88,7 @@ export interface ModelJSON {
87
88
  readonly scope?: boolean | string;
88
89
  readonly grants?: GrantsRef;
89
90
  readonly entityRoles?: readonly EntityRole[];
90
- /** The declared write-conflict disposition per committer kind. When absent,
91
- * the engine falls back to its default. */
92
- readonly conflict?: ConflictAxis;
91
+ readonly routingOnly?: true;
93
92
  readonly bootstrapLimit?: number;
94
93
  readonly bootstrapOrderBy?: string;
95
94
  readonly mutable?: boolean;
@@ -136,11 +135,12 @@ function modelToJSON(def: ModelDef): ModelJSON {
136
135
  typename: def.typename ?? '',
137
136
  tableName: def.tableName,
138
137
  tenancy: def.tenancy,
138
+ subject: def.subject,
139
139
  plane: def.plane,
140
140
  scope: def.scope,
141
141
  grants: def.grants,
142
142
  entityRoles: def.entityRoles,
143
- conflict: def.conflict,
143
+ routingOnly: def.routingOnly,
144
144
  bootstrapLimit: def.bootstrapLimit,
145
145
  bootstrapOrderBy: def.bootstrapOrderBy,
146
146
  mutable: def.mutable,
@@ -272,15 +272,14 @@ function modelFromJSON(json: ModelJSON): ModelDef {
272
272
  persist: json.persist,
273
273
  tableName: json.tableName,
274
274
  tenancy: json.tenancy,
275
+ subject: json.subject,
275
276
  // Absent in older artifacts → default `tenant`, matching the model builder
276
277
  // and provisioning defaults so the round-trip stays stable.
277
278
  plane: json.plane ?? 'tenant',
278
279
  scope: json.scope,
279
280
  grants: json.grants,
280
281
  entityRoles: json.entityRoles,
281
- // Absent in older artifacts → undefined, so the commit path falls through to
282
- // the function registry or the engine default.
283
- conflict: json.conflict,
282
+ routingOnly: json.routingOnly,
284
283
  mutable: json.mutable,
285
284
  lazyObservable: json.lazyObservable,
286
285
  // computed getters are closures and intentionally not serialized; a