@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
@@ -1,116 +1,8 @@
1
1
  /**
2
- * Routes each inbound frame from the sync WebSocket to the handler for its
3
- * type. Handlers work against a minimal {@link WsSession} interface only
4
- * the members they actually touch, rather than the transport object itself,
5
- * which keeps this module free of an import cycle. Reading a message off the
6
- * socket, parsing its JSON, and tracking heartbeats all happen before this
7
- * point; every parsed frame then passes through {@link dispatchWsFrame}.
2
+ * Moved to the settlement core with the duplex transport (ADR 0016): the
3
+ * inbound frame dispatch is the receiving half of the wire protocol, and the
4
+ * handlers already worked against the minimal `WsSession` port rather than
5
+ * the transport object. This path re-exports it so existing importers stay
6
+ * unchanged.
8
7
  */
9
- import { type CommitAck } from './commitFrames.js';
10
- /**
11
- * In-flight `commit` request record, keyed by clientTxId in the session.
12
- * Resolved when a matching `mutation_result` frame arrives from the
13
- * server, or rejected on timeout / disconnect.
14
- */
15
- export interface PendingCommit {
16
- resolve: (value: CommitAck) => void;
17
- reject: (err: Error) => void;
18
- timeout: ReturnType<typeof setTimeout>;
19
- }
20
- /**
21
- * In-flight `claim` request record, keyed by claimId. Resolved when the
22
- * matching `claim_ack` arrives, or rejected on timeout/disconnect.
23
- */
24
- export interface PendingClaim {
25
- resolve: (value: {
26
- syncGroups: string[];
27
- ttlSeconds?: number;
28
- }) => void;
29
- reject: (err: Error) => void;
30
- timeout: ReturnType<typeof setTimeout>;
31
- }
32
- /**
33
- * An in-flight `update_subscription` request awaiting its
34
- * `subscription_ack`. The wire carries no correlation id, so requests are
35
- * matched to their acknowledgements in first-in, first-out order, the same
36
- * order the server applies them.
37
- */
38
- export interface PendingSubscription {
39
- resolve: (value: {
40
- syncGroups: string[];
41
- }) => void;
42
- reject: (err: Error) => void;
43
- timeout: ReturnType<typeof setTimeout>;
44
- }
45
- /**
46
- * A parsed inbound wire frame, straight from `JSON.parse`. The data is
47
- * untrusted: every payload is loosely typed, and each handler narrows it
48
- * defensively before use.
49
- */
50
- export interface WsInboundFrame {
51
- type?: string;
52
- payload?: unknown;
53
- /** Some delta frames carry their delta fields at the top level rather than under `payload`. */
54
- actionType?: unknown;
55
- modelName?: unknown;
56
- [key: string]: unknown;
57
- }
58
- /** Narrow arbitrary wire data to a plain string-keyed record. */
59
- export declare function isRecord(value: unknown): value is Record<string, unknown>;
60
- /**
61
- * A type guard for the parsed result of an inbound message. A frame is any
62
- * plain object whose `type`, when present, is a string. Validating the
63
- * payload itself is left to each handler; delta payloads, for example, are
64
- * checked against the canonical delta schema before they are applied.
65
- */
66
- export declare function isWsInboundFrame(value: unknown): value is WsInboundFrame;
67
- /**
68
- * The subset of the sync WebSocket that the frame handlers need. The
69
- * transport builds a single object exposing these members over its own
70
- * private state. Handlers read the fields live rather than capturing them,
71
- * so resetting a field elsewhere — such as clearing pending subscriptions
72
- * on close — never leaves a handler holding a stale value.
73
- */
74
- export interface WsSession {
75
- /** EventEmitter surface — handlers emit the typed transport events. */
76
- emit(event: string, ...args: unknown[]): boolean;
77
- /** In-flight commit acks keyed by clientTxId. */
78
- pendingMutations: Map<string, PendingCommit>;
79
- /** In-flight claim acks keyed by claimId. */
80
- pendingClaims: Map<string, PendingClaim>;
81
- /** Removes and returns the oldest in-flight `update_subscription` request. */
82
- shiftPendingSubscription(): PendingSubscription | undefined;
83
- /** Connection options subset the handlers write back (acked sync groups). */
84
- options: {
85
- syncGroups: string[];
86
- };
87
- /** Registered collaboration event keys (colon format). */
88
- collaborationEventTypes: ReadonlySet<string>;
89
- /**
90
- * Processes one inbound delta. The argument is untrusted wire data; the
91
- * transport validates it against the canonical delta schema and drops
92
- * anything malformed, so handlers here never cast.
93
- */
94
- handleDelta(delta: unknown): void;
95
- handleSyncResponse(payload: unknown): void;
96
- handleBootstrapResponse(payload: unknown): void;
97
- handlePresenceUpdate(message: {
98
- payload?: unknown;
99
- [k: string]: unknown;
100
- }): void;
101
- }
102
- export type WsFrameHandler = (session: WsSession, message: WsInboundFrame) => void;
103
- /**
104
- * Maps each frame type to its handler. Every named server frame this
105
- * package understands is dispatched from this table; anything else falls
106
- * through to the collaboration-event and unknown-type path in
107
- * {@link dispatchWsFrame}.
108
- */
109
- export declare const wsFrameHandlers: Record<string, WsFrameHandler>;
110
- /**
111
- * Routes one parsed inbound frame to its handler. Keepalive frames are
112
- * ignored, a missing `type` is treated as a bare delta, and any unknown
113
- * type falls through to the collaboration-event map, whose wire names use
114
- * underscores and whose event keys use colons.
115
- */
116
- export declare function dispatchWsFrame(session: WsSession, message: WsInboundFrame): void;
8
+ export { isRecord, readWsInboundFrame, wsFrameHandlers, dispatchWsFrame, type PendingCommit, type PendingClaim, type PendingSubscription, type WsInboundFrame, type WsSession, type WsFrameHandler, } from '../transaction/transport/wsFrameHandlers.js';
@@ -1,394 +1,8 @@
1
1
  /**
2
- * Routes each inbound frame from the sync WebSocket to the handler for its
3
- * type. Handlers work against a minimal {@link WsSession} interface only
4
- * the members they actually touch, rather than the transport object itself,
5
- * which keeps this module free of an import cycle. Reading a message off the
6
- * socket, parsing its JSON, and tracking heartbeats all happen before this
7
- * point; every parsed frame then passes through {@link dispatchWsFrame}.
2
+ * Moved to the settlement core with the duplex transport (ADR 0016): the
3
+ * inbound frame dispatch is the receiving half of the wire protocol, and the
4
+ * handlers already worked against the minimal `WsSession` port rather than
5
+ * the transport object. This path re-exports it so existing importers stay
6
+ * unchanged.
8
7
  */
