@abloatai/ablo 0.25.0 → 0.27.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (425) hide show
  1. package/AGENTS.md +5 -3
  2. package/CHANGELOG.md +34 -0
  3. package/README.md +104 -88
  4. package/dist/BaseSyncedStore.d.ts +140 -266
  5. package/dist/BaseSyncedStore.js +338 -739
  6. package/dist/Database.d.ts +62 -77
  7. package/dist/Database.js +106 -127
  8. package/dist/{ObjectPool.d.ts → InstanceCache.d.ts} +10 -13
  9. package/dist/{ObjectPool.js → InstanceCache.js} +91 -83
  10. package/dist/LazyReferenceCollection.d.ts +11 -15
  11. package/dist/LazyReferenceCollection.js +16 -15
  12. package/dist/Model.d.ts +37 -52
  13. package/dist/Model.js +52 -69
  14. package/dist/ModelRegistry.d.ts +46 -25
  15. package/dist/ModelRegistry.js +32 -30
  16. package/dist/NetworkMonitor.d.ts +5 -6
  17. package/dist/NetworkMonitor.js +6 -7
  18. package/dist/SyncClient.d.ts +119 -109
  19. package/dist/SyncClient.js +303 -224
  20. package/dist/SyncEngineContext.d.ts +1 -3
  21. package/dist/SyncEngineContext.js +1 -2
  22. package/dist/adapters/alwaysOnline.d.ts +6 -8
  23. package/dist/adapters/alwaysOnline.js +6 -8
  24. package/dist/adapters/inMemoryStorage.d.ts +9 -9
  25. package/dist/adapters/inMemoryStorage.js +9 -9
  26. package/dist/agent/Agent.d.ts +39 -31
  27. package/dist/agent/Agent.js +35 -23
  28. package/dist/agent/index.d.ts +4 -4
  29. package/dist/agent/index.js +5 -5
  30. package/dist/agent/session.d.ts +47 -44
  31. package/dist/agent/session.js +37 -48
  32. package/dist/agent/types.d.ts +26 -31
  33. package/dist/agent/types.js +6 -7
  34. package/dist/ai-sdk/coordinatedTool.d.ts +108 -0
  35. package/dist/ai-sdk/{coordinated-tool.js → coordinatedTool.js} +44 -38
  36. package/dist/ai-sdk/coordinationContext.d.ts +46 -0
  37. package/dist/ai-sdk/{coordination-context.js → coordinationContext.js} +30 -31
  38. package/dist/ai-sdk/index.d.ts +25 -22
  39. package/dist/ai-sdk/index.js +25 -22
  40. package/dist/ai-sdk/wrap.d.ts +7 -8
  41. package/dist/ai-sdk/wrap.js +2 -2
  42. package/dist/auth/credentialPolicy.d.ts +74 -71
  43. package/dist/auth/credentialPolicy.js +51 -56
  44. package/dist/auth/credentialSource.d.ts +7 -18
  45. package/dist/auth/credentialSource.js +10 -18
  46. package/dist/auth/index.d.ts +59 -58
  47. package/dist/auth/index.js +34 -40
  48. package/dist/auth/schemas.d.ts +5 -4
  49. package/dist/auth/schemas.js +5 -4
  50. package/dist/batching/index.d.ts +19 -21
  51. package/dist/batching/index.js +14 -17
  52. package/dist/cli.cjs +483 -369
  53. package/dist/client/Ablo.d.ts +107 -836
  54. package/dist/client/Ablo.js +174 -833
  55. package/dist/client/ApiClient.d.ts +44 -20
  56. package/dist/client/ApiClient.js +193 -44
  57. package/dist/client/auth.d.ts +51 -60
  58. package/dist/client/auth.js +137 -110
  59. package/dist/client/claimHeartbeatLoop.d.ts +50 -0
  60. package/dist/client/claimHeartbeatLoop.js +88 -0
  61. package/dist/client/consoleLogger.d.ts +35 -0
  62. package/dist/client/consoleLogger.js +44 -0
  63. package/dist/client/createInternalComponents.d.ts +14 -17
  64. package/dist/client/createInternalComponents.js +26 -31
  65. package/dist/client/createModelProxy.d.ts +130 -120
  66. package/dist/client/createModelProxy.js +158 -124
  67. package/dist/client/credentialEndpoint.d.ts +61 -0
  68. package/dist/client/credentialEndpoint.js +86 -0
  69. package/dist/client/functionalUpdate.d.ts +29 -27
  70. package/dist/client/functionalUpdate.js +21 -21
  71. package/dist/client/hostedEndpoints.d.ts +21 -0
  72. package/dist/client/hostedEndpoints.js +21 -0
  73. package/dist/client/httpClient.d.ts +58 -54
  74. package/dist/client/httpClient.js +29 -31
  75. package/dist/client/identity.d.ts +15 -20
  76. package/dist/client/identity.js +49 -59
  77. package/dist/client/modelRegistration.d.ts +10 -0
  78. package/dist/client/modelRegistration.js +301 -0
  79. package/dist/client/options.d.ts +373 -0
  80. package/dist/client/options.js +6 -0
  81. package/dist/client/registerDataSource.d.ts +9 -9
  82. package/dist/client/registerDataSource.js +15 -16
  83. package/dist/client/resourceTypes.d.ts +333 -0
  84. package/dist/client/resourceTypes.js +7 -0
  85. package/dist/client/schemaConfig.d.ts +44 -0
  86. package/dist/client/schemaConfig.js +176 -0
  87. package/dist/client/sessionMint.d.ts +17 -13
  88. package/dist/client/sessionMint.js +26 -31
  89. package/dist/client/validateAbloOptions.d.ts +12 -14
  90. package/dist/client/validateAbloOptions.js +9 -10
  91. package/dist/client/writeOptionsSchema.d.ts +18 -16
  92. package/dist/client/writeOptionsSchema.js +23 -20
  93. package/dist/client/wsMutationExecutor.d.ts +28 -0
  94. package/dist/client/wsMutationExecutor.js +71 -0
  95. package/dist/context.d.ts +6 -4
  96. package/dist/context.js +6 -7
  97. package/dist/coordination/index.d.ts +13 -4
  98. package/dist/coordination/index.js +29 -4
  99. package/dist/coordination/schema.d.ts +176 -128
  100. package/dist/coordination/schema.js +197 -133
  101. package/dist/coordination/trace.d.ts +9 -11
  102. package/dist/coordination/trace.js +13 -15
  103. package/dist/core/DatabaseManager.d.ts +5 -8
  104. package/dist/core/DatabaseManager.js +38 -40
  105. package/dist/core/QueryProcessor.d.ts +7 -9
  106. package/dist/core/QueryProcessor.js +27 -34
  107. package/dist/core/QueryView.d.ts +17 -5
  108. package/dist/core/QueryView.js +6 -7
  109. package/dist/core/StoreManager.d.ts +14 -16
  110. package/dist/core/StoreManager.js +26 -25
  111. package/dist/core/ViewRegistry.d.ts +5 -5
  112. package/dist/core/ViewRegistry.js +4 -4
  113. package/dist/core/index.d.ts +18 -13
  114. package/dist/core/index.js +32 -26
  115. package/dist/core/openIDBWithTimeout.d.ts +38 -36
  116. package/dist/core/openIDBWithTimeout.js +57 -54
  117. package/dist/core/queryUtils.d.ts +45 -0
  118. package/dist/core/queryUtils.js +69 -0
  119. package/dist/core/storeContract.d.ts +145 -0
  120. package/dist/core/storeContract.js +12 -0
  121. package/dist/environment.d.ts +28 -0
  122. package/dist/environment.js +21 -0
  123. package/dist/errorCodes.d.ts +118 -101
  124. package/dist/errorCodes.js +277 -260
  125. package/dist/errors.d.ts +170 -165
  126. package/dist/errors.js +161 -151
  127. package/dist/index.d.ts +30 -27
  128. package/dist/index.js +90 -82
  129. package/dist/interfaces/index.d.ts +108 -133
  130. package/dist/interfaces/index.js +5 -4
  131. package/dist/keys/index.d.ts +27 -29
  132. package/dist/keys/index.js +59 -49
  133. package/dist/mutators/RecordingTransaction.d.ts +16 -16
  134. package/dist/mutators/RecordingTransaction.js +31 -37
  135. package/dist/mutators/Transaction.d.ts +18 -26
  136. package/dist/mutators/Transaction.js +14 -20
  137. package/dist/mutators/UndoManager.d.ts +122 -131
  138. package/dist/mutators/UndoManager.js +149 -155
  139. package/dist/mutators/defineMutators.d.ts +24 -37
  140. package/dist/mutators/defineMutators.js +14 -20
  141. package/dist/mutators/inverseOp.d.ts +12 -15
  142. package/dist/mutators/inverseOp.js +12 -15
  143. package/dist/mutators/mutateActions.d.ts +10 -9
  144. package/dist/mutators/mutateActions.js +1 -1
  145. package/dist/mutators/readerActions.d.ts +9 -8
  146. package/dist/mutators/readerActions.js +2 -2
  147. package/dist/mutators/undoApply.d.ts +31 -27
  148. package/dist/mutators/undoApply.js +26 -24
  149. package/dist/policy/index.d.ts +5 -3
  150. package/dist/policy/index.js +5 -3
  151. package/dist/policy/types.d.ts +105 -101
  152. package/dist/policy/types.js +67 -66
  153. package/dist/query/client.d.ts +32 -16
  154. package/dist/query/client.js +103 -72
  155. package/dist/query/types.d.ts +37 -60
  156. package/dist/query/types.js +13 -33
  157. package/dist/react/AbloProvider.d.ts +7 -11
  158. package/dist/react/AbloProvider.js +24 -17
  159. package/dist/react/context.d.ts +27 -146
  160. package/dist/react/context.js +9 -10
  161. package/dist/react/index.d.ts +41 -42
  162. package/dist/react/index.js +37 -38
  163. package/dist/react/internalContext.d.ts +17 -19
  164. package/dist/react/useAblo.d.ts +23 -22
  165. package/dist/react/useAblo.js +17 -15
  166. package/dist/react/useCurrentUserId.d.ts +8 -7
  167. package/dist/react/useCurrentUserId.js +8 -7
  168. package/dist/react/useErrorListener.d.ts +7 -7
  169. package/dist/react/useErrorListener.js +11 -12
  170. package/dist/react/useMutationFailureListener.d.ts +8 -8
  171. package/dist/react/useMutationFailureListener.js +9 -9
  172. package/dist/react/useMutators.d.ts +11 -11
  173. package/dist/react/useMutators.js +10 -4
  174. package/dist/react/useReactive.js +2 -3
  175. package/dist/react/useSyncStatus.d.ts +4 -6
  176. package/dist/react/useUndoScope.d.ts +7 -9
  177. package/dist/react/useUndoScope.js +3 -3
  178. package/dist/schema/coordination.d.ts +21 -25
  179. package/dist/schema/coordination.js +21 -25
  180. package/dist/schema/ddl.d.ts +43 -39
  181. package/dist/schema/ddl.js +75 -68
  182. package/dist/schema/ddlLock.d.ts +35 -0
  183. package/dist/schema/ddlLock.js +46 -0
  184. package/dist/schema/diff.d.ts +99 -61
  185. package/dist/schema/diff.js +43 -34
  186. package/dist/schema/field.d.ts +37 -42
  187. package/dist/schema/field.js +36 -49
  188. package/dist/schema/generate.d.ts +12 -12
  189. package/dist/schema/generate.js +12 -12
  190. package/dist/schema/index.d.ts +5 -4
  191. package/dist/schema/index.js +29 -21
  192. package/dist/schema/model.d.ts +121 -146
  193. package/dist/schema/model.js +24 -35
  194. package/dist/schema/openapi.d.ts +10 -9
  195. package/dist/schema/openapi.js +7 -1
  196. package/dist/schema/queries.d.ts +30 -32
  197. package/dist/schema/queries.js +24 -25
  198. package/dist/schema/relation.d.ts +89 -99
  199. package/dist/schema/relation.js +13 -13
  200. package/dist/schema/residency.d.ts +38 -0
  201. package/dist/schema/residency.js +30 -0
  202. package/dist/schema/roles.d.ts +45 -27
  203. package/dist/schema/roles.js +52 -21
  204. package/dist/schema/schema.d.ts +36 -45
  205. package/dist/schema/schema.js +42 -39
  206. package/dist/schema/select.d.ts +13 -13
  207. package/dist/schema/select.js +13 -13
  208. package/dist/schema/serialize.d.ts +36 -39
  209. package/dist/schema/serialize.js +27 -31
  210. package/dist/schema/sugar.d.ts +17 -32
  211. package/dist/schema/sugar.js +14 -29
  212. package/dist/schema/{sync-delta-row.d.ts → syncDeltaRow.d.ts} +27 -50
  213. package/dist/schema/syncDeltaRow.js +89 -0
  214. package/dist/schema/tenancy.d.ts +44 -46
  215. package/dist/schema/tenancy.js +46 -48
  216. package/dist/server/adapter.d.ts +58 -58
  217. package/dist/server/adapter.js +13 -14
  218. package/dist/server/commit.d.ts +60 -64
  219. package/dist/server/index.d.ts +9 -10
  220. package/dist/server/index.js +1 -1
  221. package/dist/server/readConfig.d.ts +70 -0
  222. package/dist/server/readConfig.js +8 -0
  223. package/dist/server/storageMode.d.ts +23 -0
  224. package/dist/server/storageMode.js +17 -0
  225. package/dist/source/adapter.d.ts +31 -26
  226. package/dist/source/adapter.js +10 -10
  227. package/dist/source/adapters/drizzle.d.ts +28 -23
  228. package/dist/source/adapters/drizzle.js +34 -28
  229. package/dist/source/adapters/kysely.d.ts +27 -25
  230. package/dist/source/adapters/kysely.js +28 -26
  231. package/dist/source/adapters/memory.d.ts +8 -7
  232. package/dist/source/adapters/memory.js +10 -9
  233. package/dist/source/adapters/prisma.d.ts +13 -12
  234. package/dist/source/adapters/prisma.js +27 -29
  235. package/dist/source/conformance.d.ts +18 -11
  236. package/dist/source/conformance.js +27 -19
  237. package/dist/source/connector.d.ts +31 -32
  238. package/dist/source/connector.js +30 -28
  239. package/dist/source/connectorProtocol.d.ts +160 -0
  240. package/dist/source/connectorProtocol.js +162 -0
  241. package/dist/source/contract.d.ts +26 -27
  242. package/dist/source/contract.js +28 -29
  243. package/dist/source/factory.d.ts +94 -0
  244. package/dist/source/factory.js +268 -0
  245. package/dist/source/index.d.ts +10 -462
  246. package/dist/source/index.js +17 -421
  247. package/dist/source/migrations.d.ts +9 -9
  248. package/dist/source/migrations.js +9 -9
  249. package/dist/source/next.d.ts +10 -11
  250. package/dist/source/next.js +7 -8
  251. package/dist/source/pushQueue.d.ts +70 -48
  252. package/dist/source/pushQueue.js +36 -29
  253. package/dist/source/signing.d.ts +88 -0
  254. package/dist/source/signing.js +159 -0
  255. package/dist/source/types.d.ts +351 -0
  256. package/dist/source/types.js +43 -0
  257. package/dist/stores/ObjectStore.d.ts +11 -12
  258. package/dist/stores/ObjectStore.js +34 -35
  259. package/dist/stores/ObjectStoreContract.d.ts +12 -15
  260. package/dist/stores/SyncActionStore.d.ts +8 -12
  261. package/dist/stores/SyncActionStore.js +77 -46
  262. package/dist/surface.d.ts +28 -21
  263. package/dist/surface.js +28 -20
  264. package/dist/sync/{BootstrapHelper.d.ts → BootstrapFetcher.d.ts} +37 -45
  265. package/dist/sync/{BootstrapHelper.js → BootstrapFetcher.js} +101 -80
  266. package/dist/sync/ConnectionManager.d.ts +47 -50
  267. package/dist/sync/ConnectionManager.js +74 -70
  268. package/dist/sync/NetworkProbe.d.ts +27 -31
  269. package/dist/sync/NetworkProbe.js +67 -72
  270. package/dist/sync/{HydrationCoordinator.d.ts → OnDemandLoader.d.ts} +49 -36
  271. package/dist/sync/{HydrationCoordinator.js → OnDemandLoader.js} +79 -54
  272. package/dist/sync/{AreaOfInterestManager.d.ts → SubscriptionManager.d.ts} +45 -59
  273. package/dist/sync/{AreaOfInterestManager.js → SubscriptionManager.js} +44 -52
  274. package/dist/sync/SyncWebSocket.d.ts +175 -250
  275. package/dist/sync/SyncWebSocket.js +431 -769
  276. package/dist/sync/awaitClaimGrant.d.ts +18 -18
  277. package/dist/sync/awaitClaimGrant.js +38 -30
  278. package/dist/sync/bootstrapApply.d.ts +70 -0
  279. package/dist/sync/bootstrapApply.js +73 -0
  280. package/dist/sync/commitFrames.d.ts +44 -0
  281. package/dist/sync/commitFrames.js +94 -0
  282. package/dist/sync/createClaimStream.d.ts +23 -22
  283. package/dist/sync/createClaimStream.js +108 -25
  284. package/dist/sync/createPresenceStream.d.ts +19 -18
  285. package/dist/sync/createPresenceStream.js +25 -26
  286. package/dist/sync/createSnapshot.d.ts +13 -17
  287. package/dist/sync/createSnapshot.js +20 -26
  288. package/dist/sync/credentialLifecycle.d.ts +175 -0
  289. package/dist/sync/credentialLifecycle.js +322 -0
  290. package/dist/sync/deltaPipeline.d.ts +113 -0
  291. package/dist/sync/deltaPipeline.js +261 -0
  292. package/dist/sync/groupChange.d.ts +113 -0
  293. package/dist/sync/groupChange.js +242 -0
  294. package/dist/sync/heartbeat.d.ts +63 -0
  295. package/dist/sync/heartbeat.js +91 -0
  296. package/dist/sync/participants.d.ts +27 -27
  297. package/dist/sync/schemas.d.ts +3 -2
  298. package/dist/sync/schemas.js +14 -10
  299. package/dist/sync/syncCursor.d.ts +40 -0
  300. package/dist/sync/syncCursor.js +55 -0
  301. package/dist/sync/syncPlan.d.ts +54 -0
  302. package/dist/sync/syncPlan.js +50 -0
  303. package/dist/sync/syncPosition.d.ts +54 -49
  304. package/dist/sync/syncPosition.js +57 -52
  305. package/dist/sync/wsFrameHandlers.d.ts +116 -0
  306. package/dist/sync/wsFrameHandlers.js +374 -0
  307. package/dist/testing/fixtures/bootstrap.d.ts +21 -17
  308. package/dist/testing/fixtures/bootstrap.js +12 -6
  309. package/dist/testing/fixtures/deltas.d.ts +31 -34
  310. package/dist/testing/fixtures/deltas.js +30 -33
  311. package/dist/testing/fixtures/models.d.ts +11 -10
  312. package/dist/testing/fixtures/models.js +12 -10
  313. package/dist/testing/helpers/{react-wrapper.d.ts → reactWrapper.d.ts} +13 -10
  314. package/dist/testing/helpers/{react-wrapper.js → reactWrapper.js} +15 -12
  315. package/dist/testing/helpers/{sync-engine-harness.d.ts → syncEngineHarness.d.ts} +17 -18
  316. package/dist/testing/helpers/{sync-engine-harness.js → syncEngineHarness.js} +14 -11
  317. package/dist/testing/helpers/wait.d.ts +13 -8
  318. package/dist/testing/helpers/wait.js +13 -8
  319. package/dist/testing/index.d.ts +4 -4
  320. package/dist/testing/index.js +3 -3
  321. package/dist/testing/mocks/MockMutationExecutor.d.ts +18 -17
  322. package/dist/testing/mocks/MockMutationExecutor.js +15 -14
  323. package/dist/testing/mocks/MockNetworkMonitor.d.ts +8 -8
  324. package/dist/testing/mocks/MockNetworkMonitor.js +8 -8
  325. package/dist/testing/mocks/MockSyncContext.d.ts +21 -34
  326. package/dist/testing/mocks/MockSyncContext.js +16 -45
  327. package/dist/testing/mocks/MockSyncStore.d.ts +14 -14
  328. package/dist/testing/mocks/MockSyncStore.js +11 -11
  329. package/dist/testing/mocks/MockWebSocket.d.ts +28 -24
  330. package/dist/testing/mocks/MockWebSocket.js +22 -21
  331. package/dist/transactions/TransactionQueue.d.ts +190 -221
  332. package/dist/transactions/TransactionQueue.js +424 -822
  333. package/dist/transactions/TransactionStore.d.ts +20 -0
  334. package/dist/transactions/TransactionStore.js +53 -0
  335. package/dist/transactions/UnconfirmedWrites.d.ts +82 -0
  336. package/dist/transactions/UnconfirmedWrites.js +104 -0
  337. package/dist/transactions/coalesceRules.d.ts +58 -0
  338. package/dist/transactions/coalesceRules.js +140 -0
  339. package/dist/transactions/commitPayload.d.ts +130 -0
  340. package/dist/transactions/commitPayload.js +143 -0
  341. package/dist/transactions/deltaConfirmation.d.ts +58 -0
  342. package/dist/transactions/deltaConfirmation.js +215 -0
  343. package/dist/transactions/optimisticApply.d.ts +49 -0
  344. package/dist/transactions/optimisticApply.js +65 -0
  345. package/dist/transactions/replayValidation.d.ts +99 -0
  346. package/dist/transactions/replayValidation.js +111 -0
  347. package/dist/types/global.d.ts +46 -41
  348. package/dist/types/global.js +20 -19
  349. package/dist/types/index.d.ts +74 -80
  350. package/dist/types/index.js +22 -27
  351. package/dist/types/modelData.d.ts +10 -0
  352. package/dist/types/modelData.js +9 -0
  353. package/dist/types/participant.d.ts +20 -0
  354. package/dist/types/participant.js +10 -0
  355. package/dist/types/streams.d.ts +216 -209
  356. package/dist/types/streams.js +7 -7
  357. package/dist/utils/asyncIterator.d.ts +25 -32
  358. package/dist/utils/asyncIterator.js +25 -32
  359. package/dist/utils/duration.d.ts +12 -15
  360. package/dist/utils/duration.js +12 -15
  361. package/dist/utils/mobxSetup.d.ts +53 -0
  362. package/dist/utils/{mobx-setup.js → mobxSetup.js} +44 -100
  363. package/dist/webhooks/events.d.ts +21 -16
  364. package/dist/webhooks/events.js +10 -8
  365. package/dist/webhooks/index.d.ts +5 -7
  366. package/dist/webhooks/index.js +5 -7
  367. package/dist/{schema/sync-delta-wire.d.ts → wire/delta.d.ts} +58 -41
  368. package/dist/wire/delta.js +114 -0
  369. package/dist/wire/errorEnvelope.d.ts +35 -27
  370. package/dist/wire/errorEnvelope.js +38 -32
  371. package/dist/wire/frames.d.ts +150 -67
  372. package/dist/wire/frames.js +48 -1
  373. package/dist/wire/index.d.ts +18 -13
  374. package/dist/wire/index.js +36 -13
  375. package/dist/wire/listEnvelope.d.ts +16 -23
  376. package/dist/wire/listEnvelope.js +7 -6
  377. package/dist/wire/protocol.d.ts +38 -0
  378. package/dist/wire/protocol.js +38 -0
  379. package/dist/wire/protocolVersion.d.ts +60 -0
  380. package/dist/wire/protocolVersion.js +67 -0
  381. package/docs/api-keys.md +4 -3
  382. package/docs/coordination.md +59 -0
  383. package/docs/examples/existing-python-backend.md +3 -3
  384. package/docs/identity.md +4 -4
  385. package/docs/integration-guide.md +1 -1
  386. package/docs/react.md +1 -1
  387. package/docs/sessions.md +5 -7
  388. package/package.json +24 -21
  389. package/dist/ai-sdk/coordinated-tool.d.ts +0 -101
  390. package/dist/ai-sdk/coordination-context.d.ts +0 -52
  391. package/dist/client/index.d.ts +0 -36
  392. package/dist/client/index.js +0 -33
  393. package/dist/config/index.d.ts +0 -10
  394. package/dist/config/index.js +0 -12
  395. package/dist/core/query-utils.d.ts +0 -34
  396. package/dist/core/query-utils.js +0 -59
  397. package/dist/interfaces/headless.d.ts +0 -95
  398. package/dist/interfaces/headless.js +0 -41
  399. package/dist/query/index.d.ts +0 -6
  400. package/dist/query/index.js +0 -5
  401. package/dist/realtime/index.d.ts +0 -10
  402. package/dist/realtime/index.js +0 -9
  403. package/dist/schema/plane.d.ts +0 -23
  404. package/dist/schema/plane.js +0 -19
  405. package/dist/schema/sync-delta-row.js +0 -103
  406. package/dist/schema/sync-delta-wire.js +0 -102
  407. package/dist/server/next.d.ts +0 -51
  408. package/dist/server/next.js +0 -47
  409. package/dist/server/read-config.d.ts +0 -67
  410. package/dist/server/read-config.js +0 -8
  411. package/dist/server/storage-mode.d.ts +0 -1
  412. package/dist/server/storage-mode.js +0 -18
  413. package/dist/source/connector-protocol.d.ts +0 -159
  414. package/dist/source/connector-protocol.js +0 -161
  415. package/dist/sync/OfflineFlush.d.ts +0 -9
  416. package/dist/sync/OfflineFlush.js +0 -22
  417. package/dist/sync/OfflineTransactionStore.d.ts +0 -37
  418. package/dist/sync/OfflineTransactionStore.js +0 -263
  419. package/dist/transactions/OptimisticEchoTracker.d.ts +0 -82
  420. package/dist/transactions/OptimisticEchoTracker.js +0 -104
  421. package/dist/transactions/index.d.ts +0 -16
  422. package/dist/transactions/index.js +0 -7
  423. package/dist/transactions/mutation-error-handler.d.ts +0 -5
  424. package/dist/transactions/mutation-error-handler.js +0 -39
  425. package/dist/utils/mobx-setup.d.ts +0 -42
