@abloatai/ablo 0.25.0 → 0.27.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 (425) hide show
  1. package/AGENTS.md +5 -3
  2. package/CHANGELOG.md +34 -0
  3. package/README.md +104 -88
  4. package/dist/BaseSyncedStore.d.ts +140 -266
  5. package/dist/BaseSyncedStore.js +338 -739
  6. package/dist/Database.d.ts +62 -77
  7. package/dist/Database.js +106 -127
  8. package/dist/{ObjectPool.d.ts → InstanceCache.d.ts} +10 -13
  9. package/dist/{ObjectPool.js → InstanceCache.js} +91 -83
  10. package/dist/LazyReferenceCollection.d.ts +11 -15
  11. package/dist/LazyReferenceCollection.js +16 -15
  12. package/dist/Model.d.ts +37 -52
  13. package/dist/Model.js +52 -69
  14. package/dist/ModelRegistry.d.ts +46 -25
  15. package/dist/ModelRegistry.js +32 -30
  16. package/dist/NetworkMonitor.d.ts +5 -6
  17. package/dist/NetworkMonitor.js +6 -7
  18. package/dist/SyncClient.d.ts +119 -109
  19. package/dist/SyncClient.js +303 -224
  20. package/dist/SyncEngineContext.d.ts +1 -3
  21. package/dist/SyncEngineContext.js +1 -2
  22. package/dist/adapters/alwaysOnline.d.ts +6 -8
  23. package/dist/adapters/alwaysOnline.js +6 -8
  24. package/dist/adapters/inMemoryStorage.d.ts +9 -9
  25. package/dist/adapters/inMemoryStorage.js +9 -9
  26. package/dist/agent/Agent.d.ts +39 -31
  27. package/dist/agent/Agent.js +35 -23
  28. package/dist/agent/index.d.ts +4 -4
  29. package/dist/agent/index.js +5 -5
  30. package/dist/agent/session.d.ts +47 -44
  31. package/dist/agent/session.js +37 -48
  32. package/dist/agent/types.d.ts +26 -31
  33. package/dist/agent/types.js +6 -7
  34. package/dist/ai-sdk/coordinatedTool.d.ts +108 -0
  35. package/dist/ai-sdk/{coordinated-tool.js → coordinatedTool.js} +44 -38
  36. package/dist/ai-sdk/coordinationContext.d.ts +46 -0
  37. package/dist/ai-sdk/{coordination-context.js → coordinationContext.js} +30 -31
  38. package/dist/ai-sdk/index.d.ts +25 -22
  39. package/dist/ai-sdk/index.js +25 -22
  40. package/dist/ai-sdk/wrap.d.ts +7 -8
  41. package/dist/ai-sdk/wrap.js +2 -2
  42. package/dist/auth/credentialPolicy.d.ts +74 -71
  43. package/dist/auth/credentialPolicy.js +51 -56
  44. package/dist/auth/credentialSource.d.ts +7 -18
  45. package/dist/auth/credentialSource.js +10 -18
  46. package/dist/auth/index.d.ts +59 -58
  47. package/dist/auth/index.js +34 -40
  48. package/dist/auth/schemas.d.ts +5 -4
  49. package/dist/auth/schemas.js +5 -4
  50. package/dist/batching/index.d.ts +19 -21
  51. package/dist/batching/index.js +14 -17
  52. package/dist/cli.cjs +483 -369
  53. package/dist/client/Ablo.d.ts +107 -836
  54. package/dist/client/Ablo.js +174 -833
  55. package/dist/client/ApiClient.d.ts +44 -20
  56. package/dist/client/ApiClient.js +193 -44
  57. package/dist/client/auth.d.ts +51 -60
  58. package/dist/client/auth.js +137 -110
  59. package/dist/client/claimHeartbeatLoop.d.ts +50 -0
  60. package/dist/client/claimHeartbeatLoop.js +88 -0
  61. package/dist/client/consoleLogger.d.ts +35 -0
  62. package/dist/client/consoleLogger.js +44 -0
  63. package/dist/client/createInternalComponents.d.ts +14 -17
  64. package/dist/client/createInternalComponents.js +26 -31
  65. package/dist/client/createModelProxy.d.ts +130 -120
  66. package/dist/client/createModelProxy.js +158 -124
  67. package/dist/client/credentialEndpoint.d.ts +61 -0
  68. package/dist/client/credentialEndpoint.js +86 -0
  69. package/dist/client/functionalUpdate.d.ts +29 -27
  70. package/dist/client/functionalUpdate.js +21 -21
  71. package/dist/client/hostedEndpoints.d.ts +21 -0
  72. package/dist/client/hostedEndpoints.js +21 -0
  73. package/dist/client/httpClient.d.ts +58 -54
  74. package/dist/client/httpClient.js +29 -31
  75. package/dist/client/identity.d.ts +15 -20
  76. package/dist/client/identity.js +49 -59
  77. package/dist/client/modelRegistration.d.ts +10 -0
  78. package/dist/client/modelRegistration.js +301 -0
  79. package/dist/client/options.d.ts +373 -0
  80. package/dist/client/options.js +6 -0
  81. package/dist/client/registerDataSource.d.ts +9 -9
  82. package/dist/client/registerDataSource.js +15 -16
  83. package/dist/client/resourceTypes.d.ts +333 -0
  84. package/dist/client/resourceTypes.js +7 -0
  85. package/dist/client/schemaConfig.d.ts +44 -0
  86. package/dist/client/schemaConfig.js +176 -0
  87. package/dist/client/sessionMint.d.ts +17 -13
  88. package/dist/client/sessionMint.js +26 -31
  89. package/dist/client/validateAbloOptions.d.ts +12 -14
  90. package/dist/client/validateAbloOptions.js +9 -10
  91. package/dist/client/writeOptionsSchema.d.ts +18 -16
  92. package/dist/client/writeOptionsSchema.js +23 -20
  93. package/dist/client/wsMutationExecutor.d.ts +28 -0
  94. package/dist/client/wsMutationExecutor.js +71 -0
  95. package/dist/context.d.ts +6 -4
  96. package/dist/context.js +6 -7
  97. package/dist/coordination/index.d.ts +13 -4
  98. package/dist/coordination/index.js +29 -4
  99. package/dist/coordination/schema.d.ts +176 -128
  100. package/dist/coordination/schema.js +197 -133
  101. package/dist/coordination/trace.d.ts +9 -11
  102. package/dist/coordination/trace.js +13 -15
  103. package/dist/core/DatabaseManager.d.ts +5 -8
  104. package/dist/core/DatabaseManager.js +38 -40
  105. package/dist/core/QueryProcessor.d.ts +7 -9
  106. package/dist/core/QueryProcessor.js +27 -34
  107. package/dist/core/QueryView.d.ts +17 -5
  108. package/dist/core/QueryView.js +6 -7
  109. package/dist/core/StoreManager.d.ts +14 -16
  110. package/dist/core/StoreManager.js +26 -25
  111. package/dist/core/ViewRegistry.d.ts +5 -5
  112. package/dist/core/ViewRegistry.js +4 -4
  113. package/dist/core/index.d.ts +18 -13
  114. package/dist/core/index.js +32 -26
  115. package/dist/core/openIDBWithTimeout.d.ts +38 -36
  116. package/dist/core/openIDBWithTimeout.js +57 -54
  117. package/dist/core/queryUtils.d.ts +45 -0
  118. package/dist/core/queryUtils.js +69 -0
  119. package/dist/core/storeContract.d.ts +145 -0
  120. package/dist/core/storeContract.js +12 -0
  121. package/dist/environment.d.ts +28 -0
  122. package/dist/environment.js +21 -0
  123. package/dist/errorCodes.d.ts +118 -101
  124. package/dist/errorCodes.js +277 -260
  125. package/dist/errors.d.ts +170 -165
  126. package/dist/errors.js +161 -151
  127. package/dist/index.d.ts +30 -27
  128. package/dist/index.js +90 -82
  129. package/dist/interfaces/index.d.ts +108 -133
  130. package/dist/interfaces/index.js +5 -4
  131. package/dist/keys/index.d.ts +27 -29
  132. package/dist/keys/index.js +59 -49
  133. package/dist/mutators/RecordingTransaction.d.ts +16 -16
  134. package/dist/mutators/RecordingTransaction.js +31 -37
  135. package/dist/mutators/Transaction.d.ts +18 -26
  136. package/dist/mutators/Transaction.js +14 -20
  137. package/dist/mutators/UndoManager.d.ts +122 -131
  138. package/dist/mutators/UndoManager.js +149 -155
  139. package/dist/mutators/defineMutators.d.ts +24 -37
  140. package/dist/mutators/defineMutators.js +14 -20
  141. package/dist/mutators/inverseOp.d.ts +12 -15
  142. package/dist/mutators/inverseOp.js +12 -15
  143. package/dist/mutators/mutateActions.d.ts +10 -9
  144. package/dist/mutators/mutateActions.js +1 -1
  145. package/dist/mutators/readerActions.d.ts +9 -8
  146. package/dist/mutators/readerActions.js +2 -2
  147. package/dist/mutators/undoApply.d.ts +31 -27
  148. package/dist/mutators/undoApply.js +26 -24
  149. package/dist/policy/index.d.ts +5 -3
  150. package/dist/policy/index.js +5 -3
  151. package/dist/policy/types.d.ts +105 -101
  152. package/dist/policy/types.js +67 -66
  153. package/dist/query/client.d.ts +32 -16
  154. package/dist/query/client.js +103 -72
  155. package/dist/query/types.d.ts +37 -60
  156. package/dist/query/types.js +13 -33
  157. package/dist/react/AbloProvider.d.ts +7 -11
  158. package/dist/react/AbloProvider.js +24 -17
  159. package/dist/react/context.d.ts +27 -146
  160. package/dist/react/context.js +9 -10
  161. package/dist/react/index.d.ts +41 -42
  162. package/dist/react/index.js +37 -38
  163. package/dist/react/internalContext.d.ts +17 -19
  164. package/dist/react/useAblo.d.ts +23 -22
  165. package/dist/react/useAblo.js +17 -15
  166. package/dist/react/useCurrentUserId.d.ts +8 -7
  167. package/dist/react/useCurrentUserId.js +8 -7
  168. package/dist/react/useErrorListener.d.ts +7 -7
  169. package/dist/react/useErrorListener.js +11 -12
  170. package/dist/react/useMutationFailureListener.d.ts +8 -8
  171. package/dist/react/useMutationFailureListener.js +9 -9
  172. package/dist/react/useMutators.d.ts +11 -11
  173. package/dist/react/useMutators.js +10 -4
  174. package/dist/react/useReactive.js +2 -3
  175. package/dist/react/useSyncStatus.d.ts +4 -6
  176. package/dist/react/useUndoScope.d.ts +7 -9
  177. package/dist/react/useUndoScope.js +3 -3
  178. package/dist/schema/coordination.d.ts +21 -25
  179. package/dist/schema/coordination.js +21 -25
  180. package/dist/schema/ddl.d.ts +43 -39
  181. package/dist/schema/ddl.js +75 -68
  182. package/dist/schema/ddlLock.d.ts +35 -0
  183. package/dist/schema/ddlLock.js +46 -0
  184. package/dist/schema/diff.d.ts +99 -61
  185. package/dist/schema/diff.js +43 -34
  186. package/dist/schema/field.d.ts +37 -42
  187. package/dist/schema/field.js +36 -49
  188. package/dist/schema/generate.d.ts +12 -12
  189. package/dist/schema/generate.js +12 -12
  190. package/dist/schema/index.d.ts +5 -4
  191. package/dist/schema/index.js +29 -21
  192. package/dist/schema/model.d.ts +121 -146
  193. package/dist/schema/model.js +24 -35
  194. package/dist/schema/openapi.d.ts +10 -9
  195. package/dist/schema/openapi.js +7 -1
  196. package/dist/schema/queries.d.ts +30 -32
  197. package/dist/schema/queries.js +24 -25
  198. package/dist/schema/relation.d.ts +89 -99
  199. package/dist/schema/relation.js +13 -13
  200. package/dist/schema/residency.d.ts +38 -0
  201. package/dist/schema/residency.js +30 -0
  202. package/dist/schema/roles.d.ts +45 -27
  203. package/dist/schema/roles.js +52 -21
  204. package/dist/schema/schema.d.ts +36 -45
  205. package/dist/schema/schema.js +42 -39
  206. package/dist/schema/select.d.ts +13 -13
  207. package/dist/schema/select.js +13 -13
  208. package/dist/schema/serialize.d.ts +36 -39
  209. package/dist/schema/serialize.js +27 -31
  210. package/dist/schema/sugar.d.ts +17 -32
  211. package/dist/schema/sugar.js +14 -29
  212. package/dist/schema/{sync-delta-row.d.ts → syncDeltaRow.d.ts} +27 -50
  213. package/dist/schema/syncDeltaRow.js +89 -0
  214. package/dist/schema/tenancy.d.ts +44 -46
  215. package/dist/schema/tenancy.js +46 -48
  216. package/dist/server/adapter.d.ts +58 -58
  217. package/dist/server/adapter.js +13 -14
  218. package/dist/server/commit.d.ts +60 -64
  219. package/dist/server/index.d.ts +9 -10
  220. package/dist/server/index.js +1 -1
  221. package/dist/server/readConfig.d.ts +70 -0
  222. package/dist/server/readConfig.js +8 -0
  223. package/dist/server/storageMode.d.ts +23 -0
  224. package/dist/server/storageMode.js +17 -0
  225. package/dist/source/adapter.d.ts +31 -26
  226. package/dist/source/adapter.js +10 -10
  227. package/dist/source/adapters/drizzle.d.ts +28 -23
  228. package/dist/source/adapters/drizzle.js +34 -28
  229. package/dist/source/adapters/kysely.d.ts +27 -25
  230. package/dist/source/adapters/kysely.js +28 -26
  231. package/dist/source/adapters/memory.d.ts +8 -7
  232. package/dist/source/adapters/memory.js +10 -9
  233. package/dist/source/adapters/prisma.d.ts +13 -12
  234. package/dist/source/adapters/prisma.js +27 -29
  235. package/dist/source/conformance.d.ts +18 -11
  236. package/dist/source/conformance.js +27 -19
  237. package/dist/source/connector.d.ts +31 -32
  238. package/dist/source/connector.js +30 -28
  239. package/dist/source/connectorProtocol.d.ts +160 -0
  240. package/dist/source/connectorProtocol.js +162 -0
  241. package/dist/source/contract.d.ts +26 -27
  242. package/dist/source/contract.js +28 -29
  243. package/dist/source/factory.d.ts +94 -0
  244. package/dist/source/factory.js +268 -0
  245. package/dist/source/index.d.ts +10 -462
  246. package/dist/source/index.js +17 -421
  247. package/dist/source/migrations.d.ts +9 -9
  248. package/dist/source/migrations.js +9 -9
  249. package/dist/source/next.d.ts +10 -11
  250. package/dist/source/next.js +7 -8
  251. package/dist/source/pushQueue.d.ts +70 -48
  252. package/dist/source/pushQueue.js +36 -29
  253. package/dist/source/signing.d.ts +88 -0
  254. package/dist/source/signing.js +159 -0
  255. package/dist/source/types.d.ts +351 -0
  256. package/dist/source/types.js +43 -0
  257. package/dist/stores/ObjectStore.d.ts +11 -12
  258. package/dist/stores/ObjectStore.js +34 -35
  259. package/dist/stores/ObjectStoreContract.d.ts +12 -15
  260. package/dist/stores/SyncActionStore.d.ts +8 -12
  261. package/dist/stores/SyncActionStore.js +77 -46
  262. package/dist/surface.d.ts +28 -21
  263. package/dist/surface.js +28 -20
  264. package/dist/sync/{BootstrapHelper.d.ts → BootstrapFetcher.d.ts} +37 -45
  265. package/dist/sync/{BootstrapHelper.js → BootstrapFetcher.js} +101 -80
  266. package/dist/sync/ConnectionManager.d.ts +47 -50
  267. package/dist/sync/ConnectionManager.js +74 -70
  268. package/dist/sync/NetworkProbe.d.ts +27 -31
  269. package/dist/sync/NetworkProbe.js +67 -72
  270. package/dist/sync/{HydrationCoordinator.d.ts → OnDemandLoader.d.ts} +49 -36
  271. package/dist/sync/{HydrationCoordinator.js → OnDemandLoader.js} +79 -54
  272. package/dist/sync/{AreaOfInterestManager.d.ts → SubscriptionManager.d.ts} +45 -59
  273. package/dist/sync/{AreaOfInterestManager.js → SubscriptionManager.js} +44 -52
  274. package/dist/sync/SyncWebSocket.d.ts +175 -250
  275. package/dist/sync/SyncWebSocket.js +431 -769
  276. package/dist/sync/awaitClaimGrant.d.ts +18 -18
  277. package/dist/sync/awaitClaimGrant.js +38 -30
  278. package/dist/sync/bootstrapApply.d.ts +70 -0
  279. package/dist/sync/bootstrapApply.js +73 -0
  280. package/dist/sync/commitFrames.d.ts +44 -0
  281. package/dist/sync/commitFrames.js +94 -0
  282. package/dist/sync/createClaimStream.d.ts +23 -22
  283. package/dist/sync/createClaimStream.js +108 -25
  284. package/dist/sync/createPresenceStream.d.ts +19 -18
  285. package/dist/sync/createPresenceStream.js +25 -26
  286. package/dist/sync/createSnapshot.d.ts +13 -17
  287. package/dist/sync/createSnapshot.js +20 -26
  288. package/dist/sync/credentialLifecycle.d.ts +175 -0
  289. package/dist/sync/credentialLifecycle.js +322 -0
  290. package/dist/sync/deltaPipeline.d.ts +113 -0
  291. package/dist/sync/deltaPipeline.js +261 -0
  292. package/dist/sync/groupChange.d.ts +113 -0
  293. package/dist/sync/groupChange.js +242 -0
  294. package/dist/sync/heartbeat.d.ts +63 -0
  295. package/dist/sync/heartbeat.js +91 -0
  296. package/dist/sync/participants.d.ts +27 -27
  297. package/dist/sync/schemas.d.ts +3 -2
  298. package/dist/sync/schemas.js +14 -10
  299. package/dist/sync/syncCursor.d.ts +40 -0
  300. package/dist/sync/syncCursor.js +55 -0
  301. package/dist/sync/syncPlan.d.ts +54 -0
  302. package/dist/sync/syncPlan.js +50 -0
  303. package/dist/sync/syncPosition.d.ts +54 -49
  304. package/dist/sync/syncPosition.js +57 -52
  305. package/dist/sync/wsFrameHandlers.d.ts +116 -0
  306. package/dist/sync/wsFrameHandlers.js +374 -0
  307. package/dist/testing/fixtures/bootstrap.d.ts +21 -17
  308. package/dist/testing/fixtures/bootstrap.js +12 -6
  309. package/dist/testing/fixtures/deltas.d.ts +31 -34
  310. package/dist/testing/fixtures/deltas.js +30 -33
  311. package/dist/testing/fixtures/models.d.ts +11 -10
  312. package/dist/testing/fixtures/models.js +12 -10
  313. package/dist/testing/helpers/{react-wrapper.d.ts → reactWrapper.d.ts} +13 -10
  314. package/dist/testing/helpers/{react-wrapper.js → reactWrapper.js} +15 -12
  315. package/dist/testing/helpers/{sync-engine-harness.d.ts → syncEngineHarness.d.ts} +17 -18
  316. package/dist/testing/helpers/{sync-engine-harness.js → syncEngineHarness.js} +14 -11
  317. package/dist/testing/helpers/wait.d.ts +13 -8
  318. package/dist/testing/helpers/wait.js +13 -8
  319. package/dist/testing/index.d.ts +4 -4
  320. package/dist/testing/index.js +3 -3
  321. package/dist/testing/mocks/MockMutationExecutor.d.ts +18 -17
  322. package/dist/testing/mocks/MockMutationExecutor.js +15 -14
  323. package/dist/testing/mocks/MockNetworkMonitor.d.ts +8 -8
  324. package/dist/testing/mocks/MockNetworkMonitor.js +8 -8
  325. package/dist/testing/mocks/MockSyncContext.d.ts +21 -34
  326. package/dist/testing/mocks/MockSyncContext.js +16 -45
  327. package/dist/testing/mocks/MockSyncStore.d.ts +14 -14
  328. package/dist/testing/mocks/MockSyncStore.js +11 -11
  329. package/dist/testing/mocks/MockWebSocket.d.ts +28 -24
  330. package/dist/testing/mocks/MockWebSocket.js +22 -21
  331. package/dist/transactions/TransactionQueue.d.ts +190 -221
  332. package/dist/transactions/TransactionQueue.js +424 -822
  333. package/dist/transactions/TransactionStore.d.ts +20 -0
  334. package/dist/transactions/TransactionStore.js +53 -0
  335. package/dist/transactions/UnconfirmedWrites.d.ts +82 -0
  336. package/dist/transactions/UnconfirmedWrites.js +104 -0
  337. package/dist/transactions/coalesceRules.d.ts +58 -0
  338. package/dist/transactions/coalesceRules.js +140 -0
  339. package/dist/transactions/commitPayload.d.ts +130 -0
  340. package/dist/transactions/commitPayload.js +143 -0
  341. package/dist/transactions/deltaConfirmation.d.ts +58 -0
  342. package/dist/transactions/deltaConfirmation.js +215 -0
  343. package/dist/transactions/optimisticApply.d.ts +49 -0
  344. package/dist/transactions/optimisticApply.js +65 -0
  345. package/dist/transactions/replayValidation.d.ts +99 -0
  346. package/dist/transactions/replayValidation.js +111 -0
  347. package/dist/types/global.d.ts +46 -41
  348. package/dist/types/global.js +20 -19
  349. package/dist/types/index.d.ts +74 -80
  350. package/dist/types/index.js +22 -27
  351. package/dist/types/modelData.d.ts +10 -0
  352. package/dist/types/modelData.js +9 -0
  353. package/dist/types/participant.d.ts +20 -0
  354. package/dist/types/participant.js +10 -0
  355. package/dist/types/streams.d.ts +216 -209
  356. package/dist/types/streams.js +7 -7
  357. package/dist/utils/asyncIterator.d.ts +25 -32
  358. package/dist/utils/asyncIterator.js +25 -32
  359. package/dist/utils/duration.d.ts +12 -15
  360. package/dist/utils/duration.js +12 -15
  361. package/dist/utils/mobxSetup.d.ts +53 -0
  362. package/dist/utils/{mobx-setup.js → mobxSetup.js} +44 -100
  363. package/dist/webhooks/events.d.ts +21 -16
  364. package/dist/webhooks/events.js +10 -8
  365. package/dist/webhooks/index.d.ts +5 -7
  366. package/dist/webhooks/index.js +5 -7
  367. package/dist/{schema/sync-delta-wire.d.ts → wire/delta.d.ts} +58 -41
  368. package/dist/wire/delta.js +114 -0
  369. package/dist/wire/errorEnvelope.d.ts +35 -27
  370. package/dist/wire/errorEnvelope.js +38 -32
  371. package/dist/wire/frames.d.ts +150 -67
  372. package/dist/wire/frames.js +48 -1
  373. package/dist/wire/index.d.ts +18 -13
  374. package/dist/wire/index.js +36 -13
  375. package/dist/wire/listEnvelope.d.ts +16 -23
  376. package/dist/wire/listEnvelope.js +7 -6
  377. package/dist/wire/protocol.d.ts +38 -0
  378. package/dist/wire/protocol.js +38 -0
  379. package/dist/wire/protocolVersion.d.ts +60 -0
  380. package/dist/wire/protocolVersion.js +67 -0
  381. package/docs/api-keys.md +4 -3
  382. package/docs/coordination.md +59 -0
  383. package/docs/examples/existing-python-backend.md +3 -3
  384. package/docs/identity.md +4 -4
  385. package/docs/integration-guide.md +1 -1
  386. package/docs/react.md +1 -1
  387. package/docs/sessions.md +5 -7
  388. package/package.json +24 -21
  389. package/dist/ai-sdk/coordinated-tool.d.ts +0 -101
  390. package/dist/ai-sdk/coordination-context.d.ts +0 -52
  391. package/dist/client/index.d.ts +0 -36
  392. package/dist/client/index.js +0 -33
  393. package/dist/config/index.d.ts +0 -10
  394. package/dist/config/index.js +0 -12
  395. package/dist/core/query-utils.d.ts +0 -34
  396. package/dist/core/query-utils.js +0 -59
  397. package/dist/interfaces/headless.d.ts +0 -95
  398. package/dist/interfaces/headless.js +0 -41
  399. package/dist/query/index.d.ts +0 -6
  400. package/dist/query/index.js +0 -5
  401. package/dist/realtime/index.d.ts +0 -10
  402. package/dist/realtime/index.js +0 -9
  403. package/dist/schema/plane.d.ts +0 -23
  404. package/dist/schema/plane.js +0 -19
  405. package/dist/schema/sync-delta-row.js +0 -103
  406. package/dist/schema/sync-delta-wire.js +0 -102
  407. package/dist/server/next.d.ts +0 -51
  408. package/dist/server/next.js +0 -47
  409. package/dist/server/read-config.d.ts +0 -67
  410. package/dist/server/read-config.js +0 -8
  411. package/dist/server/storage-mode.d.ts +0 -1
  412. package/dist/server/storage-mode.js +0 -18
  413. package/dist/source/connector-protocol.d.ts +0 -159
  414. package/dist/source/connector-protocol.js +0 -161
  415. package/dist/sync/OfflineFlush.d.ts +0 -9
  416. package/dist/sync/OfflineFlush.js +0 -22
  417. package/dist/sync/OfflineTransactionStore.d.ts +0 -37
  418. package/dist/sync/OfflineTransactionStore.js +0 -263
  419. package/dist/transactions/OptimisticEchoTracker.d.ts +0 -82
  420. package/dist/transactions/OptimisticEchoTracker.js +0 -104
  421. package/dist/transactions/index.d.ts +0 -16
  422. package/dist/transactions/index.js +0 -7
  423. package/dist/transactions/mutation-error-handler.d.ts +0 -5
  424. package/dist/transactions/mutation-error-handler.js +0 -39
  425. package/dist/utils/mobx-setup.d.ts +0 -42