9
- import { getContext } from '../context.js';
10
- import { AbloConnectionError, CapabilityError, errorFromWire, } from '../errors.js';
11
- import { commitAckSchema, legacyCompatibleCommitReceiptSchema, } from '../wire/commit.js';
12
- import { subscriptionAckPayloadSchema } from '../coordination/schema.js';
13
- import { formatConflict } from '../coordination/trace.js';
14
- import { parseNotifications, recordClaim } from './commitFrames.js';
15
- /** Narrow arbitrary wire data to a plain string-keyed record. */
16
- export function isRecord(value) {
17
- return typeof value === 'object' && value !== null && !Array.isArray(value);
18
- }
19
- /**
20
- * A type guard for the parsed result of an inbound message. A frame is any
21
- * plain object whose `type`, when present, is a string. Validating the
22
- * payload itself is left to each handler; delta payloads, for example, are
23
- * checked against the canonical delta schema before they are applied.
24
- */
25
- export function isWsInboundFrame(value) {
26
- if (!isRecord(value))
27
- return false;
28
- const type = value.type;
29
- return type === undefined || typeof type === 'string';
30
- }
31
- /**
32
- * Handles the acknowledgement of a `commit` request. The canonical wire
33
- * shape is `MutationResultMessage`. The payload is parsed defensively
34
- * rather than cast, since it is untrusted and may be malformed or sent by
35
- * an older server.
36
- */
37
- const handleMutationResult = (session, message) => {
38
- const p = (message.payload ?? message);
39
- const { clientTxId, success, error } = p;
40
- // Defensive: validate notifications against the canonical schema —
41
- // untrusted wire data from a possibly-older/newer server.
42
- const notifications = parseNotifications(p?.notifications);
43
- const missingIds = Array.isArray(p.missingIds)
44
- ? [
45
- ...new Set(p.missingIds.filter((id) => typeof id === 'string' && id.length > 0)),
46
- ]
47
- : undefined;
48
- const pending = typeof clientTxId === 'string'
49
- ? session.pendingMutations.get(clientTxId)
50
- : undefined;
51
- if (!pending)
52
- return;
53
- clearTimeout(pending.timeout);
54
- // `pending` exists ⇒ clientTxId was a string key (the guard above).
55
- session.pendingMutations.delete(clientTxId);
56
- if (success) {
57
- const parsedReceipt = legacyCompatibleCommitReceiptSchema.safeParse({
58
- ...p,
59
- notifications,
60
- missingIds,
61
- });
62
- if (!parsedReceipt.success) {
63
- pending.reject(new AbloConnectionError('The sync server returned an invalid commit receipt; its outcome remains pending and is safe to retry.', { code: 'commit_no_result', cause: parsedReceipt.error }));
64
- return;
65
- }
66
- const receipt = parsedReceipt.data;
67
- // The write succeeded, but a guarded premise shifted underneath it.
68
- // Emit the advisory signal so a caller can react, and still resolve
69
- // the receipt, since the commit itself went through.
70
- if (receipt.notifications && receipt.notifications.length > 0) {
71
- const txId = receipt.clientTxId;
72
- const event = {
73
- clientTxId: txId,
74
- rows: receipt.notifications.map((n) => ({
75
- model: n.model,
76
- id: n.id,
77
- fields: n.conflictingFields,
78
- writtenBy: n.writtenBy.kind,
79
- })),
80
- };
81
- const message = formatConflict(event);
82
- const ctx = getContext();
83
- ctx.logger.warn(message);
84
- ctx.observability.breadcrumb(message, 'sync.coordination', 'warning');
85
- ctx.observability.captureConflict(event);
86
- session.emit('conflict:notified', {
87
- clientTxId: txId,
88
- notifications: receipt.notifications,
89
- });
90
- }
91
- pending.resolve(commitAckSchema.parse({
92
- status: receipt.status,
93
- ...(receipt.correlationId
94
- ? { correlationId: receipt.correlationId }
95
- : {}),
96
- lastSyncId: receipt.lastSyncId,
97
- ...(receipt.notifications && receipt.notifications.length > 0
98
- ? { notifications: receipt.notifications }
99
- : {}),
100
- ...(receipt.missingIds && receipt.missingIds.length > 0
101
- ? { missingIds: receipt.missingIds }
102
- : {}),
103
- }));
104
- }
105
- else {
106
- // Capture the full server error so the caller can see what actually
107
- // rejected the mutation, rather than a generic "mutation failed on
108
- // server". Object errors are stringified so structured server payloads,
109
- // such as validation issues, survive being wrapped in an Error.
110
- let errorMessage;
111
- let errorCode;
112
- let requiredCapability;
113
- if (typeof error === 'string') {
114
- errorMessage = error;
115
- }
116
- else if (error != null && typeof error === 'object') {
117
- const obj = error;
118
- if (typeof obj.code === 'string')
119
- errorCode = obj.code;
120
- if (typeof obj.message === 'string') {
121
- errorMessage = obj.message;
122
- }
123
- else {
124
- try {
125
- errorMessage = JSON.stringify(error);
126
- }
127
- catch {
128
- errorMessage = String(error);
129
- }
130
- }
131
- if (obj.requiredCapability != null &&
132
- typeof obj.requiredCapability === 'object' &&
133
- typeof obj.requiredCapability.scope === 'string') {
134
- requiredCapability = obj.requiredCapability;
135
- }
136
- }
137
- else {
138
- errorMessage = 'mutation failed on server';
139
- }
140
- // A stale-context rejection (the write read state that has since
141
- // changed) or a foreign-claim conflict is a coordination collision.
142
- // The success-with-notifications path above records the conflict, and a
143
- // hard rejection must record it too, or the collision count would miss
144
- // every rejected write. The conflicting rows ride along on the typed
145
- // error's `conflicts` detail.
146
- if (errorCode === 'stale_context' ||
147
- errorCode === 'claim_conflict' ||
148
- errorCode === 'entity_claimed' ||
149
- errorCode?.startsWith('policy:') === true) {
150
- const rawConflicts = error != null &&
151
- typeof error === 'object' &&
152
- Array.isArray(error.conflicts)
153
- ? error
154
- .conflicts
155
- : [];
156
- const conflictEvent = {
157
- clientTxId: typeof clientTxId === 'string' ? clientTxId : '',
158
- rows: rawConflicts.map((r) => ({
159
- model: typeof r.model === 'string' ? r.model : 'unknown',
160
- id: typeof r.id === 'string' ? r.id : 'unknown',
161
- fields: [],
162
- })),
163
- };
164
- const ctx = getContext();
165
- ctx.observability.breadcrumb(formatConflict(conflictEvent), 'sync.coordination', 'warning');
166
- ctx.observability.captureConflict(conflictEvent);
167
- }
168
- // Build the proper typed AbloError from the wire code via the
169
- // shared factory — the same code→class mapping the HTTP commit
170
- // path uses (`translateHttpError`). This keeps rejected commits
171
- // inside the typed hierarchy (capability denials →
172
- // CapabilityError with `.requiredCapability`; foreign-claim
173
- // conflicts → AbloClaimedError; everything else → the subclass
174
- // its registry `httpStatus` implies) instead of a hand-rolled
175
- // `new Error`, so callers can `instanceof`/`e.type` it and
176
- // downstream retry logic can read the contract's retryability.
177
- pending.reject(errorFromWire(errorMessage, {
178
- code: errorCode,
179
- requiredCapability,
180
- }));
181
- }
182
- };
183
- /**
184
- * Handles the acknowledgement of a `claim` request. The frame has the shape
185
- * `{ type: 'claim_ack', payload: { claimId, success, syncGroups?,
186
- * ttlSeconds?, error? } }`.
187
- */
188
- const handleClaimAck = (session, message) => {
189
- const p = (message.payload ?? {});
190
- const { claimId, success, syncGroups, ttlSeconds, error } = p;
191
- const pending = typeof claimId === 'string'
192
- ? session.pendingClaims.get(claimId)
193
- : undefined;
194
- if (!pending)
195
- return;
196
- clearTimeout(pending.timeout);
197
- // `pending` exists ⇒ claimId was a string key (the guard above).
198
- session.pendingClaims.delete(claimId);
199
- if (success) {
200
- pending.resolve({
201
- syncGroups: Array.isArray(syncGroups) ? syncGroups : [],
202
- ttlSeconds: typeof ttlSeconds === 'number' ? ttlSeconds : undefined,
203
- });
204
- }
205
- else {
206
- const err = error;
207
- const code = err?.code && typeof err.code === 'string'
208
- ? err.code
209
- : 'claim_rejected';
210
- const msg = err?.message && typeof err.message === 'string'
211
- ? err.message
212
- : 'claim rejected by server';
213
- // Capability denials get the typed CapabilityError so
214
- // callers can read `.requiredCapability` and attenuate-
215
- // and-retry the claim with a narrower token.
216
- if (code === 'capability_scope_denied' ||
217
- code === 'capability_invalid') {
218
- const rc = error
219
- ?.requiredCapability;
220
- const requiredCapability = rc != null &&
221
- typeof rc === 'object' &&
222
- typeof rc.scope === 'string'
223
- ? rc
224
- : undefined;
225
- pending.reject(new CapabilityError(code, msg, requiredCapability));
226
- }
227
- else {
228
- // Route through the shared factory so a failed claim_ack is a
229
- // typed AbloError (registry code → right subclass), symmetric
230
- // with the commit `mutation_result` path — never a bare Error.
231
- pending.reject(errorFromWire(msg, { code }));
232
- }
233
- }
234
- };
235
- /**
236
- * Handles the acknowledgement of an `update_subscription` request. The wire
237
- * carries no correlation id, so the ack is matched to the oldest pending
238
- * request in first-in, first-out order, since the server applies and
239
- * acknowledges subscription updates in the order it receives them. The
240
- * payload is validated against its canonical schema before use.
241
- */
242
- const handleSubscriptionAck = (session, message) => {
243
- const pending = session.shiftPendingSubscription();
244
- if (!pending)
245
- return;
246
- clearTimeout(pending.timeout);
247
- const parsed = subscriptionAckPayloadSchema.safeParse(message.payload);
248
- if (!parsed.success) {
249
- // Unreadable ack — resolve the pending request as a failure
250
- // rather than hang it until timeout.
251
- pending.reject(errorFromWire('malformed subscription_ack from server', {
252
- code: 'malformed_subscription',
253
- }));
254
- return;
255
- }
256
- const ack = parsed.data;
257
- if (ack.success) {
258
- // Keep the reconnect URL aligned with current interest: a
259
- // reconnect re-subscribes from `this.options.syncGroups`.
260
- session.options.syncGroups = ack.syncGroups;
261
- pending.resolve({ syncGroups: ack.syncGroups });
262
- }
263
- else {
264
- pending.reject(errorFromWire(ack.error?.message ?? 'update_subscription rejected by server', { code: ack.error?.code ?? 'malformed_subscription' }));
265
- }
266
- };
267
- /**
268
- * Handles a `delta` frame, which carries either a single delta or a
269
- * `{ deltas: [...] }` batch. This only tells the two shapes apart; each
270
- * delta is validated once downstream, so batch elements are passed along
271
- * raw rather than parsed here.
272
- */
273
- const handleDeltaFrame = (session, message) => {
274
- const p = message.payload;
275
- if (!isRecord(p))
276
- return;
277
- if (p.actionType || p.modelName) {
278
- session.handleDelta(p);
279
- }
280
- else if (Array.isArray(p.deltas)) {
281
- for (const d of p.deltas) {
282
- session.handleDelta(d);
283
- }
284
- // `p.newVersions` from older servers is ignored; `sync_id` is the
285
- // causality token.
286
- }
287
- };
288
- /**
289
- * Maps each frame type to its handler. Every named server frame this
290
- * package understands is dispatched from this table; anything else falls
291
- * through to the collaboration-event and unknown-type path in
292
- * {@link dispatchWsFrame}.
293
- */
294
- export const wsFrameHandlers = {
295
- sync_response: (session, message) => { session.handleSyncResponse(message.payload); },
296
- bootstrap_response: (session, message) => { session.handleBootstrapResponse(message.payload); },
297
- presence_update: (session, message) => { session.handlePresenceUpdate(message); },
298
- mutation_result: handleMutationResult,
299
- claim_ack: handleClaimAck,
300
- subscription_ack: handleSubscriptionAck,
301
- claim_expired: (session, message) => {
302
- // Server-initiated expiry notification. Emit as a typed
303
- // event so consumers can react (re-claim with a fresh
304
- // capability, or accept the drop). The claim is already
305
- // inactive server-side by the time this arrives.
306
- const p = (message.payload ?? {});
307
- if (typeof p.claimId === 'string') {
308
- recordClaim('expired', p);
309
- session.emit('claim_expired', { claimId: p.claimId });
310
- }
311
- },
312
- claim_rejected: (session, message) => {
313
- // The server denied a claim because the target is already held by
314
- // another participant. The payload is forwarded as-is for the claim
315
- // stream consumer to interpret (peerId, target, and so on).
316
- recordClaim('rejected', (message.payload ?? {}));
317
- session.emit('claim_rejected', message.payload ?? {});
318
- },
319
- claim_acquired: (session, message) => {
320
- // Opt-in fair queue: the target was free, so the lease is ours
321
- // immediately (no waiting). Payload carries { claimId, target }.
322
- recordClaim('acquired', (message.payload ?? {}));
323
- session.emit('claim_acquired', message.payload ?? {});
324
- },
325
- claim_queue: (session, message) => {
326
- // Per-entity wait-queue snapshot for reactive `queue(id)`. Not a
327
- // single claim's state change, so it isn't logged — the per-claim
328
- // `queued`/`granted` events already tell that story.
329
- session.emit('claim_queue', message.payload ?? {});
330
- },
331
- claim_queued: (session, message) => {
332
- // Opt-in fair queue: our claim is waiting in line. Payload
333
- // carries { claimId, target, position }.
334
- recordClaim('queued', (message.payload ?? {}));
335
- session.emit('claim_queued', message.payload ?? {});
336
- },
337
- claim_granted: (session, message) => {
338
- // Our queued claim reached the head — the lease is now ours.
339
- recordClaim('granted', (message.payload ?? {}));
340
- session.emit('claim_granted', message.payload ?? {});
341
- },
342
- claim_lost: (session, message) => {
343
- // A held/granted claim was taken from us (TTL lapse, revoke).
344
- recordClaim('lost', (message.payload ?? {}));
345
- session.emit('claim_lost', message.payload ?? {});
346
- },
347
- claim_heartbeat_ack: (session, message) => {
348
- // Reply to our `claim_heartbeat` — the claim stream correlates it back
349
- // to the awaiting caller by claimId. Not logged per-frame: heartbeats
350
- // are a cadence, and the interesting transitions (lost) surface through
351
- // the caller's error path.
352
- session.emit('claim_heartbeat_ack', message.payload ?? {});
353
- },
354
- delta: handleDeltaFrame,
355
- };
356
- /**
357
- * Routes one parsed inbound frame to its handler. Keepalive frames are
358
- * ignored, a missing `type` is treated as a bare delta, and any unknown
359
- * type falls through to the collaboration-event map, whose wire names use
360
- * underscores and whose event keys use colons.
361
- */
362
- export function dispatchWsFrame(session, message) {
363
- if (message.type === 'pong' || message.type === 'ping') {
364
- // Ignore keepalive messages
365
- getContext().logger.debug('Received keepalive', { type: message.type });
366
- return;
367
- }
368
- if (message.type === undefined) {
369
- // A bare delta, validated downstream like every other delta.
370
- if (message.actionType || message.modelName) {
371
- session.handleDelta(message);
372
- }
373
- return;
374
- }
375
- // Look up own properties only, so a wire type like 'toString' can't match
376
- // an inherited Object.prototype member; such types fall through to the
377
- // unknown-type path.
378
- const handler = Object.prototype.hasOwnProperty.call(wsFrameHandlers, message.type)
379
- ? wsFrameHandlers[message.type]
380
- : undefined;
381
- if (handler) {
382
- handler(session, message);
383
- return;
384
- }
385
- // Collaboration events use underscore wire format (e.g., 'sheet_selection')
386
- // Convert to colon format for the event map (e.g., 'sheet:selection')
387
- const eventKey = message.type?.replace(/_/g, ':');
388
- if (eventKey && session.collaborationEventTypes.has(eventKey)) {
389
- session.emit(eventKey, message.payload);
390
- }
391
- else {
392
- getContext().logger.debug('Received unknown message type', { message });
393
- }
394
- }
8
+ export { isRecord, readWsInboundFrame, wsFrameHandlers, dispatchWsFrame, } from '../transaction/transport/wsFrameHandlers.js';
@@ -0,0 +1,20 @@
1
+ /** Canonical sync-log identity and position contracts shared by client/server. */
2
+ import { z } from 'zod';
3
+ export declare const deltaPositionSchema: z.ZodNumber;
4
+ export type DeltaPosition = z.infer<typeof deltaPositionSchema>;
5
+ export declare const clientMutationIdSchema: z.ZodString;
6
+ export type ClientMutationId = z.infer<typeof clientMutationIdSchema>;
7
+ export declare const sourceCorrelationIdSchema: z.ZodString;
8
+ export type SourceCorrelationId = z.infer<typeof sourceCorrelationIdSchema>;
9
+ export declare const sourceChangeIdSchema: z.ZodString;
10
+ export type SourceChangeId = z.infer<typeof sourceChangeIdSchema>;
11
+ export declare const replicationLsnSchema: z.ZodString;
12
+ export type ReplicationLSN = z.infer<typeof replicationLsnSchema>;
13
+ export declare const commitDispatchMarkerSchema: z.ZodObject<{
14
+ kind: z.ZodLiteral<"sync_deltas">;
15
+ organizationId: z.ZodString;
16
+ environment: z.ZodString;
17
+ firstSyncId: z.ZodNumber;
18
+ lastSyncId: z.ZodNumber;
19
+ }, z.core.$strict>;
20
+ export type CommitDispatchMarker = z.infer<typeof commitDispatchMarkerSchema>;
@@ -0,0 +1,19 @@
1
+ /** Canonical sync-log identity and position contracts shared by client/server. */
2
+ import { z } from 'zod';
3
+ import { environmentSchema } from '../environment.js';
4
+ export const deltaPositionSchema = z.number().int().nonnegative().safe();
5
+ export const clientMutationIdSchema = z.string().min(1).max(255);
6
+ export const sourceCorrelationIdSchema = z.string().min(1).max(255);
7
+ export const sourceChangeIdSchema = z.string().min(1).max(512);
8
+ export const replicationLsnSchema = z.string().regex(/^[0-9A-Fa-f]+\/[0-9A-Fa-f]+$/);
9
+ export const commitDispatchMarkerSchema = z.strictObject({
10
+ kind: z.literal('sync_deltas'),
11
+ organizationId: z.string().min(1),
12
+ environment: environmentSchema,
13
+ firstSyncId: deltaPositionSchema,
14
+ lastSyncId: deltaPositionSchema,
15
+ }).superRefine((value, ctx) => {
16
+ if (value.firstSyncId <= 0 || value.lastSyncId < value.firstSyncId) {
17
+ ctx.addIssue({ code: 'custom', message: 'invalid delta position range' });
18
+ }
19
+ });
@@ -0,0 +1 @@
1
+ export * from './contract.js';
@@ -0,0 +1 @@
1
+ export * from './contract.js';
@@ -0,0 +1,88 @@
1
+ /**
2
+ * `Ablo` — the entry point to the coordination layer.
3
+ *
4
+ * The factory constructs the stateless client: typed model resources, commits,
5
+ * claims, and session minting over request/response HTTP. It holds no socket,
6
+ * no store, and no local copy of anything — the bearer credential is the
7
+ * identity and the server resolves it on every request. This is the client a
8
+ * server-side actor installs: an agent, a worker, a cron job, a route handler.
9
+ *
10
+ * ```ts
11
+ * import { Ablo } from '@abloatai/ablo';
12
+ * import { schema } from './schema';
13
+ *
14
+ * const ablo = Ablo({ schema, apiKey: process.env.ABLO_API_KEY, transport: 'http' });
15
+ * await ablo.tasks.update({ id: taskId, data: { status: 'done' } });
16
+ * ```
17
+ *
18
+ * The reactive materialiser — local store, live queries, presence rendering —
19
+ * is the consumer package's entry point (`@abloatai/ablo`), which layers
20
+ * above this one and shares the same `ablo.<model>` surface (ADR 0016).
21
+ */
22
+ import { type AbloHttpClient, type AbloHttpClientOptions } from './transport/httpClient.js';
23
+ import type { SchemaRecord } from './schema/schema.js';
24
+ import type * as _Streams from './types/streams.js';
25
+ import type * as _SchemaTypes from './schema/schema.js';
26
+ import type * as _Global from './types/global.js';
27
+ import type * as _Policy from './policy/types.js';
28
+ import type * as _Http from './resources/httpResources.js';
29
+ /**
30
+ * Create a coordination-layer client in one call.
31
+ *
32
+ * The core carries one transport today — request/response HTTP — so
33
+ * `transport: 'http'` is accepted for symmetry with the reactive package's
34
+ * factory and may be omitted. The duplex transport joins this slot when the
35
+ * socket carve lands (ADR 0016, follow-up 3a).
36
+ */
37
+ export declare function Ablo<const S extends SchemaRecord>(options: AbloHttpClientOptions<S> & {
38
+ transport?: 'http';
39
+ }): AbloHttpClient<S>;
40
+ export declare namespace Ablo {
41
+ type ClaimTarget = _Streams.ClaimTarget;
42
+ type PresenceTarget = _Streams.PresenceTarget;
43
+ type Duration = _Streams.Duration;
44
+ type Peer = _Streams.Peer;
45
+ type Activity = _Streams.Activity;
46
+ type Claim = _Streams.Claim;
47
+ type ClaimHeartbeat = _Streams.ClaimHeartbeat;
48
+ type ClaimHeartbeatOptions = _Streams.ClaimHeartbeatOptions;
49
+ namespace Claim {
50
+ type Held<T = Record<string, unknown>, M = _Global.ResolveClaimMeta> = _Streams.HeldClaim<T, M>;
51
+ type WaitOptions = _Streams.ClaimWaitOptions;
52
+ type LeaseOptions = _Streams.ClaimLeaseOptions;
53
+ }
54
+ type Schema<S extends _SchemaTypes.SchemaRecord = _SchemaTypes.SchemaRecord> = _SchemaTypes.Schema<S>;
55
+ /**
56
+ * The schema this program has registered via `interface Register { Schema }`
57
+ * (falls back to a loose shape when unregistered). Use it where shared code
58
+ * needs "this app's schema" without importing a specific one.
59
+ */
60
+ type ResolveSchema = _Global.ResolveSchema;
61
+ /**
62
+ * The claim metadata shape this program has registered via
63
+ * `interface Register { ClaimMeta }` (falls back to a loose record when
64
+ * unregistered). Every claim surface reads `target.meta` as this.
65
+ */
66
+ type ResolveClaimMeta = _Global.ResolveClaimMeta;
67
+ namespace Schema {
68
+ type Model<S extends _SchemaTypes.Schema, K extends keyof S['models']> = _SchemaTypes.Model<S, K>;
69
+ type InferCreate<S extends _SchemaTypes.Schema, K extends keyof S['models']> = _SchemaTypes.InferCreate<S, K>;
70
+ type InferModelNames<S extends _SchemaTypes.Schema> = _SchemaTypes.InferModelNames<S>;
71
+ }
72
+ type Conflict = _Policy.Conflict;
73
+ namespace Conflict {
74
+ type Kind = _Policy.ConflictKind;
75
+ type Operation = _Policy.ConflictOperation;
76
+ type Decision = _Policy.ConflictDecision;
77
+ type Policy = _Policy.ConflictPolicy;
78
+ type Axis = _Policy.ConflictAxis;
79
+ }
80
+ namespace Commit {
81
+ type Wait = _Http.CommitWait;
82
+ type OperationAction = _Http.ModelOperationAction;
83
+ type OperationInput = _Http.CommitOperationInput;
84
+ type CreateOptions = _Http.CommitCreateOptions;
85
+ type Receipt = _Http.CommitReceipt;
86
+ type Client = _Http.CommitResource;
87
+ }
88
+ }