@rocicorp/zero 0.25.0-canary.9 → 0.25.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (517) hide show
  1. package/out/analyze-query/src/bin-analyze.js.map +1 -1
  2. package/out/analyze-query/src/run-ast.d.ts +1 -1
  3. package/out/analyze-query/src/run-ast.d.ts.map +1 -1
  4. package/out/analyze-query/src/run-ast.js +10 -8
  5. package/out/analyze-query/src/run-ast.js.map +1 -1
  6. package/out/otel/src/log-options.d.ts +1 -1
  7. package/out/otel/src/log-options.d.ts.map +1 -1
  8. package/out/otel/src/log-options.js +0 -1
  9. package/out/otel/src/log-options.js.map +1 -1
  10. package/out/replicache/src/persist/idb-databases-store.d.ts +1 -0
  11. package/out/replicache/src/persist/idb-databases-store.d.ts.map +1 -1
  12. package/out/replicache/src/persist/idb-databases-store.js +13 -2
  13. package/out/replicache/src/persist/idb-databases-store.js.map +1 -1
  14. package/out/shared/src/deep-merge.d.ts +6 -4
  15. package/out/shared/src/deep-merge.d.ts.map +1 -1
  16. package/out/shared/src/deep-merge.js +2 -1
  17. package/out/shared/src/deep-merge.js.map +1 -1
  18. package/out/shared/src/iterables.d.ts +0 -1
  19. package/out/shared/src/iterables.d.ts.map +1 -1
  20. package/out/shared/src/iterables.js +0 -34
  21. package/out/shared/src/iterables.js.map +1 -1
  22. package/out/shared/src/options-types.d.ts +113 -0
  23. package/out/shared/src/options-types.d.ts.map +1 -0
  24. package/out/shared/src/options.d.ts +2 -111
  25. package/out/shared/src/options.d.ts.map +1 -1
  26. package/out/shared/src/options.js.map +1 -1
  27. package/out/shared/src/record-proxy.d.ts +13 -0
  28. package/out/shared/src/record-proxy.d.ts.map +1 -0
  29. package/out/shared/src/record-proxy.js +59 -0
  30. package/out/shared/src/record-proxy.js.map +1 -0
  31. package/out/z2s/src/compiler.d.ts.map +1 -1
  32. package/out/z2s/src/compiler.js +4 -2
  33. package/out/z2s/src/compiler.js.map +1 -1
  34. package/out/zero/package.json.js +1 -1
  35. package/out/zero/src/adapters/drizzle.d.ts +1 -1
  36. package/out/zero/src/adapters/drizzle.d.ts.map +1 -1
  37. package/out/zero/src/adapters/drizzle.js +4 -1
  38. package/out/zero/src/bindings.d.ts +2 -0
  39. package/out/zero/src/bindings.d.ts.map +1 -0
  40. package/out/zero/src/bindings.js +27 -0
  41. package/out/zero/src/bindings.js.map +1 -0
  42. package/out/zero/src/pg.js +7 -5
  43. package/out/zero/src/react.js +2 -4
  44. package/out/zero/src/react.js.map +1 -1
  45. package/out/zero/src/server.js +7 -5
  46. package/out/zero/src/solid.js +2 -2
  47. package/out/zero/src/zero-cache-dev.js +11 -5
  48. package/out/zero/src/zero-cache-dev.js.map +1 -1
  49. package/out/zero/src/zero.js +6 -6
  50. package/out/zero-cache/src/auth/read-authorizer.d.ts +1 -1
  51. package/out/zero-cache/src/auth/read-authorizer.d.ts.map +1 -1
  52. package/out/zero-cache/src/auth/read-authorizer.js +1 -1
  53. package/out/zero-cache/src/auth/read-authorizer.js.map +1 -1
  54. package/out/zero-cache/src/auth/write-authorizer.d.ts.map +1 -1
  55. package/out/zero-cache/src/auth/write-authorizer.js +25 -17
  56. package/out/zero-cache/src/auth/write-authorizer.js.map +1 -1
  57. package/out/zero-cache/src/config/zero-config.d.ts +40 -4
  58. package/out/zero-cache/src/config/zero-config.d.ts.map +1 -1
  59. package/out/zero-cache/src/config/zero-config.js +58 -19
  60. package/out/zero-cache/src/config/zero-config.js.map +1 -1
  61. package/out/zero-cache/src/db/transaction-pool.d.ts.map +1 -1
  62. package/out/zero-cache/src/db/transaction-pool.js +3 -6
  63. package/out/zero-cache/src/db/transaction-pool.js.map +1 -1
  64. package/out/zero-cache/src/scripts/deploy-permissions.js +6 -3
  65. package/out/zero-cache/src/scripts/deploy-permissions.js.map +1 -1
  66. package/out/zero-cache/src/scripts/permissions.d.ts.map +1 -1
  67. package/out/zero-cache/src/scripts/permissions.js +11 -13
  68. package/out/zero-cache/src/scripts/permissions.js.map +1 -1
  69. package/out/zero-cache/src/server/anonymous-otel-start.d.ts +10 -1
  70. package/out/zero-cache/src/server/anonymous-otel-start.d.ts.map +1 -1
  71. package/out/zero-cache/src/server/anonymous-otel-start.js +34 -18
  72. package/out/zero-cache/src/server/anonymous-otel-start.js.map +1 -1
  73. package/out/zero-cache/src/server/change-streamer.d.ts.map +1 -1
  74. package/out/zero-cache/src/server/change-streamer.js +2 -8
  75. package/out/zero-cache/src/server/change-streamer.js.map +1 -1
  76. package/out/zero-cache/src/server/otel-diag-logger.d.ts.map +1 -1
  77. package/out/zero-cache/src/server/otel-diag-logger.js +1 -21
  78. package/out/zero-cache/src/server/otel-diag-logger.js.map +1 -1
  79. package/out/zero-cache/src/server/otel-start.d.ts.map +1 -1
  80. package/out/zero-cache/src/server/otel-start.js +1 -5
  81. package/out/zero-cache/src/server/otel-start.js.map +1 -1
  82. package/out/zero-cache/src/server/syncer.d.ts.map +1 -1
  83. package/out/zero-cache/src/server/syncer.js +7 -1
  84. package/out/zero-cache/src/server/syncer.js.map +1 -1
  85. package/out/zero-cache/src/services/analyze.d.ts +2 -2
  86. package/out/zero-cache/src/services/analyze.d.ts.map +1 -1
  87. package/out/zero-cache/src/services/analyze.js +55 -42
  88. package/out/zero-cache/src/services/analyze.js.map +1 -1
  89. package/out/zero-cache/src/services/change-source/pg/change-source.d.ts.map +1 -1
  90. package/out/zero-cache/src/services/change-source/pg/change-source.js +62 -42
  91. package/out/zero-cache/src/services/change-source/pg/change-source.js.map +1 -1
  92. package/out/zero-cache/src/services/change-source/pg/schema/published.d.ts.map +1 -1
  93. package/out/zero-cache/src/services/change-source/pg/schema/published.js +3 -2
  94. package/out/zero-cache/src/services/change-source/pg/schema/published.js.map +1 -1
  95. package/out/zero-cache/src/services/change-source/protocol/current/control.d.ts +1 -0
  96. package/out/zero-cache/src/services/change-source/protocol/current/control.d.ts.map +1 -1
  97. package/out/zero-cache/src/services/change-source/protocol/current/control.js +5 -1
  98. package/out/zero-cache/src/services/change-source/protocol/current/control.js.map +1 -1
  99. package/out/zero-cache/src/services/change-source/protocol/current/downstream.d.ts +2 -0
  100. package/out/zero-cache/src/services/change-source/protocol/current/downstream.d.ts.map +1 -1
  101. package/out/zero-cache/src/services/change-source/protocol/current/json.d.ts +8 -0
  102. package/out/zero-cache/src/services/change-source/protocol/current/json.d.ts.map +1 -0
  103. package/out/zero-cache/src/services/change-source/protocol/current/json.js +19 -0
  104. package/out/zero-cache/src/services/change-source/protocol/current/json.js.map +1 -0
  105. package/out/zero-cache/src/services/change-source/protocol/current.d.ts +1 -0
  106. package/out/zero-cache/src/services/change-source/protocol/current.d.ts.map +1 -1
  107. package/out/zero-cache/src/services/change-source/protocol/current.js +3 -0
  108. package/out/zero-cache/src/services/change-source/protocol/current.js.map +1 -1
  109. package/out/zero-cache/src/services/change-streamer/change-streamer-http.d.ts +0 -2
  110. package/out/zero-cache/src/services/change-streamer/change-streamer-http.d.ts.map +1 -1
  111. package/out/zero-cache/src/services/change-streamer/change-streamer-http.js +0 -5
  112. package/out/zero-cache/src/services/change-streamer/change-streamer-http.js.map +1 -1
  113. package/out/zero-cache/src/services/change-streamer/change-streamer-service.d.ts.map +1 -1
  114. package/out/zero-cache/src/services/change-streamer/change-streamer-service.js +8 -1
  115. package/out/zero-cache/src/services/change-streamer/change-streamer-service.js.map +1 -1
  116. package/out/zero-cache/src/services/change-streamer/storer.d.ts.map +1 -1
  117. package/out/zero-cache/src/services/change-streamer/storer.js +2 -3
  118. package/out/zero-cache/src/services/change-streamer/storer.js.map +1 -1
  119. package/out/zero-cache/src/services/http-service.d.ts +0 -1
  120. package/out/zero-cache/src/services/http-service.d.ts.map +1 -1
  121. package/out/zero-cache/src/services/http-service.js +0 -4
  122. package/out/zero-cache/src/services/http-service.js.map +1 -1
  123. package/out/zero-cache/src/services/litestream/commands.js +3 -2
  124. package/out/zero-cache/src/services/litestream/commands.js.map +1 -1
  125. package/out/zero-cache/src/services/mutagen/pusher.d.ts +4 -4
  126. package/out/zero-cache/src/services/replicator/replication-status.d.ts +2 -0
  127. package/out/zero-cache/src/services/replicator/replication-status.d.ts.map +1 -1
  128. package/out/zero-cache/src/services/replicator/replication-status.js +14 -1
  129. package/out/zero-cache/src/services/replicator/replication-status.js.map +1 -1
  130. package/out/zero-cache/src/services/run-ast.d.ts +1 -1
  131. package/out/zero-cache/src/services/run-ast.d.ts.map +1 -1
  132. package/out/zero-cache/src/services/run-ast.js +5 -1
  133. package/out/zero-cache/src/services/run-ast.js.map +1 -1
  134. package/out/zero-cache/src/services/view-syncer/active-users-gauge.d.ts +2 -1
  135. package/out/zero-cache/src/services/view-syncer/active-users-gauge.d.ts.map +1 -1
  136. package/out/zero-cache/src/services/view-syncer/active-users-gauge.js +26 -13
  137. package/out/zero-cache/src/services/view-syncer/active-users-gauge.js.map +1 -1
  138. package/out/zero-cache/src/services/view-syncer/cvr-purger.d.ts +1 -1
  139. package/out/zero-cache/src/services/view-syncer/cvr-purger.d.ts.map +1 -1
  140. package/out/zero-cache/src/services/view-syncer/cvr-purger.js +39 -15
  141. package/out/zero-cache/src/services/view-syncer/cvr-purger.js.map +1 -1
  142. package/out/zero-cache/src/services/view-syncer/cvr-store.d.ts +4 -1
  143. package/out/zero-cache/src/services/view-syncer/cvr-store.d.ts.map +1 -1
  144. package/out/zero-cache/src/services/view-syncer/cvr-store.js +31 -9
  145. package/out/zero-cache/src/services/view-syncer/cvr-store.js.map +1 -1
  146. package/out/zero-cache/src/services/view-syncer/cvr.d.ts +3 -0
  147. package/out/zero-cache/src/services/view-syncer/cvr.d.ts.map +1 -1
  148. package/out/zero-cache/src/services/view-syncer/cvr.js +11 -0
  149. package/out/zero-cache/src/services/view-syncer/cvr.js.map +1 -1
  150. package/out/zero-cache/src/services/view-syncer/inspect-handler.js +1 -1
  151. package/out/zero-cache/src/services/view-syncer/inspect-handler.js.map +1 -1
  152. package/out/zero-cache/src/services/view-syncer/pipeline-driver.d.ts +11 -11
  153. package/out/zero-cache/src/services/view-syncer/pipeline-driver.d.ts.map +1 -1
  154. package/out/zero-cache/src/services/view-syncer/pipeline-driver.js +81 -27
  155. package/out/zero-cache/src/services/view-syncer/pipeline-driver.js.map +1 -1
  156. package/out/zero-cache/src/services/view-syncer/schema/cvr.d.ts +1 -0
  157. package/out/zero-cache/src/services/view-syncer/schema/cvr.d.ts.map +1 -1
  158. package/out/zero-cache/src/services/view-syncer/schema/cvr.js +23 -10
  159. package/out/zero-cache/src/services/view-syncer/schema/cvr.js.map +1 -1
  160. package/out/zero-cache/src/services/view-syncer/schema/init.d.ts.map +1 -1
  161. package/out/zero-cache/src/services/view-syncer/schema/init.js +31 -1
  162. package/out/zero-cache/src/services/view-syncer/schema/init.js.map +1 -1
  163. package/out/zero-cache/src/services/view-syncer/snapshotter.d.ts +2 -2
  164. package/out/zero-cache/src/services/view-syncer/snapshotter.d.ts.map +1 -1
  165. package/out/zero-cache/src/services/view-syncer/snapshotter.js +19 -4
  166. package/out/zero-cache/src/services/view-syncer/snapshotter.js.map +1 -1
  167. package/out/zero-cache/src/services/view-syncer/view-syncer.d.ts +2 -1
  168. package/out/zero-cache/src/services/view-syncer/view-syncer.d.ts.map +1 -1
  169. package/out/zero-cache/src/services/view-syncer/view-syncer.js +31 -29
  170. package/out/zero-cache/src/services/view-syncer/view-syncer.js.map +1 -1
  171. package/out/zero-cache/src/workers/connect-params.d.ts +1 -0
  172. package/out/zero-cache/src/workers/connect-params.d.ts.map +1 -1
  173. package/out/zero-cache/src/workers/connect-params.js +2 -0
  174. package/out/zero-cache/src/workers/connect-params.js.map +1 -1
  175. package/out/zero-cache/src/workers/syncer-ws-message-handler.d.ts.map +1 -1
  176. package/out/zero-cache/src/workers/syncer-ws-message-handler.js +2 -0
  177. package/out/zero-cache/src/workers/syncer-ws-message-handler.js.map +1 -1
  178. package/out/zero-client/src/client/bindings.d.ts +12 -42
  179. package/out/zero-client/src/client/bindings.d.ts.map +1 -1
  180. package/out/zero-client/src/client/connection-manager.d.ts +3 -3
  181. package/out/zero-client/src/client/connection-manager.d.ts.map +1 -1
  182. package/out/zero-client/src/client/connection-manager.js.map +1 -1
  183. package/out/zero-client/src/client/connection.d.ts.map +1 -1
  184. package/out/zero-client/src/client/connection.js +8 -1
  185. package/out/zero-client/src/client/connection.js.map +1 -1
  186. package/out/zero-client/src/client/crud-impl.d.ts +11 -0
  187. package/out/zero-client/src/client/crud-impl.d.ts.map +1 -0
  188. package/out/zero-client/src/client/crud-impl.js +102 -0
  189. package/out/zero-client/src/client/crud-impl.js.map +1 -0
  190. package/out/zero-client/src/client/crud.d.ts +10 -42
  191. package/out/zero-client/src/client/crud.d.ts.map +1 -1
  192. package/out/zero-client/src/client/crud.js +28 -110
  193. package/out/zero-client/src/client/crud.js.map +1 -1
  194. package/out/zero-client/src/client/custom.d.ts +11 -6
  195. package/out/zero-client/src/client/custom.d.ts.map +1 -1
  196. package/out/zero-client/src/client/custom.js +12 -53
  197. package/out/zero-client/src/client/custom.js.map +1 -1
  198. package/out/zero-client/src/client/delete-clients-manager.d.ts +1 -1
  199. package/out/zero-client/src/client/delete-clients-manager.d.ts.map +1 -1
  200. package/out/zero-client/src/client/delete-clients-manager.js +30 -3
  201. package/out/zero-client/src/client/delete-clients-manager.js.map +1 -1
  202. package/out/zero-client/src/client/error.d.ts +6 -1
  203. package/out/zero-client/src/client/error.d.ts.map +1 -1
  204. package/out/zero-client/src/client/error.js +2 -2
  205. package/out/zero-client/src/client/error.js.map +1 -1
  206. package/out/zero-client/src/client/ivm-branch.d.ts.map +1 -1
  207. package/out/zero-client/src/client/ivm-branch.js +20 -13
  208. package/out/zero-client/src/client/ivm-branch.js.map +1 -1
  209. package/out/zero-client/src/client/make-mutate-property.d.ts +6 -9
  210. package/out/zero-client/src/client/make-mutate-property.d.ts.map +1 -1
  211. package/out/zero-client/src/client/make-mutate-property.js +5 -10
  212. package/out/zero-client/src/client/make-mutate-property.js.map +1 -1
  213. package/out/zero-client/src/client/make-replicache-mutators.d.ts +2 -2
  214. package/out/zero-client/src/client/make-replicache-mutators.d.ts.map +1 -1
  215. package/out/zero-client/src/client/make-replicache-mutators.js +16 -11
  216. package/out/zero-client/src/client/make-replicache-mutators.js.map +1 -1
  217. package/out/zero-client/src/client/mutator-proxy.d.ts +3 -2
  218. package/out/zero-client/src/client/mutator-proxy.d.ts.map +1 -1
  219. package/out/zero-client/src/client/mutator-proxy.js +16 -5
  220. package/out/zero-client/src/client/mutator-proxy.js.map +1 -1
  221. package/out/zero-client/src/client/options.d.ts +5 -4
  222. package/out/zero-client/src/client/options.d.ts.map +1 -1
  223. package/out/zero-client/src/client/options.js.map +1 -1
  224. package/out/zero-client/src/client/version.js +1 -1
  225. package/out/zero-client/src/client/zero.d.ts +27 -13
  226. package/out/zero-client/src/client/zero.d.ts.map +1 -1
  227. package/out/zero-client/src/client/zero.js +81 -40
  228. package/out/zero-client/src/client/zero.js.map +1 -1
  229. package/out/zero-client/src/mod.d.ts +17 -16
  230. package/out/zero-client/src/mod.d.ts.map +1 -1
  231. package/out/zero-events/src/status.d.ts +1 -1
  232. package/out/zero-events/src/status.d.ts.map +1 -1
  233. package/out/zero-protocol/src/analyze-query-result.d.ts +2 -2
  234. package/out/zero-protocol/src/analyze-query-result.js +2 -2
  235. package/out/zero-protocol/src/analyze-query-result.js.map +1 -1
  236. package/out/zero-protocol/src/down.d.ts +2 -2
  237. package/out/zero-protocol/src/inspect-down.d.ts +6 -6
  238. package/out/zero-protocol/src/inspect-up.d.ts +4 -4
  239. package/out/zero-protocol/src/inspect-up.js +1 -1
  240. package/out/zero-protocol/src/inspect-up.js.map +1 -1
  241. package/out/zero-protocol/src/protocol-version.d.ts +1 -1
  242. package/out/zero-protocol/src/protocol-version.d.ts.map +1 -1
  243. package/out/zero-protocol/src/protocol-version.js +1 -1
  244. package/out/zero-protocol/src/protocol-version.js.map +1 -1
  245. package/out/zero-protocol/src/up.d.ts +1 -1
  246. package/out/zero-react/src/bindings.d.ts +2 -0
  247. package/out/zero-react/src/bindings.d.ts.map +1 -0
  248. package/out/zero-react/src/mod.d.ts +1 -10
  249. package/out/zero-react/src/mod.d.ts.map +1 -1
  250. package/out/zero-react/src/{use-zero-connection-state.d.ts → use-connection-state.d.ts} +3 -3
  251. package/out/zero-react/src/use-connection-state.d.ts.map +1 -0
  252. package/out/zero-react/src/{use-zero-connection-state.js → use-connection-state.js} +3 -3
  253. package/out/zero-react/src/use-connection-state.js.map +1 -0
  254. package/out/zero-react/src/use-query.d.ts +4 -10
  255. package/out/zero-react/src/use-query.d.ts.map +1 -1
  256. package/out/zero-react/src/use-query.js +26 -21
  257. package/out/zero-react/src/use-query.js.map +1 -1
  258. package/out/zero-react/src/use-zero-online.d.ts +1 -1
  259. package/out/zero-react/src/use-zero-online.js.map +1 -1
  260. package/out/zero-react/src/zero-provider.d.ts +17 -10
  261. package/out/zero-react/src/zero-provider.d.ts.map +1 -1
  262. package/out/zero-react/src/zero-provider.js +19 -1
  263. package/out/zero-react/src/zero-provider.js.map +1 -1
  264. package/out/zero-react/src/zero.d.ts +2 -0
  265. package/out/zero-react/src/zero.d.ts.map +1 -0
  266. package/out/zero-schema/src/compiled-permissions.d.ts +22 -2
  267. package/out/zero-schema/src/compiled-permissions.d.ts.map +1 -1
  268. package/out/zero-schema/src/compiled-permissions.js +7 -6
  269. package/out/zero-schema/src/compiled-permissions.js.map +1 -1
  270. package/out/zero-schema/src/permissions.d.ts +11 -8
  271. package/out/zero-schema/src/permissions.d.ts.map +1 -1
  272. package/out/zero-schema/src/permissions.js +2 -8
  273. package/out/zero-schema/src/permissions.js.map +1 -1
  274. package/out/zero-schema/src/schema-config.d.ts +0 -5
  275. package/out/zero-schema/src/schema-config.d.ts.map +1 -1
  276. package/out/zero-schema/src/schema-config.js +1 -1
  277. package/out/zero-schema/src/schema-config.js.map +1 -1
  278. package/out/zero-server/src/custom.d.ts +41 -14
  279. package/out/zero-server/src/custom.d.ts.map +1 -1
  280. package/out/zero-server/src/custom.js +129 -37
  281. package/out/zero-server/src/custom.js.map +1 -1
  282. package/out/zero-server/src/mod.d.ts +1 -1
  283. package/out/zero-server/src/mod.d.ts.map +1 -1
  284. package/out/zero-server/src/process-mutations.d.ts +10 -6
  285. package/out/zero-server/src/process-mutations.d.ts.map +1 -1
  286. package/out/zero-server/src/process-mutations.js +9 -18
  287. package/out/zero-server/src/process-mutations.js.map +1 -1
  288. package/out/zero-server/src/push-processor.d.ts.map +1 -1
  289. package/out/zero-server/src/push-processor.js +10 -8
  290. package/out/zero-server/src/push-processor.js.map +1 -1
  291. package/out/zero-server/src/queries/process-queries.d.ts +14 -2
  292. package/out/zero-server/src/queries/process-queries.d.ts.map +1 -1
  293. package/out/zero-server/src/queries/process-queries.js +18 -15
  294. package/out/zero-server/src/queries/process-queries.js.map +1 -1
  295. package/out/zero-server/src/zql-database.d.ts +6 -6
  296. package/out/zero-server/src/zql-database.d.ts.map +1 -1
  297. package/out/zero-server/src/zql-database.js +5 -17
  298. package/out/zero-server/src/zql-database.js.map +1 -1
  299. package/out/zero-solid/src/bindings.d.ts +2 -0
  300. package/out/zero-solid/src/bindings.d.ts.map +1 -0
  301. package/out/zero-solid/src/mod.d.ts +1 -8
  302. package/out/zero-solid/src/mod.d.ts.map +1 -1
  303. package/out/zero-solid/src/solid-view.d.ts +3 -5
  304. package/out/zero-solid/src/solid-view.d.ts.map +1 -1
  305. package/out/zero-solid/src/solid-view.js +9 -6
  306. package/out/zero-solid/src/solid-view.js.map +1 -1
  307. package/out/zero-solid/src/{use-zero-connection-state.d.ts → use-connection-state.d.ts} +3 -3
  308. package/out/zero-solid/src/use-connection-state.d.ts.map +1 -0
  309. package/out/zero-solid/src/{use-zero-connection-state.js → use-connection-state.js} +3 -3
  310. package/out/zero-solid/src/use-connection-state.js.map +1 -0
  311. package/out/zero-solid/src/use-query.d.ts +3 -6
  312. package/out/zero-solid/src/use-query.d.ts.map +1 -1
  313. package/out/zero-solid/src/use-query.js +44 -11
  314. package/out/zero-solid/src/use-query.js.map +1 -1
  315. package/out/zero-solid/src/use-zero-online.d.ts +1 -1
  316. package/out/zero-solid/src/use-zero-online.js.map +1 -1
  317. package/out/zero-solid/src/use-zero.d.ts +19 -9
  318. package/out/zero-solid/src/use-zero.d.ts.map +1 -1
  319. package/out/zero-solid/src/use-zero.js +17 -1
  320. package/out/zero-solid/src/use-zero.js.map +1 -1
  321. package/out/zero-solid/src/zero.d.ts +2 -0
  322. package/out/zero-solid/src/zero.d.ts.map +1 -0
  323. package/out/zero-types/src/default-types.d.ts +38 -0
  324. package/out/zero-types/src/default-types.d.ts.map +1 -0
  325. package/out/zero-types/src/schema.d.ts +4 -4
  326. package/out/zql/src/builder/builder.d.ts.map +1 -1
  327. package/out/zql/src/builder/builder.js +1 -13
  328. package/out/zql/src/builder/builder.js.map +1 -1
  329. package/out/zql/src/error.js +1 -10
  330. package/out/zql/src/error.js.map +1 -1
  331. package/out/zql/src/ivm/array-view.d.ts +2 -2
  332. package/out/zql/src/ivm/array-view.d.ts.map +1 -1
  333. package/out/zql/src/ivm/array-view.js +4 -1
  334. package/out/zql/src/ivm/array-view.js.map +1 -1
  335. package/out/zql/src/ivm/data.d.ts +7 -2
  336. package/out/zql/src/ivm/data.d.ts.map +1 -1
  337. package/out/zql/src/ivm/data.js +0 -8
  338. package/out/zql/src/ivm/data.js.map +1 -1
  339. package/out/zql/src/ivm/exists.d.ts +6 -4
  340. package/out/zql/src/ivm/exists.d.ts.map +1 -1
  341. package/out/zql/src/ivm/exists.js +60 -91
  342. package/out/zql/src/ivm/exists.js.map +1 -1
  343. package/out/zql/src/ivm/fan-in.d.ts +5 -3
  344. package/out/zql/src/ivm/fan-in.d.ts.map +1 -1
  345. package/out/zql/src/ivm/fan-in.js +12 -5
  346. package/out/zql/src/ivm/fan-in.js.map +1 -1
  347. package/out/zql/src/ivm/fan-out.d.ts +4 -2
  348. package/out/zql/src/ivm/fan-out.d.ts.map +1 -1
  349. package/out/zql/src/ivm/fan-out.js +16 -6
  350. package/out/zql/src/ivm/fan-out.js.map +1 -1
  351. package/out/zql/src/ivm/filter-operators.d.ts +13 -11
  352. package/out/zql/src/ivm/filter-operators.d.ts.map +1 -1
  353. package/out/zql/src/ivm/filter-operators.js +27 -24
  354. package/out/zql/src/ivm/filter-operators.js.map +1 -1
  355. package/out/zql/src/ivm/filter-push.d.ts +2 -1
  356. package/out/zql/src/ivm/filter-push.d.ts.map +1 -1
  357. package/out/zql/src/ivm/filter-push.js +5 -5
  358. package/out/zql/src/ivm/filter-push.js.map +1 -1
  359. package/out/zql/src/ivm/filter.d.ts +4 -2
  360. package/out/zql/src/ivm/filter.d.ts.map +1 -1
  361. package/out/zql/src/ivm/filter.js +10 -4
  362. package/out/zql/src/ivm/filter.js.map +1 -1
  363. package/out/zql/src/ivm/flipped-join.d.ts +1 -2
  364. package/out/zql/src/ivm/flipped-join.d.ts.map +1 -1
  365. package/out/zql/src/ivm/flipped-join.js +133 -103
  366. package/out/zql/src/ivm/flipped-join.js.map +1 -1
  367. package/out/zql/src/ivm/join-utils.d.ts +9 -2
  368. package/out/zql/src/ivm/join-utils.d.ts.map +1 -1
  369. package/out/zql/src/ivm/join-utils.js +20 -0
  370. package/out/zql/src/ivm/join-utils.js.map +1 -1
  371. package/out/zql/src/ivm/join.d.ts +3 -16
  372. package/out/zql/src/ivm/join.d.ts.map +1 -1
  373. package/out/zql/src/ivm/join.js +62 -128
  374. package/out/zql/src/ivm/join.js.map +1 -1
  375. package/out/zql/src/ivm/maybe-split-and-push-edit-change.d.ts +1 -1
  376. package/out/zql/src/ivm/maybe-split-and-push-edit-change.d.ts.map +1 -1
  377. package/out/zql/src/ivm/maybe-split-and-push-edit-change.js +4 -4
  378. package/out/zql/src/ivm/maybe-split-and-push-edit-change.js.map +1 -1
  379. package/out/zql/src/ivm/memory-source.d.ts +7 -6
  380. package/out/zql/src/ivm/memory-source.d.ts.map +1 -1
  381. package/out/zql/src/ivm/memory-source.js +39 -28
  382. package/out/zql/src/ivm/memory-source.js.map +1 -1
  383. package/out/zql/src/ivm/operator.d.ts +15 -12
  384. package/out/zql/src/ivm/operator.d.ts.map +1 -1
  385. package/out/zql/src/ivm/operator.js +8 -0
  386. package/out/zql/src/ivm/operator.js.map +1 -1
  387. package/out/zql/src/ivm/push-accumulated.d.ts +2 -2
  388. package/out/zql/src/ivm/push-accumulated.d.ts.map +1 -1
  389. package/out/zql/src/ivm/push-accumulated.js +8 -8
  390. package/out/zql/src/ivm/push-accumulated.js.map +1 -1
  391. package/out/zql/src/ivm/skip.d.ts +2 -3
  392. package/out/zql/src/ivm/skip.d.ts.map +1 -1
  393. package/out/zql/src/ivm/skip.js +14 -11
  394. package/out/zql/src/ivm/skip.js.map +1 -1
  395. package/out/zql/src/ivm/source.d.ts +15 -7
  396. package/out/zql/src/ivm/source.d.ts.map +1 -1
  397. package/out/zql/src/ivm/stream.d.ts +2 -0
  398. package/out/zql/src/ivm/stream.d.ts.map +1 -1
  399. package/out/zql/src/ivm/stream.js +5 -14
  400. package/out/zql/src/ivm/stream.js.map +1 -1
  401. package/out/zql/src/ivm/take.d.ts +2 -3
  402. package/out/zql/src/ivm/take.d.ts.map +1 -1
  403. package/out/zql/src/ivm/take.js +168 -140
  404. package/out/zql/src/ivm/take.js.map +1 -1
  405. package/out/zql/src/ivm/union-fan-in.d.ts +4 -4
  406. package/out/zql/src/ivm/union-fan-in.d.ts.map +1 -1
  407. package/out/zql/src/ivm/union-fan-in.js +74 -15
  408. package/out/zql/src/ivm/union-fan-in.js.map +1 -1
  409. package/out/zql/src/ivm/union-fan-out.d.ts +2 -3
  410. package/out/zql/src/ivm/union-fan-out.d.ts.map +1 -1
  411. package/out/zql/src/ivm/union-fan-out.js +3 -6
  412. package/out/zql/src/ivm/union-fan-out.js.map +1 -1
  413. package/out/zql/src/ivm/view-apply-change.d.ts.map +1 -1
  414. package/out/zql/src/ivm/view-apply-change.js +4 -4
  415. package/out/zql/src/ivm/view-apply-change.js.map +1 -1
  416. package/out/zql/src/ivm/view.d.ts +2 -2
  417. package/out/zql/src/ivm/view.d.ts.map +1 -1
  418. package/out/zql/src/mutate/crud.d.ts +116 -0
  419. package/out/zql/src/mutate/crud.d.ts.map +1 -0
  420. package/out/zql/src/mutate/crud.js +41 -0
  421. package/out/zql/src/mutate/crud.js.map +1 -0
  422. package/out/zql/src/mutate/custom.d.ts +24 -62
  423. package/out/zql/src/mutate/custom.d.ts.map +1 -1
  424. package/out/zql/src/mutate/custom.js +1 -5
  425. package/out/zql/src/mutate/custom.js.map +1 -1
  426. package/out/zql/src/mutate/mutator-registry.d.ts +43 -73
  427. package/out/zql/src/mutate/mutator-registry.d.ts.map +1 -1
  428. package/out/zql/src/mutate/mutator-registry.js +25 -34
  429. package/out/zql/src/mutate/mutator-registry.js.map +1 -1
  430. package/out/zql/src/mutate/mutator.d.ts +60 -64
  431. package/out/zql/src/mutate/mutator.d.ts.map +1 -1
  432. package/out/zql/src/mutate/mutator.js +8 -9
  433. package/out/zql/src/mutate/mutator.js.map +1 -1
  434. package/out/zql/src/planner/planner-builder.d.ts +2 -1
  435. package/out/zql/src/planner/planner-builder.d.ts.map +1 -1
  436. package/out/zql/src/planner/planner-builder.js +5 -5
  437. package/out/zql/src/planner/planner-builder.js.map +1 -1
  438. package/out/zql/src/planner/planner-debug.d.ts +3 -3
  439. package/out/zql/src/planner/planner-debug.js.map +1 -1
  440. package/out/zql/src/planner/planner-graph.d.ts +3 -1
  441. package/out/zql/src/planner/planner-graph.d.ts.map +1 -1
  442. package/out/zql/src/planner/planner-graph.js +5 -5
  443. package/out/zql/src/planner/planner-graph.js.map +1 -1
  444. package/out/zql/src/planner/planner-join.d.ts.map +1 -1
  445. package/out/zql/src/planner/planner-join.js +3 -1
  446. package/out/zql/src/planner/planner-join.js.map +1 -1
  447. package/out/zql/src/query/create-builder.d.ts +4 -1
  448. package/out/zql/src/query/create-builder.d.ts.map +1 -1
  449. package/out/zql/src/query/create-builder.js +24 -36
  450. package/out/zql/src/query/create-builder.js.map +1 -1
  451. package/out/zql/src/query/expression.d.ts +5 -5
  452. package/out/zql/src/query/expression.d.ts.map +1 -1
  453. package/out/zql/src/query/expression.js.map +1 -1
  454. package/out/zql/src/query/measure-push-operator.d.ts +2 -3
  455. package/out/zql/src/query/measure-push-operator.d.ts.map +1 -1
  456. package/out/zql/src/query/measure-push-operator.js +2 -5
  457. package/out/zql/src/query/measure-push-operator.js.map +1 -1
  458. package/out/zql/src/query/query-delegate-base.d.ts +12 -6
  459. package/out/zql/src/query/query-delegate-base.d.ts.map +1 -1
  460. package/out/zql/src/query/query-delegate-base.js +132 -2
  461. package/out/zql/src/query/query-delegate-base.js.map +1 -1
  462. package/out/zql/src/query/query-delegate.d.ts +6 -6
  463. package/out/zql/src/query/query-delegate.d.ts.map +1 -1
  464. package/out/zql/src/query/query-impl.d.ts +27 -28
  465. package/out/zql/src/query/query-impl.d.ts.map +1 -1
  466. package/out/zql/src/query/query-impl.js +41 -168
  467. package/out/zql/src/query/query-impl.js.map +1 -1
  468. package/out/zql/src/query/query-internals.d.ts +6 -6
  469. package/out/zql/src/query/query-internals.d.ts.map +1 -1
  470. package/out/zql/src/query/query-internals.js +2 -2
  471. package/out/zql/src/query/query-internals.js.map +1 -1
  472. package/out/zql/src/query/query-registry.d.ts +108 -122
  473. package/out/zql/src/query/query-registry.d.ts.map +1 -1
  474. package/out/zql/src/query/query-registry.js +43 -53
  475. package/out/zql/src/query/query-registry.js.map +1 -1
  476. package/out/zql/src/query/query.d.ts +63 -37
  477. package/out/zql/src/query/query.d.ts.map +1 -1
  478. package/out/zql/src/query/runnable-query-impl.d.ts +22 -0
  479. package/out/zql/src/query/runnable-query-impl.d.ts.map +1 -0
  480. package/out/zql/src/query/runnable-query-impl.js +60 -0
  481. package/out/zql/src/query/runnable-query-impl.js.map +1 -0
  482. package/out/zql/src/query/schema-query.d.ts +2 -1
  483. package/out/zql/src/query/schema-query.d.ts.map +1 -1
  484. package/out/zql/src/query/static-query.d.ts +2 -15
  485. package/out/zql/src/query/static-query.d.ts.map +1 -1
  486. package/out/zql/src/query/static-query.js +10 -37
  487. package/out/zql/src/query/static-query.js.map +1 -1
  488. package/out/zqlite/src/internal/sql-inline.d.ts +13 -0
  489. package/out/zqlite/src/internal/sql-inline.d.ts.map +1 -0
  490. package/out/zqlite/src/internal/sql-inline.js +45 -0
  491. package/out/zqlite/src/internal/sql-inline.js.map +1 -0
  492. package/out/zqlite/src/sqlite-cost-model.d.ts.map +1 -1
  493. package/out/zqlite/src/sqlite-cost-model.js +2 -2
  494. package/out/zqlite/src/sqlite-cost-model.js.map +1 -1
  495. package/out/zqlite/src/table-source.d.ts +10 -3
  496. package/out/zqlite/src/table-source.d.ts.map +1 -1
  497. package/out/zqlite/src/table-source.js +42 -23
  498. package/out/zqlite/src/table-source.js.map +1 -1
  499. package/package.json +9 -5
  500. package/out/zero-client/src/client/bindings.js +0 -33
  501. package/out/zero-client/src/client/bindings.js.map +0 -1
  502. package/out/zero-react/src/components/inspector.d.ts +0 -9
  503. package/out/zero-react/src/components/inspector.d.ts.map +0 -1
  504. package/out/zero-react/src/components/inspector.js +0 -38
  505. package/out/zero-react/src/components/inspector.js.map +0 -1
  506. package/out/zero-react/src/components/mark-icon.d.ts +0 -3
  507. package/out/zero-react/src/components/mark-icon.d.ts.map +0 -1
  508. package/out/zero-react/src/components/mark-icon.js +0 -28
  509. package/out/zero-react/src/components/mark-icon.js.map +0 -1
  510. package/out/zero-react/src/components/zero-inspector.d.ts +0 -8
  511. package/out/zero-react/src/components/zero-inspector.d.ts.map +0 -1
  512. package/out/zero-react/src/components/zero-inspector.js +0 -44
  513. package/out/zero-react/src/components/zero-inspector.js.map +0 -1
  514. package/out/zero-react/src/use-zero-connection-state.d.ts.map +0 -1
  515. package/out/zero-react/src/use-zero-connection-state.js.map +0 -1
  516. package/out/zero-solid/src/use-zero-connection-state.d.ts.map +0 -1
  517. package/out/zero-solid/src/use-zero-connection-state.js.map +0 -1
