@abloatai/ablo 0.26.0 → 0.28.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 (418) hide show
  1. package/CHANGELOG.md +42 -2
  2. package/README.md +102 -86
  3. package/dist/BaseSyncedStore.d.ts +85 -88
  4. package/dist/BaseSyncedStore.js +134 -151
  5. package/dist/Database.d.ts +68 -69
  6. package/dist/Database.js +316 -135
  7. package/dist/{ObjectPool.d.ts → InstanceCache.d.ts} +10 -13
  8. package/dist/{ObjectPool.js → InstanceCache.js} +85 -83
  9. package/dist/LazyReferenceCollection.d.ts +11 -15
  10. package/dist/LazyReferenceCollection.js +12 -16
  11. package/dist/Model.d.ts +54 -52
  12. package/dist/Model.js +78 -62
  13. package/dist/ModelRegistry.d.ts +21 -19
  14. package/dist/ModelRegistry.js +23 -27
  15. package/dist/NetworkMonitor.d.ts +5 -6
  16. package/dist/NetworkMonitor.js +5 -6
  17. package/dist/SyncClient.d.ts +122 -118
  18. package/dist/SyncClient.js +541 -245
  19. package/dist/adapters/alwaysOnline.d.ts +6 -8
  20. package/dist/adapters/alwaysOnline.js +6 -8
  21. package/dist/adapters/inMemoryStorage.d.ts +10 -9
  22. package/dist/adapters/inMemoryStorage.js +21 -9
  23. package/dist/agent/Agent.d.ts +27 -32
  24. package/dist/agent/Agent.js +18 -19
  25. package/dist/agent/index.d.ts +4 -4
  26. package/dist/agent/index.js +5 -5
  27. package/dist/agent/session.d.ts +47 -44
  28. package/dist/agent/session.js +37 -48
  29. package/dist/agent/types.d.ts +26 -31
  30. package/dist/agent/types.js +6 -7
  31. package/dist/ai-sdk/coordinatedTool.d.ts +108 -0
  32. package/dist/ai-sdk/{coordinated-tool.js → coordinatedTool.js} +44 -38
  33. package/dist/ai-sdk/coordinationContext.d.ts +46 -0
  34. package/dist/ai-sdk/{coordination-context.js → coordinationContext.js} +26 -33
  35. package/dist/ai-sdk/index.d.ts +25 -22
  36. package/dist/ai-sdk/index.js +25 -22
  37. package/dist/ai-sdk/wrap.d.ts +6 -7
  38. package/dist/ai-sdk/wrap.js +1 -1
  39. package/dist/auth/credentialPolicy.d.ts +69 -74
  40. package/dist/auth/credentialPolicy.js +51 -56
  41. package/dist/auth/credentialSource.d.ts +6 -5
  42. package/dist/auth/credentialSource.js +9 -10
  43. package/dist/auth/index.d.ts +59 -58
  44. package/dist/auth/index.js +31 -37
  45. package/dist/auth/schemas.d.ts +5 -4
  46. package/dist/auth/schemas.js +5 -4
  47. package/dist/batching/index.d.ts +19 -21
  48. package/dist/batching/index.js +14 -17
  49. package/dist/cli.cjs +173 -121
  50. package/dist/client/Ablo.d.ts +97 -74
  51. package/dist/client/Ablo.js +129 -163
  52. package/dist/client/ApiClient.d.ts +30 -19
  53. package/dist/client/ApiClient.js +442 -81
  54. package/dist/client/auth.d.ts +47 -47
  55. package/dist/client/auth.js +108 -117
  56. package/dist/client/claimHeartbeatLoop.d.ts +50 -0
  57. package/dist/client/claimHeartbeatLoop.js +88 -0
  58. package/dist/client/consoleLogger.d.ts +5 -6
  59. package/dist/client/consoleLogger.js +5 -6
  60. package/dist/client/createInternalComponents.d.ts +16 -17
  61. package/dist/client/createInternalComponents.js +26 -31
  62. package/dist/client/createModelProxy.d.ts +130 -120
  63. package/dist/client/createModelProxy.js +152 -122
  64. package/dist/client/credentialEndpoint.d.ts +40 -42
  65. package/dist/client/credentialEndpoint.js +35 -36
  66. package/dist/client/functionalUpdate.d.ts +29 -27
  67. package/dist/client/functionalUpdate.js +21 -21
  68. package/dist/client/hostedEndpoints.d.ts +9 -12
  69. package/dist/client/hostedEndpoints.js +9 -12
  70. package/dist/client/httpClient.d.ts +59 -53
  71. package/dist/client/httpClient.js +29 -31
  72. package/dist/client/identity.d.ts +15 -20
  73. package/dist/client/identity.js +47 -58
  74. package/dist/client/modelRegistration.d.ts +5 -9
  75. package/dist/client/modelRegistration.js +78 -87
  76. package/dist/client/options.d.ts +157 -157
  77. package/dist/client/options.js +3 -7
  78. package/dist/client/registerDataSource.d.ts +9 -9
  79. package/dist/client/registerDataSource.js +15 -16
  80. package/dist/client/resourceTypes.d.ts +64 -75
  81. package/dist/client/resourceTypes.js +4 -10
  82. package/dist/client/schemaConfig.d.ts +31 -43
  83. package/dist/client/schemaConfig.js +38 -50
  84. package/dist/client/sessionMint.d.ts +16 -12
  85. package/dist/client/sessionMint.js +26 -31
  86. package/dist/client/validateAbloOptions.d.ts +12 -14
  87. package/dist/client/validateAbloOptions.js +8 -9
  88. package/dist/client/writeOptionsSchema.d.ts +18 -16
  89. package/dist/client/writeOptionsSchema.js +23 -20
  90. package/dist/client/wsMutationExecutor.d.ts +16 -20
  91. package/dist/client/wsMutationExecutor.js +18 -23
  92. package/dist/commit/contract.d.ts +493 -0
  93. package/dist/commit/contract.js +187 -0
  94. package/dist/commit/index.d.ts +6 -0
  95. package/dist/commit/index.js +5 -0
  96. package/dist/context.d.ts +6 -4
  97. package/dist/context.js +6 -4
  98. package/dist/coordination/index.d.ts +10 -8
  99. package/dist/coordination/index.js +14 -12
  100. package/dist/coordination/schema.d.ts +176 -128
  101. package/dist/coordination/schema.js +197 -133
  102. package/dist/coordination/trace.d.ts +9 -10
  103. package/dist/coordination/trace.js +13 -14
  104. package/dist/core/DatabaseManager.d.ts +5 -7
  105. package/dist/core/DatabaseManager.js +15 -19
  106. package/dist/core/QueryProcessor.d.ts +7 -9
  107. package/dist/core/QueryProcessor.js +22 -28
  108. package/dist/core/QueryView.d.ts +8 -8
  109. package/dist/core/QueryView.js +2 -2
  110. package/dist/core/StoreManager.d.ts +14 -14
  111. package/dist/core/StoreManager.js +33 -24
  112. package/dist/core/ViewRegistry.d.ts +5 -5
  113. package/dist/core/ViewRegistry.js +4 -4
  114. package/dist/core/index.d.ts +17 -12
  115. package/dist/core/index.js +32 -26
  116. package/dist/core/openIDBWithTimeout.d.ts +38 -36
  117. package/dist/core/openIDBWithTimeout.js +42 -43
  118. package/dist/core/queryUtils.d.ts +45 -0
  119. package/dist/core/queryUtils.js +69 -0
  120. package/dist/core/storeContract.d.ts +63 -61
  121. package/dist/core/storeContract.js +8 -12
  122. package/dist/environment.d.ts +28 -0
  123. package/dist/environment.js +21 -0
  124. package/dist/errorCodes.d.ts +107 -99
  125. package/dist/errorCodes.js +137 -134
  126. package/dist/errors.d.ts +160 -166
  127. package/dist/errors.js +155 -158
  128. package/dist/index.d.ts +36 -27
  129. package/dist/index.js +91 -86
  130. package/dist/interfaces/index.d.ts +102 -113
  131. package/dist/interfaces/index.js +5 -4
  132. package/dist/keys/index.d.ts +27 -29
  133. package/dist/keys/index.js +41 -40
  134. package/dist/mutators/RecordingTransaction.d.ts +16 -16
  135. package/dist/mutators/RecordingTransaction.js +31 -37
  136. package/dist/mutators/Transaction.d.ts +18 -26
  137. package/dist/mutators/Transaction.js +14 -20
  138. package/dist/mutators/UndoManager.d.ts +124 -131
  139. package/dist/mutators/UndoManager.js +177 -156
  140. package/dist/mutators/defineMutators.d.ts +23 -34
  141. package/dist/mutators/defineMutators.js +14 -20
  142. package/dist/mutators/inverseOp.d.ts +12 -15
  143. package/dist/mutators/inverseOp.js +12 -15
  144. package/dist/mutators/mutateActions.d.ts +10 -9
  145. package/dist/mutators/mutateActions.js +1 -1
  146. package/dist/mutators/readerActions.d.ts +9 -8
  147. package/dist/mutators/readerActions.js +2 -2
  148. package/dist/mutators/undoApply.d.ts +31 -27
  149. package/dist/mutators/undoApply.js +26 -24
  150. package/dist/policy/index.d.ts +5 -3
  151. package/dist/policy/index.js +5 -3
  152. package/dist/policy/types.d.ts +104 -100
  153. package/dist/policy/types.js +67 -66
  154. package/dist/query/client.d.ts +28 -23
  155. package/dist/query/client.js +45 -43
  156. package/dist/query/types.d.ts +37 -60
  157. package/dist/query/types.js +13 -33
  158. package/dist/react/AbloProvider.d.ts +1 -1
  159. package/dist/react/AbloProvider.js +2 -2
  160. package/dist/react/context.d.ts +25 -28
  161. package/dist/react/context.js +9 -10
  162. package/dist/react/index.d.ts +41 -42
  163. package/dist/react/index.js +37 -38
  164. package/dist/react/internalContext.d.ts +17 -19
  165. package/dist/react/useAblo.d.ts +28 -25
  166. package/dist/react/useAblo.js +41 -17
  167. package/dist/react/useCurrentUserId.d.ts +8 -7
  168. package/dist/react/useCurrentUserId.js +8 -7
  169. package/dist/react/useErrorListener.d.ts +7 -7
  170. package/dist/react/useErrorListener.js +10 -11
  171. package/dist/react/useMutationFailureListener.d.ts +8 -8
  172. package/dist/react/useMutationFailureListener.js +8 -8
  173. package/dist/react/useMutators.d.ts +11 -11
  174. package/dist/react/useMutators.js +3 -3
  175. package/dist/react/useReactive.js +2 -2
  176. package/dist/react/useSyncStatus.d.ts +4 -6
  177. package/dist/react/useUndoScope.d.ts +7 -9
  178. package/dist/react/useUndoScope.js +1 -1
  179. package/dist/schema/coordination.d.ts +21 -25
  180. package/dist/schema/coordination.js +21 -25
  181. package/dist/schema/ddl.d.ts +43 -39
  182. package/dist/schema/ddl.js +75 -68
  183. package/dist/schema/ddlLock.d.ts +20 -24
  184. package/dist/schema/ddlLock.js +18 -23
  185. package/dist/schema/diff.d.ts +99 -61
  186. package/dist/schema/diff.js +43 -34
  187. package/dist/schema/field.d.ts +37 -42
  188. package/dist/schema/field.js +35 -48
  189. package/dist/schema/generate.d.ts +12 -12
  190. package/dist/schema/generate.js +12 -12
  191. package/dist/schema/index.d.ts +3 -3
  192. package/dist/schema/index.js +21 -23
  193. package/dist/schema/model.d.ts +118 -143
  194. package/dist/schema/model.js +22 -33
  195. package/dist/schema/openapi.d.ts +10 -9
  196. package/dist/schema/openapi.js +5 -3
  197. package/dist/schema/queries.d.ts +29 -31
  198. package/dist/schema/queries.js +23 -25
  199. package/dist/schema/relation.d.ts +89 -99
  200. package/dist/schema/relation.js +13 -13
  201. package/dist/schema/residency.d.ts +16 -13
  202. package/dist/schema/residency.js +16 -13
  203. package/dist/schema/roles.d.ts +36 -43
  204. package/dist/schema/roles.js +31 -37
  205. package/dist/schema/schema.d.ts +64 -43
  206. package/dist/schema/schema.js +31 -32
  207. package/dist/schema/select.d.ts +13 -13
  208. package/dist/schema/select.js +13 -13
  209. package/dist/schema/serialize.d.ts +28 -31
  210. package/dist/schema/serialize.js +27 -31
  211. package/dist/schema/sugar.d.ts +17 -32
  212. package/dist/schema/sugar.js +14 -29
  213. package/dist/schema/{sync-delta-row.d.ts → syncDeltaRow.d.ts} +26 -49
  214. package/dist/schema/syncDeltaRow.js +89 -0
  215. package/dist/schema/tenancy.d.ts +44 -46
  216. package/dist/schema/tenancy.js +46 -48
  217. package/dist/server/adapter.d.ts +58 -58
  218. package/dist/server/adapter.js +13 -14
  219. package/dist/server/commit.d.ts +60 -64
  220. package/dist/server/index.d.ts +9 -10
  221. package/dist/server/index.js +1 -1
  222. package/dist/server/readConfig.d.ts +70 -0
  223. package/dist/server/readConfig.js +8 -0
  224. package/dist/server/storageMode.d.ts +23 -0
  225. package/dist/server/storageMode.js +17 -0
  226. package/dist/source/adapter.d.ts +30 -25
  227. package/dist/source/adapter.js +10 -10
  228. package/dist/source/adapters/drizzle.d.ts +28 -23
  229. package/dist/source/adapters/drizzle.js +30 -25
  230. package/dist/source/adapters/kysely.d.ts +27 -25
  231. package/dist/source/adapters/kysely.js +24 -23
  232. package/dist/source/adapters/memory.d.ts +8 -7
  233. package/dist/source/adapters/memory.js +9 -8
  234. package/dist/source/adapters/prisma.d.ts +13 -12
  235. package/dist/source/adapters/prisma.js +22 -25
  236. package/dist/source/conformance.d.ts +18 -11
  237. package/dist/source/conformance.js +17 -11
  238. package/dist/source/connector.d.ts +31 -32
  239. package/dist/source/connector.js +28 -28
  240. package/dist/source/connectorProtocol.d.ts +160 -0
  241. package/dist/source/connectorProtocol.js +162 -0
  242. package/dist/source/contract.d.ts +26 -27
  243. package/dist/source/contract.js +28 -29
  244. package/dist/source/factory.d.ts +46 -58
  245. package/dist/source/factory.js +22 -27
  246. package/dist/source/index.d.ts +7 -9
  247. package/dist/source/index.js +12 -14
  248. package/dist/source/migrations.d.ts +9 -9
  249. package/dist/source/migrations.js +9 -9
  250. package/dist/source/next.d.ts +9 -10
  251. package/dist/source/next.js +6 -7
  252. package/dist/source/pushQueue.d.ts +69 -47
  253. package/dist/source/pushQueue.js +32 -28
  254. package/dist/source/signing.d.ts +46 -17
  255. package/dist/source/signing.js +28 -11
  256. package/dist/source/types.d.ts +121 -104
  257. package/dist/source/types.js +13 -14
  258. package/dist/stores/ObjectStore.d.ts +24 -12
  259. package/dist/stores/ObjectStore.js +38 -16
  260. package/dist/stores/ObjectStoreContract.d.ts +14 -15
  261. package/dist/stores/SyncActionStore.d.ts +7 -11
  262. package/dist/stores/SyncActionStore.js +13 -17
  263. package/dist/surface.d.ts +28 -21
  264. package/dist/surface.js +29 -20
  265. package/dist/sync/{BootstrapHelper.d.ts → BootstrapFetcher.d.ts} +36 -42
  266. package/dist/sync/{BootstrapHelper.js → BootstrapFetcher.js} +76 -76
  267. package/dist/sync/ConnectionManager.d.ts +39 -50
  268. package/dist/sync/ConnectionManager.js +55 -66
  269. package/dist/sync/NetworkProbe.d.ts +24 -29
  270. package/dist/sync/NetworkProbe.js +63 -69
  271. package/dist/sync/{HydrationCoordinator.d.ts → OnDemandLoader.d.ts} +42 -41
  272. package/dist/sync/{HydrationCoordinator.js → OnDemandLoader.js} +59 -54
  273. package/dist/sync/{AreaOfInterestManager.d.ts → SubscriptionManager.d.ts} +43 -57
  274. package/dist/sync/{AreaOfInterestManager.js → SubscriptionManager.js} +43 -51
  275. package/dist/sync/SyncWebSocket.d.ts +141 -166
  276. package/dist/sync/SyncWebSocket.js +191 -223
  277. package/dist/sync/awaitClaimGrant.d.ts +18 -18
  278. package/dist/sync/awaitClaimGrant.js +11 -11
  279. package/dist/sync/bootstrapApply.d.ts +34 -24
  280. package/dist/sync/bootstrapApply.js +27 -19
  281. package/dist/sync/commitFrames.d.ts +21 -20
  282. package/dist/sync/commitFrames.js +18 -18
  283. package/dist/sync/createClaimStream.d.ts +23 -22
  284. package/dist/sync/createClaimStream.js +105 -23
  285. package/dist/sync/createPresenceStream.d.ts +19 -18
  286. package/dist/sync/createPresenceStream.js +25 -26
  287. package/dist/sync/createSnapshot.d.ts +12 -14
  288. package/dist/sync/createSnapshot.js +20 -26
  289. package/dist/sync/credentialLifecycle.d.ts +104 -104
  290. package/dist/sync/credentialLifecycle.js +140 -147
  291. package/dist/sync/deltaPipeline.d.ts +36 -34
  292. package/dist/sync/deltaPipeline.js +64 -65
  293. package/dist/sync/groupChange.d.ts +63 -61
  294. package/dist/sync/groupChange.js +74 -78
  295. package/dist/sync/heartbeat.d.ts +34 -33
  296. package/dist/sync/heartbeat.js +31 -31
  297. package/dist/sync/participants.d.ts +19 -19
  298. package/dist/sync/persistedPrefix.d.ts +12 -0
  299. package/dist/sync/persistedPrefix.js +22 -0
  300. package/dist/sync/schemas.d.ts +3 -2
  301. package/dist/sync/schemas.js +14 -10
  302. package/dist/sync/syncCursor.d.ts +17 -21
  303. package/dist/sync/syncCursor.js +17 -21
  304. package/dist/sync/syncPlan.d.ts +28 -36
  305. package/dist/sync/syncPlan.js +18 -19
  306. package/dist/sync/syncPosition.d.ts +54 -49
  307. package/dist/sync/syncPosition.js +57 -52
  308. package/dist/sync/wsFrameHandlers.d.ts +35 -36
  309. package/dist/sync/wsFrameHandlers.js +63 -67
  310. package/dist/testing/fixtures/bootstrap.d.ts +12 -6
  311. package/dist/testing/fixtures/bootstrap.js +12 -6
  312. package/dist/testing/fixtures/deltas.d.ts +30 -33
  313. package/dist/testing/fixtures/deltas.js +30 -33
  314. package/dist/testing/fixtures/models.d.ts +11 -10
  315. package/dist/testing/fixtures/models.js +11 -10
  316. package/dist/testing/helpers/{react-wrapper.d.ts → reactWrapper.d.ts} +13 -10
  317. package/dist/testing/helpers/{react-wrapper.js → reactWrapper.js} +15 -12
  318. package/dist/testing/helpers/{sync-engine-harness.d.ts → syncEngineHarness.d.ts} +17 -15
  319. package/dist/testing/helpers/{sync-engine-harness.js → syncEngineHarness.js} +12 -10
  320. package/dist/testing/helpers/wait.d.ts +13 -8
  321. package/dist/testing/helpers/wait.js +13 -8
  322. package/dist/testing/index.d.ts +5 -3
  323. package/dist/testing/index.js +3 -2
  324. package/dist/testing/mocks/FakeDatabase.d.ts +18 -0
  325. package/dist/testing/mocks/FakeDatabase.js +10 -0
  326. package/dist/testing/mocks/MockMutationExecutor.d.ts +18 -17
  327. package/dist/testing/mocks/MockMutationExecutor.js +15 -14
  328. package/dist/testing/mocks/MockNetworkMonitor.d.ts +8 -8
  329. package/dist/testing/mocks/MockNetworkMonitor.js +8 -8
  330. package/dist/testing/mocks/MockSyncContext.d.ts +20 -17
  331. package/dist/testing/mocks/MockSyncContext.js +15 -13
  332. package/dist/testing/mocks/MockSyncStore.d.ts +10 -10
  333. package/dist/testing/mocks/MockSyncStore.js +11 -11
  334. package/dist/testing/mocks/MockWebSocket.d.ts +28 -23
  335. package/dist/testing/mocks/MockWebSocket.js +22 -21
  336. package/dist/transactions/TransactionQueue.d.ts +244 -181
  337. package/dist/transactions/TransactionQueue.js +929 -423
  338. package/dist/transactions/TransactionStore.d.ts +6 -4
  339. package/dist/transactions/TransactionStore.js +6 -4
  340. package/dist/transactions/UnconfirmedWrites.d.ts +82 -0
  341. package/dist/transactions/UnconfirmedWrites.js +104 -0
  342. package/dist/transactions/coalesceRules.d.ts +41 -17
  343. package/dist/transactions/coalesceRules.js +40 -17
  344. package/dist/transactions/commitEnvelope.d.ts +132 -0
  345. package/dist/transactions/commitEnvelope.js +139 -0
  346. package/dist/transactions/commitOutboxStore.d.ts +32 -0
  347. package/dist/transactions/commitOutboxStore.js +26 -0
  348. package/dist/transactions/commitPayload.d.ts +63 -52
  349. package/dist/transactions/commitPayload.js +54 -57
  350. package/dist/transactions/deltaConfirmation.d.ts +20 -22
  351. package/dist/transactions/deltaConfirmation.js +37 -45
  352. package/dist/transactions/httpCommitEnvelope.d.ts +43 -0
  353. package/dist/transactions/httpCommitEnvelope.js +179 -0
  354. package/dist/transactions/optimisticApply.d.ts +49 -0
  355. package/dist/transactions/optimisticApply.js +65 -0
  356. package/dist/transactions/replayValidation.d.ts +182 -0
  357. package/dist/transactions/replayValidation.js +156 -0
  358. package/dist/types/global.d.ts +46 -41
  359. package/dist/types/global.js +20 -19
  360. package/dist/types/index.d.ts +71 -77
  361. package/dist/types/index.js +22 -22
  362. package/dist/types/modelData.d.ts +6 -8
  363. package/dist/types/modelData.js +5 -7
  364. package/dist/types/participant.d.ts +10 -11
  365. package/dist/types/participant.js +6 -8
  366. package/dist/types/streams.d.ts +208 -195
  367. package/dist/types/streams.js +7 -7
  368. package/dist/utils/asyncIterator.d.ts +25 -32
  369. package/dist/utils/asyncIterator.js +25 -32
  370. package/dist/utils/duration.d.ts +12 -15
  371. package/dist/utils/duration.js +12 -15
  372. package/dist/utils/mobxSetup.d.ts +53 -0
  373. package/dist/utils/{mobx-setup.js → mobxSetup.js} +42 -98
  374. package/dist/webhooks/events.d.ts +21 -16
  375. package/dist/webhooks/events.js +10 -8
  376. package/dist/webhooks/index.d.ts +5 -7
  377. package/dist/webhooks/index.js +5 -7
  378. package/dist/wire/bootstrapReason.d.ts +9 -0
  379. package/dist/wire/bootstrapReason.js +8 -0
  380. package/dist/{schema/sync-delta-wire.d.ts → wire/delta.d.ts} +58 -41
  381. package/dist/wire/delta.js +114 -0
  382. package/dist/wire/errorEnvelope.d.ts +30 -31
  383. package/dist/wire/errorEnvelope.js +34 -40
  384. package/dist/wire/frames.d.ts +315 -86
  385. package/dist/wire/frames.js +47 -33
  386. package/dist/wire/index.d.ts +18 -14
  387. package/dist/wire/index.js +32 -27
  388. package/dist/wire/listEnvelope.d.ts +16 -23
  389. package/dist/wire/listEnvelope.js +7 -6
  390. package/dist/wire/protocol.d.ts +25 -32
  391. package/dist/wire/protocol.js +25 -32
  392. package/dist/wire/protocolVersion.d.ts +44 -40
  393. package/dist/wire/protocolVersion.js +44 -40
  394. package/docs/api.md +10 -10
  395. package/docs/coordination.md +59 -0
  396. package/docs/mcp.md +1 -1
  397. package/package.json +17 -11
  398. package/dist/ai-sdk/coordinated-tool.d.ts +0 -101
  399. package/dist/ai-sdk/coordination-context.d.ts +0 -52
  400. package/dist/core/query-utils.d.ts +0 -34
  401. package/dist/core/query-utils.js +0 -59
  402. package/dist/schema/sync-delta-row.js +0 -103
  403. package/dist/schema/sync-delta-wire.js +0 -102
  404. package/dist/server/read-config.d.ts +0 -67
  405. package/dist/server/read-config.js +0 -8
  406. package/dist/server/storage-mode.d.ts +0 -8
  407. package/dist/server/storage-mode.js +0 -28
  408. package/dist/source/connector-protocol.d.ts +0 -159
  409. package/dist/source/connector-protocol.js +0 -161
  410. package/dist/transactions/OptimisticEchoTracker.d.ts +0 -82
  411. package/dist/transactions/OptimisticEchoTracker.js +0 -104
  412. package/dist/transactions/mutation-error-handler.d.ts +0 -5
  413. package/dist/transactions/mutation-error-handler.js +0 -39
  414. package/dist/transactions/optimistic.d.ts +0 -24
  415. package/dist/transactions/optimistic.js +0 -45
  416. package/dist/transactions/persistedReplay.d.ts +0 -93
  417. package/dist/transactions/persistedReplay.js +0 -105
  418. package/dist/utils/mobx-setup.d.ts +0 -42
