@abloatai/ablo 0.34.1 → 0.36.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 (536) hide show
  1. package/AGENTS.md +2 -1
  2. package/CHANGELOG.md +758 -5
  3. package/README.md +56 -502
  4. package/bin/ablo.cjs +39 -0
  5. package/dist/BaseSyncedStore.d.ts +176 -48
  6. package/dist/BaseSyncedStore.js +346 -214
  7. package/dist/Database.d.ts +17 -44
  8. package/dist/Database.js +96 -79
  9. package/dist/InstanceCache.d.ts +31 -6
  10. package/dist/InstanceCache.js +65 -30
  11. package/dist/LazyReferenceCollection.d.ts +3 -3
  12. package/dist/LazyReferenceCollection.js +4 -4
  13. package/dist/Model.d.ts +23 -13
  14. package/dist/Model.js +27 -17
  15. package/dist/ModelRegistry.d.ts +8 -4
  16. package/dist/ModelRegistry.js +20 -18
  17. package/dist/NetworkMonitor.d.ts +3 -1
  18. package/dist/NetworkMonitor.js +7 -5
  19. package/dist/{SyncEngineContext.d.ts → RuntimeContext.d.ts} +20 -13
  20. package/dist/{SyncEngineContext.js → RuntimeContext.js} +11 -12
  21. package/dist/SyncClient.d.ts +47 -47
  22. package/dist/SyncClient.js +215 -156
  23. package/dist/ai-sdk/coordinatedTool.d.ts +2 -2
  24. package/dist/ai-sdk/coordinatedTool.js +1 -1
  25. package/dist/ai-sdk/coordinationContext.d.ts +2 -2
  26. package/dist/ai-sdk/coordinationContext.js +1 -1
  27. package/dist/ai-sdk/wrap.d.ts +3 -3
  28. package/dist/ai-sdk/wrap.js +2 -2
  29. package/dist/auth/index.d.ts +1 -156
  30. package/dist/auth/index.js +8 -301
  31. package/dist/client/Ablo.d.ts +42 -287
  32. package/dist/client/Ablo.js +129 -963
  33. package/dist/client/abloClient.d.ts +309 -0
  34. package/dist/client/abloClient.js +13 -0
  35. package/dist/client/clientPrelude.d.ts +52 -0
  36. package/dist/client/clientPrelude.js +60 -0
  37. package/dist/client/consoleLogger.d.ts +2 -2
  38. package/dist/client/coreClient.d.ts +60 -0
  39. package/dist/client/coreClient.js +118 -0
  40. package/dist/client/createInternalComponents.d.ts +8 -4
  41. package/dist/client/createInternalComponents.js +17 -10
  42. package/dist/client/createModelProxy.d.ts +98 -373
  43. package/dist/client/createModelProxy.js +233 -139
  44. package/dist/client/humans.d.ts +69 -0
  45. package/dist/client/humans.js +78 -0
  46. package/dist/client/modelRegistration.d.ts +1 -1
  47. package/dist/client/modelRegistration.js +9 -9
  48. package/dist/client/options.d.ts +73 -17
  49. package/dist/client/reactiveEngine.d.ts +53 -0
  50. package/dist/client/reactiveEngine.js +688 -0
  51. package/dist/client/resourceTypes.d.ts +9 -250
  52. package/dist/client/resourceTypes.js +8 -5
  53. package/dist/client/schemaConfig.d.ts +4 -4
  54. package/dist/client/schemaConfig.js +6 -2
  55. package/dist/client/storeCluster.d.ts +47 -0
  56. package/dist/client/storeCluster.js +118 -0
  57. package/dist/client/storeLifecycle.d.ts +61 -0
  58. package/dist/client/storeLifecycle.js +231 -0
  59. package/dist/client/validateAbloOptions.d.ts +3 -2
  60. package/dist/client/validateAbloOptions.js +1 -1
  61. package/dist/client/wsMutationExecutor.d.ts +3 -3
  62. package/dist/client/wsMutationExecutor.js +3 -3
  63. package/dist/context.d.ts +22 -9
  64. package/dist/context.js +33 -9
  65. package/dist/coordination/ClaimLog.d.ts +26 -0
  66. package/dist/coordination/ClaimLog.js +32 -0
  67. package/dist/coordination/index.d.ts +1 -15
  68. package/dist/coordination/index.js +8 -31
  69. package/dist/core/index.d.ts +3 -3
  70. package/dist/core/index.js +2 -2
  71. package/dist/docs/catalog.d.ts +72 -0
  72. package/dist/docs/catalog.js +230 -0
  73. package/dist/docs/index.d.ts +10 -0
  74. package/dist/docs/index.js +10 -0
  75. package/dist/environment.d.ts +1 -40
  76. package/dist/environment.js +8 -37
  77. package/dist/index.d.ts +44 -36
  78. package/dist/index.js +30 -22
  79. package/dist/interfaces/index.d.ts +44 -134
  80. package/dist/keys/index.d.ts +1 -77
  81. package/dist/keys/index.js +8 -190
  82. package/dist/mutators/{RecordingTransaction.d.ts → RecordingMutation.d.ts} +4 -4
  83. package/dist/mutators/{RecordingTransaction.js → RecordingMutation.js} +2 -2
  84. package/dist/mutators/Transaction.d.ts +1 -1
  85. package/dist/mutators/Transaction.js +1 -1
  86. package/dist/mutators/UndoManager.d.ts +6 -6
  87. package/dist/mutators/UndoManager.js +5 -5
  88. package/dist/mutators/defineMutators.d.ts +3 -3
  89. package/dist/mutators/defineMutators.js +1 -1
  90. package/dist/mutators/inverseOp.js +2 -2
  91. package/dist/mutators/mutateActions.d.ts +3 -3
  92. package/dist/mutators/mutateActions.js +1 -1
  93. package/dist/mutators/readerActions.d.ts +1 -1
  94. package/dist/mutators/undoApply.d.ts +1 -1
  95. package/dist/mutators/undoApply.js +1 -1
  96. package/dist/policy/index.d.ts +2 -2
  97. package/dist/policy/index.js +1 -1
  98. package/dist/query/client.d.ts +5 -2
  99. package/dist/query/client.js +10 -9
  100. package/dist/query/types.d.ts +6 -41
  101. package/dist/query/types.js +2 -2
  102. package/dist/react/AbloProvider.d.ts +18 -8
  103. package/dist/react/AbloProvider.js +10 -9
  104. package/dist/react/context.d.ts +3 -3
  105. package/dist/react/context.js +1 -1
  106. package/dist/react/createAbloReact.d.ts +56 -0
  107. package/dist/react/createAbloReact.js +51 -0
  108. package/dist/react/index.d.ts +6 -5
  109. package/dist/react/index.js +6 -3
  110. package/dist/react/internalContext.d.ts +1 -1
  111. package/dist/react/useAblo.d.ts +12 -5
  112. package/dist/react/useAblo.js +26 -8
  113. package/dist/react/useCurrentUserId.js +1 -1
  114. package/dist/react/useErrorListener.js +1 -1
  115. package/dist/react/useMutationFailureListener.d.ts +2 -2
  116. package/dist/react/useMutationFailureListener.js +1 -1
  117. package/dist/react/useMutators.d.ts +3 -3
  118. package/dist/react/useMutators.js +3 -3
  119. package/dist/react/useUndoScope.d.ts +5 -5
  120. package/dist/react/useUndoScope.js +1 -1
  121. package/dist/schema/coordination.d.ts +69 -10
  122. package/dist/schema/coordination.js +90 -9
  123. package/dist/schema/ddl.js +2 -2
  124. package/dist/schema/diff.d.ts +1 -1
  125. package/dist/schema/generate.js +1 -1
  126. package/dist/schema/index.d.ts +11 -10
  127. package/dist/schema/index.js +22 -18
  128. package/dist/schema/queries.d.ts +27 -27
  129. package/dist/schema/queries.js +23 -23
  130. package/dist/schema/select.d.ts +3 -3
  131. package/dist/schema/select.js +6 -3
  132. package/dist/schema/serialize.d.ts +15 -6
  133. package/dist/schema/serialize.js +20 -3
  134. package/dist/schema/sugar.d.ts +6 -7
  135. package/dist/schema/sugar.js +9 -12
  136. package/dist/schema/syncDeltaRow.d.ts +4 -152
  137. package/dist/schema/syncDeltaRow.js +4 -105
  138. package/dist/server/adapter.d.ts +18 -1
  139. package/dist/server/commit.d.ts +10 -16
  140. package/dist/server/index.d.ts +1 -1
  141. package/dist/server/index.js +1 -1
  142. package/dist/server/readConfig.d.ts +1 -1
  143. package/dist/source/adapter.d.ts +7 -5
  144. package/dist/source/adapter.js +7 -5
  145. package/dist/source/adapters/drizzle.d.ts +1 -1
  146. package/dist/source/adapters/drizzle.js +2 -2
  147. package/dist/source/adapters/kysely.d.ts +1 -1
  148. package/dist/source/adapters/kysely.js +1 -1
  149. package/dist/source/adapters/kyselyMutationCore.d.ts +1 -1
  150. package/dist/source/adapters/kyselyMutationCore.js +2 -2
  151. package/dist/source/adapters/memory.js +1 -1
  152. package/dist/source/adapters/prisma.d.ts +8 -3
  153. package/dist/source/adapters/prisma.js +1 -1
  154. package/dist/source/connector.js +1 -1
  155. package/dist/source/connectorProtocol.d.ts +2 -8
  156. package/dist/source/connectorProtocol.js +3 -2
  157. package/dist/source/contract.d.ts +29 -17
  158. package/dist/source/contract.js +27 -22
  159. package/dist/source/factory.d.ts +1 -1
  160. package/dist/source/idempotency.js +2 -2
  161. package/dist/source/index.d.ts +1 -0
  162. package/dist/source/index.js +3 -0
  163. package/dist/source/next.d.ts +1 -1
  164. package/dist/source/signing.d.ts +9 -2
  165. package/dist/source/signing.js +4 -1
  166. package/dist/source/types.d.ts +6 -4
  167. package/dist/source/types.js +1 -1
  168. package/dist/{core/storeContract.d.ts → storeContract.d.ts} +6 -6
  169. package/dist/{core → stores}/DatabaseManager.d.ts +3 -1
  170. package/dist/{core → stores}/DatabaseManager.js +14 -13
  171. package/dist/stores/ObjectStore.d.ts +1 -1
  172. package/dist/{core → stores}/StoreManager.d.ts +9 -26
  173. package/dist/{core → stores}/StoreManager.js +29 -77
  174. package/dist/stores/SyncActionStore.d.ts +4 -2
  175. package/dist/stores/SyncActionStore.js +11 -17
  176. package/dist/stores/syncAction.d.ts +26 -0
  177. package/dist/stores/syncAction.js +16 -0
  178. package/dist/surface.d.ts +3 -3
  179. package/dist/surface.js +6 -4
  180. package/dist/sync/BootstrapFetcher.d.ts +127 -6
  181. package/dist/sync/BootstrapFetcher.js +511 -83
  182. package/dist/sync/ConnectionManager.d.ts +6 -198
  183. package/dist/sync/ConnectionManager.js +6 -677
  184. package/dist/sync/OnDemandLoader.d.ts +5 -2
  185. package/dist/sync/OnDemandLoader.js +61 -21
  186. package/dist/sync/SubscriptionManager.d.ts +13 -2
  187. package/dist/sync/SubscriptionManager.js +23 -5
  188. package/dist/sync/SyncWebSocket.d.ts +27 -510
  189. package/dist/sync/SyncWebSocket.js +76 -954
  190. package/dist/sync/awaitClaimGrant.d.ts +4 -44
  191. package/dist/sync/awaitClaimGrant.js +4 -109
  192. package/dist/sync/bootstrapApply.d.ts +3 -0
  193. package/dist/sync/bootstrapApply.js +2 -2
  194. package/dist/sync/commitFrames.d.ts +6 -40
  195. package/dist/sync/commitFrames.js +6 -97
  196. package/dist/sync/contextPorts.d.ts +18 -0
  197. package/dist/sync/contextPorts.js +31 -0
  198. package/dist/sync/createClaimStream.d.ts +5 -49
  199. package/dist/sync/createClaimStream.js +5 -469
  200. package/dist/sync/createPresenceStream.d.ts +26 -4
  201. package/dist/sync/createPresenceStream.js +28 -20
  202. package/dist/sync/createSnapshot.d.ts +2 -2
  203. package/dist/sync/createSnapshot.js +1 -1
  204. package/dist/sync/credentialLifecycle.d.ts +5 -173
  205. package/dist/sync/credentialLifecycle.js +5 -320
  206. package/dist/sync/deltaPipeline.d.ts +13 -12
  207. package/dist/sync/deltaPipeline.js +21 -4
  208. package/dist/sync/groupChange.d.ts +3 -0
  209. package/dist/sync/groupChange.js +16 -14
  210. package/dist/sync/participants.d.ts +24 -6
  211. package/dist/sync/participants.js +32 -23
  212. package/dist/sync/schemaDrift.d.ts +55 -0
  213. package/dist/sync/schemaDrift.js +53 -0
  214. package/dist/sync/schemas.d.ts +23 -33
  215. package/dist/sync/schemas.js +29 -20
  216. package/dist/sync/syncPlan.d.ts +3 -3
  217. package/dist/sync/wsFrameHandlers.d.ts +6 -114
  218. package/dist/sync/wsFrameHandlers.js +6 -392
  219. package/dist/syncLog/contract.d.ts +20 -0
  220. package/dist/syncLog/contract.js +19 -0
  221. package/dist/syncLog/index.d.ts +1 -0
  222. package/dist/syncLog/index.js +1 -0
  223. package/dist/transaction/ablo.d.ts +88 -0
  224. package/dist/transaction/ablo.js +33 -0
  225. package/dist/{client/auth.d.ts → transaction/auth/apiKey.d.ts} +43 -8
  226. package/dist/{client/auth.js → transaction/auth/apiKey.js} +19 -0
  227. package/dist/transaction/auth/bootstrapScope.d.ts +15 -0
  228. package/dist/transaction/auth/bootstrapScope.js +1 -0
  229. package/dist/transaction/auth/capability.d.ts +212 -0
  230. package/dist/transaction/auth/capability.js +224 -0
  231. package/dist/{auth → transaction/auth}/credentialSource.d.ts +8 -1
  232. package/dist/{client → transaction/auth}/identity.d.ts +8 -7
  233. package/dist/{client → transaction/auth}/identity.js +1 -1
  234. package/dist/transaction/auth/index.d.ts +162 -0
  235. package/dist/transaction/auth/index.js +304 -0
  236. package/dist/{auth → transaction/auth}/schemas.d.ts +1 -1
  237. package/dist/{auth → transaction/auth}/schemas.js +13 -13
  238. package/dist/{client → transaction/auth}/sessionMint.d.ts +8 -8
  239. package/dist/{client → transaction/auth}/sessionMint.js +4 -7
  240. package/dist/transaction/coordination/awaitClaimGrant.d.ts +56 -0
  241. package/dist/transaction/coordination/awaitClaimGrant.js +124 -0
  242. package/dist/{client → transaction/coordination}/claimHeartbeatLoop.d.ts +34 -0
  243. package/dist/{client → transaction/coordination}/claimHeartbeatLoop.js +20 -0
  244. package/dist/transaction/coordination/claimMeta.d.ts +49 -0
  245. package/dist/transaction/coordination/claimMeta.js +52 -0
  246. package/dist/transaction/coordination/createClaimStream.d.ts +64 -0
  247. package/dist/transaction/coordination/createClaimStream.js +475 -0
  248. package/dist/transaction/coordination/events.d.ts +74 -0
  249. package/dist/transaction/coordination/events.js +7 -0
  250. package/dist/transaction/coordination/index.d.ts +19 -0
  251. package/dist/transaction/coordination/index.js +45 -0
  252. package/dist/transaction/coordination/locator.d.ts +104 -0
  253. package/dist/transaction/coordination/locator.js +102 -0
  254. package/dist/transaction/coordination/schema.d.ts +1536 -0
  255. package/dist/transaction/coordination/schema.js +1177 -0
  256. package/dist/transaction/coordination/targetConflict.d.ts +2 -0
  257. package/dist/transaction/coordination/targetConflict.js +107 -0
  258. package/dist/{coordination → transaction/coordination}/trace.d.ts +7 -18
  259. package/dist/{coordination → transaction/coordination}/trace.js +18 -25
  260. package/dist/transaction/durableWrites.d.ts +62 -0
  261. package/dist/{client → transaction}/durableWrites.js +28 -3
  262. package/dist/transaction/environment.d.ts +105 -0
  263. package/dist/transaction/environment.js +108 -0
  264. package/dist/{errorCodes.d.ts → transaction/errorCodes.d.ts} +12 -12
  265. package/dist/{errorCodes.js → transaction/errorCodes.js} +45 -18
  266. package/dist/{errors.d.ts → transaction/errors.d.ts} +37 -13
  267. package/dist/{errors.js → transaction/errors.js} +85 -16
  268. package/dist/transaction/footprint.d.ts +111 -0
  269. package/dist/transaction/footprint.js +0 -0
  270. package/dist/transaction/index.d.ts +20 -0
  271. package/dist/transaction/index.js +20 -0
  272. package/dist/transaction/keys/index.d.ts +87 -0
  273. package/dist/transaction/keys/index.js +207 -0
  274. package/dist/transaction/log/syncDeltaRow.d.ts +158 -0
  275. package/dist/transaction/log/syncDeltaRow.js +95 -0
  276. package/dist/{sync/syncPosition.d.ts → transaction/logPosition.d.ts} +22 -8
  277. package/dist/{sync/syncPosition.js → transaction/logPosition.js} +15 -6
  278. package/dist/transaction/logger.d.ts +16 -0
  279. package/dist/transaction/logger.js +7 -0
  280. package/dist/transaction/observability.d.ts +53 -0
  281. package/dist/transaction/observability.js +19 -0
  282. package/dist/transaction/plugin.d.ts +285 -0
  283. package/dist/transaction/plugin.js +106 -0
  284. package/dist/{policy → transaction/policy}/types.d.ts +3 -3
  285. package/dist/{policy → transaction/policy}/types.js +2 -0
  286. package/dist/transaction/resources/httpResources.d.ts +321 -0
  287. package/dist/transaction/resources/httpResources.js +7 -0
  288. package/dist/transaction/resources/modelOperations.d.ts +427 -0
  289. package/dist/transaction/resources/modelOperations.js +12 -0
  290. package/dist/transaction/resources/mutationOptions.d.ts +66 -0
  291. package/dist/transaction/resources/mutationOptions.js +9 -0
  292. package/dist/transaction/resources/where.d.ts +101 -0
  293. package/dist/transaction/resources/where.js +115 -0
  294. package/dist/{client → transaction/resources}/writeOptionsSchema.d.ts +2 -6
  295. package/dist/{client → transaction/resources}/writeOptionsSchema.js +9 -5
  296. package/dist/{schema → transaction/schema}/field.d.ts +17 -23
  297. package/dist/{schema → transaction/schema}/field.js +5 -5
  298. package/dist/transaction/schema/fieldRef.d.ts +38 -0
  299. package/dist/transaction/schema/fieldRef.js +11 -0
  300. package/dist/transaction/schema/loadStrategy.d.ts +45 -0
  301. package/dist/transaction/schema/loadStrategy.js +46 -0
  302. package/dist/{schema → transaction/schema}/model.d.ts +50 -35
  303. package/dist/{schema → transaction/schema}/model.js +30 -20
  304. package/dist/transaction/schema/openapi.d.ts +58 -0
  305. package/dist/transaction/schema/openapi.js +501 -0
  306. package/dist/{schema → transaction/schema}/relation.d.ts +21 -16
  307. package/dist/{schema → transaction/schema}/relation.js +7 -7
  308. package/dist/{schema → transaction/schema}/residency.d.ts +0 -9
  309. package/dist/{schema → transaction/schema}/residency.js +0 -5
  310. package/dist/{schema → transaction/schema}/roles.d.ts +5 -5
  311. package/dist/{schema → transaction/schema}/roles.js +5 -5
  312. package/dist/{schema → transaction/schema}/schema.d.ts +39 -10
  313. package/dist/{schema → transaction/schema}/schema.js +24 -3
  314. package/dist/{schema → transaction/schema}/tenancy.d.ts +1 -1
  315. package/dist/{schema → transaction/schema}/tenancy.js +7 -4
  316. package/dist/transaction/transactionLayer.d.ts +82 -0
  317. package/dist/transaction/transactionLayer.js +24 -0
  318. package/dist/{transactions → transaction/transactions/settlement}/commitEnvelope.d.ts +5 -6
  319. package/dist/{transactions → transaction/transactions/settlement}/commitEnvelope.js +9 -13
  320. package/dist/{transactions → transaction/transactions/settlement}/httpCommitEnvelope.d.ts +9 -2
  321. package/dist/{transactions → transaction/transactions/settlement}/httpCommitEnvelope.js +5 -9
  322. package/dist/{transactions/durableWriteStore.d.ts → transaction/transactions/settlement/pendingWrite.d.ts} +11 -37
  323. package/dist/transaction/transactions/settlement/pendingWrite.js +20 -0
  324. package/dist/transaction/transport/commitFrames.d.ts +90 -0
  325. package/dist/transaction/transport/commitFrames.js +134 -0
  326. package/dist/transaction/transport/connectionManager.d.ts +215 -0
  327. package/dist/transaction/transport/connectionManager.js +673 -0
  328. package/dist/transaction/transport/credentialLifecycle.d.ts +177 -0
  329. package/dist/transaction/transport/credentialLifecycle.js +324 -0
  330. package/dist/{sync → transaction/transport}/heartbeat.d.ts +3 -1
  331. package/dist/{sync → transaction/transport}/heartbeat.js +6 -4
  332. package/dist/transaction/transport/httpClient.d.ts +131 -0
  333. package/dist/{client → transaction/transport}/httpClient.js +6 -5
  334. package/dist/transaction/transport/httpOptions.d.ts +33 -0
  335. package/dist/transaction/transport/httpOptions.js +12 -0
  336. package/dist/{client → transaction/transport}/httpTransport.js +295 -97
  337. package/dist/{sync/NetworkProbe.d.ts → transaction/transport/networkProbe.d.ts} +7 -4
  338. package/dist/{sync/NetworkProbe.js → transaction/transport/networkProbe.js} +14 -13
  339. package/dist/transaction/transport/wsFrameHandlers.d.ts +128 -0
  340. package/dist/transaction/transport/wsFrameHandlers.js +429 -0
  341. package/dist/transaction/transport/wsTransport.d.ts +574 -0
  342. package/dist/transaction/transport/wsTransport.js +1023 -0
  343. package/dist/transaction/types/assertExact.d.ts +17 -0
  344. package/dist/transaction/types/assertExact.js +1 -0
  345. package/dist/{types → transaction/types}/global.d.ts +17 -2
  346. package/dist/{types → transaction/types}/global.js +2 -1
  347. package/dist/{types → transaction/types}/index.d.ts +14 -46
  348. package/dist/{types → transaction/types}/index.js +7 -16
  349. package/dist/{types → transaction/types}/streams.d.ts +73 -45
  350. package/dist/transaction/utils/duration.d.ts +50 -0
  351. package/dist/{utils → transaction/utils}/duration.js +32 -0
  352. package/dist/{utils → transaction/utils}/json.d.ts +18 -0
  353. package/dist/transaction/utils/json.js +276 -0
  354. package/dist/transaction/wire/accountResponses.d.ts +420 -0
  355. package/dist/transaction/wire/accountResponses.js +290 -0
  356. package/dist/transaction/wire/auth.d.ts +56 -0
  357. package/dist/transaction/wire/auth.js +63 -0
  358. package/dist/transaction/wire/claimEvent.d.ts +76 -0
  359. package/dist/transaction/wire/claimEvent.js +73 -0
  360. package/dist/transaction/wire/claims.d.ts +530 -0
  361. package/dist/transaction/wire/claims.js +327 -0
  362. package/dist/{wire → transaction/wire}/commit.d.ts +125 -193
  363. package/dist/{wire → transaction/wire}/commit.js +68 -47
  364. package/dist/{wire → transaction/wire}/delta.d.ts +66 -17
  365. package/dist/{wire → transaction/wire}/delta.js +37 -13
  366. package/dist/transaction/wire/errorEnvelope.d.ts +72 -0
  367. package/dist/{wire → transaction/wire}/errorEnvelope.js +36 -5
  368. package/dist/transaction/wire/feedCursor.d.ts +60 -0
  369. package/dist/transaction/wire/feedCursor.js +82 -0
  370. package/dist/transaction/wire/feedEvent.d.ts +204 -0
  371. package/dist/transaction/wire/feedEvent.js +65 -0
  372. package/dist/transaction/wire/frames.d.ts +194 -0
  373. package/dist/transaction/wire/frames.js +50 -0
  374. package/dist/transaction/wire/inboundFrames.d.ts +562 -0
  375. package/dist/transaction/wire/inboundFrames.js +116 -0
  376. package/dist/transaction/wire/index.d.ts +54 -0
  377. package/dist/transaction/wire/index.js +83 -0
  378. package/dist/{wire → transaction/wire}/listEnvelope.d.ts +13 -14
  379. package/dist/transaction/wire/listEnvelope.js +42 -0
  380. package/dist/transaction/wire/modelMutations.d.ts +31 -0
  381. package/dist/transaction/wire/modelMutations.js +52 -0
  382. package/dist/transaction/wire/modelResponses.d.ts +85 -0
  383. package/dist/transaction/wire/modelResponses.js +43 -0
  384. package/dist/transaction/wire/modelShape.d.ts +78 -0
  385. package/dist/transaction/wire/modelShape.js +74 -0
  386. package/dist/transactions/{TransactionQueue.d.ts → mutations/MutationQueue.d.ts} +85 -38
  387. package/dist/transactions/{TransactionQueue.js → mutations/MutationQueue.js} +141 -80
  388. package/dist/transactions/{TransactionStore.d.ts → mutations/MutationStore.d.ts} +8 -8
  389. package/dist/transactions/{TransactionStore.js → mutations/MutationStore.js} +2 -2
  390. package/dist/transactions/{coalesceRules.d.ts → mutations/coalesceRules.d.ts} +10 -10
  391. package/dist/transactions/{coalesceRules.js → mutations/coalesceRules.js} +1 -1
  392. package/dist/transactions/mutations/commitLatency.d.ts +52 -0
  393. package/dist/transactions/mutations/commitLatency.js +130 -0
  394. package/dist/transactions/{commitOutboxStore.d.ts → mutations/commitOutboxStore.d.ts} +1 -5
  395. package/dist/transactions/{commitOutboxStore.js → mutations/commitOutboxStore.js} +1 -1
  396. package/dist/transactions/{commitPayload.d.ts → mutations/commitPayload.d.ts} +18 -16
  397. package/dist/transactions/{commitPayload.js → mutations/commitPayload.js} +15 -15
  398. package/dist/transactions/{deltaConfirmation.d.ts → mutations/deltaConfirmation.d.ts} +15 -11
  399. package/dist/transactions/{deltaConfirmation.js → mutations/deltaConfirmation.js} +14 -12
  400. package/dist/transactions/mutations/durableWriteStore.d.ts +14 -0
  401. package/dist/transactions/mutations/durableWriteStore.js +12 -0
  402. package/dist/transactions/{optimisticApply.d.ts → mutations/optimisticApply.d.ts} +7 -7
  403. package/dist/transactions/{replayValidation.d.ts → mutations/replayValidation.d.ts} +4 -3
  404. package/dist/transactions/{replayValidation.js → mutations/replayValidation.js} +7 -5
  405. package/dist/utils/mobxSetup.d.ts +1 -1
  406. package/dist/utils/mobxSetup.js +5 -2
  407. package/dist/{core → views}/QueryView.d.ts +2 -2
  408. package/dist/{core → views}/QueryView.js +2 -2
  409. package/dist/{core → views}/ViewRegistry.d.ts +1 -1
  410. package/dist/{core/queryUtils.d.ts → views/incrementalView.d.ts} +6 -6
  411. package/dist/{core/queryUtils.js → views/incrementalView.js} +6 -6
  412. package/dist/webhooks/events.d.ts +2 -2
  413. package/dist/wire/index.d.ts +1 -34
  414. package/dist/wire/index.js +8 -49
  415. package/docs/agent-messaging.md +3 -3
  416. package/docs/agents.md +20 -13
  417. package/docs/api-keys.md +14 -10
  418. package/docs/api.md +27 -61
  419. package/docs/audit.md +6 -3
  420. package/docs/cli.md +41 -13
  421. package/docs/client-behavior.md +11 -9
  422. package/docs/concurrency-convention.md +49 -57
  423. package/docs/coordination.md +283 -121
  424. package/docs/data-sources.md +7 -5
  425. package/docs/debugging.md +39 -15
  426. package/docs/deployment.md +267 -0
  427. package/docs/examples/agent-human.md +49 -42
  428. package/docs/examples/ai-sdk-tool.md +69 -44
  429. package/docs/examples/existing-python-backend.md +8 -6
  430. package/docs/examples/nextjs.md +129 -47
  431. package/docs/examples/scoped-agent.md +46 -45
  432. package/docs/examples/server-agent.md +46 -26
  433. package/docs/groups.md +87 -30
  434. package/docs/guarantees.md +41 -12
  435. package/docs/how-it-works.md +38 -12
  436. package/docs/idempotency.md +126 -0
  437. package/docs/identity.md +77 -74
  438. package/docs/index.md +172 -86
  439. package/docs/integration-guide.md +31 -19
  440. package/docs/mcp.md +46 -21
  441. package/docs/migration.md +95 -18
  442. package/docs/operating-on-your-database.md +3 -1
  443. package/docs/projects.md +3 -1
  444. package/docs/quickstart.md +22 -5
  445. package/docs/react.md +31 -18
  446. package/docs/schema-contract.md +5 -3
  447. package/docs/session-settings.md +108 -0
  448. package/docs/sessions.md +4 -2
  449. package/docs/webhooks.md +12 -10
  450. package/llms.txt +48 -18
  451. package/package.json +21 -26
  452. package/dist/agent/Agent.d.ts +0 -366
  453. package/dist/agent/Agent.js +0 -514
  454. package/dist/agent/index.d.ts +0 -115
  455. package/dist/agent/index.js +0 -128
  456. package/dist/agent/session.d.ts +0 -93
  457. package/dist/agent/session.js +0 -149
  458. package/dist/agent/types.d.ts +0 -68
  459. package/dist/agent/types.js +0 -9
  460. package/dist/cli.cjs +0 -286329
  461. package/dist/client/durableWrites.d.ts +0 -21
  462. package/dist/client/httpClient.d.ts +0 -80
  463. package/dist/coordination/schema.d.ts +0 -722
  464. package/dist/coordination/schema.js +0 -578
  465. package/dist/schema/openapi.d.ts +0 -29
  466. package/dist/schema/openapi.js +0 -124
  467. package/dist/testing/fixtures/bootstrap.d.ts +0 -49
  468. package/dist/testing/fixtures/bootstrap.js +0 -59
  469. package/dist/testing/fixtures/deltas.d.ts +0 -83
  470. package/dist/testing/fixtures/deltas.js +0 -136
  471. package/dist/testing/fixtures/models.d.ts +0 -83
  472. package/dist/testing/fixtures/models.js +0 -272
  473. package/dist/testing/helpers/reactWrapper.d.ts +0 -69
  474. package/dist/testing/helpers/reactWrapper.js +0 -67
  475. package/dist/testing/helpers/syncEngineHarness.d.ts +0 -54
  476. package/dist/testing/helpers/syncEngineHarness.js +0 -73
  477. package/dist/testing/helpers/wait.d.ts +0 -30
  478. package/dist/testing/helpers/wait.js +0 -49
  479. package/dist/testing/index.d.ts +0 -23
  480. package/dist/testing/index.js +0 -33
  481. package/dist/testing/mocks/FakeDatabase.d.ts +0 -18
  482. package/dist/testing/mocks/FakeDatabase.js +0 -10
  483. package/dist/testing/mocks/MockMutationExecutor.d.ts +0 -87
  484. package/dist/testing/mocks/MockMutationExecutor.js +0 -192
  485. package/dist/testing/mocks/MockNetworkMonitor.d.ts +0 -20
  486. package/dist/testing/mocks/MockNetworkMonitor.js +0 -46
  487. package/dist/testing/mocks/MockSyncContext.d.ts +0 -51
  488. package/dist/testing/mocks/MockSyncContext.js +0 -71
  489. package/dist/testing/mocks/MockSyncStore.d.ts +0 -88
  490. package/dist/testing/mocks/MockSyncStore.js +0 -171
  491. package/dist/testing/mocks/MockWebSocket.d.ts +0 -71
  492. package/dist/testing/mocks/MockWebSocket.js +0 -118
  493. package/dist/transactions/durableWriteStore.js +0 -30
  494. package/dist/utils/duration.d.ts +0 -25
  495. package/dist/utils/json.js +0 -88
  496. package/dist/wire/errorEnvelope.d.ts +0 -55
  497. package/dist/wire/frames.d.ts +0 -197
  498. package/dist/wire/frames.js +0 -49
  499. package/dist/wire/listEnvelope.js +0 -18
  500. package/docs/interaction-model.md +0 -97
  501. /package/dist/{core → query}/QueryProcessor.d.ts +0 -0
  502. /package/dist/{core → query}/QueryProcessor.js +0 -0
  503. /package/dist/{core/storeContract.js → storeContract.js} +0 -0
  504. /package/dist/{core → stores}/openIDBWithTimeout.d.ts +0 -0
  505. /package/dist/{core → stores}/openIDBWithTimeout.js +0 -0
  506. /package/dist/{client → transaction/auth}/credentialEndpoint.d.ts +0 -0
  507. /package/dist/{client → transaction/auth}/credentialEndpoint.js +0 -0
  508. /package/dist/{auth → transaction/auth}/credentialPolicy.d.ts +0 -0
  509. /package/dist/{auth → transaction/auth}/credentialPolicy.js +0 -0
  510. /package/dist/{auth → transaction/auth}/credentialSource.js +0 -0
  511. /package/dist/{client → transaction/auth}/hostedEndpoints.d.ts +0 -0
  512. /package/dist/{client → transaction/auth}/hostedEndpoints.js +0 -0
  513. /package/dist/{client → transaction}/persistence.d.ts +0 -0
  514. /package/dist/{client → transaction}/persistence.js +0 -0
  515. /package/dist/{client → transaction/resources}/functionalUpdate.d.ts +0 -0
  516. /package/dist/{client → transaction/resources}/functionalUpdate.js +0 -0
  517. /package/dist/{transactions → transaction/transactions/settlement}/idempotencyKey.d.ts +0 -0
  518. /package/dist/{transactions → transaction/transactions/settlement}/idempotencyKey.js +0 -0
  519. /package/dist/{client → transaction/transport}/httpTransport.d.ts +0 -0
  520. /package/dist/{types → transaction/types}/modelData.d.ts +0 -0
  521. /package/dist/{types → transaction/types}/modelData.js +0 -0
  522. /package/dist/{types → transaction/types}/participant.d.ts +0 -0
  523. /package/dist/{types → transaction/types}/participant.js +0 -0
  524. /package/dist/{types → transaction/types}/streams.js +0 -0
  525. /package/dist/{utils → transaction/utils}/asyncIterator.d.ts +0 -0
  526. /package/dist/{utils → transaction/utils}/asyncIterator.js +0 -0
  527. /package/dist/{wire → transaction/wire}/bootstrapReason.d.ts +0 -0
  528. /package/dist/{wire → transaction/wire}/bootstrapReason.js +0 -0
  529. /package/dist/{wire → transaction/wire}/protocol.d.ts +0 -0
  530. /package/dist/{wire → transaction/wire}/protocol.js +0 -0
  531. /package/dist/{wire → transaction/wire}/protocolVersion.d.ts +0 -0
  532. /package/dist/{wire → transaction/wire}/protocolVersion.js +0 -0
  533. /package/dist/transactions/{UnconfirmedWrites.d.ts → mutations/UnconfirmedWrites.d.ts} +0 -0
  534. /package/dist/transactions/{UnconfirmedWrites.js → mutations/UnconfirmedWrites.js} +0 -0
  535. /package/dist/transactions/{optimisticApply.js → mutations/optimisticApply.js} +0 -0
  536. /package/dist/{core → views}/ViewRegistry.js +0 -0
