@abloatai/ablo 0.36.0 → 0.37.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 (597) hide show
  1. package/AGENTS.md +2 -2
  2. package/CHANGELOG.md +71 -2013
  3. package/NOTICE +2 -2
  4. package/README.md +25 -71
  5. package/assets/banner.png +0 -0
  6. package/dist/auth.d.ts +2 -0
  7. package/dist/auth.d.ts.map +1 -0
  8. package/dist/auth.js +2 -0
  9. package/dist/auth.js.map +1 -0
  10. package/dist/client.d.ts +3 -0
  11. package/dist/client.d.ts.map +1 -0
  12. package/dist/client.js +3 -0
  13. package/dist/client.js.map +1 -0
  14. package/dist/coordination.d.ts +2 -0
  15. package/dist/coordination.d.ts.map +1 -0
  16. package/dist/coordination.js +2 -0
  17. package/dist/coordination.js.map +1 -0
  18. package/dist/index.d.ts +3 -114
  19. package/dist/index.d.ts.map +1 -0
  20. package/dist/index.js +3 -163
  21. package/dist/index.js.map +1 -0
  22. package/dist/react.d.ts +4 -0
  23. package/dist/react.d.ts.map +1 -0
  24. package/dist/react.js +3 -0
  25. package/dist/react.js.map +1 -0
  26. package/dist/schema.d.ts +2 -0
  27. package/dist/schema.d.ts.map +1 -0
  28. package/dist/schema.js +2 -0
  29. package/dist/schema.js.map +1 -0
  30. package/dist/server.d.ts +2 -0
  31. package/dist/server.d.ts.map +1 -0
  32. package/dist/server.js +2 -0
  33. package/dist/server.js.map +1 -0
  34. package/dist/source-conformance.d.ts +2 -0
  35. package/dist/source-conformance.d.ts.map +1 -0
  36. package/dist/source-conformance.js +2 -0
  37. package/dist/source-conformance.js.map +1 -0
  38. package/dist/source-drizzle.d.ts +2 -0
  39. package/dist/source-drizzle.d.ts.map +1 -0
  40. package/dist/source-drizzle.js +2 -0
  41. package/dist/source-drizzle.js.map +1 -0
  42. package/dist/source-kysely.d.ts +2 -0
  43. package/dist/source-kysely.d.ts.map +1 -0
  44. package/dist/source-kysely.js +2 -0
  45. package/dist/source-kysely.js.map +1 -0
  46. package/dist/source-next.d.ts +2 -0
  47. package/dist/source-next.d.ts.map +1 -0
  48. package/dist/source-next.js +2 -0
  49. package/dist/source-next.js.map +1 -0
  50. package/dist/source.d.ts +2 -0
  51. package/dist/source.d.ts.map +1 -0
  52. package/dist/source.js +2 -0
  53. package/dist/source.js.map +1 -0
  54. package/dist/wire.d.ts +2 -0
  55. package/dist/wire.d.ts.map +1 -0
  56. package/dist/wire.js +2 -0
  57. package/dist/wire.js.map +1 -0
  58. package/docs/agents.md +1 -1
  59. package/docs/api-keys.md +7 -6
  60. package/docs/api.md +10 -10
  61. package/docs/client-behavior.md +5 -5
  62. package/docs/coordination.md +52 -62
  63. package/docs/data-sources.md +1 -1
  64. package/docs/examples/agent-human.md +4 -4
  65. package/docs/examples/ai-sdk-tool.md +1 -1
  66. package/docs/examples/existing-python-backend.md +15 -4
  67. package/docs/examples/nextjs.md +27 -6
  68. package/docs/examples/server-agent.md +2 -2
  69. package/docs/how-it-works.md +4 -4
  70. package/docs/identity.md +2 -1
  71. package/docs/integration-guide.md +24 -13
  72. package/docs/internal/README.md +18 -0
  73. package/docs/internal/agent-fleet-coordination-design.md +171 -0
  74. package/docs/internal/agent-orchestration.md +58 -0
  75. package/docs/internal/commit-identifiers.md +91 -0
  76. package/docs/internal/concurrency-open-decisions.md +37 -0
  77. package/docs/internal/data-source-reverse-channel.md +150 -0
  78. package/docs/internal/per-field-conflict-detection.md +165 -0
  79. package/docs/internal/postgres-replication.md +64 -0
  80. package/docs/internal/serializable-schema.md +119 -0
  81. package/docs/internal/structure.md +32 -0
  82. package/docs/mcp.md +2 -2
  83. package/docs/migration.md +3 -3
  84. package/docs/quickstart.md +2 -2
  85. package/docs/react.md +5 -5
  86. package/docs/schema-contract.md +3 -3
  87. package/docs/sessions.md +91 -37
  88. package/examples/README.md +2 -2
  89. package/examples/data-source/README.md +1 -1
  90. package/examples/data-source/ablo-driver.ts +1 -1
  91. package/examples/data-source/customer-server.ts +1 -1
  92. package/examples/data-source/run.ts +1 -1
  93. package/examples/data-source/schema.ts +1 -1
  94. package/examples/quickstart.ts +2 -2
  95. package/llms.txt +8 -8
  96. package/package.json +63 -166
  97. package/bin/ablo.cjs +0 -39
  98. package/dist/BaseSyncedStore.d.ts +0 -843
  99. package/dist/BaseSyncedStore.js +0 -1971
  100. package/dist/Database.d.ts +0 -323
  101. package/dist/Database.js +0 -1502
  102. package/dist/InstanceCache.d.ts +0 -237
  103. package/dist/InstanceCache.js +0 -1166
  104. package/dist/LazyReferenceCollection.d.ts +0 -177
  105. package/dist/LazyReferenceCollection.js +0 -461
  106. package/dist/Model.d.ts +0 -454
  107. package/dist/Model.js +0 -919
  108. package/dist/ModelRegistry.d.ts +0 -225
  109. package/dist/ModelRegistry.js +0 -539
  110. package/dist/NetworkMonitor.d.ts +0 -28
  111. package/dist/NetworkMonitor.js +0 -79
  112. package/dist/RuntimeContext.d.ts +0 -52
  113. package/dist/RuntimeContext.js +0 -80
  114. package/dist/SyncClient.d.ts +0 -541
  115. package/dist/SyncClient.js +0 -2202
  116. package/dist/adapters/alwaysOnline.d.ts +0 -14
  117. package/dist/adapters/alwaysOnline.js +0 -17
  118. package/dist/adapters/inMemoryStorage.d.ts +0 -31
  119. package/dist/adapters/inMemoryStorage.js +0 -110
  120. package/dist/ai-sdk/coordinatedTool.d.ts +0 -120
  121. package/dist/ai-sdk/coordinatedTool.js +0 -134
  122. package/dist/ai-sdk/coordinationContext.d.ts +0 -46
  123. package/dist/ai-sdk/coordinationContext.js +0 -106
  124. package/dist/ai-sdk/index.d.ts +0 -121
  125. package/dist/ai-sdk/index.js +0 -121
  126. package/dist/ai-sdk/wrap.d.ts +0 -65
  127. package/dist/ai-sdk/wrap.js +0 -39
  128. package/dist/auth/index.d.ts +0 -1
  129. package/dist/auth/index.js +0 -8
  130. package/dist/batching/index.d.ts +0 -55
  131. package/dist/batching/index.js +0 -147
  132. package/dist/client/Ablo.d.ts +0 -231
  133. package/dist/client/Ablo.js +0 -160
  134. package/dist/client/abloClient.d.ts +0 -309
  135. package/dist/client/abloClient.js +0 -13
  136. package/dist/client/clientPrelude.d.ts +0 -52
  137. package/dist/client/clientPrelude.js +0 -60
  138. package/dist/client/consoleLogger.d.ts +0 -35
  139. package/dist/client/consoleLogger.js +0 -44
  140. package/dist/client/coreClient.d.ts +0 -60
  141. package/dist/client/coreClient.js +0 -118
  142. package/dist/client/createInternalComponents.d.ts +0 -50
  143. package/dist/client/createInternalComponents.js +0 -98
  144. package/dist/client/createModelProxy.d.ts +0 -248
  145. package/dist/client/createModelProxy.js +0 -884
  146. package/dist/client/humans.d.ts +0 -69
  147. package/dist/client/humans.js +0 -78
  148. package/dist/client/modelRegistration.d.ts +0 -10
  149. package/dist/client/modelRegistration.js +0 -312
  150. package/dist/client/options.d.ts +0 -461
  151. package/dist/client/options.js +0 -7
  152. package/dist/client/reactiveEngine.d.ts +0 -53
  153. package/dist/client/reactiveEngine.js +0 -688
  154. package/dist/client/resourceTypes.d.ts +0 -12
  155. package/dist/client/resourceTypes.js +0 -10
  156. package/dist/client/schemaConfig.d.ts +0 -44
  157. package/dist/client/schemaConfig.js +0 -185
  158. package/dist/client/storeCluster.d.ts +0 -47
  159. package/dist/client/storeCluster.js +0 -118
  160. package/dist/client/storeLifecycle.d.ts +0 -61
  161. package/dist/client/storeLifecycle.js +0 -231
  162. package/dist/client/validateAbloOptions.d.ts +0 -42
  163. package/dist/client/validateAbloOptions.js +0 -43
  164. package/dist/client/wsMutationExecutor.d.ts +0 -27
  165. package/dist/client/wsMutationExecutor.js +0 -72
  166. package/dist/context.d.ts +0 -42
  167. package/dist/context.js +0 -81
  168. package/dist/coordination/ClaimLog.d.ts +0 -26
  169. package/dist/coordination/ClaimLog.js +0 -32
  170. package/dist/coordination/index.d.ts +0 -1
  171. package/dist/coordination/index.js +0 -8
  172. package/dist/core/index.d.ts +0 -33
  173. package/dist/core/index.js +0 -48
  174. package/dist/docs/catalog.d.ts +0 -72
  175. package/dist/docs/catalog.js +0 -230
  176. package/dist/docs/index.d.ts +0 -10
  177. package/dist/docs/index.js +0 -10
  178. package/dist/environment.d.ts +0 -1
  179. package/dist/environment.js +0 -8
  180. package/dist/interfaces/index.d.ts +0 -311
  181. package/dist/interfaces/index.js +0 -9
  182. package/dist/keys/index.d.ts +0 -1
  183. package/dist/keys/index.js +0 -8
  184. package/dist/mutators/RecordingMutation.d.ts +0 -36
  185. package/dist/mutators/RecordingMutation.js +0 -182
  186. package/dist/mutators/Transaction.d.ts +0 -40
  187. package/dist/mutators/Transaction.js +0 -58
  188. package/dist/mutators/UndoManager.d.ts +0 -258
  189. package/dist/mutators/UndoManager.js +0 -658
  190. package/dist/mutators/defineMutators.d.ts +0 -60
  191. package/dist/mutators/defineMutators.js +0 -18
  192. package/dist/mutators/inverseOp.d.ts +0 -126
  193. package/dist/mutators/inverseOp.js +0 -71
  194. package/dist/mutators/mutateActions.d.ts +0 -45
  195. package/dist/mutators/mutateActions.js +0 -105
  196. package/dist/mutators/readerActions.d.ts +0 -33
  197. package/dist/mutators/readerActions.js +0 -57
  198. package/dist/mutators/undoApply.d.ts +0 -51
  199. package/dist/mutators/undoApply.js +0 -117
  200. package/dist/policy/index.d.ts +0 -21
  201. package/dist/policy/index.js +0 -20
  202. package/dist/query/QueryProcessor.d.ts +0 -75
  203. package/dist/query/QueryProcessor.js +0 -255
  204. package/dist/query/client.d.ts +0 -64
  205. package/dist/query/client.js +0 -138
  206. package/dist/query/types.d.ts +0 -85
  207. package/dist/query/types.js +0 -16
  208. package/dist/react/AbloProvider.d.ts +0 -242
  209. package/dist/react/AbloProvider.js +0 -458
  210. package/dist/react/ClientSideSuspense.d.ts +0 -36
  211. package/dist/react/ClientSideSuspense.js +0 -17
  212. package/dist/react/DefaultFallback.d.ts +0 -24
  213. package/dist/react/DefaultFallback.js +0 -43
  214. package/dist/react/context.d.ts +0 -55
  215. package/dist/react/context.js +0 -29
  216. package/dist/react/createAbloReact.d.ts +0 -56
  217. package/dist/react/createAbloReact.js +0 -51
  218. package/dist/react/index.d.ts +0 -62
  219. package/dist/react/index.js +0 -69
  220. package/dist/react/internalContext.d.ts +0 -33
  221. package/dist/react/internalContext.js +0 -3
  222. package/dist/react/useAblo.d.ts +0 -82
  223. package/dist/react/useAblo.js +0 -120
  224. package/dist/react/useCurrentUserId.d.ts +0 -22
  225. package/dist/react/useCurrentUserId.js +0 -34
  226. package/dist/react/useErrorListener.d.ts +0 -20
  227. package/dist/react/useErrorListener.js +0 -38
  228. package/dist/react/useMutationFailureListener.d.ts +0 -26
  229. package/dist/react/useMutationFailureListener.js +0 -38
  230. package/dist/react/useMutators.d.ts +0 -56
  231. package/dist/react/useMutators.js +0 -84
  232. package/dist/react/useReactive.d.ts +0 -35
  233. package/dist/react/useReactive.js +0 -123
  234. package/dist/react/useSyncStatus.d.ts +0 -59
  235. package/dist/react/useSyncStatus.js +0 -76
  236. package/dist/react/useUndoScope.d.ts +0 -34
  237. package/dist/react/useUndoScope.js +0 -81
  238. package/dist/schema/coordination.d.ts +0 -112
  239. package/dist/schema/coordination.js +0 -133
  240. package/dist/schema/ddl.d.ts +0 -97
  241. package/dist/schema/ddl.js +0 -491
  242. package/dist/schema/ddlLock.d.ts +0 -35
  243. package/dist/schema/ddlLock.js +0 -46
  244. package/dist/schema/diff.d.ts +0 -225
  245. package/dist/schema/diff.js +0 -289
  246. package/dist/schema/generate.d.ts +0 -19
  247. package/dist/schema/generate.js +0 -86
  248. package/dist/schema/index.d.ts +0 -42
  249. package/dist/schema/index.js +0 -80
  250. package/dist/schema/queries.d.ts +0 -201
  251. package/dist/schema/queries.js +0 -144
  252. package/dist/schema/select.d.ts +0 -40
  253. package/dist/schema/select.js +0 -90
  254. package/dist/schema/serialize.d.ts +0 -115
  255. package/dist/schema/serialize.js +0 -265
  256. package/dist/schema/sugar.d.ts +0 -109
  257. package/dist/schema/sugar.js +0 -83
  258. package/dist/schema/syncDeltaRow.d.ts +0 -6
  259. package/dist/schema/syncDeltaRow.js +0 -6
  260. package/dist/server/adapter.d.ts +0 -173
  261. package/dist/server/adapter.js +0 -18
  262. package/dist/server/commit.d.ts +0 -107
  263. package/dist/server/commit.js +0 -1
  264. package/dist/server/index.d.ts +0 -14
  265. package/dist/server/index.js +0 -2
  266. package/dist/server/readConfig.d.ts +0 -80
  267. package/dist/server/readConfig.js +0 -8
  268. package/dist/server/storageMode.d.ts +0 -23
  269. package/dist/server/storageMode.js +0 -17
  270. package/dist/source/adapter.d.ts +0 -83
  271. package/dist/source/adapter.js +0 -24
  272. package/dist/source/adapters/drizzle.d.ts +0 -48
  273. package/dist/source/adapters/drizzle.js +0 -219
  274. package/dist/source/adapters/kysely.d.ts +0 -42
  275. package/dist/source/adapters/kysely.js +0 -205
  276. package/dist/source/adapters/kyselyMutationCore.d.ts +0 -76
  277. package/dist/source/adapters/kyselyMutationCore.js +0 -125
  278. package/dist/source/adapters/memory.d.ts +0 -13
  279. package/dist/source/adapters/memory.js +0 -130
  280. package/dist/source/adapters/prisma.d.ts +0 -63
  281. package/dist/source/adapters/prisma.js +0 -202
  282. package/dist/source/conformance.d.ts +0 -37
  283. package/dist/source/conformance.js +0 -215
  284. package/dist/source/connector.d.ts +0 -95
  285. package/dist/source/connector.js +0 -266
  286. package/dist/source/connectorProtocol.d.ts +0 -154
  287. package/dist/source/connectorProtocol.js +0 -163
  288. package/dist/source/contract.d.ts +0 -195
  289. package/dist/source/contract.js +0 -164
  290. package/dist/source/factory.d.ts +0 -92
  291. package/dist/source/factory.js +0 -286
  292. package/dist/source/idempotency.d.ts +0 -61
  293. package/dist/source/idempotency.js +0 -144
  294. package/dist/source/index.d.ts +0 -23
  295. package/dist/source/index.js +0 -30
  296. package/dist/source/migrations.d.ts +0 -21
  297. package/dist/source/migrations.js +0 -103
  298. package/dist/source/next.d.ts +0 -32
  299. package/dist/source/next.js +0 -25
  300. package/dist/source/pushQueue.d.ts +0 -134
  301. package/dist/source/pushQueue.js +0 -256
  302. package/dist/source/signing.d.ts +0 -92
  303. package/dist/source/signing.js +0 -162
  304. package/dist/source/types.d.ts +0 -401
  305. package/dist/source/types.js +0 -59
  306. package/dist/storeContract.d.ts +0 -145
  307. package/dist/storeContract.js +0 -12
  308. package/dist/stores/DatabaseManager.d.ts +0 -107
  309. package/dist/stores/DatabaseManager.js +0 -388
  310. package/dist/stores/ObjectStore.d.ts +0 -115
  311. package/dist/stores/ObjectStore.js +0 -393
  312. package/dist/stores/ObjectStoreContract.d.ts +0 -38
  313. package/dist/stores/ObjectStoreContract.js +0 -1
  314. package/dist/stores/StoreManager.d.ts +0 -114
  315. package/dist/stores/StoreManager.js +0 -304
  316. package/dist/stores/SyncActionStore.d.ts +0 -99
  317. package/dist/stores/SyncActionStore.js +0 -506
  318. package/dist/stores/openIDBWithTimeout.d.ts +0 -65
  319. package/dist/stores/openIDBWithTimeout.js +0 -153
  320. package/dist/stores/syncAction.d.ts +0 -26
  321. package/dist/stores/syncAction.js +0 -16
  322. package/dist/surface.d.ts +0 -36
  323. package/dist/surface.js +0 -75
  324. package/dist/sync/BootstrapFetcher.d.ts +0 -284
  325. package/dist/sync/BootstrapFetcher.js +0 -964
  326. package/dist/sync/ConnectionManager.d.ts +0 -8
  327. package/dist/sync/ConnectionManager.js +0 -8
  328. package/dist/sync/OnDemandLoader.d.ts +0 -231
  329. package/dist/sync/OnDemandLoader.js +0 -743
  330. package/dist/sync/SubscriptionManager.d.ts +0 -159
  331. package/dist/sync/SubscriptionManager.js +0 -243
  332. package/dist/sync/SyncWebSocket.d.ts +0 -173
  333. package/dist/sync/SyncWebSocket.js +0 -438
  334. package/dist/sync/awaitClaimGrant.d.ts +0 -6
  335. package/dist/sync/awaitClaimGrant.js +0 -6
  336. package/dist/sync/bootstrapApply.d.ts +0 -73
  337. package/dist/sync/bootstrapApply.js +0 -73
  338. package/dist/sync/commitFrames.d.ts +0 -8
  339. package/dist/sync/commitFrames.js +0 -8
  340. package/dist/sync/contextPorts.d.ts +0 -18
  341. package/dist/sync/contextPorts.js +0 -31
  342. package/dist/sync/createClaimStream.d.ts +0 -7
  343. package/dist/sync/createClaimStream.js +0 -7
  344. package/dist/sync/createPresenceStream.d.ts +0 -69
  345. package/dist/sync/createPresenceStream.js +0 -200
  346. package/dist/sync/createSnapshot.d.ts +0 -29
  347. package/dist/sync/createSnapshot.js +0 -118
  348. package/dist/sync/credentialLifecycle.d.ts +0 -7
  349. package/dist/sync/credentialLifecycle.js +0 -7
  350. package/dist/sync/deltaPipeline.d.ts +0 -114
  351. package/dist/sync/deltaPipeline.js +0 -278
  352. package/dist/sync/groupChange.d.ts +0 -116
  353. package/dist/sync/groupChange.js +0 -244
  354. package/dist/sync/participants.d.ts +0 -132
  355. package/dist/sync/participants.js +0 -346
  356. package/dist/sync/persistedPrefix.d.ts +0 -12
  357. package/dist/sync/persistedPrefix.js +0 -22
  358. package/dist/sync/schemaDrift.d.ts +0 -55
  359. package/dist/sync/schemaDrift.js +0 -53
  360. package/dist/sync/schemas.d.ts +0 -71
  361. package/dist/sync/schemas.js +0 -94
  362. package/dist/sync/syncCursor.d.ts +0 -40
  363. package/dist/sync/syncCursor.js +0 -55
  364. package/dist/sync/syncPlan.d.ts +0 -54
  365. package/dist/sync/syncPlan.js +0 -50
  366. package/dist/sync/wsFrameHandlers.d.ts +0 -8
  367. package/dist/sync/wsFrameHandlers.js +0 -8
  368. package/dist/syncLog/contract.d.ts +0 -20
  369. package/dist/syncLog/contract.js +0 -19
  370. package/dist/syncLog/index.d.ts +0 -1
  371. package/dist/syncLog/index.js +0 -1
  372. package/dist/transaction/ablo.d.ts +0 -88
  373. package/dist/transaction/ablo.js +0 -33
  374. package/dist/transaction/auth/apiKey.d.ts +0 -152
  375. package/dist/transaction/auth/apiKey.js +0 -419
  376. package/dist/transaction/auth/bootstrapScope.d.ts +0 -15
  377. package/dist/transaction/auth/bootstrapScope.js +0 -1
  378. package/dist/transaction/auth/capability.d.ts +0 -212
  379. package/dist/transaction/auth/capability.js +0 -224
  380. package/dist/transaction/auth/credentialEndpoint.d.ts +0 -61
  381. package/dist/transaction/auth/credentialEndpoint.js +0 -86
  382. package/dist/transaction/auth/credentialPolicy.d.ts +0 -148
  383. package/dist/transaction/auth/credentialPolicy.js +0 -125
  384. package/dist/transaction/auth/credentialSource.d.ts +0 -30
  385. package/dist/transaction/auth/credentialSource.js +0 -55
  386. package/dist/transaction/auth/hostedEndpoints.d.ts +0 -21
  387. package/dist/transaction/auth/hostedEndpoints.js +0 -21
  388. package/dist/transaction/auth/identity.d.ts +0 -55
  389. package/dist/transaction/auth/identity.js +0 -210
  390. package/dist/transaction/auth/index.d.ts +0 -162
  391. package/dist/transaction/auth/index.js +0 -304
  392. package/dist/transaction/auth/schemas.d.ts +0 -59
  393. package/dist/transaction/auth/schemas.js +0 -85
  394. package/dist/transaction/auth/sessionMint.d.ts +0 -28
  395. package/dist/transaction/auth/sessionMint.js +0 -85
  396. package/dist/transaction/coordination/awaitClaimGrant.d.ts +0 -56
  397. package/dist/transaction/coordination/awaitClaimGrant.js +0 -124
  398. package/dist/transaction/coordination/claimHeartbeatLoop.d.ts +0 -84
  399. package/dist/transaction/coordination/claimHeartbeatLoop.js +0 -108
  400. package/dist/transaction/coordination/claimMeta.d.ts +0 -49
  401. package/dist/transaction/coordination/claimMeta.js +0 -52
  402. package/dist/transaction/coordination/createClaimStream.d.ts +0 -64
  403. package/dist/transaction/coordination/createClaimStream.js +0 -475
  404. package/dist/transaction/coordination/events.d.ts +0 -74
  405. package/dist/transaction/coordination/events.js +0 -7
  406. package/dist/transaction/coordination/index.d.ts +0 -19
  407. package/dist/transaction/coordination/index.js +0 -45
  408. package/dist/transaction/coordination/locator.d.ts +0 -104
  409. package/dist/transaction/coordination/locator.js +0 -102
  410. package/dist/transaction/coordination/schema.d.ts +0 -1536
  411. package/dist/transaction/coordination/schema.js +0 -1177
  412. package/dist/transaction/coordination/targetConflict.d.ts +0 -2
  413. package/dist/transaction/coordination/targetConflict.js +0 -107
  414. package/dist/transaction/coordination/trace.d.ts +0 -78
  415. package/dist/transaction/coordination/trace.js +0 -138
  416. package/dist/transaction/durableWrites.d.ts +0 -62
  417. package/dist/transaction/durableWrites.js +0 -71
  418. package/dist/transaction/environment.d.ts +0 -105
  419. package/dist/transaction/environment.js +0 -108
  420. package/dist/transaction/errorCodes.d.ts +0 -403
  421. package/dist/transaction/errorCodes.js +0 -484
  422. package/dist/transaction/errors.d.ts +0 -428
  423. package/dist/transaction/errors.js +0 -686
  424. package/dist/transaction/footprint.d.ts +0 -111
  425. package/dist/transaction/footprint.js +0 -0
  426. package/dist/transaction/index.d.ts +0 -20
  427. package/dist/transaction/index.js +0 -20
  428. package/dist/transaction/keys/index.d.ts +0 -87
  429. package/dist/transaction/keys/index.js +0 -207
  430. package/dist/transaction/log/syncDeltaRow.d.ts +0 -158
  431. package/dist/transaction/log/syncDeltaRow.js +0 -95
  432. package/dist/transaction/logPosition.d.ts +0 -97
  433. package/dist/transaction/logPosition.js +0 -125
  434. package/dist/transaction/logger.d.ts +0 -16
  435. package/dist/transaction/logger.js +0 -7
  436. package/dist/transaction/observability.d.ts +0 -53
  437. package/dist/transaction/observability.js +0 -19
  438. package/dist/transaction/persistence.d.ts +0 -12
  439. package/dist/transaction/persistence.js +0 -11
  440. package/dist/transaction/plugin.d.ts +0 -285
  441. package/dist/transaction/plugin.js +0 -106
  442. package/dist/transaction/policy/types.d.ts +0 -217
  443. package/dist/transaction/policy/types.js +0 -126
  444. package/dist/transaction/resources/functionalUpdate.d.ts +0 -79
  445. package/dist/transaction/resources/functionalUpdate.js +0 -87
  446. package/dist/transaction/resources/httpResources.d.ts +0 -321
  447. package/dist/transaction/resources/httpResources.js +0 -7
  448. package/dist/transaction/resources/modelOperations.d.ts +0 -427
  449. package/dist/transaction/resources/modelOperations.js +0 -12
  450. package/dist/transaction/resources/mutationOptions.d.ts +0 -66
  451. package/dist/transaction/resources/mutationOptions.js +0 -9
  452. package/dist/transaction/resources/where.d.ts +0 -101
  453. package/dist/transaction/resources/where.js +0 -115
  454. package/dist/transaction/resources/writeOptionsSchema.d.ts +0 -47
  455. package/dist/transaction/resources/writeOptionsSchema.js +0 -73
  456. package/dist/transaction/schema/field.d.ts +0 -120
  457. package/dist/transaction/schema/field.js +0 -265
  458. package/dist/transaction/schema/fieldRef.d.ts +0 -38
  459. package/dist/transaction/schema/fieldRef.js +0 -11
  460. package/dist/transaction/schema/loadStrategy.d.ts +0 -45
  461. package/dist/transaction/schema/loadStrategy.js +0 -46
  462. package/dist/transaction/schema/model.d.ts +0 -379
  463. package/dist/transaction/schema/model.js +0 -123
  464. package/dist/transaction/schema/openapi.d.ts +0 -58
  465. package/dist/transaction/schema/openapi.js +0 -501
  466. package/dist/transaction/schema/relation.d.ts +0 -204
  467. package/dist/transaction/schema/relation.js +0 -104
  468. package/dist/transaction/schema/residency.d.ts +0 -29
  469. package/dist/transaction/schema/residency.js +0 -25
  470. package/dist/transaction/schema/roles.d.ts +0 -249
  471. package/dist/transaction/schema/roles.js +0 -230
  472. package/dist/transaction/schema/schema.d.ts +0 -351
  473. package/dist/transaction/schema/schema.js +0 -325
  474. package/dist/transaction/schema/tenancy.d.ts +0 -139
  475. package/dist/transaction/schema/tenancy.js +0 -190
  476. package/dist/transaction/transactionLayer.d.ts +0 -82
  477. package/dist/transaction/transactionLayer.js +0 -24
  478. package/dist/transaction/transactions/settlement/commitEnvelope.d.ts +0 -143
  479. package/dist/transaction/transactions/settlement/commitEnvelope.js +0 -161
  480. package/dist/transaction/transactions/settlement/httpCommitEnvelope.d.ts +0 -53
  481. package/dist/transaction/transactions/settlement/httpCommitEnvelope.js +0 -207
  482. package/dist/transaction/transactions/settlement/idempotencyKey.d.ts +0 -10
  483. package/dist/transaction/transactions/settlement/idempotencyKey.js +0 -9
  484. package/dist/transaction/transactions/settlement/pendingWrite.d.ts +0 -112
  485. package/dist/transaction/transactions/settlement/pendingWrite.js +0 -20
  486. package/dist/transaction/transport/commitFrames.d.ts +0 -90
  487. package/dist/transaction/transport/commitFrames.js +0 -134
  488. package/dist/transaction/transport/connectionManager.d.ts +0 -215
  489. package/dist/transaction/transport/connectionManager.js +0 -673
  490. package/dist/transaction/transport/credentialLifecycle.d.ts +0 -177
  491. package/dist/transaction/transport/credentialLifecycle.js +0 -324
  492. package/dist/transaction/transport/heartbeat.d.ts +0 -65
  493. package/dist/transaction/transport/heartbeat.js +0 -93
  494. package/dist/transaction/transport/httpClient.d.ts +0 -131
  495. package/dist/transaction/transport/httpClient.js +0 -146
  496. package/dist/transaction/transport/httpOptions.d.ts +0 -33
  497. package/dist/transaction/transport/httpOptions.js +0 -12
  498. package/dist/transaction/transport/httpTransport.d.ts +0 -8
  499. package/dist/transaction/transport/httpTransport.js +0 -1388
  500. package/dist/transaction/transport/networkProbe.d.ts +0 -84
  501. package/dist/transaction/transport/networkProbe.js +0 -207
  502. package/dist/transaction/transport/wsFrameHandlers.d.ts +0 -128
  503. package/dist/transaction/transport/wsFrameHandlers.js +0 -429
  504. package/dist/transaction/transport/wsTransport.d.ts +0 -574
  505. package/dist/transaction/transport/wsTransport.js +0 -1023
  506. package/dist/transaction/types/assertExact.d.ts +0 -17
  507. package/dist/transaction/types/assertExact.js +0 -1
  508. package/dist/transaction/types/global.d.ts +0 -107
  509. package/dist/transaction/types/global.js +0 -40
  510. package/dist/transaction/types/index.d.ts +0 -205
  511. package/dist/transaction/types/index.js +0 -56
  512. package/dist/transaction/types/modelData.d.ts +0 -10
  513. package/dist/transaction/types/modelData.js +0 -9
  514. package/dist/transaction/types/participant.d.ts +0 -20
  515. package/dist/transaction/types/participant.js +0 -10
  516. package/dist/transaction/types/streams.d.ts +0 -550
  517. package/dist/transaction/types/streams.js +0 -11
  518. package/dist/transaction/utils/asyncIterator.d.ts +0 -34
  519. package/dist/transaction/utils/asyncIterator.js +0 -135
  520. package/dist/transaction/utils/duration.d.ts +0 -50
  521. package/dist/transaction/utils/duration.js +0 -77
  522. package/dist/transaction/utils/json.d.ts +0 -57
  523. package/dist/transaction/utils/json.js +0 -276
  524. package/dist/transaction/wire/accountResponses.d.ts +0 -420
  525. package/dist/transaction/wire/accountResponses.js +0 -290
  526. package/dist/transaction/wire/auth.d.ts +0 -56
  527. package/dist/transaction/wire/auth.js +0 -63
  528. package/dist/transaction/wire/bootstrapReason.d.ts +0 -9
  529. package/dist/transaction/wire/bootstrapReason.js +0 -8
  530. package/dist/transaction/wire/claimEvent.d.ts +0 -76
  531. package/dist/transaction/wire/claimEvent.js +0 -73
  532. package/dist/transaction/wire/claims.d.ts +0 -530
  533. package/dist/transaction/wire/claims.js +0 -327
  534. package/dist/transaction/wire/commit.d.ts +0 -603
  535. package/dist/transaction/wire/commit.js +0 -321
  536. package/dist/transaction/wire/delta.d.ts +0 -250
  537. package/dist/transaction/wire/delta.js +0 -147
  538. package/dist/transaction/wire/errorEnvelope.d.ts +0 -72
  539. package/dist/transaction/wire/errorEnvelope.js +0 -123
  540. package/dist/transaction/wire/feedCursor.d.ts +0 -60
  541. package/dist/transaction/wire/feedCursor.js +0 -82
  542. package/dist/transaction/wire/feedEvent.d.ts +0 -204
  543. package/dist/transaction/wire/feedEvent.js +0 -65
  544. package/dist/transaction/wire/frames.d.ts +0 -194
  545. package/dist/transaction/wire/frames.js +0 -50
  546. package/dist/transaction/wire/inboundFrames.d.ts +0 -562
  547. package/dist/transaction/wire/inboundFrames.js +0 -116
  548. package/dist/transaction/wire/index.d.ts +0 -54
  549. package/dist/transaction/wire/index.js +0 -83
  550. package/dist/transaction/wire/listEnvelope.d.ts +0 -37
  551. package/dist/transaction/wire/listEnvelope.js +0 -42
  552. package/dist/transaction/wire/modelMutations.d.ts +0 -31
  553. package/dist/transaction/wire/modelMutations.js +0 -52
  554. package/dist/transaction/wire/modelResponses.d.ts +0 -85
  555. package/dist/transaction/wire/modelResponses.js +0 -43
  556. package/dist/transaction/wire/modelShape.d.ts +0 -78
  557. package/dist/transaction/wire/modelShape.js +0 -74
  558. package/dist/transaction/wire/protocol.d.ts +0 -38
  559. package/dist/transaction/wire/protocol.js +0 -38
  560. package/dist/transaction/wire/protocolVersion.d.ts +0 -73
  561. package/dist/transaction/wire/protocolVersion.js +0 -83
  562. package/dist/transactions/mutations/MutationQueue.d.ts +0 -661
  563. package/dist/transactions/mutations/MutationQueue.js +0 -2807
  564. package/dist/transactions/mutations/MutationStore.d.ts +0 -20
  565. package/dist/transactions/mutations/MutationStore.js +0 -53
  566. package/dist/transactions/mutations/UnconfirmedWrites.d.ts +0 -82
  567. package/dist/transactions/mutations/UnconfirmedWrites.js +0 -104
  568. package/dist/transactions/mutations/coalesceRules.d.ts +0 -58
  569. package/dist/transactions/mutations/coalesceRules.js +0 -140
  570. package/dist/transactions/mutations/commitLatency.d.ts +0 -52
  571. package/dist/transactions/mutations/commitLatency.js +0 -130
  572. package/dist/transactions/mutations/commitOutboxStore.d.ts +0 -28
  573. package/dist/transactions/mutations/commitOutboxStore.js +0 -26
  574. package/dist/transactions/mutations/commitPayload.d.ts +0 -165
  575. package/dist/transactions/mutations/commitPayload.js +0 -152
  576. package/dist/transactions/mutations/deltaConfirmation.d.ts +0 -63
  577. package/dist/transactions/mutations/deltaConfirmation.js +0 -235
  578. package/dist/transactions/mutations/durableWriteStore.d.ts +0 -14
  579. package/dist/transactions/mutations/durableWriteStore.js +0 -12
  580. package/dist/transactions/mutations/optimisticApply.d.ts +0 -49
  581. package/dist/transactions/mutations/optimisticApply.js +0 -65
  582. package/dist/transactions/mutations/replayValidation.d.ts +0 -187
  583. package/dist/transactions/mutations/replayValidation.js +0 -164
  584. package/dist/utils/mobxSetup.d.ts +0 -53
  585. package/dist/utils/mobxSetup.js +0 -330
  586. package/dist/views/QueryView.d.ts +0 -79
  587. package/dist/views/QueryView.js +0 -218
  588. package/dist/views/ViewRegistry.d.ts +0 -20
  589. package/dist/views/ViewRegistry.js +0 -55
  590. package/dist/views/incrementalView.d.ts +0 -45
  591. package/dist/views/incrementalView.js +0 -69
  592. package/dist/webhooks/events.d.ts +0 -43
  593. package/dist/webhooks/events.js +0 -42
  594. package/dist/webhooks/index.d.ts +0 -8
  595. package/dist/webhooks/index.js +0 -8
  596. package/dist/wire/index.d.ts +0 -1
  597. package/dist/wire/index.js +0 -8
