@abloatai/ablo 0.26.0 → 0.27.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (398) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/README.md +101 -85
  3. package/dist/BaseSyncedStore.d.ts +85 -88
  4. package/dist/BaseSyncedStore.js +131 -147
  5. package/dist/Database.d.ts +54 -68
  6. package/dist/Database.js +97 -113
  7. package/dist/{ObjectPool.d.ts → InstanceCache.d.ts} +10 -13
  8. package/dist/{ObjectPool.js → InstanceCache.js} +85 -83
  9. package/dist/LazyReferenceCollection.d.ts +11 -15
  10. package/dist/LazyReferenceCollection.js +12 -16
  11. package/dist/Model.d.ts +37 -52
  12. package/dist/Model.js +46 -61
  13. package/dist/ModelRegistry.d.ts +21 -19
  14. package/dist/ModelRegistry.js +23 -27
  15. package/dist/NetworkMonitor.d.ts +5 -6
  16. package/dist/NetworkMonitor.js +5 -6
  17. package/dist/SyncClient.d.ts +112 -112
  18. package/dist/SyncClient.js +165 -172
  19. package/dist/adapters/alwaysOnline.d.ts +6 -8
  20. package/dist/adapters/alwaysOnline.js +6 -8
  21. package/dist/adapters/inMemoryStorage.d.ts +9 -9
  22. package/dist/adapters/inMemoryStorage.js +9 -9
  23. package/dist/agent/Agent.d.ts +27 -32
  24. package/dist/agent/Agent.js +18 -19
  25. package/dist/agent/index.d.ts +4 -4
  26. package/dist/agent/index.js +5 -5
  27. package/dist/agent/session.d.ts +47 -44
  28. package/dist/agent/session.js +37 -48
  29. package/dist/agent/types.d.ts +26 -31
  30. package/dist/agent/types.js +6 -7
  31. package/dist/ai-sdk/coordinatedTool.d.ts +108 -0
  32. package/dist/ai-sdk/{coordinated-tool.js → coordinatedTool.js} +44 -38
  33. package/dist/ai-sdk/coordinationContext.d.ts +46 -0
  34. package/dist/ai-sdk/{coordination-context.js → coordinationContext.js} +26 -33
  35. package/dist/ai-sdk/index.d.ts +25 -22
  36. package/dist/ai-sdk/index.js +25 -22
  37. package/dist/ai-sdk/wrap.d.ts +6 -7
  38. package/dist/ai-sdk/wrap.js +1 -1
  39. package/dist/auth/credentialPolicy.d.ts +69 -74
  40. package/dist/auth/credentialPolicy.js +51 -56
  41. package/dist/auth/credentialSource.d.ts +6 -5
  42. package/dist/auth/credentialSource.js +9 -10
  43. package/dist/auth/index.d.ts +59 -58
  44. package/dist/auth/index.js +31 -37
  45. package/dist/auth/schemas.d.ts +5 -4
  46. package/dist/auth/schemas.js +5 -4
  47. package/dist/batching/index.d.ts +19 -21
  48. package/dist/batching/index.js +14 -17
  49. package/dist/cli.cjs +167 -119
  50. package/dist/client/Ablo.d.ts +73 -73
  51. package/dist/client/Ablo.js +125 -160
  52. package/dist/client/ApiClient.d.ts +30 -19
  53. package/dist/client/ApiClient.js +133 -38
  54. package/dist/client/auth.d.ts +47 -47
  55. package/dist/client/auth.js +108 -117
  56. package/dist/client/claimHeartbeatLoop.d.ts +50 -0
  57. package/dist/client/claimHeartbeatLoop.js +88 -0
  58. package/dist/client/consoleLogger.d.ts +5 -6
  59. package/dist/client/consoleLogger.js +5 -6
  60. package/dist/client/createInternalComponents.d.ts +14 -17
  61. package/dist/client/createInternalComponents.js +25 -30
  62. package/dist/client/createModelProxy.d.ts +130 -120
  63. package/dist/client/createModelProxy.js +152 -122
  64. package/dist/client/credentialEndpoint.d.ts +40 -42
  65. package/dist/client/credentialEndpoint.js +35 -36
  66. package/dist/client/functionalUpdate.d.ts +29 -27
  67. package/dist/client/functionalUpdate.js +21 -21
  68. package/dist/client/hostedEndpoints.d.ts +9 -12
  69. package/dist/client/hostedEndpoints.js +9 -12
  70. package/dist/client/httpClient.d.ts +57 -53
  71. package/dist/client/httpClient.js +29 -31
  72. package/dist/client/identity.d.ts +15 -20
  73. package/dist/client/identity.js +47 -58
  74. package/dist/client/modelRegistration.d.ts +5 -9
  75. package/dist/client/modelRegistration.js +67 -87
  76. package/dist/client/options.d.ts +134 -157
  77. package/dist/client/options.js +3 -7
  78. package/dist/client/registerDataSource.d.ts +9 -9
  79. package/dist/client/registerDataSource.js +15 -16
  80. package/dist/client/resourceTypes.d.ts +64 -75
  81. package/dist/client/resourceTypes.js +4 -10
  82. package/dist/client/schemaConfig.d.ts +31 -43
  83. package/dist/client/schemaConfig.js +38 -50
  84. package/dist/client/sessionMint.d.ts +16 -12
  85. package/dist/client/sessionMint.js +26 -31
  86. package/dist/client/validateAbloOptions.d.ts +12 -14
  87. package/dist/client/validateAbloOptions.js +8 -9
  88. package/dist/client/writeOptionsSchema.d.ts +18 -16
  89. package/dist/client/writeOptionsSchema.js +23 -20
  90. package/dist/client/wsMutationExecutor.d.ts +15 -20
  91. package/dist/client/wsMutationExecutor.js +17 -23
  92. package/dist/context.d.ts +6 -4
  93. package/dist/context.js +6 -4
  94. package/dist/coordination/index.d.ts +10 -8
  95. package/dist/coordination/index.js +14 -12
  96. package/dist/coordination/schema.d.ts +176 -128
  97. package/dist/coordination/schema.js +197 -133
  98. package/dist/coordination/trace.d.ts +9 -10
  99. package/dist/coordination/trace.js +13 -14
  100. package/dist/core/DatabaseManager.d.ts +5 -7
  101. package/dist/core/DatabaseManager.js +15 -19
  102. package/dist/core/QueryProcessor.d.ts +7 -9
  103. package/dist/core/QueryProcessor.js +22 -28
  104. package/dist/core/QueryView.d.ts +8 -8
  105. package/dist/core/QueryView.js +2 -2
  106. package/dist/core/StoreManager.d.ts +12 -14
  107. package/dist/core/StoreManager.js +21 -24
  108. package/dist/core/ViewRegistry.d.ts +5 -5
  109. package/dist/core/ViewRegistry.js +4 -4
  110. package/dist/core/index.d.ts +17 -12
  111. package/dist/core/index.js +32 -26
  112. package/dist/core/openIDBWithTimeout.d.ts +38 -36
  113. package/dist/core/openIDBWithTimeout.js +42 -43
  114. package/dist/core/queryUtils.d.ts +45 -0
  115. package/dist/core/queryUtils.js +69 -0
  116. package/dist/core/storeContract.d.ts +63 -61
  117. package/dist/core/storeContract.js +8 -12
  118. package/dist/environment.d.ts +28 -0
  119. package/dist/environment.js +21 -0
  120. package/dist/errorCodes.d.ts +107 -99
  121. package/dist/errorCodes.js +131 -132
  122. package/dist/errors.d.ts +160 -166
  123. package/dist/errors.js +155 -158
  124. package/dist/index.d.ts +30 -27
  125. package/dist/index.js +89 -86
  126. package/dist/interfaces/index.d.ts +102 -113
  127. package/dist/interfaces/index.js +5 -4
  128. package/dist/keys/index.d.ts +27 -29
  129. package/dist/keys/index.js +41 -40
  130. package/dist/mutators/RecordingTransaction.d.ts +16 -16
  131. package/dist/mutators/RecordingTransaction.js +31 -37
  132. package/dist/mutators/Transaction.d.ts +18 -26
  133. package/dist/mutators/Transaction.js +14 -20
  134. package/dist/mutators/UndoManager.d.ts +122 -131
  135. package/dist/mutators/UndoManager.js +145 -156
  136. package/dist/mutators/defineMutators.d.ts +23 -34
  137. package/dist/mutators/defineMutators.js +14 -20
  138. package/dist/mutators/inverseOp.d.ts +12 -15
  139. package/dist/mutators/inverseOp.js +12 -15
  140. package/dist/mutators/mutateActions.d.ts +10 -9
  141. package/dist/mutators/mutateActions.js +1 -1
  142. package/dist/mutators/readerActions.d.ts +9 -8
  143. package/dist/mutators/readerActions.js +2 -2
  144. package/dist/mutators/undoApply.d.ts +31 -27
  145. package/dist/mutators/undoApply.js +26 -24
  146. package/dist/policy/index.d.ts +5 -3
  147. package/dist/policy/index.js +5 -3
  148. package/dist/policy/types.d.ts +104 -100
  149. package/dist/policy/types.js +67 -66
  150. package/dist/query/client.d.ts +28 -23
  151. package/dist/query/client.js +45 -43
  152. package/dist/query/types.d.ts +37 -60
  153. package/dist/query/types.js +13 -33
  154. package/dist/react/AbloProvider.d.ts +1 -1
  155. package/dist/react/AbloProvider.js +2 -2
  156. package/dist/react/context.d.ts +25 -28
  157. package/dist/react/context.js +9 -10
  158. package/dist/react/index.d.ts +41 -42
  159. package/dist/react/index.js +37 -38
  160. package/dist/react/internalContext.d.ts +17 -19
  161. package/dist/react/useAblo.d.ts +23 -22
  162. package/dist/react/useAblo.js +16 -14
  163. package/dist/react/useCurrentUserId.d.ts +8 -7
  164. package/dist/react/useCurrentUserId.js +8 -7
  165. package/dist/react/useErrorListener.d.ts +7 -7
  166. package/dist/react/useErrorListener.js +10 -11
  167. package/dist/react/useMutationFailureListener.d.ts +8 -8
  168. package/dist/react/useMutationFailureListener.js +8 -8
  169. package/dist/react/useMutators.d.ts +11 -11
  170. package/dist/react/useMutators.js +3 -3
  171. package/dist/react/useReactive.js +2 -2
  172. package/dist/react/useSyncStatus.d.ts +4 -6
  173. package/dist/react/useUndoScope.d.ts +7 -9
  174. package/dist/react/useUndoScope.js +1 -1
  175. package/dist/schema/coordination.d.ts +21 -25
  176. package/dist/schema/coordination.js +21 -25
  177. package/dist/schema/ddl.d.ts +43 -39
  178. package/dist/schema/ddl.js +75 -68
  179. package/dist/schema/ddlLock.d.ts +20 -24
  180. package/dist/schema/ddlLock.js +18 -23
  181. package/dist/schema/diff.d.ts +99 -61
  182. package/dist/schema/diff.js +43 -34
  183. package/dist/schema/field.d.ts +37 -42
  184. package/dist/schema/field.js +35 -48
  185. package/dist/schema/generate.d.ts +12 -12
  186. package/dist/schema/generate.js +12 -12
  187. package/dist/schema/index.d.ts +2 -2
  188. package/dist/schema/index.js +21 -23
  189. package/dist/schema/model.d.ts +118 -143
  190. package/dist/schema/model.js +22 -33
  191. package/dist/schema/openapi.d.ts +10 -9
  192. package/dist/schema/openapi.js +5 -3
  193. package/dist/schema/queries.d.ts +29 -31
  194. package/dist/schema/queries.js +23 -25
  195. package/dist/schema/relation.d.ts +89 -99
  196. package/dist/schema/relation.js +13 -13
  197. package/dist/schema/residency.d.ts +16 -13
  198. package/dist/schema/residency.js +16 -13
  199. package/dist/schema/roles.d.ts +36 -43
  200. package/dist/schema/roles.js +31 -37
  201. package/dist/schema/schema.d.ts +33 -42
  202. package/dist/schema/schema.js +31 -32
  203. package/dist/schema/select.d.ts +13 -13
  204. package/dist/schema/select.js +13 -13
  205. package/dist/schema/serialize.d.ts +28 -31
  206. package/dist/schema/serialize.js +27 -31
  207. package/dist/schema/sugar.d.ts +17 -32
  208. package/dist/schema/sugar.js +14 -29
  209. package/dist/schema/{sync-delta-row.d.ts → syncDeltaRow.d.ts} +26 -49
  210. package/dist/schema/syncDeltaRow.js +89 -0
  211. package/dist/schema/tenancy.d.ts +44 -46
  212. package/dist/schema/tenancy.js +46 -48
  213. package/dist/server/adapter.d.ts +58 -58
  214. package/dist/server/adapter.js +13 -14
  215. package/dist/server/commit.d.ts +60 -64
  216. package/dist/server/index.d.ts +9 -10
  217. package/dist/server/index.js +1 -1
  218. package/dist/server/readConfig.d.ts +70 -0
  219. package/dist/server/readConfig.js +8 -0
  220. package/dist/server/storageMode.d.ts +23 -0
  221. package/dist/server/storageMode.js +17 -0
  222. package/dist/source/adapter.d.ts +30 -25
  223. package/dist/source/adapter.js +10 -10
  224. package/dist/source/adapters/drizzle.d.ts +28 -23
  225. package/dist/source/adapters/drizzle.js +30 -25
  226. package/dist/source/adapters/kysely.d.ts +27 -25
  227. package/dist/source/adapters/kysely.js +24 -23
  228. package/dist/source/adapters/memory.d.ts +8 -7
  229. package/dist/source/adapters/memory.js +9 -8
  230. package/dist/source/adapters/prisma.d.ts +13 -12
  231. package/dist/source/adapters/prisma.js +22 -25
  232. package/dist/source/conformance.d.ts +18 -11
  233. package/dist/source/conformance.js +17 -11
  234. package/dist/source/connector.d.ts +31 -32
  235. package/dist/source/connector.js +28 -28
  236. package/dist/source/connectorProtocol.d.ts +160 -0
  237. package/dist/source/connectorProtocol.js +162 -0
  238. package/dist/source/contract.d.ts +26 -27
  239. package/dist/source/contract.js +28 -29
  240. package/dist/source/factory.d.ts +46 -58
  241. package/dist/source/factory.js +22 -27
  242. package/dist/source/index.d.ts +7 -9
  243. package/dist/source/index.js +12 -14
  244. package/dist/source/migrations.d.ts +9 -9
  245. package/dist/source/migrations.js +9 -9
  246. package/dist/source/next.d.ts +9 -10
  247. package/dist/source/next.js +6 -7
  248. package/dist/source/pushQueue.d.ts +69 -47
  249. package/dist/source/pushQueue.js +32 -28
  250. package/dist/source/signing.d.ts +46 -17
  251. package/dist/source/signing.js +28 -11
  252. package/dist/source/types.d.ts +121 -104
  253. package/dist/source/types.js +13 -14
  254. package/dist/stores/ObjectStore.d.ts +10 -11
  255. package/dist/stores/ObjectStore.js +11 -12
  256. package/dist/stores/ObjectStoreContract.d.ts +12 -15
  257. package/dist/stores/SyncActionStore.d.ts +7 -11
  258. package/dist/stores/SyncActionStore.js +13 -17
  259. package/dist/surface.d.ts +27 -20
  260. package/dist/surface.js +27 -20
  261. package/dist/sync/{BootstrapHelper.d.ts → BootstrapFetcher.d.ts} +36 -42
  262. package/dist/sync/{BootstrapHelper.js → BootstrapFetcher.js} +76 -76
  263. package/dist/sync/ConnectionManager.d.ts +39 -50
  264. package/dist/sync/ConnectionManager.js +55 -66
  265. package/dist/sync/NetworkProbe.d.ts +24 -29
  266. package/dist/sync/NetworkProbe.js +63 -69
  267. package/dist/sync/{HydrationCoordinator.d.ts → OnDemandLoader.d.ts} +42 -41
  268. package/dist/sync/{HydrationCoordinator.js → OnDemandLoader.js} +59 -54
  269. package/dist/sync/{AreaOfInterestManager.d.ts → SubscriptionManager.d.ts} +43 -57
  270. package/dist/sync/{AreaOfInterestManager.js → SubscriptionManager.js} +43 -51
  271. package/dist/sync/SyncWebSocket.d.ts +139 -165
  272. package/dist/sync/SyncWebSocket.js +191 -223
  273. package/dist/sync/awaitClaimGrant.d.ts +18 -18
  274. package/dist/sync/awaitClaimGrant.js +11 -11
  275. package/dist/sync/bootstrapApply.d.ts +34 -24
  276. package/dist/sync/bootstrapApply.js +27 -19
  277. package/dist/sync/commitFrames.d.ts +21 -20
  278. package/dist/sync/commitFrames.js +18 -18
  279. package/dist/sync/createClaimStream.d.ts +23 -22
  280. package/dist/sync/createClaimStream.js +105 -23
  281. package/dist/sync/createPresenceStream.d.ts +19 -18
  282. package/dist/sync/createPresenceStream.js +25 -26
  283. package/dist/sync/createSnapshot.d.ts +12 -14
  284. package/dist/sync/createSnapshot.js +20 -26
  285. package/dist/sync/credentialLifecycle.d.ts +104 -104
  286. package/dist/sync/credentialLifecycle.js +140 -147
  287. package/dist/sync/deltaPipeline.d.ts +36 -34
  288. package/dist/sync/deltaPipeline.js +64 -65
  289. package/dist/sync/groupChange.d.ts +63 -61
  290. package/dist/sync/groupChange.js +74 -78
  291. package/dist/sync/heartbeat.d.ts +34 -33
  292. package/dist/sync/heartbeat.js +31 -31
  293. package/dist/sync/participants.d.ts +19 -19
  294. package/dist/sync/schemas.d.ts +3 -2
  295. package/dist/sync/schemas.js +14 -10
  296. package/dist/sync/syncCursor.d.ts +17 -21
  297. package/dist/sync/syncCursor.js +17 -21
  298. package/dist/sync/syncPlan.d.ts +28 -36
  299. package/dist/sync/syncPlan.js +18 -19
  300. package/dist/sync/syncPosition.d.ts +54 -49
  301. package/dist/sync/syncPosition.js +57 -52
  302. package/dist/sync/wsFrameHandlers.d.ts +35 -36
  303. package/dist/sync/wsFrameHandlers.js +63 -67
  304. package/dist/testing/fixtures/bootstrap.d.ts +12 -6
  305. package/dist/testing/fixtures/bootstrap.js +12 -6
  306. package/dist/testing/fixtures/deltas.d.ts +30 -33
  307. package/dist/testing/fixtures/deltas.js +30 -33
  308. package/dist/testing/fixtures/models.d.ts +11 -10
  309. package/dist/testing/fixtures/models.js +11 -10
  310. package/dist/testing/helpers/{react-wrapper.d.ts → reactWrapper.d.ts} +13 -10
  311. package/dist/testing/helpers/{react-wrapper.js → reactWrapper.js} +15 -12
  312. package/dist/testing/helpers/{sync-engine-harness.d.ts → syncEngineHarness.d.ts} +17 -15
  313. package/dist/testing/helpers/{sync-engine-harness.js → syncEngineHarness.js} +12 -10
  314. package/dist/testing/helpers/wait.d.ts +13 -8
  315. package/dist/testing/helpers/wait.js +13 -8
  316. package/dist/testing/index.d.ts +3 -3
  317. package/dist/testing/index.js +2 -2
  318. package/dist/testing/mocks/MockMutationExecutor.d.ts +18 -17
  319. package/dist/testing/mocks/MockMutationExecutor.js +15 -14
  320. package/dist/testing/mocks/MockNetworkMonitor.d.ts +8 -8
  321. package/dist/testing/mocks/MockNetworkMonitor.js +8 -8
  322. package/dist/testing/mocks/MockSyncContext.d.ts +20 -17
  323. package/dist/testing/mocks/MockSyncContext.js +15 -13
  324. package/dist/testing/mocks/MockSyncStore.d.ts +10 -10
  325. package/dist/testing/mocks/MockSyncStore.js +11 -11
  326. package/dist/testing/mocks/MockWebSocket.d.ts +26 -22
  327. package/dist/testing/mocks/MockWebSocket.js +22 -21
  328. package/dist/transactions/TransactionQueue.d.ts +181 -176
  329. package/dist/transactions/TransactionQueue.js +338 -350
  330. package/dist/transactions/TransactionStore.d.ts +6 -4
  331. package/dist/transactions/TransactionStore.js +6 -4
  332. package/dist/transactions/UnconfirmedWrites.d.ts +82 -0
  333. package/dist/transactions/UnconfirmedWrites.js +104 -0
  334. package/dist/transactions/coalesceRules.d.ts +41 -17
  335. package/dist/transactions/coalesceRules.js +40 -17
  336. package/dist/transactions/commitPayload.d.ts +48 -52
  337. package/dist/transactions/commitPayload.js +48 -57
  338. package/dist/transactions/deltaConfirmation.d.ts +20 -22
  339. package/dist/transactions/deltaConfirmation.js +37 -45
  340. package/dist/transactions/optimisticApply.d.ts +49 -0
  341. package/dist/transactions/optimisticApply.js +65 -0
  342. package/dist/transactions/{persistedReplay.d.ts → replayValidation.d.ts} +28 -22
  343. package/dist/transactions/{persistedReplay.js → replayValidation.js} +33 -27
  344. package/dist/types/global.d.ts +46 -41
  345. package/dist/types/global.js +20 -19
  346. package/dist/types/index.d.ts +71 -77
  347. package/dist/types/index.js +22 -22
  348. package/dist/types/modelData.d.ts +6 -8
  349. package/dist/types/modelData.js +5 -7
  350. package/dist/types/participant.d.ts +10 -11
  351. package/dist/types/participant.js +6 -8
  352. package/dist/types/streams.d.ts +208 -195
  353. package/dist/types/streams.js +7 -7
  354. package/dist/utils/asyncIterator.d.ts +25 -32
  355. package/dist/utils/asyncIterator.js +25 -32
  356. package/dist/utils/duration.d.ts +12 -15
  357. package/dist/utils/duration.js +12 -15
  358. package/dist/utils/mobxSetup.d.ts +53 -0
  359. package/dist/utils/{mobx-setup.js → mobxSetup.js} +42 -98
  360. package/dist/webhooks/events.d.ts +21 -16
  361. package/dist/webhooks/events.js +10 -8
  362. package/dist/webhooks/index.d.ts +5 -7
  363. package/dist/webhooks/index.js +5 -7
  364. package/dist/{schema/sync-delta-wire.d.ts → wire/delta.d.ts} +58 -41
  365. package/dist/wire/delta.js +114 -0
  366. package/dist/wire/errorEnvelope.d.ts +30 -31
  367. package/dist/wire/errorEnvelope.js +34 -40
  368. package/dist/wire/frames.d.ts +79 -86
  369. package/dist/wire/frames.js +26 -33
  370. package/dist/wire/index.d.ts +14 -12
  371. package/dist/wire/index.js +30 -26
  372. package/dist/wire/listEnvelope.d.ts +16 -23
  373. package/dist/wire/listEnvelope.js +7 -6
  374. package/dist/wire/protocol.d.ts +25 -32
  375. package/dist/wire/protocol.js +25 -32
  376. package/dist/wire/protocolVersion.d.ts +44 -40
  377. package/dist/wire/protocolVersion.js +44 -40
  378. package/docs/coordination.md +59 -0
  379. package/package.json +11 -10
  380. package/dist/ai-sdk/coordinated-tool.d.ts +0 -101
  381. package/dist/ai-sdk/coordination-context.d.ts +0 -52
  382. package/dist/core/query-utils.d.ts +0 -34
  383. package/dist/core/query-utils.js +0 -59
  384. package/dist/schema/sync-delta-row.js +0 -103
  385. package/dist/schema/sync-delta-wire.js +0 -102
  386. package/dist/server/read-config.d.ts +0 -67
  387. package/dist/server/read-config.js +0 -8
  388. package/dist/server/storage-mode.d.ts +0 -8
  389. package/dist/server/storage-mode.js +0 -28
  390. package/dist/source/connector-protocol.d.ts +0 -159
  391. package/dist/source/connector-protocol.js +0 -161
  392. package/dist/transactions/OptimisticEchoTracker.d.ts +0 -82
  393. package/dist/transactions/OptimisticEchoTracker.js +0 -104
  394. package/dist/transactions/mutation-error-handler.d.ts +0 -5
  395. package/dist/transactions/mutation-error-handler.js +0 -39
  396. package/dist/transactions/optimistic.d.ts +0 -24
  397. package/dist/transactions/optimistic.js +0 -45
  398. package/dist/utils/mobx-setup.d.ts +0 -42
