@abloatai/ablo 0.35.0 → 0.37.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 (622) hide show
  1. package/AGENTS.md +2 -2
  2. package/CHANGELOG.md +71 -1929
  3. package/NOTICE +2 -2
  4. package/README.md +23 -532
  5. package/assets/banner.png +0 -0
  6. package/dist/auth.d.ts +2 -0
  7. package/dist/auth.d.ts.map +1 -0
  8. package/dist/auth.js +2 -0
  9. package/dist/auth.js.map +1 -0
  10. package/dist/client.d.ts +3 -0
  11. package/dist/client.d.ts.map +1 -0
  12. package/dist/client.js +3 -0
  13. package/dist/client.js.map +1 -0
  14. package/dist/coordination.d.ts +2 -0
  15. package/dist/coordination.d.ts.map +1 -0
  16. package/dist/coordination.js +2 -0
  17. package/dist/coordination.js.map +1 -0
  18. package/dist/index.d.ts +3 -112
  19. package/dist/index.d.ts.map +1 -0
  20. package/dist/index.js +3 -161
  21. package/dist/index.js.map +1 -0
  22. package/dist/react.d.ts +4 -0
  23. package/dist/react.d.ts.map +1 -0
  24. package/dist/react.js +3 -0
  25. package/dist/react.js.map +1 -0
  26. package/dist/schema.d.ts +2 -0
  27. package/dist/schema.d.ts.map +1 -0
  28. package/dist/schema.js +2 -0
  29. package/dist/schema.js.map +1 -0
  30. package/dist/server.d.ts +2 -0
  31. package/dist/server.d.ts.map +1 -0
  32. package/dist/server.js +2 -0
  33. package/dist/server.js.map +1 -0
  34. package/dist/source-conformance.d.ts +2 -0
  35. package/dist/source-conformance.d.ts.map +1 -0
  36. package/dist/source-conformance.js +2 -0
  37. package/dist/source-conformance.js.map +1 -0
  38. package/dist/source-drizzle.d.ts +2 -0
  39. package/dist/source-drizzle.d.ts.map +1 -0
  40. package/dist/source-drizzle.js +2 -0
  41. package/dist/source-drizzle.js.map +1 -0
  42. package/dist/source-kysely.d.ts +2 -0
  43. package/dist/source-kysely.d.ts.map +1 -0
  44. package/dist/source-kysely.js +2 -0
  45. package/dist/source-kysely.js.map +1 -0
  46. package/dist/source-next.d.ts +2 -0
  47. package/dist/source-next.d.ts.map +1 -0
  48. package/dist/source-next.js +2 -0
  49. package/dist/source-next.js.map +1 -0
  50. package/dist/source.d.ts +2 -0
  51. package/dist/source.d.ts.map +1 -0
  52. package/dist/source.js +2 -0
  53. package/dist/source.js.map +1 -0
  54. package/dist/wire.d.ts +2 -0
  55. package/dist/wire.d.ts.map +1 -0
  56. package/dist/wire.js +2 -0
  57. package/dist/wire.js.map +1 -0
  58. package/docs/agents.md +2 -2
  59. package/docs/api-keys.md +13 -12
  60. package/docs/api.md +15 -53
  61. package/docs/audit.md +4 -3
  62. package/docs/cli.md +11 -11
  63. package/docs/client-behavior.md +9 -9
  64. package/docs/concurrency-convention.md +28 -42
  65. package/docs/coordination.md +228 -86
  66. package/docs/data-sources.md +5 -5
  67. package/docs/debugging.md +34 -12
  68. package/docs/deployment.md +8 -8
  69. package/docs/examples/agent-human.md +4 -4
  70. package/docs/examples/ai-sdk-tool.md +1 -1
  71. package/docs/examples/existing-python-backend.md +15 -4
  72. package/docs/examples/nextjs.md +27 -6
  73. package/docs/examples/scoped-agent.md +3 -3
  74. package/docs/examples/server-agent.md +2 -2
  75. package/docs/groups.md +57 -3
  76. package/docs/guarantees.md +37 -10
  77. package/docs/how-it-works.md +32 -8
  78. package/docs/idempotency.md +6 -6
  79. package/docs/identity.md +24 -24
  80. package/docs/index.md +8 -8
  81. package/docs/integration-guide.md +38 -16
  82. package/docs/internal/README.md +18 -0
  83. package/docs/internal/agent-fleet-coordination-design.md +171 -0
  84. package/docs/internal/agent-orchestration.md +58 -0
  85. package/docs/internal/commit-identifiers.md +91 -0
  86. package/docs/internal/concurrency-open-decisions.md +37 -0
  87. package/docs/internal/data-source-reverse-channel.md +150 -0
  88. package/docs/internal/per-field-conflict-detection.md +165 -0
  89. package/docs/internal/postgres-replication.md +64 -0
  90. package/docs/internal/serializable-schema.md +119 -0
  91. package/docs/internal/structure.md +32 -0
  92. package/docs/mcp.md +9 -9
  93. package/docs/migration.md +37 -18
  94. package/docs/projects.md +1 -1
  95. package/docs/quickstart.md +2 -2
  96. package/docs/react.md +24 -13
  97. package/docs/schema-contract.md +3 -3
  98. package/docs/sessions.md +91 -37
  99. package/docs/webhooks.md +9 -9
  100. package/examples/README.md +2 -2
  101. package/examples/data-source/README.md +1 -1
  102. package/examples/data-source/ablo-driver.ts +1 -1
  103. package/examples/data-source/customer-server.ts +1 -1
  104. package/examples/data-source/run.ts +1 -1
  105. package/examples/data-source/schema.ts +1 -1
  106. package/examples/quickstart.ts +2 -2
  107. package/llms.txt +12 -12
  108. package/package.json +64 -174
  109. package/dist/BaseSyncedStore.d.ts +0 -823
  110. package/dist/BaseSyncedStore.js +0 -1955
  111. package/dist/Database.d.ts +0 -335
  112. package/dist/Database.js +0 -1500
  113. package/dist/InstanceCache.d.ts +0 -233
  114. package/dist/InstanceCache.js +0 -1164
  115. package/dist/LazyReferenceCollection.d.ts +0 -177
  116. package/dist/LazyReferenceCollection.js +0 -461
  117. package/dist/Model.d.ts +0 -444
  118. package/dist/Model.js +0 -909
  119. package/dist/ModelRegistry.d.ts +0 -221
  120. package/dist/ModelRegistry.js +0 -537
  121. package/dist/NetworkMonitor.d.ts +0 -26
  122. package/dist/NetworkMonitor.js +0 -77
  123. package/dist/RuntimeContext.d.ts +0 -52
  124. package/dist/RuntimeContext.js +0 -80
  125. package/dist/SyncClient.d.ts +0 -551
  126. package/dist/SyncClient.js +0 -2199
  127. package/dist/adapters/alwaysOnline.d.ts +0 -14
  128. package/dist/adapters/alwaysOnline.js +0 -17
  129. package/dist/adapters/inMemoryStorage.d.ts +0 -31
  130. package/dist/adapters/inMemoryStorage.js +0 -110
  131. package/dist/ai-sdk/coordinatedTool.d.ts +0 -120
  132. package/dist/ai-sdk/coordinatedTool.js +0 -134
  133. package/dist/ai-sdk/coordinationContext.d.ts +0 -46
  134. package/dist/ai-sdk/coordinationContext.js +0 -106
  135. package/dist/ai-sdk/index.d.ts +0 -121
  136. package/dist/ai-sdk/index.js +0 -121
  137. package/dist/ai-sdk/wrap.d.ts +0 -65
  138. package/dist/ai-sdk/wrap.js +0 -39
  139. package/dist/auth/index.d.ts +0 -1
  140. package/dist/auth/index.js +0 -8
  141. package/dist/batching/index.d.ts +0 -55
  142. package/dist/batching/index.js +0 -147
  143. package/dist/cli.cjs +0 -288600
  144. package/dist/client/Ablo.d.ts +0 -231
  145. package/dist/client/Ablo.js +0 -149
  146. package/dist/client/abloClient.d.ts +0 -309
  147. package/dist/client/abloClient.js +0 -13
  148. package/dist/client/clientPrelude.d.ts +0 -52
  149. package/dist/client/clientPrelude.js +0 -60
  150. package/dist/client/consoleLogger.d.ts +0 -35
  151. package/dist/client/consoleLogger.js +0 -44
  152. package/dist/client/coreClient.d.ts +0 -60
  153. package/dist/client/coreClient.js +0 -118
  154. package/dist/client/createInternalComponents.d.ts +0 -46
  155. package/dist/client/createInternalComponents.js +0 -92
  156. package/dist/client/createModelProxy.d.ts +0 -228
  157. package/dist/client/createModelProxy.js +0 -818
  158. package/dist/client/humans.d.ts +0 -48
  159. package/dist/client/humans.js +0 -52
  160. package/dist/client/modelRegistration.d.ts +0 -10
  161. package/dist/client/modelRegistration.js +0 -312
  162. package/dist/client/options.d.ts +0 -461
  163. package/dist/client/options.js +0 -7
  164. package/dist/client/reactiveEngine.d.ts +0 -48
  165. package/dist/client/reactiveEngine.js +0 -910
  166. package/dist/client/resourceTypes.d.ts +0 -12
  167. package/dist/client/resourceTypes.js +0 -10
  168. package/dist/client/schemaConfig.d.ts +0 -44
  169. package/dist/client/schemaConfig.js +0 -185
  170. package/dist/client/validateAbloOptions.d.ts +0 -42
  171. package/dist/client/validateAbloOptions.js +0 -43
  172. package/dist/client/wsMutationExecutor.d.ts +0 -27
  173. package/dist/client/wsMutationExecutor.js +0 -72
  174. package/dist/context.d.ts +0 -29
  175. package/dist/context.js +0 -58
  176. package/dist/coordination/ClaimLog.d.ts +0 -26
  177. package/dist/coordination/ClaimLog.js +0 -32
  178. package/dist/coordination/index.d.ts +0 -1
  179. package/dist/coordination/index.js +0 -8
  180. package/dist/core/DatabaseManager.d.ts +0 -105
  181. package/dist/core/DatabaseManager.js +0 -387
  182. package/dist/core/QueryProcessor.d.ts +0 -75
  183. package/dist/core/QueryProcessor.js +0 -255
  184. package/dist/core/QueryView.d.ts +0 -79
  185. package/dist/core/QueryView.js +0 -218
  186. package/dist/core/StoreManager.d.ts +0 -112
  187. package/dist/core/StoreManager.js +0 -302
  188. package/dist/core/ViewRegistry.d.ts +0 -20
  189. package/dist/core/ViewRegistry.js +0 -55
  190. package/dist/core/index.d.ts +0 -33
  191. package/dist/core/index.js +0 -48
  192. package/dist/core/openIDBWithTimeout.d.ts +0 -65
  193. package/dist/core/openIDBWithTimeout.js +0 -153
  194. package/dist/core/queryUtils.d.ts +0 -45
  195. package/dist/core/queryUtils.js +0 -69
  196. package/dist/core/storeContract.d.ts +0 -145
  197. package/dist/core/storeContract.js +0 -12
  198. package/dist/docs/catalog.d.ts +0 -72
  199. package/dist/docs/catalog.js +0 -227
  200. package/dist/docs/index.d.ts +0 -10
  201. package/dist/docs/index.js +0 -10
  202. package/dist/environment.d.ts +0 -1
  203. package/dist/environment.js +0 -8
  204. package/dist/interfaces/index.d.ts +0 -311
  205. package/dist/interfaces/index.js +0 -9
  206. package/dist/keys/index.d.ts +0 -1
  207. package/dist/keys/index.js +0 -8
  208. package/dist/mutators/RecordingMutation.d.ts +0 -36
  209. package/dist/mutators/RecordingMutation.js +0 -182
  210. package/dist/mutators/Transaction.d.ts +0 -40
  211. package/dist/mutators/Transaction.js +0 -58
  212. package/dist/mutators/UndoManager.d.ts +0 -258
  213. package/dist/mutators/UndoManager.js +0 -658
  214. package/dist/mutators/defineMutators.d.ts +0 -60
  215. package/dist/mutators/defineMutators.js +0 -18
  216. package/dist/mutators/inverseOp.d.ts +0 -126
  217. package/dist/mutators/inverseOp.js +0 -71
  218. package/dist/mutators/mutateActions.d.ts +0 -45
  219. package/dist/mutators/mutateActions.js +0 -105
  220. package/dist/mutators/readerActions.d.ts +0 -33
  221. package/dist/mutators/readerActions.js +0 -57
  222. package/dist/mutators/undoApply.d.ts +0 -51
  223. package/dist/mutators/undoApply.js +0 -117
  224. package/dist/policy/index.d.ts +0 -21
  225. package/dist/policy/index.js +0 -20
  226. package/dist/query/client.d.ts +0 -61
  227. package/dist/query/client.js +0 -137
  228. package/dist/query/types.d.ts +0 -85
  229. package/dist/query/types.js +0 -16
  230. package/dist/react/AbloProvider.d.ts +0 -230
  231. package/dist/react/AbloProvider.js +0 -455
  232. package/dist/react/ClientSideSuspense.d.ts +0 -36
  233. package/dist/react/ClientSideSuspense.js +0 -17
  234. package/dist/react/DefaultFallback.d.ts +0 -24
  235. package/dist/react/DefaultFallback.js +0 -43
  236. package/dist/react/context.d.ts +0 -55
  237. package/dist/react/context.js +0 -29
  238. package/dist/react/index.d.ts +0 -61
  239. package/dist/react/index.js +0 -66
  240. package/dist/react/internalContext.d.ts +0 -33
  241. package/dist/react/internalContext.js +0 -3
  242. package/dist/react/useAblo.d.ts +0 -75
  243. package/dist/react/useAblo.js +0 -102
  244. package/dist/react/useCurrentUserId.d.ts +0 -22
  245. package/dist/react/useCurrentUserId.js +0 -34
  246. package/dist/react/useErrorListener.d.ts +0 -20
  247. package/dist/react/useErrorListener.js +0 -38
  248. package/dist/react/useMutationFailureListener.d.ts +0 -26
  249. package/dist/react/useMutationFailureListener.js +0 -38
  250. package/dist/react/useMutators.d.ts +0 -56
  251. package/dist/react/useMutators.js +0 -84
  252. package/dist/react/useReactive.d.ts +0 -35
  253. package/dist/react/useReactive.js +0 -123
  254. package/dist/react/useSyncStatus.d.ts +0 -59
  255. package/dist/react/useSyncStatus.js +0 -76
  256. package/dist/react/useUndoScope.d.ts +0 -34
  257. package/dist/react/useUndoScope.js +0 -81
  258. package/dist/schema/coordination.d.ts +0 -112
  259. package/dist/schema/coordination.js +0 -129
  260. package/dist/schema/ddl.d.ts +0 -97
  261. package/dist/schema/ddl.js +0 -491
  262. package/dist/schema/ddlLock.d.ts +0 -35
  263. package/dist/schema/ddlLock.js +0 -46
  264. package/dist/schema/diff.d.ts +0 -225
  265. package/dist/schema/diff.js +0 -289
  266. package/dist/schema/generate.d.ts +0 -19
  267. package/dist/schema/generate.js +0 -86
  268. package/dist/schema/index.d.ts +0 -41
  269. package/dist/schema/index.js +0 -76
  270. package/dist/schema/queries.d.ts +0 -201
  271. package/dist/schema/queries.js +0 -144
  272. package/dist/schema/select.d.ts +0 -40
  273. package/dist/schema/select.js +0 -87
  274. package/dist/schema/serialize.d.ts +0 -115
  275. package/dist/schema/serialize.js +0 -262
  276. package/dist/schema/sugar.d.ts +0 -109
  277. package/dist/schema/sugar.js +0 -83
  278. package/dist/schema/syncDeltaRow.d.ts +0 -6
  279. package/dist/schema/syncDeltaRow.js +0 -6
  280. package/dist/server/adapter.d.ts +0 -173
  281. package/dist/server/adapter.js +0 -18
  282. package/dist/server/commit.d.ts +0 -107
  283. package/dist/server/commit.js +0 -1
  284. package/dist/server/index.d.ts +0 -14
  285. package/dist/server/index.js +0 -2
  286. package/dist/server/readConfig.d.ts +0 -80
  287. package/dist/server/readConfig.js +0 -8
  288. package/dist/server/storageMode.d.ts +0 -23
  289. package/dist/server/storageMode.js +0 -17
  290. package/dist/source/adapter.d.ts +0 -81
  291. package/dist/source/adapter.js +0 -22
  292. package/dist/source/adapters/drizzle.d.ts +0 -48
  293. package/dist/source/adapters/drizzle.js +0 -219
  294. package/dist/source/adapters/kysely.d.ts +0 -42
  295. package/dist/source/adapters/kysely.js +0 -205
  296. package/dist/source/adapters/kyselyMutationCore.d.ts +0 -76
  297. package/dist/source/adapters/kyselyMutationCore.js +0 -125
  298. package/dist/source/adapters/memory.d.ts +0 -13
  299. package/dist/source/adapters/memory.js +0 -130
  300. package/dist/source/adapters/prisma.d.ts +0 -63
  301. package/dist/source/adapters/prisma.js +0 -202
  302. package/dist/source/conformance.d.ts +0 -37
  303. package/dist/source/conformance.js +0 -215
  304. package/dist/source/connector.d.ts +0 -95
  305. package/dist/source/connector.js +0 -266
  306. package/dist/source/connectorProtocol.d.ts +0 -154
  307. package/dist/source/connectorProtocol.js +0 -163
  308. package/dist/source/contract.d.ts +0 -195
  309. package/dist/source/contract.js +0 -164
  310. package/dist/source/factory.d.ts +0 -92
  311. package/dist/source/factory.js +0 -286
  312. package/dist/source/footprint.d.ts +0 -111
  313. package/dist/source/footprint.js +0 -0
  314. package/dist/source/idempotency.d.ts +0 -61
  315. package/dist/source/idempotency.js +0 -144
  316. package/dist/source/index.d.ts +0 -23
  317. package/dist/source/index.js +0 -30
  318. package/dist/source/migrations.d.ts +0 -21
  319. package/dist/source/migrations.js +0 -103
  320. package/dist/source/next.d.ts +0 -32
  321. package/dist/source/next.js +0 -25
  322. package/dist/source/pushQueue.d.ts +0 -134
  323. package/dist/source/pushQueue.js +0 -256
  324. package/dist/source/signing.d.ts +0 -92
  325. package/dist/source/signing.js +0 -162
  326. package/dist/source/types.d.ts +0 -401
  327. package/dist/source/types.js +0 -59
  328. package/dist/stores/ObjectStore.d.ts +0 -115
  329. package/dist/stores/ObjectStore.js +0 -393
  330. package/dist/stores/ObjectStoreContract.d.ts +0 -38
  331. package/dist/stores/ObjectStoreContract.js +0 -1
  332. package/dist/stores/SyncActionStore.d.ts +0 -97
  333. package/dist/stores/SyncActionStore.js +0 -504
  334. package/dist/stores/syncAction.d.ts +0 -26
  335. package/dist/stores/syncAction.js +0 -16
  336. package/dist/surface.d.ts +0 -36
  337. package/dist/surface.js +0 -75
  338. package/dist/sync/BootstrapFetcher.d.ts +0 -280
  339. package/dist/sync/BootstrapFetcher.js +0 -962
  340. package/dist/sync/ConnectionManager.d.ts +0 -8
  341. package/dist/sync/ConnectionManager.js +0 -8
  342. package/dist/sync/OnDemandLoader.d.ts +0 -228
  343. package/dist/sync/OnDemandLoader.js +0 -742
  344. package/dist/sync/SubscriptionManager.d.ts +0 -159
  345. package/dist/sync/SubscriptionManager.js +0 -243
  346. package/dist/sync/SyncWebSocket.d.ts +0 -173
  347. package/dist/sync/SyncWebSocket.js +0 -438
  348. package/dist/sync/awaitClaimGrant.d.ts +0 -6
  349. package/dist/sync/awaitClaimGrant.js +0 -6
  350. package/dist/sync/bootstrapApply.d.ts +0 -70
  351. package/dist/sync/bootstrapApply.js +0 -73
  352. package/dist/sync/commitFrames.d.ts +0 -8
  353. package/dist/sync/commitFrames.js +0 -8
  354. package/dist/sync/contextPorts.d.ts +0 -18
  355. package/dist/sync/contextPorts.js +0 -31
  356. package/dist/sync/createClaimStream.d.ts +0 -7
  357. package/dist/sync/createClaimStream.js +0 -7
  358. package/dist/sync/createPresenceStream.d.ts +0 -69
  359. package/dist/sync/createPresenceStream.js +0 -200
  360. package/dist/sync/createSnapshot.d.ts +0 -29
  361. package/dist/sync/createSnapshot.js +0 -118
  362. package/dist/sync/credentialLifecycle.d.ts +0 -7
  363. package/dist/sync/credentialLifecycle.js +0 -7
  364. package/dist/sync/deltaPipeline.d.ts +0 -113
  365. package/dist/sync/deltaPipeline.js +0 -261
  366. package/dist/sync/groupChange.d.ts +0 -113
  367. package/dist/sync/groupChange.js +0 -242
  368. package/dist/sync/participants.d.ts +0 -115
  369. package/dist/sync/participants.js +0 -344
  370. package/dist/sync/persistedPrefix.d.ts +0 -12
  371. package/dist/sync/persistedPrefix.js +0 -22
  372. package/dist/sync/schemaDrift.d.ts +0 -55
  373. package/dist/sync/schemaDrift.js +0 -53
  374. package/dist/sync/schemas.d.ts +0 -70
  375. package/dist/sync/schemas.js +0 -94
  376. package/dist/sync/syncCursor.d.ts +0 -40
  377. package/dist/sync/syncCursor.js +0 -55
  378. package/dist/sync/syncPlan.d.ts +0 -54
  379. package/dist/sync/syncPlan.js +0 -50
  380. package/dist/sync/wsFrameHandlers.d.ts +0 -8
  381. package/dist/sync/wsFrameHandlers.js +0 -8
  382. package/dist/testing/fixtures/bootstrap.d.ts +0 -49
  383. package/dist/testing/fixtures/bootstrap.js +0 -59
  384. package/dist/testing/fixtures/deltas.d.ts +0 -83
  385. package/dist/testing/fixtures/deltas.js +0 -136
  386. package/dist/testing/fixtures/httpResponses.d.ts +0 -70
  387. package/dist/testing/fixtures/httpResponses.js +0 -90
  388. package/dist/testing/fixtures/models.d.ts +0 -83
  389. package/dist/testing/fixtures/models.js +0 -272
  390. package/dist/testing/helpers/reactWrapper.d.ts +0 -69
  391. package/dist/testing/helpers/reactWrapper.js +0 -67
  392. package/dist/testing/helpers/syncEngineHarness.d.ts +0 -54
  393. package/dist/testing/helpers/syncEngineHarness.js +0 -73
  394. package/dist/testing/helpers/wait.d.ts +0 -30
  395. package/dist/testing/helpers/wait.js +0 -49
  396. package/dist/testing/index.d.ts +0 -23
  397. package/dist/testing/index.js +0 -33
  398. package/dist/testing/mocks/FakeDatabase.d.ts +0 -18
  399. package/dist/testing/mocks/FakeDatabase.js +0 -10
  400. package/dist/testing/mocks/MockMutationExecutor.d.ts +0 -87
  401. package/dist/testing/mocks/MockMutationExecutor.js +0 -186
  402. package/dist/testing/mocks/MockNetworkMonitor.d.ts +0 -20
  403. package/dist/testing/mocks/MockNetworkMonitor.js +0 -46
  404. package/dist/testing/mocks/MockSyncContext.d.ts +0 -51
  405. package/dist/testing/mocks/MockSyncContext.js +0 -72
  406. package/dist/testing/mocks/MockSyncStore.d.ts +0 -88
  407. package/dist/testing/mocks/MockSyncStore.js +0 -171
  408. package/dist/testing/mocks/MockWebSocket.d.ts +0 -71
  409. package/dist/testing/mocks/MockWebSocket.js +0 -118
  410. package/dist/transaction/ablo.d.ts +0 -88
  411. package/dist/transaction/ablo.js +0 -33
  412. package/dist/transaction/auth/apiKey.d.ts +0 -152
  413. package/dist/transaction/auth/apiKey.js +0 -419
  414. package/dist/transaction/auth/bootstrapScope.d.ts +0 -15
  415. package/dist/transaction/auth/bootstrapScope.js +0 -1
  416. package/dist/transaction/auth/capability.d.ts +0 -177
  417. package/dist/transaction/auth/capability.js +0 -199
  418. package/dist/transaction/auth/credentialEndpoint.d.ts +0 -61
  419. package/dist/transaction/auth/credentialEndpoint.js +0 -86
  420. package/dist/transaction/auth/credentialPolicy.d.ts +0 -148
  421. package/dist/transaction/auth/credentialPolicy.js +0 -125
  422. package/dist/transaction/auth/credentialSource.d.ts +0 -30
  423. package/dist/transaction/auth/credentialSource.js +0 -55
  424. package/dist/transaction/auth/hostedEndpoints.d.ts +0 -21
  425. package/dist/transaction/auth/hostedEndpoints.js +0 -21
  426. package/dist/transaction/auth/identity.d.ts +0 -55
  427. package/dist/transaction/auth/identity.js +0 -210
  428. package/dist/transaction/auth/index.d.ts +0 -162
  429. package/dist/transaction/auth/index.js +0 -304
  430. package/dist/transaction/auth/schemas.d.ts +0 -59
  431. package/dist/transaction/auth/schemas.js +0 -85
  432. package/dist/transaction/auth/sessionMint.d.ts +0 -28
  433. package/dist/transaction/auth/sessionMint.js +0 -85
  434. package/dist/transaction/coordination/awaitClaimGrant.d.ts +0 -49
  435. package/dist/transaction/coordination/awaitClaimGrant.js +0 -112
  436. package/dist/transaction/coordination/claimHeartbeatLoop.d.ts +0 -50
  437. package/dist/transaction/coordination/claimHeartbeatLoop.js +0 -88
  438. package/dist/transaction/coordination/claimMeta.d.ts +0 -49
  439. package/dist/transaction/coordination/claimMeta.js +0 -52
  440. package/dist/transaction/coordination/createClaimStream.d.ts +0 -64
  441. package/dist/transaction/coordination/createClaimStream.js +0 -475
  442. package/dist/transaction/coordination/events.d.ts +0 -74
  443. package/dist/transaction/coordination/events.js +0 -7
  444. package/dist/transaction/coordination/index.d.ts +0 -19
  445. package/dist/transaction/coordination/index.js +0 -44
  446. package/dist/transaction/coordination/locator.d.ts +0 -83
  447. package/dist/transaction/coordination/locator.js +0 -82
  448. package/dist/transaction/coordination/schema.d.ts +0 -1473
  449. package/dist/transaction/coordination/schema.js +0 -1013
  450. package/dist/transaction/coordination/targetConflict.d.ts +0 -2
  451. package/dist/transaction/coordination/targetConflict.js +0 -103
  452. package/dist/transaction/coordination/trace.d.ts +0 -78
  453. package/dist/transaction/coordination/trace.js +0 -138
  454. package/dist/transaction/durableWrites.d.ts +0 -62
  455. package/dist/transaction/durableWrites.js +0 -71
  456. package/dist/transaction/environment.d.ts +0 -105
  457. package/dist/transaction/environment.js +0 -108
  458. package/dist/transaction/errorCodes.d.ts +0 -403
  459. package/dist/transaction/errorCodes.js +0 -480
  460. package/dist/transaction/errors.d.ts +0 -428
  461. package/dist/transaction/errors.js +0 -686
  462. package/dist/transaction/index.d.ts +0 -20
  463. package/dist/transaction/index.js +0 -20
  464. package/dist/transaction/keys/index.d.ts +0 -87
  465. package/dist/transaction/keys/index.js +0 -207
  466. package/dist/transaction/log/syncDeltaRow.d.ts +0 -158
  467. package/dist/transaction/log/syncDeltaRow.js +0 -95
  468. package/dist/transaction/logPosition.d.ts +0 -97
  469. package/dist/transaction/logPosition.js +0 -125
  470. package/dist/transaction/logger.d.ts +0 -16
  471. package/dist/transaction/logger.js +0 -7
  472. package/dist/transaction/observability.d.ts +0 -53
  473. package/dist/transaction/observability.js +0 -19
  474. package/dist/transaction/persistence.d.ts +0 -12
  475. package/dist/transaction/persistence.js +0 -11
  476. package/dist/transaction/plugin.d.ts +0 -192
  477. package/dist/transaction/plugin.js +0 -87
  478. package/dist/transaction/policy/types.d.ts +0 -217
  479. package/dist/transaction/policy/types.js +0 -126
  480. package/dist/transaction/resources/functionalUpdate.d.ts +0 -79
  481. package/dist/transaction/resources/functionalUpdate.js +0 -87
  482. package/dist/transaction/resources/httpResources.d.ts +0 -266
  483. package/dist/transaction/resources/httpResources.js +0 -7
  484. package/dist/transaction/resources/modelOperations.d.ts +0 -319
  485. package/dist/transaction/resources/modelOperations.js +0 -12
  486. package/dist/transaction/resources/mutationOptions.d.ts +0 -66
  487. package/dist/transaction/resources/mutationOptions.js +0 -9
  488. package/dist/transaction/resources/where.d.ts +0 -85
  489. package/dist/transaction/resources/where.js +0 -70
  490. package/dist/transaction/resources/writeOptionsSchema.d.ts +0 -47
  491. package/dist/transaction/resources/writeOptionsSchema.js +0 -73
  492. package/dist/transaction/schema/field.d.ts +0 -126
  493. package/dist/transaction/schema/field.js +0 -265
  494. package/dist/transaction/schema/loadStrategy.d.ts +0 -45
  495. package/dist/transaction/schema/loadStrategy.js +0 -46
  496. package/dist/transaction/schema/model.d.ts +0 -379
  497. package/dist/transaction/schema/model.js +0 -123
  498. package/dist/transaction/schema/openapi.d.ts +0 -57
  499. package/dist/transaction/schema/openapi.js +0 -340
  500. package/dist/transaction/schema/relation.d.ts +0 -199
  501. package/dist/transaction/schema/relation.js +0 -104
  502. package/dist/transaction/schema/residency.d.ts +0 -29
  503. package/dist/transaction/schema/residency.js +0 -25
  504. package/dist/transaction/schema/roles.d.ts +0 -249
  505. package/dist/transaction/schema/roles.js +0 -230
  506. package/dist/transaction/schema/schema.d.ts +0 -324
  507. package/dist/transaction/schema/schema.js +0 -305
  508. package/dist/transaction/schema/tenancy.d.ts +0 -139
  509. package/dist/transaction/schema/tenancy.js +0 -190
  510. package/dist/transaction/transactionLayer.d.ts +0 -82
  511. package/dist/transaction/transactionLayer.js +0 -24
  512. package/dist/transaction/transactions/settlement/commitEnvelope.d.ts +0 -143
  513. package/dist/transaction/transactions/settlement/commitEnvelope.js +0 -161
  514. package/dist/transaction/transactions/settlement/httpCommitEnvelope.d.ts +0 -53
  515. package/dist/transaction/transactions/settlement/httpCommitEnvelope.js +0 -207
  516. package/dist/transaction/transactions/settlement/idempotencyKey.d.ts +0 -10
  517. package/dist/transaction/transactions/settlement/idempotencyKey.js +0 -9
  518. package/dist/transaction/transactions/settlement/pendingWrite.d.ts +0 -112
  519. package/dist/transaction/transactions/settlement/pendingWrite.js +0 -20
  520. package/dist/transaction/transport/commitFrames.d.ts +0 -90
  521. package/dist/transaction/transport/commitFrames.js +0 -134
  522. package/dist/transaction/transport/connectionManager.d.ts +0 -215
  523. package/dist/transaction/transport/connectionManager.js +0 -673
  524. package/dist/transaction/transport/credentialLifecycle.d.ts +0 -177
  525. package/dist/transaction/transport/credentialLifecycle.js +0 -324
  526. package/dist/transaction/transport/heartbeat.d.ts +0 -65
  527. package/dist/transaction/transport/heartbeat.js +0 -93
  528. package/dist/transaction/transport/httpClient.d.ts +0 -123
  529. package/dist/transaction/transport/httpClient.js +0 -145
  530. package/dist/transaction/transport/httpOptions.d.ts +0 -33
  531. package/dist/transaction/transport/httpOptions.js +0 -12
  532. package/dist/transaction/transport/httpTransport.d.ts +0 -8
  533. package/dist/transaction/transport/httpTransport.js +0 -1276
  534. package/dist/transaction/transport/networkProbe.d.ts +0 -84
  535. package/dist/transaction/transport/networkProbe.js +0 -207
  536. package/dist/transaction/transport/wsFrameHandlers.d.ts +0 -128
  537. package/dist/transaction/transport/wsFrameHandlers.js +0 -429
  538. package/dist/transaction/transport/wsTransport.d.ts +0 -576
  539. package/dist/transaction/transport/wsTransport.js +0 -1017
  540. package/dist/transaction/types/assertExact.d.ts +0 -17
  541. package/dist/transaction/types/assertExact.js +0 -1
  542. package/dist/transaction/types/global.d.ts +0 -107
  543. package/dist/transaction/types/global.js +0 -40
  544. package/dist/transaction/types/index.d.ts +0 -205
  545. package/dist/transaction/types/index.js +0 -56
  546. package/dist/transaction/types/modelData.d.ts +0 -10
  547. package/dist/transaction/types/modelData.js +0 -9
  548. package/dist/transaction/types/participant.d.ts +0 -20
  549. package/dist/transaction/types/participant.js +0 -10
  550. package/dist/transaction/types/streams.d.ts +0 -540
  551. package/dist/transaction/types/streams.js +0 -11
  552. package/dist/transaction/utils/asyncIterator.d.ts +0 -34
  553. package/dist/transaction/utils/asyncIterator.js +0 -135
  554. package/dist/transaction/utils/duration.d.ts +0 -25
  555. package/dist/transaction/utils/duration.js +0 -45
  556. package/dist/transaction/utils/json.d.ts +0 -57
  557. package/dist/transaction/utils/json.js +0 -276
  558. package/dist/transaction/wire/accountResponses.d.ts +0 -351
  559. package/dist/transaction/wire/accountResponses.js +0 -255
  560. package/dist/transaction/wire/auth.d.ts +0 -49
  561. package/dist/transaction/wire/auth.js +0 -57
  562. package/dist/transaction/wire/bootstrapReason.d.ts +0 -9
  563. package/dist/transaction/wire/bootstrapReason.js +0 -8
  564. package/dist/transaction/wire/claimEvent.d.ts +0 -76
  565. package/dist/transaction/wire/claimEvent.js +0 -73
  566. package/dist/transaction/wire/claims.d.ts +0 -463
  567. package/dist/transaction/wire/claims.js +0 -229
  568. package/dist/transaction/wire/commit.d.ts +0 -603
  569. package/dist/transaction/wire/commit.js +0 -321
  570. package/dist/transaction/wire/delta.d.ts +0 -250
  571. package/dist/transaction/wire/delta.js +0 -147
  572. package/dist/transaction/wire/errorEnvelope.d.ts +0 -72
  573. package/dist/transaction/wire/errorEnvelope.js +0 -123
  574. package/dist/transaction/wire/feedCursor.d.ts +0 -60
  575. package/dist/transaction/wire/feedCursor.js +0 -82
  576. package/dist/transaction/wire/feedEvent.d.ts +0 -177
  577. package/dist/transaction/wire/feedEvent.js +0 -39
  578. package/dist/transaction/wire/frames.d.ts +0 -194
  579. package/dist/transaction/wire/frames.js +0 -50
  580. package/dist/transaction/wire/inboundFrames.d.ts +0 -552
  581. package/dist/transaction/wire/inboundFrames.js +0 -116
  582. package/dist/transaction/wire/index.d.ts +0 -50
  583. package/dist/transaction/wire/index.js +0 -74
  584. package/dist/transaction/wire/listEnvelope.d.ts +0 -37
  585. package/dist/transaction/wire/listEnvelope.js +0 -42
  586. package/dist/transaction/wire/modelResponses.d.ts +0 -85
  587. package/dist/transaction/wire/modelResponses.js +0 -43
  588. package/dist/transaction/wire/protocol.d.ts +0 -38
  589. package/dist/transaction/wire/protocol.js +0 -38
  590. package/dist/transaction/wire/protocolVersion.d.ts +0 -73
  591. package/dist/transaction/wire/protocolVersion.js +0 -83
  592. package/dist/transactions/mutations/MutationQueue.d.ts +0 -655
  593. package/dist/transactions/mutations/MutationQueue.js +0 -2797
  594. package/dist/transactions/mutations/MutationStore.d.ts +0 -20
  595. package/dist/transactions/mutations/MutationStore.js +0 -53
  596. package/dist/transactions/mutations/UnconfirmedWrites.d.ts +0 -82
  597. package/dist/transactions/mutations/UnconfirmedWrites.js +0 -104
  598. package/dist/transactions/mutations/coalesceRules.d.ts +0 -58
  599. package/dist/transactions/mutations/coalesceRules.js +0 -140
  600. package/dist/transactions/mutations/commitLatency.d.ts +0 -52
  601. package/dist/transactions/mutations/commitLatency.js +0 -130
  602. package/dist/transactions/mutations/commitOutboxStore.d.ts +0 -28
  603. package/dist/transactions/mutations/commitOutboxStore.js +0 -26
  604. package/dist/transactions/mutations/commitPayload.d.ts +0 -164
  605. package/dist/transactions/mutations/commitPayload.js +0 -152
  606. package/dist/transactions/mutations/deltaConfirmation.d.ts +0 -59
  607. package/dist/transactions/mutations/deltaConfirmation.js +0 -233
  608. package/dist/transactions/mutations/durableWriteStore.d.ts +0 -14
  609. package/dist/transactions/mutations/durableWriteStore.js +0 -12
  610. package/dist/transactions/mutations/optimisticApply.d.ts +0 -49
  611. package/dist/transactions/mutations/optimisticApply.js +0 -65
  612. package/dist/transactions/mutations/replayValidation.d.ts +0 -186
  613. package/dist/transactions/mutations/replayValidation.js +0 -163
  614. package/dist/utils/mobxSetup.d.ts +0 -53
  615. package/dist/utils/mobxSetup.js +0 -330
  616. package/dist/webhooks/events.d.ts +0 -43
  617. package/dist/webhooks/events.js +0 -42
  618. package/dist/webhooks/index.d.ts +0 -8
  619. package/dist/webhooks/index.js +0 -8
  620. package/dist/wire/index.d.ts +0 -1
  621. package/dist/wire/index.js +0 -8
  622. package/docs/interaction-model.md +0 -99
