@rocicorp/zero 1.10.0-canary.23 → 1.10.0-canary.25

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 (485) hide show
  1. package/out/analyze-query/src/bin-analyze.js +1 -1
  2. package/out/analyze-query/src/bin-analyze.js.map +1 -1
  3. package/out/replicache/src/btree/read.d.ts +1 -12
  4. package/out/replicache/src/btree/read.d.ts.map +1 -1
  5. package/out/replicache/src/btree/read.js +12 -24
  6. package/out/replicache/src/btree/read.js.map +1 -1
  7. package/out/replicache/src/dag/gc.d.ts.map +1 -1
  8. package/out/replicache/src/dag/gc.js +1 -2
  9. package/out/replicache/src/dag/gc.js.map +1 -1
  10. package/out/replicache/src/dag/store-impl.d.ts +2 -12
  11. package/out/replicache/src/dag/store-impl.d.ts.map +1 -1
  12. package/out/replicache/src/dag/store-impl.js +8 -22
  13. package/out/replicache/src/dag/store-impl.js.map +1 -1
  14. package/out/replicache/src/db/rebase.d.ts +2 -14
  15. package/out/replicache/src/db/rebase.d.ts.map +1 -1
  16. package/out/replicache/src/db/rebase.js +5 -27
  17. package/out/replicache/src/db/rebase.js.map +1 -1
  18. package/out/replicache/src/db/write.js.map +1 -1
  19. package/out/replicache/src/kv/expo-sqlite/store.d.ts.map +1 -1
  20. package/out/replicache/src/kv/expo-sqlite/store.js +5 -28
  21. package/out/replicache/src/kv/expo-sqlite/store.js.map +1 -1
  22. package/out/replicache/src/kv/idb-store-with-mem-fallback.d.ts +5 -15
  23. package/out/replicache/src/kv/idb-store-with-mem-fallback.d.ts.map +1 -1
  24. package/out/replicache/src/kv/idb-store-with-mem-fallback.js +25 -25
  25. package/out/replicache/src/kv/idb-store-with-mem-fallback.js.map +1 -1
  26. package/out/replicache/src/kv/idb-store.d.ts +0 -9
  27. package/out/replicache/src/kv/idb-store.d.ts.map +1 -1
  28. package/out/replicache/src/kv/idb-store.js +2 -14
  29. package/out/replicache/src/kv/idb-store.js.map +1 -1
  30. package/out/replicache/src/kv/mem-store.d.ts +0 -1
  31. package/out/replicache/src/kv/mem-store.d.ts.map +1 -1
  32. package/out/replicache/src/kv/mem-store.js +0 -3
  33. package/out/replicache/src/kv/mem-store.js.map +1 -1
  34. package/out/replicache/src/kv/op-sqlite/store.d.ts.map +1 -1
  35. package/out/replicache/src/kv/op-sqlite/store.js +1 -1
  36. package/out/replicache/src/kv/op-sqlite/store.js.map +1 -1
  37. package/out/replicache/src/kv/sqlite-store.d.ts +1 -13
  38. package/out/replicache/src/kv/sqlite-store.d.ts.map +1 -1
  39. package/out/replicache/src/kv/sqlite-store.js +4 -49
  40. package/out/replicache/src/kv/sqlite-store.js.map +1 -1
  41. package/out/replicache/src/kv/store.d.ts +0 -6
  42. package/out/replicache/src/kv/store.d.ts.map +1 -1
  43. package/out/replicache/src/persist/collect-idb-databases.d.ts +5 -10
  44. package/out/replicache/src/persist/collect-idb-databases.d.ts.map +1 -1
  45. package/out/replicache/src/persist/collect-idb-databases.js +9 -16
  46. package/out/replicache/src/persist/collect-idb-databases.js.map +1 -1
  47. package/out/replicache/src/persist/persist.d.ts.map +1 -1
  48. package/out/replicache/src/persist/persist.js +5 -12
  49. package/out/replicache/src/persist/persist.js.map +1 -1
  50. package/out/replicache/src/persist/refresh.js +2 -6
  51. package/out/replicache/src/persist/refresh.js.map +1 -1
  52. package/out/replicache/src/replicache-impl.d.ts +3 -14
  53. package/out/replicache/src/replicache-impl.d.ts.map +1 -1
  54. package/out/replicache/src/replicache-impl.js +11 -118
  55. package/out/replicache/src/replicache-impl.js.map +1 -1
  56. package/out/replicache/src/replicache-options.d.ts +0 -9
  57. package/out/replicache/src/replicache-options.d.ts.map +1 -1
  58. package/out/replicache/src/transactions.d.ts.map +1 -1
  59. package/out/replicache/src/transactions.js +1 -1
  60. package/out/replicache/src/transactions.js.map +1 -1
  61. package/out/shared/src/arrays.js +15 -1
  62. package/out/shared/src/arrays.js.map +1 -1
  63. package/out/shared/src/base64.d.ts +19 -0
  64. package/out/shared/src/base64.d.ts.map +1 -0
  65. package/out/shared/src/base64.js +40 -0
  66. package/out/shared/src/base64.js.map +1 -0
  67. package/out/shared/src/error.d.ts +0 -11
  68. package/out/shared/src/error.d.ts.map +1 -1
  69. package/out/shared/src/error.js +1 -35
  70. package/out/shared/src/error.js.map +1 -1
  71. package/out/shared/src/hash.d.ts +0 -1
  72. package/out/shared/src/hash.d.ts.map +1 -1
  73. package/out/shared/src/hash.js +10 -87
  74. package/out/shared/src/hash.js.map +1 -1
  75. package/out/shared/src/iterables.d.ts +0 -2
  76. package/out/shared/src/iterables.d.ts.map +1 -1
  77. package/out/shared/src/iterables.js +1 -18
  78. package/out/shared/src/iterables.js.map +1 -1
  79. package/out/shared/src/json.d.ts.map +1 -1
  80. package/out/shared/src/json.js +2 -2
  81. package/out/shared/src/json.js.map +1 -1
  82. package/out/shared/src/map.d.ts +2 -7
  83. package/out/shared/src/map.d.ts.map +1 -1
  84. package/out/shared/src/map.js.map +1 -1
  85. package/out/shared/src/packed-boolean-map.d.ts +7 -0
  86. package/out/shared/src/packed-boolean-map.d.ts.map +1 -0
  87. package/out/shared/src/packed-boolean-map.js +36 -0
  88. package/out/shared/src/packed-boolean-map.js.map +1 -0
  89. package/out/shared/src/ring-buffer.d.ts +0 -8
  90. package/out/shared/src/ring-buffer.d.ts.map +1 -1
  91. package/out/shared/src/ring-buffer.js +1 -22
  92. package/out/shared/src/ring-buffer.js.map +1 -1
  93. package/out/z2s/src/compiler.js +1 -1
  94. package/out/zero/package.js +3 -2
  95. package/out/zero/package.js.map +1 -1
  96. package/out/zero-cache/src/auth/read-authorizer.js +1 -1
  97. package/out/zero-cache/src/config/zero-config.d.ts +2 -27
  98. package/out/zero-cache/src/config/zero-config.d.ts.map +1 -1
  99. package/out/zero-cache/src/config/zero-config.js +28 -114
  100. package/out/zero-cache/src/config/zero-config.js.map +1 -1
  101. package/out/zero-cache/src/custom-queries/transform-query.js +1 -1
  102. package/out/zero-cache/src/db/create.d.ts.map +1 -1
  103. package/out/zero-cache/src/db/create.js +1 -4
  104. package/out/zero-cache/src/db/create.js.map +1 -1
  105. package/out/zero-cache/src/db/lite-tables.d.ts +2 -10
  106. package/out/zero-cache/src/db/lite-tables.d.ts.map +1 -1
  107. package/out/zero-cache/src/db/lite-tables.js +3 -8
  108. package/out/zero-cache/src/db/lite-tables.js.map +1 -1
  109. package/out/zero-cache/src/db/specs.d.ts +0 -41
  110. package/out/zero-cache/src/db/specs.d.ts.map +1 -1
  111. package/out/zero-cache/src/db/specs.js +3 -30
  112. package/out/zero-cache/src/db/specs.js.map +1 -1
  113. package/out/zero-cache/src/server/change-streamer.d.ts.map +1 -1
  114. package/out/zero-cache/src/server/change-streamer.js +4 -13
  115. package/out/zero-cache/src/server/change-streamer.js.map +1 -1
  116. package/out/zero-cache/src/server/inspector-delegate.d.ts +2 -18
  117. package/out/zero-cache/src/server/inspector-delegate.d.ts.map +1 -1
  118. package/out/zero-cache/src/server/inspector-delegate.js +9 -23
  119. package/out/zero-cache/src/server/inspector-delegate.js.map +1 -1
  120. package/out/zero-cache/src/server/main.d.ts.map +1 -1
  121. package/out/zero-cache/src/server/main.js +1 -8
  122. package/out/zero-cache/src/server/main.js.map +1 -1
  123. package/out/zero-cache/src/server/mutator.js +0 -2
  124. package/out/zero-cache/src/server/mutator.js.map +1 -1
  125. package/out/zero-cache/src/server/reaper.d.ts.map +1 -1
  126. package/out/zero-cache/src/server/reaper.js +0 -2
  127. package/out/zero-cache/src/server/reaper.js.map +1 -1
  128. package/out/zero-cache/src/server/replicator.d.ts.map +1 -1
  129. package/out/zero-cache/src/server/replicator.js +2 -8
  130. package/out/zero-cache/src/server/replicator.js.map +1 -1
  131. package/out/zero-cache/src/server/runner/zero-dispatcher.d.ts.map +1 -1
  132. package/out/zero-cache/src/server/runner/zero-dispatcher.js +0 -3
  133. package/out/zero-cache/src/server/runner/zero-dispatcher.js.map +1 -1
  134. package/out/zero-cache/src/server/syncer.d.ts.map +1 -1
  135. package/out/zero-cache/src/server/syncer.js +0 -2
  136. package/out/zero-cache/src/server/syncer.js.map +1 -1
  137. package/out/zero-cache/src/services/analyze.d.ts.map +1 -1
  138. package/out/zero-cache/src/services/analyze.js +2 -3
  139. package/out/zero-cache/src/services/analyze.js.map +1 -1
  140. package/out/zero-cache/src/services/change-source/common/backfill-manager.d.ts.map +1 -1
  141. package/out/zero-cache/src/services/change-source/common/backfill-manager.js +1 -14
  142. package/out/zero-cache/src/services/change-source/common/backfill-manager.js.map +1 -1
  143. package/out/zero-cache/src/services/change-source/common/change-stream-multiplexer.d.ts.map +1 -1
  144. package/out/zero-cache/src/services/change-source/common/change-stream-multiplexer.js +3 -15
  145. package/out/zero-cache/src/services/change-source/common/change-stream-multiplexer.js.map +1 -1
  146. package/out/zero-cache/src/services/change-source/pg/change-source.d.ts +1 -11
  147. package/out/zero-cache/src/services/change-source/pg/change-source.d.ts.map +1 -1
  148. package/out/zero-cache/src/services/change-source/pg/change-source.js +2 -21
  149. package/out/zero-cache/src/services/change-source/pg/change-source.js.map +1 -1
  150. package/out/zero-cache/src/services/change-source/pg/initial-sync.d.ts +0 -1
  151. package/out/zero-cache/src/services/change-source/pg/initial-sync.d.ts.map +1 -1
  152. package/out/zero-cache/src/services/change-source/pg/initial-sync.js +7 -8
  153. package/out/zero-cache/src/services/change-source/pg/initial-sync.js.map +1 -1
  154. package/out/zero-cache/src/services/change-source/pg/schema/ddl.d.ts +229 -1513
  155. package/out/zero-cache/src/services/change-source/pg/schema/ddl.d.ts.map +1 -1
  156. package/out/zero-cache/src/services/change-source/pg/schema/ddl.js +2 -2
  157. package/out/zero-cache/src/services/change-source/pg/schema/ddl.js.map +1 -1
  158. package/out/zero-cache/src/services/change-source/pg/schema/init.d.ts +1 -1
  159. package/out/zero-cache/src/services/change-source/pg/schema/init.d.ts.map +1 -1
  160. package/out/zero-cache/src/services/change-source/pg/schema/init.js +6 -15
  161. package/out/zero-cache/src/services/change-source/pg/schema/init.js.map +1 -1
  162. package/out/zero-cache/src/services/change-source/pg/schema/published.d.ts +20 -137
  163. package/out/zero-cache/src/services/change-source/pg/schema/published.d.ts.map +1 -1
  164. package/out/zero-cache/src/services/change-source/pg/schema/published.js +13 -82
  165. package/out/zero-cache/src/services/change-source/pg/schema/published.js.map +1 -1
  166. package/out/zero-cache/src/services/change-source/pg/schema/shard.d.ts +21 -128
  167. package/out/zero-cache/src/services/change-source/pg/schema/shard.d.ts.map +1 -1
  168. package/out/zero-cache/src/services/change-source/pg/schema/shard.js +5 -5
  169. package/out/zero-cache/src/services/change-source/pg/schema/shard.js.map +1 -1
  170. package/out/zero-cache/src/services/change-source/protocol/current/data.d.ts +0 -2
  171. package/out/zero-cache/src/services/change-source/protocol/current/data.d.ts.map +1 -1
  172. package/out/zero-cache/src/services/change-source/protocol/current/downstream.d.ts +0 -3
  173. package/out/zero-cache/src/services/change-source/protocol/current/downstream.d.ts.map +1 -1
  174. package/out/zero-cache/src/services/change-streamer/change-streamer-http.d.ts +0 -3
  175. package/out/zero-cache/src/services/change-streamer/change-streamer-http.d.ts.map +1 -1
  176. package/out/zero-cache/src/services/change-streamer/change-streamer-http.js +1 -3
  177. package/out/zero-cache/src/services/change-streamer/change-streamer-http.js.map +1 -1
  178. package/out/zero-cache/src/services/change-streamer/change-streamer.d.ts +0 -1
  179. package/out/zero-cache/src/services/change-streamer/change-streamer.d.ts.map +1 -1
  180. package/out/zero-cache/src/services/litestream/commands.d.ts.map +1 -1
  181. package/out/zero-cache/src/services/litestream/commands.js +3 -8
  182. package/out/zero-cache/src/services/litestream/commands.js.map +1 -1
  183. package/out/zero-cache/src/services/litestream/config-v5.yml +1 -15
  184. package/out/zero-cache/src/services/mutagen/mutagen.d.ts +0 -5
  185. package/out/zero-cache/src/services/mutagen/mutagen.d.ts.map +1 -1
  186. package/out/zero-cache/src/services/mutagen/mutagen.js +1 -7
  187. package/out/zero-cache/src/services/mutagen/mutagen.js.map +1 -1
  188. package/out/zero-cache/src/services/mutagen/pusher.d.ts +87 -87
  189. package/out/zero-cache/src/services/mutagen/pusher.js +2 -3
  190. package/out/zero-cache/src/services/mutagen/pusher.js.map +1 -1
  191. package/out/zero-cache/src/services/replicator/change-processor.d.ts.map +1 -1
  192. package/out/zero-cache/src/services/replicator/change-processor.js +16 -16
  193. package/out/zero-cache/src/services/replicator/change-processor.js.map +1 -1
  194. package/out/zero-cache/src/services/replicator/incremental-sync.d.ts.map +1 -1
  195. package/out/zero-cache/src/services/replicator/incremental-sync.js +0 -1
  196. package/out/zero-cache/src/services/replicator/incremental-sync.js.map +1 -1
  197. package/out/zero-cache/src/services/replicator/write-worker-client.d.ts +2 -27
  198. package/out/zero-cache/src/services/replicator/write-worker-client.d.ts.map +1 -1
  199. package/out/zero-cache/src/services/replicator/write-worker-client.js +2 -3
  200. package/out/zero-cache/src/services/replicator/write-worker-client.js.map +1 -1
  201. package/out/zero-cache/src/services/replicator/write-worker.js +5 -24
  202. package/out/zero-cache/src/services/replicator/write-worker.js.map +1 -1
  203. package/out/zero-cache/src/services/run-ast.d.ts +0 -12
  204. package/out/zero-cache/src/services/run-ast.d.ts.map +1 -1
  205. package/out/zero-cache/src/services/run-ast.js +15 -27
  206. package/out/zero-cache/src/services/run-ast.js.map +1 -1
  207. package/out/zero-cache/src/services/runner.d.ts.map +1 -1
  208. package/out/zero-cache/src/services/runner.js +1 -1
  209. package/out/zero-cache/src/services/runner.js.map +1 -1
  210. package/out/zero-cache/src/services/view-syncer/cvr.d.ts +0 -45
  211. package/out/zero-cache/src/services/view-syncer/cvr.d.ts.map +1 -1
  212. package/out/zero-cache/src/services/view-syncer/cvr.js +1 -133
  213. package/out/zero-cache/src/services/view-syncer/cvr.js.map +1 -1
  214. package/out/zero-cache/src/services/view-syncer/drain-coordinator.d.ts +1 -14
  215. package/out/zero-cache/src/services/view-syncer/drain-coordinator.d.ts.map +1 -1
  216. package/out/zero-cache/src/services/view-syncer/drain-coordinator.js +4 -30
  217. package/out/zero-cache/src/services/view-syncer/drain-coordinator.js.map +1 -1
  218. package/out/zero-cache/src/services/view-syncer/inspect-handler.d.ts +1 -1
  219. package/out/zero-cache/src/services/view-syncer/inspect-handler.d.ts.map +1 -1
  220. package/out/zero-cache/src/services/view-syncer/inspect-handler.js +2 -2
  221. package/out/zero-cache/src/services/view-syncer/inspect-handler.js.map +1 -1
  222. package/out/zero-cache/src/services/view-syncer/pipeline-driver.d.ts +1 -2
  223. package/out/zero-cache/src/services/view-syncer/pipeline-driver.d.ts.map +1 -1
  224. package/out/zero-cache/src/services/view-syncer/pipeline-driver.js +18 -33
  225. package/out/zero-cache/src/services/view-syncer/pipeline-driver.js.map +1 -1
  226. package/out/zero-cache/src/services/view-syncer/query-covering.d.ts.map +1 -1
  227. package/out/zero-cache/src/services/view-syncer/query-covering.js.map +1 -1
  228. package/out/zero-cache/src/services/view-syncer/snapshotter.d.ts +1 -4
  229. package/out/zero-cache/src/services/view-syncer/snapshotter.d.ts.map +1 -1
  230. package/out/zero-cache/src/services/view-syncer/snapshotter.js +3 -9
  231. package/out/zero-cache/src/services/view-syncer/snapshotter.js.map +1 -1
  232. package/out/zero-cache/src/services/view-syncer/view-syncer.d.ts +1 -11
  233. package/out/zero-cache/src/services/view-syncer/view-syncer.d.ts.map +1 -1
  234. package/out/zero-cache/src/services/view-syncer/view-syncer.js +90 -470
  235. package/out/zero-cache/src/services/view-syncer/view-syncer.js.map +1 -1
  236. package/out/zero-cache/src/types/processes.d.ts +0 -32
  237. package/out/zero-cache/src/types/processes.d.ts.map +1 -1
  238. package/out/zero-cache/src/types/processes.js +4 -43
  239. package/out/zero-cache/src/types/processes.js.map +1 -1
  240. package/out/zero-cache/src/types/profiler.d.ts +0 -12
  241. package/out/zero-cache/src/types/profiler.d.ts.map +1 -1
  242. package/out/zero-cache/src/types/profiler.js +1 -46
  243. package/out/zero-cache/src/types/profiler.js.map +1 -1
  244. package/out/zero-cache/src/workers/connect-params.d.ts +17 -1
  245. package/out/zero-cache/src/workers/connect-params.d.ts.map +1 -1
  246. package/out/zero-cache/src/workers/connect-params.js +21 -1
  247. package/out/zero-cache/src/workers/connect-params.js.map +1 -1
  248. package/out/zero-cache/src/workers/connection.d.ts +4 -4
  249. package/out/zero-cache/src/workers/connection.d.ts.map +1 -1
  250. package/out/zero-cache/src/workers/connection.js +8 -8
  251. package/out/zero-cache/src/workers/connection.js.map +1 -1
  252. package/out/zero-cache/src/workers/replicator.d.ts +0 -1
  253. package/out/zero-cache/src/workers/replicator.d.ts.map +1 -1
  254. package/out/zero-cache/src/workers/replicator.js +2 -4
  255. package/out/zero-cache/src/workers/replicator.js.map +1 -1
  256. package/out/zero-cache/src/workers/syncer-ws-message-handler.d.ts.map +1 -1
  257. package/out/zero-cache/src/workers/syncer-ws-message-handler.js +16 -21
  258. package/out/zero-cache/src/workers/syncer-ws-message-handler.js.map +1 -1
  259. package/out/zero-cache/src/workers/syncer.d.ts.map +1 -1
  260. package/out/zero-cache/src/workers/syncer.js +1 -10
  261. package/out/zero-cache/src/workers/syncer.js.map +1 -1
  262. package/out/zero-client/src/client/connection-manager.d.ts +0 -20
  263. package/out/zero-client/src/client/connection-manager.d.ts.map +1 -1
  264. package/out/zero-client/src/client/connection-manager.js +13 -77
  265. package/out/zero-client/src/client/connection-manager.js.map +1 -1
  266. package/out/zero-client/src/client/connection-status-enum.d.ts +0 -2
  267. package/out/zero-client/src/client/connection-status-enum.d.ts.map +1 -1
  268. package/out/zero-client/src/client/connection-status-enum.js +1 -3
  269. package/out/zero-client/src/client/connection-status-enum.js.map +1 -1
  270. package/out/zero-client/src/client/connection.d.ts +0 -6
  271. package/out/zero-client/src/client/connection.d.ts.map +1 -1
  272. package/out/zero-client/src/client/connection.js +1 -2
  273. package/out/zero-client/src/client/connection.js.map +1 -1
  274. package/out/zero-client/src/client/context.d.ts +2 -27
  275. package/out/zero-client/src/client/context.d.ts.map +1 -1
  276. package/out/zero-client/src/client/context.js +1 -112
  277. package/out/zero-client/src/client/context.js.map +1 -1
  278. package/out/zero-client/src/client/custom.js +2 -2
  279. package/out/zero-client/src/client/custom.js.map +1 -1
  280. package/out/zero-client/src/client/error.js +1 -1
  281. package/out/zero-client/src/client/inspector/lazy-inspector.js +2 -2
  282. package/out/zero-client/src/client/inspector/lazy-inspector.js.map +1 -1
  283. package/out/zero-client/src/client/ivm-branch.d.ts.map +1 -1
  284. package/out/zero-client/src/client/ivm-branch.js +3 -20
  285. package/out/zero-client/src/client/ivm-branch.js.map +1 -1
  286. package/out/zero-client/src/client/mutation-tracker.d.ts.map +1 -1
  287. package/out/zero-client/src/client/mutation-tracker.js +1 -1
  288. package/out/zero-client/src/client/mutation-tracker.js.map +1 -1
  289. package/out/zero-client/src/client/mutator-proxy.d.ts.map +1 -1
  290. package/out/zero-client/src/client/mutator-proxy.js +1 -2
  291. package/out/zero-client/src/client/mutator-proxy.js.map +1 -1
  292. package/out/zero-client/src/client/options.d.ts +0 -3
  293. package/out/zero-client/src/client/options.d.ts.map +1 -1
  294. package/out/zero-client/src/client/options.js.map +1 -1
  295. package/out/zero-client/src/client/query-manager.d.ts +0 -2
  296. package/out/zero-client/src/client/query-manager.d.ts.map +1 -1
  297. package/out/zero-client/src/client/query-manager.js +9 -48
  298. package/out/zero-client/src/client/query-manager.js.map +1 -1
  299. package/out/zero-client/src/client/version.js +1 -1
  300. package/out/zero-client/src/client/zero-rep.d.ts +0 -1
  301. package/out/zero-client/src/client/zero-rep.d.ts.map +1 -1
  302. package/out/zero-client/src/client/zero-rep.js +6 -9
  303. package/out/zero-client/src/client/zero-rep.js.map +1 -1
  304. package/out/zero-client/src/client/zero.d.ts +3 -18
  305. package/out/zero-client/src/client/zero.d.ts.map +1 -1
  306. package/out/zero-client/src/client/zero.js +36 -123
  307. package/out/zero-client/src/client/zero.js.map +1 -1
  308. package/out/zero-client/src/types/query-result.d.ts +0 -2
  309. package/out/zero-client/src/types/query-result.d.ts.map +1 -1
  310. package/out/zero-protocol/src/ast.d.ts +1 -64
  311. package/out/zero-protocol/src/ast.d.ts.map +1 -1
  312. package/out/zero-protocol/src/ast.js +51 -223
  313. package/out/zero-protocol/src/ast.js.map +1 -1
  314. package/out/zero-protocol/src/connect.d.ts +16 -0
  315. package/out/zero-protocol/src/connect.d.ts.map +1 -1
  316. package/out/zero-protocol/src/connect.js +27 -1
  317. package/out/zero-protocol/src/connect.js.map +1 -1
  318. package/out/zero-protocol/src/error.d.ts +1 -1
  319. package/out/zero-protocol/src/feature-flag-enum.d.ts +7 -0
  320. package/out/zero-protocol/src/feature-flag-enum.d.ts.map +1 -0
  321. package/out/zero-protocol/src/feature-flag-enum.js +7 -0
  322. package/out/zero-protocol/src/feature-flag-enum.js.map +1 -0
  323. package/out/zero-protocol/src/feature-flag.d.ts +5 -0
  324. package/out/zero-protocol/src/feature-flag.d.ts.map +1 -0
  325. package/out/zero-protocol/src/poke.d.ts +11 -4
  326. package/out/zero-protocol/src/poke.d.ts.map +1 -1
  327. package/out/zero-protocol/src/poke.js +3 -2
  328. package/out/zero-protocol/src/poke.js.map +1 -1
  329. package/out/zero-protocol/src/protocol-version.d.ts +30 -6
  330. package/out/zero-protocol/src/protocol-version.d.ts.map +1 -1
  331. package/out/zero-protocol/src/protocol-version.js +1 -1
  332. package/out/zero-protocol/src/protocol-version.js.map +1 -1
  333. package/out/zero-protocol/src/query-hash.d.ts +2 -7
  334. package/out/zero-protocol/src/query-hash.d.ts.map +1 -1
  335. package/out/zero-protocol/src/query-hash.js +9 -12
  336. package/out/zero-protocol/src/query-hash.js.map +1 -1
  337. package/out/zero-react/src/use-query.d.ts +4 -5
  338. package/out/zero-react/src/use-query.d.ts.map +1 -1
  339. package/out/zero-react/src/use-query.js +9 -86
  340. package/out/zero-react/src/use-query.js.map +1 -1
  341. package/out/zero-solid/src/solid-view.d.ts +0 -17
  342. package/out/zero-solid/src/solid-view.d.ts.map +1 -1
  343. package/out/zero-solid/src/solid-view.js +1 -39
  344. package/out/zero-solid/src/solid-view.js.map +1 -1
  345. package/out/zero-solid/src/use-query.js +3 -5
  346. package/out/zero-solid/src/use-query.js.map +1 -1
  347. package/out/zql/src/builder/debug-delegate.d.ts +1 -6
  348. package/out/zql/src/builder/debug-delegate.d.ts.map +1 -1
  349. package/out/zql/src/builder/debug-delegate.js +2 -14
  350. package/out/zql/src/builder/debug-delegate.js.map +1 -1
  351. package/out/zql/src/ivm/array-view.d.ts +0 -29
  352. package/out/zql/src/ivm/array-view.d.ts.map +1 -1
  353. package/out/zql/src/ivm/array-view.js +12 -63
  354. package/out/zql/src/ivm/array-view.js.map +1 -1
  355. package/out/zql/src/ivm/cap.d.ts.map +1 -1
  356. package/out/zql/src/ivm/cap.js +3 -5
  357. package/out/zql/src/ivm/cap.js.map +1 -1
  358. package/out/zql/src/ivm/data.d.ts.map +1 -1
  359. package/out/zql/src/ivm/data.js +3 -8
  360. package/out/zql/src/ivm/data.js.map +1 -1
  361. package/out/zql/src/ivm/exists.d.ts +1 -1
  362. package/out/zql/src/ivm/exists.d.ts.map +1 -1
  363. package/out/zql/src/ivm/exists.js +1 -1
  364. package/out/zql/src/ivm/exists.js.map +1 -1
  365. package/out/zql/src/ivm/fan-in.d.ts +2 -2
  366. package/out/zql/src/ivm/fan-in.d.ts.map +1 -1
  367. package/out/zql/src/ivm/fan-in.js +5 -6
  368. package/out/zql/src/ivm/fan-in.js.map +1 -1
  369. package/out/zql/src/ivm/fan-out.d.ts +2 -2
  370. package/out/zql/src/ivm/fan-out.d.ts.map +1 -1
  371. package/out/zql/src/ivm/fan-out.js.map +1 -1
  372. package/out/zql/src/ivm/filter-operators.d.ts +4 -4
  373. package/out/zql/src/ivm/filter-operators.d.ts.map +1 -1
  374. package/out/zql/src/ivm/filter-operators.js +8 -10
  375. package/out/zql/src/ivm/filter-operators.js.map +1 -1
  376. package/out/zql/src/ivm/filter.d.ts +2 -2
  377. package/out/zql/src/ivm/filter.d.ts.map +1 -1
  378. package/out/zql/src/ivm/filter.js +4 -7
  379. package/out/zql/src/ivm/filter.js.map +1 -1
  380. package/out/zql/src/ivm/flipped-join.js +2 -2
  381. package/out/zql/src/ivm/flipped-join.js.map +1 -1
  382. package/out/zql/src/ivm/maybe-split-and-push-edit-change.d.ts +1 -1
  383. package/out/zql/src/ivm/maybe-split-and-push-edit-change.d.ts.map +1 -1
  384. package/out/zql/src/ivm/maybe-split-and-push-edit-change.js +4 -6
  385. package/out/zql/src/ivm/maybe-split-and-push-edit-change.js.map +1 -1
  386. package/out/zql/src/ivm/memory-source.d.ts +3 -15
  387. package/out/zql/src/ivm/memory-source.d.ts.map +1 -1
  388. package/out/zql/src/ivm/memory-source.js +19 -40
  389. package/out/zql/src/ivm/memory-source.js.map +1 -1
  390. package/out/zql/src/ivm/take.d.ts.map +1 -1
  391. package/out/zql/src/ivm/take.js +4 -3
  392. package/out/zql/src/ivm/take.js.map +1 -1
  393. package/out/zql/src/ivm/union-fan-in.d.ts.map +1 -1
  394. package/out/zql/src/ivm/union-fan-in.js +7 -9
  395. package/out/zql/src/ivm/union-fan-in.js.map +1 -1
  396. package/out/zql/src/ivm/view-apply-change.d.ts.map +1 -1
  397. package/out/zql/src/ivm/view-apply-change.js +4 -9
  398. package/out/zql/src/ivm/view-apply-change.js.map +1 -1
  399. package/out/zql/src/ivm/view.d.ts +0 -15
  400. package/out/zql/src/ivm/view.d.ts.map +1 -1
  401. package/out/zql/src/mutate/mutator-registry.d.ts.map +1 -1
  402. package/out/zql/src/mutate/mutator-registry.js +2 -2
  403. package/out/zql/src/mutate/mutator-registry.js.map +1 -1
  404. package/out/zql/src/query/query-delegate-base.d.ts +1 -9
  405. package/out/zql/src/query/query-delegate-base.d.ts.map +1 -1
  406. package/out/zql/src/query/query-delegate-base.js +36 -132
  407. package/out/zql/src/query/query-delegate-base.js.map +1 -1
  408. package/out/zql/src/query/query-delegate.d.ts +1 -50
  409. package/out/zql/src/query/query-delegate.d.ts.map +1 -1
  410. package/out/zql/src/query/query-impl.d.ts +14 -25
  411. package/out/zql/src/query/query-impl.d.ts.map +1 -1
  412. package/out/zql/src/query/query-impl.js +94 -414
  413. package/out/zql/src/query/query-impl.js.map +1 -1
  414. package/out/zql/src/query/query-internals.d.ts +11 -21
  415. package/out/zql/src/query/query-internals.d.ts.map +1 -1
  416. package/out/zql/src/query/query-internals.js.map +1 -1
  417. package/out/zql/src/query/query.d.ts +2 -11
  418. package/out/zql/src/query/query.d.ts.map +1 -1
  419. package/out/zql/src/query/runnable-query-impl.d.ts +2 -3
  420. package/out/zql/src/query/runnable-query-impl.d.ts.map +1 -1
  421. package/out/zql/src/query/runnable-query-impl.js +2 -23
  422. package/out/zql/src/query/runnable-query-impl.js.map +1 -1
  423. package/out/zql/src/query/typed-view.d.ts +1 -1
  424. package/out/zql/src/query/typed-view.d.ts.map +1 -1
  425. package/out/zqlite/src/db.d.ts +1 -9
  426. package/out/zqlite/src/db.d.ts.map +1 -1
  427. package/out/zqlite/src/db.js +2 -8
  428. package/out/zqlite/src/db.js.map +1 -1
  429. package/out/zqlite/src/query-builder.d.ts.map +1 -1
  430. package/out/zqlite/src/query-builder.js +1 -2
  431. package/out/zqlite/src/query-builder.js.map +1 -1
  432. package/out/zqlite/src/sqlite-stat-fanout.d.ts.map +1 -1
  433. package/out/zqlite/src/sqlite-stat-fanout.js +0 -1
  434. package/out/zqlite/src/sqlite-stat-fanout.js.map +1 -1
  435. package/out/zqlite/src/table-source.d.ts +1 -2
  436. package/out/zqlite/src/table-source.d.ts.map +1 -1
  437. package/out/zqlite/src/table-source.js +6 -12
  438. package/out/zqlite/src/table-source.js.map +1 -1
  439. package/package.json +3 -2
  440. package/out/replicache/src/dag/invalid-ref-count-error.d.ts +0 -12
  441. package/out/replicache/src/dag/invalid-ref-count-error.d.ts.map +0 -1
  442. package/out/replicache/src/dag/invalid-ref-count-error.js +0 -19
  443. package/out/replicache/src/dag/invalid-ref-count-error.js.map +0 -1
  444. package/out/shared/src/xxhash32.d.ts +0 -36
  445. package/out/shared/src/xxhash32.d.ts.map +0 -1
  446. package/out/shared/src/xxhash32.js +0 -51
  447. package/out/shared/src/xxhash32.js.map +0 -1
  448. package/out/zero-cache/src/db/index-predicate.d.ts +0 -4
  449. package/out/zero-cache/src/db/index-predicate.d.ts.map +0 -1
  450. package/out/zero-cache/src/db/index-predicate.js +0 -46
  451. package/out/zero-cache/src/db/index-predicate.js.map +0 -1
  452. package/out/zero-cache/src/services/change-source/pg/schema/index-predicate.d.ts +0 -19
  453. package/out/zero-cache/src/services/change-source/pg/schema/index-predicate.d.ts.map +0 -1
  454. package/out/zero-cache/src/services/change-source/pg/schema/index-predicate.js +0 -581
  455. package/out/zero-cache/src/services/change-source/pg/schema/index-predicate.js.map +0 -1
  456. package/out/zero-cache/src/services/litestream/litestream-checkpointer.js +0 -131
  457. package/out/zero-cache/src/services/litestream/litestream-checkpointer.js.map +0 -1
  458. package/out/zero-cache/src/services/litestream/litestream-controller.d.ts +0 -70
  459. package/out/zero-cache/src/services/litestream/litestream-controller.d.ts.map +0 -1
  460. package/out/zero-cache/src/services/litestream/litestream-controller.js +0 -101
  461. package/out/zero-cache/src/services/litestream/litestream-controller.js.map +0 -1
  462. package/out/zero-cache/src/services/profz.d.ts +0 -7
  463. package/out/zero-cache/src/services/profz.d.ts.map +0 -1
  464. package/out/zero-cache/src/services/profz.js +0 -103
  465. package/out/zero-cache/src/services/profz.js.map +0 -1
  466. package/out/zero-cache/src/services/view-syncer/hydration-budget.d.ts +0 -33
  467. package/out/zero-cache/src/services/view-syncer/hydration-budget.d.ts.map +0 -1
  468. package/out/zero-cache/src/services/view-syncer/hydration-budget.js +0 -62
  469. package/out/zero-cache/src/services/view-syncer/hydration-budget.js.map +0 -1
  470. package/out/zero-cache/src/services/view-syncer/hydration-circuit-breaker.d.ts +0 -51
  471. package/out/zero-cache/src/services/view-syncer/hydration-circuit-breaker.d.ts.map +0 -1
  472. package/out/zero-cache/src/services/view-syncer/hydration-circuit-breaker.js +0 -78
  473. package/out/zero-cache/src/services/view-syncer/hydration-circuit-breaker.js.map +0 -1
  474. package/out/zero-protocol/src/query-hash-visitor.d.ts +0 -81
  475. package/out/zero-protocol/src/query-hash-visitor.d.ts.map +0 -1
  476. package/out/zero-protocol/src/query-hash-visitor.js +0 -324
  477. package/out/zero-protocol/src/query-hash-visitor.js.map +0 -1
  478. package/out/zql/src/ivm/deferred-input.d.ts +0 -44
  479. package/out/zql/src/ivm/deferred-input.d.ts.map +0 -1
  480. package/out/zql/src/ivm/deferred-input.js +0 -89
  481. package/out/zql/src/ivm/deferred-input.js.map +0 -1
  482. package/out/zql/src/query/query-transitions.d.ts +0 -171
  483. package/out/zql/src/query/query-transitions.d.ts.map +0 -1
  484. package/out/zql/src/query/query-transitions.js +0 -207
  485. package/out/zql/src/query/query-transitions.js.map +0 -1
