@rocicorp/zero 1.9.1-canary.1 → 1.10.0-canary.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (344) hide show
  1. package/out/analyze-query/src/analyze-cli.js +2 -2
  2. package/out/analyze-query/src/analyze-cli.js.map +1 -1
  3. package/out/replicache/src/db/commit.js +1 -4
  4. package/out/replicache/src/db/commit.js.map +1 -1
  5. package/out/replicache/src/db/read.d.ts +1 -0
  6. package/out/replicache/src/db/read.d.ts.map +1 -1
  7. package/out/replicache/src/db/read.js +1 -4
  8. package/out/replicache/src/db/read.js.map +1 -1
  9. package/out/replicache/src/db/write.d.ts +2 -1
  10. package/out/replicache/src/db/write.d.ts.map +1 -1
  11. package/out/replicache/src/db/write.js +4 -51
  12. package/out/replicache/src/db/write.js.map +1 -1
  13. package/out/replicache/src/persist/clients.d.ts +1 -0
  14. package/out/replicache/src/persist/clients.d.ts.map +1 -1
  15. package/out/replicache/src/persist/clients.js +4 -31
  16. package/out/replicache/src/persist/clients.js.map +1 -1
  17. package/out/replicache/src/process-env.d.ts +28 -0
  18. package/out/replicache/src/process-env.d.ts.map +1 -0
  19. package/out/replicache/src/replicache-impl.d.ts.map +1 -1
  20. package/out/replicache/src/replicache-impl.js.map +1 -1
  21. package/out/replicache/src/scan-iterator.js +2 -14
  22. package/out/replicache/src/scan-iterator.js.map +1 -1
  23. package/out/replicache/src/subscriptions.d.ts +1 -0
  24. package/out/replicache/src/subscriptions.d.ts.map +1 -1
  25. package/out/replicache/src/subscriptions.js +2 -10
  26. package/out/replicache/src/subscriptions.js.map +1 -1
  27. package/out/replicache/src/transactions.d.ts +1 -0
  28. package/out/replicache/src/transactions.d.ts.map +1 -1
  29. package/out/replicache/src/transactions.js +2 -4
  30. package/out/replicache/src/transactions.js.map +1 -1
  31. package/out/zero/package.js +2 -2
  32. package/out/zero/package.js.map +1 -1
  33. package/out/zero-cache/src/config/normalize.d.ts +1 -0
  34. package/out/zero-cache/src/config/normalize.d.ts.map +1 -1
  35. package/out/zero-cache/src/config/normalize.js +10 -1
  36. package/out/zero-cache/src/config/normalize.js.map +1 -1
  37. package/out/zero-cache/src/config/zero-config.d.ts +43 -1
  38. package/out/zero-cache/src/config/zero-config.d.ts.map +1 -1
  39. package/out/zero-cache/src/config/zero-config.js +139 -20
  40. package/out/zero-cache/src/config/zero-config.js.map +1 -1
  41. package/out/zero-cache/src/db/migration.js +1 -1
  42. package/out/zero-cache/src/observability/metrics.d.ts +5 -0
  43. package/out/zero-cache/src/observability/metrics.d.ts.map +1 -1
  44. package/out/zero-cache/src/observability/metrics.js +15 -1
  45. package/out/zero-cache/src/observability/metrics.js.map +1 -1
  46. package/out/zero-cache/src/server/backup-watermark-poller.js +31 -0
  47. package/out/zero-cache/src/server/backup-watermark-poller.js.map +1 -0
  48. package/out/zero-cache/src/server/change-streamer.d.ts.map +1 -1
  49. package/out/zero-cache/src/server/change-streamer.js +90 -30
  50. package/out/zero-cache/src/server/change-streamer.js.map +1 -1
  51. package/out/zero-cache/src/server/main.d.ts.map +1 -1
  52. package/out/zero-cache/src/server/main.js +5 -15
  53. package/out/zero-cache/src/server/main.js.map +1 -1
  54. package/out/zero-cache/src/server/replicator.d.ts.map +1 -1
  55. package/out/zero-cache/src/server/replicator.js +46 -3
  56. package/out/zero-cache/src/server/replicator.js.map +1 -1
  57. package/out/zero-cache/src/server/runner/run-worker.js +2 -1
  58. package/out/zero-cache/src/server/runner/run-worker.js.map +1 -1
  59. package/out/zero-cache/src/server/worker-urls.d.ts +1 -1
  60. package/out/zero-cache/src/server/worker-urls.js +2 -2
  61. package/out/zero-cache/src/server/worker-urls.js.map +1 -1
  62. package/out/zero-cache/src/services/change-source/change-source.d.ts +4 -2
  63. package/out/zero-cache/src/services/change-source/change-source.d.ts.map +1 -1
  64. package/out/zero-cache/src/services/change-source/common/replica-restore.d.ts +35 -0
  65. package/out/zero-cache/src/services/change-source/common/replica-restore.d.ts.map +1 -0
  66. package/out/zero-cache/src/services/change-source/common/replica-restore.js +34 -0
  67. package/out/zero-cache/src/services/change-source/common/replica-restore.js.map +1 -0
  68. package/out/zero-cache/src/services/change-source/common/replica-schema.d.ts +2 -0
  69. package/out/zero-cache/src/services/change-source/common/replica-schema.d.ts.map +1 -1
  70. package/out/zero-cache/src/services/change-source/common/replica-schema.js +73 -1
  71. package/out/zero-cache/src/services/change-source/common/replica-schema.js.map +1 -1
  72. package/out/zero-cache/src/services/change-source/custom/change-source.d.ts +2 -6
  73. package/out/zero-cache/src/services/change-source/custom/change-source.d.ts.map +1 -1
  74. package/out/zero-cache/src/services/change-source/custom/change-source.js +16 -7
  75. package/out/zero-cache/src/services/change-source/custom/change-source.js.map +1 -1
  76. package/out/zero-cache/src/services/change-source/pg/backfill-stream.js +4 -7
  77. package/out/zero-cache/src/services/change-source/pg/backfill-stream.js.map +1 -1
  78. package/out/zero-cache/src/services/change-source/pg/change-source.d.ts +7 -7
  79. package/out/zero-cache/src/services/change-source/pg/change-source.d.ts.map +1 -1
  80. package/out/zero-cache/src/services/change-source/pg/change-source.js +75 -23
  81. package/out/zero-cache/src/services/change-source/pg/change-source.js.map +1 -1
  82. package/out/zero-cache/src/services/change-source/pg/initial-sync.d.ts +9 -1
  83. package/out/zero-cache/src/services/change-source/pg/initial-sync.d.ts.map +1 -1
  84. package/out/zero-cache/src/services/change-source/pg/initial-sync.js +34 -4
  85. package/out/zero-cache/src/services/change-source/pg/initial-sync.js.map +1 -1
  86. package/out/zero-cache/src/services/change-source/pg/logical-replication/stream.js +1 -1
  87. package/out/zero-cache/src/services/change-source/pg/replication-slots.d.ts +4 -2
  88. package/out/zero-cache/src/services/change-source/pg/replication-slots.d.ts.map +1 -1
  89. package/out/zero-cache/src/services/change-source/pg/replication-slots.js +7 -4
  90. package/out/zero-cache/src/services/change-source/pg/replication-slots.js.map +1 -1
  91. package/out/zero-cache/src/services/change-source/pg/schema/init.d.ts +0 -5
  92. package/out/zero-cache/src/services/change-source/pg/schema/init.d.ts.map +1 -1
  93. package/out/zero-cache/src/services/change-source/pg/schema/init.js +29 -41
  94. package/out/zero-cache/src/services/change-source/pg/schema/init.js.map +1 -1
  95. package/out/zero-cache/src/services/change-source/pg/schema/shard.d.ts +35 -16
  96. package/out/zero-cache/src/services/change-source/pg/schema/shard.d.ts.map +1 -1
  97. package/out/zero-cache/src/services/change-source/pg/schema/shard.js +77 -7
  98. package/out/zero-cache/src/services/change-source/pg/schema/shard.js.map +1 -1
  99. package/out/zero-cache/src/services/change-source/protocol/current/data.d.ts +1 -1
  100. package/out/zero-cache/src/services/change-source/protocol/current/data.d.ts.map +1 -1
  101. package/out/zero-cache/src/services/change-source/protocol/current/data.js +1 -12
  102. package/out/zero-cache/src/services/change-source/protocol/current/data.js.map +1 -1
  103. package/out/zero-cache/src/services/change-source/protocol/current/downstream.d.ts +3 -3
  104. package/out/zero-cache/src/services/change-source/protocol/current/schema-change-tags.d.ts +6 -0
  105. package/out/zero-cache/src/services/change-source/protocol/current/schema-change-tags.d.ts.map +1 -0
  106. package/out/zero-cache/src/services/change-source/protocol/current/schema-change-tags.js +21 -0
  107. package/out/zero-cache/src/services/change-source/protocol/current/schema-change-tags.js.map +1 -0
  108. package/out/zero-cache/src/services/change-streamer/backup-cleanup-monitor-factory.d.ts +5 -6
  109. package/out/zero-cache/src/services/change-streamer/backup-cleanup-monitor-factory.d.ts.map +1 -1
  110. package/out/zero-cache/src/services/change-streamer/backup-cleanup-monitor-factory.js +32 -9
  111. package/out/zero-cache/src/services/change-streamer/backup-cleanup-monitor-factory.js.map +1 -1
  112. package/out/zero-cache/src/services/change-streamer/backup-monitor.d.ts +15 -5
  113. package/out/zero-cache/src/services/change-streamer/backup-monitor.d.ts.map +1 -1
  114. package/out/zero-cache/src/services/change-streamer/backup-monitor.js +66 -0
  115. package/out/zero-cache/src/services/change-streamer/backup-monitor.js.map +1 -0
  116. package/out/zero-cache/src/services/change-streamer/broadcast.d.ts +68 -78
  117. package/out/zero-cache/src/services/change-streamer/broadcast.d.ts.map +1 -1
  118. package/out/zero-cache/src/services/change-streamer/broadcast.js +84 -92
  119. package/out/zero-cache/src/services/change-streamer/broadcast.js.map +1 -1
  120. package/out/zero-cache/src/services/change-streamer/change-log-codec.d.ts +19 -0
  121. package/out/zero-cache/src/services/change-streamer/change-log-codec.d.ts.map +1 -0
  122. package/out/zero-cache/src/services/change-streamer/change-log-codec.js +50 -0
  123. package/out/zero-cache/src/services/change-streamer/change-log-codec.js.map +1 -0
  124. package/out/zero-cache/src/services/change-streamer/change-log-initializer.d.ts +141 -0
  125. package/out/zero-cache/src/services/change-streamer/change-log-initializer.d.ts.map +1 -0
  126. package/out/zero-cache/src/services/change-streamer/change-log-initializer.js +270 -0
  127. package/out/zero-cache/src/services/change-streamer/change-log-initializer.js.map +1 -0
  128. package/out/zero-cache/src/services/change-streamer/change-log-transaction-hash.d.ts +19 -0
  129. package/out/zero-cache/src/services/change-streamer/change-log-transaction-hash.d.ts.map +1 -0
  130. package/out/zero-cache/src/services/change-streamer/change-log-transaction-hash.js +39 -0
  131. package/out/zero-cache/src/services/change-streamer/change-log-transaction-hash.js.map +1 -0
  132. package/out/zero-cache/src/services/change-streamer/change-streamer-http.d.ts +3 -4
  133. package/out/zero-cache/src/services/change-streamer/change-streamer-http.d.ts.map +1 -1
  134. package/out/zero-cache/src/services/change-streamer/change-streamer-http.js +15 -20
  135. package/out/zero-cache/src/services/change-streamer/change-streamer-http.js.map +1 -1
  136. package/out/zero-cache/src/services/change-streamer/change-streamer-service.d.ts +69 -24
  137. package/out/zero-cache/src/services/change-streamer/change-streamer-service.d.ts.map +1 -1
  138. package/out/zero-cache/src/services/change-streamer/change-streamer-service.js +330 -63
  139. package/out/zero-cache/src/services/change-streamer/change-streamer-service.js.map +1 -1
  140. package/out/zero-cache/src/services/change-streamer/change-streamer.d.ts +55 -13
  141. package/out/zero-cache/src/services/change-streamer/change-streamer.d.ts.map +1 -1
  142. package/out/zero-cache/src/services/change-streamer/change-streamer.js.map +1 -1
  143. package/out/zero-cache/src/services/change-streamer/error-type-enum.d.ts +8 -0
  144. package/out/zero-cache/src/services/change-streamer/error-type-enum.d.ts.map +1 -1
  145. package/out/zero-cache/src/services/change-streamer/forwarder.d.ts +14 -3
  146. package/out/zero-cache/src/services/change-streamer/forwarder.d.ts.map +1 -1
  147. package/out/zero-cache/src/services/change-streamer/forwarder.js +41 -11
  148. package/out/zero-cache/src/services/change-streamer/forwarder.js.map +1 -1
  149. package/out/zero-cache/src/services/change-streamer/{litestream3-backup-monitor.d.ts → litestream3-prometheus-poller.d.ts} +19 -45
  150. package/out/zero-cache/src/services/change-streamer/litestream3-prometheus-poller.d.ts.map +1 -0
  151. package/out/zero-cache/src/services/change-streamer/{litestream3-backup-monitor.js → litestream3-prometheus-poller.js} +57 -171
  152. package/out/zero-cache/src/services/change-streamer/litestream3-prometheus-poller.js.map +1 -0
  153. package/out/zero-cache/src/services/change-streamer/replica-poller.d.ts +15 -0
  154. package/out/zero-cache/src/services/change-streamer/replica-poller.d.ts.map +1 -0
  155. package/out/zero-cache/src/services/change-streamer/replica-poller.js +55 -0
  156. package/out/zero-cache/src/services/change-streamer/replica-poller.js.map +1 -0
  157. package/out/zero-cache/src/services/change-streamer/schema/tables.d.ts +5 -1
  158. package/out/zero-cache/src/services/change-streamer/schema/tables.d.ts.map +1 -1
  159. package/out/zero-cache/src/services/change-streamer/schema/tables.js +2 -1
  160. package/out/zero-cache/src/services/change-streamer/schema/tables.js.map +1 -1
  161. package/out/zero-cache/src/services/change-streamer/snapshot-reservations.d.ts +14 -0
  162. package/out/zero-cache/src/services/change-streamer/snapshot-reservations.d.ts.map +1 -0
  163. package/out/zero-cache/src/services/change-streamer/snapshot-reservations.js +86 -0
  164. package/out/zero-cache/src/services/change-streamer/snapshot-reservations.js.map +1 -0
  165. package/out/zero-cache/src/services/change-streamer/snapshot.d.ts +4 -1
  166. package/out/zero-cache/src/services/change-streamer/snapshot.d.ts.map +1 -1
  167. package/out/zero-cache/src/services/change-streamer/snapshot.js +39 -14
  168. package/out/zero-cache/src/services/change-streamer/snapshot.js.map +1 -1
  169. package/out/zero-cache/src/services/change-streamer/sqlite-change-log-catchup.d.ts +75 -0
  170. package/out/zero-cache/src/services/change-streamer/sqlite-change-log-catchup.d.ts.map +1 -0
  171. package/out/zero-cache/src/services/change-streamer/sqlite-change-log-catchup.js +261 -0
  172. package/out/zero-cache/src/services/change-streamer/sqlite-change-log-catchup.js.map +1 -0
  173. package/out/zero-cache/src/services/change-streamer/sqlite-change-log-purge-scheduler.d.ts +121 -0
  174. package/out/zero-cache/src/services/change-streamer/sqlite-change-log-purge-scheduler.d.ts.map +1 -0
  175. package/out/zero-cache/src/services/change-streamer/sqlite-change-log-purge-scheduler.js +391 -0
  176. package/out/zero-cache/src/services/change-streamer/sqlite-change-log-purge-scheduler.js.map +1 -0
  177. package/out/zero-cache/src/services/change-streamer/sqlite-change-log-reader.d.ts +62 -0
  178. package/out/zero-cache/src/services/change-streamer/sqlite-change-log-reader.d.ts.map +1 -0
  179. package/out/zero-cache/src/services/change-streamer/sqlite-change-log-reader.js +159 -0
  180. package/out/zero-cache/src/services/change-streamer/sqlite-change-log-reader.js.map +1 -0
  181. package/out/zero-cache/src/services/change-streamer/sqlite-change-log-writer.d.ts +109 -0
  182. package/out/zero-cache/src/services/change-streamer/sqlite-change-log-writer.d.ts.map +1 -0
  183. package/out/zero-cache/src/services/change-streamer/sqlite-change-log-writer.js +258 -0
  184. package/out/zero-cache/src/services/change-streamer/sqlite-change-log-writer.js.map +1 -0
  185. package/out/zero-cache/src/services/change-streamer/storer.d.ts +22 -12
  186. package/out/zero-cache/src/services/change-streamer/storer.d.ts.map +1 -1
  187. package/out/zero-cache/src/services/change-streamer/storer.js +93 -117
  188. package/out/zero-cache/src/services/change-streamer/storer.js.map +1 -1
  189. package/out/zero-cache/src/services/change-streamer/subscriber.d.ts +61 -10
  190. package/out/zero-cache/src/services/change-streamer/subscriber.d.ts.map +1 -1
  191. package/out/zero-cache/src/services/change-streamer/subscriber.js +101 -8
  192. package/out/zero-cache/src/services/change-streamer/subscriber.js.map +1 -1
  193. package/out/zero-cache/src/services/change-streamer/upstream-acker.d.ts +34 -0
  194. package/out/zero-cache/src/services/change-streamer/upstream-acker.d.ts.map +1 -0
  195. package/out/zero-cache/src/services/change-streamer/upstream-acker.js +86 -0
  196. package/out/zero-cache/src/services/change-streamer/upstream-acker.js.map +1 -0
  197. package/out/zero-cache/src/services/life-cycle.d.ts +1 -1
  198. package/out/zero-cache/src/services/life-cycle.d.ts.map +1 -1
  199. package/out/zero-cache/src/services/life-cycle.js +3 -2
  200. package/out/zero-cache/src/services/life-cycle.js.map +1 -1
  201. package/out/zero-cache/src/services/litestream/commands.d.ts +12 -11
  202. package/out/zero-cache/src/services/litestream/commands.d.ts.map +1 -1
  203. package/out/zero-cache/src/services/litestream/commands.js +50 -140
  204. package/out/zero-cache/src/services/litestream/commands.js.map +1 -1
  205. package/out/zero-cache/src/services/litestream/config-v5.yml +42 -0
  206. package/out/zero-cache/src/services/litestream/metrics.d.ts +4 -4
  207. package/out/zero-cache/src/services/litestream/metrics.d.ts.map +1 -1
  208. package/out/zero-cache/src/services/litestream/metrics.js +7 -10
  209. package/out/zero-cache/src/services/litestream/metrics.js.map +1 -1
  210. package/out/zero-cache/src/services/litestream/vfs-watermark-poller.d.ts +57 -0
  211. package/out/zero-cache/src/services/litestream/vfs-watermark-poller.d.ts.map +1 -0
  212. package/out/zero-cache/src/services/litestream/vfs-watermark-poller.js +137 -0
  213. package/out/zero-cache/src/services/litestream/vfs-watermark-poller.js.map +1 -0
  214. package/out/zero-cache/src/services/replicator/change-log-cookies.d.ts +169 -0
  215. package/out/zero-cache/src/services/replicator/change-log-cookies.d.ts.map +1 -0
  216. package/out/zero-cache/src/services/replicator/change-log-cookies.js +434 -0
  217. package/out/zero-cache/src/services/replicator/change-log-cookies.js.map +1 -0
  218. package/out/zero-cache/src/services/replicator/change-log-db.d.ts +358 -0
  219. package/out/zero-cache/src/services/replicator/change-log-db.d.ts.map +1 -0
  220. package/out/zero-cache/src/services/replicator/change-log-db.js +477 -0
  221. package/out/zero-cache/src/services/replicator/change-log-db.js.map +1 -0
  222. package/out/zero-cache/src/services/replicator/change-log-stream-writer.d.ts +55 -0
  223. package/out/zero-cache/src/services/replicator/change-log-stream-writer.d.ts.map +1 -0
  224. package/out/zero-cache/src/services/replicator/change-log-stream-writer.js +150 -0
  225. package/out/zero-cache/src/services/replicator/change-log-stream-writer.js.map +1 -0
  226. package/out/zero-cache/src/services/replicator/change-processor.d.ts.map +1 -1
  227. package/out/zero-cache/src/services/replicator/change-processor.js +44 -17
  228. package/out/zero-cache/src/services/replicator/change-processor.js.map +1 -1
  229. package/out/zero-cache/src/services/replicator/incremental-sync.d.ts +1 -1
  230. package/out/zero-cache/src/services/replicator/incremental-sync.d.ts.map +1 -1
  231. package/out/zero-cache/src/services/replicator/incremental-sync.js +11 -4
  232. package/out/zero-cache/src/services/replicator/incremental-sync.js.map +1 -1
  233. package/out/zero-cache/src/services/replicator/replicator.d.ts +1 -1
  234. package/out/zero-cache/src/services/replicator/replicator.d.ts.map +1 -1
  235. package/out/zero-cache/src/services/replicator/replicator.js +2 -2
  236. package/out/zero-cache/src/services/replicator/replicator.js.map +1 -1
  237. package/out/zero-cache/src/services/replicator/schema/backfilling.d.ts +119 -0
  238. package/out/zero-cache/src/services/replicator/schema/backfilling.d.ts.map +1 -0
  239. package/out/zero-cache/src/services/replicator/schema/backfilling.js +214 -0
  240. package/out/zero-cache/src/services/replicator/schema/backfilling.js.map +1 -0
  241. package/out/zero-cache/src/services/replicator/schema/change-log.d.ts +3 -3
  242. package/out/zero-cache/src/services/replicator/schema/column-metadata.js +1 -1
  243. package/out/zero-cache/src/services/replicator/schema/column-metadata.js.map +1 -1
  244. package/out/zero-cache/src/services/replicator/schema/replication-state.d.ts +1 -1
  245. package/out/zero-cache/src/services/replicator/schema/replication-state.d.ts.map +1 -1
  246. package/out/zero-cache/src/services/replicator/schema/replication-state.js +9 -5
  247. package/out/zero-cache/src/services/replicator/schema/replication-state.js.map +1 -1
  248. package/out/zero-cache/src/services/replicator/sqlite-change-log-observability.d.ts +131 -0
  249. package/out/zero-cache/src/services/replicator/sqlite-change-log-observability.d.ts.map +1 -0
  250. package/out/zero-cache/src/services/replicator/sqlite-change-log-observability.js +413 -0
  251. package/out/zero-cache/src/services/replicator/sqlite-change-log-observability.js.map +1 -0
  252. package/out/zero-cache/src/services/replicator/sqlite-change-log-purger.d.ts +120 -0
  253. package/out/zero-cache/src/services/replicator/sqlite-change-log-purger.d.ts.map +1 -0
  254. package/out/zero-cache/src/services/replicator/sqlite-change-log-purger.js +283 -0
  255. package/out/zero-cache/src/services/replicator/sqlite-change-log-purger.js.map +1 -0
  256. package/out/zero-cache/src/services/replicator/write-worker.js +9 -6
  257. package/out/zero-cache/src/services/replicator/write-worker.js.map +1 -1
  258. package/out/zero-cache/src/services/run-ast.d.ts.map +1 -1
  259. package/out/zero-cache/src/services/run-ast.js +2 -1
  260. package/out/zero-cache/src/services/run-ast.js.map +1 -1
  261. package/out/zero-cache/src/services/running-state.d.ts +1 -1
  262. package/out/zero-cache/src/services/running-state.d.ts.map +1 -1
  263. package/out/zero-cache/src/services/running-state.js +1 -0
  264. package/out/zero-cache/src/services/running-state.js.map +1 -1
  265. package/out/zero-cache/src/services/view-syncer/e2e-serving-lag.d.ts +9 -0
  266. package/out/zero-cache/src/services/view-syncer/e2e-serving-lag.d.ts.map +1 -1
  267. package/out/zero-cache/src/services/view-syncer/e2e-serving-lag.js +9 -0
  268. package/out/zero-cache/src/services/view-syncer/e2e-serving-lag.js.map +1 -1
  269. package/out/zero-cache/src/services/view-syncer/pipeline-driver.d.ts.map +1 -1
  270. package/out/zero-cache/src/services/view-syncer/pipeline-driver.js +18 -3
  271. package/out/zero-cache/src/services/view-syncer/pipeline-driver.js.map +1 -1
  272. package/out/zero-cache/src/services/view-syncer/view-syncer.d.ts +11 -1
  273. package/out/zero-cache/src/services/view-syncer/view-syncer.d.ts.map +1 -1
  274. package/out/zero-cache/src/services/view-syncer/view-syncer.js +48 -7
  275. package/out/zero-cache/src/services/view-syncer/view-syncer.js.map +1 -1
  276. package/out/zero-cache/src/types/processes.d.ts +1 -2
  277. package/out/zero-cache/src/types/processes.d.ts.map +1 -1
  278. package/out/zero-cache/src/types/processes.js +1 -25
  279. package/out/zero-cache/src/types/processes.js.map +1 -1
  280. package/out/zero-cache/src/types/streams.d.ts +10 -0
  281. package/out/zero-cache/src/types/streams.d.ts.map +1 -1
  282. package/out/zero-cache/src/types/streams.js +25 -4
  283. package/out/zero-cache/src/types/streams.js.map +1 -1
  284. package/out/zero-cache/src/workers/connection.d.ts +1 -0
  285. package/out/zero-cache/src/workers/connection.d.ts.map +1 -1
  286. package/out/zero-cache/src/workers/connection.js +25 -3
  287. package/out/zero-cache/src/workers/connection.js.map +1 -1
  288. package/out/zero-cache/src/workers/replicator.d.ts +25 -0
  289. package/out/zero-cache/src/workers/replicator.d.ts.map +1 -1
  290. package/out/zero-cache/src/workers/replicator.js +33 -1
  291. package/out/zero-cache/src/workers/replicator.js.map +1 -1
  292. package/out/zero-cache/src/workers/syncer.d.ts +12 -0
  293. package/out/zero-cache/src/workers/syncer.d.ts.map +1 -1
  294. package/out/zero-cache/src/workers/syncer.js +75 -0
  295. package/out/zero-cache/src/workers/syncer.js.map +1 -1
  296. package/out/zero-client/src/client/version.js +1 -1
  297. package/out/zero-schema/src/builder/table-builder.d.ts +23 -0
  298. package/out/zero-schema/src/builder/table-builder.d.ts.map +1 -1
  299. package/out/zero-schema/src/builder/table-builder.js +18 -0
  300. package/out/zero-schema/src/builder/table-builder.js.map +1 -1
  301. package/out/zero-types/src/schema.d.ts +11 -0
  302. package/out/zero-types/src/schema.d.ts.map +1 -1
  303. package/out/zql/src/query/query-impl.d.ts +2 -2
  304. package/out/zql/src/query/query-impl.d.ts.map +1 -1
  305. package/out/zql/src/query/query-impl.js.map +1 -1
  306. package/out/zql/src/query/query.d.ts +83 -14
  307. package/out/zql/src/query/query.d.ts.map +1 -1
  308. package/out/zql/src/query/static-query.d.ts +1 -1
  309. package/out/zql/src/query/static-query.d.ts.map +1 -1
  310. package/out/zqlite/src/resolve-scalar-subqueries.d.ts +15 -0
  311. package/out/zqlite/src/resolve-scalar-subqueries.d.ts.map +1 -1
  312. package/out/zqlite/src/resolve-scalar-subqueries.js +20 -13
  313. package/out/zqlite/src/resolve-scalar-subqueries.js.map +1 -1
  314. package/package.json +2 -2
  315. package/out/replicache/src/db/index.js +0 -91
  316. package/out/replicache/src/db/index.js.map +0 -1
  317. package/out/replicache/src/lazy.d.ts +0 -2
  318. package/out/replicache/src/lazy.d.ts.map +0 -1
  319. package/out/replicache/src/lazy.js +0 -12
  320. package/out/replicache/src/lazy.js.map +0 -1
  321. package/out/zero-cache/src/server/backup-watermark-reader.js +0 -35
  322. package/out/zero-cache/src/server/backup-watermark-reader.js.map +0 -1
  323. package/out/zero-cache/src/services/change-streamer/litestream3-backup-monitor.d.ts.map +0 -1
  324. package/out/zero-cache/src/services/change-streamer/litestream3-backup-monitor.js.map +0 -1
  325. package/out/zero-cache/src/services/change-streamer/replica-monitor.d.ts +0 -16
  326. package/out/zero-cache/src/services/change-streamer/replica-monitor.d.ts.map +0 -1
  327. package/out/zero-cache/src/services/change-streamer/replica-monitor.js +0 -54
  328. package/out/zero-cache/src/services/change-streamer/replica-monitor.js.map +0 -1
  329. package/out/zero-cache/src/services/change-streamer/vfs-backup-monitor.d.ts +0 -25
  330. package/out/zero-cache/src/services/change-streamer/vfs-backup-monitor.d.ts.map +0 -1
  331. package/out/zero-cache/src/services/change-streamer/vfs-backup-monitor.js +0 -159
  332. package/out/zero-cache/src/services/change-streamer/vfs-backup-monitor.js.map +0 -1
  333. package/out/zero-cache/src/services/litestream/vfs-watermark-reader.d.ts +0 -44
  334. package/out/zero-cache/src/services/litestream/vfs-watermark-reader.d.ts.map +0 -1
  335. package/out/zero-cache/src/services/litestream/vfs-watermark-reader.js +0 -65
  336. package/out/zero-cache/src/services/litestream/vfs-watermark-reader.js.map +0 -1
  337. package/out/zero-cache/src/services/litestream/vfs-watermark-worker-source.d.ts +0 -11
  338. package/out/zero-cache/src/services/litestream/vfs-watermark-worker-source.d.ts.map +0 -1
  339. package/out/zero-cache/src/services/litestream/vfs-watermark-worker-source.js +0 -74
  340. package/out/zero-cache/src/services/litestream/vfs-watermark-worker-source.js.map +0 -1
  341. package/out/zero-cache/src/services/litestream/vfs-watermark-worker.d.ts +0 -42
  342. package/out/zero-cache/src/services/litestream/vfs-watermark-worker.d.ts.map +0 -1
  343. package/out/zero-cache/src/services/litestream/vfs-watermark-worker.js +0 -117
  344. package/out/zero-cache/src/services/litestream/vfs-watermark-worker.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"scan-iterator.js","names":["#iter","#options","#dbDelegateOptions","#onLimitKey","#newIterator","#it"],"sources":["../../../../replicache/src/scan-iterator.ts"],"sourcesContent":["import {greaterThan} from 'compare-utf8';\nimport type {ReadonlyJSONValue} from '../../shared/src/json.ts';\nimport {asyncIterableToArray} from './async-iterable-to-array.ts';\nimport {type IndexKey, encodeIndexScanKey} from './db/index.ts';\nimport type {IterableUnion} from './iterable-union.ts';\nimport {\n type KeyTypeForScanOptions,\n type ScanIndexOptions,\n type ScanOptionIndexedStartKey,\n type ScanOptions,\n isScanIndexOptions,\n normalizeScanOptionIndexedStartKey,\n} from './scan-options.ts';\nimport {type Closed, throwIfClosed} from './transaction-closed-error.ts';\nimport {type EntryForOptions, fromKeyForNonIndexScan} from './transactions.ts';\n\ntype ScanKey = string | IndexKey;\n\ntype ToValue<Options extends ScanOptions, Value> = (\n entry: EntryForOptions<Options, ReadonlyJSONValue>,\n) => Value;\n\n/**\n * This class is used for the results of {@link ReadTransaction.scan | scan}. It\n * implements `AsyncIterable<JSONValue>` which allows you to use it in a `for\n * await` loop. There are also methods to iterate over the {@link keys},\n * {@link entries} or {@link values}.\n */\nexport class ScanResultImpl<\n Options extends ScanOptions,\n V,\n> implements ScanResult<KeyTypeForScanOptions<Options>, V> {\n readonly #iter: AsyncIterable<EntryForOptions<Options, ReadonlyJSONValue>>;\n readonly #options: Options;\n readonly #dbDelegateOptions: Closed;\n readonly #onLimitKey: (inclusiveLimitKey: string) => void;\n\n constructor(\n iter: AsyncIterable<EntryForOptions<Options, ReadonlyJSONValue>>,\n options: Options,\n dbDelegateOptions: Closed,\n onLimitKey: (inclusiveLimitKey: string) => void,\n ) {\n this.#iter = iter;\n this.#options = options;\n this.#dbDelegateOptions = dbDelegateOptions;\n this.#onLimitKey = onLimitKey;\n }\n\n /** The default AsyncIterable. This is the same as {@link values}. */\n [Symbol.asyncIterator](): AsyncIterableIteratorToArray<V> {\n return this.values();\n }\n\n /** Async iterator over the values of the {@link ReadTransaction.scan | scan} call. */\n values(): AsyncIterableIteratorToArray<V> {\n return new AsyncIterableIteratorToArrayWrapperImpl(\n this.#newIterator(e => e[1] as V),\n );\n }\n\n /**\n * Async iterator over the keys of the {@link ReadTransaction.scan | scan}\n * call. If the {@link ReadTransaction.scan | scan} is over an index the key\n * is a tuple of `[secondaryKey: string, primaryKey]`\n */\n keys(): AsyncIterableIteratorToArray<KeyTypeForScanOptions<Options>> {\n type K = KeyTypeForScanOptions<Options>;\n return new AsyncIterableIteratorToArrayWrapperImpl<K>(\n this.#newIterator<K>(e => e[0] as K),\n );\n }\n\n /**\n * Async iterator over the entries of the {@link ReadTransaction.scan | scan}\n * call. An entry is a tuple of key values. If the\n * {@link ReadTransaction.scan | scan} is over an index the key is a tuple of\n * `[secondaryKey: string, primaryKey]`\n */\n entries(): AsyncIterableIteratorToArray<\n readonly [KeyTypeForScanOptions<Options>, V]\n > {\n type Key = KeyTypeForScanOptions<Options>;\n type Entry = readonly [Key, V];\n return new AsyncIterableIteratorToArrayWrapperImpl(\n this.#newIterator<Entry>(e => [e[0] as Key, e[1] as V]),\n );\n }\n\n /** Returns all the values as an array. Same as `values().toArray()` */\n toArray(): Promise<V[]> {\n return this.values().toArray();\n }\n\n #newIterator<T>(toValue: ToValue<Options, T>): AsyncIterableIterator<T> {\n return scanIterator(\n toValue,\n this.#iter,\n this.#options,\n this.#dbDelegateOptions,\n this.#onLimitKey,\n );\n }\n}\n\nexport interface ScanResult<K extends ScanKey, V> extends AsyncIterable<V> {\n /** The default AsyncIterable. This is the same as {@link values}. */\n [Symbol.asyncIterator](): AsyncIterableIteratorToArray<V>;\n\n /** Async iterator over the values of the {@link ReadTransaction.scan | scan} call. */\n values(): AsyncIterableIteratorToArray<V>;\n\n /**\n * Async iterator over the keys of the {@link ReadTransaction.scan | scan}\n * call. If the {@link ReadTransaction.scan | scan} is over an index the key\n * is a tuple of `[secondaryKey: string, primaryKey]`\n */\n keys(): AsyncIterableIteratorToArray<K>;\n\n /**\n * Async iterator over the entries of the {@link ReadTransaction.scan | scan}\n * call. An entry is a tuple of key values. If the\n * {@link ReadTransaction.scan | scan} is over an index the key is a tuple of\n * `[secondaryKey: string, primaryKey]`\n */\n entries(): AsyncIterableIteratorToArray<readonly [K, V]>;\n\n /** Returns all the values as an array. Same as `values().toArray()` */\n toArray(): Promise<V[]>;\n}\n\n/**\n * An interface that adds a {@link toArray} method to `AsyncIterableIterator`.\n *\n * Usage:\n *\n * ```ts\n * const keys: string[] = await rep.scan().keys().toArray();\n * ```\n */\nexport interface AsyncIterableIteratorToArray<\n V,\n> extends AsyncIterableIterator<V> {\n toArray(): Promise<V[]>;\n}\n\nclass AsyncIterableIteratorToArrayWrapperImpl<\n V,\n> implements AsyncIterableIterator<V> {\n readonly #it: AsyncIterableIterator<V>;\n\n constructor(it: AsyncIterableIterator<V>) {\n this.#it = it;\n }\n\n next() {\n return this.#it.next();\n }\n\n [Symbol.asyncIterator](): AsyncIterableIterator<V> {\n return this.#it[Symbol.asyncIterator]();\n }\n\n toArray(): Promise<V[]> {\n return asyncIterableToArray(this.#it);\n }\n}\n\nasync function* scanIterator<Options extends ScanOptions, Value>(\n toValue: ToValue<Options, Value>,\n iter: AsyncIterable<EntryForOptions<Options, ReadonlyJSONValue>>,\n options: Options,\n closed: Closed,\n onLimitKey: (inclusiveLimitKey: string) => void,\n): AsyncIterableIterator<Value> {\n throwIfClosed(closed);\n\n let {limit = Infinity} = options;\n const {prefix = ''} = options;\n let exclusive = options.start?.exclusive;\n\n const isIndexScan = isScanIndexOptions(options);\n\n // iter has already been moved to the first entry\n for await (const entry of iter) {\n const key = entry[0];\n const keyToMatch: string = isIndexScan ? key[0] : (key as string);\n if (!keyToMatch.startsWith(prefix)) {\n return;\n }\n\n if (exclusive) {\n exclusive = true;\n if (isIndexScan) {\n // oxlint-disable-next-line @typescript-eslint/no-non-null-assertion\n if (shouldSkipIndexScan(key as IndexKey, options.start!.key)) {\n continue;\n }\n } else {\n // oxlint-disable-next-line @typescript-eslint/no-non-null-assertion\n if (shouldSkipNonIndexScan(key as string, options.start!.key)) {\n continue;\n }\n }\n }\n\n yield toValue(entry);\n\n if (--limit === 0) {\n // We do not do the limit optimization for index scans in subscriptions.\n if (!isIndexScan) {\n onLimitKey(key as string);\n }\n return;\n }\n }\n}\n\nfunction shouldSkipIndexScan(\n key: IndexKey,\n startKey: ScanOptionIndexedStartKey,\n): boolean {\n const [secondaryStartKey, primaryStartKey] =\n normalizeScanOptionIndexedStartKey(startKey);\n const [secondaryKey, primaryKey] = normalizeScanOptionIndexedStartKey(key);\n if (secondaryKey !== secondaryStartKey) {\n return false;\n }\n if (primaryStartKey === undefined) {\n return true;\n }\n return primaryKey === primaryStartKey;\n}\n\nfunction shouldSkipNonIndexScan(key: string, startKey: string): boolean {\n return key === startKey;\n}\n\nexport type Entry<V> = readonly [key: string, value: V];\n\n/**\n * This is called when doing a {@link ReadTransaction.scan | scan} without an\n * `indexName`.\n *\n * @param fromKey The `fromKey` is computed by `scan` and is the key of the\n * first entry to return in the iterator. It is based on `prefix` and\n * `start.key` of the {@link ScanNoIndexOptions}.\n */\nexport type GetScanIterator = (\n fromKey: string,\n) => IterableUnion<Entry<ReadonlyJSONValue>>;\n\n/**\n * When using {@link makeScanResult} this is the type used for the function called when doing a {@link ReadTransaction.scan | scan} with an\n * `indexName`.\n *\n * @param indexName The name of the index we are scanning over.\n * @param fromSecondaryKey The `fromSecondaryKey` is computed by `scan` and is\n * the secondary key of the first entry to return in the iterator. It is based\n * on `prefix` and `start.key` of the {@link ScanIndexOptions}.\n * @param fromPrimaryKey The `fromPrimaryKey` is computed by `scan` and is the\n * primary key of the first entry to return in the iterator. It is based on\n * `prefix` and `start.key` of the {@link ScanIndexOptions}.\n */\nexport type GetIndexScanIterator = (\n indexName: string,\n fromSecondaryKey: string,\n fromPrimaryKey: string | undefined,\n) => IterableUnion<readonly [key: IndexKey, value: ReadonlyJSONValue]>;\n\n/**\n * A helper function that makes it easier to implement {@link ReadTransaction.scan}\n * with a custom backend.\n *\n * If you are implementing a custom backend and have an in memory pending async\n * iterable we provide two helper functions to make it easier to merge these\n * together. {@link mergeAsyncIterables} and {@link filterAsyncIterable}.\n *\n * For example:\n *\n * ```ts\n * const scanResult = makeScanResult(\n * options,\n * options.indexName\n * ? () => {\n * throw Error('not implemented');\n * }\n * : fromKey => {\n * const persisted: AsyncIterable<Entry<ReadonlyJSONValue>> = ...;\n * const pending: AsyncIterable<Entry<ReadonlyJSONValue | undefined>> = ...;\n * const iter = await mergeAsyncIterables(persisted, pending);\n * const filteredIter = await filterAsyncIterable(\n * iter,\n * entry => entry[1] !== undefined,\n * );\n * return filteredIter;\n * },\n * );\n * ```\n */\nexport function makeScanResult<Options extends ScanOptions>(\n options: Options,\n getScanIterator: Options extends ScanIndexOptions\n ? GetIndexScanIterator\n : GetScanIterator,\n): ScanResult<KeyTypeForScanOptions<Options>, ReadonlyJSONValue> {\n type AsyncIter = AsyncIterable<EntryForOptions<Options, ReadonlyJSONValue>>;\n\n if (isScanIndexOptions(options)) {\n const [fromSecondaryKey, fromPrimaryKey] = fromKeyForIndexScan(options);\n return new ScanResultImpl(\n (getScanIterator as GetIndexScanIterator)(\n options.indexName,\n fromSecondaryKey,\n fromPrimaryKey,\n ) as AsyncIter,\n options,\n {closed: false},\n _ => {\n // noop\n },\n );\n }\n const fromKey = fromKeyForNonIndexScan(options);\n return new ScanResultImpl(\n (getScanIterator as GetScanIterator)(fromKey) as AsyncIter,\n options,\n {closed: false},\n _ => {\n // noop\n },\n );\n}\n\nexport function fromKeyForIndexScan(\n options: ScanIndexOptions,\n): readonly [secondary: string, primary?: string | undefined] {\n const {prefix, start} = options;\n const prefixNormalized: [secondary: string, primary?: string | undefined] = [\n prefix ?? '',\n undefined,\n ];\n\n if (!start) {\n return prefixNormalized;\n }\n\n const startKeyNormalized = normalizeScanOptionIndexedStartKey(start.key);\n if (greaterThan(startKeyNormalized[0], prefixNormalized[0])) {\n return startKeyNormalized;\n }\n if (\n startKeyNormalized[0] === prefixNormalized[0] &&\n startKeyNormalized[1] !== undefined\n ) {\n return startKeyNormalized;\n }\n\n return prefixNormalized;\n}\n\nexport function fromKeyForIndexScanInternal(options: ScanIndexOptions): string {\n const {prefix, start} = options;\n let prefix2 = '';\n if (prefix !== undefined) {\n prefix2 = encodeIndexScanKey(prefix, undefined);\n }\n if (!start) {\n return prefix2;\n }\n\n const {key} = start;\n const [secondary, primary] = normalizeScanOptionIndexedStartKey(key);\n const startKey = encodeIndexScanKey(secondary, primary);\n\n if (greaterThan(startKey, prefix2)) {\n return startKey;\n }\n\n return prefix2;\n}\n"],"mappings":";;;;;;;;;;;;;AA4BA,IAAa,iBAAb,MAG2D;CACzD;CACA;CACA;CACA;CAEA,YACE,MACA,SACA,mBACA,YACA;EACA,KAAKA,QAAQ;EACb,KAAKC,WAAW;EAChB,KAAKC,qBAAqB;EAC1B,KAAKC,cAAc;CACrB;;CAGA,CAAC,OAAO,iBAAkD;EACxD,OAAO,KAAK,OAAO;CACrB;;CAGA,SAA0C;EACxC,OAAO,IAAI,wCACT,KAAKC,cAAa,MAAK,EAAE,EAAO,CAClC;CACF;;;;;;CAOA,OAAqE;EAEnE,OAAO,IAAI,wCACT,KAAKA,cAAgB,MAAK,EAAE,EAAO,CACrC;CACF;;;;;;;CAQA,UAEE;EAGA,OAAO,IAAI,wCACT,KAAKA,cAAoB,MAAK,CAAC,EAAE,IAAW,EAAE,EAAO,CAAC,CACxD;CACF;;CAGA,UAAwB;EACtB,OAAO,KAAK,OAAO,EAAE,QAAQ;CAC/B;CAEA,aAAgB,SAAwD;EACtE,OAAO,aACL,SACA,KAAKJ,OACL,KAAKC,UACL,KAAKC,oBACL,KAAKC,WACP;CACF;AACF;AA2CA,IAAM,0CAAN,MAEsC;CACpC;CAEA,YAAY,IAA8B;EACxC,KAAKE,MAAM;CACb;CAEA,OAAO;EACL,OAAO,KAAKA,IAAI,KAAK;CACvB;CAEA,CAAC,OAAO,iBAA2C;EACjD,OAAO,KAAKA,IAAI,OAAO,eAAe;CACxC;CAEA,UAAwB;EACtB,OAAO,qBAAqB,KAAKA,GAAG;CACtC;AACF;AAEA,gBAAgB,aACd,SACA,MACA,SACA,QACA,YAC8B;CAC9B,cAAc,MAAM;CAEpB,IAAI,EAAC,QAAQ,aAAY;CACzB,MAAM,EAAC,SAAS,OAAM;CACtB,IAAI,YAAY,QAAQ,OAAO;CAE/B,MAAM,cAAc,mBAAmB,OAAO;CAG9C,WAAW,MAAM,SAAS,MAAM;EAC9B,MAAM,MAAM,MAAM;EAElB,IAAI,EADuB,cAAc,IAAI,KAAM,KACnC,WAAW,MAAM,GAC/B;EAGF,IAAI,WAAW;GACb,YAAY;GACZ,IAAI;QAEE,oBAAoB,KAAiB,QAAQ,MAAO,GAAG,GACzD;GAAA,OAIF,IAAI,uBAAuB,KAAe,QAAQ,MAAO,GAAG,GAC1D;EAGN;EAEA,MAAM,QAAQ,KAAK;EAEnB,IAAI,EAAE,UAAU,GAAG;GAEjB,IAAI,CAAC,aACH,WAAW,GAAa;GAE1B;EACF;CACF;AACF;AAEA,SAAS,oBACP,KACA,UACS;CACT,MAAM,CAAC,mBAAmB,mBACxB,mCAAmC,QAAQ;CAC7C,MAAM,CAAC,cAAc,cAAc,mCAAmC,GAAG;CACzE,IAAI,iBAAiB,mBACnB,OAAO;CAET,IAAI,oBAAoB,KAAA,GACtB,OAAO;CAET,OAAO,eAAe;AACxB;AAEA,SAAS,uBAAuB,KAAa,UAA2B;CACtE,OAAO,QAAQ;AACjB;AA6HA,SAAgB,4BAA4B,SAAmC;CAC7E,MAAM,EAAC,QAAQ,UAAS;CACxB,IAAI,UAAU;CACd,IAAI,WAAW,KAAA,GACb,UAAU,mBAAmB,QAAQ,KAAA,CAAS;CAEhD,IAAI,CAAC,OACH,OAAO;CAGT,MAAM,EAAC,QAAO;CACd,MAAM,CAAC,WAAW,WAAW,mCAAmC,GAAG;CACnE,MAAM,WAAW,mBAAmB,WAAW,OAAO;CAEtD,IAAI,YAAY,UAAU,OAAO,GAC/B,OAAO;CAGT,OAAO;AACT"}
