@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,8 +1,7 @@
1
1
  /**
2
- * Schema Model Definition
3
- *
4
- * A model is a Zod object schema + optional relations.
5
- * Types are inferred directly from Zod — no custom type system.
2
+ * Defines a model — one table's worth of fields plus its relations and options. A
3
+ * model is a Zod object schema paired with optional relation definitions; the row
4
+ * type is inferred directly from Zod, with no separate type system to keep in sync.
6
5
  *
7
6
  * Usage:
8
7
  * import { z } from 'zod';
@@ -71,18 +70,14 @@ export interface ModelOptions {
71
70
  /** Order to sort by during bootstrap (e.g., 'created_at DESC'). */
72
71
  bootstrapOrderBy?: string;
73
72
  /**
74
- * The GraphQL/wire `__typename` value for this model.
75
- *
76
- * Used by the generic loader + hydration pipeline to stamp `__typename`
77
- * on raw rows before `pool.createFromData(...)`, and to look up the
78
- * matching class in the model registry. Defaults to the schema key
79
- * (e.g., `tasks` → `'tasks'`). Provide explicitly when the wire shape
80
- * uses a different casing (e.g., schema key `slideLayer` → typename
81
- * `'SlideLayer'`).
73
+ * The wire type name for this model — the value that identifies its rows on the
74
+ * wire (the `__typename`). The loader stamps it onto incoming rows and uses it to
75
+ * find the matching model class. It defaults to the schema key (`tasks`
76
+ * `'tasks'`); set it explicitly when the wire shape uses different casing, such as
77
+ * schema key `slideLayer` mapping to typename `'SlideLayer'`.
82
78
  *
83
- * This is the single source of truth for "what identifies this model
84
- * on the wire." Every other layer (IDB store name, query.returns
85
- * references, delta routing) resolves through this value.
79
+ * This is the one value that identifies the model on the wire; the client-side
80
+ * store name, query result references, and delta routing all resolve through it.
86
81
  */
87
82
  typename?: string;
88
83
  /**
@@ -90,56 +85,56 @@ export interface ModelOptions {
90
85
  */
91
86
  persist?: PersistOptions;
92
87
  /**
93
- * The actual database table name. Defaults to snake_case of the model
94
- * name if not provided. Used by the bootstrap query builder to know
95
- * which table to SELECT from without this, the server has to guess
96
- * via a naming convention that may not match the Prisma @@map directive.
88
+ * The database table this model maps to. Defaults to the snake_case form of the
89
+ * model name. Set it when the real table name does not follow that convention, so
90
+ * queries read from the right table instead of a guessed name.
97
91
  */
98
92
  tableName?: string;
99
93
  /**
100
- * **Axis 1row-access policy (tenant isolation / RLS).** Decides who may
101
- * *read* a row at all. Named after Postgres/Supabase, where a `policy` is the
102
- * rule that scopes which rows a tenant sees. A discriminated union on `by` —
103
- * one option replacing the old `orgScoped`/`scopedVia`/`orgColumn` trio:
94
+ * Row-access policydecides which rows a tenant may read at all. A discriminated
95
+ * union on `by`:
104
96
  *
105
- * - `{ by: 'column' }` — row-local tenancy column (the DEFAULT when omitted).
106
- * `column` overrides the name (default `organization_id`).
107
- * - `{ by: 'parent', fk, parent }` — inherit tenancy through a foreign key
108
- * when THIS table has no tenancy column of its own (e.g. `slide_layers` →
109
- * slide deck org). Emits, in place of `organization_id = $1`:
97
+ * - `{ by: 'column' }` — the row carries its own tenancy column (the default when
98
+ * omitted). `column` overrides the column name, which defaults to
99
+ * `organization_id`.
100
+ * - `{ by: 'parent', fk, parent }` — inherit tenancy through a foreign key when the
101
+ * table has no tenancy column of its own (for example `slide_layers` slide →
102
+ * deck → organization). In place of `organization_id = $1` the read emits
110
103
  * `WHERE <table>.<fk> IN (SELECT <parentKey> FROM <parent> WHERE
111
- * <parentTenantColumn> = $1)`. Use this for any `load: 'instant'` child
112
- * table that would otherwise leak cross-tenant on bootstrap.
113
- * - `{ by: 'none' }` — genuinely global / reference data (the `organizations`
114
- * table itself, global lookups). Makes the whole table readable
115
- * cross-tenant only correct for tenant-less tables. Because it's an
116
- * explicit, named branch (not a falsy flag) it can't be reached by accident.
104
+ * <parentTenantColumn> = $1)`. Use it for any `load: 'instant'` child table that
105
+ * would otherwise expose other tenants' rows at bootstrap.
106
+ * - `{ by: 'none' }` — genuinely global or reference data, such as a lookup table.
107
+ * This makes the whole table readable across tenants, so it is only correct for
108
+ * tables that have no tenant at all. It is a named branch rather than a falsy
109
+ * flag, so it cannot be selected by accident.
117
110
  *
118
- * Normalized into the canonical {@link Tenancy} by `resolvePolicy` at build.
111
+ * {@link resolvePolicy} normalizes this into the canonical {@link Tenancy} when the
112
+ * model is built.
119
113
  */