@@ -1,11 +1,9 @@
1
1
  /**
2
- * Ablo Sync Engine - Database Manager
3
- *
4
- * Manages the two-tier database architecture:
5
- * 1. ablo_databases - Metadata about workspace databases
6
- * 2. ablo_(hash) - Workspace-specific data storage
7
- *
8
- * Follows Ablo's architecture for database management.
2
+ * Manages the client-side IndexedDB databases the sync engine keeps in the
3
+ * browser. There are two tiers. A single registry database, `ablo_databases`,
4
+ * records metadata about every workspace database. Each user-and-workspace pair
5
+ * then gets its own data database, named `ablo_<hash>`, that holds the synced
6
+ * rows. {@link DatabaseManager} creates, versions, and deletes both tiers.
9
7
  */
10
8
  import { getContext } from '../context.js';
11
9
  import { openIDBWithTimeout, deleteIDBWithTimeout, IDBOpenTimeoutError, } from './openIDBWithTimeout.js';
@@ -90,7 +88,7 @@ export class DatabaseManager {
90
88
  else if (existingInfo) {
91
89
  schemaVersion = existingInfo.schemaVersion || 1;
92
90
  }
93
- // DEBUG: Log all existing databases for this user to detect duplicates
91
+ // Record the existing databases for this user so duplicates can be detected.
94
92
  const allUserDatabases = await this.getDatabasesForUser(userId);
95
93
  const allIndexedDBs = (await indexedDB.databases?.()) || [];
96
94
  const abloDatabases = allIndexedDBs.filter((db) => db.name?.startsWith('ablo_'));
@@ -107,7 +105,7 @@ export class DatabaseManager {
107
105
  schemaHash,
108
106
  schemaVersion,
109
107
  userVersion,
110
- createdAt: existingInfo?.createdAt || new Date(),
108
+ createdAt: existingInfo?.createdAt ?? new Date(),
111
109
  updatedAt: new Date(),
112
110
  };
113
111
  }
