@rocicorp/zero 1.12.0-canary.7 → 1.12.0-canary.9

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 (518) hide show
  1. package/out/replicache/src/btree/node.d.ts +0 -2
  2. package/out/replicache/src/btree/node.d.ts.map +1 -1
  3. package/out/replicache/src/btree/node.js.map +1 -1
  4. package/out/replicache/src/connection-loop.d.ts.map +1 -1
  5. package/out/replicache/src/connection-loop.js +1 -1
  6. package/out/replicache/src/connection-loop.js.map +1 -1
  7. package/out/replicache/src/db/commit.d.ts +0 -1
  8. package/out/replicache/src/db/commit.d.ts.map +1 -1
  9. package/out/replicache/src/db/commit.js +1 -1
  10. package/out/replicache/src/db/commit.js.map +1 -1
  11. package/out/replicache/src/db/write.d.ts +0 -2
  12. package/out/replicache/src/db/write.d.ts.map +1 -1
  13. package/out/replicache/src/db/write.js +1 -1
  14. package/out/replicache/src/db/write.js.map +1 -1
  15. package/out/replicache/src/deleted-clients.d.ts +0 -2
  16. package/out/replicache/src/deleted-clients.d.ts.map +1 -1
  17. package/out/replicache/src/deleted-clients.js +1 -1
  18. package/out/replicache/src/deleted-clients.js.map +1 -1
  19. package/out/replicache/src/frozen-json.d.ts +0 -1
  20. package/out/replicache/src/frozen-json.d.ts.map +1 -1
  21. package/out/replicache/src/frozen-json.js.map +1 -1
  22. package/out/replicache/src/index-defs.d.ts +0 -2
  23. package/out/replicache/src/index-defs.d.ts.map +1 -1
  24. package/out/replicache/src/index-defs.js +1 -1
  25. package/out/replicache/src/index-defs.js.map +1 -1
  26. package/out/replicache/src/kv/expo-sqlite/store.d.ts +0 -1
  27. package/out/replicache/src/kv/expo-sqlite/store.d.ts.map +1 -1
  28. package/out/replicache/src/kv/expo-sqlite/store.js +1 -1
  29. package/out/replicache/src/kv/expo-sqlite/store.js.map +1 -1
  30. package/out/replicache/src/kv/idb-store.js +1 -1
  31. package/out/replicache/src/kv/idb-store.js.map +1 -1
  32. package/out/replicache/src/kv/throw-if-closed.d.ts +0 -3
  33. package/out/replicache/src/kv/throw-if-closed.d.ts.map +1 -1
  34. package/out/replicache/src/kv/throw-if-closed.js.map +1 -1
  35. package/out/replicache/src/persist/client-group-gc.d.ts +0 -7
  36. package/out/replicache/src/persist/client-group-gc.d.ts.map +1 -1
  37. package/out/replicache/src/persist/client-group-gc.js +1 -1
  38. package/out/replicache/src/persist/client-group-gc.js.map +1 -1
  39. package/out/replicache/src/process-scheduler.js +1 -1
  40. package/out/replicache/src/process-scheduler.js.map +1 -1
  41. package/out/replicache/src/replicache-impl.d.ts +2 -7
  42. package/out/replicache/src/replicache-impl.d.ts.map +1 -1
  43. package/out/replicache/src/replicache-impl.js +1 -1
  44. package/out/replicache/src/replicache-impl.js.map +1 -1
  45. package/out/replicache/src/sync/patch.d.ts +0 -5
  46. package/out/replicache/src/sync/patch.d.ts.map +1 -1
  47. package/out/replicache/src/sync/patch.js +1 -1
  48. package/out/replicache/src/sync/patch.js.map +1 -1
  49. package/out/replicache/src/sync/pull.d.ts +0 -1
  50. package/out/replicache/src/sync/pull.d.ts.map +1 -1
  51. package/out/replicache/src/sync/pull.js.map +1 -1
  52. package/out/replicache/src/sync/push.d.ts +2 -1
  53. package/out/replicache/src/sync/push.d.ts.map +1 -1
  54. package/out/replicache/src/sync/push.js.map +1 -1
  55. package/out/replicache/src/types.d.ts +2 -1
  56. package/out/replicache/src/types.d.ts.map +1 -1
  57. package/out/shared/src/asserts.d.ts +0 -5
  58. package/out/shared/src/asserts.d.ts.map +1 -1
  59. package/out/shared/src/asserts.js +1 -1
  60. package/out/shared/src/asserts.js.map +1 -1
  61. package/out/shared/src/browser-env.d.ts +0 -17
  62. package/out/shared/src/browser-env.d.ts.map +1 -1
  63. package/out/shared/src/browser-env.js.map +1 -1
  64. package/out/shared/src/deep-clone.d.ts +0 -1
  65. package/out/shared/src/deep-clone.d.ts.map +1 -1
  66. package/out/shared/src/deep-clone.js +1 -1
  67. package/out/shared/src/deep-clone.js.map +1 -1
  68. package/out/shared/src/document-visible.js +1 -1
  69. package/out/shared/src/document-visible.js.map +1 -1
  70. package/out/shared/src/expand.d.ts +0 -3
  71. package/out/shared/src/expand.d.ts.map +1 -1
  72. package/out/shared/src/immutable.d.ts +1 -1
  73. package/out/shared/src/immutable.d.ts.map +1 -1
  74. package/out/shared/src/iterables.d.ts +0 -1
  75. package/out/shared/src/iterables.d.ts.map +1 -1
  76. package/out/shared/src/iterables.js.map +1 -1
  77. package/out/shared/src/logging-test-utils.js +1 -1
  78. package/out/shared/src/logging-test-utils.js.map +1 -1
  79. package/out/shared/src/options-types.d.ts +1 -1
  80. package/out/shared/src/options-types.d.ts.map +1 -1
  81. package/out/shared/src/options.d.ts +2 -3
  82. package/out/shared/src/options.d.ts.map +1 -1
  83. package/out/shared/src/options.js +1 -1
  84. package/out/shared/src/options.js.map +1 -1
  85. package/out/shared/src/promise-race.js +1 -1
  86. package/out/shared/src/promise-race.js.map +1 -1
  87. package/out/shared/src/queue.js +1 -1
  88. package/out/shared/src/queue.js.map +1 -1
  89. package/out/shared/src/resolved-promises.d.ts +0 -4
  90. package/out/shared/src/resolved-promises.d.ts.map +1 -1
  91. package/out/shared/src/resolved-promises.js +0 -1
  92. package/out/shared/src/resolved-promises.js.map +1 -1
  93. package/out/shared/src/resolver.d.ts +9 -0
  94. package/out/shared/src/resolver.d.ts.map +1 -0
  95. package/out/shared/src/resolver.js +6 -0
  96. package/out/shared/src/resolver.js.map +1 -0
  97. package/out/shared/src/sleep.js +1 -1
  98. package/out/shared/src/sleep.js.map +1 -1
  99. package/out/shared/src/tdigest.d.ts +0 -1
  100. package/out/shared/src/tdigest.d.ts.map +1 -1
  101. package/out/shared/src/tdigest.js.map +1 -1
  102. package/out/z2s/src/sql.d.ts +1 -5
  103. package/out/z2s/src/sql.d.ts.map +1 -1
  104. package/out/z2s/src/sql.js.map +1 -1
  105. package/out/zero/package.js +2 -3
  106. package/out/zero/package.js.map +1 -1
  107. package/out/zero/src/zero-cache-dev.js +1 -1
  108. package/out/zero/src/zero-cache-dev.js.map +1 -1
  109. package/out/zero-cache/src/config/zero-config.d.ts +14 -11
  110. package/out/zero-cache/src/config/zero-config.d.ts.map +1 -1
  111. package/out/zero-cache/src/config/zero-config.js +23 -0
  112. package/out/zero-cache/src/config/zero-config.js.map +1 -1
  113. package/out/zero-cache/src/db/migration-lite.js.map +1 -1
  114. package/out/zero-cache/src/db/migration.js +1 -1
  115. package/out/zero-cache/src/db/migration.js.map +1 -1
  116. package/out/zero-cache/src/db/pg-copy-binary.js +1 -1
  117. package/out/zero-cache/src/db/pg-copy-binary.js.map +1 -1
  118. package/out/zero-cache/src/db/pg-type-parser.js.map +1 -1
  119. package/out/zero-cache/src/db/specs.d.ts +3 -4
  120. package/out/zero-cache/src/db/specs.d.ts.map +1 -1
  121. package/out/zero-cache/src/db/specs.js +5 -7
  122. package/out/zero-cache/src/db/specs.js.map +1 -1
  123. package/out/zero-cache/src/db/transaction-pool.js +2 -2
  124. package/out/zero-cache/src/db/transaction-pool.js.map +1 -1
  125. package/out/zero-cache/src/observability/events.js +1 -1
  126. package/out/zero-cache/src/observability/events.js.map +1 -1
  127. package/out/zero-cache/src/server/change-streamer.js +1 -1
  128. package/out/zero-cache/src/server/change-streamer.js.map +1 -1
  129. package/out/zero-cache/src/server/main.js +1 -1
  130. package/out/zero-cache/src/server/main.js.map +1 -1
  131. package/out/zero-cache/src/server/runner/run-worker.js +1 -1
  132. package/out/zero-cache/src/server/runner/run-worker.js.map +1 -1
  133. package/out/zero-cache/src/services/change-source/common/backfill-manager.js +1 -1
  134. package/out/zero-cache/src/services/change-source/common/backfill-manager.js.map +1 -1
  135. package/out/zero-cache/src/services/change-source/common/change-stream-multiplexer.js +1 -1
  136. package/out/zero-cache/src/services/change-source/common/change-stream-multiplexer.js.map +1 -1
  137. package/out/zero-cache/src/services/change-source/common/replica-restore.js.map +1 -1
  138. package/out/zero-cache/src/services/change-source/custom/change-source.js +1 -1
  139. package/out/zero-cache/src/services/change-source/custom/change-source.js.map +1 -1
  140. package/out/zero-cache/src/services/change-source/pg/backfill-stream.js +1 -1
  141. package/out/zero-cache/src/services/change-source/pg/backfill-stream.js.map +1 -1
  142. package/out/zero-cache/src/services/change-source/pg/change-source.js +1 -1
  143. package/out/zero-cache/src/services/change-source/pg/change-source.js.map +1 -1
  144. package/out/zero-cache/src/services/change-source/pg/initial-sync.js +1 -1
  145. package/out/zero-cache/src/services/change-source/pg/initial-sync.js.map +1 -1
  146. package/out/zero-cache/src/services/change-source/pg/lsn.d.ts +0 -2
  147. package/out/zero-cache/src/services/change-source/pg/lsn.d.ts.map +1 -1
  148. package/out/zero-cache/src/services/change-source/pg/lsn.js.map +1 -1
  149. package/out/zero-cache/src/services/change-source/pg/replication-slots.js +1 -1
  150. package/out/zero-cache/src/services/change-source/pg/replication-slots.js.map +1 -1
  151. package/out/zero-cache/src/services/change-source/pg/schema/ddl.d.ts +0 -12
  152. package/out/zero-cache/src/services/change-source/pg/schema/ddl.d.ts.map +1 -1
  153. package/out/zero-cache/src/services/change-source/pg/schema/ddl.js +5 -3
  154. package/out/zero-cache/src/services/change-source/pg/schema/ddl.js.map +1 -1
  155. package/out/zero-cache/src/services/change-source/pg/schema/index-predicate.d.ts +1 -1
  156. package/out/zero-cache/src/services/change-source/pg/schema/index-predicate.d.ts.map +1 -1
  157. package/out/zero-cache/src/services/change-source/pg/schema/index-predicate.js.map +1 -1
  158. package/out/zero-cache/src/services/change-source/pg/schema/validation.d.ts +0 -1
  159. package/out/zero-cache/src/services/change-source/pg/schema/validation.d.ts.map +1 -1
  160. package/out/zero-cache/src/services/change-source/pg/schema/validation.js.map +1 -1
  161. package/out/zero-cache/src/services/change-streamer/backup-monitor.js +1 -1
  162. package/out/zero-cache/src/services/change-streamer/backup-monitor.js.map +1 -1
  163. package/out/zero-cache/src/services/change-streamer/broadcast.js +1 -1
  164. package/out/zero-cache/src/services/change-streamer/broadcast.js.map +1 -1
  165. package/out/zero-cache/src/services/change-streamer/change-streamer-http.js +1 -1
  166. package/out/zero-cache/src/services/change-streamer/change-streamer-http.js.map +1 -1
  167. package/out/zero-cache/src/services/change-streamer/change-streamer-service.js +1 -1
  168. package/out/zero-cache/src/services/change-streamer/change-streamer-service.js.map +1 -1
  169. package/out/zero-cache/src/services/change-streamer/change-streamer.js +1 -1
  170. package/out/zero-cache/src/services/change-streamer/change-streamer.js.map +1 -1
  171. package/out/zero-cache/src/services/change-streamer/drain-tracker.js +1 -1
  172. package/out/zero-cache/src/services/change-streamer/drain-tracker.js.map +1 -1
  173. package/out/zero-cache/src/services/change-streamer/litestream3-prometheus-poller.js +2 -2
  174. package/out/zero-cache/src/services/change-streamer/litestream3-prometheus-poller.js.map +1 -1
  175. package/out/zero-cache/src/services/change-streamer/restore-admission.js +2 -2
  176. package/out/zero-cache/src/services/change-streamer/restore-admission.js.map +1 -1
  177. package/out/zero-cache/src/services/change-streamer/schema/tables.js +1 -1
  178. package/out/zero-cache/src/services/change-streamer/schema/tables.js.map +1 -1
  179. package/out/zero-cache/src/services/change-streamer/snapshot-message.js +2 -3
  180. package/out/zero-cache/src/services/change-streamer/snapshot-message.js.map +1 -1
  181. package/out/zero-cache/src/services/change-streamer/sqlite-change-log-catchup.js +2 -2
  182. package/out/zero-cache/src/services/change-streamer/sqlite-change-log-catchup.js.map +1 -1
  183. package/out/zero-cache/src/services/change-streamer/sqlite-change-log-read-router.js.map +1 -1
  184. package/out/zero-cache/src/services/change-streamer/storer.js +1 -1
  185. package/out/zero-cache/src/services/change-streamer/storer.js.map +1 -1
  186. package/out/zero-cache/src/services/change-streamer/subscribe.js +1 -1
  187. package/out/zero-cache/src/services/change-streamer/subscribe.js.map +1 -1
  188. package/out/zero-cache/src/services/change-streamer/subscriber.js +1 -1
  189. package/out/zero-cache/src/services/change-streamer/subscriber.js.map +1 -1
  190. package/out/zero-cache/src/services/life-cycle.js +1 -1
  191. package/out/zero-cache/src/services/life-cycle.js.map +1 -1
  192. package/out/zero-cache/src/services/litestream/commands.js +1 -1
  193. package/out/zero-cache/src/services/litestream/commands.js.map +1 -1
  194. package/out/zero-cache/src/services/litestream/metrics.js.map +1 -1
  195. package/out/zero-cache/src/services/mutagen/mutagen.js +2 -2
  196. package/out/zero-cache/src/services/mutagen/mutagen.js.map +1 -1
  197. package/out/zero-cache/src/services/mutagen/pusher.js +57 -14
  198. package/out/zero-cache/src/services/mutagen/pusher.js.map +1 -1
  199. package/out/zero-cache/src/services/plannerz.d.ts +4 -12
  200. package/out/zero-cache/src/services/plannerz.d.ts.map +1 -1
  201. package/out/zero-cache/src/services/plannerz.js +1 -3
  202. package/out/zero-cache/src/services/plannerz.js.map +1 -1
  203. package/out/zero-cache/src/services/replicator/change-log-db.js +1 -1
  204. package/out/zero-cache/src/services/replicator/change-log-db.js.map +1 -1
  205. package/out/zero-cache/src/services/replicator/change-log-stream-writer.js +1 -1
  206. package/out/zero-cache/src/services/replicator/change-log-stream-writer.js.map +1 -1
  207. package/out/zero-cache/src/services/replicator/drain-handler.js +1 -1
  208. package/out/zero-cache/src/services/replicator/drain-handler.js.map +1 -1
  209. package/out/zero-cache/src/services/replicator/reporter/recorder.js +1 -1
  210. package/out/zero-cache/src/services/replicator/reporter/recorder.js.map +1 -1
  211. package/out/zero-cache/src/services/replicator/reporter/report-schema.d.ts +2 -11
  212. package/out/zero-cache/src/services/replicator/reporter/report-schema.d.ts.map +1 -1
  213. package/out/zero-cache/src/services/replicator/reporter/report-schema.js +1 -1
  214. package/out/zero-cache/src/services/replicator/reporter/report-schema.js.map +1 -1
  215. package/out/zero-cache/src/services/replicator/schema/change-log.d.ts +0 -10
  216. package/out/zero-cache/src/services/replicator/schema/change-log.d.ts.map +1 -1
  217. package/out/zero-cache/src/services/replicator/schema/change-log.js.map +1 -1
  218. package/out/zero-cache/src/services/replicator/schema/column-metadata.d.ts +0 -7
  219. package/out/zero-cache/src/services/replicator/schema/column-metadata.d.ts.map +1 -1
  220. package/out/zero-cache/src/services/replicator/schema/column-metadata.js +1 -1
  221. package/out/zero-cache/src/services/replicator/schema/column-metadata.js.map +1 -1
  222. package/out/zero-cache/src/services/replicator/write-worker-client.js +1 -1
  223. package/out/zero-cache/src/services/replicator/write-worker-client.js.map +1 -1
  224. package/out/zero-cache/src/services/running-state.js +1 -1
  225. package/out/zero-cache/src/services/running-state.js.map +1 -1
  226. package/out/zero-cache/src/services/view-syncer/client-handler.js.map +1 -1
  227. package/out/zero-cache/src/services/view-syncer/connection-context-manager.js.map +1 -1
  228. package/out/zero-cache/src/services/view-syncer/cvr-store.js +1 -1
  229. package/out/zero-cache/src/services/view-syncer/cvr-store.js.map +1 -1
  230. package/out/zero-cache/src/services/view-syncer/cvr.js.map +1 -1
  231. package/out/zero-cache/src/services/view-syncer/drain-coordinator.js +2 -2
  232. package/out/zero-cache/src/services/view-syncer/drain-coordinator.js.map +1 -1
  233. package/out/zero-cache/src/services/view-syncer/pipeline-driver.js.map +1 -1
  234. package/out/zero-cache/src/services/view-syncer/query-stats.js.map +1 -1
  235. package/out/zero-cache/src/services/view-syncer/row-record-cache.js +1 -1
  236. package/out/zero-cache/src/services/view-syncer/row-record-cache.js.map +1 -1
  237. package/out/zero-cache/src/services/view-syncer/schema/cvr.js +1 -1
  238. package/out/zero-cache/src/services/view-syncer/schema/cvr.js.map +1 -1
  239. package/out/zero-cache/src/services/view-syncer/schema/types.js +3 -17
  240. package/out/zero-cache/src/services/view-syncer/schema/types.js.map +1 -1
  241. package/out/zero-cache/src/services/view-syncer/snapshotter.js +1 -1
  242. package/out/zero-cache/src/services/view-syncer/snapshotter.js.map +1 -1
  243. package/out/zero-cache/src/services/view-syncer/view-syncer.js +13 -10
  244. package/out/zero-cache/src/services/view-syncer/view-syncer.js.map +1 -1
  245. package/out/zero-cache/src/types/lite.d.ts +0 -1
  246. package/out/zero-cache/src/types/lite.d.ts.map +1 -1
  247. package/out/zero-cache/src/types/lite.js +2 -2
  248. package/out/zero-cache/src/types/lite.js.map +1 -1
  249. package/out/zero-cache/src/types/pg-types.d.ts +0 -40
  250. package/out/zero-cache/src/types/pg-types.d.ts.map +1 -1
  251. package/out/zero-cache/src/types/pg-types.js.map +1 -1
  252. package/out/zero-cache/src/types/poke-chunk.js +1 -1
  253. package/out/zero-cache/src/types/poke-chunk.js.map +1 -1
  254. package/out/zero-cache/src/types/row-key.d.ts +0 -5
  255. package/out/zero-cache/src/types/row-key.d.ts.map +1 -1
  256. package/out/zero-cache/src/types/row-key.js.map +1 -1
  257. package/out/zero-cache/src/types/streams.js +1 -1
  258. package/out/zero-cache/src/types/streams.js.map +1 -1
  259. package/out/zero-cache/src/types/subscription.js +1 -1
  260. package/out/zero-cache/src/types/subscription.js.map +1 -1
  261. package/out/zero-cache/src/types/websocket-handoff.d.ts +0 -6
  262. package/out/zero-cache/src/types/websocket-handoff.d.ts.map +1 -1
  263. package/out/zero-cache/src/types/websocket-handoff.js +8 -2
  264. package/out/zero-cache/src/types/websocket-handoff.js.map +1 -1
  265. package/out/zero-cache/src/types/ws.d.ts +2 -1
  266. package/out/zero-cache/src/types/ws.d.ts.map +1 -1
  267. package/out/zero-cache/src/types/ws.js +1 -1
  268. package/out/zero-cache/src/types/ws.js.map +1 -1
  269. package/out/zero-cache/src/workers/connection.js +4 -1
  270. package/out/zero-cache/src/workers/connection.js.map +1 -1
  271. package/out/zero-cache/src/workers/mutator.js +1 -1
  272. package/out/zero-cache/src/workers/mutator.js.map +1 -1
  273. package/out/zero-cache/src/workers/syncer.js +45 -3
  274. package/out/zero-cache/src/workers/syncer.js.map +1 -1
  275. package/out/zero-client/src/client/active-clients-manager.d.ts.map +1 -1
  276. package/out/zero-client/src/client/active-clients-manager.js +1 -1
  277. package/out/zero-client/src/client/active-clients-manager.js.map +1 -1
  278. package/out/zero-client/src/client/connection-manager.js +1 -1
  279. package/out/zero-client/src/client/connection-manager.js.map +1 -1
  280. package/out/zero-client/src/client/crud.d.ts +2 -8
  281. package/out/zero-client/src/client/crud.d.ts.map +1 -1
  282. package/out/zero-client/src/client/crud.js +1 -1
  283. package/out/zero-client/src/client/crud.js.map +1 -1
  284. package/out/zero-client/src/client/custom.d.ts +0 -2
  285. package/out/zero-client/src/client/custom.d.ts.map +1 -1
  286. package/out/zero-client/src/client/custom.js +1 -1
  287. package/out/zero-client/src/client/custom.js.map +1 -1
  288. package/out/zero-client/src/client/enable-analytics.d.ts +0 -1
  289. package/out/zero-client/src/client/enable-analytics.d.ts.map +1 -1
  290. package/out/zero-client/src/client/enable-analytics.js +2 -1
  291. package/out/zero-client/src/client/enable-analytics.js.map +1 -1
  292. package/out/zero-client/src/client/error.d.ts +4 -5
  293. package/out/zero-client/src/client/error.d.ts.map +1 -1
  294. package/out/zero-client/src/client/error.js.map +1 -1
  295. package/out/zero-client/src/client/keys.d.ts +0 -1
  296. package/out/zero-client/src/client/keys.d.ts.map +1 -1
  297. package/out/zero-client/src/client/keys.js +4 -2
  298. package/out/zero-client/src/client/keys.js.map +1 -1
  299. package/out/zero-client/src/client/mutation-tracker.d.ts.map +1 -1
  300. package/out/zero-client/src/client/mutation-tracker.js +1 -1
  301. package/out/zero-client/src/client/mutation-tracker.js.map +1 -1
  302. package/out/zero-client/src/client/options.d.ts +0 -4
  303. package/out/zero-client/src/client/options.d.ts.map +1 -1
  304. package/out/zero-client/src/client/options.js.map +1 -1
  305. package/out/zero-client/src/client/replicache-types.d.ts +3 -2
  306. package/out/zero-client/src/client/replicache-types.d.ts.map +1 -1
  307. package/out/zero-client/src/client/version.js +1 -1
  308. package/out/zero-client/src/client/zero-poke-handler.d.ts +1 -2
  309. package/out/zero-client/src/client/zero-poke-handler.d.ts.map +1 -1
  310. package/out/zero-client/src/client/zero-poke-handler.js +1 -1
  311. package/out/zero-client/src/client/zero-poke-handler.js.map +1 -1
  312. package/out/zero-client/src/client/zero.d.ts +1 -5
  313. package/out/zero-client/src/client/zero.d.ts.map +1 -1
  314. package/out/zero-client/src/client/zero.js +1 -1
  315. package/out/zero-client/src/client/zero.js.map +1 -1
  316. package/out/zero-client/src/types/client-state.d.ts +0 -6
  317. package/out/zero-client/src/types/client-state.d.ts.map +1 -1
  318. package/out/zero-permissions/src/permissions.d.ts +1 -12
  319. package/out/zero-permissions/src/permissions.d.ts.map +1 -1
  320. package/out/zero-permissions/src/permissions.js +1 -2
  321. package/out/zero-permissions/src/permissions.js.map +1 -1
  322. package/out/zero-protocol/src/ast.d.ts +0 -4
  323. package/out/zero-protocol/src/ast.d.ts.map +1 -1
  324. package/out/zero-protocol/src/ast.js +1 -2
  325. package/out/zero-protocol/src/ast.js.map +1 -1
  326. package/out/zero-protocol/src/change-desired-queries.d.ts +0 -20
  327. package/out/zero-protocol/src/change-desired-queries.d.ts.map +1 -1
  328. package/out/zero-protocol/src/change-desired-queries.js.map +1 -1
  329. package/out/zero-protocol/src/client-schema.d.ts +2 -5
  330. package/out/zero-protocol/src/client-schema.d.ts.map +1 -1
  331. package/out/zero-protocol/src/client-schema.js +1 -1
  332. package/out/zero-protocol/src/client-schema.js.map +1 -1
  333. package/out/zero-protocol/src/close-connection.d.ts +0 -8
  334. package/out/zero-protocol/src/close-connection.d.ts.map +1 -1
  335. package/out/zero-protocol/src/close-connection.js +1 -1
  336. package/out/zero-protocol/src/close-connection.js.map +1 -1
  337. package/out/zero-protocol/src/connect.d.ts +0 -12
  338. package/out/zero-protocol/src/connect.d.ts.map +1 -1
  339. package/out/zero-protocol/src/connect.js +1 -1
  340. package/out/zero-protocol/src/connect.js.map +1 -1
  341. package/out/zero-protocol/src/custom-queries.d.ts +3 -17
  342. package/out/zero-protocol/src/custom-queries.d.ts.map +1 -1
  343. package/out/zero-protocol/src/custom-queries.js +1 -1
  344. package/out/zero-protocol/src/custom-queries.js.map +1 -1
  345. package/out/zero-protocol/src/data.d.ts +0 -1
  346. package/out/zero-protocol/src/data.d.ts.map +1 -1
  347. package/out/zero-protocol/src/data.js +1 -1
  348. package/out/zero-protocol/src/data.js.map +1 -1
  349. package/out/zero-protocol/src/down.d.ts +27 -27
  350. package/out/zero-protocol/src/inspect-down.d.ts +82 -84
  351. package/out/zero-protocol/src/inspect-down.d.ts.map +1 -1
  352. package/out/zero-protocol/src/inspect-down.js +1 -1
  353. package/out/zero-protocol/src/inspect-down.js.map +1 -1
  354. package/out/zero-protocol/src/inspect-up.d.ts +0 -28
  355. package/out/zero-protocol/src/inspect-up.d.ts.map +1 -1
  356. package/out/zero-protocol/src/inspect-up.js +1 -1
  357. package/out/zero-protocol/src/inspect-up.js.map +1 -1
  358. package/out/zero-protocol/src/mutate-server.d.ts +0 -21
  359. package/out/zero-protocol/src/mutate-server.d.ts.map +1 -1
  360. package/out/zero-protocol/src/mutate-server.js +1 -1
  361. package/out/zero-protocol/src/mutate-server.js.map +1 -1
  362. package/out/zero-protocol/src/mutation-type-enum.d.ts +0 -1
  363. package/out/zero-protocol/src/mutation-type-enum.d.ts.map +1 -1
  364. package/out/zero-protocol/src/mutation-type-enum.js.map +1 -1
  365. package/out/zero-protocol/src/mutation.d.ts +2 -4
  366. package/out/zero-protocol/src/mutation.d.ts.map +1 -1
  367. package/out/zero-protocol/src/mutation.js +1 -1
  368. package/out/zero-protocol/src/mutation.js.map +1 -1
  369. package/out/zero-protocol/src/mutations-patch.d.ts +0 -33
  370. package/out/zero-protocol/src/mutations-patch.d.ts.map +1 -1
  371. package/out/zero-protocol/src/mutations-patch.js +1 -1
  372. package/out/zero-protocol/src/mutations-patch.js.map +1 -1
  373. package/out/zero-protocol/src/ping.d.ts +0 -2
  374. package/out/zero-protocol/src/ping.d.ts.map +1 -1
  375. package/out/zero-protocol/src/ping.js +1 -1
  376. package/out/zero-protocol/src/ping.js.map +1 -1
  377. package/out/zero-protocol/src/poke.d.ts +3 -2
  378. package/out/zero-protocol/src/poke.d.ts.map +1 -1
  379. package/out/zero-protocol/src/poke.js +1 -1
  380. package/out/zero-protocol/src/poke.js.map +1 -1
  381. package/out/zero-protocol/src/pong.d.ts +0 -2
  382. package/out/zero-protocol/src/pong.d.ts.map +1 -1
  383. package/out/zero-protocol/src/pong.js +1 -1
  384. package/out/zero-protocol/src/pong.js.map +1 -1
  385. package/out/zero-protocol/src/pull.d.ts +2 -7
  386. package/out/zero-protocol/src/pull.d.ts.map +1 -1
  387. package/out/zero-protocol/src/pull.js +1 -1
  388. package/out/zero-protocol/src/pull.js.map +1 -1
  389. package/out/zero-protocol/src/push.d.ts +1 -3
  390. package/out/zero-protocol/src/push.d.ts.map +1 -1
  391. package/out/zero-protocol/src/push.js +1 -1
  392. package/out/zero-protocol/src/push.js.map +1 -1
  393. package/out/zero-protocol/src/queries-patch.d.ts +0 -16
  394. package/out/zero-protocol/src/queries-patch.d.ts.map +1 -1
  395. package/out/zero-protocol/src/queries-patch.js +1 -1
  396. package/out/zero-protocol/src/queries-patch.js.map +1 -1
  397. package/out/zero-protocol/src/query-server.d.ts +2 -41
  398. package/out/zero-protocol/src/query-server.d.ts.map +1 -1
  399. package/out/zero-protocol/src/query-server.js +1 -1
  400. package/out/zero-protocol/src/query-server.js.map +1 -1
  401. package/out/zero-protocol/src/up.d.ts +42 -42
  402. package/out/zero-protocol/src/version.d.ts +0 -1
  403. package/out/zero-protocol/src/version.d.ts.map +1 -1
  404. package/out/zero-protocol/src/version.js.map +1 -1
  405. package/out/zero-react/src/use-query.js +1 -1
  406. package/out/zero-react/src/use-query.js.map +1 -1
  407. package/out/zero-schema/src/builder/relationship-builder.d.ts +0 -2
  408. package/out/zero-schema/src/builder/relationship-builder.d.ts.map +1 -1
  409. package/out/zero-schema/src/builder/relationship-builder.js.map +1 -1
  410. package/out/zero-schema/src/builder/table-builder.d.ts +1 -1
  411. package/out/zero-schema/src/builder/table-builder.d.ts.map +1 -1
  412. package/out/zero-schema/src/builder/table-builder.js +1 -1
  413. package/out/zero-schema/src/builder/table-builder.js.map +1 -1
  414. package/out/zero-schema/src/schema-config.d.ts +0 -1
  415. package/out/zero-schema/src/schema-config.d.ts.map +1 -1
  416. package/out/zero-schema/src/schema-config.js +1 -1
  417. package/out/zero-schema/src/schema-config.js.map +1 -1
  418. package/out/zero-schema/src/table-schema.d.ts +3 -11
  419. package/out/zero-schema/src/table-schema.d.ts.map +1 -1
  420. package/out/zero-server/src/queries/process-queries.d.ts +2 -4
  421. package/out/zero-server/src/queries/process-queries.d.ts.map +1 -1
  422. package/out/zero-server/src/queries/process-queries.js.map +1 -1
  423. package/out/zero-solid/src/solid-view.d.ts +0 -2
  424. package/out/zero-solid/src/solid-view.d.ts.map +1 -1
  425. package/out/zero-solid/src/solid-view.js +1 -1
  426. package/out/zero-solid/src/solid-view.js.map +1 -1
  427. package/out/zero-types/src/name-mapper.d.ts +2 -1
  428. package/out/zero-types/src/name-mapper.d.ts.map +1 -1
  429. package/out/zero-types/src/name-mapper.js.map +1 -1
  430. package/out/zero-types/src/schema-value.d.ts +3 -2
  431. package/out/zero-types/src/schema-value.d.ts.map +1 -1
  432. package/out/zero-types/src/schema.d.ts +1 -1
  433. package/out/zero-types/src/schema.d.ts.map +1 -1
  434. package/out/zql/src/builder/builder.d.ts +1 -11
  435. package/out/zql/src/builder/builder.d.ts.map +1 -1
  436. package/out/zql/src/builder/builder.js +1 -1
  437. package/out/zql/src/builder/builder.js.map +1 -1
  438. package/out/zql/src/builder/filter.d.ts +0 -1
  439. package/out/zql/src/builder/filter.d.ts.map +1 -1
  440. package/out/zql/src/builder/filter.js.map +1 -1
  441. package/out/zql/src/error.d.ts +0 -5
  442. package/out/zql/src/error.d.ts.map +1 -1
  443. package/out/zql/src/error.js.map +1 -1
  444. package/out/zql/src/ivm/constraint.d.ts +0 -7
  445. package/out/zql/src/ivm/constraint.d.ts.map +1 -1
  446. package/out/zql/src/ivm/constraint.js +1 -1
  447. package/out/zql/src/ivm/constraint.js.map +1 -1
  448. package/out/zql/src/ivm/data.d.ts +0 -1
  449. package/out/zql/src/ivm/data.d.ts.map +1 -1
  450. package/out/zql/src/ivm/data.js.map +1 -1
  451. package/out/zql/src/ivm/memory-source.d.ts +1 -2
  452. package/out/zql/src/ivm/memory-source.d.ts.map +1 -1
  453. package/out/zql/src/ivm/memory-source.js +1 -1
  454. package/out/zql/src/ivm/memory-source.js.map +1 -1
  455. package/out/zql/src/ivm/stream.d.ts +0 -1
  456. package/out/zql/src/ivm/stream.d.ts.map +1 -1
  457. package/out/zql/src/ivm/stream.js.map +1 -1
  458. package/out/zql/src/ivm/union-fan-in.d.ts +0 -1
  459. package/out/zql/src/ivm/union-fan-in.d.ts.map +1 -1
  460. package/out/zql/src/ivm/union-fan-in.js +1 -1
  461. package/out/zql/src/ivm/union-fan-in.js.map +1 -1
  462. package/out/zql/src/ivm/view-apply-change.d.ts +5 -35
  463. package/out/zql/src/ivm/view-apply-change.d.ts.map +1 -1
  464. package/out/zql/src/ivm/view-apply-change.js +1 -1
  465. package/out/zql/src/ivm/view-apply-change.js.map +1 -1
  466. package/out/zql/src/mutate/crud.d.ts +1 -3
  467. package/out/zql/src/mutate/crud.d.ts.map +1 -1
  468. package/out/zql/src/mutate/crud.js +1 -1
  469. package/out/zql/src/mutate/crud.js.map +1 -1
  470. package/out/zql/src/mutate/mutator-registry.d.ts +1 -1
  471. package/out/zql/src/mutate/mutator-registry.d.ts.map +1 -1
  472. package/out/zql/src/mutate/mutator-registry.js.map +1 -1
  473. package/out/zql/src/mutate/mutator.d.ts +1 -1
  474. package/out/zql/src/mutate/mutator.d.ts.map +1 -1
  475. package/out/zql/src/mutate/mutator.js.map +1 -1
  476. package/out/zql/src/planner/planner-debug.d.ts +10 -9
  477. package/out/zql/src/planner/planner-debug.d.ts.map +1 -1
  478. package/out/zql/src/planner/planner-debug.js.map +1 -1
  479. package/out/zql/src/planner/planner-node.d.ts +0 -1
  480. package/out/zql/src/planner/planner-node.d.ts.map +1 -1
  481. package/out/zql/src/planner/planner-node.js.map +1 -1
  482. package/out/zql/src/planner/planner-warnings.d.ts +3 -3
  483. package/out/zql/src/planner/planner-warnings.d.ts.map +1 -1
  484. package/out/zql/src/planner/planner-warnings.js.map +1 -1
  485. package/out/zql/src/query/expression.d.ts +0 -22
  486. package/out/zql/src/query/expression.d.ts.map +1 -1
  487. package/out/zql/src/query/expression.js +1 -1
  488. package/out/zql/src/query/expression.js.map +1 -1
  489. package/out/zql/src/query/query-delegate-base.d.ts +0 -7
  490. package/out/zql/src/query/query-delegate-base.d.ts.map +1 -1
  491. package/out/zql/src/query/query-delegate-base.js +2 -2
  492. package/out/zql/src/query/query-delegate-base.js.map +1 -1
  493. package/out/zql/src/query/query-delegate.d.ts +1 -4
  494. package/out/zql/src/query/query-delegate.d.ts.map +1 -1
  495. package/out/zql/src/query/query-internals.d.ts +0 -3
  496. package/out/zql/src/query/query-internals.d.ts.map +1 -1
  497. package/out/zql/src/query/query-internals.js.map +1 -1
  498. package/out/zql/src/query/query-registry.d.ts +5 -5
  499. package/out/zql/src/query/query-registry.d.ts.map +1 -1
  500. package/out/zql/src/query/query-registry.js.map +1 -1
  501. package/out/zql/src/query/query.d.ts +2 -13
  502. package/out/zql/src/query/query.d.ts.map +1 -1
  503. package/out/zql/src/query/runnable-query-impl.d.ts +1 -19
  504. package/out/zql/src/query/runnable-query-impl.d.ts.map +1 -1
  505. package/out/zql/src/query/runnable-query-impl.js +1 -1
  506. package/out/zql/src/query/runnable-query-impl.js.map +1 -1
  507. package/out/zql/src/query/ttl.d.ts +2 -3
  508. package/out/zql/src/query/ttl.d.ts.map +1 -1
  509. package/out/zql/src/query/ttl.js.map +1 -1
  510. package/out/zqlite/src/query-builder.d.ts +0 -2
  511. package/out/zqlite/src/query-builder.d.ts.map +1 -1
  512. package/out/zqlite/src/query-builder.js +1 -1
  513. package/out/zqlite/src/query-builder.js.map +1 -1
  514. package/out/zqlite/src/table-source.d.ts +0 -1
  515. package/out/zqlite/src/table-source.d.ts.map +1 -1
  516. package/out/zqlite/src/table-source.js +1 -1
  517. package/out/zqlite/src/table-source.js.map +1 -1
  518. package/package.json +2 -3
