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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (819) hide show
  1. package/out/_virtual/{_@oxc-project_runtime@0.130.0/helpers → _@oxc-project_runtime@0.154.0/helpers/esm}/usingCtx.js +2 -2
  2. package/out/analyze-query/src/analyze-cli.d.ts.map +1 -1
  3. package/out/analyze-query/src/analyze-cli.js +6 -4
  4. package/out/analyze-query/src/analyze-cli.js.map +1 -1
  5. package/out/analyze-query/src/bin-transform.js +4 -3
  6. package/out/analyze-query/src/bin-transform.js.map +1 -1
  7. package/out/analyze-query/src/zql-chain.d.ts +23 -0
  8. package/out/analyze-query/src/zql-chain.d.ts.map +1 -0
  9. package/out/analyze-query/src/zql-chain.js +162 -0
  10. package/out/analyze-query/src/zql-chain.js.map +1 -0
  11. package/out/ast-to-zql/src/ast-to-zql.js.map +1 -1
  12. package/out/ast-to-zql/src/bin.js +4 -3
  13. package/out/ast-to-zql/src/bin.js.map +1 -1
  14. package/out/ast-to-zql/src/format.js.map +1 -1
  15. package/out/datadog/src/datadog-log-sink.js +5 -4
  16. package/out/datadog/src/datadog-log-sink.js.map +1 -1
  17. package/out/otel/src/log-options.js.map +1 -1
  18. package/out/replicache/src/btree/node.js +13 -11
  19. package/out/replicache/src/btree/node.js.map +1 -1
  20. package/out/replicache/src/btree/read.js +4 -2
  21. package/out/replicache/src/btree/read.js.map +1 -1
  22. package/out/replicache/src/btree/splice.js.map +1 -1
  23. package/out/replicache/src/btree/write.js +9 -5
  24. package/out/replicache/src/btree/write.js.map +1 -1
  25. package/out/replicache/src/config.js +1 -2
  26. package/out/replicache/src/connection-loop.js.map +1 -1
  27. package/out/replicache/src/dag/chunk.js +1 -1
  28. package/out/replicache/src/dag/gc.js.map +1 -1
  29. package/out/replicache/src/dag/lazy-store.js +8 -7
  30. package/out/replicache/src/dag/lazy-store.js.map +1 -1
  31. package/out/replicache/src/dag/store-impl.js +1 -1
  32. package/out/replicache/src/dag/store-impl.js.map +1 -1
  33. package/out/replicache/src/dag/visitor.js.map +1 -1
  34. package/out/replicache/src/db/commit.js +5 -3
  35. package/out/replicache/src/db/commit.js.map +1 -1
  36. package/out/replicache/src/db/read.js +1 -1
  37. package/out/replicache/src/db/read.js.map +1 -1
  38. package/out/replicache/src/db/rebase.js.map +1 -1
  39. package/out/replicache/src/db/write.js +5 -2
  40. package/out/replicache/src/db/write.js.map +1 -1
  41. package/out/replicache/src/deleted-clients.js +3 -2
  42. package/out/replicache/src/deleted-clients.js.map +1 -1
  43. package/out/replicache/src/expo-sqlite.js +1 -2
  44. package/out/replicache/src/frozen-json.js +1 -1
  45. package/out/replicache/src/frozen-json.js.map +1 -1
  46. package/out/replicache/src/get-default-puller.js +1 -1
  47. package/out/replicache/src/hash.js +1 -1
  48. package/out/replicache/src/hash.js.map +1 -1
  49. package/out/replicache/src/impl.js +1 -2
  50. package/out/replicache/src/index-defs.js +5 -3
  51. package/out/replicache/src/index-defs.js.map +1 -1
  52. package/out/replicache/src/kv/expo-sqlite/store.js +1 -1
  53. package/out/replicache/src/kv/expo-sqlite/store.js.map +1 -1
  54. package/out/replicache/src/kv/idb-store.js +1 -1
  55. package/out/replicache/src/kv/idb-store.js.map +1 -1
  56. package/out/replicache/src/kv/mem-fallback-store.js +1 -1
  57. package/out/replicache/src/kv/mem-fallback-store.js.map +1 -1
  58. package/out/replicache/src/kv/mem-store.js.map +1 -1
  59. package/out/replicache/src/kv/op-sqlite/store.js.map +1 -1
  60. package/out/replicache/src/kv/op-sqlite/types.js.map +1 -1
  61. package/out/replicache/src/kv/read-impl.js.map +1 -1
  62. package/out/replicache/src/kv/sqlite-store.js +1 -1
  63. package/out/replicache/src/kv/sqlite-store.js.map +1 -1
  64. package/out/replicache/src/kv/write-impl-base.js +4 -1
  65. package/out/replicache/src/kv/write-impl-base.js.map +1 -1
  66. package/out/replicache/src/kv/write-impl.js.map +1 -1
  67. package/out/replicache/src/log-options.js +2 -1
  68. package/out/replicache/src/log-options.js.map +1 -1
  69. package/out/replicache/src/make-idb-name.js +1 -1
  70. package/out/replicache/src/new-client-channel.js +9 -7
  71. package/out/replicache/src/new-client-channel.js.map +1 -1
  72. package/out/replicache/src/on-persist-channel.js +1 -1
  73. package/out/replicache/src/on-persist-channel.js.map +1 -1
  74. package/out/replicache/src/op-sqlite.js +1 -2
  75. package/out/replicache/src/pending-mutations.js +2 -1
  76. package/out/replicache/src/pending-mutations.js.map +1 -1
  77. package/out/replicache/src/persist/client-gc.js +2 -2
  78. package/out/replicache/src/persist/client-gc.js.map +1 -1
  79. package/out/replicache/src/persist/client-group-gc.js +2 -2
  80. package/out/replicache/src/persist/client-group-gc.js.map +1 -1
  81. package/out/replicache/src/persist/client-groups.js +1 -1
  82. package/out/replicache/src/persist/client-groups.js.map +1 -1
  83. package/out/replicache/src/persist/clients.js +1 -1
  84. package/out/replicache/src/persist/clients.js.map +1 -1
  85. package/out/replicache/src/persist/collect-idb-databases.js +5 -4
  86. package/out/replicache/src/persist/collect-idb-databases.js.map +1 -1
  87. package/out/replicache/src/persist/gather-mem-only-visitor.js.map +1 -1
  88. package/out/replicache/src/persist/gather-not-cached-visitor.js.map +1 -1
  89. package/out/replicache/src/persist/heartbeat.js +2 -2
  90. package/out/replicache/src/persist/heartbeat.js.map +1 -1
  91. package/out/replicache/src/persist/idb-databases-store.js +1 -1
  92. package/out/replicache/src/persist/idb-databases-store.js.map +1 -1
  93. package/out/replicache/src/persist/make-client-id.js +1 -1
  94. package/out/replicache/src/persist/make-client-id.js.map +1 -1
  95. package/out/replicache/src/persist/persist.js +3 -2
  96. package/out/replicache/src/persist/persist.js.map +1 -1
  97. package/out/replicache/src/persist/refresh.js +8 -5
  98. package/out/replicache/src/persist/refresh.js.map +1 -1
  99. package/out/replicache/src/process-scheduler.js.map +1 -1
  100. package/out/replicache/src/replicache-impl.js +3 -3
  101. package/out/replicache/src/replicache-impl.js.map +1 -1
  102. package/out/replicache/src/scan-iterator.js.map +1 -1
  103. package/out/replicache/src/scan-options.js +7 -6
  104. package/out/replicache/src/scan-options.js.map +1 -1
  105. package/out/replicache/src/sqlite.js +1 -2
  106. package/out/replicache/src/subscriptions.js +1 -1
  107. package/out/replicache/src/subscriptions.js.map +1 -1
  108. package/out/replicache/src/sync/diff.js +3 -1
  109. package/out/replicache/src/sync/diff.js.map +1 -1
  110. package/out/replicache/src/sync/ids.js.map +1 -1
  111. package/out/replicache/src/sync/patch.js +2 -4
  112. package/out/replicache/src/sync/patch.js.map +1 -1
  113. package/out/replicache/src/sync/pull.js +3 -1
  114. package/out/replicache/src/sync/pull.js.map +1 -1
  115. package/out/replicache/src/sync/push.js.map +1 -1
  116. package/out/replicache/src/sync/request-id.js +1 -1
  117. package/out/replicache/src/sync/request-id.js.map +1 -1
  118. package/out/replicache/src/transactions.js +1 -1
  119. package/out/replicache/src/transactions.js.map +1 -1
  120. package/out/shared/src/arrays.js +4 -1
  121. package/out/shared/src/arrays.js.map +1 -1
  122. package/out/shared/src/asserts.js +1 -1
  123. package/out/shared/src/bigint-json.d.ts +9 -0
  124. package/out/shared/src/bigint-json.d.ts.map +1 -1
  125. package/out/shared/src/bigint-json.js +27 -2
  126. package/out/shared/src/bigint-json.js.map +1 -1
  127. package/out/shared/src/broadcast-channel.js +1 -1
  128. package/out/shared/src/btree-set.js +11 -8
  129. package/out/shared/src/btree-set.js.map +1 -1
  130. package/out/shared/src/cache.js.map +1 -1
  131. package/out/shared/src/config.js +1 -1
  132. package/out/shared/src/custom-key-map.js.map +1 -1
  133. package/out/shared/src/custom-key-set.js.map +1 -1
  134. package/out/shared/src/deep-clone.js +1 -1
  135. package/out/shared/src/document-visible.js.map +1 -1
  136. package/out/shared/src/dotenv.js.map +1 -1
  137. package/out/shared/src/error.js +1 -1
  138. package/out/shared/src/error.js.map +1 -1
  139. package/out/shared/src/hash.js +2 -2
  140. package/out/shared/src/hash.js.map +1 -1
  141. package/out/shared/src/iterables.js.map +1 -1
  142. package/out/shared/src/json-schema.js.map +1 -1
  143. package/out/shared/src/json.js.map +1 -1
  144. package/out/shared/src/logging-test-utils.js +1 -1
  145. package/out/shared/src/logging.js +1 -1
  146. package/out/shared/src/logging.js.map +1 -1
  147. package/out/shared/src/navigator.js +1 -1
  148. package/out/shared/src/options.js +9 -12
  149. package/out/shared/src/options.js.map +1 -1
  150. package/out/shared/src/promise-race.js.map +1 -1
  151. package/out/shared/src/queue.js.map +1 -1
  152. package/out/shared/src/record-proxy.js.map +1 -1
  153. package/out/shared/src/ring-buffer.js.map +1 -1
  154. package/out/shared/src/size-of-value.js +7 -10
  155. package/out/shared/src/size-of-value.js.map +1 -1
  156. package/out/shared/src/sorted-entries.js.map +1 -1
  157. package/out/shared/src/tdigest-schema.js.map +1 -1
  158. package/out/shared/src/tdigest.js.map +1 -1
  159. package/out/shared/src/valita.js +1 -1
  160. package/out/shared/src/valita.js.map +1 -1
  161. package/out/z2s/src/compiler.js +2 -4
  162. package/out/z2s/src/compiler.js.map +1 -1
  163. package/out/z2s/src/sql.js +1 -1
  164. package/out/z2s/src/sql.js.map +1 -1
  165. package/out/zero/package.js +211 -189
  166. package/out/zero/package.js.map +1 -1
  167. package/out/zero/src/adapters/drizzle.js +1 -2
  168. package/out/zero/src/adapters/kysely.js +1 -2
  169. package/out/zero/src/adapters/pg.js +1 -2
  170. package/out/zero/src/adapters/postgresjs.js +1 -2
  171. package/out/zero/src/adapters/prisma.js +1 -2
  172. package/out/zero/src/analyze.js +1 -2
  173. package/out/zero/src/change-protocol/v0.js +1 -2
  174. package/out/zero/src/expo-sqlite.js +1 -2
  175. package/out/zero/src/op-sqlite.js +1 -2
  176. package/out/zero/src/react-native.js.map +1 -1
  177. package/out/zero/src/sqlite.js +1 -2
  178. package/out/zero/src/zero-cache-dev.js +10 -9
  179. package/out/zero/src/zero-cache-dev.js.map +1 -1
  180. package/out/zero/src/zero-out.js +2 -1
  181. package/out/zero/src/zero-out.js.map +1 -1
  182. package/out/zero-cache/src/auth/auth.js +1 -1
  183. package/out/zero-cache/src/auth/auth.js.map +1 -1
  184. package/out/zero-cache/src/auth/jwt.js +4 -1
  185. package/out/zero-cache/src/auth/jwt.js.map +1 -1
  186. package/out/zero-cache/src/auth/load-permissions.js +1 -1
  187. package/out/zero-cache/src/auth/load-permissions.js.map +1 -1
  188. package/out/zero-cache/src/auth/read-authorizer.js +3 -2
  189. package/out/zero-cache/src/auth/read-authorizer.js.map +1 -1
  190. package/out/zero-cache/src/auth/write-authorizer.js +6 -17
  191. package/out/zero-cache/src/auth/write-authorizer.js.map +1 -1
  192. package/out/zero-cache/src/config/network.js +1 -1
  193. package/out/zero-cache/src/config/network.js.map +1 -1
  194. package/out/zero-cache/src/config/server-context.js.map +1 -1
  195. package/out/zero-cache/src/config/zero-config.d.ts +5 -0
  196. package/out/zero-cache/src/config/zero-config.d.ts.map +1 -1
  197. package/out/zero-cache/src/config/zero-config.js +13 -2
  198. package/out/zero-cache/src/config/zero-config.js.map +1 -1
  199. package/out/zero-cache/src/custom/fetch.js +1 -1
  200. package/out/zero-cache/src/custom/fetch.js.map +1 -1
  201. package/out/zero-cache/src/custom-queries/transform-query.js.map +1 -1
  202. package/out/zero-cache/src/db/create.js.map +1 -1
  203. package/out/zero-cache/src/db/index-predicate.js.map +1 -1
  204. package/out/zero-cache/src/db/lite-tables.d.ts +2 -2
  205. package/out/zero-cache/src/db/lite-tables.d.ts.map +1 -1
  206. package/out/zero-cache/src/db/lite-tables.js.map +1 -1
  207. package/out/zero-cache/src/db/migration-lite.js +1 -1
  208. package/out/zero-cache/src/db/migration-lite.js.map +1 -1
  209. package/out/zero-cache/src/db/migration.js +5 -3
  210. package/out/zero-cache/src/db/migration.js.map +1 -1
  211. package/out/zero-cache/src/db/pg-copy-binary.js +4 -3
  212. package/out/zero-cache/src/db/pg-copy-binary.js.map +1 -1
  213. package/out/zero-cache/src/db/pg-copy.js +0 -1
  214. package/out/zero-cache/src/db/pg-copy.js.map +1 -1
  215. package/out/zero-cache/src/db/pg-to-lite.js +1 -1
  216. package/out/zero-cache/src/db/pg-to-lite.js.map +1 -1
  217. package/out/zero-cache/src/db/run-transaction.js.map +1 -1
  218. package/out/zero-cache/src/db/specs.js +7 -5
  219. package/out/zero-cache/src/db/specs.js.map +1 -1
  220. package/out/zero-cache/src/db/sqlite-corruption.js.map +1 -1
  221. package/out/zero-cache/src/db/statements.d.ts.map +1 -1
  222. package/out/zero-cache/src/db/statements.js +9 -2
  223. package/out/zero-cache/src/db/statements.js.map +1 -1
  224. package/out/zero-cache/src/db/transaction-pool.js +5 -3
  225. package/out/zero-cache/src/db/transaction-pool.js.map +1 -1
  226. package/out/zero-cache/src/db/warmup.js.map +1 -1
  227. package/out/zero-cache/src/observability/events.js.map +1 -1
  228. package/out/zero-cache/src/observability/log-throttle.js.map +1 -1
  229. package/out/zero-cache/src/observability/metrics.js.map +1 -1
  230. package/out/zero-cache/src/scripts/decommission.js +1 -1
  231. package/out/zero-cache/src/scripts/deploy-permissions.js +5 -3
  232. package/out/zero-cache/src/scripts/deploy-permissions.js.map +1 -1
  233. package/out/zero-cache/src/scripts/permissions.js.map +1 -1
  234. package/out/zero-cache/src/server/anonymous-otel-start.js +2 -1
  235. package/out/zero-cache/src/server/anonymous-otel-start.js.map +1 -1
  236. package/out/zero-cache/src/server/change-streamer.js +1 -1
  237. package/out/zero-cache/src/server/change-streamer.js.map +1 -1
  238. package/out/zero-cache/src/server/inspector-delegate.js.map +1 -1
  239. package/out/zero-cache/src/server/logging.js +1 -1
  240. package/out/zero-cache/src/server/logging.js.map +1 -1
  241. package/out/zero-cache/src/server/main.js.map +1 -1
  242. package/out/zero-cache/src/server/otel-log-sink.js.map +1 -1
  243. package/out/zero-cache/src/server/otel-start.js.map +1 -1
  244. package/out/zero-cache/src/server/reaper.js +2 -2
  245. package/out/zero-cache/src/server/reaper.js.map +1 -1
  246. package/out/zero-cache/src/server/replicator.js +1 -1
  247. package/out/zero-cache/src/server/replicator.js.map +1 -1
  248. package/out/zero-cache/src/server/runner/run-worker.js +2 -1
  249. package/out/zero-cache/src/server/runner/run-worker.js.map +1 -1
  250. package/out/zero-cache/src/server/runner/runtime.js +2 -1
  251. package/out/zero-cache/src/server/runner/runtime.js.map +1 -1
  252. package/out/zero-cache/src/server/runner/zero-dispatcher.js.map +1 -1
  253. package/out/zero-cache/src/server/shadow-syncer.js +1 -1
  254. package/out/zero-cache/src/server/shadow-syncer.js.map +1 -1
  255. package/out/zero-cache/src/server/slot-keeper.js.map +1 -1
  256. package/out/zero-cache/src/server/syncer-assigner.js.map +1 -1
  257. package/out/zero-cache/src/server/syncer.d.ts.map +1 -1
  258. package/out/zero-cache/src/server/syncer.js +9 -4
  259. package/out/zero-cache/src/server/syncer.js.map +1 -1
  260. package/out/zero-cache/src/server/worker-dispatcher.js +1 -1
  261. package/out/zero-cache/src/server/worker-dispatcher.js.map +1 -1
  262. package/out/zero-cache/src/server/worker-urls.js.map +1 -1
  263. package/out/zero-cache/src/services/analyze.js +2 -2
  264. package/out/zero-cache/src/services/analyze.js.map +1 -1
  265. package/out/zero-cache/src/services/change-source/common/backfill-manager.js +2 -2
  266. package/out/zero-cache/src/services/change-source/common/backfill-manager.js.map +1 -1
  267. package/out/zero-cache/src/services/change-source/common/change-stream-multiplexer.js.map +1 -1
  268. package/out/zero-cache/src/services/change-source/common/init-cleanup.js.map +1 -1
  269. package/out/zero-cache/src/services/change-source/common/replica-restore.js.map +1 -1
  270. package/out/zero-cache/src/services/change-source/common/replica-schema.js +4 -4
  271. package/out/zero-cache/src/services/change-source/common/replica-schema.js.map +1 -1
  272. package/out/zero-cache/src/services/change-source/custom/change-source.js +4 -4
  273. package/out/zero-cache/src/services/change-source/custom/change-source.js.map +1 -1
  274. package/out/zero-cache/src/services/change-source/pg/backfill-metadata.js.map +1 -1
  275. package/out/zero-cache/src/services/change-source/pg/backfill-stream.js +4 -4
  276. package/out/zero-cache/src/services/change-source/pg/backfill-stream.js.map +1 -1
  277. package/out/zero-cache/src/services/change-source/pg/change-source-init.js +3 -3
  278. package/out/zero-cache/src/services/change-source/pg/change-source-init.js.map +1 -1
  279. package/out/zero-cache/src/services/change-source/pg/change-source.js +6 -8
  280. package/out/zero-cache/src/services/change-source/pg/change-source.js.map +1 -1
  281. package/out/zero-cache/src/services/change-source/pg/decommission.js +2 -1
  282. package/out/zero-cache/src/services/change-source/pg/decommission.js.map +1 -1
  283. package/out/zero-cache/src/services/change-source/pg/initial-sync.js +9 -7
  284. package/out/zero-cache/src/services/change-source/pg/initial-sync.js.map +1 -1
  285. package/out/zero-cache/src/services/change-source/pg/logical-replication/binary-reader.js.map +1 -1
  286. package/out/zero-cache/src/services/change-source/pg/logical-replication/pgoutput-parser.js.map +1 -1
  287. package/out/zero-cache/src/services/change-source/pg/logical-replication/stream.js +5 -4
  288. package/out/zero-cache/src/services/change-source/pg/logical-replication/stream.js.map +1 -1
  289. package/out/zero-cache/src/services/change-source/pg/lsn.js.map +1 -1
  290. package/out/zero-cache/src/services/change-source/pg/replication-slot-cleanup-monitor.js +2 -2
  291. package/out/zero-cache/src/services/change-source/pg/replication-slot-cleanup-monitor.js.map +1 -1
  292. package/out/zero-cache/src/services/change-source/pg/replication-slot-health.js +1 -1
  293. package/out/zero-cache/src/services/change-source/pg/replication-slot-health.js.map +1 -1
  294. package/out/zero-cache/src/services/change-source/pg/replication-slots.js +3 -3
  295. package/out/zero-cache/src/services/change-source/pg/replication-slots.js.map +1 -1
  296. package/out/zero-cache/src/services/change-source/pg/schema/ddl.js +2 -2
  297. package/out/zero-cache/src/services/change-source/pg/schema/ddl.js.map +1 -1
  298. package/out/zero-cache/src/services/change-source/pg/schema/index-predicate.js +13 -12
  299. package/out/zero-cache/src/services/change-source/pg/schema/index-predicate.js.map +1 -1
  300. package/out/zero-cache/src/services/change-source/pg/schema/init.js +1 -1
  301. package/out/zero-cache/src/services/change-source/pg/schema/init.js.map +1 -1
  302. package/out/zero-cache/src/services/change-source/pg/schema/published.js +2 -2
  303. package/out/zero-cache/src/services/change-source/pg/schema/published.js.map +1 -1
  304. package/out/zero-cache/src/services/change-source/pg/schema/replica-stage-enum.js.map +1 -1
  305. package/out/zero-cache/src/services/change-source/pg/schema/shard.js +10 -7
  306. package/out/zero-cache/src/services/change-source/pg/schema/shard.js.map +1 -1
  307. package/out/zero-cache/src/services/change-source/pg/schema/validation.js +1 -1
  308. package/out/zero-cache/src/services/change-source/pg/schema/validation.js.map +1 -1
  309. package/out/zero-cache/src/services/change-source/protocol/backfill-progress.js +1 -1
  310. package/out/zero-cache/src/services/change-source/protocol/backfill-progress.js.map +1 -1
  311. package/out/zero-cache/src/services/change-source/protocol/current/control.js.map +1 -1
  312. package/out/zero-cache/src/services/change-source/protocol/current/data.js.map +1 -1
  313. package/out/zero-cache/src/services/change-source/protocol/current/downstream.js.map +1 -1
  314. package/out/zero-cache/src/services/change-source/protocol/current/status.js.map +1 -1
  315. package/out/zero-cache/src/services/change-source/protocol/current/upstream.js.map +1 -1
  316. package/out/zero-cache/src/services/change-source/protocol/current.js +1 -1
  317. package/out/zero-cache/src/services/change-source/protocol/mod.js +1 -2
  318. package/out/zero-cache/src/services/change-streamer/backfill-state-tracker.js.map +1 -1
  319. package/out/zero-cache/src/services/change-streamer/backfill-state.js +1 -1
  320. package/out/zero-cache/src/services/change-streamer/backfill-state.js.map +1 -1
  321. package/out/zero-cache/src/services/change-streamer/backup-cleanup-monitor-factory.js.map +1 -1
  322. package/out/zero-cache/src/services/change-streamer/backup-monitor.js.map +1 -1
  323. package/out/zero-cache/src/services/change-streamer/broadcast.js +1 -1
  324. package/out/zero-cache/src/services/change-streamer/broadcast.js.map +1 -1
  325. package/out/zero-cache/src/services/change-streamer/change-log-codec.d.ts +1 -1
  326. package/out/zero-cache/src/services/change-streamer/change-log-codec.d.ts.map +1 -1
  327. package/out/zero-cache/src/services/change-streamer/change-log-codec.js +2 -3
  328. package/out/zero-cache/src/services/change-streamer/change-log-codec.js.map +1 -1
  329. package/out/zero-cache/src/services/change-streamer/change-log-initializer.js +3 -3
  330. package/out/zero-cache/src/services/change-streamer/change-log-initializer.js.map +1 -1
  331. package/out/zero-cache/src/services/change-streamer/change-log-transaction-hash.js.map +1 -1
  332. package/out/zero-cache/src/services/change-streamer/change-streamer-http.js +5 -3
  333. package/out/zero-cache/src/services/change-streamer/change-streamer-http.js.map +1 -1
  334. package/out/zero-cache/src/services/change-streamer/change-streamer-service.js +21 -21
  335. package/out/zero-cache/src/services/change-streamer/change-streamer-service.js.map +1 -1
  336. package/out/zero-cache/src/services/change-streamer/change-streamer.js +1 -1
  337. package/out/zero-cache/src/services/change-streamer/change-streamer.js.map +1 -1
  338. package/out/zero-cache/src/services/change-streamer/drain-tracker.js.map +1 -1
  339. package/out/zero-cache/src/services/change-streamer/forwarder.js +11 -10
  340. package/out/zero-cache/src/services/change-streamer/forwarder.js.map +1 -1
  341. package/out/zero-cache/src/services/change-streamer/litestream-sync-requester.js +1 -1
  342. package/out/zero-cache/src/services/change-streamer/litestream-sync-requester.js.map +1 -1
  343. package/out/zero-cache/src/services/change-streamer/litestream3-prometheus-poller.js +3 -3
  344. package/out/zero-cache/src/services/change-streamer/litestream3-prometheus-poller.js.map +1 -1
  345. package/out/zero-cache/src/services/change-streamer/replica-poller.js +2 -2
  346. package/out/zero-cache/src/services/change-streamer/replica-poller.js.map +1 -1
  347. package/out/zero-cache/src/services/change-streamer/restore-admission.js +12 -1
  348. package/out/zero-cache/src/services/change-streamer/restore-admission.js.map +1 -1
  349. package/out/zero-cache/src/services/change-streamer/schema/init.js +1 -1
  350. package/out/zero-cache/src/services/change-streamer/schema/init.js.map +1 -1
  351. package/out/zero-cache/src/services/change-streamer/schema/tables.js +1 -1
  352. package/out/zero-cache/src/services/change-streamer/schema/tables.js.map +1 -1
  353. package/out/zero-cache/src/services/change-streamer/snapshot-message.js +1 -1
  354. package/out/zero-cache/src/services/change-streamer/snapshot-message.js.map +1 -1
  355. package/out/zero-cache/src/services/change-streamer/snapshot-reservations.js.map +1 -1
  356. package/out/zero-cache/src/services/change-streamer/sqlite-change-log-catchup.js +1 -1
  357. package/out/zero-cache/src/services/change-streamer/sqlite-change-log-catchup.js.map +1 -1
  358. package/out/zero-cache/src/services/change-streamer/sqlite-change-log-comparator.js +2 -2
  359. package/out/zero-cache/src/services/change-streamer/sqlite-change-log-comparator.js.map +1 -1
  360. package/out/zero-cache/src/services/change-streamer/sqlite-change-log-purge-scheduler.js.map +1 -1
  361. package/out/zero-cache/src/services/change-streamer/sqlite-change-log-read-router.js.map +1 -1
  362. package/out/zero-cache/src/services/change-streamer/sqlite-change-log-reader.d.ts.map +1 -1
  363. package/out/zero-cache/src/services/change-streamer/sqlite-change-log-reader.js +4 -6
  364. package/out/zero-cache/src/services/change-streamer/sqlite-change-log-reader.js.map +1 -1
  365. package/out/zero-cache/src/services/change-streamer/sqlite-change-log-writer.js +3 -5
  366. package/out/zero-cache/src/services/change-streamer/sqlite-change-log-writer.js.map +1 -1
  367. package/out/zero-cache/src/services/change-streamer/storer.d.ts.map +1 -1
  368. package/out/zero-cache/src/services/change-streamer/storer.js +3 -3
  369. package/out/zero-cache/src/services/change-streamer/storer.js.map +1 -1
  370. package/out/zero-cache/src/services/change-streamer/subscribe.js +1 -1
  371. package/out/zero-cache/src/services/change-streamer/subscribe.js.map +1 -1
  372. package/out/zero-cache/src/services/change-streamer/subscriber.js +2 -2
  373. package/out/zero-cache/src/services/change-streamer/subscriber.js.map +1 -1
  374. package/out/zero-cache/src/services/change-streamer/upstream-acker.js +0 -1
  375. package/out/zero-cache/src/services/change-streamer/upstream-acker.js.map +1 -1
  376. package/out/zero-cache/src/services/heapz.js +2 -1
  377. package/out/zero-cache/src/services/heapz.js.map +1 -1
  378. package/out/zero-cache/src/services/http-service.js.map +1 -1
  379. package/out/zero-cache/src/services/life-cycle.js +2 -2
  380. package/out/zero-cache/src/services/life-cycle.js.map +1 -1
  381. package/out/zero-cache/src/services/limiter/sliding-window-limiter.js +4 -2
  382. package/out/zero-cache/src/services/limiter/sliding-window-limiter.js.map +1 -1
  383. package/out/zero-cache/src/services/litestream/commands.js +3 -3
  384. package/out/zero-cache/src/services/litestream/commands.js.map +1 -1
  385. package/out/zero-cache/src/services/litestream/litestream-checkpointer.js +2 -2
  386. package/out/zero-cache/src/services/litestream/litestream-checkpointer.js.map +1 -1
  387. package/out/zero-cache/src/services/litestream/litestream-controller.js.map +1 -1
  388. package/out/zero-cache/src/services/litestream/metrics.js.map +1 -1
  389. package/out/zero-cache/src/services/litestream/restore-progress.js.map +1 -1
  390. package/out/zero-cache/src/services/mutagen/mutagen.js +1 -1
  391. package/out/zero-cache/src/services/mutagen/mutagen.js.map +1 -1
  392. package/out/zero-cache/src/services/mutagen/pusher.js +3 -2
  393. package/out/zero-cache/src/services/mutagen/pusher.js.map +1 -1
  394. package/out/zero-cache/src/services/plannerz.js +6 -5
  395. package/out/zero-cache/src/services/plannerz.js.map +1 -1
  396. package/out/zero-cache/src/services/profz.js +5 -3
  397. package/out/zero-cache/src/services/profz.js.map +1 -1
  398. package/out/zero-cache/src/services/replicator/change-log-cookies.js.map +1 -1
  399. package/out/zero-cache/src/services/replicator/change-log-db.js +4 -3
  400. package/out/zero-cache/src/services/replicator/change-log-db.js.map +1 -1
  401. package/out/zero-cache/src/services/replicator/change-log-stream-writer.js +1 -1
  402. package/out/zero-cache/src/services/replicator/change-log-stream-writer.js.map +1 -1
  403. package/out/zero-cache/src/services/replicator/change-processor.js.map +1 -1
  404. package/out/zero-cache/src/services/replicator/drain-handler.js.map +1 -1
  405. package/out/zero-cache/src/services/replicator/incremental-sync.js +4 -4
  406. package/out/zero-cache/src/services/replicator/incremental-sync.js.map +1 -1
  407. package/out/zero-cache/src/services/replicator/notifier.js.map +1 -1
  408. package/out/zero-cache/src/services/replicator/replication-status.js +4 -3
  409. package/out/zero-cache/src/services/replicator/replication-status.js.map +1 -1
  410. package/out/zero-cache/src/services/replicator/replicator.js.map +1 -1
  411. package/out/zero-cache/src/services/replicator/reporter/recorder.js +1 -1
  412. package/out/zero-cache/src/services/replicator/reporter/recorder.js.map +1 -1
  413. package/out/zero-cache/src/services/replicator/reporter/report-schema.js +1 -1
  414. package/out/zero-cache/src/services/replicator/reporter/report-schema.js.map +1 -1
  415. package/out/zero-cache/src/services/replicator/schema/backfilling.js +2 -2
  416. package/out/zero-cache/src/services/replicator/schema/backfilling.js.map +1 -1
  417. package/out/zero-cache/src/services/replicator/schema/change-log.d.ts +19 -7
  418. package/out/zero-cache/src/services/replicator/schema/change-log.d.ts.map +1 -1
  419. package/out/zero-cache/src/services/replicator/schema/change-log.js +31 -15
  420. package/out/zero-cache/src/services/replicator/schema/change-log.js.map +1 -1
  421. package/out/zero-cache/src/services/replicator/schema/column-metadata.js +1 -1
  422. package/out/zero-cache/src/services/replicator/schema/column-metadata.js.map +1 -1
  423. package/out/zero-cache/src/services/replicator/schema/replication-state.js +10 -7
  424. package/out/zero-cache/src/services/replicator/schema/replication-state.js.map +1 -1
  425. package/out/zero-cache/src/services/replicator/schema/table-metadata.js.map +1 -1
  426. package/out/zero-cache/src/services/replicator/sqlite-change-log-observability.js +1 -1
  427. package/out/zero-cache/src/services/replicator/sqlite-change-log-observability.js.map +1 -1
  428. package/out/zero-cache/src/services/replicator/sqlite-change-log-purger.js +1 -1
  429. package/out/zero-cache/src/services/replicator/sqlite-change-log-purger.js.map +1 -1
  430. package/out/zero-cache/src/services/replicator/write-worker-client.js +1 -1
  431. package/out/zero-cache/src/services/replicator/write-worker-client.js.map +1 -1
  432. package/out/zero-cache/src/services/replicator/write-worker.js +3 -3
  433. package/out/zero-cache/src/services/replicator/write-worker.js.map +1 -1
  434. package/out/zero-cache/src/services/run-ast.js +1 -1
  435. package/out/zero-cache/src/services/run-ast.js.map +1 -1
  436. package/out/zero-cache/src/services/runner.js.map +1 -1
  437. package/out/zero-cache/src/services/running-state.js.map +1 -1
  438. package/out/zero-cache/src/services/shadow-sync/shadow-sync-service.js.map +1 -1
  439. package/out/zero-cache/src/services/statz.js +4 -3
  440. package/out/zero-cache/src/services/statz.js.map +1 -1
  441. package/out/zero-cache/src/services/view-syncer/active-users-gauge.js +2 -2
  442. package/out/zero-cache/src/services/view-syncer/active-users-gauge.js.map +1 -1
  443. package/out/zero-cache/src/services/view-syncer/advancement-metrics.js.map +1 -1
  444. package/out/zero-cache/src/services/view-syncer/batch-pacer.js.map +1 -1
  445. package/out/zero-cache/src/services/view-syncer/client-handler.d.ts.map +1 -1
  446. package/out/zero-cache/src/services/view-syncer/client-handler.js +24 -3
  447. package/out/zero-cache/src/services/view-syncer/client-handler.js.map +1 -1
  448. package/out/zero-cache/src/services/view-syncer/client-schema.d.ts +15 -2
  449. package/out/zero-cache/src/services/view-syncer/client-schema.d.ts.map +1 -1
  450. package/out/zero-cache/src/services/view-syncer/client-schema.js +46 -6
  451. package/out/zero-cache/src/services/view-syncer/client-schema.js.map +1 -1
  452. package/out/zero-cache/src/services/view-syncer/connection-context-manager.js.map +1 -1
  453. package/out/zero-cache/src/services/view-syncer/cvr-purger.js +2 -2
  454. package/out/zero-cache/src/services/view-syncer/cvr-purger.js.map +1 -1
  455. package/out/zero-cache/src/services/view-syncer/cvr-store.d.ts.map +1 -1
  456. package/out/zero-cache/src/services/view-syncer/cvr-store.js +11 -6
  457. package/out/zero-cache/src/services/view-syncer/cvr-store.js.map +1 -1
  458. package/out/zero-cache/src/services/view-syncer/cvr.js +12 -4
  459. package/out/zero-cache/src/services/view-syncer/cvr.js.map +1 -1
  460. package/out/zero-cache/src/services/view-syncer/deferred-writes-budget.js +1 -1
  461. package/out/zero-cache/src/services/view-syncer/deferred-writes-budget.js.map +1 -1
  462. package/out/zero-cache/src/services/view-syncer/drain-coordinator.js.map +1 -1
  463. package/out/zero-cache/src/services/view-syncer/e2e-serving-lag.js.map +1 -1
  464. package/out/zero-cache/src/services/view-syncer/hydration-budget.js.map +1 -1
  465. package/out/zero-cache/src/services/view-syncer/hydration-circuit-breaker.js +2 -2
  466. package/out/zero-cache/src/services/view-syncer/hydration-circuit-breaker.js.map +1 -1
  467. package/out/zero-cache/src/services/view-syncer/inspect-handler.js +6 -4
  468. package/out/zero-cache/src/services/view-syncer/inspect-handler.js.map +1 -1
  469. package/out/zero-cache/src/services/view-syncer/pipeline-driver.d.ts.map +1 -1
  470. package/out/zero-cache/src/services/view-syncer/pipeline-driver.js +13 -10
  471. package/out/zero-cache/src/services/view-syncer/pipeline-driver.js.map +1 -1
  472. package/out/zero-cache/src/services/view-syncer/plan-warnings.js.map +1 -1
  473. package/out/zero-cache/src/services/view-syncer/push-cost.js.map +1 -1
  474. package/out/zero-cache/src/services/view-syncer/push-cutoff.js.map +1 -1
  475. package/out/zero-cache/src/services/view-syncer/query-covering.js.map +1 -1
  476. package/out/zero-cache/src/services/view-syncer/query-shape.js.map +1 -1
  477. package/out/zero-cache/src/services/view-syncer/query-stats.js +1 -1
  478. package/out/zero-cache/src/services/view-syncer/query-stats.js.map +1 -1
  479. package/out/zero-cache/src/services/view-syncer/row-record-cache.js +1 -1
  480. package/out/zero-cache/src/services/view-syncer/row-record-cache.js.map +1 -1
  481. package/out/zero-cache/src/services/view-syncer/schema/cvr.js +1 -1
  482. package/out/zero-cache/src/services/view-syncer/schema/types.js +1 -1
  483. package/out/zero-cache/src/services/view-syncer/schema/types.js.map +1 -1
  484. package/out/zero-cache/src/services/view-syncer/snapshot-row-cache.js +7 -1
  485. package/out/zero-cache/src/services/view-syncer/snapshot-row-cache.js.map +1 -1
  486. package/out/zero-cache/src/services/view-syncer/snapshotter.d.ts +8 -1
  487. package/out/zero-cache/src/services/view-syncer/snapshotter.d.ts.map +1 -1
  488. package/out/zero-cache/src/services/view-syncer/snapshotter.js +7 -6
  489. package/out/zero-cache/src/services/view-syncer/snapshotter.js.map +1 -1
  490. package/out/zero-cache/src/services/view-syncer/ttl-clock.js.map +1 -1
  491. package/out/zero-cache/src/services/view-syncer/view-syncer.d.ts.map +1 -1
  492. package/out/zero-cache/src/services/view-syncer/view-syncer.js +19 -15
  493. package/out/zero-cache/src/services/view-syncer/view-syncer.js.map +1 -1
  494. package/out/zero-cache/src/types/error-with-level.js.map +1 -1
  495. package/out/zero-cache/src/types/lexi-version.js.map +1 -1
  496. package/out/zero-cache/src/types/lite.js +1 -1
  497. package/out/zero-cache/src/types/lite.js.map +1 -1
  498. package/out/zero-cache/src/types/pg-data-type.js +1 -1
  499. package/out/zero-cache/src/types/pg-data-type.js.map +1 -1
  500. package/out/zero-cache/src/types/pg.js +6 -4
  501. package/out/zero-cache/src/types/pg.js.map +1 -1
  502. package/out/zero-cache/src/types/poke-chunk.js +2 -2
  503. package/out/zero-cache/src/types/poke-chunk.js.map +1 -1
  504. package/out/zero-cache/src/types/processes.js +1 -1
  505. package/out/zero-cache/src/types/processes.js.map +1 -1
  506. package/out/zero-cache/src/types/profiler.js +1 -1
  507. package/out/zero-cache/src/types/profiler.js.map +1 -1
  508. package/out/zero-cache/src/types/row-key.js.map +1 -1
  509. package/out/zero-cache/src/types/sql.js.map +1 -1
  510. package/out/zero-cache/src/types/streams.js +10 -9
  511. package/out/zero-cache/src/types/streams.js.map +1 -1
  512. package/out/zero-cache/src/types/strings.js.map +1 -1
  513. package/out/zero-cache/src/types/subscription.js.map +1 -1
  514. package/out/zero-cache/src/types/timeout.js +1 -1
  515. package/out/zero-cache/src/types/websocket-handoff.js +1 -1
  516. package/out/zero-cache/src/types/ws.js +1 -1
  517. package/out/zero-cache/src/workers/connection.js +5 -6
  518. package/out/zero-cache/src/workers/connection.js.map +1 -1
  519. package/out/zero-cache/src/workers/mutator.js.map +1 -1
  520. package/out/zero-cache/src/workers/replicator.js +5 -4
  521. package/out/zero-cache/src/workers/replicator.js.map +1 -1
  522. package/out/zero-cache/src/workers/syncer-ws-message-handler.d.ts.map +1 -1
  523. package/out/zero-cache/src/workers/syncer-ws-message-handler.js +9 -1
  524. package/out/zero-cache/src/workers/syncer-ws-message-handler.js.map +1 -1
  525. package/out/zero-cache/src/workers/syncer.js +4 -4
  526. package/out/zero-cache/src/workers/syncer.js.map +1 -1
  527. package/out/zero-client/src/client/active-clients-manager.js +1 -1
  528. package/out/zero-client/src/client/active-clients-manager.js.map +1 -1
  529. package/out/zero-client/src/client/bindings.js +11 -11
  530. package/out/zero-client/src/client/connection-manager.js.map +1 -1
  531. package/out/zero-client/src/client/connection.js +1 -1
  532. package/out/zero-client/src/client/connection.js.map +1 -1
  533. package/out/zero-client/src/client/context.js.map +1 -1
  534. package/out/zero-client/src/client/crud-impl.js +1 -1
  535. package/out/zero-client/src/client/crud-impl.js.map +1 -1
  536. package/out/zero-client/src/client/crud.js +1 -1
  537. package/out/zero-client/src/client/crud.js.map +1 -1
  538. package/out/zero-client/src/client/custom.js +1 -1
  539. package/out/zero-client/src/client/custom.js.map +1 -1
  540. package/out/zero-client/src/client/delete-clients-manager.js.map +1 -1
  541. package/out/zero-client/src/client/enable-analytics.js +1 -1
  542. package/out/zero-client/src/client/enable-analytics.js.map +1 -1
  543. package/out/zero-client/src/client/error.js.map +1 -1
  544. package/out/zero-client/src/client/inspector/client-group.js.map +1 -1
  545. package/out/zero-client/src/client/inspector/client.js.map +1 -1
  546. package/out/zero-client/src/client/inspector/html-dialog-prompt.js +1 -1
  547. package/out/zero-client/src/client/inspector/html-dialog-prompt.js.map +1 -1
  548. package/out/zero-client/src/client/inspector/inspector.js.map +1 -1
  549. package/out/zero-client/src/client/inspector/lazy-inspector.js.map +1 -1
  550. package/out/zero-client/src/client/inspector/query.js.map +1 -1
  551. package/out/zero-client/src/client/ivm-branch.js +1 -3
  552. package/out/zero-client/src/client/ivm-branch.js.map +1 -1
  553. package/out/zero-client/src/client/keys.js +2 -1
  554. package/out/zero-client/src/client/keys.js.map +1 -1
  555. package/out/zero-client/src/client/log-options.js.map +1 -1
  556. package/out/zero-client/src/client/make-replicache-mutators.js +5 -3
  557. package/out/zero-client/src/client/make-replicache-mutators.js.map +1 -1
  558. package/out/zero-client/src/client/metrics.js +3 -5
  559. package/out/zero-client/src/client/metrics.js.map +1 -1
  560. package/out/zero-client/src/client/mutation-tracker.js.map +1 -1
  561. package/out/zero-client/src/client/mutator-proxy.js.map +1 -1
  562. package/out/zero-client/src/client/options.js.map +1 -1
  563. package/out/zero-client/src/client/query-manager.js +2 -2
  564. package/out/zero-client/src/client/query-manager.js.map +1 -1
  565. package/out/zero-client/src/client/reload-error-handler.js +4 -3
  566. package/out/zero-client/src/client/reload-error-handler.js.map +1 -1
  567. package/out/zero-client/src/client/version.js +1 -1
  568. package/out/zero-client/src/client/zero-poke-handler.js +1 -1
  569. package/out/zero-client/src/client/zero-poke-handler.js.map +1 -1
  570. package/out/zero-client/src/client/zero-rep.js.map +1 -1
  571. package/out/zero-client/src/client/zero.js +19 -11
  572. package/out/zero-client/src/client/zero.js.map +1 -1
  573. package/out/zero-client/src/mod.js +23 -23
  574. package/out/zero-client/src/util/nanoid.js.map +1 -1
  575. package/out/zero-permissions/src/permissions.js +3 -2
  576. package/out/zero-permissions/src/permissions.js.map +1 -1
  577. package/out/zero-pg/src/mod.js +9 -9
  578. package/out/zero-protocol/src/analyze-query-result.js +1 -1
  579. package/out/zero-protocol/src/analyze-query-result.js.map +1 -1
  580. package/out/zero-protocol/src/application-error.js.map +1 -1
  581. package/out/zero-protocol/src/ast.js +19 -9
  582. package/out/zero-protocol/src/ast.js.map +1 -1
  583. package/out/zero-protocol/src/change-desired-queries.js.map +1 -1
  584. package/out/zero-protocol/src/client-schema.js +1 -1
  585. package/out/zero-protocol/src/client-schema.js.map +1 -1
  586. package/out/zero-protocol/src/close-connection.js +1 -1
  587. package/out/zero-protocol/src/close-connection.js.map +1 -1
  588. package/out/zero-protocol/src/connect.js +1 -1
  589. package/out/zero-protocol/src/connect.js.map +1 -1
  590. package/out/zero-protocol/src/custom-queries.js +1 -1
  591. package/out/zero-protocol/src/custom-queries.js.map +1 -1
  592. package/out/zero-protocol/src/data.js +4 -2
  593. package/out/zero-protocol/src/data.js.map +1 -1
  594. package/out/zero-protocol/src/delete-clients.js.map +1 -1
  595. package/out/zero-protocol/src/down.d.ts +27 -27
  596. package/out/zero-protocol/src/down.js.map +1 -1
  597. package/out/zero-protocol/src/error.js.map +1 -1
  598. package/out/zero-protocol/src/inspect-down.d.ts +81 -81
  599. package/out/zero-protocol/src/inspect-down.js +1 -1
  600. package/out/zero-protocol/src/inspect-down.js.map +1 -1
  601. package/out/zero-protocol/src/inspect-up.js +1 -1
  602. package/out/zero-protocol/src/inspect-up.js.map +1 -1
  603. package/out/zero-protocol/src/mutate-server.js +1 -1
  604. package/out/zero-protocol/src/mutate-server.js.map +1 -1
  605. package/out/zero-protocol/src/mutation-id.js.map +1 -1
  606. package/out/zero-protocol/src/mutation.js +1 -1
  607. package/out/zero-protocol/src/mutation.js.map +1 -1
  608. package/out/zero-protocol/src/mutations-patch.js +1 -1
  609. package/out/zero-protocol/src/mutations-patch.js.map +1 -1
  610. package/out/zero-protocol/src/ping.js +1 -1
  611. package/out/zero-protocol/src/ping.js.map +1 -1
  612. package/out/zero-protocol/src/poke.d.ts +6 -6
  613. package/out/zero-protocol/src/poke.js +1 -1
  614. package/out/zero-protocol/src/poke.js.map +1 -1
  615. package/out/zero-protocol/src/pong.js +1 -1
  616. package/out/zero-protocol/src/pong.js.map +1 -1
  617. package/out/zero-protocol/src/primary-key.js.map +1 -1
  618. package/out/zero-protocol/src/protocol-version.js +1 -0
  619. package/out/zero-protocol/src/protocol-version.js.map +1 -1
  620. package/out/zero-protocol/src/pull.js +1 -1
  621. package/out/zero-protocol/src/pull.js.map +1 -1
  622. package/out/zero-protocol/src/push.js +1 -1
  623. package/out/zero-protocol/src/push.js.map +1 -1
  624. package/out/zero-protocol/src/queries-patch.js +1 -1
  625. package/out/zero-protocol/src/queries-patch.js.map +1 -1
  626. package/out/zero-protocol/src/query-hash-visitor.js.map +1 -1
  627. package/out/zero-protocol/src/query-hash.js +2 -2
  628. package/out/zero-protocol/src/query-server.js +1 -1
  629. package/out/zero-protocol/src/query-server.js.map +1 -1
  630. package/out/zero-protocol/src/row-patch.js.map +1 -1
  631. package/out/zero-protocol/src/up.d.ts +60 -60
  632. package/out/zero-protocol/src/up.js.map +1 -1
  633. package/out/zero-protocol/src/update-auth.js.map +1 -1
  634. package/out/zero-protocol/src/version.js.map +1 -1
  635. package/out/zero-react/src/bindings.js +11 -11
  636. package/out/zero-react/src/mod.js +5 -5
  637. package/out/zero-react/src/use-query.js +1 -1
  638. package/out/zero-react/src/use-query.js.map +1 -1
  639. package/out/zero-react/src/zero-provider.d.ts +1 -1
  640. package/out/zero-react/src/zero-provider.d.ts.map +1 -1
  641. package/out/zero-react/src/zero-provider.js +2 -1
  642. package/out/zero-react/src/zero-provider.js.map +1 -1
  643. package/out/zero-react/src/zero.js +23 -23
  644. package/out/zero-schema/src/builder/schema-builder.js +3 -2
  645. package/out/zero-schema/src/builder/schema-builder.js.map +1 -1
  646. package/out/zero-schema/src/builder/table-builder.js +1 -1
  647. package/out/zero-schema/src/builder/table-builder.js.map +1 -1
  648. package/out/zero-schema/src/compiled-permissions.js.map +1 -1
  649. package/out/zero-schema/src/name-mapper.js +7 -5
  650. package/out/zero-schema/src/name-mapper.js.map +1 -1
  651. package/out/zero-schema/src/schema-config.js +1 -1
  652. package/out/zero-schema/src/schema-config.js.map +1 -1
  653. package/out/zero-server/src/adapters/drizzle.js.map +1 -1
  654. package/out/zero-server/src/adapters/kysely.js.map +1 -1
  655. package/out/zero-server/src/adapters/pg.js.map +1 -1
  656. package/out/zero-server/src/adapters/postgresjs.js.map +1 -1
  657. package/out/zero-server/src/adapters/prisma.js.map +1 -1
  658. package/out/zero-server/src/closable-db-transaction.js.map +1 -1
  659. package/out/zero-server/src/custom.js +1 -1
  660. package/out/zero-server/src/custom.js.map +1 -1
  661. package/out/zero-server/src/mod.js +8 -8
  662. package/out/zero-server/src/process-mutations.js.map +1 -1
  663. package/out/zero-server/src/push-processor.js.map +1 -1
  664. package/out/zero-server/src/queries/process-queries.js +2 -1
  665. package/out/zero-server/src/queries/process-queries.js.map +1 -1
  666. package/out/zero-server/src/schema.js +7 -7
  667. package/out/zero-server/src/schema.js.map +1 -1
  668. package/out/zero-server/src/zql-database.js.map +1 -1
  669. package/out/zero-solid/src/bindings.js +11 -11
  670. package/out/zero-solid/src/mod.js +5 -5
  671. package/out/zero-solid/src/solid-view.js +1 -1
  672. package/out/zero-solid/src/solid-view.js.map +1 -1
  673. package/out/zero-solid/src/use-connection-state.js +2 -1
  674. package/out/zero-solid/src/use-connection-state.js.map +1 -1
  675. package/out/zero-solid/src/use-query.js.map +1 -1
  676. package/out/zero-solid/src/use-zero-online.js +2 -1
  677. package/out/zero-solid/src/use-zero-online.js.map +1 -1
  678. package/out/zero-solid/src/use-zero.js +3 -2
  679. package/out/zero-solid/src/use-zero.js.map +1 -1
  680. package/out/zero-solid/src/zero.js +23 -23
  681. package/out/zero-types/src/name-mapper.js.map +1 -1
  682. package/out/zql/src/builder/builder.js +15 -13
  683. package/out/zql/src/builder/builder.js.map +1 -1
  684. package/out/zql/src/builder/correlated-predicate-pushdown.js.map +1 -1
  685. package/out/zql/src/builder/debug-delegate.js.map +1 -1
  686. package/out/zql/src/builder/like.js +0 -1
  687. package/out/zql/src/builder/like.js.map +1 -1
  688. package/out/zql/src/ivm/array-view.js.map +1 -1
  689. package/out/zql/src/ivm/cap.d.ts +1 -1
  690. package/out/zql/src/ivm/cap.d.ts.map +1 -1
  691. package/out/zql/src/ivm/cap.js +10 -0
  692. package/out/zql/src/ivm/cap.js.map +1 -1
  693. package/out/zql/src/ivm/constraint.js +1 -1
  694. package/out/zql/src/ivm/constraint.js.map +1 -1
  695. package/out/zql/src/ivm/data.d.ts +15 -1
  696. package/out/zql/src/ivm/data.d.ts.map +1 -1
  697. package/out/zql/src/ivm/data.js +15 -1
  698. package/out/zql/src/ivm/data.js.map +1 -1
  699. package/out/zql/src/ivm/deferred-input.js.map +1 -1
  700. package/out/zql/src/ivm/exists.d.ts.map +1 -1
  701. package/out/zql/src/ivm/exists.js +32 -22
  702. package/out/zql/src/ivm/exists.js.map +1 -1
  703. package/out/zql/src/ivm/fan-in.js.map +1 -1
  704. package/out/zql/src/ivm/fan-out.js.map +1 -1
  705. package/out/zql/src/ivm/filter-operators.d.ts +5 -0
  706. package/out/zql/src/ivm/filter-operators.d.ts.map +1 -1
  707. package/out/zql/src/ivm/filter-operators.js +1 -1
  708. package/out/zql/src/ivm/filter-operators.js.map +1 -1
  709. package/out/zql/src/ivm/filter-push.js.map +1 -1
  710. package/out/zql/src/ivm/filter.js.map +1 -1
  711. package/out/zql/src/ivm/flipped-join.js +1 -3
  712. package/out/zql/src/ivm/flipped-join.js.map +1 -1
  713. package/out/zql/src/ivm/join-index-tap.js.map +1 -1
  714. package/out/zql/src/ivm/join-index.js.map +1 -1
  715. package/out/zql/src/ivm/join-utils.js +11 -13
  716. package/out/zql/src/ivm/join-utils.js.map +1 -1
  717. package/out/zql/src/ivm/join.d.ts.map +1 -1
  718. package/out/zql/src/ivm/join.js +6 -3
  719. package/out/zql/src/ivm/join.js.map +1 -1
  720. package/out/zql/src/ivm/maybe-split-and-push-edit-change.js.map +1 -1
  721. package/out/zql/src/ivm/memory-source.js +27 -23
  722. package/out/zql/src/ivm/memory-source.js.map +1 -1
  723. package/out/zql/src/ivm/memory-storage.js.map +1 -1
  724. package/out/zql/src/ivm/operator.d.ts +6 -0
  725. package/out/zql/src/ivm/operator.d.ts.map +1 -1
  726. package/out/zql/src/ivm/operator.js +2 -2
  727. package/out/zql/src/ivm/operator.js.map +1 -1
  728. package/out/zql/src/ivm/push-accumulated.js +0 -1
  729. package/out/zql/src/ivm/push-accumulated.js.map +1 -1
  730. package/out/zql/src/ivm/skip-yields.js.map +1 -1
  731. package/out/zql/src/ivm/skip.js.map +1 -1
  732. package/out/zql/src/ivm/take-gate.js.map +1 -1
  733. package/out/zql/src/ivm/take.d.ts.map +1 -1
  734. package/out/zql/src/ivm/take.js +5 -4
  735. package/out/zql/src/ivm/take.js.map +1 -1
  736. package/out/zql/src/ivm/union-fan-in.js +1 -1
  737. package/out/zql/src/ivm/union-fan-in.js.map +1 -1
  738. package/out/zql/src/ivm/union-fan-out.js.map +1 -1
  739. package/out/zql/src/ivm/view-apply-change.js +1 -1
  740. package/out/zql/src/ivm/view-apply-change.js.map +1 -1
  741. package/out/zql/src/mutate/crud.js +3 -2
  742. package/out/zql/src/mutate/crud.js.map +1 -1
  743. package/out/zql/src/planner/planner-builder.js +1 -1
  744. package/out/zql/src/planner/planner-builder.js.map +1 -1
  745. package/out/zql/src/planner/planner-connection.js.map +1 -1
  746. package/out/zql/src/planner/planner-debug.js.map +1 -1
  747. package/out/zql/src/planner/planner-fan-in.js.map +1 -1
  748. package/out/zql/src/planner/planner-fan-out.js.map +1 -1
  749. package/out/zql/src/planner/planner-filter.js.map +1 -1
  750. package/out/zql/src/planner/planner-graph.js +1 -5
  751. package/out/zql/src/planner/planner-graph.js.map +1 -1
  752. package/out/zql/src/planner/planner-join.js +1 -1
  753. package/out/zql/src/planner/planner-join.js.map +1 -1
  754. package/out/zql/src/planner/planner-source.js.map +1 -1
  755. package/out/zql/src/planner/planner-terminus.js.map +1 -1
  756. package/out/zql/src/query/create-builder.js +2 -1
  757. package/out/zql/src/query/create-builder.js.map +1 -1
  758. package/out/zql/src/query/expression.js +1 -1
  759. package/out/zql/src/query/expression.js.map +1 -1
  760. package/out/zql/src/query/measure-push-operator.js.map +1 -1
  761. package/out/zql/src/query/named.js +2 -1
  762. package/out/zql/src/query/named.js.map +1 -1
  763. package/out/zql/src/query/query-delegate-base.js +1 -1
  764. package/out/zql/src/query/query-delegate-base.js.map +1 -1
  765. package/out/zql/src/query/query-impl.js +3 -2
  766. package/out/zql/src/query/query-impl.js.map +1 -1
  767. package/out/zql/src/query/query-registry.js +1 -1
  768. package/out/zql/src/query/query-registry.js.map +1 -1
  769. package/out/zql/src/query/query-transitions.js +1 -1
  770. package/out/zql/src/query/query-transitions.js.map +1 -1
  771. package/out/zql/src/query/runnable-query-impl.js +3 -2
  772. package/out/zql/src/query/runnable-query-impl.js.map +1 -1
  773. package/out/zql/src/query/static-query.js.map +1 -1
  774. package/out/zql/src/query/ttl.js +8 -8
  775. package/out/zql/src/query/ttl.js.map +1 -1
  776. package/out/zql/src/query/validate-input.js.map +1 -1
  777. package/out/zqlite/src/database-storage.d.ts +27 -8
  778. package/out/zqlite/src/database-storage.d.ts.map +1 -1
  779. package/out/zqlite/src/database-storage.js +190 -53
  780. package/out/zqlite/src/database-storage.js.map +1 -1
  781. package/out/zqlite/src/db.d.ts +47 -1
  782. package/out/zqlite/src/db.d.ts.map +1 -1
  783. package/out/zqlite/src/db.js +121 -21
  784. package/out/zqlite/src/db.js.map +1 -1
  785. package/out/zqlite/src/explain-queries.js.map +1 -1
  786. package/out/zqlite/src/fetch-sql.js.map +1 -1
  787. package/out/zqlite/src/index-usage.js.map +1 -1
  788. package/out/zqlite/src/internal/sql-inline.js.map +1 -1
  789. package/out/zqlite/src/internal/sql.js.map +1 -1
  790. package/out/zqlite/src/internal/statement-cache.d.ts +7 -0
  791. package/out/zqlite/src/internal/statement-cache.d.ts.map +1 -1
  792. package/out/zqlite/src/internal/statement-cache.js +11 -4
  793. package/out/zqlite/src/internal/statement-cache.js.map +1 -1
  794. package/out/zqlite/src/mod.js +5 -5
  795. package/out/zqlite/src/pending-delta.js.map +1 -1
  796. package/out/zqlite/src/query-builder.js +1 -1
  797. package/out/zqlite/src/query-builder.js.map +1 -1
  798. package/out/zqlite/src/query-delegate.js.map +1 -1
  799. package/out/zqlite/src/resolve-scalar-subqueries.js +2 -5
  800. package/out/zqlite/src/resolve-scalar-subqueries.js.map +1 -1
  801. package/out/zqlite/src/sqlite-cost-model.js +3 -2
  802. package/out/zqlite/src/sqlite-cost-model.js.map +1 -1
  803. package/out/zqlite/src/sqlite-stat-fanout.js.map +1 -1
  804. package/out/zqlite/src/table-source.d.ts +11 -0
  805. package/out/zqlite/src/table-source.d.ts.map +1 -1
  806. package/out/zqlite/src/table-source.js +63 -26
  807. package/out/zqlite/src/table-source.js.map +1 -1
  808. package/package.json +37 -36
  809. package/out/analyze-query/src/bin-analyze.d.ts +0 -2
  810. package/out/analyze-query/src/bin-analyze.d.ts.map +0 -1
  811. package/out/analyze-query/src/bin-analyze.js +0 -283
  812. package/out/analyze-query/src/bin-analyze.js.map +0 -1
  813. package/out/otel/src/maybe-time.d.ts +0 -3
  814. package/out/otel/src/maybe-time.d.ts.map +0 -1
  815. package/out/otel/src/maybe-time.js +0 -15
  816. package/out/otel/src/maybe-time.js.map +0 -1
  817. package/out/zero/src/analyze-query.d.ts +0 -3
  818. package/out/zero/src/analyze-query.d.ts.map +0 -1
  819. package/out/zero/src/analyze-query.js +0 -3
