@abloatai/ablo 0.25.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 (425) hide show
  1. package/AGENTS.md +5 -3
  2. package/CHANGELOG.md +34 -0
  3. package/README.md +104 -88
  4. package/dist/BaseSyncedStore.d.ts +140 -266
  5. package/dist/BaseSyncedStore.js +338 -739
  6. package/dist/Database.d.ts +62 -77
  7. package/dist/Database.js +106 -127
  8. package/dist/{ObjectPool.d.ts → InstanceCache.d.ts} +10 -13
  9. package/dist/{ObjectPool.js → InstanceCache.js} +91 -83
  10. package/dist/LazyReferenceCollection.d.ts +11 -15
  11. package/dist/LazyReferenceCollection.js +16 -15
  12. package/dist/Model.d.ts +37 -52
  13. package/dist/Model.js +52 -69
  14. package/dist/ModelRegistry.d.ts +46 -25
  15. package/dist/ModelRegistry.js +32 -30
  16. package/dist/NetworkMonitor.d.ts +5 -6
  17. package/dist/NetworkMonitor.js +6 -7
  18. package/dist/SyncClient.d.ts +119 -109
  19. package/dist/SyncClient.js +303 -224
  20. package/dist/SyncEngineContext.d.ts +1 -3
  21. package/dist/SyncEngineContext.js +1 -2
  22. package/dist/adapters/alwaysOnline.d.ts +6 -8
  23. package/dist/adapters/alwaysOnline.js +6 -8
  24. package/dist/adapters/inMemoryStorage.d.ts +9 -9
  25. package/dist/adapters/inMemoryStorage.js +9 -9
  26. package/dist/agent/Agent.d.ts +39 -31
  27. package/dist/agent/Agent.js +35 -23
  28. package/dist/agent/index.d.ts +4 -4
  29. package/dist/agent/index.js +5 -5
  30. package/dist/agent/session.d.ts +47 -44
  31. package/dist/agent/session.js +37 -48
  32. package/dist/agent/types.d.ts +26 -31
  33. package/dist/agent/types.js +6 -7
  34. package/dist/ai-sdk/coordinatedTool.d.ts +108 -0
  35. package/dist/ai-sdk/{coordinated-tool.js → coordinatedTool.js} +44 -38
  36. package/dist/ai-sdk/coordinationContext.d.ts +46 -0
  37. package/dist/ai-sdk/{coordination-context.js → coordinationContext.js} +30 -31
  38. package/dist/ai-sdk/index.d.ts +25 -22
  39. package/dist/ai-sdk/index.js +25 -22
  40. package/dist/ai-sdk/wrap.d.ts +7 -8
  41. package/dist/ai-sdk/wrap.js +2 -2
  42. package/dist/auth/credentialPolicy.d.ts +74 -71
  43. package/dist/auth/credentialPolicy.js +51 -56
  44. package/dist/auth/credentialSource.d.ts +7 -18
  45. package/dist/auth/credentialSource.js +10 -18
  46. package/dist/auth/index.d.ts +59 -58
  47. package/dist/auth/index.js +34 -40
  48. package/dist/auth/schemas.d.ts +5 -4
  49. package/dist/auth/schemas.js +5 -4
  50. package/dist/batching/index.d.ts +19 -21
  51. package/dist/batching/index.js +14 -17
  52. package/dist/cli.cjs +483 -369
  53. package/dist/client/Ablo.d.ts +107 -836
  54. package/dist/client/Ablo.js +174 -833
  55. package/dist/client/ApiClient.d.ts +44 -20
  56. package/dist/client/ApiClient.js +193 -44
  57. package/dist/client/auth.d.ts +51 -60
  58. package/dist/client/auth.js +137 -110
  59. package/dist/client/claimHeartbeatLoop.d.ts +50 -0
  60. package/dist/client/claimHeartbeatLoop.js +88 -0
  61. package/dist/client/consoleLogger.d.ts +35 -0
  62. package/dist/client/consoleLogger.js +44 -0
  63. package/dist/client/createInternalComponents.d.ts +14 -17
  64. package/dist/client/createInternalComponents.js +26 -31
  65. package/dist/client/createModelProxy.d.ts +130 -120
  66. package/dist/client/createModelProxy.js +158 -124
  67. package/dist/client/credentialEndpoint.d.ts +61 -0
  68. package/dist/client/credentialEndpoint.js +86 -0
  69. package/dist/client/functionalUpdate.d.ts +29 -27
  70. package/dist/client/functionalUpdate.js +21 -21
  71. package/dist/client/hostedEndpoints.d.ts +21 -0
  72. package/dist/client/hostedEndpoints.js +21 -0
  73. package/dist/client/httpClient.d.ts +58 -54
  74. package/dist/client/httpClient.js +29 -31
  75. package/dist/client/identity.d.ts +15 -20
  76. package/dist/client/identity.js +49 -59
  77. package/dist/client/modelRegistration.d.ts +10 -0
  78. package/dist/client/modelRegistration.js +301 -0
  79. package/dist/client/options.d.ts +373 -0
  80. package/dist/client/options.js +6 -0
  81. package/dist/client/registerDataSource.d.ts +9 -9
  82. package/dist/client/registerDataSource.js +15 -16
  83. package/dist/client/resourceTypes.d.ts +333 -0
  84. package/dist/client/resourceTypes.js +7 -0
  85. package/dist/client/schemaConfig.d.ts +44 -0
  86. package/dist/client/schemaConfig.js +176 -0
  87. package/dist/client/sessionMint.d.ts +17 -13
  88. package/dist/client/sessionMint.js +26 -31
  89. package/dist/client/validateAbloOptions.d.ts +12 -14
  90. package/dist/client/validateAbloOptions.js +9 -10
  91. package/dist/client/writeOptionsSchema.d.ts +18 -16
  92. package/dist/client/writeOptionsSchema.js +23 -20
  93. package/dist/client/wsMutationExecutor.d.ts +28 -0
  94. package/dist/client/wsMutationExecutor.js +71 -0
  95. package/dist/context.d.ts +6 -4
  96. package/dist/context.js +6 -7
  97. package/dist/coordination/index.d.ts +13 -4
  98. package/dist/coordination/index.js +29 -4
  99. package/dist/coordination/schema.d.ts +176 -128
  100. package/dist/coordination/schema.js +197 -133
  101. package/dist/coordination/trace.d.ts +9 -11
  102. package/dist/coordination/trace.js +13 -15
  103. package/dist/core/DatabaseManager.d.ts +5 -8
  104. package/dist/core/DatabaseManager.js +38 -40
  105. package/dist/core/QueryProcessor.d.ts +7 -9
  106. package/dist/core/QueryProcessor.js +27 -34
  107. package/dist/core/QueryView.d.ts +17 -5
  108. package/dist/core/QueryView.js +6 -7
  109. package/dist/core/StoreManager.d.ts +14 -16
  110. package/dist/core/StoreManager.js +26 -25
  111. package/dist/core/ViewRegistry.d.ts +5 -5
  112. package/dist/core/ViewRegistry.js +4 -4
  113. package/dist/core/index.d.ts +18 -13
  114. package/dist/core/index.js +32 -26
  115. package/dist/core/openIDBWithTimeout.d.ts +38 -36
  116. package/dist/core/openIDBWithTimeout.js +57 -54
  117. package/dist/core/queryUtils.d.ts +45 -0
  118. package/dist/core/queryUtils.js +69 -0
  119. package/dist/core/storeContract.d.ts +145 -0
  120. package/dist/core/storeContract.js +12 -0
  121. package/dist/environment.d.ts +28 -0
  122. package/dist/environment.js +21 -0
  123. package/dist/errorCodes.d.ts +118 -101
  124. package/dist/errorCodes.js +277 -260
  125. package/dist/errors.d.ts +170 -165
  126. package/dist/errors.js +161 -151
  127. package/dist/index.d.ts +30 -27
  128. package/dist/index.js +90 -82
  129. package/dist/interfaces/index.d.ts +108 -133
  130. package/dist/interfaces/index.js +5 -4
  131. package/dist/keys/index.d.ts +27 -29
  132. package/dist/keys/index.js +59 -49
  133. package/dist/mutators/RecordingTransaction.d.ts +16 -16
  134. package/dist/mutators/RecordingTransaction.js +31 -37
  135. package/dist/mutators/Transaction.d.ts +18 -26
  136. package/dist/mutators/Transaction.js +14 -20
  137. package/dist/mutators/UndoManager.d.ts +122 -131
  138. package/dist/mutators/UndoManager.js +149 -155
  139. package/dist/mutators/defineMutators.d.ts +24 -37
  140. package/dist/mutators/defineMutators.js +14 -20
  141. package/dist/mutators/inverseOp.d.ts +12 -15
  142. package/dist/mutators/inverseOp.js +12 -15
  143. package/dist/mutators/mutateActions.d.ts +10 -9
  144. package/dist/mutators/mutateActions.js +1 -1
  145. package/dist/mutators/readerActions.d.ts +9 -8
  146. package/dist/mutators/readerActions.js +2 -2
  147. package/dist/mutators/undoApply.d.ts +31 -27
  148. package/dist/mutators/undoApply.js +26 -24
  149. package/dist/policy/index.d.ts +5 -3
  150. package/dist/policy/index.js +5 -3
  151. package/dist/policy/types.d.ts +105 -101
  152. package/dist/policy/types.js +67 -66
  153. package/dist/query/client.d.ts +32 -16
  154. package/dist/query/client.js +103 -72
  155. package/dist/query/types.d.ts +37 -60
  156. package/dist/query/types.js +13 -33
  157. package/dist/react/AbloProvider.d.ts +7 -11
  158. package/dist/react/AbloProvider.js +24 -17
  159. package/dist/react/context.d.ts +27 -146
  160. package/dist/react/context.js +9 -10
  161. package/dist/react/index.d.ts +41 -42
  162. package/dist/react/index.js +37 -38
  163. package/dist/react/internalContext.d.ts +17 -19
  164. package/dist/react/useAblo.d.ts +23 -22
  165. package/dist/react/useAblo.js +17 -15
  166. package/dist/react/useCurrentUserId.d.ts +8 -7
  167. package/dist/react/useCurrentUserId.js +8 -7
  168. package/dist/react/useErrorListener.d.ts +7 -7
  169. package/dist/react/useErrorListener.js +11 -12
  170. package/dist/react/useMutationFailureListener.d.ts +8 -8
  171. package/dist/react/useMutationFailureListener.js +9 -9
  172. package/dist/react/useMutators.d.ts +11 -11
  173. package/dist/react/useMutators.js +10 -4
  174. package/dist/react/useReactive.js +2 -3
  175. package/dist/react/useSyncStatus.d.ts +4 -6
  176. package/dist/react/useUndoScope.d.ts +7 -9
  177. package/dist/react/useUndoScope.js +3 -3
  178. package/dist/schema/coordination.d.ts +21 -25
  179. package/dist/schema/coordination.js +21 -25
  180. package/dist/schema/ddl.d.ts +43 -39
  181. package/dist/schema/ddl.js +75 -68
  182. package/dist/schema/ddlLock.d.ts +35 -0
  183. package/dist/schema/ddlLock.js +46 -0
  184. package/dist/schema/diff.d.ts +99 -61
  185. package/dist/schema/diff.js +43 -34
  186. package/dist/schema/field.d.ts +37 -42
  187. package/dist/schema/field.js +36 -49
  188. package/dist/schema/generate.d.ts +12 -12
  189. package/dist/schema/generate.js +12 -12
  190. package/dist/schema/index.d.ts +5 -4
  191. package/dist/schema/index.js +29 -21
  192. package/dist/schema/model.d.ts +121 -146
  193. package/dist/schema/model.js +24 -35
  194. package/dist/schema/openapi.d.ts +10 -9
  195. package/dist/schema/openapi.js +7 -1
  196. package/dist/schema/queries.d.ts +30 -32
  197. package/dist/schema/queries.js +24 -25
  198. package/dist/schema/relation.d.ts +89 -99
  199. package/dist/schema/relation.js +13 -13
  200. package/dist/schema/residency.d.ts +38 -0
  201. package/dist/schema/residency.js +30 -0
  202. package/dist/schema/roles.d.ts +45 -27
  203. package/dist/schema/roles.js +52 -21
  204. package/dist/schema/schema.d.ts +36 -45
  205. package/dist/schema/schema.js +42 -39
  206. package/dist/schema/select.d.ts +13 -13
  207. package/dist/schema/select.js +13 -13
  208. package/dist/schema/serialize.d.ts +36 -39
  209. package/dist/schema/serialize.js +27 -31
  210. package/dist/schema/sugar.d.ts +17 -32
  211. package/dist/schema/sugar.js +14 -29
  212. package/dist/schema/{sync-delta-row.d.ts → syncDeltaRow.d.ts} +27 -50
  213. package/dist/schema/syncDeltaRow.js +89 -0
  214. package/dist/schema/tenancy.d.ts +44 -46
  215. package/dist/schema/tenancy.js +46 -48
  216. package/dist/server/adapter.d.ts +58 -58
  217. package/dist/server/adapter.js +13 -14
  218. package/dist/server/commit.d.ts +60 -64
  219. package/dist/server/index.d.ts +9 -10
  220. package/dist/server/index.js +1 -1
  221. package/dist/server/readConfig.d.ts +70 -0
  222. package/dist/server/readConfig.js +8 -0
  223. package/dist/server/storageMode.d.ts +23 -0
  224. package/dist/server/storageMode.js +17 -0
  225. package/dist/source/adapter.d.ts +31 -26
  226. package/dist/source/adapter.js +10 -10
  227. package/dist/source/adapters/drizzle.d.ts +28 -23
  228. package/dist/source/adapters/drizzle.js +34 -28
  229. package/dist/source/adapters/kysely.d.ts +27 -25
  230. package/dist/source/adapters/kysely.js +28 -26
  231. package/dist/source/adapters/memory.d.ts +8 -7
  232. package/dist/source/adapters/memory.js +10 -9
  233. package/dist/source/adapters/prisma.d.ts +13 -12
  234. package/dist/source/adapters/prisma.js +27 -29
  235. package/dist/source/conformance.d.ts +18 -11
  236. package/dist/source/conformance.js +27 -19
  237. package/dist/source/connector.d.ts +31 -32
  238. package/dist/source/connector.js +30 -28
  239. package/dist/source/connectorProtocol.d.ts +160 -0
  240. package/dist/source/connectorProtocol.js +162 -0
  241. package/dist/source/contract.d.ts +26 -27
  242. package/dist/source/contract.js +28 -29
  243. package/dist/source/factory.d.ts +94 -0
  244. package/dist/source/factory.js +268 -0
  245. package/dist/source/index.d.ts +10 -462
  246. package/dist/source/index.js +17 -421
  247. package/dist/source/migrations.d.ts +9 -9
  248. package/dist/source/migrations.js +9 -9
  249. package/dist/source/next.d.ts +10 -11
  250. package/dist/source/next.js +7 -8
  251. package/dist/source/pushQueue.d.ts +70 -48
  252. package/dist/source/pushQueue.js +36 -29
  253. package/dist/source/signing.d.ts +88 -0
  254. package/dist/source/signing.js +159 -0
  255. package/dist/source/types.d.ts +351 -0
  256. package/dist/source/types.js +43 -0
  257. package/dist/stores/ObjectStore.d.ts +11 -12
  258. package/dist/stores/ObjectStore.js +34 -35
  259. package/dist/stores/ObjectStoreContract.d.ts +12 -15
  260. package/dist/stores/SyncActionStore.d.ts +8 -12
  261. package/dist/stores/SyncActionStore.js +77 -46
  262. package/dist/surface.d.ts +28 -21
  263. package/dist/surface.js +28 -20
  264. package/dist/sync/{BootstrapHelper.d.ts → BootstrapFetcher.d.ts} +37 -45
  265. package/dist/sync/{BootstrapHelper.js → BootstrapFetcher.js} +101 -80
  266. package/dist/sync/ConnectionManager.d.ts +47 -50
  267. package/dist/sync/ConnectionManager.js +74 -70
  268. package/dist/sync/NetworkProbe.d.ts +27 -31
  269. package/dist/sync/NetworkProbe.js +67 -72
  270. package/dist/sync/{HydrationCoordinator.d.ts → OnDemandLoader.d.ts} +49 -36
  271. package/dist/sync/{HydrationCoordinator.js → OnDemandLoader.js} +79 -54
  272. package/dist/sync/{AreaOfInterestManager.d.ts → SubscriptionManager.d.ts} +45 -59
  273. package/dist/sync/{AreaOfInterestManager.js → SubscriptionManager.js} +44 -52
  274. package/dist/sync/SyncWebSocket.d.ts +175 -250
  275. package/dist/sync/SyncWebSocket.js +431 -769
  276. package/dist/sync/awaitClaimGrant.d.ts +18 -18
  277. package/dist/sync/awaitClaimGrant.js +38 -30
  278. package/dist/sync/bootstrapApply.d.ts +70 -0
  279. package/dist/sync/bootstrapApply.js +73 -0
  280. package/dist/sync/commitFrames.d.ts +44 -0
  281. package/dist/sync/commitFrames.js +94 -0
  282. package/dist/sync/createClaimStream.d.ts +23 -22
  283. package/dist/sync/createClaimStream.js +108 -25
  284. package/dist/sync/createPresenceStream.d.ts +19 -18
  285. package/dist/sync/createPresenceStream.js +25 -26
  286. package/dist/sync/createSnapshot.d.ts +13 -17
  287. package/dist/sync/createSnapshot.js +20 -26
  288. package/dist/sync/credentialLifecycle.d.ts +175 -0
  289. package/dist/sync/credentialLifecycle.js +322 -0
  290. package/dist/sync/deltaPipeline.d.ts +113 -0
  291. package/dist/sync/deltaPipeline.js +261 -0
  292. package/dist/sync/groupChange.d.ts +113 -0
  293. package/dist/sync/groupChange.js +242 -0
  294. package/dist/sync/heartbeat.d.ts +63 -0
  295. package/dist/sync/heartbeat.js +91 -0
  296. package/dist/sync/participants.d.ts +27 -27
  297. package/dist/sync/schemas.d.ts +3 -2
  298. package/dist/sync/schemas.js +14 -10
  299. package/dist/sync/syncCursor.d.ts +40 -0
  300. package/dist/sync/syncCursor.js +55 -0
  301. package/dist/sync/syncPlan.d.ts +54 -0
  302. package/dist/sync/syncPlan.js +50 -0
  303. package/dist/sync/syncPosition.d.ts +54 -49
  304. package/dist/sync/syncPosition.js +57 -52
  305. package/dist/sync/wsFrameHandlers.d.ts +116 -0
  306. package/dist/sync/wsFrameHandlers.js +374 -0
  307. package/dist/testing/fixtures/bootstrap.d.ts +21 -17
  308. package/dist/testing/fixtures/bootstrap.js +12 -6
  309. package/dist/testing/fixtures/deltas.d.ts +31 -34
  310. package/dist/testing/fixtures/deltas.js +30 -33
  311. package/dist/testing/fixtures/models.d.ts +11 -10
  312. package/dist/testing/fixtures/models.js +12 -10
  313. package/dist/testing/helpers/{react-wrapper.d.ts → reactWrapper.d.ts} +13 -10
  314. package/dist/testing/helpers/{react-wrapper.js → reactWrapper.js} +15 -12
  315. package/dist/testing/helpers/{sync-engine-harness.d.ts → syncEngineHarness.d.ts} +17 -18
  316. package/dist/testing/helpers/{sync-engine-harness.js → syncEngineHarness.js} +14 -11
  317. package/dist/testing/helpers/wait.d.ts +13 -8
  318. package/dist/testing/helpers/wait.js +13 -8
  319. package/dist/testing/index.d.ts +4 -4
  320. package/dist/testing/index.js +3 -3
  321. package/dist/testing/mocks/MockMutationExecutor.d.ts +18 -17
  322. package/dist/testing/mocks/MockMutationExecutor.js +15 -14
  323. package/dist/testing/mocks/MockNetworkMonitor.d.ts +8 -8
  324. package/dist/testing/mocks/MockNetworkMonitor.js +8 -8
  325. package/dist/testing/mocks/MockSyncContext.d.ts +21 -34
  326. package/dist/testing/mocks/MockSyncContext.js +16 -45
  327. package/dist/testing/mocks/MockSyncStore.d.ts +14 -14
  328. package/dist/testing/mocks/MockSyncStore.js +11 -11
  329. package/dist/testing/mocks/MockWebSocket.d.ts +28 -24
  330. package/dist/testing/mocks/MockWebSocket.js +22 -21
  331. package/dist/transactions/TransactionQueue.d.ts +190 -221
  332. package/dist/transactions/TransactionQueue.js +424 -822
  333. package/dist/transactions/TransactionStore.d.ts +20 -0
  334. package/dist/transactions/TransactionStore.js +53 -0
  335. package/dist/transactions/UnconfirmedWrites.d.ts +82 -0
  336. package/dist/transactions/UnconfirmedWrites.js +104 -0
  337. package/dist/transactions/coalesceRules.d.ts +58 -0
  338. package/dist/transactions/coalesceRules.js +140 -0
  339. package/dist/transactions/commitPayload.d.ts +130 -0
  340. package/dist/transactions/commitPayload.js +143 -0
  341. package/dist/transactions/deltaConfirmation.d.ts +58 -0
  342. package/dist/transactions/deltaConfirmation.js +215 -0
  343. package/dist/transactions/optimisticApply.d.ts +49 -0
  344. package/dist/transactions/optimisticApply.js +65 -0
  345. package/dist/transactions/replayValidation.d.ts +99 -0
  346. package/dist/transactions/replayValidation.js +111 -0
  347. package/dist/types/global.d.ts +46 -41
  348. package/dist/types/global.js +20 -19
  349. package/dist/types/index.d.ts +74 -80
  350. package/dist/types/index.js +22 -27
  351. package/dist/types/modelData.d.ts +10 -0
  352. package/dist/types/modelData.js +9 -0
  353. package/dist/types/participant.d.ts +20 -0
  354. package/dist/types/participant.js +10 -0
  355. package/dist/types/streams.d.ts +216 -209
  356. package/dist/types/streams.js +7 -7
  357. package/dist/utils/asyncIterator.d.ts +25 -32
  358. package/dist/utils/asyncIterator.js +25 -32
  359. package/dist/utils/duration.d.ts +12 -15
  360. package/dist/utils/duration.js +12 -15
  361. package/dist/utils/mobxSetup.d.ts +53 -0
  362. package/dist/utils/{mobx-setup.js → mobxSetup.js} +44 -100
  363. package/dist/webhooks/events.d.ts +21 -16
  364. package/dist/webhooks/events.js +10 -8
  365. package/dist/webhooks/index.d.ts +5 -7
  366. package/dist/webhooks/index.js +5 -7
  367. package/dist/{schema/sync-delta-wire.d.ts → wire/delta.d.ts} +58 -41
  368. package/dist/wire/delta.js +114 -0
  369. package/dist/wire/errorEnvelope.d.ts +35 -27
  370. package/dist/wire/errorEnvelope.js +38 -32
  371. package/dist/wire/frames.d.ts +150 -67
  372. package/dist/wire/frames.js +48 -1
  373. package/dist/wire/index.d.ts +18 -13
  374. package/dist/wire/index.js +36 -13
  375. package/dist/wire/listEnvelope.d.ts +16 -23
  376. package/dist/wire/listEnvelope.js +7 -6
  377. package/dist/wire/protocol.d.ts +38 -0
  378. package/dist/wire/protocol.js +38 -0
  379. package/dist/wire/protocolVersion.d.ts +60 -0
  380. package/dist/wire/protocolVersion.js +67 -0
  381. package/docs/api-keys.md +4 -3
  382. package/docs/coordination.md +59 -0
  383. package/docs/examples/existing-python-backend.md +3 -3
  384. package/docs/identity.md +4 -4
  385. package/docs/integration-guide.md +1 -1
  386. package/docs/react.md +1 -1
  387. package/docs/sessions.md +5 -7
  388. package/package.json +24 -21
  389. package/dist/ai-sdk/coordinated-tool.d.ts +0 -101
  390. package/dist/ai-sdk/coordination-context.d.ts +0 -52
  391. package/dist/client/index.d.ts +0 -36
  392. package/dist/client/index.js +0 -33
  393. package/dist/config/index.d.ts +0 -10
  394. package/dist/config/index.js +0 -12
  395. package/dist/core/query-utils.d.ts +0 -34
  396. package/dist/core/query-utils.js +0 -59
  397. package/dist/interfaces/headless.d.ts +0 -95
  398. package/dist/interfaces/headless.js +0 -41
  399. package/dist/query/index.d.ts +0 -6
  400. package/dist/query/index.js +0 -5
  401. package/dist/realtime/index.d.ts +0 -10
  402. package/dist/realtime/index.js +0 -9
  403. package/dist/schema/plane.d.ts +0 -23
  404. package/dist/schema/plane.js +0 -19
  405. package/dist/schema/sync-delta-row.js +0 -103
  406. package/dist/schema/sync-delta-wire.js +0 -102
  407. package/dist/server/next.d.ts +0 -51
  408. package/dist/server/next.js +0 -47
  409. package/dist/server/read-config.d.ts +0 -67
  410. package/dist/server/read-config.js +0 -8
  411. package/dist/server/storage-mode.d.ts +0 -1
  412. package/dist/server/storage-mode.js +0 -18
  413. package/dist/source/connector-protocol.d.ts +0 -159
  414. package/dist/source/connector-protocol.js +0 -161
  415. package/dist/sync/OfflineFlush.d.ts +0 -9
  416. package/dist/sync/OfflineFlush.js +0 -22
  417. package/dist/sync/OfflineTransactionStore.d.ts +0 -37
  418. package/dist/sync/OfflineTransactionStore.js +0 -263
  419. package/dist/transactions/OptimisticEchoTracker.d.ts +0 -82
  420. package/dist/transactions/OptimisticEchoTracker.js +0 -104
  421. package/dist/transactions/index.d.ts +0 -16
  422. package/dist/transactions/index.js +0 -7
  423. package/dist/transactions/mutation-error-handler.d.ts +0 -5
  424. package/dist/transactions/mutation-error-handler.js +0 -39
  425. package/dist/utils/mobx-setup.d.ts +0 -42
