@abloatai/ablo 0.34.1 → 0.36.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 (536) hide show
  1. package/AGENTS.md +2 -1
  2. package/CHANGELOG.md +758 -5
  3. package/README.md +56 -502
  4. package/bin/ablo.cjs +39 -0
  5. package/dist/BaseSyncedStore.d.ts +176 -48
  6. package/dist/BaseSyncedStore.js +346 -214
  7. package/dist/Database.d.ts +17 -44
  8. package/dist/Database.js +96 -79
  9. package/dist/InstanceCache.d.ts +31 -6
  10. package/dist/InstanceCache.js +65 -30
  11. package/dist/LazyReferenceCollection.d.ts +3 -3
  12. package/dist/LazyReferenceCollection.js +4 -4
  13. package/dist/Model.d.ts +23 -13
  14. package/dist/Model.js +27 -17
  15. package/dist/ModelRegistry.d.ts +8 -4
  16. package/dist/ModelRegistry.js +20 -18
  17. package/dist/NetworkMonitor.d.ts +3 -1
  18. package/dist/NetworkMonitor.js +7 -5
  19. package/dist/{SyncEngineContext.d.ts → RuntimeContext.d.ts} +20 -13
  20. package/dist/{SyncEngineContext.js → RuntimeContext.js} +11 -12
  21. package/dist/SyncClient.d.ts +47 -47
  22. package/dist/SyncClient.js +215 -156
  23. package/dist/ai-sdk/coordinatedTool.d.ts +2 -2
  24. package/dist/ai-sdk/coordinatedTool.js +1 -1
  25. package/dist/ai-sdk/coordinationContext.d.ts +2 -2
  26. package/dist/ai-sdk/coordinationContext.js +1 -1
  27. package/dist/ai-sdk/wrap.d.ts +3 -3
  28. package/dist/ai-sdk/wrap.js +2 -2
  29. package/dist/auth/index.d.ts +1 -156
  30. package/dist/auth/index.js +8 -301
  31. package/dist/client/Ablo.d.ts +42 -287
  32. package/dist/client/Ablo.js +129 -963
  33. package/dist/client/abloClient.d.ts +309 -0
  34. package/dist/client/abloClient.js +13 -0
  35. package/dist/client/clientPrelude.d.ts +52 -0
  36. package/dist/client/clientPrelude.js +60 -0
  37. package/dist/client/consoleLogger.d.ts +2 -2
  38. package/dist/client/coreClient.d.ts +60 -0
  39. package/dist/client/coreClient.js +118 -0
  40. package/dist/client/createInternalComponents.d.ts +8 -4
  41. package/dist/client/createInternalComponents.js +17 -10
  42. package/dist/client/createModelProxy.d.ts +98 -373
  43. package/dist/client/createModelProxy.js +233 -139
  44. package/dist/client/humans.d.ts +69 -0
  45. package/dist/client/humans.js +78 -0
  46. package/dist/client/modelRegistration.d.ts +1 -1
  47. package/dist/client/modelRegistration.js +9 -9
  48. package/dist/client/options.d.ts +73 -17
  49. package/dist/client/reactiveEngine.d.ts +53 -0
  50. package/dist/client/reactiveEngine.js +688 -0
  51. package/dist/client/resourceTypes.d.ts +9 -250
  52. package/dist/client/resourceTypes.js +8 -5
  53. package/dist/client/schemaConfig.d.ts +4 -4
  54. package/dist/client/schemaConfig.js +6 -2
  55. package/dist/client/storeCluster.d.ts +47 -0
  56. package/dist/client/storeCluster.js +118 -0
  57. package/dist/client/storeLifecycle.d.ts +61 -0
  58. package/dist/client/storeLifecycle.js +231 -0
  59. package/dist/client/validateAbloOptions.d.ts +3 -2
  60. package/dist/client/validateAbloOptions.js +1 -1
  61. package/dist/client/wsMutationExecutor.d.ts +3 -3
  62. package/dist/client/wsMutationExecutor.js +3 -3
  63. package/dist/context.d.ts +22 -9
  64. package/dist/context.js +33 -9
  65. package/dist/coordination/ClaimLog.d.ts +26 -0
  66. package/dist/coordination/ClaimLog.js +32 -0
  67. package/dist/coordination/index.d.ts +1 -15
  68. package/dist/coordination/index.js +8 -31
  69. package/dist/core/index.d.ts +3 -3
  70. package/dist/core/index.js +2 -2
  71. package/dist/docs/catalog.d.ts +72 -0
  72. package/dist/docs/catalog.js +230 -0
  73. package/dist/docs/index.d.ts +10 -0
  74. package/dist/docs/index.js +10 -0
  75. package/dist/environment.d.ts +1 -40
  76. package/dist/environment.js +8 -37
  77. package/dist/index.d.ts +44 -36
  78. package/dist/index.js +30 -22
  79. package/dist/interfaces/index.d.ts +44 -134
  80. package/dist/keys/index.d.ts +1 -77
  81. package/dist/keys/index.js +8 -190
  82. package/dist/mutators/{RecordingTransaction.d.ts → RecordingMutation.d.ts} +4 -4
  83. package/dist/mutators/{RecordingTransaction.js → RecordingMutation.js} +2 -2
  84. package/dist/mutators/Transaction.d.ts +1 -1
  85. package/dist/mutators/Transaction.js +1 -1
  86. package/dist/mutators/UndoManager.d.ts +6 -6
  87. package/dist/mutators/UndoManager.js +5 -5
  88. package/dist/mutators/defineMutators.d.ts +3 -3
  89. package/dist/mutators/defineMutators.js +1 -1
  90. package/dist/mutators/inverseOp.js +2 -2
  91. package/dist/mutators/mutateActions.d.ts +3 -3
  92. package/dist/mutators/mutateActions.js +1 -1
  93. package/dist/mutators/readerActions.d.ts +1 -1
  94. package/dist/mutators/undoApply.d.ts +1 -1
  95. package/dist/mutators/undoApply.js +1 -1
  96. package/dist/policy/index.d.ts +2 -2
  97. package/dist/policy/index.js +1 -1
  98. package/dist/query/client.d.ts +5 -2
  99. package/dist/query/client.js +10 -9
  100. package/dist/query/types.d.ts +6 -41
  101. package/dist/query/types.js +2 -2
  102. package/dist/react/AbloProvider.d.ts +18 -8
  103. package/dist/react/AbloProvider.js +10 -9
  104. package/dist/react/context.d.ts +3 -3
  105. package/dist/react/context.js +1 -1
  106. package/dist/react/createAbloReact.d.ts +56 -0
  107. package/dist/react/createAbloReact.js +51 -0
  108. package/dist/react/index.d.ts +6 -5
  109. package/dist/react/index.js +6 -3
  110. package/dist/react/internalContext.d.ts +1 -1
  111. package/dist/react/useAblo.d.ts +12 -5
  112. package/dist/react/useAblo.js +26 -8
  113. package/dist/react/useCurrentUserId.js +1 -1
  114. package/dist/react/useErrorListener.js +1 -1
  115. package/dist/react/useMutationFailureListener.d.ts +2 -2
  116. package/dist/react/useMutationFailureListener.js +1 -1
  117. package/dist/react/useMutators.d.ts +3 -3
  118. package/dist/react/useMutators.js +3 -3
  119. package/dist/react/useUndoScope.d.ts +5 -5
  120. package/dist/react/useUndoScope.js +1 -1
  121. package/dist/schema/coordination.d.ts +69 -10
  122. package/dist/schema/coordination.js +90 -9
  123. package/dist/schema/ddl.js +2 -2
  124. package/dist/schema/diff.d.ts +1 -1
  125. package/dist/schema/generate.js +1 -1
  126. package/dist/schema/index.d.ts +11 -10
  127. package/dist/schema/index.js +22 -18
  128. package/dist/schema/queries.d.ts +27 -27
  129. package/dist/schema/queries.js +23 -23
  130. package/dist/schema/select.d.ts +3 -3
  131. package/dist/schema/select.js +6 -3
  132. package/dist/schema/serialize.d.ts +15 -6
  133. package/dist/schema/serialize.js +20 -3
  134. package/dist/schema/sugar.d.ts +6 -7
  135. package/dist/schema/sugar.js +9 -12
  136. package/dist/schema/syncDeltaRow.d.ts +4 -152
  137. package/dist/schema/syncDeltaRow.js +4 -105
  138. package/dist/server/adapter.d.ts +18 -1
  139. package/dist/server/commit.d.ts +10 -16
  140. package/dist/server/index.d.ts +1 -1
  141. package/dist/server/index.js +1 -1
  142. package/dist/server/readConfig.d.ts +1 -1
  143. package/dist/source/adapter.d.ts +7 -5
  144. package/dist/source/adapter.js +7 -5
  145. package/dist/source/adapters/drizzle.d.ts +1 -1
  146. package/dist/source/adapters/drizzle.js +2 -2
  147. package/dist/source/adapters/kysely.d.ts +1 -1
  148. package/dist/source/adapters/kysely.js +1 -1
  149. package/dist/source/adapters/kyselyMutationCore.d.ts +1 -1
  150. package/dist/source/adapters/kyselyMutationCore.js +2 -2
  151. package/dist/source/adapters/memory.js +1 -1
  152. package/dist/source/adapters/prisma.d.ts +8 -3
  153. package/dist/source/adapters/prisma.js +1 -1
  154. package/dist/source/connector.js +1 -1
  155. package/dist/source/connectorProtocol.d.ts +2 -8
  156. package/dist/source/connectorProtocol.js +3 -2
  157. package/dist/source/contract.d.ts +29 -17
  158. package/dist/source/contract.js +27 -22
  159. package/dist/source/factory.d.ts +1 -1
  160. package/dist/source/idempotency.js +2 -2
  161. package/dist/source/index.d.ts +1 -0
  162. package/dist/source/index.js +3 -0
  163. package/dist/source/next.d.ts +1 -1
  164. package/dist/source/signing.d.ts +9 -2
  165. package/dist/source/signing.js +4 -1
  166. package/dist/source/types.d.ts +6 -4
  167. package/dist/source/types.js +1 -1
  168. package/dist/{core/storeContract.d.ts → storeContract.d.ts} +6 -6
  169. package/dist/{core → stores}/DatabaseManager.d.ts +3 -1
  170. package/dist/{core → stores}/DatabaseManager.js +14 -13
  171. package/dist/stores/ObjectStore.d.ts +1 -1
  172. package/dist/{core → stores}/StoreManager.d.ts +9 -26
  173. package/dist/{core → stores}/StoreManager.js +29 -77
  174. package/dist/stores/SyncActionStore.d.ts +4 -2
  175. package/dist/stores/SyncActionStore.js +11 -17
  176. package/dist/stores/syncAction.d.ts +26 -0
  177. package/dist/stores/syncAction.js +16 -0
  178. package/dist/surface.d.ts +3 -3
  179. package/dist/surface.js +6 -4
  180. package/dist/sync/BootstrapFetcher.d.ts +127 -6
  181. package/dist/sync/BootstrapFetcher.js +511 -83
  182. package/dist/sync/ConnectionManager.d.ts +6 -198
  183. package/dist/sync/ConnectionManager.js +6 -677
  184. package/dist/sync/OnDemandLoader.d.ts +5 -2
  185. package/dist/sync/OnDemandLoader.js +61 -21
  186. package/dist/sync/SubscriptionManager.d.ts +13 -2
  187. package/dist/sync/SubscriptionManager.js +23 -5
  188. package/dist/sync/SyncWebSocket.d.ts +27 -510
  189. package/dist/sync/SyncWebSocket.js +76 -954
  190. package/dist/sync/awaitClaimGrant.d.ts +4 -44
  191. package/dist/sync/awaitClaimGrant.js +4 -109
  192. package/dist/sync/bootstrapApply.d.ts +3 -0
  193. package/dist/sync/bootstrapApply.js +2 -2
  194. package/dist/sync/commitFrames.d.ts +6 -40
  195. package/dist/sync/commitFrames.js +6 -97
  196. package/dist/sync/contextPorts.d.ts +18 -0
  197. package/dist/sync/contextPorts.js +31 -0
  198. package/dist/sync/createClaimStream.d.ts +5 -49
  199. package/dist/sync/createClaimStream.js +5 -469
  200. package/dist/sync/createPresenceStream.d.ts +26 -4
  201. package/dist/sync/createPresenceStream.js +28 -20
  202. package/dist/sync/createSnapshot.d.ts +2 -2
  203. package/dist/sync/createSnapshot.js +1 -1
  204. package/dist/sync/credentialLifecycle.d.ts +5 -173
  205. package/dist/sync/credentialLifecycle.js +5 -320
  206. package/dist/sync/deltaPipeline.d.ts +13 -12
  207. package/dist/sync/deltaPipeline.js +21 -4
  208. package/dist/sync/groupChange.d.ts +3 -0
  209. package/dist/sync/groupChange.js +16 -14
  210. package/dist/sync/participants.d.ts +24 -6
  211. package/dist/sync/participants.js +32 -23
  212. package/dist/sync/schemaDrift.d.ts +55 -0
  213. package/dist/sync/schemaDrift.js +53 -0
  214. package/dist/sync/schemas.d.ts +23 -33
  215. package/dist/sync/schemas.js +29 -20
  216. package/dist/sync/syncPlan.d.ts +3 -3
  217. package/dist/sync/wsFrameHandlers.d.ts +6 -114
  218. package/dist/sync/wsFrameHandlers.js +6 -392
  219. package/dist/syncLog/contract.d.ts +20 -0
  220. package/dist/syncLog/contract.js +19 -0
  221. package/dist/syncLog/index.d.ts +1 -0
  222. package/dist/syncLog/index.js +1 -0
  223. package/dist/transaction/ablo.d.ts +88 -0
  224. package/dist/transaction/ablo.js +33 -0
  225. package/dist/{client/auth.d.ts → transaction/auth/apiKey.d.ts} +43 -8
  226. package/dist/{client/auth.js → transaction/auth/apiKey.js} +19 -0
  227. package/dist/transaction/auth/bootstrapScope.d.ts +15 -0
  228. package/dist/transaction/auth/bootstrapScope.js +1 -0
  229. package/dist/transaction/auth/capability.d.ts +212 -0
  230. package/dist/transaction/auth/capability.js +224 -0
  231. package/dist/{auth → transaction/auth}/credentialSource.d.ts +8 -1
  232. package/dist/{client → transaction/auth}/identity.d.ts +8 -7
  233. package/dist/{client → transaction/auth}/identity.js +1 -1
  234. package/dist/transaction/auth/index.d.ts +162 -0
  235. package/dist/transaction/auth/index.js +304 -0
  236. package/dist/{auth → transaction/auth}/schemas.d.ts +1 -1
  237. package/dist/{auth → transaction/auth}/schemas.js +13 -13
  238. package/dist/{client → transaction/auth}/sessionMint.d.ts +8 -8
  239. package/dist/{client → transaction/auth}/sessionMint.js +4 -7
  240. package/dist/transaction/coordination/awaitClaimGrant.d.ts +56 -0
  241. package/dist/transaction/coordination/awaitClaimGrant.js +124 -0
  242. package/dist/{client → transaction/coordination}/claimHeartbeatLoop.d.ts +34 -0
  243. package/dist/{client → transaction/coordination}/claimHeartbeatLoop.js +20 -0
  244. package/dist/transaction/coordination/claimMeta.d.ts +49 -0
  245. package/dist/transaction/coordination/claimMeta.js +52 -0
  246. package/dist/transaction/coordination/createClaimStream.d.ts +64 -0
  247. package/dist/transaction/coordination/createClaimStream.js +475 -0
  248. package/dist/transaction/coordination/events.d.ts +74 -0
  249. package/dist/transaction/coordination/events.js +7 -0
  250. package/dist/transaction/coordination/index.d.ts +19 -0
  251. package/dist/transaction/coordination/index.js +45 -0
  252. package/dist/transaction/coordination/locator.d.ts +104 -0
  253. package/dist/transaction/coordination/locator.js +102 -0
  254. package/dist/transaction/coordination/schema.d.ts +1536 -0
  255. package/dist/transaction/coordination/schema.js +1177 -0
  256. package/dist/transaction/coordination/targetConflict.d.ts +2 -0
  257. package/dist/transaction/coordination/targetConflict.js +107 -0
  258. package/dist/{coordination → transaction/coordination}/trace.d.ts +7 -18
  259. package/dist/{coordination → transaction/coordination}/trace.js +18 -25
  260. package/dist/transaction/durableWrites.d.ts +62 -0
  261. package/dist/{client → transaction}/durableWrites.js +28 -3
  262. package/dist/transaction/environment.d.ts +105 -0
  263. package/dist/transaction/environment.js +108 -0
  264. package/dist/{errorCodes.d.ts → transaction/errorCodes.d.ts} +12 -12
  265. package/dist/{errorCodes.js → transaction/errorCodes.js} +45 -18
  266. package/dist/{errors.d.ts → transaction/errors.d.ts} +37 -13
  267. package/dist/{errors.js → transaction/errors.js} +85 -16
  268. package/dist/transaction/footprint.d.ts +111 -0
  269. package/dist/transaction/footprint.js +0 -0
  270. package/dist/transaction/index.d.ts +20 -0
  271. package/dist/transaction/index.js +20 -0
  272. package/dist/transaction/keys/index.d.ts +87 -0
  273. package/dist/transaction/keys/index.js +207 -0
  274. package/dist/transaction/log/syncDeltaRow.d.ts +158 -0
  275. package/dist/transaction/log/syncDeltaRow.js +95 -0
  276. package/dist/{sync/syncPosition.d.ts → transaction/logPosition.d.ts} +22 -8
  277. package/dist/{sync/syncPosition.js → transaction/logPosition.js} +15 -6
  278. package/dist/transaction/logger.d.ts +16 -0
  279. package/dist/transaction/logger.js +7 -0
  280. package/dist/transaction/observability.d.ts +53 -0
  281. package/dist/transaction/observability.js +19 -0
  282. package/dist/transaction/plugin.d.ts +285 -0
  283. package/dist/transaction/plugin.js +106 -0
  284. package/dist/{policy → transaction/policy}/types.d.ts +3 -3
  285. package/dist/{policy → transaction/policy}/types.js +2 -0
  286. package/dist/transaction/resources/httpResources.d.ts +321 -0
  287. package/dist/transaction/resources/httpResources.js +7 -0
  288. package/dist/transaction/resources/modelOperations.d.ts +427 -0
  289. package/dist/transaction/resources/modelOperations.js +12 -0
  290. package/dist/transaction/resources/mutationOptions.d.ts +66 -0
  291. package/dist/transaction/resources/mutationOptions.js +9 -0
  292. package/dist/transaction/resources/where.d.ts +101 -0
  293. package/dist/transaction/resources/where.js +115 -0
  294. package/dist/{client → transaction/resources}/writeOptionsSchema.d.ts +2 -6
  295. package/dist/{client → transaction/resources}/writeOptionsSchema.js +9 -5
  296. package/dist/{schema → transaction/schema}/field.d.ts +17 -23
  297. package/dist/{schema → transaction/schema}/field.js +5 -5
  298. package/dist/transaction/schema/fieldRef.d.ts +38 -0
  299. package/dist/transaction/schema/fieldRef.js +11 -0
  300. package/dist/transaction/schema/loadStrategy.d.ts +45 -0
  301. package/dist/transaction/schema/loadStrategy.js +46 -0
  302. package/dist/{schema → transaction/schema}/model.d.ts +50 -35
  303. package/dist/{schema → transaction/schema}/model.js +30 -20
  304. package/dist/transaction/schema/openapi.d.ts +58 -0
  305. package/dist/transaction/schema/openapi.js +501 -0
  306. package/dist/{schema → transaction/schema}/relation.d.ts +21 -16
  307. package/dist/{schema → transaction/schema}/relation.js +7 -7
  308. package/dist/{schema → transaction/schema}/residency.d.ts +0 -9
  309. package/dist/{schema → transaction/schema}/residency.js +0 -5
  310. package/dist/{schema → transaction/schema}/roles.d.ts +5 -5
  311. package/dist/{schema → transaction/schema}/roles.js +5 -5
  312. package/dist/{schema → transaction/schema}/schema.d.ts +39 -10
  313. package/dist/{schema → transaction/schema}/schema.js +24 -3
  314. package/dist/{schema → transaction/schema}/tenancy.d.ts +1 -1
  315. package/dist/{schema → transaction/schema}/tenancy.js +7 -4
  316. package/dist/transaction/transactionLayer.d.ts +82 -0
  317. package/dist/transaction/transactionLayer.js +24 -0
  318. package/dist/{transactions → transaction/transactions/settlement}/commitEnvelope.d.ts +5 -6
  319. package/dist/{transactions → transaction/transactions/settlement}/commitEnvelope.js +9 -13
  320. package/dist/{transactions → transaction/transactions/settlement}/httpCommitEnvelope.d.ts +9 -2
  321. package/dist/{transactions → transaction/transactions/settlement}/httpCommitEnvelope.js +5 -9
  322. package/dist/{transactions/durableWriteStore.d.ts → transaction/transactions/settlement/pendingWrite.d.ts} +11 -37
  323. package/dist/transaction/transactions/settlement/pendingWrite.js +20 -0
  324. package/dist/transaction/transport/commitFrames.d.ts +90 -0
  325. package/dist/transaction/transport/commitFrames.js +134 -0
  326. package/dist/transaction/transport/connectionManager.d.ts +215 -0
  327. package/dist/transaction/transport/connectionManager.js +673 -0
  328. package/dist/transaction/transport/credentialLifecycle.d.ts +177 -0
  329. package/dist/transaction/transport/credentialLifecycle.js +324 -0
  330. package/dist/{sync → transaction/transport}/heartbeat.d.ts +3 -1
  331. package/dist/{sync → transaction/transport}/heartbeat.js +6 -4
  332. package/dist/transaction/transport/httpClient.d.ts +131 -0
  333. package/dist/{client → transaction/transport}/httpClient.js +6 -5
  334. package/dist/transaction/transport/httpOptions.d.ts +33 -0
  335. package/dist/transaction/transport/httpOptions.js +12 -0
  336. package/dist/{client → transaction/transport}/httpTransport.js +295 -97
  337. package/dist/{sync/NetworkProbe.d.ts → transaction/transport/networkProbe.d.ts} +7 -4
  338. package/dist/{sync/NetworkProbe.js → transaction/transport/networkProbe.js} +14 -13
  339. package/dist/transaction/transport/wsFrameHandlers.d.ts +128 -0
  340. package/dist/transaction/transport/wsFrameHandlers.js +429 -0
  341. package/dist/transaction/transport/wsTransport.d.ts +574 -0
  342. package/dist/transaction/transport/wsTransport.js +1023 -0
  343. package/dist/transaction/types/assertExact.d.ts +17 -0
  344. package/dist/transaction/types/assertExact.js +1 -0
  345. package/dist/{types → transaction/types}/global.d.ts +17 -2
  346. package/dist/{types → transaction/types}/global.js +2 -1
  347. package/dist/{types → transaction/types}/index.d.ts +14 -46
  348. package/dist/{types → transaction/types}/index.js +7 -16
  349. package/dist/{types → transaction/types}/streams.d.ts +73 -45
  350. package/dist/transaction/utils/duration.d.ts +50 -0
  351. package/dist/{utils → transaction/utils}/duration.js +32 -0
  352. package/dist/{utils → transaction/utils}/json.d.ts +18 -0
  353. package/dist/transaction/utils/json.js +276 -0
  354. package/dist/transaction/wire/accountResponses.d.ts +420 -0
  355. package/dist/transaction/wire/accountResponses.js +290 -0
  356. package/dist/transaction/wire/auth.d.ts +56 -0
  357. package/dist/transaction/wire/auth.js +63 -0
  358. package/dist/transaction/wire/claimEvent.d.ts +76 -0
  359. package/dist/transaction/wire/claimEvent.js +73 -0
  360. package/dist/transaction/wire/claims.d.ts +530 -0
  361. package/dist/transaction/wire/claims.js +327 -0
  362. package/dist/{wire → transaction/wire}/commit.d.ts +125 -193
  363. package/dist/{wire → transaction/wire}/commit.js +68 -47
  364. package/dist/{wire → transaction/wire}/delta.d.ts +66 -17
  365. package/dist/{wire → transaction/wire}/delta.js +37 -13
  366. package/dist/transaction/wire/errorEnvelope.d.ts +72 -0
  367. package/dist/{wire → transaction/wire}/errorEnvelope.js +36 -5
  368. package/dist/transaction/wire/feedCursor.d.ts +60 -0
  369. package/dist/transaction/wire/feedCursor.js +82 -0
  370. package/dist/transaction/wire/feedEvent.d.ts +204 -0
  371. package/dist/transaction/wire/feedEvent.js +65 -0
  372. package/dist/transaction/wire/frames.d.ts +194 -0
  373. package/dist/transaction/wire/frames.js +50 -0
  374. package/dist/transaction/wire/inboundFrames.d.ts +562 -0
  375. package/dist/transaction/wire/inboundFrames.js +116 -0
  376. package/dist/transaction/wire/index.d.ts +54 -0
  377. package/dist/transaction/wire/index.js +83 -0
  378. package/dist/{wire → transaction/wire}/listEnvelope.d.ts +13 -14
  379. package/dist/transaction/wire/listEnvelope.js +42 -0
  380. package/dist/transaction/wire/modelMutations.d.ts +31 -0
  381. package/dist/transaction/wire/modelMutations.js +52 -0
  382. package/dist/transaction/wire/modelResponses.d.ts +85 -0
  383. package/dist/transaction/wire/modelResponses.js +43 -0
  384. package/dist/transaction/wire/modelShape.d.ts +78 -0
  385. package/dist/transaction/wire/modelShape.js +74 -0
  386. package/dist/transactions/{TransactionQueue.d.ts → mutations/MutationQueue.d.ts} +85 -38
  387. package/dist/transactions/{TransactionQueue.js → mutations/MutationQueue.js} +141 -80
  388. package/dist/transactions/{TransactionStore.d.ts → mutations/MutationStore.d.ts} +8 -8
  389. package/dist/transactions/{TransactionStore.js → mutations/MutationStore.js} +2 -2
  390. package/dist/transactions/{coalesceRules.d.ts → mutations/coalesceRules.d.ts} +10 -10
  391. package/dist/transactions/{coalesceRules.js → mutations/coalesceRules.js} +1 -1
  392. package/dist/transactions/mutations/commitLatency.d.ts +52 -0
  393. package/dist/transactions/mutations/commitLatency.js +130 -0
  394. package/dist/transactions/{commitOutboxStore.d.ts → mutations/commitOutboxStore.d.ts} +1 -5
  395. package/dist/transactions/{commitOutboxStore.js → mutations/commitOutboxStore.js} +1 -1
  396. package/dist/transactions/{commitPayload.d.ts → mutations/commitPayload.d.ts} +18 -16
  397. package/dist/transactions/{commitPayload.js → mutations/commitPayload.js} +15 -15
  398. package/dist/transactions/{deltaConfirmation.d.ts → mutations/deltaConfirmation.d.ts} +15 -11
  399. package/dist/transactions/{deltaConfirmation.js → mutations/deltaConfirmation.js} +14 -12
  400. package/dist/transactions/mutations/durableWriteStore.d.ts +14 -0
  401. package/dist/transactions/mutations/durableWriteStore.js +12 -0
  402. package/dist/transactions/{optimisticApply.d.ts → mutations/optimisticApply.d.ts} +7 -7
  403. package/dist/transactions/{replayValidation.d.ts → mutations/replayValidation.d.ts} +4 -3
  404. package/dist/transactions/{replayValidation.js → mutations/replayValidation.js} +7 -5
  405. package/dist/utils/mobxSetup.d.ts +1 -1
  406. package/dist/utils/mobxSetup.js +5 -2
  407. package/dist/{core → views}/QueryView.d.ts +2 -2
  408. package/dist/{core → views}/QueryView.js +2 -2
  409. package/dist/{core → views}/ViewRegistry.d.ts +1 -1
  410. package/dist/{core/queryUtils.d.ts → views/incrementalView.d.ts} +6 -6
  411. package/dist/{core/queryUtils.js → views/incrementalView.js} +6 -6
  412. package/dist/webhooks/events.d.ts +2 -2
  413. package/dist/wire/index.d.ts +1 -34
  414. package/dist/wire/index.js +8 -49
  415. package/docs/agent-messaging.md +3 -3
  416. package/docs/agents.md +20 -13
  417. package/docs/api-keys.md +14 -10
  418. package/docs/api.md +27 -61
  419. package/docs/audit.md +6 -3
  420. package/docs/cli.md +41 -13
  421. package/docs/client-behavior.md +11 -9
  422. package/docs/concurrency-convention.md +49 -57
  423. package/docs/coordination.md +283 -121
  424. package/docs/data-sources.md +7 -5
  425. package/docs/debugging.md +39 -15
  426. package/docs/deployment.md +267 -0
  427. package/docs/examples/agent-human.md +49 -42
  428. package/docs/examples/ai-sdk-tool.md +69 -44
  429. package/docs/examples/existing-python-backend.md +8 -6
  430. package/docs/examples/nextjs.md +129 -47
  431. package/docs/examples/scoped-agent.md +46 -45
  432. package/docs/examples/server-agent.md +46 -26
  433. package/docs/groups.md +87 -30
  434. package/docs/guarantees.md +41 -12
  435. package/docs/how-it-works.md +38 -12
  436. package/docs/idempotency.md +126 -0
  437. package/docs/identity.md +77 -74
  438. package/docs/index.md +172 -86
  439. package/docs/integration-guide.md +31 -19
  440. package/docs/mcp.md +46 -21
  441. package/docs/migration.md +95 -18
  442. package/docs/operating-on-your-database.md +3 -1
  443. package/docs/projects.md +3 -1
  444. package/docs/quickstart.md +22 -5
  445. package/docs/react.md +31 -18
  446. package/docs/schema-contract.md +5 -3
  447. package/docs/session-settings.md +108 -0
  448. package/docs/sessions.md +4 -2
  449. package/docs/webhooks.md +12 -10
  450. package/llms.txt +48 -18
  451. package/package.json +21 -26
  452. package/dist/agent/Agent.d.ts +0 -366
  453. package/dist/agent/Agent.js +0 -514
  454. package/dist/agent/index.d.ts +0 -115
  455. package/dist/agent/index.js +0 -128
  456. package/dist/agent/session.d.ts +0 -93
  457. package/dist/agent/session.js +0 -149
  458. package/dist/agent/types.d.ts +0 -68
  459. package/dist/agent/types.js +0 -9
  460. package/dist/cli.cjs +0 -286329
  461. package/dist/client/durableWrites.d.ts +0 -21
  462. package/dist/client/httpClient.d.ts +0 -80
  463. package/dist/coordination/schema.d.ts +0 -722
  464. package/dist/coordination/schema.js +0 -578
  465. package/dist/schema/openapi.d.ts +0 -29
  466. package/dist/schema/openapi.js +0 -124
  467. package/dist/testing/fixtures/bootstrap.d.ts +0 -49
  468. package/dist/testing/fixtures/bootstrap.js +0 -59
  469. package/dist/testing/fixtures/deltas.d.ts +0 -83
  470. package/dist/testing/fixtures/deltas.js +0 -136
  471. package/dist/testing/fixtures/models.d.ts +0 -83
  472. package/dist/testing/fixtures/models.js +0 -272
  473. package/dist/testing/helpers/reactWrapper.d.ts +0 -69
  474. package/dist/testing/helpers/reactWrapper.js +0 -67
  475. package/dist/testing/helpers/syncEngineHarness.d.ts +0 -54
  476. package/dist/testing/helpers/syncEngineHarness.js +0 -73
  477. package/dist/testing/helpers/wait.d.ts +0 -30
  478. package/dist/testing/helpers/wait.js +0 -49
  479. package/dist/testing/index.d.ts +0 -23
  480. package/dist/testing/index.js +0 -33
  481. package/dist/testing/mocks/FakeDatabase.d.ts +0 -18
  482. package/dist/testing/mocks/FakeDatabase.js +0 -10
  483. package/dist/testing/mocks/MockMutationExecutor.d.ts +0 -87
  484. package/dist/testing/mocks/MockMutationExecutor.js +0 -192
  485. package/dist/testing/mocks/MockNetworkMonitor.d.ts +0 -20
  486. package/dist/testing/mocks/MockNetworkMonitor.js +0 -46
  487. package/dist/testing/mocks/MockSyncContext.d.ts +0 -51
  488. package/dist/testing/mocks/MockSyncContext.js +0 -71
  489. package/dist/testing/mocks/MockSyncStore.d.ts +0 -88
  490. package/dist/testing/mocks/MockSyncStore.js +0 -171
  491. package/dist/testing/mocks/MockWebSocket.d.ts +0 -71
  492. package/dist/testing/mocks/MockWebSocket.js +0 -118
  493. package/dist/transactions/durableWriteStore.js +0 -30
  494. package/dist/utils/duration.d.ts +0 -25
  495. package/dist/utils/json.js +0 -88
  496. package/dist/wire/errorEnvelope.d.ts +0 -55
  497. package/dist/wire/frames.d.ts +0 -197
  498. package/dist/wire/frames.js +0 -49
  499. package/dist/wire/listEnvelope.js +0 -18
  500. package/docs/interaction-model.md +0 -97
  501. /package/dist/{core → query}/QueryProcessor.d.ts +0 -0
  502. /package/dist/{core → query}/QueryProcessor.js +0 -0
  503. /package/dist/{core/storeContract.js → storeContract.js} +0 -0
  504. /package/dist/{core → stores}/openIDBWithTimeout.d.ts +0 -0
  505. /package/dist/{core → stores}/openIDBWithTimeout.js +0 -0
  506. /package/dist/{client → transaction/auth}/credentialEndpoint.d.ts +0 -0
  507. /package/dist/{client → transaction/auth}/credentialEndpoint.js +0 -0
  508. /package/dist/{auth → transaction/auth}/credentialPolicy.d.ts +0 -0
  509. /package/dist/{auth → transaction/auth}/credentialPolicy.js +0 -0
  510. /package/dist/{auth → transaction/auth}/credentialSource.js +0 -0
  511. /package/dist/{client → transaction/auth}/hostedEndpoints.d.ts +0 -0
  512. /package/dist/{client → transaction/auth}/hostedEndpoints.js +0 -0
  513. /package/dist/{client → transaction}/persistence.d.ts +0 -0
  514. /package/dist/{client → transaction}/persistence.js +0 -0
  515. /package/dist/{client → transaction/resources}/functionalUpdate.d.ts +0 -0
  516. /package/dist/{client → transaction/resources}/functionalUpdate.js +0 -0
  517. /package/dist/{transactions → transaction/transactions/settlement}/idempotencyKey.d.ts +0 -0
  518. /package/dist/{transactions → transaction/transactions/settlement}/idempotencyKey.js +0 -0
  519. /package/dist/{client → transaction/transport}/httpTransport.d.ts +0 -0
  520. /package/dist/{types → transaction/types}/modelData.d.ts +0 -0
  521. /package/dist/{types → transaction/types}/modelData.js +0 -0
  522. /package/dist/{types → transaction/types}/participant.d.ts +0 -0
  523. /package/dist/{types → transaction/types}/participant.js +0 -0
  524. /package/dist/{types → transaction/types}/streams.js +0 -0
  525. /package/dist/{utils → transaction/utils}/asyncIterator.d.ts +0 -0
  526. /package/dist/{utils → transaction/utils}/asyncIterator.js +0 -0
  527. /package/dist/{wire → transaction/wire}/bootstrapReason.d.ts +0 -0
  528. /package/dist/{wire → transaction/wire}/bootstrapReason.js +0 -0
  529. /package/dist/{wire → transaction/wire}/protocol.d.ts +0 -0
  530. /package/dist/{wire → transaction/wire}/protocol.js +0 -0
  531. /package/dist/{wire → transaction/wire}/protocolVersion.d.ts +0 -0
  532. /package/dist/{wire → transaction/wire}/protocolVersion.js +0 -0
  533. /package/dist/transactions/{UnconfirmedWrites.d.ts → mutations/UnconfirmedWrites.d.ts} +0 -0
  534. /package/dist/transactions/{UnconfirmedWrites.js → mutations/UnconfirmedWrites.js} +0 -0
  535. /package/dist/transactions/{optimisticApply.js → mutations/optimisticApply.js} +0 -0
  536. /package/dist/{core → views}/ViewRegistry.js +0 -0
