@rocicorp/zero 0.26.1-canary.9 → 0.26.2-canary.1

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 (1113) hide show
  1. package/out/_virtual/_@oxc-project_runtime@0.115.0/helpers/usingCtx.js +57 -0
  2. package/out/_virtual/_rolldown/runtime.js +27 -0
  3. package/out/analyze-query/src/bin-analyze.js +195 -280
  4. package/out/analyze-query/src/bin-analyze.js.map +1 -1
  5. package/out/analyze-query/src/bin-transform.js +35 -40
  6. package/out/analyze-query/src/bin-transform.js.map +1 -1
  7. package/out/analyze-query/src/explain-queries.js +11 -13
  8. package/out/analyze-query/src/explain-queries.js.map +1 -1
  9. package/out/analyze-query/src/run-ast.d.ts.map +1 -1
  10. package/out/analyze-query/src/run-ast.js +68 -94
  11. package/out/analyze-query/src/run-ast.js.map +1 -1
  12. package/out/ast-to-zql/src/ast-to-zql.js +105 -153
  13. package/out/ast-to-zql/src/ast-to-zql.js.map +1 -1
  14. package/out/ast-to-zql/src/bin.js +57 -62
  15. package/out/ast-to-zql/src/bin.js.map +1 -1
  16. package/out/ast-to-zql/src/format.js +14 -13
  17. package/out/ast-to-zql/src/format.js.map +1 -1
  18. package/out/datadog/src/datadog-log-sink.js +148 -213
  19. package/out/datadog/src/datadog-log-sink.js.map +1 -1
  20. package/out/otel/src/enabled.js +9 -11
  21. package/out/otel/src/enabled.js.map +1 -1
  22. package/out/otel/src/log-options.js +25 -35
  23. package/out/otel/src/log-options.js.map +1 -1
  24. package/out/otel/src/maybe-time.js +13 -14
  25. package/out/otel/src/maybe-time.js.map +1 -1
  26. package/out/otel/src/span.js +23 -26
  27. package/out/otel/src/span.js.map +1 -1
  28. package/out/otel/src/test-log-config.js +11 -10
  29. package/out/otel/src/test-log-config.js.map +1 -1
  30. package/out/otel/src/version.js +6 -5
  31. package/out/otel/src/version.js.map +1 -1
  32. package/out/replicache/src/async-iterable-to-array.js +8 -9
  33. package/out/replicache/src/async-iterable-to-array.js.map +1 -1
  34. package/out/replicache/src/bg-interval.js +28 -35
  35. package/out/replicache/src/bg-interval.js.map +1 -1
  36. package/out/replicache/src/btree/diff.js +6 -5
  37. package/out/replicache/src/btree/diff.js.map +1 -1
  38. package/out/replicache/src/btree/node.js +281 -372
  39. package/out/replicache/src/btree/node.js.map +1 -1
  40. package/out/replicache/src/btree/read.js +155 -256
  41. package/out/replicache/src/btree/read.js.map +1 -1
  42. package/out/replicache/src/btree/splice.js +60 -80
  43. package/out/replicache/src/btree/splice.js.map +1 -1
  44. package/out/replicache/src/btree/write.js +134 -158
  45. package/out/replicache/src/btree/write.js.map +1 -1
  46. package/out/replicache/src/call-default-fetch.js +28 -32
  47. package/out/replicache/src/call-default-fetch.js.map +1 -1
  48. package/out/replicache/src/config.js +2 -0
  49. package/out/replicache/src/connection-loop-delegates.js +31 -33
  50. package/out/replicache/src/connection-loop-delegates.js.map +1 -1
  51. package/out/replicache/src/connection-loop.js +174 -240
  52. package/out/replicache/src/connection-loop.js.map +1 -1
  53. package/out/replicache/src/cookies.js +22 -32
  54. package/out/replicache/src/cookies.js.map +1 -1
  55. package/out/replicache/src/dag/chunk.js +44 -50
  56. package/out/replicache/src/dag/chunk.js.map +1 -1
  57. package/out/replicache/src/dag/gc.js +94 -114
  58. package/out/replicache/src/dag/gc.js.map +1 -1
  59. package/out/replicache/src/dag/key.js +9 -11
  60. package/out/replicache/src/dag/key.js.map +1 -1
  61. package/out/replicache/src/dag/lazy-store.js +458 -510
  62. package/out/replicache/src/dag/lazy-store.js.map +1 -1
  63. package/out/replicache/src/dag/store-impl.js +147 -178
  64. package/out/replicache/src/dag/store-impl.js.map +1 -1
  65. package/out/replicache/src/dag/store.js +19 -22
  66. package/out/replicache/src/dag/store.js.map +1 -1
  67. package/out/replicache/src/dag/visitor.js +23 -21
  68. package/out/replicache/src/dag/visitor.js.map +1 -1
  69. package/out/replicache/src/db/commit.js +209 -283
  70. package/out/replicache/src/db/commit.js.map +1 -1
  71. package/out/replicache/src/db/index.js +79 -122
  72. package/out/replicache/src/db/index.js.map +1 -1
  73. package/out/replicache/src/db/read.js +44 -60
  74. package/out/replicache/src/db/read.js.map +1 -1
  75. package/out/replicache/src/db/rebase.js +22 -77
  76. package/out/replicache/src/db/rebase.js.map +1 -1
  77. package/out/replicache/src/db/write.js +162 -296
  78. package/out/replicache/src/db/write.js.map +1 -1
  79. package/out/replicache/src/deleted-clients.js +59 -87
  80. package/out/replicache/src/deleted-clients.js.map +1 -1
  81. package/out/replicache/src/error-responses.js +18 -26
  82. package/out/replicache/src/error-responses.js.map +1 -1
  83. package/out/replicache/src/expo-sqlite.js +2 -0
  84. package/out/replicache/src/frozen-json.js +74 -108
  85. package/out/replicache/src/frozen-json.js.map +1 -1
  86. package/out/replicache/src/get-default-puller.js +34 -46
  87. package/out/replicache/src/get-default-puller.js.map +1 -1
  88. package/out/replicache/src/get-default-pusher.js +25 -33
  89. package/out/replicache/src/get-default-pusher.js.map +1 -1
  90. package/out/replicache/src/get-kv-store-provider.js +18 -20
  91. package/out/replicache/src/get-kv-store-provider.js.map +1 -1
  92. package/out/replicache/src/hash.js +29 -29
  93. package/out/replicache/src/hash.js.map +1 -1
  94. package/out/replicache/src/http-request-info.js +9 -8
  95. package/out/replicache/src/http-request-info.js.map +1 -1
  96. package/out/replicache/src/impl.js +2 -0
  97. package/out/replicache/src/index-defs.js +17 -28
  98. package/out/replicache/src/index-defs.js.map +1 -1
  99. package/out/replicache/src/kv/expo-sqlite/store.js +52 -50
  100. package/out/replicache/src/kv/expo-sqlite/store.js.map +1 -1
  101. package/out/replicache/src/kv/idb-store-with-mem-fallback.js +71 -68
  102. package/out/replicache/src/kv/idb-store-with-mem-fallback.js.map +1 -1
  103. package/out/replicache/src/kv/idb-store.js +144 -168
  104. package/out/replicache/src/kv/idb-store.js.map +1 -1
  105. package/out/replicache/src/kv/mem-store.js +57 -45
  106. package/out/replicache/src/kv/mem-store.js.map +1 -1
  107. package/out/replicache/src/kv/op-sqlite/store.js +56 -62
  108. package/out/replicache/src/kv/op-sqlite/store.js.map +1 -1
  109. package/out/replicache/src/kv/op-sqlite/types.d.ts.map +1 -1
  110. package/out/replicache/src/kv/op-sqlite/types.js +7 -6
  111. package/out/replicache/src/kv/op-sqlite/types.js.map +1 -1
  112. package/out/replicache/src/kv/read-impl.js +26 -25
  113. package/out/replicache/src/kv/read-impl.js.map +1 -1
  114. package/out/replicache/src/kv/sqlite-store.js +194 -207
  115. package/out/replicache/src/kv/sqlite-store.js.map +1 -1
  116. package/out/replicache/src/kv/throw-if-closed.js +12 -19
  117. package/out/replicache/src/kv/throw-if-closed.js.map +1 -1
  118. package/out/replicache/src/kv/write-impl-base.js +44 -56
  119. package/out/replicache/src/kv/write-impl-base.js.map +1 -1
  120. package/out/replicache/src/kv/write-impl.js +22 -26
  121. package/out/replicache/src/kv/write-impl.js.map +1 -1
  122. package/out/replicache/src/lazy.js +10 -11
  123. package/out/replicache/src/lazy.js.map +1 -1
  124. package/out/replicache/src/log-options.js +14 -7
  125. package/out/replicache/src/log-options.js.map +1 -1
  126. package/out/replicache/src/make-idb-name.js +14 -9
  127. package/out/replicache/src/make-idb-name.js.map +1 -1
  128. package/out/replicache/src/mutation-recovery.js +12 -0
  129. package/out/replicache/src/mutation-recovery.js.map +1 -0
  130. package/out/replicache/src/new-client-channel.js +34 -42
  131. package/out/replicache/src/new-client-channel.js.map +1 -1
  132. package/out/replicache/src/on-persist-channel.js +26 -29
  133. package/out/replicache/src/on-persist-channel.js.map +1 -1
  134. package/out/replicache/src/op-sqlite.js +2 -0
  135. package/out/replicache/src/patch-operation.js +27 -36
  136. package/out/replicache/src/patch-operation.js.map +1 -1
  137. package/out/replicache/src/pending-mutations.js +14 -12
  138. package/out/replicache/src/pending-mutations.js.map +1 -1
  139. package/out/replicache/src/persist/client-gc.js +36 -51
  140. package/out/replicache/src/persist/client-gc.js.map +1 -1
  141. package/out/replicache/src/persist/client-group-gc.js +29 -36
  142. package/out/replicache/src/persist/client-group-gc.js.map +1 -1
  143. package/out/replicache/src/persist/client-groups.js +80 -154
  144. package/out/replicache/src/persist/client-groups.js.map +1 -1
  145. package/out/replicache/src/persist/clients.js +212 -307
  146. package/out/replicache/src/persist/clients.js.map +1 -1
  147. package/out/replicache/src/persist/collect-idb-databases.js +109 -171
  148. package/out/replicache/src/persist/collect-idb-databases.js.map +1 -1
  149. package/out/replicache/src/persist/gather-mem-only-visitor.js +23 -24
  150. package/out/replicache/src/persist/gather-mem-only-visitor.js.map +1 -1
  151. package/out/replicache/src/persist/gather-not-cached-visitor.js +35 -33
  152. package/out/replicache/src/persist/gather-not-cached-visitor.js.map +1 -1
  153. package/out/replicache/src/persist/heartbeat.js +31 -41
  154. package/out/replicache/src/persist/heartbeat.js.map +1 -1
  155. package/out/replicache/src/persist/idb-databases-store-db-name.js +9 -12
  156. package/out/replicache/src/persist/idb-databases-store-db-name.js.map +1 -1
  157. package/out/replicache/src/persist/idb-databases-store.js +78 -97
  158. package/out/replicache/src/persist/idb-databases-store.js.map +1 -1
  159. package/out/replicache/src/persist/make-client-id.js +13 -9
  160. package/out/replicache/src/persist/make-client-id.js.map +1 -1
  161. package/out/replicache/src/persist/persist.js +113 -174
  162. package/out/replicache/src/persist/persist.js.map +1 -1
  163. package/out/replicache/src/persist/refresh.js +94 -183
  164. package/out/replicache/src/persist/refresh.js.map +1 -1
  165. package/out/replicache/src/process-scheduler.js +122 -143
  166. package/out/replicache/src/process-scheduler.js.map +1 -1
  167. package/out/replicache/src/pusher.js +21 -26
  168. package/out/replicache/src/pusher.js.map +1 -1
  169. package/out/replicache/src/replicache-impl.js +844 -1184
  170. package/out/replicache/src/replicache-impl.js.map +1 -1
  171. package/out/replicache/src/report-error.js +9 -6
  172. package/out/replicache/src/report-error.js.map +1 -1
  173. package/out/replicache/src/request-idle.js +13 -11
  174. package/out/replicache/src/request-idle.js.map +1 -1
  175. package/out/replicache/src/scan-iterator.d.ts.map +1 -1
  176. package/out/replicache/src/scan-iterator.js +108 -135
  177. package/out/replicache/src/scan-iterator.js.map +1 -1
  178. package/out/replicache/src/scan-options.js +33 -39
  179. package/out/replicache/src/scan-options.js.map +1 -1
  180. package/out/replicache/src/set-interval-with-signal.js +11 -10
  181. package/out/replicache/src/set-interval-with-signal.js.map +1 -1
  182. package/out/replicache/src/sqlite.js +2 -0
  183. package/out/replicache/src/subscriptions.js +222 -338
  184. package/out/replicache/src/subscriptions.js.map +1 -1
  185. package/out/replicache/src/sync/diff.js +52 -65
  186. package/out/replicache/src/sync/diff.js.map +1 -1
  187. package/out/replicache/src/sync/ids.js +8 -9
  188. package/out/replicache/src/sync/ids.js.map +1 -1
  189. package/out/replicache/src/sync/patch.js +34 -45
  190. package/out/replicache/src/sync/patch.js.map +1 -1
  191. package/out/replicache/src/sync/pull-error.js +15 -15
  192. package/out/replicache/src/sync/pull-error.js.map +1 -1
  193. package/out/replicache/src/sync/pull.js +145 -283
  194. package/out/replicache/src/sync/pull.js.map +1 -1
  195. package/out/replicache/src/sync/push.js +64 -79
  196. package/out/replicache/src/sync/push.js.map +1 -1
  197. package/out/replicache/src/sync/request-id.js +23 -15
  198. package/out/replicache/src/sync/request-id.js.map +1 -1
  199. package/out/replicache/src/sync/sync-head-name.js +6 -5
  200. package/out/replicache/src/sync/sync-head-name.js.map +1 -1
  201. package/out/replicache/src/to-error.js +7 -8
  202. package/out/replicache/src/to-error.js.map +1 -1
  203. package/out/replicache/src/transaction-closed-error.js +15 -15
  204. package/out/replicache/src/transaction-closed-error.js.map +1 -1
  205. package/out/replicache/src/transactions.js +120 -140
  206. package/out/replicache/src/transactions.js.map +1 -1
  207. package/out/replicache/src/version.js +9 -5
  208. package/out/replicache/src/version.js.map +1 -1
  209. package/out/replicache/src/with-transactions.js +23 -20
  210. package/out/replicache/src/with-transactions.js.map +1 -1
  211. package/out/shared/src/abort-error.js +7 -6
  212. package/out/shared/src/abort-error.js.map +1 -1
  213. package/out/shared/src/arrays.js +35 -42
  214. package/out/shared/src/arrays.js.map +1 -1
  215. package/out/shared/src/asserts.js +21 -45
  216. package/out/shared/src/asserts.js.map +1 -1
  217. package/out/shared/src/bigint-json.js +42 -38
  218. package/out/shared/src/bigint-json.js.map +1 -1
  219. package/out/shared/src/binary-search.js +27 -18
  220. package/out/shared/src/binary-search.js.map +1 -1
  221. package/out/shared/src/broadcast-channel.js +20 -23
  222. package/out/shared/src/broadcast-channel.js.map +1 -1
  223. package/out/shared/src/browser-env.js +11 -17
  224. package/out/shared/src/browser-env.js.map +1 -1
  225. package/out/shared/src/btree-set.js +419 -481
  226. package/out/shared/src/btree-set.js.map +1 -1
  227. package/out/shared/src/cache.js +43 -36
  228. package/out/shared/src/cache.js.map +1 -1
  229. package/out/shared/src/centroid.js +24 -26
  230. package/out/shared/src/centroid.js.map +1 -1
  231. package/out/shared/src/config.js +6 -6
  232. package/out/shared/src/config.js.map +1 -1
  233. package/out/shared/src/custom-key-map.js +54 -58
  234. package/out/shared/src/custom-key-map.js.map +1 -1
  235. package/out/shared/src/custom-key-set.js +53 -51
  236. package/out/shared/src/custom-key-set.js.map +1 -1
  237. package/out/shared/src/deep-clone.js +30 -41
  238. package/out/shared/src/deep-clone.js.map +1 -1
  239. package/out/shared/src/deep-merge.js +25 -24
  240. package/out/shared/src/deep-merge.js.map +1 -1
  241. package/out/shared/src/document-visible.js +63 -70
  242. package/out/shared/src/document-visible.js.map +1 -1
  243. package/out/shared/src/dotenv.js +7 -3
  244. package/out/shared/src/dotenv.js.map +1 -1
  245. package/out/shared/src/error.js +43 -64
  246. package/out/shared/src/error.js.map +1 -1
  247. package/out/shared/src/has-own.js +6 -5
  248. package/out/shared/src/has-own.js.map +1 -1
  249. package/out/shared/src/hash.js +15 -14
  250. package/out/shared/src/hash.js.map +1 -1
  251. package/out/shared/src/iterables.js +34 -47
  252. package/out/shared/src/iterables.js.map +1 -1
  253. package/out/shared/src/json-schema.js +25 -30
  254. package/out/shared/src/json-schema.js.map +1 -1
  255. package/out/shared/src/json.js +90 -129
  256. package/out/shared/src/json.js.map +1 -1
  257. package/out/shared/src/logging-test-utils.js +9 -11
  258. package/out/shared/src/logging-test-utils.js.map +1 -1
  259. package/out/shared/src/logging.js +75 -95
  260. package/out/shared/src/logging.js.map +1 -1
  261. package/out/shared/src/must.js +7 -8
  262. package/out/shared/src/must.js.map +1 -1
  263. package/out/shared/src/navigator.js +6 -5
  264. package/out/shared/src/navigator.js.map +1 -1
  265. package/out/shared/src/object-traversal.js +23 -23
  266. package/out/shared/src/object-traversal.js.map +1 -1
  267. package/out/shared/src/objects.js +15 -18
  268. package/out/shared/src/objects.js.map +1 -1
  269. package/out/shared/src/options.js +225 -302
  270. package/out/shared/src/options.js.map +1 -1
  271. package/out/shared/src/parse-big-int.js +12 -11
  272. package/out/shared/src/parse-big-int.js.map +1 -1
  273. package/out/shared/src/promise-race.js +21 -17
  274. package/out/shared/src/promise-race.js.map +1 -1
  275. package/out/shared/src/queue.js +124 -124
  276. package/out/shared/src/queue.js.map +1 -1
  277. package/out/shared/src/rand.js +13 -7
  278. package/out/shared/src/rand.js.map +1 -1
  279. package/out/shared/src/random-uint64.js +8 -7
  280. package/out/shared/src/random-uint64.js.map +1 -1
  281. package/out/shared/src/random-values.js +8 -11
  282. package/out/shared/src/random-values.js.map +1 -1
  283. package/out/shared/src/record-proxy.js +68 -57
  284. package/out/shared/src/record-proxy.js.map +1 -1
  285. package/out/shared/src/resolved-promises.js +9 -11
  286. package/out/shared/src/resolved-promises.js.map +1 -1
  287. package/out/shared/src/sentinels.js +9 -12
  288. package/out/shared/src/sentinels.js.map +1 -1
  289. package/out/shared/src/set-utils.js +41 -63
  290. package/out/shared/src/set-utils.js.map +1 -1
  291. package/out/shared/src/size-of-value.js +55 -51
  292. package/out/shared/src/size-of-value.js.map +1 -1
  293. package/out/shared/src/sleep.js +50 -45
  294. package/out/shared/src/sleep.js.map +1 -1
  295. package/out/shared/src/string-compare.js +8 -11
  296. package/out/shared/src/string-compare.js.map +1 -1
  297. package/out/shared/src/subscribable.js +34 -33
  298. package/out/shared/src/subscribable.js.map +1 -1
  299. package/out/shared/src/tdigest-schema.js +11 -7
  300. package/out/shared/src/tdigest-schema.js.map +1 -1
  301. package/out/shared/src/tdigest.js +197 -270
  302. package/out/shared/src/tdigest.js.map +1 -1
  303. package/out/shared/src/valita.js +145 -174
  304. package/out/shared/src/valita.js.map +1 -1
  305. package/out/z2s/src/compiler.d.ts.map +1 -1
  306. package/out/z2s/src/compiler.js +238 -468
  307. package/out/z2s/src/compiler.js.map +1 -1
  308. package/out/z2s/src/sql.d.ts +0 -1
  309. package/out/z2s/src/sql.d.ts.map +1 -1
  310. package/out/z2s/src/sql.js +149 -194
  311. package/out/z2s/src/sql.js.map +1 -1
  312. package/out/zero/package.js +193 -0
  313. package/out/zero/package.js.map +1 -0
  314. package/out/zero/src/adapters/drizzle.js +1 -6
  315. package/out/zero/src/adapters/pg.js +1 -6
  316. package/out/zero/src/adapters/postgresjs.js +1 -6
  317. package/out/zero/src/adapters/prisma.js +1 -5
  318. package/out/zero/src/analyze-query.js +1 -1
  319. package/out/zero/src/ast-to-zql.js +1 -1
  320. package/out/zero/src/bindings.js +6 -21
  321. package/out/zero/src/build-schema.js +5 -1
  322. package/out/zero/src/build-schema.js.map +1 -1
  323. package/out/zero/src/change-protocol/v0.js +3 -5
  324. package/out/zero/src/cli.js +2 -2
  325. package/out/zero/src/deploy-permissions.js +1 -1
  326. package/out/zero/src/expo-sqlite.js +2 -4
  327. package/out/zero/src/op-sqlite.js +2 -4
  328. package/out/zero/src/pg.js +2 -20
  329. package/out/zero/src/react-native.js +16 -12
  330. package/out/zero/src/react-native.js.map +1 -1
  331. package/out/zero/src/react.js +3 -12
  332. package/out/zero/src/server/runner/main.js +2 -0
  333. package/out/zero/src/server.js +2 -17
  334. package/out/zero/src/solid.js +3 -12
  335. package/out/zero/src/sqlite.js +2 -6
  336. package/out/zero/src/transform-query.js +1 -1
  337. package/out/zero/src/zero-cache-dev.js +124 -151
  338. package/out/zero/src/zero-cache-dev.js.map +1 -1
  339. package/out/zero/src/zero-out.js +9 -6
  340. package/out/zero/src/zero-out.js.map +1 -1
  341. package/out/zero/src/zero.js +6 -55
  342. package/out/zero/src/zqlite.js +2 -7
  343. package/out/zero-cache/src/auth/auth.js +138 -172
  344. package/out/zero-cache/src/auth/auth.js.map +1 -1
  345. package/out/zero-cache/src/auth/jwt.js +25 -33
  346. package/out/zero-cache/src/auth/jwt.js.map +1 -1
  347. package/out/zero-cache/src/auth/load-permissions.js +54 -62
  348. package/out/zero-cache/src/auth/load-permissions.js.map +1 -1
  349. package/out/zero-cache/src/auth/read-authorizer.js +70 -80
  350. package/out/zero-cache/src/auth/read-authorizer.js.map +1 -1
  351. package/out/zero-cache/src/auth/write-authorizer.js +284 -432
  352. package/out/zero-cache/src/auth/write-authorizer.js.map +1 -1
  353. package/out/zero-cache/src/config/network.js +31 -45
  354. package/out/zero-cache/src/config/network.js.map +1 -1
  355. package/out/zero-cache/src/config/normalize.js +81 -83
  356. package/out/zero-cache/src/config/normalize.js.map +1 -1
  357. package/out/zero-cache/src/config/server-context.js +32 -29
  358. package/out/zero-cache/src/config/server-context.js.map +1 -1
  359. package/out/zero-cache/src/config/zero-config.d.ts +4 -0
  360. package/out/zero-cache/src/config/zero-config.d.ts.map +1 -1
  361. package/out/zero-cache/src/config/zero-config.js +753 -816
  362. package/out/zero-cache/src/config/zero-config.js.map +1 -1
  363. package/out/zero-cache/src/custom/fetch.js +183 -230
  364. package/out/zero-cache/src/custom/fetch.js.map +1 -1
  365. package/out/zero-cache/src/custom-queries/transform-query.js +93 -99
  366. package/out/zero-cache/src/custom-queries/transform-query.js.map +1 -1
  367. package/out/zero-cache/src/db/create.js +27 -29
  368. package/out/zero-cache/src/db/create.js.map +1 -1
  369. package/out/zero-cache/src/db/delete-lite-db.js +11 -7
  370. package/out/zero-cache/src/db/delete-lite-db.js.map +1 -1
  371. package/out/zero-cache/src/db/lite-tables.d.ts +2 -1
  372. package/out/zero-cache/src/db/lite-tables.d.ts.map +1 -1
  373. package/out/zero-cache/src/db/lite-tables.js +120 -156
  374. package/out/zero-cache/src/db/lite-tables.js.map +1 -1
  375. package/out/zero-cache/src/db/migration-lite.js +110 -178
  376. package/out/zero-cache/src/db/migration-lite.js.map +1 -1
  377. package/out/zero-cache/src/db/migration.js +82 -151
  378. package/out/zero-cache/src/db/migration.js.map +1 -1
  379. package/out/zero-cache/src/db/mode-enum.js +8 -9
  380. package/out/zero-cache/src/db/mode-enum.js.map +1 -1
  381. package/out/zero-cache/src/db/pg-copy.js +56 -54
  382. package/out/zero-cache/src/db/pg-copy.js.map +1 -1
  383. package/out/zero-cache/src/db/pg-to-lite.js +74 -110
  384. package/out/zero-cache/src/db/pg-to-lite.js.map +1 -1
  385. package/out/zero-cache/src/db/pg-type-parser.js +19 -36
  386. package/out/zero-cache/src/db/pg-type-parser.js.map +1 -1
  387. package/out/zero-cache/src/db/run-transaction.js +19 -20
  388. package/out/zero-cache/src/db/run-transaction.js.map +1 -1
  389. package/out/zero-cache/src/db/specs.d.ts +8 -2
  390. package/out/zero-cache/src/db/specs.d.ts.map +1 -1
  391. package/out/zero-cache/src/db/specs.js +42 -78
  392. package/out/zero-cache/src/db/specs.js.map +1 -1
  393. package/out/zero-cache/src/db/statements.js +52 -59
  394. package/out/zero-cache/src/db/statements.js.map +1 -1
  395. package/out/zero-cache/src/db/transaction-pool.js +376 -400
  396. package/out/zero-cache/src/db/transaction-pool.js.map +1 -1
  397. package/out/zero-cache/src/db/warmup.js +13 -24
  398. package/out/zero-cache/src/db/warmup.js.map +1 -1
  399. package/out/zero-cache/src/observability/events.js +89 -99
  400. package/out/zero-cache/src/observability/events.js.map +1 -1
  401. package/out/zero-cache/src/observability/metrics.js +30 -54
  402. package/out/zero-cache/src/observability/metrics.js.map +1 -1
  403. package/out/zero-cache/src/scripts/decommission.js +42 -47
  404. package/out/zero-cache/src/scripts/decommission.js.map +1 -1
  405. package/out/zero-cache/src/scripts/deploy-permissions.js +106 -144
  406. package/out/zero-cache/src/scripts/deploy-permissions.js.map +1 -1
  407. package/out/zero-cache/src/scripts/permissions.js +86 -107
  408. package/out/zero-cache/src/scripts/permissions.js.map +1 -1
  409. package/out/zero-cache/src/server/anonymous-otel-start.js +306 -440
  410. package/out/zero-cache/src/server/anonymous-otel-start.js.map +1 -1
  411. package/out/zero-cache/src/server/change-streamer.d.ts.map +1 -1
  412. package/out/zero-cache/src/server/change-streamer.js +57 -128
  413. package/out/zero-cache/src/server/change-streamer.js.map +1 -1
  414. package/out/zero-cache/src/server/inspector-delegate.js +89 -100
  415. package/out/zero-cache/src/server/inspector-delegate.js.map +1 -1
  416. package/out/zero-cache/src/server/logging.js +18 -26
  417. package/out/zero-cache/src/server/logging.js.map +1 -1
  418. package/out/zero-cache/src/server/main.js +85 -142
  419. package/out/zero-cache/src/server/main.js.map +1 -1
  420. package/out/zero-cache/src/server/mutator.js +16 -13
  421. package/out/zero-cache/src/server/mutator.js.map +1 -1
  422. package/out/zero-cache/src/server/otel-diag-logger.js +42 -49
  423. package/out/zero-cache/src/server/otel-diag-logger.js.map +1 -1
  424. package/out/zero-cache/src/server/otel-log-sink.js +34 -44
  425. package/out/zero-cache/src/server/otel-log-sink.js.map +1 -1
  426. package/out/zero-cache/src/server/otel-start.js +43 -51
  427. package/out/zero-cache/src/server/otel-start.js.map +1 -1
  428. package/out/zero-cache/src/server/priority-op.js +27 -25
  429. package/out/zero-cache/src/server/priority-op.js.map +1 -1
  430. package/out/zero-cache/src/server/reaper.js +32 -43
  431. package/out/zero-cache/src/server/reaper.js.map +1 -1
  432. package/out/zero-cache/src/server/replicator.d.ts.map +1 -1
  433. package/out/zero-cache/src/server/replicator.js +41 -57
  434. package/out/zero-cache/src/server/replicator.js.map +1 -1
  435. package/out/zero-cache/src/server/runner/main.js +7 -8
  436. package/out/zero-cache/src/server/runner/main.js.map +1 -1
  437. package/out/zero-cache/src/server/runner/run-worker.js +56 -52
  438. package/out/zero-cache/src/server/runner/run-worker.js.map +1 -1
  439. package/out/zero-cache/src/server/runner/runtime.js +26 -32
  440. package/out/zero-cache/src/server/runner/runtime.js.map +1 -1
  441. package/out/zero-cache/src/server/runner/zero-dispatcher.js +22 -27
  442. package/out/zero-cache/src/server/runner/zero-dispatcher.js.map +1 -1
  443. package/out/zero-cache/src/server/syncer.js +79 -148
  444. package/out/zero-cache/src/server/syncer.js.map +1 -1
  445. package/out/zero-cache/src/server/worker-dispatcher.js +84 -113
  446. package/out/zero-cache/src/server/worker-dispatcher.js.map +1 -1
  447. package/out/zero-cache/src/server/worker-urls.d.ts +2 -1
  448. package/out/zero-cache/src/server/worker-urls.d.ts.map +1 -1
  449. package/out/zero-cache/src/server/worker-urls.js +14 -18
  450. package/out/zero-cache/src/server/worker-urls.js.map +1 -1
  451. package/out/zero-cache/src/server/write-worker.js +2 -0
  452. package/out/zero-cache/src/services/analyze.js +61 -129
  453. package/out/zero-cache/src/services/analyze.js.map +1 -1
  454. package/out/zero-cache/src/services/change-source/common/backfill-manager.js +420 -419
  455. package/out/zero-cache/src/services/change-source/common/backfill-manager.js.map +1 -1
  456. package/out/zero-cache/src/services/change-source/common/change-stream-multiplexer.js +111 -114
  457. package/out/zero-cache/src/services/change-source/common/change-stream-multiplexer.js.map +1 -1
  458. package/out/zero-cache/src/services/change-source/common/replica-schema.d.ts +2 -0
  459. package/out/zero-cache/src/services/change-source/common/replica-schema.d.ts.map +1 -1
  460. package/out/zero-cache/src/services/change-source/common/replica-schema.js +100 -115
  461. package/out/zero-cache/src/services/change-source/common/replica-schema.js.map +1 -1
  462. package/out/zero-cache/src/services/change-source/custom/change-source.js +154 -216
  463. package/out/zero-cache/src/services/change-source/custom/change-source.js.map +1 -1
  464. package/out/zero-cache/src/services/change-source/pg/backfill-metadata.js +11 -14
  465. package/out/zero-cache/src/services/change-source/pg/backfill-metadata.js.map +1 -1
  466. package/out/zero-cache/src/services/change-source/pg/backfill-stream.d.ts.map +1 -1
  467. package/out/zero-cache/src/services/change-source/pg/backfill-stream.js +169 -209
  468. package/out/zero-cache/src/services/change-source/pg/backfill-stream.js.map +1 -1
  469. package/out/zero-cache/src/services/change-source/pg/change-source.d.ts.map +1 -1
  470. package/out/zero-cache/src/services/change-source/pg/change-source.js +676 -835
  471. package/out/zero-cache/src/services/change-source/pg/change-source.js.map +1 -1
  472. package/out/zero-cache/src/services/change-source/pg/decommission.js +19 -23
  473. package/out/zero-cache/src/services/change-source/pg/decommission.js.map +1 -1
  474. package/out/zero-cache/src/services/change-source/pg/initial-sync.js +258 -411
  475. package/out/zero-cache/src/services/change-source/pg/initial-sync.js.map +1 -1
  476. package/out/zero-cache/src/services/change-source/pg/logical-replication/binary-reader.js +59 -65
  477. package/out/zero-cache/src/services/change-source/pg/logical-replication/binary-reader.js.map +1 -1
  478. package/out/zero-cache/src/services/change-source/pg/logical-replication/pgoutput-parser.js +218 -247
  479. package/out/zero-cache/src/services/change-source/pg/logical-replication/pgoutput-parser.js.map +1 -1
  480. package/out/zero-cache/src/services/change-source/pg/logical-replication/stream.js +100 -142
  481. package/out/zero-cache/src/services/change-source/pg/logical-replication/stream.js.map +1 -1
  482. package/out/zero-cache/src/services/change-source/pg/lsn.js +17 -19
  483. package/out/zero-cache/src/services/change-source/pg/lsn.js.map +1 -1
  484. package/out/zero-cache/src/services/change-source/pg/schema/ddl.js +88 -98
  485. package/out/zero-cache/src/services/change-source/pg/schema/ddl.js.map +1 -1
  486. package/out/zero-cache/src/services/change-source/pg/schema/init.js +96 -177
  487. package/out/zero-cache/src/services/change-source/pg/schema/init.js.map +1 -1
  488. package/out/zero-cache/src/services/change-source/pg/schema/published.js +69 -107
  489. package/out/zero-cache/src/services/change-source/pg/schema/published.js.map +1 -1
  490. package/out/zero-cache/src/services/change-source/pg/schema/shard.js +151 -212
  491. package/out/zero-cache/src/services/change-source/pg/schema/shard.js.map +1 -1
  492. package/out/zero-cache/src/services/change-source/pg/schema/validation.js +22 -53
  493. package/out/zero-cache/src/services/change-source/pg/schema/validation.js.map +1 -1
  494. package/out/zero-cache/src/services/change-source/protocol/current/control.js +24 -12
  495. package/out/zero-cache/src/services/change-source/protocol/current/control.js.map +1 -1
  496. package/out/zero-cache/src/services/change-source/protocol/current/data.js +180 -290
  497. package/out/zero-cache/src/services/change-source/protocol/current/data.js.map +1 -1
  498. package/out/zero-cache/src/services/change-source/protocol/current/downstream.js +21 -33
  499. package/out/zero-cache/src/services/change-source/protocol/current/downstream.js.map +1 -1
  500. package/out/zero-cache/src/services/change-source/protocol/current/json.js +7 -18
  501. package/out/zero-cache/src/services/change-source/protocol/current/json.js.map +1 -1
  502. package/out/zero-cache/src/services/change-source/protocol/current/path.js +24 -5
  503. package/out/zero-cache/src/services/change-source/protocol/current/path.js.map +1 -1
  504. package/out/zero-cache/src/services/change-source/protocol/current/status.js +25 -19
  505. package/out/zero-cache/src/services/change-source/protocol/current/status.js.map +1 -1
  506. package/out/zero-cache/src/services/change-source/protocol/current/upstream.js +24 -16
  507. package/out/zero-cache/src/services/change-source/protocol/current/upstream.js.map +1 -1
  508. package/out/zero-cache/src/services/change-source/protocol/current.js +51 -46
  509. package/out/zero-cache/src/services/change-source/protocol/current.js.map +1 -1
  510. package/out/zero-cache/src/services/change-source/protocol/mod.js +2 -0
  511. package/out/zero-cache/src/services/change-streamer/backup-monitor.js +165 -171
  512. package/out/zero-cache/src/services/change-streamer/backup-monitor.js.map +1 -1
  513. package/out/zero-cache/src/services/change-streamer/broadcast.d.ts +100 -0
  514. package/out/zero-cache/src/services/change-streamer/broadcast.d.ts.map +1 -0
  515. package/out/zero-cache/src/services/change-streamer/broadcast.js +165 -0
  516. package/out/zero-cache/src/services/change-streamer/broadcast.js.map +1 -0
  517. package/out/zero-cache/src/services/change-streamer/change-streamer-http.js +154 -221
  518. package/out/zero-cache/src/services/change-streamer/change-streamer-http.js.map +1 -1
  519. package/out/zero-cache/src/services/change-streamer/change-streamer-service.d.ts +1 -1
  520. package/out/zero-cache/src/services/change-streamer/change-streamer-service.d.ts.map +1 -1
  521. package/out/zero-cache/src/services/change-streamer/change-streamer-service.js +341 -293
  522. package/out/zero-cache/src/services/change-streamer/change-streamer-service.js.map +1 -1
  523. package/out/zero-cache/src/services/change-streamer/change-streamer.js +17 -24
  524. package/out/zero-cache/src/services/change-streamer/change-streamer.js.map +1 -1
  525. package/out/zero-cache/src/services/change-streamer/forwarder.d.ts +17 -1
  526. package/out/zero-cache/src/services/change-streamer/forwarder.d.ts.map +1 -1
  527. package/out/zero-cache/src/services/change-streamer/forwarder.js +85 -56
  528. package/out/zero-cache/src/services/change-streamer/forwarder.js.map +1 -1
  529. package/out/zero-cache/src/services/change-streamer/replica-monitor.js +49 -43
  530. package/out/zero-cache/src/services/change-streamer/replica-monitor.js.map +1 -1
  531. package/out/zero-cache/src/services/change-streamer/schema/init.js +61 -89
  532. package/out/zero-cache/src/services/change-streamer/schema/init.js.map +1 -1
  533. package/out/zero-cache/src/services/change-streamer/schema/tables.d.ts +20 -1
  534. package/out/zero-cache/src/services/change-streamer/schema/tables.d.ts.map +1 -1
  535. package/out/zero-cache/src/services/change-streamer/schema/tables.js +131 -109
  536. package/out/zero-cache/src/services/change-streamer/schema/tables.js.map +1 -1
  537. package/out/zero-cache/src/services/change-streamer/snapshot.js +26 -28
  538. package/out/zero-cache/src/services/change-streamer/snapshot.js.map +1 -1
  539. package/out/zero-cache/src/services/change-streamer/storer.js +434 -513
  540. package/out/zero-cache/src/services/change-streamer/storer.js.map +1 -1
  541. package/out/zero-cache/src/services/change-streamer/subscriber.d.ts +18 -0
  542. package/out/zero-cache/src/services/change-streamer/subscriber.d.ts.map +1 -1
  543. package/out/zero-cache/src/services/change-streamer/subscriber.js +143 -100
  544. package/out/zero-cache/src/services/change-streamer/subscriber.js.map +1 -1
  545. package/out/zero-cache/src/services/heapz.js +18 -20
  546. package/out/zero-cache/src/services/heapz.js.map +1 -1
  547. package/out/zero-cache/src/services/http-service.js +59 -57
  548. package/out/zero-cache/src/services/http-service.js.map +1 -1
  549. package/out/zero-cache/src/services/life-cycle.js +182 -214
  550. package/out/zero-cache/src/services/life-cycle.js.map +1 -1
  551. package/out/zero-cache/src/services/limiter/sliding-window-limiter.js +102 -81
  552. package/out/zero-cache/src/services/limiter/sliding-window-limiter.js.map +1 -1
  553. package/out/zero-cache/src/services/litestream/commands.js +144 -205
  554. package/out/zero-cache/src/services/litestream/commands.js.map +1 -1
  555. package/out/zero-cache/src/services/mutagen/error.js +10 -14
  556. package/out/zero-cache/src/services/mutagen/error.js.map +1 -1
  557. package/out/zero-cache/src/services/mutagen/mutagen.js +166 -264
  558. package/out/zero-cache/src/services/mutagen/mutagen.js.map +1 -1
  559. package/out/zero-cache/src/services/mutagen/pusher.js +372 -487
  560. package/out/zero-cache/src/services/mutagen/pusher.js.map +1 -1
  561. package/out/zero-cache/src/services/replicator/change-processor.d.ts.map +1 -1
  562. package/out/zero-cache/src/services/replicator/change-processor.js +483 -595
  563. package/out/zero-cache/src/services/replicator/change-processor.js.map +1 -1
  564. package/out/zero-cache/src/services/replicator/incremental-sync.d.ts +4 -2
  565. package/out/zero-cache/src/services/replicator/incremental-sync.d.ts.map +1 -1
  566. package/out/zero-cache/src/services/replicator/incremental-sync.js +118 -143
  567. package/out/zero-cache/src/services/replicator/incremental-sync.js.map +1 -1
  568. package/out/zero-cache/src/services/replicator/notifier.js +52 -28
  569. package/out/zero-cache/src/services/replicator/notifier.js.map +1 -1
  570. package/out/zero-cache/src/services/replicator/replication-status.js +105 -128
  571. package/out/zero-cache/src/services/replicator/replication-status.js.map +1 -1
  572. package/out/zero-cache/src/services/replicator/replicator.d.ts +2 -1
  573. package/out/zero-cache/src/services/replicator/replicator.d.ts.map +1 -1
  574. package/out/zero-cache/src/services/replicator/replicator.js +32 -34
  575. package/out/zero-cache/src/services/replicator/replicator.js.map +1 -1
  576. package/out/zero-cache/src/services/replicator/schema/change-log.js +101 -133
  577. package/out/zero-cache/src/services/replicator/schema/change-log.js.map +1 -1
  578. package/out/zero-cache/src/services/replicator/schema/column-metadata.js +145 -174
  579. package/out/zero-cache/src/services/replicator/schema/column-metadata.js.map +1 -1
  580. package/out/zero-cache/src/services/replicator/schema/constants.js +11 -5
  581. package/out/zero-cache/src/services/replicator/schema/constants.js.map +1 -1
  582. package/out/zero-cache/src/services/replicator/schema/replication-state.js +56 -107
  583. package/out/zero-cache/src/services/replicator/schema/replication-state.js.map +1 -1
  584. package/out/zero-cache/src/services/replicator/schema/table-metadata.d.ts +28 -7
  585. package/out/zero-cache/src/services/replicator/schema/table-metadata.d.ts.map +1 -1
  586. package/out/zero-cache/src/services/replicator/schema/table-metadata.js +96 -50
  587. package/out/zero-cache/src/services/replicator/schema/table-metadata.js.map +1 -1
  588. package/out/zero-cache/src/services/replicator/write-worker-client.d.ts +69 -0
  589. package/out/zero-cache/src/services/replicator/write-worker-client.d.ts.map +1 -0
  590. package/out/zero-cache/src/services/replicator/write-worker-client.js +96 -0
  591. package/out/zero-cache/src/services/replicator/write-worker-client.js.map +1 -0
  592. package/out/zero-cache/src/services/replicator/write-worker.js +68 -0
  593. package/out/zero-cache/src/services/replicator/write-worker.js.map +1 -0
  594. package/out/zero-cache/src/services/run-ast.d.ts.map +1 -1
  595. package/out/zero-cache/src/services/run-ast.js +79 -118
  596. package/out/zero-cache/src/services/run-ast.js.map +1 -1
  597. package/out/zero-cache/src/services/runner.js +39 -41
  598. package/out/zero-cache/src/services/runner.js.map +1 -1
  599. package/out/zero-cache/src/services/running-state.js +129 -134
  600. package/out/zero-cache/src/services/running-state.js.map +1 -1
  601. package/out/zero-cache/src/services/statz.js +139 -200
  602. package/out/zero-cache/src/services/statz.js.map +1 -1
  603. package/out/zero-cache/src/services/view-syncer/active-users-gauge.js +46 -49
  604. package/out/zero-cache/src/services/view-syncer/active-users-gauge.js.map +1 -1
  605. package/out/zero-cache/src/services/view-syncer/client-handler.js +257 -299
  606. package/out/zero-cache/src/services/view-syncer/client-handler.js.map +1 -1
  607. package/out/zero-cache/src/services/view-syncer/client-schema.js +52 -82
  608. package/out/zero-cache/src/services/view-syncer/client-schema.js.map +1 -1
  609. package/out/zero-cache/src/services/view-syncer/cvr-purger.js +85 -107
  610. package/out/zero-cache/src/services/view-syncer/cvr-purger.js.map +1 -1
  611. package/out/zero-cache/src/services/view-syncer/cvr-store.js +604 -757
  612. package/out/zero-cache/src/services/view-syncer/cvr-store.js.map +1 -1
  613. package/out/zero-cache/src/services/view-syncer/cvr.js +631 -739
  614. package/out/zero-cache/src/services/view-syncer/cvr.js.map +1 -1
  615. package/out/zero-cache/src/services/view-syncer/drain-coordinator.js +60 -40
  616. package/out/zero-cache/src/services/view-syncer/drain-coordinator.js.map +1 -1
  617. package/out/zero-cache/src/services/view-syncer/inspect-handler.js +95 -178
  618. package/out/zero-cache/src/services/view-syncer/inspect-handler.js.map +1 -1
  619. package/out/zero-cache/src/services/view-syncer/pipeline-driver.d.ts +3 -2
  620. package/out/zero-cache/src/services/view-syncer/pipeline-driver.d.ts.map +1 -1
  621. package/out/zero-cache/src/services/view-syncer/pipeline-driver.js +574 -709
  622. package/out/zero-cache/src/services/view-syncer/pipeline-driver.js.map +1 -1
  623. package/out/zero-cache/src/services/view-syncer/row-record-cache.d.ts.map +1 -1
  624. package/out/zero-cache/src/services/view-syncer/row-record-cache.js +246 -257
  625. package/out/zero-cache/src/services/view-syncer/row-record-cache.js.map +1 -1
  626. package/out/zero-cache/src/services/view-syncer/schema/cvr.js +59 -45
  627. package/out/zero-cache/src/services/view-syncer/schema/cvr.js.map +1 -1
  628. package/out/zero-cache/src/services/view-syncer/schema/init.js +121 -189
  629. package/out/zero-cache/src/services/view-syncer/schema/init.js.map +1 -1
  630. package/out/zero-cache/src/services/view-syncer/schema/types.js +138 -263
  631. package/out/zero-cache/src/services/view-syncer/schema/types.js.map +1 -1
  632. package/out/zero-cache/src/services/view-syncer/snapshotter.d.ts +3 -3
  633. package/out/zero-cache/src/services/view-syncer/snapshotter.d.ts.map +1 -1
  634. package/out/zero-cache/src/services/view-syncer/snapshotter.js +322 -331
  635. package/out/zero-cache/src/services/view-syncer/snapshotter.js.map +1 -1
  636. package/out/zero-cache/src/services/view-syncer/tracer.js +7 -6
  637. package/out/zero-cache/src/services/view-syncer/tracer.js.map +1 -1
  638. package/out/zero-cache/src/services/view-syncer/ttl-clock.js +9 -11
  639. package/out/zero-cache/src/services/view-syncer/ttl-clock.js.map +1 -1
  640. package/out/zero-cache/src/services/view-syncer/view-syncer.js +1067 -1603
  641. package/out/zero-cache/src/services/view-syncer/view-syncer.js.map +1 -1
  642. package/out/zero-cache/src/types/error-with-level.js +19 -25
  643. package/out/zero-cache/src/types/error-with-level.js.map +1 -1
  644. package/out/zero-cache/src/types/http.js +17 -26
  645. package/out/zero-cache/src/types/http.js.map +1 -1
  646. package/out/zero-cache/src/types/lexi-version.js +28 -42
  647. package/out/zero-cache/src/types/lexi-version.js.map +1 -1
  648. package/out/zero-cache/src/types/lite.js +101 -121
  649. package/out/zero-cache/src/types/lite.js.map +1 -1
  650. package/out/zero-cache/src/types/names.js +6 -5
  651. package/out/zero-cache/src/types/names.js.map +1 -1
  652. package/out/zero-cache/src/types/pg-data-type.d.ts +1 -0
  653. package/out/zero-cache/src/types/pg-data-type.d.ts.map +1 -1
  654. package/out/zero-cache/src/types/pg-data-type.js +58 -73
  655. package/out/zero-cache/src/types/pg-data-type.js.map +1 -1
  656. package/out/zero-cache/src/types/pg-types.js +12 -19
  657. package/out/zero-cache/src/types/pg-types.js.map +1 -1
  658. package/out/zero-cache/src/types/pg.js +144 -218
  659. package/out/zero-cache/src/types/pg.js.map +1 -1
  660. package/out/zero-cache/src/types/processes.js +95 -90
  661. package/out/zero-cache/src/types/processes.js.map +1 -1
  662. package/out/zero-cache/src/types/profiler.js +32 -27
  663. package/out/zero-cache/src/types/profiler.js.map +1 -1
  664. package/out/zero-cache/src/types/row-key.js +42 -30
  665. package/out/zero-cache/src/types/row-key.js.map +1 -1
  666. package/out/zero-cache/src/types/shards.js +36 -45
  667. package/out/zero-cache/src/types/shards.js.map +1 -1
  668. package/out/zero-cache/src/types/sql.js +20 -9
  669. package/out/zero-cache/src/types/sql.js.map +1 -1
  670. package/out/zero-cache/src/types/state-version.js +17 -23
  671. package/out/zero-cache/src/types/state-version.js.map +1 -1
  672. package/out/zero-cache/src/types/streams.js +234 -270
  673. package/out/zero-cache/src/types/streams.js.map +1 -1
  674. package/out/zero-cache/src/types/strings.js +10 -13
  675. package/out/zero-cache/src/types/strings.js.map +1 -1
  676. package/out/zero-cache/src/types/subscription.d.ts +3 -1
  677. package/out/zero-cache/src/types/subscription.d.ts.map +1 -1
  678. package/out/zero-cache/src/types/subscription.js +266 -214
  679. package/out/zero-cache/src/types/subscription.js.map +1 -1
  680. package/out/zero-cache/src/types/url-params.js +30 -39
  681. package/out/zero-cache/src/types/url-params.js.map +1 -1
  682. package/out/zero-cache/src/types/websocket-handoff.js +62 -75
  683. package/out/zero-cache/src/types/websocket-handoff.js.map +1 -1
  684. package/out/zero-cache/src/types/ws.js +43 -53
  685. package/out/zero-cache/src/types/ws.js.map +1 -1
  686. package/out/zero-cache/src/workers/connect-params.js +42 -43
  687. package/out/zero-cache/src/workers/connect-params.js.map +1 -1
  688. package/out/zero-cache/src/workers/connection.js +213 -282
  689. package/out/zero-cache/src/workers/connection.js.map +1 -1
  690. package/out/zero-cache/src/workers/mutator.js +22 -21
  691. package/out/zero-cache/src/workers/mutator.js.map +1 -1
  692. package/out/zero-cache/src/workers/replicator.d.ts +7 -0
  693. package/out/zero-cache/src/workers/replicator.d.ts.map +1 -1
  694. package/out/zero-cache/src/workers/replicator.js +92 -97
  695. package/out/zero-cache/src/workers/replicator.js.map +1 -1
  696. package/out/zero-cache/src/workers/syncer-ws-message-handler.js +121 -203
  697. package/out/zero-cache/src/workers/syncer-ws-message-handler.js.map +1 -1
  698. package/out/zero-cache/src/workers/syncer.js +147 -201
  699. package/out/zero-cache/src/workers/syncer.js.map +1 -1
  700. package/out/zero-client/src/client/active-clients-manager.js +178 -187
  701. package/out/zero-client/src/client/active-clients-manager.js.map +1 -1
  702. package/out/zero-client/src/client/bindings.js +11 -0
  703. package/out/zero-client/src/client/client-error-kind-enum.js +18 -29
  704. package/out/zero-client/src/client/client-error-kind-enum.js.map +1 -1
  705. package/out/zero-client/src/client/connection-manager.js +291 -346
  706. package/out/zero-client/src/client/connection-manager.js.map +1 -1
  707. package/out/zero-client/src/client/connection-status-enum.js +20 -15
  708. package/out/zero-client/src/client/connection-status-enum.js.map +1 -1
  709. package/out/zero-client/src/client/connection.js +92 -110
  710. package/out/zero-client/src/client/connection.js.map +1 -1
  711. package/out/zero-client/src/client/context.js +84 -100
  712. package/out/zero-client/src/client/context.js.map +1 -1
  713. package/out/zero-client/src/client/crud-impl.js +56 -88
  714. package/out/zero-client/src/client/crud-impl.js.map +1 -1
  715. package/out/zero-client/src/client/crud.js +127 -129
  716. package/out/zero-client/src/client/crud.js.map +1 -1
  717. package/out/zero-client/src/client/custom.d.ts.map +1 -1
  718. package/out/zero-client/src/client/custom.js +50 -74
  719. package/out/zero-client/src/client/custom.js.map +1 -1
  720. package/out/zero-client/src/client/delete-clients-manager.js +72 -93
  721. package/out/zero-client/src/client/delete-clients-manager.js.map +1 -1
  722. package/out/zero-client/src/client/enable-analytics.js +8 -16
  723. package/out/zero-client/src/client/enable-analytics.js.map +1 -1
  724. package/out/zero-client/src/client/error.js +118 -133
  725. package/out/zero-client/src/client/error.js.map +1 -1
  726. package/out/zero-client/src/client/http-string.js +7 -7
  727. package/out/zero-client/src/client/http-string.js.map +1 -1
  728. package/out/zero-client/src/client/inspector/client-group.js +21 -26
  729. package/out/zero-client/src/client/inspector/client-group.js.map +1 -1
  730. package/out/zero-client/src/client/inspector/client.js +23 -26
  731. package/out/zero-client/src/client/inspector/client.js.map +1 -1
  732. package/out/zero-client/src/client/inspector/html-dialog-prompt.js +72 -73
  733. package/out/zero-client/src/client/inspector/html-dialog-prompt.js.map +1 -1
  734. package/out/zero-client/src/client/inspector/inspector.js +46 -51
  735. package/out/zero-client/src/client/inspector/inspector.js.map +1 -1
  736. package/out/zero-client/src/client/inspector/lazy-inspector.js +132 -192
  737. package/out/zero-client/src/client/inspector/lazy-inspector.js.map +1 -1
  738. package/out/zero-client/src/client/inspector/query.js +72 -77
  739. package/out/zero-client/src/client/inspector/query.js.map +1 -1
  740. package/out/zero-client/src/client/ivm-branch.js +118 -145
  741. package/out/zero-client/src/client/ivm-branch.js.map +1 -1
  742. package/out/zero-client/src/client/keys.js +15 -31
  743. package/out/zero-client/src/client/keys.js.map +1 -1
  744. package/out/zero-client/src/client/log-options.js +43 -57
  745. package/out/zero-client/src/client/log-options.js.map +1 -1
  746. package/out/zero-client/src/client/make-mutate-property.js +46 -29
  747. package/out/zero-client/src/client/make-mutate-property.js.map +1 -1
  748. package/out/zero-client/src/client/make-replicache-mutators.js +80 -96
  749. package/out/zero-client/src/client/make-replicache-mutators.js.map +1 -1
  750. package/out/zero-client/src/client/metric-name-enum.js +11 -15
  751. package/out/zero-client/src/client/metric-name-enum.js.map +1 -1
  752. package/out/zero-client/src/client/metrics.js +210 -237
  753. package/out/zero-client/src/client/metrics.js.map +1 -1
  754. package/out/zero-client/src/client/mutation-tracker.js +264 -354
  755. package/out/zero-client/src/client/mutation-tracker.js.map +1 -1
  756. package/out/zero-client/src/client/mutator-proxy.js +122 -151
  757. package/out/zero-client/src/client/mutator-proxy.js.map +1 -1
  758. package/out/zero-client/src/client/options.js +7 -10
  759. package/out/zero-client/src/client/options.js.map +1 -1
  760. package/out/zero-client/src/client/query-manager.js +305 -373
  761. package/out/zero-client/src/client/query-manager.js.map +1 -1
  762. package/out/zero-client/src/client/reload-error-handler.js +80 -101
  763. package/out/zero-client/src/client/reload-error-handler.js.map +1 -1
  764. package/out/zero-client/src/client/server-option.js +30 -59
  765. package/out/zero-client/src/client/server-option.js.map +1 -1
  766. package/out/zero-client/src/client/update-needed-reason-type-enum.js +27 -9
  767. package/out/zero-client/src/client/update-needed-reason-type-enum.js.map +1 -1
  768. package/out/zero-client/src/client/version.js +9 -5
  769. package/out/zero-client/src/client/version.js.map +1 -1
  770. package/out/zero-client/src/client/zero-poke-handler.d.ts +1 -1
  771. package/out/zero-client/src/client/zero-poke-handler.d.ts.map +1 -1
  772. package/out/zero-client/src/client/zero-poke-handler.js +205 -293
  773. package/out/zero-client/src/client/zero-poke-handler.js.map +1 -1
  774. package/out/zero-client/src/client/zero-rep.js +61 -68
  775. package/out/zero-client/src/client/zero-rep.js.map +1 -1
  776. package/out/zero-client/src/client/zero.d.ts.map +1 -1
  777. package/out/zero-client/src/client/zero.js +1367 -1834
  778. package/out/zero-client/src/client/zero.js.map +1 -1
  779. package/out/zero-client/src/mod.js +21 -0
  780. package/out/zero-client/src/util/nanoid.js +13 -18
  781. package/out/zero-client/src/util/nanoid.js.map +1 -1
  782. package/out/zero-client/src/util/socket.js +6 -5
  783. package/out/zero-client/src/util/socket.js.map +1 -1
  784. package/out/zero-pg/src/mod.js +10 -0
  785. package/out/zero-protocol/src/analyze-query-result.js +108 -148
  786. package/out/zero-protocol/src/analyze-query-result.js.map +1 -1
  787. package/out/zero-protocol/src/application-error.js +36 -34
  788. package/out/zero-protocol/src/application-error.js.map +1 -1
  789. package/out/zero-protocol/src/ast.js +236 -309
  790. package/out/zero-protocol/src/ast.js.map +1 -1
  791. package/out/zero-protocol/src/change-desired-queries.js +8 -13
  792. package/out/zero-protocol/src/change-desired-queries.js.map +1 -1
  793. package/out/zero-protocol/src/client-schema.js +21 -42
  794. package/out/zero-protocol/src/client-schema.js.map +1 -1
  795. package/out/zero-protocol/src/close-connection.js +20 -12
  796. package/out/zero-protocol/src/close-connection.js.map +1 -1
  797. package/out/zero-protocol/src/connect.js +37 -52
  798. package/out/zero-protocol/src/connect.js.map +1 -1
  799. package/out/zero-protocol/src/custom-queries.js +34 -65
  800. package/out/zero-protocol/src/custom-queries.js.map +1 -1
  801. package/out/zero-protocol/src/data.js +6 -9
  802. package/out/zero-protocol/src/data.js.map +1 -1
  803. package/out/zero-protocol/src/delete-clients.js +11 -17
  804. package/out/zero-protocol/src/delete-clients.js.map +1 -1
  805. package/out/zero-protocol/src/down.js +11 -23
  806. package/out/zero-protocol/src/down.js.map +1 -1
  807. package/out/zero-protocol/src/error-kind-enum.js +24 -41
  808. package/out/zero-protocol/src/error-kind-enum.js.map +1 -1
  809. package/out/zero-protocol/src/error-origin-enum.js +8 -9
  810. package/out/zero-protocol/src/error-origin-enum.js.map +1 -1
  811. package/out/zero-protocol/src/error-reason-enum.js +12 -17
  812. package/out/zero-protocol/src/error-reason-enum.js.map +1 -1
  813. package/out/zero-protocol/src/error.js +76 -152
  814. package/out/zero-protocol/src/error.js.map +1 -1
  815. package/out/zero-protocol/src/inspect-down.js +51 -74
  816. package/out/zero-protocol/src/inspect-down.js.map +1 -1
  817. package/out/zero-protocol/src/inspect-up.js +28 -46
  818. package/out/zero-protocol/src/inspect-up.js.map +1 -1
  819. package/out/zero-protocol/src/mutation-id.js +9 -9
  820. package/out/zero-protocol/src/mutation-id.js.map +1 -1
  821. package/out/zero-protocol/src/mutation-type-enum.js +7 -7
  822. package/out/zero-protocol/src/mutation-type-enum.js.map +1 -1
  823. package/out/zero-protocol/src/mutations-patch.js +21 -16
  824. package/out/zero-protocol/src/mutations-patch.js.map +1 -1
  825. package/out/zero-protocol/src/ping.js +8 -9
  826. package/out/zero-protocol/src/ping.js.map +1 -1
  827. package/out/zero-protocol/src/poke.js +53 -59
  828. package/out/zero-protocol/src/poke.js.map +1 -1
  829. package/out/zero-protocol/src/pong.js +8 -9
  830. package/out/zero-protocol/src/pong.js.map +1 -1
  831. package/out/zero-protocol/src/primary-key.js +9 -19
  832. package/out/zero-protocol/src/primary-key.js.map +1 -1
  833. package/out/zero-protocol/src/protocol-version.js +5 -11
  834. package/out/zero-protocol/src/protocol-version.js.map +1 -1
  835. package/out/zero-protocol/src/pull.js +16 -28
  836. package/out/zero-protocol/src/pull.js.map +1 -1
  837. package/out/zero-protocol/src/push.js +162 -209
  838. package/out/zero-protocol/src/push.js.map +1 -1
  839. package/out/zero-protocol/src/queries-patch.js +22 -30
  840. package/out/zero-protocol/src/queries-patch.js.map +1 -1
  841. package/out/zero-protocol/src/query-hash.js +14 -17
  842. package/out/zero-protocol/src/query-hash.js.map +1 -1
  843. package/out/zero-protocol/src/row-patch.js +23 -30
  844. package/out/zero-protocol/src/row-patch.js.map +1 -1
  845. package/out/zero-protocol/src/up.js +11 -22
  846. package/out/zero-protocol/src/up.js.map +1 -1
  847. package/out/zero-protocol/src/update-auth.js +8 -13
  848. package/out/zero-protocol/src/update-auth.js.map +1 -1
  849. package/out/zero-protocol/src/version.js +8 -9
  850. package/out/zero-protocol/src/version.js.map +1 -1
  851. package/out/zero-react/src/bindings.js +12 -0
  852. package/out/zero-react/src/mod.js +5 -0
  853. package/out/zero-react/src/use-connection-state.js +14 -11
  854. package/out/zero-react/src/use-connection-state.js.map +1 -1
  855. package/out/zero-react/src/use-query.js +283 -281
  856. package/out/zero-react/src/use-query.js.map +1 -1
  857. package/out/zero-react/src/use-zero-online.js +17 -11
  858. package/out/zero-react/src/use-zero-online.js.map +1 -1
  859. package/out/zero-react/src/zero-provider.js +53 -69
  860. package/out/zero-react/src/zero-provider.js.map +1 -1
  861. package/out/zero-react/src/zero.js +22 -0
  862. package/out/zero-schema/src/builder/relationship-builder.js +25 -21
  863. package/out/zero-schema/src/builder/relationship-builder.js.map +1 -1
  864. package/out/zero-schema/src/builder/schema-builder.js +51 -79
  865. package/out/zero-schema/src/builder/schema-builder.js.map +1 -1
  866. package/out/zero-schema/src/builder/table-builder.js +99 -116
  867. package/out/zero-schema/src/builder/table-builder.js.map +1 -1
  868. package/out/zero-schema/src/compiled-permissions.js +21 -25
  869. package/out/zero-schema/src/compiled-permissions.js.map +1 -1
  870. package/out/zero-schema/src/name-mapper.js +31 -47
  871. package/out/zero-schema/src/name-mapper.js.map +1 -1
  872. package/out/zero-schema/src/permissions.js +94 -181
  873. package/out/zero-schema/src/permissions.js.map +1 -1
  874. package/out/zero-schema/src/schema-config.js +26 -32
  875. package/out/zero-schema/src/schema-config.js.map +1 -1
  876. package/out/zero-server/src/adapters/drizzle.d.ts.map +1 -1
  877. package/out/zero-server/src/adapters/drizzle.js +79 -76
  878. package/out/zero-server/src/adapters/drizzle.js.map +1 -1
  879. package/out/zero-server/src/adapters/pg.d.ts.map +1 -1
  880. package/out/zero-server/src/adapters/pg.js +79 -55
  881. package/out/zero-server/src/adapters/pg.js.map +1 -1
  882. package/out/zero-server/src/adapters/postgresjs.d.ts.map +1 -1
  883. package/out/zero-server/src/adapters/postgresjs.js +66 -40
  884. package/out/zero-server/src/adapters/postgresjs.js.map +1 -1
  885. package/out/zero-server/src/adapters/prisma.d.ts.map +1 -1
  886. package/out/zero-server/src/adapters/prisma.js +75 -55
  887. package/out/zero-server/src/adapters/prisma.js.map +1 -1
  888. package/out/zero-server/src/custom.d.ts.map +1 -1
  889. package/out/zero-server/src/custom.js +188 -265
  890. package/out/zero-server/src/custom.js.map +1 -1
  891. package/out/zero-server/src/logging.js +6 -5
  892. package/out/zero-server/src/logging.js.map +1 -1
  893. package/out/zero-server/src/mod.js +8 -0
  894. package/out/zero-server/src/pg-query-executor.js +14 -17
  895. package/out/zero-server/src/pg-query-executor.js.map +1 -1
  896. package/out/zero-server/src/process-mutations.js +293 -365
  897. package/out/zero-server/src/process-mutations.js.map +1 -1
  898. package/out/zero-server/src/push-processor.js +33 -49
  899. package/out/zero-server/src/push-processor.js.map +1 -1
  900. package/out/zero-server/src/queries/process-queries.js +106 -96
  901. package/out/zero-server/src/queries/process-queries.js.map +1 -1
  902. package/out/zero-server/src/schema.js +98 -144
  903. package/out/zero-server/src/schema.js.map +1 -1
  904. package/out/zero-server/src/zql-database.d.ts.map +1 -1
  905. package/out/zero-server/src/zql-database.js +54 -69
  906. package/out/zero-server/src/zql-database.js.map +1 -1
  907. package/out/zero-solid/src/bindings.js +12 -0
  908. package/out/zero-solid/src/mod.js +5 -0
  909. package/out/zero-solid/src/solid-view.js +135 -227
  910. package/out/zero-solid/src/solid-view.js.map +1 -1
  911. package/out/zero-solid/src/use-connection-state.js +18 -14
  912. package/out/zero-solid/src/use-connection-state.js.map +1 -1
  913. package/out/zero-solid/src/use-query.js +55 -100
  914. package/out/zero-solid/src/use-query.js.map +1 -1
  915. package/out/zero-solid/src/use-zero-online.js +18 -12
  916. package/out/zero-solid/src/use-zero-online.js.map +1 -1
  917. package/out/zero-solid/src/use-zero.js +65 -77
  918. package/out/zero-solid/src/use-zero.js.map +1 -1
  919. package/out/zero-solid/src/zero.js +22 -0
  920. package/out/zero-types/src/format.js +8 -7
  921. package/out/zero-types/src/format.js.map +1 -1
  922. package/out/zero-types/src/name-mapper.js +34 -47
  923. package/out/zero-types/src/name-mapper.js.map +1 -1
  924. package/out/zql/src/builder/builder.d.ts.map +1 -1
  925. package/out/zql/src/builder/builder.js +315 -476
  926. package/out/zql/src/builder/builder.js.map +1 -1
  927. package/out/zql/src/builder/debug-delegate.js +69 -74
  928. package/out/zql/src/builder/debug-delegate.js.map +1 -1
  929. package/out/zql/src/builder/filter.js +116 -140
  930. package/out/zql/src/builder/filter.js.map +1 -1
  931. package/out/zql/src/builder/like.js +41 -46
  932. package/out/zql/src/builder/like.js.map +1 -1
  933. package/out/zql/src/error.js +10 -9
  934. package/out/zql/src/error.js.map +1 -1
  935. package/out/zql/src/ivm/array-view.js +89 -91
  936. package/out/zql/src/ivm/array-view.js.map +1 -1
  937. package/out/zql/src/ivm/constraint.js +65 -74
  938. package/out/zql/src/ivm/constraint.js.map +1 -1
  939. package/out/zql/src/ivm/data.js +61 -48
  940. package/out/zql/src/ivm/data.js.map +1 -1
  941. package/out/zql/src/ivm/exists.js +164 -213
  942. package/out/zql/src/ivm/exists.js.map +1 -1
  943. package/out/zql/src/ivm/fan-in.js +62 -59
  944. package/out/zql/src/ivm/fan-in.js.map +1 -1
  945. package/out/zql/src/ivm/fan-out.js +52 -61
  946. package/out/zql/src/ivm/fan-out.js.map +1 -1
  947. package/out/zql/src/ivm/filter-operators.js +91 -96
  948. package/out/zql/src/ivm/filter-operators.js.map +1 -1
  949. package/out/zql/src/ivm/filter-push.js +22 -26
  950. package/out/zql/src/ivm/filter-push.js.map +1 -1
  951. package/out/zql/src/ivm/filter.js +41 -35
  952. package/out/zql/src/ivm/filter.js.map +1 -1
  953. package/out/zql/src/ivm/flipped-join.js +282 -391
  954. package/out/zql/src/ivm/flipped-join.js.map +1 -1
  955. package/out/zql/src/ivm/join-utils.js +85 -115
  956. package/out/zql/src/ivm/join-utils.js.map +1 -1
  957. package/out/zql/src/ivm/join.js +162 -231
  958. package/out/zql/src/ivm/join.js.map +1 -1
  959. package/out/zql/src/ivm/maybe-split-and-push-edit-change.js +21 -25
  960. package/out/zql/src/ivm/maybe-split-and-push-edit-change.js.map +1 -1
  961. package/out/zql/src/ivm/memory-source.js +364 -503
  962. package/out/zql/src/ivm/memory-source.js.map +1 -1
  963. package/out/zql/src/ivm/memory-storage.js +33 -34
  964. package/out/zql/src/ivm/memory-storage.js.map +1 -1
  965. package/out/zql/src/ivm/operator.js +13 -15
  966. package/out/zql/src/ivm/operator.js.map +1 -1
  967. package/out/zql/src/ivm/push-accumulated.js +267 -270
  968. package/out/zql/src/ivm/push-accumulated.js.map +1 -1
  969. package/out/zql/src/ivm/skip.js +91 -104
  970. package/out/zql/src/ivm/skip.js.map +1 -1
  971. package/out/zql/src/ivm/stream.js +10 -10
  972. package/out/zql/src/ivm/stream.js.map +1 -1
  973. package/out/zql/src/ivm/take.js +422 -569
  974. package/out/zql/src/ivm/take.js.map +1 -1
  975. package/out/zql/src/ivm/union-fan-in.js +157 -231
  976. package/out/zql/src/ivm/union-fan-in.js.map +1 -1
  977. package/out/zql/src/ivm/union-fan-out.js +38 -43
  978. package/out/zql/src/ivm/union-fan-out.js.map +1 -1
  979. package/out/zql/src/ivm/view-apply-change.js +166 -255
  980. package/out/zql/src/ivm/view-apply-change.js.map +1 -1
  981. package/out/zql/src/mutate/crud.js +35 -34
  982. package/out/zql/src/mutate/crud.js.map +1 -1
  983. package/out/zql/src/mutate/custom.d.ts.map +1 -1
  984. package/out/zql/src/mutate/custom.js +7 -11
  985. package/out/zql/src/mutate/custom.js.map +1 -1
  986. package/out/zql/src/mutate/mutator-registry.js +67 -71
  987. package/out/zql/src/mutate/mutator-registry.js.map +1 -1
  988. package/out/zql/src/mutate/mutator.js +26 -25
  989. package/out/zql/src/mutate/mutator.js.map +1 -1
  990. package/out/zql/src/planner/planner-builder.js +134 -239
  991. package/out/zql/src/planner/planner-builder.js.map +1 -1
  992. package/out/zql/src/planner/planner-connection.js +222 -212
  993. package/out/zql/src/planner/planner-connection.js.map +1 -1
  994. package/out/zql/src/planner/planner-constraint.js +15 -7
  995. package/out/zql/src/planner/planner-constraint.js.map +1 -1
  996. package/out/zql/src/planner/planner-debug.js +199 -224
  997. package/out/zql/src/planner/planner-debug.js.map +1 -1
  998. package/out/zql/src/planner/planner-fan-in.js +146 -162
  999. package/out/zql/src/planner/planner-fan-in.js.map +1 -1
  1000. package/out/zql/src/planner/planner-fan-out.js +62 -74
  1001. package/out/zql/src/planner/planner-fan-out.js.map +1 -1
  1002. package/out/zql/src/planner/planner-graph.js +302 -334
  1003. package/out/zql/src/planner/planner-graph.js.map +1 -1
  1004. package/out/zql/src/planner/planner-join.js +255 -240
  1005. package/out/zql/src/planner/planner-join.js.map +1 -1
  1006. package/out/zql/src/planner/planner-node.js +10 -6
  1007. package/out/zql/src/planner/planner-node.js.map +1 -1
  1008. package/out/zql/src/planner/planner-source.js +15 -22
  1009. package/out/zql/src/planner/planner-source.js.map +1 -1
  1010. package/out/zql/src/planner/planner-terminus.js +28 -28
  1011. package/out/zql/src/planner/planner-terminus.js.map +1 -1
  1012. package/out/zql/src/query/complete-ordering.js +37 -61
  1013. package/out/zql/src/query/complete-ordering.js.map +1 -1
  1014. package/out/zql/src/query/create-builder.js +14 -22
  1015. package/out/zql/src/query/create-builder.js.map +1 -1
  1016. package/out/zql/src/query/error.js +10 -12
  1017. package/out/zql/src/query/error.js.map +1 -1
  1018. package/out/zql/src/query/escape-like.js +6 -5
  1019. package/out/zql/src/query/escape-like.js.map +1 -1
  1020. package/out/zql/src/query/expression.js +138 -157
  1021. package/out/zql/src/query/expression.js.map +1 -1
  1022. package/out/zql/src/query/measure-push-operator.js +35 -38
  1023. package/out/zql/src/query/measure-push-operator.js.map +1 -1
  1024. package/out/zql/src/query/metrics-delegate.js +7 -7
  1025. package/out/zql/src/query/metrics-delegate.js.map +1 -1
  1026. package/out/zql/src/query/named.js +52 -51
  1027. package/out/zql/src/query/named.js.map +1 -1
  1028. package/out/zql/src/query/query-delegate-base.js +190 -238
  1029. package/out/zql/src/query/query-delegate-base.js.map +1 -1
  1030. package/out/zql/src/query/query-impl.d.ts.map +1 -1
  1031. package/out/zql/src/query/query-impl.js +271 -405
  1032. package/out/zql/src/query/query-impl.js.map +1 -1
  1033. package/out/zql/src/query/query-internals.js +16 -8
  1034. package/out/zql/src/query/query-internals.js.map +1 -1
  1035. package/out/zql/src/query/query-registry.js +83 -98
  1036. package/out/zql/src/query/query-registry.js.map +1 -1
  1037. package/out/zql/src/query/query.d.ts.map +1 -1
  1038. package/out/zql/src/query/query.js +2 -0
  1039. package/out/zql/src/query/runnable-query-impl.d.ts.map +1 -1
  1040. package/out/zql/src/query/runnable-query-impl.js +30 -55
  1041. package/out/zql/src/query/runnable-query-impl.js.map +1 -1
  1042. package/out/zql/src/query/static-query.js +7 -14
  1043. package/out/zql/src/query/static-query.js.map +1 -1
  1044. package/out/zql/src/query/ttl.js +45 -67
  1045. package/out/zql/src/query/ttl.js.map +1 -1
  1046. package/out/zql/src/query/validate-input.js +23 -20
  1047. package/out/zql/src/query/validate-input.js.map +1 -1
  1048. package/out/zqlite/src/database-storage.js +99 -103
  1049. package/out/zqlite/src/database-storage.js.map +1 -1
  1050. package/out/zqlite/src/db.js +206 -249
  1051. package/out/zqlite/src/db.js.map +1 -1
  1052. package/out/zqlite/src/explain-queries.js +11 -13
  1053. package/out/zqlite/src/explain-queries.js.map +1 -1
  1054. package/out/zqlite/src/internal/sql-inline.js +54 -37
  1055. package/out/zqlite/src/internal/sql-inline.js.map +1 -1
  1056. package/out/zqlite/src/internal/sql.js +17 -15
  1057. package/out/zqlite/src/internal/sql.js.map +1 -1
  1058. package/out/zqlite/src/internal/statement-cache.js +117 -92
  1059. package/out/zqlite/src/internal/statement-cache.js.map +1 -1
  1060. package/out/zqlite/src/mod.js +5 -0
  1061. package/out/zqlite/src/query-builder.js +81 -172
  1062. package/out/zqlite/src/query-builder.js.map +1 -1
  1063. package/out/zqlite/src/query-delegate.js +45 -55
  1064. package/out/zqlite/src/query-delegate.js.map +1 -1
  1065. package/out/zqlite/src/resolve-scalar-subqueries.js +134 -124
  1066. package/out/zqlite/src/resolve-scalar-subqueries.js.map +1 -1
  1067. package/out/zqlite/src/sqlite-cost-model.js +92 -97
  1068. package/out/zqlite/src/sqlite-cost-model.js.map +1 -1
  1069. package/out/zqlite/src/sqlite-stat-fanout.js +304 -286
  1070. package/out/zqlite/src/sqlite-stat-fanout.js.map +1 -1
  1071. package/out/zqlite/src/table-source.js +281 -455
  1072. package/out/zqlite/src/table-source.js.map +1 -1
  1073. package/package.json +8 -7
  1074. package/out/replicache/src/db/index-operation-enum.js +0 -7
  1075. package/out/replicache/src/db/index-operation-enum.js.map +0 -1
  1076. package/out/replicache/src/db/meta-type-enum.js +0 -7
  1077. package/out/replicache/src/db/meta-type-enum.js.map +0 -1
  1078. package/out/replicache/src/format-version-enum.js +0 -11
  1079. package/out/replicache/src/format-version-enum.js.map +0 -1
  1080. package/out/replicache/src/http-status-unauthorized.js +0 -5
  1081. package/out/replicache/src/http-status-unauthorized.js.map +0 -1
  1082. package/out/replicache/src/invoke-kind-enum.js +0 -7
  1083. package/out/replicache/src/invoke-kind-enum.js.map +0 -1
  1084. package/out/replicache/src/sync/handle-pull-response-result-type-enum.js +0 -9
  1085. package/out/replicache/src/sync/handle-pull-response-result-type-enum.js.map +0 -1
  1086. package/out/zero/package.json.js +0 -9
  1087. package/out/zero/package.json.js.map +0 -1
  1088. package/out/zero/src/adapters/drizzle.js.map +0 -1
  1089. package/out/zero/src/adapters/pg.js.map +0 -1
  1090. package/out/zero/src/adapters/postgresjs.js.map +0 -1
  1091. package/out/zero/src/adapters/prisma.js.map +0 -1
  1092. package/out/zero/src/analyze-query.js.map +0 -1
  1093. package/out/zero/src/ast-to-zql.js.map +0 -1
  1094. package/out/zero/src/bindings.js.map +0 -1
  1095. package/out/zero/src/change-protocol/v0.js.map +0 -1
  1096. package/out/zero/src/cli.js.map +0 -1
  1097. package/out/zero/src/deploy-permissions.js.map +0 -1
  1098. package/out/zero/src/expo-sqlite.js.map +0 -1
  1099. package/out/zero/src/op-sqlite.js.map +0 -1
  1100. package/out/zero/src/pg.js.map +0 -1
  1101. package/out/zero/src/react.js.map +0 -1
  1102. package/out/zero/src/server.js.map +0 -1
  1103. package/out/zero/src/solid.js.map +0 -1
  1104. package/out/zero/src/sqlite.js.map +0 -1
  1105. package/out/zero/src/transform-query.js.map +0 -1
  1106. package/out/zero/src/zero.js.map +0 -1
  1107. package/out/zero/src/zqlite.js.map +0 -1
  1108. package/out/zero-cache/src/db/postgres-replica-identity-enum.js +0 -11
  1109. package/out/zero-cache/src/db/postgres-replica-identity-enum.js.map +0 -1
  1110. package/out/zero-cache/src/db/postgres-type-class-enum.js +0 -17
  1111. package/out/zero-cache/src/db/postgres-type-class-enum.js.map +0 -1
  1112. package/out/zero-cache/src/services/change-streamer/error-type-enum.js +0 -9
  1113. package/out/zero-cache/src/services/change-streamer/error-type-enum.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"row-record-cache.js","sources":["../../../../../../zero-cache/src/services/view-syncer/row-record-cache.ts"],"sourcesContent":["import type {LogContext} from '@rocicorp/logger';\nimport {type Resolver, resolver} from '@rocicorp/resolver';\nimport type {PendingQuery, Row} from 'postgres';\nimport {CustomKeyMap} from '../../../../shared/src/custom-key-map.ts';\nimport {must} from '../../../../shared/src/must.ts';\nimport {promiseVoid} from '../../../../shared/src/resolved-promises.ts';\nimport * as Mode from '../../db/mode-enum.ts';\nimport {runTx} from '../../db/run-transaction.ts';\nimport {TransactionPool} from '../../db/transaction-pool.ts';\nimport {\n getOrCreateCounter,\n getOrCreateHistogram,\n} from '../../observability/metrics.ts';\nimport {type PostgresDB, type PostgresTransaction} from '../../types/pg.ts';\nimport {rowIDString} from '../../types/row-key.ts';\nimport {cvrSchema, type ShardID} from '../../types/shards.ts';\nimport {checkVersion, type CVRFlushStats} from './cvr-store.ts';\nimport type {CVRSnapshot} from './cvr.ts';\nimport {\n rowRecordToRowsRow,\n type RowsRow,\n rowsRowToRowRecord,\n} from './schema/cvr.ts';\nimport {\n cmpVersions,\n type CVRVersion,\n type NullableCVRVersion,\n type RowID,\n type RowRecord,\n versionString,\n versionToNullableCookie,\n} from './schema/types.ts';\n\nconst FLUSH_TYPE_ATTRIBUTE = 'flush.type';\n\n/**\n * The RowRecordCache is an in-memory cache of the `cvr.rows` tables that\n * operates as both a write-through and write-back cache.\n *\n * For \"small\" CVR updates (i.e. zero or small numbers of rows) the\n * RowRecordCache operates as write-through, executing commits in\n * {@link executeRowUpdates()} before they are {@link apply}-ed to the\n * in-memory state.\n *\n * For \"large\" CVR updates (i.e. with many rows), the cache switches to a\n * write-back mode of operation, in which {@link executeRowUpdates()} is a\n * no-op, and {@link apply()} initiates a background task to flush the pending\n * row changes to the store. This allows the client poke to be completed and\n * committed on the client without waiting for the heavyweight operation of\n * committing the row records to the CVR store.\n *\n * Note that when the cache is in write-back mode, all updates become\n * write-back (i.e. asynchronously flushed) until the pending update queue is\n * fully flushed. This is required because updates must be applied in version\n * order. As with all pending work systems in zero-cache, multiple pending\n * updates are coalesced to reduce buildup of work.\n *\n * ### High level consistency\n *\n * Note that the above caching scheme only applies to the row data in `cvr.rows`\n * and corresponding `cvr.rowsVersion` tables. CVR metadata and query\n * information, on the other hand, are always committed before completing the\n * client poke. In this manner, the difference between the `version` column in\n * `cvr.instances` and the analogous column in `cvr.rowsVersion` determines\n * whether the data in the store is consistent, or whether it is awaiting a\n * pending update.\n *\n * The logic in {@link CVRStore#load()} takes this into account by loading both\n * the `cvr.instances` version and the `cvr.rowsVersion` version and checking\n * if they are in sync, waiting for a configurable delay until they are.\n *\n * ### Eventual conversion\n *\n * In the event of a continual stream of mutations (e.g. an animation-style\n * app), it is conceivable that the row record data be continually behind\n * the CVR metadata. In order to effect eventual convergence, a new view-syncer\n * signals the current view-syncer to stop updating by writing new `owner`\n * information to the `cvr.instances` row. This effectively stops the mutation\n * processing (in {@link CVRStore.#checkVersionAndOwnership}) so that the row\n * data can eventually catch up, allowing the new view-syncer to take over.\n *\n * Of course, there is the pathological situation in which a view-syncer\n * process crashes before the pending row updates are flushed. In this case,\n * the wait timeout will elapse and the CVR considered invalid.\n */\nexport class RowRecordCache {\n // The state in the #cache is always in sync with the CVR metadata\n // (i.e. cvr.instances). It may contain information that has not yet\n // been flushed to cvr.rows.\n #cache: Promise<CustomKeyMap<RowID, RowRecord>> | undefined;\n readonly #lc: LogContext;\n readonly #db: PostgresDB;\n readonly #schema: string;\n readonly #cvrID: string;\n readonly #failService: (e: unknown) => void;\n readonly #deferredRowFlushThreshold: number;\n readonly #setTimeout: typeof setTimeout;\n\n // Write-back cache state.\n readonly #pending = new CustomKeyMap<RowID, RowRecord | null>(rowIDString);\n #pendingRowsVersion: CVRVersion | null = null;\n #flushedRowsVersion: CVRVersion | null = null;\n #flushing: Resolver<void> | null = null;\n\n readonly #cvrFlushTime = getOrCreateHistogram('sync', 'cvr.flush-time', {\n description:\n 'Time to flush a CVR transaction. This includes both synchronous ' +\n 'and asynchronous flushes, distinguished by the flush.type attribute',\n unit: 's',\n });\n readonly #cvrRowsFlushed = getOrCreateCounter(\n 'sync',\n 'cvr.rows-flushed',\n 'Number of (changed) rows flushed to a CVR',\n );\n\n constructor(\n lc: LogContext,\n db: PostgresDB,\n shard: ShardID,\n cvrID: string,\n failService: (e: unknown) => void,\n deferredRowFlushThreshold = 100,\n setTimeoutFn = setTimeout,\n ) {\n this.#lc = lc;\n this.#db = db;\n this.#schema = cvrSchema(shard);\n this.#cvrID = cvrID;\n this.#failService = failService;\n this.#deferredRowFlushThreshold = deferredRowFlushThreshold;\n this.#setTimeout = setTimeoutFn;\n }\n\n recordSyncFlushStats(stats: CVRFlushStats, elapsedMs: number) {\n this.#cvrFlushTime.record(elapsedMs / 1000, {\n [FLUSH_TYPE_ATTRIBUTE]: 'sync',\n });\n if (stats.rowsDeferred === 0) {\n this.#cvrRowsFlushed.add(stats.rows);\n }\n }\n\n #recordAsyncFlushStats(rows: number, elapsedMs: number) {\n this.#cvrFlushTime.record(elapsedMs / 1000, {\n [FLUSH_TYPE_ATTRIBUTE]: 'async',\n });\n this.#cvrRowsFlushed.add(rows);\n }\n\n #cvr(table: string) {\n return this.#db(`${this.#schema}.${table}`);\n }\n\n async #ensureLoaded(): Promise<CustomKeyMap<RowID, RowRecord>> {\n if (this.#cache) {\n return this.#cache;\n }\n const start = Date.now();\n const r = resolver<CustomKeyMap<RowID, RowRecord>>();\n r.promise.catch(() => {});\n // Set this.#cache immediately (before await) so that only one db\n // query is made even if there are multiple callers.\n this.#cache = r.promise;\n try {\n const cache: CustomKeyMap<RowID, RowRecord> = new CustomKeyMap(\n rowIDString,\n );\n for await (const rows of this.#db<RowsRow[]>`\n SELECT * FROM ${this.#cvr(`rows`)}\n WHERE \"clientGroupID\" = ${this.#cvrID} AND \"refCounts\" IS NOT NULL`\n // TODO(arv): Arbitrary page size\n .cursor(5000)) {\n for (const row of rows) {\n const rowRecord = rowsRowToRowRecord(row);\n cache.set(rowRecord.id, rowRecord);\n }\n }\n this.#lc.debug?.(\n `Loaded ${cache.size} row records in ${Date.now() - start} ms`,\n );\n r.resolve(cache);\n return this.#cache;\n } catch (e) {\n r.reject(e); // Make sure the error is reflected in the cached promise\n throw e;\n }\n }\n\n getRowRecords(): Promise<ReadonlyMap<RowID, RowRecord>> {\n return this.#ensureLoaded();\n }\n\n /**\n * Applies the `rowRecords` corresponding to the `rowsVersion`\n * to the cache, indicating whether the corresponding updates\n * (generated by {@link executeRowUpdates}) were `flushed`.\n *\n * If `flushed` is false, the RowRecordCache will flush the records\n * asynchronously.\n *\n * Note that `apply()` indicates that the CVR metadata associated with\n * the `rowRecords` was successfully committed, which essentially means\n * that this process has the unconditional right (and responsibility) of\n * following up with a flush of the `rowRecords`. In particular, the\n * commit of row records are not conditioned on the version or ownership\n * columns of the `cvr.instances` row.\n */\n async apply(\n rowRecords: Map<RowID, RowRecord | null>,\n rowsVersion: CVRVersion,\n flushed: boolean,\n ): Promise<number> {\n const cache = await this.#ensureLoaded();\n for (const [id, row] of rowRecords.entries()) {\n if (row === null || row.refCounts === null) {\n cache.delete(id);\n } else {\n cache.set(id, row);\n }\n if (!flushed) {\n this.#pending.set(id, row);\n }\n }\n this.#pendingRowsVersion = rowsVersion;\n // Initiate a flush if not already flushing.\n if (!flushed && this.#flushing === null) {\n this.#flushing = resolver();\n // The #flush() method handles propagating errors to #failService.\n // Attach a rejection handler to this promise to avoid unhandled\n // rejections.\n this.#flushing.promise.catch(() => {});\n this.#setTimeout(() => this.#flush(), 0);\n }\n return cache.size;\n }\n\n async #flush() {\n const flushing = must(this.#flushing);\n try {\n while (this.#pendingRowsVersion !== this.#flushedRowsVersion) {\n const start = performance.now();\n\n const {rows, rowsVersion} = await runTx(\n this.#db,\n tx => {\n // Note: This code block is synchronous, guaranteeing that the\n // #pendingRowsVersion is consistent with the #pending rows.\n const rows = this.#pending.size;\n const rowsVersion = must(this.#pendingRowsVersion);\n // Awaiting all of the individual statements incurs too much\n // overhead. Instead, just catch and log exception(s); the outer\n // transaction will properly fail.\n void Promise.all(\n this.executeRowUpdates(tx, rowsVersion, this.#pending, 'force'),\n ).catch(e => this.#lc.error?.(`error flushing cvr rows`, e));\n\n this.#pending.clear();\n return {rows, rowsVersion};\n },\n {mode: Mode.READ_COMMITTED},\n );\n const elapsed = performance.now() - start;\n this.#lc.debug?.(\n `flushed ${rows} rows@${versionString(rowsVersion)} (${elapsed} ms)`,\n );\n this.#recordAsyncFlushStats(rows, elapsed);\n this.#flushedRowsVersion = rowsVersion;\n // Note: apply() may have called while the transaction was committing,\n // which will result in looping to commit the next #pendingRowsVersion.\n }\n this.#lc.debug?.(\n `up to date rows@${versionToNullableCookie(this.#flushedRowsVersion)}`,\n );\n flushing.resolve();\n this.#flushing = null;\n } catch (e) {\n flushing.reject(e);\n this.#failService(e);\n }\n }\n\n hasPendingUpdates() {\n return this.#flushing !== null;\n }\n\n /**\n * Returns a promise that resolves when all outstanding row-records\n * have been committed.\n */\n flushed(lc: LogContext): Promise<void> {\n if (this.#flushing) {\n lc.debug?.('awaiting pending row flush');\n return this.#flushing.promise;\n }\n return promiseVoid;\n }\n\n clear() {\n // Note: Only the #cache is cleared. #pending updates, on the other hand,\n // comprise canonical (i.e. already flushed) data and must be flushed\n // even if the snapshot of the present state (the #cache) is cleared.\n this.#cache = undefined;\n }\n\n async *catchupRowPatches(\n lc: LogContext,\n afterVersion: NullableCVRVersion,\n upToCVR: CVRSnapshot,\n current: CVRVersion,\n excludeQueryHashes: string[] = [],\n ): AsyncGenerator<RowsRow[], void, undefined> {\n if (cmpVersions(afterVersion, upToCVR.version) >= 0) {\n return;\n }\n\n const startMs = Date.now();\n const start = afterVersion ? versionString(afterVersion) : '';\n const end = versionString(upToCVR.version);\n lc.debug?.(`scanning row patches for clients from ${start}`);\n\n // Before accessing the CVR db, pending row records must be flushed.\n // Note that because catchupRowPatches() is called from within the\n // view syncer lock, this flush is guaranteed to complete since no\n // new CVR updates can happen while the lock is held.\n await this.flushed(lc);\n const flushMs = Date.now() - startMs;\n\n const reader = new TransactionPool(lc, Mode.READONLY).run(this.#db);\n try {\n // Verify that we are reading the right version of the CVR.\n await reader.processReadTask(tx =>\n checkVersion(tx, this.#schema, this.#cvrID, current),\n );\n\n const {query} = await reader.processReadTask(tx => {\n const query =\n excludeQueryHashes.length === 0\n ? tx<RowsRow[]>`SELECT * FROM ${this.#cvr('rows')}\n WHERE \"clientGroupID\" = ${this.#cvrID}\n AND \"patchVersion\" > ${start}\n AND \"patchVersion\" <= ${end}`\n : // Exclude rows that were already sent as part of query hydration.\n tx<RowsRow[]>`SELECT * FROM ${this.#cvr('rows')}\n WHERE \"clientGroupID\" = ${this.#cvrID}\n AND \"patchVersion\" > ${start}\n AND \"patchVersion\" <= ${end}\n AND (\"refCounts\" IS NULL OR NOT \"refCounts\" ?| ${excludeQueryHashes})`;\n return {query};\n });\n\n yield* query.cursor(10000);\n } finally {\n reader.setDone();\n }\n\n const totalMs = Date.now() - startMs;\n lc.debug?.(\n `finished row catchup (flush: ${flushMs} ms, total: ${totalMs} ms)`,\n );\n }\n\n executeRowUpdates(\n tx: PostgresTransaction,\n version: CVRVersion,\n rowUpdates: Map<RowID, RowRecord | null>,\n mode: 'allow-defer' | 'force',\n lc = this.#lc,\n ): PendingQuery<Row[]>[] {\n if (\n mode === 'allow-defer' &&\n // defer if pending rows are being flushed\n (this.#flushing !== null ||\n // or if the new batch is above the limit.\n rowUpdates.size > this.#deferredRowFlushThreshold)\n ) {\n return [];\n }\n const rowsVersion = {\n clientGroupID: this.#cvrID,\n version: versionString(version),\n };\n const pending: PendingQuery<Row[]>[] = [\n tx`INSERT INTO ${this.#cvr('rowsVersion')} ${tx(rowsVersion)}\n ON CONFLICT (\"clientGroupID\") \n DO UPDATE SET ${tx(rowsVersion)}`,\n ];\n\n const rowRecordRows: RowsRow[] = [];\n for (const [id, row] of rowUpdates.entries()) {\n if (row === null) {\n pending.push(\n tx`\n DELETE FROM ${this.#cvr('rows')}\n WHERE \"clientGroupID\" = ${this.#cvrID}\n AND \"schema\" = ${id.schema}\n AND \"table\" = ${id.table}\n AND \"rowKey\" = ${id.rowKey}\n `,\n );\n } else {\n rowRecordRows.push(rowRecordToRowsRow(this.#cvrID, row));\n }\n }\n if (rowRecordRows.length) {\n pending.push(\n tx`\n INSERT INTO ${this.#cvr('rows')}(\n \"clientGroupID\", \"schema\", \"table\", \"rowKey\", \"rowVersion\", \"patchVersion\", \"refCounts\"\n ) SELECT\n \"clientGroupID\", \"schema\", \"table\", \"rowKey\", \"rowVersion\", \"patchVersion\", \"refCounts\"\n FROM json_to_recordset(${rowRecordRows}) AS x(\n \"clientGroupID\" TEXT,\n \"schema\" TEXT,\n \"table\" TEXT,\n \"rowKey\" JSONB,\n \"rowVersion\" TEXT,\n \"patchVersion\" TEXT,\n \"refCounts\" JSONB\n ) ON CONFLICT (\"clientGroupID\", \"schema\", \"table\", \"rowKey\")\n DO UPDATE SET \"rowVersion\" = excluded.\"rowVersion\",\n \"patchVersion\" = excluded.\"patchVersion\",\n \"refCounts\" = excluded.\"refCounts\"\n `,\n );\n lc.debug?.(\n `flushing ${rowUpdates.size} rows (${rowRecordRows.length} inserts, ${\n rowUpdates.size - rowRecordRows.length\n } deletes)`,\n );\n }\n return pending;\n }\n}\n"],"names":["rows","rowsVersion","Mode.READ_COMMITTED","Mode.READONLY","query"],"mappings":"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"}