package/dist/Database.js CHANGED
@@ -5,14 +5,14 @@
5
5
  * server. {@link BaseSyncedStore} drives it, and {@link InstanceCache} holds the
6
6
  * in-memory mirror of what this class persists.
7
7
  */
8
- import { DatabaseManager } from './core/DatabaseManager.js';
9
- import { StoreManager } from './core/StoreManager.js';
8
+ import { DatabaseManager } from './stores/DatabaseManager.js';
9
+ import { StoreManager } from './stores/StoreManager.js';
10
10
  import { ModelRegistry } from './ModelRegistry.js';
11
- import { LoadStrategy } from './types/index.js';
12
- import { getContext } from './context.js';
13
- import { AbloConnectionError, AbloValidationError } from './errors.js';
11
+ import { LoadStrategy } from './transaction/types/index.js';
12
+ import { globalRuntime } from './context.js';
13
+ import { AbloConnectionError, AbloValidationError } from './transaction/errors.js';
14
14
  import { InMemoryObjectStore } from './adapters/inMemoryStorage.js';
15
- import { syncPositionSchema } from './sync/syncPosition.js';
15
+ import { logPositionSchema } from './transaction/logPosition.js';
16
16
  import { highestPersistedPrefixSyncId } from './sync/persistedPrefix.js';
