@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
@@ -13,19 +13,23 @@ import { InstanceCache } from '../InstanceCache.js';
13
13
  import { SyncClient } from '../SyncClient.js';
14
14
  import { OnDemandLoader } from '../sync/OnDemandLoader.js';
15
15
  import { BootstrapFetcher } from '../sync/BootstrapFetcher.js';
16
- import { resolveBootstrapBaseUrl } from './auth.js';
17
- import { shouldUseInMemoryPersistence } from './persistence.js';
18
- import { resolveDurableWrites } from './durableWrites.js';
16
+ import { loadsAtBootstrap } from '../transaction/schema/loadStrategy.js';
17
+ import { resolveBootstrapBaseUrl } from '../transaction/auth/apiKey.js';
18
+ import { shouldUseInMemoryPersistence } from '../transaction/persistence.js';
19
+ import { globalRuntime } from '../context.js';
20
+ import { resolveDurableWrites } from '../transaction/durableWrites.js';
19
21
  export function createInternalComponents(input) {
20
22
  const { schema, url, options, auth } = input;
23
+ const runtime = input.runtime ?? globalRuntime;
21
24
  // The registry is created here, but model registration happens in the caller,
22
25
  // which owns the schema-to-class translation.
23
26
  const modelRegistry = new ModelRegistry({
24
27
  validateOnRegister: false,
25
28
  allowLateReferences: true,
29
+ runtime,
26
30
  });
27
31
  setActiveRegistry(modelRegistry);
28
- const objectPool = new InstanceCache({ maxSize: options.maxPoolSize ?? 10000 }, modelRegistry);
32
+ const objectPool = new InstanceCache({ maxSize: options.maxPoolSize ?? 10000, runtime }, modelRegistry);
29
33
  const bootstrapBaseUrl = resolveBootstrapBaseUrl({
30
34
  url,
31
35
  bootstrapBaseUrl: options.bootstrapBaseUrl,
@@ -35,15 +39,17 @@ export function createInternalComponents(input) {
35
39
  syncGroups: options.syncGroups,
36
40
  instantModels: deriveInstantModels(schema),
37
41
  getAuthToken: auth?.getAuthToken,
42
+ runtime,
38
43
  });
39
44
  const database = new Database(modelRegistry, bootstrapHelper, {
40
45
  // By default there is no browser-local durable store unless the caller asks
41
46
  // for one. Node and edge runtimes always use the in-memory store because
42
47
  // IndexedDB is unavailable there.
43
48
  inMemory: shouldUseInMemoryPersistence(options),
49
+ runtime,
44
50
  });
45
51
  const durableWrites = resolveDurableWrites(options);
46
- const syncClient = new SyncClient(objectPool, database, durableWrites.store, durableWrites.namespace ?? url);
52
+ const syncClient = new SyncClient(objectPool, database, durableWrites.store, durableWrites.namespace ?? url, runtime);
47
53
  // Lazy-load lane: hydrates the object pool and IndexedDB on demand for
48
54
  // entities not in scope at bootstrap (`load: 'lazy'` models, or an entity
49
55
  // reached by deep link before the pool warmed up). Single-flight, with
@@ -55,6 +61,7 @@ export function createInternalComponents(input) {
55
61
  schema,
56
62
  baseUrl: bootstrapBaseUrl,
57
63
  getAuthToken: auth?.getAuthToken,
64
+ runtime,
58
65
  });
59
66
  // Drop the lazy-lane hydration ledger on reconnect. While connected, the
60
67
  // WebSocket delta stream keeps hydrated rows fresh so repeat reads serve
@@ -72,20 +79,20 @@ export function createInternalComponents(input) {
72
79
  }
73
80
  /**
74
81
  * Derives the set of models to fetch in the initial bootstrap request from each
75
- * model's load strategy. Models declared `load: 'lazy'` or `'manual'` are left
76
- * out of the bootstrap and fetched on demand instead. The default strategy is
82
+ * model's load strategy. Models declared `load: 'lazy'` are left out of the
83
+ * bootstrap and fetched on demand instead. The default strategy is
77
84
  * `'instant'`, which includes the model.
78
85
  */
79
86
  function deriveInstantModels(schema) {
80
87
  const schemaModels = schema.models ?? schema;
81
88
  return Object.entries(schemaModels).flatMap(([key, def]) => {
82
89
  if (!def || typeof def !== 'object' || !('load' in def)) {
83
- return [key]; // no load → instant
90
+ return [key]; // no load → the default strategy
84
91
  }
85
92
  const load = def.load;
86
- if (!load || load === 'instant') {
93
+ if (loadsAtBootstrap(load)) {
87
94
  return [def.typename ?? key];
88
95
  }
89
- return []; // lazy or manual → skip
96
+ return [];
90
97
  });
91
98
  }
@@ -3,113 +3,44 @@
3
3
  * `ablo.<model>`.
4
4
  *
5
5
  * Each schema model gets one {@link ModelOperations}: the async server reads
6
- * `retrieve` and `list`, the synchronous local-graph snapshots `get`, `getAll`,
7
- * and `getCount`, the writes `create`, `update`, and `delete`, the coordination
6
+ * `retrieve` and `list`, the same verbs restricted to the local graph under
7
+ * `local`, the writes `create`, `update`, and `delete`, the coordination
8
8
  * namespace `claim` (callable as `claim({ id })`, plus `claim.state`,
9
9
  * `claim.queue`, `claim.release`, and `claim.reorder`), `join`, and `onChange`.
10
10
  * The factory returns a plain object; the client assembles the `ablo.<model>`
11
11
  * lookup table from one of these per model.
12
12
  */
13
- import { AbloClaimedError } from '../errors.js';
14
- import { type ModelUpdater, type ContentionOptions } from './functionalUpdate.js';
15
- import type { MutationOptions } from '../interfaces/index.js';
16
- import type { StaleNotification } from '../coordination/schema.js';
13
+ import type { ModelTarget } from '../transaction/coordination/schema.js';
17
14
  import type { ModelRegistry } from '../ModelRegistry.js';
18
15
  import type { InstanceCache } from '../InstanceCache.js';
19
16
  import type { SyncClient } from '../SyncClient.js';
20
17
  import type { OnDemandLoader } from '../sync/OnDemandLoader.js';
21
18
  import type { JoinedParticipant } from '../sync/participants.js';
22
- import type { LoadWhere } from '../query/types.js';
23
- import { ModelScope } from '../types/index.js';
24
- import type { Duration, Claim, ClaimHeartbeat, ClaimHeartbeatOptions, HeldClaim, HeldLease, ClaimWaitOptions, Snapshot, TargetRange } from '../types/streams.js';
19
+ import type { Duration, Claim, ClaimHeartbeat, ClaimHeartbeatOptions, HeldClaim, HeldLease, ClaimWaitOptions, Snapshot } from '../transaction/types/streams.js';
20
+ export type { ModelListScope, ModelTrackParams, ModelTrackResult, LocalReadOptions, LocalCountOptions, ServerReadOptions, ServerRetrieveOptions, ClaimTargetOptions, ClaimParams, ClaimLookupParams, ClaimReorderParams, ClaimOptions, ClaimReadApi, AwaitedClaimMethod, ClaimApi, ModelRetrieveParams, ModelCreateParams, ModelUpdateParams, ModelDeleteParams, JoinOptions, } from '../transaction/resources/modelOperations.js';
21
+ export type { Claim, ClaimHeartbeat, ClaimHeartbeatOptions, HeldClaim, HeldLease };
22
+ import type { ClaimApi, JoinOptions, LocalCountOptions, LocalReadOptions } from '../transaction/resources/modelOperations.js';
23
+ import type { HttpModelClient } from '../transaction/transport/httpClient.js';
24
+ import type { ParticipantKind } from '../transaction/types/participant.js';
25
25
  export interface ModelClientMeta {
26
26
  readonly key: string;
27
27
  readonly typename: string;
28
28
  }
29
29
  export declare function getModelClientMeta(modelClient: unknown): ModelClientMeta | undefined;
30
- export type ModelListScope = ModelScope | 'live' | 'archived' | 'all';
31
- /** Options for `track({ id })` register a durable read-dependency on a row. */
32
- export interface ModelTrackParams {
33
- /** The row to keep hearing about, by id. */
34
- id: string;
35
- /**
36
- * The sync watermark this track is premised on. Omit to baseline at the
37
- * current head — "tell me about anything from here on". Pass a known
38
- * `lastSyncId` (e.g. the one you read the row at) to also catch a change that
39
- * already landed between that read and this call.
40
- */
41
- readAt?: number;
42
- }
43
- /** The result of `track({ id })`. */
44
- export interface ModelTrackResult {
45
- /**
46
- * Tracks that had ALREADY fired at registration time — a change matching an
47
- * open track that landed before this call. Present only when something was
48
- * already stale; the ongoing signal arrives on the receipts of later commits.
49
- */
50
- notifications?: StaleNotification[];
51
- }
52
- /** Options for the synchronous local-pool reads `get`, `getAll`, and
53
- * `onChange` — a JavaScript `filter`, an equality `where`, and a lifecycle
54
- * `state`. This is the local, reactive axis; contrast {@link ServerReadOptions},
55
- * the asynchronous server axis. */
56
- export interface LocalReadOptions<T> {
57
- where?: Partial<T>;
58
- /** Arbitrary local predicate. Applied after `where`. */
59
- filter?: (entity: T) => boolean;
60
- orderBy?: {
61
- [K in keyof T]?: 'asc' | 'desc';
62
- };
63
- limit?: number;
64
- offset?: number;
65
- /** Lifecycle filter — `live` (the default), `archived`, or `all`. Named
66
- * `state` so it does not collide with the sync-group `scope`. */
67
- state?: ModelListScope;
68
- }
69
- export type LocalCountOptions<T> = Pick<LocalReadOptions<T>, 'where' | 'filter' | 'state'>;
70
- /** Options for the asynchronous server reads `retrieve` and `list` — the
71
- * operator `where` filter, `type`, and `expand`. This is the server axis;
72
- * contrast {@link LocalReadOptions}, the local, reactive axis. */
73
- export interface ServerReadOptions<T> {
74
- /**
75
- * Filter for the lookup. Accepts two forms:
76
- * - object form — `{ name: 'foo' }`: equality, where an array value means `IN`
77
- * - tuple form — `[['name', 'ILIKE', '%Goldman%']]`: explicit operators
78
- *
79
- * See {@link LoadWhere} for the full grammar. The wire protocol matches on AND
80
- * only; for OR semantics, run two `list()` calls and union the results.
81
- */
82
- where?: LoadWhere<T>;
83
- orderBy?: {
84
- [K in keyof T]?: 'asc' | 'desc';
85
- };
86
- limit?: number;
87
- /**
88
- * `complete` waits for the server. `unknown` returns whatever is local
89
- * immediately and refreshes in the background.
90
- */
91
- type?: 'complete' | 'unknown';
92
- /**
93
- * Schema-declared relation names to hydrate alongside the primary
94
- * rows. The server's compiler resolves each name via the schema's
95
- * relation metadata (`relation.belongsTo` / `relation.hasMany`)
96
- * and emits the JOIN.
97
- */
98
- expand?: readonly string[];
99
- }
100
- /** Options for the single-row async server read `retrieve({ id })`. A subset of
101
- * {@link ServerReadOptions} — `where`/`limit`/`orderBy` are fixed by the id. */
102
- export type ServerRetrieveOptions = Pick<ServerReadOptions<unknown>, 'type' | 'expand'>;
103
- export interface ModelCollaboration<T> {
30
+ /**
31
+ * The entity a coordination read names, without the sub-entity narrowing
32
+ * projected from {@link ModelTarget} so the two members are spelled once.
33
+ */
34
+ type EntityHalf = Pick<ModelTarget, 'model' | 'id'>;
35
+ export interface ModelCollaboration {
104
36
  createClaim(options: {
105
- target: {
106
- model: string;
107
- id: string;
108
- field?: string;
109
- path?: string;
110
- range?: TargetRange;
111
- meta?: Record<string, unknown>;
112
- };
37
+ /**
38
+ * The locator, in the spelling the SDK surface and the HTTP routes use.
39
+ * The canonical {@link ModelTarget} rather than a shape spelled here: this
40
+ * boundary is what a claim's narrowing has to cross, and a member missing
41
+ * from it dies before the socket sees it.
42
+ */
43
+ target: ModelTarget;
113
44
  /** Peer-visible description of the work (`'rewriting the risk section'`). */
114
45
  description?: string;
115
46
  ttl?: Duration;
@@ -121,6 +52,10 @@ export interface ModelCollaboration<T> {
121
52
  queue?: boolean;
122
53
  /** Reject (don't wait) if the queue is already this deep when we join. */
123
54
  maxQueueDepth?: number;
55
+ /** Cap on the queued wait before rejecting with `grant_timeout`. */
56
+ waitTimeoutMs?: number;
57
+ /** Abort the queued wait — rejects with `claim_wait_aborted`. */
58
+ signal?: AbortSignal;
124
59
  }): Promise<Claim>;
125
60
  createSnapshot(modelKey: string, id: string): Snapshot;
126
61
  /**
@@ -135,35 +70,29 @@ export interface ModelCollaboration<T> {
135
70
  * difference is this internal contract takes an explicit `{ model, id }`
136
71
  * target because it isn't bound to a single model.
137
72
  */
138
- state(target: {
139
- model: string;
140
- id: string;
141
- }): Claim | null;
73
+ state(target: EntityHalf): Claim | null;
74
+ /**
75
+ * Every active claim on a target, not just one. Sub-row claims on disjoint
76
+ * parts of a row are all granted, so a row can have several holders at once
77
+ * and `state` answers with only the first of them.
78
+ */
79
+ holders(target: EntityHalf): readonly Claim[];
142
80
  /**
143
81
  * The reactive wait queue on a target — the FIFO line of queued claims
144
82
  * behind the holder. Synchronous snapshot off the synced claim stream.
145
83
  */
146
- queue(target: {
147
- model: string;
148
- id: string;
149
- }): readonly Claim[];
84
+ queue(target: EntityHalf): readonly Claim[];
150
85
  /**
151
86
  * Re-rank the wait queue on a target (privileged — server-gated). `order` is
152
87
  * the desired front-of-line ordering, taken from `queue(target)`.
153
88
  */
154
- reorder(target: {
155
- model: string;
156
- id: string;
157
- }, order: readonly Claim[]): void;
89
+ reorder(target: EntityHalf, order: readonly Claim[]): void;
158
90
  /**
159
91
  * Resolve once no participant holds an active claim on the target.
160
92
  * The contender's "wait until it's free" — delegates to the claim
161
93
  * stream's `waitFor`.
162
94
  */
163
- waitFor(target: {
164
- model: string;
165
- id: string;
166
- }, options?: ClaimWaitOptions): Promise<void>;
95
+ waitFor(target: EntityHalf, options?: ClaimWaitOptions): Promise<void>;
167
96
  /**
168
97
  * The local participant's id. Used to distinguish "I already hold this"
169
98
  * from "someone else holds it" in `claimOrWait`.
@@ -175,7 +104,7 @@ export interface ModelCollaboration<T> {
175
104
  * holds the lease: server presence frames exclude a holder's own claims, so
176
105
  * the holder builds its own view.
177
106
  */
178
- readonly selfParticipantKind?: 'user' | 'agent' | 'system';
107
+ readonly selfParticipantKind?: ParticipantKind;
179
108
  /**
180
109
  * Subscribes the connection to a scope's sync group(s) — read interest. The
181
110
  * typed surface calls this on single-entity reads and claim observation so a
@@ -200,261 +129,51 @@ export interface ModelCollaboration<T> {
200
129
  */
201
130
  createJoin?(modelKey: string, ids: string | readonly string[], options?: JoinOptions): Promise<JoinedParticipant>;
202
131
  }
203
- export interface ClaimTargetOptions<T = Record<string, unknown>> {
204
- /** Peer-visible description of the work being performed — the sentence a
205
- * contending participant reads to decide whether to wait, work elsewhere, or
206
- * move on. Defaults to `'editing'`. The same field on every claim surface. */
207
- description?: string;
208
- /** Field-level target, for fine-grained claimed-state badges. */
209
- field?: string;
210
- /** Optional path for document/file-like targets. */
211
- path?: string;
212
- /** Optional range for document/file-like targets. */
213
- range?: TargetRange;
214
- /** App-defined structured metadata. */
215
- meta?: Record<string, unknown>;
216
- /** Crash-cleanup TTL — the claim auto-releases if the holder dies. */
217
- ttl?: Duration;
218
- /**
219
- * Behavior under contention. `true` (the default) queues behind the current
220
- * holder and resolves once the row is yours. `false` is fail-fast: if another
221
- * participant already holds the row, it rejects immediately with
222
- * {@link AbloClaimedError} instead of waiting. Use `false` to deduplicate
223
- * distributed work ("if someone else has this job, skip it"), where waiting
224
- * would mean double-processing.
225
- *
226
- * The high-level typed claim defaults this on because it serializes writers;
227
- * the low-level lease and the HTTP client default it off, since they resolve
228
- * immediately and cannot transparently wait for a grant.
229
- */
230
- queue?: boolean;
231
- /**
232
- * Backpressure: queue, but not behind too many others. If the server reports a
233
- * position at or beyond `maxQueueDepth` when the client joins the line, it
234
- * rejects with {@link AbloClaimedError} (`queue_too_deep`) instead of waiting.
235
- * Omit to wait however deep the queue is.
236
- */
237
- maxQueueDepth?: number;
238
- /**
239
- * Keep the lease alive for the duration of real work by beating on a
240
- * cadence — the pattern for background workers whose task outlives the
241
- * crash-cleanup TTL. `true` beats every third of the TTL (so two beats can
242
- * fail before the lease is at risk, and a crashed worker's lease still
243
- * lapses within one beat window); a duration such as `'2m'` sets the
244
- * cadence explicitly. The loop stops on release. A beat answered with a
245
- * definitive loss stops the loop and calls {@link onHeartbeatLost}; you can
246
- * also beat manually with `held.heartbeat()`.
247
- */
248
- heartbeat?: true | Duration;
249
- /**
250
- * Called once if the auto-heartbeat learns the lease is no longer yours
251
- * (expired and possibly granted onward). The loop has already stopped;
252
- * abandon the work or re-claim. Any write attempted under the old lease is
253
- * independently rejected by its `readAt` guard.
254
- */
255
- onHeartbeatLost?: (error: AbloClaimedError) => void;
256
- /**
257
- * Called after every successful beat (manual or auto) with the server's
258
- * answer — chiefly `queueDepth`, the number of participants waiting in
259
- * line behind this lease. A worker that can checkpoint may read pressure
260
- * here and release early when others wait.
261
- */
262
- onHeartbeat?(beat: ClaimHeartbeat): void;
263
- }
264
- /** Options for `claim({ id, ... })`. */
265
- export interface ClaimParams<T = Record<string, unknown>> extends ClaimTargetOptions<T> {
266
- readonly id: string;
267
- }
268
- export interface ClaimLookupParams<T = Record<string, unknown>> {
269
- readonly id: string;
270
- readonly field?: string;
271
- }
272
- export interface ClaimReorderParams<T = Record<string, unknown>> extends ClaimLookupParams<T> {
273
- readonly order: readonly Claim[];
274
- }
275
132
  /**
276
- * A claim handle: the held entity data plus an explicit release hook.
133
+ * The synchronous, local-only reads reached as `ablo.<model>.local.*`.
277
134
  *
278
- * ```ts
279
- * const claim = await ablo.weatherReports.claim({
280
- * id: 'report_stockholm',
281
- * description: 'Fetching current weather before writing the forecast.',
282
- * });
283
- * try {
284
- * await ablo.weatherReports.update({
285
- * id: claim.target.id,
286
- * data: { status: 'ready' },
287
- * claim,
288
- * });
289
- * } finally {
290
- * await claim.release();
291
- * }
292
- * ```
135
+ * Every verb mirrors its asynchronous sibling on the base surface, and the one
136
+ * word in front is the whole difference. It is a narrowing, not a claim about
137
+ * the other side: `retrieve` consults the local graph and then the network,
138
+ * while `local.retrieve` is restricted to what is already resident — which is
139
+ * also why it can return a value instead of a promise. There is nothing to
140
+ * await.
293
141
  *
294
- * `data` is a snapshot taken after the lease is held. Write through the flat
295
- * `ablo.<model>.update({ id, data, claim })` verb — the handle carries the
296
- * lease id and snapshot watermark for attribution and stale-write protection.
142
+ * These reads exist only here. Exposing them at the top level too would undo
143
+ * the distinction the namespace draws.
297
144
  */
298
- export type { Claim, ClaimHeartbeat, ClaimHeartbeatOptions, HeldClaim, HeldLease };
299
- export type ClaimOptions<T = Record<string, unknown>> = ClaimTargetOptions<T>;
300
- /**
301
- * The coordination surface for a model, exposed as a callable namespace.
302
- *
303
- * Most callers do not need this namespace directly. Put `claim: { ... }` on a
304
- * write and the SDK acquires/releases around that one mutation:
305
- *
306
- * ```ts
307
- * await ablo.tasks.update({
308
- * id,
309
- * data: { title },
310
- * claim: {
311
- * field: 'title',
312
- * description: 'Renaming the task to match the project brief.',
313
- * },
314
- * });
315
- * ```
316
- *
317
- * Use `claim({ id, ... })` when a tool spans multiple writes and needs one
318
- * handle. `state`, `queue`, and `reorder` are coordination reads/scheduler
319
- * controls for UI and operators.
320
- */
321
- /**
322
- * The coordination reads and scheduler controls on a claim namespace, in their
323
- * reactive (synchronous) form: `state`, `queue`, and `reorder` resolve against
324
- * the local pool with no round-trip, which is what lets a reactive selector read
325
- * coordination state inside a React render.
326
- *
327
- * This is the single source of truth for the claim read surface. The stateless
328
- * HTTP client exposes the awaited projection of exactly these methods (derived
329
- * via {@link AwaitedClaimMethod}), so the two transports cannot drift — change a
330
- * signature here and the HTTP surface follows.
331
- */
332
- export interface ClaimReadApi<T = Record<string, unknown>> {
333
- /**
334
- * Current holder for a row, or `null` when free. Use this for UI badges and
335
- * preflight checks, not for the normal write path.
336
- */
337
- state(params: ClaimLookupParams<T>): Claim | null;
145
+ export interface LocalReads<T> {
338
146
  /**
339
- * FIFO wait line behind the current holder. Advanced: useful for operator
340
- * UIs and schedulers.
147
+ * Snapshot of a single row from the local graph. `undefined` when the row is
148
+ * not resident — a graph that is still empty, or a `lazy` model not yet
149
+ * loaded. Pairs with reactive selectors:
150
+ * `useAblo((ablo) => ablo.<model>.local.retrieve(id))`.
341
151
  */
342
- queue(params: ClaimLookupParams<T>): {
343
- readonly object: 'list';
344
- readonly data: readonly Claim[];
345
- };
152
+ retrieve(id: string): T | undefined;
346
153
  /**
347
- * Re-rank the wait line. Advanced and permission-gated.
154
+ * Snapshot of a filtered collection from the local graph. Empty until
155
+ * `retrieve`, `list`, or bootstrap has warmed the graph.
348
156
  */
349
- reorder(params: ClaimReorderParams<T>): void;
350
- /** Release a manual claim handle early. Single-write claims auto-release. */
351
- release(params: ClaimLookupParams<T> | Claim<T>): Promise<void>;
157
+ list(options?: LocalReadOptions<T>): T[];
158
+ /** Count rows in the local graph. */
159
+ count(options?: LocalCountOptions<T>): number;
352
160
  }
353
161
  /**
354
- * The awaited form of a claim method: a synchronous return becomes a `Promise`,
355
- * an already-async one (`release`) is left untouched. Used to derive the
356
- * stateless HTTP claim surface from the reactive {@link ClaimReadApi}.
162
+ * What a reactive client adds on top of the base per-model surface: a live
163
+ * graph to read (`local`), the synchronous projection of the claim reads, and
164
+ * the two subscriptions a persistent socket makes possible.
165
+ *
166
+ * `claim` is here rather than inherited because the two transports carry
167
+ * deliberately different claim types, and the difference is load-bearing: a
168
+ * stateless client has no local copy, so `state`/`queue`/`reorder` must be
169
+ * awaited, while a reactive client resolves them synchronously — which is
170
+ * precisely what lets a React render read claim state inline. The stateless
171
+ * form is *derived* from this one through {@link AwaitedClaimMethod}, so the
172
+ * only permitted difference between them is that promise wrapper.
357
173
  */
358
- export type AwaitedClaimMethod<F> = F extends (...args: infer A) => infer R ? R extends Promise<unknown> ? (...args: A) => R : (...args: A) => Promise<R> : F;
359
- export interface ClaimApi<T> extends ClaimReadApi<T> {
360
- /**
361
- * Takes a claim and returns an explicit held-work handle — a {@link HeldClaim}.
362
- * `data`, `release`, `revoke`, and the async disposer are always present (this
363
- * call re-reads the row under the lease), so callers can use `handle.data`
364
- * directly and `await using` works without a guard.
365
- */
366
- (params: ClaimParams<T>): Promise<HeldClaim<T>>;
367
- /**
368
- * Takes a claim by id alone, for a row that lives only in the customer's own
369
- * database — Ablo has never seen it, so there is nothing to re-read. Returns a
370
- * {@link HeldLease}: the same lease controls as {@link HeldClaim}
371
- * (`release`, `revoke`, `heartbeat`, `await using`) but no `.data`. Locking a
372
- * key you know by id is exactly this — serialize writers without first
373
- * syncing the row into Ablo.
374
- */
375
- (id: string, opts?: ClaimOptions<T>): Promise<HeldLease>;
376
- }
377
- export interface ModelRetrieveParams extends ServerRetrieveOptions {
378
- readonly id: string;
379
- }
380
- export interface ModelCreateParams<T, CreateInput> extends MutationOptions {
381
- readonly data: CreateInput;
382
- readonly id?: string | null;
383
- readonly claim?: Claim<T> | ClaimTargetOptions<T> | null;
384
- }
385
- export interface ModelUpdateParams<T> extends MutationOptions {
386
- readonly id: string;
387
- readonly data: Partial<T>;
388
- readonly claim?: Claim<T> | ClaimTargetOptions<T> | null;
389
- }
390
- export interface ModelDeleteParams<T> extends MutationOptions {
391
- readonly id: string;
392
- readonly claim?: Claim<T> | ClaimTargetOptions<T> | null;
393
- }
394
- /** Options for the WebSocket-only `ablo.<model>.join(ids, options?)`. */
395
- export interface JoinOptions {
396
- /**
397
- * Lease TTL for the underlying presence claim — the participant
398
- * auto-releases after this if the holder dies. Compact duration string
399
- * (`'5m'`) or ms number, mirroring the claim `ttl`.
400
- */
401
- ttl?: Duration;
402
- }
403
- export interface ModelOperations<T, CreateInput> {
404
- /**
405
- * Reads a single entity by id from the server; asynchronous. Resolves through
406
- * a three-tier lookup — local pool, then IndexedDB, then a network
407
- * `POST /sync/query` — and lands the row in the local graph. Resolves to
408
- * `undefined` when no such row exists.
409
- *
410
- * This is the default "get me this entity" read, and the one a stateless
411
- * client wants, since its local graph starts empty. For a synchronous read of
412
- * an already-warm graph (such as a React selector) use `get(id)`.
413
- */
414
- retrieve(params: ModelRetrieveParams): Promise<T | undefined>;
415
- /**
416
- * Lists entities matching a filter from the server; asynchronous. Uses the
417
- * same three-tier lookup and graph hydration as `retrieve`, deduplicated so
418
- * concurrent identical calls share one request. Returns the matched rows. For
419
- * a synchronous read of the local graph use `getAll(...)`.
420
- */
421
- list(options?: ServerReadOptions<T>): Promise<T[]>;
422
- /**
423
- * Synchronous snapshot of a single entity from the local graph; no network.
424
- * Returns `undefined` when the row is not resident (a client whose graph is
425
- * still empty, or a `lazy` model not yet loaded). Pairs with reactive
426
- * selectors: `useAblo((ablo) => ablo.<model>.get(id))`.
427
- */
428
- get(id: string): T | undefined;
429
- /**
430
- * Synchronous snapshot of a filtered collection from the local graph; no
431
- * network round-trip. Empty until `retrieve`, `list`, or bootstrap has warmed
432
- * the graph.
433
- */
434
- getAll(options?: LocalReadOptions<T>): T[];
435
- /** Count entities in the local graph; synchronous, no network. */
436
- getCount(options?: LocalCountOptions<T>): number;
437
- /**
438
- * Create a new entity — **optimistic, offline-first**. Resolves once
439
- * the mutation is queued locally, not when the server confirms.
440
- * Server rejection rolls back automatically; watch `sync.syncStatus`.
441
- */
442
- create(params: ModelCreateParams<T, CreateInput>): Promise<T>;
443
- /** Update an entity by id — optimistic, offline-first (see `create`). */
444
- update(params: ModelUpdateParams<T>): Promise<T>;
445
- /**
446
- * Updates under contention with a function of the latest state —
447
- * `update(id, current => next)`. The client reads the freshest row, runs your
448
- * updater, writes the result as a compare-and-swap, and re-reads and re-runs
449
- * on any concurrent write. Nothing about claims, identity, or conflict codes
450
- * surfaces: the write either lands or throws {@link AbloContentionError} once
451
- * its reconcile budget is spent. Return `null` or `undefined` from the updater
452
- * to skip the write. Resolves to the reconciled row, or `undefined` when the
453
- * updater opted out.
454
- */
455
- update(id: string, updater: ModelUpdater<T>, options?: ContentionOptions): Promise<T | undefined>;
456
- /** Delete an entity by id — optimistic, offline-first (see `create`). */
457
- delete(params: ModelDeleteParams<T>): Promise<void>;
174
+ interface ReactiveModelSurface<T> {
175
+ /** The synchronous local-graph reads. */
176
+ local: LocalReads<T>;
458
177
  /**
459
178
  * Claim a row so other writers wait or are rejected until you're done, and
460
179
  * inspect or manage that coordination through the same namespace. Call it to
@@ -482,25 +201,6 @@ export interface ModelOperations<T, CreateInput> {
482
201
  * ```
483
202
  */
484
203
  claim: ClaimApi<T>;
485
- /**
486
- * Register a durable read-dependency on a row of this model — keep hearing
487
- * about it after this call returns. Where the per-write `reads` gate lives for
488
- * exactly one commit, a track persists on the server: any change that lands on
489
- * the tracked row rides back on the `notifications` of your next commit, so a
490
- * long-running actor learns its context went stale without re-reading. A track
491
- * you already have is refreshed, not duplicated (it is an idempotent upsert).
492
- *
493
- * ```ts
494
- * await ablo.tasks.track({ id: 'task_42' });
495
- * // …minutes of other work later, on your next write…
496
- * const res = await ablo.tasks.update({ id: 'task_42', data: { done: true } });
497
- * res.notifications; // populated if task_42 changed under you in the meantime
498
- * ```
499
- *
500
- * The returned `notifications` are only the tracks that had ALREADY fired at
501
- * registration time; the ongoing signal arrives on later receipts.
502
- */
503
- track(params: ModelTrackParams): Promise<ModelTrackResult>;
504
204
  /**
505
205
  * Joins the sync group(s) for one or more rows of this model and returns a
506
206
  * live participant handle — presence (`.peers`), the scoped claim stream
@@ -512,7 +212,7 @@ export interface ModelOperations<T, CreateInput> {
512
212
  * clients and throws on any non-WebSocket construction.
513
213
  *
514
214
  * ```ts
515
- * await using participant = await ablo.slides.join(slideIds, { ttl: '5m' });
215
+ * await using participant = await ablo.sections.join(sectionIds, { ttl: '5m' });
516
216
  * participant.peers; // who else is here
517
217
  * ```
518
218
  */
@@ -520,4 +220,29 @@ export interface ModelOperations<T, CreateInput> {
520
220
  /** Subscribe to changes; the callback runs on every change. */
521
221
  onChange(callback: (entities: T[]) => void, options?: LocalReadOptions<T>): () => void;
522
222
  }
523
- export declare function createModelProxy<T, C>(schemaKey: string, registeredModelName: string, objectPool: InstanceCache, syncClient: SyncClient, registry: ModelRegistry, hydration: OnDemandLoader, collaboration?: ModelCollaboration<T>): ModelOperations<T, C>;
223
+ /**
224
+ * Everything reachable as `ablo.<model>` on a reactive client.
225
+ *
226
+ * The base is not written here — it is the transport-independent per-model
227
+ * surface, taken whole. A reactive client is that surface plus what a live
228
+ * graph makes possible, so this type states the relationship instead of
229
+ * restating the members, and a verb added to the base arrives here on its own.
230
+ *
231
+ * `claim` is the one member the base cannot supply directly: the two forms
232
+ * differ by an awaitedness transform, so it is replaced rather than inherited.
233
+ * See {@link ReactiveModelSurface}.
234
+ */
235
+ export type ModelOperations<T, CreateInput> = Omit<HttpModelClient<T, CreateInput>, 'claim'> & ReactiveModelSurface<T>;
236
+ export declare function createModelProxy<T, C>(schemaKey: string, registeredModelName: string, objectPool: InstanceCache, syncClient: SyncClient, registry: ModelRegistry,
237
+ /**
238
+ * The one thing this factory asks of the loader: fetch rows for a model.
239
+ *
240
+ * Declared as the slice rather than the whole `OnDemandLoader` because the
241
+ * whole is a class, and a parameter typed as a class can only ever be
242
+ * satisfied by an instance of it — so every caller that has a narrower
243
+ * collaborator, a test most of all, is pushed into a cast through `unknown`
244
+ * to supply the one method that is actually read.
245
+ */
246
+ hydration: Pick<OnDemandLoader, 'fetch'>, collaboration?: ModelCollaboration,
247
+ /** The client-wide `wait` default; a per-call `wait` still wins over it. */
248
+ defaultWait?: 'queued' | 'confirmed'): ModelOperations<T, C>;