package/AGENTS.md CHANGED
@@ -6,16 +6,18 @@ Claims don't lock. If another writer holds the row, `claim` waits for them and r
6
6
 
7
7
  ## Start here — scaffold with `ablo init`
8
8
 
9
- Don't hand-write the integration. Run the CLI; it generates the current-API schema, client, Data Source endpoint, and (for Next.js) the browser provider + session route:
9
+ Don't hand-write the integration. Run the CLI; it generates the current-API schema, client, the database connection (logical replication by default, or a signed Data Source endpoint as the fallback), and (for Next.js) the browser provider + session route:
10
10
 
11
11
  - **Scaffold:** `npx ablo init --yes` — flag-driven, never prompts. Override defaults with `--framework <nextjs|vite|remix|vanilla>`, `--auth <apikey|…>`, `--no-agent`, `--no-pull`, `--no-install`, `--no-login`. (Plain `ablo init` needs a TTY and will **HANG** in an agent/CI run — always pass `--yes`.)
12
12
  - **Auth:** set `ABLO_API_KEY` in the environment. Do **NOT** run `ablo login` — it opens a browser device flow and blocks an agent.
13
- - **Provision your DB (Data Source mode):** `npx ablo migrate` creates the tables for your Ablo models plus the adapter's bookkeeping tables (`ablo_outbox`, `ablo_idempotency`). It does **not** touch your other tableskeep your own migrations (drizzle-kit / prisma migrate) for auth and anything not in the Ablo schema.
13
+ - **Connect your database — logical replication (the primary path):** `npx ablo connect` prints the setup SQL (`wal_level=logical`, a publication, a `REPLICATION` role); `npx ablo connect --register` registers the source with Ablo in one step. Ablo **consumes your Postgres' logical-replication stream** it never runs DDL on, writes to, owns, or migrates your database, and your application keeps the write path. Registration **is** the enable; there is no tier or flag to pick. (Ablo hosts only the transaction log + coordination, never your rows.)
14
+ - **Fallback — signed Data Source endpoint** (DB can't grant a `REPLICATION` role): the generated `ablo/data-source.ts` exposes one route; Ablo sends signed requests and your app touches its own DB. **Only in this mode** does `npx ablo migrate` provision the adapter's bookkeeping tables (`ablo_outbox`, `ablo_idempotency`) plus your Ablo models — it does **not** touch your other tables. Keep your own migrations (drizzle-kit / prisma migrate) for auth and anything outside the Ablo schema.
15
+ - **No database yet?** A sandbox `sk_test` key holds throwaway **test data** (Stripe-test-mode style) so you can try Ablo before connecting your own Postgres. Test-mode only — in production every row lives in your database.
14
16
  - **Adopt an existing DB schema:** `npx ablo pull prisma [path]` / `pull drizzle <module>` (lossless) or `pull` (live DB, lossy). Writes `ablo/schema.ts`.
15
17
  - **Push your schema — REQUIRED before any write works.** The server keeps its OWN copy of the schema. After you create or edit `ablo/schema.ts`, run `npx ablo push` (one-shot) — or `npx ablo dev --no-watch`. **Skip this and every write to a new or changed model fails with `server_execute_unknown_model`.** (Plain `ablo dev` watches forever — never run it bare in an agent.)
16
18
  - **Other long-running:** `npx ablo logs --no-follow` (default tails forever). `npx ablo mode test|live` ALWAYS pass the argument. `status`, `push`, `pull`, `check`, `generate` are one-shot — safe as-is.
17
19
 
18
- The generated `ablo/data-source.ts` is the whole Data Source endpoint and needs no hand-editing: `dataSourceNext({ schema, apiKey, adapter: prismaDataSource(prisma, schema) })` (or `drizzleDataSource(db, schema)`). The adapter owns commit / idempotency / outbox.
20
+ When you use the signed-endpoint fallback, the generated `ablo/data-source.ts` is the whole endpoint and needs no hand-editing: `dataSourceNext({ schema, apiKey, adapter: prismaDataSource(prisma, schema) })` (or `drizzleDataSource(db, schema)`). The adapter owns commit / idempotency / outbox.
19
21
 
20
22
  ## Rule
21
23
 
package/CHANGELOG.md CHANGED
@@ -1,5 +1,39 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.27.0
4
+
5
+ ### Minor Changes
6
+
7
+ - **Claims can now be held for long-running work by heartbeating — on both transports.** A claim's TTL is crash cleanup, not a work estimate; work that outlives it (a 30-minute report, a long agent run) keeps its lease by beating. `claim({ heartbeat: true })` beats automatically until release; `held.heartbeat()` beats by hand. A lapsed lease answers the next beat with `AbloClaimedError` (`claim_lost`) — for a socketless worker, the failed beat _is_ the loss notification, and any write attempted under the old lease is independently rejected by its `readAt` guard.
8
+
9
+ - **Beats carry progress and pressure.** `heartbeat({ details })` stores lightweight progress as the claim's peer-visible `meta.progress` (last beat wins, via `claim.state`); every beat's answer reports `queueDepth` — how many participants wait in line behind the lease — observable per auto-beat with the new `onHeartbeat` claim option.
10
+
11
+ - **`ablo.claims.heartbeatAll({ ttl })`** extends every lease the credential holds in one request (`POST /v1/claims/heartbeat`) — the stateless twin of the WebSocket keepalive, for workers holding many rows.
12
+
13
+ - **Keepalive renewals extend but never shorten a lease**, so an explicit work-duration `ttl` now survives pings and brief reconnects instead of collapsing to the liveness window.
14
+
15
+ - **README.** The quick start leads with a runnable example, and a new _Background workers_ section shows the enqueue-on-your-own-queue / heartbeat-the-claim pattern end to end.
16
+
17
+ ## 0.26.0
18
+
19
+ ### Minor Changes
20
+
21
+ - **`ablo connect --register` works against any deployment.** Registering your database as an Ablo data source over logical replication is now a first-class path everywhere — the gate that could refuse a new connection-string registration is gone. Point `ablo connect --register` at your Postgres and Ablo begins consuming its replication stream while your application keeps owning the write path; registering the source _is_ the enable, with no tier or flag to choose. The signed `dataSource()` endpoint remains the explicit fallback for databases that can't grant replication.
22
+
23
+ - **More engine failures surface as typed errors you can branch on**, instead of opaque `500`s. New `AbloError` codes: `schema_provisioning_forbidden` (`403` — a push tried to create tables in a database where the engine isn't permitted to run DDL), `request_too_large` (`413` — a query or commit body exceeded the size limit), `commit_operation_invalid` (`400` — a malformed commit operation), and `upload_not_configured` (`503` — an upload was attempted with no blob store wired).
24
+
25
+ - **`@abloatai/ablo/wire` now exports the protocol schemas.** `commitOperationSchema`, `commitPayloadSchema`, and the frame schemas let tooling and tests validate client↔engine frames against the same contract the engine enforces.
26
+
27
+ - **Protocol version negotiation is surfaced.** `@abloatai/ablo/wire` exports `PROTOCOL_VERSION`, `MIN_SUPPORTED_PROTOCOL_VERSION`, `WS_CLOSE_PROTOCOL_VERSION`, `PROTOCOL_VERSION_HEADER`, `protocolVersionProblem`, and `ERROR_CONTRACT_VERSION` — the single integer the client and server compare on connect to detect an incompatible peer and fail with a clear reason instead of a cryptic wire error.
28
+
29
+ - **`@abloatai/ablo/coordination` exposes the conflict-policy vocabulary** — `defaultPolicy`, `capabilityPreemptPolicy`, and `interpretConflictAxis` — for server-side consumers building on the claim model. `@abloatai/ablo/schema` gains the role primitives (`identityRole`, `entityRole`, and their types and schemas) for declaring identity- and entity-scoped roles.
30
+
31
+ - **Removed unused API surface.** Dropped the `@abloatai/ablo/server/next` subpath export and the unused `MutationDispatcher` interface (plus its `MockMutationDispatcher` test double) and the offline-mutation-queue internals behind them — none had documented consumers. Every supported entry point (`@abloatai/ablo`, `/ai-sdk`, `/react`, `/source`, `/coordination`, `/schema`, `/keys`, `/auth`, `/wire`, …) is unchanged.
32
+
33
+ - **Internal:** the SDK's largest modules — the `Ablo` client, the data-source runtime, the transaction queue, and the WebSocket sync loop — were decomposed into cohesive leaf modules. No public runtime API or import path changed.
34
+
35
+ - **CLI & docs.** `ablo push` prints a calmer, information-first deploy banner (a production push still requires typing the project name to confirm). The README and `AGENTS.md` now lead with the one-path logical-replication model and clarify that sandbox is test-mode only — in production your rows stay in your database and Ablo holds only the transaction log.
36
+
3
37
  ## 0.25.0
4
38
 
5
39
  ### Minor Changes
package/README.md CHANGED
@@ -39,10 +39,10 @@ Under the hood, you define your data once with a Zod schema and get the same
39
39
  typed model client for every actor — people, server actions, and agents:
40
40
 
41
41
  ```ts
42
- await ablo.task.create({ data }) // create
43
- await ablo.task.retrieve({ id }) // read
44
- await ablo.task.update({ id, data }) // update
45
- await using task = await ablo.task.claim({ id }) // claim for safe, slow agent work
42
+ await ablo.weatherReports.create({ data }) // create
43
+ await ablo.weatherReports.retrieve({ id }) // read
44
+ await ablo.weatherReports.update({ id, data }) // update
45
+ await using claim = await ablo.weatherReports.claim({ id }) // hold for slow agent work
46
46
  ```
47
47
 
48
48
  The schema is the public contract. It gives you typed model methods, realtime
@@ -63,8 +63,9 @@ yet? A **sandbox** `sk_test` key holds throwaway **test data** — like Stripe t
63
63
  mode — so you can explore before pointing it at your Postgres. Test-mode only; in
64
64
  production every row lives in your database.)
65
65
 
66
- **Built for** collaborative editors, AI agent workflows, and internal tools —
67
- anywhere people and agents change shared state and everyone has to see it live.
66
+ **Built for** collaborative editors, AI agent workflows, background workers on
67
+ your own infrastructure, and internal tools anywhere people and agents change
68
+ shared state and everyone has to see it live.
68
69
 
69
70
  ## Set up
70
71
 
@@ -111,62 +112,15 @@ instead of guessing:
111
112
 
112
113
  ## Quick Start
113
114
 
115
+ One schema, one client, one write path for humans and agents — this runs as-is
116
+ after `ablo push`:
117
+
114
118
  ```ts
115
119
  import Ablo from '@abloatai/ablo';
116
120
  import { defineSchema, model, z } from '@abloatai/ablo/schema';
117
- ```
118
-
119
- The schema is registered once (init scaffolds `ablo/register.ts` for you), and
120
- every type is one parameter away — no `typeof schema` re-stating, anywhere:
121
-
122
- ```ts
123
- // ablo/register.ts — scaffolded by `npx ablo init`, sits beside ablo/schema.ts
124
- import type { schema } from './schema';
125
- declare module '@abloatai/ablo' {
126
- interface Register { Schema: typeof schema }
127
- }
128
- export {};
129
- ```
130
-
131
- It's a regular `.ts` module, not a hand-authored `.d.ts`. The top-level
132
- `import type { schema }` makes the `declare module` block *merge* into (augment)
133
- the SDK's `Register` interface instead of colliding with it — the same shape
134
- [TanStack Router uses in `src/router.tsx`](https://tanstack.com/router/latest/docs/framework/react/guide/type-safety). Any `.ts` file in your
135
- `tsconfig` `include` works; it never needs to be imported.
136
-
137
- ```ts
138
- import type { Model } from '@abloatai/ablo/schema';
139
-
140
- type WeatherReport = Model<'weatherReports'>; // fully typed from YOUR schema
141
- ```
142
-
143
- (The same `Register` binding types every hook and client — it's the
144
- TanStack-Router pattern: declare the source of truth once, everything
145
- infers from it.)
146
121
 
147
- ### Naming the client type
148
-
149
- When you need to pass the client around (a function parameter, a context value),
150
- **infer the type from the value** — `type Sync = typeof sync`:
151
-
152
- ```ts
153
- export const sync = Ablo({ schema, apiKey: process.env.ABLO_API_KEY });
154
- export type Sync = typeof sync; // fully-typed, schema-aware
155
-
156
- function persist(client: Sync) { /* ... */ }
157
- ```
158
-
159
- This is the same idiom as tRPC's `type AppRouter = typeof appRouter` and
160
- Drizzle's `typeof db` — the factory resolves the typed overload at the call
161
- site, so `typeof sync` carries your schema. Do **not** write
162
- `ReturnType<typeof Ablo>`: that collapses to the untyped last overload and
163
- loses your model types. There is no bespoke client-type generic to import —
164
- `typeof` your client value is the type.
165
-
166
- ```ts
167
122
  const schema = defineSchema({
168
- // Reserved fields (id, createdAt, updatedAt, organizationId, createdBy) are
169
- // provided automatically — don't declare them.
123
+ // id, createdAt, updatedAt, organizationId, createdBy come free on every model
170
124
  weatherReports: model({
171
125
  location: z.string(),
172
126
  status: z.enum(['pending', 'ready']),
@@ -174,29 +128,21 @@ const schema = defineSchema({
174
128
  }),
175
129
  });
176
130
 
177
- const ablo = Ablo({
178
- schema,
179
- apiKey: process.env.ABLO_API_KEY, // written to .env.local by `npx ablo push`
180
- });
181
- // Your Postgres is connected once via `npx ablo connect` (logical replication) —
182
- // not passed here. Ablo tails its WAL; your rows never leave your database.
183
-
131
+ const ablo = Ablo({ schema, apiKey: process.env.ABLO_API_KEY });
184
132
  await ablo.ready();
185
133
 
186
134
  const created = await ablo.weatherReports.create({
187
- data: {
188
- location: 'Stockholm',
189
- status: 'pending',
190
- },
135
+ data: { location: 'Stockholm', status: 'pending' },
191
136
  });
192
137
 
193
- // An agent claims the row, does its slow work, then writes back. While the
194
- // claim is held nobody else can overwrite it; anyone else who tries waits in
195
- // line and re-reads the result. This is the whole point of Ablo.
138
+ // Claim the row before slow work — anyone else waits in line, then re-reads.
196
139
  await using claim = await ablo.weatherReports.claim({ id: created.id });
197
- const report = claim.data;
198
- const forecast = await fetchForecast(report.location); // slow: API or LLM call
199
- await ablo.weatherReports.update({ id: report.id, data: { status: 'ready', forecast } });
140
+ const forecast = await fetchForecast(claim.data.location); // slow: API or LLM call
141
+ await ablo.weatherReports.update({
142
+ id: created.id,
143
+ data: { status: 'ready', forecast },
144
+ claim, // the write completes the claimed work and releases the lease
145
+ });
200
146
 
201
147
  const ready = ablo.weatherReports.get(created.id);
202
148
  console.log({ id: ready?.id, status: ready?.status });
@@ -210,6 +156,38 @@ Expected output:
210
156
  { id: '...', status: 'ready' }
211
157
  ```
212
158
 
159
+ ### TypeScript setup (once, scaffolded for you)
160
+
161
+ `npx ablo init` writes `ablo/register.ts` next to your schema. It binds your
162
+ schema to the SDK's types once — the same declaration-merging shape
163
+ [TanStack Router uses](https://tanstack.com/router/latest/docs/framework/react/guide/type-safety) —
164
+ so every hook and client infers from it:
165
+
166
+ ```ts
167
+ // ablo/register.ts — scaffolded by `npx ablo init`
168
+ import type { schema } from './schema';
169
+ declare module '@abloatai/ablo' {
170
+ interface Register { Schema: typeof schema }
171
+ }
172
+ export {};
173
+ ```
174
+
175
+ ```ts
176
+ import type { Model } from '@abloatai/ablo/schema';
177
+
178
+ type WeatherReport = Model<'weatherReports'>; // fully typed from your schema
179
+ ```
180
+
181
+ To pass the client around, take the type from the value — the tRPC /
182
+ Drizzle idiom:
183
+
184
+ ```ts
185
+ export const sync = Ablo({ schema, apiKey: process.env.ABLO_API_KEY });
186
+ export type Sync = typeof sync;
187
+
188
+ function persist(client: Sync) { /* ... */ }
189
+ ```
190
+
213
191
  ## Reading
214
192
 
215
193
  Two ways to read, depending on whether you can wait. `get(id)` / `getAll({ where })`
@@ -262,7 +240,11 @@ meanwhile, or worse, acts on stale state. `claim` holds the row across that gap:
262
240
  await using claim = await ablo.weatherReports.claim({ id: 'report_stockholm' });
263
241
  const report = claim.data;
264
242
  const forecast = await weatherAgent.getWeather(report.location);
265
- await ablo.weatherReports.update({ id: report.id, data: { forecast, status: 'ready' } });
243
+ await ablo.weatherReports.update({
244
+ id: report.id,
245
+ data: { forecast, status: 'ready' },
246
+ claim, // attribute the write to the held claim
247
+ });
266
248
  ```
267
249
 
268
250
  If someone else holds the row, `claim()` waits in a fair queue, then re-reads —
@@ -311,6 +293,46 @@ try {
311
293
  See [Coordination](./docs/coordination.md) for the full `claim` / `claim.state` /
312
294
  `claim.queue` / `claim.release` reference.
313
295
 
296
+ ## Background workers — jobs that run for minutes, not seconds
297
+
298
+ Your API route enqueues a job on your own queue (SQS, EventBridge, anything);
299
+ a worker on your own infrastructure does the slow part. **Keep that queue —
300
+ Ablo is the worker's data layer.** It covers the two things every queue leaves
301
+ to you: keeping the row safe, and showing progress live.
302
+
303
+ Long work holds its claim by **heartbeating** — the same pattern as an SQS
304
+ visibility heartbeat or a Temporal activity heartbeat:
305
+
306
+ ```ts
307
+ // on your worker — stateless HTTP, no socket to hold
308
+ await using claim = await ablo.weatherReports.claim({
309
+ id: msg.reportId,
310
+ ttl: '10m',
311
+ heartbeat: true, // beats automatically until release
312
+ onHeartbeatLost: () => abort(), // the lease is gone → stop working
313
+ });
314
+
315
+ for (const step of steps) {
316
+ await runStep(step);
317
+ // write progress to the row — every subscribed UI updates live
318
+ await ablo.weatherReports.update({ id: msg.reportId, data: { progress: step.pct }, claim });
319
+ }
320
+ ```
321
+
322
+ - A worker that **crashes** stops beating; the row frees within one beat and
323
+ the next worker takes over.
324
+ - A worker that **wakes up late** learns it on its next beat
325
+ (`AbloClaimedError`), and the write path rejects its stale writes anyway.
326
+ - **Retries stay on your queue** — the redelivered job claims the now-free
327
+ row, reads its current state, and resumes.
328
+ - A worker holding **many rows** extends them all in one call:
329
+ `ablo.claims.heartbeatAll({ ttl: '5m' })`.
330
+
331
+ SQS's heartbeat protects the *message* from redelivery; Ablo's protects the
332
+ *row* from concurrent and stale writes. SQS is at-least-once, so two workers
333
+ will eventually get the same job — the claim is what keeps that from
334
+ corrupting data.
335
+
314
336
  ## React
315
337
 
316
338
  In a React app it's the **same `ablo.<model>` API** — just mounted through a
@@ -322,10 +344,10 @@ import Ablo from '@abloatai/ablo';
322
344
  import { AbloProvider, useAblo } from '@abloatai/ablo/react';
323
345
  import { schema } from './ablo/schema';
324
346
 
325
- // Build the client once — it authenticates via your session route, no key in the browser.
347
+ // Build the client once — authEndpoint is your session route; no key in the browser.
326
348
  const ablo = Ablo({
327
349
  schema,
328
- apiKey: () => fetch('/api/ablo-session').then((r) => r.text()),
350
+ authEndpoint: '/api/ablo-session',
329
351
  });
330
352
 
331
353
  function App() {
@@ -381,7 +403,7 @@ to sync-group strings.
381
403
  // team membership is asserted server-side when the session route mints the token.
382
404
  const ablo = Ablo({
383
405
  schema,
384
- apiKey: () => fetch('/api/ablo-session').then((r) => r.text()),
406
+ authEndpoint: '/api/ablo-session',
385
407
  });
386
408
 
387
409
  <AbloProvider client={ablo} userId={user.id}>
@@ -445,14 +467,8 @@ connects:
445
467
  | **Logical replication** (primary) | `npx ablo connect` prints the setup SQL (`wal_level=logical`, a publication, a `REPLICATION` role); `npx ablo connect --register` tells Ablo to replicate it. Ablo tails the WAL — it never runs DDL on, writes to, owns, or migrates your database. | Your database can grant a `REPLICATION` role (most can). |
446
468
  | **Signed endpoint** (fallback) | Your app exposes one route built from an ORM adapter (`prismaDataSource` / `drizzleDataSource`); Ablo sends signed requests and your app touches its own database. Needs no database configuration. | Your database **can't** grant a replication role (a locked-down managed DB). |
447
469
 
448
- (No database yet? A **sandbox** `sk_test` key lets you try Ablo's full API and
449
- coordination with throwaway **test data** — like Stripe test mode — before you
450
- connect your own Postgres. Test-mode only: in production your rows always live in
451
- your database and Ablo holds just the transaction log, never your data.)
452
-
453
- Your database is the system of record. The old `databaseUrl` dial-in (Ablo
454
- holding a read/write connection) is **deprecated and being removed** — connect
455
- via logical replication instead. See
470
+ Your database is the system of record Ablo holds the transaction log and
471
+ coordination, never your rows. See
456
472
  [Connect Your Database](./docs/data-sources.md).
457
473
 
458
474
  ## Configuration
@@ -466,7 +482,7 @@ Every other option has correct defaults:
466
482
  | --- | --- | --- | --- |
467
483
  | `schema` | `Schema` | — (required) | Typed model proxies (`ablo.<model>.*`) |
468
484
  | `apiKey` | `string \| ApiKeySetter \| null` | `process.env.ABLO_API_KEY` | Server key — a string, or an async function for rotation |
469
- | `databaseUrl` | `string \| null` | `—` | **Deprecated — being removed.** The old dial-in (Ablo holding a read/write connection to your DB). Connect via `npx ablo connect` (logical replication) instead; Ablo tails your WAL rather than dialing in. See [Connect Your Database](./docs/data-sources.md). |
485
+ | `databaseUrl` | `string \| null` | `—` | Deprecated. Connect via `npx ablo connect` instead see [Connect Your Database](./docs/data-sources.md). |
470
486
 
471
487
  Keep `apiKey` in trusted server runtimes. In the browser, `<AbloProvider>`
472
488
  authenticates with the signed-in user's session; the raw-key path is gated
@@ -519,7 +535,7 @@ contract; there are no retry or timeout knobs to tune.
519
535
  - [Guarantees](./docs/guarantees.md) — confirmed writes, stale-write protection, claim coordination, and agent lifecycle.
520
536
  - [Integration Guide](./docs/integration-guide.md) — integrate React, your database, multiplayer, and agents.
521
537
  - [React](./docs/react.md) — `<AbloProvider>`, `useAblo`, presence, status, and bootstrap gating.
522
- - [Coordination](./docs/coordination.md) — `claim` / `claim.state` / `claim.queue` / `claim.release` reference: hold a row across slow agent work, and observe the line waiting behind it.
538
+ - [Coordination](./docs/coordination.md) — `claim` / `claim.state` / `claim.queue` / `claim.release` / `heartbeat` reference: hold a row across slow agent work — minutes or hours, via heartbeats — and observe the line waiting behind it.
523
539
  - [Client Behavior](./docs/client-behavior.md) — options, errors, retries, timeouts, and public imports.
524
540
  - [Connect Your Database](./docs/data-sources.md) — connect your Postgres by logical replication (`npx ablo connect`) or, as a fallback, a signed endpoint; your database is the system of record either way.
525
541
  - [Existing Python Backend](./docs/examples/existing-python-backend.md) — migrate existing Python endpoints to multiplayer and agent-safe writes gradually.