@rocicorp/zero 0.26.0-canary.8 → 0.26.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 (275) hide show
  1. package/out/ast-to-zql/src/ast-to-zql.d.ts.map +1 -1
  2. package/out/ast-to-zql/src/ast-to-zql.js +16 -27
  3. package/out/ast-to-zql/src/ast-to-zql.js.map +1 -1
  4. package/out/otel/src/log-options.d.ts +2 -2
  5. package/out/replicache/src/bg-interval.d.ts.map +1 -1
  6. package/out/replicache/src/bg-interval.js +3 -0
  7. package/out/replicache/src/bg-interval.js.map +1 -1
  8. package/out/shared/src/arrays.js +1 -1
  9. package/out/shared/src/arrays.js.map +1 -1
  10. package/out/shared/src/browser-env.js +0 -4
  11. package/out/shared/src/browser-env.js.map +1 -1
  12. package/out/shared/src/btree-set.js +4 -1
  13. package/out/shared/src/btree-set.js.map +1 -1
  14. package/out/shared/src/options.js +1 -1
  15. package/out/shared/src/options.js.map +1 -1
  16. package/out/shared/src/queue.js +1 -1
  17. package/out/shared/src/queue.js.map +1 -1
  18. package/out/z2s/src/compiler.d.ts.map +1 -1
  19. package/out/z2s/src/compiler.js +13 -11
  20. package/out/z2s/src/compiler.js.map +1 -1
  21. package/out/zero/package.json.js +1 -1
  22. package/out/zero/src/react.js +1 -3
  23. package/out/zero/src/react.js.map +1 -1
  24. package/out/zero-cache/src/auth/read-authorizer.js +0 -7
  25. package/out/zero-cache/src/auth/read-authorizer.js.map +1 -1
  26. package/out/zero-cache/src/config/network.d.ts +3 -2
  27. package/out/zero-cache/src/config/network.d.ts.map +1 -1
  28. package/out/zero-cache/src/config/network.js +9 -2
  29. package/out/zero-cache/src/config/network.js.map +1 -1
  30. package/out/zero-cache/src/config/server-context.d.ts +16 -0
  31. package/out/zero-cache/src/config/server-context.d.ts.map +1 -0
  32. package/out/zero-cache/src/config/server-context.js +32 -0
  33. package/out/zero-cache/src/config/server-context.js.map +1 -0
  34. package/out/zero-cache/src/config/zero-config.d.ts +3 -3
  35. package/out/zero-cache/src/config/zero-config.d.ts.map +1 -1
  36. package/out/zero-cache/src/config/zero-config.js +2 -6
  37. package/out/zero-cache/src/config/zero-config.js.map +1 -1
  38. package/out/zero-cache/src/db/migration.d.ts.map +1 -1
  39. package/out/zero-cache/src/db/migration.js +40 -51
  40. package/out/zero-cache/src/db/migration.js.map +1 -1
  41. package/out/zero-cache/src/db/run-transaction.d.ts +17 -0
  42. package/out/zero-cache/src/db/run-transaction.d.ts.map +1 -0
  43. package/out/zero-cache/src/db/run-transaction.js +24 -0
  44. package/out/zero-cache/src/db/run-transaction.js.map +1 -0
  45. package/out/zero-cache/src/db/transaction-pool.d.ts.map +1 -1
  46. package/out/zero-cache/src/db/transaction-pool.js +3 -3
  47. package/out/zero-cache/src/db/transaction-pool.js.map +1 -1
  48. package/out/zero-cache/src/scripts/decommission.d.ts +1 -1
  49. package/out/zero-cache/src/scripts/deploy-permissions.js +2 -1
  50. package/out/zero-cache/src/scripts/deploy-permissions.js.map +1 -1
  51. package/out/zero-cache/src/scripts/permissions.d.ts +1 -1
  52. package/out/zero-cache/src/server/change-streamer.d.ts.map +1 -1
  53. package/out/zero-cache/src/server/change-streamer.js +6 -2
  54. package/out/zero-cache/src/server/change-streamer.js.map +1 -1
  55. package/out/zero-cache/src/server/main.js +1 -1
  56. package/out/zero-cache/src/server/main.js.map +1 -1
  57. package/out/zero-cache/src/server/runner/run-worker.d.ts.map +1 -1
  58. package/out/zero-cache/src/server/runner/run-worker.js +7 -3
  59. package/out/zero-cache/src/server/runner/run-worker.js.map +1 -1
  60. package/out/zero-cache/src/services/change-source/common/backfill-manager.d.ts +1 -1
  61. package/out/zero-cache/src/services/change-source/common/backfill-manager.js +4 -4
  62. package/out/zero-cache/src/services/change-source/common/backfill-manager.js.map +1 -1
  63. package/out/zero-cache/src/services/change-source/common/replica-schema.d.ts.map +1 -1
  64. package/out/zero-cache/src/services/change-source/common/replica-schema.js +11 -0
  65. package/out/zero-cache/src/services/change-source/common/replica-schema.js.map +1 -1
  66. package/out/zero-cache/src/services/change-source/custom/change-source.d.ts +5 -2
  67. package/out/zero-cache/src/services/change-source/custom/change-source.d.ts.map +1 -1
  68. package/out/zero-cache/src/services/change-source/custom/change-source.js +6 -6
  69. package/out/zero-cache/src/services/change-source/custom/change-source.js.map +1 -1
  70. package/out/zero-cache/src/services/change-source/pg/change-source.d.ts +6 -4
  71. package/out/zero-cache/src/services/change-source/pg/change-source.d.ts.map +1 -1
  72. package/out/zero-cache/src/services/change-source/pg/change-source.js +130 -43
  73. package/out/zero-cache/src/services/change-source/pg/change-source.js.map +1 -1
  74. package/out/zero-cache/src/services/change-source/pg/decommission.d.ts.map +1 -1
  75. package/out/zero-cache/src/services/change-source/pg/decommission.js +2 -1
  76. package/out/zero-cache/src/services/change-source/pg/decommission.js.map +1 -1
  77. package/out/zero-cache/src/services/change-source/pg/initial-sync.d.ts +4 -1
  78. package/out/zero-cache/src/services/change-source/pg/initial-sync.d.ts.map +1 -1
  79. package/out/zero-cache/src/services/change-source/pg/initial-sync.js +35 -10
  80. package/out/zero-cache/src/services/change-source/pg/initial-sync.js.map +1 -1
  81. package/out/zero-cache/src/services/change-source/pg/logical-replication/stream.js +1 -1
  82. package/out/zero-cache/src/services/change-source/pg/logical-replication/stream.js.map +1 -1
  83. package/out/zero-cache/src/services/change-source/pg/schema/init.d.ts.map +1 -1
  84. package/out/zero-cache/src/services/change-source/pg/schema/init.js +10 -0
  85. package/out/zero-cache/src/services/change-source/pg/schema/init.js.map +1 -1
  86. package/out/zero-cache/src/services/change-source/pg/schema/shard.d.ts +6 -3
  87. package/out/zero-cache/src/services/change-source/pg/schema/shard.d.ts.map +1 -1
  88. package/out/zero-cache/src/services/change-source/pg/schema/shard.js +19 -10
  89. package/out/zero-cache/src/services/change-source/pg/schema/shard.js.map +1 -1
  90. package/out/zero-cache/src/services/change-source/protocol/current/data.d.ts +1 -0
  91. package/out/zero-cache/src/services/change-source/protocol/current/data.d.ts.map +1 -1
  92. package/out/zero-cache/src/services/change-source/protocol/current/data.js +4 -2
  93. package/out/zero-cache/src/services/change-source/protocol/current/data.js.map +1 -1
  94. package/out/zero-cache/src/services/change-source/protocol/current/downstream.d.ts +3 -0
  95. package/out/zero-cache/src/services/change-source/protocol/current/downstream.d.ts.map +1 -1
  96. package/out/zero-cache/src/services/change-source/protocol/current/status.d.ts +6 -4
  97. package/out/zero-cache/src/services/change-source/protocol/current/status.d.ts.map +1 -1
  98. package/out/zero-cache/src/services/change-source/protocol/current/status.js.map +1 -1
  99. package/out/zero-cache/src/services/change-streamer/backup-monitor.d.ts +2 -2
  100. package/out/zero-cache/src/services/change-streamer/backup-monitor.d.ts.map +1 -1
  101. package/out/zero-cache/src/services/change-streamer/backup-monitor.js +30 -12
  102. package/out/zero-cache/src/services/change-streamer/backup-monitor.js.map +1 -1
  103. package/out/zero-cache/src/services/change-streamer/change-streamer-service.js +23 -3
  104. package/out/zero-cache/src/services/change-streamer/change-streamer-service.js.map +1 -1
  105. package/out/zero-cache/src/services/change-streamer/change-streamer.d.ts +1 -0
  106. package/out/zero-cache/src/services/change-streamer/change-streamer.d.ts.map +1 -1
  107. package/out/zero-cache/src/services/change-streamer/forwarder.js +1 -1
  108. package/out/zero-cache/src/services/change-streamer/forwarder.js.map +1 -1
  109. package/out/zero-cache/src/services/change-streamer/schema/tables.d.ts +1 -1
  110. package/out/zero-cache/src/services/change-streamer/schema/tables.d.ts.map +1 -1
  111. package/out/zero-cache/src/services/change-streamer/schema/tables.js +12 -4
  112. package/out/zero-cache/src/services/change-streamer/schema/tables.js.map +1 -1
  113. package/out/zero-cache/src/services/change-streamer/storer.d.ts +11 -2
  114. package/out/zero-cache/src/services/change-streamer/storer.d.ts.map +1 -1
  115. package/out/zero-cache/src/services/change-streamer/storer.js +80 -42
  116. package/out/zero-cache/src/services/change-streamer/storer.js.map +1 -1
  117. package/out/zero-cache/src/services/litestream/commands.d.ts +1 -1
  118. package/out/zero-cache/src/services/litestream/commands.d.ts.map +1 -1
  119. package/out/zero-cache/src/services/litestream/commands.js +2 -1
  120. package/out/zero-cache/src/services/litestream/commands.js.map +1 -1
  121. package/out/zero-cache/src/services/mutagen/mutagen.d.ts.map +1 -1
  122. package/out/zero-cache/src/services/mutagen/mutagen.js +22 -17
  123. package/out/zero-cache/src/services/mutagen/mutagen.js.map +1 -1
  124. package/out/zero-cache/src/services/replicator/schema/replication-state.d.ts +10 -1
  125. package/out/zero-cache/src/services/replicator/schema/replication-state.d.ts.map +1 -1
  126. package/out/zero-cache/src/services/replicator/schema/replication-state.js +49 -9
  127. package/out/zero-cache/src/services/replicator/schema/replication-state.js.map +1 -1
  128. package/out/zero-cache/src/services/running-state.d.ts +1 -0
  129. package/out/zero-cache/src/services/running-state.d.ts.map +1 -1
  130. package/out/zero-cache/src/services/running-state.js +3 -0
  131. package/out/zero-cache/src/services/running-state.js.map +1 -1
  132. package/out/zero-cache/src/services/view-syncer/cvr-purger.d.ts.map +1 -1
  133. package/out/zero-cache/src/services/view-syncer/cvr-purger.js +32 -28
  134. package/out/zero-cache/src/services/view-syncer/cvr-purger.js.map +1 -1
  135. package/out/zero-cache/src/services/view-syncer/cvr-store.d.ts.map +1 -1
  136. package/out/zero-cache/src/services/view-syncer/cvr-store.js +329 -155
  137. package/out/zero-cache/src/services/view-syncer/cvr-store.js.map +1 -1
  138. package/out/zero-cache/src/services/view-syncer/cvr.d.ts.map +1 -1
  139. package/out/zero-cache/src/services/view-syncer/cvr.js +387 -345
  140. package/out/zero-cache/src/services/view-syncer/cvr.js.map +1 -1
  141. package/out/zero-cache/src/services/view-syncer/pipeline-driver.d.ts.map +1 -1
  142. package/out/zero-cache/src/services/view-syncer/pipeline-driver.js +68 -16
  143. package/out/zero-cache/src/services/view-syncer/pipeline-driver.js.map +1 -1
  144. package/out/zero-cache/src/services/view-syncer/row-record-cache.d.ts.map +1 -1
  145. package/out/zero-cache/src/services/view-syncer/row-record-cache.js +13 -8
  146. package/out/zero-cache/src/services/view-syncer/row-record-cache.js.map +1 -1
  147. package/out/zero-cache/src/services/view-syncer/tracer.d.ts +2 -0
  148. package/out/zero-cache/src/services/view-syncer/tracer.d.ts.map +1 -0
  149. package/out/zero-cache/src/services/view-syncer/tracer.js +7 -0
  150. package/out/zero-cache/src/services/view-syncer/tracer.js.map +1 -0
  151. package/out/zero-cache/src/services/view-syncer/view-syncer.d.ts.map +1 -1
  152. package/out/zero-cache/src/services/view-syncer/view-syncer.js +58 -43
  153. package/out/zero-cache/src/services/view-syncer/view-syncer.js.map +1 -1
  154. package/out/zero-cache/src/types/pg.js +0 -4
  155. package/out/zero-cache/src/types/pg.js.map +1 -1
  156. package/out/zero-cache/src/types/streams.d.ts +3 -1
  157. package/out/zero-cache/src/types/streams.d.ts.map +1 -1
  158. package/out/zero-cache/src/types/streams.js +1 -1
  159. package/out/zero-cache/src/types/streams.js.map +1 -1
  160. package/out/zero-cache/src/types/subscription.d.ts +7 -1
  161. package/out/zero-cache/src/types/subscription.d.ts.map +1 -1
  162. package/out/zero-cache/src/types/subscription.js +8 -2
  163. package/out/zero-cache/src/types/subscription.js.map +1 -1
  164. package/out/zero-client/src/client/options.d.ts +7 -7
  165. package/out/zero-client/src/client/options.d.ts.map +1 -1
  166. package/out/zero-client/src/client/options.js.map +1 -1
  167. package/out/zero-client/src/client/query-manager.js +1 -1
  168. package/out/zero-client/src/client/query-manager.js.map +1 -1
  169. package/out/zero-client/src/client/version.js +1 -1
  170. package/out/zero-client/src/client/zero-poke-handler.d.ts +5 -5
  171. package/out/zero-client/src/client/zero-poke-handler.d.ts.map +1 -1
  172. package/out/zero-client/src/client/zero-poke-handler.js +15 -17
  173. package/out/zero-client/src/client/zero-poke-handler.js.map +1 -1
  174. package/out/zero-client/src/client/zero.d.ts +6 -2
  175. package/out/zero-client/src/client/zero.d.ts.map +1 -1
  176. package/out/zero-client/src/client/zero.js +44 -8
  177. package/out/zero-client/src/client/zero.js.map +1 -1
  178. package/out/zero-client/src/mod.d.ts +1 -1
  179. package/out/zero-client/src/mod.d.ts.map +1 -1
  180. package/out/zero-protocol/src/ast.d.ts +2 -9
  181. package/out/zero-protocol/src/ast.d.ts.map +1 -1
  182. package/out/zero-protocol/src/ast.js +15 -32
  183. package/out/zero-protocol/src/ast.js.map +1 -1
  184. package/out/zero-protocol/src/protocol-version.d.ts +1 -1
  185. package/out/zero-protocol/src/protocol-version.d.ts.map +1 -1
  186. package/out/zero-protocol/src/protocol-version.js +5 -2
  187. package/out/zero-protocol/src/protocol-version.js.map +1 -1
  188. package/out/zero-react/src/mod.d.ts +0 -2
  189. package/out/zero-react/src/mod.d.ts.map +1 -1
  190. package/out/zero-react/src/use-query.d.ts +6 -6
  191. package/out/zero-react/src/use-query.d.ts.map +1 -1
  192. package/out/zero-react/src/use-query.js +9 -2
  193. package/out/zero-react/src/use-query.js.map +1 -1
  194. package/out/zero-react/src/zero-provider.d.ts +5 -5
  195. package/out/zero-react/src/zero-provider.d.ts.map +1 -1
  196. package/out/zero-react/src/zero-provider.js.map +1 -1
  197. package/out/zero-solid/src/solid-view.d.ts +0 -42
  198. package/out/zero-solid/src/solid-view.d.ts.map +1 -1
  199. package/out/zero-solid/src/solid-view.js +1 -1
  200. package/out/zero-solid/src/solid-view.js.map +1 -1
  201. package/out/zero-solid/src/use-query.d.ts +4 -4
  202. package/out/zero-solid/src/use-query.d.ts.map +1 -1
  203. package/out/zero-solid/src/use-query.js.map +1 -1
  204. package/out/zero-solid/src/use-zero.d.ts +5 -5
  205. package/out/zero-solid/src/use-zero.d.ts.map +1 -1
  206. package/out/zero-solid/src/use-zero.js.map +1 -1
  207. package/out/zero-types/src/default-types.d.ts +2 -0
  208. package/out/zero-types/src/default-types.d.ts.map +1 -1
  209. package/out/zql/src/builder/builder.d.ts.map +1 -1
  210. package/out/zql/src/builder/builder.js +6 -48
  211. package/out/zql/src/builder/builder.js.map +1 -1
  212. package/out/zql/src/builder/filter.d.ts.map +1 -1
  213. package/out/zql/src/builder/filter.js +0 -1
  214. package/out/zql/src/builder/filter.js.map +1 -1
  215. package/out/zql/src/ivm/array-view.d.ts.map +1 -1
  216. package/out/zql/src/ivm/array-view.js +6 -57
  217. package/out/zql/src/ivm/array-view.js.map +1 -1
  218. package/out/zql/src/ivm/view-apply-change.d.ts +3 -50
  219. package/out/zql/src/ivm/view-apply-change.d.ts.map +1 -1
  220. package/out/zql/src/ivm/view-apply-change.js +105 -358
  221. package/out/zql/src/ivm/view-apply-change.js.map +1 -1
  222. package/out/zql/src/mutate/mutator-registry.d.ts +3 -3
  223. package/out/zql/src/mutate/mutator-registry.d.ts.map +1 -1
  224. package/out/zql/src/mutate/mutator-registry.js.map +1 -1
  225. package/out/zql/src/planner/planner-builder.d.ts.map +1 -1
  226. package/out/zql/src/planner/planner-builder.js +1 -2
  227. package/out/zql/src/planner/planner-builder.js.map +1 -1
  228. package/out/zql/src/query/complete-ordering.js +0 -6
  229. package/out/zql/src/query/complete-ordering.js.map +1 -1
  230. package/out/zql/src/query/expression.d.ts +2 -19
  231. package/out/zql/src/query/expression.d.ts.map +1 -1
  232. package/out/zql/src/query/expression.js +6 -50
  233. package/out/zql/src/query/expression.js.map +1 -1
  234. package/out/zql/src/query/query-delegate-base.js +3 -1
  235. package/out/zql/src/query/query-delegate-base.js.map +1 -1
  236. package/out/zql/src/query/query-impl.d.ts.map +1 -1
  237. package/out/zql/src/query/query-impl.js +8 -12
  238. package/out/zql/src/query/query-impl.js.map +1 -1
  239. package/out/zql/src/query/query-internals.js.map +1 -1
  240. package/out/zql/src/query/query-registry.d.ts +3 -3
  241. package/out/zql/src/query/query-registry.d.ts.map +1 -1
  242. package/out/zql/src/query/query-registry.js.map +1 -1
  243. package/out/zql/src/query/query.d.ts +28 -5
  244. package/out/zql/src/query/query.d.ts.map +1 -1
  245. package/out/zqlite/src/query-builder.d.ts +0 -2
  246. package/out/zqlite/src/query-builder.d.ts.map +1 -1
  247. package/out/zqlite/src/query-builder.js.map +1 -1
  248. package/out/zqlite/src/resolve-scalar-subqueries.d.ts +10 -2
  249. package/out/zqlite/src/resolve-scalar-subqueries.d.ts.map +1 -1
  250. package/out/zqlite/src/resolve-scalar-subqueries.js +41 -9
  251. package/out/zqlite/src/resolve-scalar-subqueries.js.map +1 -1
  252. package/out/zqlite/src/sqlite-cost-model.d.ts.map +1 -1
  253. package/out/zqlite/src/sqlite-cost-model.js +0 -1
  254. package/out/zqlite/src/sqlite-cost-model.js.map +1 -1
  255. package/package.json +3 -5
  256. package/out/zero-cache/src/services/change-source/custom/sync-schema.d.ts +0 -4
  257. package/out/zero-cache/src/services/change-source/custom/sync-schema.d.ts.map +0 -1
  258. package/out/zero-cache/src/services/change-source/custom/sync-schema.js +0 -14
  259. package/out/zero-cache/src/services/change-source/custom/sync-schema.js.map +0 -1
  260. package/out/zero-cache/src/services/change-source/pg/sync-schema.d.ts +0 -5
  261. package/out/zero-cache/src/services/change-source/pg/sync-schema.d.ts.map +0 -1
  262. package/out/zero-cache/src/services/change-source/pg/sync-schema.js +0 -14
  263. package/out/zero-cache/src/services/change-source/pg/sync-schema.js.map +0 -1
  264. package/out/zero-react/src/paging-reducer.d.ts +0 -61
  265. package/out/zero-react/src/paging-reducer.d.ts.map +0 -1
  266. package/out/zero-react/src/paging-reducer.js +0 -77
  267. package/out/zero-react/src/paging-reducer.js.map +0 -1
  268. package/out/zero-react/src/use-rows.d.ts +0 -39
  269. package/out/zero-react/src/use-rows.d.ts.map +0 -1
  270. package/out/zero-react/src/use-rows.js +0 -130
  271. package/out/zero-react/src/use-rows.js.map +0 -1
  272. package/out/zero-react/src/use-zero-virtualizer.d.ts +0 -122
  273. package/out/zero-react/src/use-zero-virtualizer.d.ts.map +0 -1
  274. package/out/zero-react/src/use-zero-virtualizer.js +0 -342
  275. package/out/zero-react/src/use-zero-virtualizer.js.map +0 -1