120
114
  policy?: PolicyInput;
121
115
  /**
122
- * Which database plane this model's rows live in. `tenant` (default) =
123
- * the tenant data plane, emitted into a customer's BYO/dedicated DB by
124
- * provisioning. `control` = Ablo's control plane (sync log, attribution,
125
- * audit) — never emitted into a customer DB. See `./plane.ts`.
116
+ * Which database a model's rows live in. `tenant` (the default) is tenant data
117
+ * that provisioning places in the customer's own database; `control` is Ablo's own
118
+ * data the sync log, attribution, and audit records — which never leaves Ablo's
119
+ * database. See {@link ModelResidency}.
126
120
  */
127
121
  plane?: ModelResidency;
128
122
  /**
129
- * **Axis 2 — sync-group routing.** Decides which delta *channels* a row fans
130
- * into. Orthogonal to {@link policy} (read access). One namespaced object
131
- * replacing the old flat `scope`/`grants`/`entityRoles`:
123
+ * Sync-group routing decides which delta channels a row fans out to. This is
124
+ * independent of {@link policy}, which governs read access. One object with three
125
+ * optional parts:
132
126
  *
133
- * - `root` — mark this model a scope root; its records form the group
134
- * `<kind>:<id>` (kind defaults from the lowercased typename, e.g. `Deck` →
135
- * `deck:<id>`; pass a string to override, `root: 'matter'`). Child models
136
- * inherit a root's group via their `belongsTo` relations. Was `scope` —
137
- * renamed so it no longer collides with the old `scopedVia` tenancy sugar.
138
- * - `grants` a membership edge granting an identity access to a scope root.
139
- * Both values name `belongsTo` relations on this model (`subject` identity,
140
- * `scope` → scope root). Only needed for sub-org sharing.
141
- * - `roles` — explicit non-relational record→group roles (the inbox-fan-out
142
- * escape hatch, keyed on a plain field). Was `entityRoles`. One or many.
127
+ * - `root` — marks this model a scope root, so each of its records forms the group
128
+ * `<kind>:<id>`. The kind defaults to the lowercased typename (`Deck` →
129
+ * `deck:<id>`); pass a string to override it (`root: 'matter'`). Child models
130
+ * inherit a root's group through their `belongsTo` relations.
131
+ * - `grants` a membership edge that grants an identity access to a scope root.
132
+ * Both values name `belongsTo` relations on this model (`subject` names the
133
+ * identity, `scope` names the scope root). Use it only for sharing within an
134
+ * organization.
135
+ * - `roles` — explicit record-to-group roles keyed on a plain field, for routing
136
+ * that does not follow a relation, such as fanning a message into a recipient's
137
+ * inbox. Accepts one role or many.
143
138
  *
144
139
  * ```ts
145
140
  * // dataroomMember: { userId, dataroomId }
@@ -150,20 +145,20 @@ export interface ModelOptions {
150
145
  */
151
146
  groups?: GroupsInput;