@@ -1,32 +1,33 @@
1
1
  /**
2
- * Wrap `indexedDB.open()` with a timeout + loud `onblocked` surfacing so the
3
- * request can never silently hang the app.
2
+ * The error raised when opening an IndexedDB database does not complete in a
3
+ * bounded time. {@link openIDBWithTimeout} throws it in two situations: another
4
+ * browser tab is holding an older version of the database open and blocking the
5
+ * upgrade (`reason: 'blocked'`), or the open request produced no result at all
6
+ * within the timeout (`reason: 'timeout'`).
4
7
  *
5
- * The native `IDBOpenDBRequest` has a nasty failure mode: if another tab is
6
- * holding an older schema version, the request fires `onblocked` and then
7
- * waits forever for that tab to close the DB. Neither `onsuccess` nor
8
- * `onerror` fires the promise wrapping it never settles and every caller
9
- * above sits indefinitely.
10
- *
11
- * This helper converts that into a real error after a bounded wait, which
12
- * flows up through `engine.ready()` → `SyncEngineProvider.handleError()` →
13
- * the error skeleton with a retry button. A visible error is strictly better
14
- * than a forever-spinner the user can only escape by closing the tab.
8
+ * The native open request can otherwise hang indefinitely when a blocking tab
9
+ * never closes its connection, neither the success nor the error callback fires,
10
+ * and any code awaiting the open waits forever. Turning that into a thrown error
11
+ * lets the surrounding application show a recoverable failure instead of an
12
+ * unbreakable spinner.
15
13
  */