package/docs/api.md CHANGED
@@ -1,5 +1,7 @@
1
1
  # API
2
2
 
3
+ > The per-method reference for every model call an agent or an interface can make.
4
+
3
5
  > **Upgrading?** Every breaking change and its migration is on the
4
6
  > [Version History & Migration Guide](./migration.md).
5
7
 
@@ -11,10 +13,12 @@ row, you can optionally `claim` it so they serialize instead of clobbering
11
13
  each other.
12
14
 
13
15
  Two things to know before the method list. **Reads come in two flavors:**
14
- `retrieve({ id })` / `list({ where })` are async and hit the server (use them when
15
- the row may not be local yet); `get(id)` / `getAll({ where })` / `getCount({ where })`
16
- are synchronous reads off the local graph (use them in render, after data has
17
- synced). **Claims don't lock.** If another writer holds the row, `claim` waits
16
+ `retrieve({ id })` / `list({ where })` are async they answer from what is
17
+ already local and fall back to the server. Put `local.` in front of either and
18
+ you get the same read restricted to what is already here, which is why it can
19
+ return a value rather than a promise: `local.retrieve(id)`, `local.list({ where })`,
20
+ `local.count({ where })`. Use those in render, after data has synced.
21
+ **Claims don't lock.** If another writer holds the row, `claim` waits
18
22
  for them, re-reads the fresh row, then hands it to you — so two writers