@@ -1,12 +1,15 @@
1
1
  /**
2
- * Conflict policy the engine detects, the policy decides.
2
+ * The conflict types a policy decides on. The engine detects a conflict and
3
+ * hands it to your {@link ConflictPolicy}, which returns a
4
+ * {@link ConflictDecision}.
3
5
  *
4
- * Two conflict shapes today: `stale_context` (a write whose `readAt`
5
- * is older than the latest delta on the target) and `claim_held`
6
- * (a participant claims a target someone else is already claiming).
7
- * Adding new shapes is additive on the discriminated union.
6
+ * There are two conflict shapes. A {@link StaleContextConflict} is a write
7
+ * whose `readAt` watermark is older than the latest delta on the target row. A
8
+ * {@link ClaimHeldConflict} is a participant trying to claim a target that
9
+ * someone else already holds. {@link Conflict} is the discriminated union of
10
+ * the two; switch on `kind` to narrow it.
8
11
  */
9
- import type { ParticipantRef } from '../types/streams.js';
12
+ import type { ParticipantRef } from '../types/participant.js';
10
13
  import type { OnStaleMode } from '../coordination/schema.js';
11
14
  export type ConflictKind = 'stale_context' | 'claim_held';
12
15
  /** Fields shared by every conflict shape. */
