@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
@@ -9,11 +9,11 @@
9
9
  import { makeObservable, observable, action, computed, runInAction } from 'mobx';
10
10
  import { Model } from './Model.js';
11
11
  import { ModelRegistry } from './ModelRegistry.js';
12
- import { getContext } from './context.js';
13
- import { AbloValidationError } from './errors.js';
14
- import { ModelScope } from './types/index.js';
15
- import { ViewRegistry } from './core/ViewRegistry.js';
16
- import { QueryView } from './core/QueryView.js';
12
+ import { globalRuntime } from './context.js';
13
+ import { AbloValidationError } from './transaction/errors.js';
14
+ import { ModelScope } from './transaction/types/index.js';
15
+ import { ViewRegistry } from './views/ViewRegistry.js';
16
+ import { QueryView } from './views/QueryView.js';
17
17
  // Re-exported so `import { ModelScope } from './InstanceCache.js'` resolves
18
18
  export { ModelScope };
19
19
  /**
@@ -36,7 +36,7 @@ export class InstanceCache {
36
36
  // reactivity source; there are no computed getters with conditional cache
37
37
  // invalidation to get wrong.
38
38
  // Foreign key indexes: Map<"ModelType:fieldName", Map<fieldValue, ObservableSet<modelId>>>
39
- // Enables O(1) lookups like "all SlideLayer models where slideId = X"
39
+ // Enables O(1) lookups like "all Block models where sectionId = X"
40
40
  // instead of scanning all models of a type and filtering.
41
41
  foreignKeyIndexes = new Map();
42
42
  // Registry of which fields to index: Map<modelName, fieldName[]>
@@ -51,6 +51,7 @@ export class InstanceCache {
51
51
  };
52
52
  // Configuration
53
53
  config;
54
+ runtime;
54
55
  gcTimer;
55
56
  // ModelRegistry instance — single source of truth for model metadata
56
57
  registry;
@@ -106,6 +107,7 @@ export class InstanceCache {
106
107
  gcInterval: config.gcInterval ?? 60000, // 1 minute
107
108
  useWeakRefs: config.useWeakRefs ?? true,
108
109
  };
110
+ this.runtime = config.runtime ?? globalRuntime;
109
111
  // Store the model registry reference
110
112
  if (!modelRegistry) {
111
113
  throw new AbloValidationError('InstanceCache requires ModelRegistry for production-safe model name lookup', { code: 'pool_registry_missing' });
@@ -187,6 +189,39 @@ export class InstanceCache {
187
189
  this.metrics.hits++;
188
190
  return model ?? undefined;
189
191
  }
192
+ /**
193
+ * Look a row up **within one model**.
194
+ *
195
+ * The pool is a single id space: `get(id)` returns whatever row carries that
196
+ * id, whatever model it belongs to. That is the correct storage shape — ids
197
+ * are globally unique, the same premise as Relay's Global Object
198
+ * Identification — but it means an *untyped* lookup cannot stand in for a
199
+ * typed one. Apollo and EmberData avoid the question by keying their identity
200
+ * maps on `Type:id`; with unique ids the equivalent guarantee comes from
201
+ * stating the expected model at the lookup instead.
202
+ *
203
+ * Returns `undefined` for a row belonging to another model: from the asking
204
+ * model's perspective that id is simply absent. Callers that must tell "not
205
+ * here" apart from "here, but another model's" should compare against
206
+ * {@link get}.
207
+ *
208
+ * Prefer this over `get()` anywhere the caller knows which model it wants —
209
+ * `get()` returning another model's row has caused three product bugs, most
210
+ * recently a resize gesture that reverted after every commit.
211
+ */
212
+ // `T` appears only in the return position, which is normally a caller-chosen
213
+ // cast in disguise. It is sound here precisely because `modelName` is checked
214
+ // at runtime below before the row is handed back, so the caller's expected
215
+ // type and the row's registered identity cannot disagree.
216
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-parameters
217
+ getOfType(id, modelName) {
218
+ const model = this.get(id);
219
+ if (!model)
220
+ return undefined;
221
+ // Checked, so the assertion below is sound: `typeIndex` and
222
+ // `getModelName()` are the same registered-name identity.
223
+ return model.getModelName() === modelName ? model : undefined;
224
+ }
190
225
  /**
191
226
  * Add model with deduplication support
192
227
  */
@@ -231,7 +266,7 @@ export class InstanceCache {
231
266
  (history.lastAction === 'U' || history.lastAction === 'D')) {
232
267
  // Internal delta-ordering anomaly that reconciles on the next
233
268
  // catch-up — forensic, not consumer-actionable → debug.
234
- getContext().logger.debug(`InstanceCache.add() SUSPICIOUS: INSERT after ${history.lastAction}`, { modelType, id, syncId: deltaInfo.syncId });
269
+ this.runtime.logger.debug(`InstanceCache.add() SUSPICIOUS: INSERT after ${history.lastAction}`, { modelType, id, syncId: deltaInfo.syncId });
235
270
  }