19
23
  serialize instead of clobbering.
20
24
 
@@ -49,31 +53,31 @@ Each schema model becomes a typed model on the client:
49
53
 
50
54
  - `ablo.weatherReports.retrieve({ id })` reads one row asynchronously (server read).
51
55
  - `ablo.weatherReports.list({ where })` reads a collection asynchronously (server read).
52
- - `ablo.weatherReports.get(id)` reads one row synchronously from the local graph.
56
+ - `ablo.weatherReports.local.retrieve(id)` reads one row synchronously from the local graph.
53
57
  - `ablo.weatherReports.create({ data })` creates a row.
54
58
  - `ablo.weatherReports.update({ id, data, ...options })` updates a row.
55
59
  - `ablo.weatherReports.delete({ id, ...options })` deletes a row.
56
60
 
57
- `retrieve`/`list` and `get`/`getAll`/`getCount` are not aliases. Use
58
- `retrieve({ id })` or `list({ where })` when the row may not be local yet they
59
- hydrate pool IndexedDB network. Use `get(id)` / `getAll({ where })` /
60
- `getCount({ where })` for a cheap synchronous snapshot of what is already in
61
- the local graph.
61
+ `local.` narrows a read to what has already synced. `retrieve({ id })` and
62
+ `list({ where })` answer from the local graph and fall back to IndexedDB and
63
+ then the network, so reach for them when the row may not be here yet.
64
+ `local.retrieve(id)` and `local.list({ where })` are the same reads with the
65
+ fallback removed — nothing to await, so they return a value.
62
66
 