@@ -13,6 +13,7 @@ import { ClientNotFound, Rehome, SchemaVersionNotSupported, Internal } from "../
13
13
  import { ZeroCache } from "../../../../zero-protocol/src/error-origin-enum.js";
14
14
  import { clampTTL, DEFAULT_TTL_MS } from "../../../../zql/src/query/ttl.js";
15
15
  import { READONLY, READ_COMMITTED } from "../../db/mode-enum.js";
16
+ import { runTx } from "../../db/run-transaction.js";
16
17
  import { TransactionPool } from "../../db/transaction-pool.js";
17
18
  import { recordRowsSynced } from "../../server/anonymous-otel-start.js";
18
19
  import { ProtocolErrorWithLevel } from "../../types/error-with-level.js";
@@ -24,6 +25,16 @@ import "../../../../shared/src/bigint-json.js";
24
25
  import { EMPTY_CVR_VERSION, versionFromString, versionString, queryRecordToQueryRow, cmpVersions } from "./schema/types.js";
25
26
  import { ttlClockFromNumber, ttlClockAsNumber } from "./ttl-clock.js";
26
27
  let flushCounter = 0;
28
+ function convertTTLValues(inactivatedAt, ttl) {
29
+ return {
30
+ ttlInterval: ttl < 0 ? null : ttl / 1e3,
31
+ // INTERVAL needs seconds
32
+ ttlMs: ttl < 0 ? null : ttl,
33
+ // New column stores ms directly
34
+ inactivatedAtTimestamp: inactivatedAt === void 0 ? null : ttlClockFromNumber(ttlClockAsNumber(inactivatedAt) / 1e3),
35
+ inactivatedAtMs: inactivatedAt ?? null
36
+ };
37
+ }
27
38
  const tracer = trace.getTracer("cvr-store", version);