152
147
  /**
153
- * **Axis 3 — write-conflict disposition, per committer kind.** Decides what
154
- * happens when a commit collides with a foreign claim or a stale snapshot on
155
- * this model orthogonal to {@link policy} (read access) and {@link groups}
156
- * (delta routing). A plain map keyed by the COMMITTER's participant kind
157
- * (`user` / `agent` / `system`), with the `onStale` vocabulary as values:
148
+ * Write-conflict disposition, set per committer kind decides what happens when a
149
+ * commit collides with another participant's claim or with a stale snapshot of this
150
+ * model. This is independent of {@link policy} (read access) and {@link groups}
151
+ * (delta routing). It is a map keyed by the committer's kind (`user`, `agent`, or
152
+ * `system`), with these outcomes as values:
158
153
  *
159
154
  * - `'overwrite'` — the write wins; that committer is never blocked.
160
155
  * - `'reject'` — the write is refused; that committer yields.
161
- * - `'notify'` — hold the write and hand back the current value so the
162
- * committer re-reads and re-applies (stale writes only).
156
+ * - `'notify'` — hold the write and hand the current value back so the committer
157
+ * re-reads and re-applies (for stale writes only).
163
158
  *
164
- * An omitted kind falls through to the engine default (reject; honor
165
- * `onStale: 'notify'`). It is pure data (serializes through the schema
166
- * registry to the server) and the generic engine interprets it so e.g.
159
+ * A kind you omit falls back to the engine default: reject, while honoring
160
+ * `onStale: 'notify'`. The value is plain data that travels with the schema to the
161
+ * server, where the engine interprets it. For example:
167
162
  *
168
163
  * ```ts
169
164
  * // "a human's edit always wins (never blocked); an agent yields"
@@ -172,41 +167,33 @@ export interface ModelOptions {
172
167
  */
173
168
  conflict?: ConflictAxis;
174
169
  /**
175
- * Whether clients may issue CREATE/UPDATE/DELETE mutations for this
176
- * model via the `commit` wire protocol. Default: **true** declaring a
177
- * model in the schema IS the opt-in; if you put an entity in your synced
178
- * schema, you almost always want to write it (product decision
179
- * 2026-06-10, reversing the earlier default-deny that made every fresh
180
- * quickstart's first write die with `server_execute_unknown_model`).
181
- *
182
- * Opt OUT for server-managed projections (stats, digests, audit views):
183
- * `mutable: false`, or the `readOnly.*` sugar which sets it for you.
184
- * That keeps the 2026-04-20 `AgentJob`-class protection available where
185
- * it matters, as a deliberate marking instead of a silent default.
170
+ * Whether clients may create, update, and delete this model's rows through the
171
+ * commit protocol. Defaults to true: declaring a model in your schema is the
172
+ * opt-in, since a synced entity is almost always one you want to write. A model
173
+ * left out of the mutation allowlist rejects writes with
174
+ * `server_execute_unknown_model`.
186
175
  *
187
- * The server's `buildModelMap` (src/server/commit.ts) derives
188
- * the mutation allowlist from this flag no parallel hardcoded list.
176
+ * Set `mutable: false` (or use the `readOnly.*` shorthand, which sets it for you)
177
+ * for server-managed projections such as stats, digests, or audit views, so those
178
+ * cannot be written from a client. The server derives its mutation allowlist from
179
+ * this flag; there is no separate hardcoded list to keep in step.
189
180
  */
190
181
  mutable?: boolean;
191
182
  /**
192
- * Defer MobX observability setup until the model is first accessed
193
- * by an observer component. Default: false (observe immediately).
183
+ * Defer setting up MobX observability until the model is first accessed by an
184
+ * observing component. Defaults to false, which observes immediately.
194
185
  *
195
- * Use for models that are created in bulk (e.g., during import or
196
- * batch bootstrap) where most instances are never rendered. The
197
- * model's constructor skips makeObservable(); instead, consuming
198
- * code calls model.makeObservable() when the model enters the
199
- * render tree. This matches Ablo's SlideLayer.ensureObservable()
200
- * pattern and avoids ~10ms of MobX setup overhead per instance
201
- * when creating hundreds of models that never get observed.
186
+ * Use it for models created in bulk during an import or a batch bootstrap —
187
+ * where most instances are never rendered. The constructor skips the observability
188
+ * setup, and calling `model.makeObservable()` performs it later when the model
189
+ * enters the render tree. This avoids roughly 10ms of setup per instance when
190
+ * creating hundreds of models that are never observed.
202
191
  */
