@abloatai/ablo 0.26.0 → 0.27.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 (398) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/README.md +101 -85
  3. package/dist/BaseSyncedStore.d.ts +85 -88
  4. package/dist/BaseSyncedStore.js +131 -147
  5. package/dist/Database.d.ts +54 -68
  6. package/dist/Database.js +97 -113
  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 +37 -52
  12. package/dist/Model.js +46 -61
  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 +112 -112
  18. package/dist/SyncClient.js +165 -172
  19. package/dist/adapters/alwaysOnline.d.ts +6 -8
  20. package/dist/adapters/alwaysOnline.js +6 -8
  21. package/dist/adapters/inMemoryStorage.d.ts +9 -9
  22. package/dist/adapters/inMemoryStorage.js +9 -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 +167 -119
  50. package/dist/client/Ablo.d.ts +73 -73
  51. package/dist/client/Ablo.js +125 -160
  52. package/dist/client/ApiClient.d.ts +30 -19
  53. package/dist/client/ApiClient.js +133 -38
  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 +14 -17
  61. package/dist/client/createInternalComponents.js +25 -30
  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 +57 -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 +67 -87
  76. package/dist/client/options.d.ts +134 -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 +15 -20
  91. package/dist/client/wsMutationExecutor.js +17 -23
  92. package/dist/context.d.ts +6 -4
  93. package/dist/context.js +6 -4
  94. package/dist/coordination/index.d.ts +10 -8
  95. package/dist/coordination/index.js +14 -12
  96. package/dist/coordination/schema.d.ts +176 -128
  97. package/dist/coordination/schema.js +197 -133
  98. package/dist/coordination/trace.d.ts +9 -10
  99. package/dist/coordination/trace.js +13 -14
  100. package/dist/core/DatabaseManager.d.ts +5 -7
  101. package/dist/core/DatabaseManager.js +15 -19
  102. package/dist/core/QueryProcessor.d.ts +7 -9
  103. package/dist/core/QueryProcessor.js +22 -28
  104. package/dist/core/QueryView.d.ts +8 -8
  105. package/dist/core/QueryView.js +2 -2
  106. package/dist/core/StoreManager.d.ts +12 -14
  107. package/dist/core/StoreManager.js +21 -24
  108. package/dist/core/ViewRegistry.d.ts +5 -5
  109. package/dist/core/ViewRegistry.js +4 -4
  110. package/dist/core/index.d.ts +17 -12
  111. package/dist/core/index.js +32 -26
  112. package/dist/core/openIDBWithTimeout.d.ts +38 -36
  113. package/dist/core/openIDBWithTimeout.js +42 -43
  114. package/dist/core/queryUtils.d.ts +45 -0
  115. package/dist/core/queryUtils.js +69 -0
  116. package/dist/core/storeContract.d.ts +63 -61
  117. package/dist/core/storeContract.js +8 -12
  118. package/dist/environment.d.ts +28 -0
  119. package/dist/environment.js +21 -0
  120. package/dist/errorCodes.d.ts +107 -99
  121. package/dist/errorCodes.js +131 -132
  122. package/dist/errors.d.ts +160 -166
  123. package/dist/errors.js +155 -158
  124. package/dist/index.d.ts +30 -27
  125. package/dist/index.js +89 -86
  126. package/dist/interfaces/index.d.ts +102 -113
  127. package/dist/interfaces/index.js +5 -4
  128. package/dist/keys/index.d.ts +27 -29
  129. package/dist/keys/index.js +41 -40
  130. package/dist/mutators/RecordingTransaction.d.ts +16 -16
  131. package/dist/mutators/RecordingTransaction.js +31 -37
  132. package/dist/mutators/Transaction.d.ts +18 -26
  133. package/dist/mutators/Transaction.js +14 -20
  134. package/dist/mutators/UndoManager.d.ts +122 -131
  135. package/dist/mutators/UndoManager.js +145 -156
  136. package/dist/mutators/defineMutators.d.ts +23 -34
  137. package/dist/mutators/defineMutators.js +14 -20
  138. package/dist/mutators/inverseOp.d.ts +12 -15
  139. package/dist/mutators/inverseOp.js +12 -15
  140. package/dist/mutators/mutateActions.d.ts +10 -9
  141. package/dist/mutators/mutateActions.js +1 -1
  142. package/dist/mutators/readerActions.d.ts +9 -8
  143. package/dist/mutators/readerActions.js +2 -2
  144. package/dist/mutators/undoApply.d.ts +31 -27
  145. package/dist/mutators/undoApply.js +26 -24
  146. package/dist/policy/index.d.ts +5 -3
  147. package/dist/policy/index.js +5 -3
  148. package/dist/policy/types.d.ts +104 -100
  149. package/dist/policy/types.js +67 -66
  150. package/dist/query/client.d.ts +28 -23
  151. package/dist/query/client.js +45 -43
  152. package/dist/query/types.d.ts +37 -60
  153. package/dist/query/types.js +13 -33
  154. package/dist/react/AbloProvider.d.ts +1 -1
  155. package/dist/react/AbloProvider.js +2 -2
  156. package/dist/react/context.d.ts +25 -28
  157. package/dist/react/context.js +9 -10
  158. package/dist/react/index.d.ts +41 -42
  159. package/dist/react/index.js +37 -38
  160. package/dist/react/internalContext.d.ts +17 -19
  161. package/dist/react/useAblo.d.ts +23 -22
  162. package/dist/react/useAblo.js +16 -14
  163. package/dist/react/useCurrentUserId.d.ts +8 -7
  164. package/dist/react/useCurrentUserId.js +8 -7
  165. package/dist/react/useErrorListener.d.ts +7 -7
  166. package/dist/react/useErrorListener.js +10 -11
  167. package/dist/react/useMutationFailureListener.d.ts +8 -8
  168. package/dist/react/useMutationFailureListener.js +8 -8
  169. package/dist/react/useMutators.d.ts +11 -11
  170. package/dist/react/useMutators.js +3 -3
  171. package/dist/react/useReactive.js +2 -2
  172. package/dist/react/useSyncStatus.d.ts +4 -6
  173. package/dist/react/useUndoScope.d.ts +7 -9
  174. package/dist/react/useUndoScope.js +1 -1
  175. package/dist/schema/coordination.d.ts +21 -25
  176. package/dist/schema/coordination.js +21 -25
  177. package/dist/schema/ddl.d.ts +43 -39
  178. package/dist/schema/ddl.js +75 -68
  179. package/dist/schema/ddlLock.d.ts +20 -24
  180. package/dist/schema/ddlLock.js +18 -23
  181. package/dist/schema/diff.d.ts +99 -61
  182. package/dist/schema/diff.js +43 -34
  183. package/dist/schema/field.d.ts +37 -42
  184. package/dist/schema/field.js +35 -48
  185. package/dist/schema/generate.d.ts +12 -12
  186. package/dist/schema/generate.js +12 -12
  187. package/dist/schema/index.d.ts +2 -2
  188. package/dist/schema/index.js +21 -23
  189. package/dist/schema/model.d.ts +118 -143
  190. package/dist/schema/model.js +22 -33
  191. package/dist/schema/openapi.d.ts +10 -9
  192. package/dist/schema/openapi.js +5 -3
  193. package/dist/schema/queries.d.ts +29 -31
  194. package/dist/schema/queries.js +23 -25
  195. package/dist/schema/relation.d.ts +89 -99
  196. package/dist/schema/relation.js +13 -13
  197. package/dist/schema/residency.d.ts +16 -13
  198. package/dist/schema/residency.js +16 -13
  199. package/dist/schema/roles.d.ts +36 -43
  200. package/dist/schema/roles.js +31 -37
  201. package/dist/schema/schema.d.ts +33 -42
  202. package/dist/schema/schema.js +31 -32
  203. package/dist/schema/select.d.ts +13 -13
  204. package/dist/schema/select.js +13 -13
  205. package/dist/schema/serialize.d.ts +28 -31
  206. package/dist/schema/serialize.js +27 -31
  207. package/dist/schema/sugar.d.ts +17 -32
  208. package/dist/schema/sugar.js +14 -29
  209. package/dist/schema/{sync-delta-row.d.ts → syncDeltaRow.d.ts} +26 -49
  210. package/dist/schema/syncDeltaRow.js +89 -0
  211. package/dist/schema/tenancy.d.ts +44 -46
  212. package/dist/schema/tenancy.js +46 -48
  213. package/dist/server/adapter.d.ts +58 -58
  214. package/dist/server/adapter.js +13 -14
  215. package/dist/server/commit.d.ts +60 -64
  216. package/dist/server/index.d.ts +9 -10
  217. package/dist/server/index.js +1 -1
  218. package/dist/server/readConfig.d.ts +70 -0
  219. package/dist/server/readConfig.js +8 -0
  220. package/dist/server/storageMode.d.ts +23 -0
  221. package/dist/server/storageMode.js +17 -0
  222. package/dist/source/adapter.d.ts +30 -25
  223. package/dist/source/adapter.js +10 -10
  224. package/dist/source/adapters/drizzle.d.ts +28 -23
  225. package/dist/source/adapters/drizzle.js +30 -25
  226. package/dist/source/adapters/kysely.d.ts +27 -25
  227. package/dist/source/adapters/kysely.js +24 -23
  228. package/dist/source/adapters/memory.d.ts +8 -7
  229. package/dist/source/adapters/memory.js +9 -8
  230. package/dist/source/adapters/prisma.d.ts +13 -12
  231. package/dist/source/adapters/prisma.js +22 -25
  232. package/dist/source/conformance.d.ts +18 -11
  233. package/dist/source/conformance.js +17 -11
  234. package/dist/source/connector.d.ts +31 -32
  235. package/dist/source/connector.js +28 -28
  236. package/dist/source/connectorProtocol.d.ts +160 -0
  237. package/dist/source/connectorProtocol.js +162 -0
  238. package/dist/source/contract.d.ts +26 -27
  239. package/dist/source/contract.js +28 -29
  240. package/dist/source/factory.d.ts +46 -58
  241. package/dist/source/factory.js +22 -27
  242. package/dist/source/index.d.ts +7 -9
  243. package/dist/source/index.js +12 -14
  244. package/dist/source/migrations.d.ts +9 -9
  245. package/dist/source/migrations.js +9 -9
  246. package/dist/source/next.d.ts +9 -10
  247. package/dist/source/next.js +6 -7
  248. package/dist/source/pushQueue.d.ts +69 -47
  249. package/dist/source/pushQueue.js +32 -28
  250. package/dist/source/signing.d.ts +46 -17
  251. package/dist/source/signing.js +28 -11
  252. package/dist/source/types.d.ts +121 -104
  253. package/dist/source/types.js +13 -14
  254. package/dist/stores/ObjectStore.d.ts +10 -11
  255. package/dist/stores/ObjectStore.js +11 -12
  256. package/dist/stores/ObjectStoreContract.d.ts +12 -15
  257. package/dist/stores/SyncActionStore.d.ts +7 -11
  258. package/dist/stores/SyncActionStore.js +13 -17
  259. package/dist/surface.d.ts +27 -20
  260. package/dist/surface.js +27 -20
  261. package/dist/sync/{BootstrapHelper.d.ts → BootstrapFetcher.d.ts} +36 -42
  262. package/dist/sync/{BootstrapHelper.js → BootstrapFetcher.js} +76 -76
  263. package/dist/sync/ConnectionManager.d.ts +39 -50
  264. package/dist/sync/ConnectionManager.js +55 -66
  265. package/dist/sync/NetworkProbe.d.ts +24 -29
  266. package/dist/sync/NetworkProbe.js +63 -69
  267. package/dist/sync/{HydrationCoordinator.d.ts → OnDemandLoader.d.ts} +42 -41
  268. package/dist/sync/{HydrationCoordinator.js → OnDemandLoader.js} +59 -54
  269. package/dist/sync/{AreaOfInterestManager.d.ts → SubscriptionManager.d.ts} +43 -57
  270. package/dist/sync/{AreaOfInterestManager.js → SubscriptionManager.js} +43 -51
  271. package/dist/sync/SyncWebSocket.d.ts +139 -165
  272. package/dist/sync/SyncWebSocket.js +191 -223
  273. package/dist/sync/awaitClaimGrant.d.ts +18 -18
  274. package/dist/sync/awaitClaimGrant.js +11 -11
  275. package/dist/sync/bootstrapApply.d.ts +34 -24
  276. package/dist/sync/bootstrapApply.js +27 -19
  277. package/dist/sync/commitFrames.d.ts +21 -20
  278. package/dist/sync/commitFrames.js +18 -18
  279. package/dist/sync/createClaimStream.d.ts +23 -22
  280. package/dist/sync/createClaimStream.js +105 -23
  281. package/dist/sync/createPresenceStream.d.ts +19 -18
  282. package/dist/sync/createPresenceStream.js +25 -26
  283. package/dist/sync/createSnapshot.d.ts +12 -14
  284. package/dist/sync/createSnapshot.js +20 -26
  285. package/dist/sync/credentialLifecycle.d.ts +104 -104
  286. package/dist/sync/credentialLifecycle.js +140 -147
  287. package/dist/sync/deltaPipeline.d.ts +36 -34
  288. package/dist/sync/deltaPipeline.js +64 -65
  289. package/dist/sync/groupChange.d.ts +63 -61
  290. package/dist/sync/groupChange.js +74 -78
  291. package/dist/sync/heartbeat.d.ts +34 -33
  292. package/dist/sync/heartbeat.js +31 -31
  293. package/dist/sync/participants.d.ts +19 -19
  294. package/dist/sync/schemas.d.ts +3 -2
  295. package/dist/sync/schemas.js +14 -10
  296. package/dist/sync/syncCursor.d.ts +17 -21
  297. package/dist/sync/syncCursor.js +17 -21
  298. package/dist/sync/syncPlan.d.ts +28 -36
  299. package/dist/sync/syncPlan.js +18 -19
  300. package/dist/sync/syncPosition.d.ts +54 -49
  301. package/dist/sync/syncPosition.js +57 -52
  302. package/dist/sync/wsFrameHandlers.d.ts +35 -36
  303. package/dist/sync/wsFrameHandlers.js +63 -67
  304. package/dist/testing/fixtures/bootstrap.d.ts +12 -6
  305. package/dist/testing/fixtures/bootstrap.js +12 -6
  306. package/dist/testing/fixtures/deltas.d.ts +30 -33
  307. package/dist/testing/fixtures/deltas.js +30 -33
  308. package/dist/testing/fixtures/models.d.ts +11 -10
  309. package/dist/testing/fixtures/models.js +11 -10
  310. package/dist/testing/helpers/{react-wrapper.d.ts → reactWrapper.d.ts} +13 -10
  311. package/dist/testing/helpers/{react-wrapper.js → reactWrapper.js} +15 -12
  312. package/dist/testing/helpers/{sync-engine-harness.d.ts → syncEngineHarness.d.ts} +17 -15
  313. package/dist/testing/helpers/{sync-engine-harness.js → syncEngineHarness.js} +12 -10
  314. package/dist/testing/helpers/wait.d.ts +13 -8
  315. package/dist/testing/helpers/wait.js +13 -8
  316. package/dist/testing/index.d.ts +3 -3
  317. package/dist/testing/index.js +2 -2
  318. package/dist/testing/mocks/MockMutationExecutor.d.ts +18 -17
  319. package/dist/testing/mocks/MockMutationExecutor.js +15 -14
  320. package/dist/testing/mocks/MockNetworkMonitor.d.ts +8 -8
  321. package/dist/testing/mocks/MockNetworkMonitor.js +8 -8
  322. package/dist/testing/mocks/MockSyncContext.d.ts +20 -17
  323. package/dist/testing/mocks/MockSyncContext.js +15 -13
  324. package/dist/testing/mocks/MockSyncStore.d.ts +10 -10
  325. package/dist/testing/mocks/MockSyncStore.js +11 -11
  326. package/dist/testing/mocks/MockWebSocket.d.ts +26 -22
  327. package/dist/testing/mocks/MockWebSocket.js +22 -21
  328. package/dist/transactions/TransactionQueue.d.ts +181 -176
  329. package/dist/transactions/TransactionQueue.js +338 -350
  330. package/dist/transactions/TransactionStore.d.ts +6 -4
  331. package/dist/transactions/TransactionStore.js +6 -4
  332. package/dist/transactions/UnconfirmedWrites.d.ts +82 -0
  333. package/dist/transactions/UnconfirmedWrites.js +104 -0
  334. package/dist/transactions/coalesceRules.d.ts +41 -17
  335. package/dist/transactions/coalesceRules.js +40 -17
  336. package/dist/transactions/commitPayload.d.ts +48 -52
  337. package/dist/transactions/commitPayload.js +48 -57
  338. package/dist/transactions/deltaConfirmation.d.ts +20 -22
  339. package/dist/transactions/deltaConfirmation.js +37 -45
  340. package/dist/transactions/optimisticApply.d.ts +49 -0
  341. package/dist/transactions/optimisticApply.js +65 -0
  342. package/dist/transactions/{persistedReplay.d.ts → replayValidation.d.ts} +28 -22
  343. package/dist/transactions/{persistedReplay.js → replayValidation.js} +33 -27
  344. package/dist/types/global.d.ts +46 -41
  345. package/dist/types/global.js +20 -19
  346. package/dist/types/index.d.ts +71 -77
  347. package/dist/types/index.js +22 -22
  348. package/dist/types/modelData.d.ts +6 -8
  349. package/dist/types/modelData.js +5 -7
  350. package/dist/types/participant.d.ts +10 -11
  351. package/dist/types/participant.js +6 -8
  352. package/dist/types/streams.d.ts +208 -195
  353. package/dist/types/streams.js +7 -7
  354. package/dist/utils/asyncIterator.d.ts +25 -32
  355. package/dist/utils/asyncIterator.js +25 -32
  356. package/dist/utils/duration.d.ts +12 -15
  357. package/dist/utils/duration.js +12 -15
  358. package/dist/utils/mobxSetup.d.ts +53 -0
  359. package/dist/utils/{mobx-setup.js → mobxSetup.js} +42 -98
  360. package/dist/webhooks/events.d.ts +21 -16
  361. package/dist/webhooks/events.js +10 -8
  362. package/dist/webhooks/index.d.ts +5 -7
  363. package/dist/webhooks/index.js +5 -7
  364. package/dist/{schema/sync-delta-wire.d.ts → wire/delta.d.ts} +58 -41
  365. package/dist/wire/delta.js +114 -0
  366. package/dist/wire/errorEnvelope.d.ts +30 -31
  367. package/dist/wire/errorEnvelope.js +34 -40
  368. package/dist/wire/frames.d.ts +79 -86
  369. package/dist/wire/frames.js +26 -33
  370. package/dist/wire/index.d.ts +14 -12
  371. package/dist/wire/index.js +30 -26
  372. package/dist/wire/listEnvelope.d.ts +16 -23
  373. package/dist/wire/listEnvelope.js +7 -6
  374. package/dist/wire/protocol.d.ts +25 -32
  375. package/dist/wire/protocol.js +25 -32
  376. package/dist/wire/protocolVersion.d.ts +44 -40
  377. package/dist/wire/protocolVersion.js +44 -40
  378. package/docs/coordination.md +59 -0
  379. package/package.json +11 -10
  380. package/dist/ai-sdk/coordinated-tool.d.ts +0 -101
  381. package/dist/ai-sdk/coordination-context.d.ts +0 -52
  382. package/dist/core/query-utils.d.ts +0 -34
  383. package/dist/core/query-utils.js +0 -59
  384. package/dist/schema/sync-delta-row.js +0 -103
  385. package/dist/schema/sync-delta-wire.js +0 -102
  386. package/dist/server/read-config.d.ts +0 -67
  387. package/dist/server/read-config.js +0 -8
  388. package/dist/server/storage-mode.d.ts +0 -8
  389. package/dist/server/storage-mode.js +0 -28
  390. package/dist/source/connector-protocol.d.ts +0 -159
  391. package/dist/source/connector-protocol.js +0 -161
  392. package/dist/transactions/OptimisticEchoTracker.d.ts +0 -82
  393. package/dist/transactions/OptimisticEchoTracker.js +0 -104
  394. package/dist/transactions/mutation-error-handler.d.ts +0 -5
  395. package/dist/transactions/mutation-error-handler.js +0 -39
  396. package/dist/transactions/optimistic.d.ts +0 -24
  397. package/dist/transactions/optimistic.js +0 -45
  398. package/dist/utils/mobx-setup.d.ts +0 -42