28
39
  function asQuery(row) {
29
40
  const maybeVersion = (s) => s === null ? void 0 : versionFromString(s);
@@ -69,6 +80,10 @@ class CVRStore {
69
80
  #failService;
70
81
  #db;
71
82
  #writes = /* @__PURE__ */ new Set();
83
+ // Stored separately so repeated putInstance() calls (e.g. setClientSchema,
84
+ // setProfileID, and the final call in #flush) replace each other rather than
85
+ // accumulating as independent statements in #writes.
86
+ #pendingInstanceWrite = void 0;
72
87
  #pendingRowRecordUpdates = new CustomKeyMap(
73
88
  rowIDString
74
89
  );
@@ -77,6 +92,9 @@ class CVRStore {
77
92
  #loadAttemptIntervalMs;
78
93
  #maxLoadAttempts;
79
94
  #rowCount = 0;
95
+ #pendingQueryUpdates = /* @__PURE__ */ new Map();
96
+ #pendingDesireUpdates = /* @__PURE__ */ new Map();
97
+ #pendingQueryPartialUpdates = /* @__PURE__ */ new Map();
80
98
  constructor(lc, cvrDb, shard, taskID, cvrID, failService, loadAttemptIntervalMs = LOAD_ATTEMPT_INTERVAL_MS, maxLoadAttempts = MAX_LOAD_ATTEMPTS, deferredRowFlushThreshold = 100, setTimeoutFn = setTimeout) {
81
99
  this.#failService = failService;
82
100
  this.#db = cvrDb;
@@ -98,6 +116,9 @@ class CVRStore {
98
116
  #cvr(table) {
99
117
  return this.#db(`${this.#schema}.${table}`);
100
118
  }
119
+ #updateQueryFields(queryHash, fields) {
120
+ this.#pendingQueryPartialUpdates.set(queryHash, fields);
121
+ }
101
122
  load(lc, lastConnectTime) {
102
123
  return startAsyncSpan(tracer, "cvr.load", async () => {
103
124
  let err;
@@ -134,10 +155,12 @@ class CVRStore {
134
155
  clientSchema: null,
135
156
  profileID: null
136
157
  };
137
- const [instance, clientsRows, queryRows, desiresRows] = await this.#db.begin(READONLY, (tx) => {
138
- lc.debug?.(`CVR tx started after ${Date.now() - start} ms`);
139
- return [
140
- tx`SELECT cvr."version",
158
+ const [instance, clientsRows, queryRows, desiresRows] = await runTx(
159
+ this.#db,
160
+ (tx) => {
161
+ lc.debug?.(`CVR tx started after ${Date.now() - start} ms`);
162
+ return [
163
+ tx`SELECT cvr."version",
141
164
  "lastActive",
142
165
  "ttlClock",
143
166
  "replicaVersion",
@@ -151,13 +174,13 @@ class CVRStore {
151
174
  LEFT JOIN ${this.#cvr("rowsVersion")} AS rows
152
175
  ON cvr."clientGroupID" = rows."clientGroupID"
153
176
  WHERE cvr."clientGroupID" = ${id}`,
154
- tx`SELECT "clientID" FROM ${this.#cvr(
155
- "clients"
156
- )}
177
+ tx`SELECT "clientID" FROM ${this.#cvr(
178
+ "clients"
179
+ )}
157
180
  WHERE "clientGroupID" = ${id}`,
158
- tx`SELECT * FROM ${this.#cvr("queries")}
181
+ tx`SELECT * FROM ${this.#cvr("queries")}
159
182
  WHERE "clientGroupID" = ${id} AND deleted IS DISTINCT FROM true`,
160
- tx`SELECT
183
+ tx`SELECT
161
184
  "clientGroupID",
162
185
  "clientID",
163
186
  "queryHash",
@@ -167,8 +190,10 @@ class CVRStore {
167
190
  "inactivatedAtMs" AS "inactivatedAt"
168
191
  FROM ${this.#cvr("desires")}
169
192
  WHERE "clientGroupID" = ${id}`
170
- ];
171
- });
193
+ ];
194
+ },
195
+ { mode: READONLY }
196
+ );
172
197
  lc.debug?.(
173
198
  `CVR tx completed after ${Date.now() - start} ms (${clientsRows.length} clients, ${queryRows.length} queries, ${desiresRows.length} desires)`
174
199
  );
@@ -332,89 +357,50 @@ class CVRStore {
332
357
  profileID,
333
358
  ttlClock
334
359
  }) {
335
- this.#writes.add({
336
- stats: { instances: 1 },
337
- write: (tx, lastConnectTime) => {
338
- const change = {
339
- clientGroupID: this.#id,
340
- version: versionString(version2),
341
- lastActive,
342
- ttlClock,
343
- replicaVersion,
344
- owner: this.#taskID,
345
- grantedAt: lastConnectTime,
346
- clientSchema,
347
- profileID
348
- };
349
- return tx`
360
+ this.#pendingInstanceWrite = (tx, lastConnectTime) => {
361
+ const change = {
362
+ clientGroupID: this.#id,
363
+ version: versionString(version2),
364
+ lastActive,
365
+ ttlClock,
366
+ replicaVersion,
367
+ owner: this.#taskID,
368
+ grantedAt: lastConnectTime,
369
+ clientSchema,
370
+ profileID
371
+ };
372
+ return tx`
350
373
  INSERT INTO ${this.#cvr("instances")} ${tx(change)}
351
374
  ON CONFLICT ("clientGroupID") DO UPDATE SET ${tx(change)}`;
352
- }
353
- });
375
+ };
354
376
  }
355
377
  markQueryAsDeleted(version2, queryPatch) {
356
- this.#writes.add({
357
- stats: { queries: 1 },
358
- write: (tx) => tx`UPDATE ${this.#cvr("queries")} SET ${tx({
359
- patchVersion: versionString(version2),
360
- deleted: true,
361
- transformationHash: null,
362
- transformationVersion: null
363
- })}
364
- WHERE "clientGroupID" = ${this.#id} AND "queryHash" = ${queryPatch.id}`
378
+ this.#updateQueryFields(queryPatch.id, {
379
+ patchVersion: versionString(version2),
380
+ deleted: true,
381
+ transformationHash: null,
382
+ transformationVersion: null
365
383
  });
366
384
  }