63
67
  | Method | Returns | Use when |
64
68
  |---|---|---|
65
69
  | `retrieve({ id })` | `Promise<T \| undefined>` | You need one row, hydrating from local store and server. |
66
70
  | `list({ where })` | `Promise<T[]>` | You need to hydrate a collection from local store and server. |
67
- | `get(id)` | `T \| undefined` | You want a synchronous snapshot of one local row. |
68
- | `getAll(options?)` | `T[]` | You want a synchronous snapshot of a local collection. |
69
- | `getCount(options?)` | `number` | You want a synchronous count of local rows. |
71
+ | `local.retrieve(id)` | `T \| undefined` | You want a synchronous snapshot of one local row. |
72
+ | `local.list(options?)` | `T[]` | You want a synchronous snapshot of a local collection. |
73
+ | `local.count(options?)` | `number` | You want a synchronous count of local rows. |
70
74
  | `create({ data, ...options })` | `Promise<T>` | You want to create through the schema model. |
71
75
  | `update({ id, data, ...options })` | `Promise<T>` | You want to update through the schema model. |
72
76
  | `delete({ id, ...options })` | `Promise<void>` | You want to delete through the schema model. |
73
77
 
74
78
  `retrieve`, `list`, `create`, `update`, and `delete` are the main path — they go
