@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,32 +1,37 @@
1
1
  /**
2
- * Drizzle Data Source adapter. Same adapter interface + conformance as `prismaDataSource`,
3
- * built against Drizzle's REAL API (read from drizzle-orm's own source/docs):
4
- * - `db.transaction(async (tx) => …)` interactive transaction (commit/rollback).
5
- * - `db.execute(sql`…`)` parametrized raw SQL; `sql.identifier()` safely quotes
6
- * dynamic table/column names, `sql`${value}`` parametrizes values.
2
+ * The Drizzle adapter for the data-source interface. It implements the same
3
+ * {@link DataSourceAdapter} contract as {@link prismaDataSource} and passes the
4
+ * same conformance suite, built against Drizzle's query API:
5
+ * - `db.transaction(async (tx) => …)` runs an interactive transaction that
6
+ * commits or rolls back as a unit.
7
+ * - `db.execute(sql`…`)` runs parameterized raw SQL; `sql.identifier()` safely
8
+ * quotes dynamic table and column names, and `sql`${value}`` parameterizes
9
+ * values.
7
10
  *
8
- * SCHEMA-DRIVEN COLUMNS. Unlike Prisma whose delegate applies the model's
9
- * `@map` for free — this adapter writes raw SQL, so it would otherwise bypass any
10
- * fieldcolumn translation. It therefore derives every table + column name from
11
- * the SAME rule the provisioner uses (`generateProvisionPlan`):
11
+ * Table and column names come from your schema, not from a hand-written Drizzle
12
+ * table. Because this adapter issues raw SQL, it would otherwise bypass any
13
+ * field-to-column translation, so it derives every name from the same rule the
14
+ * table provisioner uses:
12
15
  * table = `model.tableName ?? key`
13
- * column = `fieldMeta.column ?? camelToSnake(field)` (+ the model's tenancy column)
14
- * so `ablo migrate` (which emits `operator_id`) and this adapter (which now writes
15
- * `operator_id`) COMPOSE. Define the schema once, point Ablo at your Postgres
16
- * no hand-written parallel Drizzle table. The adapter is the translation boundary:
17
- * its public surface (rows in/out, outbox `data`) is field-keyed (the SDK shape);
18
- * the physical columns it reads/writes are snake_case.
16
+ * column = `fieldMeta.column ?? camelToSnake(field)` (plus the tenancy column)
17
+ * This keeps the tables `ablo migrate` creates (for example `operator_id`) and the
18
+ * columns this adapter reads and writes in agreement. You define the schema once
19
+ * and point the engine at your Postgres database. The adapter is the translation
20
+ * boundary: the rows it accepts and returns, and the outbox `data` it writes, are
21
+ * keyed by field name, while the physical columns it touches are snake_case.
19
22
  *
20
- * IMPORTANT GOTCHAS (from drizzle-orm docs):
21
- * 1. Interactive `db.transaction` requires a driver that supports it. Neon's
22
- * `neon-http` driver does NOT (single-shot only) use `neon-serverless`
23
- * (WebSocket) or `pg`. With neon-http the commit path throws at runtime.
24
- * 2. `db.execute` result shape is driver-specific (postgres-js returns an
25
- * array-like RowList; node-postgres returns `{ rows }`). `rowsOf()`
23
+ * Two things to know about drivers:
24
+ * 1. Interactive `db.transaction` needs a driver that supports it. Neon's
25
+ * `neon-http` driver is single-shot and does not, so use `neon-serverless`
26
+ * (over WebSocket) or `pg`; under `neon-http` the commit path throws at
27
+ * runtime.
28
+ * 2. The `db.execute` result shape is driver-specific `postgres-js` returns an
29
+ * array-like row list, while `node-postgres` returns `{ rows }`. `rowsOf`
26
30
  * normalizes both.
27
31
  *
28
- * We use `sql` + `db.execute` for ALL writes (not the fluent builder) so the
29
- * adapter is one small, fully-typed unit with no per-driver builder generics.
32
+ * Every write goes through `sql` and `db.execute` rather than the fluent builder,
33
+ * which keeps the adapter one small, fully typed unit with no per-driver builder
34
+ * generics.
30
35
  */
