@abloatai/ablo 0.26.0 → 0.28.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 (418) hide show
  1. package/CHANGELOG.md +42 -2
  2. package/README.md +102 -86
  3. package/dist/BaseSyncedStore.d.ts +85 -88
  4. package/dist/BaseSyncedStore.js +134 -151
  5. package/dist/Database.d.ts +68 -69
  6. package/dist/Database.js +316 -135
  7. package/dist/{ObjectPool.d.ts → InstanceCache.d.ts} +10 -13
  8. package/dist/{ObjectPool.js → InstanceCache.js} +85 -83
  9. package/dist/LazyReferenceCollection.d.ts +11 -15
  10. package/dist/LazyReferenceCollection.js +12 -16
  11. package/dist/Model.d.ts +54 -52
  12. package/dist/Model.js +78 -62
  13. package/dist/ModelRegistry.d.ts +21 -19
  14. package/dist/ModelRegistry.js +23 -27
  15. package/dist/NetworkMonitor.d.ts +5 -6
  16. package/dist/NetworkMonitor.js +5 -6
  17. package/dist/SyncClient.d.ts +122 -118
  18. package/dist/SyncClient.js +541 -245
  19. package/dist/adapters/alwaysOnline.d.ts +6 -8
  20. package/dist/adapters/alwaysOnline.js +6 -8
  21. package/dist/adapters/inMemoryStorage.d.ts +10 -9
  22. package/dist/adapters/inMemoryStorage.js +21 -9
  23. package/dist/agent/Agent.d.ts +27 -32
  24. package/dist/agent/Agent.js +18 -19
  25. package/dist/agent/index.d.ts +4 -4
  26. package/dist/agent/index.js +5 -5
  27. package/dist/agent/session.d.ts +47 -44
  28. package/dist/agent/session.js +37 -48
  29. package/dist/agent/types.d.ts +26 -31
  30. package/dist/agent/types.js +6 -7
  31. package/dist/ai-sdk/coordinatedTool.d.ts +108 -0
  32. package/dist/ai-sdk/{coordinated-tool.js → coordinatedTool.js} +44 -38
  33. package/dist/ai-sdk/coordinationContext.d.ts +46 -0
  34. package/dist/ai-sdk/{coordination-context.js → coordinationContext.js} +26 -33
  35. package/dist/ai-sdk/index.d.ts +25 -22
  36. package/dist/ai-sdk/index.js +25 -22
  37. package/dist/ai-sdk/wrap.d.ts +6 -7
  38. package/dist/ai-sdk/wrap.js +1 -1
  39. package/dist/auth/credentialPolicy.d.ts +69 -74
  40. package/dist/auth/credentialPolicy.js +51 -56
  41. package/dist/auth/credentialSource.d.ts +6 -5
  42. package/dist/auth/credentialSource.js +9 -10
  43. package/dist/auth/index.d.ts +59 -58
  44. package/dist/auth/index.js +31 -37
  45. package/dist/auth/schemas.d.ts +5 -4
  46. package/dist/auth/schemas.js +5 -4
  47. package/dist/batching/index.d.ts +19 -21
  48. package/dist/batching/index.js +14 -17
  49. package/dist/cli.cjs +173 -121
  50. package/dist/client/Ablo.d.ts +97 -74
  51. package/dist/client/Ablo.js +129 -163
  52. package/dist/client/ApiClient.d.ts +30 -19
  53. package/dist/client/ApiClient.js +442 -81
  54. package/dist/client/auth.d.ts +47 -47
  55. package/dist/client/auth.js +108 -117
  56. package/dist/client/claimHeartbeatLoop.d.ts +50 -0
  57. package/dist/client/claimHeartbeatLoop.js +88 -0
  58. package/dist/client/consoleLogger.d.ts +5 -6
  59. package/dist/client/consoleLogger.js +5 -6
  60. package/dist/client/createInternalComponents.d.ts +16 -17
  61. package/dist/client/createInternalComponents.js +26 -31
  62. package/dist/client/createModelProxy.d.ts +130 -120
  63. package/dist/client/createModelProxy.js +152 -122
  64. package/dist/client/credentialEndpoint.d.ts +40 -42
  65. package/dist/client/credentialEndpoint.js +35 -36
  66. package/dist/client/functionalUpdate.d.ts +29 -27
  67. package/dist/client/functionalUpdate.js +21 -21
  68. package/dist/client/hostedEndpoints.d.ts +9 -12
  69. package/dist/client/hostedEndpoints.js +9 -12
  70. package/dist/client/httpClient.d.ts +59 -53
  71. package/dist/client/httpClient.js +29 -31
  72. package/dist/client/identity.d.ts +15 -20
  73. package/dist/client/identity.js +47 -58
  74. package/dist/client/modelRegistration.d.ts +5 -9
  75. package/dist/client/modelRegistration.js +78 -87
  76. package/dist/client/options.d.ts +157 -157
  77. package/dist/client/options.js +3 -7
  78. package/dist/client/registerDataSource.d.ts +9 -9
  79. package/dist/client/registerDataSource.js +15 -16
  80. package/dist/client/resourceTypes.d.ts +64 -75
  81. package/dist/client/resourceTypes.js +4 -10
  82. package/dist/client/schemaConfig.d.ts +31 -43
  83. package/dist/client/schemaConfig.js +38 -50
  84. package/dist/client/sessionMint.d.ts +16 -12
  85. package/dist/client/sessionMint.js +26 -31
  86. package/dist/client/validateAbloOptions.d.ts +12 -14
  87. package/dist/client/validateAbloOptions.js +8 -9
  88. package/dist/client/writeOptionsSchema.d.ts +18 -16
  89. package/dist/client/writeOptionsSchema.js +23 -20
  90. package/dist/client/wsMutationExecutor.d.ts +16 -20
  91. package/dist/client/wsMutationExecutor.js +18 -23
  92. package/dist/commit/contract.d.ts +493 -0
  93. package/dist/commit/contract.js +187 -0
  94. package/dist/commit/index.d.ts +6 -0
  95. package/dist/commit/index.js +5 -0
  96. package/dist/context.d.ts +6 -4
  97. package/dist/context.js +6 -4
  98. package/dist/coordination/index.d.ts +10 -8
  99. package/dist/coordination/index.js +14 -12
  100. package/dist/coordination/schema.d.ts +176 -128
  101. package/dist/coordination/schema.js +197 -133
  102. package/dist/coordination/trace.d.ts +9 -10
  103. package/dist/coordination/trace.js +13 -14
  104. package/dist/core/DatabaseManager.d.ts +5 -7
  105. package/dist/core/DatabaseManager.js +15 -19
  106. package/dist/core/QueryProcessor.d.ts +7 -9
  107. package/dist/core/QueryProcessor.js +22 -28
  108. package/dist/core/QueryView.d.ts +8 -8
  109. package/dist/core/QueryView.js +2 -2
  110. package/dist/core/StoreManager.d.ts +14 -14
  111. package/dist/core/StoreManager.js +33 -24
  112. package/dist/core/ViewRegistry.d.ts +5 -5
  113. package/dist/core/ViewRegistry.js +4 -4
  114. package/dist/core/index.d.ts +17 -12
  115. package/dist/core/index.js +32 -26
  116. package/dist/core/openIDBWithTimeout.d.ts +38 -36
  117. package/dist/core/openIDBWithTimeout.js +42 -43
  118. package/dist/core/queryUtils.d.ts +45 -0
  119. package/dist/core/queryUtils.js +69 -0
  120. package/dist/core/storeContract.d.ts +63 -61
  121. package/dist/core/storeContract.js +8 -12
  122. package/dist/environment.d.ts +28 -0
  123. package/dist/environment.js +21 -0
  124. package/dist/errorCodes.d.ts +107 -99
  125. package/dist/errorCodes.js +137 -134
  126. package/dist/errors.d.ts +160 -166
  127. package/dist/errors.js +155 -158
  128. package/dist/index.d.ts +36 -27
  129. package/dist/index.js +91 -86
  130. package/dist/interfaces/index.d.ts +102 -113
  131. package/dist/interfaces/index.js +5 -4
  132. package/dist/keys/index.d.ts +27 -29
  133. package/dist/keys/index.js +41 -40
  134. package/dist/mutators/RecordingTransaction.d.ts +16 -16
  135. package/dist/mutators/RecordingTransaction.js +31 -37
  136. package/dist/mutators/Transaction.d.ts +18 -26
  137. package/dist/mutators/Transaction.js +14 -20
  138. package/dist/mutators/UndoManager.d.ts +124 -131
  139. package/dist/mutators/UndoManager.js +177 -156
  140. package/dist/mutators/defineMutators.d.ts +23 -34
  141. package/dist/mutators/defineMutators.js +14 -20
  142. package/dist/mutators/inverseOp.d.ts +12 -15
  143. package/dist/mutators/inverseOp.js +12 -15
  144. package/dist/mutators/mutateActions.d.ts +10 -9
  145. package/dist/mutators/mutateActions.js +1 -1
  146. package/dist/mutators/readerActions.d.ts +9 -8
  147. package/dist/mutators/readerActions.js +2 -2
  148. package/dist/mutators/undoApply.d.ts +31 -27
  149. package/dist/mutators/undoApply.js +26 -24
  150. package/dist/policy/index.d.ts +5 -3
  151. package/dist/policy/index.js +5 -3
  152. package/dist/policy/types.d.ts +104 -100
  153. package/dist/policy/types.js +67 -66
  154. package/dist/query/client.d.ts +28 -23
  155. package/dist/query/client.js +45 -43
  156. package/dist/query/types.d.ts +37 -60
  157. package/dist/query/types.js +13 -33
  158. package/dist/react/AbloProvider.d.ts +1 -1
  159. package/dist/react/AbloProvider.js +2 -2
  160. package/dist/react/context.d.ts +25 -28
  161. package/dist/react/context.js +9 -10
  162. package/dist/react/index.d.ts +41 -42
  163. package/dist/react/index.js +37 -38
  164. package/dist/react/internalContext.d.ts +17 -19
  165. package/dist/react/useAblo.d.ts +28 -25
  166. package/dist/react/useAblo.js +41 -17
  167. package/dist/react/useCurrentUserId.d.ts +8 -7
  168. package/dist/react/useCurrentUserId.js +8 -7
  169. package/dist/react/useErrorListener.d.ts +7 -7
  170. package/dist/react/useErrorListener.js +10 -11
  171. package/dist/react/useMutationFailureListener.d.ts +8 -8
  172. package/dist/react/useMutationFailureListener.js +8 -8
  173. package/dist/react/useMutators.d.ts +11 -11
  174. package/dist/react/useMutators.js +3 -3
  175. package/dist/react/useReactive.js +2 -2
  176. package/dist/react/useSyncStatus.d.ts +4 -6
  177. package/dist/react/useUndoScope.d.ts +7 -9
  178. package/dist/react/useUndoScope.js +1 -1
  179. package/dist/schema/coordination.d.ts +21 -25
  180. package/dist/schema/coordination.js +21 -25
  181. package/dist/schema/ddl.d.ts +43 -39
  182. package/dist/schema/ddl.js +75 -68
  183. package/dist/schema/ddlLock.d.ts +20 -24
  184. package/dist/schema/ddlLock.js +18 -23
  185. package/dist/schema/diff.d.ts +99 -61
  186. package/dist/schema/diff.js +43 -34
  187. package/dist/schema/field.d.ts +37 -42
  188. package/dist/schema/field.js +35 -48
  189. package/dist/schema/generate.d.ts +12 -12
  190. package/dist/schema/generate.js +12 -12
  191. package/dist/schema/index.d.ts +3 -3
  192. package/dist/schema/index.js +21 -23
  193. package/dist/schema/model.d.ts +118 -143
  194. package/dist/schema/model.js +22 -33
  195. package/dist/schema/openapi.d.ts +10 -9
  196. package/dist/schema/openapi.js +5 -3
  197. package/dist/schema/queries.d.ts +29 -31
  198. package/dist/schema/queries.js +23 -25
  199. package/dist/schema/relation.d.ts +89 -99
  200. package/dist/schema/relation.js +13 -13
  201. package/dist/schema/residency.d.ts +16 -13
  202. package/dist/schema/residency.js +16 -13
  203. package/dist/schema/roles.d.ts +36 -43
  204. package/dist/schema/roles.js +31 -37
  205. package/dist/schema/schema.d.ts +64 -43
  206. package/dist/schema/schema.js +31 -32
  207. package/dist/schema/select.d.ts +13 -13
  208. package/dist/schema/select.js +13 -13
  209. package/dist/schema/serialize.d.ts +28 -31
  210. package/dist/schema/serialize.js +27 -31
  211. package/dist/schema/sugar.d.ts +17 -32
  212. package/dist/schema/sugar.js +14 -29
  213. package/dist/schema/{sync-delta-row.d.ts → syncDeltaRow.d.ts} +26 -49
  214. package/dist/schema/syncDeltaRow.js +89 -0
  215. package/dist/schema/tenancy.d.ts +44 -46
  216. package/dist/schema/tenancy.js +46 -48
  217. package/dist/server/adapter.d.ts +58 -58
  218. package/dist/server/adapter.js +13 -14
  219. package/dist/server/commit.d.ts +60 -64
  220. package/dist/server/index.d.ts +9 -10
  221. package/dist/server/index.js +1 -1
  222. package/dist/server/readConfig.d.ts +70 -0
  223. package/dist/server/readConfig.js +8 -0
  224. package/dist/server/storageMode.d.ts +23 -0
  225. package/dist/server/storageMode.js +17 -0
  226. package/dist/source/adapter.d.ts +30 -25
  227. package/dist/source/adapter.js +10 -10
  228. package/dist/source/adapters/drizzle.d.ts +28 -23
  229. package/dist/source/adapters/drizzle.js +30 -25
  230. package/dist/source/adapters/kysely.d.ts +27 -25
  231. package/dist/source/adapters/kysely.js +24 -23
  232. package/dist/source/adapters/memory.d.ts +8 -7
  233. package/dist/source/adapters/memory.js +9 -8
  234. package/dist/source/adapters/prisma.d.ts +13 -12
  235. package/dist/source/adapters/prisma.js +22 -25
  236. package/dist/source/conformance.d.ts +18 -11
  237. package/dist/source/conformance.js +17 -11
  238. package/dist/source/connector.d.ts +31 -32
  239. package/dist/source/connector.js +28 -28
  240. package/dist/source/connectorProtocol.d.ts +160 -0
  241. package/dist/source/connectorProtocol.js +162 -0
  242. package/dist/source/contract.d.ts +26 -27
  243. package/dist/source/contract.js +28 -29
  244. package/dist/source/factory.d.ts +46 -58
  245. package/dist/source/factory.js +22 -27
  246. package/dist/source/index.d.ts +7 -9
  247. package/dist/source/index.js +12 -14
  248. package/dist/source/migrations.d.ts +9 -9
  249. package/dist/source/migrations.js +9 -9
  250. package/dist/source/next.d.ts +9 -10
  251. package/dist/source/next.js +6 -7
  252. package/dist/source/pushQueue.d.ts +69 -47
  253. package/dist/source/pushQueue.js +32 -28
  254. package/dist/source/signing.d.ts +46 -17
  255. package/dist/source/signing.js +28 -11
  256. package/dist/source/types.d.ts +121 -104
  257. package/dist/source/types.js +13 -14
  258. package/dist/stores/ObjectStore.d.ts +24 -12
  259. package/dist/stores/ObjectStore.js +38 -16
  260. package/dist/stores/ObjectStoreContract.d.ts +14 -15
  261. package/dist/stores/SyncActionStore.d.ts +7 -11
  262. package/dist/stores/SyncActionStore.js +13 -17
  263. package/dist/surface.d.ts +28 -21
  264. package/dist/surface.js +29 -20
  265. package/dist/sync/{BootstrapHelper.d.ts → BootstrapFetcher.d.ts} +36 -42
  266. package/dist/sync/{BootstrapHelper.js → BootstrapFetcher.js} +76 -76
  267. package/dist/sync/ConnectionManager.d.ts +39 -50
  268. package/dist/sync/ConnectionManager.js +55 -66
  269. package/dist/sync/NetworkProbe.d.ts +24 -29
  270. package/dist/sync/NetworkProbe.js +63 -69
  271. package/dist/sync/{HydrationCoordinator.d.ts → OnDemandLoader.d.ts} +42 -41
  272. package/dist/sync/{HydrationCoordinator.js → OnDemandLoader.js} +59 -54
  273. package/dist/sync/{AreaOfInterestManager.d.ts → SubscriptionManager.d.ts} +43 -57
  274. package/dist/sync/{AreaOfInterestManager.js → SubscriptionManager.js} +43 -51
  275. package/dist/sync/SyncWebSocket.d.ts +141 -166
  276. package/dist/sync/SyncWebSocket.js +191 -223
  277. package/dist/sync/awaitClaimGrant.d.ts +18 -18
  278. package/dist/sync/awaitClaimGrant.js +11 -11
  279. package/dist/sync/bootstrapApply.d.ts +34 -24
  280. package/dist/sync/bootstrapApply.js +27 -19
  281. package/dist/sync/commitFrames.d.ts +21 -20
  282. package/dist/sync/commitFrames.js +18 -18
  283. package/dist/sync/createClaimStream.d.ts +23 -22
  284. package/dist/sync/createClaimStream.js +105 -23
  285. package/dist/sync/createPresenceStream.d.ts +19 -18
  286. package/dist/sync/createPresenceStream.js +25 -26
  287. package/dist/sync/createSnapshot.d.ts +12 -14
  288. package/dist/sync/createSnapshot.js +20 -26
  289. package/dist/sync/credentialLifecycle.d.ts +104 -104
  290. package/dist/sync/credentialLifecycle.js +140 -147
  291. package/dist/sync/deltaPipeline.d.ts +36 -34
  292. package/dist/sync/deltaPipeline.js +64 -65
  293. package/dist/sync/groupChange.d.ts +63 -61
  294. package/dist/sync/groupChange.js +74 -78
  295. package/dist/sync/heartbeat.d.ts +34 -33
  296. package/dist/sync/heartbeat.js +31 -31
  297. package/dist/sync/participants.d.ts +19 -19
  298. package/dist/sync/persistedPrefix.d.ts +12 -0
  299. package/dist/sync/persistedPrefix.js +22 -0
  300. package/dist/sync/schemas.d.ts +3 -2
  301. package/dist/sync/schemas.js +14 -10
  302. package/dist/sync/syncCursor.d.ts +17 -21
  303. package/dist/sync/syncCursor.js +17 -21
  304. package/dist/sync/syncPlan.d.ts +28 -36
  305. package/dist/sync/syncPlan.js +18 -19
  306. package/dist/sync/syncPosition.d.ts +54 -49
  307. package/dist/sync/syncPosition.js +57 -52
  308. package/dist/sync/wsFrameHandlers.d.ts +35 -36
  309. package/dist/sync/wsFrameHandlers.js +63 -67
  310. package/dist/testing/fixtures/bootstrap.d.ts +12 -6
  311. package/dist/testing/fixtures/bootstrap.js +12 -6
  312. package/dist/testing/fixtures/deltas.d.ts +30 -33
  313. package/dist/testing/fixtures/deltas.js +30 -33
  314. package/dist/testing/fixtures/models.d.ts +11 -10
  315. package/dist/testing/fixtures/models.js +11 -10
  316. package/dist/testing/helpers/{react-wrapper.d.ts → reactWrapper.d.ts} +13 -10
  317. package/dist/testing/helpers/{react-wrapper.js → reactWrapper.js} +15 -12
  318. package/dist/testing/helpers/{sync-engine-harness.d.ts → syncEngineHarness.d.ts} +17 -15
  319. package/dist/testing/helpers/{sync-engine-harness.js → syncEngineHarness.js} +12 -10
  320. package/dist/testing/helpers/wait.d.ts +13 -8
  321. package/dist/testing/helpers/wait.js +13 -8
  322. package/dist/testing/index.d.ts +5 -3
  323. package/dist/testing/index.js +3 -2
  324. package/dist/testing/mocks/FakeDatabase.d.ts +18 -0
  325. package/dist/testing/mocks/FakeDatabase.js +10 -0
  326. package/dist/testing/mocks/MockMutationExecutor.d.ts +18 -17
  327. package/dist/testing/mocks/MockMutationExecutor.js +15 -14
  328. package/dist/testing/mocks/MockNetworkMonitor.d.ts +8 -8
  329. package/dist/testing/mocks/MockNetworkMonitor.js +8 -8
  330. package/dist/testing/mocks/MockSyncContext.d.ts +20 -17
  331. package/dist/testing/mocks/MockSyncContext.js +15 -13
  332. package/dist/testing/mocks/MockSyncStore.d.ts +10 -10
  333. package/dist/testing/mocks/MockSyncStore.js +11 -11
  334. package/dist/testing/mocks/MockWebSocket.d.ts +28 -23
  335. package/dist/testing/mocks/MockWebSocket.js +22 -21
  336. package/dist/transactions/TransactionQueue.d.ts +244 -181
  337. package/dist/transactions/TransactionQueue.js +929 -423
  338. package/dist/transactions/TransactionStore.d.ts +6 -4
  339. package/dist/transactions/TransactionStore.js +6 -4
  340. package/dist/transactions/UnconfirmedWrites.d.ts +82 -0
  341. package/dist/transactions/UnconfirmedWrites.js +104 -0
  342. package/dist/transactions/coalesceRules.d.ts +41 -17
  343. package/dist/transactions/coalesceRules.js +40 -17
  344. package/dist/transactions/commitEnvelope.d.ts +132 -0
  345. package/dist/transactions/commitEnvelope.js +139 -0
  346. package/dist/transactions/commitOutboxStore.d.ts +32 -0
  347. package/dist/transactions/commitOutboxStore.js +26 -0
  348. package/dist/transactions/commitPayload.d.ts +63 -52
  349. package/dist/transactions/commitPayload.js +54 -57
  350. package/dist/transactions/deltaConfirmation.d.ts +20 -22
  351. package/dist/transactions/deltaConfirmation.js +37 -45
  352. package/dist/transactions/httpCommitEnvelope.d.ts +43 -0
  353. package/dist/transactions/httpCommitEnvelope.js +179 -0
  354. package/dist/transactions/optimisticApply.d.ts +49 -0
  355. package/dist/transactions/optimisticApply.js +65 -0
  356. package/dist/transactions/replayValidation.d.ts +182 -0
  357. package/dist/transactions/replayValidation.js +156 -0
  358. package/dist/types/global.d.ts +46 -41
  359. package/dist/types/global.js +20 -19
  360. package/dist/types/index.d.ts +71 -77
  361. package/dist/types/index.js +22 -22
  362. package/dist/types/modelData.d.ts +6 -8
  363. package/dist/types/modelData.js +5 -7
  364. package/dist/types/participant.d.ts +10 -11
  365. package/dist/types/participant.js +6 -8
  366. package/dist/types/streams.d.ts +208 -195
  367. package/dist/types/streams.js +7 -7
  368. package/dist/utils/asyncIterator.d.ts +25 -32
  369. package/dist/utils/asyncIterator.js +25 -32
  370. package/dist/utils/duration.d.ts +12 -15
  371. package/dist/utils/duration.js +12 -15
  372. package/dist/utils/mobxSetup.d.ts +53 -0
  373. package/dist/utils/{mobx-setup.js → mobxSetup.js} +42 -98
  374. package/dist/webhooks/events.d.ts +21 -16
  375. package/dist/webhooks/events.js +10 -8
  376. package/dist/webhooks/index.d.ts +5 -7
  377. package/dist/webhooks/index.js +5 -7
  378. package/dist/wire/bootstrapReason.d.ts +9 -0
  379. package/dist/wire/bootstrapReason.js +8 -0
  380. package/dist/{schema/sync-delta-wire.d.ts → wire/delta.d.ts} +58 -41
  381. package/dist/wire/delta.js +114 -0
  382. package/dist/wire/errorEnvelope.d.ts +30 -31
  383. package/dist/wire/errorEnvelope.js +34 -40
  384. package/dist/wire/frames.d.ts +315 -86
  385. package/dist/wire/frames.js +47 -33
  386. package/dist/wire/index.d.ts +18 -14
  387. package/dist/wire/index.js +32 -27
  388. package/dist/wire/listEnvelope.d.ts +16 -23
  389. package/dist/wire/listEnvelope.js +7 -6
  390. package/dist/wire/protocol.d.ts +25 -32
  391. package/dist/wire/protocol.js +25 -32
  392. package/dist/wire/protocolVersion.d.ts +44 -40
  393. package/dist/wire/protocolVersion.js +44 -40
  394. package/docs/api.md +10 -10
  395. package/docs/coordination.md +59 -0
  396. package/docs/mcp.md +1 -1
  397. package/package.json +17 -11
  398. package/dist/ai-sdk/coordinated-tool.d.ts +0 -101
  399. package/dist/ai-sdk/coordination-context.d.ts +0 -52
  400. package/dist/core/query-utils.d.ts +0 -34
  401. package/dist/core/query-utils.js +0 -59
  402. package/dist/schema/sync-delta-row.js +0 -103
  403. package/dist/schema/sync-delta-wire.js +0 -102
  404. package/dist/server/read-config.d.ts +0 -67
  405. package/dist/server/read-config.js +0 -8
  406. package/dist/server/storage-mode.d.ts +0 -8
  407. package/dist/server/storage-mode.js +0 -28
  408. package/dist/source/connector-protocol.d.ts +0 -159
  409. package/dist/source/connector-protocol.js +0 -161
  410. package/dist/transactions/OptimisticEchoTracker.d.ts +0 -82
  411. package/dist/transactions/OptimisticEchoTracker.js +0 -104
  412. package/dist/transactions/mutation-error-handler.d.ts +0 -5
  413. package/dist/transactions/mutation-error-handler.js +0 -39
  414. package/dist/transactions/optimistic.d.ts +0 -24
  415. package/dist/transactions/optimistic.js +0 -45
  416. package/dist/transactions/persistedReplay.d.ts +0 -93
  417. package/dist/transactions/persistedReplay.js +0 -105
  418. package/dist/utils/mobx-setup.d.ts +0 -42
