@abloatai/transaction 0.37.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 (723) hide show
  1. package/CONVENTIONS.md +83 -0
  2. package/README.md +48 -0
  3. package/dist/ablo.d.ts +90 -0
  4. package/dist/ablo.d.ts.map +1 -0
  5. package/dist/ablo.js +34 -0
  6. package/dist/ablo.js.map +1 -0
  7. package/dist/ai-sdk/coordinatedTool.d.ts +123 -0
  8. package/dist/ai-sdk/coordinatedTool.d.ts.map +1 -0
  9. package/dist/ai-sdk/coordinatedTool.js +135 -0
  10. package/dist/ai-sdk/coordinatedTool.js.map +1 -0
  11. package/dist/ai-sdk/index.d.ts +2 -0
  12. package/dist/ai-sdk/index.d.ts.map +1 -0
  13. package/dist/ai-sdk/index.js +2 -0
  14. package/dist/ai-sdk/index.js.map +1 -0
  15. package/dist/auth/apiKey.d.ts +154 -0
  16. package/dist/auth/apiKey.d.ts.map +1 -0
  17. package/dist/auth/apiKey.js +408 -0
  18. package/dist/auth/apiKey.js.map +1 -0
  19. package/dist/auth/bootstrapScope.d.ts +16 -0
  20. package/dist/auth/bootstrapScope.d.ts.map +1 -0
  21. package/dist/auth/bootstrapScope.js +2 -0
  22. package/dist/auth/bootstrapScope.js.map +1 -0
  23. package/dist/auth/browserCredentialSafety.d.ts +7 -0
  24. package/dist/auth/browserCredentialSafety.d.ts.map +1 -0
  25. package/dist/auth/browserCredentialSafety.js +29 -0
  26. package/dist/auth/browserCredentialSafety.js.map +1 -0
  27. package/dist/auth/capability.d.ts +241 -0
  28. package/dist/auth/capability.d.ts.map +1 -0
  29. package/dist/auth/capability.js +253 -0
  30. package/dist/auth/capability.js.map +1 -0
  31. package/dist/auth/capabilityLifecycle.d.ts +47 -0
  32. package/dist/auth/capabilityLifecycle.d.ts.map +1 -0
  33. package/dist/auth/capabilityLifecycle.js +108 -0
  34. package/dist/auth/capabilityLifecycle.js.map +1 -0
  35. package/dist/auth/credentialEndpoint.d.ts +10 -0
  36. package/dist/auth/credentialEndpoint.d.ts.map +1 -0
  37. package/dist/auth/credentialEndpoint.js +58 -0
  38. package/dist/auth/credentialEndpoint.js.map +1 -0
  39. package/dist/auth/credentialEndpointProtocol.d.ts +24 -0
  40. package/dist/auth/credentialEndpointProtocol.d.ts.map +1 -0
  41. package/dist/auth/credentialEndpointProtocol.js +34 -0
  42. package/dist/auth/credentialEndpointProtocol.js.map +1 -0
  43. package/dist/auth/credentialKind.d.ts +4 -0
  44. package/dist/auth/credentialKind.d.ts.map +1 -0
  45. package/dist/auth/credentialKind.js +15 -0
  46. package/dist/auth/credentialKind.js.map +1 -0
  47. package/dist/auth/credentialPolicy.d.ts +141 -0
  48. package/dist/auth/credentialPolicy.d.ts.map +1 -0
  49. package/dist/auth/credentialPolicy.js +113 -0
  50. package/dist/auth/credentialPolicy.js.map +1 -0
  51. package/dist/auth/credentialResult.d.ts +7 -0
  52. package/dist/auth/credentialResult.d.ts.map +1 -0
  53. package/dist/auth/credentialResult.js +9 -0
  54. package/dist/auth/credentialResult.js.map +1 -0
  55. package/dist/auth/credentialSource.d.ts +31 -0
  56. package/dist/auth/credentialSource.d.ts.map +1 -0
  57. package/dist/auth/credentialSource.js +56 -0
  58. package/dist/auth/credentialSource.js.map +1 -0
  59. package/dist/auth/hostedEndpoints.d.ts +22 -0
  60. package/dist/auth/hostedEndpoints.d.ts.map +1 -0
  61. package/dist/auth/hostedEndpoints.js +22 -0
  62. package/dist/auth/hostedEndpoints.js.map +1 -0
  63. package/dist/auth/identity.d.ts +62 -0
  64. package/dist/auth/identity.d.ts.map +1 -0
  65. package/dist/auth/identity.js +224 -0
  66. package/dist/auth/identity.js.map +1 -0
  67. package/dist/auth/index.d.ts +189 -0
  68. package/dist/auth/index.d.ts.map +1 -0
  69. package/dist/auth/index.js +312 -0
  70. package/dist/auth/index.js.map +1 -0
  71. package/dist/auth/schemas.d.ts +41 -0
  72. package/dist/auth/schemas.d.ts.map +1 -0
  73. package/dist/auth/schemas.js +69 -0
  74. package/dist/auth/schemas.js.map +1 -0
  75. package/dist/auth/sessionMint.d.ts +29 -0
  76. package/dist/auth/sessionMint.d.ts.map +1 -0
  77. package/dist/auth/sessionMint.js +92 -0
  78. package/dist/auth/sessionMint.js.map +1 -0
  79. package/dist/auth/token.d.ts +4 -0
  80. package/dist/auth/token.d.ts.map +1 -0
  81. package/dist/auth/token.js +4 -0
  82. package/dist/auth/token.js.map +1 -0
  83. package/dist/batching/index.d.ts +56 -0
  84. package/dist/batching/index.d.ts.map +1 -0
  85. package/dist/batching/index.js +148 -0
  86. package/dist/batching/index.js.map +1 -0
  87. package/dist/coordination/awaitClaimGrant.d.ts +57 -0
  88. package/dist/coordination/awaitClaimGrant.d.ts.map +1 -0
  89. package/dist/coordination/awaitClaimGrant.js +138 -0
  90. package/dist/coordination/awaitClaimGrant.js.map +1 -0
  91. package/dist/coordination/claimHeartbeatLoop.d.ts +85 -0
  92. package/dist/coordination/claimHeartbeatLoop.d.ts.map +1 -0
  93. package/dist/coordination/claimHeartbeatLoop.js +109 -0
  94. package/dist/coordination/claimHeartbeatLoop.js.map +1 -0
  95. package/dist/coordination/claimMeta.d.ts +50 -0
  96. package/dist/coordination/claimMeta.d.ts.map +1 -0
  97. package/dist/coordination/claimMeta.js +53 -0
  98. package/dist/coordination/claimMeta.js.map +1 -0
  99. package/dist/coordination/events.d.ts +75 -0
  100. package/dist/coordination/events.d.ts.map +1 -0
  101. package/dist/coordination/events.js +8 -0
  102. package/dist/coordination/events.js.map +1 -0
  103. package/dist/coordination/index.d.ts +20 -0
  104. package/dist/coordination/index.d.ts.map +1 -0
  105. package/dist/coordination/index.js +46 -0
  106. package/dist/coordination/index.js.map +1 -0
  107. package/dist/coordination/locator.d.ts +106 -0
  108. package/dist/coordination/locator.d.ts.map +1 -0
  109. package/dist/coordination/locator.js +110 -0
  110. package/dist/coordination/locator.js.map +1 -0
  111. package/dist/coordination/schema.d.ts +1332 -0
  112. package/dist/coordination/schema.d.ts.map +1 -0
  113. package/dist/coordination/schema.js +1137 -0
  114. package/dist/coordination/schema.js.map +1 -0
  115. package/dist/coordination/targetConflict.d.ts +3 -0
  116. package/dist/coordination/targetConflict.d.ts.map +1 -0
  117. package/dist/coordination/targetConflict.js +74 -0
  118. package/dist/coordination/targetConflict.js.map +1 -0
  119. package/dist/coordination/trace.d.ts +79 -0
  120. package/dist/coordination/trace.d.ts.map +1 -0
  121. package/dist/coordination/trace.js +139 -0
  122. package/dist/coordination/trace.js.map +1 -0
  123. package/dist/docs/catalog.d.ts +73 -0
  124. package/dist/docs/catalog.d.ts.map +1 -0
  125. package/dist/docs/catalog.js +231 -0
  126. package/dist/docs/catalog.js.map +1 -0
  127. package/dist/docs/index.d.ts +11 -0
  128. package/dist/docs/index.d.ts.map +1 -0
  129. package/dist/docs/index.js +11 -0
  130. package/dist/docs/index.js.map +1 -0
  131. package/dist/durableWrites.d.ts +63 -0
  132. package/dist/durableWrites.d.ts.map +1 -0
  133. package/dist/durableWrites.js +72 -0
  134. package/dist/durableWrites.js.map +1 -0
  135. package/dist/environment.d.ts +106 -0
  136. package/dist/environment.d.ts.map +1 -0
  137. package/dist/environment.js +109 -0
  138. package/dist/environment.js.map +1 -0
  139. package/dist/errorCodes.d.ts +411 -0
  140. package/dist/errorCodes.d.ts.map +1 -0
  141. package/dist/errorCodes.js +500 -0
  142. package/dist/errorCodes.js.map +1 -0
  143. package/dist/errors.d.ts +429 -0
  144. package/dist/errors.d.ts.map +1 -0
  145. package/dist/errors.js +687 -0
  146. package/dist/errors.js.map +1 -0
  147. package/dist/footprint.d.ts +112 -0
  148. package/dist/footprint.d.ts.map +1 -0
  149. package/dist/footprint.js +0 -0
  150. package/dist/footprint.js.map +1 -0
  151. package/dist/headlessClient.d.ts +10 -0
  152. package/dist/headlessClient.d.ts.map +1 -0
  153. package/dist/headlessClient.js +114 -0
  154. package/dist/headlessClient.js.map +1 -0
  155. package/dist/index.d.ts +21 -0
  156. package/dist/index.d.ts.map +1 -0
  157. package/dist/index.js +21 -0
  158. package/dist/index.js.map +1 -0
  159. package/dist/keys/index.d.ts +88 -0
  160. package/dist/keys/index.d.ts.map +1 -0
  161. package/dist/keys/index.js +208 -0
  162. package/dist/keys/index.js.map +1 -0
  163. package/dist/log/syncDeltaRow.d.ts +159 -0
  164. package/dist/log/syncDeltaRow.d.ts.map +1 -0
  165. package/dist/log/syncDeltaRow.js +96 -0
  166. package/dist/log/syncDeltaRow.js.map +1 -0
  167. package/dist/logger.d.ts +17 -0
  168. package/dist/logger.d.ts.map +1 -0
  169. package/dist/logger.js +8 -0
  170. package/dist/logger.js.map +1 -0
  171. package/dist/observability.d.ts +54 -0
  172. package/dist/observability.d.ts.map +1 -0
  173. package/dist/observability.js +20 -0
  174. package/dist/observability.js.map +1 -0
  175. package/dist/policy/types.d.ts +218 -0
  176. package/dist/policy/types.d.ts.map +1 -0
  177. package/dist/policy/types.js +127 -0
  178. package/dist/policy/types.js.map +1 -0
  179. package/dist/resources/functionalUpdate.d.ts +80 -0
  180. package/dist/resources/functionalUpdate.d.ts.map +1 -0
  181. package/dist/resources/functionalUpdate.js +88 -0
  182. package/dist/resources/functionalUpdate.js.map +1 -0
  183. package/dist/resources/httpResources.d.ts +449 -0
  184. package/dist/resources/httpResources.d.ts.map +1 -0
  185. package/dist/resources/httpResources.js +8 -0
  186. package/dist/resources/httpResources.js.map +1 -0
  187. package/dist/resources/modelOperations.d.ts +380 -0
  188. package/dist/resources/modelOperations.d.ts.map +1 -0
  189. package/dist/resources/modelOperations.js +13 -0
  190. package/dist/resources/modelOperations.js.map +1 -0
  191. package/dist/resources/mutationOptions.d.ts +67 -0
  192. package/dist/resources/mutationOptions.d.ts.map +1 -0
  193. package/dist/resources/mutationOptions.js +10 -0
  194. package/dist/resources/mutationOptions.js.map +1 -0
  195. package/dist/resources/where.d.ts +102 -0
  196. package/dist/resources/where.d.ts.map +1 -0
  197. package/dist/resources/where.js +116 -0
  198. package/dist/resources/where.js.map +1 -0
  199. package/dist/resources/writeOptionsSchema.d.ts +48 -0
  200. package/dist/resources/writeOptionsSchema.d.ts.map +1 -0
  201. package/dist/resources/writeOptionsSchema.js +74 -0
  202. package/dist/resources/writeOptionsSchema.js.map +1 -0
  203. package/dist/schema/coordination.d.ts +113 -0
  204. package/dist/schema/coordination.d.ts.map +1 -0
  205. package/dist/schema/coordination.js +134 -0
  206. package/dist/schema/coordination.js.map +1 -0
  207. package/dist/schema/ddl.d.ts +98 -0
  208. package/dist/schema/ddl.d.ts.map +1 -0
  209. package/dist/schema/ddl.js +492 -0
  210. package/dist/schema/ddl.js.map +1 -0
  211. package/dist/schema/ddlLock.d.ts +36 -0
  212. package/dist/schema/ddlLock.d.ts.map +1 -0
  213. package/dist/schema/ddlLock.js +47 -0
  214. package/dist/schema/ddlLock.js.map +1 -0
  215. package/dist/schema/diff.d.ts +226 -0
  216. package/dist/schema/diff.d.ts.map +1 -0
  217. package/dist/schema/diff.js +290 -0
  218. package/dist/schema/diff.js.map +1 -0
  219. package/dist/schema/field.d.ts +121 -0
  220. package/dist/schema/field.d.ts.map +1 -0
  221. package/dist/schema/field.js +266 -0
  222. package/dist/schema/field.js.map +1 -0
  223. package/dist/schema/fieldRef.d.ts +58 -0
  224. package/dist/schema/fieldRef.d.ts.map +1 -0
  225. package/dist/schema/fieldRef.js +26 -0
  226. package/dist/schema/fieldRef.js.map +1 -0
  227. package/dist/schema/generate.d.ts +20 -0
  228. package/dist/schema/generate.d.ts.map +1 -0
  229. package/dist/schema/generate.js +87 -0
  230. package/dist/schema/generate.js.map +1 -0
  231. package/dist/schema/index.d.ts +43 -0
  232. package/dist/schema/index.d.ts.map +1 -0
  233. package/dist/schema/index.js +81 -0
  234. package/dist/schema/index.js.map +1 -0
  235. package/dist/schema/loadStrategy.d.ts +46 -0
  236. package/dist/schema/loadStrategy.d.ts.map +1 -0
  237. package/dist/schema/loadStrategy.js +47 -0
  238. package/dist/schema/loadStrategy.js.map +1 -0
  239. package/dist/schema/model.d.ts +380 -0
  240. package/dist/schema/model.d.ts.map +1 -0
  241. package/dist/schema/model.js +124 -0
  242. package/dist/schema/model.js.map +1 -0
  243. package/dist/schema/openapi.d.ts +59 -0
  244. package/dist/schema/openapi.d.ts.map +1 -0
  245. package/dist/schema/openapi.js +508 -0
  246. package/dist/schema/openapi.js.map +1 -0
  247. package/dist/schema/queries.d.ts +202 -0
  248. package/dist/schema/queries.d.ts.map +1 -0
  249. package/dist/schema/queries.js +144 -0
  250. package/dist/schema/queries.js.map +1 -0
  251. package/dist/schema/relation.d.ts +205 -0
  252. package/dist/schema/relation.d.ts.map +1 -0
  253. package/dist/schema/relation.js +105 -0
  254. package/dist/schema/relation.js.map +1 -0
  255. package/dist/schema/residency.d.ts +30 -0
  256. package/dist/schema/residency.d.ts.map +1 -0
  257. package/dist/schema/residency.js +26 -0
  258. package/dist/schema/residency.js.map +1 -0
  259. package/dist/schema/roles.d.ts +250 -0
  260. package/dist/schema/roles.d.ts.map +1 -0
  261. package/dist/schema/roles.js +231 -0
  262. package/dist/schema/roles.js.map +1 -0
  263. package/dist/schema/schema.d.ts +352 -0
  264. package/dist/schema/schema.d.ts.map +1 -0
  265. package/dist/schema/schema.js +326 -0
  266. package/dist/schema/schema.js.map +1 -0
  267. package/dist/schema/select.d.ts +41 -0
  268. package/dist/schema/select.d.ts.map +1 -0
  269. package/dist/schema/select.js +91 -0
  270. package/dist/schema/select.js.map +1 -0
  271. package/dist/schema/serialize.d.ts +116 -0
  272. package/dist/schema/serialize.d.ts.map +1 -0
  273. package/dist/schema/serialize.js +278 -0
  274. package/dist/schema/serialize.js.map +1 -0
  275. package/dist/schema/sugar.d.ts +110 -0
  276. package/dist/schema/sugar.d.ts.map +1 -0
  277. package/dist/schema/sugar.js +84 -0
  278. package/dist/schema/sugar.js.map +1 -0
  279. package/dist/schema/tenancy.d.ts +140 -0
  280. package/dist/schema/tenancy.d.ts.map +1 -0
  281. package/dist/schema/tenancy.js +191 -0
  282. package/dist/schema/tenancy.js.map +1 -0
  283. package/dist/server/adapter.d.ts +174 -0
  284. package/dist/server/adapter.d.ts.map +1 -0
  285. package/dist/server/adapter.js +19 -0
  286. package/dist/server/adapter.js.map +1 -0
  287. package/dist/server/commit.d.ts +108 -0
  288. package/dist/server/commit.d.ts.map +1 -0
  289. package/dist/server/commit.js +2 -0
  290. package/dist/server/commit.js.map +1 -0
  291. package/dist/server/index.d.ts +15 -0
  292. package/dist/server/index.d.ts.map +1 -0
  293. package/dist/server/index.js +3 -0
  294. package/dist/server/index.js.map +1 -0
  295. package/dist/server/readConfig.d.ts +81 -0
  296. package/dist/server/readConfig.d.ts.map +1 -0
  297. package/dist/server/readConfig.js +9 -0
  298. package/dist/server/readConfig.js.map +1 -0
  299. package/dist/server/storageMode.d.ts +24 -0
  300. package/dist/server/storageMode.d.ts.map +1 -0
  301. package/dist/server/storageMode.js +18 -0
  302. package/dist/server/storageMode.js.map +1 -0
  303. package/dist/source/adapter.d.ts +84 -0
  304. package/dist/source/adapter.d.ts.map +1 -0
  305. package/dist/source/adapter.js +25 -0
  306. package/dist/source/adapter.js.map +1 -0
  307. package/dist/source/adapters/drizzle.d.ts +49 -0
  308. package/dist/source/adapters/drizzle.d.ts.map +1 -0
  309. package/dist/source/adapters/drizzle.js +220 -0
  310. package/dist/source/adapters/drizzle.js.map +1 -0
  311. package/dist/source/adapters/kysely.d.ts +43 -0
  312. package/dist/source/adapters/kysely.d.ts.map +1 -0
  313. package/dist/source/adapters/kysely.js +206 -0
  314. package/dist/source/adapters/kysely.js.map +1 -0
  315. package/dist/source/adapters/kyselyMutationCore.d.ts +77 -0
  316. package/dist/source/adapters/kyselyMutationCore.d.ts.map +1 -0
  317. package/dist/source/adapters/kyselyMutationCore.js +126 -0
  318. package/dist/source/adapters/kyselyMutationCore.js.map +1 -0
  319. package/dist/source/adapters/memory.d.ts +14 -0
  320. package/dist/source/adapters/memory.d.ts.map +1 -0
  321. package/dist/source/adapters/memory.js +131 -0
  322. package/dist/source/adapters/memory.js.map +1 -0
  323. package/dist/source/adapters/prisma.d.ts +64 -0
  324. package/dist/source/adapters/prisma.d.ts.map +1 -0
  325. package/dist/source/adapters/prisma.js +203 -0
  326. package/dist/source/adapters/prisma.js.map +1 -0
  327. package/dist/source/conformance.d.ts +38 -0
  328. package/dist/source/conformance.d.ts.map +1 -0
  329. package/dist/source/conformance.js +216 -0
  330. package/dist/source/conformance.js.map +1 -0
  331. package/dist/source/connector.d.ts +96 -0
  332. package/dist/source/connector.d.ts.map +1 -0
  333. package/dist/source/connector.js +267 -0
  334. package/dist/source/connector.js.map +1 -0
  335. package/dist/source/connectorProtocol.d.ts +155 -0
  336. package/dist/source/connectorProtocol.d.ts.map +1 -0
  337. package/dist/source/connectorProtocol.js +164 -0
  338. package/dist/source/connectorProtocol.js.map +1 -0
  339. package/dist/source/contract.d.ts +196 -0
  340. package/dist/source/contract.d.ts.map +1 -0
  341. package/dist/source/contract.js +165 -0
  342. package/dist/source/contract.js.map +1 -0
  343. package/dist/source/drizzle.d.ts +2 -0
  344. package/dist/source/drizzle.d.ts.map +1 -0
  345. package/dist/source/drizzle.js +2 -0
  346. package/dist/source/drizzle.js.map +1 -0
  347. package/dist/source/factory.d.ts +93 -0
  348. package/dist/source/factory.d.ts.map +1 -0
  349. package/dist/source/factory.js +287 -0
  350. package/dist/source/factory.js.map +1 -0
  351. package/dist/source/idempotency.d.ts +62 -0
  352. package/dist/source/idempotency.d.ts.map +1 -0
  353. package/dist/source/idempotency.js +145 -0
  354. package/dist/source/idempotency.js.map +1 -0
  355. package/dist/source/index.d.ts +24 -0
  356. package/dist/source/index.d.ts.map +1 -0
  357. package/dist/source/index.js +29 -0
  358. package/dist/source/index.js.map +1 -0
  359. package/dist/source/kysely.d.ts +3 -0
  360. package/dist/source/kysely.d.ts.map +1 -0
  361. package/dist/source/kysely.js +3 -0
  362. package/dist/source/kysely.js.map +1 -0
  363. package/dist/source/migrations.d.ts +22 -0
  364. package/dist/source/migrations.d.ts.map +1 -0
  365. package/dist/source/migrations.js +104 -0
  366. package/dist/source/migrations.js.map +1 -0
  367. package/dist/source/next.d.ts +33 -0
  368. package/dist/source/next.d.ts.map +1 -0
  369. package/dist/source/next.js +26 -0
  370. package/dist/source/next.js.map +1 -0
  371. package/dist/source/pushQueue.d.ts +135 -0
  372. package/dist/source/pushQueue.d.ts.map +1 -0
  373. package/dist/source/pushQueue.js +257 -0
  374. package/dist/source/pushQueue.js.map +1 -0
  375. package/dist/source/signing.d.ts +93 -0
  376. package/dist/source/signing.d.ts.map +1 -0
  377. package/dist/source/signing.js +163 -0
  378. package/dist/source/signing.js.map +1 -0
  379. package/dist/source/types.d.ts +402 -0
  380. package/dist/source/types.d.ts.map +1 -0
  381. package/dist/source/types.js +60 -0
  382. package/dist/source/types.js.map +1 -0
  383. package/dist/syncLog/contract.d.ts +21 -0
  384. package/dist/syncLog/contract.d.ts.map +1 -0
  385. package/dist/syncLog/contract.js +20 -0
  386. package/dist/syncLog/contract.js.map +1 -0
  387. package/dist/syncLog/index.d.ts +2 -0
  388. package/dist/syncLog/index.d.ts.map +1 -0
  389. package/dist/syncLog/index.js +2 -0
  390. package/dist/syncLog/index.js.map +1 -0
  391. package/dist/testing/fixtures/httpResponses.d.ts +74 -0
  392. package/dist/testing/fixtures/httpResponses.d.ts.map +1 -0
  393. package/dist/testing/fixtures/httpResponses.js +102 -0
  394. package/dist/testing/fixtures/httpResponses.js.map +1 -0
  395. package/dist/transactionLayer.d.ts +110 -0
  396. package/dist/transactionLayer.d.ts.map +1 -0
  397. package/dist/transactionLayer.js +25 -0
  398. package/dist/transactionLayer.js.map +1 -0
  399. package/dist/transactions/settlement/commitEnvelope.d.ts +144 -0
  400. package/dist/transactions/settlement/commitEnvelope.d.ts.map +1 -0
  401. package/dist/transactions/settlement/commitEnvelope.js +162 -0
  402. package/dist/transactions/settlement/commitEnvelope.js.map +1 -0
  403. package/dist/transactions/settlement/httpCommitEnvelope.d.ts +54 -0
  404. package/dist/transactions/settlement/httpCommitEnvelope.d.ts.map +1 -0
  405. package/dist/transactions/settlement/httpCommitEnvelope.js +208 -0
  406. package/dist/transactions/settlement/httpCommitEnvelope.js.map +1 -0
  407. package/dist/transactions/settlement/idempotencyKey.d.ts +11 -0
  408. package/dist/transactions/settlement/idempotencyKey.d.ts.map +1 -0
  409. package/dist/transactions/settlement/idempotencyKey.js +10 -0
  410. package/dist/transactions/settlement/idempotencyKey.js.map +1 -0
  411. package/dist/transactions/settlement/pendingWrite.d.ts +113 -0
  412. package/dist/transactions/settlement/pendingWrite.d.ts.map +1 -0
  413. package/dist/transactions/settlement/pendingWrite.js +21 -0
  414. package/dist/transactions/settlement/pendingWrite.js.map +1 -0
  415. package/dist/transport/commitFrames.d.ts +91 -0
  416. package/dist/transport/commitFrames.d.ts.map +1 -0
  417. package/dist/transport/commitFrames.js +135 -0
  418. package/dist/transport/commitFrames.js.map +1 -0
  419. package/dist/transport/connectionManager.d.ts +216 -0
  420. package/dist/transport/connectionManager.d.ts.map +1 -0
  421. package/dist/transport/connectionManager.js +674 -0
  422. package/dist/transport/connectionManager.js.map +1 -0
  423. package/dist/transport/credentialLifecycle.d.ts +178 -0
  424. package/dist/transport/credentialLifecycle.d.ts.map +1 -0
  425. package/dist/transport/credentialLifecycle.js +324 -0
  426. package/dist/transport/credentialLifecycle.js.map +1 -0
  427. package/dist/transport/heartbeat.d.ts +66 -0
  428. package/dist/transport/heartbeat.d.ts.map +1 -0
  429. package/dist/transport/heartbeat.js +94 -0
  430. package/dist/transport/heartbeat.js.map +1 -0
  431. package/dist/transport/httpClient.d.ts +143 -0
  432. package/dist/transport/httpClient.d.ts.map +1 -0
  433. package/dist/transport/httpClient.js +150 -0
  434. package/dist/transport/httpClient.js.map +1 -0
  435. package/dist/transport/httpFeed.d.ts +4 -0
  436. package/dist/transport/httpFeed.d.ts.map +1 -0
  437. package/dist/transport/httpFeed.js +94 -0
  438. package/dist/transport/httpFeed.js.map +1 -0
  439. package/dist/transport/httpOptions.d.ts +34 -0
  440. package/dist/transport/httpOptions.d.ts.map +1 -0
  441. package/dist/transport/httpOptions.js +13 -0
  442. package/dist/transport/httpOptions.js.map +1 -0
  443. package/dist/transport/httpTransport.d.ts +68 -0
  444. package/dist/transport/httpTransport.d.ts.map +1 -0
  445. package/dist/transport/httpTransport.js +1433 -0
  446. package/dist/transport/httpTransport.js.map +1 -0
  447. package/dist/transport/networkProbe.d.ts +85 -0
  448. package/dist/transport/networkProbe.d.ts.map +1 -0
  449. package/dist/transport/networkProbe.js +208 -0
  450. package/dist/transport/networkProbe.js.map +1 -0
  451. package/dist/transport/wsFrameHandlers.d.ts +129 -0
  452. package/dist/transport/wsFrameHandlers.d.ts.map +1 -0
  453. package/dist/transport/wsFrameHandlers.js +429 -0
  454. package/dist/transport/wsFrameHandlers.js.map +1 -0
  455. package/dist/transport/wsTransport.d.ts +575 -0
  456. package/dist/transport/wsTransport.d.ts.map +1 -0
  457. package/dist/transport/wsTransport.js +1024 -0
  458. package/dist/transport/wsTransport.js.map +1 -0
  459. package/dist/types/assertExact.d.ts +18 -0
  460. package/dist/types/assertExact.d.ts.map +1 -0
  461. package/dist/types/assertExact.js +2 -0
  462. package/dist/types/assertExact.js.map +1 -0
  463. package/dist/types/global.d.ts +108 -0
  464. package/dist/types/global.d.ts.map +1 -0
  465. package/dist/types/global.js +41 -0
  466. package/dist/types/global.js.map +1 -0
  467. package/dist/types/index.d.ts +206 -0
  468. package/dist/types/index.d.ts.map +1 -0
  469. package/dist/types/index.js +57 -0
  470. package/dist/types/index.js.map +1 -0
  471. package/dist/types/modelData.d.ts +11 -0
  472. package/dist/types/modelData.d.ts.map +1 -0
  473. package/dist/types/modelData.js +10 -0
  474. package/dist/types/modelData.js.map +1 -0
  475. package/dist/types/participant.d.ts +21 -0
  476. package/dist/types/participant.d.ts.map +1 -0
  477. package/dist/types/participant.js +11 -0
  478. package/dist/types/participant.js.map +1 -0
  479. package/dist/types/streams.d.ts +545 -0
  480. package/dist/types/streams.d.ts.map +1 -0
  481. package/dist/types/streams.js +12 -0
  482. package/dist/types/streams.js.map +1 -0
  483. package/dist/utils/asyncIterator.d.ts +35 -0
  484. package/dist/utils/asyncIterator.d.ts.map +1 -0
  485. package/dist/utils/asyncIterator.js +136 -0
  486. package/dist/utils/asyncIterator.js.map +1 -0
  487. package/dist/utils/duration.d.ts +51 -0
  488. package/dist/utils/duration.d.ts.map +1 -0
  489. package/dist/utils/duration.js +78 -0
  490. package/dist/utils/duration.js.map +1 -0
  491. package/dist/utils/json.d.ts +58 -0
  492. package/dist/utils/json.d.ts.map +1 -0
  493. package/dist/utils/json.js +277 -0
  494. package/dist/utils/json.js.map +1 -0
  495. package/dist/webhooks/events.d.ts +44 -0
  496. package/dist/webhooks/events.d.ts.map +1 -0
  497. package/dist/webhooks/events.js +43 -0
  498. package/dist/webhooks/events.js.map +1 -0
  499. package/dist/webhooks/index.d.ts +9 -0
  500. package/dist/webhooks/index.d.ts.map +1 -0
  501. package/dist/webhooks/index.js +9 -0
  502. package/dist/webhooks/index.js.map +1 -0
  503. package/dist/wire/accountResponses.d.ts +463 -0
  504. package/dist/wire/accountResponses.d.ts.map +1 -0
  505. package/dist/wire/accountResponses.js +294 -0
  506. package/dist/wire/accountResponses.js.map +1 -0
  507. package/dist/wire/auth.d.ts +57 -0
  508. package/dist/wire/auth.d.ts.map +1 -0
  509. package/dist/wire/auth.js +71 -0
  510. package/dist/wire/auth.js.map +1 -0
  511. package/dist/wire/bootstrapReason.d.ts +10 -0
  512. package/dist/wire/bootstrapReason.d.ts.map +1 -0
  513. package/dist/wire/bootstrapReason.js +9 -0
  514. package/dist/wire/bootstrapReason.js.map +1 -0
  515. package/dist/wire/claimEvent.d.ts +70 -0
  516. package/dist/wire/claimEvent.d.ts.map +1 -0
  517. package/dist/wire/claimEvent.js +74 -0
  518. package/dist/wire/claimEvent.js.map +1 -0
  519. package/dist/wire/claims.d.ts +475 -0
  520. package/dist/wire/claims.d.ts.map +1 -0
  521. package/dist/wire/claims.js +326 -0
  522. package/dist/wire/claims.js.map +1 -0
  523. package/dist/wire/commit.d.ts +604 -0
  524. package/dist/wire/commit.d.ts.map +1 -0
  525. package/dist/wire/commit.js +322 -0
  526. package/dist/wire/commit.js.map +1 -0
  527. package/dist/wire/delta.d.ts +251 -0
  528. package/dist/wire/delta.d.ts.map +1 -0
  529. package/dist/wire/delta.js +148 -0
  530. package/dist/wire/delta.js.map +1 -0
  531. package/dist/wire/errorEnvelope.d.ts +73 -0
  532. package/dist/wire/errorEnvelope.d.ts.map +1 -0
  533. package/dist/wire/errorEnvelope.js +124 -0
  534. package/dist/wire/errorEnvelope.js.map +1 -0
  535. package/dist/wire/feedCursor.d.ts +61 -0
  536. package/dist/wire/feedCursor.d.ts.map +1 -0
  537. package/dist/wire/feedCursor.js +83 -0
  538. package/dist/wire/feedCursor.js.map +1 -0
  539. package/dist/wire/feedEvent.d.ts +264 -0
  540. package/dist/wire/feedEvent.d.ts.map +1 -0
  541. package/dist/wire/feedEvent.js +66 -0
  542. package/dist/wire/feedEvent.js.map +1 -0
  543. package/dist/wire/frames.d.ts +195 -0
  544. package/dist/wire/frames.d.ts.map +1 -0
  545. package/dist/wire/frames.js +51 -0
  546. package/dist/wire/frames.js.map +1 -0
  547. package/dist/wire/inboundFrames.d.ts +490 -0
  548. package/dist/wire/inboundFrames.d.ts.map +1 -0
  549. package/dist/wire/inboundFrames.js +117 -0
  550. package/dist/wire/inboundFrames.js.map +1 -0
  551. package/dist/wire/index.d.ts +55 -0
  552. package/dist/wire/index.d.ts.map +1 -0
  553. package/dist/wire/index.js +84 -0
  554. package/dist/wire/index.js.map +1 -0
  555. package/dist/wire/listEnvelope.d.ts +38 -0
  556. package/dist/wire/listEnvelope.d.ts.map +1 -0
  557. package/dist/wire/listEnvelope.js +43 -0
  558. package/dist/wire/listEnvelope.js.map +1 -0
  559. package/dist/wire/modelMutations.d.ts +32 -0
  560. package/dist/wire/modelMutations.d.ts.map +1 -0
  561. package/dist/wire/modelMutations.js +53 -0
  562. package/dist/wire/modelMutations.js.map +1 -0
  563. package/dist/wire/modelResponses.d.ts +79 -0
  564. package/dist/wire/modelResponses.d.ts.map +1 -0
  565. package/dist/wire/modelResponses.js +44 -0
  566. package/dist/wire/modelResponses.js.map +1 -0
  567. package/dist/wire/modelShape.d.ts +79 -0
  568. package/dist/wire/modelShape.d.ts.map +1 -0
  569. package/dist/wire/modelShape.js +75 -0
  570. package/dist/wire/modelShape.js.map +1 -0
  571. package/dist/wire/protocol.d.ts +39 -0
  572. package/dist/wire/protocol.d.ts.map +1 -0
  573. package/dist/wire/protocol.js +39 -0
  574. package/dist/wire/protocol.js.map +1 -0
  575. package/dist/wire/protocolVersion.d.ts +74 -0
  576. package/dist/wire/protocolVersion.d.ts.map +1 -0
  577. package/dist/wire/protocolVersion.js +84 -0
  578. package/dist/wire/protocolVersion.js.map +1 -0
  579. package/package.json +187 -0
  580. package/src/ablo.ts +139 -0
  581. package/src/ai-sdk/coordinatedTool.ts +214 -0
  582. package/src/ai-sdk/index.ts +7 -0
  583. package/src/auth/apiKey.ts +540 -0
  584. package/src/auth/bootstrapScope.ts +15 -0
  585. package/src/auth/browserCredentialSafety.ts +48 -0
  586. package/src/auth/capability.ts +326 -0
  587. package/src/auth/capabilityLifecycle.ts +174 -0
  588. package/src/auth/credentialEndpoint.ts +79 -0
  589. package/src/auth/credentialEndpointProtocol.ts +51 -0
  590. package/src/auth/credentialKind.ts +20 -0
  591. package/src/auth/credentialPolicy.ts +244 -0
  592. package/src/auth/credentialResult.ts +23 -0
  593. package/src/auth/credentialSource.ts +99 -0
  594. package/src/auth/hostedEndpoints.ts +24 -0
  595. package/src/auth/identity.ts +330 -0
  596. package/src/auth/index.ts +592 -0
  597. package/src/auth/schemas.ts +94 -0
  598. package/src/auth/sessionMint.ts +126 -0
  599. package/src/auth/token.ts +4 -0
  600. package/src/batching/index.ts +200 -0
  601. package/src/coordination/awaitClaimGrant.ts +243 -0
  602. package/src/coordination/claimHeartbeatLoop.ts +165 -0
  603. package/src/coordination/claimMeta.ts +56 -0
  604. package/src/coordination/events.ts +86 -0
  605. package/src/coordination/index.ts +181 -0
  606. package/src/coordination/locator.ts +200 -0
  607. package/src/coordination/schema.ts +1346 -0
  608. package/src/coordination/targetConflict.ts +85 -0
  609. package/src/coordination/trace.ts +173 -0
  610. package/src/docs/catalog.ts +274 -0
  611. package/src/docs/index.ts +18 -0
  612. package/src/durableWrites.ts +134 -0
  613. package/src/environment.ts +132 -0
  614. package/src/errorCodes.ts +1591 -0
  615. package/src/errors.ts +918 -0
  616. package/src/footprint.ts +0 -0
  617. package/src/headlessClient.ts +161 -0
  618. package/src/index.ts +52 -0
  619. package/src/keys/index.ts +254 -0
  620. package/src/log/syncDeltaRow.ts +119 -0
  621. package/src/logger.ts +22 -0
  622. package/src/observability.ts +85 -0
  623. package/src/policy/types.ts +292 -0
  624. package/src/resources/functionalUpdate.ts +151 -0
  625. package/src/resources/httpResources.ts +520 -0
  626. package/src/resources/modelOperations.ts +444 -0
  627. package/src/resources/mutationOptions.ts +66 -0
  628. package/src/resources/where.ts +160 -0
  629. package/src/resources/writeOptionsSchema.ts +91 -0
  630. package/src/schema/coordination.ts +161 -0
  631. package/src/schema/ddl.ts +593 -0
  632. package/src/schema/ddlLock.ts +53 -0
  633. package/src/schema/diff.ts +489 -0
  634. package/src/schema/field.ts +321 -0
  635. package/src/schema/fieldRef.ts +88 -0
  636. package/src/schema/generate.ts +95 -0
  637. package/src/schema/index.ts +278 -0
  638. package/src/schema/loadStrategy.ts +52 -0
  639. package/src/schema/model.ts +476 -0
  640. package/src/schema/openapi.ts +658 -0
  641. package/src/schema/queries.ts +273 -0
  642. package/src/schema/relation.ts +291 -0
  643. package/src/schema/residency.ts +30 -0
  644. package/src/schema/roles.ts +325 -0
  645. package/src/schema/schema.ts +825 -0
  646. package/src/schema/select.ts +115 -0
  647. package/src/schema/serialize.ts +373 -0
  648. package/src/schema/sugar.ts +194 -0
  649. package/src/schema/tenancy.ts +221 -0
  650. package/src/server/adapter.ts +203 -0
  651. package/src/server/commit.ts +109 -0
  652. package/src/server/index.ts +26 -0
  653. package/src/server/readConfig.ts +82 -0
  654. package/src/server/storageMode.ts +20 -0
  655. package/src/source/adapter.ts +85 -0
  656. package/src/source/adapters/drizzle.ts +291 -0
  657. package/src/source/adapters/kysely.ts +346 -0
  658. package/src/source/adapters/kyselyMutationCore.ts +220 -0
  659. package/src/source/adapters/memory.ts +154 -0
  660. package/src/source/adapters/prisma.ts +282 -0
  661. package/src/source/conformance.ts +287 -0
  662. package/src/source/connector.ts +394 -0
  663. package/src/source/connectorProtocol.ts +189 -0
  664. package/src/source/contract.ts +221 -0
  665. package/src/source/drizzle.ts +1 -0
  666. package/src/source/factory.ts +444 -0
  667. package/src/source/idempotency.ts +189 -0
  668. package/src/source/index.ts +182 -0
  669. package/src/source/kysely.ts +2 -0
  670. package/src/source/migrations.ts +109 -0
  671. package/src/source/next.ts +38 -0
  672. package/src/source/pushQueue.ts +368 -0
  673. package/src/source/signing.ts +279 -0
  674. package/src/source/types.ts +502 -0
  675. package/src/syncLog/contract.ts +32 -0
  676. package/src/syncLog/index.ts +1 -0
  677. package/src/testing/fixtures/httpResponses.ts +155 -0
  678. package/src/transactionLayer.ts +122 -0
  679. package/src/transactions/settlement/commitEnvelope.ts +192 -0
  680. package/src/transactions/settlement/httpCommitEnvelope.ts +250 -0
  681. package/src/transactions/settlement/idempotencyKey.ts +11 -0
  682. package/src/transactions/settlement/pendingWrite.ts +24 -0
  683. package/src/transport/commitFrames.ts +225 -0
  684. package/src/transport/connectionManager.ts +856 -0
  685. package/src/transport/credentialLifecycle.ts +389 -0
  686. package/src/transport/heartbeat.ts +118 -0
  687. package/src/transport/httpClient.ts +354 -0
  688. package/src/transport/httpFeed.ts +111 -0
  689. package/src/transport/httpOptions.ts +41 -0
  690. package/src/transport/httpTransport.ts +1976 -0
  691. package/src/transport/networkProbe.ts +249 -0
  692. package/src/transport/wsFrameHandlers.ts +619 -0
  693. package/src/transport/wsTransport.ts +1491 -0
  694. package/src/types/assertExact.ts +17 -0
  695. package/src/types/global.ts +123 -0
  696. package/src/types/index.ts +270 -0
  697. package/src/types/modelData.ts +11 -0
  698. package/src/types/participant.ts +22 -0
  699. package/src/types/streams.ts +702 -0
  700. package/src/utils/asyncIterator.ts +141 -0
  701. package/src/utils/duration.ts +88 -0
  702. package/src/utils/json.ts +281 -0
  703. package/src/webhooks/events.ts +96 -0
  704. package/src/webhooks/index.ts +12 -0
  705. package/src/wire/accountResponses.ts +328 -0
  706. package/src/wire/auth.ts +86 -0
  707. package/src/wire/bootstrapReason.ts +10 -0
  708. package/src/wire/claimEvent.ts +85 -0
  709. package/src/wire/claims.ts +370 -0
  710. package/src/wire/commit.ts +379 -0
  711. package/src/wire/delta.ts +173 -0
  712. package/src/wire/errorEnvelope.ts +133 -0
  713. package/src/wire/feedCursor.ts +91 -0
  714. package/src/wire/feedEvent.ts +74 -0
  715. package/src/wire/frames.ts +77 -0
  716. package/src/wire/inboundFrames.ts +182 -0
  717. package/src/wire/index.ts +328 -0
  718. package/src/wire/listEnvelope.ts +51 -0
  719. package/src/wire/modelMutations.ts +55 -0
  720. package/src/wire/modelResponses.ts +48 -0
  721. package/src/wire/modelShape.ts +83 -0
  722. package/src/wire/protocol.ts +39 -0
  723. package/src/wire/protocolVersion.ts +97 -0