@@ -32,19 +35,18 @@ export interface StaleContextConflict extends ConflictBase {
32
35
  readonly observedSyncId: number;
33
36
  /**
34
37
  * The fields whose concurrent change triggered this conflict — the
35
- * intersection of the committer's written fields and the columns a
36
- * newer delta touched. Empty array means the conflicting delta was a
37
- * whole-entity change (CREATE/DELETE, or a pre-`changed_fields`
38
- * legacy delta), which conflicts with any write. Lets a policy decide
39
- * at field granularity, e.g. allow when the only collision is on a
40
- * cosmetic field. See `docs/internal/per-field-conflict-detection.md`.
38
+ * intersection of the fields the committer wrote and the columns a newer
39
+ * delta touched. An empty array means the conflicting delta was a
40
+ * whole-entity change, such as a create or delete, which conflicts with any
41
+ * write. A policy can use this to decide at field granularity — for example,
42
+ * allowing the write when the only overlap is on a cosmetic field.
41
43
  */
42
44
  readonly conflictingFields?: readonly string[];
43
45
  /**
44
- * The committer's declared `onStale` intent for this op. The default policy
45
- * honors it: `'notify'` notify+hold, anything else reject. A custom policy
46
- * may override (e.g. gate notify on claim ownership). Absent treat as
47
- * `'reject'` (the unguarded-write default).
46
+ * The committer's declared `onStale` intent for this operation. The default
47
+ * policy honors it: `'notify'` holds the write and notifies, and anything
48
+ * else rejects. A custom policy may override this. When absent, it is treated
49
+ * as `'reject'`, the default for an unguarded write.
48
50
  */
49
51
  readonly requestedMode?: 'reject' | 'overwrite' | 'notify';
50
52
  }
