@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
package/dist/Database.js CHANGED
@@ -1,9 +1,13 @@
1
1
  /**
2
- * Database - Simplified persistence layer
3
- * Fixed bootstrap triggering and data flow
2
+ * The local persistence layer for synced models. It stores rows in the
3
+ * browser's IndexedDB (or in-memory maps when run headlessly), applies inbound
4
+ * deltas to that store, and fetches the bootstrap snapshot from your sync
5
+ * server. {@link BaseSyncedStore} drives it, and {@link InstanceCache} holds the
6
+ * in-memory mirror of what this class persists.
4
7
  */
5
8
  import { DatabaseManager } from './core/DatabaseManager.js';
6
9
  import { StoreManager } from './core/StoreManager.js';
10
+ import { ModelRegistry } from './ModelRegistry.js';
7
11
  import { LoadStrategy } from './types/index.js';
8
12
  import { getContext } from './context.js';
9
13
  import { AbloConnectionError, AbloValidationError } from './errors.js';
@@ -21,11 +25,11 @@ export class Database {
21
25
  return this.bootstrapHelper;
22
26
  }
23
27
  /**
24
- * PURE scoped snapshot fetch for hydrate-on-enter (P4). Returns the FULL
25
- * current rows of the given sync groups, with NO side effects — unlike
28
+ * Fetch the current rows of the given sync groups as a side-effect-free
29
+ * snapshot, used to hydrate a scope as the user enters it. Unlike
26
30
  * {@link bootstrapFromServer}, it does not persist to IndexedDB and does not
27
- * touch the connection's `subscribedSyncGroups` (which the shrinkage check
28
- * owns). The caller applies the result to the pool via the SCOPED apply path.
31
+ * change the connection's subscribed sync groups. The caller applies the
32
+ * result to the pool through the scoped apply path.
29
33
  */