@@ -0,0 +1,85 @@
1
+ /**
2
+ * The observability the settlement core reports on its own behalf.
3
+ *
4
+ * Coordination outcomes — a claim changing state, a stale-write collision that
5
+ * notified instead of aborting — happen with no UI and no local store anywhere,
6
+ * so the core must be able to report them without depending on the consumer's
7
+ * full provider (ADR 0016).
8
+ *
9
+ * This is deliberately the narrow set the core actually calls today. Widening it
10
+ * later is non-breaking; the reactive engine's `ObservabilityProvider` extends
11
+ * this interface, so a single implementation still satisfies both.
12
+ */
13
+
14
+ import type { ClaimEvent, ConflictEvent } from './coordination/events.js';
15
+
16
+ export interface CoordinationObservability {
17
+ /** Capture a claim state change (acquired / queued / granted / lost / rejected / expired). */
18
+ captureClaim(event: ClaimEvent): void;
19
+
20
+ /** Capture a notify-instead-of-abort stale-write collision. */
21
+ captureConflict(event: ConflictEvent): void;
22
+ }
23
+
24
+ // ─────────────────────────────────────────────
25
+ // Transport observability
26
+ // ─────────────────────────────────────────────
27
+
28
+ /** Breadcrumb severity levels */
29
+ export type BreadcrumbLevel = 'debug' | 'info' | 'warning' | 'error';
30
+
31
+ /** Breadcrumb categories for sync engine lifecycle events */
32
+ export type BreadcrumbCategory =
33
+ | 'sync.bootstrap'
34
+ | 'sync.transaction'
35
+ | 'sync.websocket'
36
+ | 'sync.offline'
37
+ | 'sync.database'
38
+ | 'sync.conflict'
39
+ | 'sync.coordination'
40
+ | 'sync.groups';
41
+
42
+ export interface WebSocketErrorDetails {
43
+ context: string;
44
+ error?: string;
45
+ code?: number;
46
+ reason?: string;
47
+ }
48
+
49
+ /**
50
+ * The observability the duplex transport reports on its own behalf: connection
51
+ * lifecycle breadcrumbs and socket errors. A server-side agent holding a socket
52
+ * for claim push has no store and no UI, so the transport must be able to
53
+ * report without the consumer's full provider — the same reasoning as
54
+ * {@link CoordinationObservability}, one layer down. The reactive engine's
55
+ * `ObservabilityProvider` extends this interface, so a single implementation
56
+ * satisfies both.
57
+ */
58
+ export interface TransportObservability {
59
+ /** Add a breadcrumb for sync lifecycle events */
60
+ breadcrumb(
61
+ message: string,
62
+ category: BreadcrumbCategory,
63
+ level?: BreadcrumbLevel,
64
+ data?: Record<string, string | number | boolean | undefined>
65
+ ): void;
66
+
67
+ /** Capture WebSocket error */
68
+ captureWebSocketError(details: WebSocketErrorDetails): void;
69
+ }
70
+
71
+ /**
72
+ * Everything the duplex transport reports: its own lifecycle
73
+ * ({@link TransportObservability}) plus the coordination outcomes that ride
74
+ * the socket ({@link CoordinationObservability} — claim pushes and notified
75
+ * collisions arrive as frames, so the transport is where they surface).
76
+ */
77
+ export type SocketObservability = TransportObservability & CoordinationObservability;
78
+
79
+ /** The no-op default — what the transport reports through when nothing is wired. */
80
+ export const noopSocketObservability: SocketObservability = {
81
+ breadcrumb() {},
82
+ captureWebSocketError() {},
83
+ captureClaim() {},
84
+ captureConflict() {},
85
+ };
@@ -0,0 +1,292 @@
1
+ /**
2
+ * The conflict types a policy decides on. The engine detects a conflict and
3
+ * hands it to your {@link ConflictPolicy}, which returns a
4
+ * {@link ConflictDecision}.
5
+ *
6
+ * There are two conflict shapes. A {@link StaleContextConflict} is a write
7
+ * whose `readAt` watermark is older than the latest delta on the target row. A
8
+ * {@link ClaimHeldConflict} is a participant trying to claim a target that
9
+ * someone else already holds. {@link Conflict} is the discriminated union of
10
+ * the two; switch on `kind` to narrow it.
11
+ */
12
+
13
+ import type { z } from 'zod';
14
+ import type { ParticipantRef } from '../types/participant.js';
15
+ import type { CommitOperationType, OnStaleMode } from '../coordination/schema.js';
16
+ import type { conflictAxisWireSchema } from '../wire/accountResponses.js';
17
+
18
+ export type ConflictKind = 'stale_context' | 'claim_held';
19
+
20
+ /** Fields shared by every conflict shape. */
21
+ interface ConflictBase {
22
+ readonly committer: ParticipantRef;
23
+ readonly organizationId: string;
24
+ /** Human at the root of the committer's delegation chain (if any). */
25
+ readonly delegationChainRootUserId?: string | null;
26
+ }
27
+
28
+ /** The operation whose write conflicts. */
29
+ export interface ConflictOperation {
30
+ readonly model: string;
31
+ readonly id: string;
32
+ readonly type: CommitOperationType;
33
+ readonly input?: Readonly<Record<string, unknown>>;
34
+ }
35
+
36
+ export interface StaleContextConflict extends ConflictBase {
37
+ readonly kind: 'stale_context';
38
+ readonly operation: ConflictOperation;
39
+ /** Watermark the committer reasoned against. */
40
+ readonly readAt: number;
41
+ /** Most recent delta id on the target. */
42
+ readonly observedSyncId: number;
43
+ /**
44
+ * The fields whose concurrent change triggered this conflict — the
45
+ * intersection of the fields the committer wrote and the columns a newer
46
+ * delta touched. An empty array means the conflicting delta was a
47
+ * whole-entity change, such as a create or delete, which conflicts with any
48
+ * write. A policy can use this to decide at field granularity — for example,
49
+ * allowing the write when the only overlap is on a cosmetic field.
50
+ */
51
+ readonly conflictingFields?: readonly string[];
52
+ /**
53
+ * The committer's declared `onStale` intent for this operation. The default
54
+ * policy honors it: `'notify'` holds the write and notifies, and anything
55
+ * else rejects. A custom policy may override this. When absent, it is treated
56
+ * as `'reject'`, the default for an unguarded write.
57
+ */
58
+ readonly requestedMode?: OnStaleMode;
59
+ }
60
+
61
+ export interface ClaimHeldConflict extends ConflictBase {
62
+ readonly kind: 'claim_held';
63
+ readonly heldBy: ParticipantRef;
64
+ readonly claimId: string;
65
+ readonly entityType: string;
66
+ readonly entityId: string;
67
+ /** Holder's claim expiry (ms since epoch). */
68
+ readonly expiresAt: number;
69
+ /**
70
+ * The capability operations granted to the committer — the allowlist carried
71
+ * by its key. A policy decides purely from the conflict it is given, so this
72
+ * is the only place it can read the committer's privileges. It lets a policy
73
+ * express a rule such as "preempt only if the committer holds `claim.preempt`"
74
+ * (see {@link capabilityPreemptPolicy}). Empty for a human session that
75
+ * carries no allowlist.
76
+ */
77
+ readonly committerOperations: readonly string[];
78
+ }
79
+
80
+ /**
81
+ * The discriminated union the policy receives. Switch on `.kind` to
82
+ * narrow to the variant.
83
+ */
84
+ export type Conflict = StaleContextConflict | ClaimHeldConflict;
85
+
86
+ /** What the policy returns. */
87
+ export type ConflictDecision =
88
+ | { readonly action: 'reject'; readonly reason?: string }
89
+ | { readonly action: 'allow'; readonly note?: string }
90
+ /**
91
+ * Evict the current holder and grant the target to the committer. This is
92
+ * only meaningful for a `claim_held` conflict raised at claim time: the
93
+ * holder receives a `claim_lost` notification with reason `'preempted'`, and
94
+ * the committer takes the lease ahead of anyone already waiting in line for
95
+ * it. Return it only for a committer you consider higher priority — for
96
+ * example, a supervisor over its own sub-agents, or an identity that holds a
97
+ * preempt capability. At commit time there is no holder to evict, so a
98
+ * `preempt` decision is treated as `allow`.
99
+ */
100
+ | { readonly action: 'preempt'; readonly reason?: string }
101
+ /**
102
+ * Hold the write instead of aborting it. This is only meaningful for a
103
+ * `stale_context` conflict. The engine withholds the conflicting operation
104
+ * and returns a `StaleNotification` carrying the current value, so the actor
105
+ * — an agent or a human — can reconcile and re-commit. The rest of the batch
106
+ * still commits. It maps from `onStale: 'notify'`.
107
+ *
108
+ * The monotonic `sync_id` landing order decides who yields: the stale
109
+ * committer always recomputes against the newer value, an asymmetry that
110
+ * prevents two notifying writers from looping against each other. Retries are
111
+ * bounded by the client's reconciliation retry cap.
112
+ */
113
+ | { readonly action: 'notify'; readonly reason?: string };
114
+
115
+ /**
116
+ * The function that decides a conflict. It receives a {@link Conflict} and
117
+ * returns a {@link ConflictDecision}, either synchronously or as a promise.
118
+ * Register your implementation with the engine; the example below allows a
119
+ * cosmetic "linter" writer and defers everything else to {@link defaultPolicy}.
120
+ *
121
+ * ```ts
122
+ * const policy: ConflictPolicy = (conflict) => {
123
+ * if (conflict.committer.id.startsWith('linter:')) {
124
+ * return { action: 'allow', note: 'cosmetic writer' };
125
+ * }
126
+ * return defaultPolicy(conflict);
127
+ * };
128
+ * ```
129
+ */
130
+ export type ConflictPolicy = (
131
+ conflict: Conflict,
132
+ ) => ConflictDecision | Promise<ConflictDecision>;
133
+
134
+ /**
135
+ * The conflict policy the engine uses when you do not supply your own. It
136
+ * favors people: a human is never blocked, while agents and automated writers
137
+ * yield to a claim someone else holds.
138
+ *
139
+ * For a `claim_held` conflict, the decision follows the committer's kind:
140
+ *
141
+ * • `user` → `allow` — a human is never blocked by a claim. A claim is a
142
+ * coordination hint among agents, not a lock on
143
+ * people.
144
+ * • `agent` → `reject` — an agent yields to a claim held by someone else.
145
+ * The one sanctioned exception is the privileged
146
+ * `claim.preempt` capability; see
147
+ * {@link capabilityPreemptPolicy}.
148
+ * • `system` → `reject` — automated and backend writers serialize through
149
+ * claims the same way agents do, so a server job
150
+ * cannot silently overwrite a held row. Declare the
151
+ * model's conflict axis to overwrite if you want that.
152
+ *
153
+ * Allowing only `user` by default is deliberate: a backend key is a
154
+ * full-access credential, and claim serialization depends on those writers
155
+ * respecting claims unless a model opts out.
156
+ *
157
+ * For a `stale_context` conflict, the decision honors the committer's declared
158
+ * `onStale` intent: `'notify'` holds the write and notifies the actor to
159
+ * resolve it, and anything else (including `'reject'` or an absent value)
160
+ * rejects. An `onStale` of `'overwrite'` never reaches a policy — it is a hard
161
+ * opt-out resolved before the conflict is detected.
162
+ *
163
+ * To change this behavior for a model, declare its conflict axis in the schema;
164
+ * a declared axis overrides this default.
165
+ */
166
+ // Typed by its real synchronous shape with `satisfies`, rather than the
167
+ // async-permissive `ConflictPolicy` alias, so synchronous callers such as
168
+ // `interpretConflictAxis` and `capabilityPreemptPolicy` receive a plain
169
+ // `ConflictDecision` rather than `ConflictDecision | Promise<…>`. It remains
170
+ // assignable to `ConflictPolicy` wherever it is used as one.
171
+ export const defaultPolicy = ((conflict: Conflict): ConflictDecision => {
172
+ if (conflict.kind === 'claim_held') {
173
+ // A human (`user`) is never blocked; agents and system actors yield.
174
+ // Keeping every non-`user` kind on `reject` here ensures an agent cannot
175
+ // bypass a claim even on this default resolution path, which — unlike the
176
+ // declared-axis path — has no separate agent guard of its own.
177
+ return conflict.committer.kind === 'user'
178
+ ? { action: 'allow', note: 'principal:not-blocked' }
179
+ : { action: 'reject', reason: 'claim_conflict' };
180
+ }
181
+ return conflict.requestedMode === 'notify'
182
+ ? { action: 'notify', reason: 'stale_notify_hold' }
183
+ : { action: 'reject', reason: 'stale_context' };
184
+ }) satisfies ConflictPolicy;
185
+
186
+ /**
187
+ * A ready-made policy that grants capability-gated preemption. When the
188
+ * committer's capability allowlist includes the `claim.preempt` operation, a
189
+ * `claim_held` conflict is preempted: the current holder is evicted and the
190
+ * committer takes the lease. Every other conflict falls back to
191
+ * {@link defaultPolicy}, which rejects. Register it as your conflict policy to
192
+ * let a privileged identity take over a held entity without writing a bespoke
193
+ * policy. The authorization rests on holding the capability, not on any
194
+ * particular identity string.
195
+ */
196
+ export const capabilityPreemptPolicy: ConflictPolicy = (conflict) => {
197
+ if (
198
+ conflict.kind === 'claim_held' &&
199
+ conflict.committerOperations.includes('claim.preempt')
200
+ ) {
201
+ return { action: 'preempt', reason: 'capability:claim.preempt' };
202
+ }
203
+ return defaultPolicy(conflict);
204
+ };
205
+
206
+ /**
207
+ * A model's declared conflict disposition, keyed by the kind of committer. You
208
+ * set it in the model's schema, for example
209
+ * `conflict: { user: 'overwrite', agent: 'reject' }`, and the engine applies it
210
+ * at commit time. It is plain data using the same `'reject' | 'overwrite' |
211
+ * 'notify'` vocabulary as the write guards, so it travels through the schema
212
+ * registry to the server without naming any application model.
213
+ *
214
+ * Each key is the committer's participant kind, which the server derives and a
215
+ * client cannot forge; an omitted kind falls back to the engine default. So
216
+ * `{ user: 'overwrite', agent: 'reject' }` reads as "a human's write wins, an
217
+ * agent's write yields," and `system`, being unlisted, takes the default.
218
+ */
219
+ export interface ConflictAxis {
220
+ /** What happens when a human (`user` session) commits into a conflict. */
221
+ readonly user?: OnStaleMode;
222
+ /** What happens when an AI `agent` commits into a conflict. */
223
+ readonly agent?: OnStaleMode;
224
+ /** What happens when a `system` / automation actor commits into a conflict. */
225
+ readonly system?: OnStaleMode;
226
+ }
227
+
228
+ /**
229
+ * The same three members reach the server as `conflictAxisWireSchema`, which is
230
+ * a runtime-validatable zod object rather than an interface — `wire/` is the
231
+ * protocol leaf and cannot import this file, so the two are stated separately
232
+ * and pinned to each other here, on the side of the edge that is allowed to
233
+ * cross. A member added to one and not the other stops compiling.
234
+ *
235
+ * The import is type-only and erases, so nothing in the policy layer pulls the
236
+ * wire module in at runtime.
237
+ */
238
+ type _ConflictAxisMatchesWire =
239
+ z.infer<typeof conflictAxisWireSchema> extends ConflictAxis ? true : never;
240
+ type _WireMatchesConflictAxis =
241
+ ConflictAxis extends z.infer<typeof conflictAxisWireSchema> ? true : never;
242
+ const _conflictAxisPinned: [_ConflictAxisMatchesWire, _WireMatchesConflictAxis] = [true, true];
243
+ void _conflictAxisPinned;
244
+
245
+ /**
246
+ * Resolves a declared {@link ConflictAxis} into a {@link ConflictDecision} for
247
+ * one concrete conflict. It is pure and synchronous, doing no I/O, so it can
248
+ * run on either the client or the server. It reads the committer's kind from
249
+ * the conflict and maps the declared mode:
250
+ *
251
+ * - undefined → the engine default, {@link defaultPolicy}: a human is
252
+ * allowed, an agent or system committer is rejected on a
253
+ * `claim_held`, and a stale write honors `onStale: 'notify'`.
254
+ * - `overwrite` → `allow`; the write wins and the committer is never blocked.
255
+ * - `reject` → `reject`; the committer yields.
256
+ * - `notify` → on a `stale_context` conflict, hold the write and notify so
257
+ * the committer re-reads and re-applies; on a `claim_held`
258
+ * conflict there is no held write to reconcile (see
259
+ * {@link ConflictDecision} `notify`), so it degrades to
260
+ * `reject` rather than silently writing to a claimed row.
261
+ *
262
+ * This is only the generic interpretation. Stronger server-side rules — such as
263
+ * an agent never bypassing a claim held by someone else — are enforced where
264
+ * the decision is applied, not here.
265
+ */
266
+ export function interpretConflictAxis(
267
+ axis: ConflictAxis,
268
+ conflict: Conflict,
269
+ ): ConflictDecision {
270
+ const mode = axis[conflict.committer.kind];
271
+ if (mode === undefined) return defaultPolicy(conflict);
272
+ switch (mode) {
273
+ case 'overwrite':
274
+ return { action: 'allow', note: 'conflict:overwrite' };
275
+ case 'reject':
276
+ return {
277
+ action: 'reject',
278
+ reason: conflict.kind === 'claim_held' ? 'claim_conflict' : 'stale_context',
279
+ };
280
+ case 'notify':
281
+ return conflict.kind === 'stale_context'
282
+ ? { action: 'notify', reason: 'stale_notify_hold' }
283
+ : { action: 'reject', reason: 'claim_conflict' };
284
+ default: {
285
+ // Exhaustiveness backstop: a future `OnStaleMode` member surfaces as a
286
+ // localized compile error here, not a missing-return at the signature.
287
+ const _exhaustive: never = mode;
288
+ return _exhaustive;
289
+ }
290
+ }
291
+ }
292
+
@@ -0,0 +1,151 @@
1
+ /**
2
+ * The functional update — `ablo.<model>.update(id, current => next)`.
3
+ *
4
+ * This is the surface that just works under contention. You express only your
5
+ * intent — given the latest row, here is the next state — and the client does
6
+ * the rest: it reads the fresh row and its watermark, runs your updater, writes
7
+ * the result as a compare-and-swap against that watermark, and on any concurrent
8
+ * write it re-reads, recomputes, and retries. No claim, no identity, no transport
9
+ * awareness, and no `stale_context` or `claim_*` error codes ever reach the
10
+ * caller. The write either lands or, at the extreme, throws a single
11
+ * {@link AbloContentionError} once the reconcile budget is spent.
12
+ *
13
+ * Correctness comes from the `readAt` watermark plus `onStale: 'reject'`
14
+ * (optimistic concurrency, or compare-and-swap), not from participant identity.
15
+ * That is why it is immune to the shared-credential silent-overwrite hazard and
16
+ * behaves identically on both transports: the HTTP and WebSocket clients inject
17
+ * the same two functions ({@link ReconcileTransport}) into the shared loop below,
18
+ * so the guarantee cannot drift between them — only the mechanism differs.
19
+ *
20
+ * The mental model is React's `setState(prev => next)`: pass a function of the
21
+ * current state and the runtime owns reconciliation.
22
+ */
23
+
24
+ import {
25
+ AbloError,
26
+ AbloNotFoundError,
27
+ AbloStaleContextError,
28
+ AbloClaimedError,
29
+ AbloContentionError,
30
+ } from '../errors.js';
31
+
32
+ /**
33
+ * The functional form of an update: given the freshly-read row, return the
34
+ * fields to write. Return `null` or `undefined` to make no write — a no-op the
35
+ * caller chose after seeing the latest state (for example, "already done").
36
+ */
37
+ export type ModelUpdater<T> = (
38
+ current: T,
39
+ ) => Partial<T> | null | undefined | Promise<Partial<T> | null | undefined>;
40
+
41
+ /** Tuning for the functional update's internal reconcile loop. */
42
+ export interface ContentionOptions {
43
+ /**
44
+ * Max reconcile rounds under contention before throwing
45
+ * {@link AbloContentionError}. Each round re-reads the latest row and re-runs
46
+ * your updater. Defaults to {@link DEFAULT_CONTENTION_RETRIES}.
47
+ */
48
+ readonly retries?: number;
49
+ /** Abort the reconcile loop (e.g. the request was cancelled). */
50
+ readonly signal?: AbortSignal;
51
+ }
52
+
53
+ /** Reconcile rounds before a hot row is declared permanently contended. */
54
+ export const DEFAULT_CONTENTION_RETRIES = 16;
55
+
56
+ /**
57
+ * Reports whether a thrown error means "another writer moved the row — re-read
58
+ * and retry" rather than a genuine failure to surface. These are the
59
+ * optimistic-concurrency signals the functional update reconciles against:
60
+ * - `stale_context` — the `readAt` watermark was overtaken by a concurrent write
61
+ * - `claim_lost` — a holder preempted the write (for example a human under `humansOverwrite`)
62
+ * - `claim_queued` — a holder is actively editing the row right now
63
+ */
64
+ export function isReconcilableConflict(err: unknown): boolean {
65
+ if (err instanceof AbloStaleContextError) return true;
66
+ if (err instanceof AbloClaimedError) {
67
+ return err.code === 'claim_lost' || err.code === 'claim_queued';
68
+ }
69
+ return false;
70
+ }
71
+
72
+ const sleep = (ms: number): Promise<void> =>
73
+ new Promise((resolve) => setTimeout(resolve, ms));
74
+
75
+ /**
76
+ * Jittered backoff so N reconcilers retrying at once don't lock-step straight
77
+ * back into the same collision. Bounded; grows mildly with the attempt.
78
+ */
79
+ function backoffMs(attempt: number): number {
80
+ return 60 + attempt * 40 + Math.floor(Math.random() * 60);
81
+ }
82
+
83
+ /**
84
+ * The transport-specific read and write that the shared loop drives. Each client
85
+ * injects its own pair — the one thing that differs between the HTTP and
86
+ * WebSocket transports.
87
+ */
88
+ export interface ReconcileTransport<T, R> {
89
+ readonly model: string;
90
+ readonly id: string;
91
+ /** Read the latest row and its watermark from the authoritative store. */
92
+ readFresh: () => Promise<{ readonly data: T | null | undefined; readonly stamp: number }>;
93
+ /**
94
+ * Write the computed patch as a compare-and-swap against `readAt`. It must
95
+ * throw a reconcilable conflict (`stale_context` or `claim_*`) when the
96
+ * watermark was overtaken — that rejection is what drives the next reconcile
97
+ * round.
98
+ */
99
+ writeNext: (patch: Partial<T>, readAt: number) => Promise<R>;
100
+ }
101
+
102
+ /**
103
+ * Run the read-fresh → compute → compare-and-swap → reconcile loop. Shared by
104
+ * both transports so the guarantee is provably identical. Returns the write's
105
+ * result, or `undefined` when the updater opted out of writing.
106
+ */
107
+ export async function reconcileFunctionalUpdate<T, R>(
108
+ updater: ModelUpdater<T>,
109
+ options: ContentionOptions | undefined,
110
+ transport: ReconcileTransport<T, R>,
111
+ ): Promise<R | undefined> {
112
+ const retries = options?.retries ?? DEFAULT_CONTENTION_RETRIES;
113
+ let lastConflict: unknown;
114
+
115
+ for (let attempt = 0; attempt <= retries; attempt++) {
116
+ if (options?.signal?.aborted) {
117
+ throw new AbloError(
118
+ `Update of ${transport.model}/${transport.id} was aborted before it landed.`,
119
+ { code: 'update_aborted' },
120
+ );
121
+ }
122
+
123
+ const { data, stamp } = await transport.readFresh();
124
+ if (data == null) {
125
+ throw new AbloNotFoundError(
126
+ `Cannot update ${transport.model}/${transport.id}: it does not exist (or is ` +
127
+ `outside this credential's scope).`,
128
+ [transport.id],
129
+ );
130
+ }
131
+
132
+ const patch = await updater(data);
133
+ if (patch == null) return undefined; // updater opted out after reading fresh
134
+
135
+ try {
136
+ return await transport.writeNext(patch, stamp);
137
+ } catch (err) {
138
+ if (!isReconcilableConflict(err)) throw err; // genuine failure — surface it
139
+ lastConflict = err;
140
+ if (attempt < retries) await sleep(backoffMs(attempt));
141
+ }
142
+ }
143
+
144
+ throw new AbloContentionError(transport.model, transport.id, retries + 1, {
145
+ cause: lastConflict,
146
+ });
147
+ }
148
+
149
+ // Re-exported so call sites import the loop and its terminal error from one
150
+ // place; the class itself lives with the rest of the error hierarchy.
151
+ export { AbloContentionError };