@@ -57,11 +59,12 @@ export interface ClaimHeldConflict extends ConflictBase {
57
59
  /** Holder's claim expiry (ms since epoch). */
58
60
  readonly expiresAt: number;
59
61
  /**
60
- * The committer's granted capability operations (the key's allowlist). A
61
- * policy is a pure function of the conflict value, so it can only authorize
62
- * on what's carried here this is what lets a policy express "preempt iff
63
- * the committer holds `claim.preempt`" (see `capabilityPreemptPolicy`).
64
- * Empty for a human session with no allowlist.
62
+ * The capability operations granted to the committer — the allowlist carried
63
+ * by its key. A policy decides purely from the conflict it is given, so this
64
+ * is the only place it can read the committer's privileges. It lets a policy
65
+ * express a rule such as "preempt only if the committer holds `claim.preempt`"
66
+ * (see {@link capabilityPreemptPolicy}). Empty for a human session that
67
+ * carries no allowlist.
65
68
  */
66
69
  readonly committerOperations: readonly string[];
67
70
  }
@@ -79,37 +82,40 @@ export type ConflictDecision = {
79
82
  readonly note?: string;
80
83
  }
81
84
  /**
82
- * Evict the current holder and grant the target to the committer. Only
83
- * meaningful for an `claim_held` conflict at claim time (`claim_begin`):
84
- * the holder receives an `claim_lost` (reason `'preempted'`) and the
85
- * preemptor takes the lease, jumping ahead of any FIFO waiters. This is the
86
- * authorization seam for preemption a policy returns `preempt` only for a
87
- * committer it deems higher-priority (e.g. a supervisor over its sub-agents,
88
- * or an identity holding a preempt capability). At commit time there is no
89
- * holder to evict, so a `preempt` decision there is treated as `allow`.
85
+ * Evict the current holder and grant the target to the committer. This is
86
+ * only meaningful for a `claim_held` conflict raised at claim time: the
87
+ * holder receives a `claim_lost` notification with reason `'preempted'`, and
88
+ * the committer takes the lease ahead of anyone already waiting in line for
89
+ * it. Return it only for a committer you consider higher priority — for
90
+ * example, a supervisor over its own sub-agents, or an identity that holds a
91
+ * preempt capability. At commit time there is no holder to evict, so a
92
+ * `preempt` decision is treated as `allow`.
90
93
  */