203
192
  lazyObservable?: boolean;
204
193
  /**
205
- * Computed getters installed on the dynamic model class prototype.
206
- *
207
- * Each key becomes a getter on the model instance. The function receives
208
- * `self` (the model instance) and returns the computed value. These replace
209
- * hand-coded getter methods on legacy Model subclasses.
194
+ * Computed getters to install on the model instance. Each key becomes a getter;
195
+ * its function receives the model instance as `self` and returns the computed
196
+ * value.
210
197
  *
211
198
  * @example
212
199
  * model({ title: z.string(), metadata: z.string() }, {}, {
@@ -221,16 +208,15 @@ export interface ModelOptions {
221
208
  */
222
209
  computed?: ComputedRecord;
223
210
  /**
224
- * Fields to back-fill from the sync client identity when missing
225
- * during IndexedDB self-healing.
211
+ * Fields to back-fill from the connected sync identity when a stored row is missing
212
+ * them, during self-healing of the local store.
226
213
  *
227
- * Healing runs on every row loaded from IDB at hydration time and on
228
- * every delta merge. If the row is missing one of these fields, the
229
- * engine writes the corresponding identity value (`organizationId` /
230
- * `userId` from `SyncClient.initialize`) into the row before passing
231
- * it to the ObjectPool. Without this, rows from a past version that
232
- * didn't write the field would surface as `undefined` and break any
233
- * code that assumes the field is set.
214
+ * Healing runs on every row loaded from the local store at hydration and on every
215
+ * delta merge. When a row is missing one of these fields, the engine writes the
216
+ * matching identity value (the `organizationId` or `userId` passed to the sync
217
+ * client) into the row before it is loaded. Without this, rows written by an older
218
+ * version that did not set the field would read as `undefined` and break code that
219
+ * assumes it is present.
234
220
  *
235
221
  * @example
236
222
  * autoFill: [
@@ -240,13 +226,12 @@ export interface ModelOptions {
240
226
  */
241
227
  autoFill?: readonly AutoFillRule[];
242
228
  /**
243
- * Fields whose absence makes a stored row "orphaned" — corrupt
244
- * enough that the engine should drop it instead of loading it.
229
+ * Fields whose absence marks a stored row as orphaned — corrupt enough that the
230
+ * engine drops it instead of loading it.
245
231
  *
246
- * Healing returns `null` for the row when any listed field is
247
- * missing, which causes the caller to skip pool insertion for that
248
- * record. Use for foreign keys whose absence would crash dependent
249
- * code (e.g. a `SlideLayer` with no `slideId` can't render anywhere).
232
+ * During self-healing, a row missing any listed field is discarded rather than
233
+ * loaded. Use it for foreign keys whose absence would crash code that depends on
234
+ * them for example a child row that cannot be placed without its parent's id.
250
235
  *
251
236
  * @example requiredFields: ['slideId']
252
237
  */
@@ -263,13 +248,10 @@ export type ComputedRecord = Record<string, (self: any) => any>;
263
248
  */
264
249
  export type AutoFillSource = 'organizationId' | 'userId';
265
250
  /**
266
- * Declaration of a field that should be back-filled from the connected
267
- * sync identity if missing from a stored row.
268
- *
269
- * Used by `SyncClient.healModelRecord` to repair pre-existing IDB rows
270
- * that were written without `organizationId` / `createdBy` due to past
271
- * bugs in delta merging. Declared per-model so the engine itself stays
272
- * product-neutral.
251
+ * Declares one field to back-fill from the connected sync identity when it is
252
+ * missing from a stored row. The engine repairs rows during self-healing — for
253
+ * example rows written by an older version without an `organizationId` or
254
+ * `createdBy`. Declared per model, so the engine stays product-neutral.
273
255
  */