367
385
  putQuery(query) {
368
386
  const change = queryRecordToQueryRow(this.#id, query);
369
- this.#writes.add({
370
- stats: { queries: 1 },
371
- write: (tx) => tx`INSERT INTO ${this.#cvr("queries")} (
372
- "clientGroupID",
373
- "queryHash",
374
- "clientAST",
375
- "queryName",
376
- "queryArgs",
377
- "patchVersion",
378
- "transformationHash",
379
- "transformationVersion",
380
- "internal",
381
- "deleted"
382
- ) VALUES (
383
- ${change.clientGroupID},
384
- ${change.queryHash},
385
- ${change.clientAST},
386
- ${change.queryName},
387
- ${change.queryArgs === void 0 ? null : JSON.stringify(change.queryArgs)}::text::json,
388
- ${change.patchVersion},
389
- ${change.transformationHash ?? null},
390
- ${change.transformationVersion ?? null},
391
- ${change.internal},
392
- ${change.deleted ?? false}
393
- )
394
- ON CONFLICT ("clientGroupID", "queryHash")
395
- DO UPDATE SET
396
- "clientAST" = ${change.clientAST},
397
- "queryName" = ${change.queryName},
398
- "queryArgs" = ${change.queryArgs === void 0 ? null : JSON.stringify(change.queryArgs)}::text::json,
399
- "patchVersion" = ${change.patchVersion},
400
- "transformationHash" = ${change.transformationHash ?? null},
401
- "transformationVersion" = ${change.transformationVersion ?? null},
402
- "internal" = ${change.internal},
403
- "deleted" = ${change.deleted ?? false}`
404
- });
387
+ const c = {
388
+ ...change,
389
+ // Pre-stringify queryArgs to handle postgres.js boolean array bug
390
+ queryArgs: change.queryArgs !== null ? JSON.stringify(change.queryArgs) : null,
391
+ transformationHash: change.transformationHash ?? null,
392
+ transformationVersion: change.transformationVersion ?? null,
393
+ deleted: change.deleted ?? false
394
+ };
395
+ this.#pendingQueryUpdates.set(query.id, c);
405
396
  }