91
94
  | {
92
95
  readonly action: 'preempt';
93
96
  readonly reason?: string;
94
97
  }
95
98
  /**
96
- * Notify-instead-of-abort (non-coercion). Only meaningful for a
97
- * `stale_context` conflict, and the engine's aligned disposition: HOLD the
98
- * conflicting op (don't write it) and return a `StaleNotification` with the
99
- * current value so the actor (agent or human) resolves and re-commits. The
100
- * rest of the batch still commits. Maps from `onStale: 'notify'`.
99
+ * Hold the write instead of aborting it. This is only meaningful for a
100
+ * `stale_context` conflict. The engine withholds the conflicting operation
101
+ * and returns a `StaleNotification` carrying the current value, so the actor
102
+ * an agent or a human can reconcile and re-commit. The rest of the batch
103
+ * still commits. It maps from `onStale: 'notify'`.
101
104
  *
102
- * Serialization order is supplied by the monotonic `sync_id` landing order
103
- * (the stale committer always yields/recomputes an asymmetry that rules out
104
- * a symmetric notify-rewrite livelock). Unbounded retry is bounded by the
105
- * client's reconciliation retry cap.
105
+ * The monotonic `sync_id` landing order decides who yields: the stale
106
+ * committer always recomputes against the newer value, an asymmetry that
107
+ * prevents two notifying writers from looping against each other. Retries are
108
+ * bounded by the client's reconciliation retry cap.
106
109
  */
107
110
  | {
108
111
  readonly action: 'notify';
109
112
  readonly reason?: string;
110
113
  };
111
114
  /**
112
- * Pluggable decision function. Sync or async.
115
+ * The function that decides a conflict. It receives a {@link Conflict} and
116
+ * returns a {@link ConflictDecision}, either synchronously or as a promise.
117
+ * Register your implementation with the engine; the example below allows a
118
+ * cosmetic "linter" writer and defers everything else to {@link defaultPolicy}.
113
119
  *
114
120
  * ```ts
115
121
  * const policy: ConflictPolicy = (conflict) => {
@@ -122,64 +128,61 @@ export type ConflictDecision = {
122
128
  */
123
129
  export type ConflictPolicy = (conflict: Conflict) => ConflictDecision | Promise<ConflictDecision>;