274
256
  export interface AutoFillRule {
275
257
  /** Field name on the model (e.g. `'organizationId'`, `'createdBy'`). */
@@ -303,30 +285,29 @@ export interface ModelDef<Shape extends z.ZodRawShape = z.ZodRawShape, R extends
303
285
  /** Sort order for bootstrap */
304
286
  readonly bootstrapOrderBy?: string;
305
287
  /**
306
- * The GraphQL/wire `__typename` value for this model. When unset in
307
- * {@link ModelOptions}, this falls back to the schema key at schema
308
- * assembly time (see `defineSchema`).
288
+ * The wire type name (`__typename`) for this model. When left unset in
289
+ * {@link ModelOptions}, it falls back to the schema key when the schema is
290
+ * assembled. See {@link ModelOptions.typename}.
309
291
  */
310
292
  readonly typename?: string;
311
293
  /** IndexedDB persistence hints. See {@link PersistOptions}. */
312
294
  readonly persist?: PersistOptions;
313
- /** The actual database table name from Prisma @@map. See {@link ModelOptions.tableName}. */
295
+ /** The database table this model maps to. See {@link ModelOptions.tableName}. */
314
296
  readonly tableName?: string;
315
- /** Whether the table has organization_id. See {@link ModelOptions.orgScoped}. */
316
- /** Canonical tenancy descriptor the single source of truth, normalized from
317
- * the `orgScoped`/`scopedVia`/`orgColumn` authoring sugar at build. */
297
+ /** The canonical tenancy descriptor for this model, normalized from the `policy`
298
+ * option at build time. See {@link ModelOptions.policy}. */
318
299
  readonly tenancy: Tenancy;
319
- /** Database plane — `tenant` (default) is portable to a customer DB; `control`
320
- * is Ablo-only. See {@link ModelOptions.plane} and `./plane.ts`. */
300
+ /** Which database this model's rows live in — `tenant` (default) can be a
301
+ * customer's own database; `control` is Ablo's. See {@link ModelOptions.plane}. */
321
302
  readonly plane?: ModelResidency;
322
- /** Scope-root marker. See {@link ModelOptions.scope}. */
303
+ /** Scope-root marker. See {@link ModelOptions.groups}. */
323
304
  readonly scope?: boolean | string;
324
- /** Membership edge granting identity scope-root access. See {@link ModelOptions.grants}. */
305
+ /** Membership edge granting an identity access to a scope root. See {@link ModelOptions.groups}. */
325
306
  readonly grants?: GrantsRef;
326
- /** Explicit non-relational record→group roles (normalized to an array). See {@link ModelOptions.entityRoles}. */
307
+ /** Explicit record-to-group roles, normalized to an array. See {@link ModelOptions.groups}. */
327
308
  readonly entityRoles?: readonly EntityRole[];
328
- /** Axis 3 — declared write-conflict disposition per committer kind. Already
329
- * canonical pure data (unlike `policy`, no resolve step). See {@link ModelOptions.conflict}. */
309
+ /** The write-conflict disposition per committer kind, carried as plain data. See
310
+ * {@link ModelOptions.conflict}. */
330
311
  readonly conflict?: ConflictAxis;
331
312
  /** Whether wire-level CREATE/UPDATE/DELETE is allowed. See {@link ModelOptions.mutable}. */
332
313
  readonly mutable?: boolean;
@@ -340,35 +321,30 @@ export interface ModelDef<Shape extends z.ZodRawShape = z.ZodRawShape, R extends
340
321
  readonly requiredFields?: readonly string[];
341
322
  }