@@ -1,22 +1,28 @@
1
1
  /**
2
- * Shared Data Source wire + handler types.
2
+ * The types that describe a data source — the shapes exchanged over the wire
3
+ * and the handler interfaces you implement.
3
4
  *
4
- * These are the cross-package shapes every source module speaks (operations,
5
- * events, list queries, handler contexts, the four wire request types). They
6
- * live in this leaf not the `index.ts` barrel — so `contract.ts`,
7
- * `adapter.ts`, `pushQueue.ts` and the ORM adapters can import them directly
8
- * without routing a circular dependency through the barrel.
9
- *
10
- * `sourceEventForOperation` lives here too: it is the pure constructor for the
11
- * `SourceEvent` marker shape and has no dependency on the endpoint factory.
5
+ * A data source lets Ablo read from and write to your own database. These
6
+ * types cover the four request kinds Ablo can send ({@link SourceRequest}),
7
+ * the operations and change events they carry ({@link SourceOperation} and
8
+ * {@link SourceEvent}), the list-query and pagination shapes, and the handler
9
+ * and context types your source implements. {@link sourceEventForOperation}
10
+ * builds a change-event marker from an operation.
12
11
  */
13
12
  import type { Environment } from '../environment.js';
13
+ /** A scalar value that can appear in a source filter. */
14
14
  export type SourcePrimitive = string | number | boolean | null;