1
+ {"version":3,"file":"scan-iterator.js","names":["#iter","#options","#dbDelegateOptions","#onLimitKey","#newIterator","#it"],"sources":["../../../../replicache/src/scan-iterator.ts"],"sourcesContent":["import {greaterThan} from 'compare-utf8';\nimport type {ReadonlyJSONValue} from '../../shared/src/json.ts';\nimport {asyncIterableToArray} from './async-iterable-to-array.ts';\nimport {type IndexKey, encodeIndexScanKey} from './db/index.ts';\nimport type {IterableUnion} from './iterable-union.ts';\nimport {\n type KeyTypeForScanOptions,\n type ScanIndexOptions,\n type ScanOptionIndexedStartKey,\n type ScanOptions,\n isScanIndexOptions,\n normalizeScanOptionIndexedStartKey,\n} from './scan-options.ts';\nimport {type Closed, throwIfClosed} from './transaction-closed-error.ts';\nimport {type EntryForOptions, fromKeyForNonIndexScan} from './transactions.ts';\n\ntype ScanKey = string | IndexKey;\n\ntype ToValue<Options extends ScanOptions, Value> = (\n entry: EntryForOptions<Options, ReadonlyJSONValue>,\n) => Value;\n\n/**\n * This class is used for the results of {@link ReadTransaction.scan | scan}. It\n * implements `AsyncIterable<JSONValue>` which allows you to use it in a `for\n * await` loop. There are also methods to iterate over the {@link keys},\n * {@link entries} or {@link values}.\n */\nexport class ScanResultImpl<\n Options extends ScanOptions,\n V,\n> implements ScanResult<KeyTypeForScanOptions<Options>, V> {\n readonly #iter: AsyncIterable<EntryForOptions<Options, ReadonlyJSONValue>>;\n readonly #options: Options;\n readonly #dbDelegateOptions: Closed;\n readonly #onLimitKey: (inclusiveLimitKey: string) => void;\n\n constructor(\n iter: AsyncIterable<EntryForOptions<Options, ReadonlyJSONValue>>,\n options: Options,\n dbDelegateOptions: Closed,\n onLimitKey: (inclusiveLimitKey: string) => void,\n ) {\n this.#iter = iter;\n this.#options = options;\n this.#dbDelegateOptions = dbDelegateOptions;\n this.#onLimitKey = onLimitKey;\n }\n\n /** The default AsyncIterable. This is the same as {@link values}. */\n [Symbol.asyncIterator](): AsyncIterableIteratorToArray<V> {\n return this.values();\n }\n\n /** Async iterator over the values of the {@link ReadTransaction.scan | scan} call. */\n values(): AsyncIterableIteratorToArray<V> {\n return new AsyncIterableIteratorToArrayWrapperImpl(\n this.#newIterator(e => e[1] as V),\n );\n }\n\n /**\n * Async iterator over the keys of the {@link ReadTransaction.scan | scan}\n * call. If the {@link ReadTransaction.scan | scan} is over an index the key\n * is a tuple of `[secondaryKey: string, primaryKey]`\n */\n keys(): AsyncIterableIteratorToArray<KeyTypeForScanOptions<Options>> {\n type K = KeyTypeForScanOptions<Options>;\n return new AsyncIterableIteratorToArrayWrapperImpl<K>(\n this.#newIterator<K>(e => e[0] as K),\n );\n }\n\n /**\n * Async iterator over the entries of the {@link ReadTransaction.scan | scan}\n * call. An entry is a tuple of key values. If the\n * {@link ReadTransaction.scan | scan} is over an index the key is a tuple of\n * `[secondaryKey: string, primaryKey]`\n */\n entries(): AsyncIterableIteratorToArray<\n readonly [KeyTypeForScanOptions<Options>, V]\n > {\n type Key = KeyTypeForScanOptions<Options>;\n type Entry = readonly [Key, V];\n return new AsyncIterableIteratorToArrayWrapperImpl(\n this.#newIterator<Entry>(e => [e[0] as Key, e[1] as V]),\n );\n }\n\n /** Returns all the values as an array. Same as `values().toArray()` */\n toArray(): Promise<V[]> {\n return this.values().toArray();\n }\n\n #newIterator<T>(toValue: ToValue<Options, T>): AsyncIterableIterator<T> {\n return scanIterator(\n toValue,\n this.#iter,\n this.#options,\n this.#dbDelegateOptions,\n this.#onLimitKey,\n );\n }\n}\n\nexport interface ScanResult<K extends ScanKey, V> extends AsyncIterable<V> {\n /** The default AsyncIterable. This is the same as {@link values}. */\n [Symbol.asyncIterator](): AsyncIterableIteratorToArray<V>;\n\n /** Async iterator over the values of the {@link ReadTransaction.scan | scan} call. */\n values(): AsyncIterableIteratorToArray<V>;\n\n /**\n * Async iterator over the keys of the {@link ReadTransaction.scan | scan}\n * call. If the {@link ReadTransaction.scan | scan} is over an index the key\n * is a tuple of `[secondaryKey: string, primaryKey]`\n */\n keys(): AsyncIterableIteratorToArray<K>;\n\n /**\n * Async iterator over the entries of the {@link ReadTransaction.scan | scan}\n * call. An entry is a tuple of key values. If the\n * {@link ReadTransaction.scan | scan} is over an index the key is a tuple of\n * `[secondaryKey: string, primaryKey]`\n */\n entries(): AsyncIterableIteratorToArray<readonly [K, V]>;\n\n /** Returns all the values as an array. Same as `values().toArray()` */\n toArray(): Promise<V[]>;\n}\n\n/**\n * An interface that adds a {@link toArray} method to `AsyncIterableIterator`.\n *\n * Usage:\n *\n * ```ts\n * const keys: string[] = await rep.scan().keys().toArray();\n * ```\n */\nexport interface AsyncIterableIteratorToArray<\n V,\n> extends AsyncIterableIterator<V> {\n toArray(): Promise<V[]>;\n}\n\nclass AsyncIterableIteratorToArrayWrapperImpl<\n V,\n> implements AsyncIterableIterator<V> {\n readonly #it: AsyncIterableIterator<V>;\n\n constructor(it: AsyncIterableIterator<V>) {\n this.#it = it;\n }\n\n next() {\n return this.#it.next();\n }\n\n [Symbol.asyncIterator](): AsyncIterableIterator<V> {\n return this.#it[Symbol.asyncIterator]();\n }\n\n toArray(): Promise<V[]> {\n return asyncIterableToArray(this.#it);\n }\n}\n\nasync function* scanIterator<Options extends ScanOptions, Value>(\n toValue: ToValue<Options, Value>,\n iter: AsyncIterable<EntryForOptions<Options, ReadonlyJSONValue>>,\n options: Options,\n closed: Closed,\n onLimitKey: (inclusiveLimitKey: string) => void,\n): AsyncIterableIterator<Value> {\n throwIfClosed(closed);\n\n let {limit = Infinity} = options;\n const {prefix = ''} = options;\n let exclusive = options.start?.exclusive;\n\n const isIndexScan = isScanIndexOptions(options);\n\n // iter has already been moved to the first entry\n for await (const entry of iter) {\n const key = entry[0];\n const keyToMatch: string = isIndexScan ? key[0] : (key as string);\n if (!keyToMatch.startsWith(prefix)) {\n return;\n }\n\n if (exclusive) {\n exclusive = true;\n if (isIndexScan) {\n // oxlint-disable-next-line @typescript-eslint/no-non-null-assertion\n if (shouldSkipIndexScan(key as IndexKey, options.start!.key)) {\n continue;\n }\n } else {\n // oxlint-disable-next-line @typescript-eslint/no-non-null-assertion\n if (shouldSkipNonIndexScan(key as string, options.start!.key)) {\n continue;\n }\n }\n }\n\n yield toValue(entry);\n\n if (--limit === 0) {\n // We do not do the limit optimization for index scans in subscriptions.\n if (!isIndexScan) {\n onLimitKey(key as string);\n }\n return;\n }\n }\n}\n\nfunction shouldSkipIndexScan(\n key: IndexKey,\n startKey: ScanOptionIndexedStartKey,\n): boolean {\n const [secondaryStartKey, primaryStartKey] =\n normalizeScanOptionIndexedStartKey(startKey);\n const [secondaryKey, primaryKey] = normalizeScanOptionIndexedStartKey(key);\n if (secondaryKey !== secondaryStartKey) {\n return false;\n }\n if (primaryStartKey === undefined) {\n return true;\n }\n return primaryKey === primaryStartKey;\n}\n\nfunction shouldSkipNonIndexScan(key: string, startKey: string): boolean {\n return key === startKey;\n}\n\nexport type Entry<V> = readonly [key: string, value: V];\n\n/**\n * This is called when doing a {@link ReadTransaction.scan | scan} without an\n * `indexName`.\n *\n * @param fromKey The `fromKey` is computed by `scan` and is the key of the\n * first entry to return in the iterator. It is based on `prefix` and\n * `start.key` of the {@link ScanNoIndexOptions}.\n */\nexport type GetScanIterator = (\n fromKey: string,\n) => IterableUnion<Entry<ReadonlyJSONValue>>;\n\n/**\n * When using {@link makeScanResult} this is the type used for the function called when doing a {@link ReadTransaction.scan | scan} with an\n * `indexName`.\n *\n * @param indexName The name of the index we are scanning over.\n * @param fromSecondaryKey The `fromSecondaryKey` is computed by `scan` and is\n * the secondary key of the first entry to return in the iterator. It is based\n * on `prefix` and `start.key` of the {@link ScanIndexOptions}.\n * @param fromPrimaryKey The `fromPrimaryKey` is computed by `scan` and is the\n * primary key of the first entry to return in the iterator. It is based on\n * `prefix` and `start.key` of the {@link ScanIndexOptions}.\n */\nexport type GetIndexScanIterator = (\n indexName: string,\n fromSecondaryKey: string,\n fromPrimaryKey: string | undefined,\n) => IterableUnion<readonly [key: IndexKey, value: ReadonlyJSONValue]>;\n\n/**\n * A helper function that makes it easier to implement {@link ReadTransaction.scan}\n * with a custom backend.\n *\n * If you are implementing a custom backend and have an in memory pending async\n * iterable we provide two helper functions to make it easier to merge these\n * together. {@link mergeAsyncIterables} and {@link filterAsyncIterable}.\n *\n * For example:\n *\n * ```ts\n * const scanResult = makeScanResult(\n * options,\n * options.indexName\n * ? () => {\n * throw Error('not implemented');\n * }\n * : fromKey => {\n * const persisted: AsyncIterable<Entry<ReadonlyJSONValue>> = ...;\n * const pending: AsyncIterable<Entry<ReadonlyJSONValue | undefined>> = ...;\n * const iter = await mergeAsyncIterables(persisted, pending);\n * const filteredIter = await filterAsyncIterable(\n * iter,\n * entry => entry[1] !== undefined,\n * );\n * return filteredIter;\n * },\n * );\n * ```\n */\nexport function makeScanResult<Options extends ScanOptions>(\n options: Options,\n getScanIterator: Options extends ScanIndexOptions\n ? GetIndexScanIterator\n : GetScanIterator,\n): ScanResult<KeyTypeForScanOptions<Options>, ReadonlyJSONValue> {\n type AsyncIter = AsyncIterable<EntryForOptions<Options, ReadonlyJSONValue>>;\n\n if (isScanIndexOptions(options)) {\n const [fromSecondaryKey, fromPrimaryKey] = fromKeyForIndexScan(options);\n return new ScanResultImpl(\n (getScanIterator as GetIndexScanIterator)(\n options.indexName,\n fromSecondaryKey,\n fromPrimaryKey,\n ) as AsyncIter,\n options,\n {closed: false},\n _ => {\n // noop\n },\n );\n }\n const fromKey = fromKeyForNonIndexScan(options);\n return new ScanResultImpl(\n (getScanIterator as GetScanIterator)(fromKey) as AsyncIter,\n options,\n {closed: false},\n _ => {\n // noop\n },\n );\n}\n\nexport function fromKeyForIndexScan(\n options: ScanIndexOptions,\n): readonly [secondary: string, primary?: string | undefined] {\n const {prefix, start} = options;\n const prefixNormalized: [secondary: string, primary?: string | undefined] = [\n prefix ?? '',\n undefined,\n ];\n\n if (!start) {\n return prefixNormalized;\n }\n\n const startKeyNormalized = normalizeScanOptionIndexedStartKey(start.key);\n if (greaterThan(startKeyNormalized[0], prefixNormalized[0])) {\n return startKeyNormalized;\n }\n if (\n startKeyNormalized[0] === prefixNormalized[0] &&\n startKeyNormalized[1] !== undefined\n ) {\n return startKeyNormalized;\n }\n\n return prefixNormalized;\n}\n\nexport function fromKeyForIndexScanInternal(options: ScanIndexOptions): string {\n const {prefix, start} = options;\n let prefix2 = '';\n if (prefix !== undefined) {\n prefix2 = encodeIndexScanKey(prefix, undefined);\n }\n if (!start) {\n return prefix2;\n }\n\n const {key} = start;\n const [secondary, primary] = normalizeScanOptionIndexedStartKey(key);\n const startKey = encodeIndexScanKey(secondary, primary);\n\n if (greaterThan(startKey, prefix2)) {\n return startKey;\n }\n\n return prefix2;\n}\n"],"mappings":";;;;;;;;;;;;AA4BA,IAAa,iBAAb,MAG2D;CACzD;CACA;CACA;CACA;CAEA,YACE,MACA,SACA,mBACA,YACA;EACA,KAAKA,QAAQ;EACb,KAAKC,WAAW;EAChB,KAAKC,qBAAqB;EAC1B,KAAKC,cAAc;CACrB;;CAGA,CAAC,OAAO,iBAAkD;EACxD,OAAO,KAAK,OAAO;CACrB;;CAGA,SAA0C;EACxC,OAAO,IAAI,wCACT,KAAKC,cAAa,MAAK,EAAE,EAAO,CAClC;CACF;;;;;;CAOA,OAAqE;EAEnE,OAAO,IAAI,wCACT,KAAKA,cAAgB,MAAK,EAAE,EAAO,CACrC;CACF;;;;;;;CAQA,UAEE;EAGA,OAAO,IAAI,wCACT,KAAKA,cAAoB,MAAK,CAAC,EAAE,IAAW,EAAE,EAAO,CAAC,CACxD;CACF;;CAGA,UAAwB;EACtB,OAAO,KAAK,OAAO,EAAE,QAAQ;CAC/B;CAEA,aAAgB,SAAwD;EACtE,OAAO,aACL,SACA,KAAKJ,OACL,KAAKC,UACL,KAAKC,oBACL,KAAKC,WACP;CACF;AACF;AA2CA,IAAM,0CAAN,MAEsC;CACpC;CAEA,YAAY,IAA8B;EACxC,KAAKE,MAAM;CACb;CAEA,OAAO;EACL,OAAO,KAAKA,IAAI,KAAK;CACvB;CAEA,CAAC,OAAO,iBAA2C;EACjD,OAAO,KAAKA,IAAI,OAAO,eAAe;CACxC;CAEA,UAAwB;EACtB,OAAO,qBAAqB,KAAKA,GAAG;CACtC;AACF;AAEA,gBAAgB,aACd,SACA,MACA,SACA,QACA,YAC8B;CAC9B,cAAc,MAAM;CAEpB,IAAI,EAAC,QAAQ,aAAY;CACzB,MAAM,EAAC,SAAS,OAAM;CACtB,IAAI,YAAY,QAAQ,OAAO;CAE/B,MAAM,cAAc,mBAAmB,OAAO;CAG9C,WAAW,MAAM,SAAS,MAAM;EAC9B,MAAM,MAAM,MAAM;EAElB,IAAI,EADuB,cAAc,IAAI,KAAM,KACnC,WAAW,MAAM,GAC/B;EAGF,IAAI,WAAW;GACb,YAAY;GACZ,IAAI;QAEE,oBAAoB,KAAiB,QAAQ,MAAO,GAAG,GACzD;GAAA,OAIF,IAAI,uBAAuB,KAAe,QAAQ,MAAO,GAAG,GAC1D;EAGN;EAEA,MAAM,QAAQ,KAAK;EAEnB,IAAI,EAAE,UAAU,GAAG;GAEjB,IAAI,CAAC,aACH,WAAW,GAAa;GAE1B;EACF;CACF;AACF;AAEA,SAAS,oBACP,KACA,UACS;CACT,MAAM,CAAC,mBAAmB,mBACxB,mCAAmC,QAAQ;CAC7C,MAAM,CAAC,cAAc,cAAc,mCAAmC,GAAG;CACzE,IAAI,iBAAiB,mBACnB,OAAO;CAET,IAAI,oBAAoB,KAAA,GACtB,OAAO;CAET,OAAO,eAAe;AACxB;AAEA,SAAS,uBAAuB,KAAa,UAA2B;CACtE,OAAO,QAAQ;AACjB"}
@@ -1,3 +1,4 @@
1
+ import './process-env.ts';
1
2
  import type { LogContext } from '@rocicorp/logger';