17
17
  /**
18
18
  * Request identity excludes local timing metadata for re-entrant seals: a
@@ -110,7 +110,7 @@ export class Database {
110
110
  /** Essential fields that must be preserved during partial UPDATE merges.
111
111
  * Sourced from SyncEngineConfig.essentialFields — consumers define their own. */
112
112
  get essentialFields() {
113
- return getContext().config.essentialFields;
113
+ return this.runtime.config.essentialFields;
114
114
  }
115
115
  /**
116
116
  * When true, all IndexedDB operations are replaced with in-memory Maps.
@@ -121,13 +121,15 @@ export class Database {
121
121
  * new Database(registry, bootstrap, { inMemory: true })
122
122
  */
123
123
  inMemory;
124
+ runtime;
124
125
  /** In-memory stores used when inMemory=true. Keyed by model name. */
125
126
  inMemoryStores = new Map();
126
127
  /** In-memory workspace metadata when inMemory=true. */
127
128
  inMemoryMetadata = null;
128
129
  constructor(modelRegistry, bootstrapHelper, options) {
129
- this.databaseManager = new DatabaseManager();
130
- this.storeManager = new StoreManager(modelRegistry);
130
+ this.runtime = options?.runtime ?? globalRuntime;
131
+ this.databaseManager = new DatabaseManager(this.runtime);
132
+ this.storeManager = new StoreManager(modelRegistry, this.runtime);
131
133
  this.modelRegistry = modelRegistry;
132
134
  this.bootstrapHelper = bootstrapHelper;
133
135
  this.inMemory = options?.inMemory ?? false;
@@ -149,7 +151,7 @@ export class Database {
149
151
  ? this.inMemoryStores.get(modelName)
150
152
  : this.storeManager.getStore(modelName);
151
153
  if (!store && context) {
152
- getContext().observability.breadcrumb(`Store not found for model: ${modelName}`, 'sync.database', 'warning', { context });
154
+ this.runtime.observability.breadcrumb(`Store not found for model: ${modelName}`, 'sync.database', 'warning', { context });
153
155
  }
154
156
  return store;
155
157
  }
@@ -170,7 +172,7 @@ export class Database {
170
172
  const requiredFields = this.essentialFields[modelName] ?? [];
171
173
  const preserved = requiredFields.filter((field) => existing[field] !== undefined && delta[field] === undefined);
172
174
  if (preserved.length > 0) {
173
- getContext().logger.debug('[Database] UPDATE merged - preserved fields', {
175
+ this.runtime.logger.debug('[Database] UPDATE merged - preserved fields', {
174
176
  modelName,
175
177
  modelId: modelId.slice(0, 12),
176
178
  deltaFields: Object.keys(delta),
@@ -188,7 +190,7 @@ export class Database {
188
190
  // Creates InMemoryObjectStore instances for all registered models.
189
191
  // Bootstrap via HTTP still works; only local persistence is skipped.
190
192
  if (this.inMemory) {
191
- getContext().logger.debug('Opening in-memory database (headless mode)');
193
+ this.runtime.logger.debug('Opening in-memory database (headless mode)');
192
194
  const allModels = this.modelRegistry.getRegisteredModelNames();
193
195
  for (const modelName of allModels) {
194
196
  const storeName = `store_${modelName.toLowerCase()}`;
@@ -196,11 +198,11 @@ export class Database {
196
198
  }
197
199
  // Create a __transactions store for the offline queue
198
200
  this.inMemoryStores.set('__transactions', new InMemoryObjectStore('__transactions', '__transactions'));
199
- getContext().logger.info(`In-memory database opened: ${this.inMemoryStores.size} stores`);
201
+ this.runtime.logger.info(`In-memory database opened: ${this.inMemoryStores.size} stores`);
200
202
  return;
201
203
  }
202
204
  // ── Browser mode: IndexedDB (existing behavior, unchanged) ───
203
- getContext().logger.debug('Opening IndexedDB database');
205
+ this.runtime.logger.debug('Opening IndexedDB database');
204
206
  // Initialize meta database
205
207
  await this.databaseManager.initializeMetaDatabase();
206
208
  // Calculate database info
@@ -208,13 +210,13 @@ export class Database {
208
210
  // Register database
209
211
  await this.databaseManager.registerDatabase(this.currentDbInfo);
210
212
  // Open workspace database
211
- this.workspaceDb = await this.databaseManager.openWorkspaceDatabase(this.currentDbInfo, async (db, tx) => {
212
- await this.storeManager.createStores(db, tx);
213
+ this.workspaceDb = await this.databaseManager.openWorkspaceDatabase(this.currentDbInfo, async (db) => {
214
+ await this.storeManager.createStores(db);
213
215
  });
214
216
  // Initialize stores
215
217
  await this.storeManager.initializeStores(this.workspaceDb);
216
218
  const readiness = await this.storeManager.checkReadinessOfStores();
217
- getContext().logger.info(`Database opened: ${this.currentDbInfo.name} (${readiness.readyStores.length}/${readiness.totalStores} stores ready)`);
219
+ this.runtime.logger.info(`Database opened: ${this.currentDbInfo.name} (${readiness.readyStores.length}/${readiness.totalStores} stores ready)`);
218
220
  }
219
221
  /**
220
222
  * Shrink a record before persisting it. Drops `undefined` fields, empty
@@ -277,7 +279,7 @@ export class Database {
277
279
  */
278
280
  markRequiresFullBootstrap() {
279
281
  this._forceFullBootstrap = true;
280
- getContext().logger.info('[Database] Marked for forced full bootstrap (sync group change)');
282
+ this.runtime.logger.info('[Database] Marked for forced full bootstrap (sync group change)');
281
283
  }
282
284
  /**
283
285
  * Smart bootstrap requirements based on data freshness
@@ -309,7 +311,7 @@ export class Database {
309
311
  this._forceFullBootstrap = false;
310
312
  const instantModels = this.modelRegistry.getModelsByLoadStrategy(LoadStrategy.instant);
311
313
  const lazyModels = this.modelRegistry.getModelsByLoadStrategy(LoadStrategy.lazy);
312
- getContext().logger.info('[Database.requiredBootstrap] Forced FULL bootstrap (sync group change)');
314
+ this.runtime.logger.info('[Database.requiredBootstrap] Forced FULL bootstrap (sync group change)');
313
315
  return {
314
316
  type: 'full',
315
317
  modelsToLoad: [...instantModels, ...lazyModels],
@@ -328,7 +330,7 @@ export class Database {
328
330
  // (a corrupted negative/float cursor would previously pass `|| 0`,
329
331
  // which only catches falsy, and get sent to the server as the resume
330
332
  // point). Invalid → 0 → full bootstrap, the safe degradation.
331
- const metadataLastSyncId = syncPositionSchema.shape.persisted.safeParse(metadata?.lastSyncId).data ?? 0;
333
+ const metadataLastSyncId = logPositionSchema.shape.persisted.safeParse(metadata?.lastSyncId).data ?? 0;
332
334
  const dataAge = metadata?.updatedAt ? Date.now() - metadata.updatedAt.getTime() : Infinity;
333
335
  // ── Cache-validity check ─────────────────────────────────────
334
336
  //
@@ -348,7 +350,7 @@ export class Database {
348
350
  // we've confirmed the data it refers to actually exists in the stores.
349
351
  const lastSyncId = dataExists ? metadataLastSyncId : 0;
350
352
  // Log the resolved database state for diagnostics.
351
- getContext().logger.debug('[Database.requiredBootstrap] State check', {
353
+ this.runtime.logger.debug('[Database.requiredBootstrap] State check', {
352
354
  readinessReady: readiness.ready,
353
355
  hasMetadata: !!metadata,
354
356
  metadataLastSyncId,
@@ -365,13 +367,13 @@ export class Database {
365
367
  if (offline && hasLocalData) {
366
368
  // Offline with data - use local bootstrap (only option when offline)
367
369
  type = 'local';
368
- getContext().logger.info('Offline detected with local data - using local bootstrap');
370
+ this.runtime.logger.info('Offline detected with local data - using local bootstrap');
369
371
  }
370
372
  else {
371
373
  // The server is the source of truth: always use a full bootstrap
372
374
  // when online.
373
375
  type = 'full';
374
- getContext().logger.info('Full bootstrap - server is source of truth', {
376
+ this.runtime.logger.info('Full bootstrap - server is source of truth', {
375
377
  reason: offline ? 'offline_no_data' : 'server_authoritative',
376
378
  hasLocalData,
377
379
  lastSyncId,
@@ -396,12 +398,12 @@ export class Database {
396
398
  * shrinkage check. Caller supplies the complete list, not just
397
399
  * team-derived groups. */
398
400
  syncGroups, onProgress) {
399
- getContext().logger.debug('Starting bootstrap fetch', {
401
+ this.runtime.logger.debug('Starting bootstrap fetch', {
400
402
  type: requirements.type,
401
403
  lastSyncId: requirements.lastSyncId,
402
404
  modelsToLoad: requirements.modelsToLoad,
403
405
  });
404
- getContext().logger.info('Database: Starting bootstrap from Go server', {
406
+ this.runtime.logger.info('Database: Starting bootstrap from Go server', {
405
407
  type: requirements.type,
406
408
  syncGroups,
407
409
  modelsToLoad: requirements.modelsToLoad,
@@ -410,12 +412,12 @@ export class Database {
410
412
  // Fetch before any destructive operation, so a failed network
411
413
  // request can't leave the local store empty.
412
414
  const startTime = typeof performance !== 'undefined' ? performance.now() : Date.now();
413
- getContext().logger.info('Fetching bootstrap data from server (before clearing local data)', {
415
+ this.runtime.logger.info('Fetching bootstrap data from server (before clearing local data)', {
414
416
  type: requirements.type,
415
417
  lastSyncId: requirements.lastSyncId,
416
418
  });
417
419
  const bootstrapData = await this.bootstrapHelper.fetchBootstrap(requirements.lastSyncId);
418
- getContext().logger.debug('Received bootstrap response', {
420
+ this.runtime.logger.debug('Received bootstrap response', {
419
421
  type: bootstrapData.type,
420
422
  lastSyncId: bootstrapData.lastSyncId,
421
423
  hasModels: !!bootstrapData.models,
@@ -431,7 +433,7 @@ export class Database {
431
433
  // Handle partial bootstrap (delta batch)
432
434
  if (bootstrapData.type === 'partial') {
433
435
  const deltas = bootstrapData.deltas ?? [];
434
- getContext().logger.info('Processing partial bootstrap with delta batch', {
436
+ this.runtime.logger.info('Processing partial bootstrap with delta batch', {
435
437
  deltaCount: deltas.length,
436
438
  fromSyncId: requirements.lastSyncId,
437
439
  toSyncId: bootstrapData.lastSyncId,
@@ -444,13 +446,18 @@ export class Database {
444
446
  let deltasApplied = 0;
445
447
  let deltaResults;
446
448
  if (deltas.length > 0) {
447
- // Convert server delta format to processDelta format
449
+ // Narrow the wire delta to what processDelta reads. The field names
450
+ // are the wire's own — the only change is `id` becoming `syncId`.
451
+ // A group-change frame carries its payload as a JSON string, decoded
452
+ // here exactly as the live delta path does in BaseSyncedStore.
448
453
  const formattedDeltas = deltas.map((delta) => ({
449
454
  syncId: delta.id,
450
- actionType: delta.operation,
455
+ actionType: delta.actionType,
451
456
  modelName: delta.modelName,
452
- modelId: delta.entityId,
453
- data: delta.data,
457
+ modelId: delta.modelId,
458
+ data: typeof delta.data === 'string'
459
+ ? JSON.parse(delta.data)
460
+ : delta.data,
454
461
  }));
455
462
  // Use batch processing for better performance
456
463
  const batch = await this.processDeltaBatch(formattedDeltas);
@@ -466,7 +473,7 @@ export class Database {
466
473
  updatedAt: new Date(),
467
474
  });
468
475
  const elapsed = (typeof performance !== 'undefined' ? performance.now() : Date.now()) - startTime;
469
- getContext().logger.info(`Partial bootstrap complete in ${elapsed.toFixed(2)}ms`, {
476
+ this.runtime.logger.info(`Partial bootstrap complete in ${elapsed.toFixed(2)}ms`, {
470
477
  deltasApplied,
471
478
  lastSyncId: bootstrapData.lastSyncId,
472
479
  });
@@ -483,21 +490,21 @@ export class Database {
483
490
  for (const [modelName, modelData] of Object.entries(bootstrapData.models)) {
484
491
  // Handle null, undefined, or non-array data
485
492
  if (!modelData) {
486
- getContext().observability.breadcrumb(`No data received for ${modelName}`, 'sync.bootstrap', 'warning');
493
+ this.runtime.observability.breadcrumb(`No data received for ${modelName}`, 'sync.bootstrap', 'warning');
487
494
  continue;
488
495
  }
489
496
  if (!Array.isArray(modelData)) {
490
- getContext().observability.breadcrumb(`Skipping non-array data for ${modelName}`, 'sync.bootstrap', 'warning');
497
+ this.runtime.observability.breadcrumb(`Skipping non-array data for ${modelName}`, 'sync.bootstrap', 'warning');
491
498
  continue;
492
499
  }
493
500
  // Skip empty arrays silently (expected for some models)
494
501
  if (modelData.length === 0) {
495
- getContext().logger.debug(`No ${modelName} items to store (empty array)`);
502
+ this.runtime.logger.debug(`No ${modelName} items to store (empty array)`);
496
503
  continue;
497
504
  }
498
505
  const store = this.getStore(modelName, 'bootstrap');
499
506
  if (!store) {
500
- getContext().logger.debug(`[Bootstrap] NO IDB STORE for ${modelName} — ${modelData.length} items DROPPED`);
507
+ this.runtime.logger.debug(`[Bootstrap] NO IDB STORE for ${modelName} — ${modelData.length} items DROPPED`);
501
508
  continue;
502
509
  }
503
510
  let writeErrors = 0;
@@ -515,11 +522,18 @@ export class Database {
515
522
  }
516
523
  catch (error) {
517
524
  writeErrors++;
518
- getContext().observability.breadcrumb(`Failed to store ${modelName} item`, 'sync.database', 'error', {
525
+ this.runtime.observability.breadcrumb(`Failed to store ${modelName} item`, 'sync.database', 'error', {
519
526
  error: error instanceof Error ? error.message : String(error),
520
527
  });
521
528
  }
522
529
  }
530
+ // The model is marked persisted below whether or not every item landed,
531
+ // because a partial store is still what the next sync reconciles
532
+ // against. Counted and surfaced here so a partial does not read as a
533
+ // clean bootstrap.
534
+ if (writeErrors > 0) {
535
+ this.runtime.observability.breadcrumb(`Stored ${modelName} with ${writeErrors} of ${modelData.length} items dropped`, 'sync.database', 'warning');
536
+ }
523
537
  // Mark model as persisted after successful write
524
538
  try {
525
539
  await this.setModelPersisted(modelName, true);
@@ -536,8 +550,8 @@ export class Database {
536
550
  updatedAt: new Date(),
537
551
  });
538
552
  const elapsed = (typeof performance !== 'undefined' ? performance.now() : Date.now()) - startTime;
539
- getContext().logger.info(`Bootstrap complete: ${modelsLoaded} items loaded, ${modelsStored} stored to IndexedDB in ${elapsed.toFixed(2)}ms`);
540
- getContext().analytics?.capture('bootstrap_success', {
553
+ this.runtime.logger.info(`Bootstrap complete: ${modelsLoaded} items loaded, ${modelsStored} stored to IndexedDB in ${elapsed.toFixed(2)}ms`);
554
+ this.runtime.analytics?.capture('bootstrap_success', {
541
555
  responseTime: elapsed,
542
556
  modelsLoaded,
543
557
  });
@@ -545,12 +559,12 @@ export class Database {
545
559
  }
546
560
  catch (error) {
547
561
  // Comprehensive error logging for bootstrap failures
548
- getContext().observability.captureBootstrapFailure(error, {
562
+ this.runtime.observability.captureBootstrapFailure(error, {
549
563
  type: requirements.type,
550
564
  navigatorOnline: typeof navigator !== 'undefined' ? navigator.onLine : undefined,
551
565
  });
552
566
  // Track bootstrap failure telemetry
553
- getContext().analytics?.capture('bootstrap_failed', {
567
+ this.runtime.analytics?.capture('bootstrap_failed', {
554
568
  bootstrapType: requirements.type,
555
569
  lastSyncId: requirements.lastSyncId,
556
570
  errorMessage: error instanceof Error ? error.message : String(error),
@@ -569,7 +583,7 @@ export class Database {
569
583
  *
570
584
  * Update deltas carry only the changed fields, so they are merged onto the
571
585
  * existing record rather than replacing it. That preserves fields the delta
572
- * omits (such as deckId or title), and an explicit null is kept as a value,
586
+ * omits (such as reportId or title), and an explicit null is kept as a value,
573
587
  * clearing that field.
574
588
  */
575
589
  async processDelta(delta) {
@@ -605,7 +619,7 @@ export class Database {
605
619
  // newly created, it was newly visible. We fall through to the 'I' case
606
620
  // after a debug trace so the two can be disambiguated in logs.
607
621
  case 'C':
608
- getContext().observability.breadcrumb('Applying covering delta (gained permission)', 'sync.database', 'info', { modelName, modelId: modelId.slice(0, 12) });
622
+ this.runtime.observability.breadcrumb('Applying covering delta (gained permission)', 'sync.database', 'info', { modelName, modelId: modelId.slice(0, 12) });
609
623
  // falls through
610
624
  case 'I': {
611
625
  // Skip when the delta payload was empty/null. IDB rejects
@@ -623,7 +637,7 @@ export class Database {
623
637
  }
624
638
  }
625
639
  catch (err) {
626
- getContext().observability.breadcrumb(`IndexedDB put failed for ${modelName}:${modelId}`, 'sync.database', 'error', {
640
+ this.runtime.observability.breadcrumb(`IndexedDB put failed for ${modelName}:${modelId}`, 'sync.database', 'error', {
627
641
  error: err instanceof Error ? err.message : String(err),
628
642
  });
629
643
  throw err; // Re-throw to see the actual error
@@ -636,9 +650,9 @@ export class Database {
636
650
  const existing = await store.get(modelId);
637
651
  // Skip the update when there's no existing record to merge with:
638
652
  // building a record from partial update data would corrupt it
639
- // (missing deckId, and so on).
653
+ // (missing reportId, and so on).
640
654
  if (!existing) {
641
- getContext().observability.breadcrumb('Skipping UPDATE delta - no existing record to merge with', 'sync.database', 'warning', {
655
+ this.runtime.observability.breadcrumb('Skipping UPDATE delta - no existing record to merge with', 'sync.database', 'warning', {
642
656
  modelName,
643
657
  modelId: modelId.slice(0, 12),
644
658
  });
@@ -659,7 +673,7 @@ export class Database {
659
673
  }
660
674
  }
661
675
  catch (err) {
662
- getContext().observability.breadcrumb(`IndexedDB put failed for ${modelName}:${modelId}`, 'sync.database', 'error', {
676
+ this.runtime.observability.breadcrumb(`IndexedDB put failed for ${modelName}:${modelId}`, 'sync.database', 'error', {
663
677
  error: err instanceof Error ? err.message : String(err),
664
678
  });
665
679
  throw err;
@@ -676,7 +690,7 @@ export class Database {
676
690
  }
677
691
  }
678
692
  catch (err) {
679
- getContext().observability.breadcrumb(`IndexedDB delete failed for ${modelName}:${modelId}`, 'sync.database', 'error', {
693
+ this.runtime.observability.breadcrumb(`IndexedDB delete failed for ${modelName}:${modelId}`, 'sync.database', 'error', {
680
694
  error: err instanceof Error ? err.message : String(err),
681
695
  });
682
696
  // Surface failure so caller does not mutate InstanceCache inconsistently
@@ -694,7 +708,7 @@ export class Database {
694
708
  }
695
709
  }
696
710
  catch (err) {
697
- getContext().observability.breadcrumb(`IndexedDB archive put failed for ${modelName}:${modelId}`, 'sync.database', 'error', {
711
+ this.runtime.observability.breadcrumb(`IndexedDB archive put failed for ${modelName}:${modelId}`, 'sync.database', 'error', {
698
712
  error: err instanceof Error ? err.message : String(err),
699
713
  });
700
714
  throw err;
@@ -710,12 +724,16 @@ export class Database {
710
724
  // queue), we return a no-op verify rather than crashing the engine.
711
725
  case 'G':
712
726
  case 'S':
713
- getContext().observability.breadcrumb(`Group membership delta (${actionType}) reached processDelta — should be handled upstream`, 'sync.database', 'warning', { modelName, modelId: modelId.slice(0, 12), actionType });
727
+ this.runtime.observability.breadcrumb(`Group membership delta (${actionType}) reached processDelta — should be handled upstream`, 'sync.database', 'warning', { modelName, modelId: modelId.slice(0, 12), actionType });
714
728
  return { action: 'verify', modelName, modelId, data: null };
715
- default:
716
- throw new AbloValidationError(`Unknown action type: ${actionType}`, {
717
- code: 'db_unknown_action_type',
718
- });
729
+ default: {
730
+ // The switch above is exhaustive over the declared action types, so
731
+ // this branch is only reachable when a value escapes the type — hence
732
+ // stringifying whatever actually arrived rather than the `never`.
733
+ const _exhaustive = actionType;
734
+ void _exhaustive;
735
+ throw new AbloValidationError(`Unknown action type: ${JSON.stringify(actionType)}`, { code: 'db_unknown_action_type' });
736
+ }
719
737
  }
720
738
  }
721
739
  /**
@@ -792,7 +810,7 @@ export class Database {
792
810
  }
793
811
  }
794
812
  if (deleteSyncIds.size > 0) {
795
- getContext().logger.debug('[Database.processDeltaBatch] Built DELETE index for conflict resolution', {
813
+ this.runtime.logger.debug('[Database.processDeltaBatch] Built DELETE index for conflict resolution', {
796
814
  deleteCount: deleteSyncIds.size,
797
815
  totalDeltas: deltas.length,
798
816
  });
@@ -826,8 +844,7 @@ export class Database {
826
844
  // entity has an equal or higher sync id.
827
845
  if (delta.actionType === 'U' ||
828
846
  delta.actionType === 'I' ||
829
- delta.actionType === 'C' ||
830
- delta.actionType === 'M') {
847
+ delta.actionType === 'C') {
831
848
  const key = `${delta.modelName}:${delta.modelId}`;
832
849
  const deleteSyncId = deleteSyncIds.get(key);
833
850
  if (deleteSyncId !== undefined) {
@@ -835,7 +852,7 @@ export class Database {
835
852
  const deltaSyncId = delta.syncId ?? 0;
836
853
  if (deleteSyncId >= deltaSyncId) {
837
854
  // DELETE has equal or higher syncId - skip this UPDATE/INSERT
838
- getContext().logger.debug('[Database.processDeltaBatch] Skipping stale delta (DELETE wins)', {
855
+ this.runtime.logger.debug('[Database.processDeltaBatch] Skipping stale delta (DELETE wins)', {
839
856
  modelName: delta.modelName,
840
857
  modelId: delta.modelId.slice(0, 12),
841
858
  actionType: delta.actionType,
@@ -862,7 +879,7 @@ export class Database {
862
879
  deltasByStore.get(delta.modelName).push({ idx, delta });
863
880
  });
864
881
  if (skippedDueToConflict > 0) {
865
- getContext().logger.info('[Database.processDeltaBatch] Conflict resolution summary', {
882
+ this.runtime.logger.info('[Database.processDeltaBatch] Conflict resolution summary', {
866
883
  skippedDueToConflict,
867
884
  totalDeltas: deltas.length,
868
885
  deleteCount: deleteSyncIds.size,
@@ -892,8 +909,8 @@ export class Database {
892
909
  }
893
910
  }
894
911
  }
895
- catch (error) {
896
- getContext().observability.breadcrumb(`Batch read failed for ${modelName}, falling back to individual reads`, 'sync.database', 'warning');
912
+ catch {
913
+ this.runtime.observability.breadcrumb(`Batch read failed for ${modelName}, falling back to individual reads`, 'sync.database', 'warning');
897
914
  // Fallback: mark all as missing for self-healing
898
915
  for (const id of updateIds) {
899
916
  missingIds.add(id);
@@ -905,7 +922,7 @@ export class Database {
905
922
  // so its delta is skipped).
906
923
  const failedToFetch = new Set();
907
924
  if (missingIds.size > 0) {
908
- getContext().logger.info(`[Database.processDeltaBatch] Found ${missingIds.size} missing records for ${modelName}, fetching from server...`);
925
+ this.runtime.logger.info(`[Database.processDeltaBatch] Found ${missingIds.size} missing records for ${modelName}, fetching from server...`);
909
926
  // Fetch sequentially to avoid overwhelming server
910
927
  for (const id of missingIds) {
911
928
  try {
@@ -913,24 +930,24 @@ export class Database {
913
930
  if (fetchedRecord) {
914
931
  const compacted = this.compactRecord(modelName, fetchedRecord);
915
932
  existingRecords.set(id, compacted);
916
- getContext().logger.debug(`[Database.processDeltaBatch] Successfully fetched missing record: ${modelName}:${id}`);
933
+ this.runtime.logger.debug(`[Database.processDeltaBatch] Successfully fetched missing record: ${modelName}:${id}`);
917
934
  }
918
935
  else {
919
936
  // fetchEntity returns null for 404 — entity was deleted, skip the delta
920
937
  failedToFetch.add(id);
921
- getContext().logger.debug(`[Database.processDeltaBatch] Entity not found (deleted): ${modelName}:${id}`);
938
+ this.runtime.logger.debug(`[Database.processDeltaBatch] Entity not found (deleted): ${modelName}:${id}`);
922
939
  }
923
940
  }
924
941
  catch (error) {
925
942
  // Unexpected error (5xx, network failure) — mark for skipping and report
926
943
  failedToFetch.add(id);
927
- getContext().observability.breadcrumb(`Failed to fetch missing record ${modelName}:${id}`, 'sync.database', 'warning', {
944
+ this.runtime.observability.breadcrumb(`Failed to fetch missing record ${modelName}:${id}`, 'sync.database', 'warning', {
928
945
  error: error instanceof Error ? error.message : String(error),
929
946
  });
930
947
  }
931
948
  }
932
949
  if (failedToFetch.size > 0) {
933
- getContext().logger.info(`[Database.processDeltaBatch] Skipping ${failedToFetch.size} stale UPDATE deltas for deleted entities`, {
950
+ this.runtime.logger.info(`[Database.processDeltaBatch] Skipping ${failedToFetch.size} stale UPDATE deltas for deleted entities`, {
934
951
  modelName,
935
952
  failedCount: failedToFetch.size,
936
953
  totalMissing: missingIds.size,
@@ -982,7 +999,7 @@ export class Database {
982
999
  // store nor fetchable from the server (a 404), it was deleted,
983
1000
  // so skip it rather than create an incomplete record.
984
1001
  if (!existing && failedToFetch.has(modelId)) {
985
- getContext().logger.debug('[Database.processDeltaBatch] Skipping UPDATE for deleted entity', {
1002
+ this.runtime.logger.debug('[Database.processDeltaBatch] Skipping UPDATE for deleted entity', {
986
1003
  modelName,
987
1004
  modelId: modelId.slice(0, 12),
988
1005
  });
@@ -991,9 +1008,9 @@ export class Database {
991
1008
  }
992
1009
  // Skip the update when there's no existing record to merge with:
993
1010
  // building a record from partial update data would corrupt it
994
- // (missing deckId, and so on).
1011
+ // (missing reportId, and so on).
995
1012
  if (!existing) {
996
- getContext().observability.breadcrumb('Batch: Skipping UPDATE delta - no existing record', 'sync.database', 'warning', {
1013
+ this.runtime.observability.breadcrumb('Batch: Skipping UPDATE delta - no existing record', 'sync.database', 'warning', {
997
1014
  modelName,
998
1015
  modelId: modelId.slice(0, 12),
999
1016
  });
@@ -1063,13 +1080,13 @@ export class Database {
1063
1080
  }
1064
1081
  }
1065
1082
  catch (err) {
1066
- // Surface the IDB error directly — `captureTransactionFailure`
1083
+ // Surface the IDB error directly — `captureMutationFailure`
1067
1084
  // routes to Sentry, but during interactive debugging the console
1068
1085
  // needs to show the specific failure (e.g. `ConstraintError`,
1069
1086
  // `DataError`, `AbortError`) so we can find what's wrong with
1070
1087
  // the `compacted` payload shape or store schema.
1071
1088
  const idbErr = err instanceof Error ? err : new Error(String(err));
1072
- getContext().logger.debug('[Database.processDeltaBatch] store tx FAILED', {
1089
+ this.runtime.logger.debug('[Database.processDeltaBatch] store tx FAILED', {
1073
1090
  modelName,
1074
1091
  storeDeltasCount: storeDeltas.length,
1075
1092
  errorName: idbErr.name,
@@ -1082,7 +1099,7 @@ export class Database {
1082
1099
  : typeof delta.data,
1083
1100
  })),
1084
1101
  });
1085
- getContext().observability.captureTransactionFailure({
1102
+ this.runtime.observability.captureMutationFailure({
1086
1103
  context: 'batch-indexeddb-operation',
1087
1104
  modelName,
1088
1105
  error: idbErr,
@@ -1108,7 +1125,7 @@ export class Database {
1108
1125
  await this.updateWorkspaceMetadata({ lastSyncId: highestPersistedSyncId });
1109
1126
  }
1110
1127
  catch (err) {
1111
- getContext().observability.breadcrumb('Failed to update metadata after batch', 'sync.database', 'error', {
1128
+ this.runtime.observability.breadcrumb('Failed to update metadata after batch', 'sync.database', 'error', {
1112
1129
  error: err instanceof Error ? err.message : String(err),
1113
1130
  });
1114
1131
  }
@@ -1118,7 +1135,7 @@ export class Database {
1118
1135
  // persisted" signal loud when it actually happens. If this fires
1119
1136
  // repeatedly on the same sync IDs, a specific row is un-writable
1120
1137
  // (validation? compact issue?) and needs fixing at that layer.
1121
- getContext().logger.debug('[Database.processDeltaBatch] cursor withheld due to failed store tx', {
1138
+ this.runtime.logger.debug('[Database.processDeltaBatch] cursor withheld due to failed store tx', {
1122
1139
  seen: highestSyncId,
1123
1140
  persisted: highestPersistedSyncId,
1124
1141
  gap: highestSyncId - highestPersistedSyncId,
@@ -1138,7 +1155,7 @@ export class Database {
1138
1155
  async putRecord(modelName, id, data) {
1139
1156
  const store = this.getStore(modelName, 'putRecord');
1140
1157
  if (!store) {
1141
- getContext().observability.breadcrumb(`Store not found for putRecord: ${modelName}`, 'sync.database', 'warning');
1158
+ this.runtime.observability.breadcrumb(`Store not found for putRecord: ${modelName}`, 'sync.database', 'warning');
1142
1159
  return;
1143
1160
  }
1144
1161
  const compacted = this.compactRecord(modelName, data);
@@ -1181,7 +1198,7 @@ export class Database {
1181
1198
  // Graceful degradation: skip if database is closing or not open
1182
1199
  // This prevents "Database not opened" errors during React Strict Mode cleanup
1183
1200
  if (!this.workspaceDb || this.isClosing) {
1184
- getContext().observability.breadcrumb('updateWorkspaceMetadata: Database not open or closing', 'sync.database', 'warning', {
1201
+ this.runtime.observability.breadcrumb('updateWorkspaceMetadata: Database not open or closing', 'sync.database', 'warning', {
1185
1202
  hasDb: !!this.workspaceDb,
1186
1203
  isClosing: this.isClosing,
1187
1204
  });
@@ -1473,13 +1490,13 @@ export class Database {
1473
1490
  }
1474
1491
  await this.databaseManager.close();
1475
1492
  this.currentDbInfo = null;
1476
- getContext().logger.debug('Database closed');
1493
+ this.runtime.logger.debug('Database closed');
1477
1494
  }
1478
1495
  async clear(options = {}) {
1479
1496
  await this.storeManager.clearAllStores();
1480
1497
  if (options.includeWriteJournal) {
1481
1498
  await this.transactionStore.clear();
1482
1499
  }
1483
- getContext().logger.info('All stores cleared');
1500
+ this.runtime.logger.info('All stores cleared');
1484
1501
  }
1485
1502
  }
@@ -8,9 +8,10 @@
8
8
  */
9
9
  import { Model } from './Model.js';
10
10
  import { ModelRegistry } from './ModelRegistry.js';
11
- import { ModelScope } from './types/index.js';
12
- import { ViewRegistry } from './core/ViewRegistry.js';
13
- import { QueryView, type QueryViewOptions } from './core/QueryView.js';
11
+ import type { RuntimeContext } from './RuntimeContext.js';
12
+ import { ModelScope } from './transaction/types/index.js';
13
+ import { ViewRegistry } from './views/ViewRegistry.js';
14
+ import { QueryView, type QueryViewOptions } from './views/QueryView.js';
14
15
  /** Constructor type for Model subclasses - uses abstract to handle variance */
15
16
  type ModelConstructor<T extends Model> = abstract new (...args: never[]) => T;
16
17
  export { ModelScope };
@@ -19,6 +20,8 @@ interface PoolConfig {
19
20
  maxAge?: number;
20
21
  gcInterval?: number;
21
22
  useWeakRefs?: boolean;
23
+ /** The owning client's runtime. Defaults to the module-global bridge. */
24
+ runtime?: RuntimeContext;
22
25
  }
23
26
  interface DeltaInfo {
24
27
  action?: string;
@@ -38,6 +41,7 @@ export declare class InstanceCache {
38
41
  private foreignKeyConfig;
39
42
  private metrics;
40
43
  private config;
44
+ private readonly runtime;
41
45
  private gcTimer?;
42
46
  readonly registry: ModelRegistry;
43
47
  readonly viewRegistry: ViewRegistry;
@@ -50,6 +54,27 @@ export declare class InstanceCache {
50
54
  constructor(config?: PoolConfig, modelRegistry?: ModelRegistry);
51
55
  private resolveModel;
52
56
  get<T extends Model = Model>(id: string): T | undefined;
57
+ /**
58
+ * Look a row up **within one model**.
59
+ *
60
+ * The pool is a single id space: `get(id)` returns whatever row carries that
61
+ * id, whatever model it belongs to. That is the correct storage shape — ids
62
+ * are globally unique, the same premise as Relay's Global Object
63
+ * Identification — but it means an *untyped* lookup cannot stand in for a
64
+ * typed one. Apollo and EmberData avoid the question by keying their identity
65
+ * maps on `Type:id`; with unique ids the equivalent guarantee comes from
66
+ * stating the expected model at the lookup instead.
67
+ *
68
+ * Returns `undefined` for a row belonging to another model: from the asking
69
+ * model's perspective that id is simply absent. Callers that must tell "not
70
+ * here" apart from "here, but another model's" should compare against
71
+ * {@link get}.
72
+ *
73
+ * Prefer this over `get()` anywhere the caller knows which model it wants —
74
+ * `get()` returning another model's row has caused three product bugs, most
75
+ * recently a resize gesture that reverted after every commit.
76
+ */
77
+ getOfType<T extends Model = Model>(id: string, modelName: string): T | undefined;
53
78
  /**
54
79
  * Add model with deduplication support
55
80
  */
@@ -97,7 +122,7 @@ export declare class InstanceCache {
97
122
  * data. Cleaner than `createFromData({ __typename, ...data })` — the
98
123
  * typename lives in the arg list, not hidden inside the data object.
99
124
  *
100
- * Used for optimistic local writes: `pool.create('Slide', { id, deckId, ... })`.
125
+ * Used for optimistic local writes: `pool.create('Section', { id, reportId, ... })`.
101
126
  * For hydration from server deltas (where `__typename` already rides on
102
127
  * the payload), use `createFromData(data)` directly — that path is kept
103
128
  * because the wire format attaches the discriminator to the data itself.
@@ -178,8 +203,8 @@ export declare class InstanceCache {
178
203
  * Register a foreign key field for indexing on a model type.
179
204
  * Call once during app initialization (e.g., after model registration).
180
205
  *
181
- * Example: registerForeignKey('SlideLayer', 'slideId')
182
- * This enables getByForeignKey('SlideLayer', 'slideId', someSlideId) → O(1) lookup
206
+ * Example: registerForeignKey('Block', 'sectionId')
207
+ * This enables getByForeignKey('Block', 'sectionId', someSectionId) → O(1) lookup
183
208
  */
184
209
  registerForeignKey(modelName: string, fieldName: string): void;
185
210
  /**