@abloatai/ablo 0.34.1 → 0.35.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (483) hide show
  1. package/AGENTS.md +2 -1
  2. package/CHANGELOG.md +674 -5
  3. package/README.md +39 -22
  4. package/dist/BaseSyncedStore.d.ts +152 -44
  5. package/dist/BaseSyncedStore.js +300 -184
  6. package/dist/Database.d.ts +9 -24
  7. package/dist/Database.js +37 -22
  8. package/dist/InstanceCache.d.ts +25 -4
  9. package/dist/InstanceCache.js +48 -15
  10. package/dist/LazyReferenceCollection.d.ts +3 -3
  11. package/dist/LazyReferenceCollection.js +4 -4
  12. package/dist/Model.d.ts +6 -6
  13. package/dist/Model.js +10 -10
  14. package/dist/ModelRegistry.d.ts +4 -4
  15. package/dist/ModelRegistry.js +3 -3
  16. package/dist/{SyncEngineContext.d.ts → RuntimeContext.d.ts} +20 -13
  17. package/dist/{SyncEngineContext.js → RuntimeContext.js} +11 -12
  18. package/dist/SyncClient.d.ts +42 -32
  19. package/dist/SyncClient.js +166 -110
  20. package/dist/ai-sdk/coordinatedTool.d.ts +2 -2
  21. package/dist/ai-sdk/coordinatedTool.js +1 -1
  22. package/dist/ai-sdk/coordinationContext.d.ts +2 -2
  23. package/dist/ai-sdk/coordinationContext.js +1 -1
  24. package/dist/ai-sdk/wrap.d.ts +3 -3
  25. package/dist/ai-sdk/wrap.js +2 -2
  26. package/dist/auth/index.d.ts +1 -156
  27. package/dist/auth/index.js +8 -301
  28. package/dist/cli.cjs +3344 -1073
  29. package/dist/client/Ablo.d.ts +42 -287
  30. package/dist/client/Ablo.js +118 -963
  31. package/dist/client/abloClient.d.ts +309 -0
  32. package/dist/client/abloClient.js +13 -0
  33. package/dist/client/clientPrelude.d.ts +52 -0
  34. package/dist/client/clientPrelude.js +60 -0
  35. package/dist/client/consoleLogger.d.ts +2 -2
  36. package/dist/client/coreClient.d.ts +60 -0
  37. package/dist/client/coreClient.js +118 -0
  38. package/dist/client/createInternalComponents.d.ts +4 -4
  39. package/dist/client/createInternalComponents.js +9 -8
  40. package/dist/client/createModelProxy.d.ts +78 -373
  41. package/dist/client/createModelProxy.js +114 -86
  42. package/dist/client/humans.d.ts +48 -0
  43. package/dist/client/humans.js +52 -0
  44. package/dist/client/modelRegistration.d.ts +1 -1
  45. package/dist/client/modelRegistration.js +9 -9
  46. package/dist/client/options.d.ts +73 -17
  47. package/dist/client/reactiveEngine.d.ts +48 -0
  48. package/dist/client/reactiveEngine.js +910 -0
  49. package/dist/client/resourceTypes.d.ts +9 -250
  50. package/dist/client/resourceTypes.js +8 -5
  51. package/dist/client/schemaConfig.d.ts +4 -4
  52. package/dist/client/schemaConfig.js +6 -2
  53. package/dist/client/validateAbloOptions.d.ts +3 -2
  54. package/dist/client/validateAbloOptions.js +1 -1
  55. package/dist/client/wsMutationExecutor.d.ts +3 -3
  56. package/dist/client/wsMutationExecutor.js +3 -3
  57. package/dist/context.d.ts +9 -9
  58. package/dist/context.js +10 -9
  59. package/dist/coordination/ClaimLog.d.ts +26 -0
  60. package/dist/coordination/ClaimLog.js +32 -0
  61. package/dist/coordination/index.d.ts +1 -15
  62. package/dist/coordination/index.js +8 -31
  63. package/dist/core/DatabaseManager.js +1 -1
  64. package/dist/core/QueryView.d.ts +1 -1
  65. package/dist/core/QueryView.js +1 -1
  66. package/dist/core/StoreManager.d.ts +4 -23
  67. package/dist/core/StoreManager.js +5 -55
  68. package/dist/core/index.d.ts +2 -2
  69. package/dist/core/index.js +2 -2
  70. package/dist/core/storeContract.d.ts +2 -2
  71. package/dist/docs/catalog.d.ts +72 -0
  72. package/dist/docs/catalog.js +227 -0
  73. package/dist/docs/index.d.ts +10 -0
  74. package/dist/docs/index.js +10 -0
  75. package/dist/environment.d.ts +1 -40
  76. package/dist/environment.js +8 -37
  77. package/dist/index.d.ts +40 -34
  78. package/dist/index.js +26 -20
  79. package/dist/interfaces/index.d.ts +44 -134
  80. package/dist/keys/index.d.ts +1 -77
  81. package/dist/keys/index.js +8 -190
  82. package/dist/mutators/{RecordingTransaction.d.ts → RecordingMutation.d.ts} +4 -4
  83. package/dist/mutators/{RecordingTransaction.js → RecordingMutation.js} +2 -2
  84. package/dist/mutators/Transaction.d.ts +1 -1
  85. package/dist/mutators/Transaction.js +1 -1
  86. package/dist/mutators/UndoManager.d.ts +6 -6
  87. package/dist/mutators/UndoManager.js +5 -5
  88. package/dist/mutators/defineMutators.d.ts +3 -3
  89. package/dist/mutators/defineMutators.js +1 -1
  90. package/dist/mutators/inverseOp.js +2 -2
  91. package/dist/mutators/mutateActions.d.ts +3 -3
  92. package/dist/mutators/mutateActions.js +1 -1
  93. package/dist/mutators/readerActions.d.ts +1 -1
  94. package/dist/mutators/undoApply.d.ts +1 -1
  95. package/dist/mutators/undoApply.js +1 -1
  96. package/dist/policy/index.d.ts +2 -2
  97. package/dist/policy/index.js +1 -1
  98. package/dist/query/client.d.ts +2 -2
  99. package/dist/query/client.js +4 -4
  100. package/dist/query/types.d.ts +6 -41
  101. package/dist/query/types.js +2 -2
  102. package/dist/react/AbloProvider.d.ts +6 -8
  103. package/dist/react/AbloProvider.js +5 -7
  104. package/dist/react/context.d.ts +1 -1
  105. package/dist/react/context.js +1 -1
  106. package/dist/react/index.d.ts +5 -5
  107. package/dist/react/index.js +3 -3
  108. package/dist/react/internalContext.d.ts +1 -1
  109. package/dist/react/useAblo.d.ts +3 -3
  110. package/dist/react/useAblo.js +1 -1
  111. package/dist/react/useCurrentUserId.js +1 -1
  112. package/dist/react/useErrorListener.js +1 -1
  113. package/dist/react/useMutationFailureListener.d.ts +2 -2
  114. package/dist/react/useMutationFailureListener.js +1 -1
  115. package/dist/react/useMutators.d.ts +3 -3
  116. package/dist/react/useMutators.js +3 -3
  117. package/dist/react/useUndoScope.d.ts +5 -5
  118. package/dist/react/useUndoScope.js +1 -1
  119. package/dist/schema/coordination.d.ts +69 -10
  120. package/dist/schema/coordination.js +86 -9
  121. package/dist/schema/ddl.js +2 -2
  122. package/dist/schema/diff.d.ts +1 -1
  123. package/dist/schema/generate.js +1 -1
  124. package/dist/schema/index.d.ts +10 -10
  125. package/dist/schema/index.js +18 -18
  126. package/dist/schema/queries.d.ts +27 -27
  127. package/dist/schema/queries.js +23 -23
  128. package/dist/schema/select.d.ts +3 -3
  129. package/dist/schema/select.js +3 -3
  130. package/dist/schema/serialize.d.ts +15 -6
  131. package/dist/schema/serialize.js +17 -3
  132. package/dist/schema/sugar.d.ts +6 -7
  133. package/dist/schema/sugar.js +9 -12
  134. package/dist/schema/syncDeltaRow.d.ts +4 -152
  135. package/dist/schema/syncDeltaRow.js +4 -105
  136. package/dist/server/adapter.d.ts +18 -1
  137. package/dist/server/commit.d.ts +10 -16
  138. package/dist/server/index.d.ts +1 -1
  139. package/dist/server/index.js +1 -1
  140. package/dist/server/readConfig.d.ts +1 -1
  141. package/dist/source/adapters/drizzle.d.ts +1 -1
  142. package/dist/source/adapters/drizzle.js +2 -2
  143. package/dist/source/adapters/kysely.d.ts +1 -1
  144. package/dist/source/adapters/kysely.js +1 -1
  145. package/dist/source/adapters/kyselyMutationCore.d.ts +1 -1
  146. package/dist/source/adapters/kyselyMutationCore.js +2 -2
  147. package/dist/source/adapters/memory.js +1 -1
  148. package/dist/source/adapters/prisma.d.ts +8 -3
  149. package/dist/source/adapters/prisma.js +1 -1
  150. package/dist/source/connector.js +1 -1
  151. package/dist/source/connectorProtocol.d.ts +2 -8
  152. package/dist/source/connectorProtocol.js +3 -2
  153. package/dist/source/contract.d.ts +29 -17
  154. package/dist/source/contract.js +27 -22
  155. package/dist/source/factory.d.ts +1 -1
  156. package/dist/source/footprint.d.ts +111 -0
  157. package/dist/source/footprint.js +0 -0
  158. package/dist/source/idempotency.js +2 -2
  159. package/dist/source/index.d.ts +1 -0
  160. package/dist/source/index.js +3 -0
  161. package/dist/source/next.d.ts +1 -1
  162. package/dist/source/signing.d.ts +9 -2
  163. package/dist/source/signing.js +4 -1
  164. package/dist/source/types.d.ts +6 -4
  165. package/dist/source/types.js +1 -1
  166. package/dist/stores/ObjectStore.d.ts +1 -1
  167. package/dist/stores/SyncActionStore.d.ts +1 -1
  168. package/dist/stores/SyncActionStore.js +2 -10
  169. package/dist/stores/syncAction.d.ts +26 -0
  170. package/dist/stores/syncAction.js +16 -0
  171. package/dist/surface.d.ts +3 -3
  172. package/dist/surface.js +6 -4
  173. package/dist/sync/BootstrapFetcher.d.ts +123 -6
  174. package/dist/sync/BootstrapFetcher.js +492 -66
  175. package/dist/sync/ConnectionManager.d.ts +6 -198
  176. package/dist/sync/ConnectionManager.js +6 -677
  177. package/dist/sync/OnDemandLoader.d.ts +2 -2
  178. package/dist/sync/OnDemandLoader.js +60 -21
  179. package/dist/sync/SubscriptionManager.d.ts +13 -2
  180. package/dist/sync/SubscriptionManager.js +23 -5
  181. package/dist/sync/SyncWebSocket.d.ts +27 -510
  182. package/dist/sync/SyncWebSocket.js +76 -954
  183. package/dist/sync/awaitClaimGrant.d.ts +4 -44
  184. package/dist/sync/awaitClaimGrant.js +4 -109
  185. package/dist/sync/commitFrames.d.ts +6 -40
  186. package/dist/sync/commitFrames.js +6 -97
  187. package/dist/sync/contextPorts.d.ts +18 -0
  188. package/dist/sync/contextPorts.js +31 -0
  189. package/dist/sync/createClaimStream.d.ts +5 -49
  190. package/dist/sync/createClaimStream.js +5 -469
  191. package/dist/sync/createPresenceStream.d.ts +26 -4
  192. package/dist/sync/createPresenceStream.js +28 -20
  193. package/dist/sync/createSnapshot.d.ts +2 -2
  194. package/dist/sync/createSnapshot.js +1 -1
  195. package/dist/sync/credentialLifecycle.d.ts +5 -173
  196. package/dist/sync/credentialLifecycle.js +5 -320
  197. package/dist/sync/deltaPipeline.d.ts +1 -1
  198. package/dist/sync/participants.d.ts +5 -4
  199. package/dist/sync/participants.js +29 -22
  200. package/dist/sync/schemaDrift.d.ts +55 -0
  201. package/dist/sync/schemaDrift.js +53 -0
  202. package/dist/sync/schemas.d.ts +21 -32
  203. package/dist/sync/schemas.js +26 -17
  204. package/dist/sync/syncPlan.d.ts +3 -3
  205. package/dist/sync/wsFrameHandlers.d.ts +6 -114
  206. package/dist/sync/wsFrameHandlers.js +6 -392
  207. package/dist/testing/fixtures/bootstrap.d.ts +1 -1
  208. package/dist/testing/fixtures/deltas.d.ts +1 -1
  209. package/dist/testing/fixtures/httpResponses.d.ts +70 -0
  210. package/dist/testing/fixtures/httpResponses.js +90 -0
  211. package/dist/testing/fixtures/models.js +1 -1
  212. package/dist/testing/helpers/wait.js +1 -1
  213. package/dist/testing/mocks/MockMutationExecutor.d.ts +2 -2
  214. package/dist/testing/mocks/MockMutationExecutor.js +8 -14
  215. package/dist/testing/mocks/MockSyncContext.d.ts +11 -11
  216. package/dist/testing/mocks/MockSyncContext.js +10 -9
  217. package/dist/testing/mocks/MockSyncStore.js +1 -1
  218. package/dist/testing/mocks/MockWebSocket.d.ts +2 -2
  219. package/dist/transaction/ablo.d.ts +88 -0
  220. package/dist/transaction/ablo.js +33 -0
  221. package/dist/{client/auth.d.ts → transaction/auth/apiKey.d.ts} +43 -8
  222. package/dist/{client/auth.js → transaction/auth/apiKey.js} +19 -0
  223. package/dist/transaction/auth/bootstrapScope.d.ts +15 -0
  224. package/dist/transaction/auth/bootstrapScope.js +1 -0
  225. package/dist/transaction/auth/capability.d.ts +177 -0
  226. package/dist/transaction/auth/capability.js +199 -0
  227. package/dist/{auth → transaction/auth}/credentialSource.d.ts +8 -1
  228. package/dist/{client → transaction/auth}/identity.d.ts +8 -7
  229. package/dist/{client → transaction/auth}/identity.js +1 -1
  230. package/dist/transaction/auth/index.d.ts +162 -0
  231. package/dist/transaction/auth/index.js +304 -0
  232. package/dist/{auth → transaction/auth}/schemas.d.ts +1 -1
  233. package/dist/{auth → transaction/auth}/schemas.js +13 -13
  234. package/dist/{client → transaction/auth}/sessionMint.d.ts +8 -8
  235. package/dist/{client → transaction/auth}/sessionMint.js +4 -7
  236. package/dist/transaction/coordination/awaitClaimGrant.d.ts +49 -0
  237. package/dist/transaction/coordination/awaitClaimGrant.js +112 -0
  238. package/dist/transaction/coordination/claimMeta.d.ts +49 -0
  239. package/dist/transaction/coordination/claimMeta.js +52 -0
  240. package/dist/transaction/coordination/createClaimStream.d.ts +64 -0
  241. package/dist/transaction/coordination/createClaimStream.js +475 -0
  242. package/dist/transaction/coordination/events.d.ts +74 -0
  243. package/dist/transaction/coordination/events.js +7 -0
  244. package/dist/transaction/coordination/index.d.ts +19 -0
  245. package/dist/transaction/coordination/index.js +44 -0
  246. package/dist/transaction/coordination/locator.d.ts +83 -0
  247. package/dist/transaction/coordination/locator.js +82 -0
  248. package/dist/transaction/coordination/schema.d.ts +1473 -0
  249. package/dist/{coordination → transaction/coordination}/schema.js +490 -55
  250. package/dist/transaction/coordination/targetConflict.d.ts +2 -0
  251. package/dist/transaction/coordination/targetConflict.js +103 -0
  252. package/dist/{coordination → transaction/coordination}/trace.d.ts +7 -18
  253. package/dist/{coordination → transaction/coordination}/trace.js +18 -25
  254. package/dist/transaction/durableWrites.d.ts +62 -0
  255. package/dist/{client → transaction}/durableWrites.js +28 -3
  256. package/dist/transaction/environment.d.ts +105 -0
  257. package/dist/transaction/environment.js +108 -0
  258. package/dist/{errorCodes.d.ts → transaction/errorCodes.d.ts} +11 -11
  259. package/dist/{errorCodes.js → transaction/errorCodes.js} +35 -12
  260. package/dist/{errors.d.ts → transaction/errors.d.ts} +37 -13
  261. package/dist/{errors.js → transaction/errors.js} +85 -16
  262. package/dist/transaction/index.d.ts +20 -0
  263. package/dist/transaction/index.js +20 -0
  264. package/dist/transaction/keys/index.d.ts +87 -0
  265. package/dist/transaction/keys/index.js +207 -0
  266. package/dist/transaction/log/syncDeltaRow.d.ts +158 -0
  267. package/dist/transaction/log/syncDeltaRow.js +95 -0
  268. package/dist/{sync/syncPosition.d.ts → transaction/logPosition.d.ts} +22 -8
  269. package/dist/{sync/syncPosition.js → transaction/logPosition.js} +15 -6
  270. package/dist/transaction/logger.d.ts +16 -0
  271. package/dist/transaction/logger.js +7 -0
  272. package/dist/transaction/observability.d.ts +53 -0
  273. package/dist/transaction/observability.js +19 -0
  274. package/dist/transaction/plugin.d.ts +192 -0
  275. package/dist/transaction/plugin.js +87 -0
  276. package/dist/{policy → transaction/policy}/types.d.ts +3 -3
  277. package/dist/{policy → transaction/policy}/types.js +2 -0
  278. package/dist/transaction/resources/httpResources.d.ts +266 -0
  279. package/dist/transaction/resources/httpResources.js +7 -0
  280. package/dist/transaction/resources/modelOperations.d.ts +319 -0
  281. package/dist/transaction/resources/modelOperations.js +12 -0
  282. package/dist/transaction/resources/mutationOptions.d.ts +66 -0
  283. package/dist/transaction/resources/mutationOptions.js +9 -0
  284. package/dist/transaction/resources/where.d.ts +85 -0
  285. package/dist/transaction/resources/where.js +70 -0
  286. package/dist/{client → transaction/resources}/writeOptionsSchema.d.ts +2 -6
  287. package/dist/{client → transaction/resources}/writeOptionsSchema.js +9 -5
  288. package/dist/{schema → transaction/schema}/field.d.ts +5 -5
  289. package/dist/{schema → transaction/schema}/field.js +5 -5
  290. package/dist/transaction/schema/loadStrategy.d.ts +45 -0
  291. package/dist/transaction/schema/loadStrategy.js +46 -0
  292. package/dist/{schema → transaction/schema}/model.d.ts +50 -35
  293. package/dist/{schema → transaction/schema}/model.js +30 -20
  294. package/dist/transaction/schema/openapi.d.ts +57 -0
  295. package/dist/transaction/schema/openapi.js +340 -0
  296. package/dist/{schema → transaction/schema}/relation.d.ts +14 -14
  297. package/dist/{schema → transaction/schema}/relation.js +7 -7
  298. package/dist/{schema → transaction/schema}/residency.d.ts +0 -9
  299. package/dist/{schema → transaction/schema}/residency.js +0 -5
  300. package/dist/{schema → transaction/schema}/roles.d.ts +5 -5
  301. package/dist/{schema → transaction/schema}/roles.js +5 -5
  302. package/dist/{schema → transaction/schema}/schema.d.ts +12 -10
  303. package/dist/{schema → transaction/schema}/schema.js +4 -3
  304. package/dist/{schema → transaction/schema}/tenancy.d.ts +1 -1
  305. package/dist/{schema → transaction/schema}/tenancy.js +7 -4
  306. package/dist/transaction/transactionLayer.d.ts +82 -0
  307. package/dist/transaction/transactionLayer.js +24 -0
  308. package/dist/{transactions → transaction/transactions/settlement}/commitEnvelope.d.ts +4 -5
  309. package/dist/{transactions → transaction/transactions/settlement}/commitEnvelope.js +9 -13
  310. package/dist/{transactions → transaction/transactions/settlement}/httpCommitEnvelope.d.ts +9 -2
  311. package/dist/{transactions → transaction/transactions/settlement}/httpCommitEnvelope.js +5 -9
  312. package/dist/{transactions/durableWriteStore.d.ts → transaction/transactions/settlement/pendingWrite.d.ts} +10 -36
  313. package/dist/transaction/transactions/settlement/pendingWrite.js +20 -0
  314. package/dist/transaction/transport/commitFrames.d.ts +90 -0
  315. package/dist/transaction/transport/commitFrames.js +134 -0
  316. package/dist/transaction/transport/connectionManager.d.ts +215 -0
  317. package/dist/transaction/transport/connectionManager.js +673 -0
  318. package/dist/transaction/transport/credentialLifecycle.d.ts +177 -0
  319. package/dist/transaction/transport/credentialLifecycle.js +324 -0
  320. package/dist/{sync → transaction/transport}/heartbeat.d.ts +3 -1
  321. package/dist/{sync → transaction/transport}/heartbeat.js +6 -4
  322. package/dist/{client → transaction/transport}/httpClient.d.ts +59 -16
  323. package/dist/{client → transaction/transport}/httpClient.js +5 -5
  324. package/dist/transaction/transport/httpOptions.d.ts +33 -0
  325. package/dist/transaction/transport/httpOptions.js +12 -0
  326. package/dist/{client → transaction/transport}/httpTransport.js +171 -85
  327. package/dist/{sync/NetworkProbe.d.ts → transaction/transport/networkProbe.d.ts} +7 -4
  328. package/dist/{sync/NetworkProbe.js → transaction/transport/networkProbe.js} +14 -13
  329. package/dist/transaction/transport/wsFrameHandlers.d.ts +128 -0
  330. package/dist/transaction/transport/wsFrameHandlers.js +429 -0
  331. package/dist/transaction/transport/wsTransport.d.ts +576 -0
  332. package/dist/transaction/transport/wsTransport.js +1017 -0
  333. package/dist/transaction/types/assertExact.d.ts +17 -0
  334. package/dist/transaction/types/assertExact.js +1 -0
  335. package/dist/{types → transaction/types}/global.d.ts +17 -2
  336. package/dist/{types → transaction/types}/global.js +2 -1
  337. package/dist/{types → transaction/types}/index.d.ts +14 -46
  338. package/dist/{types → transaction/types}/index.js +7 -16
  339. package/dist/{types → transaction/types}/streams.d.ts +63 -45
  340. package/dist/{utils → transaction/utils}/json.d.ts +18 -0
  341. package/dist/transaction/utils/json.js +276 -0
  342. package/dist/transaction/wire/accountResponses.d.ts +351 -0
  343. package/dist/transaction/wire/accountResponses.js +255 -0
  344. package/dist/transaction/wire/auth.d.ts +49 -0
  345. package/dist/transaction/wire/auth.js +57 -0
  346. package/dist/transaction/wire/claimEvent.d.ts +76 -0
  347. package/dist/transaction/wire/claimEvent.js +73 -0
  348. package/dist/transaction/wire/claims.d.ts +463 -0
  349. package/dist/transaction/wire/claims.js +229 -0
  350. package/dist/{wire → transaction/wire}/commit.d.ts +125 -193
  351. package/dist/{wire → transaction/wire}/commit.js +68 -47
  352. package/dist/{wire → transaction/wire}/delta.d.ts +66 -17
  353. package/dist/{wire → transaction/wire}/delta.js +37 -13
  354. package/dist/transaction/wire/errorEnvelope.d.ts +72 -0
  355. package/dist/{wire → transaction/wire}/errorEnvelope.js +36 -5
  356. package/dist/transaction/wire/feedCursor.d.ts +60 -0
  357. package/dist/transaction/wire/feedCursor.js +82 -0
  358. package/dist/transaction/wire/feedEvent.d.ts +177 -0
  359. package/dist/transaction/wire/feedEvent.js +39 -0
  360. package/dist/transaction/wire/frames.d.ts +194 -0
  361. package/dist/transaction/wire/frames.js +50 -0
  362. package/dist/transaction/wire/inboundFrames.d.ts +552 -0
  363. package/dist/transaction/wire/inboundFrames.js +116 -0
  364. package/dist/transaction/wire/index.d.ts +50 -0
  365. package/dist/transaction/wire/index.js +74 -0
  366. package/dist/{wire → transaction/wire}/listEnvelope.d.ts +13 -14
  367. package/dist/transaction/wire/listEnvelope.js +42 -0
  368. package/dist/transaction/wire/modelResponses.d.ts +85 -0
  369. package/dist/transaction/wire/modelResponses.js +43 -0
  370. package/dist/transactions/{TransactionQueue.d.ts → mutations/MutationQueue.d.ts} +79 -38
  371. package/dist/transactions/{TransactionQueue.js → mutations/MutationQueue.js} +110 -59
  372. package/dist/transactions/{TransactionStore.d.ts → mutations/MutationStore.d.ts} +8 -8
  373. package/dist/transactions/{TransactionStore.js → mutations/MutationStore.js} +2 -2
  374. package/dist/transactions/{coalesceRules.d.ts → mutations/coalesceRules.d.ts} +10 -10
  375. package/dist/transactions/{coalesceRules.js → mutations/coalesceRules.js} +1 -1
  376. package/dist/transactions/mutations/commitLatency.d.ts +52 -0
  377. package/dist/transactions/mutations/commitLatency.js +130 -0
  378. package/dist/transactions/{commitOutboxStore.d.ts → mutations/commitOutboxStore.d.ts} +1 -5
  379. package/dist/transactions/{commitOutboxStore.js → mutations/commitOutboxStore.js} +1 -1
  380. package/dist/transactions/{commitPayload.d.ts → mutations/commitPayload.d.ts} +16 -15
  381. package/dist/transactions/{commitPayload.js → mutations/commitPayload.js} +12 -12
  382. package/dist/transactions/{deltaConfirmation.d.ts → mutations/deltaConfirmation.d.ts} +11 -11
  383. package/dist/transactions/{deltaConfirmation.js → mutations/deltaConfirmation.js} +7 -7
  384. package/dist/transactions/mutations/durableWriteStore.d.ts +14 -0
  385. package/dist/transactions/mutations/durableWriteStore.js +12 -0
  386. package/dist/transactions/{optimisticApply.d.ts → mutations/optimisticApply.d.ts} +7 -7
  387. package/dist/transactions/{replayValidation.d.ts → mutations/replayValidation.d.ts} +3 -3
  388. package/dist/transactions/{replayValidation.js → mutations/replayValidation.js} +4 -3
  389. package/dist/utils/mobxSetup.d.ts +1 -1
  390. package/dist/utils/mobxSetup.js +5 -2
  391. package/dist/webhooks/events.d.ts +2 -2
  392. package/dist/wire/index.d.ts +1 -34
  393. package/dist/wire/index.js +8 -49
  394. package/docs/agent-messaging.md +3 -3
  395. package/docs/agents.md +19 -12
  396. package/docs/api-keys.md +8 -4
  397. package/docs/api.md +22 -18
  398. package/docs/audit.md +2 -0
  399. package/docs/cli.md +31 -3
  400. package/docs/client-behavior.md +8 -6
  401. package/docs/concurrency-convention.md +30 -24
  402. package/docs/coordination.md +48 -38
  403. package/docs/data-sources.md +3 -1
  404. package/docs/debugging.md +5 -3
  405. package/docs/deployment.md +267 -0
  406. package/docs/examples/agent-human.md +49 -42
  407. package/docs/examples/ai-sdk-tool.md +69 -44
  408. package/docs/examples/existing-python-backend.md +8 -6
  409. package/docs/examples/nextjs.md +129 -47
  410. package/docs/examples/scoped-agent.md +45 -44
  411. package/docs/examples/server-agent.md +46 -26
  412. package/docs/groups.md +32 -29
  413. package/docs/guarantees.md +4 -2
  414. package/docs/how-it-works.md +9 -7
  415. package/docs/idempotency.md +126 -0
  416. package/docs/identity.md +58 -54
  417. package/docs/index.md +172 -86
  418. package/docs/integration-guide.md +17 -16
  419. package/docs/interaction-model.md +6 -4
  420. package/docs/mcp.md +41 -16
  421. package/docs/migration.md +63 -5
  422. package/docs/operating-on-your-database.md +3 -1
  423. package/docs/projects.md +2 -0
  424. package/docs/quickstart.md +22 -5
  425. package/docs/react.md +12 -10
  426. package/docs/schema-contract.md +5 -3
  427. package/docs/session-settings.md +108 -0
  428. package/docs/sessions.md +3 -1
  429. package/docs/webhooks.md +3 -1
  430. package/llms.txt +47 -17
  431. package/package.json +10 -8
  432. package/dist/agent/Agent.d.ts +0 -366
  433. package/dist/agent/Agent.js +0 -514
  434. package/dist/agent/index.d.ts +0 -115
  435. package/dist/agent/index.js +0 -128
  436. package/dist/agent/session.d.ts +0 -93
  437. package/dist/agent/session.js +0 -149
  438. package/dist/agent/types.d.ts +0 -68
  439. package/dist/agent/types.js +0 -9
  440. package/dist/client/durableWrites.d.ts +0 -21
  441. package/dist/coordination/schema.d.ts +0 -722
  442. package/dist/schema/openapi.d.ts +0 -29
  443. package/dist/schema/openapi.js +0 -124
  444. package/dist/transactions/durableWriteStore.js +0 -30
  445. package/dist/utils/json.js +0 -88
  446. package/dist/wire/errorEnvelope.d.ts +0 -55
  447. package/dist/wire/frames.d.ts +0 -197
  448. package/dist/wire/frames.js +0 -49
  449. package/dist/wire/listEnvelope.js +0 -18
  450. /package/dist/{client → transaction/auth}/credentialEndpoint.d.ts +0 -0
  451. /package/dist/{client → transaction/auth}/credentialEndpoint.js +0 -0
  452. /package/dist/{auth → transaction/auth}/credentialPolicy.d.ts +0 -0
  453. /package/dist/{auth → transaction/auth}/credentialPolicy.js +0 -0
  454. /package/dist/{auth → transaction/auth}/credentialSource.js +0 -0
  455. /package/dist/{client → transaction/auth}/hostedEndpoints.d.ts +0 -0
  456. /package/dist/{client → transaction/auth}/hostedEndpoints.js +0 -0
  457. /package/dist/{client → transaction/coordination}/claimHeartbeatLoop.d.ts +0 -0
  458. /package/dist/{client → transaction/coordination}/claimHeartbeatLoop.js +0 -0
  459. /package/dist/{client → transaction}/persistence.d.ts +0 -0
  460. /package/dist/{client → transaction}/persistence.js +0 -0
  461. /package/dist/{client → transaction/resources}/functionalUpdate.d.ts +0 -0
  462. /package/dist/{client → transaction/resources}/functionalUpdate.js +0 -0
  463. /package/dist/{transactions → transaction/transactions/settlement}/idempotencyKey.d.ts +0 -0
  464. /package/dist/{transactions → transaction/transactions/settlement}/idempotencyKey.js +0 -0
  465. /package/dist/{client → transaction/transport}/httpTransport.d.ts +0 -0
  466. /package/dist/{types → transaction/types}/modelData.d.ts +0 -0
  467. /package/dist/{types → transaction/types}/modelData.js +0 -0
  468. /package/dist/{types → transaction/types}/participant.d.ts +0 -0
  469. /package/dist/{types → transaction/types}/participant.js +0 -0
  470. /package/dist/{types → transaction/types}/streams.js +0 -0
  471. /package/dist/{utils → transaction/utils}/asyncIterator.d.ts +0 -0
  472. /package/dist/{utils → transaction/utils}/asyncIterator.js +0 -0
  473. /package/dist/{utils → transaction/utils}/duration.d.ts +0 -0
  474. /package/dist/{utils → transaction/utils}/duration.js +0 -0
  475. /package/dist/{wire → transaction/wire}/bootstrapReason.d.ts +0 -0
  476. /package/dist/{wire → transaction/wire}/bootstrapReason.js +0 -0
  477. /package/dist/{wire → transaction/wire}/protocol.d.ts +0 -0
  478. /package/dist/{wire → transaction/wire}/protocol.js +0 -0
  479. /package/dist/{wire → transaction/wire}/protocolVersion.d.ts +0 -0
  480. /package/dist/{wire → transaction/wire}/protocolVersion.js +0 -0
  481. /package/dist/transactions/{UnconfirmedWrites.d.ts → mutations/UnconfirmedWrites.d.ts} +0 -0
  482. /package/dist/transactions/{UnconfirmedWrites.js → mutations/UnconfirmedWrites.js} +0 -0
  483. /package/dist/transactions/{optimisticApply.js → mutations/optimisticApply.js} +0 -0