75
- through the server. `get` / `getAll` / `getCount` are **synchronous reads**
76
- off the rows a session has already synced, so a cheap re-read needs no round-trip.
79
+ through the server. The `local` reads work off the rows a session has already
80
+ synced, so a cheap re-read needs no round-trip.
77
81
 
78
82
  ## Protected Writes
79
83
 
@@ -103,7 +107,7 @@ Protected write options:
103
107
 
104
108
  ## Claims
105
109
 
106
- Before anyone writes a row, they can claim it so other people and agents see
110
+ Before anyone writes a row, they can claim it so other agents and people see
107
111
  who is editing it in real time. Claims don't lock. If another writer holds the
108
112
  row, `claim` waits for them, re-reads the fresh row, then hands it to you — so
109
113
  two writers serialize instead of clobbering. A claim is temporary: it expires
@@ -116,49 +120,11 @@ blocks), and `ablo.<model>.claim.release({ id })` releases it early. The full
116
120
  coordination surface is `claim.state({ id })` / `claim.queue({ id })` /
117
121
  `claim.release({ id })` / `claim.reorder({ id, order })` hanging off `claim`.
118
122
 
119
- ### The Claim State Object
120
-
121
- | Field | Type | Description |
122
- |---|---|---|
123
- | `object` | `'claim'` | String representing the object's type. |
124
- | `id` | string | Unique identifier for the claim. |
125
- | `status` | `'active' \| 'queued' \| 'committed' \| 'expired' \| 'canceled'` | The whole lifecycle, in one field. `active` is the holder; `queued` is a waiter in the FIFO line behind it. |
126
- | `target` | `{ type, id, field? }` | What is being coordinated. |
127
- | `description` | string | Peer-visible phrase for the work in progress — `'editing'`, `'writing'`, `'reviewing the risk section'`. Defaults to `'editing'`, and rides back in the rejection a blocked writer receives. |
128
- | `heldBy` | string | Participant id holding the claim. |
129
- | `participantKind` | `'user' \| 'agent' \| 'system'` | Who's behind it — a human (`user`), an AI (`agent`), or automated infrastructure (`system`). |
130
- | `createdAt` | number? | Ms-epoch the holder opened it. Optional — derived shapes may omit it. |
131
- | `expiresAt` | number | Ms-epoch at which the server auto-expires it if the holder doesn't finish. |
132
-
133
- ```json
134
- {
135
- "object": "claim",
136
- "id": "claim_3MtwBwLkdIwHu7ix",
137
- "status": "active",
138
- "target": { "type": "weatherReports", "id": "report_stockholm", "field": "status" },
139
- "description": "editing",
140
- "heldBy": "agent:report-writer",
141
- "participantKind": "agent",
142
- "expiresAt": 1716580000000
143
- }
144
- ```
145
-
146
- ### Lifecycle
147
-
148
- ```
149
- claim({ id }) update({ id }) lands
150
- (free) ───────────▶ active ───────────────────────▶ committed
151
-
152
- ┌───────────┴───────────┐
153
- ▼ ▼
154
- canceled expired
155
- (release w/o write) (TTL; holder died)
156
- ```
157
-
158
- A target is free when `ablo.<model>.claim.state({ id })` is `null`. Terminal
159
- states drop out of the live stream, so a present claim is either `active` (the
160
- holder) or `queued` (waiting in the FIFO line behind the holder; see
161
- `claim.queue({ id })`).
123
+ The fields on a claim, its lifecycle diagram, and the full method surface are in
124
+ [Coordination](./coordination.md#the-claim-state-object), which is where that
125
+ object is defined. Note that the entity half of `target` is spelled `model`/`id`
126
+ on the SDK's model surface and `type`/`id` on the claim handle and the wait
127
+ line.
162
128
 
163
129
  ### Reading and claiming
164
130
 
@@ -206,7 +172,7 @@ The SDK is a convenience wrapper over a model-scoped HTTP surface — the same
206
172
  noun (`model`) and verbs as `ablo.<model>.…`. Non-JS callers (or curl) use it
207
173
  directly. The table below shows the shape with `{model}` as a placeholder; the
208
174
  [OpenAPI spec](./openapi.json) expands it into one **typed** path per model
209
- (`/api/v1/models/task`, `/api/v1/models/deck`, …, generated from your schema) so each
175
+ (`/api/v1/models/task`, `/api/v1/models/workspace`, …, generated from your schema) so each
210
176
  endpoint documents that model's real field contract instead of a generic blob.
211
177
 
212
178
  | SDK call | HTTP |
@@ -232,7 +198,7 @@ error `code` (e.g. `stale_context`, `intent_conflict`) to act on.
232
198
  operations across rows/models that must commit together) — the per-model routes
233
199
  above are the one-record path. Both run the identical guarded-write engine.
234
200
 