@@ -1,14 +1,8 @@
1
1
  /**
2
- * The shared resource-type surface of the client `ModelRead`, `ModelClient`,
3
- * the `Commit*` / `Claim*` shapes, the session-mint params/resource, and the
4
- * `HttpClaimApi` derivation.
5
- *
6
- * Extracted from `Ablo.ts` so `ApiClient.ts` / `httpClient.ts` /
7
- * `sessionMint.ts` can take the wire-facing types WITHOUT importing the
8
- * factory module that runtime-imports them back (the 4-cycle cluster madge
9
- * flagged). This module is type-only — ZERO runtime imports — so importing it
10
- * can never create a cycle. `Ablo.ts` re-exports everything here, so existing
11
- * import paths keep resolving.
2
+ * The shared resource types of the client: {@link ModelRead}, {@link ModelClient},
3
+ * the commit and claim shapes, the session-mint params and resource, and the
4
+ * {@link HttpClaimApi} derivation. This module holds only types and has no runtime
5
+ * imports.
12
6
  */
13
7
  import type { StaleNotification, ReadDependency } from '../coordination/schema.js';
14
8
  import type { ModelTarget, ModelClaim } from '../coordination/schema.js';
@@ -19,16 +13,14 @@ import type { Claim, ClaimStream, ClaimWaitOptions, Duration, HeldClaim } from '
19
13
  import type { ModelUpdater, ContentionOptions } from './functionalUpdate.js';
