@rocicorp/zero 1.3.0-canary.3 → 1.3.1-canary.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (277) hide show
  1. package/out/analyze-query/src/bin-analyze.js +7 -7
  2. package/out/analyze-query/src/bin-transform.js +3 -3
  3. package/out/ast-to-zql/src/bin.js +2 -2
  4. package/out/shared/src/logging.d.ts.map +1 -1
  5. package/out/shared/src/logging.js +1 -1
  6. package/out/shared/src/logging.js.map +1 -1
  7. package/out/shared/src/options.d.ts.map +1 -1
  8. package/out/shared/src/options.js +1 -1
  9. package/out/shared/src/options.js.map +1 -1
  10. package/out/zero/package.js +89 -91
  11. package/out/zero/package.js.map +1 -1
  12. package/out/zero/src/zero-cache-dev.js +1 -1
  13. package/out/zero/src/zero-cache-dev.js.map +1 -1
  14. package/out/zero/src/zero-out.js +1 -1
  15. package/out/zero-cache/src/auth/auth.d.ts.map +1 -1
  16. package/out/zero-cache/src/auth/auth.js.map +1 -1
  17. package/out/zero-cache/src/auth/load-permissions.js +2 -2
  18. package/out/zero-cache/src/auth/write-authorizer.d.ts.map +1 -1
  19. package/out/zero-cache/src/auth/write-authorizer.js +14 -5
  20. package/out/zero-cache/src/auth/write-authorizer.js.map +1 -1
  21. package/out/zero-cache/src/config/network.d.ts +1 -1
  22. package/out/zero-cache/src/config/network.d.ts.map +1 -1
  23. package/out/zero-cache/src/config/network.js +1 -1
  24. package/out/zero-cache/src/config/network.js.map +1 -1
  25. package/out/zero-cache/src/config/normalize.d.ts.map +1 -1
  26. package/out/zero-cache/src/config/normalize.js.map +1 -1
  27. package/out/zero-cache/src/config/zero-config.d.ts +0 -5
  28. package/out/zero-cache/src/config/zero-config.d.ts.map +1 -1
  29. package/out/zero-cache/src/config/zero-config.js +3 -16
  30. package/out/zero-cache/src/config/zero-config.js.map +1 -1
  31. package/out/zero-cache/src/db/lite-tables.d.ts.map +1 -1
  32. package/out/zero-cache/src/db/lite-tables.js +3 -3
  33. package/out/zero-cache/src/db/lite-tables.js.map +1 -1
  34. package/out/zero-cache/src/db/pg-to-lite.d.ts +1 -1
  35. package/out/zero-cache/src/db/pg-to-lite.d.ts.map +1 -1
  36. package/out/zero-cache/src/db/pg-to-lite.js +13 -13
  37. package/out/zero-cache/src/db/pg-to-lite.js.map +1 -1
  38. package/out/zero-cache/src/db/transaction-pool.d.ts +40 -43
  39. package/out/zero-cache/src/db/transaction-pool.d.ts.map +1 -1
  40. package/out/zero-cache/src/db/transaction-pool.js +56 -76
  41. package/out/zero-cache/src/db/transaction-pool.js.map +1 -1
  42. package/out/zero-cache/src/observability/events.d.ts.map +1 -1
  43. package/out/zero-cache/src/observability/events.js +1 -1
  44. package/out/zero-cache/src/observability/events.js.map +1 -1
  45. package/out/zero-cache/src/scripts/decommission.js +1 -1
  46. package/out/zero-cache/src/scripts/deploy-permissions.js +2 -2
  47. package/out/zero-cache/src/scripts/permissions.js +1 -1
  48. package/out/zero-cache/src/server/anonymous-otel-start.d.ts.map +1 -1
  49. package/out/zero-cache/src/server/anonymous-otel-start.js +3 -3
  50. package/out/zero-cache/src/server/anonymous-otel-start.js.map +1 -1
  51. package/out/zero-cache/src/server/change-streamer.d.ts +1 -1
  52. package/out/zero-cache/src/server/change-streamer.d.ts.map +1 -1
  53. package/out/zero-cache/src/server/change-streamer.js +11 -26
  54. package/out/zero-cache/src/server/change-streamer.js.map +1 -1
  55. package/out/zero-cache/src/server/logging.d.ts +3 -1
  56. package/out/zero-cache/src/server/logging.d.ts.map +1 -1
  57. package/out/zero-cache/src/server/logging.js +3 -6
  58. package/out/zero-cache/src/server/logging.js.map +1 -1
  59. package/out/zero-cache/src/server/main.d.ts.map +1 -1
  60. package/out/zero-cache/src/server/main.js +26 -26
  61. package/out/zero-cache/src/server/main.js.map +1 -1
  62. package/out/zero-cache/src/server/mutator.js +2 -4
  63. package/out/zero-cache/src/server/mutator.js.map +1 -1
  64. package/out/zero-cache/src/server/otel-log-sink.d.ts.map +1 -1
  65. package/out/zero-cache/src/server/otel-log-sink.js +2 -0
  66. package/out/zero-cache/src/server/otel-log-sink.js.map +1 -1
  67. package/out/zero-cache/src/server/otel-start.d.ts +1 -1
  68. package/out/zero-cache/src/server/otel-start.d.ts.map +1 -1
  69. package/out/zero-cache/src/server/otel-start.js +3 -7
  70. package/out/zero-cache/src/server/otel-start.js.map +1 -1
  71. package/out/zero-cache/src/server/reaper.js +6 -6
  72. package/out/zero-cache/src/server/reaper.js.map +1 -1
  73. package/out/zero-cache/src/server/replicator.d.ts.map +1 -1
  74. package/out/zero-cache/src/server/replicator.js +3 -5
  75. package/out/zero-cache/src/server/replicator.js.map +1 -1
  76. package/out/zero-cache/src/server/runner/run-worker.js +2 -2
  77. package/out/zero-cache/src/server/runner/run-worker.js.map +1 -1
  78. package/out/zero-cache/src/server/syncer.d.ts.map +1 -1
  79. package/out/zero-cache/src/server/syncer.js +12 -13
  80. package/out/zero-cache/src/server/syncer.js.map +1 -1
  81. package/out/zero-cache/src/server/worker-dispatcher.js +1 -1
  82. package/out/zero-cache/src/services/change-source/common/backfill-manager.js +1 -1
  83. package/out/zero-cache/src/services/change-source/common/replica-schema.js +1 -1
  84. package/out/zero-cache/src/services/change-source/custom/change-source.js +2 -2
  85. package/out/zero-cache/src/services/change-source/pg/backfill-stream.js +1 -4
  86. package/out/zero-cache/src/services/change-source/pg/backfill-stream.js.map +1 -1
  87. package/out/zero-cache/src/services/change-source/pg/change-source.js +2 -2
  88. package/out/zero-cache/src/services/change-source/pg/initial-sync.d.ts +3 -58
  89. package/out/zero-cache/src/services/change-source/pg/initial-sync.d.ts.map +1 -1
  90. package/out/zero-cache/src/services/change-source/pg/initial-sync.js +51 -208
  91. package/out/zero-cache/src/services/change-source/pg/initial-sync.js.map +1 -1
  92. package/out/zero-cache/src/services/change-source/pg/logical-replication/stream.js +1 -1
  93. package/out/zero-cache/src/services/change-source/pg/schema/ddl.js +1 -1
  94. package/out/zero-cache/src/services/change-source/pg/schema/init.js +1 -1
  95. package/out/zero-cache/src/services/change-source/pg/schema/shard.js +1 -1
  96. package/out/zero-cache/src/services/change-streamer/backup-monitor.js +1 -1
  97. package/out/zero-cache/src/services/change-streamer/change-streamer-http.d.ts +1 -1
  98. package/out/zero-cache/src/services/change-streamer/change-streamer-http.d.ts.map +1 -1
  99. package/out/zero-cache/src/services/change-streamer/change-streamer-http.js +1 -1
  100. package/out/zero-cache/src/services/change-streamer/change-streamer-http.js.map +1 -1
  101. package/out/zero-cache/src/services/change-streamer/change-streamer-service.d.ts +1 -5
  102. package/out/zero-cache/src/services/change-streamer/change-streamer-service.d.ts.map +1 -1
  103. package/out/zero-cache/src/services/change-streamer/change-streamer-service.js +7 -10
  104. package/out/zero-cache/src/services/change-streamer/change-streamer-service.js.map +1 -1
  105. package/out/zero-cache/src/services/change-streamer/replica-monitor.js +2 -2
  106. package/out/zero-cache/src/services/change-streamer/storer.d.ts +2 -19
  107. package/out/zero-cache/src/services/change-streamer/storer.d.ts.map +1 -1
  108. package/out/zero-cache/src/services/change-streamer/storer.js +5 -69
  109. package/out/zero-cache/src/services/change-streamer/storer.js.map +1 -1
  110. package/out/zero-cache/src/services/heapz.d.ts.map +1 -1
  111. package/out/zero-cache/src/services/heapz.js +1 -1
  112. package/out/zero-cache/src/services/heapz.js.map +1 -1
  113. package/out/zero-cache/src/services/life-cycle.d.ts +1 -2
  114. package/out/zero-cache/src/services/life-cycle.d.ts.map +1 -1
  115. package/out/zero-cache/src/services/life-cycle.js +7 -10
  116. package/out/zero-cache/src/services/life-cycle.js.map +1 -1
  117. package/out/zero-cache/src/services/litestream/commands.d.ts +4 -15
  118. package/out/zero-cache/src/services/litestream/commands.d.ts.map +1 -1
  119. package/out/zero-cache/src/services/litestream/commands.js +31 -31
  120. package/out/zero-cache/src/services/litestream/commands.js.map +1 -1
  121. package/out/zero-cache/src/services/mutagen/mutagen.js +1 -1
  122. package/out/zero-cache/src/services/mutagen/pusher.d.ts +28 -28
  123. package/out/zero-cache/src/services/replicator/change-processor.js +2 -2
  124. package/out/zero-cache/src/services/replicator/incremental-sync.js +1 -1
  125. package/out/zero-cache/src/services/replicator/schema/replication-state.js +1 -1
  126. package/out/zero-cache/src/services/replicator/write-worker-client.js.map +1 -1
  127. package/out/zero-cache/src/services/replicator/write-worker.js +3 -3
  128. package/out/zero-cache/src/services/replicator/write-worker.js.map +1 -1
  129. package/out/zero-cache/src/services/run-ast.d.ts.map +1 -1
  130. package/out/zero-cache/src/services/run-ast.js +2 -2
  131. package/out/zero-cache/src/services/run-ast.js.map +1 -1
  132. package/out/zero-cache/src/services/statz.d.ts.map +1 -1
  133. package/out/zero-cache/src/services/statz.js +2 -2
  134. package/out/zero-cache/src/services/statz.js.map +1 -1
  135. package/out/zero-cache/src/services/view-syncer/active-users-gauge.js +1 -1
  136. package/out/zero-cache/src/services/view-syncer/connection-context-manager.d.ts +2 -2
  137. package/out/zero-cache/src/services/view-syncer/connection-context-manager.d.ts.map +1 -1
  138. package/out/zero-cache/src/services/view-syncer/connection-context-manager.js.map +1 -1
  139. package/out/zero-cache/src/services/view-syncer/cvr-purger.js +1 -1
  140. package/out/zero-cache/src/services/view-syncer/cvr-store.js +2 -2
  141. package/out/zero-cache/src/services/view-syncer/cvr-store.js.map +1 -1
  142. package/out/zero-cache/src/services/view-syncer/inspect-handler.js +1 -1
  143. package/out/zero-cache/src/services/view-syncer/pipeline-driver.d.ts +16 -6
  144. package/out/zero-cache/src/services/view-syncer/pipeline-driver.d.ts.map +1 -1
  145. package/out/zero-cache/src/services/view-syncer/pipeline-driver.js +37 -29
  146. package/out/zero-cache/src/services/view-syncer/pipeline-driver.js.map +1 -1
  147. package/out/zero-cache/src/services/view-syncer/row-record-cache.d.ts.map +1 -1
  148. package/out/zero-cache/src/services/view-syncer/row-record-cache.js +3 -3
  149. package/out/zero-cache/src/services/view-syncer/row-record-cache.js.map +1 -1
  150. package/out/zero-cache/src/services/view-syncer/snapshotter.js +2 -2
  151. package/out/zero-cache/src/services/view-syncer/view-syncer.d.ts.map +1 -1
  152. package/out/zero-cache/src/services/view-syncer/view-syncer.js +6 -6
  153. package/out/zero-cache/src/services/view-syncer/view-syncer.js.map +1 -1
  154. package/out/zero-cache/src/types/profiler.d.ts.map +1 -1
  155. package/out/zero-cache/src/types/profiler.js.map +1 -1
  156. package/out/zero-cache/src/types/row-key.d.ts.map +1 -1
  157. package/out/zero-cache/src/types/row-key.js.map +1 -1
  158. package/out/zero-cache/src/types/streams.d.ts +1 -1
  159. package/out/zero-cache/src/types/streams.d.ts.map +1 -1
  160. package/out/zero-cache/src/types/streams.js.map +1 -1
  161. package/out/zero-cache/src/types/websocket-handoff.d.ts +1 -1
  162. package/out/zero-cache/src/types/websocket-handoff.d.ts.map +1 -1
  163. package/out/zero-cache/src/types/websocket-handoff.js.map +1 -1
  164. package/out/zero-cache/src/workers/connection.d.ts +1 -1
  165. package/out/zero-cache/src/workers/connection.d.ts.map +1 -1
  166. package/out/zero-cache/src/workers/connection.js.map +1 -1
  167. package/out/zero-cache/src/workers/mutator.js.map +1 -1
  168. package/out/zero-cache/src/workers/syncer.d.ts +1 -1
  169. package/out/zero-cache/src/workers/syncer.d.ts.map +1 -1
  170. package/out/zero-cache/src/workers/syncer.js +2 -2
  171. package/out/zero-cache/src/workers/syncer.js.map +1 -1
  172. package/out/zero-client/src/client/crud-impl.d.ts.map +1 -1
  173. package/out/zero-client/src/client/crud-impl.js +13 -4
  174. package/out/zero-client/src/client/crud-impl.js.map +1 -1
  175. package/out/zero-client/src/client/ivm-branch.d.ts.map +1 -1
  176. package/out/zero-client/src/client/ivm-branch.js +13 -4
  177. package/out/zero-client/src/client/ivm-branch.js.map +1 -1
  178. package/out/zero-client/src/client/version.js +1 -1
  179. package/out/zero-protocol/src/error.d.ts.map +1 -1
  180. package/out/zero-protocol/src/error.js +1 -1
  181. package/out/zero-protocol/src/error.js.map +1 -1
  182. package/out/zero-solid/src/solid-view.d.ts.map +1 -1
  183. package/out/zero-solid/src/solid-view.js +13 -13
  184. package/out/zero-solid/src/solid-view.js.map +1 -1
  185. package/out/zql/src/builder/builder.d.ts.map +1 -1
  186. package/out/zql/src/builder/builder.js.map +1 -1
  187. package/out/zql/src/ivm/array-view.d.ts.map +1 -1
  188. package/out/zql/src/ivm/array-view.js +1 -26
  189. package/out/zql/src/ivm/array-view.js.map +1 -1
  190. package/out/zql/src/ivm/change.d.ts +22 -20
  191. package/out/zql/src/ivm/change.d.ts.map +1 -1
  192. package/out/zql/src/ivm/exists.d.ts.map +1 -1
  193. package/out/zql/src/ivm/exists.js +38 -27
  194. package/out/zql/src/ivm/exists.js.map +1 -1
  195. package/out/zql/src/ivm/fan-in.d.ts +2 -3
  196. package/out/zql/src/ivm/fan-in.d.ts.map +1 -1
  197. package/out/zql/src/ivm/fan-in.js.map +1 -1
  198. package/out/zql/src/ivm/fan-out.d.ts +1 -1
  199. package/out/zql/src/ivm/fan-out.d.ts.map +1 -1
  200. package/out/zql/src/ivm/fan-out.js +1 -1
  201. package/out/zql/src/ivm/fan-out.js.map +1 -1
  202. package/out/zql/src/ivm/filter-operators.d.ts +3 -3
  203. package/out/zql/src/ivm/filter-operators.d.ts.map +1 -1
  204. package/out/zql/src/ivm/filter-operators.js.map +1 -1
  205. package/out/zql/src/ivm/filter-push.d.ts.map +1 -1
  206. package/out/zql/src/ivm/filter-push.js +7 -7
  207. package/out/zql/src/ivm/filter-push.js.map +1 -1
  208. package/out/zql/src/ivm/filter.d.ts +1 -1
  209. package/out/zql/src/ivm/filter.d.ts.map +1 -1
  210. package/out/zql/src/ivm/filter.js.map +1 -1
  211. package/out/zql/src/ivm/flipped-join.d.ts.map +1 -1
  212. package/out/zql/src/ivm/flipped-join.js +58 -49
  213. package/out/zql/src/ivm/flipped-join.js.map +1 -1
  214. package/out/zql/src/ivm/join-utils.d.ts +6 -2
  215. package/out/zql/src/ivm/join-utils.d.ts.map +1 -1
  216. package/out/zql/src/ivm/join-utils.js +25 -25
  217. package/out/zql/src/ivm/join-utils.js.map +1 -1
  218. package/out/zql/src/ivm/join.d.ts.map +1 -1
  219. package/out/zql/src/ivm/join.js +51 -32
  220. package/out/zql/src/ivm/join.js.map +1 -1
  221. package/out/zql/src/ivm/maybe-split-and-push-edit-change.d.ts +1 -1
  222. package/out/zql/src/ivm/maybe-split-and-push-edit-change.d.ts.map +1 -1
  223. package/out/zql/src/ivm/maybe-split-and-push-edit-change.js +10 -5
  224. package/out/zql/src/ivm/maybe-split-and-push-edit-change.js.map +1 -1
  225. package/out/zql/src/ivm/memory-source.d.ts.map +1 -1
  226. package/out/zql/src/ivm/memory-source.js +59 -51
  227. package/out/zql/src/ivm/memory-source.js.map +1 -1
  228. package/out/zql/src/ivm/push-accumulated.d.ts +2 -3
  229. package/out/zql/src/ivm/push-accumulated.d.ts.map +1 -1
  230. package/out/zql/src/ivm/push-accumulated.js +122 -98
  231. package/out/zql/src/ivm/push-accumulated.js.map +1 -1
  232. package/out/zql/src/ivm/skip.d.ts +1 -1
  233. package/out/zql/src/ivm/skip.d.ts.map +1 -1
  234. package/out/zql/src/ivm/skip.js +2 -2
  235. package/out/zql/src/ivm/skip.js.map +1 -1
  236. package/out/zql/src/ivm/source.d.ts +13 -11
  237. package/out/zql/src/ivm/source.d.ts.map +1 -1
  238. package/out/zql/src/ivm/take.d.ts.map +1 -1
  239. package/out/zql/src/ivm/take.js +50 -27
  240. package/out/zql/src/ivm/take.js.map +1 -1
  241. package/out/zql/src/ivm/union-fan-in.d.ts +1 -2
  242. package/out/zql/src/ivm/union-fan-in.d.ts.map +1 -1
  243. package/out/zql/src/ivm/union-fan-in.js +3 -3
  244. package/out/zql/src/ivm/union-fan-in.js.map +1 -1
  245. package/out/zql/src/ivm/union-fan-out.d.ts.map +1 -1
  246. package/out/zql/src/ivm/union-fan-out.js +1 -1
  247. package/out/zql/src/ivm/union-fan-out.js.map +1 -1
  248. package/out/zql/src/planner/planner-debug.d.ts +2 -2
  249. package/out/zql/src/planner/planner-debug.d.ts.map +1 -1
  250. package/out/zql/src/planner/planner-debug.js.map +1 -1
  251. package/out/zql/src/planner/planner-graph.d.ts +1 -1
  252. package/out/zql/src/planner/planner-graph.d.ts.map +1 -1
  253. package/out/zql/src/planner/planner-graph.js.map +1 -1
  254. package/out/zqlite/src/internal/sql-inline.d.ts.map +1 -1
  255. package/out/zqlite/src/internal/sql-inline.js.map +1 -1
  256. package/out/zqlite/src/query-builder.d.ts.map +1 -1
  257. package/out/zqlite/src/query-builder.js.map +1 -1
  258. package/out/zqlite/src/table-source.d.ts.map +1 -1
  259. package/out/zqlite/src/table-source.js +11 -11
  260. package/out/zqlite/src/table-source.js.map +1 -1
  261. package/package.json +93 -95
  262. package/out/zql/src/ivm/change-index-enum.d.ts +0 -9
  263. package/out/zql/src/ivm/change-index-enum.d.ts.map +0 -1
  264. package/out/zql/src/ivm/change-index.d.ts +0 -5
  265. package/out/zql/src/ivm/change-index.d.ts.map +0 -1
  266. package/out/zql/src/ivm/change-type-enum.d.ts +0 -9
  267. package/out/zql/src/ivm/change-type-enum.d.ts.map +0 -1
  268. package/out/zql/src/ivm/change-type.d.ts +0 -5
  269. package/out/zql/src/ivm/change-type.d.ts.map +0 -1
  270. package/out/zql/src/ivm/change.js +0 -33
  271. package/out/zql/src/ivm/change.js.map +0 -1
  272. package/out/zql/src/ivm/source-change-index-enum.d.ts +0 -7
  273. package/out/zql/src/ivm/source-change-index-enum.d.ts.map +0 -1
  274. package/out/zql/src/ivm/source-change-index.d.ts +0 -5
  275. package/out/zql/src/ivm/source-change-index.d.ts.map +0 -1
  276. package/out/zql/src/ivm/source.js +0 -26
  277. package/out/zql/src/ivm/source.js.map +0 -1