124
130
  /**
125
- * Default policy **Law 7 (the human is the principal) is the engine-wide
126
- * default, not an opt-in.**
131
+ * The conflict policy the engine uses when you do not supply your own. It
132
+ * favors people: a human is never blocked, while agents and automated writers
133
+ * yield to a claim someone else holds.
127
134
  *
128
- * A `claim_held` conflict resolves by the COMMITTER's kind. This default is, by
129
- * construction, identical to `coordination(humansOverwrite())` applied to every
130
- * model — so a developer who wants different behaviour just declares the conflict
131
- * axis on that model (`humansReject()`, `humansNotify()`, `systemOverwrite()`, …)
132
- * and it wins. The default and the override speak the same vocabulary; the
133
- * default is the one you get for free.
135
+ * For a `claim_held` conflict, the decision follows the committer's kind:
134
136
  *
135
- * • `user` → `allow` — a human is never blocked by a claim (a claim is a
136
- * coordination hint among agents, not a lock on people)
137
- * • `agent` → `reject` — an agent yields to a foreign claim (the no-bypass
138
- * invariant; the ONLY sanctioned agent override is the
139
- * privileged `claim.preempt` capability seam, see
140
- * {@link capabilityPreemptPolicy})
141
- * `system` → `reject` — automation / backend (`sk_`) writers SERIALIZE
142
- * through claims by default like agents do, so a server
143
- * job can't silently steamroll a held row. Opt a model
144
- * in with `systemOverwrite()` when that's wanted.
137
+ * • `user` → `allow` — a human is never blocked by a claim. A claim is a
138
+ * coordination hint among agents, not a lock on
139
+ * people.
140
+ * `agent` → `reject` an agent yields to a claim held by someone else.
141
+ * The one sanctioned exception is the privileged
142
+ * `claim.preempt` capability; see
143
+ * {@link capabilityPreemptPolicy}.
144
+ * `system` `reject` automated and backend writers serialize through
145
+ * claims the same way agents do, so a server job
146
+ * cannot silently overwrite a held row. Declare the
147
+ * model's conflict axis to overwrite if you want that.
145
148
  *
146
- * Scope note: only `user` is allowed by default that is the exact Law 7
147
- * decision ("a human is never blocked"). `system` is deliberately NOT a
148
- * free-bypass: `sk_` keys are full-access backend credentials, and a foundational
149
- * contract (claim serialization / the retry-storm guard) depends on them
150
- * respecting claims unless a model says otherwise.
149
+ * Allowing only `user` by default is deliberate: a backend key is a
150
+ * full-access credential, and claim serialization depends on those writers
151
+ * respecting claims unless a model opts out.
151
152
  *
152
- * `stale_context` conflicts honor the committer's declared `onStale` intent:
153
+ * For a `stale_context` conflict, the decision honors the committer's declared
154
+ * `onStale` intent: `'notify'` holds the write and notifies the actor to
155
+ * resolve it, and anything else (including `'reject'` or an absent value)
156
+ * rejects. An `onStale` of `'overwrite'` never reaches a policy — it is a hard
157
+ * opt-out resolved before the conflict is detected.
153
158
  *
154
- * `'notify'` notify + hold (op withheld; the actor resolves)
155
- * anything else (incl. `'reject'`, absent) → reject
156
- *
157
- * `'overwrite'` never reaches a policy on the stale path — it's a hard opt-out
158
- * resolved before detection.
159
+ * To change this behavior for a model, declare its conflict axis in the schema;
160
+ * a declared axis overrides this default.
159
161
  */
160
162
  export declare const defaultPolicy: (conflict: Conflict) => ConflictDecision;
161
163
  /**
162
- * Capability-gated preemption. An `claim_held` conflict is PREEMPTED when the
163
- * committer holds the `claim.preempt` operation in its capability allowlist
164
- * (the holder is evicted, the committer takes the lease); everything else falls
165
- * back to `defaultPolicy` (reject). Opt-in wire it as a `conflictPolicies`
166
- * global to let a privileged identity jump a held entity without a bespoke
167
- * policy. The authorization is the capability, not an identity string.
164
+ * A ready-made policy that grants capability-gated preemption. When the
165
+ * committer's capability allowlist includes the `claim.preempt` operation, a
166
+ * `claim_held` conflict is preempted: the current holder is evicted and the
167
+ * committer takes the lease. Every other conflict falls back to
168
+ * {@link defaultPolicy}, which rejects. Register it as your conflict policy to
169
+ * let a privileged identity take over a held entity without writing a bespoke
170
+ * policy. The authorization rests on holding the capability, not on any
171
+ * particular identity string.
168
172
  */
169
173
  export declare const capabilityPreemptPolicy: ConflictPolicy;
170
174
  /**
171
- * **Axis 3 declared write-conflict disposition, per committer kind.**
172
- *
173
- * A model declares this in its schema (`conflict: { user: 'overwrite', agent:
174
- * 'reject' }`); the generic engine interprets it at the commit chokepoint. It's
175
- * pure data the same `OnStaleMode` vocabulary used by write guards
176
- * (`'reject' | 'overwrite' | 'notify'`) so it serializes through the schema
177
- * registry to the schema-agnostic server, which names no app model.
175
+ * A model's declared conflict disposition, keyed by the kind of committer. You
176
+ * set it in the model's schema, for example
177
+ * `conflict: { user: 'overwrite', agent: 'reject' }`, and the engine applies it
178
+ * at commit time. It is plain data using the same `'reject' | 'overwrite' |
179
+ * 'notify'` vocabulary as the write guards, so it travels through the schema
180
+ * registry to the server without naming any application model.
178
181
  *
179
- * Keys are the COMMITTER's participant kind (server-derived, forge-proof): an
180
- * omitted kind falls through to the engine default. So `{ user: 'overwrite',
181
- * agent: 'reject' }` reads "a human's write wins (never blocked); an agent's
182
- * write yields", and `system` (unlisted) takes the default.
182
+ * Each key is the committer's participant kind, which the server derives and a
183
+ * client cannot forge; an omitted kind falls back to the engine default. So
184
+ * `{ user: 'overwrite', agent: 'reject' }` reads as "a human's write wins, an
185
+ * agent's write yields," and `system`, being unlisted, takes the default.
183
186
  */