@@ -9,10 +9,10 @@ var idSymbol = Symbol("id");
9
9
  /**
10
10
  * Get child nodes from a relationship, handling both lazy (Node) and expanded (ExpandedNode).
11
11
  */
12
- function getChildNodes(node, relationship) {
12
+ function* getChildNodes(node, relationship) {
13
13
  const children = node.relationships[relationship];
14
- if (Array.isArray(children)) return children;
15
- return skipYields(children());
14
+ if (Array.isArray(children)) yield* children;
15
+ else yield* skipYields(children());
16
16
  }
17
17
  /**
18
18
  * Transaction-scoped copy-on-write.
@@ -279,13 +279,8 @@ function removeAndUpdateRefCount(view, row, compareRows, mutate) {
279
279
  * Recover insertion point with `~result`.
280
280
  */
281
281
  function binarySearch(view, target, comparator) {
282
- let high = view.length - 1;
283
- if (high < 0) return -1;
284
- const last = comparator(view[high], target);
285
- if (last < 0) return ~(high + 1);
286
- if (last === 0) return high;
287
282
  let low = 0;
288
- high -= 1;
283
+ let high = view.length - 1;
289
284
  while (low <= high) {
290
285
  const mid = low + high >>> 1;
291
286
  const comparison = comparator(view[mid], target);
@@ -1 +1 @@
1
- {"version":3,"file":"view-apply-change.js","names":[],"sources":["../../../../../zql/src/ivm/view-apply-change.ts"],"sourcesContent":["import {\n assert,\n assertArray,\n assertNumber,\n unreachable,\n} from '../../../shared/src/asserts.ts';\nimport {must} from '../../../shared/src/must.ts';\nimport {assignProperty} from '../../../shared/src/objects.ts';\nimport type {Writable} from '../../../shared/src/writable.ts';\nimport type {Row} from '../../../zero-protocol/src/data.ts';\nimport {type Comparator, type Node} from './data.ts';\nimport {skipYields} from './operator.ts';\nimport type {SourceSchema} from './schema.ts';\nimport type {Entry, Format} from './view.ts';\n\nexport const refCountSymbol = Symbol('rc');\nexport const idSymbol = Symbol('id');\n\ntype ReadonlyMetaEntry = Entry & {\n readonly [refCountSymbol]: number;\n readonly [idSymbol]?: string | undefined;\n};\n\ntype MutableMetaEntry = Writable<ReadonlyMetaEntry>;\n\n/**\n * MetaEntry is an Entry with internal tracking fields for reference counting\n * and stable identity. All entries in the view tree are MetaEntry instances,\n * created through makeNewMetaEntry().\n */\ntype MetaEntry<M extends Mutate> = M extends true\n ? MutableMetaEntry\n : ReadonlyMetaEntry;\n\ntype MutableArray<M extends Mutate, T> = M extends true ? T[] : readonly T[];\n\ntype MetaEntryList<M extends Mutate> = MutableArray<M, MetaEntry<M>>;\n\ntype MutableMetaEntryList = MutableMetaEntry[];\n\n/**\n * Node with eagerly-expanded relationships (arrays instead of generators).\n * Used when batching changes to capture source state at push time.\n */\nexport type ExpandedNode = {\n row: Row;\n relationships: Record<string, ExpandedNode[]>;\n};\n\n/**\n * A node for view changes. Can be either:\n * - A lazy Node with generator relationships (original behavior)\n * - An ExpandedNode with pre-computed relationship arrays (for batching)\n */\nexport type ViewNode = Node | ExpandedNode;\n\n/**\n * `applyChange` does not consume the `relationships` of `ChildChange#node`,\n * `EditChange#node` and `EditChange#oldNode`. The `ViewChange` type\n * documents and enforces this via the type system.\n */\nexport type ViewChange =\n | AddViewChange\n | RemoveViewChange\n | ChildViewChange\n | EditViewChange;\n\nexport type RowOnlyNode = {row: Row};\n\nexport type AddViewChange = {\n type: 'add';\n node: ViewNode;\n};\n\nexport type RemoveViewChange = {\n type: 'remove';\n node: ViewNode;\n};\n\ntype ChildViewChange = {\n type: 'child';\n node: RowOnlyNode;\n child: {\n relationshipName: string;\n change: ViewChange;\n };\n};\n\ntype EditViewChange = {\n type: 'edit';\n node: RowOnlyNode;\n oldNode: RowOnlyNode;\n};\n\n/**\n * This is a subset of WeakMap but restricted to what we need.\n * @deprecated Not used anymore. This will be removed in the future.\n */\nexport interface RefCountMap {\n get(entry: Entry): number | undefined;\n set(entry: Entry, refCount: number): void;\n delete(entry: Entry): boolean;\n}\n\n/**\n * Get child nodes from a relationship, handling both lazy (Node) and expanded (ExpandedNode).\n */\nfunction getChildNodes(\n node: ViewNode,\n relationship: string,\n): Iterable<ViewNode> {\n const children = node.relationships[relationship];\n if (Array.isArray(children)) {\n // ExpandedNode: already an array\n return children;\n }\n // Node: lazy generator function\n return skipYields(children());\n}\n\ntype Mutate = boolean;\ntype WithIDs = boolean;\n\n/**\n * Transaction-scoped copy-on-write.\n *\n * `applyChange` is immutable: it path-copies a new spine on every call so the\n * previously-emitted snapshot is never mutated. But within a single transaction\n * (a run of `push()` calls before `flush()`) only the final state is ever\n * observed by a listener, so the intermediate spines are pure allocation/GC\n * churn — making a K-change transaction O(K * spineSize).\n *\n * When the caller passes a WeakSet as the `mutate` argument, objects and arrays\n * that were created or cloned during the current transaction are recorded in it.\n * A helper that needs to modify such an object mutates it in place (it is not\n * yet observed) instead of cloning again. The first touch of a node still\n * copies-on-write (preserving the committed snapshot's references); subsequent\n * touches in the same transaction are in-place. This brings a K-change\n * transaction to O(spineSize + K) while keeping cross-transaction reference\n * stability.\n *\n * The set is module-scoped for the duration of a single (synchronous,\n * non-re-entrant) `applyChange` call and saved/restored around it.\n *\n * It is a WeakSet on purpose: it must not keep transiently-cloned arrays/entries\n * alive. A strong Set would extend their lifetime to the end of the transaction,\n * pushing large clones out of the young generation and adding GC pressure that\n * shows up as a regression on single-change transactions over wide lists. A\n * WeakSet gives the same identity test (\"created this transaction?\") while\n * letting dead clones be collected as cheaply as in the plain immutable path.\n */\nlet activeDirty: WeakSet<object> | undefined;\n\n/** True if `o` was created/cloned during the current transaction. */\nfunction owns(o: object): boolean {\n return activeDirty !== undefined && activeDirty.has(o);\n}\n\n/** Record `o` as owned by the current transaction (no-op outside a txn). */\nfunction track<T extends object>(o: T): T {\n activeDirty?.add(o);\n return o;\n}\n\n/**\n * Immutable view update. Returns new Entry on change, same Entry if unchanged.\n * Unchanged entries keep identity, enabling shallow comparison optimizations\n * in UI frameworks (React.memo, Solid's fine-grained reactivity, etc).\n *\n * Propagation: recurse DOWN to find target, copy objects on the way UP.\n * Siblings keep original refs. Only the ancestor path is copied.\n *\n * root {users:[A,B], items:[C,D,E]} --edit C--> root' {users:[A,B], items':[C',D,E]}\n * │ same ref │ │ │\n * └─────────────────┴── unchanged ──────────────┘ new array C' new, D/E same\n *\n * `mutate` selects the update strategy:\n * - `false` (default): fully immutable; every changed node is path-copied.\n * - `true`: mutate the tree in place (only safe when it is not yet observed,\n * e.g. during initial hydration).\n * - a `WeakSet`: transaction-scoped copy-on-write — copy on first touch, then\n * mutate in place for the rest of the transaction. See `activeDirty` above.\n */\nexport function applyChange(\n parentEntry: Entry,\n change: ViewChange,\n schema: SourceSchema,\n relationship: string,\n format: Format,\n withIDs = false,\n mutate: boolean | WeakSet<object> = false,\n): Entry {\n // A WeakSet selects copy-on-write; a boolean selects full mutate / immutable.\n const inPlace = mutate === true;\n const prevDirty = activeDirty;\n activeDirty = typeof mutate === 'object' ? mutate : undefined;\n try {\n return applyChangeInternal(\n parentEntry as MetaEntry<typeof inPlace>,\n change,\n schema,\n relationship,\n format,\n withIDs,\n inPlace,\n );\n } finally {\n activeDirty = prevDirty;\n }\n}\n\nexport function applyChangeInternal<M extends Mutate>(\n parentEntry: MetaEntry<M>,\n change: ViewChange,\n schema: SourceSchema,\n relationship: string,\n format: Format,\n withIDs: WithIDs,\n mutate: M,\n): MetaEntry<M> {\n if (schema.isHidden) {\n switch (change.type) {\n case 'add':\n case 'remove': {\n let currentParent = parentEntry;\n for (const relationship of Object.keys(change.node.relationships)) {\n const childSchema = must(schema.relationships[relationship]);\n for (const node of getChildNodes(change.node, relationship)) {\n currentParent = applyChangeInternal(\n currentParent,\n {type: change.type, node},\n childSchema,\n relationship,\n format,\n withIDs,\n mutate,\n );\n }\n }\n return currentParent;\n }\n case 'edit':\n // If hidden at this level it means that the hidden row was changed. If\n // the row was changed in such a way that it would change the\n // relationships then the edit would have been split into remove and\n // add.\n return parentEntry;\n case 'child': {\n const childSchema = must(\n schema.relationships[change.child.relationshipName],\n );\n return applyChangeInternal(\n parentEntry,\n change.child.change,\n childSchema,\n relationship,\n format,\n withIDs,\n mutate,\n );\n }\n default:\n unreachable(change);\n }\n }\n\n const {singular, relationships: childFormats} = format;\n switch (change.type) {\n // ADD: Insert row (rc=1) or increment refCount if duplicate.\n // RefCount tracks when the same row is reachable via multiple edges\n // within a relationship:\n //\n // issue.labels: [L1, L2] both point to same creator\n // │ │ │\n // ▼ ▼ ▼\n // label.creator ──────────► [User:rc=2] (one row, two refs)\n //\n // add(A) add(A) remove(A) remove(A)\n // ↓ ↓ ↓ ↓\n // [A:rc=1] → [A:rc=2] → [A:rc=1] → (deleted)\n case 'add': {\n if (singular) {\n const oldEntry = getOptionalSingularEntry(parentEntry, relationship);\n if (oldEntry !== undefined) {\n // Duplicate add: increment refCount\n assert(\n schema.compareRows(oldEntry, change.node.row) === 0,\n `Singular relationship '${relationship}' should not have multiple rows. You may need to declare this relationship with the \\`many\\` helper instead of the \\`one\\` helper in your schema.`,\n );\n\n const newEntry = incRefCount(mutate, oldEntry);\n return setRelation(mutate, parentEntry, relationship, newEntry);\n } else {\n // New row: create with rc=1, initialize nested relationships\n const newEntry = makeNewMetaEntry(\n change.node.row,\n schema,\n withIDs,\n 1,\n );\n initializeRelationshipsForNewEntryIfAny(\n newEntry,\n change.node,\n schema,\n childFormats,\n withIDs,\n );\n return setRelation(mutate, parentEntry, relationship, newEntry);\n }\n } else {\n // Plural: binary search for position, insert or increment refCount\n const view = getChildEntryList(parentEntry, relationship);\n const {newEntry, newView} = add(\n change.node.row,\n view,\n schema,\n withIDs,\n mutate,\n );\n\n if (newEntry) {\n initializeRelationshipsForNewEntryIfAny(\n newEntry,\n change.node,\n schema,\n childFormats,\n withIDs,\n );\n }\n return setRelation(mutate, parentEntry, relationship, newView);\n }\n }\n // REMOVE: Decrement refCount, physically remove when rc=0.\n case 'remove': {\n if (singular) {\n const oldEntry = getSingularEntry(parentEntry, relationship);\n const rc = oldEntry[refCountSymbol];\n if (rc === 1) {\n return setRelation(mutate, parentEntry, relationship, undefined);\n }\n const newEntry = decRefCount(mutate, oldEntry);\n return setRelation(mutate, parentEntry, relationship, newEntry);\n } else {\n const view = getChildEntryList(parentEntry, relationship);\n const newView = removeAndUpdateRefCount(\n view,\n change.node.row,\n schema.compareRows,\n mutate,\n );\n return setRelation(mutate, parentEntry, relationship, newView);\n }\n }\n // CHILD: Propagate nested change up to this level (leaf-to-root pattern).\n case 'child': {\n const childSchema = must(\n schema.relationships[change.child.relationshipName],\n );\n const childFormat = format.relationships[change.child.relationshipName];\n if (childFormat === undefined) {\n return parentEntry; // Relationship not in view format\n }\n\n if (singular) {\n const existing = getSingularEntry(parentEntry, relationship);\n const newExisting = applyChangeInternal(\n existing,\n change.child.change,\n childSchema,\n change.child.relationshipName,\n childFormat,\n withIDs,\n mutate,\n );\n // Preserve identity if child didn't change (enables shallow-compare optimizations).\n if (newExisting === existing) {\n return parentEntry;\n }\n return setRelation(mutate, parentEntry, relationship, newExisting);\n } else {\n // Find the target row in the sorted array via binary search.\n const view = getChildEntryList(parentEntry, relationship);\n const pos = binarySearch(view, change.node.row, schema.compareRows);\n assert(pos >= 0, 'node does not exist');\n const existing = view[pos];\n const newExisting = applyChangeInternal(\n existing,\n change.child.change,\n childSchema,\n change.child.relationshipName,\n childFormat,\n withIDs,\n mutate,\n );\n // Preserve identity if descendant didn't change.\n if (newExisting === existing) {\n return parentEntry;\n }\n // applyChangeInternal preserves MetaEntry structure when input is MetaEntry\n assertMetaEntry(newExisting);\n return setRelation(\n mutate,\n parentEntry,\n relationship,\n arrayWith(mutate, view, pos, newExisting),\n );\n }\n }\n // EDIT: Update row fields. If sort key changes, row may move position.\n //\n // Position change with rc>1 (two query paths reach same row):\n //\n // Before: [A, B(rc=2), C, D] After: [A, B(rc=1), C, B'(rc=1), D]\n // │ │ │\n // path1 + path2 path1 ghost path2 moved\n //\n // Why ghost stays: path1 still expects B at old position.\n // B' appears where path2's sort order places it.\n case 'edit': {\n if (singular) {\n const existing = getSingularEntry(parentEntry, relationship);\n const newEntry = applyEdit(existing, change, schema, withIDs, mutate);\n return setRelation(mutate, parentEntry, relationship, newEntry);\n } else {\n const view = getChildEntryList(parentEntry, relationship);\n // Sort key changed: row may need to move\n if (schema.compareRows(change.oldNode.row, change.node.row) !== 0) {\n const oldPos = binarySearch(\n view,\n change.oldNode.row,\n schema.compareRows,\n );\n assert(oldPos >= 0, 'old node does not exist');\n const oldEntry = view[oldPos];\n const rawPos = binarySearch(\n view,\n change.node.row,\n schema.compareRows,\n );\n const found = rawPos >= 0;\n const pos = found ? rawPos : ~rawPos;\n // A special case:\n // when refCount is 1 (so the row is being moved without leaving a\n // placeholder behind), and the new pos is the same as the old, or\n // directly after the old (so after the remove of the old it would be\n // in the same pos): the row does not need to be moved, just edited.\n if (\n oldEntry[refCountSymbol] === 1 &&\n (pos === oldPos || pos - 1 === oldPos)\n ) {\n const newEntry = applyEdit(\n oldEntry,\n change,\n schema,\n withIDs,\n mutate,\n );\n return setRelation(\n mutate,\n parentEntry,\n relationship,\n arrayWith(mutate, view, oldPos, newEntry),\n );\n } else {\n // Move the row. If rc > 1, an edit will be received for each ref.\n // On first edit: move row, apply edit, set rc=1. Leave a copy at\n // old pos with decremented rc. As each edit arrives, old copy's rc\n // decrements and new pos rc increments. When copy rc hits 0, remove.\n const newRefCount = oldEntry[refCountSymbol] - 1;\n let newView: MutableMetaEntryList;\n let adjustedPos = pos;\n\n if (newRefCount === 0) {\n newView = removeAt(mutate, view, oldPos);\n adjustedPos = oldPos < pos ? pos - 1 : pos;\n } else {\n const oldEntryCopy = setRefCount(mutate, oldEntry, newRefCount);\n newView = arrayWith(mutate, view, oldPos, oldEntryCopy);\n }\n\n if (found) {\n // Merge with existing at new pos\n const existingEntry = newView[adjustedPos];\n const editedEntry = applyEdit(\n existingEntry,\n change,\n schema,\n withIDs,\n mutate,\n );\n const updatedEntry = setRefCount(\n mutate,\n editedEntry,\n existingEntry[refCountSymbol] + 1,\n );\n return setRelation(\n mutate,\n parentEntry,\n relationship,\n arrayWith(mutate, newView, adjustedPos, updatedEntry),\n );\n } else {\n // Insert at new pos with rc=1\n const editedEntry = applyEdit(\n oldEntry,\n change,\n schema,\n withIDs,\n mutate,\n );\n const movedEntry = setRefCount(mutate, editedEntry, 1);\n return setRelation(\n mutate,\n parentEntry,\n relationship,\n insertAt(mutate, newView, adjustedPos, movedEntry),\n );\n }\n }\n } else {\n // Sort key unchanged: edit in place\n const pos = binarySearch(\n view,\n change.oldNode.row,\n schema.compareRows,\n );\n assert(pos >= 0, 'node does not exist');\n const newEntry = applyEdit(\n view[pos],\n change,\n schema,\n withIDs,\n mutate,\n );\n return setRelation(\n mutate,\n parentEntry,\n relationship,\n arrayWith(mutate, view, pos, newEntry),\n );\n }\n }\n }\n default:\n unreachable(change);\n }\n}\n\n/**\n * Batch apply multiple changes to an Entry tree.\n * For small batches or complex cases, falls back to sequential applyChange.\n * Future optimization: O(N + K) batch processing for large K.\n */\nexport function applyChanges(\n parentEntry: Entry,\n changes: ViewChange[],\n schema: SourceSchema,\n relationship: string,\n format: Format,\n withIDs: WithIDs = false,\n mutate: Mutate = false,\n): Entry {\n let result = parentEntry;\n for (const change of changes) {\n result = applyChange(\n result,\n change,\n schema,\n relationship,\n format,\n withIDs,\n mutate,\n );\n }\n return result;\n}\n\nfunction applyEdit<M extends Mutate>(\n existing: MetaEntry<M>,\n change: EditViewChange,\n schema: SourceSchema,\n withIDs: WithIDs,\n mutate: Mutate,\n): MetaEntry<M> {\n // In-place edit is safe when fully mutating or when `existing` was already\n // created/cloned in this transaction (copy-on-write). A primary-key change\n // always needs a fresh entry so identity tracks the new key.\n const canMutate = mutate || owns(existing);\n const newEntry: MutableMetaEntry =\n canMutate && schema.compareRows(change.oldNode.row, change.node.row) === 0\n ? Object.assign(existing, change.node.row)\n : track({...existing, ...change.node.row});\n\n if (withIDs) {\n return setProperty(\n mutate,\n newEntry,\n idSymbol,\n makeID(change.node.row, schema),\n );\n }\n return newEntry;\n}\n\n/**\n * Initialize child relationships on a newly-added entry by mutating it in place.\n *\n * New nodes don't exist in the view yet, so we can build in-place (no refs to preserve):\n *\n * New nodes don't exist in the view yet, so we can build in-place (no refs to preserve):\n *\n * Existing node edit (must path-copy): New node (can build in-place):\n *\n * view: [A, B, C] view: [A, B, _]\n * │ │\n * edit C.child add C with children\n * │ │\n * ▼ ▼\n * view': [A, B, C'] ◄─ path-copy view': [A, B, C{children:[...]}]\n * up the tree └─ built in-place\n *\n * Hidden schemas still use applyChange to collapse junction levels.\n */\nfunction initializeRelationshipsForNewEntryIfAny(\n entry: MutableMetaEntry,\n node: ViewNode,\n schema: SourceSchema,\n childFormats: Record<string, Format>,\n withIDs: WithIDs,\n): void {\n let result = entry;\n for (const relationship of Object.keys(node.relationships)) {\n const childSchema = must(schema.relationships[relationship]);\n const childFormat = childFormats[relationship];\n if (childFormat === undefined) {\n continue;\n }\n\n // Hidden/singular: use applyChange to handle properly\n if (childSchema.isHidden || childFormat.singular) {\n const newView = childFormat.singular\n ? undefined\n : track([] as MutableMetaEntryList);\n result[relationship] = newView;\n\n for (const childNode of getChildNodes(node, relationship)) {\n applyChangeInternal(\n result,\n {type: 'add', node: childNode},\n childSchema,\n relationship,\n childFormat,\n withIDs,\n true, // this is a new entry, so we can mutate\n );\n }\n } else {\n // Plural non-hidden: build array in-place for efficiency\n const childArray: MutableMetaEntryList = track([]);\n\n for (const childNode of getChildNodes(node, relationship)) {\n const newEntry = makeNewMetaEntry(\n childNode.row,\n childSchema,\n withIDs,\n 1,\n );\n const rawPos = binarySearch(\n childArray,\n childNode.row,\n childSchema.compareRows,\n );\n\n if (rawPos >= 0) {\n childArray[rawPos][refCountSymbol]++;\n } else {\n childArray.splice(~rawPos, 0, newEntry);\n initializeRelationshipsForNewEntryIfAny(\n newEntry,\n childNode,\n childSchema,\n childFormat.relationships,\n withIDs,\n );\n }\n }\n\n result[relationship] = childArray;\n }\n }\n}\n\nfunction add<M extends Mutate>(\n row: Row,\n view: MetaEntryList<M>,\n schema: SourceSchema,\n withIDs: WithIDs,\n mutate: M,\n): {\n newEntry: MutableMetaEntry | undefined;\n newView: MutableMetaEntryList;\n} {\n const rawPos = binarySearch(view, row, schema.compareRows);\n\n if (rawPos >= 0) {\n const existing = view[rawPos];\n\n const updated = incRefCount(mutate, existing);\n return {\n newEntry: undefined,\n newView: arrayWith(mutate, view, rawPos, updated),\n };\n }\n const newEntry = makeNewMetaEntry(row, schema, withIDs, 1);\n return {newEntry, newView: insertAt(mutate, view, ~rawPos, newEntry)};\n}\n\nfunction insertAt<M extends Mutate, T>(\n mutate: M,\n array: MutableArray<M, T>,\n index: number,\n item: T,\n): T[] {\n if (mutate || owns(array)) {\n (array as T[]).splice(index, 0, item);\n return array as T[];\n }\n return track(array.toSpliced(index, 0, item));\n}\n\nfunction removeAt<M extends Mutate, T>(\n mutate: M,\n array: MutableArray<M, T>,\n index: number,\n): T[] {\n if (mutate || owns(array)) {\n (array as T[]).splice(index, 1);\n return array as T[];\n }\n return track(array.toSpliced(index, 1));\n}\n\nfunction removeAndUpdateRefCount<M extends Mutate>(\n view: MetaEntryList<M>,\n row: Row,\n compareRows: Comparator,\n mutate: M,\n): MutableMetaEntryList {\n const pos = binarySearch(view, row, compareRows);\n assert(pos >= 0, 'node does not exist');\n const oldEntry = view[pos];\n const rc = oldEntry[refCountSymbol];\n if (rc === 1) {\n return removeAt(mutate, view, pos);\n }\n const newEntry = decRefCount(mutate, oldEntry);\n return arrayWith(mutate, view, pos, newEntry);\n}\n\n/**\n * Binary search returning a number.\n * - If found at index `i`: returns `i` (>= 0).\n * - If not found, insertion point is `low`: returns `~low` (< 0).\n * Recover insertion point with `~result`.\n */\nfunction binarySearch(\n view: MetaEntryList<Mutate>,\n target: Row,\n comparator: Comparator,\n): number {\n let high = view.length - 1;\n if (high < 0) {\n return ~0;\n }\n\n // Probe the last entry before searching. Hydration feeds the view rows in\n // the query's sort order, so every insert belongs at the end and the plain\n // search spends log2(n) comparisons to rediscover that -- about eleven per\n // row for a view of a couple of thousand. Row comparison is the single\n // largest cost in hydration on Hermes, so collapsing those eleven to one is\n // worth the one extra comparison this costs when the row does land inside\n // the view, which is a single push rather than a bulk load.\n // MetaEntry has all Row props; comparator only reads string keys\n const last = comparator(view[high] as Row, target);\n if (last < 0) {\n return ~(high + 1);\n }\n if (last === 0) {\n return high;\n }\n\n let low = 0;\n high -= 1;\n while (low <= high) {\n const mid = (low + high) >>> 1;\n const comparison = comparator(view[mid] as Row, target);\n if (comparison < 0) {\n low = mid + 1;\n } else if (comparison > 0) {\n high = mid - 1;\n } else {\n return mid;\n }\n }\n return ~low;\n}\n\n/** Assert value is MetaEntry (has refCountSymbol). */\nfunction assertMetaEntry<M extends Mutate>(\n v: unknown,\n): asserts v is MetaEntry<M> {\n assertNumber((v as Partial<MetaEntry<M>>)[refCountSymbol]);\n}\n\n/** Get singular MetaEntry, throws if missing. */\nfunction getSingularEntry<M extends Mutate>(\n parentEntry: MetaEntry<M>,\n relationship: string,\n): MetaEntry<M> {\n const entry = parentEntry[relationship];\n assert(entry !== undefined, 'node does not exist');\n assertMetaEntry(entry);\n return entry;\n}\n\n/** Get singular MetaEntry or undefined if not set. */\nfunction getOptionalSingularEntry<M extends Mutate>(\n parentEntry: MetaEntry<M>,\n relationship: string,\n): MetaEntry<M> | undefined {\n const entry = parentEntry[relationship];\n if (entry === undefined) {\n return undefined;\n }\n assertMetaEntry(entry);\n return entry;\n}\n\n/** Get child array as MetaEntryList. */\nfunction getChildEntryList<M extends Mutate>(\n parentEntry: MetaEntry<M>,\n relationship: string,\n): MetaEntryList<M> {\n const view = parentEntry[relationship];\n assertArray(view);\n return view as MetaEntryList<M>;\n}\n\n/** Create MetaEntry from row with given refCount. */\nfunction makeNewMetaEntry(\n row: Row,\n schema: SourceSchema,\n withIDs: WithIDs,\n rc: number,\n): MutableMetaEntry {\n // This creates a new MetaEntry from a Row. We never mutate Rows.\n if (withIDs) {\n return track({\n ...row,\n [refCountSymbol]: rc,\n [idSymbol]: makeID(row, schema),\n });\n }\n return track({\n ...row,\n [refCountSymbol]: rc,\n });\n}\n\nfunction makeID(row: Row, schema: SourceSchema) {\n // optimization for case of non-compound primary key\n if (schema.primaryKey.length === 1) {\n return JSON.stringify(row[schema.primaryKey[0]]);\n }\n return JSON.stringify(schema.primaryKey.map(k => row[k]));\n}\n\nfunction incRefCount<M extends Mutate>(\n mutate: M,\n entry: MetaEntry<M>,\n): MutableMetaEntry {\n return setRefCount(mutate, entry, entry[refCountSymbol] + 1);\n}\n\nfunction decRefCount<M extends Mutate>(\n mutate: M,\n entry: MetaEntry<M>,\n): MutableMetaEntry {\n return setRefCount(mutate, entry, entry[refCountSymbol] - 1);\n}\n\nfunction setRefCount<M extends Mutate>(\n mutate: M,\n entry: MetaEntry<M>,\n count: number,\n): MutableMetaEntry {\n if (mutate || owns(entry)) {\n (entry as MutableMetaEntry)[refCountSymbol] = count;\n return entry;\n }\n return track({\n ...entry,\n [refCountSymbol]: count,\n });\n}\n\nfunction arrayWith<M extends Mutate, T>(\n mutate: M,\n array: MutableArray<M, T>,\n index: number,\n value: T,\n): T[] {\n if (mutate || owns(array)) {\n (array as T[])[index] = value;\n return array as T[];\n }\n return track(array.with(index, value));\n}\n\nfunction setProperty<\n M extends Mutate,\n K extends string | keyof MetaEntry<M>,\n V,\n>(\n mutate: M,\n parentEntry: MetaEntry<M>,\n key: K,\n value: V,\n): MutableMetaEntry & {[P in K]: V} {\n if (mutate || owns(parentEntry)) {\n assignProperty(parentEntry as {[P in K]: V}, key, value);\n return parentEntry as MutableMetaEntry & {[P in K]: V};\n }\n return track({\n ...parentEntry,\n [key]: value,\n }) as MutableMetaEntry & {[P in K]: V};\n}\n\nconst setRelation: <M extends Mutate>(\n mutate: M,\n parentEntry: MetaEntry<M>,\n relationship: string,\n value: Entry | Entry[] | undefined,\n) => MutableMetaEntry = setProperty;\n"],"mappings":"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"}
1
+ {"version":3,"file":"view-apply-change.js","names":[],"sources":["../../../../../zql/src/ivm/view-apply-change.ts"],"sourcesContent":["import {\n assert,\n assertArray,\n assertNumber,\n unreachable,\n} from '../../../shared/src/asserts.ts';\nimport {must} from '../../../shared/src/must.ts';\nimport {assignProperty} from '../../../shared/src/objects.ts';\nimport type {Writable} from '../../../shared/src/writable.ts';\nimport type {Row} from '../../../zero-protocol/src/data.ts';\nimport {type Comparator, type Node} from './data.ts';\nimport {skipYields} from './operator.ts';\nimport type {SourceSchema} from './schema.ts';\nimport type {Entry, Format} from './view.ts';\n\nexport const refCountSymbol = Symbol('rc');\nexport const idSymbol = Symbol('id');\n\ntype ReadonlyMetaEntry = Entry & {\n readonly [refCountSymbol]: number;\n readonly [idSymbol]?: string | undefined;\n};\n\ntype MutableMetaEntry = Writable<ReadonlyMetaEntry>;\n\n/**\n * MetaEntry is an Entry with internal tracking fields for reference counting\n * and stable identity. All entries in the view tree are MetaEntry instances,\n * created through makeNewMetaEntry().\n */\ntype MetaEntry<M extends Mutate> = M extends true\n ? MutableMetaEntry\n : ReadonlyMetaEntry;\n\ntype MutableArray<M extends Mutate, T> = M extends true ? T[] : readonly T[];\n\ntype MetaEntryList<M extends Mutate> = MutableArray<M, MetaEntry<M>>;\n\ntype MutableMetaEntryList = MutableMetaEntry[];\n\n/**\n * Node with eagerly-expanded relationships (arrays instead of generators).\n * Used when batching changes to capture source state at push time.\n */\nexport type ExpandedNode = {\n row: Row;\n relationships: Record<string, ExpandedNode[]>;\n};\n\n/**\n * A node for view changes. Can be either:\n * - A lazy Node with generator relationships (original behavior)\n * - An ExpandedNode with pre-computed relationship arrays (for batching)\n */\nexport type ViewNode = Node | ExpandedNode;\n\n/**\n * `applyChange` does not consume the `relationships` of `ChildChange#node`,\n * `EditChange#node` and `EditChange#oldNode`. The `ViewChange` type\n * documents and enforces this via the type system.\n */\nexport type ViewChange =\n | AddViewChange\n | RemoveViewChange\n | ChildViewChange\n | EditViewChange;\n\nexport type RowOnlyNode = {row: Row};\n\nexport type AddViewChange = {\n type: 'add';\n node: ViewNode;\n};\n\nexport type RemoveViewChange = {\n type: 'remove';\n node: ViewNode;\n};\n\ntype ChildViewChange = {\n type: 'child';\n node: RowOnlyNode;\n child: {\n relationshipName: string;\n change: ViewChange;\n };\n};\n\ntype EditViewChange = {\n type: 'edit';\n node: RowOnlyNode;\n oldNode: RowOnlyNode;\n};\n\n/**\n * This is a subset of WeakMap but restricted to what we need.\n * @deprecated Not used anymore. This will be removed in the future.\n */\nexport interface RefCountMap {\n get(entry: Entry): number | undefined;\n set(entry: Entry, refCount: number): void;\n delete(entry: Entry): boolean;\n}\n\n/**\n * Get child nodes from a relationship, handling both lazy (Node) and expanded (ExpandedNode).\n */\nfunction* getChildNodes(\n node: ViewNode,\n relationship: string,\n): Generator<ViewNode> {\n const children = node.relationships[relationship];\n if (Array.isArray(children)) {\n // ExpandedNode: already an array\n yield* children;\n } else {\n // Node: lazy generator function\n yield* skipYields(children());\n }\n}\n\ntype Mutate = boolean;\ntype WithIDs = boolean;\n\n/**\n * Transaction-scoped copy-on-write.\n *\n * `applyChange` is immutable: it path-copies a new spine on every call so the\n * previously-emitted snapshot is never mutated. But within a single transaction\n * (a run of `push()` calls before `flush()`) only the final state is ever\n * observed by a listener, so the intermediate spines are pure allocation/GC\n * churn — making a K-change transaction O(K * spineSize).\n *\n * When the caller passes a WeakSet as the `mutate` argument, objects and arrays\n * that were created or cloned during the current transaction are recorded in it.\n * A helper that needs to modify such an object mutates it in place (it is not\n * yet observed) instead of cloning again. The first touch of a node still\n * copies-on-write (preserving the committed snapshot's references); subsequent\n * touches in the same transaction are in-place. This brings a K-change\n * transaction to O(spineSize + K) while keeping cross-transaction reference\n * stability.\n *\n * The set is module-scoped for the duration of a single (synchronous,\n * non-re-entrant) `applyChange` call and saved/restored around it.\n *\n * It is a WeakSet on purpose: it must not keep transiently-cloned arrays/entries\n * alive. A strong Set would extend their lifetime to the end of the transaction,\n * pushing large clones out of the young generation and adding GC pressure that\n * shows up as a regression on single-change transactions over wide lists. A\n * WeakSet gives the same identity test (\"created this transaction?\") while\n * letting dead clones be collected as cheaply as in the plain immutable path.\n */\nlet activeDirty: WeakSet<object> | undefined;\n\n/** True if `o` was created/cloned during the current transaction. */\nfunction owns(o: object): boolean {\n return activeDirty !== undefined && activeDirty.has(o);\n}\n\n/** Record `o` as owned by the current transaction (no-op outside a txn). */\nfunction track<T extends object>(o: T): T {\n activeDirty?.add(o);\n return o;\n}\n\n/**\n * Immutable view update. Returns new Entry on change, same Entry if unchanged.\n * Unchanged entries keep identity, enabling shallow comparison optimizations\n * in UI frameworks (React.memo, Solid's fine-grained reactivity, etc).\n *\n * Propagation: recurse DOWN to find target, copy objects on the way UP.\n * Siblings keep original refs. Only the ancestor path is copied.\n *\n * root {users:[A,B], items:[C,D,E]} --edit C--> root' {users:[A,B], items':[C',D,E]}\n * │ same ref │ │ │\n * └─────────────────┴── unchanged ──────────────┘ new array C' new, D/E same\n *\n * `mutate` selects the update strategy:\n * - `false` (default): fully immutable; every changed node is path-copied.\n * - `true`: mutate the tree in place (only safe when it is not yet observed,\n * e.g. during initial hydration).\n * - a `WeakSet`: transaction-scoped copy-on-write — copy on first touch, then\n * mutate in place for the rest of the transaction. See `activeDirty` above.\n */\nexport function applyChange(\n parentEntry: Entry,\n change: ViewChange,\n schema: SourceSchema,\n relationship: string,\n format: Format,\n withIDs = false,\n mutate: boolean | WeakSet<object> = false,\n): Entry {\n // A WeakSet selects copy-on-write; a boolean selects full mutate / immutable.\n const inPlace = mutate === true;\n const prevDirty = activeDirty;\n activeDirty = typeof mutate === 'object' ? mutate : undefined;\n try {\n return applyChangeInternal(\n parentEntry as MetaEntry<typeof inPlace>,\n change,\n schema,\n relationship,\n format,\n withIDs,\n inPlace,\n );\n } finally {\n activeDirty = prevDirty;\n }\n}\n\nexport function applyChangeInternal<M extends Mutate>(\n parentEntry: MetaEntry<M>,\n change: ViewChange,\n schema: SourceSchema,\n relationship: string,\n format: Format,\n withIDs: WithIDs,\n mutate: M,\n): MetaEntry<M> {\n if (schema.isHidden) {\n switch (change.type) {\n case 'add':\n case 'remove': {\n let currentParent = parentEntry;\n for (const relationship of Object.keys(change.node.relationships)) {\n const childSchema = must(schema.relationships[relationship]);\n for (const node of getChildNodes(change.node, relationship)) {\n currentParent = applyChangeInternal(\n currentParent,\n {type: change.type, node},\n childSchema,\n relationship,\n format,\n withIDs,\n mutate,\n );\n }\n }\n return currentParent;\n }\n case 'edit':\n // If hidden at this level it means that the hidden row was changed. If\n // the row was changed in such a way that it would change the\n // relationships then the edit would have been split into remove and\n // add.\n return parentEntry;\n case 'child': {\n const childSchema = must(\n schema.relationships[change.child.relationshipName],\n );\n return applyChangeInternal(\n parentEntry,\n change.child.change,\n childSchema,\n relationship,\n format,\n withIDs,\n mutate,\n );\n }\n default:\n unreachable(change);\n }\n }\n\n const {singular, relationships: childFormats} = format;\n switch (change.type) {\n // ADD: Insert row (rc=1) or increment refCount if duplicate.\n // RefCount tracks when the same row is reachable via multiple edges\n // within a relationship:\n //\n // issue.labels: [L1, L2] both point to same creator\n // │ │ │\n // ▼ ▼ ▼\n // label.creator ──────────► [User:rc=2] (one row, two refs)\n //\n // add(A) add(A) remove(A) remove(A)\n // ↓ ↓ ↓ ↓\n // [A:rc=1] → [A:rc=2] → [A:rc=1] → (deleted)\n case 'add': {\n if (singular) {\n const oldEntry = getOptionalSingularEntry(parentEntry, relationship);\n if (oldEntry !== undefined) {\n // Duplicate add: increment refCount\n assert(\n schema.compareRows(oldEntry, change.node.row) === 0,\n `Singular relationship '${relationship}' should not have multiple rows. You may need to declare this relationship with the \\`many\\` helper instead of the \\`one\\` helper in your schema.`,\n );\n\n const newEntry = incRefCount(mutate, oldEntry);\n return setRelation(mutate, parentEntry, relationship, newEntry);\n } else {\n // New row: create with rc=1, initialize nested relationships\n const newEntry = makeNewMetaEntry(\n change.node.row,\n schema,\n withIDs,\n 1,\n );\n initializeRelationshipsForNewEntryIfAny(\n newEntry,\n change.node,\n schema,\n childFormats,\n withIDs,\n );\n return setRelation(mutate, parentEntry, relationship, newEntry);\n }\n } else {\n // Plural: binary search for position, insert or increment refCount\n const view = getChildEntryList(parentEntry, relationship);\n const {newEntry, newView} = add(\n change.node.row,\n view,\n schema,\n withIDs,\n mutate,\n );\n\n if (newEntry) {\n initializeRelationshipsForNewEntryIfAny(\n newEntry,\n change.node,\n schema,\n childFormats,\n withIDs,\n );\n }\n return setRelation(mutate, parentEntry, relationship, newView);\n }\n }\n // REMOVE: Decrement refCount, physically remove when rc=0.\n case 'remove': {\n if (singular) {\n const oldEntry = getSingularEntry(parentEntry, relationship);\n const rc = oldEntry[refCountSymbol];\n if (rc === 1) {\n return setRelation(mutate, parentEntry, relationship, undefined);\n }\n const newEntry = decRefCount(mutate, oldEntry);\n return setRelation(mutate, parentEntry, relationship, newEntry);\n } else {\n const view = getChildEntryList(parentEntry, relationship);\n const newView = removeAndUpdateRefCount(\n view,\n change.node.row,\n schema.compareRows,\n mutate,\n );\n return setRelation(mutate, parentEntry, relationship, newView);\n }\n }\n // CHILD: Propagate nested change up to this level (leaf-to-root pattern).\n case 'child': {\n const childSchema = must(\n schema.relationships[change.child.relationshipName],\n );\n const childFormat = format.relationships[change.child.relationshipName];\n if (childFormat === undefined) {\n return parentEntry; // Relationship not in view format\n }\n\n if (singular) {\n const existing = getSingularEntry(parentEntry, relationship);\n const newExisting = applyChangeInternal(\n existing,\n change.child.change,\n childSchema,\n change.child.relationshipName,\n childFormat,\n withIDs,\n mutate,\n );\n // Preserve identity if child didn't change (enables shallow-compare optimizations).\n if (newExisting === existing) {\n return parentEntry;\n }\n return setRelation(mutate, parentEntry, relationship, newExisting);\n } else {\n // Find the target row in the sorted array via binary search.\n const view = getChildEntryList(parentEntry, relationship);\n const pos = binarySearch(view, change.node.row, schema.compareRows);\n assert(pos >= 0, 'node does not exist');\n const existing = view[pos];\n const newExisting = applyChangeInternal(\n existing,\n change.child.change,\n childSchema,\n change.child.relationshipName,\n childFormat,\n withIDs,\n mutate,\n );\n // Preserve identity if descendant didn't change.\n if (newExisting === existing) {\n return parentEntry;\n }\n // applyChangeInternal preserves MetaEntry structure when input is MetaEntry\n assertMetaEntry(newExisting);\n return setRelation(\n mutate,\n parentEntry,\n relationship,\n arrayWith(mutate, view, pos, newExisting),\n );\n }\n }\n // EDIT: Update row fields. If sort key changes, row may move position.\n //\n // Position change with rc>1 (two query paths reach same row):\n //\n // Before: [A, B(rc=2), C, D] After: [A, B(rc=1), C, B'(rc=1), D]\n // │ │ │\n // path1 + path2 path1 ghost path2 moved\n //\n // Why ghost stays: path1 still expects B at old position.\n // B' appears where path2's sort order places it.\n case 'edit': {\n if (singular) {\n const existing = getSingularEntry(parentEntry, relationship);\n const newEntry = applyEdit(existing, change, schema, withIDs, mutate);\n return setRelation(mutate, parentEntry, relationship, newEntry);\n } else {\n const view = getChildEntryList(parentEntry, relationship);\n // Sort key changed: row may need to move\n if (schema.compareRows(change.oldNode.row, change.node.row) !== 0) {\n const oldPos = binarySearch(\n view,\n change.oldNode.row,\n schema.compareRows,\n );\n assert(oldPos >= 0, 'old node does not exist');\n const oldEntry = view[oldPos];\n const rawPos = binarySearch(\n view,\n change.node.row,\n schema.compareRows,\n );\n const found = rawPos >= 0;\n const pos = found ? rawPos : ~rawPos;\n // A special case:\n // when refCount is 1 (so the row is being moved without leaving a\n // placeholder behind), and the new pos is the same as the old, or\n // directly after the old (so after the remove of the old it would be\n // in the same pos): the row does not need to be moved, just edited.\n if (\n oldEntry[refCountSymbol] === 1 &&\n (pos === oldPos || pos - 1 === oldPos)\n ) {\n const newEntry = applyEdit(\n oldEntry,\n change,\n schema,\n withIDs,\n mutate,\n );\n return setRelation(\n mutate,\n parentEntry,\n relationship,\n arrayWith(mutate, view, oldPos, newEntry),\n );\n } else {\n // Move the row. If rc > 1, an edit will be received for each ref.\n // On first edit: move row, apply edit, set rc=1. Leave a copy at\n // old pos with decremented rc. As each edit arrives, old copy's rc\n // decrements and new pos rc increments. When copy rc hits 0, remove.\n const newRefCount = oldEntry[refCountSymbol] - 1;\n let newView: MutableMetaEntryList;\n let adjustedPos = pos;\n\n if (newRefCount === 0) {\n newView = removeAt(mutate, view, oldPos);\n adjustedPos = oldPos < pos ? pos - 1 : pos;\n } else {\n const oldEntryCopy = setRefCount(mutate, oldEntry, newRefCount);\n newView = arrayWith(mutate, view, oldPos, oldEntryCopy);\n }\n\n if (found) {\n // Merge with existing at new pos\n const existingEntry = newView[adjustedPos];\n const editedEntry = applyEdit(\n existingEntry,\n change,\n schema,\n withIDs,\n mutate,\n );\n const updatedEntry = setRefCount(\n mutate,\n editedEntry,\n existingEntry[refCountSymbol] + 1,\n );\n return setRelation(\n mutate,\n parentEntry,\n relationship,\n arrayWith(mutate, newView, adjustedPos, updatedEntry),\n );\n } else {\n // Insert at new pos with rc=1\n const editedEntry = applyEdit(\n oldEntry,\n change,\n schema,\n withIDs,\n mutate,\n );\n const movedEntry = setRefCount(mutate, editedEntry, 1);\n return setRelation(\n mutate,\n parentEntry,\n relationship,\n insertAt(mutate, newView, adjustedPos, movedEntry),\n );\n }\n }\n } else {\n // Sort key unchanged: edit in place\n const pos = binarySearch(\n view,\n change.oldNode.row,\n schema.compareRows,\n );\n assert(pos >= 0, 'node does not exist');\n const newEntry = applyEdit(\n view[pos],\n change,\n schema,\n withIDs,\n mutate,\n );\n return setRelation(\n mutate,\n parentEntry,\n relationship,\n arrayWith(mutate, view, pos, newEntry),\n );\n }\n }\n }\n default:\n unreachable(change);\n }\n}\n\n/**\n * Batch apply multiple changes to an Entry tree.\n * For small batches or complex cases, falls back to sequential applyChange.\n * Future optimization: O(N + K) batch processing for large K.\n */\nexport function applyChanges(\n parentEntry: Entry,\n changes: ViewChange[],\n schema: SourceSchema,\n relationship: string,\n format: Format,\n withIDs: WithIDs = false,\n mutate: Mutate = false,\n): Entry {\n let result = parentEntry;\n for (const change of changes) {\n result = applyChange(\n result,\n change,\n schema,\n relationship,\n format,\n withIDs,\n mutate,\n );\n }\n return result;\n}\n\nfunction applyEdit<M extends Mutate>(\n existing: MetaEntry<M>,\n change: EditViewChange,\n schema: SourceSchema,\n withIDs: WithIDs,\n mutate: Mutate,\n): MetaEntry<M> {\n // In-place edit is safe when fully mutating or when `existing` was already\n // created/cloned in this transaction (copy-on-write). A primary-key change\n // always needs a fresh entry so identity tracks the new key.\n const canMutate = mutate || owns(existing);\n const newEntry: MutableMetaEntry =\n canMutate && schema.compareRows(change.oldNode.row, change.node.row) === 0\n ? Object.assign(existing, change.node.row)\n : track({...existing, ...change.node.row});\n\n if (withIDs) {\n return setProperty(\n mutate,\n newEntry,\n idSymbol,\n makeID(change.node.row, schema),\n );\n }\n return newEntry;\n}\n\n/**\n * Initialize child relationships on a newly-added entry by mutating it in place.\n *\n * New nodes don't exist in the view yet, so we can build in-place (no refs to preserve):\n *\n * New nodes don't exist in the view yet, so we can build in-place (no refs to preserve):\n *\n * Existing node edit (must path-copy): New node (can build in-place):\n *\n * view: [A, B, C] view: [A, B, _]\n * │ │\n * edit C.child add C with children\n * │ │\n * ▼ ▼\n * view': [A, B, C'] ◄─ path-copy view': [A, B, C{children:[...]}]\n * up the tree └─ built in-place\n *\n * Hidden schemas still use applyChange to collapse junction levels.\n */\nfunction initializeRelationshipsForNewEntryIfAny(\n entry: MutableMetaEntry,\n node: ViewNode,\n schema: SourceSchema,\n childFormats: Record<string, Format>,\n withIDs: WithIDs,\n): void {\n let result = entry;\n for (const relationship of Object.keys(node.relationships)) {\n const childSchema = must(schema.relationships[relationship]);\n const childFormat = childFormats[relationship];\n if (childFormat === undefined) {\n continue;\n }\n\n // Hidden/singular: use applyChange to handle properly\n if (childSchema.isHidden || childFormat.singular) {\n const newView = childFormat.singular\n ? undefined\n : track([] as MutableMetaEntryList);\n result[relationship] = newView;\n\n for (const childNode of getChildNodes(node, relationship)) {\n applyChangeInternal(\n result,\n {type: 'add', node: childNode},\n childSchema,\n relationship,\n childFormat,\n withIDs,\n true, // this is a new entry, so we can mutate\n );\n }\n } else {\n // Plural non-hidden: build array in-place for efficiency\n const childArray: MutableMetaEntryList = track([]);\n\n for (const childNode of getChildNodes(node, relationship)) {\n const newEntry = makeNewMetaEntry(\n childNode.row,\n childSchema,\n withIDs,\n 1,\n );\n const rawPos = binarySearch(\n childArray,\n childNode.row,\n childSchema.compareRows,\n );\n\n if (rawPos >= 0) {\n childArray[rawPos][refCountSymbol]++;\n } else {\n childArray.splice(~rawPos, 0, newEntry);\n initializeRelationshipsForNewEntryIfAny(\n newEntry,\n childNode,\n childSchema,\n childFormat.relationships,\n withIDs,\n );\n }\n }\n\n result[relationship] = childArray;\n }\n }\n}\n\nfunction add<M extends Mutate>(\n row: Row,\n view: MetaEntryList<M>,\n schema: SourceSchema,\n withIDs: WithIDs,\n mutate: M,\n): {\n newEntry: MutableMetaEntry | undefined;\n newView: MutableMetaEntryList;\n} {\n const rawPos = binarySearch(view, row, schema.compareRows);\n\n if (rawPos >= 0) {\n const existing = view[rawPos];\n\n const updated = incRefCount(mutate, existing);\n return {\n newEntry: undefined,\n newView: arrayWith(mutate, view, rawPos, updated),\n };\n }\n const newEntry = makeNewMetaEntry(row, schema, withIDs, 1);\n return {newEntry, newView: insertAt(mutate, view, ~rawPos, newEntry)};\n}\n\nfunction insertAt<M extends Mutate, T>(\n mutate: M,\n array: MutableArray<M, T>,\n index: number,\n item: T,\n): T[] {\n if (mutate || owns(array)) {\n (array as T[]).splice(index, 0, item);\n return array as T[];\n }\n return track(array.toSpliced(index, 0, item));\n}\n\nfunction removeAt<M extends Mutate, T>(\n mutate: M,\n array: MutableArray<M, T>,\n index: number,\n): T[] {\n if (mutate || owns(array)) {\n (array as T[]).splice(index, 1);\n return array as T[];\n }\n return track(array.toSpliced(index, 1));\n}\n\nfunction removeAndUpdateRefCount<M extends Mutate>(\n view: MetaEntryList<M>,\n row: Row,\n compareRows: Comparator,\n mutate: M,\n): MutableMetaEntryList {\n const pos = binarySearch(view, row, compareRows);\n assert(pos >= 0, 'node does not exist');\n const oldEntry = view[pos];\n const rc = oldEntry[refCountSymbol];\n if (rc === 1) {\n return removeAt(mutate, view, pos);\n }\n const newEntry = decRefCount(mutate, oldEntry);\n return arrayWith(mutate, view, pos, newEntry);\n}\n\n/**\n * Binary search returning a number.\n * - If found at index `i`: returns `i` (>= 0).\n * - If not found, insertion point is `low`: returns `~low` (< 0).\n * Recover insertion point with `~result`.\n */\nfunction binarySearch(\n view: MetaEntryList<Mutate>,\n target: Row,\n comparator: Comparator,\n): number {\n let low = 0;\n let high = view.length - 1;\n while (low <= high) {\n const mid = (low + high) >>> 1;\n // MetaEntry has all Row props; comparator only reads string keys\n const comparison = comparator(view[mid] as Row, target);\n if (comparison < 0) {\n low = mid + 1;\n } else if (comparison > 0) {\n high = mid - 1;\n } else {\n return mid;\n }\n }\n return ~low;\n}\n\n/** Assert value is MetaEntry (has refCountSymbol). */\nfunction assertMetaEntry<M extends Mutate>(\n v: unknown,\n): asserts v is MetaEntry<M> {\n assertNumber((v as Partial<MetaEntry<M>>)[refCountSymbol]);\n}\n\n/** Get singular MetaEntry, throws if missing. */\nfunction getSingularEntry<M extends Mutate>(\n parentEntry: MetaEntry<M>,\n relationship: string,\n): MetaEntry<M> {\n const entry = parentEntry[relationship];\n assert(entry !== undefined, 'node does not exist');\n assertMetaEntry(entry);\n return entry;\n}\n\n/** Get singular MetaEntry or undefined if not set. */\nfunction getOptionalSingularEntry<M extends Mutate>(\n parentEntry: MetaEntry<M>,\n relationship: string,\n): MetaEntry<M> | undefined {\n const entry = parentEntry[relationship];\n if (entry === undefined) {\n return undefined;\n }\n assertMetaEntry(entry);\n return entry;\n}\n\n/** Get child array as MetaEntryList. */\nfunction getChildEntryList<M extends Mutate>(\n parentEntry: MetaEntry<M>,\n relationship: string,\n): MetaEntryList<M> {\n const view = parentEntry[relationship];\n assertArray(view);\n return view as MetaEntryList<M>;\n}\n\n/** Create MetaEntry from row with given refCount. */\nfunction makeNewMetaEntry(\n row: Row,\n schema: SourceSchema,\n withIDs: WithIDs,\n rc: number,\n): MutableMetaEntry {\n // This creates a new MetaEntry from a Row. We never mutate Rows.\n if (withIDs) {\n return track({\n ...row,\n [refCountSymbol]: rc,\n [idSymbol]: makeID(row, schema),\n });\n }\n return track({\n ...row,\n [refCountSymbol]: rc,\n });\n}\n\nfunction makeID(row: Row, schema: SourceSchema) {\n // optimization for case of non-compound primary key\n if (schema.primaryKey.length === 1) {\n return JSON.stringify(row[schema.primaryKey[0]]);\n }\n return JSON.stringify(schema.primaryKey.map(k => row[k]));\n}\n\nfunction incRefCount<M extends Mutate>(\n mutate: M,\n entry: MetaEntry<M>,\n): MutableMetaEntry {\n return setRefCount(mutate, entry, entry[refCountSymbol] + 1);\n}\n\nfunction decRefCount<M extends Mutate>(\n mutate: M,\n entry: MetaEntry<M>,\n): MutableMetaEntry {\n return setRefCount(mutate, entry, entry[refCountSymbol] - 1);\n}\n\nfunction setRefCount<M extends Mutate>(\n mutate: M,\n entry: MetaEntry<M>,\n count: number,\n): MutableMetaEntry {\n if (mutate || owns(entry)) {\n (entry as MutableMetaEntry)[refCountSymbol] = count;\n return entry;\n }\n return track({\n ...entry,\n [refCountSymbol]: count,\n });\n}\n\nfunction arrayWith<M extends Mutate, T>(\n mutate: M,\n array: MutableArray<M, T>,\n index: number,\n value: T,\n): T[] {\n if (mutate || owns(array)) {\n (array as T[])[index] = value;\n return array as T[];\n }\n return track(array.with(index, value));\n}\n\nfunction setProperty<\n M extends Mutate,\n K extends string | keyof MetaEntry<M>,\n V,\n>(\n mutate: M,\n parentEntry: MetaEntry<M>,\n key: K,\n value: V,\n): MutableMetaEntry & {[P in K]: V} {\n if (mutate || owns(parentEntry)) {\n assignProperty(parentEntry as {[P in K]: V}, key, value);\n return parentEntry as MutableMetaEntry & {[P in K]: V};\n }\n return track({\n ...parentEntry,\n [key]: value,\n }) as MutableMetaEntry & {[P in K]: V};\n}\n\nconst setRelation: <M extends Mutate>(\n mutate: M,\n parentEntry: MetaEntry<M>,\n relationship: string,\n value: Entry | Entry[] | undefined,\n) => MutableMetaEntry = setProperty;\n"],"mappings":"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"}
@@ -11,21 +11,6 @@ export type Entry = {
11
11
  readonly [key: string]: Value | View;
12
12
  };
13
13
  export type { Format };
14
- /**
15
- * Creates the view `materialize` returns.
16
- *
17
- * A view notifies its observers from the callback it registers with
18
- * `onTransactionCommit`, not from `push`. Usually the pushes of a transaction
19
- * and its commit happen in one synchronous task, so nothing can look at the
20
- * view in between. The exception is views materialized before the client's
21
- * data is loaded: they are hydrated in time slices, over several tasks, and
22
- * committed together. A view whose state is readable outside of those
23
- * notifications (as `ArrayView.data` is) would show its rows ahead of the
24
- * views it is committed with. Such a view can implement the optional
25
- * `holdData()`, called right before that hydration, to keep showing its
26
- * current snapshot, and `releaseData()`, called on every view of the batch
27
- * right before they are all committed, to stop.
28
- */
29
14
  export type ViewFactory<TTable extends keyof TSchema['tables'] & string, TSchema extends Schema, TReturn, T> = (query: Query<TTable, TSchema, TReturn>, input: Input, format: Format, onDestroy: () => void, onTransactionCommit: (cb: () => void) => void, queryComplete: true | ErroredQuery | Promise<true>, updateTTL: (ttl: TTL) => void) => T;
30
15
  export type AnyViewFactory = ViewFactory<string, Schema, any, any>;
31
16
  //# sourceMappingURL=view.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"view.d.ts","sourceRoot":"","sources":["../../../../../zql/src/ivm/view.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,YAAY,EAAC,MAAM,8CAA8C,CAAC;AAC/E,OAAO,KAAK,EAAC,KAAK,EAAC,MAAM,oCAAoC,CAAC;AAC9D,OAAO,KAAK,EAAC,MAAM,EAAC,MAAM,mCAAmC,CAAC;AAC9D,OAAO,KAAK,EAAC,MAAM,EAAC,MAAM,mCAAmC,CAAC;AAC9D,OAAO,KAAK,EAAC,KAAK,EAAC,MAAM,mBAAmB,CAAC;AAC7C,OAAO,KAAK,EAAC,GAAG,EAAC,MAAM,iBAAiB,CAAC;AACzC,OAAO,KAAK,EAAC,KAAK,EAAC,MAAM,eAAe,CAAC;AAEzC,MAAM,MAAM,IAAI,GAAG,SAAS,GAAG,KAAK,GAAG,SAAS,CAAC;AACjD,MAAM,MAAM,SAAS,GAAG,SAAS,KAAK,EAAE,CAAC;AACzC,MAAM,MAAM,KAAK,GAAG;IAAC,QAAQ,EAAE,GAAG,EAAE,MAAM,GAAG,KAAK,GAAG,IAAI,CAAA;CAAC,CAAC;AAE3D,YAAY,EAAC,MAAM,EAAC,CAAC;AAErB;;;;;;;;;;;;;;GAcG;AACH,MAAM,MAAM,WAAW,CACrB,MAAM,SAAS,MAAM,OAAO,CAAC,QAAQ,CAAC,GAAG,MAAM,EAC/C,OAAO,SAAS,MAAM,EACtB,OAAO,EACP,CAAC,IACC,CACF,KAAK,EAAE,KAAK,CAAC,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,EACtC,KAAK,EAAE,KAAK,EACZ,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,IAAI,EACrB,mBAAmB,EAAE,CAAC,EAAE,EAAE,MAAM,IAAI,KAAK,IAAI,EAC7C,aAAa,EAAE,IAAI,GAAG,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,EAClD,SAAS,EAAE,CAAC,GAAG,EAAE,GAAG,KAAK,IAAI,KAC1B,CAAC,CAAC;AAGP,MAAM,MAAM,cAAc,GAAG,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC"}
1
+ {"version":3,"file":"view.d.ts","sourceRoot":"","sources":["../../../../../zql/src/ivm/view.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,YAAY,EAAC,MAAM,8CAA8C,CAAC;AAC/E,OAAO,KAAK,EAAC,KAAK,EAAC,MAAM,oCAAoC,CAAC;AAC9D,OAAO,KAAK,EAAC,MAAM,EAAC,MAAM,mCAAmC,CAAC;AAC9D,OAAO,KAAK,EAAC,MAAM,EAAC,MAAM,mCAAmC,CAAC;AAC9D,OAAO,KAAK,EAAC,KAAK,EAAC,MAAM,mBAAmB,CAAC;AAC7C,OAAO,KAAK,EAAC,GAAG,EAAC,MAAM,iBAAiB,CAAC;AACzC,OAAO,KAAK,EAAC,KAAK,EAAC,MAAM,eAAe,CAAC;AAEzC,MAAM,MAAM,IAAI,GAAG,SAAS,GAAG,KAAK,GAAG,SAAS,CAAC;AACjD,MAAM,MAAM,SAAS,GAAG,SAAS,KAAK,EAAE,CAAC;AACzC,MAAM,MAAM,KAAK,GAAG;IAAC,QAAQ,EAAE,GAAG,EAAE,MAAM,GAAG,KAAK,GAAG,IAAI,CAAA;CAAC,CAAC;AAE3D,YAAY,EAAC,MAAM,EAAC,CAAC;AAErB,MAAM,MAAM,WAAW,CACrB,MAAM,SAAS,MAAM,OAAO,CAAC,QAAQ,CAAC,GAAG,MAAM,EAC/C,OAAO,SAAS,MAAM,EACtB,OAAO,EACP,CAAC,IACC,CACF,KAAK,EAAE,KAAK,CAAC,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,EACtC,KAAK,EAAE,KAAK,EACZ,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,IAAI,EACrB,mBAAmB,EAAE,CAAC,EAAE,EAAE,MAAM,IAAI,KAAK,IAAI,EAC7C,aAAa,EAAE,IAAI,GAAG,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,EAClD,SAAS,EAAE,CAAC,GAAG,EAAE,GAAG,KAAK,IAAI,KAC1B,CAAC,CAAC;AAGP,MAAM,MAAM,cAAc,GAAG,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"mutator-registry.d.ts","sourceRoot":"","sources":["../../../../../zql/src/mutate/mutator-registry.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,KAAK,SAAS,EACf,MAAM,mCAAmC,CAAC;AAC3C,OAAO,KAAK,EAAC,iBAAiB,EAAC,MAAM,6BAA6B,CAAC;AAKnE,OAAO,KAAK,EACV,iBAAiB,EACjB,aAAa,EACd,MAAM,0CAA0C,CAAC;AAClD,OAAO,KAAK,EAAC,MAAM,EAAC,MAAM,mCAAmC,CAAC;AAG9D,OAAO,EAGL,KAAK,UAAU,EACf,KAAK,oBAAoB,EAGzB,KAAK,OAAO,EAIb,MAAM,cAAc,CAAC;AAEtB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AACH,wBAAgB,cAAc,CAE5B,KAAK,CAAC,EAAE,EACR,CAAC,SAAS,iBAAiB,GAAG,aAAa,EAG3C,WAAW,EAAE,EAAE,GAAG,wBAAwB,CAAC,EAAE,CAAC,GAC7C,eAAe,CAAC,wBAAwB,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;AAEpD,wBAAgB,cAAc,CAE5B,KAAK,CAAC,KAAK,EACX,KAAK,CAAC,UAAU,EAChB,CAAC,SAAS,iBAAiB,GAAG,aAAa,EAE3C,IAAI,EACA,eAAe,CAAC,wBAAwB,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,GACnD,CAAC,KAAK,GAAG,wBAAwB,CAAC,KAAK,CAAC,CAAC,EAC7C,SAAS,EAAE,UAAU,GAAG,wBAAwB,CAAC,UAAU,CAAC,GAC3D,eAAe,CAChB,SAAS,CACP,wBAAwB,CAAC,KAAK,CAAC,EAC/B,wBAAwB,CAAC,UAAU,CAAC,EACpC,oBAAoB,CACrB,EACD,CAAC,CACF,CAAC;AAuDF;;GAEG;AACH,wBAAgB,sBAAsB,CACpC,OAAO,SAAS,MAAM,KACnB,mBAAmB,CAAC,OAAO,CAAC,CAEhC;AAED;;;GAGG;AACH,KAAK,mBAAmB,CAAC,CAAC,SAAS,MAAM,IAAI;IAE3C,CAAC,EAAE,EACD,WAAW,EAAE,EAAE,GAAG,wBAAwB,CAAC,EAAE,CAAC,GAC7C,eAAe,CAAC,wBAAwB,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;IAGpD,CAAC,KAAK,EAAE,UAAU,EAChB,IAAI,EACA,eAAe,CAAC,wBAAwB,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,GACnD,CAAC,KAAK,GAAG,wBAAwB,CAAC,KAAK,CAAC,CAAC,EAC7C,SAAS,EAAE,UAAU,GACpB,eAAe,CAChB,SAAS,CACP,wBAAwB,CAAC,KAAK,CAAC,EAC/B,wBAAwB,CAAC,UAAU,CAAC,EACpC,oBAAoB,CACrB,EACD,CAAC,CACF,CAAC;CACH,CAAC;AAEF,MAAM,MAAM,wBAAwB,CAAC,EAAE,IAAI,EAAE,SAAS,kBAAkB,GACpE,OAAO,GACP,KAAK,CAAC;AAEV,MAAM,MAAM,wBAAwB,CAAC,EAAE,IAAI,EAAE,SAAS,kBAAkB,GACpE,EAAE,GACF,KAAK,CAAC;AAEV;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,kBAAkB,CAM7E;AAED,MAAM,MAAM,oBAAoB,CAAC,OAAO,SAAS,MAAM,IAAI,iBAAiB,GAAG;IAC7E,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;CAC3B,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,eAAe,CACzB,EAAE,SAAS,kBAAkB,EAC7B,OAAO,SAAS,MAAM,IACpB,aAAa,CAAC,EAAE,EAAE,OAAO,CAAC,GAAG;IAC/B,CAAC,GAAG,CAAC,EAAE,oBAAoB,CAAC,OAAO,CAAC,CAAC;CACtC,CAAC;AAEF;;;;GAIG;AACH,MAAM,MAAM,kBAAkB,GAAG;IAC/B,CAAC,GAAG,CAAC,EAAE,oBAAoB,CAAC,MAAM,CAAC,CAAC;IACpC,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB,CAAC;AAEF;;;;GAIG;AACH,MAAM,MAAM,aAAa,CACvB,EAAE,SAAS,kBAAkB,EAC7B,OAAO,SAAS,MAAM,IACpB;IACF,QAAQ,EAAE,CAAC,IAAI,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,SAAS,oBAAoB,GAExD,OAAO,CACL,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,EACpB,OAAO,EACP,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,UAAU,CAAC,EACtB,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,qBAAqB,CAAC,CAClC,GACD,EAAE,CAAC,CAAC,CAAC,SAAS,kBAAkB,GAC9B,aAAa,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,GAC7B,KAAK;CACZ,CAAC;AAEF,MAAM,MAAM,eAAe,CACzB,EAAE,SAAS,kBAAkB,EAC7B,OAAO,SAAS,MAAM,IACpB;IACF,QAAQ,EAAE,CAAC,IAAI,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,SAAS,oBAAoB,GAExD,OAAO,CACL,iBAAiB,GAAG,SAAS,EAAE,yDAAyD;IACxF,OAAO,EACP,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,UAAU,CAAC,EACtB,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,qBAAqB,CAAC,CAClC,GACD,EAAE,CAAC,CAAC,CAAC,SAAS,kBAAkB,GAC9B,eAAe,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,GAC/B,KAAK;CACZ,CAAC,MAAM,EAAE,CAAC,CAAC;AAEZ;;GAEG;AACH,MAAM,MAAM,kBAAkB,GAAG;IAC/B,QAAQ,EAAE,GAAG,EAAE,MAAM,GAAG,oBAAoB,GAAG,kBAAkB,CAAC;CACnE,CAAC;AAkEF,wBAAgB,eAAe,CAC7B,QAAQ,EAAE,kBAAkB,GAC3B,QAAQ,CAAC,UAAU,CAAC,CAEtB;AAED;;;GAGG;AACH,wBAAgB,UAAU,CACxB,EAAE,SAAS,kBAAkB,EAC7B,OAAO,SAAS,MAAM,EAEtB,QAAQ,EAAE,eAAe,CAAC,EAAE,EAAE,OAAO,CAAC,EACtC,IAAI,EAAE,MAAM,GACX,eAAe,CAAC,EAAE,EAAE,OAAO,CAAC,GAAG,SAAS,CAG1C;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAC5B,EAAE,SAAS,kBAAkB,EAC7B,OAAO,SAAS,MAAM,EAEtB,QAAQ,EAAE,eAAe,CAAC,EAAE,EAAE,OAAO,CAAC,EACtC,IAAI,EAAE,MAAM,GACX,eAAe,CAAC,EAAE,EAAE,OAAO,CAAC,CAM9B"}
1
+ {"version":3,"file":"mutator-registry.d.ts","sourceRoot":"","sources":["../../../../../zql/src/mutate/mutator-registry.ts"],"names":[],"mappings":"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"}
@@ -59,8 +59,8 @@ function createMutator(name, definition) {
59
59
  mutator["~"] = "Mutator";
60
60
  return mutator;
61
61
  }
62
- function iterateMutators(registry) {
63
- return iterateLeaves(registry, isMutator);
62
+ function* iterateMutators(registry) {
63
+ yield* iterateLeaves(registry, isMutator);
64
64
  }
65
65
  /**
66
66
  * Gets a Mutator by its dot-separated name from a MutatorRegistry.
@@ -1 +1 @@
1
- {"version":3,"file":"mutator-registry.js","names":[],"sources":["../../../../../zql/src/mutate/mutator-registry.ts"],"sourcesContent":["import {\n deepMerge,\n isPlainObject,\n type DeepMerge,\n} from '../../../shared/src/deep-merge.ts';\nimport type {ReadonlyJSONValue} from '../../../shared/src/json.ts';\nimport {\n getValueAtPath,\n iterateLeaves,\n} from '../../../shared/src/object-traversal.ts';\nimport type {\n BaseDefaultSchema,\n DefaultSchema,\n} from '../../../zero-types/src/default-types.ts';\nimport type {Schema} from '../../../zero-types/src/schema.ts';\nimport {validateInput} from '../query/validate-input.ts';\nimport type {Transaction} from './custom.ts';\nimport {\n isMutator,\n isMutatorDefinition,\n type AnyMutator,\n type AnyMutatorDefinition,\n type MutateRequest,\n type MutateRequestTypes,\n type Mutator,\n type MutatorDefinition,\n type MutatorExecutionFunction,\n type MutatorTypes,\n} from './mutator.ts';\n\n/**\n * Creates a MutatorRegistry from a tree of MutatorDefinitions,\n * optionally extending a base MutatorRegistry.\n *\n * @example\n * ```ts\n * // Create a new registry\n * const mutators = defineMutators({\n * user: {\n * create: defineMutator(...),\n * delete: defineMutator(...),\n * },\n * post: {\n * publish: defineMutator(...),\n * },\n * });\n *\n * // Extend an existing registry (e.g., for server-side overrides)\n * const serverMutators = defineMutators(mutators, {\n * user: {\n * create: defineMutator(...), // overrides mutators.user.create\n * },\n * // post.publish is inherited from mutators\n * });\n *\n * // Access mutators by path\n * const mr = mutators.user.create({name: 'Alice'});\n *\n * // Execute on client\n * zero.mutate(mr);\n *\n * // Execute on server\n * mr.mutator.fn({tx, ctx, args: mr.args});\n *\n * // Lookup by name (for server-side dispatch)\n * const mutator = getMutator(mutators, 'user.create');\n * ```\n */\nexport function defineMutators<\n // let MD infer freely so defaults aren't erased by a MutatorDefinitions constraint\n const MD,\n S extends BaseDefaultSchema = DefaultSchema,\n>(\n // we assert types here for clear error messages\n definitions: MD & AssertMutatorDefinitions<MD>,\n): MutatorRegistry<EnsureMutatorDefinitions<MD>, S>;\n\nexport function defineMutators<\n // same as MD above, but for TBase and TOverrides\n const TBase,\n const TOverrides,\n S extends BaseDefaultSchema = DefaultSchema,\n>(\n base:\n | MutatorRegistry<EnsureMutatorDefinitions<TBase>, S>\n | (TBase & AssertMutatorDefinitions<TBase>),\n overrides: TOverrides & AssertMutatorDefinitions<TOverrides>,\n): MutatorRegistry<\n DeepMerge<\n EnsureMutatorDefinitions<TBase>,\n EnsureMutatorDefinitions<TOverrides>,\n AnyMutatorDefinition\n >,\n S\n>;\n\nexport function defineMutators(\n definitionsOrBase: MutatorDefinitions | AnyMutatorRegistry,\n maybeOverrides?: MutatorDefinitions,\n): AnyMutatorRegistry {\n function processDefinitions(\n definitions: MutatorDefinitions,\n path: string[],\n ): Record<string | symbol, unknown> {\n const result: Record<string | symbol, unknown> = {\n ['~']: 'MutatorRegistry',\n };\n\n for (const [key, value] of Object.entries(definitions)) {\n path.push(key);\n const name = path.join('.');\n\n if (isMutatorDefinition(value)) {\n result[key] = createMutator(name, value);\n } else {\n // Nested definitions\n result[key] = processDefinitions(value, path);\n }\n path.pop();\n }\n\n return result;\n }\n\n if (maybeOverrides !== undefined) {\n // Merge base and overrides\n let base: Record<string | symbol, unknown>;\n if (!isMutatorRegistry(definitionsOrBase)) {\n base = processDefinitions(definitionsOrBase, []);\n } else {\n base = definitionsOrBase;\n }\n\n const processed = processDefinitions(maybeOverrides, []);\n\n const merged = deepMerge(base, processed, isMutatorLeaf);\n merged['~'] = 'MutatorRegistry';\n return merged as AnyMutatorRegistry;\n }\n\n return processDefinitions(\n definitionsOrBase as MutatorDefinitions,\n [],\n ) as AnyMutatorRegistry;\n}\n\nconst isMutatorLeaf = (value: unknown): boolean =>\n !isPlainObject(value) || isMutator(value);\n\n/**\n * Creates a function that can be used to define mutators with a specific schema.\n */\nexport function defineMutatorsWithType<\n TSchema extends Schema,\n>(): TypedDefineMutators<TSchema> {\n return defineMutators;\n}\n\n/**\n * The return type of defineMutatorsWithType. A function matching the\n * defineMutators overloads but with Schema pre-bound.\n */\ntype TypedDefineMutators<S extends Schema> = {\n // Single definitions\n <MD>(\n definitions: MD & AssertMutatorDefinitions<MD>,\n ): MutatorRegistry<EnsureMutatorDefinitions<MD>, S>;\n\n // Base and overrides\n <TBase, TOverrides>(\n base:\n | MutatorRegistry<EnsureMutatorDefinitions<TBase>, S>\n | (TBase & AssertMutatorDefinitions<TBase>),\n overrides: TOverrides,\n ): MutatorRegistry<\n DeepMerge<\n EnsureMutatorDefinitions<TBase>,\n EnsureMutatorDefinitions<TOverrides>,\n AnyMutatorDefinition\n >,\n S\n >;\n};\n\nexport type AssertMutatorDefinitions<MD> = MD extends MutatorDefinitions\n ? unknown\n : never;\n\nexport type EnsureMutatorDefinitions<MD> = MD extends MutatorDefinitions\n ? MD\n : never;\n\n/**\n * Checks if a value is a MutatorRegistry.\n */\nexport function isMutatorRegistry(value: unknown): value is AnyMutatorRegistry {\n return (\n typeof value === 'object' &&\n value !== null &&\n (value as Record<string, unknown>)['~'] === 'MutatorRegistry'\n );\n}\n\nexport type MutatorRegistryTypes<TSchema extends Schema> = 'MutatorRegistry' & {\n readonly $schema: TSchema;\n};\n\n/**\n * The result of defineMutators(). A tree of Mutators with a tag for detection.\n */\nexport type MutatorRegistry<\n MD extends MutatorDefinitions,\n TSchema extends Schema,\n> = ToMutatorTree<MD, TSchema> & {\n ['~']: MutatorRegistryTypes<TSchema>;\n};\n\n/**\n * A branded type for use in type constraints. Use this instead of\n * `MutatorRegistry<S, C, any>` to avoid TypeScript drilling into\n * the complex ToMutatorTree structure and hitting variance issues.\n */\nexport type AnyMutatorRegistry = {\n ['~']: MutatorRegistryTypes<Schema>;\n [key: string]: unknown;\n};\n\n/**\n * Transforms a MutatorDefinitions into a tree of Mutators.\n * Each MutatorDefinition becomes a Mutator at the same path.\n * Uses TInput for the callable args (TOutput is only used internally for validation).\n */\nexport type ToMutatorTree<\n MD extends MutatorDefinitions,\n TSchema extends Schema,\n> = {\n readonly [K in keyof MD]: MD[K] extends AnyMutatorDefinition\n ? // pull types from the phantom property\n Mutator<\n MD[K]['~']['$input'],\n TSchema,\n MD[K]['~']['$context'],\n MD[K]['~']['$wrappedTransaction']\n >\n : MD[K] extends MutatorDefinitions\n ? ToMutatorTree<MD[K], TSchema>\n : never;\n};\n\nexport type FromMutatorTree<\n MD extends MutatorDefinitions,\n TSchema extends Schema,\n> = {\n readonly [K in keyof MD]: MD[K] extends AnyMutatorDefinition\n ? // pull types from the phantom property\n Mutator<\n ReadonlyJSONValue | undefined, // intentionally left as generic to avoid variance issues\n TSchema,\n MD[K]['~']['$context'],\n MD[K]['~']['$wrappedTransaction']\n >\n : MD[K] extends MutatorDefinitions\n ? FromMutatorTree<MD[K], TSchema>\n : never;\n}[keyof MD];\n\n/**\n * A tree of MutatorDefinitions, possibly nested.\n */\nexport type MutatorDefinitions = {\n readonly [key: string]: AnyMutatorDefinition | MutatorDefinitions;\n};\n\nfunction createMutator<\n ArgsInput extends ReadonlyJSONValue | undefined,\n ArgsOutput extends ReadonlyJSONValue | undefined,\n TSchema extends Schema,\n C,\n TWrappedTransaction,\n>(\n name: string,\n definition: MutatorDefinition<ArgsInput, ArgsOutput, C, TWrappedTransaction>,\n): Mutator<ArgsInput, TSchema, C, TWrappedTransaction> {\n const {validator} = definition;\n\n // fn takes ReadonlyJSONValue args because it's called during rebase (from\n // stored JSON) and on the server (from wire format). Validation happens here.\n const fn: MutatorExecutionFunction<\n ArgsInput,\n C,\n Transaction<TSchema, TWrappedTransaction>\n > = async options => {\n const validatedArgs = validator\n ? validateInput(name, options.args, validator, 'mutator')\n : (options.args as unknown as ArgsOutput);\n await definition.fn({\n args: validatedArgs,\n ctx: options.ctx as C,\n tx: options.tx,\n });\n };\n\n const mutator = (\n args: ArgsInput,\n ): MutateRequest<ArgsInput, TSchema, C, TWrappedTransaction> => ({\n args,\n '~': 'MutateRequest' as MutateRequestTypes<\n ArgsInput,\n TSchema,\n C,\n TWrappedTransaction\n >,\n 'mutator': mutator as unknown as Mutator<\n ArgsInput,\n TSchema,\n C,\n TWrappedTransaction\n >,\n });\n\n mutator.mutatorName = name;\n mutator.fn = fn;\n mutator['~'] = 'Mutator' as unknown as MutatorTypes<\n ArgsInput,\n TSchema,\n C,\n TWrappedTransaction\n >;\n\n return mutator as unknown as Mutator<\n ArgsInput,\n TSchema,\n C,\n TWrappedTransaction\n >;\n}\n\nexport function iterateMutators(\n registry: AnyMutatorRegistry,\n): Iterable<AnyMutator> {\n return iterateLeaves(registry, isMutator);\n}\n\n/**\n * Gets a Mutator by its dot-separated name from a MutatorRegistry.\n * Returns undefined if not found.\n */\nexport function getMutator<\n MD extends MutatorDefinitions,\n TSchema extends Schema,\n>(\n registry: MutatorRegistry<MD, TSchema>,\n name: string,\n): FromMutatorTree<MD, TSchema> | undefined {\n const m = getValueAtPath(registry, name, '.');\n return m as FromMutatorTree<MD, TSchema> | undefined;\n}\n\n/**\n * Gets a Mutator by its dot-separated name from a MutatorRegistry.\n * Throws if not found.\n */\nexport function mustGetMutator<\n MD extends MutatorDefinitions,\n TSchema extends Schema,\n>(\n registry: MutatorRegistry<MD, TSchema>,\n name: string,\n): FromMutatorTree<MD, TSchema> {\n const mutator = getMutator(registry, name);\n if (mutator === undefined) {\n throw new Error(`Mutator not found: ${name}`);\n }\n return mutator;\n}\n"],"mappings":";;;;;AAgGA,SAAgB,eACd,mBACA,gBACoB;CACpB,SAAS,mBACP,aACA,MACkC;EAClC,MAAM,SAA2C,GAC9C,MAAM,kBACT;EAEA,KAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,WAAW,GAAG;GACtD,KAAK,KAAK,GAAG;GACb,MAAM,OAAO,KAAK,KAAK,GAAG;GAE1B,IAAI,oBAAoB,KAAK,GAC3B,OAAO,OAAO,cAAc,MAAM,KAAK;QAGvC,OAAO,OAAO,mBAAmB,OAAO,IAAI;GAE9C,KAAK,IAAI;EACX;EAEA,OAAO;CACT;CAEA,IAAI,mBAAmB,KAAA,GAAW;EAEhC,IAAI;EACJ,IAAI,CAAC,kBAAkB,iBAAiB,GACtC,OAAO,mBAAmB,mBAAmB,CAAC,CAAC;OAE/C,OAAO;EAGT,MAAM,YAAY,mBAAmB,gBAAgB,CAAC,CAAC;EAEvD,MAAM,SAAS,UAAU,MAAM,WAAW,aAAa;EACvD,OAAO,OAAO;EACd,OAAO;CACT;CAEA,OAAO,mBACL,mBACA,CAAC,CACH;AACF;AAEA,IAAM,iBAAiB,UACrB,CAAC,cAAc,KAAK,KAAK,UAAU,KAAK;;;;AAK1C,SAAgB,yBAEkB;CAChC,OAAO;AACT;;;;AAuCA,SAAgB,kBAAkB,OAA6C;CAC7E,OACE,OAAO,UAAU,YACjB,UAAU,QACT,MAAkC,SAAS;AAEhD;AAwEA,SAAS,cAOP,MACA,YACqD;CACrD,MAAM,EAAC,cAAa;CAIpB,MAAM,KAIF,OAAM,YAAW;EACnB,MAAM,gBAAgB,YAClB,cAAc,MAAM,QAAQ,MAAM,WAAW,SAAS,IACrD,QAAQ;EACb,MAAM,WAAW,GAAG;GAClB,MAAM;GACN,KAAK,QAAQ;GACb,IAAI,QAAQ;EACd,CAAC;CACH;CAEA,MAAM,WACJ,UAC+D;EAC/D;EACA,KAAK;EAML,WAAW;CAMb;CAEA,QAAQ,cAAc;CACtB,QAAQ,KAAK;CACb,QAAQ,OAAO;CAOf,OAAO;AAMT;AAEA,SAAgB,gBACd,UACsB;CACtB,OAAO,cAAc,UAAU,SAAS;AAC1C;;;;;AAMA,SAAgB,WAId,UACA,MAC0C;CAE1C,OADU,eAAe,UAAU,MAAM,GAClC;AACT;;;;;AAMA,SAAgB,eAId,UACA,MAC8B;CAC9B,MAAM,UAAU,WAAW,UAAU,IAAI;CACzC,IAAI,YAAY,KAAA,GACd,MAAM,IAAI,MAAM,sBAAsB,MAAM;CAE9C,OAAO;AACT"}
1
+ {"version":3,"file":"mutator-registry.js","names":[],"sources":["../../../../../zql/src/mutate/mutator-registry.ts"],"sourcesContent":["import {\n deepMerge,\n isPlainObject,\n type DeepMerge,\n} from '../../../shared/src/deep-merge.ts';\nimport type {ReadonlyJSONValue} from '../../../shared/src/json.ts';\nimport {\n getValueAtPath,\n iterateLeaves,\n} from '../../../shared/src/object-traversal.ts';\nimport type {\n BaseDefaultSchema,\n DefaultSchema,\n} from '../../../zero-types/src/default-types.ts';\nimport type {Schema} from '../../../zero-types/src/schema.ts';\nimport {validateInput} from '../query/validate-input.ts';\nimport type {Transaction} from './custom.ts';\nimport {\n isMutator,\n isMutatorDefinition,\n type AnyMutator,\n type AnyMutatorDefinition,\n type MutateRequest,\n type MutateRequestTypes,\n type Mutator,\n type MutatorDefinition,\n type MutatorExecutionFunction,\n type MutatorTypes,\n} from './mutator.ts';\n\n/**\n * Creates a MutatorRegistry from a tree of MutatorDefinitions,\n * optionally extending a base MutatorRegistry.\n *\n * @example\n * ```ts\n * // Create a new registry\n * const mutators = defineMutators({\n * user: {\n * create: defineMutator(...),\n * delete: defineMutator(...),\n * },\n * post: {\n * publish: defineMutator(...),\n * },\n * });\n *\n * // Extend an existing registry (e.g., for server-side overrides)\n * const serverMutators = defineMutators(mutators, {\n * user: {\n * create: defineMutator(...), // overrides mutators.user.create\n * },\n * // post.publish is inherited from mutators\n * });\n *\n * // Access mutators by path\n * const mr = mutators.user.create({name: 'Alice'});\n *\n * // Execute on client\n * zero.mutate(mr);\n *\n * // Execute on server\n * mr.mutator.fn({tx, ctx, args: mr.args});\n *\n * // Lookup by name (for server-side dispatch)\n * const mutator = getMutator(mutators, 'user.create');\n * ```\n */\nexport function defineMutators<\n // let MD infer freely so defaults aren't erased by a MutatorDefinitions constraint\n const MD,\n S extends BaseDefaultSchema = DefaultSchema,\n>(\n // we assert types here for clear error messages\n definitions: MD & AssertMutatorDefinitions<MD>,\n): MutatorRegistry<EnsureMutatorDefinitions<MD>, S>;\n\nexport function defineMutators<\n // same as MD above, but for TBase and TOverrides\n const TBase,\n const TOverrides,\n S extends BaseDefaultSchema = DefaultSchema,\n>(\n base:\n | MutatorRegistry<EnsureMutatorDefinitions<TBase>, S>\n | (TBase & AssertMutatorDefinitions<TBase>),\n overrides: TOverrides & AssertMutatorDefinitions<TOverrides>,\n): MutatorRegistry<\n DeepMerge<\n EnsureMutatorDefinitions<TBase>,\n EnsureMutatorDefinitions<TOverrides>,\n AnyMutatorDefinition\n >,\n S\n>;\n\nexport function defineMutators(\n definitionsOrBase: MutatorDefinitions | AnyMutatorRegistry,\n maybeOverrides?: MutatorDefinitions,\n): AnyMutatorRegistry {\n function processDefinitions(\n definitions: MutatorDefinitions,\n path: string[],\n ): Record<string | symbol, unknown> {\n const result: Record<string | symbol, unknown> = {\n ['~']: 'MutatorRegistry',\n };\n\n for (const [key, value] of Object.entries(definitions)) {\n path.push(key);\n const name = path.join('.');\n\n if (isMutatorDefinition(value)) {\n result[key] = createMutator(name, value);\n } else {\n // Nested definitions\n result[key] = processDefinitions(value, path);\n }\n path.pop();\n }\n\n return result;\n }\n\n if (maybeOverrides !== undefined) {\n // Merge base and overrides\n let base: Record<string | symbol, unknown>;\n if (!isMutatorRegistry(definitionsOrBase)) {\n base = processDefinitions(definitionsOrBase, []);\n } else {\n base = definitionsOrBase;\n }\n\n const processed = processDefinitions(maybeOverrides, []);\n\n const merged = deepMerge(base, processed, isMutatorLeaf);\n merged['~'] = 'MutatorRegistry';\n return merged as AnyMutatorRegistry;\n }\n\n return processDefinitions(\n definitionsOrBase as MutatorDefinitions,\n [],\n ) as AnyMutatorRegistry;\n}\n\nconst isMutatorLeaf = (value: unknown): boolean =>\n !isPlainObject(value) || isMutator(value);\n\n/**\n * Creates a function that can be used to define mutators with a specific schema.\n */\nexport function defineMutatorsWithType<\n TSchema extends Schema,\n>(): TypedDefineMutators<TSchema> {\n return defineMutators;\n}\n\n/**\n * The return type of defineMutatorsWithType. A function matching the\n * defineMutators overloads but with Schema pre-bound.\n */\ntype TypedDefineMutators<S extends Schema> = {\n // Single definitions\n <MD>(\n definitions: MD & AssertMutatorDefinitions<MD>,\n ): MutatorRegistry<EnsureMutatorDefinitions<MD>, S>;\n\n // Base and overrides\n <TBase, TOverrides>(\n base:\n | MutatorRegistry<EnsureMutatorDefinitions<TBase>, S>\n | (TBase & AssertMutatorDefinitions<TBase>),\n overrides: TOverrides,\n ): MutatorRegistry<\n DeepMerge<\n EnsureMutatorDefinitions<TBase>,\n EnsureMutatorDefinitions<TOverrides>,\n AnyMutatorDefinition\n >,\n S\n >;\n};\n\nexport type AssertMutatorDefinitions<MD> = MD extends MutatorDefinitions\n ? unknown\n : never;\n\nexport type EnsureMutatorDefinitions<MD> = MD extends MutatorDefinitions\n ? MD\n : never;\n\n/**\n * Checks if a value is a MutatorRegistry.\n */\nexport function isMutatorRegistry(value: unknown): value is AnyMutatorRegistry {\n return (\n typeof value === 'object' &&\n value !== null &&\n (value as Record<string, unknown>)['~'] === 'MutatorRegistry'\n );\n}\n\nexport type MutatorRegistryTypes<TSchema extends Schema> = 'MutatorRegistry' & {\n readonly $schema: TSchema;\n};\n\n/**\n * The result of defineMutators(). A tree of Mutators with a tag for detection.\n */\nexport type MutatorRegistry<\n MD extends MutatorDefinitions,\n TSchema extends Schema,\n> = ToMutatorTree<MD, TSchema> & {\n ['~']: MutatorRegistryTypes<TSchema>;\n};\n\n/**\n * A branded type for use in type constraints. Use this instead of\n * `MutatorRegistry<S, C, any>` to avoid TypeScript drilling into\n * the complex ToMutatorTree structure and hitting variance issues.\n */\nexport type AnyMutatorRegistry = {\n ['~']: MutatorRegistryTypes<Schema>;\n [key: string]: unknown;\n};\n\n/**\n * Transforms a MutatorDefinitions into a tree of Mutators.\n * Each MutatorDefinition becomes a Mutator at the same path.\n * Uses TInput for the callable args (TOutput is only used internally for validation).\n */\nexport type ToMutatorTree<\n MD extends MutatorDefinitions,\n TSchema extends Schema,\n> = {\n readonly [K in keyof MD]: MD[K] extends AnyMutatorDefinition\n ? // pull types from the phantom property\n Mutator<\n MD[K]['~']['$input'],\n TSchema,\n MD[K]['~']['$context'],\n MD[K]['~']['$wrappedTransaction']\n >\n : MD[K] extends MutatorDefinitions\n ? ToMutatorTree<MD[K], TSchema>\n : never;\n};\n\nexport type FromMutatorTree<\n MD extends MutatorDefinitions,\n TSchema extends Schema,\n> = {\n readonly [K in keyof MD]: MD[K] extends AnyMutatorDefinition\n ? // pull types from the phantom property\n Mutator<\n ReadonlyJSONValue | undefined, // intentionally left as generic to avoid variance issues\n TSchema,\n MD[K]['~']['$context'],\n MD[K]['~']['$wrappedTransaction']\n >\n : MD[K] extends MutatorDefinitions\n ? FromMutatorTree<MD[K], TSchema>\n : never;\n}[keyof MD];\n\n/**\n * A tree of MutatorDefinitions, possibly nested.\n */\nexport type MutatorDefinitions = {\n readonly [key: string]: AnyMutatorDefinition | MutatorDefinitions;\n};\n\nfunction createMutator<\n ArgsInput extends ReadonlyJSONValue | undefined,\n ArgsOutput extends ReadonlyJSONValue | undefined,\n TSchema extends Schema,\n C,\n TWrappedTransaction,\n>(\n name: string,\n definition: MutatorDefinition<ArgsInput, ArgsOutput, C, TWrappedTransaction>,\n): Mutator<ArgsInput, TSchema, C, TWrappedTransaction> {\n const {validator} = definition;\n\n // fn takes ReadonlyJSONValue args because it's called during rebase (from\n // stored JSON) and on the server (from wire format). Validation happens here.\n const fn: MutatorExecutionFunction<\n ArgsInput,\n C,\n Transaction<TSchema, TWrappedTransaction>\n > = async options => {\n const validatedArgs = validator\n ? validateInput(name, options.args, validator, 'mutator')\n : (options.args as unknown as ArgsOutput);\n await definition.fn({\n args: validatedArgs,\n ctx: options.ctx as C,\n tx: options.tx,\n });\n };\n\n const mutator = (\n args: ArgsInput,\n ): MutateRequest<ArgsInput, TSchema, C, TWrappedTransaction> => ({\n args,\n '~': 'MutateRequest' as MutateRequestTypes<\n ArgsInput,\n TSchema,\n C,\n TWrappedTransaction\n >,\n 'mutator': mutator as unknown as Mutator<\n ArgsInput,\n TSchema,\n C,\n TWrappedTransaction\n >,\n });\n\n mutator.mutatorName = name;\n mutator.fn = fn;\n mutator['~'] = 'Mutator' as unknown as MutatorTypes<\n ArgsInput,\n TSchema,\n C,\n TWrappedTransaction\n >;\n\n return mutator as unknown as Mutator<\n ArgsInput,\n TSchema,\n C,\n TWrappedTransaction\n >;\n}\n\nexport function* iterateMutators(\n registry: AnyMutatorRegistry,\n): Iterable<AnyMutator> {\n yield* iterateLeaves(registry, isMutator);\n}\n\n/**\n * Gets a Mutator by its dot-separated name from a MutatorRegistry.\n * Returns undefined if not found.\n */\nexport function getMutator<\n MD extends MutatorDefinitions,\n TSchema extends Schema,\n>(\n registry: MutatorRegistry<MD, TSchema>,\n name: string,\n): FromMutatorTree<MD, TSchema> | undefined {\n const m = getValueAtPath(registry, name, '.');\n return m as FromMutatorTree<MD, TSchema> | undefined;\n}\n\n/**\n * Gets a Mutator by its dot-separated name from a MutatorRegistry.\n * Throws if not found.\n */\nexport function mustGetMutator<\n MD extends MutatorDefinitions,\n TSchema extends Schema,\n>(\n registry: MutatorRegistry<MD, TSchema>,\n name: string,\n): FromMutatorTree<MD, TSchema> {\n const mutator = getMutator(registry, name);\n if (mutator === undefined) {\n throw new Error(`Mutator not found: ${name}`);\n }\n return mutator;\n}\n"],"mappings":";;;;;AAgGA,SAAgB,eACd,mBACA,gBACoB;CACpB,SAAS,mBACP,aACA,MACkC;EAClC,MAAM,SAA2C,GAC9C,MAAM,kBACT;EAEA,KAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,WAAW,GAAG;GACtD,KAAK,KAAK,GAAG;GACb,MAAM,OAAO,KAAK,KAAK,GAAG;GAE1B,IAAI,oBAAoB,KAAK,GAC3B,OAAO,OAAO,cAAc,MAAM,KAAK;QAGvC,OAAO,OAAO,mBAAmB,OAAO,IAAI;GAE9C,KAAK,IAAI;EACX;EAEA,OAAO;CACT;CAEA,IAAI,mBAAmB,KAAA,GAAW;EAEhC,IAAI;EACJ,IAAI,CAAC,kBAAkB,iBAAiB,GACtC,OAAO,mBAAmB,mBAAmB,CAAC,CAAC;OAE/C,OAAO;EAGT,MAAM,YAAY,mBAAmB,gBAAgB,CAAC,CAAC;EAEvD,MAAM,SAAS,UAAU,MAAM,WAAW,aAAa;EACvD,OAAO,OAAO;EACd,OAAO;CACT;CAEA,OAAO,mBACL,mBACA,CAAC,CACH;AACF;AAEA,IAAM,iBAAiB,UACrB,CAAC,cAAc,KAAK,KAAK,UAAU,KAAK;;;;AAK1C,SAAgB,yBAEkB;CAChC,OAAO;AACT;;;;AAuCA,SAAgB,kBAAkB,OAA6C;CAC7E,OACE,OAAO,UAAU,YACjB,UAAU,QACT,MAAkC,SAAS;AAEhD;AAwEA,SAAS,cAOP,MACA,YACqD;CACrD,MAAM,EAAC,cAAa;CAIpB,MAAM,KAIF,OAAM,YAAW;EACnB,MAAM,gBAAgB,YAClB,cAAc,MAAM,QAAQ,MAAM,WAAW,SAAS,IACrD,QAAQ;EACb,MAAM,WAAW,GAAG;GAClB,MAAM;GACN,KAAK,QAAQ;GACb,IAAI,QAAQ;EACd,CAAC;CACH;CAEA,MAAM,WACJ,UAC+D;EAC/D;EACA,KAAK;EAML,WAAW;CAMb;CAEA,QAAQ,cAAc;CACtB,QAAQ,KAAK;CACb,QAAQ,OAAO;CAOf,OAAO;AAMT;AAEA,UAAiB,gBACf,UACsB;CACtB,OAAO,cAAc,UAAU,SAAS;AAC1C;;;;;AAMA,SAAgB,WAId,UACA,MAC0C;CAE1C,OADU,eAAe,UAAU,MAAM,GAClC;AACT;;;;;AAMA,SAAgB,eAId,UACA,MAC8B;CAC9B,MAAM,UAAU,WAAW,UAAU,IAAI;CACzC,IAAI,YAAY,KAAA,GACd,MAAM,IAAI,MAAM,sBAAsB,MAAM;CAE9C,OAAO;AACT"}
@@ -6,7 +6,7 @@ import type { Source, SourceInput } from '../ivm/source.ts';
6
6
  import type { ViewFactory } from '../ivm/view.ts';
7
7
  import type { MetricMap } from './metrics-delegate.ts';
8
8
  import type { CustomQueryID } from './named.ts';
9
- import type { AttachPipeline, CommitListener, GotCallback, QueryDelegate } from './query-delegate.ts';
9
+ import type { CommitListener, GotCallback, QueryDelegate } from './query-delegate.ts';
10
10
  import type { HumanReadable, MaterializeOptions, PreloadOptions, Query, RunOptions } from './query.ts';
11
11
  import { type TTL } from './ttl.ts';
12
12
  import type { TypedView } from './typed-view.ts';
@@ -47,7 +47,6 @@ export declare abstract class QueryDelegateBase implements QueryDelegate {
47
47
  preload<TTable extends keyof TSchema['tables'] & string, TSchema extends Schema, TReturn>(query: Query<TTable, TSchema, TReturn>, options?: PreloadOptions): {
48
48
  cleanup: () => void;
49
49
  complete: Promise<void>;
50
- cached: Promise<void>;
51
50
  };
52
51
  /**
53
52
  * Default no-op implementation for decorateSourceInput.
@@ -110,19 +109,12 @@ export declare abstract class QueryDelegateBase implements QueryDelegate {
110
109
  */
111
110
  assertValidRunOptions(_options?: RunOptions): void;
112
111
  abstract readonly defaultQueryComplete: boolean;
113
- /**
114
- * Default: pipelines can always be built immediately. Override (together
115
- * with `onPipelinesReady`) to defer pipeline construction.
116
- */
117
- get pipelinesReady(): boolean;
118
- onPipelinesReady(_attach: AttachPipeline): () => void;
119
112
  abstract getSource(name: string): Source | undefined;
120
113
  }
121
114
  export declare function runImpl<TTable extends keyof TSchema['tables'] & string, TSchema extends Schema, TReturn>(query: Query<TTable, TSchema, TReturn>, delegate: QueryDelegate, options?: RunOptions): Promise<HumanReadable<TReturn>>;
122
115
  export declare function preloadImpl<TTable extends keyof TSchema['tables'] & string, TSchema extends Schema, TReturn>(query: Query<TTable, TSchema, TReturn>, delegate: QueryDelegate, options?: PreloadOptions): {
123
116
  cleanup: () => void;
124
117
  complete: Promise<void>;
125
- cached: Promise<void>;
126
118
  };
127
119
  export declare function materializeImpl<TTable extends keyof TSchema['tables'] & string, TSchema extends Schema, TReturn, T>(query: Query<TTable, TSchema, TReturn>, delegate: QueryDelegate, factory?: ViewFactory<TTable, TSchema, TReturn, T>, options?: MaterializeOptions): T;
128
120
  //# sourceMappingURL=query-delegate-base.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"query-delegate-base.d.ts","sourceRoot":"","sources":["../../../../../zql/src/query/query-delegate-base.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"query-delegate-base.d.ts","sourceRoot":"","sources":["../../../../../zql/src/query/query-delegate-base.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAC,GAAG,EAAC,MAAM,mCAAmC,CAAC;AAG3D,OAAO,KAAK,EAAC,MAAM,EAAC,MAAM,mCAAmC,CAAC;AAG9D,OAAO,KAAK,EAAC,WAAW,EAAC,MAAM,4BAA4B,CAAC;AAE5D,OAAO,KAAK,EAAC,KAAK,EAAE,SAAS,EAAE,OAAO,EAAC,MAAM,oBAAoB,CAAC;AAClE,OAAO,KAAK,EAAC,MAAM,EAAE,WAAW,EAAC,MAAM,kBAAkB,CAAC;AAC1D,OAAO,KAAK,EAAS,WAAW,EAAC,MAAM,gBAAgB,CAAC;AACxD,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,uBAAuB,CAAC;AACrD,OAAO,KAAK,EAAC,aAAa,EAAC,MAAM,YAAY,CAAC;AAC9C,OAAO,KAAK,EACV,cAAc,EACd,WAAW,EACX,aAAa,EACd,MAAM,qBAAqB,CAAC;AAE7B,OAAO,KAAK,EACV,aAAa,EACb,kBAAkB,EAClB,cAAc,EACd,KAAK,EACL,UAAU,EACX,MAAM,YAAY,CAAC;AACpB,OAAO,EAAyC,KAAK,GAAG,EAAC,MAAM,UAAU,CAAC;AAC1E,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,iBAAiB,CAAC;AAE/C;;;GAGG;AACH,8BAAsB,iBAAkB,YAAW,aAAa;IAC9D;;;OAGG;IACH,gBAAgB,CAAC,CAAC,EAAE,gBAAgB,EAAE,MAAM,CAAC,GAAG,CAAC;IAIjD;;;OAGG;IACH,aAAa,IAAI,OAAO;IAIxB;;;OAGG;IACH,WAAW,CACT,MAAM,SAAS,MAAM,OAAO,CAAC,QAAQ,CAAC,GAAG,MAAM,EAC/C,OAAO,SAAS,MAAM,EACtB,OAAO,EAEP,KAAK,EAAE,KAAK,CAAC,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,EACtC,OAAO,CAAC,EAAE,SAAS,EACnB,OAAO,CAAC,EAAE,kBAAkB,GAC3B,SAAS,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;IAEpC,WAAW,CACT,MAAM,SAAS,MAAM,OAAO,CAAC,QAAQ,CAAC,GAAG,MAAM,EAC/C,OAAO,SAAS,MAAM,EACtB,OAAO,EACP,CAAC,EAED,KAAK,EAAE,KAAK,CAAC,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,EACtC,OAAO,CAAC,EAAE,WAAW,CAAC,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC,EAClD,OAAO,CAAC,EAAE,kBAAkB,GAC3B,CAAC;IAEJ;;OAEG;IACH,WAAW,CACT,MAAM,SAAS,MAAM,OAAO,CAAC,QAAQ,CAAC,GAAG,MAAM,EAC/C,OAAO,SAAS,MAAM,EACtB,OAAO,EACP,CAAC,EAED,KAAK,EAAE,KAAK,CAAC,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,EACtC,OAAO,CAAC,EAAE,WAAW,CAAC,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC,EAClD,OAAO,CAAC,EAAE,kBAAkB,GAC3B,CAAC;IAeJ;;;OAGG;IACH,GAAG,CACD,MAAM,SAAS,MAAM,OAAO,CAAC,QAAQ,CAAC,GAAG,MAAM,EAC/C,OAAO,SAAS,MAAM,EACtB,OAAO,EAEP,KAAK,EAAE,KAAK,CAAC,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,EACtC,OAAO,CAAC,EAAE,UAAU,GACnB,OAAO,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;IAIlC;;;OAGG;IACH,OAAO,CACL,MAAM,SAAS,MAAM,OAAO,CAAC,QAAQ,CAAC,GAAG,MAAM,EAC/C,OAAO,SAAS,MAAM,EACtB,OAAO,EAEP,KAAK,EAAE,KAAK,CAAC,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,EACtC,OAAO,CAAC,EAAE,cAAc,GACvB;QACD,OAAO,EAAE,MAAM,IAAI,CAAC;QACpB,QAAQ,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;KACzB;IAID;;;OAGG;IACH,mBAAmB,CAAC,KAAK,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,GAAG,KAAK;IAIhE;;;OAGG;IACH,aAAa,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,GAAG,KAAK;IAIjD;;;OAGG;IACH,mBAAmB,CAAC,KAAK,EAAE,WAAW,EAAE,KAAK,EAAE,MAAM,GAAG,WAAW;IAInE;;;OAGG;IACH,OAAO,CAAC,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,GAAG,IAAI;IAInD;;;OAGG;IACH,SAAS,CAAC,CAAC,SAAS,MAAM,SAAS,EACjC,OAAO,EAAE,CAAC,EACV,MAAM,EAAE,MAAM,EACd,GAAG,KAAK,EAAE,SAAS,CAAC,CAAC,CAAC,GACrB,IAAI;IAIP;;;OAGG;IACH,cAAc,CAAC,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,YAAY,CAAC,EAAE,WAAW,GAAG,MAAM,IAAI;IAI5E;;;OAGG;IACH,cAAc,CACZ,IAAI,EAAE,GAAG,EACT,cAAc,EAAE,aAAa,EAC7B,IAAI,EAAE,GAAG,EACT,YAAY,CAAC,EAAE,WAAW,GACzB,MAAM,IAAI;IAIb;;;OAGG;IACH,iBAAiB,CAAC,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,GAAG,IAAI;IAI7C;;;OAGG;IACH,iBAAiB,CAAC,cAAc,EAAE,aAAa,EAAE,IAAI,EAAE,GAAG,GAAG,IAAI;IAIjE;;;OAGG;IACH,iBAAiB,IAAI,IAAI;IAIzB;;;OAGG;IACH,mBAAmB,CAAC,GAAG,EAAE,cAAc,GAAG,MAAM,IAAI;IAIpD;;;OAGG;IACH,qBAAqB,CAAC,QAAQ,CAAC,EAAE,UAAU,GAAG,IAAI;IAIlD,QAAQ,CAAC,QAAQ,CAAC,oBAAoB,EAAE,OAAO,CAAC;IAGhD,QAAQ,CAAC,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;CACrD;AAGD,wBAAsB,OAAO,CAC3B,MAAM,SAAS,MAAM,OAAO,CAAC,QAAQ,CAAC,GAAG,MAAM,EAC/C,OAAO,SAAS,MAAM,EACtB,OAAO,EAEP,KAAK,EAAE,KAAK,CAAC,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,EACtC,QAAQ,EAAE,aAAa,EACvB,OAAO,CAAC,EAAE,UAAU,GACnB,OAAO,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC,CA6BjC;AAED,wBAAgB,WAAW,CACzB,MAAM,SAAS,MAAM,OAAO,CAAC,QAAQ,CAAC,GAAG,MAAM,EAC/C,OAAO,SAAS,MAAM,EACtB,OAAO,EAEP,KAAK,EAAE,KAAK,CAAC,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,EACtC,QAAQ,EAAE,aAAa,EACvB,OAAO,CAAC,EAAE,cAAc,GACvB;IACD,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,QAAQ,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;CACzB,CA0BA;AAED,wBAAgB,eAAe,CAC7B,MAAM,SAAS,MAAM,OAAO,CAAC,QAAQ,CAAC,GAAG,MAAM,EAC/C,OAAO,SAAS,MAAM,EACtB,OAAO,EACP,CAAC,EAED,KAAK,EAAE,KAAK,CAAC,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,EACtC,QAAQ,EAAE,aAAa,EACvB,OAAO,GAAE,WAAW,CAClB,MAAM,EACN,OAAO,EACP,OAAO,EACP,CAAC,CAEwB,EAC3B,OAAO,CAAC,EAAE,kBAAkB,GAC3B,CAAC,CA2EH"}
@@ -1,9 +1,7 @@
1
- import { hashNameAndArgs } from "../../../zero-protocol/src/query-hash-visitor.js";
1
+ import { hashOfNameAndArgs } from "../../../zero-protocol/src/query-hash.js";
2
2
  import { asQueryInternals } from "./query-internals.js";
3
- import { hashOfAST } from "../../../zero-protocol/src/query-hash.js";
4
3
  import { buildPipeline } from "../builder/builder.js";
5
4
  import { ArrayView } from "../ivm/array-view.js";
6
- import { DeferredInput } from "../ivm/deferred-input.js";
7
5
  import { MemoryStorage } from "../ivm/memory-storage.js";
8
6
  import "./ttl.js";
9
7
  import { resolver } from "@rocicorp/resolver";
@@ -116,34 +114,21 @@ var QueryDelegateBase = class {
116
114
  * Default implementation is a no-op.
117
115
  */
118
116
  assertValidRunOptions(_options) {}
119
- /**
120
- * Default: pipelines can always be built immediately. Override (together
121
- * with `onPipelinesReady`) to defer pipeline construction.
122
- */
123
- get pipelinesReady() {
124
- return true;
125
- }
126
- onPipelinesReady(_attach) {
127
- throw new Error("onPipelinesReady called on a delegate whose pipelines are always ready");
128
- }
129
117
  };
130
118
  async function runImpl(query, delegate, options) {
131
119
  delegate.assertValidRunOptions(options);
132
120
  const v = materializeImpl(query, delegate, void 0, { ttl: options?.ttl });
133
- if (options?.type === "complete" || options?.type === "cached") {
134
- const acceptCached = options.type === "cached";
135
- return new Promise((resolve) => {
136
- v.addListener((data, type) => {
137
- if (type === "complete" || acceptCached && type === "cached") {
138
- v.destroy();
139
- resolve(data);
140
- } else if (type === "error") {
141
- v.destroy();
142
- resolve(Promise.reject(data));
143
- }
144
- });
121
+ if (options?.type === "complete") return new Promise((resolve) => {
122
+ v.addListener((data, type) => {
123
+ if (type === "complete") {
124
+ v.destroy();
125
+ resolve(data);
126
+ } else if (type === "error") {
127
+ v.destroy();
128
+ resolve(Promise.reject(data));
129
+ }
145
130
  });
146
- }
131
+ });
147
132
  options?.type;
148
133
  const ret = v.data;
149
134
  v.destroy();
@@ -152,142 +137,61 @@ async function runImpl(query, delegate, options) {
152
137
  function preloadImpl(query, delegate, options) {
153
138
  const qi = asQueryInternals(query);
154
139
  const ttl = options?.ttl ?? 0;
155
- const completeResolver = resolver();
156
- const cachedResolver = resolver();
157
- const { promise: complete } = completeResolver;
158
- const { promise: cached } = cachedResolver;
159
- complete.catch(() => {});
160
- cached.catch(() => {});
140
+ const { resolve, promise: complete } = resolver();
161
141
  const { customQueryID, ast } = qi;
162
- const gotCallback = (got, error) => {
163
- if (error) {
164
- cachedResolver.reject(error);
165
- completeResolver.reject(error);
166
- return;
167
- }
168
- if (got === true) {
169
- cachedResolver.resolve();
170
- completeResolver.resolve();
171
- } else if (got === "cached") cachedResolver.resolve();
142
+ if (customQueryID) return {
143
+ cleanup: delegate.addCustomQuery(ast, customQueryID, ttl, (got) => {
144
+ if (got) resolve();
145
+ }),
146
+ complete
172
147
  };
173
- const cleanup = customQueryID ? delegate.addCustomQuery(ast, customQueryID, ttl, gotCallback) : delegate.addServerQuery(ast, ttl, gotCallback);
174
- if (delegate.defaultQueryComplete) {
175
- cachedResolver.resolve();
176
- completeResolver.resolve();
177
- }
178
148
  return {
179
- cleanup,
180
- complete,
181
- cached
149
+ cleanup: delegate.addServerQuery(ast, ttl, (got) => {
150
+ if (got) resolve();
151
+ }),
152
+ complete
182
153
  };
183
154
  }
184
155
  function materializeImpl(query, delegate, factory = arrayViewFactory, options) {
185
156
  let ttl = options?.ttl ?? 3e5;
186
157
  const qi = asQueryInternals(query);
187
158
  const { ast, format, customQueryID } = qi;
188
- const queryID = customQueryID ? hashNameAndArgs(customQueryID.name, customQueryID.args) : hashOfAST(qi.ast);
159
+ const queryHash = qi.hash();
160
+ const queryID = customQueryID ? hashOfNameAndArgs(customQueryID.name, customQueryID.args) : queryHash;
189
161
  const queryCompleteResolver = resolver();
190
- const deferPipeline = !delegate.pipelinesReady;
191
- let attached = !deferPipeline;
192
- let got = delegate.defaultQueryComplete;
193
- let queryComplete = attached && got === true;
162
+ let queryComplete = delegate.defaultQueryComplete;
163
+ let endToEndMetricRecorded = false;
194
164
  const updateTTL = customQueryID ? (newTTL) => delegate.updateCustomQuery(customQueryID, newTTL) : (newTTL) => delegate.updateServerQuery(ast, newTTL);
195
- const maybeResolveComplete = () => {
196
- if (attached && got === true && queryComplete !== true) {
197
- delegate.addMetric("query-materialization-end-to-end", performance.now() - t0, queryID, ast);
198
- queryComplete = true;
199
- queryCompleteResolver.resolve(true);
200
- }
201
- };
202
- let viewHooks;
203
- const maybeMarkCached = () => {
204
- if (attached && got === "cached" && queryComplete === false) viewHooks?.markCached?.();
205
- };
206
- let destroyed = false;
207
- const gotCallback = (value, error) => {
208
- if (destroyed) return;
165
+ const gotCallback = (got, error) => {
209
166
  if (error) {
210
167
  queryCompleteResolver.reject(error);
211
168
  queryComplete = error;
212
169
  return;
213
170
  }
214
- got = value;
215
- if (got === "cached") maybeMarkCached();
216
- else if (got === false) viewHooks?.unmarkCached?.();
217
- else maybeResolveComplete();
171
+ if (got) {
172
+ if (!endToEndMetricRecorded) {
173
+ delegate.addMetric("query-materialization-end-to-end", performance.now() - t0, queryID, ast);
174
+ endToEndMetricRecorded = true;
175
+ }
176
+ queryComplete = true;
177
+ queryCompleteResolver.resolve(true);
178
+ }
218
179
  };
219
180
  let removeCommitObserver;
220
- let removePendingAttach;
221
181
  const onDestroy = () => {
222
- destroyed = true;
223
- removePendingAttach?.();
224
- removePendingAttach = void 0;
225
182
  input.destroy();
226
183
  removeCommitObserver?.();
227
184
  removeAddedQuery();
228
185
  };
229
186
  const t0 = performance.now();
230
187
  const removeAddedQuery = customQueryID ? delegate.addCustomQuery(ast, customQueryID, ttl, gotCallback) : delegate.addServerQuery(ast, ttl, gotCallback);
231
- const deferred = deferPipeline ? newDeferredInput(ast, delegate, queryID) : void 0;
232
- const input = deferred ?? buildPipeline(ast, delegate, queryID);
188
+ const input = buildPipeline(ast, delegate, queryID);
233
189
  const view = delegate.batchViewUpdates(() => (factory ?? arrayViewFactory)(query, input, format, onDestroy, (cb) => {
234
190
  removeCommitObserver = delegate.onTransactionCommit(cb);
235
191
  }, queryComplete || queryCompleteResolver.promise, updateTTL));
236
- if (!deferred) delegate.addMetric("query-materialization-client", performance.now() - t0, queryID);
237
- else removePendingAttach = delegate.onPipelinesReady(() => {
238
- removePendingAttach = void 0;
239
- if (deferred.destroyed) return () => {};
240
- const t1 = performance.now();
241
- try {
242
- viewHooks?.holdData?.();
243
- deferred.attach();
244
- } catch (e) {
245
- const error = {
246
- error: "app",
247
- id: queryID,
248
- name: customQueryID?.name ?? "",
249
- message: e instanceof Error ? e.message : String(e)
250
- };
251
- queryComplete = error;
252
- queryCompleteResolver.reject(error);
253
- throw e;
254
- }
255
- const hydrateMs = performance.now() - t1;
256
- return () => {
257
- if (destroyed) return;
258
- attached = true;
259
- viewHooks?.releaseData?.();
260
- delegate.addMetric("query-materialization-client", hydrateMs, queryID);
261
- maybeResolveComplete();
262
- maybeMarkCached();
263
- };
264
- });
265
- viewHooks = view;
266
- maybeMarkCached();
192
+ delegate.addMetric("query-materialization-client", performance.now() - t0, queryID);
267
193
  return view;
268
194
  }
269
- /**
270
- * Creates the placeholder input for a query whose pipeline cannot be built yet.
271
- *
272
- * `Input.getSchema()` is unconditional, so the placeholder needs the schema up
273
- * front. It is captured by building a pipeline and immediately destroying it:
274
- * building only connects to the sources, while the indexes and rows -- the
275
- * expensive part this deferral exists to postpone -- are read on the first
276
- * fetch. Measured at ~5us against ~500us for a single 100 row fetch.
277
- *
278
- * Building here also means a query that cannot be built at all (an unknown
279
- * table, `not(exists())` on the client) still throws from `materialize()`,
280
- * as it did before hydration was deferred.
281
- */
282
- function newDeferredInput(ast, delegate, queryID) {
283
- const build = () => buildPipeline(ast, delegate, queryID);
284
- const probe = build();
285
- try {
286
- return new DeferredInput(probe.getSchema(), build);
287
- } finally {
288
- probe.destroy();
289
- }
290
- }
291
195
  function arrayViewFactory(_query, input, format, onDestroy, onTransactionCommit, queryComplete, updateTTL) {
292
196
  const v = new ArrayView(input, format, queryComplete, updateTTL);
293
197
  v.onDestroy = onDestroy;