16
14
  export declare class IDBOpenTimeoutError extends Error {
17
15
  readonly dbName: string;
18
16
  readonly reason: 'blocked' | 'timeout';
19
17
  /**
20
- * Stable, transport-independent code. `toAbloError` preserves a string
21
- * `.code`, so this survives the wrap into `AbloError` and reaches the
22
- * provider's `onError` intact letting the app distinguish a wedged-storage
23
- * failure (show a recovery screen) from any other bootstrap error without a
24
- * brittle message match.
18
+ * A stable identifier for this failure, independent of the message text. When
19
+ * this error is wrapped into an {@link AbloError} by `toAbloError`, the string
20
+ * code is preserved, so error handlers can recognize a wedged-storage failure
21
+ * and offer a recovery path rather than matching on the message.
25
22
  */
26
23
  readonly code = "storage_open_timeout";
27
24
  constructor(dbName: string, reason: 'blocked' | 'timeout', message: string);
28
25
  }
29
- /** True for the wedged-IndexedDB failure, after it has been wrapped anywhere. */
26
+ /**
27
+ * Returns true when a caught value is the storage-open-timeout failure. It
28
+ * detects the failure by its stable `code`, so it still matches after the error
29
+ * has been wrapped into an {@link AbloError} or another error type.
30
+ */
30
31
  export declare function isStorageOpenTimeout(err: unknown): boolean;