2
3
  import type { Enum } from '../../shared/src/enum.ts';
3
4
  import type { Diff, IndexDiff, InternalDiffOperation, NoIndexDiff } from './btree/node.ts';
@@ -1 +1 @@
1
- {"version":3,"file":"subscriptions.d.ts","sourceRoot":"","sources":["../../../../replicache/src/subscriptions.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"subscriptions.d.ts","sourceRoot":"","sources":["../../../../replicache/src/subscriptions.ts"],"names":[],"mappings":"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"}
@@ -1,7 +1,6 @@
1
1
  import { assert } from "../../shared/src/asserts.js";
2
2
  import { deepEqual } from "../../shared/src/json.js";
3
3
  import { binarySearch } from "../../shared/src/binary-search.js";
4
- import { decodeIndexKey } from "./db/index.js";
5
4
  import { SubscriptionTransactionWrapper } from "./transactions.js";
6
5
  import { compareUTF8, greaterThan, lessThan, lessThanEq } from "compare-utf8";
7
6
  //#region ../replicache/src/subscriptions.ts
@@ -90,7 +89,6 @@ var WatchSubscription = class {
90
89
  else break;
91
90
  return kind === 0 || newDiff.length > 0 ? newDiff : void 0;
92
91
  };
93
- if (this.#indexName) return invoke(this.#indexName, this.#prefix, (diff) => diff.key[0], (internalDiff) => convertDiffValues(internalDiff, decodeIndexKey));
94
92
  return invoke(void 0, this.#prefix, (diff) => diff.key, (internalDiff) => convertDiffValues(internalDiff, (k) => k));
95
93
  }
96
94
  matches(diffs) {
@@ -212,13 +210,7 @@ function scanInfoMatchesKey(scanInfo, changeIndexName, changedKey) {
212
210
  return true;
213
211
  }
214
212
  if (!prefix && !startKey && !startSecondaryKey) return true;
215
- const [changedKeySecondary, changedKeyPrimary] = decodeIndexKey(changedKey);
216
- if (prefix) {
217
- if (!changedKeySecondary.startsWith(prefix)) return false;
218
- }
219
- if (startSecondaryKey && (startExclusive && lessThanEq(changedKeySecondary, startSecondaryKey) || lessThan(changedKeySecondary, startSecondaryKey))) return false;
220
- if (startKey && (startExclusive && lessThanEq(changedKeyPrimary, startKey) || lessThan(changedKeyPrimary, startKey))) return false;
221
- return true;
213
+ return false;
222
214
  }
223
215
  function isKeyPastInclusiveLimit(scanInfo, changedKey) {
224
216
  const { inclusiveLimitKey } = scanInfo;
@@ -229,7 +221,7 @@ function* subscriptionsForDiffs(subscriptions, diffs) {
229
221
  }
230
222
  function watcherMatchesDiff(diff, prefix, indexName) {
231
223
  if (prefix === "") return true;
232
- const compareKey = indexName ? (diffOp) => decodeIndexKey(diffOp.key)[0] : (diffOp) => diffOp.key;
224
+ const compareKey = (diffOp) => diffOp.key;
233
225
  const i = diffBinarySearch(diff, prefix, compareKey);
234
226
  return i < diff.length && compareKey(diff[i]).startsWith(prefix);
235
227
  }
@@ -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":";;;;;;AAiDA,IAAM,2BAAgC,IAAI,IAAI;AAE9C,IAAM,uBAAuB,OAAO;AAGpC,IAAa,mBAAb,MAA4D;CAC1D;CACA;CACA,aAAuC;CACvC,QAAQ;CACR,SAAoD,CAAC;CAErD;CACA;CACA;CAEA,YACE,MACA,QACA,SACA,QAEA,UAAmC,WACnC;EACA,KAAKA,QAAQ;EACb,KAAKC,UAAU;EACf,KAAK,UAAU;EACf,KAAK,SAAS;EACd,KAAKC,WAAW;CAClB;CAEA,qBAAqB,WAA4B;EAC/C,KAAK,MAAM,QAAQ,KAAKC,QACtB,IAAI,KAAK,QAAQ,cAAc,WAC7B,OAAO;EAGX,OAAO;CACT;CAEA,OACE,IACA,OACA,QACY;EACZ,OAAO,KAAKH,MAAM,EAAE;CACtB;CAEA,QAAQ,OAA0B;EAChC,KAAK,MAAM,CAAC,WAAW,SAAS,OAC9B,IAAI,wBAAwB,KAAKI,OAAO,KAAKD,QAAQ,WAAW,IAAI,GAClE,OAAO;EAIX,OAAO;CACT;CAEA,WACE,MACA,OACM;EACN,KAAKC,QAAQ;EACb,KAAKD,SAAS;CAChB;CAEA,OAAO,QAAiB;EACtB,IACE,KAAKE,eAAe,wBACpB,CAAC,KAAKH,SAAS,KAAKG,YAAY,MAAM,GACtC;GACA,KAAKA,aAAa;GAClB,KAAKJ,QAAQ,MAAM;EACrB;CACF;AACF;AAgEA,IAAa,oBAAb,MAAyE;CACvE;CACA;CACA;CACA;CAEA,UAA2D,KAAA;CAC3D,SAA4C,KAAA;CAE5C,YAAY,UAAyB,SAAwB;EAC3D,KAAKK,YAAY;EACjB,KAAKC,UAAU,SAAS,UAAU;EAClC,KAAKC,aAAc,SAA+B;EAClD,KAAKC,4BAA4B,SAAS,4BAA4B;CACxE;CAEA,qBAAqB,WAA4B;EAC/C,OAAO,KAAKD,eAAe;CAC7B;CAEA,OAAO,QAAgC;EACrC,IAAI,WAAW,KAAA,GACb,KAAKF,UAAU,MAAM;CAEzB;CAEA,OACE,IACA,MACA,OAC2B;EAC3B,MAAM,SAAS,OACb,WACA,QACA,YACA,wBAGuD;GACvD,IAAI;GACJ,IAAI,SAAS,GAAuB;IAClC,IAAI,CAAC,KAAKG,2BAGR;IAIF,OACE,UAAU,KAAA,GACV,+CACF;IAEA,MAAM,UAAgC,CAAC;IACvC,WAAW,MAAM,SAAS,GAAG,KAAK;KAAC;KAAQ;IAAS,CAAC,EAAE,QAAQ,GAC7D,QAAQ,KAAK;KACX,IAAI;KACJ,KAAK,MAAM;KACX,UAAU,MAAM;IAClB,CAAC;IAEH,OAAO;GACT,OAAO;IACL,OAAO,OAAO,kDAAkD;IAEhE,OAAO,oBADW,MAAM,IAAI,aAAa,EAAE,KAAK,CAAC,CACb;GACtC;GACA,MAAM,UAAgC,CAAC;GACvC,MAAM,EAAC,WAAU;GACjB,KACE,IAAI,IAAI,iBAAiB,MAAM,QAAQ,UAAU,GACjD,IAAI,QACJ,KAEA,IAAI,WAAW,KAAK,EAAE,EAAE,WAAW,MAAM,GACvC,QAAQ,KAAK,KAAK,EAAE;QAEpB;GAKJ,OAAO,SAAS,KAAyB,QAAQ,SAAS,IACtD,UACA,KAAA;EACN;EAWA,OAAO,OACL,KAAA,GACA,KAAKF,UACL,SAAQ,KAAK,MACb,iBAAgB,kBAAkB,eAAc,MAAK,CAAC,CACxD;CACF;CAEA,QAAQ,OAA0B;EAChC,MAAM,OAAO,MAAM,IAAI,KAAKC,cAAc,EAAE;EAC5C,IAAI,SAAS,KAAA,GACX,OAAO;EAGT,OAAO,mBAAmB,MAAM,KAAKD,SAAS,KAAKC,UAAU;CAC/D;CAEA,WACE,OACA,QACM,CAER;AACF;AAEA,SAAS,kBACP,MACA,YACsB;CACtB,OAAO,KAAK,KAAI,OAAM;EACpB,MAAM,MAAM,WAAW,GAAG,GAAG;EAC7B,QAAQ,GAAG,IAAX;GACE,KAAK,OACH,OAAO;IACL,IAAI;IACJ;IACA,UAAU,GAAG;GACf;GACF,KAAK,UACH,OAAO;IACL,IAAI;IACJ;IACA,UAAU,GAAG;IACb,UAAU,GAAG;GACf;GACF,KAAK,OACH,OAAO;IACL,IAAI;IACJ;IACA,UAAU,GAAG;GACf;EACJ;CACF,CAAC;AACH;AAwCA,IAAa,2BAAb,MAAsE;CACpE,iCAA2C,IAAI,IAAI;CACnD,wCAAkD,IAAI,IAAI;CAC1D;CACA;CACA,6BAA6B;CAC7B;CAEA,YACE,eACA,IACA,QACA;EACA,KAAKI,iBAAiB;EACtB,KAAKC,MAAM;EACX,KAAKC,UAAU;CACjB;CAEA,IAAO,cAA2C;EAChD,KAAKJ,eAAe,IAAI,YAAmC;EAC3D,KAAUK,gCACR,YACF;EACA,aACE,KAAKL,eAAe,OAAO,YAAmC;CAClE;CAEA,QAAc;EACZ,KAAK,MAAM,gBAAgB,KAAKA,gBAC9B,aAAa,SAAS;EAExB,KAAKA,eAAe,MAAM;CAC5B;CAEA,KAAK,OAAgC;EACnC,MAAM,gBAAgB,sBAAsB,KAAKA,gBAAgB,KAAK;EACtE,OAAO,KAAKM,mBAAmB,eAAe,GAAoB,KAAK;CACzE;CAEA,MAAMA,mBACJ,eACA,MACA,OACA;EACA,IAAI,KAAKF,QAAQ,SACf;EAGF,MAAM,OAAO,CAAC,GAAG,aAAa;EAC9B,IAAI,KAAK,WAAW,GAClB;EAIF,MAAM,UAAU,MAAM,KAAKF,gBAAe,OACxC,QAAQ,WACN,KAAK,IAAI,OAAM,MAAK;GAClB,MAAM,MAAM,IAAI,+BAA+B,EAAE;GACjD,IAAI;IACF,OAAO,MAAM,EAAE,OAAO,KAAK,MAAM,KAAK;GACxC,UAAU;IAIR,EAAE,WAAW,IAAI,MAAM,IAAI,KAAK;GAClC;EACF,CAAC,CACH,CACF;EAEA,KAAK,cAAc,MAAM,OAAO;CAClC;CAGA,cACE,MACA,SACA;EACA,KAAK,IAAI,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK;GACpC,MAAM,IAAI,KAAK;GACf,MAAM,SAAS,QAAQ;GACvB,IAAI,OAAO,WAAW,aACpB,EAAE,OAAO,OAAO,KAAK;QAErB,IAAI,EAAE,SACJ,EAAE,QAAQ,OAAO,MAAM;QAEvB,KAAKC,IAAI,QAAQ,+BAA+B,OAAO,MAAM;EAGnE;CACF;CAEA,MAAME,gCAAgC,GAAwB;EAC5D,KAAKJ,sBAAsB,IAAI,CAAC;EAEhC,IAAI,CAAC,KAAK,4BAA4B;GACpC,KAAK,6BAA6B;GAClC,MAAM,QAAQ,QAAQ;GACtB,KAAK,6BAA6B;GAClC,MAAM,gBAAgB,CAAC,GAAG,KAAKA,qBAAqB;GACpD,KAAKA,sBAAsB,MAAM;GACjC,MAAM,KAAKK,mBACT,eACA,GACA,KAAA,CACF;EACF;CACF;CAEA,qBAA8B;EAC5B,OAAO,KAAKN,eAAe,OAAO;CACpC;CAEA,2BAA2B,WAA4B;EACrD,KAAK,MAAM,KAAK,KAAKA,gBACnB,IAAI,EAAE,qBAAqB,SAAS,GAClC,OAAO;EAGX,OAAO;CACT;AACF;AAOA,SAAS,wBACP,MACA,OACA,WACA,MACS;CAET,IAAI,cAAc;OACX,MAAM,aAAa,MACtB,IAAI,KAAK,IAAI,UAAU,GAAG,GACxB,OAAO;CAAA;CAKb,KAAK,MAAM,YAAY,OACrB,IAAI,oBAAoB,UAAU,WAAW,IAAI,GAC/C,OAAO;CAGX,OAAO;AACT;AAEA,SAAS,oBACP,UACA,iBACA,MACS;CAET,KAAK,MAAM,aAAa,MACtB,IAAI,mBAAmB,UAAU,iBAAiB,UAAU,GAAG,GAC7D,OAAO;CAIX,OAAO;AACT;AAEA,SAAgB,mBACd,UACA,iBACA,YACS;CACT,MAAM,EACJ,YAAY,IACZ,OACA,QACA,UACA,gBACA,sBACE,SAAS;CAEb,IAAI,oBAAoB,WACtB,OAAO;CAGT,IAAI,CAAC,WAAW;EAEd,IAAI,UAAU,KAAA,KAAa,SAAS,GAClC,OAAO;EAKT,IAAI,CAAC,UAAU,CAAC,UACd,OAAO;EAGT,IACE,WACC,CAAC,WAAW,WAAW,MAAM,KAC5B,wBAAwB,UAAU,UAAU,IAE9C,OAAO;EAGT,IACE,aACE,kBAAkB,WAAW,YAAY,QAAQ,KACjD,SAAS,YAAY,QAAQ,KAC7B,wBAAwB,UAAU,UAAU,IAE9C,OAAO;EAGT,OAAO;CACT;CAIA,IAAI,CAAC,UAAU,CAAC,YAAY,CAAC,mBAC3B,OAAO;CAQP,OAAO;AA4BX;AAEA,SAAS,wBACP,UACA,YACS;CACT,MAAM,EAAC,sBAAqB;CAC5B,OACE,SAAS,QAAQ,UAAU,KAAA,KAC3B,sBAAsB,KAAA,KACtB,YAAY,YAAY,iBAAiB;AAE7C;AAEA,UAAU,sBACR,eACA,OAC4B;CAC5B,KAAK,MAAM,gBAAgB,eACzB,IAAI,aAAa,QAAQ,KAAK,GAC5B,MAAM;AAGZ;AAEA,SAAS,mBACP,MACA,QACA,WACS;CACT,IAAI,WAAW,IACb,OAAO;CAGT,MAAM,cAGC,WAAkC,OAAO;CAChD,MAAM,IAAI,iBAAiB,MAAM,QAAQ,UAAU;CACnD,OAAO,IAAI,KAAK,UAAU,WAAW,KAAK,EAAE,EAAE,WAAW,MAAM;AACjE;AAEA,SAAgB,iBACd,MACA,QACA,YACQ;CACR,OAAO,aAAa,KAAK,SAAQ,MAC/B,YAAY,QAAQ,WAAW,KAAK,EAAE,CAAC,CACzC;AACF"}
@@ -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":";;;;;;AA0GA,IAAI,uBAAuB;AAE3B,IAAa,sBAAb,MAA4D;CAC1D;CACA;CACA;;;;CAKA;;CAEA;CAEA,YACE,UACA,QACA,IACA,UAAU,uBACV;EACA,KAAK,WAAW;EAChB,KAAK,OAAO;EACZ,KAAK,MAAM,GACR,YAAY,OAAO,EACnB,YAAY,QAAQ,sBAAsB;EAC7C,KAAK,cAAc;EACnB,KAAK,WAAW;CAClB;CAGA,IAAyB,KAAmD;EAC1E,OACE,eAAe,KAAK,IAAI,KACvB,KAAK,KAAK,IAAI,GAAG;CAEtB;CAGA,MAAM,IAAI,KAA+B;EACvC,cAAc,KAAK,IAAI;EACvB,OAAO,KAAK,KAAK,IAAI,GAAG;CAC1B;CAGA,MAAM,UAA4B;EAChC,cAAc,KAAK,IAAI;EACvB,OAAO,KAAK,KAAK,QAAQ;CAC3B;CAgBA,KACE,SACkD;EAClD,OAAO,KAAK,SAAS,KAAK,MAAM,IAAI;CACtC;AACF;AAEA,SAAS,KAAK,GAAkB,CAEhC;AAEA,SAAS,KACP,SACA,QACA,YAC+C;CAE/C,OAAO,uCADM,gBAA4B,QAAQ,OAE/C,GACA,WAAY,CAAC,GACb,QACA,UACF;AACF;AAIA,IAAa,iCAAb,MAAuE;CACrE,wBAA8B,IAAI,IAAI;CACtC,SAA0C,CAAC;CAC3C;CAEA,YAAY,IAAyB;EACnC,KAAKE,MAAM;CACb;CAEA,IAAI,cAAmC;EACrC,OAAO,KAAKA,IAAI;CAClB;CAEA,IAAI,WAAgC;EAClC,OAAO,KAAKA,IAAI;CAClB;CAEA,IAAI,WAAmB;EACrB,OAAO,KAAKA,IAAI;CAClB;CAEA,UAA4B;EAE1B,KAAKD,OAAO,KAAK,EAAC,SAAS,CAAC,EAAC,CAAC;EAC9B,OAAO,KAAKC,IAAI,QAAQ;CAC1B;CAGA,IAAyB,KAAmD;EAC1E,KAAKF,MAAM,IAAI,GAAG;EAClB,OAAO,KAAKE,IAAI,IAAI,GAAG;CACzB;CAEA,IAAI,KAA+B;EACjC,KAAKF,MAAM,IAAI,GAAG;EAClB,OAAO,KAAKE,IAAI,IAAI,GAAG;CACzB;CAgBA,KACE,SACkD;EAClD,MAAM,WAAiC;GACrC,SAAS,gBAAgB,OAAO;GAChC,mBAAmB,KAAA;EACrB;EACA,KAAKD,OAAO,KAAK,QAAQ;EACzB,OAAO,KAAK,SAAS,KAAKC,IAAI,OAAM,sBAAqB;GACvD,SAAS,oBAAoB;EAC/B,CAAC;CACH;CAEA,IAAI,OAA4B;EAC9B,OAAO,KAAKF;CACd;CAEA,IAAI,QAAgC;EAClC,OAAO,KAAKC;CACd;AACF;AAsCA,IAAa,WAAW,OAAO;AAE/B,IAAa,uBAAb,cACU,oBAEV;CAGE;CACA;CACA,CAAU;CAEV,YACE,UACA,YACA,QACA,OACA,SACA,IACA,UAAU,wBACV;EACA,MAAM,UAAU,SAAS,IAAI,OAAO;EACpC,KAAK,aAAa;EAClB,KAAK,SAAS;EACd,KAAK,YAAY;CACnB;CAEA,IAAI,KAAa,OAAyC;EACxD,OAAO,KAAK,IAAI,KAAK,KAAK;CAC5B;CAEA,MAAM,IAAI,KAAa,OAAyC;EAC9D,cAAc,KAAK,IAAI;EACvB,MAAM,KAAK,KAAK,IAAI,KAAK,KAAK,KAAK,WAAW,KAAK,CAAC;CACtD;CAEA,IAAI,KAA+B;EACjC,OAAO,eAAe,KAAK,IAAI,KAAK,KAAK,KAAK,IAAI,KAAK,KAAK,GAAG;CACjE;AACF;AAeA,SAAS,gBACP,QACA,SAC4C;CAC5C,IAAI,WAAW,mBAAmB,OAAO,GACvC,OAAO,2BAA2B,QAAQ,OAAO;CAKnD,OAAO,OAAO,IAAI,KAAK,uBAAuB,OAAO,CAAC;AAGxD;AAEA,SAAgB,uBACd,SACQ;CACR,IAAI,CAAC,SACH,OAAO;CAGT,MAAM,EAAC,SAAS,IAAI,UAAS;CAC7B,IAAI,SAAS,YAAY,MAAM,KAAK,MAAM,GACxC,OAAO,MAAM;CAEf,OAAO;AACT;AAEA,SAAS,uCAIP,MACA,SACA,QACA,YAC+C;CAC/C,OAAO,IAAI,eAAe,MAAM,SAAS,QAAQ,UAAU;AAC7D;AAEA,gBAAgB,2BACd,QACA,SACiD;CAK/C,MAAM,IAAI,MAAM,uBAAuB,QAAQ,WAAW;AAM9D"}
@@ -1,6 +1,6 @@
1
1
  var package_default = {
2
2
  name: "@rocicorp/zero",
3
- version: "1.9.1-canary.1",
3
+ version: "1.10.0-canary.1",
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" },
@@ -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 };
@@ -1 +1 @@
1
- {"version":3,"file":"package.js","names":[],"sources":["../../package.json"],"sourcesContent":["{\n \"name\": \"@rocicorp/zero\",\n \"version\": \"1.9.1-canary.1\",\n \"description\": \"Zero is a web framework for serverless web development.\",\n \"homepage\": \"https://zero.rocicorp.dev\",\n \"bugs\": {\n \"url\": \"https://bugs.rocicorp.dev\"\n },\n \"license\": \"Apache-2.0\",\n \"author\": \"Rocicorp, Inc.\",\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"git+https://github.com/rocicorp/mono.git\",\n \"directory\": \"packages/zero\"\n },\n \"bin\": {\n \"analyze-query\": \"./out/zero/src/analyze-query.js\",\n \"ast-to-zql\": \"./out/zero/src/ast-to-zql.js\",\n \"transform-query\": \"./out/zero/src/transform-query.js\",\n \"zero-build-schema\": \"./out/zero/src/build-schema.js\",\n \"zero-cache\": \"./out/zero/src/cli.js\",\n \"zero-cache-dev\": \"./out/zero/src/zero-cache-dev.js\",\n \"zero-deploy-permissions\": \"./out/zero/src/deploy-permissions.js\",\n \"zero-out\": \"./out/zero/src/zero-out.js\"\n },\n \"files\": [\n \"out\",\n \"!*.tsbuildinfo\"\n ],\n \"type\": \"module\",\n \"main\": \"out/zero/src/zero.js\",\n \"module\": \"out/zero/src/zero.js\",\n \"types\": \"out/zero/src/zero.d.ts\",\n \"exports\": {\n \".\": {\n \"types\": \"./out/zero/src/zero.d.ts\",\n \"default\": \"./out/zero/src/zero.js\"\n },\n \"./analyze\": {\n \"types\": \"./out/zero/src/analyze.d.ts\",\n \"default\": \"./out/zero/src/analyze.js\"\n },\n \"./bindings\": {\n \"types\": \"./out/zero/src/bindings.d.ts\",\n \"default\": \"./out/zero/src/bindings.js\"\n },\n \"./change-protocol/v0\": {\n \"types\": \"./out/zero/src/change-protocol/v0.d.ts\",\n \"default\": \"./out/zero/src/change-protocol/v0.js\"\n },\n \"./expo-sqlite\": {\n \"types\": \"./out/zero/src/expo-sqlite.d.ts\",\n \"default\": \"./out/zero/src/expo-sqlite.js\"\n },\n \"./op-sqlite\": {\n \"types\": \"./out/zero/src/op-sqlite.d.ts\",\n \"default\": \"./out/zero/src/op-sqlite.js\"\n },\n \"./pg\": {\n \"types\": \"./out/zero/src/pg.d.ts\",\n \"default\": \"./out/zero/src/pg.js\"\n },\n \"./react\": {\n \"types\": \"./out/zero/src/react.d.ts\",\n \"default\": \"./out/zero/src/react.js\"\n },\n \"./react-native\": {\n \"types\": \"./out/zero/src/react-native.d.ts\",\n \"default\": \"./out/zero/src/react-native.js\"\n },\n \"./server\": {\n \"types\": \"./out/zero/src/server.d.ts\",\n \"default\": \"./out/zero/src/server.js\"\n },\n \"./server/adapters/drizzle\": {\n \"types\": \"./out/zero/src/adapters/drizzle.d.ts\",\n \"default\": \"./out/zero/src/adapters/drizzle.js\"\n },\n \"./server/adapters/kysely\": {\n \"types\": \"./out/zero/src/adapters/kysely.d.ts\",\n \"default\": \"./out/zero/src/adapters/kysely.js\"\n },\n \"./server/adapters/prisma\": {\n \"types\": \"./out/zero/src/adapters/prisma.d.ts\",\n \"default\": \"./out/zero/src/adapters/prisma.js\"\n },\n \"./server/adapters/pg\": {\n \"types\": \"./out/zero/src/adapters/pg.d.ts\",\n \"default\": \"./out/zero/src/adapters/pg.js\"\n },\n \"./server/adapters/postgresjs\": {\n \"types\": \"./out/zero/src/adapters/postgresjs.d.ts\",\n \"default\": \"./out/zero/src/adapters/postgresjs.js\"\n },\n \"./solid\": {\n \"types\": \"./out/zero/src/solid.d.ts\",\n \"default\": \"./out/zero/src/solid.js\"\n },\n \"./sqlite\": {\n \"types\": \"./out/zero/src/sqlite.d.ts\",\n \"default\": \"./out/zero/src/sqlite.js\"\n },\n \"./zqlite\": {\n \"types\": \"./out/zero/src/zqlite.d.ts\",\n \"default\": \"./out/zero/src/zqlite.js\"\n }\n },\n \"scripts\": {\n \"build\": \"node --experimental-strip-types --no-warnings tool/build.ts\",\n \"build:watch\": \"node --experimental-strip-types --no-warnings tool/build.ts --watch\",\n \"check-types\": \"tsc -p tsconfig.client.json && tsc -p tsconfig.server.json\",\n \"check-types:client:watch\": \"tsc -p tsconfig.client.json --watch\",\n \"check-types:server:watch\": \"tsc -p tsconfig.server.json --watch\",\n \"format\": \"oxfmt .\",\n \"check-format\": \"oxfmt --check .\",\n \"lint\": \"oxlint --quiet --config ../../oxlint.config.ts src/\",\n \"docs\": \"node --experimental-strip-types --no-warnings tool/generate-docs.ts\",\n \"docs:server\": \"node --watch --experimental-strip-types --no-warnings tool/generate-docs.ts --server\",\n \"fmt\": \"oxfmt .\",\n \"check-fmt\": \"oxfmt --check .\"\n },\n \"dependencies\": {\n \"@badrap/valita\": \"0.3.11\",\n \"@databases/escape-identifier\": \"^1.0.3\",\n \"@databases/sql\": \"^3.3.0\",\n \"@dotenvx/dotenvx\": \"^1.39.0\",\n \"@drdgvhbh/postgres-error-codes\": \"^0.0.6\",\n \"@fastify/cors\": \"^10.0.0\",\n \"@fastify/websocket\": \"^11.0.0\",\n \"@google-cloud/precise-date\": \"^4.0.0\",\n \"@opentelemetry/api\": \"^1.9.0\",\n \"@opentelemetry/api-logs\": \"^0.218.0\",\n \"@opentelemetry/auto-instrumentations-node\": \"^0.76.0\",\n \"@opentelemetry/exporter-metrics-otlp-http\": \"^0.218.0\",\n \"@opentelemetry/resources\": \"^2.7.1\",\n \"@opentelemetry/sdk-metrics\": \"^2.7.1\",\n \"@opentelemetry/sdk-node\": \"^0.218.0\",\n \"@opentelemetry/sdk-trace-node\": \"^2.7.1\",\n \"@opentelemetry/semantic-conventions\": \"^1.41.1\",\n \"@postgresql-typed/oids\": \"^0.2.0\",\n \"@rocicorp/lock\": \"^1.0.4\",\n \"@rocicorp/logger\": \"^6.1.0\",\n \"@rocicorp/resolver\": \"^1.0.2\",\n \"@rocicorp/zero-sqlite3\": \"^1.1.4\",\n \"@standard-schema/spec\": \"^1.0.0\",\n \"@types/basic-auth\": \"^1.1.8\",\n \"@types/ws\": \"^8.5.12\",\n \"basic-auth\": \"^2.0.1\",\n \"chalk-template\": \"^1.1.0\",\n \"chokidar\": \"^4.0.1\",\n \"cloudevents\": \"^10.0.0\",\n \"command-line-args\": \"^6.0.1\",\n \"command-line-usage\": \"^7.0.3\",\n \"compare-utf8\": \"^0.2.0\",\n \"defu\": \"^6.1.4\",\n \"eventemitter3\": \"^5.0.1\",\n \"fastify\": \"^5.0.0\",\n \"is-in-subnet\": \"^4.0.1\",\n \"jose\": \"^5.9.3\",\n \"js-xxhash\": \"^4.0.0\",\n \"json-custom-numbers\": \"^3.1.1\",\n \"kasi\": \"^1.1.0\",\n \"nanoid\": \"^5.1.2\",\n \"oxfmt\": \"^0.45.0\",\n \"parse-prometheus-text-format\": \"^1.1.1\",\n \"pg-format\": \"npm:pg-format-fix@^1.0.5\",\n \"postgres\": \"3.4.7\",\n \"semver\": \"^7.5.4\",\n \"url-pattern\": \"^1.0.3\",\n \"urlpattern-polyfill\": \"^10.1.0\",\n \"ws\": \"^8.18.1\"\n },\n \"devDependencies\": {\n \"@op-engineering/op-sqlite\": \">=15\",\n \"@vitest/runner\": \"^4.1.6\",\n \"analyze-query\": \"workspace:*\",\n \"ast-to-zql\": \"workspace:*\",\n \"expo-sqlite\": \">=15\",\n \"oxc-parser\": \"^0.129.0\",\n \"replicache\": \"workspace:*\",\n \"shared\": \"workspace:*\",\n \"syncpack\": \"^14.3.0\",\n \"typedoc\": \"^0.28.17\",\n \"typedoc-plugin-markdown\": \"^4.10.0\",\n \"typescript\": \"~6.0.2\",\n \"vite\": \"^8.0.13\",\n \"vitest\": \"^4.1.6\",\n \"zero-cache\": \"workspace:*\",\n \"zero-client\": \"workspace:*\",\n \"zero-pg\": \"workspace:*\",\n \"zero-react\": \"workspace:*\",\n \"zero-server\": \"workspace:*\",\n \"zero-solid\": \"workspace:*\",\n \"zqlite\": \"workspace:*\"\n },\n \"engines\": {\n \"node\": \">=22\"\n },\n \"packageManager\": \"pnpm@11.5.3\"\n}\n"],"mappings":""}
1
+ {"version":3,"file":"package.js","names":[],"sources":["../../package.json"],"sourcesContent":["{\n \"name\": \"@rocicorp/zero\",\n \"version\": \"1.10.0-canary.1\",\n \"description\": \"Zero is a web framework for serverless web development.\",\n \"homepage\": \"https://zero.rocicorp.dev\",\n \"bugs\": {\n \"url\": \"https://bugs.rocicorp.dev\"\n },\n \"license\": \"Apache-2.0\",\n \"author\": \"Rocicorp, Inc.\",\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"git+https://github.com/rocicorp/mono.git\",\n \"directory\": \"packages/zero\"\n },\n \"bin\": {\n \"analyze-query\": \"./out/zero/src/analyze-query.js\",\n \"ast-to-zql\": \"./out/zero/src/ast-to-zql.js\",\n \"transform-query\": \"./out/zero/src/transform-query.js\",\n \"zero-build-schema\": \"./out/zero/src/build-schema.js\",\n \"zero-cache\": \"./out/zero/src/cli.js\",\n \"zero-cache-dev\": \"./out/zero/src/zero-cache-dev.js\",\n \"zero-deploy-permissions\": \"./out/zero/src/deploy-permissions.js\",\n \"zero-out\": \"./out/zero/src/zero-out.js\"\n },\n \"files\": [\n \"out\",\n \"!*.tsbuildinfo\"\n ],\n \"type\": \"module\",\n \"main\": \"out/zero/src/zero.js\",\n \"module\": \"out/zero/src/zero.js\",\n \"types\": \"out/zero/src/zero.d.ts\",\n \"exports\": {\n \".\": {\n \"types\": \"./out/zero/src/zero.d.ts\",\n \"default\": \"./out/zero/src/zero.js\"\n },\n \"./analyze\": {\n \"types\": \"./out/zero/src/analyze.d.ts\",\n \"default\": \"./out/zero/src/analyze.js\"\n },\n \"./bindings\": {\n \"types\": \"./out/zero/src/bindings.d.ts\",\n \"default\": \"./out/zero/src/bindings.js\"\n },\n \"./change-protocol/v0\": {\n \"types\": \"./out/zero/src/change-protocol/v0.d.ts\",\n \"default\": \"./out/zero/src/change-protocol/v0.js\"\n },\n \"./expo-sqlite\": {\n \"types\": \"./out/zero/src/expo-sqlite.d.ts\",\n \"default\": \"./out/zero/src/expo-sqlite.js\"\n },\n \"./op-sqlite\": {\n \"types\": \"./out/zero/src/op-sqlite.d.ts\",\n \"default\": \"./out/zero/src/op-sqlite.js\"\n },\n \"./pg\": {\n \"types\": \"./out/zero/src/pg.d.ts\",\n \"default\": \"./out/zero/src/pg.js\"\n },\n \"./react\": {\n \"types\": \"./out/zero/src/react.d.ts\",\n \"default\": \"./out/zero/src/react.js\"\n },\n \"./react-native\": {\n \"types\": \"./out/zero/src/react-native.d.ts\",\n \"default\": \"./out/zero/src/react-native.js\"\n },\n \"./server\": {\n \"types\": \"./out/zero/src/server.d.ts\",\n \"default\": \"./out/zero/src/server.js\"\n },\n \"./server/adapters/drizzle\": {\n \"types\": \"./out/zero/src/adapters/drizzle.d.ts\",\n \"default\": \"./out/zero/src/adapters/drizzle.js\"\n },\n \"./server/adapters/kysely\": {\n \"types\": \"./out/zero/src/adapters/kysely.d.ts\",\n \"default\": \"./out/zero/src/adapters/kysely.js\"\n },\n \"./server/adapters/prisma\": {\n \"types\": \"./out/zero/src/adapters/prisma.d.ts\",\n \"default\": \"./out/zero/src/adapters/prisma.js\"\n },\n \"./server/adapters/pg\": {\n \"types\": \"./out/zero/src/adapters/pg.d.ts\",\n \"default\": \"./out/zero/src/adapters/pg.js\"\n },\n \"./server/adapters/postgresjs\": {\n \"types\": \"./out/zero/src/adapters/postgresjs.d.ts\",\n \"default\": \"./out/zero/src/adapters/postgresjs.js\"\n },\n \"./solid\": {\n \"types\": \"./out/zero/src/solid.d.ts\",\n \"default\": \"./out/zero/src/solid.js\"\n },\n \"./sqlite\": {\n \"types\": \"./out/zero/src/sqlite.d.ts\",\n \"default\": \"./out/zero/src/sqlite.js\"\n },\n \"./zqlite\": {\n \"types\": \"./out/zero/src/zqlite.d.ts\",\n \"default\": \"./out/zero/src/zqlite.js\"\n }\n },\n \"scripts\": {\n \"build\": \"node --experimental-strip-types --no-warnings tool/build.ts\",\n \"build:watch\": \"node --experimental-strip-types --no-warnings tool/build.ts --watch\",\n \"check-types\": \"tsc -p tsconfig.client.json && tsc -p tsconfig.server.json\",\n \"check-types:client:watch\": \"tsc -p tsconfig.client.json --watch\",\n \"check-types:server:watch\": \"tsc -p tsconfig.server.json --watch\",\n \"format\": \"oxfmt .\",\n \"check-format\": \"oxfmt --check .\",\n \"lint\": \"oxlint --quiet --config ../../oxlint.config.ts src/\",\n \"docs\": \"node --experimental-strip-types --no-warnings tool/generate-docs.ts\",\n \"docs:server\": \"node --watch --experimental-strip-types --no-warnings tool/generate-docs.ts --server\",\n \"fmt\": \"oxfmt .\",\n \"check-fmt\": \"oxfmt --check .\"\n },\n \"dependencies\": {\n \"@badrap/valita\": \"0.3.11\",\n \"@databases/escape-identifier\": \"^1.0.3\",\n \"@databases/sql\": \"^3.3.0\",\n \"@dotenvx/dotenvx\": \"^1.39.0\",\n \"@drdgvhbh/postgres-error-codes\": \"^0.0.6\",\n \"@fastify/cors\": \"^10.0.0\",\n \"@fastify/websocket\": \"^11.0.0\",\n \"@google-cloud/precise-date\": \"^4.0.0\",\n \"@opentelemetry/api\": \"^1.9.0\",\n \"@opentelemetry/api-logs\": \"^0.218.0\",\n \"@opentelemetry/auto-instrumentations-node\": \"^0.76.0\",\n \"@opentelemetry/exporter-metrics-otlp-http\": \"^0.218.0\",\n \"@opentelemetry/resources\": \"^2.7.1\",\n \"@opentelemetry/sdk-metrics\": \"^2.7.1\",\n \"@opentelemetry/sdk-node\": \"^0.218.0\",\n \"@opentelemetry/sdk-trace-node\": \"^2.7.1\",\n \"@opentelemetry/semantic-conventions\": \"^1.41.1\",\n \"@postgresql-typed/oids\": \"^0.2.0\",\n \"@rocicorp/lock\": \"^1.0.4\",\n \"@rocicorp/logger\": \"^6.1.0\",\n \"@rocicorp/resolver\": \"^1.0.2\",\n \"@rocicorp/zero-sqlite3\": \"^1.1.4\",\n \"@standard-schema/spec\": \"^1.0.0\",\n \"@types/basic-auth\": \"^1.1.8\",\n \"@types/ws\": \"^8.5.12\",\n \"basic-auth\": \"^2.0.1\",\n \"chalk-template\": \"^1.1.0\",\n \"chokidar\": \"^4.0.1\",\n \"cloudevents\": \"^10.0.0\",\n \"command-line-args\": \"^6.0.1\",\n \"command-line-usage\": \"^7.0.3\",\n \"compare-utf8\": \"^0.2.0\",\n \"defu\": \"^6.1.4\",\n \"eventemitter3\": \"^5.0.1\",\n \"fastify\": \"^5.0.0\",\n \"is-in-subnet\": \"^4.0.1\",\n \"jose\": \"^5.9.3\",\n \"js-xxhash\": \"^4.0.0\",\n \"json-custom-numbers\": \"^3.1.1\",\n \"kasi\": \"^1.1.0\",\n \"nanoid\": \"^5.1.2\",\n \"oxfmt\": \"^0.45.0\",\n \"parse-prometheus-text-format\": \"^1.1.1\",\n \"pg-format\": \"npm:pg-format-fix@^1.0.5\",\n \"postgres\": \"3.4.7\",\n \"semver\": \"^7.5.4\",\n \"url-pattern\": \"^1.0.3\",\n \"urlpattern-polyfill\": \"^10.1.0\",\n \"ws\": \"^8.18.1\"\n },\n \"devDependencies\": {\n \"@op-engineering/op-sqlite\": \">=15\",\n \"@vitest/runner\": \"^4.1.6\",\n \"analyze-query\": \"workspace:*\",\n \"ast-to-zql\": \"workspace:*\",\n \"expo-sqlite\": \">=15\",\n \"oxc-parser\": \"^0.129.0\",\n \"replicache\": \"workspace:*\",\n \"shared\": \"workspace:*\",\n \"syncpack\": \"^14.3.0\",\n \"typedoc\": \"^0.28.17\",\n \"typedoc-plugin-markdown\": \"^4.10.0\",\n \"typescript\": \"~6.0.2\",\n \"vite\": \"^8.0.13\",\n \"vitest\": \"^4.1.6\",\n \"zero-cache\": \"workspace:*\",\n \"zero-client\": \"workspace:*\",\n \"zero-pg\": \"workspace:*\",\n \"zero-react\": \"workspace:*\",\n \"zero-server\": \"workspace:*\",\n \"zero-solid\": \"workspace:*\",\n \"zqlite\": \"workspace:*\"\n },\n \"engines\": {\n \"node\": \">=22\"\n },\n \"packageManager\": \"pnpm@11.11.0\"\n}\n"],"mappings":""}
@@ -18,6 +18,7 @@ export type NormalizedZeroConfig = ZeroConfig & {
18
18
  };
19
19
  numSyncWorkers: number;
20
20
  };
21
+ export type LitestreamConfig = NormalizedZeroConfig['litestream'];
21
22
  export declare function isDevelopmentMode(): boolean;
22
23
  export declare function assertNormalized(config: ZeroConfig): asserts config is NormalizedZeroConfig;
23
24
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"normalize.d.ts","sourceRoot":"","sources":["../../../../../zero-cache/src/config/normalize.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAC,UAAU,EAAC,MAAM,kBAAkB,CAAC;AAIjD,OAAO,KAAK,EAAC,UAAU,EAAC,MAAM,kBAAkB,CAAC;AAEjD,qEAAqE;AACrE,MAAM,MAAM,oBAAoB,GAAG,UAAU,GAAG;IAC9C,MAAM,EAAE,MAAM,CAAC;IACf,cAAc,EAAE;QACd,IAAI,EAAE,MAAM,CAAC;QACb,OAAO,EAAE,MAAM,CAAC;KACjB,CAAC;IACF,MAAM,EAAE;QACN,EAAE,EAAE,MAAM,CAAC;KACZ,CAAC;IACF,GAAG,EAAE;QACH,EAAE,EAAE,MAAM,CAAC;KACZ,CAAC;IACF,UAAU,EAAE;QACV,IAAI,EAAE,MAAM,CAAC;KACd,CAAC;IACF,cAAc,EAAE,MAAM,CAAC;CACxB,CAAC;AAEF,wBAAgB,iBAAiB,IAAI,OAAO,CAE3C;AASD,wBAAgB,gBAAgB,CAC9B,MAAM,EAAE,UAAU,GACjB,OAAO,CAAC,MAAM,IAAI,oBAAoB,CAiCxC;AAED;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CACjC,EAAE,EAAE,UAAU,EACd,MAAM,EAAE,UAAU,EAClB,GAAG,EAAE,MAAM,CAAC,UAAU,EACtB,aAAa,CAAC,EAAE,MAAM,GACrB,oBAAoB,CA8EtB"}
1
+ {"version":3,"file":"normalize.d.ts","sourceRoot":"","sources":["../../../../../zero-cache/src/config/normalize.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAC,UAAU,EAAC,MAAM,kBAAkB,CAAC;AAIjD,OAAO,KAAK,EAAC,UAAU,EAAC,MAAM,kBAAkB,CAAC;AAEjD,qEAAqE;AACrE,MAAM,MAAM,oBAAoB,GAAG,UAAU,GAAG;IAC9C,MAAM,EAAE,MAAM,CAAC;IACf,cAAc,EAAE;QACd,IAAI,EAAE,MAAM,CAAC;QACb,OAAO,EAAE,MAAM,CAAC;KACjB,CAAC;IACF,MAAM,EAAE;QACN,EAAE,EAAE,MAAM,CAAC;KACZ,CAAC;IACF,GAAG,EAAE;QACH,EAAE,EAAE,MAAM,CAAC;KACZ,CAAC;IACF,UAAU,EAAE;QACV,IAAI,EAAE,MAAM,CAAC;KACd,CAAC;IACF,cAAc,EAAE,MAAM,CAAC;CACxB,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG,oBAAoB,CAAC,YAAY,CAAC,CAAC;AAElE,wBAAgB,iBAAiB,IAAI,OAAO,CAE3C;AASD,wBAAgB,gBAAgB,CAC9B,MAAM,EAAE,UAAU,GACjB,OAAO,CAAC,MAAM,IAAI,oBAAoB,CAuDxC;AAED;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CACjC,EAAE,EAAE,UAAU,EACd,MAAM,EAAE,UAAU,EAClB,GAAG,EAAE,MAAM,CAAC,UAAU,EACtB,aAAa,CAAC,EAAE,MAAM,GACrB,oBAAoB,CA8EtB"}
@@ -14,9 +14,18 @@ function assertNormalized(config) {
14
14
  assert(config.taskID, "missing --task-id");
15
15
  assert(config.changeStreamer.port, "missing --change-streamer-port");
16
16
  assert(config.changeStreamer.address, "missing --change-streamer-address");
17
+ const { sqliteChangeLogMode, sqliteChangeLogReadPercent, sqliteChangeLogRetentionMs, sqliteChangeLogReadBatchRows, sqliteChangeLogPurgeBatchRows, sqliteChangeLogBarrierTimeoutMs } = config.changeStreamer;
18
+ assert(Number.isSafeInteger(sqliteChangeLogReadPercent) && sqliteChangeLogReadPercent >= 0 && sqliteChangeLogReadPercent <= 100, "--change-streamer-sqlite-change-log-read-percent must be an integer between 0 and 100");
19
+ assert(sqliteChangeLogMode === "serve" || sqliteChangeLogReadPercent === 0, "--change-streamer-sqlite-change-log-read-percent must be 0 unless --change-streamer-sqlite-change-log-mode=serve");
20
+ for (const [flag, value] of [
21
+ ["retention-ms", sqliteChangeLogRetentionMs],
22
+ ["read-batch-rows", sqliteChangeLogReadBatchRows],
23
+ ["purge-batch-rows", sqliteChangeLogPurgeBatchRows],
24
+ ["barrier-timeout-ms", sqliteChangeLogBarrierTimeoutMs]
25
+ ]) assert(Number.isSafeInteger(value) && value > 0, `--change-streamer-sqlite-change-log-${flag} must be a positive integer`);
17
26
  assert(config.litestream.port, "missing --litestream-port");
18
27
  assert(!config.litestream.backupUsingV5 || config.litestream.restoreUsingV5, "--litestream-backup-using-v5 requires --litestream-restore-using-v5");
19
- assert(!config.litestream.backupUsingV5 || config.litestream.executableV5 !== void 0 && config.litestream.executable === config.litestream.executableV5, "--litestream-backup-using-v5 requires --litestream-executable to be flipped to the v5 binary (--litestream-executable must equal --litestream-executable-v5)");
28
+ assert(!config.litestream.backupURL || config.litestream.executableV5 || !(config.litestream.restoreUsingV5 || config.litestream.backupUsingV5), "--litestream-restore-using-v5 and --litestream-backup-using-v5 require --litestream-executable to be specified");
20
29
  assert(config.change.db, "missing --change-db");
21
30
  assert(config.cvr.db, "missing --cvr-db");
22
31
  assertNotUndefined(config.numSyncWorkers, "missing --num-sync-workers");
@@ -1 +1 @@
1
- {"version":3,"file":"normalize.js","names":[],"sources":["../../../../../zero-cache/src/config/normalize.ts"],"sourcesContent":["import {availableParallelism} from 'node:os';\nimport type {LogContext} from '@rocicorp/logger';\nimport {nanoid} from 'nanoid';\nimport {assert, assertNotUndefined} from '../../../shared/src/asserts.ts';\nimport {getHostIp} from './network.ts';\nimport type {ZeroConfig} from './zero-config.ts';\n\n/** {@link ZeroConfig} with defaults set per option documentation. */\nexport type NormalizedZeroConfig = ZeroConfig & {\n taskID: string;\n changeStreamer: {\n port: number;\n address: string;\n };\n change: {\n db: string;\n };\n cvr: {\n db: string;\n };\n litestream: {\n port: number;\n };\n numSyncWorkers: number;\n};\n\nexport function isDevelopmentMode(): boolean {\n return process.env.NODE_ENV === 'development';\n}\n\nfunction isRunningInECS(): boolean {\n // https://docs.aws.amazon.com/AmazonECS/latest/developerguide/ecs-environment-variables.html\n return process.env.ECS_CONTAINER_METADATA_URI_V4 !== undefined;\n}\n\nconst DEFAULT_ECS_KEEPALIVE_TIMEOUT_MS = 20_000;\n\nexport function assertNormalized(\n config: ZeroConfig,\n): asserts config is NormalizedZeroConfig {\n assert(config.taskID, 'missing --task-id');\n assert(config.changeStreamer.port, 'missing --change-streamer-port');\n assert(config.changeStreamer.address, 'missing --change-streamer-address');\n assert(config.litestream.port, 'missing --litestream-port');\n assert(\n !config.litestream.backupUsingV5 || config.litestream.restoreUsingV5,\n '--litestream-backup-using-v5 requires --litestream-restore-using-v5',\n );\n // The `litestream replicate` process always runs --litestream-executable, so\n // enabling v5 backups (which write the LTX format read by the VFS monitor)\n // requires --litestream-executable itself to have been flipped to the v5\n // binary. Restoring is verified separately via --litestream-restore-using-v5,\n // which is the prerequisite step that must roll out *before* the executable\n // is flipped (so every replica can restore both WAL and LTX formats).\n assert(\n !config.litestream.backupUsingV5 ||\n (config.litestream.executableV5 !== undefined &&\n config.litestream.executable === config.litestream.executableV5),\n '--litestream-backup-using-v5 requires --litestream-executable to be ' +\n 'flipped to the v5 binary (--litestream-executable must equal ' +\n '--litestream-executable-v5)',\n );\n assert(config.change.db, 'missing --change-db');\n assert(config.cvr.db, 'missing --cvr-db');\n assertNotUndefined(config.numSyncWorkers, 'missing --num-sync-workers');\n\n if (!isDevelopmentMode()) {\n assert(\n config.adminPassword,\n 'missing --admin-password: required in production mode',\n );\n }\n}\n\n/**\n * Normalizes the parsed `config` by setting defaults from the environment\n * or from other options as documented. When defaults are applied, the\n * corresponding `env` variable is updated so that the settings are propagated\n * to spawned child workers. Child workers can then call\n * {@link assertNormalized} to verify that the expected defaults have been set.\n */\nexport function normalizeZeroConfig(\n lc: LogContext,\n config: ZeroConfig,\n env: NodeJS.ProcessEnv,\n defaultTaskID?: string,\n): NormalizedZeroConfig {\n if (!config.taskID) {\n const taskID = defaultTaskID ?? nanoid();\n config.taskID = taskID;\n env['ZERO_TASK_ID'] = taskID;\n }\n if (!config.changeStreamer.port) {\n const port = config.port + 1;\n config.changeStreamer.port = port;\n env['ZERO_CHANGE_STREAMER_PORT'] = String(port);\n }\n if (!config.litestream.port) {\n const port = config.port + 2;\n config.litestream.port = port;\n env['ZERO_LITESTREAM_PORT'] = String(port);\n }\n if (config.numSyncWorkers === undefined) {\n // Reserve 1 core for the replicator. The change-streamer is not CPU heavy.\n const numSyncers = Math.max(1, availableParallelism() - 1);\n config.numSyncWorkers = numSyncers;\n env['ZERO_NUM_SYNC_WORKERS'] = String(numSyncers);\n }\n\n const hostIP = getHostIp(\n lc,\n config.changeStreamer.discoveryInterfacePreferences,\n );\n if (!config.changeStreamer.address) {\n const {port} = config.changeStreamer;\n const address = `${hostIP}:${port}`;\n config.changeStreamer.address = address;\n env['ZERO_CHANGE_STREAMER_ADDRESS'] = address;\n }\n\n if (!config.change.db) {\n config.change.db = config.upstream.db;\n env['ZERO_CHANGE_DB'] = config.upstream.db;\n }\n\n if (!config.cvr.db) {\n config.cvr.db = config.upstream.db;\n env['ZERO_CVR_DB'] = config.upstream.db;\n }\n\n if (!config.keepaliveTimeoutMs && isRunningInECS()) {\n config.keepaliveTimeoutMs = DEFAULT_ECS_KEEPALIVE_TIMEOUT_MS;\n env['ZERO_KEEPALIVE_TIMEOUT_MS'] = String(DEFAULT_ECS_KEEPALIVE_TIMEOUT_MS);\n }\n\n lc.info?.(`runtime env: taskID=${config.taskID}, hostIP=${hostIP}`);\n\n return {\n ...config,\n taskID: config.taskID,\n\n changeStreamer: {\n ...config.changeStreamer,\n port: config.changeStreamer.port,\n address: config.changeStreamer.address,\n },\n\n litestream: {\n ...config.litestream,\n port: config.litestream.port,\n },\n\n change: {\n ...config.change,\n db: config.change.db,\n },\n\n cvr: {\n ...config.cvr,\n db: config.cvr.db,\n },\n\n numSyncWorkers: config.numSyncWorkers,\n };\n}\n"],"mappings":";;;;;AA0BA,SAAgB,oBAA6B;CAC3C,OAAA,QAAA,IAAA,aAAgC;AAClC;AAEA,SAAS,iBAA0B;CAEjC,OAAO,QAAQ,IAAI,kCAAkC,KAAA;AACvD;AAEA,IAAM,mCAAmC;AAEzC,SAAgB,iBACd,QACwC;CACxC,OAAO,OAAO,QAAQ,mBAAmB;CACzC,OAAO,OAAO,eAAe,MAAM,gCAAgC;CACnE,OAAO,OAAO,eAAe,SAAS,mCAAmC;CACzE,OAAO,OAAO,WAAW,MAAM,2BAA2B;CAC1D,OACE,CAAC,OAAO,WAAW,iBAAiB,OAAO,WAAW,gBACtD,qEACF;CAOA,OACE,CAAC,OAAO,WAAW,iBAChB,OAAO,WAAW,iBAAiB,KAAA,KAClC,OAAO,WAAW,eAAe,OAAO,WAAW,cACvD,8JAGF;CACA,OAAO,OAAO,OAAO,IAAI,qBAAqB;CAC9C,OAAO,OAAO,IAAI,IAAI,kBAAkB;CACxC,mBAAmB,OAAO,gBAAgB,4BAA4B;CAEtE,IAAI,CAAC,kBAAkB,GACrB,OACE,OAAO,eACP,uDACF;AAEJ;;;;;;;;AASA,SAAgB,oBACd,IACA,QACA,KACA,eACsB;CACtB,IAAI,CAAC,OAAO,QAAQ;EAClB,MAAM,SAAS,iBAAiB,OAAO;EACvC,OAAO,SAAS;EAChB,IAAI,kBAAkB;CACxB;CACA,IAAI,CAAC,OAAO,eAAe,MAAM;EAC/B,MAAM,OAAO,OAAO,OAAO;EAC3B,OAAO,eAAe,OAAO;EAC7B,IAAI,+BAA+B,OAAO,IAAI;CAChD;CACA,IAAI,CAAC,OAAO,WAAW,MAAM;EAC3B,MAAM,OAAO,OAAO,OAAO;EAC3B,OAAO,WAAW,OAAO;EACzB,IAAI,0BAA0B,OAAO,IAAI;CAC3C;CACA,IAAI,OAAO,mBAAmB,KAAA,GAAW;EAEvC,MAAM,aAAa,KAAK,IAAI,GAAG,qBAAqB,IAAI,CAAC;EACzD,OAAO,iBAAiB;EACxB,IAAI,2BAA2B,OAAO,UAAU;CAClD;CAEA,MAAM,SAAS,UACb,IACA,OAAO,eAAe,6BACxB;CACA,IAAI,CAAC,OAAO,eAAe,SAAS;EAClC,MAAM,EAAC,SAAQ,OAAO;EACtB,MAAM,UAAU,GAAG,OAAO,GAAG;EAC7B,OAAO,eAAe,UAAU;EAChC,IAAI,kCAAkC;CACxC;CAEA,IAAI,CAAC,OAAO,OAAO,IAAI;EACrB,OAAO,OAAO,KAAK,OAAO,SAAS;EACnC,IAAI,oBAAoB,OAAO,SAAS;CAC1C;CAEA,IAAI,CAAC,OAAO,IAAI,IAAI;EAClB,OAAO,IAAI,KAAK,OAAO,SAAS;EAChC,IAAI,iBAAiB,OAAO,SAAS;CACvC;CAEA,IAAI,CAAC,OAAO,sBAAsB,eAAe,GAAG;EAClD,OAAO,qBAAqB;EAC5B,IAAI,+BAA+B,OAAO,gCAAgC;CAC5E;CAEA,GAAG,OAAO,uBAAuB,OAAO,OAAO,WAAW,QAAQ;CAElE,OAAO;EACL,GAAG;EACH,QAAQ,OAAO;EAEf,gBAAgB;GACd,GAAG,OAAO;GACV,MAAM,OAAO,eAAe;GAC5B,SAAS,OAAO,eAAe;EACjC;EAEA,YAAY;GACV,GAAG,OAAO;GACV,MAAM,OAAO,WAAW;EAC1B;EAEA,QAAQ;GACN,GAAG,OAAO;GACV,IAAI,OAAO,OAAO;EACpB;EAEA,KAAK;GACH,GAAG,OAAO;GACV,IAAI,OAAO,IAAI;EACjB;EAEA,gBAAgB,OAAO;CACzB;AACF"}
1
+ {"version":3,"file":"normalize.js","names":[],"sources":["../../../../../zero-cache/src/config/normalize.ts"],"sourcesContent":["import {availableParallelism} from 'node:os';\nimport type {LogContext} from '@rocicorp/logger';\nimport {nanoid} from 'nanoid';\nimport {assert, assertNotUndefined} from '../../../shared/src/asserts.ts';\nimport {getHostIp} from './network.ts';\nimport type {ZeroConfig} from './zero-config.ts';\n\n/** {@link ZeroConfig} with defaults set per option documentation. */\nexport type NormalizedZeroConfig = ZeroConfig & {\n taskID: string;\n changeStreamer: {\n port: number;\n address: string;\n };\n change: {\n db: string;\n };\n cvr: {\n db: string;\n };\n litestream: {\n port: number;\n };\n numSyncWorkers: number;\n};\n\nexport type LitestreamConfig = NormalizedZeroConfig['litestream'];\n\nexport function isDevelopmentMode(): boolean {\n return process.env.NODE_ENV === 'development';\n}\n\nfunction isRunningInECS(): boolean {\n // https://docs.aws.amazon.com/AmazonECS/latest/developerguide/ecs-environment-variables.html\n return process.env.ECS_CONTAINER_METADATA_URI_V4 !== undefined;\n}\n\nconst DEFAULT_ECS_KEEPALIVE_TIMEOUT_MS = 20_000;\n\nexport function assertNormalized(\n config: ZeroConfig,\n): asserts config is NormalizedZeroConfig {\n assert(config.taskID, 'missing --task-id');\n assert(config.changeStreamer.port, 'missing --change-streamer-port');\n assert(config.changeStreamer.address, 'missing --change-streamer-address');\n const {\n sqliteChangeLogMode,\n sqliteChangeLogReadPercent,\n sqliteChangeLogRetentionMs,\n sqliteChangeLogReadBatchRows,\n sqliteChangeLogPurgeBatchRows,\n sqliteChangeLogBarrierTimeoutMs,\n } = config.changeStreamer;\n assert(\n Number.isSafeInteger(sqliteChangeLogReadPercent) &&\n sqliteChangeLogReadPercent >= 0 &&\n sqliteChangeLogReadPercent <= 100,\n '--change-streamer-sqlite-change-log-read-percent must be an integer between 0 and 100',\n );\n assert(\n sqliteChangeLogMode === 'serve' || sqliteChangeLogReadPercent === 0,\n '--change-streamer-sqlite-change-log-read-percent must be 0 unless --change-streamer-sqlite-change-log-mode=serve',\n );\n for (const [flag, value] of [\n ['retention-ms', sqliteChangeLogRetentionMs],\n ['read-batch-rows', sqliteChangeLogReadBatchRows],\n ['purge-batch-rows', sqliteChangeLogPurgeBatchRows],\n ['barrier-timeout-ms', sqliteChangeLogBarrierTimeoutMs],\n ] as const) {\n assert(\n Number.isSafeInteger(value) && value > 0,\n `--change-streamer-sqlite-change-log-${flag} must be a positive integer`,\n );\n }\n assert(config.litestream.port, 'missing --litestream-port');\n assert(\n !config.litestream.backupUsingV5 || config.litestream.restoreUsingV5,\n '--litestream-backup-using-v5 requires --litestream-restore-using-v5',\n );\n assert(\n !config.litestream.backupURL ||\n config.litestream.executableV5 ||\n !(config.litestream.restoreUsingV5 || config.litestream.backupUsingV5),\n '--litestream-restore-using-v5 and --litestream-backup-using-v5 ' +\n 'require --litestream-executable to be specified',\n );\n assert(config.change.db, 'missing --change-db');\n assert(config.cvr.db, 'missing --cvr-db');\n assertNotUndefined(config.numSyncWorkers, 'missing --num-sync-workers');\n\n if (!isDevelopmentMode()) {\n assert(\n config.adminPassword,\n 'missing --admin-password: required in production mode',\n );\n }\n}\n\n/**\n * Normalizes the parsed `config` by setting defaults from the environment\n * or from other options as documented. When defaults are applied, the\n * corresponding `env` variable is updated so that the settings are propagated\n * to spawned child workers. Child workers can then call\n * {@link assertNormalized} to verify that the expected defaults have been set.\n */\nexport function normalizeZeroConfig(\n lc: LogContext,\n config: ZeroConfig,\n env: NodeJS.ProcessEnv,\n defaultTaskID?: string,\n): NormalizedZeroConfig {\n if (!config.taskID) {\n const taskID = defaultTaskID ?? nanoid();\n config.taskID = taskID;\n env['ZERO_TASK_ID'] = taskID;\n }\n if (!config.changeStreamer.port) {\n const port = config.port + 1;\n config.changeStreamer.port = port;\n env['ZERO_CHANGE_STREAMER_PORT'] = String(port);\n }\n if (!config.litestream.port) {\n const port = config.port + 2;\n config.litestream.port = port;\n env['ZERO_LITESTREAM_PORT'] = String(port);\n }\n if (config.numSyncWorkers === undefined) {\n // Reserve 1 core for the replicator. The change-streamer is not CPU heavy.\n const numSyncers = Math.max(1, availableParallelism() - 1);\n config.numSyncWorkers = numSyncers;\n env['ZERO_NUM_SYNC_WORKERS'] = String(numSyncers);\n }\n\n const hostIP = getHostIp(\n lc,\n config.changeStreamer.discoveryInterfacePreferences,\n );\n if (!config.changeStreamer.address) {\n const {port} = config.changeStreamer;\n const address = `${hostIP}:${port}`;\n config.changeStreamer.address = address;\n env['ZERO_CHANGE_STREAMER_ADDRESS'] = address;\n }\n\n if (!config.change.db) {\n config.change.db = config.upstream.db;\n env['ZERO_CHANGE_DB'] = config.upstream.db;\n }\n\n if (!config.cvr.db) {\n config.cvr.db = config.upstream.db;\n env['ZERO_CVR_DB'] = config.upstream.db;\n }\n\n if (!config.keepaliveTimeoutMs && isRunningInECS()) {\n config.keepaliveTimeoutMs = DEFAULT_ECS_KEEPALIVE_TIMEOUT_MS;\n env['ZERO_KEEPALIVE_TIMEOUT_MS'] = String(DEFAULT_ECS_KEEPALIVE_TIMEOUT_MS);\n }\n\n lc.info?.(`runtime env: taskID=${config.taskID}, hostIP=${hostIP}`);\n\n return {\n ...config,\n taskID: config.taskID,\n\n changeStreamer: {\n ...config.changeStreamer,\n port: config.changeStreamer.port,\n address: config.changeStreamer.address,\n },\n\n litestream: {\n ...config.litestream,\n port: config.litestream.port,\n },\n\n change: {\n ...config.change,\n db: config.change.db,\n },\n\n cvr: {\n ...config.cvr,\n db: config.cvr.db,\n },\n\n numSyncWorkers: config.numSyncWorkers,\n };\n}\n"],"mappings":"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"}