@rocicorp/zero 1.12.0-canary.3 → 1.12.0-canary.5

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 (819) hide show
  1. package/out/_virtual/{_@oxc-project_runtime@0.130.0/helpers → _@oxc-project_runtime@0.154.0/helpers/esm}/usingCtx.js +2 -2
  2. package/out/analyze-query/src/analyze-cli.d.ts.map +1 -1
  3. package/out/analyze-query/src/analyze-cli.js +6 -4
  4. package/out/analyze-query/src/analyze-cli.js.map +1 -1
  5. package/out/analyze-query/src/bin-transform.js +4 -3
  6. package/out/analyze-query/src/bin-transform.js.map +1 -1
  7. package/out/analyze-query/src/zql-chain.d.ts +23 -0
  8. package/out/analyze-query/src/zql-chain.d.ts.map +1 -0
  9. package/out/analyze-query/src/zql-chain.js +162 -0
  10. package/out/analyze-query/src/zql-chain.js.map +1 -0
  11. package/out/ast-to-zql/src/ast-to-zql.js.map +1 -1
  12. package/out/ast-to-zql/src/bin.js +4 -3
  13. package/out/ast-to-zql/src/bin.js.map +1 -1
  14. package/out/ast-to-zql/src/format.js.map +1 -1
  15. package/out/datadog/src/datadog-log-sink.js +5 -4
  16. package/out/datadog/src/datadog-log-sink.js.map +1 -1
  17. package/out/otel/src/log-options.js.map +1 -1
  18. package/out/replicache/src/btree/node.js +13 -11
  19. package/out/replicache/src/btree/node.js.map +1 -1
  20. package/out/replicache/src/btree/read.js +4 -2
  21. package/out/replicache/src/btree/read.js.map +1 -1
  22. package/out/replicache/src/btree/splice.js.map +1 -1
  23. package/out/replicache/src/btree/write.js +9 -5
  24. package/out/replicache/src/btree/write.js.map +1 -1
  25. package/out/replicache/src/config.js +1 -2
  26. package/out/replicache/src/connection-loop.js.map +1 -1
  27. package/out/replicache/src/dag/chunk.js +1 -1
  28. package/out/replicache/src/dag/gc.js.map +1 -1
  29. package/out/replicache/src/dag/lazy-store.js +8 -7
  30. package/out/replicache/src/dag/lazy-store.js.map +1 -1
  31. package/out/replicache/src/dag/store-impl.js +1 -1
  32. package/out/replicache/src/dag/store-impl.js.map +1 -1
  33. package/out/replicache/src/dag/visitor.js.map +1 -1
  34. package/out/replicache/src/db/commit.js +5 -3
  35. package/out/replicache/src/db/commit.js.map +1 -1
  36. package/out/replicache/src/db/read.js +1 -1
  37. package/out/replicache/src/db/read.js.map +1 -1
  38. package/out/replicache/src/db/rebase.js.map +1 -1
  39. package/out/replicache/src/db/write.js +5 -2
  40. package/out/replicache/src/db/write.js.map +1 -1
  41. package/out/replicache/src/deleted-clients.js +3 -2
  42. package/out/replicache/src/deleted-clients.js.map +1 -1
  43. package/out/replicache/src/expo-sqlite.js +1 -2
  44. package/out/replicache/src/frozen-json.js +1 -1
  45. package/out/replicache/src/frozen-json.js.map +1 -1
  46. package/out/replicache/src/get-default-puller.js +1 -1
  47. package/out/replicache/src/hash.js +1 -1
  48. package/out/replicache/src/hash.js.map +1 -1
  49. package/out/replicache/src/impl.js +1 -2
  50. package/out/replicache/src/index-defs.js +5 -3
  51. package/out/replicache/src/index-defs.js.map +1 -1
  52. package/out/replicache/src/kv/expo-sqlite/store.js +1 -1
  53. package/out/replicache/src/kv/expo-sqlite/store.js.map +1 -1
  54. package/out/replicache/src/kv/idb-store.js +1 -1
  55. package/out/replicache/src/kv/idb-store.js.map +1 -1
  56. package/out/replicache/src/kv/mem-fallback-store.js +1 -1
  57. package/out/replicache/src/kv/mem-fallback-store.js.map +1 -1
  58. package/out/replicache/src/kv/mem-store.js.map +1 -1
  59. package/out/replicache/src/kv/op-sqlite/store.js.map +1 -1
  60. package/out/replicache/src/kv/op-sqlite/types.js.map +1 -1
  61. package/out/replicache/src/kv/read-impl.js.map +1 -1
  62. package/out/replicache/src/kv/sqlite-store.js +1 -1
  63. package/out/replicache/src/kv/sqlite-store.js.map +1 -1
  64. package/out/replicache/src/kv/write-impl-base.js +4 -1
  65. package/out/replicache/src/kv/write-impl-base.js.map +1 -1
  66. package/out/replicache/src/kv/write-impl.js.map +1 -1
  67. package/out/replicache/src/log-options.js +2 -1
  68. package/out/replicache/src/log-options.js.map +1 -1
  69. package/out/replicache/src/make-idb-name.js +1 -1
  70. package/out/replicache/src/new-client-channel.js +9 -7
  71. package/out/replicache/src/new-client-channel.js.map +1 -1
  72. package/out/replicache/src/on-persist-channel.js +1 -1
  73. package/out/replicache/src/on-persist-channel.js.map +1 -1
  74. package/out/replicache/src/op-sqlite.js +1 -2
  75. package/out/replicache/src/pending-mutations.js +2 -1
  76. package/out/replicache/src/pending-mutations.js.map +1 -1
  77. package/out/replicache/src/persist/client-gc.js +2 -2
  78. package/out/replicache/src/persist/client-gc.js.map +1 -1
  79. package/out/replicache/src/persist/client-group-gc.js +2 -2
  80. package/out/replicache/src/persist/client-group-gc.js.map +1 -1
  81. package/out/replicache/src/persist/client-groups.js +1 -1
  82. package/out/replicache/src/persist/client-groups.js.map +1 -1
  83. package/out/replicache/src/persist/clients.js +1 -1
  84. package/out/replicache/src/persist/clients.js.map +1 -1
  85. package/out/replicache/src/persist/collect-idb-databases.js +5 -4
  86. package/out/replicache/src/persist/collect-idb-databases.js.map +1 -1
  87. package/out/replicache/src/persist/gather-mem-only-visitor.js.map +1 -1
  88. package/out/replicache/src/persist/gather-not-cached-visitor.js.map +1 -1
  89. package/out/replicache/src/persist/heartbeat.js +2 -2
  90. package/out/replicache/src/persist/heartbeat.js.map +1 -1
  91. package/out/replicache/src/persist/idb-databases-store.js +1 -1
  92. package/out/replicache/src/persist/idb-databases-store.js.map +1 -1
  93. package/out/replicache/src/persist/make-client-id.js +1 -1
  94. package/out/replicache/src/persist/make-client-id.js.map +1 -1
  95. package/out/replicache/src/persist/persist.js +3 -2
  96. package/out/replicache/src/persist/persist.js.map +1 -1
  97. package/out/replicache/src/persist/refresh.js +8 -5
  98. package/out/replicache/src/persist/refresh.js.map +1 -1
  99. package/out/replicache/src/process-scheduler.js.map +1 -1
  100. package/out/replicache/src/replicache-impl.js +3 -3
  101. package/out/replicache/src/replicache-impl.js.map +1 -1
  102. package/out/replicache/src/scan-iterator.js.map +1 -1
  103. package/out/replicache/src/scan-options.js +7 -6
  104. package/out/replicache/src/scan-options.js.map +1 -1
  105. package/out/replicache/src/sqlite.js +1 -2
  106. package/out/replicache/src/subscriptions.js +1 -1
  107. package/out/replicache/src/subscriptions.js.map +1 -1
  108. package/out/replicache/src/sync/diff.js +3 -1
  109. package/out/replicache/src/sync/diff.js.map +1 -1
  110. package/out/replicache/src/sync/ids.js.map +1 -1
  111. package/out/replicache/src/sync/patch.js +2 -4
  112. package/out/replicache/src/sync/patch.js.map +1 -1
  113. package/out/replicache/src/sync/pull.js +3 -1
  114. package/out/replicache/src/sync/pull.js.map +1 -1
  115. package/out/replicache/src/sync/push.js.map +1 -1
  116. package/out/replicache/src/sync/request-id.js +1 -1
  117. package/out/replicache/src/sync/request-id.js.map +1 -1
  118. package/out/replicache/src/transactions.js +1 -1
  119. package/out/replicache/src/transactions.js.map +1 -1
  120. package/out/shared/src/arrays.js +4 -1
  121. package/out/shared/src/arrays.js.map +1 -1
  122. package/out/shared/src/asserts.js +1 -1
  123. package/out/shared/src/bigint-json.d.ts +9 -0
  124. package/out/shared/src/bigint-json.d.ts.map +1 -1
  125. package/out/shared/src/bigint-json.js +27 -2
  126. package/out/shared/src/bigint-json.js.map +1 -1
  127. package/out/shared/src/broadcast-channel.js +1 -1
  128. package/out/shared/src/btree-set.js +11 -8
  129. package/out/shared/src/btree-set.js.map +1 -1
  130. package/out/shared/src/cache.js.map +1 -1
  131. package/out/shared/src/config.js +1 -1
  132. package/out/shared/src/custom-key-map.js.map +1 -1
  133. package/out/shared/src/custom-key-set.js.map +1 -1
  134. package/out/shared/src/deep-clone.js +1 -1
  135. package/out/shared/src/document-visible.js.map +1 -1
  136. package/out/shared/src/dotenv.js.map +1 -1
  137. package/out/shared/src/error.js +1 -1
  138. package/out/shared/src/error.js.map +1 -1
  139. package/out/shared/src/hash.js +2 -2
  140. package/out/shared/src/hash.js.map +1 -1
  141. package/out/shared/src/iterables.js.map +1 -1
  142. package/out/shared/src/json-schema.js.map +1 -1
  143. package/out/shared/src/json.js.map +1 -1
  144. package/out/shared/src/logging-test-utils.js +1 -1
  145. package/out/shared/src/logging.js +1 -1
  146. package/out/shared/src/logging.js.map +1 -1
  147. package/out/shared/src/navigator.js +1 -1
  148. package/out/shared/src/options.js +9 -12
  149. package/out/shared/src/options.js.map +1 -1
  150. package/out/shared/src/promise-race.js.map +1 -1
  151. package/out/shared/src/queue.js.map +1 -1
  152. package/out/shared/src/record-proxy.js.map +1 -1
  153. package/out/shared/src/ring-buffer.js.map +1 -1
  154. package/out/shared/src/size-of-value.js +7 -10
  155. package/out/shared/src/size-of-value.js.map +1 -1
  156. package/out/shared/src/sorted-entries.js.map +1 -1
  157. package/out/shared/src/tdigest-schema.js.map +1 -1
  158. package/out/shared/src/tdigest.js.map +1 -1
  159. package/out/shared/src/valita.js +1 -1
  160. package/out/shared/src/valita.js.map +1 -1
  161. package/out/z2s/src/compiler.js +2 -4
  162. package/out/z2s/src/compiler.js.map +1 -1
  163. package/out/z2s/src/sql.js +1 -1
  164. package/out/z2s/src/sql.js.map +1 -1
  165. package/out/zero/package.js +211 -189
  166. package/out/zero/package.js.map +1 -1
  167. package/out/zero/src/adapters/drizzle.js +1 -2
  168. package/out/zero/src/adapters/kysely.js +1 -2
  169. package/out/zero/src/adapters/pg.js +1 -2
  170. package/out/zero/src/adapters/postgresjs.js +1 -2
  171. package/out/zero/src/adapters/prisma.js +1 -2
  172. package/out/zero/src/analyze.js +1 -2
  173. package/out/zero/src/change-protocol/v0.js +1 -2
  174. package/out/zero/src/expo-sqlite.js +1 -2
  175. package/out/zero/src/op-sqlite.js +1 -2
  176. package/out/zero/src/react-native.js.map +1 -1
  177. package/out/zero/src/sqlite.js +1 -2
  178. package/out/zero/src/zero-cache-dev.js +10 -9
  179. package/out/zero/src/zero-cache-dev.js.map +1 -1
  180. package/out/zero/src/zero-out.js +2 -1
  181. package/out/zero/src/zero-out.js.map +1 -1
  182. package/out/zero-cache/src/auth/auth.js +1 -1
  183. package/out/zero-cache/src/auth/auth.js.map +1 -1
  184. package/out/zero-cache/src/auth/jwt.js +4 -1
  185. package/out/zero-cache/src/auth/jwt.js.map +1 -1
  186. package/out/zero-cache/src/auth/load-permissions.js +1 -1
  187. package/out/zero-cache/src/auth/load-permissions.js.map +1 -1
  188. package/out/zero-cache/src/auth/read-authorizer.js +3 -2
  189. package/out/zero-cache/src/auth/read-authorizer.js.map +1 -1
  190. package/out/zero-cache/src/auth/write-authorizer.js +6 -17
  191. package/out/zero-cache/src/auth/write-authorizer.js.map +1 -1
  192. package/out/zero-cache/src/config/network.js +1 -1
  193. package/out/zero-cache/src/config/network.js.map +1 -1
  194. package/out/zero-cache/src/config/server-context.js.map +1 -1
  195. package/out/zero-cache/src/config/zero-config.d.ts +5 -0
  196. package/out/zero-cache/src/config/zero-config.d.ts.map +1 -1
  197. package/out/zero-cache/src/config/zero-config.js +13 -2
  198. package/out/zero-cache/src/config/zero-config.js.map +1 -1
  199. package/out/zero-cache/src/custom/fetch.js +1 -1
  200. package/out/zero-cache/src/custom/fetch.js.map +1 -1
  201. package/out/zero-cache/src/custom-queries/transform-query.js.map +1 -1
  202. package/out/zero-cache/src/db/create.js.map +1 -1
  203. package/out/zero-cache/src/db/index-predicate.js.map +1 -1
  204. package/out/zero-cache/src/db/lite-tables.d.ts +2 -2
  205. package/out/zero-cache/src/db/lite-tables.d.ts.map +1 -1
  206. package/out/zero-cache/src/db/lite-tables.js.map +1 -1
  207. package/out/zero-cache/src/db/migration-lite.js +1 -1
  208. package/out/zero-cache/src/db/migration-lite.js.map +1 -1
  209. package/out/zero-cache/src/db/migration.js +5 -3
  210. package/out/zero-cache/src/db/migration.js.map +1 -1
  211. package/out/zero-cache/src/db/pg-copy-binary.js +4 -3
  212. package/out/zero-cache/src/db/pg-copy-binary.js.map +1 -1
  213. package/out/zero-cache/src/db/pg-copy.js +0 -1
  214. package/out/zero-cache/src/db/pg-copy.js.map +1 -1
  215. package/out/zero-cache/src/db/pg-to-lite.js +1 -1
  216. package/out/zero-cache/src/db/pg-to-lite.js.map +1 -1
  217. package/out/zero-cache/src/db/run-transaction.js.map +1 -1
  218. package/out/zero-cache/src/db/specs.js +7 -5
  219. package/out/zero-cache/src/db/specs.js.map +1 -1
  220. package/out/zero-cache/src/db/sqlite-corruption.js.map +1 -1
  221. package/out/zero-cache/src/db/statements.d.ts.map +1 -1
  222. package/out/zero-cache/src/db/statements.js +9 -2
  223. package/out/zero-cache/src/db/statements.js.map +1 -1
  224. package/out/zero-cache/src/db/transaction-pool.js +5 -3
  225. package/out/zero-cache/src/db/transaction-pool.js.map +1 -1
  226. package/out/zero-cache/src/db/warmup.js.map +1 -1
  227. package/out/zero-cache/src/observability/events.js.map +1 -1
  228. package/out/zero-cache/src/observability/log-throttle.js.map +1 -1
  229. package/out/zero-cache/src/observability/metrics.js.map +1 -1
  230. package/out/zero-cache/src/scripts/decommission.js +1 -1
  231. package/out/zero-cache/src/scripts/deploy-permissions.js +5 -3
  232. package/out/zero-cache/src/scripts/deploy-permissions.js.map +1 -1
  233. package/out/zero-cache/src/scripts/permissions.js.map +1 -1
  234. package/out/zero-cache/src/server/anonymous-otel-start.js +2 -1
  235. package/out/zero-cache/src/server/anonymous-otel-start.js.map +1 -1
  236. package/out/zero-cache/src/server/change-streamer.js +1 -1
  237. package/out/zero-cache/src/server/change-streamer.js.map +1 -1
  238. package/out/zero-cache/src/server/inspector-delegate.js.map +1 -1
  239. package/out/zero-cache/src/server/logging.js +1 -1
  240. package/out/zero-cache/src/server/logging.js.map +1 -1
  241. package/out/zero-cache/src/server/main.js.map +1 -1
  242. package/out/zero-cache/src/server/otel-log-sink.js.map +1 -1
  243. package/out/zero-cache/src/server/otel-start.js.map +1 -1
  244. package/out/zero-cache/src/server/reaper.js +2 -2
  245. package/out/zero-cache/src/server/reaper.js.map +1 -1
  246. package/out/zero-cache/src/server/replicator.js +1 -1
  247. package/out/zero-cache/src/server/replicator.js.map +1 -1
  248. package/out/zero-cache/src/server/runner/run-worker.js +2 -1
  249. package/out/zero-cache/src/server/runner/run-worker.js.map +1 -1
  250. package/out/zero-cache/src/server/runner/runtime.js +2 -1
  251. package/out/zero-cache/src/server/runner/runtime.js.map +1 -1
  252. package/out/zero-cache/src/server/runner/zero-dispatcher.js.map +1 -1
  253. package/out/zero-cache/src/server/shadow-syncer.js +1 -1
  254. package/out/zero-cache/src/server/shadow-syncer.js.map +1 -1
  255. package/out/zero-cache/src/server/slot-keeper.js.map +1 -1
  256. package/out/zero-cache/src/server/syncer-assigner.js.map +1 -1
  257. package/out/zero-cache/src/server/syncer.d.ts.map +1 -1
  258. package/out/zero-cache/src/server/syncer.js +9 -4
  259. package/out/zero-cache/src/server/syncer.js.map +1 -1
  260. package/out/zero-cache/src/server/worker-dispatcher.js +1 -1
  261. package/out/zero-cache/src/server/worker-dispatcher.js.map +1 -1
  262. package/out/zero-cache/src/server/worker-urls.js.map +1 -1
  263. package/out/zero-cache/src/services/analyze.js +2 -2
  264. package/out/zero-cache/src/services/analyze.js.map +1 -1
  265. package/out/zero-cache/src/services/change-source/common/backfill-manager.js +2 -2
  266. package/out/zero-cache/src/services/change-source/common/backfill-manager.js.map +1 -1
  267. package/out/zero-cache/src/services/change-source/common/change-stream-multiplexer.js.map +1 -1
  268. package/out/zero-cache/src/services/change-source/common/init-cleanup.js.map +1 -1
  269. package/out/zero-cache/src/services/change-source/common/replica-restore.js.map +1 -1
  270. package/out/zero-cache/src/services/change-source/common/replica-schema.js +4 -4
  271. package/out/zero-cache/src/services/change-source/common/replica-schema.js.map +1 -1
  272. package/out/zero-cache/src/services/change-source/custom/change-source.js +4 -4
  273. package/out/zero-cache/src/services/change-source/custom/change-source.js.map +1 -1
  274. package/out/zero-cache/src/services/change-source/pg/backfill-metadata.js.map +1 -1
  275. package/out/zero-cache/src/services/change-source/pg/backfill-stream.js +4 -4
  276. package/out/zero-cache/src/services/change-source/pg/backfill-stream.js.map +1 -1
  277. package/out/zero-cache/src/services/change-source/pg/change-source-init.js +3 -3
  278. package/out/zero-cache/src/services/change-source/pg/change-source-init.js.map +1 -1
  279. package/out/zero-cache/src/services/change-source/pg/change-source.js +6 -8
  280. package/out/zero-cache/src/services/change-source/pg/change-source.js.map +1 -1
  281. package/out/zero-cache/src/services/change-source/pg/decommission.js +2 -1
  282. package/out/zero-cache/src/services/change-source/pg/decommission.js.map +1 -1
  283. package/out/zero-cache/src/services/change-source/pg/initial-sync.js +9 -7
  284. package/out/zero-cache/src/services/change-source/pg/initial-sync.js.map +1 -1
  285. package/out/zero-cache/src/services/change-source/pg/logical-replication/binary-reader.js.map +1 -1
  286. package/out/zero-cache/src/services/change-source/pg/logical-replication/pgoutput-parser.js.map +1 -1
  287. package/out/zero-cache/src/services/change-source/pg/logical-replication/stream.js +5 -4
  288. package/out/zero-cache/src/services/change-source/pg/logical-replication/stream.js.map +1 -1
  289. package/out/zero-cache/src/services/change-source/pg/lsn.js.map +1 -1
  290. package/out/zero-cache/src/services/change-source/pg/replication-slot-cleanup-monitor.js +2 -2
  291. package/out/zero-cache/src/services/change-source/pg/replication-slot-cleanup-monitor.js.map +1 -1
  292. package/out/zero-cache/src/services/change-source/pg/replication-slot-health.js +1 -1
  293. package/out/zero-cache/src/services/change-source/pg/replication-slot-health.js.map +1 -1
  294. package/out/zero-cache/src/services/change-source/pg/replication-slots.js +3 -3
  295. package/out/zero-cache/src/services/change-source/pg/replication-slots.js.map +1 -1
  296. package/out/zero-cache/src/services/change-source/pg/schema/ddl.js +2 -2
  297. package/out/zero-cache/src/services/change-source/pg/schema/ddl.js.map +1 -1
  298. package/out/zero-cache/src/services/change-source/pg/schema/index-predicate.js +13 -12
  299. package/out/zero-cache/src/services/change-source/pg/schema/index-predicate.js.map +1 -1
  300. package/out/zero-cache/src/services/change-source/pg/schema/init.js +1 -1
  301. package/out/zero-cache/src/services/change-source/pg/schema/init.js.map +1 -1
  302. package/out/zero-cache/src/services/change-source/pg/schema/published.js +2 -2
  303. package/out/zero-cache/src/services/change-source/pg/schema/published.js.map +1 -1
  304. package/out/zero-cache/src/services/change-source/pg/schema/replica-stage-enum.js.map +1 -1
  305. package/out/zero-cache/src/services/change-source/pg/schema/shard.js +10 -7
  306. package/out/zero-cache/src/services/change-source/pg/schema/shard.js.map +1 -1
  307. package/out/zero-cache/src/services/change-source/pg/schema/validation.js +1 -1
  308. package/out/zero-cache/src/services/change-source/pg/schema/validation.js.map +1 -1
  309. package/out/zero-cache/src/services/change-source/protocol/backfill-progress.js +1 -1
  310. package/out/zero-cache/src/services/change-source/protocol/backfill-progress.js.map +1 -1
  311. package/out/zero-cache/src/services/change-source/protocol/current/control.js.map +1 -1
  312. package/out/zero-cache/src/services/change-source/protocol/current/data.js.map +1 -1
  313. package/out/zero-cache/src/services/change-source/protocol/current/downstream.js.map +1 -1
  314. package/out/zero-cache/src/services/change-source/protocol/current/status.js.map +1 -1
  315. package/out/zero-cache/src/services/change-source/protocol/current/upstream.js.map +1 -1
  316. package/out/zero-cache/src/services/change-source/protocol/current.js +1 -1
  317. package/out/zero-cache/src/services/change-source/protocol/mod.js +1 -2
  318. package/out/zero-cache/src/services/change-streamer/backfill-state-tracker.js.map +1 -1
  319. package/out/zero-cache/src/services/change-streamer/backfill-state.js +1 -1
  320. package/out/zero-cache/src/services/change-streamer/backfill-state.js.map +1 -1
  321. package/out/zero-cache/src/services/change-streamer/backup-cleanup-monitor-factory.js.map +1 -1
  322. package/out/zero-cache/src/services/change-streamer/backup-monitor.js.map +1 -1
  323. package/out/zero-cache/src/services/change-streamer/broadcast.js +1 -1
  324. package/out/zero-cache/src/services/change-streamer/broadcast.js.map +1 -1
  325. package/out/zero-cache/src/services/change-streamer/change-log-codec.d.ts +1 -1
  326. package/out/zero-cache/src/services/change-streamer/change-log-codec.d.ts.map +1 -1
  327. package/out/zero-cache/src/services/change-streamer/change-log-codec.js +2 -3
  328. package/out/zero-cache/src/services/change-streamer/change-log-codec.js.map +1 -1
  329. package/out/zero-cache/src/services/change-streamer/change-log-initializer.js +3 -3
  330. package/out/zero-cache/src/services/change-streamer/change-log-initializer.js.map +1 -1
  331. package/out/zero-cache/src/services/change-streamer/change-log-transaction-hash.js.map +1 -1
  332. package/out/zero-cache/src/services/change-streamer/change-streamer-http.js +5 -3
  333. package/out/zero-cache/src/services/change-streamer/change-streamer-http.js.map +1 -1
  334. package/out/zero-cache/src/services/change-streamer/change-streamer-service.js +21 -21
  335. package/out/zero-cache/src/services/change-streamer/change-streamer-service.js.map +1 -1
  336. package/out/zero-cache/src/services/change-streamer/change-streamer.js +1 -1
  337. package/out/zero-cache/src/services/change-streamer/change-streamer.js.map +1 -1
  338. package/out/zero-cache/src/services/change-streamer/drain-tracker.js.map +1 -1
  339. package/out/zero-cache/src/services/change-streamer/forwarder.js +11 -10
  340. package/out/zero-cache/src/services/change-streamer/forwarder.js.map +1 -1
  341. package/out/zero-cache/src/services/change-streamer/litestream-sync-requester.js +1 -1
  342. package/out/zero-cache/src/services/change-streamer/litestream-sync-requester.js.map +1 -1
  343. package/out/zero-cache/src/services/change-streamer/litestream3-prometheus-poller.js +3 -3
  344. package/out/zero-cache/src/services/change-streamer/litestream3-prometheus-poller.js.map +1 -1
  345. package/out/zero-cache/src/services/change-streamer/replica-poller.js +2 -2
  346. package/out/zero-cache/src/services/change-streamer/replica-poller.js.map +1 -1
  347. package/out/zero-cache/src/services/change-streamer/restore-admission.js +12 -1
  348. package/out/zero-cache/src/services/change-streamer/restore-admission.js.map +1 -1
  349. package/out/zero-cache/src/services/change-streamer/schema/init.js +1 -1
  350. package/out/zero-cache/src/services/change-streamer/schema/init.js.map +1 -1
  351. package/out/zero-cache/src/services/change-streamer/schema/tables.js +1 -1
  352. package/out/zero-cache/src/services/change-streamer/schema/tables.js.map +1 -1
  353. package/out/zero-cache/src/services/change-streamer/snapshot-message.js +1 -1
  354. package/out/zero-cache/src/services/change-streamer/snapshot-message.js.map +1 -1
  355. package/out/zero-cache/src/services/change-streamer/snapshot-reservations.js.map +1 -1
  356. package/out/zero-cache/src/services/change-streamer/sqlite-change-log-catchup.js +1 -1
  357. package/out/zero-cache/src/services/change-streamer/sqlite-change-log-catchup.js.map +1 -1
  358. package/out/zero-cache/src/services/change-streamer/sqlite-change-log-comparator.js +2 -2
  359. package/out/zero-cache/src/services/change-streamer/sqlite-change-log-comparator.js.map +1 -1
  360. package/out/zero-cache/src/services/change-streamer/sqlite-change-log-purge-scheduler.js.map +1 -1
  361. package/out/zero-cache/src/services/change-streamer/sqlite-change-log-read-router.js.map +1 -1
  362. package/out/zero-cache/src/services/change-streamer/sqlite-change-log-reader.d.ts.map +1 -1
  363. package/out/zero-cache/src/services/change-streamer/sqlite-change-log-reader.js +4 -6
  364. package/out/zero-cache/src/services/change-streamer/sqlite-change-log-reader.js.map +1 -1
  365. package/out/zero-cache/src/services/change-streamer/sqlite-change-log-writer.js +3 -5
  366. package/out/zero-cache/src/services/change-streamer/sqlite-change-log-writer.js.map +1 -1
  367. package/out/zero-cache/src/services/change-streamer/storer.d.ts.map +1 -1
  368. package/out/zero-cache/src/services/change-streamer/storer.js +3 -3
  369. package/out/zero-cache/src/services/change-streamer/storer.js.map +1 -1
  370. package/out/zero-cache/src/services/change-streamer/subscribe.js +1 -1
  371. package/out/zero-cache/src/services/change-streamer/subscribe.js.map +1 -1
  372. package/out/zero-cache/src/services/change-streamer/subscriber.js +2 -2
  373. package/out/zero-cache/src/services/change-streamer/subscriber.js.map +1 -1
  374. package/out/zero-cache/src/services/change-streamer/upstream-acker.js +0 -1
  375. package/out/zero-cache/src/services/change-streamer/upstream-acker.js.map +1 -1
  376. package/out/zero-cache/src/services/heapz.js +2 -1
  377. package/out/zero-cache/src/services/heapz.js.map +1 -1
  378. package/out/zero-cache/src/services/http-service.js.map +1 -1
  379. package/out/zero-cache/src/services/life-cycle.js +2 -2
  380. package/out/zero-cache/src/services/life-cycle.js.map +1 -1
  381. package/out/zero-cache/src/services/limiter/sliding-window-limiter.js +4 -2
  382. package/out/zero-cache/src/services/limiter/sliding-window-limiter.js.map +1 -1
  383. package/out/zero-cache/src/services/litestream/commands.js +3 -3
  384. package/out/zero-cache/src/services/litestream/commands.js.map +1 -1
  385. package/out/zero-cache/src/services/litestream/litestream-checkpointer.js +2 -2
  386. package/out/zero-cache/src/services/litestream/litestream-checkpointer.js.map +1 -1
  387. package/out/zero-cache/src/services/litestream/litestream-controller.js.map +1 -1
  388. package/out/zero-cache/src/services/litestream/metrics.js.map +1 -1
  389. package/out/zero-cache/src/services/litestream/restore-progress.js.map +1 -1
  390. package/out/zero-cache/src/services/mutagen/mutagen.js +1 -1
  391. package/out/zero-cache/src/services/mutagen/mutagen.js.map +1 -1
  392. package/out/zero-cache/src/services/mutagen/pusher.js +3 -2
  393. package/out/zero-cache/src/services/mutagen/pusher.js.map +1 -1
  394. package/out/zero-cache/src/services/plannerz.js +6 -5
  395. package/out/zero-cache/src/services/plannerz.js.map +1 -1
  396. package/out/zero-cache/src/services/profz.js +5 -3
  397. package/out/zero-cache/src/services/profz.js.map +1 -1
  398. package/out/zero-cache/src/services/replicator/change-log-cookies.js.map +1 -1
  399. package/out/zero-cache/src/services/replicator/change-log-db.js +4 -3
  400. package/out/zero-cache/src/services/replicator/change-log-db.js.map +1 -1
  401. package/out/zero-cache/src/services/replicator/change-log-stream-writer.js +1 -1
  402. package/out/zero-cache/src/services/replicator/change-log-stream-writer.js.map +1 -1
  403. package/out/zero-cache/src/services/replicator/change-processor.js.map +1 -1
  404. package/out/zero-cache/src/services/replicator/drain-handler.js.map +1 -1
  405. package/out/zero-cache/src/services/replicator/incremental-sync.js +4 -4
  406. package/out/zero-cache/src/services/replicator/incremental-sync.js.map +1 -1
  407. package/out/zero-cache/src/services/replicator/notifier.js.map +1 -1
  408. package/out/zero-cache/src/services/replicator/replication-status.js +4 -3
  409. package/out/zero-cache/src/services/replicator/replication-status.js.map +1 -1
  410. package/out/zero-cache/src/services/replicator/replicator.js.map +1 -1
  411. package/out/zero-cache/src/services/replicator/reporter/recorder.js +1 -1
  412. package/out/zero-cache/src/services/replicator/reporter/recorder.js.map +1 -1
  413. package/out/zero-cache/src/services/replicator/reporter/report-schema.js +1 -1
  414. package/out/zero-cache/src/services/replicator/reporter/report-schema.js.map +1 -1
  415. package/out/zero-cache/src/services/replicator/schema/backfilling.js +2 -2
  416. package/out/zero-cache/src/services/replicator/schema/backfilling.js.map +1 -1
  417. package/out/zero-cache/src/services/replicator/schema/change-log.d.ts +19 -7
  418. package/out/zero-cache/src/services/replicator/schema/change-log.d.ts.map +1 -1
  419. package/out/zero-cache/src/services/replicator/schema/change-log.js +31 -15
  420. package/out/zero-cache/src/services/replicator/schema/change-log.js.map +1 -1
  421. package/out/zero-cache/src/services/replicator/schema/column-metadata.js +1 -1
  422. package/out/zero-cache/src/services/replicator/schema/column-metadata.js.map +1 -1
  423. package/out/zero-cache/src/services/replicator/schema/replication-state.js +10 -7
  424. package/out/zero-cache/src/services/replicator/schema/replication-state.js.map +1 -1
  425. package/out/zero-cache/src/services/replicator/schema/table-metadata.js.map +1 -1
  426. package/out/zero-cache/src/services/replicator/sqlite-change-log-observability.js +1 -1
  427. package/out/zero-cache/src/services/replicator/sqlite-change-log-observability.js.map +1 -1
  428. package/out/zero-cache/src/services/replicator/sqlite-change-log-purger.js +1 -1
  429. package/out/zero-cache/src/services/replicator/sqlite-change-log-purger.js.map +1 -1
  430. package/out/zero-cache/src/services/replicator/write-worker-client.js +1 -1
  431. package/out/zero-cache/src/services/replicator/write-worker-client.js.map +1 -1
  432. package/out/zero-cache/src/services/replicator/write-worker.js +3 -3
  433. package/out/zero-cache/src/services/replicator/write-worker.js.map +1 -1
  434. package/out/zero-cache/src/services/run-ast.js +1 -1
  435. package/out/zero-cache/src/services/run-ast.js.map +1 -1
  436. package/out/zero-cache/src/services/runner.js.map +1 -1
  437. package/out/zero-cache/src/services/running-state.js.map +1 -1
  438. package/out/zero-cache/src/services/shadow-sync/shadow-sync-service.js.map +1 -1
  439. package/out/zero-cache/src/services/statz.js +4 -3
  440. package/out/zero-cache/src/services/statz.js.map +1 -1
  441. package/out/zero-cache/src/services/view-syncer/active-users-gauge.js +2 -2
  442. package/out/zero-cache/src/services/view-syncer/active-users-gauge.js.map +1 -1
  443. package/out/zero-cache/src/services/view-syncer/advancement-metrics.js.map +1 -1
  444. package/out/zero-cache/src/services/view-syncer/batch-pacer.js.map +1 -1
  445. package/out/zero-cache/src/services/view-syncer/client-handler.d.ts.map +1 -1
  446. package/out/zero-cache/src/services/view-syncer/client-handler.js +24 -3
  447. package/out/zero-cache/src/services/view-syncer/client-handler.js.map +1 -1
  448. package/out/zero-cache/src/services/view-syncer/client-schema.d.ts +15 -2
  449. package/out/zero-cache/src/services/view-syncer/client-schema.d.ts.map +1 -1
  450. package/out/zero-cache/src/services/view-syncer/client-schema.js +46 -6
  451. package/out/zero-cache/src/services/view-syncer/client-schema.js.map +1 -1
  452. package/out/zero-cache/src/services/view-syncer/connection-context-manager.js.map +1 -1
  453. package/out/zero-cache/src/services/view-syncer/cvr-purger.js +2 -2
  454. package/out/zero-cache/src/services/view-syncer/cvr-purger.js.map +1 -1
  455. package/out/zero-cache/src/services/view-syncer/cvr-store.d.ts.map +1 -1
  456. package/out/zero-cache/src/services/view-syncer/cvr-store.js +11 -6
  457. package/out/zero-cache/src/services/view-syncer/cvr-store.js.map +1 -1
  458. package/out/zero-cache/src/services/view-syncer/cvr.js +12 -4
  459. package/out/zero-cache/src/services/view-syncer/cvr.js.map +1 -1
  460. package/out/zero-cache/src/services/view-syncer/deferred-writes-budget.js +1 -1
  461. package/out/zero-cache/src/services/view-syncer/deferred-writes-budget.js.map +1 -1
  462. package/out/zero-cache/src/services/view-syncer/drain-coordinator.js.map +1 -1
  463. package/out/zero-cache/src/services/view-syncer/e2e-serving-lag.js.map +1 -1
  464. package/out/zero-cache/src/services/view-syncer/hydration-budget.js.map +1 -1
  465. package/out/zero-cache/src/services/view-syncer/hydration-circuit-breaker.js +2 -2
  466. package/out/zero-cache/src/services/view-syncer/hydration-circuit-breaker.js.map +1 -1
  467. package/out/zero-cache/src/services/view-syncer/inspect-handler.js +6 -4
  468. package/out/zero-cache/src/services/view-syncer/inspect-handler.js.map +1 -1
  469. package/out/zero-cache/src/services/view-syncer/pipeline-driver.d.ts.map +1 -1
  470. package/out/zero-cache/src/services/view-syncer/pipeline-driver.js +13 -10
  471. package/out/zero-cache/src/services/view-syncer/pipeline-driver.js.map +1 -1
  472. package/out/zero-cache/src/services/view-syncer/plan-warnings.js.map +1 -1
  473. package/out/zero-cache/src/services/view-syncer/push-cost.js.map +1 -1
  474. package/out/zero-cache/src/services/view-syncer/push-cutoff.js.map +1 -1
  475. package/out/zero-cache/src/services/view-syncer/query-covering.js.map +1 -1
  476. package/out/zero-cache/src/services/view-syncer/query-shape.js.map +1 -1
  477. package/out/zero-cache/src/services/view-syncer/query-stats.js +1 -1
  478. package/out/zero-cache/src/services/view-syncer/query-stats.js.map +1 -1
  479. package/out/zero-cache/src/services/view-syncer/row-record-cache.js +1 -1
  480. package/out/zero-cache/src/services/view-syncer/row-record-cache.js.map +1 -1
  481. package/out/zero-cache/src/services/view-syncer/schema/cvr.js +1 -1
  482. package/out/zero-cache/src/services/view-syncer/schema/types.js +1 -1
  483. package/out/zero-cache/src/services/view-syncer/schema/types.js.map +1 -1
  484. package/out/zero-cache/src/services/view-syncer/snapshot-row-cache.js +7 -1
  485. package/out/zero-cache/src/services/view-syncer/snapshot-row-cache.js.map +1 -1
  486. package/out/zero-cache/src/services/view-syncer/snapshotter.d.ts +8 -1
  487. package/out/zero-cache/src/services/view-syncer/snapshotter.d.ts.map +1 -1
  488. package/out/zero-cache/src/services/view-syncer/snapshotter.js +7 -6
  489. package/out/zero-cache/src/services/view-syncer/snapshotter.js.map +1 -1
  490. package/out/zero-cache/src/services/view-syncer/ttl-clock.js.map +1 -1
  491. package/out/zero-cache/src/services/view-syncer/view-syncer.d.ts.map +1 -1
  492. package/out/zero-cache/src/services/view-syncer/view-syncer.js +19 -15
  493. package/out/zero-cache/src/services/view-syncer/view-syncer.js.map +1 -1
  494. package/out/zero-cache/src/types/error-with-level.js.map +1 -1
  495. package/out/zero-cache/src/types/lexi-version.js.map +1 -1
  496. package/out/zero-cache/src/types/lite.js +1 -1
  497. package/out/zero-cache/src/types/lite.js.map +1 -1
  498. package/out/zero-cache/src/types/pg-data-type.js +1 -1
  499. package/out/zero-cache/src/types/pg-data-type.js.map +1 -1
  500. package/out/zero-cache/src/types/pg.js +6 -4
  501. package/out/zero-cache/src/types/pg.js.map +1 -1
  502. package/out/zero-cache/src/types/poke-chunk.js +2 -2
  503. package/out/zero-cache/src/types/poke-chunk.js.map +1 -1
  504. package/out/zero-cache/src/types/processes.js +1 -1
  505. package/out/zero-cache/src/types/processes.js.map +1 -1
  506. package/out/zero-cache/src/types/profiler.js +1 -1
  507. package/out/zero-cache/src/types/profiler.js.map +1 -1
  508. package/out/zero-cache/src/types/row-key.js.map +1 -1
  509. package/out/zero-cache/src/types/sql.js.map +1 -1
  510. package/out/zero-cache/src/types/streams.js +10 -9
  511. package/out/zero-cache/src/types/streams.js.map +1 -1
  512. package/out/zero-cache/src/types/strings.js.map +1 -1
  513. package/out/zero-cache/src/types/subscription.js.map +1 -1
  514. package/out/zero-cache/src/types/timeout.js +1 -1
  515. package/out/zero-cache/src/types/websocket-handoff.js +1 -1
  516. package/out/zero-cache/src/types/ws.js +1 -1
  517. package/out/zero-cache/src/workers/connection.js +5 -6
  518. package/out/zero-cache/src/workers/connection.js.map +1 -1
  519. package/out/zero-cache/src/workers/mutator.js.map +1 -1
  520. package/out/zero-cache/src/workers/replicator.js +5 -4
  521. package/out/zero-cache/src/workers/replicator.js.map +1 -1
  522. package/out/zero-cache/src/workers/syncer-ws-message-handler.d.ts.map +1 -1
  523. package/out/zero-cache/src/workers/syncer-ws-message-handler.js +9 -1
  524. package/out/zero-cache/src/workers/syncer-ws-message-handler.js.map +1 -1
  525. package/out/zero-cache/src/workers/syncer.js +4 -4
  526. package/out/zero-cache/src/workers/syncer.js.map +1 -1
  527. package/out/zero-client/src/client/active-clients-manager.js +1 -1
  528. package/out/zero-client/src/client/active-clients-manager.js.map +1 -1
  529. package/out/zero-client/src/client/bindings.js +11 -11
  530. package/out/zero-client/src/client/connection-manager.js.map +1 -1
  531. package/out/zero-client/src/client/connection.js +1 -1
  532. package/out/zero-client/src/client/connection.js.map +1 -1
  533. package/out/zero-client/src/client/context.js.map +1 -1
  534. package/out/zero-client/src/client/crud-impl.js +1 -1
  535. package/out/zero-client/src/client/crud-impl.js.map +1 -1
  536. package/out/zero-client/src/client/crud.js +1 -1
  537. package/out/zero-client/src/client/crud.js.map +1 -1
  538. package/out/zero-client/src/client/custom.js +1 -1
  539. package/out/zero-client/src/client/custom.js.map +1 -1
  540. package/out/zero-client/src/client/delete-clients-manager.js.map +1 -1
  541. package/out/zero-client/src/client/enable-analytics.js +1 -1
  542. package/out/zero-client/src/client/enable-analytics.js.map +1 -1
  543. package/out/zero-client/src/client/error.js.map +1 -1
  544. package/out/zero-client/src/client/inspector/client-group.js.map +1 -1
  545. package/out/zero-client/src/client/inspector/client.js.map +1 -1
  546. package/out/zero-client/src/client/inspector/html-dialog-prompt.js +1 -1
  547. package/out/zero-client/src/client/inspector/html-dialog-prompt.js.map +1 -1
  548. package/out/zero-client/src/client/inspector/inspector.js.map +1 -1
  549. package/out/zero-client/src/client/inspector/lazy-inspector.js.map +1 -1
  550. package/out/zero-client/src/client/inspector/query.js.map +1 -1
  551. package/out/zero-client/src/client/ivm-branch.js +1 -3
  552. package/out/zero-client/src/client/ivm-branch.js.map +1 -1
  553. package/out/zero-client/src/client/keys.js +2 -1
  554. package/out/zero-client/src/client/keys.js.map +1 -1
  555. package/out/zero-client/src/client/log-options.js.map +1 -1
  556. package/out/zero-client/src/client/make-replicache-mutators.js +5 -3
  557. package/out/zero-client/src/client/make-replicache-mutators.js.map +1 -1
  558. package/out/zero-client/src/client/metrics.js +3 -5
  559. package/out/zero-client/src/client/metrics.js.map +1 -1
  560. package/out/zero-client/src/client/mutation-tracker.js.map +1 -1
  561. package/out/zero-client/src/client/mutator-proxy.js.map +1 -1
  562. package/out/zero-client/src/client/options.js.map +1 -1
  563. package/out/zero-client/src/client/query-manager.js +2 -2
  564. package/out/zero-client/src/client/query-manager.js.map +1 -1
  565. package/out/zero-client/src/client/reload-error-handler.js +4 -3
  566. package/out/zero-client/src/client/reload-error-handler.js.map +1 -1
  567. package/out/zero-client/src/client/version.js +1 -1
  568. package/out/zero-client/src/client/zero-poke-handler.js +1 -1
  569. package/out/zero-client/src/client/zero-poke-handler.js.map +1 -1
  570. package/out/zero-client/src/client/zero-rep.js.map +1 -1
  571. package/out/zero-client/src/client/zero.js +19 -11
  572. package/out/zero-client/src/client/zero.js.map +1 -1
  573. package/out/zero-client/src/mod.js +23 -23
  574. package/out/zero-client/src/util/nanoid.js.map +1 -1
  575. package/out/zero-permissions/src/permissions.js +3 -2
  576. package/out/zero-permissions/src/permissions.js.map +1 -1
  577. package/out/zero-pg/src/mod.js +9 -9
  578. package/out/zero-protocol/src/analyze-query-result.js +1 -1
  579. package/out/zero-protocol/src/analyze-query-result.js.map +1 -1
  580. package/out/zero-protocol/src/application-error.js.map +1 -1
  581. package/out/zero-protocol/src/ast.js +19 -9
  582. package/out/zero-protocol/src/ast.js.map +1 -1
  583. package/out/zero-protocol/src/change-desired-queries.js.map +1 -1
  584. package/out/zero-protocol/src/client-schema.js +1 -1
  585. package/out/zero-protocol/src/client-schema.js.map +1 -1
  586. package/out/zero-protocol/src/close-connection.js +1 -1
  587. package/out/zero-protocol/src/close-connection.js.map +1 -1
  588. package/out/zero-protocol/src/connect.js +1 -1
  589. package/out/zero-protocol/src/connect.js.map +1 -1
  590. package/out/zero-protocol/src/custom-queries.js +1 -1
  591. package/out/zero-protocol/src/custom-queries.js.map +1 -1
  592. package/out/zero-protocol/src/data.js +4 -2
  593. package/out/zero-protocol/src/data.js.map +1 -1
  594. package/out/zero-protocol/src/delete-clients.js.map +1 -1
  595. package/out/zero-protocol/src/down.d.ts +27 -27
  596. package/out/zero-protocol/src/down.js.map +1 -1
  597. package/out/zero-protocol/src/error.js.map +1 -1
  598. package/out/zero-protocol/src/inspect-down.d.ts +81 -81
  599. package/out/zero-protocol/src/inspect-down.js +1 -1
  600. package/out/zero-protocol/src/inspect-down.js.map +1 -1
  601. package/out/zero-protocol/src/inspect-up.js +1 -1
  602. package/out/zero-protocol/src/inspect-up.js.map +1 -1
  603. package/out/zero-protocol/src/mutate-server.js +1 -1
  604. package/out/zero-protocol/src/mutate-server.js.map +1 -1
  605. package/out/zero-protocol/src/mutation-id.js.map +1 -1
  606. package/out/zero-protocol/src/mutation.js +1 -1
  607. package/out/zero-protocol/src/mutation.js.map +1 -1
  608. package/out/zero-protocol/src/mutations-patch.js +1 -1
  609. package/out/zero-protocol/src/mutations-patch.js.map +1 -1
  610. package/out/zero-protocol/src/ping.js +1 -1
  611. package/out/zero-protocol/src/ping.js.map +1 -1
  612. package/out/zero-protocol/src/poke.d.ts +6 -6
  613. package/out/zero-protocol/src/poke.js +1 -1
  614. package/out/zero-protocol/src/poke.js.map +1 -1
  615. package/out/zero-protocol/src/pong.js +1 -1
  616. package/out/zero-protocol/src/pong.js.map +1 -1
  617. package/out/zero-protocol/src/primary-key.js.map +1 -1
  618. package/out/zero-protocol/src/protocol-version.js +1 -0
  619. package/out/zero-protocol/src/protocol-version.js.map +1 -1
  620. package/out/zero-protocol/src/pull.js +1 -1
  621. package/out/zero-protocol/src/pull.js.map +1 -1
  622. package/out/zero-protocol/src/push.js +1 -1
  623. package/out/zero-protocol/src/push.js.map +1 -1
  624. package/out/zero-protocol/src/queries-patch.js +1 -1
  625. package/out/zero-protocol/src/queries-patch.js.map +1 -1
  626. package/out/zero-protocol/src/query-hash-visitor.js.map +1 -1
  627. package/out/zero-protocol/src/query-hash.js +2 -2
  628. package/out/zero-protocol/src/query-server.js +1 -1
  629. package/out/zero-protocol/src/query-server.js.map +1 -1
  630. package/out/zero-protocol/src/row-patch.js.map +1 -1
  631. package/out/zero-protocol/src/up.d.ts +60 -60
  632. package/out/zero-protocol/src/up.js.map +1 -1
  633. package/out/zero-protocol/src/update-auth.js.map +1 -1
  634. package/out/zero-protocol/src/version.js.map +1 -1
  635. package/out/zero-react/src/bindings.js +11 -11
  636. package/out/zero-react/src/mod.js +5 -5
  637. package/out/zero-react/src/use-query.js +1 -1
  638. package/out/zero-react/src/use-query.js.map +1 -1
  639. package/out/zero-react/src/zero-provider.d.ts +1 -1
  640. package/out/zero-react/src/zero-provider.d.ts.map +1 -1
  641. package/out/zero-react/src/zero-provider.js +2 -1
  642. package/out/zero-react/src/zero-provider.js.map +1 -1
  643. package/out/zero-react/src/zero.js +23 -23
  644. package/out/zero-schema/src/builder/schema-builder.js +3 -2
  645. package/out/zero-schema/src/builder/schema-builder.js.map +1 -1
  646. package/out/zero-schema/src/builder/table-builder.js +1 -1
  647. package/out/zero-schema/src/builder/table-builder.js.map +1 -1
  648. package/out/zero-schema/src/compiled-permissions.js.map +1 -1
  649. package/out/zero-schema/src/name-mapper.js +7 -5
  650. package/out/zero-schema/src/name-mapper.js.map +1 -1
  651. package/out/zero-schema/src/schema-config.js +1 -1
  652. package/out/zero-schema/src/schema-config.js.map +1 -1
  653. package/out/zero-server/src/adapters/drizzle.js.map +1 -1
  654. package/out/zero-server/src/adapters/kysely.js.map +1 -1
  655. package/out/zero-server/src/adapters/pg.js.map +1 -1
  656. package/out/zero-server/src/adapters/postgresjs.js.map +1 -1
  657. package/out/zero-server/src/adapters/prisma.js.map +1 -1
  658. package/out/zero-server/src/closable-db-transaction.js.map +1 -1
  659. package/out/zero-server/src/custom.js +1 -1
  660. package/out/zero-server/src/custom.js.map +1 -1
  661. package/out/zero-server/src/mod.js +8 -8
  662. package/out/zero-server/src/process-mutations.js.map +1 -1
  663. package/out/zero-server/src/push-processor.js.map +1 -1
  664. package/out/zero-server/src/queries/process-queries.js +2 -1
  665. package/out/zero-server/src/queries/process-queries.js.map +1 -1
  666. package/out/zero-server/src/schema.js +7 -7
  667. package/out/zero-server/src/schema.js.map +1 -1
  668. package/out/zero-server/src/zql-database.js.map +1 -1
  669. package/out/zero-solid/src/bindings.js +11 -11
  670. package/out/zero-solid/src/mod.js +5 -5
  671. package/out/zero-solid/src/solid-view.js +1 -1
  672. package/out/zero-solid/src/solid-view.js.map +1 -1
  673. package/out/zero-solid/src/use-connection-state.js +2 -1
  674. package/out/zero-solid/src/use-connection-state.js.map +1 -1
  675. package/out/zero-solid/src/use-query.js.map +1 -1
  676. package/out/zero-solid/src/use-zero-online.js +2 -1
  677. package/out/zero-solid/src/use-zero-online.js.map +1 -1
  678. package/out/zero-solid/src/use-zero.js +3 -2
  679. package/out/zero-solid/src/use-zero.js.map +1 -1
  680. package/out/zero-solid/src/zero.js +23 -23
  681. package/out/zero-types/src/name-mapper.js.map +1 -1
  682. package/out/zql/src/builder/builder.js +15 -13
  683. package/out/zql/src/builder/builder.js.map +1 -1
  684. package/out/zql/src/builder/correlated-predicate-pushdown.js.map +1 -1
  685. package/out/zql/src/builder/debug-delegate.js.map +1 -1
  686. package/out/zql/src/builder/like.js +0 -1
  687. package/out/zql/src/builder/like.js.map +1 -1
  688. package/out/zql/src/ivm/array-view.js.map +1 -1
  689. package/out/zql/src/ivm/cap.d.ts +1 -1
  690. package/out/zql/src/ivm/cap.d.ts.map +1 -1
  691. package/out/zql/src/ivm/cap.js +10 -0
  692. package/out/zql/src/ivm/cap.js.map +1 -1
  693. package/out/zql/src/ivm/constraint.js +1 -1
  694. package/out/zql/src/ivm/constraint.js.map +1 -1
  695. package/out/zql/src/ivm/data.d.ts +15 -1
  696. package/out/zql/src/ivm/data.d.ts.map +1 -1
  697. package/out/zql/src/ivm/data.js +15 -1
  698. package/out/zql/src/ivm/data.js.map +1 -1
  699. package/out/zql/src/ivm/deferred-input.js.map +1 -1
  700. package/out/zql/src/ivm/exists.d.ts.map +1 -1
  701. package/out/zql/src/ivm/exists.js +32 -22
  702. package/out/zql/src/ivm/exists.js.map +1 -1
  703. package/out/zql/src/ivm/fan-in.js.map +1 -1
  704. package/out/zql/src/ivm/fan-out.js.map +1 -1
  705. package/out/zql/src/ivm/filter-operators.d.ts +5 -0
  706. package/out/zql/src/ivm/filter-operators.d.ts.map +1 -1
  707. package/out/zql/src/ivm/filter-operators.js +1 -1
  708. package/out/zql/src/ivm/filter-operators.js.map +1 -1
  709. package/out/zql/src/ivm/filter-push.js.map +1 -1
  710. package/out/zql/src/ivm/filter.js.map +1 -1
  711. package/out/zql/src/ivm/flipped-join.js +1 -3
  712. package/out/zql/src/ivm/flipped-join.js.map +1 -1
  713. package/out/zql/src/ivm/join-index-tap.js.map +1 -1
  714. package/out/zql/src/ivm/join-index.js.map +1 -1
  715. package/out/zql/src/ivm/join-utils.js +11 -13
  716. package/out/zql/src/ivm/join-utils.js.map +1 -1
  717. package/out/zql/src/ivm/join.d.ts.map +1 -1
  718. package/out/zql/src/ivm/join.js +6 -3
  719. package/out/zql/src/ivm/join.js.map +1 -1
  720. package/out/zql/src/ivm/maybe-split-and-push-edit-change.js.map +1 -1
  721. package/out/zql/src/ivm/memory-source.js +27 -23
  722. package/out/zql/src/ivm/memory-source.js.map +1 -1
  723. package/out/zql/src/ivm/memory-storage.js.map +1 -1
  724. package/out/zql/src/ivm/operator.d.ts +6 -0
  725. package/out/zql/src/ivm/operator.d.ts.map +1 -1
  726. package/out/zql/src/ivm/operator.js +2 -2
  727. package/out/zql/src/ivm/operator.js.map +1 -1
  728. package/out/zql/src/ivm/push-accumulated.js +0 -1
  729. package/out/zql/src/ivm/push-accumulated.js.map +1 -1
  730. package/out/zql/src/ivm/skip-yields.js.map +1 -1
  731. package/out/zql/src/ivm/skip.js.map +1 -1
  732. package/out/zql/src/ivm/take-gate.js.map +1 -1
  733. package/out/zql/src/ivm/take.d.ts.map +1 -1
  734. package/out/zql/src/ivm/take.js +5 -4
  735. package/out/zql/src/ivm/take.js.map +1 -1
  736. package/out/zql/src/ivm/union-fan-in.js +1 -1
  737. package/out/zql/src/ivm/union-fan-in.js.map +1 -1
  738. package/out/zql/src/ivm/union-fan-out.js.map +1 -1
  739. package/out/zql/src/ivm/view-apply-change.js +1 -1
  740. package/out/zql/src/ivm/view-apply-change.js.map +1 -1
  741. package/out/zql/src/mutate/crud.js +3 -2
  742. package/out/zql/src/mutate/crud.js.map +1 -1
  743. package/out/zql/src/planner/planner-builder.js +1 -1
  744. package/out/zql/src/planner/planner-builder.js.map +1 -1
  745. package/out/zql/src/planner/planner-connection.js.map +1 -1
  746. package/out/zql/src/planner/planner-debug.js.map +1 -1
  747. package/out/zql/src/planner/planner-fan-in.js.map +1 -1
  748. package/out/zql/src/planner/planner-fan-out.js.map +1 -1
  749. package/out/zql/src/planner/planner-filter.js.map +1 -1
  750. package/out/zql/src/planner/planner-graph.js +1 -5
  751. package/out/zql/src/planner/planner-graph.js.map +1 -1
  752. package/out/zql/src/planner/planner-join.js +1 -1
  753. package/out/zql/src/planner/planner-join.js.map +1 -1
  754. package/out/zql/src/planner/planner-source.js.map +1 -1
  755. package/out/zql/src/planner/planner-terminus.js.map +1 -1
  756. package/out/zql/src/query/create-builder.js +2 -1
  757. package/out/zql/src/query/create-builder.js.map +1 -1
  758. package/out/zql/src/query/expression.js +1 -1
  759. package/out/zql/src/query/expression.js.map +1 -1
  760. package/out/zql/src/query/measure-push-operator.js.map +1 -1
  761. package/out/zql/src/query/named.js +2 -1
  762. package/out/zql/src/query/named.js.map +1 -1
  763. package/out/zql/src/query/query-delegate-base.js +1 -1
  764. package/out/zql/src/query/query-delegate-base.js.map +1 -1
  765. package/out/zql/src/query/query-impl.js +3 -2
  766. package/out/zql/src/query/query-impl.js.map +1 -1
  767. package/out/zql/src/query/query-registry.js +1 -1
  768. package/out/zql/src/query/query-registry.js.map +1 -1
  769. package/out/zql/src/query/query-transitions.js +1 -1
  770. package/out/zql/src/query/query-transitions.js.map +1 -1
  771. package/out/zql/src/query/runnable-query-impl.js +3 -2
  772. package/out/zql/src/query/runnable-query-impl.js.map +1 -1
  773. package/out/zql/src/query/static-query.js.map +1 -1
  774. package/out/zql/src/query/ttl.js +8 -8
  775. package/out/zql/src/query/ttl.js.map +1 -1
  776. package/out/zql/src/query/validate-input.js.map +1 -1
  777. package/out/zqlite/src/database-storage.d.ts +27 -8
  778. package/out/zqlite/src/database-storage.d.ts.map +1 -1
  779. package/out/zqlite/src/database-storage.js +190 -53
  780. package/out/zqlite/src/database-storage.js.map +1 -1
  781. package/out/zqlite/src/db.d.ts +47 -1
  782. package/out/zqlite/src/db.d.ts.map +1 -1
  783. package/out/zqlite/src/db.js +121 -21
  784. package/out/zqlite/src/db.js.map +1 -1
  785. package/out/zqlite/src/explain-queries.js.map +1 -1
  786. package/out/zqlite/src/fetch-sql.js.map +1 -1
  787. package/out/zqlite/src/index-usage.js.map +1 -1
  788. package/out/zqlite/src/internal/sql-inline.js.map +1 -1
  789. package/out/zqlite/src/internal/sql.js.map +1 -1
  790. package/out/zqlite/src/internal/statement-cache.d.ts +7 -0
  791. package/out/zqlite/src/internal/statement-cache.d.ts.map +1 -1
  792. package/out/zqlite/src/internal/statement-cache.js +11 -4
  793. package/out/zqlite/src/internal/statement-cache.js.map +1 -1
  794. package/out/zqlite/src/mod.js +5 -5
  795. package/out/zqlite/src/pending-delta.js.map +1 -1
  796. package/out/zqlite/src/query-builder.js +1 -1
  797. package/out/zqlite/src/query-builder.js.map +1 -1
  798. package/out/zqlite/src/query-delegate.js.map +1 -1
  799. package/out/zqlite/src/resolve-scalar-subqueries.js +2 -5
  800. package/out/zqlite/src/resolve-scalar-subqueries.js.map +1 -1
  801. package/out/zqlite/src/sqlite-cost-model.js +3 -2
  802. package/out/zqlite/src/sqlite-cost-model.js.map +1 -1
  803. package/out/zqlite/src/sqlite-stat-fanout.js.map +1 -1
  804. package/out/zqlite/src/table-source.d.ts +11 -0
  805. package/out/zqlite/src/table-source.d.ts.map +1 -1
  806. package/out/zqlite/src/table-source.js +63 -26
  807. package/out/zqlite/src/table-source.js.map +1 -1
  808. package/package.json +37 -36
  809. package/out/analyze-query/src/bin-analyze.d.ts +0 -2
  810. package/out/analyze-query/src/bin-analyze.d.ts.map +0 -1
  811. package/out/analyze-query/src/bin-analyze.js +0 -283
  812. package/out/analyze-query/src/bin-analyze.js.map +0 -1
  813. package/out/otel/src/maybe-time.d.ts +0 -3
  814. package/out/otel/src/maybe-time.d.ts.map +0 -1
  815. package/out/otel/src/maybe-time.js +0 -15
  816. package/out/otel/src/maybe-time.js.map +0 -1
  817. package/out/zero/src/analyze-query.d.ts +0 -3
  818. package/out/zero/src/analyze-query.d.ts.map +0 -1
  819. package/out/zero/src/analyze-query.js +0 -3