15
+ /**
16
+ * A single filter condition on a `list` query: a field paired with a value,
17
+ * or a field, comparison operator, and value. The two-element form is
18
+ * shorthand for equality.
19
+ */
15
20
  export type SourceWhere = readonly [field: string, value: SourcePrimitive] | readonly [
16
21
  field: string,
17
22
  op: '=' | '!=' | '<' | '<=' | '>' | '>=' | 'IN' | 'NOT IN' | 'IS' | 'IS NOT' | 'LIKE' | 'NOT LIKE' | 'ILIKE' | 'NOT ILIKE',
18
23
  value: SourcePrimitive | readonly SourcePrimitive[]
19
24
  ];
25
+ /** The query Ablo passes to your `list` handler: filters, ordering, a limit, and a pagination cursor. */
20
26
  export interface SourceListQuery {
21
27
  readonly where?: readonly SourceWhere[];
22
28
  readonly limit?: number;
@@ -24,33 +30,31 @@ export interface SourceListQuery {
24
30
  readonly order?: 'asc' | 'desc';
25
31
  readonly related?: readonly string[];
26
32
  /**
27
- * Opaque cursor returned by a previous `list` call. The customer's
28
- * `list` handler defines what this encodes (page index, last id,
29
- * keyset). Ablo treats it as a black box round-trips it back to
30
- * fetch the next page until the handler returns no `nextCursor`.
33
+ * An opaque cursor returned by a previous `list` call. Your `list` handler
34
+ * decides what it encodes — a page index, a last id, a keyset. Ablo treats
35
+ * it as a black box and hands it back to fetch the next page until your
36
+ * handler stops returning a `nextCursor`.
31
37
  */
32
38
  readonly cursor?: string;
33
39
  }
34
40
  /**
35
- * Optional structured shape for a `list` handler that supports
36
- * pagination. Handlers may keep returning a plain `Row[]` (no
37
- * pagination, single-shot) or upgrade to this shape to expose a
38
- * cursor that Ablo will round-trip on the next request.
41
+ * The paginated return shape for a `list` handler. A handler may return a
42
+ * plain `Row[]` for a single, unpaginated page, or return this shape to expose
43
+ * a `nextCursor` that Ablo hands back on the following request.
39
44
  */
40
45
  export interface SourceListPage<Row> {
41
46
  readonly rows: readonly Row[];
42
47
  readonly nextCursor?: string;
43
48
  }
49
+ /** What a `list` handler returns: either a plain array of rows or a {@link SourceListPage}. */
44
50
  export type SourceListResult<Row> = readonly Row[] | SourceListPage<Row>;
45
51
  /**
46
- * Read-side scope context that Ablo attaches to source requests so
47
- * the customer's `authorize` / model handlers can refuse calls that
48
- * fall outside the participant's permitted syncGroups.
52
+ * The scope of a source request: who is asking and what they are allowed to
53
+ * see. Ablo attaches this so your `authorize` and model handlers can reject
54
+ * calls that fall outside the participant's permitted sync groups.
49
55
  *
50
- * This is informational the customer is the only side that can
51
- * actually enforce, since the canonical data lives in their store.
52
- * Mirrors how Auth0 Custom DB scripts receive the requested scope and
53
- * trust the script to honor it.
56
+ * It is advisory. Because the canonical data lives in your database, your
57
+ * handlers are the only place that can actually enforce these limits.
54
58
  */
55
59
  export interface SourceRequestContext {
56
60
  readonly participantId?: string;
@@ -58,22 +62,22 @@ export interface SourceRequestContext {
58
62
  readonly organizationId?: string;
59
63
  readonly requiredSyncGroups?: readonly string[];
60
64
  /**
61
- * Production/sandbox mode for this request. Customers branch their source
62
- * handlers on this (`if (mode === 'sandbox') db = sandboxDb`) so sandbox
63
- * traffic exercises the same code path against an isolated store.
65
+ * Whether this request runs in production or sandbox mode. Branch your
66
+ * handlers on it for example, read and write a separate sandbox database
67
+ * when `mode === 'sandbox'` — so sandbox traffic exercises the same code
68
+ * against isolated data. Keeping the two apart is your handler's
69
+ * responsibility, since your database holds the canonical rows.
64
70
  *
65
- * Mirrors Stripe's `sk_test_` / `sk_live_` prefixes: same wire
66
- * shape, same handler code, different namespace. Ablo's server-side
67
- * fan-out does not yet partition deltas by mode — that lands when
68
- * `sync_deltas.mode` ships. Until then, isolation is enforced
69
- * customer-side via this field, which is the right boundary anyway
70
- * (the customer's database is where the canonical data lives).
71
- *
72
- * Defaults to `'production'` when omitted so callers that don't opt in
73
- * keep the existing behavior.
71
+ * Defaults to `'production'` when omitted.
74
72
  */
75
73
  readonly mode?: Environment;
76
74
  }
75
+ /**
76
+ * A single change Ablo asks your source to apply — a create, update, delete,
77
+ * archive, or unarchive of one row of `model`. Operations arrive in your
78
+ * `commit` handler through {@link SourceCommitParams}. `onStale` says what to
79
+ * do when the row changed since it was read at `readAt`.
80
+ */
77
81
  export interface SourceOperation {
78
82
  readonly type: 'CREATE' | 'UPDATE' | 'DELETE' | 'ARCHIVE' | 'UNARCHIVE';
79
83
  readonly model: string;
@@ -83,6 +87,11 @@ export interface SourceOperation {
83
87
  readonly readAt?: number | null;
84
88
  readonly onStale?: 'reject' | 'overwrite' | 'notify' | null;
85
89
  }
90
+ /**
91
+ * A computed change to one row, ready to append to the change log. Your
92
+ * `commit` handler may return these directly, or return rows and let Ablo
93
+ * derive the deltas from them.
94
+ */
86
95
  export interface SourceDelta {
87
96
  readonly model: string;
88
97
  readonly id: string;
@@ -91,21 +100,20 @@ export interface SourceDelta {
91
100
  readonly transactionId?: string | null;
92
101
  }
93
102
  /**
94
- * A change that happened in the customer's store. The source's
95
- * `events` handler returns these so Ablo can append them to
96
- * `sync_deltas` and fan them out to connected clients exactly like
97
- * SDK-originated commits.
103
+ * A change that already happened in your database. Your `events` handler
104
+ * returns these, and Ablo appends them to the `sync_deltas` change log and
105
+ * fans them out to connected clients, exactly as it would a change made
106
+ * through the SDK.
98
107
  *
99
- * The events handler can return everything from the outbox unfiltered. Ablo
100
- * dedupes stable `event.id` values and uses `clientTxId` to filter SDK-origin
101
- * echoes after the direct append has already succeeded. If the direct append
102
- * failed, the same outbox event repairs it on poll/push because no matching
103
- * `mutation_log` row exists yet.
108
+ * Your handler can return the whole outbox unfiltered. Ablo deduplicates on
109
+ * the stable `id` and uses `clientTxId` to drop echoes of changes the SDK
110
+ * already committed. If that earlier commit never landed, the same outbox
111
+ * event repairs the gap on the next poll or push.
104
112
  */
105
113
  export interface SourceEvent {
106
114
  /**
107
- * Globally unique event id from the customer's outbox. Used by Ablo
108
- * for replay protection re-delivering the same id is a no-op.
115
+ * A globally unique event id from your outbox. Ablo uses it for replay
116
+ * protection, so re-delivering the same id is a no-op.
109
117
  */
110
118
  readonly id: string;
111
119
  readonly model: string;
@@ -113,111 +121,118 @@ export interface SourceEvent {
113
121
  readonly type: SourceOperation['type'];
114
122
  readonly data?: Record<string, unknown> | null;
115
123
  /**
116
- * Tenant the event belongs to. Multi-tenant customers populate this
117
- * from the row's organization column. Single-tenant deployments may
118
- * omit it and let the poller fall back to its configured default.
119
- * Drives the sync-group fan-out: clients in `org:${organizationId}`
120
- * receive the resulting delta.
124
+ * The tenant this event belongs to. Populate it from the row's organization
125
+ * column for multi-tenant data; a single-tenant source may omit it and let
126
+ * the poller fall back to its configured default. It drives fan-out: clients
127
+ * in `org:${organizationId}` receive the resulting change.
121
128
  */
122
129
  readonly organizationId?: string;
123
130
  /**
124
- * Originating Ablo SDK commit id, when known. If the customer's
125
- * outbox stores the `clientTxId` Ablo passed into the matching
126
- * `commit` handler, round-trip it here and Ablo will skip events
127
- * whose commit already produced a delta. External-origin events
128
- * (cron jobs, batch imports, manual edits) leave this unset.
131
+ * The originating SDK commit id, when you know it. If your outbox records the
132
+ * `clientTxId` that Ablo passed into the matching `commit` handler, echo it
133
+ * back here and Ablo will skip events whose commit already produced a change.
134
+ * Leave it unset for changes made outside the SDK, such as cron jobs, batch
135
+ * imports, or manual edits.
129
136
  */
130
137
  readonly clientTxId?: string;
131
138
  /**
132
- * Wall-clock time the event occurred in the source. Optional; used
133
- * only for ordering hints. Ablo trusts the customer's response order
134
- * over this field.
139
+ * When the change occurred in your database. Optional and used only as an
140
+ * ordering hint; Ablo trusts the order of your handler's response over this
141
+ * field.
135
142
  */
136
143
  readonly occurredAt?: number;
137
144
  }
145
+ /** Inputs to {@link sourceEventForOperation}. */
138
146
  export interface SourceEventForOperationOptions {
139
147
  /**
140
- * Stable id from the customer's outbox table. This is Ablo's replay-
141
- * protection key; retries must return the same id.
148
+ * The stable id from your outbox table. It is Ablo's replay-protection key,
149
+ * so retries must return the same id.
142
150
  */
143
151
  readonly eventId: string;
144
152
  readonly operation: SourceOperation;
145
153
  /**
146
- * Committed row id. Defaults to `operation.id`; pass this for generated-id
147
- * CREATEs where the database assigns the id inside the transaction.
154
+ * The committed row id. Defaults to `operation.id`; pass it explicitly for
155
+ * creates where the database assigns the id inside the transaction.
148
156
  */
149
157
  readonly entityId?: string;
150
158
  /**
151
- * Canonical row payload after the write. Pass `null` for DELETE. When omitted
152
- * the event carries no row payload, which is valid but less useful for
153
- * realtime hydration.
159
+ * The row's payload after the write. Pass `null` for a delete. When omitted,
160
+ * the event carries no payload, which is valid but leaves less for clients to
161
+ * hydrate from in realtime.
154
162
  */
155
163
  readonly data?: Record<string, unknown> | null;
156
164
  /**
157
- * Batch idempotency key from the Data Source commit request. Round-tripping it
158
- * lets Ablo filter SDK-origin echoes after the direct append succeeds, while
159
- * still using the outbox event to repair a failed direct append.
165
+ * The commit request's idempotency key. Echoing it lets Ablo drop echoes of
166
+ * a change the SDK already committed, while still letting the outbox event
167
+ * repair that change if it never landed.
160
168
  */
161
169
  readonly clientTxId?: string;
162
170
  readonly organizationId?: string;
163
171
  readonly occurredAt?: number | Date;
164
172
  }
165
173
  /**
166
- * Build the source-event marker customers should write to their outbox table in
167
- * the SAME transaction as their app-row mutation.
174
+ * Build the {@link SourceEvent} marker you should record in your outbox table,
175
+ * within the same transaction as the row change it describes.
168
176
  *
169
- * This helper does not persist anything. It only standardizes the marker shape
170
- * so Prisma/Drizzle/Kysely/raw-SQL adapters all emit the fields Ablo's
171
- * reconciler expects.
177
+ * This helper only shapes the marker; it does not persist anything. Writing the
178
+ * returned event through your ORM or raw SQL keeps every source emitting the
179
+ * fields Ablo expects when it reconciles the change.
172
180
  */
173
181
  export declare function sourceEventForOperation(options: SourceEventForOperationOptions): SourceEvent;
182
+ /** What your `commit` handler returns after applying operations. */
174
183
  export interface SourceCommitResult<Row = Record<string, unknown>> {
175
184
  /**
176
- * Canonical rows after the write. Ablo uses these to update hosted
177
- * realtime projections and append deltas.
185
+ * The rows as they stand after the write. Ablo uses them to update its
186
+ * realtime projections and append the resulting changes.
178
187
  */
179
188
  readonly rows?: readonly Row[];
180
189
  /**
181
- * Optional explicit deltas when the source already computes them.
182
- * Most sources can return rows and let Ablo derive the delta payload.
190
+ * Explicit changes, for sources that already compute them. Most sources can
191
+ * return rows instead and let Ablo derive the change payload.
183
192
  */
184
193
  readonly deltas?: readonly SourceDelta[];
185
194
  }
195
+ /** The arguments passed to a top-level {@link SourceCommitHandler}. */
186
196
  export interface SourceCommitParams<TAuth = unknown> {
187
197
  readonly operations: readonly SourceOperation[];
188
198
  readonly clientTxId?: string;
189
199
  readonly context: SourceHandlerContext<TAuth>;
190
200
  }
191
201
  /**
192
- * Operation-level permission tag used by `resolveScopes`. Mirrors the
193
- * four wire request types: an API key carries the set of operations
194
- * it's allowed to invoke. Stripe's restricted-key model at the
195
- * operation granularity — model-level scoping is a future addition.
202
+ * The operation an API key is permitted to invoke, one per request kind:
203
+ * `load` and `list` read, `commit` writes, and `events` reads the change feed.
204
+ * A key carries the set of scopes it is allowed to use.
196
205
  */
197
206
  export type SourceScope = 'load' | 'list' | 'commit' | 'events';
207
+ /** What your `events` handler returns: a batch of changes and an optional next cursor. */
198
208
  export interface SourceEventsResult {
199
209
  readonly events: readonly SourceEvent[];
200
210
  /**
201
- * Cursor for the next poll. When omitted Ablo treats the feed as
202
- * fully drained for this round and uses the last event's cursor (or
203
- * the initial cursor) for the next call.
211
+ * The cursor for the next poll. When omitted, Ablo treats the feed as fully
212
+ * drained for this round and reuses the last event's cursor, or the initial
213
+ * cursor, on the following call.
204
214
  */
205
215
  readonly nextCursor?: string;
206
216
  }
217
+ /**
218
+ * Your handler for the `events` request. Return the changes since `cursor` so
219
+ * Ablo can append and fan them out. See {@link SourceEvent}.
220
+ */
207
221
  export type SourceEventsHandler<TAuth = unknown> = (params: {
208
222
  /**
209
- * Cursor returned by a previous `events` call. Undefined on the
210
- * first poll for a freshly-onboarded source. The customer decides
211
- * what it encodes (last event id, timestamp, LSN, etc).
223
+ * The cursor from a previous `events` call, or undefined on the first poll of
224
+ * a newly connected source. You decide what it encodes — a last event id, a
225
+ * timestamp, a log sequence number.
212
226
  */
213
227
  readonly cursor?: string;
214
228
  /**
215
- * Caller-suggested upper bound on returned events. Customers may
216
- * return fewer; returning more risks tripping Ablo's per-poll cap.
229
+ * A suggested upper bound on how many events to return. You may return fewer;
230
+ * returning many more risks tripping Ablo's per-poll cap.
217
231
  */
218
232
  readonly limit?: number;
219
233
  readonly context: SourceHandlerContext<TAuth>;
220
234
  }) => Promise<SourceEventsResult> | SourceEventsResult;
235
+ /** The request being authorized, passed to a function-form {@link SourceApiKey} or an `authorize` hook. */
221
236
  export interface SourceAuthorizeContext {
222
237
  readonly request: Request;
223
238
  readonly body: unknown;
@@ -227,22 +242,23 @@ export interface SourceHandlerContext<TAuth = unknown> {
227
242
  readonly auth: TAuth;
228
243
  readonly request: Request;
229
244
  /**
230
- * `webhook-id` from the signed request globally unique per the
231
- * Standard Webhooks spec. Customers should dedupe by this id to
232
- * defend against replay (Ablo doesn't dedupe at the source-handler
233
- * boundary; commit idempotency is `clientTxId`, and event replay
234
- * protection is the outbox event `id`).
245
+ * The `webhook-id` from the signed request, globally unique per the
246
+ * Standard Webhooks specification. Dedupe by this id to defend against
247
+ * replay: Ablo does not deduplicate at the source-handler boundary.
248
+ * Commit idempotency keys on `clientTxId`, and event replay protection
249
+ * keys on the outbox event `id`.
235
250
  */
236
251
  readonly messageId?: string;
237
252
  readonly signedAt?: number;
238
253
  /**
239
- * Scope context Ablo attached to this request. Present when the
240
- * caller (sync-server) opted into scope-aware source mode. Customers
241
- * can use it in `authorize` (to reject out-of-scope calls) and in
242
- * `list` / `load` (to filter rows the participant is allowed to see).
254
+ * The scope context Ablo attached to this request, naming the participant
255
+ * and the sync groups they are allowed to see. Present when the host
256
+ * opted into scope-aware requests. Use it in `authorize` to reject
257
+ * out-of-scope calls, and in `list` and `load` to filter rows down to
258
+ * what the participant may see.
243
259
  *
244
- * Absent for calls made without scope context, such as tests or
245
- * single-tenant deployments that do not need scoped fan-out yet.
260
+ * Absent for requests made without scope context, such as tests or
261
+ * single-tenant deployments that do not need scoped fan-out.
246
262
  */
247
263
  readonly scope?: SourceRequestContext;
248
264
  }
@@ -256,8 +272,9 @@ export interface SourceModelHandlers<Row, CreateInput, TAuth = unknown> {
256
272
  readonly context: SourceHandlerContext<TAuth>;
257
273
  }): Promise<SourceListResult<Row>> | SourceListResult<Row>;
258
274
  /**
259
- * Apply one or more operations for this model in the customer's own
260
- * transaction. The source must be idempotent by operation/clientTxId.
275
+ * Apply one or more operations for this model within your own database
276
+ * transaction. Your handler must be idempotent on the operation and its
277
+ * `clientTxId`, so that a retried commit does not apply the change twice.
261
278
  */
262
279
  commit?(params: {
263
280
  readonly operations: readonly SourceOperation[];
@@ -1,23 +1,22 @@
1
1
  /**
2
- * Shared Data Source wire + handler types.
2
+ * The types that describe a data source — the shapes exchanged over the wire
3
+ * and the handler interfaces you implement.
3
4
  *
4
- * These are the cross-package shapes every source module speaks (operations,
5
- * events, list queries, handler contexts, the four wire request types). They
6
- * live in this leaf not the `index.ts` barrel — so `contract.ts`,
7
- * `adapter.ts`, `pushQueue.ts` and the ORM adapters can import them directly
8
- * without routing a circular dependency through the barrel.
9
- *
10
- * `sourceEventForOperation` lives here too: it is the pure constructor for the
11
- * `SourceEvent` marker shape and has no dependency on the endpoint factory.
5
+ * A data source lets Ablo read from and write to your own database. These
6
+ * types cover the four request kinds Ablo can send ({@link SourceRequest}),
7
+ * the operations and change events they carry ({@link SourceOperation} and
8
+ * {@link SourceEvent}), the list-query and pagination shapes, and the handler
9
+ * and context types your source implements. {@link sourceEventForOperation}
10
+ * builds a change-event marker from an operation.
12
11
  */
13
12
  import { AbloValidationError } from '../errors.js';
14
13
  /**
15
- * Build the source-event marker customers should write to their outbox table in
16
- * the SAME transaction as their app-row mutation.
14
+ * Build the {@link SourceEvent} marker you should record in your outbox table,
15
+ * within the same transaction as the row change it describes.
17
16
  *
18
- * This helper does not persist anything. It only standardizes the marker shape
19
- * so Prisma/Drizzle/Kysely/raw-SQL adapters all emit the fields Ablo's
20
- * reconciler expects.
17
+ * This helper only shapes the marker; it does not persist anything. Writing the
18
+ * returned event through your ORM or raw SQL keeps every source emitting the
19
+ * fields Ablo expects when it reconciles the change.
21
20
  */
22
21
  export function sourceEventForOperation(options) {
23
22
  const entityId = options.entityId ?? options.operation.id;
@@ -1,29 +1,40 @@
1
1
  /**
2
- * Linear Sync Engine - Object Store Base Class
3
- *
4
- * Abstract base class for all store implementations.
5
- * Provides the interface for storing and retrieving models from IndexedDB.
6
- * Uses native IndexedDB for maximum performance (no wrapper overhead).
2
+ * The IndexedDB-backed object store: durable, per-model record storage for
3
+ * the browser. See {@link ObjectStore}.
7
4
  */
8
5
  import type { ModelMetadata } from '../types/index.js';
9
6
  import type { ObjectStoreContract } from './ObjectStoreContract.js';
10
7
  /**
11
- * ObjectStore - IDB-backed model storage.
8
+ * IDB transaction options type (TypeScript's lib.dom.d.ts may be outdated)
9
+ * durability: 'relaxed' provides ~16x write performance improvement
10
+ * by not requiring fsync on each transaction commit.
11
+ * Safe for optimistic sync engines that can recover from server state.
12
+ */
13
+ interface IDBTransactionOptionsWithDurability {
14
+ durability?: 'default' | 'relaxed' | 'strict';
15
+ }
16
+ /**
17
+ * An IndexedDB-backed store holding the records of a single model.
12
18
  *
13
- * Implements {@link ObjectStoreContract}, the shared surface that
14
- * `InMemoryObjectStore` also satisfies. Centralizing the contract
15
- * means callers can hold either implementation behind one type and
16
- * a future drift between the two trips a typecheck error here.
19
+ * It implements {@link ObjectStoreContract}, the shared surface that
20
+ * {@link InMemoryObjectStore} also satisfies, so callers can hold either
21
+ * implementation behind one type. Because both are checked against the same
22
+ * interface, any drift between them surfaces as a typecheck error rather
23
+ * than a runtime surprise.
17
24
  *
18
- * Uses native IndexedDB API for Linear-level performance.
25
+ * The store talks to the native IndexedDB API directly and uses relaxed
26
+ * transaction durability on writes.
19
27
  */
20
28
  export declare class ObjectStore implements ObjectStoreContract {
21
29
  protected db: IDBDatabase;
22
30
  protected modelName: string;
23
31
  protected storeName: string;
24
32
  protected metadata: ModelMetadata;
33
+ private readonly writeDurability;
25
34
  private isClosing;
26
- constructor(db: IDBDatabase, modelName: string, storeName: string, metadata: ModelMetadata);
35
+ constructor(db: IDBDatabase, modelName: string, storeName: string, metadata: ModelMetadata, writeDurability?: NonNullable<IDBTransactionOptionsWithDurability['durability']>);
36
+ /** Insert without replacing an existing key (used by the commit outbox). */
37
+ add(data: Record<string, unknown>): Promise<void>;
27
38
  /**
28
39
  * Mark this store as closing to prevent new operations
29
40
  */
@@ -101,3 +112,4 @@ export declare class ObjectStore implements ObjectStoreContract {
101
112
  */
102
113
  performMaintenance(): Promise<void>;
103
114
  }
115
+ export {};
@@ -1,31 +1,53 @@
1
1
  /**
2
- * Linear Sync Engine - Object Store Base Class
3
- *
4
- * Abstract base class for all store implementations.
5
- * Provides the interface for storing and retrieving models from IndexedDB.
6
- * Uses native IndexedDB for maximum performance (no wrapper overhead).
2
+ * The IndexedDB-backed object store: durable, per-model record storage for
3
+ * the browser. See {@link ObjectStore}.
7
4
  */
8
5
  /**
9
- * ObjectStore - IDB-backed model storage.
6
+ * An IndexedDB-backed store holding the records of a single model.
10
7
  *
11
- * Implements {@link ObjectStoreContract}, the shared surface that
12
- * `InMemoryObjectStore` also satisfies. Centralizing the contract
13
- * means callers can hold either implementation behind one type and
14
- * a future drift between the two trips a typecheck error here.
8
+ * It implements {@link ObjectStoreContract}, the shared surface that
9
+ * {@link InMemoryObjectStore} also satisfies, so callers can hold either
10
+ * implementation behind one type. Because both are checked against the same
11
+ * interface, any drift between them surfaces as a typecheck error rather
12
+ * than a runtime surprise.
15
13
  *
16
- * Uses native IndexedDB API for Linear-level performance.
14
+ * The store talks to the native IndexedDB API directly and uses relaxed
15
+ * transaction durability on writes.
17
16
  */
18
17
  export class ObjectStore {
19
18
  db;
20
19
  modelName;
21
20
  storeName;
22
21
  metadata;
22
+ writeDurability;
23
23
  isClosing = false;
24
- constructor(db, modelName, storeName, metadata) {
24
+ constructor(db, modelName, storeName, metadata, writeDurability = 'relaxed') {
25
25
  this.db = db;
26
26
  this.modelName = modelName;
27
27
  this.storeName = storeName;
28
28
  this.metadata = metadata;
29
+ this.writeDurability = writeDurability;
30
+ }
31
+ /** Insert without replacing an existing key (used by the commit outbox). */
32
+ async add(data) {
33
+ if (!this.checkDatabaseAvailable()) {
34
+ return Promise.reject(new Error('IndexedDB not available (closing or invalid)'));
35
+ }
36
+ return new Promise((resolve, reject) => {
37
+ try {
38
+ const tx = this.db.transaction([this.storeName], 'readwrite', {
39
+ durability: this.writeDurability,
40
+ });
41
+ const store = tx.objectStore(this.storeName);
42
+ const request = store.add(data);
43
+ tx.oncomplete = () => { resolve(); };
44
+ tx.onerror = () => { reject(tx.error || new Error('IndexedDB transaction error')); };
45
+ request.onerror = () => { reject(request.error || new Error('IndexedDB request error')); };
46
+ }
47
+ catch (error) {
48
+ reject(error instanceof Error ? error : new Error(String(error)));
49
+ }
50
+ });
29
51
  }
30
52
  /**
31
53
  * Mark this store as closing to prevent new operations
@@ -45,7 +67,7 @@ export class ObjectStore {
45
67
  // but we can check if the database object is still valid
46
68
  try {
47
69
  // Accessing objectStoreNames will throw if the database is closed
48
- const _ = this.db.objectStoreNames;
70
+ void this.db.objectStoreNames;
49
71
  return true;
50
72
  }
51
73
  catch (error) {
@@ -66,7 +88,7 @@ export class ObjectStore {
66
88
  try {
67
89
  // Use relaxed durability for ~16x write performance (safe with optimistic sync)
68
90
  const tx = this.db.transaction([this.storeName], 'readwrite', {
69
- durability: 'relaxed',
91
+ durability: this.writeDurability,
70
92
  });
71
93
  const store = tx.objectStore(this.storeName);
72
94
  const request = store.put(data);
@@ -170,7 +192,7 @@ export class ObjectStore {
170
192
  try {
171
193
  // Use relaxed durability for ~16x write performance (safe with optimistic sync)
172
194
  const tx = this.db.transaction([this.storeName], 'readwrite', {
173
- durability: 'relaxed',
195
+ durability: this.writeDurability,
174
196
  });
175
197
  const store = tx.objectStore(this.storeName);
176
198
  const request = store.delete(id);
@@ -206,7 +228,7 @@ export class ObjectStore {
206
228
  try {
207
229
  // Use relaxed durability for ~16x write performance (safe with optimistic sync)
208
230
  const tx = this.db.transaction([this.storeName], 'readwrite', {
209
- durability: 'relaxed',
231
+ durability: this.writeDurability,
210
232
  });
211
233
  const store = tx.objectStore(this.storeName);
212
234
  const request = store.clear();
@@ -1,23 +1,22 @@
1
1
  /**
2
- * Shared contract for record-shaped object stores.
2
+ * The shared interface for record-shaped object stores. Two implementations
3
+ * satisfy it:
3
4
  *
4
- * The SDK has two implementations:
5
- * - {@link ObjectStore} — IndexedDB-backed (browser persistence)
6
- * - {@link InMemoryObjectStore} — Map-backed (tests, SSR fallback)
5
+ * - {@link ObjectStore} backed by IndexedDB, for durable persistence in
6
+ * the browser.
7
+ * - {@link InMemoryObjectStore} — backed by a Map, for tests and
8
+ * environments without IndexedDB.
7
9
  *
8
- * Both expose the same async surface: `put` / `get` / `getAll` /
9
- * `delete` / `getAllFromIndex` / `clear` / `markAsClosing`.
10
- * Callers depend on this interface so they don't have to
11
- * branch on which concrete class they got from `Database.getStore`
12
- * the bootstrap, hydration, transaction-persistence, and reconciler
13
- * paths all consume the contract.
14
- *
15
- * Centralizing the types here means a future drift between the two
16
- * stores trips a typecheck error at the implementor, not silently in
17
- * a caller. This replaced ad-hoc `as unknown as ReturnType<...>`
18
- * casts in `Database.ts` that bridged the two classes.
10
+ * Both expose the same asynchronous surface `put`, `get`, `getAll`,
11
+ * `delete`, `getAllFromIndex`, `clear`, and `markAsClosing` so callers
12
+ * work against this interface and never branch on which concrete store they
13
+ * hold. Because both implementations are checked against one interface, any
14
+ * drift between them surfaces as a typecheck error at the store rather than
15
+ * a silent failure in a caller.
19
16
  */
20
17
  export interface ObjectStoreContract {
18
+ /** Insert a record only when its key is absent. */
19
+ add(data: Record<string, unknown>): Promise<void>;
21
20
  /** Insert or update a record. The record must carry an `id` field. */
22
21
  put(data: Record<string, unknown>): Promise<void>;
23
22
  /** Look up a record by id. */