30
34
  async fetchScopedBootstrapData(syncGroups) {
31
35
  // No lastSyncId → a full snapshot of exactly these groups.
@@ -105,7 +109,7 @@ export class Database {
105
109
  logPreservedFields(modelName, modelId, existing, delta) {
106
110
  if (modelName === 'Activity')
107
111
  return;
108
- const requiredFields = this.essentialFields[modelName] || [];
112
+ const requiredFields = this.essentialFields[modelName] ?? [];
109
113
  const preserved = requiredFields.filter((field) => existing[field] !== undefined && delta[field] === undefined);
110
114
  if (preserved.length > 0) {
111
115
  getContext().logger.debug('[Database] UPDATE merged - preserved fields', {
@@ -155,17 +159,14 @@ export class Database {
155
159
  getContext().logger.info(`Database opened: ${this.currentDbInfo.name} (${readiness.readyStores.length}/${readiness.totalStores} stores ready)`);
156
160
  }
157
161
  /**
158
- * Compact a record before persisting to IndexedDB
159
- * - Removes null/undefined fields
160
- * - Removes empty arrays and empty objects
161
- * - Drops redundant fields: __typename, __class, clientId, syncStatus
162
+ * Shrink a record before persisting it. Drops `undefined` fields, empty
163
+ * arrays, empty objects, and the redundant markers `__typename`, `__class`,
164
+ * `clientId`, and `syncStatus`. Explicit `null` values are preserved, since
165
+ * a null is a meaningful "clear this field" in a nullable column.
162
166
  *
163
- * ARCHITECTURE: By design, this method receives plain objects, not MobX observables:
164
- * - WebSocket deltas: Already JSON-parsed (SyncedStore.ts:889)
165
- * - Optimistic updates: Models call toJSON() which uses toJS() (SlideLayer.ts:224)
166
- * - Bootstrap data: Plain JSON from server
167
- *
168
- * Note: We do NOT drop required defaults; server provides them.
167
+ * By design this receives plain objects, never live observables: WebSocket
168
+ * deltas arrive already parsed, optimistic updates come through `toJSON()`,
169
+ * and bootstrap data is plain JSON from the server.
169
170
  */
170
171
  compactRecord(_modelName, data) {
171
172
  if (!data || typeof data !== 'object')
@@ -176,8 +177,8 @@ export class Database {
176
177
  if (key === '__typename' || key === '__class' || key === 'clientId' || key === 'syncStatus') {
177
178
  continue;
178
179
  }
179
- // FIXED: Only skip undefined, preserve explicit null values
180
- // Null is semantically meaningful in Prisma schemas (nullable fields)
180
+ // Skip only `undefined`; preserve explicit `null`, which is a
181
+ // meaningful value for a nullable column.
181
182
  if (value === undefined) {
182
183
  continue;
183
184
  }
@@ -271,26 +272,24 @@ export class Database {
271
272
  // point). Invalid → 0 → full bootstrap, the safe degradation.
272
273
  const metadataLastSyncId = syncPositionSchema.shape.persisted.safeParse(metadata?.lastSyncId).data ?? 0;
273
274
  const dataAge = metadata?.updatedAt ? Date.now() - metadata.updatedAt.getTime() : Infinity;
274
- // ── Zero-style cache-validity check ──────────────────────────
275
+ // ── Cache-validity check ─────────────────────────────────────
275
276
  //
276
277
  // The cursor (lastSyncId) is only valid if the data it refers to
277
- // actually exists in the stores. If IDB was cleared (or this is a
278
- // fresh in-memory session), the metadata's lastSyncId is stale —
279
- // sending it to the server would trigger a partial bootstrap that
280
- // returns zero deltas because the gap is 0, leaving the client
281
- // with an empty ObjectPool.
278
+ // actually exists in the stores. If the local store was cleared (or
279
+ // this is a fresh in-memory session), the metadata's lastSyncId is
280
+ // stale — sending it to the server would trigger a partial bootstrap
281
+ // that returns zero deltas because the gap is 0, leaving the client
282
+ // with an empty InstanceCache.
282
283
  //
283
- // Zero solves this by co-locating the cursor with the cached data:
284
- // if the data is gone, the cursor is gone. We achieve the same
285
- // property by sampling the actual stores — if they're empty, the
286
- // cursor is meaningless regardless of what metadata claims.
284
+ // The fix is to sample the actual stores: if they hold no rows, the
285
+ // cursor is meaningless regardless of what the metadata claims.
287
286
  const dataExists = this.inMemory
288
287
  ? false // In-memory mode: no persistent data across sessions
289
288
  : await this.storeManager.hasAnyData();
290
289
  // The effective lastSyncId: only trust the metadata cursor when
291
290
  // we've confirmed the data it refers to actually exists in the stores.
292
291
  const lastSyncId = dataExists ? metadataLastSyncId : 0;
293
- // 🔍 DIAGNOSTIC: Log database state
292
+ // Log the resolved database state for diagnostics.
294
293
  getContext().logger.debug('[Database.requiredBootstrap] State check', {
295
294
  readinessReady: readiness.ready,
296
295
  hasMetadata: !!metadata,
@@ -311,7 +310,8 @@ export class Database {
311
310
  getContext().logger.info('Offline detected with local data - using local bootstrap');
312
311
  }
313
312
  else {
314
- // SERVER-AUTHORITATIVE: Always use full bootstrap when online.
313
+ // The server is the source of truth: always use a full bootstrap
314
+ // when online.
315
315
  type = 'full';
316
316
  getContext().logger.info('Full bootstrap - server is source of truth', {
317
317
  reason: offline ? 'offline_no_data' : 'server_authoritative',
@@ -324,11 +324,13 @@ export class Database {
324
324
  type,
325
325
  modelsToLoad,
326
326
  lastSyncId,
327
- syncGroups: metadata?.syncGroups || [],
327
+ syncGroups: metadata?.syncGroups ?? [],
328
328
  };
329
329
  }
330
330
  /**
331
- * Bootstrap database with data from Go server
331
+ * Fetch a bootstrap snapshot (or delta batch) from the sync server and load
332
+ * it into the local store, then return a {@link BootstrapResult} the caller
333
+ * applies to the {@link InstanceCache}.
332
334
  */
333
335
  async bootstrapFromServer(requirements,
334
336
  /** Full sync-group subscription list — what the WS subscribes to
@@ -347,8 +349,8 @@ export class Database {
347
349
  modelsToLoad: requirements.modelsToLoad,
348
350
  });
349
351
  try {
350
- // FETCH FIRST (before any destructive operations)
351
- // This prevents data loss if the network request fails
352
+ // Fetch before any destructive operation, so a failed network
353
+ // request can't leave the local store empty.
352
354
  const startTime = typeof performance !== 'undefined' ? performance.now() : Date.now();
353
355
  getContext().logger.info('Fetching bootstrap data from server (before clearing local data)', {
354
356
  type: requirements.type,
@@ -360,16 +362,17 @@ export class Database {
360
362
  lastSyncId: bootstrapData.lastSyncId,
361
363
  hasModels: !!bootstrapData.models,
362
364
  hasDeltas: !!bootstrapData.deltas,
363
- deltaCount: bootstrapData.deltaCount || 0,
365
+ deltaCount: bootstrapData.deltaCount ?? 0,
364
366
  });
365
- // Only clear AFTER successful fetch (transactional safety)
366
- // IMPORTANT: Clear if the SERVER says it's a full snapshot, regardless of what we asked.
367
+ // Clear only after a successful fetch, for transactional safety.
368
+ // Clear when the server says the response is a full snapshot,
369
+ // regardless of what type was requested.
367
370
  if (bootstrapData.type === 'full') {
368
371
  await this.clear();
369
372
  }
370
373
  // Handle partial bootstrap (delta batch)
371
374
  if (bootstrapData.type === 'partial') {
372
- const deltas = bootstrapData.deltas || [];
375
+ const deltas = bootstrapData.deltas ?? [];
373
376
  getContext().logger.info('Processing partial bootstrap with delta batch', {
374
377
  deltaCount: deltas.length,
375
378
  fromSyncId: requirements.lastSyncId,
@@ -378,7 +381,7 @@ export class Database {
378
381
  // Apply deltas to IndexedDB using processDeltaBatch for better performance.
379
382
  // Capture the return value so the pool can be updated by the caller —
380
383
  // without this, partial-bootstrap DELETEs persist to IDB but don't
381
- // evict entities from the in-memory ObjectPool, leaving ghost rows
384
+ // evict entities from the in-memory InstanceCache, leaving ghost rows
382
385
  // visible on the canvas until a full reload rebuilds the pool.
383
386
  let deltasApplied = 0;
384
387
  let deltaResults;
@@ -500,17 +503,16 @@ export class Database {
500
503
  }
501
504
  // bootstrapSpecificModels removed per request
502
505
  /**
503
- * Process incoming delta from WebSocket - simplified
506
+ * Apply a single inbound delta from the WebSocket to the local store.
504
507
  *
505
- * ⚠️ PERFORMANCE NOTE: This method is called for each individual delta.
506
- * For batch processing, use processDeltaBatch() instead to avoid
507
- * transaction overhead (2x transactions per delta = major bottleneck).
508
+ * This handles one delta at a time. To apply several, prefer
509
+ * {@link processDeltaBatch}, which commits them in one IndexedDB transaction
510
+ * rather than two transactions per delta.
508
511
  *
509
- * 📝 PARTIAL DELTA PATTERN:
510
- * - Server sends only changed fields: {id, position: {...}, updatedAt}
511
- * - UPDATE deltas are MERGED with existing records: {...existing, ...delta}
512
- * - This preserves fields not included in the delta (e.g., deckId, title)
513
- * - Explicit null values ARE preserved: {position: null} clears the field
512
+ * Update deltas carry only the changed fields, so they are merged onto the
513
+ * existing record rather than replacing it. That preserves fields the delta
514
+ * omits (such as deckId or title), and an explicit null is kept as a value,
515
+ * clearing that field.
514
516
  */
515
517
  async processDelta(delta) {
516
518
  const { actionType, modelName, modelId, data, syncId } = delta;
@@ -518,7 +520,7 @@ export class Database {
518
520
  if (!store) {
519
521
  return { action: 'verify', modelName, modelId };
520
522
  }
521
- // Best-practice gating: ignore already-applied deltas by comparing with persisted lastSyncId
523
+ // Idempotency gate: ignore already-applied deltas by comparing with the persisted lastSyncId
522
524
  try {
523
525
  const lastApplied = await this.getLastSyncId();
524
526
  const incomingId = typeof syncId === 'number' ? syncId : undefined;
@@ -571,11 +573,12 @@ export class Database {
571
573
  return { action: 'add', modelName, modelId, data: compacted };
572
574
  }
573
575
  case 'U': {
574
- // ✅ UPDATE: MUST merge with existing record (partial delta pattern)
575
- // Read existing record first
576
+ // Update: merge onto the existing record (partial-delta pattern).
577
+ // Read the existing record first.
576
578
  const existing = await store.get(modelId);
577
- // CRITICAL FIX: Skip UPDATE if there's no existing record to merge with
578
- // Creating a record from partial UPDATE data causes corruption (missing deckId, etc.)
579
+ // Skip the update when there's no existing record to merge with:
580
+ // building a record from partial update data would corrupt it
581
+ // (missing deckId, and so on).
579
582
  if (!existing) {
580
583
  getContext().observability.breadcrumb('Skipping UPDATE delta - no existing record to merge with', 'sync.database', 'warning', {
581
584
  modelName,
@@ -618,7 +621,7 @@ export class Database {
618
621
  getContext().observability.breadcrumb(`IndexedDB delete failed for ${modelName}:${modelId}`, 'sync.database', 'error', {
619
622
  error: err instanceof Error ? err.message : String(err),
620
623
  });
621
- // Surface failure so caller does not mutate ObjectPool inconsistently
624
+ // Surface failure so caller does not mutate InstanceCache inconsistently
622
625
  throw err;
623
626
  }
624
627
  return { action: 'remove', modelName, modelId };
@@ -658,27 +661,20 @@ export class Database {
658
661
  }
659
662
  }
660
663
  /**
661
- * PERFORMANCE FIX: Process multiple deltas in a single IndexedDB transaction
662
- *
663
- * This method dramatically improves sync performance by:
664
- * 1. Batch-reading all existing records for UPDATEs (outside transaction for speed)
665
- * 2. Opening a single transaction per store for all writes
666
- * 3. Merging UPDATE deltas with existing data to preserve unmodified fields
667
- * 4. Updating metadata only once at the end with highest syncId
668
- *
669
- * Performance impact: 186 deltas goes from ~372 transactions to just 1 transaction
664
+ * Apply many deltas to the local store in as few IndexedDB transactions as
665
+ * possible. Deltas are grouped by store, and each store's writes commit in a
666
+ * single transaction, so a batch of 186 deltas becomes roughly one
667
+ * transaction per store instead of two per delta.
670
668
  *
671
- * 📝 PARTIAL DELTA MERGE PATTERN:
672
- * - UPDATE deltas contain only changed fields
673
- * - We merge with existing: {...existing, ...delta}
674
- * - Preserves deckId, title, settings etc. when updating just position
675
- * - Handles explicit null: {field: null} clears the field correctly
669
+ * The method reads the existing records for update deltas up front, then
670
+ * merges each update onto its existing record so fields the delta omits are
671
+ * preserved and an explicit null still clears its field. It advances the
672
+ * persisted sync cursor once, to the highest committed sync id.
676
673
  *
677
- * 🔄 LINEAR-STYLE CONFLICT RESOLUTION:
678
- * - Builds a map of DELETE deltas with their syncIds
679
- * - Before processing UPDATE/INSERT, checks for DELETE with higher syncId
680
- * - Skips stale updates for entities that will be/were deleted
681
- * - Prevents 404 errors from fetching already-deleted entities
674
+ * Conflict resolution follows a delete-wins rule: it first indexes the
675
+ * delete deltas by entity, then skips any insert or update whose sync id is
676
+ * at or below a delete for the same entity. This avoids resurrecting a
677
+ * deleted entity and avoids fetching one that no longer exists.
682
678
  */
683
679
  async processDeltaBatch(deltas) {
684
680
  if ((!this.workspaceDb && !this.inMemory) || this.isClosing || deltas.length === 0) {
@@ -721,14 +717,11 @@ export class Database {
721
717
  }
722
718
  // Prepare results aligned with input order
723
719
  const results = new Array(deltas.length);
724
- // ========================================================================
725
- // LINEAR-STYLE CONFLICT RESOLUTION: Build DELETE syncId index
726
- // ========================================================================
727
- // Per Linear's architecture: "If the syncId of the deleting action is larger,
728
- // the model will not be created." This prevents processing stale UPDATE deltas
729
- // for entities that have been cascade-deleted (where DELETE delta exists).
730
- // ========================================================================
731
- const deleteSyncIds = new Map(); // key: "ModelName:modelId" -> DELETE syncId
720
+ // Build a delete index for conflict resolution. When a delete has a sync
721
+ // id at or above a later insert or update for the same entity, that entity
722
+ // is not (re)created — which drops stale updates for cascade-deleted
723
+ // entities.
724
+ const deleteSyncIds = new Map(); // key: "ModelName:modelId" -> delete syncId
732
725
  for (const delta of deltas) {
733
726
  if (delta.actionType === 'D' && delta.syncId) {
734
727
  const key = `${delta.modelName}:${delta.modelId}`;
@@ -748,18 +741,17 @@ export class Database {
748
741
  }
749
742
  // Group deltas by store for efficient transaction management.
750
743
  //
751
- // We intentionally track TWO highwater marks: `highestSyncId` for the
752
- // total range seen, and `highestPersistedSyncId` accumulated only from
753
- // deltas whose store transaction actually succeeded. The cursor
754
- // advance (at `updateWorkspaceMetadata`) uses ONLY the persisted one.
744
+ // The method tracks two high-water marks: `highestSyncId` for the total
745
+ // range seen, and `highestPersistedSyncId`, accumulated only from deltas
746
+ // whose store transaction actually committed. The cursor advance (at
747
+ // `updateWorkspaceMetadata`) uses only the persisted one.
755
748
  //
756
- // Without this split, a single store-level IDB failure (e.g. compact
757
- // record missing required field, validation abort) silently advances
758
- // the cursor past deltas that never wrote to IDB. Next partial
759
- // bootstrap asks "what's new since {advanced cursor}?" and the
760
- // skipped rows fall into the already-seen range forever the
761
- // observed "postgres has the deck, IDB doesn't, full reload can't
762
- // recover it" failure mode.
749
+ // Without this split, a single store-level failure (a compacted record
750
+ // missing a required field, a validation abort) would advance the cursor
751
+ // past deltas that never wrote to IndexedDB. The next partial bootstrap
752
+ // would ask "what's new since {advanced cursor}?", the skipped rows would
753
+ // fall into the already-seen range forever, and the local store would stay
754
+ // permanently behind the server with no way to recover on reload.
763
755
  const deltasByStore = new Map();
764
756
  let highestSyncId = 0;
765
757
  let highestPersistedSyncId = 0;
@@ -772,9 +764,8 @@ export class Database {
772
764
  if (typeof deltaSyncIdNum === 'number' && !isNaN(deltaSyncIdNum) && deltaSyncIdNum > highestSyncId) {
773
765
  highestSyncId = deltaSyncIdNum;
774
766
  }
775
- // ========================================================================
776
- // CONFLICT CHECK: Skip UPDATE/INSERT if DELETE exists with higher syncId
777
- // ========================================================================
767
+ // Conflict check: skip an insert or update when a delete for the same
768
+ // entity has an equal or higher sync id.
778
769
  if (delta.actionType === 'U' ||
779
770
  delta.actionType === 'I' ||
780
771
  delta.actionType === 'C' ||
@@ -783,7 +774,7 @@ export class Database {
783
774
  const deleteSyncId = deleteSyncIds.get(key);
784
775
  if (deleteSyncId !== undefined) {
785
776
  // DELETE exists for this entity
786
- const deltaSyncId = delta.syncId || 0;
777
+ const deltaSyncId = delta.syncId ?? 0;
787
778
  if (deleteSyncId >= deltaSyncId) {
788
779
  // DELETE has equal or higher syncId - skip this UPDATE/INSERT
789
780
  getContext().logger.debug('[Database.processDeltaBatch] Skipping stale delta (DELETE wins)', {
@@ -822,8 +813,8 @@ export class Database {
822
813
  if (!store)
823
814
  continue;
824
815
  try {
825
- // ✅ BEST PRACTICE: Batch read-modify-write pattern
826
- // Step 1: Identify which deltas need existing data (UPDATEs)
816
+ // Batch read-modify-write.
817
+ // Step 1: Identify which deltas need existing data (updates)
827
818
  const updateDeltas = storeDeltas.filter(({ delta }) => delta.actionType === 'U');
828
819
  const updateIds = updateDeltas.map(({ delta }) => delta.modelId);
829
820
  // Step 2: Batch read all existing records in a SINGLE IDB transaction
@@ -848,8 +839,9 @@ export class Database {
848
839
  }
849
840
  }
850
841
  }
851
- // ✅ SELF-HEALING: Fetch missing records for UPDATE deltas
852
- // Track IDs that failed to fetch (404 = entity deleted, skip the delta)
842
+ // Self-heal by fetching missing records for update deltas.
843
+ // Track ids that failed to fetch (a 404 means the entity was deleted,
844
+ // so its delta is skipped).
853
845
  const failedToFetch = new Set();
854
846
  if (missingIds.size > 0) {
855
847
  getContext().logger.info(`[Database.processDeltaBatch] Found ${missingIds.size} missing records for ${modelName}, fetching from server...`);
@@ -923,13 +915,11 @@ export class Database {
923
915
  });
924
916
  break;
925
917
  case 'U': {
926
- // ✅ UPDATE: Merge delta with existing record (already fetched)
918
+ // Update: merge the delta onto the existing record (already fetched).
927
919
  const existing = existingRecords.get(modelId);
928
- // ========================================================================
929
- // SKIP STALE DELTAS: If entity doesn't exist locally AND failed to fetch
930
- // from server (404), this is a stale UPDATE for a deleted entity.
931
- // Per Linear's architecture, skip it instead of creating incomplete data.
932
- // ========================================================================
920
+ // Skip a stale update: if the entity is neither in the local
921
+ // store nor fetchable from the server (a 404), it was deleted,
922
+ // so skip it rather than create an incomplete record.
933
923
  if (!existing && failedToFetch.has(modelId)) {
934
924
  getContext().logger.debug('[Database.processDeltaBatch] Skipping UPDATE for deleted entity', {
935
925
  modelName,
@@ -938,8 +928,9 @@ export class Database {
938
928
  stagedResults.push({ action: 'verify', modelName, modelId, idx });
939
929
  break; // Skip this delta
940
930
  }
941
- // CRITICAL FIX: Skip UPDATE if there's no existing record to merge with
942
- // Creating a record from partial UPDATE data causes corruption (missing deckId, etc.)
931
+ // Skip the update when there's no existing record to merge with:
932
+ // building a record from partial update data would corrupt it
933
+ // (missing deckId, and so on).
943
934
  if (!existing) {
944
935
  getContext().observability.breadcrumb('Batch: Skipping UPDATE delta - no existing record', 'sync.database', 'warning', {
945
936
  modelName,
@@ -989,12 +980,12 @@ export class Database {
989
980
  }
990
981
  // Wait for transaction to complete
991
982
  await new Promise((resolve, reject) => {
992
- tx.oncomplete = () => resolve();
993
- tx.onerror = () => reject(tx.error);
983
+ tx.oncomplete = () => { resolve(); };
984
+ tx.onerror = () => { reject(tx.error); };
994
985
  });
995
986
  // Only commit staged results to the global results if the transaction succeeded.
996
- // Also advance `highestPersistedSyncId` ONLY for deltas in this successful tx
997
- // so the cursor can't advance past rows that never wrote to IDB.
987
+ // Advance `highestPersistedSyncId` only for deltas in this successful
988
+ // transaction, so the cursor can't advance past rows that never wrote to IDB.
998
989
  for (const r of stagedResults) {
999
990
  // Resolve the originating delta so we can carry its
1000
991
  // transactionId through to the result. Echo detection in
@@ -1103,13 +1094,7 @@ export class Database {
1103
1094
  const store = this.getRequiredStore(modelName);
1104
1095
  return await store.getAllFromIndex(indexName, value);
1105
1096
  }
1106
- /**
1107
- * Update workspace metadata
1108
- */
1109
- /**
1110
- * Get the last sync ID from workspace metadata
1111
- */
1112
- /** Read workspace metadata from IDB (returns null if db not open). */
1097
+ /** Read workspace metadata from IndexedDB. Returns null when the database is not open. */
1113
1098
  async getWorkspaceMetadata() {
1114
1099
  if (this.inMemory)
1115
1100
  return this.inMemoryMetadata;
@@ -1122,13 +1107,7 @@ export class Database {
1122
1107
  return 0;
1123
1108
  }
1124
1109
  const metadata = await this.databaseManager.getWorkspaceMetadata(this.workspaceDb);
1125
- return metadata?.lastSyncId || 0;
1126
- }
1127
- async getVersionVector() {
1128
- if (!this.workspaceDb)
1129
- return null;
1130
- const metadata = await this.databaseManager.getWorkspaceMetadata(this.workspaceDb);
1131
- return (metadata?.versions || null);
1110
+ return metadata?.lastSyncId ?? 0;
1132
1111
  }
1133
1112
  async updateWorkspaceMetadata(metadata) {
1134
1113
  // In-memory mode: store in local variable
@@ -1,8 +1,10 @@
1
1
  /**
2
- * ObjectPool - In-memory model cache with deduplication
3
- *
4
- * Pure memory management without database or registry dependencies.
5
- * Uses static ModelRegistry for model class lookup only.
2
+ * InstanceCache is the in-memory cache of live model instances, keyed by id and
3
+ * deduplicated so each entity has a single instance. It maintains type and
4
+ * foreign-key indexes for fast lookups, evicts entries under a size cap, and
5
+ * notifies subscribers and query views as models are added, updated, or
6
+ * removed. It holds a {@link ModelRegistry} to map between model names and
7
+ * constructor classes, but performs no persistence of its own.
6
8
  */
7
9
  import { Model } from './Model.js';
8
10
  import { ModelRegistry } from './ModelRegistry.js';
@@ -23,9 +25,10 @@ interface DeltaInfo {
23
25
  syncId?: number;
24
26
  }
25
27
  /**
26
- * ObjectPool - Pure in-memory model cache with deduplication
28
+ * The in-memory cache of model instances, keyed by id and deduplicated so each
29
+ * entity resolves to a single instance.
27
30
  */
28
- export declare class ObjectPool {
31
+ export declare class InstanceCache {
29
32
  private entries;
30
33
  private typeIndex;
31
34
  private accessTimes;
@@ -45,12 +48,6 @@ export declare class ObjectPool {
45
48
  subscribe<T extends Model>(modelClass: ModelConstructor<T>, callback: (model: T) => void): () => void;
46
49
  private notifySubscribers;
47
50
  constructor(config?: PoolConfig, modelRegistry?: ModelRegistry);
48
- /**
49
- * 🔧 PRODUCTION FIX: Initialize type indexes for all registered models
50
- * This prevents the "No type index found" error in production where constructor
51
- * references are lost due to minification.
52
- */
53
- private initializeTypeIndexes;
54
51
  private resolveModel;
55
52
  get<T extends Model = Model>(id: string): T | undefined;
56
53
  /**
@@ -115,7 +112,7 @@ export declare class ObjectPool {
115
112
  /**
116
113
  * Throw (instead of warn + return null) when the wire names a model
117
114
  * this client never registered. Passed by the developer-await read
118
- * path (`HydrationCoordinator`'s network leg) so a schema collision
115
+ * path (`OnDemandLoader`'s network leg) so a schema collision
119
116
  * — the org's pushed schema names `Document` but this client only
120
117
  * registered `documents` — surfaces AT the row that failed, with the
121
118
  * known-model list and `ablo status` pointer, instead of bubbling up