@@ -1,26 +1,21 @@
1
1
  /**
2
- * Participant identity + scope resolution for `Ablo()`.
2
+ * Resolves a participant's identity and scope when an {@link Ablo} client is
3
+ * constructed, following whichever of three authentication paths the caller's
4
+ * options select:
3
5
  *
4
- * Three branches, mirroring the three auth paths the SDK supports:
6
+ * 1. **Hosted cloud** the caller passed an `apiKey`. The client exchanges it
7
+ * for a capability token and scope, then starts a scheduler that re-mints the
8
+ * token before it expires, so the rotation is invisible to the caller.
9
+ * 2. **Self-derived** — the caller passed a bearer or capability token but not
10
+ * an identity. The client asks the identity endpoint to recover the
11
+ * participant id and scope from the token.
12
+ * 3. **Explicit** — a self-hosted caller passed the organization id and a user
13
+ * or agent id directly. No server round-trip; the client trusts the caller.
5
14
  *
6
- * 1. **Hosted-cloud** caller passed `apiKey`. SDK exchanges it
7
- * server-side for a capability token + scope blob, then sets
8
- * up a refresh scheduler that re-mints transparently before
9
- * expiry.
10
- * 2. **Self-derived** — caller passed an authToken / capability
11
- * token but the SDK doesn't yet know the identity. Calls
12
- * `resolveIdentity` against the bootstrap endpoint to recover
13
- * `participantId` + scope from the token.
14
- * 3. **Legacy explicit** — self-hosted callers that pass
15
- * `organizationId` + `user.id` (or `agentId`) directly. No
16
- * server round-trip; SDK trusts the caller.
17
- *
18
- * Extracted from `Ablo.ts` so each branch is testable in isolation
19
- * and the constructor body reads as a single named call rather than
20
- * a 100+-line if/elif/else with three different side-effect chains.
15
+ * Each branch is a separate function below, so it can be read and tested on its own.
21
16
  */