@@ -1 +1 @@
1
- {"version":3,"file":"planner-debug.js","names":[],"sources":["../../../../../zql/src/planner/planner-debug.ts"],"sourcesContent":["import {newArray} from '../../../shared/src/arrays.ts';\nimport {getOrInsertComputed} from '../../../shared/src/map.ts';\nimport type * as v from '../../../shared/src/valita.ts';\nimport type {\n attemptStartEventJSONSchema,\n bestPlanSelectedEventJSONSchema,\n connectionSelectedEventJSONSchema,\n nodeConstraintEventJSONSchema,\n PlanDebugEventJSON,\n planFailedEventJSONSchema,\n} from '../../../zero-protocol/src/analyze-query-result.ts';\nimport type {\n Condition,\n Ordering,\n ValuePosition,\n} from '../../../zero-protocol/src/ast.ts';\nimport type {PlannerConstraint} from './planner-constraint.ts';\nimport type {PlanState} from './planner-graph.ts';\nimport type {CostEstimate, JoinType} from './planner-node.ts';\n\n/**\n * Structured debug events emitted during query planning.\n * These events can be accumulated, printed, or analyzed to understand\n * the planner's decision-making process.\n */\n\n/**\n * Starting a new planning attempt with a different root connection.\n */\nexport type AttemptStartEvent = v.Infer<typeof attemptStartEventJSONSchema>;\n\n/**\n * Snapshot of connection costs before selecting the next connection.\n */\nexport type ConnectionCostsEvent = {\n type: 'connection-costs';\n attemptNumber: number;\n costs: Array<{\n connection: string;\n cost: number;\n costEstimate: Omit<CostEstimate, 'fanout'>;\n pinned: boolean;\n constraints: Record<string, PlannerConstraint | undefined>;\n constraintCosts: Record<string, Omit<CostEstimate, 'fanout'>>;\n }>;\n};\n\n/**\n * A connection was chosen and pinned.\n */\nexport type ConnectionSelectedEvent = v.Infer<\n typeof connectionSelectedEventJSONSchema\n>;\n\n/**\n * Constraints have been propagated through the graph.\n */\nexport type ConstraintsPropagatedEvent = {\n type: 'constraints-propagated';\n attemptNumber: number;\n connectionConstraints: Array<{\n connection: string;\n constraints: Record<string, PlannerConstraint | undefined>;\n constraintCosts: Record<string, Omit<CostEstimate, 'fanout'>>;\n }>;\n};\n\n/**\n * A complete plan was found for this attempt.\n */\nexport type PlanCompleteEvent = {\n type: 'plan-complete';\n attemptNumber: number;\n totalCost: number;\n flipPattern: number; // Bitmask indicating which joins are flipped\n joinStates: Array<{\n join: string;\n type: JoinType;\n }>;\n // Planning snapshot that can be restored and applied to AST\n planSnapshot: PlanState;\n};\n\n/**\n * Planning attempt failed (e.g., unflippable join).\n */\nexport type PlanFailedEvent = v.Infer<typeof planFailedEventJSONSchema>;\n\n/**\n * The best plan across all attempts was selected.\n */\nexport type BestPlanSelectedEvent = v.Infer<\n typeof bestPlanSelectedEventJSONSchema\n>;\n\n/**\n * A node computed its cost estimate during planning.\n * Emitted by nodes during estimateCost() traversal.\n * attemptNumber is added by the debugger.\n */\nexport type NodeCostEvent = {\n type: 'node-cost';\n attemptNumber?: number;\n nodeType:\n | 'connection'\n | 'join'\n | 'fan-out'\n | 'fan-in'\n | 'filter'\n | 'terminus';\n node: string;\n branchPattern: number[];\n downstreamChildSelectivity: number;\n costEstimate: Omit<CostEstimate, 'fanout'>;\n filters?: Condition | undefined; // Only for connections\n ordering?: Ordering | undefined; // Only for connections\n joinType?: JoinType | undefined; // Only for joins\n};\n\n/**\n * A node received constraints during constraint propagation.\n * Emitted by nodes during propagateConstraints() traversal.\n * attemptNumber is added by the debugger.\n */\nexport type NodeConstraintEvent = v.Infer<typeof nodeConstraintEventJSONSchema>;\n\n/**\n * Union of all debug event types.\n */\nexport type PlanDebugEvent =\n | AttemptStartEvent\n | ConnectionCostsEvent\n | ConnectionSelectedEvent\n | ConstraintsPropagatedEvent\n | PlanCompleteEvent\n | PlanFailedEvent\n | BestPlanSelectedEvent\n | NodeCostEvent\n | NodeConstraintEvent;\n\n/**\n * Interface for objects that receive debug events during planning.\n */\nexport interface PlanDebugger {\n log(event: PlanDebugEvent): void;\n}\n\n/**\n * Simple accumulator debugger that stores all events.\n * Useful for tests and debugging.\n */\nexport class AccumulatorDebugger implements PlanDebugger {\n readonly events: PlanDebugEvent[] = [];\n private currentAttempt = 0;\n\n log(event: PlanDebugEvent): void {\n // Track current attempt number\n if (event.type === 'attempt-start') {\n this.currentAttempt = event.attemptNumber;\n }\n\n // Add attempt number to node events\n if (event.type === 'node-cost' || event.type === 'node-constraint') {\n (event as NodeCostEvent | NodeConstraintEvent).attemptNumber =\n this.currentAttempt;\n }\n\n this.events.push(event);\n }\n\n /**\n * Get all events of a specific type.\n */\n getEvents<T extends PlanDebugEvent['type']>(\n type: T,\n ): Extract<PlanDebugEvent, {type: T}>[] {\n return this.events.filter(e => e.type === type) as Extract<\n PlanDebugEvent,\n {type: T}\n >[];\n }\n\n /**\n * Format events as a human-readable string.\n */\n format(): string {\n return formatPlannerEvents(this.events);\n }\n}\n\n/**\n * Format a constraint object as a human-readable string.\n */\nfunction formatConstraint(\n constraint: PlannerConstraint | Record<string, unknown> | null | undefined,\n): string {\n if (!constraint) return '{}';\n const keys = Object.keys(constraint);\n if (keys.length === 0) return '{}';\n return '{' + keys.join(', ') + '}';\n}\n\n/**\n * Format a ValuePosition (column, literal, or static parameter) as a human-readable string.\n */\nfunction formatValuePosition(value: ValuePosition): string {\n switch (value.type) {\n case 'column':\n return value.name;\n case 'literal':\n // Format literal values with SQL-style quoting for strings\n if (typeof value.value === 'string') {\n return `'${value.value}'`;\n }\n return JSON.stringify(value.value);\n case 'static':\n return `@${value.anchor}.${Array.isArray(value.field) ? value.field.join('.') : value.field}`;\n }\n}\n\n/**\n * Format a Condition (filter) as a human-readable string.\n */\nfunction formatFilter(filter: Condition | undefined): string {\n if (!filter) return 'none';\n\n switch (filter.type) {\n case 'simple':\n return `${formatValuePosition(filter.left)} ${filter.op} ${formatValuePosition(filter.right)}`;\n case 'and':\n return `(${filter.conditions.map(formatFilter).join(' AND ')})`;\n case 'or':\n return `(${filter.conditions.map(formatFilter).join(' OR ')})`;\n case 'correlatedSubquery':\n return `EXISTS(${filter.related.subquery.table})`;\n default:\n return JSON.stringify(filter);\n }\n}\n\n/**\n * Format an Ordering as a human-readable string.\n */\nfunction formatOrdering(ordering: Ordering | undefined): string {\n if (!ordering || ordering.length === 0) return 'none';\n return ordering\n .map(([field, direction]) => `${field} ${direction}`)\n .join(', ');\n}\n\n/**\n * Format a compact summary for a single planning attempt.\n */\nfunction formatAttemptSummary(\n attemptNum: number,\n events: (PlanDebugEvent | PlanDebugEventJSON)[],\n): string[] {\n const lines: string[] = [];\n\n // Find the attempt-start event to get total attempts\n const startEvent = events.find(e => e.type === 'attempt-start') as\n | AttemptStartEvent\n | undefined;\n const totalAttempts = startEvent?.totalAttempts ?? '?';\n\n // Calculate number of bits needed for pattern\n const numBits =\n typeof totalAttempts === 'number'\n ? Math.ceil(Math.log2(totalAttempts)) || 1\n : 1;\n const bitPattern = attemptNum.toString(2).padStart(numBits, '0');\n\n lines.push(\n `[Attempt ${attemptNum + 1}/${totalAttempts}] Pattern ${attemptNum} (${bitPattern})`,\n );\n\n // Collect connection costs (use array to preserve all connections, including duplicates)\n const connectionCostEvents: (\n | NodeCostEvent\n | Extract<PlanDebugEventJSON, {type: 'node-cost'}>\n )[] = [];\n const connectionConstraintEvents: NodeConstraintEvent[] = [];\n\n for (const event of events) {\n if (event.type === 'node-cost' && event.nodeType === 'connection') {\n connectionCostEvents.push(event);\n }\n if (event.type === 'node-constraint' && event.nodeType === 'connection') {\n connectionConstraintEvents.push(event);\n }\n }\n\n // Show connection summary\n if (connectionCostEvents.length > 0) {\n lines.push(' Connections:');\n for (const cost of connectionCostEvents) {\n // Find matching constraint event (same node name and branch pattern)\n const constraint = connectionConstraintEvents.find(\n c =>\n c.node === cost.node &&\n c.branchPattern.join(',') === cost.branchPattern.join(','),\n )?.constraint;\n\n const constraintStr = formatConstraint(constraint);\n const filterStr = formatFilter(cost.filters);\n const orderingStr = formatOrdering(cost.ordering);\n const limitStr =\n cost.costEstimate.limit !== undefined\n ? cost.costEstimate.limit.toString()\n : 'none';\n\n lines.push(` ${cost.node}:`);\n lines.push(\n ` cost=${cost.costEstimate.cost.toFixed(2)}, startup=${cost.costEstimate.startupCost.toFixed(2)}, scan=${cost.costEstimate.scanEst.toFixed(2)}`,\n );\n lines.push(\n ` rows=${cost.costEstimate.returnedRows.toFixed(2)}, selectivity=${cost.costEstimate.selectivity.toFixed(8)}, limit=${limitStr}`,\n );\n lines.push(\n ` downstreamChildSelectivity=${cost.downstreamChildSelectivity.toFixed(8)}`,\n );\n lines.push(` constraints=${constraintStr}`);\n lines.push(` filters=${filterStr}`);\n lines.push(` ordering=${orderingStr}`);\n }\n }\n\n // Collect join costs from node-cost events\n const joinCosts: (\n | NodeCostEvent\n | Extract<PlanDebugEventJSON, {type: 'node-cost'}>\n )[] = [];\n for (const event of events) {\n if (event.type === 'node-cost' && event.nodeType === 'join') {\n joinCosts.push(event);\n }\n }\n\n if (joinCosts.length > 0) {\n lines.push(' Joins:');\n for (const cost of joinCosts) {\n const typeStr = cost.joinType ? ` (${cost.joinType})` : '';\n const limitStr =\n cost.costEstimate.limit !== undefined\n ? cost.costEstimate.limit.toString()\n : 'none';\n\n lines.push(` ${cost.node}${typeStr}:`);\n lines.push(\n ` cost=${cost.costEstimate.cost.toFixed(2)}, startup=${cost.costEstimate.startupCost.toFixed(2)}, scan=${cost.costEstimate.scanEst.toFixed(2)}`,\n );\n lines.push(\n ` rows=${cost.costEstimate.returnedRows.toFixed(2)}, selectivity=${cost.costEstimate.selectivity.toFixed(8)}, limit=${limitStr}`,\n );\n lines.push(\n ` downstreamChildSelectivity=${cost.downstreamChildSelectivity.toFixed(8)}`,\n );\n }\n }\n\n // Find completion/failure events\n const completeEvent = events.find(e => e.type === 'plan-complete') as\n | PlanCompleteEvent\n | undefined;\n const failedEvent = events.find(e => e.type === 'plan-failed') as\n | PlanFailedEvent\n | undefined;\n\n // Show final status\n\n if (completeEvent) {\n lines.push(\n ` ✓ Plan complete: total cost = ${completeEvent.totalCost.toFixed(2)}`,\n );\n } else if (failedEvent) {\n lines.push(` ✗ Plan failed: ${failedEvent.reason}`);\n }\n\n return lines;\n}\n\n/**\n * Convert undefined values to null in a constraint object for JSON serialization.\n * PlannerConstraint uses Record<string, undefined> which loses keys during JSON.stringify.\n */\nfunction convertConstraintUndefinedToNull(\n constraint: PlannerConstraint | Record<string, unknown> | undefined | null,\n): Record<string, unknown> | undefined | null {\n if (constraint === undefined) {\n return undefined;\n }\n if (constraint === null) {\n return null;\n }\n const result: Record<string, unknown> = {};\n for (const [key, val] of Object.entries(constraint)) {\n result[key] = val === undefined ? null : val;\n }\n return result;\n}\n\n/**\n * Serialize a single debug event to JSON-compatible format.\n * The fanout function is already omitted when events are created.\n * The planSnapshot is excluded as it's internal state not needed for debugging.\n * Undefined values in constraints are converted to null for JSON serialization.\n */\nfunction serializeEvent(event: PlanDebugEvent): PlanDebugEventJSON {\n // Remove planSnapshot from plan-complete events\n if (event.type === 'plan-complete') {\n const {planSnapshot: _, ...rest} = event;\n return rest as PlanDebugEventJSON;\n }\n\n // Convert constraint undefined values to null for specific event types\n if (event.type === 'node-constraint') {\n return {\n ...event,\n constraint: convertConstraintUndefinedToNull(event.constraint),\n } as PlanDebugEventJSON;\n }\n\n if (event.type === 'connection-costs') {\n return {\n ...event,\n costs: event.costs.map(cost => ({\n ...cost,\n constraints: Object.fromEntries(\n Object.entries(cost.constraints).map(([key, val]) => [\n key,\n convertConstraintUndefinedToNull(val),\n ]),\n ),\n })),\n } as PlanDebugEventJSON;\n }\n\n if (event.type === 'constraints-propagated') {\n return {\n ...event,\n connectionConstraints: event.connectionConstraints.map(cc => ({\n ...cc,\n constraints: Object.fromEntries(\n Object.entries(cc.constraints).map(([key, val]) => [\n key,\n convertConstraintUndefinedToNull(val),\n ]),\n ),\n })),\n } as PlanDebugEventJSON;\n }\n\n return event as PlanDebugEventJSON;\n}\n\n/**\n * Serialize an array of debug events to JSON-compatible format.\n * The fanout function is already omitted when events are created.\n * The planSnapshot is excluded as it's internal state not needed for debugging.\n */\nexport function serializePlanDebugEvents(\n events: PlanDebugEvent[],\n): PlanDebugEventJSON[] {\n return events.map(serializeEvent);\n}\n\n/**\n * Format planner debug events as a human-readable string.\n * Works with JSON-serialized events (from inspector API) or native events (from AccumulatorDebugger).\n *\n * @param events - Array of planner debug events (either JSON or native format)\n * @returns Formatted string showing planning attempts, costs, and final plan selection\n *\n * @example\n * ```typescript\n * const result = await inspector.analyzeQuery(query, { joinPlans: true });\n * if (result.joinPlans) {\n * console.log(formatPlannerEvents(result.joinPlans));\n * }\n * ```\n */\nexport function formatPlannerEvents(\n events: PlanDebugEventJSON[] | PlanDebugEvent[],\n): string {\n const lines: string[] = [];\n\n // Group events by attempt\n const eventsByAttempt = new Map<\n number,\n (PlanDebugEventJSON | PlanDebugEvent)[]\n >();\n let bestPlanEvent:\n | {\n type: 'best-plan-selected';\n bestAttemptNumber: number;\n totalCost: number;\n flipPattern: number;\n joinStates: Array<{join: string; type: string}>;\n }\n | undefined;\n\n for (const event of events) {\n if ('attemptNumber' in event) {\n const attempt = event.attemptNumber;\n if (attempt !== undefined) {\n getOrInsertComputed(eventsByAttempt, attempt, newArray).push(event);\n }\n } else if (event.type === 'best-plan-selected') {\n // Save for displaying at the end\n bestPlanEvent = event;\n }\n }\n\n // Format each attempt as a compact summary\n for (const [attemptNum, events] of eventsByAttempt.entries()) {\n lines.push(...formatAttemptSummary(attemptNum, events));\n lines.push(''); // Blank line between attempts\n }\n\n // Show the final plan selection\n if (bestPlanEvent) {\n lines.push('─'.repeat(60));\n lines.push(\n `✓ Best plan: Attempt ${bestPlanEvent.bestAttemptNumber + 1} (cost=${bestPlanEvent.totalCost.toFixed(2)})`,\n );\n if (bestPlanEvent.joinStates.length > 0) {\n lines.push(' Join types:');\n for (const j of bestPlanEvent.joinStates) {\n lines.push(` ${j.join}: ${j.type}`);\n }\n }\n lines.push('─'.repeat(60));\n }\n\n return lines.join('\\n');\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"planner-debug.js","names":[],"sources":["../../../../../zql/src/planner/planner-debug.ts"],"sourcesContent":["import {newArray} from '../../../shared/src/arrays.ts';\nimport {getOrInsertComputed} from '../../../shared/src/map.ts';\nimport type * as v from '../../../shared/src/valita.ts';\nimport type {\n attemptStartEventJSONSchema,\n bestPlanSelectedEventJSONSchema,\n connectionSelectedEventJSONSchema,\n nodeConstraintEventJSONSchema,\n PlanDebugEventJSON,\n planFailedEventJSONSchema,\n} from '../../../zero-protocol/src/analyze-query-result.ts';\nimport type {\n Condition,\n Ordering,\n ValuePosition,\n} from '../../../zero-protocol/src/ast.ts';\nimport type {PlannerConstraint} from './planner-constraint.ts';\nimport type {PlanState} from './planner-graph.ts';\nimport type {CostEstimate, JoinType} from './planner-node.ts';\n\n/**\n * Structured debug events emitted during query planning.\n * These events can be accumulated, printed, or analyzed to understand\n * the planner's decision-making process.\n */\n\n/**\n * Starting a new planning attempt with a different root connection.\n */\ntype AttemptStartEvent = v.Infer<typeof attemptStartEventJSONSchema>;\n\n/**\n * Snapshot of connection costs before selecting the next connection.\n */\ntype ConnectionCostsEvent = {\n type: 'connection-costs';\n attemptNumber: number;\n costs: Array<{\n connection: string;\n cost: number;\n costEstimate: Omit<CostEstimate, 'fanout'>;\n pinned: boolean;\n constraints: Record<string, PlannerConstraint | undefined>;\n constraintCosts: Record<string, Omit<CostEstimate, 'fanout'>>;\n }>;\n};\n\n/**\n * A connection was chosen and pinned.\n */\ntype ConnectionSelectedEvent = v.Infer<\n typeof connectionSelectedEventJSONSchema\n>;\n\n/**\n * Constraints have been propagated through the graph.\n */\ntype ConstraintsPropagatedEvent = {\n type: 'constraints-propagated';\n attemptNumber: number;\n connectionConstraints: Array<{\n connection: string;\n constraints: Record<string, PlannerConstraint | undefined>;\n constraintCosts: Record<string, Omit<CostEstimate, 'fanout'>>;\n }>;\n};\n\n/**\n * A complete plan was found for this attempt.\n */\ntype PlanCompleteEvent = {\n type: 'plan-complete';\n attemptNumber: number;\n totalCost: number;\n flipPattern: number; // Bitmask indicating which joins are flipped\n joinStates: Array<{\n join: string;\n type: JoinType;\n }>;\n // Planning snapshot that can be restored and applied to AST\n planSnapshot: PlanState;\n};\n\n/**\n * Planning attempt failed (e.g., unflippable join).\n */\ntype PlanFailedEvent = v.Infer<typeof planFailedEventJSONSchema>;\n\n/**\n * The best plan across all attempts was selected.\n */\ntype BestPlanSelectedEvent = v.Infer<typeof bestPlanSelectedEventJSONSchema>;\n\n/**\n * A node computed its cost estimate during planning.\n * Emitted by nodes during estimateCost() traversal.\n * attemptNumber is added by the debugger.\n */\ntype NodeCostEvent = {\n type: 'node-cost';\n attemptNumber?: number;\n nodeType:\n | 'connection'\n | 'join'\n | 'fan-out'\n | 'fan-in'\n | 'filter'\n | 'terminus';\n node: string;\n branchPattern: number[];\n downstreamChildSelectivity: number;\n costEstimate: Omit<CostEstimate, 'fanout'>;\n filters?: Condition | undefined; // Only for connections\n ordering?: Ordering | undefined; // Only for connections\n joinType?: JoinType | undefined; // Only for joins\n};\n\n/**\n * A node received constraints during constraint propagation.\n * Emitted by nodes during propagateConstraints() traversal.\n * attemptNumber is added by the debugger.\n */\ntype NodeConstraintEvent = v.Infer<typeof nodeConstraintEventJSONSchema>;\n\n/**\n * Union of all debug event types.\n */\nexport type PlanDebugEvent =\n | AttemptStartEvent\n | ConnectionCostsEvent\n | ConnectionSelectedEvent\n | ConstraintsPropagatedEvent\n | PlanCompleteEvent\n | PlanFailedEvent\n | BestPlanSelectedEvent\n | NodeCostEvent\n | NodeConstraintEvent;\n\n/**\n * Interface for objects that receive debug events during planning.\n */\nexport interface PlanDebugger {\n log(event: PlanDebugEvent): void;\n}\n\n/**\n * Simple accumulator debugger that stores all events.\n * Useful for tests and debugging.\n */\nexport class AccumulatorDebugger implements PlanDebugger {\n readonly events: PlanDebugEvent[] = [];\n private currentAttempt = 0;\n\n log(event: PlanDebugEvent): void {\n // Track current attempt number\n if (event.type === 'attempt-start') {\n this.currentAttempt = event.attemptNumber;\n }\n\n // Add attempt number to node events\n if (event.type === 'node-cost' || event.type === 'node-constraint') {\n (event as NodeCostEvent | NodeConstraintEvent).attemptNumber =\n this.currentAttempt;\n }\n\n this.events.push(event);\n }\n\n /**\n * Get all events of a specific type.\n */\n getEvents<T extends PlanDebugEvent['type']>(\n type: T,\n ): Extract<PlanDebugEvent, {type: T}>[] {\n return this.events.filter(e => e.type === type) as Extract<\n PlanDebugEvent,\n {type: T}\n >[];\n }\n\n /**\n * Format events as a human-readable string.\n */\n format(): string {\n return formatPlannerEvents(this.events);\n }\n}\n\n/**\n * Format a constraint object as a human-readable string.\n */\nfunction formatConstraint(\n constraint: PlannerConstraint | Record<string, unknown> | null | undefined,\n): string {\n if (!constraint) return '{}';\n const keys = Object.keys(constraint);\n if (keys.length === 0) return '{}';\n return '{' + keys.join(', ') + '}';\n}\n\n/**\n * Format a ValuePosition (column, literal, or static parameter) as a human-readable string.\n */\nfunction formatValuePosition(value: ValuePosition): string {\n switch (value.type) {\n case 'column':\n return value.name;\n case 'literal':\n // Format literal values with SQL-style quoting for strings\n if (typeof value.value === 'string') {\n return `'${value.value}'`;\n }\n return JSON.stringify(value.value);\n case 'static':\n return `@${value.anchor}.${Array.isArray(value.field) ? value.field.join('.') : value.field}`;\n }\n}\n\n/**\n * Format a Condition (filter) as a human-readable string.\n */\nfunction formatFilter(filter: Condition | undefined): string {\n if (!filter) return 'none';\n\n switch (filter.type) {\n case 'simple':\n return `${formatValuePosition(filter.left)} ${filter.op} ${formatValuePosition(filter.right)}`;\n case 'and':\n return `(${filter.conditions.map(formatFilter).join(' AND ')})`;\n case 'or':\n return `(${filter.conditions.map(formatFilter).join(' OR ')})`;\n case 'correlatedSubquery':\n return `EXISTS(${filter.related.subquery.table})`;\n default:\n return JSON.stringify(filter);\n }\n}\n\n/**\n * Format an Ordering as a human-readable string.\n */\nfunction formatOrdering(ordering: Ordering | undefined): string {\n if (!ordering || ordering.length === 0) return 'none';\n return ordering\n .map(([field, direction]) => `${field} ${direction}`)\n .join(', ');\n}\n\n/**\n * Format a compact summary for a single planning attempt.\n */\nfunction formatAttemptSummary(\n attemptNum: number,\n events: (PlanDebugEvent | PlanDebugEventJSON)[],\n): string[] {\n const lines: string[] = [];\n\n // Find the attempt-start event to get total attempts\n const startEvent = events.find(e => e.type === 'attempt-start') as\n | AttemptStartEvent\n | undefined;\n const totalAttempts = startEvent?.totalAttempts ?? '?';\n\n // Calculate number of bits needed for pattern\n const numBits =\n typeof totalAttempts === 'number'\n ? Math.ceil(Math.log2(totalAttempts)) || 1\n : 1;\n const bitPattern = attemptNum.toString(2).padStart(numBits, '0');\n\n lines.push(\n `[Attempt ${attemptNum + 1}/${totalAttempts}] Pattern ${attemptNum} (${bitPattern})`,\n );\n\n // Collect connection costs (use array to preserve all connections, including duplicates)\n const connectionCostEvents: (\n | NodeCostEvent\n | Extract<PlanDebugEventJSON, {type: 'node-cost'}>\n )[] = [];\n const connectionConstraintEvents: NodeConstraintEvent[] = [];\n\n for (const event of events) {\n if (event.type === 'node-cost' && event.nodeType === 'connection') {\n connectionCostEvents.push(event);\n }\n if (event.type === 'node-constraint' && event.nodeType === 'connection') {\n connectionConstraintEvents.push(event);\n }\n }\n\n // Show connection summary\n if (connectionCostEvents.length > 0) {\n lines.push(' Connections:');\n for (const cost of connectionCostEvents) {\n // Find matching constraint event (same node name and branch pattern)\n const constraint = connectionConstraintEvents.find(\n c =>\n c.node === cost.node &&\n c.branchPattern.join(',') === cost.branchPattern.join(','),\n )?.constraint;\n\n const constraintStr = formatConstraint(constraint);\n const filterStr = formatFilter(cost.filters);\n const orderingStr = formatOrdering(cost.ordering);\n const limitStr =\n cost.costEstimate.limit !== undefined\n ? cost.costEstimate.limit.toString()\n : 'none';\n\n lines.push(` ${cost.node}:`);\n lines.push(\n ` cost=${cost.costEstimate.cost.toFixed(2)}, startup=${cost.costEstimate.startupCost.toFixed(2)}, scan=${cost.costEstimate.scanEst.toFixed(2)}`,\n );\n lines.push(\n ` rows=${cost.costEstimate.returnedRows.toFixed(2)}, selectivity=${cost.costEstimate.selectivity.toFixed(8)}, limit=${limitStr}`,\n );\n lines.push(\n ` downstreamChildSelectivity=${cost.downstreamChildSelectivity.toFixed(8)}`,\n );\n lines.push(` constraints=${constraintStr}`);\n lines.push(` filters=${filterStr}`);\n lines.push(` ordering=${orderingStr}`);\n }\n }\n\n // Collect join costs from node-cost events\n const joinCosts: (\n | NodeCostEvent\n | Extract<PlanDebugEventJSON, {type: 'node-cost'}>\n )[] = [];\n for (const event of events) {\n if (event.type === 'node-cost' && event.nodeType === 'join') {\n joinCosts.push(event);\n }\n }\n\n if (joinCosts.length > 0) {\n lines.push(' Joins:');\n for (const cost of joinCosts) {\n const typeStr = cost.joinType ? ` (${cost.joinType})` : '';\n const limitStr =\n cost.costEstimate.limit !== undefined\n ? cost.costEstimate.limit.toString()\n : 'none';\n\n lines.push(` ${cost.node}${typeStr}:`);\n lines.push(\n ` cost=${cost.costEstimate.cost.toFixed(2)}, startup=${cost.costEstimate.startupCost.toFixed(2)}, scan=${cost.costEstimate.scanEst.toFixed(2)}`,\n );\n lines.push(\n ` rows=${cost.costEstimate.returnedRows.toFixed(2)}, selectivity=${cost.costEstimate.selectivity.toFixed(8)}, limit=${limitStr}`,\n );\n lines.push(\n ` downstreamChildSelectivity=${cost.downstreamChildSelectivity.toFixed(8)}`,\n );\n }\n }\n\n // Find completion/failure events\n const completeEvent = events.find(e => e.type === 'plan-complete') as\n | PlanCompleteEvent\n | undefined;\n const failedEvent = events.find(e => e.type === 'plan-failed') as\n | PlanFailedEvent\n | undefined;\n\n // Show final status\n\n if (completeEvent) {\n lines.push(\n ` ✓ Plan complete: total cost = ${completeEvent.totalCost.toFixed(2)}`,\n );\n } else if (failedEvent) {\n lines.push(` ✗ Plan failed: ${failedEvent.reason}`);\n }\n\n return lines;\n}\n\n/**\n * Convert undefined values to null in a constraint object for JSON serialization.\n * PlannerConstraint uses Record<string, undefined> which loses keys during JSON.stringify.\n */\nfunction convertConstraintUndefinedToNull(\n constraint: PlannerConstraint | Record<string, unknown> | undefined | null,\n): Record<string, unknown> | undefined | null {\n if (constraint === undefined) {\n return undefined;\n }\n if (constraint === null) {\n return null;\n }\n const result: Record<string, unknown> = {};\n for (const [key, val] of Object.entries(constraint)) {\n result[key] = val === undefined ? null : val;\n }\n return result;\n}\n\n/**\n * Serialize a single debug event to JSON-compatible format.\n * The fanout function is already omitted when events are created.\n * The planSnapshot is excluded as it's internal state not needed for debugging.\n * Undefined values in constraints are converted to null for JSON serialization.\n */\nfunction serializeEvent(event: PlanDebugEvent): PlanDebugEventJSON {\n // Remove planSnapshot from plan-complete events\n if (event.type === 'plan-complete') {\n const {planSnapshot: _, ...rest} = event;\n return rest as PlanDebugEventJSON;\n }\n\n // Convert constraint undefined values to null for specific event types\n if (event.type === 'node-constraint') {\n return {\n ...event,\n constraint: convertConstraintUndefinedToNull(event.constraint),\n } as PlanDebugEventJSON;\n }\n\n if (event.type === 'connection-costs') {\n return {\n ...event,\n costs: event.costs.map(cost => ({\n ...cost,\n constraints: Object.fromEntries(\n Object.entries(cost.constraints).map(([key, val]) => [\n key,\n convertConstraintUndefinedToNull(val),\n ]),\n ),\n })),\n } as PlanDebugEventJSON;\n }\n\n if (event.type === 'constraints-propagated') {\n return {\n ...event,\n connectionConstraints: event.connectionConstraints.map(cc => ({\n ...cc,\n constraints: Object.fromEntries(\n Object.entries(cc.constraints).map(([key, val]) => [\n key,\n convertConstraintUndefinedToNull(val),\n ]),\n ),\n })),\n } as PlanDebugEventJSON;\n }\n\n return event as PlanDebugEventJSON;\n}\n\n/**\n * Serialize an array of debug events to JSON-compatible format.\n * The fanout function is already omitted when events are created.\n * The planSnapshot is excluded as it's internal state not needed for debugging.\n */\nexport function serializePlanDebugEvents(\n events: PlanDebugEvent[],\n): PlanDebugEventJSON[] {\n return events.map(serializeEvent);\n}\n\n/**\n * Format planner debug events as a human-readable string.\n * Works with JSON-serialized events (from inspector API) or native events (from AccumulatorDebugger).\n *\n * @param events - Array of planner debug events (either JSON or native format)\n * @returns Formatted string showing planning attempts, costs, and final plan selection\n *\n * @example\n * ```typescript\n * const result = await inspector.analyzeQuery(query, { joinPlans: true });\n * if (result.joinPlans) {\n * console.log(formatPlannerEvents(result.joinPlans));\n * }\n * ```\n */\nexport function formatPlannerEvents(\n events: PlanDebugEventJSON[] | PlanDebugEvent[],\n): string {\n const lines: string[] = [];\n\n // Group events by attempt\n const eventsByAttempt = new Map<\n number,\n (PlanDebugEventJSON | PlanDebugEvent)[]\n >();\n let bestPlanEvent:\n | {\n type: 'best-plan-selected';\n bestAttemptNumber: number;\n totalCost: number;\n flipPattern: number;\n joinStates: Array<{join: string; type: string}>;\n }\n | undefined;\n\n for (const event of events) {\n if ('attemptNumber' in event) {\n const attempt = event.attemptNumber;\n if (attempt !== undefined) {\n getOrInsertComputed(eventsByAttempt, attempt, newArray).push(event);\n }\n } else if (event.type === 'best-plan-selected') {\n // Save for displaying at the end\n bestPlanEvent = event;\n }\n }\n\n // Format each attempt as a compact summary\n for (const [attemptNum, events] of eventsByAttempt.entries()) {\n lines.push(...formatAttemptSummary(attemptNum, events));\n lines.push(''); // Blank line between attempts\n }\n\n // Show the final plan selection\n if (bestPlanEvent) {\n lines.push('─'.repeat(60));\n lines.push(\n `✓ Best plan: Attempt ${bestPlanEvent.bestAttemptNumber + 1} (cost=${bestPlanEvent.totalCost.toFixed(2)})`,\n );\n if (bestPlanEvent.joinStates.length > 0) {\n lines.push(' Join types:');\n for (const j of bestPlanEvent.joinStates) {\n lines.push(` ${j.join}: ${j.type}`);\n }\n }\n lines.push('─'.repeat(60));\n }\n\n return lines.join('\\n');\n}\n"],"mappings":"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"}
@@ -48,7 +48,6 @@ export type CostEstimate = {
48
48
  * Omit the fanout function from a cost estimate for serialization.
49
49
  */
50
50
  export declare function omitFanout(cost: CostEstimate): Omit<CostEstimate, 'fanout'>;
51
- export type NodeType = PlannerNode['kind'];
52
51
  export type JoinOrConnection = 'join' | 'connection';
53
52
  export type JoinType = PlannerJoin['type'];
54
53
  //# sourceMappingURL=planner-node.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"planner-node.d.ts","sourceRoot":"","sources":["../../../../../zql/src/planner/planner-node.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,eAAe,EAAE,iBAAiB,EAAC,MAAM,yBAAyB,CAAC;AAChF,OAAO,KAAK,EAAC,YAAY,EAAC,MAAM,qBAAqB,CAAC;AACtD,OAAO,KAAK,EAAC,aAAa,EAAC,MAAM,sBAAsB,CAAC;AACxD,OAAO,KAAK,EAAC,aAAa,EAAC,MAAM,qBAAqB,CAAC;AACvD,OAAO,KAAK,EAAC,WAAW,EAAC,MAAM,mBAAmB,CAAC;AACnD,OAAO,KAAK,EAAC,eAAe,EAAC,MAAM,uBAAuB,CAAC;AAE3D;;;GAGG;AACH,MAAM,MAAM,WAAW,GACnB,WAAW,GACX,iBAAiB,GACjB,aAAa,GACb,YAAY,GACZ,aAAa,GACb,eAAe,CAAC;AAEpB,MAAM,MAAM,YAAY,GAAG;IACzB,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAEhB;;;;;;;;;;OAUG;IACH,IAAI,EAAE,MAAM,CAAC;IAEb;;;;;;;OAOG;IACH,YAAY,EAAE,MAAM,CAAC;IAErB;;;;;;OAMG;IACH,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,MAAM,GAAG,SAAS,CAAC;IAE1B,MAAM,EAAE,eAAe,CAAC;CACzB,CAAC;AAEF;;GAEG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,YAAY,GAAG,IAAI,CAAC,YAAY,EAAE,QAAQ,CAAC,CAG3E;AAED,MAAM,MAAM,QAAQ,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC;AAE3C,MAAM,MAAM,gBAAgB,GAAG,MAAM,GAAG,YAAY,CAAC;AAErD,MAAM,MAAM,QAAQ,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC"}
1
+ {"version":3,"file":"planner-node.d.ts","sourceRoot":"","sources":["../../../../../zql/src/planner/planner-node.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,eAAe,EAAE,iBAAiB,EAAC,MAAM,yBAAyB,CAAC;AAChF,OAAO,KAAK,EAAC,YAAY,EAAC,MAAM,qBAAqB,CAAC;AACtD,OAAO,KAAK,EAAC,aAAa,EAAC,MAAM,sBAAsB,CAAC;AACxD,OAAO,KAAK,EAAC,aAAa,EAAC,MAAM,qBAAqB,CAAC;AACvD,OAAO,KAAK,EAAC,WAAW,EAAC,MAAM,mBAAmB,CAAC;AACnD,OAAO,KAAK,EAAC,eAAe,EAAC,MAAM,uBAAuB,CAAC;AAE3D;;;GAGG;AACH,MAAM,MAAM,WAAW,GACnB,WAAW,GACX,iBAAiB,GACjB,aAAa,GACb,YAAY,GACZ,aAAa,GACb,eAAe,CAAC;AAEpB,MAAM,MAAM,YAAY,GAAG;IACzB,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAEhB;;;;;;;;;;OAUG;IACH,IAAI,EAAE,MAAM,CAAC;IAEb;;;;;;;OAOG;IACH,YAAY,EAAE,MAAM,CAAC;IAErB;;;;;;OAMG;IACH,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,MAAM,GAAG,SAAS,CAAC;IAE1B,MAAM,EAAE,eAAe,CAAC;CACzB,CAAC;AAEF;;GAEG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,YAAY,GAAG,IAAI,CAAC,YAAY,EAAE,QAAQ,CAAC,CAG3E;AAED,MAAM,MAAM,gBAAgB,GAAG,MAAM,GAAG,YAAY,CAAC;AAErD,MAAM,MAAM,QAAQ,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"planner-node.js","names":[],"sources":["../../../../../zql/src/planner/planner-node.ts"],"sourcesContent":["import type {FanoutCostModel, PlannerConnection} from './planner-connection.ts';\nimport type {PlannerFanIn} from './planner-fan-in.ts';\nimport type {PlannerFanOut} from './planner-fan-out.ts';\nimport type {PlannerFilter} from './planner-filter.ts';\nimport type {PlannerJoin} from './planner-join.ts';\nimport type {PlannerTerminus} from './planner-terminus.ts';\n\n/**\n * Union of all node types that can appear in the planner graph.\n * All nodes follow the dual-state pattern described above.\n */\nexport type PlannerNode =\n | PlannerJoin\n | PlannerConnection\n | PlannerFanOut\n | PlannerFanIn\n | PlannerFilter\n | PlannerTerminus;\n\nexport type CostEstimate = {\n startupCost: number;\n scanEst: number;\n\n /**\n * The cumulative cost to run the pipeline so far.\n *\n * In a semi-join, each row output by the parent is multiplied by the cost to evaluate the child.\n * In a flipped join, each row output by the child is multiplied by the cost to evaluate the parent.\n *\n * \"each row output by the parent\" is determined by the downstreamChildSelectivity parameter in combination\n * with the limit or the rows output by the parent node.\n *\n * We pull on the parent and stop when hitting a limit or exhausting rows.\n */\n cost: number;\n\n /**\n * The number of rows output from a node.\n * - For a connection, this is the estimated number of rows returned by the source query.\n * - For a semi-join, this is the estimated number of rows that pass the semi-join filter.\n * - For a flipped join, this is the estimated number of rows that match all child rows.\n * - For fan-in, this is the sum of the rows from each input.\n * - For fan-out, this is the rows from its input.\n */\n returnedRows: number;\n\n /**\n * The selectivity of the node.\n * For a connection, this is the fraction of rows passing filters (1.0 = no filtering).\n * For joins, this is the fraction of parent rows that match child rows.\n * For fan-in, this is the probability of a match in any branch, assuming independent events.\n * For fan-out, this is the selectivity of its input.\n */\n selectivity: number;\n limit: number | undefined;\n\n fanout: FanoutCostModel;\n};\n\n/**\n * Omit the fanout function from a cost estimate for serialization.\n */\nexport function omitFanout(cost: CostEstimate): Omit<CostEstimate, 'fanout'> {\n const {fanout: _, ...rest} = cost;\n return rest;\n}\n\nexport type NodeType = PlannerNode['kind'];\n\nexport type JoinOrConnection = 'join' | 'connection';\n\nexport type JoinType = PlannerJoin['type'];\n"],"mappings":";;;;AA8DA,SAAgB,WAAW,MAAkD;CAC3E,MAAM,EAAC,QAAQ,GAAG,GAAG,SAAQ;CAC7B,OAAO;AACT"}
1
+ {"version":3,"file":"planner-node.js","names":[],"sources":["../../../../../zql/src/planner/planner-node.ts"],"sourcesContent":["import type {FanoutCostModel, PlannerConnection} from './planner-connection.ts';\nimport type {PlannerFanIn} from './planner-fan-in.ts';\nimport type {PlannerFanOut} from './planner-fan-out.ts';\nimport type {PlannerFilter} from './planner-filter.ts';\nimport type {PlannerJoin} from './planner-join.ts';\nimport type {PlannerTerminus} from './planner-terminus.ts';\n\n/**\n * Union of all node types that can appear in the planner graph.\n * All nodes follow the dual-state pattern described above.\n */\nexport type PlannerNode =\n | PlannerJoin\n | PlannerConnection\n | PlannerFanOut\n | PlannerFanIn\n | PlannerFilter\n | PlannerTerminus;\n\nexport type CostEstimate = {\n startupCost: number;\n scanEst: number;\n\n /**\n * The cumulative cost to run the pipeline so far.\n *\n * In a semi-join, each row output by the parent is multiplied by the cost to evaluate the child.\n * In a flipped join, each row output by the child is multiplied by the cost to evaluate the parent.\n *\n * \"each row output by the parent\" is determined by the downstreamChildSelectivity parameter in combination\n * with the limit or the rows output by the parent node.\n *\n * We pull on the parent and stop when hitting a limit or exhausting rows.\n */\n cost: number;\n\n /**\n * The number of rows output from a node.\n * - For a connection, this is the estimated number of rows returned by the source query.\n * - For a semi-join, this is the estimated number of rows that pass the semi-join filter.\n * - For a flipped join, this is the estimated number of rows that match all child rows.\n * - For fan-in, this is the sum of the rows from each input.\n * - For fan-out, this is the rows from its input.\n */\n returnedRows: number;\n\n /**\n * The selectivity of the node.\n * For a connection, this is the fraction of rows passing filters (1.0 = no filtering).\n * For joins, this is the fraction of parent rows that match child rows.\n * For fan-in, this is the probability of a match in any branch, assuming independent events.\n * For fan-out, this is the selectivity of its input.\n */\n selectivity: number;\n limit: number | undefined;\n\n fanout: FanoutCostModel;\n};\n\n/**\n * Omit the fanout function from a cost estimate for serialization.\n */\nexport function omitFanout(cost: CostEstimate): Omit<CostEstimate, 'fanout'> {\n const {fanout: _, ...rest} = cost;\n return rest;\n}\n\nexport type JoinOrConnection = 'join' | 'connection';\n\nexport type JoinType = PlannerJoin['type'];\n"],"mappings":";;;;AA8DA,SAAgB,WAAW,MAAkD;CAC3E,MAAM,EAAC,QAAQ,GAAG,GAAG,SAAQ;CAC7B,OAAO;AACT"}
@@ -39,7 +39,7 @@ type TableRead = {
39
39
  * read scans the whole table. This is typically a relationship whose foreign
40
40
  * key is not indexed.
41
41
  */
42
- export type MissingIndexWarning = TableRead & {
42
+ type MissingIndexWarning = TableRead & {
43
43
  readonly type: 'missing-index';
44
44
  /**
45
45
  * The columns the rows are found by: the columns a join binds and the
@@ -54,7 +54,7 @@ export type MissingIndexWarning = TableRead & {
54
54
  * sorts all of the matching rows before returning the first one. A limit does
55
55
  * not reduce the rows read.
56
56
  */
57
- export type FullSortWarning = TableRead & {
57
+ type FullSortWarning = TableRead & {
58
58
  readonly type: 'full-sort';
59
59
  readonly orderBy: Ordering;
60
60
  /** The estimated number of rows each read sorts. */
@@ -65,7 +65,7 @@ export type FullSortWarning = TableRead & {
65
65
  * rows. Only reported when every table the query reads has statistics, since
66
66
  * the estimates are guesses otherwise.
67
67
  */
68
- export type HighCostWarning = {
68
+ type HighCostWarning = {
69
69
  readonly type: 'high-cost';
70
70
  readonly table: string;
71
71
  /** The estimated number of rows the plan processes. */
@@ -1 +1 @@
1
- {"version":3,"file":"planner-warnings.d.ts","sourceRoot":"","sources":["../../../../../zql/src/planner/planner-warnings.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAY,QAAQ,EAAC,MAAM,mCAAmC,CAAC;AAC3E,OAAO,KAAK,EAAC,KAAK,EAAC,MAAM,sBAAsB,CAAC;AAOhD;;;GAGG;AACH,MAAM,MAAM,qBAAqB,GAAG;IAClC;;;OAGG;IACH,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAEtB;;;OAGG;IACH,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB,CAAC;AAEF,KAAK,SAAS,GAAG;IACf,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IAEvB;;;OAGG;IACH,QAAQ,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,CAAC;IAEjC;;;OAGG;IACH,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IAEzB;;;OAGG;IACH,QAAQ,CAAC,cAAc,EAAE,SAAS,MAAM,EAAE,CAAC;CAC5C,CAAC;AAEF;;;;GAIG;AACH,MAAM,MAAM,mBAAmB,GAAG,SAAS,GAAG;IAC5C,QAAQ,CAAC,IAAI,EAAE,eAAe,CAAC;IAC/B;;;OAGG;IACH,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;IACpC,gCAAgC;IAChC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB,CAAC;AAEF;;;;GAIG;AACH,MAAM,MAAM,eAAe,GAAG,SAAS,GAAG;IACxC,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAC;IAC3B,QAAQ,CAAC,OAAO,EAAE,QAAQ,CAAC;IAC3B,oDAAoD;IACpD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB,CAAC;AAEF;;;;GAIG;AACH,MAAM,MAAM,eAAe,GAAG;IAC5B,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAC;IAC3B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,uDAAuD;IACvD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB,CAAC;AAEF,MAAM,MAAM,WAAW,GACnB,mBAAmB,GACnB,eAAe,GACf,eAAe,CAAC;AAEpB;;;;;GAKG;AACH,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,KAAK,EACZ,UAAU,EAAE,qBAAqB,GAChC,WAAW,EAAE,CASf"}
1
+ {"version":3,"file":"planner-warnings.d.ts","sourceRoot":"","sources":["../../../../../zql/src/planner/planner-warnings.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAY,QAAQ,EAAC,MAAM,mCAAmC,CAAC;AAC3E,OAAO,KAAK,EAAC,KAAK,EAAC,MAAM,sBAAsB,CAAC;AAOhD;;;GAGG;AACH,MAAM,MAAM,qBAAqB,GAAG;IAClC;;;OAGG;IACH,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAEtB;;;OAGG;IACH,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB,CAAC;AAEF,KAAK,SAAS,GAAG;IACf,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IAEvB;;;OAGG;IACH,QAAQ,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,CAAC;IAEjC;;;OAGG;IACH,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IAEzB;;;OAGG;IACH,QAAQ,CAAC,cAAc,EAAE,SAAS,MAAM,EAAE,CAAC;CAC5C,CAAC;AAEF;;;;GAIG;AACH,KAAK,mBAAmB,GAAG,SAAS,GAAG;IACrC,QAAQ,CAAC,IAAI,EAAE,eAAe,CAAC;IAC/B;;;OAGG;IACH,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;IACpC,gCAAgC;IAChC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB,CAAC;AAEF;;;;GAIG;AACH,KAAK,eAAe,GAAG,SAAS,GAAG;IACjC,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAC;IAC3B,QAAQ,CAAC,OAAO,EAAE,QAAQ,CAAC;IAC3B,oDAAoD;IACpD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB,CAAC;AAEF;;;;GAIG;AACH,KAAK,eAAe,GAAG;IACrB,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAC;IAC3B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,uDAAuD;IACvD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB,CAAC;AAEF,MAAM,MAAM,WAAW,GACnB,mBAAmB,GACnB,eAAe,GACf,eAAe,CAAC;AAEpB;;;;;GAKG;AACH,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,KAAK,EACZ,UAAU,EAAE,qBAAqB,GAChC,WAAW,EAAE,CASf"}
@@ -1 +1 @@
1
- {"version":3,"file":"planner-warnings.js","names":[],"sources":["../../../../../zql/src/planner/planner-warnings.ts"],"sourcesContent":["import type {Condition, Ordering} from '../../../zero-protocol/src/ast.ts';\nimport type {Plans} from './planner-builder.ts';\nimport type {\n AccessPlan,\n ConnectionAccess,\n PlannerConnection,\n} from './planner-connection.ts';\n\n/**\n * When the planner reports a {@link PlanWarning}. Each threshold is compared\n * against the cost model's estimates, and 0 disables the warnings it gates.\n */\nexport type PlanWarningThresholds = {\n /**\n * The number of rows a single read of a table must scan (for a\n * {@link MissingIndexWarning}) or sort (for a {@link FullSortWarning}).\n */\n readonly rows: number;\n\n /**\n * The number of rows the chosen plan must be estimated to process, for a\n * {@link HighCostWarning}.\n */\n readonly cost: number;\n};\n\ntype TableRead = {\n readonly table: string;\n\n /**\n * The aliases of the `related` subqueries leading to the read, starting\n * from the root query. Empty for the root query and its EXISTS subqueries.\n */\n readonly path: readonly string[];\n\n /**\n * Whether the read runs once per row of another table, because a join\n * binds some of its columns, rather than once per query.\n */\n readonly perRow: boolean;\n\n /**\n * An index that would let the source find the rows it reads and return\n * them in order: the columns the rows are found by, then the ordering.\n */\n readonly suggestedIndex: readonly string[];\n};\n\n/**\n * The rows of a table are found by columns that no index covers, so every\n * read scans the whole table. This is typically a relationship whose foreign\n * key is not indexed.\n */\nexport type MissingIndexWarning = TableRead & {\n readonly type: 'missing-index';\n /**\n * The columns the rows are found by: the columns a join binds and the\n * columns filtered for equality.\n */\n readonly columns: readonly string[];\n /** The rows each read scans. */\n readonly rows: number;\n};\n\n/**\n * No index returns the rows of a table in the requested order, so every read\n * sorts all of the matching rows before returning the first one. A limit does\n * not reduce the rows read.\n */\nexport type FullSortWarning = TableRead & {\n readonly type: 'full-sort';\n readonly orderBy: Ordering;\n /** The estimated number of rows each read sorts. */\n readonly rows: number;\n};\n\n/**\n * The best plan the planner found is still estimated to process a lot of\n * rows. Only reported when every table the query reads has statistics, since\n * the estimates are guesses otherwise.\n */\nexport type HighCostWarning = {\n readonly type: 'high-cost';\n readonly table: string;\n /** The estimated number of rows the plan processes. */\n readonly cost: number;\n};\n\nexport type PlanWarning =\n | MissingIndexWarning\n | FullSortWarning\n | HighCostWarning;\n\n/**\n * Warns about what the cost model reports the plans in `plans` will do\n * slowly. Call this after planning: it estimates each graph's current plan.\n *\n * @param table The table of the query that `plans` was built for.\n */\nexport function collectPlanWarnings(\n table: string,\n plans: Plans,\n thresholds: PlanWarningThresholds,\n): PlanWarning[] {\n const warnings = new Map<string, PlanWarning>();\n const state = {warnings, estimated: true};\n const cost = visit(plans, [], thresholds, state);\n const result = [...warnings.values()];\n if (state.estimated && thresholds.cost > 0 && cost >= thresholds.cost) {\n result.push({type: 'high-cost', table, cost: Math.round(cost)});\n }\n return result;\n}\n\ntype VisitState = {\n readonly warnings: Map<string, PlanWarning>;\n /** Whether every access read a table with statistics. */\n estimated: boolean;\n};\n\n/**\n * Collects the warnings for `plans` and its subplans, and returns the\n * estimated number of rows they process.\n */\nfunction visit(\n plans: Plans,\n path: readonly string[],\n thresholds: PlanWarningThresholds,\n state: VisitState,\n): number {\n const estimate = plans.plan.estimateCurrentPlan();\n for (const connection of plans.plan.connections) {\n for (const access of connection.accesses()) {\n if (access.plan?.tableRows === undefined) {\n state.estimated = false;\n } else if (thresholds.rows > 0) {\n for (const warning of accessWarnings(\n connection,\n access,\n access.plan,\n access.plan.tableRows,\n path,\n thresholds.rows,\n )) {\n state.warnings.set(JSON.stringify(warning), warning);\n }\n }\n }\n }\n\n // A `related` subquery runs once for each row of its parent.\n let subCost = 0;\n for (const [alias, subPlans] of Object.entries(plans.subPlans)) {\n subCost += visit(subPlans, [...path, alias], thresholds, state);\n }\n const rowsOut =\n estimate.limit === undefined\n ? estimate.returnedRows\n : Math.min(estimate.returnedRows, estimate.limit);\n return (\n estimate.startupCost + estimate.cost + estimate.scanEst + rowsOut * subCost\n );\n}\n\nfunction* accessWarnings(\n connection: PlannerConnection,\n access: ConnectionAccess,\n plan: AccessPlan,\n tableRows: number,\n path: readonly string[],\n minRows: number,\n): Iterable<MissingIndexWarning | FullSortWarning> {\n const constrained = Object.keys(access.constraint ?? {});\n const columns = unique([...constrained, ...equalityColumns(access.filters)]);\n const read: TableRead = {\n table: connection.table,\n path,\n perRow: constrained.length > 0,\n suggestedIndex: unique([\n ...columns,\n ...connection.sort.map(([column]) => column),\n ]),\n };\n\n // A scan that stops at a limit reads an unknown share of the table, unless\n // it runs per row: then even a limit of one (an EXISTS) scans the table\n // for every row that has no match.\n if (\n plan.access === 'scan' &&\n columns.length > 0 &&\n (read.perRow || connection.limit === undefined) &&\n tableRows >= minRows\n ) {\n yield {type: 'missing-index', ...read, columns, rows: tableRows};\n }\n\n if (plan.sort === 'full' && access.rows >= minRows) {\n yield {\n type: 'full-sort',\n ...read,\n orderBy: connection.sort,\n rows: Math.round(access.rows),\n };\n }\n}\n\n/**\n * The columns that the top-level conjuncts of `condition` compare for\n * equality with a value, which an index lookup can use.\n */\nfunction equalityColumns(condition: Condition | undefined): string[] {\n switch (condition?.type) {\n case 'simple': {\n const {left, op} = condition;\n return (op === '=' || op === 'IS' || op === 'IN') &&\n left.type === 'column'\n ? [left.name]\n : [];\n }\n case 'and':\n return condition.conditions.flatMap(equalityColumns);\n default:\n return [];\n }\n}\n\nfunction unique(values: string[]): string[] {\n return [...new Set(values)];\n}\n"],"mappings":";;;;;;;AAmGA,SAAgB,oBACd,OACA,OACA,YACe;CACf,MAAM,2BAAW,IAAI,IAAyB;CAC9C,MAAM,QAAQ;EAAC;EAAU,WAAW;CAAI;CACxC,MAAM,OAAO,MAAM,OAAO,CAAC,GAAG,YAAY,KAAK;CAC/C,MAAM,SAAS,CAAC,GAAG,SAAS,OAAO,CAAC;CACpC,IAAI,MAAM,aAAa,WAAW,OAAO,KAAK,QAAQ,WAAW,MAC/D,OAAO,KAAK;EAAC,MAAM;EAAa;EAAO,MAAM,KAAK,MAAM,IAAI;CAAC,CAAC;CAEhE,OAAO;AACT;;;;;AAYA,SAAS,MACP,OACA,MACA,YACA,OACQ;CACR,MAAM,WAAW,MAAM,KAAK,oBAAoB;CAChD,KAAK,MAAM,cAAc,MAAM,KAAK,aAClC,KAAK,MAAM,UAAU,WAAW,SAAS,GACvC,IAAI,OAAO,MAAM,cAAc,KAAA,GAC7B,MAAM,YAAY;MACb,IAAI,WAAW,OAAO,GAC3B,KAAK,MAAM,WAAW,eACpB,YACA,QACA,OAAO,MACP,OAAO,KAAK,WACZ,MACA,WAAW,IACb,GACE,MAAM,SAAS,IAAI,KAAK,UAAU,OAAO,GAAG,OAAO;CAO3D,IAAI,UAAU;CACd,KAAK,MAAM,CAAC,OAAO,aAAa,OAAO,QAAQ,MAAM,QAAQ,GAC3D,WAAW,MAAM,UAAU,CAAC,GAAG,MAAM,KAAK,GAAG,YAAY,KAAK;CAEhE,MAAM,UACJ,SAAS,UAAU,KAAA,IACf,SAAS,eACT,KAAK,IAAI,SAAS,cAAc,SAAS,KAAK;CACpD,OACE,SAAS,cAAc,SAAS,OAAO,SAAS,UAAU,UAAU;AAExE;AAEA,UAAU,eACR,YACA,QACA,MACA,WACA,MACA,SACiD;CACjD,MAAM,cAAc,OAAO,KAAK,OAAO,cAAc,CAAC,CAAC;CACvD,MAAM,UAAU,OAAO,CAAC,GAAG,aAAa,GAAG,gBAAgB,OAAO,OAAO,CAAC,CAAC;CAC3E,MAAM,OAAkB;EACtB,OAAO,WAAW;EAClB;EACA,QAAQ,YAAY,SAAS;EAC7B,gBAAgB,OAAO,CACrB,GAAG,SACH,GAAG,WAAW,KAAK,KAAK,CAAC,YAAY,MAAM,CAC7C,CAAC;CACH;CAKA,IACE,KAAK,WAAW,UAChB,QAAQ,SAAS,MAChB,KAAK,UAAU,WAAW,UAAU,KAAA,MACrC,aAAa,SAEb,MAAM;EAAC,MAAM;EAAiB,GAAG;EAAM;EAAS,MAAM;CAAS;CAGjE,IAAI,KAAK,SAAS,UAAU,OAAO,QAAQ,SACzC,MAAM;EACJ,MAAM;EACN,GAAG;EACH,SAAS,WAAW;EACpB,MAAM,KAAK,MAAM,OAAO,IAAI;CAC9B;AAEJ;;;;;AAMA,SAAS,gBAAgB,WAA4C;CACnE,QAAQ,WAAW,MAAnB;EACE,KAAK,UAAU;GACb,MAAM,EAAC,MAAM,OAAM;GACnB,QAAQ,OAAO,OAAO,OAAO,QAAQ,OAAO,SAC1C,KAAK,SAAS,WACZ,CAAC,KAAK,IAAI,IACV,CAAC;EACP;EACA,KAAK,OACH,OAAO,UAAU,WAAW,QAAQ,eAAe;EACrD,SACE,OAAO,CAAC;CACZ;AACF;AAEA,SAAS,OAAO,QAA4B;CAC1C,OAAO,CAAC,GAAG,IAAI,IAAI,MAAM,CAAC;AAC5B"}
1
+ {"version":3,"file":"planner-warnings.js","names":[],"sources":["../../../../../zql/src/planner/planner-warnings.ts"],"sourcesContent":["import type {Condition, Ordering} from '../../../zero-protocol/src/ast.ts';\nimport type {Plans} from './planner-builder.ts';\nimport type {\n AccessPlan,\n ConnectionAccess,\n PlannerConnection,\n} from './planner-connection.ts';\n\n/**\n * When the planner reports a {@link PlanWarning}. Each threshold is compared\n * against the cost model's estimates, and 0 disables the warnings it gates.\n */\nexport type PlanWarningThresholds = {\n /**\n * The number of rows a single read of a table must scan (for a\n * {@link MissingIndexWarning}) or sort (for a {@link FullSortWarning}).\n */\n readonly rows: number;\n\n /**\n * The number of rows the chosen plan must be estimated to process, for a\n * {@link HighCostWarning}.\n */\n readonly cost: number;\n};\n\ntype TableRead = {\n readonly table: string;\n\n /**\n * The aliases of the `related` subqueries leading to the read, starting\n * from the root query. Empty for the root query and its EXISTS subqueries.\n */\n readonly path: readonly string[];\n\n /**\n * Whether the read runs once per row of another table, because a join\n * binds some of its columns, rather than once per query.\n */\n readonly perRow: boolean;\n\n /**\n * An index that would let the source find the rows it reads and return\n * them in order: the columns the rows are found by, then the ordering.\n */\n readonly suggestedIndex: readonly string[];\n};\n\n/**\n * The rows of a table are found by columns that no index covers, so every\n * read scans the whole table. This is typically a relationship whose foreign\n * key is not indexed.\n */\ntype MissingIndexWarning = TableRead & {\n readonly type: 'missing-index';\n /**\n * The columns the rows are found by: the columns a join binds and the\n * columns filtered for equality.\n */\n readonly columns: readonly string[];\n /** The rows each read scans. */\n readonly rows: number;\n};\n\n/**\n * No index returns the rows of a table in the requested order, so every read\n * sorts all of the matching rows before returning the first one. A limit does\n * not reduce the rows read.\n */\ntype FullSortWarning = TableRead & {\n readonly type: 'full-sort';\n readonly orderBy: Ordering;\n /** The estimated number of rows each read sorts. */\n readonly rows: number;\n};\n\n/**\n * The best plan the planner found is still estimated to process a lot of\n * rows. Only reported when every table the query reads has statistics, since\n * the estimates are guesses otherwise.\n */\ntype HighCostWarning = {\n readonly type: 'high-cost';\n readonly table: string;\n /** The estimated number of rows the plan processes. */\n readonly cost: number;\n};\n\nexport type PlanWarning =\n | MissingIndexWarning\n | FullSortWarning\n | HighCostWarning;\n\n/**\n * Warns about what the cost model reports the plans in `plans` will do\n * slowly. Call this after planning: it estimates each graph's current plan.\n *\n * @param table The table of the query that `plans` was built for.\n */\nexport function collectPlanWarnings(\n table: string,\n plans: Plans,\n thresholds: PlanWarningThresholds,\n): PlanWarning[] {\n const warnings = new Map<string, PlanWarning>();\n const state = {warnings, estimated: true};\n const cost = visit(plans, [], thresholds, state);\n const result = [...warnings.values()];\n if (state.estimated && thresholds.cost > 0 && cost >= thresholds.cost) {\n result.push({type: 'high-cost', table, cost: Math.round(cost)});\n }\n return result;\n}\n\ntype VisitState = {\n readonly warnings: Map<string, PlanWarning>;\n /** Whether every access read a table with statistics. */\n estimated: boolean;\n};\n\n/**\n * Collects the warnings for `plans` and its subplans, and returns the\n * estimated number of rows they process.\n */\nfunction visit(\n plans: Plans,\n path: readonly string[],\n thresholds: PlanWarningThresholds,\n state: VisitState,\n): number {\n const estimate = plans.plan.estimateCurrentPlan();\n for (const connection of plans.plan.connections) {\n for (const access of connection.accesses()) {\n if (access.plan?.tableRows === undefined) {\n state.estimated = false;\n } else if (thresholds.rows > 0) {\n for (const warning of accessWarnings(\n connection,\n access,\n access.plan,\n access.plan.tableRows,\n path,\n thresholds.rows,\n )) {\n state.warnings.set(JSON.stringify(warning), warning);\n }\n }\n }\n }\n\n // A `related` subquery runs once for each row of its parent.\n let subCost = 0;\n for (const [alias, subPlans] of Object.entries(plans.subPlans)) {\n subCost += visit(subPlans, [...path, alias], thresholds, state);\n }\n const rowsOut =\n estimate.limit === undefined\n ? estimate.returnedRows\n : Math.min(estimate.returnedRows, estimate.limit);\n return (\n estimate.startupCost + estimate.cost + estimate.scanEst + rowsOut * subCost\n );\n}\n\nfunction* accessWarnings(\n connection: PlannerConnection,\n access: ConnectionAccess,\n plan: AccessPlan,\n tableRows: number,\n path: readonly string[],\n minRows: number,\n): Iterable<MissingIndexWarning | FullSortWarning> {\n const constrained = Object.keys(access.constraint ?? {});\n const columns = unique([...constrained, ...equalityColumns(access.filters)]);\n const read: TableRead = {\n table: connection.table,\n path,\n perRow: constrained.length > 0,\n suggestedIndex: unique([\n ...columns,\n ...connection.sort.map(([column]) => column),\n ]),\n };\n\n // A scan that stops at a limit reads an unknown share of the table, unless\n // it runs per row: then even a limit of one (an EXISTS) scans the table\n // for every row that has no match.\n if (\n plan.access === 'scan' &&\n columns.length > 0 &&\n (read.perRow || connection.limit === undefined) &&\n tableRows >= minRows\n ) {\n yield {type: 'missing-index', ...read, columns, rows: tableRows};\n }\n\n if (plan.sort === 'full' && access.rows >= minRows) {\n yield {\n type: 'full-sort',\n ...read,\n orderBy: connection.sort,\n rows: Math.round(access.rows),\n };\n }\n}\n\n/**\n * The columns that the top-level conjuncts of `condition` compare for\n * equality with a value, which an index lookup can use.\n */\nfunction equalityColumns(condition: Condition | undefined): string[] {\n switch (condition?.type) {\n case 'simple': {\n const {left, op} = condition;\n return (op === '=' || op === 'IS' || op === 'IN') &&\n left.type === 'column'\n ? [left.name]\n : [];\n }\n case 'and':\n return condition.conditions.flatMap(equalityColumns);\n default:\n return [];\n }\n}\n\nfunction unique(values: string[]): string[] {\n return [...new Set(values)];\n}\n"],"mappings":";;;;;;;AAmGA,SAAgB,oBACd,OACA,OACA,YACe;CACf,MAAM,2BAAW,IAAI,IAAyB;CAC9C,MAAM,QAAQ;EAAC;EAAU,WAAW;CAAI;CACxC,MAAM,OAAO,MAAM,OAAO,CAAC,GAAG,YAAY,KAAK;CAC/C,MAAM,SAAS,CAAC,GAAG,SAAS,OAAO,CAAC;CACpC,IAAI,MAAM,aAAa,WAAW,OAAO,KAAK,QAAQ,WAAW,MAC/D,OAAO,KAAK;EAAC,MAAM;EAAa;EAAO,MAAM,KAAK,MAAM,IAAI;CAAC,CAAC;CAEhE,OAAO;AACT;;;;;AAYA,SAAS,MACP,OACA,MACA,YACA,OACQ;CACR,MAAM,WAAW,MAAM,KAAK,oBAAoB;CAChD,KAAK,MAAM,cAAc,MAAM,KAAK,aAClC,KAAK,MAAM,UAAU,WAAW,SAAS,GACvC,IAAI,OAAO,MAAM,cAAc,KAAA,GAC7B,MAAM,YAAY;MACb,IAAI,WAAW,OAAO,GAC3B,KAAK,MAAM,WAAW,eACpB,YACA,QACA,OAAO,MACP,OAAO,KAAK,WACZ,MACA,WAAW,IACb,GACE,MAAM,SAAS,IAAI,KAAK,UAAU,OAAO,GAAG,OAAO;CAO3D,IAAI,UAAU;CACd,KAAK,MAAM,CAAC,OAAO,aAAa,OAAO,QAAQ,MAAM,QAAQ,GAC3D,WAAW,MAAM,UAAU,CAAC,GAAG,MAAM,KAAK,GAAG,YAAY,KAAK;CAEhE,MAAM,UACJ,SAAS,UAAU,KAAA,IACf,SAAS,eACT,KAAK,IAAI,SAAS,cAAc,SAAS,KAAK;CACpD,OACE,SAAS,cAAc,SAAS,OAAO,SAAS,UAAU,UAAU;AAExE;AAEA,UAAU,eACR,YACA,QACA,MACA,WACA,MACA,SACiD;CACjD,MAAM,cAAc,OAAO,KAAK,OAAO,cAAc,CAAC,CAAC;CACvD,MAAM,UAAU,OAAO,CAAC,GAAG,aAAa,GAAG,gBAAgB,OAAO,OAAO,CAAC,CAAC;CAC3E,MAAM,OAAkB;EACtB,OAAO,WAAW;EAClB;EACA,QAAQ,YAAY,SAAS;EAC7B,gBAAgB,OAAO,CACrB,GAAG,SACH,GAAG,WAAW,KAAK,KAAK,CAAC,YAAY,MAAM,CAC7C,CAAC;CACH;CAKA,IACE,KAAK,WAAW,UAChB,QAAQ,SAAS,MAChB,KAAK,UAAU,WAAW,UAAU,KAAA,MACrC,aAAa,SAEb,MAAM;EAAC,MAAM;EAAiB,GAAG;EAAM;EAAS,MAAM;CAAS;CAGjE,IAAI,KAAK,SAAS,UAAU,OAAO,QAAQ,SACzC,MAAM;EACJ,MAAM;EACN,GAAG;EACH,SAAS,WAAW;EACpB,MAAM,KAAK,MAAM,OAAO,IAAI;CAC9B;AAEJ;;;;;AAMA,SAAS,gBAAgB,WAA4C;CACnE,QAAQ,WAAW,MAAnB;EACE,KAAK,UAAU;GACb,MAAM,EAAC,MAAM,OAAM;GACnB,QAAQ,OAAO,OAAO,OAAO,QAAQ,OAAO,SAC1C,KAAK,SAAS,WACZ,CAAC,KAAK,IAAI,IACV,CAAC;EACP;EACA,KAAK,OACH,OAAO,UAAU,WAAW,QAAQ,eAAe;EACrD,SACE,OAAO,CAAC;CACZ;AACF;AAEA,SAAS,OAAO,QAA4B;CAC1C,OAAO,CAAC,GAAG,IAAI,IAAI,MAAM,CAAC;AAC5B"}
@@ -39,27 +39,5 @@ export declare function and(...conditions: (Condition | undefined)[]): Condition
39
39
  export declare function or(...conditions: (Condition | undefined)[]): Condition;
40
40
  export declare function not(expression: Condition): Condition;
41
41
  export declare function cmp(field: string, opOrValue: SimpleOperator | ParameterReference | LiteralValue | undefined, value?: ParameterReference | LiteralValue): Condition;
42
- export declare const TRUE: Condition;
43
42
  export declare function simplifyCondition(c: Condition): Condition;
44
- export declare function flatten(type: 'and' | 'or', conditions: readonly Condition[]): Condition[];
45
- declare const negateOperatorMap: {
46
- readonly "=": '!=';
47
- readonly "!=": '=';
48
- readonly "<": '>=';
49
- readonly ">": '<=';
50
- readonly ">=": '<';
51
- readonly "<=": '>';
52
- readonly IN: 'NOT IN';
53
- readonly "NOT IN": 'IN';
54
- readonly LIKE: 'NOT LIKE';
55
- readonly "NOT LIKE": 'LIKE';
56
- readonly ILIKE: 'NOT ILIKE';
57
- readonly "NOT ILIKE": 'ILIKE';
58
- readonly IS: 'IS NOT';
59
- readonly "IS NOT": 'IS';
60
- readonly EXISTS: 'NOT EXISTS';
61
- readonly "NOT EXISTS": 'EXISTS';
62
- };
63
- export declare function negateOperator<OP extends keyof typeof negateOperatorMap>(op: OP): (typeof negateOperatorMap)[OP];
64
- export {};
65
43
  //# sourceMappingURL=expression.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"expression.d.ts","sourceRoot":"","sources":["../../../../../zql/src/query/expression.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"expression.d.ts","sourceRoot":"","sources":["../../../../../zql/src/query/expression.ts"],"names":[],"mappings":"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"}
@@ -164,6 +164,6 @@ function filterFalse(conditions) {
164
164
  return conditions.filter((c) => !isAlwaysFalse(c));
165
165
  }
166
166
  //#endregion
167
- export { ExpressionBuilder, TRUE, and, cmp, flatten, negateOperator, not, or, simplifyCondition };
167
+ export { ExpressionBuilder, and, cmp, not, or, simplifyCondition };
168
168
 
169
169
  //# sourceMappingURL=expression.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"expression.js","names":[],"sources":["../../../../../zql/src/query/expression.ts"],"sourcesContent":["/* oxlint-disable @typescript-eslint/no-explicit-any */\nimport {must} from '../../../shared/src/must.ts';\nimport {\n toStaticParam,\n type Condition,\n type LiteralValue,\n type Parameter,\n type SimpleOperator,\n} from '../../../zero-protocol/src/ast.ts';\nimport type {Schema as ZeroSchema} from '../../../zero-types/src/schema.ts';\nimport type {\n DestTableName,\n ExistsOptions,\n GetFilterType,\n NoCompoundTypeSelector,\n PullTableSchema,\n Query,\n} from './query.ts';\n\nexport type ParameterReference = {\n [toStaticParam](): Parameter;\n};\n\n/**\n * A factory function that creates a condition. This is used to create\n * complex conditions that can be passed to the `where` method of a query.\n *\n * @example\n *\n * ```ts\n * const condition: ExpressionFactory<User> = ({and, cmp, or}) =>\n * and(\n * cmp('name', '=', 'Alice'),\n * or(cmp('age', '>', 18), cmp('isStudent', '=', true)),\n * );\n *\n * const query = z.query.user.where(condition);\n * ```\n */\nexport interface ExpressionFactory<\n TTable extends keyof TSchema['tables'] & string,\n TSchema extends ZeroSchema,\n> {\n (eb: ExpressionBuilder<TTable, TSchema>): Condition;\n}\n\nexport class ExpressionBuilder<\n TTable extends keyof TSchema['tables'] & string,\n TSchema extends ZeroSchema,\n> {\n readonly #exists: (\n relationship: string,\n cb?: (query: Query<TTable, TSchema>) => Query<TTable, TSchema, any>,\n options?: ExistsOptions,\n ) => Condition;\n\n constructor(\n exists: (\n relationship: string,\n cb?: (query: Query<TTable, TSchema>) => Query<TTable, TSchema, any>,\n options?: ExistsOptions,\n ) => Condition,\n ) {\n this.#exists = exists;\n this.exists = this.exists.bind(this);\n }\n\n get eb() {\n return this;\n }\n\n cmp<\n TSelector extends NoCompoundTypeSelector<PullTableSchema<TTable, TSchema>>,\n TOperator extends SimpleOperator,\n >(\n field: TSelector,\n op: TOperator,\n value:\n | GetFilterType<PullTableSchema<TTable, TSchema>, TSelector, TOperator>\n | ParameterReference\n | undefined,\n ): Condition;\n cmp<\n TSelector extends NoCompoundTypeSelector<PullTableSchema<TTable, TSchema>>,\n >(\n field: TSelector,\n value:\n | GetFilterType<PullTableSchema<TTable, TSchema>, TSelector, '='>\n | ParameterReference\n | undefined,\n ): Condition;\n cmp(\n field: string,\n opOrValue: SimpleOperator | ParameterReference | LiteralValue | undefined,\n value?: ParameterReference | LiteralValue,\n ): Condition {\n if (arguments.length === 2) {\n return cmp(field, opOrValue);\n }\n return cmp(field, opOrValue, value);\n }\n\n cmpLit(\n left: ParameterReference | LiteralValue | undefined,\n op: SimpleOperator,\n right: ParameterReference | LiteralValue | undefined,\n ): Condition {\n return {\n type: 'simple',\n left: isParameterReference(left)\n ? left[toStaticParam]()\n : {type: 'literal', value: left ?? null},\n right: isParameterReference(right)\n ? right[toStaticParam]()\n : {type: 'literal', value: right ?? null},\n op,\n };\n }\n\n and = and;\n or = or;\n not = not;\n\n // The relationship names are inline for the reason given on `Query.related`.\n exists = <\n TRelationship extends keyof TSchema['relationships'][TTable] & string,\n >(\n relationship: TRelationship,\n cb?: (\n query: Query<DestTableName<TTable, TSchema, TRelationship>, TSchema>,\n ) => Query<any, TSchema>,\n options?: ExistsOptions,\n ): Condition => this.#exists(relationship, cb, options);\n}\n\nexport function and(...conditions: (Condition | undefined)[]): Condition {\n const expressions = filterTrue(filterUndefined(conditions));\n\n if (expressions.length === 1) {\n return expressions[0];\n }\n\n if (expressions.some(isAlwaysFalse)) {\n return FALSE;\n }\n\n return {type: 'and', conditions: expressions};\n}\n\nexport function or(...conditions: (Condition | undefined)[]): Condition {\n const expressions = filterFalse(filterUndefined(conditions));\n\n if (expressions.length === 1) {\n return expressions[0];\n }\n\n if (expressions.some(isAlwaysTrue)) {\n return TRUE;\n }\n\n return {type: 'or', conditions: expressions};\n}\n\nexport function not(expression: Condition): Condition {\n switch (expression.type) {\n case 'and':\n return {\n type: 'or',\n conditions: expression.conditions.map(not),\n };\n case 'or':\n return {\n type: 'and',\n conditions: expression.conditions.map(not),\n };\n case 'correlatedSubquery':\n return {\n type: 'correlatedSubquery',\n related: expression.related,\n op: negateOperator(expression.op),\n ...(expression.flip !== undefined ? {flip: expression.flip} : {}),\n ...(expression.scalar !== undefined ? {scalar: expression.scalar} : {}),\n };\n case 'simple':\n return {\n type: 'simple',\n op: negateOperator(expression.op),\n left: expression.left,\n right: expression.right,\n };\n }\n}\n\nexport function cmp(\n field: string,\n opOrValue: SimpleOperator | ParameterReference | LiteralValue | undefined,\n value?: ParameterReference | LiteralValue,\n): Condition {\n let op: SimpleOperator;\n let actualValue: ParameterReference | LiteralValue | undefined;\n\n if (arguments.length === 2) {\n // 2-arg form: cmp(field, value) - defaults to '=' operator\n actualValue = opOrValue as ParameterReference | LiteralValue | undefined;\n op = '=';\n } else {\n // 3-arg form: cmp(field, op, value)\n op = opOrValue as SimpleOperator;\n actualValue = value;\n }\n\n return {\n type: 'simple',\n left: {type: 'column', name: field},\n right: isParameterReference(actualValue)\n ? actualValue[toStaticParam]()\n : {type: 'literal', value: actualValue ?? null},\n op,\n };\n}\n\nfunction isParameterReference(\n value: ParameterReference | LiteralValue | null | undefined,\n): value is ParameterReference {\n return (\n value !== null &&\n value !== undefined &&\n typeof value === 'object' &&\n (value as any)[toStaticParam]\n );\n}\n\nexport const TRUE: Condition = {\n type: 'and',\n conditions: [],\n};\n\nconst FALSE: Condition = {\n type: 'or',\n conditions: [],\n};\n\nfunction isAlwaysTrue(condition: Condition): boolean {\n return condition.type === 'and' && condition.conditions.length === 0;\n}\n\nfunction isAlwaysFalse(condition: Condition): boolean {\n return condition.type === 'or' && condition.conditions.length === 0;\n}\n\nexport function simplifyCondition(c: Condition): Condition {\n if (c.type === 'simple' || c.type === 'correlatedSubquery') {\n return c;\n }\n if (c.conditions.length === 1) {\n return simplifyCondition(c.conditions[0]);\n }\n const conditions = flatten(c.type, c.conditions.map(simplifyCondition));\n if (c.type === 'and' && conditions.some(isAlwaysFalse)) {\n return FALSE;\n }\n if (c.type === 'or' && conditions.some(isAlwaysTrue)) {\n return TRUE;\n }\n return {\n type: c.type,\n conditions,\n };\n}\n\nexport function flatten(\n type: 'and' | 'or',\n conditions: readonly Condition[],\n): Condition[] {\n const flattened: Condition[] = [];\n for (const c of conditions) {\n if (c.type === type) {\n flattened.push(...c.conditions);\n } else {\n flattened.push(c);\n }\n }\n\n return flattened;\n}\n\nconst negateSimpleOperatorMap = {\n ['=']: '!=',\n ['!=']: '=',\n ['<']: '>=',\n ['>']: '<=',\n ['>=']: '<',\n ['<=']: '>',\n ['IN']: 'NOT IN',\n ['NOT IN']: 'IN',\n ['LIKE']: 'NOT LIKE',\n ['NOT LIKE']: 'LIKE',\n ['ILIKE']: 'NOT ILIKE',\n ['NOT ILIKE']: 'ILIKE',\n ['IS']: 'IS NOT',\n ['IS NOT']: 'IS',\n} as const;\n\nconst negateOperatorMap = {\n ...negateSimpleOperatorMap,\n ['EXISTS']: 'NOT EXISTS',\n ['NOT EXISTS']: 'EXISTS',\n} as const;\n\nexport function negateOperator<OP extends keyof typeof negateOperatorMap>(\n op: OP,\n): (typeof negateOperatorMap)[OP] {\n return must(negateOperatorMap[op]);\n}\n\nfunction filterUndefined<T>(array: (T | undefined)[]): T[] {\n return array.filter(e => e !== undefined);\n}\n\nfunction filterTrue(conditions: Condition[]): Condition[] {\n return conditions.filter(c => !isAlwaysTrue(c));\n}\n\nfunction filterFalse(conditions: Condition[]): Condition[] {\n return conditions.filter(c => !isAlwaysFalse(c));\n}\n"],"mappings":";;;AA8CA,IAAa,oBAAb,MAGE;CACA;CAMA,YACE,QAKA;EACA,KAAK,UAAU;EACf,KAAK,SAAS,KAAK,OAAO,KAAK,IAAI;CACrC;CAEA,IAAI,KAAK;EACP,OAAO;CACT;CAsBA,IACE,OACA,WACA,OACW;EACX,IAAI,UAAU,WAAW,GACvB,OAAO,IAAI,OAAO,SAAS;EAE7B,OAAO,IAAI,OAAO,WAAW,KAAK;CACpC;CAEA,OACE,MACA,IACA,OACW;EACX,OAAO;GACL,MAAM;GACN,MAAM,qBAAqB,IAAI,IAC3B,KAAK,cAAc,CAAC,IACpB;IAAC,MAAM;IAAW,OAAO,QAAQ;GAAI;GACzC,OAAO,qBAAqB,KAAK,IAC7B,MAAM,cAAc,CAAC,IACrB;IAAC,MAAM;IAAW,OAAO,SAAS;GAAI;GAC1C;EACF;CACF;CAEA,MAAM;CACN,KAAK;CACL,MAAM;CAGN,UAGE,cACA,IAGA,YACc,KAAK,QAAQ,cAAc,IAAI,OAAO;AACxD;AAEA,SAAgB,IAAI,GAAG,YAAkD;CACvE,MAAM,cAAc,WAAW,gBAAgB,UAAU,CAAC;CAE1D,IAAI,YAAY,WAAW,GACzB,OAAO,YAAY;CAGrB,IAAI,YAAY,KAAK,aAAa,GAChC,OAAO;CAGT,OAAO;EAAC,MAAM;EAAO,YAAY;CAAW;AAC9C;AAEA,SAAgB,GAAG,GAAG,YAAkD;CACtE,MAAM,cAAc,YAAY,gBAAgB,UAAU,CAAC;CAE3D,IAAI,YAAY,WAAW,GACzB,OAAO,YAAY;CAGrB,IAAI,YAAY,KAAK,YAAY,GAC/B,OAAO;CAGT,OAAO;EAAC,MAAM;EAAM,YAAY;CAAW;AAC7C;AAEA,SAAgB,IAAI,YAAkC;CACpD,QAAQ,WAAW,MAAnB;EACE,KAAK,OACH,OAAO;GACL,MAAM;GACN,YAAY,WAAW,WAAW,IAAI,GAAG;EAC3C;EACF,KAAK,MACH,OAAO;GACL,MAAM;GACN,YAAY,WAAW,WAAW,IAAI,GAAG;EAC3C;EACF,KAAK,sBACH,OAAO;GACL,MAAM;GACN,SAAS,WAAW;GACpB,IAAI,eAAe,WAAW,EAAE;GAChC,GAAI,WAAW,SAAS,KAAA,IAAY,EAAC,MAAM,WAAW,KAAI,IAAI,CAAC;GAC/D,GAAI,WAAW,WAAW,KAAA,IAAY,EAAC,QAAQ,WAAW,OAAM,IAAI,CAAC;EACvE;EACF,KAAK,UACH,OAAO;GACL,MAAM;GACN,IAAI,eAAe,WAAW,EAAE;GAChC,MAAM,WAAW;GACjB,OAAO,WAAW;EACpB;CACJ;AACF;AAEA,SAAgB,IACd,OACA,WACA,OACW;CACX,IAAI;CACJ,IAAI;CAEJ,IAAI,UAAU,WAAW,GAAG;EAE1B,cAAc;EACd,KAAK;CACP,OAAO;EAEL,KAAK;EACL,cAAc;CAChB;CAEA,OAAO;EACL,MAAM;EACN,MAAM;GAAC,MAAM;GAAU,MAAM;EAAK;EAClC,OAAO,qBAAqB,WAAW,IACnC,YAAY,cAAc,CAAC,IAC3B;GAAC,MAAM;GAAW,OAAO,eAAe;EAAI;EAChD;CACF;AACF;AAEA,SAAS,qBACP,OAC6B;CAC7B,OACE,UAAU,QACV,UAAU,KAAA,KACV,OAAO,UAAU,YAChB,MAAc;AAEnB;AAEA,IAAa,OAAkB;CAC7B,MAAM;CACN,YAAY,CAAC;AACf;AAEA,IAAM,QAAmB;CACvB,MAAM;CACN,YAAY,CAAC;AACf;AAEA,SAAS,aAAa,WAA+B;CACnD,OAAO,UAAU,SAAS,SAAS,UAAU,WAAW,WAAW;AACrE;AAEA,SAAS,cAAc,WAA+B;CACpD,OAAO,UAAU,SAAS,QAAQ,UAAU,WAAW,WAAW;AACpE;AAEA,SAAgB,kBAAkB,GAAyB;CACzD,IAAI,EAAE,SAAS,YAAY,EAAE,SAAS,sBACpC,OAAO;CAET,IAAI,EAAE,WAAW,WAAW,GAC1B,OAAO,kBAAkB,EAAE,WAAW,EAAE;CAE1C,MAAM,aAAa,QAAQ,EAAE,MAAM,EAAE,WAAW,IAAI,iBAAiB,CAAC;CACtE,IAAI,EAAE,SAAS,SAAS,WAAW,KAAK,aAAa,GACnD,OAAO;CAET,IAAI,EAAE,SAAS,QAAQ,WAAW,KAAK,YAAY,GACjD,OAAO;CAET,OAAO;EACL,MAAM,EAAE;EACR;CACF;AACF;AAEA,SAAgB,QACd,MACA,YACa;CACb,MAAM,YAAyB,CAAC;CAChC,KAAK,MAAM,KAAK,YACd,IAAI,EAAE,SAAS,MACb,UAAU,KAAK,GAAG,EAAE,UAAU;MAE9B,UAAU,KAAK,CAAC;CAIpB,OAAO;AACT;AAmBA,IAAM,oBAAoB;EAhBvB,MAAM;EACN,OAAO;EACP,MAAM;EACN,MAAM;EACN,OAAO;EACP,OAAO;EACP,OAAO;EACP,WAAW;EACX,SAAS;EACT,aAAa;EACb,UAAU;EACV,cAAc;EACd,OAAO;EACP,WAAW;EAKX,WAAW;EACX,eAAe;AAClB;AAEA,SAAgB,eACd,IACgC;CAChC,OAAO,KAAK,kBAAkB,GAAG;AACnC;AAEA,SAAS,gBAAmB,OAA+B;CACzD,OAAO,MAAM,QAAO,MAAK,MAAM,KAAA,CAAS;AAC1C;AAEA,SAAS,WAAW,YAAsC;CACxD,OAAO,WAAW,QAAO,MAAK,CAAC,aAAa,CAAC,CAAC;AAChD;AAEA,SAAS,YAAY,YAAsC;CACzD,OAAO,WAAW,QAAO,MAAK,CAAC,cAAc,CAAC,CAAC;AACjD"}
1
+ {"version":3,"file":"expression.js","names":[],"sources":["../../../../../zql/src/query/expression.ts"],"sourcesContent":["/* oxlint-disable @typescript-eslint/no-explicit-any */\nimport {must} from '../../../shared/src/must.ts';\nimport {\n toStaticParam,\n type Condition,\n type LiteralValue,\n type Parameter,\n type SimpleOperator,\n} from '../../../zero-protocol/src/ast.ts';\nimport type {Schema as ZeroSchema} from '../../../zero-types/src/schema.ts';\nimport type {\n DestTableName,\n ExistsOptions,\n GetFilterType,\n NoCompoundTypeSelector,\n PullTableSchema,\n Query,\n} from './query.ts';\n\nexport type ParameterReference = {\n [toStaticParam](): Parameter;\n};\n\n/**\n * A factory function that creates a condition. This is used to create\n * complex conditions that can be passed to the `where` method of a query.\n *\n * @example\n *\n * ```ts\n * const condition: ExpressionFactory<User> = ({and, cmp, or}) =>\n * and(\n * cmp('name', '=', 'Alice'),\n * or(cmp('age', '>', 18), cmp('isStudent', '=', true)),\n * );\n *\n * const query = z.query.user.where(condition);\n * ```\n */\nexport interface ExpressionFactory<\n TTable extends keyof TSchema['tables'] & string,\n TSchema extends ZeroSchema,\n> {\n (eb: ExpressionBuilder<TTable, TSchema>): Condition;\n}\n\nexport class ExpressionBuilder<\n TTable extends keyof TSchema['tables'] & string,\n TSchema extends ZeroSchema,\n> {\n readonly #exists: (\n relationship: string,\n cb?: (query: Query<TTable, TSchema>) => Query<TTable, TSchema, any>,\n options?: ExistsOptions,\n ) => Condition;\n\n constructor(\n exists: (\n relationship: string,\n cb?: (query: Query<TTable, TSchema>) => Query<TTable, TSchema, any>,\n options?: ExistsOptions,\n ) => Condition,\n ) {\n this.#exists = exists;\n this.exists = this.exists.bind(this);\n }\n\n get eb() {\n return this;\n }\n\n cmp<\n TSelector extends NoCompoundTypeSelector<PullTableSchema<TTable, TSchema>>,\n TOperator extends SimpleOperator,\n >(\n field: TSelector,\n op: TOperator,\n value:\n | GetFilterType<PullTableSchema<TTable, TSchema>, TSelector, TOperator>\n | ParameterReference\n | undefined,\n ): Condition;\n cmp<\n TSelector extends NoCompoundTypeSelector<PullTableSchema<TTable, TSchema>>,\n >(\n field: TSelector,\n value:\n | GetFilterType<PullTableSchema<TTable, TSchema>, TSelector, '='>\n | ParameterReference\n | undefined,\n ): Condition;\n cmp(\n field: string,\n opOrValue: SimpleOperator | ParameterReference | LiteralValue | undefined,\n value?: ParameterReference | LiteralValue,\n ): Condition {\n if (arguments.length === 2) {\n return cmp(field, opOrValue);\n }\n return cmp(field, opOrValue, value);\n }\n\n cmpLit(\n left: ParameterReference | LiteralValue | undefined,\n op: SimpleOperator,\n right: ParameterReference | LiteralValue | undefined,\n ): Condition {\n return {\n type: 'simple',\n left: isParameterReference(left)\n ? left[toStaticParam]()\n : {type: 'literal', value: left ?? null},\n right: isParameterReference(right)\n ? right[toStaticParam]()\n : {type: 'literal', value: right ?? null},\n op,\n };\n }\n\n and = and;\n or = or;\n not = not;\n\n // The relationship names are inline for the reason given on `Query.related`.\n exists = <\n TRelationship extends keyof TSchema['relationships'][TTable] & string,\n >(\n relationship: TRelationship,\n cb?: (\n query: Query<DestTableName<TTable, TSchema, TRelationship>, TSchema>,\n ) => Query<any, TSchema>,\n options?: ExistsOptions,\n ): Condition => this.#exists(relationship, cb, options);\n}\n\nexport function and(...conditions: (Condition | undefined)[]): Condition {\n const expressions = filterTrue(filterUndefined(conditions));\n\n if (expressions.length === 1) {\n return expressions[0];\n }\n\n if (expressions.some(isAlwaysFalse)) {\n return FALSE;\n }\n\n return {type: 'and', conditions: expressions};\n}\n\nexport function or(...conditions: (Condition | undefined)[]): Condition {\n const expressions = filterFalse(filterUndefined(conditions));\n\n if (expressions.length === 1) {\n return expressions[0];\n }\n\n if (expressions.some(isAlwaysTrue)) {\n return TRUE;\n }\n\n return {type: 'or', conditions: expressions};\n}\n\nexport function not(expression: Condition): Condition {\n switch (expression.type) {\n case 'and':\n return {\n type: 'or',\n conditions: expression.conditions.map(not),\n };\n case 'or':\n return {\n type: 'and',\n conditions: expression.conditions.map(not),\n };\n case 'correlatedSubquery':\n return {\n type: 'correlatedSubquery',\n related: expression.related,\n op: negateOperator(expression.op),\n ...(expression.flip !== undefined ? {flip: expression.flip} : {}),\n ...(expression.scalar !== undefined ? {scalar: expression.scalar} : {}),\n };\n case 'simple':\n return {\n type: 'simple',\n op: negateOperator(expression.op),\n left: expression.left,\n right: expression.right,\n };\n }\n}\n\nexport function cmp(\n field: string,\n opOrValue: SimpleOperator | ParameterReference | LiteralValue | undefined,\n value?: ParameterReference | LiteralValue,\n): Condition {\n let op: SimpleOperator;\n let actualValue: ParameterReference | LiteralValue | undefined;\n\n if (arguments.length === 2) {\n // 2-arg form: cmp(field, value) - defaults to '=' operator\n actualValue = opOrValue as ParameterReference | LiteralValue | undefined;\n op = '=';\n } else {\n // 3-arg form: cmp(field, op, value)\n op = opOrValue as SimpleOperator;\n actualValue = value;\n }\n\n return {\n type: 'simple',\n left: {type: 'column', name: field},\n right: isParameterReference(actualValue)\n ? actualValue[toStaticParam]()\n : {type: 'literal', value: actualValue ?? null},\n op,\n };\n}\n\nfunction isParameterReference(\n value: ParameterReference | LiteralValue | null | undefined,\n): value is ParameterReference {\n return (\n value !== null &&\n value !== undefined &&\n typeof value === 'object' &&\n (value as any)[toStaticParam]\n );\n}\n\nconst TRUE: Condition = {\n type: 'and',\n conditions: [],\n};\n\nconst FALSE: Condition = {\n type: 'or',\n conditions: [],\n};\n\nfunction isAlwaysTrue(condition: Condition): boolean {\n return condition.type === 'and' && condition.conditions.length === 0;\n}\n\nfunction isAlwaysFalse(condition: Condition): boolean {\n return condition.type === 'or' && condition.conditions.length === 0;\n}\n\nexport function simplifyCondition(c: Condition): Condition {\n if (c.type === 'simple' || c.type === 'correlatedSubquery') {\n return c;\n }\n if (c.conditions.length === 1) {\n return simplifyCondition(c.conditions[0]);\n }\n const conditions = flatten(c.type, c.conditions.map(simplifyCondition));\n if (c.type === 'and' && conditions.some(isAlwaysFalse)) {\n return FALSE;\n }\n if (c.type === 'or' && conditions.some(isAlwaysTrue)) {\n return TRUE;\n }\n return {\n type: c.type,\n conditions,\n };\n}\n\nfunction flatten(\n type: 'and' | 'or',\n conditions: readonly Condition[],\n): Condition[] {\n const flattened: Condition[] = [];\n for (const c of conditions) {\n if (c.type === type) {\n flattened.push(...c.conditions);\n } else {\n flattened.push(c);\n }\n }\n\n return flattened;\n}\n\nconst negateSimpleOperatorMap = {\n ['=']: '!=',\n ['!=']: '=',\n ['<']: '>=',\n ['>']: '<=',\n ['>=']: '<',\n ['<=']: '>',\n ['IN']: 'NOT IN',\n ['NOT IN']: 'IN',\n ['LIKE']: 'NOT LIKE',\n ['NOT LIKE']: 'LIKE',\n ['ILIKE']: 'NOT ILIKE',\n ['NOT ILIKE']: 'ILIKE',\n ['IS']: 'IS NOT',\n ['IS NOT']: 'IS',\n} as const;\n\nconst negateOperatorMap = {\n ...negateSimpleOperatorMap,\n ['EXISTS']: 'NOT EXISTS',\n ['NOT EXISTS']: 'EXISTS',\n} as const;\n\nfunction negateOperator<OP extends keyof typeof negateOperatorMap>(\n op: OP,\n): (typeof negateOperatorMap)[OP] {\n return must(negateOperatorMap[op]);\n}\n\nfunction filterUndefined<T>(array: (T | undefined)[]): T[] {\n return array.filter(e => e !== undefined);\n}\n\nfunction filterTrue(conditions: Condition[]): Condition[] {\n return conditions.filter(c => !isAlwaysTrue(c));\n}\n\nfunction filterFalse(conditions: Condition[]): Condition[] {\n return conditions.filter(c => !isAlwaysFalse(c));\n}\n"],"mappings":";;;AA8CA,IAAa,oBAAb,MAGE;CACA;CAMA,YACE,QAKA;EACA,KAAK,UAAU;EACf,KAAK,SAAS,KAAK,OAAO,KAAK,IAAI;CACrC;CAEA,IAAI,KAAK;EACP,OAAO;CACT;CAsBA,IACE,OACA,WACA,OACW;EACX,IAAI,UAAU,WAAW,GACvB,OAAO,IAAI,OAAO,SAAS;EAE7B,OAAO,IAAI,OAAO,WAAW,KAAK;CACpC;CAEA,OACE,MACA,IACA,OACW;EACX,OAAO;GACL,MAAM;GACN,MAAM,qBAAqB,IAAI,IAC3B,KAAK,cAAc,CAAC,IACpB;IAAC,MAAM;IAAW,OAAO,QAAQ;GAAI;GACzC,OAAO,qBAAqB,KAAK,IAC7B,MAAM,cAAc,CAAC,IACrB;IAAC,MAAM;IAAW,OAAO,SAAS;GAAI;GAC1C;EACF;CACF;CAEA,MAAM;CACN,KAAK;CACL,MAAM;CAGN,UAGE,cACA,IAGA,YACc,KAAK,QAAQ,cAAc,IAAI,OAAO;AACxD;AAEA,SAAgB,IAAI,GAAG,YAAkD;CACvE,MAAM,cAAc,WAAW,gBAAgB,UAAU,CAAC;CAE1D,IAAI,YAAY,WAAW,GACzB,OAAO,YAAY;CAGrB,IAAI,YAAY,KAAK,aAAa,GAChC,OAAO;CAGT,OAAO;EAAC,MAAM;EAAO,YAAY;CAAW;AAC9C;AAEA,SAAgB,GAAG,GAAG,YAAkD;CACtE,MAAM,cAAc,YAAY,gBAAgB,UAAU,CAAC;CAE3D,IAAI,YAAY,WAAW,GACzB,OAAO,YAAY;CAGrB,IAAI,YAAY,KAAK,YAAY,GAC/B,OAAO;CAGT,OAAO;EAAC,MAAM;EAAM,YAAY;CAAW;AAC7C;AAEA,SAAgB,IAAI,YAAkC;CACpD,QAAQ,WAAW,MAAnB;EACE,KAAK,OACH,OAAO;GACL,MAAM;GACN,YAAY,WAAW,WAAW,IAAI,GAAG;EAC3C;EACF,KAAK,MACH,OAAO;GACL,MAAM;GACN,YAAY,WAAW,WAAW,IAAI,GAAG;EAC3C;EACF,KAAK,sBACH,OAAO;GACL,MAAM;GACN,SAAS,WAAW;GACpB,IAAI,eAAe,WAAW,EAAE;GAChC,GAAI,WAAW,SAAS,KAAA,IAAY,EAAC,MAAM,WAAW,KAAI,IAAI,CAAC;GAC/D,GAAI,WAAW,WAAW,KAAA,IAAY,EAAC,QAAQ,WAAW,OAAM,IAAI,CAAC;EACvE;EACF,KAAK,UACH,OAAO;GACL,MAAM;GACN,IAAI,eAAe,WAAW,EAAE;GAChC,MAAM,WAAW;GACjB,OAAO,WAAW;EACpB;CACJ;AACF;AAEA,SAAgB,IACd,OACA,WACA,OACW;CACX,IAAI;CACJ,IAAI;CAEJ,IAAI,UAAU,WAAW,GAAG;EAE1B,cAAc;EACd,KAAK;CACP,OAAO;EAEL,KAAK;EACL,cAAc;CAChB;CAEA,OAAO;EACL,MAAM;EACN,MAAM;GAAC,MAAM;GAAU,MAAM;EAAK;EAClC,OAAO,qBAAqB,WAAW,IACnC,YAAY,cAAc,CAAC,IAC3B;GAAC,MAAM;GAAW,OAAO,eAAe;EAAI;EAChD;CACF;AACF;AAEA,SAAS,qBACP,OAC6B;CAC7B,OACE,UAAU,QACV,UAAU,KAAA,KACV,OAAO,UAAU,YAChB,MAAc;AAEnB;AAEA,IAAM,OAAkB;CACtB,MAAM;CACN,YAAY,CAAC;AACf;AAEA,IAAM,QAAmB;CACvB,MAAM;CACN,YAAY,CAAC;AACf;AAEA,SAAS,aAAa,WAA+B;CACnD,OAAO,UAAU,SAAS,SAAS,UAAU,WAAW,WAAW;AACrE;AAEA,SAAS,cAAc,WAA+B;CACpD,OAAO,UAAU,SAAS,QAAQ,UAAU,WAAW,WAAW;AACpE;AAEA,SAAgB,kBAAkB,GAAyB;CACzD,IAAI,EAAE,SAAS,YAAY,EAAE,SAAS,sBACpC,OAAO;CAET,IAAI,EAAE,WAAW,WAAW,GAC1B,OAAO,kBAAkB,EAAE,WAAW,EAAE;CAE1C,MAAM,aAAa,QAAQ,EAAE,MAAM,EAAE,WAAW,IAAI,iBAAiB,CAAC;CACtE,IAAI,EAAE,SAAS,SAAS,WAAW,KAAK,aAAa,GACnD,OAAO;CAET,IAAI,EAAE,SAAS,QAAQ,WAAW,KAAK,YAAY,GACjD,OAAO;CAET,OAAO;EACL,MAAM,EAAE;EACR;CACF;AACF;AAEA,SAAS,QACP,MACA,YACa;CACb,MAAM,YAAyB,CAAC;CAChC,KAAK,MAAM,KAAK,YACd,IAAI,EAAE,SAAS,MACb,UAAU,KAAK,GAAG,EAAE,UAAU;MAE9B,UAAU,KAAK,CAAC;CAIpB,OAAO;AACT;AAmBA,IAAM,oBAAoB;EAhBvB,MAAM;EACN,OAAO;EACP,MAAM;EACN,MAAM;EACN,OAAO;EACP,OAAO;EACP,OAAO;EACP,WAAW;EACX,SAAS;EACT,aAAa;EACb,UAAU;EACV,cAAc;EACd,OAAO;EACP,WAAW;EAKX,WAAW;EACX,eAAe;AAClB;AAEA,SAAS,eACP,IACgC;CAChC,OAAO,KAAK,kBAAkB,GAAG;AACnC;AAEA,SAAS,gBAAmB,OAA+B;CACzD,OAAO,MAAM,QAAO,MAAK,MAAM,KAAA,CAAS;AAC1C;AAEA,SAAS,WAAW,YAAsC;CACxD,OAAO,WAAW,QAAO,MAAK,CAAC,aAAa,CAAC,CAAC;AAChD;AAEA,SAAS,YAAY,YAAsC;CACzD,OAAO,WAAW,QAAO,MAAK,CAAC,cAAc,CAAC,CAAC;AACjD"}
@@ -118,11 +118,4 @@ export declare abstract class QueryDelegateBase implements QueryDelegate {
118
118
  onPipelinesReady(_attach: AttachPipeline): () => void;
119
119
  abstract getSource(name: string): Source | undefined;
120
120
  }
121
- export declare function runImpl<TTable extends keyof TSchema['tables'] & string, TSchema extends Schema, TReturn>(query: Query<TTable, TSchema, TReturn>, delegate: QueryDelegate, options?: RunOptions): Promise<HumanReadable<TReturn>>;
122
- export declare function preloadImpl<TTable extends keyof TSchema['tables'] & string, TSchema extends Schema, TReturn>(query: Query<TTable, TSchema, TReturn>, delegate: QueryDelegate, options?: PreloadOptions): {
123
- cleanup: () => void;
124
- complete: Promise<void>;
125
- cached: Promise<void>;
126
- };
127
- export declare function materializeImpl<TTable extends keyof TSchema['tables'] & string, TSchema extends Schema, TReturn, T>(query: Query<TTable, TSchema, TReturn>, delegate: QueryDelegate, factory?: ViewFactory<TTable, TSchema, TReturn, T>, options?: MaterializeOptions): T;
128
121
  //# sourceMappingURL=query-delegate-base.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"query-delegate-base.d.ts","sourceRoot":"","sources":["../../../../../zql/src/query/query-delegate-base.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"query-delegate-base.d.ts","sourceRoot":"","sources":["../../../../../zql/src/query/query-delegate-base.ts"],"names":[],"mappings":"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"}
@@ -1,3 +1,4 @@
1
+ import { resolver } from "../../../shared/src/resolver.js";
1
2
  import { hashNameAndArgs } from "../../../zero-protocol/src/query-hash-visitor.js";
2
3
  import { asQueryInternals } from "./query-internals.js";
3
4
  import { hashOfAST } from "../../../zero-protocol/src/query-hash.js";
@@ -6,7 +7,6 @@ import { ArrayView } from "../ivm/array-view.js";
6
7
  import { DeferredInput } from "../ivm/deferred-input.js";
7
8
  import { MemoryStorage } from "../ivm/memory-storage.js";
8
9
  import "./ttl.js";
9
- import { resolver } from "@rocicorp/resolver";
10
10
  //#region ../zql/src/query/query-delegate-base.ts
11
11
  /**
12
12
  * Base class that provides default implementations for common QueryDelegate methods.
@@ -295,6 +295,6 @@ function arrayViewFactory(_query, input, format, onDestroy, onTransactionCommit,
295
295
  return v;
296
296
  }
297
297
  //#endregion
298
- export { QueryDelegateBase, materializeImpl, preloadImpl, runImpl };
298
+ export { QueryDelegateBase };
299
299
 
300
300
  //# sourceMappingURL=query-delegate-base.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"query-delegate-base.js","names":["hashOfNameAndArgs"],"sources":["../../../../../zql/src/query/query-delegate-base.ts"],"sourcesContent":["import {resolver} from '@rocicorp/resolver';\nimport type {AST} from '../../../zero-protocol/src/ast.ts';\nimport type {ErroredQuery} from '../../../zero-protocol/src/custom-queries.ts';\nimport {\n hashOfAST,\n hashOfNameAndArgs,\n} from '../../../zero-protocol/src/query-hash.ts';\nimport type {Schema} from '../../../zero-types/src/schema.ts';\nimport {buildPipeline} from '../builder/builder.ts';\nimport {ArrayView} from '../ivm/array-view.ts';\nimport {DeferredInput} from '../ivm/deferred-input.ts';\nimport type {FilterInput} from '../ivm/filter-operators.ts';\nimport {MemoryStorage} from '../ivm/memory-storage.ts';\nimport type {Input, InputBase, Storage} from '../ivm/operator.ts';\nimport type {Source, SourceInput} from '../ivm/source.ts';\nimport type {Format, ViewFactory} from '../ivm/view.ts';\nimport type {MetricMap} from './metrics-delegate.ts';\nimport type {CustomQueryID} from './named.ts';\nimport type {\n AttachPipeline,\n CommitListener,\n GotCallback,\n QueryDelegate,\n} from './query-delegate.ts';\nimport {asQueryInternals, type QueryInternals} from './query-internals.ts';\nimport type {\n HumanReadable,\n MaterializeOptions,\n PreloadOptions,\n Query,\n RunOptions,\n} from './query.ts';\nimport {DEFAULT_PRELOAD_TTL_MS, DEFAULT_TTL_MS, type TTL} from './ttl.ts';\nimport type {TypedView} from './typed-view.ts';\n\n/**\n * Base class that provides default implementations for common QueryDelegate methods.\n * Subclasses can override specific methods as needed.\n */\nexport abstract class QueryDelegateBase implements QueryDelegate {\n /**\n * Default implementation that just calls applyViewUpdates synchronously.\n * Override if you need custom batching behavior (e.g., SolidJS).\n */\n batchViewUpdates<T>(applyViewUpdates: () => T): T {\n return applyViewUpdates();\n }\n\n /**\n * Default implementation returns MemoryStorage.\n * Override if you need custom storage.\n */\n createStorage(): Storage {\n return new MemoryStorage();\n }\n\n /**\n * Default implementation calls materializeImpl.\n * Override if you need custom materialization behavior.\n */\n materialize<\n TTable extends keyof TSchema['tables'] & string,\n TSchema extends Schema,\n TReturn,\n >(\n query: Query<TTable, TSchema, TReturn>,\n factory?: undefined,\n options?: MaterializeOptions,\n ): TypedView<HumanReadable<TReturn>>;\n\n materialize<\n TTable extends keyof TSchema['tables'] & string,\n TSchema extends Schema,\n TReturn,\n T,\n >(\n query: Query<TTable, TSchema, TReturn>,\n factory?: ViewFactory<TTable, TSchema, TReturn, T>,\n options?: MaterializeOptions,\n ): T;\n\n /**\n * Materialize a query into a custom view using a provided factory function.\n */\n materialize<\n TTable extends keyof TSchema['tables'] & string,\n TSchema extends Schema,\n TReturn,\n T,\n >(\n query: Query<TTable, TSchema, TReturn>,\n factory?: ViewFactory<TTable, TSchema, TReturn, T>,\n options?: MaterializeOptions,\n ): T;\n\n materialize<\n TTable extends keyof TSchema['tables'] & string,\n TSchema extends Schema,\n TReturn,\n T,\n >(\n query: Query<TTable, TSchema, TReturn>,\n factory?: ViewFactory<TTable, TSchema, TReturn, T>,\n options?: MaterializeOptions,\n ): T {\n return materializeImpl(query, this, factory, options);\n }\n\n /**\n * Default implementation calls runImpl.\n * Override if you need custom query execution (e.g., TestPGQueryDelegate).\n */\n run<\n TTable extends keyof TSchema['tables'] & string,\n TSchema extends Schema,\n TReturn,\n >(\n query: Query<TTable, TSchema, TReturn>,\n options?: RunOptions,\n ): Promise<HumanReadable<TReturn>> {\n return runImpl(query, this, options);\n }\n\n /**\n * Default implementation calls preloadImpl.\n * Override if you need custom preload behavior.\n */\n preload<\n TTable extends keyof TSchema['tables'] & string,\n TSchema extends Schema,\n TReturn,\n >(\n query: Query<TTable, TSchema, TReturn>,\n options?: PreloadOptions,\n ): {\n cleanup: () => void;\n complete: Promise<void>;\n cached: Promise<void>;\n } {\n return preloadImpl(query, this, options);\n }\n\n /**\n * Default no-op implementation for decorateSourceInput.\n * Override if you need to wrap or instrument source inputs.\n */\n decorateSourceInput(input: SourceInput, _queryID: string): Input {\n return input;\n }\n\n /**\n * Default no-op implementation for decorateInput.\n * Override if you need to wrap or instrument inputs.\n */\n decorateInput(input: Input, _name: string): Input {\n return input;\n }\n\n /**\n * Default no-op implementation for decorateFilterInput.\n * Override if you need to wrap or instrument filter inputs.\n */\n decorateFilterInput(input: FilterInput, _name: string): FilterInput {\n return input;\n }\n\n /**\n * Default no-op implementation for addEdge.\n * Override if you need to track graph edges (e.g., visualization).\n */\n addEdge(_source: InputBase, _dest: InputBase): void {\n // No-op\n }\n\n /**\n * Default no-op implementation for addMetric.\n * Override if you need to collect metrics.\n */\n addMetric<K extends keyof MetricMap>(\n _metric: K,\n _value: number,\n ..._args: MetricMap[K]\n ): void {\n // No-op\n }\n\n /**\n * Default no-op implementation.\n * Override if you need to track server queries (e.g., ZeroContext, test delegates).\n */\n addServerQuery(_ast: AST, _ttl: TTL, _gotCallback?: GotCallback): () => void {\n return () => {};\n }\n\n /**\n * Default no-op implementation.\n * Override if you need to track custom queries (e.g., ZeroContext, test delegates).\n */\n addCustomQuery(\n _ast: AST,\n _customQueryID: CustomQueryID,\n _ttl: TTL,\n _gotCallback?: GotCallback,\n ): () => void {\n return () => {};\n }\n\n /**\n * Default no-op implementation.\n * Override if you need to handle query updates.\n */\n updateServerQuery(_ast: AST, _ttl: TTL): void {\n // No-op\n }\n\n /**\n * Default no-op implementation.\n * Override if you need to handle custom query updates.\n */\n updateCustomQuery(_customQueryID: CustomQueryID, _ttl: TTL): void {\n // No-op\n }\n\n /**\n * Default no-op implementation.\n * Override if you need to flush query changes.\n */\n flushQueryChanges(): void {\n // No-op\n }\n\n /**\n * Called when a transaction commits. Override to add custom behavior.\n * Default implementation returns a no-op cleanup function.\n */\n onTransactionCommit(_cb: CommitListener): () => void {\n return () => {};\n }\n\n /**\n * Validates run options. Override to add custom validation.\n * Default implementation is a no-op.\n */\n assertValidRunOptions(_options?: RunOptions): void {\n // No-op\n }\n\n abstract readonly defaultQueryComplete: boolean;\n\n /**\n * Default: pipelines can always be built immediately. Override (together\n * with `onPipelinesReady`) to defer pipeline construction.\n */\n get pipelinesReady(): boolean {\n return true;\n }\n\n onPipelinesReady(_attach: AttachPipeline): () => void {\n throw new Error(\n 'onPipelinesReady called on a delegate whose pipelines are always ready',\n );\n }\n\n // BuilderDelegate methods - must be implemented\n abstract getSource(name: string): Source | undefined;\n}\n\n// oxlint-disable-next-line require-await\nexport async function runImpl<\n TTable extends keyof TSchema['tables'] & string,\n TSchema extends Schema,\n TReturn,\n>(\n query: Query<TTable, TSchema, TReturn>,\n delegate: QueryDelegate,\n options?: RunOptions,\n): Promise<HumanReadable<TReturn>> {\n delegate.assertValidRunOptions(options);\n const v: TypedView<HumanReadable<TReturn>> = materializeImpl(\n query,\n delegate,\n undefined,\n {\n ttl: options?.ttl,\n },\n );\n if (options?.type === 'complete' || options?.type === 'cached') {\n // 'cached' is satisfied by a result the server confirmed on a previous\n // connection, or by this connection confirming it, whichever comes first.\n const acceptCached = options.type === 'cached';\n return new Promise(resolve => {\n v.addListener((data, type) => {\n if (type === 'complete' || (acceptCached && type === 'cached')) {\n v.destroy();\n resolve(data as HumanReadable<TReturn>);\n } else if (type === 'error') {\n v.destroy();\n resolve(Promise.reject(data));\n }\n });\n });\n }\n\n options?.type satisfies 'unknown' | undefined;\n\n // A snapshot of what the view holds right now. While the delegate's\n // pipelines are not ready the view is deferred and this is empty; 'unknown'\n // has never waited for the local data, so it does not wait for that either.\n const ret = v.data;\n v.destroy();\n return ret;\n}\n\nexport function preloadImpl<\n TTable extends keyof TSchema['tables'] & string,\n TSchema extends Schema,\n TReturn,\n>(\n query: Query<TTable, TSchema, TReturn>,\n delegate: QueryDelegate,\n options?: PreloadOptions,\n): {\n cleanup: () => void;\n complete: Promise<void>;\n cached: Promise<void>;\n} {\n const qi = asQueryInternals(query);\n const ttl = options?.ttl ?? DEFAULT_PRELOAD_TTL_MS;\n const completeResolver = resolver<void>();\n const cachedResolver = resolver<void>();\n const {promise: complete} = completeResolver;\n const {promise: cached} = cachedResolver;\n // A caller may ignore either promise; a query error must not surface as an\n // unhandled rejection through the one nobody awaits.\n void complete.catch(() => {});\n void cached.catch(() => {});\n const {customQueryID, ast} = qi;\n const gotCallback: GotCallback = (got, error) => {\n if (error) {\n // The query cannot be satisfied; neither waiter should hang.\n cachedResolver.reject(error);\n completeResolver.reject(error);\n return;\n }\n // Only a server confirmation on this connection resolves `complete`;\n // `cached` is also satisfied by one from a previous connection.\n if (got === true) {\n cachedResolver.resolve();\n completeResolver.resolve();\n } else if (got === 'cached') {\n cachedResolver.resolve();\n }\n };\n const cleanup = customQueryID\n ? delegate.addCustomQuery(ast, customQueryID, ttl, gotCallback)\n : delegate.addServerQuery(ast, ttl, gotCallback);\n if (delegate.defaultQueryComplete) {\n // A delegate whose results are complete from the start (a server-side\n // one) has no got callback to drive the waiters.\n cachedResolver.resolve();\n completeResolver.resolve();\n }\n return {\n cleanup,\n complete,\n cached,\n };\n}\n\nexport function materializeImpl<\n TTable extends keyof TSchema['tables'] & string,\n TSchema extends Schema,\n TReturn,\n T,\n>(\n query: Query<TTable, TSchema, TReturn>,\n delegate: QueryDelegate,\n factory: ViewFactory<\n TTable,\n TSchema,\n TReturn,\n T\n // oxlint-disable-next-line no-explicit-any\n > = arrayViewFactory as any,\n options?: MaterializeOptions,\n): T {\n let ttl: TTL = options?.ttl ?? DEFAULT_TTL_MS;\n\n const qi = asQueryInternals(query);\n const {ast, format, customQueryID} = qi;\n\n const queryID = customQueryID\n ? hashOfNameAndArgs(customQueryID.name, customQueryID.args)\n : hashOfAST(qi.ast);\n const queryCompleteResolver = resolver<true>();\n // When the delegate cannot build pipelines yet, the view starts over an\n // empty DeferredInput and is hydrated later. A view must not report\n // `complete` until it has actually been hydrated, so completion is gated on\n // both the server's \"got\" and the pipeline being attached.\n const deferPipeline = !delegate.pipelinesReady;\n let attached = !deferPipeline;\n // The last got report: `true` once the server confirmed the query on this\n // connection, `'cached'` while the store holds a previous connection's\n // confirmed result, `false` otherwise.\n let got: boolean | 'cached' = delegate.defaultQueryComplete;\n let queryComplete: boolean | ErroredQuery = attached && got === true;\n const updateTTL = customQueryID\n ? (newTTL: TTL) => delegate.updateCustomQuery(customQueryID, newTTL)\n : (newTTL: TTL) => delegate.updateServerQuery(ast, newTTL);\n\n // Completion, and the end-to-end metric, require both the server's \"got\"\n // and the pipeline being attached: until then the view is still empty.\n const maybeResolveComplete = () => {\n if (attached && got === true && queryComplete !== true) {\n delegate.addMetric(\n 'query-materialization-end-to-end',\n performance.now() - t0,\n queryID,\n ast,\n );\n queryComplete = true;\n queryCompleteResolver.resolve(true);\n }\n };\n\n // The view, seen as its optional hooks. Only views that implement\n // `markCached`/`unmarkCached` (e.g. ArrayView) surface 'cached'; for any\n // other factory the optional calls are no-ops. The registration path can\n // report 'cached' synchronously, before the view below exists, so this\n // stays undefined until then and the mark is applied afterwards.\n let viewHooks: OptionalViewHooks | undefined;\n\n // Like 'complete', 'cached' is a claim about the rows the view holds, so it\n // waits for the view to exist and its pipeline to be attached. Once the\n // server has confirmed the query on this connection, 'complete' supersedes\n // it and the mark is skipped.\n const maybeMarkCached = () => {\n // Only while the query is still incomplete: 'complete' supersedes the\n // mark, and an error that arrived before attach must not be preceded by\n // a 'cached' notification.\n if (attached && got === 'cached' && queryComplete === false) {\n viewHooks?.markCached?.();\n }\n };\n\n let destroyed = false;\n const gotCallback: GotCallback = (value, error) => {\n if (destroyed) {\n // The delegate may keep this callback registered for a while after\n // destroy (removals are deferred while mutations are pending); a dead\n // view must not be driven, nor its listeners fired.\n return;\n }\n if (error) {\n queryCompleteResolver.reject(error);\n queryComplete = error;\n return;\n }\n\n got = value;\n if (got === 'cached') {\n maybeMarkCached();\n } else if (got === false) {\n // The got key was deleted (eviction) before the server confirmed the\n // query on this connection.\n viewHooks?.unmarkCached?.();\n } else {\n maybeResolveComplete();\n }\n };\n\n let removeCommitObserver: (() => void) | undefined;\n let removePendingAttach: (() => void) | undefined;\n const onDestroy = () => {\n destroyed = true;\n removePendingAttach?.();\n removePendingAttach = undefined;\n input.destroy();\n removeCommitObserver?.();\n removeAddedQuery();\n };\n\n const t0 = performance.now();\n\n const removeAddedQuery = customQueryID\n ? delegate.addCustomQuery(ast, customQueryID, ttl, gotCallback)\n : delegate.addServerQuery(ast, ttl, gotCallback);\n\n const deferred = deferPipeline\n ? newDeferredInput(ast, delegate, queryID)\n : undefined;\n // No type annotation here: annotating this as `Input` widens it enough that\n // the view type loses the pipeline's concrete schema, and `Zero.run` then\n // stops rejecting a query built from a schema with legacy queries enabled\n // (custom.test.ts covers that rejection).\n const input = deferred ?? buildPipeline(ast, delegate, queryID);\n\n const view = delegate.batchViewUpdates(() =>\n (factory ?? arrayViewFactory)(\n query,\n input,\n format,\n onDestroy,\n cb => {\n removeCommitObserver = delegate.onTransactionCommit(cb);\n },\n queryComplete || queryCompleteResolver.promise,\n updateTTL,\n ),\n );\n\n if (!deferred) {\n delegate.addMetric(\n 'query-materialization-client',\n performance.now() - t0,\n queryID,\n );\n } else {\n // Registered after the factory ran so a throwing factory leaves nothing\n // behind.\n removePendingAttach = delegate.onPipelinesReady(() => {\n removePendingAttach = undefined;\n if (deferred.destroyed) {\n return () => {};\n }\n const t1 = performance.now();\n try {\n viewHooks?.holdData?.();\n deferred.attach();\n } catch (e) {\n // Surface the failure on this view and let the delegate decide how\n // to log it. Other pending pipelines are unaffected.\n const error: ErroredQuery = {\n error: 'app',\n id: queryID,\n name: customQueryID?.name ?? '',\n message: e instanceof Error ? e.message : String(e),\n };\n queryComplete = error;\n queryCompleteResolver.reject(error);\n throw e;\n }\n const hydrateMs = performance.now() - t1;\n // The view holds its rows now but must not say so yet: the delegate\n // releases every view hydrated in the same batch together.\n return () => {\n if (destroyed) {\n return;\n }\n attached = true;\n viewHooks?.releaseData?.();\n delegate.addMetric('query-materialization-client', hydrateMs, queryID);\n maybeResolveComplete();\n maybeMarkCached();\n };\n });\n }\n\n viewHooks = view as OptionalViewHooks;\n maybeMarkCached();\n\n return view as T;\n}\n\n/**\n * Creates the placeholder input for a query whose pipeline cannot be built yet.\n *\n * `Input.getSchema()` is unconditional, so the placeholder needs the schema up\n * front. It is captured by building a pipeline and immediately destroying it:\n * building only connects to the sources, while the indexes and rows -- the\n * expensive part this deferral exists to postpone -- are read on the first\n * fetch. Measured at ~5us against ~500us for a single 100 row fetch.\n *\n * Building here also means a query that cannot be built at all (an unknown\n * table, `not(exists())` on the client) still throws from `materialize()`,\n * as it did before hydration was deferred.\n */\nfunction newDeferredInput(\n ast: AST,\n delegate: QueryDelegate,\n queryID: string,\n): DeferredInput {\n const build = () => buildPipeline(ast, delegate, queryID);\n const probe = build();\n try {\n return new DeferredInput(probe.getSchema(), build);\n } finally {\n probe.destroy();\n }\n}\n\n/**\n * Optional methods `materialize` calls on a view when it has them (ArrayView\n * does). See {@link ViewFactory} for what a custom view needs to know.\n */\ntype OptionalViewHooks = {\n // Surface the 'cached' result type. Views without these never show it.\n markCached?: (() => void) | undefined;\n unmarkCached?: (() => void) | undefined;\n // Keep showing the current snapshot until `releaseData()` (or the next\n // flush), and notify nobody until that flush, so a deferred view does not\n // show rows ahead of its release.\n holdData?: (() => void) | undefined;\n // Called at the release: show the hydrated rows through `data` again, but\n // leave notifying listeners to the flush that follows all the releases.\n releaseData?: (() => void) | undefined;\n};\n\nfunction arrayViewFactory<\n TTable extends string,\n TSchema extends Schema,\n TReturn,\n>(\n _query: QueryInternals<TTable, TSchema, TReturn>,\n input: Input,\n format: Format,\n onDestroy: () => void,\n onTransactionCommit: (cb: () => void) => void,\n queryComplete: true | ErroredQuery | Promise<true>,\n updateTTL: (ttl: TTL) => void,\n): TypedView<HumanReadable<TReturn>> {\n const v = new ArrayView<HumanReadable<TReturn>>(\n input,\n format,\n queryComplete,\n updateTTL,\n );\n v.onDestroy = onDestroy;\n onTransactionCommit(() => v.flush());\n return v;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"query-delegate-base.js","names":["hashOfNameAndArgs"],"sources":["../../../../../zql/src/query/query-delegate-base.ts"],"sourcesContent":["import {resolver} from '../../../shared/src/resolver.ts';\nimport type {AST} from '../../../zero-protocol/src/ast.ts';\nimport type {ErroredQuery} from '../../../zero-protocol/src/custom-queries.ts';\nimport {\n hashOfAST,\n hashOfNameAndArgs,\n} from '../../../zero-protocol/src/query-hash.ts';\nimport type {Schema} from '../../../zero-types/src/schema.ts';\nimport {buildPipeline} from '../builder/builder.ts';\nimport {ArrayView} from '../ivm/array-view.ts';\nimport {DeferredInput} from '../ivm/deferred-input.ts';\nimport type {FilterInput} from '../ivm/filter-operators.ts';\nimport {MemoryStorage} from '../ivm/memory-storage.ts';\nimport type {Input, InputBase, Storage} from '../ivm/operator.ts';\nimport type {Source, SourceInput} from '../ivm/source.ts';\nimport type {Format, ViewFactory} from '../ivm/view.ts';\nimport type {MetricMap} from './metrics-delegate.ts';\nimport type {CustomQueryID} from './named.ts';\nimport type {\n AttachPipeline,\n CommitListener,\n GotCallback,\n QueryDelegate,\n} from './query-delegate.ts';\nimport {asQueryInternals, type QueryInternals} from './query-internals.ts';\nimport type {\n HumanReadable,\n MaterializeOptions,\n PreloadOptions,\n Query,\n RunOptions,\n} from './query.ts';\nimport {DEFAULT_PRELOAD_TTL_MS, DEFAULT_TTL_MS, type TTL} from './ttl.ts';\nimport type {TypedView} from './typed-view.ts';\n\n/**\n * Base class that provides default implementations for common QueryDelegate methods.\n * Subclasses can override specific methods as needed.\n */\nexport abstract class QueryDelegateBase implements QueryDelegate {\n /**\n * Default implementation that just calls applyViewUpdates synchronously.\n * Override if you need custom batching behavior (e.g., SolidJS).\n */\n batchViewUpdates<T>(applyViewUpdates: () => T): T {\n return applyViewUpdates();\n }\n\n /**\n * Default implementation returns MemoryStorage.\n * Override if you need custom storage.\n */\n createStorage(): Storage {\n return new MemoryStorage();\n }\n\n /**\n * Default implementation calls materializeImpl.\n * Override if you need custom materialization behavior.\n */\n materialize<\n TTable extends keyof TSchema['tables'] & string,\n TSchema extends Schema,\n TReturn,\n >(\n query: Query<TTable, TSchema, TReturn>,\n factory?: undefined,\n options?: MaterializeOptions,\n ): TypedView<HumanReadable<TReturn>>;\n\n materialize<\n TTable extends keyof TSchema['tables'] & string,\n TSchema extends Schema,\n TReturn,\n T,\n >(\n query: Query<TTable, TSchema, TReturn>,\n factory?: ViewFactory<TTable, TSchema, TReturn, T>,\n options?: MaterializeOptions,\n ): T;\n\n /**\n * Materialize a query into a custom view using a provided factory function.\n */\n materialize<\n TTable extends keyof TSchema['tables'] & string,\n TSchema extends Schema,\n TReturn,\n T,\n >(\n query: Query<TTable, TSchema, TReturn>,\n factory?: ViewFactory<TTable, TSchema, TReturn, T>,\n options?: MaterializeOptions,\n ): T;\n\n materialize<\n TTable extends keyof TSchema['tables'] & string,\n TSchema extends Schema,\n TReturn,\n T,\n >(\n query: Query<TTable, TSchema, TReturn>,\n factory?: ViewFactory<TTable, TSchema, TReturn, T>,\n options?: MaterializeOptions,\n ): T {\n return materializeImpl(query, this, factory, options);\n }\n\n /**\n * Default implementation calls runImpl.\n * Override if you need custom query execution (e.g., TestPGQueryDelegate).\n */\n run<\n TTable extends keyof TSchema['tables'] & string,\n TSchema extends Schema,\n TReturn,\n >(\n query: Query<TTable, TSchema, TReturn>,\n options?: RunOptions,\n ): Promise<HumanReadable<TReturn>> {\n return runImpl(query, this, options);\n }\n\n /**\n * Default implementation calls preloadImpl.\n * Override if you need custom preload behavior.\n */\n preload<\n TTable extends keyof TSchema['tables'] & string,\n TSchema extends Schema,\n TReturn,\n >(\n query: Query<TTable, TSchema, TReturn>,\n options?: PreloadOptions,\n ): {\n cleanup: () => void;\n complete: Promise<void>;\n cached: Promise<void>;\n } {\n return preloadImpl(query, this, options);\n }\n\n /**\n * Default no-op implementation for decorateSourceInput.\n * Override if you need to wrap or instrument source inputs.\n */\n decorateSourceInput(input: SourceInput, _queryID: string): Input {\n return input;\n }\n\n /**\n * Default no-op implementation for decorateInput.\n * Override if you need to wrap or instrument inputs.\n */\n decorateInput(input: Input, _name: string): Input {\n return input;\n }\n\n /**\n * Default no-op implementation for decorateFilterInput.\n * Override if you need to wrap or instrument filter inputs.\n */\n decorateFilterInput(input: FilterInput, _name: string): FilterInput {\n return input;\n }\n\n /**\n * Default no-op implementation for addEdge.\n * Override if you need to track graph edges (e.g., visualization).\n */\n addEdge(_source: InputBase, _dest: InputBase): void {\n // No-op\n }\n\n /**\n * Default no-op implementation for addMetric.\n * Override if you need to collect metrics.\n */\n addMetric<K extends keyof MetricMap>(\n _metric: K,\n _value: number,\n ..._args: MetricMap[K]\n ): void {\n // No-op\n }\n\n /**\n * Default no-op implementation.\n * Override if you need to track server queries (e.g., ZeroContext, test delegates).\n */\n addServerQuery(_ast: AST, _ttl: TTL, _gotCallback?: GotCallback): () => void {\n return () => {};\n }\n\n /**\n * Default no-op implementation.\n * Override if you need to track custom queries (e.g., ZeroContext, test delegates).\n */\n addCustomQuery(\n _ast: AST,\n _customQueryID: CustomQueryID,\n _ttl: TTL,\n _gotCallback?: GotCallback,\n ): () => void {\n return () => {};\n }\n\n /**\n * Default no-op implementation.\n * Override if you need to handle query updates.\n */\n updateServerQuery(_ast: AST, _ttl: TTL): void {\n // No-op\n }\n\n /**\n * Default no-op implementation.\n * Override if you need to handle custom query updates.\n */\n updateCustomQuery(_customQueryID: CustomQueryID, _ttl: TTL): void {\n // No-op\n }\n\n /**\n * Default no-op implementation.\n * Override if you need to flush query changes.\n */\n flushQueryChanges(): void {\n // No-op\n }\n\n /**\n * Called when a transaction commits. Override to add custom behavior.\n * Default implementation returns a no-op cleanup function.\n */\n onTransactionCommit(_cb: CommitListener): () => void {\n return () => {};\n }\n\n /**\n * Validates run options. Override to add custom validation.\n * Default implementation is a no-op.\n */\n assertValidRunOptions(_options?: RunOptions): void {\n // No-op\n }\n\n abstract readonly defaultQueryComplete: boolean;\n\n /**\n * Default: pipelines can always be built immediately. Override (together\n * with `onPipelinesReady`) to defer pipeline construction.\n */\n get pipelinesReady(): boolean {\n return true;\n }\n\n onPipelinesReady(_attach: AttachPipeline): () => void {\n throw new Error(\n 'onPipelinesReady called on a delegate whose pipelines are always ready',\n );\n }\n\n // BuilderDelegate methods - must be implemented\n abstract getSource(name: string): Source | undefined;\n}\n\n// oxlint-disable-next-line require-await\nasync function runImpl<\n TTable extends keyof TSchema['tables'] & string,\n TSchema extends Schema,\n TReturn,\n>(\n query: Query<TTable, TSchema, TReturn>,\n delegate: QueryDelegate,\n options?: RunOptions,\n): Promise<HumanReadable<TReturn>> {\n delegate.assertValidRunOptions(options);\n const v: TypedView<HumanReadable<TReturn>> = materializeImpl(\n query,\n delegate,\n undefined,\n {\n ttl: options?.ttl,\n },\n );\n if (options?.type === 'complete' || options?.type === 'cached') {\n // 'cached' is satisfied by a result the server confirmed on a previous\n // connection, or by this connection confirming it, whichever comes first.\n const acceptCached = options.type === 'cached';\n return new Promise(resolve => {\n v.addListener((data, type) => {\n if (type === 'complete' || (acceptCached && type === 'cached')) {\n v.destroy();\n resolve(data as HumanReadable<TReturn>);\n } else if (type === 'error') {\n v.destroy();\n resolve(Promise.reject(data));\n }\n });\n });\n }\n\n options?.type satisfies 'unknown' | undefined;\n\n // A snapshot of what the view holds right now. While the delegate's\n // pipelines are not ready the view is deferred and this is empty; 'unknown'\n // has never waited for the local data, so it does not wait for that either.\n const ret = v.data;\n v.destroy();\n return ret;\n}\n\nfunction preloadImpl<\n TTable extends keyof TSchema['tables'] & string,\n TSchema extends Schema,\n TReturn,\n>(\n query: Query<TTable, TSchema, TReturn>,\n delegate: QueryDelegate,\n options?: PreloadOptions,\n): {\n cleanup: () => void;\n complete: Promise<void>;\n cached: Promise<void>;\n} {\n const qi = asQueryInternals(query);\n const ttl = options?.ttl ?? DEFAULT_PRELOAD_TTL_MS;\n const completeResolver = resolver<void>();\n const cachedResolver = resolver<void>();\n const {promise: complete} = completeResolver;\n const {promise: cached} = cachedResolver;\n // A caller may ignore either promise; a query error must not surface as an\n // unhandled rejection through the one nobody awaits.\n void complete.catch(() => {});\n void cached.catch(() => {});\n const {customQueryID, ast} = qi;\n const gotCallback: GotCallback = (got, error) => {\n if (error) {\n // The query cannot be satisfied; neither waiter should hang.\n cachedResolver.reject(error);\n completeResolver.reject(error);\n return;\n }\n // Only a server confirmation on this connection resolves `complete`;\n // `cached` is also satisfied by one from a previous connection.\n if (got === true) {\n cachedResolver.resolve();\n completeResolver.resolve();\n } else if (got === 'cached') {\n cachedResolver.resolve();\n }\n };\n const cleanup = customQueryID\n ? delegate.addCustomQuery(ast, customQueryID, ttl, gotCallback)\n : delegate.addServerQuery(ast, ttl, gotCallback);\n if (delegate.defaultQueryComplete) {\n // A delegate whose results are complete from the start (a server-side\n // one) has no got callback to drive the waiters.\n cachedResolver.resolve();\n completeResolver.resolve();\n }\n return {\n cleanup,\n complete,\n cached,\n };\n}\n\nfunction materializeImpl<\n TTable extends keyof TSchema['tables'] & string,\n TSchema extends Schema,\n TReturn,\n T,\n>(\n query: Query<TTable, TSchema, TReturn>,\n delegate: QueryDelegate,\n factory: ViewFactory<\n TTable,\n TSchema,\n TReturn,\n T\n // oxlint-disable-next-line no-explicit-any\n > = arrayViewFactory as any,\n options?: MaterializeOptions,\n): T {\n let ttl: TTL = options?.ttl ?? DEFAULT_TTL_MS;\n\n const qi = asQueryInternals(query);\n const {ast, format, customQueryID} = qi;\n\n const queryID = customQueryID\n ? hashOfNameAndArgs(customQueryID.name, customQueryID.args)\n : hashOfAST(qi.ast);\n const queryCompleteResolver = resolver<true>();\n // When the delegate cannot build pipelines yet, the view starts over an\n // empty DeferredInput and is hydrated later. A view must not report\n // `complete` until it has actually been hydrated, so completion is gated on\n // both the server's \"got\" and the pipeline being attached.\n const deferPipeline = !delegate.pipelinesReady;\n let attached = !deferPipeline;\n // The last got report: `true` once the server confirmed the query on this\n // connection, `'cached'` while the store holds a previous connection's\n // confirmed result, `false` otherwise.\n let got: boolean | 'cached' = delegate.defaultQueryComplete;\n let queryComplete: boolean | ErroredQuery = attached && got === true;\n const updateTTL = customQueryID\n ? (newTTL: TTL) => delegate.updateCustomQuery(customQueryID, newTTL)\n : (newTTL: TTL) => delegate.updateServerQuery(ast, newTTL);\n\n // Completion, and the end-to-end metric, require both the server's \"got\"\n // and the pipeline being attached: until then the view is still empty.\n const maybeResolveComplete = () => {\n if (attached && got === true && queryComplete !== true) {\n delegate.addMetric(\n 'query-materialization-end-to-end',\n performance.now() - t0,\n queryID,\n ast,\n );\n queryComplete = true;\n queryCompleteResolver.resolve(true);\n }\n };\n\n // The view, seen as its optional hooks. Only views that implement\n // `markCached`/`unmarkCached` (e.g. ArrayView) surface 'cached'; for any\n // other factory the optional calls are no-ops. The registration path can\n // report 'cached' synchronously, before the view below exists, so this\n // stays undefined until then and the mark is applied afterwards.\n let viewHooks: OptionalViewHooks | undefined;\n\n // Like 'complete', 'cached' is a claim about the rows the view holds, so it\n // waits for the view to exist and its pipeline to be attached. Once the\n // server has confirmed the query on this connection, 'complete' supersedes\n // it and the mark is skipped.\n const maybeMarkCached = () => {\n // Only while the query is still incomplete: 'complete' supersedes the\n // mark, and an error that arrived before attach must not be preceded by\n // a 'cached' notification.\n if (attached && got === 'cached' && queryComplete === false) {\n viewHooks?.markCached?.();\n }\n };\n\n let destroyed = false;\n const gotCallback: GotCallback = (value, error) => {\n if (destroyed) {\n // The delegate may keep this callback registered for a while after\n // destroy (removals are deferred while mutations are pending); a dead\n // view must not be driven, nor its listeners fired.\n return;\n }\n if (error) {\n queryCompleteResolver.reject(error);\n queryComplete = error;\n return;\n }\n\n got = value;\n if (got === 'cached') {\n maybeMarkCached();\n } else if (got === false) {\n // The got key was deleted (eviction) before the server confirmed the\n // query on this connection.\n viewHooks?.unmarkCached?.();\n } else {\n maybeResolveComplete();\n }\n };\n\n let removeCommitObserver: (() => void) | undefined;\n let removePendingAttach: (() => void) | undefined;\n const onDestroy = () => {\n destroyed = true;\n removePendingAttach?.();\n removePendingAttach = undefined;\n input.destroy();\n removeCommitObserver?.();\n removeAddedQuery();\n };\n\n const t0 = performance.now();\n\n const removeAddedQuery = customQueryID\n ? delegate.addCustomQuery(ast, customQueryID, ttl, gotCallback)\n : delegate.addServerQuery(ast, ttl, gotCallback);\n\n const deferred = deferPipeline\n ? newDeferredInput(ast, delegate, queryID)\n : undefined;\n // No type annotation here: annotating this as `Input` widens it enough that\n // the view type loses the pipeline's concrete schema, and `Zero.run` then\n // stops rejecting a query built from a schema with legacy queries enabled\n // (custom.test.ts covers that rejection).\n const input = deferred ?? buildPipeline(ast, delegate, queryID);\n\n const view = delegate.batchViewUpdates(() =>\n (factory ?? arrayViewFactory)(\n query,\n input,\n format,\n onDestroy,\n cb => {\n removeCommitObserver = delegate.onTransactionCommit(cb);\n },\n queryComplete || queryCompleteResolver.promise,\n updateTTL,\n ),\n );\n\n if (!deferred) {\n delegate.addMetric(\n 'query-materialization-client',\n performance.now() - t0,\n queryID,\n );\n } else {\n // Registered after the factory ran so a throwing factory leaves nothing\n // behind.\n removePendingAttach = delegate.onPipelinesReady(() => {\n removePendingAttach = undefined;\n if (deferred.destroyed) {\n return () => {};\n }\n const t1 = performance.now();\n try {\n viewHooks?.holdData?.();\n deferred.attach();\n } catch (e) {\n // Surface the failure on this view and let the delegate decide how\n // to log it. Other pending pipelines are unaffected.\n const error: ErroredQuery = {\n error: 'app',\n id: queryID,\n name: customQueryID?.name ?? '',\n message: e instanceof Error ? e.message : String(e),\n };\n queryComplete = error;\n queryCompleteResolver.reject(error);\n throw e;\n }\n const hydrateMs = performance.now() - t1;\n // The view holds its rows now but must not say so yet: the delegate\n // releases every view hydrated in the same batch together.\n return () => {\n if (destroyed) {\n return;\n }\n attached = true;\n viewHooks?.releaseData?.();\n delegate.addMetric('query-materialization-client', hydrateMs, queryID);\n maybeResolveComplete();\n maybeMarkCached();\n };\n });\n }\n\n viewHooks = view as OptionalViewHooks;\n maybeMarkCached();\n\n return view as T;\n}\n\n/**\n * Creates the placeholder input for a query whose pipeline cannot be built yet.\n *\n * `Input.getSchema()` is unconditional, so the placeholder needs the schema up\n * front. It is captured by building a pipeline and immediately destroying it:\n * building only connects to the sources, while the indexes and rows -- the\n * expensive part this deferral exists to postpone -- are read on the first\n * fetch. Measured at ~5us against ~500us for a single 100 row fetch.\n *\n * Building here also means a query that cannot be built at all (an unknown\n * table, `not(exists())` on the client) still throws from `materialize()`,\n * as it did before hydration was deferred.\n */\nfunction newDeferredInput(\n ast: AST,\n delegate: QueryDelegate,\n queryID: string,\n): DeferredInput {\n const build = () => buildPipeline(ast, delegate, queryID);\n const probe = build();\n try {\n return new DeferredInput(probe.getSchema(), build);\n } finally {\n probe.destroy();\n }\n}\n\n/**\n * Optional methods `materialize` calls on a view when it has them (ArrayView\n * does). See {@link ViewFactory} for what a custom view needs to know.\n */\ntype OptionalViewHooks = {\n // Surface the 'cached' result type. Views without these never show it.\n markCached?: (() => void) | undefined;\n unmarkCached?: (() => void) | undefined;\n // Keep showing the current snapshot until `releaseData()` (or the next\n // flush), and notify nobody until that flush, so a deferred view does not\n // show rows ahead of its release.\n holdData?: (() => void) | undefined;\n // Called at the release: show the hydrated rows through `data` again, but\n // leave notifying listeners to the flush that follows all the releases.\n releaseData?: (() => void) | undefined;\n};\n\nfunction arrayViewFactory<\n TTable extends string,\n TSchema extends Schema,\n TReturn,\n>(\n _query: QueryInternals<TTable, TSchema, TReturn>,\n input: Input,\n format: Format,\n onDestroy: () => void,\n onTransactionCommit: (cb: () => void) => void,\n queryComplete: true | ErroredQuery | Promise<true>,\n updateTTL: (ttl: TTL) => void,\n): TypedView<HumanReadable<TReturn>> {\n const v = new ArrayView<HumanReadable<TReturn>>(\n input,\n format,\n queryComplete,\n updateTTL,\n );\n v.onDestroy = onDestroy;\n onTransactionCommit(() => v.flush());\n return v;\n}\n"],"mappings":"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"}
@@ -2,7 +2,7 @@ import type { AST } from '../../../zero-protocol/src/ast.ts';
2
2
  import type { ErroredQuery } from '../../../zero-protocol/src/custom-queries.ts';
3
3
  import type { Schema } from '../../../zero-types/src/schema.ts';
4
4
  import type { BuilderDelegate } from '../builder/builder.ts';
5
- import type { Format, ViewFactory } from '../ivm/view.ts';
5
+ import type { ViewFactory } from '../ivm/view.ts';
6
6
  import type { MetricsDelegate } from './metrics-delegate.ts';
7
7
  import type { CustomQueryID } from './named.ts';
8
8
  import type { HumanReadable, MaterializeOptions, PreloadOptions, Query, RunOptions } from './query.ts';
@@ -19,9 +19,6 @@ export type CommitListener = () => void;
19
19
  * complete-waiters — freshness stays a promise only the connection can keep.
20
20
  */
21
21
  export type GotCallback = (got: boolean | 'cached', error?: ErroredQuery) => void;
22
- export interface NewQueryDelegate {
23
- newQuery<TTable extends keyof TSchema['tables'] & string, TSchema extends Schema, TReturn>(schema: TSchema, table: TTable, ast: AST, format: Format): Query<TTable, TSchema, TReturn>;
24
- }
25
22
  /**
26
23
  * Builds and hydrates a deferred pipeline. Returns the function that exposes
27
24
  * the result. See {@link QueryDelegate.onPipelinesReady}.
@@ -1 +1 @@
1
- {"version":3,"file":"query-delegate.d.ts","sourceRoot":"","sources":["../../../../../zql/src/query/query-delegate.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"query-delegate.d.ts","sourceRoot":"","sources":["../../../../../zql/src/query/query-delegate.ts"],"names":[],"mappings":"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"}
@@ -72,7 +72,4 @@ export interface QueryInternals<TTable extends keyof TSchema['tables'] & string,
72
72
  * @internal
73
73
  */
74
74
  export declare function asQueryInternals<TTable extends keyof TSchema['tables'] & string, TSchema extends ZeroSchema, TReturn>(query: Query<TTable, TSchema, TReturn>): QueryInternals<TTable, TSchema, TReturn>;
75
- export declare function isQueryInternals<TTable extends keyof TSchema['tables'] & string, TSchema extends ZeroSchema, TReturn>(obj: unknown): obj is QueryInternals<TTable, TSchema, TReturn>;
76
- export declare function asQuery<TTable extends keyof TSchema['tables'] & string, TSchema extends ZeroSchema, TReturn>(queryInternals: QueryInternals<TTable, TSchema, TReturn>): Query<TTable, TSchema, TReturn>;
77
- export type AnyQueryInternals = QueryInternals<string, ZeroSchema, any>;
78
75
  //# sourceMappingURL=query-internals.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"query-internals.d.ts","sourceRoot":"","sources":["../../../../../zql/src/query/query-internals.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAC,iBAAiB,EAAC,MAAM,6BAA6B,CAAC;AACnE,OAAO,KAAK,EAAC,GAAG,EAAC,MAAM,mCAAmC,CAAC;AAC3D,OAAO,KAAK,EAAC,MAAM,IAAI,UAAU,EAAC,MAAM,mCAAmC,CAAC;AAC5E,OAAO,KAAK,EAAC,MAAM,EAAC,MAAM,gBAAgB,CAAC;AAC3C,OAAO,KAAK,EAAC,aAAa,EAAC,MAAM,YAAY,CAAC;AAC9C,OAAO,KAAK,EAAC,KAAK,EAAC,MAAM,YAAY,CAAC;AAEtC,eAAO,MAAM,iBAAiB,eAAW,CAAC;AAE1C;;;;;;;;GAQG;AACH,MAAM,WAAW,cAAc,CAC7B,MAAM,SAAS,MAAM,OAAO,CAAC,QAAQ,CAAC,GAAG,MAAM,EAC/C,OAAO,SAAS,UAAU,EAC1B,OAAO;IAEP,QAAQ,CAAC,CAAC,iBAAiB,CAAC,EAAE,IAAI,CAAC;IAEnC;;;;OAIG;IACH,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IAExB;;;;;;;;;;;;;;;;;;;;;;OAsBG;IACH,IAAI,IAAI,MAAM,CAAC;IAEf;;;;;;OAMG;IACH,QAAQ,CAAC,GAAG,EAAE,GAAG,CAAC;IAElB,QAAQ,CAAC,aAAa,EAAE,aAAa,GAAG,SAAS,CAAC;IAElD;;;;;OAKG;IACH,WAAW,CACT,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,aAAa,CAAC,iBAAiB,CAAC,GACrC,KAAK,CAAC,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;CACpC;AAED;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAC9B,MAAM,SAAS,MAAM,OAAO,CAAC,QAAQ,CAAC,GAAG,MAAM,EAC/C,OAAO,SAAS,UAAU,EAC1B,OAAO,EAEP,KAAK,EAAE,KAAK,CAAC,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,GACrC,cAAc,CAAC,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,CAM1C;AAED,wBAAgB,gBAAgB,CAC9B,MAAM,SAAS,MAAM,OAAO,CAAC,QAAQ,CAAC,GAAG,MAAM,EAC/C,OAAO,SAAS,UAAU,EAC1B,OAAO,EACP,GAAG,EAAE,OAAO,GAAG,GAAG,IAAI,cAAc,CAAC,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,CAE/D;AAED,wBAAgB,OAAO,CACrB,MAAM,SAAS,MAAM,OAAO,CAAC,QAAQ,CAAC,GAAG,MAAM,EAC/C,OAAO,SAAS,UAAU,EAC1B,OAAO,EAEP,cAAc,EAAE,cAAc,CAAC,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,GACvD,KAAK,CAAC,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,CAGjC;AAGD,MAAM,MAAM,iBAAiB,GAAG,cAAc,CAAC,MAAM,EAAE,UAAU,EAAE,GAAG,CAAC,CAAC"}
1
+ {"version":3,"file":"query-internals.d.ts","sourceRoot":"","sources":["../../../../../zql/src/query/query-internals.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAC,iBAAiB,EAAC,MAAM,6BAA6B,CAAC;AACnE,OAAO,KAAK,EAAC,GAAG,EAAC,MAAM,mCAAmC,CAAC;AAC3D,OAAO,KAAK,EAAC,MAAM,IAAI,UAAU,EAAC,MAAM,mCAAmC,CAAC;AAC5E,OAAO,KAAK,EAAC,MAAM,EAAC,MAAM,gBAAgB,CAAC;AAC3C,OAAO,KAAK,EAAC,aAAa,EAAC,MAAM,YAAY,CAAC;AAC9C,OAAO,KAAK,EAAC,KAAK,EAAC,MAAM,YAAY,CAAC;AAEtC,eAAO,MAAM,iBAAiB,eAAW,CAAC;AAE1C;;;;;;;;GAQG;AACH,MAAM,WAAW,cAAc,CAC7B,MAAM,SAAS,MAAM,OAAO,CAAC,QAAQ,CAAC,GAAG,MAAM,EAC/C,OAAO,SAAS,UAAU,EAC1B,OAAO;IAEP,QAAQ,CAAC,CAAC,iBAAiB,CAAC,EAAE,IAAI,CAAC;IAEnC;;;;OAIG;IACH,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IAExB;;;;;;;;;;;;;;;;;;;;;;OAsBG;IACH,IAAI,IAAI,MAAM,CAAC;IAEf;;;;;;OAMG;IACH,QAAQ,CAAC,GAAG,EAAE,GAAG,CAAC;IAElB,QAAQ,CAAC,aAAa,EAAE,aAAa,GAAG,SAAS,CAAC;IAElD;;;;;OAKG;IACH,WAAW,CACT,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,aAAa,CAAC,iBAAiB,CAAC,GACrC,KAAK,CAAC,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;CACpC;AAED;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAC9B,MAAM,SAAS,MAAM,OAAO,CAAC,QAAQ,CAAC,GAAG,MAAM,EAC/C,OAAO,SAAS,UAAU,EAC1B,OAAO,EAEP,KAAK,EAAE,KAAK,CAAC,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,GACrC,cAAc,CAAC,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,CAM1C"}