20
14
  import type { ClaimOptions, ClaimParams, ClaimReadApi, AwaitedClaimMethod, ServerReadOptions } from './createModelProxy.js';
21
15
  /**
22
- * Operations available on each model in the sync engine.
23
- *
24
- * Naming aligns with Stripe / OpenAI / Anthropic conventions:
25
- * `retrieve({ id })` — async single-row server read
26
- * `list({ where })` — async collection server read
27
- * `get(id)` / `getAll(...)` / `getCount(...)` — local graph snapshots
16
+ * The operations available on each model in the sync engine:
17
+ * `retrieve({ id })` — an async single-row server read
18
+ * `list({ where })` an async collection server read
19
+ * `get(id)` / `getAll(...)` / `getCount(...)` synchronous local-cache reads
28
20
  * `create({ data })` / `update({ id, data })` / `delete({ id })` — writes
29
- * `claim({ id })` — durable claim handle for coordinated writes
21
+ * `claim({ id })` — a durable claim handle for coordinated writes
30
22
  */
31
- export type { LocalCountOptions, LocalReadOptions, ModelListScope, ServerReadOptions, ModelRetrieveParams, ModelCreateParams, ModelUpdateParams, ModelDeleteParams, ClaimOptions, ClaimParams, ClaimLookupParams, ClaimReorderParams, Claim, HeldClaim, ModelOperations, } from './createModelProxy.js';
23
+ export type { LocalCountOptions, LocalReadOptions, ModelListScope, ServerReadOptions, ModelRetrieveParams, ModelCreateParams, ModelUpdateParams, ModelDeleteParams, ClaimOptions, ClaimParams, ClaimLookupParams, ClaimReorderParams, Claim, ClaimHeartbeat, ClaimHeartbeatOptions, HeldClaim, ModelOperations, } from './createModelProxy.js';
32
24
  export type ModelOperationAction = 'create' | 'update' | 'delete' | 'archive' | 'unarchive';