235
- The [coordination MCP server](./mcp.md) (`@ablo/mcp`) is this same surface
201
+ The [coordination MCP server](./mcp.md) (`@abloatai/mcp`) is this same surface
236
202
  rendered as agent tools.
237
203
 
238
204
  ## Errors
package/docs/audit.md CHANGED
@@ -1,5 +1,7 @@
1
1
  # Audit log
2
2
 
3
+ > Trace any committed change back to the key that made it, and to the person behind that key.
4
+
3
5
  The audit log records who changed what in your org, and when — including
4
6
  changes an AI agent made on a person's behalf. Every change is one row, and the
5
7
  rows are chained with a keyed hash (HMAC-SHA256) so you can later prove the
@@ -21,11 +23,12 @@ with which key — and the chain columns that make the log tamper-evident:
21
23
  capabilityId: string | null, // the API key/capability used for the write
22
24
  capabilityLabel: string | null, // its human-readable name, for scanning the log
23
25
  delegationChainRootUserId: string | null, // always points at a human
24
- actionType: string, // e.g. 'weatherReport.update'
25
- modelName: string, // e.g. 'claude-opus-4-8'
26
+ actionType: 'I' | 'U' | 'D', // insert, update, delete
27
+ modelName: string, // the model that changed, e.g. 'orders'
28
+ modelId: string, // the row that changed
26
29
  confirmationState: 'auto' | 'previewed' | 'approved' | 'required_human_approval' | 'auto_historical',
27
30
  diffSummary: unknown,
28
- // chain columns carried on every stored row, checked by verify (below)
31
+ // chain columns, carried on every stored row and checked by verify (below)
29
32
  chainSeq: number,
30
33
  prevHash: string,
31
34
  rowHash: string,
package/docs/cli.md CHANGED
@@ -1,5 +1,7 @@
1
1
  # CLI
2
2
 
3
+ > Scaffold a schema, connect a database, push it, and watch it sync.
4
+
3
5
  The `ablo` CLI gets you from an empty project to live-syncing data: scaffold a
4
6
  schema, authenticate, push the schema, and watch it sync. Your
5
7
  `defineSchema(...)` is the single source of truth: whether you run the CLI
@@ -34,7 +36,7 @@ This mirrors `stripe login`.
34
36
  | `ablo login` | Authorize in the browser; provisions + stores a test and a live key. |
35
37
  | `ablo login --project <slug>` | Same, but scope (and mint) the pair to a project, and make it active. |
36
38
  | `ablo logout` | Remove the stored keys. |
37
- | `ablo status` | Show the active org, mode, both keys (prefix + expiry), and server health. |
39
+ | `ablo status` | Show the active org, mode, both keys (prefix, what each can do, expiry), and server health. |
38
40
  | `ablo mode [sandbox\|production]` | Switch the active environment. With no argument, prompts. |
39
41
 
40
42
  Keys live in `~/.config/ablo/credentials.json` (mode `0600`), keyed by project
@@ -49,8 +51,11 @@ belongs to one of them. Test keys are bound to an isolated sandbox: their reads
49
51
  and writes never touch production data. Switch with `ablo mode`; `ablo dev` is always
50
52
  the sandbox by design.
51
53
 
52
- The schema, however, is **shared** across the org pushing a schema (from
53
- either environment) defines the same models sandbox and production see; only the rows differ.
54
+ The schema is **one definition serving both**: a sandbox reads the production
55
+ schema until it is pushed one of its own, so your test and live keys see the same
56
+ models and only the rows differ. Each plane keeps its own copy once pushed, so a
57
+ schema change reaches production when you push it with a live key — see
58
+ [Deployment](./deployment.md).
54
59
 
55
60
  ## Projects
56
61
 
@@ -89,17 +94,40 @@ profiles entirely: it acts in whatever project it was minted for.
89
94
 
90
95
  | Command | What it does | Flags |
91
96
  | ---------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------ |