406
397
  updateQuery(query) {
407
398
  const maybeVersionString = (v2) => v2 ? versionString(v2) : null;
408
- const change = {
399
+ this.#updateQueryFields(query.id, {
409
400
  patchVersion: query.type === "internal" ? null : maybeVersionString(query.patchVersion),
410
401
  transformationHash: query.transformationHash ?? null,
411
402
  transformationVersion: maybeVersionString(query.transformationVersion),
412
403
  deleted: false
413
- };
414
- this.#writes.add({
415
- stats: { queries: 1 },
416
- write: (tx) => tx`UPDATE ${this.#cvr("queries")} SET ${tx(change)}
417
- WHERE "clientGroupID" = ${this.#id} AND "queryHash" = ${query.id}`
418
404
  });
419
405
  }
420
406
  insertClient(client) {
@@ -436,38 +422,18 @@ class CVRStore {
436
422
  });
437
423
  }
438
424
  putDesiredQuery(newVersion, query, client, deleted, inactivatedAt, ttl) {
425
+ const { ttlMs, inactivatedAtMs } = convertTTLValues(inactivatedAt, ttl);
439
426
  const change = {
440
427
  clientGroupID: this.#id,
441
428
  clientID: client.id,
442
429
  deleted,
430
+ inactivatedAt: inactivatedAtMs,
443
431
  patchVersion: versionString(newVersion),
444
- queryHash: query.id
432
+ queryHash: query.id,
433
+ ttl: ttlMs
445
434
  };
446
- const inactivatedAtTimestamp = inactivatedAt === void 0 ? null : ttlClockFromNumber(ttlClockAsNumber(inactivatedAt) / 1e3);
447
- const inactivatedAtMs = inactivatedAt ?? null;
448
- const ttlInterval = ttl < 0 ? null : ttl / 1e3;
449
- const ttlMs = ttl < 0 ? null : ttl;
450
- this.#writes.add({
451
- stats: { desires: 1 },
452
- write: (tx) => tx`
453
- INSERT INTO ${this.#cvr("desires")} (
454
- "clientGroupID", "clientID", "queryHash", "patchVersion", "deleted",
455
- "ttl", "ttlMs", "inactivatedAt", "inactivatedAtMs"
456
- ) VALUES (
457
- ${change.clientGroupID}, ${change.clientID}, ${change.queryHash},
458
- ${change.patchVersion}, ${change.deleted}, ${ttlInterval}, ${ttlMs},
459
- ${inactivatedAtTimestamp}, ${inactivatedAtMs}
460
- )
461
- ON CONFLICT ("clientGroupID", "clientID", "queryHash")
462
- DO UPDATE SET
463
- "patchVersion" = ${change.patchVersion},
464
- "deleted" = ${change.deleted},
465
- "ttl" = ${ttlInterval},
466
- "ttlMs" = ${ttlMs},
467
- "inactivatedAt" = ${inactivatedAtTimestamp},
468
- "inactivatedAtMs" = ${inactivatedAtMs}
469
- `
470
- });
435
+ const key = `${client.id}:${query.id}`;
436
+ this.#pendingDesireUpdates.set(key, change);
471
437
  }