31
36
  import { AbloValidationError } from '../../errors.js';
32
37
  import { sql } from 'drizzle-orm';
@@ -82,14 +87,14 @@ export function drizzleDataSource(db, schema) {
82
87
  };
83
88
  const columnFor = (mc, field) => mc.fieldToColumn.get(field) ?? camelToSnake(field);
84
89
  const fieldFor = (mc, column) => mc.columnToField.get(column) ?? snakeToCamel(column);
85
- /** Field-keyed (SDK shape) column-keyed (physical), for INSERT/UPDATE. */
90
+ /** Field-keyed row to column-keyed row, for INSERT and UPDATE values. */
86
91
  const toColumns = (mc, row) => {
87
92
  const out = {};
88
93
  for (const k of Object.keys(row))
89
94
  out[columnFor(mc, k)] = row[k];
90
95
  return out;
91
96
  };
92
- /** Column-keyed (RETURNING * / SELECT *) field-keyed (SDK shape), for reads + results. */
97
+ /** Column-keyed row (from `RETURNING *` or `SELECT *`) back to a field-keyed row, for reads and results. */
93
98
  const toFields = (mc, row) => {
94
99
  const out = {};
95
100
  for (const k of Object.keys(row))
@@ -144,8 +149,9 @@ export function drizzleDataSource(db, schema) {
144
149
  async commit(change) {
145
150
  return db.transaction(async (tx) => {
146
151
  const cached = rowsOf(await tx.execute(sql `SELECT response FROM ablo_idempotency WHERE client_tx_id = ${change.clientTxId} LIMIT 1`));
147
- if (cached.length > 0)
148
- return { rows: cached[0].response };
152
+ const cachedRow = cached[0];
153
+ if (cachedRow)
154
+ return { rows: cachedRow.response };
149
155
  const rows = [];
150
156
  for (const [index, op] of change.operations.entries()) {
151
157
  const row = await applyOperation(tx, op);
@@ -180,7 +186,7 @@ export function drizzleDataSource(db, schema) {
180
186
  occurredAt: r.occurred_at != null ? Number(r.occurred_at) : null,
181
187
  cursor: String(r.cursor),
182
188
  }));
183
- return { events, nextCursor: events.length > 0 ? events[events.length - 1].cursor : null };
189
+ return { events, nextCursor: events.at(-1)?.cursor ?? null };
184
190
  },
185
191
  };
186
192
  }
@@ -1,36 +1,38 @@
1
1
  /**
2
- * Kysely Data Source adapter. Same adapter interface + conformance shape as
3
- * `prismaDataSource` / `drizzleDataSource`, built against Kysely's REAL
4
- * query-builder API:
5
- * - `db.transaction().execute(async (trx) => …)` — interactive transaction.
6
- * - `insertInto/updateTable/deleteFrom/selectFrom` + `returningAll()`
7
- * the fluent builder; table/column names are plain strings, so no raw
8
- * SQL tag is needed and this module imports NOTHING from `kysely`
9
- * (structural `KyselyLike`, mirroring the Prisma adapter's zero-dep
10
- * `PrismaLike`).
2
+ * The Kysely adapter for the data-source interface. It implements the same
3
+ * {@link DataSourceAdapter} contract as {@link prismaDataSource} and
4
+ * {@link drizzleDataSource} and passes the same conformance suite, built against
5
+ * Kysely's query builder:
6
+ * - `db.transaction().execute(async (trx) => …)` runs an interactive transaction.
7
+ * - `insertInto` / `updateTable` / `deleteFrom` / `selectFrom` with
8
+ * `returningAll()` form the fluent query. Table and column names are plain
9
+ * strings, so the adapter needs no raw-SQL tag and imports nothing from
10
+ * `kysely`; it depends only on the structural {@link KyselyLike} shape, the
11
+ * same approach the Prisma adapter takes with {@link PrismaLike}.
11
12
  *
12
- * SCHEMA-DRIVEN COLUMNS. Kysely is SQL-near: it passes the column names you
13
- * give it through verbatim (no Prisma-style `@map`). Like the Drizzle
14
- * adapter, every table + column name is derived from the SAME rule the
15
- * provisioner uses (`generateProvisionPlan`):
13
+ * Table and column names come from your schema. Kysely passes the column names you
14
+ * give it straight through to SQL, so, like the Drizzle adapter, this one derives
15
+ * every name from the same rule the table provisioner uses:
16
16
  * table = `model.tableName ?? key`
17
- * column = `fieldMeta.column ?? camelToSnake(field)` (+ the tenancy column)
18
- * so `ablo migrate` (which emits `operator_id`) and this adapter COMPOSE.
19
- * The adapter is the translation boundary: rows in/out are field-keyed (the
20
- * SDK shape); the physical columns it reads/writes are snake_case.
17
+ * column = `fieldMeta.column ?? camelToSnake(field)` (plus the tenancy column)
18
+ * This keeps the tables `ablo migrate` creates (for example `operator_id`) and the
19
+ * columns this adapter uses in agreement. The adapter is the translation boundary:
20
+ * the rows it accepts and returns are keyed by field name, while the physical
21
+ * columns are snake_case.
21
22
  *
22
- * JSONB note: the outbox `data` / idempotency `response` values are passed
23
- * as JSON strings Postgres infers the parameter type from the target
24
- * `jsonb` column, so the coercion is server-side and driver-agnostic (no
25
- * `::jsonb` cast available without raw SQL).
23
+ * A note on JSON columns: the outbox `data` and idempotency `response` values are
24
+ * passed as JSON strings. Postgres infers the parameter type from the target
25
+ * `jsonb` column, so the conversion happens on the server and works across drivers,
26
+ * without the `::jsonb` cast that only raw SQL allows.
26
27
  */
27
28
  import type { DataSourceAdapter, Row } from '../adapter.js';
28
29
  import type { Schema, SchemaRecord } from '../../schema/schema.js';
29
30
  /**
30
- * The subset of a Kysely instance (or transaction handle) the adapter calls.
31
- * Structural on purpose declared with method shorthand so a real
32
- * `Kysely<DB>` (whose params are narrowed to `keyof DB`) stays assignable
33
- * under TypeScript's method bivariance, exactly like `PrismaLike`.
31
+ * The subset of a Kysely instance, or transaction handle, that the adapter calls.
32
+ * It is structural by design: declaring the members with method shorthand lets a
33
+ * real `Kysely<DB>` whose parameters are narrowed to `keyof DB` stay assignable
34
+ * under TypeScript's method-parameter bivariance, the same way {@link PrismaLike}
35
+ * accepts a real `PrismaClient`.
34
36
  */
35
37
  export interface KyselyLike {
36
38
  selectFrom(table: string): KyselySelectBuilder;
@@ -1,28 +1,29 @@
1
1
  /**
2
- * Kysely Data Source adapter. Same adapter interface + conformance shape as
3
- * `prismaDataSource` / `drizzleDataSource`, built against Kysely's REAL
4
- * query-builder API:
5
- * - `db.transaction().execute(async (trx) => …)` — interactive transaction.
6
- * - `insertInto/updateTable/deleteFrom/selectFrom` + `returningAll()`
7
- * the fluent builder; table/column names are plain strings, so no raw
8
- * SQL tag is needed and this module imports NOTHING from `kysely`
9
- * (structural `KyselyLike`, mirroring the Prisma adapter's zero-dep
10
- * `PrismaLike`).
2
+ * The Kysely adapter for the data-source interface. It implements the same
3
+ * {@link DataSourceAdapter} contract as {@link prismaDataSource} and
4
+ * {@link drizzleDataSource} and passes the same conformance suite, built against
5
+ * Kysely's query builder:
6
+ * - `db.transaction().execute(async (trx) => …)` runs an interactive transaction.
7
+ * - `insertInto` / `updateTable` / `deleteFrom` / `selectFrom` with
8
+ * `returningAll()` form the fluent query. Table and column names are plain
9
+ * strings, so the adapter needs no raw-SQL tag and imports nothing from
10
+ * `kysely`; it depends only on the structural {@link KyselyLike} shape, the
11
+ * same approach the Prisma adapter takes with {@link PrismaLike}.
11
12
  *
12
- * SCHEMA-DRIVEN COLUMNS. Kysely is SQL-near: it passes the column names you
13
- * give it through verbatim (no Prisma-style `@map`). Like the Drizzle
14
- * adapter, every table + column name is derived from the SAME rule the
15
- * provisioner uses (`generateProvisionPlan`):
13
+ * Table and column names come from your schema. Kysely passes the column names you
14
+ * give it straight through to SQL, so, like the Drizzle adapter, this one derives
15
+ * every name from the same rule the table provisioner uses:
16
16
  * table = `model.tableName ?? key`
17
- * column = `fieldMeta.column ?? camelToSnake(field)` (+ the tenancy column)
18
- * so `ablo migrate` (which emits `operator_id`) and this adapter COMPOSE.
19
- * The adapter is the translation boundary: rows in/out are field-keyed (the
20
- * SDK shape); the physical columns it reads/writes are snake_case.
17
+ * column = `fieldMeta.column ?? camelToSnake(field)` (plus the tenancy column)
18
+ * This keeps the tables `ablo migrate` creates (for example `operator_id`) and the
19
+ * columns this adapter uses in agreement. The adapter is the translation boundary:
20
+ * the rows it accepts and returns are keyed by field name, while the physical
21
+ * columns are snake_case.
21
22
  *
22
- * JSONB note: the outbox `data` / idempotency `response` values are passed
23
- * as JSON strings Postgres infers the parameter type from the target
24
- * `jsonb` column, so the coercion is server-side and driver-agnostic (no
25
- * `::jsonb` cast available without raw SQL).
23
+ * A note on JSON columns: the outbox `data` and idempotency `response` values are
24
+ * passed as JSON strings. Postgres infers the parameter type from the target
25
+ * `jsonb` column, so the conversion happens on the server and works across drivers,
26
+ * without the `::jsonb` cast that only raw SQL allows.
26
27
  */
27
28
  import { AbloValidationError } from '../../errors.js';
28
29
  import { outboxEventSchema } from '../contract.js';
@@ -75,14 +76,14 @@ export function kyselyDataSource(db, schema) {
75
76
  };
76
77
  const columnFor = (mc, field) => mc.fieldToColumn.get(field) ?? camelToSnake(field);
77
78
  const fieldFor = (mc, column) => mc.columnToField.get(column) ?? snakeToCamel(column);
78
- /** Field-keyed (SDK shape) column-keyed (physical), for INSERT/UPDATE. */
79
+ /** Field-keyed row to column-keyed row, for INSERT and UPDATE values. */
79
80
  const toColumns = (mc, row) => {
80
81
  const out = {};
81
82
  for (const k of Object.keys(row))
82
83
  out[columnFor(mc, k)] = row[k];
83
84
  return out;
84
85
  };
85
- /** Column-keyed (RETURNING * / SELECT *) field-keyed (SDK shape). */
86
+ /** Column-keyed row (from `RETURNING *` or `SELECT *`) back to a field-keyed row. */
86
87
  const toFields = (mc, row) => {
87
88
  const out = {};
88
89
  for (const k of Object.keys(row))
@@ -153,8 +154,9 @@ export function kyselyDataSource(db, schema) {
153
154
  .where('client_tx_id', '=', change.clientTxId)
154
155
  .limit(1)
155
156
  .execute();
156
- if (cached.length > 0) {
157
- const response = cached[0].response;
157
+ const cachedRow = cached[0];
158
+ if (cachedRow) {
159
+ const response = cachedRow.response;
158
160
  return {
159
161
  rows: (typeof response === 'string' ? JSON.parse(response) : response),
160
162
  };
@@ -204,7 +206,7 @@ export function kyselyDataSource(db, schema) {
204
206
  occurredAt: r.occurred_at != null ? Number(r.occurred_at) : null,
205
207
  cursor: String(r.cursor),
206
208
  }));
207
- return { events, nextCursor: events.length > 0 ? events[events.length - 1].cursor : null };
209
+ return { events, nextCursor: events.at(-1)?.cursor ?? null };
208
210
  },
209
211
  };
210
212
  }
@@ -1,12 +1,13 @@
1
1
  /**
2
- * In-memory reference Data Source adapter the canonical correct implementation
3
- * of the adapter interface. It is the test double for the bridge/handler AND the thing the
4
- * conformance suite runs against to prove the suite itself is real (same role as
5
- * the server's `memoryTenantDirectory`). A new ORM adapter is "done" when it
6
- * passes the same suite this one passes.
2
+ * The in-memory reference implementation of {@link DataSourceAdapter}. It is the
3
+ * simplest correct adapter: a stand-in you can commit to and read from in tests
4
+ * without a database, and the fixture the conformance suite runs against to confirm
5
+ * the suite exercises real behavior. An adapter for a given object-relational
6
+ * mapper is complete when it passes the same suite this one passes.
7
7
  *
8
- * It models the real semantics minimally but faithfully: one canonical row store
9
- * per model, an idempotency ledger keyed by `clientTxId`, and a monotonic outbox.
8
+ * It models the semantics minimally but faithfully: one row store per model, an
9
+ * idempotency ledger keyed by `clientTxId`, and an append-only outbox with a
10
+ * monotonic cursor.
10
11
  */
11
12
  import type { DataSourceAdapter } from '../adapter.js';
12
13
  export declare function memoryDataSource(): DataSourceAdapter;
@@ -1,12 +1,13 @@
1
1
  /**
2
- * In-memory reference Data Source adapter the canonical correct implementation
3
- * of the adapter interface. It is the test double for the bridge/handler AND the thing the
4
- * conformance suite runs against to prove the suite itself is real (same role as
5
- * the server's `memoryTenantDirectory`). A new ORM adapter is "done" when it
6
- * passes the same suite this one passes.
2
+ * The in-memory reference implementation of {@link DataSourceAdapter}. It is the
3
+ * simplest correct adapter: a stand-in you can commit to and read from in tests
4
+ * without a database, and the fixture the conformance suite runs against to confirm
5
+ * the suite exercises real behavior. An adapter for a given object-relational
6
+ * mapper is complete when it passes the same suite this one passes.
7
7
  *
8
- * It models the real semantics minimally but faithfully: one canonical row store
9
- * per model, an idempotency ledger keyed by `clientTxId`, and a monotonic outbox.
8
+ * It models the semantics minimally but faithfully: one row store per model, an
9
+ * idempotency ledger keyed by `clientTxId`, and an append-only outbox with a
10
+ * monotonic cursor.
10
11
  */
11
12
  import { AbloValidationError } from '../../errors.js';
12
13
  function rowId(op) {
@@ -63,7 +64,7 @@ export function memoryDataSource() {
63
64
  return {
64
65
  capabilities: { transactions: true, propose: false, schemaIntrospection: false },
65
66
  migrations() {
66
- // In-memory: no table-creation SQL. A real ORM adapter ships ablo_idempotency + ablo_outbox here.
67
+ // Nothing to create in memory. A database-backed adapter returns the SQL for its ablo_idempotency and ablo_outbox tables here.
67
68
  return [];
68
69
  },
69
70
  async read(req) {
@@ -108,7 +109,7 @@ export function memoryDataSource() {
108
109
  const page = outbox.filter((e) => Number(e.cursor) > after).slice(0, limit);
109
110
  return {
110
111
  events: page,
111
- nextCursor: page.length > 0 ? page[page.length - 1].cursor : null,
112
+ nextCursor: page.at(-1)?.cursor ?? null,
112
113
  };
113
114
  },
114
115
  };
@@ -1,20 +1,21 @@
1
1
  /**
2
- * Prisma Data Source adapter. The first real ORM adapter (Auth.js pattern: one
3
- * package per ORM, all behind the `DataSourceAdapter` interface, all proven by the
4
- * same conformance suite the in-memory reference passes).
2
+ * The Prisma adapter for the data-source interface. It implements
3
+ * {@link DataSourceAdapter} against a Prisma client and passes the same conformance
4
+ * suite as the in-memory reference and the other adapters.
5
5
  *
6
- * It owns the transactional outbox + idempotency so the customer never writes
7
- * them: `commit` runs the app-row mutations, the `ablo_outbox` append, and the
8
- * `ablo_idempotency` record in ONE `prisma.$transaction`. `migrations()` ships
9
- * the table-creation SQL for those two tables.
6
+ * The adapter owns the transactional outbox and idempotency bookkeeping, so you
7
+ * never write them: `commit` runs the row mutations, the `ablo_outbox` append, and
8
+ * the `ablo_idempotency` record inside a single `prisma.$transaction`, and
9
+ * `migrations` returns the SQL that creates those two tables.
10
10
  *
11
- * No `@prisma/client` dependency: the client is accepted structurally
12
- * (`PrismaLike`), so this compiles in the SDK package and is unit-testable with
13
- * a fake, while a real `PrismaClient` satisfies it at the call site.
11
+ * It takes no dependency on `@prisma/client`. The client is accepted structurally
12
+ * as {@link PrismaLike}, so this module compiles without Prisma installed and can
13
+ * be tested with a fake, while a real `PrismaClient` satisfies the shape at the
14
+ * call site.
14
15
  */
15
16
  import type { DataSourceAdapter, Row } from '../adapter.js';
16
17
  import type { SchemaRecord, Schema } from '../../schema/schema.js';
17
- /** A Prisma model delegate (the subset we call). */
18
+ /** A Prisma model delegate the subset of its methods the adapter calls. */
18
19
  export interface PrismaDelegate {
19
20
  findUnique(args: {
20
21
  where: {
@@ -46,7 +47,7 @@ export interface PrismaRaw {
46
47
  $executeRawUnsafe(query: string, ...values: unknown[]): Promise<number>;
47
48
  $queryRawUnsafe<T = unknown>(query: string, ...values: unknown[]): Promise<T>;
48
49
  }
49
- /** A Prisma client (or interactive-transaction client) structural, no SDK dependency. */
50
+ /** A Prisma client, or its interactive-transaction client, as a structural shape that needs no `@prisma/client` import. */
50
51
  export interface PrismaLike extends PrismaRaw {
51
52
  $transaction<T>(fn: (tx: PrismaLike & PrismaRaw) => Promise<T>): Promise<T>;
52
53
  }
@@ -1,34 +1,31 @@
1
1
  /**
2
- * Prisma Data Source adapter. The first real ORM adapter (Auth.js pattern: one
3
- * package per ORM, all behind the `DataSourceAdapter` interface, all proven by the
4
- * same conformance suite the in-memory reference passes).
2
+ * The Prisma adapter for the data-source interface. It implements
3
+ * {@link DataSourceAdapter} against a Prisma client and passes the same conformance
4
+ * suite as the in-memory reference and the other adapters.
5
5
  *
6
- * It owns the transactional outbox + idempotency so the customer never writes
7
- * them: `commit` runs the app-row mutations, the `ablo_outbox` append, and the
8
- * `ablo_idempotency` record in ONE `prisma.$transaction`. `migrations()` ships
9
- * the table-creation SQL for those two tables.
6
+ * The adapter owns the transactional outbox and idempotency bookkeeping, so you
7
+ * never write them: `commit` runs the row mutations, the `ablo_outbox` append, and
8
+ * the `ablo_idempotency` record inside a single `prisma.$transaction`, and
9
+ * `migrations` returns the SQL that creates those two tables.
10
10
  *
11
- * No `@prisma/client` dependency: the client is accepted structurally
12
- * (`PrismaLike`), so this compiles in the SDK package and is unit-testable with
13
- * a fake, while a real `PrismaClient` satisfies it at the call site.
11
+ * It takes no dependency on `@prisma/client`. The client is accepted structurally
12
+ * as {@link PrismaLike}, so this module compiles without Prisma installed and can
13
+ * be tested with a fake, while a real `PrismaClient` satisfies the shape at the
14
+ * call site.
14
15
  */
15
16
  import { AbloValidationError } from '../../errors.js';
16
17
  import { outboxEventSchema } from '../contract.js';
17
18
  import { adapterTableMigrations } from '../migrations.js';
18
- const lowerFirst = (s) => (s ? s[0].toLowerCase() + s.slice(1) : s);
19
+ const lowerFirst = (s) => (s ? s.charAt(0).toLowerCase() + s.slice(1) : s);
19
20
  /**
20
- * Resolve a model's Prisma delegate by name. This is the ONE irreducible cast in
21
- * the adapter layer, and it's a genuine type-system limit, not laziness:
22
- *
23
- * - Inside `prisma.$transaction(tx => …)` the writes MUST go through the
24
- * transactional client `tx`, and the model is only known as a runtime string.
25
- * - Prisma's client (and transaction handle) is NOMINALLY keyed (`{ task: TaskDelegate; }`), so a
26
- * dynamic `tx[name]` is `unknown` to the compiler there is no key to infer.
27
- *
28
- * Dynamic property access on a statically-keyed type cannot be typed without an
29
- * assertion; this is the reflection boundary, validated at runtime (`findMany` is
30
- * a function) right after. `ablo generate` removes even this by emitting a typed
31
- * `model → delegate` map, at which point this helper is replaced by a lookup.
21
+ * Resolves a model's Prisma delegate by name. This is the one unavoidable cast in
22
+ * the adapter, and it reflects a real limit of the type system rather than a
23
+ * shortcut. Writes inside `prisma.$transaction(tx => …)` must go through the
24
+ * transactional client `tx`, and the model is known only as a runtime string.
25
+ * Prisma keys its client by fixed property names (`{ task: TaskDelegate; }`), so
26
+ * a dynamic `tx[name]` lookup is `unknown` to the compiler: there is no static key
27
+ * to infer from a string. The cast is checked at runtime immediately afterward by
28
+ * confirming that `findMany` is a function on the resolved delegate.
32
29
  */
33
30
  function delegateFor(client, name) {
34
31
  const delegate = client[name];
@@ -37,7 +34,7 @@ function delegateFor(client, name) {
37
34
  }
38
35
  return delegate;
39
36
  }
40
- /** Translate a Source `where` tuple set into a Prisma `where` object. */
37
+ /** Translates a source-query `where` tuple set into a Prisma `where` object. */
41
38
  function toPrismaWhere(where) {
42
39
  const out = {};
43
40
  for (const clause of where ?? []) {
@@ -104,7 +101,7 @@ function rowId(op) {
104
101
  }
105
102
  export function prismaDataSource(prisma, schema, options = {}) {
106
103
  const delegateName = options.delegateName ?? lowerFirst;
107
- void schema; // reserved for codegen-typed reads / model validation
104
+ void schema; // held for typed reads and model validation
108
105
  const applyOperation = async (tx, op) => {
109
106
  const delegate = delegateFor(tx, delegateName(op.model));
110
107
  const id = rowId(op);
@@ -138,14 +135,15 @@ export function prismaDataSource(prisma, schema, options = {}) {
138
135
  return prisma.$transaction(async (tx) => {
139
136
  // Idempotency: a duplicate clientTxId returns the original rows, no re-apply.
140
137
  const cached = await tx.$queryRawUnsafe(`SELECT response FROM ablo_idempotency WHERE client_tx_id = $1 LIMIT 1`, change.clientTxId);
141
- if (cached.length > 0)
142
- return { rows: cached[0].response };
138
+ const cachedRow = cached[0];
139
+ if (cachedRow)
140
+ return { rows: cachedRow.response };
143
141
  const rows = [];
144
142
  for (const [index, op] of change.operations.entries()) {
145
143
  const row = await applyOperation(tx, op);
146
144
  rows.push(row);
147
145
  const entityId = String(row.id ?? rowId(op));
148
- // Transactional outbox: one event per op, written in THIS transaction.
146
+ // Transactional outbox: one event per operation, written in this same transaction.
149
147
  await tx.$executeRawUnsafe(`INSERT INTO ablo_outbox (id, model, entity_id, type, data, client_tx_id, occurred_at)
150
148
  VALUES ($1, $2, $3, $4, $5::jsonb, $6, $7)`, `${change.clientTxId}:${index}`, op.model, entityId, op.type, JSON.stringify(op.type === 'DELETE' ? null : row), change.clientTxId, Date.now());
151
149
  }
@@ -170,7 +168,7 @@ export function prismaDataSource(prisma, schema, options = {}) {
170
168
  }));
171
169
  return {
172
170
  events,
173
- nextCursor: events.length > 0 ? events[events.length - 1].cursor : null,
171
+ nextCursor: events.at(-1)?.cursor ?? null,
174
172
  };
175
173
  },
176
174
  };
@@ -1,28 +1,35 @@
1
1
  /**
2
- * Data Source adapter conformance suite the shared "is this adapter correct?"
3
- * test set, in the Auth.js `@auth/adapter-test` mould. Every ORM adapter
4
- * (Prisma/Drizzle/Kysely) and any hand-written handler runs THIS to prove,
5
- * before production, the guarantees the adapter interface promises. A new adapter is "done"
6
- * when it passes not when it compiles.
2
+ * The conformance suite for data-source adapters: a shared set of tests that checks
3
+ * whether an adapter is correct. Every adapter in this package (Prisma, Drizzle,
4
+ * Kysely) and any adapter you write yourself runs this suite to confirm it upholds
5
+ * the guarantees {@link DataSourceAdapter} promises. An adapter is complete when it
6
+ * passes, not merely when it compiles.
7
7
  *
8
- * Runner-agnostic: checks are plain async functions that throw (node:assert) on
9
- * failure. `runDataSourceTests` registers them with whatever `it`/`test` you
10
- * pass, so it works under vitest, jest, or node:test:
8
+ * The suite is runner-agnostic: each check is a plain async function that throws,
9
+ * via `node:assert`, on failure. {@link runDataSourceTests} registers the checks
10
+ * with whichever `it` or `test` function you pass, so it runs under vitest, jest,
11
+ * or `node:test`:
11
12
  *
12
13
  * import { it } from 'vitest';
13
14
  * runDataSourceTests(memoryDataSource, it);
14
15
  *
15
- * Scope: this covers the ADAPTER contract (commit idempotency, read-after-write,
16
- * the transactional outbox + cursor). Signature/scope rejection is a HANDLER
17
- * concern (the adapter never sees a signature) and is tested separately.
16
+ * The checks cover the adapter contract: commit idempotency, read-after-write, and
17
+ * the transactional outbox with its cursor. They do not cover request-signature or
18
+ * scope rejection, which the HTTP handler enforces before the adapter is ever
19
+ * called and which is tested separately.
18
20
  */
19
21
  import type { DataSourceAdapter } from './adapter.js';
22
+ /** A factory that returns a fresh adapter. Each check calls it to start from clean state. */
20
23
  export type MakeAdapter = () => DataSourceAdapter | Promise<DataSourceAdapter>;
21
24
  /** A single conformance check. `run` throws on failure. */
22
25
  export interface ConformanceCheck {
23
26
  readonly name: string;
24
27
  run(): Promise<void>;
25
28
  }
29
+ /**
30
+ * Builds the list of conformance checks for an adapter. Call this to run the checks
31
+ * yourself, or use {@link runDataSourceTests} to register them with a test runner.
32
+ */
26
33
  export declare function dataSourceConformanceChecks(make: MakeAdapter): ConformanceCheck[];
27
34
  /**
28
35
  * Register the conformance checks with a test runner's `it`/`test` function.