22
17
  import { type RefreshScheduler } from '../auth/index.js';
23
- import type { BootstrapHelper } from '../sync/BootstrapHelper.js';
18
+ import type { BootstrapFetcher } from '../sync/BootstrapFetcher.js';
24
19
  import type { SyncLogger } from '../interfaces/index.js';
25
20
  import type { AuthCredentialSource } from '../auth/credentialSource.js';
26
21
  import type { ApiKeySetter } from './auth.js';
@@ -42,7 +37,7 @@ export interface IdentityResolveInput {
42
37
  readonly kind: 'user' | 'agent' | 'system';
43
38
  readonly configuredApiKey: string | ApiKeySetter | null;
44
39
  readonly configuredAuthToken: string | null;
45
- readonly bootstrapHelper: BootstrapHelper;
40
+ readonly bootstrapHelper: BootstrapFetcher;
46
41
  readonly auth: AuthCredentialSource;
47
42
  readonly logger: SyncLogger;
48
43
  }
@@ -53,7 +48,7 @@ export interface ResolvedIdentity {
53
48
  readonly capabilityToken: string | undefined;
54
49
  readonly syncGroups: readonly string[] | undefined;
55
50
  readonly participantKind: 'user' | 'agent' | 'system';
56
- /** Non-null on the hosted-cloud path; caller stores it for shutdown. */
51
+ /** Set only on the hosted-cloud path; the caller keeps it to stop refreshes on shutdown. */
57
52
  readonly refreshScheduler: RefreshScheduler | null;
58
53
  }