@@ -1,5 +1,4 @@
1
1
  import { assert } from "../../../shared/src/asserts.js";
2
- import { mergeIterables } from "../../../shared/src/iterables.js";
3
2
  import { throwOutput } from "./operator.js";
4
3
  import { pushAccumulatedChanges, makeAddEmptyRelationships, mergeRelationships } from "./push-accumulated.js";
5
4
  import { first } from "./stream.js";
@@ -63,9 +62,6 @@ class UnionFanIn {
63
62
  this.#schema = schema;
64
63
  this.#inputs = inputs;
65
64
  }
66
- cleanup(_req) {
67
- return [];
68
- }
69
65
  destroy() {
70
66
  for (const input of this.#inputs) {
71
67
  input.destroy();
@@ -73,18 +69,17 @@ class UnionFanIn {
73
69
  }
74
70
  fetch(req) {
75
71
  const iterables = this.#inputs.map((input) => input.fetch(req));
76
- return mergeIterables(
72
+ return mergeFetches(
77
73
  iterables,
78
- (l, r) => this.#schema.compareRows(l.row, r.row),
79
- true
74
+ (l, r) => this.#schema.compareRows(l.row, r.row)
80
75
  );
81
76
  }
82
77
  getSchema() {
83
78
  return this.#schema;
84
79
  }
85
- push(change, pusher) {
80
+ *push(change, pusher) {
86
81
  if (!this.#fanOutPushStarted) {
87
- this.#pushInternalChange(change, pusher);
82
+ yield* this.#pushInternalChange(change, pusher);
88
83
  } else {
89
84
  this.#accumulatedPushes.push(change);
90
85
  }
@@ -110,9 +105,9 @@ class UnionFanIn {
110
105
  * 4. Edits will always come through as child changes as flip join will flip them into children.
111
106
  * An edit that would result in a remove or add will have been split into an add/remove pair rather than being an edit.
112
107
  */
113
- #pushInternalChange(change, pusher) {
108
+ *#pushInternalChange(change, pusher) {
114
109
  if (change.type === "child") {
115
- this.#output.push(change, this);
110
+ yield* this.#output.push(change, this);
116
111
  return;
117
112
  }
118
113
  assert(change.type === "add" || change.type === "remove");
@@ -134,13 +129,13 @@ class UnionFanIn {
134
129
  }
135
130
  }
136
131
  assert(hadMatch, "Pusher was not one of the inputs to union-fan-in!");
137
- this.#output.push(change, this);
132
+ yield* this.#output.push(change, this);
138
133
  }
139
134
  fanOutStartedPushing() {
140
135
  assert(this.#fanOutPushStarted === false);
141
136
  this.#fanOutPushStarted = true;
142
137
  }
143
- fanOutDonePushing(fanOutChangeType) {
138
+ *fanOutDonePushing(fanOutChangeType) {
144
139
  assert(this.#fanOutPushStarted);
145
140
  this.#fanOutPushStarted = false;
146
141
  if (this.#inputs.length === 0) {
@@ -149,7 +144,7 @@ class UnionFanIn {
149
144
  if (this.#accumulatedPushes.length === 0) {
150
145
  return;
151
146
  }
152
- pushAccumulatedChanges(
147
+ yield* pushAccumulatedChanges(
153
148
  this.#accumulatedPushes,
154
149
  this.#output,
155
150
  this,
@@ -162,7 +157,71 @@ class UnionFanIn {
162
157
  this.#output = output;
163
158
  }
164
159
  }
160
+ function* mergeFetches(fetches, comparator) {
161
+ const iterators = fetches.map((i) => i[Symbol.iterator]());
162
+ let threw = false;
163
+ try {
164
+ const current = [];
165
+ let lastNodeYielded;
166
+ for (let i = 0; i < iterators.length; i++) {
167
+ const iter = iterators[i];
168
+ let result = iter.next();
169
+ while (!result.done && result.value === "yield") {
170
+ yield result.value;
171
+ result = iter.next();
172
+ }
173
+ current[i] = result.done ? null : result.value;
174
+ }
175
+ while (current.some((c) => c !== null)) {
176
+ const min = current.reduce(
177
+ (acc, c, i) => {
178
+ if (c === null) {
179
+ return acc;
180
+ }
181
+ if (acc === void 0 || comparator(c, acc[0]) < 0) {
182
+ return [c, i];
183
+ }
184
+ return acc;
185
+ },
186
+ void 0
187
+ );
188
+ assert(min !== void 0, "min is undefined");
189
+ const [minNode, minIndex] = min;
190
+ const iter = iterators[minIndex];
191
+ let result = iter.next();
192
+ while (!result.done && result.value === "yield") {
193
+ yield result.value;
194
+ result = iter.next();
195
+ }
196
+ current[minIndex] = result.done ? null : result.value;
197
+ if (lastNodeYielded !== void 0 && comparator(lastNodeYielded, minNode) === 0) {
198
+ continue;
199
+ }
200
+ lastNodeYielded = minNode;
201
+ yield minNode;
202
+ }
203
+ } catch (e) {
204
+ threw = true;
205
+ for (const iter of iterators) {
206
+ try {
207
+ iter.throw?.(e);
208
+ } catch (_cleanupError) {
209
+ }
210
+ }
211
+ throw e;
212
+ } finally {
213
+ if (!threw) {
214
+ for (const iter of iterators) {
215
+ try {
216
+ iter.return?.();
217
+ } catch (_cleanupError) {
218
+ }
219
+ }
220
+ }
221
+ }
222
+ }
165
223
  export {
166
- UnionFanIn
224
+ UnionFanIn,
225
+ mergeFetches
167
226
  };
168
227
  //# sourceMappingURL=union-fan-in.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"union-fan-in.js","sources":["../../../../../zql/src/ivm/union-fan-in.ts"],"sourcesContent":["import {assert} from '../../../shared/src/asserts.ts';\nimport {mergeIterables} from '../../../shared/src/iterables.ts';\nimport type {Writable} from '../../../shared/src/writable.ts';\nimport type {Change} from './change.ts';\nimport type {Constraint} from './constraint.ts';\nimport type {Node} from './data.ts';\nimport {\n throwOutput,\n type FetchRequest,\n type Input,\n type InputBase,\n type Operator,\n type Output,\n} from './operator.ts';\nimport {\n makeAddEmptyRelationships,\n mergeRelationships,\n pushAccumulatedChanges,\n} from './push-accumulated.ts';\nimport type {SourceSchema} from './schema.ts';\nimport {first, type Stream} from './stream.ts';\nimport type {UnionFanOut} from './union-fan-out.ts';\n\nexport class UnionFanIn implements Operator {\n readonly #inputs: readonly Input[];\n readonly #schema: SourceSchema;\n #fanOutPushStarted: boolean = false;\n #output: Output = throwOutput;\n #accumulatedPushes: Change[] = [];\n\n constructor(fanOut: UnionFanOut, inputs: Input[]) {\n this.#inputs = inputs;\n const fanOutSchema = fanOut.getSchema();\n fanOut.setFanIn(this);\n\n const schema: Writable<SourceSchema> = {\n tableName: fanOutSchema.tableName,\n columns: fanOutSchema.columns,\n primaryKey: fanOutSchema.primaryKey,\n relationships: {\n ...fanOutSchema.relationships,\n },\n isHidden: fanOutSchema.isHidden,\n system: fanOutSchema.system,\n compareRows: fanOutSchema.compareRows,\n sort: fanOutSchema.sort,\n };\n\n // now go through inputs and merge relationships\n const relationshipsFromBranches: Set<string> = new Set();\n for (const input of inputs) {\n const inputSchema = input.getSchema();\n assert(\n schema.tableName === inputSchema.tableName,\n `Table name mismatch in union fan-in: ${schema.tableName} !== ${inputSchema.tableName}`,\n );\n assert(\n schema.primaryKey === inputSchema.primaryKey,\n `Primary key mismatch in union fan-in`,\n );\n assert(\n schema.system === inputSchema.system,\n `System mismatch in union fan-in: ${schema.system} !== ${inputSchema.system}`,\n );\n assert(\n schema.compareRows === inputSchema.compareRows,\n `compareRows mismatch in union fan-in`,\n );\n assert(schema.sort === inputSchema.sort, `Sort mismatch in union fan-in`);\n\n for (const [relName, relSchema] of Object.entries(\n inputSchema.relationships,\n )) {\n if (relName in fanOutSchema.relationships) {\n continue;\n }\n\n // All branches will have unique relationship names except for relationships\n // that come in from `fanOut`.\n assert(\n !relationshipsFromBranches.has(relName),\n `Relationship ${relName} exists in multiple upstream inputs to union fan-in`,\n );\n schema.relationships[relName] = relSchema;\n relationshipsFromBranches.add(relName);\n }\n\n input.setOutput(this);\n }\n\n this.#schema = schema;\n this.#inputs = inputs;\n }\n\n cleanup(_req: FetchRequest): Stream<Node> {\n // Cleanup is going away. Not implemented.\n return [];\n }\n\n destroy(): void {\n for (const input of this.#inputs) {\n input.destroy();\n }\n }\n\n fetch(req: FetchRequest): Stream<Node> {\n const iterables = this.#inputs.map(input => input.fetch(req));\n return mergeIterables(\n iterables,\n (l, r) => this.#schema.compareRows(l.row, r.row),\n true,\n );\n }\n\n getSchema(): SourceSchema {\n return this.#schema;\n }\n\n push(change: Change, pusher: InputBase): void {\n if (!this.#fanOutPushStarted) {\n this.#pushInternalChange(change, pusher);\n } else {\n this.#accumulatedPushes.push(change);\n }\n }\n\n /**\n * An internal change means that a change was received inside the fan-out/fan-in sub-graph.\n *\n * These changes always come from children of a flip-join as no other push generating operators\n * currently exist between union-fan-in and union-fan-out. All other pushes\n * enter into union-fan-out before reaching union-fan-in.\n *\n * - normal joins for `exists` come before `union-fan-out`\n * - joins for `related` come after `union-fan-out`\n * - take comes after `union-fan-out`\n *\n * The algorithm for deciding whether or not to forward a push that came from inside the ufo/ufi sub-graph:\n * 1. If the change is a `child` change we can forward it. This is because all child branches in the ufo/ufi sub-graph are unique.\n * 2. If the change is `add` we can forward it iff no `fetches` for the row return any results.\n * If another branch has it, the add was already emitted in the past.\n * 3. If the change is `remove` we can forward it iff no `fetches` for the row return any results.\n * If no other branches have the change, the remove can be sent as the value is no longer present.\n * If other branches have it, the last branch the processes the remove will send the remove.\n * 4. Edits will always come through as child changes as flip join will flip them into children.\n * An edit that would result in a remove or add will have been split into an add/remove pair rather than being an edit.\n */\n #pushInternalChange(change: Change, pusher: InputBase): void {\n if (change.type === 'child') {\n this.#output.push(change, this);\n return;\n }\n\n assert(change.type === 'add' || change.type === 'remove');\n\n let hadMatch = false;\n for (const input of this.#inputs) {\n if (input === pusher) {\n hadMatch = true;\n continue;\n }\n\n const constraint: Writable<Constraint> = {};\n for (const key of this.#schema.primaryKey) {\n constraint[key] = change.node.row[key];\n }\n const fetchResult = input.fetch({\n constraint,\n });\n\n if (first(fetchResult) !== undefined) {\n // Another branch has the row, so the add/remove is not needed.\n return;\n }\n }\n\n assert(hadMatch, 'Pusher was not one of the inputs to union-fan-in!');\n\n // No other branches have the row, so we can push the change.\n this.#output.push(change, this);\n }\n\n fanOutStartedPushing() {\n assert(this.#fanOutPushStarted === false);\n this.#fanOutPushStarted = true;\n }\n\n fanOutDonePushing(fanOutChangeType: Change['type']) {\n assert(this.#fanOutPushStarted);\n this.#fanOutPushStarted = false;\n if (this.#inputs.length === 0) {\n return;\n }\n\n if (this.#accumulatedPushes.length === 0) {\n // It is possible for no forks to pass along the push.\n // E.g., if no filters match in any fork.\n return;\n }\n\n pushAccumulatedChanges(\n this.#accumulatedPushes,\n this.#output,\n this,\n fanOutChangeType,\n mergeRelationships,\n makeAddEmptyRelationships(this.#schema),\n );\n }\n\n setOutput(output: Output): void {\n this.#output = output;\n }\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"union-fan-in.js","sources":["../../../../../zql/src/ivm/union-fan-in.ts"],"sourcesContent":["import {assert} from '../../../shared/src/asserts.ts';\nimport type {Writable} from '../../../shared/src/writable.ts';\nimport type {Change} from './change.ts';\nimport type {Constraint} from './constraint.ts';\nimport type {Node} from './data.ts';\nimport {\n throwOutput,\n type FetchRequest,\n type Input,\n type InputBase,\n type Operator,\n type Output,\n} from './operator.ts';\nimport {\n makeAddEmptyRelationships,\n mergeRelationships,\n pushAccumulatedChanges,\n} from './push-accumulated.ts';\nimport type {SourceSchema} from './schema.ts';\nimport {first, type Stream} from './stream.ts';\nimport type {UnionFanOut} from './union-fan-out.ts';\n\nexport class UnionFanIn implements Operator {\n readonly #inputs: readonly Input[];\n readonly #schema: SourceSchema;\n #fanOutPushStarted: boolean = false;\n #output: Output = throwOutput;\n #accumulatedPushes: Change[] = [];\n\n constructor(fanOut: UnionFanOut, inputs: Input[]) {\n this.#inputs = inputs;\n const fanOutSchema = fanOut.getSchema();\n fanOut.setFanIn(this);\n\n const schema: Writable<SourceSchema> = {\n tableName: fanOutSchema.tableName,\n columns: fanOutSchema.columns,\n primaryKey: fanOutSchema.primaryKey,\n relationships: {\n ...fanOutSchema.relationships,\n },\n isHidden: fanOutSchema.isHidden,\n system: fanOutSchema.system,\n compareRows: fanOutSchema.compareRows,\n sort: fanOutSchema.sort,\n };\n\n // now go through inputs and merge relationships\n const relationshipsFromBranches: Set<string> = new Set();\n for (const input of inputs) {\n const inputSchema = input.getSchema();\n assert(\n schema.tableName === inputSchema.tableName,\n `Table name mismatch in union fan-in: ${schema.tableName} !== ${inputSchema.tableName}`,\n );\n assert(\n schema.primaryKey === inputSchema.primaryKey,\n `Primary key mismatch in union fan-in`,\n );\n assert(\n schema.system === inputSchema.system,\n `System mismatch in union fan-in: ${schema.system} !== ${inputSchema.system}`,\n );\n assert(\n schema.compareRows === inputSchema.compareRows,\n `compareRows mismatch in union fan-in`,\n );\n assert(schema.sort === inputSchema.sort, `Sort mismatch in union fan-in`);\n\n for (const [relName, relSchema] of Object.entries(\n inputSchema.relationships,\n )) {\n if (relName in fanOutSchema.relationships) {\n continue;\n }\n\n // All branches will have unique relationship names except for relationships\n // that come in from `fanOut`.\n assert(\n !relationshipsFromBranches.has(relName),\n `Relationship ${relName} exists in multiple upstream inputs to union fan-in`,\n );\n schema.relationships[relName] = relSchema;\n relationshipsFromBranches.add(relName);\n }\n\n input.setOutput(this);\n }\n\n this.#schema = schema;\n this.#inputs = inputs;\n }\n\n destroy(): void {\n for (const input of this.#inputs) {\n input.destroy();\n }\n }\n\n fetch(req: FetchRequest): Stream<Node | 'yield'> {\n const iterables = this.#inputs.map(input => input.fetch(req));\n return mergeFetches(iterables, (l, r) =>\n this.#schema.compareRows(l.row, r.row),\n );\n }\n\n getSchema(): SourceSchema {\n return this.#schema;\n }\n\n *push(change: Change, pusher: InputBase): Stream<'yield'> {\n if (!this.#fanOutPushStarted) {\n yield* this.#pushInternalChange(change, pusher);\n } else {\n this.#accumulatedPushes.push(change);\n }\n }\n\n /**\n * An internal change means that a change was received inside the fan-out/fan-in sub-graph.\n *\n * These changes always come from children of a flip-join as no other push generating operators\n * currently exist between union-fan-in and union-fan-out. All other pushes\n * enter into union-fan-out before reaching union-fan-in.\n *\n * - normal joins for `exists` come before `union-fan-out`\n * - joins for `related` come after `union-fan-out`\n * - take comes after `union-fan-out`\n *\n * The algorithm for deciding whether or not to forward a push that came from inside the ufo/ufi sub-graph:\n * 1. If the change is a `child` change we can forward it. This is because all child branches in the ufo/ufi sub-graph are unique.\n * 2. If the change is `add` we can forward it iff no `fetches` for the row return any results.\n * If another branch has it, the add was already emitted in the past.\n * 3. If the change is `remove` we can forward it iff no `fetches` for the row return any results.\n * If no other branches have the change, the remove can be sent as the value is no longer present.\n * If other branches have it, the last branch the processes the remove will send the remove.\n * 4. Edits will always come through as child changes as flip join will flip them into children.\n * An edit that would result in a remove or add will have been split into an add/remove pair rather than being an edit.\n */\n *#pushInternalChange(change: Change, pusher: InputBase): Stream<'yield'> {\n if (change.type === 'child') {\n yield* this.#output.push(change, this);\n return;\n }\n\n assert(change.type === 'add' || change.type === 'remove');\n\n let hadMatch = false;\n for (const input of this.#inputs) {\n if (input === pusher) {\n hadMatch = true;\n continue;\n }\n\n const constraint: Writable<Constraint> = {};\n for (const key of this.#schema.primaryKey) {\n constraint[key] = change.node.row[key];\n }\n const fetchResult = input.fetch({\n constraint,\n });\n\n if (first(fetchResult) !== undefined) {\n // Another branch has the row, so the add/remove is not needed.\n return;\n }\n }\n\n assert(hadMatch, 'Pusher was not one of the inputs to union-fan-in!');\n\n // No other branches have the row, so we can push the change.\n yield* this.#output.push(change, this);\n }\n\n fanOutStartedPushing() {\n assert(this.#fanOutPushStarted === false);\n this.#fanOutPushStarted = true;\n }\n\n *fanOutDonePushing(fanOutChangeType: Change['type']): Stream<'yield'> {\n assert(this.#fanOutPushStarted);\n this.#fanOutPushStarted = false;\n if (this.#inputs.length === 0) {\n return;\n }\n\n if (this.#accumulatedPushes.length === 0) {\n // It is possible for no forks to pass along the push.\n // E.g., if no filters match in any fork.\n return;\n }\n\n yield* pushAccumulatedChanges(\n this.#accumulatedPushes,\n this.#output,\n this,\n fanOutChangeType,\n mergeRelationships,\n makeAddEmptyRelationships(this.#schema),\n );\n }\n\n setOutput(output: Output): void {\n this.#output = output;\n }\n}\n\nexport function* mergeFetches(\n fetches: Iterable<Node | 'yield'>[],\n comparator: (l: Node, r: Node) => number,\n): IterableIterator<Node | 'yield'> {\n const iterators = fetches.map(i => i[Symbol.iterator]());\n let threw = false;\n try {\n const current: (Node | null)[] = [];\n let lastNodeYielded: Node | undefined;\n for (let i = 0; i < iterators.length; i++) {\n const iter = iterators[i];\n let result = iter.next();\n // yield yields when initializing\n while (!result.done && result.value === 'yield') {\n yield result.value;\n result = iter.next();\n }\n current[i] = result.done ? null : (result.value as Node);\n }\n while (current.some(c => c !== null)) {\n const min = current.reduce(\n (acc: [Node, number] | undefined, c, i): [Node, number] | undefined => {\n if (c === null) {\n return acc;\n }\n if (acc === undefined || comparator(c, acc[0]) < 0) {\n return [c, i];\n }\n return acc;\n },\n undefined,\n );\n\n assert(min !== undefined, 'min is undefined');\n const [minNode, minIndex] = min;\n const iter = iterators[minIndex];\n let result = iter.next();\n while (!result.done && result.value === 'yield') {\n yield result.value;\n result = iter.next();\n }\n current[minIndex] = result.done ? null : (result.value as Node);\n if (\n lastNodeYielded !== undefined &&\n comparator(lastNodeYielded, minNode) === 0\n ) {\n continue;\n }\n lastNodeYielded = minNode;\n yield minNode;\n }\n } catch (e) {\n threw = true;\n for (const iter of iterators) {\n try {\n iter.throw?.(e);\n } catch (_cleanupError) {\n // error in the iter.throw cleanup,\n // catch so other iterators are cleaned up\n }\n }\n throw e;\n } finally {\n if (!threw) {\n for (const iter of iterators) {\n try {\n iter.return?.();\n } catch (_cleanupError) {\n // error in the iter.return cleanup,\n // catch so other iterators are cleaned up\n }\n }\n }\n }\n}\n"],"names":[],"mappings":"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"}
@@ -8,11 +8,10 @@ export declare class UnionFanOut implements Operator {
8
8
  #private;
9
9
  constructor(input: Input);
10
10
  setFanIn(fanIn: UnionFanIn): void;
11
- push(change: Change): void;
11
+ push(change: Change): Stream<'yield'>;
12
12
  setOutput(output: Output): void;
13
13
  getSchema(): SourceSchema;
14
- fetch(req: FetchRequest): Stream<Node>;
15
- cleanup(_req: FetchRequest): Stream<Node>;
14
+ fetch(req: FetchRequest): Stream<Node | 'yield'>;
16
15
  destroy(): void;
17
16
  }
18
17
  //# sourceMappingURL=union-fan-out.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"union-fan-out.d.ts","sourceRoot":"","sources":["../../../../../zql/src/ivm/union-fan-out.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAC,MAAM,EAAC,MAAM,aAAa,CAAC;AACxC,OAAO,KAAK,EAAC,IAAI,EAAC,MAAM,WAAW,CAAC;AACpC,OAAO,KAAK,EAAC,YAAY,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAC,MAAM,eAAe,CAAC;AACzE,OAAO,KAAK,EAAC,YAAY,EAAC,MAAM,aAAa,CAAC;AAC9C,OAAO,KAAK,EAAC,MAAM,EAAC,MAAM,aAAa,CAAC;AACxC,OAAO,KAAK,EAAC,UAAU,EAAC,MAAM,mBAAmB,CAAC;AAElD,qBAAa,WAAY,YAAW,QAAQ;;gBAM9B,KAAK,EAAE,KAAK;IAKxB,QAAQ,CAAC,KAAK,EAAE,UAAU;IAK1B,IAAI,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAQ1B,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAI/B,SAAS,IAAI,YAAY;IAIzB,KAAK,CAAC,GAAG,EAAE,YAAY,GAAG,MAAM,CAAC,IAAI,CAAC;IAItC,OAAO,CAAC,IAAI,EAAE,YAAY,GAAG,MAAM,CAAC,IAAI,CAAC;IAKzC,OAAO,IAAI,IAAI;CAUhB"}
1
+ {"version":3,"file":"union-fan-out.d.ts","sourceRoot":"","sources":["../../../../../zql/src/ivm/union-fan-out.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAC,MAAM,EAAC,MAAM,aAAa,CAAC;AACxC,OAAO,KAAK,EAAC,IAAI,EAAC,MAAM,WAAW,CAAC;AACpC,OAAO,KAAK,EAAC,YAAY,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAC,MAAM,eAAe,CAAC;AACzE,OAAO,KAAK,EAAC,YAAY,EAAC,MAAM,aAAa,CAAC;AAC9C,OAAO,KAAK,EAAC,MAAM,EAAC,MAAM,aAAa,CAAC;AACxC,OAAO,KAAK,EAAC,UAAU,EAAC,MAAM,mBAAmB,CAAC;AAElD,qBAAa,WAAY,YAAW,QAAQ;;gBAM9B,KAAK,EAAE,KAAK;IAKxB,QAAQ,CAAC,KAAK,EAAE,UAAU;IAKzB,IAAI,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC;IAQtC,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAI/B,SAAS,IAAI,YAAY;IAIzB,KAAK,CAAC,GAAG,EAAE,YAAY,GAAG,MAAM,CAAC,IAAI,GAAG,OAAO,CAAC;IAIhD,OAAO,IAAI,IAAI;CAUhB"}
@@ -13,12 +13,12 @@ class UnionFanOut {
13
13
  assert(!this.#unionFanIn, "FanIn already set for this FanOut");
14
14
  this.#unionFanIn = fanIn;
15
15
  }
16
- push(change) {
16
+ *push(change) {
17
17
  must(this.#unionFanIn).fanOutStartedPushing();
18
18
  for (const output of this.#outputs) {
19
- output.push(change, this);
19
+ yield* output.push(change, this);
20
20
  }
21
- must(this.#unionFanIn).fanOutDonePushing(change.type);
21
+ yield* must(this.#unionFanIn).fanOutDonePushing(change.type);
22
22
  }
23
23
  setOutput(output) {
24
24
  this.#outputs.push(output);
@@ -29,9 +29,6 @@ class UnionFanOut {
29
29
  fetch(req) {
30
30
  return this.#input.fetch(req);
31
31
  }
32
- cleanup(_req) {
33
- return [];
34
- }
35
32
  destroy() {
36
33
  if (this.#destroyCount < this.#outputs.length) {
37
34
  ++this.#destroyCount;
@@ -1 +1 @@
1
- {"version":3,"file":"union-fan-out.js","sources":["../../../../../zql/src/ivm/union-fan-out.ts"],"sourcesContent":["import {assert} from '../../../shared/src/asserts.ts';\nimport {must} from '../../../shared/src/must.ts';\nimport type {Change} from './change.ts';\nimport type {Node} from './data.ts';\nimport type {FetchRequest, Input, Operator, Output} from './operator.ts';\nimport type {SourceSchema} from './schema.ts';\nimport type {Stream} from './stream.ts';\nimport type {UnionFanIn} from './union-fan-in.ts';\n\nexport class UnionFanOut implements Operator {\n #destroyCount: number = 0;\n #unionFanIn?: UnionFanIn;\n readonly #input: Input;\n readonly #outputs: Output[] = [];\n\n constructor(input: Input) {\n this.#input = input;\n input.setOutput(this);\n }\n\n setFanIn(fanIn: UnionFanIn) {\n assert(!this.#unionFanIn, 'FanIn already set for this FanOut');\n this.#unionFanIn = fanIn;\n }\n\n push(change: Change): void {\n must(this.#unionFanIn).fanOutStartedPushing();\n for (const output of this.#outputs) {\n output.push(change, this);\n }\n must(this.#unionFanIn).fanOutDonePushing(change.type);\n }\n\n setOutput(output: Output): void {\n this.#outputs.push(output);\n }\n\n getSchema(): SourceSchema {\n return this.#input.getSchema();\n }\n\n fetch(req: FetchRequest): Stream<Node> {\n return this.#input.fetch(req);\n }\n\n cleanup(_req: FetchRequest): Stream<Node> {\n // Cleanup is going away. Not implemented.\n return [];\n }\n\n destroy(): void {\n if (this.#destroyCount < this.#outputs.length) {\n ++this.#destroyCount;\n if (this.#destroyCount === this.#outputs.length) {\n this.#input.destroy();\n }\n } else {\n throw new Error('FanOut already destroyed once for each output');\n }\n }\n}\n"],"names":[],"mappings":";;AASO,MAAM,YAAgC;AAAA,EAC3C,gBAAwB;AAAA,EACxB;AAAA,EACS;AAAA,EACA,WAAqB,CAAA;AAAA,EAE9B,YAAY,OAAc;AACxB,SAAK,SAAS;AACd,UAAM,UAAU,IAAI;AAAA,EACtB;AAAA,EAEA,SAAS,OAAmB;AAC1B,WAAO,CAAC,KAAK,aAAa,mCAAmC;AAC7D,SAAK,cAAc;AAAA,EACrB;AAAA,EAEA,KAAK,QAAsB;AACzB,SAAK,KAAK,WAAW,EAAE,qBAAA;AACvB,eAAW,UAAU,KAAK,UAAU;AAClC,aAAO,KAAK,QAAQ,IAAI;AAAA,IAC1B;AACA,SAAK,KAAK,WAAW,EAAE,kBAAkB,OAAO,IAAI;AAAA,EACtD;AAAA,EAEA,UAAU,QAAsB;AAC9B,SAAK,SAAS,KAAK,MAAM;AAAA,EAC3B;AAAA,EAEA,YAA0B;AACxB,WAAO,KAAK,OAAO,UAAA;AAAA,EACrB;AAAA,EAEA,MAAM,KAAiC;AACrC,WAAO,KAAK,OAAO,MAAM,GAAG;AAAA,EAC9B;AAAA,EAEA,QAAQ,MAAkC;AAExC,WAAO,CAAA;AAAA,EACT;AAAA,EAEA,UAAgB;AACd,QAAI,KAAK,gBAAgB,KAAK,SAAS,QAAQ;AAC7C,QAAE,KAAK;AACP,UAAI,KAAK,kBAAkB,KAAK,SAAS,QAAQ;AAC/C,aAAK,OAAO,QAAA;AAAA,MACd;AAAA,IACF,OAAO;AACL,YAAM,IAAI,MAAM,+CAA+C;AAAA,IACjE;AAAA,EACF;AACF;"}
1
+ {"version":3,"file":"union-fan-out.js","sources":["../../../../../zql/src/ivm/union-fan-out.ts"],"sourcesContent":["import {assert} from '../../../shared/src/asserts.ts';\nimport {must} from '../../../shared/src/must.ts';\nimport type {Change} from './change.ts';\nimport type {Node} from './data.ts';\nimport type {FetchRequest, Input, Operator, Output} from './operator.ts';\nimport type {SourceSchema} from './schema.ts';\nimport type {Stream} from './stream.ts';\nimport type {UnionFanIn} from './union-fan-in.ts';\n\nexport class UnionFanOut implements Operator {\n #destroyCount: number = 0;\n #unionFanIn?: UnionFanIn;\n readonly #input: Input;\n readonly #outputs: Output[] = [];\n\n constructor(input: Input) {\n this.#input = input;\n input.setOutput(this);\n }\n\n setFanIn(fanIn: UnionFanIn) {\n assert(!this.#unionFanIn, 'FanIn already set for this FanOut');\n this.#unionFanIn = fanIn;\n }\n\n *push(change: Change): Stream<'yield'> {\n must(this.#unionFanIn).fanOutStartedPushing();\n for (const output of this.#outputs) {\n yield* output.push(change, this);\n }\n yield* must(this.#unionFanIn).fanOutDonePushing(change.type);\n }\n\n setOutput(output: Output): void {\n this.#outputs.push(output);\n }\n\n getSchema(): SourceSchema {\n return this.#input.getSchema();\n }\n\n fetch(req: FetchRequest): Stream<Node | 'yield'> {\n return this.#input.fetch(req);\n }\n\n destroy(): void {\n if (this.#destroyCount < this.#outputs.length) {\n ++this.#destroyCount;\n if (this.#destroyCount === this.#outputs.length) {\n this.#input.destroy();\n }\n } else {\n throw new Error('FanOut already destroyed once for each output');\n }\n }\n}\n"],"names":[],"mappings":";;AASO,MAAM,YAAgC;AAAA,EAC3C,gBAAwB;AAAA,EACxB;AAAA,EACS;AAAA,EACA,WAAqB,CAAA;AAAA,EAE9B,YAAY,OAAc;AACxB,SAAK,SAAS;AACd,UAAM,UAAU,IAAI;AAAA,EACtB;AAAA,EAEA,SAAS,OAAmB;AAC1B,WAAO,CAAC,KAAK,aAAa,mCAAmC;AAC7D,SAAK,cAAc;AAAA,EACrB;AAAA,EAEA,CAAC,KAAK,QAAiC;AACrC,SAAK,KAAK,WAAW,EAAE,qBAAA;AACvB,eAAW,UAAU,KAAK,UAAU;AAClC,aAAO,OAAO,KAAK,QAAQ,IAAI;AAAA,IACjC;AACA,WAAO,KAAK,KAAK,WAAW,EAAE,kBAAkB,OAAO,IAAI;AAAA,EAC7D;AAAA,EAEA,UAAU,QAAsB;AAC9B,SAAK,SAAS,KAAK,MAAM;AAAA,EAC3B;AAAA,EAEA,YAA0B;AACxB,WAAO,KAAK,OAAO,UAAA;AAAA,EACrB;AAAA,EAEA,MAAM,KAA2C;AAC/C,WAAO,KAAK,OAAO,MAAM,GAAG;AAAA,EAC9B;AAAA,EAEA,UAAgB;AACd,QAAI,KAAK,gBAAgB,KAAK,SAAS,QAAQ;AAC7C,QAAE,KAAK;AACP,UAAI,KAAK,kBAAkB,KAAK,SAAS,QAAQ;AAC/C,aAAK,OAAO,QAAA;AAAA,MACd;AAAA,IACF,OAAO;AACL,YAAM,IAAI,MAAM,+CAA+C;AAAA,IACjE;AAAA,EACF;AACF;"}
@@ -1 +1 @@
1
- {"version":3,"file":"view-apply-change.d.ts","sourceRoot":"","sources":["../../../../../zql/src/ivm/view-apply-change.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAC,GAAG,EAAC,MAAM,oCAAoC,CAAC;AAC5D,OAAO,EAAgC,KAAK,IAAI,EAAC,MAAM,WAAW,CAAC;AACnE,OAAO,KAAK,EAAC,YAAY,EAAC,MAAM,aAAa,CAAC;AAC9C,OAAO,KAAK,EAAC,KAAK,EAAE,MAAM,EAAC,MAAM,WAAW,CAAC;AAE7C,eAAO,MAAM,cAAc,eAAe,CAAC;AAC3C,eAAO,MAAM,QAAQ,eAAe,CAAC;AAQrC;;;;GAIG;AACH,MAAM,MAAM,UAAU,GAClB,aAAa,GACb,gBAAgB,GAChB,eAAe,GACf,cAAc,CAAC;AAEnB,MAAM,MAAM,WAAW,GAAG;IAAC,GAAG,EAAE,GAAG,CAAA;CAAC,CAAC;AAErC,MAAM,MAAM,aAAa,GAAG;IAC1B,IAAI,EAAE,KAAK,CAAC;IACZ,IAAI,EAAE,IAAI,CAAC;CACZ,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG;IAC7B,IAAI,EAAE,QAAQ,CAAC;IACf,IAAI,EAAE,IAAI,CAAC;CACZ,CAAC;AAEF,KAAK,eAAe,GAAG;IACrB,IAAI,EAAE,OAAO,CAAC;IACd,IAAI,EAAE,WAAW,CAAC;IAClB,KAAK,EAAE;QACL,gBAAgB,EAAE,MAAM,CAAC;QACzB,MAAM,EAAE,UAAU,CAAC;KACpB,CAAC;CACH,CAAC;AAEF,KAAK,cAAc,GAAG;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,WAAW,CAAC;IAClB,OAAO,EAAE,WAAW,CAAC;CACtB,CAAC;AAEF;;;GAGG;AACH,MAAM,WAAW,WAAW;IAC1B,GAAG,CAAC,KAAK,EAAE,KAAK,GAAG,MAAM,GAAG,SAAS,CAAC;IACtC,GAAG,CAAC,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1C,MAAM,CAAC,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC;CAC/B;AAED,wBAAgB,WAAW,CACzB,WAAW,EAAE,KAAK,EAClB,MAAM,EAAE,UAAU,EAClB,MAAM,EAAE,YAAY,EACpB,YAAY,EAAE,MAAM,EACpB,MAAM,EAAE,MAAM,EACd,OAAO,UAAQ,GACd,IAAI,CA2ON"}
1
+ {"version":3,"file":"view-apply-change.d.ts","sourceRoot":"","sources":["../../../../../zql/src/ivm/view-apply-change.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAC,GAAG,EAAC,MAAM,oCAAoC,CAAC;AAC5D,OAAO,EAAkB,KAAK,IAAI,EAAC,MAAM,WAAW,CAAC;AAErD,OAAO,KAAK,EAAC,YAAY,EAAC,MAAM,aAAa,CAAC;AAC9C,OAAO,KAAK,EAAC,KAAK,EAAE,MAAM,EAAC,MAAM,WAAW,CAAC;AAE7C,eAAO,MAAM,cAAc,eAAe,CAAC;AAC3C,eAAO,MAAM,QAAQ,eAAe,CAAC;AAQrC;;;;GAIG;AACH,MAAM,MAAM,UAAU,GAClB,aAAa,GACb,gBAAgB,GAChB,eAAe,GACf,cAAc,CAAC;AAEnB,MAAM,MAAM,WAAW,GAAG;IAAC,GAAG,EAAE,GAAG,CAAA;CAAC,CAAC;AAErC,MAAM,MAAM,aAAa,GAAG;IAC1B,IAAI,EAAE,KAAK,CAAC;IACZ,IAAI,EAAE,IAAI,CAAC;CACZ,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG;IAC7B,IAAI,EAAE,QAAQ,CAAC;IACf,IAAI,EAAE,IAAI,CAAC;CACZ,CAAC;AAEF,KAAK,eAAe,GAAG;IACrB,IAAI,EAAE,OAAO,CAAC;IACd,IAAI,EAAE,WAAW,CAAC;IAClB,KAAK,EAAE;QACL,gBAAgB,EAAE,MAAM,CAAC;QACzB,MAAM,EAAE,UAAU,CAAC;KACpB,CAAC;CACH,CAAC;AAEF,KAAK,cAAc,GAAG;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,WAAW,CAAC;IAClB,OAAO,EAAE,WAAW,CAAC;CACtB,CAAC;AAEF;;;GAGG;AACH,MAAM,WAAW,WAAW;IAC1B,GAAG,CAAC,KAAK,EAAE,KAAK,GAAG,MAAM,GAAG,SAAS,CAAC;IACtC,GAAG,CAAC,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1C,MAAM,CAAC,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC;CAC/B;AAED,wBAAgB,WAAW,CACzB,WAAW,EAAE,KAAK,EAClB,MAAM,EAAE,UAAU,EAClB,MAAM,EAAE,YAAY,EACpB,YAAY,EAAE,MAAM,EACpB,MAAM,EAAE,MAAM,EACd,OAAO,UAAQ,GACd,IAAI,CAyON"}
@@ -1,6 +1,7 @@
1
1
  import { unreachable, assert, assertNumber, assertArray } from "../../../shared/src/asserts.js";
2
2
  import { must } from "../../../shared/src/must.js";
3
- import { drainStreams } from "./data.js";
3
+ import "compare-utf8";
4
+ import { skipYields } from "./operator.js";
4
5
  const refCountSymbol = Symbol("rc");
5
6
  const idSymbol = Symbol("id");
6
7
  function applyChange(parentEntry, change, schema, relationship, format, withIDs = false) {
@@ -12,7 +13,7 @@ function applyChange(parentEntry, change, schema, relationship, format, withIDs
12
13
  change.node.relationships
13
14
  )) {
14
15
  const childSchema = must(schema.relationships[relationship2]);
15
- for (const node of children()) {
16
+ for (const node of skipYields(children())) {
16
17
  applyChange(
17
18
  parentEntry,
18
19
  { type: change.type, node },
@@ -79,7 +80,7 @@ function applyChange(parentEntry, change, schema, relationship, format, withIDs
79
80
  }
80
81
  const newView = childFormat.singular ? void 0 : [];
81
82
  newEntry[relationship2] = newView;
82
- for (const node of children()) {
83
+ for (const node of skipYields(children())) {
83
84
  applyChange(
84
85
  newEntry,
85
86
  { type: "add", node },
@@ -109,7 +110,6 @@ function applyChange(parentEntry, change, schema, relationship, format, withIDs
109
110
  schema.compareRows
110
111
  );
111
112
  }
112
- drainStreams(change.node);
113
113
  break;
114
114
  }
115
115
  case "child": {
@@ -1 +1 @@
1
- {"version":3,"file":"view-apply-change.js","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 type {Writable} from '../../../shared/src/writable.ts';\nimport type {Row} from '../../../zero-protocol/src/data.ts';\nimport {drainStreams, type Comparator, type Node} from './data.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 MetaEntry = Writable<Entry> & {\n [refCountSymbol]: number;\n [idSymbol]?: string | undefined;\n};\ntype MetaEntryList = MetaEntry[];\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: Node;\n};\n\nexport type RemoveViewChange = {\n type: 'remove';\n node: Node;\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\nexport function applyChange(\n parentEntry: Entry,\n change: ViewChange,\n schema: SourceSchema,\n relationship: string,\n format: Format,\n withIDs = false,\n): void {\n if (schema.isHidden) {\n switch (change.type) {\n case 'add':\n case 'remove':\n for (const [relationship, children] of Object.entries(\n change.node.relationships,\n )) {\n const childSchema = must(schema.relationships[relationship]);\n for (const node of children()) {\n applyChange(\n parentEntry,\n {type: change.type, node},\n childSchema,\n relationship,\n format,\n withIDs,\n );\n }\n }\n return;\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;\n case 'child': {\n const childSchema = must(\n schema.relationships[change.child.relationshipName],\n );\n applyChange(\n parentEntry,\n change.child.change,\n childSchema,\n relationship,\n format,\n withIDs,\n );\n return;\n }\n default:\n unreachable(change);\n }\n }\n\n const {singular, relationships: childFormats} = format;\n switch (change.type) {\n case 'add': {\n let newEntry: MetaEntry | undefined;\n\n if (singular) {\n const oldEntry = parentEntry[relationship] as MetaEntry | undefined;\n if (oldEntry !== undefined) {\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 // adding same again.\n oldEntry[refCountSymbol]++;\n } else {\n newEntry = makeNewMetaEntry(change.node.row, schema, withIDs, 1);\n\n (parentEntry as Writable<Entry>)[relationship] = newEntry;\n }\n } else {\n newEntry = add(\n change.node.row,\n getChildEntryList(parentEntry, relationship),\n schema,\n withIDs,\n );\n }\n\n if (newEntry) {\n for (const [relationship, children] of Object.entries(\n change.node.relationships,\n )) {\n // TODO: Is there a flag to make TypeScript complain that dictionary access might be undefined?\n const childSchema = must(schema.relationships[relationship]);\n const childFormat = childFormats[relationship];\n if (childFormat === undefined) {\n continue;\n }\n\n const newView = childFormat.singular\n ? undefined\n : ([] as MetaEntryList);\n newEntry[relationship] = newView;\n\n for (const node of children()) {\n applyChange(\n newEntry,\n {type: 'add', node},\n childSchema,\n relationship,\n childFormat,\n withIDs,\n );\n }\n }\n }\n break;\n }\n case 'remove': {\n if (singular) {\n const oldEntry = parentEntry[relationship] as MetaEntry | undefined;\n assert(oldEntry !== undefined, 'node does not exist');\n const rc = oldEntry[refCountSymbol];\n if (rc === 1) {\n (parentEntry as Writable<Entry>)[relationship] = undefined;\n }\n oldEntry[refCountSymbol]--;\n } else {\n removeAndUpdateRefCount(\n getChildEntryList(parentEntry, relationship),\n change.node.row,\n schema.compareRows,\n );\n }\n // Needed to ensure cleanup of operator state is fully done.\n drainStreams(change.node);\n break;\n }\n case 'child': {\n let existing: MetaEntry;\n if (singular) {\n existing = getSingularEntry(parentEntry, relationship);\n } else {\n const view = getChildEntryList(parentEntry, relationship);\n const {pos, found} = binarySearch(\n view,\n change.node.row,\n schema.compareRows,\n );\n assert(found, 'node does not exist');\n existing = view[pos];\n }\n\n const childSchema = must(\n schema.relationships[change.child.relationshipName],\n );\n const childFormat = format.relationships[change.child.relationshipName];\n if (childFormat !== undefined) {\n applyChange(\n existing,\n change.child.change,\n childSchema,\n change.child.relationshipName,\n childFormat,\n withIDs,\n );\n }\n break;\n }\n case 'edit': {\n if (singular) {\n const existing = parentEntry[relationship];\n assertMetaEntry(existing);\n applyEdit(existing, change, schema, withIDs);\n } else {\n const view = getChildEntryList(parentEntry, relationship);\n // The position of the row in the list may have changed due to the edit.\n if (schema.compareRows(change.oldNode.row, change.node.row) !== 0) {\n const {pos: oldPos, found: oldFound} = binarySearch(\n view,\n change.oldNode.row,\n schema.compareRows,\n );\n assert(oldFound, 'old node does not exist');\n const oldEntry = view[oldPos];\n const {pos, found} = binarySearch(\n view,\n change.node.row,\n schema.compareRows,\n );\n // A special case:\n // when refCount is 1 (so the row is being moved\n // without leaving a placeholder behind), and the new pos is\n // the same as the old, or directly after the old (so after the remove\n // of the old it would be in the same pos):\n // the row does not need to be moved, it can just be edited in place.\n if (\n oldEntry[refCountSymbol] === 1 &&\n (pos === oldPos || pos - 1 === oldPos)\n ) {\n applyEdit(oldEntry, change, schema, withIDs);\n } else {\n // Move the row. If the row has > 1 ref count, an edit should\n // be received for each ref count. On the first edit, the original\n // row is moved, the edit is applied to it and its ref count is set\n // to 1. A shallow copy of the row is left at the old pos for\n // processing of the remaining edit, and the copy's ref count\n // is decremented. As each edit is received the ref count of the\n // copy is decrement, and the ref count of the row at the new\n // position is incremented. When the copy's ref count goes to 0,\n // it is removed.\n oldEntry[refCountSymbol]--;\n let adjustedPos = pos;\n if (oldEntry[refCountSymbol] === 0) {\n view.splice(oldPos, 1);\n adjustedPos = oldPos < pos ? pos - 1 : pos;\n }\n\n let entryToEdit;\n if (found) {\n entryToEdit = view[adjustedPos];\n } else {\n view.splice(adjustedPos, 0, oldEntry);\n entryToEdit = oldEntry;\n if (oldEntry[refCountSymbol] > 0) {\n const oldEntryCopy = {...oldEntry};\n view[oldPos] = oldEntryCopy;\n }\n }\n entryToEdit[refCountSymbol]++;\n applyEdit(entryToEdit, change, schema, withIDs);\n }\n } else {\n // Position could not have changed, so simply edit in place.\n const {pos, found} = binarySearch(\n view,\n change.oldNode.row,\n schema.compareRows,\n );\n assert(found, 'node does not exist');\n applyEdit(view[pos], change, schema, withIDs);\n }\n }\n\n break;\n }\n default:\n unreachable(change);\n }\n}\n\nfunction applyEdit(\n existing: MetaEntry,\n change: EditViewChange,\n schema: SourceSchema,\n withIDs: boolean,\n) {\n Object.assign(existing, change.node.row);\n if (withIDs) {\n existing[idSymbol] = makeID(change.node.row, schema);\n }\n}\n\nfunction add(\n row: Row,\n view: MetaEntryList,\n schema: SourceSchema,\n withIDs: boolean,\n): MetaEntry | undefined {\n const {pos, found} = binarySearch(view, row, schema.compareRows);\n\n if (found) {\n view[pos][refCountSymbol]++;\n return undefined;\n }\n const newEntry = makeNewMetaEntry(row, schema, withIDs, 1);\n view.splice(pos, 0, newEntry);\n return newEntry;\n}\n\nfunction removeAndUpdateRefCount(\n view: MetaEntryList,\n row: Row,\n compareRows: Comparator,\n): MetaEntry {\n const {pos, found} = binarySearch(view, row, compareRows);\n assert(found, 'node does not exist');\n const oldEntry = view[pos];\n const rc = oldEntry[refCountSymbol];\n if (rc === 1) {\n view.splice(pos, 1);\n }\n oldEntry[refCountSymbol]--;\n\n return oldEntry;\n}\n\n// TODO: Do not return an object. It puts unnecessary pressure on the GC.\nfunction binarySearch(\n view: MetaEntryList,\n target: Row,\n comparator: Comparator,\n) {\n let low = 0;\n let high = view.length - 1;\n while (low <= high) {\n const mid = (low + high) >>> 1;\n const comparison = comparator(view[mid] as Row, target as Row);\n if (comparison < 0) {\n low = mid + 1;\n } else if (comparison > 0) {\n high = mid - 1;\n } else {\n return {pos: mid, found: true};\n }\n }\n return {pos: low, found: false};\n}\n\nfunction getChildEntryList(\n parentEntry: Entry,\n relationship: string,\n): MetaEntryList {\n const view = parentEntry[relationship];\n assertArray(view);\n return view as MetaEntryList;\n}\n\nfunction assertMetaEntry(v: unknown): asserts v is MetaEntry {\n assertNumber((v as Partial<MetaEntry>)[refCountSymbol]);\n}\n\nfunction getSingularEntry(parentEntry: Entry, relationship: string): MetaEntry {\n const e = parentEntry[relationship];\n assertNumber((e as Partial<MetaEntry>)[refCountSymbol]);\n return e as MetaEntry;\n}\n\nfunction makeNewMetaEntry(\n row: Row,\n schema: SourceSchema,\n withIDs: boolean,\n rc: number,\n): MetaEntry {\n if (withIDs) {\n return {...row, [refCountSymbol]: rc, [idSymbol]: makeID(row, schema)};\n }\n return {...row, [refCountSymbol]: rc};\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"],"names":["relationship"],"mappings":"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"}
1
+ {"version":3,"file":"view-apply-change.js","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 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 MetaEntry = Writable<Entry> & {\n [refCountSymbol]: number;\n [idSymbol]?: string | undefined;\n};\ntype MetaEntryList = MetaEntry[];\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: Node;\n};\n\nexport type RemoveViewChange = {\n type: 'remove';\n node: Node;\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\nexport function applyChange(\n parentEntry: Entry,\n change: ViewChange,\n schema: SourceSchema,\n relationship: string,\n format: Format,\n withIDs = false,\n): void {\n if (schema.isHidden) {\n switch (change.type) {\n case 'add':\n case 'remove':\n for (const [relationship, children] of Object.entries(\n change.node.relationships,\n )) {\n const childSchema = must(schema.relationships[relationship]);\n for (const node of skipYields(children())) {\n applyChange(\n parentEntry,\n {type: change.type, node},\n childSchema,\n relationship,\n format,\n withIDs,\n );\n }\n }\n return;\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;\n case 'child': {\n const childSchema = must(\n schema.relationships[change.child.relationshipName],\n );\n applyChange(\n parentEntry,\n change.child.change,\n childSchema,\n relationship,\n format,\n withIDs,\n );\n return;\n }\n default:\n unreachable(change);\n }\n }\n\n const {singular, relationships: childFormats} = format;\n switch (change.type) {\n case 'add': {\n let newEntry: MetaEntry | undefined;\n\n if (singular) {\n const oldEntry = parentEntry[relationship] as MetaEntry | undefined;\n if (oldEntry !== undefined) {\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 // adding same again.\n oldEntry[refCountSymbol]++;\n } else {\n newEntry = makeNewMetaEntry(change.node.row, schema, withIDs, 1);\n\n (parentEntry as Writable<Entry>)[relationship] = newEntry;\n }\n } else {\n newEntry = add(\n change.node.row,\n getChildEntryList(parentEntry, relationship),\n schema,\n withIDs,\n );\n }\n\n if (newEntry) {\n for (const [relationship, children] of Object.entries(\n change.node.relationships,\n )) {\n // TODO: Is there a flag to make TypeScript complain that dictionary access might be undefined?\n const childSchema = must(schema.relationships[relationship]);\n const childFormat = childFormats[relationship];\n if (childFormat === undefined) {\n continue;\n }\n\n const newView = childFormat.singular\n ? undefined\n : ([] as MetaEntryList);\n newEntry[relationship] = newView;\n\n for (const node of skipYields(children())) {\n applyChange(\n newEntry,\n {type: 'add', node},\n childSchema,\n relationship,\n childFormat,\n withIDs,\n );\n }\n }\n }\n break;\n }\n case 'remove': {\n if (singular) {\n const oldEntry = parentEntry[relationship] as MetaEntry | undefined;\n assert(oldEntry !== undefined, 'node does not exist');\n const rc = oldEntry[refCountSymbol];\n if (rc === 1) {\n (parentEntry as Writable<Entry>)[relationship] = undefined;\n }\n oldEntry[refCountSymbol]--;\n } else {\n removeAndUpdateRefCount(\n getChildEntryList(parentEntry, relationship),\n change.node.row,\n schema.compareRows,\n );\n }\n break;\n }\n case 'child': {\n let existing: MetaEntry;\n if (singular) {\n existing = getSingularEntry(parentEntry, relationship);\n } else {\n const view = getChildEntryList(parentEntry, relationship);\n const {pos, found} = binarySearch(\n view,\n change.node.row,\n schema.compareRows,\n );\n assert(found, 'node does not exist');\n existing = view[pos];\n }\n\n const childSchema = must(\n schema.relationships[change.child.relationshipName],\n );\n const childFormat = format.relationships[change.child.relationshipName];\n if (childFormat !== undefined) {\n applyChange(\n existing,\n change.child.change,\n childSchema,\n change.child.relationshipName,\n childFormat,\n withIDs,\n );\n }\n break;\n }\n case 'edit': {\n if (singular) {\n const existing = parentEntry[relationship];\n assertMetaEntry(existing);\n applyEdit(existing, change, schema, withIDs);\n } else {\n const view = getChildEntryList(parentEntry, relationship);\n // The position of the row in the list may have changed due to the edit.\n if (schema.compareRows(change.oldNode.row, change.node.row) !== 0) {\n const {pos: oldPos, found: oldFound} = binarySearch(\n view,\n change.oldNode.row,\n schema.compareRows,\n );\n assert(oldFound, 'old node does not exist');\n const oldEntry = view[oldPos];\n const {pos, found} = binarySearch(\n view,\n change.node.row,\n schema.compareRows,\n );\n // A special case:\n // when refCount is 1 (so the row is being moved\n // without leaving a placeholder behind), and the new pos is\n // the same as the old, or directly after the old (so after the remove\n // of the old it would be in the same pos):\n // the row does not need to be moved, it can just be edited in place.\n if (\n oldEntry[refCountSymbol] === 1 &&\n (pos === oldPos || pos - 1 === oldPos)\n ) {\n applyEdit(oldEntry, change, schema, withIDs);\n } else {\n // Move the row. If the row has > 1 ref count, an edit should\n // be received for each ref count. On the first edit, the original\n // row is moved, the edit is applied to it and its ref count is set\n // to 1. A shallow copy of the row is left at the old pos for\n // processing of the remaining edit, and the copy's ref count\n // is decremented. As each edit is received the ref count of the\n // copy is decrement, and the ref count of the row at the new\n // position is incremented. When the copy's ref count goes to 0,\n // it is removed.\n oldEntry[refCountSymbol]--;\n let adjustedPos = pos;\n if (oldEntry[refCountSymbol] === 0) {\n view.splice(oldPos, 1);\n adjustedPos = oldPos < pos ? pos - 1 : pos;\n }\n\n let entryToEdit;\n if (found) {\n entryToEdit = view[adjustedPos];\n } else {\n view.splice(adjustedPos, 0, oldEntry);\n entryToEdit = oldEntry;\n if (oldEntry[refCountSymbol] > 0) {\n const oldEntryCopy = {...oldEntry};\n view[oldPos] = oldEntryCopy;\n }\n }\n entryToEdit[refCountSymbol]++;\n applyEdit(entryToEdit, change, schema, withIDs);\n }\n } else {\n // Position could not have changed, so simply edit in place.\n const {pos, found} = binarySearch(\n view,\n change.oldNode.row,\n schema.compareRows,\n );\n assert(found, 'node does not exist');\n applyEdit(view[pos], change, schema, withIDs);\n }\n }\n\n break;\n }\n default:\n unreachable(change);\n }\n}\n\nfunction applyEdit(\n existing: MetaEntry,\n change: EditViewChange,\n schema: SourceSchema,\n withIDs: boolean,\n) {\n Object.assign(existing, change.node.row);\n if (withIDs) {\n existing[idSymbol] = makeID(change.node.row, schema);\n }\n}\n\nfunction add(\n row: Row,\n view: MetaEntryList,\n schema: SourceSchema,\n withIDs: boolean,\n): MetaEntry | undefined {\n const {pos, found} = binarySearch(view, row, schema.compareRows);\n\n if (found) {\n view[pos][refCountSymbol]++;\n return undefined;\n }\n const newEntry = makeNewMetaEntry(row, schema, withIDs, 1);\n view.splice(pos, 0, newEntry);\n return newEntry;\n}\n\nfunction removeAndUpdateRefCount(\n view: MetaEntryList,\n row: Row,\n compareRows: Comparator,\n): MetaEntry {\n const {pos, found} = binarySearch(view, row, compareRows);\n assert(found, 'node does not exist');\n const oldEntry = view[pos];\n const rc = oldEntry[refCountSymbol];\n if (rc === 1) {\n view.splice(pos, 1);\n }\n oldEntry[refCountSymbol]--;\n\n return oldEntry;\n}\n\n// TODO: Do not return an object. It puts unnecessary pressure on the GC.\nfunction binarySearch(\n view: MetaEntryList,\n target: Row,\n comparator: Comparator,\n) {\n let low = 0;\n let high = view.length - 1;\n while (low <= high) {\n const mid = (low + high) >>> 1;\n const comparison = comparator(view[mid] as Row, target as Row);\n if (comparison < 0) {\n low = mid + 1;\n } else if (comparison > 0) {\n high = mid - 1;\n } else {\n return {pos: mid, found: true};\n }\n }\n return {pos: low, found: false};\n}\n\nfunction getChildEntryList(\n parentEntry: Entry,\n relationship: string,\n): MetaEntryList {\n const view = parentEntry[relationship];\n assertArray(view);\n return view as MetaEntryList;\n}\n\nfunction assertMetaEntry(v: unknown): asserts v is MetaEntry {\n assertNumber((v as Partial<MetaEntry>)[refCountSymbol]);\n}\n\nfunction getSingularEntry(parentEntry: Entry, relationship: string): MetaEntry {\n const e = parentEntry[relationship];\n assertNumber((e as Partial<MetaEntry>)[refCountSymbol]);\n return e as MetaEntry;\n}\n\nfunction makeNewMetaEntry(\n row: Row,\n schema: SourceSchema,\n withIDs: boolean,\n rc: number,\n): MetaEntry {\n if (withIDs) {\n return {...row, [refCountSymbol]: rc, [idSymbol]: makeID(row, schema)};\n }\n return {...row, [refCountSymbol]: rc};\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"],"names":["relationship"],"mappings":"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"}
@@ -11,6 +11,6 @@ export type Entry = {
11
11
  readonly [key: string]: Value | View;
12
12
  };
13
13
  export type { Format };
14
- export type ViewFactory<TSchema extends Schema, TTable extends keyof TSchema['tables'] & string, TReturn, T> = (query: Query<TSchema, TTable, TReturn>, input: Input, format: Format, onDestroy: () => void, onTransactionCommit: (cb: () => void) => void, queryComplete: true | ErroredQuery | Promise<true>, updateTTL: (ttl: TTL) => void) => T;
15
- export type AnyViewFactory = ViewFactory<Schema, any, any, any>;
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;
15
+ export type AnyViewFactory = ViewFactory<string, Schema, any, any>;
16
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,MAAM,MAAM,WAAW,CACrB,OAAO,SAAS,MAAM,EACtB,MAAM,SAAS,MAAM,OAAO,CAAC,QAAQ,CAAC,GAAG,MAAM,EAC/C,OAAO,EACP,CAAC,IACC,CACF,KAAK,EAAE,KAAK,CAAC,OAAO,EAAE,MAAM,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,GAAG,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"}
@@ -0,0 +1,116 @@
1
+ import type { Expand } from '../../../shared/src/expand.ts';
2
+ import type { SchemaValueToTSType } from '../../../zero-types/src/schema-value.ts';
3
+ import type { Schema, TableSchema } from '../../../zero-types/src/schema.ts';
4
+ import type { MutateCRUD } from './custom.ts';
5
+ export type SchemaCRUD<S extends Schema> = {
6
+ [Table in keyof S['tables']]: TableCRUD<S['tables'][Table]>;
7
+ };
8
+ export type TransactionMutate<S extends Schema> = SchemaCRUD<S>;
9
+ export type TableCRUD<S extends TableSchema> = {
10
+ /**
11
+ * Writes a row if a row with the same primary key doesn't already exist.
12
+ * Non-primary-key fields that are 'optional' can be omitted or set to
13
+ * `undefined`. Such fields will be assigned the value `null` optimistically
14
+ * and then the default value as defined by the server.
15
+ */
16
+ insert: (value: InsertValue<S>) => Promise<void>;
17
+ /**
18
+ * Writes a row unconditionally, overwriting any existing row with the same
19
+ * primary key. Non-primary-key fields that are 'optional' can be omitted or
20
+ * set to `undefined`. Such fields will be assigned the value `null`
21
+ * optimistically and then the default value as defined by the server.
22
+ */
23
+ upsert: (value: UpsertValue<S>) => Promise<void>;
24
+ /**
25
+ * Updates a row with the same primary key. If no such row exists, this
26
+ * function does nothing. All non-primary-key fields can be omitted or set to
27
+ * `undefined`. Such fields will be left unchanged from previous value.
28
+ */
29
+ update: (value: UpdateValue<S>) => Promise<void>;
30
+ /**
31
+ * Deletes the row with the specified primary key. If no such row exists, this
32
+ * function does nothing.
33
+ */
34
+ delete: (id: DeleteID<S>) => Promise<void>;
35
+ };
36
+ export type CRUDKind = keyof TableCRUD<TableSchema>;
37
+ export declare const CRUD_KINDS: readonly ["insert", "upsert", "update", "delete"];
38
+ export type DeleteID<S extends TableSchema> = Expand<PrimaryKeyFields<S>>;
39
+ type PrimaryKeyFields<S extends TableSchema> = {
40
+ [K in Extract<S['primaryKey'][number], keyof S['columns']>]: SchemaValueToTSType<S['columns'][K]>;
41
+ };
42
+ export type InsertValue<S extends TableSchema> = Expand<PrimaryKeyFields<S> & {
43
+ [K in keyof S['columns'] as S['columns'][K] extends {
44
+ optional: true;
45
+ } ? K : never]?: SchemaValueToTSType<S['columns'][K]> | undefined;
46
+ } & {
47
+ [K in keyof S['columns'] as S['columns'][K] extends {
48
+ optional: true;
49
+ } ? never : K]: SchemaValueToTSType<S['columns'][K]>;
50
+ }>;
51
+ export type UpsertValue<S extends TableSchema> = InsertValue<S>;
52
+ export type UpdateValue<S extends TableSchema> = Expand<PrimaryKeyFields<S> & {
53
+ [K in keyof S['columns']]?: SchemaValueToTSType<S['columns'][K]> | undefined;
54
+ }>;
55
+ /**
56
+ * This is the type of the generated mutate.<name>.<verb> function.
57
+ */
58
+ export type TableMutator<TS extends TableSchema> = {
59
+ /**
60
+ * Writes a row if a row with the same primary key doesn't already exist.
61
+ * Non-primary-key fields that are 'optional' can be omitted or set to
62
+ * `undefined`. Such fields will be assigned the value `null` optimistically
63
+ * and then the default value as defined by the server.
64
+ */
65
+ insert: (value: InsertValue<TS>) => Promise<void>;
66
+ /**
67
+ * Writes a row unconditionally, overwriting any existing row with the same
68
+ * primary key. Non-primary-key fields that are 'optional' can be omitted or
69
+ * set to `undefined`. Such fields will be assigned the value `null`
70
+ * optimistically and then the default value as defined by the server.
71
+ */
72
+ upsert: (value: UpsertValue<TS>) => Promise<void>;
73
+ /**
74
+ * Updates a row with the same primary key. If no such row exists, this
75
+ * function does nothing. All non-primary-key fields can be omitted or set to
76
+ * `undefined`. Such fields will be left unchanged from previous value.
77
+ */
78
+ update: (value: UpdateValue<TS>) => Promise<void>;
79
+ /**
80
+ * Deletes the row with the specified primary key. If no such row exists, this
81
+ * function does nothing.
82
+ */
83
+ delete: (id: DeleteID<TS>) => Promise<void>;
84
+ };
85
+ /**
86
+ * A function that executes a CRUD operation.
87
+ * Client and server provide different implementations.
88
+ */
89
+ export type CRUDExecutor = (table: string, kind: CRUDKind, args: unknown) => Promise<void>;
90
+ /**
91
+ * Creates a MutateCRUD function from a schema and executor.
92
+ * This is the shared implementation used by both client and server.
93
+ *
94
+ * @param schema - The Zero schema
95
+ * @param executor - A function that executes CRUD operations
96
+ * @returns A MutateCRUD function that can be called with CRUDMutateRequest objects
97
+ */
98
+ export declare function makeCRUDMutate<TSchema extends Schema, TAddSchemaCRUD extends boolean>(schema: TSchema, addSchemaCRUD: TAddSchemaCRUD, executor: CRUDExecutor): MutateCRUD<TSchema, TAddSchemaCRUD>;
99
+ export declare function makeTransactionMutate<TSchema extends Schema>(schema: TSchema, executor: CRUDExecutor): TransactionMutate<TSchema>;
100
+ export type CRUDMutator<TSchema extends Schema, TTable extends keyof TSchema['tables'] & string, TKind extends keyof TableMutator<TSchema['tables'][TTable]>, TArgs extends Parameters<TableMutator<TSchema['tables'][TTable]>[TKind]>[0]> = {
101
+ (args: TArgs): CRUDMutateRequest<TSchema, TTable, TKind, TArgs>;
102
+ /**
103
+ * Type-only phantom property to surface mutator types in a covariant position.
104
+ */
105
+ ['~']: Expand<CRUDMutatorTypes<TSchema, TTable, TKind, TArgs>>;
106
+ };
107
+ export type CRUDMutatorTypes<TSchema extends Schema, TTable extends keyof TSchema['tables'] & string, TKind extends keyof TableMutator<TSchema['tables'][TTable]>, TArgs extends Parameters<TableMutator<TSchema['tables'][TTable]>[TKind]>[0]> = 'CRUDMutator' & CRUDMutateRequest<TSchema, TTable, TKind, TArgs>;
108
+ export type CRUDMutateRequest<TSchema extends Schema, TTable extends keyof TSchema['tables'], TKind extends keyof TableMutator<TSchema['tables'][TTable]>, TArgs extends Parameters<TableMutator<TSchema['tables'][TTable]>[TKind]>[0]> = {
109
+ readonly schema: TSchema;
110
+ readonly table: TTable;
111
+ readonly kind: TKind;
112
+ readonly args: TArgs;
113
+ };
114
+ export type AnyCRUDMutateRequest = CRUDMutateRequest<any, any, CRUDKind, any>;
115
+ export {};
116
+ //# sourceMappingURL=crud.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"crud.d.ts","sourceRoot":"","sources":["../../../../../zql/src/mutate/crud.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,41 @@
1
+ import { recordProxy } from "../../../shared/src/record-proxy.js";
2
+ const CRUD_KINDS = ["insert", "upsert", "update", "delete"];
3
+ function makeCRUDMutate(schema, addSchemaCRUD, executor) {
4
+ const mutate = (request) => {
5
+ const { table, kind, args } = request;
6
+ return executor(table, kind, args);
7
+ };
8
+ {
9
+ for (const tableName of Object.keys(schema.tables)) {
10
+ mutate[tableName] = void 0;
11
+ }
12
+ return recordProxy(
13
+ mutate,
14
+ (_value, tableName) => makeTableCRUD(tableName, executor)
15
+ );
16
+ }
17
+ }
18
+ function makeTransactionMutate(schema, executor) {
19
+ const target = {};
20
+ for (const tableName of Object.keys(schema.tables)) {
21
+ target[tableName] = void 0;
22
+ }
23
+ return recordProxy(
24
+ target,
25
+ (_value, tableName) => makeTableCRUD(tableName, executor)
26
+ );
27
+ }
28
+ function makeTableCRUD(tableName, executor) {
29
+ return Object.fromEntries(
30
+ CRUD_KINDS.map((kind) => [
31
+ kind,
32
+ (value) => executor(tableName, kind, value)
33
+ ])
34
+ );
35
+ }
36
+ export {
37
+ CRUD_KINDS,
38
+ makeCRUDMutate,
39
+ makeTransactionMutate
40
+ };
41
+ //# sourceMappingURL=crud.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"crud.js","sources":["../../../../../zql/src/mutate/crud.ts"],"sourcesContent":["import type {Expand} from '../../../shared/src/expand.ts';\nimport {recordProxy} from '../../../shared/src/record-proxy.ts';\nimport type {SchemaValueToTSType} from '../../../zero-types/src/schema-value.ts';\nimport type {Schema, TableSchema} from '../../../zero-types/src/schema.ts';\nimport type {MutateCRUD} from './custom.ts';\n\nexport type SchemaCRUD<S extends Schema> = {\n [Table in keyof S['tables']]: TableCRUD<S['tables'][Table]>;\n};\n\nexport type TransactionMutate<S extends Schema> = SchemaCRUD<S>;\n\nexport type TableCRUD<S extends TableSchema> = {\n /**\n * Writes a row if a row with the same primary key doesn't already exist.\n * Non-primary-key fields that are 'optional' can be omitted or set to\n * `undefined`. Such fields will be assigned the value `null` optimistically\n * and then the default value as defined by the server.\n */\n insert: (value: InsertValue<S>) => Promise<void>;\n\n /**\n * Writes a row unconditionally, overwriting any existing row with the same\n * primary key. Non-primary-key fields that are 'optional' can be omitted or\n * set to `undefined`. Such fields will be assigned the value `null`\n * optimistically and then the default value as defined by the server.\n */\n upsert: (value: UpsertValue<S>) => Promise<void>;\n\n /**\n * Updates a row with the same primary key. If no such row exists, this\n * function does nothing. All non-primary-key fields can be omitted or set to\n * `undefined`. Such fields will be left unchanged from previous value.\n */\n update: (value: UpdateValue<S>) => Promise<void>;\n\n /**\n * Deletes the row with the specified primary key. If no such row exists, this\n * function does nothing.\n */\n delete: (id: DeleteID<S>) => Promise<void>;\n};\n\nexport type CRUDKind = keyof TableCRUD<TableSchema>;\n\nexport const CRUD_KINDS = ['insert', 'upsert', 'update', 'delete'] as const;\n\nexport type DeleteID<S extends TableSchema> = Expand<PrimaryKeyFields<S>>;\n\ntype PrimaryKeyFields<S extends TableSchema> = {\n [K in Extract<\n S['primaryKey'][number],\n keyof S['columns']\n >]: SchemaValueToTSType<S['columns'][K]>;\n};\n\nexport type InsertValue<S extends TableSchema> = Expand<\n PrimaryKeyFields<S> & {\n [K in keyof S['columns'] as S['columns'][K] extends {optional: true}\n ? K\n : never]?: SchemaValueToTSType<S['columns'][K]> | undefined;\n } & {\n [K in keyof S['columns'] as S['columns'][K] extends {optional: true}\n ? never\n : K]: SchemaValueToTSType<S['columns'][K]>;\n }\n>;\n\nexport type UpsertValue<S extends TableSchema> = InsertValue<S>;\n\nexport type UpdateValue<S extends TableSchema> = Expand<\n PrimaryKeyFields<S> & {\n [K in keyof S['columns']]?:\n | SchemaValueToTSType<S['columns'][K]>\n | undefined;\n }\n>;\n\n/**\n * This is the type of the generated mutate.<name>.<verb> function.\n */\nexport type TableMutator<TS extends TableSchema> = {\n /**\n * Writes a row if a row with the same primary key doesn't already exist.\n * Non-primary-key fields that are 'optional' can be omitted or set to\n * `undefined`. Such fields will be assigned the value `null` optimistically\n * and then the default value as defined by the server.\n */\n insert: (value: InsertValue<TS>) => Promise<void>;\n\n /**\n * Writes a row unconditionally, overwriting any existing row with the same\n * primary key. Non-primary-key fields that are 'optional' can be omitted or\n * set to `undefined`. Such fields will be assigned the value `null`\n * optimistically and then the default value as defined by the server.\n */\n upsert: (value: UpsertValue<TS>) => Promise<void>;\n\n /**\n * Updates a row with the same primary key. If no such row exists, this\n * function does nothing. All non-primary-key fields can be omitted or set to\n * `undefined`. Such fields will be left unchanged from previous value.\n */\n update: (value: UpdateValue<TS>) => Promise<void>;\n\n /**\n * Deletes the row with the specified primary key. If no such row exists, this\n * function does nothing.\n */\n delete: (id: DeleteID<TS>) => Promise<void>;\n};\n\n/**\n * A function that executes a CRUD operation.\n * Client and server provide different implementations.\n */\nexport type CRUDExecutor = (\n table: string,\n kind: CRUDKind,\n args: unknown,\n) => Promise<void>;\n\n/**\n * Creates a MutateCRUD function from a schema and executor.\n * This is the shared implementation used by both client and server.\n *\n * @param schema - The Zero schema\n * @param executor - A function that executes CRUD operations\n * @returns A MutateCRUD function that can be called with CRUDMutateRequest objects\n */\nexport function makeCRUDMutate<\n TSchema extends Schema,\n TAddSchemaCRUD extends boolean,\n>(\n schema: TSchema,\n addSchemaCRUD: TAddSchemaCRUD,\n executor: CRUDExecutor,\n): MutateCRUD<TSchema, TAddSchemaCRUD> {\n // Create a callable function that accepts CRUDMutateRequest\n const mutate = (request: AnyCRUDMutateRequest) => {\n const {table, kind, args} = request;\n return executor(table, kind, args);\n };\n\n // Only add table properties when enableLegacyMutators is true\n if (addSchemaCRUD) {\n // Add table names as keys so the proxy can discover them\n for (const tableName of Object.keys(schema.tables)) {\n (mutate as unknown as Record<string, undefined>)[tableName] = undefined;\n }\n\n // Wrap in proxy that lazily creates and caches table CRUD objects\n return recordProxy(\n mutate as unknown as Record<string, undefined>,\n (_value, tableName) => makeTableCRUD(tableName, executor),\n ) as unknown as MutateCRUD<TSchema, TAddSchemaCRUD>;\n }\n\n return mutate as MutateCRUD<TSchema, TAddSchemaCRUD>;\n}\n\nexport function makeTransactionMutate<TSchema extends Schema>(\n schema: TSchema,\n executor: CRUDExecutor,\n): TransactionMutate<TSchema> {\n const target: Record<string, undefined> = {};\n for (const tableName of Object.keys(schema.tables)) {\n target[tableName] = undefined;\n }\n\n return recordProxy(target, (_value, tableName) =>\n makeTableCRUD(tableName, executor),\n ) as SchemaCRUD<TSchema>;\n}\n\n/**\n * Creates a TableCRUD object that delegates to the executor.\n */\nfunction makeTableCRUD(\n tableName: string,\n executor: CRUDExecutor,\n): TableCRUD<TableSchema> {\n return Object.fromEntries(\n CRUD_KINDS.map(kind => [\n kind,\n (value: unknown) => executor(tableName, kind, value),\n ]),\n ) as TableCRUD<TableSchema>;\n}\n\nexport type CRUDMutator<\n TSchema extends Schema,\n TTable extends keyof TSchema['tables'] & string,\n TKind extends keyof TableMutator<TSchema['tables'][TTable]>,\n TArgs extends Parameters<TableMutator<TSchema['tables'][TTable]>[TKind]>[0],\n> = {\n (args: TArgs): CRUDMutateRequest<TSchema, TTable, TKind, TArgs>;\n\n /**\n * Type-only phantom property to surface mutator types in a covariant position.\n */\n ['~']: Expand<CRUDMutatorTypes<TSchema, TTable, TKind, TArgs>>;\n};\n\nexport type CRUDMutatorTypes<\n TSchema extends Schema,\n TTable extends keyof TSchema['tables'] & string,\n TKind extends keyof TableMutator<TSchema['tables'][TTable]>,\n TArgs extends Parameters<TableMutator<TSchema['tables'][TTable]>[TKind]>[0],\n> = 'CRUDMutator' & CRUDMutateRequest<TSchema, TTable, TKind, TArgs>;\n\nexport type CRUDMutateRequest<\n TSchema extends Schema,\n TTable extends keyof TSchema['tables'],\n TKind extends keyof TableMutator<TSchema['tables'][TTable]>,\n TArgs extends Parameters<TableMutator<TSchema['tables'][TTable]>[TKind]>[0],\n> = {\n readonly schema: TSchema;\n readonly table: TTable;\n readonly kind: TKind;\n readonly args: TArgs;\n};\n\n// oxlint-disable-next-line no-explicit-any\nexport type AnyCRUDMutateRequest = CRUDMutateRequest<any, any, CRUDKind, any>;\n"],"names":[],"mappings":";AA6CO,MAAM,aAAa,CAAC,UAAU,UAAU,UAAU,QAAQ;AAqF1D,SAAS,eAId,QACA,eACA,UACqC;AAErC,QAAM,SAAS,CAAC,YAAkC;AAChD,UAAM,EAAC,OAAO,MAAM,KAAA,IAAQ;AAC5B,WAAO,SAAS,OAAO,MAAM,IAAI;AAAA,EACnC;AAGmB;AAEjB,eAAW,aAAa,OAAO,KAAK,OAAO,MAAM,GAAG;AACjD,aAAgD,SAAS,IAAI;AAAA,IAChE;AAGA,WAAO;AAAA,MACL;AAAA,MACA,CAAC,QAAQ,cAAc,cAAc,WAAW,QAAQ;AAAA,IAAA;AAAA,EAE5D;AAGF;AAEO,SAAS,sBACd,QACA,UAC4B;AAC5B,QAAM,SAAoC,CAAA;AAC1C,aAAW,aAAa,OAAO,KAAK,OAAO,MAAM,GAAG;AAClD,WAAO,SAAS,IAAI;AAAA,EACtB;AAEA,SAAO;AAAA,IAAY;AAAA,IAAQ,CAAC,QAAQ,cAClC,cAAc,WAAW,QAAQ;AAAA,EAAA;AAErC;AAKA,SAAS,cACP,WACA,UACwB;AACxB,SAAO,OAAO;AAAA,IACZ,WAAW,IAAI,CAAA,SAAQ;AAAA,MACrB;AAAA,MACA,CAAC,UAAmB,SAAS,WAAW,MAAM,KAAK;AAAA,IAAA,CACpD;AAAA,EAAA;AAEL;"}