@@ -1 +1 @@
1
- {"version":3,"file":"join-index.js","names":["#parentKey","#primaryKey","#joinKeyIsPK","#partitionKey","#unpartitioned","#partitioned","#size","#pkOf"],"sources":["../../../../../zql/src/ivm/join-index.ts"],"sourcesContent":["import {must} from '../../../shared/src/must.ts';\nimport type {CompoundKey} from '../../../zero-protocol/src/ast.ts';\nimport type {Row, Value} from '../../../zero-protocol/src/data.ts';\nimport {canonicalKey} from './join-utils.ts';\n\n/**\n * The partitions of the indexed parents that share a join key, as fetch\n * constraints. An unpartitioned index reports a single `undefined`.\n */\nexport type ParentPartitions = readonly (Record<string, Value> | undefined)[];\n\nconst UNPARTITIONED: ParentPartitions = [undefined];\n\ntype Partition = {\n readonly constraint: Record<string, Value>;\n readonly pks: Set<string>;\n};\n\n/**\n * An in-memory index from a join key to the parent rows that have it. Join\n * and FlippedJoin look up a child change's join key here to skip the parent\n * fetch when no indexed parent can see the change.\n *\n * Parents are tracked by primary key so that adding or removing a row twice\n * is harmless. Lookups only report whether any parent has the key and, when\n * the index is partitioned, in which partitions.\n */\nexport class JoinIndex {\n readonly #parentKey: CompoundKey;\n readonly #primaryKey: CompoundKey;\n /** The join key is the primary key, so one string serves as both. */\n readonly #joinKeyIsPK: boolean;\n readonly #partitionKey: CompoundKey | undefined;\n readonly #unpartitioned = new Map<string, Set<string>>();\n readonly #partitioned = new Map<string, Map<string, Partition>>();\n #size = 0;\n\n constructor(\n parentKey: CompoundKey,\n primaryKey: CompoundKey,\n partitionKey?: CompoundKey | undefined,\n ) {\n this.#parentKey = parentKey;\n this.#primaryKey = primaryKey;\n this.#joinKeyIsPK =\n parentKey.length === primaryKey.length &&\n parentKey.every((k, i) => k === primaryKey[i]);\n this.#partitionKey = partitionKey;\n }\n\n /** The number of parent rows in the index. */\n get size(): number {\n return this.#size;\n }\n\n add(row: Row): void {\n const joinKey = joinKeyOf(row, this.#parentKey);\n if (joinKey === undefined) {\n return;\n }\n const pk = this.#pkOf(row, joinKey);\n const partitionKey = this.#partitionKey;\n if (partitionKey === undefined) {\n let pks = this.#unpartitioned.get(joinKey);\n if (pks === undefined) {\n pks = new Set();\n this.#unpartitioned.set(joinKey, pks);\n }\n if (!pks.has(pk)) {\n pks.add(pk);\n this.#size++;\n }\n return;\n }\n\n const partKey = canonicalKey(row, partitionKey);\n let partitions = this.#partitioned.get(joinKey);\n if (partitions === undefined) {\n partitions = new Map();\n this.#partitioned.set(joinKey, partitions);\n }\n let partition = partitions.get(partKey);\n if (partition === undefined) {\n const constraint: Record<string, Value> = {};\n for (const key of partitionKey) {\n constraint[key] = row[key];\n }\n partition = {constraint, pks: new Set()};\n partitions.set(partKey, partition);\n }\n if (!partition.pks.has(pk)) {\n partition.pks.add(pk);\n this.#size++;\n }\n }\n\n remove(row: Row): void {\n const joinKey = joinKeyOf(row, this.#parentKey);\n if (joinKey === undefined) {\n return;\n }\n const pk = this.#pkOf(row, joinKey);\n const partitionKey = this.#partitionKey;\n if (partitionKey === undefined) {\n const pks = this.#unpartitioned.get(joinKey);\n if (pks === undefined) {\n return;\n }\n if (pks.delete(pk)) {\n this.#size--;\n if (pks.size === 0) {\n this.#unpartitioned.delete(joinKey);\n }\n }\n return;\n }\n\n const partitions = this.#partitioned.get(joinKey);\n if (partitions === undefined) {\n return;\n }\n const partKey = canonicalKey(row, partitionKey);\n const partition = partitions.get(partKey);\n if (partition === undefined) {\n return;\n }\n if (partition.pks.delete(pk)) {\n this.#size--;\n if (partition.pks.size === 0) {\n partitions.delete(partKey);\n if (partitions.size === 0) {\n this.#partitioned.delete(joinKey);\n }\n }\n }\n }\n\n /**\n * The partitions of the indexed parents whose join key matches `childRow`\n * over `childKey`, or `undefined` if there are none.\n */\n lookup(childRow: Row, childKey: CompoundKey): ParentPartitions | undefined {\n const joinKey = joinKeyOf(childRow, childKey);\n if (joinKey === undefined) {\n return undefined;\n }\n if (this.#partitionKey === undefined) {\n return this.#unpartitioned.has(joinKey) ? UNPARTITIONED : undefined;\n }\n const partitions = this.#partitioned.get(joinKey);\n if (partitions === undefined) {\n return undefined;\n }\n return Array.from(partitions.values(), p => p.constraint);\n }\n\n /**\n * The index as the operator storage entries it replaced, keyed\n * `j\\0<joinKey>\\0[<partitionKey>\\0]<primaryKey>`. For tests.\n */\n entriesForTest(): Record<string, 1> {\n const entries: Record<string, 1> = {};\n for (const [joinKey, pks] of this.#unpartitioned) {\n for (const pk of pks) {\n entries[`j\\x00${joinKey}\\x00${pk}`] = 1;\n }\n }\n for (const [joinKey, partitions] of this.#partitioned) {\n const partitionKey = must(this.#partitionKey);\n for (const {constraint, pks} of partitions.values()) {\n const partKey = canonicalKey(constraint, partitionKey);\n for (const pk of pks) {\n entries[`j\\x00${joinKey}\\x00${partKey}\\x00${pk}`] = 1;\n }\n }\n }\n return entries;\n }\n\n #pkOf(row: Row, joinKey: string): string {\n return this.#joinKeyIsPK ? joinKey : canonicalKey(row, this.#primaryKey);\n }\n}\n\n/**\n * The canonical join key of `row`, or `undefined` if any part of it is null:\n * a null key cannot match anything.\n */\nfunction joinKeyOf(row: Row, key: CompoundKey): string | undefined {\n for (const k of key) {\n if (row[k] === null) {\n return undefined;\n }\n }\n return canonicalKey(row, key);\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"join-index.js","names":[],"sources":["../../../../../zql/src/ivm/join-index.ts"],"sourcesContent":["import {must} from '../../../shared/src/must.ts';\nimport type {CompoundKey} from '../../../zero-protocol/src/ast.ts';\nimport type {Row, Value} from '../../../zero-protocol/src/data.ts';\nimport {canonicalKey} from './join-utils.ts';\n\n/**\n * The partitions of the indexed parents that share a join key, as fetch\n * constraints. An unpartitioned index reports a single `undefined`.\n */\nexport type ParentPartitions = readonly (Record<string, Value> | undefined)[];\n\nconst UNPARTITIONED: ParentPartitions = [undefined];\n\ntype Partition = {\n readonly constraint: Record<string, Value>;\n readonly pks: Set<string>;\n};\n\n/**\n * An in-memory index from a join key to the parent rows that have it. Join\n * and FlippedJoin look up a child change's join key here to skip the parent\n * fetch when no indexed parent can see the change.\n *\n * Parents are tracked by primary key so that adding or removing a row twice\n * is harmless. Lookups only report whether any parent has the key and, when\n * the index is partitioned, in which partitions.\n */\nexport class JoinIndex {\n readonly #parentKey: CompoundKey;\n readonly #primaryKey: CompoundKey;\n /** The join key is the primary key, so one string serves as both. */\n readonly #joinKeyIsPK: boolean;\n readonly #partitionKey: CompoundKey | undefined;\n readonly #unpartitioned = new Map<string, Set<string>>();\n readonly #partitioned = new Map<string, Map<string, Partition>>();\n #size = 0;\n\n constructor(\n parentKey: CompoundKey,\n primaryKey: CompoundKey,\n partitionKey?: CompoundKey | undefined,\n ) {\n this.#parentKey = parentKey;\n this.#primaryKey = primaryKey;\n this.#joinKeyIsPK =\n parentKey.length === primaryKey.length &&\n parentKey.every((k, i) => k === primaryKey[i]);\n this.#partitionKey = partitionKey;\n }\n\n /** The number of parent rows in the index. */\n get size(): number {\n return this.#size;\n }\n\n add(row: Row): void {\n const joinKey = joinKeyOf(row, this.#parentKey);\n if (joinKey === undefined) {\n return;\n }\n const pk = this.#pkOf(row, joinKey);\n const partitionKey = this.#partitionKey;\n if (partitionKey === undefined) {\n let pks = this.#unpartitioned.get(joinKey);\n if (pks === undefined) {\n pks = new Set();\n this.#unpartitioned.set(joinKey, pks);\n }\n if (!pks.has(pk)) {\n pks.add(pk);\n this.#size++;\n }\n return;\n }\n\n const partKey = canonicalKey(row, partitionKey);\n let partitions = this.#partitioned.get(joinKey);\n if (partitions === undefined) {\n partitions = new Map();\n this.#partitioned.set(joinKey, partitions);\n }\n let partition = partitions.get(partKey);\n if (partition === undefined) {\n const constraint: Record<string, Value> = {};\n for (const key of partitionKey) {\n constraint[key] = row[key];\n }\n partition = {constraint, pks: new Set()};\n partitions.set(partKey, partition);\n }\n if (!partition.pks.has(pk)) {\n partition.pks.add(pk);\n this.#size++;\n }\n }\n\n remove(row: Row): void {\n const joinKey = joinKeyOf(row, this.#parentKey);\n if (joinKey === undefined) {\n return;\n }\n const pk = this.#pkOf(row, joinKey);\n const partitionKey = this.#partitionKey;\n if (partitionKey === undefined) {\n const pks = this.#unpartitioned.get(joinKey);\n if (pks === undefined) {\n return;\n }\n if (pks.delete(pk)) {\n this.#size--;\n if (pks.size === 0) {\n this.#unpartitioned.delete(joinKey);\n }\n }\n return;\n }\n\n const partitions = this.#partitioned.get(joinKey);\n if (partitions === undefined) {\n return;\n }\n const partKey = canonicalKey(row, partitionKey);\n const partition = partitions.get(partKey);\n if (partition === undefined) {\n return;\n }\n if (partition.pks.delete(pk)) {\n this.#size--;\n if (partition.pks.size === 0) {\n partitions.delete(partKey);\n if (partitions.size === 0) {\n this.#partitioned.delete(joinKey);\n }\n }\n }\n }\n\n /**\n * The partitions of the indexed parents whose join key matches `childRow`\n * over `childKey`, or `undefined` if there are none.\n */\n lookup(childRow: Row, childKey: CompoundKey): ParentPartitions | undefined {\n const joinKey = joinKeyOf(childRow, childKey);\n if (joinKey === undefined) {\n return undefined;\n }\n if (this.#partitionKey === undefined) {\n return this.#unpartitioned.has(joinKey) ? UNPARTITIONED : undefined;\n }\n const partitions = this.#partitioned.get(joinKey);\n if (partitions === undefined) {\n return undefined;\n }\n return Array.from(partitions.values(), p => p.constraint);\n }\n\n /**\n * The index as the operator storage entries it replaced, keyed\n * `j\\0<joinKey>\\0[<partitionKey>\\0]<primaryKey>`. For tests.\n */\n entriesForTest(): Record<string, 1> {\n const entries: Record<string, 1> = {};\n for (const [joinKey, pks] of this.#unpartitioned) {\n for (const pk of pks) {\n entries[`j\\x00${joinKey}\\x00${pk}`] = 1;\n }\n }\n for (const [joinKey, partitions] of this.#partitioned) {\n const partitionKey = must(this.#partitionKey);\n for (const {constraint, pks} of partitions.values()) {\n const partKey = canonicalKey(constraint, partitionKey);\n for (const pk of pks) {\n entries[`j\\x00${joinKey}\\x00${partKey}\\x00${pk}`] = 1;\n }\n }\n }\n return entries;\n }\n\n #pkOf(row: Row, joinKey: string): string {\n return this.#joinKeyIsPK ? joinKey : canonicalKey(row, this.#primaryKey);\n }\n}\n\n/**\n * The canonical join key of `row`, or `undefined` if any part of it is null:\n * a null key cannot match anything.\n */\nfunction joinKeyOf(row: Row, key: CompoundKey): string | undefined {\n for (const k of key) {\n if (row[k] === null) {\n return undefined;\n }\n }\n return canonicalKey(row, key);\n}\n"],"mappings":"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"}
@@ -39,19 +39,17 @@ function* generateWithOverlay(stream, overlay, schema) {
39
39
  yieldNode = false;
40
40
  }
41
41
  break;
42
- case 3:
43
- if (schema.compareRows(overlay[1].row, node.row) === 0) {
44
- applied = true;
45
- yield {
46
- row: node.row,
47
- relationships: {
48
- ...node.relationships,
49
- [overlay[2].relationshipName]: () => generateWithOverlay(node.relationships[overlay[2].relationshipName](), overlay[2].change, schema.relationships[overlay[2].relationshipName])
50
- }
51
- };
52
- yieldNode = false;
53
- }
54
- break;
42
+ case 3: if (schema.compareRows(overlay[1].row, node.row) === 0) {
43
+ applied = true;
44
+ yield {
45
+ row: node.row,
46
+ relationships: {
47
+ ...node.relationships,
48
+ [overlay[2].relationshipName]: () => generateWithOverlay(node.relationships[overlay[2].relationshipName](), overlay[2].change, schema.relationships[overlay[2].relationshipName])
49
+ }
50
+ };
51
+ yieldNode = false;
52
+ }
55
53
  }
56
54
  if (yieldNode) yield node;
57
55
  }
@@ -1 +1 @@
1
- {"version":3,"file":"join-utils.js","names":[],"sources":["../../../../../zql/src/ivm/join-utils.ts"],"sourcesContent":["import {assert} from '../../../shared/src/asserts.ts';\nimport type {CompoundKey} from '../../../zero-protocol/src/ast.ts';\nimport type {Row, Value} 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 {compareValues, valuesEqual, type Node} from './data.ts';\nimport type {SourceSchema} from './schema.ts';\nimport type {Stream} from './stream.ts';\n\nexport function generateWithOverlayNoYield(\n stream: Stream<Node>,\n overlay: Change,\n schema: SourceSchema,\n): Stream<Node> {\n return generateWithOverlay(stream, overlay, schema) as Stream<Node>;\n}\n\nexport function* generateWithOverlay(\n stream: Stream<Node | 'yield'>,\n overlay: Change,\n schema: SourceSchema,\n): Stream<Node | 'yield'> {\n let applied = false;\n let editOldApplied = false;\n let editNewApplied = false;\n for (const node of stream) {\n if (node === 'yield') {\n yield node;\n continue;\n }\n let yieldNode = true;\n if (!applied) {\n switch (overlay[ChangeIndex.TYPE]) {\n case ChangeType.ADD: {\n if (\n schema.compareRows(overlay[ChangeIndex.NODE].row, node.row) === 0\n ) {\n applied = true;\n yieldNode = false;\n }\n break;\n }\n case ChangeType.REMOVE: {\n if (schema.compareRows(overlay[ChangeIndex.NODE].row, node.row) < 0) {\n applied = true;\n yield overlay[ChangeIndex.NODE];\n }\n break;\n }\n case ChangeType.EDIT: {\n if (\n !editOldApplied &&\n schema.compareRows(overlay[ChangeIndex.OLD_NODE].row, node.row) < 0\n ) {\n editOldApplied = true;\n if (editNewApplied) {\n applied = true;\n }\n yield overlay[ChangeIndex.OLD_NODE];\n }\n if (\n !editNewApplied &&\n schema.compareRows(overlay[ChangeIndex.NODE].row, node.row) === 0\n ) {\n editNewApplied = true;\n if (editOldApplied) {\n applied = true;\n }\n yieldNode = false;\n }\n break;\n }\n case ChangeType.CHILD: {\n if (\n schema.compareRows(overlay[ChangeIndex.NODE].row, node.row) === 0\n ) {\n applied = true;\n yield {\n row: node.row,\n relationships: {\n ...node.relationships,\n [overlay[ChangeIndex.CHILD_DATA].relationshipName]: () =>\n generateWithOverlay(\n node.relationships[\n overlay[ChangeIndex.CHILD_DATA].relationshipName\n ](),\n overlay[ChangeIndex.CHILD_DATA].change,\n schema.relationships[\n overlay[ChangeIndex.CHILD_DATA].relationshipName\n ],\n ),\n },\n };\n yieldNode = false;\n }\n break;\n }\n }\n }\n if (yieldNode) {\n yield node;\n }\n }\n if (!applied) {\n if (overlay[ChangeIndex.TYPE] === ChangeType.REMOVE) {\n applied = true;\n yield overlay[ChangeIndex.NODE];\n } else if (overlay[ChangeIndex.TYPE] === ChangeType.EDIT) {\n assert(\n editNewApplied,\n 'edit overlay: new node must be applied before old node',\n );\n editOldApplied = true;\n applied = true;\n yield overlay[ChangeIndex.OLD_NODE];\n }\n }\n\n assert(\n applied,\n 'overlayGenerator: overlay was never applied to any fetched node',\n );\n}\n\nexport function generateWithOverlayNoYieldUnordered(\n stream: Stream<Node>,\n overlay: Change,\n schema: SourceSchema,\n): Stream<Node> {\n return generateWithOverlayUnordered(stream, overlay, schema) as Stream<Node>;\n}\n\nexport function* generateWithOverlayUnordered(\n stream: Stream<Node | 'yield'>,\n overlay: Change,\n schema: SourceSchema,\n): Stream<Node | 'yield'> {\n // Eager inject\n if (overlay[ChangeIndex.TYPE] === ChangeType.REMOVE) {\n yield overlay[ChangeIndex.NODE];\n } else if (overlay[ChangeIndex.TYPE] === ChangeType.EDIT) {\n yield overlay[ChangeIndex.OLD_NODE];\n }\n\n // Stream with inline suppress\n let suppressed = false;\n for (const node of stream) {\n if (node === 'yield') {\n yield node;\n continue;\n }\n if (!suppressed) {\n if (\n overlay[ChangeIndex.TYPE] === ChangeType.ADD ||\n overlay[ChangeIndex.TYPE] === ChangeType.EDIT\n ) {\n if (\n rowEqualsForCompoundKey(\n overlay[ChangeIndex.NODE].row,\n node.row,\n schema.primaryKey,\n )\n ) {\n suppressed = true;\n continue;\n }\n }\n if (overlay[ChangeIndex.TYPE] === ChangeType.CHILD) {\n if (\n rowEqualsForCompoundKey(\n overlay[ChangeIndex.NODE].row,\n node.row,\n schema.primaryKey,\n )\n ) {\n suppressed = true;\n yield {\n row: node.row,\n relationships: {\n ...node.relationships,\n [overlay[ChangeIndex.CHILD_DATA].relationshipName]: () =>\n generateWithOverlay(\n node.relationships[\n overlay[ChangeIndex.CHILD_DATA].relationshipName\n ](),\n overlay[ChangeIndex.CHILD_DATA].change,\n schema.relationships[\n overlay[ChangeIndex.CHILD_DATA].relationshipName\n ],\n ),\n },\n };\n continue;\n }\n }\n }\n yield node;\n }\n assert(\n suppressed || overlay[ChangeIndex.TYPE] === ChangeType.REMOVE,\n 'overlayGenerator: overlay was never applied to any fetched node',\n );\n}\n\nexport function rowEqualsForCompoundKey(\n a: Row,\n b: Row,\n key: CompoundKey,\n): boolean {\n for (let i = 0; i < key.length; i++) {\n if (compareValues(a[key[i]], b[key[i]]) !== 0) {\n return false;\n }\n }\n return true;\n}\n\nexport function isJoinMatch(\n parent: Row,\n parentKey: CompoundKey,\n child: Row,\n childKey: CompoundKey,\n) {\n for (let i = 0; i < parentKey.length; i++) {\n if (!valuesEqual(parent[parentKey[i]], child[childKey[i]])) {\n return false;\n }\n }\n return true;\n}\n\n/**\n * Builds a constraint object by mapping values from `sourceRow` using `sourceKey`\n * to keys specified by `targetKey`. Returns `undefined` if any source value is `null`,\n * since null foreign keys cannot match any rows.\n */\nexport function buildJoinConstraint(\n sourceRow: Row,\n sourceKey: CompoundKey,\n targetKey: CompoundKey,\n): Record<string, Value> | undefined {\n const constraint: Record<string, Value> = {};\n for (let i = 0; i < targetKey.length; i++) {\n const value = sourceRow[sourceKey[i]];\n if (value === null) {\n return undefined;\n }\n constraint[targetKey[i]] = value;\n }\n return constraint;\n}\n\nexport function canonicalKeyForTest(\n record: Record<string, Value | undefined>,\n keys: CompoundKey,\n): string {\n return canonicalKey(record, keys);\n}\n\n/**\n * Canonical string key over `keys` of `record`. Tags values by type\n * so distinct types (e.g. 1 and \"1\") do not collide.\n */\nexport function canonicalKey(\n record: Record<string, Value | undefined>,\n keys: CompoundKey,\n): string {\n if (keys.length === 1) {\n return canonicalValue(record[keys[0]]);\n }\n let s = '';\n for (let i = 0; i < keys.length; i++) {\n if (i > 0) s += '\\x00';\n s += canonicalValue(record[keys[i]]);\n }\n return s;\n}\n\nfunction canonicalValue(v: Value): string {\n // Tag by type so we don't conflate e.g. `1` (number) with `\"1\"` (string).\n if (v === null || v === undefined) return 'n';\n const t = typeof v;\n if (t === 'string') return 's' + (v as string);\n if (t === 'number') return 'd' + (v as number);\n if (t === 'boolean') return v ? 't' : 'f';\n return 'j' + JSON.stringify(v);\n}\n"],"mappings":";;;AAUA,SAAgB,2BACd,QACA,SACA,QACc;CACd,OAAO,oBAAoB,QAAQ,SAAS,MAAM;AACpD;AAEA,UAAiB,oBACf,QACA,SACA,QACwB;CACxB,IAAI,UAAU;CACd,IAAI,iBAAiB;CACrB,IAAI,iBAAiB;CACrB,KAAK,MAAM,QAAQ,QAAQ;EACzB,IAAI,SAAS,SAAS;GACpB,MAAM;GACN;EACF;EACA,IAAI,YAAY;EAChB,IAAI,CAAC,SACH,QAAQ,QAAQ,IAAhB;GACE,KAAK;IACH,IACE,OAAO,YAAY,QAAQ,GAAkB,KAAK,KAAK,GAAG,MAAM,GAChE;KACA,UAAU;KACV,YAAY;IACd;IACA;GAEF,KAAK;IACH,IAAI,OAAO,YAAY,QAAQ,GAAkB,KAAK,KAAK,GAAG,IAAI,GAAG;KACnE,UAAU;KACV,MAAM,QAAQ;IAChB;IACA;GAEF,KAAK;IACH,IACE,CAAC,kBACD,OAAO,YAAY,QAAQ,GAAsB,KAAK,KAAK,GAAG,IAAI,GAClE;KACA,iBAAiB;KACjB,IAAI,gBACF,UAAU;KAEZ,MAAM,QAAQ;IAChB;IACA,IACE,CAAC,kBACD,OAAO,YAAY,QAAQ,GAAkB,KAAK,KAAK,GAAG,MAAM,GAChE;KACA,iBAAiB;KACjB,IAAI,gBACF,UAAU;KAEZ,YAAY;IACd;IACA;GAEF,KAAK;IACH,IACE,OAAO,YAAY,QAAQ,GAAkB,KAAK,KAAK,GAAG,MAAM,GAChE;KACA,UAAU;KACV,MAAM;MACJ,KAAK,KAAK;MACV,eAAe;OACb,GAAG,KAAK;QACP,QAAQ,GAAwB,yBAC/B,oBACE,KAAK,cACH,QAAQ,GAAwB,kBAChC,GACF,QAAQ,GAAwB,QAChC,OAAO,cACL,QAAQ,GAAwB,iBAEpC;MACJ;KACF;KACA,YAAY;IACd;IACA;EAEJ;EAEF,IAAI,WACF,MAAM;CAEV;CACA,IAAI,CAAC;MACC,QAAQ,OAAsB,GAAmB;GACnD,UAAU;GACV,MAAM,QAAQ;EAChB,OAAO,IAAI,QAAQ,OAAsB,GAAiB;GACxD,OACE,gBACA,wDACF;GACA,iBAAiB;GACjB,UAAU;GACV,MAAM,QAAQ;EAChB;;CAGF,OACE,SACA,iEACF;AACF;AAUA,UAAiB,6BACf,QACA,SACA,QACwB;CAExB,IAAI,QAAQ,OAAsB,GAChC,MAAM,QAAQ;MACT,IAAI,QAAQ,OAAsB,GACvC,MAAM,QAAQ;CAIhB,IAAI,aAAa;CACjB,KAAK,MAAM,QAAQ,QAAQ;EACzB,IAAI,SAAS,SAAS;GACpB,MAAM;GACN;EACF;EACA,IAAI,CAAC,YAAY;GACf,IACE,QAAQ,OAAsB,KAC9B,QAAQ,OAAsB;QAG5B,wBACE,QAAQ,GAAkB,KAC1B,KAAK,KACL,OAAO,UACT,GACA;KACA,aAAa;KACb;IACF;;GAEF,IAAI,QAAQ,OAAsB;QAE9B,wBACE,QAAQ,GAAkB,KAC1B,KAAK,KACL,OAAO,UACT,GACA;KACA,aAAa;KACb,MAAM;MACJ,KAAK,KAAK;MACV,eAAe;OACb,GAAG,KAAK;QACP,QAAQ,GAAwB,yBAC/B,oBACE,KAAK,cACH,QAAQ,GAAwB,kBAChC,GACF,QAAQ,GAAwB,QAChC,OAAO,cACL,QAAQ,GAAwB,iBAEpC;MACJ;KACF;KACA;IACF;;EAEJ;EACA,MAAM;CACR;CACA,OACE,cAAc,QAAQ,OAAsB,GAC5C,iEACF;AACF;AAEA,SAAgB,wBACd,GACA,GACA,KACS;CACT,KAAK,IAAI,IAAI,GAAG,IAAI,IAAI,QAAQ,KAC9B,IAAI,cAAc,EAAE,IAAI,KAAK,EAAE,IAAI,GAAG,MAAM,GAC1C,OAAO;CAGX,OAAO;AACT;AAEA,SAAgB,YACd,QACA,WACA,OACA,UACA;CACA,KAAK,IAAI,IAAI,GAAG,IAAI,UAAU,QAAQ,KACpC,IAAI,CAAC,YAAY,OAAO,UAAU,KAAK,MAAM,SAAS,GAAG,GACvD,OAAO;CAGX,OAAO;AACT;;;;;;AAOA,SAAgB,oBACd,WACA,WACA,WACmC;CACnC,MAAM,aAAoC,CAAC;CAC3C,KAAK,IAAI,IAAI,GAAG,IAAI,UAAU,QAAQ,KAAK;EACzC,MAAM,QAAQ,UAAU,UAAU;EAClC,IAAI,UAAU,MACZ;EAEF,WAAW,UAAU,MAAM;CAC7B;CACA,OAAO;AACT;;;;;AAaA,SAAgB,aACd,QACA,MACQ;CACR,IAAI,KAAK,WAAW,GAClB,OAAO,eAAe,OAAO,KAAK,GAAG;CAEvC,IAAI,IAAI;CACR,KAAK,IAAI,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK;EACpC,IAAI,IAAI,GAAG,KAAK;EAChB,KAAK,eAAe,OAAO,KAAK,GAAG;CACrC;CACA,OAAO;AACT;AAEA,SAAS,eAAe,GAAkB;CAExC,IAAI,MAAM,QAAQ,MAAM,KAAA,GAAW,OAAO;CAC1C,MAAM,IAAI,OAAO;CACjB,IAAI,MAAM,UAAU,OAAO,MAAO;CAClC,IAAI,MAAM,UAAU,OAAO,MAAO;CAClC,IAAI,MAAM,WAAW,OAAO,IAAI,MAAM;CACtC,OAAO,MAAM,KAAK,UAAU,CAAC;AAC/B"}
1
+ {"version":3,"file":"join-utils.js","names":[],"sources":["../../../../../zql/src/ivm/join-utils.ts"],"sourcesContent":["import {assert} from '../../../shared/src/asserts.ts';\nimport type {CompoundKey} from '../../../zero-protocol/src/ast.ts';\nimport type {Row, Value} 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 {compareValues, valuesEqual, type Node} from './data.ts';\nimport type {SourceSchema} from './schema.ts';\nimport type {Stream} from './stream.ts';\n\nexport function generateWithOverlayNoYield(\n stream: Stream<Node>,\n overlay: Change,\n schema: SourceSchema,\n): Stream<Node> {\n return generateWithOverlay(stream, overlay, schema) as Stream<Node>;\n}\n\nexport function* generateWithOverlay(\n stream: Stream<Node | 'yield'>,\n overlay: Change,\n schema: SourceSchema,\n): Stream<Node | 'yield'> {\n let applied = false;\n let editOldApplied = false;\n let editNewApplied = false;\n for (const node of stream) {\n if (node === 'yield') {\n yield node;\n continue;\n }\n let yieldNode = true;\n if (!applied) {\n switch (overlay[ChangeIndex.TYPE]) {\n case ChangeType.ADD: {\n if (\n schema.compareRows(overlay[ChangeIndex.NODE].row, node.row) === 0\n ) {\n applied = true;\n yieldNode = false;\n }\n break;\n }\n case ChangeType.REMOVE: {\n if (schema.compareRows(overlay[ChangeIndex.NODE].row, node.row) < 0) {\n applied = true;\n yield overlay[ChangeIndex.NODE];\n }\n break;\n }\n case ChangeType.EDIT: {\n if (\n !editOldApplied &&\n schema.compareRows(overlay[ChangeIndex.OLD_NODE].row, node.row) < 0\n ) {\n editOldApplied = true;\n if (editNewApplied) {\n applied = true;\n }\n yield overlay[ChangeIndex.OLD_NODE];\n }\n if (\n !editNewApplied &&\n schema.compareRows(overlay[ChangeIndex.NODE].row, node.row) === 0\n ) {\n editNewApplied = true;\n if (editOldApplied) {\n applied = true;\n }\n yieldNode = false;\n }\n break;\n }\n case ChangeType.CHILD: {\n if (\n schema.compareRows(overlay[ChangeIndex.NODE].row, node.row) === 0\n ) {\n applied = true;\n yield {\n row: node.row,\n relationships: {\n ...node.relationships,\n [overlay[ChangeIndex.CHILD_DATA].relationshipName]: () =>\n generateWithOverlay(\n node.relationships[\n overlay[ChangeIndex.CHILD_DATA].relationshipName\n ](),\n overlay[ChangeIndex.CHILD_DATA].change,\n schema.relationships[\n overlay[ChangeIndex.CHILD_DATA].relationshipName\n ],\n ),\n },\n };\n yieldNode = false;\n }\n break;\n }\n }\n }\n if (yieldNode) {\n yield node;\n }\n }\n if (!applied) {\n if (overlay[ChangeIndex.TYPE] === ChangeType.REMOVE) {\n applied = true;\n yield overlay[ChangeIndex.NODE];\n } else if (overlay[ChangeIndex.TYPE] === ChangeType.EDIT) {\n assert(\n editNewApplied,\n 'edit overlay: new node must be applied before old node',\n );\n editOldApplied = true;\n applied = true;\n yield overlay[ChangeIndex.OLD_NODE];\n }\n }\n\n assert(\n applied,\n 'overlayGenerator: overlay was never applied to any fetched node',\n );\n}\n\nexport function generateWithOverlayNoYieldUnordered(\n stream: Stream<Node>,\n overlay: Change,\n schema: SourceSchema,\n): Stream<Node> {\n return generateWithOverlayUnordered(stream, overlay, schema) as Stream<Node>;\n}\n\nexport function* generateWithOverlayUnordered(\n stream: Stream<Node | 'yield'>,\n overlay: Change,\n schema: SourceSchema,\n): Stream<Node | 'yield'> {\n // Eager inject\n if (overlay[ChangeIndex.TYPE] === ChangeType.REMOVE) {\n yield overlay[ChangeIndex.NODE];\n } else if (overlay[ChangeIndex.TYPE] === ChangeType.EDIT) {\n yield overlay[ChangeIndex.OLD_NODE];\n }\n\n // Stream with inline suppress\n let suppressed = false;\n for (const node of stream) {\n if (node === 'yield') {\n yield node;\n continue;\n }\n if (!suppressed) {\n if (\n overlay[ChangeIndex.TYPE] === ChangeType.ADD ||\n overlay[ChangeIndex.TYPE] === ChangeType.EDIT\n ) {\n if (\n rowEqualsForCompoundKey(\n overlay[ChangeIndex.NODE].row,\n node.row,\n schema.primaryKey,\n )\n ) {\n suppressed = true;\n continue;\n }\n }\n if (overlay[ChangeIndex.TYPE] === ChangeType.CHILD) {\n if (\n rowEqualsForCompoundKey(\n overlay[ChangeIndex.NODE].row,\n node.row,\n schema.primaryKey,\n )\n ) {\n suppressed = true;\n yield {\n row: node.row,\n relationships: {\n ...node.relationships,\n [overlay[ChangeIndex.CHILD_DATA].relationshipName]: () =>\n generateWithOverlay(\n node.relationships[\n overlay[ChangeIndex.CHILD_DATA].relationshipName\n ](),\n overlay[ChangeIndex.CHILD_DATA].change,\n schema.relationships[\n overlay[ChangeIndex.CHILD_DATA].relationshipName\n ],\n ),\n },\n };\n continue;\n }\n }\n }\n yield node;\n }\n assert(\n suppressed || overlay[ChangeIndex.TYPE] === ChangeType.REMOVE,\n 'overlayGenerator: overlay was never applied to any fetched node',\n );\n}\n\nexport function rowEqualsForCompoundKey(\n a: Row,\n b: Row,\n key: CompoundKey,\n): boolean {\n for (let i = 0; i < key.length; i++) {\n if (compareValues(a[key[i]], b[key[i]]) !== 0) {\n return false;\n }\n }\n return true;\n}\n\nexport function isJoinMatch(\n parent: Row,\n parentKey: CompoundKey,\n child: Row,\n childKey: CompoundKey,\n) {\n for (let i = 0; i < parentKey.length; i++) {\n if (!valuesEqual(parent[parentKey[i]], child[childKey[i]])) {\n return false;\n }\n }\n return true;\n}\n\n/**\n * Builds a constraint object by mapping values from `sourceRow` using `sourceKey`\n * to keys specified by `targetKey`. Returns `undefined` if any source value is `null`,\n * since null foreign keys cannot match any rows.\n */\nexport function buildJoinConstraint(\n sourceRow: Row,\n sourceKey: CompoundKey,\n targetKey: CompoundKey,\n): Record<string, Value> | undefined {\n const constraint: Record<string, Value> = {};\n for (let i = 0; i < targetKey.length; i++) {\n const value = sourceRow[sourceKey[i]];\n if (value === null) {\n return undefined;\n }\n constraint[targetKey[i]] = value;\n }\n return constraint;\n}\n\nexport function canonicalKeyForTest(\n record: Record<string, Value | undefined>,\n keys: CompoundKey,\n): string {\n return canonicalKey(record, keys);\n}\n\n/**\n * Canonical string key over `keys` of `record`. Tags values by type\n * so distinct types (e.g. 1 and \"1\") do not collide.\n */\nexport function canonicalKey(\n record: Record<string, Value | undefined>,\n keys: CompoundKey,\n): string {\n if (keys.length === 1) {\n return canonicalValue(record[keys[0]]);\n }\n let s = '';\n for (let i = 0; i < keys.length; i++) {\n if (i > 0) s += '\\x00';\n s += canonicalValue(record[keys[i]]);\n }\n return s;\n}\n\nfunction canonicalValue(v: Value): string {\n // Tag by type so we don't conflate e.g. `1` (number) with `\"1\"` (string).\n if (v === null || v === undefined) return 'n';\n const t = typeof v;\n if (t === 'string') return 's' + (v as string);\n if (t === 'number') return 'd' + (v as number);\n if (t === 'boolean') return v ? 't' : 'f';\n return 'j' + JSON.stringify(v);\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"join.d.ts","sourceRoot":"","sources":["../../../../../zql/src/ivm/join.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAC,WAAW,EAAE,MAAM,EAAC,MAAM,mCAAmC,CAAC;AAW3E,OAAO,KAAK,EAAC,IAAI,EAAC,MAAM,WAAW,CAAC;AACpC,OAAO,EAAC,SAAS,EAAC,MAAM,iBAAiB,CAAC;AAU1C,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;AACxC,OAAO,EAIL,KAAK,iBAAiB,EACvB,MAAM,gBAAgB,CAAC;AAExB,KAAK,IAAI,GAAG;IACV,MAAM,EAAE,KAAK,CAAC;IACd,KAAK,EAAE,KAAK,CAAC;IAEb,SAAS,EAAE,WAAW,CAAC;IACvB,QAAQ,EAAE,WAAW,CAAC;IACtB,gBAAgB,EAAE,MAAM,CAAC;IACzB,MAAM,EAAE,OAAO,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,kBAAkB,CAAC,EAAE,WAAW,GAAG,SAAS,CAAC;IAC7C,aAAa,CAAC,EAAE,iBAAiB,GAAG,SAAS,CAAC;IAC9C;;;;;;;OAOG;IACH,MAAM,CAAC,EAAE,UAAU,GAAG,SAAS,CAAC;CACjC,CAAC;AAEF,MAAM,MAAM,UAAU,GAAG;IACvB,QAAQ,CAAC,EAAE,EAAE,QAAQ,GAAG,YAAY,CAAC;IACrC,QAAQ,CAAC,WAAW,EAAE,SAAS,CAAC;CACjC,CAAC;AAEF;;;;;;;;;GASG;AACH,qBAAa,IAAK,YAAW,KAAK;;IAkChC,YAAY,EACV,MAAM,EACN,KAAK,EACL,SAAS,EACT,QAAQ,EACR,gBAAgB,EAChB,MAAM,EACN,MAAM,EACN,kBAAkB,EAClB,aAAa,EACb,MAAM,GACP,EAAE,IAAI,EAkDN;IAQD,OAAO,IAAI,IAAI,CAGd;IAED,IAAI,kBAAkB,IAAI,SAAS,CAElC;IAED,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAE9B;IAED,SAAS,IAAI,YAAY,CAExB;IAEA,KAAK,CAAC,GAAG,EAAE,YAAY,GAAG,MAAM,CAAC,IAAI,GAAG,OAAO,CAAC,CAShD;CA0QF"}
1
+ {"version":3,"file":"join.d.ts","sourceRoot":"","sources":["../../../../../zql/src/ivm/join.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAC,WAAW,EAAE,MAAM,EAAC,MAAM,mCAAmC,CAAC;AAW3E,OAAO,KAAK,EAAC,IAAI,EAAC,MAAM,WAAW,CAAC;AACpC,OAAO,EAAC,SAAS,EAAC,MAAM,iBAAiB,CAAC;AAU1C,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;AACxC,OAAO,EAIL,KAAK,iBAAiB,EACvB,MAAM,gBAAgB,CAAC;AAExB,KAAK,IAAI,GAAG;IACV,MAAM,EAAE,KAAK,CAAC;IACd,KAAK,EAAE,KAAK,CAAC;IAEb,SAAS,EAAE,WAAW,CAAC;IACvB,QAAQ,EAAE,WAAW,CAAC;IACtB,gBAAgB,EAAE,MAAM,CAAC;IACzB,MAAM,EAAE,OAAO,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,kBAAkB,CAAC,EAAE,WAAW,GAAG,SAAS,CAAC;IAC7C,aAAa,CAAC,EAAE,iBAAiB,GAAG,SAAS,CAAC;IAC9C;;;;;;;OAOG;IACH,MAAM,CAAC,EAAE,UAAU,GAAG,SAAS,CAAC;CACjC,CAAC;AAEF,MAAM,MAAM,UAAU,GAAG;IACvB,QAAQ,CAAC,EAAE,EAAE,QAAQ,GAAG,YAAY,CAAC;IACrC,QAAQ,CAAC,WAAW,EAAE,SAAS,CAAC;CACjC,CAAC;AAEF;;;;;;;;;GASG;AACH,qBAAa,IAAK,YAAW,KAAK;;IAkChC,YAAY,EACV,MAAM,EACN,KAAK,EACL,SAAS,EACT,QAAQ,EACR,gBAAgB,EAChB,MAAM,EACN,MAAM,EACN,kBAAkB,EAClB,aAAa,EACb,MAAM,GACP,EAAE,IAAI,EAkDN;IAQD,OAAO,IAAI,IAAI,CAGd;IAED,IAAI,kBAAkB,IAAI,SAAS,CAElC;IAED,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAE9B;IAED,SAAS,IAAI,YAAY,CAExB;IAEA,KAAK,CAAC,GAAG,EAAE,YAAY,GAAG,MAAM,CAAC,IAAI,GAAG,OAAO,CAAC,CAShD;CA6QF"}
@@ -216,16 +216,19 @@ var Join = class {
216
216
  if (this.#indexesParents) this.#parentIndex.remove(row);
217
217
  }
218
218
  #processParentNode(parentNodeRow, parentNodeRelations) {
219
- const childStream = () => {
219
+ const childStream = (countOnly) => {
220
220
  const constraint = buildJoinConstraint(parentNodeRow, this.#parentKey, this.#childKey);
221
- const stream = constraint ? this.#child.fetch({ constraint }) : [];
222
221
  const inPushQueue = this.#isAfterInprogressPosition(parentNodeRow) && (this.#inprogressParentFetchBounds === void 0 || isInParentFetch(this.#inprogressParentFetchBounds, parentNodeRow, this.#schema.compareRows));
223
222
  if (this.#inprogressChildChange && isJoinMatch(parentNodeRow, this.#parentKey, this.#inprogressChildChange[1].row, this.#childKey) && inPushQueue) {
223
+ const stream = constraint ? this.#child.fetch({ constraint }) : [];
224
224
  const childSchema = this.#child.getSchema();
225
225
  if (childSchema.sort === void 0) return generateWithOverlayUnordered(stream, this.#inprogressChildChange, childSchema);
226
226
  return generateWithOverlay(stream, this.#inprogressChildChange, childSchema);
227
227
  }
228
- return stream;
228
+ return constraint ? this.#child.fetch(countOnly ? {
229
+ constraint,
230
+ countOnly
231
+ } : { constraint }) : [];
229
232
  };
230
233
  return {
231
234
  row: parentNodeRow,
@@ -1 +1 @@
1
- {"version":3,"file":"join.js","names":["#parent","#child","#parentKey","#childKey","#relationshipName","#schema","#parentIndex","#indexesParents","#qualifyingChildChange","#boundProvider","#pushParent","#reconcile","#pushChild","#output","#indexParentRow","#processParentNode","#unindexParentRow","#pushChildChange","#inprogressChildChange","#inprogressChildChangePosition","#inprogressReachedParents","#inprogressParentFetchBounds","#isAfterInprogressPosition"],"sources":["../../../../../zql/src/ivm/join.ts"],"sourcesContent":["import {assert, unreachable} from '../../../shared/src/asserts.ts';\nimport type {CompoundKey, System} from '../../../zero-protocol/src/ast.ts';\nimport type {Row, Value} from '../../../zero-protocol/src/data.ts';\nimport {ChangeIndex} from './change-index.ts';\nimport {ChangeType} from './change-type.ts';\nimport {\n makeAddChange,\n makeChildChange,\n makeEditChange,\n makeRemoveChange,\n type Change,\n} from './change.ts';\nimport type {Node} from './data.ts';\nimport {JoinIndex} from './join-index.ts';\nimport {\n buildJoinConstraint,\n canonicalKey,\n generateWithOverlay,\n generateWithOverlayUnordered,\n isJoinMatch,\n rowEqualsForCompoundKey,\n} from './join-utils.ts';\nimport {mergeSortedStreams} from './memory-source.ts';\nimport {\n throwOutput,\n type FetchRequest,\n type Input,\n type Output,\n} from './operator.ts';\nimport type {SourceSchema} from './schema.ts';\nimport {type Stream} from './stream.ts';\nimport {\n isInParentFetch,\n readParentFetchBounds,\n type ParentFetchBound,\n type TakeBoundProvider,\n} from './take-gate.ts';\n\ntype Args = {\n parent: Input;\n child: Input;\n // The nth key in parentKey corresponds to the nth key in childKey.\n parentKey: CompoundKey;\n childKey: CompoundKey;\n relationshipName: string;\n hidden: boolean;\n system: System;\n parentPartitionKey?: CompoundKey | undefined;\n boundProvider?: TakeBoundProvider | undefined;\n /**\n * Set when this join feeds an EXISTS or NOT EXISTS condition. Its parent\n * index is then kept by a JoinIndexTap at the end of the pipeline, so it\n * only holds the parents the pipeline emits, not every parent this join\n * sees. A child change that misses the index is dropped unless it could\n * make a parent pass the condition: an add for EXISTS, a remove for NOT\n * EXISTS. Those still fetch the parents.\n */\n exists?: ExistsJoin | undefined;\n};\n\nexport type ExistsJoin = {\n readonly op: 'EXISTS' | 'NOT EXISTS';\n readonly parentIndex: JoinIndex;\n};\n\n/**\n * The Join operator joins the output from two upstream inputs. Zero's join\n * is a little different from SQL's join in that we output hierarchical data,\n * not a flat table. This makes it a lot more useful for UI programming and\n * avoids duplicating tons of data like left join would.\n *\n * The Nodes output from Join have a new relationship added to them, which has\n * the name #relationshipName. The value of the relationship is a stream of\n * child nodes which are the corresponding values from the child source.\n */\nexport class Join implements Input {\n readonly #parent: Input;\n readonly #child: Input;\n readonly #parentKey: CompoundKey;\n readonly #childKey: CompoundKey;\n readonly #relationshipName: string;\n readonly #schema: SourceSchema;\n readonly #parentIndex: JoinIndex;\n /**\n * Whether this join adds and removes parents in #parentIndex itself. Not\n * so for EXISTS joins, see Args.exists.\n */\n readonly #indexesParents: boolean;\n /**\n * The child change type that is still pushed to the parents when no\n * indexed parent has its join key. See Args.exists.\n */\n readonly #qualifyingChildChange: ChangeType | undefined;\n readonly #boundProvider: TakeBoundProvider | undefined;\n\n #output: Output = throwOutput;\n\n #inprogressChildChange: Change | undefined;\n #inprogressChildChangePosition: Row | undefined;\n /**\n * Primary keys of the parents #inprogressChildChange has reached so far,\n * kept only when the parent input is unordered. An unordered stream is not\n * in `compareRows` order (SQLite returns it in whatever order its plan\n * visits, e.g. rowid order), so whether a parent is still in the push queue\n * cannot be decided by comparing it to #inprogressChildChangePosition.\n */\n #inprogressReachedParents: Set<string> | undefined;\n #inprogressParentFetchBounds: ParentFetchBound[] | undefined;\n\n constructor({\n parent,\n child,\n parentKey,\n childKey,\n relationshipName,\n hidden,\n system,\n parentPartitionKey,\n boundProvider,\n exists,\n }: Args) {\n assert(parent !== child, 'Parent and child must be different operators');\n assert(\n parentKey.length === childKey.length,\n 'The parentKey and childKey keys must have same length',\n );\n assert(!exists || !parentPartitionKey, 'EXISTS joins are not partitioned');\n this.#parent = parent;\n this.#child = child;\n this.#parentKey = parentKey;\n this.#childKey = childKey;\n this.#relationshipName = relationshipName;\n if (exists) {\n this.#parentIndex = exists.parentIndex;\n this.#indexesParents = false;\n this.#qualifyingChildChange =\n exists.op === 'EXISTS' ? ChangeType.ADD : ChangeType.REMOVE;\n } else {\n this.#parentIndex = new JoinIndex(\n parentKey,\n parent.getSchema().primaryKey,\n parentPartitionKey,\n );\n this.#indexesParents = true;\n this.#qualifyingChildChange = undefined;\n }\n this.#boundProvider = boundProvider;\n\n const parentSchema = parent.getSchema();\n const childSchema = child.getSchema();\n this.#schema = {\n ...parentSchema,\n relationships: {\n ...parentSchema.relationships,\n [relationshipName]: {\n ...childSchema,\n isHidden: hidden,\n system,\n },\n },\n };\n\n parent.setOutput({\n push: (change: Change) => this.#pushParent(change),\n reconcile: () => this.#reconcile(),\n });\n child.setOutput({\n push: (change: Change) => this.#pushChild(change),\n reconcile: () => this.#reconcile(),\n });\n }\n\n *#reconcile(): Stream<'yield'> {\n if (this.#output.reconcile) {\n yield* this.#output.reconcile(this);\n }\n }\n\n destroy(): void {\n this.#parent.destroy();\n this.#child.destroy();\n }\n\n get parentIndexForTest(): JoinIndex {\n return this.#parentIndex;\n }\n\n setOutput(output: Output): void {\n this.#output = output;\n }\n\n getSchema(): SourceSchema {\n return this.#schema;\n }\n\n *fetch(req: FetchRequest): Stream<Node | 'yield'> {\n for (const parentNode of this.#parent.fetch(req)) {\n if (parentNode === 'yield') {\n yield parentNode;\n continue;\n }\n this.#indexParentRow(parentNode.row);\n yield this.#processParentNode(parentNode.row, parentNode.relationships);\n }\n }\n\n *#pushParent(change: Change): Stream<'yield'> {\n switch (change[ChangeIndex.TYPE]) {\n case ChangeType.ADD:\n this.#indexParentRow(change[ChangeIndex.NODE].row);\n yield* this.#output.push(\n makeAddChange(\n this.#processParentNode(\n change[ChangeIndex.NODE].row,\n change[ChangeIndex.NODE].relationships,\n ),\n ),\n this,\n );\n break;\n case ChangeType.REMOVE:\n this.#unindexParentRow(change[ChangeIndex.NODE].row);\n yield* this.#output.push(\n makeRemoveChange(\n this.#processParentNode(\n change[ChangeIndex.NODE].row,\n change[ChangeIndex.NODE].relationships,\n ),\n ),\n this,\n );\n break;\n case ChangeType.CHILD:\n yield* this.#output.push(\n makeChildChange(\n this.#processParentNode(\n change[ChangeIndex.NODE].row,\n change[ChangeIndex.NODE].relationships,\n ),\n change[ChangeIndex.CHILD_DATA],\n ),\n this,\n );\n break;\n case ChangeType.EDIT: {\n // Assert the edit could not change the relationship.\n assert(\n rowEqualsForCompoundKey(\n change[ChangeIndex.OLD_NODE].row,\n change[ChangeIndex.NODE].row,\n this.#parentKey,\n ),\n `Parent edit must not change relationship.`,\n );\n this.#unindexParentRow(change[ChangeIndex.OLD_NODE].row);\n this.#indexParentRow(change[ChangeIndex.NODE].row);\n yield* this.#output.push(\n makeEditChange(\n this.#processParentNode(\n change[ChangeIndex.NODE].row,\n change[ChangeIndex.NODE].relationships,\n ),\n this.#processParentNode(\n change[ChangeIndex.OLD_NODE].row,\n change[ChangeIndex.OLD_NODE].relationships,\n ),\n ),\n this,\n );\n break;\n }\n default:\n unreachable(change);\n }\n }\n\n *#pushChild(change: Change): Stream<'yield'> {\n switch (change[ChangeIndex.TYPE]) {\n case ChangeType.ADD:\n case ChangeType.REMOVE:\n yield* this.#pushChildChange(change[ChangeIndex.NODE].row, change);\n break;\n case ChangeType.CHILD:\n yield* this.#pushChildChange(change[ChangeIndex.NODE].row, change);\n break;\n case ChangeType.EDIT: {\n const childRow = change[ChangeIndex.NODE].row;\n const oldChildRow = change[ChangeIndex.OLD_NODE].row;\n // Assert the edit could not change the relationship.\n assert(\n rowEqualsForCompoundKey(oldChildRow, childRow, this.#childKey),\n 'Child edit must not change relationship.',\n );\n yield* this.#pushChildChange(childRow, change);\n break;\n }\n\n default:\n unreachable(change);\n }\n }\n\n *#pushChildChange(childRow: Row, change: Change): Stream<'yield'> {\n this.#inprogressChildChange = change;\n this.#inprogressChildChangePosition = undefined;\n this.#inprogressReachedParents =\n this.#parent.getSchema().sort === undefined ? new Set() : undefined;\n try {\n const constraint = buildJoinConstraint(\n childRow,\n this.#childKey,\n this.#parentKey,\n );\n if (constraint) {\n const partitions = this.#parentIndex.lookup(childRow, this.#childKey);\n let fetchConstraints: Record<string, Value>[];\n if (partitions) {\n fetchConstraints = partitions.map(partitionConstraint =>\n partitionConstraint\n ? {...constraint, ...partitionConstraint}\n : constraint,\n );\n } else if (change[ChangeIndex.TYPE] === this.#qualifyingChildChange) {\n fetchConstraints = [constraint];\n } else {\n return;\n }\n\n if (this.#boundProvider) {\n this.#inprogressParentFetchBounds = readParentFetchBounds(\n this.#boundProvider,\n fetchConstraints,\n );\n }\n\n let parentNodeStream: Stream<Node | 'yield'>;\n if (fetchConstraints.length === 1) {\n parentNodeStream = this.#parent.fetch({\n constraint: fetchConstraints[0],\n });\n } else {\n const streams = fetchConstraints.map(c =>\n this.#parent.fetch({constraint: c}),\n );\n const compare = (a: Node, b: Node) =>\n this.#schema.compareRows(a.row, b.row);\n parentNodeStream = mergeSortedStreams(streams, compare);\n }\n\n for (const parentNode of parentNodeStream) {\n if (parentNode === 'yield') {\n yield parentNode;\n continue;\n }\n this.#inprogressChildChangePosition = parentNode.row;\n this.#inprogressReachedParents?.add(\n canonicalKey(parentNode.row, this.#schema.primaryKey),\n );\n const childChange = makeChildChange(\n this.#processParentNode(parentNode.row, parentNode.relationships),\n {\n relationshipName: this.#relationshipName,\n change,\n },\n );\n yield* this.#output.push(childChange, this);\n }\n }\n } finally {\n this.#inprogressChildChange = undefined;\n this.#inprogressChildChangePosition = undefined;\n this.#inprogressReachedParents = undefined;\n this.#inprogressParentFetchBounds = undefined;\n }\n }\n\n /**\n * Whether the in-progress child change has yet to reach `parentNodeRow`,\n * i.e. the row comes after #inprogressChildChangePosition in the parent\n * stream.\n */\n #isAfterInprogressPosition(parentNodeRow: Row): boolean {\n if (this.#inprogressChildChangePosition === undefined) {\n return false;\n }\n if (this.#inprogressReachedParents) {\n return !this.#inprogressReachedParents.has(\n canonicalKey(parentNodeRow, this.#schema.primaryKey),\n );\n }\n return (\n this.#schema.compareRows(\n parentNodeRow,\n this.#inprogressChildChangePosition,\n ) > 0\n );\n }\n\n #indexParentRow(row: Row): void {\n if (this.#indexesParents) {\n this.#parentIndex.add(row);\n }\n }\n\n #unindexParentRow(row: Row): void {\n if (this.#indexesParents) {\n this.#parentIndex.remove(row);\n }\n }\n\n #processParentNode(\n parentNodeRow: Row,\n parentNodeRelations: Record<string, () => Stream<Node | 'yield'>>,\n ): Node {\n const childStream = () => {\n const constraint = buildJoinConstraint(\n parentNodeRow,\n this.#parentKey,\n this.#childKey,\n );\n const stream = constraint ? this.#child.fetch({constraint}) : [];\n\n // The parent has yet to get the in-progress child change if it comes\n // after the current position and a parent fetch of the push yields it.\n // With a TakeGate the fetches are capped at the bounds read when they\n // started.\n const inPushQueue =\n this.#isAfterInprogressPosition(parentNodeRow) &&\n (this.#inprogressParentFetchBounds === undefined ||\n isInParentFetch(\n this.#inprogressParentFetchBounds,\n parentNodeRow,\n this.#schema.compareRows,\n ));\n\n if (\n this.#inprogressChildChange &&\n isJoinMatch(\n parentNodeRow,\n this.#parentKey,\n this.#inprogressChildChange[ChangeIndex.NODE].row,\n this.#childKey,\n ) &&\n inPushQueue\n ) {\n const childSchema = this.#child.getSchema();\n if (childSchema.sort === undefined) {\n return generateWithOverlayUnordered(\n stream,\n this.#inprogressChildChange,\n childSchema,\n );\n }\n return generateWithOverlay(\n stream,\n this.#inprogressChildChange,\n childSchema,\n );\n }\n return stream;\n };\n\n return {\n row: parentNodeRow,\n relationships: {\n ...parentNodeRelations,\n [this.#relationshipName]: childStream,\n },\n };\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"join.js","names":[],"sources":["../../../../../zql/src/ivm/join.ts"],"sourcesContent":["import {assert, unreachable} from '../../../shared/src/asserts.ts';\nimport type {CompoundKey, System} from '../../../zero-protocol/src/ast.ts';\nimport type {Row, Value} from '../../../zero-protocol/src/data.ts';\nimport {ChangeIndex} from './change-index.ts';\nimport {ChangeType} from './change-type.ts';\nimport {\n makeAddChange,\n makeChildChange,\n makeEditChange,\n makeRemoveChange,\n type Change,\n} from './change.ts';\nimport type {Node} from './data.ts';\nimport {JoinIndex} from './join-index.ts';\nimport {\n buildJoinConstraint,\n canonicalKey,\n generateWithOverlay,\n generateWithOverlayUnordered,\n isJoinMatch,\n rowEqualsForCompoundKey,\n} from './join-utils.ts';\nimport {mergeSortedStreams} from './memory-source.ts';\nimport {\n throwOutput,\n type FetchRequest,\n type Input,\n type Output,\n} from './operator.ts';\nimport type {SourceSchema} from './schema.ts';\nimport {type Stream} from './stream.ts';\nimport {\n isInParentFetch,\n readParentFetchBounds,\n type ParentFetchBound,\n type TakeBoundProvider,\n} from './take-gate.ts';\n\ntype Args = {\n parent: Input;\n child: Input;\n // The nth key in parentKey corresponds to the nth key in childKey.\n parentKey: CompoundKey;\n childKey: CompoundKey;\n relationshipName: string;\n hidden: boolean;\n system: System;\n parentPartitionKey?: CompoundKey | undefined;\n boundProvider?: TakeBoundProvider | undefined;\n /**\n * Set when this join feeds an EXISTS or NOT EXISTS condition. Its parent\n * index is then kept by a JoinIndexTap at the end of the pipeline, so it\n * only holds the parents the pipeline emits, not every parent this join\n * sees. A child change that misses the index is dropped unless it could\n * make a parent pass the condition: an add for EXISTS, a remove for NOT\n * EXISTS. Those still fetch the parents.\n */\n exists?: ExistsJoin | undefined;\n};\n\nexport type ExistsJoin = {\n readonly op: 'EXISTS' | 'NOT EXISTS';\n readonly parentIndex: JoinIndex;\n};\n\n/**\n * The Join operator joins the output from two upstream inputs. Zero's join\n * is a little different from SQL's join in that we output hierarchical data,\n * not a flat table. This makes it a lot more useful for UI programming and\n * avoids duplicating tons of data like left join would.\n *\n * The Nodes output from Join have a new relationship added to them, which has\n * the name #relationshipName. The value of the relationship is a stream of\n * child nodes which are the corresponding values from the child source.\n */\nexport class Join implements Input {\n readonly #parent: Input;\n readonly #child: Input;\n readonly #parentKey: CompoundKey;\n readonly #childKey: CompoundKey;\n readonly #relationshipName: string;\n readonly #schema: SourceSchema;\n readonly #parentIndex: JoinIndex;\n /**\n * Whether this join adds and removes parents in #parentIndex itself. Not\n * so for EXISTS joins, see Args.exists.\n */\n readonly #indexesParents: boolean;\n /**\n * The child change type that is still pushed to the parents when no\n * indexed parent has its join key. See Args.exists.\n */\n readonly #qualifyingChildChange: ChangeType | undefined;\n readonly #boundProvider: TakeBoundProvider | undefined;\n\n #output: Output = throwOutput;\n\n #inprogressChildChange: Change | undefined;\n #inprogressChildChangePosition: Row | undefined;\n /**\n * Primary keys of the parents #inprogressChildChange has reached so far,\n * kept only when the parent input is unordered. An unordered stream is not\n * in `compareRows` order (SQLite returns it in whatever order its plan\n * visits, e.g. rowid order), so whether a parent is still in the push queue\n * cannot be decided by comparing it to #inprogressChildChangePosition.\n */\n #inprogressReachedParents: Set<string> | undefined;\n #inprogressParentFetchBounds: ParentFetchBound[] | undefined;\n\n constructor({\n parent,\n child,\n parentKey,\n childKey,\n relationshipName,\n hidden,\n system,\n parentPartitionKey,\n boundProvider,\n exists,\n }: Args) {\n assert(parent !== child, 'Parent and child must be different operators');\n assert(\n parentKey.length === childKey.length,\n 'The parentKey and childKey keys must have same length',\n );\n assert(!exists || !parentPartitionKey, 'EXISTS joins are not partitioned');\n this.#parent = parent;\n this.#child = child;\n this.#parentKey = parentKey;\n this.#childKey = childKey;\n this.#relationshipName = relationshipName;\n if (exists) {\n this.#parentIndex = exists.parentIndex;\n this.#indexesParents = false;\n this.#qualifyingChildChange =\n exists.op === 'EXISTS' ? ChangeType.ADD : ChangeType.REMOVE;\n } else {\n this.#parentIndex = new JoinIndex(\n parentKey,\n parent.getSchema().primaryKey,\n parentPartitionKey,\n );\n this.#indexesParents = true;\n this.#qualifyingChildChange = undefined;\n }\n this.#boundProvider = boundProvider;\n\n const parentSchema = parent.getSchema();\n const childSchema = child.getSchema();\n this.#schema = {\n ...parentSchema,\n relationships: {\n ...parentSchema.relationships,\n [relationshipName]: {\n ...childSchema,\n isHidden: hidden,\n system,\n },\n },\n };\n\n parent.setOutput({\n push: (change: Change) => this.#pushParent(change),\n reconcile: () => this.#reconcile(),\n });\n child.setOutput({\n push: (change: Change) => this.#pushChild(change),\n reconcile: () => this.#reconcile(),\n });\n }\n\n *#reconcile(): Stream<'yield'> {\n if (this.#output.reconcile) {\n yield* this.#output.reconcile(this);\n }\n }\n\n destroy(): void {\n this.#parent.destroy();\n this.#child.destroy();\n }\n\n get parentIndexForTest(): JoinIndex {\n return this.#parentIndex;\n }\n\n setOutput(output: Output): void {\n this.#output = output;\n }\n\n getSchema(): SourceSchema {\n return this.#schema;\n }\n\n *fetch(req: FetchRequest): Stream<Node | 'yield'> {\n for (const parentNode of this.#parent.fetch(req)) {\n if (parentNode === 'yield') {\n yield parentNode;\n continue;\n }\n this.#indexParentRow(parentNode.row);\n yield this.#processParentNode(parentNode.row, parentNode.relationships);\n }\n }\n\n *#pushParent(change: Change): Stream<'yield'> {\n switch (change[ChangeIndex.TYPE]) {\n case ChangeType.ADD:\n this.#indexParentRow(change[ChangeIndex.NODE].row);\n yield* this.#output.push(\n makeAddChange(\n this.#processParentNode(\n change[ChangeIndex.NODE].row,\n change[ChangeIndex.NODE].relationships,\n ),\n ),\n this,\n );\n break;\n case ChangeType.REMOVE:\n this.#unindexParentRow(change[ChangeIndex.NODE].row);\n yield* this.#output.push(\n makeRemoveChange(\n this.#processParentNode(\n change[ChangeIndex.NODE].row,\n change[ChangeIndex.NODE].relationships,\n ),\n ),\n this,\n );\n break;\n case ChangeType.CHILD:\n yield* this.#output.push(\n makeChildChange(\n this.#processParentNode(\n change[ChangeIndex.NODE].row,\n change[ChangeIndex.NODE].relationships,\n ),\n change[ChangeIndex.CHILD_DATA],\n ),\n this,\n );\n break;\n case ChangeType.EDIT: {\n // Assert the edit could not change the relationship.\n assert(\n rowEqualsForCompoundKey(\n change[ChangeIndex.OLD_NODE].row,\n change[ChangeIndex.NODE].row,\n this.#parentKey,\n ),\n `Parent edit must not change relationship.`,\n );\n this.#unindexParentRow(change[ChangeIndex.OLD_NODE].row);\n this.#indexParentRow(change[ChangeIndex.NODE].row);\n yield* this.#output.push(\n makeEditChange(\n this.#processParentNode(\n change[ChangeIndex.NODE].row,\n change[ChangeIndex.NODE].relationships,\n ),\n this.#processParentNode(\n change[ChangeIndex.OLD_NODE].row,\n change[ChangeIndex.OLD_NODE].relationships,\n ),\n ),\n this,\n );\n break;\n }\n default:\n unreachable(change);\n }\n }\n\n *#pushChild(change: Change): Stream<'yield'> {\n switch (change[ChangeIndex.TYPE]) {\n case ChangeType.ADD:\n case ChangeType.REMOVE:\n yield* this.#pushChildChange(change[ChangeIndex.NODE].row, change);\n break;\n case ChangeType.CHILD:\n yield* this.#pushChildChange(change[ChangeIndex.NODE].row, change);\n break;\n case ChangeType.EDIT: {\n const childRow = change[ChangeIndex.NODE].row;\n const oldChildRow = change[ChangeIndex.OLD_NODE].row;\n // Assert the edit could not change the relationship.\n assert(\n rowEqualsForCompoundKey(oldChildRow, childRow, this.#childKey),\n 'Child edit must not change relationship.',\n );\n yield* this.#pushChildChange(childRow, change);\n break;\n }\n\n default:\n unreachable(change);\n }\n }\n\n *#pushChildChange(childRow: Row, change: Change): Stream<'yield'> {\n this.#inprogressChildChange = change;\n this.#inprogressChildChangePosition = undefined;\n this.#inprogressReachedParents =\n this.#parent.getSchema().sort === undefined ? new Set() : undefined;\n try {\n const constraint = buildJoinConstraint(\n childRow,\n this.#childKey,\n this.#parentKey,\n );\n if (constraint) {\n const partitions = this.#parentIndex.lookup(childRow, this.#childKey);\n let fetchConstraints: Record<string, Value>[];\n if (partitions) {\n fetchConstraints = partitions.map(partitionConstraint =>\n partitionConstraint\n ? {...constraint, ...partitionConstraint}\n : constraint,\n );\n } else if (change[ChangeIndex.TYPE] === this.#qualifyingChildChange) {\n fetchConstraints = [constraint];\n } else {\n return;\n }\n\n if (this.#boundProvider) {\n this.#inprogressParentFetchBounds = readParentFetchBounds(\n this.#boundProvider,\n fetchConstraints,\n );\n }\n\n let parentNodeStream: Stream<Node | 'yield'>;\n if (fetchConstraints.length === 1) {\n parentNodeStream = this.#parent.fetch({\n constraint: fetchConstraints[0],\n });\n } else {\n const streams = fetchConstraints.map(c =>\n this.#parent.fetch({constraint: c}),\n );\n const compare = (a: Node, b: Node) =>\n this.#schema.compareRows(a.row, b.row);\n parentNodeStream = mergeSortedStreams(streams, compare);\n }\n\n for (const parentNode of parentNodeStream) {\n if (parentNode === 'yield') {\n yield parentNode;\n continue;\n }\n this.#inprogressChildChangePosition = parentNode.row;\n this.#inprogressReachedParents?.add(\n canonicalKey(parentNode.row, this.#schema.primaryKey),\n );\n const childChange = makeChildChange(\n this.#processParentNode(parentNode.row, parentNode.relationships),\n {\n relationshipName: this.#relationshipName,\n change,\n },\n );\n yield* this.#output.push(childChange, this);\n }\n }\n } finally {\n this.#inprogressChildChange = undefined;\n this.#inprogressChildChangePosition = undefined;\n this.#inprogressReachedParents = undefined;\n this.#inprogressParentFetchBounds = undefined;\n }\n }\n\n /**\n * Whether the in-progress child change has yet to reach `parentNodeRow`,\n * i.e. the row comes after #inprogressChildChangePosition in the parent\n * stream.\n */\n #isAfterInprogressPosition(parentNodeRow: Row): boolean {\n if (this.#inprogressChildChangePosition === undefined) {\n return false;\n }\n if (this.#inprogressReachedParents) {\n return !this.#inprogressReachedParents.has(\n canonicalKey(parentNodeRow, this.#schema.primaryKey),\n );\n }\n return (\n this.#schema.compareRows(\n parentNodeRow,\n this.#inprogressChildChangePosition,\n ) > 0\n );\n }\n\n #indexParentRow(row: Row): void {\n if (this.#indexesParents) {\n this.#parentIndex.add(row);\n }\n }\n\n #unindexParentRow(row: Row): void {\n if (this.#indexesParents) {\n this.#parentIndex.remove(row);\n }\n }\n\n #processParentNode(\n parentNodeRow: Row,\n parentNodeRelations: Record<string, () => Stream<Node | 'yield'>>,\n ): Node {\n const childStream = (countOnly?: boolean | undefined) => {\n const constraint = buildJoinConstraint(\n parentNodeRow,\n this.#parentKey,\n this.#childKey,\n );\n\n // The parent has yet to get the in-progress child change if it comes\n // after the current position and a parent fetch of the push yields it.\n // With a TakeGate the fetches are capped at the bounds read when they\n // started.\n const inPushQueue =\n this.#isAfterInprogressPosition(parentNodeRow) &&\n (this.#inprogressParentFetchBounds === undefined ||\n isInParentFetch(\n this.#inprogressParentFetchBounds,\n parentNodeRow,\n this.#schema.compareRows,\n ));\n\n if (\n this.#inprogressChildChange &&\n isJoinMatch(\n parentNodeRow,\n this.#parentKey,\n this.#inprogressChildChange[ChangeIndex.NODE].row,\n this.#childKey,\n ) &&\n inPushQueue\n ) {\n // The overlay needs the child rows, so countOnly is not forwarded.\n const stream = constraint ? this.#child.fetch({constraint}) : [];\n const childSchema = this.#child.getSchema();\n if (childSchema.sort === undefined) {\n return generateWithOverlayUnordered(\n stream,\n this.#inprogressChildChange,\n childSchema,\n );\n }\n return generateWithOverlay(\n stream,\n this.#inprogressChildChange,\n childSchema,\n );\n }\n return constraint\n ? this.#child.fetch(countOnly ? {constraint, countOnly} : {constraint})\n : [];\n };\n\n return {\n row: parentNodeRow,\n relationships: {\n ...parentNodeRelations,\n [this.#relationshipName]: childStream,\n },\n };\n }\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"maybe-split-and-push-edit-change.js","names":[],"sources":["../../../../../zql/src/ivm/maybe-split-and-push-edit-change.ts"],"sourcesContent":["import {emptyArray} from '../../../shared/src/sentinels.ts';\nimport type {Row} from '../../../zero-protocol/src/data.ts';\nimport {ChangeIndex} from './change-index.ts';\nimport {makeAddChange, makeRemoveChange, type EditChange} from './change.ts';\nimport type {InputBase, Output} from './operator.ts';\n\n/**\n * This takes an {@link EditChange} and a predicate that determines if a row\n * should be present based on the row's data. It then splits the change and\n * pushes the appropriate changes to the output based on the predicate.\n */\nexport function maybeSplitAndPushEditChange(\n change: EditChange,\n predicate: (row: Row) => boolean,\n output: Output,\n pusher: InputBase,\n) {\n const oldWasPresent = predicate(change[ChangeIndex.OLD_NODE].row);\n const newIsPresent = predicate(change[ChangeIndex.NODE].row);\n\n if (oldWasPresent && newIsPresent) {\n return output.push(change, pusher);\n }\n if (oldWasPresent && !newIsPresent) {\n return output.push(makeRemoveChange(change[ChangeIndex.OLD_NODE]), pusher);\n }\n if (!oldWasPresent && newIsPresent) {\n return output.push(makeAddChange(change[ChangeIndex.NODE]), pusher);\n }\n\n return emptyArray;\n}\n"],"mappings":";;;;;;;;AAWA,SAAgB,4BACd,QACA,WACA,QACA,QACA;CACA,MAAM,gBAAgB,UAAU,OAAO,GAAsB,GAAG;CAChE,MAAM,eAAe,UAAU,OAAO,GAAkB,GAAG;CAE3D,IAAI,iBAAiB,cACnB,OAAO,OAAO,KAAK,QAAQ,MAAM;CAEnC,IAAI,iBAAiB,CAAC,cACpB,OAAO,OAAO,KAAK,iBAAiB,OAAO,EAAqB,GAAG,MAAM;CAE3E,IAAI,CAAC,iBAAiB,cACpB,OAAO,OAAO,KAAK,cAAc,OAAO,EAAiB,GAAG,MAAM;CAGpE,OAAO;AACT"}
1
+ {"version":3,"file":"maybe-split-and-push-edit-change.js","names":[],"sources":["../../../../../zql/src/ivm/maybe-split-and-push-edit-change.ts"],"sourcesContent":["import {emptyArray} from '../../../shared/src/sentinels.ts';\nimport type {Row} from '../../../zero-protocol/src/data.ts';\nimport {ChangeIndex} from './change-index.ts';\nimport {makeAddChange, makeRemoveChange, type EditChange} from './change.ts';\nimport type {InputBase, Output} from './operator.ts';\n\n/**\n * This takes an {@link EditChange} and a predicate that determines if a row\n * should be present based on the row's data. It then splits the change and\n * pushes the appropriate changes to the output based on the predicate.\n */\nexport function maybeSplitAndPushEditChange(\n change: EditChange,\n predicate: (row: Row) => boolean,\n output: Output,\n pusher: InputBase,\n) {\n const oldWasPresent = predicate(change[ChangeIndex.OLD_NODE].row);\n const newIsPresent = predicate(change[ChangeIndex.NODE].row);\n\n if (oldWasPresent && newIsPresent) {\n return output.push(change, pusher);\n }\n if (oldWasPresent && !newIsPresent) {\n return output.push(makeRemoveChange(change[ChangeIndex.OLD_NODE]), pusher);\n }\n if (!oldWasPresent && newIsPresent) {\n return output.push(makeAddChange(change[ChangeIndex.NODE]), pusher);\n }\n\n return emptyArray;\n}\n"],"mappings":";;;;;;;;AAWA,SAAgB,4BACd,QACA,WACA,QACA,QACA;CACA,MAAM,gBAAgB,UAAU,OAAO,EAAqB,CAAC,GAAG;CAChE,MAAM,eAAe,UAAU,OAAO,EAAiB,CAAC,GAAG;CAE3D,IAAI,iBAAiB,cACnB,OAAO,OAAO,KAAK,QAAQ,MAAM;CAEnC,IAAI,iBAAiB,CAAC,cACpB,OAAO,OAAO,KAAK,iBAAiB,OAAO,EAAqB,GAAG,MAAM;CAE3E,IAAI,CAAC,iBAAiB,cACpB,OAAO,OAAO,KAAK,cAAc,OAAO,EAAiB,GAAG,MAAM;CAGpE,OAAO;AACT"}
@@ -4,9 +4,9 @@ import { once, toSorted } from "../../../shared/src/iterables.js";
4
4
  import { must } from "../../../shared/src/must.js";
5
5
  import { skipYields } from "./skip-yields.js";
6
6
  import { makeAddChange, makeEditChange, makeRemoveChange } from "./change.js";
7
+ import { compareValues, makeComparator, valuesEqual } from "./data.js";
7
8
  import { consume } from "./stream.js";
8
9
  import { assertOrderingIncludesPK } from "../query/complete-ordering.js";
9
- import { compareValues, makeComparator, valuesEqual } from "./data.js";
10
10
  import { filterPush } from "./filter-push.js";
11
11
  import { constraintMatchesPrimaryKey, constraintMatchesRow, primaryKeyConstraintFromFilters } from "./constraint.js";
12
12
  import { BTreeSet } from "../../../shared/src/btree-set.js";
@@ -166,7 +166,8 @@ var MemorySource = class MemorySource {
166
166
  }
167
167
  return;
168
168
  }
169
- const withConstraint = generateWithConstraint(skipYields(generateWithStart(generateWithOverlay(startAt, pkConstraint ? once(rowsIterable) : rowsIterable, req.constraint, this.#overlay, conn.lastPushedEpoch, indexComparator, connectionComparator, mergedFilterPredicate), req.start, connectionComparator)), req.constraint);
169
+ const withOverlay = generateWithOverlay(startAt, pkConstraint ? once(rowsIterable) : rowsIterable, req.constraint, this.#overlay, conn.lastPushedEpoch, indexComparator, connectionComparator, mergedFilterPredicate);
170
+ const withConstraint = generateWithConstraint(skipYields(generateWithStart(withOverlay, req.start, connectionComparator)), req.constraint);
170
171
  yield* mergedFilterPredicate ? generateWithFilter(withConstraint, mergedFilterPredicate) : withConstraint;
171
172
  }
172
173
  *#fetchMulti(req, conn) {
@@ -242,16 +243,22 @@ var MemorySource = class MemorySource {
242
243
  }
243
244
  #writeChange(change) {
244
245
  for (const { data } of this.#indexes.values()) switch (change[0]) {
245
- case 0:
246
- assert(data.add(change[1]), "MemorySource: add must succeed since row existence was already checked");
246
+ case 0: {
247
+ const added = data.add(change[1]);
248
+ assert(added, "MemorySource: add must succeed since row existence was already checked");
247
249
  break;
248
- case 1:
249
- assert(data.delete(change[1]), "MemorySource: remove must succeed since row existence was already checked");
250
+ }
251
+ case 1: {
252
+ const removed = data.delete(change[1]);
253
+ assert(removed, "MemorySource: remove must succeed since row existence was already checked");
250
254
  break;
251
- case 2:
252
- assert(data.delete(change[2]), "MemorySource: edit remove must succeed since row existence was already checked");
255
+ }
256
+ case 2: {
257
+ const removed = data.delete(change[2]);
258
+ assert(removed, "MemorySource: edit remove must succeed since row existence was already checked");
253
259
  data.add(change[1]);
254
260
  break;
261
+ }
255
262
  default: unreachable(change);
256
263
  }
257
264
  }
@@ -312,7 +319,7 @@ function* genPush(connections, change, exists, setOverlay, pushEpoch) {
312
319
  const { output, filters, input } = conn;
313
320
  if (output) {
314
321
  conn.lastPushedEpoch = pushEpoch;
315
- yield* filterPush(change[0] === 2 ? makeEditChange({
322
+ const outputChange = change[0] === 2 ? makeEditChange({
316
323
  row: change[1],
317
324
  relationships: {}
318
325
  }, {
@@ -324,7 +331,8 @@ function* genPush(connections, change, exists, setOverlay, pushEpoch) {
324
331
  }) : makeRemoveChange({
325
332
  row: change[1],
326
333
  relationships: {}
327
- }), output, input, filters?.predicate);
334
+ });
335
+ yield* filterPush(outputChange, output, input, filters?.predicate);
328
336
  yield void 0;
329
337
  }
330
338
  }
@@ -403,12 +411,10 @@ function computeOverlays(startAt, constraint, overlay, startAtCompare, filterPre
403
411
  remove: overlay.change[1]
404
412
  };
405
413
  break;
406
- case 2:
407
- overlays = {
408
- add: overlay.change[1],
409
- remove: overlay.change[2]
410
- };
411
- break;
414
+ case 2: overlays = {
415
+ add: overlay.change[1],
416
+ remove: overlay.change[2]
417
+ };
412
418
  }
413
419
  if (startAt) overlays = overlaysForStartAt(overlays, startAt, startAtCompare);
414
420
  if (constraint) overlays = overlaysForConstraint(overlays, constraint);
@@ -507,12 +513,10 @@ function generateWithOverlayUnordered(rows, constraint, overlay, lastPushedEpoch
507
513
  remove: overlayToApply.change[1]
508
514
  };
509
515
  break;
510
- case 2:
511
- overlays = {
512
- add: overlayToApply.change[1],
513
- remove: overlayToApply.change[2]
514
- };
515
- break;
516
+ case 2: overlays = {
517
+ add: overlayToApply.change[1],
518
+ remove: overlayToApply.change[2]
519
+ };
516
520
  }
517
521
  if (constraint) overlays = overlaysForConstraint(overlays, constraint);
518
522
  overlays = applyMultiConstraintsToOverlays(overlays, multiConstraints);
@@ -670,6 +674,6 @@ function* mergeSortedStreams(streams, compare) {
670
674
  }
671
675
  }
672
676
  //#endregion
673
- export { MemorySource, genPushAndWriteWithSplitEdit, generateRows, generateWithOverlay, generateWithOverlayUnordered, generateWithStart, makeBoundComparator, maxValue, mergeSortedStreams, minValue };
677
+ export { MemorySource, genPushAndWriteWithSplitEdit, generateRows, generateWithOverlay, generateWithOverlayInner, generateWithOverlayInnerUnordered, generateWithOverlayUnordered, generateWithStart, makeBoundComparator, maxValue, mergeSortedStreams, minValue, overlaysForConstraint as overlaysForConstraintForTest, overlaysForMultiConstraint as overlaysForMultiConstraintForTest, overlaysForStartAt as overlaysForStartAtForTest, stringify };
674
678
 
675
679
  //# sourceMappingURL=memory-source.js.map