@@ -7,9 +7,12 @@
7
7
  */
8
8
  import { type DatabaseInfo, type WorkspaceMetadata } from './core/DatabaseManager.js';
9
9
  import { ModelRegistry } from './ModelRegistry.js';
10
- import { LoadStrategy } from './types/index.js';
10
+ import { LoadStrategy } from './transaction/types/index.js';
11
11
  import type { BootstrapFetcher, BootstrapData } from './sync/BootstrapFetcher.js';
12
12
  import { InMemoryObjectStore } from './adapters/inMemoryStorage.js';
13
+ import type { SyncDeltaAction } from './transaction/wire/delta.js';
14
+ import type { OnStaleMode } from './transaction/coordination/schema.js';
15
+ import type { BootstrapType } from './transaction/types/index.js';
13
16
  /** Generic record type for model data */
14
17
  type ModelData = Record<string, unknown>;
15
18
  /** Persisted mutation in a transaction */
@@ -20,7 +23,7 @@ interface PersistedMutation {
20
23
  timestamp: string;
21
24
  writeOptions?: {
22
25
  readAt?: number | null;
23
- onStale?: 'reject' | 'overwrite' | 'notify' | null;
26
+ onStale?: OnStaleMode | null;
24
27
  };
25
28
  }
26
29
  /** Persisted transaction for offline/retry support.
@@ -45,20 +48,7 @@ interface PersistedTransaction {
45
48
  };
46
49
  [key: string]: unknown;
47
50
  }
48
- /**
49
- * How a session establishes its baseline state at startup.
50
- *
51
- * 'full' — Fetch a complete snapshot from the server, clear the local store,
52
- * load the snapshot, and adopt its `lastSyncId`.
53
- *
54
- * 'partial' — Fetch only the deltas since the stored `lastSyncId` and apply
55
- * them on top of the existing local data.
56
- *
57
- * 'local' — Skip the server entirely: hydrate the {@link InstanceCache} from the
58
- * local store, connect the WebSocket with the stored `lastSyncId`, and
59
- * receive deltas from there onward. Used when offline with valid local data.
60
- */
61
- export type BootstrapType = 'full' | 'partial' | 'local';
51
+ export type { BootstrapType };
62
52
  export interface BootstrapRequirements {
63
53
  type: BootstrapType;
64
54
  modelsToLoad: string[];
@@ -191,7 +181,7 @@ export declare class Database {
191
181
  *
192
182
  * Update deltas carry only the changed fields, so they are merged onto the
193
183
  * existing record rather than replacing it. That preserves fields the delta
194
- * omits (such as deckId or title), and an explicit null is kept as a value,
184
+ * omits (such as reportId or title), and an explicit null is kept as a value,
195
185
  * clearing that field.
196
186
  */
197
187
  processDelta(delta: {
@@ -202,7 +192,7 @@ export declare class Database {
202
192
  * but the switch returns a no-op verify if one slips through (e.g.
203
193
  * replayed from the bootstrap queue) rather than crashing the engine.
204
194
  */
205
- actionType: 'I' | 'U' | 'D' | 'A' | 'V' | 'C' | 'G' | 'S' | 'M';
195
+ actionType: SyncDeltaAction;
206
196
  modelName: string;
207
197
  modelId: string;
208
198
  data: ModelData | null;
@@ -235,7 +225,7 @@ export declare class Database {
235
225
  * shouldn't reach batch processing, but the switch inside returns
236
226
  * no-op verify for them if one slips through.
237
227
  */
238
- actionType: 'I' | 'U' | 'D' | 'A' | 'V' | 'C' | 'G' | 'S' | 'M';
228
+ actionType: SyncDeltaAction;
239
229
  modelName: string;
240
230
  modelId: string;
241
231
  data: ModelData | null;
@@ -319,10 +309,6 @@ export declare class Database {
319
309
  database: DatabaseInfo | null;
320
310
  stores: {
321
311
  totalStores: number;
322
- storeTypes: {
323
- full: number;
324
- partial: number;
325
- };
326
312
  readiness: {
327
313
  ready: number;
328
314
  notReady: number;
@@ -347,4 +333,3 @@ export declare class Database {
347
333
  includeWriteJournal?: boolean;
348
334
  }): Promise<void>;
349
335
  }
350
- export {};
package/dist/Database.js CHANGED
@@ -8,11 +8,11 @@
8
8
  import { DatabaseManager } from './core/DatabaseManager.js';
9
9
  import { StoreManager } from './core/StoreManager.js';
10
10
  import { ModelRegistry } from './ModelRegistry.js';
11
- import { LoadStrategy } from './types/index.js';
11
+ import { LoadStrategy } from './transaction/types/index.js';
12
12
  import { getContext } from './context.js';
13
- import { AbloConnectionError, AbloValidationError } from './errors.js';
13
+ import { AbloConnectionError, AbloValidationError } from './transaction/errors.js';
14
14
  import { InMemoryObjectStore } from './adapters/inMemoryStorage.js';
15
- import { syncPositionSchema } from './sync/syncPosition.js';
15
+ import { logPositionSchema } from './transaction/logPosition.js';
16
16
  import { highestPersistedPrefixSyncId } from './sync/persistedPrefix.js';
17
17
  /**
18
18
  * Request identity excludes local timing metadata for re-entrant seals: a
@@ -208,8 +208,8 @@ export class Database {
208
208
  // Register database
209
209
  await this.databaseManager.registerDatabase(this.currentDbInfo);
210
210
  // Open workspace database
211
- this.workspaceDb = await this.databaseManager.openWorkspaceDatabase(this.currentDbInfo, async (db, tx) => {
212
- await this.storeManager.createStores(db, tx);
211
+ this.workspaceDb = await this.databaseManager.openWorkspaceDatabase(this.currentDbInfo, async (db) => {
212
+ await this.storeManager.createStores(db);
213
213
  });
214
214
  // Initialize stores
215
215
  await this.storeManager.initializeStores(this.workspaceDb);
@@ -328,7 +328,7 @@ export class Database {
328
328
  // (a corrupted negative/float cursor would previously pass `|| 0`,
329
329
  // which only catches falsy, and get sent to the server as the resume
330
330
  // point). Invalid → 0 → full bootstrap, the safe degradation.
331
- const metadataLastSyncId = syncPositionSchema.shape.persisted.safeParse(metadata?.lastSyncId).data ?? 0;
331
+ const metadataLastSyncId = logPositionSchema.shape.persisted.safeParse(metadata?.lastSyncId).data ?? 0;
332
332
  const dataAge = metadata?.updatedAt ? Date.now() - metadata.updatedAt.getTime() : Infinity;
333
333
  // ── Cache-validity check ─────────────────────────────────────
334
334
  //
@@ -444,13 +444,18 @@ export class Database {
444
444
  let deltasApplied = 0;
445
445
  let deltaResults;
446
446
  if (deltas.length > 0) {
447
- // Convert server delta format to processDelta format
447
+ // Narrow the wire delta to what processDelta reads. The field names
448
+ // are the wire's own — the only change is `id` becoming `syncId`.
449
+ // A group-change frame carries its payload as a JSON string, decoded
450
+ // here exactly as the live delta path does in BaseSyncedStore.
448
451
  const formattedDeltas = deltas.map((delta) => ({
449
452
  syncId: delta.id,
450
- actionType: delta.operation,
453
+ actionType: delta.actionType,
451
454
  modelName: delta.modelName,
452
- modelId: delta.entityId,
453
- data: delta.data,
455
+ modelId: delta.modelId,
456
+ data: typeof delta.data === 'string'
457
+ ? JSON.parse(delta.data)
458
+ : delta.data,
454
459
  }));
455
460
  // Use batch processing for better performance
456
461
  const batch = await this.processDeltaBatch(formattedDeltas);
@@ -520,6 +525,13 @@ export class Database {
520
525
  });
521
526
  }
522
527
  }
528
+ // The model is marked persisted below whether or not every item landed,
529
+ // because a partial store is still what the next sync reconciles
530
+ // against. Counted and surfaced here so a partial does not read as a
531
+ // clean bootstrap.
532
+ if (writeErrors > 0) {
533
+ getContext().observability.breadcrumb(`Stored ${modelName} with ${writeErrors} of ${modelData.length} items dropped`, 'sync.database', 'warning');
534
+ }
523
535
  // Mark model as persisted after successful write
524
536
  try {
525
537
  await this.setModelPersisted(modelName, true);
@@ -569,7 +581,7 @@ export class Database {
569
581
  *
570
582
  * Update deltas carry only the changed fields, so they are merged onto the
571
583
  * existing record rather than replacing it. That preserves fields the delta
572
- * omits (such as deckId or title), and an explicit null is kept as a value,
584
+ * omits (such as reportId or title), and an explicit null is kept as a value,
573
585
  * clearing that field.
574
586
  */
575
587
  async processDelta(delta) {
@@ -636,7 +648,7 @@ export class Database {
636
648
  const existing = await store.get(modelId);
637
649
  // Skip the update when there's no existing record to merge with:
638
650
  // building a record from partial update data would corrupt it
639
- // (missing deckId, and so on).
651
+ // (missing reportId, and so on).
640
652
  if (!existing) {
641
653
  getContext().observability.breadcrumb('Skipping UPDATE delta - no existing record to merge with', 'sync.database', 'warning', {
642
654
  modelName,
@@ -712,10 +724,14 @@ export class Database {
712
724
  case 'S':
713
725
  getContext().observability.breadcrumb(`Group membership delta (${actionType}) reached processDelta — should be handled upstream`, 'sync.database', 'warning', { modelName, modelId: modelId.slice(0, 12), actionType });
714
726
  return { action: 'verify', modelName, modelId, data: null };
715
- default:
716
- throw new AbloValidationError(`Unknown action type: ${actionType}`, {
717
- code: 'db_unknown_action_type',
718
- });
727
+ default: {
728
+ // The switch above is exhaustive over the declared action types, so
729
+ // this branch is only reachable when a value escapes the type — hence
730
+ // stringifying whatever actually arrived rather than the `never`.
731
+ const _exhaustive = actionType;
732
+ void _exhaustive;
733
+ throw new AbloValidationError(`Unknown action type: ${JSON.stringify(actionType)}`, { code: 'db_unknown_action_type' });
734
+ }
719
735
  }
720
736
  }
721
737
  /**
@@ -826,8 +842,7 @@ export class Database {
826
842
  // entity has an equal or higher sync id.
827
843
  if (delta.actionType === 'U' ||
828
844
  delta.actionType === 'I' ||
829
- delta.actionType === 'C' ||
830
- delta.actionType === 'M') {
845
+ delta.actionType === 'C') {
831
846
  const key = `${delta.modelName}:${delta.modelId}`;
832
847
  const deleteSyncId = deleteSyncIds.get(key);
833
848
  if (deleteSyncId !== undefined) {
@@ -892,7 +907,7 @@ export class Database {
892
907
  }
893
908
  }
894
909
  }
895
- catch (error) {
910
+ catch {
896
911
  getContext().observability.breadcrumb(`Batch read failed for ${modelName}, falling back to individual reads`, 'sync.database', 'warning');
897
912
  // Fallback: mark all as missing for self-healing
898
913
  for (const id of updateIds) {
@@ -991,7 +1006,7 @@ export class Database {
991
1006
  }
992
1007
  // Skip the update when there's no existing record to merge with:
993
1008
  // building a record from partial update data would corrupt it
994
- // (missing deckId, and so on).
1009
+ // (missing reportId, and so on).
995
1010
  if (!existing) {
996
1011
  getContext().observability.breadcrumb('Batch: Skipping UPDATE delta - no existing record', 'sync.database', 'warning', {
997
1012
  modelName,
@@ -1063,7 +1078,7 @@ export class Database {
1063
1078
  }
1064
1079
  }
1065
1080
  catch (err) {
1066
- // Surface the IDB error directly — `captureTransactionFailure`
1081
+ // Surface the IDB error directly — `captureMutationFailure`
1067
1082
  // routes to Sentry, but during interactive debugging the console
1068
1083
  // needs to show the specific failure (e.g. `ConstraintError`,
1069
1084
  // `DataError`, `AbortError`) so we can find what's wrong with
@@ -1082,7 +1097,7 @@ export class Database {
1082
1097
  : typeof delta.data,
1083
1098
  })),
1084
1099
  });
1085
- getContext().observability.captureTransactionFailure({
1100
+ getContext().observability.captureMutationFailure({
1086
1101
  context: 'batch-indexeddb-operation',
1087
1102
  modelName,
1088
1103
  error: idbErr,
@@ -8,7 +8,7 @@
8
8
  */
9
9
  import { Model } from './Model.js';
10
10
  import { ModelRegistry } from './ModelRegistry.js';
11
- import { ModelScope } from './types/index.js';
11
+ import { ModelScope } from './transaction/types/index.js';
12
12
  import { ViewRegistry } from './core/ViewRegistry.js';
13
13
  import { QueryView, type QueryViewOptions } from './core/QueryView.js';
14
14
  /** Constructor type for Model subclasses - uses abstract to handle variance */
@@ -50,6 +50,27 @@ export declare class InstanceCache {
50
50
  constructor(config?: PoolConfig, modelRegistry?: ModelRegistry);
51
51
  private resolveModel;
52
52
  get<T extends Model = Model>(id: string): T | undefined;
53
+ /**
54
+ * Look a row up **within one model**.
55
+ *
56
+ * The pool is a single id space: `get(id)` returns whatever row carries that
57
+ * id, whatever model it belongs to. That is the correct storage shape — ids
58
+ * are globally unique, the same premise as Relay's Global Object
59
+ * Identification — but it means an *untyped* lookup cannot stand in for a
60
+ * typed one. Apollo and EmberData avoid the question by keying their identity
61
+ * maps on `Type:id`; with unique ids the equivalent guarantee comes from
62
+ * stating the expected model at the lookup instead.
63
+ *
64
+ * Returns `undefined` for a row belonging to another model: from the asking
65
+ * model's perspective that id is simply absent. Callers that must tell "not
66
+ * here" apart from "here, but another model's" should compare against
67
+ * {@link get}.
68
+ *
69
+ * Prefer this over `get()` anywhere the caller knows which model it wants —
70
+ * `get()` returning another model's row has caused three product bugs, most
71
+ * recently a resize gesture that reverted after every commit.
72
+ */
73
+ getOfType<T extends Model = Model>(id: string, modelName: string): T | undefined;
53
74
  /**
54
75
  * Add model with deduplication support
55
76
  */
@@ -97,7 +118,7 @@ export declare class InstanceCache {
97
118
  * data. Cleaner than `createFromData({ __typename, ...data })` — the
98
119
  * typename lives in the arg list, not hidden inside the data object.
99
120
  *
100
- * Used for optimistic local writes: `pool.create('Slide', { id, deckId, ... })`.
121
+ * Used for optimistic local writes: `pool.create('Section', { id, reportId, ... })`.
101
122
  * For hydration from server deltas (where `__typename` already rides on
102
123
  * the payload), use `createFromData(data)` directly — that path is kept
103
124
  * because the wire format attaches the discriminator to the data itself.
@@ -178,8 +199,8 @@ export declare class InstanceCache {
178
199
  * Register a foreign key field for indexing on a model type.
179
200
  * Call once during app initialization (e.g., after model registration).
180
201
  *
181
- * Example: registerForeignKey('SlideLayer', 'slideId')
182
- * This enables getByForeignKey('SlideLayer', 'slideId', someSlideId) → O(1) lookup
202
+ * Example: registerForeignKey('Block', 'sectionId')
203
+ * This enables getByForeignKey('Block', 'sectionId', someSectionId) → O(1) lookup
183
204
  */
184
205
  registerForeignKey(modelName: string, fieldName: string): void;
185
206
  /**
@@ -10,8 +10,8 @@ import { makeObservable, observable, action, computed, runInAction } from 'mobx'
10
10
  import { Model } from './Model.js';
11
11
  import { ModelRegistry } from './ModelRegistry.js';
12
12
  import { getContext } from './context.js';
13
- import { AbloValidationError } from './errors.js';
14
- import { ModelScope } from './types/index.js';
13
+ import { AbloValidationError } from './transaction/errors.js';
14
+ import { ModelScope } from './transaction/types/index.js';
15
15
  import { ViewRegistry } from './core/ViewRegistry.js';
16
16
  import { QueryView } from './core/QueryView.js';
17
17
  // Re-exported so `import { ModelScope } from './InstanceCache.js'` resolves
@@ -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[]>
@@ -187,6 +187,39 @@ export class InstanceCache {
187
187
  this.metrics.hits++;
188
188
  return model ?? undefined;
189
189
  }
190
+ /**
191
+ * Look a row up **within one model**.
192
+ *
193
+ * The pool is a single id space: `get(id)` returns whatever row carries that
194
+ * id, whatever model it belongs to. That is the correct storage shape — ids
195
+ * are globally unique, the same premise as Relay's Global Object
196
+ * Identification — but it means an *untyped* lookup cannot stand in for a
197
+ * typed one. Apollo and EmberData avoid the question by keying their identity
198
+ * maps on `Type:id`; with unique ids the equivalent guarantee comes from
199
+ * stating the expected model at the lookup instead.
200
+ *
201
+ * Returns `undefined` for a row belonging to another model: from the asking
202
+ * model's perspective that id is simply absent. Callers that must tell "not
203
+ * here" apart from "here, but another model's" should compare against
204
+ * {@link get}.
205
+ *
206
+ * Prefer this over `get()` anywhere the caller knows which model it wants —
207
+ * `get()` returning another model's row has caused three product bugs, most
208
+ * recently a resize gesture that reverted after every commit.
209
+ */
210
+ // `T` appears only in the return position, which is normally a caller-chosen
211
+ // cast in disguise. It is sound here precisely because `modelName` is checked
212
+ // at runtime below before the row is handed back, so the caller's expected
213
+ // type and the row's registered identity cannot disagree.
214
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-parameters
215
+ getOfType(id, modelName) {
216
+ const model = this.get(id);
217
+ if (!model)
218
+ return undefined;
219
+ // Checked, so the assertion below is sound: `typeIndex` and
220
+ // `getModelName()` are the same registered-name identity.
221
+ return model.getModelName() === modelName ? model : undefined;
222
+ }
190
223
  /**
191
224
  * Add model with deduplication support
192
225
  */
@@ -341,13 +374,13 @@ export class InstanceCache {
341
374
  this.addToTypeIndex(id, modelType);
342
375
  // Populate the foreign-key indexes. The single-item `add()` path
343
376
  // 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
377
+ // block / ledger cell / message that came in through a bulk
378
+ // loader (`ensureReportBlocks`, `prefetchSectionBlocks`, bootstrap
346
379
  // hydration) was in the pool but invisible to `hasMany` lookups
347
- // — `slide.layers` returned `[]` until the user clicked a layer
380
+ // — `section.blocks` returned `[]` until the user clicked a block
348
381
  // and something else ran a non-batch `add` that happened to
349
382
  // populate the FK index as a side effect. The UX symptom was
350
- // "slides show empty until you click on one." Adding this one
383
+ // "sections show empty until you click on one." Adding this one
351
384
  // line closes the gap.
352
385
  this.addToForeignKeyIndex(id, model, modelType);
353
386
  this.metrics.additions++;
@@ -461,7 +494,7 @@ export class InstanceCache {
461
494
  // FK cleanup silently no-ops — leaving ghost ids in the FK index.
462
495
  // That causes `getByForeignKey(..., parentId)` to report
463
496
  // `matched > returned` (dropped-no-entry) and, on the UI, keeps the
464
- // stale layer visible until the next reload rebuilds the index
497
+ // stale block visible until the next reload rebuilds the index
465
498
  // from fresh data. Do the FK/type cleanup first, then delete the
466
499
  // entry.
467
500
  runInAction(() => {
@@ -598,7 +631,7 @@ export class InstanceCache {
598
631
  * data. Cleaner than `createFromData({ __typename, ...data })` — the
599
632
  * typename lives in the arg list, not hidden inside the data object.
600
633
  *
601
- * Used for optimistic local writes: `pool.create('Slide', { id, deckId, ... })`.
634
+ * Used for optimistic local writes: `pool.create('Section', { id, reportId, ... })`.
602
635
  * For hydration from server deltas (where `__typename` already rides on
603
636
  * the payload), use `createFromData(data)` directly — that path is kept
604
637
  * because the wire format attaches the discriminator to the data itself.
@@ -643,7 +676,7 @@ export class InstanceCache {
643
676
  existing.updateFromData(data);
644
677
  return existing;
645
678
  }
646
- // Different type with same ID - this is a shared PK scenario (e.g., Project/Dataroom)
679
+ // Different type with same ID - this is a shared PK scenario (e.g., two models sharing one row id)
647
680
  // Don't return existing, create new model (will use composite key for storage)
648
681
  }
649
682
  // Log model creation attempt
@@ -658,7 +691,7 @@ export class InstanceCache {
658
691
  // Internal construction failure — captured via observability below and
659
692
  // re-fetched on resync; the stack is forensic → debug.
660
693
  getContext().logger.debug(`[InstanceCache.createFromData] FAILED ${modelName}`, { errorMessage, stack: error instanceof Error ? error.stack : undefined });
661
- getContext().observability.captureTransactionFailure({
694
+ getContext().observability.captureMutationFailure({
662
695
  context: 'createFromData',
663
696
  modelName,
664
697
  modelId: data.id,
@@ -849,7 +882,7 @@ export class InstanceCache {
849
882
  // caused silent data loss — any model actively being rendered
850
883
  // through a schema-driven dynamic class (i.e., most of them)
851
884
  // would be demoted, collected, and the next render's
852
- // `weakRef.deref()` returned undefined, so layers / cells /
885
+ // `weakRef.deref()` returned undefined, so blocks / cells /
853
886
  // messages "disappeared" after ~10 min of idle.
854
887
  //
855
888
  // The `hasObservedCollections()` guard used by the eviction
@@ -934,8 +967,8 @@ export class InstanceCache {
934
967
  * Register a foreign key field for indexing on a model type.
935
968
  * Call once during app initialization (e.g., after model registration).
936
969
  *
937
- * Example: registerForeignKey('SlideLayer', 'slideId')
938
- * This enables getByForeignKey('SlideLayer', 'slideId', someSlideId) → O(1) lookup
970
+ * Example: registerForeignKey('Block', 'sectionId')
971
+ * This enables getByForeignKey('Block', 'sectionId', someSectionId) → O(1) lookup
939
972
  */
940
973
  registerForeignKey(modelName, fieldName) {
941
974
  const fields = this.foreignKeyConfig.get(modelName) ?? [];
@@ -977,7 +1010,7 @@ export class InstanceCache {
977
1010
  // entry for this specific parent id (entity genuinely has no
978
1011
  // children). These used to `console.warn` diagnostic dumps on every
979
1012
  // call, which turned into hundreds of log lines per second during
980
- // cursor hover / rapid re-renders on the deck page. If a caller
1013
+ // cursor hover / rapid re-renders on a busy page. If a caller
981
1014
  // needs visibility into "why is this empty," wire an opt-in
982
1015
  // `logger.debug` at the specific call site rather than re-adding
983
1016
  // a blanket warn here.
@@ -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
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
@@ -7,7 +7,7 @@
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
11
  import type { Model } from './Model.js';
12
12
  import type { ConcreteModelConstructor } from './BaseSyncedStore.js';
13
13
  /**
@@ -51,9 +51,9 @@ export interface SerializedReferenceMetadata extends Omit<ExtendedReferenceMetad
51
51
  * child's pending transactions can be cancelled.
52
52
  */
53
53
  export interface BackReferenceMetadata {
54
- /** The parent model name (e.g., 'SlideDeck') */
54
+ /** The parent model name (e.g., 'Report') */
55
55
  parentModel: string;
56
- /** The foreign key property on this model (e.g., 'deckId') */
56
+ /** The foreign key property on this model (e.g., 'reportId') */
57
57
  foreignKey: string;
58
58
  /** Whether to cascade-cancel transactions when parent is deleted */
59
59
  cascadeDelete: boolean;
@@ -107,7 +107,7 @@ export declare class ModelRegistry {
107
107
  * transactions for every child model that declares a back-reference to that
108
108
  * parent.
109
109
  *
110
- * @param childModelName - The model that holds a foreign key to the parent (e.g., 'Slide')
110
+ * @param childModelName - The model that holds a foreign key to the parent (e.g., 'Section')
111
111
  * @param metadata - The back-reference configuration
112
112
  */
113
113
  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';
11
+ import { PropertyType, LoadStrategy, } from './transaction/types/index.js';
12
12
  import { getContext } from './context.js';
13
- import { AbloValidationError } from './errors.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.
@@ -248,7 +248,7 @@ export class ModelRegistry {
248
248
  * transactions for every child model that declares a back-reference to that
249
249
  * parent.
250
250
  *
251
- * @param childModelName - The model that holds a foreign key to the parent (e.g., 'Slide')
251
+ * @param childModelName - The model that holds a foreign key to the parent (e.g., 'Section')
252
252
  * @param metadata - The back-reference configuration
253
253
  */
254
254
  registerBackReference(childModelName, metadata) {