472
438
  catchupRowPatches(lc, afterVersion, upToCVR, current, excludeQueryHashes = []) {
473
439
  return this.#rowCache.catchupRowPatches(
@@ -526,13 +492,200 @@ class CVRStore {
526
492
  reader.setDone();
527
493
  }
528
494
  }
495
+ #flushQueries(tx, lc) {
496
+ const partialOnly = /* @__PURE__ */ new Map();
497
+ for (const [queryHash, partial] of this.#pendingQueryPartialUpdates) {
498
+ const existing = this.#pendingQueryUpdates.get(queryHash);
499
+ if (existing) {
500
+ Object.assign(existing, partial);
501
+ } else {
502
+ partialOnly.set(queryHash, partial);
503
+ }
504
+ }
505
+ const queries = [];
506
+ if (this.#pendingQueryUpdates.size > 0) {
507
+ const rows = [...this.#pendingQueryUpdates.values()];
508
+ lc.debug?.(`Batch flushing ${rows.length} full query updates`);
509
+ queries.push(tx`
510
+ INSERT INTO ${this.#cvr("queries")} (
511
+ "clientGroupID",
512
+ "queryHash",
513
+ "clientAST",
514
+ "queryName",
515
+ "queryArgs",
516
+ "patchVersion",
517
+ "transformationHash",
518
+ "transformationVersion",
519
+ "internal",
520
+ "deleted"
521
+ )
522
+ SELECT
523
+ "clientGroupID",
524
+ "queryHash",
525
+ "clientAST",
526
+ "queryName",
527
+ CASE
528
+ WHEN "queryArgs" IS NULL THEN NULL
529
+ ELSE "queryArgs"::json
530
+ END,
531
+ "patchVersion",
532
+ "transformationHash",
533
+ "transformationVersion",
534
+ "internal",
535
+ "deleted"
536
+ FROM json_to_recordset(${rows}) AS x(
537
+ "clientGroupID" TEXT,
538
+ "queryHash" TEXT,
539
+ "clientAST" JSONB,
540
+ "queryName" TEXT,
541
+ "queryArgs" TEXT,
542
+ "patchVersion" TEXT,
543
+ "transformationHash" TEXT,
544
+ "transformationVersion" TEXT,
545
+ "internal" BOOLEAN,
546
+ "deleted" BOOLEAN
547
+ )
548
+ ON CONFLICT ("clientGroupID", "queryHash") DO UPDATE SET
549
+ "clientAST" = excluded."clientAST",
550
+ "queryName" = excluded."queryName",
551
+ "queryArgs" = CASE
552
+ WHEN excluded."queryArgs" IS NULL THEN NULL
553
+ ELSE excluded."queryArgs"::json
554
+ END,
555
+ "patchVersion" = excluded."patchVersion",
556
+ "transformationHash" = excluded."transformationHash",
557
+ "transformationVersion" = excluded."transformationVersion",
558
+ "internal" = excluded."internal",
559
+ "deleted" = excluded."deleted"
560
+ `);
561
+ }
562
+ if (partialOnly.size > 0) {
563
+ lc.debug?.(`Batch flushing ${partialOnly.size} partial query updates`);
564
+ const rows = Array.from(
565
+ partialOnly.entries(),
566
+ ([queryHash, partial]) => ({
567
+ clientGroupID: this.#id,
568
+ queryHash,
569
+ patchVersionSet: partial.patchVersion !== void 0,
570
+ patchVersion: partial.patchVersion ?? null,
571
+ deletedSet: partial.deleted !== void 0,
572
+ deleted: partial.deleted ?? null,
573
+ transformationHashSet: partial.transformationHash !== void 0,
574
+ transformationHash: partial.transformationHash ?? null,
575
+ transformationVersionSet: partial.transformationVersion !== void 0,
576
+ transformationVersion: partial.transformationVersion ?? null
577
+ })
578
+ );
579
+ queries.push(tx`
580
+ UPDATE ${this.#cvr("queries")} AS q
581
+ SET
582
+ "patchVersion" = CASE
583
+ WHEN u."patchVersionSet" THEN u."patchVersion"
584
+ ELSE q."patchVersion"
585
+ END,
586
+ "deleted" = CASE
587
+ WHEN u."deletedSet" THEN u."deleted"
588
+ ELSE q."deleted"
589
+ END,
590
+ "transformationHash" = CASE
591
+ WHEN u."transformationHashSet" THEN u."transformationHash"
592
+ ELSE q."transformationHash"
593
+ END,
594
+ "transformationVersion" = CASE
595
+ WHEN u."transformationVersionSet" THEN u."transformationVersion"
596
+ ELSE q."transformationVersion"
597
+ END
598
+ FROM json_to_recordset(${rows}) AS u(
599
+ "clientGroupID" TEXT,
600
+ "queryHash" TEXT,
601
+ "patchVersionSet" BOOLEAN,
602
+ "patchVersion" TEXT,
603
+ "deletedSet" BOOLEAN,
604
+ "deleted" BOOLEAN,
605
+ "transformationHashSet" BOOLEAN,
606
+ "transformationHash" TEXT,
607
+ "transformationVersionSet" BOOLEAN,
608
+ "transformationVersion" TEXT
609
+ )
610
+ WHERE q."clientGroupID" = u."clientGroupID"
611
+ AND q."queryHash" = u."queryHash"
612
+ `);
613
+ }
614
+ return queries;
615
+ }
616
+ #flushDesires(tx, lc) {
617
+ if (this.#pendingDesireUpdates.size === 0) {
618
+ return null;
619
+ }
620
+ const rows = Array.from(this.#pendingDesireUpdates.values(), (row) => {
621
+ const { ttlInterval, ttlMs, inactivatedAtTimestamp, inactivatedAtMs } = convertTTLValues(row.inactivatedAt ?? void 0, row.ttl ?? -1);
622
+ return {
623
+ clientGroupID: row.clientGroupID,
624
+ clientID: row.clientID,
625
+ queryHash: row.queryHash,
626
+ patchVersion: row.patchVersion,
627
+ deleted: row.deleted,
628
+ ttl: ttlInterval,
629
+ ttlMs,
630
+ inactivatedAt: inactivatedAtTimestamp,
631
+ inactivatedAtMs
632
+ };
633
+ });
634
+ lc.debug?.(`Batch flushing ${rows.length} desire updates`);
635
+ return tx`
636
+ INSERT INTO ${this.#cvr("desires")} (
637
+ "clientGroupID",
638
+ "clientID",
639
+ "queryHash",
640
+ "patchVersion",
641
+ "deleted",
642
+ "ttl",
643
+ "ttlMs",
644
+ "inactivatedAt",
645
+ "inactivatedAtMs"
646
+ )
647
+ SELECT
648
+ "clientGroupID",
649
+ "clientID",
650
+ "queryHash",
651
+ "patchVersion",
652
+ "deleted",
653
+ "ttl",
654
+ "ttlMs",
655
+ CASE
656
+ WHEN "inactivatedAt" IS NULL THEN NULL
657
+ -- Divide by 1000 because postgres.js serializeTimestamp treats numbers as ms
658
+ -- and to_timestamp expects seconds. This matches non-batched behavior.
659
+ ELSE to_timestamp("inactivatedAt" / 1000.0)
660
+ END,
661
+ "inactivatedAtMs"
662
+ FROM json_to_recordset(${rows}) AS x(
663
+ "clientGroupID" TEXT,
664
+ "clientID" TEXT,
665
+ "queryHash" TEXT,
666
+ "patchVersion" TEXT,
667
+ "deleted" BOOLEAN,
668
+ "ttl" INTERVAL,
669
+ "ttlMs" DOUBLE PRECISION,
670
+ "inactivatedAt" DOUBLE PRECISION,
671
+ "inactivatedAtMs" DOUBLE PRECISION
672
+ )
673
+ ON CONFLICT ("clientGroupID", "clientID", "queryHash") DO UPDATE SET
674
+ "patchVersion" = excluded."patchVersion",
675
+ "deleted" = excluded."deleted",
676
+ "ttl" = excluded."ttl",
677
+ "ttlMs" = excluded."ttlMs",
678
+ "inactivatedAt" = excluded."inactivatedAt",
679
+ "inactivatedAtMs" = excluded."inactivatedAtMs"
680
+ `;
681
+ }
529
682
  async #checkVersionAndOwnership(lc, tx, expectedCurrentVersion, lastConnectTime) {