33
25
  export type CommitWait = 'queued' | 'confirmed';
34
26
  export interface ModelRead<T = Record<string, unknown>> {
@@ -109,12 +101,12 @@ export interface CommitCreateOptions {
109
101
  readonly operations?: readonly CommitOperationInput[];
110
102
  readonly wait?: CommitWait;
111
103
  /**
112
- * Batch-level read dependencies (the STORM "did anything I looked at change?"
113
- * layer). Declare the rows (`{model,id,readAt,fields?}`) or sync groups
114
- * (`{group,readAt}`, e.g. `deck:abc`) this batch was premised on; the server
115
- * validates none moved since `readAt` and fires the entry's `onStale` over the
116
- * batch. Distinct from the write-target `readAt` this guards what you READ,
117
- * not what you write.
104
+ * Batch-level read dependencies the "did anything I looked at change?" guard.
105
+ * Declare the rows (`{ model, id, readAt, fields? }`) or sync groups
106
+ * (`{ group, readAt }`, for example `deck:abc`) this batch was premised on; the
107
+ * server checks that none moved since `readAt` and fires the entry's `onStale`
108
+ * over the batch. This is distinct from the write-target `readAt`: it guards what
109
+ * you read, not what you write.
118
110
  */
119
111
  readonly reads?: readonly ReadDependency[] | null;
120
112
  }
@@ -123,19 +115,18 @@ export interface CommitReceipt {
123
115
  readonly status: CommitWait;
124
116
  readonly lastSyncId?: number;
125
117
  /**
126
- * Stale-context notifications (notify-instead-of-abort, non-coercion). Present
127
- * only when this commit guarded a write with `onStale: 'notify' and
128
- * the premise moved concurrently — the conflicting field's current value,
129
- * handed back as data instead of a forced `AbloStaleContextError`. The engine
130
- * surfaces state; the intelligent actor (agent or human) decides how to
131
- * resolve. Also fires on `conflict:notified`.
118
+ * Stale-context notifications: present only when this commit guarded a write with
119
+ * `onStale: 'notify'` and the premise moved concurrently. Each carries the
120
+ * conflicting field's current value, handed back as data rather than raising an
121
+ * `AbloStaleContextError`, so the caller an agent or a human decides how to
122
+ * resolve it.
132
123
  */
133
124
  readonly notifications?: readonly StaleNotification[];
134
125
  /**
135
- * Ids of UPDATE/DELETE targets in this commit that matched ZERO rows (the row
136
- * doesn't exist, or is outside the caller's org). Present (non-empty) only
137
- * when a write missed. Typed resource wrappers turn this into a loud
138
- * `AbloNotFoundError`; a raw `commits.create` caller can inspect it directly.
126
+ * Ids of update or delete targets in this commit that matched no rows, because
127
+ * the row does not exist or is outside the caller's organization. Present and
128
+ * non-empty only when a write missed. The typed resource wrappers turn this into
129
+ * an `AbloNotFoundError`; a raw `commits.create` caller can inspect it directly.
139
130
  */
140
131
  readonly missingIds?: readonly string[];
141
132
  }
@@ -158,20 +149,20 @@ export interface ModelMutationOptions extends ClaimedOptions {
158
149
  readonly claim?: Claim | ClaimOptions | null;
159
150
  }
160
151
  /**
161
- * The HTTP/stateless claim surface. Normal tools usually put `claim` directly
162
- * on the write (`update({ id, data, claim })`) and let the SDK release it. Use
163
- * this namespace for multi-step handles and coordination screens.
152
+ * The stateless HTTP claim surface. Most code puts a `claim` directly on the write
153
+ * (`update({ id, data, claim })`) and lets the SDK release it; reach for this
154
+ * namespace for multi-step handles and coordination screens.
164
155
  *
165
- * Same surface as the reactive {@link ClaimApi}, but every read is a server
166
- * round-trip, so `state`/`queue`/`reorder` are **awaited** here (the WebSocket
167
- * client resolves them synchronously from its local pool which is what lets
168
- * `useAblo((ablo) => ablo.x.claim.state({ id }))` work inside a React render; a
169
- * stateless client has no pool to read, so the `Promise` is unavoidable).
156
+ * It is the same surface as the reactive claim API, but because every read is a
157
+ * server round-trip, `state`, `queue`, and `reorder` are awaited here. The
158
+ * WebSocket client resolves those synchronously from its local cache, which is what
159
+ * lets it read a claim's state inside a React render; a stateless client has no
160
+ * cache to read, so the promise is unavoidable.
170
161
  *
171
- * Mechanically DERIVED from `ClaimReadApi` via {@link AwaitedClaimMethod} so the
172
- * two transports can never drift: the ONLY difference is the uniform `Promise`
173
- * wrapper that statelessness forces. `claim({ id })` is identical (already async
174
- * on both); `state`/`queue`/`reorder`/`release` are the awaited form.
162
+ * It is derived from `ClaimReadApi` through {@link AwaitedClaimMethod} so the two
163
+ * transports cannot drift: the only difference is the promise wrapper that
164
+ * statelessness forces. `claim({ id })` is identical on both (already async);
165
+ * `state`, `queue`, `reorder`, and `release` are the awaited form.
175
166
  */
176
167
  export type HttpClaimApi<T = Record<string, unknown>> = ((params: ClaimParams<T>) => Promise<HeldClaim<T>>) & {
177
168
  [K in keyof ClaimReadApi<T>]: AwaitedClaimMethod<ClaimReadApi<T>[K]>;
@@ -183,7 +174,7 @@ export interface ModelClient<T = Record<string, unknown>> {
183
174
  * guards on the following write) and any active `.claims`. A stateless HTTP
184
175
  * client can't synthesize the watermark from a local snapshot, so the
185
176
  * envelope is load-bearing here (the WebSocket client's `retrieve` returns
186
- * `T | undefined` because it reads from the hydrated pool).
177
+ * `T | undefined` because it reads from its local cache).
187
178
  *
188
179
  * ```ts
189
180
  * const deal = await ablo.deals.retrieve({ id });
@@ -201,10 +192,10 @@ export interface ModelClient<T = Record<string, unknown>> {
201
192
  */
202
193
  list?(options?: ServerReadOptions<T>): Promise<T[]>;
203
194
  /**
204
- * Create a row and return it — the confirmed, authoritative server row (with
205
- * framework defaults like `createdAt`/`createdBy`), mirroring the WebSocket
206
- * client's `create`. A re-create of an existing caller-supplied id is
207
- * idempotent and returns the EXISTING row, not the input.
195
+ * Creates a row and returns the confirmed server row, including framework
196
+ * defaults such as `createdAt` and `createdBy`. Matches the stateful client's
197
+ * `create`. Passing an id that already exists is idempotent: the existing row is
198
+ * returned, not the input.
208
199
  */
209
200
  create(params: ModelMutationOptions & {
210
201
  readonly data: Record<string, unknown>;
@@ -238,27 +229,26 @@ export interface ModelClient<T = Record<string, unknown>> {
238
229
  }
239
230
  /** A single data operation a scoped **agent** session may perform on a model. */
240
231
  export type SessionOperation = 'read' | 'create' | 'update' | 'delete';
241
- /** Mint params for an **end-user** session — full data authority within the
242
- * org (the Stripe `ephemeralKeys.create` / Supabase session shape). Mints an
243
- * `ek_` token. `user.id` is your end user's external IdP id (becomes the
244
- * session's `participantId`); Ablo does not model your users, so it's an
245
- * honest string at the trust boundary. */
232
+ /** Parameters for minting an end-user session — full data authority within the
233
+ * organization. Mints an `ek_` token. `user.id` is your end user's id from your
234
+ * own identity provider and becomes the session's `participantId`; Ablo does not
235
+ * model your users, so it is treated as an opaque string at the trust boundary. */
246
236
  export interface CreateUserSessionParams {
247
237
  /** Your end user. `id` becomes the token's `participantId`. */
248
238
  user: {
249
239
  id: string;
250
240
  };
251
- /** Mint the session into THIS organization instead of the key's own org the
252
- * Stripe Connect `Stripe-Account` pattern, for a platform serving many tenants
253
- * from one backend. Requires the `sk_` to carry the `ephemeral:mint-any-org`
254
- * scope; omit for the normal single-tenant case. */
241
+ /** Mint the session into this organization instead of the key's own — for a
242
+ * platform that serves many tenants from one backend. Requires the `sk_` key to
243
+ * carry the `ephemeral:mint-any-org` scope; omit it for the normal
244
+ * single-tenant case. */
255
245
  organizationId?: string;
256
246
  /** Sync groups this session may subscribe to — typed (`'default'` or
257
247
  * `<namespace>:<id>`; build with `syncGroup(kind, id)` from
258
248
  * `@abloatai/ablo/schema`). Omit for the server default:
259
249
  * `[org:<your org>, user:<user.id>]`. */
260
250
  syncGroups?: readonly SyncGroupInput[];
261
- /** Token lifetime in seconds. Defaults to 900 (15m, the Stripe ephemeral default). */
251
+ /** Token lifetime in seconds. Defaults to 900 (15 minutes). */
262
252
  ttlSeconds?: number;
263
253
  /** Opaque identity blob echoed back to the client as `ablo.user`. */
264
254
  userMeta?: Record<string, unknown>;
@@ -281,7 +271,7 @@ export interface CreateAgentSessionParams<S extends SchemaRecord> {
281
271
  * `@abloatai/ablo/schema`). Omit for the server default: the org
282
272
  * anchor (`org:<your org>`) + the agent's own anchor. */
283
273
  syncGroups?: readonly SyncGroupInput[];
284
- /** Token lifetime in seconds. Defaults to 900 (15m, the Stripe ephemeral default). */
274
+ /** Token lifetime in seconds. Defaults to 900 (15 minutes). */
285
275
  ttlSeconds?: number;
286
276
  /** Opaque identity blob echoed back to the client as `ablo.agent`. */
287
277
  userMeta?: Record<string, unknown>;
@@ -296,15 +286,15 @@ export type CreateSessionParams<S extends SchemaRecord> = CreateUserSessionParam
296
286
  * {@link CreateSessionParams} it resolves to a connected, scoped {@link Ablo}
297
287
  * client rather than a raw token. */
298
288
  export interface CreateAgentClientParams<S extends SchemaRecord> {
299
- /** Wire participant identity (`agent:<id>`) what claim exclusion and the
300
- * FIFO queue gate on. OMIT to get a fresh `crypto.randomUUID()`: a distinct,
301
- * independent participant (the default, and what you want for concurrent
302
- * agents). Pass a STABLE string only when one logical agent must re-attach
303
- * to its own held claims across reconnects/restarts. */
289
+ /** The wire participant identity (`agent:<id>`) that claim exclusion and the
290
+ * FIFO queue gate on. Omit it to get a fresh random id — a distinct, independent
291
+ * participant, which is the default and what you want for concurrent agents.
292
+ * Pass a stable string only when one logical agent must re-attach to its own
293
+ * held claims across reconnects or restarts. */
304
294
  id?: string;
305
- /** Human-readable label for logs / attribution (carried in `userMeta.name`).
306
- * INDEPENDENT of `id`: two agents that share a `name` still receive distinct
307
- * ids and coordinate as SEPARATE participants — `name` never derives or
295
+ /** A human-readable label for logs and attribution (carried in `userMeta.name`).
296
+ * It is independent of `id`: two agents that share a `name` still receive
297
+ * distinct ids and coordinate as separate participants — `name` never derives or
308
298
  * collapses identity. */
309
299
  name?: string;
310
300
  /** Per-model operation allowlist, typed against the schema's model names. */
@@ -313,16 +303,15 @@ export interface CreateAgentClientParams<S extends SchemaRecord> {
313
303
  * `<namespace>:<id>`). Omit for the server default (org anchor + the
314
304
  * agent's own anchor). */
315
305
  syncGroups?: readonly SyncGroupInput[];
316
- /** Token lifetime in seconds. Defaults to 900 (15m); the returned client
317
- * auto-re-mints before expiry, so a long-running agent never handles
318
- * rotation itself. */
306
+ /** Token lifetime in seconds. Defaults to 900 (15 minutes); the returned client
307
+ * re-mints before expiry, so a long-running agent never handles rotation
308
+ * itself. */
319
309
  ttlSeconds?: number;
320
310
  /** Extra opaque identity blob echoed on the session scope. Merged with
321
311
  * `name` (the `name` param wins if you also set `userMeta.name`). */
322
312
  userMeta?: Record<string, unknown>;
323
313
  }
324
- /** A minted session token the Stripe ephemeral-key / Supabase session
325
- * resource. `token` is the secret the holder presents as its bearer. */
314
+ /** A minted session. `token` is the secret the holder presents as its bearer. */
326
315
  export interface AbloSession {
327
316
  object: 'session';
328
317
  /** Stable id of the minted credential (for revocation). */
@@ -1,13 +1,7 @@
1
1
  /**
2
- * The shared resource-type surface of the client `ModelRead`, `ModelClient`,
3
- * the `Commit*` / `Claim*` shapes, the session-mint params/resource, and the
4
- * `HttpClaimApi` derivation.
5
- *
6
- * Extracted from `Ablo.ts` so `ApiClient.ts` / `httpClient.ts` /
7
- * `sessionMint.ts` can take the wire-facing types WITHOUT importing the
8
- * factory module that runtime-imports them back (the 4-cycle cluster madge
9
- * flagged). This module is type-only — ZERO runtime imports — so importing it
10
- * can never create a cycle. `Ablo.ts` re-exports everything here, so existing
11
- * import paths keep resolving.
2
+ * The shared resource types of the client: {@link ModelRead}, {@link ModelClient},
3
+ * the commit and claim shapes, the session-mint params and resource, and the
4
+ * {@link HttpClaimApi} derivation. This module holds only types and has no runtime
5
+ * imports.
12
6
  */
13
7
  export {};
@@ -1,56 +1,44 @@
1
1
  /**
2
- * Schema-derived engine config `computeFKDepthPriority` (the Tarjan-SCC
3
- * create-order derivation) and `deriveConfigFromSchema` (the `SyncEngineConfig`
4
- * the factory seeds the DI context with).
5
- *
6
- * Extracted from `Ablo.ts` as a pure leaf: both functions are deterministic
7
- * schema value derivations with no engine state.
2
+ * Derives engine configuration from a schema. This module holds two pure
3
+ * functions: {@link computeFKDepthPriority} works out a safe row-insertion
4
+ * order from the schema's foreign-key relations, and
5
+ * {@link deriveConfigFromSchema} packages that ordering, together with a few
6
+ * defaults, into the {@link SyncEngineConfig} a client uses at startup. Both
7
+ * are deterministic transforms of the schema and hold no engine state.
8
8
  */
9
9
  import type { Schema } from '../schema/schema.js';
10
10
  import type { SyncEngineConfig } from '../interfaces/index.js';
11
11
  /**
12
- * Compute a create-priority map from schema `belongsTo` relations using
13
- * Tarjan's strongly-connected-components algorithm.
14
- *
15
- * The FK graph has an edge `child → parent` for every `belongsTo`. Tarjan
16
- * runs a single linear DFS that simultaneously (a) detects cycles by
17
- * grouping mutually-reachable nodes into SCCs and (b) emits those SCCs
18
- * in reverse topological order of the condensation graph. In this edge
19
- * convention a "sink" SCC has no outgoing edges — i.e. no parents — so
20
- * it is an *FK root* (`organizations`, `themes`, etc.). Tarjan emits
21
- * roots first and leaves last, exactly the order in which rows must be
22
- * inserted to satisfy FK constraints.
23
- *
24
- * Priorities are assigned by emit order: SCC #0 → 10, SCC #1 → 20, …
25
- * Members of the same SCC share a priority, so insertion order wins the
26
- * tiebreak inside a cycle (this matters for cyclic schemas like
27
- * `slideDecks ↔ layouts`, where one direction is the user's chosen
28
- * "soft" edge — only the consumer's mutator sequence knows which one).
12
+ * Computes a create-priority map that gives the engine a safe order for
13
+ * inserting rows, so a child row is never written before the parent its
14
+ * foreign key references.
29
15
  *
30
- * This algorithm is iteration-order-independent: starting the DFS from
31
- * any node yields the same SCC partitioning, and SCCs always come out
32
- * in valid topological order. The previous DFS-with-memoization
33
- * heuristic broke under cycles by treating the back-edge as depth 0,
34
- * which made priorities depend on which node the walk happened to
35
- * enter the cycle at.
16
+ * Every `belongsTo` relation is an edge from a child model to its parent. This
17
+ * function runs Tarjan's strongly-connected-components algorithm over that
18
+ * graph, which does two things at once: it groups any models that reference
19
+ * each other in a cycle into a single component, and it produces those
20
+ * components in an order where parents come before children. Each model then
21
+ * gets a numeric priority from that order, where a lower number means "insert
22
+ * earlier". Top-level models with no parent — an organization or a theme, say —
23
+ * come first, and the deepest descendants come last.
36
24
  *
37
- * Schema authors can mark one side of a cycle with
38
- * `belongsTo(target, fk, { defer: true })`. Those edges are excluded
39
- * from the dependency graph entirely, which deterministically breaks
40
- * the cycle and turns the SCC into a chain the marked child gets a
41
- * strictly higher priority than its parent instead of being tied with
42
- * it. Pair with a Postgres `DEFERRABLE INITIALLY DEFERRED` constraint
43
- * if you want the database side of the cycle to also relax. See
44
- * {@link BelongsToOptions.defer}.
25
+ * Models in the same cycle share a priority, so within a cycle the order rows
26
+ * were queued in breaks the tie. To break a cycle deterministically instead,
27
+ * mark one side of it with `belongsTo(target, fk, { defer: true })`. A deferred
28
+ * edge is left out of the graph, which turns the cycle into a chain and gives
29
+ * the deferred child a strictly higher priority than its parent. Pair it with a
30
+ * Postgres `DEFERRABLE INITIALLY DEFERRED` constraint if you also want the
31
+ * database to relax its check. See {@link BelongsToOptions.defer}.
45
32
  *
46
- * The returned map is keyed by {@link ModelDef.typename} (falling back
47
- * to the schema key), because that is what `Model.getModelName()`
48
- * returns at transaction time keying by schema key would silently
49
- * miss the lookup and every model would fall through to
50
- * `defaultCreatePriority`.
33
+ * The returned map is keyed by each model's wire type name
34
+ * ({@link ModelDef.typename}, falling back to the schema key), because that is
35
+ * the name the engine looks up at commit time. Keying by the schema key would
36
+ * miss that lookup, and every model would fall back to the default priority.
51
37
  *
38
+ * The result does not depend on which model the walk starts from, and the
39
+ * algorithm runs in time linear in the number of models plus relations.
52
40
  * Reference: Tarjan, R. (1972), "Depth-first search and linear graph
53
- * algorithms." Linear in V + E.
41
+ * algorithms."
54
42
  */
55
43
  export declare function computeFKDepthPriority(schema: Schema): ReadonlyMap<string, number>;
56
44
  export declare function deriveConfigFromSchema(schema: Schema): SyncEngineConfig;
@@ -1,56 +1,44 @@
1
1
  /**
2
- * Schema-derived engine config `computeFKDepthPriority` (the Tarjan-SCC
3
- * create-order derivation) and `deriveConfigFromSchema` (the `SyncEngineConfig`
4
- * the factory seeds the DI context with).
5
- *
6
- * Extracted from `Ablo.ts` as a pure leaf: both functions are deterministic
7
- * schema value derivations with no engine state.
2
+ * Derives engine configuration from a schema. This module holds two pure
3
+ * functions: {@link computeFKDepthPriority} works out a safe row-insertion
4
+ * order from the schema's foreign-key relations, and
5
+ * {@link deriveConfigFromSchema} packages that ordering, together with a few
6
+ * defaults, into the {@link SyncEngineConfig} a client uses at startup. Both
7
+ * are deterministic transforms of the schema and hold no engine state.
8
8
  */
9
9
  import { schemaHash } from '../schema/serialize.js';
10
10
  // ── Config derivation from schema ─────────────────────────────────────────
11
11
  /**
12
- * Compute a create-priority map from schema `belongsTo` relations using
13
- * Tarjan's strongly-connected-components algorithm.
14
- *
15
- * The FK graph has an edge `child → parent` for every `belongsTo`. Tarjan
16
- * runs a single linear DFS that simultaneously (a) detects cycles by
17
- * grouping mutually-reachable nodes into SCCs and (b) emits those SCCs
18
- * in reverse topological order of the condensation graph. In this edge
19
- * convention a "sink" SCC has no outgoing edges — i.e. no parents — so
20
- * it is an *FK root* (`organizations`, `themes`, etc.). Tarjan emits
21
- * roots first and leaves last, exactly the order in which rows must be
22
- * inserted to satisfy FK constraints.
23
- *
24
- * Priorities are assigned by emit order: SCC #0 → 10, SCC #1 → 20, …
25
- * Members of the same SCC share a priority, so insertion order wins the
26
- * tiebreak inside a cycle (this matters for cyclic schemas like
27
- * `slideDecks ↔ layouts`, where one direction is the user's chosen
28
- * "soft" edge — only the consumer's mutator sequence knows which one).
12
+ * Computes a create-priority map that gives the engine a safe order for
13
+ * inserting rows, so a child row is never written before the parent its
14
+ * foreign key references.
29
15
  *
30
- * This algorithm is iteration-order-independent: starting the DFS from
31
- * any node yields the same SCC partitioning, and SCCs always come out
32
- * in valid topological order. The previous DFS-with-memoization
33
- * heuristic broke under cycles by treating the back-edge as depth 0,
34
- * which made priorities depend on which node the walk happened to
35
- * enter the cycle at.
16
+ * Every `belongsTo` relation is an edge from a child model to its parent. This
17
+ * function runs Tarjan's strongly-connected-components algorithm over that
18
+ * graph, which does two things at once: it groups any models that reference
19
+ * each other in a cycle into a single component, and it produces those
20
+ * components in an order where parents come before children. Each model then
21
+ * gets a numeric priority from that order, where a lower number means "insert
22
+ * earlier". Top-level models with no parent — an organization or a theme, say —
23
+ * come first, and the deepest descendants come last.
36
24
  *
37
- * Schema authors can mark one side of a cycle with
38
- * `belongsTo(target, fk, { defer: true })`. Those edges are excluded
39
- * from the dependency graph entirely, which deterministically breaks
40
- * the cycle and turns the SCC into a chain the marked child gets a
41
- * strictly higher priority than its parent instead of being tied with
42
- * it. Pair with a Postgres `DEFERRABLE INITIALLY DEFERRED` constraint
43
- * if you want the database side of the cycle to also relax. See
44
- * {@link BelongsToOptions.defer}.
25
+ * Models in the same cycle share a priority, so within a cycle the order rows
26
+ * were queued in breaks the tie. To break a cycle deterministically instead,
27
+ * mark one side of it with `belongsTo(target, fk, { defer: true })`. A deferred
28
+ * edge is left out of the graph, which turns the cycle into a chain and gives
29
+ * the deferred child a strictly higher priority than its parent. Pair it with a
30
+ * Postgres `DEFERRABLE INITIALLY DEFERRED` constraint if you also want the
31
+ * database to relax its check. See {@link BelongsToOptions.defer}.
45
32
  *
46
- * The returned map is keyed by {@link ModelDef.typename} (falling back
47
- * to the schema key), because that is what `Model.getModelName()`
48
- * returns at transaction time keying by schema key would silently
49
- * miss the lookup and every model would fall through to
50
- * `defaultCreatePriority`.
33
+ * The returned map is keyed by each model's wire type name
34
+ * ({@link ModelDef.typename}, falling back to the schema key), because that is
35
+ * the name the engine looks up at commit time. Keying by the schema key would
36
+ * miss that lookup, and every model would fall back to the default priority.
51
37
  *
38
+ * The result does not depend on which model the walk starts from, and the
39
+ * algorithm runs in time linear in the number of models plus relations.
52
40
  * Reference: Tarjan, R. (1972), "Depth-first search and linear graph
53
- * algorithms." Linear in V + E.
41
+ * algorithms."
54
42
  */
55
43
  export function computeFKDepthPriority(schema) {
56
44
  // schemaKey → typename (wire name used at transaction time)
@@ -170,19 +158,19 @@ export function computeFKDepthPriority(schema) {
170
158
  return out;
171
159
  }
172
160
  export function deriveConfigFromSchema(schema) {
173
- // Commit payload projection is done directly inside `TransactionQueue`
174
- // see `projectCommitPayload` there. Each model's field metadata
175
- // rides on `ModelRegistry` (populated by `registerModelsFromSchema`),
176
- // so there's no config-layer shim: the queue asks the registry for
177
- // the declared fields and serializes accordingly.
161
+ // Field-level serialization for commits happens in the transaction queue,
162
+ // which reads each model's declared fields from the model registry at commit
163
+ // time. There is no per-field metadata to configure here, so these maps stay
164
+ // empty.
178
165
  return {
179
166
  modelCreatePriority: computeFKDepthPriority(schema),
180
167
  defaultCreatePriority: 40,
181
168
  defaultNonCreatePriority: 50,
182
169
  essentialFields: {},
183
170
  classNameFallbackMap: {},
184
- // Hash this client's schema once so bootstrap can detect drift against the
185
- // server's active hash (same `schemaHash` the CLI push + server compute).
171
+ // Hash this schema once, so startup can detect when it has drifted from the
172
+ // schema the server currently has active. The server and the `ablo push`
173
+ // command compute this same hash.
186
174
  expectedSchemaHash: schemaHash(schema),
187
175
  };
188
176
  }
@@ -1,25 +1,29 @@
1
1
  import type { SchemaRecord } from '../schema/schema.js';
2
2
  import type { AbloSession, CreateSessionParams } from './resourceTypes.js';
3
- /** The resolved control-plane context a mint needs. `fetch` is optional — the
4
- * auth helpers fall back to the runtime global when omitted. */
3
+ /**
4
+ * The resolved control-plane details a mint needs: a secret key, a base URL,
5
+ * and an optional `fetch`. When `fetch` is omitted, the auth helpers fall back
6
+ * to the runtime's global `fetch`.
7
+ */
5
8
  export interface MintSessionContext {
6
9
  readonly apiKey: string;
7
10
  readonly baseUrl: string;
8
11
  readonly fetch?: typeof fetch;
9
12
  /**
10
- * Schema-key wire typename map, supplied ONLY by the schema client
11
- * (`Ablo`). A capability is scoped by the lowercased TYPENAME the Hub
12
- * checks, but `can` is keyed by schema key — so `can: { documents: ['update'] }`
13
- * on a model whose `typename` is overridden to `Document` must mint
14
- * `document.update`, not `documents.update` (else the Hub denies it with
15
- * `capability_scope_denied`). The schemaless `ApiClient` omits this map:
16
- * there the `can` key already IS the wire token, so no translation applies.
13
+ * Maps each schema key to its wire type name. Only the schema-aware client
14
+ * supplies this. A capability is scoped by the lowercased type name the
15
+ * server checks, but `can` is keyed by schema key — so
16
+ * `can: { documents: ['update'] }` on a model whose type name is overridden
17
+ * to `Document` must mint `document.update`, not `documents.update`, or the
18
+ * server denies the write with `capability_scope_denied`. The schemaless
19
+ * client omits this map, because there the `can` key is already the wire
20
+ * token and needs no translation.
17
21
  */
18
22
  readonly modelTypenames?: Readonly<Record<string, string>>;
19
23
  }
20
24
  /**
21
- * Mint a session token from an already-resolved `sk_` credential + base URL.
22
- * Discriminates the `{ user }` / `{ agent }` union onto the server's two mint
23
- * doors and reshapes each flat response into the `AbloSession` resource.
25
+ * Mints a session token from an already-resolved secret key and base URL.
26
+ * Routes the `{ user }` or `{ agent }` request to the matching mint endpoint
27
+ * and reshapes the response into an {@link AbloSession}.
24
28
  */
25
29
  export declare function mintSession<S extends SchemaRecord>(params: CreateSessionParams<S>, ctx: MintSessionContext): Promise<AbloSession>;
@@ -1,37 +1,32 @@
1
1
  /**
2
- * `mintSession` the ONE implementation behind `sessions.create`, shared by the
3
- * stateful `Ablo` client and the stateless protocol / HTTP client so the two can
4
- * never drift on HOW a token is minted.
2
+ * Mints a session token. This is the single implementation behind
3
+ * `sessions.create`, shared by the schema-aware client and the schemaless HTTP
4
+ * client so the two never disagree on how a token is produced.
5
5
  *
6
- * Minting is a pure control-plane HTTP call (no socket, no synced pool): a backend
7
- * holding a secret `sk_` exchanges it for a short-lived scoped token — `ek_` for an
8
- * `{ user }` session (full end-user authority) or `rk_` for an `{ agent }` session
9
- * (scoped to exactly the operations named in `can`). The two arms map to the
10
- * server's two mint doors:
6
+ * Minting is a plain control-plane HTTP call no socket, no synced data. A
7
+ * backend holding a secret key (`sk_`) exchanges it for a short-lived, scoped
8
+ * token whose kind depends on the session requested:
11
9
  *
12
- * `{ user }` → POST /auth/ephemeral-keys `ek_`. The user-session door;
13
- * routing this arm through /auth/capability is structurally
14
- * impossible that route rejects participantKind 'user' outright
15
- * (`invalid_participant_kind`, the 2026-06-11 Pulse cascade where
16
- * the SDK's own blessed pattern 403'd and integrators fell back to
17
- * minting humans as agents).
18
- * `{ agent }` → POST /auth/capability → scoped `rk_`. `can: { tasks: ['update'] }`
19
- * serializes to the wire allowlist (`tasks.update`); the Hub matches
20
- * it against every registered alias of the model.
10
+ * `{ user }` → POST /auth/ephemeral-keys, returning an `ek_` key that carries
11
+ * full end-user authority. This is the only route that mints a
12
+ * user session; the capability route rejects a `user`
13
+ * participant with `invalid_participant_kind`.
14
+ * `{ agent }` POST /auth/capability, returning an `rk_` key scoped to exactly
15
+ * the operations named in `can`. For example
16
+ * `can: { tasks: ['update'] }` becomes the wire allowlist entry
17
+ * `tasks.update`, which the server matches against the model's
18
+ * registered names.
21
19
  *
22
- * The caller supplies the resolved control-plane credential + base URL in `ctx`;
23
- * WHICH key to use (the original `sk_`, never a derived `rk_` the startup exchange
24
- * may have installed) is the caller's concern see the two call sites.
25
- *
26
- * Type-only imports of `CreateSessionParams` / `AbloSession` keep this module a
27
- * leaf (no runtime cycle back to `Ablo.ts`): at runtime it depends on `auth` +
28
- * `schema` only.
20
+ * The caller supplies the already-resolved secret key and base URL in
21
+ * {@link MintSessionContext}. Choosing which key to pass the original secret
22
+ * key, not a derived key that an earlier exchange may have produced — is the
23
+ * caller's responsibility.
29
24
  */
30
25
  import { exchangeApiKey, mintUserSessionKey } from '../auth/index.js';
31
26
  /**
32
- * Mint a session token from an already-resolved `sk_` credential + base URL.
33
- * Discriminates the `{ user }` / `{ agent }` union onto the server's two mint
34
- * doors and reshapes each flat response into the `AbloSession` resource.
27
+ * Mints a session token from an already-resolved secret key and base URL.
28
+ * Routes the `{ user }` or `{ agent }` request to the matching mint endpoint
29
+ * and reshapes the response into an {@link AbloSession}.
35
30
  */
36
31
  export async function mintSession(params, ctx) {
37
32
  const { apiKey, baseUrl } = ctx;
@@ -64,10 +59,10 @@ export async function mintSession(params, ctx) {
64
59
  };
65
60
  }
66
61
  const operations = Object.entries(params.can).flatMap(([model, ops]) => {
67
- // Translate the schema key the developer used in `can` to the wire
68
- // typename the Hub gates on — see `modelTypenames` above. Falls back to
69
- // the key when no map is supplied (schemaless client) or the key isn't
70
- // in it, preserving the prior behaviour exactly for those callers.
62
+ // Translate the schema key the developer used in `can` into the wire type
63
+ // name the server checks — see `modelTypenames` above. Falls back to the
64
+ // key itself when no map is supplied (the schemaless client) or the key is
65
+ // absent from it.
71
66
  const ns = ctx.modelTypenames?.[model] ?? model;
72
67
  return (ops ?? []).map((op) => `${ns.toLowerCase()}.${op}`);
73
68
  });