@@ -1,261 +0,0 @@
1
- /**
2
- * The pipeline that takes incoming deltas from the server and lands them in
3
- * local state. It has four stages: deduplicating deltas by state signature,
4
- * per-delta bookkeeping and enqueue, a debounce for live traffic, and a flush
5
- * that writes to the local store and then the in-memory pool. Every call it
6
- * makes back into the surrounding store — resolving state fields, identifying
7
- * custom entities, deduplicating, flushing, handling sync-group changes —
8
- * routes through the {@link DeltaPipelineContext} interface, so a subclass that
9
- * overrides any of those hooks still takes effect. The atomic frame-apply entry
10
- * point lives on the store and drives this pipeline through {@link enqueueDelta}
11
- * and {@link flushPendingDeltas}.
12
- */
13
- import { runInAction } from 'mobx';
14
- import { getContext } from '../context.js';
15
- import { ModelScope } from '../InstanceCache.js';
16
- /**
17
- * Handles a sync-group ('G' or 'S') delta whose handler rejected after the
18
- * applied watermark had already advanced. That delta will never be redelivered,
19
- * so a failed security clear — revoked data that must not stay cached — would
20
- * otherwise fail silently. The safe fallback is blunt: drop the whole in-memory
21
- * pool and force a full re-bootstrap, rebuilding local state from the server.
22
- * It never throws, because it runs inside the pipeline's fire-and-forget path.
23
- */
24
- export function handleGroupHandlerFailure(ctx, delta, error) {
25
- getContext().logger.error('Your access changed but cached data could not be cleared — resetting local data.', {
26
- syncId: delta.id,
27
- error: error instanceof Error ? error.message : String(error),
28
- });
29
- try {
30
- ctx.objectPool.clear();
31
- }
32
- catch {
33
- // In-memory clear must never mask the re-bootstrap below.
34
- }
35
- try {
36
- ctx.forceFullRebootstrap();
37
- }
38
- catch {
39
- // Best-effort: the reconnect/bootstrap cycle self-heals on next connect.
40
- }
41
- }
42
- /** Builds a small signature of a delta's state fields, used to detect no-op duplicate deltas. */
43
- function extractStateSignature(ctx, delta) {
44
- if (!delta.data || typeof delta.data !== 'object')
45
- return null;
46
- const data = typeof delta.data === 'string'
47
- ? JSON.parse(delta.data)
48
- : (delta.data);
49
- // Generic state fields — subclasses can override getStateFields() for model-specific fields
50
- const fieldsToCheck = ctx.getStateFields(delta.modelName);
51
- const signature = {
52
- actionType: delta.actionType,
53
- modelName: delta.modelName,
54
- };
55
- for (const field of fieldsToCheck) {
56
- if (field in data)
57
- signature[field] = data[field];
58
- }
59
- return signature;
60
- }
61
- function isSameState(a, b) {
62
- if (!a || !b)
63
- return false;
64
- const keys = Object.keys(a);
65
- if (keys.length !== Object.keys(b).length)
66
- return false;
67
- return keys.every((k) => a[k] === b[k]);
68
- }
69
- /** Deduplicate deltas to the same entity — keep meaningful state transitions only */
70
- export function deduplicateDeltas(ctx, deltas) {
71
- const byEntity = new Map();
72
- for (const d of deltas) {
73
- const key = `${d.modelName}:${d.modelId}`;
74
- if (!byEntity.has(key))
75
- byEntity.set(key, []);
76
- byEntity.get(key).push(d);
77
- }
78
- const result = [];
79
- for (const entityDeltas of byEntity.values()) {
80
- const sorted = entityDeltas.sort((a, b) => a.id - b.id);
81
- // DELETE wins — it's the final state
82
- const del = sorted.find((d) => d.actionType === 'D');
83
- if (del) {
84
- result.push(del);
85
- continue;
86
- }
87
- // Keep deltas that represent different states
88
- const unique = [];
89
- let prev = null;
90
- for (const d of sorted) {
91
- const sig = extractStateSignature(ctx, d);
92
- if (!isSameState(prev, sig)) {
93
- unique.push(d);
94
- prev = sig;
95
- }
96
- }
97
- if (unique.length > 0) {
98
- result.push(...unique);
99
- }
100
- else {
101
- // `sorted` is never empty (every byEntity bucket gets at least one
102
- // delta pushed) — the guard only narrows the indexed access.
103
- const last = sorted.at(-1);
104
- if (last)
105
- result.push(last);
106
- }
107
- }
108
- return result.sort((a, b) => a.id - b.id);
109
- }
110
- /**
111
- * Performs per-delta bookkeeping and enqueues the delta. Returns `true` when
112
- * the delta was pushed onto `pendingDeltas` — a regular batchable insert,
113
- * update, covering, or delete that a later flush must drain — and `false` when
114
- * it was skipped as a duplicate, deferred into the bootstrap queue, or handled
115
- * immediately (a 'G'/'S' sync-group change). It does not schedule the flush
116
- * itself; the caller chooses whether to debounce live traffic or flush a
117
- * catch-up frame atomically.
118
- */
119
- export function enqueueDelta(ctx, delta, options = {}) {
120
- // Dedup guard — skip already-processed deltas. The `applied` watermark is a
121
- // valid skip threshold only for in-order live traffic; an authoritative
122
- // catch-up frame bypasses it, so an out-of-order live delta that advanced the
123
- // watermark can't cause the frame's lower ids to be dropped silently.
124
- if (!options.authoritative && delta.id > 0 && delta.id <= ctx.highestProcessedSyncId) {
125
- return false;
126
- }
127
- // Confirm awaiting transactions via sync ID threshold (before batching)
128
- ctx.onDeltaReceived(delta.id, delta.transactionId, delta.correlationId);
129
- // Queue during active bootstrap
130
- if (ctx.bootstrapDeltaQueue !== null) {
131
- ctx.bootstrapDeltaQueue.push(delta);
132
- return false;
133
- }
134
- // Advance watermark
135
- ctx.advanceApplied(delta.id);
136
- // Sync group added — handle immediately. Accepts both the batched
137
- // (addedGroups/removedGroups) and incremental (group/userId) payloads. This
138
- // is deliberately not fire-and-forget: the watermark has already advanced, so
139
- // a rejected handler (a failed security clear) must trigger the fallback
140
- // rather than vanish.
141
- if (delta.actionType === 'G') {
142
- void ctx.handleSyncGroupChange(delta).catch((error) => {
143
- handleGroupHandlerFailure(ctx, delta, error);
144
- });
145
- return false;
146
- }
147
- // Sync group removed — handle immediately. Clears affected local state
148
- // and forces re-bootstrap with the updated group list. Same fallback:
149
- // a failed revocation clear escalates instead of leaving revoked rows.
150
- if (delta.actionType === 'S') {
151
- void ctx.handleGroupRemoved(delta).catch((error) => {
152
- handleGroupHandlerFailure(ctx, delta, error);
153
- });
154
- return false;
155
- }
156
- // Delete — run the cascade cancel immediately (O(1) through the foreign-key
157
- // index; it must run before any later update on the same model lands, so
158
- // pending update transactions for soon-deleted children don't race their
159
- // parent's delete). The persistence and pool write still goes through the
160
- // same batched path as updates: flushing each delete on its own produced one
161
- // store write, one pool mutation, and one `models:changed` event per row, so
162
- // deleting a parent with many children fanned out into many of each, whereas
163
- // the batched path collapses them into one per flush. Deduplication in
164
- // `flushPendingDeltas` handles an update-then-delete on the same model by
165
- // replaying in arrival order.
166
- if (delta.actionType === 'D') {
167
- ctx.cascadeCancelTransactionsForDeletedParent(delta.modelName, delta.modelId);
168
- }
169
- ctx.pendingDeltas.push(delta);
170
- return true;
171
- }
172
- /** Debounce a flush for live single-delta traffic. */
173
- export function scheduleDeltaFlush(ctx) {
174
- if (ctx.batchTimer)
175
- clearTimeout(ctx.batchTimer);
176
- if (ctx.pendingDeltas.length >= ctx.smartSyncOptions.maxBatchSize) {
177
- void ctx.flushPendingDeltas().catch(ctx.handleFlushError);
178
- }
179
- else {
180
- ctx.batchTimer = setTimeout(() => {
181
- void ctx.flushPendingDeltas().catch(ctx.handleFlushError);
182
- }, ctx.smartSyncOptions.batchingDelay);
183
- }
184
- }
185
- /**
186
- * Flushes the queued deltas: deduplicates them, applies custom-entity deltas
187
- * straight to the pool, writes the rest to the local store and then the pool,
188
- * and advances the acknowledgement cursor once the store write has committed.
189
- */
190
- export async function flushPendingDeltas(ctx) {
191
- if (ctx.pendingDeltas.length === 0)
192
- return;
193
- const deduplicatedDeltas = ctx.deduplicateDeltas(ctx.pendingDeltas);
194
- // Custom entities → apply straight to the pool, skipping the local store.
195
- const customDeltas = deduplicatedDeltas.filter((d) => ctx.isCustomEntity(d.modelName));
196
- if (customDeltas.length > 0) {
197
- runInAction(() => {
198
- for (const delta of customDeltas) {
199
- const data = typeof delta.data === 'string'
200
- ? JSON.parse(delta.data)
201
- : (delta.data);
202
- // 'C' (Covering) is treated identically to 'I' here — the client
203
- // gained permission to see the entity, so we insert it into the
204
- // pool as if newly created.
205
- if (delta.actionType === 'I' || delta.actionType === 'U' || delta.actionType === 'C') {
206
- const existing = ctx.objectPool.get(delta.modelId);
207
- if (existing) {
208
- existing.updateFromData(data);
209
- }
210
- else {
211
- const model = ctx.createCustomEntity(delta.modelName, delta.modelId, data);
212
- if (model) {
213
- model.markAsPersisted();
214
- ctx.objectPool.add(model, ModelScope.live);
215
- }
216
- }
217
- }
218
- else if (delta.actionType === 'D') {
219
- ctx.objectPool.remove(delta.modelId);
220
- }
221
- }
222
- });
223
- }
224
- // Regular deltas → the local store, then the pool.
225
- // 'G' and 'S' deltas are handled earlier (handleSyncGroupChange /
226
- // handleGroupRemoved) and never reach here, though the persistence
227
- // signature accepts them defensively.
228
- const regularDeltas = deduplicatedDeltas.filter((d) => !ctx.isCustomEntity(d.modelName));
229
- const batch = await ctx.processDeltaBatch(regularDeltas.map((d) => ({
230
- syncId: d.id,
231
- actionType: d.actionType,
232
- modelName: d.modelName,
233
- modelId: d.modelId,
234
- data: typeof d.data === 'string' ? JSON.parse(d.data) : d.data,
235
- // Thread `transactionId` through so the receive layer can recognize
236
- // echoes of locally-applied transactions and skip the pool mutation.
237
- transactionId: d.transactionId,
238
- })));
239
- const dbResults = batch.results;
240
- // Apply the batch results to the in-memory pool.
241
- ctx.applyDeltaBatchToPool(dbResults);
242
- // Acknowledge and advance the sync cursor, gated on persistence.
243
- //
244
- // We must acknowledge `persistedSyncId` — the high-water mark of deltas whose
245
- // store transaction actually committed — not the input batch's last delta id.
246
- // Acknowledging the input range would advance the server's view past deltas
247
- // that never persisted; the next catch-up would then send the advanced cursor,
248
- // the server would answer "you're up to date", and the unpersisted delta would
249
- // be lost. The cursor and the persisted state must move together.
250
- const persistedSyncId = batch.persistedSyncId;
251
- if (persistedSyncId > ctx.lastAckedId) {
252
- ctx.acknowledge(persistedSyncId);
253
- ctx.advancePersisted(persistedSyncId);
254
- }
255
- // Cache invalidation happens automatically via the 'models:changed' event.
256
- ctx.pendingDeltas = [];
257
- if (ctx.batchTimer) {
258
- clearTimeout(ctx.batchTimer);
259
- ctx.batchTimer = null;
260
- }
261
- }
@@ -1,113 +0,0 @@
1
- /**
2
- * Handles the delta types that change which sync groups a session can see. A
3
- * sync group is a fan-out scope the server uses to decide which entities a
4
- * client receives. When a session's membership changes, these handlers update
5
- * the client's subscription list; when access is revoked, they clear cached
6
- * data and trigger a full re-bootstrap so revoked rows cannot linger on the
7
- * device.
8
- *
9
- * Every handler takes a {@link GroupChangeContext}, the narrow facade through
10
- * which it reaches the client's local storage and connection lifecycle hooks.
11
- */
12
- import type { SyncDelta, SyncGroupChangePayload, GroupAddedPayload } from './SyncWebSocket.js';
13
- /**
14
- * The collaborators the group-change handlers depend on. It gathers the
15
- * client's local storage, in-memory pool, and connection lifecycle hooks
16
- * behind one narrow interface, so the handlers stay decoupled from the larger
17
- * store that supplies them.
18
- */
19
- export interface GroupChangeContext {
20
- /**
21
- * Local persistence. Performs the security clear, reads and writes the
22
- * subscription metadata, and sets the flag that forces a full bootstrap.
23
- */
24
- readonly database: {
25
- clear(): Promise<void>;
26
- getWorkspaceMetadata(): Promise<{
27
- subscribedSyncGroups?: string[];
28
- } | null>;
29
- updateWorkspaceMetadata(metadata: {
30
- subscribedSyncGroups: string[];
31
- }): Promise<void>;
32
- markRequiresFullBootstrap(): void;
33
- };
34
- /** The in-memory object cache, cleared alongside local storage when access is revoked. */
35
- readonly objectPool: {
36
- clear(): void;
37
- };
38
- /** Returns the sync groups the live connection is currently subscribed to. */
39
- getSubscribedSyncGroups(): readonly string[];
40
- /**
41
- * Returns the session's authoritative sync groups, resolved from the current
42
- * user context via {@link resolveSyncGroups}; null when no user context has
43
- * been set yet.
44
- */
45
- getCurrentSyncGroups(): readonly string[] | null;
46
- /**
47
- * Returns the session's bootstrap mode. A value of 'none' means the
48
- * participant never pulls a baseline, so it never re-bootstraps.
49
- */
50
- getBootstrapMode(): 'full' | 'none' | undefined;
51
- /** Disconnects the live connection, one step of the forced re-bootstrap cycle. */
52
- disconnectWebSocket(): void;
53
- /** Emits a connection lifecycle event to any registered listener; a no-op when none is set. */
54
- emitConnectionEvent(event: string): void;
55
- handleGroupAdded(payload: GroupAddedPayload, syncId: number): Promise<void>;
56
- computeUpdatedSyncGroups(payload: SyncGroupChangePayload): string[];
57
- forceFullRebootstrap(): void;
58
- }
59
- /**
60
- * Handles a 'G' (group-change) delta. The server sends two shapes of this
61
- * delta, told apart by the payload:
62
- *
63
- * Incremental — `{ group, userId }`: the recipient was added to a single
64
- * sync group. No re-bootstrap follows; the newly visible entities arrive as
65
- * ordinary 'C' (covering) deltas through the normal insert path.
66
- *
67
- * Full diff — `{ addedGroups, removedGroups }`: one delta carrying the whole
68
- * membership change. This forces a full re-bootstrap (disconnect, reconnect,
69
- * and refetch), clearing cached data first if any group was removed.
70
- */
71
- export declare function handleSyncGroupChange(ctx: GroupChangeContext, delta: SyncDelta): Promise<void>;
72
- /**
73
- * Handles an incremental group-added delta. It records the new sync group in
74
- * the subscription metadata without forcing a re-bootstrap; the server then
75
- * sends a 'C' (covering) delta for each newly visible entity, which flows
76
- * through the normal insert path.
77
- */
78
- export declare function handleGroupAdded(ctx: GroupChangeContext, payload: GroupAddedPayload, syncId: number): Promise<void>;
79
- /**
80
- * Handles an 'S' (group-removed) delta, which signals the recipient has lost
81
- * access to a sync group. The client does not track which entities belong to
82
- * which group, so it cannot purge only the affected rows; instead it clears
83
- * local state and forces a re-bootstrap with the updated group list.
84
- */
85
- export declare function handleGroupRemoved(ctx: GroupChangeContext, delta: SyncDelta): Promise<void>;
86
- /** Computes the new sync-group set after applying the additions and removals in a diff. */
87
- export declare function computeUpdatedSyncGroups(ctx: GroupChangeContext, payload: SyncGroupChangePayload): string[];
88
- /**
89
- * Forces a full re-bootstrap by marking local storage as needing one,
90
- * disconnecting, and emitting a connection lifecycle event that the reconnect
91
- * path acts on. Does nothing for participants whose bootstrap mode is 'none':
92
- * they never pull a baseline, so after a trigger such as a sync-group shrink or
93
- * an access revocation they rely on covering deltas to repopulate the data they
94
- * subscribe to.
95
- */
96
- export declare function forceFullRebootstrap(ctx: GroupChangeContext): void;
97
- /**
98
- * Resolves the sync-group list this session subscribes to, and is the single
99
- * place that decision is made. The server-issued `context.syncGroups` is
100
- * authoritative; when it is absent, the session subscribes to no explicit
101
- * groups. {@link checkSyncGroupShrinkage} and connection setup both read
102
- * through here, so the live subscription and the access-revocation check can
103
- * never disagree.
104
- */
105
- export declare function resolveSyncGroups(context: {
106
- syncGroups?: readonly string[];
107
- }): readonly string[];
108
- /**
109
- * Compares the session's current sync groups against the set stored from the
110
- * last session. If any group is now missing, access has narrowed, so this
111
- * clears cached data and forces a full bootstrap before recording the new set.
112
- */
113
- export declare function checkSyncGroupShrinkage(ctx: GroupChangeContext): Promise<void>;
@@ -1,242 +0,0 @@
1
- /**
2
- * Handles the delta types that change which sync groups a session can see. A
3
- * sync group is a fan-out scope the server uses to decide which entities a
4
- * client receives. When a session's membership changes, these handlers update
5
- * the client's subscription list; when access is revoked, they clear cached
6
- * data and trigger a full re-bootstrap so revoked rows cannot linger on the
7
- * device.
8
- *
9
- * Every handler takes a {@link GroupChangeContext}, the narrow facade through
10
- * which it reaches the client's local storage and connection lifecycle hooks.
11
- */
12
- import { getContext } from '../context.js';
13
- /**
14
- * Marker returned when a group-change payload cannot be parsed, kept distinct
15
- * from a valid null or absent payload, which the handlers accept normally.
16
- */
17
- const MALFORMED_PAYLOAD = Symbol('malformed-group-change-payload');
18
- /**
19
- * Parses a group-change delta payload without ever throwing. The server sends
20
- * these as JSON strings. If a frame is corrupt, this returns
21
- * {@link MALFORMED_PAYLOAD} rather than raising, because an error escaping here
22
- * would leave the delta pipeline after the watermark has already advanced. The
23
- * delta is never re-delivered, so the security clear it carried would be lost.
24
- */
25
- function parseGroupChangePayload(delta) {
26
- if (typeof delta.data !== 'string')
27
- return delta.data;
28
- try {
29
- return JSON.parse(delta.data);
30
- }
31
- catch (error) {
32
- getContext().logger.debug('[BaseSyncedStore] Malformed group-change payload', {
33
- syncId: delta.id,
34
- actionType: delta.actionType,
35
- error: error instanceof Error ? error.message : String(error),
36
- });
37
- return MALFORMED_PAYLOAD;
38
- }
39
- }
40
- /**
41
- * Fallback for a group-change delta that could not be read. Because we know
42
- * access changed but not how, this treats it as a revocation: it clears cached
43
- * data from both local storage and the in-memory pool, then forces a full
44
- * re-bootstrap from the server.
45
- */
46
- async function clearForUnknownGroupChange(ctx, delta, kind) {
47
- getContext().logger.debug(`[BaseSyncedStore] Unreadable ${kind} payload — clearing cached data and re-bootstrapping`, { syncId: delta.id });
48
- // Revoked data must not persist if the device goes offline before the
49
- // re-bootstrap, the same reasoning as the explicit removed-groups path.
50
- await ctx.database.clear();
51
- ctx.objectPool.clear();
52
- ctx.forceFullRebootstrap();
53
- }
54
- /**
55
- * Handles a 'G' (group-change) delta. The server sends two shapes of this
56
- * delta, told apart by the payload:
57
- *
58
- * Incremental — `{ group, userId }`: the recipient was added to a single
59
- * sync group. No re-bootstrap follows; the newly visible entities arrive as
60
- * ordinary 'C' (covering) deltas through the normal insert path.
61
- *
62
- * Full diff — `{ addedGroups, removedGroups }`: one delta carrying the whole
63
- * membership change. This forces a full re-bootstrap (disconnect, reconnect,
64
- * and refetch), clearing cached data first if any group was removed.
65
- */
66
- export async function handleSyncGroupChange(ctx, delta) {
67
- const raw = parseGroupChangePayload(delta);
68
- if (raw === MALFORMED_PAYLOAD) {
69
- // The payload is unreadable, so we cannot tell which groups changed, and
70
- // this delta will never be re-delivered because the watermark has already
71
- // advanced. Fall back to the safe direction: assume a revocation, clear
72
- // cached data, and rebuild from the server rather than throwing.
73
- await clearForUnknownGroupChange(ctx, delta, 'sync-group change');
74
- return;
75
- }
76
- const rawObj = (raw ?? {});
77
- // Detect incremental payload shape: { group, userId }
78
- if (typeof rawObj.group === 'string' && typeof rawObj.userId === 'string') {
79
- const incremental = {
80
- group: rawObj.group,
81
- userId: rawObj.userId,
82
- };
83
- await ctx.handleGroupAdded(incremental, delta.id);
84
- return;
85
- }
86
- // Full-diff payload: { addedGroups, removedGroups }
87
- const payload = {
88
- removedGroups: rawObj.removedGroups ?? [],
89
- addedGroups: rawObj.addedGroups ?? [],
90
- };
91
- getContext().logger.info('[BaseSyncedStore] Sync group change received (legacy)', {
92
- removedGroups: payload.removedGroups,
93
- addedGroups: payload.addedGroups,
94
- syncId: delta.id,
95
- });
96
- // If any groups were removed, clear cached data immediately so revoked data
97
- // cannot persist should the device go offline before the re-bootstrap
98
- // completes.
99
- if (payload.removedGroups.length > 0) {
100
- await ctx.database.clear();
101
- ctx.objectPool.clear();
102
- getContext().logger.info('[BaseSyncedStore] Cleared cached data due to revoked sync groups', {
103
- removedGroups: payload.removedGroups,
104
- });
105
- }
106
- const updatedGroups = ctx.computeUpdatedSyncGroups(payload);
107
- await ctx.database.updateWorkspaceMetadata({ subscribedSyncGroups: updatedGroups });
108
- ctx.forceFullRebootstrap();
109
- }
110
- /**
111
- * Handles an incremental group-added delta. It records the new sync group in
112
- * the subscription metadata without forcing a re-bootstrap; the server then
113
- * sends a 'C' (covering) delta for each newly visible entity, which flows
114
- * through the normal insert path.
115
- */
116
- export async function handleGroupAdded(ctx, payload, syncId) {
117
- getContext().logger.info('[BaseSyncedStore] Group added (incremental)', {
118
- group: payload.group,
119
- syncId,
120
- });
121
- const current = new Set(ctx.getSubscribedSyncGroups());
122
- current.add(payload.group);
123
- await ctx.database.updateWorkspaceMetadata({ subscribedSyncGroups: Array.from(current) });
124
- // No forceFullRebootstrap() here; the covering deltas will bring the entities.
125
- }
126
- /**
127
- * Handles an 'S' (group-removed) delta, which signals the recipient has lost
128
- * access to a sync group. The client does not track which entities belong to
129
- * which group, so it cannot purge only the affected rows; instead it clears
130
- * local state and forces a re-bootstrap with the updated group list.
131
- */
132
- export async function handleGroupRemoved(ctx, delta) {
133
- const raw = parseGroupChangePayload(delta);
134
- if (raw === MALFORMED_PAYLOAD) {
135
- // The payload is unreadable: access was revoked but we cannot tell which
136
- // group. Fall back to a full clear, the safe direction for an
137
- // access-revocation delta, rather than throwing.
138
- await clearForUnknownGroupChange(ctx, delta, 'group-removed');
139
- return;
140
- }
141
- const rawObj = (raw ?? {});
142
- const groupKey = typeof rawObj.group === 'string' ? rawObj.group : undefined;
143
- if (!groupKey) {
144
- getContext().logger.debug('[BaseSyncedStore] Group removed delta missing group key', {
145
- syncId: delta.id,
146
- });
147
- return;
148
- }
149
- getContext().logger.info('[BaseSyncedStore] Group removed', {
150
- group: groupKey,
151
- syncId: delta.id,
152
- });
153
- // Clear cached data before the re-bootstrap so revoked-group data cannot
154
- // persist if the device goes offline between receiving this delta and
155
- // completing the re-bootstrap.
156
- await ctx.database.clear();
157
- ctx.objectPool.clear();
158
- // Update subscription metadata so the re-bootstrap fetches the
159
- // correct set of groups.
160
- const current = new Set(ctx.getSubscribedSyncGroups());
161
- current.delete(groupKey);
162
- await ctx.database.updateWorkspaceMetadata({ subscribedSyncGroups: Array.from(current) });
163
- ctx.forceFullRebootstrap();
164
- }
165
- /** Computes the new sync-group set after applying the additions and removals in a diff. */
166
- export function computeUpdatedSyncGroups(ctx, payload) {
167
- const current = new Set(ctx.getSubscribedSyncGroups());
168
- for (const g of payload.removedGroups)
169
- current.delete(g);
170
- for (const g of payload.addedGroups)
171
- current.add(g);
172
- return Array.from(current);
173
- }
174
- /**
175
- * Forces a full re-bootstrap by marking local storage as needing one,
176
- * disconnecting, and emitting a connection lifecycle event that the reconnect
177
- * path acts on. Does nothing for participants whose bootstrap mode is 'none':
178
- * they never pull a baseline, so after a trigger such as a sync-group shrink or
179
- * an access revocation they rely on covering deltas to repopulate the data they
180
- * subscribe to.
181
- */
182
- export function forceFullRebootstrap(ctx) {
183
- if (ctx.getBootstrapMode() === 'none') {
184
- getContext().logger.info('[BaseSyncedStore] forceFullRebootstrap skipped (bootstrapMode=none)');
185
- return;
186
- }
187
- ctx.database.markRequiresFullBootstrap();
188
- ctx.disconnectWebSocket();
189
- ctx.emitConnectionEvent('WS_DISCONNECTED');
190
- }
191
- /**
192
- * Resolves the sync-group list this session subscribes to, and is the single
193
- * place that decision is made. The server-issued `context.syncGroups` is
194
- * authoritative; when it is absent, the session subscribes to no explicit
195
- * groups. {@link checkSyncGroupShrinkage} and connection setup both read
196
- * through here, so the live subscription and the access-revocation check can
197
- * never disagree.
198
- */
199
- export function resolveSyncGroups(context) {
200
- if (context.syncGroups && context.syncGroups.length > 0) {
201
- return context.syncGroups;
202
- }
203
- return [];
204
- }
205
- /**
206
- * Compares the session's current sync groups against the set stored from the
207
- * last session. If any group is now missing, access has narrowed, so this
208
- * clears cached data and forces a full bootstrap before recording the new set.
209
- */
210
- export async function checkSyncGroupShrinkage(ctx) {
211
- const currentSyncGroups = ctx.getCurrentSyncGroups();
212
- if (!currentSyncGroups)
213
- return;
214
- try {
215
- const metadata = await ctx.database.getWorkspaceMetadata();
216
- const stored = metadata?.subscribedSyncGroups ?? [];
217
- if (stored.length === 0)
218
- return;
219
- const currentGroups = new Set(currentSyncGroups);
220
- const removedGroups = stored.filter((g) => !currentGroups.has(g));
221
- if (removedGroups.length > 0) {
222
- getContext().logger.info('[BaseSyncedStore] Sync groups shrank — forcing full bootstrap', {
223
- removedGroups,
224
- storedCount: stored.length,
225
- currentCount: currentGroups.size,
226
- });
227
- // Clear cached data before the re-bootstrap so revoked-group data cannot
228
- // persist if the device goes offline first.
229
- await ctx.database.clear();
230
- ctx.objectPool.clear();
231
- ctx.database.markRequiresFullBootstrap();
232
- }
233
- await ctx.database.updateWorkspaceMetadata({
234
- subscribedSyncGroups: Array.from(currentGroups),
235
- });
236
- }
237
- catch (error) {
238
- getContext().logger.debug('[BaseSyncedStore] Failed to check sync group shrinkage', {
239
- error: error instanceof Error ? error.message : String(error),
240
- });
241
- }
242
- }