1
+ {"version":3,"file":"row-record-cache.js","names":["#lc","#db","#schema","#cvrID","#failService","#deferredRowFlushThreshold","#setTimeout","#pending","#cvrFlushTime","#cvrRowsFlushed","#ensureLoaded","#cache","#cvr","#pendingRowsVersion","#flushing","#flush","#flushedRowsVersion","#recordAsyncFlushStats"],"sources":["../../../../../../zero-cache/src/services/view-syncer/row-record-cache.ts"],"sourcesContent":["import type {LogContext} from '@rocicorp/logger';\nimport {type Resolver, resolver} from '@rocicorp/resolver';\nimport type {PendingQuery, Row} from 'postgres';\nimport {CustomKeyMap} from '../../../../shared/src/custom-key-map.ts';\nimport {must} from '../../../../shared/src/must.ts';\nimport {promiseVoid} from '../../../../shared/src/resolved-promises.ts';\nimport * as Mode from '../../db/mode-enum.ts';\nimport {runTx} from '../../db/run-transaction.ts';\nimport {TransactionPool} from '../../db/transaction-pool.ts';\nimport {\n getOrCreateCounter,\n getOrCreateHistogram,\n} from '../../observability/metrics.ts';\nimport {type PostgresDB, type PostgresTransaction} from '../../types/pg.ts';\nimport {rowIDString} from '../../types/row-key.ts';\nimport {cvrSchema, type ShardID} from '../../types/shards.ts';\nimport {checkVersion, type CVRFlushStats} from './cvr-store.ts';\nimport type {CVRSnapshot} from './cvr.ts';\nimport {\n rowRecordToRowsRow,\n type RowsRow,\n rowsRowToRowRecord,\n} from './schema/cvr.ts';\nimport {\n cmpVersions,\n type CVRVersion,\n type NullableCVRVersion,\n type RowID,\n type RowRecord,\n versionString,\n versionToNullableCookie,\n} from './schema/types.ts';\n\nconst FLUSH_TYPE_ATTRIBUTE = 'flush.type';\n\n/**\n * The RowRecordCache is an in-memory cache of the `cvr.rows` tables that\n * operates as both a write-through and write-back cache.\n *\n * For \"small\" CVR updates (i.e. zero or small numbers of rows) the\n * RowRecordCache operates as write-through, executing commits in\n * {@link executeRowUpdates()} before they are {@link apply}-ed to the\n * in-memory state.\n *\n * For \"large\" CVR updates (i.e. with many rows), the cache switches to a\n * write-back mode of operation, in which {@link executeRowUpdates()} is a\n * no-op, and {@link apply()} initiates a background task to flush the pending\n * row changes to the store. This allows the client poke to be completed and\n * committed on the client without waiting for the heavyweight operation of\n * committing the row records to the CVR store.\n *\n * Note that when the cache is in write-back mode, all updates become\n * write-back (i.e. asynchronously flushed) until the pending update queue is\n * fully flushed. This is required because updates must be applied in version\n * order. As with all pending work systems in zero-cache, multiple pending\n * updates are coalesced to reduce buildup of work.\n *\n * ### High level consistency\n *\n * Note that the above caching scheme only applies to the row data in `cvr.rows`\n * and corresponding `cvr.rowsVersion` tables. CVR metadata and query\n * information, on the other hand, are always committed before completing the\n * client poke. In this manner, the difference between the `version` column in\n * `cvr.instances` and the analogous column in `cvr.rowsVersion` determines\n * whether the data in the store is consistent, or whether it is awaiting a\n * pending update.\n *\n * The logic in {@link CVRStore#load()} takes this into account by loading both\n * the `cvr.instances` version and the `cvr.rowsVersion` version and checking\n * if they are in sync, waiting for a configurable delay until they are.\n *\n * ### Eventual conversion\n *\n * In the event of a continual stream of mutations (e.g. an animation-style\n * app), it is conceivable that the row record data be continually behind\n * the CVR metadata. In order to effect eventual convergence, a new view-syncer\n * signals the current view-syncer to stop updating by writing new `owner`\n * information to the `cvr.instances` row. This effectively stops the mutation\n * processing (in {@link CVRStore.#checkVersionAndOwnership}) so that the row\n * data can eventually catch up, allowing the new view-syncer to take over.\n *\n * Of course, there is the pathological situation in which a view-syncer\n * process crashes before the pending row updates are flushed. In this case,\n * the wait timeout will elapse and the CVR considered invalid.\n */\nexport class RowRecordCache {\n // The state in the #cache is always in sync with the CVR metadata\n // (i.e. cvr.instances). It may contain information that has not yet\n // been flushed to cvr.rows.\n #cache: Promise<CustomKeyMap<RowID, RowRecord>> | undefined;\n readonly #lc: LogContext;\n readonly #db: PostgresDB;\n readonly #schema: string;\n readonly #cvrID: string;\n readonly #failService: (e: unknown) => void;\n readonly #deferredRowFlushThreshold: number;\n readonly #setTimeout: typeof setTimeout;\n\n // Write-back cache state.\n readonly #pending = new CustomKeyMap<RowID, RowRecord | null>(rowIDString);\n #pendingRowsVersion: CVRVersion | null = null;\n #flushedRowsVersion: CVRVersion | null = null;\n #flushing: Resolver<void> | null = null;\n\n readonly #cvrFlushTime = getOrCreateHistogram('sync', 'cvr.flush-time', {\n description:\n 'Time to flush a CVR transaction. This includes both synchronous ' +\n 'and asynchronous flushes, distinguished by the flush.type attribute',\n unit: 's',\n });\n readonly #cvrRowsFlushed = getOrCreateCounter(\n 'sync',\n 'cvr.rows-flushed',\n 'Number of (changed) rows flushed to a CVR',\n );\n\n constructor(\n lc: LogContext,\n db: PostgresDB,\n shard: ShardID,\n cvrID: string,\n failService: (e: unknown) => void,\n deferredRowFlushThreshold = 100,\n setTimeoutFn = setTimeout,\n ) {\n this.#lc = lc;\n this.#db = db;\n this.#schema = cvrSchema(shard);\n this.#cvrID = cvrID;\n this.#failService = failService;\n this.#deferredRowFlushThreshold = deferredRowFlushThreshold;\n this.#setTimeout = setTimeoutFn;\n }\n\n recordSyncFlushStats(stats: CVRFlushStats, elapsedMs: number) {\n this.#cvrFlushTime.record(elapsedMs / 1000, {\n [FLUSH_TYPE_ATTRIBUTE]: 'sync',\n });\n if (stats.rowsDeferred === 0) {\n this.#cvrRowsFlushed.add(stats.rows);\n }\n }\n\n #recordAsyncFlushStats(rows: number, elapsedMs: number) {\n this.#cvrFlushTime.record(elapsedMs / 1000, {\n [FLUSH_TYPE_ATTRIBUTE]: 'async',\n });\n this.#cvrRowsFlushed.add(rows);\n }\n\n #cvr(table: string) {\n return this.#db(`${this.#schema}.${table}`);\n }\n\n async #ensureLoaded(): Promise<CustomKeyMap<RowID, RowRecord>> {\n if (this.#cache) {\n return this.#cache;\n }\n const start = Date.now();\n const r = resolver<CustomKeyMap<RowID, RowRecord>>();\n r.promise.catch(() => {});\n // Set this.#cache immediately (before await) so that only one db\n // query is made even if there are multiple callers.\n this.#cache = r.promise;\n try {\n const cache: CustomKeyMap<RowID, RowRecord> = new CustomKeyMap(\n rowIDString,\n );\n for await (const rows of this.#db<RowsRow[]>`\n SELECT * FROM ${this.#cvr(`rows`)}\n WHERE \"clientGroupID\" = ${this.#cvrID} AND \"refCounts\" IS NOT NULL`\n // TODO(arv): Arbitrary page size\n .cursor(5000)) {\n for (const row of rows) {\n const rowRecord = rowsRowToRowRecord(row);\n cache.set(rowRecord.id, rowRecord);\n }\n }\n this.#lc.info?.(\n `Loaded ${cache.size} row records in ${Date.now() - start} ms`,\n );\n r.resolve(cache);\n return this.#cache;\n } catch (e) {\n r.reject(e); // Make sure the error is reflected in the cached promise\n throw e;\n }\n }\n\n getRowRecords(): Promise<ReadonlyMap<RowID, RowRecord>> {\n return this.#ensureLoaded();\n }\n\n /**\n * Applies the `rowRecords` corresponding to the `rowsVersion`\n * to the cache, indicating whether the corresponding updates\n * (generated by {@link executeRowUpdates}) were `flushed`.\n *\n * If `flushed` is false, the RowRecordCache will flush the records\n * asynchronously.\n *\n * Note that `apply()` indicates that the CVR metadata associated with\n * the `rowRecords` was successfully committed, which essentially means\n * that this process has the unconditional right (and responsibility) of\n * following up with a flush of the `rowRecords`. In particular, the\n * commit of row records are not conditioned on the version or ownership\n * columns of the `cvr.instances` row.\n */\n async apply(\n rowRecords: Map<RowID, RowRecord | null>,\n rowsVersion: CVRVersion,\n flushed: boolean,\n ): Promise<number> {\n const cache = await this.#ensureLoaded();\n for (const [id, row] of rowRecords.entries()) {\n if (row === null || row.refCounts === null) {\n cache.delete(id);\n } else {\n cache.set(id, row);\n }\n if (!flushed) {\n this.#pending.set(id, row);\n }\n }\n this.#pendingRowsVersion = rowsVersion;\n // Initiate a flush if not already flushing.\n if (!flushed && this.#flushing === null) {\n this.#flushing = resolver();\n // The #flush() method handles propagating errors to #failService.\n // Attach a rejection handler to this promise to avoid unhandled\n // rejections.\n this.#flushing.promise.catch(() => {});\n this.#setTimeout(() => this.#flush(), 0);\n }\n return cache.size;\n }\n\n async #flush() {\n const flushing = must(this.#flushing);\n try {\n while (this.#pendingRowsVersion !== this.#flushedRowsVersion) {\n const start = performance.now();\n\n const {rows, rowsVersion} = await runTx(\n this.#db,\n tx => {\n // Note: This code block is synchronous, guaranteeing that the\n // #pendingRowsVersion is consistent with the #pending rows.\n const rows = this.#pending.size;\n const rowsVersion = must(this.#pendingRowsVersion);\n // Awaiting all of the individual statements incurs too much\n // overhead. Instead, just catch and log exception(s); the outer\n // transaction will properly fail.\n void Promise.all(\n this.executeRowUpdates(tx, rowsVersion, this.#pending, 'force'),\n ).catch(e => this.#lc.error?.(`error flushing cvr rows`, e));\n\n this.#pending.clear();\n return {rows, rowsVersion};\n },\n {mode: Mode.READ_COMMITTED},\n );\n const elapsed = performance.now() - start;\n this.#lc.info?.(\n `flushed ${rows} rows@${versionString(rowsVersion)} (${elapsed} ms)`,\n );\n this.#recordAsyncFlushStats(rows, elapsed);\n this.#flushedRowsVersion = rowsVersion;\n // Note: apply() may have called while the transaction was committing,\n // which will result in looping to commit the next #pendingRowsVersion.\n }\n this.#lc.info?.(\n `up to date rows@${versionToNullableCookie(this.#flushedRowsVersion)}`,\n );\n flushing.resolve();\n this.#flushing = null;\n } catch (e) {\n this.#lc.info?.(`row record flush failed`, e);\n flushing.reject(e);\n this.#failService(e);\n }\n }\n\n hasPendingUpdates() {\n return this.#flushing !== null;\n }\n\n /**\n * Returns a promise that resolves when all outstanding row-records\n * have been committed.\n */\n flushed(lc: LogContext): Promise<void> {\n if (this.#flushing) {\n lc.debug?.('awaiting pending row flush');\n return this.#flushing.promise;\n }\n return promiseVoid;\n }\n\n clear() {\n // Note: Only the #cache is cleared. #pending updates, on the other hand,\n // comprise canonical (i.e. already flushed) data and must be flushed\n // even if the snapshot of the present state (the #cache) is cleared.\n this.#cache = undefined;\n }\n\n async *catchupRowPatches(\n lc: LogContext,\n afterVersion: NullableCVRVersion,\n upToCVR: CVRSnapshot,\n current: CVRVersion,\n excludeQueryHashes: string[] = [],\n ): AsyncGenerator<RowsRow[], void, undefined> {\n if (cmpVersions(afterVersion, upToCVR.version) >= 0) {\n return;\n }\n\n const startMs = Date.now();\n const start = afterVersion ? versionString(afterVersion) : '';\n const end = versionString(upToCVR.version);\n lc.debug?.(`scanning row patches for clients from ${start}`);\n\n // Before accessing the CVR db, pending row records must be flushed.\n // Note that because catchupRowPatches() is called from within the\n // view syncer lock, this flush is guaranteed to complete since no\n // new CVR updates can happen while the lock is held.\n await this.flushed(lc);\n const flushMs = Date.now() - startMs;\n\n const reader = new TransactionPool(lc, Mode.READONLY).run(this.#db);\n try {\n // Verify that we are reading the right version of the CVR.\n await reader.processReadTask(tx =>\n checkVersion(tx, this.#schema, this.#cvrID, current),\n );\n\n const {query} = await reader.processReadTask(tx => {\n const query =\n excludeQueryHashes.length === 0\n ? tx<RowsRow[]>`SELECT * FROM ${this.#cvr('rows')}\n WHERE \"clientGroupID\" = ${this.#cvrID}\n AND \"patchVersion\" > ${start}\n AND \"patchVersion\" <= ${end}`\n : // Exclude rows that were already sent as part of query hydration.\n tx<RowsRow[]>`SELECT * FROM ${this.#cvr('rows')}\n WHERE \"clientGroupID\" = ${this.#cvrID}\n AND \"patchVersion\" > ${start}\n AND \"patchVersion\" <= ${end}\n AND (\"refCounts\" IS NULL OR NOT \"refCounts\" ?| ${excludeQueryHashes})`;\n return {query};\n });\n\n yield* query.cursor(10000);\n } finally {\n reader.setDone();\n }\n\n const totalMs = Date.now() - startMs;\n lc.info?.(\n `finished row catchup (flush: ${flushMs} ms, total: ${totalMs} ms)`,\n );\n }\n\n executeRowUpdates(\n tx: PostgresTransaction,\n version: CVRVersion,\n rowUpdates: Map<RowID, RowRecord | null>,\n mode: 'allow-defer' | 'force',\n lc = this.#lc,\n ): PendingQuery<Row[]>[] {\n if (\n mode === 'allow-defer' &&\n // defer if pending rows are being flushed\n (this.#flushing !== null ||\n // or if the new batch is above the limit.\n rowUpdates.size > this.#deferredRowFlushThreshold)\n ) {\n return [];\n }\n const rowsVersion = {\n clientGroupID: this.#cvrID,\n version: versionString(version),\n };\n const pending: PendingQuery<Row[]>[] = [\n tx`INSERT INTO ${this.#cvr('rowsVersion')} ${tx(rowsVersion)}\n ON CONFLICT (\"clientGroupID\") \n DO UPDATE SET ${tx(rowsVersion)}`,\n ];\n\n const rowRecordRows: RowsRow[] = [];\n for (const [id, row] of rowUpdates.entries()) {\n if (row === null) {\n pending.push(\n tx`\n DELETE FROM ${this.#cvr('rows')}\n WHERE \"clientGroupID\" = ${this.#cvrID}\n AND \"schema\" = ${id.schema}\n AND \"table\" = ${id.table}\n AND \"rowKey\" = ${id.rowKey}\n `,\n );\n } else {\n rowRecordRows.push(rowRecordToRowsRow(this.#cvrID, row));\n }\n }\n if (rowRecordRows.length) {\n pending.push(\n tx`\n INSERT INTO ${this.#cvr('rows')}(\n \"clientGroupID\", \"schema\", \"table\", \"rowKey\", \"rowVersion\", \"patchVersion\", \"refCounts\"\n ) SELECT\n \"clientGroupID\", \"schema\", \"table\", \"rowKey\", \"rowVersion\", \"patchVersion\", \"refCounts\"\n FROM json_to_recordset(${rowRecordRows}) AS x(\n \"clientGroupID\" TEXT,\n \"schema\" TEXT,\n \"table\" TEXT,\n \"rowKey\" JSONB,\n \"rowVersion\" TEXT,\n \"patchVersion\" TEXT,\n \"refCounts\" JSONB\n ) ON CONFLICT (\"clientGroupID\", \"schema\", \"table\", \"rowKey\")\n DO UPDATE SET \"rowVersion\" = excluded.\"rowVersion\",\n \"patchVersion\" = excluded.\"patchVersion\",\n \"refCounts\" = excluded.\"refCounts\"\n `,\n );\n lc.info?.(\n `flushing ${rowUpdates.size} rows (${rowRecordRows.length} inserts, ${\n rowUpdates.size - rowRecordRows.length\n } deletes)`,\n );\n }\n return pending;\n }\n}\n"],"mappings":"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"}
@@ -1,18 +1,17 @@
1
- import { ident } from "pg-format";
2
1
  import "../../../../../shared/src/bigint-json.js";