342
323
  /**
343
- * Define a model with a Zod shape and optional relations.
324
+ * Defines a model from a Zod shape, with optional relations and options. The row
325
+ * type is inferred from the shape; fields built with the {@link field} builders
326
+ * carry extra metadata, while plain Zod fields get metadata inferred from their Zod
327
+ * type. The third argument sets options such as the {@link LoadStrategy}.
344
328
  *
345
329
  * ```ts
346
330
  * import { z } from 'zod';
347
331
  * import { model, relation } from '@abloatai/ablo/schema';
348
332
  *
333
+ * // Loaded at bootstrap (the default)
349
334
  * const tasks = model({
350
335
  * title: z.string(),
351
336
  * status: z.enum(['todo', 'doing', 'done']).default('todo'),
352
- * priority: z.number().default(0),
353
337
  * projectId: z.string().optional(),
354
338
  * }, {
355
339
  * project: relation.belongsTo('projects', 'projectId'),
356
340
  * });
357
- * ```
358
- */
359
- /**
360
- * Define a model with fields, optional relations, and load strategy.
361
- *
362
- * ```ts
363
- * // Loaded at bootstrap (default)
364
- * const tasks = model({ title: z.string() });
365
341
  *
366
- * // Loaded on first access (lazy)
342
+ * // Loaded on first access
367
343
  * const slideLayers = model({ slideId: z.string(), type: z.string() }, {
368
344
  * slide: relation.belongsTo('slides', 'slideId'),
369
345
  * }, { load: 'lazy' });
370
346
  *
371
- * // Only loaded when explicitly requested
347
+ * // Loaded only when explicitly requested
372
348
  * const auditLogs = model({ action: z.string() }, {}, { load: 'manual' });
373
349
  * ```
374
350
  */
@@ -376,12 +352,11 @@ export declare function model<Shape extends z.ZodRawShape, R extends RelationRec
376
352
  computed?: C;
377
353
  }): ModelDef<Shape, R, C>;
378
354
  /**
379
- * The sync-group kind a scope-root model mints, or `undefined` when the model
380
- * isn't a scope root. `scope: true` derives the kind from the lowercased
381
- * typename (`SlideDeck` → `slidedeck`); `scope: 'deck'` sets it explicitly
382
- * (the form to use when the wire kind must differ from the typename). One place
383
- * so the commit path, the membership resolver, and the participant join-side
384
- * all agree on what a record's own group is.
355
+ * Returns the sync-group kind a scope-root model produces, or `undefined` when the
356
+ * model is not a scope root. `scope: true` derives the kind from the lowercased
357
+ * typename (`SlideDeck` → `slidedeck`); `scope: 'deck'` sets it explicitly, which
358
+ * you use when the wire kind must differ from the typename. This is the single place
359
+ * that decides a record's own group, so every layer that reads it agrees.
385
360
  */