59
54
  export declare function resolveParticipantIdentity(input: IdentityResolveInput): Promise<ResolvedIdentity>;
@@ -1,23 +1,18 @@
1
1
  /**
2
- * Participant identity + scope resolution for `Ablo()`.
2
+ * Resolves a participant's identity and scope when an {@link Ablo} client is
3
+ * constructed, following whichever of three authentication paths the caller's
4
+ * options select:
3
5
  *
4
- * Three branches, mirroring the three auth paths the SDK supports:
6
+ * 1. **Hosted cloud** the caller passed an `apiKey`. The client exchanges it
7
+ * for a capability token and scope, then starts a scheduler that re-mints the
8
+ * token before it expires, so the rotation is invisible to the caller.
9
+ * 2. **Self-derived** — the caller passed a bearer or capability token but not
10
+ * an identity. The client asks the identity endpoint to recover the
11
+ * participant id and scope from the token.
12
+ * 3. **Explicit** — a self-hosted caller passed the organization id and a user
13
+ * or agent id directly. No server round-trip; the client trusts the caller.
5
14
  *
6
- * 1. **Hosted-cloud** caller passed `apiKey`. SDK exchanges it
7
- * server-side for a capability token + scope blob, then sets
8
- * up a refresh scheduler that re-mints transparently before
9
- * expiry.
10
- * 2. **Self-derived** — caller passed an authToken / capability
11
- * token but the SDK doesn't yet know the identity. Calls
12
- * `resolveIdentity` against the bootstrap endpoint to recover
13
- * `participantId` + scope from the token.
14
- * 3. **Legacy explicit** — self-hosted callers that pass
15
- * `organizationId` + `user.id` (or `agentId`) directly. No
16
- * server round-trip; SDK trusts the caller.
17
- *
18
- * Extracted from `Ablo.ts` so each branch is testable in isolation
19
- * and the constructor body reads as a single named call rather than
20
- * a 100+-line if/elif/else with three different side-effect chains.
15
+ * Each branch is a separate function below, so it can be read and tested on its own.
21
16
  */