@@ -117,7 +115,7 @@ export class DatabaseManager {
117
115
  generateDatabaseName(userId, workspaceId, userVersion = 1) {
118
116
  // Combine userId, workspaceId, and userVersion for unique database
119
117
  const combined = `${userId}:${workspaceId}:${userVersion}`;
120
- // Generate hash similar to Linear's approach
118
+ // Hash the combined key into a compact, deterministic identifier.
121
119
  let hash = 0;
122
120
  for (let i = 0; i < combined.length; i++) {
123
121
  hash = (hash << 5) - hash + combined.charCodeAt(i);
@@ -143,8 +141,8 @@ export class DatabaseManager {
143
141
  tx.oncomplete = () => {
144
142
  resolve();
145
143
  };
146
- tx.onerror = () => reject(tx.error);
147
- request.onerror = () => reject(request.error);
144
+ tx.onerror = () => { reject(tx.error); };
145
+ request.onerror = () => { reject(request.error); };
148
146
  });
149
147
  }
150
148
  /**
@@ -157,8 +155,8 @@ export class DatabaseManager {
157
155
  const tx = this.metaDb.transaction(['databases'], 'readonly');
158
156
  const store = tx.objectStore('databases');
159
157
  const request = store.get(name);
160
- request.onsuccess = () => resolve(request.result || null);
161
- request.onerror = () => reject(request.error);
158
+ request.onsuccess = () => { resolve(request.result ?? null); };
159
+ request.onerror = () => { reject(request.error); };
162
160
  });
163
161
  }
164
162
  /**
@@ -172,8 +170,8 @@ export class DatabaseManager {
172
170
  const store = tx.objectStore('databases');
173
171
  const index = store.index('userId');
174
172
  const request = index.getAll(userId);
175
- request.onsuccess = () => resolve(request.result || []);
176
- request.onerror = () => reject(request.error);
173
+ request.onsuccess = () => { resolve(request.result || []); };
174
+ request.onerror = () => { reject(request.error); };
177
175
  });
178
176
  }
179
177
  /**
@@ -185,13 +183,12 @@ export class DatabaseManager {
185
183
  onUpgrade: (request, event) => {
186
184
  const db = request.result;
187
185
  const tx = event.target.transaction;
188
- // Per jakearchibald/idb's "Transaction Lifetime Management":
189
- // only IDB-request awaits keep an upgrade transaction alive; any
190
- // non-IDB await (fetch, timer, etc.) commits it prematurely and
191
- // later ops throw `TransactionInactiveError`. StoreManager.createStores
192
- // (src/core/StoreManager.ts:93) is only synchronous createObjectStore
193
- // / createIndex calls wrapped in an `async` keyword, so firing it
194
- // without awaiting is safe and matches the VCS-slot semantics.
186
+ // IndexedDB rule: only awaits on IndexedDB requests keep an upgrade
187
+ // transaction alive. Any other await a fetch, a timer — commits the
188
+ // transaction early, and later operations then throw
189
+ // `TransactionInactiveError`. StoreManager.createStores runs only
190
+ // synchronous createObjectStore / createIndex calls under an `async`
191
+ // keyword, so calling it without awaiting is safe here.
195
192
  if (createStoresFn && tx) {
196
193
  try {
197
194
  void createStoresFn(db, tx).catch((err) => {
@@ -231,18 +228,19 @@ export class DatabaseManager {
231
228
  return;
232
229
  }
233
230
  const meta = {
234
- lastSyncId: data.lastSyncId || 0,
235
- firstSyncId: data.firstSyncId || 0,
236
- backendDatabaseVersion: data.backendDatabaseVersion || 1,
237
- subscribedSyncGroups: data.subscribedSyncGroups || [],
231
+ lastSyncId: data.lastSyncId ?? 0,
232
+ firstSyncId: data.firstSyncId ?? 0,
233
+ backendDatabaseVersion: data.backendDatabaseVersion ?? 1,
234
+ subscribedSyncGroups: data.subscribedSyncGroups ?? [],
238
235
  updatedAt: data.updatedAt ? new Date(data.updatedAt) : new Date(),
239
236
  schemaHash: data.schemaHash,
240
237
  syncGroups: data.syncGroups,
241
- versions: data.versions || undefined,
238
+ // Older persisted records may still carry an extra `versions` key
239
+ // that is no longer used; it is tolerated by simply not reading it here.
242
240
  };
243
241
  resolve(meta);
244
242
  };
245
- request.onerror = () => reject(request.error);
243
+ request.onerror = () => { reject(request.error); };
246
244
  });
247
245
  }
248
246
  /**
@@ -253,9 +251,9 @@ export class DatabaseManager {
253
251
  const tx = db.transaction(['__meta'], 'readwrite');
254
252
  const store = tx.objectStore('__meta');
255
253
  const request = store.put(metadata, 'metadata');
256
- tx.oncomplete = () => resolve();
257
- tx.onerror = () => reject(tx.error);
258
- request.onerror = () => reject(request.error);
254
+ tx.oncomplete = () => { resolve(); };
255
+ tx.onerror = () => { reject(tx.error); };
256
+ request.onerror = () => { reject(request.error); };
259
257
  });
260
258
  }
261
259
  /**
@@ -270,7 +268,7 @@ export class DatabaseManager {
270
268
  const data = request.result;
271
269
  resolve(data?.persisted === true);
272
270
  };
273
- request.onerror = () => reject(request.error);
271
+ request.onerror = () => { reject(request.error); };
274
272
  });
275
273
  }
276
274
  /**
@@ -287,9 +285,9 @@ export class DatabaseManager {
287
285
  updatedAt: new Date().toISOString(),
288
286
  };
289
287
  const request = store.put(persistenceData, modelName);
290
- tx.oncomplete = () => resolve();
291
- tx.onerror = () => reject(tx.error);
292
- request.onerror = () => reject(request.error);
288
+ tx.oncomplete = () => { resolve(); };
289
+ tx.onerror = () => { reject(tx.error); };
290
+ request.onerror = () => { reject(request.error); };
293
291
  });
294
292
  }
295
293
  /**
@@ -312,7 +310,7 @@ export class DatabaseManager {
312
310
  }
313
311
  resolve(states);
314
312
  };
315
- request.onerror = () => reject(request.error);
313
+ request.onerror = () => { reject(request.error); };
316
314
  });
317
315
  }
318
316
  /**
@@ -362,10 +360,10 @@ export class DatabaseManager {
362
360
  const schemaVersions = {};
363
361
  for (const db of databases) {
364
362
  // Count by user
365
- databasesByUser[db.userId] = (databasesByUser[db.userId] || 0) + 1;
363
+ databasesByUser[db.userId] = (databasesByUser[db.userId] ?? 0) + 1;
366
364
  // Count schema versions
367
365
  const versionKey = `v${db.schemaVersion}`;
368
- schemaVersions[versionKey] = (schemaVersions[versionKey] || 0) + 1;
366
+ schemaVersions[versionKey] = (schemaVersions[versionKey] ?? 0) + 1;
369
367
  }
370
368
  resolve({
371
369
  metaDatabaseSize: databases.length,
@@ -374,7 +372,7 @@ export class DatabaseManager {
374
372
  schemaVersions,
375
373
  });
376
374
  };
377
- request.onerror = () => reject(request.error);
375
+ request.onerror = () => { reject(request.error); };
378
376
  });
379
377
  }
380
378
  /**
@@ -1,15 +1,13 @@
1
1
  /**
2
- * QueryProcessor - Centralized query processing for the sync engine
3
- *
4
- * Responsibilities:
5
- * - Complex filtering, sorting, and pagination logic
6
- * - Query optimization and caching strategies
7
- * - Predicate evaluation and result processing
8
- *
9
- * This extracts query processing logic from SyncedStore for proper separation of concerns
2
+ * Runs in-memory queries over a set of models — filtering by predicate,
3
+ * sorting, paginating, and caching the results. A caller hands
4
+ * {@link QueryProcessor} the candidate models and the query options, and it
5
+ * returns a {@link QueryResult}. It keeps two caches: a string-keyed cache for
6
+ * plain queries, and a structural-identity cache for predicate queries, whose
7
+ * closures cannot be turned into a stable string key.
10
8
  */
11
9
  import type { Model } from '../Model.js';
12
- import type { ModelScope } from '../ObjectPool.js';
10
+ import type { ModelScope } from '../InstanceCache.js';
13
11
  export interface QueryOptions<T extends Model> {
14
12
  predicate?: (model: T) => boolean;
15
13
  /** Stable key to distinguish different predicates for the same model type.
@@ -1,20 +1,17 @@
1
1
  /**
2
- * QueryProcessor - Centralized query processing for the sync engine
3
- *
4
- * Responsibilities:
5
- * - Complex filtering, sorting, and pagination logic
6
- * - Query optimization and caching strategies
7
- * - Predicate evaluation and result processing
8
- *
9
- * This extracts query processing logic from SyncedStore for proper separation of concerns
2
+ * Runs in-memory queries over a set of models — filtering by predicate,
3
+ * sorting, paginating, and caching the results. A caller hands
4
+ * {@link QueryProcessor} the candidate models and the query options, and it
5
+ * returns a {@link QueryResult}. It keeps two caches: a string-keyed cache for
6
+ * plain queries, and a structural-identity cache for predicate queries, whose
7
+ * closures cannot be turned into a stable string key.
10
8
  */
11
9
  /**
12
- * Optimized in-memory cache implementation
13
- *
14
- * 2025 Best Practice: O(1) invalidation by model type instead of O(n) regex matching
15
- * - Maintains a reverse index from model type to cache keys
16
- * - Invalidation by model type is O(k) where k = keys for that model type
17
- * - No regex compilation or full cache iteration needed
10
+ * The default in-memory cache. It keeps a reverse index from model type to the
11
+ * cache keys for that type, so invalidating one model type costs work
12
+ * proportional to that type's keys rather than a scan of the whole cache. A
13
+ * regex fallback still covers the rare pattern that is not a plain model-type
14
+ * match.
18
15
  */
19
16
  class BasicQueryCache {
20
17
  cache = new Map();
@@ -48,9 +45,8 @@ class BasicQueryCache {
48
45
  return;
49
46
  }
50
47
  // Fast path: Check if pattern is a simple model type match like ".*ModelType.*"
51
- const simpleMatch = pattern.match(/^\.\*(\w+)\.\*$/);
52
- if (simpleMatch) {
53
- const modelType = simpleMatch[1];
48
+ const modelType = /^\.\*(\w+)\.\*$/.exec(pattern)?.[1];
49
+ if (modelType !== undefined) {
54
50
  const keysToDelete = this.modelTypeIndex.get(modelType);
55
51
  if (keysToDelete) {
56
52
  for (const key of keysToDelete) {
@@ -88,20 +84,19 @@ class BasicQueryCache {
88
84
  * Cache key format: "operation:ModelType:options"
89
85
  */
90
86
  extractModelType(key) {
91
- const parts = key.split(':');
92
- return parts.length >= 2 ? parts[1] : null;
87
+ // A missing second segment reads as undefined, so `?? null` yields null.
88
+ return key.split(':')[1] ?? null;
93
89
  }
94
90
  }
95
91
  export class QueryProcessor {
96
92
  cache;
97
93
  enableCache;
98
- // Stable-reference cache for predicate queries.
99
- // String-based cache keys can't represent closures, so we use a separate
100
- // identity-based cache that compares result model IDs. This follows the same
101
- // principle as MobX's comparer.structural return the previous reference
102
- // when the structural content hasn't changed.
103
- // Key: deterministic portion of query (modelName + serializable options)
104
- // Value: previous result + its ID fingerprint
94
+ // Stable-reference cache for predicate queries. A string cache key cannot
95
+ // capture a closure, so predicate queries use a separate identity-based
96
+ // cache keyed on the deterministic part of the query (model name plus
97
+ // serializable options). Each entry stores the previous result and a
98
+ // fingerprint of its model ids; when the ids are unchanged, the processor
99
+ // returns the previous array reference so observers do not re-render.
105
100
  predicateResultCache = new Map();
106
101
  constructor(config = {}) {
107
102
  this.enableCache = config.enableCache ?? true;
@@ -137,10 +132,9 @@ export class QueryProcessor {
137
132
  hasMore: offset + limit < total,
138
133
  fromCache: false,
139
134
  };
140
- // For predicate queries: use structural identity comparison
141
- // Return the previous array reference if model IDs haven't changed.
142
- // This is the query-layer equivalent of MobX's comparer.structural —
143
- // observers won't re-render when the result is structurally identical.
135
+ // For predicate queries: compare by structural identity. Return the
136
+ // previous array reference when the model ids are unchanged, so observers
137
+ // don't re-render on a structurally identical result.
144
138
  if (options.predicate && this.enableCache) {
145
139
  const ids = data.map((m) => m.id).join(',');
146
140
  const cached = this.predicateResultCache.get(cacheKey);
@@ -151,7 +145,7 @@ export class QueryProcessor {
151
145
  // New result — store for future comparison
152
146
  this.predicateResultCache.set(cacheKey, { ids, result });
153
147
  }
154
- // For non-predicate queries: use string-based cache as before
148
+ // For non-predicate queries: use the string-based cache.
155
149
  if (!options.predicate && this.enableCache) {
156
150
  this.cache.set(cacheKey, result);
157
151
  }
@@ -229,9 +223,8 @@ export class QueryProcessor {
229
223
  this.cache.invalidate(pattern);
230
224
  // Also invalidate predicate result cache for this model type
231
225
  if (pattern) {
232
- const simpleMatch = pattern.match(/^\.\*(\w+)\.\*$/);
233
- if (simpleMatch) {
234
- const modelType = simpleMatch[1];
226
+ const modelType = /^\.\*(\w+)\.\*$/.exec(pattern)?.[1];
227
+ if (modelType !== undefined) {
235
228
  for (const key of this.predicateResultCache.keys()) {
236
229
  if (key.includes(modelType)) {
237
230
  this.predicateResultCache.delete(key);
@@ -9,10 +9,22 @@
9
9
  * directly and receive granular updates (splice/push, never replacement).
10
10
  */
11
11
  import { type IObservableArray } from 'mobx';
12
+ import { type Model } from '../Model.js';
12
13
  import { ModelScope } from '../types/index.js';
13
- import type { ObjectPool } from '../ObjectPool.js';
14
14
  import type { ViewRegistry } from './ViewRegistry.js';
15
- import type { IncrementalView } from './query-utils.js';
15
+ import type { IncrementalView } from './queryUtils.js';
16
+ /**
17
+ * The slice of the object pool that a {@link QueryView} reads. It is a minimal
18
+ * structural interface rather than the concrete pool class, which lets a query
19
+ * view avoid importing the pool and so breaks what would otherwise be an import
20
+ * cycle — the pool imports {@link QueryView} to construct one. The concrete
21
+ * pool satisfies this interface structurally.
22
+ */
23
+ export interface QueryViewPool {
24
+ hasForeignKeyIndex(typename: string, fieldName: string): boolean;
25
+ getByForeignKey(modelName: string, fieldName: string, fieldValue: string): Model[];
26
+ getByTypeName(modelName: string, scope?: ModelScope): Model[];
27
+ }
16
28
  export interface QueryViewOptions<T> {
17
29
  where?: Partial<T>;
18
30
  filter?: (entity: T) => boolean;
@@ -20,8 +32,8 @@ export interface QueryViewOptions<T> {
20
32
  order?: 'asc' | 'desc';
21
33
  limit?: number;
22
34
  offset?: number;
23
- /** Lifecycle filter — `live` (default), `archived`, or `all`. Named `state`
24
- * (GitHub's open/closed/all precedent) so it doesn't collide with the
35
+ /** Lifecycle filter — `live` (the default), `archived`, or `all`. It is
36
+ * named `state` rather than `scope` so it does not collide with the
25
37
  * sync-group `scope`. */
26
38
  state?: ModelScope;
27
39
  }
@@ -47,7 +59,7 @@ export declare class QueryView<T extends Record<string, unknown>> implements Inc
47
59
  private readonly fkField;
48
60
  private readonly fkValue;
49
61
  private disposed;
50
- constructor(typename: string, pool: ObjectPool, registry: ViewRegistry, options?: QueryViewOptions<T>);
62
+ constructor(typename: string, pool: QueryViewPool, registry: ViewRegistry, options?: QueryViewOptions<T>);
51
63
  private initialScan;
52
64
  handleAdded(model: Record<string, unknown>): void;
53
65
  handleUpdated(model: Record<string, unknown>): void;
@@ -11,7 +11,7 @@
11
11
  import { observable, runInAction } from 'mobx';
12
12
  import { modelAsRow } from '../Model.js';
13
13
  import { ModelScope } from '../types/index.js';
14
- import { compareValues, binaryInsertionIndex, findIndexById, } from './query-utils.js';
14
+ import { compareValues, binaryInsertionIndex, findIndexById, } from './queryUtils.js';
15
15
  // ---------------------------------------------------------------------------
16
16
  // QueryView
17
17
  // ---------------------------------------------------------------------------
@@ -54,10 +54,9 @@ export class QueryView {
54
54
  // Check for FK-index optimization: single-field where with an indexed FK
55
55
  this.fkField = null;
56
56
  this.fkValue = null;
57
- if (this.whereEntries &&
58
- this.whereEntries.length === 1 &&
59
- typeof this.whereEntries[0][1] === 'string') {
60
- const [field, value] = this.whereEntries[0];
57
+ const soleWhereEntry = this.whereEntries && this.whereEntries.length === 1 ? this.whereEntries[0] : undefined;
58
+ if (soleWhereEntry && typeof soleWhereEntry[1] === 'string') {
59
+ const [field, value] = soleWhereEntry;
61
60
  if (pool.hasForeignKeyIndex(typename, field)) {
62
61
  this.fkField = field;
63
62
  this.fkValue = value;
@@ -120,7 +119,7 @@ export class QueryView {
120
119
  if (this.disposed)
121
120
  return;
122
121
  const entity = model;
123
- const id = entity['id'];
122
+ const id = entity.id;
124
123
  const idx = id !== undefined ? this.findIndexById(id) : -1;
125
124
  const matchesNow = this.matchesFilter(entity);
126
125
  runInAction(() => {
@@ -169,7 +168,7 @@ export class QueryView {
169
168
  // -----------------------------------------------------------------------
170
169
  /** Check whether an entity passes both `where` and `filter`. */
171
170
  matchesFilter(entity) {
172
- // Note: scope is tracked per-entry in the ObjectPool, not on the model.
171
+ // Note: scope is tracked per-entry in the InstanceCache, not on the model.
173
172
  // The initial scan handles scope via getByTypeName(typename, scope).
174
173
  // Incremental notifications from the pool are scope-appropriate since
175
174
  // add/upsert/remove reflect the pool's authoritative scope tracking.
@@ -1,9 +1,10 @@
1
1
  /**
2
- * Linear Sync Engine - Store Manager
3
- *
4
- * Manages all ObjectStore instances for registered models.
5
- * Creates appropriate store types based on model load strategies.
6
- * Follows Linear's architecture with 80+ ObjectStore instances.
2
+ * Manages the {@link ObjectStore} instances the sync engine keeps in the
3
+ * browser — one per registered model — alongside the single
4
+ * {@link SyncActionStore} for pending changes. It creates each store from the
5
+ * model's metadata, tracks readiness, and provisions the underlying IndexedDB
6
+ * object stores. A model's load strategy (instant, lazy, or partial) decides
7
+ * how and when its data is loaded.
7
8
  */
8
9
  import { ModelRegistry } from '../ModelRegistry.js';
9
10
  import { ObjectStore } from '../stores/ObjectStore.js';
@@ -63,15 +64,12 @@ export declare class StoreManager {
63
64
  totalStores: number;
64
65
  }>;
65
66
  /**
66
- * Check if ANY data store has at least one record.
67
- *
68
- * This is the Zero-style cache-validity check: if the stores are empty,
69
- * the sync cursor (lastSyncId) is invalid regardless of what the metadata
70
- * says. The cursor and the data must be co-located no data means no
71
- * cursor, which means full bootstrap.
72
- *
73
- * Samples up to 3 stores to avoid a full scan. If any store has records,
74
- * returns true (we have cached data worth preserving).
67
+ * Reports whether any data store holds at least one record. This is a
68
+ * cache-validity check: if the stores are empty, the sync cursor
69
+ * (`lastSyncId`) is meaningless no matter what the metadata says, because the
70
+ * cursor and the data must travel together no data means no cursor, which
71
+ * forces a full bootstrap. To stay cheap it samples up to three stores rather
72
+ * than scanning them all, and returns true as soon as one has records.
75
73
  */
76
74
  hasAnyData(): Promise<boolean>;
77
75
  /**
@@ -120,12 +118,12 @@ export declare class StoreManager {
120
118
  notReady: number;
121
119
  };
122
120
  totalRecords: number;
123
- storeDetails: Array<{
121
+ storeDetails: {
124
122
  modelName: string;
125
123
  storeName: string;
126
124
  strategy: LoadStrategy;
127
125
  ready: boolean;
128
126
  count: number;
129
- }>;
127
+ }[];
130
128
  }>;
131
129
  }
@@ -1,10 +1,12 @@
1
1
  /**
2
- * Linear Sync Engine - Store Manager
3
- *
4
- * Manages all ObjectStore instances for registered models.
5
- * Creates appropriate store types based on model load strategies.
6
- * Follows Linear's architecture with 80+ ObjectStore instances.
2
+ * Manages the {@link ObjectStore} instances the sync engine keeps in the
3
+ * browser — one per registered model — alongside the single
4
+ * {@link SyncActionStore} for pending changes. It creates each store from the
5
+ * model's metadata, tracks readiness, and provisions the underlying IndexedDB
6
+ * object stores. A model's load strategy (instant, lazy, or partial) decides
7
+ * how and when its data is loaded.
7
8
  */
9
+ import { ModelRegistry } from '../ModelRegistry.js';
8
10
  import { ObjectStore } from '../stores/ObjectStore.js';
9
11
  import { SyncActionStore } from '../stores/SyncActionStore.js';
10
12
  import { LoadStrategy } from '../types/index.js';
@@ -69,7 +71,7 @@ export class StoreManager {
69
71
  }
70
72
  // Use model name directly as store name
71
73
  const storeName = modelName;
72
- // Create ObjectStore (MVP: simplified - use single store type for all strategies)
74
+ // Create the ObjectStore. One store type currently serves every load strategy.
73
75
  const store = new ObjectStore(this.db, modelName, storeName, metadata);
74
76
  this.stores.set(modelName, store);
75
77
  }
@@ -121,7 +123,7 @@ export class StoreManager {
121
123
  }
122
124
  // Create __meta table for model persistence state and database metadata
123
125
  if (!db.objectStoreNames.contains('__meta')) {
124
- const metaStore = db.createObjectStore('__meta');
126
+ db.createObjectStore('__meta');
125
127
  getContext().logger.debug('Created __meta table');
126
128
  }
127
129
  // Create __transactions table for unsent transactions
@@ -183,22 +185,22 @@ export class StoreManager {
183
185
  };
184
186
  }
185
187
  /**
186
- * Check if ANY data store has at least one record.
187
- *
188
- * This is the Zero-style cache-validity check: if the stores are empty,
189
- * the sync cursor (lastSyncId) is invalid regardless of what the metadata
190
- * says. The cursor and the data must be co-located no data means no
191
- * cursor, which means full bootstrap.
192
- *
193
- * Samples up to 3 stores to avoid a full scan. If any store has records,
194
- * returns true (we have cached data worth preserving).
188
+ * Reports whether any data store holds at least one record. This is a
189
+ * cache-validity check: if the stores are empty, the sync cursor
190
+ * (`lastSyncId`) is meaningless no matter what the metadata says, because the
191
+ * cursor and the data must travel together no data means no cursor, which
192
+ * forces a full bootstrap. To stay cheap it samples up to three stores rather
193
+ * than scanning them all, and returns true as soon as one has records.
195
194
  */
196
195
  async hasAnyData() {
197
196
  const storeEntries = Array.from(this.stores);
198
197
  // Sample a few stores — don't check all 30+ if the first one has data
199
198
  const samplesToCheck = Math.min(storeEntries.length, 3);
200
199
  for (let i = 0; i < samplesToCheck; i++) {
201
- const [, store] = storeEntries[i];
200
+ const entry = storeEntries[i];
201
+ if (!entry)
202
+ break;
203
+ const [, store] = entry;
202
204
  try {
203
205
  const count = await store.count();
204
206
  if (count > 0)
@@ -277,8 +279,8 @@ export class StoreManager {
277
279
  * Clear all stores
278
280
  */
279
281
  async clearAllStores() {
280
- // Lifecycle chatter (logout / identity switch / reset) NOT a warning.
281
- // `debug` so it's silent under the default `warn` threshold.
282
+ // Lifecycle chatter (logout / identity switch / reset), not a warning.
283
+ // Logged at `debug` so it stays silent under the default `warn` threshold.
282
284
  getContext().logger.debug('Clearing all stores');
283
285
  const promises = Array.from(this.stores.values()).map((store) => store.clear());
284
286
  await Promise.all(promises);
@@ -293,12 +295,11 @@ export class StoreManager {
293
295
  for (const store of this.stores.values()) {
294
296
  store.markAsClosing();
295
297
  }
296
- // SyncActionStore is a standalone store (does NOT extend ObjectStore)
297
- // and has no markAsClosing equivalent. The previous `(syncactionStore
298
- // as any).markAsClosing?.()` was a silent no-op disguised as a real
299
- // call the optional chain swallowed the missing method. If
300
- // closing-state coordination is needed for sync actions, add it
301
- // explicitly to SyncActionStore rather than reintroducing the cast.
298
+ // SyncActionStore is a standalone store that does not extend ObjectStore
299
+ // and has no markAsClosing equivalent, so it is intentionally skipped here.
300
+ // If closing-state coordination is ever needed for sync actions, add it
301
+ // explicitly to SyncActionStore rather than casting to reach a method that
302
+ // may not exist.
302
303
  getContext().logger.debug('All stores marked as closing');
303
304
  }
304
305
  /**
@@ -1,20 +1,20 @@
1
1
  /**
2
2
  * ViewRegistry — tracks active QueryViews per typename.
3
3
  *
4
- * When the ObjectPool mutates a model, it calls notifyAdded / notifyUpdated /
4
+ * When the InstanceCache mutates a model, it calls notifyAdded / notifyUpdated /
5
5
  * notifyRemoved on the registry, which fans the event out to every active
6
6
  * QueryView subscribed to that typename.
7
7
  */
8
8
  import { type Model } from '../Model.js';
9
- import type { IncrementalView } from './query-utils.js';
9
+ import type { IncrementalView } from './queryUtils.js';
10
10
  export declare class ViewRegistry {
11
11
  private views;
12
12
  register(typename: string, view: IncrementalView): void;
13
13
  unregister(typename: string, view: IncrementalView): void;
14
- /** Called by ObjectPool after a model is added to the pool. */
14
+ /** Called by InstanceCache after a model is added to the pool. */
15
15
  notifyAdded(typename: string, model: Model): void;
16
- /** Called by ObjectPool after a model is updated in the pool. */
16
+ /** Called by InstanceCache after a model is updated in the pool. */
17
17
  notifyUpdated(typename: string, model: Model): void;
18
- /** Called by ObjectPool after a model is removed from the pool. */
18
+ /** Called by InstanceCache after a model is removed from the pool. */
19
19
  notifyRemoved(typename: string, modelId: string): void;
20
20
  }
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * ViewRegistry — tracks active QueryViews per typename.
3
3
  *
4
- * When the ObjectPool mutates a model, it calls notifyAdded / notifyUpdated /
4
+ * When the InstanceCache mutates a model, it calls notifyAdded / notifyUpdated /
5
5
  * notifyRemoved on the registry, which fans the event out to every active
6
6
  * QueryView subscribed to that typename.
7
7
  */
@@ -25,7 +25,7 @@ export class ViewRegistry {
25
25
  this.views.delete(typename);
26
26
  }
27
27
  }
28
- /** Called by ObjectPool after a model is added to the pool. */
28
+ /** Called by InstanceCache after a model is added to the pool. */
29
29
  notifyAdded(typename, model) {
30
30
  const set = this.views.get(typename);
31
31
  if (!set)
@@ -34,7 +34,7 @@ export class ViewRegistry {
34
34
  view.handleAdded(modelAsRow(model));
35
35
  }
36
36
  }
37
- /** Called by ObjectPool after a model is updated in the pool. */
37
+ /** Called by InstanceCache after a model is updated in the pool. */
38
38
  notifyUpdated(typename, model) {
39
39
  const set = this.views.get(typename);
40
40
  if (!set)
@@ -43,7 +43,7 @@ export class ViewRegistry {
43
43
  view.handleUpdated(modelAsRow(model));
44
44
  }
45
45
  }
46
- /** Called by ObjectPool after a model is removed from the pool. */
46
+ /** Called by InstanceCache after a model is removed from the pool. */
47
47
  notifyRemoved(typename, modelId) {
48
48
  const set = this.views.get(typename);
49
49
  if (!set)