92
- | `ablo init` | Scaffold `ablo/` (`schema.ts`, client, optional Data Source / agent / component), write `.env`, install the SDK. Offers to log in at the end. | |
93
- | `ablo login` / `logout` / `status` | Authentication & status (above). | |
94
- | `ablo mode [sandbox\|production]` | Switch active environment. | |
97
+ | `ablo init` | Scaffold `ablo/` (`schema.ts`, client, optional Data Source / agent / component), write `.env`, install the SDK. Offers to log in at the end. |: |
98
+ | `ablo login` / `logout` / `status` | Authentication & status (above). |: |
99
+ | `ablo mode [sandbox\|production]` | Switch active environment. |: |
95
100
  | `ablo projects list\|create\|use\|rename` | Manage projects and the active one (see [Projects](#projects)). Each project's keys/schema/data are isolated. | `--name "<display>"` (create/rename) |
96
- | `ablo dev` | **Hosted** push the schema to your test sandbox, then watch `ablo/schema.ts` and re-push on save. | `--no-watch`, `--schema <path>`, `--export <name>`, `--url <url>` |
101
+ | `ablo dev` | **Hosted**: push the schema to your test sandbox, then watch `ablo/schema.ts` and re-push on save. | `--no-watch`, `--schema <path>`, `--export <name>`, `--url <url>` |
97
102
  | `ablo logs` | Tail your scope's commit activity (`stripe logs tail`). Follows by default. | `-n, --tail <N>`, `--since <dur\|ts>`, `--model`, `--op`, `--json`, `--no-follow`, `--mode sandbox\|production` |
98
- | `ablo push` | **Hosted** upload the schema to Ablo; the server diffs, migrates, and activates it. | `--force`, `--rename old:new`, `--backfill model.field=value`, `--schema`, `--export`, `--url` |
99
- | `ablo migrate` | **Direct Postgres** provision just the synced models (plus the adapter's `ablo_outbox` / `ablo_idempotency`) in your own `DATABASE_URL`. Leaves your other tables alone. | `--dry-run`, `--output <file>`, `--schema`, `--export` |
100
- | `ablo pull` | **Direct Postgres** generate `defineSchema(...)` from your existing tables (read-only, like `prisma db pull`). | `--out <path>`, `--app-schema <name>`, `--import <pkg>`, `--force` |
101
- | `ablo check` | **Direct Postgres** verify your _existing_ tables fit the schema (read-only, no schema changes). | `--schema <path>`, `--export <name>`, `--app-schema <name>` |
103
+ | `ablo push` | **Hosted**: upload the schema to Ablo; the server diffs, migrates, and activates it. | `--force`, `--rename old:new`, `--backfill model.field=value`, `--schema`, `--export`, `--url` |
104
+ | `ablo migrate` | **Direct Postgres**: provision just the synced models (plus the adapter's `ablo_outbox` / `ablo_idempotency`) in your own `DATABASE_URL`. Leaves your other tables alone. | `--dry-run`, `--output <file>`, `--schema`, `--export` |
105
+ | `ablo pull` | **Direct Postgres**: generate `defineSchema(...)` from your existing tables (read-only, like `prisma db pull`). | `--out <path>`, `--app-schema <name>`, `--import <pkg>`, `--force` |
106
+ | `ablo check` | **Direct Postgres**: verify your _existing_ tables fit the schema (read-only, no schema changes). | `--schema <path>`, `--export <name>`, `--app-schema <name>` |
102
107
  | `ablo generate` | Emit TypeScript types from the schema. | `--out <path>`, `--schema`, `--export` |
108
+ | `ablo docs` | Read these pages for the version you installed: offline, no network (see [`ablo docs`](#ablo-docs)). | `--json` |
109
+
110
+ ## `ablo docs`
111
+
112
+ The documentation for the version in your `node_modules`, not the version on the
113
+ website.
114
+
115
+ ```bash
116
+ npx ablo docs # every page, with what it covers
117
+ npx ablo docs coordination # one page, as markdown
118
+ npx ablo docs --json # the page list, machine-readable
119
+ ```
120
+
121
+ These pages ship inside the npm package, so they describe the code beside them
122
+ and stay reachable with no network — the sandboxes and CI runners agents work in
123
+ often have none. That matters most when a project is pinned: `get` / `getAll` /
124
+ `getCount` became `retrieve` / `list` in 0.35.0, and a website always describes
125
+ the newest release, so an agent on an earlier version reads the new name and
126
+ writes a call its own package doesn't have.
127
+
128
+ Pass a slug (`coordination`), a path (`docs/coordination.md`), or a file name
129
+ (`AGENTS.md`). A miss names the closest page. The same pages are served over
130
+ HTTP at `/api/docs/<slug>` and through the docs MCP server.
103
131
 
104
132
  ## `ablo dev`
105
133
 
@@ -213,7 +241,7 @@ The one type map, shared by both paths (there is no second mapping):
213
241
  | Zod | Postgres |
214
242
  | ------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------- |
215
243
  | `z.string()` | `TEXT` |
216
- | `z.number()` | `DOUBLE PRECISION` never `INTEGER`; a Zod number may be fractional, and truncating is silent data loss |
244
+ | `z.number()` | `DOUBLE PRECISION`: never `INTEGER`; a Zod number may be fractional, and truncating is silent data loss |
217
245
  | `z.boolean()` | `BOOLEAN` |
218
246
  | `z.date()` | `TIMESTAMPTZ` |
219
247
  | `z.enum([...])` | `TEXT` + a `CHECK (col IN (...))` constraint |
@@ -268,7 +296,7 @@ migration can't leave clients gated against tables that don't match.
268
296
 
269
297
  | Variable | Purpose | Default |
270
298
  | ------------------------------------- | ------------------------------------------------------------------------ | -------------------------- |
271
- | `ABLO_API_KEY` | Authenticate without `ablo login` (CI). Always overrides the stored key. | |
299
+ | `ABLO_API_KEY` | Authenticate without `ablo login` (CI). Always overrides the stored key. |: |
272
300
  | `ABLO_API_URL` | Control-plane / API host (`push`, `dev`, `status`). | `https://api.abloatai.com` |
273
301
  | `ABLO_AUTH_URL` | Dashboard origin for `ablo login`'s device flow. | `https://abloatai.com` |
274
302
  | `ABLO_CONFIG_DIR` / `XDG_CONFIG_HOME` | Where the credential file lives. | `~/.config/ablo` |
@@ -1,6 +1,8 @@
1
1
  # Client Behavior
2
2
 
3
- When several writers touch the same data at once — a person in the browser, a Server Action, an agent worker — the SDK decides whose write lands and how the others find out. This page is the reference for that: per-write options like `wait` and `onStale`, claiming a record so your slow work runs uninterrupted, and which errors are safe to retry.
3
+ > Per-write options, claim behavior, and which errors are safe to retry.
4
+
5
+ When several writers touch the same data at once — an agent worker, a Server Action, a person in the browser — the SDK decides whose write lands and how the others find out. This page is the reference for that: per-write options like `wait` and `onStale`, claiming a record so your slow work runs uninterrupted, and which errors are safe to retry.
4
6
 
5
7
  Claims don't lock. If another writer holds the row, `claim` waits for them, re-reads the fresh row, then hands it to you — so two writers serialize instead of clobbering.
6
8
 
@@ -32,7 +34,7 @@ Common options:
32
34
  | `baseURL` | Override the hosted sync endpoint for staging or private deployments. |
33
35
  | `persistence` | `memory` by default. Use `indexeddb` for a durable browser cache that survives reloads. |
34
36
  | `durableWrites` | Optional crash recovery for unacknowledged agent/worker writes. Independent of the default memory cache; accepts `{ store, namespace? }`. |
35
- | `transport` | `'websocket'` (default) is the live, stateful client a persistent socket, a local synced pool, and `onChange` subscriptions. `'http'` returns the **stateless** client for server-side actors (agents, workers, serverless): the same `ablo.<model>` read/write/claim surface, but each call is one HTTP round-trip with no socket. Under `'http'` the return type narrows to `AbloHttpClient`, so stateful-only methods (`get`/`getAll`, `onChange`, `join`) are compile errors rather than runtime gaps. |
37
+ | `transport` | `'websocket'` (default) is the live, stateful client: a persistent socket, a local synced pool, and `onChange` subscriptions. `'http'` returns the **stateless** client for server-side actors (agents, workers, serverless): the same `ablo.<model>` read/write/claim surface, but each call is one HTTP round-trip with no socket. Under `'http'` the return type narrows to `AbloHttpClient`, so stateful-only methods (the `local` reads, `onChange`, `join`) are compile errors rather than runtime gaps. |
36
38
  | `fetch` | Custom fetch implementation for tests or non-standard runtimes. |
37
39
  | `defaultHeaders` | Extra headers attached to every HTTP request. |
38
40
  | `defaultQuery` | Extra query parameters attached to every HTTP request. |
@@ -52,7 +54,7 @@ Each schema model becomes a typed model:
52
54
  await ablo.ready();
53
55
 
54
56
  const report = await ablo.weatherReports.retrieve({ id: 'report_stockholm' });
55
- const local = ablo.weatherReports.get('report_stockholm');
57
+ const local = ablo.weatherReports.local.retrieve('report_stockholm');
56
58
 
57
59
  await ablo.weatherReports.create({ data: { location: 'Stockholm', status: 'pending' } });
58
60
  await ablo.weatherReports.update({ id: 'report_stockholm', data: { status: 'ready' }, wait: 'confirmed' });
@@ -60,11 +62,11 @@ await ablo.weatherReports.delete({ id: 'report_stockholm', wait: 'confirmed' });
60
62
  ```
61
63
 
62
64
  Call `retrieve`/`list` first — they fetch from the server and you `await` them.
63
- After that, `get`/`getAll`/`getCount` read the already-synced data instantly with
65
+ After that, `local.retrieve`/`local.list`/`local.count` read the already-synced data instantly with
64
66
  no `await`, and stay reactive in render. Use the async pair to load, the sync trio
65
67
  to read.
66
68
 
67
- `getAll` accepts the same practical read options the React selector path uses:
69
+ `local.list` accepts the same practical read options the React selector path uses:
68
70
  `where`, `filter`, `orderBy`, `limit`, `offset`, and `state`. The `state`
69
71
  lifecycle filter defaults to `'live'`; pass `'archived'` or `'all'` when you
70
72
  intentionally want non-live rows.
@@ -91,7 +93,7 @@ await ablo.weatherReports.update({
91
93
 
92
94
  Once the server accepts the write, every other connected client gets the new row
93
95
  automatically — no polling or manual refresh on your side. React clients that use
94
- `useAblo((ablo) => ablo.weatherReports.get(id))` receive the new row, and selectors
96
+ `useAblo((ablo) => ablo.weatherReports.local.retrieve(id))` receive the new row, and selectors
95
97
  such as `useAblo((ablo) => ablo.weatherReports.claim.state({ id }))`
96
98
  receive active claim state. There is
97
99
  no extra multiplayer setup beyond routing shared state through Ablo.
@@ -216,8 +218,8 @@ Only these imports are public SemVer surface:
216
218
  - `@abloatai/ablo`
217
219
  - `@abloatai/ablo/schema`
218
220
  - `@abloatai/ablo/react`
219
- - `@abloatai/ablo/testing`
220
221
 
221
222
  `dataSource(...)` is exported from the root package for customer-owned storage
222
- adapters. Everything outside the four import paths is internal to Ablo-owned
223
- apps and infrastructure.
223
+ adapters. Everything outside the three import paths is internal to Ablo-owned
224
+ apps and infrastructure. For adapter authors, `@abloatai/ablo/source/conformance`
225
+ is the suite that proves a storage adapter behaves correctly.
@@ -1,8 +1,10 @@
1
1
  # Concurrency Convention
2
2
 
3
- > The governing convention for how Ablo resolves concurrent writes to shared
4
- > state, and the boundaries of that convention. This is the contract; the
5
- > three-layer mechanics live in [`coordination.md`](./coordination.md).
3
+ > The governing rule for how Ablo resolves concurrent writes to shared state.
4
+
5
+ This page is the contract: the `onStale` dispositions, what a conflict is
6
+ checked against, and where the convention stops. The three-layer mechanics of
7
+ claiming live in [Coordination](./coordination.md).
6
8
 
7
9
  ---
8
10
 
@@ -25,8 +27,8 @@ moments in time:
25
27
 
26
28
  | form | when | mechanism |
27
29
  |---|---|---|
28
- | **Claim** | *prospective* before you act | reserve the row; others queue. Coordinate so the conflict never forms. |
29
- | **Notification** | *in-flight* after a concurrent change | surface the changed value; the actor resolves and re-issues. |
30
+ | **Claim** | *prospective*: before you act | reserve the row; others queue. Coordinate so the conflict never forms. |
31
+ | **Notification** | *in-flight*: after a concurrent change | surface the changed value; the actor resolves and re-issues. |
30
32
 
31
33
  Use a claim when you will hold the row across a slow read→reason→write gap. Use a
32
34
  notification when you didn't, and the premise moved under you.
@@ -35,14 +37,14 @@ notification when you didn't, and the premise moved under you.
35
37
 
36
38
  ## 2. The dispositions (`onStale`)
37
39
 
38
- Every guarded write (and every read dependency, §4) declares how a stale premise
39
- should be handled. Three modes, split by whether they **force** an outcome:
40
+ Every guarded write (and every premise declared in §4) says what should happen
41
+ when it goes stale. Three modes, split by whether they **force** an outcome:
40
42
 
41
43
  | mode | coercive? | what the engine does | who resolves | use when |
42
44
  |---|---|---|---|---|
43
- | `notify` | **No** surface + delegate | Holds the write (does **not** apply it); returns a `StaleNotification` with the current value. | The actor (agent or human) reconciles and re-issues. | The aligned mode: tell the actor what changed, let it solve. |
44
- | `reject` | **Yes** force-abort | Throws `AbloStaleContextError`; the batch is discarded. | The caller retries from scratch. | Hard invariants; legacy/strict callers. The current default. |
45
- | `overwrite` | **Yes** force-clobber | Overwrites blindly last-writer-wins; **no** signal. | Nobody. | You genuinely own the field and concurrent values are noise. |
45
+ | `notify` | **No**: surface + delegate | Holds the write (does **not** apply it); returns a `StaleNotification` with the current value. | The actor (agent or human) reconciles and re-issues. | The aligned mode: tell the actor what changed, let it solve. |
46
+ | `reject` | **Yes**: force-abort | Throws `AbloStaleContextError`; the batch is discarded. | The caller retries from scratch. | Hard invariants; legacy/strict callers. The current default. |
47
+ | `overwrite` | **Yes**: force-clobber | Overwrites blindly last-writer-wins; **no** signal. | Nobody. | You genuinely own the field and concurrent values are noise. |
46
48
 
47
49
  > `notify` is the convention. `reject` and `overwrite` are escape hatches for the
48
50
  > two ends — "never let this be wrong" and "never bother me." They are not the
@@ -50,43 +52,44 @@ should be handled. Three modes, split by whether they **force** an outcome:
50
52
 
51
53
  ---
52
54
 
53
- ## 3. What is checked: two footprints
55
+ ## 3. What is checked: two premises
54
56
 
55
- A conflict is a **footprint intersection** — your operation's footprint overlaps
56
- a concurrent delta. Ablo checks two footprints, and they are independent:
57
+ A conflict is a **premise intersection** — what your operation was based on
58
+ overlaps a concurrent delta. Ablo checks two premises, and they are independent.
59
+ They differ only in what declared them:
57
60
 
58
- | footprint | declared by | question | scope |
61
+ | premise | declared by | question | scope |
59
62
  |---|---|---|---|
60
63
  | **Write-target** | per-op `readAt` | "did a row I'm **writing** change since I read it?" | the rows in `operations[]` |
61
- | **Read-set** | batch-level `reads[]` | "did anything I **looked at** change since I read it?" | rows/groups in `reads[]`, even if not written |
64
+ | **Batch** | batch-level `reads[]` | "did anything I **looked at** change since I read it?" | rows/groups in `reads[]`, even if not written |
62
65
 
63
66
  The write-target check alone is the narrow case the canary anomaly defeats: an
64
67
  agent reads `deal.stage`, writes `task.status`, and a peer moves `deal.stage` —
65
- `task` never changed, so a write-target-only check waves it through. The read-set
66
- closes that gap.
68
+ `task` never changed, so a write-target-only check waves it through. The batch
69
+ premise closes that gap.
67
70
 
68
71
  ---
69
72
 
70
- ## 4. The read-set (`reads[]`)
73
+ ## 4. The batch premise (`reads[]`)
71
74
 
72
- A commit may declare, at the batch level, the premises its writes depended on.
75
+ A commit may declare, at the batch level, what its writes were based on.
73
76
  Two granularities, developer's choice per entry:
74
77
 
75
78
  ```ts
76
79
  reads: [
77
- { model: 'Slide', id: 's-1', readAt: N, fields?: ['title'] }, // ROW premise
78
- { group: 'deck:abc', readAt: N, onStale: 'notify' }, // GROUP premise
80
+ { model: 'Document', id: 's-1', readAt: N, fields?: ['title'] }, // ROW premise
81
+ { group: 'workspace:abc', readAt: N, onStale: 'notify' }, // GROUP premise
79
82
  ]
80
83
  ```
81
84
 
82
- - **Row** did this specific row (optionally these fields) change? The literal
85
+ - **Row:** did this specific row (optionally these fields) change? The literal
83
86
  per-object premise.
84
- - **Group** did *anything* in this sync group change? `group` is a sync-group
85
- key (`deck:abc`, `slide:s1`, `org:X`) — the same unit a participant **watches
87
+ - **Group:** did *anything* in this sync group change? `group` is a sync-group
88
+ key (`workspace:abc`, `document:s1`, `org:X`) — the same unit a participant **watches
86
89
  and claims**. This is the more Ablo-native granularity.
87
90
 
88
- **Boundary — a stale read fires over the whole batch.** A read dependency is a
89
- premise for *all* the writes in the commit, so its disposition governs the batch:
91
+ **Boundary — a stale premise fires over the whole batch.** Each entry covers
92
+ *all* the writes in the commit, so its disposition governs the batch:
90
93
  `reject` aborts it, `notify` holds **every** write and notifies, `overwrite`
91
94
  lets them land. Per-entry `onStale` defaults to `reject`.
92
95
 
@@ -105,13 +108,13 @@ Shape (canonical in `coordination/schema.ts`):
105
108
 
106
109
  | field | meaning |
107
110
  |---|---|
108
- | `object` | Stripe-style type tag `'stale_notification'` |
111
+ | `object` | Stripe-style type tag: `'stale_notification'` |
109
112
  | `model`, `id` | the conflicting row (for a group dep, both are the group key) |
110
113
  | `group?` | set when this is a group-scoped notification |
111
114
  | `readAt` | the watermark the committer reasoned against |
112
- | `observedSyncId` | the newest delta on the premise re-read at/after this |
115
+ | `observedSyncId` | the newest delta on the premise: re-read at/after this |
113
116
  | `conflictingFields` | fields that moved (empty for group / whole-entity) |
114
- | `currentValues` | the live values of those fields the premise to reconcile against (empty for group) |
117
+ | `currentValues` | the live values of those fields: the premise to reconcile against (empty for group) |
115
118
  | `writtenBy` | `{ kind, id }` of the concurrent author, reported faithfully |
116
119
 
117
120
  Only `notify` produces a notification (the write was held). `reject` throws and
@@ -152,7 +155,7 @@ function reconcile(n: StaleNotification) {
152
155
 
153
156
  The loop **terminates** because each retry advances `readAt` to `observedSyncId`;
154
157
  a peer that keeps writing only ever notifies you against a *newer* baseline, never
155
- the same one twice. A group read-dep reconciles identically, except `group` is set
158
+ the same one twice. A group premise reconciles identically, except `group` is set
156
159
  and `currentValues` is empty (re-read the group).
157
160
 
158
161
  ---
@@ -166,7 +169,7 @@ What the convention **guarantees**, and where it **stops**:
166
169
  or human) owns the resolution. The engine does not distinguish them — it is
167
170
  actor-neutral by design.
168
171
 
169
- 2. **Truthfulness.** `currentValues` / `observedSyncId` reflect committed state at
172
+ 2. **Truthfulness:** `currentValues` / `observedSyncId` reflect committed state at
170
173
  detection time, inside the same transaction as the write. A notification is
171
174
  never speculative.
172
175
 
@@ -182,13 +185,11 @@ What the convention **guarantees**, and where it **stops**:
182
185
  so they must not be gated by `notify`.
183
186
 
184
187
  5. **Defaults.** A plain write (no `readAt`) is last-writer-wins with **no**
185
- check. A guarded write with `readAt` but no `onStale` defaults to `reject`
186
- (back-compat). *Open decision (§7).*
188
+ check. A guarded write with `readAt` but no `onStale` defaults to `reject`.
187
189
 
188
190
  6. **Policy seam.** Custom `ConflictPolicy` functions see **write-target**
189
- conflicts (`stale_context` / `claim_held`). **Read-set** conflicts are
190
- currently resolved directly via each entry's `onStale`, not through the policy
191
- seam. *Open decision (§7).*
191
+ conflicts (`stale_context` / `claim_held`). **Batch-premise** conflicts are
192
+ resolved directly via each entry's `onStale`, not through the policy seam.
192
193
 
193
194
  7. **Claims win when held.** A non-holder writing to a claimed row is rejected
194
195
  (`AbloClaimedError`) regardless of `readAt` — the prospective form takes
@@ -197,26 +198,17 @@ What the convention **guarantees**, and where it **stops**:
197
198
 
198
199
  ---
199
200
 
200
- ## 7. Open decisions (bounded, not yet made)
201
-
202
- These are deliberately left open; they change behavior and are the user's call.
203
-
204
- - **Default disposition for agents.** Should an agent-participant guarded write
205
- default to `notify` (philosophy-aligned: surface, don't overwrite) instead of
206
- `reject` (back-compat)? Trade-off: alignment vs. a behavior change for existing
207
- agent callers.
208
- - **Read-deps through the policy seam.** Should read-set conflicts also pass
209
- through `ConflictPolicy` (requires a group-aware conflict shape), or stay on
210
- the direct `onStale` mapping?
211
-
212
- ---
201
+ ## 7. What this convention does not cover
213
202
 
214
- ## 8. Out of scope
203
+ Three limits worth knowing before you rely on it.
215
204
 
216
- - Irreversible external side-effects (§6.4) not gated by this convention.
217
- - Cross-object *serializability proof*. The read-set is a sound premise check,
218
- not a full precedence-graph guarantee; it needs declared reads to catch a
219
- premise, and a caller that declares none gets only write-target checking.
220
- - Identity participant-kind mapping. `writtenBy.kind` reports whatever
221
- authenticated (an `sk_` key resolves to `system`, not `agent`); how identities
222
- map to kinds is a separate concern.
205
+ - **Irreversible external side-effects.** Emails, payments, and third-party
206
+ calls are not gated by this convention (§6.4). The engine cannot hold or undo
207
+ them, so never place one behind `notify`.
208
+ - **A caller that declares nothing gets no check.** The batch premise catches
209
+ only what you declared. Write-target checking needs a `readAt` to compare
210
+ against, so a plain write with neither is last-writer-wins (§6.5). What you
211
+ declare is what is protected.
212
+ - **`writtenBy.kind` reports what authenticated, not what you meant.** An `sk_`
213
+ key resolves to `system`, not `agent`. How identities map to participant kinds
214
+ is a separate concern from this convention.