@abloatai/ablo 0.34.1 → 0.35.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 (483) hide show
  1. package/AGENTS.md +2 -1
  2. package/CHANGELOG.md +674 -5
  3. package/README.md +39 -22
  4. package/dist/BaseSyncedStore.d.ts +152 -44
  5. package/dist/BaseSyncedStore.js +300 -184
  6. package/dist/Database.d.ts +9 -24
  7. package/dist/Database.js +37 -22
  8. package/dist/InstanceCache.d.ts +25 -4
  9. package/dist/InstanceCache.js +48 -15
  10. package/dist/LazyReferenceCollection.d.ts +3 -3
  11. package/dist/LazyReferenceCollection.js +4 -4
  12. package/dist/Model.d.ts +6 -6
  13. package/dist/Model.js +10 -10
  14. package/dist/ModelRegistry.d.ts +4 -4
  15. package/dist/ModelRegistry.js +3 -3
  16. package/dist/{SyncEngineContext.d.ts → RuntimeContext.d.ts} +20 -13
  17. package/dist/{SyncEngineContext.js → RuntimeContext.js} +11 -12
  18. package/dist/SyncClient.d.ts +42 -32
  19. package/dist/SyncClient.js +166 -110
  20. package/dist/ai-sdk/coordinatedTool.d.ts +2 -2
  21. package/dist/ai-sdk/coordinatedTool.js +1 -1
  22. package/dist/ai-sdk/coordinationContext.d.ts +2 -2
  23. package/dist/ai-sdk/coordinationContext.js +1 -1
  24. package/dist/ai-sdk/wrap.d.ts +3 -3
  25. package/dist/ai-sdk/wrap.js +2 -2
  26. package/dist/auth/index.d.ts +1 -156
  27. package/dist/auth/index.js +8 -301
  28. package/dist/cli.cjs +3344 -1073
  29. package/dist/client/Ablo.d.ts +42 -287
  30. package/dist/client/Ablo.js +118 -963
  31. package/dist/client/abloClient.d.ts +309 -0
  32. package/dist/client/abloClient.js +13 -0
  33. package/dist/client/clientPrelude.d.ts +52 -0
  34. package/dist/client/clientPrelude.js +60 -0
  35. package/dist/client/consoleLogger.d.ts +2 -2
  36. package/dist/client/coreClient.d.ts +60 -0
  37. package/dist/client/coreClient.js +118 -0
  38. package/dist/client/createInternalComponents.d.ts +4 -4
  39. package/dist/client/createInternalComponents.js +9 -8
  40. package/dist/client/createModelProxy.d.ts +78 -373
  41. package/dist/client/createModelProxy.js +114 -86
  42. package/dist/client/humans.d.ts +48 -0
  43. package/dist/client/humans.js +52 -0
  44. package/dist/client/modelRegistration.d.ts +1 -1
  45. package/dist/client/modelRegistration.js +9 -9
  46. package/dist/client/options.d.ts +73 -17
  47. package/dist/client/reactiveEngine.d.ts +48 -0
  48. package/dist/client/reactiveEngine.js +910 -0
  49. package/dist/client/resourceTypes.d.ts +9 -250
  50. package/dist/client/resourceTypes.js +8 -5
  51. package/dist/client/schemaConfig.d.ts +4 -4
  52. package/dist/client/schemaConfig.js +6 -2
  53. package/dist/client/validateAbloOptions.d.ts +3 -2
  54. package/dist/client/validateAbloOptions.js +1 -1
  55. package/dist/client/wsMutationExecutor.d.ts +3 -3
  56. package/dist/client/wsMutationExecutor.js +3 -3
  57. package/dist/context.d.ts +9 -9
  58. package/dist/context.js +10 -9
  59. package/dist/coordination/ClaimLog.d.ts +26 -0
  60. package/dist/coordination/ClaimLog.js +32 -0
  61. package/dist/coordination/index.d.ts +1 -15
  62. package/dist/coordination/index.js +8 -31
  63. package/dist/core/DatabaseManager.js +1 -1
  64. package/dist/core/QueryView.d.ts +1 -1
  65. package/dist/core/QueryView.js +1 -1
  66. package/dist/core/StoreManager.d.ts +4 -23
  67. package/dist/core/StoreManager.js +5 -55
  68. package/dist/core/index.d.ts +2 -2
  69. package/dist/core/index.js +2 -2
  70. package/dist/core/storeContract.d.ts +2 -2
  71. package/dist/docs/catalog.d.ts +72 -0
  72. package/dist/docs/catalog.js +227 -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 +40 -34
  78. package/dist/index.js +26 -20
  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 +2 -2
  99. package/dist/query/client.js +4 -4
  100. package/dist/query/types.d.ts +6 -41
  101. package/dist/query/types.js +2 -2
  102. package/dist/react/AbloProvider.d.ts +6 -8
  103. package/dist/react/AbloProvider.js +5 -7
  104. package/dist/react/context.d.ts +1 -1
  105. package/dist/react/context.js +1 -1
  106. package/dist/react/index.d.ts +5 -5
  107. package/dist/react/index.js +3 -3
  108. package/dist/react/internalContext.d.ts +1 -1
  109. package/dist/react/useAblo.d.ts +3 -3
  110. package/dist/react/useAblo.js +1 -1
  111. package/dist/react/useCurrentUserId.js +1 -1
  112. package/dist/react/useErrorListener.js +1 -1
  113. package/dist/react/useMutationFailureListener.d.ts +2 -2
  114. package/dist/react/useMutationFailureListener.js +1 -1
  115. package/dist/react/useMutators.d.ts +3 -3
  116. package/dist/react/useMutators.js +3 -3
  117. package/dist/react/useUndoScope.d.ts +5 -5
  118. package/dist/react/useUndoScope.js +1 -1
  119. package/dist/schema/coordination.d.ts +69 -10
  120. package/dist/schema/coordination.js +86 -9
  121. package/dist/schema/ddl.js +2 -2
  122. package/dist/schema/diff.d.ts +1 -1
  123. package/dist/schema/generate.js +1 -1
  124. package/dist/schema/index.d.ts +10 -10
  125. package/dist/schema/index.js +18 -18
  126. package/dist/schema/queries.d.ts +27 -27
  127. package/dist/schema/queries.js +23 -23
  128. package/dist/schema/select.d.ts +3 -3
  129. package/dist/schema/select.js +3 -3
  130. package/dist/schema/serialize.d.ts +15 -6
  131. package/dist/schema/serialize.js +17 -3
  132. package/dist/schema/sugar.d.ts +6 -7
  133. package/dist/schema/sugar.js +9 -12
  134. package/dist/schema/syncDeltaRow.d.ts +4 -152
  135. package/dist/schema/syncDeltaRow.js +4 -105
  136. package/dist/server/adapter.d.ts +18 -1
  137. package/dist/server/commit.d.ts +10 -16
  138. package/dist/server/index.d.ts +1 -1
  139. package/dist/server/index.js +1 -1
  140. package/dist/server/readConfig.d.ts +1 -1
  141. package/dist/source/adapters/drizzle.d.ts +1 -1
  142. package/dist/source/adapters/drizzle.js +2 -2
  143. package/dist/source/adapters/kysely.d.ts +1 -1
  144. package/dist/source/adapters/kysely.js +1 -1
  145. package/dist/source/adapters/kyselyMutationCore.d.ts +1 -1
  146. package/dist/source/adapters/kyselyMutationCore.js +2 -2
  147. package/dist/source/adapters/memory.js +1 -1
  148. package/dist/source/adapters/prisma.d.ts +8 -3
  149. package/dist/source/adapters/prisma.js +1 -1
  150. package/dist/source/connector.js +1 -1
  151. package/dist/source/connectorProtocol.d.ts +2 -8
  152. package/dist/source/connectorProtocol.js +3 -2
  153. package/dist/source/contract.d.ts +29 -17
  154. package/dist/source/contract.js +27 -22
  155. package/dist/source/factory.d.ts +1 -1
  156. package/dist/source/footprint.d.ts +111 -0
  157. package/dist/source/footprint.js +0 -0
  158. package/dist/source/idempotency.js +2 -2
  159. package/dist/source/index.d.ts +1 -0
  160. package/dist/source/index.js +3 -0
  161. package/dist/source/next.d.ts +1 -1
  162. package/dist/source/signing.d.ts +9 -2
  163. package/dist/source/signing.js +4 -1
  164. package/dist/source/types.d.ts +6 -4
  165. package/dist/source/types.js +1 -1
  166. package/dist/stores/ObjectStore.d.ts +1 -1
  167. package/dist/stores/SyncActionStore.d.ts +1 -1
  168. package/dist/stores/SyncActionStore.js +2 -10
  169. package/dist/stores/syncAction.d.ts +26 -0
  170. package/dist/stores/syncAction.js +16 -0
  171. package/dist/surface.d.ts +3 -3
  172. package/dist/surface.js +6 -4
  173. package/dist/sync/BootstrapFetcher.d.ts +123 -6
  174. package/dist/sync/BootstrapFetcher.js +492 -66
  175. package/dist/sync/ConnectionManager.d.ts +6 -198
  176. package/dist/sync/ConnectionManager.js +6 -677
  177. package/dist/sync/OnDemandLoader.d.ts +2 -2
  178. package/dist/sync/OnDemandLoader.js +60 -21
  179. package/dist/sync/SubscriptionManager.d.ts +13 -2
  180. package/dist/sync/SubscriptionManager.js +23 -5
  181. package/dist/sync/SyncWebSocket.d.ts +27 -510
  182. package/dist/sync/SyncWebSocket.js +76 -954
  183. package/dist/sync/awaitClaimGrant.d.ts +4 -44
  184. package/dist/sync/awaitClaimGrant.js +4 -109
  185. package/dist/sync/commitFrames.d.ts +6 -40
  186. package/dist/sync/commitFrames.js +6 -97
  187. package/dist/sync/contextPorts.d.ts +18 -0
  188. package/dist/sync/contextPorts.js +31 -0
  189. package/dist/sync/createClaimStream.d.ts +5 -49
  190. package/dist/sync/createClaimStream.js +5 -469
  191. package/dist/sync/createPresenceStream.d.ts +26 -4
  192. package/dist/sync/createPresenceStream.js +28 -20
  193. package/dist/sync/createSnapshot.d.ts +2 -2
  194. package/dist/sync/createSnapshot.js +1 -1
  195. package/dist/sync/credentialLifecycle.d.ts +5 -173
  196. package/dist/sync/credentialLifecycle.js +5 -320
  197. package/dist/sync/deltaPipeline.d.ts +1 -1
  198. package/dist/sync/participants.d.ts +5 -4
  199. package/dist/sync/participants.js +29 -22
  200. package/dist/sync/schemaDrift.d.ts +55 -0
  201. package/dist/sync/schemaDrift.js +53 -0
  202. package/dist/sync/schemas.d.ts +21 -32
  203. package/dist/sync/schemas.js +26 -17
  204. package/dist/sync/syncPlan.d.ts +3 -3
  205. package/dist/sync/wsFrameHandlers.d.ts +6 -114
  206. package/dist/sync/wsFrameHandlers.js +6 -392
  207. package/dist/testing/fixtures/bootstrap.d.ts +1 -1
  208. package/dist/testing/fixtures/deltas.d.ts +1 -1
  209. package/dist/testing/fixtures/httpResponses.d.ts +70 -0
  210. package/dist/testing/fixtures/httpResponses.js +90 -0
  211. package/dist/testing/fixtures/models.js +1 -1
  212. package/dist/testing/helpers/wait.js +1 -1
  213. package/dist/testing/mocks/MockMutationExecutor.d.ts +2 -2
  214. package/dist/testing/mocks/MockMutationExecutor.js +8 -14
  215. package/dist/testing/mocks/MockSyncContext.d.ts +11 -11
  216. package/dist/testing/mocks/MockSyncContext.js +10 -9
  217. package/dist/testing/mocks/MockSyncStore.js +1 -1
  218. package/dist/testing/mocks/MockWebSocket.d.ts +2 -2
  219. package/dist/transaction/ablo.d.ts +88 -0
  220. package/dist/transaction/ablo.js +33 -0
  221. package/dist/{client/auth.d.ts → transaction/auth/apiKey.d.ts} +43 -8
  222. package/dist/{client/auth.js → transaction/auth/apiKey.js} +19 -0
  223. package/dist/transaction/auth/bootstrapScope.d.ts +15 -0
  224. package/dist/transaction/auth/bootstrapScope.js +1 -0
  225. package/dist/transaction/auth/capability.d.ts +177 -0
  226. package/dist/transaction/auth/capability.js +199 -0
  227. package/dist/{auth → transaction/auth}/credentialSource.d.ts +8 -1
  228. package/dist/{client → transaction/auth}/identity.d.ts +8 -7
  229. package/dist/{client → transaction/auth}/identity.js +1 -1
  230. package/dist/transaction/auth/index.d.ts +162 -0
  231. package/dist/transaction/auth/index.js +304 -0
  232. package/dist/{auth → transaction/auth}/schemas.d.ts +1 -1
  233. package/dist/{auth → transaction/auth}/schemas.js +13 -13
  234. package/dist/{client → transaction/auth}/sessionMint.d.ts +8 -8
  235. package/dist/{client → transaction/auth}/sessionMint.js +4 -7
  236. package/dist/transaction/coordination/awaitClaimGrant.d.ts +49 -0
  237. package/dist/transaction/coordination/awaitClaimGrant.js +112 -0
  238. package/dist/transaction/coordination/claimMeta.d.ts +49 -0
  239. package/dist/transaction/coordination/claimMeta.js +52 -0
  240. package/dist/transaction/coordination/createClaimStream.d.ts +64 -0
  241. package/dist/transaction/coordination/createClaimStream.js +475 -0
  242. package/dist/transaction/coordination/events.d.ts +74 -0
  243. package/dist/transaction/coordination/events.js +7 -0
  244. package/dist/transaction/coordination/index.d.ts +19 -0
  245. package/dist/transaction/coordination/index.js +44 -0
  246. package/dist/transaction/coordination/locator.d.ts +83 -0
  247. package/dist/transaction/coordination/locator.js +82 -0
  248. package/dist/transaction/coordination/schema.d.ts +1473 -0
  249. package/dist/{coordination → transaction/coordination}/schema.js +490 -55
  250. package/dist/transaction/coordination/targetConflict.d.ts +2 -0
  251. package/dist/transaction/coordination/targetConflict.js +103 -0
  252. package/dist/{coordination → transaction/coordination}/trace.d.ts +7 -18
  253. package/dist/{coordination → transaction/coordination}/trace.js +18 -25
  254. package/dist/transaction/durableWrites.d.ts +62 -0
  255. package/dist/{client → transaction}/durableWrites.js +28 -3
  256. package/dist/transaction/environment.d.ts +105 -0
  257. package/dist/transaction/environment.js +108 -0
  258. package/dist/{errorCodes.d.ts → transaction/errorCodes.d.ts} +11 -11
  259. package/dist/{errorCodes.js → transaction/errorCodes.js} +35 -12
  260. package/dist/{errors.d.ts → transaction/errors.d.ts} +37 -13
  261. package/dist/{errors.js → transaction/errors.js} +85 -16
  262. package/dist/transaction/index.d.ts +20 -0
  263. package/dist/transaction/index.js +20 -0
  264. package/dist/transaction/keys/index.d.ts +87 -0
  265. package/dist/transaction/keys/index.js +207 -0
  266. package/dist/transaction/log/syncDeltaRow.d.ts +158 -0
  267. package/dist/transaction/log/syncDeltaRow.js +95 -0
  268. package/dist/{sync/syncPosition.d.ts → transaction/logPosition.d.ts} +22 -8
  269. package/dist/{sync/syncPosition.js → transaction/logPosition.js} +15 -6
  270. package/dist/transaction/logger.d.ts +16 -0
  271. package/dist/transaction/logger.js +7 -0
  272. package/dist/transaction/observability.d.ts +53 -0
  273. package/dist/transaction/observability.js +19 -0
  274. package/dist/transaction/plugin.d.ts +192 -0
  275. package/dist/transaction/plugin.js +87 -0
  276. package/dist/{policy → transaction/policy}/types.d.ts +3 -3
  277. package/dist/{policy → transaction/policy}/types.js +2 -0
  278. package/dist/transaction/resources/httpResources.d.ts +266 -0
  279. package/dist/transaction/resources/httpResources.js +7 -0
  280. package/dist/transaction/resources/modelOperations.d.ts +319 -0
  281. package/dist/transaction/resources/modelOperations.js +12 -0
  282. package/dist/transaction/resources/mutationOptions.d.ts +66 -0
  283. package/dist/transaction/resources/mutationOptions.js +9 -0
  284. package/dist/transaction/resources/where.d.ts +85 -0
  285. package/dist/transaction/resources/where.js +70 -0
  286. package/dist/{client → transaction/resources}/writeOptionsSchema.d.ts +2 -6
  287. package/dist/{client → transaction/resources}/writeOptionsSchema.js +9 -5
  288. package/dist/{schema → transaction/schema}/field.d.ts +5 -5
  289. package/dist/{schema → transaction/schema}/field.js +5 -5
  290. package/dist/transaction/schema/loadStrategy.d.ts +45 -0
  291. package/dist/transaction/schema/loadStrategy.js +46 -0
  292. package/dist/{schema → transaction/schema}/model.d.ts +50 -35
  293. package/dist/{schema → transaction/schema}/model.js +30 -20
  294. package/dist/transaction/schema/openapi.d.ts +57 -0
  295. package/dist/transaction/schema/openapi.js +340 -0
  296. package/dist/{schema → transaction/schema}/relation.d.ts +14 -14
  297. package/dist/{schema → transaction/schema}/relation.js +7 -7
  298. package/dist/{schema → transaction/schema}/residency.d.ts +0 -9
  299. package/dist/{schema → transaction/schema}/residency.js +0 -5
  300. package/dist/{schema → transaction/schema}/roles.d.ts +5 -5
  301. package/dist/{schema → transaction/schema}/roles.js +5 -5
  302. package/dist/{schema → transaction/schema}/schema.d.ts +12 -10
  303. package/dist/{schema → transaction/schema}/schema.js +4 -3
  304. package/dist/{schema → transaction/schema}/tenancy.d.ts +1 -1
  305. package/dist/{schema → transaction/schema}/tenancy.js +7 -4
  306. package/dist/transaction/transactionLayer.d.ts +82 -0
  307. package/dist/transaction/transactionLayer.js +24 -0
  308. package/dist/{transactions → transaction/transactions/settlement}/commitEnvelope.d.ts +4 -5
  309. package/dist/{transactions → transaction/transactions/settlement}/commitEnvelope.js +9 -13
  310. package/dist/{transactions → transaction/transactions/settlement}/httpCommitEnvelope.d.ts +9 -2
  311. package/dist/{transactions → transaction/transactions/settlement}/httpCommitEnvelope.js +5 -9
  312. package/dist/{transactions/durableWriteStore.d.ts → transaction/transactions/settlement/pendingWrite.d.ts} +10 -36
  313. package/dist/transaction/transactions/settlement/pendingWrite.js +20 -0
  314. package/dist/transaction/transport/commitFrames.d.ts +90 -0
  315. package/dist/transaction/transport/commitFrames.js +134 -0
  316. package/dist/transaction/transport/connectionManager.d.ts +215 -0
  317. package/dist/transaction/transport/connectionManager.js +673 -0
  318. package/dist/transaction/transport/credentialLifecycle.d.ts +177 -0
  319. package/dist/transaction/transport/credentialLifecycle.js +324 -0
  320. package/dist/{sync → transaction/transport}/heartbeat.d.ts +3 -1
  321. package/dist/{sync → transaction/transport}/heartbeat.js +6 -4
  322. package/dist/{client → transaction/transport}/httpClient.d.ts +59 -16
  323. package/dist/{client → transaction/transport}/httpClient.js +5 -5
  324. package/dist/transaction/transport/httpOptions.d.ts +33 -0
  325. package/dist/transaction/transport/httpOptions.js +12 -0
  326. package/dist/{client → transaction/transport}/httpTransport.js +171 -85
  327. package/dist/{sync/NetworkProbe.d.ts → transaction/transport/networkProbe.d.ts} +7 -4
  328. package/dist/{sync/NetworkProbe.js → transaction/transport/networkProbe.js} +14 -13
  329. package/dist/transaction/transport/wsFrameHandlers.d.ts +128 -0
  330. package/dist/transaction/transport/wsFrameHandlers.js +429 -0
  331. package/dist/transaction/transport/wsTransport.d.ts +576 -0
  332. package/dist/transaction/transport/wsTransport.js +1017 -0
  333. package/dist/transaction/types/assertExact.d.ts +17 -0
  334. package/dist/transaction/types/assertExact.js +1 -0
  335. package/dist/{types → transaction/types}/global.d.ts +17 -2
  336. package/dist/{types → transaction/types}/global.js +2 -1
  337. package/dist/{types → transaction/types}/index.d.ts +14 -46
  338. package/dist/{types → transaction/types}/index.js +7 -16
  339. package/dist/{types → transaction/types}/streams.d.ts +63 -45
  340. package/dist/{utils → transaction/utils}/json.d.ts +18 -0
  341. package/dist/transaction/utils/json.js +276 -0
  342. package/dist/transaction/wire/accountResponses.d.ts +351 -0
  343. package/dist/transaction/wire/accountResponses.js +255 -0
  344. package/dist/transaction/wire/auth.d.ts +49 -0
  345. package/dist/transaction/wire/auth.js +57 -0
  346. package/dist/transaction/wire/claimEvent.d.ts +76 -0
  347. package/dist/transaction/wire/claimEvent.js +73 -0
  348. package/dist/transaction/wire/claims.d.ts +463 -0
  349. package/dist/transaction/wire/claims.js +229 -0
  350. package/dist/{wire → transaction/wire}/commit.d.ts +125 -193
  351. package/dist/{wire → transaction/wire}/commit.js +68 -47
  352. package/dist/{wire → transaction/wire}/delta.d.ts +66 -17
  353. package/dist/{wire → transaction/wire}/delta.js +37 -13
  354. package/dist/transaction/wire/errorEnvelope.d.ts +72 -0
  355. package/dist/{wire → transaction/wire}/errorEnvelope.js +36 -5
  356. package/dist/transaction/wire/feedCursor.d.ts +60 -0
  357. package/dist/transaction/wire/feedCursor.js +82 -0
  358. package/dist/transaction/wire/feedEvent.d.ts +177 -0
  359. package/dist/transaction/wire/feedEvent.js +39 -0
  360. package/dist/transaction/wire/frames.d.ts +194 -0
  361. package/dist/transaction/wire/frames.js +50 -0
  362. package/dist/transaction/wire/inboundFrames.d.ts +552 -0
  363. package/dist/transaction/wire/inboundFrames.js +116 -0
  364. package/dist/transaction/wire/index.d.ts +50 -0
  365. package/dist/transaction/wire/index.js +74 -0
  366. package/dist/{wire → transaction/wire}/listEnvelope.d.ts +13 -14
  367. package/dist/transaction/wire/listEnvelope.js +42 -0
  368. package/dist/transaction/wire/modelResponses.d.ts +85 -0
  369. package/dist/transaction/wire/modelResponses.js +43 -0
  370. package/dist/transactions/{TransactionQueue.d.ts → mutations/MutationQueue.d.ts} +79 -38
  371. package/dist/transactions/{TransactionQueue.js → mutations/MutationQueue.js} +110 -59
  372. package/dist/transactions/{TransactionStore.d.ts → mutations/MutationStore.d.ts} +8 -8
  373. package/dist/transactions/{TransactionStore.js → mutations/MutationStore.js} +2 -2
  374. package/dist/transactions/{coalesceRules.d.ts → mutations/coalesceRules.d.ts} +10 -10
  375. package/dist/transactions/{coalesceRules.js → mutations/coalesceRules.js} +1 -1
  376. package/dist/transactions/mutations/commitLatency.d.ts +52 -0
  377. package/dist/transactions/mutations/commitLatency.js +130 -0
  378. package/dist/transactions/{commitOutboxStore.d.ts → mutations/commitOutboxStore.d.ts} +1 -5
  379. package/dist/transactions/{commitOutboxStore.js → mutations/commitOutboxStore.js} +1 -1
  380. package/dist/transactions/{commitPayload.d.ts → mutations/commitPayload.d.ts} +16 -15
  381. package/dist/transactions/{commitPayload.js → mutations/commitPayload.js} +12 -12
  382. package/dist/transactions/{deltaConfirmation.d.ts → mutations/deltaConfirmation.d.ts} +11 -11
  383. package/dist/transactions/{deltaConfirmation.js → mutations/deltaConfirmation.js} +7 -7
  384. package/dist/transactions/mutations/durableWriteStore.d.ts +14 -0
  385. package/dist/transactions/mutations/durableWriteStore.js +12 -0
  386. package/dist/transactions/{optimisticApply.d.ts → mutations/optimisticApply.d.ts} +7 -7
  387. package/dist/transactions/{replayValidation.d.ts → mutations/replayValidation.d.ts} +3 -3
  388. package/dist/transactions/{replayValidation.js → mutations/replayValidation.js} +4 -3
  389. package/dist/utils/mobxSetup.d.ts +1 -1
  390. package/dist/utils/mobxSetup.js +5 -2
  391. package/dist/webhooks/events.d.ts +2 -2
  392. package/dist/wire/index.d.ts +1 -34
  393. package/dist/wire/index.js +8 -49
  394. package/docs/agent-messaging.md +3 -3
  395. package/docs/agents.md +19 -12
  396. package/docs/api-keys.md +8 -4
  397. package/docs/api.md +22 -18
  398. package/docs/audit.md +2 -0
  399. package/docs/cli.md +31 -3
  400. package/docs/client-behavior.md +8 -6
  401. package/docs/concurrency-convention.md +30 -24
  402. package/docs/coordination.md +48 -38
  403. package/docs/data-sources.md +3 -1
  404. package/docs/debugging.md +5 -3
  405. package/docs/deployment.md +267 -0
  406. package/docs/examples/agent-human.md +49 -42
  407. package/docs/examples/ai-sdk-tool.md +69 -44
  408. package/docs/examples/existing-python-backend.md +8 -6
  409. package/docs/examples/nextjs.md +129 -47
  410. package/docs/examples/scoped-agent.md +45 -44
  411. package/docs/examples/server-agent.md +46 -26
  412. package/docs/groups.md +32 -29
  413. package/docs/guarantees.md +4 -2
  414. package/docs/how-it-works.md +9 -7
  415. package/docs/idempotency.md +126 -0
  416. package/docs/identity.md +58 -54
  417. package/docs/index.md +172 -86
  418. package/docs/integration-guide.md +17 -16
  419. package/docs/interaction-model.md +6 -4
  420. package/docs/mcp.md +41 -16
  421. package/docs/migration.md +63 -5
  422. package/docs/operating-on-your-database.md +3 -1
  423. package/docs/projects.md +2 -0
  424. package/docs/quickstart.md +22 -5
  425. package/docs/react.md +12 -10
  426. package/docs/schema-contract.md +5 -3
  427. package/docs/session-settings.md +108 -0
  428. package/docs/sessions.md +3 -1
  429. package/docs/webhooks.md +3 -1
  430. package/llms.txt +47 -17
  431. package/package.json +10 -8
  432. package/dist/agent/Agent.d.ts +0 -366
  433. package/dist/agent/Agent.js +0 -514
  434. package/dist/agent/index.d.ts +0 -115
  435. package/dist/agent/index.js +0 -128
  436. package/dist/agent/session.d.ts +0 -93
  437. package/dist/agent/session.js +0 -149
  438. package/dist/agent/types.d.ts +0 -68
  439. package/dist/agent/types.js +0 -9
  440. package/dist/client/durableWrites.d.ts +0 -21
  441. package/dist/coordination/schema.d.ts +0 -722
  442. package/dist/schema/openapi.d.ts +0 -29
  443. package/dist/schema/openapi.js +0 -124
  444. package/dist/transactions/durableWriteStore.js +0 -30
  445. package/dist/utils/json.js +0 -88
  446. package/dist/wire/errorEnvelope.d.ts +0 -55
  447. package/dist/wire/frames.d.ts +0 -197
  448. package/dist/wire/frames.js +0 -49
  449. package/dist/wire/listEnvelope.js +0 -18
  450. /package/dist/{client → transaction/auth}/credentialEndpoint.d.ts +0 -0
  451. /package/dist/{client → transaction/auth}/credentialEndpoint.js +0 -0
  452. /package/dist/{auth → transaction/auth}/credentialPolicy.d.ts +0 -0
  453. /package/dist/{auth → transaction/auth}/credentialPolicy.js +0 -0
  454. /package/dist/{auth → transaction/auth}/credentialSource.js +0 -0
  455. /package/dist/{client → transaction/auth}/hostedEndpoints.d.ts +0 -0
  456. /package/dist/{client → transaction/auth}/hostedEndpoints.js +0 -0
  457. /package/dist/{client → transaction/coordination}/claimHeartbeatLoop.d.ts +0 -0
  458. /package/dist/{client → transaction/coordination}/claimHeartbeatLoop.js +0 -0
  459. /package/dist/{client → transaction}/persistence.d.ts +0 -0
  460. /package/dist/{client → transaction}/persistence.js +0 -0
  461. /package/dist/{client → transaction/resources}/functionalUpdate.d.ts +0 -0
  462. /package/dist/{client → transaction/resources}/functionalUpdate.js +0 -0
  463. /package/dist/{transactions → transaction/transactions/settlement}/idempotencyKey.d.ts +0 -0
  464. /package/dist/{transactions → transaction/transactions/settlement}/idempotencyKey.js +0 -0
  465. /package/dist/{client → transaction/transport}/httpTransport.d.ts +0 -0
  466. /package/dist/{types → transaction/types}/modelData.d.ts +0 -0
  467. /package/dist/{types → transaction/types}/modelData.js +0 -0
  468. /package/dist/{types → transaction/types}/participant.d.ts +0 -0
  469. /package/dist/{types → transaction/types}/participant.js +0 -0
  470. /package/dist/{types → transaction/types}/streams.js +0 -0
  471. /package/dist/{utils → transaction/utils}/asyncIterator.d.ts +0 -0
  472. /package/dist/{utils → transaction/utils}/asyncIterator.js +0 -0
  473. /package/dist/{utils → transaction/utils}/duration.d.ts +0 -0
  474. /package/dist/{utils → transaction/utils}/duration.js +0 -0
  475. /package/dist/{wire → transaction/wire}/bootstrapReason.d.ts +0 -0
  476. /package/dist/{wire → transaction/wire}/bootstrapReason.js +0 -0
  477. /package/dist/{wire → transaction/wire}/protocol.d.ts +0 -0
  478. /package/dist/{wire → transaction/wire}/protocol.js +0 -0
  479. /package/dist/{wire → transaction/wire}/protocolVersion.d.ts +0 -0
  480. /package/dist/{wire → transaction/wire}/protocolVersion.js +0 -0
  481. /package/dist/transactions/{UnconfirmedWrites.d.ts → mutations/UnconfirmedWrites.d.ts} +0 -0
  482. /package/dist/transactions/{UnconfirmedWrites.js → mutations/UnconfirmedWrites.js} +0 -0
  483. /package/dist/transactions/{optimisticApply.js → mutations/optimisticApply.js} +0 -0