@@ -1,6 +1,5 @@
1
1
  import { assert, unreachable } from "../../../shared/src/asserts.js";
2
2
  import { areEqual } from "../../../shared/src/arrays.js";
3
- import { makeAddChange, makeRemoveChange } from "./change.js";
4
3
  import { normalizeUndefined } from "./data.js";
5
4
  import { throwFilterOutput } from "./filter-operators.js";
6
5
  //#region ../zql/src/ivm/exists.ts
@@ -69,41 +68,53 @@ var Exists = class {
69
68
  assert(!this.#inPush, "Unexpected re-entrancy");
70
69
  this.#inPush = true;
71
70
  try {
72
- switch (change[0]) {
73
- case 0:
74
- case 2:
75
- case 1:
71
+ switch (change.type) {
72
+ case "add":
73
+ case "edit":
74
+ case "remove":
76
75
  yield* this.#pushWithFilter(change);
77
76
  return;
78
- case 3:
79
- if (change[2].relationshipName !== this.#relationshipName || change[2].change[0] === 2 || change[2].change[0] === 3) {
77
+ case "child":
78
+ if (change.child.relationshipName !== this.#relationshipName || change.child.change.type === "edit" || change.child.change.type === "child") {
80
79
  yield* this.#pushWithFilter(change);
81
80
  return;
82
81
  }
83
- switch (change[2].change[0]) {
84
- case 0: {
85
- const size = yield* this.#fetchSize(change[1]);
86
- if (size === 1) if (this.#not) yield* this.#output.push(makeRemoveChange({
87
- row: change[1].row,
88
- relationships: {
89
- ...change[1].relationships,
90
- [this.#relationshipName]: () => []
82
+ switch (change.child.change.type) {
83
+ case "add": {
84
+ const size = yield* this.#fetchSize(change.node);
85
+ if (size === 1) if (this.#not) yield* this.#output.push({
86
+ type: "remove",
87
+ node: {
88
+ row: change.node.row,
89
+ relationships: {
90
+ ...change.node.relationships,
91
+ [this.#relationshipName]: () => []
92
+ }
91
93
  }
92
- }), this);
93
- else yield* this.#output.push(makeAddChange(change[1]), this);
94
+ }, this);
95
+ else yield* this.#output.push({
96
+ type: "add",
97
+ node: change.node
98
+ }, this);
94
99
  else yield* this.#pushWithFilter(change, size > 0);
95
100
  return;
96
101
  }
97
- case 1: {
98
- const size = yield* this.#fetchSize(change[1]);
99
- if (size === 0) if (this.#not) yield* this.#output.push(makeAddChange(change[1]), this);
100
- else yield* this.#output.push(makeRemoveChange({
101
- row: change[1].row,
102
- relationships: {
103
- ...change[1].relationships,
104
- [this.#relationshipName]: () => [change[2].change[1]]
102
+ case "remove": {
103
+ const size = yield* this.#fetchSize(change.node);
104
+ if (size === 0) if (this.#not) yield* this.#output.push({
105
+ type: "add",
106
+ node: change.node
107
+ }, this);
108
+ else yield* this.#output.push({
109
+ type: "remove",
110
+ node: {
111
+ row: change.node.row,
112
+ relationships: {
113
+ ...change.node.relationships,
114
+ [this.#relationshipName]: () => [change.child.change.node]
115
+ }
105
116
  }
106
- }), this);
117
+ }, this);
107
118
  else yield* this.#pushWithFilter(change, size > 0);
108
119
  return;
109
120
  }
@@ -137,7 +148,7 @@ var Exists = class {
137
148
  * Pushes a change if this.#filter is true for its row.
138
149
  */
139
150
  *#pushWithFilter(change, exists) {
140
- if (yield* this.#filter(change[1], exists)) yield* this.#output.push(change, this);
151
+ if (yield* this.#filter(change.node, exists)) yield* this.#output.push(change, this);
141
152
  }
142
153
  *#fetchExists(node) {
143
154
  return (yield* this.#fetchSize(node)) > 0;
@@ -1 +1 @@
1
- {"version":3,"file":"exists.js","names":["#input","#relationshipName","#not","#parentJoinKey","#noSizeReuse","#cache","#cacheHitCountsForTesting","#output","#inPush","#getCacheKey","#fetchExists","#filter","#pushWithFilter","#fetchSize"],"sources":["../../../../../zql/src/ivm/exists.ts"],"sourcesContent":["import {areEqual} from '../../../shared/src/arrays.ts';\nimport {assert, unreachable} from '../../../shared/src/asserts.ts';\nimport type {CompoundKey} from '../../../zero-protocol/src/ast.ts';\nimport {ChangeIndex} from './change-index.ts';\nimport {ChangeType} from './change-type.ts';\nimport {makeAddChange, makeRemoveChange, type Change} from './change.ts';\nimport {normalizeUndefined, type Node, type NormalizedValue} from './data.ts';\nimport {\n throwFilterOutput,\n type FilterInput,\n type FilterOperator,\n type FilterOutput,\n} from './filter-operators.ts';\nimport type {SourceSchema} from './schema.ts';\nimport {type Stream} from './stream.ts';\n\n/**\n * The Exists operator filters data based on whether or not a relationship is\n * non-empty.\n */\nexport class Exists implements FilterOperator {\n readonly #input: FilterInput;\n readonly #relationshipName: string;\n readonly #not: boolean;\n readonly #parentJoinKey: CompoundKey;\n readonly #noSizeReuse: boolean;\n #cache: Map<string, boolean>;\n #cacheHitCountsForTesting: Map<string, number> | undefined;\n #output: FilterOutput = throwFilterOutput;\n\n /**\n * This instance variable is `true` when this operator is processing a `push`,\n * and is used to disable reuse of cached sizes across rows with the\n * same parent join key value.\n * This is necessary because during a push relationships can be inconsistent\n * due to push communicating changes (which may change multiple Nodes) one\n * Node at a time.\n */\n #inPush = false;\n\n constructor(\n input: FilterInput,\n relationshipName: string,\n parentJoinKey: CompoundKey,\n type: 'EXISTS' | 'NOT EXISTS',\n cacheHitCountsForTesting?: Map<string, number>,\n ) {\n this.#input = input;\n this.#relationshipName = relationshipName;\n this.#input.setFilterOutput(this);\n this.#cache = new Map();\n this.#cacheHitCountsForTesting = cacheHitCountsForTesting;\n assert(\n this.#input.getSchema().relationships[relationshipName],\n `Input schema missing ${relationshipName}`,\n );\n this.#not = type === 'NOT EXISTS';\n this.#parentJoinKey = parentJoinKey;\n\n // If the parentJoinKey is the primary key, no sense in trying to reuse.\n this.#noSizeReuse = areEqual(\n parentJoinKey,\n this.#input.getSchema().primaryKey,\n );\n }\n\n setFilterOutput(output: FilterOutput): void {\n this.#output = output;\n }\n\n beginFilter() {\n this.#output.beginFilter();\n }\n\n endFilter() {\n this.#cache = new Map();\n this.#output.endFilter();\n }\n\n *filter(node: Node): Generator<'yield', boolean> {\n let exists: boolean | undefined;\n if (!this.#noSizeReuse && !this.#inPush) {\n const key = this.#getCacheKey(node, this.#parentJoinKey);\n exists = this.#cache.get(key);\n if (exists === undefined) {\n exists = yield* this.#fetchExists(node);\n this.#cache.set(key, exists);\n } else if (this.#cacheHitCountsForTesting) {\n this.#cacheHitCountsForTesting.set(\n key,\n (this.#cacheHitCountsForTesting.get(key) ?? 0) + 1,\n );\n }\n }\n\n const result =\n (yield* this.#filter(node, exists)) && (yield* this.#output.filter(node));\n return result;\n }\n\n destroy(): void {\n this.#input.destroy();\n }\n\n getSchema(): SourceSchema {\n return this.#input.getSchema();\n }\n\n *push(change: Change): Stream<'yield'> {\n assert(!this.#inPush, 'Unexpected re-entrancy');\n this.#inPush = true;\n try {\n switch (change[ChangeIndex.TYPE]) {\n // add, remove and edit cannot change the size of the\n // this.#relationshipName relationship, so simply #pushWithFilter\n case ChangeType.ADD:\n case ChangeType.EDIT:\n case ChangeType.REMOVE: {\n yield* this.#pushWithFilter(change);\n return;\n }\n case ChangeType.CHILD:\n // Only add and remove child changes for the\n // this.#relationshipName relationship, can change the size\n // of the this.#relationshipName relationship, for other\n // child changes simply #pushWithFilter\n if (\n change[ChangeIndex.CHILD_DATA].relationshipName !==\n this.#relationshipName ||\n change[ChangeIndex.CHILD_DATA].change[ChangeIndex.TYPE] ===\n ChangeType.EDIT ||\n change[ChangeIndex.CHILD_DATA].change[ChangeIndex.TYPE] ===\n ChangeType.CHILD\n ) {\n yield* this.#pushWithFilter(change);\n return;\n }\n switch (change[ChangeIndex.CHILD_DATA].change[ChangeIndex.TYPE]) {\n case ChangeType.ADD: {\n const size = yield* this.#fetchSize(change[ChangeIndex.NODE]);\n if (size === 1) {\n if (this.#not) {\n // Since the add child change currently being processed is not\n // pushed to output, the added child needs to be excluded from\n // the remove being pushed to output (since the child has\n // never been added to the output).\n yield* this.#output.push(\n makeRemoveChange({\n row: change[ChangeIndex.NODE].row,\n relationships: {\n ...change[ChangeIndex.NODE].relationships,\n [this.#relationshipName]: () => [],\n },\n }),\n this,\n );\n } else {\n yield* this.#output.push(\n makeAddChange(change[ChangeIndex.NODE]),\n this,\n );\n }\n } else {\n yield* this.#pushWithFilter(change, size > 0);\n }\n return;\n }\n case ChangeType.REMOVE: {\n const size = yield* this.#fetchSize(change[ChangeIndex.NODE]);\n if (size === 0) {\n if (this.#not) {\n yield* this.#output.push(\n makeAddChange(change[ChangeIndex.NODE]),\n this,\n );\n } else {\n // Since the remove child change currently being processed is\n // not pushed to output, the removed child needs to be added to\n // the remove being pushed to output.\n yield* this.#output.push(\n makeRemoveChange({\n row: change[ChangeIndex.NODE].row,\n relationships: {\n ...change[ChangeIndex.NODE].relationships,\n [this.#relationshipName]: () => [\n change[ChangeIndex.CHILD_DATA].change[\n ChangeIndex.NODE\n ],\n ],\n },\n }),\n this,\n );\n }\n } else {\n yield* this.#pushWithFilter(change, size > 0);\n }\n return;\n }\n }\n return;\n default:\n unreachable(change);\n }\n } finally {\n this.#inPush = false;\n }\n }\n\n /**\n * Returns whether or not the node's this.#relationshipName\n * relationship passes the exist/not exists filter condition.\n * If the optional `size` is passed it is used.\n * Otherwise, if there is a stored size for the row it is used.\n * Otherwise the size is computed by streaming the node's\n * relationship with this.#relationshipName (this computed size is also\n * stored).\n */\n *#filter(node: Node, exists?: boolean): Generator<'yield', boolean> {\n exists = exists ?? (yield* this.#fetchExists(node));\n return this.#not ? !exists : exists;\n }\n\n #getCacheKey(node: Node, def: CompoundKey): string {\n const values: NormalizedValue[] = [];\n for (const key of def) {\n values.push(normalizeUndefined(node.row[key]));\n }\n return JSON.stringify(values);\n }\n\n /**\n * Pushes a change if this.#filter is true for its row.\n */\n *#pushWithFilter(change: Change, exists?: boolean): Stream<'yield'> {\n if (yield* this.#filter(change[ChangeIndex.NODE], exists)) {\n yield* this.#output.push(change, this);\n }\n }\n\n *#fetchExists(node: Node): Generator<'yield', boolean> {\n // While it seems like this should be able to fetch just 1 node\n // to check for exists, we can't because Take does not support\n // early return during initial fetch.\n return (yield* this.#fetchSize(node)) > 0;\n }\n\n *#fetchSize(node: Node): Generator<'yield', number> {\n const relationship = node.relationships[this.#relationshipName];\n assert(\n relationship,\n () =>\n `Exists: relationship \"${this.#relationshipName}\" not found on node`,\n );\n let size = 0;\n for (const n of relationship()) {\n if (n === 'yield') {\n yield 'yield';\n } else {\n size++;\n }\n }\n return size;\n }\n}\n"],"mappings":";;;;;;;;;;AAoBA,IAAa,SAAb,MAA8C;CAC5C;CACA;CACA;CACA;CACA;CACA;CACA;CACA,UAAwB;;;;;;;;;CAUxB,UAAU;CAEV,YACE,OACA,kBACA,eACA,MACA,0BACA;AACA,QAAA,QAAc;AACd,QAAA,mBAAyB;AACzB,QAAA,MAAY,gBAAgB,KAAK;AACjC,QAAA,wBAAc,IAAI,KAAK;AACvB,QAAA,2BAAiC;AACjC,SACE,MAAA,MAAY,WAAW,CAAC,cAAc,mBACtC,wBAAwB,mBACzB;AACD,QAAA,MAAY,SAAS;AACrB,QAAA,gBAAsB;AAGtB,QAAA,cAAoB,SAClB,eACA,MAAA,MAAY,WAAW,CAAC,WACzB;;CAGH,gBAAgB,QAA4B;AAC1C,QAAA,SAAe;;CAGjB,cAAc;AACZ,QAAA,OAAa,aAAa;;CAG5B,YAAY;AACV,QAAA,wBAAc,IAAI,KAAK;AACvB,QAAA,OAAa,WAAW;;CAG1B,CAAC,OAAO,MAAyC;EAC/C,IAAI;AACJ,MAAI,CAAC,MAAA,eAAqB,CAAC,MAAA,QAAc;GACvC,MAAM,MAAM,MAAA,YAAkB,MAAM,MAAA,cAAoB;AACxD,YAAS,MAAA,MAAY,IAAI,IAAI;AAC7B,OAAI,WAAW,KAAA,GAAW;AACxB,aAAS,OAAO,MAAA,YAAkB,KAAK;AACvC,UAAA,MAAY,IAAI,KAAK,OAAO;cACnB,MAAA,yBACT,OAAA,yBAA+B,IAC7B,MACC,MAAA,yBAA+B,IAAI,IAAI,IAAI,KAAK,EAClD;;AAML,UADG,OAAO,MAAA,OAAa,MAAM,OAAO,MAAM,OAAO,MAAA,OAAa,OAAO,KAAK;;CAI5E,UAAgB;AACd,QAAA,MAAY,SAAS;;CAGvB,YAA0B;AACxB,SAAO,MAAA,MAAY,WAAW;;CAGhC,CAAC,KAAK,QAAiC;AACrC,SAAO,CAAC,MAAA,QAAc,yBAAyB;AAC/C,QAAA,SAAe;AACf,MAAI;AACF,WAAQ,OAAO,IAAf;IAGE,KAAK;IACL,KAAK;IACL,KAAK;AACH,YAAO,MAAA,eAAqB,OAAO;AACnC;IAEF,KAAK;AAKH,SACE,OAAO,GAAwB,qBAC7B,MAAA,oBACF,OAAO,GAAwB,OAAO,OACpC,KACF,OAAO,GAAwB,OAAO,OACpC,GACF;AACA,aAAO,MAAA,eAAqB,OAAO;AACnC;;AAEF,aAAQ,OAAO,GAAwB,OAAO,IAA9C;MACE,KAAK,GAAgB;OACnB,MAAM,OAAO,OAAO,MAAA,UAAgB,OAAO,GAAkB;AAC7D,WAAI,SAAS,EACX,KAAI,MAAA,IAKF,QAAO,MAAA,OAAa,KAClB,iBAAiB;QACf,KAAK,OAAO,GAAkB;QAC9B,eAAe;SACb,GAAG,OAAO,GAAkB;UAC3B,MAAA,yBAA+B,EAAE;SACnC;QACF,CAAC,EACF,KACD;WAED,QAAO,MAAA,OAAa,KAClB,cAAc,OAAO,GAAkB,EACvC,KACD;WAGH,QAAO,MAAA,eAAqB,QAAQ,OAAO,EAAE;AAE/C;;MAEF,KAAK,GAAmB;OACtB,MAAM,OAAO,OAAO,MAAA,UAAgB,OAAO,GAAkB;AAC7D,WAAI,SAAS,EACX,KAAI,MAAA,IACF,QAAO,MAAA,OAAa,KAClB,cAAc,OAAO,GAAkB,EACvC,KACD;WAKD,QAAO,MAAA,OAAa,KAClB,iBAAiB;QACf,KAAK,OAAO,GAAkB;QAC9B,eAAe;SACb,GAAG,OAAO,GAAkB;UAC3B,MAAA,yBAA+B,CAC9B,OAAO,GAAwB,OAC7B,GAEH;SACF;QACF,CAAC,EACF,KACD;WAGH,QAAO,MAAA,eAAqB,QAAQ,OAAO,EAAE;AAE/C;;;AAGJ;IACF,QACE,aAAY,OAAO;;YAEf;AACR,SAAA,SAAe;;;;;;;;;;;;CAanB,EAAA,OAAS,MAAY,QAA+C;AAClE,WAAS,WAAW,OAAO,MAAA,YAAkB,KAAK;AAClD,SAAO,MAAA,MAAY,CAAC,SAAS;;CAG/B,aAAa,MAAY,KAA0B;EACjD,MAAM,SAA4B,EAAE;AACpC,OAAK,MAAM,OAAO,IAChB,QAAO,KAAK,mBAAmB,KAAK,IAAI,KAAK,CAAC;AAEhD,SAAO,KAAK,UAAU,OAAO;;;;;CAM/B,EAAA,eAAiB,QAAgB,QAAmC;AAClE,MAAI,OAAO,MAAA,OAAa,OAAO,IAAmB,OAAO,CACvD,QAAO,MAAA,OAAa,KAAK,QAAQ,KAAK;;CAI1C,EAAA,YAAc,MAAyC;AAIrD,UAAQ,OAAO,MAAA,UAAgB,KAAK,IAAI;;CAG1C,EAAA,UAAY,MAAwC;EAClD,MAAM,eAAe,KAAK,cAAc,MAAA;AACxC,SACE,oBAEE,yBAAyB,MAAA,iBAAuB,qBACnD;EACD,IAAI,OAAO;AACX,OAAK,MAAM,KAAK,cAAc,CAC5B,KAAI,MAAM,QACR,OAAM;MAEN;AAGJ,SAAO"}
1
+ {"version":3,"file":"exists.js","names":["#input","#relationshipName","#not","#parentJoinKey","#noSizeReuse","#cache","#cacheHitCountsForTesting","#output","#inPush","#getCacheKey","#fetchExists","#filter","#pushWithFilter","#fetchSize"],"sources":["../../../../../zql/src/ivm/exists.ts"],"sourcesContent":["import {areEqual} from '../../../shared/src/arrays.ts';\nimport {assert, unreachable} from '../../../shared/src/asserts.ts';\nimport type {CompoundKey} from '../../../zero-protocol/src/ast.ts';\nimport {type Change} from './change.ts';\nimport {normalizeUndefined, type Node, type NormalizedValue} from './data.ts';\nimport {\n throwFilterOutput,\n type FilterInput,\n type FilterOperator,\n type FilterOutput,\n} from './filter-operators.ts';\nimport type {SourceSchema} from './schema.ts';\nimport {type Stream} from './stream.ts';\n\n/**\n * The Exists operator filters data based on whether or not a relationship is\n * non-empty.\n */\nexport class Exists implements FilterOperator {\n readonly #input: FilterInput;\n readonly #relationshipName: string;\n readonly #not: boolean;\n readonly #parentJoinKey: CompoundKey;\n readonly #noSizeReuse: boolean;\n #cache: Map<string, boolean>;\n #cacheHitCountsForTesting: Map<string, number> | undefined;\n #output: FilterOutput = throwFilterOutput;\n\n /**\n * This instance variable is `true` when this operator is processing a `push`,\n * and is used to disable reuse of cached sizes across rows with the\n * same parent join key value.\n * This is necessary because during a push relationships can be inconsistent\n * due to push communicating changes (which may change multiple Nodes) one\n * Node at a time.\n */\n #inPush = false;\n\n constructor(\n input: FilterInput,\n relationshipName: string,\n parentJoinKey: CompoundKey,\n type: 'EXISTS' | 'NOT EXISTS',\n cacheHitCountsForTesting?: Map<string, number>,\n ) {\n this.#input = input;\n this.#relationshipName = relationshipName;\n this.#input.setFilterOutput(this);\n this.#cache = new Map();\n this.#cacheHitCountsForTesting = cacheHitCountsForTesting;\n assert(\n this.#input.getSchema().relationships[relationshipName],\n `Input schema missing ${relationshipName}`,\n );\n this.#not = type === 'NOT EXISTS';\n this.#parentJoinKey = parentJoinKey;\n\n // If the parentJoinKey is the primary key, no sense in trying to reuse.\n this.#noSizeReuse = areEqual(\n parentJoinKey,\n this.#input.getSchema().primaryKey,\n );\n }\n\n setFilterOutput(output: FilterOutput): void {\n this.#output = output;\n }\n\n beginFilter() {\n this.#output.beginFilter();\n }\n\n endFilter() {\n this.#cache = new Map();\n this.#output.endFilter();\n }\n\n *filter(node: Node): Generator<'yield', boolean> {\n let exists: boolean | undefined;\n if (!this.#noSizeReuse && !this.#inPush) {\n const key = this.#getCacheKey(node, this.#parentJoinKey);\n exists = this.#cache.get(key);\n if (exists === undefined) {\n exists = yield* this.#fetchExists(node);\n this.#cache.set(key, exists);\n } else if (this.#cacheHitCountsForTesting) {\n this.#cacheHitCountsForTesting.set(\n key,\n (this.#cacheHitCountsForTesting.get(key) ?? 0) + 1,\n );\n }\n }\n\n const result =\n (yield* this.#filter(node, exists)) && (yield* this.#output.filter(node));\n return result;\n }\n\n destroy(): void {\n this.#input.destroy();\n }\n\n getSchema(): SourceSchema {\n return this.#input.getSchema();\n }\n\n *push(change: Change): Stream<'yield'> {\n assert(!this.#inPush, 'Unexpected re-entrancy');\n this.#inPush = true;\n try {\n switch (change.type) {\n // add, remove and edit cannot change the size of the\n // this.#relationshipName relationship, so simply #pushWithFilter\n case 'add':\n case 'edit':\n case 'remove': {\n yield* this.#pushWithFilter(change);\n return;\n }\n case 'child':\n // Only add and remove child changes for the\n // this.#relationshipName relationship, can change the size\n // of the this.#relationshipName relationship, for other\n // child changes simply #pushWithFilter\n if (\n change.child.relationshipName !== this.#relationshipName ||\n change.child.change.type === 'edit' ||\n change.child.change.type === 'child'\n ) {\n yield* this.#pushWithFilter(change);\n return;\n }\n switch (change.child.change.type) {\n case 'add': {\n const size = yield* this.#fetchSize(change.node);\n if (size === 1) {\n if (this.#not) {\n // Since the add child change currently being processed is not\n // pushed to output, the added child needs to be excluded from\n // the remove being pushed to output (since the child has\n // never been added to the output).\n yield* this.#output.push(\n {\n type: 'remove',\n node: {\n row: change.node.row,\n relationships: {\n ...change.node.relationships,\n [this.#relationshipName]: () => [],\n },\n },\n },\n this,\n );\n } else {\n yield* this.#output.push(\n {\n type: 'add',\n node: change.node,\n },\n this,\n );\n }\n } else {\n yield* this.#pushWithFilter(change, size > 0);\n }\n return;\n }\n case 'remove': {\n const size = yield* this.#fetchSize(change.node);\n if (size === 0) {\n if (this.#not) {\n yield* this.#output.push(\n {\n type: 'add',\n node: change.node,\n },\n this,\n );\n } else {\n // Since the remove child change currently being processed is\n // not pushed to output, the removed child needs to be added to\n // the remove being pushed to output.\n yield* this.#output.push(\n {\n type: 'remove',\n node: {\n row: change.node.row,\n relationships: {\n ...change.node.relationships,\n [this.#relationshipName]: () => [\n change.child.change.node,\n ],\n },\n },\n },\n this,\n );\n }\n } else {\n yield* this.#pushWithFilter(change, size > 0);\n }\n return;\n }\n }\n return;\n default:\n unreachable(change);\n }\n } finally {\n this.#inPush = false;\n }\n }\n\n /**\n * Returns whether or not the node's this.#relationshipName\n * relationship passes the exist/not exists filter condition.\n * If the optional `size` is passed it is used.\n * Otherwise, if there is a stored size for the row it is used.\n * Otherwise the size is computed by streaming the node's\n * relationship with this.#relationshipName (this computed size is also\n * stored).\n */\n *#filter(node: Node, exists?: boolean): Generator<'yield', boolean> {\n exists = exists ?? (yield* this.#fetchExists(node));\n return this.#not ? !exists : exists;\n }\n\n #getCacheKey(node: Node, def: CompoundKey): string {\n const values: NormalizedValue[] = [];\n for (const key of def) {\n values.push(normalizeUndefined(node.row[key]));\n }\n return JSON.stringify(values);\n }\n\n /**\n * Pushes a change if this.#filter is true for its row.\n */\n *#pushWithFilter(change: Change, exists?: boolean): Stream<'yield'> {\n if (yield* this.#filter(change.node, exists)) {\n yield* this.#output.push(change, this);\n }\n }\n\n *#fetchExists(node: Node): Generator<'yield', boolean> {\n // While it seems like this should be able to fetch just 1 node\n // to check for exists, we can't because Take does not support\n // early return during initial fetch.\n return (yield* this.#fetchSize(node)) > 0;\n }\n\n *#fetchSize(node: Node): Generator<'yield', number> {\n const relationship = node.relationships[this.#relationshipName];\n assert(\n relationship,\n () =>\n `Exists: relationship \"${this.#relationshipName}\" not found on node`,\n );\n let size = 0;\n for (const n of relationship()) {\n if (n === 'yield') {\n yield 'yield';\n } else {\n size++;\n }\n }\n return size;\n }\n}\n"],"mappings":";;;;;;;;;AAkBA,IAAa,SAAb,MAA8C;CAC5C;CACA;CACA;CACA;CACA;CACA;CACA;CACA,UAAwB;;;;;;;;;CAUxB,UAAU;CAEV,YACE,OACA,kBACA,eACA,MACA,0BACA;AACA,QAAA,QAAc;AACd,QAAA,mBAAyB;AACzB,QAAA,MAAY,gBAAgB,KAAK;AACjC,QAAA,wBAAc,IAAI,KAAK;AACvB,QAAA,2BAAiC;AACjC,SACE,MAAA,MAAY,WAAW,CAAC,cAAc,mBACtC,wBAAwB,mBACzB;AACD,QAAA,MAAY,SAAS;AACrB,QAAA,gBAAsB;AAGtB,QAAA,cAAoB,SAClB,eACA,MAAA,MAAY,WAAW,CAAC,WACzB;;CAGH,gBAAgB,QAA4B;AAC1C,QAAA,SAAe;;CAGjB,cAAc;AACZ,QAAA,OAAa,aAAa;;CAG5B,YAAY;AACV,QAAA,wBAAc,IAAI,KAAK;AACvB,QAAA,OAAa,WAAW;;CAG1B,CAAC,OAAO,MAAyC;EAC/C,IAAI;AACJ,MAAI,CAAC,MAAA,eAAqB,CAAC,MAAA,QAAc;GACvC,MAAM,MAAM,MAAA,YAAkB,MAAM,MAAA,cAAoB;AACxD,YAAS,MAAA,MAAY,IAAI,IAAI;AAC7B,OAAI,WAAW,KAAA,GAAW;AACxB,aAAS,OAAO,MAAA,YAAkB,KAAK;AACvC,UAAA,MAAY,IAAI,KAAK,OAAO;cACnB,MAAA,yBACT,OAAA,yBAA+B,IAC7B,MACC,MAAA,yBAA+B,IAAI,IAAI,IAAI,KAAK,EAClD;;AAML,UADG,OAAO,MAAA,OAAa,MAAM,OAAO,MAAM,OAAO,MAAA,OAAa,OAAO,KAAK;;CAI5E,UAAgB;AACd,QAAA,MAAY,SAAS;;CAGvB,YAA0B;AACxB,SAAO,MAAA,MAAY,WAAW;;CAGhC,CAAC,KAAK,QAAiC;AACrC,SAAO,CAAC,MAAA,QAAc,yBAAyB;AAC/C,QAAA,SAAe;AACf,MAAI;AACF,WAAQ,OAAO,MAAf;IAGE,KAAK;IACL,KAAK;IACL,KAAK;AACH,YAAO,MAAA,eAAqB,OAAO;AACnC;IAEF,KAAK;AAKH,SACE,OAAO,MAAM,qBAAqB,MAAA,oBAClC,OAAO,MAAM,OAAO,SAAS,UAC7B,OAAO,MAAM,OAAO,SAAS,SAC7B;AACA,aAAO,MAAA,eAAqB,OAAO;AACnC;;AAEF,aAAQ,OAAO,MAAM,OAAO,MAA5B;MACE,KAAK,OAAO;OACV,MAAM,OAAO,OAAO,MAAA,UAAgB,OAAO,KAAK;AAChD,WAAI,SAAS,EACX,KAAI,MAAA,IAKF,QAAO,MAAA,OAAa,KAClB;QACE,MAAM;QACN,MAAM;SACJ,KAAK,OAAO,KAAK;SACjB,eAAe;UACb,GAAG,OAAO,KAAK;WACd,MAAA,yBAA+B,EAAE;UACnC;SACF;QACF,EACD,KACD;WAED,QAAO,MAAA,OAAa,KAClB;QACE,MAAM;QACN,MAAM,OAAO;QACd,EACD,KACD;WAGH,QAAO,MAAA,eAAqB,QAAQ,OAAO,EAAE;AAE/C;;MAEF,KAAK,UAAU;OACb,MAAM,OAAO,OAAO,MAAA,UAAgB,OAAO,KAAK;AAChD,WAAI,SAAS,EACX,KAAI,MAAA,IACF,QAAO,MAAA,OAAa,KAClB;QACE,MAAM;QACN,MAAM,OAAO;QACd,EACD,KACD;WAKD,QAAO,MAAA,OAAa,KAClB;QACE,MAAM;QACN,MAAM;SACJ,KAAK,OAAO,KAAK;SACjB,eAAe;UACb,GAAG,OAAO,KAAK;WACd,MAAA,yBAA+B,CAC9B,OAAO,MAAM,OAAO,KACrB;UACF;SACF;QACF,EACD,KACD;WAGH,QAAO,MAAA,eAAqB,QAAQ,OAAO,EAAE;AAE/C;;;AAGJ;IACF,QACE,aAAY,OAAO;;YAEf;AACR,SAAA,SAAe;;;;;;;;;;;;CAanB,EAAA,OAAS,MAAY,QAA+C;AAClE,WAAS,WAAW,OAAO,MAAA,YAAkB,KAAK;AAClD,SAAO,MAAA,MAAY,CAAC,SAAS;;CAG/B,aAAa,MAAY,KAA0B;EACjD,MAAM,SAA4B,EAAE;AACpC,OAAK,MAAM,OAAO,IAChB,QAAO,KAAK,mBAAmB,KAAK,IAAI,KAAK,CAAC;AAEhD,SAAO,KAAK,UAAU,OAAO;;;;;CAM/B,EAAA,eAAiB,QAAgB,QAAmC;AAClE,MAAI,OAAO,MAAA,OAAa,OAAO,MAAM,OAAO,CAC1C,QAAO,MAAA,OAAa,KAAK,QAAQ,KAAK;;CAI1C,EAAA,YAAc,MAAyC;AAIrD,UAAQ,OAAO,MAAA,UAAgB,KAAK,IAAI;;CAG1C,EAAA,UAAY,MAAwC;EAClD,MAAM,eAAe,KAAK,cAAc,MAAA;AACxC,SACE,oBAEE,yBAAyB,MAAA,iBAAuB,qBACnD;EACD,IAAI,OAAO;AACX,OAAK,MAAM,KAAK,cAAc,CAC5B,KAAI,MAAM,QACR,OAAM;MAEN;AAGJ,SAAO"}
@@ -1,5 +1,4 @@
1
- import type { ChangeType } from './change-type.ts';
2
- import { type Change } from './change.ts';
1
+ import type { Change } from './change.ts';
3
2
  import { type Node } from './data.ts';
4
3
  import type { FanOut } from './fan-out.ts';
5
4
  import { type FilterInput, type FilterOperator, type FilterOutput } from './filter-operators.ts';
@@ -28,6 +27,6 @@ export declare class FanIn implements FilterOperator {
28
27
  endFilter(): void;
29
28
  filter(node: Node): Generator<'yield', boolean>;
30
29
  push(change: Change): readonly never[];
31
- fanOutDonePushingToAllBranches(fanOutChangeType: ChangeType): Generator<"yield", void, any>;
30
+ fanOutDonePushingToAllBranches(fanOutChangeType: Change['type']): Generator<"yield", void, any>;
32
31
  }
33
32
  //# sourceMappingURL=fan-in.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"fan-in.d.ts","sourceRoot":"","sources":["../../../../../zql/src/ivm/fan-in.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAC,UAAU,EAAC,MAAM,kBAAkB,CAAC;AACjD,OAAO,EAAC,KAAK,MAAM,EAAC,MAAM,aAAa,CAAC;AACxC,OAAO,EAAC,KAAK,IAAI,EAAC,MAAM,WAAW,CAAC;AACpC,OAAO,KAAK,EAAC,MAAM,EAAC,MAAM,cAAc,CAAC;AACzC,OAAO,EAEL,KAAK,WAAW,EAChB,KAAK,cAAc,EACnB,KAAK,YAAY,EAClB,MAAM,uBAAuB,CAAC;AAE/B,OAAO,KAAK,EAAC,YAAY,EAAC,MAAM,aAAa,CAAC;AAE9C;;;;;;;;;;;;;GAaG;AACH,qBAAa,KAAM,YAAW,cAAc;;gBAM9B,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE;IASjD,eAAe,CAAC,MAAM,EAAE,YAAY,GAAG,IAAI;IAI3C,OAAO,IAAI,IAAI;IAMf,SAAS;IAIT,WAAW,IAAI,IAAI;IAInB,SAAS,IAAI,IAAI;IAIhB,MAAM,CAAC,IAAI,EAAE,IAAI,GAAG,SAAS,CAAC,OAAO,EAAE,OAAO,CAAC;IAIhD,IAAI,CAAC,MAAM,EAAE,MAAM;IAKlB,8BAA8B,CAAC,gBAAgB,EAAE,UAAU;CAkB7D"}
1
+ {"version":3,"file":"fan-in.d.ts","sourceRoot":"","sources":["../../../../../zql/src/ivm/fan-in.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAC,MAAM,EAAC,MAAM,aAAa,CAAC;AACxC,OAAO,EAAC,KAAK,IAAI,EAAC,MAAM,WAAW,CAAC;AACpC,OAAO,KAAK,EAAC,MAAM,EAAC,MAAM,cAAc,CAAC;AACzC,OAAO,EAEL,KAAK,WAAW,EAChB,KAAK,cAAc,EACnB,KAAK,YAAY,EAClB,MAAM,uBAAuB,CAAC;AAE/B,OAAO,KAAK,EAAC,YAAY,EAAC,MAAM,aAAa,CAAC;AAE9C;;;;;;;;;;;;;GAaG;AACH,qBAAa,KAAM,YAAW,cAAc;;gBAM9B,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE;IASjD,eAAe,CAAC,MAAM,EAAE,YAAY,GAAG,IAAI;IAI3C,OAAO,IAAI,IAAI;IAMf,SAAS;IAIT,WAAW,IAAI,IAAI;IAInB,SAAS,IAAI,IAAI;IAIhB,MAAM,CAAC,IAAI,EAAE,IAAI,GAAG,SAAS,CAAC,OAAO,EAAE,OAAO,CAAC;IAIhD,IAAI,CAAC,MAAM,EAAE,MAAM;IAKlB,8BAA8B,CAAC,gBAAgB,EAAE,MAAM,CAAC,MAAM,CAAC;CAkBjE"}
@@ -1 +1 @@
1
- {"version":3,"file":"fan-in.js","names":["#inputs","#schema","#output","#accumulatedPushes"],"sources":["../../../../../zql/src/ivm/fan-in.ts"],"sourcesContent":["import {assert} from '../../../shared/src/asserts.ts';\nimport {emptyArray, identity} from '../../../shared/src/sentinels.ts';\nimport type {ChangeType} from './change-type.ts';\nimport {type Change} from './change.ts';\nimport {type Node} from './data.ts';\nimport type {FanOut} from './fan-out.ts';\nimport {\n throwFilterOutput,\n type FilterInput,\n type FilterOperator,\n type FilterOutput,\n} from './filter-operators.ts';\nimport {pushAccumulatedChanges} from './push-accumulated.ts';\nimport type {SourceSchema} from './schema.ts';\n\n/**\n * The FanIn operator merges multiple streams into one.\n * It eliminates duplicates and must be paired with a fan-out operator\n * somewhere upstream of the fan-in.\n *\n * issue\n * |\n * fan-out\n * / \\\n * a b\n * \\ /\n * fan-in\n * |\n */\nexport class FanIn implements FilterOperator {\n readonly #inputs: readonly FilterInput[];\n readonly #schema: SourceSchema;\n #output: FilterOutput = throwFilterOutput;\n #accumulatedPushes: Change[] = [];\n\n constructor(fanOut: FanOut, inputs: FilterInput[]) {\n this.#inputs = inputs;\n this.#schema = fanOut.getSchema();\n for (const input of inputs) {\n input.setFilterOutput(this);\n assert(this.#schema === input.getSchema(), `Schema mismatch in fan-in`);\n }\n }\n\n setFilterOutput(output: FilterOutput): void {\n this.#output = output;\n }\n\n destroy(): void {\n for (const input of this.#inputs) {\n input.destroy();\n }\n }\n\n getSchema() {\n return this.#schema;\n }\n\n beginFilter(): void {\n this.#output.beginFilter();\n }\n\n endFilter(): void {\n this.#output.endFilter();\n }\n\n *filter(node: Node): Generator<'yield', boolean> {\n return yield* this.#output.filter(node);\n }\n\n push(change: Change) {\n this.#accumulatedPushes.push(change);\n return emptyArray;\n }\n\n *fanOutDonePushingToAllBranches(fanOutChangeType: ChangeType) {\n if (this.#inputs.length === 0) {\n assert(\n this.#accumulatedPushes.length === 0,\n 'If there are no inputs then fan-in should not receive any pushes.',\n );\n return;\n }\n\n yield* pushAccumulatedChanges(\n this.#accumulatedPushes,\n this.#output,\n this,\n fanOutChangeType,\n identity,\n identity,\n );\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AA6BA,IAAa,QAAb,MAA6C;CAC3C;CACA;CACA,UAAwB;CACxB,qBAA+B,EAAE;CAEjC,YAAY,QAAgB,QAAuB;AACjD,QAAA,SAAe;AACf,QAAA,SAAe,OAAO,WAAW;AACjC,OAAK,MAAM,SAAS,QAAQ;AAC1B,SAAM,gBAAgB,KAAK;AAC3B,UAAO,MAAA,WAAiB,MAAM,WAAW,EAAE,4BAA4B;;;CAI3E,gBAAgB,QAA4B;AAC1C,QAAA,SAAe;;CAGjB,UAAgB;AACd,OAAK,MAAM,SAAS,MAAA,OAClB,OAAM,SAAS;;CAInB,YAAY;AACV,SAAO,MAAA;;CAGT,cAAoB;AAClB,QAAA,OAAa,aAAa;;CAG5B,YAAkB;AAChB,QAAA,OAAa,WAAW;;CAG1B,CAAC,OAAO,MAAyC;AAC/C,SAAO,OAAO,MAAA,OAAa,OAAO,KAAK;;CAGzC,KAAK,QAAgB;AACnB,QAAA,kBAAwB,KAAK,OAAO;AACpC,SAAO;;CAGT,CAAC,+BAA+B,kBAA8B;AAC5D,MAAI,MAAA,OAAa,WAAW,GAAG;AAC7B,UACE,MAAA,kBAAwB,WAAW,GACnC,oEACD;AACD;;AAGF,SAAO,uBACL,MAAA,mBACA,MAAA,QACA,MACA,kBACA,UACA,SACD"}
1
+ {"version":3,"file":"fan-in.js","names":["#inputs","#schema","#output","#accumulatedPushes"],"sources":["../../../../../zql/src/ivm/fan-in.ts"],"sourcesContent":["import {assert} from '../../../shared/src/asserts.ts';\nimport {emptyArray, identity} from '../../../shared/src/sentinels.ts';\nimport type {Change} from './change.ts';\nimport {type Node} from './data.ts';\nimport type {FanOut} from './fan-out.ts';\nimport {\n throwFilterOutput,\n type FilterInput,\n type FilterOperator,\n type FilterOutput,\n} from './filter-operators.ts';\nimport {pushAccumulatedChanges} from './push-accumulated.ts';\nimport type {SourceSchema} from './schema.ts';\n\n/**\n * The FanIn operator merges multiple streams into one.\n * It eliminates duplicates and must be paired with a fan-out operator\n * somewhere upstream of the fan-in.\n *\n * issue\n * |\n * fan-out\n * / \\\n * a b\n * \\ /\n * fan-in\n * |\n */\nexport class FanIn implements FilterOperator {\n readonly #inputs: readonly FilterInput[];\n readonly #schema: SourceSchema;\n #output: FilterOutput = throwFilterOutput;\n #accumulatedPushes: Change[] = [];\n\n constructor(fanOut: FanOut, inputs: FilterInput[]) {\n this.#inputs = inputs;\n this.#schema = fanOut.getSchema();\n for (const input of inputs) {\n input.setFilterOutput(this);\n assert(this.#schema === input.getSchema(), `Schema mismatch in fan-in`);\n }\n }\n\n setFilterOutput(output: FilterOutput): void {\n this.#output = output;\n }\n\n destroy(): void {\n for (const input of this.#inputs) {\n input.destroy();\n }\n }\n\n getSchema() {\n return this.#schema;\n }\n\n beginFilter(): void {\n this.#output.beginFilter();\n }\n\n endFilter(): void {\n this.#output.endFilter();\n }\n\n *filter(node: Node): Generator<'yield', boolean> {\n return yield* this.#output.filter(node);\n }\n\n push(change: Change) {\n this.#accumulatedPushes.push(change);\n return emptyArray;\n }\n\n *fanOutDonePushingToAllBranches(fanOutChangeType: Change['type']) {\n if (this.#inputs.length === 0) {\n assert(\n this.#accumulatedPushes.length === 0,\n 'If there are no inputs then fan-in should not receive any pushes.',\n );\n return;\n }\n\n yield* pushAccumulatedChanges(\n this.#accumulatedPushes,\n this.#output,\n this,\n fanOutChangeType,\n identity,\n identity,\n );\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AA4BA,IAAa,QAAb,MAA6C;CAC3C;CACA;CACA,UAAwB;CACxB,qBAA+B,EAAE;CAEjC,YAAY,QAAgB,QAAuB;AACjD,QAAA,SAAe;AACf,QAAA,SAAe,OAAO,WAAW;AACjC,OAAK,MAAM,SAAS,QAAQ;AAC1B,SAAM,gBAAgB,KAAK;AAC3B,UAAO,MAAA,WAAiB,MAAM,WAAW,EAAE,4BAA4B;;;CAI3E,gBAAgB,QAA4B;AAC1C,QAAA,SAAe;;CAGjB,UAAgB;AACd,OAAK,MAAM,SAAS,MAAA,OAClB,OAAM,SAAS;;CAInB,YAAY;AACV,SAAO,MAAA;;CAGT,cAAoB;AAClB,QAAA,OAAa,aAAa;;CAG5B,YAAkB;AAChB,QAAA,OAAa,WAAW;;CAG1B,CAAC,OAAO,MAAyC;AAC/C,SAAO,OAAO,MAAA,OAAa,OAAO,KAAK;;CAGzC,KAAK,QAAgB;AACnB,QAAA,kBAAwB,KAAK,OAAO;AACpC,SAAO;;CAGT,CAAC,+BAA+B,kBAAkC;AAChE,MAAI,MAAA,OAAa,WAAW,GAAG;AAC7B,UACE,MAAA,kBAAwB,WAAW,GACnC,oEACD;AACD;;AAGF,SAAO,uBACL,MAAA,mBACA,MAAA,QACA,MACA,kBACA,UACA,SACD"}
@@ -1,6 +1,6 @@
1
1
  import type { Change } from './change.ts';
2
- import type { Node } from './data.ts';
3
2
  import type { FanIn } from './fan-in.ts';
3
+ import type { Node } from './data.ts';
4
4
  import type { FilterInput, FilterOperator, FilterOutput } from './filter-operators.ts';
5
5
  /**
6
6
  * Forks a stream into multiple streams.
@@ -1 +1 @@
1
- {"version":3,"file":"fan-out.d.ts","sourceRoot":"","sources":["../../../../../zql/src/ivm/fan-out.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAC,MAAM,EAAC,MAAM,aAAa,CAAC;AACxC,OAAO,KAAK,EAAC,IAAI,EAAC,MAAM,WAAW,CAAC;AACpC,OAAO,KAAK,EAAC,KAAK,EAAC,MAAM,aAAa,CAAC;AACvC,OAAO,KAAK,EACV,WAAW,EACX,cAAc,EACd,YAAY,EACb,MAAM,uBAAuB,CAAC;AAE/B;;;;GAIG;AACH,qBAAa,MAAO,YAAW,cAAc;;gBAM/B,KAAK,EAAE,WAAW;IAK9B,QAAQ,CAAC,KAAK,EAAE,KAAK;IAIrB,eAAe,CAAC,MAAM,EAAE,YAAY,GAAG,IAAI;IAI3C,OAAO,IAAI,IAAI;IAWf,SAAS;IAIT,WAAW,IAAI,IAAI;IAMnB,SAAS,IAAI,IAAI;IAMhB,MAAM,CAAC,IAAI,EAAE,IAAI,GAAG,SAAS,CAAC,OAAO,EAAE,OAAO,CAAC;IAW/C,IAAI,CAAC,MAAM,EAAE,MAAM;CASrB"}
1
+ {"version":3,"file":"fan-out.d.ts","sourceRoot":"","sources":["../../../../../zql/src/ivm/fan-out.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAC,MAAM,EAAC,MAAM,aAAa,CAAC;AACxC,OAAO,KAAK,EAAC,KAAK,EAAC,MAAM,aAAa,CAAC;AACvC,OAAO,KAAK,EAAC,IAAI,EAAC,MAAM,WAAW,CAAC;AACpC,OAAO,KAAK,EACV,WAAW,EACX,cAAc,EACd,YAAY,EACb,MAAM,uBAAuB,CAAC;AAE/B;;;;GAIG;AACH,qBAAa,MAAO,YAAW,cAAc;;gBAM/B,KAAK,EAAE,WAAW;IAK9B,QAAQ,CAAC,KAAK,EAAE,KAAK;IAIrB,eAAe,CAAC,MAAM,EAAE,YAAY,GAAG,IAAI;IAI3C,OAAO,IAAI,IAAI;IAWf,SAAS;IAIT,WAAW,IAAI,IAAI;IAMnB,SAAS,IAAI,IAAI;IAMhB,MAAM,CAAC,IAAI,EAAE,IAAI,GAAG,SAAS,CAAC,OAAO,EAAE,OAAO,CAAC;IAW/C,IAAI,CAAC,MAAM,EAAE,MAAM;CASrB"}
@@ -45,7 +45,7 @@ var FanOut = class {
45
45
  }
46
46
  *push(change) {
47
47
  for (const out of this.#outputs) yield* out.push(change, this);
48
- yield* must(this.#fanIn, "fan-out must have a corresponding fan-in set!").fanOutDonePushingToAllBranches(change[0]);
48
+ yield* must(this.#fanIn, "fan-out must have a corresponding fan-in set!").fanOutDonePushingToAllBranches(change.type);
49
49
  }
50
50
  };
51
51
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"fan-out.js","names":["#input","#outputs","#fanIn","#destroyCount"],"sources":["../../../../../zql/src/ivm/fan-out.ts"],"sourcesContent":["import {must} from '../../../shared/src/must.ts';\nimport {ChangeIndex} from './change-index.ts';\nimport type {Change} from './change.ts';\nimport type {Node} from './data.ts';\nimport type {FanIn} from './fan-in.ts';\nimport type {\n FilterInput,\n FilterOperator,\n FilterOutput,\n} from './filter-operators.ts';\n\n/**\n * Forks a stream into multiple streams.\n * Is meant to be paired with a `FanIn` operator which will\n * later merge the forks back together.\n */\nexport class FanOut implements FilterOperator {\n readonly #input: FilterInput;\n readonly #outputs: FilterOutput[] = [];\n #fanIn: FanIn | undefined;\n #destroyCount: number = 0;\n\n constructor(input: FilterInput) {\n this.#input = input;\n input.setFilterOutput(this);\n }\n\n setFanIn(fanIn: FanIn) {\n this.#fanIn = fanIn;\n }\n\n setFilterOutput(output: FilterOutput): void {\n this.#outputs.push(output);\n }\n\n destroy(): void {\n if (this.#destroyCount < this.#outputs.length) {\n ++this.#destroyCount;\n if (this.#destroyCount === this.#outputs.length) {\n this.#input.destroy();\n }\n } else {\n throw new Error('FanOut already destroyed once for each output');\n }\n }\n\n getSchema() {\n return this.#input.getSchema();\n }\n\n beginFilter(): void {\n for (const output of this.#outputs) {\n output.beginFilter();\n }\n }\n\n endFilter(): void {\n for (const output of this.#outputs) {\n output.endFilter();\n }\n }\n\n *filter(node: Node): Generator<'yield', boolean> {\n let result = false;\n for (const output of this.#outputs) {\n result = (yield* output.filter(node)) || result;\n if (result) {\n return true;\n }\n }\n return result;\n }\n\n *push(change: Change) {\n for (const out of this.#outputs) {\n yield* out.push(change, this);\n }\n yield* must(\n this.#fanIn,\n 'fan-out must have a corresponding fan-in set!',\n ).fanOutDonePushingToAllBranches(change[ChangeIndex.TYPE]);\n }\n}\n"],"mappings":";;;;;;;AAgBA,IAAa,SAAb,MAA8C;CAC5C;CACA,WAAoC,EAAE;CACtC;CACA,gBAAwB;CAExB,YAAY,OAAoB;AAC9B,QAAA,QAAc;AACd,QAAM,gBAAgB,KAAK;;CAG7B,SAAS,OAAc;AACrB,QAAA,QAAc;;CAGhB,gBAAgB,QAA4B;AAC1C,QAAA,QAAc,KAAK,OAAO;;CAG5B,UAAgB;AACd,MAAI,MAAA,eAAqB,MAAA,QAAc,QAAQ;AAC7C,KAAE,MAAA;AACF,OAAI,MAAA,iBAAuB,MAAA,QAAc,OACvC,OAAA,MAAY,SAAS;QAGvB,OAAM,IAAI,MAAM,gDAAgD;;CAIpE,YAAY;AACV,SAAO,MAAA,MAAY,WAAW;;CAGhC,cAAoB;AAClB,OAAK,MAAM,UAAU,MAAA,QACnB,QAAO,aAAa;;CAIxB,YAAkB;AAChB,OAAK,MAAM,UAAU,MAAA,QACnB,QAAO,WAAW;;CAItB,CAAC,OAAO,MAAyC;EAC/C,IAAI,SAAS;AACb,OAAK,MAAM,UAAU,MAAA,SAAe;AAClC,aAAU,OAAO,OAAO,OAAO,KAAK,KAAK;AACzC,OAAI,OACF,QAAO;;AAGX,SAAO;;CAGT,CAAC,KAAK,QAAgB;AACpB,OAAK,MAAM,OAAO,MAAA,QAChB,QAAO,IAAI,KAAK,QAAQ,KAAK;AAE/B,SAAO,KACL,MAAA,OACA,gDACD,CAAC,+BAA+B,OAAO,GAAkB"}
1
+ {"version":3,"file":"fan-out.js","names":["#input","#outputs","#fanIn","#destroyCount"],"sources":["../../../../../zql/src/ivm/fan-out.ts"],"sourcesContent":["import {must} from '../../../shared/src/must.ts';\nimport type {Change} from './change.ts';\nimport type {FanIn} from './fan-in.ts';\nimport type {Node} from './data.ts';\nimport type {\n FilterInput,\n FilterOperator,\n FilterOutput,\n} from './filter-operators.ts';\n\n/**\n * Forks a stream into multiple streams.\n * Is meant to be paired with a `FanIn` operator which will\n * later merge the forks back together.\n */\nexport class FanOut implements FilterOperator {\n readonly #input: FilterInput;\n readonly #outputs: FilterOutput[] = [];\n #fanIn: FanIn | undefined;\n #destroyCount: number = 0;\n\n constructor(input: FilterInput) {\n this.#input = input;\n input.setFilterOutput(this);\n }\n\n setFanIn(fanIn: FanIn) {\n this.#fanIn = fanIn;\n }\n\n setFilterOutput(output: FilterOutput): void {\n this.#outputs.push(output);\n }\n\n destroy(): void {\n if (this.#destroyCount < this.#outputs.length) {\n ++this.#destroyCount;\n if (this.#destroyCount === this.#outputs.length) {\n this.#input.destroy();\n }\n } else {\n throw new Error('FanOut already destroyed once for each output');\n }\n }\n\n getSchema() {\n return this.#input.getSchema();\n }\n\n beginFilter(): void {\n for (const output of this.#outputs) {\n output.beginFilter();\n }\n }\n\n endFilter(): void {\n for (const output of this.#outputs) {\n output.endFilter();\n }\n }\n\n *filter(node: Node): Generator<'yield', boolean> {\n let result = false;\n for (const output of this.#outputs) {\n result = (yield* output.filter(node)) || result;\n if (result) {\n return true;\n }\n }\n return result;\n }\n\n *push(change: Change) {\n for (const out of this.#outputs) {\n yield* out.push(change, this);\n }\n yield* must(\n this.#fanIn,\n 'fan-out must have a corresponding fan-in set!',\n ).fanOutDonePushingToAllBranches(change.type);\n }\n}\n"],"mappings":";;;;;;;AAeA,IAAa,SAAb,MAA8C;CAC5C;CACA,WAAoC,EAAE;CACtC;CACA,gBAAwB;CAExB,YAAY,OAAoB;AAC9B,QAAA,QAAc;AACd,QAAM,gBAAgB,KAAK;;CAG7B,SAAS,OAAc;AACrB,QAAA,QAAc;;CAGhB,gBAAgB,QAA4B;AAC1C,QAAA,QAAc,KAAK,OAAO;;CAG5B,UAAgB;AACd,MAAI,MAAA,eAAqB,MAAA,QAAc,QAAQ;AAC7C,KAAE,MAAA;AACF,OAAI,MAAA,iBAAuB,MAAA,QAAc,OACvC,OAAA,MAAY,SAAS;QAGvB,OAAM,IAAI,MAAM,gDAAgD;;CAIpE,YAAY;AACV,SAAO,MAAA,MAAY,WAAW;;CAGhC,cAAoB;AAClB,OAAK,MAAM,UAAU,MAAA,QACnB,QAAO,aAAa;;CAIxB,YAAkB;AAChB,OAAK,MAAM,UAAU,MAAA,QACnB,QAAO,WAAW;;CAItB,CAAC,OAAO,MAAyC;EAC/C,IAAI,SAAS;AACb,OAAK,MAAM,UAAU,MAAA,SAAe;AAClC,aAAU,OAAO,OAAO,OAAO,KAAK,KAAK;AACzC,OAAI,OACF,QAAO;;AAGX,SAAO;;CAGT,CAAC,KAAK,QAAgB;AACpB,OAAK,MAAM,OAAO,MAAA,QAChB,QAAO,IAAI,KAAK,QAAQ,KAAK;AAE/B,SAAO,KACL,MAAA,OACA,gDACD,CAAC,+BAA+B,OAAO,KAAK"}
@@ -1,9 +1,9 @@
1
- import type { BuilderDelegate } from '../builder/builder.ts';
2
- import type { Change } from './change.ts';
3
- import { type Node } from './data.ts';
4
1
  import type { FetchRequest, Input, InputBase, Output } from './operator.ts';
2
+ import { type Node } from './data.ts';
3
+ import type { Change } from './change.ts';
5
4
  import type { SourceSchema } from './schema.ts';
6
5
  import { type Stream } from './stream.ts';
6
+ import type { BuilderDelegate } from '../builder/builder.ts';
7
7
  /**
8
8
  * The `where` clause of a ZQL query is implemented using a sub-graph of
9
9
  * `FilterOperators`. This sub-graph starts with a `FilterStart` operator,
@@ -1 +1 @@
1
- {"version":3,"file":"filter-operators.d.ts","sourceRoot":"","sources":["../../../../../zql/src/ivm/filter-operators.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,eAAe,EAAC,MAAM,uBAAuB,CAAC;AAC3D,OAAO,KAAK,EAAC,MAAM,EAAC,MAAM,aAAa,CAAC;AACxC,OAAO,EAAC,KAAK,IAAI,EAAC,MAAM,WAAW,CAAC;AACpC,OAAO,KAAK,EAAC,YAAY,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,EAAC,MAAM,eAAe,CAAC;AAC1E,OAAO,KAAK,EAAC,YAAY,EAAC,MAAM,aAAa,CAAC;AAC9C,OAAO,EAAC,KAAK,MAAM,EAAC,MAAM,aAAa,CAAC;AAExC;;;;;;;;;;;;;;;;;GAiBG;AAEH,MAAM,WAAW,WAAY,SAAQ,SAAS;IAC5C,+CAA+C;IAC/C,eAAe,CAAC,MAAM,EAAE,YAAY,GAAG,IAAI,CAAC;CAC7C;AAED,MAAM,WAAW,YAAa,SAAQ,MAAM;IAI1C,WAAW,IAAI,IAAI,CAAC;IACpB,MAAM,CAAC,IAAI,EAAE,IAAI,GAAG,SAAS,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IAChD,SAAS,IAAI,IAAI,CAAC;CACnB;AAED,MAAM,WAAW,cAAe,SAAQ,WAAW,EAAE,YAAY;CAAG;AAEpE;;;;GAIG;AACH,eAAO,MAAM,iBAAiB,EAAE,YAW/B,CAAC;AAEF,qBAAa,WAAY,YAAW,WAAW,EAAE,MAAM;;gBAIzC,KAAK,EAAE,KAAK;IAKxB,eAAe,CAAC,MAAM,EAAE,YAAY;IAIpC,OAAO,IAAI,IAAI;IAIf,SAAS,IAAI,YAAY;IAIxB,IAAI,CAAC,MAAM,EAAE,MAAM;IAInB,KAAK,CAAC,GAAG,EAAE,YAAY,GAAG,MAAM,CAAC,IAAI,GAAG,OAAO,CAAC;CAkBlD;AAED,qBAAa,SAAU,YAAW,KAAK,EAAE,YAAY;;gBAMvC,KAAK,EAAE,WAAW,EAAE,KAAK,EAAE,WAAW;IAMjD,KAAK,CAAC,GAAG,EAAE,YAAY,GAAG,MAAM,CAAC,IAAI,GAAG,OAAO,CAAC;IAMjD,WAAW;IACX,SAAS;IAER,MAAM,CAAC,KAAK,EAAE,IAAI;IAInB,SAAS,CAAC,MAAM,EAAE,MAAM;IAIxB,OAAO,IAAI,IAAI;IAIf,SAAS,IAAI,YAAY;IAIxB,IAAI,CAAC,MAAM,EAAE,MAAM;CAGrB;AAED,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,KAAK,EACZ,QAAQ,EAAE,eAAe,EACzB,QAAQ,EAAE,CAAC,WAAW,EAAE,WAAW,KAAK,WAAW,GAClD,KAAK,CAQP"}
1
+ {"version":3,"file":"filter-operators.d.ts","sourceRoot":"","sources":["../../../../../zql/src/ivm/filter-operators.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,YAAY,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,EAAC,MAAM,eAAe,CAAC;AAC1E,OAAO,EAAC,KAAK,IAAI,EAAC,MAAM,WAAW,CAAC;AACpC,OAAO,KAAK,EAAC,MAAM,EAAC,MAAM,aAAa,CAAC;AACxC,OAAO,KAAK,EAAC,YAAY,EAAC,MAAM,aAAa,CAAC;AAC9C,OAAO,EAAC,KAAK,MAAM,EAAC,MAAM,aAAa,CAAC;AACxC,OAAO,KAAK,EAAC,eAAe,EAAC,MAAM,uBAAuB,CAAC;AAE3D;;;;;;;;;;;;;;;;;GAiBG;AAEH,MAAM,WAAW,WAAY,SAAQ,SAAS;IAC5C,+CAA+C;IAC/C,eAAe,CAAC,MAAM,EAAE,YAAY,GAAG,IAAI,CAAC;CAC7C;AAED,MAAM,WAAW,YAAa,SAAQ,MAAM;IAI1C,WAAW,IAAI,IAAI,CAAC;IACpB,MAAM,CAAC,IAAI,EAAE,IAAI,GAAG,SAAS,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IAChD,SAAS,IAAI,IAAI,CAAC;CACnB;AAED,MAAM,WAAW,cAAe,SAAQ,WAAW,EAAE,YAAY;CAAG;AAEpE;;;;GAIG;AACH,eAAO,MAAM,iBAAiB,EAAE,YAW/B,CAAC;AAEF,qBAAa,WAAY,YAAW,WAAW,EAAE,MAAM;;gBAIzC,KAAK,EAAE,KAAK;IAKxB,eAAe,CAAC,MAAM,EAAE,YAAY;IAIpC,OAAO,IAAI,IAAI;IAIf,SAAS,IAAI,YAAY;IAIxB,IAAI,CAAC,MAAM,EAAE,MAAM;IAInB,KAAK,CAAC,GAAG,EAAE,YAAY,GAAG,MAAM,CAAC,IAAI,GAAG,OAAO,CAAC;CAkBlD;AAED,qBAAa,SAAU,YAAW,KAAK,EAAE,YAAY;;gBAMvC,KAAK,EAAE,WAAW,EAAE,KAAK,EAAE,WAAW;IAMjD,KAAK,CAAC,GAAG,EAAE,YAAY,GAAG,MAAM,CAAC,IAAI,GAAG,OAAO,CAAC;IAMjD,WAAW;IACX,SAAS;IAER,MAAM,CAAC,KAAK,EAAE,IAAI;IAInB,SAAS,CAAC,MAAM,EAAE,MAAM;IAIxB,OAAO,IAAI,IAAI;IAIf,SAAS,IAAI,YAAY;IAIxB,IAAI,CAAC,MAAM,EAAE,MAAM;CAGrB;AAED,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,KAAK,EACZ,QAAQ,EAAE,eAAe,EACzB,QAAQ,EAAE,CAAC,WAAW,EAAE,WAAW,KAAK,WAAW,GAClD,KAAK,CAQP"}
@@ -1 +1 @@
1
- {"version":3,"file":"filter-operators.js","names":["#input","#output","#start"],"sources":["../../../../../zql/src/ivm/filter-operators.ts"],"sourcesContent":["import type {BuilderDelegate} from '../builder/builder.ts';\nimport type {Change} from './change.ts';\nimport {type Node} from './data.ts';\nimport type {FetchRequest, Input, InputBase, Output} from './operator.ts';\nimport type {SourceSchema} from './schema.ts';\nimport {type Stream} from './stream.ts';\n\n/**\n * The `where` clause of a ZQL query is implemented using a sub-graph of\n * `FilterOperators`. This sub-graph starts with a `FilterStart` operator,\n * that adapts from the normal `Operator` `Output`, to the\n * `FilterOperator` `FilterInput`, and ends with a `FilterEnd` operator that\n * adapts from a `FilterOperator` `FilterOutput` to a normal `Operator` `Input`.\n * `FilterOperator`'s do not have `fetch` instead they have a\n * `filter(node: Node): boolean` method.\n * They also have `push` which is just like normal `Operator` push.\n * Not having a `fetch` means these `FilterOperator`'s cannot modify\n * `Node` `row`s or `relationship`s, but they shouldn't, they should just\n * filter.\n *\n * This `FilterOperator` abstraction enables much more efficient processing of\n * `fetch` for `where` clauses containing OR conditions.\n *\n * See https://github.com/rocicorp/mono/pull/4339\n */\n\nexport interface FilterInput extends InputBase {\n /** Tell the input where to send its output. */\n setFilterOutput(output: FilterOutput): void;\n}\n\nexport interface FilterOutput extends Output {\n // Lets the operator know that we're in a loop of filtering\n // nodes. E.g., so the operator can cache results for the\n // duration of the loop.\n beginFilter(): void;\n filter(node: Node): Generator<'yield', boolean>;\n endFilter(): void;\n}\n\nexport interface FilterOperator extends FilterInput, FilterOutput {}\n\n/**\n * An implementation of FilterOutput that throws if push or filter is called.\n * It is used as the initial value for for an operator's output before it is\n * set.\n */\nexport const throwFilterOutput: FilterOutput = {\n *push(_change: Change): Stream<'yield'> {\n throw new Error('Output not set');\n },\n\n *filter(_node: Node): Generator<'yield', boolean> {\n throw new Error('Output not set');\n },\n\n beginFilter() {},\n endFilter() {},\n};\n\nexport class FilterStart implements FilterInput, Output {\n readonly #input: Input;\n #output: FilterOutput = throwFilterOutput;\n\n constructor(input: Input) {\n this.#input = input;\n input.setOutput(this);\n }\n\n setFilterOutput(output: FilterOutput) {\n this.#output = output;\n }\n\n destroy(): void {\n this.#input.destroy();\n }\n\n getSchema(): SourceSchema {\n return this.#input.getSchema();\n }\n\n *push(change: Change) {\n yield* this.#output.push(change, this);\n }\n\n *fetch(req: FetchRequest): Stream<Node | 'yield'> {\n this.#output.beginFilter();\n try {\n for (const node of this.#input.fetch(req)) {\n if (node === 'yield') {\n yield node;\n continue;\n }\n if (yield* this.#output.filter(node)) {\n yield node;\n }\n }\n } finally {\n // finally is important if an exception is thrown or\n // if the stream is not fully consumed.\n this.#output.endFilter();\n }\n }\n}\n\nexport class FilterEnd implements Input, FilterOutput {\n readonly #start: FilterStart;\n readonly #input: FilterInput;\n\n #output: Output = throwFilterOutput;\n\n constructor(start: FilterStart, input: FilterInput) {\n this.#start = start;\n this.#input = input;\n input.setFilterOutput(this);\n }\n\n *fetch(req: FetchRequest): Stream<Node | 'yield'> {\n for (const node of this.#start.fetch(req)) {\n yield node;\n }\n }\n\n beginFilter() {}\n endFilter() {}\n\n *filter(_node: Node) {\n return true;\n }\n\n setOutput(output: Output) {\n this.#output = output;\n }\n\n destroy(): void {\n this.#input.destroy();\n }\n\n getSchema(): SourceSchema {\n return this.#input.getSchema();\n }\n\n *push(change: Change) {\n yield* this.#output.push(change, this);\n }\n}\n\nexport function buildFilterPipeline(\n input: Input,\n delegate: BuilderDelegate,\n pipeline: (filterInput: FilterInput) => FilterInput,\n): Input {\n const filterStart = new FilterStart(input);\n delegate.addEdge(input, filterStart);\n const middle = pipeline(filterStart);\n delegate.addEdge(filterStart, middle);\n const filterEnd = new FilterEnd(filterStart, middle);\n delegate.addEdge(middle, filterEnd);\n return filterEnd;\n}\n"],"mappings":";;;;;;;AA+CA,IAAa,oBAAkC;CAC7C,CAAC,KAAK,SAAkC;AACtC,QAAM,IAAI,MAAM,iBAAiB;;CAGnC,CAAC,OAAO,OAA0C;AAChD,QAAM,IAAI,MAAM,iBAAiB;;CAGnC,cAAc;CACd,YAAY;CACb;AAED,IAAa,cAAb,MAAwD;CACtD;CACA,UAAwB;CAExB,YAAY,OAAc;AACxB,QAAA,QAAc;AACd,QAAM,UAAU,KAAK;;CAGvB,gBAAgB,QAAsB;AACpC,QAAA,SAAe;;CAGjB,UAAgB;AACd,QAAA,MAAY,SAAS;;CAGvB,YAA0B;AACxB,SAAO,MAAA,MAAY,WAAW;;CAGhC,CAAC,KAAK,QAAgB;AACpB,SAAO,MAAA,OAAa,KAAK,QAAQ,KAAK;;CAGxC,CAAC,MAAM,KAA2C;AAChD,QAAA,OAAa,aAAa;AAC1B,MAAI;AACF,QAAK,MAAM,QAAQ,MAAA,MAAY,MAAM,IAAI,EAAE;AACzC,QAAI,SAAS,SAAS;AACpB,WAAM;AACN;;AAEF,QAAI,OAAO,MAAA,OAAa,OAAO,KAAK,CAClC,OAAM;;YAGF;AAGR,SAAA,OAAa,WAAW;;;;AAK9B,IAAa,YAAb,MAAsD;CACpD;CACA;CAEA,UAAkB;CAElB,YAAY,OAAoB,OAAoB;AAClD,QAAA,QAAc;AACd,QAAA,QAAc;AACd,QAAM,gBAAgB,KAAK;;CAG7B,CAAC,MAAM,KAA2C;AAChD,OAAK,MAAM,QAAQ,MAAA,MAAY,MAAM,IAAI,CACvC,OAAM;;CAIV,cAAc;CACd,YAAY;CAEZ,CAAC,OAAO,OAAa;AACnB,SAAO;;CAGT,UAAU,QAAgB;AACxB,QAAA,SAAe;;CAGjB,UAAgB;AACd,QAAA,MAAY,SAAS;;CAGvB,YAA0B;AACxB,SAAO,MAAA,MAAY,WAAW;;CAGhC,CAAC,KAAK,QAAgB;AACpB,SAAO,MAAA,OAAa,KAAK,QAAQ,KAAK;;;AAI1C,SAAgB,oBACd,OACA,UACA,UACO;CACP,MAAM,cAAc,IAAI,YAAY,MAAM;AAC1C,UAAS,QAAQ,OAAO,YAAY;CACpC,MAAM,SAAS,SAAS,YAAY;AACpC,UAAS,QAAQ,aAAa,OAAO;CACrC,MAAM,YAAY,IAAI,UAAU,aAAa,OAAO;AACpD,UAAS,QAAQ,QAAQ,UAAU;AACnC,QAAO"}
1
+ {"version":3,"file":"filter-operators.js","names":["#input","#output","#start"],"sources":["../../../../../zql/src/ivm/filter-operators.ts"],"sourcesContent":["import type {FetchRequest, Input, InputBase, Output} from './operator.ts';\nimport {type Node} from './data.ts';\nimport type {Change} from './change.ts';\nimport type {SourceSchema} from './schema.ts';\nimport {type Stream} from './stream.ts';\nimport type {BuilderDelegate} from '../builder/builder.ts';\n\n/**\n * The `where` clause of a ZQL query is implemented using a sub-graph of\n * `FilterOperators`. This sub-graph starts with a `FilterStart` operator,\n * that adapts from the normal `Operator` `Output`, to the\n * `FilterOperator` `FilterInput`, and ends with a `FilterEnd` operator that\n * adapts from a `FilterOperator` `FilterOutput` to a normal `Operator` `Input`.\n * `FilterOperator`'s do not have `fetch` instead they have a\n * `filter(node: Node): boolean` method.\n * They also have `push` which is just like normal `Operator` push.\n * Not having a `fetch` means these `FilterOperator`'s cannot modify\n * `Node` `row`s or `relationship`s, but they shouldn't, they should just\n * filter.\n *\n * This `FilterOperator` abstraction enables much more efficient processing of\n * `fetch` for `where` clauses containing OR conditions.\n *\n * See https://github.com/rocicorp/mono/pull/4339\n */\n\nexport interface FilterInput extends InputBase {\n /** Tell the input where to send its output. */\n setFilterOutput(output: FilterOutput): void;\n}\n\nexport interface FilterOutput extends Output {\n // Lets the operator know that we're in a loop of filtering\n // nodes. E.g., so the operator can cache results for the\n // duration of the loop.\n beginFilter(): void;\n filter(node: Node): Generator<'yield', boolean>;\n endFilter(): void;\n}\n\nexport interface FilterOperator extends FilterInput, FilterOutput {}\n\n/**\n * An implementation of FilterOutput that throws if push or filter is called.\n * It is used as the initial value for for an operator's output before it is\n * set.\n */\nexport const throwFilterOutput: FilterOutput = {\n *push(_change: Change): Stream<'yield'> {\n throw new Error('Output not set');\n },\n\n *filter(_node: Node): Generator<'yield', boolean> {\n throw new Error('Output not set');\n },\n\n beginFilter() {},\n endFilter() {},\n};\n\nexport class FilterStart implements FilterInput, Output {\n readonly #input: Input;\n #output: FilterOutput = throwFilterOutput;\n\n constructor(input: Input) {\n this.#input = input;\n input.setOutput(this);\n }\n\n setFilterOutput(output: FilterOutput) {\n this.#output = output;\n }\n\n destroy(): void {\n this.#input.destroy();\n }\n\n getSchema(): SourceSchema {\n return this.#input.getSchema();\n }\n\n *push(change: Change) {\n yield* this.#output.push(change, this);\n }\n\n *fetch(req: FetchRequest): Stream<Node | 'yield'> {\n this.#output.beginFilter();\n try {\n for (const node of this.#input.fetch(req)) {\n if (node === 'yield') {\n yield node;\n continue;\n }\n if (yield* this.#output.filter(node)) {\n yield node;\n }\n }\n } finally {\n // finally is important if an exception is thrown or\n // if the stream is not fully consumed.\n this.#output.endFilter();\n }\n }\n}\n\nexport class FilterEnd implements Input, FilterOutput {\n readonly #start: FilterStart;\n readonly #input: FilterInput;\n\n #output: Output = throwFilterOutput;\n\n constructor(start: FilterStart, input: FilterInput) {\n this.#start = start;\n this.#input = input;\n input.setFilterOutput(this);\n }\n\n *fetch(req: FetchRequest): Stream<Node | 'yield'> {\n for (const node of this.#start.fetch(req)) {\n yield node;\n }\n }\n\n beginFilter() {}\n endFilter() {}\n\n *filter(_node: Node) {\n return true;\n }\n\n setOutput(output: Output) {\n this.#output = output;\n }\n\n destroy(): void {\n this.#input.destroy();\n }\n\n getSchema(): SourceSchema {\n return this.#input.getSchema();\n }\n\n *push(change: Change) {\n yield* this.#output.push(change, this);\n }\n}\n\nexport function buildFilterPipeline(\n input: Input,\n delegate: BuilderDelegate,\n pipeline: (filterInput: FilterInput) => FilterInput,\n): Input {\n const filterStart = new FilterStart(input);\n delegate.addEdge(input, filterStart);\n const middle = pipeline(filterStart);\n delegate.addEdge(filterStart, middle);\n const filterEnd = new FilterEnd(filterStart, middle);\n delegate.addEdge(middle, filterEnd);\n return filterEnd;\n}\n"],"mappings":";;;;;;;AA+CA,IAAa,oBAAkC;CAC7C,CAAC,KAAK,SAAkC;AACtC,QAAM,IAAI,MAAM,iBAAiB;;CAGnC,CAAC,OAAO,OAA0C;AAChD,QAAM,IAAI,MAAM,iBAAiB;;CAGnC,cAAc;CACd,YAAY;CACb;AAED,IAAa,cAAb,MAAwD;CACtD;CACA,UAAwB;CAExB,YAAY,OAAc;AACxB,QAAA,QAAc;AACd,QAAM,UAAU,KAAK;;CAGvB,gBAAgB,QAAsB;AACpC,QAAA,SAAe;;CAGjB,UAAgB;AACd,QAAA,MAAY,SAAS;;CAGvB,YAA0B;AACxB,SAAO,MAAA,MAAY,WAAW;;CAGhC,CAAC,KAAK,QAAgB;AACpB,SAAO,MAAA,OAAa,KAAK,QAAQ,KAAK;;CAGxC,CAAC,MAAM,KAA2C;AAChD,QAAA,OAAa,aAAa;AAC1B,MAAI;AACF,QAAK,MAAM,QAAQ,MAAA,MAAY,MAAM,IAAI,EAAE;AACzC,QAAI,SAAS,SAAS;AACpB,WAAM;AACN;;AAEF,QAAI,OAAO,MAAA,OAAa,OAAO,KAAK,CAClC,OAAM;;YAGF;AAGR,SAAA,OAAa,WAAW;;;;AAK9B,IAAa,YAAb,MAAsD;CACpD;CACA;CAEA,UAAkB;CAElB,YAAY,OAAoB,OAAoB;AAClD,QAAA,QAAc;AACd,QAAA,QAAc;AACd,QAAM,gBAAgB,KAAK;;CAG7B,CAAC,MAAM,KAA2C;AAChD,OAAK,MAAM,QAAQ,MAAA,MAAY,MAAM,IAAI,CACvC,OAAM;;CAIV,cAAc;CACd,YAAY;CAEZ,CAAC,OAAO,OAAa;AACnB,SAAO;;CAGT,UAAU,QAAgB;AACxB,QAAA,SAAe;;CAGjB,UAAgB;AACd,QAAA,MAAY,SAAS;;CAGvB,YAA0B;AACxB,SAAO,MAAA,MAAY,WAAW;;CAGhC,CAAC,KAAK,QAAgB;AACpB,SAAO,MAAA,OAAa,KAAK,QAAQ,KAAK;;;AAI1C,SAAgB,oBACd,OACA,UACA,UACO;CACP,MAAM,cAAc,IAAI,YAAY,MAAM;AAC1C,UAAS,QAAQ,OAAO,YAAY;CACpC,MAAM,SAAS,SAAS,YAAY;AACpC,UAAS,QAAQ,aAAa,OAAO;CACrC,MAAM,YAAY,IAAI,UAAU,aAAa,OAAO;AACpD,UAAS,QAAQ,QAAQ,UAAU;AACnC,QAAO"}
@@ -1 +1 @@
1
- {"version":3,"file":"filter-push.d.ts","sourceRoot":"","sources":["../../../../../zql/src/ivm/filter-push.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAC,GAAG,EAAC,MAAM,oCAAoC,CAAC;AAG5D,OAAO,KAAK,EAAC,MAAM,EAAC,MAAM,aAAa,CAAC;AAExC,OAAO,KAAK,EAAC,SAAS,EAAE,MAAM,EAAC,MAAM,eAAe,CAAC;AACrD,OAAO,KAAK,EAAC,MAAM,EAAC,MAAM,aAAa,CAAC;AAExC,wBAAiB,UAAU,CACzB,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,SAAS,EACjB,SAAS,CAAC,EAAE,CAAC,GAAG,EAAE,GAAG,KAAK,OAAO,GAChC,MAAM,CAAC,OAAO,CAAC,CAuBjB"}
1
+ {"version":3,"file":"filter-push.d.ts","sourceRoot":"","sources":["../../../../../zql/src/ivm/filter-push.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAC,GAAG,EAAC,MAAM,oCAAoC,CAAC;AAC5D,OAAO,KAAK,EAAC,MAAM,EAAC,MAAM,aAAa,CAAC;AAExC,OAAO,KAAK,EAAC,SAAS,EAAE,MAAM,EAAC,MAAM,eAAe,CAAC;AACrD,OAAO,KAAK,EAAC,MAAM,EAAC,MAAM,aAAa,CAAC;AAExC,wBAAiB,UAAU,CACzB,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,SAAS,EACjB,SAAS,CAAC,EAAE,CAAC,GAAG,EAAE,GAAG,KAAK,OAAO,GAChC,MAAM,CAAC,OAAO,CAAC,CAuBjB"}
@@ -6,15 +6,15 @@ function* filterPush(change, output, pusher, predicate) {
6
6
  yield* output.push(change, pusher);
7
7
  return;
8
8
  }
9
- switch (change[0]) {
10
- case 0:
11
- case 1:
12
- if (predicate(change[1].row)) yield* output.push(change, pusher);
9
+ switch (change.type) {
10
+ case "add":
11
+ case "remove":
12
+ if (predicate(change.node.row)) yield* output.push(change, pusher);
13
13
  break;
14
- case 3:
15
- if (predicate(change[1].row)) yield* output.push(change, pusher);
14
+ case "child":
15
+ if (predicate(change.node.row)) yield* output.push(change, pusher);
16
16
  break;
17
- case 2:
17
+ case "edit":
18
18
  yield* maybeSplitAndPushEditChange(change, predicate, output, pusher);
19
19
  break;
20
20
  default: unreachable(change);
@@ -1 +1 @@
1
- {"version":3,"file":"filter-push.js","names":[],"sources":["../../../../../zql/src/ivm/filter-push.ts"],"sourcesContent":["import {unreachable} from '../../../shared/src/asserts.ts';\nimport type {Row} from '../../../zero-protocol/src/data.ts';\nimport {ChangeIndex} from './change-index.ts';\nimport {ChangeType} from './change-type.ts';\nimport type {Change} from './change.ts';\nimport {maybeSplitAndPushEditChange} from './maybe-split-and-push-edit-change.ts';\nimport type {InputBase, Output} from './operator.ts';\nimport type {Stream} from './stream.ts';\n\nexport function* filterPush(\n change: Change,\n output: Output,\n pusher: InputBase,\n predicate?: (row: Row) => boolean,\n): Stream<'yield'> {\n if (!predicate) {\n yield* output.push(change, pusher);\n return;\n }\n switch (change[ChangeIndex.TYPE]) {\n case ChangeType.ADD:\n case ChangeType.REMOVE:\n if (predicate(change[ChangeIndex.NODE].row)) {\n yield* output.push(change, pusher);\n }\n break;\n case ChangeType.CHILD:\n if (predicate(change[ChangeIndex.NODE].row)) {\n yield* output.push(change, pusher);\n }\n break;\n case ChangeType.EDIT:\n yield* maybeSplitAndPushEditChange(change, predicate, output, pusher);\n break;\n default:\n unreachable(change);\n }\n}\n"],"mappings":";;;AASA,UAAiB,WACf,QACA,QACA,QACA,WACiB;AACjB,KAAI,CAAC,WAAW;AACd,SAAO,OAAO,KAAK,QAAQ,OAAO;AAClC;;AAEF,SAAQ,OAAO,IAAf;EACE,KAAK;EACL,KAAK;AACH,OAAI,UAAU,OAAO,GAAkB,IAAI,CACzC,QAAO,OAAO,KAAK,QAAQ,OAAO;AAEpC;EACF,KAAK;AACH,OAAI,UAAU,OAAO,GAAkB,IAAI,CACzC,QAAO,OAAO,KAAK,QAAQ,OAAO;AAEpC;EACF,KAAK;AACH,UAAO,4BAA4B,QAAQ,WAAW,QAAQ,OAAO;AACrE;EACF,QACE,aAAY,OAAO"}
1
+ {"version":3,"file":"filter-push.js","names":[],"sources":["../../../../../zql/src/ivm/filter-push.ts"],"sourcesContent":["import {unreachable} from '../../../shared/src/asserts.ts';\nimport type {Row} from '../../../zero-protocol/src/data.ts';\nimport type {Change} from './change.ts';\nimport {maybeSplitAndPushEditChange} from './maybe-split-and-push-edit-change.ts';\nimport type {InputBase, Output} from './operator.ts';\nimport type {Stream} from './stream.ts';\n\nexport function* filterPush(\n change: Change,\n output: Output,\n pusher: InputBase,\n predicate?: (row: Row) => boolean,\n): Stream<'yield'> {\n if (!predicate) {\n yield* output.push(change, pusher);\n return;\n }\n switch (change.type) {\n case 'add':\n case 'remove':\n if (predicate(change.node.row)) {\n yield* output.push(change, pusher);\n }\n break;\n case 'child':\n if (predicate(change.node.row)) {\n yield* output.push(change, pusher);\n }\n break;\n case 'edit':\n yield* maybeSplitAndPushEditChange(change, predicate, output, pusher);\n break;\n default:\n unreachable(change);\n }\n}\n"],"mappings":";;;AAOA,UAAiB,WACf,QACA,QACA,QACA,WACiB;AACjB,KAAI,CAAC,WAAW;AACd,SAAO,OAAO,KAAK,QAAQ,OAAO;AAClC;;AAEF,SAAQ,OAAO,MAAf;EACE,KAAK;EACL,KAAK;AACH,OAAI,UAAU,OAAO,KAAK,IAAI,CAC5B,QAAO,OAAO,KAAK,QAAQ,OAAO;AAEpC;EACF,KAAK;AACH,OAAI,UAAU,OAAO,KAAK,IAAI,CAC5B,QAAO,OAAO,KAAK,QAAQ,OAAO;AAEpC;EACF,KAAK;AACH,UAAO,4BAA4B,QAAQ,WAAW,QAAQ,OAAO;AACrE;EACF,QACE,aAAY,OAAO"}
@@ -1,7 +1,7 @@
1
1
  import type { Row } from '../../../zero-protocol/src/data.ts';
2
2
  import type { Change } from './change.ts';
3
- import { type Node } from './data.ts';
4
3
  import { type FilterInput, type FilterOperator, type FilterOutput } from './filter-operators.ts';
4
+ import { type Node } from './data.ts';
5
5
  import type { SourceSchema } from './schema.ts';
6
6
  /**
7
7
  * The Filter operator filters data through a predicate. It is stateless.
@@ -1 +1 @@
1
- {"version":3,"file":"filter.d.ts","sourceRoot":"","sources":["../../../../../zql/src/ivm/filter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,GAAG,EAAC,MAAM,oCAAoC,CAAC;AAC5D,OAAO,KAAK,EAAC,MAAM,EAAC,MAAM,aAAa,CAAC;AACxC,OAAO,EAAC,KAAK,IAAI,EAAC,MAAM,WAAW,CAAC;AACpC,OAAO,EAEL,KAAK,WAAW,EAChB,KAAK,cAAc,EACnB,KAAK,YAAY,EAClB,MAAM,uBAAuB,CAAC;AAE/B,OAAO,KAAK,EAAC,YAAY,EAAC,MAAM,aAAa,CAAC;AAE9C;;;;GAIG;AACH,qBAAa,MAAO,YAAW,cAAc;;gBAM/B,KAAK,EAAE,WAAW,EAAE,SAAS,EAAE,CAAC,GAAG,EAAE,GAAG,KAAK,OAAO;IAMhE,WAAW,IAAI,IAAI;IAInB,SAAS,IAAI,IAAI;IAIhB,MAAM,CAAC,IAAI,EAAE,IAAI,GAAG,SAAS,CAAC,OAAO,EAAE,OAAO,CAAC;IAIhD,eAAe,CAAC,MAAM,EAAE,YAAY;IAIpC,OAAO,IAAI,IAAI;IAIf,SAAS,IAAI,YAAY;IAIxB,IAAI,CAAC,MAAM,EAAE,MAAM;CAGrB"}
1
+ {"version":3,"file":"filter.d.ts","sourceRoot":"","sources":["../../../../../zql/src/ivm/filter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,GAAG,EAAC,MAAM,oCAAoC,CAAC;AAC5D,OAAO,KAAK,EAAC,MAAM,EAAC,MAAM,aAAa,CAAC;AACxC,OAAO,EAEL,KAAK,WAAW,EAChB,KAAK,cAAc,EACnB,KAAK,YAAY,EAClB,MAAM,uBAAuB,CAAC;AAE/B,OAAO,EAAC,KAAK,IAAI,EAAC,MAAM,WAAW,CAAC;AACpC,OAAO,KAAK,EAAC,YAAY,EAAC,MAAM,aAAa,CAAC;AAE9C;;;;GAIG;AACH,qBAAa,MAAO,YAAW,cAAc;;gBAM/B,KAAK,EAAE,WAAW,EAAE,SAAS,EAAE,CAAC,GAAG,EAAE,GAAG,KAAK,OAAO;IAMhE,WAAW,IAAI,IAAI;IAInB,SAAS,IAAI,IAAI;IAIhB,MAAM,CAAC,IAAI,EAAE,IAAI,GAAG,SAAS,CAAC,OAAO,EAAE,OAAO,CAAC;IAIhD,eAAe,CAAC,MAAM,EAAE,YAAY;IAIpC,OAAO,IAAI,IAAI;IAIf,SAAS,IAAI,YAAY;IAIxB,IAAI,CAAC,MAAM,EAAE,MAAM;CAGrB"}
@@ -1 +1 @@
1
- {"version":3,"file":"filter.js","names":["#input","#predicate","#output"],"sources":["../../../../../zql/src/ivm/filter.ts"],"sourcesContent":["import type {Row} from '../../../zero-protocol/src/data.ts';\nimport type {Change} from './change.ts';\nimport {type Node} from './data.ts';\nimport {\n throwFilterOutput,\n type FilterInput,\n type FilterOperator,\n type FilterOutput,\n} from './filter-operators.ts';\nimport {filterPush} from './filter-push.ts';\nimport type {SourceSchema} from './schema.ts';\n\n/**\n * The Filter operator filters data through a predicate. It is stateless.\n *\n * The predicate must be pure.\n */\nexport class Filter implements FilterOperator {\n readonly #input: FilterInput;\n readonly #predicate: (row: Row) => boolean;\n\n #output: FilterOutput = throwFilterOutput;\n\n constructor(input: FilterInput, predicate: (row: Row) => boolean) {\n this.#input = input;\n this.#predicate = predicate;\n input.setFilterOutput(this);\n }\n\n beginFilter(): void {\n this.#output.beginFilter();\n }\n\n endFilter(): void {\n this.#output.endFilter();\n }\n\n *filter(node: Node): Generator<'yield', boolean> {\n return this.#predicate(node.row) && (yield* this.#output.filter(node));\n }\n\n setFilterOutput(output: FilterOutput) {\n this.#output = output;\n }\n\n destroy(): void {\n this.#input.destroy();\n }\n\n getSchema(): SourceSchema {\n return this.#input.getSchema();\n }\n\n *push(change: Change) {\n yield* filterPush(change, this.#output, this, this.#predicate);\n }\n}\n"],"mappings":";;;;;;;;;AAiBA,IAAa,SAAb,MAA8C;CAC5C;CACA;CAEA,UAAwB;CAExB,YAAY,OAAoB,WAAkC;AAChE,QAAA,QAAc;AACd,QAAA,YAAkB;AAClB,QAAM,gBAAgB,KAAK;;CAG7B,cAAoB;AAClB,QAAA,OAAa,aAAa;;CAG5B,YAAkB;AAChB,QAAA,OAAa,WAAW;;CAG1B,CAAC,OAAO,MAAyC;AAC/C,SAAO,MAAA,UAAgB,KAAK,IAAI,KAAK,OAAO,MAAA,OAAa,OAAO,KAAK;;CAGvE,gBAAgB,QAAsB;AACpC,QAAA,SAAe;;CAGjB,UAAgB;AACd,QAAA,MAAY,SAAS;;CAGvB,YAA0B;AACxB,SAAO,MAAA,MAAY,WAAW;;CAGhC,CAAC,KAAK,QAAgB;AACpB,SAAO,WAAW,QAAQ,MAAA,QAAc,MAAM,MAAA,UAAgB"}
1
+ {"version":3,"file":"filter.js","names":["#input","#predicate","#output"],"sources":["../../../../../zql/src/ivm/filter.ts"],"sourcesContent":["import type {Row} from '../../../zero-protocol/src/data.ts';\nimport type {Change} from './change.ts';\nimport {\n throwFilterOutput,\n type FilterInput,\n type FilterOperator,\n type FilterOutput,\n} from './filter-operators.ts';\nimport {filterPush} from './filter-push.ts';\nimport {type Node} from './data.ts';\nimport type {SourceSchema} from './schema.ts';\n\n/**\n * The Filter operator filters data through a predicate. It is stateless.\n *\n * The predicate must be pure.\n */\nexport class Filter implements FilterOperator {\n readonly #input: FilterInput;\n readonly #predicate: (row: Row) => boolean;\n\n #output: FilterOutput = throwFilterOutput;\n\n constructor(input: FilterInput, predicate: (row: Row) => boolean) {\n this.#input = input;\n this.#predicate = predicate;\n input.setFilterOutput(this);\n }\n\n beginFilter(): void {\n this.#output.beginFilter();\n }\n\n endFilter(): void {\n this.#output.endFilter();\n }\n\n *filter(node: Node): Generator<'yield', boolean> {\n return this.#predicate(node.row) && (yield* this.#output.filter(node));\n }\n\n setFilterOutput(output: FilterOutput) {\n this.#output = output;\n }\n\n destroy(): void {\n this.#input.destroy();\n }\n\n getSchema(): SourceSchema {\n return this.#input.getSchema();\n }\n\n *push(change: Change) {\n yield* filterPush(change, this.#output, this, this.#predicate);\n }\n}\n"],"mappings":";;;;;;;;;AAiBA,IAAa,SAAb,MAA8C;CAC5C;CACA;CAEA,UAAwB;CAExB,YAAY,OAAoB,WAAkC;AAChE,QAAA,QAAc;AACd,QAAA,YAAkB;AAClB,QAAM,gBAAgB,KAAK;;CAG7B,cAAoB;AAClB,QAAA,OAAa,aAAa;;CAG5B,YAAkB;AAChB,QAAA,OAAa,WAAW;;CAG1B,CAAC,OAAO,MAAyC;AAC/C,SAAO,MAAA,UAAgB,KAAK,IAAI,KAAK,OAAO,MAAA,OAAa,OAAO,KAAK;;CAGvE,gBAAgB,QAAsB;AACpC,QAAA,SAAe;;CAGjB,UAAgB;AACd,QAAA,MAAY,SAAS;;CAGvB,YAA0B;AACxB,SAAO,MAAA,MAAY,WAAW;;CAGhC,CAAC,KAAK,QAAgB;AACpB,SAAO,WAAW,QAAQ,MAAA,QAAc,MAAM,MAAA,UAAgB"}
@@ -1 +1 @@
1
- {"version":3,"file":"flipped-join.d.ts","sourceRoot":"","sources":["../../../../../zql/src/ivm/flipped-join.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAC,WAAW,EAAE,MAAM,EAAC,MAAM,mCAAmC,CAAC;AAY3E,OAAO,KAAK,EAAC,IAAI,EAAC,MAAM,WAAW,CAAC;AAOpC,OAAO,EAEL,KAAK,YAAY,EACjB,KAAK,KAAK,EACV,KAAK,MAAM,EACZ,MAAM,eAAe,CAAC;AACvB,OAAO,KAAK,EAAC,YAAY,EAAC,MAAM,aAAa,CAAC;AAC9C,OAAO,EAAC,KAAK,MAAM,EAAC,MAAM,aAAa,CAAC;AAExC,KAAK,IAAI,GAAG;IACV,MAAM,EAAE,KAAK,CAAC;IACd,KAAK,EAAE,KAAK,CAAC;IAEb,SAAS,EAAE,WAAW,CAAC;IACvB,QAAQ,EAAE,WAAW,CAAC;IAEtB,gBAAgB,EAAE,MAAM,CAAC;IACzB,MAAM,EAAE,OAAO,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF;;;;;;;GAOG;AACH,qBAAa,WAAY,YAAW,KAAK;;gBAa3B,EACV,MAAM,EACN,KAAK,EACL,SAAS,EACT,QAAQ,EACR,gBAAgB,EAChB,MAAM,EACN,MAAM,GACP,EAAE,IAAI;IAkCP,OAAO,IAAI,IAAI;IAKf,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAI/B,SAAS,IAAI,YAAY;IAQxB,KAAK,CAAC,GAAG,EAAE,YAAY,GAAG,MAAM,CAAC,IAAI,GAAG,OAAO,CAAC;CA6XlD"}
1
+ {"version":3,"file":"flipped-join.d.ts","sourceRoot":"","sources":["../../../../../zql/src/ivm/flipped-join.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAC,WAAW,EAAE,MAAM,EAAC,MAAM,mCAAmC,CAAC;AAI3E,OAAO,KAAK,EAAC,IAAI,EAAC,MAAM,WAAW,CAAC;AAQpC,OAAO,EAEL,KAAK,YAAY,EACjB,KAAK,KAAK,EACV,KAAK,MAAM,EACZ,MAAM,eAAe,CAAC;AACvB,OAAO,KAAK,EAAC,YAAY,EAAC,MAAM,aAAa,CAAC;AAC9C,OAAO,EAAC,KAAK,MAAM,EAAC,MAAM,aAAa,CAAC;AAExC,KAAK,IAAI,GAAG;IACV,MAAM,EAAE,KAAK,CAAC;IACd,KAAK,EAAE,KAAK,CAAC;IAEb,SAAS,EAAE,WAAW,CAAC;IACvB,QAAQ,EAAE,WAAW,CAAC;IAEtB,gBAAgB,EAAE,MAAM,CAAC;IACzB,MAAM,EAAE,OAAO,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF;;;;;;;GAOG;AACH,qBAAa,WAAY,YAAW,KAAK;;gBAY3B,EACV,MAAM,EACN,KAAK,EACL,SAAS,EACT,QAAQ,EACR,gBAAgB,EAChB,MAAM,EACN,MAAM,GACP,EAAE,IAAI;IAkCP,OAAO,IAAI,IAAI;IAKf,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAI/B,SAAS,IAAI,YAAY;IAQxB,KAAK,CAAC,GAAG,EAAE,YAAY,GAAG,MAAM,CAAC,IAAI,GAAG,OAAO,CAAC;CAuXlD"}
@@ -2,7 +2,6 @@ import { assert, unreachable } from "../../../shared/src/asserts.js";
2
2
  import { binarySearch } from "../../../shared/src/binary-search.js";
3
3
  import { emptyArray } from "../../../shared/src/sentinels.js";
4
4
  import { throwOutput } from "./operator.js";
5
- import { makeAddChange, makeChildChange, makeEditChange, makeRemoveChange } from "./change.js";
6
5
  import { constraintsAreCompatible } from "./constraint.js";
7
6
  import { buildJoinConstraint, generateWithOverlayNoYield, isJoinMatch, rowEqualsForCompoundKey } from "./join-utils.js";
8
7
  //#region ../zql/src/ivm/flipped-join.ts
@@ -23,7 +22,6 @@ var FlippedJoin = class {
23
22
  #schema;
24
23
  #output = throwOutput;
25
24
  #inprogressChildChange;
26
- #inprogressChildChangePosition;
27
25
  constructor({ parent, child, parentKey, childKey, relationshipName, hidden, system }) {
28
26
  assert(parent !== child, "Parent and child must be different operators");
29
27
  assert(parentKey.length === childKey.length, "The parentKey and childKey keys must have same length");
@@ -76,8 +74,8 @@ var FlippedJoin = class {
76
74
  }
77
75
  childNodes.push(node);
78
76
  }
79
- if (this.#inprogressChildChange?.[0] === 1) {
80
- const removedNode = this.#inprogressChildChange[1];
77
+ if (this.#inprogressChildChange?.change.type === "remove") {
78
+ const removedNode = this.#inprogressChildChange.change.node;
81
79
  const compare = this.#child.getSchema().compareRows;
82
80
  const insertPos = binarySearch(childNodes.length, (i) => compare(removedNode.row, childNodes[i].row));
83
81
  childNodes.splice(insertPos, 0, removedNode);
@@ -140,11 +138,11 @@ var FlippedJoin = class {
140
138
  nextParentNodes[minParentNodeChildIndex] = result.done ? null : result.value;
141
139
  }
142
140
  let overlaidRelatedChildNodes = relatedChildNodes;
143
- if (this.#inprogressChildChange && this.#inprogressChildChangePosition && isJoinMatch(this.#inprogressChildChange[1].row, this.#childKey, minParentNode.row, this.#parentKey)) {
144
- const hasInprogressChildChangeBeenPushedForMinParentNode = this.#parent.getSchema().compareRows(minParentNode.row, this.#inprogressChildChangePosition) <= 0;
145
- if (this.#inprogressChildChange[0] === 1) {
146
- if (hasInprogressChildChangeBeenPushedForMinParentNode) overlaidRelatedChildNodes = relatedChildNodes.filter((n) => n !== this.#inprogressChildChange?.[1]);
147
- } else if (!hasInprogressChildChangeBeenPushedForMinParentNode) overlaidRelatedChildNodes = [...generateWithOverlayNoYield(relatedChildNodes, this.#inprogressChildChange, this.#child.getSchema())];
141
+ if (this.#inprogressChildChange && this.#inprogressChildChange.position && isJoinMatch(this.#inprogressChildChange.change.node.row, this.#childKey, minParentNode.row, this.#parentKey)) {
142
+ const hasInprogressChildChangeBeenPushedForMinParentNode = this.#parent.getSchema().compareRows(minParentNode.row, this.#inprogressChildChange.position) <= 0;
143
+ if (this.#inprogressChildChange.change.type === "remove") {
144
+ if (hasInprogressChildChangeBeenPushedForMinParentNode) overlaidRelatedChildNodes = relatedChildNodes.filter((n) => n !== this.#inprogressChildChange?.change.node);
145
+ } else if (!hasInprogressChildChangeBeenPushedForMinParentNode) overlaidRelatedChildNodes = [...generateWithOverlayNoYield(relatedChildNodes, this.#inprogressChildChange.change, this.#child.getSchema())];
148
146
  }
149
147
  if (overlaidRelatedChildNodes.length > 0) yield {
150
148
  ...minParentNode,
@@ -167,33 +165,37 @@ var FlippedJoin = class {
167
165
  }
168
166
  }
169
167
  *#pushChild(change) {
170
- switch (change[0]) {
171
- case 0:
172
- case 1:
168
+ switch (change.type) {
169
+ case "add":
170
+ case "remove":
173
171
  yield* this.#pushChildChange(change);
174
172
  break;
175
- case 2:
176
- assert(rowEqualsForCompoundKey(change[2].row, change[1].row, this.#childKey), `Child edit must not change relationship.`);
173
+ case "edit":
174
+ assert(rowEqualsForCompoundKey(change.oldNode.row, change.node.row, this.#childKey), `Child edit must not change relationship.`);
177
175
  yield* this.#pushChildChange(change, true);
178
176
  break;
179
- case 3:
177
+ case "child":
180
178
  yield* this.#pushChildChange(change, true);
181
179
  break;
182
180
  }
183
181
  }
184
182
  *#pushChildChange(change, exists) {
185
- this.#inprogressChildChange = change;
186
- this.#inprogressChildChangePosition = void 0;
183
+ this.#inprogressChildChange = {
184
+ change,
185
+ position: void 0
186
+ };
187
187
  try {
188
- const constraint = buildJoinConstraint(change[1].row, this.#childKey, this.#parentKey);
188
+ const constraint = buildJoinConstraint(change.node.row, this.#childKey, this.#parentKey);
189
189
  const parentNodeStream = constraint ? this.#parent.fetch({ constraint }) : [];
190
190
  for (const parentNode of parentNodeStream) {
191
191
  if (parentNode === "yield") {
192
192
  yield "yield";
193
193
  continue;
194
194
  }
195
- this.#inprogressChildChange = change;
196
- this.#inprogressChildChangePosition = parentNode.row;
195
+ this.#inprogressChildChange = {
196
+ change,
197
+ position: parentNode.row
198
+ };
197
199
  const childNodeStream = () => {
198
200
  const constraint = buildJoinConstraint(parentNode.row, this.#parentKey, this.#childKey);
199
201
  return constraint ? this.#child.fetch({ constraint }) : [];
@@ -203,31 +205,35 @@ var FlippedJoin = class {
203
205
  yield "yield";
204
206
  continue;
205
207
  }
206
- if (this.#child.getSchema().compareRows(childNode.row, change[1].row) !== 0) {
208
+ if (this.#child.getSchema().compareRows(childNode.row, change.node.row) !== 0) {
207
209
  exists = true;
208
210
  break;
209
211
  }
210
212
  }
211
- if (exists) yield* this.#output.push(makeChildChange({
212
- ...parentNode,
213
- relationships: {
214
- ...parentNode.relationships,
215
- [this.#relationshipName]: childNodeStream
213
+ if (exists) yield* this.#output.push({
214
+ type: "child",
215
+ node: {
216
+ ...parentNode,
217
+ relationships: {
218
+ ...parentNode.relationships,
219
+ [this.#relationshipName]: childNodeStream
220
+ }
221
+ },
222
+ child: {
223
+ relationshipName: this.#relationshipName,
224
+ change
216
225
  }
217
- }, {
218
- relationshipName: this.#relationshipName,
219
- change
220
- }), this);
221
- else {
222
- const newNode = {
226
+ }, this);
227
+ else yield* this.#output.push({
228
+ ...change,
229
+ node: {
223
230
  ...parentNode,
224
231
  relationships: {
225
232
  ...parentNode.relationships,
226
- [this.#relationshipName]: () => [change[1]]
233
+ [this.#relationshipName]: () => [change.node]
227
234
  }
228
- };
229
- yield* this.#output.push(change[0] === 0 ? makeAddChange(newNode) : makeRemoveChange(newNode), this);
230
- }
235
+ }
236
+ }, this);
231
237
  }
232
238
  } finally {
233
239
  this.#inprogressChildChange = void 0;
@@ -246,7 +252,7 @@ var FlippedJoin = class {
246
252
  }
247
253
  });
248
254
  let hasRelatedChild = false;
249
- for (const node of childNodeStream(change[1])()) if (node === "yield") {
255
+ for (const node of childNodeStream(change.node)()) if (node === "yield") {
250
256
  yield "yield";
251
257
  continue;
252
258
  } else {
@@ -254,19 +260,22 @@ var FlippedJoin = class {
254
260
  break;
255
261
  }
256
262
  if (!hasRelatedChild) return;
257
- switch (change[0]) {
258
- case 0:
259
- yield* this.#output.push(makeAddChange(flip(change[1])), this);
260
- break;
261
- case 1:
262
- yield* this.#output.push(makeRemoveChange(flip(change[1])), this);
263
- break;
264
- case 3:
265
- yield* this.#output.push(makeChildChange(flip(change[1]), change[2]), this);
263
+ switch (change.type) {
264
+ case "add":
265
+ case "remove":
266
+ case "child":
267
+ yield* this.#output.push({
268
+ ...change,
269
+ node: flip(change.node)
270
+ }, this);
266
271
  break;
267
- case 2:
268
- assert(rowEqualsForCompoundKey(change[2].row, change[1].row, this.#parentKey), `Parent edit must not change relationship.`);
269
- yield* this.#output.push(makeEditChange(flip(change[1]), flip(change[2])), this);
272
+ case "edit":
273
+ assert(rowEqualsForCompoundKey(change.oldNode.row, change.node.row, this.#parentKey), `Parent edit must not change relationship.`);
274
+ yield* this.#output.push({
275
+ type: "edit",
276
+ oldNode: flip(change.oldNode),
277
+ node: flip(change.node)
278
+ }, this);
270
279
  break;
271
280
  default: unreachable(change);
272
281
  }