386
361
  export declare function scopeKindOf(def: {
387
362
  scope?: boolean | string;
@@ -1,8 +1,7 @@
1
1
  /**
2
- * Schema Model Definition
3
- *
4
- * A model is a Zod object schema + optional relations.
5
- * Types are inferred directly from Zod — no custom type system.
2
+ * Defines a model — one table's worth of fields plus its relations and options. A
3
+ * model is a Zod object schema paired with optional relation definitions; the row
4
+ * type is inferred directly from Zod, with no separate type system to keep in sync.
6
5
  *
7
6
  * Usage:
8
7
  * import { z } from 'zod';
@@ -18,11 +17,9 @@
18
17
  */
19
18
  import { z } from 'zod';
20
19
  import { getFieldMeta, inferFieldMetaFromZod } from './field.js';
21
- // Tenancy is owned by `tenancy.ts` (single source of truth). `ScopedViaRef` is
22
- // re-exported so existing `import { ScopedViaRef } from './model'` call sites
23
- // keep resolving. Authoring uses the `policy` option (`PolicyInput`, named for
24
- // Postgres/Supabase RLS), normalized to the canonical `Tenancy` by
25
- // `resolvePolicy` at build time.
20
+ // Tenancy lives in `tenancy.ts`. Authoring uses the `policy` option
21
+ // (`PolicyInput`), which `resolvePolicy` normalizes into the canonical `Tenancy`
22
+ // at build time.
26
23
  import { resolvePolicy } from './tenancy.js';
27
24
  import { DEFAULT_RESIDENCY } from './residency.js';
28
25
  /** Normalize the `entityRoles` option (single | array | undefined) to an array. */
@@ -33,35 +30,30 @@ function normalizeEntityRoles(input) {
33
30
  }
34
31
  // ── Model factory ─────────────────────────────────────────────────────────
35
32
  /**
36
- * Define a model with a Zod shape and optional relations.
33
+ * Defines a model from a Zod shape, with optional relations and options. The row
34
+ * type is inferred from the shape; fields built with the {@link field} builders
35
+ * carry extra metadata, while plain Zod fields get metadata inferred from their Zod
36
+ * type. The third argument sets options such as the {@link LoadStrategy}.
37
37
  *
38
38
  * ```ts
39
39
  * import { z } from 'zod';
40
40
  * import { model, relation } from '@abloatai/ablo/schema';
41
41
  *
42
+ * // Loaded at bootstrap (the default)
42
43
  * const tasks = model({
43
44
  * title: z.string(),
44
45
  * status: z.enum(['todo', 'doing', 'done']).default('todo'),
45
- * priority: z.number().default(0),
46
46
  * projectId: z.string().optional(),
47
47
  * }, {
48
48
  * project: relation.belongsTo('projects', 'projectId'),
49
49
  * });
50
- * ```
51
- */
52
- /**
53
- * Define a model with fields, optional relations, and load strategy.
54
- *
55
- * ```ts
56
- * // Loaded at bootstrap (default)
57
- * const tasks = model({ title: z.string() });
58
50
  *
59
- * // Loaded on first access (lazy)
51
+ * // Loaded on first access
60
52
  * const slideLayers = model({ slideId: z.string(), type: z.string() }, {
61
53
  * slide: relation.belongsTo('slides', 'slideId'),
62
54
  * }, { load: 'lazy' });
63
55
  *
64
- * // Only loaded when explicitly requested
56
+ * // Loaded only when explicitly requested
65
57
  * const auditLogs = model({ action: z.string() }, {}, { load: 'manual' });
66
58
  * ```
67
59
  */
@@ -90,17 +82,15 @@ export function model(shape, relations, options) {
90
82
  typename: options?.typename,
91
83
  persist: options?.persist,
92
84
  tableName: options?.tableName,
93
- // Axis 1 — normalize the `policy` authoring option into the one canonical
94
- // tenancy descriptor (defaults to a row-local org column).
85
+ // Normalize the `policy` option into the canonical tenancy descriptor (defaults
86
+ // to a row-local organization column).
95
87
  tenancy: resolvePolicy(options?.policy),
96
88
  plane: options?.plane ?? DEFAULT_RESIDENCY,
97
- // Axis 2 — unpack the `groups` routing namespace into the wire fields the
98
- // server reads (`scope`/`grants`/`entityRoles` on ModelDef/ModelJSON).
89
+ // Unpack the `groups` option into the individual routing fields the server reads.
99
90
  scope: options?.groups?.root,
100
91
  grants: options?.groups?.grants,
101
92
  entityRoles: normalizeEntityRoles(options?.groups?.roles),
102
- // Axis 3 already canonical pure data (a per-kind disposition map), so it
103
- // passes through verbatim; no resolve step like `resolvePolicy`.
93
+ // The conflict disposition is already plain data, so it passes through unchanged.
104
94
  conflict: options?.conflict,
105
95
  mutable: options?.mutable ?? true,
106
96
  lazyObservable: options?.lazyObservable,
@@ -110,12 +100,11 @@ export function model(shape, relations, options) {
110
100
  };
111
101
  }
112
102
  /**
113
- * The sync-group kind a scope-root model mints, or `undefined` when the model
114
- * isn't a scope root. `scope: true` derives the kind from the lowercased
115
- * typename (`SlideDeck` → `slidedeck`); `scope: 'deck'` sets it explicitly
116
- * (the form to use when the wire kind must differ from the typename). One place
117
- * so the commit path, the membership resolver, and the participant join-side
118
- * all agree on what a record's own group is.
103
+ * Returns the sync-group kind a scope-root model produces, or `undefined` when the
104
+ * model is not a scope root. `scope: true` derives the kind from the lowercased
105
+ * typename (`SlideDeck` → `slidedeck`); `scope: 'deck'` sets it explicitly, which
106
+ * you use when the wire kind must differ from the typename. This is the single place
107
+ * that decides a record's own group, so every layer that reads it agrees.
119
108
  */
120
109
  export function scopeKindOf(def, fallbackKey) {
121
110
  if (!def.scope)
@@ -1,20 +1,21 @@
1
1
  /**
2
- * `schemaToOpenApi(schema)` — generate an OpenAPI 3.1 spec FROM a pushed schema,
3
- * so the API Reference reflects the customer's OWN models, not Ablo's.
4
- *
5
- * The API surface *is* the schema: a `task` model is what makes `/v1/models/task`
6
- * exist. This walks `schema.models[*].fields` (the introspectable `FieldMeta`)
7
- * and emits, per model, the CRUD + coordination routes the hosted API serves:
2
+ * Generates an OpenAPI 3.1 specification from a pushed schema, so the API reference
3
+ * describes your own models rather than a fixed set. The API surface is the schema:
4
+ * defining a `task` model is what makes `/v1/models/task` exist. This walks each
5
+ * model's `fields` (the introspectable {@link FieldMeta}) and emits, per model, the
6
+ * CRUD and coordination routes the API serves:
8
7
  * GET/POST /v1/models/{model}
9
8
  * GET/PATCH/DELETE /v1/models/{model}/{id}
10
9
  * POST/DELETE /v1/models/{model}/{id}/claim
10
+ * POST /v1/models/{model}/{id}/claim/heartbeat
11
11
  * POST /v1/models/{model}/{id}/claim/reorder
12
- * plus POST /v1/commits. Auth is a single Bearer scheme (the API key).
12
+ * plus POST /v1/commits. Authentication is a single Bearer scheme, your API key.
13
13
  *
14
- * Wire it into `ablo` codegen (e.g. `ablo openapi > openapi.json`) or serve it
15
- * per-org; the output is a plain JSON-able object.
14
+ * Feed it into codegen (for example `ablo openapi > openapi.json`) or serve it
15
+ * directly; the return value is a plain JSON-serializable object.
16
16
  */
17
17
  import type { Schema, SchemaRecord } from './schema.js';
18
+ /** Options for {@link schemaToOpenApi} — the metadata stamped into the generated spec. */
18
19
  export interface SchemaToOpenApiOptions {
19
20
  /** Spec title. Default `"Ablo API"`. */
20
21
  readonly title?: string;
@@ -1,6 +1,5 @@
1
- // Dependency-free leaf (NOT client/auth.ts that would pull the error
2
- // registry + credential policy into the schema subpath and close a
3
- // schema → client → errors → coordination → schema cycle).
1
+ // Pulled from the endpoints module to keep this schema file free of the client's
2
+ // error-handling and credential dependencies.
4
3
  import { ABLO_HOSTED_HTTP_BASE_URL } from '../client/hostedEndpoints.js';
5
4
  function fieldSchema(f) {
6
5
  switch (f.type) {
@@ -94,6 +93,9 @@ export function schemaToOpenApi(schema, options = {}) {
94
93
  post: { tags: [key], summary: `Claim a ${key} (acquire lease)`, parameters: [idParam()], responses: { '200': jsonResp('Claim acquired', { type: 'object' }) } },
95
94
  delete: { tags: [key], summary: `Release a ${key} claim`, parameters: [idParam()], responses: { '200': jsonResp('Released', { type: 'object' }) } },
96
95
  };
96
+ paths[`/v1/models/${key}/{id}/claim/heartbeat`] = {
97
+ post: { tags: [key], summary: `Heartbeat a held ${key} claim (extend the lease for long-running work)`, parameters: [idParam()], responses: { '200': jsonResp('Lease extended (or queued slot refreshed)', { type: 'object', properties: { object: { type: 'string', enum: ['claim_heartbeat'] }, claimId: { type: 'string' }, status: { type: 'string', enum: ['held', 'queued'] }, expiresAt: { type: 'integer' }, position: { type: 'integer' } } }) } },
98
+ };
97
99
  paths[`/v1/models/${key}/{id}/claim/reorder`] = {
98
100
  post: { tags: [key], summary: `Reorder the ${key} wait-line (privileged)`, parameters: [idParam()], responses: { '200': jsonResp('Reordered', { type: 'object' }) } },
99
101
  };