236
271
  }
237
272
  // Update delta history
@@ -341,13 +376,13 @@ export class InstanceCache {
341
376
  this.addToTypeIndex(id, modelType);
342
377
  // Populate the foreign-key indexes. The single-item `add()` path
343
378
  // does this; `addBatch()` used to skip it, which meant every
344
- // layer / sheet cell / message that came in through a bulk
345
- // loader (`ensureDeckLayers`, `prefetchSlideLayers`, bootstrap
379
+ // block / ledger cell / message that came in through a bulk
380
+ // loader (`ensureReportBlocks`, `prefetchSectionBlocks`, bootstrap
346
381
  // hydration) was in the pool but invisible to `hasMany` lookups
347
- // — `slide.layers` returned `[]` until the user clicked a layer
382
+ // — `section.blocks` returned `[]` until the user clicked a block
348
383
  // and something else ran a non-batch `add` that happened to
349
384
  // populate the FK index as a side effect. The UX symptom was
350
- // "slides show empty until you click on one." Adding this one
385
+ // "sections show empty until you click on one." Adding this one
351
386
  // line closes the gap.
352
387
  this.addToForeignKeyIndex(id, model, modelType);
353
388
  this.metrics.additions++;
@@ -461,7 +496,7 @@ export class InstanceCache {
461
496
  // FK cleanup silently no-ops — leaving ghost ids in the FK index.
462
497
  // That causes `getByForeignKey(..., parentId)` to report
463
498
  // `matched > returned` (dropped-no-entry) and, on the UI, keeps the
464
- // stale layer visible until the next reload rebuilds the index
499
+ // stale block visible until the next reload rebuilds the index
465
500
  // from fresh data. Do the FK/type cleanup first, then delete the
466
501
  // entry.
467
502
  runInAction(() => {
@@ -506,7 +541,7 @@ export class InstanceCache {
506
541
  // This is expected during migration from hand-coded → dynamic models.
507
542
  }
508
543
  catch (e) {
509
- getContext().observability.breadcrumb(`Failed to create fallback instance for ${modelClass.name}`, 'sync.database', 'error', {
544
+ this.runtime.observability.breadcrumb(`Failed to create fallback instance for ${modelClass.name}`, 'sync.database', 'error', {
510
545
  error: e instanceof Error ? e.message : String(e),
511
546
  });
512
547
  return [];
@@ -598,7 +633,7 @@ export class InstanceCache {
598
633
  * data. Cleaner than `createFromData({ __typename, ...data })` — the
599
634
  * typename lives in the arg list, not hidden inside the data object.
600
635
  *
601
- * Used for optimistic local writes: `pool.create('Slide', { id, deckId, ... })`.
636
+ * Used for optimistic local writes: `pool.create('Section', { id, reportId, ... })`.
602
637
  * For hydration from server deltas (where `__typename` already rides on
603
638
  * the payload), use `createFromData(data)` directly — that path is kept
604
639
  * because the wire format attaches the discriminator to the data itself.
@@ -614,8 +649,8 @@ export class InstanceCache {
614
649
  if (modelName === 'Unknown') {
615
650
  // Malformed row with no type marker — dropped, but nothing the consumer
616
651
  // can act on (the actionable schema-drift case is handled below) → debug.
617
- getContext().logger.debug('InstanceCache.createFromData: No model identifier found', { data });
618
- getContext().modelDebugLogger?.logError('Unknown', 'CREATE', 'No model identifier found', data);
652
+ this.runtime.logger.debug('InstanceCache.createFromData: No model identifier found', { data });
653
+ this.runtime.modelDebugLogger?.logError('Unknown', 'CREATE', 'No model identifier found', data);
619
654
  return null;
620
655
  }
621
656
  if (opts?.strict) {
@@ -628,9 +663,9 @@ export class InstanceCache {
628
663
  // Genuinely actionable and NOT self-healing: a model the server is sending
629
664
  // isn't in your schema, so these rows are silently skipped. Keep at warn,
630
665
  // consumer register (their model name + the `ablo status` fix); forensics ride debug.
631
- getContext().logger.warn(`Received data for "${modelName}", which isn't in your schema — these rows will be skipped. Run \`ablo status\` to compare your local schema with the server.`);
632
- getContext().logger.debug(`InstanceCache.createFromData: No constructor found for model "${modelName}"`, { data });
633
- getContext().modelDebugLogger?.logError(modelName, 'CREATE', `No constructor found for model "${modelName}"`, data);
666
+ this.runtime.logger.warn(`Received data for "${modelName}", which isn't in your schema — these rows will be skipped. Run \`ablo status\` to compare your local schema with the server.`);
667
+ this.runtime.logger.debug(`InstanceCache.createFromData: No constructor found for model "${modelName}"`, { data });
668
+ this.runtime.modelDebugLogger?.logError(modelName, 'CREATE', `No constructor found for model "${modelName}"`, data);
634
669
  return null;
635
670
  }
636
671
  // If the model already exists, update it in place instead of creating a
@@ -643,11 +678,11 @@ export class InstanceCache {
643
678
  existing.updateFromData(data);
644
679
  return existing;
645
680
  }
646
- // Different type with same ID - this is a shared PK scenario (e.g., Project/Dataroom)
681
+ // Different type with same ID - this is a shared PK scenario (e.g., two models sharing one row id)
647
682
  // Don't return existing, create new model (will use composite key for storage)
648
683
  }
649
684
  // Log model creation attempt
650
- getContext().modelDebugLogger?.logCreation(modelName, data, Constructor);
685
+ this.runtime.modelDebugLogger?.logCreation(modelName, data, Constructor);
651
686
  try {
652
687
  // Pass data directly to constructor for Prisma-first models
653
688
  const model = new Constructor(data);
@@ -657,14 +692,14 @@ export class InstanceCache {
657
692
  const errorMessage = error instanceof Error ? error.message : String(error);
658
693
  // Internal construction failure — captured via observability below and
659
694
  // re-fetched on resync; the stack is forensic → debug.
660
- getContext().logger.debug(`[InstanceCache.createFromData] FAILED ${modelName}`, { errorMessage, stack: error instanceof Error ? error.stack : undefined });
661
- getContext().observability.captureTransactionFailure({
695
+ this.runtime.logger.debug(`[InstanceCache.createFromData] FAILED ${modelName}`, { errorMessage, stack: error instanceof Error ? error.stack : undefined });
696
+ this.runtime.observability.captureMutationFailure({
662
697
  context: 'createFromData',
663
698
  modelName,
664
699
  modelId: data.id,
665
700
  error: errorMessage,
666
701
  });
667
- getContext().modelDebugLogger?.logError(modelName, 'CREATE', errorMessage, {
702
+ this.runtime.modelDebugLogger?.logError(modelName, 'CREATE', errorMessage, {
668
703
  data,
669
704
  constructor: Constructor.name,
670
705
  });
@@ -849,7 +884,7 @@ export class InstanceCache {
849
884
  // caused silent data loss — any model actively being rendered
850
885
  // through a schema-driven dynamic class (i.e., most of them)
851
886
  // would be demoted, collected, and the next render's
852
- // `weakRef.deref()` returned undefined, so layers / cells /
887
+ // `weakRef.deref()` returned undefined, so blocks / cells /
853
888
  // messages "disappeared" after ~10 min of idle.
854
889
  //
855
890
  // The `hasObservedCollections()` guard used by the eviction
@@ -871,7 +906,7 @@ export class InstanceCache {
871
906
  }
872
907
  }
873
908
  if (skippedObserved > 0) {
874
- getContext().logger.debug(`[InstanceCache GC] Skipped ${skippedObserved} models with active React observers`);
909
+ this.runtime.logger.debug(`[InstanceCache GC] Skipped ${skippedObserved} models with active React observers`);
875
910
  }
876
911
  // Also clean up old tracking data
877
912
  this.clearDeltaHistory();
@@ -934,8 +969,8 @@ export class InstanceCache {
934
969
  * Register a foreign key field for indexing on a model type.
935
970
  * Call once during app initialization (e.g., after model registration).
936
971
  *
937
- * Example: registerForeignKey('SlideLayer', 'slideId')
938
- * This enables getByForeignKey('SlideLayer', 'slideId', someSlideId) → O(1) lookup
972
+ * Example: registerForeignKey('Block', 'sectionId')
973
+ * This enables getByForeignKey('Block', 'sectionId', someSectionId) → O(1) lookup
939
974
  */
940
975
  registerForeignKey(modelName, fieldName) {
941
976
  const fields = this.foreignKeyConfig.get(modelName) ?? [];
@@ -977,7 +1012,7 @@ export class InstanceCache {
977
1012
  // entry for this specific parent id (entity genuinely has no
978
1013
  // children). These used to `console.warn` diagnostic dumps on every
979
1014
  // call, which turned into hundreds of log lines per second during
980
- // cursor hover / rapid re-renders on the deck page. If a caller
1015
+ // cursor hover / rapid re-renders on a busy page. If a caller
981
1016
  // needs visibility into "why is this empty," wire an opt-in
982
1017
  // `logger.debug` at the specific call site rather than re-adding
983
1018
  // a blanket warn here.
@@ -1013,7 +1048,7 @@ export class InstanceCache {
1013
1048
  // has dangling refs (legacy orphan deltas, pending CREATE
1014
1049
  // transactions, etc.). Noisy at warn level, useful during
1015
1050
  // investigation.
1016
- getContext().logger.debug('[InstanceCache.getByForeignKey] ROWS DROPPED', {
1051
+ this.runtime.logger.debug('[InstanceCache.getByForeignKey] ROWS DROPPED', {
1017
1052
  modelName,
1018
1053
  fieldName,
1019
1054
  fieldValue,
@@ -86,9 +86,9 @@ export declare class LazyReferenceCollection<T extends Model> {
86
86
  * so any pool.remove invalidates the computed and re-renders the
87
87
  * consumer with the deleted item gone.
88
88
  *
89
- * Without this, deleting a slide layer would pool.remove() cleanly
90
- * but the canvas — which reads `slide.layers.value` — would keep
91
- * showing the deleted layer until a full reload rebuilt the
89
+ * Without this, deleting a block would pool.remove() cleanly
90
+ * but the view — which reads `section.blocks.value` — would keep
91
+ * showing the deleted block until a full reload rebuilt the
92
92
  * collection.
93
93
  */
94
94
  get value(): T[];
@@ -7,7 +7,7 @@ import { makeObservable, observable, action, computed, onBecomeObserved, onBecom
7
7
  import { Database } from './Database.js';
8
8
  import { InstanceCache } from './InstanceCache.js';
9
9
  import { getActiveRegistry } from './ModelRegistry.js';
10
- import { AbloValidationError } from './errors.js';
10
+ import { AbloValidationError } from './transaction/errors.js';
11
11
  /**
12
12
  * A lazy-loaded one-to-many relationship between a parent {@link Model} and
13
13
  * its children. It reads from the local store first and falls back to the
@@ -136,9 +136,9 @@ export class LazyReferenceCollection {
136
136
  * so any pool.remove invalidates the computed and re-renders the
137
137
  * consumer with the deleted item gone.
138
138
  *
139
- * Without this, deleting a slide layer would pool.remove() cleanly
140
- * but the canvas — which reads `slide.layers.value` — would keep
141
- * showing the deleted layer until a full reload rebuilt the
139
+ * Without this, deleting a block would pool.remove() cleanly
140
+ * but the view — which reads `section.blocks.value` — would keep
141
+ * showing the deleted block until a full reload rebuilt the
142
142
  * collection.
143
143
  */
144
144
  get value() {
package/dist/Model.d.ts CHANGED
@@ -120,10 +120,10 @@ export declare abstract class Model {
120
120
  * narrow the return to their concrete store type.
121
121
  *
122
122
  * @example
123
- * // In a Slide model getter
124
- * const store = Slide.getStore();
123
+ * // In a Section model getter
124
+ * const store = Section.getStore();
125
125
  * if (!store) return [];
126
- * return store.getByForeignKey<SlideLayer>('SlideLayer', 'slideId', this.id);
126
+ * return store.getByForeignKey<Block>('Block', 'sectionId', this.id);
127
127
  */
128
128
  static getStore<T extends SyncStoreRef = SyncStoreRef>(): T | null;
129
129
  /**
@@ -159,7 +159,7 @@ export declare abstract class Model {
159
159
  *
160
160
  * This per-instance baseline is needed because application code can edit a
161
161
  * model in two ways that coexist: a direct property write
162
- * (`slide.title = 'foo'`) and a recorded mutation. A design in which every
162
+ * (`section.title = 'foo'`) and a recorded mutation. A design in which every
163
163
  * write went through a single recorded path would not need it, since the
164
164
  * last acknowledged state would already be the authoritative baseline.
165
165
  */
@@ -172,8 +172,8 @@ export declare abstract class Model {
172
172
  * Capture a before-image for `keys` — the single source of truth for the
173
173
  * "previous value" that undo inverses are built from. Both undo paths call
174
174
  * this so they can never drift: the stream path
175
- * (`TransactionQueue.extractPreviousData`) and the manual-record path
176
- * (`RecordingTransaction.snapshotFields`).
175
+ * (`MutationQueue.extractPreviousData`) and the manual-record path
176
+ * (`RecordingMutation.snapshotFields`).
177
177
  *
178
178
  * Resolution order per key:
179
179
  * 1. `modifiedProperties.get(key).old` — first-old-wins pre-session
@@ -246,9 +246,16 @@ export declare abstract class Model {
246
246
  * written, `onWrite(key, oldValue, newValue)` is invoked with the value
247
247
  * captured immediately before assignment. `applyChanges` passes a hook
248
248
  * that records the change in `modifiedProperties`; `updateFromData`
249
- * passes none (hydration must not generate outbound mutations). This
250
- * is the single source of mutation tracking now that the `mobx-setup`
251
- * `observe()` bridge has been removed (one write path: the SDK proxy).
249
+ * passes none (hydration must not generate outbound mutations).
250
+ *
251
+ * This is not the ONLY tracking path. `mobxSetup`'s `observe()` bridge is
252
+ * live and forwards a DIRECT assignment (`layer.position = next`) to
253
+ * `propertyChanged` as well — product code writes model fields directly in
254
+ * plenty of places (keyboard nudge, formatting, AI tools), and those writes
255
+ * have to reach the server and the undo stream too. The two paths compose:
256
+ * a direct write establishes the first-old-wins baseline, and a later
257
+ * `applyChanges` carrying the value the model already holds is a no-op that
258
+ * leaves that baseline intact.
252
259
  */
253
260
  private assignFieldsFromData;
254
261
  /**
@@ -260,10 +267,13 @@ export declare abstract class Model {
260
267
  * brand-new outbound mutation and the record would echo forever. For a
261
268
  * local user edit, use `applyChanges` instead.
262
269
  *
263
- * Suppression is belt-and-suspenders: we pass no `onWrite` hook AND
264
- * clear/restore `modifiedProperties` around the assignment, so any
265
- * remaining `mobx-setup` `observe()` side-channel writes are discarded
266
- * too. (The clear/restore is a harmless no-op once that bridge is gone.)
270
+ * Suppression takes two forms and BOTH are load-bearing: we pass no
271
+ * `onWrite` hook, and we clear/restore `modifiedProperties` around the
272
+ * assignment. The second is what catches `mobxSetup`'s `observe()` bridge,
273
+ * which fires on the assignment itself and would otherwise record an
274
+ * inbound delta as a local edit — queueing an outbound mutation that echoes
275
+ * forever, and putting a collaborator's change on your undo stack. Do not
276
+ * remove it while that bridge exists (`mobxSetup.M1`).
267
277
  */
268
278
  updateFromData(data: ModelData): void;
269
279
  /**
package/dist/Model.js CHANGED
@@ -11,7 +11,7 @@ import { v4 as uuid } from 'uuid';
11
11
  import { M1 } from './utils/mobxSetup.js';
12
12
  import { getActiveRegistry, hasActiveRegistry } from './ModelRegistry.js';
13
13
  import { getContext } from './context.js';
14
- import { AbloValidationError } from './errors.js';
14
+ import { AbloValidationError } from './transaction/errors.js';
15
15
  /**
16
16
  * Validation error for model validation failures
17
17
  */
@@ -78,7 +78,7 @@ export class Model {
78
78
  // A record that arrives WITH `createdAt` but WITHOUT `updatedAt` is
79
79
  // server/IDB data whose update timestamp didn't survive the wire —
80
80
  // falling back to "now" here fabricated an edit time for every such
81
- // record on every bootstrap (the decks gallery sorted everything to
81
+ // record on every bootstrap (the reports gallery sorted everything to
82
82
  // "edited just now"). Fall back to createdAt instead; only a genuinely
83
83
  // new local model (no dates at all) stamps the current time.
84
84
  this.updatedAt = data.updatedAt
@@ -113,10 +113,10 @@ export class Model {
113
113
  * narrow the return to their concrete store type.
114
114
  *
115
115
  * @example
116
- * // In a Slide model getter
117
- * const store = Slide.getStore();
116
+ * // In a Section model getter
117
+ * const store = Section.getStore();
118
118
  * if (!store) return [];
119
- * return store.getByForeignKey<SlideLayer>('SlideLayer', 'slideId', this.id);
119
+ * return store.getByForeignKey<Block>('Block', 'sectionId', this.id);
120
120
  */
121
121
  static getStore() {
122
122
  return Model.store;
@@ -142,9 +142,9 @@ export class Model {
142
142
  // Preserve the earliest captured `old` for this field until the entry
143
143
  // is cleared (by `clearChanges` on sync-ack or by a mutator consuming
144
144
  // it). Consecutive in-place mutations between mutator invocations —
145
- // e.g. a drag loop writing `layer.position = ...` on every frame —
145
+ // e.g. a drag loop writing `block.position = ...` on every frame —
146
146
  // would otherwise overwrite `.old` with each frame's predecessor,
147
- // destroying the pre-session baseline that `RecordingTransaction`
147
+ // destroying the pre-session baseline that `RecordingMutation`
148
148
  // relies on to record a correct undo inverse. `.new` always reflects
149
149
  // the latest value so the transaction queue's `getChanges()` keeps
150
150
  // sending the right payload to the server.
@@ -194,7 +194,7 @@ export class Model {
194
194
  *
195
195
  * This per-instance baseline is needed because application code can edit a
196
196
  * model in two ways that coexist: a direct property write
197
- * (`slide.title = 'foo'`) and a recorded mutation. A design in which every
197
+ * (`section.title = 'foo'`) and a recorded mutation. A design in which every
198
198
  * write went through a single recorded path would not need it, since the
199
199
  * last acknowledged state would already be the authoritative baseline.
200
200
  */
@@ -214,8 +214,8 @@ export class Model {
214
214
  * Capture a before-image for `keys` — the single source of truth for the
215
215
  * "previous value" that undo inverses are built from. Both undo paths call
216
216
  * this so they can never drift: the stream path
217
- * (`TransactionQueue.extractPreviousData`) and the manual-record path
218
- * (`RecordingTransaction.snapshotFields`).
217
+ * (`MutationQueue.extractPreviousData`) and the manual-record path
218
+ * (`RecordingMutation.snapshotFields`).
219
219
  *
220
220
  * Resolution order per key:
221
221
  * 1. `modifiedProperties.get(key).old` — first-old-wins pre-session
@@ -428,9 +428,16 @@ export class Model {
428
428
  * written, `onWrite(key, oldValue, newValue)` is invoked with the value
429
429
  * captured immediately before assignment. `applyChanges` passes a hook
430
430
  * that records the change in `modifiedProperties`; `updateFromData`
431
- * passes none (hydration must not generate outbound mutations). This
432
- * is the single source of mutation tracking now that the `mobx-setup`
433
- * `observe()` bridge has been removed (one write path: the SDK proxy).
431
+ * passes none (hydration must not generate outbound mutations).
432
+ *
433
+ * This is not the ONLY tracking path. `mobxSetup`'s `observe()` bridge is
434
+ * live and forwards a DIRECT assignment (`layer.position = next`) to
435
+ * `propertyChanged` as well — product code writes model fields directly in
436
+ * plenty of places (keyboard nudge, formatting, AI tools), and those writes
437
+ * have to reach the server and the undo stream too. The two paths compose:
438
+ * a direct write establishes the first-old-wins baseline, and a later
439
+ * `applyChanges` carrying the value the model already holds is a no-op that
440
+ * leaves that baseline intact.
434
441
  */
435
442
  assignFieldsFromData(data, onWrite) {
436
443
  // Update properties with safety checks for read-only/computed accessors
@@ -489,10 +496,13 @@ export class Model {
489
496
  * brand-new outbound mutation and the record would echo forever. For a
490
497
  * local user edit, use `applyChanges` instead.
491
498
  *
492
- * Suppression is belt-and-suspenders: we pass no `onWrite` hook AND
493
- * clear/restore `modifiedProperties` around the assignment, so any
494
- * remaining `mobx-setup` `observe()` side-channel writes are discarded
495
- * too. (The clear/restore is a harmless no-op once that bridge is gone.)
499
+ * Suppression takes two forms and BOTH are load-bearing: we pass no
500
+ * `onWrite` hook, and we clear/restore `modifiedProperties` around the
501
+ * assignment. The second is what catches `mobxSetup`'s `observe()` bridge,
502
+ * which fires on the assignment itself and would otherwise record an
503
+ * inbound delta as a local edit — queueing an outbound mutation that echoes
504
+ * forever, and putting a collaborator's change on your undo stack. Do not
505
+ * remove it while that bridge exists (`mobxSetup.M1`).
496
506
  */
497
507
  updateFromData(data) {
498
508
  if (this.isDisposed) {
@@ -7,7 +7,8 @@
7
7
  * classes. References resolve lazily, so a model may declare a reference to
8
8
  * another model that is registered later.
9
9
  */
10
- import { type ModelMetadata, type PropertyMetadata, type ReferenceMetadata, LoadStrategy } from './types/index.js';
10
+ import { type ModelMetadata, type PropertyMetadata, type ReferenceMetadata, LoadStrategy } from './transaction/types/index.js';
11
+ import type { RuntimeContext } from './RuntimeContext.js';
11
12
  import type { Model } from './Model.js';
12
13
  import type { ConcreteModelConstructor } from './BaseSyncedStore.js';
13
14
  /**
@@ -51,9 +52,9 @@ export interface SerializedReferenceMetadata extends Omit<ExtendedReferenceMetad
51
52
  * child's pending transactions can be cancelled.
52
53
  */
53
54
  export interface BackReferenceMetadata {
54
- /** The parent model name (e.g., 'SlideDeck') */
55
+ /** The parent model name (e.g., 'Report') */
55
56
  parentModel: string;
56
- /** The foreign key property on this model (e.g., 'deckId') */
57
+ /** The foreign key property on this model (e.g., 'reportId') */
57
58
  foreignKey: string;
58
59
  /** Whether to cascade-cancel transactions when parent is deleted */
59
60
  cascadeDelete: boolean;
@@ -61,6 +62,8 @@ export interface BackReferenceMetadata {
61
62
  interface RegistryConfig {
62
63
  validateOnRegister?: boolean;
63
64
  allowLateReferences?: boolean;
65
+ /** The owning client's runtime. Defaults to the module-global bridge. */
66
+ runtime?: RuntimeContext;
64
67
  }
65
68
  /** Set the active ModelRegistry instance (called by createSyncEngine) */
66
69
  export declare function setActiveRegistry(registry: ModelRegistry): void;
@@ -80,6 +83,7 @@ export declare class ModelRegistry {
80
83
  private backReferences;
81
84
  private schemaHash?;
82
85
  private config;
86
+ private readonly runtime;
83
87
  private registeredModels;
84
88
  private pendingHashUpdate;
85
89
  constructor(config?: RegistryConfig);
@@ -107,7 +111,7 @@ export declare class ModelRegistry {
107
111
  * transactions for every child model that declares a back-reference to that
108
112
  * parent.
109
113
  *
110
- * @param childModelName - The model that holds a foreign key to the parent (e.g., 'Slide')
114
+ * @param childModelName - The model that holds a foreign key to the parent (e.g., 'Section')
111
115
  * @param metadata - The back-reference configuration
112
116
  */
113
117
  registerBackReference(childModelName: string, metadata: BackReferenceMetadata): void;
@@ -8,9 +8,9 @@
8
8
  * another model that is registered later.
9
9
  */
10
10
  // Removed Node.js crypto import for browser compatibility
11
- import { PropertyType, LoadStrategy, } from './types/index.js';
12
- import { getContext } from './context.js';
13
- import { AbloValidationError } from './errors.js';
11
+ import { PropertyType, LoadStrategy, } from './transaction/types/index.js';
12
+ import { globalRuntime } from './context.js';
13
+ import { AbloValidationError } from './transaction/errors.js';
14
14
  /**
15
15
  * Module-level active registry. Set by createSyncEngine so that Model instances
16
16
  * (which don't receive DI) can look up metadata without static maps.
@@ -51,6 +51,7 @@ export class ModelRegistry {
51
51
  backReferences = new Map();
52
52
  schemaHash;
53
53
  config;
54
+ runtime;
54
55
  registeredModels = new Set();
55
56
  pendingHashUpdate = false;
56
57
  constructor(config = {}) {
@@ -58,6 +59,7 @@ export class ModelRegistry {
58
59
  validateOnRegister: config.validateOnRegister ?? true,
59
60
  allowLateReferences: config.allowLateReferences ?? true,
60
61
  };
62
+ this.runtime = config.runtime ?? globalRuntime;
61
63
  }
62
64
  validateModelConstructor(name, constructor) {
63
65
  if (typeof constructor !== 'function') {
@@ -71,7 +73,7 @@ export class ModelRegistry {
71
73
  const required = ['updateFromData', 'toJSON', 'getModelName'];
72
74
  for (const method of required) {
73
75
  if (typeof prototype[method] !== 'function') {
74
- getContext().logger.debug('Model missing required method', name, { method });
76
+ this.runtime.logger.debug('Model missing required method', name, { method });
75
77
  }
76
78
  }
77
79
  }
@@ -99,7 +101,7 @@ export class ModelRegistry {
99
101
  this.pendingReferences.set(targetName, pending);
100
102
  }
101
103
  pending.push({ modelName, propertyName, metadata });
102
- getContext().logger.debug('Reference deferred', `${modelName}.${propertyName}`, { targetModel: targetName });
104
+ this.runtime.logger.debug('Reference deferred', `${modelName}.${propertyName}`, { targetModel: targetName });
103
105
  }
104
106
  resolvePendingReferences(targetModelName) {
105
107
  const pending = this.pendingReferences.get(targetModelName);
@@ -108,12 +110,12 @@ export class ModelRegistry {
108
110
  for (const ref of pending) {
109
111
  try {
110
112
  this.completeReferenceRegistration(ref.modelName, ref.propertyName, ref.metadata);
111
- getContext().logger.debug('Reference resolved', `${ref.modelName}.${ref.propertyName}`, {
113
+ this.runtime.logger.debug('Reference resolved', `${ref.modelName}.${ref.propertyName}`, {
112
114
  targetModel: targetModelName,
113
115
  });
114
116
  }
115
117
  catch (error) {
116
- getContext().observability.breadcrumb(`Failed to resolve reference ${ref.modelName}.${ref.propertyName}`, 'sync.database', 'error', {
118
+ this.runtime.observability.breadcrumb(`Failed to resolve reference ${ref.modelName}.${ref.propertyName}`, 'sync.database', 'error', {
117
119
  error: error instanceof Error ? error.message : String(error),
118
120
  });
119
121
  }
@@ -154,10 +156,10 @@ export class ModelRegistry {
154
156
  }
155
157
  // Check for duplicate
156
158
  if (this.models.has(name)) {
157
- getContext().logger.debug('Model already registered, skipping', name);
159
+ this.runtime.logger.debug('Model already registered, skipping', name);
158
160
  return;
159
161
  }
160
- getContext().logger.debug('Registering model', name);
162
+ this.runtime.logger.debug('Registering model', name);
161
163
  // Register. The one cast in this file: input is any Model-subclass
162
164
  // constructor (validated above); registered classes are concrete
163
165
  // subclasses constructible with `data?` and carrying Model's statics —
@@ -180,7 +182,7 @@ export class ModelRegistry {
180
182
  this.resolvePendingReferences(name);
181
183
  // Invalidate schema hash
182
184
  this.schemaHash = undefined;
183
- getContext().logger.debug('Model registered', name, metadata);
185
+ this.runtime.logger.debug('Model registered', name, metadata);
184
186
  }
185
187
  /**
186
188
  * Register property with validation
@@ -201,7 +203,7 @@ export class ModelRegistry {
201
203
  if (existing) {
202
204
  if (this.arePropertiesCompatible(existing, metadata)) {
203
205
  // Properties are compatible, skip re-registration
204
- getContext().logger.debug('Property already registered (compatible)', `${modelName}.${propertyName}`);
206
+ this.runtime.logger.debug('Property already registered (compatible)', `${modelName}.${propertyName}`);
205
207
  return;
206
208
  }
207
209
  else {
@@ -210,7 +212,7 @@ export class ModelRegistry {
210
212
  }
211
213
  props.set(propertyName, metadata);
212
214
  this.schemaHash = undefined;
213
- getContext().logger.debug('Property registered', `${modelName}.${propertyName}`, metadata);
215
+ this.runtime.logger.debug('Property registered', `${modelName}.${propertyName}`, metadata);
214
216
  }
215
217
  /**
216
218
  * Register reference with lazy resolution
@@ -248,7 +250,7 @@ export class ModelRegistry {
248
250
  * transactions for every child model that declares a back-reference to that
249
251
  * parent.
250
252
  *
251
- * @param childModelName - The model that holds a foreign key to the parent (e.g., 'Slide')
253
+ * @param childModelName - The model that holds a foreign key to the parent (e.g., 'Section')
252
254
  * @param metadata - The back-reference configuration
253
255
  */
254
256
  registerBackReference(childModelName, metadata) {
@@ -265,7 +267,7 @@ export class ModelRegistry {
265
267
  }
266
268
  // Reverse lookup (parent → children) is derived on demand by
267
269
  // `getChildModels`, which scans this map.
268
- getContext().logger.debug('BackReference registered', `${childModelName} -> ${metadata.parentModel}`, {
270
+ this.runtime.logger.debug('BackReference registered', `${childModelName} -> ${metadata.parentModel}`, {
269
271
  foreignKey: metadata.foreignKey,
270
272
  cascadeDelete: metadata.cascadeDelete,
271
273
  });
@@ -365,7 +367,7 @@ export class ModelRegistry {
365
367
  const sorted = JSON.stringify(schema, Object.keys(schema).sort());
366
368
  // Create hash - browser-compatible simple hash
367
369
  this.schemaHash = this.simpleHash(sorted);
368
- getContext().logger.debug('Schema hash updated', this.schemaHash);
370
+ this.runtime.logger.debug('Schema hash updated', this.schemaHash);
369
371
  return this.schemaHash;
370
372
  }
371
373
  /**
@@ -410,10 +412,10 @@ export class ModelRegistry {
410
412
  }
411
413
  const isValid = errors.length === 0;
412
414
  if (isValid) {
413
- getContext().logger.info('All model references are valid');
415
+ this.runtime.logger.info('All model references are valid');
414
416
  }
415
417
  else {
416
- getContext().observability.breadcrumb('Reference validation failed', 'sync.database', 'error');
418
+ this.runtime.observability.breadcrumb('Reference validation failed', 'sync.database', 'error');
417
419
  }
418
420
  return {
419
421
  valid: isValid,
@@ -458,7 +460,7 @@ export class ModelRegistry {
458
460
  this.constructorToModelName.clear();
459
461
  this.schemaHash = undefined;
460
462
  this.pendingHashUpdate = false;
461
- getContext().logger.info('ModelRegistry cleared');
463
+ this.runtime.logger.info('ModelRegistry cleared');
462
464
  }
463
465
  /**
464
466
  * Static wrapper for backward compatibility