@@ -1,484 +0,0 @@
1
- /**
2
- * The registry of every stable error code Ablo can produce. Error handling has
3
- * two levels, and this file defines the finer one.
4
- *
5
- * - The `type` is the coarse category, and each one corresponds to an
6
- * {@link AbloError} subclass such as `AbloPermissionError` or
7
- * `AbloValidationError`. Catching by `instanceof` is equivalent to switching
8
- * on `error.type`.
9
- * - The `code` is the fine-grained, machine-readable identifier defined here,
10
- * written in `snake_case` (for example `entity_claimed` or `queue_too_deep`).
11
- * This is what you switch on to handle a specific situation, and what the
12
- * documentation link for an error is built from.
13
- *
14
- * The client, the server, and the tool-calling boundary all speak this same
15
- * vocabulary, which makes the registry part of the API contract. Two things
16
- * follow from that:
17
- *
18
- * 1. {@link ErrorCode} is a closed set — plus the dynamic `policy:${string}`
19
- * family — so producing a code that is not registered here is a
20
- * compile-time error. The {@link AbloError} constructor accepts only a
21
- * registered code. The one place an arbitrary string is accepted as a code
22
- * is where an incoming response is parsed, which lets an older client
23
- * tolerate a code from a newer server it does not yet recognize.
24
- * 2. The codes marked `surface: 'wire'` are the ones that cross the network
25
- * and are mapped at the HTTP and tool-calling boundaries; the public error
26
- * documentation is generated from them. Codes marked `surface: 'client'`
27
- * describe local mistakes — accessing the database before opening it, or
28
- * writing to a model that was never registered — and are never sent over
29
- * the network, so they carry no HTTP status.
30
- */
31
- import { z } from 'zod';
32
- /**
33
- * The version of the error contract: the envelope shape together with the set of
34
- * codes and their meanings. It is date-based, and changes only when the contract
35
- * changes in a way a consumer can observe — a code added or removed, an HTTP
36
- * status changed, or an envelope field changed. It is emitted in the generated
37
- * error documentation and returned on the `Ablo-Version` response header, so a
38
- * consumer can detect when its expected contract has drifted from the server's.
39
- */
40
- export const ERROR_CONTRACT_VERSION = '2026-07-23';
41
- /**
42
- * A closed classification of how a failure can be recovered from — a level above
43
- * the raw {@link ErrorCode}. Where a code says what went wrong, a recovery class
44
- * says what a client should do about it, which is exactly the distinction the
45
- * connection layer needs to decide between retrying, re-minting a credential, and
46
- * signing the user out. Every code maps to one of these, and the set is
47
- * validated at runtime.
48
- *
49
- * - `access_credential_expiry` — the short-lived access credential the client
50
- * presents (its ephemeral `ek_` or `rk_` key) has expired, while the
51
- * underlying login is still valid. The remedy is to mint a fresh key from the
52
- * session and retry the same request. This does not sign the user out; a
53
- * short-lived key expiring — for example after a laptop resumes from sleep —
54
- * is routine.
55
- * - `session_expiry` — the long-lived login itself is gone. This is terminal:
56
- * sign out and route to re-authentication.
57
- * - `auth_blocked` — the server was reachable but rejected the kind or
58
- * configuration of the credential (wrong key type, untrusted issuer, no
59
- * organization). Re-authenticating would present the same rejected credential
60
- * and loop, so the client should stop rather than reconnect or sign out.
61
- * - `permission` — an authorization denial (403) based on scope, role, or
62
- * membership.
63
- * - `transient` — a temporary failure, such as a server error or lease
64
- * contention, that may succeed if the same request is retried unchanged.
65
- * - `none` — not a recoverable authentication condition: validation errors,
66
- * not-found, local invariants, and any code an older client does not
67
- * recognize.
68
- */
69
- export const RECOVERY_CLASSES = [
70
- 'access_credential_expiry',
71
- 'session_expiry',
72
- 'auth_blocked',
73
- 'permission',
74
- 'transient',
75
- 'none',
76
- ];
77
- /** A Zod enum over {@link RECOVERY_CLASSES}, for validating a recovery class at
78
- * runtime. */
79
- export const recoveryClassSchema = z.enum(RECOVERY_CLASSES);
80
- const wire = (category, httpStatus, retryable, message, recovery) => ({ category, surface: 'wire', httpStatus, retryable, message, recovery });
81
- const client = (category, message) => ({ category, surface: 'client', retryable: false, message });
82
- /**
83
- * The complete set of stable error codes, keyed by code. A code must be added
84
- * here before it can be thrown, since the {@link AbloError} constructor accepts
85
- * only codes from this set.
86
- */
87
- export const ERROR_CODES = {
88
- // ── auth (401) ─────────────────────────────────────────────────────
89
- apikey_invalid: wire('auth', 401, false, "This API key isn't one Ablo recognizes — it may be mistyped, truncated, or belong to a different environment. Check the key and try again."),
90
- apikey_revoked: wire('auth', 401, false, 'This API key has been revoked and can no longer be used. Mint a new key from the dashboard.'),
91
- // The short-lived access credential — the ephemeral key (`ek_` for users,
92
- // `rk_` for agents) minted from the login and presented as a bearer token.
93
- // Its expiry is routine and re-mintable: get a fresh key from the still-valid
94
- // session and retry, rather than signing out. An agent's expired `rk_` must
95
- // not sign a human out either. This is the one code on the silent re-mint
96
- // path; see the `access_credential_expiry` recovery class.
97
- apikey_expired: wire('auth', 401, false, 'This ephemeral API key has expired. Mint a fresh key from your still-valid session and retry the request.', 'access_credential_expiry'),
98
- apikey_missing: wire('auth', 401, false, 'The request arrived without an API key. Send one as `Authorization: Bearer <key>`.'),
99
- api_key_required: wire('auth', 401, false, 'This operation requires an API key, and none was presented. Send one as `Authorization: Bearer <key>`.'),
100
- capability_id_missing: wire('auth', 401, false, 'This request must name a capability id, but none was provided.'),
101
- exchange_failed: wire('auth', 401, false, 'The API key could not be exchanged for a working credential — the exchange was rejected. Check that the key is still valid.'),
102
- identity_resolve_failed: wire('auth', 401, false, 'The server could not resolve an identity for this credential — the identity lookup was rejected. Check that the credential is still valid.'),
103
- auth_no_credentials: wire('auth', 401, false, 'No recognized authentication credential was presented — no API key and no bearer JWT. Send `Authorization: Bearer <token>`.'),
104
- identity_missing_organization: wire('auth', 401, false, 'Authentication succeeded, but the credential resolves to no organization, so requests cannot be scoped. Check that the key or token carries an organization.'),
105
- // The long-lived login is gone; this is terminal and drives sign-out and
106
- // re-authentication.
107
- session_expired: wire('auth', 401, false, 'Your session has expired or is no longer valid. Sign in again to continue.', 'session_expiry'),
108
- // `jwt_invalid` is the general fallback; the codes below it split out specific
109
- // failure modes, so an integrator can tell a wrong JWKS registration from a
110
- // token with no organization claim from a wrong audience, instead of getting
111
- // one opaque code for all of them.
112
- jwt_invalid: wire('auth', 401, false, "The bearer JWT failed validation for a reason the server could not classify further. Check the token's issuer, signature, audience, and expiry."),
113
- jwt_malformed: wire('auth', 401, false, 'The bearer token is not a well-formed JWT and could not be decoded. Check that the full, unmodified token was sent.'),
114
- jwt_missing_issuer: wire('auth', 401, false, 'The bearer JWT has no `iss` (issuer) claim, so it cannot be routed to a trusted issuer.'),
115
- jwt_issuer_untrusted: wire('auth', 401, false, "The bearer JWT's `iss` is not a registered trusted issuer. Check the token's issuer claim, or register the issuer with your deployment before retrying."),
116
- jwt_signature_invalid: wire('auth', 401, false, "The bearer JWT's signature could not be verified against the issuer's JWKS (wrong key, rotated key, or forged token)."),
117
- jwt_audience_mismatch: wire('auth', 401, false, "The bearer JWT's `aud` (audience) claim does not match the audience this issuer is registered with."),
118
- jwt_missing_subject: wire('auth', 401, false, 'The bearer JWT has no `sub` (subject) claim to identify the user.'),
119
- jwt_missing_organization: wire('auth', 401, false, 'The bearer JWT carries no organization context — neither a fixed org for the issuer nor the configured organization claim.'),
120
- // Applies only to the trusted-issuer path, where a customer authenticates with
121
- // a JWT from their own identity provider. When such a token expires, the
122
- // remedy is to re-authenticate against that provider, so it classifies as a
123
- // session expiry.
124
- jwt_expired: wire('auth', 401, false, 'The bearer JWT has expired. Obtain a fresh token from your identity provider and retry.', 'session_expiry'),
125
- jwt_org_membership_denied: wire('auth', 403, false, "The bearer JWT's subject is not an active member of the organization in its `org_id` claim (removed, suspended, or the claim does not match a membership)."),
126
- file_upload_auth_required: wire('auth', 401, false, 'File uploads require an authenticated session. Sign in and retry.'),
127
- browser_apikey_blocked: client('auth', 'A raw API key was used from a browser, where anyone can read it. Keep secret keys server-side and hand the browser a short-lived ephemeral key instead.'),
128
- datasource_connection_unsupported: wire('validation', 400, false, 'This deployment does not accept direct connection-string data sources. Register a signed Data Source endpoint instead.'),
129
- // ── permission / capability (403) ──────────────────────────────────
130
- capability_scope_denied: wire('capability', 403, false, 'This action falls outside the scope granted to the connection, so it was denied.'),
131
- issuer_register_forbidden: wire('permission', 403, false, 'Registering a trusted issuer requires a secret (`sk_`) API key. The key presented is not a secret key.'),
132
- capability_invalid: wire('capability', 403, false, 'This capability cannot be used — it is unknown, revoked, or expired. Request a fresh grant.'),
133
- test_database_not_registered: wire('permission', 403, false, 'Test mode requires a registered dev database for this org — run `npx ablo init` to register one for your test key.'),
134
- tenant_routing_failed: wire('server', 500, true, "The org's registered database could not be resolved or dialed. Ablo never falls back to shared storage for a dedicated tenant — retry, and check the datasource status if it persists."),
135
- database_role_cannot_enforce_rls: wire('permission', 403, false, 'The database role Ablo connects with is a superuser or has `BYPASSRLS`, so Postgres will not enforce row-level security for it. Connect with a role that is subject to RLS.'),
136
- database_role_unreadable: wire('permission', 403, false, 'Ablo could not introspect the database role it connects with, so it cannot verify that row-level security is enforced.'),
137
- database_tables_unforced_rls: wire('permission', 403, false, 'Some synced tables do not have `FORCE ROW LEVEL SECURITY` applied, so the table owner can bypass row isolation. Run `ALTER TABLE ... FORCE ROW LEVEL SECURITY` on each synced table.'),
138
- database_host_not_allowed: wire('permission', 403, false, "The database host resolves to a private, loopback, or link-local address, which Ablo's servers will not connect to. Use a publicly resolvable host."),
139
- connected_database_unreachable: wire('tenant', 503, false, 'Ablo could not reach the database connected to this environment: it refused the credentials on file, or did not answer at all. A database often changes after it is connected — a password is rotated, an instance is replaced — while the connection goes on pointing at what used to be there. The error names the host it tried. If the password changed, `ablo connect rotate` re-keys the roles and re-registers them; if the database itself was replaced, `ablo connect apply` sets up the new one and `ablo connect register` hands it over. Run either with a key for this environment.'),
140
- // Older spellings of the `database_*` codes above, still sent by some servers
141
- // and kept so they classify identically. Prefer the `database_*` codes.
142
- byo_role_cannot_enforce_rls: wire('permission', 403, false, 'The direct Postgres connector role cannot enforce row-level security.'),
143
- byo_role_unreadable: wire('permission', 403, false, 'The direct Postgres connector role could not be introspected.'),
144
- byo_tenant_tables_unforced_rls: wire('permission', 403, false, 'Tenant tables do not have RLS forced under the direct Postgres connector role.'),
145
- byo_host_not_allowed: wire('permission', 403, false, 'The direct Postgres connector host resolves to a private, loopback, or link-local address and cannot be used.'),
146
- // ── claim / claim conflict (409) ──────────────────────────────────
147
- // A rejection because another participant holds a claim is not retryable.
148
- // Re-sending the same write cannot succeed while the claim is held, and a
149
- // claim can outlive any reasonable retry budget, so an automatic retry would
150
- // only loop. Recovery belongs to the caller: take a claim, which queues fairly
151
- // behind the holder (`ablo.<model>.claim`), or re-read and rebase.
152
- claim_conflict: wire('claim', 409, false, 'Another participant holds a claim on this row, so the write was rejected. Take a claim with `ablo.<model>.claim` to queue fairly behind the holder, or re-read and rebase.'),
153
- claim_lost: wire('claim', 409, false, 'The claim held on this row was lost before the write could apply. Re-acquire with `ablo.<model>.claim` and retry from its fresh snapshot.'),
154
- fence_token_stale: wire('claim', 409, false, 'This write carried a fencing token below the row’s current high-water: a later holder claimed the row, wrote, and moved on while this claim was lapsed, so applying the write would silently overwrite their work. The claim is gone — re-claim the row and retry from the current state.'),
155
- entity_claimed: wire('claim', 409, false, 'This row is currently claimed by another participant, so the write was blocked. Queue behind the holder with `ablo.<model>.claim`, or wait for the claim to clear.'),
156
- // A claim payload that cannot be parsed is a malformed request, not
157
- // contention — it is filed with `malformed_subscription` below rather than
158
- // with the 409s above, so the claim category stays purely about a target
159
- // being held. This is the code for a claim that fails to name its target,
160
- // over either transport — and for the participant claim behind `join`, which
161
- // names scopes rather than a row but fails the same way and to the same
162
- // caller. The copy covers both because the caller sees one word, `claim`, and
163
- // needs to be told which shape was expected without being handed a lecture on
164
- // the two frames.
165
- malformed_claim: wire('validation', 400, false, 'The claim payload could not be parsed. A claim on a row must name the model and the entity it targets; a claim on a scope, which is what `join` opens, must name sync groups spelled `kind:id` or `default`. Check the payload shape and resend.'),
166
- malformed_subscription: wire('validation', 400, false, 'The `update_subscription` payload was malformed; expected `{ syncGroups: string[] }`.'),
167
- // The counterpart to the two above, pointing the other way: those are a
168
- // client sending the server something it cannot read, this is the server
169
- // sending the client something it cannot read. One code covers both
170
- // transports — a mis-shaped socket frame and a mis-shaped HTTP body are the
171
- // same failure, and the message says which arrived. Not retryable: it means
172
- // the two sides are running different versions of the protocol, and waiting
173
- // does not change that.
174
- malformed_response: wire('transport', 502, false, 'The server sent a message this client could not read, so it was declined whole rather than applied in part. Nothing was changed locally. This normally means the client and the server are running different versions; upgrading the client resolves it.'),
175
- model_claimed: wire('claim', 409, false, 'Another participant holds a claim on this row. Read `claim.state` to see who holds it, or queue behind them with a claim of your own.'),
176
- model_claimed_timeout: wire('claim', 409, false, 'Another participant held a claim on this row and did not release it in time. Retry, or read `claim.state` to see who holds it.'),
177
- model_claim_not_configured: client('claim', 'Claiming requires the collaboration runtime, which the standard Ablo({ schema, apiKey }) client wires up for every model automatically — there is no per-model claim configuration to add. This appears only when a model proxy is constructed directly without that runtime (an internal/advanced path).'),
178
- model_join_not_configured: client('claim', 'join() opens a presence/claim subscription and needs a live WebSocket, so it is unavailable on the HTTP transport and on model proxies built without a socket. Use the standard Ablo({ schema, apiKey }) client (default WebSocket transport).'),
179
- // ── stale context / idempotency (409) ──────────────────────────────
180
- // Not retryable at the transport: the rejected request carries its frozen
181
- // `readAt`, so resending the identical payload can never succeed. Recovery
182
- // is a caller-level re-read that produces a NEW request with a fresh
183
- // watermark — the same shape as `claim_conflict`.
184
- stale_context: wire('conflict', 409, false, "The row changed after you read it — the write's `readAt` watermark is older than the current row version. Pass a function to `update(id, current => next)` and the SDK re-reads and retries for you; or re-read and retry by hand."),
185
- // Raised by the functional `update(id, current => next)` form once its
186
- // internal reconcile budget is exhausted, because the row stayed continuously
187
- // contended. The SDK has already retried; the caller decides whether to back
188
- // off, raise `retries`, or move the row to the WebSocket transport.
189
- contention_exhausted: client('conflict', 'A functional update kept losing to concurrent writes and exhausted its reconcile budget. Back off and retry, raise `retries`, or move the row to the WebSocket transport.'),
190
- update_aborted: client('conflict', 'The functional update was aborted via its `AbortSignal` before the write landed; nothing was written.'),
191
- idempotency_conflict: wire('conflict', 409, false, 'This `Idempotency-Key` was already used with a different request body. Reuse a key only to retry an identical request; otherwise generate a new one.'),
192
- idempotency_key_expired: wire('conflict', 409, false, 'This idempotency key belongs to an expired retained source intent and cannot be executed again safely. Use a new key only for a genuinely new write.'),
193
- source_transport_pinned: wire('conflict', 409, false, 'An earlier attempt under this idempotency key was pinned to a different source transport. Restore that route and retry the same key; Ablo will not switch a possibly committed write.'),
194
- idempotency_key_too_long: wire('validation', 400, false, 'The supplied `Idempotency-Key` exceeds the maximum length. Use a shorter key — a UUID works well.'),
195
- // ── validation (400 / 422) ─────────────────────────────────────────
196
- write_options_invalid: client('validation', 'The write options (`idempotencyKey` / `label` / `wait` / `readAt` / `onStale` / `claim`) failed validation against the write-options schema.'),
197
- write_payload_invalid: client('validation', 'A write payload contained a value that cannot be represented safely as JSON. Use plain objects, arrays, finite numbers, strings, booleans, null, or valid dates.'),
198
- source_operation_id_required: client('validation', 'A data-source operation arrived without the entity `id` it targets.'),
199
- source_adapter_misconfigured: client('validation', 'The data-source ORM adapter could not map a schema model onto the backing client — the client exposes no matching delegate or model. Check that the adapter and schema agree on model names.'),
200
- // The server validates every incoming data-source event before appending it
201
- // to the log and rejects the whole batch with this code; `param` names the
202
- // offending index and field path, such as `events[3].entityId`. It is also
203
- // raised on the client when an outbound source event cannot be built.
204
- source_event_invalid: wire('validation', 400, false, 'A data-source event was malformed — missing or invalid id, model, entityId, type, or field value. The whole event batch was rejected and nothing was ingested; fix the offending outbox row and re-send.'),
205
- duration_invalid: client('validation', 'A duration value was not a number of seconds or a "500ms" | "30s" | "3m" | "24h" string.'),
206
- schema_definition_invalid: client('validation', 'A schema definition value was invalid (bad column identifier, non-finite backfill, or unsupported schema-JSON version).'),
207
- cli_invalid_arguments: client('validation', 'The CLI was invoked with an unknown flag or a malformed flag value.'),
208
- commit_operation_required: wire('validation', 400, false, 'A commit must carry `operation` or `operations`.'),
209
- // Both commit transports — the WebSocket `commit` frame and the HTTP
210
- // `/v1/commits` endpoint — validate every operation and reject the whole batch
211
- // with this code. `param` names the offending index and field path, such as
212
- // `operations[3].readAt`.
213
- commit_operation_invalid: wire('validation', 400, false, 'A commit operation failed validation against the wire commit-operation schema — wrong field type (e.g. a string `readAt`), unknown `type`, or missing `model`. The whole batch was rejected; the error names the offending operation index and field path.'),
214
- commit_operation_model_required: wire('validation', 400, false, 'A commit operation is missing its `model`.'),
215
- commit_operations_ambiguous: wire('validation', 400, false, 'A commit supplied both `operation` and `operations`. Send one or the other, not both.'),
216
- commit_too_many_operations: wire('validation', 400, false, 'A commit exceeded the per-commit operation limit; split it into smaller batches.'),
217
- model_required_field_missing: wire('validation', 400, false, 'The write is missing a field the model marks as required. Include the field and retry.'),
218
- model_identifier_missing: wire('validation', 400, false, "The payload is missing the model's identifier, so the target row cannot be determined. Include the `id` field."),
219
- snapshot_reserved_key: wire('validation', 400, false, 'The snapshot uses a key name that is reserved by the runtime. Rename the key and retry.'),
220
- mesh_message_invalid_input: wire('validation', 400, false, 'The mesh message payload failed input validation and was not delivered.'),
221
- mesh_message_from_id_spoof: wire('validation', 403, false, "The mesh message's `from` id does not match the authenticated sender, so it was rejected — participants may only send as themselves."),
222
- mesh_message_from_kind_mismatch: wire('validation', 403, false, "The mesh message's `from` kind does not match the kind of the authenticated sender, so it was rejected."),
223
- agent_perception_missing_context: wire('validation', 422, false, 'The agent perception request is missing context it needs to run. Include the required context fields and retry.'),
224
- // ── not found (404) ────────────────────────────────────────────────
225
- entity_not_found: wire('not_found', 404, false, 'No row exists with the requested id. It may have been deleted, or the id may belong to a different environment.'),
226
- model_not_found: wire('not_found', 404, false, 'No row of this model exists with the requested id. It may have been deleted, or the id may belong to a different environment.'),
227
- mutate_update_entity_not_found: wire('not_found', 404, false, 'The row targeted by this update does not exist — it may have been deleted since you read it. Re-read before retrying.'),
228
- no_data_source_registered: wire('not_found', 404, false, 'No database is connected to this plane yet, so there is nothing to check. Connect one with `ablo connect apply`, then run the check again.'),
229
- task_id_missing: wire('server', 502, true, 'The task-create response arrived without a task id, so the result cannot be used. Retry the request.'),
230
- // ── data integrity / database constraints ──────────────────────────
231
- // Emitted when a database integrity constraint rejects a write. None are
232
- // retryable: the same payload re-sent unchanged fails identically, so the
233
- // client must roll back rather than retry. The server maps the underlying SQL
234
- // constraint to one of these codes and places the raw constraint, column, and
235
- // table detail in `details` instead of exposing the driver's message text.
236
- not_null_violation: wire('validation', 400, false, 'The database rejected the write because a required column was left empty — a not-null constraint. The error details name the column; supply a value and retry.'),
237
- foreign_key_violation: wire('conflict', 409, false, 'The database rejected the write on a foreign-key constraint: a referenced row does not exist, or the row being deleted is still referenced by others. The error details name the constraint.'),
238
- unique_violation: wire('conflict', 409, false, 'The write duplicates a value that must be unique — another row already holds it. Choose a different value, or update the existing row.'),
239
- check_violation: wire('validation', 400, false, 'The database rejected a value that fails one of its check constraints. The error details name the constraint; adjust the value and retry.'),
240
- constraint_violation: wire('validation', 400, false, 'The database rejected the write on an integrity constraint. The error details identify the specific constraint.'),
241
- column_type_mismatch: wire('validation', 400, false, 'A structured (JSON) value was written to a column whose database type cannot hold it. Ablo adapts a json field to either a jsonb column (native) or a text column (serialized) — but a scalar column (integer, boolean, uuid, timestamp, …) cannot store a JSON object or array. Use a jsonb or text column for this field. Ablo adapts to your column; it does not alter your schema.'),
242
- // ── tenant / unknown model (400) ───────────────────────────────────
243
- server_execute_unknown_model: wire('tenant', 400, false, 'Wrote to a model the server does not know. The server keeps its own copy of the schema — run `ablo push` (or keep `ablo dev` running) to upload `ablo/schema.ts` before writing to new or changed models.'),
244
- mutate_create_unknown_model: wire('tenant', 400, false, 'Created a model the server does not know. Run `ablo push` (or keep `ablo dev` running) to upload `ablo/schema.ts` first — the server keeps its own copy of the schema.'),
245
- tenant_model_columns_unknown: wire('tenant', 400, false, 'The columns for this model could not be resolved in the tenant database, so the operation cannot be mapped onto its table.'),
246
- tenant_model_missing_organization_id: wire('tenant', 400, false, "This model's table has no `organization_id` column, which Ablo requires to isolate rows by organization. Add the column before syncing this model."),
247
- // ── schema migration / declaration (validation) ────────────────────
248
- schema_mutable_missing_meta: wire('schema', 400, false, 'The schema is declared mutable but is missing its required `meta` block.'),
249
- schema_scope_kind_invalid: wire('schema', 400, false, 'A scope declaration in the schema uses a kind the engine does not recognize.'),
250
- schema_field_not_camelcase: wire('schema', 400, false, 'A schema field name is not camelCase. Rename the field (for example `dueDate`) — Ablo derives column names from camelCase field names.'),
251
- schema_field_consecutive_caps: wire('schema', 400, false, 'A schema field name contains consecutive capital letters, which cannot be mapped to a column name unambiguously. Write acronyms in lower case (`apiKey`, not `APIKey`).'),
252
- schema_reserved_field: client('schema', 'A model redeclared a reserved base field (id, createdAt, updatedAt, organizationId, createdBy) that the SDK provides automatically.'),
253
- schema_grants_shape_invalid: wire('schema', 400, false, 'A `grants` declaration in the schema has an invalid shape and could not be parsed.'),
254
- schema_grants_identifier_unsafe: wire('schema', 400, false, 'A `grants` declaration references an identifier that is not safe to use in SQL. Use plain column and relation names.'),
255
- schema_grants_relation_kind: wire('schema', 400, false, 'A `grants` declaration references a relation of a kind it cannot traverse.'),
256
- schema_grants_relation_missing: wire('schema', 400, false, 'A `grants` declaration references a relation the model does not define. Check the relation name against the model.'),
257
- schema_grants_target_not_scope_root: wire('schema', 400, false, 'A `grants` declaration targets a model that is not a scope root, so access cannot be derived from it.'),
258
- drop_field: client('schema', 'This migration would drop an existing field, destroying the data stored in it.'),
259
- drop_model: client('schema', 'This migration would drop an entire model and its table, destroying the rows stored in it.'),
260
- lossy_recreate: client('schema', 'This migration can only apply by recreating the table, which would not preserve its existing rows.'),
261
- made_required: client('schema', 'This migration makes an existing optional field required, which rows without a value for it would violate.'),
262
- required_field_added: client('schema', 'This migration adds a new required field that existing rows have no value for.'),
263
- enum_value_removed: client('schema', 'This migration removes an enum value that existing rows may still hold.'),
264
- risky_cast: client('schema', 'This migration changes a column to a type its current values may not convert to cleanly.'),
265
- // ── claim / lease (409 / transport) ───────────────────────────────
266
- claim_lease_unavailable: wire('claim', 503, true, 'The claim-lease coordination subsystem is temporarily unavailable, so the claim could not be processed. Retry shortly.'),
267
- claim_not_wired: client('claim', 'Claims were used, but this runtime has no claim support wired in. The standard `Ablo({ schema, apiKey })` client wires it up automatically.'),
268
- claim_queued: wire('claim', 409, true, 'The claim was queued behind the current lease holder and will be granted in turn. Poll `claims.retrieve({ claimId })` for the grant — the id rides on the error — or read `claim.queue` to see the line.'),
269
- claim_wait_aborted: wire('claim', 409, true, 'The wait for this claim lease was aborted before the lease was granted.'),
270
- grant_timeout: wire('claim', 504, true, 'The wait for the claim grant timed out before your turn arrived (`waitTimeoutMs`). Claim again to rejoin the line, raise the cap, or re-read and proceed without the claim.'),
271
- // ── bootstrap (transport) ──────────────────────────────────────────
272
- bootstrap_fetch_timeout: wire('bootstrap', 504, true, 'The initial bootstrap fetch timed out before the server responded. Retry shortly.'),
273
- // Deliberate cancellation, never a failure of the network. It is what the
274
- // client hands to `abort()` so the layer above can tell "we stopped this on
275
- // purpose" apart from "the transfer died" — the two are indistinguishable
276
- // from a bare abort, and retrying the first re-issues requests that were just
277
- // killed. Non-retryable by construction: whoever cancelled it either has a
278
- // newer request in flight or has already given up.
279
- bootstrap_cancelled: client('bootstrap', 'This bootstrap request was cancelled before it finished, because a newer one replaced it or the bootstrap it belonged to had already failed. It is not retried on its own.'),
280
- bootstrap_offline: wire('bootstrap', 503, true, 'Bootstrap could not run because the client is offline. It can proceed once the network returns.'),
281
- bootstrap_offline_no_cache: wire('bootstrap', 503, false, 'The client is offline and no cached snapshot is available to start from, so there is no data to load until the network returns.'),
282
- bootstrap_response_invalid: wire('bootstrap', 502, true, 'The bootstrap response could not be parsed. Retrying may succeed.'),
283
- bootstrap_response_schema_invalid: wire('bootstrap', 502, true, 'The bootstrap response parsed but failed schema validation, so it was not applied. Retrying may succeed.'),
284
- // ── transport / connection ─────────────────────────────────────────
285
- exchange_malformed_response: wire('transport', 502, true, 'The credential exchange returned a response that could not be parsed. Retrying may succeed.'),
286
- exchange_network_error: wire('transport', 503, true, 'A network error interrupted the credential exchange. Check connectivity and retry.'),
287
- source_network_error: wire('transport', 503, true, 'A network error occurred while talking to the data source. Check connectivity and retry.'),
288
- source_unreachable: wire('transport', 503, true, 'Ablo could not safely reach the registered direct data source before completing the write. The write remains pinned to direct; retry the same idempotency key after connectivity recovers.'),
289
- data_source_blocked: wire('transport', 503, false, 'The plane\'s data source is not in a verified, resolvable state. Fix its registration, secret, or configuration; Ablo will not fall through to hosted storage.'),
290
- identity_network_error: wire('transport', 503, true, 'A network error occurred while resolving your identity. Check connectivity and retry.'),
291
- commit_no_result: wire('transport', 504, true, 'The commit was sent, but no result frame arrived, so its outcome is unknown. It is safe to retry.'),
292
- commit_failed: wire('transport', 500, true, 'The commit reached the server but failed to apply. Retrying may succeed.'),
293
- replication_lag_timeout: wire('transport', 504, true, "The data source accepted the write, but its correlated authoritative source delta did not arrive before the confirmation deadline. The write may still materialize; retry with the same idempotency key or wait for source ingestion to recover."),
294
- commit_offline_grace_expired: wire('transport', 503, false, 'The offline grace window expired before this commit could be sent, so it was not applied. Re-apply the change once the connection returns.'),
295
- queue_too_deep: wire('transport', 503, true, 'The line is already past its depth limit. For a claim, more participants were waiting than your `maxQueueDepth` allows — claim again without the cap to wait anyway, or work elsewhere and retry later. For a write, the transaction queue is draining — retry shortly.'),
296
- flush_timeout: wire('transport', 504, true, 'Flushing the transaction queue timed out before every pending write was sent. Retry once connectivity stabilizes.'),
297
- wait_for_timeout: wire('transport', 504, true, 'A wait-for condition timed out before it was satisfied. Retry, or extend the timeout.'),
298
- instance_at_capacity: wire('transport', 503, true, 'The server is at connection capacity. Retry shortly — transient and not specific to your credentials.'),
299
- fetch_unavailable: client('transport', 'This environment provides no `fetch` implementation, so HTTP requests cannot be made. Run on a platform with `fetch` (Node 18+, modern browsers) or supply a polyfill.'),
300
- base_url_missing: client('transport', 'The client has no base URL configured, so it cannot address the server. Set the base URL when constructing the client.'),
301
- sync_not_ready: client('transport', 'A sync operation ran before the client finished initializing. Wait for the client to be ready before syncing.'),
302
- ws_not_ready: client('transport', 'A frame was sent before the WebSocket connection was established. Wait for the connection to open before sending.'),
303
- // ── quota / rate limit (429) ──────────────────────────────────────
304
- quota_exceeded: wire('rate_limit', 429, true, 'Your organization has used up its configured usage quota. Requests will succeed again once the quota resets or the limit is raised.'),
305
- connection_limit_exceeded: wire('rate_limit', 429, true, 'Too many concurrent WebSocket connections for this principal or organization. Close idle connections, or retry once others drain.'),
306
- // A per-key request-rate limit — the fast, requests-per-second axis, as
307
- // opposed to `quota_exceeded`, which is the slower organization-wide usage
308
- // limit. It is keyed per API key, so one noisy key backs off without affecting
309
- // the rest of the organization. The `Retry-After` header carries the delay
310
- // before the next request is allowed.
311
- rate_limit_exceeded: wire('rate_limit', 429, true, 'This API key is sending requests faster than its rate limit allows. Slow down and retry after the delay in the `Retry-After` header.'),
312
- // ── server (5xx) ───────────────────────────────────────────────────
313
- internal_error: wire('server', 500, true, "Something went wrong on Ablo's side — an unexpected server error. It is safe to retry."),
314
- quota_lookup_failed: wire('server', 503, true, "The server could not load this organization's quota state, so the request was rejected rather than admitted unchecked. Retry shortly."),
315
- // The rate-limiter backend was unreachable and this endpoint is configured to
316
- // fail closed, so the request was rejected rather than admitted unchecked. It
317
- // is retryable: the next attempt re-probes the backend.
318
- rate_limiter_unavailable: wire('server', 503, true, 'The rate-limiter backend is unavailable and this endpoint is configured to fail closed; retry shortly.'),
319
- // ── client-only invariants (never serialized) ──────────────────────
320
- invalid_options: client('client', 'The Ablo client was constructed with invalid or incomplete options.'),
321
- no_ablo_provider: client('client', 'An Ablo hook was used outside of an Ablo provider.'),
322
- no_sync_group_provider: client('client', 'A sync-group hook was used outside of its provider.'),
323
- sync_context_missing_provider: client('client', 'Sync context was read outside of its provider.'),
324
- db_not_opened: client('client', 'The local database was accessed before it was opened.'),
325
- db_store_not_found: client('client', 'The requested IndexedDB object store does not exist.'),
326
- db_unknown_action_type: client('client', 'An unknown database action type was dispatched.'),
327
- idb_unavailable: client('client', 'IndexedDB is unavailable in this environment.'),
328
- meta_db_not_initialized: client('client', 'The meta database was accessed before initialization.'),
329
- sync_client_db_missing: client('client', 'The sync client has no database handle.'),
330
- lazy_ref_db_missing: client('client', 'A lazy reference was resolved without a database handle.'),
331
- lazy_ref_pool_missing: client('client', 'A lazy reference was resolved without a model pool.'),
332
- model_class_not_registered: client('client', 'The model class is not registered with the store.'),
333
- model_not_registered: client('client', 'The model is not registered with the store.'),
334
- model_disposed: client('client', 'The model instance has been disposed.'),
335
- pool_model_class_not_registered: client('client', 'The model class is not registered with the pool.'),
336
- pool_registry_missing: client('client', 'The model pool registry is not initialized.'),
337
- pool_subscribe_unregistered: client('client', 'Subscribed to a model that is not registered with the pool.'),
338
- registry_invalid_constructor: client('client', 'A model was registered with an invalid constructor.'),
339
- registry_not_initialized: client('client', 'The registry was used before initialization.'),
340
- registry_property_conflict: client('client', 'Two registered models declared a conflicting property.'),
341
- registry_reference_unknown_target: client('client', 'A relation referenced an unknown target model.'),
342
- registry_reference_unresolved: client('client', 'A relation reference could not be resolved.'),
343
- registry_unknown_model: client('client', 'The registry has no entry for the requested model.'),
344
- query_returns_unknown_model: client('client', 'A query returned a model the registry does not know.'),
345
- store_create_schema_missing: client('client', 'Store.create was called without a schema.'),
346
- store_manager_unknown_model: client('client', 'The store manager has no entry for the requested model.'),
347
- store_query_schema_missing: client('client', 'Store.query was called without a schema.'),
348
- store_query_unknown_model: client('client', 'Store.query named a model the store does not know.'),
349
- transaction_mutate_unknown_model: client('client', 'A transaction mutated a model the registry does not know.'),
350
- transaction_read_unknown_model: client('client', 'A transaction read a model the registry does not know.'),
351
- mutator_registry_duplicate: client('client', 'Two mutator definitions registered under the same name.'),
352
- mutator_registry_unnamed_def: client('client', 'A mutator definition was registered without a name.'),
353
- mutators_schema_missing: client('client', 'Mutators were registered without a schema.'),
354
- undo_scope_schema_missing: client('client', 'An undo scope was opened without a schema.'),
355
- undo_entry_invalid: client('client', 'An undo entry failed inverse-op schema validation.'),
356
- mock_mutation_failed: client('client', 'A mock mutation adapter was configured to fail.'),
357
- mock_unsupported_operation: client('client', 'A mock adapter received an unsupported operation.'),
358
- // ── HTTP route edge codes ──────────────────────────────────────────
359
- invalid_body: wire('validation', 400, false, 'The request body was missing, unparseable, or the wrong shape.'),
360
- invalid_json: wire('validation', 400, false, 'The request body was not valid JSON.'),
361
- capability_id_required: wire('validation', 400, false, 'A capability id is required for this request.'),
362
- organization_mismatch: wire('permission', 403, false, 'The request targeted an organization the caller is not scoped to.'),
363
- project_scope_denied: wire('permission', 403, false, "The request targeted a project the caller's key is not scoped to."),
364
- project_slug_taken: wire('validation', 409, false, 'A project with this slug already exists in the organization. Choose a different slug.'),
365
- forbidden: wire('permission', 403, false, 'The caller lacks permission for this operation.'),
366
- source_api_key_unresolved: wire('auth', 401, false, 'The API key presented for this data source could not be resolved to a known key. Check the key and its environment.'),
367
- capability_auth_disabled: wire('server', 503, false, 'Capability authentication is disabled on this server.'),
368
- capability_rotation_unavailable: wire('server', 500, false, 'This capability could not be rotated, because the environment it belongs to could not be read from it. It is unchanged and still works. Create a replacement capability and retire this one.'),
369
- provisioner_unavailable: wire('server', 503, false, 'This deployment has no database provisioner configured, so tables cannot be created here.'),
370
- invalid_model: wire('validation', 400, false, 'The model name in the request is not a valid model identifier.'),
371
- invalid_id: wire('validation', 400, false, 'The id in the request is not a valid identifier.'),
372
- unknown_model: wire('tenant', 400, false, 'Named a model the server does not know. Run `ablo push` (or keep `ablo dev` running) to upload `ablo/schema.ts` — the server keeps its own copy of the schema.'),
373
- model_not_tenant_scoped: wire('tenant', 400, false, 'This model is not tenant-scoped, so it cannot be queried through the tenant-scoped read path.'),
374
- source_tenancy_not_enforced: wire('tenant', 400, false, "This model is scoped by its connected data source (`policy: { by: 'source' }`), so its tenant is resolved from the source registration rather than a row column. Enforcing that resolution requires the write-through connect path, which is not enabled on this plane yet — so the model cannot be served through the tenant-scoped read or bootstrap path without risking a cross-tenant read. If this model lives on a log plane, scope it with `by: 'column'` or `by: 'parent'` instead."),
375
- user_scope_not_enforced: wire('tenant', 400, false, "Rows in this model belong to one person rather than to the whole organization, and that boundary is kept where the rows are stored. This plane is currently served from its log, which carries the organization and the project on every row but not the owner — so the boundary cannot be applied here, and serving the read would show one member another member's private records. It was declined whole and nothing was returned. Serve the plane from its tables, or read with a credential that acts for the organization rather than for a person."),
376
- model_not_provisioned: wire('tenant', 409, false, "This model is in the plane's registered schema, but its table has not been provisioned yet. Registering a schema with `ablo push` records the model; a plane's physical tables are created separately, out of band, so a model can appear in the schema before its table exists. Provision the plane's tables, then retry the read."),
377
- schema_table_invalid: wire('schema', 500, false, "The model's table identifier is invalid."),
378
- schema_scope_invalid: wire('schema', 500, false, "The model's scope predicate could not be built."),
379
- entity_fetch_failed: wire('server', 500, true, 'The server failed to fetch the requested entity. It is safe to retry.'),
380
- events_required: wire('validation', 400, false, 'The request must include a non-empty `events` array.'),
381
- ingest_failed: wire('validation', 400, false, 'The source-event batch was rejected during ingest and nothing was appended. Check the events against the expected shape and re-send.'),
382
- migration_failed: wire('server', 500, false, 'The schema migration failed while applying and did not complete.'),
383
- schema_provisioning_forbidden: wire('permission', 403, false, 'Schema registration could not create tables in the target database: the engine is not permitted to run DDL there.'),
384
- model_query_failed: wire('validation', 400, false, 'The model query failed to execute. Check the query filters and operators.'),
385
- queries_required: wire('validation', 400, false, 'The request must include a non-empty `queries` array.'),
386
- query_unsupported_operator: wire('validation', 400, false, 'The query used an unsupported operator.'),
387
- query_invalid_like_pattern: wire('validation', 400, false, 'The `LIKE` pattern must not end with an escape character.'),
388
- query_invalid_boolean: wire('validation', 400, false, 'The query compared a boolean column against an invalid boolean literal.'),
389
- protocol_version_unsupported: wire('transport', 426, false, 'The client sync-protocol version is outside the range this server supports — upgrade the SDK (or the server was rolled back mid-fleet).'),
390
- database_unreachable: wire('validation', 400, false, "Ablo could not reach this database to check that it can stream replication. The connection string may be wrong, the host may not be reachable from Ablo's servers, or the credentials may not be accepted."),
391
- database_not_replication_ready: wire('validation', 400, false, 'This database is not set up for logical replication yet. Every failing item — wal_level, the publication, the replication grant, a replica identity — is listed in the error details with its exact fix. `ablo connect` prints the one-time setup; `ablo connect check` verifies it.'),
392
- database_already_connected: wire('conflict', 409, false, 'This database is already connected to another environment in your organization. Ablo streams a database from one environment at a time, so connecting it to a second one would leave the two reading the same change stream, and the newer connection would take the stream over from the older. Give this environment a database of its own — on a branching provider a branch of the same database is the usual answer, and it is what sandbox is for. If you meant to move the connection rather than add one, disconnect it from the environment that holds it with `ablo connect deregister` first.'),
393
- replication_publication_drift: wire('validation', 400, false, 'Your schema maps to tables that are not members of the replication publication, so their changes silently never stream and the source looks frozen. The missing tables and the exact `ALTER PUBLICATION … ADD TABLE …` to add them are in the error details — Ablo never alters your database for you.'),
394
- query_unknown_relation: wire('validation', 400, false, 'The query references a relation the model does not define. Check the relation name against the schema.'),
395
- query_relation_target_unknown: wire('schema', 500, false, 'A relation in the query targets a model the schema does not define.'),
396
- query_invalid_identifier: wire('validation', 400, false, 'The query contained an invalid identifier.'),
397
- org_id_required: wire('validation', 400, false, 'An organization id is required for this request.'),
398
- presence_identity_required: wire('validation', 400, false, 'Presence requests must carry both `userId` and `organizationId`.'),
399
- upload_fields_required: wire('validation', 400, false, 'The upload request is missing a required field.'),
400
- upload_items_required: wire('validation', 400, false, 'The request must include a non-empty `items` array.'),
401
- presigned_url_failed: wire('server', 500, true, 'The server could not generate a presigned upload URL. It is safe to retry.'),
402
- upload_not_configured: wire('server', 503, false, 'Uploads are not configured on this deployment: the upload storage bucket and CDN domain are unset.'),
403
- task_id_required: wire('validation', 400, false, 'A task id is required for this request.'),
404
- claim_id_required: wire('validation', 400, false, 'A claim id is required for this request.'),
405
- commit_operation_action_required: wire('validation', 400, false, 'A commit operation is missing its `action`.'),
406
- commit_operation_unsupported: wire('validation', 400, false, 'A commit operation used an unsupported `action`.'),
407
- usage_invalid: wire('validation', 400, false, 'The usage request was invalid.'),
408
- invalid_request: wire('validation', 400, false, 'The request parameters were invalid.'),
409
- capability_not_found: wire('not_found', 404, false, 'No capability exists with the given id.'),
410
- claim_not_found: wire('not_found', 404, false, 'No claim of yours exists with the given id. It was released, it expired, or it was never acquired on this plane.'),
411
- invalid_participant_kind: wire('validation', 400, false, 'The participant kind is not one the server recognizes.'),
412
- invalid_sync_group: wire('validation', 400, false, 'Sync groups must be `default` or `<namespace>:<id>`.'),
413
- narrow_scope_required: wire('validation', 400, false, 'This request requires a scope narrowed to specific resources; the presented scope is too broad.'),
414
- wide_scope_forbidden: wire('permission', 403, false, 'This caller may not use a wide scope. Request a scope narrowed to the resources you need.'),
415
- capability_required: wire('auth', 401, false, 'This operation requires a capability, and none was presented.'),
416
- // A row in an ordered collection can be created at a position stated relative
417
- // to its neighbours ("before this one"), so the position has to be resolved
418
- // against the parent before the row lands. These are the two ways that request
419
- // can fail to describe a real place: no parent to resolve against, and a
420
- // neighbour that is not in it.
421
- position_missing_parent: wire('validation', 400, false, 'This row gives a position but not the parent it belongs to, so the position cannot be resolved. Send the parent id alongside the position.'),
422
- position_unknown_sibling: wire('validation', 400, false, 'This row is positioned relative to another row that is not in the same parent. Check that the neighbouring row id is correct and still present.'),
423
- schema_too_large: wire('validation', 413, false, 'The submitted schema exceeds the maximum size.'),
424
- request_too_large: wire('validation', 413, false, 'The request body exceeds the maximum size.'),
425
- invalid_schema: wire('validation', 400, false, 'The submitted schema could not be parsed.'),
426
- incompatible_change: wire('conflict', 409, false, 'The schema change is incompatible with the schema currently deployed and cannot be applied as-is.'),
427
- replication_reset_required: wire('conflict', 409, false, 'A connected log plane has live rows for a mapped model that disappeared. Declare a rename or an explicit drop/reset before advancing the schema.'),
428
- };
429
- /** Looks up the {@link ErrorCodeSpec} for a code. Returns `undefined` for the
430
- * dynamic `policy:*` family and for any newer code this client does not yet
431
- * recognize. */
432
- export function errorCodeSpec(code) {
433
- return ERROR_CODES[code];
434
- }
435
- /** Reports whether a code is marked retryable. Unknown and dynamic codes
436
- * default to non-retryable, so an unrecognized failure is never retried
437
- * automatically. */
438
- export function isRetryableCode(code) {
439
- return errorCodeSpec(code)?.retryable ?? false;
440
- }
441
- /**
442
- * Classifies a code into its {@link RecoveryClass} — the single value the
443
- * connection layer and the network probe branch on to decide how to recover.
444
- *
445
- * The registry is the source of truth. An explicit `recovery` on the code's spec
446
- * wins; it is set only on the few authentication codes whose remedy the HTTP
447
- * status cannot reveal. Every other code is derived from its spec:
448
- * - retryable → `transient`
449
- * - HTTP 403 → `permission`
450
- * - remaining `auth` category → `auth_blocked` (the credential-type 401s)
451
- * - anything else, or unknown → `none`
452
- *
453
- * An unknown code, a dynamic `policy:*` code, or a code this client predates
454
- * (no spec) defaults to `none`, the same safe default as {@link isRetryableCode}:
455
- * an unrecognized code is never treated as a credential expiry or a sign-out.
456
- */
457
- export function classifyRecovery(code) {
458
- const spec = errorCodeSpec(code);
459
- if (!spec)
460
- return 'none';
461
- if (spec.recovery)
462
- return spec.recovery;
463
- if (spec.retryable)
464
- return 'transient';
465
- if (spec.httpStatus === 403)
466
- return 'permission';
467
- if (spec.category === 'auth')
468
- return 'auth_blocked';
469
- return 'none';
470
- }
471
- /**
472
- * A compile-time exhaustiveness guard: it forces every {@link RecoveryClass} to
473
- * be listed here, so adding a class to {@link RECOVERY_CLASSES} without deciding
474
- * its meaning is a type error rather than a silent gap.
475
- */
476
- const _RECOVERY_CLASS_EXHAUSTIVE = {
477
- access_credential_expiry: true,
478
- session_expiry: true,
479
- auth_blocked: true,
480
- permission: true,
481
- transient: true,
482
- none: true,
483
- };
484
- void _RECOVERY_CLASS_EXHAUSTIVE;