530
683
  const start = Date.now();
531
684
  lc.debug?.("checking cvr version and ownership");
532
- const expected = versionString(expectedCurrentVersion);
533
685
  const result = await tx`SELECT "version", "owner", "grantedAt" FROM ${this.#cvr("instances")}
534
686
  WHERE "clientGroupID" = ${this.#id}
535
- FOR UPDATE`.execute();
687
+ FOR UPDATE`;
688
+ const expected = versionString(expectedCurrentVersion);
536
689
  const { version: version2, owner, grantedAt } = result.length > 0 ? result[0] : {
537
690
  version: EMPTY_CVR_VERSION.stateVersion,
538
691
  owner: null,
@@ -578,65 +731,82 @@ class CVRStore {
578
731
  }
579
732
  }
580
733
  }
581
- if (this.#pendingRowRecordUpdates.size === 0 && this.#writes.size === 0) {
734
+ if (this.#pendingRowRecordUpdates.size === 0 && this.#writes.size === 0 && this.#pendingInstanceWrite === void 0 && this.#pendingQueryUpdates.size === 0 && this.#pendingQueryPartialUpdates.size === 0 && this.#pendingDesireUpdates.size === 0) {
582
735
  return null;
583
736
  }
584
737
  this.putInstance(cvr);
585
738
  const start = Date.now();
586
739
  lc.debug?.("flush tx beginning");
587
- const rowsFlushed = await this.#db.begin(READ_COMMITTED, async (tx) => {
588
- lc.debug?.(`flush tx begun after ${Date.now() - start} ms`);
589
- const pipelined = [
590
- // #checkVersionAndOwnership() executes a `SELECT ... FOR UPDATE`
591
- // query to acquire a row-level lock so that version-updating
592
- // transactions are effectively serialized per cvr.instance.
593
- //
594
- // Note that `rowsVersion` updates, on the other hand, are not subject
595
- // to this lock and can thus commit / be-committed independently of
596
- // cvr.instances.
597
- this.#checkVersionAndOwnership(
740
+ const results = await runTx(
741
+ this.#db,
742
+ async (tx) => {
743
+ lc.debug?.(`flush tx begun after ${Date.now() - start} ms`);
744
+ await this.#checkVersionAndOwnership(
598
745
  lc,
599
746
  tx,
600
747
  expectedCurrentVersion,
601
748
  lastConnectTime
602
- )
603
- ];
604
- let i = 0;
605
- for (const write of this.#writes) {
606
- stats.instances += write.stats.instances ?? 0;
607
- stats.queries += write.stats.queries ?? 0;
608
- stats.desires += write.stats.desires ?? 0;
609
- stats.clients += write.stats.clients ?? 0;
610
- stats.rows += write.stats.rows ?? 0;
611
- const writeIndex = i++;
612
- const writeStart = Date.now();
613
- pipelined.push(
614
- write.write(tx, lastConnectTime).execute().then(() => {
615
- lc.debug?.(
616
- `write ${writeIndex}/${this.#writes.size} completed in ${Date.now() - writeStart} ms`
617
- );
618
- })
619
749
  );