3
- import "js-xxhash";
4
2
  import { cvrSchema } from "../../../types/shards.js";
3
+ import "../../../types/row-key.js";
5
4
  import { versionFromString, versionString } from "./types.js";
5
+ import { ident } from "pg-format";
6
+ //#region ../zero-cache/src/services/view-syncer/schema/cvr.ts
6
7
  function schema(shard) {
7
- return ident(cvrSchema(shard));
8
+ return ident(cvrSchema(shard));
8
9
  }
9
10
  function createSchema(shard) {
10
- return `CREATE SCHEMA IF NOT EXISTS ${schema(shard)};`;
11
+ return `CREATE SCHEMA IF NOT EXISTS ${schema(shard)};`;
11
12
  }
12
13
  function createInstancesTable(shard) {
13
- return (
14
- /*sql*/
15
- `
14
+ return `
16
15
  CREATE TABLE ${schema(shard)}.instances (
17
16
  "clientGroupID" TEXT PRIMARY KEY,
18
17
  "version" TEXT NOT NULL, -- Sortable representation of CVRVersion, e.g. "5nbqa2w:09"
@@ -37,11 +36,10 @@ CREATE INDEX tombstones_last_active
37
36
  -- an index scan without additional table lookups.
38
37
  CREATE INDEX profile_ids_last_active ON ${schema(shard)}.instances ("lastActive", "profileID")
39
38
  WHERE "profileID" IS NOT NULL;
40
- `
41
- );
39
+ `;
42
40
  }
43
41
  function createClientsTable(shard) {
44
- return `
42
+ return `
45
43
  CREATE TABLE ${schema(shard)}.clients (
46
44
  "clientGroupID" TEXT,
47
45
  "clientID" TEXT,
@@ -57,7 +55,7 @@ CREATE TABLE ${schema(shard)}.clients (
57
55
  `;
58
56
  }
59
57
  function createQueriesTable(shard) {
60
- return `
58
+ return `
61
59
  CREATE TABLE ${schema(shard)}.queries (
62
60
  "clientGroupID" TEXT,
63
61
  "queryHash" TEXT, -- this is the hash of the client query AST
@@ -84,7 +82,7 @@ CREATE INDEX queries_patch_version
84
82
  `;
85
83
  }
86
84
  function createDesiresTable(shard) {
87
- return `
85
+ return `
88
86
  CREATE TABLE ${schema(shard)}.desires (
89
87
  "clientGroupID" TEXT,
90
88
  "clientID" TEXT,
@@ -113,41 +111,61 @@ CREATE INDEX desires_inactivated_at
113
111
  `;
114
112
  }
115
113
  function rowsRowToRowID(rowsRow) {
116
- return {
117
- schema: rowsRow.schema,
118
- table: rowsRow.table,
119
- rowKey: rowsRow.rowKey
120
- };
114
+ return {
115
+ schema: rowsRow.schema,
116
+ table: rowsRow.table,
117
+ rowKey: rowsRow.rowKey
118
+ };
121
119
  }
122
120
  function rowsRowToRowRecord(rowsRow) {
123
- return {
124
- id: rowsRowToRowID(rowsRow),
125
- rowVersion: rowsRow.rowVersion,
126
- patchVersion: versionFromString(rowsRow.patchVersion),
127
- refCounts: rowsRow.refCounts
128
- };
121
+ return {
122
+ id: rowsRowToRowID(rowsRow),
123
+ rowVersion: rowsRow.rowVersion,
124
+ patchVersion: versionFromString(rowsRow.patchVersion),
125
+ refCounts: rowsRow.refCounts
126
+ };
129
127
  }
130
128
  function rowRecordToRowsRow(clientGroupID, rowRecord) {
131
- return {
132
- clientGroupID,
133
- schema: rowRecord.id.schema,
134
- table: rowRecord.id.table,
135
- rowKey: rowRecord.id.rowKey,
136
- rowVersion: rowRecord.rowVersion,
137
- patchVersion: versionString(rowRecord.patchVersion),
138
- refCounts: rowRecord.refCounts
139
- };
129
+ return {
130
+ clientGroupID,
131
+ schema: rowRecord.id.schema,
132
+ table: rowRecord.id.table,
133
+ rowKey: rowRecord.id.rowKey,
134
+ rowVersion: rowRecord.rowVersion,
135
+ patchVersion: versionString(rowRecord.patchVersion),
136
+ refCounts: rowRecord.refCounts
137
+ };
140
138
  }
139
+ /**
140
+ * The version of the data in the `cvr.rows` table. This may lag
141
+ * `version` in `cvr.instances` but eventually catches up, modulo
142
+ * exceptional circumstances like a server crash.
143
+ *
144
+ * The `rowsVersion` is tracked in a separate table (as opposed to
145
+ * a column in the `cvr.instances` table) so that general `cvr` updates
146
+ * and `row` updates can be executed independently without serialization
147
+ * conflicts.
148
+ *
149
+ * Note: Although `clientGroupID` logically references the same column in
150
+ * `cvr.instances`, a FOREIGN KEY constraint must not be declared as the
151
+ * `cvr.rows` TABLE needs to be updated without affecting the
152
+ * `SELECT ... FOR UPDATE` lock when `cvr.instances` is updated.
153
+ */
141
154
  function createRowsVersionTable(shard) {
142
- return `
155
+ return `
143
156
  CREATE TABLE ${schema(shard)}."rowsVersion" (
144
157
  "clientGroupID" TEXT PRIMARY KEY,
145
158
  "version" TEXT NOT NULL
146
159
  );
147
160
  `;
148
161
  }
162
+ /**
163
+ * CVR `rows` are updated asynchronously from the CVR metadata
164
+ * (i.e. `instances`). The `rowsVersion` table is updated atomically with
165
+ * updates to the `rows` data.
166
+ */
149
167
  function createRowsTable(shard) {
150
- return `
168
+ return `
151
169
  CREATE TABLE ${schema(shard)}.rows (
152
170
  "clientGroupID" TEXT,
153
171
  "schema" TEXT,
@@ -176,17 +194,13 @@ CREATE INDEX row_ref_counts ON ${schema(shard)}.rows
176
194
  `;
177
195
  }
178
196
  function createTables(shard) {
179
- return createSchema(shard) + createInstancesTable(shard) + createClientsTable(shard) + createQueriesTable(shard) + createDesiresTable(shard) + createRowsVersionTable(shard) + createRowsTable(shard);
197
+ return createSchema(shard) + createInstancesTable(shard) + createClientsTable(shard) + createQueriesTable(shard) + createDesiresTable(shard) + createRowsVersionTable(shard) + createRowsTable(shard);
180
198
  }
181
199
  async function setupCVRTables(lc, db, shard) {
182
- lc.info?.(`Setting up CVR tables`);
183
- await db.unsafe(createTables(shard));
200
+ lc.info?.(`Setting up CVR tables`);
201
+ await db.unsafe(createTables(shard));
184
202
  }
185
- export {
186
- createRowsVersionTable,
187
- rowRecordToRowsRow,
188
- rowsRowToRowID,
189
- rowsRowToRowRecord,
190
- setupCVRTables
191
- };
192
- //# sourceMappingURL=cvr.js.map
203
+ //#endregion
204
+ export { createRowsVersionTable, rowRecordToRowsRow, rowsRowToRowRecord, setupCVRTables };
205
+
206
+ //# sourceMappingURL=cvr.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"cvr.js","sources":["../../../../../../../zero-cache/src/services/view-syncer/schema/cvr.ts"],"sourcesContent":["import type {LogContext} from '@rocicorp/logger';\nimport {ident} from 'pg-format';\nimport type postgres from 'postgres';\nimport {\n type JSONObject,\n type JSONValue,\n stringify,\n} from '../../../../../shared/src/bigint-json.ts';\nimport type {ReadonlyJSONValue} from '../../../../../shared/src/json.ts';\nimport {stringCompare} from '../../../../../shared/src/string-compare.ts';\nimport type {ClientSchema} from '../../../../../zero-protocol/src/client-schema.ts';\nimport {normalizedKeyOrder, type RowKey} from '../../../types/row-key.ts';\nimport {cvrSchema, type ShardID} from '../../../types/shards.ts';\nimport type {TTLClock} from '../ttl-clock.ts';\nimport {\n type RowID,\n type RowRecord,\n versionFromString,\n versionString,\n} from './types.ts';\n\n// For readability in the sql statements.\nfunction schema(shard: ShardID) {\n return ident(cvrSchema(shard));\n}\n\nfunction createSchema(shard: ShardID) {\n return `CREATE SCHEMA IF NOT EXISTS ${schema(shard)};`;\n}\n\nexport type InstancesRow = {\n clientGroupID: string;\n version: string;\n lastActive: number;\n ttlClock: TTLClock;\n replicaVersion: string | null;\n owner: string | null;\n grantedAt: number | null;\n clientSchema: ClientSchema | null;\n profileID: string | null;\n};\n\nfunction createInstancesTable(shard: ShardID) {\n return /*sql*/ `\nCREATE TABLE ${schema(shard)}.instances (\n \"clientGroupID\" TEXT PRIMARY KEY,\n \"version\" TEXT NOT NULL, -- Sortable representation of CVRVersion, e.g. \"5nbqa2w:09\"\n \"lastActive\" TIMESTAMPTZ NOT NULL, -- For garbage collection\n \"ttlClock\" DOUBLE PRECISION NOT NULL DEFAULT 0, -- The ttl clock gets \"paused\" when disconnected.\n \"replicaVersion\" TEXT, -- Identifies the replica (i.e. initial-sync point) from which the CVR data comes.\n \"owner\" TEXT, -- The ID of the task / server that has been granted ownership of the CVR.\n \"grantedAt\" TIMESTAMPTZ, -- The time at which the current owner was last granted ownership (most recent connection time).\n \"clientSchema\" JSONB, -- ClientSchema of the client group\n \"profileID\" TEXT, -- Stable profile id (\"p...\"), falling back to the clientGroupID (\"cg{clientGroupID}\") for old clients\n \"deleted\" BOOL DEFAULT FALSE -- Tombstone column for deleted CVRs; instances rows are kept longer for usage stats\n);\n\n-- For garbage collection.\nCREATE INDEX instances_last_active\n ON ${schema(shard)}.instances (\"lastActive\") WHERE NOT \"deleted\";\nCREATE INDEX tombstones_last_active\n ON ${schema(shard)}.instances (\"lastActive\") WHERE \"deleted\";\n\n-- For usage stats; the composite index allows a \n-- SELECT COUNT(DISTINCT(\"profileID\")) query to be answered by\n-- an index scan without additional table lookups.\nCREATE INDEX profile_ids_last_active ON ${schema(shard)}.instances (\"lastActive\", \"profileID\")\n WHERE \"profileID\" IS NOT NULL;\n`;\n}\n\nexport function compareInstancesRows(a: InstancesRow, b: InstancesRow) {\n return stringCompare(a.clientGroupID, b.clientGroupID);\n}\n\nexport type ClientsRow = {\n clientGroupID: string;\n clientID: string;\n};\n\nfunction createClientsTable(shard: ShardID) {\n return `\nCREATE TABLE ${schema(shard)}.clients (\n \"clientGroupID\" TEXT,\n \"clientID\" TEXT,\n\n PRIMARY KEY (\"clientGroupID\", \"clientID\"),\n\n CONSTRAINT fk_clients_client_group\n FOREIGN KEY(\"clientGroupID\")\n REFERENCES ${schema(shard)}.instances(\"clientGroupID\")\n ON DELETE CASCADE\n);\n\n`;\n}\nexport function compareClientsRows(a: ClientsRow, b: ClientsRow) {\n const clientGroupIDComp = stringCompare(a.clientGroupID, b.clientGroupID);\n if (clientGroupIDComp !== 0) {\n return clientGroupIDComp;\n }\n return stringCompare(a.clientID, b.clientID);\n}\n\nexport type QueriesRow = {\n clientGroupID: string;\n queryHash: string;\n // This is the client AST _AFTER_ applying server name transformations.\n clientAST: JSONValue | null;\n queryName: string | null;\n queryArgs: readonly ReadonlyJSONValue[] | null;\n patchVersion: string | null;\n transformationHash: string | null;\n transformationVersion: string | null;\n internal: boolean | null;\n deleted: boolean | null;\n};\n\nfunction createQueriesTable(shard: ShardID) {\n return `\nCREATE TABLE ${schema(shard)}.queries (\n \"clientGroupID\" TEXT,\n \"queryHash\" TEXT, -- this is the hash of the client query AST\n \"clientAST\" JSONB, -- this is nullable as custom queries will not persist an AST\n \"queryName\" TEXT, -- the name of the query if it is a custom query\n \"queryArgs\" JSON, -- the arguments of the query if it is a custom query\n \"patchVersion\" TEXT, -- NULL if only desired but not yet \"got\"\n \"transformationHash\" TEXT,\n \"transformationVersion\" TEXT,\n \"internal\" BOOL, -- If true, no need to track / send patches\n \"deleted\" BOOL, -- put vs del \"got\" query\n\n PRIMARY KEY (\"clientGroupID\", \"queryHash\"),\n\n CONSTRAINT fk_queries_client_group\n FOREIGN KEY(\"clientGroupID\")\n REFERENCES ${schema(shard)}.instances(\"clientGroupID\")\n ON DELETE CASCADE\n);\n\n-- For catchup patches.\nCREATE INDEX queries_patch_version \n ON ${schema(shard)}.queries (\"patchVersion\" NULLS FIRST);\n`;\n}\n\nexport function compareQueriesRows(a: QueriesRow, b: QueriesRow) {\n const clientGroupIDComp = stringCompare(a.clientGroupID, b.clientGroupID);\n if (clientGroupIDComp !== 0) {\n return clientGroupIDComp;\n }\n return stringCompare(a.queryHash, b.queryHash);\n}\n\nexport type DesiresRow = {\n clientGroupID: string;\n clientID: string;\n queryHash: string;\n patchVersion: string;\n deleted: boolean | null;\n ttl: number | null;\n inactivatedAt: TTLClock | null;\n};\n\nfunction createDesiresTable(shard: ShardID) {\n return `\nCREATE TABLE ${schema(shard)}.desires (\n \"clientGroupID\" TEXT,\n \"clientID\" TEXT,\n \"queryHash\" TEXT,\n \"patchVersion\" TEXT NOT NULL,\n \"deleted\" BOOL, -- put vs del \"desired\" query\n \"ttl\" INTERVAL, -- DEPRECATED: Use ttlMs instead. Time to live for this client\n \"ttlMs\" DOUBLE PRECISION, -- Time to live in milliseconds\n \"inactivatedAt\" TIMESTAMPTZ, -- DEPRECATED: Use inactivatedAtMs instead. Time at which this row was inactivated\n \"inactivatedAtMs\" DOUBLE PRECISION, -- Time at which this row was inactivated (milliseconds since client group start)\n\n PRIMARY KEY (\"clientGroupID\", \"clientID\", \"queryHash\"),\n\n CONSTRAINT fk_desires_query\n FOREIGN KEY(\"clientGroupID\", \"queryHash\")\n REFERENCES ${ident(cvrSchema(shard))}.queries(\"clientGroupID\", \"queryHash\")\n ON DELETE CASCADE\n);\n\n-- For catchup patches.\nCREATE INDEX desires_patch_version\n ON ${schema(shard)}.desires (\"patchVersion\");\n\nCREATE INDEX desires_inactivated_at\n ON ${schema(shard)}.desires (\"inactivatedAt\");\n`;\n}\n\nexport function compareDesiresRows(a: DesiresRow, b: DesiresRow) {\n const clientGroupIDComp = stringCompare(a.clientGroupID, b.clientGroupID);\n if (clientGroupIDComp !== 0) {\n return clientGroupIDComp;\n }\n const clientIDComp = stringCompare(a.clientID, b.clientID);\n if (clientIDComp !== 0) {\n return clientIDComp;\n }\n return stringCompare(a.queryHash, b.queryHash);\n}\n\nexport type RowsRow = {\n clientGroupID: string;\n schema: string;\n table: string;\n rowKey: JSONObject;\n rowVersion: string;\n patchVersion: string;\n refCounts: {[queryHash: string]: number} | null;\n};\n\nexport function rowsRowToRowID(rowsRow: RowsRow): RowID {\n return {\n schema: rowsRow.schema,\n table: rowsRow.table,\n rowKey: rowsRow.rowKey as Record<string, JSONValue>,\n };\n}\n\nexport function rowsRowToRowRecord(rowsRow: RowsRow): RowRecord {\n return {\n id: rowsRowToRowID(rowsRow),\n rowVersion: rowsRow.rowVersion,\n patchVersion: versionFromString(rowsRow.patchVersion),\n refCounts: rowsRow.refCounts,\n };\n}\n\nexport function rowRecordToRowsRow(\n clientGroupID: string,\n rowRecord: RowRecord,\n): RowsRow {\n return {\n clientGroupID,\n schema: rowRecord.id.schema,\n table: rowRecord.id.table,\n rowKey: rowRecord.id.rowKey as Record<string, JSONValue>,\n rowVersion: rowRecord.rowVersion,\n patchVersion: versionString(rowRecord.patchVersion),\n refCounts: rowRecord.refCounts,\n };\n}\n\nexport function compareRowsRows(a: RowsRow, b: RowsRow) {\n const clientGroupIDComp = stringCompare(a.clientGroupID, b.clientGroupID);\n if (clientGroupIDComp !== 0) {\n return clientGroupIDComp;\n }\n const schemaComp = stringCompare(a.schema, b.schema);\n if (schemaComp !== 0) {\n return schemaComp;\n }\n const tableComp = stringCompare(b.table, b.table);\n if (tableComp !== 0) {\n return tableComp;\n }\n return stringCompare(\n stringifySorted(a.rowKey as RowKey),\n stringifySorted(b.rowKey as RowKey),\n );\n}\n\n/**\n * The version of the data in the `cvr.rows` table. This may lag\n * `version` in `cvr.instances` but eventually catches up, modulo\n * exceptional circumstances like a server crash.\n *\n * The `rowsVersion` is tracked in a separate table (as opposed to\n * a column in the `cvr.instances` table) so that general `cvr` updates\n * and `row` updates can be executed independently without serialization\n * conflicts.\n *\n * Note: Although `clientGroupID` logically references the same column in\n * `cvr.instances`, a FOREIGN KEY constraint must not be declared as the\n * `cvr.rows` TABLE needs to be updated without affecting the\n * `SELECT ... FOR UPDATE` lock when `cvr.instances` is updated.\n */\nexport function createRowsVersionTable(shard: ShardID) {\n return `\nCREATE TABLE ${schema(shard)}.\"rowsVersion\" (\n \"clientGroupID\" TEXT PRIMARY KEY,\n \"version\" TEXT NOT NULL\n);\n`;\n}\n\n/**\n * CVR `rows` are updated asynchronously from the CVR metadata\n * (i.e. `instances`). The `rowsVersion` table is updated atomically with\n * updates to the `rows` data.\n */\nfunction createRowsTable(shard: ShardID) {\n return `\nCREATE TABLE ${schema(shard)}.rows (\n \"clientGroupID\" TEXT,\n \"schema\" TEXT,\n \"table\" TEXT,\n \"rowKey\" JSONB,\n \"rowVersion\" TEXT NOT NULL,\n \"patchVersion\" TEXT NOT NULL,\n \"refCounts\" JSONB, -- {[queryHash: string]: number}, NULL for tombstone\n\n PRIMARY KEY (\"clientGroupID\", \"schema\", \"table\", \"rowKey\"),\n\n CONSTRAINT fk_rows_client_group\n FOREIGN KEY(\"clientGroupID\")\n REFERENCES ${schema(shard)}.\"rowsVersion\" (\"clientGroupID\")\n ON DELETE CASCADE\n);\n\n-- For catchup patches.\nCREATE INDEX row_patch_version \n ON ${schema(shard)}.rows (\"patchVersion\");\n\n-- For listing rows returned by one or more query hashes. e.g.\n-- SELECT * FROM cvr_shard.rows WHERE \"refCounts\" ?| array[...queryHashes...];\nCREATE INDEX row_ref_counts ON ${schema(shard)}.rows \n USING GIN (\"refCounts\");\n`;\n}\n\nexport type RowsVersionRow = {\n clientGroupID: string;\n version: string;\n};\n\nfunction createTables(shard: ShardID) {\n return (\n createSchema(shard) +\n createInstancesTable(shard) +\n createClientsTable(shard) +\n createQueriesTable(shard) +\n createDesiresTable(shard) +\n createRowsVersionTable(shard) +\n createRowsTable(shard)\n );\n}\n\nexport async function setupCVRTables(\n lc: LogContext,\n db: postgres.TransactionSql,\n shard: ShardID,\n) {\n lc.info?.(`Setting up CVR tables`);\n await db.unsafe(createTables(shard));\n}\n\nfunction stringifySorted(r: RowKey) {\n return stringify(normalizedKeyOrder(r));\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"cvr.js","names":[],"sources":["../../../../../../../zero-cache/src/services/view-syncer/schema/cvr.ts"],"sourcesContent":["import type {LogContext} from '@rocicorp/logger';\nimport {ident} from 'pg-format';\nimport type postgres from 'postgres';\nimport {\n type JSONObject,\n type JSONValue,\n stringify,\n} from '../../../../../shared/src/bigint-json.ts';\nimport type {ReadonlyJSONValue} from '../../../../../shared/src/json.ts';\nimport {stringCompare} from '../../../../../shared/src/string-compare.ts';\nimport type {ClientSchema} from '../../../../../zero-protocol/src/client-schema.ts';\nimport {normalizedKeyOrder, type RowKey} from '../../../types/row-key.ts';\nimport {cvrSchema, type ShardID} from '../../../types/shards.ts';\nimport type {TTLClock} from '../ttl-clock.ts';\nimport {\n type RowID,\n type RowRecord,\n versionFromString,\n versionString,\n} from './types.ts';\n\n// For readability in the sql statements.\nfunction schema(shard: ShardID) {\n return ident(cvrSchema(shard));\n}\n\nfunction createSchema(shard: ShardID) {\n return `CREATE SCHEMA IF NOT EXISTS ${schema(shard)};`;\n}\n\nexport type InstancesRow = {\n clientGroupID: string;\n version: string;\n lastActive: number;\n ttlClock: TTLClock;\n replicaVersion: string | null;\n owner: string | null;\n grantedAt: number | null;\n clientSchema: ClientSchema | null;\n profileID: string | null;\n};\n\nfunction createInstancesTable(shard: ShardID) {\n return /*sql*/ `\nCREATE TABLE ${schema(shard)}.instances (\n \"clientGroupID\" TEXT PRIMARY KEY,\n \"version\" TEXT NOT NULL, -- Sortable representation of CVRVersion, e.g. \"5nbqa2w:09\"\n \"lastActive\" TIMESTAMPTZ NOT NULL, -- For garbage collection\n \"ttlClock\" DOUBLE PRECISION NOT NULL DEFAULT 0, -- The ttl clock gets \"paused\" when disconnected.\n \"replicaVersion\" TEXT, -- Identifies the replica (i.e. initial-sync point) from which the CVR data comes.\n \"owner\" TEXT, -- The ID of the task / server that has been granted ownership of the CVR.\n \"grantedAt\" TIMESTAMPTZ, -- The time at which the current owner was last granted ownership (most recent connection time).\n \"clientSchema\" JSONB, -- ClientSchema of the client group\n \"profileID\" TEXT, -- Stable profile id (\"p...\"), falling back to the clientGroupID (\"cg{clientGroupID}\") for old clients\n \"deleted\" BOOL DEFAULT FALSE -- Tombstone column for deleted CVRs; instances rows are kept longer for usage stats\n);\n\n-- For garbage collection.\nCREATE INDEX instances_last_active\n ON ${schema(shard)}.instances (\"lastActive\") WHERE NOT \"deleted\";\nCREATE INDEX tombstones_last_active\n ON ${schema(shard)}.instances (\"lastActive\") WHERE \"deleted\";\n\n-- For usage stats; the composite index allows a \n-- SELECT COUNT(DISTINCT(\"profileID\")) query to be answered by\n-- an index scan without additional table lookups.\nCREATE INDEX profile_ids_last_active ON ${schema(shard)}.instances (\"lastActive\", \"profileID\")\n WHERE \"profileID\" IS NOT NULL;\n`;\n}\n\nexport function compareInstancesRows(a: InstancesRow, b: InstancesRow) {\n return stringCompare(a.clientGroupID, b.clientGroupID);\n}\n\nexport type ClientsRow = {\n clientGroupID: string;\n clientID: string;\n};\n\nfunction createClientsTable(shard: ShardID) {\n return `\nCREATE TABLE ${schema(shard)}.clients (\n \"clientGroupID\" TEXT,\n \"clientID\" TEXT,\n\n PRIMARY KEY (\"clientGroupID\", \"clientID\"),\n\n CONSTRAINT fk_clients_client_group\n FOREIGN KEY(\"clientGroupID\")\n REFERENCES ${schema(shard)}.instances(\"clientGroupID\")\n ON DELETE CASCADE\n);\n\n`;\n}\nexport function compareClientsRows(a: ClientsRow, b: ClientsRow) {\n const clientGroupIDComp = stringCompare(a.clientGroupID, b.clientGroupID);\n if (clientGroupIDComp !== 0) {\n return clientGroupIDComp;\n }\n return stringCompare(a.clientID, b.clientID);\n}\n\nexport type QueriesRow = {\n clientGroupID: string;\n queryHash: string;\n // This is the client AST _AFTER_ applying server name transformations.\n clientAST: JSONValue | null;\n queryName: string | null;\n queryArgs: readonly ReadonlyJSONValue[] | null;\n patchVersion: string | null;\n transformationHash: string | null;\n transformationVersion: string | null;\n internal: boolean | null;\n deleted: boolean | null;\n};\n\nfunction createQueriesTable(shard: ShardID) {\n return `\nCREATE TABLE ${schema(shard)}.queries (\n \"clientGroupID\" TEXT,\n \"queryHash\" TEXT, -- this is the hash of the client query AST\n \"clientAST\" JSONB, -- this is nullable as custom queries will not persist an AST\n \"queryName\" TEXT, -- the name of the query if it is a custom query\n \"queryArgs\" JSON, -- the arguments of the query if it is a custom query\n \"patchVersion\" TEXT, -- NULL if only desired but not yet \"got\"\n \"transformationHash\" TEXT,\n \"transformationVersion\" TEXT,\n \"internal\" BOOL, -- If true, no need to track / send patches\n \"deleted\" BOOL, -- put vs del \"got\" query\n\n PRIMARY KEY (\"clientGroupID\", \"queryHash\"),\n\n CONSTRAINT fk_queries_client_group\n FOREIGN KEY(\"clientGroupID\")\n REFERENCES ${schema(shard)}.instances(\"clientGroupID\")\n ON DELETE CASCADE\n);\n\n-- For catchup patches.\nCREATE INDEX queries_patch_version \n ON ${schema(shard)}.queries (\"patchVersion\" NULLS FIRST);\n`;\n}\n\nexport function compareQueriesRows(a: QueriesRow, b: QueriesRow) {\n const clientGroupIDComp = stringCompare(a.clientGroupID, b.clientGroupID);\n if (clientGroupIDComp !== 0) {\n return clientGroupIDComp;\n }\n return stringCompare(a.queryHash, b.queryHash);\n}\n\nexport type DesiresRow = {\n clientGroupID: string;\n clientID: string;\n queryHash: string;\n patchVersion: string;\n deleted: boolean | null;\n ttl: number | null;\n inactivatedAt: TTLClock | null;\n};\n\nfunction createDesiresTable(shard: ShardID) {\n return `\nCREATE TABLE ${schema(shard)}.desires (\n \"clientGroupID\" TEXT,\n \"clientID\" TEXT,\n \"queryHash\" TEXT,\n \"patchVersion\" TEXT NOT NULL,\n \"deleted\" BOOL, -- put vs del \"desired\" query\n \"ttl\" INTERVAL, -- DEPRECATED: Use ttlMs instead. Time to live for this client\n \"ttlMs\" DOUBLE PRECISION, -- Time to live in milliseconds\n \"inactivatedAt\" TIMESTAMPTZ, -- DEPRECATED: Use inactivatedAtMs instead. Time at which this row was inactivated\n \"inactivatedAtMs\" DOUBLE PRECISION, -- Time at which this row was inactivated (milliseconds since client group start)\n\n PRIMARY KEY (\"clientGroupID\", \"clientID\", \"queryHash\"),\n\n CONSTRAINT fk_desires_query\n FOREIGN KEY(\"clientGroupID\", \"queryHash\")\n REFERENCES ${ident(cvrSchema(shard))}.queries(\"clientGroupID\", \"queryHash\")\n ON DELETE CASCADE\n);\n\n-- For catchup patches.\nCREATE INDEX desires_patch_version\n ON ${schema(shard)}.desires (\"patchVersion\");\n\nCREATE INDEX desires_inactivated_at\n ON ${schema(shard)}.desires (\"inactivatedAt\");\n`;\n}\n\nexport function compareDesiresRows(a: DesiresRow, b: DesiresRow) {\n const clientGroupIDComp = stringCompare(a.clientGroupID, b.clientGroupID);\n if (clientGroupIDComp !== 0) {\n return clientGroupIDComp;\n }\n const clientIDComp = stringCompare(a.clientID, b.clientID);\n if (clientIDComp !== 0) {\n return clientIDComp;\n }\n return stringCompare(a.queryHash, b.queryHash);\n}\n\nexport type RowsRow = {\n clientGroupID: string;\n schema: string;\n table: string;\n rowKey: JSONObject;\n rowVersion: string;\n patchVersion: string;\n refCounts: {[queryHash: string]: number} | null;\n};\n\nexport function rowsRowToRowID(rowsRow: RowsRow): RowID {\n return {\n schema: rowsRow.schema,\n table: rowsRow.table,\n rowKey: rowsRow.rowKey as Record<string, JSONValue>,\n };\n}\n\nexport function rowsRowToRowRecord(rowsRow: RowsRow): RowRecord {\n return {\n id: rowsRowToRowID(rowsRow),\n rowVersion: rowsRow.rowVersion,\n patchVersion: versionFromString(rowsRow.patchVersion),\n refCounts: rowsRow.refCounts,\n };\n}\n\nexport function rowRecordToRowsRow(\n clientGroupID: string,\n rowRecord: RowRecord,\n): RowsRow {\n return {\n clientGroupID,\n schema: rowRecord.id.schema,\n table: rowRecord.id.table,\n rowKey: rowRecord.id.rowKey as Record<string, JSONValue>,\n rowVersion: rowRecord.rowVersion,\n patchVersion: versionString(rowRecord.patchVersion),\n refCounts: rowRecord.refCounts,\n };\n}\n\nexport function compareRowsRows(a: RowsRow, b: RowsRow) {\n const clientGroupIDComp = stringCompare(a.clientGroupID, b.clientGroupID);\n if (clientGroupIDComp !== 0) {\n return clientGroupIDComp;\n }\n const schemaComp = stringCompare(a.schema, b.schema);\n if (schemaComp !== 0) {\n return schemaComp;\n }\n const tableComp = stringCompare(b.table, b.table);\n if (tableComp !== 0) {\n return tableComp;\n }\n return stringCompare(\n stringifySorted(a.rowKey as RowKey),\n stringifySorted(b.rowKey as RowKey),\n );\n}\n\n/**\n * The version of the data in the `cvr.rows` table. This may lag\n * `version` in `cvr.instances` but eventually catches up, modulo\n * exceptional circumstances like a server crash.\n *\n * The `rowsVersion` is tracked in a separate table (as opposed to\n * a column in the `cvr.instances` table) so that general `cvr` updates\n * and `row` updates can be executed independently without serialization\n * conflicts.\n *\n * Note: Although `clientGroupID` logically references the same column in\n * `cvr.instances`, a FOREIGN KEY constraint must not be declared as the\n * `cvr.rows` TABLE needs to be updated without affecting the\n * `SELECT ... FOR UPDATE` lock when `cvr.instances` is updated.\n */\nexport function createRowsVersionTable(shard: ShardID) {\n return `\nCREATE TABLE ${schema(shard)}.\"rowsVersion\" (\n \"clientGroupID\" TEXT PRIMARY KEY,\n \"version\" TEXT NOT NULL\n);\n`;\n}\n\n/**\n * CVR `rows` are updated asynchronously from the CVR metadata\n * (i.e. `instances`). The `rowsVersion` table is updated atomically with\n * updates to the `rows` data.\n */\nfunction createRowsTable(shard: ShardID) {\n return `\nCREATE TABLE ${schema(shard)}.rows (\n \"clientGroupID\" TEXT,\n \"schema\" TEXT,\n \"table\" TEXT,\n \"rowKey\" JSONB,\n \"rowVersion\" TEXT NOT NULL,\n \"patchVersion\" TEXT NOT NULL,\n \"refCounts\" JSONB, -- {[queryHash: string]: number}, NULL for tombstone\n\n PRIMARY KEY (\"clientGroupID\", \"schema\", \"table\", \"rowKey\"),\n\n CONSTRAINT fk_rows_client_group\n FOREIGN KEY(\"clientGroupID\")\n REFERENCES ${schema(shard)}.\"rowsVersion\" (\"clientGroupID\")\n ON DELETE CASCADE\n);\n\n-- For catchup patches.\nCREATE INDEX row_patch_version \n ON ${schema(shard)}.rows (\"patchVersion\");\n\n-- For listing rows returned by one or more query hashes. e.g.\n-- SELECT * FROM cvr_shard.rows WHERE \"refCounts\" ?| array[...queryHashes...];\nCREATE INDEX row_ref_counts ON ${schema(shard)}.rows \n USING GIN (\"refCounts\");\n`;\n}\n\nexport type RowsVersionRow = {\n clientGroupID: string;\n version: string;\n};\n\nfunction createTables(shard: ShardID) {\n return (\n createSchema(shard) +\n createInstancesTable(shard) +\n createClientsTable(shard) +\n createQueriesTable(shard) +\n createDesiresTable(shard) +\n createRowsVersionTable(shard) +\n createRowsTable(shard)\n );\n}\n\nexport async function setupCVRTables(\n lc: LogContext,\n db: postgres.TransactionSql,\n shard: ShardID,\n) {\n lc.info?.(`Setting up CVR tables`);\n await db.unsafe(createTables(shard));\n}\n\nfunction stringifySorted(r: RowKey) {\n return stringify(normalizedKeyOrder(r));\n}\n"],"mappings":";;;;;;AAsBA,SAAS,OAAO,OAAgB;AAC9B,QAAO,MAAM,UAAU,MAAM,CAAC;;AAGhC,SAAS,aAAa,OAAgB;AACpC,QAAO,+BAA+B,OAAO,MAAM,CAAC;;AAetD,SAAS,qBAAqB,OAAgB;AAC5C,QAAe;eACF,OAAO,MAAM,CAAC;;;;;;;;;;;;;;;OAetB,OAAO,MAAM,CAAC;;OAEd,OAAO,MAAM,CAAC;;;;;0CAKqB,OAAO,MAAM,CAAC;;;;AAcxD,SAAS,mBAAmB,OAAgB;AAC1C,QAAO;eACM,OAAO,MAAM,CAAC;;;;;;;;iBAQZ,OAAO,MAAM,CAAC;;;;;;AA4B/B,SAAS,mBAAmB,OAAgB;AAC1C,QAAO;eACM,OAAO,MAAM,CAAC;;;;;;;;;;;;;;;;iBAgBZ,OAAO,MAAM,CAAC;;;;;;OAMxB,OAAO,MAAM,CAAC;;;AAsBrB,SAAS,mBAAmB,OAAgB;AAC1C,QAAO;eACM,OAAO,MAAM,CAAC;;;;;;;;;;;;;;;iBAeZ,MAAM,UAAU,MAAM,CAAC,CAAC;;;;;;OAMlC,OAAO,MAAM,CAAC;;;OAGd,OAAO,MAAM,CAAC;;;AA0BrB,SAAgB,eAAe,SAAyB;AACtD,QAAO;EACL,QAAQ,QAAQ;EAChB,OAAO,QAAQ;EACf,QAAQ,QAAQ;EACjB;;AAGH,SAAgB,mBAAmB,SAA6B;AAC9D,QAAO;EACL,IAAI,eAAe,QAAQ;EAC3B,YAAY,QAAQ;EACpB,cAAc,kBAAkB,QAAQ,aAAa;EACrD,WAAW,QAAQ;EACpB;;AAGH,SAAgB,mBACd,eACA,WACS;AACT,QAAO;EACL;EACA,QAAQ,UAAU,GAAG;EACrB,OAAO,UAAU,GAAG;EACpB,QAAQ,UAAU,GAAG;EACrB,YAAY,UAAU;EACtB,cAAc,cAAc,UAAU,aAAa;EACnD,WAAW,UAAU;EACtB;;;;;;;;;;;;;;;;;AAqCH,SAAgB,uBAAuB,OAAgB;AACrD,QAAO;eACM,OAAO,MAAM,CAAC;;;;;;;;;;;AAY7B,SAAS,gBAAgB,OAAgB;AACvC,QAAO;eACM,OAAO,MAAM,CAAC;;;;;;;;;;;;;iBAaZ,OAAO,MAAM,CAAC;;;;;;OAMxB,OAAO,MAAM,CAAC;;;;iCAIY,OAAO,MAAM,CAAC;;;;AAU/C,SAAS,aAAa,OAAgB;AACpC,QACE,aAAa,MAAM,GACnB,qBAAqB,MAAM,GAC3B,mBAAmB,MAAM,GACzB,mBAAmB,MAAM,GACzB,mBAAmB,MAAM,GACzB,uBAAuB,MAAM,GAC7B,gBAAgB,MAAM;;AAI1B,eAAsB,eACpB,IACA,IACA,OACA;AACA,IAAG,OAAO,wBAAwB;AAClC,OAAM,GAAG,OAAO,aAAa,MAAM,CAAC"}