@@ -1,4 +1,4 @@
1
- //#region \0@oxc-project+runtime@0.130.0/helpers/usingCtx.js
1
+ //#region \0@oxc-project+runtime@0.154.0/helpers/esm/usingCtx.js
2
2
  function _usingCtx() {
3
3
  var r = "function" == typeof SuppressedError ? SuppressedError : function(r, e) {
4
4
  var n = Error();
@@ -54,4 +54,4 @@ function _usingCtx() {
54
54
  };
55
55
  }
56
56
  //#endregion
57
- export { _usingCtx };
57
+ export { _usingCtx as default };
@@ -1 +1 @@
1
- {"version":3,"file":"analyze-cli.d.ts","sourceRoot":"","sources":["../../../../analyze-query/src/analyze-cli.ts"],"names":[],"mappings":"AAAA,OAAO,4BAA4B,CAAC;AAcpC,OAAO,KAAK,EAAC,MAAM,EAAC,MAAM,gCAAgC,CAAC;AAM3D,MAAM,MAAM,iBAAiB,GAAG;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,2CAA2C;IAC3C,IAAI,CAAC,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,CAAC;CACtC,CAAC;AAuHF;;;;;;;;;;;;;GAaG;AACH,wBAAsB,aAAa,CAAC,IAAI,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC,CAiG1E"}
1
+ {"version":3,"file":"analyze-cli.d.ts","sourceRoot":"","sources":["../../../../analyze-query/src/analyze-cli.ts"],"names":[],"mappings":"AAAA,OAAO,4BAA4B,CAAC;AAcpC,OAAO,KAAK,EAAC,MAAM,EAAC,MAAM,gCAAgC,CAAC;AAO3D,MAAM,MAAM,iBAAiB,GAAG;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,2CAA2C;IAC3C,IAAI,CAAC,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,CAAC;CACtC,CAAC;AAuHF;;;;;;;;;;;;;GAaG;AACH,wBAAsB,aAAa,CAAC,IAAI,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC,CAiG1E"}
@@ -7,9 +7,10 @@ import { logLevel, logOptions } from "../../otel/src/log-options.js";
7
7
  import { colorConsole } from "../../shared/src/logging.js";
8
8
  import { parseOptions } from "../../shared/src/options.js";
9
9
  import { ZERO_ENV_VAR_PREFIX } from "../../zero-cache/src/config/zero-config.js";
10
+ import { evaluateZQLChain } from "./zql-chain.js";
10
11
  import { Console } from "node:console";
11
12
  import { styleText } from "node:util";
12
- import { WebSocket as WebSocket$1 } from "ws";
13
+ import { WebSocket } from "ws";
13
14
  //#region ../analyze-query/src/analyze-cli.ts
14
15
  var options = {
15
16
  zeroCacheURL: {
@@ -101,8 +102,9 @@ var stderrLogSink = { log(level, context, ...args) {
101
102
  * Exits the process with code 1 on error.
102
103
  */
103
104
  async function runAnalyzeCLI(opts) {
105
+ const argv = (opts.argv ?? process.argv.slice(2)).map((s) => s.replaceAll("\n", " "));
104
106
  const config = parseOptions(options, {
105
- argv: (opts.argv ?? process.argv.slice(2)).map((s) => s.replaceAll("\n", " ")),
107
+ argv,
106
108
  envNamePrefix: ZERO_ENV_VAR_PREFIX,
107
109
  description: [{
108
110
  header: "analyze-query (remote)",
@@ -195,7 +197,7 @@ function buildQueryPlan(config) {
195
197
  };
196
198
  }
197
199
  function buildZqlQuery(queryString, builder) {
198
- return new Function("builder", `return builder.${queryString};`)(builder);
200
+ return evaluateZQLChain(queryString, builder);
199
201
  }
200
202
  function resolveHandshakeHeaders(config) {
201
203
  const headers = {};
@@ -223,7 +225,7 @@ function resolveHandshakeHeaders(config) {
223
225
  return headers;
224
226
  }
225
227
  function installWebSocketHeaderShim(headers) {
226
- class HeaderInjectingWebSocket extends WebSocket$1 {
228
+ class HeaderInjectingWebSocket extends WebSocket {
227
229
  constructor(url, protocols) {
228
230
  super(url, protocols, { headers });
229
231
  }
@@ -1 +1 @@
1
- {"version":3,"file":"analyze-cli.js","names":[],"sources":["../../../../analyze-query/src/analyze-cli.ts"],"sourcesContent":["import '../../shared/src/dotenv.ts';\n\nimport {Console} from 'node:console';\nimport {styleText} from 'node:util';\nimport type {LogSink} from '@rocicorp/logger';\nimport {WebSocket as NodeWebSocket} from 'ws';\nimport {logLevel, logOptions} from '../../otel/src/log-options.ts';\nimport {colorConsole} from '../../shared/src/logging.ts';\nimport {parseOptions} from '../../shared/src/options.ts';\nimport * as v from '../../shared/src/valita.ts';\nimport {ZERO_ENV_VAR_PREFIX} from '../../zero-cache/src/config/zero-config.ts';\nimport {Zero} from '../../zero-client/src/client/zero.ts';\nimport type {AnalyzeQueryResult} from '../../zero-protocol/src/analyze-query-result.ts';\nimport type {AST} from '../../zero-protocol/src/ast.ts';\nimport type {Schema} from '../../zero-types/src/schema.ts';\nimport {formatPlannerEvents} from '../../zql/src/planner/planner-debug.ts';\nimport {createBuilder} from '../../zql/src/query/create-builder.ts';\nimport type {AnyQuery} from '../../zql/src/query/query.ts';\nimport type {SchemaQuery} from '../../zql/src/query/schema-query.ts';\n\nexport type AnalyzeCLIOptions = {\n schema: Schema;\n /** Defaults to `process.argv.slice(2)`. */\n argv?: readonly string[] | undefined;\n};\n\nconst options = {\n zeroCacheURL: {\n type: v.string().optional(),\n desc: [\n 'URL of the remote zero-cache to analyze against.',\n 'Accepts http(s):// or ws(s):// (ws(s) is the transport actually used).',\n ],\n },\n adminPassword: {\n type: v.string().optional(),\n desc: [\n 'Admin password for zero-cache.',\n 'Required when the server is configured with one; ignored in dev mode.',\n ],\n },\n authToken: {\n type: v.string().optional(),\n desc: [\n 'Raw JWT forwarded to zero-cache.',\n 'Used server-side to fill permission variables for the query.',\n ],\n },\n cookie: {\n type: v.string().optional(),\n desc: [\n 'Cookie header value sent on the WebSocket upgrade request,',\n 'e.g. `session=abc; foo=bar`. Use this when zero-cache is behind',\n 'a proxy that resolves auth via cookies. Merged with --headers-json',\n '(--cookie wins on conflict).',\n ],\n },\n headersJson: {\n type: v.string().optional(),\n desc: [\n 'JSON object of arbitrary headers to send on the WebSocket upgrade',\n 'request, e.g. `{\"x-api-key\":\"...\"}`. Escape hatch for exotic auth',\n 'schemes; prefer --auth-token or --cookie when possible.',\n ],\n },\n userId: {\n type: v.string().optional(),\n desc: [\n 'Optional userID to report to zero-cache.',\n 'Omit for anonymous analysis.',\n ],\n },\n ast: {\n type: v.string().optional(),\n desc: [\n 'JSON-encoded AST. Exactly one of --ast / --query / --query-name is required.',\n 'The AST is sent to the server verbatim — provide it in server (post-mapping) form.',\n ],\n },\n query: {\n type: v.string().optional(),\n desc: [\n 'ZQL query in chain form, e.g. `issue.related(\"comments\").limit(10)`.',\n 'Evaluated against the schema you pass to runAnalyzeCLI.',\n ],\n },\n queryName: {\n type: v.string().optional(),\n desc: [\n 'Name of a server-registered custom (named) query.',\n 'The server resolves the name + args via its registered query handler.',\n ],\n },\n queryArgs: {\n type: v.string().optional(),\n desc: [\n 'JSON-encoded array of arguments for --query-name. Defaults to `[]`.',\n ],\n },\n outputVendedRows: {\n type: v.boolean().optional(() => false),\n desc: [\n 'Include the rows read from the replica to execute the query.',\n 'Each row appears once per read.',\n ],\n },\n outputSyncedRows: {\n type: v.boolean().optional(() => false),\n desc: ['Include the rows that would be synced to the client.'],\n },\n joinPlans: {\n type: v.boolean().optional(() => false),\n desc: ['Include join planner diagnostics.'],\n },\n log: {\n ...logOptions,\n level: logLevel.optional(() => 'error'),\n },\n};\n\ntype QueryPlan =\n | {kind: 'ast'; ast: AST}\n | {kind: 'zql'; text: string}\n | {kind: 'named'; name: string; args: ReadonlyArray<unknown>};\n\n// Route all Zero client log output to stderr so stdout contains only the\n// analyze result. Shell redirection (`2>/dev/null`) can then cleanly silence\n// logs without affecting output.\nconst stderrConsole = new Console({\n stdout: process.stderr,\n stderr: process.stderr,\n});\nconst stderrLogSink: LogSink = {\n log(level, context, ...args) {\n const ctx = context\n ? Object.entries(context).map(([k, v]) =>\n v === undefined ? k : `${k}=${v}`,\n )\n : [];\n stderrConsole[level](...ctx, ...args);\n },\n};\n\n/**\n * Entry point for a user's `cli.ts`. Parses argv, connects to a remote\n * zero-cache by standing up an in-process Zero client (in-memory storage,\n * no subscriptions), calls the inspector's `analyze-query` RPC, and\n * renders the result. Intended to be called as:\n *\n * ```ts\n * import {schema} from './schema.ts';\n * import {runAnalyzeCLI} from '@rocicorp/zero/analyze';\n * await runAnalyzeCLI({schema});\n * ```\n *\n * Exits the process with code 1 on error.\n */\nexport async function runAnalyzeCLI(opts: AnalyzeCLIOptions): Promise<void> {\n const argv = (opts.argv ?? process.argv.slice(2)).map(s =>\n s.replaceAll('\\n', ' '),\n );\n\n const config = parseOptions(options, {\n argv,\n envNamePrefix: ZERO_ENV_VAR_PREFIX,\n description: [\n {\n header: 'analyze-query (remote)',\n content: `Analyze a ZQL query against a remote zero-cache.\n\n Connects to zero-cache's inspector protocol and reports the server-observed\n row scans, SQLite query plans, and timings.`,\n },\n {\n header: 'Examples',\n content: ` node cli.ts --zero-cache-url=https://zero.example.com \\\\\n --admin-password=\"$ZERO_ADMIN_PASSWORD\" \\\\\n --query='issue.related(\"comments\").limit(10)'\n\n node cli.ts --zero-cache-url=http://localhost:4848 \\\\\n --ast='\\\\{\"table\": \"issue\", \"limit\": 5\\\\}'\n\n node cli.ts --zero-cache-url=http://localhost:4848 \\\\\n --query-name=issueList --query-args='[]'`,\n },\n ],\n });\n\n if (!config.zeroCacheURL) {\n colorConsole.error('--zero-cache-url is required. See --help for usage.');\n process.exit(1);\n }\n\n const plan = buildQueryPlan(config);\n\n const handshakeHeaders = resolveHandshakeHeaders(config);\n if (Object.keys(handshakeHeaders).length > 0) {\n installWebSocketHeaderShim(handshakeHeaders);\n }\n\n // zero-client and replicache reference a build-time `TESTING` global that\n // bundlers replace with a boolean literal; under node there's no replacement,\n // so provide a runtime default.\n (globalThis as {TESTING?: boolean}).TESTING ??= false;\n\n const z = new Zero({\n schema: opts.schema,\n server: config.zeroCacheURL,\n auth: config.authToken,\n userID: config.userId,\n kvStore: 'mem',\n logLevel: config.log.level,\n logSink: stderrLogSink,\n });\n\n let result: AnalyzeQueryResult;\n try {\n const authOk = await z.inspector.authenticate(config.adminPassword ?? '');\n if (!authOk) {\n throw new Error(\n 'admin password rejected (or --admin-password is required)',\n );\n }\n\n const rpcOptions = {\n vendedRows: config.outputVendedRows,\n syncedRows: config.outputSyncedRows,\n joinPlans: config.joinPlans,\n };\n\n if (plan.kind === 'ast') {\n result = await z.inspector.analyzeServerAST(plan.ast, rpcOptions);\n } else if (plan.kind === 'named') {\n result = await z.inspector.analyzeNamedQuery(\n plan.name,\n plan.args as ReadonlyArray<never>,\n rpcOptions,\n );\n } else {\n const built = buildZqlQuery(plan.text, createBuilder(opts.schema));\n result = await z.inspector.analyzeQuery(built, rpcOptions);\n }\n } catch (e) {\n colorConsole.error(e instanceof Error ? e.message : String(e));\n await z.close().catch(() => {});\n process.exit(1);\n }\n\n renderResult(result, {\n outputSyncedRows: config.outputSyncedRows,\n outputVendedRows: config.outputVendedRows,\n });\n\n await z.close();\n}\n\nfunction buildQueryPlan(config: {\n ast?: string | undefined;\n query?: string | undefined;\n queryName?: string | undefined;\n queryArgs?: string | undefined;\n}): QueryPlan {\n const selectors = [\n config.ast !== undefined && 'ast',\n config.query !== undefined && 'query',\n config.queryName !== undefined && 'queryName',\n ].filter(Boolean) as string[];\n\n if (selectors.length === 0) {\n colorConsole.error(\n 'Exactly one of --ast / --query / --query-name is required.',\n );\n process.exit(1);\n }\n if (selectors.length > 1) {\n colorConsole.error(\n `Only one of --ast / --query / --query-name may be provided; got: ${selectors.join(', ')}`,\n );\n process.exit(1);\n }\n\n if (config.ast !== undefined) {\n return {kind: 'ast', ast: JSON.parse(config.ast) as AST};\n }\n if (config.query !== undefined) {\n return {kind: 'zql', text: config.query};\n }\n const args = config.queryArgs\n ? (JSON.parse(config.queryArgs) as ReadonlyArray<unknown>)\n : [];\n return {kind: 'named', name: config.queryName as string, args};\n}\n\nfunction buildZqlQuery(\n queryString: string,\n builder: SchemaQuery<Schema>,\n): AnyQuery {\n const f = new Function('builder', `return builder.${queryString};`);\n return f(builder) as AnyQuery;\n}\n\nfunction resolveHandshakeHeaders(config: {\n cookie?: string | undefined;\n headersJson?: string | undefined;\n}): Record<string, string> {\n const headers: Record<string, string> = {};\n if (config.headersJson !== undefined) {\n let parsed: unknown;\n try {\n parsed = JSON.parse(config.headersJson);\n } catch (e) {\n colorConsole.error(\n `--headers-json is not valid JSON: ${e instanceof Error ? e.message : String(e)}`,\n );\n process.exit(1);\n }\n if (\n parsed === null ||\n typeof parsed !== 'object' ||\n Array.isArray(parsed)\n ) {\n colorConsole.error('--headers-json must be a JSON object.');\n process.exit(1);\n }\n for (const [k, val] of Object.entries(parsed)) {\n if (typeof val !== 'string') {\n colorConsole.error(\n `--headers-json values must be strings; got ${typeof val} for \"${k}\".`,\n );\n process.exit(1);\n }\n headers[k] = val;\n }\n }\n if (config.cookie !== undefined) {\n headers.cookie = config.cookie;\n }\n return headers;\n}\n\nfunction installWebSocketHeaderShim(headers: Record<string, string>): void {\n class HeaderInjectingWebSocket extends NodeWebSocket {\n constructor(url: string | URL, protocols?: string | string[]) {\n super(url, protocols, {headers});\n }\n }\n (globalThis as {WebSocket?: unknown}).WebSocket = HeaderInjectingWebSocket;\n}\n\nfunction renderResult(\n result: AnalyzeQueryResult,\n opts: {outputSyncedRows: boolean; outputVendedRows: boolean},\n) {\n if (opts.outputSyncedRows) {\n colorConsole.log(styleText(['blue', 'bold'], '=== Synced Rows: ===\\n'));\n for (const [table, rows] of Object.entries(result.syncedRows ?? {})) {\n colorConsole.log(styleText('bold', table + ':'), rows);\n }\n }\n\n colorConsole.log(styleText(['blue', 'bold'], '=== Query Stats: ===\\n'));\n colorConsole.log(\n styleText('bold', 'total synced rows:'),\n result.syncedRowCount,\n );\n\n const readRowCountsByQuery = result.readRowCountsByQuery ?? {};\n let totalRowsRead = 0;\n for (const table of Object.keys(readRowCountsByQuery).sort()) {\n const counts = readRowCountsByQuery[table];\n for (const n of Object.values(counts)) {\n totalRowsRead += n;\n }\n colorConsole.log(styleText('bold', `${table} vended:`), counts);\n }\n colorConsole.log(\n styleText('bold', 'Rows Read (into JS):'),\n colorRowsConsidered(totalRowsRead),\n );\n const duration = result.elapsed ?? result.end - result.start;\n colorConsole.log(styleText('bold', 'time:'), colorTime(duration), 'ms');\n\n if (opts.outputVendedRows) {\n colorConsole.log(\n styleText(['blue', 'bold'], '=== JS Row Scan Values: ===\\n'),\n );\n for (const [table, rows] of Object.entries(result.readRows ?? {})) {\n colorConsole.log(styleText('bold', `${table}:`), rows);\n }\n }\n\n colorConsole.log(\n styleText(['blue', 'bold'], '\\n=== Rows Scanned (by SQLite): ===\\n'),\n );\n const dbScansByQuery = result.dbScansByQuery ?? {};\n let totalNVisit = 0;\n for (const [table, queries] of Object.entries(dbScansByQuery)) {\n colorConsole.log(styleText('bold', `${table}:`), queries);\n for (const count of Object.values(queries)) {\n totalNVisit += count;\n }\n }\n colorConsole.log(\n styleText('bold', 'total rows scanned:'),\n colorRowsConsidered(totalNVisit),\n );\n\n colorConsole.log(styleText(['blue', 'bold'], '\\n\\n=== Query Plans: ===\\n'));\n const plans = result.sqlitePlans ?? {};\n for (const [query, plan] of Object.entries(plans)) {\n colorConsole.log(styleText('bold', 'query'), query);\n colorConsole.log(plan.map((row, i) => colorPlanRow(row, i)).join('\\n'));\n colorConsole.log('\\n');\n }\n\n if (result.warnings.length > 0) {\n colorConsole.log(styleText(['yellow', 'bold'], '=== Warnings: ===\\n'));\n for (const w of result.warnings) {\n colorConsole.log(styleText('yellow', w));\n }\n }\n\n if (result.joinPlans && result.joinPlans.length > 0) {\n colorConsole.log(styleText(['blue', 'bold'], '\\n=== Join Plans: ===\\n'));\n colorConsole.log(formatPlannerEvents(result.joinPlans));\n }\n}\n\nfunction colorTime(duration: number) {\n if (duration < 100) {\n return styleText('green', duration.toFixed(2) + 'ms');\n } else if (duration < 1000) {\n return styleText('yellow', duration.toFixed(2) + 'ms');\n }\n return styleText('red', duration.toFixed(2) + 'ms');\n}\n\nfunction colorRowsConsidered(n: number) {\n if (n < 1000) {\n return styleText('green', n.toString());\n } else if (n < 10000) {\n return styleText('yellow', n.toString());\n }\n return styleText('red', n.toString());\n}\n\nfunction colorPlanRow(row: string, i: number) {\n if (row.includes('SCAN')) {\n if (i === 0) {\n return styleText('yellow', row);\n }\n return styleText('red', row);\n }\n return styleText('green', row);\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"analyze-cli.js","names":["v","NodeWebSocket"],"sources":["../../../../analyze-query/src/analyze-cli.ts"],"sourcesContent":["import '../../shared/src/dotenv.ts';\n\nimport {Console} from 'node:console';\nimport {styleText} from 'node:util';\nimport type {LogSink} from '@rocicorp/logger';\nimport {WebSocket as NodeWebSocket} from 'ws';\nimport {logLevel, logOptions} from '../../otel/src/log-options.ts';\nimport {colorConsole} from '../../shared/src/logging.ts';\nimport {parseOptions} from '../../shared/src/options.ts';\nimport * as v from '../../shared/src/valita.ts';\nimport {ZERO_ENV_VAR_PREFIX} from '../../zero-cache/src/config/zero-config.ts';\nimport {Zero} from '../../zero-client/src/client/zero.ts';\nimport type {AnalyzeQueryResult} from '../../zero-protocol/src/analyze-query-result.ts';\nimport type {AST} from '../../zero-protocol/src/ast.ts';\nimport type {Schema} from '../../zero-types/src/schema.ts';\nimport {formatPlannerEvents} from '../../zql/src/planner/planner-debug.ts';\nimport {createBuilder} from '../../zql/src/query/create-builder.ts';\nimport type {AnyQuery} from '../../zql/src/query/query.ts';\nimport type {SchemaQuery} from '../../zql/src/query/schema-query.ts';\nimport {evaluateZQLChain} from './zql-chain.ts';\n\nexport type AnalyzeCLIOptions = {\n schema: Schema;\n /** Defaults to `process.argv.slice(2)`. */\n argv?: readonly string[] | undefined;\n};\n\nconst options = {\n zeroCacheURL: {\n type: v.string().optional(),\n desc: [\n 'URL of the remote zero-cache to analyze against.',\n 'Accepts http(s):// or ws(s):// (ws(s) is the transport actually used).',\n ],\n },\n adminPassword: {\n type: v.string().optional(),\n desc: [\n 'Admin password for zero-cache.',\n 'Required when the server is configured with one; ignored in dev mode.',\n ],\n },\n authToken: {\n type: v.string().optional(),\n desc: [\n 'Raw JWT forwarded to zero-cache.',\n 'Used server-side to fill permission variables for the query.',\n ],\n },\n cookie: {\n type: v.string().optional(),\n desc: [\n 'Cookie header value sent on the WebSocket upgrade request,',\n 'e.g. `session=abc; foo=bar`. Use this when zero-cache is behind',\n 'a proxy that resolves auth via cookies. Merged with --headers-json',\n '(--cookie wins on conflict).',\n ],\n },\n headersJson: {\n type: v.string().optional(),\n desc: [\n 'JSON object of arbitrary headers to send on the WebSocket upgrade',\n 'request, e.g. `{\"x-api-key\":\"...\"}`. Escape hatch for exotic auth',\n 'schemes; prefer --auth-token or --cookie when possible.',\n ],\n },\n userId: {\n type: v.string().optional(),\n desc: [\n 'Optional userID to report to zero-cache.',\n 'Omit for anonymous analysis.',\n ],\n },\n ast: {\n type: v.string().optional(),\n desc: [\n 'JSON-encoded AST. Exactly one of --ast / --query / --query-name is required.',\n 'The AST is sent to the server verbatim — provide it in server (post-mapping) form.',\n ],\n },\n query: {\n type: v.string().optional(),\n desc: [\n 'ZQL query in chain form, e.g. `issue.related(\"comments\").limit(10)`.',\n 'Evaluated against the schema you pass to runAnalyzeCLI.',\n ],\n },\n queryName: {\n type: v.string().optional(),\n desc: [\n 'Name of a server-registered custom (named) query.',\n 'The server resolves the name + args via its registered query handler.',\n ],\n },\n queryArgs: {\n type: v.string().optional(),\n desc: [\n 'JSON-encoded array of arguments for --query-name. Defaults to `[]`.',\n ],\n },\n outputVendedRows: {\n type: v.boolean().optional(() => false),\n desc: [\n 'Include the rows read from the replica to execute the query.',\n 'Each row appears once per read.',\n ],\n },\n outputSyncedRows: {\n type: v.boolean().optional(() => false),\n desc: ['Include the rows that would be synced to the client.'],\n },\n joinPlans: {\n type: v.boolean().optional(() => false),\n desc: ['Include join planner diagnostics.'],\n },\n log: {\n ...logOptions,\n level: logLevel.optional(() => 'error'),\n },\n};\n\ntype QueryPlan =\n | {kind: 'ast'; ast: AST}\n | {kind: 'zql'; text: string}\n | {kind: 'named'; name: string; args: ReadonlyArray<unknown>};\n\n// Route all Zero client log output to stderr so stdout contains only the\n// analyze result. Shell redirection (`2>/dev/null`) can then cleanly silence\n// logs without affecting output.\nconst stderrConsole = new Console({\n stdout: process.stderr,\n stderr: process.stderr,\n});\nconst stderrLogSink: LogSink = {\n log(level, context, ...args) {\n const ctx = context\n ? Object.entries(context).map(([k, v]) =>\n v === undefined ? k : `${k}=${v}`,\n )\n : [];\n stderrConsole[level](...ctx, ...args);\n },\n};\n\n/**\n * Entry point for a user's `cli.ts`. Parses argv, connects to a remote\n * zero-cache by standing up an in-process Zero client (in-memory storage,\n * no subscriptions), calls the inspector's `analyze-query` RPC, and\n * renders the result. Intended to be called as:\n *\n * ```ts\n * import {schema} from './schema.ts';\n * import {runAnalyzeCLI} from '@rocicorp/zero/analyze';\n * await runAnalyzeCLI({schema});\n * ```\n *\n * Exits the process with code 1 on error.\n */\nexport async function runAnalyzeCLI(opts: AnalyzeCLIOptions): Promise<void> {\n const argv = (opts.argv ?? process.argv.slice(2)).map(s =>\n s.replaceAll('\\n', ' '),\n );\n\n const config = parseOptions(options, {\n argv,\n envNamePrefix: ZERO_ENV_VAR_PREFIX,\n description: [\n {\n header: 'analyze-query (remote)',\n content: `Analyze a ZQL query against a remote zero-cache.\n\n Connects to zero-cache's inspector protocol and reports the server-observed\n row scans, SQLite query plans, and timings.`,\n },\n {\n header: 'Examples',\n content: ` node cli.ts --zero-cache-url=https://zero.example.com \\\\\n --admin-password=\"$ZERO_ADMIN_PASSWORD\" \\\\\n --query='issue.related(\"comments\").limit(10)'\n\n node cli.ts --zero-cache-url=http://localhost:4848 \\\\\n --ast='\\\\{\"table\": \"issue\", \"limit\": 5\\\\}'\n\n node cli.ts --zero-cache-url=http://localhost:4848 \\\\\n --query-name=issueList --query-args='[]'`,\n },\n ],\n });\n\n if (!config.zeroCacheURL) {\n colorConsole.error('--zero-cache-url is required. See --help for usage.');\n process.exit(1);\n }\n\n const plan = buildQueryPlan(config);\n\n const handshakeHeaders = resolveHandshakeHeaders(config);\n if (Object.keys(handshakeHeaders).length > 0) {\n installWebSocketHeaderShim(handshakeHeaders);\n }\n\n // zero-client and replicache reference a build-time `TESTING` global that\n // bundlers replace with a boolean literal; under node there's no replacement,\n // so provide a runtime default.\n (globalThis as {TESTING?: boolean}).TESTING ??= false;\n\n const z = new Zero({\n schema: opts.schema,\n server: config.zeroCacheURL,\n auth: config.authToken,\n userID: config.userId,\n kvStore: 'mem',\n logLevel: config.log.level,\n logSink: stderrLogSink,\n });\n\n let result: AnalyzeQueryResult;\n try {\n const authOk = await z.inspector.authenticate(config.adminPassword ?? '');\n if (!authOk) {\n throw new Error(\n 'admin password rejected (or --admin-password is required)',\n );\n }\n\n const rpcOptions = {\n vendedRows: config.outputVendedRows,\n syncedRows: config.outputSyncedRows,\n joinPlans: config.joinPlans,\n };\n\n if (plan.kind === 'ast') {\n result = await z.inspector.analyzeServerAST(plan.ast, rpcOptions);\n } else if (plan.kind === 'named') {\n result = await z.inspector.analyzeNamedQuery(\n plan.name,\n plan.args as ReadonlyArray<never>,\n rpcOptions,\n );\n } else {\n const built = buildZqlQuery(plan.text, createBuilder(opts.schema));\n result = await z.inspector.analyzeQuery(built, rpcOptions);\n }\n } catch (e) {\n colorConsole.error(e instanceof Error ? e.message : String(e));\n await z.close().catch(() => {});\n process.exit(1);\n }\n\n renderResult(result, {\n outputSyncedRows: config.outputSyncedRows,\n outputVendedRows: config.outputVendedRows,\n });\n\n await z.close();\n}\n\nfunction buildQueryPlan(config: {\n ast?: string | undefined;\n query?: string | undefined;\n queryName?: string | undefined;\n queryArgs?: string | undefined;\n}): QueryPlan {\n const selectors = [\n config.ast !== undefined && 'ast',\n config.query !== undefined && 'query',\n config.queryName !== undefined && 'queryName',\n ].filter(Boolean) as string[];\n\n if (selectors.length === 0) {\n colorConsole.error(\n 'Exactly one of --ast / --query / --query-name is required.',\n );\n process.exit(1);\n }\n if (selectors.length > 1) {\n colorConsole.error(\n `Only one of --ast / --query / --query-name may be provided; got: ${selectors.join(', ')}`,\n );\n process.exit(1);\n }\n\n if (config.ast !== undefined) {\n return {kind: 'ast', ast: JSON.parse(config.ast) as AST};\n }\n if (config.query !== undefined) {\n return {kind: 'zql', text: config.query};\n }\n const args = config.queryArgs\n ? (JSON.parse(config.queryArgs) as ReadonlyArray<unknown>)\n : [];\n return {kind: 'named', name: config.queryName as string, args};\n}\n\nfunction buildZqlQuery(\n queryString: string,\n builder: SchemaQuery<Schema>,\n): AnyQuery {\n return evaluateZQLChain(queryString, builder) as AnyQuery;\n}\n\nfunction resolveHandshakeHeaders(config: {\n cookie?: string | undefined;\n headersJson?: string | undefined;\n}): Record<string, string> {\n const headers: Record<string, string> = {};\n if (config.headersJson !== undefined) {\n let parsed: unknown;\n try {\n parsed = JSON.parse(config.headersJson);\n } catch (e) {\n colorConsole.error(\n `--headers-json is not valid JSON: ${e instanceof Error ? e.message : String(e)}`,\n );\n process.exit(1);\n }\n if (\n parsed === null ||\n typeof parsed !== 'object' ||\n Array.isArray(parsed)\n ) {\n colorConsole.error('--headers-json must be a JSON object.');\n process.exit(1);\n }\n for (const [k, val] of Object.entries(parsed)) {\n if (typeof val !== 'string') {\n colorConsole.error(\n `--headers-json values must be strings; got ${typeof val} for \"${k}\".`,\n );\n process.exit(1);\n }\n headers[k] = val;\n }\n }\n if (config.cookie !== undefined) {\n headers.cookie = config.cookie;\n }\n return headers;\n}\n\nfunction installWebSocketHeaderShim(headers: Record<string, string>): void {\n class HeaderInjectingWebSocket extends NodeWebSocket {\n constructor(url: string | URL, protocols?: string | string[]) {\n super(url, protocols, {headers});\n }\n }\n (globalThis as {WebSocket?: unknown}).WebSocket = HeaderInjectingWebSocket;\n}\n\nfunction renderResult(\n result: AnalyzeQueryResult,\n opts: {outputSyncedRows: boolean; outputVendedRows: boolean},\n) {\n if (opts.outputSyncedRows) {\n colorConsole.log(styleText(['blue', 'bold'], '=== Synced Rows: ===\\n'));\n for (const [table, rows] of Object.entries(result.syncedRows ?? {})) {\n colorConsole.log(styleText('bold', table + ':'), rows);\n }\n }\n\n colorConsole.log(styleText(['blue', 'bold'], '=== Query Stats: ===\\n'));\n colorConsole.log(\n styleText('bold', 'total synced rows:'),\n result.syncedRowCount,\n );\n\n const readRowCountsByQuery = result.readRowCountsByQuery ?? {};\n let totalRowsRead = 0;\n for (const table of Object.keys(readRowCountsByQuery).sort()) {\n const counts = readRowCountsByQuery[table];\n for (const n of Object.values(counts)) {\n totalRowsRead += n;\n }\n colorConsole.log(styleText('bold', `${table} vended:`), counts);\n }\n colorConsole.log(\n styleText('bold', 'Rows Read (into JS):'),\n colorRowsConsidered(totalRowsRead),\n );\n const duration = result.elapsed ?? result.end - result.start;\n colorConsole.log(styleText('bold', 'time:'), colorTime(duration), 'ms');\n\n if (opts.outputVendedRows) {\n colorConsole.log(\n styleText(['blue', 'bold'], '=== JS Row Scan Values: ===\\n'),\n );\n for (const [table, rows] of Object.entries(result.readRows ?? {})) {\n colorConsole.log(styleText('bold', `${table}:`), rows);\n }\n }\n\n colorConsole.log(\n styleText(['blue', 'bold'], '\\n=== Rows Scanned (by SQLite): ===\\n'),\n );\n const dbScansByQuery = result.dbScansByQuery ?? {};\n let totalNVisit = 0;\n for (const [table, queries] of Object.entries(dbScansByQuery)) {\n colorConsole.log(styleText('bold', `${table}:`), queries);\n for (const count of Object.values(queries)) {\n totalNVisit += count;\n }\n }\n colorConsole.log(\n styleText('bold', 'total rows scanned:'),\n colorRowsConsidered(totalNVisit),\n );\n\n colorConsole.log(styleText(['blue', 'bold'], '\\n\\n=== Query Plans: ===\\n'));\n const plans = result.sqlitePlans ?? {};\n for (const [query, plan] of Object.entries(plans)) {\n colorConsole.log(styleText('bold', 'query'), query);\n colorConsole.log(plan.map((row, i) => colorPlanRow(row, i)).join('\\n'));\n colorConsole.log('\\n');\n }\n\n if (result.warnings.length > 0) {\n colorConsole.log(styleText(['yellow', 'bold'], '=== Warnings: ===\\n'));\n for (const w of result.warnings) {\n colorConsole.log(styleText('yellow', w));\n }\n }\n\n if (result.joinPlans && result.joinPlans.length > 0) {\n colorConsole.log(styleText(['blue', 'bold'], '\\n=== Join Plans: ===\\n'));\n colorConsole.log(formatPlannerEvents(result.joinPlans));\n }\n}\n\nfunction colorTime(duration: number) {\n if (duration < 100) {\n return styleText('green', duration.toFixed(2) + 'ms');\n } else if (duration < 1000) {\n return styleText('yellow', duration.toFixed(2) + 'ms');\n }\n return styleText('red', duration.toFixed(2) + 'ms');\n}\n\nfunction colorRowsConsidered(n: number) {\n if (n < 1000) {\n return styleText('green', n.toString());\n } else if (n < 10000) {\n return styleText('yellow', n.toString());\n }\n return styleText('red', n.toString());\n}\n\nfunction colorPlanRow(row: string, i: number) {\n if (row.includes('SCAN')) {\n if (i === 0) {\n return styleText('yellow', row);\n }\n return styleText('red', row);\n }\n return styleText('green', row);\n}\n"],"mappings":";;;;;;;;;;;;;;AA2BA,IAAM,UAAU;CACd,cAAc;EACZ,MAAMA,eAAE,OAAO,CAAC,CAAC,SAAS;EAC1B,MAAM,CACJ,oDACA,wEACF;CACF;CACA,eAAe;EACb,MAAMA,eAAE,OAAO,CAAC,CAAC,SAAS;EAC1B,MAAM,CACJ,kCACA,uEACF;CACF;CACA,WAAW;EACT,MAAMA,eAAE,OAAO,CAAC,CAAC,SAAS;EAC1B,MAAM,CACJ,oCACA,8DACF;CACF;CACA,QAAQ;EACN,MAAMA,eAAE,OAAO,CAAC,CAAC,SAAS;EAC1B,MAAM;GACJ;GACA;GACA;GACA;EACF;CACF;CACA,aAAa;EACX,MAAMA,eAAE,OAAO,CAAC,CAAC,SAAS;EAC1B,MAAM;GACJ;GACA;GACA;EACF;CACF;CACA,QAAQ;EACN,MAAMA,eAAE,OAAO,CAAC,CAAC,SAAS;EAC1B,MAAM,CACJ,4CACA,8BACF;CACF;CACA,KAAK;EACH,MAAMA,eAAE,OAAO,CAAC,CAAC,SAAS;EAC1B,MAAM,CACJ,gFACA,oFACF;CACF;CACA,OAAO;EACL,MAAMA,eAAE,OAAO,CAAC,CAAC,SAAS;EAC1B,MAAM,CACJ,0EACA,yDACF;CACF;CACA,WAAW;EACT,MAAMA,eAAE,OAAO,CAAC,CAAC,SAAS;EAC1B,MAAM,CACJ,qDACA,uEACF;CACF;CACA,WAAW;EACT,MAAMA,eAAE,OAAO,CAAC,CAAC,SAAS;EAC1B,MAAM,CACJ,qEACF;CACF;CACA,kBAAkB;EAChB,MAAMA,eAAE,QAAQ,CAAC,CAAC,eAAe,KAAK;EACtC,MAAM,CACJ,gEACA,iCACF;CACF;CACA,kBAAkB;EAChB,MAAMA,eAAE,QAAQ,CAAC,CAAC,eAAe,KAAK;EACtC,MAAM,CAAC,sDAAsD;CAC/D;CACA,WAAW;EACT,MAAMA,eAAE,QAAQ,CAAC,CAAC,eAAe,KAAK;EACtC,MAAM,CAAC,mCAAmC;CAC5C;CACA,KAAK;EACH,GAAG;EACH,OAAO,SAAS,eAAe,OAAO;CACxC;AACF;AAUA,IAAM,gBAAgB,IAAI,QAAQ;CAChC,QAAQ,QAAQ;CAChB,QAAQ,QAAQ;AAClB,CAAC;AACD,IAAM,gBAAyB,EAC7B,IAAI,OAAO,SAAS,GAAG,MAAM;CAC3B,MAAM,MAAM,UACR,OAAO,QAAQ,OAAO,CAAC,CAAC,KAAK,CAAC,GAAG,OAC/B,MAAM,KAAA,IAAY,IAAI,GAAG,EAAE,GAAG,GAChC,IACA,CAAC;CACL,cAAc,MAAM,CAAC,GAAG,KAAK,GAAG,IAAI;AACtC,EACF;;;;;;;;;;;;;;;AAgBA,eAAsB,cAAc,MAAwC;CAC1E,MAAM,QAAQ,KAAK,QAAQ,QAAQ,KAAK,MAAM,CAAC,EAAA,CAAG,KAAI,MACpD,EAAE,WAAW,MAAM,GAAG,CACxB;CAEA,MAAM,SAAS,aAAa,SAAS;EACnC;EACA,eAAe;EACf,aAAa,CACX;GACE,QAAQ;GACR,SAAS;;;;EAIX,GACA;GACE,QAAQ;GACR,SAAS;;;;;;;;;EASX,CACF;CACF,CAAC;CAED,IAAI,CAAC,OAAO,cAAc;EACxB,aAAa,MAAM,qDAAqD;EACxE,QAAQ,KAAK,CAAC;CAChB;CAEA,MAAM,OAAO,eAAe,MAAM;CAElC,MAAM,mBAAmB,wBAAwB,MAAM;CACvD,IAAI,OAAO,KAAK,gBAAgB,CAAC,CAAC,SAAS,GACzC,2BAA2B,gBAAgB;CAM7C,WAAoC,YAAY;CAEhD,MAAM,IAAI,IAAI,KAAK;EACjB,QAAQ,KAAK;EACb,QAAQ,OAAO;EACf,MAAM,OAAO;EACb,QAAQ,OAAO;EACf,SAAS;EACT,UAAU,OAAO,IAAI;EACrB,SAAS;CACX,CAAC;CAED,IAAI;CACJ,IAAI;EAEF,IAAI,CAAC,MADgB,EAAE,UAAU,aAAa,OAAO,iBAAiB,EAAE,GAEtE,MAAM,IAAI,MACR,2DACF;EAGF,MAAM,aAAa;GACjB,YAAY,OAAO;GACnB,YAAY,OAAO;GACnB,WAAW,OAAO;EACpB;EAEA,IAAI,KAAK,SAAS,OAChB,SAAS,MAAM,EAAE,UAAU,iBAAiB,KAAK,KAAK,UAAU;OAC3D,IAAI,KAAK,SAAS,SACvB,SAAS,MAAM,EAAE,UAAU,kBACzB,KAAK,MACL,KAAK,MACL,UACF;OACK;GACL,MAAM,QAAQ,cAAc,KAAK,MAAM,cAAc,KAAK,MAAM,CAAC;GACjE,SAAS,MAAM,EAAE,UAAU,aAAa,OAAO,UAAU;EAC3D;CACF,SAAS,GAAG;EACV,aAAa,MAAM,aAAa,QAAQ,EAAE,UAAU,OAAO,CAAC,CAAC;EAC7D,MAAM,EAAE,MAAM,CAAC,CAAC,YAAY,CAAC,CAAC;EAC9B,QAAQ,KAAK,CAAC;CAChB;CAEA,aAAa,QAAQ;EACnB,kBAAkB,OAAO;EACzB,kBAAkB,OAAO;CAC3B,CAAC;CAED,MAAM,EAAE,MAAM;AAChB;AAEA,SAAS,eAAe,QAKV;CACZ,MAAM,YAAY;EAChB,OAAO,QAAQ,KAAA,KAAa;EAC5B,OAAO,UAAU,KAAA,KAAa;EAC9B,OAAO,cAAc,KAAA,KAAa;CACpC,CAAC,CAAC,OAAO,OAAO;CAEhB,IAAI,UAAU,WAAW,GAAG;EAC1B,aAAa,MACX,4DACF;EACA,QAAQ,KAAK,CAAC;CAChB;CACA,IAAI,UAAU,SAAS,GAAG;EACxB,aAAa,MACX,oEAAoE,UAAU,KAAK,IAAI,GACzF;EACA,QAAQ,KAAK,CAAC;CAChB;CAEA,IAAI,OAAO,QAAQ,KAAA,GACjB,OAAO;EAAC,MAAM;EAAO,KAAK,KAAK,MAAM,OAAO,GAAG;CAAQ;CAEzD,IAAI,OAAO,UAAU,KAAA,GACnB,OAAO;EAAC,MAAM;EAAO,MAAM,OAAO;CAAK;CAEzC,MAAM,OAAO,OAAO,YACf,KAAK,MAAM,OAAO,SAAS,IAC5B,CAAC;CACL,OAAO;EAAC,MAAM;EAAS,MAAM,OAAO;EAAqB;CAAI;AAC/D;AAEA,SAAS,cACP,aACA,SACU;CACV,OAAO,iBAAiB,aAAa,OAAO;AAC9C;AAEA,SAAS,wBAAwB,QAGN;CACzB,MAAM,UAAkC,CAAC;CACzC,IAAI,OAAO,gBAAgB,KAAA,GAAW;EACpC,IAAI;EACJ,IAAI;GACF,SAAS,KAAK,MAAM,OAAO,WAAW;EACxC,SAAS,GAAG;GACV,aAAa,MACX,qCAAqC,aAAa,QAAQ,EAAE,UAAU,OAAO,CAAC,GAChF;GACA,QAAQ,KAAK,CAAC;EAChB;EACA,IACE,WAAW,QACX,OAAO,WAAW,YAClB,MAAM,QAAQ,MAAM,GACpB;GACA,aAAa,MAAM,uCAAuC;GAC1D,QAAQ,KAAK,CAAC;EAChB;EACA,KAAK,MAAM,CAAC,GAAG,QAAQ,OAAO,QAAQ,MAAM,GAAG;GAC7C,IAAI,OAAO,QAAQ,UAAU;IAC3B,aAAa,MACX,8CAA8C,OAAO,IAAI,QAAQ,EAAE,GACrE;IACA,QAAQ,KAAK,CAAC;GAChB;GACA,QAAQ,KAAK;EACf;CACF;CACA,IAAI,OAAO,WAAW,KAAA,GACpB,QAAQ,SAAS,OAAO;CAE1B,OAAO;AACT;AAEA,SAAS,2BAA2B,SAAuC;CACzE,MAAM,iCAAiCC,UAAc;EACnD,YAAY,KAAmB,WAA+B;GAC5D,MAAM,KAAK,WAAW,EAAC,QAAO,CAAC;EACjC;CACF;CACA,WAAsC,YAAY;AACpD;AAEA,SAAS,aACP,QACA,MACA;CACA,IAAI,KAAK,kBAAkB;EACzB,aAAa,IAAI,UAAU,CAAC,QAAQ,MAAM,GAAG,wBAAwB,CAAC;EACtE,KAAK,MAAM,CAAC,OAAO,SAAS,OAAO,QAAQ,OAAO,cAAc,CAAC,CAAC,GAChE,aAAa,IAAI,UAAU,QAAQ,QAAQ,GAAG,GAAG,IAAI;CAEzD;CAEA,aAAa,IAAI,UAAU,CAAC,QAAQ,MAAM,GAAG,wBAAwB,CAAC;CACtE,aAAa,IACX,UAAU,QAAQ,oBAAoB,GACtC,OAAO,cACT;CAEA,MAAM,uBAAuB,OAAO,wBAAwB,CAAC;CAC7D,IAAI,gBAAgB;CACpB,KAAK,MAAM,SAAS,OAAO,KAAK,oBAAoB,CAAC,CAAC,KAAK,GAAG;EAC5D,MAAM,SAAS,qBAAqB;EACpC,KAAK,MAAM,KAAK,OAAO,OAAO,MAAM,GAClC,iBAAiB;EAEnB,aAAa,IAAI,UAAU,QAAQ,GAAG,MAAM,SAAS,GAAG,MAAM;CAChE;CACA,aAAa,IACX,UAAU,QAAQ,sBAAsB,GACxC,oBAAoB,aAAa,CACnC;CACA,MAAM,WAAW,OAAO,WAAW,OAAO,MAAM,OAAO;CACvD,aAAa,IAAI,UAAU,QAAQ,OAAO,GAAG,UAAU,QAAQ,GAAG,IAAI;CAEtE,IAAI,KAAK,kBAAkB;EACzB,aAAa,IACX,UAAU,CAAC,QAAQ,MAAM,GAAG,+BAA+B,CAC7D;EACA,KAAK,MAAM,CAAC,OAAO,SAAS,OAAO,QAAQ,OAAO,YAAY,CAAC,CAAC,GAC9D,aAAa,IAAI,UAAU,QAAQ,GAAG,MAAM,EAAE,GAAG,IAAI;CAEzD;CAEA,aAAa,IACX,UAAU,CAAC,QAAQ,MAAM,GAAG,uCAAuC,CACrE;CACA,MAAM,iBAAiB,OAAO,kBAAkB,CAAC;CACjD,IAAI,cAAc;CAClB,KAAK,MAAM,CAAC,OAAO,YAAY,OAAO,QAAQ,cAAc,GAAG;EAC7D,aAAa,IAAI,UAAU,QAAQ,GAAG,MAAM,EAAE,GAAG,OAAO;EACxD,KAAK,MAAM,SAAS,OAAO,OAAO,OAAO,GACvC,eAAe;CAEnB;CACA,aAAa,IACX,UAAU,QAAQ,qBAAqB,GACvC,oBAAoB,WAAW,CACjC;CAEA,aAAa,IAAI,UAAU,CAAC,QAAQ,MAAM,GAAG,4BAA4B,CAAC;CAC1E,MAAM,QAAQ,OAAO,eAAe,CAAC;CACrC,KAAK,MAAM,CAAC,OAAO,SAAS,OAAO,QAAQ,KAAK,GAAG;EACjD,aAAa,IAAI,UAAU,QAAQ,OAAO,GAAG,KAAK;EAClD,aAAa,IAAI,KAAK,KAAK,KAAK,MAAM,aAAa,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC;EACtE,aAAa,IAAI,IAAI;CACvB;CAEA,IAAI,OAAO,SAAS,SAAS,GAAG;EAC9B,aAAa,IAAI,UAAU,CAAC,UAAU,MAAM,GAAG,qBAAqB,CAAC;EACrE,KAAK,MAAM,KAAK,OAAO,UACrB,aAAa,IAAI,UAAU,UAAU,CAAC,CAAC;CAE3C;CAEA,IAAI,OAAO,aAAa,OAAO,UAAU,SAAS,GAAG;EACnD,aAAa,IAAI,UAAU,CAAC,QAAQ,MAAM,GAAG,yBAAyB,CAAC;EACvE,aAAa,IAAI,oBAAoB,OAAO,SAAS,CAAC;CACxD;AACF;AAEA,SAAS,UAAU,UAAkB;CACnC,IAAI,WAAW,KACb,OAAO,UAAU,SAAS,SAAS,QAAQ,CAAC,IAAI,IAAI;MAC/C,IAAI,WAAW,KACpB,OAAO,UAAU,UAAU,SAAS,QAAQ,CAAC,IAAI,IAAI;CAEvD,OAAO,UAAU,OAAO,SAAS,QAAQ,CAAC,IAAI,IAAI;AACpD;AAEA,SAAS,oBAAoB,GAAW;CACtC,IAAI,IAAI,KACN,OAAO,UAAU,SAAS,EAAE,SAAS,CAAC;MACjC,IAAI,IAAI,KACb,OAAO,UAAU,UAAU,EAAE,SAAS,CAAC;CAEzC,OAAO,UAAU,OAAO,EAAE,SAAS,CAAC;AACtC;AAEA,SAAS,aAAa,KAAa,GAAW;CAC5C,IAAI,IAAI,SAAS,MAAM,GAAG;EACxB,IAAI,MAAM,GACR,OAAO,UAAU,UAAU,GAAG;EAEhC,OAAO,UAAU,OAAO,GAAG;CAC7B;CACA,OAAO,UAAU,SAAS,GAAG;AAC/B"}
@@ -4,14 +4,14 @@ import "../../shared/src/dotenv.js";
4
4
  import { parseOptions } from "../../shared/src/options.js";
5
5
  import { getShardID, upstreamSchema } from "../../zero-cache/src/types/shards.js";
6
6
  import { ZERO_ENV_VAR_PREFIX, appOptions, shardOptions } from "../../zero-cache/src/config/zero-config.js";
7
+ import { loadSchemaAndPermissions } from "../../zero-cache/src/scripts/permissions.js";
7
8
  import { astToZQL } from "../../ast-to-zql/src/ast-to-zql.js";
8
9
  import { formatOutput } from "../../ast-to-zql/src/format.js";
9
- import { loadSchemaAndPermissions } from "../../zero-cache/src/scripts/permissions.js";
10
10
  import { transformAndHashQuery } from "../../zero-cache/src/auth/read-authorizer.js";
11
11
  import { pgClient } from "../../zero-cache/src/types/pg.js";
12
12
  import { LogContext, consoleLogSink } from "@rocicorp/logger";
13
13
  //#region ../analyze-query/src/bin-transform.ts
14
- var config = parseOptions({
14
+ var options = {
15
15
  cvr: { db: valita_exports.string() },
16
16
  schema: {
17
17
  type: valita_exports.string().optional(() => "./schema.ts"),
@@ -23,7 +23,8 @@ var config = parseOptions({
23
23
  type: valita_exports.string().optional(),
24
24
  desc: ["Hash of the query to fetch the AST for."]
25
25
  }
26
- }, { envNamePrefix: ZERO_ENV_VAR_PREFIX });
26
+ };
27
+ var config = parseOptions(options, { envNamePrefix: ZERO_ENV_VAR_PREFIX });
27
28
  var lc = new LogContext("debug", {}, consoleLogSink);
28
29
  var { permissions } = await loadSchemaAndPermissions(config.schema);
29
30
  var cvrDB = pgClient(lc, config.cvr.db, "analyze-query-transform-cvr");
@@ -1 +1 @@
1
- {"version":3,"file":"bin-transform.js","names":[],"sources":["../../../../analyze-query/src/bin-transform.ts"],"sourcesContent":["import '../../shared/src/dotenv.ts';\n\nimport {consoleLogSink, LogContext} from '@rocicorp/logger';\nimport {astToZQL} from '../../ast-to-zql/src/ast-to-zql.ts';\nimport {formatOutput} from '../../ast-to-zql/src/format.ts';\nimport {must} from '../../shared/src/must.ts';\nimport {parseOptions} from '../../shared/src/options.ts';\nimport * as v from '../../shared/src/valita.ts';\nimport {transformAndHashQuery} from '../../zero-cache/src/auth/read-authorizer.ts';\nimport {\n appOptions,\n shardOptions,\n ZERO_ENV_VAR_PREFIX,\n} from '../../zero-cache/src/config/zero-config.ts';\nimport {loadSchemaAndPermissions} from '../../zero-cache/src/scripts/permissions.ts';\nimport {pgClient} from '../../zero-cache/src/types/pg.ts';\nimport {getShardID, upstreamSchema} from '../../zero-cache/src/types/shards.ts';\n\nconst options = {\n cvr: {db: v.string()},\n schema: {\n type: v.string().optional(() => './schema.ts'),\n desc: ['Path to the schema file.'],\n },\n app: appOptions,\n shard: shardOptions,\n hash: {\n type: v.string().optional(),\n desc: ['Hash of the query to fetch the AST for.'],\n },\n};\n\nconst config = parseOptions(options, {envNamePrefix: ZERO_ENV_VAR_PREFIX});\n\nconst lc = new LogContext('debug', {}, consoleLogSink);\nconst {permissions} = await loadSchemaAndPermissions(config.schema);\n\nconst cvrDB = pgClient(lc, config.cvr.db, 'analyze-query-transform-cvr');\n\nconst rows =\n await cvrDB`select \"clientAST\", \"internal\" from ${cvrDB(upstreamSchema(getShardID(config)) + '/cvr')}.\"queries\" where \"queryHash\" = ${must(\n config.hash,\n )} limit 1;`;\n\nconst queryAst = transformAndHashQuery(\n lc,\n '',\n rows[0].clientAST,\n permissions,\n {\n type: 'jwt',\n raw: '',\n decoded: {},\n },\n rows[0].internal,\n).transformedAst;\n\n// oxlint-disable no-console\nconsole.log('\\n=== AST ===\\n');\nconsole.log(JSON.stringify(queryAst, null, 2));\nconsole.log('\\n=== ZQL ===\\n');\nconsole.log(await formatOutput(queryAst.table + astToZQL(queryAst)));\n// oxlint-enable no-console\n\nawait cvrDB.end();\n"],"mappings":";;;;;;;;;;;;;AAgCA,IAAM,SAAS,aAAa;CAb1B,KAAK,EAAC,IAAI,eAAE,OAAO,EAAC;CACpB,QAAQ;EACN,MAAM,eAAE,OAAO,EAAE,eAAe,aAAa;EAC7C,MAAM,CAAC,0BAA0B;CACnC;CACA,KAAK;CACL,OAAO;CACP,MAAM;EACJ,MAAM,eAAE,OAAO,EAAE,SAAS;EAC1B,MAAM,CAAC,yCAAyC;CAClD;AAG0B,GAAS,EAAC,eAAe,oBAAmB,CAAC;AAEzE,IAAM,KAAK,IAAI,WAAW,SAAS,CAAC,GAAG,cAAc;AACrD,IAAM,EAAC,gBAAe,MAAM,yBAAyB,OAAO,MAAM;AAElE,IAAM,QAAQ,SAAS,IAAI,OAAO,IAAI,IAAI,6BAA6B;AAEvE,IAAM,OACJ,MAAM,KAAK,uCAAuC,MAAM,eAAe,WAAW,MAAM,CAAC,IAAI,MAAM,EAAE,iCAAiC,KACpI,OAAO,IACT,EAAE;AAEJ,IAAM,WAAW,sBACf,IACA,IACA,KAAK,GAAG,WACR,aACA;CACE,MAAM;CACN,KAAK;CACL,SAAS,CAAC;AACZ,GACA,KAAK,GAAG,QACV,EAAE;AAGF,QAAQ,IAAI,iBAAiB;AAC7B,QAAQ,IAAI,KAAK,UAAU,UAAU,MAAM,CAAC,CAAC;AAC7C,QAAQ,IAAI,iBAAiB;AAC7B,QAAQ,IAAI,MAAM,aAAa,SAAS,QAAQ,SAAS,QAAQ,CAAC,CAAC;AAGnE,MAAM,MAAM,IAAI"}
1
+ {"version":3,"file":"bin-transform.js","names":["v"],"sources":["../../../../analyze-query/src/bin-transform.ts"],"sourcesContent":["import '../../shared/src/dotenv.ts';\n\nimport {consoleLogSink, LogContext} from '@rocicorp/logger';\nimport {astToZQL} from '../../ast-to-zql/src/ast-to-zql.ts';\nimport {formatOutput} from '../../ast-to-zql/src/format.ts';\nimport {must} from '../../shared/src/must.ts';\nimport {parseOptions} from '../../shared/src/options.ts';\nimport * as v from '../../shared/src/valita.ts';\nimport {transformAndHashQuery} from '../../zero-cache/src/auth/read-authorizer.ts';\nimport {\n appOptions,\n shardOptions,\n ZERO_ENV_VAR_PREFIX,\n} from '../../zero-cache/src/config/zero-config.ts';\nimport {loadSchemaAndPermissions} from '../../zero-cache/src/scripts/permissions.ts';\nimport {pgClient} from '../../zero-cache/src/types/pg.ts';\nimport {getShardID, upstreamSchema} from '../../zero-cache/src/types/shards.ts';\n\nconst options = {\n cvr: {db: v.string()},\n schema: {\n type: v.string().optional(() => './schema.ts'),\n desc: ['Path to the schema file.'],\n },\n app: appOptions,\n shard: shardOptions,\n hash: {\n type: v.string().optional(),\n desc: ['Hash of the query to fetch the AST for.'],\n },\n};\n\nconst config = parseOptions(options, {envNamePrefix: ZERO_ENV_VAR_PREFIX});\n\nconst lc = new LogContext('debug', {}, consoleLogSink);\nconst {permissions} = await loadSchemaAndPermissions(config.schema);\n\nconst cvrDB = pgClient(lc, config.cvr.db, 'analyze-query-transform-cvr');\n\nconst rows =\n await cvrDB`select \"clientAST\", \"internal\" from ${cvrDB(upstreamSchema(getShardID(config)) + '/cvr')}.\"queries\" where \"queryHash\" = ${must(\n config.hash,\n )} limit 1;`;\n\nconst queryAst = transformAndHashQuery(\n lc,\n '',\n rows[0].clientAST,\n permissions,\n {\n type: 'jwt',\n raw: '',\n decoded: {},\n },\n rows[0].internal,\n).transformedAst;\n\n// oxlint-disable no-console\nconsole.log('\\n=== AST ===\\n');\nconsole.log(JSON.stringify(queryAst, null, 2));\nconsole.log('\\n=== ZQL ===\\n');\nconsole.log(await formatOutput(queryAst.table + astToZQL(queryAst)));\n// oxlint-enable no-console\n\nawait cvrDB.end();\n"],"mappings":";;;;;;;;;;;;;AAkBA,IAAM,UAAU;CACd,KAAK,EAAC,IAAIA,eAAE,OAAO,EAAC;CACpB,QAAQ;EACN,MAAMA,eAAE,OAAO,CAAC,CAAC,eAAe,aAAa;EAC7C,MAAM,CAAC,0BAA0B;CACnC;CACA,KAAK;CACL,OAAO;CACP,MAAM;EACJ,MAAMA,eAAE,OAAO,CAAC,CAAC,SAAS;EAC1B,MAAM,CAAC,yCAAyC;CAClD;AACF;AAEA,IAAM,SAAS,aAAa,SAAS,EAAC,eAAe,oBAAmB,CAAC;AAEzE,IAAM,KAAK,IAAI,WAAW,SAAS,CAAC,GAAG,cAAc;AACrD,IAAM,EAAC,gBAAe,MAAM,yBAAyB,OAAO,MAAM;AAElE,IAAM,QAAQ,SAAS,IAAI,OAAO,IAAI,IAAI,6BAA6B;AAEvE,IAAM,OACJ,MAAM,KAAK,uCAAuC,MAAM,eAAe,WAAW,MAAM,CAAC,IAAI,MAAM,EAAE,iCAAiC,KACpI,OAAO,IACT,EAAE;AAEJ,IAAM,WAAW,sBACf,IACA,IACA,KAAK,EAAE,CAAC,WACR,aACA;CACE,MAAM;CACN,KAAK;CACL,SAAS,CAAC;AACZ,GACA,KAAK,EAAE,CAAC,QACV,CAAC,CAAC;AAGF,QAAQ,IAAI,iBAAiB;AAC7B,QAAQ,IAAI,KAAK,UAAU,UAAU,MAAM,CAAC,CAAC;AAC7C,QAAQ,IAAI,iBAAiB;AAC7B,QAAQ,IAAI,MAAM,aAAa,SAAS,QAAQ,SAAS,QAAQ,CAAC,CAAC;AAGnE,MAAM,MAAM,IAAI"}
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Evaluates a ZQL query written in chain form, e.g.
3
+ * `issue.where('open', true).related('comments', q => q.limit(10))`.
4
+ *
5
+ * The text is parsed with oxc and the resulting JavaScript AST is evaluated
6
+ * directly. It is never run as JavaScript. Only these constructs are
7
+ * accepted:
8
+ *
9
+ * - identifiers: table names (looked up on `root`), arrow function
10
+ * parameters, and `undefined`
11
+ * - calls to the query and expression builder methods in
12
+ * {@link ALLOWED_METHODS}, either as `x.method(...)` or through a
13
+ * destructured parameter such as `({cmp, or}) => or(cmp(...))`
14
+ * - string, number, boolean and null literals, negative numbers, and
15
+ * template literals without substitutions
16
+ * - array and object literals
17
+ * - arrow functions with an expression body whose parameters are
18
+ * identifiers or `{a, b}` patterns of allowed method names
19
+ *
20
+ * Anything else, including access to any other property, is rejected.
21
+ */
22
+ export declare function evaluateZQLChain(text: string, root: object): unknown;
23
+ //# sourceMappingURL=zql-chain.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"zql-chain.d.ts","sourceRoot":"","sources":["../../../../analyze-query/src/zql-chain.ts"],"names":[],"mappings":"AAWA;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAiBpE"}
@@ -0,0 +1,162 @@
1
+ import { parseSync } from "oxc-parser";
2
+ //#region ../analyze-query/src/zql-chain.ts
3
+ /**
4
+ * Evaluates a ZQL query written in chain form, e.g.
5
+ * `issue.where('open', true).related('comments', q => q.limit(10))`.
6
+ *
7
+ * The text is parsed with oxc and the resulting JavaScript AST is evaluated
8
+ * directly. It is never run as JavaScript. Only these constructs are
9
+ * accepted:
10
+ *
11
+ * - identifiers: table names (looked up on `root`), arrow function
12
+ * parameters, and `undefined`
13
+ * - calls to the query and expression builder methods in
14
+ * {@link ALLOWED_METHODS}, either as `x.method(...)` or through a
15
+ * destructured parameter such as `({cmp, or}) => or(cmp(...))`
16
+ * - string, number, boolean and null literals, negative numbers, and
17
+ * template literals without substitutions
18
+ * - array and object literals
19
+ * - arrow functions with an expression body whose parameters are
20
+ * identifiers or `{a, b}` patterns of allowed method names
21
+ *
22
+ * Anything else, including access to any other property, is rejected.
23
+ */
24
+ function evaluateZQLChain(text, root) {
25
+ const { program, errors } = parseSync("query.js", text, {
26
+ lang: "js",
27
+ sourceType: "script"
28
+ });
29
+ if (errors.length > 0) {
30
+ const [error] = errors;
31
+ const pos = error.labels[0]?.start;
32
+ throw new SyntaxError(pos === void 0 ? error.message : `${error.message} at position ${pos}`);
33
+ }
34
+ const [statement, ...rest] = program.body;
35
+ if (statement?.type !== "ExpressionStatement" || rest.length > 0) throw new SyntaxError("Expected a single query expression");
36
+ return new Evaluator(text, root).evaluate(statement.expression, /* @__PURE__ */ new Map());
37
+ }
38
+ var QUERY_METHODS = {
39
+ where: true,
40
+ whereExists: true,
41
+ related: true,
42
+ orderBy: true,
43
+ limit: true,
44
+ one: true,
45
+ start: true,
46
+ run: false,
47
+ preload: false,
48
+ materialize: false
49
+ };
50
+ var EXPRESSION_BUILDER_METHODS = {
51
+ cmp: true,
52
+ cmpLit: true,
53
+ and: true,
54
+ or: true,
55
+ not: true,
56
+ exists: true,
57
+ eb: true
58
+ };
59
+ var ALLOWED_METHODS = new Set(Object.entries({
60
+ ...QUERY_METHODS,
61
+ ...EXPRESSION_BUILDER_METHODS
62
+ }).filter(([, allowed]) => allowed).map(([name]) => name));
63
+ var Evaluator = class {
64
+ #text;
65
+ #root;
66
+ constructor(text, root) {
67
+ this.#text = text;
68
+ this.#root = root;
69
+ }
70
+ #reject(node, what) {
71
+ const source = this.#text.slice(node.start, node.end);
72
+ throw new SyntaxError(`${what} is not allowed: \`${source}\` at position ${node.start}`);
73
+ }
74
+ evaluate(node, scope) {
75
+ switch (node.type) {
76
+ case "ParenthesizedExpression": return this.evaluate(node.expression, scope);
77
+ case "Literal":
78
+ if (node.regex || node.bigint) this.#reject(node, "Literal");
79
+ return node.value;
80
+ case "TemplateLiteral":
81
+ if (node.expressions.length > 0) this.#reject(node, "Template substitution");
82
+ return node.quasis[0].value.cooked;
83
+ case "UnaryExpression":
84
+ if (node.operator === "-" && node.argument.type === "Literal" && typeof node.argument.value === "number") return -node.argument.value;
85
+ return this.#reject(node, "Operator");
86
+ case "Identifier": return this.#lookup(node, node.name, scope);
87
+ case "ArrayExpression": return node.elements.map((e) => {
88
+ if (e === null || e.type === "SpreadElement") return this.#reject(node, "Array hole or spread");
89
+ return this.evaluate(e, scope);
90
+ });
91
+ case "ObjectExpression": return this.#evaluateObject(node, scope);
92
+ case "ArrowFunctionExpression": return this.#evaluateArrow(node, scope);
93
+ case "CallExpression": return this.#evaluateCall(node, scope);
94
+ default: return this.#reject(node, node.type);
95
+ }
96
+ }
97
+ #lookup(node, name, scope) {
98
+ if (scope.has(name)) return scope.get(name);
99
+ if (name === "undefined") return;
100
+ if (!Object.hasOwn(this.#root, name)) this.#reject(node, "Unknown identifier");
101
+ return this.#root[name];
102
+ }
103
+ #evaluateObject(node, scope) {
104
+ const obj = {};
105
+ for (const prop of node.properties) {
106
+ if (prop.type !== "Property" || prop.kind !== "init" || prop.method || prop.computed) return this.#reject(prop, "Object member");
107
+ let key;
108
+ if (prop.key.type === "Identifier") key = prop.key.name;
109
+ else if (prop.key.type === "Literal" && typeof prop.key.value === "string") key = prop.key.value;
110
+ else return this.#reject(prop.key, "Object key");
111
+ if (key === "__proto__") return this.#reject(prop.key, "Object key");
112
+ obj[key] = this.evaluate(prop.value, scope);
113
+ }
114
+ return obj;
115
+ }
116
+ #evaluateArrow(node, scope) {
117
+ if (!node.expression || node.async) return this.#reject(node, "Arrow function with a block body");
118
+ const body = node.body;
119
+ const params = node.params.map((param) => {
120
+ if (param.type === "Identifier") return { name: param.name };
121
+ if (param.type !== "ObjectPattern") return this.#reject(param, "Parameter");
122
+ return { names: param.properties.map((p) => {
123
+ if (p.type !== "Property" || p.computed || p.value.type !== "Identifier" || !p.shorthand || p.key.type !== "Identifier" || !ALLOWED_METHODS.has(p.key.name)) return this.#reject(p, "Destructured parameter");
124
+ return p.key.name;
125
+ }) };
126
+ });
127
+ return (...args) => {
128
+ const inner = new Map(scope);
129
+ params.forEach((param, i) => {
130
+ if ("name" in param) inner.set(param.name, args[i]);
131
+ else {
132
+ const arg = args[i];
133
+ for (const name of param.names) inner.set(name, arg[name]);
134
+ }
135
+ });
136
+ return this.evaluate(body, inner);
137
+ };
138
+ }
139
+ #evaluateCall(node, scope) {
140
+ if (node.optional) return this.#reject(node, "Optional call");
141
+ const args = node.arguments.map((a) => {
142
+ if (a.type === "SpreadElement") return this.#reject(a, "Spread");
143
+ return this.evaluate(a, scope);
144
+ });
145
+ const { callee } = node;
146
+ let thisValue;
147
+ let fn;
148
+ if (callee.type === "MemberExpression") {
149
+ if (callee.computed || callee.optional || callee.property.type !== "Identifier" || !ALLOWED_METHODS.has(callee.property.name)) return this.#reject(callee, "Method");
150
+ thisValue = this.evaluate(callee.object, scope);
151
+ if (thisValue === null || typeof thisValue !== "object") return this.#reject(callee.object, "Receiver");
152
+ fn = thisValue[callee.property.name];
153
+ } else if (callee.type === "Identifier" && scope.has(callee.name)) fn = scope.get(callee.name);
154
+ else return this.#reject(callee, "Callee");
155
+ if (typeof fn !== "function") return this.#reject(callee, "Non-function call");
156
+ return Reflect.apply(fn, thisValue, args);
157
+ }
158
+ };
159
+ //#endregion
160
+ export { evaluateZQLChain };
161
+
162
+ //# sourceMappingURL=zql-chain.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"zql-chain.js","names":[],"sources":["../../../../analyze-query/src/zql-chain.ts"],"sourcesContent":["import {\n parseSync,\n type ArrowFunctionExpression,\n type Expression,\n type Node,\n type ObjectExpression,\n} from 'oxc-parser';\nimport type {Schema} from '../../zero-types/src/schema.ts';\nimport type {ExpressionBuilder} from '../../zql/src/query/expression.ts';\nimport type {Query} from '../../zql/src/query/query.ts';\n\n/**\n * Evaluates a ZQL query written in chain form, e.g.\n * `issue.where('open', true).related('comments', q => q.limit(10))`.\n *\n * The text is parsed with oxc and the resulting JavaScript AST is evaluated\n * directly. It is never run as JavaScript. Only these constructs are\n * accepted:\n *\n * - identifiers: table names (looked up on `root`), arrow function\n * parameters, and `undefined`\n * - calls to the query and expression builder methods in\n * {@link ALLOWED_METHODS}, either as `x.method(...)` or through a\n * destructured parameter such as `({cmp, or}) => or(cmp(...))`\n * - string, number, boolean and null literals, negative numbers, and\n * template literals without substitutions\n * - array and object literals\n * - arrow functions with an expression body whose parameters are\n * identifiers or `{a, b}` patterns of allowed method names\n *\n * Anything else, including access to any other property, is rejected.\n */\nexport function evaluateZQLChain(text: string, root: object): unknown {\n const {program, errors} = parseSync('query.js', text, {\n lang: 'js',\n sourceType: 'script',\n });\n if (errors.length > 0) {\n const [error] = errors;\n const pos = error.labels[0]?.start;\n throw new SyntaxError(\n pos === undefined ? error.message : `${error.message} at position ${pos}`,\n );\n }\n const [statement, ...rest] = program.body;\n if (statement?.type !== 'ExpressionStatement' || rest.length > 0) {\n throw new SyntaxError('Expected a single query expression');\n }\n return new Evaluator(text, root).evaluate(statement.expression, new Map());\n}\n\n// Every string-keyed member of Query and ExpressionBuilder is listed here, so\n// adding or removing one fails type checking until it is classified as\n// allowed or not. Symbol keys can't be written in the query text.\ntype MethodName<T> = Extract<keyof T, string>;\n\nconst QUERY_METHODS = {\n where: true,\n whereExists: true,\n related: true,\n orderBy: true,\n limit: true,\n one: true,\n start: true,\n run: false,\n preload: false,\n materialize: false,\n} satisfies Record<MethodName<Query<string, Schema>>, boolean>;\n\nconst EXPRESSION_BUILDER_METHODS = {\n cmp: true,\n cmpLit: true,\n and: true,\n or: true,\n not: true,\n exists: true,\n eb: true,\n} satisfies Record<MethodName<ExpressionBuilder<string, Schema>>, boolean>;\n\nconst ALLOWED_METHODS: ReadonlySet<string> = new Set(\n Object.entries({...QUERY_METHODS, ...EXPRESSION_BUILDER_METHODS})\n .filter(([, allowed]) => allowed)\n .map(([name]) => name),\n);\n\ntype Scope = ReadonlyMap<string, unknown>;\n\nclass Evaluator {\n readonly #text: string;\n readonly #root: object;\n\n constructor(text: string, root: object) {\n this.#text = text;\n this.#root = root;\n }\n\n #reject(node: Node, what: string): never {\n const source = this.#text.slice(node.start, node.end);\n throw new SyntaxError(\n `${what} is not allowed: \\`${source}\\` at position ${node.start}`,\n );\n }\n\n evaluate(node: Expression, scope: Scope): unknown {\n switch (node.type) {\n case 'ParenthesizedExpression':\n return this.evaluate(node.expression, scope);\n case 'Literal':\n if (\n (node as {regex?: unknown}).regex ||\n (node as {bigint?: unknown}).bigint\n ) {\n this.#reject(node, 'Literal');\n }\n return node.value;\n case 'TemplateLiteral':\n if (node.expressions.length > 0) {\n this.#reject(node, 'Template substitution');\n }\n return node.quasis[0].value.cooked;\n case 'UnaryExpression':\n if (\n node.operator === '-' &&\n node.argument.type === 'Literal' &&\n typeof node.argument.value === 'number'\n ) {\n return -node.argument.value;\n }\n return this.#reject(node, 'Operator');\n case 'Identifier':\n return this.#lookup(node, node.name, scope);\n case 'ArrayExpression':\n return node.elements.map(e => {\n if (e === null || e.type === 'SpreadElement') {\n return this.#reject(node, 'Array hole or spread');\n }\n return this.evaluate(e, scope);\n });\n case 'ObjectExpression':\n return this.#evaluateObject(node, scope);\n case 'ArrowFunctionExpression':\n return this.#evaluateArrow(node, scope);\n case 'CallExpression':\n return this.#evaluateCall(node, scope);\n default:\n return this.#reject(node, node.type);\n }\n }\n\n #lookup(node: Node, name: string, scope: Scope): unknown {\n if (scope.has(name)) {\n return scope.get(name);\n }\n if (name === 'undefined') {\n return undefined;\n }\n if (!Object.hasOwn(this.#root, name)) {\n this.#reject(node, 'Unknown identifier');\n }\n return (this.#root as Record<string, unknown>)[name];\n }\n\n #evaluateObject(node: ObjectExpression, scope: Scope): unknown {\n const obj: Record<string, unknown> = {};\n for (const prop of node.properties) {\n if (\n prop.type !== 'Property' ||\n prop.kind !== 'init' ||\n prop.method ||\n prop.computed\n ) {\n return this.#reject(prop, 'Object member');\n }\n let key: string;\n if (prop.key.type === 'Identifier') {\n key = prop.key.name;\n } else if (\n prop.key.type === 'Literal' &&\n typeof prop.key.value === 'string'\n ) {\n key = prop.key.value;\n } else {\n return this.#reject(prop.key, 'Object key');\n }\n if (key === '__proto__') {\n return this.#reject(prop.key, 'Object key');\n }\n obj[key] = this.evaluate(prop.value as Expression, scope);\n }\n return obj;\n }\n\n #evaluateArrow(node: ArrowFunctionExpression, scope: Scope): unknown {\n if (!node.expression || node.async) {\n return this.#reject(node, 'Arrow function with a block body');\n }\n const body = node.body as Expression;\n const params = node.params.map(param => {\n if (param.type === 'Identifier') {\n return {name: param.name};\n }\n if (param.type !== 'ObjectPattern') {\n return this.#reject(param, 'Parameter');\n }\n return {\n names: param.properties.map(p => {\n if (\n p.type !== 'Property' ||\n p.computed ||\n p.value.type !== 'Identifier' ||\n !p.shorthand ||\n p.key.type !== 'Identifier' ||\n !ALLOWED_METHODS.has(p.key.name)\n ) {\n return this.#reject(p, 'Destructured parameter');\n }\n return p.key.name;\n }),\n };\n });\n return (...args: unknown[]) => {\n const inner = new Map(scope);\n params.forEach((param, i) => {\n if ('name' in param) {\n inner.set(param.name, args[i]);\n } else {\n const arg = args[i] as Record<string, unknown>;\n for (const name of param.names) {\n inner.set(name, arg[name]);\n }\n }\n });\n return this.evaluate(body, inner);\n };\n }\n\n #evaluateCall(\n node: Extract<Expression, {type: 'CallExpression'}>,\n scope: Scope,\n ): unknown {\n if (node.optional) {\n return this.#reject(node, 'Optional call');\n }\n const args = node.arguments.map(a => {\n if (a.type === 'SpreadElement') {\n return this.#reject(a, 'Spread');\n }\n return this.evaluate(a, scope);\n });\n const {callee} = node;\n let thisValue: unknown;\n let fn: unknown;\n if (callee.type === 'MemberExpression') {\n if (\n callee.computed ||\n callee.optional ||\n callee.property.type !== 'Identifier' ||\n !ALLOWED_METHODS.has(callee.property.name)\n ) {\n return this.#reject(callee, 'Method');\n }\n thisValue = this.evaluate(callee.object, scope);\n if (thisValue === null || typeof thisValue !== 'object') {\n return this.#reject(callee.object, 'Receiver');\n }\n fn = (thisValue as Record<string, unknown>)[callee.property.name];\n } else if (callee.type === 'Identifier' && scope.has(callee.name)) {\n fn = scope.get(callee.name);\n } else {\n return this.#reject(callee, 'Callee');\n }\n if (typeof fn !== 'function') {\n return this.#reject(callee, 'Non-function call');\n }\n return Reflect.apply(fn, thisValue, args);\n }\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"ast-to-zql.js","names":[],"sources":["../../../../ast-to-zql/src/ast-to-zql.ts"],"sourcesContent":["import {unreachable} from '../../shared/src/asserts.ts';\nimport {toSorted} from '../../shared/src/iterables.ts';\nimport {must} from '../../shared/src/must.ts';\nimport type {\n AST,\n Condition,\n Conjunction,\n CorrelatedSubquery,\n CorrelatedSubqueryCondition,\n Disjunction,\n LiteralReference,\n Ordering,\n Parameter,\n SimpleCondition,\n ValuePosition,\n} from '../../zero-protocol/src/ast.ts';\nimport {SUBQ_PREFIX} from '../../zero-protocol/src/ast.ts';\n\n/**\n * Converts an AST to the equivalent query builder code.\n * This is useful for debugging and understanding queries.\n *\n * @example\n * ```\n * const ast = query.issue.where('id', '=', 123)[astSymbol];\n * console.log(astToZQL(ast)); // outputs: .where('id', '=', 123)\n * ```\n */\nexport function astToZQL(ast: AST, options: AstToZQLOptions = {}): string {\n let code = '';\n\n // Handle where conditions\n if (ast.where) {\n code += transformCondition(ast.where, '.where', new Set(), options);\n }\n\n // Handle related subqueries\n if (ast.related && ast.related.length > 0) {\n for (const related of ast.related) {\n if (related.hidden) {\n const nestedRelated = related.subquery.related?.[0];\n if (nestedRelated) {\n code += transformRelated(nestedRelated, options);\n }\n } else {\n code += transformRelated(related, options);\n }\n }\n }\n\n // Handle orderBy\n if (ast.orderBy && ast.orderBy.length > 0) {\n code += transformOrder(ast.orderBy);\n }\n\n // Handle limit\n if (ast.limit !== undefined) {\n code += `.limit(${ast.limit})`;\n }\n\n // Handle start\n if (ast.start) {\n const {row, exclusive} = ast.start;\n code += `.start(${options.redactLiterals ? '?' : JSON.stringify(row)}${\n exclusive ? '' : ', { inclusive: true }'\n })`;\n }\n\n return code;\n}\n\nexport type AstToZQLOptions = {\n /**\n * Renders every literal value, and the `start` row, as `?` so that the\n * output can be logged without leaking row data or query arguments.\n */\n readonly redactLiterals?: boolean | undefined;\n};\n\ntype Args = Set<string>;\n\ntype Prefix = '.where' | 'cmp';\n\nfunction transformCondition(\n condition: Condition,\n prefix: Prefix,\n args: Args,\n options: AstToZQLOptions,\n): string {\n switch (condition.type) {\n case 'simple':\n return transformSimpleCondition(condition, prefix, options);\n case 'and':\n case 'or':\n return transformLogicalCondition(condition, prefix, args, options);\n case 'correlatedSubquery':\n return transformExistsCondition(condition, prefix, args, options);\n default:\n unreachable(condition);\n }\n}\n\nfunction transformSimpleCondition(\n condition: SimpleCondition,\n prefix: Prefix,\n options: AstToZQLOptions,\n): string {\n const {left, op, right} = condition;\n\n const leftCode = transformValuePosition(left, options);\n const rightCode = transformValuePosition(right, options);\n\n // Handle the shorthand form for equals\n if (op === '=') {\n return `${prefix}(${leftCode}, ${rightCode})`;\n }\n\n return `${prefix}(${leftCode}, '${op}', ${rightCode})`;\n}\n\nfunction transformLogicalCondition(\n condition: Conjunction | Disjunction,\n prefix: Prefix,\n args: Args,\n options: AstToZQLOptions,\n): string {\n const {type, conditions} = condition;\n\n // For single condition, no need for logical operator\n if (conditions.length === 1) {\n return transformCondition(conditions[0], prefix, args, options);\n }\n\n // Generate multiple where calls for top-level AND conditions\n if (type === 'and') {\n const parts = conditions.map(c =>\n transformCondition(c, prefix, args, options),\n );\n // Simply concatenate the where conditions\n if (prefix === '.where') {\n return parts.join('');\n }\n args.add('and');\n return 'and(' + parts.join(', ') + ')';\n }\n\n args = new Set<string>();\n\n // Handle nested conditions with a callback for OR conditions and nested ANDs/ORs\n const conditionsCode = conditions\n .map(c => transformCondition(c, 'cmp', args, options))\n .join(', ');\n\n args.add('cmp');\n args.add(type);\n const argsCode = toSorted(args).join(', ');\n\n return `.where(({${argsCode}}) => ${type}(${conditionsCode}))`;\n}\n\nfunction transformExistsCondition(\n condition: CorrelatedSubqueryCondition,\n prefix: '.where' | 'cmp',\n args: Set<string>,\n options: AstToZQLOptions,\n): string {\n const {related, op} = condition;\n const relationship = extractRelationshipName(related);\n\n const nextSubquery = getNextExistsSubquery(related);\n\n // Check if subquery has additional properties\n const hasSubQueryProps =\n nextSubquery.where ||\n (nextSubquery.related && nextSubquery.related.length > 0) ||\n nextSubquery.orderBy ||\n nextSubquery.limit;\n\n // Build options string for flip and scalar\n const optionParts: string[] = [];\n if (condition.flip !== undefined) {\n optionParts.push(`flip: ${condition.flip}`);\n }\n if (condition.scalar !== undefined) {\n optionParts.push(`scalar: ${condition.scalar}`);\n }\n const optionsStr =\n optionParts.length > 0 ? `, {${optionParts.join(', ')}}` : '';\n\n if (op === 'EXISTS') {\n if (!hasSubQueryProps) {\n if (prefix === '.where') {\n return `.whereExists('${relationship}'${optionsStr})`;\n }\n args.add('exists');\n return `exists('${relationship}'${optionsStr})`;\n }\n\n if (prefix === '.where') {\n return `.whereExists('${relationship}', q => q${astToZQL(nextSubquery, options)}${optionsStr})`;\n }\n prefix satisfies 'cmp';\n args.add('exists');\n return `exists('${relationship}', q => q${astToZQL(nextSubquery, options)}${optionsStr})`;\n }\n\n op satisfies 'NOT EXISTS';\n\n if (hasSubQueryProps) {\n if (prefix === '.where') {\n return `.where(({exists, not}) => not(exists('${relationship}', q => q${astToZQL(\n nextSubquery,\n options,\n )}${optionsStr})))`;\n }\n prefix satisfies 'cmp';\n args.add('not');\n args.add('exists');\n return `not(exists('${relationship}', q => q${astToZQL(nextSubquery, options)}${optionsStr}))`;\n }\n\n if (prefix === '.where') {\n return `.where(({exists, not}) => not(exists('${relationship}'${optionsStr})))`;\n }\n args.add('not');\n args.add('exists');\n\n return `not(exists('${relationship}'${optionsStr})))`;\n}\n\n// If the `exists` is applied against a junction edge, both hops will have the same alias and both hops will be exists conditions.\nfunction getNextExistsSubquery(related: CorrelatedSubquery): AST {\n if (\n related.subquery.where?.type === 'correlatedSubquery' &&\n related.subquery.where.related.subquery.alias?.includes(\n SUBQ_PREFIX + 'zhidden_',\n )\n ) {\n return getNextExistsSubquery(related.subquery.where.related);\n }\n\n return related.subquery;\n}\n\nfunction extractRelationshipName(related: CorrelatedSubquery): string {\n const alias = must(related.subquery.alias);\n return alias.startsWith(SUBQ_PREFIX)\n ? alias.substring(SUBQ_PREFIX.length)\n : alias;\n}\n\nfunction transformRelated(\n related: CorrelatedSubquery,\n options: AstToZQLOptions,\n): string {\n const {alias} = related.subquery;\n if (!alias) return '';\n\n const relationship = alias;\n let code = `.related('${relationship}'`;\n\n // If the subquery has additional filters or configurations\n if (\n related.subquery.where ||\n (related.subquery.related && related.subquery.related.length > 0) ||\n related.subquery.orderBy ||\n related.subquery.limit\n ) {\n code += ', q => q' + astToZQL(related.subquery, options);\n }\n\n code += ')';\n return code;\n}\n\nfunction transformOrder(orderBy: Ordering): string {\n let code = '';\n for (const [field, direction] of orderBy) {\n code += `.orderBy('${field}', '${direction}')`;\n }\n return code;\n}\n\nfunction transformValuePosition(\n value: ValuePosition,\n options: AstToZQLOptions,\n): string {\n switch (value.type) {\n case 'literal':\n return options.redactLiterals ? '?' : transformLiteral(value);\n case 'column':\n return `'${value.name}'`;\n case 'static':\n return transformParameter(value);\n default:\n unreachable(value);\n }\n}\n\nfunction transformLiteral(literal: LiteralReference): string {\n if (literal.value === null) {\n return 'null';\n }\n if (Array.isArray(literal.value)) {\n return JSON.stringify(literal.value);\n }\n if (typeof literal.value === 'string') {\n return `'${literal.value.replace(/'/g, \"\\\\'\")}'`;\n }\n return String(literal.value);\n}\n\nfunction transformParameter(param: Parameter): string {\n const fieldStr = Array.isArray(param.field)\n ? `[${param.field.map(f => `'${f}'`).join(', ')}]`\n : `'${param.field}'`;\n\n return `authParam(${fieldStr})`;\n}\n"],"mappings":";;;;;;;;;;;;;;;AA4BA,SAAgB,SAAS,KAAU,UAA2B,CAAC,GAAW;CACxE,IAAI,OAAO;CAGX,IAAI,IAAI,OACN,QAAQ,mBAAmB,IAAI,OAAO,0BAAU,IAAI,IAAI,GAAG,OAAO;CAIpE,IAAI,IAAI,WAAW,IAAI,QAAQ,SAAS,GACtC,KAAK,MAAM,WAAW,IAAI,SACxB,IAAI,QAAQ,QAAQ;EAClB,MAAM,gBAAgB,QAAQ,SAAS,UAAU;EACjD,IAAI,eACF,QAAQ,iBAAiB,eAAe,OAAO;CAEnD,OACE,QAAQ,iBAAiB,SAAS,OAAO;CAM/C,IAAI,IAAI,WAAW,IAAI,QAAQ,SAAS,GACtC,QAAQ,eAAe,IAAI,OAAO;CAIpC,IAAI,IAAI,UAAU,KAAA,GAChB,QAAQ,UAAU,IAAI,MAAM;CAI9B,IAAI,IAAI,OAAO;EACb,MAAM,EAAC,KAAK,cAAa,IAAI;EAC7B,QAAQ,UAAU,QAAQ,iBAAiB,MAAM,KAAK,UAAU,GAAG,IACjE,YAAY,KAAK,wBAClB;CACH;CAEA,OAAO;AACT;AAcA,SAAS,mBACP,WACA,QACA,MACA,SACQ;CACR,QAAQ,UAAU,MAAlB;EACE,KAAK,UACH,OAAO,yBAAyB,WAAW,QAAQ,OAAO;EAC5D,KAAK;EACL,KAAK,MACH,OAAO,0BAA0B,WAAW,QAAQ,MAAM,OAAO;EACnE,KAAK,sBACH,OAAO,yBAAyB,WAAW,QAAQ,MAAM,OAAO;EAClE,SACE,YAAY,SAAS;CACzB;AACF;AAEA,SAAS,yBACP,WACA,QACA,SACQ;CACR,MAAM,EAAC,MAAM,IAAI,UAAS;CAE1B,MAAM,WAAW,uBAAuB,MAAM,OAAO;CACrD,MAAM,YAAY,uBAAuB,OAAO,OAAO;CAGvD,IAAI,OAAO,KACT,OAAO,GAAG,OAAO,GAAG,SAAS,IAAI,UAAU;CAG7C,OAAO,GAAG,OAAO,GAAG,SAAS,KAAK,GAAG,KAAK,UAAU;AACtD;AAEA,SAAS,0BACP,WACA,QACA,MACA,SACQ;CACR,MAAM,EAAC,MAAM,eAAc;CAG3B,IAAI,WAAW,WAAW,GACxB,OAAO,mBAAmB,WAAW,IAAI,QAAQ,MAAM,OAAO;CAIhE,IAAI,SAAS,OAAO;EAClB,MAAM,QAAQ,WAAW,KAAI,MAC3B,mBAAmB,GAAG,QAAQ,MAAM,OAAO,CAC7C;EAEA,IAAI,WAAW,UACb,OAAO,MAAM,KAAK,EAAE;EAEtB,KAAK,IAAI,KAAK;EACd,OAAO,SAAS,MAAM,KAAK,IAAI,IAAI;CACrC;CAEA,uBAAO,IAAI,IAAY;CAGvB,MAAM,iBAAiB,WACpB,KAAI,MAAK,mBAAmB,GAAG,OAAO,MAAM,OAAO,CAAC,EACpD,KAAK,IAAI;CAEZ,KAAK,IAAI,KAAK;CACd,KAAK,IAAI,IAAI;CAGb,OAAO,YAFU,SAAS,IAAI,EAAE,KAAK,IAElB,EAAS,QAAQ,KAAK,GAAG,eAAe;AAC7D;AAEA,SAAS,yBACP,WACA,QACA,MACA,SACQ;CACR,MAAM,EAAC,SAAS,OAAM;CACtB,MAAM,eAAe,wBAAwB,OAAO;CAEpD,MAAM,eAAe,sBAAsB,OAAO;CAGlD,MAAM,mBACJ,aAAa,SACZ,aAAa,WAAW,aAAa,QAAQ,SAAS,KACvD,aAAa,WACb,aAAa;CAGf,MAAM,cAAwB,CAAC;CAC/B,IAAI,UAAU,SAAS,KAAA,GACrB,YAAY,KAAK,SAAS,UAAU,MAAM;CAE5C,IAAI,UAAU,WAAW,KAAA,GACvB,YAAY,KAAK,WAAW,UAAU,QAAQ;CAEhD,MAAM,aACJ,YAAY,SAAS,IAAI,MAAM,YAAY,KAAK,IAAI,EAAE,KAAK;CAE7D,IAAI,OAAO,UAAU;EACnB,IAAI,CAAC,kBAAkB;GACrB,IAAI,WAAW,UACb,OAAO,iBAAiB,aAAa,GAAG,WAAW;GAErD,KAAK,IAAI,QAAQ;GACjB,OAAO,WAAW,aAAa,GAAG,WAAW;EAC/C;EAEA,IAAI,WAAW,UACb,OAAO,iBAAiB,aAAa,WAAW,SAAS,cAAc,OAAO,IAAI,WAAW;EAG/F,KAAK,IAAI,QAAQ;EACjB,OAAO,WAAW,aAAa,WAAW,SAAS,cAAc,OAAO,IAAI,WAAW;CACzF;CAIA,IAAI,kBAAkB;EACpB,IAAI,WAAW,UACb,OAAO,yCAAyC,aAAa,WAAW,SACtE,cACA,OACF,IAAI,WAAW;EAGjB,KAAK,IAAI,KAAK;EACd,KAAK,IAAI,QAAQ;EACjB,OAAO,eAAe,aAAa,WAAW,SAAS,cAAc,OAAO,IAAI,WAAW;CAC7F;CAEA,IAAI,WAAW,UACb,OAAO,yCAAyC,aAAa,GAAG,WAAW;CAE7E,KAAK,IAAI,KAAK;CACd,KAAK,IAAI,QAAQ;CAEjB,OAAO,eAAe,aAAa,GAAG,WAAW;AACnD;AAGA,SAAS,sBAAsB,SAAkC;CAC/D,IACE,QAAQ,SAAS,OAAO,SAAS,wBACjC,QAAQ,SAAS,MAAM,QAAQ,SAAS,OAAO,SAAA,gBAE/C,GAEA,OAAO,sBAAsB,QAAQ,SAAS,MAAM,OAAO;CAG7D,OAAO,QAAQ;AACjB;AAEA,SAAS,wBAAwB,SAAqC;CACpE,MAAM,QAAQ,KAAK,QAAQ,SAAS,KAAK;CACzC,OAAO,MAAM,WAAA,QAAsB,IAC/B,MAAM,UAAU,YAAY,MAAM,IAClC;AACN;AAEA,SAAS,iBACP,SACA,SACQ;CACR,MAAM,EAAC,UAAS,QAAQ;CACxB,IAAI,CAAC,OAAO,OAAO;CAGnB,IAAI,OAAO,aAAa,MAAa;CAGrC,IACE,QAAQ,SAAS,SAChB,QAAQ,SAAS,WAAW,QAAQ,SAAS,QAAQ,SAAS,KAC/D,QAAQ,SAAS,WACjB,QAAQ,SAAS,OAEjB,QAAQ,aAAa,SAAS,QAAQ,UAAU,OAAO;CAGzD,QAAQ;CACR,OAAO;AACT;AAEA,SAAS,eAAe,SAA2B;CACjD,IAAI,OAAO;CACX,KAAK,MAAM,CAAC,OAAO,cAAc,SAC/B,QAAQ,aAAa,MAAM,MAAM,UAAU;CAE7C,OAAO;AACT;AAEA,SAAS,uBACP,OACA,SACQ;CACR,QAAQ,MAAM,MAAd;EACE,KAAK,WACH,OAAO,QAAQ,iBAAiB,MAAM,iBAAiB,KAAK;EAC9D,KAAK,UACH,OAAO,IAAI,MAAM,KAAK;EACxB,KAAK,UACH,OAAO,mBAAmB,KAAK;EACjC,SACE,YAAY,KAAK;CACrB;AACF;AAEA,SAAS,iBAAiB,SAAmC;CAC3D,IAAI,QAAQ,UAAU,MACpB,OAAO;CAET,IAAI,MAAM,QAAQ,QAAQ,KAAK,GAC7B,OAAO,KAAK,UAAU,QAAQ,KAAK;CAErC,IAAI,OAAO,QAAQ,UAAU,UAC3B,OAAO,IAAI,QAAQ,MAAM,QAAQ,MAAM,KAAK,EAAE;CAEhD,OAAO,OAAO,QAAQ,KAAK;AAC7B;AAEA,SAAS,mBAAmB,OAA0B;CAKpD,OAAO,aAJU,MAAM,QAAQ,MAAM,KAAK,IACtC,IAAI,MAAM,MAAM,KAAI,MAAK,IAAI,EAAE,EAAE,EAAE,KAAK,IAAI,EAAE,KAC9C,IAAI,MAAM,MAAM,GAES;AAC/B"}
1
+ {"version":3,"file":"ast-to-zql.js","names":["relationship"],"sources":["../../../../ast-to-zql/src/ast-to-zql.ts"],"sourcesContent":["import {unreachable} from '../../shared/src/asserts.ts';\nimport {toSorted} from '../../shared/src/iterables.ts';\nimport {must} from '../../shared/src/must.ts';\nimport type {\n AST,\n Condition,\n Conjunction,\n CorrelatedSubquery,\n CorrelatedSubqueryCondition,\n Disjunction,\n LiteralReference,\n Ordering,\n Parameter,\n SimpleCondition,\n ValuePosition,\n} from '../../zero-protocol/src/ast.ts';\nimport {SUBQ_PREFIX} from '../../zero-protocol/src/ast.ts';\n\n/**\n * Converts an AST to the equivalent query builder code.\n * This is useful for debugging and understanding queries.\n *\n * @example\n * ```\n * const ast = query.issue.where('id', '=', 123)[astSymbol];\n * console.log(astToZQL(ast)); // outputs: .where('id', '=', 123)\n * ```\n */\nexport function astToZQL(ast: AST, options: AstToZQLOptions = {}): string {\n let code = '';\n\n // Handle where conditions\n if (ast.where) {\n code += transformCondition(ast.where, '.where', new Set(), options);\n }\n\n // Handle related subqueries\n if (ast.related && ast.related.length > 0) {\n for (const related of ast.related) {\n if (related.hidden) {\n const nestedRelated = related.subquery.related?.[0];\n if (nestedRelated) {\n code += transformRelated(nestedRelated, options);\n }\n } else {\n code += transformRelated(related, options);\n }\n }\n }\n\n // Handle orderBy\n if (ast.orderBy && ast.orderBy.length > 0) {\n code += transformOrder(ast.orderBy);\n }\n\n // Handle limit\n if (ast.limit !== undefined) {\n code += `.limit(${ast.limit})`;\n }\n\n // Handle start\n if (ast.start) {\n const {row, exclusive} = ast.start;\n code += `.start(${options.redactLiterals ? '?' : JSON.stringify(row)}${\n exclusive ? '' : ', { inclusive: true }'\n })`;\n }\n\n return code;\n}\n\nexport type AstToZQLOptions = {\n /**\n * Renders every literal value, and the `start` row, as `?` so that the\n * output can be logged without leaking row data or query arguments.\n */\n readonly redactLiterals?: boolean | undefined;\n};\n\ntype Args = Set<string>;\n\ntype Prefix = '.where' | 'cmp';\n\nfunction transformCondition(\n condition: Condition,\n prefix: Prefix,\n args: Args,\n options: AstToZQLOptions,\n): string {\n switch (condition.type) {\n case 'simple':\n return transformSimpleCondition(condition, prefix, options);\n case 'and':\n case 'or':\n return transformLogicalCondition(condition, prefix, args, options);\n case 'correlatedSubquery':\n return transformExistsCondition(condition, prefix, args, options);\n default:\n unreachable(condition);\n }\n}\n\nfunction transformSimpleCondition(\n condition: SimpleCondition,\n prefix: Prefix,\n options: AstToZQLOptions,\n): string {\n const {left, op, right} = condition;\n\n const leftCode = transformValuePosition(left, options);\n const rightCode = transformValuePosition(right, options);\n\n // Handle the shorthand form for equals\n if (op === '=') {\n return `${prefix}(${leftCode}, ${rightCode})`;\n }\n\n return `${prefix}(${leftCode}, '${op}', ${rightCode})`;\n}\n\nfunction transformLogicalCondition(\n condition: Conjunction | Disjunction,\n prefix: Prefix,\n args: Args,\n options: AstToZQLOptions,\n): string {\n const {type, conditions} = condition;\n\n // For single condition, no need for logical operator\n if (conditions.length === 1) {\n return transformCondition(conditions[0], prefix, args, options);\n }\n\n // Generate multiple where calls for top-level AND conditions\n if (type === 'and') {\n const parts = conditions.map(c =>\n transformCondition(c, prefix, args, options),\n );\n // Simply concatenate the where conditions\n if (prefix === '.where') {\n return parts.join('');\n }\n args.add('and');\n return 'and(' + parts.join(', ') + ')';\n }\n\n args = new Set<string>();\n\n // Handle nested conditions with a callback for OR conditions and nested ANDs/ORs\n const conditionsCode = conditions\n .map(c => transformCondition(c, 'cmp', args, options))\n .join(', ');\n\n args.add('cmp');\n args.add(type);\n const argsCode = toSorted(args).join(', ');\n\n return `.where(({${argsCode}}) => ${type}(${conditionsCode}))`;\n}\n\nfunction transformExistsCondition(\n condition: CorrelatedSubqueryCondition,\n prefix: '.where' | 'cmp',\n args: Set<string>,\n options: AstToZQLOptions,\n): string {\n const {related, op} = condition;\n const relationship = extractRelationshipName(related);\n\n const nextSubquery = getNextExistsSubquery(related);\n\n // Check if subquery has additional properties\n const hasSubQueryProps =\n nextSubquery.where ||\n (nextSubquery.related && nextSubquery.related.length > 0) ||\n nextSubquery.orderBy ||\n nextSubquery.limit;\n\n // Build options string for flip and scalar\n const optionParts: string[] = [];\n if (condition.flip !== undefined) {\n optionParts.push(`flip: ${condition.flip}`);\n }\n if (condition.scalar !== undefined) {\n optionParts.push(`scalar: ${condition.scalar}`);\n }\n const optionsStr =\n optionParts.length > 0 ? `, {${optionParts.join(', ')}}` : '';\n\n if (op === 'EXISTS') {\n if (!hasSubQueryProps) {\n if (prefix === '.where') {\n return `.whereExists('${relationship}'${optionsStr})`;\n }\n args.add('exists');\n return `exists('${relationship}'${optionsStr})`;\n }\n\n if (prefix === '.where') {\n return `.whereExists('${relationship}', q => q${astToZQL(nextSubquery, options)}${optionsStr})`;\n }\n prefix satisfies 'cmp';\n args.add('exists');\n return `exists('${relationship}', q => q${astToZQL(nextSubquery, options)}${optionsStr})`;\n }\n\n op satisfies 'NOT EXISTS';\n\n if (hasSubQueryProps) {\n if (prefix === '.where') {\n return `.where(({exists, not}) => not(exists('${relationship}', q => q${astToZQL(\n nextSubquery,\n options,\n )}${optionsStr})))`;\n }\n prefix satisfies 'cmp';\n args.add('not');\n args.add('exists');\n return `not(exists('${relationship}', q => q${astToZQL(nextSubquery, options)}${optionsStr}))`;\n }\n\n if (prefix === '.where') {\n return `.where(({exists, not}) => not(exists('${relationship}'${optionsStr})))`;\n }\n args.add('not');\n args.add('exists');\n\n return `not(exists('${relationship}'${optionsStr})))`;\n}\n\n// If the `exists` is applied against a junction edge, both hops will have the same alias and both hops will be exists conditions.\nfunction getNextExistsSubquery(related: CorrelatedSubquery): AST {\n if (\n related.subquery.where?.type === 'correlatedSubquery' &&\n related.subquery.where.related.subquery.alias?.includes(\n SUBQ_PREFIX + 'zhidden_',\n )\n ) {\n return getNextExistsSubquery(related.subquery.where.related);\n }\n\n return related.subquery;\n}\n\nfunction extractRelationshipName(related: CorrelatedSubquery): string {\n const alias = must(related.subquery.alias);\n return alias.startsWith(SUBQ_PREFIX)\n ? alias.substring(SUBQ_PREFIX.length)\n : alias;\n}\n\nfunction transformRelated(\n related: CorrelatedSubquery,\n options: AstToZQLOptions,\n): string {\n const {alias} = related.subquery;\n if (!alias) return '';\n\n const relationship = alias;\n let code = `.related('${relationship}'`;\n\n // If the subquery has additional filters or configurations\n if (\n related.subquery.where ||\n (related.subquery.related && related.subquery.related.length > 0) ||\n related.subquery.orderBy ||\n related.subquery.limit\n ) {\n code += ', q => q' + astToZQL(related.subquery, options);\n }\n\n code += ')';\n return code;\n}\n\nfunction transformOrder(orderBy: Ordering): string {\n let code = '';\n for (const [field, direction] of orderBy) {\n code += `.orderBy('${field}', '${direction}')`;\n }\n return code;\n}\n\nfunction transformValuePosition(\n value: ValuePosition,\n options: AstToZQLOptions,\n): string {\n switch (value.type) {\n case 'literal':\n return options.redactLiterals ? '?' : transformLiteral(value);\n case 'column':\n return `'${value.name}'`;\n case 'static':\n return transformParameter(value);\n default:\n unreachable(value);\n }\n}\n\nfunction transformLiteral(literal: LiteralReference): string {\n if (literal.value === null) {\n return 'null';\n }\n if (Array.isArray(literal.value)) {\n return JSON.stringify(literal.value);\n }\n if (typeof literal.value === 'string') {\n return `'${literal.value.replace(/'/g, \"\\\\'\")}'`;\n }\n return String(literal.value);\n}\n\nfunction transformParameter(param: Parameter): string {\n const fieldStr = Array.isArray(param.field)\n ? `[${param.field.map(f => `'${f}'`).join(', ')}]`\n : `'${param.field}'`;\n\n return `authParam(${fieldStr})`;\n}\n"],"mappings":"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"}
@@ -2,17 +2,18 @@ import { valita_exports } from "../../shared/src/valita.js";
2
2
  import { mapAST } from "../../zero-protocol/src/ast.js";
3
3
  import { serverToClient } from "../../zero-schema/src/name-mapper.js";
4
4
  import { parseOptions } from "../../shared/src/options.js";
5
+ import { loadSchemaAndPermissions } from "../../zero-cache/src/scripts/permissions.js";
5
6
  import { astToZQL } from "./ast-to-zql.js";
6
7
  import { formatOutput } from "./format.js";
7
- import { loadSchemaAndPermissions } from "../../zero-cache/src/scripts/permissions.js";
8
8
  import process from "node:process";
9
9
  import { readFile } from "node:fs/promises";
10
10
  import { createInterface } from "node:readline";
11
11
  //#region ../ast-to-zql/src/bin.ts
12
- var config = parseOptions({ schema: {
12
+ var options = { schema: {
13
13
  type: valita_exports.string().optional(),
14
14
  desc: ["Path to the schema file. Use this to re-map the AST to client names."]
15
- } });
15
+ } };
16
+ var config = parseOptions(options);
16
17
  var schema;
17
18
  if (config.schema) schema = (await loadSchemaAndPermissions(config.schema)).schema;
18
19
  function isStdinPiped() {
@@ -1 +1 @@
1
- {"version":3,"file":"bin.js","names":[],"sources":["../../../../ast-to-zql/src/bin.ts"],"sourcesContent":["/* oxlint-disable no-console */\nimport {readFile} from 'node:fs/promises';\nimport process from 'node:process';\nimport {createInterface} from 'node:readline';\nimport {parseOptions} from '../../shared/src/options.ts';\nimport * as v from '../../shared/src/valita.ts';\nimport {loadSchemaAndPermissions} from '../../zero-cache/src/scripts/permissions.ts';\nimport {mapAST} from '../../zero-protocol/src/ast.ts';\nimport {serverToClient} from '../../zero-schema/src/name-mapper.ts';\nimport type {Schema} from '../../zero-types/src/schema.ts';\nimport {astToZQL} from './ast-to-zql.ts';\nimport {formatOutput} from './format.ts';\n\nconst options = {\n schema: {\n type: v.string().optional(),\n desc: [\n 'Path to the schema file. Use this to re-map the AST to client names.',\n ],\n },\n};\n\nconst config = parseOptions(options);\n\nlet schema: Schema | undefined;\nif (config.schema) {\n schema = (await loadSchemaAndPermissions(config.schema)).schema;\n}\n\nfunction isStdinPiped(): boolean {\n return !process.stdin.isTTY;\n}\n\nfunction readFromStdin(): Promise<string> {\n return new Promise(resolve => {\n let data = '';\n const rl = createInterface({\n input: process.stdin,\n output: process.stdout,\n terminal: false,\n });\n\n rl.on('line', line => {\n data += line + '\\n';\n });\n\n rl.on('close', () => {\n resolve(data);\n });\n });\n}\n\nasync function main(): Promise<void> {\n try {\n let input: string;\n\n if (isStdinPiped()) {\n input = await readFromStdin();\n } else if (process.argv.length > 2) {\n const filePath = process.argv[2];\n input = await readFile(filePath, 'utf-8');\n } else {\n console.error('Error: No input provided.');\n console.error('Usage:');\n console.error(` cat ast.json | npx ast-to-zql`);\n console.error(` npx ast-to-zql ast.json`);\n process.exit(1);\n }\n\n let ast = JSON.parse(input);\n if (schema) {\n const mapper = serverToClient(schema.tables);\n ast = mapAST(ast, mapper);\n }\n\n const zql = astToZQL(ast);\n const code = `query.${ast.table}${zql}`;\n\n console.log(await formatOutput(code));\n } catch (error) {\n console.error('Error processing input:', error);\n process.exit(1);\n }\n}\n\nawait main();\n"],"mappings":";;;;;;;;;;;AAsBA,IAAM,SAAS,aAAa,EAR1B,QAAQ;CACN,MAAM,eAAE,OAAO,EAAE,SAAS;CAC1B,MAAM,CACJ,sEACF;AACF,EAG0B,CAAO;AAEnC,IAAI;AACJ,IAAI,OAAO,QACT,UAAU,MAAM,yBAAyB,OAAO,MAAM,GAAG;AAG3D,SAAS,eAAwB;CAC/B,OAAO,CAAC,QAAQ,MAAM;AACxB;AAEA,SAAS,gBAAiC;CACxC,OAAO,IAAI,SAAQ,YAAW;EAC5B,IAAI,OAAO;EACX,MAAM,KAAK,gBAAgB;GACzB,OAAO,QAAQ;GACf,QAAQ,QAAQ;GAChB,UAAU;EACZ,CAAC;EAED,GAAG,GAAG,SAAQ,SAAQ;GACpB,QAAQ,OAAO;EACjB,CAAC;EAED,GAAG,GAAG,eAAe;GACnB,QAAQ,IAAI;EACd,CAAC;CACH,CAAC;AACH;AAEA,eAAe,OAAsB;CACnC,IAAI;EACF,IAAI;EAEJ,IAAI,aAAa,GACf,QAAQ,MAAM,cAAc;OACvB,IAAI,QAAQ,KAAK,SAAS,GAAG;GAClC,MAAM,WAAW,QAAQ,KAAK;GAC9B,QAAQ,MAAM,SAAS,UAAU,OAAO;EAC1C,OAAO;GACL,QAAQ,MAAM,2BAA2B;GACzC,QAAQ,MAAM,QAAQ;GACtB,QAAQ,MAAM,iCAAiC;GAC/C,QAAQ,MAAM,2BAA2B;GACzC,QAAQ,KAAK,CAAC;EAChB;EAEA,IAAI,MAAM,KAAK,MAAM,KAAK;EAC1B,IAAI,QAAQ;GACV,MAAM,SAAS,eAAe,OAAO,MAAM;GAC3C,MAAM,OAAO,KAAK,MAAM;EAC1B;EAEA,MAAM,MAAM,SAAS,GAAG;EACxB,MAAM,OAAO,SAAS,IAAI,QAAQ;EAElC,QAAQ,IAAI,MAAM,aAAa,IAAI,CAAC;CACtC,SAAS,OAAO;EACd,QAAQ,MAAM,2BAA2B,KAAK;EAC9C,QAAQ,KAAK,CAAC;CAChB;AACF;AAEA,MAAM,KAAK"}
1
+ {"version":3,"file":"bin.js","names":["v"],"sources":["../../../../ast-to-zql/src/bin.ts"],"sourcesContent":["/* oxlint-disable no-console */\nimport {readFile} from 'node:fs/promises';\nimport process from 'node:process';\nimport {createInterface} from 'node:readline';\nimport {parseOptions} from '../../shared/src/options.ts';\nimport * as v from '../../shared/src/valita.ts';\nimport {loadSchemaAndPermissions} from '../../zero-cache/src/scripts/permissions.ts';\nimport {mapAST} from '../../zero-protocol/src/ast.ts';\nimport {serverToClient} from '../../zero-schema/src/name-mapper.ts';\nimport type {Schema} from '../../zero-types/src/schema.ts';\nimport {astToZQL} from './ast-to-zql.ts';\nimport {formatOutput} from './format.ts';\n\nconst options = {\n schema: {\n type: v.string().optional(),\n desc: [\n 'Path to the schema file. Use this to re-map the AST to client names.',\n ],\n },\n};\n\nconst config = parseOptions(options);\n\nlet schema: Schema | undefined;\nif (config.schema) {\n schema = (await loadSchemaAndPermissions(config.schema)).schema;\n}\n\nfunction isStdinPiped(): boolean {\n return !process.stdin.isTTY;\n}\n\nfunction readFromStdin(): Promise<string> {\n return new Promise(resolve => {\n let data = '';\n const rl = createInterface({\n input: process.stdin,\n output: process.stdout,\n terminal: false,\n });\n\n rl.on('line', line => {\n data += line + '\\n';\n });\n\n rl.on('close', () => {\n resolve(data);\n });\n });\n}\n\nasync function main(): Promise<void> {\n try {\n let input: string;\n\n if (isStdinPiped()) {\n input = await readFromStdin();\n } else if (process.argv.length > 2) {\n const filePath = process.argv[2];\n input = await readFile(filePath, 'utf-8');\n } else {\n console.error('Error: No input provided.');\n console.error('Usage:');\n console.error(` cat ast.json | npx ast-to-zql`);\n console.error(` npx ast-to-zql ast.json`);\n process.exit(1);\n }\n\n let ast = JSON.parse(input);\n if (schema) {\n const mapper = serverToClient(schema.tables);\n ast = mapAST(ast, mapper);\n }\n\n const zql = astToZQL(ast);\n const code = `query.${ast.table}${zql}`;\n\n console.log(await formatOutput(code));\n } catch (error) {\n console.error('Error processing input:', error);\n process.exit(1);\n }\n}\n\nawait main();\n"],"mappings":";;;;;;;;;;;AAaA,IAAM,UAAU,EACd,QAAQ;CACN,MAAMA,eAAE,OAAO,CAAC,CAAC,SAAS;CAC1B,MAAM,CACJ,sEACF;AACF,EACF;AAEA,IAAM,SAAS,aAAa,OAAO;AAEnC,IAAI;AACJ,IAAI,OAAO,QACT,UAAU,MAAM,yBAAyB,OAAO,MAAM,EAAA,CAAG;AAG3D,SAAS,eAAwB;CAC/B,OAAO,CAAC,QAAQ,MAAM;AACxB;AAEA,SAAS,gBAAiC;CACxC,OAAO,IAAI,SAAQ,YAAW;EAC5B,IAAI,OAAO;EACX,MAAM,KAAK,gBAAgB;GACzB,OAAO,QAAQ;GACf,QAAQ,QAAQ;GAChB,UAAU;EACZ,CAAC;EAED,GAAG,GAAG,SAAQ,SAAQ;GACpB,QAAQ,OAAO;EACjB,CAAC;EAED,GAAG,GAAG,eAAe;GACnB,QAAQ,IAAI;EACd,CAAC;CACH,CAAC;AACH;AAEA,eAAe,OAAsB;CACnC,IAAI;EACF,IAAI;EAEJ,IAAI,aAAa,GACf,QAAQ,MAAM,cAAc;OACvB,IAAI,QAAQ,KAAK,SAAS,GAAG;GAClC,MAAM,WAAW,QAAQ,KAAK;GAC9B,QAAQ,MAAM,SAAS,UAAU,OAAO;EAC1C,OAAO;GACL,QAAQ,MAAM,2BAA2B;GACzC,QAAQ,MAAM,QAAQ;GACtB,QAAQ,MAAM,iCAAiC;GAC/C,QAAQ,MAAM,2BAA2B;GACzC,QAAQ,KAAK,CAAC;EAChB;EAEA,IAAI,MAAM,KAAK,MAAM,KAAK;EAC1B,IAAI,QAAQ;GACV,MAAM,SAAS,eAAe,OAAO,MAAM;GAC3C,MAAM,OAAO,KAAK,MAAM;EAC1B;EAEA,MAAM,MAAM,SAAS,GAAG;EACxB,MAAM,OAAO,SAAS,IAAI,QAAQ;EAElC,QAAQ,IAAI,MAAM,aAAa,IAAI,CAAC;CACtC,SAAS,OAAO;EACd,QAAQ,MAAM,2BAA2B,KAAK;EAC9C,QAAQ,KAAK,CAAC;CAChB;AACF;AAEA,MAAM,KAAK"}
@@ -1 +1 @@
1
- {"version":3,"file":"format.js","names":[],"sources":["../../../../ast-to-zql/src/format.ts"],"sourcesContent":["import {format} from 'oxfmt';\n\nexport async function formatOutput(content: string): Promise<string> {\n try {\n const result = await format('output.ts', content, {\n semi: false,\n printWidth: 80,\n });\n return result.code;\n } catch (error) {\n // oxlint-disable-next-line no-console\n console.warn('Warning: Unable to format output with oxfmt:', error);\n return content;\n }\n}\n"],"mappings":";;AAEA,eAAsB,aAAa,SAAkC;CACnE,IAAI;EAKF,QAAO,MAJc,OAAO,aAAa,SAAS;GAChD,MAAM;GACN,YAAY;EACd,CAAC,GACa;CAChB,SAAS,OAAO;EAEd,QAAQ,KAAK,gDAAgD,KAAK;EAClE,OAAO;CACT;AACF"}
1
+ {"version":3,"file":"format.js","names":[],"sources":["../../../../ast-to-zql/src/format.ts"],"sourcesContent":["import {format} from 'oxfmt';\n\nexport async function formatOutput(content: string): Promise<string> {\n try {\n const result = await format('output.ts', content, {\n semi: false,\n printWidth: 80,\n });\n return result.code;\n } catch (error) {\n // oxlint-disable-next-line no-console\n console.warn('Warning: Unable to format output with oxfmt:', error);\n return content;\n }\n}\n"],"mappings":";;AAEA,eAAsB,aAAa,SAAkC;CACnE,IAAI;EAKF,QAAO,MAJc,OAAO,aAAa,SAAS;GAChD,MAAM;GACN,YAAY;EACd,CAAC,EAAA,CACa;CAChB,SAAS,OAAO;EAEd,QAAQ,KAAK,gDAAgD,KAAK;EAClE,OAAO;CACT;AACF"}
@@ -1,9 +1,10 @@
1
1
  import { Lock } from "@rocicorp/lock";
2
2
  //#region ../datadog/src/datadog-log-sink.ts
3
3
  var DD_BASE_URL = new URL("https://http-intake.logs.datadoghq.com/api/v2/logs");
4
- var MAX_ENTRY_BYTES = 5 * 1024 * 1024;
4
+ var MAX_LOG_ENTRIES_PER_FLUSH = 1e3;
5
+ var MAX_ENTRY_BYTES = 5242880;
5
6
  var MAX_MESSAGE_RETRIES = 2;
6
- MAX_ENTRY_BYTES / 4;
7
+ var MAX_ENTRY_CHARS = MAX_ENTRY_BYTES / 4;
7
8
  var DatadogLogSink = class {
8
9
  #messages = [];
9
10
  #apiKey;
@@ -88,7 +89,7 @@ var DatadogLogSink = class {
88
89
  if (m.flushRetryCount > MAX_MESSAGE_RETRIES) numWithTooManyRetries++;
89
90
  }
90
91
  if (numWithTooManyRetries > 0) {
91
- console.error(`Dropping ${numWithTooManyRetries} datadog log messages which failed to send ${MAX_MESSAGE_RETRIES + 1} times.`);
92
+ console.error(`Dropping ${numWithTooManyRetries} datadog log messages which failed to send 3 times.`);
92
93
  this.#messages.splice(0, numWithTooManyRetries);
93
94
  }
94
95
  }
@@ -153,6 +154,6 @@ function makeMessage(message, context, logLevel) {
153
154
  return msg;
154
155
  }
155
156
  //#endregion
156
- export { DatadogLogSink };
157
+ export { DatadogLogSink, MAX_ENTRY_CHARS, MAX_LOG_ENTRIES_PER_FLUSH };
157
158
 
158
159
  //# sourceMappingURL=datadog-log-sink.js.map