@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,13 +1,13 @@
1
1
  /**
2
2
  * Tracks whether the confirming delta for a write has arrived. It holds the
3
- * acknowledgement watermark (through the shared {@link SyncPosition}), the
3
+ * acknowledgement watermark (through the shared {@link LogPosition}), the
4
4
  * per-transaction confirmation timeouts, and the retry-with-backoff and
5
5
  * reconciliation policy for transactions in the `awaiting_delta` status. It
6
- * reaches back to {@link TransactionQueue} only through the small
6
+ * reaches back to {@link MutationQueue} only through the small
7
7
  * {@link DeltaConfirmationContext} interface, not the queue class itself, so it
8
8
  * has no cyclic dependency and can be tested on its own.
9
9
  */
10
- import { getContext } from '../context.js';
10
+ import { globalRuntime } from '../../context.js';
11
11
  export class DeltaConfirmationTracker {
12
12
  ctx;
13
13
  // Retry configuration for delta confirmation, using exponential backoff.
@@ -20,8 +20,10 @@ export class DeltaConfirmationTracker {
20
20
  deltaConfirmationTimeouts = new Map();
21
21
  // Track retry attempts per transaction for exponential backoff
22
22
  deltaConfirmationRetries = new Map();
23
+ runtime;
23
24
  constructor(ctx) {
24
25
  this.ctx = ctx;
26
+ this.runtime = ctx.runtime ?? globalRuntime;
25
27
  }
26
28
  /** Applied-cursor alias, kept so the read sites below stay legible. */
27
29
  get lastSeenSyncId() {
@@ -48,7 +50,7 @@ export class DeltaConfirmationTracker {
48
50
  const executingTxs = this.ctx.store.getByStatus('executing');
49
51
  // Debug: Show state when delta arrives
50
52
  if (awaitingTxs.length > 0 || executingTxs.length > 0) {
51
- getContext().logger.debug('tx:delta_received', {
53
+ this.runtime.logger.debug('tx:delta_received', {
52
54
  syncId,
53
55
  lastSeenSyncId: this.lastSeenSyncId,
54
56
  awaitingCount: awaitingTxs.length,
@@ -86,7 +88,7 @@ export class DeltaConfirmationTracker {
86
88
  this.ctx.emit(`transaction:completed:${tx.id}`, tx);
87
89
  this.ctx.optimisticUpdates.delete(tx.id);
88
90
  confirmedCount++;
89
- getContext().logger.debug('tx:confirm_via_delta', {
91
+ this.runtime.logger.debug('tx:confirm_via_delta', {
90
92
  txId: tx.id.slice(0, 8),
91
93
  model: tx.modelName,
92
94
  neededSyncId: tx.syncIdNeededForCompletion,
@@ -98,7 +100,7 @@ export class DeltaConfirmationTracker {
98
100
  // Log batch summary only if we confirmed something
99
101
  if (confirmedCount > 0) {
100
102
  // Leave a breadcrumb when transactions confirm.
101
- getContext().observability.breadcrumb('Transactions confirmed via delta', 'sync.transaction', 'info', {
103
+ this.runtime.observability.breadcrumb('Transactions confirmed via delta', 'sync.transaction', 'info', {
102
104
  count: confirmedCount,
103
105
  syncId,
104
106
  remainingAwaiting: awaitingTxs.length - confirmedCount,
@@ -118,7 +120,7 @@ export class DeltaConfirmationTracker {
118
120
  // rejection instead of a catchable synchronous error.
119
121
  const timeoutHandle = setTimeout(() => {
120
122
  const currentTx = this.ctx.store.get(tx.id);
121
- if (!currentTx || currentTx.status !== 'awaiting_delta') {
123
+ if (currentTx?.status !== 'awaiting_delta') {
122
124
  this.deltaConfirmationRetries.delete(tx.id);
123
125
  return; // Already confirmed or failed
124
126
  }
@@ -126,7 +128,7 @@ export class DeltaConfirmationTracker {
126
128
  if (!this.ctx.isConnected()) {
127
129
  // Self-healing: re-schedule the confirmation wait while offline, no
128
130
  // consumer action needed → debug.
129
- getContext().logger.debug('[TransactionQueue] Timeout fired while disconnected - re-scheduling', {
131
+ this.runtime.logger.debug('[MutationQueue] Timeout fired while disconnected - re-scheduling', {
130
132
  txId: tx.id.slice(0, 8),
131
133
  model: tx.modelName,
132
134
  });
@@ -135,7 +137,7 @@ export class DeltaConfirmationTracker {
135
137
  return;
136
138
  }
137
139
  const retryCount = this.deltaConfirmationRetries.get(tx.id) ?? 0;
138
- getContext().observability.captureReconciliation({
140
+ this.runtime.observability.captureReconciliation({
139
141
  reason: 'delta_timeout',
140
142
  model: tx.modelName,
141
143
  modelId: tx.modelId,
@@ -165,7 +167,7 @@ export class DeltaConfirmationTracker {
165
167
  });
166
168
  // Self-healing retry with backoff — the server already committed; we're
167
169
  // just waiting on the delta. No consumer action → debug.
168
- getContext().logger.debug('[TransactionQueue] Re-scheduling with backoff', {
170
+ this.runtime.logger.debug('[MutationQueue] Re-scheduling with backoff', {
169
171
  txId: tx.id.slice(0, 8),
170
172
  model: tx.modelName,
171
173
  nextTimeoutMs: nextTimeout,
@@ -180,7 +182,7 @@ export class DeltaConfirmationTracker {
180
182
  // session, reconnecting and catching up on deltas will confirm it.
181
183
  this.deltaConfirmationRetries.delete(tx.id);
182
184
  this.deltaConfirmationTimeouts.delete(tx.id);
183
- getContext().observability.captureDeltaRetryExhausted({
185
+ this.runtime.observability.captureDeltaRetryExhausted({
184
186
  txId: tx.id,
185
187
  model: tx.modelName,
186
188
  modelId: tx.modelId,
@@ -220,7 +222,7 @@ export class DeltaConfirmationTracker {
220
222
  }
221
223
  /**
222
224
  * Clears every armed confirmation timer, one per in-flight transaction.
223
- * {@link TransactionQueue.dispose} calls this; without it a disposed queue
225
+ * {@link MutationQueue.dispose} calls this; without it a disposed queue
224
226
  * would keep the process alive and fire callbacks against a cleared store.
225
227
  */
226
228
  dispose() {
@@ -0,0 +1,14 @@
1
+ /**
2
+ * The durable-write port moved to the settlement core (ADR 0016): it is a
3
+ * contract over commit envelopes and holds no local rows. Re-exported here so
4
+ * the existing `transactions/mutations/durableWriteStore` import path keeps
5
+ * resolving for the queue, the outbox, and the client options.
6
+ *
7
+ * The port and its config live in the core's `durableWrites` module (a behavior
8
+ * contract, not a persisted shape); the records that cross it are owned by
9
+ * `transactions/settlement/pendingWrite`.
10
+ */
11
+ export { durableWriteStoreSchema, durableWritesConfigSchema, } from '../../transaction/durableWrites.js';
12
+ export type { DurableWriteStore, DurableWritesConfig, } from '../../transaction/durableWrites.js';
13
+ export { pendingWriteSchema } from '../../transaction/transactions/settlement/pendingWrite.js';
14
+ export type { PendingWrite } from '../../transaction/transactions/settlement/pendingWrite.js';
@@ -0,0 +1,12 @@
1
+ /**
2
+ * The durable-write port moved to the settlement core (ADR 0016): it is a
3
+ * contract over commit envelopes and holds no local rows. Re-exported here so
4
+ * the existing `transactions/mutations/durableWriteStore` import path keeps
5
+ * resolving for the queue, the outbox, and the client options.
6
+ *
7
+ * The port and its config live in the core's `durableWrites` module (a behavior
8
+ * contract, not a persisted shape); the records that cross it are owned by
9
+ * `transactions/settlement/pendingWrite`.
10
+ */
11
+ export { durableWriteStoreSchema, durableWritesConfigSchema, } from '../../transaction/durableWrites.js';
12
+ export { pendingWriteSchema } from '../../transaction/transactions/settlement/pendingWrite.js';
@@ -8,8 +8,8 @@
8
8
  * than any larger object, so the rules have no dependencies of their own and
9
9
  * can be tested in isolation.
10
10
  */
11
- import type { Model } from '../Model.js';
12
- import type { MutationInput, Transaction } from './commitPayload.js';
11
+ import type { Model } from '../../Model.js';
12
+ import type { MutationInput, QueuedMutation } from './commitPayload.js';
13
13
  /**
14
14
  * One tracked optimistic mutation: the live model plus the value it held
15
15
  * before the change, kept so a rollback can restore it.
@@ -17,7 +17,7 @@ import type { MutationInput, Transaction } from './commitPayload.js';
17
17
  export interface OptimisticUpdateEntry {
18
18
  model: Model;
19
19
  previousState: MutationInput | null | undefined;
20
- transaction: Transaction;
20
+ transaction: QueuedMutation;
21
21
  }
22
22
  /**
23
23
  * The event emitter these functions use to announce each optimistic change and
@@ -30,20 +30,20 @@ export interface OptimisticEmitter {
30
30
  * Record an optimistic create and announce it. There is no prior value to
31
31
  * restore, so the rollback pre-image is `null`.
32
32
  */
33
- export declare function applyOptimisticCreate(optimisticUpdates: Map<string, OptimisticUpdateEntry>, emitter: OptimisticEmitter, model: Model, transaction: Transaction): void;
33
+ export declare function applyOptimisticCreate(optimisticUpdates: Map<string, OptimisticUpdateEntry>, emitter: OptimisticEmitter, model: Model, transaction: QueuedMutation): void;
34
34
  /**
35
35
  * Record an optimistic update and announce it, keeping the row's prior value so
36
36
  * a rollback can put it back.
37
37
  */
38
- export declare function applyOptimisticUpdate(optimisticUpdates: Map<string, OptimisticUpdateEntry>, emitter: OptimisticEmitter, model: Model, transaction: Transaction): void;
38
+ export declare function applyOptimisticUpdate(optimisticUpdates: Map<string, OptimisticUpdateEntry>, emitter: OptimisticEmitter, model: Model, transaction: QueuedMutation): void;
39
39
  /**
40
40
  * Record an optimistic delete and announce it, keeping the deleted row so a
41
41
  * rollback can restore it.
42
42
  */
43
- export declare function applyOptimisticDelete(optimisticUpdates: Map<string, OptimisticUpdateEntry>, emitter: OptimisticEmitter, model: Model, transaction: Transaction): void;
43
+ export declare function applyOptimisticDelete(optimisticUpdates: Map<string, OptimisticUpdateEntry>, emitter: OptimisticEmitter, model: Model, transaction: QueuedMutation): void;
44
44
  /**
45
45
  * Undo an optimistic mutation by its transaction id: emit `optimistic:rollback`
46
46
  * with the saved pre-image so listeners can restore the prior value, then drop
47
47
  * the ledger entry. Does nothing if the transaction was never tracked.
48
48
  */
49
- export declare function rollbackOptimistic(optimisticUpdates: Map<string, OptimisticUpdateEntry>, emitter: OptimisticEmitter, transaction: Transaction, reason?: string, error?: Error): Promise<void>;
49
+ export declare function rollbackOptimistic(optimisticUpdates: Map<string, OptimisticUpdateEntry>, emitter: OptimisticEmitter, transaction: QueuedMutation, reason?: string, error?: Error): Promise<void>;
@@ -15,7 +15,8 @@
15
15
  * quietly rather than flagged as corruption.
16
16
  */
17
17
  import { z } from 'zod';
18
- import type { Transaction } from './commitPayload.js';
18
+ import type { QueuedMutation } from './commitPayload.js';
19
+ import type { RuntimeContext } from '../../RuntimeContext.js';
19
20
  /**
20
21
  * The shape of a persisted transaction that can be replayed: the fields the
21
22
  * transaction queue reads when it re-enqueues the row — its id, operation type,
@@ -73,12 +74,12 @@ export type PersistedReplayableTransaction = z.infer<typeof persistedTransaction
73
74
  */
74
75
  export declare function isNonReplayablePersistedRow(row: unknown): boolean;
75
76
  /**
76
- * Validates one stored row and rehydrates it into a {@link Transaction} ready
77
+ * Validates one stored row and rehydrates it into a {@link QueuedMutation} ready
77
78
  * to replay, or returns `null` when the row fails validation. Bookkeeping
78
79
  * fields the stored row lacks — status, attempts, priority, timestamp — are
79
80
  * re-derived the same way a freshly staged transaction derives them.
80
81
  */
81
- export declare function deserializePersistedTransaction(row: unknown): Transaction | null;
82
+ export declare function deserializePersistedTransaction(row: unknown, runtime?: RuntimeContext): QueuedMutation | null;
82
83
  /**
83
84
  * The shape of one entry in the persisted offline mutation queue — an item of
84
85
  * the `'queue'` row's `mutations` array, carrying the fields read when the
@@ -16,12 +16,14 @@
16
16
  */
17
17
  import { z } from 'zod';
18
18
  import { computePriorityScore, normalizeModelKey } from './commitPayload.js';
19
- import { commitEnvelopeMemberSchema, commitOutboxScopeSchema, } from './commitEnvelope.js';
19
+ import { globalRuntime } from '../../context.js';
20
+ import { commitEnvelopeMemberSchema, commitOutboxScopeSchema, } from '../../transaction/transactions/settlement/commitEnvelope.js';
21
+ import { onStaleModeSchema } from '../../transaction/coordination/schema.js';
20
22
  /** The subset of a write's options that is stored with each transaction or queued mutation. */
21
23
  const persistedWriteOptionsSchema = z
22
24
  .object({
23
25
  readAt: z.number().nullable().optional(),
24
- onStale: z.enum(['reject', 'overwrite', 'notify']).nullable().optional(),
26
+ onStale: onStaleModeSchema.nullable().optional(),
25
27
  idempotencyKey: z.string().optional(),
26
28
  label: z.string().optional(),
27
29
  // Aligned with the `WriteOptions` type: a claimed write persisted offline
@@ -81,12 +83,12 @@ export function isNonReplayablePersistedRow(row) {
81
83
  NON_REPLAYABLE_TYPES.has(row.type));
82
84
  }
83
85
  /**
84
- * Validates one stored row and rehydrates it into a {@link Transaction} ready
86
+ * Validates one stored row and rehydrates it into a {@link QueuedMutation} ready
85
87
  * to replay, or returns `null` when the row fails validation. Bookkeeping
86
88
  * fields the stored row lacks — status, attempts, priority, timestamp — are
87
89
  * re-derived the same way a freshly staged transaction derives them.
88
90
  */
89
- export function deserializePersistedTransaction(row) {
91
+ export function deserializePersistedTransaction(row, runtime = globalRuntime) {
90
92
  const parsed = persistedTransactionSchema.safeParse(row);
91
93
  if (!parsed.success)
92
94
  return null;
@@ -104,7 +106,7 @@ export function deserializePersistedTransaction(row) {
104
106
  createdAt: tx.createdAt ?? Date.now(),
105
107
  attempts: 0,
106
108
  priority: 'normal',
107
- priorityScore: computePriorityScore(tx.type, tx.modelName),
109
+ priorityScore: computePriorityScore(tx.type, tx.modelName, runtime),
108
110
  ...(tx.batchId !== undefined ? { batchId: tx.batchId } : {}),
109
111
  ...(tx.commitEnvelope !== undefined
110
112
  ? { commitEnvelope: tx.commitEnvelope }
@@ -5,7 +5,7 @@
5
5
  * each field, leaving any hand-written getter or setter in place.
6
6
  */
7
7
  import { type AnnotationMapEntry } from 'mobx';
8
- import { type PropertyMetadata, type ReferenceMetadata } from '../types/index.js';
8
+ import { type PropertyMetadata, type ReferenceMetadata } from '../transaction/types/index.js';
9
9
  /**
10
10
  * The subset of a model instance that {@link M1} reads and writes. A model calls
11
11
  * {@link M1} from its constructor, where these members exist on `this`;
@@ -5,7 +5,7 @@
5
5
  * each field, leaving any hand-written getter or setter in place.
6
6
  */
7
7
  import { observable, makeObservable, action, computed, observe, } from 'mobx';
8
- import { PropertyType } from '../types/index.js';
8
+ import { PropertyType } from '../transaction/types/index.js';
9
9
  import { getContext } from '../context.js';
10
10
  /**
11
11
  * Makes a model instance's schema-defined properties observable with MobX. For
@@ -140,7 +140,10 @@ export function M1(target, propertyMetadata, referenceMetadata) {
140
140
  annotations.updatedAt = observable;
141
141
  }
142
142
  if (!hasGetter('modifiedProperties') && !hasSetter('modifiedProperties')) {
143
- annotations.modifiedProperties = observable;
143
+ // Track map membership, but keep change payloads as plain values. These
144
+ // entries are replaced rather than mutated and later cross IndexedDB's
145
+ // structured-clone boundary, where MobX's deep proxies are invalid.
146
+ annotations.modifiedProperties = observable.shallow;
144
147
  }
145
148
  // Add actions only if methods exist and aren't already actions.
146
149
  // `Reflect.get` keeps the read typed without an index-signature
@@ -10,9 +10,9 @@
10
10
  */
11
11
  import { type IObservableArray } from 'mobx';
12
12
  import { type Model } from '../Model.js';
13
- import { ModelScope } from '../types/index.js';
13
+ import { ModelScope } from '../transaction/types/index.js';
14
14
  import type { ViewRegistry } from './ViewRegistry.js';
15
- import type { IncrementalView } from './queryUtils.js';
15
+ import type { IncrementalView } from './incrementalView.js';
16
16
  /**
17
17
  * The slice of the object pool that a {@link QueryView} reads. It is a minimal
18
18
  * structural interface rather than the concrete pool class, which lets a query
@@ -10,8 +10,8 @@
10
10
  */
11
11
  import { observable, runInAction } from 'mobx';
12
12
  import { modelAsRow } from '../Model.js';
13
- import { ModelScope } from '../types/index.js';
14
- import { compareValues, binaryInsertionIndex, findIndexById, } from './queryUtils.js';
13
+ import { ModelScope } from '../transaction/types/index.js';
14
+ import { compareValues, binaryInsertionIndex, findIndexById, } from './incrementalView.js';
15
15
  // ---------------------------------------------------------------------------
16
16
  // QueryView
17
17
  // ---------------------------------------------------------------------------
@@ -6,7 +6,7 @@
6
6
  * QueryView subscribed to that typename.
7
7
  */
8
8
  import { type Model } from '../Model.js';
9
- import type { IncrementalView } from './queryUtils.js';
9
+ import type { IncrementalView } from './incrementalView.js';
10
10
  export declare class ViewRegistry {
11
11
  private views;
12
12
  register(typename: string, view: IncrementalView): void;
@@ -1,10 +1,10 @@
1
1
  /**
2
- * Small, self-contained helpers for sorting, filtering, and binary insertion.
3
- * The incrementally-updated views that implement {@link IncrementalView} rely on
4
- * these for their ordering and matching, so keeping the rules in one place
5
- * ensures every view sorts and filters identically. The functions here work on
6
- * plain arrays and values — they hold no reference to models, pools, or the
7
- * reactivity system.
2
+ * The {@link IncrementalView} contract the interface a live view implements
3
+ * to receive add/update/remove notifications together with the sorting,
4
+ * matching, and binary-insertion rules every view shares. Keeping the rules in
5
+ * one place ensures every view sorts and filters identically. The functions
6
+ * here work on plain arrays and values — they hold no reference to models,
7
+ * pools, or the reactivity system.
8
8
  */
9
9
  /**
10
10
  * The interface a live view implements to receive incremental updates: one call
@@ -1,10 +1,10 @@
1
1
  /**
2
- * Small, self-contained helpers for sorting, filtering, and binary insertion.
3
- * The incrementally-updated views that implement {@link IncrementalView} rely on
4
- * these for their ordering and matching, so keeping the rules in one place
5
- * ensures every view sorts and filters identically. The functions here work on
6
- * plain arrays and values — they hold no reference to models, pools, or the
7
- * reactivity system.
2
+ * The {@link IncrementalView} contract the interface a live view implements
3
+ * to receive add/update/remove notifications together with the sorting,
4
+ * matching, and binary-insertion rules every view shares. Keeping the rules in
5
+ * one place ensures every view sorts and filters identically. The functions
6
+ * here work on plain arrays and values — they hold no reference to models,
7
+ * pools, or the reactivity system.
8
8
  */
9
9
  /**
10
10
  * Compares two values for sorting, tolerating `null` and `undefined`, which
@@ -7,10 +7,10 @@ export interface AbloWebhookEvent {
7
7
  /** A stable, unique event identifier equal to `String(syncId)`. Use it to
8
8
  * deduplicate deliveries. */
9
9
  readonly id: string;
10
- /** The event type, formatted as `<model>.<verb>`, such as `"slide.updated"`.
10
+ /** The event type, formatted as `<model>.<verb>`, such as `"report.updated"`.
11
11
  * Branch on this to route the event. */
12
12
  readonly type: string;
13
- /** The name of the model whose row changed, such as `"Slide"`. */
13
+ /** The name of the model whose row changed, such as `"Report"`. */
14
14
  readonly model: string;
15
15
  /** The identifier of the row that changed. */
16
16
  readonly objectId: string;
@@ -1,34 +1 @@
1
- /**
2
- * The wire contract for the sync protocol: the HTTP envelope shapes and the
3
- * write-path frames, with no dependency on the client runtime. A server — a
4
- * route handler, an edge function — can import the envelope producers here
5
- * without pulling in the full sync client.
6
- *
7
- * It has two halves, used across every endpoint:
8
- * - Error responses — {@link errorEnvelope}, {@link ErrorEnvelope}, and
9
- * {@link statusForType} turn any thrown value into the uniform
10
- * `{ type, code, param, message, doc_url, request_id }` body.
11
- * - List responses — {@link listEnvelope} and {@link ListEnvelope} stamp the
12
- * uniform `{ object: 'list', data, has_more, next_cursor }` collection.
13
- *
14
- * The {@link AbloError} hierarchy, {@link docUrlForCode}, and the wire-parsing
15
- * helpers are re-exported too, so a single import lets a route throw the right
16
- * typed error and serialize it back out.
17
- */
18
- export { errorEnvelope, statusForType } from './errorEnvelope.js';
19
- export type { ErrorEnvelope } from './errorEnvelope.js';
20
- export { listEnvelope } from './listEnvelope.js';
21
- export type { ListEnvelope } from './listEnvelope.js';
22
- export { bootstrapReasonSchema } from './bootstrapReason.js';
23
- export type { BootstrapReason } from './bootstrapReason.js';
24
- export { commitOperationSchema, commitPayloadSchema, } from './frames.js';
25
- export { PROTOCOL_VERSION, MIN_SUPPORTED_PROTOCOL_VERSION, DEFAULT_PROTOCOL_VERSION, SUPPORTED_PROTOCOL_VERSIONS, WS_CLOSE_PROTOCOL_VERSION, PROTOCOL_VERSION_HEADER, protocolVersionProblem, resolveProtocolVersion, } from './protocolVersion.js';
26
- export type { SupportedProtocolVersion, ProtocolVersionProblem, } from './protocolVersion.js';
27
- export type { CommitOperation, CommitMessage, MutationResultMessage, } from './frames.js';
28
- export { COMMIT_CORRELATION_ID_MAX_LENGTH, correlationIdSchema, commitStatusSchema, commitSettlementSchema, commitReceiptSchema, legacyCompatibleCommitReceiptSchema, rejectedCommitReceiptSchema, mutationResultPayloadSchema, mutationResultMessageSchema, commitAckSchema, mutationCommitResultSchema, } from './commit.js';
29
- export type { CorrelationId, CommitStatus, CommitSettlement, CommitReceiptWire, RejectedCommitReceiptWire, MutationResultPayload, MutationResultMessageWire, CommitAck, MutationCommitResultInput, MutationCommitResult, } from './commit.js';
30
- export { participantKindSchema, confirmationStateSchema, syncDeltaActionSchema, wireDeltaDataSchema, participantRefSchema, syncDeltaWireCoreSchema, clientSyncDeltaSchema, serverSyncDeltaSchema, } from './delta.js';
31
- export type { ParticipantKind, ConfirmationState, SyncDeltaAction, WireDeltaData, ParticipantRef, SyncDeltaWireCore, ClientSyncDelta, ServerSyncDelta, } from './delta.js';
32
- export { AbloError, AbloAuthenticationError, AbloPermissionError, AbloValidationError, AbloRateLimitError, AbloIdempotencyError, AbloConnectionError, AbloServerError, AbloStaleContextError, AbloClaimedError, CapabilityError, SyncSessionError, docUrlForCode, translateHttpError, errorFromWire, toAbloError, ERROR_CONTRACT_VERSION, errorCodeSpec, } from '../errors.js';
33
- export type { ErrorCode, WireErrorCode } from '../errors.js';
34
- export { PING_INTERVAL_MS, LEASE_TTL_MS, WS_BEARER_SUBPROTOCOL_PREFIX, WS_SYNC_SUBPROTOCOL, } from './protocol.js';
1
+ export * from '../transaction/wire/index.js';
@@ -1,49 +1,8 @@
1
- /**
2
- * The wire contract for the sync protocol: the HTTP envelope shapes and the
3
- * write-path frames, with no dependency on the client runtime. A server — a
4
- * route handler, an edge function can import the envelope producers here
5
- * without pulling in the full sync client.
6
- *
7
- * It has two halves, used across every endpoint:
8
- * - Error responses — {@link errorEnvelope}, {@link ErrorEnvelope}, and
9
- * {@link statusForType} turn any thrown value into the uniform
10
- * `{ type, code, param, message, doc_url, request_id }` body.
11
- * - List responses — {@link listEnvelope} and {@link ListEnvelope} stamp the
12
- * uniform `{ object: 'list', data, has_more, next_cursor }` collection.
13
- *
14
- * The {@link AbloError} hierarchy, {@link docUrlForCode}, and the wire-parsing
15
- * helpers are re-exported too, so a single import lets a route throw the right
16
- * typed error and serialize it back out.
17
- */
18
- export { errorEnvelope, statusForType } from './errorEnvelope.js';
19
- export { listEnvelope } from './listEnvelope.js';
20
- export { bootstrapReasonSchema } from './bootstrapReason.js';
21
- // The write-path frame contract: the message shapes shared by the client and
22
- // the server. The runtime Zod validators sit beside the interfaces and are
23
- // pinned to them, and they gate every operation and payload on both commit
24
- // transports.
25
- export { commitOperationSchema, commitPayloadSchema, } from './frames.js';
26
- // Protocol versioning: the single integer the client and server compare to
27
- // confirm they can speak to each other, plus the WebSocket close code used to
28
- // reject a mismatch. See protocolVersion.ts for the changelog and deploy rules.
29
- export { PROTOCOL_VERSION, MIN_SUPPORTED_PROTOCOL_VERSION, DEFAULT_PROTOCOL_VERSION, SUPPORTED_PROTOCOL_VERSIONS, WS_CLOSE_PROTOCOL_VERSION, PROTOCOL_VERSION_HEADER, protocolVersionProblem, resolveProtocolVersion, } from './protocolVersion.js';
30
- // Commit settlement backbone. The transport receipt, server execution cache,
31
- // and normalized client acknowledgement are different envelopes composed from
32
- // this one discriminated settlement vocabulary.
33
- export { COMMIT_CORRELATION_ID_MAX_LENGTH, correlationIdSchema, commitStatusSchema, commitSettlementSchema, commitReceiptSchema, legacyCompatibleCommitReceiptSchema, rejectedCommitReceiptSchema, mutationResultPayloadSchema, mutationResultMessageSchema, commitAckSchema, mutationCommitResultSchema, } from './commit.js';
34
- // The read-path delta contract: the shape the server broadcasts to clients as the
35
- // payload of a `delta` or `sync_response` frame, together with the shared
36
- // participant vocabulary it carries. Both ends derive their delta type from these
37
- // schemas, so the client and server cannot drift apart.
38
- export { participantKindSchema, confirmationStateSchema, syncDeltaActionSchema, wireDeltaDataSchema, participantRefSchema, syncDeltaWireCoreSchema, clientSyncDeltaSchema, serverSyncDeltaSchema, } from './delta.js';
39
- // The error surface a wire consumer needs to throw, classify, and serialize.
40
- export { AbloError, AbloAuthenticationError, AbloPermissionError, AbloValidationError, AbloRateLimitError, AbloIdempotencyError, AbloConnectionError, AbloServerError, AbloStaleContextError, AbloClaimedError, CapabilityError, SyncSessionError, docUrlForCode, translateHttpError, errorFromWire, toAbloError, ERROR_CONTRACT_VERSION,
41
- // The table mapping each error code to its HTTP status and retryable flag —
42
- // plain data a server can use to resolve a code's canonical status the same
43
- // way the client's error serializer does.
44
- errorCodeSpec, } from '../errors.js';
45
- // Protocol timing constants — the 30-second ping cadence and the lease window
46
- // derived from it, shared by the client heartbeat and the server keepalive,
47
- // claim leasing, and presence expiry (see protocol.ts) — plus the WebSocket
48
- // subprotocols used during the authenticated handshake.
49
- export { PING_INTERVAL_MS, LEASE_TTL_MS, WS_BEARER_SUBPROTOCOL_PREFIX, WS_SYNC_SUBPROTOCOL, } from './protocol.js';
1
+ // Moved to @ablo/transaction (ADR 0013 — the settlement core extraction).
2
+ // This shim re-exports it at the original path so in-package importers of
3
+ // `wire/index.js` keep working; rewire to `@ablo/transaction/wire`
4
+ // and delete this shim once the core package is fully wired.
5
+ //
6
+ // Line comments on purpose: tsc copies a leading JSDoc block into the
7
+ // published `.d.ts`, and this note names a package npm has never heard of.
8
+ export * from '../transaction/wire/index.js';
@@ -1,5 +1,7 @@
1
1
  # Agent Messaging
2
2
 
3
+ > Durable handoffs between agents, linked to the claim they are about.
4
+
3
5
  Use a normal model when agents or humans need durable communication inside a
4
6
  syncGroup. Use claim `description` and `meta` for live coordination context.
5
7
  Use a `messages` row when the information must survive reconnects, work over
@@ -32,7 +34,6 @@ export const schema = defineSchema({
32
34
  status: z.string(),
33
35
  teamId: z.string(),
34
36
  },
35
- {},
36
37
  { entityRoles: [entityRole({ kind: "team", source: "teamId" })] },
37
38
  ),
38
39
 
@@ -47,7 +48,6 @@ export const schema = defineSchema({
47
48
  aboutEntityId: z.string().optional(),
48
49
  aboutIntentId: z.string().optional(),
49
50
  },
50
- {},
51
51
  { entityRoles: [entityRole({ kind: "team", source: "teamId" })] },
52
52
  ),
53
53
  });
@@ -121,7 +121,7 @@ Peers outside that syncGroup do not.
121
121
  Live clients read locally and update when deltas arrive:
122
122
 
123
123
  ```ts
124
- const rows = ablo.messages.getAll({
124
+ const rows = ablo.messages.local.list({
125
125
  where: { teamId },
126
126
  orderBy: { createdAt: "asc" },
127
127
  });
package/docs/agents.md CHANGED
@@ -1,14 +1,17 @@
1
1
  # Agents
2
2
 
3
+ > The stateless participant: wake on a trigger, read, claim, commit, go idle.
4
+
3
5
  An agent is a **reactive** participant: it wakes on something happening, reads
4
6
  what it needs, writes a result, and goes idle. That's a request/response
5
7
  workload — so agents talk to Ablo over **plain HTTP**, holding no WebSocket. The
6
8
  credential *is* the identity; the server resolves the org, scope, and actor from
7
9
  the key on every request (the Stripe server-SDK / Liveblocks-node shape).
8
10
 
9
- Humans get the live plane (WebSocket: presence, optimistic, sub-100ms). Agents
10
- get the stateless plane (HTTP). **Both operate on the same typed, coordinated
11
- state — and coordinate *with each other*.**
11
+ Agents get the stateless plane (HTTP). People when you add the `humans()`
12
+ plugin — get the live plane (WebSocket: presence, optimistic, sub-100ms).
13
+ **Both operate on the same typed, coordinated state — and coordinate *with each
14
+ other*.**
12
15
 
13
16
  <Note>
14
17
  Agents transact against your **pushed schema**, same as everyone — `ablo.tasks`
@@ -40,11 +43,11 @@ await ablo.tasks.update({ id: task.id, data: { status: "done" } });
40
43
 
41
44
  It exposes `retrieve` / `list` / `create` / `update` / `delete`, plus `commits`
42
45
  and `claim`. It does **not** expose the stateful-only surface (`get` /
43
- `getAll` / `getCount` local reads, `onChange` live subscription) — those need a
46
+ `local` reads, `onChange` live subscription) — those need a
44
47
  live connection, so with `transport: 'http'` the return type narrows and they
45
48
  are a *compile error*, not a runtime surprise.
46
49
 
47
- ## Coordination claim, queue, reorder
50
+ ## Coordination: claim, queue, reorder
48
51
 
49
52
  The differentiator. A claim is a **durable lease + FIFO wait-line** on a row —
50
53
  "who's working on this, who's waiting" — and it's request/response, so an agent
@@ -77,14 +80,18 @@ a message back to the claim it discusses.
77
80
 
78
81
  See [Agent Messaging](/agent-messaging) for the schema and setup details.
79
82
 
80
- ## Humans + agents on one state
83
+ ## When a person is in the loop
84
+
85
+ There's no separate "agent mode" — and no separate human mode either. The bare
86
+ client is the coordination layer; `humans()` is the plugin that adds the live
87
+ plane on top of it. An agent acting over HTTP and a person editing over their
88
+ socket share the same typed state and the same coordination: the agent can claim
89
+ the row that person is holding (and wait in line), and they see the agent's
90
+ committed changes stream in **live** over their own socket, even though the
91
+ agent committed over HTTP.
81
92
 
82
- There's no separate "agent mode." A human editing a record over their WebSocket
83
- and an agent acting over HTTP share the same typed state and the same coordination
84
- plane: the agent can claim the row a human is editing (and wait in line), and the
85
- human sees the agent's committed changes stream in **live** — over the human's
86
- own socket, even though the agent committed over HTTP. You write the agent once;
87
- it's a first-class participant, not a bolt-on.
93
+ There is no `agents()` plugin, and the absence is the point an agent is the
94
+ default caller here, not a bolt-on.
88
95
 
89
96
  ## How an agent runs
90
97
 
@@ -101,7 +108,7 @@ agents costs nothing on the live plane — that capacity stays for humans.
101
108
 
102
109
  ## What stays on the live (human) plane
103
110
 
104
- `onChange` (live subscriptions) and `get`/`getAll`/`getCount` (local synced-pool
111
+ `onChange` (live subscriptions) and the `local` reads (local synced-pool
105
112
  reads) require a WebSocket and a local store — they're for interactive UIs, not
106
113
  stateless agents. An agent reacts to an external trigger (a job/queue/webhook),
107
114
  then reads with `list`/`retrieve`. See [client behavior](/client-behavior) for
package/docs/api-keys.md CHANGED
@@ -1,5 +1,7 @@
1
1
  # API Keys
2
2
 
3
+ > The credential that carries an agent's identity and bounds what it may write.
4
+
3
5
  Authenticate a server-side client — a route handler, worker, or CLI — by passing an API key when you create the client.
4
6
 
5
7
  ```ts
@@ -19,9 +21,9 @@ Pick your row:
19
21
 
20
22
  | Where your code runs | What to pass | Example |
21
23
  |---|---|---|
22
- | **Server / worker / CLI** (can hold a secret) | your secret `sk_` it defaults to `ABLO_API_KEY`, so usually pass **nothing** | `Ablo({ schema })` |
23
- | **Browser read-only** | a publishable `pk_` (safe to ship, like a Stripe `pk_`) | `Ablo({ schema, apiKey: process.env.NEXT_PUBLIC_ABLO_PUBLISHABLE_KEY })` |
24
- | **Browser writing as the signed-in user** | `authEndpoint` the route on your own backend that mints a short-lived per-user token | `Ablo({ schema, authEndpoint: '/api/ablo-session' })` |
24
+ | **Server / worker / CLI** (can hold a secret) | your secret `sk_`: it defaults to `ABLO_API_KEY`, so usually pass **nothing** | `Ablo({ schema })` |
25
+ | **Browser: read-only** | a publishable `pk_` (safe to ship, like a Stripe `pk_`) | `Ablo({ schema, apiKey: process.env.NEXT_PUBLIC_ABLO_PUBLISHABLE_KEY })` |
26
+ | **Browser: writing as the signed-in user** | `authEndpoint`: the route on your own backend that mints a short-lived per-user token | `Ablo({ schema, authEndpoint: '/api/ablo-session' })` |
25
27
 
26
28
  That's the whole story: one knob, filled by audience.
27
29
 
@@ -29,8 +31,8 @@ That's the whole story: one knob, filled by audience.
29
31
 
30
32
  | Stripe | Ablo | Where it goes |
31
33
  |---|---|---|
32
- | publishable `pk_` (client-safe) | `pk_` | browser read-only |
33
- | secret `sk_` (server, full) | `sk_` | server full authority |
34
+ | publishable `pk_` (client-safe) | `pk_` | browser: read-only |
35
+ | secret `sk_` (server, full) | `sk_` | server: full authority |
34
36
  | restricted `rk_` (granular) | `rk_` | scoped agent sessions (`sessions.create({ agent, can })`) |
35
37
  | ephemeral key (client, customer-scoped) | `ek_` | per-user browser sessions (`sessions.create({ user })`) |
36
38
 
@@ -72,7 +74,7 @@ Use API keys from trusted (server-side) runtimes:
72
74
 
73
75
  Never ship a secret API key to a browser bundle.
74
76
 
75
- ## Publishable key (`pk_`) browser-safe, read-only
77
+ ## Publishable key (`pk_`): browser-safe, read-only
76
78
 
77
79
  For a read-only browser experience, a publishable key is safe to ship in the
78
80
  bundle. Like a Stripe `pk_` or a Supabase anon key, it is long-lived,
@@ -97,10 +99,12 @@ Test and live keys are the same shape; the prefix names the environment:
97
99
  - `sk_live_…` — a key against your live data.
98
100
 
99
101
  Every org has a default sandbox, plus any number of additional
100
- sandboxes you create. **Data is isolated per sandbox; the schema is shared
101
- across the whole org.** A schema you push from a test key defines the same
102
- models your live keys see — only the rows differ. This mirrors how Stripe
103
- separates sandbox and production data while keeping the API shape identical.
102
+ sandboxes you create. **Data is isolated per sandbox; the schema is one
103
+ definition serving both.** A sandbox reads the production schema until it is
104
+ pushed one of its own, so your test and live keys see the same models and only
105
+ the rows differ — how Stripe separates sandbox and production data while keeping
106
+ the API shape identical. A schema change reaches production when you push it
107
+ with a live key ([Deployment](./deployment.md)).
104
108
 
105
109
  ## Scopes
106
110