620
- stats.statements++;
621
- }
622
- const rowUpdates = this.#rowCache.executeRowUpdates(
623
- tx,
624
- cvr.version,
625
- this.#pendingRowRecordUpdates,
626
- "allow-defer",
627
- lc
628
- );
629
- pipelined.push(...rowUpdates);
630
- stats.statements += rowUpdates.length;
631
- await Promise.all(pipelined);
632
- lc.debug?.(`flush tx returning after ${Date.now() - start} ms`);
633
- if (rowUpdates.length === 0) {
634
- stats.rowsDeferred = this.#pendingRowRecordUpdates.size;
635
- return false;
636
- }
750
+ const writeQueries = [];
751
+ if (this.#pendingInstanceWrite) {
752
+ writeQueries.push(this.#pendingInstanceWrite(tx, lastConnectTime));
753
+ stats.instances++;
754
+ stats.statements++;
755
+ }
756
+ for (const write of this.#writes) {
757
+ stats.clients += write.stats.clients ?? 0;
758
+ stats.rows += write.stats.rows ?? 0;
759
+ writeQueries.push(write.write(tx, lastConnectTime));
760
+ stats.statements++;
761
+ }
762
+ const hasQueryUpdates = this.#pendingQueryUpdates.size > 0 || this.#pendingQueryPartialUpdates.size > 0;
763
+ const desireFlush = this.#flushDesires(tx, lc);
764
+ let queryFlushes = [];
765
+ if (hasQueryUpdates) {
766
+ queryFlushes = this.#flushQueries(tx, lc);
767
+ const partialOnlyCount = Array.from(
768
+ this.#pendingQueryPartialUpdates.keys()
769
+ ).filter((key) => !this.#pendingQueryUpdates.has(key)).length;
770
+ stats.queries = this.#pendingQueryUpdates.size + partialOnlyCount;
771
+ stats.statements += (this.#pendingQueryUpdates.size > 0 ? 1 : 0) + (partialOnlyCount > 0 ? 1 : 0);
772
+ if (desireFlush) {
773
+ stats.desires = this.#pendingDesireUpdates.size;
774
+ stats.statements++;
775
+ }
776
+ } else if (desireFlush) {
777
+ stats.desires = this.#pendingDesireUpdates.size;
778
+ stats.statements++;
779
+ }
780
+ const rowUpdates = this.#rowCache.executeRowUpdates(
781
+ tx,
782
+ cvr.version,
783
+ this.#pendingRowRecordUpdates,
784
+ "allow-defer",
785
+ lc
786
+ );
787
+ stats.statements += rowUpdates.length;
788
+ const pipelined = [
789
+ ...writeQueries,
790
+ ...queryFlushes,
791
+ ...desireFlush ? [desireFlush] : [],
792
+ ...rowUpdates
793
+ ];
794
+ lc.debug?.(`returning ${pipelined.length} queries for pipelining`);
795
+ return Promise.all(pipelined);
796
+ },
797
+ { mode: READ_COMMITTED }
798
+ );
799
+ lc.debug?.(`flush tx completed after ${Date.now() - start} ms`);
800
+ const baseQueries = (this.#pendingInstanceWrite ? 1 : 0) + this.#writes.size + (this.#pendingQueryUpdates.size > 0 ? 1 : 0) + (Array.from(this.#pendingQueryPartialUpdates.keys()).filter(
801
+ (key) => !this.#pendingQueryUpdates.has(key)
802
+ ).length > 0 ? 1 : 0) + (this.#pendingDesireUpdates.size > 0 ? 1 : 0);
803
+ const rowUpdateCount = results.length - baseQueries;
804
+ const rowsFlushed = rowUpdateCount > 0;
805
+ if (!rowsFlushed) {
806
+ stats.rowsDeferred = this.#pendingRowRecordUpdates.size;
807
+ } else {
637
808
  stats.rows += this.#pendingRowRecordUpdates.size;
638
- return true;
639
- });
809
+ }
640
810
  this.#rowCount = await this.#rowCache.apply(
641
811
  this.#pendingRowRecordUpdates,
642
812
  cvr.version,
@@ -671,8 +841,12 @@ class CVRStore {
671
841
  throw e;
672
842
  } finally {
673
843
  this.#writes.clear();
844
+ this.#pendingInstanceWrite = void 0;
674
845
  this.#pendingRowRecordUpdates.clear();
675
846
  this.#forceUpdates.clear();
847
+ this.#pendingQueryUpdates.clear();
848
+ this.#pendingDesireUpdates.clear();
849
+ this.#pendingQueryPartialUpdates.clear();
676
850
  }
677
851
  }
678
852
  hasPendingUpdates() {