@rocicorp/zero 1.10.0-canary.0 → 1.10.0-canary.10

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 (484) hide show
  1. package/out/replicache/src/db/commit.js +1 -4
  2. package/out/replicache/src/db/commit.js.map +1 -1
  3. package/out/replicache/src/db/read.d.ts +1 -0
  4. package/out/replicache/src/db/read.d.ts.map +1 -1
  5. package/out/replicache/src/db/read.js +1 -4
  6. package/out/replicache/src/db/read.js.map +1 -1
  7. package/out/replicache/src/db/write.d.ts +2 -1
  8. package/out/replicache/src/db/write.d.ts.map +1 -1
  9. package/out/replicache/src/db/write.js +4 -51
  10. package/out/replicache/src/db/write.js.map +1 -1
  11. package/out/replicache/src/persist/clients.d.ts +1 -0
  12. package/out/replicache/src/persist/clients.d.ts.map +1 -1
  13. package/out/replicache/src/persist/clients.js +4 -31
  14. package/out/replicache/src/persist/clients.js.map +1 -1
  15. package/out/replicache/src/process-env.d.ts +28 -0
  16. package/out/replicache/src/process-env.d.ts.map +1 -0
  17. package/out/replicache/src/replicache-impl.d.ts.map +1 -1
  18. package/out/replicache/src/replicache-impl.js.map +1 -1
  19. package/out/replicache/src/scan-iterator.js +2 -14
  20. package/out/replicache/src/scan-iterator.js.map +1 -1
  21. package/out/replicache/src/subscriptions.d.ts +1 -0
  22. package/out/replicache/src/subscriptions.d.ts.map +1 -1
  23. package/out/replicache/src/subscriptions.js +2 -10
  24. package/out/replicache/src/subscriptions.js.map +1 -1
  25. package/out/replicache/src/transactions.d.ts +1 -0
  26. package/out/replicache/src/transactions.d.ts.map +1 -1
  27. package/out/replicache/src/transactions.js +2 -4
  28. package/out/replicache/src/transactions.js.map +1 -1
  29. package/out/shared/src/promise-race.d.ts +14 -0
  30. package/out/shared/src/promise-race.d.ts.map +1 -1
  31. package/out/shared/src/promise-race.js +32 -1
  32. package/out/shared/src/promise-race.js.map +1 -1
  33. package/out/z2s/src/compiler.d.ts.map +1 -1
  34. package/out/z2s/src/compiler.js +1 -22
  35. package/out/z2s/src/compiler.js.map +1 -1
  36. package/out/zero/package.js +3 -3
  37. package/out/zero/package.js.map +1 -1
  38. package/out/zero-cache/src/auth/write-authorizer.d.ts.map +1 -1
  39. package/out/zero-cache/src/auth/write-authorizer.js +8 -1
  40. package/out/zero-cache/src/auth/write-authorizer.js.map +1 -1
  41. package/out/zero-cache/src/config/normalize.d.ts +6 -0
  42. package/out/zero-cache/src/config/normalize.d.ts.map +1 -1
  43. package/out/zero-cache/src/config/normalize.js +24 -2
  44. package/out/zero-cache/src/config/normalize.js.map +1 -1
  45. package/out/zero-cache/src/config/zero-config.d.ts +65 -4
  46. package/out/zero-cache/src/config/zero-config.d.ts.map +1 -1
  47. package/out/zero-cache/src/config/zero-config.js +202 -35
  48. package/out/zero-cache/src/config/zero-config.js.map +1 -1
  49. package/out/zero-cache/src/custom/fetch.js +1 -1
  50. package/out/zero-cache/src/custom/fetch.js.map +1 -1
  51. package/out/zero-cache/src/db/delete-lite-db.js +2 -1
  52. package/out/zero-cache/src/db/delete-lite-db.js.map +1 -1
  53. package/out/zero-cache/src/db/migration-lite.d.ts.map +1 -1
  54. package/out/zero-cache/src/db/migration-lite.js +10 -5
  55. package/out/zero-cache/src/db/migration-lite.js.map +1 -1
  56. package/out/zero-cache/src/db/migration.d.ts.map +1 -1
  57. package/out/zero-cache/src/db/migration.js +4 -2
  58. package/out/zero-cache/src/db/migration.js.map +1 -1
  59. package/out/zero-cache/src/db/sqlite-corruption.d.ts +3 -2
  60. package/out/zero-cache/src/db/sqlite-corruption.d.ts.map +1 -1
  61. package/out/zero-cache/src/db/sqlite-corruption.js +13 -8
  62. package/out/zero-cache/src/db/sqlite-corruption.js.map +1 -1
  63. package/out/zero-cache/src/db/transaction-pool.d.ts +5 -15
  64. package/out/zero-cache/src/db/transaction-pool.d.ts.map +1 -1
  65. package/out/zero-cache/src/db/transaction-pool.js +8 -72
  66. package/out/zero-cache/src/db/transaction-pool.js.map +1 -1
  67. package/out/zero-cache/src/observability/metrics.d.ts +6 -1
  68. package/out/zero-cache/src/observability/metrics.d.ts.map +1 -1
  69. package/out/zero-cache/src/observability/metrics.js +20 -2
  70. package/out/zero-cache/src/observability/metrics.js.map +1 -1
  71. package/out/zero-cache/src/server/change-streamer.d.ts.map +1 -1
  72. package/out/zero-cache/src/server/change-streamer.js +105 -34
  73. package/out/zero-cache/src/server/change-streamer.js.map +1 -1
  74. package/out/zero-cache/src/server/main.d.ts.map +1 -1
  75. package/out/zero-cache/src/server/main.js +8 -18
  76. package/out/zero-cache/src/server/main.js.map +1 -1
  77. package/out/zero-cache/src/server/replicator.d.ts.map +1 -1
  78. package/out/zero-cache/src/server/replicator.js +48 -5
  79. package/out/zero-cache/src/server/replicator.js.map +1 -1
  80. package/out/zero-cache/src/server/runner/run-worker.js +3 -2
  81. package/out/zero-cache/src/server/runner/run-worker.js.map +1 -1
  82. package/out/zero-cache/src/server/syncer.d.ts.map +1 -1
  83. package/out/zero-cache/src/server/syncer.js +1 -1
  84. package/out/zero-cache/src/server/syncer.js.map +1 -1
  85. package/out/zero-cache/src/server/worker-urls.d.ts +0 -1
  86. package/out/zero-cache/src/server/worker-urls.d.ts.map +1 -1
  87. package/out/zero-cache/src/server/worker-urls.js +1 -2
  88. package/out/zero-cache/src/server/worker-urls.js.map +1 -1
  89. package/out/zero-cache/src/services/change-source/change-source.d.ts +4 -2
  90. package/out/zero-cache/src/services/change-source/change-source.d.ts.map +1 -1
  91. package/out/zero-cache/src/services/change-source/common/replica-restore.d.ts +35 -0
  92. package/out/zero-cache/src/services/change-source/common/replica-restore.d.ts.map +1 -0
  93. package/out/zero-cache/src/services/change-source/common/replica-restore.js +34 -0
  94. package/out/zero-cache/src/services/change-source/common/replica-restore.js.map +1 -0
  95. package/out/zero-cache/src/services/change-source/common/replica-schema.d.ts +2 -0
  96. package/out/zero-cache/src/services/change-source/common/replica-schema.d.ts.map +1 -1
  97. package/out/zero-cache/src/services/change-source/common/replica-schema.js +81 -3
  98. package/out/zero-cache/src/services/change-source/common/replica-schema.js.map +1 -1
  99. package/out/zero-cache/src/services/change-source/custom/change-source.d.ts +2 -6
  100. package/out/zero-cache/src/services/change-source/custom/change-source.d.ts.map +1 -1
  101. package/out/zero-cache/src/services/change-source/custom/change-source.js +14 -5
  102. package/out/zero-cache/src/services/change-source/custom/change-source.js.map +1 -1
  103. package/out/zero-cache/src/services/change-source/pg/backfill-stream.d.ts.map +1 -1
  104. package/out/zero-cache/src/services/change-source/pg/backfill-stream.js +22 -11
  105. package/out/zero-cache/src/services/change-source/pg/backfill-stream.js.map +1 -1
  106. package/out/zero-cache/src/services/change-source/pg/change-source.d.ts +7 -7
  107. package/out/zero-cache/src/services/change-source/pg/change-source.d.ts.map +1 -1
  108. package/out/zero-cache/src/services/change-source/pg/change-source.js +90 -31
  109. package/out/zero-cache/src/services/change-source/pg/change-source.js.map +1 -1
  110. package/out/zero-cache/src/services/change-source/pg/decommission.d.ts.map +1 -1
  111. package/out/zero-cache/src/services/change-source/pg/decommission.js +20 -11
  112. package/out/zero-cache/src/services/change-source/pg/decommission.js.map +1 -1
  113. package/out/zero-cache/src/services/change-source/pg/initial-sync.d.ts +9 -1
  114. package/out/zero-cache/src/services/change-source/pg/initial-sync.d.ts.map +1 -1
  115. package/out/zero-cache/src/services/change-source/pg/initial-sync.js +61 -76
  116. package/out/zero-cache/src/services/change-source/pg/initial-sync.js.map +1 -1
  117. package/out/zero-cache/src/services/change-source/pg/logical-replication/stream.d.ts +65 -2
  118. package/out/zero-cache/src/services/change-source/pg/logical-replication/stream.d.ts.map +1 -1
  119. package/out/zero-cache/src/services/change-source/pg/logical-replication/stream.js +101 -10
  120. package/out/zero-cache/src/services/change-source/pg/logical-replication/stream.js.map +1 -1
  121. package/out/zero-cache/src/services/change-source/pg/replication-slots.d.ts +27 -2
  122. package/out/zero-cache/src/services/change-source/pg/replication-slots.d.ts.map +1 -1
  123. package/out/zero-cache/src/services/change-source/pg/replication-slots.js +41 -8
  124. package/out/zero-cache/src/services/change-source/pg/replication-slots.js.map +1 -1
  125. package/out/zero-cache/src/services/change-source/pg/schema/init.d.ts +0 -5
  126. package/out/zero-cache/src/services/change-source/pg/schema/init.d.ts.map +1 -1
  127. package/out/zero-cache/src/services/change-source/pg/schema/init.js +29 -41
  128. package/out/zero-cache/src/services/change-source/pg/schema/init.js.map +1 -1
  129. package/out/zero-cache/src/services/change-source/pg/schema/shard.d.ts +35 -16
  130. package/out/zero-cache/src/services/change-source/pg/schema/shard.d.ts.map +1 -1
  131. package/out/zero-cache/src/services/change-source/pg/schema/shard.js +77 -7
  132. package/out/zero-cache/src/services/change-source/pg/schema/shard.js.map +1 -1
  133. package/out/zero-cache/src/services/change-source/protocol/current/data.d.ts +2 -1
  134. package/out/zero-cache/src/services/change-source/protocol/current/data.d.ts.map +1 -1
  135. package/out/zero-cache/src/services/change-source/protocol/current/data.js +5 -13
  136. package/out/zero-cache/src/services/change-source/protocol/current/data.js.map +1 -1
  137. package/out/zero-cache/src/services/change-source/protocol/current/downstream.d.ts +6 -3
  138. package/out/zero-cache/src/services/change-source/protocol/current/downstream.d.ts.map +1 -1
  139. package/out/zero-cache/src/services/change-source/protocol/current/schema-change-tags.d.ts +6 -0
  140. package/out/zero-cache/src/services/change-source/protocol/current/schema-change-tags.d.ts.map +1 -0
  141. package/out/zero-cache/src/services/change-source/protocol/current/schema-change-tags.js +21 -0
  142. package/out/zero-cache/src/services/change-source/protocol/current/schema-change-tags.js.map +1 -0
  143. package/out/zero-cache/src/services/change-source/protocol/current/status.d.ts +1 -0
  144. package/out/zero-cache/src/services/change-source/protocol/current/status.d.ts.map +1 -1
  145. package/out/zero-cache/src/services/change-source/protocol/current/upstream.d.ts +1 -0
  146. package/out/zero-cache/src/services/change-source/protocol/current/upstream.d.ts.map +1 -1
  147. package/out/zero-cache/src/services/change-streamer/backup-cleanup-monitor-factory.d.ts +3 -7
  148. package/out/zero-cache/src/services/change-streamer/backup-cleanup-monitor-factory.d.ts.map +1 -1
  149. package/out/zero-cache/src/services/change-streamer/backup-cleanup-monitor-factory.js +26 -10
  150. package/out/zero-cache/src/services/change-streamer/backup-cleanup-monitor-factory.js.map +1 -1
  151. package/out/zero-cache/src/services/change-streamer/backup-monitor.d.ts +15 -5
  152. package/out/zero-cache/src/services/change-streamer/backup-monitor.d.ts.map +1 -1
  153. package/out/zero-cache/src/services/change-streamer/backup-monitor.js +71 -0
  154. package/out/zero-cache/src/services/change-streamer/backup-monitor.js.map +1 -0
  155. package/out/zero-cache/src/services/change-streamer/broadcast.d.ts +68 -78
  156. package/out/zero-cache/src/services/change-streamer/broadcast.d.ts.map +1 -1
  157. package/out/zero-cache/src/services/change-streamer/broadcast.js +84 -92
  158. package/out/zero-cache/src/services/change-streamer/broadcast.js.map +1 -1
  159. package/out/zero-cache/src/services/change-streamer/change-log-codec.d.ts +19 -0
  160. package/out/zero-cache/src/services/change-streamer/change-log-codec.d.ts.map +1 -0
  161. package/out/zero-cache/src/services/change-streamer/change-log-codec.js +50 -0
  162. package/out/zero-cache/src/services/change-streamer/change-log-codec.js.map +1 -0
  163. package/out/zero-cache/src/services/change-streamer/change-log-compare-digest.d.ts +34 -0
  164. package/out/zero-cache/src/services/change-streamer/change-log-compare-digest.d.ts.map +1 -0
  165. package/out/zero-cache/src/services/change-streamer/change-log-compare-digest.js +67 -0
  166. package/out/zero-cache/src/services/change-streamer/change-log-compare-digest.js.map +1 -0
  167. package/out/zero-cache/src/services/change-streamer/change-log-initializer.d.ts +141 -0
  168. package/out/zero-cache/src/services/change-streamer/change-log-initializer.d.ts.map +1 -0
  169. package/out/zero-cache/src/services/change-streamer/change-log-initializer.js +270 -0
  170. package/out/zero-cache/src/services/change-streamer/change-log-initializer.js.map +1 -0
  171. package/out/zero-cache/src/services/change-streamer/change-log-transaction-hash.d.ts +19 -0
  172. package/out/zero-cache/src/services/change-streamer/change-log-transaction-hash.d.ts.map +1 -0
  173. package/out/zero-cache/src/services/change-streamer/change-log-transaction-hash.js +39 -0
  174. package/out/zero-cache/src/services/change-streamer/change-log-transaction-hash.js.map +1 -0
  175. package/out/zero-cache/src/services/change-streamer/change-streamer-http.d.ts +5 -8
  176. package/out/zero-cache/src/services/change-streamer/change-streamer-http.d.ts.map +1 -1
  177. package/out/zero-cache/src/services/change-streamer/change-streamer-http.js +20 -19
  178. package/out/zero-cache/src/services/change-streamer/change-streamer-http.js.map +1 -1
  179. package/out/zero-cache/src/services/change-streamer/change-streamer-service.d.ts +90 -24
  180. package/out/zero-cache/src/services/change-streamer/change-streamer-service.d.ts.map +1 -1
  181. package/out/zero-cache/src/services/change-streamer/change-streamer-service.js +456 -66
  182. package/out/zero-cache/src/services/change-streamer/change-streamer-service.js.map +1 -1
  183. package/out/zero-cache/src/services/change-streamer/change-streamer.d.ts +50 -13
  184. package/out/zero-cache/src/services/change-streamer/change-streamer.d.ts.map +1 -1
  185. package/out/zero-cache/src/services/change-streamer/change-streamer.js.map +1 -1
  186. package/out/zero-cache/src/services/change-streamer/error-type-enum.d.ts +8 -0
  187. package/out/zero-cache/src/services/change-streamer/error-type-enum.d.ts.map +1 -1
  188. package/out/zero-cache/src/services/change-streamer/forwarder.d.ts +14 -3
  189. package/out/zero-cache/src/services/change-streamer/forwarder.d.ts.map +1 -1
  190. package/out/zero-cache/src/services/change-streamer/forwarder.js +42 -12
  191. package/out/zero-cache/src/services/change-streamer/forwarder.js.map +1 -1
  192. package/out/zero-cache/src/services/change-streamer/{litestream3-backup-monitor.d.ts → litestream3-prometheus-poller.d.ts} +19 -45
  193. package/out/zero-cache/src/services/change-streamer/litestream3-prometheus-poller.d.ts.map +1 -0
  194. package/out/zero-cache/src/services/change-streamer/{litestream3-backup-monitor.js → litestream3-prometheus-poller.js} +68 -176
  195. package/out/zero-cache/src/services/change-streamer/litestream3-prometheus-poller.js.map +1 -0
  196. package/out/zero-cache/src/services/change-streamer/replica-poller.d.ts +15 -0
  197. package/out/zero-cache/src/services/change-streamer/replica-poller.d.ts.map +1 -0
  198. package/out/zero-cache/src/services/change-streamer/replica-poller.js +55 -0
  199. package/out/zero-cache/src/services/change-streamer/replica-poller.js.map +1 -0
  200. package/out/zero-cache/src/services/change-streamer/schema/tables.d.ts +5 -1
  201. package/out/zero-cache/src/services/change-streamer/schema/tables.d.ts.map +1 -1
  202. package/out/zero-cache/src/services/change-streamer/schema/tables.js +2 -1
  203. package/out/zero-cache/src/services/change-streamer/schema/tables.js.map +1 -1
  204. package/out/zero-cache/src/services/change-streamer/shard-sampling.d.ts +11 -0
  205. package/out/zero-cache/src/services/change-streamer/shard-sampling.d.ts.map +1 -0
  206. package/out/zero-cache/src/services/change-streamer/shard-sampling.js +19 -0
  207. package/out/zero-cache/src/services/change-streamer/shard-sampling.js.map +1 -0
  208. package/out/zero-cache/src/services/change-streamer/snapshot-reservations.d.ts +24 -0
  209. package/out/zero-cache/src/services/change-streamer/snapshot-reservations.d.ts.map +1 -0
  210. package/out/zero-cache/src/services/change-streamer/snapshot-reservations.js +119 -0
  211. package/out/zero-cache/src/services/change-streamer/snapshot-reservations.js.map +1 -0
  212. package/out/zero-cache/src/services/change-streamer/snapshot.d.ts +4 -1
  213. package/out/zero-cache/src/services/change-streamer/snapshot.d.ts.map +1 -1
  214. package/out/zero-cache/src/services/change-streamer/snapshot.js +39 -14
  215. package/out/zero-cache/src/services/change-streamer/snapshot.js.map +1 -1
  216. package/out/zero-cache/src/services/change-streamer/sqlite-change-log-catchup.d.ts +99 -0
  217. package/out/zero-cache/src/services/change-streamer/sqlite-change-log-catchup.d.ts.map +1 -0
  218. package/out/zero-cache/src/services/change-streamer/sqlite-change-log-catchup.js +344 -0
  219. package/out/zero-cache/src/services/change-streamer/sqlite-change-log-catchup.js.map +1 -0
  220. package/out/zero-cache/src/services/change-streamer/sqlite-change-log-comparator.d.ts +83 -0
  221. package/out/zero-cache/src/services/change-streamer/sqlite-change-log-comparator.d.ts.map +1 -0
  222. package/out/zero-cache/src/services/change-streamer/sqlite-change-log-comparator.js +417 -0
  223. package/out/zero-cache/src/services/change-streamer/sqlite-change-log-comparator.js.map +1 -0
  224. package/out/zero-cache/src/services/change-streamer/sqlite-change-log-purge-scheduler.d.ts +121 -0
  225. package/out/zero-cache/src/services/change-streamer/sqlite-change-log-purge-scheduler.d.ts.map +1 -0
  226. package/out/zero-cache/src/services/change-streamer/sqlite-change-log-purge-scheduler.js +391 -0
  227. package/out/zero-cache/src/services/change-streamer/sqlite-change-log-purge-scheduler.js.map +1 -0
  228. package/out/zero-cache/src/services/change-streamer/sqlite-change-log-read-router.d.ts +73 -0
  229. package/out/zero-cache/src/services/change-streamer/sqlite-change-log-read-router.d.ts.map +1 -0
  230. package/out/zero-cache/src/services/change-streamer/sqlite-change-log-read-router.js +157 -0
  231. package/out/zero-cache/src/services/change-streamer/sqlite-change-log-read-router.js.map +1 -0
  232. package/out/zero-cache/src/services/change-streamer/sqlite-change-log-reader.d.ts +62 -0
  233. package/out/zero-cache/src/services/change-streamer/sqlite-change-log-reader.d.ts.map +1 -0
  234. package/out/zero-cache/src/services/change-streamer/sqlite-change-log-reader.js +164 -0
  235. package/out/zero-cache/src/services/change-streamer/sqlite-change-log-reader.js.map +1 -0
  236. package/out/zero-cache/src/services/change-streamer/sqlite-change-log-writer.d.ts +109 -0
  237. package/out/zero-cache/src/services/change-streamer/sqlite-change-log-writer.d.ts.map +1 -0
  238. package/out/zero-cache/src/services/change-streamer/sqlite-change-log-writer.js +258 -0
  239. package/out/zero-cache/src/services/change-streamer/sqlite-change-log-writer.js.map +1 -0
  240. package/out/zero-cache/src/services/change-streamer/storer.d.ts +85 -12
  241. package/out/zero-cache/src/services/change-streamer/storer.d.ts.map +1 -1
  242. package/out/zero-cache/src/services/change-streamer/storer.js +286 -141
  243. package/out/zero-cache/src/services/change-streamer/storer.js.map +1 -1
  244. package/out/zero-cache/src/services/change-streamer/subscriber.d.ts +61 -10
  245. package/out/zero-cache/src/services/change-streamer/subscriber.d.ts.map +1 -1
  246. package/out/zero-cache/src/services/change-streamer/subscriber.js +101 -8
  247. package/out/zero-cache/src/services/change-streamer/subscriber.js.map +1 -1
  248. package/out/zero-cache/src/services/change-streamer/upstream-acker.d.ts +34 -0
  249. package/out/zero-cache/src/services/change-streamer/upstream-acker.d.ts.map +1 -0
  250. package/out/zero-cache/src/services/change-streamer/upstream-acker.js +86 -0
  251. package/out/zero-cache/src/services/change-streamer/upstream-acker.js.map +1 -0
  252. package/out/zero-cache/src/services/change-streamer/vfs-watermark-poller.d.ts +29 -0
  253. package/out/zero-cache/src/services/change-streamer/vfs-watermark-poller.d.ts.map +1 -0
  254. package/out/zero-cache/src/services/change-streamer/vfs-watermark-poller.js +154 -0
  255. package/out/zero-cache/src/services/change-streamer/vfs-watermark-poller.js.map +1 -0
  256. package/out/zero-cache/src/services/http-service.d.ts +1 -0
  257. package/out/zero-cache/src/services/http-service.d.ts.map +1 -1
  258. package/out/zero-cache/src/services/http-service.js +7 -3
  259. package/out/zero-cache/src/services/http-service.js.map +1 -1
  260. package/out/zero-cache/src/services/life-cycle.d.ts +1 -1
  261. package/out/zero-cache/src/services/life-cycle.d.ts.map +1 -1
  262. package/out/zero-cache/src/services/life-cycle.js +4 -3
  263. package/out/zero-cache/src/services/life-cycle.js.map +1 -1
  264. package/out/zero-cache/src/services/litestream/commands.d.ts +12 -11
  265. package/out/zero-cache/src/services/litestream/commands.d.ts.map +1 -1
  266. package/out/zero-cache/src/services/litestream/commands.js +115 -152
  267. package/out/zero-cache/src/services/litestream/commands.js.map +1 -1
  268. package/out/zero-cache/src/services/litestream/config-v5.yml +42 -0
  269. package/out/zero-cache/src/services/litestream/config.yml +3 -2
  270. package/out/zero-cache/src/services/litestream/metrics.d.ts +5 -4
  271. package/out/zero-cache/src/services/litestream/metrics.d.ts.map +1 -1
  272. package/out/zero-cache/src/services/litestream/metrics.js +10 -10
  273. package/out/zero-cache/src/services/litestream/metrics.js.map +1 -1
  274. package/out/zero-cache/src/services/mutagen/mutagen.d.ts.map +1 -1
  275. package/out/zero-cache/src/services/mutagen/mutagen.js +5 -2
  276. package/out/zero-cache/src/services/mutagen/mutagen.js.map +1 -1
  277. package/out/zero-cache/src/services/replicator/change-log-cookies.d.ts +169 -0
  278. package/out/zero-cache/src/services/replicator/change-log-cookies.d.ts.map +1 -0
  279. package/out/zero-cache/src/services/replicator/change-log-cookies.js +434 -0
  280. package/out/zero-cache/src/services/replicator/change-log-cookies.js.map +1 -0
  281. package/out/zero-cache/src/services/replicator/change-log-db.d.ts +368 -0
  282. package/out/zero-cache/src/services/replicator/change-log-db.d.ts.map +1 -0
  283. package/out/zero-cache/src/services/replicator/change-log-db.js +491 -0
  284. package/out/zero-cache/src/services/replicator/change-log-db.js.map +1 -0
  285. package/out/zero-cache/src/services/replicator/change-log-stream-writer.d.ts +55 -0
  286. package/out/zero-cache/src/services/replicator/change-log-stream-writer.d.ts.map +1 -0
  287. package/out/zero-cache/src/services/replicator/change-log-stream-writer.js +150 -0
  288. package/out/zero-cache/src/services/replicator/change-log-stream-writer.js.map +1 -0
  289. package/out/zero-cache/src/services/replicator/change-processor.d.ts +6 -0
  290. package/out/zero-cache/src/services/replicator/change-processor.d.ts.map +1 -1
  291. package/out/zero-cache/src/services/replicator/change-processor.js +70 -25
  292. package/out/zero-cache/src/services/replicator/change-processor.js.map +1 -1
  293. package/out/zero-cache/src/services/replicator/incremental-sync.d.ts +1 -1
  294. package/out/zero-cache/src/services/replicator/incremental-sync.d.ts.map +1 -1
  295. package/out/zero-cache/src/services/replicator/incremental-sync.js +19 -6
  296. package/out/zero-cache/src/services/replicator/incremental-sync.js.map +1 -1
  297. package/out/zero-cache/src/services/replicator/notifier.d.ts +0 -22
  298. package/out/zero-cache/src/services/replicator/notifier.d.ts.map +1 -1
  299. package/out/zero-cache/src/services/replicator/notifier.js +7 -1
  300. package/out/zero-cache/src/services/replicator/notifier.js.map +1 -1
  301. package/out/zero-cache/src/services/replicator/replicator.d.ts +17 -2
  302. package/out/zero-cache/src/services/replicator/replicator.d.ts.map +1 -1
  303. package/out/zero-cache/src/services/replicator/replicator.js +9 -3
  304. package/out/zero-cache/src/services/replicator/replicator.js.map +1 -1
  305. package/out/zero-cache/src/services/replicator/reporter/recorder.d.ts +27 -0
  306. package/out/zero-cache/src/services/replicator/reporter/recorder.d.ts.map +1 -1
  307. package/out/zero-cache/src/services/replicator/reporter/recorder.js +32 -0
  308. package/out/zero-cache/src/services/replicator/reporter/recorder.js.map +1 -1
  309. package/out/zero-cache/src/services/replicator/reporter/report-schema.d.ts +1 -1
  310. package/out/zero-cache/src/services/replicator/schema/backfilling.d.ts +119 -0
  311. package/out/zero-cache/src/services/replicator/schema/backfilling.d.ts.map +1 -0
  312. package/out/zero-cache/src/services/replicator/schema/backfilling.js +214 -0
  313. package/out/zero-cache/src/services/replicator/schema/backfilling.js.map +1 -0
  314. package/out/zero-cache/src/services/replicator/schema/change-log.d.ts +3 -3
  315. package/out/zero-cache/src/services/replicator/schema/column-metadata.js +1 -1
  316. package/out/zero-cache/src/services/replicator/schema/column-metadata.js.map +1 -1
  317. package/out/zero-cache/src/services/replicator/schema/replication-state.d.ts +1 -1
  318. package/out/zero-cache/src/services/replicator/schema/replication-state.d.ts.map +1 -1
  319. package/out/zero-cache/src/services/replicator/schema/replication-state.js +9 -5
  320. package/out/zero-cache/src/services/replicator/schema/replication-state.js.map +1 -1
  321. package/out/zero-cache/src/services/replicator/sqlite-change-log-observability.d.ts +132 -0
  322. package/out/zero-cache/src/services/replicator/sqlite-change-log-observability.d.ts.map +1 -0
  323. package/out/zero-cache/src/services/replicator/sqlite-change-log-observability.js +415 -0
  324. package/out/zero-cache/src/services/replicator/sqlite-change-log-observability.js.map +1 -0
  325. package/out/zero-cache/src/services/replicator/sqlite-change-log-purger.d.ts +120 -0
  326. package/out/zero-cache/src/services/replicator/sqlite-change-log-purger.d.ts.map +1 -0
  327. package/out/zero-cache/src/services/replicator/sqlite-change-log-purger.js +283 -0
  328. package/out/zero-cache/src/services/replicator/sqlite-change-log-purger.js.map +1 -0
  329. package/out/zero-cache/src/services/replicator/write-worker.js +23 -12
  330. package/out/zero-cache/src/services/replicator/write-worker.js.map +1 -1
  331. package/out/zero-cache/src/services/run-ast.d.ts.map +1 -1
  332. package/out/zero-cache/src/services/run-ast.js +2 -1
  333. package/out/zero-cache/src/services/run-ast.js.map +1 -1
  334. package/out/zero-cache/src/services/running-state.d.ts +1 -1
  335. package/out/zero-cache/src/services/running-state.d.ts.map +1 -1
  336. package/out/zero-cache/src/services/running-state.js +1 -0
  337. package/out/zero-cache/src/services/running-state.js.map +1 -1
  338. package/out/zero-cache/src/services/view-syncer/client-handler.d.ts +3 -2
  339. package/out/zero-cache/src/services/view-syncer/client-handler.d.ts.map +1 -1
  340. package/out/zero-cache/src/services/view-syncer/client-handler.js +25 -17
  341. package/out/zero-cache/src/services/view-syncer/client-handler.js.map +1 -1
  342. package/out/zero-cache/src/services/view-syncer/cvr-store.d.ts.map +1 -1
  343. package/out/zero-cache/src/services/view-syncer/cvr-store.js +14 -1
  344. package/out/zero-cache/src/services/view-syncer/cvr-store.js.map +1 -1
  345. package/out/zero-cache/src/services/view-syncer/e2e-serving-lag.d.ts +53 -0
  346. package/out/zero-cache/src/services/view-syncer/e2e-serving-lag.d.ts.map +1 -0
  347. package/out/zero-cache/src/services/view-syncer/e2e-serving-lag.js +68 -0
  348. package/out/zero-cache/src/services/view-syncer/e2e-serving-lag.js.map +1 -0
  349. package/out/zero-cache/src/services/view-syncer/pipeline-driver.d.ts.map +1 -1
  350. package/out/zero-cache/src/services/view-syncer/pipeline-driver.js +18 -3
  351. package/out/zero-cache/src/services/view-syncer/pipeline-driver.js.map +1 -1
  352. package/out/zero-cache/src/services/view-syncer/snapshotter.d.ts.map +1 -1
  353. package/out/zero-cache/src/services/view-syncer/snapshotter.js.map +1 -1
  354. package/out/zero-cache/src/services/view-syncer/view-syncer.d.ts +14 -4
  355. package/out/zero-cache/src/services/view-syncer/view-syncer.d.ts.map +1 -1
  356. package/out/zero-cache/src/services/view-syncer/view-syncer.js +70 -8
  357. package/out/zero-cache/src/services/view-syncer/view-syncer.js.map +1 -1
  358. package/out/zero-cache/src/types/downstream.d.ts +11 -0
  359. package/out/zero-cache/src/types/downstream.d.ts.map +1 -0
  360. package/out/zero-cache/src/types/pg.d.ts.map +1 -1
  361. package/out/zero-cache/src/types/pg.js +14 -4
  362. package/out/zero-cache/src/types/pg.js.map +1 -1
  363. package/out/zero-cache/src/types/poke-chunk.d.ts +18 -0
  364. package/out/zero-cache/src/types/poke-chunk.d.ts.map +1 -0
  365. package/out/zero-cache/src/types/poke-chunk.js +57 -0
  366. package/out/zero-cache/src/types/poke-chunk.js.map +1 -0
  367. package/out/zero-cache/src/types/processes.d.ts +1 -2
  368. package/out/zero-cache/src/types/processes.d.ts.map +1 -1
  369. package/out/zero-cache/src/types/processes.js +1 -28
  370. package/out/zero-cache/src/types/processes.js.map +1 -1
  371. package/out/zero-cache/src/types/streams.d.ts +16 -0
  372. package/out/zero-cache/src/types/streams.d.ts.map +1 -1
  373. package/out/zero-cache/src/types/streams.js +25 -4
  374. package/out/zero-cache/src/types/streams.js.map +1 -1
  375. package/out/zero-cache/src/types/subscription.d.ts +2 -0
  376. package/out/zero-cache/src/types/subscription.d.ts.map +1 -1
  377. package/out/zero-cache/src/types/subscription.js +6 -0
  378. package/out/zero-cache/src/types/subscription.js.map +1 -1
  379. package/out/zero-cache/src/workers/connection.d.ts +23 -4
  380. package/out/zero-cache/src/workers/connection.d.ts.map +1 -1
  381. package/out/zero-cache/src/workers/connection.js +130 -10
  382. package/out/zero-cache/src/workers/connection.js.map +1 -1
  383. package/out/zero-cache/src/workers/replicator.d.ts +25 -0
  384. package/out/zero-cache/src/workers/replicator.d.ts.map +1 -1
  385. package/out/zero-cache/src/workers/replicator.js +33 -1
  386. package/out/zero-cache/src/workers/replicator.js.map +1 -1
  387. package/out/zero-cache/src/workers/syncer.d.ts +12 -0
  388. package/out/zero-cache/src/workers/syncer.d.ts.map +1 -1
  389. package/out/zero-cache/src/workers/syncer.js +75 -0
  390. package/out/zero-cache/src/workers/syncer.js.map +1 -1
  391. package/out/zero-client/src/client/version.js +1 -1
  392. package/out/zero-client/src/client/zero-poke-handler.d.ts +7 -2
  393. package/out/zero-client/src/client/zero-poke-handler.d.ts.map +1 -1
  394. package/out/zero-client/src/client/zero-poke-handler.js +52 -2
  395. package/out/zero-client/src/client/zero-poke-handler.js.map +1 -1
  396. package/out/zero-client/src/client/zero.d.ts +6 -7
  397. package/out/zero-client/src/client/zero.d.ts.map +1 -1
  398. package/out/zero-client/src/client/zero.js +194 -107
  399. package/out/zero-client/src/client/zero.js.map +1 -1
  400. package/out/zero-protocol/src/down.d.ts +1 -1
  401. package/out/zero-protocol/src/poke.d.ts +89 -7
  402. package/out/zero-protocol/src/poke.d.ts.map +1 -1
  403. package/out/zero-protocol/src/poke.js +16 -8
  404. package/out/zero-protocol/src/poke.js.map +1 -1
  405. package/out/zero-protocol/src/protocol-version.d.ts +12 -7
  406. package/out/zero-protocol/src/protocol-version.d.ts.map +1 -1
  407. package/out/zero-protocol/src/protocol-version.js.map +1 -1
  408. package/out/zero-schema/src/builder/table-builder.d.ts +23 -0
  409. package/out/zero-schema/src/builder/table-builder.d.ts.map +1 -1
  410. package/out/zero-schema/src/builder/table-builder.js +18 -0
  411. package/out/zero-schema/src/builder/table-builder.js.map +1 -1
  412. package/out/zero-server/src/custom.js +10 -3
  413. package/out/zero-server/src/custom.js.map +1 -1
  414. package/out/zero-server/src/schema.d.ts +8 -0
  415. package/out/zero-server/src/schema.d.ts.map +1 -1
  416. package/out/zero-server/src/schema.js +63 -24
  417. package/out/zero-server/src/schema.js.map +1 -1
  418. package/out/zero-types/src/schema.d.ts +11 -0
  419. package/out/zero-types/src/schema.d.ts.map +1 -1
  420. package/out/zql/src/ivm/memory-source.d.ts +10 -2
  421. package/out/zql/src/ivm/memory-source.d.ts.map +1 -1
  422. package/out/zql/src/ivm/memory-source.js +14 -6
  423. package/out/zql/src/ivm/memory-source.js.map +1 -1
  424. package/out/zql/src/ivm/stream.d.ts +0 -1
  425. package/out/zql/src/ivm/stream.d.ts.map +1 -1
  426. package/out/zql/src/ivm/stream.js +1 -7
  427. package/out/zql/src/ivm/stream.js.map +1 -1
  428. package/out/zql/src/ivm/union-fan-in.d.ts +1 -1
  429. package/out/zql/src/ivm/union-fan-in.d.ts.map +1 -1
  430. package/out/zql/src/ivm/union-fan-in.js +11 -2
  431. package/out/zql/src/ivm/union-fan-in.js.map +1 -1
  432. package/out/zql/src/mutate/crud.d.ts +10 -8
  433. package/out/zql/src/mutate/crud.d.ts.map +1 -1
  434. package/out/zql/src/mutate/crud.js.map +1 -1
  435. package/out/zql/src/query/query-delegate-base.d.ts.map +1 -1
  436. package/out/zql/src/query/query-delegate-base.js +5 -1
  437. package/out/zql/src/query/query-delegate-base.js.map +1 -1
  438. package/out/zql/src/query/query-impl.d.ts +2 -2
  439. package/out/zql/src/query/query-impl.d.ts.map +1 -1
  440. package/out/zql/src/query/query-impl.js.map +1 -1
  441. package/out/zql/src/query/query.d.ts +83 -14
  442. package/out/zql/src/query/query.d.ts.map +1 -1
  443. package/out/zql/src/query/static-query.d.ts +1 -1
  444. package/out/zql/src/query/static-query.d.ts.map +1 -1
  445. package/out/zqlite/src/db.js +2 -2
  446. package/out/zqlite/src/resolve-scalar-subqueries.d.ts +15 -0
  447. package/out/zqlite/src/resolve-scalar-subqueries.d.ts.map +1 -1
  448. package/out/zqlite/src/resolve-scalar-subqueries.js +33 -14
  449. package/out/zqlite/src/resolve-scalar-subqueries.js.map +1 -1
  450. package/out/zqlite/src/sqlite-cost-model.js +5 -5
  451. package/out/zqlite/src/table-source.d.ts.map +1 -1
  452. package/out/zqlite/src/table-source.js +4 -4
  453. package/out/zqlite/src/table-source.js.map +1 -1
  454. package/package.json +3 -3
  455. package/out/replicache/src/db/index.js +0 -91
  456. package/out/replicache/src/db/index.js.map +0 -1
  457. package/out/replicache/src/lazy.d.ts +0 -2
  458. package/out/replicache/src/lazy.d.ts.map +0 -1
  459. package/out/replicache/src/lazy.js +0 -12
  460. package/out/replicache/src/lazy.js.map +0 -1
  461. package/out/zero-cache/src/server/backup-watermark-reader.js +0 -35
  462. package/out/zero-cache/src/server/backup-watermark-reader.js.map +0 -1
  463. package/out/zero-cache/src/services/change-streamer/litestream3-backup-monitor.d.ts.map +0 -1
  464. package/out/zero-cache/src/services/change-streamer/litestream3-backup-monitor.js.map +0 -1
  465. package/out/zero-cache/src/services/change-streamer/replica-monitor.d.ts +0 -16
  466. package/out/zero-cache/src/services/change-streamer/replica-monitor.d.ts.map +0 -1
  467. package/out/zero-cache/src/services/change-streamer/replica-monitor.js +0 -54
  468. package/out/zero-cache/src/services/change-streamer/replica-monitor.js.map +0 -1
  469. package/out/zero-cache/src/services/change-streamer/vfs-backup-monitor.d.ts +0 -25
  470. package/out/zero-cache/src/services/change-streamer/vfs-backup-monitor.d.ts.map +0 -1
  471. package/out/zero-cache/src/services/change-streamer/vfs-backup-monitor.js +0 -159
  472. package/out/zero-cache/src/services/change-streamer/vfs-backup-monitor.js.map +0 -1
  473. package/out/zero-cache/src/services/litestream/vfs-watermark-reader.d.ts +0 -44
  474. package/out/zero-cache/src/services/litestream/vfs-watermark-reader.d.ts.map +0 -1
  475. package/out/zero-cache/src/services/litestream/vfs-watermark-reader.js +0 -65
  476. package/out/zero-cache/src/services/litestream/vfs-watermark-reader.js.map +0 -1
  477. package/out/zero-cache/src/services/litestream/vfs-watermark-worker-source.d.ts +0 -11
  478. package/out/zero-cache/src/services/litestream/vfs-watermark-worker-source.d.ts.map +0 -1
  479. package/out/zero-cache/src/services/litestream/vfs-watermark-worker-source.js +0 -74
  480. package/out/zero-cache/src/services/litestream/vfs-watermark-worker-source.js.map +0 -1
  481. package/out/zero-cache/src/services/litestream/vfs-watermark-worker.d.ts +0 -42
  482. package/out/zero-cache/src/services/litestream/vfs-watermark-worker.d.ts.map +0 -1
  483. package/out/zero-cache/src/services/litestream/vfs-watermark-worker.js +0 -117
  484. package/out/zero-cache/src/services/litestream/vfs-watermark-worker.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"subscriptions.js","names":["#body","#onData","#isEqual","#scans","#keys","#lastValue","#callback","#prefix","#indexName","#initialValuesInFirstDiff","#subscriptions","#pendingSubscriptions","#queryInternal","#lc","#signal","#scheduleInitialSubscriptionRun","#fireSubscriptions"],"sources":["../../../../replicache/src/subscriptions.ts"],"sourcesContent":["import type {LogContext} from '@rocicorp/logger';\nimport {compareUTF8, greaterThan, lessThan, lessThanEq} from 'compare-utf8';\nimport {assert} from '../../shared/src/asserts.ts';\nimport {binarySearch} from '../../shared/src/binary-search.ts';\nimport type {Enum} from '../../shared/src/enum.ts';\nimport {deepEqual} from '../../shared/src/json.ts';\nimport type {\n Diff,\n DiffOperation,\n IndexDiff,\n InternalDiff,\n InternalDiffOperation,\n NoIndexDiff,\n} from './btree/node.ts';\nimport type {IndexKey} from './db/index.ts';\nimport {decodeIndexKey} from './db/index.ts';\nimport type {ScanOptions} from './db/scan.ts';\nimport * as InvokeKind from './invoke-kind-enum.ts';\nimport type {DiffComputationConfig, DiffsMap} from './sync/diff.ts';\nimport {\n type ReadTransaction,\n SubscriptionTransactionWrapper,\n} from './transactions.ts';\nimport type {QueryInternal} from './types.ts';\n\ntype InvokeKind = Enum<typeof InvokeKind>;\n\nexport interface Subscription<R> {\n hasIndexSubscription(indexName: string): boolean;\n\n invoke(\n tx: ReadTransaction,\n kind: InvokeKind,\n diffs: DiffsMap | undefined,\n ): Promise<R>;\n\n matches(diffs: DiffsMap): boolean;\n\n updateDeps(\n keys: ReadonlySet<string>,\n scans: ReadonlyArray<Readonly<ScanSubscriptionInfo>>,\n ): void;\n\n readonly onData: (result: R) => void;\n readonly onError: ((error: unknown) => void) | undefined;\n readonly onDone: (() => void) | undefined;\n}\n\nconst emptySet: ReadonlySet<string> = new Set();\n\nconst unitializedLastValue = Symbol();\ntype UnitializedLastValue = typeof unitializedLastValue;\n\nexport class SubscriptionImpl<R> implements Subscription<R> {\n readonly #body: (tx: ReadTransaction) => Promise<R>;\n readonly #onData: (result: R) => void;\n #lastValue: R | UnitializedLastValue = unitializedLastValue;\n #keys = emptySet;\n #scans: readonly Readonly<ScanSubscriptionInfo>[] = [];\n\n readonly onError: ((error: unknown) => void) | undefined;\n readonly onDone: (() => void) | undefined;\n readonly #isEqual: (a: R, b: R) => boolean;\n\n constructor(\n body: (tx: ReadTransaction) => Promise<R>,\n onData: (result: R) => void,\n onError: ((error: unknown) => void) | undefined,\n onDone: (() => void) | undefined,\n // deepEqual operates on any JSON value but argument might be more specific.\n isEqual: (a: R, b: R) => boolean = deepEqual as (a: R, b: R) => boolean,\n ) {\n this.#body = body;\n this.#onData = onData;\n this.onError = onError;\n this.onDone = onDone;\n this.#isEqual = isEqual;\n }\n\n hasIndexSubscription(indexName: string): boolean {\n for (const scan of this.#scans) {\n if (scan.options.indexName === indexName) {\n return true;\n }\n }\n return false;\n }\n\n invoke(\n tx: ReadTransaction,\n _kind: InvokeKind,\n _diffs: DiffsMap | undefined,\n ): Promise<R> {\n return this.#body(tx);\n }\n\n matches(diffs: DiffsMap): boolean {\n for (const [indexName, diff] of diffs) {\n if (diffMatchesSubscription(this.#keys, this.#scans, indexName, diff)) {\n return true;\n }\n }\n\n return false;\n }\n\n updateDeps(\n keys: ReadonlySet<string>,\n scans: readonly Readonly<ScanSubscriptionInfo>[],\n ): void {\n this.#keys = keys;\n this.#scans = scans;\n }\n\n onData(result: R): void {\n if (\n this.#lastValue === unitializedLastValue ||\n !this.#isEqual(this.#lastValue, result)\n ) {\n this.#lastValue = result;\n this.#onData(result);\n }\n }\n}\n\nexport {SubscriptionImpl as SubscriptionImplForTesting};\n\n/**\n * Function that gets passed into {@link Replicache.experimentalWatch} and gets\n * called when the data in Replicache changes.\n *\n * @experimental This type is experimental and may change in the future.\n */\nexport type WatchNoIndexCallback = (diff: NoIndexDiff) => void;\n\nexport type WatchCallbackForOptions<Options extends WatchOptions> =\n Options extends WatchIndexOptions ? WatchIndexCallback : WatchNoIndexCallback;\n\n/**\n * Function that gets passed into {@link Replicache.experimentalWatch} when doing a\n * watch on a secondary index map and gets called when the data in Replicache\n * changes.\n *\n * @experimental This type is experimental and may change in the future.\n */\nexport type WatchIndexCallback = (diff: IndexDiff) => void;\n\n/**\n * Options for {@link Replicache.experimentalWatch}.\n *\n * @experimental This interface is experimental and may change in the future.\n */\nexport type WatchOptions = WatchIndexOptions | WatchNoIndexOptions;\n\n/**\n * Options object passed to {@link Replicache.experimentalWatch}. This is for an\n * index watch.\n */\nexport type WatchIndexOptions = WatchNoIndexOptions & {\n /**\n * When provided, the `watch` is limited to the changes that apply to the index map.\n */\n indexName: string;\n};\n\n/**\n * Options object passed to {@link Replicache.experimentalWatch}. This is for a non\n * index watch.\n */\nexport type WatchNoIndexOptions = {\n /**\n * When provided, the `watch` is limited to changes where the `key` starts\n * with `prefix`.\n */\n prefix?: string | undefined;\n\n /**\n * When this is set to `true` (default is `false`), the `watch` callback will\n * be called once asynchronously when watch is called. The arguments in that\n * case is a diff where we consider all the existing values in Replicache as\n * being added.\n */\n initialValuesInFirstDiff?: boolean | undefined;\n};\n\nexport type WatchCallback = (diff: Diff) => void;\n\nexport class WatchSubscription implements Subscription<Diff | undefined> {\n readonly #callback: WatchCallback;\n readonly #prefix: string;\n readonly #indexName: string | undefined;\n readonly #initialValuesInFirstDiff: boolean;\n\n readonly onError: ((error: unknown) => void) | undefined = undefined;\n readonly onDone: (() => void) | undefined = undefined;\n\n constructor(callback: WatchCallback, options?: WatchOptions) {\n this.#callback = callback;\n this.#prefix = options?.prefix ?? '';\n this.#indexName = (options as WatchIndexOptions)?.indexName;\n this.#initialValuesInFirstDiff = options?.initialValuesInFirstDiff ?? false;\n }\n\n hasIndexSubscription(indexName: string): boolean {\n return this.#indexName === indexName;\n }\n\n onData(result: Diff | undefined): void {\n if (result !== undefined) {\n this.#callback(result);\n }\n }\n\n invoke(\n tx: ReadTransaction,\n kind: InvokeKind,\n diffs: DiffsMap | undefined,\n ): Promise<Diff | undefined> {\n const invoke = async <Key extends IndexKey | string>(\n indexName: string | undefined,\n prefix: string,\n compareKey: (diff: DiffOperation<Key>) => string,\n convertInternalDiff: (\n diff: InternalDiff,\n ) => readonly DiffOperation<Key>[],\n ): Promise<readonly DiffOperation<Key>[] | undefined> => {\n let diff: readonly DiffOperation<Key>[];\n if (kind === InvokeKind.InitialRun) {\n if (!this.#initialValuesInFirstDiff) {\n // We are using `undefined` here as a sentinel value to indicate that we\n // should not call the callback in `onDone`.\n return undefined;\n }\n\n // For the initial run, we need to get the \"diffs\" for the whole tree.\n assert(\n diffs === undefined,\n 'Expected diffs to be undefined on initial run',\n );\n\n const newDiff: DiffOperation<Key>[] = [];\n for await (const entry of tx.scan({prefix, indexName}).entries()) {\n newDiff.push({\n op: 'add',\n key: entry[0] as Key,\n newValue: entry[1],\n });\n }\n diff = newDiff;\n } else {\n assert(diffs, 'Expected diffs to be defined for non-initial run');\n const maybeDiff = diffs.get(indexName ?? '') ?? [];\n diff = convertInternalDiff(maybeDiff);\n }\n const newDiff: DiffOperation<Key>[] = [];\n const {length} = diff;\n for (\n let i = diffBinarySearch(diff, prefix, compareKey);\n i < length;\n i++\n ) {\n if (compareKey(diff[i]).startsWith(prefix)) {\n newDiff.push(diff[i]);\n } else {\n break;\n }\n }\n\n // For initial run we should always return something.\n return kind === InvokeKind.InitialRun || newDiff.length > 0\n ? newDiff\n : undefined;\n };\n\n if (this.#indexName) {\n return invoke<IndexKey>(\n this.#indexName,\n this.#prefix,\n diff => diff.key[0],\n internalDiff => convertDiffValues(internalDiff, decodeIndexKey),\n );\n }\n\n return invoke<string>(\n undefined,\n this.#prefix,\n diff => diff.key,\n internalDiff => convertDiffValues(internalDiff, k => k),\n );\n }\n\n matches(diffs: DiffsMap): boolean {\n const diff = diffs.get(this.#indexName ?? '');\n if (diff === undefined) {\n return false;\n }\n\n return watcherMatchesDiff(diff, this.#prefix, this.#indexName);\n }\n\n updateDeps(\n _keys: ReadonlySet<string>,\n _scans: readonly Readonly<ScanSubscriptionInfo>[],\n ): void {\n // not used\n }\n}\n\nfunction convertDiffValues<Key>(\n diff: InternalDiff,\n convertKey: (k: string) => Key,\n): DiffOperation<Key>[] {\n return diff.map(op => {\n const key = convertKey(op.key);\n switch (op.op) {\n case 'add':\n return {\n op: 'add',\n key,\n newValue: op.newValue,\n };\n case 'change':\n return {\n op: 'change',\n key,\n oldValue: op.oldValue,\n newValue: op.newValue,\n };\n case 'del':\n return {\n op: 'del',\n key,\n oldValue: op.oldValue,\n };\n }\n });\n}\n\n/**\n * The options passed to {@link Replicache.subscribe}.\n */\nexport interface SubscribeOptions<R> {\n /**\n * Called when the return value of the body function changes.\n */\n onData: (result: R) => void;\n\n /**\n * If present, called when an error occurs.\n */\n onError?: ((error: unknown) => void) | undefined;\n\n /**\n * If present, called when the subscription is removed/done.\n */\n onDone?: (() => void) | undefined;\n\n /**\n * If present this function is used to determine if the value returned by the\n * body function has changed. If not provided a JSON deep equality check is\n * used.\n */\n isEqual?: ((a: R, b: R) => boolean) | undefined;\n}\n\nexport type UnknownSubscription = Subscription<unknown>;\n\ntype SubscriptionSet = Set<UnknownSubscription>;\n\nexport interface SubscriptionsManager extends DiffComputationConfig {\n clear(): void;\n fire(diffs: DiffsMap): Promise<void>;\n hasPendingSubscriptionRuns: boolean;\n add<R>(subscription: Subscription<R>): () => void;\n}\n\nexport class SubscriptionsManagerImpl implements SubscriptionsManager {\n readonly #subscriptions: SubscriptionSet = new Set();\n readonly #pendingSubscriptions: SubscriptionSet = new Set();\n readonly #queryInternal: QueryInternal;\n readonly #lc: LogContext;\n hasPendingSubscriptionRuns = false;\n readonly #signal: AbortSignal;\n\n constructor(\n queryInternal: QueryInternal,\n lc: LogContext,\n signal: AbortSignal,\n ) {\n this.#queryInternal = queryInternal;\n this.#lc = lc;\n this.#signal = signal;\n }\n\n add<R>(subscription: Subscription<R>): () => void {\n this.#subscriptions.add(subscription as UnknownSubscription);\n void this.#scheduleInitialSubscriptionRun(\n subscription as UnknownSubscription,\n );\n return () =>\n this.#subscriptions.delete(subscription as UnknownSubscription);\n }\n\n clear(): void {\n for (const subscription of this.#subscriptions) {\n subscription.onDone?.();\n }\n this.#subscriptions.clear();\n }\n\n fire(diffs: DiffsMap): Promise<void> {\n const subscriptions = subscriptionsForDiffs(this.#subscriptions, diffs);\n return this.#fireSubscriptions(subscriptions, InvokeKind.Regular, diffs);\n }\n\n async #fireSubscriptions(\n subscriptions: Iterable<UnknownSubscription>,\n kind: InvokeKind,\n diffs: DiffsMap | undefined,\n ) {\n if (this.#signal.aborted) {\n return;\n }\n\n const subs = [...subscriptions] as readonly Subscription<unknown>[];\n if (subs.length === 0) {\n return;\n }\n\n // Use allSettled to gather fulfilled and rejected promises.\n const results = await this.#queryInternal(tx =>\n Promise.allSettled(\n subs.map(async s => {\n const stx = new SubscriptionTransactionWrapper(tx);\n try {\n return await s.invoke(stx, kind, diffs);\n } finally {\n // We need to keep track of the subscription keys even if there was an\n // exception because changes to the keys can make the subscription\n // body succeed.\n s.updateDeps(stx.keys, stx.scans);\n }\n }),\n ),\n );\n\n this.callCallbacks(subs, results);\n }\n\n // Public method so that ZQL can wrap it in a transaction.\n callCallbacks(\n subs: readonly Subscription<unknown>[],\n results: PromiseSettledResult<unknown>[],\n ) {\n for (let i = 0; i < subs.length; i++) {\n const s = subs[i];\n const result = results[i];\n if (result.status === 'fulfilled') {\n s.onData(result.value);\n } else {\n if (s.onError) {\n s.onError(result.reason);\n } else {\n this.#lc.error?.('Error in subscription body:', result.reason);\n }\n }\n }\n }\n\n async #scheduleInitialSubscriptionRun(s: UnknownSubscription) {\n this.#pendingSubscriptions.add(s);\n\n if (!this.hasPendingSubscriptionRuns) {\n this.hasPendingSubscriptionRuns = true;\n await Promise.resolve();\n this.hasPendingSubscriptionRuns = false;\n const subscriptions = [...this.#pendingSubscriptions];\n this.#pendingSubscriptions.clear();\n await this.#fireSubscriptions(\n subscriptions,\n InvokeKind.InitialRun,\n undefined,\n );\n }\n }\n\n shouldComputeDiffs(): boolean {\n return this.#subscriptions.size > 0;\n }\n\n shouldComputeDiffsForIndex(indexName: string): boolean {\n for (const s of this.#subscriptions) {\n if (s.hasIndexSubscription(indexName)) {\n return true;\n }\n }\n return false;\n }\n}\n\nexport type ScanSubscriptionInfo = {\n options: ScanOptions;\n inclusiveLimitKey?: string | undefined;\n};\n\nfunction diffMatchesSubscription(\n keys: ReadonlySet<string>,\n scans: Iterable<Readonly<ScanSubscriptionInfo>>,\n indexName: string,\n diff: InternalDiff,\n): boolean {\n // Keys can only match for non index scans.\n if (indexName === '') {\n for (const diffEntry of diff) {\n if (keys.has(diffEntry.key)) {\n return true;\n }\n }\n }\n\n for (const scanInfo of scans) {\n if (scanInfoMatchesDiff(scanInfo, indexName, diff)) {\n return true;\n }\n }\n return false;\n}\n\nfunction scanInfoMatchesDiff(\n scanInfo: ScanSubscriptionInfo,\n changeIndexName: string,\n diff: InternalDiff,\n): boolean {\n // TODO(arv): Use binary search\n for (const diffEntry of diff) {\n if (scanInfoMatchesKey(scanInfo, changeIndexName, diffEntry.key)) {\n return true;\n }\n }\n\n return false;\n}\n\nexport function scanInfoMatchesKey(\n scanInfo: ScanSubscriptionInfo,\n changeIndexName: string,\n changedKey: string,\n): boolean {\n const {\n indexName = '',\n limit,\n prefix,\n startKey,\n startExclusive,\n startSecondaryKey,\n } = scanInfo.options;\n\n if (changeIndexName !== indexName) {\n return false;\n }\n\n if (!indexName) {\n // A scan with limit <= 0 can have no matches\n if (limit !== undefined && limit <= 0) {\n return false;\n }\n\n // No prefix and no start. Must recompute the subscription because all keys\n // will have an effect on the subscription.\n if (!prefix && !startKey) {\n return true;\n }\n\n if (\n prefix &&\n (!changedKey.startsWith(prefix) ||\n isKeyPastInclusiveLimit(scanInfo, changedKey))\n ) {\n return false;\n }\n\n if (\n startKey &&\n ((startExclusive && lessThanEq(changedKey, startKey)) ||\n lessThan(changedKey, startKey) ||\n isKeyPastInclusiveLimit(scanInfo, changedKey))\n ) {\n return false;\n }\n\n return true;\n }\n\n // No prefix and no start. Must recompute the subscription because all keys\n // will have an effect on the subscription.\n if (!prefix && !startKey && !startSecondaryKey) {\n return true;\n }\n\n const [changedKeySecondary, changedKeyPrimary] = decodeIndexKey(changedKey);\n\n if (prefix) {\n if (!changedKeySecondary.startsWith(prefix)) {\n return false;\n }\n }\n\n if (\n startSecondaryKey &&\n ((startExclusive && lessThanEq(changedKeySecondary, startSecondaryKey)) ||\n lessThan(changedKeySecondary, startSecondaryKey))\n ) {\n return false;\n }\n\n if (\n startKey &&\n ((startExclusive && lessThanEq(changedKeyPrimary, startKey)) ||\n lessThan(changedKeyPrimary, startKey))\n ) {\n return false;\n }\n\n return true;\n}\n\nfunction isKeyPastInclusiveLimit(\n scanInfo: ScanSubscriptionInfo,\n changedKey: string,\n): boolean {\n const {inclusiveLimitKey} = scanInfo;\n return (\n scanInfo.options.limit !== undefined &&\n inclusiveLimitKey !== undefined &&\n greaterThan(changedKey, inclusiveLimitKey)\n );\n}\n\nfunction* subscriptionsForDiffs<V>(\n subscriptions: Set<Subscription<V>>,\n diffs: DiffsMap,\n): Generator<Subscription<V>> {\n for (const subscription of subscriptions) {\n if (subscription.matches(diffs)) {\n yield subscription;\n }\n }\n}\n\nfunction watcherMatchesDiff(\n diff: InternalDiff,\n prefix: string,\n indexName: string | undefined,\n): boolean {\n if (prefix === '') {\n return true;\n }\n\n const compareKey = indexName\n ? (diffOp: InternalDiffOperation) => decodeIndexKey(diffOp.key)[0]\n : (diffOp: InternalDiffOperation) => diffOp.key;\n const i = diffBinarySearch(diff, prefix, compareKey);\n return i < diff.length && compareKey(diff[i]).startsWith(prefix);\n}\n\nexport function diffBinarySearch<Key, Value>(\n diff: readonly InternalDiffOperation<Key, Value>[],\n prefix: string,\n compareKey: (diff: InternalDiffOperation<Key, Value>) => string,\n): number {\n return binarySearch(diff.length, i =>\n compareUTF8(prefix, compareKey(diff[i])),\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"subscriptions.js","names":["#body","#onData","#isEqual","#scans","#keys","#lastValue","#callback","#prefix","#indexName","#initialValuesInFirstDiff","#subscriptions","#pendingSubscriptions","#queryInternal","#lc","#signal","#scheduleInitialSubscriptionRun","#fireSubscriptions"],"sources":["../../../../replicache/src/subscriptions.ts"],"sourcesContent":["import './process-env.ts';\nimport type {LogContext} from '@rocicorp/logger';\nimport {compareUTF8, greaterThan, lessThan, lessThanEq} from 'compare-utf8';\nimport {assert} from '../../shared/src/asserts.ts';\nimport {binarySearch} from '../../shared/src/binary-search.ts';\nimport type {Enum} from '../../shared/src/enum.ts';\nimport {deepEqual} from '../../shared/src/json.ts';\nimport type {\n Diff,\n DiffOperation,\n IndexDiff,\n InternalDiff,\n InternalDiffOperation,\n NoIndexDiff,\n} from './btree/node.ts';\nimport type {IndexKey} from './db/index.ts';\nimport {decodeIndexKey} from './db/index.ts';\nimport type {ScanOptions} from './db/scan.ts';\nimport * as InvokeKind from './invoke-kind-enum.ts';\nimport type {DiffComputationConfig, DiffsMap} from './sync/diff.ts';\nimport {\n type ReadTransaction,\n SubscriptionTransactionWrapper,\n} from './transactions.ts';\nimport type {QueryInternal} from './types.ts';\n\ntype InvokeKind = Enum<typeof InvokeKind>;\n\nexport interface Subscription<R> {\n hasIndexSubscription(indexName: string): boolean;\n\n invoke(\n tx: ReadTransaction,\n kind: InvokeKind,\n diffs: DiffsMap | undefined,\n ): Promise<R>;\n\n matches(diffs: DiffsMap): boolean;\n\n updateDeps(\n keys: ReadonlySet<string>,\n scans: ReadonlyArray<Readonly<ScanSubscriptionInfo>>,\n ): void;\n\n readonly onData: (result: R) => void;\n readonly onError: ((error: unknown) => void) | undefined;\n readonly onDone: (() => void) | undefined;\n}\n\nconst emptySet: ReadonlySet<string> = new Set();\n\nconst unitializedLastValue = Symbol();\ntype UnitializedLastValue = typeof unitializedLastValue;\n\nexport class SubscriptionImpl<R> implements Subscription<R> {\n readonly #body: (tx: ReadTransaction) => Promise<R>;\n readonly #onData: (result: R) => void;\n #lastValue: R | UnitializedLastValue = unitializedLastValue;\n #keys = emptySet;\n #scans: readonly Readonly<ScanSubscriptionInfo>[] = [];\n\n readonly onError: ((error: unknown) => void) | undefined;\n readonly onDone: (() => void) | undefined;\n readonly #isEqual: (a: R, b: R) => boolean;\n\n constructor(\n body: (tx: ReadTransaction) => Promise<R>,\n onData: (result: R) => void,\n onError: ((error: unknown) => void) | undefined,\n onDone: (() => void) | undefined,\n // deepEqual operates on any JSON value but argument might be more specific.\n isEqual: (a: R, b: R) => boolean = deepEqual as (a: R, b: R) => boolean,\n ) {\n this.#body = body;\n this.#onData = onData;\n this.onError = onError;\n this.onDone = onDone;\n this.#isEqual = isEqual;\n }\n\n hasIndexSubscription(indexName: string): boolean {\n for (const scan of this.#scans) {\n if (scan.options.indexName === indexName) {\n return true;\n }\n }\n return false;\n }\n\n invoke(\n tx: ReadTransaction,\n _kind: InvokeKind,\n _diffs: DiffsMap | undefined,\n ): Promise<R> {\n return this.#body(tx);\n }\n\n matches(diffs: DiffsMap): boolean {\n for (const [indexName, diff] of diffs) {\n if (diffMatchesSubscription(this.#keys, this.#scans, indexName, diff)) {\n return true;\n }\n }\n\n return false;\n }\n\n updateDeps(\n keys: ReadonlySet<string>,\n scans: readonly Readonly<ScanSubscriptionInfo>[],\n ): void {\n this.#keys = keys;\n this.#scans = scans;\n }\n\n onData(result: R): void {\n if (\n this.#lastValue === unitializedLastValue ||\n !this.#isEqual(this.#lastValue, result)\n ) {\n this.#lastValue = result;\n this.#onData(result);\n }\n }\n}\n\nexport {SubscriptionImpl as SubscriptionImplForTesting};\n\n/**\n * Function that gets passed into {@link Replicache.experimentalWatch} and gets\n * called when the data in Replicache changes.\n *\n * @experimental This type is experimental and may change in the future.\n */\nexport type WatchNoIndexCallback = (diff: NoIndexDiff) => void;\n\nexport type WatchCallbackForOptions<Options extends WatchOptions> =\n Options extends WatchIndexOptions ? WatchIndexCallback : WatchNoIndexCallback;\n\n/**\n * Function that gets passed into {@link Replicache.experimentalWatch} when doing a\n * watch on a secondary index map and gets called when the data in Replicache\n * changes.\n *\n * @experimental This type is experimental and may change in the future.\n */\nexport type WatchIndexCallback = (diff: IndexDiff) => void;\n\n/**\n * Options for {@link Replicache.experimentalWatch}.\n *\n * @experimental This interface is experimental and may change in the future.\n */\nexport type WatchOptions = WatchIndexOptions | WatchNoIndexOptions;\n\n/**\n * Options object passed to {@link Replicache.experimentalWatch}. This is for an\n * index watch.\n */\nexport type WatchIndexOptions = WatchNoIndexOptions & {\n /**\n * When provided, the `watch` is limited to the changes that apply to the index map.\n */\n indexName: string;\n};\n\n/**\n * Options object passed to {@link Replicache.experimentalWatch}. This is for a non\n * index watch.\n */\nexport type WatchNoIndexOptions = {\n /**\n * When provided, the `watch` is limited to changes where the `key` starts\n * with `prefix`.\n */\n prefix?: string | undefined;\n\n /**\n * When this is set to `true` (default is `false`), the `watch` callback will\n * be called once asynchronously when watch is called. The arguments in that\n * case is a diff where we consider all the existing values in Replicache as\n * being added.\n */\n initialValuesInFirstDiff?: boolean | undefined;\n};\n\nexport type WatchCallback = (diff: Diff) => void;\n\nexport class WatchSubscription implements Subscription<Diff | undefined> {\n readonly #callback: WatchCallback;\n readonly #prefix: string;\n readonly #indexName: string | undefined;\n readonly #initialValuesInFirstDiff: boolean;\n\n readonly onError: ((error: unknown) => void) | undefined = undefined;\n readonly onDone: (() => void) | undefined = undefined;\n\n constructor(callback: WatchCallback, options?: WatchOptions) {\n this.#callback = callback;\n this.#prefix = options?.prefix ?? '';\n this.#indexName = (options as WatchIndexOptions)?.indexName;\n this.#initialValuesInFirstDiff = options?.initialValuesInFirstDiff ?? false;\n }\n\n hasIndexSubscription(indexName: string): boolean {\n return this.#indexName === indexName;\n }\n\n onData(result: Diff | undefined): void {\n if (result !== undefined) {\n this.#callback(result);\n }\n }\n\n invoke(\n tx: ReadTransaction,\n kind: InvokeKind,\n diffs: DiffsMap | undefined,\n ): Promise<Diff | undefined> {\n const invoke = async <Key extends IndexKey | string>(\n indexName: string | undefined,\n prefix: string,\n compareKey: (diff: DiffOperation<Key>) => string,\n convertInternalDiff: (\n diff: InternalDiff,\n ) => readonly DiffOperation<Key>[],\n ): Promise<readonly DiffOperation<Key>[] | undefined> => {\n let diff: readonly DiffOperation<Key>[];\n if (kind === InvokeKind.InitialRun) {\n if (!this.#initialValuesInFirstDiff) {\n // We are using `undefined` here as a sentinel value to indicate that we\n // should not call the callback in `onDone`.\n return undefined;\n }\n\n // For the initial run, we need to get the \"diffs\" for the whole tree.\n assert(\n diffs === undefined,\n 'Expected diffs to be undefined on initial run',\n );\n\n const newDiff: DiffOperation<Key>[] = [];\n for await (const entry of tx.scan({prefix, indexName}).entries()) {\n newDiff.push({\n op: 'add',\n key: entry[0] as Key,\n newValue: entry[1],\n });\n }\n diff = newDiff;\n } else {\n assert(diffs, 'Expected diffs to be defined for non-initial run');\n const maybeDiff = diffs.get(indexName ?? '') ?? [];\n diff = convertInternalDiff(maybeDiff);\n }\n const newDiff: DiffOperation<Key>[] = [];\n const {length} = diff;\n for (\n let i = diffBinarySearch(diff, prefix, compareKey);\n i < length;\n i++\n ) {\n if (compareKey(diff[i]).startsWith(prefix)) {\n newDiff.push(diff[i]);\n } else {\n break;\n }\n }\n\n // For initial run we should always return something.\n return kind === InvokeKind.InitialRun || newDiff.length > 0\n ? newDiff\n : undefined;\n };\n\n if (!process.env.DISABLE_REPLICACHE_INDEXES && this.#indexName) {\n return invoke<IndexKey>(\n this.#indexName,\n this.#prefix,\n diff => diff.key[0],\n internalDiff => convertDiffValues(internalDiff, decodeIndexKey),\n );\n }\n\n return invoke<string>(\n undefined,\n this.#prefix,\n diff => diff.key,\n internalDiff => convertDiffValues(internalDiff, k => k),\n );\n }\n\n matches(diffs: DiffsMap): boolean {\n const diff = diffs.get(this.#indexName ?? '');\n if (diff === undefined) {\n return false;\n }\n\n return watcherMatchesDiff(diff, this.#prefix, this.#indexName);\n }\n\n updateDeps(\n _keys: ReadonlySet<string>,\n _scans: readonly Readonly<ScanSubscriptionInfo>[],\n ): void {\n // not used\n }\n}\n\nfunction convertDiffValues<Key>(\n diff: InternalDiff,\n convertKey: (k: string) => Key,\n): DiffOperation<Key>[] {\n return diff.map(op => {\n const key = convertKey(op.key);\n switch (op.op) {\n case 'add':\n return {\n op: 'add',\n key,\n newValue: op.newValue,\n };\n case 'change':\n return {\n op: 'change',\n key,\n oldValue: op.oldValue,\n newValue: op.newValue,\n };\n case 'del':\n return {\n op: 'del',\n key,\n oldValue: op.oldValue,\n };\n }\n });\n}\n\n/**\n * The options passed to {@link Replicache.subscribe}.\n */\nexport interface SubscribeOptions<R> {\n /**\n * Called when the return value of the body function changes.\n */\n onData: (result: R) => void;\n\n /**\n * If present, called when an error occurs.\n */\n onError?: ((error: unknown) => void) | undefined;\n\n /**\n * If present, called when the subscription is removed/done.\n */\n onDone?: (() => void) | undefined;\n\n /**\n * If present this function is used to determine if the value returned by the\n * body function has changed. If not provided a JSON deep equality check is\n * used.\n */\n isEqual?: ((a: R, b: R) => boolean) | undefined;\n}\n\nexport type UnknownSubscription = Subscription<unknown>;\n\ntype SubscriptionSet = Set<UnknownSubscription>;\n\nexport interface SubscriptionsManager extends DiffComputationConfig {\n clear(): void;\n fire(diffs: DiffsMap): Promise<void>;\n hasPendingSubscriptionRuns: boolean;\n add<R>(subscription: Subscription<R>): () => void;\n}\n\nexport class SubscriptionsManagerImpl implements SubscriptionsManager {\n readonly #subscriptions: SubscriptionSet = new Set();\n readonly #pendingSubscriptions: SubscriptionSet = new Set();\n readonly #queryInternal: QueryInternal;\n readonly #lc: LogContext;\n hasPendingSubscriptionRuns = false;\n readonly #signal: AbortSignal;\n\n constructor(\n queryInternal: QueryInternal,\n lc: LogContext,\n signal: AbortSignal,\n ) {\n this.#queryInternal = queryInternal;\n this.#lc = lc;\n this.#signal = signal;\n }\n\n add<R>(subscription: Subscription<R>): () => void {\n this.#subscriptions.add(subscription as UnknownSubscription);\n void this.#scheduleInitialSubscriptionRun(\n subscription as UnknownSubscription,\n );\n return () =>\n this.#subscriptions.delete(subscription as UnknownSubscription);\n }\n\n clear(): void {\n for (const subscription of this.#subscriptions) {\n subscription.onDone?.();\n }\n this.#subscriptions.clear();\n }\n\n fire(diffs: DiffsMap): Promise<void> {\n const subscriptions = subscriptionsForDiffs(this.#subscriptions, diffs);\n return this.#fireSubscriptions(subscriptions, InvokeKind.Regular, diffs);\n }\n\n async #fireSubscriptions(\n subscriptions: Iterable<UnknownSubscription>,\n kind: InvokeKind,\n diffs: DiffsMap | undefined,\n ) {\n if (this.#signal.aborted) {\n return;\n }\n\n const subs = [...subscriptions] as readonly Subscription<unknown>[];\n if (subs.length === 0) {\n return;\n }\n\n // Use allSettled to gather fulfilled and rejected promises.\n const results = await this.#queryInternal(tx =>\n Promise.allSettled(\n subs.map(async s => {\n const stx = new SubscriptionTransactionWrapper(tx);\n try {\n return await s.invoke(stx, kind, diffs);\n } finally {\n // We need to keep track of the subscription keys even if there was an\n // exception because changes to the keys can make the subscription\n // body succeed.\n s.updateDeps(stx.keys, stx.scans);\n }\n }),\n ),\n );\n\n this.callCallbacks(subs, results);\n }\n\n // Public method so that ZQL can wrap it in a transaction.\n callCallbacks(\n subs: readonly Subscription<unknown>[],\n results: PromiseSettledResult<unknown>[],\n ) {\n for (let i = 0; i < subs.length; i++) {\n const s = subs[i];\n const result = results[i];\n if (result.status === 'fulfilled') {\n s.onData(result.value);\n } else {\n if (s.onError) {\n s.onError(result.reason);\n } else {\n this.#lc.error?.('Error in subscription body:', result.reason);\n }\n }\n }\n }\n\n async #scheduleInitialSubscriptionRun(s: UnknownSubscription) {\n this.#pendingSubscriptions.add(s);\n\n if (!this.hasPendingSubscriptionRuns) {\n this.hasPendingSubscriptionRuns = true;\n await Promise.resolve();\n this.hasPendingSubscriptionRuns = false;\n const subscriptions = [...this.#pendingSubscriptions];\n this.#pendingSubscriptions.clear();\n await this.#fireSubscriptions(\n subscriptions,\n InvokeKind.InitialRun,\n undefined,\n );\n }\n }\n\n shouldComputeDiffs(): boolean {\n return this.#subscriptions.size > 0;\n }\n\n shouldComputeDiffsForIndex(indexName: string): boolean {\n for (const s of this.#subscriptions) {\n if (s.hasIndexSubscription(indexName)) {\n return true;\n }\n }\n return false;\n }\n}\n\nexport type ScanSubscriptionInfo = {\n options: ScanOptions;\n inclusiveLimitKey?: string | undefined;\n};\n\nfunction diffMatchesSubscription(\n keys: ReadonlySet<string>,\n scans: Iterable<Readonly<ScanSubscriptionInfo>>,\n indexName: string,\n diff: InternalDiff,\n): boolean {\n // Keys can only match for non index scans.\n if (indexName === '') {\n for (const diffEntry of diff) {\n if (keys.has(diffEntry.key)) {\n return true;\n }\n }\n }\n\n for (const scanInfo of scans) {\n if (scanInfoMatchesDiff(scanInfo, indexName, diff)) {\n return true;\n }\n }\n return false;\n}\n\nfunction scanInfoMatchesDiff(\n scanInfo: ScanSubscriptionInfo,\n changeIndexName: string,\n diff: InternalDiff,\n): boolean {\n // TODO(arv): Use binary search\n for (const diffEntry of diff) {\n if (scanInfoMatchesKey(scanInfo, changeIndexName, diffEntry.key)) {\n return true;\n }\n }\n\n return false;\n}\n\nexport function scanInfoMatchesKey(\n scanInfo: ScanSubscriptionInfo,\n changeIndexName: string,\n changedKey: string,\n): boolean {\n const {\n indexName = '',\n limit,\n prefix,\n startKey,\n startExclusive,\n startSecondaryKey,\n } = scanInfo.options;\n\n if (changeIndexName !== indexName) {\n return false;\n }\n\n if (!indexName) {\n // A scan with limit <= 0 can have no matches\n if (limit !== undefined && limit <= 0) {\n return false;\n }\n\n // No prefix and no start. Must recompute the subscription because all keys\n // will have an effect on the subscription.\n if (!prefix && !startKey) {\n return true;\n }\n\n if (\n prefix &&\n (!changedKey.startsWith(prefix) ||\n isKeyPastInclusiveLimit(scanInfo, changedKey))\n ) {\n return false;\n }\n\n if (\n startKey &&\n ((startExclusive && lessThanEq(changedKey, startKey)) ||\n lessThan(changedKey, startKey) ||\n isKeyPastInclusiveLimit(scanInfo, changedKey))\n ) {\n return false;\n }\n\n return true;\n }\n\n // No prefix and no start. Must recompute the subscription because all keys\n // will have an effect on the subscription.\n if (!prefix && !startKey && !startSecondaryKey) {\n return true;\n }\n\n if (process.env.DISABLE_REPLICACHE_INDEXES) {\n // Unreachable in practice: when indexes are disabled no scan subscription\n // has an indexName and no diff is keyed by one, so changeIndexName and\n // indexName are both '' and we return above. This early return exists so\n // that the decodeIndexKey call below can be dead-code eliminated.\n return false;\n }\n\n const [changedKeySecondary, changedKeyPrimary] = decodeIndexKey(changedKey);\n\n if (prefix) {\n if (!changedKeySecondary.startsWith(prefix)) {\n return false;\n }\n }\n\n if (\n startSecondaryKey &&\n ((startExclusive && lessThanEq(changedKeySecondary, startSecondaryKey)) ||\n lessThan(changedKeySecondary, startSecondaryKey))\n ) {\n return false;\n }\n\n if (\n startKey &&\n ((startExclusive && lessThanEq(changedKeyPrimary, startKey)) ||\n lessThan(changedKeyPrimary, startKey))\n ) {\n return false;\n }\n\n return true;\n}\n\nfunction isKeyPastInclusiveLimit(\n scanInfo: ScanSubscriptionInfo,\n changedKey: string,\n): boolean {\n const {inclusiveLimitKey} = scanInfo;\n return (\n scanInfo.options.limit !== undefined &&\n inclusiveLimitKey !== undefined &&\n greaterThan(changedKey, inclusiveLimitKey)\n );\n}\n\nfunction* subscriptionsForDiffs<V>(\n subscriptions: Set<Subscription<V>>,\n diffs: DiffsMap,\n): Generator<Subscription<V>> {\n for (const subscription of subscriptions) {\n if (subscription.matches(diffs)) {\n yield subscription;\n }\n }\n}\n\nfunction watcherMatchesDiff(\n diff: InternalDiff,\n prefix: string,\n indexName: string | undefined,\n): boolean {\n if (prefix === '') {\n return true;\n }\n\n const compareKey =\n !process.env.DISABLE_REPLICACHE_INDEXES && indexName\n ? (diffOp: InternalDiffOperation) => decodeIndexKey(diffOp.key)[0]\n : (diffOp: InternalDiffOperation) => diffOp.key;\n const i = diffBinarySearch(diff, prefix, compareKey);\n return i < diff.length && compareKey(diff[i]).startsWith(prefix);\n}\n\nexport function diffBinarySearch<Key, Value>(\n diff: readonly InternalDiffOperation<Key, Value>[],\n prefix: string,\n compareKey: (diff: InternalDiffOperation<Key, Value>) => string,\n): number {\n return binarySearch(diff.length, i =>\n compareUTF8(prefix, compareKey(diff[i])),\n );\n}\n"],"mappings":"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"}
@@ -1,3 +1,4 @@
1
+ import './process-env.ts';
1
2
  import type { LogContext } from '@rocicorp/logger';
2
3
  import type { JSONValue, ReadonlyJSONValue } from '../../shared/src/json.ts';
3
4
  import { type IndexKey } from './db/index.ts';
@@ -1 +1 @@
1
- {"version":3,"file":"transactions.d.ts","sourceRoot":"","sources":["../../../../replicache/src/transactions.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"transactions.d.ts","sourceRoot":"","sources":["../../../../replicache/src/transactions.ts"],"names":[],"mappings":"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"}
@@ -1,8 +1,7 @@
1
1
  import { deepFreeze } from "./frozen-json.js";
2
- import { decodeIndexKey } from "./db/index.js";
3
2
  import { rejectIfClosed, throwIfClosed } from "./transaction-closed-error.js";
4
3
  import { isScanIndexOptions, toDbScanOptions } from "./scan-options.js";
5
- import { ScanResultImpl, fromKeyForIndexScanInternal } from "./scan-iterator.js";
4
+ import { ScanResultImpl } from "./scan-iterator.js";
6
5
  import { greaterThan } from "compare-utf8";
7
6
  //#region ../replicache/src/transactions.ts
8
7
  var transactionIDCounter = 0;
@@ -123,8 +122,7 @@ function makeScanResultFromScanIteratorInternal(iter, options, dbRead, onLimitKe
123
122
  return new ScanResultImpl(iter, options, dbRead, onLimitKey);
124
123
  }
125
124
  async function* getScanIteratorForIndexMap(dbRead, options) {
126
- const map = dbRead.getMapForIndex(options.indexName);
127
- for await (const entry of map.scan(fromKeyForIndexScanInternal(options))) yield [decodeIndexKey(entry[0]), entry[1]];
125
+ throw new Error(`Unknown index name: ${options.indexName}`);
128
126
  }
129
127
  //#endregion
130
128
  export { ReadTransactionImpl, SubscriptionTransactionWrapper, WriteTransactionImpl, zeroData };
@@ -1 +1 @@
1
- {"version":3,"file":"transactions.js","names":["#keys","#scans","#tx"],"sources":["../../../../replicache/src/transactions.ts"],"sourcesContent":["import type {LogContext} from '@rocicorp/logger';\nimport {greaterThan} from 'compare-utf8';\nimport type {JSONValue, ReadonlyJSONValue} from '../../shared/src/json.ts';\nimport {type IndexKey, decodeIndexKey} from './db/index.ts';\nimport type {Read} from './db/read.ts';\nimport type {Write} from './db/write.ts';\nimport {deepFreeze} from './frozen-json.ts';\nimport type {IndexDefinition} from './index-defs.ts';\nimport type {ZeroTxData} from './replicache-options.ts';\nimport type {ScanResult} from './scan-iterator.ts';\nimport {ScanResultImpl, fromKeyForIndexScanInternal} from './scan-iterator.ts';\nimport {\n type KeyTypeForScanOptions,\n type ScanIndexOptions,\n type ScanNoIndexOptions,\n type ScanOptions,\n isScanIndexOptions,\n toDbScanOptions,\n} from './scan-options.ts';\nimport type {ScanSubscriptionInfo} from './subscriptions.ts';\nimport type {ClientID} from './sync/ids.ts';\nimport {rejectIfClosed, throwIfClosed} from './transaction-closed-error.ts';\n\nexport type TransactionEnvironment = 'client' | 'server';\nexport type TransactionLocation = TransactionEnvironment;\nexport type TransactionReason = 'initial' | 'rebase' | 'authoritative';\n\n/**\n * Basic deep readonly type. It works for {@link JSONValue}.\n */\nexport type DeepReadonly<T> = T extends\n | null\n | boolean\n | string\n | number\n | undefined\n ? T\n : DeepReadonlyObject<T>;\n\nexport type DeepReadonlyObject<T> = {\n readonly [K in keyof T]: DeepReadonly<T[K]>;\n};\n\n/**\n * ReadTransactions are used with {@link Replicache.query} and\n * {@link Replicache.subscribe} and allows read operations on the\n * database.\n */\nexport interface ReadTransaction {\n readonly clientID: ClientID;\n /** @deprecated Use {@link ReadTransaction.location} instead. */\n readonly environment: TransactionLocation;\n readonly location: TransactionLocation;\n\n /**\n * Get a single value from the database. If the `key` is not present this\n * returns `undefined`.\n *\n * Important: The returned JSON is readonly and should not be modified. This\n * is only enforced statically by TypeScript and there are no runtime checks\n * for performance reasons. If you mutate the return value you will get\n * undefined behavior.\n */\n\n get(key: string): Promise<ReadonlyJSONValue | undefined>;\n get<T extends JSONValue>(key: string): Promise<DeepReadonly<T> | undefined>;\n\n /** Determines if a single `key` is present in the database. */\n has(key: string): Promise<boolean>;\n\n /** Whether the database is empty. */\n isEmpty(): Promise<boolean>;\n\n /**\n * Gets many values from the database. This returns a {@link ScanResult} which\n * implements `AsyncIterable`. It also has methods to iterate over the\n * {@link ScanResult.keys | keys} and {@link ScanResult.entries | entries}.\n *\n * If `options` has an `indexName`, then this does a scan over an index with\n * that name. A scan over an index uses a tuple for the key consisting of\n * `[secondary: string, primary: string]`.\n *\n * If the {@link ScanResult} is used after the `ReadTransaction` has been closed\n * it will throw a {@link TransactionClosedError}.\n *\n * Important: The returned JSON is readonly and should not be modified. This\n * is only enforced statically by TypeScript and there are no runtime checks\n * for performance reasons. If you mutate the return value you will get\n * undefined behavior.\n */\n scan(options: ScanIndexOptions): ScanResult<IndexKey, ReadonlyJSONValue>;\n scan(options?: ScanNoIndexOptions): ScanResult<string, ReadonlyJSONValue>;\n scan(options?: ScanOptions): ScanResult<IndexKey | string, ReadonlyJSONValue>;\n\n scan<V extends ReadonlyJSONValue>(\n options: ScanIndexOptions,\n ): ScanResult<IndexKey, DeepReadonly<V>>;\n scan<V extends ReadonlyJSONValue>(\n options?: ScanNoIndexOptions,\n ): ScanResult<string, DeepReadonly<V>>;\n scan<V extends ReadonlyJSONValue>(\n options?: ScanOptions,\n ): ScanResult<IndexKey | string, DeepReadonly<V>>;\n}\n\nlet transactionIDCounter = 0;\n\nexport class ReadTransactionImpl implements ReadTransaction {\n readonly clientID: ClientID;\n readonly dbtx: Read;\n protected readonly _lc: LogContext;\n\n /**\n * The location in which this transaction is being used. This is either `client` or `server`.\n */\n readonly location: TransactionLocation;\n /** @deprecated Use {@link ReadTransaction.location} instead. */\n readonly environment: TransactionLocation;\n\n constructor(\n clientID: ClientID,\n dbRead: Read,\n lc: LogContext,\n rpcName = 'openReadTransaction',\n ) {\n this.clientID = clientID;\n this.dbtx = dbRead;\n this._lc = lc\n .withContext(rpcName)\n .withContext('txid', transactionIDCounter++);\n this.environment = 'client';\n this.location = 'client';\n }\n\n get(key: string): Promise<ReadonlyJSONValue | undefined>;\n get<V extends JSONValue>(key: string): Promise<DeepReadonly<V> | undefined> {\n return (\n rejectIfClosed(this.dbtx) ||\n (this.dbtx.get(key) as Promise<DeepReadonly<V> | undefined>)\n );\n }\n\n // oxlint-disable-next-line require-await\n async has(key: string): Promise<boolean> {\n throwIfClosed(this.dbtx);\n return this.dbtx.has(key);\n }\n\n // oxlint-disable-next-line require-await\n async isEmpty(): Promise<boolean> {\n throwIfClosed(this.dbtx);\n return this.dbtx.isEmpty();\n }\n\n scan(options: ScanIndexOptions): ScanResult<IndexKey, ReadonlyJSONValue>;\n scan(options?: ScanNoIndexOptions): ScanResult<string, ReadonlyJSONValue>;\n scan(options?: ScanOptions): ScanResult<IndexKey | string, ReadonlyJSONValue>;\n\n scan<V extends ReadonlyJSONValue>(\n options: ScanIndexOptions,\n ): ScanResult<IndexKey, DeepReadonly<V>>;\n scan<V extends ReadonlyJSONValue>(\n options?: ScanNoIndexOptions,\n ): ScanResult<string, DeepReadonly<V>>;\n scan<V extends ReadonlyJSONValue>(\n options?: ScanOptions,\n ): ScanResult<IndexKey | string, DeepReadonly<V>>;\n\n scan(\n options?: ScanOptions,\n ): ScanResult<IndexKey | string, ReadonlyJSONValue> {\n return scan(options, this.dbtx, noop);\n }\n}\n\nfunction noop(_: unknown): void {\n // empty\n}\n\nfunction scan<Options extends ScanOptions, V extends JSONValue>(\n options: Options | undefined,\n dbRead: Read,\n onLimitKey: (inclusiveLimitKey: string) => void,\n): ScanResult<KeyTypeForScanOptions<Options>, V> {\n const iter = getScanIterator<Options, V>(dbRead, options);\n return makeScanResultFromScanIteratorInternal(\n iter,\n options ?? ({} as Options),\n dbRead,\n onLimitKey,\n );\n}\n\n// An implementation of ReadTransaction that keeps track of `keys` and `scans`\n// for use with Subscriptions.\nexport class SubscriptionTransactionWrapper implements ReadTransaction {\n readonly #keys: Set<string> = new Set();\n readonly #scans: ScanSubscriptionInfo[] = [];\n readonly #tx: ReadTransactionImpl;\n\n constructor(tx: ReadTransactionImpl) {\n this.#tx = tx;\n }\n\n get environment(): TransactionLocation {\n return this.#tx.location;\n }\n\n get location(): TransactionLocation {\n return this.#tx.location;\n }\n\n get clientID(): string {\n return this.#tx.clientID;\n }\n\n isEmpty(): Promise<boolean> {\n // Any change to the subscription requires rerunning it.\n this.#scans.push({options: {}});\n return this.#tx.isEmpty();\n }\n\n get(key: string): Promise<ReadonlyJSONValue | undefined>;\n get<T extends JSONValue>(key: string): Promise<DeepReadonly<T> | undefined> {\n this.#keys.add(key);\n return this.#tx.get(key) as Promise<DeepReadonly<T> | undefined>;\n }\n\n has(key: string): Promise<boolean> {\n this.#keys.add(key);\n return this.#tx.has(key);\n }\n\n scan(options: ScanIndexOptions): ScanResult<IndexKey, ReadonlyJSONValue>;\n scan(options?: ScanNoIndexOptions): ScanResult<string, ReadonlyJSONValue>;\n scan(options?: ScanOptions): ScanResult<IndexKey | string, ReadonlyJSONValue>;\n\n scan<V extends ReadonlyJSONValue>(\n options: ScanIndexOptions,\n ): ScanResult<IndexKey, DeepReadonly<V>>;\n scan<V extends ReadonlyJSONValue>(\n options?: ScanNoIndexOptions,\n ): ScanResult<string, DeepReadonly<V>>;\n scan<V extends ReadonlyJSONValue>(\n options?: ScanOptions,\n ): ScanResult<IndexKey | string, DeepReadonly<V>>;\n\n scan(\n options?: ScanOptions,\n ): ScanResult<IndexKey | string, ReadonlyJSONValue> {\n const scanInfo: ScanSubscriptionInfo = {\n options: toDbScanOptions(options),\n inclusiveLimitKey: undefined,\n };\n this.#scans.push(scanInfo);\n return scan(options, this.#tx.dbtx, inclusiveLimitKey => {\n scanInfo.inclusiveLimitKey = inclusiveLimitKey;\n });\n }\n\n get keys(): ReadonlySet<string> {\n return this.#keys;\n }\n\n get scans(): ScanSubscriptionInfo[] {\n return this.#scans;\n }\n}\n\n/**\n * WriteTransactions are used with *mutators* which are registered using\n * {@link ReplicacheOptions.mutators} and allows read and write operations on the\n * database.\n */\nexport interface WriteTransaction extends ReadTransaction {\n /**\n * The ID of the mutation that is being applied.\n */\n readonly mutationID: number;\n\n /**\n * The reason for the transaction. This can be `initial`, `rebase` or `authoriative`.\n */\n readonly reason: TransactionReason;\n\n /**\n * Sets a single `value` in the database. The value will be frozen (using\n * `Object.freeze`) in debug mode.\n */\n set(key: string, value: ReadonlyJSONValue): Promise<void>;\n\n /**\n * @deprecated Use {@link WriteTransaction.set} instead.\n */\n put(key: string, value: ReadonlyJSONValue): Promise<void>;\n\n /**\n * Removes a `key` and its value from the database. Returns `true` if there was a\n * `key` to remove.\n */\n del(key: string): Promise<boolean>;\n}\n\n// Internal symbol, not exported by Replicache\n// but accessible to Zero.\nexport const zeroData = Symbol();\n\nexport class WriteTransactionImpl\n extends ReadTransactionImpl\n implements WriteTransaction\n{\n // use `declare` to specialize the type.\n declare readonly dbtx: Write;\n readonly reason: TransactionReason;\n readonly mutationID: number;\n readonly [zeroData]: ZeroTxData | undefined;\n\n constructor(\n clientID: ClientID,\n mutationID: number,\n reason: TransactionReason,\n zData: ZeroTxData | undefined,\n dbWrite: Write,\n lc: LogContext,\n rpcName = 'openWriteTransaction',\n ) {\n super(clientID, dbWrite, lc, rpcName);\n this.mutationID = mutationID;\n this.reason = reason;\n this[zeroData] = zData;\n }\n\n put(key: string, value: ReadonlyJSONValue): Promise<void> {\n return this.set(key, value);\n }\n\n async set(key: string, value: ReadonlyJSONValue): Promise<void> {\n throwIfClosed(this.dbtx);\n await this.dbtx.put(this._lc, key, deepFreeze(value));\n }\n\n del(key: string): Promise<boolean> {\n return rejectIfClosed(this.dbtx) ?? this.dbtx.del(this._lc, key);\n }\n}\n\nexport type CreateIndexDefinition = IndexDefinition & {name: string};\n\ntype Entry<Key, Value> = readonly [key: Key, value: Value];\n\ntype IndexKeyEntry<Value> = Entry<IndexKey, Value>;\n\ntype StringKeyEntry<Value> = Entry<string, Value>;\n\nexport type EntryForOptions<\n Options extends ScanOptions,\n V,\n> = Options extends ScanIndexOptions ? IndexKeyEntry<V> : StringKeyEntry<V>;\n\nfunction getScanIterator<Options extends ScanOptions, V>(\n dbRead: Read,\n options: Options | undefined,\n): AsyncIterable<EntryForOptions<Options, V>> {\n if (options && isScanIndexOptions(options)) {\n return getScanIteratorForIndexMap(dbRead, options) as AsyncIterable<\n EntryForOptions<Options, V>\n >;\n }\n\n return dbRead.map.scan(fromKeyForNonIndexScan(options)) as AsyncIterable<\n EntryForOptions<Options, V>\n >;\n}\n\nexport function fromKeyForNonIndexScan(\n options: ScanNoIndexOptions | undefined,\n): string {\n if (!options) {\n return '';\n }\n\n const {prefix = '', start} = options;\n if (start && greaterThan(start.key, prefix)) {\n return start.key;\n }\n return prefix;\n}\n\nfunction makeScanResultFromScanIteratorInternal<\n Options extends ScanOptions,\n V extends JSONValue,\n>(\n iter: AsyncIterable<EntryForOptions<Options, V>>,\n options: Options,\n dbRead: Read,\n onLimitKey: (inclusiveLimitKey: string) => void,\n): ScanResult<KeyTypeForScanOptions<Options>, V> {\n return new ScanResultImpl(iter, options, dbRead, onLimitKey);\n}\n\nasync function* getScanIteratorForIndexMap(\n dbRead: Read,\n options: ScanIndexOptions,\n): AsyncIterable<IndexKeyEntry<ReadonlyJSONValue>> {\n const map = dbRead.getMapForIndex(options.indexName);\n for await (const entry of map.scan(fromKeyForIndexScanInternal(options))) {\n yield [decodeIndexKey(entry[0]), entry[1]];\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"transactions.js","names":["#keys","#scans","#tx"],"sources":["../../../../replicache/src/transactions.ts"],"sourcesContent":["import './process-env.ts';\nimport type {LogContext} from '@rocicorp/logger';\nimport {greaterThan} from 'compare-utf8';\nimport type {JSONValue, ReadonlyJSONValue} from '../../shared/src/json.ts';\nimport {type IndexKey, decodeIndexKey} from './db/index.ts';\nimport type {Read} from './db/read.ts';\nimport type {Write} from './db/write.ts';\nimport {deepFreeze} from './frozen-json.ts';\nimport type {IndexDefinition} from './index-defs.ts';\nimport type {ZeroTxData} from './replicache-options.ts';\nimport type {ScanResult} from './scan-iterator.ts';\nimport {ScanResultImpl, fromKeyForIndexScanInternal} from './scan-iterator.ts';\nimport {\n type KeyTypeForScanOptions,\n type ScanIndexOptions,\n type ScanNoIndexOptions,\n type ScanOptions,\n isScanIndexOptions,\n toDbScanOptions,\n} from './scan-options.ts';\nimport type {ScanSubscriptionInfo} from './subscriptions.ts';\nimport type {ClientID} from './sync/ids.ts';\nimport {rejectIfClosed, throwIfClosed} from './transaction-closed-error.ts';\n\nexport type TransactionEnvironment = 'client' | 'server';\nexport type TransactionLocation = TransactionEnvironment;\nexport type TransactionReason = 'initial' | 'rebase' | 'authoritative';\n\n/**\n * Basic deep readonly type. It works for {@link JSONValue}.\n */\nexport type DeepReadonly<T> = T extends\n | null\n | boolean\n | string\n | number\n | undefined\n ? T\n : DeepReadonlyObject<T>;\n\nexport type DeepReadonlyObject<T> = {\n readonly [K in keyof T]: DeepReadonly<T[K]>;\n};\n\n/**\n * ReadTransactions are used with {@link Replicache.query} and\n * {@link Replicache.subscribe} and allows read operations on the\n * database.\n */\nexport interface ReadTransaction {\n readonly clientID: ClientID;\n /** @deprecated Use {@link ReadTransaction.location} instead. */\n readonly environment: TransactionLocation;\n readonly location: TransactionLocation;\n\n /**\n * Get a single value from the database. If the `key` is not present this\n * returns `undefined`.\n *\n * Important: The returned JSON is readonly and should not be modified. This\n * is only enforced statically by TypeScript and there are no runtime checks\n * for performance reasons. If you mutate the return value you will get\n * undefined behavior.\n */\n\n get(key: string): Promise<ReadonlyJSONValue | undefined>;\n get<T extends JSONValue>(key: string): Promise<DeepReadonly<T> | undefined>;\n\n /** Determines if a single `key` is present in the database. */\n has(key: string): Promise<boolean>;\n\n /** Whether the database is empty. */\n isEmpty(): Promise<boolean>;\n\n /**\n * Gets many values from the database. This returns a {@link ScanResult} which\n * implements `AsyncIterable`. It also has methods to iterate over the\n * {@link ScanResult.keys | keys} and {@link ScanResult.entries | entries}.\n *\n * If `options` has an `indexName`, then this does a scan over an index with\n * that name. A scan over an index uses a tuple for the key consisting of\n * `[secondary: string, primary: string]`.\n *\n * If the {@link ScanResult} is used after the `ReadTransaction` has been closed\n * it will throw a {@link TransactionClosedError}.\n *\n * Important: The returned JSON is readonly and should not be modified. This\n * is only enforced statically by TypeScript and there are no runtime checks\n * for performance reasons. If you mutate the return value you will get\n * undefined behavior.\n */\n scan(options: ScanIndexOptions): ScanResult<IndexKey, ReadonlyJSONValue>;\n scan(options?: ScanNoIndexOptions): ScanResult<string, ReadonlyJSONValue>;\n scan(options?: ScanOptions): ScanResult<IndexKey | string, ReadonlyJSONValue>;\n\n scan<V extends ReadonlyJSONValue>(\n options: ScanIndexOptions,\n ): ScanResult<IndexKey, DeepReadonly<V>>;\n scan<V extends ReadonlyJSONValue>(\n options?: ScanNoIndexOptions,\n ): ScanResult<string, DeepReadonly<V>>;\n scan<V extends ReadonlyJSONValue>(\n options?: ScanOptions,\n ): ScanResult<IndexKey | string, DeepReadonly<V>>;\n}\n\nlet transactionIDCounter = 0;\n\nexport class ReadTransactionImpl implements ReadTransaction {\n readonly clientID: ClientID;\n readonly dbtx: Read;\n protected readonly _lc: LogContext;\n\n /**\n * The location in which this transaction is being used. This is either `client` or `server`.\n */\n readonly location: TransactionLocation;\n /** @deprecated Use {@link ReadTransaction.location} instead. */\n readonly environment: TransactionLocation;\n\n constructor(\n clientID: ClientID,\n dbRead: Read,\n lc: LogContext,\n rpcName = 'openReadTransaction',\n ) {\n this.clientID = clientID;\n this.dbtx = dbRead;\n this._lc = lc\n .withContext(rpcName)\n .withContext('txid', transactionIDCounter++);\n this.environment = 'client';\n this.location = 'client';\n }\n\n get(key: string): Promise<ReadonlyJSONValue | undefined>;\n get<V extends JSONValue>(key: string): Promise<DeepReadonly<V> | undefined> {\n return (\n rejectIfClosed(this.dbtx) ||\n (this.dbtx.get(key) as Promise<DeepReadonly<V> | undefined>)\n );\n }\n\n // oxlint-disable-next-line require-await\n async has(key: string): Promise<boolean> {\n throwIfClosed(this.dbtx);\n return this.dbtx.has(key);\n }\n\n // oxlint-disable-next-line require-await\n async isEmpty(): Promise<boolean> {\n throwIfClosed(this.dbtx);\n return this.dbtx.isEmpty();\n }\n\n scan(options: ScanIndexOptions): ScanResult<IndexKey, ReadonlyJSONValue>;\n scan(options?: ScanNoIndexOptions): ScanResult<string, ReadonlyJSONValue>;\n scan(options?: ScanOptions): ScanResult<IndexKey | string, ReadonlyJSONValue>;\n\n scan<V extends ReadonlyJSONValue>(\n options: ScanIndexOptions,\n ): ScanResult<IndexKey, DeepReadonly<V>>;\n scan<V extends ReadonlyJSONValue>(\n options?: ScanNoIndexOptions,\n ): ScanResult<string, DeepReadonly<V>>;\n scan<V extends ReadonlyJSONValue>(\n options?: ScanOptions,\n ): ScanResult<IndexKey | string, DeepReadonly<V>>;\n\n scan(\n options?: ScanOptions,\n ): ScanResult<IndexKey | string, ReadonlyJSONValue> {\n return scan(options, this.dbtx, noop);\n }\n}\n\nfunction noop(_: unknown): void {\n // empty\n}\n\nfunction scan<Options extends ScanOptions, V extends JSONValue>(\n options: Options | undefined,\n dbRead: Read,\n onLimitKey: (inclusiveLimitKey: string) => void,\n): ScanResult<KeyTypeForScanOptions<Options>, V> {\n const iter = getScanIterator<Options, V>(dbRead, options);\n return makeScanResultFromScanIteratorInternal(\n iter,\n options ?? ({} as Options),\n dbRead,\n onLimitKey,\n );\n}\n\n// An implementation of ReadTransaction that keeps track of `keys` and `scans`\n// for use with Subscriptions.\nexport class SubscriptionTransactionWrapper implements ReadTransaction {\n readonly #keys: Set<string> = new Set();\n readonly #scans: ScanSubscriptionInfo[] = [];\n readonly #tx: ReadTransactionImpl;\n\n constructor(tx: ReadTransactionImpl) {\n this.#tx = tx;\n }\n\n get environment(): TransactionLocation {\n return this.#tx.location;\n }\n\n get location(): TransactionLocation {\n return this.#tx.location;\n }\n\n get clientID(): string {\n return this.#tx.clientID;\n }\n\n isEmpty(): Promise<boolean> {\n // Any change to the subscription requires rerunning it.\n this.#scans.push({options: {}});\n return this.#tx.isEmpty();\n }\n\n get(key: string): Promise<ReadonlyJSONValue | undefined>;\n get<T extends JSONValue>(key: string): Promise<DeepReadonly<T> | undefined> {\n this.#keys.add(key);\n return this.#tx.get(key) as Promise<DeepReadonly<T> | undefined>;\n }\n\n has(key: string): Promise<boolean> {\n this.#keys.add(key);\n return this.#tx.has(key);\n }\n\n scan(options: ScanIndexOptions): ScanResult<IndexKey, ReadonlyJSONValue>;\n scan(options?: ScanNoIndexOptions): ScanResult<string, ReadonlyJSONValue>;\n scan(options?: ScanOptions): ScanResult<IndexKey | string, ReadonlyJSONValue>;\n\n scan<V extends ReadonlyJSONValue>(\n options: ScanIndexOptions,\n ): ScanResult<IndexKey, DeepReadonly<V>>;\n scan<V extends ReadonlyJSONValue>(\n options?: ScanNoIndexOptions,\n ): ScanResult<string, DeepReadonly<V>>;\n scan<V extends ReadonlyJSONValue>(\n options?: ScanOptions,\n ): ScanResult<IndexKey | string, DeepReadonly<V>>;\n\n scan(\n options?: ScanOptions,\n ): ScanResult<IndexKey | string, ReadonlyJSONValue> {\n const scanInfo: ScanSubscriptionInfo = {\n options: toDbScanOptions(options),\n inclusiveLimitKey: undefined,\n };\n this.#scans.push(scanInfo);\n return scan(options, this.#tx.dbtx, inclusiveLimitKey => {\n scanInfo.inclusiveLimitKey = inclusiveLimitKey;\n });\n }\n\n get keys(): ReadonlySet<string> {\n return this.#keys;\n }\n\n get scans(): ScanSubscriptionInfo[] {\n return this.#scans;\n }\n}\n\n/**\n * WriteTransactions are used with *mutators* which are registered using\n * {@link ReplicacheOptions.mutators} and allows read and write operations on the\n * database.\n */\nexport interface WriteTransaction extends ReadTransaction {\n /**\n * The ID of the mutation that is being applied.\n */\n readonly mutationID: number;\n\n /**\n * The reason for the transaction. This can be `initial`, `rebase` or `authoriative`.\n */\n readonly reason: TransactionReason;\n\n /**\n * Sets a single `value` in the database. The value will be frozen (using\n * `Object.freeze`) in debug mode.\n */\n set(key: string, value: ReadonlyJSONValue): Promise<void>;\n\n /**\n * @deprecated Use {@link WriteTransaction.set} instead.\n */\n put(key: string, value: ReadonlyJSONValue): Promise<void>;\n\n /**\n * Removes a `key` and its value from the database. Returns `true` if there was a\n * `key` to remove.\n */\n del(key: string): Promise<boolean>;\n}\n\n// Internal symbol, not exported by Replicache\n// but accessible to Zero.\nexport const zeroData = Symbol();\n\nexport class WriteTransactionImpl\n extends ReadTransactionImpl\n implements WriteTransaction\n{\n // use `declare` to specialize the type.\n declare readonly dbtx: Write;\n readonly reason: TransactionReason;\n readonly mutationID: number;\n readonly [zeroData]: ZeroTxData | undefined;\n\n constructor(\n clientID: ClientID,\n mutationID: number,\n reason: TransactionReason,\n zData: ZeroTxData | undefined,\n dbWrite: Write,\n lc: LogContext,\n rpcName = 'openWriteTransaction',\n ) {\n super(clientID, dbWrite, lc, rpcName);\n this.mutationID = mutationID;\n this.reason = reason;\n this[zeroData] = zData;\n }\n\n put(key: string, value: ReadonlyJSONValue): Promise<void> {\n return this.set(key, value);\n }\n\n async set(key: string, value: ReadonlyJSONValue): Promise<void> {\n throwIfClosed(this.dbtx);\n await this.dbtx.put(this._lc, key, deepFreeze(value));\n }\n\n del(key: string): Promise<boolean> {\n return rejectIfClosed(this.dbtx) ?? this.dbtx.del(this._lc, key);\n }\n}\n\nexport type CreateIndexDefinition = IndexDefinition & {name: string};\n\ntype Entry<Key, Value> = readonly [key: Key, value: Value];\n\ntype IndexKeyEntry<Value> = Entry<IndexKey, Value>;\n\ntype StringKeyEntry<Value> = Entry<string, Value>;\n\nexport type EntryForOptions<\n Options extends ScanOptions,\n V,\n> = Options extends ScanIndexOptions ? IndexKeyEntry<V> : StringKeyEntry<V>;\n\nfunction getScanIterator<Options extends ScanOptions, V>(\n dbRead: Read,\n options: Options | undefined,\n): AsyncIterable<EntryForOptions<Options, V>> {\n if (options && isScanIndexOptions(options)) {\n return getScanIteratorForIndexMap(dbRead, options) as AsyncIterable<\n EntryForOptions<Options, V>\n >;\n }\n\n return dbRead.map.scan(fromKeyForNonIndexScan(options)) as AsyncIterable<\n EntryForOptions<Options, V>\n >;\n}\n\nexport function fromKeyForNonIndexScan(\n options: ScanNoIndexOptions | undefined,\n): string {\n if (!options) {\n return '';\n }\n\n const {prefix = '', start} = options;\n if (start && greaterThan(start.key, prefix)) {\n return start.key;\n }\n return prefix;\n}\n\nfunction makeScanResultFromScanIteratorInternal<\n Options extends ScanOptions,\n V extends JSONValue,\n>(\n iter: AsyncIterable<EntryForOptions<Options, V>>,\n options: Options,\n dbRead: Read,\n onLimitKey: (inclusiveLimitKey: string) => void,\n): ScanResult<KeyTypeForScanOptions<Options>, V> {\n return new ScanResultImpl(iter, options, dbRead, onLimitKey);\n}\n\nasync function* getScanIteratorForIndexMap(\n dbRead: Read,\n options: ScanIndexOptions,\n): AsyncIterable<IndexKeyEntry<ReadonlyJSONValue>> {\n if (process.env.DISABLE_REPLICACHE_INDEXES) {\n // Indexes are compiled out of this build so no index name ever exists.\n // Thrown here (inside the generator) so that the error surfaces on first\n // iteration, matching getMapForIndex — tx.scan() itself never throws.\n throw new Error(`Unknown index name: ${options.indexName}`);\n }\n const map = dbRead.getMapForIndex(options.indexName);\n for await (const entry of map.scan(fromKeyForIndexScanInternal(options))) {\n yield [decodeIndexKey(entry[0]), entry[1]];\n }\n}\n"],"mappings":"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"}
@@ -13,5 +13,19 @@ type PromiseRaceResult<T extends Record<string, PromiseLike<unknown>>> = {
13
13
  * @throws An error if the record is empty or if a promise is rejected.
14
14
  */
15
15
  export declare function promiseRace<T extends Record<string, PromiseLike<unknown>>>(promises: T): Promise<PromiseRaceResult<T> & {}>;
16
+ /**
17
+ * A memory-safe way to race a short-lived `Promise` with one or more
18
+ * long-leved `AbortSignal`s. This works around the unsafe practice
19
+ * of racing a short-lived promise (e.g. in a loop) with a long-lived one,
20
+ * which results in accumulating memory via `then` callbacks on the latter:
21
+ *
22
+ * https://github.com/nodejs/node/issues/17469
23
+ *
24
+ * The safe way to race a short-lived, expected-to-complete Promise against a
25
+ * long-lived termination signal is to control the latter via an
26
+ * {@link AbortController} and race the former against the signal of the
27
+ * latter.
28
+ */
29
+ export declare function promiseOrAbort<T>(shortLived: Promise<T>, ...longLived: AbortSignal[]): Promise<T>;
16
30
  export {};
17
31
  //# sourceMappingURL=promise-race.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"promise-race.d.ts","sourceRoot":"","sources":["../../../../shared/src/promise-race.ts"],"names":[],"mappings":"AAAA,KAAK,iBAAiB,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,CAAC,IAAI;KACtE,CAAC,IAAI,OAAO,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC,GAAG;QAC/B,GAAG,EAAE,CAAC,CAAC;QACP,MAAM,EAAE,WAAW,CAAC;QACpB,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;KACvB;CACF,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC;AAc5B;;;;;;GAMG;AACH,wBAAsB,WAAW,CAC/B,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,CAAC,EAC9C,QAAQ,EAAE,CAAC,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAYjD"}
1
+ {"version":3,"file":"promise-race.d.ts","sourceRoot":"","sources":["../../../../shared/src/promise-race.ts"],"names":[],"mappings":"AAEA,KAAK,iBAAiB,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,CAAC,IAAI;KACtE,CAAC,IAAI,OAAO,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC,GAAG;QAC/B,GAAG,EAAE,CAAC,CAAC;QACP,MAAM,EAAE,WAAW,CAAC;QACpB,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;KACvB;CACF,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC;AAc5B;;;;;;GAMG;AACH,wBAAsB,WAAW,CAC/B,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,CAAC,EAC9C,QAAQ,EAAE,CAAC,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAYjD;AAED;;;;;;;;;;;;GAYG;AACH,wBAAsB,cAAc,CAAC,CAAC,EACpC,UAAU,EAAE,OAAO,CAAC,CAAC,CAAC,EACtB,GAAG,SAAS,EAAE,WAAW,EAAE,GAC1B,OAAO,CAAC,CAAC,CAAC,CAoBZ"}
@@ -1,3 +1,4 @@
1
+ import { resolver } from "@rocicorp/resolver";
1
2
  //#region ../shared/src/promise-race.ts
2
3
  var NO_PROMISES_MESSAGE = "No promises to race";
3
4
  var wrapPromise = (key, promise) => Promise.resolve(promise).then((result) => ({
@@ -18,7 +19,37 @@ async function promiseRace(promises) {
18
19
  const wrapped = keys.map((key) => wrapPromise(key, promises[key]));
19
20
  return await Promise.race(wrapped);
20
21
  }
22
+ /**
23
+ * A memory-safe way to race a short-lived `Promise` with one or more
24
+ * long-leved `AbortSignal`s. This works around the unsafe practice
25
+ * of racing a short-lived promise (e.g. in a loop) with a long-lived one,
26
+ * which results in accumulating memory via `then` callbacks on the latter:
27
+ *
28
+ * https://github.com/nodejs/node/issues/17469
29
+ *
30
+ * The safe way to race a short-lived, expected-to-complete Promise against a
31
+ * long-lived termination signal is to control the latter via an
32
+ * {@link AbortController} and race the former against the signal of the
33
+ * latter.
34
+ */
35
+ async function promiseOrAbort(shortLived, ...longLived) {
36
+ const promises = [];
37
+ const cleanup = [];
38
+ for (const signal of longLived) if (signal.aborted) promises.push(Promise.reject(signal.reason));
39
+ else {
40
+ const { promise, reject } = resolver();
41
+ const handler = () => reject(signal.reason);
42
+ signal.addEventListener("abort", handler);
43
+ cleanup.push(() => signal.removeEventListener("abort", handler));
44
+ promises.push(promise);
45
+ }
46
+ try {
47
+ return await Promise.race([shortLived, ...promises]);
48
+ } finally {
49
+ cleanup.forEach((fn) => fn());
50
+ }
51
+ }
21
52
  //#endregion
22
- export { promiseRace };
53
+ export { promiseOrAbort, promiseRace };
23
54
 
24
55
  //# sourceMappingURL=promise-race.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"promise-race.js","names":[],"sources":["../../../../shared/src/promise-race.ts"],"sourcesContent":["type PromiseRaceResult<T extends Record<string, PromiseLike<unknown>>> = {\n [K in Extract<keyof T, string>]: {\n key: K;\n status: 'fulfilled';\n result: Awaited<T[K]>;\n };\n}[Extract<keyof T, string>];\n\nconst NO_PROMISES_MESSAGE = 'No promises to race';\n\nconst wrapPromise = <K extends string, V>(\n key: K,\n promise: PromiseLike<V>,\n): Promise<{key: K; status: 'fulfilled'; result: V}> =>\n Promise.resolve(promise).then(result => ({\n key,\n status: 'fulfilled' as const,\n result,\n }));\n\n/**\n * Race a record of promises and resolve with the first resolved entry.\n *\n * @param promises Record of promises to race.\n * @returns Promise resolving to a discriminated union of key/result pairs.\n * @throws An error if the record is empty or if a promise is rejected.\n */\nexport async function promiseRace<\n T extends Record<string, PromiseLike<unknown>>,\n>(promises: T): Promise<PromiseRaceResult<T> & {}> {\n const keys = Object.keys(promises) as Array<Extract<keyof T, string>>;\n\n if (keys.length === 0) {\n throw new Error(NO_PROMISES_MESSAGE);\n }\n\n const wrapped = keys.map(key =>\n wrapPromise(key, promises[key] as PromiseLike<Awaited<T[typeof key]>>),\n );\n\n return await Promise.race(wrapped);\n}\n"],"mappings":";AAQA,IAAM,sBAAsB;AAE5B,IAAM,eACJ,KACA,YAEA,QAAQ,QAAQ,OAAO,EAAE,MAAK,YAAW;CACvC;CACA,QAAQ;CACR;AACF,EAAE;;;;;;;;AASJ,eAAsB,YAEpB,UAAiD;CACjD,MAAM,OAAO,OAAO,KAAK,QAAQ;CAEjC,IAAI,KAAK,WAAW,GAClB,MAAM,IAAI,MAAM,mBAAmB;CAGrC,MAAM,UAAU,KAAK,KAAI,QACvB,YAAY,KAAK,SAAS,IAA2C,CACvE;CAEA,OAAO,MAAM,QAAQ,KAAK,OAAO;AACnC"}
1
+ {"version":3,"file":"promise-race.js","names":[],"sources":["../../../../shared/src/promise-race.ts"],"sourcesContent":["import {resolver} from '@rocicorp/resolver';\n\ntype PromiseRaceResult<T extends Record<string, PromiseLike<unknown>>> = {\n [K in Extract<keyof T, string>]: {\n key: K;\n status: 'fulfilled';\n result: Awaited<T[K]>;\n };\n}[Extract<keyof T, string>];\n\nconst NO_PROMISES_MESSAGE = 'No promises to race';\n\nconst wrapPromise = <K extends string, V>(\n key: K,\n promise: PromiseLike<V>,\n): Promise<{key: K; status: 'fulfilled'; result: V}> =>\n Promise.resolve(promise).then(result => ({\n key,\n status: 'fulfilled' as const,\n result,\n }));\n\n/**\n * Race a record of promises and resolve with the first resolved entry.\n *\n * @param promises Record of promises to race.\n * @returns Promise resolving to a discriminated union of key/result pairs.\n * @throws An error if the record is empty or if a promise is rejected.\n */\nexport async function promiseRace<\n T extends Record<string, PromiseLike<unknown>>,\n>(promises: T): Promise<PromiseRaceResult<T> & {}> {\n const keys = Object.keys(promises) as Array<Extract<keyof T, string>>;\n\n if (keys.length === 0) {\n throw new Error(NO_PROMISES_MESSAGE);\n }\n\n const wrapped = keys.map(key =>\n wrapPromise(key, promises[key] as PromiseLike<Awaited<T[typeof key]>>),\n );\n\n return await Promise.race(wrapped);\n}\n\n/**\n * A memory-safe way to race a short-lived `Promise` with one or more\n * long-leved `AbortSignal`s. This works around the unsafe practice\n * of racing a short-lived promise (e.g. in a loop) with a long-lived one,\n * which results in accumulating memory via `then` callbacks on the latter:\n *\n * https://github.com/nodejs/node/issues/17469\n *\n * The safe way to race a short-lived, expected-to-complete Promise against a\n * long-lived termination signal is to control the latter via an\n * {@link AbortController} and race the former against the signal of the\n * latter.\n */\nexport async function promiseOrAbort<T>(\n shortLived: Promise<T>,\n ...longLived: AbortSignal[]\n): Promise<T> {\n const promises: Promise<T>[] = [];\n const cleanup: (() => void)[] = [];\n for (const signal of longLived) {\n if (signal.aborted) {\n promises.push(Promise.reject(signal.reason));\n } else {\n const {promise, reject} = resolver<T>();\n const handler = () => reject(signal.reason);\n signal.addEventListener('abort', handler);\n cleanup.push(() => signal.removeEventListener('abort', handler));\n promises.push(promise);\n }\n }\n\n try {\n return await Promise.race([shortLived, ...promises]);\n } finally {\n cleanup.forEach(fn => fn());\n }\n}\n"],"mappings":";;AAUA,IAAM,sBAAsB;AAE5B,IAAM,eACJ,KACA,YAEA,QAAQ,QAAQ,OAAO,EAAE,MAAK,YAAW;CACvC;CACA,QAAQ;CACR;AACF,EAAE;;;;;;;;AASJ,eAAsB,YAEpB,UAAiD;CACjD,MAAM,OAAO,OAAO,KAAK,QAAQ;CAEjC,IAAI,KAAK,WAAW,GAClB,MAAM,IAAI,MAAM,mBAAmB;CAGrC,MAAM,UAAU,KAAK,KAAI,QACvB,YAAY,KAAK,SAAS,IAA2C,CACvE;CAEA,OAAO,MAAM,QAAQ,KAAK,OAAO;AACnC;;;;;;;;;;;;;;AAeA,eAAsB,eACpB,YACA,GAAG,WACS;CACZ,MAAM,WAAyB,CAAC;CAChC,MAAM,UAA0B,CAAC;CACjC,KAAK,MAAM,UAAU,WACnB,IAAI,OAAO,SACT,SAAS,KAAK,QAAQ,OAAO,OAAO,MAAM,CAAC;MACtC;EACL,MAAM,EAAC,SAAS,WAAU,SAAY;EACtC,MAAM,gBAAgB,OAAO,OAAO,MAAM;EAC1C,OAAO,iBAAiB,SAAS,OAAO;EACxC,QAAQ,WAAW,OAAO,oBAAoB,SAAS,OAAO,CAAC;EAC/D,SAAS,KAAK,OAAO;CACvB;CAGF,IAAI;EACF,OAAO,MAAM,QAAQ,KAAK,CAAC,YAAY,GAAG,QAAQ,CAAC;CACrD,UAAU;EACR,QAAQ,SAAQ,OAAM,GAAG,CAAC;CAC5B;AACF"}
@@ -1 +1 @@
1
- {"version":3,"file":"compiler.d.ts","sourceRoot":"","sources":["../../../../z2s/src/compiler.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"compiler.d.ts","sourceRoot":"","sources":["../../../../z2s/src/compiler.ts"],"names":[],"mappings":"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"}
@@ -125,9 +125,7 @@ function where(spec, condition, table) {
125
125
  switch (condition.type) {
126
126
  case "and": return sql`(${sql.join(condition.conditions.map((c) => where(spec, c, table)), " AND ")})`;
127
127
  case "or": return sql`(${sql.join(condition.conditions.map((c) => where(spec, c, table)), " OR ")})`;
128
- case "correlatedSubquery":
129
- if (condition.scalar) return scalarSubquery(spec, condition, table);
130
- return exists(spec, condition, table);
128
+ case "correlatedSubquery": return exists(spec, condition, table);
131
129
  case "simple": return simple(spec, condition, table);
132
130
  }
133
131
  }
@@ -143,25 +141,6 @@ function exists(spec, condition, parentTable) {
143
141
  })), condition.related.correlation.childField))})`;
144
142
  }
145
143
  }
146
- function scalarSubquery(spec, condition, parentTable) {
147
- const parentField = condition.related.correlation.parentField[0];
148
- const childField = condition.related.correlation.childField[0];
149
- const subqueryAST = condition.related.subquery;
150
- const parentCol = colIdent(spec.server, {
151
- table: parentTable,
152
- zql: parentField
153
- });
154
- const subqueryTable = makeTable(spec, subqueryAST.table);
155
- const childCol = colIdent(spec.server, {
156
- table: subqueryTable,
157
- zql: childField
158
- });
159
- const op = sql.__dangerous__rawValue(condition.op === "EXISTS" ? "=" : "IS NOT");
160
- const subqueryConditions = subqueryAST.where ? [where(spec, subqueryAST.where, subqueryTable)] : [];
161
- if (subqueryAST.start) subqueryConditions.push(start(spec, subqueryAST.start, subqueryAST.orderBy, subqueryTable));
162
- const subqueryOrderBy = orderBy(spec, subqueryAST.orderBy, subqueryTable);
163
- return sql`${parentCol} ${op} (SELECT ${childCol} FROM ${fromIdent(spec.server, subqueryTable)} ${subqueryConditions.length > 0 ? sql`WHERE ${sql.join(subqueryConditions, " AND ")}` : sql``} ${subqueryOrderBy} LIMIT 1)`;
164
- }
165
144
  function makeCorrelator(spec, parentFields, childZqlFields) {
166
145
  return (childTable) => {
167
146
  const childFields = childZqlFields.map((zqlField) => ({
@@ -1 +1 @@
1
- {"version":3,"file":"compiler.js","names":[],"sources":["../../../../z2s/src/compiler.ts"],"sourcesContent":["import type {SQLQuery} from '@databases/sql';\nimport {last, zip} from '../../shared/src/arrays.ts';\nimport {assert, unreachable} from '../../shared/src/asserts.ts';\nimport {\n parse as parseBigIntJson,\n type JSONValue as BigIntJSONValue,\n} from '../../shared/src/bigint-json.ts';\nimport {hasOwn} from '../../shared/src/has-own.ts';\nimport {type JSONValue} from '../../shared/src/json.ts';\nimport {must} from '../../shared/src/must.ts';\nimport type {\n AST,\n Bound,\n Condition,\n CorrelatedSubquery,\n CorrelatedSubqueryCondition,\n Correlation,\n LiteralReference,\n Ordering,\n SimpleCondition,\n ValuePosition,\n} from '../../zero-protocol/src/ast.ts';\nimport {\n clientToServer,\n type NameMapper,\n} from '../../zero-schema/src/name-mapper.ts';\nimport type {Schema} from '../../zero-types/src/schema.ts';\nimport type {ServerSchema} from '../../zero-types/src/server-schema.ts';\nimport type {Format} from '../../zql/src/ivm/view.ts';\nimport {completeOrdering} from '../../zql/src/query/complete-ordering.ts';\nimport {\n sql,\n sqlConvertColumnArg,\n sqlConvertPluralLiteralArg,\n sqlConvertSingularLiteralArg,\n type PluralLiteralType,\n} from './sql.ts';\n\ntype Table = {\n zql: string;\n alias: string;\n};\n\ntype QualifiedColumn = {\n table: Table;\n zql: string;\n};\n\ntype ServerSpec = {\n schema: ServerSchema;\n // maps zql names to server names\n mapper: NameMapper;\n};\n\nexport type Spec = {\n server: ServerSpec;\n zql: Schema['tables'];\n aliasCount: number;\n};\n\nconst ZQL_RESULT_KEY = 'zql_result';\nconst ZQL_RESULT_KEY_IDENT = sql.ident(ZQL_RESULT_KEY);\n\nconst ZQL_RESULT_TABLE_KEY = 'zql_root';\nconst ZQL_RESULT_TABLE_IDENT = sql.ident(ZQL_RESULT_TABLE_KEY);\n\nexport function compile(\n serverSchema: ServerSchema,\n zqlSchema: Schema,\n ast: AST,\n format?: Format,\n): SQLQuery {\n ast = completeOrdering(\n ast,\n tableName => zqlSchema.tables[tableName].primaryKey,\n );\n const spec: Spec = {\n aliasCount: 0,\n server: {\n schema: serverSchema,\n mapper: clientToServer(zqlSchema.tables),\n },\n zql: zqlSchema.tables,\n };\n return sql`SELECT \n ${toJSON(ZQL_RESULT_TABLE_KEY, format?.singular)}::text AS ${ZQL_RESULT_KEY_IDENT}\n FROM (${select(spec, ast, format)}) ${ZQL_RESULT_TABLE_IDENT}`;\n}\n\nfunction select(\n spec: Spec,\n ast: AST,\n format: Format | undefined,\n correlate?: (childTable: Table) => SQLQuery,\n): SQLQuery {\n const table = makeTable(spec, ast.table);\n const selectionSet = related(spec, ast.related ?? [], format, table);\n const tableSchema = spec.zql[ast.table];\n const usedAliases = new Set<string>(\n ast.related?.map(r => r.subquery.alias ?? ''),\n );\n for (const column of Object.keys(tableSchema.columns)) {\n if (!usedAliases.has(column)) {\n selectionSet.push(\n selectIdent(spec.server, {\n table,\n zql: column,\n }),\n );\n }\n }\n\n let appliedWhere = false;\n function maybeWhere(test: unknown) {\n if (!test) {\n return sql``;\n }\n\n const ret = appliedWhere ? sql`AND` : sql`WHERE`;\n appliedWhere = true;\n return ret;\n }\n\n return sql`SELECT ${sql.join(selectionSet, ',')}\n FROM ${fromIdent(spec.server, table)}\n ${maybeWhere(ast.where)} ${where(spec, ast.where, table)}${\n ast.start\n ? sql`\n ${maybeWhere(ast.start)} ${start(spec, ast.start, ast.orderBy, table)}`\n : sql``\n }\n ${maybeWhere(correlate)} ${correlate ? correlate(table) : sql``}\n ${orderBy(spec, ast.orderBy, table)}\n ${limit(ast.limit, format?.singular)}`;\n}\n\nexport function limit(\n limit: number | undefined,\n singular: boolean | undefined,\n): SQLQuery {\n if (limit === 0) {\n return sql`LIMIT 0`;\n }\n if (singular) {\n return sql`LIMIT 1`;\n }\n if (limit === undefined) {\n return sql``;\n }\n return sql`LIMIT ${sqlConvertSingularLiteralArg(limit)}`;\n}\n\nfunction makeTable(spec: Spec, zql: string, alias?: string): Table {\n alias = alias ?? zql + '_' + spec.aliasCount++;\n return {\n zql,\n alias,\n };\n}\n\nexport function orderBy(\n spec: Spec,\n orderBy: Ordering | undefined,\n table: Table,\n): SQLQuery {\n if (!orderBy) {\n return sql``;\n }\n return sql`ORDER BY ${sql.join(\n orderBy.map(([col, dir]) =>\n dir === 'asc'\n ? // Oh postgres. The table must be referred to by client name but the column by server name.\n // E.g., `SELECT server_col as client_col FROM server_table as client_table ORDER BY client_Table.server_col`\n sql`${colIdent(spec.server, {\n table,\n zql: col,\n })} ASC NULLS FIRST`\n : sql`${colIdent(spec.server, {\n table,\n zql: col,\n })} DESC NULLS LAST`,\n ),\n ', ',\n )}`;\n}\n\nexport function start(\n spec: Spec,\n bound: Bound | undefined,\n orderBy: Ordering | undefined,\n table: Table,\n): SQLQuery {\n if (!bound) {\n return sql``;\n }\n assert(\n orderBy !== undefined && orderBy.length > 0,\n 'start requires ordering',\n );\n\n const constraints: SQLQuery[] = [];\n for (let i = 0; i < orderBy.length; i++) {\n const group: SQLQuery[] = [];\n const [iField, iDirection] = orderBy[i];\n for (let j = 0; j <= i; j++) {\n const [field] = orderBy[j];\n if (j === i) {\n group.push(\n startRangeComparison(\n spec,\n table,\n iField,\n bound.row[iField] ?? null,\n iDirection === 'asc' ? '>' : '<',\n ),\n );\n } else {\n group.push(startEquality(spec, table, field, bound.row[field] ?? null));\n }\n }\n constraints.push(sql`(${sql.join(group, ' AND ')})`);\n }\n\n if (!bound.exclusive) {\n constraints.push(\n sql`(${sql.join(\n orderBy.map(([field]) =>\n startEquality(spec, table, field, bound.row[field] ?? null),\n ),\n ' AND ',\n )})`,\n );\n }\n\n return sql`(${sql.join(constraints, ' OR ')})`;\n}\n\nfunction related(\n spec: Spec,\n relationships: readonly CorrelatedSubquery[],\n format: Format | undefined,\n parentTable: Table,\n): SQLQuery[] {\n return relationships.map(relationship =>\n relationshipSubquery(\n spec,\n relationship,\n format?.relationships[must(relationship.subquery.alias)],\n parentTable,\n ),\n );\n}\n\nfunction relationshipSubquery(\n spec: Spec,\n relationship: CorrelatedSubquery,\n format: Format | undefined,\n parentTable: Table,\n): SQLQuery {\n const innerAlias = `inner_${relationship.subquery.alias}`;\n if (relationship.hidden) {\n const {join, participatingTables} = makeJunctionJoin(spec, relationship);\n const lastTable = must(last(participatingTables)).table;\n\n assert(\n relationship.subquery.related,\n 'hidden relationship must be a junction',\n );\n const nestedAst = relationship.subquery.related[0].subquery;\n const selectionSet = related(\n spec,\n nestedAst.related ?? [],\n format,\n lastTable,\n );\n const tableSchema = spec.zql[nestedAst.table];\n for (const column of Object.keys(tableSchema.columns)) {\n selectionSet.push(\n selectIdent(spec.server, {\n table: lastTable,\n zql: column,\n }),\n );\n }\n\n return sql`(\n SELECT ${toJSON(innerAlias, format?.singular)} FROM (SELECT ${sql.join(\n selectionSet,\n ',',\n )} FROM ${join} WHERE (${makeCorrelator(\n spec,\n relationship.correlation.parentField.map(f => ({\n table: parentTable,\n zql: f,\n })),\n relationship.correlation.childField,\n )(participatingTables[0].table)}) ${\n nestedAst.where\n ? sql`AND ${where(spec, nestedAst.where, lastTable)}`\n : sql``\n }${\n nestedAst.start\n ? sql` AND ${start(\n spec,\n nestedAst.start,\n nestedAst.orderBy,\n lastTable,\n )}`\n : sql``\n } ${orderBy(spec, nestedAst.orderBy, lastTable)} ${limit(\n last(participatingTables)?.limit,\n format?.singular,\n )} ) ${sql.ident(innerAlias)}\n ) as ${sql.ident(relationship.subquery.alias)}`;\n }\n\n return sql`(\n SELECT ${toJSON(innerAlias, format?.singular)} FROM (${select(\n spec,\n relationship.subquery,\n format,\n makeCorrelator(\n spec,\n relationship.correlation.parentField.map(f => ({\n table: parentTable,\n zql: f,\n })),\n relationship.correlation.childField,\n ),\n )}) ${sql.ident(innerAlias)}\n ) as ${sql.ident(relationship.subquery.alias)}`;\n}\n\nfunction where(\n spec: Spec,\n condition: Condition | undefined,\n table: Table,\n): SQLQuery {\n if (!condition) {\n return sql``;\n }\n\n switch (condition.type) {\n case 'and':\n return sql`(${sql.join(\n condition.conditions.map(c => where(spec, c, table)),\n ' AND ',\n )})`;\n case 'or':\n return sql`(${sql.join(\n condition.conditions.map(c => where(spec, c, table)),\n ' OR ',\n )})`;\n case 'correlatedSubquery':\n if (condition.scalar) {\n return scalarSubquery(spec, condition, table);\n }\n return exists(spec, condition, table);\n case 'simple':\n return simple(spec, condition, table);\n }\n}\n\nfunction exists(\n spec: Spec,\n condition: CorrelatedSubqueryCondition,\n parentTable: Table,\n): SQLQuery {\n switch (condition.op) {\n case 'EXISTS':\n return sql`EXISTS (${select(\n spec,\n condition.related.subquery,\n undefined,\n makeCorrelator(\n spec,\n condition.related.correlation.parentField.map(f => ({\n table: parentTable,\n zql: f,\n })),\n condition.related.correlation.childField,\n ),\n )})`;\n case 'NOT EXISTS':\n return sql`NOT EXISTS (${select(\n spec,\n condition.related.subquery,\n undefined,\n makeCorrelator(\n spec,\n condition.related.correlation.parentField.map(f => ({\n table: parentTable,\n zql: f,\n })),\n condition.related.correlation.childField,\n ),\n )})`;\n }\n}\n\nfunction scalarSubquery(\n spec: Spec,\n condition: CorrelatedSubqueryCondition,\n parentTable: Table,\n): SQLQuery {\n const parentField = condition.related.correlation.parentField[0];\n const childField = condition.related.correlation.childField[0];\n const subqueryAST = condition.related.subquery;\n\n const parentCol = colIdent(spec.server, {\n table: parentTable,\n zql: parentField,\n });\n\n const subqueryTable = makeTable(spec, subqueryAST.table);\n const childCol = colIdent(spec.server, {\n table: subqueryTable,\n zql: childField,\n });\n\n const op = sql.__dangerous__rawValue(\n condition.op === 'EXISTS' ? '=' : 'IS NOT',\n );\n\n const subqueryConditions = subqueryAST.where\n ? [where(spec, subqueryAST.where, subqueryTable)]\n : [];\n if (subqueryAST.start) {\n subqueryConditions.push(\n start(spec, subqueryAST.start, subqueryAST.orderBy, subqueryTable),\n );\n }\n const subqueryOrderBy = orderBy(spec, subqueryAST.orderBy, subqueryTable);\n\n return sql`${parentCol} ${op} (SELECT ${childCol} FROM ${fromIdent(spec.server, subqueryTable)} ${\n subqueryConditions.length > 0\n ? sql`WHERE ${sql.join(subqueryConditions, ' AND ')}`\n : sql``\n } ${subqueryOrderBy} LIMIT 1)`;\n}\n\nexport function makeCorrelator(\n spec: Spec,\n parentFields: readonly QualifiedColumn[],\n childZqlFields: readonly string[],\n): (childTable: Table) => SQLQuery {\n return (childTable: Table) => {\n const childFields = childZqlFields.map(zqlField => ({\n table: childTable,\n zql: zqlField,\n }));\n return sql.join(\n zip(parentFields, childFields).map(\n ([parentColumn, childColumn]) =>\n sql`${colIdent(spec.server, parentColumn)} = ${colIdent(\n spec.server,\n childColumn,\n )}`,\n ),\n ' AND ',\n );\n };\n}\n\nexport function simple(\n spec: Spec,\n condition: SimpleCondition,\n table: Table,\n): SQLQuery {\n switch (condition.op) {\n case '!=':\n case '<':\n case '<=':\n case '=':\n case '>':\n case '>=':\n case 'ILIKE':\n case 'LIKE':\n case 'NOT ILIKE':\n case 'NOT LIKE':\n return sql`${valueComparison(\n spec,\n condition.left,\n table,\n condition.right,\n false,\n )} ${sql.__dangerous__rawValue(condition.op)} ${valueComparison(\n spec,\n condition.right,\n table,\n condition.left,\n false,\n )}`;\n case 'NOT IN':\n case 'IN':\n return any(spec, condition, table);\n case 'IS':\n case 'IS NOT':\n return distinctFrom(spec, condition, table);\n }\n}\n\nexport function any(\n spec: Spec,\n condition: SimpleCondition,\n table: Table,\n): SQLQuery {\n return sql`${condition.op === 'NOT IN' ? sql`NOT` : sql``}\n (\n ${valueComparison(spec, condition.left, table, condition.right, false)} = ANY \n (${valueComparison(spec, condition.right, table, condition.left, true)})\n )`;\n}\n\nexport function distinctFrom(\n spec: Spec,\n condition: SimpleCondition,\n table: Table,\n): SQLQuery {\n return sql`${valueComparison(spec, condition.left, table, condition.right, false)} ${\n condition.op === 'IS' ? sql`IS NOT DISTINCT FROM` : sql`IS DISTINCT FROM`\n } ${valueComparison(spec, condition.right, table, condition.left, false)}`;\n}\n\nfunction startEquality(\n spec: Spec,\n table: Table,\n field: string,\n value: unknown,\n): SQLQuery {\n return sql`${colIdent(spec.server, {\n table,\n zql: field,\n })} IS NOT DISTINCT FROM ${startValue(spec, table, field, value)}`;\n}\n\nfunction startRangeComparison(\n spec: Spec,\n table: Table,\n field: string,\n value: unknown,\n operator: '>' | '<',\n): SQLQuery {\n const column = colIdent(spec.server, {table, zql: field});\n if (value === null) {\n return operator === '>' ? sql`${column} IS NOT NULL` : sql`FALSE`;\n }\n const typedValue = startValue(spec, table, field, value);\n return operator === '>'\n ? sql`${column} > ${typedValue}`\n : sql`(${column} IS NULL OR ${column} < ${typedValue})`;\n}\n\nfunction startValue(\n spec: Spec,\n table: Table,\n field: string,\n value: unknown,\n): SQLQuery {\n return sqlConvertColumnArg(\n getServerColumn(spec.server, table, field),\n value,\n false,\n true,\n );\n}\n\nfunction valueComparison(\n spec: Spec,\n valuePos: ValuePosition,\n table: Table,\n otherValuePos: ValuePosition,\n plural: boolean,\n): SQLQuery {\n const valuePosType = valuePos.type;\n switch (valuePosType) {\n case 'column': {\n const qualified: QualifiedColumn = {\n table,\n zql: valuePos.name,\n };\n return colIdent(spec.server, qualified);\n }\n case 'literal':\n return literalValueComparison(\n spec,\n valuePos,\n table,\n otherValuePos,\n plural,\n );\n case 'static':\n throw new Error(\n 'Static parameters must be bound to a value before compiling to SQL',\n );\n default:\n unreachable(valuePosType);\n break;\n }\n}\n\nfunction literalValueComparison(\n spec: Spec,\n valuePos: LiteralReference,\n table: Table,\n otherValuePos: ValuePosition,\n plural: boolean,\n): SQLQuery {\n const otherType = otherValuePos.type;\n switch (otherType) {\n case 'column':\n return sqlConvertColumnArg(\n getServerColumn(spec.server, table, otherValuePos.name),\n valuePos.value,\n plural,\n true,\n );\n case 'literal': {\n assert(\n plural === Array.isArray(valuePos.value),\n 'Expected plural flag to match whether value is an array',\n );\n if (Array.isArray(valuePos.value)) {\n if (valuePos.value.length > 0) {\n // If the array is non-empty base its type on its first\n // element\n return sqlConvertPluralLiteralArg(\n typeof valuePos.value[0] as PluralLiteralType,\n valuePos.value as PluralLiteralType[],\n );\n }\n // If the array is empty, base its type on the other value\n // position's type (as long as the other value position is non-null,\n // cannot have a null[]).\n if (otherValuePos.value !== null) {\n return sqlConvertPluralLiteralArg(\n typeof otherValuePos.value as PluralLiteralType,\n [],\n );\n }\n // If the other value position is null, it can be compared to any\n // type of empty array, chose 'string' arbitrarily.\n return sqlConvertPluralLiteralArg('string', []);\n }\n if (\n typeof valuePos.value === 'string' ||\n typeof valuePos.value === 'number' ||\n typeof valuePos.value === 'boolean'\n ) {\n return sqlConvertSingularLiteralArg(valuePos.value);\n }\n throw new Error(\n `Literal of unexpected type. ${valuePos.value} of type ${typeof valuePos.value}`,\n );\n }\n case 'static':\n throw new Error(\n 'Static parameters must be bound to a value before compiling to SQL',\n );\n default:\n unreachable(otherType);\n }\n}\n\nexport function makeJunctionJoin(\n spec: Spec,\n relationship: CorrelatedSubquery,\n): {\n join: SQLQuery;\n participatingTables: ReturnType<typeof pullTablesForJunction>;\n} {\n const participatingTables = pullTablesForJunction(spec, relationship);\n const joins: SQLQuery[] = [];\n\n for (const {table} of participatingTables) {\n if (joins.length === 0) {\n joins.push(fromIdent(spec.server, table));\n continue;\n }\n joins.push(\n sql` JOIN ${fromIdent(spec.server, table)} ON ${makeCorrelator(\n spec,\n participatingTables[joins.length].correlation.parentField.map(f => ({\n table: participatingTables[joins.length - 1].table,\n zql: f,\n })),\n participatingTables[joins.length].correlation.childField,\n )(participatingTables[joins.length].table)}`,\n );\n }\n\n return {\n join: sql`${sql.join(joins, '')}`,\n participatingTables,\n // lastTable: participatingTables[participatingTables.length - 1].table,\n // lastLimit: participatingTables[participatingTables.length - 1].limit,\n };\n}\n\nexport function pullTablesForJunction(\n spec: Spec,\n relationship: CorrelatedSubquery,\n): [\n {\n table: Table;\n correlation: Correlation;\n limit: number | undefined;\n },\n {table: Table; correlation: Correlation; limit: number | undefined},\n] {\n assert(\n relationship.subquery.related?.length === 1,\n 'Too many related tables for a junction edge',\n );\n const otherRelationship = relationship.subquery.related[0];\n assert(\n !otherRelationship.hidden,\n 'Expected junction edge relationship to not be hidden',\n );\n return [\n {\n table: makeTable(spec, relationship.subquery.table),\n correlation: relationship.correlation,\n limit: relationship.subquery.limit,\n },\n {\n table: makeTable(spec, otherRelationship.subquery.table),\n correlation: otherRelationship.correlation,\n limit: otherRelationship.subquery.limit,\n },\n ];\n}\n\nfunction toJSON(table: string, singular = false): SQLQuery {\n return sql`${\n singular ? sql`` : sql`COALESCE(json_agg`\n }(row_to_json(${sql.ident(table)}))${singular ? sql`` : sql`, '[]'::json)`}`;\n}\n\nfunction selectIdent(server: ServerSpec, column: QualifiedColumn): SQLQuery {\n const serverColumnSchema =\n server.schema[server.mapper.tableName(column.table.zql)][\n server.mapper.columnName(column.table.zql, column.zql)\n ];\n const serverType = serverColumnSchema.type;\n if (!serverColumnSchema.isEnum) {\n let needsNormalization = false;\n switch (serverType) {\n case 'timestamptz':\n // @ts-expect-error Fallthrough intended\n case 'timetz':\n needsNormalization = true;\n // fallthrough\n\n case 'date':\n case 'time':\n case 'time without time zone':\n case 'time with time zone':\n case 'timestamp':\n case 'timestamp without time zone':\n case 'timestamp with time zone': {\n // EXTRACT(EPOCH FROM timetz) can be negative when the UTC offset is\n // positive (e.g. 01:00+02 = 23:00 UTC prev day = -3600s). Wrap with\n // modular arithmetic to normalize to 0..86400000.\n const toMs = (epochExpr: SQLQuery): SQLQuery =>\n needsNormalization\n ? sql`((${epochExpr})::bigint + 86400000) % 86400000`\n : epochExpr;\n\n if (serverColumnSchema.isArray) {\n const col = colIdent(server, column);\n return sql`CASE WHEN ${col} IS NULL THEN NULL ELSE ARRAY(SELECT ${toMs(\n sql`EXTRACT(EPOCH FROM unnest(${col})) * 1000`,\n )}) END as ${sql.ident(column.zql)}`;\n }\n\n return sql`${toMs(\n sql`EXTRACT(EPOCH FROM ${colIdent(server, column)}) * 1000`,\n )} as ${sql.ident(column.zql)}`;\n }\n }\n }\n\n return sql`${colIdent(server, column)} as ${sql.ident(column.zql)}`;\n}\n\nfunction colIdent(server: ServerSpec, column: QualifiedColumn) {\n return sql.ident(\n column.table.alias,\n server.mapper.columnName(column.table.zql, column.zql),\n );\n}\n\nfunction fromIdent(server: ServerSpec, table: Table) {\n return sql`${sql.ident(server.mapper.tableName(table.zql))} AS ${sql.ident(table.alias)}`;\n}\n\nfunction getServerColumn(spec: ServerSpec, table: Table, zqlColumn: string) {\n return spec.schema[spec.mapper.tableName(table.zql)][\n spec.mapper.columnName(table.zql, zqlColumn)\n ];\n}\n\n// oxlint-disable-next-line @typescript-eslint/no-explicit-any\nexport function extractZqlResult(pgResult: Array<any>): JSONValue {\n const bigIntJson: BigIntJSONValue = parseBigIntJson(\n pgResult[0][ZQL_RESULT_KEY],\n );\n assertJSONValue(bigIntJson);\n return bigIntJson;\n}\n\nfunction assertJSONValue(v: BigIntJSONValue): asserts v is JSONValue {\n const path = findPathToBigInt(v);\n if (path) {\n throw new Error(`Value exceeds safe Number range. ${path}`);\n }\n}\n\nfunction findPathToBigInt(v: BigIntJSONValue): string | undefined {\n const typeOfV = typeof v;\n switch (typeOfV) {\n case 'bigint':\n return ` = ${v}`;\n case 'object': {\n if (v === null) {\n return;\n }\n if (Array.isArray(v)) {\n for (let i = 0; i < v.length; i++) {\n const path = findPathToBigInt(v[i]);\n if (path) {\n return `[${i}]${path}`;\n }\n }\n return undefined;\n }\n\n const o = v as Record<string, BigIntJSONValue>;\n for (const k in o) {\n if (hasOwn(o, k)) {\n const path = findPathToBigInt(o[k]);\n if (path) {\n return `['${k}']${path}`;\n }\n }\n }\n return undefined;\n }\n case 'number':\n return undefined;\n case 'boolean':\n return undefined;\n default:\n return undefined;\n }\n}\n"],"mappings":";;;;;;;;;;AA4DA,IAAM,iBAAiB;AACvB,IAAM,uBAAuB,IAAI,MAAM,cAAc;AAErD,IAAM,uBAAuB;AAC7B,IAAM,yBAAyB,IAAI,MAAM,oBAAoB;AAE7D,SAAgB,QACd,cACA,WACA,KACA,QACU;CACV,MAAM,iBACJ,MACA,cAAa,UAAU,OAAO,WAAW,UAC3C;CACA,MAAM,OAAa;EACjB,YAAY;EACZ,QAAQ;GACN,QAAQ;GACR,QAAQ,eAAe,UAAU,MAAM;EACzC;EACA,KAAK,UAAU;CACjB;CACA,OAAO,GAAG;MACN,OAAO,sBAAsB,QAAQ,QAAQ,EAAE,YAAY,qBAAqB;YAC1E,OAAO,MAAM,KAAK,MAAM,EAAE,IAAI;AAC1C;AAEA,SAAS,OACP,MACA,KACA,QACA,WACU;CACV,MAAM,QAAQ,UAAU,MAAM,IAAI,KAAK;CACvC,MAAM,eAAe,QAAQ,MAAM,IAAI,WAAW,CAAC,GAAG,QAAQ,KAAK;CACnE,MAAM,cAAc,KAAK,IAAI,IAAI;CACjC,MAAM,cAAc,IAAI,IACtB,IAAI,SAAS,KAAI,MAAK,EAAE,SAAS,SAAS,EAAE,CAC9C;CACA,KAAK,MAAM,UAAU,OAAO,KAAK,YAAY,OAAO,GAClD,IAAI,CAAC,YAAY,IAAI,MAAM,GACzB,aAAa,KACX,YAAY,KAAK,QAAQ;EACvB;EACA,KAAK;CACP,CAAC,CACH;CAIJ,IAAI,eAAe;CACnB,SAAS,WAAW,MAAe;EACjC,IAAI,CAAC,MACH,OAAO,GAAG;EAGZ,MAAM,MAAM,eAAe,GAAG,QAAQ,GAAG;EACzC,eAAe;EACf,OAAO;CACT;CAEA,OAAO,GAAG,UAAU,IAAI,KAAK,cAAc,GAAG,EAAE;WACvC,UAAU,KAAK,QAAQ,KAAK,EAAE;MACnC,WAAW,IAAI,KAAK,EAAE,GAAG,MAAM,MAAM,IAAI,OAAO,KAAK,IACrD,IAAI,QACA,GAAG;MACP,WAAW,IAAI,KAAK,EAAE,GAAG,MAAM,MAAM,IAAI,OAAO,IAAI,SAAS,KAAK,MAC9D,GAAG,GACR;MACC,WAAW,SAAS,EAAE,GAAG,YAAY,UAAU,KAAK,IAAI,GAAG,GAAG;MAC9D,QAAQ,MAAM,IAAI,SAAS,KAAK,EAAE;MAClC,MAAM,IAAI,OAAO,QAAQ,QAAQ;AACvC;AAEA,SAAgB,MACd,OACA,UACU;CACV,IAAI,UAAU,GACZ,OAAO,GAAG;CAEZ,IAAI,UACF,OAAO,GAAG;CAEZ,IAAI,UAAU,KAAA,GACZ,OAAO,GAAG;CAEZ,OAAO,GAAG,SAAS,6BAA6B,KAAK;AACvD;AAEA,SAAS,UAAU,MAAY,KAAa,OAAuB;CACjE,QAAQ,SAAS,MAAM,MAAM,KAAK;CAClC,OAAO;EACL;EACA;CACF;AACF;AAEA,SAAgB,QACd,MACA,SACA,OACU;CACV,IAAI,CAAC,SACH,OAAO,GAAG;CAEZ,OAAO,GAAG,YAAY,IAAI,KACxB,QAAQ,KAAK,CAAC,KAAK,SACjB,QAAQ,QAGJ,GAAG,GAAG,SAAS,KAAK,QAAQ;EAC1B;EACA,KAAK;CACP,CAAC,EAAE,oBACH,GAAG,GAAG,SAAS,KAAK,QAAQ;EAC1B;EACA,KAAK;CACP,CAAC,EAAE,iBACT,GACA,IACF;AACF;AAEA,SAAgB,MACd,MACA,OACA,SACA,OACU;CACV,IAAI,CAAC,OACH,OAAO,GAAG;CAEZ,OACE,YAAY,KAAA,KAAa,QAAQ,SAAS,GAC1C,yBACF;CAEA,MAAM,cAA0B,CAAC;CACjC,KAAK,IAAI,IAAI,GAAG,IAAI,QAAQ,QAAQ,KAAK;EACvC,MAAM,QAAoB,CAAC;EAC3B,MAAM,CAAC,QAAQ,cAAc,QAAQ;EACrC,KAAK,IAAI,IAAI,GAAG,KAAK,GAAG,KAAK;GAC3B,MAAM,CAAC,SAAS,QAAQ;GACxB,IAAI,MAAM,GACR,MAAM,KACJ,qBACE,MACA,OACA,QACA,MAAM,IAAI,WAAW,MACrB,eAAe,QAAQ,MAAM,GAC/B,CACF;QAEA,MAAM,KAAK,cAAc,MAAM,OAAO,OAAO,MAAM,IAAI,UAAU,IAAI,CAAC;EAE1E;EACA,YAAY,KAAK,GAAG,IAAI,IAAI,KAAK,OAAO,OAAO,EAAE,EAAE;CACrD;CAEA,IAAI,CAAC,MAAM,WACT,YAAY,KACV,GAAG,IAAI,IAAI,KACT,QAAQ,KAAK,CAAC,WACZ,cAAc,MAAM,OAAO,OAAO,MAAM,IAAI,UAAU,IAAI,CAC5D,GACA,OACF,EAAE,EACJ;CAGF,OAAO,GAAG,IAAI,IAAI,KAAK,aAAa,MAAM,EAAE;AAC9C;AAEA,SAAS,QACP,MACA,eACA,QACA,aACY;CACZ,OAAO,cAAc,KAAI,iBACvB,qBACE,MACA,cACA,QAAQ,cAAc,KAAK,aAAa,SAAS,KAAK,IACtD,WACF,CACF;AACF;AAEA,SAAS,qBACP,MACA,cACA,QACA,aACU;CACV,MAAM,aAAa,SAAS,aAAa,SAAS;CAClD,IAAI,aAAa,QAAQ;EACvB,MAAM,EAAC,MAAM,wBAAuB,iBAAiB,MAAM,YAAY;EACvE,MAAM,YAAY,KAAK,KAAK,mBAAmB,CAAC,EAAE;EAElD,OACE,aAAa,SAAS,SACtB,wCACF;EACA,MAAM,YAAY,aAAa,SAAS,QAAQ,GAAG;EACnD,MAAM,eAAe,QACnB,MACA,UAAU,WAAW,CAAC,GACtB,QACA,SACF;EACA,MAAM,cAAc,KAAK,IAAI,UAAU;EACvC,KAAK,MAAM,UAAU,OAAO,KAAK,YAAY,OAAO,GAClD,aAAa,KACX,YAAY,KAAK,QAAQ;GACvB,OAAO;GACP,KAAK;EACP,CAAC,CACH;EAGF,OAAO,GAAG;iBACG,OAAO,YAAY,QAAQ,QAAQ,EAAE,gBAAgB,IAAI,KAChE,cACA,GACF,EAAE,QAAQ,KAAK,UAAU,eACvB,MACA,aAAa,YAAY,YAAY,KAAI,OAAM;GAC7C,OAAO;GACP,KAAK;EACP,EAAE,GACF,aAAa,YAAY,UAC3B,EAAE,oBAAoB,GAAG,KAAK,EAAE,IAC9B,UAAU,QACN,GAAG,OAAO,MAAM,MAAM,UAAU,OAAO,SAAS,MAChD,GAAG,KAEP,UAAU,QACN,GAAG,QAAQ,MACT,MACA,UAAU,OACV,UAAU,SACV,SACF,MACA,GAAG,GACR,GAAG,QAAQ,MAAM,UAAU,SAAS,SAAS,EAAE,GAAG,MACjD,KAAK,mBAAmB,GAAG,OAC3B,QAAQ,QACV,EAAE,KAAK,IAAI,MAAM,UAAU,EAAE;aACxB,IAAI,MAAM,aAAa,SAAS,KAAK;CAChD;CAEA,OAAO,GAAG;eACG,OAAO,YAAY,QAAQ,QAAQ,EAAE,SAAS,OACrD,MACA,aAAa,UACb,QACA,eACE,MACA,aAAa,YAAY,YAAY,KAAI,OAAM;EAC7C,OAAO;EACP,KAAK;CACP,EAAE,GACF,aAAa,YAAY,UAC3B,CACF,EAAE,IAAI,IAAI,MAAM,UAAU,EAAE;WACvB,IAAI,MAAM,aAAa,SAAS,KAAK;AAChD;AAEA,SAAS,MACP,MACA,WACA,OACU;CACV,IAAI,CAAC,WACH,OAAO,GAAG;CAGZ,QAAQ,UAAU,MAAlB;EACE,KAAK,OACH,OAAO,GAAG,IAAI,IAAI,KAChB,UAAU,WAAW,KAAI,MAAK,MAAM,MAAM,GAAG,KAAK,CAAC,GACnD,OACF,EAAE;EACJ,KAAK,MACH,OAAO,GAAG,IAAI,IAAI,KAChB,UAAU,WAAW,KAAI,MAAK,MAAM,MAAM,GAAG,KAAK,CAAC,GACnD,MACF,EAAE;EACJ,KAAK;GACH,IAAI,UAAU,QACZ,OAAO,eAAe,MAAM,WAAW,KAAK;GAE9C,OAAO,OAAO,MAAM,WAAW,KAAK;EACtC,KAAK,UACH,OAAO,OAAO,MAAM,WAAW,KAAK;CACxC;AACF;AAEA,SAAS,OACP,MACA,WACA,aACU;CACV,QAAQ,UAAU,IAAlB;EACE,KAAK,UACH,OAAO,GAAG,WAAW,OACnB,MACA,UAAU,QAAQ,UAClB,KAAA,GACA,eACE,MACA,UAAU,QAAQ,YAAY,YAAY,KAAI,OAAM;GAClD,OAAO;GACP,KAAK;EACP,EAAE,GACF,UAAU,QAAQ,YAAY,UAChC,CACF,EAAE;EACJ,KAAK,cACH,OAAO,GAAG,eAAe,OACvB,MACA,UAAU,QAAQ,UAClB,KAAA,GACA,eACE,MACA,UAAU,QAAQ,YAAY,YAAY,KAAI,OAAM;GAClD,OAAO;GACP,KAAK;EACP,EAAE,GACF,UAAU,QAAQ,YAAY,UAChC,CACF,EAAE;CACN;AACF;AAEA,SAAS,eACP,MACA,WACA,aACU;CACV,MAAM,cAAc,UAAU,QAAQ,YAAY,YAAY;CAC9D,MAAM,aAAa,UAAU,QAAQ,YAAY,WAAW;CAC5D,MAAM,cAAc,UAAU,QAAQ;CAEtC,MAAM,YAAY,SAAS,KAAK,QAAQ;EACtC,OAAO;EACP,KAAK;CACP,CAAC;CAED,MAAM,gBAAgB,UAAU,MAAM,YAAY,KAAK;CACvD,MAAM,WAAW,SAAS,KAAK,QAAQ;EACrC,OAAO;EACP,KAAK;CACP,CAAC;CAED,MAAM,KAAK,IAAI,sBACb,UAAU,OAAO,WAAW,MAAM,QACpC;CAEA,MAAM,qBAAqB,YAAY,QACnC,CAAC,MAAM,MAAM,YAAY,OAAO,aAAa,CAAC,IAC9C,CAAC;CACL,IAAI,YAAY,OACd,mBAAmB,KACjB,MAAM,MAAM,YAAY,OAAO,YAAY,SAAS,aAAa,CACnE;CAEF,MAAM,kBAAkB,QAAQ,MAAM,YAAY,SAAS,aAAa;CAExE,OAAO,GAAG,GAAG,UAAU,GAAG,GAAG,WAAW,SAAS,QAAQ,UAAU,KAAK,QAAQ,aAAa,EAAE,GAC7F,mBAAmB,SAAS,IACxB,GAAG,SAAS,IAAI,KAAK,oBAAoB,OAAO,MAChD,GAAG,GACR,GAAG,gBAAgB;AACtB;AAEA,SAAgB,eACd,MACA,cACA,gBACiC;CACjC,QAAQ,eAAsB;EAC5B,MAAM,cAAc,eAAe,KAAI,cAAa;GAClD,OAAO;GACP,KAAK;EACP,EAAE;EACF,OAAO,IAAI,KACT,IAAI,cAAc,WAAW,EAAE,KAC5B,CAAC,cAAc,iBACd,GAAG,GAAG,SAAS,KAAK,QAAQ,YAAY,EAAE,KAAK,SAC7C,KAAK,QACL,WACF,GACJ,GACA,OACF;CACF;AACF;AAEA,SAAgB,OACd,MACA,WACA,OACU;CACV,QAAQ,UAAU,IAAlB;EACE,KAAK;EACL,KAAK;EACL,KAAK;EACL,KAAK;EACL,KAAK;EACL,KAAK;EACL,KAAK;EACL,KAAK;EACL,KAAK;EACL,KAAK,YACH,OAAO,GAAG,GAAG,gBACX,MACA,UAAU,MACV,OACA,UAAU,OACV,KACF,EAAE,GAAG,IAAI,sBAAsB,UAAU,EAAE,EAAE,GAAG,gBAC9C,MACA,UAAU,OACV,OACA,UAAU,MACV,KACF;EACF,KAAK;EACL,KAAK,MACH,OAAO,IAAI,MAAM,WAAW,KAAK;EACnC,KAAK;EACL,KAAK,UACH,OAAO,aAAa,MAAM,WAAW,KAAK;CAC9C;AACF;AAEA,SAAgB,IACd,MACA,WACA,OACU;CACV,OAAO,GAAG,GAAG,UAAU,OAAO,WAAW,GAAG,QAAQ,GAAG,GAAG;;QAEpD,gBAAgB,MAAM,UAAU,MAAM,OAAO,UAAU,OAAO,KAAK,EAAE;SACpE,gBAAgB,MAAM,UAAU,OAAO,OAAO,UAAU,MAAM,IAAI,EAAE;;AAE7E;AAEA,SAAgB,aACd,MACA,WACA,OACU;CACV,OAAO,GAAG,GAAG,gBAAgB,MAAM,UAAU,MAAM,OAAO,UAAU,OAAO,KAAK,EAAE,GAChF,UAAU,OAAO,OAAO,GAAG,yBAAyB,GAAG,mBACxD,GAAG,gBAAgB,MAAM,UAAU,OAAO,OAAO,UAAU,MAAM,KAAK;AACzE;AAEA,SAAS,cACP,MACA,OACA,OACA,OACU;CACV,OAAO,GAAG,GAAG,SAAS,KAAK,QAAQ;EACjC;EACA,KAAK;CACP,CAAC,EAAE,wBAAwB,WAAW,MAAM,OAAO,OAAO,KAAK;AACjE;AAEA,SAAS,qBACP,MACA,OACA,OACA,OACA,UACU;CACV,MAAM,SAAS,SAAS,KAAK,QAAQ;EAAC;EAAO,KAAK;CAAK,CAAC;CACxD,IAAI,UAAU,MACZ,OAAO,aAAa,MAAM,GAAG,GAAG,OAAO,gBAAgB,GAAG;CAE5D,MAAM,aAAa,WAAW,MAAM,OAAO,OAAO,KAAK;CACvD,OAAO,aAAa,MAChB,GAAG,GAAG,OAAO,KAAK,eAClB,GAAG,IAAI,OAAO,cAAc,OAAO,KAAK,WAAW;AACzD;AAEA,SAAS,WACP,MACA,OACA,OACA,OACU;CACV,OAAO,oBACL,gBAAgB,KAAK,QAAQ,OAAO,KAAK,GACzC,OACA,OACA,IACF;AACF;AAEA,SAAS,gBACP,MACA,UACA,OACA,eACA,QACU;CACV,MAAM,eAAe,SAAS;CAC9B,QAAQ,cAAR;EACE,KAAK,UAAU;GACb,MAAM,YAA6B;IACjC;IACA,KAAK,SAAS;GAChB;GACA,OAAO,SAAS,KAAK,QAAQ,SAAS;EACxC;EACA,KAAK,WACH,OAAO,uBACL,MACA,UACA,OACA,eACA,MACF;EACF,KAAK,UACH,MAAM,IAAI,MACR,oEACF;EACF;GACE,YAAY,YAAY;GACxB;CACJ;AACF;AAEA,SAAS,uBACP,MACA,UACA,OACA,eACA,QACU;CACV,MAAM,YAAY,cAAc;CAChC,QAAQ,WAAR;EACE,KAAK,UACH,OAAO,oBACL,gBAAgB,KAAK,QAAQ,OAAO,cAAc,IAAI,GACtD,SAAS,OACT,QACA,IACF;EACF,KAAK;GACH,OACE,WAAW,MAAM,QAAQ,SAAS,KAAK,GACvC,yDACF;GACA,IAAI,MAAM,QAAQ,SAAS,KAAK,GAAG;IACjC,IAAI,SAAS,MAAM,SAAS,GAG1B,OAAO,2BACL,OAAO,SAAS,MAAM,IACtB,SAAS,KACX;IAKF,IAAI,cAAc,UAAU,MAC1B,OAAO,2BACL,OAAO,cAAc,OACrB,CAAC,CACH;IAIF,OAAO,2BAA2B,UAAU,CAAC,CAAC;GAChD;GACA,IACE,OAAO,SAAS,UAAU,YAC1B,OAAO,SAAS,UAAU,YAC1B,OAAO,SAAS,UAAU,WAE1B,OAAO,6BAA6B,SAAS,KAAK;GAEpD,MAAM,IAAI,MACR,+BAA+B,SAAS,MAAM,WAAW,OAAO,SAAS,OAC3E;EAEF,KAAK,UACH,MAAM,IAAI,MACR,oEACF;EACF,SACE,YAAY,SAAS;CACzB;AACF;AAEA,SAAgB,iBACd,MACA,cAIA;CACA,MAAM,sBAAsB,sBAAsB,MAAM,YAAY;CACpE,MAAM,QAAoB,CAAC;CAE3B,KAAK,MAAM,EAAC,WAAU,qBAAqB;EACzC,IAAI,MAAM,WAAW,GAAG;GACtB,MAAM,KAAK,UAAU,KAAK,QAAQ,KAAK,CAAC;GACxC;EACF;EACA,MAAM,KACJ,GAAG,SAAS,UAAU,KAAK,QAAQ,KAAK,EAAE,MAAM,eAC9C,MACA,oBAAoB,MAAM,QAAQ,YAAY,YAAY,KAAI,OAAM;GAClE,OAAO,oBAAoB,MAAM,SAAS,GAAG;GAC7C,KAAK;EACP,EAAE,GACF,oBAAoB,MAAM,QAAQ,YAAY,UAChD,EAAE,oBAAoB,MAAM,QAAQ,KAAK,GAC3C;CACF;CAEA,OAAO;EACL,MAAM,GAAG,GAAG,IAAI,KAAK,OAAO,EAAE;EAC9B;CAGF;AACF;AAEA,SAAgB,sBACd,MACA,cAQA;CACA,OACE,aAAa,SAAS,SAAS,WAAW,GAC1C,6CACF;CACA,MAAM,oBAAoB,aAAa,SAAS,QAAQ;CACxD,OACE,CAAC,kBAAkB,QACnB,sDACF;CACA,OAAO,CACL;EACE,OAAO,UAAU,MAAM,aAAa,SAAS,KAAK;EAClD,aAAa,aAAa;EAC1B,OAAO,aAAa,SAAS;CAC/B,GACA;EACE,OAAO,UAAU,MAAM,kBAAkB,SAAS,KAAK;EACvD,aAAa,kBAAkB;EAC/B,OAAO,kBAAkB,SAAS;CACpC,CACF;AACF;AAEA,SAAS,OAAO,OAAe,WAAW,OAAiB;CACzD,OAAO,GAAG,GACR,WAAW,GAAG,KAAK,GAAG,oBACvB,eAAe,IAAI,MAAM,KAAK,EAAE,IAAI,WAAW,GAAG,KAAK,GAAG;AAC7D;AAEA,SAAS,YAAY,QAAoB,QAAmC;CAC1E,MAAM,qBACJ,OAAO,OAAO,OAAO,OAAO,UAAU,OAAO,MAAM,GAAG,GACpD,OAAO,OAAO,WAAW,OAAO,MAAM,KAAK,OAAO,GAAG;CAEzD,MAAM,aAAa,mBAAmB;CACtC,IAAI,CAAC,mBAAmB,QAAQ;EAC9B,IAAI,qBAAqB;EACzB,QAAQ,YAAR;GACE,KAAK;GAEL,KAAK,UACH,qBAAqB;GAGvB,KAAK;GACL,KAAK;GACL,KAAK;GACL,KAAK;GACL,KAAK;GACL,KAAK;GACL,KAAK,4BAA4B;IAI/B,MAAM,QAAQ,cACZ,qBACI,GAAG,KAAK,UAAU,oCAClB;IAEN,IAAI,mBAAmB,SAAS;KAC9B,MAAM,MAAM,SAAS,QAAQ,MAAM;KACnC,OAAO,GAAG,aAAa,IAAI,uCAAuC,KAChE,GAAG,6BAA6B,IAAI,UACtC,EAAE,WAAW,IAAI,MAAM,OAAO,GAAG;IACnC;IAEA,OAAO,GAAG,GAAG,KACX,GAAG,sBAAsB,SAAS,QAAQ,MAAM,EAAE,SACpD,EAAE,MAAM,IAAI,MAAM,OAAO,GAAG;GAC9B;EACF;CACF;CAEA,OAAO,GAAG,GAAG,SAAS,QAAQ,MAAM,EAAE,MAAM,IAAI,MAAM,OAAO,GAAG;AAClE;AAEA,SAAS,SAAS,QAAoB,QAAyB;CAC7D,OAAO,IAAI,MACT,OAAO,MAAM,OACb,OAAO,OAAO,WAAW,OAAO,MAAM,KAAK,OAAO,GAAG,CACvD;AACF;AAEA,SAAS,UAAU,QAAoB,OAAc;CACnD,OAAO,GAAG,GAAG,IAAI,MAAM,OAAO,OAAO,UAAU,MAAM,GAAG,CAAC,EAAE,MAAM,IAAI,MAAM,MAAM,KAAK;AACxF;AAEA,SAAS,gBAAgB,MAAkB,OAAc,WAAmB;CAC1E,OAAO,KAAK,OAAO,KAAK,OAAO,UAAU,MAAM,GAAG,GAChD,KAAK,OAAO,WAAW,MAAM,KAAK,SAAS;AAE/C;AAGA,SAAgB,iBAAiB,UAAiC;CAChE,MAAM,aAA8B,MAClC,SAAS,GAAG,eACd;CACA,gBAAgB,UAAU;CAC1B,OAAO;AACT;AAEA,SAAS,gBAAgB,GAA4C;CACnE,MAAM,OAAO,iBAAiB,CAAC;CAC/B,IAAI,MACF,MAAM,IAAI,MAAM,oCAAoC,MAAM;AAE9D;AAEA,SAAS,iBAAiB,GAAwC;CAEhE,QAAQ,OADe,GACvB;EACE,KAAK,UACH,OAAO,MAAM;EACf,KAAK,UAAU;GACb,IAAI,MAAM,MACR;GAEF,IAAI,MAAM,QAAQ,CAAC,GAAG;IACpB,KAAK,IAAI,IAAI,GAAG,IAAI,EAAE,QAAQ,KAAK;KACjC,MAAM,OAAO,iBAAiB,EAAE,EAAE;KAClC,IAAI,MACF,OAAO,IAAI,EAAE,GAAG;IAEpB;IACA;GACF;GAEA,MAAM,IAAI;GACV,KAAK,MAAM,KAAK,GACd,IAAI,OAAO,GAAG,CAAC,GAAG;IAChB,MAAM,OAAO,iBAAiB,EAAE,EAAE;IAClC,IAAI,MACF,OAAO,KAAK,EAAE,IAAI;GAEtB;GAEF;EACF;EACA,KAAK,UACH;EACF,KAAK,WACH;EACF,SACE;CACJ;AACF"}
1
+ {"version":3,"file":"compiler.js","names":[],"sources":["../../../../z2s/src/compiler.ts"],"sourcesContent":["import type {SQLQuery} from '@databases/sql';\nimport {last, zip} from '../../shared/src/arrays.ts';\nimport {assert, unreachable} from '../../shared/src/asserts.ts';\nimport {\n parse as parseBigIntJson,\n type JSONValue as BigIntJSONValue,\n} from '../../shared/src/bigint-json.ts';\nimport {hasOwn} from '../../shared/src/has-own.ts';\nimport {type JSONValue} from '../../shared/src/json.ts';\nimport {must} from '../../shared/src/must.ts';\nimport type {\n AST,\n Bound,\n Condition,\n CorrelatedSubquery,\n CorrelatedSubqueryCondition,\n Correlation,\n LiteralReference,\n Ordering,\n SimpleCondition,\n ValuePosition,\n} from '../../zero-protocol/src/ast.ts';\nimport {\n clientToServer,\n type NameMapper,\n} from '../../zero-schema/src/name-mapper.ts';\nimport type {Schema} from '../../zero-types/src/schema.ts';\nimport type {ServerSchema} from '../../zero-types/src/server-schema.ts';\nimport type {Format} from '../../zql/src/ivm/view.ts';\nimport {completeOrdering} from '../../zql/src/query/complete-ordering.ts';\nimport {\n sql,\n sqlConvertColumnArg,\n sqlConvertPluralLiteralArg,\n sqlConvertSingularLiteralArg,\n type PluralLiteralType,\n} from './sql.ts';\n\ntype Table = {\n zql: string;\n alias: string;\n};\n\ntype QualifiedColumn = {\n table: Table;\n zql: string;\n};\n\ntype ServerSpec = {\n schema: ServerSchema;\n // maps zql names to server names\n mapper: NameMapper;\n};\n\nexport type Spec = {\n server: ServerSpec;\n zql: Schema['tables'];\n aliasCount: number;\n};\n\nconst ZQL_RESULT_KEY = 'zql_result';\nconst ZQL_RESULT_KEY_IDENT = sql.ident(ZQL_RESULT_KEY);\n\nconst ZQL_RESULT_TABLE_KEY = 'zql_root';\nconst ZQL_RESULT_TABLE_IDENT = sql.ident(ZQL_RESULT_TABLE_KEY);\n\nexport function compile(\n serverSchema: ServerSchema,\n zqlSchema: Schema,\n ast: AST,\n format?: Format,\n): SQLQuery {\n ast = completeOrdering(\n ast,\n tableName => zqlSchema.tables[tableName].primaryKey,\n );\n const spec: Spec = {\n aliasCount: 0,\n server: {\n schema: serverSchema,\n mapper: clientToServer(zqlSchema.tables),\n },\n zql: zqlSchema.tables,\n };\n return sql`SELECT \n ${toJSON(ZQL_RESULT_TABLE_KEY, format?.singular)}::text AS ${ZQL_RESULT_KEY_IDENT}\n FROM (${select(spec, ast, format)}) ${ZQL_RESULT_TABLE_IDENT}`;\n}\n\nfunction select(\n spec: Spec,\n ast: AST,\n format: Format | undefined,\n correlate?: (childTable: Table) => SQLQuery,\n): SQLQuery {\n const table = makeTable(spec, ast.table);\n const selectionSet = related(spec, ast.related ?? [], format, table);\n const tableSchema = spec.zql[ast.table];\n const usedAliases = new Set<string>(\n ast.related?.map(r => r.subquery.alias ?? ''),\n );\n for (const column of Object.keys(tableSchema.columns)) {\n if (!usedAliases.has(column)) {\n selectionSet.push(\n selectIdent(spec.server, {\n table,\n zql: column,\n }),\n );\n }\n }\n\n let appliedWhere = false;\n function maybeWhere(test: unknown) {\n if (!test) {\n return sql``;\n }\n\n const ret = appliedWhere ? sql`AND` : sql`WHERE`;\n appliedWhere = true;\n return ret;\n }\n\n return sql`SELECT ${sql.join(selectionSet, ',')}\n FROM ${fromIdent(spec.server, table)}\n ${maybeWhere(ast.where)} ${where(spec, ast.where, table)}${\n ast.start\n ? sql`\n ${maybeWhere(ast.start)} ${start(spec, ast.start, ast.orderBy, table)}`\n : sql``\n }\n ${maybeWhere(correlate)} ${correlate ? correlate(table) : sql``}\n ${orderBy(spec, ast.orderBy, table)}\n ${limit(ast.limit, format?.singular)}`;\n}\n\nexport function limit(\n limit: number | undefined,\n singular: boolean | undefined,\n): SQLQuery {\n if (limit === 0) {\n return sql`LIMIT 0`;\n }\n if (singular) {\n return sql`LIMIT 1`;\n }\n if (limit === undefined) {\n return sql``;\n }\n return sql`LIMIT ${sqlConvertSingularLiteralArg(limit)}`;\n}\n\nfunction makeTable(spec: Spec, zql: string, alias?: string): Table {\n alias = alias ?? zql + '_' + spec.aliasCount++;\n return {\n zql,\n alias,\n };\n}\n\nexport function orderBy(\n spec: Spec,\n orderBy: Ordering | undefined,\n table: Table,\n): SQLQuery {\n if (!orderBy) {\n return sql``;\n }\n return sql`ORDER BY ${sql.join(\n orderBy.map(([col, dir]) =>\n dir === 'asc'\n ? // Oh postgres. The table must be referred to by client name but the column by server name.\n // E.g., `SELECT server_col as client_col FROM server_table as client_table ORDER BY client_Table.server_col`\n sql`${colIdent(spec.server, {\n table,\n zql: col,\n })} ASC NULLS FIRST`\n : sql`${colIdent(spec.server, {\n table,\n zql: col,\n })} DESC NULLS LAST`,\n ),\n ', ',\n )}`;\n}\n\nexport function start(\n spec: Spec,\n bound: Bound | undefined,\n orderBy: Ordering | undefined,\n table: Table,\n): SQLQuery {\n if (!bound) {\n return sql``;\n }\n assert(\n orderBy !== undefined && orderBy.length > 0,\n 'start requires ordering',\n );\n\n const constraints: SQLQuery[] = [];\n for (let i = 0; i < orderBy.length; i++) {\n const group: SQLQuery[] = [];\n const [iField, iDirection] = orderBy[i];\n for (let j = 0; j <= i; j++) {\n const [field] = orderBy[j];\n if (j === i) {\n group.push(\n startRangeComparison(\n spec,\n table,\n iField,\n bound.row[iField] ?? null,\n iDirection === 'asc' ? '>' : '<',\n ),\n );\n } else {\n group.push(startEquality(spec, table, field, bound.row[field] ?? null));\n }\n }\n constraints.push(sql`(${sql.join(group, ' AND ')})`);\n }\n\n if (!bound.exclusive) {\n constraints.push(\n sql`(${sql.join(\n orderBy.map(([field]) =>\n startEquality(spec, table, field, bound.row[field] ?? null),\n ),\n ' AND ',\n )})`,\n );\n }\n\n return sql`(${sql.join(constraints, ' OR ')})`;\n}\n\nfunction related(\n spec: Spec,\n relationships: readonly CorrelatedSubquery[],\n format: Format | undefined,\n parentTable: Table,\n): SQLQuery[] {\n return relationships.map(relationship =>\n relationshipSubquery(\n spec,\n relationship,\n format?.relationships[must(relationship.subquery.alias)],\n parentTable,\n ),\n );\n}\n\nfunction relationshipSubquery(\n spec: Spec,\n relationship: CorrelatedSubquery,\n format: Format | undefined,\n parentTable: Table,\n): SQLQuery {\n const innerAlias = `inner_${relationship.subquery.alias}`;\n if (relationship.hidden) {\n const {join, participatingTables} = makeJunctionJoin(spec, relationship);\n const lastTable = must(last(participatingTables)).table;\n\n assert(\n relationship.subquery.related,\n 'hidden relationship must be a junction',\n );\n const nestedAst = relationship.subquery.related[0].subquery;\n const selectionSet = related(\n spec,\n nestedAst.related ?? [],\n format,\n lastTable,\n );\n const tableSchema = spec.zql[nestedAst.table];\n for (const column of Object.keys(tableSchema.columns)) {\n selectionSet.push(\n selectIdent(spec.server, {\n table: lastTable,\n zql: column,\n }),\n );\n }\n\n return sql`(\n SELECT ${toJSON(innerAlias, format?.singular)} FROM (SELECT ${sql.join(\n selectionSet,\n ',',\n )} FROM ${join} WHERE (${makeCorrelator(\n spec,\n relationship.correlation.parentField.map(f => ({\n table: parentTable,\n zql: f,\n })),\n relationship.correlation.childField,\n )(participatingTables[0].table)}) ${\n nestedAst.where\n ? sql`AND ${where(spec, nestedAst.where, lastTable)}`\n : sql``\n }${\n nestedAst.start\n ? sql` AND ${start(\n spec,\n nestedAst.start,\n nestedAst.orderBy,\n lastTable,\n )}`\n : sql``\n } ${orderBy(spec, nestedAst.orderBy, lastTable)} ${limit(\n last(participatingTables)?.limit,\n format?.singular,\n )} ) ${sql.ident(innerAlias)}\n ) as ${sql.ident(relationship.subquery.alias)}`;\n }\n\n return sql`(\n SELECT ${toJSON(innerAlias, format?.singular)} FROM (${select(\n spec,\n relationship.subquery,\n format,\n makeCorrelator(\n spec,\n relationship.correlation.parentField.map(f => ({\n table: parentTable,\n zql: f,\n })),\n relationship.correlation.childField,\n ),\n )}) ${sql.ident(innerAlias)}\n ) as ${sql.ident(relationship.subquery.alias)}`;\n}\n\nfunction where(\n spec: Spec,\n condition: Condition | undefined,\n table: Table,\n): SQLQuery {\n if (!condition) {\n return sql``;\n }\n\n switch (condition.type) {\n case 'and':\n return sql`(${sql.join(\n condition.conditions.map(c => where(spec, c, table)),\n ' AND ',\n )})`;\n case 'or':\n return sql`(${sql.join(\n condition.conditions.map(c => where(spec, c, table)),\n ' OR ',\n )})`;\n case 'correlatedSubquery':\n // `scalar` is deliberately ignored here. It is a planner hint for the\n // IVM engines, which have no cost-based planner and benefit from\n // pre-resolving an at-most-one-row subquery to a literal comparison\n // (see zqlite's `resolveSimpleScalarSubqueries`). Postgres decorrelates\n // EXISTS into a semi-join on its own, so the hint buys nothing here —\n // and honoring it as `parentField = (SELECT childField … LIMIT 1)` is\n // only sound when the subquery matches at most one row *globally*.\n // Applying it unconditionally silently dropped rows whenever the\n // subquery was not pinned to a unique key.\n return exists(spec, condition, table);\n case 'simple':\n return simple(spec, condition, table);\n }\n}\n\nfunction exists(\n spec: Spec,\n condition: CorrelatedSubqueryCondition,\n parentTable: Table,\n): SQLQuery {\n switch (condition.op) {\n case 'EXISTS':\n return sql`EXISTS (${select(\n spec,\n condition.related.subquery,\n undefined,\n makeCorrelator(\n spec,\n condition.related.correlation.parentField.map(f => ({\n table: parentTable,\n zql: f,\n })),\n condition.related.correlation.childField,\n ),\n )})`;\n case 'NOT EXISTS':\n return sql`NOT EXISTS (${select(\n spec,\n condition.related.subquery,\n undefined,\n makeCorrelator(\n spec,\n condition.related.correlation.parentField.map(f => ({\n table: parentTable,\n zql: f,\n })),\n condition.related.correlation.childField,\n ),\n )})`;\n }\n}\n\nexport function makeCorrelator(\n spec: Spec,\n parentFields: readonly QualifiedColumn[],\n childZqlFields: readonly string[],\n): (childTable: Table) => SQLQuery {\n return (childTable: Table) => {\n const childFields = childZqlFields.map(zqlField => ({\n table: childTable,\n zql: zqlField,\n }));\n return sql.join(\n zip(parentFields, childFields).map(\n ([parentColumn, childColumn]) =>\n sql`${colIdent(spec.server, parentColumn)} = ${colIdent(\n spec.server,\n childColumn,\n )}`,\n ),\n ' AND ',\n );\n };\n}\n\nexport function simple(\n spec: Spec,\n condition: SimpleCondition,\n table: Table,\n): SQLQuery {\n switch (condition.op) {\n case '!=':\n case '<':\n case '<=':\n case '=':\n case '>':\n case '>=':\n case 'ILIKE':\n case 'LIKE':\n case 'NOT ILIKE':\n case 'NOT LIKE':\n return sql`${valueComparison(\n spec,\n condition.left,\n table,\n condition.right,\n false,\n )} ${sql.__dangerous__rawValue(condition.op)} ${valueComparison(\n spec,\n condition.right,\n table,\n condition.left,\n false,\n )}`;\n case 'NOT IN':\n case 'IN':\n return any(spec, condition, table);\n case 'IS':\n case 'IS NOT':\n return distinctFrom(spec, condition, table);\n }\n}\n\nexport function any(\n spec: Spec,\n condition: SimpleCondition,\n table: Table,\n): SQLQuery {\n return sql`${condition.op === 'NOT IN' ? sql`NOT` : sql``}\n (\n ${valueComparison(spec, condition.left, table, condition.right, false)} = ANY \n (${valueComparison(spec, condition.right, table, condition.left, true)})\n )`;\n}\n\nexport function distinctFrom(\n spec: Spec,\n condition: SimpleCondition,\n table: Table,\n): SQLQuery {\n return sql`${valueComparison(spec, condition.left, table, condition.right, false)} ${\n condition.op === 'IS' ? sql`IS NOT DISTINCT FROM` : sql`IS DISTINCT FROM`\n } ${valueComparison(spec, condition.right, table, condition.left, false)}`;\n}\n\nfunction startEquality(\n spec: Spec,\n table: Table,\n field: string,\n value: unknown,\n): SQLQuery {\n return sql`${colIdent(spec.server, {\n table,\n zql: field,\n })} IS NOT DISTINCT FROM ${startValue(spec, table, field, value)}`;\n}\n\nfunction startRangeComparison(\n spec: Spec,\n table: Table,\n field: string,\n value: unknown,\n operator: '>' | '<',\n): SQLQuery {\n const column = colIdent(spec.server, {table, zql: field});\n if (value === null) {\n return operator === '>' ? sql`${column} IS NOT NULL` : sql`FALSE`;\n }\n const typedValue = startValue(spec, table, field, value);\n return operator === '>'\n ? sql`${column} > ${typedValue}`\n : sql`(${column} IS NULL OR ${column} < ${typedValue})`;\n}\n\nfunction startValue(\n spec: Spec,\n table: Table,\n field: string,\n value: unknown,\n): SQLQuery {\n return sqlConvertColumnArg(\n getServerColumn(spec.server, table, field),\n value,\n false,\n true,\n );\n}\n\nfunction valueComparison(\n spec: Spec,\n valuePos: ValuePosition,\n table: Table,\n otherValuePos: ValuePosition,\n plural: boolean,\n): SQLQuery {\n const valuePosType = valuePos.type;\n switch (valuePosType) {\n case 'column': {\n const qualified: QualifiedColumn = {\n table,\n zql: valuePos.name,\n };\n return colIdent(spec.server, qualified);\n }\n case 'literal':\n return literalValueComparison(\n spec,\n valuePos,\n table,\n otherValuePos,\n plural,\n );\n case 'static':\n throw new Error(\n 'Static parameters must be bound to a value before compiling to SQL',\n );\n default:\n unreachable(valuePosType);\n break;\n }\n}\n\nfunction literalValueComparison(\n spec: Spec,\n valuePos: LiteralReference,\n table: Table,\n otherValuePos: ValuePosition,\n plural: boolean,\n): SQLQuery {\n const otherType = otherValuePos.type;\n switch (otherType) {\n case 'column':\n return sqlConvertColumnArg(\n getServerColumn(spec.server, table, otherValuePos.name),\n valuePos.value,\n plural,\n true,\n );\n case 'literal': {\n assert(\n plural === Array.isArray(valuePos.value),\n 'Expected plural flag to match whether value is an array',\n );\n if (Array.isArray(valuePos.value)) {\n if (valuePos.value.length > 0) {\n // If the array is non-empty base its type on its first\n // element\n return sqlConvertPluralLiteralArg(\n typeof valuePos.value[0] as PluralLiteralType,\n valuePos.value as PluralLiteralType[],\n );\n }\n // If the array is empty, base its type on the other value\n // position's type (as long as the other value position is non-null,\n // cannot have a null[]).\n if (otherValuePos.value !== null) {\n return sqlConvertPluralLiteralArg(\n typeof otherValuePos.value as PluralLiteralType,\n [],\n );\n }\n // If the other value position is null, it can be compared to any\n // type of empty array, chose 'string' arbitrarily.\n return sqlConvertPluralLiteralArg('string', []);\n }\n if (\n typeof valuePos.value === 'string' ||\n typeof valuePos.value === 'number' ||\n typeof valuePos.value === 'boolean'\n ) {\n return sqlConvertSingularLiteralArg(valuePos.value);\n }\n throw new Error(\n `Literal of unexpected type. ${valuePos.value} of type ${typeof valuePos.value}`,\n );\n }\n case 'static':\n throw new Error(\n 'Static parameters must be bound to a value before compiling to SQL',\n );\n default:\n unreachable(otherType);\n }\n}\n\nexport function makeJunctionJoin(\n spec: Spec,\n relationship: CorrelatedSubquery,\n): {\n join: SQLQuery;\n participatingTables: ReturnType<typeof pullTablesForJunction>;\n} {\n const participatingTables = pullTablesForJunction(spec, relationship);\n const joins: SQLQuery[] = [];\n\n for (const {table} of participatingTables) {\n if (joins.length === 0) {\n joins.push(fromIdent(spec.server, table));\n continue;\n }\n joins.push(\n sql` JOIN ${fromIdent(spec.server, table)} ON ${makeCorrelator(\n spec,\n participatingTables[joins.length].correlation.parentField.map(f => ({\n table: participatingTables[joins.length - 1].table,\n zql: f,\n })),\n participatingTables[joins.length].correlation.childField,\n )(participatingTables[joins.length].table)}`,\n );\n }\n\n return {\n join: sql`${sql.join(joins, '')}`,\n participatingTables,\n // lastTable: participatingTables[participatingTables.length - 1].table,\n // lastLimit: participatingTables[participatingTables.length - 1].limit,\n };\n}\n\nexport function pullTablesForJunction(\n spec: Spec,\n relationship: CorrelatedSubquery,\n): [\n {\n table: Table;\n correlation: Correlation;\n limit: number | undefined;\n },\n {table: Table; correlation: Correlation; limit: number | undefined},\n] {\n assert(\n relationship.subquery.related?.length === 1,\n 'Too many related tables for a junction edge',\n );\n const otherRelationship = relationship.subquery.related[0];\n assert(\n !otherRelationship.hidden,\n 'Expected junction edge relationship to not be hidden',\n );\n return [\n {\n table: makeTable(spec, relationship.subquery.table),\n correlation: relationship.correlation,\n limit: relationship.subquery.limit,\n },\n {\n table: makeTable(spec, otherRelationship.subquery.table),\n correlation: otherRelationship.correlation,\n limit: otherRelationship.subquery.limit,\n },\n ];\n}\n\nfunction toJSON(table: string, singular = false): SQLQuery {\n return sql`${\n singular ? sql`` : sql`COALESCE(json_agg`\n }(row_to_json(${sql.ident(table)}))${singular ? sql`` : sql`, '[]'::json)`}`;\n}\n\nfunction selectIdent(server: ServerSpec, column: QualifiedColumn): SQLQuery {\n const serverColumnSchema =\n server.schema[server.mapper.tableName(column.table.zql)][\n server.mapper.columnName(column.table.zql, column.zql)\n ];\n const serverType = serverColumnSchema.type;\n if (!serverColumnSchema.isEnum) {\n let needsNormalization = false;\n switch (serverType) {\n case 'timestamptz':\n // @ts-expect-error Fallthrough intended\n case 'timetz':\n needsNormalization = true;\n // fallthrough\n\n case 'date':\n case 'time':\n case 'time without time zone':\n case 'time with time zone':\n case 'timestamp':\n case 'timestamp without time zone':\n case 'timestamp with time zone': {\n // EXTRACT(EPOCH FROM timetz) can be negative when the UTC offset is\n // positive (e.g. 01:00+02 = 23:00 UTC prev day = -3600s). Wrap with\n // modular arithmetic to normalize to 0..86400000.\n const toMs = (epochExpr: SQLQuery): SQLQuery =>\n needsNormalization\n ? sql`((${epochExpr})::bigint + 86400000) % 86400000`\n : epochExpr;\n\n if (serverColumnSchema.isArray) {\n const col = colIdent(server, column);\n return sql`CASE WHEN ${col} IS NULL THEN NULL ELSE ARRAY(SELECT ${toMs(\n sql`EXTRACT(EPOCH FROM unnest(${col})) * 1000`,\n )}) END as ${sql.ident(column.zql)}`;\n }\n\n return sql`${toMs(\n sql`EXTRACT(EPOCH FROM ${colIdent(server, column)}) * 1000`,\n )} as ${sql.ident(column.zql)}`;\n }\n }\n }\n\n return sql`${colIdent(server, column)} as ${sql.ident(column.zql)}`;\n}\n\nfunction colIdent(server: ServerSpec, column: QualifiedColumn) {\n return sql.ident(\n column.table.alias,\n server.mapper.columnName(column.table.zql, column.zql),\n );\n}\n\nfunction fromIdent(server: ServerSpec, table: Table) {\n return sql`${sql.ident(server.mapper.tableName(table.zql))} AS ${sql.ident(table.alias)}`;\n}\n\nfunction getServerColumn(spec: ServerSpec, table: Table, zqlColumn: string) {\n return spec.schema[spec.mapper.tableName(table.zql)][\n spec.mapper.columnName(table.zql, zqlColumn)\n ];\n}\n\n// oxlint-disable-next-line @typescript-eslint/no-explicit-any\nexport function extractZqlResult(pgResult: Array<any>): JSONValue {\n const bigIntJson: BigIntJSONValue = parseBigIntJson(\n pgResult[0][ZQL_RESULT_KEY],\n );\n assertJSONValue(bigIntJson);\n return bigIntJson;\n}\n\nfunction assertJSONValue(v: BigIntJSONValue): asserts v is JSONValue {\n const path = findPathToBigInt(v);\n if (path) {\n throw new Error(`Value exceeds safe Number range. ${path}`);\n }\n}\n\nfunction findPathToBigInt(v: BigIntJSONValue): string | undefined {\n const typeOfV = typeof v;\n switch (typeOfV) {\n case 'bigint':\n return ` = ${v}`;\n case 'object': {\n if (v === null) {\n return;\n }\n if (Array.isArray(v)) {\n for (let i = 0; i < v.length; i++) {\n const path = findPathToBigInt(v[i]);\n if (path) {\n return `[${i}]${path}`;\n }\n }\n return undefined;\n }\n\n const o = v as Record<string, BigIntJSONValue>;\n for (const k in o) {\n if (hasOwn(o, k)) {\n const path = findPathToBigInt(o[k]);\n if (path) {\n return `['${k}']${path}`;\n }\n }\n }\n return undefined;\n }\n case 'number':\n return undefined;\n case 'boolean':\n return undefined;\n default:\n return undefined;\n }\n}\n"],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  var package_default = {
2
2
  name: "@rocicorp/zero",
3
- version: "1.10.0-canary.0",
3
+ version: "1.10.0-canary.10",
4
4
  description: "Zero is a web framework for serverless web development.",
5
5
  homepage: "https://zero.rocicorp.dev",
6
6
  bugs: { "url": "https://bugs.rocicorp.dev" },
@@ -136,7 +136,7 @@ var package_default = {
136
136
  "@rocicorp/lock": "^1.0.4",
137
137
  "@rocicorp/logger": "^6.1.0",
138
138
  "@rocicorp/resolver": "^1.0.2",
139
- "@rocicorp/zero-sqlite3": "^1.1.2",
139
+ "@rocicorp/zero-sqlite3": "^1.1.4",
140
140
  "@standard-schema/spec": "^1.0.0",
141
141
  "@types/basic-auth": "^1.1.8",
142
142
  "@types/ws": "^8.5.12",
@@ -189,7 +189,7 @@ var package_default = {
189
189
  "zqlite": "workspace:*"
190
190
  },
191
191
  engines: { "node": ">=22" },
192
- packageManager: "pnpm@11.5.3"
192
+ packageManager: "pnpm@11.11.0"
193
193
  };
194
194
  //#endregion
195
195
  export { package_default as default };