22
17
  import { AbloAuthenticationError } from '../errors.js';
23
18
  import { exchangeApiKey } from '../auth/index.js';
@@ -29,22 +24,21 @@ import { resolveApiKeyValue, resolveBootstrapBaseUrl } from './auth.js';
29
24
  export async function resolveParticipantIdentity(input) {
30
25
  const { options, internalOptions, url, kind, configuredApiKey, configuredAuthToken, bootstrapHelper, auth, logger, } = input;
31
26
  const apiKeyValue = await resolveApiKeyValue(configuredApiKey);
32
- // Single source of truth for the http(s) base coerces ws/wss http/https
33
- // even when `bootstrapBaseUrl` is an explicit override (see auth.ts).
27
+ // Resolve the http(s) base URL, coercing ws/wss to http/https even when
28
+ // `bootstrapBaseUrl` is an explicit override (see auth.ts).
34
29
  const baseUrl = resolveBootstrapBaseUrl({
35
30
  url,
36
31
  bootstrapBaseUrl: options.bootstrapBaseUrl,
37
32
  });
38
- // `internalOptions.organizationId` + a caller-supplied participant id is the
39
- // legacy explicit path: the caller already knows its own identity, so no
40
- // server round-trip is needed.
33
+ // An organization id plus a caller-supplied participant id is the explicit path:
34
+ // the caller already knows its own identity, so no server round-trip is needed.
41
35
  const hasExplicitIdentity = internalOptions.organizationId != null &&
42
36
  (kind === 'agent' ? options.agentId != null : options.user?.id != null);
43
- // The connect-time credential ROUTING decision lives in `credentialPolicy`:
44
- // classify the apiKey (sk_/ek_/rk_/pk_) and route. The hosted exchange is the
45
- // one mint the policy performs (delegating to the injected `exchangeApiKey`);
46
- // every other route just hands back the bearer to use. We then switch on the
47
- // resolved `kind` below to wire up scope + the refresh scheduler.
37
+ // The credential-routing decision lives in `credentialPolicy`: it classifies the
38
+ // apiKey by prefix (`sk_`/`ek_`/`rk_`/`pk_`) and picks a route. The hosted
39
+ // exchange is the one mint the policy performs (via the injected
40
+ // `exchangeApiKey`); every other route simply returns the bearer to use. The
41
+ // switch below applies scope and sets up the refresh scheduler for each case.
48
42
  const cred = await resolveCredential({
49
43
  apiKeyValue,
50
44
  configuredApiKey,
@@ -68,12 +62,12 @@ export async function resolveParticipantIdentity(input) {
68
62
  });
69
63
  switch (cred.kind) {
70
64
  case 'publishable':
71
- // `pk_` a long-lived, browser-safe, READ-ONLY project key. Used DIRECTLY
72
- // as the bearer and NEVER exchanged for a short-lived capability — so it
73
- // never expires and there is nothing to refresh. The sync-server's
74
- // `apiKeyProvider` resolves the org + read-only scope from the key itself;
75
- // we still call `/auth/identity` (authenticated by the `pk_` bearer) to
76
- // learn the account scope + syncGroups for the bootstrap cache.
65
+ // `pk_` is a long-lived, browser-safe, read-only project key. It is used
66
+ // directly as the bearer and is never exchanged for a short-lived
67
+ // capability, so it never expires and there is nothing to refresh. The
68
+ // server resolves the organization and read-only scope from the key itself;
69
+ // we still call `/auth/identity` with the `pk_` bearer to learn the account
70
+ // scope and sync groups for the bootstrap cache.
77
71
  return resolveViaIdentity({
78
72
  bearer: cred.getBearer,
79
73
  baseUrl,
@@ -105,8 +99,8 @@ export async function resolveParticipantIdentity(input) {
105
99
  auth,
106
100
  });
107
101
  case 'explicit': {
108
- // Legacy explicit (self-hosted, pre-Phase-3 caller knows its own
109
- // organizationId + user/agentId).
102
+ // Explicit self-hosted identity: the caller supplied its own organization id
103
+ // and user or agent id.
110
104
  const userId = kind === 'agent' ? options.agentId : options.user.id;
111
105
  const accountScope = internalOptions.organizationId;
112
106
  bootstrapHelper.setCacheScope(accountScope);
@@ -125,24 +119,21 @@ export async function resolveParticipantIdentity(input) {
125
119
  }
126
120
  }
127
121
  /**
128
- * Shared `/auth/identity` resolution for the `pk_` (publishable) and pre-minted
129
- * (`ek_`/`rk_` or explicit cap token) routes: the bearer is used as-is, the
130
- * server resolves the identity, and caller-passed syncGroups are MERGED with the
131
- * server-resolved set.
122
+ * Resolves identity through the `/auth/identity` endpoint for the publishable
123
+ * (`pk_`) and pre-minted (`ek_`/`rk_` or explicit capability token) routes. The
124
+ * bearer is used as-is, the server resolves the identity, and any caller-passed
125
+ * sync groups are merged with the server-resolved set.
132
126
  */
133
127
  async function resolveViaIdentity(input) {
134
128
  const { bearer, baseUrl, options, bootstrapHelper, auth } = input;
135
129
  const identity = await resolveIdentity({ baseUrl, authToken: bearer });
136
- // Merge caller-passed syncGroups with server-resolved ones rather than letting
137
- // the server's response silently overwrite. Browser consumers (apps/web's
138
- // SyncEngineProvider) compose `['default', 'org:${orgId}', 'user:${userId}',
139
- // ...team:]` from the resolved session and pass it via `<AbloProvider
140
- // syncGroups>`; before this merge, the self-derived path dropped that set on
141
- // the floor in favor of `/auth/identity`'s response, which is empty for
142
- // cookie-auth users today (apps/sync-server/src/routes/auth.ts only populates
143
- // from `effectiveSyncGroups`, the cap-narrowed list). Empty syncGroups →
144
- // server bootstrap falls back to `['default']` → no deltas fan out → live
145
- // updates appear only on hard reload.
130
+ // Merge the caller's sync groups with the server-resolved set rather than
131
+ // letting the server response overwrite them. A client may compose groups such
132
+ // as `['default', 'org:<id>', 'user:<id>', 'team:<id>']` from the resolved
133
+ // session and pass them in; the identity endpoint can return an empty set (for
134
+ // example, for cookie-authenticated users), and an empty set makes the server
135
+ // bootstrap fall back to `['default']`, so no deltas fan out and live updates
136
+ // appear only on a hard reload. Merging keeps the caller's groups intact.
146
137
  const callerGroups = options.syncGroups ?? [];
147
138
  const mergedSyncGroups = callerGroups.length > 0
148
139
  ? [...new Set([...callerGroups, ...identity.syncGroups])]
@@ -161,9 +152,9 @@ async function resolveViaIdentity(input) {
161
152
  };
162
153
  }
163
154
  async function resolveHosted(input) {
164
- // Pure managed-cloud shape: `Ablo({schema, apiKey})`. The credential policy
165
- // already exchanged the apiKey (delegating to `exchangeApiKey`); here we apply
166
- // the returned scope + userMeta and stand up the refresh scheduler.
155
+ // The managed-cloud shape, `Ablo({ schema, apiKey })`. The credential policy has
156
+ // already exchanged the apiKey via `exchangeApiKey`; here we apply the returned
157
+ // scope and set up the refresh scheduler.
167
158
  const { exchange } = input.cred;
168
159
  const baseUrl = input.baseUrl;
169
160
  // The refresh path re-runs `exchangeApiKey` with a freshly-resolved apiKey, so
@@ -179,12 +170,10 @@ async function resolveHosted(input) {
179
170
  input.bootstrapHelper.setCacheScope(exchange.scope.organizationId);
180
171
  input.bootstrapHelper.setSyncGroups(exchange.scope.syncGroups);
181
172
  input.auth.setAuthToken(exchange.token);
182
- // Cap tokens have a server-set TTL (3600s by default). Without
183
- // proactive refresh the WS would either get force-closed at expiry
184
- // or fail its next reconnect with 401. The scheduler re-mints
185
- // transparently before that fires; the consumer never sees the
186
- // rotation. Rationale + tradeoffs in
187
- // `packages/sync-engine/src/auth/refreshScheduler.ts`
173
+ // Capability tokens carry a server-set TTL (3600s by default). Without proactive
174
+ // refresh, the socket would be force-closed at expiry, or the next reconnect
175
+ // would fail with a 401. The scheduler re-mints ahead of that, so the consumer
176
+ // never sees the rotation.
188
177
  const refreshScheduler = createRefreshScheduler({
189
178
  initialExpiresAtMs: Date.parse(exchange.expiresAt),
190
179
  refresh: async () => {
@@ -1,13 +1,9 @@
1
1
  /**
2
- * Schema Model-class registration `registerModelsFromSchema` walks the
3
- * declarative schema and populates the `ModelRegistry`: a dynamic `Model`
4
- * subclass per model (`createDynamicModelClass`, with `${field}Json` getters,
5
- * computed getters, and opt-in MobX field observability), property/relation
6
- * registration, and IDB index selection.
7
- *
8
- * Extracted from `Ablo.ts` — the factory calls `registerModelsFromSchema`
9
- * right after `createInternalComponents` builds the registry. The zod unwrap
10
- * helpers stay module-local.
2
+ * Registers model classes from a declarative schema. {@link registerModelsFromSchema}
3
+ * walks the schema and populates the model registry: for each model it builds a
4
+ * dynamic {@link Model} subclass (with `${field}Json` getters, computed getters,
5
+ * and opt-in field-level reactivity) and registers the model's properties,
6
+ * relations, and any local-database indexes.
11
7
  */
12
8
  import type { Schema } from '../schema/schema.js';
13
9
  import type { ModelRegistry } from '../ModelRegistry.js';
@@ -1,13 +1,9 @@
1
1
  /**
2
- * Schema Model-class registration `registerModelsFromSchema` walks the
3
- * declarative schema and populates the `ModelRegistry`: a dynamic `Model`
4
- * subclass per model (`createDynamicModelClass`, with `${field}Json` getters,
5
- * computed getters, and opt-in MobX field observability), property/relation
6
- * registration, and IDB index selection.
7
- *
8
- * Extracted from `Ablo.ts` — the factory calls `registerModelsFromSchema`
9
- * right after `createInternalComponents` builds the registry. The zod unwrap
10
- * helpers stay module-local.
2
+ * Registers model classes from a declarative schema. {@link registerModelsFromSchema}
3
+ * walks the schema and populates the model registry: for each model it builds a
4
+ * dynamic {@link Model} subclass (with `${field}Json` getters, computed getters,
5
+ * and opt-in field-level reactivity) and registers the model's properties,
6
+ * relations, and any local-database indexes.
11
7
  */
12
8
  import { z } from 'zod';
13
9
  import { baseFieldsSchema } from '../schema/schema.js';
@@ -32,25 +28,22 @@ export function registerModelsFromSchema(schema, registry) {
32
28
  }
33
29
  // Create a dynamic Model subclass with JSON sub-property getters.
34
30
  //
35
- // Field-level MobX observability is ON BY DEFAULT. A reactive read like
36
- // `useAblo((a) => a.documents.get(id))` must re-render when a remote delta
37
- // mutates the row IN PLACE (the common collaborative case); without
38
- // per-field observability that update fires no reaction and the UI silently
39
- // goes stale. Models opt OUT with an explicit `lazyObservable: false`
40
- // appropriate only for very large read-only list models where per-field
41
- // atoms cost more than the QueryView's entry-replaced reactivity already
42
- // provides. json fields register as `observable.ref` (see
43
- // `registerModelsFromSchema`), so the default is ~one atom per scalar field
44
- // per loaded row — cheap — not a deep atom tree per blob.
31
+ // Field-level reactivity is on by default. A reactive read must re-render when
32
+ // a remote delta mutates a row in place, which is the common collaborative
33
+ // case; without per-field reactivity that update fires no reaction and the UI
34
+ // silently goes stale. A model opts out with `lazyObservable: false`, which
35
+ // suits only very large read-only list models where per-field atoms cost more
36
+ // than the coarser entry-replaced reactivity already provides. JSON fields
37
+ // register as reference-tracked, so the default is about one atom per scalar
38
+ // field per loaded row cheap — not a deep atom tree per blob.
45
39
  const isLazy = modelDef.lazyObservable !== false;
46
40
  // Base provenance fields (`organizationId`, `createdBy`) live in
47
- // `baseFieldsSchema`, not the per-model `shape`. The server stamps + emits
48
- // them (camelCased on the wire), but hydration (`Model.assignFieldsFromData`)
49
- // only assigns keys that already exist as an own/prototype property so
50
- // without a slot here, `deck.createdBy` / `deck.organizationId` silently read
51
- // `undefined` (this is why the profile decks tab showed nothing: it filters
52
- // `decks.filter(d => d.createdBy === userId)`). `id`/`createdAt`/`updatedAt`
53
- // are already seeded by the base Model constructor, so they're excluded.
41
+ // `baseFieldsSchema`, not in the per-model `shape`. The server stamps and emits
42
+ // them (camelCased on the wire), but hydration only assigns keys that already
43
+ // exist as own or prototype properties so without a slot here, reads like
44
+ // `row.createdBy` or `row.organizationId` would silently be `undefined`.
45
+ // `id`, `createdAt`, and `updatedAt` are already seeded by the base Model
46
+ // constructor, so they are excluded.
54
47
  const fieldNames = [
55
48
  ...Object.keys(modelDef.shape),
56
49
  ...Object.keys(baseFieldsSchema.shape).filter((f) => f !== 'id' && f !== 'createdAt' && f !== 'updatedAt' && !(f in modelDef.shape)),
@@ -67,18 +60,14 @@ export function registerModelsFromSchema(schema, registry) {
67
60
  autoFill: modelDef.autoFill,
68
61
  requiredFields: modelDef.requiredFields,
69
62
  });
70
- // Collect the set of fields that should get an IDB secondary index.
71
- //
72
- // Matches Linear's opt-in model (see wzhudev/reverse-linear-sync-engine):
73
- // `@Reference(..., { indexed: true })`. Only `belongsTo` relations that
74
- // explicitly set `{ index: true }` in their options get an IDB secondary
75
- // index. Every other FK (and every scalar) is resolved via in-memory
76
- // ObjectPool scans, which are fast enough at org-scope sizes (~10k rows)
77
- // and reactive via MobX.
63
+ // Collect the fields that should get a local-database secondary index.
78
64
  //
79
- // Auto-indexing every belongsTo was wrong: it bloated write amplification
80
- // for the vast majority of FKs that are never queried by fk. Indexing
81
- // every scalar (like the legacy Go backend did) is even worse.
65
+ // Only `belongsTo` relations that explicitly set `{ index: true }` are indexed.
66
+ // Every other foreign key, and every scalar, is resolved by in-memory scans,
67
+ // which are fast enough at organization-scope sizes (on the order of 10k rows)
68
+ // and stay reactive. Indexing is opt-in deliberately: auto-indexing every
69
+ // foreign key inflates write amplification for the many keys never queried by
70
+ // id, and indexing every scalar is worse still.
82
71
  const indexedFields = new Set();
83
72
  for (const relDef of Object.values(modelDef.relations)) {
84
73
  if (relDef.type === 'belongsTo' && relDef.foreignKey && relDef.options?.index === true) {
@@ -89,16 +78,15 @@ export function registerModelsFromSchema(schema, registry) {
89
78
  for (const [fieldName, rawZodType] of Object.entries(modelDef.shape)) {
90
79
  const zodType = rawZodType;
91
80
  const isOptional = zodType.isOptional?.() ?? false;
92
- // A field is indexed if it's the FK of a `belongsTo({ index: true })`
93
- // relation. Legacy `description === 'indexed'` still works for
94
- // consumers using `field.*().indexed()`.
81
+ // A field is indexed if it is the foreign key of a
82
+ // `belongsTo({ index: true })` relation. A `description === 'indexed'` tag
83
+ // also works, for consumers using the `field.*().indexed()` builder.
95
84
  const isIndexed = indexedFields.has(fieldName) || zodType.description === 'indexed';
96
- // JSON-typed fields (per the schema's wire-type tag) are opaque
97
- // blobs from MobX's perspective chart specs, ProseMirror docs,
98
- // style maps. Deep observability on them recursively walks every
99
- // nested property and creates an atom for each leaf, producing a
100
- // microtask storm on every commit/streaming update. `ref` tracks
101
- // only reassignment, which is how blob consumers actually use them.
85
+ // JSON-typed fields (per the schema's wire-type tag) are opaque blobs —
86
+ // chart specs, rich-text documents, style maps. Deep reactivity on them
87
+ // would walk every nested property and create an atom per leaf, producing a
88
+ // storm of updates on each commit or streaming change. Reference tracking
89
+ // watches only reassignment, which is how blob consumers actually use them.
102
90
  const wireType = modelDef.fields?.[fieldName]?.type;
103
91
  const observability = wireType === 'json' ? 'ref' : undefined;
104
92
  registry.registerProperty(modelName, fieldName, {
@@ -185,9 +173,8 @@ function unwrapZodType(schema) {
185
173
  continue;
186
174
  }
187
175
  if (current instanceof z.ZodDefault) {
188
- // v4 deprecates removeDefault in favor of unwrap, but the
189
- // installed @types declarations only expose removeDefault on
190
- // ZodDefault. Use it — it's the same runtime function.
176
+ // Zod v4 unwraps a default via `.unwrap()`, the same runtime function older
177
+ // versions exposed as `removeDefault`.
191
178
  current = current.unwrap();
192
179
  continue;
193
180
  }
@@ -205,50 +192,55 @@ function isZodObject(schema) {
205
192
  }
206
193
  /** Create a Model subclass for a schema-defined model */
207
194
  function createDynamicModelClass(modelName, jsonSubFields, fieldNames, computed, lazyObservable = false) {
195
+ // Names `toReactiveSnapshot` materializes onto plain snapshots: every
196
+ // `${field}Json` getter plus every schema-declared computed. Without this,
197
+ // snapshot rows silently drop getters that the schema's inferred row type
198
+ // declares — reads like `snapshot.settingsObject` would be `undefined`.
199
+ const derivedGetterNames = Object.freeze([
200
+ ...jsonSubFields.map(({ fieldName }) => `${fieldName}Json`),
201
+ ...Object.keys(computed ?? {}),
202
+ ]);
208
203
  const ModelClass = class extends Model {
209
204
  _modelName = modelName;
205
+ getDerivedGetterNames() {
206
+ return derivedGetterNames;
207
+ }
210
208
  constructor(data) {
211
209
  super(data);
212
- // Gate `propertyChanged`-via-`observe` tracking during initial
213
- // hydration. M1 installs a MobX `observe()` listener per schema
214
- // property that forwards writes to `propertyChanged()` so direct
215
- // assignments like `layer.position = newPos` still round-trip
216
- // through the transaction queue. During construction we're writing
217
- // wire data, NOT user edits flagging this as "constructing" lets
218
- // the listener early-return on those writes so `modifiedProperties`
219
- // doesn't get polluted with every field of every hydrated model.
210
+ // Suppress change tracking during initial hydration. `makeObservable()`
211
+ // installs a listener per schema property that forwards writes to the
212
+ // transaction queue, so direct assignments like `row.position = next` still
213
+ // round-trip. During construction we are writing wire data, not user edits,
214
+ // so this flag lets that listener skip these writes and keeps the set of
215
+ // modified properties from filling up with every field of every hydrated row.
220
216
  //
221
- // The listener is installed by `makeObservable()` below (inside
222
- // M1), so writes that happen BEFORE that line won't fire it; this
223
- // flag is defensive in case a subclass or call path reorders the
224
- // steps later.
217
+ // The listener is installed by `makeObservable()` below, so writes before
218
+ // that line never reach it; this flag is defensive in case a subclass or call
219
+ // path later reorders the steps.
225
220
  this._isConstructing = true;
226
- // MobX 6 requires fields to exist as own properties BEFORE makeObservable().
227
- // Model base only sets id/createdAt/updatedAt. Schema fields (title, userId, etc.)
228
- // must be initialized here so M1's annotations can find them.
221
+ // Reactive fields must exist as own properties before `makeObservable()` runs.
222
+ // The base Model sets only id, createdAt, and updatedAt, so schema fields
223
+ // (title, userId, and so on) are initialized here for the annotations to find.
229
224
  for (const field of fieldNames) {
230
225
  if (!(field in this)) {
231
226
  this[field] = data?.[field] ?? undefined;
232
227
  }
233
228
  }
234
- // Per-field MobX observability opt-in via `lazyObservable: true` on
235
- // the model definition. Defaults to plain objects reactivity comes
236
- // from the QueryView "entry replaced" pattern, which is cheap for
237
- // read-only list UIs but invisible to in-place field mutations.
229
+ // When field-level reactivity is enabled (the default; a model turns it off
230
+ // with `lazyObservable: false`), make each field observable. Without it,
231
+ // reactivity comes only from the coarser entry-replaced pattern, which is
232
+ // cheap for read-only lists but invisible to in-place field mutations.
238
233
  //
239
- // Multiplayer editors need live field-level reactivity so remote
240
- // deltas AND local drag/resize/rename mutations surface through
241
- // `observer()` components without the whole pool entry being
242
- // replaced. Without observability, `layer.position.x = 500` emits
243
- // nothing and the UI lags until some unrelated state change triggers
244
- // a pass (toolbar close, deselect).
234
+ // Collaborative editors need field-level reactivity so both remote deltas and
235
+ // local edits surface through observer components without the whole cache
236
+ // entry being replaced. Otherwise an in-place mutation such as
237
+ // `row.position.x = 500` emits nothing and the UI lags until an unrelated
238
+ // change triggers a pass.
245
239
  //
246
- // Delegates to `Model.makeObservable()` (the inherited method) so
247
- // MobX annotations are derived from the same registry that M1 reads.
248
- // That means computed getters, reference collections, custom
249
- // getters/setters, and property-change tracking all integrate
250
- // correctly — reimplementing `makeObservable` inline here would miss
251
- // those seams.
240
+ // This delegates to the inherited `Model.makeObservable()` so the annotations
241
+ // come from the same registry the rest of the model reads, keeping computed
242
+ // getters, reference collections, custom getters and setters, and change
243
+ // tracking all consistent; reimplementing it inline here would miss those.
252
244
  if (lazyObservable) {
253
245
  this.makeObservable();
254
246
  }
@@ -258,15 +250,14 @@ function createDynamicModelClass(modelName, jsonSubFields, fieldNames, computed,
258
250
  return this._modelName;
259
251
  }
260
252
  };
261
- // Generate ${field}Json getters for JSON fields with sub-properties.
253
+ // Generate `${field}Json` getters for JSON fields that have sub-properties.
262
254
  //
263
- // The getter reads the raw JSON string from the instance (set via
264
- // updateFromData), parses it, applies Zod defaults, and caches by
265
- // raw value. This replaces the hand-coded metadataObject + sub-property
266
- // getter pattern that 11+ Ablo models currently repeat.
255
+ // Each getter reads the raw JSON from the instance, parses it, applies the
256
+ // sub-schema's defaults, and caches the result keyed by the raw value.
267
257
  //
268
- // Example: field named 'metadata' with sub-schema { icon: z.string().default('presentation') }
269
- // → model.metadataJson returns { icon: 'presentation', ... } (typed, cached)
258
+ // Example: a field named `metadata` with sub-schema
259
+ // `{ icon: z.string().default('presentation') }` yields a `metadataJson` getter
260
+ // returning `{ icon: 'presentation', ... }` — typed and cached.
270
261
  for (const { fieldName, subSchema } of jsonSubFields) {
271
262
  const getterName = `${fieldName}Json`;
272
263
  const cacheKey = `__${fieldName}JsonCache`;