31
32
  export interface OpenIDBOptions {
32
33
  /** Called inside `onupgradeneeded` — mirrors `IDBOpenDBRequest.onupgradeneeded`. */
@@ -34,30 +35,31 @@ export interface OpenIDBOptions {
34
35
  /** Max milliseconds to wait for the open request to resolve. Default 10_000. */
35
36
  timeoutMs?: number;
36
37
  /**
37
- * Called when another context (a new tab, a fresh deploy, or our own
38
- * `deleteIDBWithTimeout` self-heal) fires `versionchange` on this connection.
39
- * By default the connection is `close()`d immediately the W3C/MDN-mandated
40
- * behavior that lets the other context's upgrade/delete proceed instead of
41
- * blocking forever. Provide this to ALSO react (e.g. prompt a reload) AFTER
42
- * the close. Throwing here is swallowed.
38
+ * Called when another context a new tab, a page reload after a deploy, or
39
+ * this package's own {@link deleteIDBWithTimeout} recovery needs to upgrade
40
+ * or delete the database and fires a `versionchange` event on this connection.
41
+ * The connection is always closed first, which is what lets the other
42
+ * context's upgrade or delete proceed instead of blocking on this one. Provide
43
+ * this callback to react after that close, for example to prompt the user to
44
+ * reload. Any error it throws is ignored.
43
45
  */
44
46
  onVersionChange?: () => void;
45
47
  }
46
48
  export declare function openIDBWithTimeout(name: string, version: number | undefined, options?: OpenIDBOptions): Promise<IDBDatabase>;
47
49
  /**
48
- * Bounded `indexedDB.deleteDatabase()` — the delete counterpart of
49
- * `openIDBWithTimeout`. Used by the meta-DB self-heal: when opening
50
- * `ablo_databases` times out (a wedged backing store), we attempt to delete it
51
- * and re-create from scratch. The registry it holds is rebuildable from the
52
- * server on the next bootstrap, so dropping it is safe.
50
+ * Deletes an IndexedDB database within a bounded time — the delete counterpart
51
+ * to {@link openIDBWithTimeout}. It is used to recover from a wedged backing
52
+ * store: when opening a database times out, the caller can delete it and start
53
+ * fresh, which is safe for any database whose contents can be rebuilt on the
54
+ * next load.
53
55
  *
54
- * Like `open`, `deleteDatabase` can hang indefinitely: if another live
55
- * connection holds the DB it fires `onblocked` and waits, and on a truly stuck
56
- * store it fires *no* event at all. Both become a bounded rejection here so the
57
- * caller can fall through to surfacing a real error instead of spinning.
56
+ * Like an open request, a native delete can hang indefinitely it fires a
57
+ * blocked event and waits when another connection still holds the database, and
58
+ * on a truly stuck store it fires no event at all. Both cases become a bounded,
59
+ * resolved result here, so the caller never spins.
58
60
  *
59
- * Resolves `true` on a clean delete, `false` if it was blocked or timed out
60
- * (caller decides whether to retry the open regardless — a no-op delete still
61
- * leaves us no worse off).
61
+ * Resolves to `true` on a clean delete and `false` when the delete was blocked
62
+ * or timed out. Either way the caller can decide whether to retry the open; a
63
+ * delete that did nothing leaves the store no worse off.
62
64
  */
63
65
  export declare function deleteIDBWithTimeout(name: string, timeoutMs?: number): Promise<boolean>;
@@ -1,27 +1,24 @@
1
1
  /**
2
- * Wrap `indexedDB.open()` with a timeout + loud `onblocked` surfacing so the
3
- * request can never silently hang the app.
2
+ * The error raised when opening an IndexedDB database does not complete in a
3
+ * bounded time. {@link openIDBWithTimeout} throws it in two situations: another
4
+ * browser tab is holding an older version of the database open and blocking the
5
+ * upgrade (`reason: 'blocked'`), or the open request produced no result at all
6
+ * within the timeout (`reason: 'timeout'`).
4
7
  *
5
- * The native `IDBOpenDBRequest` has a nasty failure mode: if another tab is
6
- * holding an older schema version, the request fires `onblocked` and then
7
- * waits forever for that tab to close the DB. Neither `onsuccess` nor
8
- * `onerror` fires the promise wrapping it never settles and every caller
9
- * above sits indefinitely.
10
- *
11
- * This helper converts that into a real error after a bounded wait, which
12
- * flows up through `engine.ready()` → `SyncEngineProvider.handleError()` →
13
- * the error skeleton with a retry button. A visible error is strictly better
14
- * than a forever-spinner the user can only escape by closing the tab.
8
+ * The native open request can otherwise hang indefinitely when a blocking tab
9
+ * never closes its connection, neither the success nor the error callback fires,
10
+ * and any code awaiting the open waits forever. Turning that into a thrown error
11
+ * lets the surrounding application show a recoverable failure instead of an
12
+ * unbreakable spinner.
15
13
  */
16
14
  export class IDBOpenTimeoutError extends Error {
17
15
  dbName;
18
16
  reason;
19
17
  /**
20
- * Stable, transport-independent code. `toAbloError` preserves a string
21
- * `.code`, so this survives the wrap into `AbloError` and reaches the
22
- * provider's `onError` intact letting the app distinguish a wedged-storage
23
- * failure (show a recovery screen) from any other bootstrap error without a
24
- * brittle message match.
18
+ * A stable identifier for this failure, independent of the message text. When
19
+ * this error is wrapped into an {@link AbloError} by `toAbloError`, the string
20
+ * code is preserved, so error handlers can recognize a wedged-storage failure
21
+ * and offer a recovery path rather than matching on the message.
25
22
  */
26
23
  code = 'storage_open_timeout';
27
24
  constructor(dbName, reason, message) {
@@ -31,7 +28,11 @@ export class IDBOpenTimeoutError extends Error {
31
28
  this.name = 'IDBOpenTimeoutError';
32
29
  }
33
30
  }
34
- /** True for the wedged-IndexedDB failure, after it has been wrapped anywhere. */
31
+ /**
32
+ * Returns true when a caught value is the storage-open-timeout failure. It
33
+ * detects the failure by its stable `code`, so it still matches after the error
34
+ * has been wrapped into an {@link AbloError} or another error type.
35
+ */
35
36
  export function isStorageOpenTimeout(err) {
36
37
  return (typeof err === 'object' &&
37
38
  err !== null &&
@@ -57,13 +58,12 @@ export function openIDBWithTimeout(name, version, options = {}) {
57
58
  };
58
59
  }
59
60
  request.onsuccess = () => {
60
- // If we ALREADY timed out (or blocked) and rejected, this is a late
61
+ // If we already timed out or were blocked and rejected, this is a late
61
62
  // success: the native open eventually completed after we gave up. The
62
- // resulting connection is orphaned — nobody up the stack holds it, so
63
- // nobody will `.close()` it. A leaked open connection holds an IndexedDB
64
- // lock that wedges every subsequent open/delete of this DB name (the
65
- // exact "ablo_databases open/delete hangs forever with no event" failure
66
- // mode). Close it here so a timed-out attempt can't poison the store.
63
+ // resulting connection is orphaned — nothing up the stack holds it, so
64
+ // nothing will close it. A leaked open connection holds an IndexedDB lock
65
+ // that wedges every later open or delete of this database name, so close
66
+ // it here to keep a timed-out attempt from poisoning the store.
67
67
  if (settled) {
68
68
  try {
69
69
  request.result.close();
@@ -74,13 +74,12 @@ export function openIDBWithTimeout(name, version, options = {}) {
74
74
  return;
75
75
  }
76
76
  const db = request.result;
77
- // MANDATORY resilience handler (W3C IndexedDB / MDN): close this
78
- // connection the instant any other context wants to upgrade or delete the
79
- // DB. Without it, an open connection that ignores `versionchange` blocks
80
- // the other context's request indefinitely — the root cause of a wedged
81
- // `ablo_databases` that survives reloads (an interrupted transaction's
82
- // connection never closes, so every later open/delete hangs with no
83
- // event). Auto-closing here makes the store self-releasing.
77
+ // Required resilience handler per the IndexedDB specification: close this
78
+ // connection as soon as any other context wants to upgrade or delete the
79
+ // database. Without it, a connection that ignores `versionchange` blocks
80
+ // the other context's request indefinitely — a common cause of a database
81
+ // that stays wedged across reloads. Closing here makes the store release
82
+ // itself.
84
83
  db.onversionchange = () => {
85
84
  try {
86
85
  db.close();
@@ -120,20 +119,20 @@ export function openIDBWithTimeout(name, version, options = {}) {
120
119
  });
121
120
  }
122
121
  /**
123
- * Bounded `indexedDB.deleteDatabase()` — the delete counterpart of
124
- * `openIDBWithTimeout`. Used by the meta-DB self-heal: when opening
125
- * `ablo_databases` times out (a wedged backing store), we attempt to delete it
126
- * and re-create from scratch. The registry it holds is rebuildable from the
127
- * server on the next bootstrap, so dropping it is safe.
122
+ * Deletes an IndexedDB database within a bounded time — the delete counterpart
123
+ * to {@link openIDBWithTimeout}. It is used to recover from a wedged backing
124
+ * store: when opening a database times out, the caller can delete it and start
125
+ * fresh, which is safe for any database whose contents can be rebuilt on the
126
+ * next load.
128
127
  *
129
- * Like `open`, `deleteDatabase` can hang indefinitely: if another live
130
- * connection holds the DB it fires `onblocked` and waits, and on a truly stuck
131
- * store it fires *no* event at all. Both become a bounded rejection here so the
132
- * caller can fall through to surfacing a real error instead of spinning.
128
+ * Like an open request, a native delete can hang indefinitely it fires a
129
+ * blocked event and waits when another connection still holds the database, and
130
+ * on a truly stuck store it fires no event at all. Both cases become a bounded,
131
+ * resolved result here, so the caller never spins.
133
132
  *
134
- * Resolves `true` on a clean delete, `false` if it was blocked or timed out
135
- * (caller decides whether to retry the open regardless — a no-op delete still
136
- * leaves us no worse off).
133
+ * Resolves to `true` on a clean delete and `false` when the delete was blocked
134
+ * or timed out. Either way the caller can decide whether to retry the open; a
135
+ * delete that did nothing leaves the store no worse off.
137
136
  */
138
137
  export function deleteIDBWithTimeout(name, timeoutMs = 5_000) {
139
138
  return new Promise((resolve) => {
@@ -0,0 +1,45 @@
1
+ /**
2
+ * Small, self-contained helpers for sorting, filtering, and binary insertion.
3
+ * The incrementally-updated views that implement {@link IncrementalView} rely on
4
+ * these for their ordering and matching, so keeping the rules in one place
5
+ * ensures every view sorts and filters identically. The functions here work on
6
+ * plain arrays and values — they hold no reference to models, pools, or the
7
+ * reactivity system.
8
+ */
9
+ /**
10
+ * The interface a live view implements to receive incremental updates: one call
11
+ * when an entity is added, one when it changes, and one when it is removed. A
12
+ * view registry holds its views under this non-generic base type so it can keep
13
+ * views over different entity shapes in a single collection and notify them
14
+ * uniformly. Because a generic `View<T>` is invariant in `T`, this shared base
15
+ * is what lets the registry store and dispatch to them without unsafe casts.
16
+ */
17
+ export interface IncrementalView {
18
+ handleAdded(entity: Record<string, unknown>): void;
19
+ handleUpdated(entity: Record<string, unknown>): void;
20
+ handleRemoved(id: string): void;
21
+ }
22
+ /**
23
+ * Compares two values for sorting, tolerating `null` and `undefined`, which
24
+ * always sort last regardless of direction. `dir` is 1 for ascending or -1 for
25
+ * descending. Returns -1, 0, or 1.
26
+ */
27
+ export declare function compareValues(a: unknown, b: unknown, dir: 1 | -1): number;
28
+ /**
29
+ * Finds, by binary search, the index at which `item` should be inserted to keep
30
+ * an array ordered. The array must already be sorted by `sortKey` in direction
31
+ * `dir`, using the same rule as {@link compareValues}. Returns that insertion
32
+ * index.
33
+ */
34
+ export declare function binaryInsertionIndex<T>(arr: ArrayLike<T>, item: T, sortKey: string, dir: 1 | -1): number;
35
+ /**
36
+ * Returns true when an entity satisfies a declarative `where` filter: every key
37
+ * present in `where` must equal the entity's value for that key. A key whose
38
+ * filter value is `undefined` is skipped, so a partially-filled filter matches
39
+ * on only its defined keys.
40
+ */
41
+ export declare function matchesWhere<T extends Record<string, unknown>>(entity: T, where: Partial<T>): boolean;
42
+ /**
43
+ * Find the index of an entity by id in an array. Returns -1 if not found.
44
+ */
45
+ export declare function findIndexById<T extends Record<string, unknown>>(arr: ArrayLike<T>, id: string): number;
@@ -0,0 +1,69 @@
1
+ /**
2
+ * Small, self-contained helpers for sorting, filtering, and binary insertion.
3
+ * The incrementally-updated views that implement {@link IncrementalView} rely on
4
+ * these for their ordering and matching, so keeping the rules in one place
5
+ * ensures every view sorts and filters identically. The functions here work on
6
+ * plain arrays and values — they hold no reference to models, pools, or the
7
+ * reactivity system.
8
+ */
9
+ /**
10
+ * Compares two values for sorting, tolerating `null` and `undefined`, which
11
+ * always sort last regardless of direction. `dir` is 1 for ascending or -1 for
12
+ * descending. Returns -1, 0, or 1.
13
+ */
14
+ export function compareValues(a, b, dir) {
15
+ if (a === b)
16
+ return 0;
17
+ if (a == null)
18
+ return 1;
19
+ if (b == null)
20
+ return -1;
21
+ return (a < b ? -1 : 1) * dir;
22
+ }
23
+ /**
24
+ * Finds, by binary search, the index at which `item` should be inserted to keep
25
+ * an array ordered. The array must already be sorted by `sortKey` in direction
26
+ * `dir`, using the same rule as {@link compareValues}. Returns that insertion
27
+ * index.
28
+ */
29
+ export function binaryInsertionIndex(arr, item, sortKey, dir) {
30
+ let lo = 0;
31
+ let hi = arr.length;
32
+ const itemVal = item[sortKey];
33
+ while (lo < hi) {
34
+ const mid = (lo + hi) >>> 1;
35
+ const midVal = arr[mid][sortKey];
36
+ if (compareValues(midVal, itemVal, dir) <= 0) {
37
+ lo = mid + 1;
38
+ }
39
+ else {
40
+ hi = mid;
41
+ }
42
+ }
43
+ return lo;
44
+ }
45
+ /**
46
+ * Returns true when an entity satisfies a declarative `where` filter: every key
47
+ * present in `where` must equal the entity's value for that key. A key whose
48
+ * filter value is `undefined` is skipped, so a partially-filled filter matches
49
+ * on only its defined keys.
50
+ */
51
+ export function matchesWhere(entity, where) {
52
+ for (const [key, value] of Object.entries(where)) {
53
+ if (value === undefined)
54
+ continue;
55
+ if (entity[key] !== value)
56
+ return false;
57
+ }
58
+ return true;
59
+ }
60
+ /**
61
+ * Find the index of an entity by id in an array. Returns -1 if not found.
62
+ */
63
+ export function findIndexById(arr, id) {
64
+ for (let i = 0; i < arr.length; i++) {
65
+ if (arr[i]?.id === id)
66
+ return i;
67
+ }
68
+ return -1;
69
+ }
@@ -1,24 +1,25 @@
1
1
  /**
2
- * storeContract — the framework-neutral store contract.
2
+ * The framework-neutral store contract. {@link SyncStoreContract} is the minimal
3
+ * store interface the SDK's hooks and mutators are written against, and
4
+ * {@link BaseSyncedStore} is the concrete class that implements it. Framework
5
+ * integrations, such as the React bindings, re-export these types, so a hook can
6
+ * accept any store that satisfies the contract without depending on a particular
7
+ * UI framework.
3
8
  *
4
- * `SyncStoreContract` is the minimal store interface the SDK's hooks and
5
- * mutators program against; `BaseSyncedStore` is the concrete engine class
6
- * that implements it. The contract used to live in `react/context.ts`, which
7
- * meant the CORE store layer imported its own contract from the React
8
- * adapter (a module that runtime-imports 'react') — an L2-core →
9
- * react-integration inversion and a module cycle. It now lives here, in a
10
- * dependency-free core leaf: `react/context.ts` re-exports these types so
11
- * React consumers are unchanged, and the core layer never touches 'react'.
12
- *
13
- * Everything in this module is type-only — no runtime imports, no runtime
14
- * exports beyond erased interfaces.
9
+ * This module is type-only: it has no runtime imports and contributes nothing to
10
+ * the runtime bundle beyond the erased interface declarations.
15
11
  */
16
12
  import type { Model } from '../Model.js';
17
13
  import type { ModelScope } from '../types/index.js';
18
14
  import type { QueryView, QueryViewOptions } from './QueryView.js';
19
15
  import type { ViewRegistry } from './ViewRegistry.js';
20
16
  import type { ParticipantScope } from '../sync/participants.js';
21
- /** Sync status for UI binding */
17
+ /**
18
+ * A snapshot of the client's synchronization state, shaped for binding to UI.
19
+ * {@link SyncStoreContract.syncStatus} exposes a reactive instance of this, and
20
+ * the `useSyncStatus()` hook reads its fields to render connection and progress
21
+ * indicators.
22
+ */
22
23
  export interface SyncStatus {
23
24
  state: 'idle' | 'syncing' | 'error' | 'offline' | 'reconnecting';
24
25
  progress: number;
@@ -30,39 +31,41 @@ export interface SyncStatus {
30
31
  offlineSince?: Date;
31
32
  }
32
33
  /**
33
- * A single LOCAL mutation as observed off the commit stream the substrate
34
- * the undo system records from. One is emitted per local create/update/
35
- * delete/archive (remote/collaborator deltas never appear here: they apply
36
- * through a separate pool path that doesn't queue mutations). `previousData`
37
- * holds the pre-edit field values (captured from the model's
38
- * `modifiedProperties` first-old-wins baseline), so an inverse op is fully
39
- * derivable from the event alone — no separate snapshot pass.
40
- *
41
- * This mirrors how Yjs's `UndoManager` derives reverse-ops by observing the
42
- * doc and Liveblocks' `room.history` records room ops: undo listens to the
43
- * one place all local writes converge, rather than wrapping the write call.
34
+ * A single locally-originated mutation, observed as it flows through the commit
35
+ * stream. The undo system records these to build its inverse operations: one is
36
+ * emitted per local create, update, delete, or archive. Changes arriving from
37
+ * other participants do not appear here they apply through a separate path
38
+ * that does not queue mutations. Because `previousData` captures the field
39
+ * values as they were before the edit, each event carries everything needed to
40
+ * derive its inverse, with no separate snapshot step. A store exposes this
41
+ * stream through {@link SyncStoreContract.subscribeLocalMutations}.
44
42
  */
45
43
  export interface LocalMutation {
46
44
  type: 'create' | 'update' | 'delete' | 'archive' | 'unarchive';
47
- /** Registered model name (e.g. `'SlideLayer'`); resolved to a schema key by the recorder. */
45
+ /** The registered name of the mutated model, for example `'SlideLayer'`. */
48
46
  modelName: string;
49
47
  modelId: string;
50
- /** New field values (create/update). */
48
+ /** The new field values, for a create or an update. */
51
49
  data?: Record<string, unknown> | null;
52
- /** Pre-edit field values (update inverse patch; delete full re-create row). */
50
+ /** The field values as they were before the edit. For an update these form
51
+ * the inverse patch; for a delete they hold the full row needed to recreate
52
+ * it. */
53
53
  previousData?: Record<string, unknown> | null;
54
54
  }
55
55
  /**
56
- * Minimal store interface that the SDK hooks need.
57
- * Consumers provide their concrete store (e.g., SyncedStore) that implements this.
56
+ * The minimal store interface the SDK's hooks and mutators depend on. Provide a
57
+ * concrete store that implements it {@link BaseSyncedStore} is the built-in
58
+ * implementation — and the hooks work against your store without knowing its
59
+ * exact type. Optional members exist so lightweight test doubles can implement
60
+ * only the parts they exercise.
58
61
  */
59
62
  export interface SyncStoreContract {
60
63
  /**
61
- * Subscribe to the LOCAL mutation stream (optimistic, pre-ack) for undo
62
- * recording. Optional so minimal test doubles can omit it when absent,
63
- * undo scopes simply record nothing. The concrete store
64
- * (`BaseSyncedStore`) wires this to the TransactionQueue's
65
- * `transaction:created` event. Returns an unsubscribe function.
64
+ * Subscribes to the stream of local mutations for undo recording, delivering
65
+ * each optimistic write before it is acknowledged by the server. See
66
+ * {@link LocalMutation}. Returns a function that removes the subscription.
67
+ * This is optional: when a store does not implement it, undo scopes simply
68
+ * record nothing.
66
69
  */
67
70
  subscribeLocalMutations?(handler: (mutation: LocalMutation) => void): () => void;
68
71
  retrieve(modelClass: abstract new (...args: never[]) => Model, id: string): Model | undefined;
@@ -77,17 +80,15 @@ export interface SyncStoreContract {
77
80
  data: Model[];
78
81
  };
79
82
  /**
80
- * Save (create or update) one entity. Calling `save` in a tight loop
81
- * produces a single wire commit with one `batchIndex`: the SyncClient
82
- * debounces IDB persistence and the server push to one microtask, and
83
- * TransactionQueue coalesces every transaction staged in the tick into
84
- * one batch. There is intentionally no `saveMany` — Zero, Replicache,
85
- * and the rest of the local-first lineage all expose one-row writes
86
- * and rely on the implicit tick boundary.
83
+ * Saves one entity, creating it if new or updating it if it already exists.
84
+ * Calling `save` repeatedly within the same tick is efficient: the writes are
85
+ * coalesced and persisted, then sent to the server, as a single commit. There
86
+ * is deliberately no bulk method issue one `save` per row and let the tick
87
+ * boundary batch them.
87
88
  *
88
- * `skipValidation` exists for trusted bulk paths (AI sandbox layer
89
- * generation, PPTX import, hydration) where the producer has already
90
- * type-checked and per-row Zod is a measurable cost.
89
+ * Pass `skipValidation` on trusted, high-volume paths bulk import or
90
+ * hydration, where the data has already been validated — to skip the per-row
91
+ * schema check, which is a measurable cost at that volume.
91
92
  */
92
93
  save(model: Model, options?: {
93
94
  skipValidation?: boolean;
@@ -95,7 +96,8 @@ export interface SyncStoreContract {
95
96
  delete(model: Model): Promise<void>;
96
97
  archive(model: Model): Promise<void>;
97
98
  unarchive(model: Model): Promise<void>;
98
- /** The ObjectPool for entity/collection lookups by ID or typename. */
99
+ /** The in-memory object pool: look up individual entities or collections by
100
+ * id or model name, create views, and resolve foreign-key relationships. */
99
101
  pool: {
100
102
  get(id: string): Model | undefined;
101
103
  getByTypeName(typename: string, scope?: ModelScope): Model[];
@@ -106,10 +108,11 @@ export interface SyncStoreContract {
106
108
  viewRegistry: ViewRegistry;
107
109
  };
108
110
  /**
109
- * Reactive sync-status getters. Powered by MobX `computed` inside
110
- * `BaseSyncedStore`, so they're safe to read in `observer` components
111
- * and inside `reaction(() => store.isReady, ...)`. Consumers that
112
- * don't want to touch MobX should prefer the `useSyncStatus()` hook.
111
+ * Reactive getters for the current sync state. In the built-in store these
112
+ * are backed by observable computeds, so reading them inside a reactive
113
+ * context an observer component or a reaction re-runs that context when
114
+ * the state changes. Code that prefers not to work with the reactivity system
115
+ * directly can read the same values through the `useSyncStatus()` hook.
113
116
  */
114
117
  readonly isReady: boolean;
115
118
  readonly isSyncing: boolean;
@@ -118,14 +121,13 @@ export interface SyncStoreContract {
118
121
  readonly isError: boolean;
119
122
  readonly hasUnsyncedChanges: boolean;
120
123
  /**
121
- * Area-of-interest (dynamic read subscription). `enterScope`/`leaveScope`
122
- * move the connection's read interest as the user navigates (open/close a
123
- * deck, sheet, doc); `pinScope`/`unpinScope` express prominence (an active
124
- * claim keeps a group subscribed). Each resolves the scope through the same
125
- * resolver the claim path uses, so read interest and write claims agree on
126
- * the sync-group string. Optional so minimal test doubles can omit them;
127
- * no-ops before the socket exists. The concrete store (`BaseSyncedStore`)
128
- * forwards to its `AreaOfInterestManager`.
124
+ * Manages the connection's area of interest — the dynamic set of data it
125
+ * subscribes to. Call `enterScope` and `leaveScope` to move that interest as
126
+ * the user navigates between documents, and `pinScope` and `unpinScope` to
127
+ * keep a scope subscribed while it stays important, such as while a claim is
128
+ * held. Every scope resolves through the same resolver the claim path uses, so
129
+ * read subscriptions and write claims always agree on which group they refer
130
+ * to. These are optional and do nothing until the connection is open.
129
131
  */
130
132
  enterScope?(scope: ParticipantScope, opts?: {
131
133
  hydrate?: boolean;
@@ -134,10 +136,10 @@ export interface SyncStoreContract {
134
136
  pinScope?(scope: ParticipantScope): Promise<void>;
135
137
  unpinScope?(scope: ParticipantScope): Promise<void>;
136
138
  /**
137
- * Raw MobX-observable `SyncStatus` record. `useSyncStatus()` reads
138
- * `state`, `progress`, `pendingChanges`, `isSessionError`, `error`
139
- * from this to build its tagged union. Exposed on the contract so
140
- * consumer-facing hooks and test doubles can manipulate it directly.
139
+ * The full reactive {@link SyncStatus} record. The `useSyncStatus()` hook
140
+ * reads its fields — `state`, `progress`, `pendingChanges`, `isSessionError`,
141
+ * and `error` to present the current sync state. It is part of the contract
142
+ * so hooks and test doubles can read or set it directly.
141
143
  */
142
144
  readonly syncStatus: SyncStatus;
143
145
  }
@@ -1,16 +1,12 @@
1
1
  /**
2
- * storeContract — the framework-neutral store contract.
2
+ * The framework-neutral store contract. {@link SyncStoreContract} is the minimal
3
+ * store interface the SDK's hooks and mutators are written against, and
4
+ * {@link BaseSyncedStore} is the concrete class that implements it. Framework
5
+ * integrations, such as the React bindings, re-export these types, so a hook can
6
+ * accept any store that satisfies the contract without depending on a particular
7
+ * UI framework.
3
8
  *
4
- * `SyncStoreContract` is the minimal store interface the SDK's hooks and
5
- * mutators program against; `BaseSyncedStore` is the concrete engine class
6
- * that implements it. The contract used to live in `react/context.ts`, which
7
- * meant the CORE store layer imported its own contract from the React
8
- * adapter (a module that runtime-imports 'react') — an L2-core →
9
- * react-integration inversion and a module cycle. It now lives here, in a
10
- * dependency-free core leaf: `react/context.ts` re-exports these types so
11
- * React consumers are unchanged, and the core layer never touches 'react'.
12
- *
13
- * Everything in this module is type-only — no runtime imports, no runtime
14
- * exports beyond erased interfaces.
9
+ * This module is type-only: it has no runtime imports and contributes nothing to
10
+ * the runtime bundle beyond the erased interface declarations.
15
11
  */
16
12
  export {};
@@ -1,12 +1,40 @@
1
1
  import { z } from 'zod';
2
+ /**
3
+ * The two environments an Ablo project runs in: `production` for live data and
4
+ * `sandbox` for isolated test data. Every credential and every stored row
5
+ * belongs to exactly one of them.
6
+ */
2
7
  export declare const ENVIRONMENTS: readonly ["production", "sandbox"];
8
+ /**
9
+ * How an environment is spelled inside an API-key prefix: a `live` key acts on
10
+ * the production environment and a `test` key acts on the sandbox. Convert
11
+ * between this spelling and {@link Environment} with
12
+ * {@link environmentFromKeyPrefix} and {@link environmentToKeyPrefix}.
13
+ */
3
14
  export type KeyPrefixEnvironment = 'live' | 'test';
15
+ /** A Zod schema that validates a value as one of the {@link ENVIRONMENTS}. */
4
16
  export declare const environmentSchema: z.ZodEnum<{
5
17
  production: "production";
6
18
  sandbox: "sandbox";
7
19
  }>;
20
+ /** One of the {@link ENVIRONMENTS} — either `'production'` or `'sandbox'`. */
8
21
  export type Environment = z.infer<typeof environmentSchema>;
22
+ /**
23
+ * Coerces an untrusted value into a valid {@link Environment}, returning
24
+ * `fallback` (which defaults to `'production'`) when the value is not a
25
+ * recognized environment. Use it when reading an environment from configuration
26
+ * or off the wire.
27
+ */
9
28
  export declare function normalizeEnvironment(value: unknown, fallback?: Environment): Environment;
29
+ /**
30
+ * Maps an API-key prefix spelling to its {@link Environment}: a `'test'` key
31
+ * operates on the sandbox, and anything else on production.
32
+ */
10
33
  export declare function environmentFromKeyPrefix(value: KeyPrefixEnvironment): Environment;
34
+ /**
35
+ * Maps an {@link Environment} to the spelling used in an API-key prefix: the
36
+ * sandbox is `'test'` and production is `'live'`.
37
+ */
11
38
  export declare function environmentToKeyPrefix(value: Environment): KeyPrefixEnvironment;
39
+ /** Returns true when the given environment is the sandbox. */
12
40
  export declare function isSandboxEnvironment(value: Environment): boolean;