184
187
  export interface ConflictAxis {
185
188
  /** What happens when a human (`user` session) commits into a conflict. */
@@ -190,24 +193,25 @@ export interface ConflictAxis {
190
193
  readonly system?: OnStaleMode;
191
194
  }
192
195
  /**
193
- * Interpret a declared {@link ConflictAxis} for a concrete conflict — pure and
194
- * synchronous (no I/O), so it runs on either side of the schema-agnostic
195
- * boundary. Looks up the committer's kind and maps the declared `OnStaleMode`:
196
+ * Resolves a declared {@link ConflictAxis} into a {@link ConflictDecision} for
197
+ * one concrete conflict. It is pure and synchronous, doing no I/O, so it can
198
+ * run on either the client or the server. It reads the committer's kind from
199
+ * the conflict and maps the declared mode:
196
200
  *
197
- * - undefined → the engine default (`defaultPolicy`: Law 7 — a human (`user`)
198
- * committer is allowed (never blocked); `agent` and `system`
199
- * reject on a `claim_held`; on a stale write, honor
200
- * `onStale: 'notify'`)
201
- * - `overwrite` → `allow` the write wins / the committer is never blocked
202
- * - `reject` → `reject` the committer yields
203
- * - `notify` → on `stale_context`: notify + hold (re-read & re-apply);
204
- * on `claim_held`: notify has no held op to reconcile against
205
- * (see {@link ConflictDecision} `notify`), so degrade to
206
- * `reject` rather than silently allowing a claimed-row write.
201
+ * - undefined → the engine default, {@link defaultPolicy}: a human is
202
+ * allowed, an agent or system committer is rejected on a
203
+ * `claim_held`, and a stale write honors `onStale: 'notify'`.
204
+ * - `overwrite` `allow`; the write wins and the committer is never blocked.
205
+ * - `reject` → `reject`; the committer yields.
206
+ * - `notify` → on a `stale_context` conflict, hold the write and notify so
207
+ * the committer re-reads and re-applies; on a `claim_held`
208
+ * conflict there is no held write to reconcile (see
209
+ * {@link ConflictDecision} `notify`), so it degrades to
210
+ * `reject` rather than silently writing to a claimed row.
207
211
  *
208
- * NOTE: this is a generic interpretation only. Server-side invariants (e.g. an
209
- * agent may never bypass a foreign claim) are enforced where the decision is
210
- * applied, not here.
212
+ * This is only the generic interpretation. Stronger server-side rules such as
213
+ * an agent never bypassing a claim held by someone else — are enforced where
214
+ * the decision is applied, not here.
211
215
  */
212
216
  export declare function interpretConflictAxis(axis: ConflictAxis, conflict: Conflict): ConflictDecision;
213
217
  export {};
@@ -1,59 +1,57 @@
1
1
  /**
2
- * Conflict policy the engine detects, the policy decides.
2
+ * The conflict types a policy decides on. The engine detects a conflict and
3
+ * hands it to your {@link ConflictPolicy}, which returns a
4
+ * {@link ConflictDecision}.
3
5
  *
4
- * Two conflict shapes today: `stale_context` (a write whose `readAt`
5
- * is older than the latest delta on the target) and `claim_held`
6
- * (a participant claims a target someone else is already claiming).
7
- * Adding new shapes is additive on the discriminated union.
6
+ * There are two conflict shapes. A {@link StaleContextConflict} is a write
7
+ * whose `readAt` watermark is older than the latest delta on the target row. A
8
+ * {@link ClaimHeldConflict} is a participant trying to claim a target that
9
+ * someone else already holds. {@link Conflict} is the discriminated union of
10
+ * the two; switch on `kind` to narrow it.
8
11
  */
9
12
  /**
10
- * Default policy **Law 7 (the human is the principal) is the engine-wide
11
- * default, not an opt-in.**
13
+ * The conflict policy the engine uses when you do not supply your own. It
14
+ * favors people: a human is never blocked, while agents and automated writers
15
+ * yield to a claim someone else holds.
12
16
  *
13
- * A `claim_held` conflict resolves by the COMMITTER's kind. This default is, by
14
- * construction, identical to `coordination(humansOverwrite())` applied to every
15
- * model — so a developer who wants different behaviour just declares the conflict
16
- * axis on that model (`humansReject()`, `humansNotify()`, `systemOverwrite()`, …)
17
- * and it wins. The default and the override speak the same vocabulary; the
18
- * default is the one you get for free.
17
+ * For a `claim_held` conflict, the decision follows the committer's kind:
19
18
  *
20
- * • `user` → `allow` — a human is never blocked by a claim (a claim is a
21
- * coordination hint among agents, not a lock on people)
22
- * • `agent` → `reject` — an agent yields to a foreign claim (the no-bypass
23
- * invariant; the ONLY sanctioned agent override is the
24
- * privileged `claim.preempt` capability seam, see
25
- * {@link capabilityPreemptPolicy})
26
- * `system` → `reject` — automation / backend (`sk_`) writers SERIALIZE
27
- * through claims by default like agents do, so a server
28
- * job can't silently steamroll a held row. Opt a model
29
- * in with `systemOverwrite()` when that's wanted.
19
+ * • `user` → `allow` — a human is never blocked by a claim. A claim is a
20
+ * coordination hint among agents, not a lock on
21
+ * people.
22
+ * `agent` → `reject` an agent yields to a claim held by someone else.
23
+ * The one sanctioned exception is the privileged
24
+ * `claim.preempt` capability; see
25
+ * {@link capabilityPreemptPolicy}.
26
+ * `system` `reject` automated and backend writers serialize through
27
+ * claims the same way agents do, so a server job
28
+ * cannot silently overwrite a held row. Declare the
29
+ * model's conflict axis to overwrite if you want that.
30
30
  *
31
- * Scope note: only `user` is allowed by default that is the exact Law 7
32
- * decision ("a human is never blocked"). `system` is deliberately NOT a
33
- * free-bypass: `sk_` keys are full-access backend credentials, and a foundational
34
- * contract (claim serialization / the retry-storm guard) depends on them
35
- * respecting claims unless a model says otherwise.
31
+ * Allowing only `user` by default is deliberate: a backend key is a
32
+ * full-access credential, and claim serialization depends on those writers
33
+ * respecting claims unless a model opts out.
36
34
  *
37
- * `stale_context` conflicts honor the committer's declared `onStale` intent:
35
+ * For a `stale_context` conflict, the decision honors the committer's declared
36
+ * `onStale` intent: `'notify'` holds the write and notifies the actor to
37
+ * resolve it, and anything else (including `'reject'` or an absent value)
38
+ * rejects. An `onStale` of `'overwrite'` never reaches a policy — it is a hard
39
+ * opt-out resolved before the conflict is detected.
38
40
  *
39
- * `'notify'` notify + hold (op withheld; the actor resolves)
40
- * anything else (incl. `'reject'`, absent) → reject
41
- *
42
- * `'overwrite'` never reaches a policy on the stale path — it's a hard opt-out
43
- * resolved before detection.
41
+ * To change this behavior for a model, declare its conflict axis in the schema;
42
+ * a declared axis overrides this default.
44
43
  */
45
- // Typed by its real SYNCHRONOUS shape (via `satisfies`) rather than the
46
- // async-permissive `ConflictPolicy` alias, so sync callers like
47
- // `interpretConflictAxis` and `capabilityPreemptPolicy` get a plain
48
- // `ConflictDecision` back (not `… | Promise<…>`). Still assignable to
49
- // `ConflictPolicy` everywhere it's used as a policy.
44
+ // Typed by its real synchronous shape with `satisfies`, rather than the
45
+ // async-permissive `ConflictPolicy` alias, so synchronous callers such as
46
+ // `interpretConflictAxis` and `capabilityPreemptPolicy` receive a plain
47
+ // `ConflictDecision` rather than `ConflictDecision | Promise<…>`. It remains
48
+ // assignable to `ConflictPolicy` wherever it is used as one.
50
49
  export const defaultPolicy = ((conflict) => {
51
50
  if (conflict.kind === 'claim_held') {
52
- // Law 7 universal default: a human (`user`) is never blocked; agents AND
53
- // system actors yield. Keeping every non-`user` kind on `reject` here is
54
- // what makes the no-bypass invariant hold even on the registry/default
55
- // resolution path (which, unlike the declared-axis path, has no separate
56
- // agent-degradation guard).
51
+ // A human (`user`) is never blocked; agents and system actors yield.
52
+ // Keeping every non-`user` kind on `reject` here ensures an agent cannot
53
+ // bypass a claim even on this default resolution path, which — unlike the
54
+ // declared-axis path has no separate agent guard of its own.
57
55
  return conflict.committer.kind === 'user'
58
56
  ? { action: 'allow', note: 'principal:not-blocked' }
59
57
  : { action: 'reject', reason: 'claim_conflict' };
@@ -63,12 +61,14 @@ export const defaultPolicy = ((conflict) => {
63
61
  : { action: 'reject', reason: 'stale_context' };
64
62
  });
65
63
  /**
66
- * Capability-gated preemption. An `claim_held` conflict is PREEMPTED when the
67
- * committer holds the `claim.preempt` operation in its capability allowlist
68
- * (the holder is evicted, the committer takes the lease); everything else falls
69
- * back to `defaultPolicy` (reject). Opt-in wire it as a `conflictPolicies`
70
- * global to let a privileged identity jump a held entity without a bespoke
71
- * policy. The authorization is the capability, not an identity string.
64
+ * A ready-made policy that grants capability-gated preemption. When the
65
+ * committer's capability allowlist includes the `claim.preempt` operation, a
66
+ * `claim_held` conflict is preempted: the current holder is evicted and the
67
+ * committer takes the lease. Every other conflict falls back to
68
+ * {@link defaultPolicy}, which rejects. Register it as your conflict policy to
69
+ * let a privileged identity take over a held entity without writing a bespoke
70
+ * policy. The authorization rests on holding the capability, not on any
71
+ * particular identity string.
72
72
  */
73
73
  export const capabilityPreemptPolicy = (conflict) => {
74
74
  if (conflict.kind === 'claim_held' &&
@@ -78,24 +78,25 @@ export const capabilityPreemptPolicy = (conflict) => {
78
78
  return defaultPolicy(conflict);
79
79
  };
80
80
  /**
81
- * Interpret a declared {@link ConflictAxis} for a concrete conflict — pure and
82
- * synchronous (no I/O), so it runs on either side of the schema-agnostic
83
- * boundary. Looks up the committer's kind and maps the declared `OnStaleMode`:
81
+ * Resolves a declared {@link ConflictAxis} into a {@link ConflictDecision} for
82
+ * one concrete conflict. It is pure and synchronous, doing no I/O, so it can
83
+ * run on either the client or the server. It reads the committer's kind from
84
+ * the conflict and maps the declared mode:
84
85
  *
85
- * - undefined → the engine default (`defaultPolicy`: Law 7 — a human (`user`)
86
- * committer is allowed (never blocked); `agent` and `system`
87
- * reject on a `claim_held`; on a stale write, honor
88
- * `onStale: 'notify'`)
89
- * - `overwrite` → `allow` the write wins / the committer is never blocked
90
- * - `reject` → `reject` the committer yields
91
- * - `notify` → on `stale_context`: notify + hold (re-read & re-apply);
92
- * on `claim_held`: notify has no held op to reconcile against
93
- * (see {@link ConflictDecision} `notify`), so degrade to
94
- * `reject` rather than silently allowing a claimed-row write.
86
+ * - undefined → the engine default, {@link defaultPolicy}: a human is
87
+ * allowed, an agent or system committer is rejected on a
88
+ * `claim_held`, and a stale write honors `onStale: 'notify'`.
89
+ * - `overwrite` `allow`; the write wins and the committer is never blocked.
90
+ * - `reject` → `reject`; the committer yields.
91
+ * - `notify` → on a `stale_context` conflict, hold the write and notify so
92
+ * the committer re-reads and re-applies; on a `claim_held`
93
+ * conflict there is no held write to reconcile (see
94
+ * {@link ConflictDecision} `notify`), so it degrades to
95
+ * `reject` rather than silently writing to a claimed row.
95
96
  *
96
- * NOTE: this is a generic interpretation only. Server-side invariants (e.g. an
97
- * agent may never bypass a foreign claim) are enforced where the decision is
98
- * applied, not here.
97
+ * This is only the generic interpretation. Stronger server-side rules such as
98
+ * an agent never bypassing a claim held by someone else — are enforced where
99
+ * the decision is applied, not here.
99
100
  */
100
101
  export function interpretConflictAxis(axis, conflict) {
101
102
  const mode = axis[conflict.committer.kind];
@@ -1,17 +1,18 @@
1
1
  /**
2
- * HTTP client for the generic /sync/query endpoint.
2
+ * The HTTP client for the sync query endpoint.
3
3
  *
4
- * Thin wrapper over fetch() that:
5
- * - POSTs a QueryBatch as JSON
6
- * - Sends the bearer credential via withAuthHeaders (Authorization header)
7
- * - Throws on non-2xx responses
8
- * - Parses the response into a typed QueryBatchResult
4
+ * {@link postQuery} is a small wrapper over `fetch` that POSTs a
5
+ * {@link QueryBatch} as JSON to `/sync/query`, attaches the bearer credential
6
+ * as an `Authorization` header, and parses the response into a typed
7
+ * {@link QueryBatchResult}. An HTTP failure is not thrown: it is logged, and
8
+ * every query in the batch comes back with an empty result, so a
9
+ * fire-and-forget caller cannot crash on an unhandled rejection.
9
10
  *
10
- * The higher-level BootstrapHelper methods (fetchDeckSlideLayers,
11
- * fetchChatMessages, etc.) use this to issue structured queries
12
- * without duplicating the fetch boilerplate.
11
+ * Higher-level query helpers build on this to issue structured queries without
12
+ * repeating the fetch and error-handling boilerplate.
13
13
  */
14
14
  import type { QueryBatch, QueryBatchResult } from './types.js';
15
+ import { type RecoveryClass } from '../errorCodes.js';
15
16
  import { type AuthTokenGetter } from '../auth/credentialSource.js';
16
17
  export interface PostQueryOptions {
17
18
  /**
@@ -29,17 +30,32 @@ export interface PostQueryOptions {
29
30
  */
30
31
  getAuthToken?: AuthTokenGetter;
31
32
  /**
32
- * Compatibility fallback for callers that have only a copied token string.
33
- * New SDK internals should pass `getAuthToken`.
33
+ * A fixed credential string, for callers that hold only a copied token.
34
+ * Prefer `getAuthToken`, which is re-read on each request so a refresh takes
35
+ * effect without rebuilding the client.
34
36
  */
35
37
  capabilityToken?: string;
38
+ /**
39
+ * An optional hook that tries to recover from a rejected credential. When a
40
+ * query comes back with a 401, its {@link RecoveryClass} is passed here: a
41
+ * return of `'retry'` means a fresh credential has been obtained and the
42
+ * request is replayed exactly once, while `'stop'` ends the attempt. Because
43
+ * the replay happens at most once, a wedged credential cannot cause a retry
44
+ * loop. When this hook is absent, a 401 is logged and returns empty results
45
+ * like any other failure.
46
+ */
47
+ recoverCredential?: (recovery: RecoveryClass) => Promise<'retry' | 'stop'>;
36
48
  }
37
49
  /**
38
- * POST a batch of queries to /sync/query. Returns the parsed
39
- * QueryBatchResult. Throws a descriptive error on HTTP failure.
50
+ * Sends a batch of queries to `/sync/query` and returns the parsed
51
+ * {@link QueryBatchResult}. An HTTP failure is not thrown: it is logged, and
52
+ * every query in the batch comes back with an empty result, which keeps a
53
+ * fire-and-forget caller from crashing on an unhandled rejection. A 401 may
54
+ * first be handed to {@link PostQueryOptions.recoverCredential} for a single
55
+ * retry.
40
56
  *
41
- * The server guarantees results[i] corresponds to queries[i] in the
42
- * request callers can rely on index alignment to extract typed
43
- * results from a multi-query batch.
57
+ * The response preserves order: `results[i]` corresponds to the query at
58
+ * `queries[i]`, so callers can rely on index alignment to pull typed results
59
+ * out of a multi-query batch.
44
60
  */
45
61
  export declare function postQuery(options: PostQueryOptions, batch: QueryBatch): Promise<QueryBatchResult>;