package/README.md CHANGED
@@ -66,10 +66,21 @@ claims are visible while the work is still in progress.
66
66
  [Version History & Migration Guide](./docs/migration.md)
67
67
 
68
68
  It works with the auth and database you already have. **In production, your
69
- database is the system of record.** Ablo is the sync + coordination layer on top
70
- of it: it consumes your Postgres' logical-replication stream, scopes realtime
71
- data to *sync groups* from your own identity, and your application keeps owning
72
- the write path every row lives in your Postgres. (Trying Ablo with no database
69
+ database is the system of record.** You write through Ablo, and Ablo writes to
70
+ your Postgres: the call enters Ablo's commit chokepoint — where claims, ordering,
71
+ and idempotency are enforced and lands in your own tables through a scoped
72
+ writer role. The commit is accepted (`queued`) the moment Ablo takes it; when the
73
+ row surfaces in your write-ahead log, the receipt is promoted to `confirmed`.
74
+ **The WAL echo is how Ablo confirms, not how it writes** — your database, not
75
+ Ablo, is the source of truth for row state, and that same stream is what keeps
76
+ every connected client current, scoped to *sync groups* from your own identity.
77
+
78
+ The writer role is non-superuser and cannot bypass RLS. Before each write Ablo
79
+ sets your tenant context on the connection, so your own row-level security
80
+ policies enforce against Ablo exactly as they do against your app. Ablo runs no
81
+ DDL and owns no schema — your migration tool stays in charge of the shape of your
82
+ database, and Ablo holds only the ordered transaction log and the coordination
83
+ state, never your rows. (Trying Ablo with no database
73
84
  yet? A **sandbox** `sk_test` key holds throwaway **test data** — like Stripe test
74
85
  mode — so you can explore before pointing it at your Postgres. Test-mode only; in
75
86
  production every row lives in your database.)
@@ -91,7 +102,8 @@ production, your database is the system of record**.
91
102
  npm install @abloatai/ablo
92
103
  npx ablo login # opens the browser: sign in (or sign up) → a sk_test_ key is saved locally
93
104
  npx ablo init # scaffolds ablo/schema.ts (offers to log in if you skipped it)
94
- npx ablo push # pushes your schema (sandbox), writes ABLO_API_KEY to .env.local, watches for changes
105
+ npx ablo push # pushes your schema (sandbox), writes ABLO_API_KEY to .env.local
106
+ npx ablo dev # the same push, watching ablo/schema.ts and re-pushing on save
95
107
  ```
96
108
 
97
109
  Then point Ablo at the tables for your synced models. Most teams **already
@@ -124,7 +136,7 @@ instead of guessing:
124
136
 
125
137
  ## Quick Start
126
138
 
127
- One schema, one client, one write path for humans and agents — this runs as-is
139
+ One schema, one client, one write path for agents, servers, and people — this runs as-is
128
140
  after `ablo push`:
129
141
 
130
142
  ```ts
@@ -156,7 +168,7 @@ await ablo.weatherReports.update({
156
168
  claim, // the write completes the claimed work and releases the lease
157
169
  });
158
170
 
159
- const ready = ablo.weatherReports.get(created.id);
171
+ const ready = ablo.weatherReports.local.retrieve(created.id);
160
172
  console.log({ id: ready?.id, status: ready?.status });
161
173
 
162
174
  await ablo.dispose();
@@ -202,16 +214,15 @@ function persist(client: Sync) { /* ... */ }
202
214
 
203
215
  ## Reading
204
216
 
205
- Two ways to read, depending on whether you can wait. `get(id)` / `getAll({ where })`
206
- / `getCount({ where })` are instant — they read what's already local and re-render
207
- on their own when it changes, so they're what your UI uses. `retrieve(id)` /
208
- `list({ where })` go ask the server and return a `Promise`, for when you need the
209
- authoritative answer right now.
217
+ Two ways to read, depending on whether you can wait. `retrieve({ id })` /
218
+ `list({ where })` answer from what's local and go ask the server when they have
219
+ to, so they return a `Promise`. Put `local.` in front and the read is restricted
220
+ to what's already here instant, reactive in render, and what your UI uses.
210
221
 
211
222
  ```ts
212
- ablo.weatherReports.get('report_stockholm');
223
+ ablo.weatherReports.local.retrieve('report_stockholm');
213
224
 
214
- const pending = ablo.weatherReports.getAll({
225
+ const pending = ablo.weatherReports.local.list({
215
226
  where: { status: 'pending' },
216
227
  orderBy: { location: 'asc' },
217
228
  limit: 20,
@@ -373,7 +384,7 @@ function App() {
373
384
  }
374
385
 
375
386
  function Report({ id }: { id: string }) {
376
- const report = useAblo((ablo) => ablo.weatherReports.get(id));
387
+ const report = useAblo((ablo) => ablo.weatherReports.local.retrieve(id));
377
388
  const ablo = useAblo();
378
389
 
379
390
  if (!report) return null;
@@ -392,7 +403,7 @@ method as the server example above.
392
403
 
393
404
  `<AbloProvider>` owns the connection — no API key in the browser. That's the
394
405
  whole loop: read with `useAblo(selector)`, write with `ablo.<model>`, and every
395
- other client (human or agent) on that row sees it in real time. See
406
+ other client (agent or human) on that row sees it in real time. See
396
407
  [React](./docs/react.md) for the `<AbloProvider>` prop surface (`client`,
397
408
  `userId`, `fallback`, `onError`) — schema, scope, and team membership live on the
398
409
  `Ablo({ … })` client you pass it — plus status hooks.
@@ -402,7 +413,7 @@ other client (human or agent) on that row sees it in real time. See
402
413
  Ablo is **not** an auth provider — you keep your own (Clerk, Auth0, NextAuth,
403
414
  whatever). Ablo's job starts after you've authenticated a request: you tell it
404
415
  *who* is connecting, and it scopes their realtime data to the right **sync
405
- groups** (named channels like `org:acme` or `deck:abc123` that are both the unit
416
+ groups** (named channels like `org:acme` or `workspace:abc123` that are both the unit
406
417
  of fan-out and the unit of access).
407
418
 
408
419
  The model is a proxy: your `ABLO_API_KEY` stays on your trusted server, your
@@ -434,19 +445,25 @@ browser.
434
445
 
435
446
  ## Multiplayer
436
447
 
437
- There is no separate multiplayer mode. When human UI, server actions, and agent
438
- workers share the same schema and write through `ablo.<model>`, they all see
448
+ There is no separate multiplayer mode. When agent workers, server actions, and
449
+ human UI share the same schema and write through `ablo.<model>`, they all see
439
450
  each other's changes in real time — that's the default, not a feature you turn on.
440
451
 
441
452
  - `ablo.<model>.create/update/delete` fan out confirmed deltas to subscribers.
442
453
  - `useAblo(...)` gives React clients the live row, kept current automatically.
443
- - `ablo.<model>.claim({ id })` / `claim.state({ id })` / `claim.queue({ id })` let humans and agents coordinate (and observe) active work on a row — and the line waiting behind it — before a write lands.
454
+ - `ablo.<model>.claim({ id })` / `claim.state({ id })` / `claim.queue({ id })` let agents and people coordinate (and observe) active work on a row — and the line waiting behind it — before a write lands.
455
+
456
+ The bare client is the coordination layer: commit, read, observe, claim. The live
457
+ plane people watch — presence, live queries, the local copy — is the `humans()`
458
+ plugin on top of it, installed by default on a socket client. There is no
459
+ `agents()` plugin, and the absence is the point: an agent is the default caller
460
+ here, not a special one.
444
461
 
445
462
  Writes go through Ablo. `ablo.<model>.create/update/delete` and the HTTP write
446
463
  endpoint enter Ablo's commit chokepoint — where claims, ordering, and idempotency
447
464
  are enforced — and Ablo lands the change in your database. It then tails the WAL to
448
465
  confirm the row landed and fans the confirmed change out to every connected client.
449
- One surface for humans, servers, and agents; one place coordination happens.
466
+ One surface for agents, servers, and people; one place coordination happens.
450
467
 
451
468
  ## HTTP Writes
452
469
 
@@ -477,7 +494,7 @@ connects:
477
494
 
478
495
  | | How Ablo connects to your Postgres | Use when |
479
496
  | --- | --- | --- |
480
- | **`ablo connect`** (primary) | Sets up logical replication and a scoped writer role (`npx ablo connect apply` does it end to end). Ablo writes your rows through the writer role and reads them back over the WAL to confirm — it writes rows but runs no DDL and owns no schema. | Your database can grant a `REPLICATION` role (most can). |
497
+ | **`ablo connect`** (primary) | Sets up logical replication and a scoped writer role (`npx ablo connect apply` does it end to end). Ablo writes your rows through the writer role and reads them back over the WAL to confirm — it writes rows but runs no DDL and owns no schema. The role is non-superuser and cannot bypass RLS, so your own policies govern Ablo's writes. | Your database can grant a `REPLICATION` role (most can). |
481
498
  | **Signed endpoint** (fallback) | Your app exposes one route built from an ORM adapter (`prismaDataSource` / `drizzleDataSource`); Ablo writes and confirms through it. Needs no replication setup. | Your database **can't** grant a replication role (a locked-down managed DB). |
482
499
 
483
500
  Your database is the system of record. See
@@ -10,7 +10,7 @@
10
10
  * queue, {@link Database} owns local persistence, {@link InstanceCache} holds the
11
11
  * in-memory models, and {@link ModelRegistry} holds their metadata.
12
12
  */
13
- import type { RecoveryClass } from './errorCodes.js';
13
+ import type { RecoveryClass } from './transaction/errorCodes.js';
14
14
  import { ConnectionManager } from './sync/ConnectionManager.js';
15
15
  import { SubscriptionManager } from './sync/SubscriptionManager.js';
16
16
  import { type ParticipantScope } from './sync/participants.js';
@@ -18,22 +18,23 @@ import type { SyncClient } from './SyncClient.js';
18
18
  import type { Database, BootstrapResult } from './Database.js';
19
19
  import type { InstanceCache } from './InstanceCache.js';
20
20
  import { ModelRegistry } from './ModelRegistry.js';
21
- import { SyncWebSocket, type SyncDelta, type SyncGroupChangePayload, type GroupAddedPayload, type GroupRemovedPayload, type BootstrapHint, type BootstrapDataEvent, type PresenceUpdateEvent, type EventMap, type DefaultCollaborationEvents } from './sync/SyncWebSocket.js';
21
+ import { SyncWebSocket, type SyncDelta, type SyncGroupChangePayload, type GroupAddedPayload, type GroupRemovedPayload, type BootstrapHint, type BootstrapDataEvent, type PresenceUpdate, type EventMap, type DefaultCollaborationEvents, type SyncWebSocketEventMap } from './sync/SyncWebSocket.js';
22
22
  import { QueryProcessor } from './core/QueryProcessor.js';
23
23
  import { Model } from './Model.js';
24
24
  import { ModelScope } from './InstanceCache.js';
25
- import type { Schema } from './schema/schema.js';
25
+ import type { Schema } from './transaction/schema/schema.js';
26
26
  import type { SyncStatus, LocalMutation } from './core/storeContract.js';
27
- import type { AuthCredentialSource } from './auth/credentialSource.js';
28
- import type { ModelData } from './types/modelData.js';
27
+ import type { AuthCredentialSource } from './transaction/auth/credentialSource.js';
28
+ import type { ModelData } from './transaction/types/modelData.js';
29
29
  import type { EnrichmentPlanEntry, ForeignKeyIndexSpec } from './sync/syncPlan.js';
30
30
  import { type CredentialRefresher } from './sync/credentialLifecycle.js';
31
31
  import type { RehydrationStats } from './sync/bootstrapApply.js';
32
+ import type { ParticipantKind } from './transaction/types/participant.js';
32
33
  /** Constructor type for Model subclasses (accepts abstract classes) */
33
34
  export type ModelConstructor<T extends Model> = abstract new (...args: never[]) => T;
34
35
  /** Concrete constructor type for instantiation */
35
36
  export type ConcreteModelConstructor<T extends Model> = new (data?: any) => T;
36
- export type { ModelData } from './types/modelData.js';
37
+ export type { ModelData } from './transaction/types/modelData.js';
37
38
  /** Query result interface */
38
39
  export interface QueryResult<T extends Model> {
39
40
  data: T[];
@@ -47,6 +48,16 @@ export interface SyncedStoreConfig {
47
48
  enableOffline?: boolean;
48
49
  enableCache?: boolean;
49
50
  enableTelemetry?: boolean;
51
+ /**
52
+ * Wire message types to surface as collaboration events, e.g.
53
+ * `['document:selection', 'document:cursor']`.
54
+ *
55
+ * The vocabulary belongs to the application, not the SDK — these name the
56
+ * application's own concepts, and a schema with no documents should never see
57
+ * them. Defaults to none, so an application opts in by naming the events it
58
+ * actually broadcasts.
59
+ */
60
+ collaborationEvents?: readonly string[];
50
61
  /**
51
62
  * Declarative enrichment plan consumed by `enrichRelations`. Replaces
52
63
  * the subclass override of `enrichRelations` for per-model parent
@@ -75,7 +86,7 @@ export interface UserContext {
75
86
  * sessions; 'agent' for headless bots / worker processes. The
76
87
  * store routes this to SyncWebSocket so the WS URL carries
77
88
  * `kind=agent` and the server applies capability-token auth. */
78
- kind?: 'user' | 'agent' | 'system';
89
+ kind?: ParticipantKind;
79
90
  /** Restricted (`rk_`) API key for `kind: 'agent'` — the agent's
80
91
  * bearer credential. Sent in the `ablo.bearer.<token>` WebSocket
81
92
  * subprotocol, never in the URL. */
@@ -107,14 +118,20 @@ export interface SmartSyncOptions {
107
118
  maxBatchSize?: number;
108
119
  }
109
120
  export type { RehydrationStats } from './sync/bootstrapApply.js';
110
- /** Bootstrap timeout configuration */
121
+ /**
122
+ * Bootstrap retry configuration.
123
+ *
124
+ * There is deliberately no overall timeout here. How long one attempt may run
125
+ * is not a policy this layer gets to invent — it is a property of the fetcher's
126
+ * watchdogs, read from `BootstrapFetcher.budgetMs`. A second number kept here
127
+ * would only be able to disagree with them, which is exactly what it used to do.
128
+ */
111
129
  export declare const BOOTSTRAP_CONFIG: {
112
- readonly OVERALL_TIMEOUT_MS: 15000;
113
130
  readonly MAX_RETRY_ATTEMPTS: 3;
114
131
  readonly RETRY_DELAY_MS: 500;
115
132
  };
116
133
  export { ModelScope };
117
- export type { SyncDelta, SyncGroupChangePayload, GroupAddedPayload, GroupRemovedPayload, BootstrapHint, BootstrapDataEvent, PresenceUpdateEvent, };
134
+ export type { SyncDelta, SyncGroupChangePayload, GroupAddedPayload, GroupRemovedPayload, BootstrapHint, BootstrapDataEvent, PresenceUpdate, };
118
135
  export { deriveSyncPlanFromSchema } from './sync/syncPlan.js';
119
136
  /**
120
137
  * The abstract base class that application-specific sync stores extend. It
@@ -133,13 +150,13 @@ export { deriveSyncPlanFromSchema } from './sync/syncPlan.js';
133
150
  * the underlying SyncWebSocket without casts:
134
151
  *
135
152
  * @example
136
- * interface AbloEvents {
137
- * 'sheet:selection': [SheetSelectionEvent];
138
- * 'slide:cursor': [SlideCursorEvent];
153
+ * interface EditorEvents {
154
+ * 'document:selection': [SelectionEvent];
155
+ * 'document:cursor': [CursorEvent];
139
156
  * }
140
- * class SyncedStore extends BaseSyncedStore<AbloEvents> {
141
- * subscribeToSlideCursor(handler: (e: SlideCursorEvent) => void) {
142
- * return this.syncWebSocket?.subscribe('slide:cursor', handler);
157
+ * class EditorStore extends BaseSyncedStore<EditorEvents> {
158
+ * subscribeToCursor(handler: (e: CursorEvent) => void) {
159
+ * return this.syncWebSocket.subscribe('document:cursor', handler);
143
160
  * }
144
161
  * }
145
162
  */
@@ -155,15 +172,20 @@ export declare class BaseSyncedStore<TCollaboration extends EventMap<TCollaborat
155
172
  * `create(key, data)` factory and model self-healing.
156
173
  */
157
174
  protected readonly schema?: TSchema;
158
- protected syncWebSocket: SyncWebSocket<TCollaboration> | null;
175
+ /**
176
+ * The connection, owned by whoever built this store (ADR 0016 follow-up
177
+ * 3b): the host constructs it and hands it in, the store seeds its late
178
+ * values during `initialize()` and owns the lifecycle from there. One
179
+ * instance for the store's whole lifetime — reconnects replace the socket
180
+ * inside it, never the object.
181
+ */
182
+ protected readonly syncWebSocket: SyncWebSocket<TCollaboration>;
159
183
  /**
160
184
  * Dynamic read interest (area-of-interest) over the connection's sync
161
- * groups. Lives alongside `syncWebSocket` and is recreated with it; the
162
- * stable `enterScope`/`leaveScope`/`pinScope`/`unpinScope` methods forward
163
- * to whichever instance is current, so callers (the React participant
164
- * hook) never hold a stale reference. Null until `setupWebSocketSync`.
185
+ * groups. Constructed with the connection; the permanent base scopes are
186
+ * seeded in `setupWebSocketSync` once identity resolves.
165
187
  */
166
- protected areaOfInterest: SubscriptionManager | null;
188
+ protected readonly areaOfInterest: SubscriptionManager;
167
189
  /** Sync groups whose current state has been backfilled into the pool
168
190
  * (hydrate-on-enter). Cleared when the pool is reset on (re)bootstrap. */
169
191
  private readonly hydratedGroups;
@@ -171,15 +193,32 @@ export declare class BaseSyncedStore<TCollaboration extends EventMap<TCollaborat
171
193
  * enters of the same scope so they share one fetch. */
172
194
  private readonly hydratingGroups;
173
195
  private _syncServerUrl?;
196
+ /** Application-declared collaboration event types; empty unless configured. */
197
+ private _collaborationEvents;
174
198
  /**
175
199
  * Public accessor for the underlying SyncWebSocket. Used by the
176
200
  * factory in `createSyncEngine` to wire the default mutation
177
201
  * executor — the executor needs the WS handle to send commit
178
202
  * frames, and the factory can't reach `protected` state through
179
- * normal typing. Returns null until WS is initialized during
180
- * `initialize()`.
203
+ * normal typing.
204
+ */
205
+ getSyncWebSocket(): SyncWebSocket<TCollaboration>;
206
+ /**
207
+ * Subscribe to pushed frames — deltas, presence updates, claim grants and
208
+ * losses, connection changes, and this store's collaboration events.
209
+ * Durable by construction: the connection object exists for the store's
210
+ * whole lifetime (reconnects replace only the socket inside it), so a
211
+ * subscription made before the first connect starts delivering when the
212
+ * socket opens and keeps delivering across every reconnect. Returns the
213
+ * unsubscribe function.
181
214
  */
182
- getSyncWebSocket(): SyncWebSocket<TCollaboration> | null;
215
+ subscribe<K extends keyof SyncWebSocketEventMap<TCollaboration>>(event: K, handler: (...args: SyncWebSocketEventMap<TCollaboration>[K]) => void): () => void;
216
+ /**
217
+ * Send a collaboration event (an app-specific real-time message from this
218
+ * store's `TCollaboration` map). A no-op while the connection is down —
219
+ * presence-grade traffic is not queued.
220
+ */
221
+ sendCollaborationEvent<K extends string & keyof TCollaboration>(messageType: K, payload: TCollaboration[K] extends [infer P] ? Omit<P & Record<string, unknown>, 'timestamp'> : never): void;
183
222
  private scopeToGroups;
184
223
  /**
185
224
  * Bring a scope into view and subscribe to its sync groups. With
@@ -230,13 +269,15 @@ export declare class BaseSyncedStore<TCollaboration extends EventMap<TCollaborat
230
269
  protected pendingDeltas: SyncDelta[];
231
270
  protected batchTimer: ReturnType<typeof setTimeout> | null;
232
271
  protected syncPromise: Promise<void> | null;
233
- /** Resume/ack cursor — delegates to the shared SyncPosition (see
234
- * sync/syncPosition.ts). Advances only after IDB persistence. */
272
+ /** Resume/ack cursor — delegates to the shared LogPosition (see
273
+ * logPosition.ts). Advances only after IDB persistence. */
235
274
  protected get lastAckedId(): number;
236
- /** Pool-applied cursor — delegates to the shared SyncPosition. */
275
+ /** Pool-applied cursor — delegates to the shared LogPosition. */
237
276
  protected get highestProcessedSyncId(): number;
238
277
  protected bootstrapDeltaQueue: SyncDelta[] | null;
239
278
  protected activeBootstrapCount: number;
279
+ /** The live deadline for the bootstrap attempt in flight, if any. */
280
+ private bootstrapDeadlineTimer;
240
281
  protected pendingDeletes: Set<string>;
241
282
  protected modelTypesHydrated: Set<string>;
242
283
  protected modelTypeHydrationInFlight: Map<string, Promise<void>>;
@@ -245,6 +286,15 @@ export declare class BaseSyncedStore<TCollaboration extends EventMap<TCollaborat
245
286
  database: Database;
246
287
  objectPool: InstanceCache;
247
288
  modelRegistry: ModelRegistry;
289
+ /**
290
+ * The connection, built by the host. When omitted, the store constructs
291
+ * its own from `url` and the collaboration-event config — the
292
+ * self-contained path subclasses and tests use. Either way the store
293
+ * owns the lifecycle from here: it seeds the late values (identity,
294
+ * read scope, resume cursor) during `initialize()` and releases the
295
+ * first connect.
296
+ */
297
+ syncWebSocket?: SyncWebSocket<TCollaboration>;
248
298
  /**
249
299
  * Optional schema. When provided, {@link deriveSyncPlanFromSchema} walks
250
300
  * the schema's models and relations to auto-populate foreign-key indexes
@@ -331,7 +381,7 @@ export declare class BaseSyncedStore<TCollaboration extends EventMap<TCollaborat
331
381
  subscribeSessionError(listener: (error: Error) => void): () => void;
332
382
  /**
333
383
  * Subscribe to per-mutation failure payloads. Forwarded from the
334
- * underlying `SyncClient.transactionQueue` so consumers (toast layer,
384
+ * underlying `SyncClient.mutationQueue` so consumers (toast layer,
335
385
  * route-level reverted boundaries, telemetry) can react without
336
386
  * reaching across the store. Returns an unsubscribe function.
337
387
  *
@@ -342,10 +392,17 @@ export declare class BaseSyncedStore<TCollaboration extends EventMap<TCollaborat
342
392
  * same shape, same lifecycle.
343
393
  */
344
394
  subscribeMutationFailure(listener: (payload: {
345
- transaction: import('./transactions/TransactionQueue.js').Transaction;
395
+ transaction: import('./transactions/mutations/MutationQueue.js').QueuedMutation;
346
396
  error: Error;
347
397
  permanent?: boolean;
348
398
  }) => void): () => void;
399
+ /**
400
+ * Subscribe to commit round-trip latency. Forwarded from the underlying
401
+ * `SyncClient` for the same reason as `subscribeMutationFailure` — the
402
+ * React provider binds against this surface, so the engine's wiring stays
403
+ * private while the SDK keeps one hook to expose.
404
+ */
405
+ subscribeCommitLatency(listener: (sample: import('./transactions/mutations/commitLatency.js').CommitLatencySample) => void): () => void;
349
406
  /**
350
407
  * Wait for the in-flight transaction for (modelName, modelId) to be
351
408
  * confirmed by the server. See `SyncClient.waitForConfirmation` for the
@@ -355,7 +412,7 @@ export declare class BaseSyncedStore<TCollaboration extends EventMap<TCollaborat
355
412
  /**
356
413
  * Observe the LOCAL mutation stream for undo recording (see
357
414
  * {@link import('./core/storeContract.js').LocalMutation}). Taps the
358
- * TransactionQueue's `transaction:created` event — fired once per local
415
+ * MutationQueue's `transaction:created` event — fired once per local
359
416
  * create/update/delete/archive with `previousData` already captured.
360
417
  * Remote/collaborator deltas apply via `applyDeltaBatchToPool` and never
361
418
  * emit here, so undo is naturally local-only (you can't undo a teammate).
@@ -366,8 +423,29 @@ export declare class BaseSyncedStore<TCollaboration extends EventMap<TCollaborat
366
423
  * Prevents the common issue where bootstrap hangs on startup.
367
424
  */
368
425
  protected executeBootstrapWithTimeout<T>(bootstrapFn: () => Promise<T>, _context: UserContext, signal?: AbortSignal): Promise<T>;
369
- /** Create a timeout promise for bootstrap attempts */
426
+ /**
427
+ * The outer deadline for one bootstrap attempt.
428
+ *
429
+ * The length is DERIVED from the fetcher's own watchdog budget, not chosen. A
430
+ * chosen number is what broke this: the previous fixed 15s was shorter than a
431
+ * single model chunk's allowance — 20s waiting for response headers plus 15s
432
+ * of stall grace — so on any workspace with one slow model the deadline fired
433
+ * before the watchdogs it was meant to backstop, and every attempt timed out
434
+ * by construction. The watchdogs below are progress-based and already
435
+ * guarantee termination; this deadline exists only for a hang somewhere other
436
+ * than the network, so it must sit above them, and it can only do that
437
+ * reliably by asking them how long they take.
438
+ *
439
+ * Reaching it aborts the work in flight. `Promise.race` merely stops waiting:
440
+ * without the abort the losing bootstrap keeps running, keeps its sockets, and
441
+ * races the retry that replaced it — which is how one page load turned into
442
+ * dozens of overlapping requests.
443
+ */
370
444
  protected createBootstrapTimeout(attempt: number): Promise<never>;
445
+ /** Disarm the deadline once its attempt has settled. Load-bearing now that
446
+ * firing it aborts real work: a leftover timer would cancel a later,
447
+ * unrelated bootstrap. */
448
+ private clearBootstrapDeadline;
371
449
  /** Reset bootstrap-related state for a clean retry */
372
450
  protected resetBootstrapState(): void;
373
451
  /** Perform reconnect: bootstrap + WS reconnect. Returns outcome for state machine. */
@@ -495,8 +573,15 @@ export declare class BaseSyncedStore<TCollaboration extends EventMap<TCollaborat
495
573
  * driven session" vs "is this a server agent". The latter never has
496
574
  * a tab to lose focus or a network adapter to wake up.
497
575
  */
498
- protected createConnectionManager(kind?: 'user' | 'agent' | 'system'): ConnectionManager | null;
499
- /** Disconnect and clean up all resources */
576
+ protected createConnectionManager(kind?: ParticipantKind): ConnectionManager | null;
577
+ /**
578
+ * Disconnect and clean up all resources. Terminal: this means "the client
579
+ * is finished", not "close and reopen later" — the connection object stays
580
+ * assigned but closed, the event wiring is torn down, and nothing
581
+ * re-initializes a disconnected store. (Mid-session closes during recovery
582
+ * go through the connection FSM's `onDisconnectWebSocket`, which closes
583
+ * the transport without touching the store.)
584
+ */
500
585
  disconnect(): Promise<void>;
501
586
  /**
502
587
  * Destroy every IndexedDB database owned by the sync engine.
@@ -535,7 +620,30 @@ export declare class BaseSyncedStore<TCollaboration extends EventMap<TCollaborat
535
620
  * mutation attempt surface a clearer error.
536
621
  */
537
622
  protected waitForWebSocketConnected(timeoutMs: number): Promise<boolean>;
623
+ /**
624
+ * Seed the connection's late values and open it. The socket itself exists
625
+ * from construction; what identity resolution supplies — the participant
626
+ * kind, the credential, the read scope, and the resume cursor — is seeded
627
+ * here, and only then is the held first connect released. A retried
628
+ * `initialize()` after a failed `ready()` re-runs this against the same
629
+ * connection object: the reconnect counter is reset for a clean slate,
630
+ * while the session-error latch deliberately survives (only the
631
+ * credential-expiry recovery clears it).
632
+ */
538
633
  protected setupWebSocketSync(context: UserContext, lastSyncId: number): void;
634
+ /**
635
+ * Wire the store's handlers onto the connection. Runs once, at
636
+ * construction — the connection object is stable for the store's
637
+ * lifetime, so the wiring is too.
638
+ */
639
+ protected wireSocketEvents(): void;
640
+ /**
641
+ * Build and start the connection FSM. The `onConnectionEvent` hook is the
642
+ * bridge — WS events fire the hook, the hook forwards into the FSM. Called
643
+ * from `setupWebSocketSync` because the FSM's shape depends on the resolved
644
+ * participant kind (agents get none — see {@link createConnectionManager}).
645
+ */
646
+ private startConnectionManager;
539
647
  /** Memoized pipeline context — `enqueueDelta` runs once per delta, so the
540
648
  * accessor object is built once and reused (the get/set accessors always
541
649
  * read the live host fields). */
@@ -590,7 +698,7 @@ export declare class BaseSyncedStore<TCollaboration extends EventMap<TCollaborat
590
698
  * schema build time) to find children. The previous implementation did
591
699
  * `getByType(ctor).filter(e => e.toJSON()[foreignKey] === parentId)` —
592
700
  * a full pool scan per child model + a `toJSON()` allocation per
593
- * candidate. For a deck delete with 10K layers in the pool, that was
701
+ * candidate. For a report delete with 10K blocks in the pool, that was
594
702
  * 10K toJSON allocations per cascade level. The FK-indexed lookup
595
703
  * skips both the scan AND the allocation.
596
704
  */
@@ -605,7 +713,7 @@ export declare class BaseSyncedStore<TCollaboration extends EventMap<TCollaborat
605
713
  * Save a model (create or update).
606
714
  *
607
715
  * Accepts any entity shape with `{ id: string }` so consumers can pass the
608
- * Zod-inferred model types from `InferModel<Schema, K>` without knowing
716
+ * Zod-inferred model types from `Model<Schema, K>` without knowing
609
717
  * about the internal `Model` base class. At runtime, every entity reaching
610
718
  * this method came through the object pool (via `store.create`, a query
611
719
  * accessor, or an optimistic insert) and IS a `Model` instance — the one
@@ -618,7 +726,7 @@ export declare class BaseSyncedStore<TCollaboration extends EventMap<TCollaborat
618
726
  }>(entity: T, options?: {
619
727
  skipValidation?: boolean;
620
728
  }): Promise<void>;
621
- /** Save with an atomic server mutation (e.g., createSlideWithLayers) */
729
+ /** Save with an atomic server mutation (e.g., createSectionWithBlocks) */
622
730
  saveWithAtomicMutation(model: Model, mutation: (gql: unknown) => Promise<unknown>): Promise<void>;
623
731
  /** Delete a model. Accepts schema-inferred entity shapes (see `save`). */
624
732
  delete<T extends {
@@ -648,17 +756,17 @@ export declare class BaseSyncedStore<TCollaboration extends EventMap<TCollaborat
648
756
  * Create a model instance locally, typed via the schema.
649
757
  *
650
758
  * ```ts
651
- * const sheet = store.create('spreadsheetSheets', { name, spreadsheetId });
652
- * // sheet: SpreadsheetSheet | null — no cast needed
759
+ * const ledger = store.create('ledgers', { name, reportId });
760
+ * // ledger: Ledger | null — no cast needed
653
761
  * ```
654
762
  *
655
763
  * The `typename` arg is the schema key (camelCase plural, e.g.
656
- * `'spreadsheetSheets'`); the returned instance has the
657
- * `InferModel<Schema, K>` shape including computeds + relation accessors.
764
+ * `'ledgers'`); the returned instance has the
765
+ * `Model<Schema, K>` shape including computeds + relation accessors.
658
766
  * Wraps `pool.create(...)` — the underlying runtime is unchanged, just
659
767
  * type-narrowed.
660
768
  */
661
- create<K extends keyof TSchema['models'] & string>(typename: K, data: Record<string, unknown>): import('./schema/schema.js').InferModel<TSchema, K> | null;
769
+ create<K extends keyof TSchema['models'] & string>(typename: K, data: Record<string, unknown>): import('./transaction/schema/schema.js').Model<TSchema, K> | null;
662
770
  /**
663
771
  * Query entry point for callers that hold a {@link Model} constructor and an
664
772
  * options object. It filters, orders, and paginates the matching models from
@@ -676,7 +784,7 @@ export declare class BaseSyncedStore<TCollaboration extends EventMap<TCollaborat
676
784
  /**
677
785
  * Get all models of a type. Returns Model[] honestly — callers that need
678
786
  * narrow types should use `useAblo((ablo) => ablo.<model>.list(...))`
679
- * which does proper inference via `InferModel<S, K>`.
787
+ * which does proper inference via `Model<S, K>`.
680
788
  */
681
789
  allModelsOfType(modelClass: ModelConstructor<Model>, scope?: ModelScope): Model[];
682
790
  /** Error handler for fire-and-forget flushPendingDeltas calls */
@@ -688,7 +796,7 @@ export declare class BaseSyncedStore<TCollaboration extends EventMap<TCollaborat
688
796
  /** Handle bootstrap_data event. Override in subclass. */
689
797
  protected handleBootstrapData(_data: BootstrapDataEvent): void;
690
798
  /** Handle presence_update event. Override in subclass. */
691
- protected handlePresenceUpdate(_data: PresenceUpdateEvent): void;
799
+ protected handlePresenceUpdate(_data: PresenceUpdate): void;
692
800
  protected incrementPendingChanges(): void;
693
801
  protected decrementPendingChanges(): void;
694
802
  protected updateSyncStatus(updates: Partial<SyncStatus>): void;